summaryrefslogtreecommitdiff
path: root/macros/luatex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/luatex
Initial commit
Diffstat (limited to 'macros/luatex')
-rw-r--r--macros/luatex/generic/chickenize/README.md19
-rw-r--r--macros/luatex/generic/chickenize/chickenize.dtx2101
-rw-r--r--macros/luatex/generic/chickenize/chickenize.lua965
-rw-r--r--macros/luatex/generic/chickenize/chickenize.pdfbin0 -> 195033 bytes
-rw-r--r--macros/luatex/generic/chickenize/chickenize.sty32
-rw-r--r--macros/luatex/generic/chickenize/chickenize.tex441
-rw-r--r--macros/luatex/generic/cstypo/LICENSE21
-rw-r--r--macros/luatex/generic/cstypo/README.md9
-rw-r--r--macros/luatex/generic/cstypo/cstypo-tex.tex24
-rw-r--r--macros/luatex/generic/cstypo/cstypo.lua176
-rw-r--r--macros/luatex/generic/cstypo/cstypo.pdfbin0 -> 74001 bytes
-rw-r--r--macros/luatex/generic/cstypo/cstypo.sty45
-rw-r--r--macros/luatex/generic/cstypo/cstypo.tex138
-rw-r--r--macros/luatex/generic/cstypo/cstypotest.pdfbin0 -> 28731 bytes
-rw-r--r--macros/luatex/generic/cstypo/cstypotest.tex158
-rw-r--r--macros/luatex/generic/ctablestack/README.md4
-rw-r--r--macros/luatex/generic/ctablestack/ctablestack.dtx207
-rw-r--r--macros/luatex/generic/ctablestack/ctablestack.ins10
-rw-r--r--macros/luatex/generic/ctablestack/ctablestack.pdfbin0 -> 151121 bytes
-rw-r--r--macros/luatex/generic/enigma/COPYING22
-rw-r--r--macros/luatex/generic/enigma/README29
-rw-r--r--macros/luatex/generic/enigma/enigma-doc.pdfbin0 -> 265288 bytes
-rw-r--r--macros/luatex/generic/enigma/enigma-example-context.tex59
-rw-r--r--macros/luatex/generic/enigma/enigma-example-latex.tex53
-rw-r--r--macros/luatex/generic/enigma/enigma-example-plain.tex50
-rw-r--r--macros/luatex/generic/enigma/enigma.lua1662
-rw-r--r--macros/luatex/generic/enigma/enigma.sty7
-rw-r--r--macros/luatex/generic/enigma/enigma.tex130
-rw-r--r--macros/luatex/generic/enigma/enigma_manual.tex498
-rw-r--r--macros/luatex/generic/enigma/mtx-t-enigma.lua72
-rw-r--r--macros/luatex/generic/enigma/t-enigma.mkvi157
-rw-r--r--macros/luatex/generic/interpreter/README29
-rw-r--r--macros/luatex/generic/interpreter/i-doc.lua254
-rw-r--r--macros/luatex/generic/interpreter/interpreter-doc.pdfbin0 -> 110003 bytes
-rw-r--r--macros/luatex/generic/interpreter/interpreter-doc.tex115
-rw-r--r--macros/luatex/generic/interpreter/interpreter-doc.txt732
-rw-r--r--macros/luatex/generic/interpreter/interpreter.lua450
-rw-r--r--macros/luatex/generic/interpreter/interpreter.sty17
-rw-r--r--macros/luatex/generic/interpreter/interpreter.tex37
-rw-r--r--macros/luatex/generic/kanaparser/README.md27
-rw-r--r--macros/luatex/generic/kanaparser/description.pdfbin0 -> 200250 bytes
-rw-r--r--macros/luatex/generic/kanaparser/description.tex109
-rw-r--r--macros/luatex/generic/kanaparser/examples.pdfbin0 -> 168753 bytes
-rw-r--r--macros/luatex/generic/kanaparser/examples.tex43
-rw-r--r--macros/luatex/generic/kanaparser/kanaparser.lua427
-rw-r--r--macros/luatex/generic/kanaparser/kanaparser.tex25
l---------macros/luatex/generic/lua-visual-debug/README.md1
-rw-r--r--macros/luatex/generic/lua-visual-debug/doc/README.md37
-rw-r--r--macros/luatex/generic/lua-visual-debug/doc/lvdebug-doc.pdfbin0 -> 209760 bytes
-rw-r--r--macros/luatex/generic/lua-visual-debug/doc/lvdebug-doc.tex70
-rw-r--r--macros/luatex/generic/lua-visual-debug/doc/lvdebugdetail1-num.pngbin0 -> 73328 bytes
-rw-r--r--macros/luatex/generic/lua-visual-debug/doc/sample-plain.pdfbin0 -> 49093 bytes
-rw-r--r--macros/luatex/generic/lua-visual-debug/doc/sample-plain.tex16
-rw-r--r--macros/luatex/generic/lua-visual-debug/doc/sample.pdfbin0 -> 45257 bytes
-rw-r--r--macros/luatex/generic/lua-visual-debug/doc/sample.tex32
-rw-r--r--macros/luatex/generic/lua-visual-debug/doc/strut.pngbin0 -> 11445 bytes
-rw-r--r--macros/luatex/generic/lua-visual-debug/lua-visual-debug.lua160
-rw-r--r--macros/luatex/generic/lua-visual-debug/lua-visual-debug.sty37
-rw-r--r--macros/luatex/generic/lualibs/LICENSE339
-rw-r--r--macros/luatex/generic/lualibs/NEWS88
-rw-r--r--macros/luatex/generic/lualibs/README.md99
-rw-r--r--macros/luatex/generic/lualibs/lualibs-basic-merged.lua5640
-rw-r--r--macros/luatex/generic/lualibs/lualibs-boolean.lua69
-rw-r--r--macros/luatex/generic/lualibs/lualibs-compat.lua31
-rw-r--r--macros/luatex/generic/lualibs/lualibs-dir.lua642
-rw-r--r--macros/luatex/generic/lualibs/lualibs-extended-merged.lua4194
-rw-r--r--macros/luatex/generic/lualibs/lualibs-file.lua738
-rw-r--r--macros/luatex/generic/lualibs/lualibs-function.lua11
-rw-r--r--macros/luatex/generic/lualibs/lualibs-gzip.lua54
-rw-r--r--macros/luatex/generic/lualibs/lualibs-io.lua473
-rw-r--r--macros/luatex/generic/lualibs/lualibs-lpeg.lua1196
-rw-r--r--macros/luatex/generic/lualibs/lualibs-lua.lua259
-rw-r--r--macros/luatex/generic/lualibs/lualibs-math.lua149
-rw-r--r--macros/luatex/generic/lualibs/lualibs-md5.lua110
-rw-r--r--macros/luatex/generic/lualibs/lualibs-number.lua241
-rw-r--r--macros/luatex/generic/lualibs/lualibs-os.lua655
-rw-r--r--macros/luatex/generic/lualibs/lualibs-package.lua400
-rw-r--r--macros/luatex/generic/lualibs/lualibs-set.lua87
-rw-r--r--macros/luatex/generic/lualibs/lualibs-string.lua244
-rw-r--r--macros/luatex/generic/lualibs/lualibs-table.lua1471
-rw-r--r--macros/luatex/generic/lualibs/lualibs-trac-inf.lua313
-rw-r--r--macros/luatex/generic/lualibs/lualibs-unicode.lua1405
-rw-r--r--macros/luatex/generic/lualibs/lualibs-url.lua431
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-deb.lua348
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-dim.lua456
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-fil.lua382
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-jsn.lua443
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-lua.lua212
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-prs.lua804
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-sta.lua352
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-sto.lua282
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-str.lua1461
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-tab.lua874
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-tpl.lua215
-rw-r--r--macros/luatex/generic/lualibs/lualibs.dtx813
-rw-r--r--macros/luatex/generic/lualibs/lualibs.pdfbin0 -> 80996 bytes
-rw-r--r--macros/luatex/generic/luamplib/Makefile96
-rw-r--r--macros/luatex/generic/luamplib/NEWS202
-rw-r--r--macros/luatex/generic/luamplib/README62
-rw-r--r--macros/luatex/generic/luamplib/luamplib.dtx2713
-rw-r--r--macros/luatex/generic/luamplib/luamplib.pdfbin0 -> 148871 bytes
-rw-r--r--macros/luatex/generic/luamplib/test-luamplib-latex.tex164
-rw-r--r--macros/luatex/generic/luamplib/test-luamplib-plain.tex162
-rw-r--r--macros/luatex/generic/luaotfload/COPYING350
-rw-r--r--macros/luatex/generic/luaotfload/NEWS343
-rw-r--r--macros/luatex/generic/luaotfload/README.md103
-rw-r--r--macros/luatex/generic/luaotfload/filegraph.pdfbin0 -> 39715 bytes
-rw-r--r--macros/luatex/generic/luaotfload/filegraph.tex266
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-2019-08-11.lua34169
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-basics-chr.lua3619
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-basics-gen.lua479
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-basics-nod.lua263
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-data-con.lua138
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-afk.lua200
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-cff.lua2483
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-cid.lua177
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-con.lua1711
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-def.lua536
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-dsp.lua3902
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua414
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua147
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua136
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua144
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ini.lua54
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-lua.lua46
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-map.lua693
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ocl.lua670
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-one.lua842
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-onr.lua550
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-osd.lua2859
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ota.lua448
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otc.lua875
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-oti.lua262
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otj.lua1755
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otl.lua857
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-oto.lua542
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otr.lua2553
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ots.lua4492
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ott.lua1234
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-oup.lua3067
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ttf.lua1379
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-vfc.lua123
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-fonts-def.lua98
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-fonts-enc.lua75
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-fonts-ext.lua244
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-fonts-gbn.lua300
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-fonts-lig.lua2067
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-fonts-mis.lua35
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-fonts-syn.lua104
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-fonts-tfm.lua654
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-boolean.lua69
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-file.lua738
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-function.lua11
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-io.lua473
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-lpeg.lua1196
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-lua.lua259
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-math.lua149
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-string.lua244
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-table.lua1471
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-unicode.lua1405
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua349
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-reference-load-order.tex140
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-reference.lua38728
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-util-fil.lua452
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-util-str.lua1461
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua851
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-blacklist.cnf4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-characters.lua203947
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-colors.lua414
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-conf.pdfbin0 -> 77672 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-configuration.lua1034
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-database.lua3764
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua698
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-embolden.lua42
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-features.lua596
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-filelist.lua430
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua4313
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-init.lua781
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-latex.pdfbin0 -> 347111 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-latex.tex530
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-letterspace.lua578
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-loaders.lua240
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-log.lua394
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-main.lua313
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-main.tex2035
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-notdef.lua105
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-parsers.lua799
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-resolvers.lua303
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-status.lua90
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.1442
-rwxr-xr-xmacros/luatex/generic/luaotfload/luaotfload-tool.lua1661
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.pdfbin0 -> 76919 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.rst328
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-unicode.lua109
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.conf.5632
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.conf.example30
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.conf.rst409
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.sty53
-rw-r--r--macros/luatex/generic/luapackageloader/README.md22
-rw-r--r--macros/luatex/generic/luapackageloader/luapackageloader.lua71
-rw-r--r--macros/luatex/generic/luapackageloader/luapackageloader.pdfbin0 -> 34079 bytes
-rw-r--r--macros/luatex/generic/luapackageloader/luapackageloader.sty35
-rw-r--r--macros/luatex/generic/luapackageloader/luapackageloader.tex116
-rw-r--r--macros/luatex/generic/luatexbase/README.md7
-rw-r--r--macros/luatex/generic/luatexbase/luatexbase.dtx860
-rw-r--r--macros/luatex/generic/luatexbase/luatexbase.ins19
-rw-r--r--macros/luatex/generic/luatexbase/luatexbase.pdfbin0 -> 263467 bytes
-rw-r--r--macros/luatex/generic/luatexja/COPYING23
-rw-r--r--macros/luatex/generic/luatexja/README90
-rw-r--r--macros/luatex/generic/luatexja/doc/jfm-test.lua110
-rw-r--r--macros/luatex/generic/luatexja/doc/jfm-ujisc33.lua135
-rw-r--r--macros/luatex/generic/luatexja/doc/lltjp-geometry.pdfbin0 -> 140622 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/lltjp-geometry.tex288
-rw-r--r--macros/luatex/generic/luatexja/doc/ltjclasses.pdfbin0 -> 408511 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/ltjltxdoc.pdfbin0 -> 68494 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/ltjsclasses.pdfbin0 -> 504124 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja-en.pdfbin0 -> 474968 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja-ja.pdfbin0 -> 863227 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja-ruby.pdfbin0 -> 394907 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja-ruby.tex806
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja-zhfonts.pdfbin0 -> 563358 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja-zhfonts.tex280
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja.dtx11274
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja.ins10
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-adjust.sty144
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-ajmacros.sty844
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-25c.sty357
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-26h.sty412
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-27c.sty406
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-fontspec.sty60
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-otf.sty205
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-preset.sty706
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-ruby.sty210
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-zhfonts.sty77
-rw-r--r--macros/luatex/generic/luatexja/src/jfm-CCT.lua84
-rw-r--r--macros/luatex/generic/luatexja/src/jfm-banjiao.lua98
-rw-r--r--macros/luatex/generic/luatexja/src/jfm-jis.lua92
-rw-r--r--macros/luatex/generic/luatexja/src/jfm-kaiming.lua98
-rw-r--r--macros/luatex/generic/luatexja/src/jfm-min.lua261
-rw-r--r--macros/luatex/generic/luatexja/src/jfm-mono.lua9
-rw-r--r--macros/luatex/generic/luatexja/src/jfm-prop.lua9
-rw-r--r--macros/luatex/generic/luatexja/src/jfm-propv.lua9
-rw-r--r--macros/luatex/generic/luatexja/src/jfm-quanjiao.lua98
-rw-r--r--macros/luatex/generic/luatexja/src/jfm-tmin.lua189
-rw-r--r--macros/luatex/generic/luatexja/src/jfm-ujis.lua304
-rw-r--r--macros/luatex/generic/luatexja/src/jfm-ujisv.lua307
-rw-r--r--macros/luatex/generic/luatexja/src/lltjext.sty758
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-adjust.lua551
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-base.lua403
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-base.sty472
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-charrange.lua112
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-compat.lua140
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-debug.lua187
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-direction.lua1147
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-inputbuf.lua53
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-ivd_aj1.lua23096
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-jfmglue.lua1375
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-jfont.lua1028
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-jisx0208.lua6883
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-kinsoku_make.tex456
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-latex.sty91
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-lineskip.lua116
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-math.lua181
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-otf.lua296
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-plain.sty110
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-pretreat.lua188
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-rmlgbm.lua416
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-ruby.lua782
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-setwidth.lua311
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-stack.lua143
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-unicode-ccfix.lua276
-rw-r--r--macros/luatex/generic/luatexja/src/ltjclasses.dtx4676
-rw-r--r--macros/luatex/generic/luatexja/src/ltjclasses.ins28
-rw-r--r--macros/luatex/generic/luatexja/src/ltjltxdoc.dtx218
-rw-r--r--macros/luatex/generic/luatexja/src/ltjltxdoc.ins10
-rw-r--r--macros/luatex/generic/luatexja/src/ltjsclasses.dtx5709
-rw-r--r--macros/luatex/generic/luatexja/src/ltjsclasses.ins13
-rw-r--r--macros/luatex/generic/luatexja/src/luatexja-compat.sty140
-rw-r--r--macros/luatex/generic/luatexja/src/luatexja-core.sty742
-rw-r--r--macros/luatex/generic/luatexja/src/luatexja.lua601
-rw-r--r--macros/luatex/generic/luatexja/src/luatexja.sty61
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjcore.sty339
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjdefs.sty230
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjfont.sty874
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-array.sty26
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-fontspec.sty155
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-footmisc.sty58
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty513
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-listings.sty440
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-microtype.sty67
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-preview.sty22
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-siunitx.sty96
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-stfloats.sty27
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-tascmac.sty142
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-unicode-math.sty87
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-xunicode.sty99
-rw-r--r--macros/luatex/generic/luatexja/tool/blocks2defcharrange.rb25
-rw-r--r--macros/luatex/generic/luatexja/tool/chars2defcharrange.rb51
-rw-r--r--macros/luatex/generic/luatexja/tool/function_uax50.lua50
-rw-r--r--macros/luatex/generic/luatexja/tool/ivslist.tex58
-rwxr-xr-xmacros/luatex/generic/luatexja/tool/jfm-convert.lua281
-rw-r--r--macros/luatex/generic/luatexja/tool/jfm-readable.rb25
-rw-r--r--macros/luatex/generic/luatexja/tool/kyoikukanji.txt19
-rw-r--r--macros/luatex/generic/luatexja/tool/kyoikukanjiChars.tex1
-rwxr-xr-xmacros/luatex/generic/luatexja/tool/ltj-unicode-ccfix_make2.pl107
-rw-r--r--macros/luatex/generic/luatexja/tool/otf-AdobeMingStd-Light.txt13
-rw-r--r--macros/luatex/generic/luatexja/tool/otf-AdobeMyungjoStd-Medium.txt13
-rw-r--r--macros/luatex/generic/luatexja/tool/otf-AdobeSongStd-Light.txt12
-rw-r--r--macros/luatex/generic/luatexja/tool/otf-KozMinPr6N-Regular.txt38
-rw-r--r--macros/luatex/generic/luatexja/tool/table_ivd_aj1.lua32
-rw-r--r--macros/luatex/generic/luatexja/tool/table_jisx0208.lua112
-rw-r--r--macros/luatex/generic/luatexja/tool/unicodeBlocks.tex210
-rw-r--r--macros/luatex/generic/luatexko/ChangeLog235
-rw-r--r--macros/luatex/generic/luatexko/README151
-rw-r--r--macros/luatex/generic/luatexko/luatexko-doc.pdfbin0 -> 288860 bytes
-rw-r--r--macros/luatex/generic/luatexko/luatexko-doc.tex664
-rw-r--r--macros/luatex/generic/luatexko/luatexko-normalize.lua620
-rw-r--r--macros/luatex/generic/luatexko/luatexko-uhc2utf8.lua128
-rw-r--r--macros/luatex/generic/luatexko/luatexko.lua1969
-rw-r--r--macros/luatex/generic/luatexko/luatexko.sty728
l---------macros/luatex/generic/luatextra1
-rw-r--r--macros/luatex/generic/luavlna/README.md119
-rw-r--r--macros/luatex/generic/luavlna/luavlna-csplain-langs.lua21
-rw-r--r--macros/luatex/generic/luavlna/luavlna-doc.pdfbin0 -> 87293 bytes
-rw-r--r--macros/luatex/generic/luavlna/luavlna-doc.tex266
-rw-r--r--macros/luatex/generic/luavlna/luavlna-langno.lua119
-rw-r--r--macros/luatex/generic/luavlna/luavlna-predegrees.lua65
-rw-r--r--macros/luatex/generic/luavlna/luavlna-presi.lua30
-rw-r--r--macros/luatex/generic/luavlna/luavlna-si.lua38
-rw-r--r--macros/luatex/generic/luavlna/luavlna-sufdegrees.lua21
-rw-r--r--macros/luatex/generic/luavlna/luavlna.4ht5
-rw-r--r--macros/luatex/generic/luavlna/luavlna.lua314
-rw-r--r--macros/luatex/generic/luavlna/luavlna.sty24
-rw-r--r--macros/luatex/generic/luavlna/luavlna.tex103
-rw-r--r--macros/luatex/generic/luaxml/README37
-rw-r--r--macros/luatex/generic/luaxml/luaxml-cssquery.lua276
-rw-r--r--macros/luatex/generic/luaxml/luaxml-domobject.lua529
-rw-r--r--macros/luatex/generic/luaxml/luaxml-entities.lua37
-rw-r--r--macros/luatex/generic/luaxml/luaxml-mod-handler.lua359
-rw-r--r--macros/luatex/generic/luaxml/luaxml-mod-xml.lua565
-rw-r--r--macros/luatex/generic/luaxml/luaxml-namedentities.lua2233
-rw-r--r--macros/luatex/generic/luaxml/luaxml-parse-query.lua46
-rw-r--r--macros/luatex/generic/luaxml/luaxml-pretty.lua89
-rw-r--r--macros/luatex/generic/luaxml/luaxml-stack.lua67
-rw-r--r--macros/luatex/generic/luaxml/luaxml-testxml.lua147
-rw-r--r--macros/luatex/generic/luaxml/luaxml.pdfbin0 -> 98455 bytes
-rw-r--r--macros/luatex/generic/luaxml/luaxml.tex749
-rw-r--r--macros/luatex/generic/nodetree/README.md104
-rw-r--r--macros/luatex/generic/nodetree/nodetree.dtx2010
-rw-r--r--macros/luatex/generic/nodetree/nodetree.ins61
-rw-r--r--macros/luatex/generic/nodetree/nodetree.pdfbin0 -> 396294 bytes
-rw-r--r--macros/luatex/generic/spelling/CHANGES90
-rw-r--r--macros/luatex/generic/spelling/LICENSE416
-rw-r--r--macros/luatex/generic/spelling/README70
-rw-r--r--macros/luatex/generic/spelling/spelling-doc-lst-lua.tex84
-rw-r--r--macros/luatex/generic/spelling/spelling-doc.bad4
-rw-r--r--macros/luatex/generic/spelling/spelling-doc.pdfbin0 -> 128505 bytes
-rw-r--r--macros/luatex/generic/spelling/spelling-doc.tex830
-rw-r--r--macros/luatex/generic/spelling/spelling-main.lua220
-rw-r--r--macros/luatex/generic/spelling/spelling-recurse.lua110
-rw-r--r--macros/luatex/generic/spelling/spelling-stage-1.lua370
-rw-r--r--macros/luatex/generic/spelling/spelling-stage-2.lua675
-rw-r--r--macros/luatex/generic/spelling/spelling-stage-3.lua301
-rw-r--r--macros/luatex/generic/spelling/spelling-stage-4.lua202
-rw-r--r--macros/luatex/generic/spelling/spelling.sty150
-rw-r--r--macros/luatex/latex/addliga/README6
-rw-r--r--macros/luatex/latex/addliga/addliga.pdfbin0 -> 18477 bytes
-rw-r--r--macros/luatex/latex/addliga/addliga.sty22
-rw-r--r--macros/luatex/latex/addliga/addliga.tex33
-rw-r--r--macros/luatex/latex/arabluatex/README.md146
-rw-r--r--macros/luatex/latex/arabluatex/arabluatex.dtx5181
-rw-r--r--macros/luatex/latex/arabluatex/arabluatex.ins109
-rw-r--r--macros/luatex/latex/arabluatex/arabluatex.lua1187
-rw-r--r--macros/luatex/latex/arabluatex/arabluatex.pdfbin0 -> 685259 bytes
-rw-r--r--macros/luatex/latex/arabluatex/arabluatex_fullvoc.lua1015
-rw-r--r--macros/luatex/latex/arabluatex/arabluatex_novoc.lua166
-rw-r--r--macros/luatex/latex/arabluatex/arabluatex_trans.lua1018
-rw-r--r--macros/luatex/latex/arabluatex/arabluatex_voc.lua903
-rw-r--r--macros/luatex/latex/arabluatex/samples/al-Jahiz.pdfbin0 -> 114234 bytes
-rw-r--r--macros/luatex/latex/arabluatex/samples/al-Jahiz.tex178
-rw-r--r--macros/luatex/latex/arabluatex/samples/exporting.pdfbin0 -> 59687 bytes
-rw-r--r--macros/luatex/latex/arabluatex/samples/exporting.tex206
-rw-r--r--macros/luatex/latex/arabluatex/samples/template-01.pdfbin0 -> 65289 bytes
-rw-r--r--macros/luatex/latex/arabluatex/samples/template-01.tex109
-rw-r--r--macros/luatex/latex/beamer-rl/Example-of-use-ar.pdfbin0 -> 124480 bytes
-rw-r--r--macros/luatex/latex/beamer-rl/Example-of-use-ar.tex277
-rw-r--r--macros/luatex/latex/beamer-rl/Example-of-use-en.pdfbin0 -> 102473 bytes
-rw-r--r--macros/luatex/latex/beamer-rl/Example-of-use-en.tex266
-rw-r--r--macros/luatex/latex/beamer-rl/README.txt23
-rw-r--r--macros/luatex/latex/beamer-rl/beamer-rl.sty467
-rw-r--r--macros/luatex/latex/bezierplot/README21
-rw-r--r--macros/luatex/latex/bezierplot/bezierplot-doc.pdfbin0 -> 251276 bytes
-rw-r--r--macros/luatex/latex/bezierplot/bezierplot-doc.tex200
-rwxr-xr-xmacros/luatex/latex/bezierplot/bezierplot.lua940
-rw-r--r--macros/luatex/latex/bezierplot/bezierplot.sty17
-rw-r--r--macros/luatex/latex/cloze/README53
-rw-r--r--macros/luatex/latex/cloze/cloze.dtx2379
-rw-r--r--macros/luatex/latex/cloze/cloze.ins61
-rw-r--r--macros/luatex/latex/cloze/cloze.pdfbin0 -> 236534 bytes
-rw-r--r--macros/luatex/latex/combofont/README.md24
-rw-r--r--macros/luatex/latex/combofont/combofont-test-fira-math.pdfbin0 -> 15301 bytes
-rw-r--r--macros/luatex/latex/combofont/combofont-test-fira-math.tex125
-rw-r--r--macros/luatex/latex/combofont/combofont.pdfbin0 -> 78828 bytes
-rw-r--r--macros/luatex/latex/combofont/combofont.sty106
-rw-r--r--macros/luatex/latex/combofont/combofont.tex217
-rw-r--r--macros/luatex/latex/gurps/README.md19
-rw-r--r--macros/luatex/latex/gurps/gurps.dtx416
-rw-r--r--macros/luatex/latex/gurps/gurps.lua312
-rw-r--r--macros/luatex/latex/gurps/gurps.pdfbin0 -> 239743 bytes
-rw-r--r--macros/luatex/latex/gurps/gurps_tables.lua112
-rw-r--r--macros/luatex/latex/hmtrump/README.md63
-rw-r--r--macros/luatex/latex/hmtrump/by-sa.pngbin0 -> 11916 bytes
-rw-r--r--macros/luatex/latex/hmtrump/hmtrump-sample.pdfbin0 -> 420230 bytes
-rw-r--r--macros/luatex/latex/hmtrump/hmtrump-sample.tex189
-rw-r--r--macros/luatex/latex/hmtrump/hmtrump.pdfbin0 -> 609703 bytes
-rw-r--r--macros/luatex/latex/hmtrump/hmtrump.sty258
-rw-r--r--macros/luatex/latex/hmtrump/hmtrump.tex372
-rw-r--r--macros/luatex/latex/hmtrump/nkd04_playing_cards_index/LICENSE62
-rw-r--r--macros/luatex/latex/hmtrump/nkd04_playing_cards_index/nkd04_playing_cards_index.ttfbin0 -> 49152 bytes
-rw-r--r--macros/luatex/latex/hmtrump/nkd04_playing_cards_index/readme.txt55
-rw-r--r--macros/luatex/latex/lilyglyphs/CHANGES.md142
-rw-r--r--macros/luatex/latex/lilyglyphs/INSTALL44
-rw-r--r--macros/luatex/latex/lilyglyphs/README44
-rw-r--r--macros/luatex/latex/lilyglyphs/VERSION2
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-400.pngbin0 -> 38525 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-600.pngbin0 -> 78141 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-de.pdfbin0 -> 75153 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-de.tex91
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example.pdfbin0 -> 74791 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example.pngbin0 -> 102939 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example.tex89
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/lilyglyphs.pdfbin0 -> 539669 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/lilyglyphs.tex1429
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/lilyglyphs_logo/lilyglyphs_logo.pdfbin0 -> 22496 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/lilyglyphs_logo/lilyglyphs_logo.pngbin0 -> 9893 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/lilyglyphs_logo/lilyglyphs_logo.tex57
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-088c978c.pngbin0 -> 10336 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-1981c3c7.pngbin0 -> 9104 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-20e8632d.pngbin0 -> 70410 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-2abb8a04.pngbin0 -> 15011 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-2be182be.pngbin0 -> 5779 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-3b47d3fe.pngbin0 -> 6756 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-3f4afecc.pngbin0 -> 20569 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-40869867.pngbin0 -> 8021 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-5b13ce04.pngbin0 -> 18669 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-5c91a201.pngbin0 -> 57774 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-707477b7.pngbin0 -> 33720 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-76dbcd67.pngbin0 -> 9447 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-7fd84ff8.pngbin0 -> 2446 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-8155deab.pngbin0 -> 1144 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-8b332c94.pngbin0 -> 2226 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-8d82df0c.pngbin0 -> 4655 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-8d8bb8a3.pngbin0 -> 5948 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-907bc72d.pngbin0 -> 58314 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-a2bf82dd.pngbin0 -> 2686 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-ae3fd948.pngbin0 -> 1583 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-b3dc0958.pngbin0 -> 5776 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-b69af986.pngbin0 -> 20817 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-d9988a2c.pngbin0 -> 10241 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-dffaecd2.pngbin0 -> 2229 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lily-f4d0afc9.pngbin0 -> 5433 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lilyglyphsManualFonts.sty51
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lilyglyphsStyle.sty186
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/resources/lilypond-manuals.css469
-rw-r--r--macros/luatex/latex/lilyglyphs/documentation/the-feta-font-2-18-0.html571
-rw-r--r--macros/luatex/latex/lilyglyphs/fonts/FONTLOG23
-rw-r--r--macros/luatex/latex/lilyglyphs/fonts/LICENSE.OFL95
-rw-r--r--macros/luatex/latex/lilyglyphs/fonts/emmentaler-11.otfbin0 -> 160820 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/fonts/emmentaler-13.otfbin0 -> 160980 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/fonts/emmentaler-14.otfbin0 -> 160828 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/fonts/emmentaler-16.otfbin0 -> 160552 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/fonts/emmentaler-18.otfbin0 -> 160560 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/fonts/emmentaler-20.otfbin0 -> 160332 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/fonts/emmentaler-23.otfbin0 -> 160728 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/fonts/emmentaler-26.otfbin0 -> 160780 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/fonts/emmentaler-brace.otfbin0 -> 200704 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/license/COPYING.LPPL419
-rw-r--r--macros/luatex/latex/lilyglyphs/license/MANIFEST180
-rw-r--r--macros/luatex/latex/lilyglyphs/license/license-preamble.inp31
-rw-r--r--macros/luatex/latex/lilyglyphs/scripts/README-scripts3
-rwxr-xr-xmacros/luatex/latex/lilyglyphs/scripts/lily-glyph-commands.py136
-rwxr-xr-xmacros/luatex/latex/lilyglyphs/scripts/lily-image-commands.py321
-rwxr-xr-xmacros/luatex/latex/lilyglyphs/scripts/lily-rebuild-pdfs.py142
-rw-r--r--macros/luatex/latex/lilyglyphs/scripts/lilyglyphs_common.py360
-rw-r--r--macros/luatex/latex/lilyglyphs/source/fonts/README-emmentaler8
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/_template.ly54
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/beamednotes.ly111
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/dynamicsigns.ly62
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/fancyexamples.ly61
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/score.ily49
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/singlenotes.ly377
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/singlenotes.pdfbin0 -> 25328 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crescHairpin.ly69
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchet.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDotted.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDottedDouble.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDottedDoubleDown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDottedDown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-decrescHairpin.ly69
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaver.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDotted.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDottedDouble.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDottedDoubleDown.ly72
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDottedDown.ly72
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDown.ly72
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-fancyExample.ly74
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNote.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDotted.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDottedDouble.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDottedDoubleDown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDottedDown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaver.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDotted.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDouble.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDoubleDdown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDoubleDown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaver.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDotted.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDottedDouble.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDottedDoubleDown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDottedDown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDown.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuavers.ly71
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuaversI.ly72
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuaversII.ly72
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuaversIII.ly72
-rw-r--r--macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-twoBeamedQuavers.ly70
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/README-tex7
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/README-commands2
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/accidentals.inp120
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/accordion.inp116
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/beamednotes.inp81
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/clefs.inp76
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/dynamics.inp97
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/fancyexamples.inp51
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/noteheads.inp48
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/numbers.inp53
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/rests.inp141
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/scripts.inp121
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/singlenotes.inp321
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/commands/timesignatures.inp63
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/core/README-core2
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/core/dotted.inp114
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/core/genericAccess.inp189
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/core/keyval.inp100
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/core/opticals.inp55
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/lilyglyphs.sty103
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crescHairpin.pdfbin0 -> 2421 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchet.pdfbin0 -> 8799 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDotted.pdfbin0 -> 9104 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDottedDouble.pdfbin0 -> 9111 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDottedDoubleDown.pdfbin0 -> 9109 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDottedDown.pdfbin0 -> 9102 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDown.pdfbin0 -> 8798 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-decrescHairpin.pdfbin0 -> 2421 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaver.pdfbin0 -> 9148 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDotted.pdfbin0 -> 9226 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDottedDouble.pdfbin0 -> 9230 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDottedDoubleDown.pdfbin0 -> 9226 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDottedDown.pdfbin0 -> 9220 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDown.pdfbin0 -> 9145 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-fancyExample.pdfbin0 -> 9140 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNote.pdfbin0 -> 8778 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDotted.pdfbin0 -> 9086 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDottedDouble.pdfbin0 -> 9092 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDottedDoubleDown.pdfbin0 -> 9088 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDottedDown.pdfbin0 -> 9082 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDown.pdfbin0 -> 8774 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaver.pdfbin0 -> 9209 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDotted.pdfbin0 -> 9285 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDouble.pdfbin0 -> 9289 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDoubleDdown.pdfbin0 -> 9000 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDoubleDown.pdfbin0 -> 9000 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDown.pdfbin0 -> 8995 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDown.pdfbin0 -> 8921 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaver.pdfbin0 -> 9296 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDotted.pdfbin0 -> 9371 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDottedDouble.pdfbin0 -> 9376 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDottedDoubleDown.pdfbin0 -> 9092 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDottedDown.pdfbin0 -> 9086 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDown.pdfbin0 -> 9015 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuavers.pdfbin0 -> 8804 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuaversI.pdfbin0 -> 9081 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuaversII.pdfbin0 -> 9074 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuaversIII.pdfbin0 -> 9075 bytes
-rw-r--r--macros/luatex/latex/lilyglyphs/tex/pdfs/lily-twoBeamedQuavers.pdfbin0 -> 8870 bytes
l---------macros/luatex/latex/lua-check-hyphen/README.md1
-rw-r--r--macros/luatex/latex/lua-check-hyphen/doc/README.md27
-rw-r--r--macros/luatex/latex/lua-check-hyphen/doc/luacheckhyphenmanual.pdfbin0 -> 112214 bytes
-rw-r--r--macros/luatex/latex/lua-check-hyphen/doc/luacheckhyphenmanual.tex173
-rw-r--r--macros/luatex/latex/lua-check-hyphen/doc/mit-license.txt19
-rw-r--r--macros/luatex/latex/lua-check-hyphen/doc/sample.pdfbin0 -> 5268 bytes
-rw-r--r--macros/luatex/latex/lua-check-hyphen/doc/sample.tex10
-rw-r--r--macros/luatex/latex/lua-check-hyphen/lua-check-hyphen.lua284
-rw-r--r--macros/luatex/latex/lua-check-hyphen/lua-check-hyphen.sty44
-rw-r--r--macros/luatex/latex/luabibentry/Makefile100
-rw-r--r--macros/luatex/latex/luabibentry/News6
-rw-r--r--macros/luatex/latex/luabibentry/README45
-rw-r--r--macros/luatex/latex/luabibentry/luabibentry.dtx401
-rw-r--r--macros/luatex/latex/luabibentry/luabibentry.pdfbin0 -> 157304 bytes
-rw-r--r--macros/luatex/latex/luabidi/LICENCE.md6
-rw-r--r--macros/luatex/latex/luabidi/README.md8
-rw-r--r--macros/luatex/latex/luabidi/doc/test.tex13
-rw-r--r--macros/luatex/latex/luabidi/tex/arabmaths.tex2
-rw-r--r--macros/luatex/latex/luabidi/tex/autofootnoterule.tex116
-rw-r--r--macros/luatex/latex/luabidi/tex/luabidi.sty56
-rw-r--r--macros/luatex/latex/luabidi/tex/textwidthfootnoterule.tex2
-rw-r--r--macros/luatex/latex/luacode/Makefile90
-rw-r--r--macros/luatex/latex/luacode/News13
-rw-r--r--macros/luatex/latex/luacode/README43
-rw-r--r--macros/luatex/latex/luacode/luacode.dtx723
-rw-r--r--macros/luatex/latex/luacode/luacode.pdfbin0 -> 410840 bytes
-rw-r--r--macros/luatex/latex/luahyphenrules/README.md15
-rw-r--r--macros/luatex/latex/luahyphenrules/luahyphenrules.pdfbin0 -> 37590 bytes
-rw-r--r--macros/luatex/latex/luahyphenrules/luahyphenrules.sty161
-rw-r--r--macros/luatex/latex/luahyphenrules/luahyphenrules.tex114
-rw-r--r--macros/luatex/latex/luaimageembed/LICENSE21
-rw-r--r--macros/luatex/latex/luaimageembed/README.md41
-rw-r--r--macros/luatex/latex/luaimageembed/luaimageembed.sty85
-rw-r--r--macros/luatex/latex/luaindex/README55
-rw-r--r--macros/luatex/latex/luaindex/luaindex.dtx1602
-rw-r--r--macros/luatex/latex/luaindex/luaindex.pdfbin0 -> 122907 bytes
-rw-r--r--macros/luatex/latex/luainputenc/Makefile94
-rw-r--r--macros/luatex/latex/luainputenc/NEWS27
-rw-r--r--macros/luatex/latex/luainputenc/README78
-rw-r--r--macros/luatex/latex/luainputenc/luainputenc.dtx1464
-rw-r--r--macros/luatex/latex/luainputenc/luainputenc.pdfbin0 -> 404095 bytes
-rw-r--r--macros/luatex/latex/lualatex-math/MANIFEST14
-rw-r--r--macros/luatex/latex/lualatex-math/README48
-rw-r--r--macros/luatex/latex/lualatex-math/lualatex-math.dtx724
-rw-r--r--macros/luatex/latex/lualatex-math/lualatex-math.ins88
-rw-r--r--macros/luatex/latex/lualatex-math/lualatex-math.pdfbin0 -> 190559 bytes
-rw-r--r--macros/luatex/latex/lualatex-truncate/README.md36
-rw-r--r--macros/luatex/latex/lualatex-truncate/lualatex-truncate-doc.dtx262
-rw-r--r--macros/luatex/latex/lualatex-truncate/lualatex-truncate-doc.pdfbin0 -> 63410 bytes
-rw-r--r--macros/luatex/latex/lualatex-truncate/lualatex-truncate.dtx166
-rw-r--r--macros/luatex/latex/lualatex-truncate/lualatex-truncate.ins41
-rw-r--r--macros/luatex/latex/luamesh/README47
-rw-r--r--macros/luatex/latex/luamesh/doc/animation-crop.pdfbin0 -> 382796 bytes
-rw-r--r--macros/luatex/latex/luamesh/doc/biblio.bib92
-rw-r--r--macros/luatex/latex/luamesh/doc/dum.tex6
-rw-r--r--macros/luatex/latex/luamesh/doc/fond.mp21
-rw-r--r--macros/luatex/latex/luamesh/doc/fond.pdfbin0 -> 1309 bytes
-rw-r--r--macros/luatex/latex/luamesh/doc/lltxdoc.cls105
-rw-r--r--macros/luatex/latex/luamesh/doc/luamesh-doc.listing84
-rw-r--r--macros/luatex/latex/luamesh/doc/luamesh-doc.pdfbin0 -> 168735 bytes
-rw-r--r--macros/luatex/latex/luamesh/doc/luamesh-doc.tex1219
-rw-r--r--macros/luatex/latex/luamesh/doc/luamesh-title.pdfbin0 -> 4225 bytes
-rw-r--r--macros/luatex/latex/luamesh/doc/maillage.geo9
-rw-r--r--macros/luatex/latex/luamesh/doc/maillage.msh160
-rw-r--r--macros/luatex/latex/luamesh/doc/mesh.txt7
-rw-r--r--macros/luatex/latex/luamesh/doc/meshgarde.txt9
-rw-r--r--macros/luatex/latex/luamesh/scripts/luamesh-polygon.lua87
-rw-r--r--macros/luatex/latex/luamesh/scripts/luamesh-tex.lua998
-rw-r--r--macros/luatex/latex/luamesh/scripts/luamesh.lua545
-rw-r--r--macros/luatex/latex/luamesh/tex/luamesh.sty984
-rw-r--r--macros/luatex/latex/luarandom/Changes4
-rw-r--r--macros/luatex/latex/luarandom/README12
-rw-r--r--macros/luatex/latex/luarandom/doc/luarandom-doc.pdfbin0 -> 49787 bytes
-rw-r--r--macros/luatex/latex/luarandom/doc/luarandom-doc.tex90
-rw-r--r--macros/luatex/latex/luarandom/latex/luarandom.sty76
-rw-r--r--macros/luatex/latex/luasseq/README6
-rw-r--r--macros/luatex/latex/luasseq/luasseq.dtx992
-rw-r--r--macros/luatex/latex/luasseq/luasseq.ins4
-rw-r--r--macros/luatex/latex/luasseq/luasseq.lua894
-rw-r--r--macros/luatex/latex/luasseq/luasseq.pdfbin0 -> 224059 bytes
-rw-r--r--macros/luatex/latex/luatextra/Makefile92
-rw-r--r--macros/luatex/latex/luatextra/News58
-rw-r--r--macros/luatex/latex/luatextra/README37
-rw-r--r--macros/luatex/latex/luatextra/luatextra.dtx200
-rw-r--r--macros/luatex/latex/luatextra/luatextra.pdfbin0 -> 315129 bytes
-rw-r--r--macros/luatex/latex/luatodonotes/README.md35
-rw-r--r--macros/luatex/latex/luatodonotes/inspect.lua297
-rw-r--r--macros/luatex/latex/luatodonotes/luatodonotes.dtx2082
-rw-r--r--macros/luatex/latex/luatodonotes/luatodonotes.ins75
-rw-r--r--macros/luatex/latex/luatodonotes/luatodonotes.lua2231
-rw-r--r--macros/luatex/latex/luatodonotes/luatodonotes.pdfbin0 -> 212809 bytes
-rw-r--r--macros/luatex/latex/luatodonotes/path_line.lua120
-rw-r--r--macros/luatex/latex/luatodonotes/path_point.lua73
-rw-r--r--macros/luatex/latex/makecookbook/README.old109
-rw-r--r--macros/luatex/latex/makecookbook/README.txt110
-rw-r--r--macros/luatex/latex/makecookbook/makecookbook-doc.pdfbin0 -> 292770 bytes
-rw-r--r--macros/luatex/latex/makecookbook/makecookbook-doc.tex1819
-rw-r--r--macros/luatex/latex/makecookbook/mycookbook/cb-idxstyle.ist16
-rw-r--r--macros/luatex/latex/makecookbook/mycookbook/cb-lettrine.cfl44
-rw-r--r--macros/luatex/latex/makecookbook/mycookbook/cb-preamble.tex762
-rw-r--r--macros/luatex/latex/makecookbook/mycookbook/img/image-a.jpgbin0 -> 12904 bytes
-rw-r--r--macros/luatex/latex/makecookbook/mycookbook/img/image-b.jpgbin0 -> 12940 bytes
-rw-r--r--macros/luatex/latex/makecookbook/mycookbook/makecookbook.pdfbin0 -> 248344 bytes
-rw-r--r--macros/luatex/latex/makecookbook/mycookbook/makecookbook.tex24
-rw-r--r--macros/luatex/latex/makecookbook/mycookbook/tex/cb-chapterA.tex413
-rw-r--r--macros/luatex/latex/makecookbook/mycookbook/tex/cb-chapterB.tex121
-rw-r--r--macros/luatex/latex/makecookbook/mycookbook/tex/cb-frontmatter.tex66
-rw-r--r--macros/luatex/latex/novel/README.md30
-rw-r--r--macros/luatex/latex/novel/doc/extras/CPmodified.otfbin0 -> 51972 bytes
-rw-r--r--macros/luatex/latex/novel/doc/extras/NovelDeco-glyphs.pdfbin0 -> 42202 bytes
-rw-r--r--macros/luatex/latex/novel/doc/extras/novel-Gallery-ChapterStart.pdfbin0 -> 311166 bytes
-rw-r--r--macros/luatex/latex/novel/doc/extras/novel-example.tex127
-rw-r--r--macros/luatex/latex/novel/doc/extras/novel-extras-README.html36
-rw-r--r--macros/luatex/latex/novel/doc/extras/novel-testimage.jpgbin0 -> 1990 bytes
-rw-r--r--macros/luatex/latex/novel/doc/extras/novel-testimage.pngbin0 -> 1908 bytes
-rw-r--r--macros/luatex/latex/novel/doc/extras/novel-testscript.jpgbin0 -> 2456 bytes
-rw-r--r--macros/luatex/latex/novel/doc/extras/novel-testscript.pngbin0 -> 2064 bytes
-rw-r--r--macros/luatex/latex/novel/doc/extras/novel-testsuite.tex312
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/10transold.pngbin0 -> 563 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/10trueold.pngbin0 -> 608 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/CPmodified-sample.pngbin0 -> 5898 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/I-shade.pngbin0 -> 5508 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/Iboxcap.pngbin0 -> 7616 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/acronym2.pngbin0 -> 5475 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/alphabetagamma.pngbin0 -> 11185 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/authorsnote.pngbin0 -> 142528 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/badaboom.pngbin0 -> 4711 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/bixby-original.pngbin0 -> 239173 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/bixby-softproof.pngbin0 -> 246911 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/bookmanglerdashboard.pngbin0 -> 22434 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/bookofbeirh.pngbin0 -> 22144 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/chaptertitlesubtitle.pngbin0 -> 21460 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/charscaletext.pngbin0 -> 10831 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/closecrop.pngbin0 -> 19382 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/colormax-original.pngbin0 -> 12701 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/colormax-softproof.pngbin0 -> 14287 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/colorsampler-softproof.pngbin0 -> 95659 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/colorsampler.pngbin0 -> 54423 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/cropmarks.pngbin0 -> 22507 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/cropview.pngbin0 -> 19907 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/ctimg35.pngbin0 -> 4523 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/doordie.pngbin0 -> 39286 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/dorfmcnorf.pngbin0 -> 2349 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/dropcap-antestar.pngbin0 -> 6548 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/dropcap-gap.pngbin0 -> 6181 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/dropcap-scalebloat.pngbin0 -> 6806 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/dropcap.pngbin0 -> 18252 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/emblembar.pngbin0 -> 5479 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/emblemdingbats.pngbin0 -> 6019 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/emblemimg.pngbin0 -> 7415 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/endnotetext.pngbin0 -> 27873 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/firstletterspecial.pngbin0 -> 17688 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/firstlinespecial.pngbin0 -> 17690 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/fluffy-conspiracy.pngbin0 -> 8518 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/font-tree.pngbin0 -> 15268 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/fontbyfamily.pngbin0 -> 5151 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/fontbyfilenamei.pngbin0 -> 4331 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/fpaper.pngbin0 -> 8144 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/frankenfont.pngbin0 -> 5029 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/gnome-censored.pngbin0 -> 37436 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/graytext.pngbin0 -> 9856 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/head-foot-jumps.pngbin0 -> 15625 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/headfont-default.pngbin0 -> 8187 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/headfont-montserrat-el.pngbin0 -> 7254 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/headfont-roboto.pngbin0 -> 7940 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/headfoot1.pngbin0 -> 14569 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/headfoot2.pngbin0 -> 14028 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/headfoot3.pngbin0 -> 14028 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/headfoot4.pngbin0 -> 14605 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/headfoot5.pngbin0 -> 14973 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/headfoot6.pngbin0 -> 14429 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/human-robot-talk.pngbin0 -> 16097 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/imgdialogs.pngbin0 -> 33975 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/info18.pngbin0 -> 1288 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/inlineimagest.pngbin0 -> 42231 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/jackbequick.pngbin0 -> 12057 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/jollybeers.pngbin0 -> 7043 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/jpgcolorspace.pngbin0 -> 4533 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/jump-change.pngbin0 -> 69093 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/looseheads.pngbin0 -> 6412 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/lowdown.pngbin0 -> 17173 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/map.pngbin0 -> 7449 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/margins-trim-media.pngbin0 -> 30606 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/mcdingle.pngbin0 -> 20701 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/mediasize.pngbin0 -> 30516 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/megadocprops.pngbin0 -> 24517 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/megatitlepagesm.pngbin0 -> 8567 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/monitorgamut.pngbin0 -> 18804 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/no-brainer.pngbin0 -> 34282 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/novel-color-sampler.pngbin0 -> 80977 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/overflowrule.pngbin0 -> 15026 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/page-leaf.pngbin0 -> 12898 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/parascale.pngbin0 -> 36954 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/perfectbinding.pngbin0 -> 10407 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/pngcolortype.pngbin0 -> 4599 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/printgamut.pngbin0 -> 19633 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/quickchapter.pngbin0 -> 33749 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/raffaelino-original.pngbin0 -> 246157 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/raffaelino-softproof.pngbin0 -> 241149 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/robberies.pngbin0 -> 9411 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/scenebreaks.pngbin0 -> 25213 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/shademargins.pngbin0 -> 30022 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/shakepi.pngbin0 -> 1894 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/signature.pngbin0 -> 5233 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/simpletoc.pngbin0 -> 18412 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/sixpage-frontmatter.pngbin0 -> 9584 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/skygrad.jpgbin0 -> 56275 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/smallcapsrealfake.pngbin0 -> 5448 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/smfingerprint8.pngbin0 -> 13322 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/smythsewn.pngbin0 -> 7134 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/toc.pngbin0 -> 13553 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/topmargins.pngbin0 -> 12250 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/trdol.pngbin0 -> 27867 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/trimsize.pngbin0 -> 41850 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/ublibser.pngbin0 -> 34135 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/unsafe-vs-margin.pngbin0 -> 19235 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/whichgutter.pngbin0 -> 19012 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/win10libser.pngbin0 -> 10690 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/workedforme.pngbin0 -> 62302 bytes
-rw-r--r--macros/luatex/latex/novel/doc/html-resources/wrapme.pngbin0 -> 4256 bytes
-rw-r--r--macros/luatex/latex/novel/doc/novel-documentation.html3270
-rw-r--r--macros/luatex/latex/novel/doc/novel.pdf860
-rw-r--r--macros/luatex/latex/novel/doc/novel.tex125
-rw-r--r--macros/luatex/latex/novel/fonts/NovelDeco.otfbin0 -> 132000 bytes
-rw-r--r--macros/luatex/latex/novel/novel-CGATSTR001.clo28
-rw-r--r--macros/luatex/latex/novel/novel-CalculateLayout.sty328
-rw-r--r--macros/luatex/latex/novel/novel-ChapterScene.sty406
-rw-r--r--macros/luatex/latex/novel/novel-DropCap.sty235
-rw-r--r--macros/luatex/latex/novel/novel-FOGRA39.clo27
-rw-r--r--macros/luatex/latex/novel/novel-FileData.sty208
-rw-r--r--macros/luatex/latex/novel/novel-Fonts.sty416
-rw-r--r--macros/luatex/latex/novel/novel-Footnotes.sty431
-rw-r--r--macros/luatex/latex/novel/novel-HeadFootStyles.sty498
-rw-r--r--macros/luatex/latex/novel/novel-Images.sty567
-rw-r--r--macros/luatex/latex/novel/novel-JC200103.clo27
-rw-r--r--macros/luatex/latex/novel/novel-LayoutSettings.sty435
-rw-r--r--macros/luatex/latex/novel/novel-Obsolete.sty485
-rw-r--r--macros/luatex/latex/novel/novel-PostLayout.sty263
-rw-r--r--macros/luatex/latex/novel/novel-Sandbox.sty145
-rw-r--r--macros/luatex/latex/novel/novel-TextMacros.sty587
-rw-r--r--macros/luatex/latex/novel/novel-microtype.cfg252
-rw-r--r--macros/luatex/latex/novel/novel-pdfx.sty517
-rw-r--r--macros/luatex/latex/novel/novel-xmppacket.sty186
-rw-r--r--macros/luatex/latex/novel/novel.cls678
-rw-r--r--macros/luatex/latex/odsfile/README53
-rw-r--r--macros/luatex/latex/odsfile/odsfile.lua300
-rw-r--r--macros/luatex/latex/odsfile/odsfile.pdfbin0 -> 253761 bytes
-rw-r--r--macros/luatex/latex/odsfile/odsfile.sty256
-rw-r--r--macros/luatex/latex/odsfile/odsfile.tex404
-rw-r--r--macros/luatex/latex/odsfile/pokus.odsbin0 -> 15481 bytes
-rw-r--r--macros/luatex/latex/pdfarticle/README6
-rw-r--r--macros/luatex/latex/pdfarticle/pdfArticle.cls162
-rw-r--r--macros/luatex/latex/pdfarticle/pdfArticle.pdfbin0 -> 41590 bytes
-rw-r--r--macros/luatex/latex/pdfarticle/pdfArticle.tex125
-rw-r--r--macros/luatex/latex/pgfmolbio/README18
-rw-r--r--macros/luatex/latex/pgfmolbio/SampleGff.gff14
-rw-r--r--macros/luatex/latex/pgfmolbio/SampleScf.scfbin0 -> 135018 bytes
-rw-r--r--macros/luatex/latex/pgfmolbio/SampleUniprot.txt19
-rw-r--r--macros/luatex/latex/pgfmolbio/pgfmolbio.dtx5135
-rw-r--r--macros/luatex/latex/pgfmolbio/pgfmolbio.ins102
-rw-r--r--macros/luatex/latex/pgfmolbio/pgfmolbio.pdfbin0 -> 852998 bytes
-rw-r--r--macros/luatex/latex/placeat/README.md18
-rw-r--r--macros/luatex/latex/placeat/placeat.dtx813
-rw-r--r--macros/luatex/latex/placeat/placeat.lua162
-rw-r--r--macros/luatex/latex/placeat/placeat.pdfbin0 -> 97006 bytes
-rw-r--r--macros/luatex/latex/placeat/placeat.sty223
-rw-r--r--macros/luatex/latex/placeat/placeat.tex17
-rw-r--r--macros/luatex/latex/plantuml/CHANGELOG.md50
-rw-r--r--macros/luatex/latex/plantuml/README.md104
-rw-r--r--macros/luatex/latex/plantuml/example-class-relations--latex.tex19
-rw-r--r--macros/luatex/latex/plantuml/example-class-relations--svg.pngbin0 -> 13997 bytes
-rw-r--r--macros/luatex/latex/plantuml/example-class-relations--svg.tex26
-rw-r--r--macros/luatex/latex/plantuml/example-minimal.pngbin0 -> 4829 bytes
-rw-r--r--macros/luatex/latex/plantuml/example-minimal.tex9
-rw-r--r--macros/luatex/latex/plantuml/plantuml.lua48
-rw-r--r--macros/luatex/latex/plantuml/plantuml.pdfbin0 -> 47135 bytes
-rw-r--r--macros/luatex/latex/plantuml/plantuml.sty101
-rwxr-xr-xmacros/luatex/latex/plantuml/release.sh11
-rw-r--r--macros/luatex/latex/selnolig/README25
-rw-r--r--macros/luatex/latex/selnolig/gpp-ft.fea23
-rw-r--r--macros/luatex/latex/selnolig/selnolig-bugreport.tex35
-rw-r--r--macros/luatex/latex/selnolig/selnolig-english-hyphex.sty212
-rw-r--r--macros/luatex/latex/selnolig/selnolig-english-patterns.sty1125
-rw-r--r--macros/luatex/latex/selnolig/selnolig-english-test.pdfbin0 -> 81746 bytes
-rw-r--r--macros/luatex/latex/selnolig/selnolig-english-test.tex109
-rw-r--r--macros/luatex/latex/selnolig/selnolig-english-wordlist.tex762
-rw-r--r--macros/luatex/latex/selnolig/selnolig-german-hyphex.sty6402
-rw-r--r--macros/luatex/latex/selnolig/selnolig-german-patterns.sty2017
-rw-r--r--macros/luatex/latex/selnolig/selnolig-german-test.pdfbin0 -> 32239 bytes
-rw-r--r--macros/luatex/latex/selnolig/selnolig-german-test.tex61
-rw-r--r--macros/luatex/latex/selnolig/selnolig-german-wordlist.tex987
-rw-r--r--macros/luatex/latex/selnolig/selnolig.lua201
-rw-r--r--macros/luatex/latex/selnolig/selnolig.pdfbin0 -> 358610 bytes
-rw-r--r--macros/luatex/latex/selnolig/selnolig.sty267
-rw-r--r--macros/luatex/latex/selnolig/selnolig.tex1331
-rw-r--r--macros/luatex/latex/showhyphens/README11
-rw-r--r--macros/luatex/latex/showhyphens/showhyphens-doc.pdfbin0 -> 83289 bytes
-rw-r--r--macros/luatex/latex/showhyphens/showhyphens-doc.tex102
-rw-r--r--macros/luatex/latex/showhyphens/showhyphens-sample.pdfbin0 -> 17790 bytes
-rw-r--r--macros/luatex/latex/showhyphens/showhyphens.sty68
l---------macros/luatex/latex/simurgh/README1
-rw-r--r--macros/luatex/latex/simurgh/doc/ChangeLog25
-rw-r--r--macros/luatex/latex/simurgh/doc/README17
-rw-r--r--macros/luatex/latex/simurgh/doc/simurgh-doc.pdfbin0 -> 117941 bytes
-rw-r--r--macros/luatex/latex/simurgh/doc/simurgh-doc.tex658
-rw-r--r--macros/luatex/latex/simurgh/doc/simurgh-logo.pdfbin0 -> 17869 bytes
-rw-r--r--macros/luatex/latex/simurgh/doc/simurgh-logo.tex1483
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-abjad.sty51
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-adadi.sty109
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-algorithm.sty8
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-algorithmic.sty7
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-amsart.sty118
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-amsbook.sty117
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-amsmath.sty128
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-amstext.sty9
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-amsthm.sty4
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-array.sty61
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-article.sty77
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-artikel1.sty59
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-artikel2.sty56
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-artikel3.sty58
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-arydshln.sty90
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-backref.sty24
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-bidi.sty108
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-boek.sty72
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-boek3.sty70
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-book.sty93
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-bookest.sty43
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-caption3.sty7
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-char-def.lua193863
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-char-ini.lua1191
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-chkeng.sty18
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-clss.sty48
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-counters.sty7
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-cptns.sty23
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-doc.cls247
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-empheq.sty132
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-extarticle.sty85
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-extbook.sty85
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-extletter.sty41
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-extreport.sty85
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-fleqn.sty27
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-fonts.sty128
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-footnotes.sty361
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-ftnxtra.sty189
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-glossaries.sty79
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-harfi.sty10
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-jalalical.sty176
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-leqno.sty13
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-letter.sty30
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-lettrine.sty96
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-loader.sty12
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-ltx.sty668
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-mathdigitspec.sty206
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-memoir.sty48
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-minitoc.sty14
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-natbib.sty258
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-pkgs.sty17
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-poem.sty271
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-rapport1.sty68
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-rapport3.sty66
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-refrep.sty66
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-report.sty90
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-scrartcl.sty296
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-scrbook.sty328
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-scrlettr.sty117
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-scrreprt.sty315
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-shellescape.sty10
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-tags.sty7
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-tartibi.sty97
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-tools.sty507
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-unibidi-core.lua375
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-unibidi-ini.lua219
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-unibidi-math.lua152
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-unibidi.lua319
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh-unibidi.sty23
-rw-r--r--macros/luatex/latex/simurgh/tex/simurgh.sty93
-rw-r--r--macros/luatex/latex/typewriter/README.md10
-rw-r--r--macros/luatex/latex/typewriter/typewriter-guide.pdfbin0 -> 101048 bytes
-rw-r--r--macros/luatex/latex/typewriter/typewriter-guide.tex121
-rw-r--r--macros/luatex/latex/typewriter/typewriter.sty2798
-rw-r--r--macros/luatex/latex/wallcalendar/LICENSE.txt7
-rw-r--r--macros/luatex/latex/wallcalendar/README.md29
-rw-r--r--macros/luatex/latex/wallcalendar/doc/Makefile10
-rw-r--r--macros/luatex/latex/wallcalendar/doc/auto/wallcalendar-code.el243
-rw-r--r--macros/luatex/latex/wallcalendar/doc/auto/wallcalendar.el71
-rw-r--r--macros/luatex/latex/wallcalendar/doc/doc-setup.org9
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/Makefile61
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-plain-01.pdfbin0 -> 246084 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-plain-02.pdfbin0 -> 246072 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-plain-03.pdfbin0 -> 245527 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showframe-01.pdfbin0 -> 9581 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showframe-02.pdfbin0 -> 9561 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showframe-03.pdfbin0 -> 9561 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showtrims-01.pdfbin0 -> 253986 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showtrims-02.pdfbin0 -> 253952 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showtrims-03.pdfbin0 -> 253425 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-varnishmask-01.pdfbin0 -> 9088 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-varnishmask-02.pdfbin0 -> 9076 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-varnishmask-03.pdfbin0 -> 9077 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-marks.pdfbin0 -> 413256 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-marks.tex50
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-plain.pdfbin0 -> 248558 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-plain.tex7
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-showframe.pdfbin0 -> 10259 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-showframe.tex9
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-showtrims.pdfbin0 -> 256061 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-showtrims.tex8
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-thumbnails.pdfbin0 -> 192915 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-thumbnails.tex200
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-translations-english.pdfbin0 -> 422090 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-translations-english.tex16
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-translations-hungarian.pdfbin0 -> 422049 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-translations-hungarian.tex16
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-translations-japanese.pdfbin0 -> 573551 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-translations-japanese.tex18
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-varnishmask.pdfbin0 -> 9215 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-varnishmask.tex9
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-year-planner.pdfbin0 -> 18924 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/cal-year-planner.tex75
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/data/astro-2018.json1
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/data/holidays.csv10
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/data/mark_defaults.csv3
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/data/moonphases.csv51
-rwxr-xr-xmacros/luatex/latex/wallcalendar/doc/examples/diff-cal.sh40
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/forest.tex116
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/frog-english.tex16
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/frog-hungarian.tex16
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/frog-japanese.tex16
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/frog.tex19
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/local-english.sty6
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/local-hungarian.sty6
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/local-japanese.sty23
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/photos/frog-crop-thumb.jpgbin0 -> 184006 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/photos/frog-crop.jpgbin0 -> 399868 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/photos/frog.jpgbin0 -> 630222 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/examples/photos/obscure-crop.jpgbin0 -> 219675 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/doc/frontpage.tex103
-rw-r--r--macros/luatex/latex/wallcalendar/doc/latexmkrc4
-rw-r--r--macros/luatex/latex/wallcalendar/doc/local.sty70
-rw-r--r--macros/luatex/latex/wallcalendar/doc/memoir-article.cls401
-rw-r--r--macros/luatex/latex/wallcalendar/doc/wallcalendar-code.fdb_latexmk315
-rw-r--r--macros/luatex/latex/wallcalendar/doc/wallcalendar-code.fls1072
-rw-r--r--macros/luatex/latex/wallcalendar/doc/wallcalendar-code.org2238
-rw-r--r--macros/luatex/latex/wallcalendar/doc/wallcalendar-code.tex2371
-rw-r--r--macros/luatex/latex/wallcalendar/doc/wallcalendar.org1125
-rw-r--r--macros/luatex/latex/wallcalendar/doc/wallcalendar.tex1190
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-czech.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-dutch.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-english.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-french.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-german.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-hungarian.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-italian.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-japanese.tex35
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-norwegian.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-portuguese.tex35
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-romanian.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-serbian.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-slovakian.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-slovenian.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-spanish.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-swedish.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/i18n/wallcalendar-thai.tex36
-rw-r--r--macros/luatex/latex/wallcalendar/wallcalendar-code.pdfbin0 -> 182922 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/wallcalendar-csv.lua557
-rw-r--r--macros/luatex/latex/wallcalendar/wallcalendar-date.lua747
-rw-r--r--macros/luatex/latex/wallcalendar/wallcalendar-helpers.lua279
-rw-r--r--macros/luatex/latex/wallcalendar/wallcalendar-layouts.pngbin0 -> 704910 bytes
-rw-r--r--macros/luatex/latex/wallcalendar/wallcalendar.cls1714
-rw-r--r--macros/luatex/latex/wallcalendar/wallcalendar.pdfbin0 -> 2896302 bytes
1061 files changed, 785704 insertions, 0 deletions
diff --git a/macros/luatex/generic/chickenize/README.md b/macros/luatex/generic/chickenize/README.md
new file mode 100644
index 0000000000..0943366201
--- /dev/null
+++ b/macros/luatex/generic/chickenize/README.md
@@ -0,0 +1,19 @@
+The package chickenize provides several commands and Lua functions to manipulate the input or output tokens of any Lua(La)TeX document. It serves mostly educational and playful usage, but some functions may be used in serious documents.
+
+To produce the package files, run lualatex on chickinize.dtx, wich should result in the creation of the following files:
+ chickenize.pdf (documentation)
+ chickenize.tex (plainTeX user interface)
+ chickenize.sty (LaTeX user interface)
+ chickenize.lua (Lua package code) [does the actual work]
+
+You need an up-to-date TeX Live (2017, if possible) to use this package. Maybe a full MiKTeX will will also work. (Not tested!) Lua\TeX > 1.0.4 is required for some features since the corresponding syntax has changed!
+
+For any comments or suggestions, contact me:
+arno dot trautmann at gmx dot de
+
+Hope you have fun with this package!
+
+This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+modified under the conditions of the LaTeX Project Public License, either version 1.3c
+of this license or (at your option) any later version. This work has the LPPL mainten-
+ance status ‘maintained’.
diff --git a/macros/luatex/generic/chickenize/chickenize.dtx b/macros/luatex/generic/chickenize/chickenize.dtx
new file mode 100644
index 0000000000..6da6c1b4c1
--- /dev/null
+++ b/macros/luatex/generic/chickenize/chickenize.dtx
@@ -0,0 +1,2101 @@
+% \iffalse
+%<*driver>
+%% File: chickenize.dtx by Arno Trautmann, mail: arno dot trautmann at gmx dot de
+\iffalse
+%</driver>
+%<*readme>
+The package chickenize provides several commands and Lua functions to manipulate the input or output tokens of any Lua(La)TeX document. It serves mostly educational and playful usage, but some functions may be used in serious documents.
+
+To produce the package files, run lualatex on chickinize.dtx, wich should result in the creation of the following files:
+ chickenize.pdf (documentation)
+ chickenize.tex (plainTeX user interface)
+ chickenize.sty (LaTeX user interface)
+ chickenize.lua (Lua package code) [does the actual work]
+
+You need an up-to-date TeX Live (2017, if possible) to use this package. Maybe a full MiKTeX will will also work. (Not tested!) Lua\TeX > 1.0.4 is required for some features since the corresponding syntax has changed!
+
+For any comments or suggestions, contact me:
+arno dot trautmann at gmx dot de
+
+Hope you have fun with this package!
+
+This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+modified under the conditions of the LaTeX Project Public License, either version 1.3c
+of this license or (at your option) any later version. This work has the LPPL mainten-
+ance status ‘maintained’.
+%</readme>
+%<*driver>
+\fi
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+\input docstrip.tex
+\keepsilent
+\let\MetaPrefix\relax
+\preamble
+
+EXPERIMENTAL CODE
+
+This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+modified under the conditions of the LaTeX Project Public License, either version 1.3c
+of this license or (at your option) any later version. This work has the LPPL mainten-
+ance status ‘maintained’.
+\endpreamble
+\let\MetaPrefix\DoubleperCent
+\postamble
+\endpostamble
+\askforoverwritefalse
+
+\generate{\file{chickenize.sty}{\from{chickenize.dtx}{package}}}
+\generate{\file{chickenize.tex}{\from{chickenize.dtx}{tex}}}
+\def\MetaPrefix{-- }
+\def\luapostamble{%
+ \MetaPrefix^^J%
+ \MetaPrefix\space End of File `\outFileName'.%
+}
+\def\currentpostamble{\luapostamble}%
+
+\generate{\file{chickenize.lua}{\from{chickenize.dtx}{lua}}}
+\nopreamble\nopostamble
+\catcode`\@12
+
+\generate{\file{README.md}{\from{chickenize.dtx}{readme}}}
+
+
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+\documentclass[11pt,english]{ltxdoc}
+\usepackage{
+ array,
+ babel,
+ booktabs,
+ fontspec,
+ geometry,
+ graphicx,
+ hyperref,
+ longtable,
+ microtype,
+ scrpage2,
+ tabu
+}
+\hypersetup{
+ colorlinks=true,
+ linkcolor=blue,
+ filecolor=blue,
+ urlcolor=blue
+}
+
+\cfoot{chicken \pagemark}
+\ohead{}
+\pagestyle{scrheadings}
+\setmainfont{Linux Libertine O}
+\setsansfont{Linux Biolinum O}
+\newfontfamily\XITS{XITS}
+\newfontfamily\TGChorus{TeX Gyre Chorus}
+
+\usepackage{chickenize}
+\chickenizesetup{
+ rainbow_step=0.3
+}
+
+\begin{document}
+{\hspace*{-2cm}{\scalebox{.2}{\drawchicken}
+\hfill\hfill \parbox{6.3cm}{{\TGChorus{\Large »\,}\large The Monty Pythons, were they \TeX~users,\\\hspace*{.2em} could have written the chickenize macro.{\Large \textit «}}\\[1ex]
+\hspace*{4cm}\small Paul Isambert}\kern-2.5cm
+}
+
+\begin{center}
+\rainbowcolor
+\fontsize{55}{0}\selectfont \fontspec[Letters=Random]{Punk Nova}
+chickenize
+\end{center}
+
+\unrainbowcolor
+
+\centerline{v0.2.5}
+\centerline{\hspace*{2cm} Arno L. Trautmann {\Large \ALT}}
+\centerline{\href{mailto:arno.trautmann@gmx.de}{arno.trautmann@gmx.de}}
+
+\kern.5cm
+\textcolor{blue}{\Large How to read this document.}
+
+This is the documentation of the package |chickenize|. It allows manipulations of any Lua\TeX\ document\footnote{The code is based on pure Lua\TeX\ features, so don't even try to use it with any other \TeX\ flavour. The package is tested under plain Lua\TeX\ and Lua\LaTeX. If you tried using it with Con\TeX t, please share your experience, I will gladly try to make it compatible!} exploiting the possibilities offered by the callbacks that influence line breaking (and some other stuff). Most of this package's content is just for fun and educational use, but there are also some functions that can be useful in a normal document.
+
+The table on the next page shortly informs you about some of your possibilities and provides links to the (documented) Lua functions. The \TeX\ interface is presented \hyperlink{texinterface}{below}.
+
+The documentation of this package is far from being well-readable, consistent or even complete. This is caused either by lack of time or priority. If you miss anything that should be documented or if you have suggestions on how to increase the readability of the descriptions, please let me know.
+
+For a better understanding of what's going on in the code of this package, there is a small \hyperlink{tutorial}{tutorial} below that explains shortly the most important features used here.
+
+\emph{Attention}: This package is under development and everything presented here might be subject to incompatible changes. If, by any reason, you decide to use this package for an important document, please make a local copy of the source code and use that. This package will not be considered stable until it reaches at least v0.5, which might never happen.
+
+If you have any suggestions or comments, just drop me a mail, I’ll be happy to get any response! The latet source code is hosted on github: \url{https://github.com/alt/chickenize}. Feel free to comment or report bugs there, to fork, pull, etc.
+
+\vfill
+
+\small\noindent
+\fbox{\parbox{.97\textwidth}{
+This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+modified under the conditions of the LaTeX Project Public License, either version 1.3c
+of this license or (at your option) any later version. This work has the LPPL maintenance status ‘maintained’.}}
+\vspace*{1cm}
+
+\newpage
+
+\section*{\rainbowcolor For the Impatient:}
+
+\unrainbowcolor
+A small and incomplete overview of the functionalities offered by this package. I try to keep this list as complete as possible.\footnote{If you notice that something is missing, please help me improving the documentation!} Of course, the label “complete nonsense†depends on what you are doing …\\[2ex]
+
+\noindent
+\tabulinesep=.5ex
+\begin{longtabu} to .95\textwidth [c]{lX[j]}
+\hbox to 0cm{\bfseries \hspace*{2cm} maybe useful functions}\\
+\cmidrule(lr){1-2}
+\hyperref[sec:colorstretch]{colorstretch} & shows grey boxes that visualise the badness and font expansion line-wise\\
+\hyperref[sec:letterspaceadjust]{letterspaceadjust} & improves the greyness by using a small amount of letterspacing\\
+\hyperref[sec:substitutewords]{substitutewords} & replaces words by other words (chosen by the user)\\
+\hyperref[sec:variantjustification]{variantjustification} & Justification by using glyph variants\\
+\hyperref[sec:suppressonecharbreak]{suppressonecharbreak} & suppresses linebreaks after single-letter words\\
+\addlinespace\addlinespace
+\hbox to 0cm{\bfseries \hspace*{2cm} less useful functions} \\
+\cmidrule(lr){1-2}
+\hyperref[sec:boustrophedon]{boustrophedon} & invert every second line in the style of archaic greek texts\\
+\hyperref[sec:countglyphs]{countglyphs} & counts the number of glyphs in the whole document\\
+\hyperref[sec:countwords]{countwords} & counts the number of words in the whole document\\
+\hyperref[sec:leetspeak]{leetspeak} & translates the (latin-based) input into 1337 5p34k\\
+\hyperref[sec:medievalumlaut]{medievalumlaut} & \medievalumlaut changes each umlaut to normal glyph plus “e†above it: äöü\\
+\hyperref[sec:randomuclc]{randomuclc} & \unmedievalumlaut alternates randomly between uppercase and lowercase\\
+\hyperref[sec:randomrainbowcolor]{rainbowcolor} & changes the color of letters slowly according to a rainbow\\
+\hyperref[sec:randomrainbowcolor]{randomcolor} & prints every letter in a random color\\
+\hyperref[sec:tabularasa]{tabularasa} & removes every glyph from the output and leaves an empty document\\
+\hyperref[sec:uppercasecolor]{uppercasecolor} & makes every uppercase letter colored\\
+\addlinespace\addlinespace
+\hbox to 0cm{\bfseries \hspace*{2cm} complete nonsense} \\
+\cmidrule(lr){1-2}
+\hyperref[sec:chickenize]{chickenize} & replaces every word with “chicken†(or user-adjustable words)\\
+\hyperref[sec:guttenbergenize]{guttenbergenize} & deletes every quote and footnotes\\
+\hyperref[sec:hammertime]{hammertime} & U can't touch this!\\
+\hyperref[sec:kernmanipulate]{kernmanipulate} & manipulates the kerning (tbi)\\
+\hyperref[sec:matrixize]{matrixize} & replaces every glyph by its ASCII value in binary code\\
+\hyperref[sec:randomerror]{randomerror} & just throws random (La)\TeX\ errors at random times\\
+\hyperref[sec:randomfonts]{randomfonts} & changes the font randomly between every letter\\
+\hyperref[sec:randomchars]{randomchars} & randomizes the (letters of the) whole input\\
+\bottomrule
+\end{longtabu}
+
+\newpage
+\tableofcontents
+\newpage
+\part{User Documentation}
+\section{How It Works}
+We make use of Lua\TeX s callbacks, especially the |pre_line|\-|break_filter| and the |post_line|\-|break_filter|. Hooking a function into these, we can nearly arbitrarily change the content of the document. If the changes should be on the input-side (e.\,g.~replacing words with |chicken|), one can use the |pre_linebreak_filter|. However, changes like inserting color are best made after the linebreak is finalized, so |post_linebreak_filter| is to be preferred for such things.
+
+All functions traverse the node list of a paragraph and manipulate the nodes' properties (like |.font| or |.char|) or insert nodes (like color push/pop nodes) and return this changed node list.
+
+\hypertarget{texinterface}{}
+\section{Commands – How You Can Use It}
+There are several ways to make use of the \emph{chickenize} package – you can either stay on the \TeX\ side or use the Lua functions directly. In fact, the \TeX\ macros are simple wrappers around the functions.
+
+\subsection{\TeX\ Commands – Document Wide}
+You have a number of commands at your hand, each of which does some manipulation of the input or output. In fact, the code is simple and straightforward, but be careful, especially when combining things. Apply features step by step so your brain won't be damaged …
+
+The effect of the commands can be influenced, not with arguments, but only via the |\chickenizesetup| described \hyperlink{adjustment}{below}.
+
+\begin{description}
+\def\command#1{\item[\ttfamily \color{blue} \textbackslash#1]}
+\command{allownumberincommands} Normally, you cannot use numbers as part of a control sequence (or, command) name. This makes perfect sense and is good as it is. However, just to raise awareness to this, we provide a command here that changes the chategory codes of numbers 0–9 to 11, i.\,e.~normal character. So they \emph{can} be used in command names. However, this will break many packages, so do \emph{not} expect anything to work! At least use it \emph{after} all packages are loaded.
+\command{boustrophedon} Reverts every second line. This immitates archaic greek writings where one line was right-to-left, the next one left-to-right etc.\footnote{\url{en.wikipedia.org/wiki/Boustrophedon}} Interestingly, also every glyph was adaptet to the writing direction, so all glyphs are inverted in the right-to-left lines. Actually, there are two versions of this command that differ in their implementation: |\boustrophedon| rotates the whole line, while |\boustrophedonglyphs| changes the writing direction and reverses glyph-wise. The second one takes much more compilation time, but may be more reliable. A Rongorongo\footnote{\url{en.wikipedia.org/wiki/Rongorongo}} similar style boustrophedon is available with |\boustrophedoninverse| or |\rongorongonize|, where subsequent lines are rotated by 180° instead of mirrored.
+\command{countglyphs} \textcolor{blue}{\texttt{\textbackslash countwords}} Counts every printed character (or word, respectively) that appears in anything that is a paragraph. Which is quite everything, in fact, \emph{exept} math mode! The total number of glyphs/words will be printed at the end of the log file/console output. For glyphs, also the number of use for every letter is printed separately.
+\command{chickenize} Replaces every word of the input with the word “chickenâ€. Maybe sometime the replacement will be made configurable, but up to now, it's only chicken. To be a bit less static, about every 10\textsuperscript{th} chicken is uppercase. However, the beginning of a sentence is not recognized automatically.\footnote{If you have a nice implementation idea, I'd love to include this!}
+\command{colorstretch} Inspired by Paul Isambert's code, this command prints boxes instead of lines. The greyness of the first (left-hand) box corresponds to the badness of the line, i.\,e. it is a measure for how much the space between words has been extended to get proper paragraph justification. The second box on the right-hand side shows the amount of stretching/shrinking when font expansion is used. Together, the greyness of both boxes indicate how well the greyness is distributed over the typeset page.
+\command{dubstepize} wub wub wub wub wub BROOOOOAR WOBBBWOBBWOBB BZZZRRRRRRROOOOOOAAAAA … (inspired by \url{http://www.youtube.com/watch?v=ZFQ5EpO7iHk} and \url{http://www.youtube.com/watch?v=nGxpSsbodnw})
+\command{dubstepenize} synomym for |\dubstepize| as I am not sure what is the better name. Both macros are just a special case of |chickenize| with a very special “zoo†… there is no |\undubstepize| – once you go dubstep, you cannot go back …
+\command{explainbackslashes} A small list that gives hints on how many |\| characters you actually need for a backslash. I's supposed to be funny. At least my head thinks it's funny. Inspired (and mostly copied from, actually) xkcd.
+\command{gameoflife} Try it.
+\command{hammertime} STOP! —— Hammertime!
+\command{leetspeak} Translates the input into 1337 speak. If you don't understand that, lern it, n00b.
+\command{matrixize} Replaces every glyph by a binary representation of its ASCII value.
+\command{medievalumlaut} Changes every lowercase umlaut into the corresponding vocale glyph with a small “e†glyph above it to show the origins of the german umlauts coming from ae, oe, ue. Text-variant may follow.
+\command{nyanize} A synonym for |rainbowcolor|.
+\command{randomerror} Just throws a random \TeX\ or \LaTeX\ error at a random time during the compilation. I have quite no idea what this could be used for.
+\command{randomuclc} Changes every character of the input into its uppercase or lowercase variant. Well, guess what the “random†means …
+\command{randomfonts} Changes the font randomly for every character. If no parameters are given, all fonts that have been loaded are used, especially including math fonts.
+\command{randomcolor} Does what its name says.
+\command{rainbowcolor} Instead of random colors, this command causes the text color to change gradually according to the colors of a rainbow. Do not mix this with |randomcolor|, as that doesn't make any sense.
+\command{pancakenize} This is a dummy command that does nothing. However, every time you use it, you owe a pancake to the package author. You can either send it via mail or bring it to some (local) \TeX\ user's group meeting.
+\command{substitutewords} You have to specify pairs of words by using |\addtosubstitutions{word1}{word2}|. Then call |\substitutewords| (or the other way round, doesn't matter) and each occurance of |word1| will be replaced by |word2|. You can add replacement pairs by repeated calls to |\addtosubstitutions|. Take care! This function works with the input stream directly, therefore it does \emph{not} work on text that is inserted by macros, but it \emph{will} work on macro names itself! This way, you may use it to change macros (or environments) at will. Bug or feature? I'm not sure right now …
+\command{suppressonecharbreak} \TeX~normally does not suppress a linebreak after words with only one character (“I“, “a†etc.) This command suppresses line breaks. It is very similar to the code provided by the |impnattypo| package and based on the same ideas. However, the code in |chickenize| has been written before the author knew |impnattypo|, and the code differs a bit, might even be a bit faster. Well, test it!
+\command{tabularasa} Takes every glyph out of the document and replaces it by empty space of the same width. That could be useful if you want to hide some part of a text or similar. The |\text|-version is most likely more useful.
+\command{uppercasecolor} Makes every uppercase character in the input colored. At the moment, the color is randomized over the full rgb scale, but that will be adjustable once options are well implemented.
+\command{variantjustification} For special document types, it might be mandatory to have a fixed interword space. If you still want to have a justified type area, there must be another kind of stretchable material – one version realized by this command is using wide variants of glyphs to fill the remaining space. As the glyph substitution takes place randomly, this does \emph{not} provide the optimum justification, as this would take up much computation power.
+\end{description}
+
+\subsection{How to Deactivate It}
+Every command has a |\un|-version that deactivates it's functionality. So once you used |\chickenize|, it will chickenize the whole document up to |\unchickenize|. However, the paragraph in which |\unchickenize| appears, will \emph{not} be chickenized. The same is true for all other manipulations. Take care that you don't |\un|-anything bevor activating it, as this will result in an error.\footnote{Which is so far not catchable due to missing functionality in luatexbase.}
+
+If you want to manipulate only a part of a paragraph, you will have to use the corresponding |\text|-version of the function, see below. However, feel free to set and unset every function at will at any place in your document.
+
+\subsection{\texttt{\textbackslash text}-Versions}
+The functions provided by this package might be much more useful if applied only to a short sequence of words or single words instead of the whole document or paragraph. Therefore, most of the above-mentioned commands have\footnote{If they don't have, I did miss that, sorry. Please inform me about such cases.} a |\text|-version that takes an argument. |\textrandomcolor{foo}| results in a colored |foo| while the rest of the document remains unaffected. However, to achieve this effect, still the whole node list has to be traversed. Thus, it may slow down the compilation of your document, even if you use |\textrandomcolor| only once. Fortunately, the effect is very small and mostly negligible.\footnote{On a 500 pages text-only \LaTeX\ document the dilation is on the order of 10\% with |textrandomcolor|, but other manipulations can take much more time. However, you are not supposed to make such long documents with |chickenize|!}
+
+Please don't fool around by mixing a |\text|-version with the non-|\text|-version. If you feel like it and are not pleased with the result, it is up to \emph{you} to provide a stable and working solution.
+
+\subsection{Lua functions}
+As all features are implemented on the Lua side, you can use these functions independently. If you do so, please consult the corresponding subsections in the \hyperlink{sec:luamodule}{implementation} part, because there are some variables that can be adapted to your need.
+
+You can use the following code inside a |\directlua| statement or in a |luacode| environment (or the corresponding thing in your format):
+\begin{verbatim}
+luatexbase.add_to_callback("pre_linebreak_filter",chickenize,"chickenize")
+\end{verbatim}
+Replace |pre| by |post| to register into the post linebreak filter. The second argument (here: |chickenize|) specifies the function name; the available functions are listed below. You can supply a label as you like in the third argument. The fourth and last argument, which is omitted in the example, determines the order in which the functions in the callback are used. If you have no fancy stuff going on, you can safely use |1|.
+
+\hypertarget{adjustment}{}
+\section{Options – How to Adjust It}
+There are several ways to change the behaviour of |chickenize| and its macros. Most of the options are Lua variables and can be set using |\chickenizesetup|. But be \emph{careful!} The argument of |\chickenizesetup| is passed directly to Lua, therefore you are \emph{not} using a comma-separated key-value list, but uncorrelated Lua commands. The argument must have the syntax |{randomfontslower = 1| |randomfontsupper = 0}| instead of |{randomfontslower = 1,| |randomfontsupper = 0}|. Alright?
+
+However, |\chickenizesetup| is a macro on the \TeX\ side meaning that you can use \emph{only} |%| as comment string. If you use |--|, all of the argument will be ignored as \TeX\ does not pass an eol to |\directlua|. If you don't understand that, just ignore it and go on as usual.
+
+The following list tries to kind of keep track of the options and variables. There is no guarantee for completeness, and if you find something that is missing or doesn't work as described here, please inform me!
+
+\def\arg#1{\textcolor{red}{\ttfamily <#1>}}
+\def\opt#1{\textcolor{blue}{\ttfamily #1}}
+\def\default#1{\textcolor{black}{\ttfamily #1}}
+\begin{description}
+\item[\opt{randomfontslower}, \opt{randomfontsupper} = \arg{int}] These two integer variables determine the span of fonts used for the font randomization. Just play around with them a bit to find out what they are doing.
+\item[\opt{chickenstring} = \arg{table}] The string that is printed when using |\chickenize|. In fact, |chickenstring| is a table which allows for some more random action. To specify the default string, say |chickenstring[1] = 'chicken'|. For more than one animal, just step the index: |chickenstring[2] = 'rabbit'|. All existing table entries will be used randomly. Remember that we are dealing with Lua strings here, so use |' '| to mark them. (|" "| can cause problems with |babel|.)
+\item[\opt{chickenizefraction} = \arg{float} \default{1}] Gives the fraction of words that get replaced by the |chickenstring|. The default means that every word is substituted. However, with a value of, say, |0.0001|, only one word in ten thousand will be |chickenstring|. |chickenizefraction| must be specified \emph{after} |\begin{document}|. No idea, why …
+\item[\opt{chickencount} = \arg{true}] Activates the counting of substituted words and prints the number at the end of the terminal output.
+\item[\opt{colorstretchnumbers} = \arg{true} \default{0}] If true, the amount of stretching or shrinking of each line is printed into the margin as a green, red or black number.
+\item[\opt{chickenkernamount} = \arg{int}] The amount the kerning is set to when using |\kernmanipulate|.
+\item[\opt{chickenkerninvert} = \arg{bool}] If set to true, the kerning is inverted (to be used with |\kernmanipulate|.
+\item[\opt{leettable} = \arg{table}] From this table, the substitution for 1337 is taken. If you want to add or change an entry, you have to provide the unicode numbers of the characters, e.\,g. |leettable[101] = 50| replaces every |e| (|101|) with the number |3| (|50|).
+\item[\opt{uclcratio} = \arg{float} \default{0.5}] Gives the fraction of uppercases to lowercases in the |\randomuclc| mode. A higher number (up to 1) gives more uppercase letters. Guess what a lower number does.
+\item[\opt{randomcolor\_grey} = \arg{bool} \default{false}] For a printer-friendly version, this offers a grey scale instead of an rgb value for |\randomcolor|.
+\item[\opt{rainbow\_step} = \arg{float} \default{0.005}] This indicates the relative change of color using the rainbow functionality. A value of |1| changes the color in one step from red to yellow, while a value of |0.005| takes 200 letters for the transition to be completed. Useful values are below |0.05|, but it depends on the amount of text. The longer the text and the lower the |step|, the nicer your rainbow will be.
+\item[\opt{Rgb\_lower}, \opt{rGb\_upper} = \arg{int}] To specify the color space that is used for |\randomcolor|, you can specify six values, the upper and lower value for each color. The uppercase letter in the variable denotes the color, so |rGb_upper| gives the upper value for green etc. Possible values are between |1| and |254|. If you enter anything outside this range, your PDF will become invalid and break. For grey scale, use |grey_lower| and |grey_upper|, with values between |0| (black) and |1000| (white), included. Default is |0| to |900| to prevent white letters.
+\item[\opt{keeptext} = \arg{bool} \default{false}] This is for the |\colorstretch| command. If set to |true|, the text of your document will be kept. This way, it is easier to identify bad lines and the reason for the badness.
+\item[\opt{colorexpansion} = \arg{bool} \default{true}] If |true|, two bars are shown of which the second one denotes the font expansion. Only useful if font expansion is used. (You \emph{do} use font expansion, don’t you?)
+\end{description}
+
+\clearpage
+\part[Tutorial]{Tutorial\hypertarget{tutorial}}
+I thought it might be helpful to add a small tutorial to this package as it is mainly written with instructional purposes in mind. However, the following is \emph{not} intended as a comprehensive guide to Lua\TeX\. It's just to get an idea how things work here. For a deeper understanding of Lua\TeX\ you should consult both the Lua\TeX\ manual and some introduction into Lua proper like “Programming in Lua“. (See the section \hyperref[sec:literature]{Literature} at the end of the manual.)
+
+\section{Lua code}
+The crucial novelty in Lua\TeX\ is the first part of its name: The programming language Lua. One can use nearly any Lua code inside the commands |\directlua{}| or |\latelua{}|. This alleviates simple tasks like calculating a number and printing it, just as if it was entered by hand:
+\begin{verbatim}
+\directlua{
+ a = 5*2
+ tex.print(a)
+}
+\end{verbatim}
+A number of additions to the Lua language renders it particularly suitable for \TeX ing, especially the |tex.| library that offers access to \TeX\ internals. In the simple example above, the function |tex.print()| inserts its argument into the \TeX\ input stream, so the result of the calcuation (10) is printed in the document.
+
+Larger parts of Lua code should not be embedded in your \TeX\ code, but rather in a separate file. It can then be loaded using
+\begin{verbatim}
+\directlua{dofile("filename")}
+\end{verbatim}
+
+If you use Lua\LaTeX, you can also use the |luacode| environment from the eponymous package.
+
+\section{callbacks}
+While Lua code can be inserted using |\directlua| at any point in the input, a very powerful concept allows to change the way \TeX\ behaves: The \emph{callbacks}. A callback is a point where you can hook into \TeX's working and do anything to it that may make sense – or not. (Thus maybe breaking your document completely …)
+
+Callbacks are employed at several stages of \TeX's work – e.\,g. for font loading, paragraph breaking, shipping out etc. In this package, we make heavy use of mostly two callbacks: The |pre_linebreak_filter| and the |post_linebreak| filter. These callbacks are called just before (or after, resp.) \TeX\ breaks a paragraph into lines. Normally, these callbacks are empty, so they are a great playground. In between these callbacks, the |linebreak_filter| takes care of \TeX's line breaking mechanism. We won't touch this as I have no idea of what's going on there ;)
+
+\subsection{How to use a callback}
+The normal way to use a callback is to “register†a function in it. This way, the function is called each time the callback is executed. Typically, the function takes a node list (see below) as an argument, does something with it, and returns it. So a basic use of the |post_linebreak_filter| would look like:
+
+\begin{verbatim}
+function my_new_filter(head)
+ return head
+end
+
+callback.register("post_linebreak_filter",my_new_filter)
+\end{verbatim}
+The function |callback.register| takes the name of the callback and your new function. However, there are some reasons why we avoid this syntax here. Instead, we rely on the function |luatexbase.add_to_callback|. This is provided by the \LaTeX\ kernel table |luatexbase| which was initially a package by Manuel Pégourié-Gonnard and Élie Roux.\footnote{Since the late 2015 release of \LaTeX, the package has not to be loaded anymore since the functionality is absorbed by the kernel. Plain\TeX~users can load the |ltluatex| file which provides the needed functionality.} This function has a more extended syntax:
+\begin{verbatim}
+luatexbase.add_to_callback("post_linebreak_filter",my_new_filter,"a fancy new filter")
+\end{verbatim}
+The third argument is a name you can (have to) give to your function in the callback. That is necessary because the package also allows for removing functions from callbacks, and then you need a unique identifier for the function:
+\begin{verbatim}
+luatexbase.remove_from_callback("post_linebreak_filter","a fancy new filter")
+\end{verbatim}
+
+You have to consult the Lua\TeX\ manual to see what functionality a callback has when executed, what arguments it expects and what return values have to be given.
+
+Everything I have written here is not the complete truth – please consult the Lua\TeX\ manual and the |luatexbase| section in the \LaTeX\ kernel documentation for details!
+
+\section{Nodes}
+Essentially everything that Lua\TeX\ deals with are nodes – letters, spaces, colors, rules etc. In this package, we make heavy use of different types of nodes, so an understanding of the concept is crucial for the functionality.
+
+A node is an object that has different properties, depending on its type which is stored in its |.id| field. For example, a node of type |glyph| has |id| 27 (up to Lua\TeX~0.80., it was 37) has a number |.char| that represents its unicode codepoint, a |.font| entry that determines the font used for this glyph, a |.height|, |.depth| and |.width| etc.
+
+Also, a node typically has a non-empty field |.next| and |.prev|. In a list, these point to the – guess it – next or previous node. Using this, one can walk over a list of nodes step by step and manipulate the list.
+
+A more convenient way to adress each node of a list is the function |node.traverse(head)| which takes as first argument the first node of the list. However, often one wants to adress only a certain type of nodes in a list – e.\,g. all glyphs in a vertical list that also contains glue, rules etc. This is achieved by calling the function |node.traverse_id(GLYPH,head)|, with the first argument giving the respective id of the nodes.\footnote{GLYPH here stands for the id that the glyph node type has. This number can be achieved by calling |GLYPH = nodeid("glyph")| which will result in the correct number independent of the Lua\TeX~version. We will use this substitute throughout this docmuent.}
+
+The following example removes all characters “e†from the input just before paragraph breaking. This might not make any sense, but it is a good example anyways:
+\begin{verbatim}
+function remove_e(head)
+ for n in node.traverse_id(GLYPH,head) do
+ if n.char == 101 then
+ node.remove(head,n)
+ end
+ end
+ return head
+end
+
+luatexbase.add_to_callback("pre_linebreak_filter",remove_e,"remove all letters e")
+\end{verbatim}
+
+Now, don't read on, but try out this code by yourself! Change the number of the character to be removed, try to play around a bit. Also, try to remove the spaces between words. Those are glue nodes – look up their id in the Lua\TeX\ manual! Then, you have to remove the |if n.char| condition on the third line of the listing, because glue nodes lack a |.char| field. If everything works, you should have an input consisting of only one long word. Congratulations!
+
+The |pre_linebreak_filter| is especially easy because its argument (here called |head|) is just one horizontal list. For the |post_linebreak_filter|, one has to traverse a whole vertical stack of horizontal lists, vertical glue and other material. See some of the functions below to understand what is necessary in this more complicated case.
+
+\section{Other things}
+Lua is a very intuitive and simple language, but nonetheless powerful. Just two tips: use local variables if possible – your code will be much faster. For this reason we prefer synonyms like |nodetraverseid = node.traverse_id| instead of the original names.
+
+Also, Lua is kind of built around tables. Everything is best done with tables!
+
+The namespace of the chickenize package is \emph{not} consistent. Please don't take anything here as an example for good Lua coding, for good \TeX ing or even for good Lua\TeX ing. It's not. For high quality code check out the code written by Hans Hagen or other professionals. Once you understand the package at hand, you should be ready to go on and improve your knowledge. After that, you might come back and help me improve this package – I'm always happy for any help ☺
+
+\DocInput{chickenize.dtx}
+\end{document}
+%</driver>
+%<*tex>
+% \fi
+% \clearpage
+%\part{Implementation}
+%\label{sec:implementation}
+%\section{\TeX\ file}
+% This file is more-or-less a dummy file to offer a nice interface for the functions. Basically, every macro registers a function of the same name in the corresponding callback. The |un|-macros later remove these functions. Where it makes sense, there are |text|-variants that activate the function only in a certain area of the text, by means of Lua\TeX's attributes.
+%
+% For (un)registering, we use the |luatexbase| \LaTeX\ kernel functionality. Then, the |.lua| file is loaded which does the actual work. Finally, the \TeX\ macros are defined as simple |\directlua| calls.
+%
+% The Lua file is not found by using a simple |dofile("chickenize.lua")| call, but we have to use kpse's |find_file|.
+% \begin{macrocode}
+\directlua{dofile(kpse.find_file("chickenize.lua"))}
+
+\def\ALT{%
+ \bgroup%
+ \fontspec{Latin Modern Sans}%
+ A%
+ \kern-.4em \raisebox{.65ex}{\scalebox{0.3}{L}}%
+ \kern-.0em \raisebox{-0.98ex}{T}%
+ \egroup%
+}
+
+\def\allownumberincommands{
+ \catcode`\0=11
+ \catcode`\1=11
+ \catcode`\2=11
+ \catcode`\3=11
+ \catcode`\4=11
+ \catcode`\5=11
+ \catcode`\6=11
+ \catcode`\7=11
+ \catcode`\8=11
+ \catcode`\9=11
+}
+
+\def\BEClerize{
+ \chickenize
+ \directlua{
+ chickenstring[1] = "noise noise"
+ chickenstring[2] = "atom noise"
+ chickenstring[3] = "shot noise"
+ chickenstring[4] = "photon noise"
+ chickenstring[5] = "camera noise"
+ chickenstring[6] = "noising noise"
+ chickenstring[7] = "thermal noise"
+ chickenstring[8] = "electronic noise"
+ chickenstring[9] = "spin noise"
+ chickenstring[10] = "electron noise"
+ chickenstring[11] = "Bogoliubov noise"
+ chickenstring[12] = "white noise"
+ chickenstring[13] = "brown noise"
+ chickenstring[14] = "pink noise"
+ chickenstring[15] = "bloch sphere"
+ chickenstring[16] = "atom shot noise"
+ chickenstring[17] = "nature physics"
+ }
+}
+
+\def\boustrophedon{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",boustrophedon,"boustrophedon")}}
+\def\unboustrophedon{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","boustrophedon")}}
+
+\def\boustrophedonglyphs{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",boustrophedon_glyphs,"boustrophedon_glyphs")}}
+\def\unboustrophedonglyphs{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","boustrophedon_glyphs")}}
+
+\def\boustrophedoninverse{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",boustrophedon_inverse,"boustrophedon_inverse")}}
+\def\unboustrophedoninverse{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","boustrophedon_inverse")}}
+
+\def\bubblesort{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",bubblesort,"bubblesort")}}
+\def\unbubblesort{
+ \directlua{luatexbase.remove_from_callback("bubblesort","bubblesort")}}
+
+\def\chickenize{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",chickenize,"chickenize")
+ luatexbase.add_to_callback("start_page_number",
+ function() texio.write("["..status.total_pages) end ,"cstartpage")
+ luatexbase.add_to_callback("stop_page_number",
+ function() texio.write(" chickens]") end,"cstoppage")
+ luatexbase.add_to_callback("stop_run",nicetext,"a nice text")
+ }
+}
+\def\unchickenize{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","chickenize")
+ luatexbase.remove_from_callback("start_page_number","cstartpage")
+ luatexbase.remove_from_callback("stop_page_number","cstoppage")}}
+
+\def\coffeestainize{ %% to be implemented.
+ \directlua{}}
+\def\uncoffeestainize{
+ \directlua{}}
+
+\def\colorstretch{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",colorstretch,"stretch_expansion")}}
+\def\uncolorstretch{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","stretch_expansion")}}
+
+\def\countglyphs{
+ \directlua{
+ counted_glyphs_by_code = {}
+ for i = 1,10000 do
+ counted_glyphs_by_code[i] = 0
+ end
+ glyphnumber = 0 spacenumber = 0
+ luatexbase.add_to_callback("post_linebreak_filter",countglyphs,"countglyphs")
+ luatexbase.add_to_callback("stop_run",printglyphnumber,"printglyphnumber")
+ }
+}
+
+\def\countwords{
+ \directlua{wordnumber = 0
+ luatexbase.add_to_callback("pre_linebreak_filter",countwords,"countwords")
+ luatexbase.add_to_callback("stop_run",printwordnumber,"printwordnumber")
+ }
+}
+
+\def\detectdoublewords{
+ \directlua{
+ luatexbase.add_to_callback("post_linebreak_filter",detectdoublewords,"detectdoublewords")
+ luatexbase.add_to_callback("stop_run",printdoublewords,"printdoublewords")
+ }
+}
+
+\def\dosomethingfunny{
+ %% should execute one of the “funny†commands, but randomly. So every compilation is completely different. Maybe a list of commands could be specified to exclude total nonesense-functions. Maybe also on a per-paragraph-basis?
+}
+
+\def\dubstepenize{
+ \chickenize
+ \directlua{
+ chickenstring[1] = "WOB"
+ chickenstring[2] = "WOB"
+ chickenstring[3] = "WOB"
+ chickenstring[4] = "BROOOAR"
+ chickenstring[5] = "WHEE"
+ chickenstring[6] = "WOB WOB WOB"
+ chickenstring[7] = "WAAAAAAAAH"
+ chickenstring[8] = "duhduh duhduh duh"
+ chickenstring[9] = "BEEEEEEEEEW"
+ chickenstring[10] = "DDEEEEEEEW"
+ chickenstring[11] = "EEEEEW"
+ chickenstring[12] = "boop"
+ chickenstring[13] = "buhdee"
+ chickenstring[14] = "bee bee"
+ chickenstring[15] = "BZZZRRRRRRROOOOOOAAAAA"
+
+ chickenizefraction = 1
+ }
+}
+\let\dubstepize\dubstepenize
+
+\def\explainbackslashes{ %% inspired by xkcd #1638
+ {\tt\noindent
+\textbackslash escape character\\
+\textbackslash\textbackslash line end or escaped escape character in tex.print("")\\
+\textbackslash\textbackslash\textbackslash real, real backslash\\
+\textbackslash\textbackslash\textbackslash\textbackslash line end in tex.print("")\\
+\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash elder backslash \\
+\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash backslash which escapes the screen and enters your brain\\
+\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash backslash so real it transcends time and space \\
+\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash backslash to end all other text\\
+\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash... the true name of Ba'al, the soul-eater}
+}
+
+\def\gameoflife{
+ Your Life Is Tetris. Stop Playing It Like Chess.
+}
+
+\def\guttenbergenize{ %% makes only sense when using LaTeX
+ \AtBeginDocument{
+ \let\grqq\relax\let\glqq\relax
+ \let\frqq\relax\let\flqq\relax
+ \let\grq\relax\let\glq\relax
+ \let\frq\relax\let\flq\relax
+%
+ \gdef\footnote##1{}
+ \gdef\cite##1{}\gdef\parencite##1{}
+ \gdef\Cite##1{}\gdef\Parencite##1{}
+ \gdef\cites##1{}\gdef\parencites##1{}
+ \gdef\Cites##1{}\gdef\Parencites##1{}
+ \gdef\footcite##1{}\gdef\footcitetext##1{}
+ \gdef\footcites##1{}\gdef\footcitetexts##1{}
+ \gdef\textcite##1{}\gdef\Textcite##1{}
+ \gdef\textcites##1{}\gdef\Textcites##1{}
+ \gdef\smartcites##1{}\gdef\Smartcites##1{}
+ \gdef\supercite##1{}\gdef\supercites##1{}
+ \gdef\autocite##1{}\gdef\Autocite##1{}
+ \gdef\autocites##1{}\gdef\Autocites##1{}
+ %% many, many missing … maybe we need to tackle the underlying mechanism?
+ }
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",guttenbergenize_rq,"guttenbergenize_rq")}
+}
+
+\def\hammertime{
+ \global\let\n\relax
+ \directlua{hammerfirst = true
+ luatexbase.add_to_callback("pre_linebreak_filter",hammertime,"hammertime")}}
+\def\unhammertime{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","hammertime")}}
+
+\let\hendlnize\chickenize % homage to Hendl/Chicken
+\let\unhendlnize\unchickenize % may the soldering strength always be with him
+
+% \def\itsame{
+% \directlua{drawmario}} %%% does not exist
+
+\def\kernmanipulate{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",kernmanipulate,"kernmanipulate")}}
+\def\unkernmanipulate{
+ \directlua{lutaexbase.remove_from_callback("pre_linebreak_filter",kernmanipulate)}}
+
+\def\leetspeak{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",leet,"1337")}}
+\def\unleetspeak{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","1337")}}
+
+\def\leftsideright#1{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",leftsideright,"leftsideright")}
+ \directlua{
+ leftsiderightindex = {#1}
+ leftsiderightarray = {}
+ for _,i in pairs(leftsiderightindex) do
+ leftsiderightarray[i] = true
+ end
+ }
+}
+\def\unleftsideright{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","leftsideright")}}
+
+\def\letterspaceadjust{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",letterspaceadjust,"letterspaceadjust")}}
+\def\unletterspaceadjust{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","letterspaceadjust")}}
+
+\def\listallcommands{
+ \directlua{
+ for name in pairs(tex.hashtokens()) do
+ print(name)
+ end}
+}
+
+\let\stealsheep\letterspaceadjust %% synonym in honor of Paul
+\let\unstealsheep\unletterspaceadjust
+\let\returnsheep\unletterspaceadjust
+
+\def\matrixize{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",matrixize,"matrixize")}}
+\def\unmatrixize{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","matrixize")}}
+
+\def\milkcow{ %% FIXME %% to be implemented
+ \directlua{}}
+\def\unmilkcow{
+ \directlua{}}
+
+\def\medievalumlaut{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",medievalumlaut,"medievalumlaut")}}
+\def\unmedievalumlaut{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","medievalumlaut")}}
+
+\def\pancakenize{
+ \directlua{luatexbase.add_to_callback("stop_run",pancaketext,"pancaketext")}}
+
+\def\rainbowcolor{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomcolor,"rainbowcolor")
+ rainbowcolor = true}}
+\def\unrainbowcolor{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","rainbowcolor")
+ rainbowcolor = false}}
+\let\nyanize\rainbowcolor
+\let\unnyanize\unrainbowcolor
+
+\def\randomchars{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomchars,"randomchars")}}
+\def\unrandomchars{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","randomchars")}}
+
+\def\randomcolor{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomcolor,"randomcolor")}}
+\def\unrandomcolor{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","randomcolor")}}
+
+\def\randomerror{ %% FIXME
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomerror,"randomerror")}}
+\def\unrandomerror{ %% FIXME
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","randomerror")}}
+
+\def\randomfonts{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomfonts,"randomfonts")}}
+\def\unrandomfonts{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","randomfonts")}}
+
+\def\randomuclc{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",randomuclc,"randomuclc")}}
+\def\unrandomuclc{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","randomuclc")}}
+
+\let\rongorongonize\boustrophedoninverse
+\let\unrongorongonize\unboustrophedoninverse
+
+\def\scorpionize{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",scorpionize_color,"scorpionize_color")}}
+\def\unscorpionize{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","scorpionize_color")}}
+
+\def\spankmonkey{ %% to be implemented
+ \directlua{}}
+\def\unspankmonkey{
+ \directlua{}}
+
+\def\substitutewords{
+ \directlua{luatexbase.add_to_callback("process_input_buffer",substitutewords,"substitutewords")}}
+\def\unsubstitutewords{
+ \directlua{luatexbase.remove_from_callback("process_input_buffer","substitutewords")}}
+
+\def\addtosubstitutions#1#2{
+ \directlua{addtosubstitutions("#1","#2")}
+}
+
+\def\suppressonecharbreak{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",suppressonecharbreak,"suppressonecharbreak")}}
+\def\unsuppressonecharbreak{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","suppressonecharbreak")}}
+
+\def\tabularasa{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",tabularasa,"tabularasa")}}
+\def\untabularasa{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","tabularasa")}}
+
+\def\tanjanize{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",tanjanize,"tanjanize")}}
+\def\untanjanize{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","tanjanize")}}
+
+\def\uppercasecolor{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",uppercasecolor,"uppercasecolor")}}
+\def\unuppercasecolor{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","uppercasecolor")}}
+
+\def\upsidedown#1{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",upsidedown,"upsidedown")}
+ \directlua{
+ upsidedownindex = {#1}
+ upsidedownarray = {}
+ for _,i in pairs(upsidedownindex) do
+ upsidedownarray[i] = true
+ end
+ }
+}
+\def\unupsidedown{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","upsidedown")}}
+
+\def\variantjustification{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",variantjustification,"variantjustification")}}
+\def\unvariantjustification{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","variantjustification")}}
+
+\def\zebranize{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",zebranize,"zebranize")}}
+\def\unzebranize{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","zebranize")}}
+% \end{macrocode}
+% Now the setup for the |\text|-versions. We utilize Lua\TeX s attributes to mark all nodes that should be manipulated. The macros should be |\long| to allow arbitrary input.
+% \begin{macrocode}
+\newattribute\leetattr
+\newattribute\letterspaceadjustattr
+\newattribute\randcolorattr
+\newattribute\randfontsattr
+\newattribute\randuclcattr
+\newattribute\tabularasaattr
+\newattribute\uppercasecolorattr
+
+\long\def\textleetspeak#1%
+ {\setluatexattribute\leetattr{42}#1\unsetluatexattribute\leetattr}
+
+\long\def\textletterspaceadjust#1{
+ \setluatexattribute\letterspaceadjustattr{42}#1\unsetluatexattribute\letterspaceadjustattr
+ \directlua{
+ if (textletterspaceadjustactive) then else % -- if already active, do nothing
+ luatexbase.add_to_callback("pre_linebreak_filter",textletterspaceadjust,"textletterspaceadjust")
+ end
+ textletterspaceadjustactive = true % -- set to active
+ }
+}
+\let\textlsa\textletterspaceadjust
+
+\long\def\textrandomcolor#1%
+ {\setluatexattribute\randcolorattr{42}#1\unsetluatexattribute\randcolorattr}
+\long\def\textrandomfonts#1%
+ {\setluatexattribute\randfontsattr{42}#1\unsetluatexattribute\randfontsattr}
+\long\def\textrandomfonts#1%
+ {\setluatexattribute\randfontsattr{42}#1\unsetluatexattribute\randfontsattr}
+\long\def\textrandomuclc#1%
+ {\setluatexattribute\randuclcattr{42}#1\unsetluatexattribute\randuclcattr}
+\long\def\texttabularasa#1%
+ {\setluatexattribute\tabularasaattr{42}#1\unsetluatexattribute\tabularasaattr}
+\long\def\textuppercasecolor#1%
+ {\setluatexattribute\uppercasecolorattr{42}#1\unsetluatexattribute\uppercasecolorattr}
+% \end{macrocode}
+% Finally, a macro to control the setup. So far, it's only a wrapper that allows \TeX-style comments to make the user feel more at home.
+% \begin{macrocode}
+\def\chickenizesetup#1{\directlua{#1}}
+% \end{macrocode}
+% The following is the very first try of implementing a small drawing language in Lua. It draws a beautiful chicken.
+% \begin{macrocode}
+\long\def\luadraw#1#2{%
+ \vbox to #1bp{%
+ \vfil
+ \latelua{pdf_print("q") #2 pdf_print("Q")}%
+ }%
+}
+\long\def\drawchicken{
+ \luadraw{90}{
+ chickenhead = {200,50} % chicken head center
+ chickenhead_rad = 20
+
+ neckstart = {215,35} % neck
+ neckstop = {230,10} %
+
+ chickenbody = {260,-10}
+ chickenbody_rad = 40
+ chickenleg = {
+ {{260,-50},{250,-70},{235,-70}},
+ {{270,-50},{260,-75},{245,-75}}
+ }
+
+ beak_top = {185,55}
+ beak_front = {165,45}
+ beak_bottom = {185,35}
+
+ wing_front = {260,-10}
+ wing_bottom = {280,-40}
+ wing_back = {275,-15}
+
+ sloppycircle(chickenhead,chickenhead_rad) sloppyline(neckstart,neckstop)
+ sloppycircle(chickenbody,chickenbody_rad)
+ sloppyline(chickenleg[1][1],chickenleg[1][2]) sloppyline(chickenleg[1][2],chickenleg[1][3])
+ sloppyline(chickenleg[2][1],chickenleg[2][2]) sloppyline(chickenleg[2][2],chickenleg[2][3])
+ sloppyline(beak_front,beak_top) sloppyline(beak_front,beak_bottom)
+ sloppyline(wing_front,wing_bottom) sloppyline(wing_back,wing_bottom)
+ }
+}
+% \end{macrocode}
+% \iffalse
+%</tex>
+%<*package>
+% \fi
+% \section{\LaTeX\ package}
+% I have decided to keep the \LaTeX-part of this package as small as possible. So far, it does … nothing useful, but it provides a |chickenize.sty| that loads |chickenize.tex| so the user can still say |\usepackage{chickenize}|. This file will never support package options!
+%
+% Some code might be implemented to manipulate figures for full chickenization. However, I will \emph{not} load any packages at this place, as loading of expl3 or TikZ or whatever takes too much time for such a tiny package like this one. If you require any of the features presented here, you have to load the packages on your own. Maybe this will change.
+% \begin{macrocode}
+\ProvidesPackage{chickenize}%
+ [2017/08/19 v0.2.5 chickenize package]
+\input{chickenize}
+% \end{macrocode}
+% \subsection{Free Compliments}
+% \begin{macrocode}
+
+% \end{macrocode}
+% \subsection{Definition of User-Level Macros}
+% Nothing done so far, just some minor ideas. If you want to implement some cool things, contact me! :)
+% \begin{macrocode}
+\iffalse
+ \DeclareDocumentCommand\includegraphics{O{}m}{
+ \fbox{Chicken} %% actually, I'd love to draw an MP graph showing a chicken …
+ }
+%%%% specials: the balmerpeak. A tribute to http://xkcd.com/323/.
+%% So far, you have to load pgfplots yourself.
+%% As it is a mighty package, I don't want the user to force loading it.
+\NewDocumentCommand\balmerpeak{G{}O{-4cm}}{
+%% to be done using Lua drawing.
+}
+\fi
+% \end{macrocode}
+%\iffalse
+%</package>
+%<*lua>
+%\fi
+% \section{Lua Module}
+% \label{sec:luamodule}
+% This file contains all the necessary functions and is the actual work horse of this package. The functions are sorted strictly alphabetically (or, they \emph{should} be …) and not by sense, functionality or anything.
+%
+% First, we set up some constants that are used by many of the following functions. These are made global so the code can be manipulated at the document level, too.
+% \begin{macrocode}
+
+local nodeid = node.id
+local nodecopy = node.copy
+local nodenew = node.new
+local nodetail = node.tail
+local nodeslide = node.slide
+local noderemove = node.remove
+local nodetraverseid = node.traverse_id
+local nodeinsertafter = node.insert_after
+local nodeinsertbefore = node.insert_before
+
+Hhead = nodeid("hhead")
+RULE = nodeid("rule")
+GLUE = nodeid("glue")
+WHAT = nodeid("whatsit")
+COL = node.subtype("pdf_colorstack")
+DISC = nodeid("disc")
+GLYPH = nodeid("glyph")
+GLUE = nodeid("glue")
+HLIST = nodeid("hlist")
+KERN = nodeid("kern")
+PUNCT = nodeid("punct")
+PENALTY = nodeid("penalty")
+PDF_LITERAL = node.subtype("pdf_literal")
+% \end{macrocode}
+% Now we set up the nodes used for all color things. The nodes are whatsits of subtype |pdf_colorstack|.
+% \begin{macrocode}
+color_push = nodenew(WHAT,COL)
+color_pop = nodenew(WHAT,COL)
+color_push.stack = 0
+color_pop.stack = 0
+color_push.command = 1
+color_pop.command = 2
+% \end{macrocode}
+% \subsection{chickenize}\label{sec:chickenize}
+% The infamous |\chickenize| macro. Substitutes every word of the input with the given string. This can be elaborated arbitrarily, and whenever I feel like, I might add functionality. So far, only the string replaces the word, and even hyphenation is not possible.
+% \begin{macrocode}
+chicken_pagenumbers = true
+
+chickenstring = {}
+chickenstring[1] = "chicken" -- chickenstring is a table, please remeber this!
+
+chickenizefraction = 0.5
+-- set this to a small value to fool somebody, or to see if your text has been read carefully. This is also a great way to lay easter eggs for your own class / package …
+chicken_substitutions = 0 -- value to count the substituted chickens. Makes sense for testing your proofreaders.
+
+local match = unicode.utf8.match
+chickenize_ignore_word = false
+% \end{macrocode}
+% The function |chickenize_real_stuff| is started once the beginning of a to-be-substituted word is found.
+% \begin{macrocode}
+chickenize_real_stuff = function(i,head)
+ while ((i.next.id == GLYPH) or (i.next.id == KERN) or (i.next.id == DISC) or (i.next.id == HLIST)) do --find end of a word
+ i.next = i.next.next
+ end
+
+ chicken = {} -- constructing the node list.
+
+-- Should this be done only once? No, otherwise we lose the freedom to change the string in-document.
+-- But it could be done only once each paragraph as in-paragraph changes are not possible!
+
+ chickenstring_tmp = chickenstring[math.random(1,#chickenstring)]
+ chicken[0] = nodenew(GLYPH,1) -- only a dummy for the loop
+ for i = 1,string.len(chickenstring_tmp) do
+ chicken[i] = nodenew(GLYPH,1)
+ chicken[i].font = font.current()
+ chicken[i-1].next = chicken[i]
+ end
+
+ j = 1
+ for s in string.utfvalues(chickenstring_tmp) do
+ local char = unicode.utf8.char(s)
+ chicken[j].char = s
+ if match(char,"%s") then
+ chicken[j] = nodenew(GLUE)
+ chicken[j].width = space
+ chicken[j].shrink = shrink
+ chicken[j].stretch = stretch
+ end
+ j = j+1
+ end
+
+ nodeslide(chicken[1])
+ lang.hyphenate(chicken[1])
+ chicken[1] = node.kerning(chicken[1]) -- FIXME: does not work
+ chicken[1] = node.ligaturing(chicken[1]) -- dito
+
+ nodeinsertbefore(head,i,chicken[1])
+ chicken[1].next = chicken[2] -- seems to be necessary … to be fixed
+ chicken[string.len(chickenstring_tmp)].next = i.next
+
+ -- shift lowercase latin letter to uppercase if the original input was an uppercase
+ if (chickenize_capital and (chicken[1].char > 96 and chicken[1].char < 123)) then
+ chicken[1].char = chicken[1].char - 32
+ end
+
+ return head
+end
+
+chickenize = function(head)
+ for i in nodetraverseid(GLYPH,head) do --find start of a word
+ -- Random determination of the chickenization of the next word:
+ if math.random() > chickenizefraction then
+ chickenize_ignore_word = true
+ elseif chickencount then
+ chicken_substitutions = chicken_substitutions + 1
+ end
+
+ if (chickenize_ignore_word == false) then -- normal case: at the beginning of a word, we jump into chickenization
+ if (i.char > 64 and i.char < 91) then chickenize_capital = true else chickenize_capital = false end
+ head = chickenize_real_stuff(i,head)
+ end
+
+-- At the end of the word, the ignoring is reset. New chance for everyone.
+ if not((i.next.id == GLYPH) or (i.next.id == DISC) or (i.next.id == PUNCT) or (i.next.id == KERN)) then
+ chickenize_ignore_word = false
+ end
+ end
+ return head
+end
+
+% \end{macrocode}
+% A small additional feature: Some nice text to cheer up the user. Mainly to show that and how we can access the |stop_run| callback. (see above)
+% \begin{macrocode}
+local separator = string.rep("=", 28)
+local texiowrite_nl = texio.write_nl
+nicetext = function()
+ texiowrite_nl("Output written on "..tex.jobname..".pdf ("..status.total_pages.." chicken,".." eggs).")
+ texiowrite_nl(" ")
+ texiowrite_nl(separator)
+ texiowrite_nl("Hello my dear user,")
+ texiowrite_nl("good job, now go outside and enjoy the world!")
+ texiowrite_nl(" ")
+ texiowrite_nl("And don't forget to feed your chicken!")
+ texiowrite_nl(separator .. "\n")
+ if chickencount then
+ texiowrite_nl("There were "..chicken_substitutions.." substitutions made.")
+ texiowrite_nl(separator)
+ end
+end
+% \end{macrocode}
+% \subsection{boustrophedon}\label{sec:boustrophedon}
+% There are two implementations of the boustrophedon: One reverses every line as a whole, the other one changes the writing direction and reverses glyphs one by one. The latter one might be more reliable, but takes considerably more time.
+%
+% Linewise rotation:
+% \begin{macrocode}
+boustrophedon = function(head)
+ rot = node.new(WHAT,PDF_LITERAL)
+ rot2 = node.new(WHAT,PDF_LITERAL)
+ odd = true
+ for line in node.traverse_id(0,head) do
+ if odd == false then
+ w = line.width/65536*0.99625 -- empirical correction factor (?)
+ rot.data = "-1 0 0 1 "..w.." 0 cm"
+ rot2.data = "-1 0 0 1 "..-w.." 0 cm"
+ line.head = node.insert_before(line.head,line.head,nodecopy(rot))
+ nodeinsertafter(line.head,nodetail(line.head),nodecopy(rot2))
+ odd = true
+ else
+ odd = false
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% Glyphwise rotation:
+% \begin{macrocode}
+boustrophedon_glyphs = function(head)
+ odd = false
+ rot = nodenew(WHAT,PDF_LITERAL)
+ rot2 = nodenew(WHAT,PDF_LITERAL)
+ for line in nodetraverseid(0,head) do
+ if odd==true then
+ line.dir = "TRT"
+ for g in nodetraverseid(GLYPH,line.head) do
+ w = -g.width/65536*0.99625
+ rot.data = "-1 0 0 1 " .. w .." 0 cm"
+ rot2.data = "-1 0 0 1 " .. -w .." 0 cm"
+ line.head = node.insert_before(line.head,g,nodecopy(rot))
+ nodeinsertafter(line.head,g,nodecopy(rot2))
+ end
+ odd = false
+ else
+ line.dir = "TLT"
+ odd = true
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% Inverse boustrophedon. At least I think, this is the way Rongorongo is written. However, the top-to-bottom direction has to be inverted, too.
+% \begin{macrocode}
+boustrophedon_inverse = function(head)
+ rot = node.new(WHAT,PDF_LITERAL)
+ rot2 = node.new(WHAT,PDF_LITERAL)
+ odd = true
+ for line in node.traverse_id(0,head) do
+ if odd == false then
+texio.write_nl(line.height)
+ w = line.width/65536*0.99625 -- empirical correction factor (?)
+ h = line.height/65536*0.99625
+ rot.data = "-1 0 0 -1 "..w.." "..h.." cm"
+ rot2.data = "-1 0 0 -1 "..-w.." "..0.5*h.." cm"
+ line.head = node.insert_before(line.head,line.head,node.copy(rot))
+ node.insert_after(line.head,node.tail(line.head),node.copy(rot2))
+ odd = true
+ else
+ odd = false
+ end
+ end
+ return head
+end
+% \end{macrocode}
+%
+% \subsection{bubblesort}\label{sec:bubblesort}
+% Bubllesort is to be implemented. Why? Because it's funny.
+% \begin{macrocode}
+function bubblesort(head)
+ for line in nodetraverseid(0,head) do
+ for glyph in nodetraverseid(GLYPH,line.head) do
+
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{countglyphs}\label{sec:countglyphs}
+% Counts the glyphs in your document. Where “glyph†means every printed character in everything that is a paragraph – formulas do \emph{not} work! Captions of floats etc.~also will \emph{not} work. However, hyphenations \emph{do} work and the hyphen sign \emph{is counted}! And that is the sole reason for this function – every simple script could read the letters in a doucment, but only after the hyphenation it is possible to count the real number of printed characters – where the hyphen does count.
+%
+% Not only the total number of glyphs is recorded, but also the number of glyphs by character code. By this, you know exactly how many “a†or “߆you used. A feature of category “completely uselessâ€.
+%
+% Spaces are also counted, but only spaces between glyphs in the output (i.\,e.~nothing at the end/beginning of the lines), excluding indentation.
+%
+% This function will (maybe, upon request) be extended to allow counting of whatever you want.
+%
+%% Take care: This will slow down the compilation extremely, by about a factor of 2! Only use for playing around or counting a final version of your document!
+% \begin{macrocode}
+countglyphs = function(head)
+ for line in nodetraverseid(0,head) do
+ for glyph in nodetraverseid(GLYPH,line.head) do
+ glyphnumber = glyphnumber + 1
+ if (glyph.next.next) then
+ if (glyph.next.id == 10) and (glyph.next.next.id == GLYPH) then
+ spacenumber = spacenumber + 1
+ end
+ counted_glyphs_by_code[glyph.char] = counted_glyphs_by_code[glyph.char] + 1
+ end
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% To print out the number at the end of the document, the following function is registered in the |stop_run| callback. This will prevent the normal message from being printed, informing the user about page and memory stats etc. But I guess when counting characters, everything else does not matter at all? …
+% \begin{macrocode}
+printglyphnumber = function()
+ texiowrite_nl("\nNumber of glyphs by character code (only up to 127):")
+ for i = 1,127 do --%% FIXME: should allow for more characters, but cannot be printed to console output – print into document?
+ texiowrite_nl(string.char(i)..": "..counted_glyphs_by_code[i])
+ end
+
+ texiowrite_nl("\nTotal number of glyphs in this document: "..glyphnumber)
+ texiowrite_nl("Number of spaces in this document: "..spacenumber)
+ texiowrite_nl("Glyphs plus spaces: "..glyphnumber+spacenumber.."\n")
+end
+% \end{macrocode}
+% \subsection{countwords}\label{sec:countwords}
+% Counts the number of words in the document. The function works directly before the line breaking, so all macros are expanded. A “word†then is everything that is between two spaces before paragraph formatting. The beginning of a paragraph is a word, and the last word of a paragraph is accounted for by explicit increasing the counter, as no space token follows.
+% \begin{macrocode}
+countwords = function(head)
+ for glyph in nodetraverseid(GLYPH,head) do
+ if (glyph.next.id == 10) then
+ wordnumber = wordnumber + 1
+ end
+ end
+ wordnumber = wordnumber + 1 -- add 1 for the last word in a paragraph which is not found otherwise
+ return head
+end
+% \end{macrocode}
+% Printing is done at the end of the compilation in the |stop_run| callback:
+% \begin{macrocode}
+printwordnumber = function()
+ texiowrite_nl("\nNumber of words in this document: "..wordnumber)
+end
+% \end{macrocode}
+
+% \subsection{detectdoublewords}\label{sec:detectdoublewords}
+% \begin{macrocode} %% FIXME: Does this work? …
+function detectdoublewords(head)
+ prevlastword = {} -- array of numbers representing the glyphs
+ prevfirstword = {}
+ newlastword = {}
+ newfirstword = {}
+ for line in nodetraverseid(0,head) do
+ for g in nodetraverseid(GLYPH,line.head) do
+texio.write_nl("next glyph",#newfirstword+1)
+ newfirstword[#newfirstword+1] = g.char
+ if (g.next.id == 10) then break end
+ end
+texio.write_nl("nfw:"..#newfirstword)
+ end
+end
+
+function printdoublewords()
+ texio.write_nl("finished")
+end
+% \end{macrocode}
+% \subsection{guttenbergenize}\label{sec:guttenbergenize}
+% A function in honor of the German politician Guttenberg.\footnote{Thanks to Jasper for bringing me to this idea!} Please do \emph{not} confuse him with the grand master Gutenberg!
+%
+% Calling |\guttenbergenize| will not only execute or manipulate Lua code, but also redefine some \TeX\ or \LaTeX\ commands. The aim is to remove all quotations, footnotes and anything that will give information about the real sources of your work.
+%
+% The following Lua function will remove all quotation marks from the input. Again, the |pre_linebreak_filter| is used for this, although it should be rather removed in the input filter or so.
+% \subsubsection{guttenbergenize – preliminaries}
+% This is a nice solution Lua offers for our needs. Learn it, this might be helpful for you sometime, too.
+% \begin{macrocode}
+local quotestrings = {
+ [171] = true, [172] = true,
+ [8216] = true, [8217] = true, [8218] = true,
+ [8219] = true, [8220] = true, [8221] = true,
+ [8222] = true, [8223] = true,
+ [8248] = true, [8249] = true, [8250] = true,
+}
+% \end{macrocode}
+% \subsubsection{guttenbergenize – the function}
+% \begin{macrocode}
+guttenbergenize_rq = function(head)
+ for n in nodetraverseid(nodeid"glyph",head) do
+ local i = n.char
+ if quotestrings[i] then
+ noderemove(head,n)
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{hammertime}\label{sec:hammertime}
+% This is a completely useless function. It just prints STOP! – HAMMERTIME at the beginnig of the first paragraph after |\hammertime|, and “U can't touch this†for every following one. As the function writes to the terminal, you have to be sure that your terminal is line-buffered and not block-buffered. Compare the explanation by Taco on the Lua\TeX\ mailing list.\footnote{\url{http://tug.org/pipermail/luatex/2011-November/003355.html}}
+% \begin{macrocode}
+hammertimedelay = 1.2
+local htime_separator = string.rep("=", 30) .. "\n" -- slightly inconsistent with the “nicetextâ€
+hammertime = function(head)
+ if hammerfirst then
+ texiowrite_nl(htime_separator)
+ texiowrite_nl("============STOP!=============\n")
+ texiowrite_nl(htime_separator .. "\n\n\n")
+ os.sleep (hammertimedelay*1.5)
+ texiowrite_nl(htime_separator .. "\n")
+ texiowrite_nl("==========HAMMERTIME==========\n")
+ texiowrite_nl(htime_separator .. "\n\n")
+ os.sleep (hammertimedelay)
+ hammerfirst = false
+ else
+ os.sleep (hammertimedelay)
+ texiowrite_nl(htime_separator)
+ texiowrite_nl("======U can't touch this!=====\n")
+ texiowrite_nl(htime_separator .. "\n\n")
+ os.sleep (hammertimedelay*0.5)
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{itsame}\label{sec:itsame}
+% The (very first, very basic, very stupid) code to draw a small mario. You need to input luadraw.tex or do luadraw.lua for the rectangle function.
+% \begin{macrocode}
+itsame = function()
+local mr = function(a,b) rectangle({a*10,b*-10},10,10) end
+color = "1 .6 0"
+for i = 6,9 do mr(i,3) end
+for i = 3,11 do mr(i,4) end
+for i = 3,12 do mr(i,5) end
+for i = 4,8 do mr(i,6) end
+for i = 4,10 do mr(i,7) end
+for i = 1,12 do mr(i,11) end
+for i = 1,12 do mr(i,12) end
+for i = 1,12 do mr(i,13) end
+
+color = ".3 .5 .2"
+for i = 3,5 do mr(i,3) end mr(8,3)
+mr(2,4) mr(4,4) mr(8,4)
+mr(2,5) mr(4,5) mr(5,5) mr(9,5)
+mr(2,6) mr(3,6) for i = 8,11 do mr(i,6) end
+for i = 3,8 do mr(i,8) end
+for i = 2,11 do mr(i,9) end
+for i = 1,12 do mr(i,10) end
+mr(3,11) mr(10,11)
+for i = 2,4 do mr(i,15) end for i = 9,11 do mr(i,15) end
+for i = 1,4 do mr(i,16) end for i = 9,12 do mr(i,16) end
+
+color = "1 0 0"
+for i = 4,9 do mr(i,1) end
+for i = 3,12 do mr(i,2) end
+for i = 8,10 do mr(5,i) end
+for i = 5,8 do mr(i,10) end
+mr(8,9) mr(4,11) mr(6,11) mr(7,11) mr(9,11)
+for i = 4,9 do mr(i,12) end
+for i = 3,10 do mr(i,13) end
+for i = 3,5 do mr(i,14) end
+for i = 7,10 do mr(i,14) end
+end
+% \end{macrocode}
+% \subsection{kernmanipulate}\label{sec:kernmanipulate}
+% This function either eliminates all the kerning, inverts the sign of the kerning or changes it to a user-given value.
+%
+% If the boolean |chickeninvertkerning| is true, the kerning amount is negative, if it is false, the kerning will be set to th e value of |chickenkernvalue|. A large value (> 100\,000) can be used to show explicitely where kerns are inserted. Good for educational use.
+% \begin{macrocode}
+chickenkernamount = 0
+chickeninvertkerning = false
+
+function kernmanipulate (head)
+ if chickeninvertkerning then -- invert the kerning
+ for n in nodetraverseid(11,head) do
+ n.kern = -n.kern
+ end
+ else -- if not, set it to the given value
+ for n in nodetraverseid(11,head) do
+ n.kern = chickenkernamount
+ end
+ end
+ return head
+end
+% \end{macrocode}
+
+% \subsection{leetspeak}\label{sec:leetspeak}
+% The |leettable| is the substitution scheme. Just add items if you feel to. Maybe we will differ between a light-weight version and a hardcore 1337.
+% \begin{macrocode}
+leetspeak_onlytext = false
+leettable = {
+ [101] = 51, -- E
+ [105] = 49, -- I
+ [108] = 49, -- L
+ [111] = 48, -- O
+ [115] = 53, -- S
+ [116] = 55, -- T
+
+ [101-32] = 51, -- e
+ [105-32] = 49, -- i
+ [108-32] = 49, -- l
+ [111-32] = 48, -- o
+ [115-32] = 53, -- s
+ [116-32] = 55, -- t
+}
+% \end{macrocode}
+% And here the function itself. So simple that I will not write any
+% \begin{macrocode}
+leet = function(head)
+ for line in nodetraverseid(Hhead,head) do
+ for i in nodetraverseid(GLYPH,line.head) do
+ if not leetspeak_onlytext or
+ node.has_attribute(i,luatexbase.attributes.leetattr)
+ then
+ if leettable[i.char] then
+ i.char = leettable[i.char]
+ end
+ end
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{leftsideright}\label{sec:leftsideright}
+% This function mirrors each glyph given in the array of \verb|leftsiderightarray| horizontally.
+% \begin{macrocode}
+leftsideright = function(head)
+ local factor = 65536/0.99626
+ for n in nodetraverseid(GLYPH,head) do
+ if (leftsiderightarray[n.char]) then
+ shift = nodenew(WHAT,PDF_LITERAL)
+ shift2 = nodenew(WHAT,PDF_LITERAL)
+ shift.data = "q -1 0 0 1 " .. n.width/factor .." 0 cm"
+ shift2.data = "Q 1 0 0 1 " .. n.width/factor .." 0 cm"
+ nodeinsertbefore(head,n,shift)
+ nodeinsertafter(head,n,shift2)
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{letterspaceadjust}\label{sec:letterspaceadjust}
+% Yet another piece of code by Paul. This is primarily intended for very narrow columns, but may also increase the overall quality of typesetting. Basically, it does nothing else than adding expandable space \emph{between} letters. This way, the amount of stretching between words can be reduced which will, hopefully, result in the greyness to be more equally distributed over the page.
+%
+% Why the synonym |stealsheep|? Because of a comment of Paul on the |texhax| mailing list: \url{http://tug.org/pipermail/texhax/2011-October/018374.html}
+% \subsubsection{setup of variables}
+% \begin{macrocode}
+local letterspace_glue = nodenew(nodeid"glue")
+local letterspace_pen = nodenew(nodeid"penalty")
+
+letterspace_glue.width = tex.sp"0pt"
+letterspace_glue.stretch = tex.sp"0.5pt"
+letterspace_pen.penalty = 10000
+% \end{macrocode}
+% \subsubsection{function implementation}
+% \begin{macrocode}
+letterspaceadjust = function(head)
+ for glyph in nodetraverseid(nodeid"glyph", head) do
+ if glyph.prev and (glyph.prev.id == nodeid"glyph" or glyph.prev.id == nodeid"disc" or glyph.prev.id == nodeid"kern") then
+ local g = nodecopy(letterspace_glue)
+ nodeinsertbefore(head, glyph, g)
+ nodeinsertbefore(head, g, nodecopy(letterspace_pen))
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsubsection{textletterspaceadjust}
+% The |\text...|-version of |letterspaceadjust|. Just works, without the need to call |\letterspaceadjust| globally or anything else. Just put the |\textletterspaceadjust| around the part of text you want the function to work on. Might have problems with surrounding spacing, take care!
+% \begin{macrocode}
+textletterspaceadjust = function(head)
+ for glyph in nodetraverseid(nodeid"glyph", head) do
+ if node.has_attribute(glyph,luatexbase.attributes.letterspaceadjustattr) then
+ if glyph.prev and (glyph.prev.id == node.id"glyph" or glyph.prev.id == node.id"disc" or glyph.prev.id == nodeid"kern") then
+ local g = node.copy(letterspace_glue)
+ nodeinsertbefore(head, glyph, g)
+ nodeinsertbefore(head, g, nodecopy(letterspace_pen))
+ end
+ end
+ end
+ luatexbase.remove_from_callback("pre_linebreak_filter","textletterspaceadjust")
+ return head
+end
+% \end{macrocode}
+% \subsection{matrixize}\label{sec:matrixize}
+% Substitutes every glyph by a representation of its ASCII value. Migth be extended to cover the entire unicode range, but so far only 8bit is supported. The code is quite straight-forward and works OK. The line ends are not necessarily adjusted correctly. However, with microtype, i.\,e. font expansion, everything looks fine.
+% \begin{macrocode}
+matrixize = function(head)
+ x = {}
+ s = nodenew(nodeid"disc")
+ for n in nodetraverseid(nodeid"glyph",head) do
+ j = n.char
+ for m = 0,7 do -- stay ASCII for now
+ x[7-m] = nodecopy(n) -- to get the same font etc.
+
+ if (j / (2^(7-m)) < 1) then
+ x[7-m].char = 48
+ else
+ x[7-m].char = 49
+ j = j-(2^(7-m))
+ end
+ nodeinsertbefore(head,n,x[7-m])
+ nodeinsertafter(head,x[7-m],nodecopy(s))
+ end
+ noderemove(head,n)
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{medievalumlaut}\label{sec:medievalumlaut}
+% Changes the umlauts ä, ö, ü into a, o, u with an e as an accent. The exact position of the e is adapted for each glyph, but that is only tested with one font. Other fonts might f*ck up everything.
+%
+% For this, we define node representing the e (which then is copied every time) and two nodes that shift the e to where it belongs by using pdf matrix-nodes. An additional kern node shifts the space that the e took back so that everything ends up in the right place. All this happens in the \verb|post_linebreak_filter| to enable normal hyphenation and line breaking. Well, \verb|pre_linebreak_filter| would also have done …
+% \begin{macrocode}
+medievalumlaut = function(head)
+ local factor = 65536/0.99626
+ local org_e_node = nodenew(GLYPH)
+ org_e_node.char = 101
+ for line in nodetraverseid(0,head) do
+ for n in nodetraverseid(GLYPH,line.head) do
+ if (n.char == 228 or n.char == 246 or n.char == 252) then
+ e_node = nodecopy(org_e_node)
+ e_node.font = n.font
+ shift = nodenew(WHAT,PDF_LITERAL)
+ shift2 = nodenew(WHAT,PDF_LITERAL)
+ shift2.data = "Q 1 0 0 1 " .. e_node.width/factor .." 0 cm"
+ nodeinsertafter(head,n,e_node)
+
+ nodeinsertbefore(head,e_node,shift)
+ nodeinsertafter(head,e_node,shift2)
+
+ x_node = nodenew(KERN)
+ x_node.kern = -e_node.width
+ nodeinsertafter(head,shift2,x_node)
+ end
+
+ if (n.char == 228) then -- ä
+ shift.data = "q 0.5 0 0 0.5 " ..
+ -n.width/factor*0.85 .." ".. n.height/factor*0.75 .. " cm"
+ n.char = 97
+ end
+ if (n.char == 246) then -- ö
+ shift.data = "q 0.5 0 0 0.5 " ..
+ -n.width/factor*0.75 .." ".. n.height/factor*0.75 .. " cm"
+ n.char = 111
+ end
+ if (n.char == 252) then -- ü
+ shift.data = "q 0.5 0 0 0.5 " ..
+ -n.width/factor*0.75 .." ".. n.height/factor*0.75 .. " cm"
+ n.char = 117
+ end
+ end
+ end
+ return head
+end
+% \end{macrocode}
+%
+% \subsection{pancakenize}\label{sec:pancakenize}
+% \begin{macrocode}
+local separator = string.rep("=", 28)
+local texiowrite_nl = texio.write_nl
+pancaketext = function()
+ texiowrite_nl("Output written on "..tex.jobname..".pdf ("..status.total_pages.." chicken,".." eggs).")
+ texiowrite_nl(" ")
+ texiowrite_nl(separator)
+ texiowrite_nl("Soo ... you decided to use \\pancakenize.")
+ texiowrite_nl("That means you owe me a pancake!")
+ texiowrite_nl(" ")
+ texiowrite_nl("(This goes by document, not compilation.)")
+ texiowrite_nl(separator.."\n\n")
+ texiowrite_nl("Looking forward for my pancake! :)")
+ texiowrite_nl("\n\n")
+end
+% \end{macrocode}
+% \subsection{randomerror}\label{sec:randomerror}
+
+
+% \subsection{randomfonts}\label{sec:randomfonts}
+% Traverses the output and substitutes fonts randomly. A check is done so that the font number is existing.
+% One day, the fonts should be easily given explicitly in terms of |\bf| etc.
+% \begin{macrocode}
+randomfontslower = 1
+randomfontsupper = 0
+%
+randomfonts = function(head)
+ local rfub
+ if randomfontsupper > 0 then -- fixme: this should be done only once, no? Or at every paragraph?
+ rfub = randomfontsupper -- user-specified value
+ else
+ rfub = font.max() -- or just take all fonts
+ end
+ for line in nodetraverseid(Hhead,head) do
+ for i in nodetraverseid(GLYPH,line.head) do
+ if not(randomfonts_onlytext) or node.has_attribute(i,luatexbase.attributes.randfontsattr) then
+ i.font = math.random(randomfontslower,rfub)
+ end
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{randomuclc}\label{sec:randomuclc}
+% Traverses the input list and changes lowercase/uppercase codes.
+% \begin{macrocode}
+uclcratio = 0.5 -- ratio between uppercase and lower case
+randomuclc = function(head)
+ for i in nodetraverseid(GLYPH,head) do
+ if not(randomuclc_onlytext) or node.has_attribute(i,luatexbase.attributes.randuclcattr) then
+ if math.random() < uclcratio then
+ i.char = tex.uccode[i.char]
+ else
+ i.char = tex.lccode[i.char]
+ end
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{randomchars}\label{sec:randomchars}
+% \begin{macrocode}
+randomchars = function(head)
+ for line in nodetraverseid(Hhead,head) do
+ for i in nodetraverseid(GLYPH,line.head) do
+ i.char = math.floor(math.random()*512)
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{randomcolor and rainbowcolor}\label{sec:randomrainbowcolor}
+% \subsubsection{randomcolor – preliminaries}
+% Setup of the boolean for grey/color or rainbowcolor, and boundaries for the colors. RGB space is fully used, but greyscale is only used in a visible range, i.\,e. to 90\% instead of 100\% white.
+% \begin{macrocode}
+randomcolor_grey = false
+randomcolor_onlytext = false --switch between local and global colorization
+rainbowcolor = false
+
+grey_lower = 0
+grey_upper = 900
+
+Rgb_lower = 1
+rGb_lower = 1
+rgB_lower = 1
+Rgb_upper = 254
+rGb_upper = 254
+rgB_upper = 254
+% \end{macrocode}
+% Variables for the rainbow. 1/rainbow\_step*5 is the number of letters used for one cycle, the color changes from red to yellow to green to blue to purple.
+% \begin{macrocode}
+rainbow_step = 0.005
+rainbow_Rgb = 1-rainbow_step -- we start in the red phase
+rainbow_rGb = rainbow_step -- values x must always be 0 < x < 1
+rainbow_rgB = rainbow_step
+rainind = 1 -- 1:red,2:yellow,3:green,4:blue,5:purple
+% \end{macrocode}
+% This function produces the string needed for the pdf color stack. We need values 0]..[1 for the colors.
+% \begin{macrocode}
+randomcolorstring = function()
+ if randomcolor_grey then
+ return (0.001*math.random(grey_lower,grey_upper)).." g"
+ elseif rainbowcolor then
+ if rainind == 1 then -- red
+ rainbow_rGb = rainbow_rGb + rainbow_step
+ if rainbow_rGb >= 1-rainbow_step then rainind = 2 end
+ elseif rainind == 2 then -- yellow
+ rainbow_Rgb = rainbow_Rgb - rainbow_step
+ if rainbow_Rgb <= rainbow_step then rainind = 3 end
+ elseif rainind == 3 then -- green
+ rainbow_rgB = rainbow_rgB + rainbow_step
+ rainbow_rGb = rainbow_rGb - rainbow_step
+ if rainbow_rGb <= rainbow_step then rainind = 4 end
+ elseif rainind == 4 then -- blue
+ rainbow_Rgb = rainbow_Rgb + rainbow_step
+ if rainbow_Rgb >= 1-rainbow_step then rainind = 5 end
+ else -- purple
+ rainbow_rgB = rainbow_rgB - rainbow_step
+ if rainbow_rgB <= rainbow_step then rainind = 1 end
+ end
+ return rainbow_Rgb.." "..rainbow_rGb.." "..rainbow_rgB.." rg"
+ else
+ Rgb = math.random(Rgb_lower,Rgb_upper)/255
+ rGb = math.random(rGb_lower,rGb_upper)/255
+ rgB = math.random(rgB_lower,rgB_upper)/255
+ return Rgb.." "..rGb.." "..rgB.." ".." rg"
+ end
+end
+% \end{macrocode}
+% \subsubsection{randomcolor – the function}
+% The function that does all the colorizing action. It goes through the whole paragraph and looks at every glyph. If the boolean |randomcolor_onlytext| is set, only glyphs with the set attribute will be colored. Elsewise, all glyphs are taken.
+% \begin{macrocode}
+randomcolor = function(head)
+ for line in nodetraverseid(0,head) do
+ for i in nodetraverseid(GLYPH,line.head) do
+ if not(randomcolor_onlytext) or
+ (node.has_attribute(i,luatexbase.attributes.randcolorattr))
+ then
+ color_push.data = randomcolorstring() -- color or grey string
+ line.head = nodeinsertbefore(line.head,i,nodecopy(color_push))
+ nodeinsertafter(line.head,i,nodecopy(color_pop))
+ end
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{randomerror}\label{sec:randomerror}
+% \begin{macrocode}
+%
+% \end{macrocode}
+% \subsection{rickroll}\label{sec:rickroll}
+% Another tribute to pop culture. Either: substitute word-by-word as in pancake. OR: substitute each link to a youtube-rickroll …
+% \begin{macrocode}
+%
+% \end{macrocode}
+% \subsection{substitutewords}\label{sec:substitutewords}
+% This function is one of the rather usefull ones of this package. It replaces each occurance of one word by another word, which both are specified by the user. So nothing random or funny, but a real serious function! There are three levels for this function: At user-level, the user just specifies two strings that are passed to the function |addtosubstitutions|. This is needed as the |#| has a special meaning both in \TeX s definitions and in Lua. In this second step, the list of substitutions is just extended, and the real work is done by the function |substiuteword| which is registered in the |process_input_buffer| callback. Once the substitution list is built, the rest is very simple: We just use |gsub| to substitute, do this for every item in the list, and that's it.
+% \begin{macrocode}
+substitutewords_strings = {}
+
+addtosubstitutions = function(input,output)
+ substitutewords_strings[#substitutewords_strings + 1] = {}
+ substitutewords_strings[#substitutewords_strings][1] = input
+ substitutewords_strings[#substitutewords_strings][2] = output
+end
+
+substitutewords = function(head)
+ for i = 1,#substitutewords_strings do
+ head = string.gsub(head,substitutewords_strings[i][1],substitutewords_strings[i][2])
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{suppressonecharbreak}\label{sec:suppressonecharbreak}
+% We rush through the node list before line breaking takes place and insert large penalties for breaks after single glyphs. To keep the code as small, simple and fast as possible, we |traverse_id| over spaces and see wether the |next.next| node is also a space. This might not be the best and most universal way of doing it, but the simplest. The penalty is not created newly each time, but copied – no significant speed gain, however.
+% \begin{macrocode}
+suppressonecharbreakpenaltynode = node.new(PENALTY)
+suppressonecharbreakpenaltynode.penalty = 10000
+% \end{macrocode}
+% \begin{macrocode}
+function suppressonecharbreak(head)
+ for i in node.traverse_id(GLUE,head) do
+ if ((i.next) and (i.next.next.id == GLUE)) then
+ pen = node.copy(suppressonecharbreakpenaltynode)
+ node.insert_after(head,i.next,pen)
+ end
+ end
+
+ return head
+end
+% \end{macrocode}
+% \subsection{tabularasa}\label{sec:tabularasa}
+% Removes every glyph from the output and replaces it by empty space. In the end, next to nothing will be visible. Should be extended to also remove rules or just anything visible.
+% \begin{macrocode}
+tabularasa_onlytext = false
+
+tabularasa = function(head)
+ local s = nodenew(nodeid"kern")
+ for line in nodetraverseid(nodeid"hlist",head) do
+ for n in nodetraverseid(nodeid"glyph",line.head) do
+ if not(tabularasa_onlytext) or node.has_attribute(n,luatexbase.attributes.tabularasaattr) then
+ s.kern = n.width
+ nodeinsertafter(line.list,n,nodecopy(s))
+ line.head = noderemove(line.list,n)
+ end
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{tanjanize}\label{sec:tanjanize}
+% \begin{macrocode}
+tanjanize = function(head)
+ local s = nodenew(nodeid"kern")
+ local m = nodenew(GLYPH,1)
+ local use_letter_i = true
+ scale = nodenew(WHAT,PDF_LITERAL)
+ scale2 = nodenew(WHAT,PDF_LITERAL)
+ scale.data = "0.5 0 0 0.5 0 0 cm"
+ scale2.data = "2 0 0 2 0 0 cm"
+
+ for line in nodetraverseid(nodeid"hlist",head) do
+ for n in nodetraverseid(nodeid"glyph",line.head) do
+ mimicount = 0
+ tmpwidth = 0
+ while ((n.next.id == GLYPH) or (n.next.id == 11) or (n.next.id == 7) or (n.next.id == 0)) do --find end of a word
+ n.next = n.next.next
+ mimicount = mimicount + 1
+ tmpwidth = tmpwidth + n.width
+ end
+
+ mimi = {} -- constructing the node list.
+ mimi[0] = nodenew(GLYPH,1) -- only a dummy for the loop
+ for i = 1,string.len(mimicount) do
+ mimi[i] = nodenew(GLYPH,1)
+ mimi[i].font = font.current()
+ if(use_letter_i) then mimi[i].char = 109 else mimi[i].char = 105 end
+ use_letter_i = not(use_letter_i)
+ mimi[i-1].next = mimi[i]
+ end
+--]]
+
+line.head = nodeinsertbefore(line.head,n,nodecopy(scale))
+nodeinsertafter(line.head,n,nodecopy(scale2))
+ s.kern = (tmpwidth*2-n.width)
+ nodeinsertafter(line.head,n,nodecopy(s))
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{uppercasecolor}\label{sec:uppercasecolor}
+% Loop through all the nodes and checking whether it is uppercase. If so (and also for small caps), color it.
+% \begin{macrocode}
+uppercasecolor_onlytext = false
+
+uppercasecolor = function (head)
+ for line in nodetraverseid(Hhead,head) do
+ for upper in nodetraverseid(GLYPH,line.head) do
+ if not(uppercasecolor_onlytext) or node.has_attribute(upper,luatexbase.attributes.uppercasecolorattr) then
+ if (((upper.char > 64) and (upper.char < 91)) or
+ ((upper.char > 57424) and (upper.char < 57451))) then -- for small caps! nice ☺
+ color_push.data = randomcolorstring() -- color or grey string
+ line.head = nodeinsertbefore(line.head,upper,nodecopy(color_push))
+ nodeinsertafter(line.head,upper,nodecopy(color_pop))
+ end
+ end
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{upsidedown}\label{sec:upsidedown}
+% This function mirrors all glyphs given in the array \verb|upsidedownarray| vertically.
+% \begin{macrocode}
+upsidedown = function(head)
+ local factor = 65536/0.99626
+ for line in nodetraverseid(Hhead,head) do
+ for n in nodetraverseid(GLYPH,line.head) do
+ if (upsidedownarray[n.char]) then
+ shift = nodenew(WHAT,PDF_LITERAL)
+ shift2 = nodenew(WHAT,PDF_LITERAL)
+ shift.data = "q 1 0 0 -1 0 " .. n.height/factor .." cm"
+ shift2.data = "Q 1 0 0 1 " .. n.width/factor .." 0 cm"
+ nodeinsertbefore(head,n,shift)
+ nodeinsertafter(head,n,shift2)
+ end
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{colorstretch}\label{sec:colorstretch}
+% This function displays the amount of stretching that has been done for each line of an arbitrary document. A well-typeset document should be equally grey over all lines, which is not always possible.
+%
+% In fact, two boxes are drawn: The first (left) box shows the badness, i.\,e. the amount of stretching the spaces between words. Too much space results in ligth grey, whereas a too dense line is indicated by a dark grey box.
+%
+%The second box is only useful if microtypographic extensions are used, e.\,g. with the |microtype| package under \LaTeX. The box color then corresponds to the amount of font expansion in the line. This works great for demonstrating the positive effect of font expansion on the badness of a line!
+%
+% The base structure of the following code was provided by Paul Isambert. Thanks for the code and support, Paul!
+% \subsubsection{colorstretch – preliminaries}
+% Two booleans, |keeptext|, and |colorexpansion|, are used to control the behaviour of the function.
+% \begin{macrocode}
+keeptext = true
+colorexpansion = true
+
+colorstretch_coloroffset = 0.5
+colorstretch_colorrange = 0.5
+chickenize_rule_bad_height = 4/5 -- height and depth of the rules
+chickenize_rule_bad_depth = 1/5
+
+
+colorstretchnumbers = true
+drawstretchthreshold = 0.1
+drawexpansionthreshold = 0.9
+% \end{macrocode}
+% After these constants have been set, the function starts. It receives the vertical list of the typeset paragraph as |head|, and loops through all horizontal lists.
+%
+% If font expansion should be shown (|colorexpansion == true|), then the first glyph node is determined and its width compared with the width of the unexpanded glyph. This gives a measure for the expansion factor and is translated into a grey scale.
+% \begin{macrocode}
+colorstretch = function (head)
+ local f = font.getfont(font.current()).characters
+ for line in nodetraverseid(Hhead,head) do
+ local rule_bad = nodenew(RULE)
+
+ if colorexpansion then -- if also the font expansion should be shown
+ local g = line.head
+ while not(g.id == GLYPH) and (g.next) do g = g.next end -- find first glyph on line. If line is empty, no glyph:
+ if (g.id == GLYPH) then -- read width only if g is a glyph!
+ exp_factor = g.width / f[g.char].width
+ exp_color = colorstretch_coloroffset + (1-exp_factor)*10 .. " g"
+ rule_bad.width = 0.5*line.width -- we need two rules on each line!
+ end
+ else
+ rule_bad.width = line.width -- only the space expansion should be shown, only one rule
+ end
+% \end{macrocode}
+% Height and depth of the rules are adapted to print a closed grey pattern, so no white interspace is left.
+%
+% The glue order and sign can be obtained directly and are translated into a grey scale.
+% \begin{macrocode}
+ rule_bad.height = tex.baselineskip.width*chickenize_rule_bad_height -- this should give a better output
+ rule_bad.depth = tex.baselineskip.width*chickenize_rule_bad_depth
+
+ local glue_ratio = 0
+ if line.glue_order == 0 then
+ if line.glue_sign == 1 then
+ glue_ratio = colorstretch_colorrange * math.min(line.glue_set,1)
+ else
+ glue_ratio = -colorstretch_colorrange * math.min(line.glue_set,1)
+ end
+ end
+ color_push.data = colorstretch_coloroffset + glue_ratio .. " g"
+
+% \end{macrocode}
+% Now, we throw everything together in a way that works. Somehow …
+% \begin{macrocode}
+-- set up output
+ local p = line.head
+
+ -- a rule to immitate kerning all the way back
+ local kern_back = nodenew(RULE)
+ kern_back.width = -line.width
+
+ -- if the text should still be displayed, the color and box nodes are inserted additionally
+ -- and the head is set to the color node
+ if keeptext then
+ line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push))
+ else
+ node.flush_list(p)
+ line.head = nodecopy(color_push)
+ end
+ nodeinsertafter(line.head,line.head,rule_bad) -- then the rule
+ nodeinsertafter(line.head,line.head.next,nodecopy(color_pop)) -- and then pop!
+ tmpnode = nodeinsertafter(line.head,line.head.next.next,kern_back)
+
+ -- then a rule with the expansion color
+ if colorexpansion then -- if also the stretch/shrink of letters should be shown
+ color_push.data = exp_color
+ nodeinsertafter(line.head,tmpnode,nodecopy(color_push))
+ nodeinsertafter(line.head,tmpnode.next,nodecopy(rule_bad))
+ nodeinsertafter(line.head,tmpnode.next.next,nodecopy(color_pop))
+ end
+% \end{macrocode}
+% Now we are ready with the boxes and stuff and everything. However, a very useful information might be the amount of stretching, not encoded as color, but the real value. In concreto, I mean: narrow boxes get one color, loose boxes get another one, but only if the badness is above a certain amount. This information is printed into the right-hand margin. The threshold is user-adjustable.
+% \begin{macrocode}
+ if colorstretchnumbers then
+ j = 1
+ glue_ratio_output = {}
+ for s in string.utfvalues(math.abs(glue_ratio)) do -- using math.abs here gets us rid of the minus sign
+ local char = unicode.utf8.char(s)
+ glue_ratio_output[j] = nodenew(GLYPH,1)
+ glue_ratio_output[j].font = font.current()
+ glue_ratio_output[j].char = s
+ j = j+1
+ end
+ if math.abs(glue_ratio) > drawstretchthreshold then
+ if glue_ratio < 0 then color_push.data = "0.99 0 0 rg"
+ else color_push.data = "0 0.99 0 rg" end
+ else color_push.data = "0 0 0 rg"
+ end
+
+ nodeinsertafter(line.head,node.tail(line.head),nodecopy(color_push))
+ for i = 1,math.min(j-1,7) do
+ nodeinsertafter(line.head,node.tail(line.head),glue_ratio_output[i])
+ end
+ nodeinsertafter(line.head,node.tail(line.head),nodecopy(color_pop))
+ end -- end of stretch number insertion
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection*{dubstepize} %% FIXME – Isn't that already implemented above?
+% BROOOAR WOBWOBWOB BROOOOAR WOBWOBWOB BROOOOAR WOB WOB WOB …
+% \begin{macrocode}
+
+% \end{macrocode}
+% \subsection*{scorpionize}
+% This function's intentionally not documented. In memoriam scorpionem. %% FIXME
+% \begin{macrocode}
+function scorpionize_color(head)
+ color_push.data = ".35 .55 .75 rg"
+ nodeinsertafter(head,head,nodecopy(color_push))
+ nodeinsertafter(head,node.tail(head),nodecopy(color_pop))
+ return head
+end
+% \end{macrocode}
+% \subsection{variantjustification}\label{sec:variantjustification}
+% The list |substlist| defines which glyphs can be replaced by others. Use the unicode code points for this. So far, only wider variants are possible! Extend the list at will. If you find useful definitions, send me any glyph combination!
+%
+% Some predefined values for hebrew typesetting; the list is not local so the user can change it in a very transparent way (using |\chickenizesetup{}|. This costs runtime, however … I guess … (?)
+% \begin{macrocode}
+substlist = {}
+substlist[1488] = 64289
+substlist[1491] = 64290
+substlist[1492] = 64291
+substlist[1499] = 64292
+substlist[1500] = 64293
+substlist[1501] = 64294
+substlist[1512] = 64295
+substlist[1514] = 64296
+% \end{macrocode}
+% In the function, we need reproduceable randomization so every compilation of the same document looks the same. Else this would make contracts invalid.
+%
+% The last line is excluded from the procedure as it makes no sense to extend it this way. If you really want to typeset a rectangle, use the appropriate way to disable the space at the end of the paragraph (german “Ausgang“).
+% \begin{macrocode}
+function variantjustification(head)
+ math.randomseed(1)
+ for line in nodetraverseid(nodeid"hhead",head) do
+ if (line.glue_sign == 1 and line.glue_order == 0) then -- exclude the last line!
+ substitutions_wide = {} -- we store all “expandable†letters of each line
+ for n in nodetraverseid(nodeid"glyph",line.head) do
+ if (substlist[n.char]) then
+ substitutions_wide[#substitutions_wide+1] = n
+ end
+ end
+ line.glue_set = 0 -- deactivate normal glue expansion
+ local width = node.dimensions(line.head) -- check the new width of the line
+ local goal = line.width
+ while (width < goal and #substitutions_wide > 0) do
+ x = math.random(#substitutions_wide) -- choose randomly a glyph to be substituted
+ oldchar = substitutions_wide[x].char
+ substitutions_wide[x].char = substlist[substitutions_wide[x].char] -- substitute by wide letter
+ width = node.dimensions(line.head) -- check if the line is too wide
+ if width > goal then substitutions_wide[x].char = oldchar break end -- substitute back if the line would be too wide and break out of the loop
+ table.remove(substitutions_wide,x) -- if further substitutions have to be done, remove the just substituted node from the list
+ end
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% That's it. Actually, the function is quite simple and should work out of the box. However, small columns will most probably not work as there typically is not much expandable stuff in a normal line of text.
+%
+% \subsection{zebranize}\label{sec:zebranize}
+% This function is inspired by a discussion with the Heidelberg regular's table and will change the color of each paragraph linewise. Both the textcolor and background color are changed to create a true zebra like look. If you want to change or add colors, just change the values of |zebracolorarray[]| for the text colors and |zebracolorarray_bg[]| for the background. Do not mix with other color changing functions of this package, as that will turn out ugly or erroneous.
+%
+% The code works just the same as every other thing here: insert color nodes, insert rules, and register the whole thing in |post_linebreak_filter|.
+% \subsubsection{zebranize – preliminaries}
+% \begin{macrocode}
+zebracolorarray = {}
+zebracolorarray_bg = {}
+zebracolorarray[1] = "0.1 g"
+zebracolorarray[2] = "0.9 g"
+zebracolorarray_bg[1] = "0.9 g"
+zebracolorarray_bg[2] = "0.1 g"
+% \end{macrocode}
+% \subsubsection{zebranize – the function}
+% This code has to be revisited, it is ugly.
+% \begin{macrocode}
+function zebranize(head)
+ zebracolor = 1
+ for line in nodetraverseid(nodeid"hhead",head) do
+ if zebracolor == #zebracolorarray then zebracolor = 0 end
+ zebracolor = zebracolor + 1
+ color_push.data = zebracolorarray[zebracolor]
+ line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push))
+ for n in nodetraverseid(nodeid"glyph",line.head) do
+ if n.next then else
+ nodeinsertafter(line.head,n,nodecopy(color_pull))
+ end
+ end
+
+ local rule_zebra = nodenew(RULE)
+ rule_zebra.width = line.width
+ rule_zebra.height = tex.baselineskip.width*4/5
+ rule_zebra.depth = tex.baselineskip.width*1/5
+
+ local kern_back = nodenew(RULE)
+ kern_back.width = -line.width
+
+ color_push.data = zebracolorarray_bg[zebracolor]
+ line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_pop))
+ line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push))
+ nodeinsertafter(line.head,line.head,kern_back)
+ nodeinsertafter(line.head,line.head,rule_zebra)
+ end
+ return (head)
+end
+% \end{macrocode}
+% And that's it!\qquad {\fontsize{40}{0}\raisebox{-2ex}{\XITS ☺}}
+% \newpage
+% Well, it's not the whole story so far. I plan to test some drawing using only Lua code, writing directly to the pdf file. This section will grow and get better in parallel to my understandings of what's going on. I.e. it will be very slowly … Nothing here is to be taken as good and/or correct LuaTeXing, and most code is plain ugly. However, it kind of works already {\XITS ☺}
+% \section{Drawing}
+% A \emph{very} first, experimental implementation of a drawing of a chicken. The parameters should be consistent, easy to change and that monster should look more like a cute chicken. However, it is chicken, it is Lua, so it belongs into this package. So far, all numbers and positions are hard coded, this will of course change!
+% \begin{macrocode}
+--
+function pdf_print (...)
+ for _, str in ipairs({...}) do
+ pdf.print(str .. " ")
+ end
+ pdf.print("\n")
+end
+
+function move (p)
+ pdf_print(p[1],p[2],"m")
+end
+
+function line (p)
+ pdf_print(p[1],p[2],"l")
+end
+
+function curve(p1,p2,p3)
+ pdf_print(p1[1], p1[2],
+ p2[1], p2[2],
+ p3[1], p3[2], "c")
+end
+
+function close ()
+ pdf_print("h")
+end
+
+function linewidth (w)
+ pdf_print(w,"w")
+end
+
+function stroke ()
+ pdf_print("S")
+end
+--
+
+function strictcircle(center,radius)
+ local left = {center[1] - radius, center[2]}
+ local lefttop = {left[1], left[2] + 1.45*radius}
+ local leftbot = {left[1], left[2] - 1.45*radius}
+ local right = {center[1] + radius, center[2]}
+ local righttop = {right[1], right[2] + 1.45*radius}
+ local rightbot = {right[1], right[2] - 1.45*radius}
+
+ move (left)
+ curve (lefttop, righttop, right)
+ curve (rightbot, leftbot, left)
+stroke()
+end
+
+function disturb_point(point)
+ return {point[1] + math.random()*5 - 2.5,
+ point[2] + math.random()*5 - 2.5}
+end
+
+function sloppycircle(center,radius)
+ local left = disturb_point({center[1] - radius, center[2]})
+ local lefttop = disturb_point({left[1], left[2] + 1.45*radius})
+ local leftbot = {lefttop[1], lefttop[2] - 2.9*radius}
+ local right = disturb_point({center[1] + radius, center[2]})
+ local righttop = disturb_point({right[1], right[2] + 1.45*radius})
+ local rightbot = disturb_point({right[1], right[2] - 1.45*radius})
+
+ local right_end = disturb_point(right)
+
+ move (right)
+ curve (rightbot, leftbot, left)
+ curve (lefttop, righttop, right_end)
+ linewidth(math.random()+0.5)
+ stroke()
+end
+
+function sloppyline(start,stop)
+ local start_line = disturb_point(start)
+ local stop_line = disturb_point(stop)
+ start = disturb_point(start)
+ stop = disturb_point(stop)
+ move(start) curve(start_line,stop_line,stop)
+ linewidth(math.random()+0.5)
+ stroke()
+end
+% \end{macrocode}
+%\iffalse
+% </lua>
+%\fi
+% \newpage
+% \section{Known Bugs and Fun Facts}\label{bugs}
+% The behaviour of the |\chickenize| macro is under construction and everything it does so far is considered a feature.
+% \begin{description}
+% \item[babel] Using |chickenize| with |babel| leads to a problem with the " (double quote) character, as it is made active: When using |\chickenizesetup| \emph{after} |\begin{document}|, you can \emph{not} use " for strings, but you have to use ' (single quote) instead. No problem really, but take care of this.
+% \item[medievalumlaut] You should use a decent OpenType font to get the best result. The standard font will not nicely support the positioning of the e character.
+% \item[boustrophedon and chickenize] do not work together nicely. There is an additional shift I cannot explain so far. However, if you really, really need a boustrophedon of chickenize, you do have some serious problems.
+% \item[letterspaceadjust and chickenize] When using both letterspaceadjust and chickenize, make sure to activate |\chickenize| before |\letterspaceadjust|. Elsewise the chickenization will not work due to the implementation of letterspaceadjust.
+% \end{description}
+% \section{To Do's}
+% Some things that should be implemented but aren’t so far or are very poor at the moment:
+% \begin{description}
+% \item[traversing] Every function that is based on node traversing fails when boxes are involved – so far I have not implemented recursive calling of the functions. I list it here, as it is not really a bug – this package is meant to be as simple as possible!
+% \item[countglyphs] should be extended to count anything the user wants to count
+% \item[rainbowcolor] should be more flexible – the angle of the rainbow should be easily adjustable.
+% \item[pancakenize] should do something funny.
+% \item[chickenize] should differentiate between character and punctuation.
+% \item[swing] swing dancing apes – that will be very hard, actually …
+% \item[chickenmath] chickenization of math mode
+% \end{description}
+% \section{Literature}\label{sec:literature}
+% The following list directs you to helpful literature that will help you to better understand the concepts used in this package and for in-depth explanation. Also, most of the code here is taken from or based on this literature, so it is also a list of references somehow:
+% \begin{itemize}
+% \item Lua\TeX\ documentation – the manual and links to presentations and talks: \url{http://www.luatex.org/documentation.html}
+% \item The Lua manual, for Lua 5.1: \url{http://www.lua.org/manual/5.1/}
+% \item Programming in Lua, 1\textsuperscript{st} edition, aiming at Lua 5.0, but still (largely) valid for 5.1: \url{http://www.lua.org/pil/}
+%
+%
+% \end{itemize}
+% \section{Thanks}
+% This package would not have been possible without the help of many people who patiently answered my annoying questions on mailing lists and in personal mails. And of course not without the work of the Lua\TeX\ team!
+%
+% Special thanks go to Paul “we could have chickenized the world†Isambert who contributed a lot of ideas, code and bug fixes and made much of the code executable at all. I also thank Philipp Gesang who gave me many advices on the Lua code – which I still didn't have time to correct …
+% \Finale
+% \endinput \ No newline at end of file
diff --git a/macros/luatex/generic/chickenize/chickenize.lua b/macros/luatex/generic/chickenize/chickenize.lua
new file mode 100644
index 0000000000..c25aa75b75
--- /dev/null
+++ b/macros/luatex/generic/chickenize/chickenize.lua
@@ -0,0 +1,965 @@
+--
+-- This is file `chickenize.lua',
+-- generated with the docstrip utility.
+--
+-- The original source files were:
+--
+-- chickenize.dtx (with options: `lua')
+--
+-- EXPERIMENTAL CODE
+--
+-- This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+-- modified under the conditions of the LaTeX Project Public License, either version 1.3c
+-- of this license or (at your option) any later version. This work has the LPPL mainten-
+-- ance status ‘maintained’.
+
+local nodeid = node.id
+local nodecopy = node.copy
+local nodenew = node.new
+local nodetail = node.tail
+local nodeslide = node.slide
+local noderemove = node.remove
+local nodetraverseid = node.traverse_id
+local nodeinsertafter = node.insert_after
+local nodeinsertbefore = node.insert_before
+
+Hhead = nodeid("hhead")
+RULE = nodeid("rule")
+GLUE = nodeid("glue")
+WHAT = nodeid("whatsit")
+COL = node.subtype("pdf_colorstack")
+DISC = nodeid("disc")
+GLYPH = nodeid("glyph")
+GLUE = nodeid("glue")
+HLIST = nodeid("hlist")
+KERN = nodeid("kern")
+PUNCT = nodeid("punct")
+PENALTY = nodeid("penalty")
+PDF_LITERAL = node.subtype("pdf_literal")
+color_push = nodenew(WHAT,COL)
+color_pop = nodenew(WHAT,COL)
+color_push.stack = 0
+color_pop.stack = 0
+color_push.command = 1
+color_pop.command = 2
+chicken_pagenumbers = true
+
+chickenstring = {}
+chickenstring[1] = "chicken" -- chickenstring is a table, please remeber this!
+
+chickenizefraction = 0.5
+-- set this to a small value to fool somebody, or to see if your text has been read carefully. This is also a great way to lay easter eggs for your own class / package …
+chicken_substitutions = 0 -- value to count the substituted chickens. Makes sense for testing your proofreaders.
+
+local match = unicode.utf8.match
+chickenize_ignore_word = false
+chickenize_real_stuff = function(i,head)
+ while ((i.next.id == GLYPH) or (i.next.id == KERN) or (i.next.id == DISC) or (i.next.id == HLIST)) do --find end of a word
+ i.next = i.next.next
+ end
+
+ chicken = {} -- constructing the node list.
+
+-- Should this be done only once? No, otherwise we lose the freedom to change the string in-document.
+-- But it could be done only once each paragraph as in-paragraph changes are not possible!
+
+ chickenstring_tmp = chickenstring[math.random(1,#chickenstring)]
+ chicken[0] = nodenew(GLYPH,1) -- only a dummy for the loop
+ for i = 1,string.len(chickenstring_tmp) do
+ chicken[i] = nodenew(GLYPH,1)
+ chicken[i].font = font.current()
+ chicken[i-1].next = chicken[i]
+ end
+
+ j = 1
+ for s in string.utfvalues(chickenstring_tmp) do
+ local char = unicode.utf8.char(s)
+ chicken[j].char = s
+ if match(char,"%s") then
+ chicken[j] = nodenew(GLUE)
+ chicken[j].width = space
+ chicken[j].shrink = shrink
+ chicken[j].stretch = stretch
+ end
+ j = j+1
+ end
+
+ nodeslide(chicken[1])
+ lang.hyphenate(chicken[1])
+ chicken[1] = node.kerning(chicken[1]) -- FIXME: does not work
+ chicken[1] = node.ligaturing(chicken[1]) -- dito
+
+ nodeinsertbefore(head,i,chicken[1])
+ chicken[1].next = chicken[2] -- seems to be necessary … to be fixed
+ chicken[string.len(chickenstring_tmp)].next = i.next
+
+ -- shift lowercase latin letter to uppercase if the original input was an uppercase
+ if (chickenize_capital and (chicken[1].char > 96 and chicken[1].char < 123)) then
+ chicken[1].char = chicken[1].char - 32
+ end
+
+ return head
+end
+
+chickenize = function(head)
+ for i in nodetraverseid(GLYPH,head) do --find start of a word
+ -- Random determination of the chickenization of the next word:
+ if math.random() > chickenizefraction then
+ chickenize_ignore_word = true
+ elseif chickencount then
+ chicken_substitutions = chicken_substitutions + 1
+ end
+
+ if (chickenize_ignore_word == false) then -- normal case: at the beginning of a word, we jump into chickenization
+ if (i.char > 64 and i.char < 91) then chickenize_capital = true else chickenize_capital = false end
+ head = chickenize_real_stuff(i,head)
+ end
+
+-- At the end of the word, the ignoring is reset. New chance for everyone.
+ if not((i.next.id == GLYPH) or (i.next.id == DISC) or (i.next.id == PUNCT) or (i.next.id == KERN)) then
+ chickenize_ignore_word = false
+ end
+ end
+ return head
+end
+
+local separator = string.rep("=", 28)
+local texiowrite_nl = texio.write_nl
+nicetext = function()
+ texiowrite_nl("Output written on "..tex.jobname..".pdf ("..status.total_pages.." chicken,".." eggs).")
+ texiowrite_nl(" ")
+ texiowrite_nl(separator)
+ texiowrite_nl("Hello my dear user,")
+ texiowrite_nl("good job, now go outside and enjoy the world!")
+ texiowrite_nl(" ")
+ texiowrite_nl("And don't forget to feed your chicken!")
+ texiowrite_nl(separator .. "\n")
+ if chickencount then
+ texiowrite_nl("There were "..chicken_substitutions.." substitutions made.")
+ texiowrite_nl(separator)
+ end
+end
+boustrophedon = function(head)
+ rot = node.new(WHAT,PDF_LITERAL)
+ rot2 = node.new(WHAT,PDF_LITERAL)
+ odd = true
+ for line in node.traverse_id(0,head) do
+ if odd == false then
+ w = line.width/65536*0.99625 -- empirical correction factor (?)
+ rot.data = "-1 0 0 1 "..w.." 0 cm"
+ rot2.data = "-1 0 0 1 "..-w.." 0 cm"
+ line.head = node.insert_before(line.head,line.head,nodecopy(rot))
+ nodeinsertafter(line.head,nodetail(line.head),nodecopy(rot2))
+ odd = true
+ else
+ odd = false
+ end
+ end
+ return head
+end
+boustrophedon_glyphs = function(head)
+ odd = false
+ rot = nodenew(WHAT,PDF_LITERAL)
+ rot2 = nodenew(WHAT,PDF_LITERAL)
+ for line in nodetraverseid(0,head) do
+ if odd==true then
+ line.dir = "TRT"
+ for g in nodetraverseid(GLYPH,line.head) do
+ w = -g.width/65536*0.99625
+ rot.data = "-1 0 0 1 " .. w .." 0 cm"
+ rot2.data = "-1 0 0 1 " .. -w .." 0 cm"
+ line.head = node.insert_before(line.head,g,nodecopy(rot))
+ nodeinsertafter(line.head,g,nodecopy(rot2))
+ end
+ odd = false
+ else
+ line.dir = "TLT"
+ odd = true
+ end
+ end
+ return head
+end
+boustrophedon_inverse = function(head)
+ rot = node.new(WHAT,PDF_LITERAL)
+ rot2 = node.new(WHAT,PDF_LITERAL)
+ odd = true
+ for line in node.traverse_id(0,head) do
+ if odd == false then
+texio.write_nl(line.height)
+ w = line.width/65536*0.99625 -- empirical correction factor (?)
+ h = line.height/65536*0.99625
+ rot.data = "-1 0 0 -1 "..w.." "..h.." cm"
+ rot2.data = "-1 0 0 -1 "..-w.." "..0.5*h.." cm"
+ line.head = node.insert_before(line.head,line.head,node.copy(rot))
+ node.insert_after(line.head,node.tail(line.head),node.copy(rot2))
+ odd = true
+ else
+ odd = false
+ end
+ end
+ return head
+end
+function bubblesort(head)
+ for line in nodetraverseid(0,head) do
+ for glyph in nodetraverseid(GLYPH,line.head) do
+
+ end
+ end
+ return head
+end
+-- Take care: This will slow down the compilation extremely, by about a factor of 2! Only use for playing around or counting a final version of your document!
+countglyphs = function(head)
+ for line in nodetraverseid(0,head) do
+ for glyph in nodetraverseid(GLYPH,line.head) do
+ glyphnumber = glyphnumber + 1
+ if (glyph.next.next) then
+ if (glyph.next.id == 10) and (glyph.next.next.id == GLYPH) then
+ spacenumber = spacenumber + 1
+ end
+ counted_glyphs_by_code[glyph.char] = counted_glyphs_by_code[glyph.char] + 1
+ end
+ end
+ end
+ return head
+end
+printglyphnumber = function()
+ texiowrite_nl("\nNumber of glyphs by character code (only up to 127):")
+ for i = 1,127 do --%% FIXME: should allow for more characters, but cannot be printed to console output – print into document?
+ texiowrite_nl(string.char(i)..": "..counted_glyphs_by_code[i])
+ end
+
+ texiowrite_nl("\nTotal number of glyphs in this document: "..glyphnumber)
+ texiowrite_nl("Number of spaces in this document: "..spacenumber)
+ texiowrite_nl("Glyphs plus spaces: "..glyphnumber+spacenumber.."\n")
+end
+countwords = function(head)
+ for glyph in nodetraverseid(GLYPH,head) do
+ if (glyph.next.id == 10) then
+ wordnumber = wordnumber + 1
+ end
+ end
+ wordnumber = wordnumber + 1 -- add 1 for the last word in a paragraph which is not found otherwise
+ return head
+end
+printwordnumber = function()
+ texiowrite_nl("\nNumber of words in this document: "..wordnumber)
+end
+
+function detectdoublewords(head)
+ prevlastword = {} -- array of numbers representing the glyphs
+ prevfirstword = {}
+ newlastword = {}
+ newfirstword = {}
+ for line in nodetraverseid(0,head) do
+ for g in nodetraverseid(GLYPH,line.head) do
+texio.write_nl("next glyph",#newfirstword+1)
+ newfirstword[#newfirstword+1] = g.char
+ if (g.next.id == 10) then break end
+ end
+texio.write_nl("nfw:"..#newfirstword)
+ end
+end
+
+function printdoublewords()
+ texio.write_nl("finished")
+end
+local quotestrings = {
+ [171] = true, [172] = true,
+ [8216] = true, [8217] = true, [8218] = true,
+ [8219] = true, [8220] = true, [8221] = true,
+ [8222] = true, [8223] = true,
+ [8248] = true, [8249] = true, [8250] = true,
+}
+guttenbergenize_rq = function(head)
+ for n in nodetraverseid(nodeid"glyph",head) do
+ local i = n.char
+ if quotestrings[i] then
+ noderemove(head,n)
+ end
+ end
+ return head
+end
+hammertimedelay = 1.2
+local htime_separator = string.rep("=", 30) .. "\n" -- slightly inconsistent with the “nicetextâ€
+hammertime = function(head)
+ if hammerfirst then
+ texiowrite_nl(htime_separator)
+ texiowrite_nl("============STOP!=============\n")
+ texiowrite_nl(htime_separator .. "\n\n\n")
+ os.sleep (hammertimedelay*1.5)
+ texiowrite_nl(htime_separator .. "\n")
+ texiowrite_nl("==========HAMMERTIME==========\n")
+ texiowrite_nl(htime_separator .. "\n\n")
+ os.sleep (hammertimedelay)
+ hammerfirst = false
+ else
+ os.sleep (hammertimedelay)
+ texiowrite_nl(htime_separator)
+ texiowrite_nl("======U can't touch this!=====\n")
+ texiowrite_nl(htime_separator .. "\n\n")
+ os.sleep (hammertimedelay*0.5)
+ end
+ return head
+end
+itsame = function()
+local mr = function(a,b) rectangle({a*10,b*-10},10,10) end
+color = "1 .6 0"
+for i = 6,9 do mr(i,3) end
+for i = 3,11 do mr(i,4) end
+for i = 3,12 do mr(i,5) end
+for i = 4,8 do mr(i,6) end
+for i = 4,10 do mr(i,7) end
+for i = 1,12 do mr(i,11) end
+for i = 1,12 do mr(i,12) end
+for i = 1,12 do mr(i,13) end
+
+color = ".3 .5 .2"
+for i = 3,5 do mr(i,3) end mr(8,3)
+mr(2,4) mr(4,4) mr(8,4)
+mr(2,5) mr(4,5) mr(5,5) mr(9,5)
+mr(2,6) mr(3,6) for i = 8,11 do mr(i,6) end
+for i = 3,8 do mr(i,8) end
+for i = 2,11 do mr(i,9) end
+for i = 1,12 do mr(i,10) end
+mr(3,11) mr(10,11)
+for i = 2,4 do mr(i,15) end for i = 9,11 do mr(i,15) end
+for i = 1,4 do mr(i,16) end for i = 9,12 do mr(i,16) end
+
+color = "1 0 0"
+for i = 4,9 do mr(i,1) end
+for i = 3,12 do mr(i,2) end
+for i = 8,10 do mr(5,i) end
+for i = 5,8 do mr(i,10) end
+mr(8,9) mr(4,11) mr(6,11) mr(7,11) mr(9,11)
+for i = 4,9 do mr(i,12) end
+for i = 3,10 do mr(i,13) end
+for i = 3,5 do mr(i,14) end
+for i = 7,10 do mr(i,14) end
+end
+chickenkernamount = 0
+chickeninvertkerning = false
+
+function kernmanipulate (head)
+ if chickeninvertkerning then -- invert the kerning
+ for n in nodetraverseid(11,head) do
+ n.kern = -n.kern
+ end
+ else -- if not, set it to the given value
+ for n in nodetraverseid(11,head) do
+ n.kern = chickenkernamount
+ end
+ end
+ return head
+end
+
+leetspeak_onlytext = false
+leettable = {
+ [101] = 51, -- E
+ [105] = 49, -- I
+ [108] = 49, -- L
+ [111] = 48, -- O
+ [115] = 53, -- S
+ [116] = 55, -- T
+
+ [101-32] = 51, -- e
+ [105-32] = 49, -- i
+ [108-32] = 49, -- l
+ [111-32] = 48, -- o
+ [115-32] = 53, -- s
+ [116-32] = 55, -- t
+}
+leet = function(head)
+ for line in nodetraverseid(Hhead,head) do
+ for i in nodetraverseid(GLYPH,line.head) do
+ if not leetspeak_onlytext or
+ node.has_attribute(i,luatexbase.attributes.leetattr)
+ then
+ if leettable[i.char] then
+ i.char = leettable[i.char]
+ end
+ end
+ end
+ end
+ return head
+end
+leftsideright = function(head)
+ local factor = 65536/0.99626
+ for n in nodetraverseid(GLYPH,head) do
+ if (leftsiderightarray[n.char]) then
+ shift = nodenew(WHAT,PDF_LITERAL)
+ shift2 = nodenew(WHAT,PDF_LITERAL)
+ shift.data = "q -1 0 0 1 " .. n.width/factor .." 0 cm"
+ shift2.data = "Q 1 0 0 1 " .. n.width/factor .." 0 cm"
+ nodeinsertbefore(head,n,shift)
+ nodeinsertafter(head,n,shift2)
+ end
+ end
+ return head
+end
+local letterspace_glue = nodenew(nodeid"glue")
+local letterspace_pen = nodenew(nodeid"penalty")
+
+letterspace_glue.width = tex.sp"0pt"
+letterspace_glue.stretch = tex.sp"0.5pt"
+letterspace_pen.penalty = 10000
+letterspaceadjust = function(head)
+ for glyph in nodetraverseid(nodeid"glyph", head) do
+ if glyph.prev and (glyph.prev.id == nodeid"glyph" or glyph.prev.id == nodeid"disc" or glyph.prev.id == nodeid"kern") then
+ local g = nodecopy(letterspace_glue)
+ nodeinsertbefore(head, glyph, g)
+ nodeinsertbefore(head, g, nodecopy(letterspace_pen))
+ end
+ end
+ return head
+end
+textletterspaceadjust = function(head)
+ for glyph in nodetraverseid(nodeid"glyph", head) do
+ if node.has_attribute(glyph,luatexbase.attributes.letterspaceadjustattr) then
+ if glyph.prev and (glyph.prev.id == node.id"glyph" or glyph.prev.id == node.id"disc" or glyph.prev.id == nodeid"kern") then
+ local g = node.copy(letterspace_glue)
+ nodeinsertbefore(head, glyph, g)
+ nodeinsertbefore(head, g, nodecopy(letterspace_pen))
+ end
+ end
+ end
+ luatexbase.remove_from_callback("pre_linebreak_filter","textletterspaceadjust")
+ return head
+end
+matrixize = function(head)
+ x = {}
+ s = nodenew(nodeid"disc")
+ for n in nodetraverseid(nodeid"glyph",head) do
+ j = n.char
+ for m = 0,7 do -- stay ASCII for now
+ x[7-m] = nodecopy(n) -- to get the same font etc.
+
+ if (j / (2^(7-m)) < 1) then
+ x[7-m].char = 48
+ else
+ x[7-m].char = 49
+ j = j-(2^(7-m))
+ end
+ nodeinsertbefore(head,n,x[7-m])
+ nodeinsertafter(head,x[7-m],nodecopy(s))
+ end
+ noderemove(head,n)
+ end
+ return head
+end
+medievalumlaut = function(head)
+ local factor = 65536/0.99626
+ local org_e_node = nodenew(GLYPH)
+ org_e_node.char = 101
+ for line in nodetraverseid(0,head) do
+ for n in nodetraverseid(GLYPH,line.head) do
+ if (n.char == 228 or n.char == 246 or n.char == 252) then
+ e_node = nodecopy(org_e_node)
+ e_node.font = n.font
+ shift = nodenew(WHAT,PDF_LITERAL)
+ shift2 = nodenew(WHAT,PDF_LITERAL)
+ shift2.data = "Q 1 0 0 1 " .. e_node.width/factor .." 0 cm"
+ nodeinsertafter(head,n,e_node)
+
+ nodeinsertbefore(head,e_node,shift)
+ nodeinsertafter(head,e_node,shift2)
+
+ x_node = nodenew(KERN)
+ x_node.kern = -e_node.width
+ nodeinsertafter(head,shift2,x_node)
+ end
+
+ if (n.char == 228) then -- ä
+ shift.data = "q 0.5 0 0 0.5 " ..
+ -n.width/factor*0.85 .." ".. n.height/factor*0.75 .. " cm"
+ n.char = 97
+ end
+ if (n.char == 246) then -- ö
+ shift.data = "q 0.5 0 0 0.5 " ..
+ -n.width/factor*0.75 .." ".. n.height/factor*0.75 .. " cm"
+ n.char = 111
+ end
+ if (n.char == 252) then -- ü
+ shift.data = "q 0.5 0 0 0.5 " ..
+ -n.width/factor*0.75 .." ".. n.height/factor*0.75 .. " cm"
+ n.char = 117
+ end
+ end
+ end
+ return head
+end
+local separator = string.rep("=", 28)
+local texiowrite_nl = texio.write_nl
+pancaketext = function()
+ texiowrite_nl("Output written on "..tex.jobname..".pdf ("..status.total_pages.." chicken,".." eggs).")
+ texiowrite_nl(" ")
+ texiowrite_nl(separator)
+ texiowrite_nl("Soo ... you decided to use \\pancakenize.")
+ texiowrite_nl("That means you owe me a pancake!")
+ texiowrite_nl(" ")
+ texiowrite_nl("(This goes by document, not compilation.)")
+ texiowrite_nl(separator.."\n\n")
+ texiowrite_nl("Looking forward for my pancake! :)")
+ texiowrite_nl("\n\n")
+end
+
+randomfontslower = 1
+randomfontsupper = 0
+randomfonts = function(head)
+ local rfub
+ if randomfontsupper > 0 then -- fixme: this should be done only once, no? Or at every paragraph?
+ rfub = randomfontsupper -- user-specified value
+ else
+ rfub = font.max() -- or just take all fonts
+ end
+ for line in nodetraverseid(Hhead,head) do
+ for i in nodetraverseid(GLYPH,line.head) do
+ if not(randomfonts_onlytext) or node.has_attribute(i,luatexbase.attributes.randfontsattr) then
+ i.font = math.random(randomfontslower,rfub)
+ end
+ end
+ end
+ return head
+end
+uclcratio = 0.5 -- ratio between uppercase and lower case
+randomuclc = function(head)
+ for i in nodetraverseid(GLYPH,head) do
+ if not(randomuclc_onlytext) or node.has_attribute(i,luatexbase.attributes.randuclcattr) then
+ if math.random() < uclcratio then
+ i.char = tex.uccode[i.char]
+ else
+ i.char = tex.lccode[i.char]
+ end
+ end
+ end
+ return head
+end
+randomchars = function(head)
+ for line in nodetraverseid(Hhead,head) do
+ for i in nodetraverseid(GLYPH,line.head) do
+ i.char = math.floor(math.random()*512)
+ end
+ end
+ return head
+end
+randomcolor_grey = false
+randomcolor_onlytext = false --switch between local and global colorization
+rainbowcolor = false
+
+grey_lower = 0
+grey_upper = 900
+
+Rgb_lower = 1
+rGb_lower = 1
+rgB_lower = 1
+Rgb_upper = 254
+rGb_upper = 254
+rgB_upper = 254
+rainbow_step = 0.005
+rainbow_Rgb = 1-rainbow_step -- we start in the red phase
+rainbow_rGb = rainbow_step -- values x must always be 0 < x < 1
+rainbow_rgB = rainbow_step
+rainind = 1 -- 1:red,2:yellow,3:green,4:blue,5:purple
+randomcolorstring = function()
+ if randomcolor_grey then
+ return (0.001*math.random(grey_lower,grey_upper)).." g"
+ elseif rainbowcolor then
+ if rainind == 1 then -- red
+ rainbow_rGb = rainbow_rGb + rainbow_step
+ if rainbow_rGb >= 1-rainbow_step then rainind = 2 end
+ elseif rainind == 2 then -- yellow
+ rainbow_Rgb = rainbow_Rgb - rainbow_step
+ if rainbow_Rgb <= rainbow_step then rainind = 3 end
+ elseif rainind == 3 then -- green
+ rainbow_rgB = rainbow_rgB + rainbow_step
+ rainbow_rGb = rainbow_rGb - rainbow_step
+ if rainbow_rGb <= rainbow_step then rainind = 4 end
+ elseif rainind == 4 then -- blue
+ rainbow_Rgb = rainbow_Rgb + rainbow_step
+ if rainbow_Rgb >= 1-rainbow_step then rainind = 5 end
+ else -- purple
+ rainbow_rgB = rainbow_rgB - rainbow_step
+ if rainbow_rgB <= rainbow_step then rainind = 1 end
+ end
+ return rainbow_Rgb.." "..rainbow_rGb.." "..rainbow_rgB.." rg"
+ else
+ Rgb = math.random(Rgb_lower,Rgb_upper)/255
+ rGb = math.random(rGb_lower,rGb_upper)/255
+ rgB = math.random(rgB_lower,rgB_upper)/255
+ return Rgb.." "..rGb.." "..rgB.." ".." rg"
+ end
+end
+randomcolor = function(head)
+ for line in nodetraverseid(0,head) do
+ for i in nodetraverseid(GLYPH,line.head) do
+ if not(randomcolor_onlytext) or
+ (node.has_attribute(i,luatexbase.attributes.randcolorattr))
+ then
+ color_push.data = randomcolorstring() -- color or grey string
+ line.head = nodeinsertbefore(line.head,i,nodecopy(color_push))
+ nodeinsertafter(line.head,i,nodecopy(color_pop))
+ end
+ end
+ end
+ return head
+end
+substitutewords_strings = {}
+
+addtosubstitutions = function(input,output)
+ substitutewords_strings[#substitutewords_strings + 1] = {}
+ substitutewords_strings[#substitutewords_strings][1] = input
+ substitutewords_strings[#substitutewords_strings][2] = output
+end
+
+substitutewords = function(head)
+ for i = 1,#substitutewords_strings do
+ head = string.gsub(head,substitutewords_strings[i][1],substitutewords_strings[i][2])
+ end
+ return head
+end
+suppressonecharbreakpenaltynode = node.new(PENALTY)
+suppressonecharbreakpenaltynode.penalty = 10000
+function suppressonecharbreak(head)
+ for i in node.traverse_id(GLUE,head) do
+ if ((i.next) and (i.next.next.id == GLUE)) then
+ pen = node.copy(suppressonecharbreakpenaltynode)
+ node.insert_after(head,i.next,pen)
+ end
+ end
+
+ return head
+end
+tabularasa_onlytext = false
+
+tabularasa = function(head)
+ local s = nodenew(nodeid"kern")
+ for line in nodetraverseid(nodeid"hlist",head) do
+ for n in nodetraverseid(nodeid"glyph",line.head) do
+ if not(tabularasa_onlytext) or node.has_attribute(n,luatexbase.attributes.tabularasaattr) then
+ s.kern = n.width
+ nodeinsertafter(line.list,n,nodecopy(s))
+ line.head = noderemove(line.list,n)
+ end
+ end
+ end
+ return head
+end
+tanjanize = function(head)
+ local s = nodenew(nodeid"kern")
+ local m = nodenew(GLYPH,1)
+ local use_letter_i = true
+ scale = nodenew(WHAT,PDF_LITERAL)
+ scale2 = nodenew(WHAT,PDF_LITERAL)
+ scale.data = "0.5 0 0 0.5 0 0 cm"
+ scale2.data = "2 0 0 2 0 0 cm"
+
+ for line in nodetraverseid(nodeid"hlist",head) do
+ for n in nodetraverseid(nodeid"glyph",line.head) do
+ mimicount = 0
+ tmpwidth = 0
+ while ((n.next.id == GLYPH) or (n.next.id == 11) or (n.next.id == 7) or (n.next.id == 0)) do --find end of a word
+ n.next = n.next.next
+ mimicount = mimicount + 1
+ tmpwidth = tmpwidth + n.width
+ end
+
+ mimi = {} -- constructing the node list.
+ mimi[0] = nodenew(GLYPH,1) -- only a dummy for the loop
+ for i = 1,string.len(mimicount) do
+ mimi[i] = nodenew(GLYPH,1)
+ mimi[i].font = font.current()
+ if(use_letter_i) then mimi[i].char = 109 else mimi[i].char = 105 end
+ use_letter_i = not(use_letter_i)
+ mimi[i-1].next = mimi[i]
+ end
+--]]
+
+line.head = nodeinsertbefore(line.head,n,nodecopy(scale))
+nodeinsertafter(line.head,n,nodecopy(scale2))
+ s.kern = (tmpwidth*2-n.width)
+ nodeinsertafter(line.head,n,nodecopy(s))
+ end
+ end
+ return head
+end
+uppercasecolor_onlytext = false
+
+uppercasecolor = function (head)
+ for line in nodetraverseid(Hhead,head) do
+ for upper in nodetraverseid(GLYPH,line.head) do
+ if not(uppercasecolor_onlytext) or node.has_attribute(upper,luatexbase.attributes.uppercasecolorattr) then
+ if (((upper.char > 64) and (upper.char < 91)) or
+ ((upper.char > 57424) and (upper.char < 57451))) then -- for small caps! nice ☺
+ color_push.data = randomcolorstring() -- color or grey string
+ line.head = nodeinsertbefore(line.head,upper,nodecopy(color_push))
+ nodeinsertafter(line.head,upper,nodecopy(color_pop))
+ end
+ end
+ end
+ end
+ return head
+end
+upsidedown = function(head)
+ local factor = 65536/0.99626
+ for line in nodetraverseid(Hhead,head) do
+ for n in nodetraverseid(GLYPH,line.head) do
+ if (upsidedownarray[n.char]) then
+ shift = nodenew(WHAT,PDF_LITERAL)
+ shift2 = nodenew(WHAT,PDF_LITERAL)
+ shift.data = "q 1 0 0 -1 0 " .. n.height/factor .." cm"
+ shift2.data = "Q 1 0 0 1 " .. n.width/factor .." 0 cm"
+ nodeinsertbefore(head,n,shift)
+ nodeinsertafter(head,n,shift2)
+ end
+ end
+ end
+ return head
+end
+keeptext = true
+colorexpansion = true
+
+colorstretch_coloroffset = 0.5
+colorstretch_colorrange = 0.5
+chickenize_rule_bad_height = 4/5 -- height and depth of the rules
+chickenize_rule_bad_depth = 1/5
+
+colorstretchnumbers = true
+drawstretchthreshold = 0.1
+drawexpansionthreshold = 0.9
+colorstretch = function (head)
+ local f = font.getfont(font.current()).characters
+ for line in nodetraverseid(Hhead,head) do
+ local rule_bad = nodenew(RULE)
+
+ if colorexpansion then -- if also the font expansion should be shown
+ local g = line.head
+ while not(g.id == GLYPH) and (g.next) do g = g.next end -- find first glyph on line. If line is empty, no glyph:
+ if (g.id == GLYPH) then -- read width only if g is a glyph!
+ exp_factor = g.width / f[g.char].width
+ exp_color = colorstretch_coloroffset + (1-exp_factor)*10 .. " g"
+ rule_bad.width = 0.5*line.width -- we need two rules on each line!
+ end
+ else
+ rule_bad.width = line.width -- only the space expansion should be shown, only one rule
+ end
+ rule_bad.height = tex.baselineskip.width*chickenize_rule_bad_height -- this should give a better output
+ rule_bad.depth = tex.baselineskip.width*chickenize_rule_bad_depth
+
+ local glue_ratio = 0
+ if line.glue_order == 0 then
+ if line.glue_sign == 1 then
+ glue_ratio = colorstretch_colorrange * math.min(line.glue_set,1)
+ else
+ glue_ratio = -colorstretch_colorrange * math.min(line.glue_set,1)
+ end
+ end
+ color_push.data = colorstretch_coloroffset + glue_ratio .. " g"
+
+-- set up output
+ local p = line.head
+
+ -- a rule to immitate kerning all the way back
+ local kern_back = nodenew(RULE)
+ kern_back.width = -line.width
+
+ -- if the text should still be displayed, the color and box nodes are inserted additionally
+ -- and the head is set to the color node
+ if keeptext then
+ line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push))
+ else
+ node.flush_list(p)
+ line.head = nodecopy(color_push)
+ end
+ nodeinsertafter(line.head,line.head,rule_bad) -- then the rule
+ nodeinsertafter(line.head,line.head.next,nodecopy(color_pop)) -- and then pop!
+ tmpnode = nodeinsertafter(line.head,line.head.next.next,kern_back)
+
+ -- then a rule with the expansion color
+ if colorexpansion then -- if also the stretch/shrink of letters should be shown
+ color_push.data = exp_color
+ nodeinsertafter(line.head,tmpnode,nodecopy(color_push))
+ nodeinsertafter(line.head,tmpnode.next,nodecopy(rule_bad))
+ nodeinsertafter(line.head,tmpnode.next.next,nodecopy(color_pop))
+ end
+ if colorstretchnumbers then
+ j = 1
+ glue_ratio_output = {}
+ for s in string.utfvalues(math.abs(glue_ratio)) do -- using math.abs here gets us rid of the minus sign
+ local char = unicode.utf8.char(s)
+ glue_ratio_output[j] = nodenew(GLYPH,1)
+ glue_ratio_output[j].font = font.current()
+ glue_ratio_output[j].char = s
+ j = j+1
+ end
+ if math.abs(glue_ratio) > drawstretchthreshold then
+ if glue_ratio < 0 then color_push.data = "0.99 0 0 rg"
+ else color_push.data = "0 0.99 0 rg" end
+ else color_push.data = "0 0 0 rg"
+ end
+
+ nodeinsertafter(line.head,node.tail(line.head),nodecopy(color_push))
+ for i = 1,math.min(j-1,7) do
+ nodeinsertafter(line.head,node.tail(line.head),glue_ratio_output[i])
+ end
+ nodeinsertafter(line.head,node.tail(line.head),nodecopy(color_pop))
+ end -- end of stretch number insertion
+ end
+ return head
+end
+
+function scorpionize_color(head)
+ color_push.data = ".35 .55 .75 rg"
+ nodeinsertafter(head,head,nodecopy(color_push))
+ nodeinsertafter(head,node.tail(head),nodecopy(color_pop))
+ return head
+end
+substlist = {}
+substlist[1488] = 64289
+substlist[1491] = 64290
+substlist[1492] = 64291
+substlist[1499] = 64292
+substlist[1500] = 64293
+substlist[1501] = 64294
+substlist[1512] = 64295
+substlist[1514] = 64296
+function variantjustification(head)
+ math.randomseed(1)
+ for line in nodetraverseid(nodeid"hhead",head) do
+ if (line.glue_sign == 1 and line.glue_order == 0) then -- exclude the last line!
+ substitutions_wide = {} -- we store all “expandable†letters of each line
+ for n in nodetraverseid(nodeid"glyph",line.head) do
+ if (substlist[n.char]) then
+ substitutions_wide[#substitutions_wide+1] = n
+ end
+ end
+ line.glue_set = 0 -- deactivate normal glue expansion
+ local width = node.dimensions(line.head) -- check the new width of the line
+ local goal = line.width
+ while (width < goal and #substitutions_wide > 0) do
+ x = math.random(#substitutions_wide) -- choose randomly a glyph to be substituted
+ oldchar = substitutions_wide[x].char
+ substitutions_wide[x].char = substlist[substitutions_wide[x].char] -- substitute by wide letter
+ width = node.dimensions(line.head) -- check if the line is too wide
+ if width > goal then substitutions_wide[x].char = oldchar break end -- substitute back if the line would be too wide and break out of the loop
+ table.remove(substitutions_wide,x) -- if further substitutions have to be done, remove the just substituted node from the list
+ end
+ end
+ end
+ return head
+end
+zebracolorarray = {}
+zebracolorarray_bg = {}
+zebracolorarray[1] = "0.1 g"
+zebracolorarray[2] = "0.9 g"
+zebracolorarray_bg[1] = "0.9 g"
+zebracolorarray_bg[2] = "0.1 g"
+function zebranize(head)
+ zebracolor = 1
+ for line in nodetraverseid(nodeid"hhead",head) do
+ if zebracolor == #zebracolorarray then zebracolor = 0 end
+ zebracolor = zebracolor + 1
+ color_push.data = zebracolorarray[zebracolor]
+ line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push))
+ for n in nodetraverseid(nodeid"glyph",line.head) do
+ if n.next then else
+ nodeinsertafter(line.head,n,nodecopy(color_pull))
+ end
+ end
+
+ local rule_zebra = nodenew(RULE)
+ rule_zebra.width = line.width
+ rule_zebra.height = tex.baselineskip.width*4/5
+ rule_zebra.depth = tex.baselineskip.width*1/5
+
+ local kern_back = nodenew(RULE)
+ kern_back.width = -line.width
+
+ color_push.data = zebracolorarray_bg[zebracolor]
+ line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_pop))
+ line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push))
+ nodeinsertafter(line.head,line.head,kern_back)
+ nodeinsertafter(line.head,line.head,rule_zebra)
+ end
+ return (head)
+end
+--
+function pdf_print (...)
+ for _, str in ipairs({...}) do
+ pdf.print(str .. " ")
+ end
+ pdf.print("\n")
+end
+
+function move (p)
+ pdf_print(p[1],p[2],"m")
+end
+
+function line (p)
+ pdf_print(p[1],p[2],"l")
+end
+
+function curve(p1,p2,p3)
+ pdf_print(p1[1], p1[2],
+ p2[1], p2[2],
+ p3[1], p3[2], "c")
+end
+
+function close ()
+ pdf_print("h")
+end
+
+function linewidth (w)
+ pdf_print(w,"w")
+end
+
+function stroke ()
+ pdf_print("S")
+end
+--
+
+function strictcircle(center,radius)
+ local left = {center[1] - radius, center[2]}
+ local lefttop = {left[1], left[2] + 1.45*radius}
+ local leftbot = {left[1], left[2] - 1.45*radius}
+ local right = {center[1] + radius, center[2]}
+ local righttop = {right[1], right[2] + 1.45*radius}
+ local rightbot = {right[1], right[2] - 1.45*radius}
+
+ move (left)
+ curve (lefttop, righttop, right)
+ curve (rightbot, leftbot, left)
+stroke()
+end
+
+function disturb_point(point)
+ return {point[1] + math.random()*5 - 2.5,
+ point[2] + math.random()*5 - 2.5}
+end
+
+function sloppycircle(center,radius)
+ local left = disturb_point({center[1] - radius, center[2]})
+ local lefttop = disturb_point({left[1], left[2] + 1.45*radius})
+ local leftbot = {lefttop[1], lefttop[2] - 2.9*radius}
+ local right = disturb_point({center[1] + radius, center[2]})
+ local righttop = disturb_point({right[1], right[2] + 1.45*radius})
+ local rightbot = disturb_point({right[1], right[2] - 1.45*radius})
+
+ local right_end = disturb_point(right)
+
+ move (right)
+ curve (rightbot, leftbot, left)
+ curve (lefttop, righttop, right_end)
+ linewidth(math.random()+0.5)
+ stroke()
+end
+
+function sloppyline(start,stop)
+ local start_line = disturb_point(start)
+ local stop_line = disturb_point(stop)
+ start = disturb_point(start)
+ stop = disturb_point(stop)
+ move(start) curve(start_line,stop_line,stop)
+ linewidth(math.random()+0.5)
+ stroke()
+end
+--
+-- End of File `chickenize.lua'.
diff --git a/macros/luatex/generic/chickenize/chickenize.pdf b/macros/luatex/generic/chickenize/chickenize.pdf
new file mode 100644
index 0000000000..2e4c7d9aa4
--- /dev/null
+++ b/macros/luatex/generic/chickenize/chickenize.pdf
Binary files differ
diff --git a/macros/luatex/generic/chickenize/chickenize.sty b/macros/luatex/generic/chickenize/chickenize.sty
new file mode 100644
index 0000000000..82e4b2129a
--- /dev/null
+++ b/macros/luatex/generic/chickenize/chickenize.sty
@@ -0,0 +1,32 @@
+%%
+%% This is file `chickenize.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% chickenize.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+%% modified under the conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version. This work has the LPPL mainten-
+%% ance status ‘maintained’.
+\ProvidesPackage{chickenize}%
+ [2017/08/19 v0.2.5 chickenize package]
+\input{chickenize}
+
+\iffalse
+ \DeclareDocumentCommand\includegraphics{O{}m}{
+ \fbox{Chicken} %% actually, I'd love to draw an MP graph showing a chicken …
+ }
+%%%% specials: the balmerpeak. A tribute to http://xkcd.com/323/.
+%% So far, you have to load pgfplots yourself.
+%% As it is a mighty package, I don't want the user to force loading it.
+\NewDocumentCommand\balmerpeak{G{}O{-4cm}}{
+%% to be done using Lua drawing.
+}
+\fi
+%%
+%%
+%% End of file `chickenize.sty'.
diff --git a/macros/luatex/generic/chickenize/chickenize.tex b/macros/luatex/generic/chickenize/chickenize.tex
new file mode 100644
index 0000000000..aa48c98457
--- /dev/null
+++ b/macros/luatex/generic/chickenize/chickenize.tex
@@ -0,0 +1,441 @@
+%%
+%% This is file `chickenize.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% chickenize.dtx (with options: `tex')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+%% modified under the conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version. This work has the LPPL mainten-
+%% ance status ‘maintained’.
+\directlua{dofile(kpse.find_file("chickenize.lua"))}
+
+\def\ALT{%
+ \bgroup%
+ \fontspec{Latin Modern Sans}%
+ A%
+ \kern-.4em \raisebox{.65ex}{\scalebox{0.3}{L}}%
+ \kern-.0em \raisebox{-0.98ex}{T}%
+ \egroup%
+}
+
+\def\allownumberincommands{
+ \catcode`\0=11
+ \catcode`\1=11
+ \catcode`\2=11
+ \catcode`\3=11
+ \catcode`\4=11
+ \catcode`\5=11
+ \catcode`\6=11
+ \catcode`\7=11
+ \catcode`\8=11
+ \catcode`\9=11
+}
+
+\def\BEClerize{
+ \chickenize
+ \directlua{
+ chickenstring[1] = "noise noise"
+ chickenstring[2] = "atom noise"
+ chickenstring[3] = "shot noise"
+ chickenstring[4] = "photon noise"
+ chickenstring[5] = "camera noise"
+ chickenstring[6] = "noising noise"
+ chickenstring[7] = "thermal noise"
+ chickenstring[8] = "electronic noise"
+ chickenstring[9] = "spin noise"
+ chickenstring[10] = "electron noise"
+ chickenstring[11] = "Bogoliubov noise"
+ chickenstring[12] = "white noise"
+ chickenstring[13] = "brown noise"
+ chickenstring[14] = "pink noise"
+ chickenstring[15] = "bloch sphere"
+ chickenstring[16] = "atom shot noise"
+ chickenstring[17] = "nature physics"
+ }
+}
+
+\def\boustrophedon{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",boustrophedon,"boustrophedon")}}
+\def\unboustrophedon{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","boustrophedon")}}
+
+\def\boustrophedonglyphs{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",boustrophedon_glyphs,"boustrophedon_glyphs")}}
+\def\unboustrophedonglyphs{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","boustrophedon_glyphs")}}
+
+\def\boustrophedoninverse{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",boustrophedon_inverse,"boustrophedon_inverse")}}
+\def\unboustrophedoninverse{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","boustrophedon_inverse")}}
+
+\def\bubblesort{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",bubblesort,"bubblesort")}}
+\def\unbubblesort{
+ \directlua{luatexbase.remove_from_callback("bubblesort","bubblesort")}}
+
+\def\chickenize{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",chickenize,"chickenize")
+ luatexbase.add_to_callback("start_page_number",
+ function() texio.write("["..status.total_pages) end ,"cstartpage")
+ luatexbase.add_to_callback("stop_page_number",
+ function() texio.write(" chickens]") end,"cstoppage")
+ luatexbase.add_to_callback("stop_run",nicetext,"a nice text")
+ }
+}
+\def\unchickenize{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","chickenize")
+ luatexbase.remove_from_callback("start_page_number","cstartpage")
+ luatexbase.remove_from_callback("stop_page_number","cstoppage")}}
+
+\def\coffeestainize{ %% to be implemented.
+ \directlua{}}
+\def\uncoffeestainize{
+ \directlua{}}
+
+\def\colorstretch{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",colorstretch,"stretch_expansion")}}
+\def\uncolorstretch{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","stretch_expansion")}}
+
+\def\countglyphs{
+ \directlua{
+ counted_glyphs_by_code = {}
+ for i = 1,10000 do
+ counted_glyphs_by_code[i] = 0
+ end
+ glyphnumber = 0 spacenumber = 0
+ luatexbase.add_to_callback("post_linebreak_filter",countglyphs,"countglyphs")
+ luatexbase.add_to_callback("stop_run",printglyphnumber,"printglyphnumber")
+ }
+}
+
+\def\countwords{
+ \directlua{wordnumber = 0
+ luatexbase.add_to_callback("pre_linebreak_filter",countwords,"countwords")
+ luatexbase.add_to_callback("stop_run",printwordnumber,"printwordnumber")
+ }
+}
+
+\def\detectdoublewords{
+ \directlua{
+ luatexbase.add_to_callback("post_linebreak_filter",detectdoublewords,"detectdoublewords")
+ luatexbase.add_to_callback("stop_run",printdoublewords,"printdoublewords")
+ }
+}
+
+\def\dosomethingfunny{
+ %% should execute one of the “funny†commands, but randomly. So every compilation is completely different. Maybe a list of commands could be specified to exclude total nonesense-functions. Maybe also on a per-paragraph-basis?
+}
+
+\def\dubstepenize{
+ \chickenize
+ \directlua{
+ chickenstring[1] = "WOB"
+ chickenstring[2] = "WOB"
+ chickenstring[3] = "WOB"
+ chickenstring[4] = "BROOOAR"
+ chickenstring[5] = "WHEE"
+ chickenstring[6] = "WOB WOB WOB"
+ chickenstring[7] = "WAAAAAAAAH"
+ chickenstring[8] = "duhduh duhduh duh"
+ chickenstring[9] = "BEEEEEEEEEW"
+ chickenstring[10] = "DDEEEEEEEW"
+ chickenstring[11] = "EEEEEW"
+ chickenstring[12] = "boop"
+ chickenstring[13] = "buhdee"
+ chickenstring[14] = "bee bee"
+ chickenstring[15] = "BZZZRRRRRRROOOOOOAAAAA"
+
+ chickenizefraction = 1
+ }
+}
+\let\dubstepize\dubstepenize
+
+\def\explainbackslashes{ %% inspired by xkcd #1638
+ {\tt\noindent
+\textbackslash escape character\\
+\textbackslash\textbackslash line end or escaped escape character in tex.print("")\\
+\textbackslash\textbackslash\textbackslash real, real backslash\\
+\textbackslash\textbackslash\textbackslash\textbackslash line end in tex.print("")\\
+\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash elder backslash \\
+\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash backslash which escapes the screen and enters your brain\\
+\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash backslash so real it transcends time and space \\
+\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash backslash to end all other text\\
+\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash... the true name of Ba'al, the soul-eater}
+}
+
+\def\gameoflife{
+ Your Life Is Tetris. Stop Playing It Like Chess.
+}
+
+\def\guttenbergenize{ %% makes only sense when using LaTeX
+ \AtBeginDocument{
+ \let\grqq\relax\let\glqq\relax
+ \let\frqq\relax\let\flqq\relax
+ \let\grq\relax\let\glq\relax
+ \let\frq\relax\let\flq\relax
+ \gdef\footnote##1{}
+ \gdef\cite##1{}\gdef\parencite##1{}
+ \gdef\Cite##1{}\gdef\Parencite##1{}
+ \gdef\cites##1{}\gdef\parencites##1{}
+ \gdef\Cites##1{}\gdef\Parencites##1{}
+ \gdef\footcite##1{}\gdef\footcitetext##1{}
+ \gdef\footcites##1{}\gdef\footcitetexts##1{}
+ \gdef\textcite##1{}\gdef\Textcite##1{}
+ \gdef\textcites##1{}\gdef\Textcites##1{}
+ \gdef\smartcites##1{}\gdef\Smartcites##1{}
+ \gdef\supercite##1{}\gdef\supercites##1{}
+ \gdef\autocite##1{}\gdef\Autocite##1{}
+ \gdef\autocites##1{}\gdef\Autocites##1{}
+ %% many, many missing … maybe we need to tackle the underlying mechanism?
+ }
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",guttenbergenize_rq,"guttenbergenize_rq")}
+}
+
+\def\hammertime{
+ \global\let\n\relax
+ \directlua{hammerfirst = true
+ luatexbase.add_to_callback("pre_linebreak_filter",hammertime,"hammertime")}}
+\def\unhammertime{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","hammertime")}}
+
+\let\hendlnize\chickenize % homage to Hendl/Chicken
+\let\unhendlnize\unchickenize % may the soldering strength always be with him
+
+
+\def\kernmanipulate{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",kernmanipulate,"kernmanipulate")}}
+\def\unkernmanipulate{
+ \directlua{lutaexbase.remove_from_callback("pre_linebreak_filter",kernmanipulate)}}
+
+\def\leetspeak{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",leet,"1337")}}
+\def\unleetspeak{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","1337")}}
+
+\def\leftsideright#1{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",leftsideright,"leftsideright")}
+ \directlua{
+ leftsiderightindex = {#1}
+ leftsiderightarray = {}
+ for _,i in pairs(leftsiderightindex) do
+ leftsiderightarray[i] = true
+ end
+ }
+}
+\def\unleftsideright{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","leftsideright")}}
+
+\def\letterspaceadjust{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",letterspaceadjust,"letterspaceadjust")}}
+\def\unletterspaceadjust{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","letterspaceadjust")}}
+
+\def\listallcommands{
+ \directlua{
+ for name in pairs(tex.hashtokens()) do
+ print(name)
+ end}
+}
+
+\let\stealsheep\letterspaceadjust %% synonym in honor of Paul
+\let\unstealsheep\unletterspaceadjust
+\let\returnsheep\unletterspaceadjust
+
+\def\matrixize{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",matrixize,"matrixize")}}
+\def\unmatrixize{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","matrixize")}}
+
+\def\milkcow{ %% FIXME %% to be implemented
+ \directlua{}}
+\def\unmilkcow{
+ \directlua{}}
+
+\def\medievalumlaut{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",medievalumlaut,"medievalumlaut")}}
+\def\unmedievalumlaut{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","medievalumlaut")}}
+
+\def\pancakenize{
+ \directlua{luatexbase.add_to_callback("stop_run",pancaketext,"pancaketext")}}
+
+\def\rainbowcolor{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomcolor,"rainbowcolor")
+ rainbowcolor = true}}
+\def\unrainbowcolor{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","rainbowcolor")
+ rainbowcolor = false}}
+\let\nyanize\rainbowcolor
+\let\unnyanize\unrainbowcolor
+
+\def\randomchars{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomchars,"randomchars")}}
+\def\unrandomchars{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","randomchars")}}
+
+\def\randomcolor{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomcolor,"randomcolor")}}
+\def\unrandomcolor{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","randomcolor")}}
+
+\def\randomerror{ %% FIXME
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomerror,"randomerror")}}
+\def\unrandomerror{ %% FIXME
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","randomerror")}}
+
+\def\randomfonts{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomfonts,"randomfonts")}}
+\def\unrandomfonts{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","randomfonts")}}
+
+\def\randomuclc{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",randomuclc,"randomuclc")}}
+\def\unrandomuclc{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","randomuclc")}}
+
+\let\rongorongonize\boustrophedoninverse
+\let\unrongorongonize\unboustrophedoninverse
+
+\def\scorpionize{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",scorpionize_color,"scorpionize_color")}}
+\def\unscorpionize{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","scorpionize_color")}}
+
+\def\spankmonkey{ %% to be implemented
+ \directlua{}}
+\def\unspankmonkey{
+ \directlua{}}
+
+\def\substitutewords{
+ \directlua{luatexbase.add_to_callback("process_input_buffer",substitutewords,"substitutewords")}}
+\def\unsubstitutewords{
+ \directlua{luatexbase.remove_from_callback("process_input_buffer","substitutewords")}}
+
+\def\addtosubstitutions#1#2{
+ \directlua{addtosubstitutions("#1","#2")}
+}
+
+\def\suppressonecharbreak{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",suppressonecharbreak,"suppressonecharbreak")}}
+\def\unsuppressonecharbreak{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","suppressonecharbreak")}}
+
+\def\tabularasa{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",tabularasa,"tabularasa")}}
+\def\untabularasa{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","tabularasa")}}
+
+\def\tanjanize{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",tanjanize,"tanjanize")}}
+\def\untanjanize{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","tanjanize")}}
+
+\def\uppercasecolor{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",uppercasecolor,"uppercasecolor")}}
+\def\unuppercasecolor{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","uppercasecolor")}}
+
+\def\upsidedown#1{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",upsidedown,"upsidedown")}
+ \directlua{
+ upsidedownindex = {#1}
+ upsidedownarray = {}
+ for _,i in pairs(upsidedownindex) do
+ upsidedownarray[i] = true
+ end
+ }
+}
+\def\unupsidedown{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","upsidedown")}}
+
+\def\variantjustification{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",variantjustification,"variantjustification")}}
+\def\unvariantjustification{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","variantjustification")}}
+
+\def\zebranize{
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",zebranize,"zebranize")}}
+\def\unzebranize{
+ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","zebranize")}}
+\newattribute\leetattr
+\newattribute\letterspaceadjustattr
+\newattribute\randcolorattr
+\newattribute\randfontsattr
+\newattribute\randuclcattr
+\newattribute\tabularasaattr
+\newattribute\uppercasecolorattr
+
+\long\def\textleetspeak#1%
+ {\setluatexattribute\leetattr{42}#1\unsetluatexattribute\leetattr}
+
+\long\def\textletterspaceadjust#1{
+ \setluatexattribute\letterspaceadjustattr{42}#1\unsetluatexattribute\letterspaceadjustattr
+ \directlua{
+ if (textletterspaceadjustactive) then else % -- if already active, do nothing
+ luatexbase.add_to_callback("pre_linebreak_filter",textletterspaceadjust,"textletterspaceadjust")
+ end
+ textletterspaceadjustactive = true % -- set to active
+ }
+}
+\let\textlsa\textletterspaceadjust
+
+\long\def\textrandomcolor#1%
+ {\setluatexattribute\randcolorattr{42}#1\unsetluatexattribute\randcolorattr}
+\long\def\textrandomfonts#1%
+ {\setluatexattribute\randfontsattr{42}#1\unsetluatexattribute\randfontsattr}
+\long\def\textrandomfonts#1%
+ {\setluatexattribute\randfontsattr{42}#1\unsetluatexattribute\randfontsattr}
+\long\def\textrandomuclc#1%
+ {\setluatexattribute\randuclcattr{42}#1\unsetluatexattribute\randuclcattr}
+\long\def\texttabularasa#1%
+ {\setluatexattribute\tabularasaattr{42}#1\unsetluatexattribute\tabularasaattr}
+\long\def\textuppercasecolor#1%
+ {\setluatexattribute\uppercasecolorattr{42}#1\unsetluatexattribute\uppercasecolorattr}
+\def\chickenizesetup#1{\directlua{#1}}
+\long\def\luadraw#1#2{%
+ \vbox to #1bp{%
+ \vfil
+ \latelua{pdf_print("q") #2 pdf_print("Q")}%
+ }%
+}
+\long\def\drawchicken{
+ \luadraw{90}{
+ chickenhead = {200,50} % chicken head center
+ chickenhead_rad = 20
+
+ neckstart = {215,35} % neck
+ neckstop = {230,10} %
+
+ chickenbody = {260,-10}
+ chickenbody_rad = 40
+ chickenleg = {
+ {{260,-50},{250,-70},{235,-70}},
+ {{270,-50},{260,-75},{245,-75}}
+ }
+
+ beak_top = {185,55}
+ beak_front = {165,45}
+ beak_bottom = {185,35}
+
+ wing_front = {260,-10}
+ wing_bottom = {280,-40}
+ wing_back = {275,-15}
+
+ sloppycircle(chickenhead,chickenhead_rad) sloppyline(neckstart,neckstop)
+ sloppycircle(chickenbody,chickenbody_rad)
+ sloppyline(chickenleg[1][1],chickenleg[1][2]) sloppyline(chickenleg[1][2],chickenleg[1][3])
+ sloppyline(chickenleg[2][1],chickenleg[2][2]) sloppyline(chickenleg[2][2],chickenleg[2][3])
+ sloppyline(beak_front,beak_top) sloppyline(beak_front,beak_bottom)
+ sloppyline(wing_front,wing_bottom) sloppyline(wing_back,wing_bottom)
+ }
+}
+%%
+%%
+%% End of file `chickenize.tex'.
diff --git a/macros/luatex/generic/cstypo/LICENSE b/macros/luatex/generic/cstypo/LICENSE
new file mode 100644
index 0000000000..872ab4f9e1
--- /dev/null
+++ b/macros/luatex/generic/cstypo/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2016 Václav Haisman
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/macros/luatex/generic/cstypo/README.md b/macros/luatex/generic/cstypo/README.md
new file mode 100644
index 0000000000..4b0ed9a8ef
--- /dev/null
+++ b/macros/luatex/generic/cstypo/README.md
@@ -0,0 +1,9 @@
+# cstypo
+
+This package provides macros for Czech language typography rules using Lua(La)TeX.
+
+- License is MIT license. See `LICENSE` file.
+
+- Author is [Václav Haisman](mailto:vhaisman+cstypo@gmail.com?subject=[cstypo])
+
+- Source code on GitHub in [`wilx/cstypo`](https://github.com/wilx/cstypo) repository.
diff --git a/macros/luatex/generic/cstypo/cstypo-tex.tex b/macros/luatex/generic/cstypo/cstypo-tex.tex
new file mode 100644
index 0000000000..28488daec1
--- /dev/null
+++ b/macros/luatex/generic/cstypo/cstypo-tex.tex
@@ -0,0 +1,24 @@
+\catcode`\@=11
+\directlua{cstypo_czech_language_id = \the\l@czech}
+\catcode`\@=12
+\directlua{require('cstypo')}
+
+\long\def\cstypoSingleLetterEnable{%
+ \directlua{cstypo_single_letter_enable()}}
+\long\def\cstypoSingleLetterDisable{%
+ \directlua{cstypo_single_letter_disable()}}
+
+\long\def\cstypoALetterEnable{%
+ \directlua{cstypo_a_letter_enable()}}
+\long\def\cstypoALetterDisable{%
+ \directlua{cstypo_a_letter_disable()}}
+
+\long\def\cstypoPercentsEnable{%
+ \directlua{cstypo_percents_enable()}}
+\long\def\cstypoPercentsDisable{%
+ \directlua{cstypo_percents_disable()}}
+
+\long\def\cstypoParagraphEnable{%
+ \directlua{cstypo_paragraph_enable()}}
+\long\def\cstypoParagraphDisable{%
+ \directlua{cstypo_paragraph_disable()}}
diff --git a/macros/luatex/generic/cstypo/cstypo.lua b/macros/luatex/generic/cstypo/cstypo.lua
new file mode 100644
index 0000000000..4ad6f651fb
--- /dev/null
+++ b/macros/luatex/generic/cstypo/cstypo.lua
@@ -0,0 +1,176 @@
+--[[--
+(c) 2016 Václav Haisman
+
+This program can be redistributed and/or modified under the terms of the MIT
+license. See LICENSE file.
+--]]--
+
+local GLYPH = node.id("glyph")
+--print('GLYPH value: ', GLYPH)
+
+local GLUE = node.id("glue")
+--print('GLUE value: ', GLUE)
+
+local CZECH_ID = cstypo_czech_language_id
+--print('CZECH_ID value: ', CZECH_ID)
+
+local function prevent_single_letter (head)
+ while head do
+ -- glyph
+ if (head.id == GLYPH
+ -- and in Czech or unspecified (???)
+ and (head.lang == nil
+ or head.lang == CZECH_ID)) then
+ -- only if we are at one letter word
+ if unicode.utf8.match(unicode.utf8.char(head.char), "[zZsSuUkKoOvViI]") then
+ -- and left of it is either a space
+ if ((head.prev.id == GLUE
+ -- or one of '{[('
+ or (head.prev.id == GLYPH
+ and unicode.utf8.match(unicode.utf8.char(head.prev.char),
+ "[%[%]()%{%}]")))
+ -- and right of the one letter word is also a space
+ and head.next.id == GLUE) then
+ -- then avoid line break between the single letter word and the
+ -- word following it
+ local p = node.new("penalty")
+ p.penalty = 10000
+ node.insert_after(head, head, p)
+ --print('inserting penalty at ', head)
+ end
+ end
+ end
+ head = head.next
+ end
+ return true
+end
+
+function cstypo_single_letter_enable ()
+ print('cstypo: Enabling single letter hook.')
+ luatexbase.add_to_callback("pre_linebreak_filter", prevent_single_letter,
+ "cstyposingleletter")
+end
+
+function cstypo_single_letter_disable ()
+ print('cstypo: Disabling single letter hook.')
+ luatexbase.remove_from_callback("pre_linebreak_filter", "cstyposingleletter")
+end
+
+
+local function prevent_a_letter (head)
+ while head do
+ -- glyph
+ if (head.id == GLYPH
+ -- and in Czech or unspecified (???)
+ and (head.lang == nil
+ or head.lang == CZECH_ID)) then
+ -- only if we are at one letter word
+ if unicode.utf8.match(unicode.utf8.char(head.char), "[aA]") then
+ -- and previous is space
+ if ((head.prev.id == GLUE
+ -- or previous is one of '{[('
+ or (head.prev.id == GLYPH
+ and unicode.utf8.match(unicode.utf8.char(head.prev.char),
+ "[%[%]()%{%}]")))
+ -- and right of the one letter word is also a space
+ and head.next.id == GLUE) then
+ -- then avoid line break between the single letter word and the
+ -- word following it
+ local p = node.new("penalty")
+ p.penalty = 10000
+ node.insert_after(head, head, p)
+ end
+ end
+ end
+ head = head.next
+ end
+ return true
+end
+
+function cstypo_a_letter_enable ()
+ print('cstypo: Enabling \'a\' letter hook.')
+ luatexbase.add_to_callback("pre_linebreak_filter", prevent_a_letter,
+ "cstypoaletter")
+end
+
+function cstypo_a_letter_disable ()
+ print('cstypo: Disabling \'a\' letter hook.')
+ luatexbase.remove_from_callback("pre_linebreak_filter", "cstypoaletter")
+end
+
+
+local function prevent_percents (head)
+ while head do
+ -- glyph
+ if (head.id == GLYPH
+ -- and in Czech or unspecified (???)
+ and (head.lang == nil
+ or head.lang == CZECH_ID)) then
+ -- only if we are at percentage sign
+ if unicode.utf8.match(unicode.utf8.char(head.char), "[%%‰°℃℉]") then
+ -- and left of it is a space
+ if (head.prev.id == GLUE
+ -- and left of the space is a digit.
+ and head.prev.prev.id == GLYPH
+ and unicode.utf8.match(unicode.utf8.char(head.prev.prev.char),
+ "[0-9]")) then
+ local p = node.new("penalty")
+ p.penalty = 10000
+ node.insert_after(head.prev.prev, head.prev.prev, p)
+ end
+ end
+ end
+ head = head.next
+ end
+ return true
+end
+
+function cstypo_percents_enable()
+ print('cstypo: Enabling percents hook.')
+ luatexbase.add_to_callback("pre_linebreak_filter", prevent_percents,
+ "cstypopercents")
+end
+
+function cstypo_percents_disable()
+ print('cstypo: Disabling percents hook.')
+ luatexbase.remove_from_callback("pre_linebreak_filter", "cstypopercents")
+end
+
+
+local function prevent_paragraph (head)
+ while head do
+ -- glyph
+ if (head.id == GLYPH
+ -- and in Czech or unspecified (???)
+ and (head.lang == nil
+ or head.lang == CZECH_ID)) then
+ -- only if we are at paragraph symbol
+ if unicode.utf8.match(unicode.utf8.char(head.char), "[§]") then
+ -- and right of it is a space
+ if (head.next.id == GLUE
+ and (head.next.next.id == GLYPH
+ and unicode.utf8.match(unicode.utf8.char(head.next.next.char),
+ "[0-9]"))) then
+ -- then avoid line break between the paragraph and the number
+ -- following it
+ local p = node.new("penalty")
+ p.penalty = 10000
+ node.insert_after(head, head, p)
+ end
+ end
+ end
+ head = head.next
+ end
+ return true
+end
+
+function cstypo_paragraph_enable()
+ print('cstypo: Enabling paragraph hook.')
+ luatexbase.add_to_callback("pre_linebreak_filter", prevent_paragraph,
+ "cstypoparagraph")
+end
+
+function cstypo_paragraph_disable()
+ print('cstypo: Disabling paragraph hook.')
+ luatexbase.remove_from_callback("pre_linebreak_filter", "cstypoparagraph")
+end
diff --git a/macros/luatex/generic/cstypo/cstypo.pdf b/macros/luatex/generic/cstypo/cstypo.pdf
new file mode 100644
index 0000000000..a1454c3707
--- /dev/null
+++ b/macros/luatex/generic/cstypo/cstypo.pdf
Binary files differ
diff --git a/macros/luatex/generic/cstypo/cstypo.sty b/macros/luatex/generic/cstypo/cstypo.sty
new file mode 100644
index 0000000000..a556597098
--- /dev/null
+++ b/macros/luatex/generic/cstypo/cstypo.sty
@@ -0,0 +1,45 @@
+% LaTeX package to enforce some basic Czech language typography
+% rules. Requires LuaLaTeX.
+%
+% (c) 2016 Václav Haisman
+%
+%% This program can be redistributed and/or modified under the terms of the
+%% MIT license. See LICENSE file.
+%
+\NeedsTeXFormat{LaTeX2e}[1994/06/01]
+\ProvidesPackage{cstypo}
+ [2016/08/31 v0.03 LaTeX package to enforce some basic Czech language
+ typography rules. Requires Lua(La)TeX.]
+
+\RequirePackage{ifluatex}
+
+\ifluatex
+
+\makeatletter
+\ifcsname l@czech\endcsname
+\PackageInfo{cstypo}{%
+ Czech language ID is \the\l@czech
+}
+\else
+\PackageError{cstypo}{%
+ \protect\l@czech\space is not defined
+}{%
+ Include cstypo package after polyglossia or babel.
+}
+\fi
+\makeatother
+
+\input{cstypo-tex}
+\else
+\PackageError{cstypo}{%
+ This requires LuaTeX or LuaLaTeX
+}{%
+ Compile this with LuaTeX or LuaLaTeX.
+}
+
+\fi
+
+\endinput
+
+%%
+%% End of file `cstypo.sty'.
diff --git a/macros/luatex/generic/cstypo/cstypo.tex b/macros/luatex/generic/cstypo/cstypo.tex
new file mode 100644
index 0000000000..1246e3d956
--- /dev/null
+++ b/macros/luatex/generic/cstypo/cstypo.tex
@@ -0,0 +1,138 @@
+\documentclass[paper=B5,DIV=calc,parskip=half]{scrartcl}
+\usepackage{ifluatex}
+
+\usepackage{fontspec}
+%\defaultfontfeatures{Ligatures={TeX,Common},Scale=MatchLowercase}
+\setmainfont[]{Charis SIL}
+\setsansfont[Ligatures={TeX,Common}, Scale=MatchLowercase]{TeX Gyre Heros}
+\setmonofont[Ligatures=,Scale=MatchLowercase]{DejaVu Sans Mono}
+
+\usepackage{listings}
+\usepackage{enumitem}
+%\usepackage{enumitem-zref}
+\usepackage{polyglossia}
+\setmainlanguage[]{english}
+
+\usepackage{newunicodechar}
+\newunicodechar{℃}{{°C}}
+\newunicodechar{℉}{{°F}}
+
+\usepackage[autostyle]{csquotes}
+
+\author{Václav Haisman\texorpdfstring{%
+ \\{\small\href{mailto:vhaisman+cstypo@gmail.com?subject=[cstypo]}{vhaisman@gmail.com}}}{}}
+\date{\today}
+\title{\texttt{cstypo} user manual}
+
+\PassOptionsToPackage{unicode}{hyperref}
+\usepackage{bookmark}
+\usepackage{xcolor}
+\hypersetup{
+ colorlinks,
+ linkcolor={red!50!black},
+ citecolor={blue!50!black},
+ urlcolor={blue!80!black},
+ breaklinks=true}
+\urlstyle{same} % don't use monospace font for urls
+
+\usepackage{microtype}
+\usepackage{metalogo}
+
+\setlength{\emergencystretch}{3em} % prevent overfull lines
+
+\lstdefinestyle{myLatexStyle}{
+ language=[LaTeX]{Tex},
+ basicstyle=\ttfamily
+}
+
+
+\begin{document}
+\begin{titlepage}
+ \maketitle
+\end{titlepage}
+
+\tableofcontents
+
+\section{Introduction}
+The \href{https://www.ctan.org/pkg/cstypo}{\texttt{cstypo}}\footnote{Source
+ code is on GitHub in
+ \href{https://github.com/wilx/cstypo}{\texttt{wilx/cstypo}} repository.}
+package provides macros that enforce basic Czech typography rules through Lua
+hooks available in \LuaTeX{}.
+
+\begin{enumerate}%[name=rulesList]
+\item\label{itm:singleletter} There should be no line break between single
+ letter preprosition and single letter conjugations and word following them.
+\item\label{itm:percents} There should be no line break between number and \%
+ symbol.
+\end{enumerate}
+
+There are obviously more rules than these two but only the above rules are
+enforcable through this package.
+
+\section{User interface}
+
+Czech typography rules, when enabled by the following macros, are only
+enforced on text marked as Czech by \texttt{polyglossia} or \texttt{babel}.
+
+The following two macros allow to enable and disable hook that enforces
+penalization of line breaks after single letter words:
+%(\refitem{rulesList{itm:singleletter}):
+
+\begin{lstlisting}[style=myLatexStyle]
+\cstypoSingleLetterEnable
+\cstypoSingleLetterDisable
+\end{lstlisting}
+
+The following two macros allow to enable and disable hook that enforces the
+same rule as above but for ‘a’ conjugation. The reason that this is separete
+from the rest of the single letter prepositions and conjugations is that line
+break after ‘a’ is tolerated for narrow column texts. It might be desirable
+to have this rule enforced for all of the single letter words except for the
+‘a’.
+
+\begin{lstlisting}[style=myLatexStyle]
+\cstypoALetterEnable
+\cstypoALetterDisable
+\end{lstlisting}
+
+The following two macros allow to enable and disable hook that enforces
+penalization of line breaks between number and \enquote*{\%} symbol and also
+few more symbols: per thousand~\enquote*{‰}, degree~\enquote*{°}, degree
+Celsius~\enquote*{℃} and degree Fahrenheit~\enquote*{℉}.
+
+\begin{lstlisting}[style=myLatexStyle]
+\cstypoPercentsEnable
+\cstypoPercentsDisable
+\end{lstlisting}
+
+The following two macros allow to enable and disable hook that enforces
+penalization of line breaks between~\enquote*{§} symbol and following number.
+
+\begin{lstlisting}[style=myLatexStyle]
+\cstypoParagraphEnable
+\cstypoParagraphDisable
+\end{lstlisting}
+
+
+\section{History}
+
+This package was inspired by
+\texttt{\href{http://www.ctan.org/pkg/impnattypo}{impnattypo}} French
+typography package. It would not be possible without help and comments from
+people of
+\href{http://chat.stackexchange.com/rooms/41/tex-latex-and-friends}{\TeX{},
+ \LaTeX{} and Friends} StackExchange chat room and the
+\href{http://tex.stackexchange.com/}{\TeX.SE} site itself.
+
+\begin{description}[style=nextline, labelwidth=4.5em, leftmargin=!, labelindent=0em]
+\item[\texttt{v0.03}] Limit Czech typography rules enforcement only to text
+ marked as Czech language. Handle per thousand~\enquote*{‰},
+ degree~\enquote*{°}, degree Celsius~\enquote*{℃}, degree
+ Fahrenheit~\enquote*{℉} and paragraph~\enquote*{§} symbols.
+\item[\texttt{v0.02}] Fixed some packaging and documentation issues found by
+ CTAN submission review.
+\item[\texttt{v0.01}] First published version of this package.
+\end{description}
+
+\end{document}
diff --git a/macros/luatex/generic/cstypo/cstypotest.pdf b/macros/luatex/generic/cstypo/cstypotest.pdf
new file mode 100644
index 0000000000..1d6912a134
--- /dev/null
+++ b/macros/luatex/generic/cstypo/cstypotest.pdf
Binary files differ
diff --git a/macros/luatex/generic/cstypo/cstypotest.tex b/macros/luatex/generic/cstypo/cstypotest.tex
new file mode 100644
index 0000000000..bfdc3cfab4
--- /dev/null
+++ b/macros/luatex/generic/cstypo/cstypotest.tex
@@ -0,0 +1,158 @@
+\documentclass{article}
+\usepackage{lmodern}
+\usepackage{ifluatex}
+\usepackage[a6paper]{geometry}
+\usepackage{parskip}
+\usepackage{polyglossia}
+\setmainlanguage[]{czech}
+\setotherlanguage{english}
+\usepackage{microtype}
+
+\setlength{\emergencystretch}{3em} % prevent overfull lines
+\newcommand{\expl}[1]{\begin{english}\sffamily #1\end{english}}
+
+\usepackage{cstypo}
+
+\begin{document}
+\section{Bad line breaks}
+\expl{The follwing text has prepostions `O' and `k' at end of line which
+ is incorrect according to Czech language typography standards:}
+
+Mezi oblíbené dÄ›tské pohádky patří pohádky \emph{O PaleÄkovi, Alenka v říši
+ divů} a \emph{Socialismem k lepším zítřkům.}
+
+\expl{The follwing text is the same as above but parentheses are used to test
+ that a preposition stay (or not stay, in this case) with following word
+ even if the prepostion is preceeded with a parenthesis:}
+
+Mezi oblíbené dÄ›tské pohádky patří pohádky \emph{[O PaleÄkovi], Alenka v říši
+ divů} a \emph{Socialismem (k lepším zítřkům).}
+
+\expl{Next line shows bad line break between number and the \% symbol.}
+
+Se správným nastavením fontů znak \% v `na 100 \%' skonÄí na další řádce.
+
+\expl{Next line is similar as the one above but tests behaviour for the ‰
+ character.}
+
+Zde, v České republice, stále není povoleno ani 1 ‰ alkoholu v krvi při
+řízení automobilu.
+
+\expl{Next line shows bad line break between degree sign `°' and number.}
+
+SouÄet vÅ¡ech tří úhlů v trojůhelníku je vždy 180 °.
+
+Voda taje při teplotě 0 ℃ a vypařuje se při 100 ℃.
+
+\expl{Next line show use of ``paragraf'' symbol. It should be kept with the
+ following number.}
+
+Jak může státní zástupce věc odložit zmiňuje § 159a.
+
+\section{Better line breaks}
+\expl{And here we add Lua code to penalize single letter words. It results in
+following line layout:}
+
+\cstypoSingleLetterEnable{}
+\cstypoPercentsEnable{}
+\cstypoALetterEnable{}
+\cstypoParagraphEnable{}
+Mezi oblíbené dÄ›tské pohádky patří pohádky \emph{O PaleÄkovi, Alenka v říši
+ divů} a \emph{Socialismem k lepším zítřkům.}
+
+\expl{The follwing text is the same as above but parentheses are used to test
+ that a preposition stay with following word even if the prepostion is
+ preceeded with a parenthesis:}
+
+Mezi oblíbené dÄ›tské pohádky patří pohádky \emph{[O PaleÄkovi], Alenka v říši
+ divů} a \emph{Socialismem (k lepším zítřkům).}
+
+\expl{Here, the \% symbol should be together with the number.}
+
+Se správným nastavením fontů znak \% v `na 100 \%' skonÄí na další řádce.
+
+\expl{Next line is similar as the one above but tests behaviour for the ‰
+ character.}
+
+Zde, v České republice, stále není povoleno ani 1 ‰ alkoholu v krvi při
+řízení automobilu.
+
+\expl{Next line shows line break between degree sign `°' and number. The
+ degree sign should stay with the number.}
+
+SouÄet vÅ¡ech tří úhlů v trojůhelníku je vždy 180 °.
+
+Voda taje při teplotě 0 ℃ a vypařuje se při 100 ℃.
+
+\expl{Next line show use of ``paragraf'' symbol. It should be kept with the
+ following number.}
+
+Jak může státní zástupce věc odložit zmiňuje § 159a.
+
+
+\section{Bad line breaks because of English}
+\expl{This section shows that while the hooks are still active, the actual
+ Czech language text is marked as English which results in bad line breaks.}
+
+\begin{english}
+Mezi oblíbené dÄ›tské pohádky patří pohádky \emph{O PaleÄkovi, Alenka v říši
+ divů} a \emph{Socialismem k lepším zítřkům.}
+
+Mezi oblíbené dÄ›tské pohádky patří pohádky \emph{[O PaleÄkovi], Alenka v říši
+ divů} a \emph{Socialismem (k lepším zítřkům).}
+
+Se správným nastavením fontů znak \% v `na 100 \%' skonÄí na další řádce.
+
+Zde, v České republice, stále není povoleno ani 1 ‰ alkoholu v krvi při
+řízení automobilu.
+
+SouÄet vÅ¡ech tří úhlů v trojůhelníku je vždy 180 °.
+
+Voda taje při teplotě 0 ℃ a vypařuje se při 100 ℃.
+
+Jak může státní zástupce věc odložit zmiňuje § 159a.
+
+\end{english}
+
+
+\section{Bad line breaks again}
+\expl{This section shows that disabling of the hook works and that the
+ prepositions are again left at the end of their line.}
+
+\cstypoSingleLetterDisable{}
+\cstypoPercentsDisable{}
+\cstypoALetterDisable{}
+\cstypoParagraphDisable{}
+
+Mezi oblíbené dÄ›tské pohádky patří pohádky \emph{O PaleÄkovi, Alenka v říši
+ divů} a \emph{Socialismem k lepším zítřkům.}
+
+\expl{The follwing text is the same as above but parentheses are used to test
+ that a preposition stay (or not stay, in this case) with following word
+ even if the prepostion is preceeded with a parenthesis:}
+
+Mezi oblíbené dÄ›tské pohádky patří pohádky \emph{[O PaleÄkovi], Alenka v říši
+ divů} a \emph{Socialismem (k lepším zítřkům).}
+
+\expl{And here, line break is inserted before the \% symbol again.}
+
+Se správným nastavením fontů znak \% v `na 100 \%' skonÄí na další řádce.
+
+\expl{Next line is similar as the one above but tests behaviour for the ‰
+ character.}
+
+Zde, v České republice, stále není povoleno ani 1 ‰ alkoholu v krvi při
+řízení automobilu.
+
+\expl{Next line shows bad line break between degree sign `°' and number.}
+
+SouÄet vÅ¡ech tří úhlů v trojůhelníku je vždy 180 °.
+
+Voda taje při teplotě 0 ℃ a vypařuje se při 100 ℃.
+
+\expl{Next line show use of ``paragraf'' symbol. It should be kept with the
+ following number.}
+
+Jak může státní zástupce věc odložit zmiňuje § 159a.
+
+\end{document}
diff --git a/macros/luatex/generic/ctablestack/README.md b/macros/luatex/generic/ctablestack/README.md
new file mode 100644
index 0000000000..6f9e145f26
--- /dev/null
+++ b/macros/luatex/generic/ctablestack/README.md
@@ -0,0 +1,4 @@
+This package provides a stack system for category code tables in LuaTeX.
+The code here builds on the LaTeX kernel support for LuaTeX (LaTeX2e
+2015/10/01 onward), which is also available as `ltluatex.tex` for plain
+TeX users and those with older LaTeX kernel implementations.
diff --git a/macros/luatex/generic/ctablestack/ctablestack.dtx b/macros/luatex/generic/ctablestack/ctablestack.dtx
new file mode 100644
index 0000000000..63a3260a37
--- /dev/null
+++ b/macros/luatex/generic/ctablestack/ctablestack.dtx
@@ -0,0 +1,207 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2015 David Carlisle and Joseph Wright
+%
+% It may be distributed and/or modified under the conditions of
+% the LaTeX Project Public License (LPPL), either version 1.3c of
+% this license or (at your option) any later version. The latest
+% version of this license is in the file:
+%
+% http://www.latex-project.org/lppl.txt
+%
+%<package>\ifx
+%<package> \ProvidesPackage\undefined\begingroup\def\ProvidesPackage
+%<package> #1#2[#3]{\endgroup\immediate\write-1{Package: #1 #3}}
+%<package>\fi
+%<package>\ProvidesPackage{ctablestack}
+%<*driver>
+\ProvidesFile{ctablestack.dtx}
+%</driver>
+%<*package>
+ [2015/10/01 v1.0 Catcode table stable support]
+%</package>
+%<*driver>
+\documentclass{ltxdoc}
+\GetFileInfo{ctablestack.dtx}
+\begin{document}
+\title{\filename\\Catcode table stable support}
+\author{David Carlisle and Joseph Wright}
+\date{\filedate}
+\maketitle
+\setcounter{tocdepth}{2}
+\tableofcontents
+\DocInput{\filename}
+\end{document}
+%</driver>
+% \fi
+%
+% \section{Overview}
+%
+% This small package adds support for a stack of category code tables to
+% the core support for Lua\TeX{} provided by the \LaTeX{} kernel and
+% available for plain users as |ltluatex.tex|. As such, the
+% code here may be used with both plain \TeX{} and \LaTeX{}, and requires
+% either an up-to-date \LaTeX{} kernel (2016 onward), use of \textsf{latexrelease}
+% with older kernels or loading |ltluatex.tex| for plain users.
+%
+% The commands here are aimed mainly for use by package authors to develop
+% environments needing specific catcode regimes. As such the package does
+% not define any user level commands.
+%
+% \noindent
+% \DescribeMacro{\@setrangecatcode}
+% |\@setrangecatcode{|\meta{start}|}{|\meta{end}|}{|\meta{catcode}|}|\\
+% Sets all characters in the range \meta{start}--\meta{end} inclusive to
+% have the \meta{catcode} specified.
+%
+% \noindent
+% \DescribeMacro{\@pushcatcodetable}
+% \DescribeMacro{\@popcatcodetable}
+% |\@pushcatcodetable|\\
+% |\@popcatcodetable|\\
+% This pair of commands enable the current category code r\'{e}gime to
+% be saved and restored meaning that arbitrary catcode changes can be made.
+% This functionality will normally be used in concert with applying
+% catcode tables. For example
+% \begin{verbatim}
+% \catcode`\Z=4 %
+% \@pushcatcodetable
+% \catcodetable\catcodetable@latex
+% % Code here
+% \@popcatcodetable
+% \showthe\catcode`\Z
+% \end{verbatim}
+% will ensure that the `content' is set with normal category codes but
+% allow restoration of the non-standard codes at the conclusion. Importantly,
+% it does not require that anything is known about the catcode situation in
+% advance (\emph{cf.}~a more traditional approach to saving the state of
+% targeting characters).
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\edef\ctstackatcatcode{\the\catcode`\@}
+\catcode`\@=11
+% \end{macrocode}
+%
+% Check for \textsf{ltluatex} functionality using \cs{newluafunction} as a marker.
+% \begin{macrocode}
+\ifx\newluafunction\@undefined
+ \input{ltluatex}%
+\fi
+% \end{macrocode}
+%
+% \begin{macro}{\@setcatcodetable}
+% Save a catcode table specified in |#1| using the catcode settings specified in |#2|.
+% These settings are executed in a local group to avoid affecting surrounding code.
+% (Saving a catcode table is always a global operation.)
+% \begin{macrocode}1
+\def\@setcatcodetable#1#2{%
+ \begingroup
+ #2%
+ \savecatcodetable#1%
+ \endgroup
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@setrangecatcode}
+% Set a range of characters from |#1| to |#2| inclusive to the catcode specified in |#3|.
+% \begin{macrocode}
+\def\@setrangecatcode#1#2#3{%
+ \ifnum#1>#2 %
+ \expandafter\@gobble
+ \else
+ \expandafter\@firstofone
+ \fi
+ {%
+ \catcode#1=#3 %
+ \expandafter\@setrangecatcode\expandafter
+ {\number\numexpr#1+1\relax}{#2}{#3}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@catcodetablelist}
+% \begin{macro}{\@catcodetablestack}
+% Data structures for a stack: a list of free tables in the stack and
+% the stack record itself.
+% \begin{macrocode}
+\def\@catcodetablelist{}
+\def\@catcodetablestack{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@catcodetablestackcnt}
+% A count for adding to the list of scratch tables.
+% \begin{macrocode}
+\newcount\@catcodetablestackcnt
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@pushcatcodetable}
+% \begin{macro}{\@pushctbl}
+% To push a table, first check there is a free one in the pool and if
+% not create one. Then take the top table in the pool and use it to save
+% the current table.
+% \begin{macrocode}
+\def\@pushcatcodetable{%
+ \ifx\@catcodetablelist\empty
+ \global\advance\@catcodetablestackcnt by\@ne
+ \edef\@tempa{\csname ct@\the\@catcodetablestackcnt\endcsname}%
+ \expandafter\newcatcodetable\@tempa
+ \xdef\@catcodetablelist{\@tempa}%
+ \fi
+ \expandafter\@pushctbl\@catcodetablelist\@nil
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\@pushctbl#1#2\@nil{%
+ \gdef\@catcodetablelist{#2}%
+ \xdef\@catcodetablestack{#1\@catcodetablestack}%
+ \savecatcodetable#1%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@popcatcodetable}
+% \begin{macro}{\@popctbl}
+% Much the same in reverse.
+% \begin{macrocode}
+\def\@popcatcodetable{%
+ \if!\@catcodetablestack!%
+ \errmessage{Attempt to pop empty catcodetable stack}%
+ \else
+ \expandafter\@popctbl\@catcodetablestack\@nil
+ \fi
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\@popctbl#1#2\@nil{%
+ \gdef\@catcodetablestack{#2}%
+ \xdef\@catcodetablelist{\@catcodetablelist#1}%
+ \catcodetable#1%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+\catcode`\@\ctstackatcatcode\relax
+% \end{macrocode}
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \Finale
diff --git a/macros/luatex/generic/ctablestack/ctablestack.ins b/macros/luatex/generic/ctablestack/ctablestack.ins
new file mode 100644
index 0000000000..3da7318eed
--- /dev/null
+++ b/macros/luatex/generic/ctablestack/ctablestack.ins
@@ -0,0 +1,10 @@
+\input docstrip
+\keepsilent
+\nopreamble
+\nopostamble
+
+\askforoverwritefalse
+
+\generate{\file{ctablestack.sty}{\from{ctablestack.dtx}{package}}}
+
+\endbatchfile
diff --git a/macros/luatex/generic/ctablestack/ctablestack.pdf b/macros/luatex/generic/ctablestack/ctablestack.pdf
new file mode 100644
index 0000000000..b083b9e3fc
--- /dev/null
+++ b/macros/luatex/generic/ctablestack/ctablestack.pdf
Binary files differ
diff --git a/macros/luatex/generic/enigma/COPYING b/macros/luatex/generic/enigma/COPYING
new file mode 100644
index 0000000000..dad85d026e
--- /dev/null
+++ b/macros/luatex/generic/enigma/COPYING
@@ -0,0 +1,22 @@
+Copyright 2011-2013 Philipp Gesang. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/macros/luatex/generic/enigma/README b/macros/luatex/generic/enigma/README
new file mode 100644
index 0000000000..1da3eb0790
--- /dev/null
+++ b/macros/luatex/generic/enigma/README
@@ -0,0 +1,29 @@
+Description of files:
+
+./enigma-example-context.tex usage example for Context
+./enigma-example-latex.tex usage example for LaTeX
+./enigma-example-plain.tex usage example for Plain
+./COPYING License (BSD)
+./enigma_manual.tex manual source (Context)
+./enigma-doc.pdf compiled manual
+./mtx-t-enigma.lua mtx script (run as “mtxrun --script enigmaâ€)
+./enigma.lua format independent code
+./t-enigma.mkvi Context interface
+./enigma.sty wrapper for LaTeX (inputs enigma.tex)
+./enigma.tex Plain interface
+
+This is the directory layout I have in mind:
+
+enigma_manual.tex -> ./doc/context/third/enigma/enigma_manual.tex
+enigma-example-plain.tex -> ./doc/context/third/enigma/examples/enigma-example-plain.tex
+enigma-example-latex.tex -> ./doc/context/third/enigma/examples/enigma-example-latex.tex
+enigma-example-context.tex -> ./doc/context/third/enigma/examples/enigma-example-context.tex
+enigma-doc.pdf -> ./doc/context/third/enigma/enigma-doc.pdf
+COPYING -> ./doc/context/third/enigma/COPYING
+mtx-t-enigma.lua -> ./scripts/context/lua/third/enigma/mtx-t-enigma.lua
+t-enigma.mkvi -> ./tex/context/third/enigma/t-enigma.mkvi
+enigma.sty -> ./tex/latex/enigma/enigma.sty
+enigma.tex -> ./tex/plain/enigma/enigma.tex
+enigma.lua -> ./tex/generic/enigma/enigma.lua
+
+
diff --git a/macros/luatex/generic/enigma/enigma-doc.pdf b/macros/luatex/generic/enigma/enigma-doc.pdf
new file mode 100644
index 0000000000..2a9a2f9ab7
--- /dev/null
+++ b/macros/luatex/generic/enigma/enigma-doc.pdf
Binary files differ
diff --git a/macros/luatex/generic/enigma/enigma-example-context.tex b/macros/luatex/generic/enigma/enigma-example-context.tex
new file mode 100644
index 0000000000..051e719697
--- /dev/null
+++ b/macros/luatex/generic/enigma/enigma-example-context.tex
@@ -0,0 +1,59 @@
+\usemodule [enigma]
+%\usetypescript [computer-modern-unicode]
+%\setupbodyfont [computer-modern-unicode,20pt]
+%\usetypescript [iwona]
+%\setupbodyfont [iwona,20pt]
+\usetypescript [modern]
+\setupbodyfont [modern,20pt]
+
+\defineenigma [nilsettings]
+\setupenigma [nilsettings] [ %% a machine with vanilla settings
+ other_chars = no,
+ day_key = I II III 01 01 01,
+ rotor_setting = aaa,
+ spacing = yes,
+ verbose = 3,
+]
+
+\defineenigma [othernilsettings] [nilsettings]
+
+\defineenigma [secretmessage]
+\setupenigma [secretmessage] [
+ other_chars = yes,
+ day_key = B V III II 12 03 01 GI JV KZ WM PU QY AD CN ET FL,
+ rotor_setting = ben,
+]
+
+\defineenigma [othersecretmessage] [secretmessage]
+
+\defineenigma [othermessage] [secretmessage]
+\setupenigma [othermessage] [other_chars=wrong]
+
+\starttext
+
+\placefigure{Enigma output and its reversal using nil settings}{
+ \framed [width=.7\hsize,frame=off,align=middle]{
+ \startnilsettings
+ aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aa
+ \stopnilsettings
+
+ \startothernilsettings
+ bdzgo wcxlt ksbtm cdlpb muqof xyhcx tgyjf linhn xs
+ \stopothernilsettings
+ }
+}
+
+\startsecretmessage
+ føo bąr baž
+\stopsecretmessage
+
+\startothersecretmessage
+ iøtyąwqiž
+\stopothersecretmessage
+
+\startothermessage
+ føo bąr baž
+\stopothermessage
+
+\stoptext
+% vim:ft=context:tw=71:ts=2:sw=2:expandtab
diff --git a/macros/luatex/generic/enigma/enigma-example-latex.tex b/macros/luatex/generic/enigma/enigma-example-latex.tex
new file mode 100644
index 0000000000..ea825cf1e9
--- /dev/null
+++ b/macros/luatex/generic/enigma/enigma-example-latex.tex
@@ -0,0 +1,53 @@
+\documentclass[a5paper]{scrartcl}
+\parindent0pt
+%%····································································%
+\usepackage {enigma}
+%%····································································%
+%% The first machine will be used for encryption of our plain text.
+\defineenigma {encryption}
+\setupenigma {encryption} {
+ other_chars = yes,
+ day_key = B V III II 12 03 01 GI JV KZ WM PU QY AD CN ET FL,
+ rotor_setting = ben,
+ spacing = yes,
+ verbose = 2,
+}
+%%····································································%
+%% This second machine below will be used to decrypt the string. It is
+%% initialized with exactly the same settings as the first one. The
+%% reason for this is that we can’t reuse the “encryption†machine as
+%% it will already have progressed to some later state after the
+%% encryption. Applying it on the ciphertext would yield a totally
+%% different string. Hence the need for another machine.
+\defineenigma{decryption}
+\setupenigma{decryption}{
+ other_chars = yes,
+ day_key = B V III II 12 03 01 GI JV KZ WM PU QY AD CN ET FL,
+ rotor_setting = ben,
+}
+%%····································································%
+\begin{document}
+
+%%····································································%
+%% Ciphertext in the PDF. Rely on the addressee to decrypt the document
+%% externally.
+\beginencryption
+ Never underestimate the amount of money, time, and effort someone
+ will expend to thwart a security system.
+\endencryption
+
+%%····································································%
+%% Input string generated with:
+%% mtxrun --script t-enigma \
+%% --setup="day_key=B V III II 12 03 01 GI JV KZ WM PU QY AD CN ET FL,\
+%% rotor_setting=ben,\
+%% other_chars=yes"\
+%% --text="Never underestimate the amount of money,\
+%% time, and effort someone will expend to\
+%% thwart a security system."
+\begindecryption
+ aqsnwyxgqarpuzrdktscbslaqmdhyonywxkwhcdgphvuqsspfjwhlszahygjbzmfpcpbniahvfcuradntepxsfchnn
+\enddecryption
+%%····································································%
+\end{document}
+% vim:ft=tex:tw=71:expandtab:ts=2:sw=2
diff --git a/macros/luatex/generic/enigma/enigma-example-plain.tex b/macros/luatex/generic/enigma/enigma-example-plain.tex
new file mode 100644
index 0000000000..bd50c93ca4
--- /dev/null
+++ b/macros/luatex/generic/enigma/enigma-example-plain.tex
@@ -0,0 +1,50 @@
+\parindent0pt
+%%····································································%
+\input {enigma}
+%%····································································%
+%% The first machine will be used for encryption of our plain text.
+\defineenigma {encryption}
+\setupenigma {encryption} {
+ other_chars = yes,
+ day_key = B V III II 12 03 01 GI JV KZ WM PU QY AD CN ET FL,
+ rotor_setting = ben,
+ spacing = yes,
+ verbose = 1,
+}
+%%····································································%
+%% This second machine below will be used to decrypt the string.
+\defineenigma{decryption}
+\setupenigma{decryption}{
+ other_chars = yes,
+ day_key = B V III II 12 03 01 GI JV KZ WM PU QY AD CN ET FL,
+ rotor_setting = ben,
+}
+%%····································································%
+%% main
+%%····································································%
+%% Ciphertext in the PDF. Rely on the addressee to decrypt the document
+%% externally.
+%%····································································%
+%% encryption of plain text
+%%····································································%
+\beginencryption
+ Never underestimate the amount of money, time, and effort someone
+ will expend to thwart a security system.
+\endencryption
+
+%%····································································%
+%% decryption of ciphertext
+%%····································································%
+%% Input string generated with:
+%% mtxrun --script t-enigma \
+%% --setup="day_key=B V III II 12 03 01 GI JV KZ WM PU QY AD CN ET FL,\
+%% rotor_setting=ben,\
+%% other_chars=yes"\
+%% --text="Never underestimate the amount of money,\
+%% time, and effort someone will expend to\
+%% thwart a security system."
+\begindecryption
+ aqsnwyxgqarpuzrdktscbslaqmdhyonywxkwhcdgphvuqsspfjwhlszahygjbzmfpcpbniahvfcuradntepxsfchnn
+\enddecryption
+%%·····································································%
+\bye
diff --git a/macros/luatex/generic/enigma/enigma.lua b/macros/luatex/generic/enigma/enigma.lua
new file mode 100644
index 0000000000..9da428842b
--- /dev/null
+++ b/macros/luatex/generic/enigma/enigma.lua
@@ -0,0 +1,1662 @@
+#!/usr/bin/env texlua
+-----------------------------------------------------------------------
+-- FILE: enigma.lua
+-- USAGE: Call via interface from within a TeX session.
+-- DESCRIPTION: Enigma logic.
+-- REQUIREMENTS: LuaTeX capable format (Luaplain, ConTeXt).
+-- AUTHOR: Philipp Gesang (Phg), <phg42 dot 2a at gmail dot com>
+-- VERSION: release
+-- CREATED: 2013-03-28 02:12:03+0100
+-----------------------------------------------------------------------
+--
+
+--[[ichd--
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startdocsection[title=Format Dependent Code]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\startparagraph
+Exported functionality will be collected in the table
+\identifier{enigma}.
+\stopparagraph
+--ichd]]--
+
+local enigma = { machines = { }, callbacks = { } }
+local format_is_context = false
+
+--[[ichd--
+\startparagraph
+Afaict, \LATEX\ for \LUATEX\ still lacks a globally accepted
+namespacing convention. This is more than bad, but we’ll have to cope
+with that. For this reason we brazenly introduce
+\identifier{packagedata} (in analogy to \CONTEXT’s
+\identifier{thirddata}) table as a package namespace proposal. If this
+module is called from a \LATEX\ or plain session, the table
+\identifier{packagedata} will already have been created so we will
+identify the format according to its presence or absence, respectively.
+\stopparagraph
+--ichd]]--
+
+if packagedata then -- latex or plain
+ packagedata.enigma = enigma
+elseif thirddata then -- context
+ format_is_context = true
+ thirddata.enigma = enigma
+else -- external call, mtx-script or whatever
+ _ENV.enigma = enigma
+end
+--[[ichd--
+\stopdocsection
+--ichd]]--
+
+--[[ichd--
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startdocsection[title=Prerequisites]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startparagraph
+First of all, we generate local copies of all those library functions
+that are expected to be referenced frequently.
+The format-independent stuff comes first; it consists of functions from
+the
+\identifier{io},
+\identifier{lpeg},
+\identifier{math},
+\identifier{string},
+\identifier{table}, and
+\identifier{unicode}
+libraries.
+\stopparagraph
+--ichd]]--
+
+local get_debug_info = debug.getinfo
+local ioread = io.read
+local iowrite = io.write
+local mathfloor = math.floor
+local mathrandom = math.random
+local next = next
+local nodecopy = node and node.copy
+local nodeid = node and node.id
+local nodeinsert_before = node and node.insert_before
+local nodeinsert_after = node and node.insert_after
+local nodelength = node and node.length
+local nodenew = node and node.new
+local noderemove = node and node.remove
+local nodeslide = node and node.slide
+local nodetraverse = node and node.traverse
+local nodetraverse_id = node and node.traverse_id
+local nodesinstallattributehandler
+local nodestasksappendaction
+local nodestasksdisableaction
+if format_is_context then
+ nodesinstallattributehandler = nodes.installattributehandler
+ nodestasksappendaction = nodes.tasks.appendaction
+ nodestasksdisableaction = nodes.tasks.disableaction
+end
+local stringfind = string.find
+local stringformat = string.format
+local stringlower = string.lower
+local stringsub = string.sub
+local stringupper = string.upper
+local tableconcat = table.concat
+local tonumber = tonumber
+local type = type
+local utf8byte = unicode.utf8.byte
+local utf8char = unicode.utf8.char
+local utf8len = unicode.utf8.len
+local utf8lower = unicode.utf8.lower
+local utf8sub = unicode.utf8.sub
+local utfcharacters = string.utfcharacters
+
+--- debugging tool (careful, this *will* break context!)
+--dofile(kpse.find_file("lualibs-table.lua")) -- archaic version :(
+--table.print = function (...) print(table.serialize(...)) end
+
+local tablecopy
+if format_is_context then
+ tablecopy = table.copy
+else -- could use lualibs instead but not worth the overhead
+ tablecopy = function (t) -- ignores tables as keys
+ local result = { }
+ for k, v in next, t do
+ if type(v) == table then
+ result[k] = tablecopy(v)
+ else
+ result[k] = v
+ end
+ end
+ return result
+ end
+end
+
+local GLYPH_NODE = node and nodeid"glyph"
+local GLUE_NODE = node and nodeid"glue"
+local GLUE_SPEC_NODE = node and nodeid"glue_spec"
+local KERN_NODE = node and nodeid"kern"
+local DISC_NODE = node and nodeid"disc"
+local HLIST_NODE = node and nodeid"hlist"
+local VLIST_NODE = node and nodeid"vlist"
+
+local IGNORE_NODES = node and {
+--[GLUE_NODE] = true,
+ [KERN_NODE] = true,
+--[DISC_NODE] = true,
+} or { }
+
+--[[ichd--
+\startparagraph
+The initialization of the module relies heavily on parsers generated by
+\type{LPEG}.
+\stopparagraph
+--ichd]]--
+
+local lpeg = require "lpeg"
+
+local C, Cb, Cc, Cf, Cg,
+ Cmt, Cp, Cs, Ct
+ = lpeg.C, lpeg.Cb, lpeg.Cc, lpeg.Cf, lpeg.Cg,
+ lpeg.Cmt, lpeg.Cp, lpeg.Cs, lpeg.Ct
+
+local P, R, S, V, lpegmatch
+ = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.match
+
+--local B = lpeg.version() == "0.10" and lpeg.B or nil
+
+--[[ichd--
+\startparagraph
+By default the output to \type{stdout} will be zero. The verbosity
+level can be adjusted in order to alleviate debugging.
+\stopparagraph
+--ichd]]--
+--local verbose_level = 42
+local verbose_level = 0
+
+--[[ichd--
+\startparagraph
+Historically, Enigma-encoded messages were restricted to a size of 250
+characters. With sufficient verbosity we will indicate whether this
+limit has been exceeded during the \TEX\ run.
+\stopparagraph
+--ichd]]--
+local max_msg_length = 250
+--[[ichd--
+\stopdocsection
+--ichd]]--
+
+
+--[[ichd--
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startdocsection[title=Globals]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startparagraph
+The following mappings are used all over the place as we convert back
+and forth between the characters (unicode) and their numerical
+representation.
+\stopparagraph
+--ichd]]--
+
+local value_to_letter -- { [int] -> chr }
+local letter_to_value -- { [chr] -> int }
+local alpha_sorted -- string, length 26
+local raw_rotor_wiring -- { string0, .. string5, }
+local notches -- { [int] -> int } // rotor num -> notch pos
+local reflector_wiring -- { { [int] -> int }, ... } // symmetrical
+do
+ value_to_letter = {
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
+ "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
+ }
+
+ letter_to_value = {
+ a = 01, b = 02, c = 03, d = 04, e = 05, f = 06, g = 07, h = 08,
+ i = 09, j = 10, k = 11, l = 12, m = 13, n = 14, o = 15, p = 16,
+ q = 17, r = 18, s = 19, t = 20, u = 21, v = 22, w = 23, x = 24,
+ y = 25, z = 26,
+ }
+--[[ichd--
+\startparagraph
+The five rotors to simulate.\reference[listing:rotor_wiring]{}
+Their wirings are created from strings at runtime, see below the
+function \luafunction{get_rotors}.
+\stopparagraph
+--ichd]]--
+
+ --[[
+ Nice: http://www.ellsbury.com/ultraenigmawirings.htm
+ ]]--
+ alpha_sorted = "abcdefghijklmnopqrstuvwxyz"
+ raw_rotor_wiring = {
+ [0] = alpha_sorted,
+ "ekmflgdqvzntowyhxuspaibrcj",
+ "ajdksiruxblhwtmcqgznpyfvoe",
+ "bdfhjlcprtxvznyeiwgakmusqo",
+ "esovpzjayquirhxlnftgkdcmwb",
+ "vzbrgityupsdnhlxawmjqofeck",
+ }
+
+--[[ichd--
+\startparagraph
+Notches are assigned to rotors according to the Royal Army
+mnemonic.
+\stopparagraph
+--ichd]]--
+ notches = { }
+ do
+ local raw_notches = "rfwkannnn"
+ --local raw_notches = "qevjz"
+ local n = 1
+ for chr in utfcharacters(raw_notches) do
+ local pos = stringfind(alpha_sorted, chr)
+ notches[n] = pos - 1
+ n = n + 1
+ end
+ end
+
+--[[ichd--
+\placetable[here][listing:reflector]%
+ {The three reflectors and their substitution rules.}{%
+ \starttabulate[|r|l|]
+ \NC UKW a \NC AE BJ CM DZ FL GY HX IV KW NR OQ PU ST \NC \NR
+ \NC UKW b \NC AY BR CU DH EQ FS GL IP JX KN MO TZ VW \NC \NR
+ \NC UKW c \NC AF BV CP DJ EI GO HY KR LZ MX NW QT SU \NC \NR
+ \stoptabulate
+}
+--ichd]]--
+
+ reflector_wiring = { }
+ local raw_ukw = {
+ { a = "e", b = "j", c = "m", d = "z", f = "l", g = "y", h = "x",
+ i = "v", k = "w", n = "r", o = "q", p = "u", s = "t", },
+ { a = "y", b = "r", c = "u", d = "h", e = "q", f = "s", g = "l",
+ i = "p", j = "x", k = "n", m = "o", t = "z", v = "w", },
+ { a = "f", b = "v", c = "p", d = "j", e = "i", g = "o", h = "y",
+ k = "r", l = "z", m = "x", n = "w", q = "t", s = "u", },
+ }
+ for i=1, #raw_ukw do
+ local new_wiring = { }
+ local current_ukw = raw_ukw[i]
+ for from, to in next, current_ukw do
+ from = letter_to_value[from]
+ to = letter_to_value[to]
+ new_wiring[from] = to
+ new_wiring[to] = from
+ end
+ reflector_wiring[i] = new_wiring
+ end
+end
+
+--[[ichd--
+\stopdocsection
+--ichd]]--
+
+--[[ichd--
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startdocsection[title=Pretty printing for debug purposes]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startparagraph
+The functions below allow for formatting of the terminal output; they
+have no effect on the workings of the enigma simulator.
+\stopparagraph
+--ichd]]--
+
+local emit
+local pprint_ciphertext
+local pprint_encoding
+local pprint_encoding_scheme
+local pprint_init
+local pprint_machine_step
+local pprint_new_machine
+local pprint_rotor
+local pprint_rotor_scheme
+local pprint_step
+local polite_key_request
+local key_invalid
+do
+ local eol = "\n"
+
+ local colorstring_template = "\027[%d;1m%s\027[0m"
+ local colorize = function (s, color)
+ color = color and color < 38 and color > 29 and color or 31
+ return stringformat(colorstring_template,
+ color,
+ s)
+ end
+
+ local underline = function (s)
+ return stringformat("\027[4;37m%s\027[0m", s)
+ end
+
+ local s_steps = [[Total characters encoded with machine “]]
+ local f_warnsteps = [[ (%d over permitted maximum)]]
+ pprint_machine_step = function (n, name)
+ local sn
+ name = colorize(name, 36)
+ if n > max_msg_length then
+ sn = colorize(n, 31) .. stringformat(f_warnsteps,
+ n - max_msg_length)
+ else
+ sn = colorize(n, 37)
+ end
+ return s_steps .. name .. "â€: " .. sn .. "."
+ end
+ local rotorstate = "[s \027[1;37m%s\027[0m n\027[1;37m%2d\027[0m]> "
+ pprint_rotor = function (rotor)
+ local visible = rotor.state % 26 + 1
+ local w, n = rotor.wiring, (rotor.notch - visible) % 26 + 1
+ local tmp = { }
+ for i=1, 26 do
+ local which = (i + rotor.state - 1) % 26 + 1
+ local chr = value_to_letter[rotor.wiring.from[which]]
+ if i == n then -- highlight positions of notches
+ tmp[i] = colorize(stringupper(chr), 32)
+ --elseif chr == value_to_letter[visible] then
+ ---- highlight the character in window
+ -- tmp[i] = colorize(chr, 33)
+ else
+ tmp[i] = chr
+ end
+ end
+ return stringformat(rotorstate,
+ stringupper(value_to_letter[visible]),
+ n)
+ .. tableconcat(tmp)
+ end
+
+ local rotor_scheme = underline"[rot not]"
+ .. " "
+ .. underline(alpha_sorted)
+ pprint_rotor_scheme = function ()
+ return rotor_scheme
+ end
+
+ local s_encoding_scheme = eol
+ .. [[in > 1 => 2 => 3 > UKW > 3 => 2 => 1]]
+ pprint_encoding_scheme = function ()
+ return underline(s_encoding_scheme)
+ end
+ local s_step = " => "
+ local stepcolor = 36
+ local finalcolor = 32
+ pprint_encoding = function (steps)
+ local nsteps, result = #steps, { }
+ for i=0, nsteps-1 do
+ result[i+1] = colorize(value_to_letter[steps[i]], stepcolor)
+ .. s_step
+ end
+ result[nsteps+1] = colorize(value_to_letter[steps[nsteps]],
+ finalcolor)
+ return tableconcat(result)
+ end
+
+ local init_announcement
+ = colorize("\n" .. [[Initial position of rotors: ]],
+ 37)
+ pprint_init = function (init)
+ local result = ""
+ result = value_to_letter[init[1]] .. " "
+ .. value_to_letter[init[2]] .. " "
+ .. value_to_letter[init[3]]
+ return init_announcement .. colorize(stringupper(result), 34)
+ end
+
+ local machine_announcement =
+ [[Enigma machine initialized with the following settings.]] .. eol
+ local s_ukw = colorize(" Reflector:", 37)
+ local s_pb = colorize("Plugboard setting:", 37)
+ local s_ring = colorize(" Ring positions:", 37)
+ local empty_plugboard = colorize(" ——", 34)
+ pprint_new_machine = function (m)
+ local result = { "" }
+ result[#result+1] = underline(machine_announcement)
+ result[#result+1] = s_ukw
+ .. " "
+ .. colorize(
+ stringupper(value_to_letter[m.reflector]),
+ 34
+ )
+ local rings = ""
+ for i=1, 3 do
+ local this = m.ring[i]
+ rings = rings
+ .. " "
+ .. colorize(stringupper(value_to_letter[this + 1]), 34)
+ end
+ result[#result+1] = s_ring .. rings
+ if m.__raw.plugboard then
+ local tpb, pb = m.__raw.plugboard, ""
+ for i=1, #tpb do
+ pb = pb .. " " .. colorize(tpb[i], 34)
+ end
+ result[#result+1] = s_pb .. pb
+ else
+ result[#result+1] = s_pb .. empty_plugboard
+ end
+ result[#result+1] = ""
+ result[#result+1] = pprint_rotor_scheme()
+ for i=1, 3 do
+ result[#result+1] = pprint_rotor(m.rotors[i])
+ end
+ return tableconcat(result, eol) .. eol
+ end
+
+ local step_template = colorize([[Step â„– ]], 37)
+ local chr_template = colorize([[ —— Input ]], 37)
+ local pbchr_template = colorize([[ → ]], 37)
+ pprint_step = function (n, chr, pb_chr)
+ return eol
+ .. step_template
+ .. colorize(n, 34)
+ .. chr_template
+ .. colorize(stringupper(value_to_letter[chr]), 34)
+ .. pbchr_template
+ .. colorize(stringupper(value_to_letter[pb_chr]), 34)
+ .. eol
+ end
+
+ -- Split the strings into lines, group them in bunches of five etc.
+ local tw = 30
+ local pprint_textblock = function (s)
+ local len = utf8len(s)
+ local position = 1 -- position in string
+ local nline = 5 -- width of current line
+ local out = utf8sub(s, position, position+4)
+ repeat
+ position = position + 5
+ nline = nline + 6
+ if nline > tw then
+ out = out .. eol .. utf8sub(s, position, position+4)
+ nline = 1
+ else
+ out = out .. " " .. utf8sub(s, position, position+4)
+ end
+ until position > len
+ return out
+ end
+
+ local intext = colorize([[Input text:]], 37)
+ local outtext = colorize([[Output text:]], 37)
+ pprint_ciphertext = function (input, output, upper_p)
+ if upper_p then
+ input = stringupper(input)
+ output = stringupper(output)
+ end
+ return eol
+ .. intext
+ .. eol
+ .. pprint_textblock(input)
+ .. eol .. eol
+ .. outtext
+ .. eol
+ .. pprint_textblock(output)
+ end
+
+--[[ichd--
+\startparagraph
+\luafunction{emit} is the main wrapper function for
+\identifier{stdout}. Checks if the global verbosity setting exceeds
+the specified threshold, and only then pushes the output.
+\stopparagraph
+--ichd]]--
+ emit = function (v, f, ...)
+ if f and v and verbose_level >= v then
+ iowrite(f(...) .. eol)
+ end
+ return 0
+ end
+--[[ichd--
+\startparagraph
+The \luafunction{polite_key_request} will be called in case the
+\identifier{day_key} field of the machine setup is empty at the time of
+initialization.
+\stopparagraph
+--ichd]]--
+ local s_request = "\n\n "
+ .. underline"This is an encrypted document." .. [[
+
+
+ Please enter the document key for enigma machine
+ “%sâ€.
+
+ Key Format:
+
+Ref R1 R2 R3 I1 I2 I3 [P1 ..] Ref: reflector A/B/C
+ Rn: rotor, I through V
+ In: ring position, 01 through 26
+ Pn: optional plugboard wiring, upto 32
+
+>]]
+ polite_key_request = function (name)
+ return stringformat(s_request, colorize(name, 33))
+ end
+
+ local s_invalid_key = colorize"Warning!"
+ .. " The specified key is invalid."
+ key_invalid = function ()
+ return s_invalid_key
+ end
+end
+
+--[[ichd--
+\startparagraph
+The functions \luafunction{new} and \luafunction{ask_for_day_key} are
+used outside their scope, so we declare them beforehand.
+\stopparagraph
+--ichd]]--
+local new
+local ask_for_day_key
+do
+--[[ichd--
+\stopdocsection
+--ichd]]--
+
+--[[ichd--
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startdocsection[title=Rotation]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startparagraph
+The following function \luafunction{do_rotate} increments the
+rotational state of a single rotor. There are two tests for notches:
+\startitemize[n]
+ \item whether it’s at the current character, and
+ \item whether it’s at the next character.
+\stopitemize
+The latter is an essential prerequisite for double-stepping.
+\stopparagraph
+--ichd]]--
+ local do_rotate = function (rotor)
+ rotor.state = rotor.state % 26 + 1
+ return rotor,
+ rotor.state == rotor.notch,
+ rotor.state + 1 == rotor.notch
+ end
+
+--[[ichd--
+\startparagraph
+The \luafunction{rotate} function takes care of rotor (\emph{Walze})
+movement. This entails incrementing the next rotor whenever the notch
+has been reached and covers the corner case \emph{double stepping}.
+\stopparagraph
+--ichd]]--
+ local rotate = function (machine)
+ local rotors = machine.rotors
+ local rc, rb, ra = rotors[1], rotors[2], rotors[3]
+
+ ra, nxt = do_rotate(ra)
+ if nxt or machine.double_step then
+ rb, nxt, nxxt = do_rotate(rb)
+ if nxt then
+ rc = do_rotate(rc)
+ end
+ if nxxt then
+ --- weird: home.comcast.net/~dhhamer/downloads/rotors1.pdf
+ machine.double_step = true
+ else
+ machine.double_step = false
+ end
+ end
+ machine.rotors = { rc, rb, ra }
+ end
+--[[ichd--
+\stopdocsection
+--ichd]]--
+
+--[[ichd--
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startdocsection[title=Input Preprocessing]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startparagraph
+Internally, we will use lowercase strings as they are a lot more
+readable than uppercase. Lowercasing happens prior to any further
+dealings with input. After the encoding or decoding has been
+accomplished, there will be an optional (re-)uppercasing.
+\stopparagraph
+
+\startparagraph
+Substitutions \reference[listing:preproc]{}are applied onto the
+lowercased input. You might want to avoid some of these, above all the
+rules for numbers, because they translate single digits only. The
+solution is to write out numbers above ten.
+\stopparagraph
+--ichd]]--
+
+ local pp_substitutions = {
+ -- Umlauts are resolved.
+ ["ö"] = "oe",
+ ["ä"] = "ae",
+ ["ü"] = "ue",
+ ["ß"] = "ss",
+ -- WTF?
+ ["ch"] = "q",
+ ["ck"] = "q",
+ -- Punctuation -> “xâ€
+ [","] = "x",
+ ["."] = "x",
+ [";"] = "x",
+ [":"] = "x",
+ ["/"] = "x",
+ ["’"] = "x",
+ ["‘"] = "x",
+ ["„"] = "x",
+ ["“"] = "x",
+ ["“"] = "x",
+ ["-"] = "x",
+ ["–"] = "x",
+ ["—"] = "x",
+ ["!"] = "x",
+ ["?"] = "x",
+ ["‽"] = "x",
+ ["("] = "x",
+ [")"] = "x",
+ ["["] = "x",
+ ["]"] = "x",
+ ["<"] = "x",
+ [">"] = "x",
+ -- Spaces are omitted.
+ [" "] = "",
+ ["\n"] = "",
+ ["\t"] = "",
+ ["\v"] = "",
+ ["\\"] = "",
+ -- Numbers are resolved.
+ ["0"] = "null",
+ ["1"] = "eins",
+ ["2"] = "zwei",
+ ["3"] = "drei",
+ ["4"] = "vier",
+ ["5"] = "fuenf",
+ ["6"] = "sechs",
+ ["7"] = "sieben",
+ ["8"] = "acht",
+ ["9"] = "neun",
+ }
+
+--[[ichd--
+\stopdocsection
+--ichd]]--
+
+--[[ichd--
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startdocsection[
+ title={Main function chain to be applied to single characters},
+]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\startparagraph
+As far as the Enigma is concerned, there is no difference between
+encoding and decoding. Thus, we need only one function
+(\luafunction{encode_char}) to achieve the complete functionality.
+However, within every encoding step, characters will be wired
+differently in at least one of the rotors according to its rotational
+state. Rotation is simulated by adding the \identifier{state} field of
+each rotor to the letter value (its position on the ingoing end).
+\stopparagraph
+\placetable[here][table:dirs]{Directional terminology}{%
+ \starttabulate[|l|r|l|]
+ \NC boolean \NC direction \NC meaning \NC \AR
+ \NC true \NC “from†\NC right to left \NC \AR
+ \NC false \NC “to†\NC left to right \NC \AR
+ \stoptabulate%
+}
+\startparagraph
+The function \luafunction{do_do_encode_char} returns the character
+substitution for one rotor. As a letter passes through each rotor
+twice, the argument \identifier{direction} determines which way the
+substitution is applied.
+\stopparagraph
+--ichd]]--
+ local do_do_encode_char = function (char, rotor, direction)
+ local rw = rotor.wiring
+ local rs = rotor.state
+ local result = char
+ if direction then -- from
+ result = (result + rs - 1) % 26 + 1
+ result = rw.from[result]
+ result = (result - rs - 1) % 26 + 1
+ else -- to
+ result = (result + rs - 1) % 26 + 1
+ result = rw.to[result]
+ result = (result - rs - 1) % 26 + 1
+ end
+ return result
+ end
+
+--[[ichd--
+\startparagraph
+Behind the plugboard, every character undergoes seven substitutions:
+two for each rotor plus the central one through the reflector. The
+function \luafunction{do_encode_char}, although it returns the final
+result only, keeps every intermediary step inside a table for debugging
+purposes. This may look inefficient but is actually a great advantage
+whenever something goes wrong.
+\stopparagraph
+--ichd]]--
+ --- ra -> rb -> rc -> ukw -> rc -> rb -> ra
+ local do_encode_char = function (rotors, reflector, char)
+ local rc, rb, ra = rotors[1], rotors[2], rotors[3]
+ local steps = { [0] = char }
+ --
+ steps[1] = do_do_encode_char(steps[0], ra, true)
+ steps[2] = do_do_encode_char(steps[1], rb, true)
+ steps[3] = do_do_encode_char(steps[2], rc, true)
+ steps[4] = reflector_wiring[reflector][steps[3]]
+ steps[5] = do_do_encode_char(steps[4], rc, false)
+ steps[6] = do_do_encode_char(steps[5], rb, false)
+ steps[7] = do_do_encode_char(steps[6], ra, false)
+ emit(2, pprint_encoding_scheme)
+ emit(2, pprint_encoding, steps)
+ return steps[7]
+ end
+
+--[[ichd--
+\startparagraph
+Before an input character is passed on to the actual encoding routing,
+the function \luafunction{encode_char} matches it agains the latin
+alphabet.
+Characters failing this test are either passed through or ignored,
+depending on the machine option \identifier{other_chars}.
+Also, the counter of encoded characters is incremented at this stage
+and some pretty printer hooks reside here.
+\stopparagraph
+
+\startparagraph
+\luafunction{encode_char} contributes only one element of the encoding
+procedure: the plugboard (\emph{Steckerbrett}).
+Like the rotors described above, a character passed through this
+device twice; the plugboard marks the beginning and end of every step.
+For debugging purposes, the first substitution is stored in a separate
+local variable, \identifier{pb_char}.
+\stopparagraph
+--ichd]]--
+
+ local encode_char = function (machine, char)
+ machine.step = machine.step + 1
+ machine:rotate()
+ local pb = machine.plugboard
+ char = letter_to_value[char]
+ local pb_char = pb[char] -- first plugboard substitution
+ emit(2, pprint_step, machine.step, char, pb_char)
+ emit(3, pprint_rotor_scheme)
+ emit(3, pprint_rotor, machine.rotors[1])
+ emit(3, pprint_rotor, machine.rotors[2])
+ emit(3, pprint_rotor, machine.rotors[3])
+ char = do_encode_char(machine.rotors,
+ machine.reflector,
+ pb_char)
+ return value_to_letter[pb[char]] -- second plugboard substitution
+ end
+
+ local get_random_pattern = function ()
+ local a, b, c
+ = mathrandom(1,26), mathrandom(1,26), mathrandom(1,26)
+ return value_to_letter[a]
+ .. value_to_letter[b]
+ .. value_to_letter[c]
+ end
+
+ local pattern_to_state = function (pat)
+ return {
+ letter_to_value[stringsub(pat, 1, 1)],
+ letter_to_value[stringsub(pat, 2, 2)],
+ letter_to_value[stringsub(pat, 3, 3)],
+ }
+ end
+
+ local set_state = function (machine, state)
+ local rotors = machine.rotors
+ for i=1, 3 do
+ rotors[i].state = state[i] - 1
+ end
+ end
+
+--[[ichd--
+\startparagraph
+When \modulename{Enigma} is called from \TEX, the encoding
+proceeds character by character as we iterate one node at a time.
+\luafunction{encode_string} is a wrapper for use with strings, e.~g. in
+the mtx-script (\at{page}[sec:fun]).
+It handles iteration and extraction of successive characters from the
+sequence.
+\stopparagraph
+--ichd]]--
+ local encode_string = function (machine, str) --, pattern)
+ local result = { }
+ for char in utfcharacters(str) do
+ local tmp = machine:encode(char)
+ if tmp ~= false then
+ if type(tmp) == "table" then
+ for i=1, #tmp do
+ result[#result+1] = tmp[i]
+ end
+ else
+ result[#result+1] = tmp
+ end
+ end
+ end
+ machine:processed_chars()
+ return tableconcat(result)
+ end
+--[[ichd--
+\stopdocsection
+--ichd]]--
+
+--[[ichd--
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startdocsection[title=Initialization string parser]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\placetable[here][]{Initialization strings}{%
+ \bTABLE
+ \bTR
+ \bTD Reflector \eTD
+ \bTD[nc=3] Rotor \eTD
+ \bTD[nc=3] Initial \eTD
+ \bTD[nc=10] Plugboard wiring \eTD
+ \eTR
+ \eTR
+ \bTR
+ \bTD in slot \eTD
+ \bTD[nc=3] setting \eTD
+ \bTD[nc=3] rotor \eTD
+ \eTR
+ \bTR
+ \bTD \eTD
+ \bTD 1 \eTD\bTD 2 \eTD\bTD 3 \eTD
+ \bTD 1 \eTD\bTD 2 \eTD\bTD 3 \eTD
+ \bTD 1 \eTD\bTD 2 \eTD\bTD 3 \eTD\bTD 4 \eTD\bTD 5 \eTD
+ \bTD 6 \eTD\bTD 7 \eTD\bTD 8 \eTD\bTD 9 \eTD\bTD 10 \eTD
+ \eTR
+ \bTR
+ \bTD B \eTD
+ \bTD I \eTD\bTD IV \eTD\bTD III \eTD
+ \bTD 16 \eTD\bTD 26 \eTD\bTD 08 \eTD
+ \bTD AD \eTD\bTD CN \eTD\bTD ET \eTD
+ \bTD FL \eTD\bTD GI \eTD\bTD JV \eTD
+ \bTD KZ \eTD\bTD PU \eTD\bTD QY \eTD
+ \bTD WX \eTD
+ \eTR
+ \eTABLE
+}
+--ichd]]--
+ local roman_digits = {
+ i = 1, I = 1,
+ ii = 2, II = 2,
+ iii = 3, III = 3,
+ iv = 4, IV = 4,
+ v = 5, V = 5,
+ }
+
+ local p_init = P{
+ "init",
+ init = V"whitespace"^-1 * Ct(V"do_init"),
+ do_init = (V"reflector" * V"whitespace")^-1
+ * V"rotors" * V"whitespace"
+ * V"ring"
+ * (V"whitespace" * V"plugboard")^-1
+ ,
+ reflector = Cg(C(R("ac","AC")) / stringlower, "reflector")
+ ,
+
+ rotors = Cg(Ct(V"rotor" * V"whitespace"
+ * V"rotor" * V"whitespace"
+ * V"rotor"),
+ "rotors")
+ ,
+ rotor = Cs(V"roman_five" / roman_digits
+ + V"roman_four" / roman_digits
+ + V"roman_three" / roman_digits
+ + V"roman_two" / roman_digits
+ + V"roman_one" / roman_digits)
+ ,
+ roman_one = P"I" + P"i",
+ roman_two = P"II" + P"ii",
+ roman_three = P"III" + P"iii",
+ roman_four = P"IV" + P"iv",
+ roman_five = P"V" + P"v",
+
+ ring = Cg(Ct(V"double_digit" * V"whitespace"
+ * V"double_digit" * V"whitespace"
+ * V"double_digit"),
+ "ring")
+ ,
+ double_digit = C(R"02" * R"09"),
+
+ plugboard = Cg(V"do_plugboard", "plugboard"),
+ --- no need to enforce exactly ten substitutions
+ --do_plugboard = Ct(V"letter_combination" * V"whitespace"
+ -- * V"letter_combination" * V"whitespace"
+ -- * V"letter_combination" * V"whitespace"
+ -- * V"letter_combination" * V"whitespace"
+ -- * V"letter_combination" * V"whitespace"
+ -- * V"letter_combination" * V"whitespace"
+ -- * V"letter_combination" * V"whitespace"
+ -- * V"letter_combination" * V"whitespace"
+ -- * V"letter_combination" * V"whitespace"
+ -- * V"letter_combination")
+ do_plugboard = Ct(V"letter_combination"
+ * (V"whitespace" * V"letter_combination")^0)
+ ,
+ letter_combination = C(R("az", "AZ") * R("az", "AZ")),
+
+ whitespace = S" \n\t\v"^1,
+ }
+
+
+--[[ichd--
+\stopdocsection
+--ichd]]--
+
+--[[ichd--
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startdocsection[title=Initialization routines]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\startparagraph
+The plugboard is implemented as a pair of hash tables.
+\stopparagraph
+--ichd]]--
+ local get_plugboard_substitution = function (p)
+ --- Plugboard wirings are symmetrical, thus we have one table for
+ --- each direction.
+ local tmp, result = { }, { }
+ for _, str in next, p do
+ local one, two = stringlower(stringsub(str, 1, 1)),
+ stringlower(stringsub(str, 2))
+ tmp[one] = two
+ tmp[two] = one
+ end
+ local n_letters = 26
+
+ local lv = letter_to_value
+ for n=1, n_letters do
+ local letter = value_to_letter[n]
+ local sub = tmp[letter] or letter
+ -- Map each char either to the plugboard substitution or itself.
+ result[lv[letter]] = lv[sub or letter]
+ end
+ return result
+ end
+
+--[[ichd--
+\startparagraph
+Initialization of the rotors requires some precautions to be taken.
+The most obvious of which is adjusting the displacement of its wiring
+by the ring setting.
+\stopparagraph
+\startparagraph
+Another important task is to store the notch position in order for it
+to be retrievable by the rotation subroutine at a later point.
+\stopparagraph
+\startparagraph
+The actual bidirectional mapping is implemented as a pair of tables.
+The initial order of letters, before the ring shift is applied, is
+alphabetical on the input (right, “fromâ€) side and, on the output
+(left, “toâ€) side taken by the hard wired correspondence as specified
+in the rotor wirings above.
+NB the descriptions in terms of “output†and “input†directions is
+misleading in so far as during any encoding step the electricity will
+pass through every rotor in both ways.
+Hence, the “input†(right, from) direction literally applies only to
+the first half of the encoding process between plugboard and reflector.
+\stopparagraph
+\startparagraph
+The function \luafunction{do_get_rotor} creates a single rotor instance
+and populates it with character mappings. The \identifier{from} and
+\identifier{to} subfields of its \identifier{wiring} field represent
+the wiring in the respective directions.
+This initital wiring was specified in the corresponding
+\identifier{raw_rotor_wiring} table; the ringshift is added modulo the
+alphabet size in order to get the correctly initialized rotor.
+\stopparagraph
+--ichd]]--
+ local do_get_rotor = function (raw, notch, ringshift)
+ local rotor = {
+ wiring = {
+ from = { },
+ to = { },
+ },
+ state = 0,
+ notch = notch,
+ }
+ local w = rotor.wiring
+ for from=1, 26 do
+ local to = letter_to_value[stringsub(raw, from, from)]
+ --- The shift needs to be added in both directions.
+ to = (to + ringshift - 1) % 26 + 1
+ from = (from + ringshift - 1) % 26 + 1
+ rotor.wiring.from[from] = to
+ rotor.wiring.to [to ] = from
+ end
+ --table.print(rotor, "rotor")
+ return rotor
+ end
+
+--[[ichd--
+\startparagraph
+Rotors are initialized sequentially accordings to the initialization
+request.
+The function \luafunction{get_rotors} walks over the list of
+initialization instructions and calls \luafunction{do_get_rotor} for
+the actual generation of the rotor table. Each rotor generation request
+consists of three elements:
+\stopparagraph
+\startitemize[n]
+ \item the choice of rotor (one of five),
+ \item the notch position of said rotor, and
+ \item the ring shift.
+\stopitemize
+--ichd]]--
+ local get_rotors = function (rotors, ring)
+ local s, r = { }, { }
+ for n=1, 3 do
+ local nr = tonumber(rotors[n])
+ local ni = tonumber(ring[n]) - 1 -- “1†means shift of zero
+ r[n] = do_get_rotor(raw_rotor_wiring[nr], notches[nr], ni)
+ s[n] = ni
+ end
+ return r, s
+ end
+
+ local decode_char = encode_char -- hooray for involutory ciphers
+
+--[[ichd--
+\startparagraph
+The function \luafunction{encode_general} is an intermediate step for
+the actual single-character encoding / decoding routine
+\luafunction{enchode_char}.
+Its purpose is to ensure encodability of a given character before
+passing it along.
+Characters are first checked against the replacement table
+\identifier{pp_substitutions} (see \at{page}[listing:preproc]).
+For single-character replacements the function returns the encoded
+character (string).
+However, should the replacement turn out to consist of more than one
+character, each one will be encoded successively, yielding a list.
+\stopparagraph
+--ichd]]--
+ local encode_general = function (machine, chr)
+ local chr = utf8lower(chr)
+ local replacement
+ = pp_substitutions[chr] or letter_to_value[chr] and chr
+ if not replacement then
+ if machine.other_chars then
+ return chr
+ else
+ return false
+ end
+ end
+
+ if utf8len(replacement) == 1 then
+ return encode_char(machine, replacement)
+ end
+ local result = { }
+ for new_chr in utfcharacters(replacement) do
+ result[#result+1] = encode_char(machine, new_chr)
+ end
+ return result
+ end
+
+ local process_message_key
+ local alpha = R"az"
+ local alpha_dec = alpha / letter_to_value
+ local whitespace = S" \n\t\v"
+ local mkeypattern = Ct(alpha_dec * alpha_dec * alpha_dec)
+ * whitespace^0
+ * C(alpha * alpha *alpha)
+ process_message_key = function (machine, message_key)
+ message_key = stringlower(message_key)
+ local init, three = lpegmatch(mkeypattern, message_key)
+ -- to be implemented
+ end
+
+ local decode_string = function (machine, str, message_key)
+ machine.kenngruppe, str = stringsub(str, 3, 5), stringsub(str, 6)
+ machine:process_message_key(message_key)
+ local decoded = encode_string(machine, str)
+ return decoded
+ end
+
+ local testoptions = {
+ size = 42,
+
+ }
+ local generate_header = function (options)
+ end
+
+ local processed_chars = function (machine)
+ emit(1, pprint_machine_step, machine.step, machine.name)
+ end
+
+--[[ichd--
+\startparagraph
+The day key is entrusted to the function \luafunction{handle_day_key}.
+If the day key is the empty string or \type{nil}, it will ask for a key
+on the terminal. (Cf. below, \at{page}[listing:ask_for_day_key].)
+Lesson: don’t forget providing day keys in your setups when running in
+batch mode.
+\stopparagraph
+--ichd]]--
+ local handle_day_key handle_day_key = function (dk, name, old)
+ local result
+ if not dk or dk == "" then
+ dk = ask_for_day_key(name, old)
+ end
+ result = lpegmatch(p_init, dk)
+ result.reflector = result.reflector or "b"
+ -- If we don’t like the key we’re going to ask again. And again....
+ return result or handle_day_key(nil, name, dk)
+ end
+
+--[[ichd--
+\startparagraph
+The enigma encoding is restricted to an input -- and, naturally, output
+-- alphabet of exactly twenty-seven characters. Obviously, this would
+severely limit the set of encryptable documents. For this reason the
+plain text would be \emph{preprocessed} prior to encoding, removing
+spaces and substituting a range of characters, e.\,g. punctuation, with
+placeholders (“Xâ€) from the encodable spectrum. See above
+\at{page}[listing:preproc] for a comprehensive list of substitutions.
+\stopparagraph
+
+\startparagraph
+The above mentioned preprocessing, however, does not even nearly extend
+to the whole unicode range that modern day typesetting is expected to
+handle. Thus, sooner or later an Enigma machine will encounter
+non-preprocessable characters and it will have to decide what to do
+with them. The Enigma module offers two ways to handle this kind of
+situation: \emph{drop} those characters, possibly distorting the
+deciphered plain text, or to leave them in, leaving hints behind as to
+the structure of the encrypted text. None of these is optional, so it
+is nevertheless advisable to not include non-latin characters in the
+plain text in the first place. The settings key
+\identifier{other_chars} (type boolean) determines whether we will keep
+or drop offending characters.
+\stopparagraph
+--ichd]]--
+
+ new = function (name, args)
+ local setup_string, pattern = args.day_key, args.rotor_setting
+ local raw_settings = handle_day_key(setup_string, name)
+ local rotors, ring =
+ get_rotors(raw_settings.rotors, raw_settings.ring)
+ local plugboard
+ = raw_settings.plugboard
+ and get_plugboard_substitution(raw_settings.plugboard)
+ or get_plugboard_substitution{ }
+ local machine = {
+ name = name,
+ step = 0, -- n characters encoded
+ init = {
+ rotors = raw_settings.rotors,
+ ring = raw_settings.ring
+ },
+ rotors = rotors,
+ ring = ring,
+ state = init_state,
+ other_chars = args.other_chars,
+ spacing = args.spacing,
+ ---> a>1, b>2, c>3
+ reflector = letter_to_value[raw_settings.reflector],
+ plugboard = plugboard,
+ --- functionality
+ rotate = rotate,
+ --process_message_key = process_message_key,
+ encode_string = encode_string,
+ encode_char = encode_char,
+ encode = encode_general,
+ decode_string = decode_string,
+ decode_char = decode_char,
+ set_state = set_state,
+ processed_chars = processed_chars,
+ --- <badcodingstyle> -- hackish but occasionally useful
+ __raw = raw_settings
+ --- </badcodingstyle>
+ } --- machine
+ local init_state
+ = pattern_to_state(pattern or get_random_pattern())
+ emit(1, pprint_init, init_state)
+ machine:set_state(init_state)
+
+ --table.print(machine.rotors)
+ emit(1, pprint_new_machine, machine)
+ return machine
+ end
+
+end
+--[[ichd--
+\stopdocsection
+--ichd]]--
+
+
+--[[ichd--
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\startdocsection[title=Setup Argument Handling]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+--ichd]]--
+do
+--[[ichd--
+\startparagraph
+As the module is intended to work both with the Plain and \LATEX\
+formats as well as \CONTEXT, we can’t rely on format dependent setups.
+Hence the need for an argument parser. Should be more efficient anyways
+as all the functionality resides in Lua.
+\stopparagraph
+--ichd]]--
+
+ local p_args = P{
+ "args",
+ args = Cf(Ct"" * (V"kv_pair" + V"emptyline")^0, rawset),
+ kv_pair = Cg(V"key"
+ * V"separator"
+ * (V"value" * V"final"
+ + V"empty"))
+ * V"rest_of_line"^-1
+ ,
+ key = V"whitespace"^0 * C(V"key_char"^1),
+ key_char = (1 - V"whitespace" - V"eol" - V"equals")^1,
+ separator = V"whitespace"^0 * V"equals" * V"whitespace"^0,
+ empty = V"whitespace"^0 * V"comma" * V"rest_of_line"^-1
+ * Cc(false)
+ ,
+ value = C((V"balanced" + (1 - V"final"))^1),
+ final = V"whitespace"^0 * V"comma" + V"rest_of_string",
+ rest_of_string = V"whitespace"^0
+ * V"eol_comment"^-1
+ * V"eol"^0
+ * V"eof"
+ ,
+ rest_of_line = V"whitespace"^0 * V"eol_comment"^-1 * V"eol",
+ eol_comment = V"comment_string" * (1 - (V"eol" + V"eof"))^0,
+ comment_string = V"lua_comment" + V"TeX_comment",
+ TeX_comment = V"percent",
+ lua_comment = V"double_dash",
+ emptyline = V"rest_of_line",
+
+ balanced = V"balanced_brk" + V"balanced_brc",
+ balanced_brk = V"lbrk"
+ * (V"balanced" + (1 - V"rbrk"))^0
+ * V"rbrk"
+ ,
+ balanced_brc = V"lbrc"
+ * (V"balanced" + (1 - V"rbrc"))^0
+ * V"rbrc"
+ ,
+ -- Terminals
+ eol = P"\n\r" + P"\r\n" + P"\n" + P"\r",
+ eof = -P(1),
+ whitespace = S" \t\v",
+ equals = P"=",
+ dot = P".",
+ comma = P",",
+ dash = P"-", double_dash = V"dash" * V"dash",
+ percent = P"%",
+ lbrk = P"[", rbrk = P"]",
+ lbrc = P"{", rbrc = P"}",
+ }
+
+
+--[[ichd--
+\startparagraph
+In the next step we process the arguments, check the input for sanity
+etc. The function \luafunction{parse_args} will test whether a value
+has a sanitizer routine and, if so, apply it to its value.
+\stopparagraph
+--ichd]]--
+
+ local boolean_synonyms = {
+ ["1"] = true,
+ doit = true,
+ indeed = true,
+ ok = true,
+ ["⊤"] = true,
+ ["true"] = true,
+ yes = true,
+ }
+ local toboolean
+ = function (value) return boolean_synonyms[value] or false end
+ local alpha = R("az", "AZ")
+ local digit = R"09"
+ local space = S" \t\v"
+ local ans = alpha + digit + space
+ local p_ans = Cs((ans + (1 - ans / ""))^1)
+ local alphanum_or_space = function (str)
+ if type(str) ~= "string" then return nil end
+ return lpegmatch(p_ans, str)
+ end
+ local ensure_int = function (n)
+ n = tonumber(n)
+ if not n then return 0 end
+ return mathfloor(n + 0.5)
+ end
+ p_alpha = Cs((alpha + (1 - alpha / ""))^1)
+ local ensure_alpha = function (s)
+ s = tostring(s)
+ return lpegmatch(p_alpha, s)
+ end
+
+ local sanitizers = {
+ other_chars = toboolean, -- true = keep, false = drop
+ spacing = toboolean,
+ day_key = alphanum_or_space,
+ rotor_setting = ensure_alpha,
+ verbose = ensure_int,
+ }
+ enigma.parse_args = function (raw)
+ local args = lpegmatch(p_args, raw)
+ for k, v in next, args do
+ local f = sanitizers[k]
+ if f then
+ args[k] = f(v)
+ else
+ -- OPTIONAL be fascist and permit only predefined args
+ args[k] = v
+ end
+ end
+ return args
+ end
+--[[ichd--
+\startparagraph
+If the machine setting lacks key settings then we’ll go ahead and ask
+\reference[listing:ask_for_day_key]{}%
+the user directly, hence the function \luafunction{ask_for_day_key}.
+We abort after three misses lest we annoy the user \dots
+\stopparagraph
+--ichd]]--
+ local max_tries = 3
+ ask_for_day_key = function (name, old, try)
+ if try == max_tries then
+ iowrite[[
+Aborting. Entered invalid key three times.
+]]
+ os.exit()
+ end
+ if old then
+ emit(0, key_invalid)
+ end
+ emit(0, polite_key_request, name)
+ local result = ioread()
+ iowrite("\n")
+ return alphanum_or_space(result) or
+ ask_for_day_key(name, (try and try + 1 or 1))
+ end
+end
+
+--[[ichd--
+\stopdocsection
+--ichd]]--
+
+--[[ichd--
+\startdocsection[title=Callback]
+\startparagraph
+This is the interface to \TEX. We generate a new callback handler for
+each defined Enigma machine. \CONTEXT\ delivers the head as third
+argument of a callback only (...‽), so we’ll have to do some variable
+shuffling on the function side.
+\stopparagraph
+
+\startparagraph
+When grouping output into the traditional blocks of five letters we
+insert space nodes. As their properties depend on the font we need to
+recreate the space item for every paragraph. Also, as \CONTEXT\ does
+not preload a font we lack access to font metrics before
+\type{\starttext}. Thus creating the space earlier will result in an
+error.
+The function \luafunction{generate_space} will be called inside the
+callback in order to get an appropriate space glue.
+\stopparagraph
+--ichd]]--
+
+local generate_space = function ( )
+ local current_fontparms = font.getfont(font.current()).parameters
+ local space_node = nodenew(GLUE_NODE)
+ space_node.spec = nodenew(GLUE_SPEC_NODE)
+ space_node.spec.width = current_fontparms.space
+ space_node.spec.shrink = current_fontparms.space_shrink
+ space_node.spec.stretch = current_fontparms.space_stretch
+ return space_node
+end
+
+--[[ichd--
+\startparagraph
+\useURL[khaled_hosny_texsx] [http://tex.stackexchange.com/a/11970]
+ [] [tex.sx]
+Registering a callback (“node attribute�, “node task�, “task
+action�) in \CONTEXT\ is not straightforward, let alone documented.
+The trick is to create, install and register a handler first in order
+to use it later on \dots\ many thanks to Khaled Hosny, who posted an
+answer to \from[khaled_hosny_texsx].
+\stopparagraph
+--ichd]]--
+
+local new_callback = function (machine, name)
+ enigma.machines [name] = machine
+ local format_is_context = format_is_context
+ local current_space_node
+ local mod_5 = 0
+
+ --- First we need to choose an insertion method. If autospacing is
+ --- requested, a space will have to be inserted every five
+ --- characters. The rationale behind using differend functions to
+ --- implement each method is that it should be faster than branching
+ --- for each character.
+ local insert_encoded
+
+ if machine.spacing then -- auto-group output
+ insert_encoded = function (head, n, replacement)
+ local insert_glyph = nodecopy(n)
+ if replacement then -- inefficient but bulletproof
+ insert_glyph.char = utf8byte(replacement)
+ --print(utf8char(n.char), "=>", utf8char(insertion.char))
+ end
+ --- if we insert a space we need to return the
+ --- glyph node in order to track positions when
+ --- replacing multiple nodes at once (e.g. ligatures)
+ local insertion = insert_glyph
+ mod_5 = mod_5 + 1
+ if mod_5 > 5 then
+ mod_5 = 1
+ insertion = nodecopy(current_space_node)
+ insertion.next, insert_glyph.prev = insert_glyph, insertion
+ end
+ if head == n then --> replace head
+ local succ = head.next
+ if succ then
+ insert_glyph.next, succ.prev = succ, insert_glyph
+ end
+ head = insertion
+ else --> replace n
+ local pred, succ = n.prev, n.next
+ pred.next, insertion.prev = insertion, pred
+ if succ then
+ insert_glyph.next, succ.prev = succ, insert_glyph
+ end
+ end
+
+ --- insertion becomes the new head
+ return head, insert_glyph -- so we know where to insert
+ end
+ else
+
+ insert_encoded = function (head, n, replacement)
+ local insertion = nodecopy(n)
+ if replacement then
+ insertion.char = utf8byte(replacement)
+ end
+ if head == n then
+ local succ = head.next
+ if succ then
+ insertion.next, succ.prev = succ, insertion
+ end
+ head = insertion
+ else
+ nodeinsert_before(head, n, insertion)
+ noderemove(head, n)
+ end
+ return head, insertion
+ end
+ end
+
+ --- The callback proper starts here.
+ local aux aux = function (head, recurse)
+ if recurse == nil then recurse = 0 end
+ for n in nodetraverse(head) do
+ local nid = n.id
+ --print(utf8char(n.char), n)
+ if nid == GLYPH_NODE then
+ local chr = utf8char(n.char)
+ --print(chr, n)
+ local replacement = machine:encode(chr)
+ --print(chr, replacement, n)
+ local treplacement = replacement and type(replacement)
+ --if replacement == false then
+ if not replacement then
+ noderemove(head, n)
+ elseif treplacement == "string" then
+ --print(head, n, replacement)
+ head, _ = insert_encoded(head, n, replacement)
+ elseif treplacement == "table" then
+ local current = n
+ for i=1, #replacement do
+ head, current = insert_encoded(head, current, replacement[i])
+ end
+ end
+ elseif nid == GLUE_NODE then
+ if n.subtype ~= 15 then -- keeping the parfillskip
+ noderemove(head, n)
+ end
+ elseif IGNORE_NODES[nid] then
+ -- drop spaces and kerns
+ noderemove(head, n)
+ elseif nid == DISC_NODE then
+ --- ligatures need to be resolved if they are characters
+ local npre, npost = n.pre, n.post
+ if nodeid(npre) == GLYPH_NODE and
+ nodeid(npost) == GLYPH_NODE then
+ if npre.char and npost.char then -- ligature between glyphs
+ local replacement_pre = machine:encode(utf8char(npre.char))
+ local replacement_post = machine:encode(utf8char(npost.char))
+ insert_encoded(head, npre, replacement_pre)
+ insert_encoded(head, npost, replacement_post)
+ else -- hlists or whatever
+ -- pass
+ --noderemove(head, npre)
+ --noderemove(head, npost)
+ end
+ end
+ noderemove(head, n)
+ elseif nid == HLIST_NODE or nid == VLIST_NODE then
+ if nodelength(n.list) > 0 then
+ n.list = aux(n.list, recurse + 1)
+ end
+-- else
+-- -- TODO other node types
+-- print(n)
+ end
+ end
+ nodeslide(head)
+ return head
+ end -- callback auxiliary
+
+ --- Context requires
+ --- × argument shuffling; a properly registered “action†gets the
+ --- head passed as its third argument
+ --- × hacking our way around the coupling of pre_linebreak_filter
+ --- and hpack_filter; background:
+ --- http://www.ntg.nl/pipermail/ntg-context/2012/067779.html
+ local cbk = function (a, _, c)
+ local head
+ current_space_node = generate_space ()
+ mod_5 = 0
+ if format_is_context == true then
+ head = c
+ local cbk_env = get_debug_info(4) -- no getenv in lua 5.2
+ --inspect(cbk_env)
+ if cbk_env.func == nodes.processors.pre_linebreak_filter then
+ -- how weird is that?
+ return aux(head)
+ end
+ return head
+ end
+ head = a
+ return aux(head)
+ end
+
+ if format_is_context then
+ local cbk_id = "enigma_" .. name
+ enigma.callbacks[name] = nodesinstallattributehandler{
+ name = cbk_id,
+ namespace = thirddata.enigma,
+ processor = cbk,
+ }
+ local cbk_location = "thirddata.enigma.callbacks." .. name
+ nodestasksappendaction("processors",
+ --"characters",
+ --"finalizers",
+ --- this one is tagged “for usersâ€
+ --- (cf. node-tsk.lua)
+ "before",
+ cbk_location)
+ nodestasksdisableaction("processors", cbk_location)
+ else
+ enigma.callbacks[name] = cbk
+ end
+end
+
+--[[ichd--
+\startparagraph
+Enigma\reference[listing:retrieve]{} machines can be copied and derived
+from one another at will, cf. the \texmacro{defineenigma} on
+\at{page}[listing:define]. Two helper functions residing inside the
+\identifier{thirddata.enigma} namespace take care of these actions:
+\luafunction{save_raw_args} and \luafunction{retrieve_raw_args}. As
+soon as a machine is defined, we store its parsed options inside the
+table \identifier{configurations} for later reference. For further
+details on the machine derivation mechanism see
+\at{page}[listing:inherit].
+\stopparagraph
+--ichd]]--
+local configurations = { }
+
+local save_raw_args = function (conf, name)
+ local current = configurations[name] or { }
+ for k, v in next, conf do
+ current[k] = v
+ end
+ configurations[name] = current
+end
+
+local retrieve_raw_args = function (name)
+ local cn = configurations[name]
+ return cn and tablecopy(cn) or { }
+end
+
+enigma.save_raw_args = save_raw_args
+enigma.retrieve_raw_args = retrieve_raw_args
+
+
+--[[ichd--
+\startparagraph
+The function \luafunction{new_machine} instantiates a table containing
+the complete specification of a workable \emph{Enigma} machine and
+other metadata. The result is intended to be handed over to the
+callback creation mechanism (\luafunction{new_callback}). However, the
+arguments table is usally stored away in the
+\identifier{thirddata.enigma} namespace anyway
+(\luafunction{save_raw_args}), so that the specification of any machine
+can be inherited by some new setup later on.
+\stopparagraph
+--ichd]]--
+local new_machine = function (name)
+ local args = configurations[name]
+ --table.print(configurations)
+ verbose_level = args and args.verbose or verbose_level
+ local machine = new(name, args)
+ return machine
+end
+
+enigma.new_machine = new_machine
+enigma.new_callback = new_callback
+
+--[[ichd--
+\stopdocsection
+--ichd]]--
+
+-- vim:ft=lua:sw=2:ts=2:tw=71:expandtab
diff --git a/macros/luatex/generic/enigma/enigma.sty b/macros/luatex/generic/enigma/enigma.sty
new file mode 100644
index 0000000000..07bb8e78c9
--- /dev/null
+++ b/macros/luatex/generic/enigma/enigma.sty
@@ -0,0 +1,7 @@
+\ProvidesPackage
+ {enigma}
+ [2013/03/28 Enigma Document Encryption]
+\RequirePackage{luatexbase}
+\input{enigma}
+\endinput
+% vim:ft=tex:sw=2:ts=2:expandtab:tw=71
diff --git a/macros/luatex/generic/enigma/enigma.tex b/macros/luatex/generic/enigma/enigma.tex
new file mode 100644
index 0000000000..d18b72ffa1
--- /dev/null
+++ b/macros/luatex/generic/enigma/enigma.tex
@@ -0,0 +1,130 @@
+\newif\ifenigmaisrunningplain
+\ifcsname ver@enigma.sty\endcsname\else
+ \enigmaisrunningplaintrue
+ \input{luatexbase.sty}
+ \catcode`\@=11
+% \else latex
+\fi
+\catcode`\_=11 % There’s no reason why this shouldn’t be the case.
+\catcode`\!=11
+%D Nice tool from luat-ini.mkiv. This really helps with those annoying
+%D string separators of Lua’s that clutter the source.
+% this permits \typefile{self} otherwise nested b/e sep problems
+\def\luastringsep{===}
+\edef\!!bs{[\luastringsep[}
+\edef\!!es{]\luastringsep]}
+%D \startdocsection[title=Prerequisites]
+%D \startparagraph
+%D Package loading and the namespacing issue are commented on in
+%D \identifier{enigma.lua}.
+%D \stopparagraph
+\directlua{
+ packagedata = packagedata or { }
+ dofile(kpse.find_file\!!bs enigma.lua\!!es)
+}
+
+%D \startparagraph
+%D First, create somthing like \CONTEXT’s asciimode. We found
+%D \texmacro{newluatexcatcodetable} in \identifier{luacode.sty} and it
+%D seems to get the job done.
+%D \stopparagraph
+\newluatexcatcodetable \enigmasetupcatcodes
+\bgroup
+ \def\escapecatcode {0}
+ \def\begingroupcatcode {1}
+ \def\endgroupcatcode {2}
+ \def\spacecatcode {10}
+ \def\lettercatcode {11}
+ \setluatexcatcodetable\enigmasetupcatcodes {
+ \catcode`\^^I = \spacecatcode % tab
+ \catcode`\ = \spacecatcode
+ \catcode`\{ = \begingroupcatcode
+ \catcode`\} = \endgroupcatcode
+ \catcode`\^^L = \lettercatcode % form feed
+ \catcode`\^^M = \lettercatcode % eol
+ }
+\egroup
+%D \stopdocsection
+
+%D \startdocsection[title=Setups]
+%D \startparagraph
+%D Once the proper catcodes are in place, the setup macro
+%D \texmacro{do_setup_enigma} doesn’t to anything besides passing stuff
+%D through to Lua.
+%D \stopparagraph
+\def\do_setup_enigma#1{%
+ \directlua{
+ local enigma = packagedata.enigma
+ local current_args = enigma.parse_args(\!!bs\detokenize{#1}\!!es)
+ enigma.save_raw_args(current_args, \!!bs\current_enigma_id\!!es)
+ enigma.new_callback(
+ enigma.new_machine(\!!bs\current_enigma_id\!!es),
+ \!!bs\current_enigma_id\!!es)
+ }%
+ \egroup%
+}
+
+%D The module setup \texmacro{setupenigma} expects key=value, notation.
+%D All the logic is at the Lua end, not much to see here …
+\def\setupenigma#1{%
+ \bgroup
+ \edef\current_enigma_id{#1}
+ \luatexcatcodetable \enigmasetupcatcodes
+ \do_setup_enigma%
+}
+%D \stopdocsection
+
+%D \startdocsection[title=Encoding Macros]
+%D \startparagraph
+%D The environment of \texmacro{begin<enigmaid>} and
+%D \texmacro{end<enigmaid>} toggles Enigma encoding.
+%D (Regarding environment delimiters we adhere to Knuth’s
+%D practice of prefixing with \type{begin}/\type{end}.)
+%D \stopparagraph
+
+\def\e!start{begin} %{start}
+\def \e!stop{end} %{stop}
+\edef\c!pre_linebreak_filter{pre_linebreak_filter}
+\def\do_define_enigma#1{%
+ \@EA\gdef\csname \e!start\current_enigma_id\endcsname{%
+ \endgraf
+ \bgroup%
+ \directlua{%
+ if packagedata.enigma and
+ packagedata.enigma.machines[ \!!bs#1\!!es] then
+ luatexbase.add_to_callback(
+ \!!bs\c!pre_linebreak_filter\!!es,
+ packagedata.enigma.callbacks[ \!!bs#1\!!es],
+ \!!bs#1\!!es)
+ else
+ print\!!bs ENIGMA: No machine of that name: #1!\!!es
+ os.exit()
+ end
+ }%
+ }%
+ \@EA\gdef\csname \e!stop\current_enigma_id\endcsname{%
+ \endgraf
+ \directlua{
+ luatexbase.remove_from_callback(
+ \!!bs\c!pre_linebreak_filter\!!es,
+ \!!bs#1\!!es)
+ packagedata.enigma.machines[ \!!bs#1\!!es]:processed_chars()
+ }%
+ \egroup%
+ }%
+}
+
+\def\defineenigma#1{%
+ \begingroup
+ \let\@EA\expandafter
+ \edef\current_enigma_id{#1}%
+ \@EA\do_define_enigma\@EA{\current_enigma_id}%
+ \endgroup%
+}
+
+%D \stopdocsection
+
+\catcode`\_=8 % \popcatcodes
+\catcode`\!=12 % reserved according to source2e
+\ifenigmaisrunningplain\catcode`\@=12\fi
+% vim:ft=plaintex:sw=2:ts=2:expandtab:tw=71
diff --git a/macros/luatex/generic/enigma/enigma_manual.tex b/macros/luatex/generic/enigma/enigma_manual.tex
new file mode 100644
index 0000000000..4331521900
--- /dev/null
+++ b/macros/luatex/generic/enigma/enigma_manual.tex
@@ -0,0 +1,498 @@
+%% If you’re looking for instructions concerning how to build this
+%% manual, please for now drop me an email: ·phg42.2a at gmail dot com·
+%% as you will need a certain mtx-script.
+\defineitemgroup [credits]
+\setupitemgroup [credits] [
+ % before={\startnarrower[middle]},
+ % after=\stopnarrower,
+ left=,
+ right=,
+ margin=,
+ option=2,
+]
+
+\pushcatcodetable
+\setcatcodetable\txtcatcodes
+\useurl [chickenize] [https://github.com/alt/chickenize]
+\useurl [codebook] [http://simonsingh.net/books/the-code-book/]
+\useurl [key_procedure] [http://users.telenet.be/d.rijmenants/en/enigmaproc.htm]
+\useurl [luatex-web] [http://www.luatex.org/]
+\useurl [rotor_wirings] [http://www.ellsbury.com/ultraenigmawirings.htm]
+\useurl [wp:day_key] [http://en.wikipedia.org/wiki/Cryptanalysis_of_the_Enigma#Key_setting]
+ [] [\hyphenatedurl{http://en.wikipedia.org/wiki/Cryptanalysis_of_the_Enigma\#Key_setting}]
+\useurl [wp:ring] [http://en.wikipedia.org/wiki/Enigma_rotor_details#The_ring_setting]
+ [] [\hyphenatedurl{http://en.wikipedia.org/wiki/Enigma_rotor_details\#The_ring_setting}]
+\useurl [initialization] [http://w1tp.com/enigma/mewirg.htm]
+\useurl [model-i] [http://www.cryptomuseum.com/crypto/enigma/i/index.htm]
+\useurl [ecollection] [http://cryptocellar.org/enigma/]
+\useurl [heinz_diss] [http://rzbl04.biblio.etc.tu-bs.de:8080/docportal/receive/DocPortal_document_00001705]
+\popcatcodetable
+
+\startdocchapter[title=Introduction]
+ This module implements an \emph{Enigma} cipher that is equivalent to
+ the most widely distributed model: the Enigma~I (subtypes {\sc m1}
+ {\sc m2} and {\sc m3}).%
+ \footnote{%
+ See \from[model-i] for a showcase.
+ }
+ Machines of this type had three rotors, a non-moving reflector and,
+ as a novelty at the time of their introduction, a plugboard.
+ The simulation accepts arbitrary configurations of these components,
+ as well as the starting position of the rotors, and then processes
+ text accordingly.
+ Depending on the input, this yields the plaintext or ciphertext, as
+ encryption and decryption are the same.
+
+ The code is provided as a module (interface for \CONTEXT) as well as
+ a package (\PLAIN, \LATEX).
+ It is subject to the {\sc bsd} license, see below,
+ \at{page}[license], for details.
+\stopdocchapter
+
+\startdocchapter[title=Usage]
+
+\startdocsection[title=Loading the Module / Package]
+ The intention is for the \modulename{Enigma} codebase to integrate
+ with the three most popular (as of 2012) \TEX\ formats:
+ \CONTEXT,
+ \PLAIN, and
+ \LATEX.
+ If the user interface does not fully conform with the common practice
+ of the latter two, please be lenient toward the author whose
+ intuitions are for the most part informed by \CONTEXT.
+ For this reason, a couple words concerning the interfaces will be
+ necessary.
+ The examples in this manual will be cycling through all three
+ formats, but once you get the general idea of how it works, you will
+ have no problem translating between coding styles.
+ Those familiar with \CONTEXT\ might, therefore, skip the following
+ paragraphs and continue directly with the next section on
+ \at{page}[sec:opts].%
+
+ The package is loaded as usual. For \PLAIN, issue a
+ \type{\input{enigma}}.
+ \LATEX-users need to place \type{\usepackage{enigma}} somewhere
+ inside the preamble.
+ (There are no package options.)
+ From this point on, instructions for both formats are the same.
+
+ The interface provides two basic macros from which all functionality
+ will be derived:
+ \texmacro{defineenigma} and \texmacro{setupenigma}.
+ Both are a kind of \emph{meta-macros}, meaning that they generate
+ other macros which may then be employed to access the functionality
+ of the package.
+ As such they naturally belong inside the preamble (if you chose to
+ use
+ \modulename{Enigma} with \LATEX, that is).
+ The correct order is to \texmacro{defineenigma} an enigma machine
+ first and then \texmacro{setupenigma} it.
+ The definition takes a single, setups a double mandatory argument.
+ Thus, \type{\defineenigma{encrypt}} creates a new environment
+ consisting of the macros \texmacro{beginencrypt} and
+ \texmacro{endencrypt}.%
+ \footnote{%
+ \CONTEXT-users will have noticed that there is no direct macro
+ \type{\encrypt{foo}}. The reason for this is that the callback
+ which the module relies on operates on node-level.
+ This means that for the Enigma encryption to have an effect it will
+ have to process entire paragraphs.
+ As encrypted passages are supposed to stand on their own, this
+ small limitation should not have a severe impact on functionality.
+ If you should, however, need a macro that works for smaller
+ portions of text, please send a feature request to the maintainer
+ (\ichdparameter{email}).
+ }
+ These correspond to \texmacro{startencrypt}/\texmacro{stopencrypt} in
+ the \CONTEXT\ interface.
+ The \CONTEXT-examples below are easily translated to
+ Plain/\LATEX-syntax by replacing curly brackets (groups) with
+ square brackets and substituting environment prefixes:
+ \type{\start<foo>} becomes \type{\begin<foo>} and
+ \type{\stop<foo>} becomes \type{\end<foo>}.
+ Except for those conventions the syntax, even in key-value
+ assignments, is identical.
+
+ However, the environment is not usable right away, as we still have
+ to set the initial state of the machine.
+ This is achieved by the second meta-macro,
+ \type{\setupenigma{encrypt}{<args>}}, where \type{<args>} is a
+ placeholder for a list of \emph{assignments}, i.\,e. pairs of
+ \emph{key=value} statements by means of which all further parameters
+ are specified.
+ The possible parameters are listed in the next section,
+ examples of their effects will be given further below in the section
+ on functionality (see \at{page}[sec:fun]).%
+ \footnote{%
+ If you grasp the concept of paired \type{\define<foo>}
+ \endash\space \type{\setup<foo>} macros, then congratulations are
+ in order: you qualify for migration from your current macro package
+ to \CONTEXT.
+ }
+\stopdocsection
+\startdocsection[title=Options Explained,reference=sec:opts]
+
+At the moment, the \texmacro{setupenigma} macro in any format accepts
+the following parameters.
+% \startpostponing[+2]%% messes up floats -- why?
+ \startplacefigure[
+ location={right,high},
+ title={Usage example for the \PLAIN\ format.},
+ ]
+ % \framed[align=right,frameoffset=1em]{%
+ \startframed[
+ align=right,
+ frameoffset=1em,
+ frame=off,
+ ]%
+ \startlatextyping[before=,after=,]
+ \input {enigma}
+ %% Definition ··········· %%
+ \defineenigma {encryption}
+ %% Setup ················ %%
+ \setupenigma {encryption} {
+ other_chars = no,
+ day_key = I II III
+ 01 01 01,
+ rotor_setting = aaa,
+ spacing = yes,
+ verbose = 1,
+ }
+ %% Usage ················ %%
+ \beginencryption
+ aaaaa aaaaa aaaaa
+ aaaaa aaaaa aaaaa
+ \endencryption
+ \beginencryption
+ Nobody in Poland is going
+ to be able to read this,
+ har har!
+ \endencryption
+ \bye
+ \stoplatextyping
+ \stopframed
+ \stopplacefigure
+% \stoppostponing
+\startitemize
+ \setuptolerance[tolerant]%% it’s crowded in here due to the float
+ \let\olditem\item
+ \let\item\undefined
+ \def\item#1#2{% 1 name, 2 type
+ \olditem
+ \identifier{#1}%
+ \reference[option:#1]{}%
+ \space
+ <\emph{#2}>%
+ \hskip1em%
+ }
+ \item{other_chars}{boolean} How to handle non-encodable characters,
+ i.\,e. glyphs outside the bare set of Latin letters; see below on
+ \at{page}[explained:other_chars].
+ \item{day_key}{string} Encryption key, i.\,e. a description of the
+ initial setup of an Enigma machine: the reflector used, the choice
+ and positions of the three rotors, the ring settings, and the
+ plugboard wiring.
+ \item{rotor_setting}{string} The initial rotor advancement.
+ \item{spacing}{boolean} Auto-space output?
+ \item{verbose}{integer} Controls overall verbosity level
+ (\emph{global}\/!).
+\stopitemize
+
+%% day key
+\noindentation
+To state the obvious, the value of \identifier{day_key} serves as the
+\emph{day key} for encryption. An Enigma day key ordinarily consists of
+(1) a list of the the rotor configuration,
+(2) the ring settings, and
+(3) the plugboard connections.\footnote{%
+ For a description of the initialization process see
+ \from[initialization].
+}
+Together these have the denotation \emph{day key}, because they are
+meant to be supplied in special code books by central authority, one
+for each day.\footnote{%
+ Read about the historical directives for daily key renewal at
+ \from[key_procedure].
+ there are some {\sc pdf}s with images of \emph{Kenngruppenbücher} at
+ \from[ecollection], section \emph{Enigma Messages and Keys}.
+ Also, while you’re at it, don’t miss the explanation on Wikipedia:
+ \from[wp:day_key].
+}
+In the \modulename{Enigma} setup, the day key starts
+with a triple of Roman numerals ({\sc i} to {\sc v}) describing which
+of the five rotors is located in which of the three slots.
+(e.\,g. \type{I VI II}).\footnote{%
+ For the individual wirings of the five rotors see
+ \from[rotor_wirings], as well as the implementation below at
+ \at{page}[listing:rotor_wiring].
+}
+Its next part is the ring setting, a triple of two-digit integers that
+are the amount by which the internal wiring of each rotor has been
+shifted (\type{03 23 11}). As the Enigma encrypts only the letters of
+the Latin alphabet, sane values range from one (first position: no
+shift) to twenty six.\footnote{%
+ Consult \from[wp:ring] for an introduction into the ring mechanics.
+}
+The third section specifies which pairs of letters are substituted by
+each other by means of plugboard connections (\type{NI CE GO LD ...}).
+There can be zero to thirteen of these redirections, thus the presence
+of this section is entirely optional.
+Also part of the \identifier{day_key}, but not mentioned yet, is the
+choice of the \emph{reflector}.
+It may be specified as one of the three letters \type{A}, \type{B} and
+\type{C} as the first item. If no reflector is requested explicitly,
+the machine defaults to \type{B}, which is actually the only one of the
+three models that had been in widespread use
+(see below on \at{page}[listing:reflector] for the wirings).
+
+Initialization is not complete without a \identifier{rotor_setting}.
+This is a triple of letters, each representing the initial state of one
+rotor (e.\,g. \type{fkd}). Historically this was not part of the day
+key but supposed to be chosen at random by the operating signal
+officer.
+
+The output can be automatically grouped into sequences of five
+characters, delimited by spaces (option \identifier{spacing}). This
+does not only conform with traditional crypto-style, but also allows
+for the resulting text to be sanely broken into lines by \TEX.
+
+%%% other_chars
+Most documents don’t naturally adhere to the machine-imposed
+restriction to the 26 letters of the Latin alphabet. The original
+encipherment directives comprised substitution tables to compensate for
+a set of intrinsic peculiarities of the German language, like umlauts
+and common digraphs. The \modulename{Enigma} simulation module strives
+to apply these automatically but there is no guarantee of completeness.
+
+However,\reference[explained:other_chars]{} the Enigma lacks means of
+handling languages other than German. When the substitution lookup
+fails, there are two ways of proceeding: either to ignore the current
+character or to pass it on to the output as if nothing happened. The
+default behaviour is to drop alien letters and move on. If the user
+intends to keep these foreign characters instead, E can achieve this by
+setting the \identifier{other_chars} key in the \modulename{Enigma}
+setup to the value \emph{true}. An example of how the result of both
+methods may look, other things being equal, is given in below listing
+(example for \CONTEXT; see the file \type{enigma-example-context.tex}
+in the \type{doc/} subtree of your installation path).
+
+\startcontexttyping
+\usemodule [enigma]
+\defineenigma [secretmessage]
+\setupenigma [secretmessage] [
+ other_chars = yes,
+ day_key = B V III II 12 03 01 GI JV KZ WM PU QY AD CN ET FL,
+ rotor_setting = ben,
+]
+
+\defineenigma [othermessage] [secretmessage]
+\setupenigma [othermessage] [other_chars=wrong]
+
+\starttext
+
+\startsecretmessage
+ føo bąr baž
+\stopsecretmessage
+\startothermessage
+ føo bąr baž
+\stopothermessage
+
+\stoptext
+\stopcontexttyping
+
+Both methods have their disadvantages: if the user chooses to have the
+unknown characters removed it might distort the decrypted text to
+becoming illegible. Far more serious, however, are the consequences of
+keeping them. As artefacts in the ciphertext they would convey
+information about the structure of the plain text.
+
+\stopdocsection
+
+\startdocsection[title=Basic Functionality,reference=sec:fun]
+
+Encrypt the text of your document using the script interface. For
+a start try out the settings as given in below listing.
+
+\starttyping
+mtxrun --script mtx-t-enigma \
+ --setup="day_key = B I II III 01 01 01, \
+ rotor_setting = xyz, \
+ verbose=0" \
+ --text="Gentlemen don’t read each other’s mail, Mr. Turing\!"
+\stoptyping
+
+This will result in the thoroughly scrambled string
+\typ{omribshpwfrfjovkntgqgi abbkhjpxmhdztapkatwrvf}.
+Then, use the same settings you encrypted the text with in your
+document.
+
+\startcontexttyping
+\usemodule[enigma]
+\defineenigma [secretmessage]
+\setupenigma [secretmessage] [
+ day_key = B I II III 01 01 01,
+ rotor_setting = xyz,
+ verbose=3,
+]
+
+\starttext
+
+\startsecretmessage
+ omribshpwfrfjovkntgqgiabbkhjpxmhdztapkatwrvf
+\stopsecretmessage
+
+\stoptext
+\stopcontexttyping
+
+If you compile this document with \CONTEXT, the plain text will
+reappear.
+Notice that punctuation is substituted with the letter “x†before
+encryption and that spaces are omitted.
+
+\useURL[kgbuch] [http://de.wikipedia.org/wiki/Kenngruppenbuch]
+ [] [code book]
+Now it’s certainly not wise to carry around the key to encrypted
+documents as plain text within those documents. The keys will have to
+be distributed via an independent channel, e.\,g. a \from[kgbuch].
+Keys in general don’t have to be supplied inside the document. If there
+is none specified, the module will interrupt the \TEX\ run and
+\emph{ask} for user input. Suppose Alice wanted to send an encrypted
+file to Bob and already generated the cipher text as follows:
+
+\starttyping
+mtxrun --script mtx-t-enigma \
+ --setup="day_key =B I IV V 22 07 10 AZ DG IE YJ QM CW, \
+ rotor_setting = bar, \
+ verbose=0" \
+ --text="I have nothing to hide. From the NSA, that is."
+\stoptyping
+
+Alice would then include the result of this line in her \LATEX\
+document as follows:
+
+\startlatextyping
+\documentclass{scrartcl}
+\usepackage{enigma}
+\defineenigma{decryption}
+%% Encryption key not given in the setup.
+\setupenigma{decryption}{
+ rotor_setting = bar,
+ verbose = 3,
+}
+\begin{document}
+
+\begindecryption
+usbatbwcaajhzgeyzkqskupzbmdhbdepccgeh
+\enddecryption
+
+\end{document}
+\stoplatextyping
+
+She subsequently mails this file to Bob and conveys the key through a
+secure channel. They only thing that will be left for Bob to do now, is
+to enter the key at the prompt when compiling the document with
+\LUALATEX.
+\stopdocsection
+
+\startdocsection[title=Uses and Abuses]
+
+In \LUATEX, \identifier{callback}s may stack. This allows filtering the
+input through many enigma machines successively. For instance, in the
+following listing, two instances of the same machine are generated and
+applied.
+
+\startcontexttyping
+\usemodule [enigma] %% load the module
+\defineenigma [secretmessage] %% generate and
+\setupenigma [secretmessage] [ %% configure a machine
+ day_key = B IV V II 01 01 01 AD CN ET FL GI JV KZ PU QY WX,
+ rotor_setting = foo,
+ verbose=3,
+]
+
+%% now, copy the first machine’s settings
+\defineenigma [othermessage] [secretmessage]
+
+%% here we go!
+\starttext
+
+\startothermessage %% enable machine 1
+\startsecretmessage %% enable machine 2 while no 1 is active
+Encryption equals decryption.
+\stopothermessage
+\stopsecretmessage
+
+\stoptext \endinput
+\stopcontexttyping
+
+\stopdocsection
+
+\stopdocchapter
+
+\startdocchapter[title=Metadata]
+\startdocsection[title=License,reference=license]
+
+© 2012--2013 \emph{Philipp Gesang}. All rights reserved.
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following
+conditions are met:
+
+\startitemize[n]
+ \item Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer.
+ \item Redistributions in binary form must reproduce the
+ above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+\stopitemize
+
+\begingroup
+\setuptolerance [horizontal,strict]
+\startalignment [right,nothyphenated]
+\noindentation\startsmallcaps
+ this software is provided by the copyright
+ holder “as is†and any express or implied warranties,
+ including, but not limited to, the implied warranties of
+ merchantability and fitness for a particular purpose are
+ disclaimed. in no event shall the copyright holder or
+ contributors be liable for any direct, indirect, incidental,
+ special, exemplary, or consequential damages (including, but
+ not limited to, procurement of substitute goods or services;
+ loss of use, data, or profits; or business interruption)
+ however caused and on any theory of liability, whether in
+ contract, strict liability, or tort (including negligence or
+ otherwise) arising in any way out of the use of this software,
+ even if advised of the possibility of such damage.
+\stopsmallcaps\endgraf
+\stopalignment
+\endgroup
+\stopdocsection
+
+\startdocsection[title=Acknowledgements]
+\startcredits
+ \item The idea to implement the \emph{Enigma} cipher for \TEX\ came
+ up while I was reading \emph{The Code Book} by Simon Singh.
+ This work contains an excellent portrayal of the history of
+ German military cryptography and Allied cryptanalysis before
+ and during the Second World War.\par
+ \from[codebook]
+ \item A more detailed account from a historical-cryptological
+ perspective is provided by Ulrich Heinz in his Dissertation (in
+ German), which is freely available.
+ Includes an interesting albeit speculative note on the
+ effectiveness of the Soviet code breaking efforts (chapter
+ seven).\par
+ \from[heinz_diss]
+ \item Also, the \modulename{Enigma} module drew lots of inspiration
+ from Arno Trautmann’s \modulename{Chickenize} package, which
+ remains the unsurpassed hands-on introduction to callback
+ trickery.\par
+ \from[chickenize]
+ \item Finally, without \LUATEX, encryption on node-level would not
+ have been possible.\par
+ \from[luatex-web]
+\stopcredits
+\stopdocsection
+\stopdocchapter
diff --git a/macros/luatex/generic/enigma/mtx-t-enigma.lua b/macros/luatex/generic/enigma/mtx-t-enigma.lua
new file mode 100644
index 0000000000..1b093afb75
--- /dev/null
+++ b/macros/luatex/generic/enigma/mtx-t-enigma.lua
@@ -0,0 +1,72 @@
+--
+--------------------------------------------------------------------------------
+-- FILE: mtx-t-enigma.lua
+-- USAGE: mtxrun --script enigma --setup="s" --text="t"
+-- DESCRIPTION: context script interface for the Enigma module
+-- REQUIREMENTS: latest ConTeXt MkIV
+-- AUTHOR: Philipp Gesang (Phg), <gesang@stud.uni-heidelberg.de>
+-- CREATED: 2013-03-28 02:14:05+0100
+--------------------------------------------------------------------------------
+--
+
+environment.loadluafile("enigma")
+
+local iowrite = io.write
+
+local helpinfo = [[
+===============================================================
+ The Enigma module, command line interface.
+ © 2012--2013 Philipp Gesang. License: 2-clause BSD.
+ Home: <https://bitbucket.org/phg/enigma/>
+===============================================================
+
+USAGE:
+
+ mtxrun --script enigma --setup="settings" --text="text"
+ --verbose=int
+
+ where the settings are to be specified as a comma-delimited
+ conjunction of “key=value†statements, and “text†refers to
+ the text to be encoded. Note that due to the involutory
+ design of the enigma cipher, the text can be both plaintext
+ and ciphertext.
+
+===============================================================
+]]
+
+local application = logs.application {
+ name = "mtx-t-enigma",
+ banner = "The Enigma for ConTeXt, hg-rev 37+",
+ helpinfo = helpinfo,
+}
+
+local ea = environment.argument
+
+local setup, text = ea"setup" or ea"s", ea"text" or ea"t"
+local verbose = ea"verbose" or ea"v"
+
+local out = function (str)
+ iowrite(str)
+end
+
+local machine_id = "external"
+if setup and text then
+ local args = enigma.parse_args(setup)
+ if not args then
+ application.help()
+ iowrite"\n\n[Error] Could not process enigma setup!\n\n"
+ end
+ enigma.save_raw_args(args, machine_id)
+ --local machine = enigma.new_machine(enigma.parse_args(setup))
+ local machine = enigma.new_machine(machine_id)
+ --machine.name = machine_id
+ local result = machine:encode_string(text)
+ if result then
+ out(result)
+ else
+ application.help()
+ end
+else
+ application.help()
+end
+
diff --git a/macros/luatex/generic/enigma/t-enigma.mkvi b/macros/luatex/generic/enigma/t-enigma.mkvi
new file mode 100644
index 0000000000..b5fea293a8
--- /dev/null
+++ b/macros/luatex/generic/enigma/t-enigma.mkvi
@@ -0,0 +1,157 @@
+%D \module
+%D [ file=t-enigma.mkvi,
+%D version=2013-03-28 02:15:37+0100,
+%D title=\CONTEXT\ User Module,
+%D subtitle=Enigma,
+%D author=Philipp Gesang,
+%D date=\currentdate,
+%D copyright=Philipp Gesang,
+%D license=2-clause BSD,
+%D email={phg42 dot 2a at gmail dot com}]
+%C This module is licensed under the conditions of the BSD license with
+%C two clauses. There is a copy in a file named "COPYING" in the
+%C t-enigma source tree.
+
+\unprotect
+
+\writestatus{loading} {ConTeXt module / Enigma Document Encryption}
+
+\startinterface all
+ \setinterfacevariable {enigma} {enigma}
+\stopinterface
+
+\definenamespace [\v!enigma] [
+ \v!command=\v!no,
+ comment=Enigma Document Encryption,
+ \s!name=\v!enigma,
+ \s!parent=\v!enigma,
+ % setup=\v!list,
+ setup=\v!no,
+ style=\v!no,
+ type=module,
+ version=hg-tip,
+]
+
+%D Loading the \LUA\ conversion routines.
+
+\startluacode
+thirddata = thirddata or { }
+\stopluacode
+\registerctxluafile{enigma}
+
+%D \startdocsection[title=Macro Generator]
+%D \startparagraph
+%D The main setup.\reference[listing:define]{} The
+%D \texmacro{defineenigma} macro does not adhere to the reommended
+%D practis of automatical macro derivation. Rather, we have our own
+%D parser do the job of setting globals. This is a consequence of the
+%D intention to offer the same behavior in any of the three main
+%D formats, \PLAIN, \CONTEXT and \LATEX. Hence, we don’t rely on the
+%D internal mechanisms but implement our own macro generator.
+%D \stopparagraph
+
+\def\enigma_define_indeed#id{%
+ \edef\enigmaid{#id}%
+ \expandafter\gdef\csname \e!start\enigmaid\endcsname{%
+ \endgraf
+ \bgroup
+ \ctxlua{
+ if thirddata.enigma.machines["#id"] then
+ nodes.tasks.enableaction("processors",
+ "thirddata.enigma.callbacks.#id")
+ else
+ print([[ENIGMA: No machine of that name: #id!]])
+ end
+ }%
+ }%
+ %
+ \expandafter\gdef\csname \e!stop\enigmaid\endcsname{%
+ \endgraf%% We need to force a paragraph here for the callback to be
+ %% applied.
+ \ctxlua{
+ nodes.tasks.disableaction("processors",
+ "thirddata.enigma.callbacks.#id")
+ thirddata.enigma.machines["#id"]:processed_chars()
+ }%
+ \egroup%
+ }%
+}
+
+%D \startparagraph
+%D The \texmacro{enigma_inherit}\reference[listing:inherit]{} is called
+%D as an intermediate step when deriving one machine from an already
+%D existing one. It gets the stored configuration of its ancestor,
+%D relying on the \luafunction{retrieve_raw_args} function (see
+%D \at{page}[listing:retrieve].
+%D \stopparagraph
+\def\enigma_inherit#to#from{%
+ \ctxlua{%
+ local enigma = thirddata.enigma
+ local current_args = enigma.retrieve_raw_args(\!!bs#from\!!es)
+ enigma.save_raw_args(current_args, \!!bs#to\!!es)
+ enigma.new_callback(enigma.new_machine(\!!bs#to\!!es),
+ \!!bs#to\!!es)
+ }%
+ \enigma_define_indeed{#to}%
+}
+
+\def\enigma_define[#id][#secondid]{%
+ \ifsecondargument %% Copy an existing machine and callback.
+ \enigma_inherit{#id}{#secondid}%
+ \else %% Create a new machine.
+ \iffirstargument
+ \enigma_define_indeed{#id}%
+ \else
+ \donothing
+ \fi
+ \fi
+ \endgroup%
+}
+
+\def\defineenigma{%
+ \begingroup
+ \dodoubleempty\enigma_define
+}
+
+%D \stopdocsection
+
+%D \startdocsection[title=Setup]
+\def\enigma_setup_indeed#args{%
+ \ctxlua{
+ local enigma = thirddata.enigma
+ local current_args =
+ enigma.parse_args(\!!bs\detokenize{#args}\!!es)
+ enigma.save_raw_args(current_args, \!!bs\currentenigmaid\!!es)
+ enigma.new_callback(
+ enigma.new_machine(\!!bs\currentenigmaid\!!es),
+ \!!bs\currentenigmaid\!!es)
+ }%
+}
+
+%D \startparagraph
+%D The module setup \texmacro{setupenigma} expects key=value, notation.
+%D All the logic is at the Lua end, not much to see here …
+%D \stopparagraph
+
+\def\enigma_setup[#id][#args]{%
+ \ifsecondargument
+ \edef\currentenigmaid{#id}
+ \pushcatcodetable
+ \catcodetable \txtcatcodes
+ \enigma_setup_indeed{#args}%
+ \else
+ \donothing
+ \fi
+ \popcatcodetable
+ \egroup%
+}
+
+\def\setupenigma{%
+ \bgroup
+ \dodoubleempty\enigma_setup%
+}
+
+%D \stopdocsection
+
+\protect
+% vim:ft=context:sw=2:ts=2:tw=71
diff --git a/macros/luatex/generic/interpreter/README b/macros/luatex/generic/interpreter/README
new file mode 100644
index 0000000000..f3e1c56c52
--- /dev/null
+++ b/macros/luatex/generic/interpreter/README
@@ -0,0 +1,29 @@
+This is the README file for the Interpreter package.
+Author: Paul Isambert.
+E-mail: zappathustra AT free DOT fr
+Comments and suggestions are welcome.
+Date: June 2012.
+Version: 1.2.
+
+Interpreter preprocesses input files on the fly (no external program) and
+manipulates input lines, e.g. to turn some markup into proper TeX syntax.
+Interpreter doesn't work with ConTeXt.
+
+LuaTeX is required, and the Lua side of the Gates package (i.e. gates.lua),
+version at least 0.2.
+
+Relevant information can be found in interpreter-doc.pdf
+or interpreter-doc.txt (source of the doc readable in a text editor).
+
+The files in this distribution are:
+
+interpreter.lua - main code
+interpreter.tex - \input in plain TeX
+interpreter.sty - wrapper for LaTeX
+interpreter-doc.tex - master file for the doc
+interpreter-doc.txt - text of the doc
+interpreter-doc.pdf - typeset doc
+i-doc.lua - interpretation for the doc (because, of course, the doc
+ is typeset with Interpreter)
+
+Licensing of this package is covered by LPPL.
diff --git a/macros/luatex/generic/interpreter/i-doc.lua b/macros/luatex/generic/interpreter/i-doc.lua
new file mode 100644
index 0000000000..12bc214eda
--- /dev/null
+++ b/macros/luatex/generic/interpreter/i-doc.lua
@@ -0,0 +1,254 @@
+--[[
+Here's a description of "i-doc.lua", the file containing the interpretation
+used for Interpreter's documentation. Remember that none of the TeX macros
+used here is defined by Interpreter; instead, they are my own and should be
+adapted if necessary. Also several options taken here are far from optimal but
+are convenient examples.
+
+Shorthands for often used functions.
+--]]
+local gsub, match = string.gsub, string.match
+local add_pattern = interpreter.add_pattern
+local nomagic = interpreter.nomagic
+
+--[[
+Class 1 and 2 will be used for verbatim (thus protecting) and ``normal''
+patterns go into class 3 or higher.
+--]]
+interpreter.default_class = 3
+
+--[[
+The reader might have observed that "interpreter-doc.txt" begins with a table
+of contents. This table is useful for the source file only, and isn't typeset
+by TeX, because the following pattern suppresses it: the entire paragraph
+containing "TABLE OF CONTENTS" on a line of its own is deleted. Protecting the
+paragraph is useless, but it makes things a little bit faster because the
+paragraph won't be pointlessly searched for other patterns.
+--]]
+local function contents (buffer)
+ for n in ipairs(buffer) do
+ buffer[n] = ""
+ end
+ interpreter.protect()
+end
+add_pattern{
+ pattern = "^%s*TABLE OF CONTENTS%s*$",
+ call = contents,
+ class = 1
+}
+
+--[[
+Sections headers are typeset as
+
+ ====================================== section_tag
+ === Section title ====================
+ ======================================
+
+The first and third line are decorations and they are removed. The
+"section_tag" is meant for the source only again (linking the section to the table
+of contents). I could have used it to create PDF destinations, but that seemed
+unnecessary in such a small file. The associated pattern is: at least four
+equals signs.
+--]]
+add_pattern{
+ pattern = "^====+.*",
+ replace = ""
+}
+
+--[[
+The middle line is spotted with the tree equals sign at the beginning of the
+line (the previous pattern being longer, the decoration lines have been
+already removed and they won't be taken for section titles). The signs are
+removed and replaced with "\section{" and "}".
+--]]
+local function section (buffer, num)
+ local l = buffer[num]
+ l = gsub(l, "^===%s*", "\\section{")
+ l = gsub(l, "%s*=+%s*", "}")
+ buffer[num] = l
+end
+add_pattern{
+ pattern = "^===",
+ call = section
+}
+
+--[[
+The following pattern simply turns "Interpreter" into "\ital{Interpreter}". The
+meaning of the "\ital" command is obvious, I suppose. Note the offset:
+starting at the backslash, this leads to the _n_ in Interpreter, thus avoiding
+matching the pattern again. The Lua notation with double square brackets is
+used for strings with no escape character (hence "\ital" and not "\\ital" as
+would be necessary with a simple string).
+--]]
+add_pattern{
+ pattern = "Interpreter",
+ replace = [[\ital{Interpreter}]],
+ offset = 7
+}
+
+--[[
+Turning "TeX" into TeX. This illustrates the use of a function as "replace";
+the point is that "\TeX" should be suffixed with a space if initially followed
+by anything but a space or end of line (so as not to form a control sequence
+with the following letters), and it should be suffixed with a control space if
+initially followed by a space or end of line (so as to avoid gobbling the
+space). So the function checks the second capture. Note that simply replacing
+"TeX" with "\TeX{}" would be much simpler, but less instructive!
+--]]
+local function maketex (tex, next)
+ if next == " " or next == "" then
+ return [[\TeX\ ]]
+ else
+ return [[\TeX ]] .. next
+ end
+end
+add_pattern{
+ pattern = "(TeX)(.?)",
+ replace = maketex,
+ offset = 2
+}
+
+--[[
+The following turns "<text>" into <text> and "_text_" into _text_. Setting a
+class just so the patterns inherit the "nomagic" feature is of course an
+overkill, but that's an example.
+--]]
+interpreter.set_class(4, {nomagic = true})
+add_pattern{
+ pattern = "<...>",
+ replace = [[\arg{%1}]],
+ class = 4
+}
+add_pattern{
+ pattern = "_..._",
+ replace = [[\ital{%1}]],
+ class = 4
+}
+
+--[[
+I use double quotes as protectors; they are replaced with a "\verb" command at
+the very end of the processing (with class 0).
+--]]
+interpreter.protector('"')
+add_pattern{
+ pattern = nomagic'"..."',
+ replace = [[\verb`%1`]],
+ class = 0
+}
+
+--[[
+The description of functions (in red in the PDF file) are handled with the
+"\describe" macro, which takes the function as its first argument and
+additional information as its second one (typeset in italics in the PDF file).
+In the source, it is simply marked as
+
+ > function (arguments) [Additional information]
+
+with "[Additional information]" sometimes missing (i.e. there is no empty
+pairs of square brackets). Descriptions of entries in pattern tables follows
+the same syntax, except the line begins with ">>". So the pattern first spots
+lines beginning with ">[>]" followed by at least one space, adds an empty pair of
+brackets at the end if there isn't any, and turn the whole into "\describe".
+The number of ">" symbols sets "\describe"'s third argument, which specifies
+the level of the bookmark.
+--]]
+local function describe (buffer, num)
+ local l = buffer[num]
+ if not match (l, "%[.-%]%s*$") then
+ l = l .. " []"
+ end
+ local le = match(l, ">>") and 4 or 3
+ buffer[num] = gsub(l, ">+%s+(.-)%s+%[(.-)%]",
+ [[\describe{%1}{%2}{]] .. le .. "}")
+end
+add_pattern{
+ pattern = "^>+%s+",
+ call = describe
+}
+
+--[[
+Here's how multiline verbatim is handled; in the source it is simply marked by
+indenting the line with ten spaces; thus code is easily spotted when reading
+the source without useless and annoying "<code>"/"</code>" or anything similar
+to mark it. To be properly processed by TeX, the code should be surrounded by
+"\verbatim" and "\verbatim/" (my way of signalling blocks). Those must be on
+their own lines, so we insert a line at the beginning and at the end of the
+paragraph: for the closing "\verbatim/", we can simply replace the last line
+of the paragraph, which is the boundary line, unless we're at the end of the
+file. But for the opening "\verbatim" a line must be added at the beginning of
+the paragraph; thus line numbers in the original source file and in its
+processed version don't match anymore, and this might be annoying when TeX
+reports erros. Besides, blank verbatim lines aren't handled correctly and
+create a new verbatim block instead. So this way of marking verbatim material
+is good for small documents, but explicit marking is cleaner and more
+powerful (albeit not so good-looking in the source file).
+
+Note that the verbatim pattern belongs to class 2 and the entire paragraph is
+protected, so Interpreter leaves it alone afterward (remember the default
+class is 3). Of course, the first ten space characters are removed.
+--]]
+local function verbatim (buffer)
+ for n, l in ipairs(buffer) do
+ buffer[n] = gsub(l, "%s%s%s%s%s%s%s%s%s%s","", 1)
+ end
+ table.insert(buffer, 1, [[\verbatim]])
+ if gsub(buffer[#buffer],
+ interpreter.paragraph, "") == "" then
+ buffer[#buffer] = [[\verbatim/]]
+ else
+ table.insert(buffer, [[\verbatim/]])
+ end
+ interpreter.protect()
+end
+add_pattern{
+ pattern = "^%s%s%s%s%s%s%s%s%s%s",
+ call = verbatim,
+ class = 2
+}
+
+--[[
+And now comes the fun part. I wanted "i-doc.lua" to be self-describing. The
+source of what you're reading right now isn't "interpreter-doc.txt", but
+"i-doc.lua" itself input in the latter file with
+
+ \intepreterfile{doc}{i-doc.lua}
+
+How should code and comment be organized in "i-doc.lua"? Well, there is little
+choice, since the file is a normal Lua file: comment lines should be prefixed
+with "--" or surrounded with
+\tcode{--[{}[} and \tcode{--]{}]}. % Sorry for the braces, I can't nest Lua comments!
+I chose the latter option, which is simpler. But normal code should also be
+typeset as verbatim material; I could have begun all lines with ten spaces,
+but that would have seemed strange. Instead, \tcode{--]{}]} is turned into
+"\source" and "\source/" is added at the end of the paragraph ("\source" is
+just "\verbatim" with a different layout). Which means all paragraphs have the
+same structure: comments between
+\tcode{--[{}[} and \tcode{--]{}]}
+and code immediately following (\tcode{--[{}[} is simply removed). The pattern
+is in class 1 and the paragraph is protected, so that lines indented with ten
+spaces or more aren't touched by the previous verbatim pattern (in class 2).
+--]]
+local function autoverbatim (buffer, line)
+ buffer[line] = [[\source]]
+ for n = line + 1, #buffer do
+ interpreter.protect(n)
+ end
+ if gsub(buffer[#buffer],
+ interpreter.paragraph, "") == "" then
+ buffer[#buffer] = [[\source/]]
+ else
+ table.insert(buffer, [[\source/]])
+ end
+end
+add_pattern{
+ pattern = nomagic"%^--]]",
+ call = autoverbatim,
+ class = 1
+}
+local function remove_comment ()
+ return ""
+end
+add_pattern{
+ pattern = nomagic"%^--[[",
+ replace = remove_comment
+}
diff --git a/macros/luatex/generic/interpreter/interpreter-doc.pdf b/macros/luatex/generic/interpreter/interpreter-doc.pdf
new file mode 100644
index 0000000000..2dcc32ea48
--- /dev/null
+++ b/macros/luatex/generic/interpreter/interpreter-doc.pdf
Binary files differ
diff --git a/macros/luatex/generic/interpreter/interpreter-doc.tex b/macros/luatex/generic/interpreter/interpreter-doc.tex
new file mode 100644
index 0000000000..30a1da52ba
--- /dev/null
+++ b/macros/luatex/generic/interpreter/interpreter-doc.tex
@@ -0,0 +1,115 @@
+% This is the master file producing interpreter-doc.pdf. The version of the
+% documentation readable in a text editor is interpreter-doc.txt (input below).
+%
+% Paul Isambert - zappathustra AT free DOT fr - June 2012
+
+\input pitex
+
+\overfullrule=0pt
+
+\OutputRoutine remove {headers}{shipout}
+
+\setparameter page :
+ hsize = 25pc
+ left = 60pt
+ width = "\dimexpr 25pc + 120pt\relax"
+ lines = 35
+ height = 20cm
+
+\setparameter section :
+ font = \bf
+ link = true
+ number = none
+ numbercommand = \llap
+ beforeskip = 1
+
+\setparameter navigator :
+ title = "Interpreter documentation"
+ author = "Paul Isambert"
+ mode = outlines
+
+\setfont\mainfont:
+ name = "Chaparral Pro"
+ bold = Semibold
+ big = 18pt
+
+\setfont\codefont:
+ name = "Lucida Console"
+ slant = 15
+ bold italic = none
+ size = 8pt
+ features = "-tlig, -trep, space = mono"
+
+\parfillskip=0pt plus 1fill
+\def\describe#1#2#3{%
+ \unless\ifdim\lastskip=\baselineskip
+ \vskip\baselineskip
+ \fi
+ \needspace{2\baselineskip}%
+ \noindent\color{.8 0 0}{%
+ {\outline{#3}{\directlua{%
+ local t = string.gsub("\luaescapestring{#1}", "[ (].*", "")
+ tex.print(t)}}%
+ \codefont#1}%
+ \reverse\iffemptystring{#2}
+ {\kern1em \hfil\penalty0\hbox{\ital{(#2)}}}}%
+ \par
+ \removenextindent}
+
+\newverbatim\source{}
+ {\vskip\baselineskip
+ \hfuzz=1em
+ \codefont\parindent=0pt
+ \pdfcolorstack0 push {.8 0 0 rg}
+ \printverbatim
+ \pdfcolorstack0 pop
+ \vskip\baselineskip}
+
+% The verbatim facilities in PiTeX aren't gated yet, so I must rely on
+% this horrible hack!
+\directlua{
+function do_verbatim (name, exec)
+ if exec then
+ tex.print(pitex.verbatims[name])
+ else
+ for n, l in ipairs(pitex.verbatims[name]) do
+ if n == \string#pitex.verbatims[name] then
+ tex.print("\noexpand\\penalty\noexpand\\widowpenalty")
+ end
+ tex.print(pitex.verbatims[name].regime, l)
+ if n == 1 and \string#pitex.verbatims[name] > 2 then
+ tex.print("\noexpand\\penalty\noexpand\\widowpenalty")
+ end
+ end
+ end
+end
+}
+
+\def\arg#1{{\codefont\char"2039 #1\char"203A}}
+\pdfdef\ital#1{#1}
+\pdfdef\verb`#1`{#1}
+
+% Not optimal, but hey, with all the "intepreter.core.classes" stuff...
+\hyphenation{li-nes cla-sses}
+
+\input interpreter
+
+% Title
+\vbox to 3\baselineskip{
+\hbox to \hsize{\big Interpreter\hfil\normalsize Paul Isambert}
+\hbox to \hsize{v.1.2, June 2012 \hfil \tcode{zappathustra AT free DOT fr}}
+\vfil
+}
+
+
+
+% Bulk of the doc.
+\interpretfile{doc}{interpreter-doc.txt}
+\vskip0pt plus 1filll
+\noindent
+\bgroup\it
+Typeset with Lua\TeX\ 0.71 in Chaparral Pro and Lucida Console
+... nonetheless this documentation looks dull, I don't know why.
+\egroup
+
+\bye
diff --git a/macros/luatex/generic/interpreter/interpreter-doc.txt b/macros/luatex/generic/interpreter/interpreter-doc.txt
new file mode 100644
index 0000000000..6257aa6733
--- /dev/null
+++ b/macros/luatex/generic/interpreter/interpreter-doc.txt
@@ -0,0 +1,732 @@
+ TABLE OF CONTENTS
+ (Make a search on the tag in the right column to jump
+ to the associated section.
+ Vim users can simply type * on the tag;
+ Emacs users do that with C-s C-w (I think);
+ Other editors: I don't know!)
+===========================================================
+ Introduction intro_tag
+ Input files input_tag
+ Paragraphs paragraphs_tag
+ Declaring patterns patterns_tag
+ Classes classes_tag
+ Protecting input protect_tag
+ Technical stuff technical_tag
+ An example: i-doc.lua example_tag
+ The Gates in Interpreter gates_tag
+ The interpreter table interpreter_tag
+ The interpreter.core.tools table interpreter_tools_tag
+ The interpreter.core.reader table interpreter_reader_tag
+===========================================================
+
+
+
+================================== intro_tag
+=== Introduction =================
+==================================
+
+Interpreter preprocesses input files before their contents is fed to TeX. It
+is meant to write document with whatever markup one wishes to define while
+using normal TeX macros in the background. As a simple example, suppose you
+have a macro "\bold" to put text in boldface; then Interpreter lets you map
+"*text*", or "<strong>text</strong>", or simply "!text", or anything else, to
+"\bold{text}". Interpreter doesn't perform any trickery with active
+characters; instead, it manipulates the strings representing the lines of
+a file and search for patterns.
+
+There are two main advantages: first, TeX documents can be typeset with
+a completely non-TeX syntax; second, if one uses some lightweight markup
+language, the source file is much easier to read and might even be more useful
+than the typeset PDF file, e.g. for some technical documentation you want to
+read directly in your text editor while writing code (powerful editors
+generally have their own documentation in such a format, for a good reason).
+A third advantage, not explored in this documentation, is that while feeding
+modified lines to TeX you can also translate the original lines into, say,
+HTML, and write them to an external file, thus creating both PDF and HTML
+output at once.
+
+Interpreter has been rewritten with the Gates package (actually, only
+the Lua side) in version 1.1. That hasn't changed anything to its default
+behavior, but now it can also be customized quite deeply, since its
+code is a collection of small chunks with names that can be externally
+controlled and/or augmented. See the Gates documentation for further
+information. The last sections of this documentation describe the gates
+in Interpreter.
+
+
+
+================================== input_tag
+=== Input files ==================
+==================================
+
+Once Interpreter is loaded with
+
+ \input interpreter
+
+in plain TeX or
+
+ \usepackage{interpreter}
+
+in LaTeX, files to be processed are input as follows:
+
+ \interpretfile{<language>}{<file>}
+
+There should exist a file "i-<language>.lua" containing the language used in
+<file>. For instance, the source of this documentation is
+"interpreter-doc.txt", input in the master file "interpreter-doc.tex" with
+
+ \interpretfile{doc}{interpreter-doc.txt}
+
+and the interpretation to be used is defined in "i-doc.lua". The contents of
+such an interpretation file is the object of the rest of this documentation.
+
+
+
+================================== paragraphs_tag
+=== Paragraphs ===================
+==================================
+
+Interpreter doesn't process lines one by one. Instead, it gathers an entire
+paragraph and then processes the lines. It is important because you can
+manipulate an entire paragraph when a given pattern is detected, and modify
+several lines according to what happens in only one. A paragraph in
+Interpreter has nothing to do with what TeX considers a paragraph; instead, it
+is defined by the following string.
+
+> interpreter.paragraph [Default: blank line with spaces ignored]
+ A string to be interpreted as a paragraph boundary when Interpreter collects
+ lines before processing them. The string actually represents a pattern, so
+ magic characters are obeyed. The default is "%s*", i.e. a blank line is
+ considered a paragraph boundary, spaces notwithstanding. Of course, the end
+ of the file itself is a paragraph boundary.
+
+
+
+================================== patterns_tag
+=== Declaring patterns ===========
+==================================
+
+Once the lines of a paragraph have been collected, Interpreter searches them
+trying to match declared patterns, but it doesn't do so indiscriminately:
+patterns are searched in a given order, as explained below.
+
+Patterns are searched for in each line only, i.e. no match can occur across
+lines. However, since you can manipulate entire paragraphs based on a match in
+one line, the limitation easily vanishes.
+
+> interpreter.add_pattern(<table>)
+ This is the basic function used to defined patterns. The <table> may
+ contain the following entries, along other entries Interpreter won't use
+ but which can be useful to you, especially with "call" below. The function
+ returns a table.
+
+>> class [Default: "intepreter.default_class"]
+ The class of the pattern. See the section on classes.
+
+>> pattern
+ The pattern to match. Lua's magic characters are in force and should be
+ escaped with "%" if necessary, unless "nomagic" is "true" (or the pattern
+ itself is the result of "interpreter.nomagic").
+
+>> nomagic [Default: "false"]
+ A boolean deciding whether the pattern should be transformed with
+ "interpreter.nomagic".
+
+>> replace
+ The replacement for the pattern, applied only if there is no "call" entry.
+ This may be a string, a table or a function. Interpreter simply executes
+ something similar to "string.gsub()", hence the replacement follows this
+ function's ordinary syntax. More precisely, if "replace" is a string, the
+ pattern is replaced with it; in this string, "%n" may be used to denote the
+ _n_th capture in the pattern. If "replace" is a table, the first capture or
+ the entire match (if there is no capture) is used as the key, and the
+ associated value is used as the replacement. If "replace" is a function, it
+ is called with the captures passed as arguments, or the entire match if
+ there is no capture. For instance, the following pattern will replace all
+ "*text*" with "\bold{text}":
+
+ interpreter.add_pattern{
+ pattern = "%*(.-)%*",
+ replace = [[\bold{%1}]]
+ }
+
+>> offset [Default: 0]
+ The number of positions Interpreter should shift to the right after a match
+ has occurred. Normally, Interpreter starts searching for another occurrence
+ of the current pattern at the same position where it found the last one.
+ However, loops might easily occur: the replacement for a pattern may very
+ well contain another match for the same pattern, so Interpreter will get
+ stuck. Suppose for instance you want to replace "TeX" with "\TeX". The
+ first match will do that, but then Interpreter will start searching again
+ at the backslash, producing "\\TeX", then "\\\TeX", etc. In this case, if
+ you set "offset" to 2 in the pattern, then search will start again at the
+ "e" and no new match will occur.
+
+>> call
+ This entry shall contain a function to be called if there is a match (if
+ this entry exists, "replace" isn't applied). It is meant to perform complex
+ tasks that aren't amenable to simple string replacement. The function will
+ be executed as follows:
+
+ function (paragraph, line, index, pattern)
+
+ "paragraph" is a table representing the current paragraph; lines are stored
+ at successive indices. The last line of this paragraph is always the
+ paragraph boundary (see "interpreter.paragraph"), unless the paragraph
+ stopped at the end of the file. The second argument, "line", is a number
+ representing the index in "paragraph" containing the line where the pattern
+ was found; "index" is the position in this line where the match occurred.
+ Finally, "pattern" is the entire table declared with
+ "interpreter.add_pattern" and containing all the entries discussed here.
+
+ The function may return zero, one, or two numbers. If it returns none, the
+ search for the next occurrence of the pattern will start again on the same
+ line (rather, on the line with the same position in the paragraph), at
+ "index". If it returns one number, the search will resume at the same line
+ but at position _n_, with _n_ the returned number. Finally, if two numbers
+ are returned, the search will resume at line _m_ at position _n_, _m_ and
+ _n_ being the returned values. Specifying which line should be examined
+ when the search resumes might be necessary if the function adds new lines
+ in the paragraph _before_ the current line, since Interpreter only keeps
+ count of line numbers.
+
+ The entire paragraph can thus be modified if necessary. For instance,
+ suppose you want to declare comments in your source file with only
+ "!Comment" in the first line, i.e. TeX should ignore a paragraph such as:
+
+ !Comment
+ This should be ignored
+ by TeX
+
+ Then the following pattern will do (where the function requires only the
+ first argument):
+
+ local function comment (paragraph)
+ for n, l in ipairs(paragraph) do
+ paragraph[n] = "%" .. l
+ end
+ end
+ interpreter.add_pattern{
+ pattern = "^!Comment",
+ call = comment
+ }
+
+> interpreter.nomagic (string)
+ A function which reverses the usual Lua magic for patterns: ordinary magic
+ characters are normal characters here, unless they are prefixed with "%", in
+ which case they are magic again. For instance, a pattern like ".+" is
+ normally interpreted as ``one or more characters''. If passed to this
+ function, a pattern is returned meaning ``a dot followed by a plus sign''.
+ On the contrary, "%.%+" normally has the second interpretation, while with
+ "interpreter.nomagic" it has the first one. The function makes another
+ transformation: "..." is used to denote a capture "(.-)". Thus
+ "interpreter.nomagic('*...*')" returns a pattern matching any number of
+ characters surrounded by stars and capturing those characters; this would be
+ expressed in ordinary Lua magic as "%*(.-)%*".
+
+
+
+================================== classes_tag
+=== Classes ======================
+==================================
+
+As already alluded to, the search for patterns isn't done at random. Instead,
+patterns are organized in classes, which are applied one after the other. More
+precisely, the process is as follows: Interpreter searches the entire
+paragraph for the first pattern in class~1, then for the second pattern in the
+same class, then for the third, etc., then when there is no pattern left in
+class~1 it does the same with class~2, up to class~_n_, where _n_ is the
+highest class number such that there exists a class _n - 1_ (in other words,
+classes should be numbered consecutively). Finally, the same goes for the
+patterns in class~0 (which always exists, even if it contains no pattern).
+
+Inside a class, patterns are ordered by length from long to short, or
+alphabetically if two patterns have the same length. This means that if you
+use e.g. "/text/" for italics and "//text//" for bold, you don't need to put
+the second pattern in a class before the first to avoid "//text//" being
+interpreted as two empty arguments in italics surrounding a text in roman.
+Since the way the bold-pattern will be declared, e.g. "//(.-)//", is probably
+longer than for the italic-pattern, e.g. "/(.-)/", it will always match first.
+
+That said, the sorting isn't very clever and simply relies on the number of
+symbols, no matter what they mean; in the patterns above, the parentheses
+denote a capture but they still count in the pattern's length as understood by
+Interpreter. Alternatively, while ".*" denotes ``zero or more character'' and
+"%+" means ``a plus sign'' ("+" being magic, you have to escape it to refer to
+it), in Interpreter's eye the two patterns have the same length: two. Finally,
+one should be aware that patterns declared with a "nomagic" entry set to
+"true" are sorted after they've been transformed (so that their real length
+might not be obvious). So classes are needed when patterns need a proper
+ordering no matter their lengths. For instance, some patterns should always be
+declared first, as they protect input from Interpreter (see next section),
+while others might need to be declared last, as they rely on what previous
+patterns might have done. Besides, classes are metatables for the patterns
+they contain.
+
+> interpreter.default_class [Default: 1]
+ All patterns belong to a class, even though you may omit the "class" entry
+ when declaring one. In this case, the pattern is assigned to the class
+ denoted by this number.
+
+> interpreter.set_class(number, table)
+ Defines class "number" as "table". Classes don't need to be defined
+ beforehand for patterns to be added to them (rather, Interpreter defines
+ them implicitly when needed). However, classes are also metatables for the
+ patterns, so that if there lacks an entry in a pattern's table, the class's
+ entry is used if it exists. The function returns a table.
+
+
+
+================================== protect_tag
+=== Protecting input =============
+==================================
+
+Sometimes you want Interpreter to refrain from interpreting; that is most
+useful for verbatim code, for instance. There are various ways to do that.
+
+> interpreter.active [Default: true]
+ A boolean switching Interpreter on and off. Beware, the switching applies
+ only starting at the next paragraph.
+
+> interpreter.protect([line])
+ A function protecting all or part of the current paragraph. If "line" is
+ given, it should be a number _n_, and line _n_ in the current paragraph will
+ be protected; without "line", the entire paragraph is protected. Protecting
+ means that the patterns not yet searched for will be ignored. For instance,
+ if you want material to be read verbatim when surrounded with "<code>" and
+ "</code>", you can declare a pattern as follows:
+
+ local function verbatim (buffer)
+ buffer[1] = "\\verbatim"
+ buffer[#buffer - 1] = "\\endverbatim"
+ intepreter.protect()
+ end
+ interpreter.add_pattern{
+ pattern = "^%s*<code>%*s$",
+ call = verbatim,
+ class = 1
+ }
+
+ This code is extremely simplified : it assumes that "<code>" and "</code>"
+ starts and ends the paragraph and that "</code>" isn't the last line of the
+ file (otherwise it'd also be the last line in the paragraph, whereas here
+ the last one is the paragraph boundary). An important point is that the
+ pattern belongs to the first class, so it is called before all other
+ patterns (provided there is no shorter pattern in class~1) and prevents them
+ from doing anything, since the entire paragraph is protected. (Typesetting
+ the material as verbatim material obviously depends on the "\verbatim"
+ macro, not on Interpreter.)
+
+> interpreter.escape
+ A character which prevents patterns from being replaced if immediately
+ preceded by it. As an example, if "interpreter.escape = '_'", and "*text*"
+ denotes italic, then "*text*" will produce _text_ while "_*text*" will
+ produce *text*. Once a paragraph has been processed, Interpreter removes all
+ escape characters. Only one character can be an escape character.
+
+> interpreter.protector(left[, right]) ["right" defaults to "left"]
+ Defines two characters to protect what they surround. In other words,
+ Interpreter replaces patterns only if the match isn't found between "left"
+ and "right". Unlike the escape character, you can define as many protectors
+ as you wish; and unlike the escape character again, Interpreter _doesn't_
+ remove them once the paragraph has been processed, so you must take care of
+ them. For instance:
+
+ intepreter.protector('"')
+ interpreter.add_pattern{
+ pattern = '"(.-)"',
+ replace = '\\verb`%1`',
+ class = 0
+ }
+
+ Anything between double quotes will be left untouched; then, when the
+ paragraph has been processed for all other classes, a pattern in class~0
+ calls the "\verb" command to take care of the argument. Note that the
+ protectors should enclose what they protect without coinciding with it; this
+ is not the case here, which is why the pattern is applied.
+
+> interpreter.direct [Default: two percent signs then "I" and at least one space]
+ A string, actually a pattern, signalling that the line which it begins
+ should be processed as Lua code. The default is "%%%%I%s+", i.e. "%%I"
+ followed by at least one space. The pattern shouldn't declare itself as
+ attached to the beginning of the line (as in "^%%%%I%s+") because they will
+ be matched at the beginning of the line only anyway. The line is processed
+ with the "loadstring" function, and then turned into an empty line. For
+ instance:
+
+ %%I interpreter.active = false
+ This won't be interpreted...
+ %%I interpreter.active = true
+
+ As this example shows, lines flagged with "interpreter.direct" don't obey
+ "interpreter.active" and are always processed as described above.
+
+
+
+================================== technical_tag
+=== Technical stuff ==============
+==================================
+
+You don't have to bother with this section if you don't mind how Interpreter
+does its job; actually you won't learn much anyway.
+
+> interpreter.reset()
+ A function which resets everything to default and deletes classes. It is used
+ when calling "\interpretefile" so that new interpretetions start from zero.
+
+> interpreter.register(function)
+ A function called to put Interpreter's main function into the
+ "post_linebreak_filter" callback; you can redefine it at will. If it is
+ undefined, "callback.register()" is used, unless "luatexbase.add_to_callback()"
+ is detected. (The detection takes place at the first call to
+ "\interpretfile", so there is no need to load Interpreter after
+ "luatexbase".)
+
+> interpreter.unregister(function)
+ A function called to remove Interpreter's main function from the
+ "post_linebreak_filter" callback. It works similarly to the previous one.
+
+
+
+================================== example_tag
+=== An example: i-doc.lua ========
+==================================
+
+\interpretfile{doc}{i-doc.lua}
+
+
+
+================================== gates_tag
+=== The Gates in Interpreter =====
+==================================
+
+Interpreter is written with the Gates package (only the Lua side,
+actually). It means that it can be hacked down to the core. Here I'll
+simply list the gates involved; you should read the Gates
+documentation to learn how to use them.
+
+There are three gates families: "interpreter", associated with the main
+"interpreter" table, contains the user interface; "interpreter_tools",
+associated with "interpreter.core.tools" table, contains internal
+functions; finally "interpreter_reader", associated with the
+"interpreter.core.reader" table, contains the main functions used to
+read the file.
+
+Whenever I mention a conditional or a loop, I mean the local conditionals
+and loops, relative to the l-gate where the gate appears. Also, the
+syntax indicates the arguments a gate uses, not all the arguments that
+are passed to it (which are simply what the previous gate has returned).
+
+As an example of customizing Interpreter with Gates, you could very
+well add a bit of code which does something to all lines. Inserting a
+small gate, say "everyline", after "check_direct" in "aggregate_lines"
+below would do the trick, e.g.:
+
+
+ function interpreter.core.reader.everyline (file, line)
+ line = dosomething(line)
+ return file, line
+ end
+ interpreter.core.reader.add(
+ "everyline", "aggregate_lines", "after check_direct")
+ interpreter.core.reader.conditional(
+ "everyline", "aggregate_lines", function (f, l) return l end)
+
+(Note that it is important to check that the line really exist,
+because one might have hit the end of the file; hence the conditional,
+as with others gates in "aggregate_lines").
+
+
+
+
+================================== interpreter_tag
+=== The "interpreter" table ========
+==================================
+
+All the user functions in "interpreter" are simple m-gates, so they can
+be treated as ordinary functions, except "interpreter.add_pattern",
+which is an l-gate containing, built as:
+
+ add_pattern
+ . ensure_class
+ . apply_nomagic
+ . insert-pattern
+ . . do_insert
+ . . sort_class
+
+> ensure_class (<pattern>) [m-gate]
+ Creates the class of <pattern> if necessary, and set it as the metatable
+ for <pattern>. Classes themselves are kept in the "interpreter.core.classes"
+ table. The gate return <pattern> and the class number.
+
+> apply_nomagic (<pattern>, <class>) [m-gate]
+ Transforms the "pattern" entry in <pattern> with "intepreter.nomagic";
+ tied to a conditional that returns <pattern>'s "nomagic" entry (so
+ the gate is executed only if "nomagic" is true); autoreturns both
+ arguments.
+
+> insert_pattern (<pattern>, <class>) [l-gate]
+ An autoreturning l-gate containing the following two gates.
+
+> do_insert (<pattern>, <class>) [m-gate]
+ Adds <pattern> to <class> (i.e. "interpreter.core.classes[<class>]").
+
+> sort_class (<pattern>, <class>) [m-gate]
+ Sorts <class> with function "interpreter.core.tools.sort". This gate
+ can be skipped to apply the patterns in the order in which they were
+ declared.
+
+
+
+============================================= interpreter_tools_tag
+=== The interpreter.core.tools table ========
+=============================================
+
+All the functions in the "interpreter.core.tools" all are simple m-gates.
+
+> sort (<patt1>, <patt2>) [m-gate]
+ Returns true if the pattern in "patt1" is longer than the one in
+ "patt2", or if they have the same length and the first ranks before
+ the second with respect to alphabetical order. The gate is used in
+ the "interpreter.sort_class" m-gate.
+
+> xsub (<string>, <index>, <pattern>, <replacement>) [m-gate]
+ Returns <string> with <pattern> replaced with <replacement>, but only
+ once, and only after <index>.
+
+> protector (<string>, <index>) [m-gate]
+ Checks whether <index> in <string> isn't between characters declared
+ with "interpreter.protector". If that is the case, the function returns
+ "nil" and the index of the second protector. Otherwise, it returns
+ <index>.
+
+> get_index (<string>, <pattern>, <index>) [m-gate]
+ Checks whether <pattern> occurs in <string>, starting at <index>. If
+ it does, but if <index>-1 is "interpreter.escape", calls itself with
+ <index>+1. Otherwise, calls "interpreter.core.tools.protector" to
+ check whether <index> is in a protected part of the string. If so,
+ calls itself with <right>+1 instead of <index>, where <right> is the
+ second return value of of "interpreter.core.tools.protector", i.e.
+ it searches again after the right protector. If <index> is found,
+ end of story, returns <index>, otherwise returns nothing.
+
+The "interpreter.core.tools" table also contains
+"magic_characters", a table with an entry for each magic character in Lua except
+`"."' and `"%"'; the values to those entries are the same characters
+prefixed with `"%"'. The table is used by "interpreter.nomagic" to spot
+and replace magic characters, with the dot and the percent sign dealt
+with independantly.
+
+
+
+============================================= interpreter_reader_tag
+=== The interpreter.core.reader table =======
+=============================================
+
+Interpreter works by hooking in the "open_read_file" callback; the
+function registered there is the "interpreter.core.reader.input"
+l-gate, built as follows:
+
+ input
+ . unregister
+ . . set_unregister
+ . . use_unregister
+ . open_file
+ . set_reader
+
+> unregister (<filename>) [l-gate]
+ Contains the following two m-gates; <filename> is received from
+ "input", which itself receives it from the callback, i.e. that's the
+ file that's being input (the second argument to "\interpretfile").
+ It is also automatically returned.
+
+> set_unregister () [m-gate]
+ Sets the function to remove "input" from the callback, namely
+ "interpreter.unregister"; the gate is called only if gate
+ "interpreter.unregister" doesn't already exits. If "luatexbase" is
+ detected, the functions there are used; otherwise, "callback.register"
+ is used with "nil" as the second argument.
+
+> use_unregister () [m-gate]
+ Calls "interpreter.unregister()". (You don't want the next input file
+ to be processed with Interpreter by default, that's why you remove
+ the callback function; not that the current one is nonetheless
+ processed with the current file, of course.)
+
+> open_file (<filename>) [m-gate]
+ Returns "io.open(<filename>)".
+
+> set_reader (<file>) [m-gate]
+ Returns a table with a "reader" entry containing a function whose
+ definition is
+
+ function ()
+ return interpreter.core.reader.read_file(f)
+ end
+
+ That's the convention for the "open_read_file" callback: it should
+ return such a table, and the function will be called each time a
+ line is required from the input file.
+
+So most of the work is done by "interpreter.core.reader.read_file",
+which is why it is so heavy; it receives a file handle:
+
+ read_file
+ . make_paragraph
+ . . aggregate_lines
+ . . . read_line
+ . . . check_direct
+ . . . insert_line
+ . . apply_classes
+ . . . pass_class
+ . . . . pass_pattern
+ . . . . . process_lines
+ . . . . . . switch
+ . . . . . . call
+ . . . . . . replace
+ . . . . . . protect
+ . . . unprotect
+ . . . . undo_protected
+ . . . . unprotect_lines
+ . . . remove_escape
+ . return_line
+
+> make_paragraph (<file>) [l-gate]
+ The big l-gate that contains everything that follows, barring
+ "return_line". It is called if and only if the "interpreter.core.lines"
+ table is empty; that table is where lines of a paragraph are stored,
+ and it is emptied by "return_line".
+
+> aggregate_lines (<file>, <line>) [l-gate]
+ The main l-gate that reads line from <file> and stores them in
+ "interpreter.core.lines". It loops until <line> is "nil" or equivalent
+ to "interpreter.paragraph". (Of course, <line> is "nil" on the first
+ iteration, but the "loopuntil" conditional is evaluated after that
+ first iteration, during which the last subgate "insert_line" will
+ probably returns a line.)
+
+> read_line (<file>) [m-gate]
+ Reads the next line from <file>, and returns <file> and that line.
+
+> check_direct (<file>, <line>) [m-gate]
+ If <line> begins with "interpreter.direct", removes it and use
+ "loadstring" on the resulting string. Returns <file> and <line>, the
+ latter set to an empty string is the previous operation applied. The
+ gate depends on a conditional: <line> should be non-"nil" (of
+ course), and "interpreter.direct" should be defined.
+
+> insert_line (<file>, <line>) [m-gate]
+ Adds <line> to "interpreter.core.lines". Automatically returns the
+ two arguments (and if <line> isn't "nil" or equivalent to
+ "interpreter.paragraph", it will be executed again).
+
+> apply_classes () [l-gate]
+ The l-gate that applies transformations to the lines, once the paragraph
+ has been gathered, with the gates that follow. For each class, it
+ will apply each pattern on each line. It depends on a conditional:
+ "interpreter.core.lines" shouldn't be empty, and "interpreter.active"
+ should be true.
+
+> pass_class () [l-gate]
+ This gate iterates on all classes in "interpreter.core.classes" and
+ then on class 0. On each iteration it checks beforehand whether the
+ paragraph is protected, i.e. "interpreter.core.reader.protected" isn't
+ a boolean (see "unprotecte" below). On each iteration, the class
+ number and the class itself are returned. (This behavior is
+ implemented with a Gates iterator.)
+
+> pass_pattern (<ignored>, <class>) [l-gate]
+ Same as "pass_class", except it iterates on the patterns in "class":
+ it is executed as long as "interpreter.core.reader.protected" and
+ returns the patter number and the pattern itself. (The <ignored>
+ argument isn't used; it is for the "pass_class" iterator; the same
+ holds for the following gates.)
+
+> process_lines (<ignored>, <pattern>) [l-gate]
+ Again, this calls an iterator. It browses each line in "interpreter.core.lines"
+ and returns the line's number (provided it is valid, i.e. not a table,
+ see "protect" below), <pattern> and the current index in that line.
+ To keep track of the current line and index, two internal numbers are
+ used: "interpreter.core.reader.current_line" and
+ "interpreter.core.reader.current_index".
+
+> switch (<line>, <pattern>, <index>) [m-gate]
+ If <pattern> has a "call" entry, it sets the "call" gate below to
+ "ajar"; otherwise, if <pattern> has a "replace" entry, it sets the
+ "replace" gate to "ajar".
+
+> call (<line>, <pattern>, <index>) [m-gate]
+ This gate is closed by default and set to "ajar" by "switch" above.
+ If, starting at <index>, the <pattern>'s "pattern" entry can be
+ found in <line> with "interpreter.core.tools.get_index" (which makes
+ sure that protectors are obeyed and returns <newindex>, where the
+ pattern is found if it occurs), the <pattern>'s "call" entry is
+ applied as
+
+ <pattern>.call(interpreter.core.lines,
+ <line>, <newindex>, <pattern>)
+
+ This may returned zero, one or two values. If nothing is returned,
+ "interpreter.core.reader.current_index" is set to 0, which makes
+ the "process_lines" iterator consider the next line. If one value is
+ returned, it is the new current index and "process_lines" will not
+ update the line number. If two values are returned, the first is the
+ new current line number and the second the new current index.
+
+> replace (<line>, <pattern>, <index>) [m-gate]
+ This gate is closed by default and set to "ajar" by "switch" above.
+ This tries to find the <pattern>'s "pattern" like "call" above, and if
+ it is found, it applies "interpreter.core.tools.xsub" as:
+
+ xsub (interpreter.core.lines[<line>],
+ <newindex>, <pattern>.pattern, <pattern>.replace)
+
+ where <newindex> is defined as in "call". The return value of "xsub"
+ is assigned to "interpreter.core.lines[<line>]", and the current
+ index is set to <index> plus the <pattern>'s "offset" if any. If the
+ pattern wasn't found, the current index is set to 0, which makes
+ "process_lines" turn to the next line as explained in "call".
+
+> protect () [m-gate]
+ The "interpreter.protect()" function can either protect the whole
+ paragraph (when no argument is passed) or a single line (when a number
+ is passed). In the first case, "interpreter.core.tools.protected"
+ takes the value "true", which is checked in various gates above. In
+ the second case, "interpreter.core.tools.protected" is a table with
+ each index indicating a line to be protected. This gate implements
+ the protection in that case: it iterates on all entries in the table
+ with "pairs" and protects the line with the same index in
+ "interpreter.core.lines" by transforming it into a table (with a
+ single entry, the string representing the original line); the type
+ of the line is checked in the "process_lines" iterator above. The
+ gate's iterator doesn't take arguments, but the function itself is
+ defined as taking a number (the line).
+
+> unprotect () [l-gate]
+ Now all the patterns in all the classes have been applied to the
+ entire paragraph, and protection must be removed. This l-gate
+ contains the following two gates.
+
+> undo_protected () [m-gate]
+ Simply sets "interpreter.core.tools.protected" to "nil" so it is
+ ready for the next paragraph.
+
+> unprotect_lines () [m-gate]
+ Restores all the lines in "interpreter.core.lines" as simple strings.
+ The gate uses an iterator that simply runs "ipairs" on "interpreter.core.lines",
+ so the function's definition actually takes the line's number and
+ the line itself as arguments.
+
+> remove_escape () [m-gate]
+ If "interpreter.escape" is defined, removes all its occurrences in
+ each line of the paragraph.
+
+This is the end of the big "make_paragraph" l-gate. It won't be called
+again until the paragraph has been fully passed to TeX, i.e. when
+"interpreter.core.lines" is empty.
+
+> return_line () [m-gate]
+ Pops the first line from "interpreter.core.lines" and returns it.
+ Since this is the very last subgate of "read_file", the line is
+ passed to TeX.
+
diff --git a/macros/luatex/generic/interpreter/interpreter.lua b/macros/luatex/generic/interpreter/interpreter.lua
new file mode 100644
index 0000000000..05de6eb791
--- /dev/null
+++ b/macros/luatex/generic/interpreter/interpreter.lua
@@ -0,0 +1,450 @@
+-- This is the main Lua file for the Interpreter package.
+-- Further information in interpreter-doc.pdf or interpreter-doc.txt.
+-- Paul Isambert - zappathustra AT free DOT fr - June 2012
+--
+-- Beware, this is written with Gates. Please read the Gates doc if
+-- you want to understand something.
+
+local find, gsub, match, sub = string.find, string.gsub, string.match, string.sub
+local insert, sort, remove = table.insert, table.sort, table.remove
+local io_open = io.open
+local ipairs, pairs, type = ipairs, pairs, type
+require("gates.lua")
+if not gates.iterator then
+ tex.error("Interpreter error: Your version of Gates should be at least v.0.2. I quit. Expect chaos")
+ return
+end
+
+interpreter = gates.new("interpreter")
+
+-- *** interpreter.active ***
+-- Following paragraphs (as defined by interpreter.paragraph) are interpreted
+-- iff this is not set to false.
+interpreter.active = true
+-- *** interpreter.default_class ***
+-- Sets the default class for patterns which are added without specifying the
+-- class. Default 1.
+interpreter.default_class = 1
+
+interpreter.core = {
+ classes = {}, -- The classes of patterns.
+ lines = {}, -- The lines of the paragraph.
+ reader = gates.new("interpreter_reader"), -- The main processing functions.
+ tools = gates.new("interpreter_tools")} -- Auxiliary functions.
+
+-- Utility function sorting patterns by length (alphabetically if they are of
+-- equal length).
+function interpreter.core.tools.sort (a, b)
+ local a, b = a.pattern, b.pattern
+ return #a == #b and a < b or #a > #b
+end
+
+-- *** interpreter.add_pattern (table) ***
+-- Creates pattern <table>, which can contain the following entries:
+-- pattern [string] = The pattern to match. Magic characters are obeyed!
+-- replace [string] = The replacement for <pattern>. Can be a string, a
+-- table or a function. A simple string.gsub() is
+-- applied.
+-- call [function] = The function applied to <pattern>; <replace> is applied
+-- iff there is no <call>.
+-- offset [number] = If <pattern> is used at index n, then the search on the
+-- same line for the same pattern starts again at index n
+-- + offset. Applied only when no <call> (in this case,
+-- search starts again at the beginning of the line). By
+-- default, offset = 0. This is needed to avoid infinite
+-- loops with replacements which contain the pattern;
+-- e.g. replacing "TeX" with "\TeX" will produce an
+-- infinite loop, unless offset = 2.
+-- nomagic [boolean] = Sets whether <replace> should be transformed with interpreter.nomagic.
+-- class [number] = The pattern's <class> (classes of patterns are applied in
+-- order, e.g. all patterns in class 1 are applied, then
+-- all patterns in class 2, etc; class 0, however, is
+-- always applied last). If <class> is not given, the
+-- default_class number is used. Classes must be numbered
+-- consecutively.
+interpreter.list{"add_pattern",
+ {"ensure_class",
+ function (tb)
+ local class = tb.class or interpreter.default_class
+ interpreter.set_class(class, {})
+ setmetatable(tb, interpreter.core.classes[class].meta)
+ return tb, class
+ end},
+ {"apply_nomagic", conditional = function (tb) return tb.nomagic end,
+ autoreturn = true,
+ function (tb, class)
+ tb.pattern = interpreter.nomagic(tb.pattern)
+ end},
+ {"insert_pattern", autoreturn = true,
+ {"do_insert", autoreturn = true,
+ function (tb, class)
+ insert(interpreter.core.classes[class], tb)
+ end},
+ {"sort_class", autoreturn = true,
+ function (tb, class)
+ sort(interpreter.core.classes[class], interpreter.core.tools.sort)
+ end}}}
+
+-- *** interpreter.set_class (number, table) ***
+-- Sets default values (of the table normally specified in add_pattern) for
+-- patterns of class <number>; patterns added to this class can still specify
+-- different values, which will override defaults. In other words, this is a
+-- metatable for patterns (which are tables) of that class.
+function interpreter.set_class (num, tb)
+ interpreter.core.classes[num] = interpreter.core.classes[num] or
+ { meta = { __index = function (_, k) return interpreter.core.classes[num].meta[k] end } }
+ for a, b in pairs(tb) do
+ interpreter.core.classes[num].meta[a] = b
+ end
+ return interpreter.core.classes[num]
+end
+
+-- Class 0 must exist since it is always used at the end of the paragraph.
+interpreter.set_class(0, {})
+
+-- *** interpreter.nomagic (string) ***
+-- Turns a normal string into a string with magic characters escaped, so it
+-- can be used as a pattern.
+interpreter.core.tools.magic_characters = {
+ ["^"] = "%^",
+ ["$"] = "%$",
+ ["("] = "%(",
+ [")"] = "%)",
+ ["%"] = "%%",
+ ["."] = "%.",
+ ["["] = "%[",
+ ["]"] = "%]",
+ ["*"] = "%*",
+ ["+"] = "%+",
+ ["-"] = "%-",
+ ["?"] = "%?",
+}
+function interpreter.nomagic (str)
+ local i, s = 1, ""
+ local magic_characters = interpreter.core.tools.magic_characters
+ while i <= #str do
+ local c, c2, c3 = sub(str, i, i), sub(str, i + 1, i + 1), sub(str, i + 2, i + 2)
+ i = i + 1
+ if c == "%" and magic_characters[c2] then
+ s = s .. c2
+ i = i + 1
+ elseif c == "." and c2 == "." and c3 == "." then
+ s = s .. "(.-)"
+ i = i + 2
+ elseif magic_characters[c] then
+ s = s .. "%" .. c
+ else
+ s = s .. c
+ end
+ end
+ return s
+end
+
+-- *** interpreter.protect ([spec]) ***
+-- Protects a set of lines in a paragraph; a protected line won't be
+-- interpreted. If <spec> is a number, this protects line <spec> in the current
+-- paragraph; if <spec> is true, this protects the entire current paragraph. Of
+-- course, patterns that were applied to the line(s) or paragraph before
+-- protection happened aren't undone.
+function interpreter.protect (num)
+ if type(num) == "number" then
+ if type(interpreter.core.reader.protected) ~= "boolean" then
+ interpreter.core.reader.protected = interpreter.core.reader.protected or {}
+ interpreter.core.reader.protected[num] = true
+ end
+ else
+ interpreter.core.reader.protected = true
+ end
+end
+
+-- Utility function making a replacement in a string but only from a certain
+-- position and only once. We can't let gsub unrestricted, because some
+-- part(s) of the string might be protected.
+function interpreter.core.tools.xsub (str, num, patt, rep)
+ return sub(str, 1, num-1) .. gsub(sub(str, num), patt, rep, 1)
+end
+
+-- *** interpreter.protector (left [, right]) ***
+-- Sets <left> and <right> (set to <left> if missing) as protectors, i.e.
+-- enclosed material won't be processed even if the line is processed
+-- otherwise. For instance: after interpreter.protector ("|"), the word
+-- "little" in
+--
+-- Hello, |little| world!
+--
+-- will be left untouched; Interpreter is terribly smart (thanks to lpeg), so
+-- in "|a| b |c|", "b" isn't protected, as intended, because the "|" on its
+-- left doesn't match the one on its right but with the one before "a". An
+-- example with <right> specified: interpreter.protector("[", "]") and
+-- then:
+--
+-- Hello, [little] world!
+--
+-- achieves the same as above. Protectors AREN'T removed when the line is
+-- finally passed to TeX; and there can be several protectors. Compare with
+-- interpreter.escape.
+local P, Cf, Cg, Cp, Ct, V = lpeg.P, lpeg.Cf, lpeg.Cg, lpeg.Cp, lpeg.Ct, lpeg.V
+local _grammar
+function interpreter.core.tools.protector (str, index)
+ local protections = Cf(Ct("") * Cg{ _grammar + 1 * V(1) }^1, rawset)
+ protections = protections:match(str)
+ if protections then
+ for a, b in pairs(protections) do
+ if index > a and index < b then
+ return nil, b
+ end
+ end
+ end
+ return index
+end
+function interpreter.protector (left, right)
+ right = right or left
+ local gram = P(Cp() * P(left) * (1 - P(right))^0 * Cp() * P(right))
+ if _grammar then
+ _grammar = _grammar + gram
+ else
+ _grammar = gram
+ end
+end
+
+-- *** interpreter.escape ***
+-- A string used as an escape character: if a pattern matches, it is processed
+-- iff the character immediately to its left isn't <escape>. The escape
+-- character IS removed once the lines have been processed, so TeX never sees
+-- it; also, only one escape character is allowed, and itself can't be escaped
+-- (i.e. it doesn't mean anything to try to escape it). E.g.:
+--
+-- interpreter.escape = "|"
+-- ... this won't be |*processed*
+--
+-- Assuming you have a pattern with stars, here it won't be applied. Instead
+-- "this won't be *processed*" will be passed to TeX (note that the escape
+-- character has disappeared).
+
+function interpreter.core.tools.get_index (str, patt, index)
+ index = find(str, patt, index)
+ if index then
+ if sub(str, index-1, index-1) == interpreter.escape then
+ return interpreter.core.tools.get_index(str, patt, index + 1)
+ elseif _grammar then
+ local right
+ index, right = interpreter.core.tools.protector(str, index, patt)
+ return index or interpreter.core.tools.get_index(str, patt, right + 1)
+ else
+ return index
+ end
+ end
+end
+
+-- *** interpreter.paragraph ***
+-- The pattern that defines a line acting as a paragraph boundary,
+-- prompting Interpreter to process the lines gathered up to now. Default is a
+-- line composed of spaces at most.
+interpreter.paragraph = "%s*"
+
+-- *** interpreter.direct (pattern) ***
+-- Sets the pattern defining a line as direct Lua code: if a line begins with
+-- <pattern> (which itself shouldn't contain the beginning-of-string character "^")
+-- the code that follows is processed as Lua code, and the line is turned to
+-- an empty string; note that this empty string will be seen as a paragraph
+-- boundary if the line happened in the middle of a paragraph and
+-- interpreter.paragraph has set paragraph boundary to empty string. Default
+-- is "%%I " (two "%" followed by one "I" followed by at least one space
+-- character).
+interpreter.direct = "%%%%I%s+"
+
+-- At last, the function to be registered in open_read_file, defining the
+-- function that reads a file.
+
+interpreter.core.reader.current_line = 0
+interpreter.core.reader.current_line = 0
+
+interpreter.core.reader.list{"read_file",
+ {"make_paragraph", conditional = function () return #interpreter.core.lines == 0 end,
+ {"aggregate_lines", loopuntil = function (_, line) return not line or gsub(line, "^" .. interpreter.paragraph .. "$", "") == "" end,
+ {"read_line",
+ function (f)
+ return f, f:read()
+ end},
+ {"check_direct", conditional = function (_, line) return line and interpreter.direct end,
+ function (f, line)
+ if match(line, "^" .. interpreter.direct) then
+ loadstring(gsub(line, "^" .. interpreter.direct, ""))()
+ line = ""
+ end
+ return f, line
+ end},
+ {"insert_line", conditional = function (_, line) return line end,
+ autoreturn = true,
+ function (f, line)
+ insert(interpreter.core.lines, line)
+ end}},
+ {"apply_classes", conditional = function () return #interpreter.core.lines > 0 and interpreter.active end,
+ {"pass_class", iterator = function ()
+ local done_zero
+ local function f (t, i)
+ if type(interpreter.core.reader.protected) ~= "boolean" then
+ if not done_zero then
+ i = i+1
+ local v = t[i]
+ if v then
+ return i, v
+ else
+ done_zero = true
+ return 0, t[0]
+ end
+ end
+ end
+ end
+ return f, interpreter.core.classes, 0
+ end,
+ {"pass_pattern", iterator = function (_, class)
+ local function f (t, i)
+ if type(interpreter.core.reader.protected) ~= "boolean" then
+ i = i+1
+ local v = t[i]
+ if v then
+ return i, v
+ end
+ end
+ end
+ return f, class, 0
+ end,
+ {"process_lines", iterator = function (_, pattern)
+ interpreter.core.reader.current_line = 0
+ interpreter.core.reader.current_index = 0
+ return function ()
+ if type(interpreter.core.reader.protected) ~= "boolean" then
+ local l = interpreter.core.reader.current_line
+ local i = interpreter.core.reader.current_index
+ if i == 0 then
+ l, i = l + 1, 1
+ end
+ line = interpreter.core.lines[l]
+ -- When protected, a line is a table.
+ while type(line) == "table" do
+ l, i = l+1, 1
+ line = interpreter.core.lines[l]
+ end
+ if line then
+ interpreter.core.reader.current_line = l
+ interpreter.core.reader.current_index = i
+ return l, pattern, i
+ end
+ end
+ end
+ end,
+ {"switch", autoreturn = true,
+ function (_, pattern)
+ if pattern.call then
+ interpreter.core.reader.ajar("call", "process_lines")
+ elseif pattern.replace then
+ interpreter.core.reader.ajar("replace", "process_lines")
+ end
+ end},
+ {"call", status = "close",
+ function(i, pattern, ind)
+ local line = interpreter.core.lines[i]
+ local index = interpreter.core.tools.get_index(line, pattern.pattern, ind)
+ if index then
+ local L, O = pattern.call(interpreter.core.lines, i, index, pattern)
+ if O then
+ interpreter.core.reader.current_line = L
+ interpreter.core.reader.current_index = O
+ elseif L then
+ interpreter.core.reader.current_index = L
+ end
+ else
+ interpreter.core.reader.current_index = 0
+ end
+ end},
+ {"replace", status = "close",
+ function(i, pattern, ind)
+ local line = interpreter.core.lines[i]
+ local index = interpreter.core.tools.get_index(line, pattern.pattern, ind)
+ if index then
+ interpreter.core.lines[i] = interpreter.core.tools.xsub(line, index, pattern.pattern, pattern.replace)
+ interpreter.core.reader.current_index = index + (pattern.offset or 0)
+ else
+ interpreter.core.reader.current_index = 0
+ end
+ end},
+ {"protect", iterator = function ()
+ if type(interpreter.core.reader.protected) == "table" then
+ return pairs(interpreter.core.reader.protected)
+ end
+ end,
+ function (n)
+ if type(interpreter.core.lines[n]) == "string" then
+ interpreter.core.lines[n] = {interpreter.core.lines[n]}
+ end
+ end}}}},
+ {"unprotect",
+ {"undo_protected",
+ function ()
+ interpreter.core.reader.protected = nil
+ end},
+ {"unprotect_lines", iterator = function () return ipairs(interpreter.core.lines) end,
+ function (i, l)
+ if type(l) == "table" then
+ interpreter.core.lines[i] = l[1]
+ end
+ end}},
+ {"remove_escape", conditional = function () return interpreter.escape end,
+ function ()
+ for num, line in ipairs(interpreter.core.lines) do
+ interpreter.core.lines[num] = gsub(line, interpreter.escape, "")
+ end
+ end}}},
+ {"return_line",
+ function ()
+ return remove(interpreter.core.lines, 1)
+ end}}
+
+interpreter.core.reader.list{"input",
+ -- *** interpreter.unregister () ***
+ -- The function used to remove read_file from the "open_read_file" callback.
+ -- Uses callback.register by default, or luatexbase.remove_from_callback if
+ -- detected.
+ {"unregister", autoreturn = true,
+ {"set_unregister", conditional = function () return interpreter.type"unregister" == 0 end,
+ function ()
+ if luatexbase and luatexbase.remove_from_callback then
+ function interpreter.unregister ()
+ luatexbase.remove_from_callback("open_read_file", "interpreter")
+ end
+ else
+ function interpreter.unregister ()
+ callback.register("open_read_file", nil)
+ end
+ end
+ end},
+ {"use_unregister",
+ function () -- You can't use the `unregister' gate directly, because it isn't created yet.
+ interpreter.unregister()
+ end}},
+ {"open_file",
+ function (fname)
+ return io_open(fname)
+ end},
+ {"set_reader",
+ function (f)
+ return {reader = function () return interpreter.core.reader.read_file(f) end}
+ end}}
+
+function interpreter.reset ()
+ interpreter.active = true
+ interpreter.default_class = 1
+ interpreter.core.classes = {}
+ interpreter.set_class(0, {})
+ _grammar = nil
+ interpreter.escape = nil
+ interpreter.paragraph = "%s*"
+ interpreter.direct = "%%%%I%s+"
+end
+
+-- *** interpreter.register (function) ***
+-- The function used to register the read_file function in the
+-- "open_read_file" callback. If none is given, use callback.register, or
+-- luatexbase.add_to_callback if detected (with "interpreter" as the name).
+-- The function is defined in \interpretfile (see interpreter.tex).
diff --git a/macros/luatex/generic/interpreter/interpreter.sty b/macros/luatex/generic/interpreter/interpreter.sty
new file mode 100644
index 0000000000..ba16a86256
--- /dev/null
+++ b/macros/luatex/generic/interpreter/interpreter.sty
@@ -0,0 +1,17 @@
+% This is interpreter.sty, a style file to load
+% the Interpreter package in LaTeX. Useful information
+% can be found in interpreter-doc.pdf or interpreter-doc.txt.
+%
+% Author: Paul Isambert.
+% E-mail: zappathustra AT free DOT fr
+% Comments and suggestions are welcome.
+% Date: June 2012.
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{interpreter}[2012/06/10 v.1.2 Preprocessing input files on the fly.]
+% Needed to prevent LaTeX check input, which would call open_read_file and
+% thus remove Interpreter's main function (which is removed as soon as it is
+% used).
+\expandafter\let\expandafter\interpreterinput\csname @@input\endcsname
+\input interpreter.tex
+\endinput
diff --git a/macros/luatex/generic/interpreter/interpreter.tex b/macros/luatex/generic/interpreter/interpreter.tex
new file mode 100644
index 0000000000..3568fc90e9
--- /dev/null
+++ b/macros/luatex/generic/interpreter/interpreter.tex
@@ -0,0 +1,37 @@
+% This is the main TeX file for the Interpreter package.
+% Further information in interpreter-doc.pdf or interpreter-doc.txt.
+%
+% Paul Isambert - zappathustra AT free DOT fr - June 2012
+%
+\csname Oh no, Interpreter won't be loaded twice!\endcsname
+\expandafter\let\csname Oh no, Interpreter won't be loaded twice!\endcsname\endinput
+\directlua{require("interpreter.lua")}
+\def\interpretergobble#1{}
+\unless\ifdefined\interpreterinput
+ \let\interpreterinput\input
+\fi
+\def\interpretfile#1#2{%
+ \directlua{%
+ local f = kpse.find_file("i-#1.lua")
+ if f then
+ interpreter.reset()
+ dofile(f)
+ if interpreter.type"register" == 0 then
+ if luatexbase and luatexbase.add_to_callback then
+ function interpreter.register (f)
+ luatexbase.add_to_callback("open_read_file", f, "interpreter")
+ end
+ else
+ function interpreter.register (f)
+ callback.register("open_read_file", f)
+ end
+ end
+ end
+ interpreter.register(interpreter.core.reader.input)
+ tex.print([[\noexpand\interpreterinput]])
+ else
+ tex.error("I can't find file `i-#1.lua'. I won't input file `#2'")
+ tex.print([[\noexpand\interpretergobble]])
+ end
+ }{#2}%
+ }
diff --git a/macros/luatex/generic/kanaparser/README.md b/macros/luatex/generic/kanaparser/README.md
new file mode 100644
index 0000000000..7bf1f99c1a
--- /dev/null
+++ b/macros/luatex/generic/kanaparser/README.md
@@ -0,0 +1,27 @@
+# Kana Parser for LuaTeX
+
+## Author: Adam Zahumenský
+-----------------------------
+
+This is a LuaTeX package that allows for transliteration of Japanese syllabic alphabets, hiragana and katakana, to latin and vice versa.
+The intention of this package is to assist in learning of the kana alphabets and allow users to write kana directly using latin, convert between the two kanas or romanize kana using simple macros.
+I used the most common Hepburn romanization system while keeping to ASCII character set, hence not supporting long latin characters and instead using direct vowel transliteration (ou instead of Å).
+
+The package features three functional macros, one for each target alphabet (latin, hiragana, katakana), which transliterate as much of the provided text as possible to the target alphabet.
+The macros accept a multi-paragraph argument containing the text to transliterate.
+Before using of any of these macros, use the \parserInit macro once to initialize the parser.
+
+Some syllables such as "ji" support multiple kana representations. Refer to kanaparser.tex for the list of these syllables and use the \toggleChars macro to toggle between their representations.
+Default choices are based on usage frequency.
+
+To remove ambiguity of syllables beginning with a vowel and following the 'n' character, this package features an isolator character, ' (apostrophe). Refer to examples.tex for its usage.
+
+To use geminated consonants in syllables such as tta using the little tsu (sokuon) character, double the desired consonant instead of typing 't'. Hence type ecchi instead of etchi.
+
+To output Japanese characters you need to use a font with support for these characters. An example of this is ipafont.
+LuaTeX cannot load otf/ttf fonts natively, use the luaotfload.sty helper bundled in TeXLive to do that.
+Refer to examples.txt for font usage, ipafont is required to use the ipagp.otf font referenced in the file.
+
+License: BSD
+Supported Lua version: 5.2
+Last package revision: 19 June 2018 \ No newline at end of file
diff --git a/macros/luatex/generic/kanaparser/description.pdf b/macros/luatex/generic/kanaparser/description.pdf
new file mode 100644
index 0000000000..72ae33af35
--- /dev/null
+++ b/macros/luatex/generic/kanaparser/description.pdf
Binary files differ
diff --git a/macros/luatex/generic/kanaparser/description.tex b/macros/luatex/generic/kanaparser/description.tex
new file mode 100644
index 0000000000..3a6a424ea4
--- /dev/null
+++ b/macros/luatex/generic/kanaparser/description.tex
@@ -0,0 +1,109 @@
+% This file produces a description document for the Kana Parser project
+
+\input luaotfload.sty % otf font loader
+\input kanaparser % load the parser package
+
+\font\jp = ipagp % ipagp.otf font is included in the ipafont font package: https://www.internationalphoneticassociation.org/content/ipa-fonts
+\font\hdf = cmbx12 at 18pt
+\font\nmf = cmbx12 at 14pt
+
+% wrapper macros that change font automatically
+\def\jchar#1{{\jp #1}}
+\def\kpth#1{\jchar{\toHiragana{#1}}}
+\def\kptk#1{\jchar{\toKatakana{#1}}}
+\def\kptl#1{\jchar{\toLatin{#1}}}
+
+% styling macros
+\def\hd#1{{\hdf#1}\vskip 10pt}
+\def\nm#1{\vskip 10pt{\nmf#1}\vskip 8pt}
+
+\parserInit % initialize kana parser
+
+\hd{Kana Parser for Lua\TeX}
+
+Greetings, reader. This document will describe this Lua\TeX \kern3pt package in detail, providing all the information you need to start using this package.
+We will analyze the Japanese writing system and see how it relates to the Latin script. Then we will see how this package handles the conversion.
+
+\nm{1. The Japanese writing system}
+
+The modern Japanese uses four distinct character sets: Latin (also known as `romaji' in Japanese), a pair of syllabic sets known as kana and ultimately kanji, the complex ideographic set borrowed from the Chinese. They combine these four sets regularly, a practice usually very confusing for newcomers to the language.
+
+Kanji is based on a subset of Chinese ideograms known as `hanzi' in China and cannot be transliterated to Latin by a simple state automaton, requiring solid context awareness.
+
+Kana, however, is a phonetic system based on syllables which can be directly transliterated to Latin. The two kana sets are known as hiragana and katakana.
+Kana represents a set of roughly 46 syllables (48 including two obsolete ones), each syllable has a hiragana and a katakana character assigned to it.
+There are five vowel characters (a, i, u, e, o), an `n' character and the rest are syllabic compounds of vowels and consonants, such as `wo'.
+
+Hiragana is used for native syntactic and grammatic constructs as well as common words and phrases. It's also used in material intended to be read by juveniles and children who do not yet understand complex kanji.
+
+Katakana is used for loanwords, foreign words and usually onomatopoeia among other uses.
+The two kanas cover the same set of syllables and as such can be freely converted between each other.
+
+\nm{2. Differences between the kanas}
+
+Despite covering the same syllable set, there are certain differences between the systems.
+The most striking difference is in how the sets prolong their syllables.
+Prolongation here means extending a vowel-terminated syllable by a pure vowel, getting a syllable of double length. An example of this is \jchar{ma => maa}.
+
+Hiragana prolongs syllables by explicitly putting a vowel character after a syllable: \kpth{ma => maa}.\break
+Here you can see how an \kpth{a} gets appended to \kpth{ma} to prolong it.
+Syllables ending in o and e are instead prolonged by u and i, respectively: \jchar{mo => mou} (\kpth{mo => mou})
+
+Katakana uses a single prolonging character, \jchar ー, to prolong any vowel-terminated syllable.
+This package ensures this character is always correctly transliterated to its respective hiragana vowel or Latin vowel.\break
+\kptk{mo => mou} in katakana translates correctly to \kpth{\toKatakana{mo => mou}} in hiragana and \kptl{\toKatakana{mo => mou}} in Latin.
+
+Another difference is in katakana's added support for various foreign syllables. These syllables don't exist in native Japanese, such as vu (\kptk{vu}).
+These syllables help in better representing foreign words and as such don't commonly have hiragana counterparts.
+However, thanks to the inter-compatibility of kana character set, even these syllables can be written in hiragana, although such use is very unusual: vu (\kpth{vu}).
+This package supports such conversions to promote learning of the character sets.
+
+\nm{3. Consonant gemination}
+
+Japanese language supports doubling (or gemination) of certain unvoiced consonants (s, t, k, p, ch) when they appear at the beginning of a syllable. An example of this is the syllable `ka' (\kpth{ka}) which turns into `kka' (\kpth{kka}) when geminated. As seen in the example, the kana sets have a special character, \jchar ã£, called sokuon (little tsu), a small version of the `tsu' (\kpth{tsu}) character, which is placed in front of the syllable which is to be geminated.
+This package detects correct usage of sokuon and represents it in Latin by doubling the respective consonant.
+In several romanization systems, gemination is represented by using `t' instead in all cases but I find the doubling of the affected consonant a better way to show the true nature of sokuon.
+
+\break\nm{4. Ambiguity of `n'}
+
+N is the only consonant in Japanese with its own kana character, \kpth{n}.
+As such, there is some ambiguity in following it by other characters.
+There are several syllables beginning in `n', such as nya (\kpth{nya}) or nyo (\kpth{nyo}), which could be ambiguously split into `n-ya' (\kpth{n'ya}) and `n-yo' (\kpth{n'yo}) respectively.
+To make sure there is no ambiguity in romanization of these characters, an isoLating delimiter is used: '. To demonstrate its usage, `nyaa' becomes \kptk{nyaa} in katakana but `n'yaa' becomes \kptk{n'yaa} --- ambiguity resolved.
+This works backwards too, where \kpth{ren'youkei} which contains the `nyo' syllable split to `n-yo' transliterates to \kptl{\toHiragana{ren'youkei}}.
+
+\nm{5. Transliteration alternatives}
+
+As expected with completely different writing systems, the conversion between them is not really isomorphic. Several syllables have multiple kana representations and several kana characters have multiple romanization options.
+To tackle this problem, this package tries to be as permissive as possible by letting the user configure alternatives on the go.
+The most frequent alternatives are selected by default and can be viewed in the kanaparser.tex file. There is a switch macro in the package that lets the user choose which kana character(s) will be used in place of the selected syllable if that syllable supports alternatives. There is always at most one alternative to a syllable representation.
+For example, if you wish that `we' is not written as \kptk{we} in katakana but instead as the obsolete \toggleChars{we}\kptk{we}, the package lets you do it.
+On the other hand, `sisi' and `shishi' will both transliterate to \kpth{sisi} although backwards transliteration will always be the closer-sounding \kptl{\toHiragana{sisi}}.
+Romanization of all the alternative kana characters is enabled by default.
+
+\nm{6. Transliterating mixed character sets and special characters}
+
+This package has limited support for this feature. Its three macros always attempt to transliterate as much as they can into the target character set. There is no option to only transliterate hiragana, for example. When targetting Latin, both kana sets will be converted. Same goes for transliterating to the kanas, both Latin and the other kana set will be converted.
+Characters not understood by the used macro (including ") will be left unchanged except for apostrophes ('), which will be consumed (and treated as isolation delimiters) when transLating to kana.
+
+\nm{7. Introducing romanization systems}
+
+There are several systems for romanization of Japanese and this package loosely follows the Hepburn system (\jchar{ヘボンå¼ãƒ­ãƒ¼ãƒžå­—}).
+The first difference is that the package ignores the characters with macron in long syllables (such as \jchar Å).
+This is to stay within the ASCII character set (which simplifies typing on a common keyboard) and lets newcomers to the language get used to the prolongation rules.
+As such, \kpth{koukou} transliterates to \kptl{\toHiragana{koukou}} instead of \jchar{kÅkÅ}.
+Contextual variations are also ignored in this package, such as writing \kpth{ha} as \jchar{wa} when used as a topic particle.
+Another notable deviation from Hepburn is not using `t' for consonant gemination except for syllables beginning in `t'. As such, \jchar{ã¾ã£ã¡ã‚ƒ} becomes \kptl{ã¾ã£ã¡ã‚ƒ} and not \jchar{matcha}.
+
+\nm{8. Fonts, unicode and implementation}
+
+Kana are multibyte unicode characters, a compatible font is needed to display any of them, hence the bundled macros won't print anything readable without a font with japanese support.
+An example of such font is the ipafont family.
+
+Both Lua and Lua\TeX \kern3pt support unicode characters although Lua only considers them multibyte strings. As such an UTF-8 tokenizer is needed to properly recognize individual characters.
+Once tokenized, conversion both to and from kana sets is possible using a state automaton with a processing buffer.
+
+When converting Latin to kana, a three-character buffer is needed to process characters such as `nya' (\kpth{nya}); the other way around only two-character is required to process multi-character compounds.
+Based on the contents of this buffer the automaton decides what to transliterate, prolong, geminate or print as-is. Conversion between kana sets is implemented as a simple translation table.
+
+\bye
diff --git a/macros/luatex/generic/kanaparser/examples.pdf b/macros/luatex/generic/kanaparser/examples.pdf
new file mode 100644
index 0000000000..2777a5c052
--- /dev/null
+++ b/macros/luatex/generic/kanaparser/examples.pdf
Binary files differ
diff --git a/macros/luatex/generic/kanaparser/examples.tex b/macros/luatex/generic/kanaparser/examples.tex
new file mode 100644
index 0000000000..6ab850c9ff
--- /dev/null
+++ b/macros/luatex/generic/kanaparser/examples.tex
@@ -0,0 +1,43 @@
+% This file shows various usage of this parser
+
+\input luaotfload.sty % otf font loader
+\input kanaparser % load the parser package
+
+\font\jp = ipagp % ipagp.otf font is included in the ipafont font package: https://www.internationalphoneticassociation.org/content/ipa-fonts
+
+\parserInit % initialize kana parser
+
+% wrapper macros that change font automatically
+\def\jchar#1{{\jp #1}}
+\def\kpth#1{\jchar{\toHiragana{#1}}}
+\def\kptk#1{\jchar{\toKatakana{#1}}}
+\def\kptl#1{\jchar{\toLatin{#1}}}
+
+Example of transliteration to Latin: \kptl{ã—ã‚…ã‚“ã‹ã—ã‚…ã†ã¨ã† ã—ã—}
+
+Example of transliteration to katakana featuring prolongation dashes: \kptk{ã—ã‚…ã‚“ã‹ã—ã‚…ã†ã¨ã† ã—ã—}
+
+Example of transliteration to hiragana converting prolongation dashes: \kpth{シュンカシュートー}
+
+Example of transliteration of multiple-form syllables to hiragana using default settings: \kpth{jiji wewe}
+
+\toggleChars{ji we} % toggles the kana representation of 'ji' and 'we' syllables
+Example of transliteration of multiple-form syllables to hiragana using alternate settings: \kpth{jiji wewe}
+
+Mixed example of transliteration to katakana: \kptk{shunkashuutouuuxxxxxchou}
+
+Example of default transliteration to hiragana using ambiguous syllables after n: \kpth{renyoukei}
+
+Example of isolated n-character to resolve ambiguity: \kpth{ren'youkkei}
+
+Example of hiragana to Latin transliteration from previous example: \kptl{れんよã†ã‘ã„}
+
+Example of consonant gemination from hiragana to Latin: \kptl{ã«ã£ã½ã‚“}
+
+Example of consonant gemination from Latin to hiragana: \kpth{nippon}
+
+Example of character preservation: \kptl{when transLating to Latin, ' and " are preserved}
+
+Example of character preservation 2: \kptl{\kpth{when transLating to kana, ' is consumed, " is preserved}}
+
+\bye
diff --git a/macros/luatex/generic/kanaparser/kanaparser.lua b/macros/luatex/generic/kanaparser/kanaparser.lua
new file mode 100644
index 0000000000..9034f0196e
--- /dev/null
+++ b/macros/luatex/generic/kanaparser/kanaparser.lua
@@ -0,0 +1,427 @@
+-- Kana Parser lua engine
+
+local vowels = {'a', 'e', 'i', 'o', 'u'} -- latin vowels
+local vowelsK = {'ア', 'エ', 'イ', 'オ', 'ウ'} -- katakana vowels
+local ambigousToN = {'ã‚', 'ãˆ', 'ã„', 'ãŠ', 'ã†', 'ã‚„', 'よ', 'ゆ'} -- characters ambiguous to preceding "n"
+local littleTsuWL = {'s', 't', 'k', 'p', 'c'} -- whitelist for little tsu gemination
+local transRaw = { -- latin -> hiragana
+ n = 'ã‚“', a = 'ã‚', e = 'ãˆ', i = 'ã„', o = 'ãŠ', u = 'ã†',
+ ba = 'ã°', be = 'ã¹', bi = 'ã³', bo = 'ã¼', bu = 'ã¶',
+ bya = 'ã³ã‚ƒ', byo = 'ã³ã‚‡', byu = 'ã³ã‚…',
+ cha = 'ã¡ã‚ƒ', che = 'ã¡ã‡', chi = 'ã¡', cho = 'ã¡ã‚‡', chu = 'ã¡ã‚…',
+ da = 'ã ', de = 'ã§', di = 'ã§ãƒ', ['do'] = 'ã©', du = { 'ã¥', 'ã©ã…' },
+ dya = 'ã§ã‚ƒ', dyo = 'ã§ã‚‡', dyu = 'ã§ã‚…',
+ fa = 'ãµã', fe = 'ãµã‡', fi = 'ãµãƒ', fo = 'ãµã‰',
+ fya = 'ãµã‚ƒ', fyo = 'ãµã‚‡', fyu = 'ãµã‚…',
+ ga = 'ãŒ', ge = 'ã’', gi = 'ãŽ', go = 'ã”', gu = 'ã',
+ gwa = 'ãã', gwe = 'ãã‡', gwi = 'ããƒ', gwo = 'ãã‰', gya = 'ãŽã‚ƒ', gyo = 'ãŽã‚‡', gyu = 'ãŽã‚…',
+ ha = 'ã¯', he = 'ã¸', hi = 'ã²', ho = 'ã»', hu = 'ãµ',
+ hya = 'ã²ã‚ƒ', hyo = 'ã²ã‚‡', hyu = 'ã²ã‚…',
+ ja = { 'ã˜ã‚ƒ', 'ã¢ã‚ƒ' }, je = 'ã˜ã‡', ji = { 'ã˜', 'ã¢' }, jo = { 'ã˜ã‚‡', 'ã¢ã‚‡' }, ju = { 'ã˜ã‚…', 'ã¢ã‚…' },
+ ka = 'ã‹', ke = 'ã‘', ki = 'ã', ko = 'ã“', ku = 'ã',
+ kwa = 'ãã', kwe = 'ãã‡', kwi = 'ããƒ', kwo = 'ãã‰', kya = 'ãゃ', kyo = 'ãょ', kyu = 'ãã‚…',
+ ma = 'ã¾', me = 'ã‚', mi = 'ã¿', mo = 'ã‚‚', mu = 'ã‚€',
+ mya = 'ã¿ã‚ƒ', myo = 'ã¿ã‚‡', myu = 'ã¿ã‚…',
+ na = 'ãª', ne = 'ã­', ni = 'ã«', no = 'ã®', nu = 'ã¬',
+ nya = 'ã«ã‚ƒ', nyo = 'ã«ã‚‡', nyu = 'ã«ã‚…',
+ pa = 'ã±', pe = 'ãº', pi = 'ã´', po = 'ã½', pu = 'ã·',
+ pya = 'ã´ã‚ƒ', pyo = 'ã´ã‚‡', pyu = 'ã´ã‚…',
+ ra = 'ら', re = 'ã‚Œ', ri = 'ã‚Š', ro = 'ã‚', ru = 'ã‚‹',
+ rya = 'りゃ', ryo = 'りょ', ryu = 'りゅ',
+ sa = 'ã•', se = 'ã›', si = 'ã—', so = 'ã', su = 'ã™',
+ sha = 'ã—ゃ', she = 'ã—ã‡', shi = 'ã—', sho = 'ã—ょ', shu = 'ã—ã‚…',
+ ta = 'ãŸ', te = 'ã¦', ti = 'ã¦ãƒ', to = 'ã¨',
+ tha = 'ã¦ã‚ƒ', tho = 'ã¦ã‚‡', thu = 'ã¦ã‚…',
+ tsa = 'ã¤ã', tse = 'ã¤ã‡', tsu = 'ã¤', tsi = 'ã¤ãƒ', tso = 'ã¤ã‰',
+ tu = 'ã¤',
+ va = 'ã‚”ã', ve = 'ã‚”ã‡', vi = 'ã‚”ãƒ', vo = 'ã‚”ã‰', vu = 'ã‚”ã…',
+ vya = 'ゔゃ', vyo = 'ゔょ', vyu = 'ゔゅ',
+ wa = 'ã‚', we = { 'ã†ã‡', 'ã‚‘' }, wi = 'ã‚', wo = { 'ã‚’', 'ã†ã‰' },
+ ya = 'ã‚„', ye = 'ã„ã‡', yo = 'よ', yu = 'ゆ',
+ za = 'ã–', ze = 'ãœ', zo = 'ãž', zu = 'ãš'
+}
+local transK = { -- hiragana -> katakana
+ ['ã‚“'] = 'ン', ['ã‚'] = 'ã‚¢', ['ãˆ'] = 'エ', ['ã„'] = 'イ', ['ãŠ'] = 'オ', ['ã†'] = 'ウ',
+ ['ã'] = 'ã‚¡', ['ãƒ'] = 'ã‚£', ['ã…'] = 'ã‚¥', ['ã‡'] = 'ェ', ['ã‰'] = 'ã‚©',
+ ['ゃ'] = 'ャ', ['ゅ'] = 'ュ', ['ょ'] = 'ョ',
+ ['ã¯'] = 'ãƒ', ['ã¸'] = 'ヘ', ['ã²'] = 'ヒ', ['ã»'] = 'ホ', ['ãµ'] = 'フ',
+ ['ã°'] = 'ãƒ', ['ã¹'] = 'ベ', ['ã³'] = 'ビ', ['ã¼'] = 'ボ', ['ã¶'] = 'ブ',
+ ['ã±'] = 'パ', ['ãº'] = 'ペ', ['ã´'] = 'ピ', ['ã½'] = 'ãƒ', ['ã·'] = 'プ',
+ ['ãŸ'] = 'ã‚¿', ['ã¦'] = 'テ', ['ã¡'] = 'ãƒ', ['ã¨'] = 'ト', ['ã¤'] = 'ツ',
+ ['ã '] = 'ダ', ['ã§'] = 'デ', ['ã¢'] = 'ヂ', ['ã©'] = 'ド', ['ã¥'] = 'ヅ',
+ ['ã‹'] = 'ã‚«', ['ã‘'] = 'ケ', ['ã'] = 'ã‚­', ['ã“'] = 'コ', ['ã'] = 'ク',
+ ['ãŒ'] = 'ガ', ['ã’'] = 'ゲ', ['ãŽ'] = 'ã‚®', ['ã”'] = 'ã‚´', ['ã'] = 'ã‚°',
+ ['ã¾'] = 'マ', ['ã‚'] = 'マ', ['ã¿'] = 'マ', ['ã‚‚'] = 'モ', ['ã‚€'] = 'マ',
+ ['ãª'] = 'ナ', ['ã­'] = 'ãƒ', ['ã«'] = 'ニ', ['ã®'] = 'ノ', ['ã¬'] = 'ヌ',
+ ['ら'] = 'ラ', ['ã‚Œ'] = 'レ', ['ã‚Š'] = 'リ', ['ã‚'] = 'ロ', ['ã‚‹'] = 'ル',
+ ['ã•'] = 'サ', ['ã›'] = 'ã‚»', ['ã—'] = 'ã‚·', ['ã'] = 'ソ', ['ã™'] = 'ス',
+ ['ã–'] = 'ザ', ['ãœ'] = 'ゼ', ['ã˜'] = 'ジ', ['ãž'] = 'ゾ', ['ãš'] = 'ズ',
+ ['ã‚'] = 'ワ', ['ã‚‘'] = 'ヱ', ['ã‚'] = 'ヰ', ['ã‚’'] = 'ヲ',
+ ['や'] = 'ヤ', ['よ'] = 'ヨ', ['ゆ'] = 'ユ',
+ ['ã‚”'] = 'ヴ', ['ã£'] = 'ッ'
+}
+local correctionsFromKana = { -- manual transliteration choices
+ ['ã—'] = 'shi'
+}
+local longK = 'ー'
+local isolator = '\''
+local prolongRules = { -- special rules for prolonging syllables
+ o = 'u',
+ e = 'i'
+}
+
+-- builds a reverse table
+local function rev(t)
+ local res = {}
+ for k, v in pairs(t) do
+ if (type(v) == 'table') then
+ res[v[1]] = k
+ res[v[2]] = k
+ else
+ res[v] = k
+ end
+ end
+ return res
+end
+
+-- builds the default translation tables latin <-> kana from transRaw
+local function buildDefaultTransTables()
+ local tr, rtr = {}, {}
+
+ for k, v in pairs(transRaw) do
+ tr[k] = type(v) == 'table' and v[1] or v
+ end
+
+ rtr = rev(tr)
+
+ -- apply corrections
+ for i, v in pairs(correctionsFromKana) do
+ rtr[i] = v
+ end
+
+ return tr, rtr, rev(transK)
+end
+
+-- decides which wovel should prolong the given vowel
+local function prolong(c)
+ for i, v in ipairs(vowels) do
+ if c == v then
+ if prolongRules[c] then return prolongRules[c] else return c end
+ end
+ end
+ return nil
+end
+
+-- checks if a katakana token is a vowel and returns its latin representation
+local function getWovelK(c)
+ for i, v in ipairs(vowelsK) do
+ if c == v then return vowels[i] end
+ end
+ return nil
+end
+
+-- checks if a given symbol is ambiguous to preceding n
+local function isAmbiguous(c)
+ for i, v in ipairs(ambigousToN) do
+ if c == v then return true end
+ end
+ return false
+end
+
+-- init translation tables
+local trans, revTrans, revTransK = buildDefaultTransTables()
+
+-- init default transliteration choices (everything default to first alternative)
+local transChoices = {}
+
+-- checks if two characters are valid candidates for little tsu
+local function isValidTsuCandidate(a, b)
+ if a ~= b then return false end
+ for i, v in ipairs(littleTsuWL) do
+ if a == v then return true end
+ end
+ return false
+end
+
+-- checks if two characters are a little tsu used correctly and returns the gemination consonant if true
+local function getGeminationConsonant(a, b)
+ if a ~= 'ã£' then return nil end -- disregard katakana, only hiragana is processed in romanization
+ local tr = revTrans[b]
+ if not tr then return nil end -- invalid hiragana character
+ local fst = string.sub(tr, 1, 1) -- get first character of the transliteration
+ for i, v in ipairs(littleTsuWL) do
+ if fst == v then return fst end
+ end
+ return nil -- invalid gemination
+end
+
+-- parses an utf8 string into utf8 chars (tokens)
+local function tokenize(utf8str)
+ assert(type(utf8str) == 'string')
+ local res, seq, val = {}, 0, ''
+ for i = 1, #utf8str do
+ local c = string.byte(utf8str, i)
+ if seq == 0 then
+ if i ~= 1 then table.insert(res, val) end
+ seq = c < 0x80 and 1 or c < 0xE0 and 2 or c < 0xF0 and 3 or
+ c < 0xF8 and 4 or error('invalid UTF-8 character sequence')
+ val = string.char(c)
+ else
+ val = val .. string.char(c)
+ end
+ seq = seq - 1
+ end
+ table.insert(res, val)
+ return res
+end
+
+-- PUBLIC API SECTION
+
+-- toggles used characters for supplied syllables (whitespace-separated)
+function toggleChars(input)
+ local cur, choices = '', {}
+ for s in string.gmatch(input, '%S+') do -- split by whitespaces
+ cur = trans[s]
+ if cur then -- don't process unknown syllables
+ choices = transRaw[s]
+ if type(choices) == 'table' then -- only process syllables with alternatives
+ trans[s] = cur == choices[1] and choices[2] or choices[1] -- toggle between alternatives
+ end
+ end
+ end
+end
+
+-- any kana to latin
+function toLatin(input)
+ if input == '' then return end
+ local tbl = tokenize(input)
+ local buffer, res = {}, ''
+
+ -- read tokenized input
+ local tjoin, tfst, last, gc = '', '', 0, '' -- last is the last valid transliterated vowel, gc is the last gemination consonant
+ for i, v in ipairs(tbl) do
+ if revTransK[v] ~= nil then v = revTransK[v] end -- convert all katakana to hiragana
+ table.insert(buffer, v)
+
+ if #buffer == 2 then -- kana can be formed with up to two characters, always keep two in buffer
+ tjoin, tfst, gc = revTrans[ buffer[1] .. buffer[2] ], revTrans[ buffer[1] ], getGeminationConsonant(buffer[1], buffer[2])
+ if tjoin ~= nil then -- double character
+ res = res .. tjoin
+ buffer, last = {}, string.sub(tjoin, -1)
+ elseif gc then -- check for little tsu
+ res = res .. gc
+ buffer, last = {buffer[2]}, 0
+ elseif tfst ~= nil then -- single character
+ res = res .. tfst
+ if tfst == 'n' and isAmbiguous(buffer[2]) then -- ambiguous character succeeding an "n"
+ res = res .. isolator
+ end
+ buffer, last = {buffer[2]}, string.sub(tfst, -1)
+ elseif buffer[1] == longK and prolong(last) ~= nil then -- prolonging dash
+ res = res .. prolong(last)
+ buffer, last = {buffer[2]}, 0
+ else -- cannot transliterate, output as-is
+ res = res .. buffer[1]
+ buffer, last = {buffer[2]}, 0
+ end
+ end
+ end
+
+ if #buffer == 1 then -- trailing character
+ if revTrans[ buffer[1] ] ~= nil then -- single character
+ res = res .. revTrans [ buffer[1] ]
+ elseif buffer[1] == longK and prolong(last) ~= nil then -- prolonging dash
+ res = res .. prolong(last)
+ else -- cannot transliterate, output as-is
+ res = res .. buffer[1]
+ end
+ end
+
+ tex.print(res)
+end
+
+-- latin or katakana to hiragana, 'raw' parameter is for internal use, leave it blank to get output to TeX
+function toHiragana(input, raw)
+ if input == '' then return end
+ local tbl = tokenize(input)
+ local buffer, res = {}, ''
+ local t3, t2, t1, last, lastsym, lastcnd = '', '', '', 0, nil, nil
+
+ for i, v in ipairs(tbl) do
+ if revTransK[v] then v = revTransK[v] end -- translate katakana to hiragana on the go
+ table.insert(buffer, v)
+
+ if #buffer == 3 then
+ t3, t2, t1 = trans[ buffer[1] .. buffer[2] .. buffer[3] ], trans[ buffer[1] .. buffer[2] ], trans[ buffer[1] ]
+ if t3 ~= nil then -- all three letters yield translation
+ if lastcnd then -- add little tsu
+ res = res .. 'ã£'
+ lastcnd = nil
+ end
+ res = res .. t3
+ last = buffer[3]
+ buffer = {}
+ elseif t2 ~= nil then -- first two letters yield translation
+ if lastcnd then -- add little tsu
+ res = res .. 'ã£'
+ lastcnd = nil
+ end
+ res = res .. t2
+ last = buffer[2]
+ buffer = {buffer[3]}
+ elseif isValidTsuCandidate(buffer[1], buffer[2]) then -- test little tsu candidates
+ if lastcnd then res = res .. lastcnd end -- add last consonant in raw form
+ lastcnd = buffer[1] -- set last candidate consonant
+ last = 0 -- is not vowel
+ buffer = {buffer[2], buffer[3]}
+ elseif t1 ~= nil then -- first letter yields translation : a, e, i, o, u, n
+ res = res .. t1
+ last = buffer[1]
+ buffer = {buffer[2], buffer[3]}
+ elseif buffer[1] == longK and prolong(last) ~= nil then -- valid prolonger sign
+ res = res .. trans[prolong(last)]
+ buffer, last = {buffer[2], buffer[3]}, 0
+ elseif buffer[1] == isolator then -- isolating apostrophe, consume it
+ buffer = {buffer[2], buffer[3]}
+ else
+ if lastcnd then -- add last consonant in raw form
+ res = res .. lastcnd
+ lastcnd = nil
+ end
+
+ -- this code allows for proper conversion of katakana's prolongation dash to hiragana
+ t1 = revTrans[ buffer[1] ]
+ if t1 then -- symbol is standalone hiragana
+ last = string.sub(t1, -1)
+ lastsym = buffer[1]
+ elseif lastsym then -- attempt to merge symbol with previous symbol
+ t1 = revTrans[ lastsym .. buffer[1] ]
+ if t1 then -- symbol is a valid non-standalone hiragana compound
+ last = string.sub(t1, -1)
+ else -- symbol is an invalid non-standalone hiragana compound
+ last = nil
+ end
+ lastsym = nil
+ else
+ last, lastsym = 0, nil
+ end
+
+ res = res .. buffer[1]
+ buffer = {buffer[2], buffer[3]}
+ end
+ end
+ end
+
+ if #buffer == 2 then
+ if trans[ buffer[1] .. buffer[2] ] ~= nil then -- first two symbols yield translation
+ if lastcnd then res = res .. 'ã£' end -- add little tsu
+ res = res .. trans[ buffer[1] .. buffer[2] ]
+ last = buffer[2]
+ buffer = {}
+ elseif trans[ buffer[1] ] ~= nil then -- first symbol yields translation
+ res = res .. trans[ buffer[1] ]
+ last = buffer[1]
+ buffer = {buffer[2]}
+ elseif buffer[1] == longK and prolong(last) ~= nil then -- valid prolonger
+ res = res .. trans[prolong(last)]
+ buffer, last = {buffer[2]}, 0
+ elseif buffer[1] == isolator then -- consume isolator
+ buffer = {buffer[2]}
+ else
+ if lastcnd then res = res .. lastcnd end -- add last consonant in raw form
+
+ -- this code allows for proper conversion of katakana's prolongation dash to hiragana
+ t1 = revTrans[ buffer[1] ]
+ if t1 then -- symbol is standalone hiragana
+ last = string.sub(t1, -1)
+ lastsym = buffer[1]
+ elseif lastsym then -- attempt to merge symbol with previous symbol
+ t1 = revTrans[ lastsym .. buffer[1] ]
+ if t1 then -- symbol is a valid non-standalone hiragana compound
+ last = string.sub(t1, -1)
+ else -- symbol is an invalid non-standalone hiragana compound
+ last = nil
+ end
+ lastsym = nil -- erase last valid symbol
+ else
+ last, lastsym = 0, nil
+ end
+
+ res = res .. buffer[1]
+ buffer = {buffer[2]}
+ end
+ end
+
+ if #buffer == 1 then -- remaining symbol
+ if trans[ buffer[1] ] ~= nil then
+ res = res .. trans[ buffer[1] ]
+ elseif buffer[1] == longK and prolong(last) ~= nil then
+ res = res .. trans[prolong(last)]
+ elseif buffer[1] ~= isolator then
+ res = res .. buffer[1]
+ end
+ end
+
+ if not raw then
+ tex.print(res)
+ else
+ return res -- for internal use
+ end
+end
+
+-- latin or hiragana to katakana
+function toKatakana(input)
+ if input == '' then return end
+ local hiraganized = tokenize(toHiragana(input, true)) -- convert everything to hiragana
+
+ -- replace hiragana with katakana
+ for i, v in ipairs(hiraganized) do
+ if transK[v] ~= nil then
+ hiraganized[i] = transK[v]
+ end
+ end
+
+ -- insert prolonging symbols and prepare output
+ local prev, nxt, vowel, tprev, tnext, res = hiraganized[1], '', '', '', '', hiraganized[1]
+ local merge, toprolong = '', nil
+ for i = 2, #hiraganized do
+ nxt = hiraganized[i]
+
+ vowel = getWovelK(nxt)
+
+ if not toprolong then -- check prev for ending vowel
+ tprev = revTransK[prev]
+ if tprev then
+ tprev = revTrans[tprev]
+ if tprev then
+ toprolong = prolong(string.sub(tprev, -1))
+ end
+ end
+ end
+
+ if toprolong then -- check nxt for matching prolonger
+ if toprolong == vowel then
+ nxt = longK
+ toprolong = nil
+ elseif vowel then
+ toprolong = prolong(vowel)
+ else
+ toprolong = nil
+ end
+ end
+
+ -- try merging prev and nxt for a single token
+ tprev, tnext = revTransK[prev], revTransK[nxt]
+ if tprev and tnext then
+ merge = revTrans[tprev .. tnext]
+ if merge then
+ toprolong = prolong(string.sub(merge, -1))
+ end
+ end
+
+ res = res .. nxt
+ prev = nxt
+ end
+
+ tex.print(res)
+end
diff --git a/macros/luatex/generic/kanaparser/kanaparser.tex b/macros/luatex/generic/kanaparser/kanaparser.tex
new file mode 100644
index 0000000000..183a02cfd7
--- /dev/null
+++ b/macros/luatex/generic/kanaparser/kanaparser.tex
@@ -0,0 +1,25 @@
+% Kana Parser for LuaTeX
+% Author: Adam Zahumensky, FIT CVUT
+
+% initializer macro, use it before using any other macros in this package
+\def\parserInit{ \directlua{ dofile('kanaparser.lua') } }
+
+% supply a whitespace-separated list of syllables whose kana characters you'd like to toggle
+% list of supported alternatives ([] denotes default choice):
+% du : [ã¥], ã©ã…
+% ja : [ã˜ã‚ƒ], ã¢ã‚ƒ
+% ji : [ã˜], ã¢
+% jo : [ã˜ã‚‡], ã¢ã‚‡
+% ju : [ã˜ã‚…], ã¢ã‚…
+% we : [ã†ã‡], ã‚‘
+% wo : [ã‚’], ã†ã‰
+\def\toggleChars#1{\directlua{ toggleChars("\luatexluaescapestring{#1}") }}
+
+% convert all kana to latin
+\long\def\toLatin#1{\directlua{ toLatin("\luatexluaescapestring{#1}") }}
+
+% convert latin and katakana to hiragana
+\long\def\toHiragana#1{\directlua{ toHiragana("\luatexluaescapestring{#1}") }}
+
+% convert latin and hiragana to katakana
+\long\def\toKatakana#1{\directlua{ toKatakana("\luatexluaescapestring{#1}") }} \ No newline at end of file
diff --git a/macros/luatex/generic/lua-visual-debug/README.md b/macros/luatex/generic/lua-visual-debug/README.md
new file mode 120000
index 0000000000..fd42db32e3
--- /dev/null
+++ b/macros/luatex/generic/lua-visual-debug/README.md
@@ -0,0 +1 @@
+doc/README.md \ No newline at end of file
diff --git a/macros/luatex/generic/lua-visual-debug/doc/README.md b/macros/luatex/generic/lua-visual-debug/doc/README.md
new file mode 100644
index 0000000000..a45bbcb16e
--- /dev/null
+++ b/macros/luatex/generic/lua-visual-debug/doc/README.md
@@ -0,0 +1,37 @@
+Visual debugging for LuaTeX
+===========================
+
+The LuaTeX package `lua-visual-debug` shows boxes, glues, kerns and penalties in the PDF output.
+
+Usage:
+
+LaTeX:
+
+ \usepackage{lua-visual-debug}
+
+or (plain)
+
+ \input lua-visual-debug.sty
+
+
+
+Requirements: The package has only been tested with LuaTeX and
+ the formats plain and LaTeX. Other formats might work as well,
+ but other engines only show a warning message.
+
+
+Copyright 2012–2019 Patrick Gundlach (<patrick@gundla.ch>) and others (see Git information)
+
+Package version: 0.7
+
+Public repository: <https://github.com/pgundlach/lvdebug>
+
+Licensed under the MIT license. See the Lua file for details.
+
+The idea is heavily inspired by Hans Hagen's <http://pragma-ade.com/articles/art-visi.pdf>
+
+
+Example output
+--------------
+
+<p align="center"><img width="300px" src="https://i.imgur.com/S78jTxb.png"></p>
diff --git a/macros/luatex/generic/lua-visual-debug/doc/lvdebug-doc.pdf b/macros/luatex/generic/lua-visual-debug/doc/lvdebug-doc.pdf
new file mode 100644
index 0000000000..71b2936a29
--- /dev/null
+++ b/macros/luatex/generic/lua-visual-debug/doc/lvdebug-doc.pdf
Binary files differ
diff --git a/macros/luatex/generic/lua-visual-debug/doc/lvdebug-doc.tex b/macros/luatex/generic/lua-visual-debug/doc/lvdebug-doc.tex
new file mode 100644
index 0000000000..c87c2b49a4
--- /dev/null
+++ b/macros/luatex/generic/lua-visual-debug/doc/lvdebug-doc.tex
@@ -0,0 +1,70 @@
+\documentclass{article}
+\usepackage{graphicx,listings,lmodern,luatextra}
+\newcommand\pkgversion{0.7}
+
+\newcommand*\pgsmall{\fontsize{8.5}{8.7}\selectfont\ttfamily}
+\lstset{basicstyle=\pgsmall,
+ basewidth=0.55em,
+ columns=fullflexible,
+ breakautoindent=true,
+ breaklines=true,
+ prebreak=,
+ postbreak=\mbox{$\hookrightarrow$},
+}
+
+\begin{document}
+\title{The lua-visual-debug package (V\pkgversion)}
+\author{Patrick Gundlach}
+% \address{patrick@gundla.ch}
+\maketitle
+
+\tableofcontents
+\section{About}
+
+This package aids debugging your \TeX\ and \LaTeX\ document by drawing rectangles around boxes and rules where glue is inserted. Other items are marked as well: kerns, hyphenation points and penalties.
+
+\section{How to use}
+
+When you load the package \texttt{lua-visual-debug} in your \LuaLaTeX\ document (or use \verb|\input lua-visual-debug.sty| in plain \TeX), \LuaTeX\ will highlight boxes, penalties, glues and kerns in the PDF. This package requires you to process the document with \LuaTeX\ (plain and \LaTeX formats).
+
+\section{A \LaTeX\ example}
+\lstinputlisting[language=tex]{sample.tex}
+
+\noindent yields \vspace{5mm}
+
+\noindent \includegraphics[width=\textwidth]{sample-crop.pdf}
+
+\section{A plain \TeX\ example}
+
+\lstinputlisting[language=tex]{sample-plain.tex}
+
+\noindent yields \vspace{5mm}
+
+\noindent \includegraphics{sample-plain-crop.pdf}
+
+\section{How to interpret the markers} % (fold)
+\label{sec:how_to_interpret_the_markers}
+
+\noindent\includegraphics[width=.9\textwidth]{lvdebugdetail1-num}
+\begin{enumerate}
+ \item A vertical glue. Beginning and end are marked with a small tick. At the mark 1, two vertical glues are connected.
+\item A horizontal glue.
+\item A negative kern. Positive kerns are yellow.
+\item A possible hyphenation point.
+\item Horizontal and vertical boxes are drawn with a border.
+\item Penalties are marked with a square. A penalty of 10,000 is marked with a blank square, a penalty less than 10,000 is filled with a gray square (that will improve in the future, currently it is grayness of penalty / 10000).
+\end{enumerate}
+
+A strut box (zero width box) is marked with a red rule:
+
+\noindent\includegraphics[scale=0.8]{strut}
+
+% section how_to_interpret_the_ (end)
+
+
+\section{Copying}
+
+Copyright 2012–2019 Patrick Gundlach (patrick@gundla.ch) and other authors (see Git for information), licensed under the MIT license. See the Lua file for details.
+
+
+\end{document}
diff --git a/macros/luatex/generic/lua-visual-debug/doc/lvdebugdetail1-num.png b/macros/luatex/generic/lua-visual-debug/doc/lvdebugdetail1-num.png
new file mode 100644
index 0000000000..4c5fa553f8
--- /dev/null
+++ b/macros/luatex/generic/lua-visual-debug/doc/lvdebugdetail1-num.png
Binary files differ
diff --git a/macros/luatex/generic/lua-visual-debug/doc/sample-plain.pdf b/macros/luatex/generic/lua-visual-debug/doc/sample-plain.pdf
new file mode 100644
index 0000000000..2aaafad75f
--- /dev/null
+++ b/macros/luatex/generic/lua-visual-debug/doc/sample-plain.pdf
Binary files differ
diff --git a/macros/luatex/generic/lua-visual-debug/doc/sample-plain.tex b/macros/luatex/generic/lua-visual-debug/doc/sample-plain.tex
new file mode 100644
index 0000000000..da1e423238
--- /dev/null
+++ b/macros/luatex/generic/lua-visual-debug/doc/sample-plain.tex
@@ -0,0 +1,16 @@
+\input lua-visual-debug.sty
+
+\hsize 3in \vsize 3in
+\centerline{A centered line with \TeX}
+
+\vskip .5in
+
+A wonderful serenity has taken possession of my entire soul, like these sweet
+mornings of spring which I enjoy with my whole heart. I am alone, and feel
+the charm of existence in this spot, which was created for the bliss of souls
+like mine. I am so happy, my dear friend, so absorbed in the exquisite sense
+of mere tranquil existence, that I neglect my talents.
+
+$$\int_e^x=mc^2$$
+
+\bye
diff --git a/macros/luatex/generic/lua-visual-debug/doc/sample.pdf b/macros/luatex/generic/lua-visual-debug/doc/sample.pdf
new file mode 100644
index 0000000000..81cf4fc223
--- /dev/null
+++ b/macros/luatex/generic/lua-visual-debug/doc/sample.pdf
Binary files differ
diff --git a/macros/luatex/generic/lua-visual-debug/doc/sample.tex b/macros/luatex/generic/lua-visual-debug/doc/sample.tex
new file mode 100644
index 0000000000..aa9fbf1412
--- /dev/null
+++ b/macros/luatex/generic/lua-visual-debug/doc/sample.tex
@@ -0,0 +1,32 @@
+\documentclass{article}
+\usepackage{lua-visual-debug}
+
+\usepackage{lmodern}
+\setlength\textwidth{300pt}
+\setlength\textheight{10cm}
+
+\begin{document}
+
+\section{A short story}
+
+A wonderful serenity has taken possession of my entire soul, like these sweet
+mornings of spring which I enjoy with my whole heart. I am alone, and feel
+the charm of existence in this spot, which was created for the bliss of souls
+like mine. I am so happy, my dear friend, so absorbed in the exquisite sense
+of mere tranquil existence, that I neglect my talents\footnote{A very special note for you}.
+
+\begin{itemize}
+ \item one
+ \item two
+ \item three
+\end{itemize}
+
+\bgroup\fontsize{30}{34}\selectfont
+\centerline{\TeX}
+\egroup
+
+\vbox{\strut Hello}\kern .5cm\vbox{\strut World}
+
+\[ \int_e^x=mc^2 \]
+
+\end{document}
diff --git a/macros/luatex/generic/lua-visual-debug/doc/strut.png b/macros/luatex/generic/lua-visual-debug/doc/strut.png
new file mode 100644
index 0000000000..c7cd0176af
--- /dev/null
+++ b/macros/luatex/generic/lua-visual-debug/doc/strut.png
Binary files differ
diff --git a/macros/luatex/generic/lua-visual-debug/lua-visual-debug.lua b/macros/luatex/generic/lua-visual-debug/lua-visual-debug.lua
new file mode 100644
index 0000000000..b6fb5907c9
--- /dev/null
+++ b/macros/luatex/generic/lua-visual-debug/lua-visual-debug.lua
@@ -0,0 +1,160 @@
+-- Copyright 2012-2019 Patrick Gundlach, patrick@gundla.ch
+-- Public repository: https://github.com/pgundlach/lvdebug (issues/pull requests,...)
+-- Version: 0.7
+
+-- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
+-- "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
+-- publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
+-- so, subject to the following conditions:
+--
+-- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+-- FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+-- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+module(...,package.seeall)
+
+-- There are 65782 scaled points in a PDF point
+-- Therefore we need to divide all TeX lengths by
+-- this amount to get the PDF points.
+local number_sp_in_a_pdf_point = 65782
+
+
+-- The idea is the following: at page shipout, all elements on a page are fixed.
+-- TeX creates an intermediate data structure before putting that into the PDF
+-- We can "intercept" that data structure and add pdf_literal (whatist) nodes,
+-- that makes glues, kerns and other items visible by drawing a rule, rectangle or
+-- other visual aids.
+-- This has no influence on typeset material, because these pdf_literal instructions
+-- are only visible to the PDF file (PDF renderer) and have no size themselves.
+
+-- We recursively loop through the contents of boxes and look at the (linear) list of
+-- items in that box. We start at the "shipout box".
+
+-- The "algorithm" goes like this:
+--
+-- head = pointer_to_beginning_of_box_material
+-- while head is not nil
+-- if this_item_is_a_box
+-- recurse_into_contents
+-- draw a rectangle around the contents
+-- elseif this_item_is_a_glue
+-- draw a rule that has the length of that glue
+-- elseif this_item_is_a_kern
+-- draw a rectangle with width of that kern
+-- ...
+-- end
+-- move pointer to the next item in the list
+-- -- the pointer is "nil" if there is no next item
+-- end
+
+local HLIST = node.id("hlist")
+local VLIST = node.id("vlist")
+local RULE = node.id("rule")
+local DISC = node.id("disc")
+local GLUE = node.id("glue")
+local KERN = node.id("kern")
+local PENALTY = node.id("penalty")
+
+function math.round(num, idp)
+ if idp and idp>0 then
+ local mult = 10^idp
+ return math.floor(num * mult + 0.5) / mult
+ end
+ return math.floor(num + 0.5)
+end
+
+
+function show_page_elements(parent)
+ local head = parent.list
+ while head do
+ if head.id == HLIST or head.id == VLIST then
+
+ local rule_width = 0.1
+ local wd = math.round(head.width / number_sp_in_a_pdf_point - rule_width ,2)
+ local ht = math.round((head.height + head.depth) / number_sp_in_a_pdf_point - rule_width ,2)
+ local dp = math.round(head.depth / number_sp_in_a_pdf_point - rule_width / 2 ,2)
+
+ -- recurse into the contents of the box
+ show_page_elements(head)
+ local rectangle = node.new("whatsit","pdf_literal")
+ if head.id == HLIST then -- hbox
+ rectangle.data = string.format("q 0.5 G %g w %g %g %g %g re s Q", rule_width, -rule_width / 2, -dp, wd, ht)
+ else
+ rectangle.data = string.format("q 0.1 G %g w %g %g %g %g re s Q", rule_width, -rule_width / 2, 0, wd, -ht)
+ end
+ head.list = node.insert_before(head.list,head.list,rectangle)
+
+
+ elseif head.id == RULE then
+ local show_rule = node.new("whatsit","pdf_literal")
+ if head.width == -1073741824 or head.height == -1073741824 or head.depth == -1073741824 then
+ -- ignore for now -- these rules are stretchable
+ else
+ local dp = math.round( head.depth / number_sp_in_a_pdf_point ,2)
+ local ht = math.round( head.height / number_sp_in_a_pdf_point ,2)
+ show_rule.data = string.format("q 1 0 0 RG 1 0 0 rg 0.4 w 0 %g m 0 %g l S Q",-dp,ht)
+ end
+ parent.list = node.insert_before(parent.list,head,show_rule)
+
+
+ elseif head.id == DISC then
+ local hyphen_marker = node.new("whatsit","pdf_literal")
+ hyphen_marker.data = "q 0 0 1 RG 0.3 w 0 -1 m 0 0 l S Q"
+ parent.list = node.insert_before(parent.list,head,hyphen_marker)
+
+
+ elseif head.id == GLUE then
+ local head_spec = head.spec
+ if not head_spec then
+ head_spec = head
+ end
+ local wd = head_spec.width
+ local color = "0.5 G"
+ if parent.glue_sign == 1 and parent.glue_order == head_spec.stretch_order then
+ wd = wd + parent.glue_set * head_spec.stretch
+ color = "0 0 1 RG"
+ elseif parent.glue_sign == 2 and parent.glue_order == head_spec.shrink_order then
+ wd = wd - parent.glue_set * head_spec.shrink
+ color = "1 0 1 RG"
+ end
+ local pdfstring = node.new("whatsit","pdf_literal")
+ local wd_bp = math.round(wd / number_sp_in_a_pdf_point,2)
+ if parent.id == HLIST then
+ pdfstring.data = string.format("q %s [0.2] 0 d 0.5 w 0 0 m %g 0 l s Q",color,wd_bp)
+ else -- vlist
+ pdfstring.data = string.format("q 0.1 G 0.1 w -0.5 0 m 0.5 0 l -0.5 %g m 0.5 %g l s [0.2] 0 d 0.5 w 0.25 0 m 0.25 %g l s Q",-wd_bp,-wd_bp,-wd_bp)
+ end
+ parent.list = node.insert_before(parent.list,head,pdfstring)
+
+
+ elseif head.id == KERN then
+ local rectangle = node.new("whatsit","pdf_literal")
+ local color = "1 1 0 rg"
+ if head.kern < 0 then color = "1 0 0 rg" end
+ local k = math.round(head.kern / number_sp_in_a_pdf_point,2)
+ if parent.id == HLIST then
+ rectangle.data = string.format("q %s 0 w 0 0 %g 1 re B Q",color, k )
+ else
+ rectangle.data = string.format("q %s 0 w 0 0 1 %g re B Q",color, -k )
+ end
+ parent.list = node.insert_before(parent.list,head,rectangle)
+
+
+ elseif head.id == PENALTY then
+ local color = "1 g"
+ local rectangle = node.new("whatsit","pdf_literal")
+ if head.penalty < 10000 then
+ color = string.format("%d g", 1 - math.floor(head.penalty / 10000))
+ end
+ rectangle.data = string.format("q %s 0 w 0 0 1 1 re B Q",color)
+ parent.list = node.insert_before(parent.list,head,rectangle)
+ end
+ head = head.next
+ end
+ return true
+end
diff --git a/macros/luatex/generic/lua-visual-debug/lua-visual-debug.sty b/macros/luatex/generic/lua-visual-debug/lua-visual-debug.sty
new file mode 100644
index 0000000000..9d5b22337a
--- /dev/null
+++ b/macros/luatex/generic/lua-visual-debug/lua-visual-debug.sty
@@ -0,0 +1,37 @@
+% see lua file for copyright information (MIT License)
+
+\def\lvdebugpkgdate{2019/01/07}
+\def\lvdebugpkgversion{0.7}
+
+\ifx\ProvidesPackage\undefined
+ \input ifluatex.sty\relax
+\else
+ \NeedsTeXFormat{LaTeX2e}
+ \ProvidesPackage{lua-visual-debug}[\lvdebugpkgdate\space v\lvdebugpkgversion\space Visual debugging in LuaLaTeX (PGU)]
+ \RequirePackage{ifluatex}
+\fi
+
+\def\luavisualdebug@dothings{%
+ \directlua{ lvd = require("lua-visual-debug")}%
+ \AtBeginShipout {\directlua{lvd.show_page_elements(tex.box["AtBeginShipoutBox"])}}%
+}
+
+\ifx\ProvidesPackage\undefined
+ \ifluatex
+ \input atbegshi.sty\relax
+ \luavisualdebug@dothings
+ \AtBeginShipoutInit
+ \else
+ \message{Warning: lua-visual-debug only works with LuaTeX (plain and LaTeX format)}
+ \fi
+\else
+ \ifluatex
+ \RequirePackage{atbegshi}
+ \luavisualdebug@dothings
+ \else
+ \PackageWarning{lua-visual-debug}{You are using this package without LuaTeX. This is not supported, so you don't get any visual debugging.}
+ \fi
+\fi
+
+
+
diff --git a/macros/luatex/generic/lualibs/LICENSE b/macros/luatex/generic/lualibs/LICENSE
new file mode 100644
index 0000000000..d159169d10
--- /dev/null
+++ b/macros/luatex/generic/lualibs/LICENSE
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/macros/luatex/generic/lualibs/NEWS b/macros/luatex/generic/lualibs/NEWS
new file mode 100644
index 0000000000..66ee05e8cb
--- /dev/null
+++ b/macros/luatex/generic/lualibs/NEWS
@@ -0,0 +1,88 @@
+ History of the lualibs package
+2019/08/11 v2.67/
+ * sync with Context current as of 2019/08/11
+
+2019/07/04 v2.66/
+ * sync with Context current as of 2019/07/04
+ * changed kpse initialization to avoid conflicts with latex-dev format
+
+2019/05/18 v2.65/
+ * sync with Context current as of 2019/05/18
+
+2019/02/14 v2.64/
+ * sync with Context beta as of 2019/02/14
+
+2019/01/28 v2.63/
+ * sync with Context beta as of 2019/01/28
+
+2019/01/28 v2.62/
+ * sync with Context beta as of 2018/12/19
+
+2018/10/18 v2.61/
+ * sync with Context beta as of 2018-10-18
+
+2018/09/20 v2.6/
+ * sync with Context beta as of 2018-09-20
+
+
+2017/02/01 v2.5/
+ * sync with Context beta as of 2017-02-01
+
+2016/04/06 v2.4/
+ * sync with Context beta as of 2016-04-06
+ * basic maintenance
+ * include util-fil.lua, a fontloader requirement, in the extended
+ collection
+
+2015/12/02 v2.3/
+ * sync with Context beta as of 2015-11-19
+ * basic maintenance
+
+2014/05/05 v2.2/
+ * sync with Context beta as of 2014-07-26
+ * remove util-env.lua
+
+2013/31/03 v2.1a/
+ * sync with Context beta as of 2013-12-30
+
+2013/11/03 v2.1/
+ * sync with Context beta as of 2013-11-01
+ * add l-gzip
+
+2013/07/23 v2.0c/
+ * sync with Context beta as of 2013-07-14
+
+2013/05/18 v2.0/
+ * sync with Context beta as of 2013.04.29 20:30
+ * merge with mtx-package
+ * split in basic and extended collection, allowing for partial
+ loading
+ * include additional files from Context
+ * drop module() in favor of locals
+
+2012/10/19 v0.9/
+ * sync with ConTeXt beta 2012.10.17
+ * move some files to util-* prefix
+ * add util-sto util-lua util-sto util-jsn
+
+2011/01/20 v0.96
+ * Fix computability with lfs in luatex 0.65
+
+2010/06/28 v0.95
+ * don't use kpse.set_program_name(), people loading lualibs with texlua
+ should set it themselves, to avoid possible clashes
+ * drop deprecated functions and aliases
+ * update the documentation
+
+2010/05/28 v0.94
+ * sync with ConTeXt beta 2010.05.20, adding new functions used
+ by luaotfload
+
+2010/05/10 v0.93
+ * renamed the package from luaextra to lualibs
+ * now a separate package (previously part of the luatextra bundle)
+
+2010/01/10 v0.92
+ * making the file loadable without luatextra (useful for lua scripts)
+ * fixing typo in localize_sep
+
diff --git a/macros/luatex/generic/lualibs/README.md b/macros/luatex/generic/lualibs/README.md
new file mode 100644
index 0000000000..b89ca40fb7
--- /dev/null
+++ b/macros/luatex/generic/lualibs/README.md
@@ -0,0 +1,99 @@
+# The Lualibs Package
+
+VERSION: 2.67
+
+DATE: 2019-08-11
+
+Lualibs is a collection of Lua modules useful for general programming.
+
+This work is based on Lua modules shipped with ConTeXt, to make them available
+for use independent of ConTeXt.
+
+This package has been developed by the LuaLaTeX development team on
+<https://github.com/lualatex/lualibs>.
+
+The current version has been build by Ulrike Fischer on
+<https://github.com/u-fischer/lualibs>. The date equals the date of the context files.
+
+See the 'NEWS' file for version history.
+
+
+
+## Installation
+
+
+1. If you are using TeX Live 2010 or later use 'tlmgr install lualibs'.
+ With miktex, use the miktex console.
+ Alternatively, use your (TeX or Linux) distribution's package management
+ system.
+
+2.
+ 1. Grab lualibs.tds.zip on CTAN.
+ 2. Unzip it at the root of one or your TDS trees.
+ 3. You may need to update some filename database after this, see your TeX
+ distribution's manual for details.
+
+
+## Manifest
+
+### Source files:
+
+| file | TDS location
+|------------------------------------|-----------------------------------
+| lualibs.dtx |source/luatex/lualibs/lualibs.dtx
+| lualibs-boolean.lua |tex/luatex/lualibs/lualibs-boolean.lua
+| lualibs-compat.lua |tex/luatex/lualibs/lualibs-compat.lua
+| lualibs-dir.lua |tex/luatex/lualibs/lualibs-dir.lua
+| lualibs-file.lua | tex/luatex/lualibs/lualibs-file.lua
+| lualibs-gzip.lua | tex/luatex/lualibs/lualibs-gzip.lua
+| lualibs-function.lua | tex/luatex/lualibs/lualibs-function.lua
+| lualibs-io.lua | tex/luatex/lualibs/lualibs-io.lua
+| lualibs-lpeg.lua | tex/luatex/lualibs/lualibs-lpeg.lua
+| lualibs-lua.lua | tex/luatex/lualibs/lualibs-lua.lua
+| lualibs-math.lua | tex/luatex/lualibs/lualibs-math.lua
+| lualibs-md5.lua | tex/luatex/lualibs/lualibs-md5.lua
+| lualibs-number.lua | tex/luatex/lualibs/lualibs-number.lua
+| lualibs-os.lua | tex/luatex/lualibs/lualibs-os.lua
+| lualibs-package.lua | tex/luatex/lualibs/lualibs-package.lua
+| lualibs-set.lua | tex/luatex/lualibs/lualibs-set.lua
+| lualibs-string.lua | tex/luatex/lualibs/lualibs-string.lua
+| lualibs-table.lua | tex/luatex/lualibs/lualibs-table.lua
+| lualibs-trac-inf.lua | tex/luatex/lualibs/lualibs-trac-inf.lua
+| lualibs-unicode.lua\* | tex/luatex/lualibs/lualibs-unicode.lua
+| lualibs-url.lua | tex/luatex/lualibs/lualibs-url.lua
+| lualibs-util-deb.lua | tex/luatex/lualibs/lualibs-util-deb.lua
+| lualibs-util-dim.lua | tex/luatex/lualibs/lualibs-util-dim.lua
+| lualibs-util-jsn.lua | tex/luatex/lualibs/lualibs-util-jsn.lua
+| lualibs-util-lua.lua | tex/luatex/lualibs/lualibs-util-lua.lua
+| lualibs-util-prs.lua | tex/luatex/lualibs/lualibs-util-prs.lua
+| lualibs-util-sta.lua | tex/luatex/lualibs/lualibs-util-sta.lua
+| lualibs-util-sto.lua | tex/luatex/lualibs/lualibs-util-sto.lua
+| lualibs-util-str.lua | tex/luatex/lualibs/lualibs-util-str.lua
+| lualibs-util-tab.lua | tex/luatex/lualibs/lualibs-util-tab.lua
+| lualibs-util-tpl.lua | tex/luatex/lualibs/lualibs-util-tpl.lua
+| LICENSE | doc/luatex/lualibs/LICENSE
+| NEWS | doc/luatex/lualibs/NEWS
+| README | doc/luatex/lualibs/README
+
+\* the file has been modified to enable the unicode library again
+
+### Derived files:
+
+| file | TDS location
+|------------------------------------|-----------------------------------
+| lualibs.lua | tex/luatex/lualibs/lualibs.lua
+| lualibs-basic.lua | tex/luatex/lualibs/lualibs-basic.lua
+| lualibs-basic-merged.lua | tex/luatex/lualibs/lualibs-basic-merged.lua
+| lualibs-extended.lua | tex/luatex/lualibs/lualibs-extended.lua
+| lualibs-extended-merged.lua | tex/luatex/lualibs/lualibs-extended-merged.lua
+| lualibs.pdf | doc/luatex/lualibs/lualibs.pdf
+
+## License and Copyright
+
+As a derived work of Context, this work and the derived files are under the
+GNU GPL v.2.0 license.
+The full text of the license is included in the file LICENSE.
+
+The files taken from Context (lualibs-*.lua) are copyright PRAGMA ADE / ConTeXt
+Development Team.
+
diff --git a/macros/luatex/generic/lualibs/lualibs-basic-merged.lua b/macros/luatex/generic/lualibs/lualibs-basic-merged.lua
new file mode 100644
index 0000000000..0cb07cea2a
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-basic-merged.lua
@@ -0,0 +1,5640 @@
+-- merged file : lualibs-basic-merged.lua
+-- parent file : lualibs-basic.lua
+-- merge date : Tue Aug 13 20:13:08 2019
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-lua']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type,tonumber=next,type,tonumber
+LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
+LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
+LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
+LUAVERSION=LUAMAJORVERSION+LUAMINORVERSION/10
+if LUAVERSION<5.2 and jit then
+ MINORVERSION=2
+ LUAVERSION=5.2
+end
+if not lpeg then
+ lpeg=require("lpeg")
+end
+if loadstring then
+ local loadnormal=load
+ function load(first,...)
+ if type(first)=="string" then
+ return loadstring(first,...)
+ else
+ return loadnormal(first,...)
+ end
+ end
+else
+ loadstring=load
+end
+if not ipairs then
+ local function iterate(a,i)
+ i=i+1
+ local v=a[i]
+ if v~=nil then
+ return i,v
+ end
+ end
+ function ipairs(a)
+ return iterate,a,0
+ end
+end
+if not pairs then
+ function pairs(t)
+ return next,t
+ end
+end
+if not table.unpack then
+ table.unpack=_G.unpack
+elseif not unpack then
+ _G.unpack=table.unpack
+end
+if not package.loaders then
+ package.loaders=package.searchers
+end
+local print,select,tostring=print,select,tostring
+local inspectors={}
+function setinspector(kind,inspector)
+ inspectors[kind]=inspector
+end
+function inspect(...)
+ for s=1,select("#",...) do
+ local value=select(s,...)
+ if value==nil then
+ print("nil")
+ else
+ local done=false
+ local kind=type(value)
+ local inspector=inspectors[kind]
+ if inspector then
+ done=inspector(value)
+ if done then
+ break
+ end
+ end
+ for kind,inspector in next,inspectors do
+ done=inspector(value)
+ if done then
+ break
+ end
+ end
+ if not done then
+ print(tostring(value))
+ end
+ end
+ end
+end
+local dummy=function() end
+function optionalrequire(...)
+ local ok,result=xpcall(require,dummy,...)
+ if ok then
+ return result
+ end
+end
+if lua then
+ lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
+end
+local flush=io.flush
+if flush then
+ local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
+ local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
+ local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
+ local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
+end
+FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
+if not FFISUPPORTED then
+ local okay;okay,ffi=pcall(require,"ffi")
+ FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
+end
+if not FFISUPPORTED then
+ ffi=nil
+elseif not ffi.number then
+ ffi.number=tonumber
+end
+if LUAVERSION>5.3 then
+end
+if status and os.setenv then
+ os.setenv("engine",string.lower(status.luatex_engine or "unknown"))
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-package']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local type=type
+local gsub,format,find=string.gsub,string.format,string.find
+local insert,remove=table.insert,table.remove
+local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
+local package=package
+local searchers=package.searchers or package.loaders
+local filejoin=file and file.join or function(path,name) return path.."/"..name end
+local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
+local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
+local function cleanpath(path)
+ return path
+end
+local pattern=Cs((((1-S("\\/"))^0*(S("\\/")^1/"/"))^0*(P(".")^1/"/"+P(1))^1)*-1)
+local function lualibfile(name)
+ return lpegmatch(pattern,name) or name
+end
+local offset=luarocks and 1 or 0
+local helpers=package.helpers or {
+ cleanpath=cleanpath,
+ lualibfile=lualibfile,
+ trace=false,
+ report=function(...) print(format(...)) end,
+ builtin={
+ ["preload table"]=searchers[1+offset],
+ ["path specification"]=searchers[2+offset],
+ ["cpath specification"]=searchers[3+offset],
+ ["all in one fallback"]=searchers[4+offset],
+ },
+ methods={},
+ sequence={
+ "already loaded",
+ "preload table",
+ "qualified path",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
+ }
+}
+package.helpers=helpers
+local methods=helpers.methods
+local builtin=helpers.builtin
+local extraluapaths={}
+local extralibpaths={}
+local luapaths=nil
+local libpaths=nil
+local oldluapath=nil
+local oldlibpath=nil
+local nofextralua=-1
+local nofextralib=-1
+local nofpathlua=-1
+local nofpathlib=-1
+local function listpaths(what,paths)
+ local nofpaths=#paths
+ if nofpaths>0 then
+ for i=1,nofpaths do
+ helpers.report("using %s path %i: %s",what,i,paths[i])
+ end
+ else
+ helpers.report("no %s paths defined",what)
+ end
+ return nofpaths
+end
+local function getextraluapaths()
+ if helpers.trace and #extraluapaths~=nofextralua then
+ nofextralua=listpaths("extra lua",extraluapaths)
+ end
+ return extraluapaths
+end
+local function getextralibpaths()
+ if helpers.trace and #extralibpaths~=nofextralib then
+ nofextralib=listpaths("extra lib",extralibpaths)
+ end
+ return extralibpaths
+end
+local function getluapaths()
+ local luapath=package.path or ""
+ if oldluapath~=luapath then
+ luapaths=file.splitpath(luapath,";")
+ oldluapath=luapath
+ nofpathlua=-1
+ end
+ if helpers.trace and #luapaths~=nofpathlua then
+ nofpathlua=listpaths("builtin lua",luapaths)
+ end
+ return luapaths
+end
+local function getlibpaths()
+ local libpath=package.cpath or ""
+ if oldlibpath~=libpath then
+ libpaths=file.splitpath(libpath,";")
+ oldlibpath=libpath
+ nofpathlib=-1
+ end
+ if helpers.trace and #libpaths~=nofpathlib then
+ nofpathlib=listpaths("builtin lib",libpaths)
+ end
+ return libpaths
+end
+package.luapaths=getluapaths
+package.libpaths=getlibpaths
+package.extraluapaths=getextraluapaths
+package.extralibpaths=getextralibpaths
+local hashes={
+ lua={},
+ lib={},
+}
+local function registerpath(tag,what,target,...)
+ local pathlist={... }
+ local cleanpath=helpers.cleanpath
+ local trace=helpers.trace
+ local report=helpers.report
+ local hash=hashes[what]
+ local function add(path)
+ local path=cleanpath(path)
+ if not hash[path] then
+ target[#target+1]=path
+ hash[path]=true
+ if trace then
+ report("registered %s path %s: %s",tag,#target,path)
+ end
+ else
+ if trace then
+ report("duplicate %s path: %s",tag,path)
+ end
+ end
+ end
+ for p=1,#pathlist do
+ local path=pathlist[p]
+ if type(path)=="table" then
+ for i=1,#path do
+ add(path[i])
+ end
+ else
+ add(path)
+ end
+ end
+end
+local function pushpath(tag,what,target,path)
+ local path=helpers.cleanpath(path)
+ insert(target,1,path)
+ if helpers.trace then
+ helpers.report("pushing %s path in front: %s",tag,path)
+ end
+end
+local function poppath(tag,what,target)
+ local path=remove(target,1)
+ if helpers.trace then
+ if path then
+ helpers.report("popping %s path from front: %s",tag,path)
+ else
+ helpers.report("no %s path to pop",tag)
+ end
+ end
+end
+helpers.registerpath=registerpath
+function package.extraluapath(...)
+ registerpath("extra lua","lua",extraluapaths,...)
+end
+function package.pushluapath(path)
+ pushpath("extra lua","lua",extraluapaths,path)
+end
+function package.popluapath()
+ poppath("extra lua","lua",extraluapaths)
+end
+function package.extralibpath(...)
+ registerpath("extra lib","lib",extralibpaths,...)
+end
+function package.pushlibpath(path)
+ pushpath("extra lib","lib",extralibpaths,path)
+end
+function package.poplibpath()
+ poppath("extra lib","lua",extralibpaths)
+end
+local function loadedaslib(resolved,rawname)
+ local base=gsub(rawname,"%.","_")
+ local init="luaopen_"..gsub(base,"%.","_")
+ if helpers.trace then
+ helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+ end
+ return package.loadlib(resolved,init)
+end
+helpers.loadedaslib=loadedaslib
+local function loadedbypath(name,rawname,paths,islib,what)
+ local trace=helpers.trace
+ for p=1,#paths do
+ local path=paths[p]
+ local resolved=filejoin(path,name)
+ if trace then
+ helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
+ end
+ if isreadable(resolved) then
+ if trace then
+ helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
+ end
+ end
+end
+helpers.loadedbypath=loadedbypath
+local function loadedbyname(name,rawname)
+ if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
+ local trace=helpers.trace
+ if trace then
+ helpers.report("qualified name, identifying '%s'",what,name)
+ end
+ if isreadable(name) then
+ if trace then
+ helpers.report("qualified name, '%s' found",what,name)
+ end
+ return loadfile(name)
+ end
+ end
+end
+helpers.loadedbyname=loadedbyname
+methods["already loaded"]=function(name)
+ return package.loaded[name]
+end
+methods["preload table"]=function(name)
+ return builtin["preload table"](name)
+end
+methods["qualified path"]=function(name)
+ return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
+end
+methods["lua extra list"]=function(name)
+ return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
+end
+methods["lib extra list"]=function(name)
+ return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
+end
+methods["path specification"]=function(name)
+ getluapaths()
+ return builtin["path specification"](name)
+end
+methods["cpath specification"]=function(name)
+ getlibpaths()
+ return builtin["cpath specification"](name)
+end
+methods["all in one fallback"]=function(name)
+ return builtin["all in one fallback"](name)
+end
+methods["not loaded"]=function(name)
+ if helpers.trace then
+ helpers.report("unable to locate '%s'",name or "?")
+ end
+ return nil
+end
+local level=0
+local used={}
+helpers.traceused=false
+function helpers.loaded(name)
+ local sequence=helpers.sequence
+ level=level+1
+ for i=1,#sequence do
+ local method=sequence[i]
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
+ end
+ local result,rest=methods[method](name)
+ if type(result)=="function" then
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
+ end
+ if helpers.traceused then
+ used[#used+1]={ level=level,name=name }
+ end
+ level=level-1
+ return result,rest
+ end
+ end
+ level=level-1
+ return nil
+end
+function helpers.showused()
+ local n=#used
+ if n>0 then
+ helpers.report("%s libraries loaded:",n)
+ helpers.report()
+ for i=1,n do
+ local u=used[i]
+ helpers.report("%i %a",u.level,u.name)
+ end
+ helpers.report()
+ end
+end
+function helpers.unload(name)
+ if helpers.trace then
+ if package.loaded[name] then
+ helpers.report("unloading, name '%s', %s",name,"done")
+ else
+ helpers.report("unloading, name '%s', %s",name,"not loaded")
+ end
+ end
+ package.loaded[name]=nil
+end
+table.insert(searchers,1,helpers.loaded)
+if context then
+ package.path=""
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-lpeg']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+lpeg=require("lpeg")
+local lpeg=lpeg
+if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end
+local type,next,tostring=type,next,tostring
+local byte,char,gmatch,format=string.byte,string.char,string.gmatch,string.format
+local floor=math.floor
+local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt
+local lpegtype,lpegmatch,lpegprint=lpeg.type,lpeg.match,lpeg.print
+if setinspector then
+ setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
+end
+lpeg.patterns=lpeg.patterns or {}
+local patterns=lpeg.patterns
+local anything=P(1)
+local endofstring=P(-1)
+local alwaysmatched=P(true)
+patterns.anything=anything
+patterns.endofstring=endofstring
+patterns.beginofstring=alwaysmatched
+patterns.alwaysmatched=alwaysmatched
+local sign=S('+-')
+local zero=P('0')
+local digit=R('09')
+local digits=digit^1
+local octdigit=R("07")
+local octdigits=octdigit^1
+local lowercase=R("az")
+local uppercase=R("AZ")
+local underscore=P("_")
+local hexdigit=digit+lowercase+uppercase
+local hexdigits=hexdigit^1
+local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
+local newline=P("\r")*(P("\n")+P(true))+P("\n")
+local escaped=P("\\")*anything
+local squote=P("'")
+local dquote=P('"')
+local space=P(" ")
+local period=P(".")
+local comma=P(",")
+local utfbom_32_be=P('\000\000\254\255')
+local utfbom_32_le=P('\255\254\000\000')
+local utfbom_16_be=P('\254\255')
+local utfbom_16_le=P('\255\254')
+local utfbom_8=P('\239\187\191')
+local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8
+local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8")
+local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")
+local utfoffset=utfbom_32_be*Cc(4)+utfbom_32_le*Cc(4)+utfbom_16_be*Cc(2)+utfbom_16_le*Cc(2)+utfbom_8*Cc(3)+Cc(0)
+local utf8next=R("\128\191")
+patterns.utfbom_32_be=utfbom_32_be
+patterns.utfbom_32_le=utfbom_32_le
+patterns.utfbom_16_be=utfbom_16_be
+patterns.utfbom_16_le=utfbom_16_le
+patterns.utfbom_8=utfbom_8
+patterns.utf_16_be_nl=P("\000\r\000\n")+P("\000\r")+P("\000\n")
+patterns.utf_16_le_nl=P("\r\000\n\000")+P("\r\000")+P("\n\000")
+patterns.utf_32_be_nl=P("\000\000\000\r\000\000\000\n")+P("\000\000\000\r")+P("\000\000\000\n")
+patterns.utf_32_le_nl=P("\r\000\000\000\n\000\000\000")+P("\r\000\000\000")+P("\n\000\000\000")
+patterns.utf8one=R("\000\127")
+patterns.utf8two=R("\194\223")*utf8next
+patterns.utf8three=R("\224\239")*utf8next*utf8next
+patterns.utf8four=R("\240\244")*utf8next*utf8next*utf8next
+patterns.utfbom=utfbom
+patterns.utftype=utftype
+patterns.utfstricttype=utfstricttype
+patterns.utfoffset=utfoffset
+local utf8char=patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four
+local validutf8char=utf8char^0*endofstring*Cc(true)+Cc(false)
+local utf8character=P(1)*R("\128\191")^0
+patterns.utf8=utf8char
+patterns.utf8char=utf8char
+patterns.utf8character=utf8character
+patterns.validutf8=validutf8char
+patterns.validutf8char=validutf8char
+local eol=S("\n\r")
+local spacer=S(" \t\f\v")
+local whitespace=eol+spacer
+local nonspacer=1-spacer
+local nonwhitespace=1-whitespace
+patterns.eol=eol
+patterns.spacer=spacer
+patterns.whitespace=whitespace
+patterns.nonspacer=nonspacer
+patterns.nonwhitespace=nonwhitespace
+local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
+local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0)
+local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
+local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0)
+local b_collapser=Cs(whitespace^0/""*(nonwhitespace^1+whitespace^1/" ")^0)
+local e_collapser=Cs((whitespace^1*endofstring/""+nonwhitespace^1+whitespace^1/" ")^0)
+local m_collapser=Cs((nonwhitespace^1+whitespace^1/" ")^0)
+local b_stripper=Cs(spacer^0/""*(nonspacer^1+spacer^1/" ")^0)
+local e_stripper=Cs((spacer^1*endofstring/""+nonspacer^1+spacer^1/" ")^0)
+local m_stripper=Cs((nonspacer^1+spacer^1/" ")^0)
+patterns.stripper=stripper
+patterns.fullstripper=fullstripper
+patterns.collapser=collapser
+patterns.nospacer=nospacer
+patterns.b_collapser=b_collapser
+patterns.m_collapser=m_collapser
+patterns.e_collapser=e_collapser
+patterns.b_stripper=b_stripper
+patterns.m_stripper=m_stripper
+patterns.e_stripper=e_stripper
+patterns.lowercase=lowercase
+patterns.uppercase=uppercase
+patterns.letter=patterns.lowercase+patterns.uppercase
+patterns.space=space
+patterns.tab=P("\t")
+patterns.spaceortab=patterns.space+patterns.tab
+patterns.newline=newline
+patterns.emptyline=newline^1
+patterns.equal=P("=")
+patterns.comma=comma
+patterns.commaspacer=comma*spacer^0
+patterns.period=period
+patterns.colon=P(":")
+patterns.semicolon=P(";")
+patterns.underscore=underscore
+patterns.escaped=escaped
+patterns.squote=squote
+patterns.dquote=dquote
+patterns.nosquote=(escaped+(1-squote))^0
+patterns.nodquote=(escaped+(1-dquote))^0
+patterns.unsingle=(squote/"")*patterns.nosquote*(squote/"")
+patterns.undouble=(dquote/"")*patterns.nodquote*(dquote/"")
+patterns.unquoted=patterns.undouble+patterns.unsingle
+patterns.unspacer=((patterns.spacer^1)/"")^0
+patterns.singlequoted=squote*patterns.nosquote*squote
+patterns.doublequoted=dquote*patterns.nodquote*dquote
+patterns.quoted=patterns.doublequoted+patterns.singlequoted
+patterns.digit=digit
+patterns.digits=digits
+patterns.octdigit=octdigit
+patterns.octdigits=octdigits
+patterns.hexdigit=hexdigit
+patterns.hexdigits=hexdigits
+patterns.sign=sign
+patterns.cardinal=digits
+patterns.integer=sign^-1*digits
+patterns.unsigned=digit^0*period*digits
+patterns.float=sign^-1*patterns.unsigned
+patterns.cunsigned=digit^0*comma*digits
+patterns.cpunsigned=digit^0*(period+comma)*digits
+patterns.cfloat=sign^-1*patterns.cunsigned
+patterns.cpfloat=sign^-1*patterns.cpunsigned
+patterns.number=patterns.float+patterns.integer
+patterns.cnumber=patterns.cfloat+patterns.integer
+patterns.cpnumber=patterns.cpfloat+patterns.integer
+patterns.oct=zero*octdigits
+patterns.octal=patterns.oct
+patterns.HEX=zero*P("X")*(digit+uppercase)^1
+patterns.hex=zero*P("x")*(digit+lowercase)^1
+patterns.hexadecimal=zero*S("xX")*hexdigits
+patterns.hexafloat=sign^-1*zero*S("xX")*(hexdigit^0*period*hexdigits+hexdigits*period*hexdigit^0+hexdigits)*(S("pP")*sign^-1*hexdigits)^-1
+patterns.decafloat=sign^-1*(digit^0*period*digits+digits*period*digit^0+digits)*S("eE")*sign^-1*digits
+patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring
+patterns.somecontent=(anything-newline-space)^1
+patterns.beginline=#(1-newline)
+patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0))
+function anywhere(pattern)
+ return (1-P(pattern))^0*P(pattern)
+end
+lpeg.anywhere=anywhere
+function lpeg.instringchecker(p)
+ p=anywhere(p)
+ return function(str)
+ return lpegmatch(p,str) and true or false
+ end
+end
+function lpeg.splitter(pattern,action)
+ if action then
+ return (((1-P(pattern))^1)/action+1)^0
+ else
+ return (Cs((1-P(pattern))^1)+1)^0
+ end
+end
+function lpeg.tsplitter(pattern,action)
+ if action then
+ return Ct((((1-P(pattern))^1)/action+1)^0)
+ else
+ return Ct((Cs((1-P(pattern))^1)+1)^0)
+ end
+end
+local splitters_s,splitters_m,splitters_t={},{},{}
+local function splitat(separator,single)
+ local splitter=(single and splitters_s[separator]) or splitters_m[separator]
+ if not splitter then
+ separator=P(separator)
+ local other=C((1-separator)^0)
+ if single then
+ local any=anything
+ splitter=other*(separator*C(any^0)+"")
+ splitters_s[separator]=splitter
+ else
+ splitter=other*(separator*other)^0
+ splitters_m[separator]=splitter
+ end
+ end
+ return splitter
+end
+local function tsplitat(separator)
+ local splitter=splitters_t[separator]
+ if not splitter then
+ splitter=Ct(splitat(separator))
+ splitters_t[separator]=splitter
+ end
+ return splitter
+end
+lpeg.splitat=splitat
+lpeg.tsplitat=tsplitat
+function string.splitup(str,separator)
+ if not separator then
+ separator=","
+ end
+ return lpegmatch(splitters_m[separator] or splitat(separator),str)
+end
+local cache={}
+function lpeg.split(separator,str)
+ local c=cache[separator]
+ if not c then
+ c=tsplitat(separator)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+function string.split(str,separator)
+ if separator then
+ local c=cache[separator]
+ if not c then
+ c=tsplitat(separator)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+ else
+ return { str }
+ end
+end
+local spacing=patterns.spacer^0*newline
+local empty=spacing*Cc("")
+local nonempty=Cs((1-spacing)^1)*spacing^-1
+local content=(empty+nonempty)^1
+patterns.textline=content
+local linesplitter=tsplitat(newline)
+patterns.linesplitter=linesplitter
+function string.splitlines(str)
+ return lpegmatch(linesplitter,str)
+end
+local cache={}
+function lpeg.checkedsplit(separator,str)
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+function string.checkedsplit(str,separator)
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
+local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
+local function f4(s) local c1,c2,c3,c4=byte(s,1,4) return ((c1*64+c2)*64+c3)*64+c4-63447168 end
+local utf8byte=patterns.utf8one/byte+patterns.utf8two/f2+patterns.utf8three/f3+patterns.utf8four/f4
+patterns.utf8byte=utf8byte
+local cache={}
+function lpeg.stripper(str)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs(((S(str)^1)/""+1)^0)
+ cache[str]=s
+ end
+ return s
+ else
+ return Cs(((str^1)/""+1)^0)
+ end
+end
+local cache={}
+function lpeg.keeper(str)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs((((1-S(str))^1)/""+1)^0)
+ cache[str]=s
+ end
+ return s
+ else
+ return Cs((((1-str)^1)/""+1)^0)
+ end
+end
+function lpeg.frontstripper(str)
+ return (P(str)+P(true))*Cs(anything^0)
+end
+function lpeg.endstripper(str)
+ return Cs((1-P(str)*endofstring)^0)
+end
+function lpeg.replacer(one,two,makefunction,isutf)
+ local pattern
+ local u=isutf and utf8char or 1
+ if type(one)=="table" then
+ local no=#one
+ local p=P(false)
+ if no==0 then
+ for k,v in next,one do
+ p=p+P(k)/v
+ end
+ pattern=Cs((p+u)^0)
+ elseif no==1 then
+ local o=one[1]
+ one,two=P(o[1]),o[2]
+ pattern=Cs((one/two+u)^0)
+ else
+ for i=1,no do
+ local o=one[i]
+ p=p+P(o[1])/o[2]
+ end
+ pattern=Cs((p+u)^0)
+ end
+ else
+ pattern=Cs((P(one)/(two or "")+u)^0)
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
+ end
+ else
+ return pattern
+ end
+end
+function lpeg.finder(lst,makefunction,isutf)
+ local pattern
+ if type(lst)=="table" then
+ pattern=P(false)
+ if #lst==0 then
+ for k,v in next,lst do
+ pattern=pattern+P(k)
+ end
+ else
+ for i=1,#lst do
+ pattern=pattern+P(lst[i])
+ end
+ end
+ else
+ pattern=P(lst)
+ end
+ if isutf then
+ pattern=((utf8char or 1)-pattern)^0*pattern
+ else
+ pattern=(1-pattern)^0*pattern
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
+ end
+ else
+ return pattern
+ end
+end
+local splitters_f,splitters_s={},{}
+function lpeg.firstofsplit(separator)
+ local splitter=splitters_f[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)
+ splitters_f[separator]=splitter
+ end
+ return splitter
+end
+function lpeg.secondofsplit(separator)
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=(1-pattern)^0*pattern*C(anything^0)
+ splitters_s[separator]=splitter
+ end
+ return splitter
+end
+local splitters_s,splitters_p={},{}
+function lpeg.beforesuffix(separator)
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)*pattern*endofstring
+ splitters_s[separator]=splitter
+ end
+ return splitter
+end
+function lpeg.afterprefix(separator)
+ local splitter=splitters_p[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=pattern*C(anything^0)
+ splitters_p[separator]=splitter
+ end
+ return splitter
+end
+function lpeg.balancer(left,right)
+ left,right=P(left),P(right)
+ return P { left*((1-left-right)+V(1))^0*right }
+end
+function lpeg.counter(pattern,action)
+ local n=0
+ local pattern=(P(pattern)/function() n=n+1 end+anything)^0
+ if action then
+ return function(str) n=0;lpegmatch(pattern,str);action(n) end
+ else
+ return function(str) n=0;lpegmatch(pattern,str);return n end
+ end
+end
+function lpeg.is_lpeg(p)
+ return p and lpegtype(p)=="pattern"
+end
+function lpeg.oneof(list,...)
+ if type(list)~="table" then
+ list={ list,... }
+ end
+ local p=P(list[1])
+ for l=2,#list do
+ p=p+P(list[l])
+ end
+ return p
+end
+local sort=table.sort
+local function copyindexed(old)
+ local new={}
+ for i=1,#old do
+ new[i]=old
+ end
+ return new
+end
+local function sortedkeys(tab)
+ local keys,s={},0
+ for key,_ in next,tab do
+ s=s+1
+ keys[s]=key
+ end
+ sort(keys)
+ return keys
+end
+function lpeg.append(list,pp,delayed,checked)
+ local p=pp
+ if #list>0 then
+ local keys=copyindexed(list)
+ sort(keys)
+ for i=#keys,1,-1 do
+ local k=keys[i]
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
+ end
+ elseif delayed then
+ local keys=sortedkeys(list)
+ if p then
+ for i=1,#keys,1 do
+ local k=keys[i]
+ local v=list[k]
+ p=P(k)/list+p
+ end
+ else
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
+ end
+ if p then
+ p=p/list
+ end
+ end
+ elseif checked then
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ if k==v then
+ p=P(k)+p
+ else
+ p=P(k)/v+p
+ end
+ else
+ if k==v then
+ p=P(k)
+ else
+ p=P(k)/v
+ end
+ end
+ end
+ else
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ p=P(k)/v+p
+ else
+ p=P(k)/v
+ end
+ end
+ end
+ return p
+end
+local p_false=P(false)
+local p_true=P(true)
+local lower=utf and utf.lower or string.lower
+local upper=utf and utf.upper or string.upper
+function lpeg.setutfcasers(l,u)
+ lower=l or lower
+ upper=u or upper
+end
+local function make1(t,rest)
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+P(k)*p_true
+ elseif v==false then
+ else
+ p=p+P(k)*make1(v,v[""])
+ end
+ end
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
+end
+local function make2(t,rest)
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+(P(lower(k))+P(upper(k)))*p_true
+ elseif v==false then
+ else
+ p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
+ end
+ end
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
+end
+local function utfchartabletopattern(list,insensitive)
+ local tree={}
+ local n=#list
+ if n==0 then
+ for s in next,list do
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
+ end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
+ end
+ else
+ for i=1,n do
+ local s=list[i]
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
+ end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
+ end
+ end
+ return (insensitive and make2 or make1)(tree)
+end
+lpeg.utfchartabletopattern=utfchartabletopattern
+function lpeg.utfreplacer(list,insensitive)
+ local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
+ return function(str)
+ return lpegmatch(pattern,str) or str
+ end
+end
+patterns.containseol=lpeg.finder(eol)
+local function nextstep(n,step,result)
+ local m=n%step
+ local d=floor(n/step)
+ if d>0 then
+ local v=V(tostring(step))
+ local s=result.start
+ for i=1,d do
+ if s then
+ s=v*s
+ else
+ s=v
+ end
+ end
+ result.start=s
+ end
+ if step>1 and result.start then
+ local v=V(tostring(step/2))
+ result[tostring(step)]=v*v
+ end
+ if step>0 then
+ return nextstep(m,step/2,result)
+ else
+ return result
+ end
+end
+function lpeg.times(pattern,n)
+ return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
+end
+do
+ local trailingzeros=zero^0*-digit
+ local stripper=Cs((
+ digits*(
+ period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
+ )+1
+ )^0)
+ lpeg.patterns.stripzeros=stripper
+ local nonzero=digit-zero
+ local trailingzeros=zero^1*endofstring
+ local stripper=Cs((1-period)^0*(
+ period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
+ ))
+ lpeg.patterns.stripzero=stripper
+end
+local byte_to_HEX={}
+local byte_to_hex={}
+local byte_to_dec={}
+local hex_to_byte={}
+for i=0,255 do
+ local H=format("%02X",i)
+ local h=format("%02x",i)
+ local d=format("%03i",i)
+ local c=char(i)
+ byte_to_HEX[c]=H
+ byte_to_hex[c]=h
+ byte_to_dec[c]=d
+ hex_to_byte[h]=c
+ hex_to_byte[H]=c
+end
+local hextobyte=P(2)/hex_to_byte
+local bytetoHEX=P(1)/byte_to_HEX
+local bytetohex=P(1)/byte_to_hex
+local bytetodec=P(1)/byte_to_dec
+local hextobytes=Cs(hextobyte^0)
+local bytestoHEX=Cs(bytetoHEX^0)
+local bytestohex=Cs(bytetohex^0)
+local bytestodec=Cs(bytetodec^0)
+patterns.hextobyte=hextobyte
+patterns.bytetoHEX=bytetoHEX
+patterns.bytetohex=bytetohex
+patterns.bytetodec=bytetodec
+patterns.hextobytes=hextobytes
+patterns.bytestoHEX=bytestoHEX
+patterns.bytestohex=bytestohex
+patterns.bytestodec=bytestodec
+function string.toHEX(s)
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestoHEX,s)
+ end
+end
+function string.tohex(s)
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestohex,s)
+ end
+end
+function string.todec(s)
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestodec,s)
+ end
+end
+function string.tobytes(s)
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(hextobytes,s)
+ end
+end
+local patterns={}
+local function containsws(what)
+ local p=patterns[what]
+ if not p then
+ local p1=P(what)*(whitespace+endofstring)*Cc(true)
+ local p2=whitespace*P(p1)
+ p=P(p1)+P(1-p2)^0*p2+Cc(false)
+ patterns[what]=p
+ end
+ return p
+end
+lpeg.containsws=containsws
+function string.containsws(str,what)
+ return lpegmatch(patterns[what] or containsws(what),str)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-functions']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+functions=functions or {}
+function functions.dummy() end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-string']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local string=string
+local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower
+local lpegmatch,patterns=lpeg.match,lpeg.patterns
+local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs
+local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote
+function string.unquoted(str)
+ return lpegmatch(unquoted,str) or str
+end
+function string.quoted(str)
+ return format("%q",str)
+end
+function string.count(str,pattern)
+ local n=0
+ for _ in gmatch(str,pattern) do
+ n=n+1
+ end
+ return n
+end
+function string.limit(str,n,sentinel)
+ if #str>n then
+ sentinel=sentinel or "..."
+ return sub(str,1,(n-#sentinel))..sentinel
+ else
+ return str
+ end
+end
+local stripper=patterns.stripper
+local fullstripper=patterns.fullstripper
+local collapser=patterns.collapser
+local nospacer=patterns.nospacer
+local longtostring=patterns.longtostring
+function string.strip(str)
+ return str and lpegmatch(stripper,str) or ""
+end
+function string.fullstrip(str)
+ return str and lpegmatch(fullstripper,str) or ""
+end
+function string.collapsespaces(str)
+ return str and lpegmatch(collapser,str) or ""
+end
+function string.nospaces(str)
+ return str and lpegmatch(nospacer,str) or ""
+end
+function string.longtostring(str)
+ return str and lpegmatch(longtostring,str) or ""
+end
+local pattern=P(" ")^0*P(-1)
+function string.is_empty(str)
+ if not str or str=="" then
+ return true
+ else
+ return lpegmatch(pattern,str) and true or false
+ end
+end
+local anything=patterns.anything
+local moreescapes=Cc("%")*S(".-+%?()[]*$^{}")
+local allescapes=Cc("%")*S(".-+%?()[]*")
+local someescapes=Cc("%")*S(".-+%()[]")
+local matchescapes=Cc(".")*S("*?")
+local pattern_m=Cs ((moreescapes+anything )^0 )
+local pattern_a=Cs ((allescapes+anything )^0 )
+local pattern_b=Cs ((someescapes+matchescapes+anything )^0 )
+local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") )
+function string.escapedpattern(str,simple)
+ return lpegmatch(simple and pattern_b or pattern_a,str)
+end
+function string.topattern(str,lowercase,strict)
+ if str=="" or type(str)~="string" then
+ return ".*"
+ elseif strict=="all" then
+ str=lpegmatch(pattern_m,str)
+ elseif strict then
+ str=lpegmatch(pattern_c,str)
+ else
+ str=lpegmatch(pattern_b,str)
+ end
+ if lowercase then
+ return lower(str)
+ else
+ return str
+ end
+end
+function string.valid(str,default)
+ return (type(str)=="string" and str~="" and str) or default or nil
+end
+string.itself=function(s) return s end
+local pattern_c=Ct(C(1)^0)
+local pattern_b=Ct((C(1)/byte)^0)
+function string.totable(str,bytes)
+ return lpegmatch(bytes and pattern_b or pattern_c,str)
+end
+local replacer=lpeg.replacer("@","%%")
+function string.tformat(fmt,...)
+ return format(lpegmatch(replacer,fmt),...)
+end
+string.quote=string.quoted
+string.unquote=string.unquoted
+if not string.bytetable then
+ local limit=5000
+ function string.bytetable(str)
+ local n=#str
+ if n>limit then
+ local t={ byte(str,1,limit) }
+ for i=limit+1,n do
+ t[i]=byte(str,i)
+ end
+ return t
+ else
+ return { byte(str,1,n) }
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-table']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local type,next,tostring,tonumber,select=type,next,tostring,tonumber,select
+local table,string=table,string
+local concat,sort=table.concat,table.sort
+local format,lower,dump=string.format,string.lower,string.dump
+local getmetatable,setmetatable=getmetatable,setmetatable
+local lpegmatch,patterns=lpeg.match,lpeg.patterns
+local floor=math.floor
+local stripper=patterns.stripper
+function table.getn(t)
+ return t and #t
+end
+function table.strip(tab)
+ local lst={}
+ local l=0
+ for i=1,#tab do
+ local s=lpegmatch(stripper,tab[i]) or ""
+ if s=="" then
+ else
+ l=l+1
+ lst[l]=s
+ end
+ end
+ return lst
+end
+function table.keys(t)
+ if t then
+ local keys={}
+ local k=0
+ for key in next,t do
+ k=k+1
+ keys[k]=key
+ end
+ return keys
+ else
+ return {}
+ end
+end
+local function compare(a,b)
+ local ta=type(a)
+ if ta=="number" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ elseif tb=="string" then
+ return tostring(a)<b
+ end
+ elseif ta=="string" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ else
+ return a<tostring(b)
+ end
+ end
+ return tostring(a)<tostring(b)
+end
+local function sortedkeys(tab)
+ if tab then
+ local srt={}
+ local category=0
+ local s=0
+ for key in next,tab do
+ s=s+1
+ srt[s]=key
+ if category~=3 then
+ local tkey=type(key)
+ if category==1 then
+ if tkey~="string" then
+ category=3
+ end
+ elseif category==2 then
+ if tkey~="number" then
+ category=3
+ end
+ else
+ if tkey=="string" then
+ category=1
+ elseif tkey=="number" then
+ category=2
+ else
+ category=3
+ end
+ end
+ end
+ end
+ if s<2 then
+ elseif category==3 then
+ sort(srt,compare)
+ else
+ sort(srt)
+ end
+ return srt
+ else
+ return {}
+ end
+end
+local function sortedhashonly(tab)
+ if tab then
+ local srt={}
+ local s=0
+ for key in next,tab do
+ if type(key)=="string" then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return {}
+ end
+end
+local function sortedindexonly(tab)
+ if tab then
+ local srt={}
+ local s=0
+ for key in next,tab do
+ if type(key)=="number" then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return {}
+ end
+end
+local function sortedhashkeys(tab,cmp)
+ if tab then
+ local srt={}
+ local s=0
+ for key in next,tab do
+ if key then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt,cmp)
+ end
+ return srt
+ else
+ return {}
+ end
+end
+function table.allkeys(t)
+ local keys={}
+ for k,v in next,t do
+ for k in next,v do
+ keys[k]=true
+ end
+ end
+ return sortedkeys(keys)
+end
+table.sortedkeys=sortedkeys
+table.sortedhashonly=sortedhashonly
+table.sortedindexonly=sortedindexonly
+table.sortedhashkeys=sortedhashkeys
+local function nothing() end
+local function sortedhash(t,cmp)
+ if t then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local m=#s
+ if m==1 then
+ return next,t
+ elseif m>0 then
+ local n=0
+ return function()
+ if n<m then
+ n=n+1
+ local k=s[n]
+ return k,t[k]
+ end
+ end
+ end
+ end
+ return nothing
+end
+table.sortedhash=sortedhash
+table.sortedpairs=sortedhash
+function table.append(t,list)
+ local n=#t
+ for i=1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ return t
+end
+function table.prepend(t,list)
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+ t[nt]=t[i]
+ nt=nt-1
+ end
+ for i=1,#list do
+ t[i]=list[i]
+ end
+ return t
+end
+function table.merge(t,...)
+ if not t then
+ t={}
+ end
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
+ end
+ end
+ return t
+end
+function table.merged(...)
+ local t={}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
+ end
+ end
+ return t
+end
+function table.imerge(t,...)
+ local nt=#t
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ nt=nt+1
+ t[nt]=nst[j]
+ end
+ end
+ return t
+end
+function table.imerged(...)
+ local tmp={}
+ local ntmp=0
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ ntmp=ntmp+1
+ tmp[ntmp]=nst[j]
+ end
+ end
+ return tmp
+end
+local function fastcopy(old,metatabletoo)
+ if old then
+ local new={}
+ for k,v in next,old do
+ if type(v)=="table" then
+ new[k]=fastcopy(v,metatabletoo)
+ else
+ new[k]=v
+ end
+ end
+ if metatabletoo then
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ end
+ return new
+ else
+ return {}
+ end
+end
+local function copy(t,tables)
+ if not tables then
+ tables={}
+ end
+ local tcopy={}
+ if not tables[t] then
+ tables[t]=tcopy
+ end
+ for i,v in next,t do
+ if type(i)=="table" then
+ if tables[i] then
+ i=tables[i]
+ else
+ i=copy(i,tables)
+ end
+ end
+ if type(v)~="table" then
+ tcopy[i]=v
+ elseif tables[v] then
+ tcopy[i]=tables[v]
+ else
+ tcopy[i]=copy(v,tables)
+ end
+ end
+ local mt=getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
+end
+table.fastcopy=fastcopy
+table.copy=copy
+function table.derive(parent)
+ local child={}
+ if parent then
+ setmetatable(child,{ __index=parent })
+ end
+ return child
+end
+function table.tohash(t,value)
+ local h={}
+ if t then
+ if value==nil then value=true end
+ for _,v in next,t do
+ h[v]=value
+ end
+ end
+ return h
+end
+function table.fromhash(t)
+ local hsh={}
+ local h=0
+ for k,v in next,t do
+ if v then
+ h=h+1
+ hsh[h]=k
+ end
+ end
+ return hsh
+end
+local noquotes,hexify,handle,compact,inline,functions,metacheck
+local reserved=table.tohash {
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
+}
+local function is_simple_table(t,hexify)
+ local nt=#t
+ if nt>0 then
+ local n=0
+ for _,v in next,t do
+ n=n+1
+ if type(v)=="table" then
+ return nil
+ end
+ end
+ local haszero=rawget(t,0)
+ if n==nt then
+ local tt={}
+ for i=1,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i]=format("0x%X",v)
+ else
+ tt[i]=v
+ end
+ elseif tv=="string" then
+ tt[i]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i]=v and "true" or "false"
+ else
+ return nil
+ end
+ end
+ return tt
+ elseif haszero and (n==nt+1) then
+ local tt={}
+ for i=0,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i+1]=format("0x%X",v)
+ else
+ tt[i+1]=v
+ end
+ elseif tv=="string" then
+ tt[i+1]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i+1]=v and "true" or "false"
+ else
+ return nil
+ end
+ end
+ tt[1]="[0] = "..tt[1]
+ return tt
+ end
+ end
+ return nil
+end
+table.is_simple_table=is_simple_table
+local propername=patterns.propername
+local function dummy() end
+local function do_serialize(root,name,depth,level,indexed)
+ if level>0 then
+ depth=depth.." "
+ if indexed then
+ handle(format("%s{",depth))
+ else
+ local tn=type(name)
+ if tn=="number" then
+ if hexify then
+ handle(format("%s[0x%X]={",depth,name))
+ else
+ handle(format("%s[%s]={",depth,name))
+ end
+ elseif tn=="string" then
+ if noquotes and not reserved[name] and lpegmatch(propername,name) then
+ handle(format("%s%s={",depth,name))
+ else
+ handle(format("%s[%q]={",depth,name))
+ end
+ elseif tn=="boolean" then
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
+ else
+ handle(format("%s{",depth))
+ end
+ end
+ end
+ if root and next(root)~=nil then
+ local first=nil
+ local last=0
+ if compact then
+ last=#root
+ for k=1,last do
+ if rawget(root,k)==nil then
+ last=k-1
+ break
+ end
+ end
+ if last>0 then
+ first=1
+ end
+ end
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if compact and first and tk=="number" and k>=first and k<=last then
+ if tv=="number" then
+ if hexify then
+ handle(format("%s 0x%X,",depth,v))
+ else
+ handle(format("%s %s,",depth,v))
+ end
+ elseif tv=="string" then
+ handle(format("%s %q,",depth,v))
+ elseif tv=="table" then
+ if next(v)==nil then
+ handle(format("%s {},",depth))
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ handle(format("%s { %s },",depth,concat(st,", ")))
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ elseif tv=="boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv=="function" then
+ if functions then
+ handle(format('%s load(%q),',depth,dump(v)))
+ else
+ handle(format('%s "function",',depth))
+ end
+ else
+ handle(format("%s %q,",depth,tostring(v)))
+ end
+ elseif k=="__p__" then
+ if false then
+ handle(format("%s __p__=nil,",depth))
+ end
+ elseif tv=="number" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ if hexify then
+ handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ else
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
+ end
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ if hexify then
+ handle(format("%s %s=0x%X,",depth,k,v))
+ else
+ handle(format("%s %s=%s,",depth,k,v))
+ end
+ else
+ if hexify then
+ handle(format("%s [%q]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v))
+ end
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,v))
+ else
+ handle(format("%s [%s]=%q,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,v))
+ else
+ handle(format("%s [%q]=%q,",depth,k,v))
+ end
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={},",depth,k))
+ else
+ handle(format("%s [%s]={},",depth,k))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={},",depth,k))
+ else
+ handle(format("%s [%q]={},",depth,k))
+ end
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tv=="function" then
+ if functions then
+ local getinfo=debug and debug.getinfo
+ if getinfo then
+ local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%s]=load(%q),",depth,k,f))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%q]=load(%q),",depth,k,f))
+ end
+ end
+ end
+ else
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
+ end
+ end
+ end
+ end
+ if level>0 then
+ handle(format("%s},",depth))
+ end
+end
+local function serialize(_handle,root,name,specification)
+ local tname=type(name)
+ if type(specification)=="table" then
+ noquotes=specification.noquotes
+ hexify=specification.hexify
+ handle=_handle or specification.handle or print
+ functions=specification.functions
+ compact=specification.compact
+ inline=specification.inline and compact
+ metacheck=specification.metacheck
+ if functions==nil then
+ functions=true
+ end
+ if compact==nil then
+ compact=true
+ end
+ if inline==nil then
+ inline=compact
+ end
+ if metacheck==nil then
+ metacheck=true
+ end
+ else
+ noquotes=false
+ hexify=false
+ handle=_handle or print
+ compact=true
+ inline=true
+ functions=true
+ metacheck=true
+ end
+ if tname=="string" then
+ if name=="return" then
+ handle("return {")
+ else
+ handle(name.."={")
+ end
+ elseif tname=="number" then
+ if hexify then
+ handle(format("[0x%X]={",name))
+ else
+ handle("["..name.."]={")
+ end
+ elseif tname=="boolean" then
+ if name then
+ handle("return {")
+ else
+ handle("{")
+ end
+ else
+ handle("t={")
+ end
+ if root then
+ if metacheck and getmetatable(root) then
+ local dummy=root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_=nil
+ end
+ if next(root)~=nil then
+ do_serialize(root,name,"",0)
+ end
+ end
+ handle("}")
+end
+function table.serialize(root,name,specification)
+ local t={}
+ local n=0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ end
+ serialize(flush,root,name,specification)
+ return concat(t,"\n")
+end
+table.tohandle=serialize
+local maxtab=2*1024
+function table.tofile(filename,root,name,specification)
+ local f=io.open(filename,'w')
+ if f then
+ if maxtab>1 then
+ local t={}
+ local n=0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ if n>maxtab then
+ f:write(concat(t,"\n"),"\n")
+ t={}
+ n=0
+ end
+ end
+ serialize(flush,root,name,specification)
+ f:write(concat(t,"\n"),"\n")
+ else
+ local function flush(s)
+ f:write(s,"\n")
+ end
+ serialize(flush,root,name,specification)
+ end
+ f:close()
+ io.flush()
+ end
+end
+local function flattened(t,f,depth)
+ if f==nil then
+ f={}
+ depth=0xFFFF
+ elseif tonumber(f) then
+ depth=f
+ f={}
+ elseif not depth then
+ depth=0xFFFF
+ end
+ for k,v in next,t do
+ if type(k)~="number" then
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
+ end
+ end
+ end
+ for k=1,#t do
+ local v=t[k]
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
+ end
+ end
+ return f
+end
+table.flattened=flattened
+local function collapsed(t,f,h)
+ if f==nil then
+ f={}
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsed(v,f,h)
+ elseif not h[v] then
+ f[#f+1]=v
+ h[v]=true
+ end
+ end
+ return f
+end
+local function collapsedhash(t,h)
+ if h==nil then
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsedhash(v,h)
+ else
+ h[v]=true
+ end
+ end
+ return h
+end
+table.collapsed=collapsed
+table.collapsedhash=collapsedhash
+local function unnest(t,f)
+ if not f then
+ f={}
+ end
+ for i=1,#t do
+ local v=t[i]
+ if type(v)=="table" then
+ if type(v[1])=="table" then
+ unnest(v,f)
+ else
+ f[#f+1]=v
+ end
+ else
+ f[#f+1]=v
+ end
+ end
+ return f
+end
+function table.unnest(t)
+ return unnest(t)
+end
+local function are_equal(a,b,n,m)
+ if a==b then
+ return true
+ elseif a and b and #a==#b then
+ if not n then
+ n=1
+ end
+ if not m then
+ m=#a
+ end
+ for i=n,m do
+ local ai,bi=a[i],b[i]
+ if ai==bi then
+ elseif type(ai)=="table" and type(bi)=="table" then
+ if not are_equal(ai,bi) then
+ return false
+ end
+ else
+ return false
+ end
+ end
+ return true
+ else
+ return false
+ end
+end
+local function identical(a,b)
+ if a~=b then
+ for ka,va in next,a do
+ local vb=b[ka]
+ if va==vb then
+ elseif type(va)=="table" and type(vb)=="table" then
+ if not identical(va,vb) then
+ return false
+ end
+ else
+ return false
+ end
+ end
+ end
+ return true
+end
+table.identical=identical
+table.are_equal=are_equal
+local function sparse(old,nest,keeptables)
+ local new={}
+ for k,v in next,old do
+ if not (v=="" or v==false) then
+ if nest and type(v)=="table" then
+ v=sparse(v,nest)
+ if keeptables or next(v)~=nil then
+ new[k]=v
+ end
+ else
+ new[k]=v
+ end
+ end
+ end
+ return new
+end
+table.sparse=sparse
+function table.compact(t)
+ return sparse(t,true,true)
+end
+function table.contains(t,v)
+ if t then
+ for i=1,#t do
+ if t[i]==v then
+ return i
+ end
+ end
+ end
+ return false
+end
+function table.count(t)
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ end
+ return n
+end
+function table.swapped(t,s)
+ local n={}
+ if s then
+ for k,v in next,s do
+ n[k]=v
+ end
+ end
+ for k,v in next,t do
+ n[v]=k
+ end
+ return n
+end
+function table.hashed(t)
+ for i=1,#t do
+ t[t[i]]=i
+ end
+ return t
+end
+function table.mirrored(t)
+ local n={}
+ for k,v in next,t do
+ n[v]=k
+ n[k]=v
+ end
+ return n
+end
+function table.reversed(t)
+ if t then
+ local tt={}
+ local tn=#t
+ if tn>0 then
+ local ttn=0
+ for i=tn,1,-1 do
+ ttn=ttn+1
+ tt[ttn]=t[i]
+ end
+ end
+ return tt
+ end
+end
+function table.reverse(t)
+ if t then
+ local n=#t
+ local m=n+1
+ for i=1,floor(n/2) do
+ local j=m-i
+ t[i],t[j]=t[j],t[i]
+ end
+ return t
+ end
+end
+local function sequenced(t,sep,simple)
+ if not t then
+ return ""
+ elseif type(t)~="table" then
+ return t
+ end
+ local n=#t
+ local s={}
+ if n>0 then
+ for i=1,n do
+ local v=t[i]
+ if type(v)=="table" then
+ s[i]="{"..sequenced(v,sep,simple).."}"
+ else
+ s[i]=tostring(t[i])
+ end
+ end
+ else
+ n=0
+ for k,v in sortedhash(t) do
+ if simple then
+ if v==true then
+ n=n+1
+ s[n]=k
+ elseif v and v~="" then
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
+ end
+ end
+ else
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
+ end
+ end
+ end
+ end
+ if sep==true then
+ return "{ "..concat(s,", ").." }"
+ else
+ return concat(s,sep or " | ")
+ end
+end
+table.sequenced=sequenced
+function table.print(t,...)
+ if type(t)~="table" then
+ print(tostring(t))
+ else
+ serialize(print,t,...)
+ end
+end
+if setinspector then
+ setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
+end
+function table.sub(t,i,j)
+ return { unpack(t,i,j) }
+end
+function table.is_empty(t)
+ return not t or next(t)==nil
+end
+function table.has_one_entry(t)
+ return t and next(t,next(t))==nil
+end
+function table.loweredkeys(t)
+ local l={}
+ for k,v in next,t do
+ l[lower(k)]=v
+ end
+ return l
+end
+function table.unique(old)
+ local hash={}
+ local new={}
+ local n=0
+ for i=1,#old do
+ local oi=old[i]
+ if not hash[oi] then
+ n=n+1
+ new[n]=oi
+ hash[oi]=true
+ end
+ end
+ return new
+end
+function table.sorted(t,...)
+ sort(t,...)
+ return t
+end
+function table.values(t,s)
+ if t then
+ local values={}
+ local keys={}
+ local v=0
+ for key,value in next,t do
+ if not keys[value] then
+ v=v+1
+ values[v]=value
+ keys[k]=key
+ end
+ end
+ if s then
+ sort(values)
+ end
+ return values
+ else
+ return {}
+ end
+end
+function table.filtered(t,pattern,sort,cmp)
+ if t and type(pattern)=="string" then
+ if sort then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local n=0
+ local m=#s
+ local function kv(s)
+ while n<m do
+ n=n+1
+ local k=s[n]
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return kv,s
+ else
+ local n=next(t)
+ local function iterator()
+ while n~=nil do
+ local k=n
+ n=next(t,k)
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return iterator,t
+ end
+ else
+ return nothing
+ end
+end
+if not table.move then
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1~=a2 then
+ for i=f,e do
+ a2[t]=a1[i]
+ t=t+1
+ end
+ return a2
+ else
+ t=t+e-f
+ for i=e,f,-1 do
+ a1[t]=a1[i]
+ t=t-1
+ end
+ return a1
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-boolean']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local type,tonumber=type,tonumber
+boolean=boolean or {}
+local boolean=boolean
+function boolean.tonumber(b)
+ if b then return 1 else return 0 end
+end
+function toboolean(str,tolerant)
+ if str==nil then
+ return false
+ elseif str==false then
+ return false
+ elseif str==true then
+ return true
+ elseif str=="true" then
+ return true
+ elseif str=="false" then
+ return false
+ elseif not tolerant then
+ return false
+ elseif str==0 then
+ return false
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
+end
+string.toboolean=toboolean
+function string.booleanstring(str)
+ if str=="0" then
+ return false
+ elseif str=="1" then
+ return true
+ elseif str=="" then
+ return false
+ elseif str=="false" then
+ return false
+ elseif str=="true" then
+ return true
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
+end
+function string.is_boolean(str,default,strict)
+ if type(str)=="string" then
+ if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
+ return true
+ elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
+ return false
+ end
+ end
+ return default
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-number']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local tostring,tonumber=tostring,tonumber
+local format,floor,match,rep=string.format,math.floor,string.match,string.rep
+local concat,insert=table.concat,table.insert
+local lpegmatch=lpeg.match
+local floor=math.floor
+number=number or {}
+local number=number
+if bit32 then
+ local bextract=bit32.extract
+ local t={
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ }
+ function number.tobitstring(b,m,w)
+ if not w then
+ w=32
+ end
+ local n=w
+ for i=0,w-1 do
+ local v=bextract(b,i)
+ local k=w-i
+ if v==1 then
+ n=k
+ t[k]="1"
+ else
+ t[k]="0"
+ end
+ end
+ if w then
+ return concat(t,"",1,w)
+ elseif m then
+ m=33-m*8
+ if m<1 then
+ m=1
+ end
+ return concat(t,"",1,m)
+ elseif n<8 then
+ return concat(t)
+ elseif n<16 then
+ return concat(t,"",9)
+ elseif n<24 then
+ return concat(t,"",17)
+ else
+ return concat(t,"",25)
+ end
+ end
+else
+ function number.tobitstring(n,m)
+ if n>0 then
+ local t={}
+ while n>0 do
+ insert(t,1,n%2>0 and 1 or 0)
+ n=floor(n/2)
+ end
+ local nn=8-#t%8
+ if nn>0 and nn<8 then
+ for i=1,nn do
+ insert(t,1,0)
+ end
+ end
+ if m then
+ m=m*8-#t
+ if m>0 then
+ insert(t,1,rep("0",m))
+ end
+ end
+ return concat(t)
+ elseif m then
+ rep("00000000",m)
+ else
+ return "00000000"
+ end
+ end
+end
+function number.valid(str,default)
+ return tonumber(str) or default or nil
+end
+function number.toevenhex(n)
+ local s=format("%X",n)
+ if #s%2==0 then
+ return s
+ else
+ return "0"..s
+ end
+end
+function number.bytetodecimal(b)
+ local d=floor(b*100/255+0.5)
+ if d>100 then
+ return 100
+ elseif d<-100 then
+ return -100
+ else
+ return d
+ end
+end
+function number.decimaltobyte(d)
+ local b=floor(d*255/100+0.5)
+ if b>255 then
+ return 255
+ elseif b<-255 then
+ return -255
+ else
+ return b
+ end
+end
+function number.idiv(i,d)
+ return floor(i/d)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-math']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if not math.ceiling then
+ math.ceiling=math.ceil
+end
+if not math.round then
+ local floor=math.floor
+ function math.round(x) return floor(x+0.5) end
+end
+if not math.div then
+ local floor=math.floor
+ function math.div(n,m) return floor(n/m) end
+end
+if not math.mod then
+ function math.mod(n,m) return n%m end
+end
+if not math.sind then
+ local sin,cos,tan=math.sin,math.cos,math.tan
+ local pipi=2*math.pi/360
+ function math.sind(d) return sin(d*pipi) end
+ function math.cosd(d) return cos(d*pipi) end
+ function math.tand(d) return tan(d*pipi) end
+end
+if not math.odd then
+ function math.odd (n) return n%2~=0 end
+ function math.even(n) return n%2==0 end
+end
+if not math.cosh then
+ local exp=math.exp
+ function math.cosh(x)
+ local xx=exp(x)
+ return (xx+1/xx)/2
+ end
+ function math.sinh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/2
+ end
+ function math.tanh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/(xx+1/xx)
+ end
+end
+if not math.pow then
+ function math.pow(x,y)
+ return x^y
+ end
+end
+if not math.atan2 then
+ math.atan2=math.atan
+end
+if not math.ldexp then
+ function math.ldexp(x,e)
+ return x*2.0^e
+ end
+end
+if not math.log10 then
+ local log=math.log
+ function math.log10(x)
+ return log(x,10)
+ end
+end
+if not math.type then
+ function math.type()
+ return "float"
+ end
+end
+if not math.tointeger then
+ math.mininteger=-0x4FFFFFFFFFFF
+ math.maxinteger=0x4FFFFFFFFFFF
+ local floor=math.floor
+ function math.tointeger(n)
+ local f=floor(n)
+ return f==n and f or nil
+ end
+end
+if not math.ult then
+ local floor=math.floor
+ function math.tointeger(m,n)
+ return floor(m)<floor(n)
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-io']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local io=io
+local open,flush,write,read=io.open,io.flush,io.write,io.read
+local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
+local concat=table.concat
+local type=type
+if string.find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator,io.pathseparator="\\",";"
+else
+ io.fileseparator,io.pathseparator="/",":"
+end
+local large=0x01000000
+local medium=0x00100000
+local small=0x00020000
+local function readall(f)
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ return f:read(size)
+ else
+ return ""
+ end
+end
+io.readall=readall
+function io.loaddata(filename,textmode)
+ local f=open(filename,(textmode and 'r') or 'rb')
+ if f then
+ local size=f:seek("end")
+ local data=nil
+ if size>0 then
+ f:seek("set",0)
+ data=f:read(size)
+ end
+ f:close()
+ return data
+ end
+end
+function io.copydata(source,target,action)
+ local f=open(source,"rb")
+ if f then
+ local g=open(target,"wb")
+ if g then
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ local data=f:read(size)
+ if action then
+ data=action(data)
+ end
+ if data then
+ g:write(data)
+ end
+ end
+ g:close()
+ end
+ f:close()
+ flush()
+ end
+end
+function io.savedata(filename,data,joiner)
+ local f=open(filename,"wb")
+ if f then
+ if type(data)=="table" then
+ f:write(concat(data,joiner or ""))
+ elseif type(data)=="function" then
+ data(f)
+ else
+ f:write(data or "")
+ end
+ f:close()
+ flush()
+ return true
+ else
+ return false
+ end
+end
+if fio and fio.readline then
+ local readline=fio.readline
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=readline(f)
+ if line then
+ lines[i]=line
+ else
+ break
+ end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=readline(f)
+ f:close()
+ if line and #line>0 then
+ return line
+ end
+ end
+ end
+else
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=f:read("*lines")
+ if line then
+ lines[i]=line
+ else
+ break
+ end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=f:read("*line") or ""
+ f:close()
+ if #line>0 then
+ return line
+ end
+ end
+ end
+end
+function io.loadchunk(filename,n)
+ local f=open(filename,'rb')
+ if f then
+ local data=f:read(n or 1024)
+ f:close()
+ if #data>0 then
+ return data
+ end
+ end
+end
+function io.exists(filename)
+ local f=open(filename)
+ if f==nil then
+ return false
+ else
+ f:close()
+ return true
+ end
+end
+function io.size(filename)
+ local f=open(filename)
+ if f==nil then
+ return 0
+ else
+ local s=f:seek("end")
+ f:close()
+ return s
+ end
+end
+local function noflines(f)
+ if type(f)=="string" then
+ local f=open(filename)
+ if f then
+ local n=f and noflines(f) or 0
+ f:close()
+ return n
+ else
+ return 0
+ end
+ else
+ local n=0
+ for _ in f:lines() do
+ n=n+1
+ end
+ f:seek('set',0)
+ return n
+ end
+end
+io.noflines=noflines
+local nextchar={
+ [ 4]=function(f)
+ return f:read(1,1,1,1)
+ end,
+ [ 2]=function(f)
+ return f:read(1,1)
+ end,
+ [ 1]=function(f)
+ return f:read(1)
+ end,
+ [-2]=function(f)
+ local a,b=f:read(1,1)
+ return b,a
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ return d,c,b,a
+ end
+}
+function io.characters(f,n)
+ if f then
+ return nextchar[n or 1],f
+ end
+end
+local nextbyte={
+ [4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(a),byte(b),byte(c),byte(d)
+ end
+ end,
+ [3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(a),byte(b),byte(c)
+ end
+ end,
+ [2]=function(f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(a),byte(b)
+ end
+ end,
+ [1]=function (f)
+ local a=f:read(1)
+ if a then
+ return byte(a)
+ end
+ end,
+ [-2]=function (f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(b),byte(a)
+ end
+ end,
+ [-3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(c),byte(b),byte(a)
+ end
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(d),byte(c),byte(b),byte(a)
+ end
+ end
+}
+function io.bytes(f,n)
+ if f then
+ return nextbyte[n or 1],f
+ else
+ return nil,nil
+ end
+end
+function io.ask(question,default,options)
+ while true do
+ write(question)
+ if options then
+ write(format(" [%s]",concat(options,"|")))
+ end
+ if default then
+ write(format(" [%s]",default))
+ end
+ write(format(" "))
+ flush()
+ local answer=read()
+ answer=gsub(answer,"^%s*(.*)%s*$","%1")
+ if answer=="" and default then
+ return default
+ elseif not options then
+ return answer
+ else
+ for k=1,#options do
+ if options[k]==answer then
+ return answer
+ end
+ end
+ local pattern="^"..answer
+ for k=1,#options do
+ local v=options[k]
+ if find(v,pattern) then
+ return v
+ end
+ end
+ end
+ end
+end
+local function readnumber(f,n,m)
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ if n==1 then
+ return byte(f:read(1))
+ elseif n==2 then
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==3 then
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==4 then
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==8 then
+ local a,b=readnumber(f,4),readnumber(f,4)
+ return 0x100*a+b
+ elseif n==12 then
+ local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
+ return 0x10000*a+0x100*b+c
+ elseif n==-2 then
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==-3 then
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==-4 then
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==-8 then
+ local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
+ return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+ else
+ return 0
+ end
+end
+io.readnumber=readnumber
+function io.readstring(f,n,m)
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ local str=gsub(f:read(n),"\000","")
+ return str
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-os']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local os=os
+local date,time=os.date,os.time
+local find,format,gsub,upper,gmatch=string.find,string.format,string.gsub,string.upper,string.gmatch
+local concat=table.concat
+local random,ceil,randomseed=math.random,math.ceil,math.randomseed
+local rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring=rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring
+do
+ local selfdir=os.selfdir
+ if selfdir=="" then
+ selfdir=nil
+ end
+ if not selfdir then
+ if arg then
+ for i=1,#arg do
+ local a=arg[i]
+ if find(a,"^%-%-[c:]*texmfbinpath=") then
+ selfdir=gsub(a,"^.-=","")
+ break
+ end
+ end
+ end
+ if not selfdir then
+ selfdir=os.selfbin or "luatex"
+ if find(selfdir,"[/\\]") then
+ selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
+ elseif os.getenv then
+ local path=os.getenv("PATH")
+ local name=gsub(selfdir,"^.*[/\\][^/\\]","")
+ local patt="[^:]+"
+ if os.type=="windows" then
+ patt="[^;]+"
+ name=name..".exe"
+ end
+ local isfile
+ if lfs then
+ local attributes=lfs.attributes
+ isfile=function(name)
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
+ end
+ else
+ local open=io.open
+ isfile=function(name)
+ local f=open(name)
+ if f then
+ f:close()
+ return true
+ end
+ end
+ end
+ for p in gmatch(path,patt) do
+ if isfile(p.."/"..name) then
+ selfdir=p
+ break
+ end
+ end
+ end
+ end
+ os.selfdir=selfdir or "."
+ end
+end
+math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
+randomseed(math.initialseed)
+if not os.__getenv__ then
+ os.__getenv__=os.getenv
+ os.__setenv__=os.setenv
+ if os.env then
+ local osgetenv=os.getenv
+ local ossetenv=os.setenv
+ local osenv=os.env local _=osenv.PATH
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ if type(v)=="table" then
+ v=concat(v,";")
+ end
+ ossetenv(K,v)
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ else
+ local ossetenv=os.setenv
+ local osgetenv=os.getenv
+ local osenv={}
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ local function __index(t,k)
+ return os.getenv(k)
+ end
+ local function __newindex(t,k,v)
+ os.setenv(k,v)
+ end
+ os.env={}
+ setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
+end
+local execute=os.execute
+local iopopen=io.popen
+local function resultof(command)
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ else
+ return ""
+ end
+end
+os.resultof=resultof
+function os.pipeto(command)
+ return iopopen(command,"w")
+end
+if not io.fileseparator then
+ if find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
+ else
+ io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
+ end
+end
+os.type=os.type or (io.pathseparator==";" and "windows") or "unix"
+os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
+if os.type=="windows" then
+ os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
+else
+ os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
+end
+local launchers={
+ windows="start %s",
+ macosx="open %s",
+ unix="xdg-open %s &> /dev/null &",
+}
+function os.launch(str)
+ local command=format(launchers[os.name] or launchers.unix,str)
+ execute(command)
+end
+local gettimeofday=os.gettimeofday or os.clock
+os.gettimeofday=gettimeofday
+local startuptime=gettimeofday()
+function os.runtime()
+ return gettimeofday()-startuptime
+end
+local resolvers=os.resolvers or {}
+os.resolvers=resolvers
+setmetatable(os,{ __index=function(t,k)
+ local r=resolvers[k]
+ return r and r(t,k) or nil
+end })
+local name,platform=os.name or "linux",os.getenv("MTX_PLATFORM") or ""
+if platform~="" then
+ os.platform=platform
+elseif os.type=="windows" then
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
+ local platform=""
+ if find(architecture,"AMD64",1,true) then
+ platform="win64"
+ else
+ platform="mswin"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
+elseif name=="linux" then
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=os.getenv("MTX_PLATFORM") or ""
+ local musl=find(os.selfdir or "","linuxmusl")
+ if platform~="" then
+ elseif find(architecture,"x86_64",1,true) then
+ platform=musl and "linuxmusl" or "linux-64"
+ elseif find(architecture,"ppc",1,true) then
+ platform="linux-ppc"
+ else
+ platform=musl and "linuxmusl" or "linux"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
+elseif name=="macosx" then
+ function resolvers.platform(t,k)
+ local architecture=resultof("echo $HOSTTYPE") or ""
+ local platform=""
+ if architecture=="" then
+ platform="osx-intel"
+ elseif find(architecture,"i386",1,true) then
+ platform="osx-intel"
+ elseif find(architecture,"x86_64",1,true) then
+ platform="osx-64"
+ else
+ platform="osx-ppc"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
+elseif name=="sunos" then
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"sparc",1,true) then
+ platform="solaris-sparc"
+ else
+ platform="solaris-intel"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
+elseif name=="freebsd" then
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"amd64",1,true) then
+ platform="freebsd-amd64"
+ else
+ platform="freebsd"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
+elseif name=="kfreebsd" then
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"x86_64",1,true) then
+ platform="kfreebsd-amd64"
+ else
+ platform="kfreebsd-i386"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
+else
+ function resolvers.platform(t,k)
+ local platform="linux"
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
+end
+os.newline=name=="windows" and "\013\010" or "\010"
+function resolvers.bits(t,k)
+ local bits=find(os.platform,"64",1,true) and 64 or 32
+ os.bits=bits
+ return bits
+end
+local t={ 8,9,"a","b" }
+function os.uuid()
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
+end
+local d
+function os.timezone(delta)
+ d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ if delta then
+ if d>0 then
+ return format("+%02i:00",d)
+ else
+ return format("-%02i:00",-d)
+ end
+ else
+ return 1
+ end
+end
+local timeformat=format("%%s%s",os.timezone(true))
+local dateformat="!%Y-%m-%d %H:%M:%S"
+local lasttime=nil
+local lastdate=nil
+function os.fulltime(t,default)
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=format(timeformat,date(dateformat))
+ end
+ return lastdate
+end
+local dateformat="%Y-%m-%d %H:%M:%S"
+local lasttime=nil
+local lastdate=nil
+function os.localtime(t,default)
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=date(dateformat,t)
+ end
+ return lastdate
+end
+function os.converttime(t,default)
+ local t=tonumber(t)
+ if t and t>0 then
+ return date(dateformat,t)
+ else
+ return default or "-"
+ end
+end
+local memory={}
+local function which(filename)
+ local fullname=memory[filename]
+ if fullname==nil then
+ local suffix=file.suffix(filename)
+ local suffixes=suffix=="" and os.binsuffixes or { suffix }
+ for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local df=file.join(directory,filename)
+ for i=1,#suffixes do
+ local dfs=file.addsuffix(df,suffixes[i])
+ if io.exists(dfs) then
+ fullname=dfs
+ break
+ end
+ end
+ end
+ if not fullname then
+ fullname=false
+ end
+ memory[filename]=fullname
+ end
+ return fullname
+end
+os.which=which
+os.where=which
+function os.today()
+ return date("!*t")
+end
+function os.now()
+ return date("!%Y-%m-%d %H:%M:%S")
+end
+if not os.sleep then
+ local socket=socket
+ function os.sleep(n)
+ if not socket then
+ socket=require("socket")
+ end
+ socket.sleep(n)
+ end
+end
+local function isleapyear(year)
+ return (year%4==0) and (year%100~=0 or year%400==0)
+end
+os.isleapyear=isleapyear
+local days={ 31,28,31,30,31,30,31,31,30,31,30,31 }
+local function nofdays(year,month)
+ if not month then
+ return isleapyear(year) and 365 or 364
+ else
+ return month==2 and isleapyear(year) and 29 or days[month]
+ end
+end
+os.nofdays=nofdays
+function os.weekday(day,month,year)
+ return date("%w",time { year=year,month=month,day=day })+1
+end
+function os.validdate(year,month,day)
+ if month<1 then
+ month=1
+ elseif month>12 then
+ month=12
+ end
+ if day<1 then
+ day=1
+ else
+ local max=nofdays(year,month)
+ if day>max then
+ day=max
+ end
+ end
+ return year,month,day
+end
+local osexit=os.exit
+local exitcode=nil
+function os.setexitcode(code)
+ exitcode=code
+end
+function os.exit(c)
+ if exitcode~=nil then
+ return osexit(exitcode)
+ end
+ if c~=nil then
+ return osexit(c)
+ end
+ return osexit()
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-file']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+file=file or {}
+local file=file
+if not lfs then
+ lfs=optionalrequire("lfs")
+end
+local insert,concat=table.insert,table.concat
+local match,find,gmatch=string.match,string.find,string.gmatch
+local lpegmatch=lpeg.match
+local getcurrentdir,attributes=lfs.currentdir,lfs.attributes
+local checkedsplit=string.checkedsplit
+local P,R,S,C,Cs,Cp,Cc,Ct=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cp,lpeg.Cc,lpeg.Ct
+local attributes=lfs.attributes
+function lfs.isdir(name)
+ return attributes(name,"mode")=="directory"
+end
+function lfs.isfile(name)
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
+end
+function lfs.isfound(name)
+ local a=attributes(name,"mode")
+ return (a=="file" or a=="link") and name or nil
+end
+if sandbox then
+ sandbox.redefine(lfs.isfile,"lfs.isfile")
+ sandbox.redefine(lfs.isdir,"lfs.isdir")
+ sandbox.redefine(lfs.isfound,"lfs.isfound")
+end
+local colon=P(":")
+local period=P(".")
+local periods=P("..")
+local fwslash=P("/")
+local bwslash=P("\\")
+local slashes=S("\\/")
+local noperiod=1-period
+local noslashes=1-slashes
+local name=noperiod^1
+local suffix=period/""*(1-period-slashes)^1*-1
+local pattern=C((1-(slashes^1*noslashes^1*-1))^1)*P(1)
+local function pathpart(name,default)
+ return name and lpegmatch(pattern,name) or default or ""
+end
+local pattern=(noslashes^0*slashes)^1*C(noslashes^1)*-1
+local function basename(name)
+ return name and lpegmatch(pattern,name) or name
+end
+local pattern=(noslashes^0*slashes^1)^0*Cs((1-suffix)^1)*suffix^0
+local function nameonly(name)
+ return name and lpegmatch(pattern,name) or name
+end
+local pattern=(noslashes^0*slashes)^0*(noperiod^1*period)^1*C(noperiod^1)*-1
+local function suffixonly(name)
+ return name and lpegmatch(pattern,name) or ""
+end
+local pattern=(noslashes^0*slashes)^0*noperiod^1*((period*C(noperiod^1))^1)*-1+Cc("")
+local function suffixesonly(name)
+ if name then
+ return lpegmatch(pattern,name)
+ else
+ return ""
+ end
+end
+file.pathpart=pathpart
+file.basename=basename
+file.nameonly=nameonly
+file.suffixonly=suffixonly
+file.suffix=suffixonly
+file.suffixesonly=suffixesonly
+file.suffixes=suffixesonly
+file.dirname=pathpart
+file.extname=suffixonly
+local drive=C(R("az","AZ"))*colon
+local path=C((noslashes^0*slashes)^0)
+local suffix=period*C(P(1-period)^0*P(-1))
+local base=C((1-suffix)^0)
+local rest=C(P(1)^0)
+drive=drive+Cc("")
+path=path+Cc("")
+base=base+Cc("")
+suffix=suffix+Cc("")
+local pattern_a=drive*path*base*suffix
+local pattern_b=path*base*suffix
+local pattern_c=C(drive*path)*C(base*suffix)
+local pattern_d=path*rest
+function file.splitname(str,splitdrive)
+ if not str then
+ elseif splitdrive then
+ return lpegmatch(pattern_a,str)
+ else
+ return lpegmatch(pattern_b,str)
+ end
+end
+function file.splitbase(str)
+ if str then
+ return lpegmatch(pattern_d,str)
+ else
+ return "",str
+ end
+end
+function file.nametotable(str,splitdrive)
+ if str then
+ local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
+ if splitdrive then
+ return {
+ path=path,
+ drive=drive,
+ subpath=subpath,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
+ else
+ return {
+ path=path,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
+ end
+ end
+end
+local pattern=Cs(((period*(1-period-slashes)^1*-1)/""+1)^1)
+function file.removesuffix(name)
+ return name and lpegmatch(pattern,name)
+end
+local suffix=period/""*(1-period-slashes)^1*-1
+local pattern=Cs((noslashes^0*slashes^1)^0*((1-suffix)^1))*Cs(suffix)
+function file.addsuffix(filename,suffix,criterium)
+ if not filename or not suffix or suffix=="" then
+ return filename
+ elseif criterium==true then
+ return filename.."."..suffix
+ elseif not criterium then
+ local n,s=lpegmatch(pattern,filename)
+ if not s or s=="" then
+ return filename.."."..suffix
+ else
+ return filename
+ end
+ else
+ local n,s=lpegmatch(pattern,filename)
+ if s and s~="" then
+ local t=type(criterium)
+ if t=="table" then
+ for i=1,#criterium do
+ if s==criterium[i] then
+ return filename
+ end
+ end
+ elseif t=="string" then
+ if s==criterium then
+ return filename
+ end
+ end
+ end
+ return (n or filename).."."..suffix
+ end
+end
+local suffix=period*(1-period-slashes)^1*-1
+local pattern=Cs((1-suffix)^0)
+function file.replacesuffix(name,suffix)
+ if name and suffix and suffix~="" then
+ return lpegmatch(pattern,name).."."..suffix
+ else
+ return name
+ end
+end
+local reslasher=lpeg.replacer(P("\\"),"/")
+function file.reslash(str)
+ return str and lpegmatch(reslasher,str)
+end
+if lfs.isreadablefile and lfs.iswritablefile then
+ file.is_readable=lfs.isreadablefile
+ file.is_writable=lfs.iswritablefile
+else
+ function file.is_writable(name)
+ if not name then
+ elseif lfs.isdir(name) then
+ name=name.."/m_t_x_t_e_s_t.tmp"
+ local f=io.open(name,"wb")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ elseif lfs.isfile(name) then
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ return true
+ end
+ else
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ end
+ return false
+ end
+ local readable=P("r")*Cc(true)
+ function file.is_readable(name)
+ if name then
+ local a=attributes(name)
+ return a and lpegmatch(readable,a.permissions) or false
+ else
+ return false
+ end
+ end
+end
+file.isreadable=file.is_readable
+file.iswritable=file.is_writable
+function file.size(name)
+ if name then
+ local a=attributes(name)
+ return a and a.size or 0
+ else
+ return 0
+ end
+end
+function file.splitpath(str,separator)
+ return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
+end
+function file.joinpath(tab,separator)
+ return tab and concat(tab,separator or io.pathseparator)
+end
+local someslash=S("\\/")
+local stripper=Cs(P(fwslash)^0/""*reslasher)
+local isnetwork=someslash*someslash*(1-someslash)+(1-fwslash-colon)^1*colon
+local isroot=fwslash^1*-1
+local hasroot=fwslash^1
+local reslasher=lpeg.replacer(S("\\/"),"/")
+local deslasher=lpeg.replacer(S("\\/")^1,"/")
+function file.join(one,two,three,...)
+ if not two then
+ return one=="" and one or lpegmatch(reslasher,one)
+ end
+ if one=="" then
+ return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
+ end
+ if lpegmatch(isnetwork,one) then
+ local one=lpegmatch(reslasher,one)
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return one..two
+ else
+ return one.."/"..two
+ end
+ elseif lpegmatch(isroot,one) then
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return two
+ else
+ return "/"..two
+ end
+ else
+ return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+ end
+end
+local drivespec=R("az","AZ")^1*colon
+local anchors=fwslash+drivespec
+local untouched=periods+(1-period)^1*P(-1)
+local mswindrive=Cs(drivespec*(bwslash/"/"+fwslash)^0)
+local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//")
+local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
+local absolute=fwslash
+function file.collapsepath(str,anchor)
+ if not str then
+ return
+ end
+ if anchor==true and not lpegmatch(anchors,str) then
+ str=getcurrentdir().."/"..str
+ end
+ if str=="" or str=="." then
+ return "."
+ elseif lpegmatch(untouched,str) then
+ return lpegmatch(reslasher,str)
+ end
+ local starter,oldelements=lpegmatch(splitstarter,str)
+ local newelements={}
+ local i=#oldelements
+ while i>0 do
+ local element=oldelements[i]
+ if element=='.' then
+ elseif element=='..' then
+ local n=i-1
+ while n>0 do
+ local element=oldelements[n]
+ if element~='..' and element~='.' then
+ oldelements[n]='.'
+ break
+ else
+ n=n-1
+ end
+ end
+ if n<1 then
+ insert(newelements,1,'..')
+ end
+ elseif element~="" then
+ insert(newelements,1,element)
+ end
+ i=i-1
+ end
+ if #newelements==0 then
+ return starter or "."
+ elseif starter then
+ return starter..concat(newelements,'/')
+ elseif lpegmatch(absolute,str) then
+ return "/"..concat(newelements,'/')
+ else
+ newelements=concat(newelements,'/')
+ if anchor=="." and find(str,"^%./") then
+ return "./"..newelements
+ else
+ return newelements
+ end
+ end
+end
+local validchars=R("az","09","AZ","--","..")
+local pattern_a=lpeg.replacer(1-validchars)
+local pattern_a=Cs((validchars+P(1)/"-")^1)
+local whatever=P("-")^0/""
+local pattern_b=Cs(whatever*(1-whatever*-1)^1)
+function file.robustname(str,strict)
+ if str then
+ str=lpegmatch(pattern_a,str) or str
+ if strict then
+ return lpegmatch(pattern_b,str) or str
+ else
+ return str
+ end
+ end
+end
+local loaddata=io.loaddata
+local savedata=io.savedata
+file.readdata=loaddata
+file.savedata=savedata
+function file.copy(oldname,newname)
+ if oldname and newname then
+ local data=loaddata(oldname)
+ if data and data~="" then
+ savedata(newname,data)
+ end
+ end
+end
+local letter=R("az","AZ")+S("_-+")
+local separator=P("://")
+local qualified=period^0*fwslash+letter*colon+letter^1*separator+letter^1*fwslash
+local rootbased=fwslash+letter*colon
+lpeg.patterns.qualified=qualified
+lpeg.patterns.rootbased=rootbased
+function file.is_qualified_path(filename)
+ return filename and lpegmatch(qualified,filename)~=nil
+end
+function file.is_rootbased_path(filename)
+ return filename and lpegmatch(rootbased,filename)~=nil
+end
+function file.strip(name,dir)
+ if name then
+ local b,a=match(name,"^(.-)"..dir.."(.*)$")
+ return a~="" and a or name
+ end
+end
+function lfs.mkdirs(path)
+ local full=""
+ for sub in gmatch(path,"(/*[^\\/]+)") do
+ full=full..sub
+ lfs.mkdir(full)
+ end
+end
+function file.withinbase(path)
+ local l=0
+ if not find(path,"^/") then
+ path="/"..path
+ end
+ for dir in gmatch(path,"/([^/]+)") do
+ if dir==".." then
+ l=l-1
+ elseif dir~="." then
+ l=l+1
+ end
+ if l<0 then
+ return false
+ end
+ end
+ return true
+end
+local symlinkattributes=lfs.symlinkattributes
+function lfs.readlink(name)
+ return symlinkattributes(name,"target") or nil
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-gzip']={
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if not gzip then
+ return
+end
+local suffix,suffixes=file.suffix,file.suffixes
+function gzip.load(filename)
+ local f=io.open(filename,"rb")
+ if not f then
+ elseif suffix(filename)=="gz" then
+ f:close()
+ local g=gzip.open(filename,"rb")
+ if g then
+ local str=g:read("*all")
+ g:close()
+ return str
+ end
+ else
+ local str=f:read("*all")
+ f:close()
+ return str
+ end
+end
+function gzip.save(filename,data)
+ if suffix(filename)~="gz" then
+ filename=filename..".gz"
+ end
+ local f=io.open(filename,"wb")
+ if f then
+ local s=zlib.compress(data or "",9,nil,15+16)
+ f:write(s)
+ f:close()
+ return #s
+ end
+end
+function gzip.suffix(filename)
+ local suffix,extra=suffixes(filename)
+ local gzipped=extra=="gz"
+ return suffix,gzipped
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-md5']={
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if not md5 then
+ md5=optionalrequire("md5")
+end
+if not md5 then
+ md5={
+ sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
+ sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
+ }
+end
+local md5,file=md5,file
+local gsub=string.gsub
+do
+ local patterns=lpeg and lpeg.patterns
+ if patterns then
+ local bytestoHEX=patterns.bytestoHEX
+ local bytestohex=patterns.bytestohex
+ local bytestodec=patterns.bytestodec
+ local lpegmatch=lpeg.match
+ local md5sum=md5.sum
+ if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
+ if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
+ if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
+ md5.sumhexa=md5.hex
+ md5.sumHEXA=md5.HEX
+ end
+end
+function file.needsupdating(oldname,newname,threshold)
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime then
+ local newtime=lfs.attributes(newname,"modification")
+ if not newtime then
+ return true
+ elseif newtime>=oldtime then
+ return false
+ elseif oldtime-newtime<(threshold or 1) then
+ return false
+ else
+ return true
+ end
+ else
+ return false
+ end
+end
+file.needs_updating=file.needsupdating
+function file.syncmtimes(oldname,newname)
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime and lfs.isfile(newname) then
+ lfs.touch(newname,oldtime,oldtime)
+ end
+end
+function file.checksum(name)
+ if md5 then
+ local data=io.loaddata(name)
+ if data then
+ return md5.HEX(data)
+ end
+ end
+ return nil
+end
+function file.loadchecksum(name)
+ if md5 then
+ local data=io.loaddata(name..".md5")
+ return data and (gsub(data,"%s",""))
+ end
+ return nil
+end
+function file.savechecksum(name,checksum)
+ if not checksum then checksum=file.checksum(name) end
+ if checksum then
+ io.savedata(name..".md5",checksum)
+ return checksum
+ end
+ return nil
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-dir']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local type,select=type,select
+local find,gmatch,match,gsub,sub=string.find,string.gmatch,string.match,string.gsub,string.sub
+local concat,insert,remove,unpack=table.concat,table.insert,table.remove,table.unpack
+local lpegmatch=lpeg.match
+local P,S,R,C,Cc,Cs,Ct,Cv,V=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cc,lpeg.Cs,lpeg.Ct,lpeg.Cv,lpeg.V
+dir=dir or {}
+local dir=dir
+local lfs=lfs
+local attributes=lfs.attributes
+local walkdir=lfs.dir
+local isdir=lfs.isdir
+local isfile=lfs.isfile
+local currentdir=lfs.currentdir
+local chdir=lfs.chdir
+local mkdir=lfs.mkdir
+local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true)
+if onwindows then
+ local tricky=S("/\\")*P(-1)
+ isdir=function(name)
+ if lpegmatch(tricky,name) then
+ return attributes(name,"mode")=="directory"
+ else
+ return attributes(name.."/.","mode")=="directory"
+ end
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
+else
+ isdir=function(name)
+ return attributes(name,"mode")=="directory"
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
+end
+function dir.current()
+ return (gsub(currentdir(),"\\","/"))
+end
+local function glob_pattern_function(path,patt,recurse,action)
+ if isdir(path) then
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ for name,mode,size,time in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ if mode==nil then
+ mode=attributes(full,'mode')
+ end
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ action(full,size,time)
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
+ end
+ end
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_function(dirs[i],patt,recurse,action)
+ end
+ end
+ end
+end
+local function glob_pattern_table(path,patt,recurse,result)
+ if not result then
+ result={}
+ end
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ local noffiles=#result
+ for name,mode in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ if mode==nil then
+ mode=attributes(full,'mode')
+ end
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ noffiles=noffiles+1
+ result[noffiles]=full
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
+ end
+ end
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_table(dirs[i],patt,recurse,result)
+ end
+ end
+ return result
+end
+local function globpattern(path,patt,recurse,method)
+ local kind=type(method)
+ if patt and sub(patt,1,-3)==path then
+ patt=false
+ end
+ local okay=isdir(path)
+ if kind=="function" then
+ return okay and glob_pattern_function(path,patt,recurse,method) or {}
+ elseif kind=="table" then
+ return okay and glob_pattern_table(path,patt,recurse,method) or method
+ else
+ return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
+end
+dir.globpattern=globpattern
+local function collectpattern(path,patt,recurse,result)
+ local ok,scanner
+ result=result or {}
+ if path=="/" then
+ ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
+ else
+ ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
+ end
+ if ok and type(scanner)=="function" then
+ if not find(path,"/$") then
+ path=path..'/'
+ end
+ for name in scanner,first do
+ if name=="." then
+ elseif name==".." then
+ else
+ local full=path..name
+ local attr=attributes(full)
+ local mode=attr.mode
+ if mode=='file' then
+ if find(full,patt) then
+ result[name]=attr
+ end
+ elseif recurse and mode=="directory" then
+ attr.list=collectpattern(full,patt,recurse)
+ result[name]=attr
+ end
+ end
+ end
+ end
+ return result
+end
+dir.collectpattern=collectpattern
+local separator,pattern
+if onwindows then
+ local slash=S("/\\")/"/"
+ pattern={
+ [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
+ [3]=Cs(P(1)^0)
+ }
+else
+ pattern={
+ [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ [2]=C(((1-S("*?/"))^0*P("/"))^0),
+ [3]=C(P(1)^0)
+ }
+end
+local filter=Cs ((
+ P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
+)^0 )
+local function glob(str,t)
+ if type(t)=="function" then
+ if type(str)=="table" then
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ elseif isfile(str) then
+ t(str)
+ else
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ globpattern(start,result,recurse,t)
+ end
+ end
+ else
+ if type(str)=="table" then
+ local t=t or {}
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ return t
+ elseif isfile(str) then
+ if t then
+ t[#t+1]=str
+ return t
+ else
+ return { str }
+ end
+ else
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ return globpattern(start,result,recurse,t)
+ else
+ return {}
+ end
+ end
+ end
+end
+dir.glob=glob
+local function globfiles(path,recurse,func,files)
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name,mode in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ if mode==nil then
+ mode=attributes(name,'mode')
+ end
+ if mode=="directory" then
+ if recurse then
+ globfiles(path.."/"..name,recurse,func,files)
+ end
+ elseif mode=="file" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
+ end
+ end
+ end
+ end
+ return files
+end
+dir.globfiles=globfiles
+local function globdirs(path,recurse,func,files)
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name,mode in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ if mode==nil then
+ mode=attributes(name,'mode')
+ end
+ if mode=="directory" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
+ if recurse then
+ globdirs(path.."/"..name,recurse,func,files)
+ end
+ end
+ end
+ end
+ end
+ return files
+end
+dir.globdirs=globdirs
+function dir.ls(pattern)
+ return concat(glob(pattern),"\n")
+end
+local make_indeed=true
+if onwindows then
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s=="" then
+ elseif str=="" then
+ str=s
+ else
+ str=str.."/"..s
+ end
+ end
+ end
+ local pth=""
+ local drive=false
+ local first,middle,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ else
+ first,last=match(str,"^(//)/*(.-)$")
+ if first then
+ middle,last=match(str,"([^/]+)/+(.-)$")
+ if middle then
+ pth="//"..middle
+ else
+ pth="//"..last
+ last=""
+ end
+ else
+ first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
+ if first then
+ pth,drive=first..middle,true
+ else
+ middle,last=match(str,"^(/*)(.-)$")
+ if not middle then
+ last=str
+ end
+ end
+ end
+ end
+ for s in gmatch(last,"[^/]+") do
+ if pth=="" then
+ pth=s
+ elseif drive then
+ pth,drive=pth..s,false
+ else
+ pth=pth.."/"..s
+ end
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ return pth,(isdir(pth)==true)
+ end
+else
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str,pth
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s and s~="" then
+ if str~="" then
+ str=str.."/"..s
+ else
+ str=s
+ end
+ end
+ end
+ end
+ str=gsub(str,"/+","/")
+ if find(str,"^/") then
+ pth="/"
+ for s in gmatch(str,"[^/]+") do
+ local first=(pth=="/")
+ if first then
+ pth=pth..s
+ else
+ pth=pth.."/"..s
+ end
+ if make_indeed and not first and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ else
+ pth="."
+ for s in gmatch(str,"[^/]+") do
+ pth=pth.."/"..s
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ end
+ return pth,(isdir(pth)==true)
+ end
+end
+dir.makedirs=dir.mkdirs
+do
+ local chdir=sandbox and sandbox.original(chdir) or chdir
+ if onwindows then
+ local xcurrentdir=dir.current
+ function dir.expandname(str)
+ local first,nothing,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ first=xcurrentdir().."/"
+ end
+ if not first then
+ first,last=match(str,"^(//)/*(.*)$")
+ end
+ if not first then
+ first,last=match(str,"^([a-zA-Z]:)(.*)$")
+ if first and not find(last,"^/") then
+ local d=currentdir()
+ if chdir(first) then
+ first=xcurrentdir()
+ end
+ chdir(d)
+ end
+ end
+ if not first then
+ first,last=xcurrentdir(),str
+ end
+ last=gsub(last,"//","/")
+ last=gsub(last,"/%./","/")
+ last=gsub(last,"^/*","")
+ first=gsub(first,"/*$","")
+ if last=="" or last=="." then
+ return first
+ else
+ return first.."/"..last
+ end
+ end
+ else
+ function dir.expandname(str)
+ if not find(str,"^/") then
+ str=currentdir().."/"..str
+ end
+ str=gsub(str,"//","/")
+ str=gsub(str,"/%./","/")
+ str=gsub(str,"(.)/%.$","%1")
+ return str
+ end
+ end
+end
+file.expandname=dir.expandname
+local stack={}
+function dir.push(newdir)
+ local curdir=currentdir()
+ insert(stack,curdir)
+ if newdir and newdir~="" and chdir(newdir) then
+ return newdir
+ else
+ return curdir
+ end
+end
+function dir.pop()
+ local d=remove(stack)
+ if d then
+ chdir(d)
+ end
+ return d
+end
+local function found(...)
+ for i=1,select("#",...) do
+ local path=select(i,...)
+ local kind=type(path)
+ if kind=="string" then
+ if isdir(path) then
+ return path
+ end
+ elseif kind=="table" then
+ local path=found(unpack(path))
+ if path then
+ return path
+ end
+ end
+ end
+end
+dir.found=found
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-unicode']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+utf=utf or {}
+if not string.utfcharacters then
+ local gmatch=string.gmatch
+ function string.characters(str)
+ return gmatch(str,".[\128-\191]*")
+ end
+end
+utf.characters=string.utfcharacters
+local type=type
+local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch
+local concat=table.concat
+local P,C,R,Cs,Ct,Cmt,Cc,Carg,Cp=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Ct,lpeg.Cmt,lpeg.Cc,lpeg.Carg,lpeg.Cp
+local lpegmatch=lpeg.match
+local patterns=lpeg.patterns
+local tabletopattern=lpeg.utfchartabletopattern
+local bytepairs=string.bytepairs
+local finder=lpeg.finder
+local replacer=lpeg.replacer
+local p_utftype=patterns.utftype
+local p_utfstricttype=patterns.utfstricttype
+local p_utfoffset=patterns.utfoffset
+local p_utf8character=patterns.utf8character
+local p_utf8char=patterns.utf8char
+local p_utf8byte=patterns.utf8byte
+local p_utfbom=patterns.utfbom
+local p_newline=patterns.newline
+local p_whitespace=patterns.whitespace
+if not utf.char then
+ utf.char=string.utfcharacter or (utf8 and utf8.char)
+ if not utf.char then
+ local char=string.char
+ if bit32 then
+ local rshift=bit32.rshift
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+rshift(n,6),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+rshift(n,12),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+rshift(n,18),
+ 0x80+(rshift(n,12)%0x40),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
+ else
+ return ""
+ end
+ end
+ else
+ local floor=math.floor
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+floor(n/0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+floor(n/0x1000),
+ 0x80+(floor(n/0x40)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+floor(n/0x40000),
+ 0x80+(floor(n/0x1000)%0x40),
+ 0x80+(floor(n/0x40)%0x40),
+ 0x80+(n%0x40)
+ )
+ else
+ return ""
+ end
+ end
+ end
+ end
+end
+if not utf.byte then
+ utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
+ if not utf.byte then
+ function utf.byte(c)
+ return lpegmatch(p_utf8byte,c)
+ end
+ end
+end
+local utfchar,utfbyte=utf.char,utf.byte
+function utf.filetype(data)
+ return data and lpegmatch(p_utftype,data) or "unknown"
+end
+local toentities=Cs (
+ (
+ patterns.utf8one+(
+ patterns.utf8two+patterns.utf8three+patterns.utf8four
+ )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
+ )^0
+)
+patterns.toentities=toentities
+function utf.toentities(str)
+ return lpegmatch(toentities,str)
+end
+local one=P(1)
+local two=C(1)*C(1)
+local four=C(R(utfchar(0xD8),utfchar(0xFF)))*C(1)*C(1)*C(1)
+local pattern=P("\254\255")*Cs((
+ four/function(a,b,c,d)
+ local ab=0xFF*byte(a)+byte(b)
+ local cd=0xFF*byte(c)+byte(d)
+ return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+ end+two/function(a,b)
+ return utfchar(byte(a)*256+byte(b))
+ end+one
+ )^1 )+P("\255\254")*Cs((
+ four/function(b,a,d,c)
+ local ab=0xFF*byte(a)+byte(b)
+ local cd=0xFF*byte(c)+byte(d)
+ return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+ end+two/function(b,a)
+ return utfchar(byte(a)*256+byte(b))
+ end+one
+ )^1 )
+function string.toutf(s)
+ return lpegmatch(pattern,s) or s
+end
+local validatedutf=Cs (
+ (
+ patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
+ )^0
+)
+patterns.validatedutf=validatedutf
+function utf.is_valid(str)
+ return type(str)=="string" and lpegmatch(validatedutf,str) or false
+end
+if not utf.len then
+ utf.len=string.utflength or (utf8 and utf8.len)
+ if not utf.len then
+ local n,f=0,1
+ local utfcharcounter=patterns.utfbom^-1*Cmt (
+ Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
+ function(_,t,d)
+ n=n+(t-f)/d
+ f=t
+ return true
+ end
+ )^0
+ function utf.len(str)
+ n,f=0,1
+ lpegmatch(utfcharcounter,str or "")
+ return n
+ end
+ end
+end
+utf.length=utf.len
+if not utf.sub then
+ local utflength=utf.length
+ local b,e,n,first,last=0,0,0,0,0
+ local function slide_zero(s,p)
+ n=n+1
+ if n>=last then
+ e=p-1
+ else
+ return p
+ end
+ end
+ local function slide_one(s,p)
+ n=n+1
+ if n==first then
+ b=p
+ end
+ if n>=last then
+ e=p-1
+ else
+ return p
+ end
+ end
+ local function slide_two(s,p)
+ n=n+1
+ if n==first then
+ b=p
+ else
+ return true
+ end
+ end
+ local pattern_zero=Cmt(p_utf8character,slide_zero)^0
+ local pattern_one=Cmt(p_utf8character,slide_one )^0
+ local pattern_two=Cmt(p_utf8character,slide_two )^0
+ local pattern_first=C(p_utf8character)
+ function utf.sub(str,start,stop)
+ if not start then
+ return str
+ end
+ if start==0 then
+ start=1
+ end
+ if not stop then
+ if start<0 then
+ local l=utflength(str)
+ start=l+start
+ else
+ start=start-1
+ end
+ b,n,first=0,0,start
+ lpegmatch(pattern_two,str)
+ if n>=first then
+ return sub(str,b)
+ else
+ return ""
+ end
+ end
+ if start<0 or stop<0 then
+ local l=utf.length(str)
+ if start<0 then
+ start=l+start
+ if start<=0 then
+ start=1
+ else
+ start=start+1
+ end
+ end
+ if stop<0 then
+ stop=l+stop
+ if stop==0 then
+ stop=1
+ else
+ stop=stop+1
+ end
+ end
+ end
+ if start==1 and stop==1 then
+ return lpegmatch(pattern_first,str) or ""
+ elseif start>stop then
+ return ""
+ elseif start>1 then
+ b,e,n,first,last=0,0,0,start-1,stop
+ lpegmatch(pattern_one,str)
+ if n>=first and e==0 then
+ e=#str
+ end
+ return sub(str,b,e)
+ else
+ b,e,n,last=1,0,0,stop
+ lpegmatch(pattern_zero,str)
+ if e==0 then
+ e=#str
+ end
+ return sub(str,b,e)
+ end
+ end
+end
+function utf.remapper(mapping,option,action)
+ local variant=type(mapping)
+ if variant=="table" then
+ action=action or mapping
+ if option=="dynamic" then
+ local pattern=false
+ table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ if not pattern then
+ pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ end
+ return lpegmatch(pattern,str)
+ end
+ end
+ elseif option=="pattern" then
+ return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ else
+ local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
+ end
+ end,pattern
+ end
+ elseif variant=="function" then
+ if option=="pattern" then
+ return Cs((p_utf8character/mapping+p_utf8character)^0)
+ else
+ local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
+ end
+ end,pattern
+ end
+ else
+ return function(str)
+ return str or ""
+ end
+ end
+end
+function utf.replacer(t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ return lpegmatch(r,str)
+ end
+end
+function utf.subtituter(t)
+ local f=finder (t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ local i=lpegmatch(f,str)
+ if not i then
+ return str
+ elseif i>#str then
+ return str
+ else
+ return lpegmatch(r,str)
+ end
+ end
+end
+local utflinesplitter=p_utfbom^-1*lpeg.tsplitat(p_newline)
+local utfcharsplitter_ows=p_utfbom^-1*Ct(C(p_utf8character)^0)
+local utfcharsplitter_iws=p_utfbom^-1*Ct((p_whitespace^1+C(p_utf8character))^0)
+local utfcharsplitter_raw=Ct(C(p_utf8character)^0)
+patterns.utflinesplitter=utflinesplitter
+function utf.splitlines(str)
+ return lpegmatch(utflinesplitter,str or "")
+end
+function utf.split(str,ignorewhitespace)
+ if ignorewhitespace then
+ return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+ return lpegmatch(utfcharsplitter_ows,str or "")
+ end
+end
+function utf.totable(str)
+ return lpegmatch(utfcharsplitter_raw,str)
+end
+function utf.magic(f)
+ local str=f:read(4) or ""
+ local off=lpegmatch(p_utfoffset,str)
+ if off<4 then
+ f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
+end
+local utf16_to_utf8_be,utf16_to_utf8_le
+local utf32_to_utf8_be,utf32_to_utf8_le
+local utf_16_be_getbom=patterns.utfbom_16_be^-1
+local utf_16_le_getbom=patterns.utfbom_16_le^-1
+local utf_32_be_getbom=patterns.utfbom_32_be^-1
+local utf_32_le_getbom=patterns.utfbom_32_le^-1
+local utf_16_be_linesplitter=utf_16_be_getbom*lpeg.tsplitat(patterns.utf_16_be_nl)
+local utf_16_le_linesplitter=utf_16_le_getbom*lpeg.tsplitat(patterns.utf_16_le_nl)
+local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_nl)
+local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
+local more=0
+local p_utf16_to_utf8_be=C(1)*C(1)/function(left,right)
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ return ""
+ else
+ return utfchar(now)
+ end
+end
+local p_utf16_to_utf8_le=C(1)*C(1)/function(right,left)
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ return ""
+ else
+ return utfchar(now)
+ end
+end
+local p_utf32_to_utf8_be=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
+ return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
+end
+local p_utf32_to_utf8_le=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
+ return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
+end
+p_utf16_to_utf8_be=P(true)/function() more=0 end*utf_16_be_getbom*Cs(p_utf16_to_utf8_be^0)
+p_utf16_to_utf8_le=P(true)/function() more=0 end*utf_16_le_getbom*Cs(p_utf16_to_utf8_le^0)
+p_utf32_to_utf8_be=P(true)/function() more=0 end*utf_32_be_getbom*Cs(p_utf32_to_utf8_be^0)
+p_utf32_to_utf8_le=P(true)/function() more=0 end*utf_32_le_getbom*Cs(p_utf32_to_utf8_le^0)
+patterns.utf16_to_utf8_be=p_utf16_to_utf8_be
+patterns.utf16_to_utf8_le=p_utf16_to_utf8_le
+patterns.utf32_to_utf8_be=p_utf32_to_utf8_be
+patterns.utf32_to_utf8_le=p_utf32_to_utf8_le
+utf16_to_utf8_be=function(s)
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+ return s
+ end
+end
+local utf16_to_utf8_be_t=function(t)
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_16_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf16_to_utf8_be,s)
+ end
+ end
+ return t
+end
+utf16_to_utf8_le=function(s)
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+ return s
+ end
+end
+local utf16_to_utf8_le_t=function(t)
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_16_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf16_to_utf8_le,s)
+ end
+ end
+ return t
+end
+utf32_to_utf8_be=function(s)
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+ return s
+ end
+end
+local utf32_to_utf8_be_t=function(t)
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_32_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf32_to_utf8_be,s)
+ end
+ end
+ return t
+end
+utf32_to_utf8_le=function(s)
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+ return s
+ end
+end
+local utf32_to_utf8_le_t=function(t)
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_32_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf32_to_utf8_le,s)
+ end
+ end
+ return t
+end
+utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
+utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
+utf.utf32_to_utf8_le_t=utf32_to_utf8_le_t
+utf.utf32_to_utf8_be_t=utf32_to_utf8_be_t
+utf.utf16_to_utf8_le=utf16_to_utf8_le
+utf.utf16_to_utf8_be=utf16_to_utf8_be
+utf.utf32_to_utf8_le=utf32_to_utf8_le
+utf.utf32_to_utf8_be=utf32_to_utf8_be
+function utf.utf8_to_utf8_t(t)
+ return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
+end
+function utf.utf16_to_utf8_t(t,endian)
+ return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
+end
+function utf.utf32_to_utf8_t(t,endian)
+ return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
+end
+local function little(b)
+ if b<0x10000 then
+ return char(b%256,rshift(b,8))
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
+end
+local function big(b)
+ if b<0x10000 then
+ return char(rshift(b,8),b%256)
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
+end
+local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
+local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
+local function utf8_to_utf16_be(str,nobom)
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
+end
+local function utf8_to_utf16_le(str,nobom)
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
+end
+utf.utf8_to_utf16_be=utf8_to_utf16_be
+utf.utf8_to_utf16_le=utf8_to_utf16_le
+function utf.utf8_to_utf16(str,littleendian,nobom)
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
+end
+local pattern=Cs (
+ (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
+)
+function utf.tocodes(str,separator)
+ return lpegmatch(pattern,str,1,separator or " ")
+end
+function utf.ustring(s)
+ return format("U+%05X",type(s)=="number" and s or utfbyte(s))
+end
+function utf.xstring(s)
+ return format("0x%05X",type(s)=="number" and s or utfbyte(s))
+end
+function utf.toeight(str)
+ if not str or str=="" then
+ return nil
+ end
+ local utftype=lpegmatch(p_utfstricttype,str)
+ if utftype=="utf-8" then
+ return sub(str,4)
+ elseif utftype=="utf-16-be" then
+ return utf16_to_utf8_be(str)
+ elseif utftype=="utf-16-le" then
+ return utf16_to_utf8_le(str)
+ else
+ return str
+ end
+end
+do
+ local p_nany=p_utf8character/""
+ local cache={}
+ function utf.count(str,what)
+ if type(what)=="string" then
+ local p=cache[what]
+ if not p then
+ p=Cs((P(what)/" "+p_nany)^0)
+ cache[p]=p
+ end
+ return #lpegmatch(p,str)
+ else
+ return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
+ end
+ end
+end
+if not string.utfvalues then
+ local find=string.find
+ local dummy=function()
+ end
+ function string.utfvalues(str)
+ local n=#str
+ if n==0 then
+ return dummy
+ elseif n==1 then
+ return function() return utfbyte(str) end
+ else
+ local p=1
+ return function()
+ local b,e=find(str,".[\128-\191]*",p)
+ if b then
+ p=e+1
+ return utfbyte(sub(str,b,e))
+ end
+ end
+ end
+ end
+end
+utf.values=string.utfvalues
+function utf.chrlen(u)
+ return
+ (u<0x80 and 1) or
+ (u<0xE0 and 2) or
+ (u<0xF0 and 3) or
+ (u<0xF8 and 4) or
+ (u<0xFC and 5) or
+ (u<0xFE and 6) or 0
+end
+if bit32 then
+ local extract=bit32.extract
+ local char=string.char
+ function utf.toutf32string(n)
+ if n<=0xFF then
+ return
+ char(n).."\000\000\000"
+ elseif n<=0xFFFF then
+ return
+ char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
+ elseif n<=0xFFFFFF then
+ return
+ char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
+ else
+ return
+ char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
+ end
+ end
+end
+local len=utf.len
+local rep=rep
+function string.utfpadd(s,n)
+ if n and n~=0 then
+ local l=len(s)
+ if n>0 then
+ local d=n-l
+ if d>0 then
+ return rep(c or " ",d)..s
+ end
+ else
+ local d=- n-l
+ if d>0 then
+ return s..rep(c or " ",d)
+ end
+ end
+ end
+ return s
+end
+do
+ local utfcharacters=utf.characters or string.utfcharacters
+ local utfchar=utf.char or string.utfcharacter
+ lpeg.UP=P
+ if utfcharacters then
+ function lpeg.US(str)
+ local p=P(false)
+ for uc in utfcharacters(str) do
+ p=p+P(uc)
+ end
+ return p
+ end
+ else
+ function lpeg.US(str)
+ local p=P(false)
+ local f=function(uc)
+ p=p+P(uc)
+ end
+ lpegmatch((p_utf8char/f)^0,str)
+ return p
+ end
+ end
+ local range=p_utf8byte*p_utf8byte+Cc(false)
+ function lpeg.UR(str,more)
+ local first,last
+ if type(str)=="number" then
+ first=str
+ last=more or first
+ else
+ first,last=lpegmatch(range,str)
+ if not last then
+ return P(str)
+ end
+ end
+ if first==last then
+ return P(str)
+ end
+ if not utfchar then
+ utfchar=utf.char
+ end
+ if utfchar and (last-first<8) then
+ local p=P(false)
+ for i=first,last do
+ p=p+P(utfchar(i))
+ end
+ return p
+ else
+ local f=function(b)
+ return b>=first and b<=last
+ end
+ return p_utf8byte/f
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-url']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local char,format,byte=string.char,string.format,string.byte
+local concat=table.concat
+local tonumber,type,next=tonumber,type,next
+local P,C,R,S,Cs,Cc,Ct,Cf,Cg,V=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Cf,lpeg.Cg,lpeg.V
+local lpegmatch,lpegpatterns,replacer=lpeg.match,lpeg.patterns,lpeg.replacer
+local sortedhash=table.sortedhash
+url=url or {}
+local url=url
+local unescapes={}
+local escapes={}
+setmetatable(unescapes,{ __index=function(t,k)
+ local v=char(tonumber(k,16))
+ t[k]=v
+ return v
+end })
+setmetatable(escapes,{ __index=function(t,k)
+ local v=format("%%%02X",byte(k))
+ t[k]=v
+ return v
+end })
+local colon=P(":")
+local qmark=P("?")
+local hash=P("#")
+local slash=P("/")
+local atsign=P("@")
+local percent=P("%")
+local endofstring=P(-1)
+local hexdigit=R("09","AF","af")
+local plus=P("+")
+local nothing=Cc("")
+local okay=R("09","AZ","az")+S("-_.,:=+*~!'()@&$")
+local escapedchar=(percent*C(hexdigit*hexdigit))/unescapes
+local unescapedchar=P(1)/escapes
+local escaped=(plus/" ")+escapedchar
+local noslash=P("/")/""
+local plustospace=P("+")/" "
+local decoder=Cs((
+ plustospace+escapedchar+P("\r\n")/"\n"+P(1)
+ )^0 )
+local encoder=Cs((
+ R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
+ )^0 )
+lpegpatterns.urldecoder=decoder
+lpegpatterns.urlencoder=encoder
+function url.decode (str) return str and lpegmatch(decoder,str) or str end
+function url.encode (str) return str and lpegmatch(encoder,str) or str end
+function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
+local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2)
+local authoritystr=Cs((escaped+(1- slash-qmark-hash))^0)
+local pathstr=Cs((escaped+(1- qmark-hash))^0)
+local querystr=Cs(((1- hash))^0)
+local fragmentstr=Cs((escaped+(1- endofstring))^0)
+local scheme=schemestr*colon+nothing
+local authority=slash*slash*authoritystr+nothing
+local path=slash*pathstr+nothing
+local query=qmark*querystr+nothing
+local fragment=hash*fragmentstr+nothing
+local validurl=scheme*authority*path*query*fragment
+local parser=Ct(validurl)
+lpegpatterns.url=validurl
+lpegpatterns.urlsplitter=parser
+local escaper=Cs((R("09","AZ","az")^1+P(" ")/"%%20"+S("-./_:")^1+P(1)/escapes)^0)
+local unescaper=Cs((escapedchar+1)^0)
+local getcleaner=Cs((P("+++")/"%%2B"+P("+")/"%%20"+P(1))^1)
+lpegpatterns.urlunescaped=escapedchar
+lpegpatterns.urlescaper=escaper
+lpegpatterns.urlunescaper=unescaper
+lpegpatterns.urlgetcleaner=getcleaner
+function url.unescapeget(str)
+ return lpegmatch(getcleaner,str)
+end
+local function split(str)
+ return (type(str)=="string" and lpegmatch(parser,str)) or str
+end
+local isscheme=schemestr*colon*slash*slash
+local function hasscheme(str)
+ if str then
+ local scheme=lpegmatch(isscheme,str)
+ return scheme~="" and scheme or false
+ else
+ return false
+ end
+end
+local rootletter=R("az","AZ")+S("_-+")
+local separator=P("://")
+local qualified=P(".")^0*P("/")+rootletter*P(":")+rootletter^1*separator+rootletter^1*P("/")
+local rootbased=P("/")+rootletter*P(":")
+local barswapper=replacer("|",":")
+local backslashswapper=replacer("\\","/")
+local equal=P("=")
+local amp=P("&")
+local key=Cs(((plustospace+escapedchar+1)-equal )^0)
+local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0)
+local splitquery=Cf (Ct("")*P { "sequence",
+ sequence=V("pair")*(amp*V("pair"))^0,
+ pair=Cg(key*equal*value),
+},rawset)
+local userpart=(1-atsign-colon)^1
+local serverpart=(1-colon)^1
+local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil))
+local function hashed(str)
+ if not str or str=="" then
+ return {
+ scheme="invalid",
+ original=str,
+ }
+ end
+ local detailed=split(str)
+ local rawscheme=""
+ local rawquery=""
+ local somescheme=false
+ local somequery=false
+ if detailed then
+ rawscheme=detailed[1]
+ rawquery=detailed[4]
+ somescheme=rawscheme~=""
+ somequery=rawquery~=""
+ end
+ if not somescheme and not somequery then
+ return {
+ scheme="file",
+ authority="",
+ path=str,
+ query="",
+ fragment="",
+ original=str,
+ noscheme=true,
+ filename=str,
+ }
+ end
+ local authority=detailed[2]
+ local path=detailed[3]
+ local filename
+ local username
+ local password
+ local host
+ local port
+ if authority~="" then
+ username,password,host,port=lpegmatch(splitauthority,authority)
+ end
+ if authority=="" then
+ filename=path
+ elseif path=="" then
+ filename=""
+ else
+ filename=authority.."/"..path
+ end
+ return {
+ scheme=rawscheme,
+ authority=authority,
+ path=path,
+ query=lpegmatch(unescaper,rawquery),
+ queries=lpegmatch(splitquery,rawquery),
+ fragment=detailed[5],
+ original=str,
+ noscheme=false,
+ filename=filename,
+ host=host,
+ port=port,
+ }
+end
+url.split=split
+url.hasscheme=hasscheme
+url.hashed=hashed
+function url.addscheme(str,scheme)
+ if hasscheme(str) then
+ return str
+ elseif not scheme then
+ return "file:///"..str
+ else
+ return scheme..":///"..str
+ end
+end
+function url.construct(hash)
+ local result,r={},0
+ local scheme=hash.scheme
+ local authority=hash.authority
+ local path=hash.path
+ local queries=hash.queries
+ local fragment=hash.fragment
+ if scheme and scheme~="" then
+ r=r+1;result[r]=lpegmatch(escaper,scheme)
+ r=r+1;result[r]="://"
+ end
+ if authority and authority~="" then
+ r=r+1;result[r]=lpegmatch(escaper,authority)
+ end
+ if path and path~="" then
+ r=r+1;result[r]="/"
+ r=r+1;result[r]=lpegmatch(escaper,path)
+ end
+ if queries then
+ local done=false
+ for k,v in sortedhash(queries) do
+ r=r+1;result[r]=done and "&" or "?"
+ r=r+1;result[r]=lpegmatch(escaper,k)
+ r=r+1;result[r]="="
+ r=r+1;result[r]=lpegmatch(escaper,v)
+ done=true
+ end
+ end
+ if fragment and fragment~="" then
+ r=r+1;result[r]="#"
+ r=r+1;result[r]=lpegmatch(escaper,fragment)
+ end
+ return concat(result)
+end
+local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0)
+function url.filename(filename)
+ local spec=hashed(filename)
+ local path=spec.path
+ return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
+end
+local function escapestring(str)
+ return lpegmatch(escaper,str)
+end
+url.escape=escapestring
+function url.query(str)
+ if type(str)=="string" then
+ return lpegmatch(splitquery,str) or ""
+ else
+ return str
+ end
+end
+function url.toquery(data)
+ local td=type(data)
+ if td=="string" then
+ return #str and escape(data) or nil
+ elseif td=="table" then
+ if next(data) then
+ local t={}
+ for k,v in next,data do
+ t[#t+1]=format("%s=%s",k,escapestring(v))
+ end
+ return concat(t,"&")
+ end
+ else
+ end
+end
+local pattern=Cs(noslash^0*(1-noslash*P(-1))^0)
+function url.barepath(path)
+ if not path or path=="" then
+ return ""
+ else
+ return lpegmatch(pattern,path)
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-set']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+set=set or {}
+local nums={}
+local tabs={}
+local concat=table.concat
+local next,type=next,type
+set.create=table.tohash
+function set.tonumber(t)
+ if next(t) then
+ local s=""
+ for k,v in next,t do
+ if v then
+ s=s.." "..k
+ end
+ end
+ local n=nums[s]
+ if not n then
+ n=#tabs+1
+ tabs[n]=t
+ nums[s]=n
+ end
+ return n
+ else
+ return 0
+ end
+end
+function set.totable(n)
+ if n==0 then
+ return {}
+ else
+ return tabs[n] or {}
+ end
+end
+function set.tolist(n)
+ if n==0 or not tabs[n] then
+ return ""
+ else
+ local t,n={},0
+ for k,v in next,tabs[n] do
+ if v then
+ n=n+1
+ t[n]=k
+ end
+ end
+ return concat(t," ")
+ end
+end
+function set.contains(n,s)
+ if type(n)=="table" then
+ return n[s]
+ elseif n==0 then
+ return false
+ else
+ local t=tabs[n]
+ return t and t[s]
+ end
+end
+
+end -- closure
diff --git a/macros/luatex/generic/lualibs/lualibs-boolean.lua b/macros/luatex/generic/lualibs/lualibs-boolean.lua
new file mode 100644
index 0000000000..8f18d4c003
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-boolean.lua
@@ -0,0 +1,69 @@
+if not modules then modules = { } end modules ['l-boolean'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type, tonumber = type, tonumber
+
+boolean = boolean or { }
+local boolean = boolean
+
+function boolean.tonumber(b)
+ if b then return 1 else return 0 end -- test and return or return
+end
+
+function toboolean(str,tolerant) -- global
+ if str == nil then
+ return false
+ elseif str == false then
+ return false
+ elseif str == true then
+ return true
+ elseif str == "true" then
+ return true
+ elseif str == "false" then
+ return false
+ elseif not tolerant then
+ return false
+ elseif str == 0 then
+ return false
+ elseif (tonumber(str) or 0) > 0 then
+ return true
+ else
+ return str == "yes" or str == "on" or str == "t"
+ end
+end
+
+string.toboolean = toboolean
+
+function string.booleanstring(str)
+ if str == "0" then
+ return false
+ elseif str == "1" then
+ return true
+ elseif str == "" then
+ return false
+ elseif str == "false" then
+ return false
+ elseif str == "true" then
+ return true
+ elseif (tonumber(str) or 0) > 0 then
+ return true
+ else
+ return str == "yes" or str == "on" or str == "t"
+ end
+end
+
+function string.is_boolean(str,default,strict)
+ if type(str) == "string" then
+ if str == "true" or str == "yes" or str == "on" or str == "t" or (not strict and str == "1") then
+ return true
+ elseif str == "false" or str == "no" or str == "off" or str == "f" or (not strict and str == "0") then
+ return false
+ end
+ end
+ return default
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-compat.lua b/macros/luatex/generic/lualibs/lualibs-compat.lua
new file mode 100644
index 0000000000..707f26b8b6
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-compat.lua
@@ -0,0 +1,31 @@
+#!/usr/bin/env texlua
+
+lualibs = lualibs or { }
+
+local stringgsub = string.gsub
+local stringlower = string.lower
+local next = next
+local Ct, splitat = lpeg.Ct, lpeg.splitat
+
+--[[doc
+Needed by legacy luat-dum.lua.
+--doc]]--
+table.reverse_hash = function (h)
+ local r = { }
+ for k,v in next, h do
+ r[v] = stringlower(stringgsub(k," ",""))
+ end
+ return r
+end
+
+--[[doc
+Needed by legacy font-otn.lua.
+--doc]]--
+lpeg.splitters = { [" "] = Ct(splitat" ") }
+
+--[[doc
+Needed by legacy font-nms.lua.
+--doc]]--
+
+file.split_path = file.splitpath
+file.collapse_path = file.collapsepath
diff --git a/macros/luatex/generic/lualibs/lualibs-dir.lua b/macros/luatex/generic/lualibs/lualibs-dir.lua
new file mode 100644
index 0000000000..325039cb1e
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-dir.lua
@@ -0,0 +1,642 @@
+if not modules then modules = { } end modules ['l-dir'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo: dir.expandname will be sped up and merged with cleanpath and collapsepath
+-- todo: keep track of currentdir (chdir, pushdir, popdir)
+
+local type, select = type, select
+local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub
+local concat, insert, remove, unpack = table.concat, table.insert, table.remove, table.unpack
+local lpegmatch = lpeg.match
+
+local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V
+
+dir = dir or { }
+local dir = dir
+local lfs = lfs
+
+local attributes = lfs.attributes
+local walkdir = lfs.dir
+local isdir = lfs.isdir -- not robust, will be overloaded anyway
+local isfile = lfs.isfile -- not robust, will be overloaded anyway
+local currentdir = lfs.currentdir
+local chdir = lfs.chdir
+local mkdir = lfs.mkdir
+
+local onwindows = os.type == "windows" or find(os.getenv("PATH"),";",1,true)
+
+-- in case we load outside luatex
+
+if onwindows then
+
+ -- lfs.isdir does not like trailing /
+ -- lfs.dir accepts trailing /
+
+ local tricky = S("/\\") * P(-1)
+
+ isdir = function(name)
+ if lpegmatch(tricky,name) then
+ return attributes(name,"mode") == "directory"
+ else
+ return attributes(name.."/.","mode") == "directory"
+ end
+ end
+
+ isfile = function(name)
+ return attributes(name,"mode") == "file"
+ end
+
+ lfs.isdir = isdir
+ lfs.isfile = isfile
+
+else
+
+ isdir = function(name)
+ return attributes(name,"mode") == "directory"
+ end
+
+ isfile = function(name)
+ return attributes(name,"mode") == "file"
+ end
+
+ lfs.isdir = isdir
+ lfs.isfile = isfile
+
+end
+
+-- handy
+
+function dir.current()
+ return (gsub(currentdir(),"\\","/"))
+end
+
+-- The next one is somewhat optimized but still slow but it's a pitty that the iterator
+-- doesn't return a mode too.
+
+local function glob_pattern_function(path,patt,recurse,action)
+ if isdir(path) then
+ local usedpath
+ if path == "/" then
+ usedpath = "/."
+ elseif not find(path,"/$") then
+ usedpath = path .. "/."
+ path = path .. "/"
+ else
+ usedpath = path
+ end
+ local dirs
+ local nofdirs = 0
+ for name, mode, size, time in walkdir(usedpath) do
+ if name ~= "." and name ~= ".." then
+ local full = path .. name
+ if mode == nil then
+ mode = attributes(full,'mode')
+ end
+ if mode == 'file' then
+ if not patt or find(full,patt) then
+ action(full,size,time)
+ end
+ elseif recurse and mode == "directory" then
+ if dirs then
+ nofdirs = nofdirs + 1
+ dirs[nofdirs] = full
+ else
+ nofdirs = 1
+ dirs = { full }
+ end
+ end
+ end
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_function(dirs[i],patt,recurse,action)
+ end
+ end
+ end
+end
+
+local function glob_pattern_table(path,patt,recurse,result)
+ if not result then
+ result = { }
+ end
+ local usedpath
+ if path == "/" then
+ usedpath = "/."
+ elseif not find(path,"/$") then
+ usedpath = path .. "/."
+ path = path .. "/"
+ else
+ usedpath = path
+ end
+ local dirs
+ local nofdirs = 0
+ local noffiles = #result
+ for name, mode in walkdir(usedpath) do
+ if name ~= "." and name ~= ".." then
+ local full = path .. name
+ if mode == nil then
+ mode = attributes(full,'mode')
+ end
+ if mode == 'file' then
+ if not patt or find(full,patt) then
+ noffiles = noffiles + 1
+ result[noffiles] = full
+ end
+ elseif recurse and mode == "directory" then
+ if dirs then
+ nofdirs = nofdirs + 1
+ dirs[nofdirs] = full
+ else
+ nofdirs = 1
+ dirs = { full }
+ end
+ end
+ end
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_table(dirs[i],patt,recurse,result)
+ end
+ end
+ return result
+end
+
+local function globpattern(path,patt,recurse,method)
+ local kind = type(method)
+ if patt and sub(patt,1,-3) == path then
+ patt = false
+ end
+ local okay = isdir(path)
+ if kind == "function" then
+ return okay and glob_pattern_function(path,patt,recurse,method) or { }
+ elseif kind == "table" then
+ return okay and glob_pattern_table(path,patt,recurse,method) or method
+ else
+ return okay and glob_pattern_table(path,patt,recurse,{ }) or { }
+ end
+end
+
+dir.globpattern = globpattern
+
+-- never or seldom used so far:
+
+local function collectpattern(path,patt,recurse,result)
+ local ok, scanner
+ result = result or { }
+ if path == "/" then
+ ok, scanner, first = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe
+ else
+ ok, scanner, first = xpcall(function() return walkdir(path) end, function() end) -- kepler safe
+ end
+ if ok and type(scanner) == "function" then
+ if not find(path,"/$") then
+ path = path .. '/'
+ end
+ for name in scanner, first do -- cna be optimized
+ if name == "." then
+ -- skip
+ elseif name == ".." then
+ -- skip
+ else
+ local full = path .. name
+ local attr = attributes(full)
+ local mode = attr.mode
+ if mode == 'file' then
+ if find(full,patt) then
+ result[name] = attr
+ end
+ elseif recurse and mode == "directory" then
+ attr.list = collectpattern(full,patt,recurse)
+ result[name] = attr
+ end
+ end
+ end
+ end
+ return result
+end
+
+dir.collectpattern = collectpattern
+
+local separator, pattern
+
+if onwindows then -- we could sanitize here
+
+ local slash = S("/\\") / "/"
+
+-- pattern = Ct {
+ pattern = {
+ [1] = (Cs(P(".") + slash^1) + Cs(R("az","AZ") * P(":") * slash^0) + Cc("./")) * V(2) * V(3),
+ [2] = Cs(((1-S("*?/\\"))^0 * slash)^0),
+ [3] = Cs(P(1)^0)
+ }
+
+else -- assume unix
+
+-- pattern = Ct {
+ pattern = {
+ [1] = (C(P(".") + P("/")^1) + Cc("./")) * V(2) * V(3),
+ [2] = C(((1-S("*?/"))^0 * P("/"))^0),
+ [3] = C(P(1)^0)
+ }
+
+end
+
+local filter = Cs ( (
+ P("**") / ".*" +
+ P("*") / "[^/]*" +
+ P("?") / "[^/]" +
+ P(".") / "%%." +
+ P("+") / "%%+" +
+ P("-") / "%%-" +
+ P(1)
+)^0 )
+
+local function glob(str,t)
+ if type(t) == "function" then
+ if type(str) == "table" then
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ elseif isfile(str) then
+ t(str)
+ else
+ local root, path, base = lpegmatch(pattern,str) -- we could use the file splitter
+ if root and path and base then
+ local recurse = find(base,"**",1,true) -- find(base,"%*%*")
+ local start = root .. path
+ local result = lpegmatch(filter,start .. base)
+ globpattern(start,result,recurse,t)
+ end
+ end
+ else
+ if type(str) == "table" then
+ local t = t or { }
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ return t
+ elseif isfile(str) then
+ if t then
+ t[#t+1] = str
+ return t
+ else
+ return { str }
+ end
+ else
+ local root, path, base = lpegmatch(pattern,str) -- we could use the file splitter
+ if root and path and base then
+ local recurse = find(base,"**",1,true) -- find(base,"%*%*")
+ local start = root .. path
+ local result = lpegmatch(filter,start .. base)
+ return globpattern(start,result,recurse,t)
+ else
+ return { }
+ end
+ end
+ end
+end
+
+dir.glob = glob
+
+-- local c = os.clock()
+-- local t = dir.glob("e:/**")
+-- local t = dir.glob("t:/sources/**")
+-- local t = dir.glob("t:/**")
+-- print(os.clock()-c,#t)
+
+-- for i=1,3000 do print(t[i]) end
+-- for i=1,10 do print(t[i]) end
+
+-- list = dir.glob("**/*.tif")
+-- list = dir.glob("/**/*.tif")
+-- list = dir.glob("./**/*.tif")
+-- list = dir.glob("oeps/**/*.tif")
+-- list = dir.glob("/oeps/**/*.tif")
+
+local function globfiles(path,recurse,func,files) -- func == pattern or function
+ if type(func) == "string" then
+ local s = func
+ func = function(name) return find(name,s) end
+ end
+ files = files or { }
+ local noffiles = #files
+ for name, mode in walkdir(path) do
+ if find(name,"^%.") then
+ --- skip
+ else
+ if mode == nil then
+ mode = attributes(name,'mode')
+ end
+ if mode == "directory" then
+ if recurse then
+ globfiles(path .. "/" .. name,recurse,func,files)
+ end
+ elseif mode == "file" then
+ if not func or func(name) then
+ noffiles = noffiles + 1
+ files[noffiles] = path .. "/" .. name
+ end
+ end
+ end
+ end
+ return files
+end
+
+dir.globfiles = globfiles
+
+local function globdirs(path,recurse,func,files) -- func == pattern or function
+ if type(func) == "string" then
+ local s = func
+ func = function(name) return find(name,s) end
+ end
+ files = files or { }
+ local noffiles = #files
+ for name, mode in walkdir(path) do
+ if find(name,"^%.") then
+ --- skip
+ else
+ if mode == nil then
+ mode = attributes(name,'mode')
+ end
+ if mode == "directory" then
+ if not func or func(name) then
+ noffiles = noffiles + 1
+ files[noffiles] = path .. "/" .. name
+ if recurse then
+ globdirs(path .. "/" .. name,recurse,func,files)
+ end
+ end
+ end
+ end
+ end
+ return files
+end
+
+dir.globdirs = globdirs
+
+-- inspect(globdirs("e:/tmp"))
+
+-- t = dir.glob("c:/data/develop/context/sources/**/????-*.tex")
+-- t = dir.glob("c:/data/develop/tex/texmf/**/*.tex")
+-- t = dir.glob("c:/data/develop/context/texmf/**/*.tex")
+-- t = dir.glob("f:/minimal/tex/**/*")
+-- print(dir.ls("f:/minimal/tex/**/*"))
+-- print(dir.ls("*.tex"))
+
+function dir.ls(pattern)
+ return concat(glob(pattern),"\n")
+end
+
+-- mkdirs("temp")
+-- mkdirs("a/b/c")
+-- mkdirs(".","/a/b/c")
+-- mkdirs("a","b","c")
+
+local make_indeed = true -- false
+
+if onwindows then
+
+ function dir.mkdirs(...)
+ local n = select("#",...)
+ local str
+ if n == 1 then
+ str = select(1,...)
+ if isdir(str) then
+ return str, true
+ end
+ else
+ str = ""
+ for i=1,n do
+ local s = select(i,...)
+ if s == "" then
+ -- skip
+ elseif str == "" then
+ str = s
+ else
+ str = str .. "/" .. s
+ end
+ end
+ end
+ local pth = ""
+ local drive = false
+ local first, middle, last = match(str,"^(//)(//*)(.*)$")
+ if first then
+ -- empty network path == local path
+ else
+ first, last = match(str,"^(//)/*(.-)$")
+ if first then
+ middle, last = match(str,"([^/]+)/+(.-)$")
+ if middle then
+ pth = "//" .. middle
+ else
+ pth = "//" .. last
+ last = ""
+ end
+ else
+ first, middle, last = match(str,"^([a-zA-Z]:)(/*)(.-)$")
+ if first then
+ pth, drive = first .. middle, true
+ else
+ middle, last = match(str,"^(/*)(.-)$")
+ if not middle then
+ last = str
+ end
+ end
+ end
+ end
+ for s in gmatch(last,"[^/]+") do
+ if pth == "" then
+ pth = s
+ elseif drive then
+ pth, drive = pth .. s, false
+ else
+ pth = pth .. "/" .. s
+ end
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ return pth, (isdir(pth) == true)
+ end
+
+ -- print(dir.mkdirs("","","a","c"))
+ -- print(dir.mkdirs("a"))
+ -- print(dir.mkdirs("a:"))
+ -- print(dir.mkdirs("a:/b/c"))
+ -- print(dir.mkdirs("a:b/c"))
+ -- print(dir.mkdirs("a:/bbb/c"))
+ -- print(dir.mkdirs("/a/b/c"))
+ -- print(dir.mkdirs("/aaa/b/c"))
+ -- print(dir.mkdirs("//a/b/c"))
+ -- print(dir.mkdirs("///a/b/c"))
+ -- print(dir.mkdirs("a/bbb//ccc/"))
+
+else
+
+ function dir.mkdirs(...)
+ local n = select("#",...)
+ local str, pth
+ if n == 1 then
+ str = select(1,...)
+ if isdir(str) then
+ return str, true
+ end
+ else
+ str = ""
+ for i=1,n do
+ local s = select(i,...)
+ if s and s ~= "" then -- we catch nil and false
+ if str ~= "" then
+ str = str .. "/" .. s
+ else
+ str = s
+ end
+ end
+ end
+ end
+ str = gsub(str,"/+","/")
+ if find(str,"^/") then
+ pth = "/"
+ for s in gmatch(str,"[^/]+") do
+ local first = (pth == "/")
+ if first then
+ pth = pth .. s
+ else
+ pth = pth .. "/" .. s
+ end
+ if make_indeed and not first and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ else
+ pth = "."
+ for s in gmatch(str,"[^/]+") do
+ pth = pth .. "/" .. s
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ end
+ return pth, (isdir(pth) == true)
+ end
+
+ -- print(dir.mkdirs("","","a","c"))
+ -- print(dir.mkdirs("a"))
+ -- print(dir.mkdirs("/a/b/c"))
+ -- print(dir.mkdirs("/aaa/b/c"))
+ -- print(dir.mkdirs("//a/b/c"))
+ -- print(dir.mkdirs("///a/b/c"))
+ -- print(dir.mkdirs("a/bbb//ccc/"))
+
+end
+
+dir.makedirs = dir.mkdirs
+
+
+do
+
+ -- we can only define it here as it uses dir.chdir and we also need to
+ -- make sure we use the non sandboxed variant because otherwise we get
+ -- into a recursive loop due to usage of expandname in the file resolver
+
+ local chdir = sandbox and sandbox.original(chdir) or chdir
+
+ if onwindows then
+
+ local xcurrentdir = dir.current
+
+ function dir.expandname(str) -- will be merged with cleanpath and collapsepath\
+ local first, nothing, last = match(str,"^(//)(//*)(.*)$")
+ if first then
+ first = xcurrentdir() .. "/" -- xcurrentdir sanitizes
+ end
+ if not first then
+ first, last = match(str,"^(//)/*(.*)$")
+ end
+ if not first then
+ first, last = match(str,"^([a-zA-Z]:)(.*)$")
+ if first and not find(last,"^/") then
+ local d = currentdir() -- push / pop
+ if chdir(first) then
+ first = xcurrentdir() -- xcurrentdir sanitizes
+ end
+ chdir(d)
+ end
+ end
+ if not first then
+ first, last = xcurrentdir(), str
+ end
+ last = gsub(last,"//","/")
+ last = gsub(last,"/%./","/")
+ last = gsub(last,"^/*","")
+ first = gsub(first,"/*$","")
+ if last == "" or last == "." then
+ return first
+ else
+ return first .. "/" .. last
+ end
+ end
+
+ else
+
+ function dir.expandname(str) -- will be merged with cleanpath and collapsepath
+ if not find(str,"^/") then
+ str = currentdir() .. "/" .. str
+ end
+ str = gsub(str,"//","/")
+ str = gsub(str,"/%./","/")
+ str = gsub(str,"(.)/%.$","%1")
+ return str
+ end
+
+ end
+
+end
+
+file.expandname = dir.expandname -- for convenience
+
+local stack = { }
+
+function dir.push(newdir)
+ local curdir = currentdir()
+ insert(stack,curdir)
+ if newdir and newdir ~= "" and chdir(newdir) then
+ return newdir
+ else
+ return curdir
+ end
+end
+
+function dir.pop()
+ local d = remove(stack)
+ if d then
+ chdir(d)
+ end
+ return d
+end
+
+local function found(...) -- can have nil entries
+ for i=1,select("#",...) do
+ local path = select(i,...)
+ local kind = type(path)
+ if kind == "string" then
+ if isdir(path) then
+ return path
+ end
+ elseif kind == "table" then
+ -- here we asume no holes, i.e. an indexed table
+ local path = found(unpack(path))
+ if path then
+ return path
+ end
+ end
+ end
+ -- return nil -- if we want print("crappath") to show something
+end
+
+dir.found = found
diff --git a/macros/luatex/generic/lualibs/lualibs-extended-merged.lua b/macros/luatex/generic/lualibs/lualibs-extended-merged.lua
new file mode 100644
index 0000000000..b3fecf2c3e
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-extended-merged.lua
@@ -0,0 +1,4194 @@
+-- merged file : lualibs-extended-merged.lua
+-- parent file : lualibs-extended.lua
+-- merge date : Tue Aug 13 20:12:59 2019
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-str']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+utilities=utilities or {}
+utilities.strings=utilities.strings or {}
+local strings=utilities.strings
+local format,gsub,rep,sub,find=string.format,string.gsub,string.rep,string.sub,string.find
+local load,dump=load,string.dump
+local tonumber,type,tostring,next,setmetatable=tonumber,type,tostring,next,setmetatable
+local unpack,concat=table.unpack,table.concat
+local P,V,C,S,R,Ct,Cs,Cp,Carg,Cc=lpeg.P,lpeg.V,lpeg.C,lpeg.S,lpeg.R,lpeg.Ct,lpeg.Cs,lpeg.Cp,lpeg.Carg,lpeg.Cc
+local patterns,lpegmatch=lpeg.patterns,lpeg.match
+local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
+local loadstripped=function(str,shortcuts)
+ if shortcuts then
+ return load(dump(load(str),true),nil,nil,shortcuts)
+ else
+ return load(dump(load(str),true))
+ end
+end
+if not number then number={} end
+local stripzero=patterns.stripzero
+local stripzeros=patterns.stripzeros
+local newline=patterns.newline
+local endofstring=patterns.endofstring
+local anything=patterns.anything
+local whitespace=patterns.whitespace
+local space=patterns.space
+local spacer=patterns.spacer
+local spaceortab=patterns.spaceortab
+local digit=patterns.digit
+local sign=patterns.sign
+local period=patterns.period
+local ptf=1/65536
+local bpf=(7200/7227)/65536
+local function points(n)
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*ptf
+ if n%1==0 then
+ return format("%ipt",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fpt",n))
+end
+local function basepoints(n)
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*bpf
+ if n%1==0 then
+ return format("%ibp",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fbp",n))
+end
+number.points=points
+number.basepoints=basepoints
+local rubish=spaceortab^0*newline
+local anyrubish=spaceortab+newline
+local stripped=(spaceortab^1/"")*newline
+local leading=rubish^0/""
+local trailing=(anyrubish^1*endofstring)/""
+local redundant=rubish^3/"\n"
+local pattern=Cs(leading*(trailing+redundant+stripped+anything)^0)
+function strings.collapsecrlf(str)
+ return lpegmatch(pattern,str)
+end
+local repeaters={}
+function strings.newrepeater(str,offset)
+ offset=offset or 0
+ local s=repeaters[str]
+ if not s then
+ s={}
+ repeaters[str]=s
+ end
+ local t=s[offset]
+ if t then
+ return t
+ end
+ t={}
+ setmetatable(t,{ __index=function(t,k)
+ if not k then
+ return ""
+ end
+ local n=k+offset
+ local s=n>0 and rep(str,n) or ""
+ t[k]=s
+ return s
+ end })
+ s[offset]=t
+ return t
+end
+local extra,tab,start=0,0,4,0
+local nspaces=strings.newrepeater(" ")
+string.nspaces=nspaces
+local pattern=Carg(1)/function(t)
+ extra,tab,start=0,t or 7,1
+ end*Cs((
+ Cp()*patterns.tab/function(position)
+ local current=(position-start+1)+extra
+ local spaces=tab-(current-1)%tab
+ if spaces>0 then
+ extra=extra+spaces-1
+ return nspaces[spaces]
+ else
+ return ""
+ end
+ end+newline*Cp()/function(position)
+ extra,start=0,position
+ end+anything
+ )^1)
+function strings.tabtospace(str,tab)
+ return lpegmatch(pattern,str,1,tab or 7)
+end
+function string.utfpadding(s,n)
+ if not n or n==0 then
+ return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
+end
+local optionalspace=spacer^0
+local nospace=optionalspace/""
+local endofline=nospace*newline
+local stripend=(whitespace^1*endofstring)/""
+local normalline=(nospace*((1-optionalspace*(newline+endofstring))^1)*nospace)
+local stripempty=endofline^1/""
+local normalempty=endofline^1
+local singleempty=endofline*(endofline^0/"")
+local doubleempty=endofline*endofline^-1*(endofline^0/"")
+local stripstart=stripempty^0
+local intospace=whitespace^1/" "
+local noleading=whitespace^1/""
+local notrailing=noleading*endofstring
+local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 )
+local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 )
+local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 )
+local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
+local p_retain_normal=Cs ((normalline+normalempty )^0 )
+local p_retain_collapse=Cs ((normalline+doubleempty )^0 )
+local p_retain_noempty=Cs ((normalline+singleempty )^0 )
+local striplinepatterns={
+ ["prune"]=p_prune_normal,
+ ["prune and collapse"]=p_prune_collapse,
+ ["prune and no empty"]=p_prune_noempty,
+ ["prune and to space"]=p_prune_intospace,
+ ["retain"]=p_retain_normal,
+ ["retain and collapse"]=p_retain_collapse,
+ ["retain and no empty"]=p_retain_noempty,
+ ["collapse"]=patterns.collapser,
+}
+setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end })
+strings.striplinepatterns=striplinepatterns
+function strings.striplines(str,how)
+ return str and lpegmatch(striplinepatterns[how],str) or str
+end
+function strings.collapse(str)
+ return str and lpegmatch(p_prune_intospace,str) or str
+end
+strings.striplong=strings.striplines
+function strings.nice(str)
+ str=gsub(str,"[:%-+_]+"," ")
+ return str
+end
+local n=0
+local sequenced=table.sequenced
+function string.autodouble(s,sep)
+ if s==nil then
+ return '""'
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ('"'..sequenced(s,sep or ",")..'"')
+ end
+ return ('"'..tostring(s)..'"')
+end
+function string.autosingle(s,sep)
+ if s==nil then
+ return "''"
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ("'"..sequenced(s,sep or ",").."'")
+ end
+ return ("'"..tostring(s).."'")
+end
+local tracedchars={ [0]=
+ "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
+ "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
+ "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
+ "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
+ "[space]",
+}
+string.tracedchars=tracedchars
+strings.tracers=tracedchars
+function string.tracedchar(b)
+ if type(b)=="number" then
+ return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
+ else
+ local c=utfbyte(b)
+ return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
+ end
+end
+function number.signed(i)
+ if i>0 then
+ return "+",i
+ else
+ return "-",-i
+ end
+end
+local two=digit*digit
+local three=two*digit
+local prefix=(Carg(1)*three)^1
+local splitter=Cs (
+ (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
+)
+local splitter3=Cs (
+ three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
+)
+patterns.formattednumber=splitter
+function number.formatted(n,sep1,sep2)
+ if sep1==false then
+ if type(n)=="number" then
+ n=tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n)=="number" then
+ n=format("%0.2f",n)
+ end
+ if sep1==true then
+ return lpegmatch(splitter,n,1,".",",")
+ elseif sep1=="." then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
+ elseif sep1=="," then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
+ else
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
+ end
+ end
+end
+local p=Cs(
+ P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
+ )
+function number.compactfloat(n,fmt)
+ if n==0 then
+ return "0"
+ elseif n==1 then
+ return "1"
+ end
+ n=lpegmatch(p,format(fmt or "%0.3f",n))
+ if n=="." or n=="" or n=="-" then
+ return "0"
+ end
+ return n
+end
+local zero=P("0")^1/""
+local plus=P("+")/""
+local minus=P("-")
+local separator=period
+local trailing=zero^1*#S("eE")
+local exponent=(S("eE")*(plus+Cs((minus*zero^0*endofstring)/"")+minus)*zero^0*(endofstring*Cc("0")+anything^1))
+local pattern_a=Cs(minus^0*digit^1*(separator/""*trailing+separator*(trailing+digit)^0)*exponent)
+local pattern_b=Cs((exponent+anything)^0)
+function number.sparseexponent(f,n)
+ if not n then
+ n=f
+ f="%e"
+ end
+ local tn=type(n)
+ if tn=="string" then
+ local m=tonumber(n)
+ if m then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
+ end
+ elseif tn=="number" then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ end
+ return tostring(n)
+end
+local hf={}
+local hs={}
+setmetatable(hf,{ __index=function(t,k)
+ local v="%."..k.."f"
+ t[k]=v
+ return v
+end } )
+setmetatable(hs,{ __index=function(t,k)
+ local v="%"..k.."s"
+ t[k]=v
+ return v
+end } )
+function number.formattedfloat(n,b,a)
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
+end
+local template=[[
+%s
+%s
+return function(%s) return %s end
+]]
+local pattern=Cs(Cc('"')*(
+ (1-S('"\\\n\r'))^1+P('"')/'\\"'+P('\\')/'\\\\'+P('\n')/'\\n'+P('\r')/'\\r'
+)^0*Cc('"'))
+patterns.escapedquotes=pattern
+function string.escapedquotes(s)
+ return lpegmatch(pattern,s)
+end
+local preamble=""
+local environment={
+ global=global or _G,
+ lpeg=lpeg,
+ type=type,
+ tostring=tostring,
+ tonumber=tonumber,
+ format=string.format,
+ concat=table.concat,
+ signed=number.signed,
+ points=number.points,
+ basepoints=number.basepoints,
+ utfchar=utf.char,
+ utfbyte=utf.byte,
+ lpegmatch=lpeg.match,
+ nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
+ tracedchar=string.tracedchar,
+ autosingle=string.autosingle,
+ autodouble=string.autodouble,
+ sequenced=table.sequenced,
+ formattednumber=number.formatted,
+ sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat,
+ stripzero=patterns.stripzero,
+ stripzeros=patterns.stripzeros,
+ escapedquotes=string.escapedquotes,
+ FORMAT=string.f9,
+}
+local arguments={ "a1" }
+setmetatable(arguments,{ __index=function(t,k)
+ local v=t[k-1]..",a"..k
+ t[k]=v
+ return v
+ end
+})
+local prefix_any=C((sign+space+period+digit)^0)
+local prefix_sub=(C((sign+digit)^0)+Cc(0))*period*(C((sign+digit)^0)+Cc(0))
+local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
+local format_s=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("(a%s or '')",n)
+ end
+end
+local format_S=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',tostring(a%s))",f,n)
+ else
+ return format("tostring(a%s)",n)
+ end
+end
+local format_right=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ elseif f>0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
+end
+local format_left=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ end
+ if f<0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
+end
+local format_q=function()
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+end
+local format_Q=function()
+ n=n+1
+ return format("escapedquotes(tostring(a%s))",n)
+end
+local format_i=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%si',a%s)",f,n)
+ else
+ return format("format('%%i',a%s)",n)
+ end
+end
+local format_d=format_i
+local format_I=function(f)
+ n=n+1
+ return format("format('%%s%%%si',signed(a%s))",f,n)
+end
+local format_f=function(f)
+ n=n+1
+ return format("format('%%%sf',a%s)",f,n)
+end
+local format_F=function(f)
+ n=n+1
+ if not f or f=="" then
+ return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
+ else
+ return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
+ end
+end
+local format_k=function(b,a)
+ n=n+1
+ return format("formattedfloat(a%s,%s,%s)",n,b or 0,a or 0)
+end
+local format_g=function(f)
+ n=n+1
+ return format("format('%%%sg',a%s)",f,n)
+end
+local format_G=function(f)
+ n=n+1
+ return format("format('%%%sG',a%s)",f,n)
+end
+local format_e=function(f)
+ n=n+1
+ return format("format('%%%se',a%s)",f,n)
+end
+local format_E=function(f)
+ n=n+1
+ return format("format('%%%sE',a%s)",f,n)
+end
+local format_j=function(f)
+ n=n+1
+ return format("sparseexponent('%%%se',a%s)",f,n)
+end
+local format_J=function(f)
+ n=n+1
+ return format("sparseexponent('%%%sE',a%s)",f,n)
+end
+local format_x=function(f)
+ n=n+1
+ return format("format('%%%sx',a%s)",f,n)
+end
+local format_X=function(f)
+ n=n+1
+ return format("format('%%%sX',a%s)",f,n)
+end
+local format_o=function(f)
+ n=n+1
+ return format("format('%%%so',a%s)",f,n)
+end
+local format_c=function()
+ n=n+1
+ return format("utfchar(a%s)",n)
+end
+local format_C=function()
+ n=n+1
+ return format("tracedchar(a%s)",n)
+end
+local format_r=function(f)
+ n=n+1
+ return format("format('%%%s.0f',a%s)",f,n)
+end
+local format_h=function(f)
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
+end
+local format_H=function(f)
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
+end
+local format_u=function(f)
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
+end
+local format_U=function(f)
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
+end
+local format_p=function()
+ n=n+1
+ return format("points(a%s)",n)
+end
+local format_b=function()
+ n=n+1
+ return format("basepoints(a%s)",n)
+end
+local format_t=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("concat(a%s,%q)",n,f)
+ else
+ return format("concat(a%s)",n)
+ end
+end
+local format_T=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("sequenced(a%s,%q)",n,f)
+ else
+ return format("sequenced(a%s)",n)
+ end
+end
+local format_l=function()
+ n=n+1
+ return format("(a%s and 'true' or 'false')",n)
+end
+local format_L=function()
+ n=n+1
+ return format("(a%s and 'TRUE' or 'FALSE')",n)
+end
+local format_n=function()
+ n=n+1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+end
+local format_N=function(f)
+ n=n+1
+ if not f or f=="" then
+ f=".9"
+ end
+ return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+end
+local format_a=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("autosingle(a%s,%q)",n,f)
+ else
+ return format("autosingle(a%s)",n)
+ end
+end
+local format_A=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("autodouble(a%s,%q)",n,f)
+ else
+ return format("autodouble(a%s)",n)
+ end
+end
+local format_w=function(f)
+ n=n+1
+ f=tonumber(f)
+ if f then
+ return format("nspaces[%s+a%s]",f,n)
+ else
+ return format("nspaces[a%s]",n)
+ end
+end
+local format_W=function(f)
+ return format("nspaces[%s]",tonumber(f) or 0)
+end
+local format_m=function(f)
+ n=n+1
+ if not f or f=="" then
+ f=","
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,".")]],n,f)
+ end
+end
+local format_M=function(f)
+ n=n+1
+ if not f or f=="" then
+ f="."
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,",")]],n,f)
+ end
+end
+local format_z=function(f)
+ n=n+(tonumber(f) or 1)
+ return "''"
+end
+local format_rest=function(s)
+ return format("%q",s)
+end
+local format_extension=function(extensions,f,name)
+ local extension=extensions[name] or "tostring(%s)"
+ local f=tonumber(f) or 1
+ local w=find(extension,"%.%.%.")
+ if w then
+ if f==0 then
+ extension=gsub(extension,"%.%.%.","")
+ return extension
+ elseif f==1 then
+ extension=gsub(extension,"%.%.%.","%%s")
+ n=n+1
+ local a="a"..n
+ return format(extension,a,a)
+ elseif f<0 then
+ local a="a"..(n+f+1)
+ return format(extension,a,a)
+ else
+ extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+ local t={}
+ for i=1,f do
+ n=n+1
+ t[i]="a"..n
+ end
+ return format(extension,unpack(t))
+ end
+ else
+ extension=gsub(extension,"%%s",function()
+ n=n+1
+ return "a"..n
+ end)
+ return extension
+ end
+end
+local builder=Cs { "start",
+ start=(
+ (
+ P("%")/""*(
+ V("!")
++V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
++V("c")+V("C")+V("S")
++V("Q")
++V("n")
++V("N")
++V("k")
++V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
++V("W")
++V("a")
++V("A")
++V("j")+V("J")
++V("m")+V("M")
++V("z")
++V(">")
++V("<")
+ )+V("*")
+ )*(endofstring+Carg(1))
+ )^0,
+ ["s"]=(prefix_any*P("s"))/format_s,
+ ["q"]=(prefix_any*P("q"))/format_q,
+ ["i"]=(prefix_any*P("i"))/format_i,
+ ["d"]=(prefix_any*P("d"))/format_d,
+ ["f"]=(prefix_any*P("f"))/format_f,
+ ["F"]=(prefix_any*P("F"))/format_F,
+ ["g"]=(prefix_any*P("g"))/format_g,
+ ["G"]=(prefix_any*P("G"))/format_G,
+ ["e"]=(prefix_any*P("e"))/format_e,
+ ["E"]=(prefix_any*P("E"))/format_E,
+ ["x"]=(prefix_any*P("x"))/format_x,
+ ["X"]=(prefix_any*P("X"))/format_X,
+ ["o"]=(prefix_any*P("o"))/format_o,
+ ["S"]=(prefix_any*P("S"))/format_S,
+ ["Q"]=(prefix_any*P("Q"))/format_Q,
+ ["n"]=(prefix_any*P("n"))/format_n,
+ ["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
+ ["c"]=(prefix_any*P("c"))/format_c,
+ ["C"]=(prefix_any*P("C"))/format_C,
+ ["r"]=(prefix_any*P("r"))/format_r,
+ ["h"]=(prefix_any*P("h"))/format_h,
+ ["H"]=(prefix_any*P("H"))/format_H,
+ ["u"]=(prefix_any*P("u"))/format_u,
+ ["U"]=(prefix_any*P("U"))/format_U,
+ ["p"]=(prefix_any*P("p"))/format_p,
+ ["b"]=(prefix_any*P("b"))/format_b,
+ ["t"]=(prefix_tab*P("t"))/format_t,
+ ["T"]=(prefix_tab*P("T"))/format_T,
+ ["l"]=(prefix_any*P("l"))/format_l,
+ ["L"]=(prefix_any*P("L"))/format_L,
+ ["I"]=(prefix_any*P("I"))/format_I,
+ ["w"]=(prefix_any*P("w"))/format_w,
+ ["W"]=(prefix_any*P("W"))/format_W,
+ ["j"]=(prefix_any*P("j"))/format_j,
+ ["J"]=(prefix_any*P("J"))/format_J,
+ ["m"]=(prefix_any*P("m"))/format_m,
+ ["M"]=(prefix_any*P("M"))/format_M,
+ ["z"]=(prefix_any*P("z"))/format_z,
+ ["a"]=(prefix_any*P("a"))/format_a,
+ ["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
+ ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
+ ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
+ ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
+}
+local xx=setmetatable({},{ __index=function(t,k) local v=format("%02x",k) t[k]=v return v end })
+local XX=setmetatable({},{ __index=function(t,k) local v=format("%02X",k) t[k]=v return v end })
+local preset={
+ ["%02x"]=function(n) return xx[n] end,
+ ["%02X"]=function(n) return XX[n] end,
+}
+local direct=P("%")*(sign+space+period+digit)^0*S("sqidfgGeExXo")*endofstring/[[local format = string.format return function(str) return format("%0",str) end]]
+local function make(t,str)
+ local f=preset[str]
+ if f then
+ return f
+ end
+ local p=lpegmatch(direct,str)
+ if p then
+ f=loadstripped(p)()
+ else
+ n=0
+ p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
+ if n>0 then
+ p=format(template,preamble,t._preamble_,arguments[n],p)
+ f=loadstripped(p,t._environment_)()
+ else
+ f=function() return str end
+ end
+ end
+ t[str]=f
+ return f
+end
+local function use(t,fmt,...)
+ return t[fmt](...)
+end
+strings.formatters={}
+function strings.formatters.new(noconcat)
+ local e={}
+ for k,v in next,environment do
+ e[k]=v
+ end
+ local t={
+ _type_="formatter",
+ _connector_=noconcat and "," or "..",
+ _extensions_={},
+ _preamble_="",
+ _environment_=e,
+ }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
+end
+local formatters=strings.formatters.new()
+string.formatters=formatters
+string.formatter=function(str,...) return formatters[str](...) end
+local function add(t,name,template,preamble)
+ if type(t)=="table" and t._type_=="formatter" then
+ t._extensions_[name]=template or "%s"
+ if type(preamble)=="string" then
+ t._preamble_=preamble.."\n"..t._preamble_
+ elseif type(preamble)=="table" then
+ for k,v in next,preamble do
+ t._environment_[k]=v
+ end
+ end
+ end
+end
+strings.formatters.add=add
+patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+anything)^0)
+patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+anything)^0)
+patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0)
+patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"'))
+add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=patterns.xmlescape })
+add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=patterns.texescape })
+add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=patterns.luaescape })
+local dquote=patterns.dquote
+local equote=patterns.escaped+dquote/'\\"'+1
+local cquote=Cc('"')
+local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
++Cs(cquote*(equote-space)^0*space*equote^0*cquote)
+function string.optionalquoted(str)
+ return lpegmatch(pattern,str) or str
+end
+local pattern=Cs((newline/(os.newline or "\r")+1)^0)
+function string.replacenewlines(str)
+ return lpegmatch(pattern,str)
+end
+function strings.newcollector()
+ local result,r={},0
+ return
+ function(fmt,str,...)
+ r=r+1
+ result[r]=str==nil and fmt or formatters[fmt](str,...)
+ end,
+ function(connector)
+ if result then
+ local str=concat(result,connector)
+ result,r={},0
+ return str
+ end
+ end
+end
+local f_16_16=formatters["%0.5N"]
+function number.to16dot16(n)
+ return f_16_16(n/65536.0)
+end
+if not string.explode then
+ local tsplitat=lpeg.tsplitat
+ local p_utf=patterns.utf8character
+ local p_check=C(p_utf)*(P("+")*Cc(true))^0
+ local p_split=Ct(C(p_utf)^0)
+ local p_space=Ct((C(1-P(" ")^1)+P(" ")^1)^0)
+ function string.explode(str,symbol)
+ if symbol=="" then
+ return lpegmatch(p_split,str)
+ elseif symbol then
+ local a,b=lpegmatch(p_check,symbol)
+ if b then
+ return lpegmatch(tsplitat(P(a)^1),str)
+ else
+ return lpegmatch(tsplitat(a),str)
+ end
+ else
+ return lpegmatch(p_space,str)
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-fil']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local byte=string.byte
+local char=string.char
+utilities=utilities or {}
+local files={}
+utilities.files=files
+local zerobased={}
+function files.open(filename,zb)
+ local f=io.open(filename,"rb")
+ if f then
+ zerobased[f]=zb or false
+ end
+ return f
+end
+function files.close(f)
+ zerobased[f]=nil
+ f:close()
+end
+function files.size(f)
+ local current=f:seek()
+ local size=f:seek("end")
+ f:seek("set",current)
+ return size
+end
+files.getsize=files.size
+function files.setposition(f,n)
+ if zerobased[f] then
+ f:seek("set",n)
+ else
+ f:seek("set",n-1)
+ end
+end
+function files.getposition(f)
+ if zerobased[f] then
+ return f:seek()
+ else
+ return f:seek()+1
+ end
+end
+function files.look(f,n,chars)
+ local p=f:seek()
+ local s=f:read(n)
+ f:seek("set",p)
+ if chars then
+ return s
+ else
+ return byte(s,1,#s)
+ end
+end
+function files.skip(f,n)
+ if n==1 then
+ f:read(n)
+ else
+ f:seek("set",f:seek()+n)
+ end
+end
+function files.readbyte(f)
+ return byte(f:read(1))
+end
+function files.readbytes(f,n)
+ return byte(f:read(n),1,n)
+end
+function files.readbytetable(f,n)
+ local s=f:read(n or 1)
+ return { byte(s,1,#s) }
+end
+function files.readchar(f)
+ return f:read(1)
+end
+function files.readstring(f,n)
+ return f:read(n or 1)
+end
+function files.readinteger1(f)
+ local n=byte(f:read(1))
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
+end
+files.readcardinal1=files.readbyte
+files.readcardinal=files.readcardinal1
+files.readinteger=files.readinteger1
+files.readsignedbyte=files.readinteger1
+function files.readcardinal2(f)
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
+end
+function files.readcardinal2le(f)
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
+end
+function files.readinteger2(f)
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
+end
+function files.readinteger2le(f)
+ local b,a=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
+end
+function files.readcardinal3(f)
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+end
+function files.readcardinal3le(f)
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+end
+function files.readinteger3(f)
+ local a,b,c=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
+end
+function files.readinteger3le(f)
+ local c,b,a=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
+end
+function files.readcardinal4(f)
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+end
+function files.readcardinal4le(f)
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+end
+function files.readinteger4(f)
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
+end
+function files.readinteger4le(f)
+ local d,c,b,a=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
+end
+function files.readfixed2(f)
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return (a-0x100)+b/0x100
+ else
+ return (a )+b/0x100
+ end
+end
+function files.readfixed4(f)
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return (0x100*a+b-0x10000)+(0x100*c+d)/0x10000
+ else
+ return (0x100*a+b )+(0x100*c+d)/0x10000
+ end
+end
+if bit32 then
+ local extract=bit32.extract
+ local band=bit32.band
+ function files.read2dot14(f)
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+ else
+ local n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+ end
+ end
+end
+function files.skipshort(f,n)
+ f:read(2*(n or 1))
+end
+function files.skiplong(f,n)
+ f:read(4*(n or 1))
+end
+if bit32 then
+ local rshift=bit32.rshift
+ function files.writecardinal2(f,n)
+ local a=char(n%256)
+ n=rshift(n,8)
+ local b=char(n%256)
+ f:write(b,a)
+ end
+else
+ local floor=math.floor
+ function files.writecardinal2(f,n)
+ local a=char(n%256)
+ n=floor(n/256)
+ local b=char(n%256)
+ f:write(b,a)
+ end
+end
+function files.writecardinal4(f,n)
+ local a=char(n%256)
+ n=rshift(n,8)
+ local b=char(n%256)
+ n=rshift(n,8)
+ local c=char(n%256)
+ n=rshift(n,8)
+ local d=char(n%256)
+ f:write(d,c,b,a)
+end
+function files.writestring(f,s)
+ f:write(char(byte(s,1,#s)))
+end
+function files.writebyte(f,b)
+ f:write(char(b))
+end
+if fio and fio.readcardinal1 then
+ files.readcardinal1=fio.readcardinal1
+ files.readcardinal2=fio.readcardinal2
+ files.readcardinal3=fio.readcardinal3
+ files.readcardinal4=fio.readcardinal4
+ files.readinteger1=fio.readinteger1
+ files.readinteger2=fio.readinteger2
+ files.readinteger3=fio.readinteger3
+ files.readinteger4=fio.readinteger4
+ files.readfixed2=fio.readfixed2
+ files.readfixed4=fio.readfixed4
+ files.read2dot14=fio.read2dot14
+ files.setposition=fio.setposition
+ files.getposition=fio.getposition
+ files.readbyte=files.readcardinal1
+ files.readsignedbyte=files.readinteger1
+ files.readcardinal=files.readcardinal1
+ files.readinteger=files.readinteger1
+ local skipposition=fio.skipposition
+ files.skipposition=skipposition
+ files.readbytes=fio.readbytes
+ files.readbytetable=fio.readbytetable
+ function files.skipshort(f,n)
+ skipposition(f,2*(n or 1))
+ end
+ function files.skiplong(f,n)
+ skipposition(f,4*(n or 1))
+ end
+end
+if fio and fio.readcardinaltable then
+ files.readcardinaltable=fio.readcardinaltable
+ files.readintegertable=fio.readintegertable
+else
+ local readcardinal1=files.readcardinal1
+ local readcardinal2=files.readcardinal2
+ local readcardinal3=files.readcardinal3
+ local readcardinal4=files.readcardinal4
+ function files.readcardinaltable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readcardinal1(f) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
+ return t
+ end
+ local readinteger1=files.readinteger1
+ local readinteger2=files.readinteger2
+ local readinteger3=files.readinteger3
+ local readinteger4=files.readinteger4
+ function files.readintegertable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readinteger1(f) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
+ return t
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-tab']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+utilities=utilities or {}
+utilities.tables=utilities.tables or {}
+local tables=utilities.tables
+local format,gmatch,gsub,sub=string.format,string.gmatch,string.gsub,string.sub
+local concat,insert,remove,sort=table.concat,table.insert,table.remove,table.sort
+local setmetatable,getmetatable,tonumber,tostring,rawget=setmetatable,getmetatable,tonumber,tostring,rawget
+local type,next,rawset,tonumber,tostring,load,select=type,next,rawset,tonumber,tostring,load,select
+local lpegmatch,P,Cs,Cc=lpeg.match,lpeg.P,lpeg.Cs,lpeg.Cc
+local sortedkeys,sortedpairs=table.sortedkeys,table.sortedpairs
+local formatters=string.formatters
+local utftoeight=utf.toeight
+local splitter=lpeg.tsplitat(".")
+function utilities.tables.definetable(target,nofirst,nolast)
+ local composed=nil
+ local t={}
+ local snippets=lpegmatch(splitter,target)
+ for i=1,#snippets-(nolast and 1 or 0) do
+ local name=snippets[i]
+ if composed then
+ composed=composed.."."..name
+ t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
+ else
+ composed=name
+ if not nofirst then
+ t[#t+1]=formatters["%s = %s or { }"](composed,composed)
+ end
+ end
+ end
+ if composed then
+ if nolast then
+ composed=composed.."."..snippets[#snippets]
+ end
+ return concat(t,"\n"),composed
+ else
+ return "",target
+ end
+end
+function tables.definedtable(...)
+ local t=_G
+ for i=1,select("#",...) do
+ local li=select(i,...)
+ local tl=t[li]
+ if not tl then
+ tl={}
+ t[li]=tl
+ end
+ t=tl
+ end
+ return t
+end
+function tables.accesstable(target,root)
+ local t=root or _G
+ for name in gmatch(target,"([^%.]+)") do
+ t=t[name]
+ if not t then
+ return
+ end
+ end
+ return t
+end
+function tables.migratetable(target,v,root)
+ local t=root or _G
+ local names=lpegmatch(splitter,target)
+ for i=1,#names-1 do
+ local name=names[i]
+ t[name]=t[name] or {}
+ t=t[name]
+ if not t then
+ return
+ end
+ end
+ t[names[#names]]=v
+end
+function tables.removevalue(t,value)
+ if value then
+ for i=1,#t do
+ if t[i]==value then
+ remove(t,i)
+ end
+ end
+ end
+end
+function tables.replacevalue(t,oldvalue,newvalue)
+ if oldvalue and newvalue then
+ for i=1,#t do
+ if t[i]==oldvalue then
+ t[i]=newvalue
+ end
+ end
+ end
+end
+function tables.insertbeforevalue(t,value,extra)
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
+ end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i,extra)
+ return
+ end
+ end
+ insert(t,1,extra)
+end
+function tables.insertaftervalue(t,value,extra)
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
+ end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i+1,extra)
+ return
+ end
+ end
+ insert(t,#t+1,extra)
+end
+local escape=Cs(Cc('"')*((P('"')/'""'+P(1))^0)*Cc('"'))
+function table.tocsv(t,specification)
+ if t and #t>0 then
+ local result={}
+ local r={}
+ specification=specification or {}
+ local fields=specification.fields
+ if type(fields)~="string" then
+ fields=sortedkeys(t[1])
+ end
+ local separator=specification.separator or ","
+ local noffields=#fields
+ if specification.preamble==true then
+ for f=1,noffields do
+ r[f]=lpegmatch(escape,tostring(fields[f]))
+ end
+ result[1]=concat(r,separator)
+ end
+ for i=1,#t do
+ local ti=t[i]
+ for f=1,noffields do
+ local field=ti[fields[f]]
+ if type(field)=="string" then
+ r[f]=lpegmatch(escape,field)
+ else
+ r[f]=tostring(field)
+ end
+ end
+ result[i+1]=concat(r,separator)
+ end
+ return concat(result,"\n")
+ else
+ return ""
+ end
+end
+local nspaces=utilities.strings.newrepeater(" ")
+local function toxml(t,d,result,step)
+ local r=#result
+ for k,v in sortedpairs(t) do
+ local s=nspaces[d]
+ local tk=type(k)
+ local tv=type(v)
+ if tv=="table" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</entry>"](s,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</%s>"](s,k)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
+ end
+ elseif tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
+ end
+ end
+end
+function table.toxml(t,specification)
+ specification=specification or {}
+ local name=specification.name
+ local noroot=name==false
+ local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
+ local indent=specification.indent or 0
+ local spaces=specification.spaces or 1
+ if noroot then
+ toxml(t,indent,result,spaces)
+ else
+ toxml({ [name or "data"]=t },indent,result,spaces)
+ end
+ return concat(result,"\n")
+end
+function tables.encapsulate(core,capsule,protect)
+ if type(capsule)~="table" then
+ protect=true
+ capsule={}
+ end
+ for key,value in next,core do
+ if capsule[key] then
+ print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
+ os.exit()
+ else
+ capsule[key]=value
+ end
+ end
+ if protect then
+ for key,value in next,core do
+ core[key]=nil
+ end
+ setmetatable(core,{
+ __index=capsule,
+ __newindex=function(t,key,value)
+ if capsule[key] then
+ print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
+ os.exit()
+ else
+ rawset(t,key,value)
+ end
+ end
+ } )
+ end
+end
+local f_hashed_string=formatters["[%Q]=%Q,"]
+local f_hashed_number=formatters["[%Q]=%s,"]
+local f_hashed_boolean=formatters["[%Q]=%l,"]
+local f_hashed_table=formatters["[%Q]="]
+local f_indexed_string=formatters["[%s]=%Q,"]
+local f_indexed_number=formatters["[%s]=%s,"]
+local f_indexed_boolean=formatters["[%s]=%l,"]
+local f_indexed_table=formatters["[%s]="]
+local f_ordered_string=formatters["%Q,"]
+local f_ordered_number=formatters["%s,"]
+local f_ordered_boolean=formatters["%l,"]
+function table.fastserialize(t,prefix)
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ for i=0,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
+ end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
+ end
+ else
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_hashed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_hashed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_hashed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_hashed_boolean(k,v)
+ end
+ end
+ end
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
+ end
+ return concat(fastserialize(t,true))
+end
+function table.deserialize(str)
+ if not str or str=="" then
+ return
+ end
+ local code=load(str)
+ if not code then
+ return
+ end
+ code=code()
+ if not code then
+ return
+ end
+ return code
+end
+function table.load(filename,loader)
+ if filename then
+ local t=(loader or io.loaddata)(filename)
+ if t and t~="" then
+ local t=utftoeight(t)
+ t=load(t)
+ if type(t)=="function" then
+ t=t()
+ if type(t)=="table" then
+ return t
+ end
+ end
+ end
+ end
+end
+function table.save(filename,t,n,...)
+ io.savedata(filename,table.serialize(t,n==nil and true or n,...))
+end
+local f_key_value=formatters["%s=%q"]
+local f_add_table=formatters[" {%t},\n"]
+local f_return_table=formatters["return {\n%t}"]
+local function slowdrop(t)
+ local r={}
+ local l={}
+ for i=1,#t do
+ local ti=t[i]
+ local j=0
+ for k,v in next,ti do
+ j=j+1
+ l[j]=f_key_value(k,v)
+ end
+ r[i]=f_add_table(l)
+ end
+ return f_return_table(r)
+end
+local function fastdrop(t)
+ local r={ "return {\n" }
+ local m=1
+ for i=1,#t do
+ local ti=t[i]
+ m=m+1 r[m]=" {"
+ for k,v in next,ti do
+ m=m+1 r[m]=f_key_value(k,v)
+ end
+ m=m+1 r[m]="},\n"
+ end
+ m=m+1
+ r[m]="}"
+ return concat(r)
+end
+function table.drop(t,slow)
+ if #t==0 then
+ return "return { }"
+ elseif slow==true then
+ return slowdrop(t)
+ else
+ return fastdrop(t)
+ end
+end
+local selfmapper={ __index=function(t,k) t[k]=k return k end }
+function table.twowaymapper(t)
+ if not t then
+ t={}
+ else
+ local zero=rawget(t,0)
+ for i=zero and 0 or 1,#t do
+ local ti=t[i]
+ if ti then
+ local i=tostring(i)
+ t[i]=ti
+ t[ti]=i
+ end
+ end
+ end
+ setmetatable(t,selfmapper)
+ return t
+end
+local f_start_key_idx=formatters["%w{"]
+local f_start_key_num=formatters["%w[%s]={"]
+local f_start_key_str=formatters["%w[%q]={"]
+local f_start_key_boo=formatters["%w[%l]={"]
+local f_start_key_nop=formatters["%w{"]
+local f_stop=formatters["%w},"]
+local f_key_num_value_num=formatters["%w[%s]=%s,"]
+local f_key_str_value_num=formatters["%w[%Q]=%s,"]
+local f_key_boo_value_num=formatters["%w[%l]=%s,"]
+local f_key_num_value_str=formatters["%w[%s]=%Q,"]
+local f_key_str_value_str=formatters["%w[%Q]=%Q,"]
+local f_key_boo_value_str=formatters["%w[%l]=%Q,"]
+local f_key_num_value_boo=formatters["%w[%s]=%l,"]
+local f_key_str_value_boo=formatters["%w[%Q]=%l,"]
+local f_key_boo_value_boo=formatters["%w[%l]=%l,"]
+local f_key_num_value_not=formatters["%w[%s]={},"]
+local f_key_str_value_not=formatters["%w[%Q]={},"]
+local f_key_boo_value_not=formatters["%w[%l]={},"]
+local f_key_num_value_seq=formatters["%w[%s]={ %, t },"]
+local f_key_str_value_seq=formatters["%w[%Q]={ %, t },"]
+local f_key_boo_value_seq=formatters["%w[%l]={ %, t },"]
+local f_val_num=formatters["%w%s,"]
+local f_val_str=formatters["%w%Q,"]
+local f_val_boo=formatters["%w%l,"]
+local f_val_not=formatters["%w{},"]
+local f_val_seq=formatters["%w{ %, t },"]
+local f_fin_seq=formatters[" %, t }"]
+local f_table_return=formatters["return {"]
+local f_table_name=formatters["%s={"]
+local f_table_direct=formatters["{"]
+local f_table_entry=formatters["[%Q]={"]
+local f_table_finish=formatters["}"]
+local spaces=utilities.strings.newrepeater(" ")
+local original_serialize=table.serialize
+local is_simple_table=table.is_simple_table
+local function serialize(root,name,specification)
+ if type(specification)=="table" then
+ return original_serialize(root,name,specification)
+ end
+ local t
+ local n=1
+ local unknown=false
+ local function do_serialize(root,name,depth,level,indexed)
+ if level>0 then
+ n=n+1
+ if indexed then
+ t[n]=f_start_key_idx(depth)
+ else
+ local tn=type(name)
+ if tn=="number" then
+ t[n]=f_start_key_num(depth,name)
+ elseif tn=="string" then
+ t[n]=f_start_key_str(depth,name)
+ elseif tn=="boolean" then
+ t[n]=f_start_key_boo(depth,name)
+ else
+ t[n]=f_start_key_nop(depth)
+ end
+ end
+ depth=depth+1
+ end
+ if root and next(root)~=nil then
+ local first=nil
+ local last=#root
+ if last>0 then
+ for k=1,last do
+ if rawget(root,k)==nil then
+ last=k-1
+ break
+ end
+ end
+ if last>0 then
+ first=1
+ end
+ end
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if first and tk=="number" and k<=last and k>=first then
+ if tv=="number" then
+ n=n+1 t[n]=f_val_num(depth,v)
+ elseif tv=="string" then
+ n=n+1 t[n]=f_val_str(depth,v)
+ elseif tv=="table" then
+ if next(v)==nil then
+ n=n+1 t[n]=f_val_not(depth)
+ else
+ local st=is_simple_table(v)
+ if st then
+ n=n+1 t[n]=f_val_seq(depth,st)
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ end
+ elseif tv=="boolean" then
+ n=n+1 t[n]=f_val_boo(depth,v)
+ elseif unknown then
+ n=n+1 t[n]=f_val_str(depth,tostring(v))
+ end
+ elseif tv=="number" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_num(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_num(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
+ end
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_not(depth,k)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_not(depth,k)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_not(depth,k)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
+ end
+ else
+ local st=is_simple_table(v)
+ if not st then
+ do_serialize(v,k,depth,level+1)
+ elseif tk=="number" then
+ n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
+ end
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
+ end
+ else
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
+ end
+ end
+ end
+ end
+ if level>0 then
+ n=n+1 t[n]=f_stop(depth-1)
+ end
+ end
+ local tname=type(name)
+ if tname=="string" then
+ if name=="return" then
+ t={ f_table_return() }
+ else
+ t={ f_table_name(name) }
+ end
+ elseif tname=="number" then
+ t={ f_table_entry(name) }
+ elseif tname=="boolean" then
+ if name then
+ t={ f_table_return() }
+ else
+ t={ f_table_direct() }
+ end
+ else
+ t={ f_table_name("t") }
+ end
+ if root then
+ if getmetatable(root) then
+ local dummy=root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_=nil
+ end
+ if next(root)~=nil then
+ local st=is_simple_table(root)
+ if st then
+ return t[1]..f_fin_seq(st)
+ else
+ do_serialize(root,name,1,0)
+ end
+ end
+ end
+ n=n+1
+ t[n]=f_table_finish()
+ return concat(t,"\n")
+end
+table.serialize=serialize
+if setinspector then
+ setinspector("table",function(v)
+ if type(v)=="table" then
+ print(serialize(v,"table",{ metacheck=false }))
+ return true
+ end
+ end)
+end
+local mt={
+ __newindex=function(t,k,v)
+ local n=t.last+1
+ t.last=n
+ t.list[n]=k
+ t.hash[k]=v
+ end,
+ __index=function(t,k)
+ return t.hash[k]
+ end,
+ __len=function(t)
+ return t.last
+ end,
+}
+function table.orderedhash()
+ return setmetatable({ list={},hash={},last=0 },mt)
+end
+function table.ordered(t)
+ local n=t.last
+ if n>0 then
+ local l=t.list
+ local i=1
+ local h=t.hash
+ local f=function()
+ if i<=n then
+ local k=i
+ local v=h[l[k]]
+ i=i+1
+ return k,v
+ end
+ end
+ return f,1,h[l[1]]
+ else
+ return function() end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-sto']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type
+utilities=utilities or {}
+utilities.storage=utilities.storage or {}
+local storage=utilities.storage
+function storage.mark(t)
+ if not t then
+ print("\nfatal error: storage cannot be marked\n")
+ os.exit()
+ return
+ end
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
+end
+function storage.allocate(t)
+ t=t or {}
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
+end
+function storage.marked(t)
+ local m=getmetatable(t)
+ return m and m.__storage__
+end
+function storage.checked(t)
+ if not t then
+ report("\nfatal error: storage has not been allocated\n")
+ os.exit()
+ return
+ end
+ return t
+end
+function storage.setinitializer(data,initialize)
+ local m=getmetatable(data) or {}
+ m.__index=function(data,k)
+ m.__index=nil
+ initialize()
+ return data[k]
+ end
+ setmetatable(data,m)
+end
+local keyisvalue={ __index=function(t,k)
+ t[k]=k
+ return k
+end }
+function storage.sparse(t)
+ t=t or {}
+ setmetatable(t,keyisvalue)
+ return t
+end
+local function f_empty () return "" end
+local function f_self (t,k) t[k]=k return k end
+local function f_table (t,k) local v={} t[k]=v return v end
+local function f_number(t,k) t[k]=0 return 0 end
+local function f_ignore() end
+local f_index={
+ ["empty"]=f_empty,
+ ["self"]=f_self,
+ ["table"]=f_table,
+ ["number"]=f_number,
+}
+function table.setmetatableindex(t,f)
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ else
+ setmetatable(t,{ __index=i })
+ end
+ return t
+end
+local f_index={
+ ["ignore"]=f_ignore,
+}
+function table.setmetatablenewindex(t,f)
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__newindex=i
+ else
+ setmetatable(t,{ __newindex=i })
+ end
+ return t
+end
+function table.setmetatablecall(t,f)
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__call=f
+ else
+ setmetatable(t,{ __call=f })
+ end
+ return t
+end
+function table.setmetatableindices(t,f,n,c)
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ m.__newindex=n
+ m.__call=c
+ else
+ setmetatable(t,{
+ __index=i,
+ __newindex=n,
+ __call=c,
+ })
+ end
+ return t
+end
+function table.setmetatablekey(t,key,value)
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m[key]=value
+ return t
+end
+function table.getmetatablekey(t,key,value)
+ local m=getmetatable(t)
+ return m and m[key]
+end
+function table.makeweak(t)
+ if not t then
+ t={}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__mode="v"
+ else
+ setmetatable(t,{ __mode="v" })
+ end
+ return t
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-prs']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local lpeg,table,string=lpeg,table,string
+local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp
+local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
+local concat,gmatch,find=table.concat,string.gmatch,string.find
+local tostring,type,next,rawset=tostring,type,next,rawset
+local mod,div=math.mod,math.div
+utilities=utilities or {}
+local parsers=utilities.parsers or {}
+utilities.parsers=parsers
+local patterns=parsers.patterns or {}
+parsers.patterns=patterns
+local setmetatableindex=table.setmetatableindex
+local sortedhash=table.sortedhash
+local sortedkeys=table.sortedkeys
+local tohash=table.tohash
+local hashes={}
+parsers.hashes=hashes
+local digit=R("09")
+local space=P(' ')
+local equal=P("=")
+local colon=P(":")
+local comma=P(",")
+local lbrace=P("{")
+local rbrace=P("}")
+local lparent=P("(")
+local rparent=P(")")
+local lbracket=P("[")
+local rbracket=P("]")
+local period=S(".")
+local punctuation=S(".,:;")
+local spacer=lpegpatterns.spacer
+local whitespace=lpegpatterns.whitespace
+local newline=lpegpatterns.newline
+local anything=lpegpatterns.anything
+local endofstring=lpegpatterns.endofstring
+local nobrace=1-(lbrace+rbrace )
+local noparent=1-(lparent+rparent)
+local nobracket=1-(lbracket+rbracket)
+local escape,left,right=P("\\"),P('{'),P('}')
+lpegpatterns.balanced=P {
+ [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
+ [2]=left*V(1)*right
+}
+local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
+local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
+local nestedbrackets=P { lbracket*(nobracket+V(1))^0*rbracket }
+local spaces=space^0
+local argument=Cs((lbrace/"")*((nobrace+nestedbraces)^0)*(rbrace/""))
+local content=(1-endofstring)^0
+lpegpatterns.nestedbraces=nestedbraces
+lpegpatterns.nestedparents=nestedparents
+lpegpatterns.nested=nestedbraces
+lpegpatterns.argument=argument
+lpegpatterns.content=content
+local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
+local key=C((1-equal-comma)^1)
+local pattern_a=(space+comma)^0*(key*equal*value+key*C(""))
+local pattern_c=(space+comma)^0*(key*equal*value)
+local pattern_d=(space+comma)^0*(key*(equal+colon)*value+key*C(""))
+local key=C((1-space-equal-comma)^1)
+local pattern_b=spaces*comma^0*spaces*(key*((spaces*equal*spaces*value)+C("")))
+local hash={}
+local function set(key,value)
+ hash[key]=value
+end
+local pattern_a_s=(pattern_a/set)^1
+local pattern_b_s=(pattern_b/set)^1
+local pattern_c_s=(pattern_c/set)^1
+local pattern_d_s=(pattern_d/set)^1
+patterns.settings_to_hash_a=pattern_a_s
+patterns.settings_to_hash_b=pattern_b_s
+patterns.settings_to_hash_c=pattern_c_s
+patterns.settings_to_hash_d=pattern_d_s
+function parsers.make_settings_to_hash_pattern(set,how)
+ if how=="strict" then
+ return (pattern_c/set)^1
+ elseif how=="tolerant" then
+ return (pattern_b/set)^1
+ else
+ return (pattern_a/set)^1
+ end
+end
+function parsers.settings_to_hash(str,existing)
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
+ else
+ return str
+ end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_a_s,str)
+ return hash
+ end
+end
+function parsers.settings_to_hash_colon_too(str)
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ else
+ hash={}
+ lpegmatch(pattern_d_s,str)
+ return hash
+ end
+end
+function parsers.settings_to_hash_tolerant(str,existing)
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
+ else
+ return str
+ end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_b_s,str)
+ return hash
+ end
+end
+function parsers.settings_to_hash_strict(str,existing)
+ if not str or str=="" then
+ return nil
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
+ else
+ return str
+ end
+ elseif str and str~="" then
+ hash=existing or {}
+ lpegmatch(pattern_c_s,str)
+ return next(hash) and hash
+ end
+end
+local separator=comma*space^0
+local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
+local pattern=spaces*Ct(value*(separator*value)^0)
+patterns.settings_to_array=pattern
+function parsers.settings_to_array(str,strict)
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ elseif strict then
+ if find(str,"{",1,true) then
+ return lpegmatch(pattern,str)
+ else
+ return { str }
+ end
+ elseif find(str,",",1,true) then
+ return lpegmatch(pattern,str)
+ else
+ return { str }
+ end
+end
+function parsers.settings_to_numbers(str)
+ if not str or str=="" then
+ return {}
+ end
+ if type(str)=="table" then
+ elseif find(str,",",1,true) then
+ str=lpegmatch(pattern,str)
+ else
+ return { tonumber(str) }
+ end
+ for i=1,#str do
+ str[i]=tonumber(str[i])
+ end
+ return str
+end
+local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
+local pattern=spaces*Ct(value*(separator*value)^0)
+function parsers.settings_to_array_obey_fences(str)
+ return lpegmatch(pattern,str)
+end
+local cache_a={}
+local cache_b={}
+function parsers.groupedsplitat(symbol,withaction)
+ if not symbol then
+ symbol=","
+ end
+ local pattern=(withaction and cache_b or cache_a)[symbol]
+ if not pattern then
+ local symbols=S(symbol)
+ local separator=space^0*symbols*space^0
+ local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
+ if withaction then
+ local withvalue=Carg(1)*value/function(f,s) return f(s) end
+ pattern=spaces*withvalue*(separator*withvalue)^0
+ cache_b[symbol]=pattern
+ else
+ pattern=spaces*Ct(value*(separator*value)^0)
+ cache_a[symbol]=pattern
+ end
+ end
+ return pattern
+end
+local pattern_a=parsers.groupedsplitat(",",false)
+local pattern_b=parsers.groupedsplitat(",",true)
+function parsers.stripped_settings_to_array(str)
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_a,str)
+ end
+end
+function parsers.process_stripped_settings(str,action)
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_b,str,1,action)
+ end
+end
+local function set(t,v)
+ t[#t+1]=v
+end
+local value=P(Carg(1)*value)/set
+local pattern=value*(separator*value)^0*Carg(1)
+function parsers.add_settings_to_array(t,str)
+ return lpegmatch(pattern,str,nil,t)
+end
+function parsers.hash_to_string(h,separator,yes,no,strict,omit)
+ if h then
+ local t={}
+ local tn=0
+ local s=sortedkeys(h)
+ omit=omit and tohash(omit)
+ for i=1,#s do
+ local key=s[i]
+ if not omit or not omit[key] then
+ local value=h[key]
+ if type(value)=="boolean" then
+ if yes and no then
+ if value then
+ tn=tn+1
+ t[tn]=key..'='..yes
+ elseif not strict then
+ tn=tn+1
+ t[tn]=key..'='..no
+ end
+ elseif value or not strict then
+ tn=tn+1
+ t[tn]=key..'='..tostring(value)
+ end
+ else
+ tn=tn+1
+ t[tn]=key..'='..value
+ end
+ end
+ end
+ return concat(t,separator or ",")
+ else
+ return ""
+ end
+end
+function parsers.array_to_string(a,separator)
+ if a then
+ return concat(a,separator or ",")
+ else
+ return ""
+ end
+end
+local pattern=Cf(Ct("")*Cg(C((1-S(", "))^1)*S(", ")^0*Cc(true))^1,rawset)
+function parsers.settings_to_set(str)
+ return str and lpegmatch(pattern,str) or {}
+end
+hashes.settings_to_set=table.setmetatableindex(function(t,k)
+ local v=k and lpegmatch(pattern,k) or {}
+ t[k]=v
+ return v
+end)
+getmetatable(hashes.settings_to_set).__mode="kv"
+function parsers.simple_hash_to_string(h,separator)
+ local t={}
+ local tn=0
+ for k,v in sortedhash(h) do
+ if v then
+ tn=tn+1
+ t[tn]=k
+ end
+ end
+ return concat(t,separator or ",")
+end
+local str=Cs(lpegpatterns.unquoted)+C((1-whitespace-equal)^1)
+local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset)
+local splitter=setting^1
+function parsers.options_to_hash(str,target)
+ return str and lpegmatch(splitter,str,1,target or {}) or {}
+end
+local splitter=lpeg.tsplitat(" ")
+function parsers.options_to_array(str)
+ return str and lpegmatch(splitter,str) or {}
+end
+local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1)
+local pattern_a=spaces*Ct(value*(separator*value)^0)
+local function repeater(n,str)
+ if not n then
+ return str
+ else
+ local s=lpegmatch(pattern_a,str)
+ if n==1 then
+ return unpack(s)
+ else
+ local t={}
+ local tn=0
+ for i=1,n do
+ for j=1,#s do
+ tn=tn+1
+ t[tn]=s[j]
+ end
+ end
+ return unpack(t)
+ end
+ end
+end
+local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+(C(digit^1)/tonumber*lparent*Cs((noparent+nestedparents)^1)*rparent)/repeater+C((nestedbraces+(1-comma))^1)
+local pattern_b=spaces*Ct(value*(separator*value)^0)
+function parsers.settings_to_array_with_repeat(str,expand)
+ if expand then
+ return lpegmatch(pattern_b,str) or {}
+ else
+ return lpegmatch(pattern_a,str) or {}
+ end
+end
+local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace
+local pattern=Ct((space+value)^0)
+function parsers.arguments_to_table(str)
+ return lpegmatch(pattern,str)
+end
+function parsers.getparameters(self,class,parentclass,settings)
+ local sc=self[class]
+ if not sc then
+ sc={}
+ self[class]=sc
+ if parentclass then
+ local sp=self[parentclass]
+ if not sp then
+ sp={}
+ self[parentclass]=sp
+ end
+ setmetatableindex(sc,sp)
+ end
+ end
+ parsers.settings_to_hash(settings,sc)
+end
+function parsers.listitem(str)
+ return gmatch(str,"[^, ]+")
+end
+local pattern=Cs { "start",
+ start=V("one")+V("two")+V("three"),
+ rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
+ thousand=digit*digit*digit,
+ one=digit*V("rest"),
+ two=digit*digit*V("rest"),
+ three=V("thousand")*V("rest"),
+}
+lpegpatterns.splitthousands=pattern
+function parsers.splitthousands(str)
+ return lpegmatch(pattern,str) or str
+end
+local optionalwhitespace=whitespace^0
+lpegpatterns.words=Ct((Cs((1-punctuation-whitespace)^1)+anything)^1)
+lpegpatterns.sentences=Ct((optionalwhitespace*Cs((1-period)^0*period))^1)
+lpegpatterns.paragraphs=Ct((optionalwhitespace*Cs((whitespace^1*endofstring/""+1-(spacer^0*newline*newline))^1))^1)
+local dquote=P('"')
+local equal=P('=')
+local escape=P('\\')
+local separator=S(' ,')
+local key=C((1-equal)^1)
+local value=dquote*C((1-dquote-escape*dquote)^0)*dquote
+local pattern=Cf(Ct("")*(Cg(key*equal*value)*separator^0)^1,rawset)^0*P(-1)
+function parsers.keq_to_hash(str)
+ if str and str~="" then
+ return lpegmatch(pattern,str)
+ else
+ return {}
+ end
+end
+local defaultspecification={ separator=",",quote='"' }
+function parsers.csvsplitter(specification)
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=specification.quote
+ local separator=S(separator~="" and separator or ",")
+ local whatever=C((1-separator-newline)^0)
+ if quotechar and quotechar~="" then
+ local quotedata=nil
+ for chr in gmatch(quotechar,".") do
+ local quotechar=P(chr)
+ local quoteword=quotechar*C((1-quotechar)^0)*quotechar
+ if quotedata then
+ quotedata=quotedata+quoteword
+ else
+ quotedata=quoteword
+ end
+ end
+ whatever=quotedata+whatever
+ end
+ local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
+ return function(data)
+ return lpegmatch(parser,data)
+ end
+end
+function parsers.rfc4180splitter(specification)
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=P(specification.quote)
+ local dquotechar=quotechar*quotechar
+/specification.quote
+ local separator=S(separator~="" and separator or ",")
+ local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
+ local non_escaped=C((1-quotechar-newline-separator)^1)
+ local field=escaped+non_escaped+Cc("")
+ local record=Ct(field*(separator*field)^1)
+ local headerline=record*Cp()
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
+ return function(data,getheader)
+ if getheader then
+ local header,position=lpegmatch(headerline,data)
+ local data=lpegmatch(headeryes,data,position)
+ return data,header
+ else
+ return lpegmatch(headernop,data)
+ end
+ end
+end
+local function ranger(first,last,n,action)
+ if not first then
+ elseif last==true then
+ for i=first,n or first do
+ action(i)
+ end
+ elseif last then
+ for i=first,last do
+ action(i)
+ end
+ else
+ action(first)
+ end
+end
+local cardinal=lpegpatterns.cardinal/tonumber
+local spacers=lpegpatterns.spacer^0
+local endofstring=lpegpatterns.endofstring
+local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
+local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
+function parsers.stepper(str,n,action)
+ if type(n)=="function" then
+ lpegmatch(stepper,str,1,false,n or print)
+ else
+ lpegmatch(stepper,str,1,n,action or print)
+ end
+end
+local pattern_math=Cs((P("%")/"\\percent "+P("^")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
+local pattern_text=Cs((P("%")/"\\percent "+(P("^")/"\\high")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
+patterns.unittotex=pattern
+function parsers.unittotex(str,textmode)
+ return lpegmatch(textmode and pattern_text or pattern_math,str)
+end
+local pattern=Cs((P("^")/"<sup>"*lpegpatterns.integer*Cc("</sup>")+anything)^0)
+function parsers.unittoxml(str)
+ return lpegmatch(pattern,str)
+end
+local cache={}
+local spaces=lpegpatterns.space^0
+local dummy=function() end
+setmetatableindex(cache,function(t,k)
+ local separator=P(k)
+ local value=(1-separator)^0
+ local pattern=spaces*C(value)*separator^0*Cp()
+ t[k]=pattern
+ return pattern
+end)
+local commalistiterator=cache[","]
+function parsers.iterator(str,separator)
+ local n=#str
+ if n==0 then
+ return dummy
+ else
+ local pattern=separator and cache[separator] or commalistiterator
+ local p=1
+ return function()
+ if p<=n then
+ local s,e=lpegmatch(pattern,str,p)
+ if e then
+ p=e
+ return s
+ end
+ end
+ end
+ end
+end
+local function initialize(t,name)
+ local source=t[name]
+ if source then
+ local result={}
+ for k,v in next,t[name] do
+ result[k]=v
+ end
+ return result
+ else
+ return {}
+ end
+end
+local function fetch(t,name)
+ return t[name] or {}
+end
+local function process(result,more)
+ for k,v in next,more do
+ result[k]=v
+ end
+ return result
+end
+local name=C((1-S(", "))^1)
+local parser=(Carg(1)*name/initialize)*(S(", ")^1*(Carg(1)*name/fetch))^0
+local merge=Cf(parser,process)
+function parsers.mergehashes(hash,list)
+ return lpegmatch(merge,list,1,hash)
+end
+function parsers.runtime(time)
+ if not time then
+ time=os.runtime()
+ end
+ local days=div(time,24*60*60)
+ time=mod(time,24*60*60)
+ local hours=div(time,60*60)
+ time=mod(time,60*60)
+ local minutes=div(time,60)
+ local seconds=mod(time,60)
+ return days,hours,minutes,seconds
+end
+local spacing=whitespace^0
+local apply=P("->")
+local method=C((1-apply)^1)
+local token=lbrace*C((1-rbrace)^1)*rbrace+C(anything^1)
+local pattern=spacing*(method*spacing*apply+Carg(1))*spacing*token
+function parsers.splitmethod(str,default)
+ if str then
+ return lpegmatch(pattern,str,1,default or false)
+ else
+ return default or false,""
+ end
+end
+local p_year=lpegpatterns.digit^4/tonumber
+local pattern=Cf(Ct("")*(
+ (Cg(Cc("year")*p_year)*S("-/")*Cg(Cc("month")*cardinal)*S("-/")*Cg(Cc("day")*cardinal)
+ )+(Cg(Cc("day")*cardinal)*S("-/")*Cg(Cc("month")*cardinal)*S("-/")*Cg(Cc("year")*p_year)
+ )
+ )*P(" ")*Cg(Cc("hour")*cardinal)*P(":")*Cg(Cc("min")*cardinal)*(P(":")*Cg(Cc("sec")*cardinal))^-1
+,rawset)
+lpegpatterns.splittime=pattern
+function parsers.totime(str)
+ return lpegmatch(pattern,str)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-dim']={
+ version=1.001,
+ comment="support for dimensions",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local format,match,gsub,type,setmetatable=string.format,string.match,string.gsub,type,setmetatable
+local P,S,R,Cc,C,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.Cc,lpeg.C,lpeg.match
+local allocate=utilities.storage.allocate
+local setmetatableindex=table.setmetatableindex
+local formatters=string.formatters
+local texget=tex and tex.get or function() return 65536*10*100 end
+local p_stripzeros=lpeg.patterns.stripzeros
+number=number or {}
+local number=number
+number.tonumberf=function(n) return lpegmatch(p_stripzeros,format("%.20f",n)) end
+number.tonumberg=function(n) return format("%.20g",n) end
+local dimenfactors=allocate {
+ ["pt"]=1/65536,
+ ["in"]=(100/7227)/65536,
+ ["cm"]=(254/7227)/65536,
+ ["mm"]=(2540/7227)/65536,
+ ["sp"]=1,
+ ["bp"]=(7200/7227)/65536,
+ ["pc"]=(1/12)/65536,
+ ["dd"]=(1157/1238)/65536,
+ ["cc"]=(1157/14856)/65536,
+ ["nd"]=(20320/21681)/65536,
+ ["nc"]=(5080/65043)/65536
+}
+local f_none=formatters["%s%s"]
+local f_true=formatters["%0.5F%s"]
+local function numbertodimen(n,unit,fmt)
+ if type(n)=='string' then
+ return n
+ else
+ unit=unit or 'pt'
+ n=n*dimenfactors[unit]
+ if not fmt then
+ fmt=f_none(n,unit)
+ elseif fmt==true then
+ fmt=f_true(n,unit)
+ else
+ return formatters[fmt](n,unit)
+ end
+ end
+end
+number.maxdimen=1073741823
+number.todimen=numbertodimen
+number.dimenfactors=dimenfactors
+function number.topoints (n,fmt) return numbertodimen(n,"pt",fmt) end
+function number.toinches (n,fmt) return numbertodimen(n,"in",fmt) end
+function number.tocentimeters (n,fmt) return numbertodimen(n,"cm",fmt) end
+function number.tomillimeters (n,fmt) return numbertodimen(n,"mm",fmt) end
+function number.toscaledpoints(n,fmt) return numbertodimen(n,"sp",fmt) end
+function number.toscaledpoints(n) return n.."sp" end
+function number.tobasepoints (n,fmt) return numbertodimen(n,"bp",fmt) end
+function number.topicas (n,fmt) return numbertodimen(n "pc",fmt) end
+function number.todidots (n,fmt) return numbertodimen(n,"dd",fmt) end
+function number.tociceros (n,fmt) return numbertodimen(n,"cc",fmt) end
+function number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end
+function number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end
+local amount=(S("+-")^0*R("09")^0*P(".")^0*R("09")^0)+Cc("0")
+local unit=R("az")^1+P("%")
+local dimenpair=amount/tonumber*(unit^1/dimenfactors+Cc(1))
+lpeg.patterns.dimenpair=dimenpair
+local splitter=amount/tonumber*C(unit^1)
+function number.splitdimen(str)
+ return lpegmatch(splitter,str)
+end
+setmetatableindex(dimenfactors,function(t,s)
+ return false
+end)
+local stringtodimen
+local amount=S("+-")^0*R("09")^0*S(".,")^0*R("09")^0
+local unit=P("pt")+P("cm")+P("mm")+P("sp")+P("bp")+P("in")+P("pc")+P("dd")+P("cc")+P("nd")+P("nc")
+local validdimen=amount*unit
+lpeg.patterns.validdimen=validdimen
+local dimensions={}
+function dimensions.__add(a,b)
+ local ta,tb=type(a),type(b)
+ if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
+ if tb=="string" then b=stringtodimen(b) elseif tb=="table" then b=b[1] end
+ return setmetatable({ a+b },dimensions)
+end
+function dimensions.__sub(a,b)
+ local ta,tb=type(a),type(b)
+ if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
+ if tb=="string" then b=stringtodimen(b) elseif tb=="table" then b=b[1] end
+ return setmetatable({ a-b },dimensions)
+end
+function dimensions.__mul(a,b)
+ local ta,tb=type(a),type(b)
+ if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
+ if tb=="string" then b=stringtodimen(b) elseif tb=="table" then b=b[1] end
+ return setmetatable({ a*b },dimensions)
+end
+function dimensions.__div(a,b)
+ local ta,tb=type(a),type(b)
+ if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
+ if tb=="string" then b=stringtodimen(b) elseif tb=="table" then b=b[1] end
+ return setmetatable({ a/b },dimensions)
+end
+function dimensions.__unm(a)
+ local ta=type(a)
+ if ta=="string" then a=stringtodimen(a) elseif ta=="table" then a=a[1] end
+ return setmetatable({-a },dimensions)
+end
+function dimensions.__lt(a,b)
+ return a[1]<b[1]
+end
+function dimensions.__eq(a,b)
+ return a[1]==b[1]
+end
+function dimensions.__tostring(a)
+ return a[1]/65536 .."pt"
+end
+function dimensions.__index(tab,key)
+ local d=dimenfactors[key]
+ if not d then
+ error("illegal property of dimen: "..key)
+ d=1
+ end
+ return 1/d
+end
+ dimenfactors["ex"]=4*1/65536
+ dimenfactors["em"]=10*1/65536
+local known={} setmetatable(known,{ __mode="v" })
+function dimen(a)
+ if a then
+ local ta=type(a)
+ if ta=="string" then
+ local k=known[a]
+ if k then
+ a=k
+ else
+ local value,unit=lpegmatch(dimenpair,a)
+ if value and unit then
+ k=value/unit
+ else
+ k=0
+ end
+ known[a]=k
+ a=k
+ end
+ elseif ta=="table" then
+ a=a[1]
+ end
+ return setmetatable({ a },dimensions)
+ else
+ return setmetatable({ 0 },dimensions)
+ end
+end
+function string.todimen(str)
+ local t=type(str)
+ if t=="number" then
+ return str
+ else
+ local k=known[str]
+ if not k then
+ if t=="string" then
+ local value,unit=lpegmatch(dimenpair,str)
+ if value and unit then
+ k=value/unit
+ else
+ k=0
+ end
+ else
+ k=0
+ end
+ known[str]=k
+ end
+ return k
+ end
+end
+stringtodimen=string.todimen
+function number.toscaled(d)
+ return format("%0.5f",d/0x10000)
+end
+function number.percent(n,d)
+ d=d or texget("hsize")
+ if type(d)=="string" then
+ d=stringtodimen(d)
+ end
+ return (n/100)*d
+end
+number["%"]=number.percent
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-jsn']={
+ version=1.001,
+ comment="companion to m-json.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local P,V,R,S,C,Cc,Cs,Ct,Cf,Cg=lpeg.P,lpeg.V,lpeg.R,lpeg.S,lpeg.C,lpeg.Cc,lpeg.Cs,lpeg.Ct,lpeg.Cf,lpeg.Cg
+local lpegmatch=lpeg.match
+local format,gsub=string.format,string.gsub
+local formatters=string.formatters
+local utfchar=utf.char
+local concat,sortedkeys=table.concat,table.sortedkeys
+local tonumber,tostring,rawset,type,next=tonumber,tostring,rawset,type,next
+local json=utilities.json or {}
+utilities.json=json
+do
+ local lbrace=P("{")
+ local rbrace=P("}")
+ local lparent=P("[")
+ local rparent=P("]")
+ local comma=P(",")
+ local colon=P(":")
+ local dquote=P('"')
+ local whitespace=lpeg.patterns.whitespace
+ local optionalws=whitespace^0
+ local escapes={
+ ["b"]="\010",
+ ["f"]="\014",
+ ["n"]="\n",
+ ["r"]="\r",
+ ["t"]="\t",
+ }
+ local escape_un=P("\\u")/""*(C(R("09","AF","af")^-4)/function(s)
+ return utfchar(tonumber(s,16))
+ end)
+ local escape_bs=P([[\]])/""*(P(1)/escapes)
+ local jstring=dquote*Cs((escape_un+escape_bs+(1-dquote))^0)*dquote
+ local jtrue=P("true")*Cc(true)
+ local jfalse=P("false")*Cc(false)
+ local jnull=P("null")*Cc(nil)
+ local jnumber=(1-whitespace-rparent-rbrace-comma)^1/tonumber
+ local key=jstring
+ local jsonconverter={ "value",
+ hash=lbrace*Cf(Ct("")*(V("pair")*(comma*V("pair"))^0+optionalws),rawset)*rbrace,
+ pair=Cg(optionalws*key*optionalws*colon*V("value")),
+ array=Ct(lparent*(V("value")*(comma*V("value"))^0+optionalws)*rparent),
+ value=optionalws*(jstring+V("hash")+V("array")+jtrue+jfalse+jnull+jnumber)*optionalws,
+ }
+ function json.tolua(str)
+ return lpegmatch(jsonconverter,str)
+ end
+ function json.load(filename)
+ local data=io.loaddata(filename)
+ if data then
+ return lpegmatch(jsonconverter,data)
+ end
+ end
+end
+do
+ local escaper
+ local f_start_hash=formatters[ '%w{' ]
+ local f_start_array=formatters[ '%w[' ]
+ local f_start_hash_new=formatters[ "\n"..'%w{' ]
+ local f_start_array_new=formatters[ "\n"..'%w[' ]
+ local f_start_hash_key=formatters[ "\n"..'%w"%s" : {' ]
+ local f_start_array_key=formatters[ "\n"..'%w"%s" : [' ]
+ local f_stop_hash=formatters[ "\n"..'%w}' ]
+ local f_stop_array=formatters[ "\n"..'%w]' ]
+ local f_key_val_seq=formatters[ "\n"..'%w"%s" : %s' ]
+ local f_key_val_str=formatters[ "\n"..'%w"%s" : "%s"' ]
+ local f_key_val_num=f_key_val_seq
+ local f_key_val_yes=formatters[ "\n"..'%w"%s" : true' ]
+ local f_key_val_nop=formatters[ "\n"..'%w"%s" : false' ]
+ local f_key_val_null=formatters[ "\n"..'%w"%s" : null' ]
+ local f_val_num=formatters[ "\n"..'%w%s' ]
+ local f_val_str=formatters[ "\n"..'%w"%s"' ]
+ local f_val_yes=formatters[ "\n"..'%wtrue' ]
+ local f_val_nop=formatters[ "\n"..'%wfalse' ]
+ local f_val_null=formatters[ "\n"..'%wnull' ]
+ local f_val_empty=formatters[ "\n"..'%w{ }' ]
+ local f_val_seq=f_val_num
+ local t={}
+ local n=0
+ local function is_simple_table(tt)
+ local l=#tt
+ if l>0 then
+ for i=1,l do
+ if type(tt[i])=="table" then
+ return false
+ end
+ end
+ local nn=n
+ n=n+1 t[n]="[ "
+ for i=1,l do
+ if i>1 then
+ n=n+1 t[n]=", "
+ end
+ local v=tt[i]
+ local tv=type(v)
+ if tv=="number" then
+ n=n+1 t[n]=v
+ elseif tv=="string" then
+ n=n+1 t[n]='"'
+ n=n+1 t[n]=lpegmatch(escaper,v) or v
+ n=n+1 t[n]='"'
+ elseif tv=="boolean" then
+ n=n+1 t[n]=v and "true" or "false"
+ elseif v then
+ n=n+1 t[n]=tostring(v)
+ else
+ n=n+1 t[n]="null"
+ end
+ end
+ n=n+1 t[n]=" ]"
+ local s=concat(t,"",nn+1,n)
+ n=nn
+ return s
+ end
+ return false
+ end
+ local function tojsonpp(root,name,depth,level,size)
+ if root then
+ local indexed=size>0
+ n=n+1
+ if level==0 then
+ if indexed then
+ t[n]=f_start_array(depth)
+ else
+ t[n]=f_start_hash(depth)
+ end
+ elseif name then
+ if tn=="string" then
+ name=lpegmatch(escaper,name) or name
+ elseif tn~="number" then
+ name=tostring(name)
+ end
+ if indexed then
+ t[n]=f_start_array_key(depth,name)
+ else
+ t[n]=f_start_hash_key(depth,name)
+ end
+ else
+ if indexed then
+ t[n]=f_start_array_new(depth)
+ else
+ t[n]=f_start_hash_new(depth)
+ end
+ end
+ depth=depth+1
+ if indexed then
+ for i=1,size do
+ if i>1 then
+ n=n+1 t[n]=","
+ end
+ local v=root[i]
+ local tv=type(v)
+ if tv=="number" then
+ n=n+1 t[n]=f_val_num(depth,v)
+ elseif tv=="string" then
+ v=lpegmatch(escaper,v) or v
+ n=n+1 t[n]=f_val_str(depth,v)
+ elseif tv=="table" then
+ if next(v) then
+ local st=is_simple_table(v)
+ if st then
+ n=n+1 t[n]=f_val_seq(depth,st)
+ else
+ tojsonpp(v,nil,depth,level+1,#v)
+ end
+ else
+ n=n+1
+ t[n]=f_val_empty(depth)
+ end
+ elseif tv=="boolean" then
+ n=n+1
+ if v then
+ t[n]=f_val_yes(depth,v)
+ else
+ t[n]=f_val_nop(depth,v)
+ end
+ else
+ n=n+1
+ t[n]=f_val_null(depth)
+ end
+ end
+ elseif next(root) then
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ if i>1 then
+ n=n+1 t[n]=","
+ end
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if tv=="number" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_val_num(depth,k,v)
+ elseif tk=="string" then
+ k=lpegmatch(escaper,k) or k
+ n=n+1 t[n]=f_key_val_num(depth,k,v)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ v=lpegmatch(escaper,v) or v
+ n=n+1 t[n]=f_key_val_str(depth,k,v)
+ elseif tk=="string" then
+ k=lpegmatch(escaper,k) or k
+ v=lpegmatch(escaper,v) or v
+ n=n+1 t[n]=f_key_val_str(depth,k,v)
+ end
+ elseif tv=="table" then
+ local l=#v
+ if l>0 then
+ local st=is_simple_table(v)
+ if not st then
+ tojsonpp(v,k,depth,level+1,l)
+ elseif tk=="number" then
+ n=n+1 t[n]=f_key_val_seq(depth,k,st)
+ elseif tk=="string" then
+ k=lpegmatch(escaper,k) or k
+ n=n+1 t[n]=f_key_val_seq(depth,k,st)
+ end
+ elseif next(v) then
+ tojsonpp(v,k,depth,level+1,0)
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ n=n+1
+ if v then
+ t[n]=f_key_val_yes(depth,k)
+ else
+ t[n]=f_key_val_nop(depth,k)
+ end
+ elseif tk=="string" then
+ k=lpegmatch(escaper,k) or k
+ n=n+1
+ if v then
+ t[n]=f_key_val_yes(depth,k)
+ else
+ t[n]=f_key_val_nop(depth,k)
+ end
+ end
+ else
+ if tk=="number" then
+ n=n+1
+ t[n]=f_key_val_null(depth,k)
+ elseif tk=="string" then
+ k=lpegmatch(escaper,k) or k
+ n=n+1
+ t[n]=f_key_val_null(depth,k)
+ end
+ end
+ end
+ end
+ n=n+1
+ if indexed then
+ t[n]=f_stop_array(depth-1)
+ else
+ t[n]=f_stop_hash(depth-1)
+ end
+ end
+ end
+ local function tojson(value,n)
+ local kind=type(value)
+ if kind=="table" then
+ local done=false
+ local size=#value
+ if size==0 then
+ for k,v in next,value do
+ if done then
+ n=n+1;t[n]=',"'
+ else
+ n=n+1;t[n]='{"'
+ done=true
+ end
+ n=n+1;t[n]=lpegmatch(escaper,k) or k
+ n=n+1;t[n]='":'
+ t,n=tojson(v,n)
+ end
+ if done then
+ n=n+1;t[n]="}"
+ else
+ n=n+1;t[n]="{}"
+ end
+ elseif size==1 then
+ n=n+1;t[n]="["
+ t,n=tojson(value[1],n)
+ n=n+1;t[n]="]"
+ else
+ for i=1,size do
+ if done then
+ n=n+1;t[n]=","
+ else
+ n=n+1;t[n]="["
+ done=true
+ end
+ t,n=tojson(value[i],n)
+ end
+ n=n+1;t[n]="]"
+ end
+ elseif kind=="string" then
+ n=n+1;t[n]='"'
+ n=n+1;t[n]=lpegmatch(escaper,value) or value
+ n=n+1;t[n]='"'
+ elseif kind=="number" then
+ n=n+1;t[n]=value
+ elseif kind=="boolean" then
+ n=n+1;t[n]=tostring(value)
+ else
+ n=n+1;t[n]="null"
+ end
+ return t,n
+ end
+ local function jsontostring(value,pretty)
+ local kind=type(value)
+ if kind=="table" then
+ if not escaper then
+ local escapes={
+ ["\\"]="\\u005C",
+ ["\""]="\\u0022",
+ }
+ for i=0,0x1F do
+ escapes[utfchar(i)]=format("\\u%04X",i)
+ end
+ escaper=Cs((
+ (R('\0\x20')+S('\"\\'))/escapes+P(1)
+ )^1 )
+ end
+ t={}
+ n=0
+ if pretty then
+ tojsonpp(value,name,0,0,#value)
+ value=concat(t,"",1,n)
+ else
+ t,n=tojson(value,0)
+ value=concat(t,"",1,n)
+ end
+ t=nil
+ n=0
+ return value
+ elseif kind=="string" or kind=="number" then
+ return lpegmatch(escaper,value) or value
+ else
+ return tostring(value)
+ end
+ end
+ json.tostring=jsontostring
+ function json.tojson(value)
+ return jsontostring(value,true)
+ end
+end
+return json
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['trac-inf']={
+ version=1.001,
+ comment="companion to trac-inf.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local type,tonumber,select=type,tonumber,select
+local format,lower,find=string.format,string.lower,string.find
+local concat=table.concat
+local clock=os.gettimeofday or os.clock
+local setmetatableindex=table.setmetatableindex
+local serialize=table.serialize
+local formatters=string.formatters
+statistics=statistics or {}
+local statistics=statistics
+statistics.enable=true
+statistics.threshold=0.01
+local statusinfo,n,registered,timers={},0,{},{}
+setmetatableindex(timers,function(t,k)
+ local v={ timing=0,loadtime=0,offset=0 }
+ t[k]=v
+ return v
+end)
+local function hastiming(instance)
+ return instance and timers[instance]
+end
+local function resettiming(instance)
+ timers[instance or "notimer"]={ timing=0,loadtime=0,offset=0 }
+end
+local ticks=clock
+local seconds=function(n) return n or 0 end
+local function starttiming(instance,reset)
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if reset then
+ it=0
+ timer.loadtime=0
+ end
+ if it==0 then
+ timer.starttime=ticks()
+ if not timer.loadtime then
+ timer.loadtime=0
+ end
+ end
+ timer.timing=it+1
+end
+local function stoptiming(instance)
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
+ timer.timing=it-1
+ else
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ local stoptime=ticks()
+ local loadtime=stoptime-starttime
+ timer.stoptime=stoptime
+ timer.loadtime=timer.loadtime+loadtime
+ timer.timing=0
+ timer.starttime=0
+ return loadtime
+ end
+ end
+ return 0
+end
+local function benchmarktimer(instance)
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
+ timer.timing=it-1
+ else
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ timer.offset=ticks()-starttime
+ else
+ timer.offset=0
+ end
+ end
+end
+local function elapsed(instance)
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ return timer and seconds(timer.loadtime-2*(timer.offset or 0)) or 0
+ end
+end
+local function currenttime(instance)
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
+ else
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ return seconds(timer.loadtime+ticks()-starttime-2*(timer.offset or 0))
+ end
+ end
+ return 0
+ end
+end
+local function elapsedtime(instance)
+ return format("%0.3f",elapsed(instance))
+end
+local function elapsedindeed(instance)
+ return elapsed(instance)>statistics.threshold
+end
+local function elapsedseconds(instance,rest)
+ if elapsedindeed(instance) then
+ return format("%0.3f seconds %s",elapsed(instance),rest or "")
+ end
+end
+statistics.hastiming=hastiming
+statistics.resettiming=resettiming
+statistics.starttiming=starttiming
+statistics.stoptiming=stoptiming
+statistics.currenttime=currenttime
+statistics.elapsed=elapsed
+statistics.elapsedtime=elapsedtime
+statistics.elapsedindeed=elapsedindeed
+statistics.elapsedseconds=elapsedseconds
+statistics.benchmarktimer=benchmarktimer
+function statistics.register(tag,fnc)
+ if statistics.enable and type(fnc)=="function" then
+ local rt=registered[tag] or (#statusinfo+1)
+ statusinfo[rt]={ tag,fnc }
+ registered[tag]=rt
+ if #tag>n then n=#tag end
+ end
+end
+local report=logs.reporter("mkiv lua stats")
+function statistics.show()
+ if statistics.enable then
+ local register=statistics.register
+ register("used platform",function()
+ return format("%s, type: %s, binary subtree: %s",
+ os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
+ end)
+ if LUATEXENGINE=="luametatex" then
+ register("used engine",function()
+ return format("%s version %s, functionality level %s, format id %s",
+ LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID)
+ end)
+ else
+ register("used engine",function()
+ return format("%s version %s with functionality level %s, banner: %s",
+ LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
+ end)
+ end
+ register("control sequences",function()
+ return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
+ end)
+ register("callbacks",statistics.callbacks)
+ if TEXENGINE=="luajittex" and JITSUPPORTED then
+ local jitstatus=jit.status
+ if jitstatus then
+ local jitstatus={ jitstatus() }
+ if jitstatus[1] then
+ register("luajit options",concat(jitstatus," ",2))
+ end
+ end
+ end
+ register("lua properties",function()
+ local hashchar=tonumber(status.luatex_hashchars)
+ local mask=lua.mask or "ascii"
+ return format("engine: %s %s, used memory: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
+ jit and "luajit" or "lua",
+ LUAVERSION,
+ statistics.memused(),
+ hashchar and 2^hashchar or "unknown",
+ mask,
+ mask=="utf" and "τεχ" or "tex")
+ end)
+ register("runtime",statistics.runtime)
+ logs.newline()
+ for i=1,#statusinfo do
+ local s=statusinfo[i]
+ local r=s[2]()
+ if r then
+ report("%s: %s",s[1],r)
+ end
+ end
+ statistics.enable=false
+ end
+end
+function statistics.memused()
+ local round=math.round or math.floor
+ return format("%s MB, ctx: %s MB, max: %s MB)",
+ round(collectgarbage("count")/1000),
+ round(status.luastate_bytes/1000000),
+ status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"
+ )
+end
+starttiming(statistics)
+function statistics.formatruntime(runtime)
+ return format("%s seconds",runtime)
+end
+function statistics.runtime()
+ stoptiming(statistics)
+ local runtime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
+end
+local report=logs.reporter("system")
+function statistics.timed(action,all)
+ starttiming("run")
+ action()
+ stoptiming("run")
+ local runtime=tonumber(elapsedtime("run"))
+ if all then
+ local alltime=tonumber(lua.getruntime and lua.getruntime() or elapsedtime(statistics))
+ if alltime and alltime>0 then
+ report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime)
+ return
+ end
+ end
+ report("total runtime: %0.3f seconds",runtime)
+end
+function statistics.tracefunction(base,tag,...)
+ for i=1,select("#",...) do
+ local name=select(i,...)
+ local stat={}
+ local func=base[name]
+ setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
+ base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
+ statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-lua']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ comment="the strip code is written by Peter Cawley",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format
+local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage
+utilities=utilities or {}
+utilities.lua=utilities.lua or {}
+local luautilities=utilities.lua
+local report_lua=logs.reporter("system","lua")
+local report_mem=logs.reporter("system","lua memory")
+local tracestripping=false
+local tracememory=false
+luautilities.stripcode=true
+luautilities.alwaysstripcode=false
+luautilities.nofstrippedchunks=0
+luautilities.nofstrippedbytes=0
+local strippedchunks={}
+luautilities.strippedchunks=strippedchunks
+luautilities.suffixes={
+ tma="tma",
+ tmc=(CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 and "tmd") or (jit and "tmb") or "tmc",
+ lua="lua",
+ luc=(CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 and "lud") or (jit and "lub") or "luc",
+ lui="lui",
+ luv="luv",
+ luj="luj",
+ tua="tua",
+ tuc="tuc",
+}
+local function register(name)
+ if tracestripping then
+ report_lua("stripped bytecode from %a",name or "unknown")
+ end
+ strippedchunks[#strippedchunks+1]=name
+ luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
+end
+local function stupidcompile(luafile,lucfile,strip)
+ local code=io.loaddata(luafile)
+ if code and code~="" then
+ code=load(code)
+ if code then
+ code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
+ if code and code~="" then
+ register(name)
+ io.savedata(lucfile,code)
+ return true,0
+ end
+ else
+ report_lua("fatal error %a in file %a",1,luafile)
+ end
+ else
+ report_lua("fatal error %a in file %a",2,luafile)
+ end
+ return false,0
+end
+function luautilities.loadedluacode(fullname,forcestrip,name,macros)
+ name=name or fullname
+ if macros then
+ macros=lua.macros
+ end
+ local code,message
+ if macros then
+ code,message=macros.loaded(fullname,true,false)
+ else
+ code,message=loadfile(fullname)
+ end
+ if code then
+ code()
+ else
+ report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
+ code,message=loadfile(fullname)
+ end
+ if forcestrip and luautilities.stripcode then
+ if type(forcestrip)=="function" then
+ forcestrip=forcestrip(fullname)
+ end
+ if forcestrip or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
+ elseif luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
+end
+function luautilities.strippedloadstring(code,name,forcestrip)
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
+end
+function luautilities.loadstring(code,name)
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ return code,0
+end
+function luautilities.compile(luafile,lucfile,cleanup,strip,fallback)
+ report_lua("compiling %a into %a",luafile,lucfile)
+ os.remove(lucfile)
+ local done=stupidcompile(luafile,lucfile,strip~=false)
+ if done then
+ report_lua("dumping %a into %a stripped",luafile,lucfile)
+ if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+ report_lua("removing %a",luafile)
+ os.remove(luafile)
+ end
+ end
+ return done
+end
+function luautilities.loadstripped(...)
+ local l=load(...)
+ if l then
+ return load(dump(l,true))
+ end
+end
+local finalizers={}
+setmetatable(finalizers,{
+ __gc=function(t)
+ for i=1,#t do
+ pcall(t[i])
+ end
+ end
+} )
+function luautilities.registerfinalizer(f)
+ finalizers[#finalizers+1]=f
+end
+function luautilities.checkmemory(previous,threshold,trace)
+ local current=collectgarbage("count")
+ if previous then
+ local checked=(threshold or 64)*1024
+ local delta=current-previous
+ if current-previous>checked then
+ collectgarbage("collect")
+ local afterwards=collectgarbage("count")
+ if trace or tracememory then
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
+ previous/1024,current/1024,delta/1024,threshold,afterwards)
+ end
+ return afterwards
+ elseif trace or tracememory then
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
+ previous/1024,current/1024,delta/1024,threshold)
+ end
+ end
+ return current
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-deb']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local type,next,tostring,tonumber=type,next,tostring,tonumber
+local format,find,sub,gsub=string.format,string.find,string.sub,string.gsub
+local insert,remove,sort=table.insert,table.remove,table.sort
+local setmetatableindex=table.setmetatableindex
+utilities=utilities or {}
+local debugger=utilities.debugger or {}
+utilities.debugger=debugger
+local report=logs.reporter("debugger")
+local ticks=os.gettimeofday or os.clock
+local seconds=function(n) return n or 0 end
+local overhead=0
+local dummycalls=10*1000
+local nesting=0
+local names={}
+local initialize=false
+if lua.getpreciseticks then
+ initialize=function()
+ ticks=lua.getpreciseticks
+ seconds=lua.getpreciseseconds
+ initialize=false
+ end
+elseif not (FFISUPPORTED and ffi) then
+elseif os.type=="windows" then
+ initialize=function()
+ local kernel=ffilib("kernel32","system")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ ffi.cdef[[
+ int QueryPerformanceFrequency(int64_t *lpFrequency);
+ int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+ ]]
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ end
+ initialize=false
+ end
+elseif os.type=="unix" then
+ initialize=function()
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ ffi.cdef [[
+ /* what a mess */
+ typedef int clk_id_t;
+ typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
+ typedef struct timespec { long sec; long nsec; } ctx_timespec;
+ int clock_gettime(clk_id_t timerid, struct timespec *t);
+ ]]
+ local target=ffi.new("ctx_timespec[?]",1)
+ local clock=C.CLOCK_PROCESS_CPUTIME_ID
+ ticks=function ()
+ C.clock_gettime(clock,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
+ end
+ seconds=function(ticks)
+ return ticks/1000000000
+ end
+ initialize=false
+ end
+end
+setmetatableindex(names,function(t,name)
+ local v=setmetatableindex(function(t,source)
+ local v=setmetatableindex(function(t,line)
+ local v={ total=0,count=0,nesting=0 }
+ t[line]=v
+ return v
+ end)
+ t[source]=v
+ return v
+ end)
+ t[name]=v
+ return v
+end)
+local getinfo=nil
+local sethook=nil
+local function hook(where)
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
+ end
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ local nesting=data.nesting
+ if nesting==0 then
+ data.count=data.count+1
+ insert(data,ticks())
+ data.nesting=1
+ else
+ data.nesting=nesting+1
+ end
+ elseif where=="return" then
+ local nesting=data.nesting
+ if nesting==1 then
+ local t=remove(data)
+ if t then
+ data.total=data.total+ticks()-t
+ end
+ data.nesting=0
+ else
+ data.nesting=nesting-1
+ end
+ end
+ end
+end
+function debugger.showstats(printer,threshold)
+ local printer=printer or report
+ local calls=0
+ local functions=0
+ local dataset={}
+ local length=0
+ local realtime=0
+ local totaltime=0
+ local threshold=threshold or 0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ local count=data.count
+ if count>threshold then
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ realtime=realtime+real
+ end
+ totaltime=totaltime+total
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
+ end
+ end
+ end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
+ else
+ return a[5]<b[5]
+ end
+ else
+ return a[4]<b[4]
+ end
+ else
+ return b[3]<a[3]
+ end
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
+ end
+ local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
+ for i=1,#dataset do
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ calls=calls+count
+ functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
+ end
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
+end
+local function getdebug()
+ if sethook and getinfo then
+ return
+ end
+ if not debug then
+ local okay
+ okay,debug=pcall(require,"debug")
+ end
+ if type(debug)~="table" then
+ return
+ end
+ getinfo=debug.getinfo
+ sethook=debug.sethook
+ if type(getinfo)~="function" then
+ getinfo=nil
+ end
+ if type(sethook)~="function" then
+ sethook=nil
+ end
+end
+function debugger.savestats(filename,threshold)
+ local f=io.open(filename,'w')
+ if f then
+ debugger.showstats(function(str) f:write(str,"\n") end,threshold)
+ f:close()
+ end
+end
+function debugger.enable()
+ getdebug()
+ if sethook and getinfo and nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
+end
+function debugger.disable()
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if sethook and getinfo and nesting==0 then
+ sethook()
+ end
+end
+local function showtraceback(rep)
+ getdebug()
+ if getinfo then
+ local level=2
+ local reporter=rep or report
+ while true do
+ local info=getinfo(level,"Sl")
+ if not info then
+ break
+ elseif info.what=="C" then
+ reporter("%2i : %s",level-1,"C function")
+ else
+ reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
+ end
+ level=level+1
+ end
+ end
+end
+debugger.showtraceback=showtraceback
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-tpl']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+utilities.templates=utilities.templates or {}
+local templates=utilities.templates
+local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
+local report_template=logs.reporter("template")
+local tostring,next=tostring,next
+local format,sub,byte=string.format,string.sub,string.byte
+local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
+local replacer
+local function replacekey(k,t,how,recursive)
+ local v=t[k]
+ if not v then
+ if trace_template then
+ report_template("unknown key %a",k)
+ end
+ return ""
+ else
+ v=tostring(v)
+ if trace_template then
+ report_template("setting key %a to value %a",k,v)
+ end
+ if recursive then
+ return lpegmatch(replacer,v,1,t,how,recursive)
+ else
+ return v
+ end
+ end
+end
+local sqlescape=lpeg.replacer {
+ { "'","''" },
+ { "\\","\\\\" },
+ { "\r\n","\\n" },
+ { "\r","\\n" },
+}
+local sqlquoted=Cs(Cc("'")*sqlescape*Cc("'"))
+lpegpatterns.sqlescape=sqlescape
+lpegpatterns.sqlquoted=sqlquoted
+local luaescape=lpegpatterns.luaescape
+local escapers={
+ lua=function(s)
+ return lpegmatch(luaescape,s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlescape,s)
+ end,
+}
+local quotedescapers={
+ lua=function(s)
+ return format("%q",s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlquoted,s)
+ end,
+}
+local luaescaper=escapers.lua
+local quotedluaescaper=quotedescapers.lua
+local function replacekeyunquoted(s,t,how,recurse)
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and escapers[how] or luaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
+end
+local function replacekeyquoted(s,t,how,recurse)
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and quotedescapers[how] or quotedluaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
+end
+local function replaceoptional(l,m,r,t,how,recurse)
+ local v=t[l]
+ return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
+end
+local single=P("%")
+local double=P("%%")
+local lquoted=P("%[")
+local rquoted=P("]%")
+local lquotedq=P("%(")
+local rquotedq=P(")%")
+local escape=double/'%%'
+local nosingle=single/''
+local nodouble=double/''
+local nolquoted=lquoted/''
+local norquoted=rquoted/''
+local nolquotedq=lquotedq/''
+local norquotedq=rquotedq/''
+local noloptional=P("%?")/''
+local noroptional=P("?%")/''
+local nomoptional=P(":")/''
+local args=Carg(1)*Carg(2)*Carg(3)
+local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
+local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
+local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
+local optional=noloptional*((C((1-nomoptional)^1)*nomoptional*C((1-noroptional)^1)*args)/replaceoptional)*noroptional
+local any=P(1)
+ replacer=Cs((unquoted+quoted+escape+optional+key+any)^0)
+local function replace(str,mapping,how,recurse)
+ if mapping and str then
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ else
+ return str
+ end
+end
+templates.replace=replace
+function templates.replacer(str,how,recurse)
+ return function(mapping)
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ end
+end
+function templates.load(filename,mapping,how,recurse)
+ local data=io.loaddata(filename) or ""
+ if mapping and next(mapping) then
+ return replace(data,mapping,how,recurse)
+ else
+ return data
+ end
+end
+function templates.resolve(t,mapping,how,recurse)
+ if not mapping then
+ mapping=t
+ end
+ for k,v in next,t do
+ t[k]=replace(v,mapping,how,recurse)
+ end
+ return t
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-sta']={
+ version=1.001,
+ comment="companion to util-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local insert,remove,fastcopy,concat=table.insert,table.remove,table.fastcopy,table.concat
+local format=string.format
+local select,tostring=select,tostring
+local trace_stacker=false trackers.register("stacker.resolve",function(v) trace_stacker=v end)
+local stacker=stacker or {}
+utilities.stacker=stacker
+local function start(s,t,first,last)
+ if s.mode=="switch" then
+ local n=tostring(t[last])
+ if trace_stacker then
+ s.report("start: %s",n)
+ end
+ return n
+ else
+ local r={}
+ for i=first,last do
+ r[#r+1]=tostring(t[i])
+ end
+ local n=concat(r," ")
+ if trace_stacker then
+ s.report("start: %s",n)
+ end
+ return n
+ end
+end
+local function stop(s,t,first,last)
+ if s.mode=="switch" then
+ local n=tostring(false)
+ if trace_stacker then
+ s.report("stop: %s",n)
+ end
+ return n
+ else
+ local r={}
+ for i=last,first,-1 do
+ r[#r+1]=tostring(false)
+ end
+ local n=concat(r," ")
+ if trace_stacker then
+ s.report("stop: %s",n)
+ end
+ return n
+ end
+end
+local function change(s,t1,first1,last1,t2,first2,last2)
+ if s.mode=="switch" then
+ local n=tostring(t2[last2])
+ if trace_stacker then
+ s.report("change: %s",n)
+ end
+ return n
+ else
+ local r={}
+ for i=last1,first1,-1 do
+ r[#r+1]=tostring(false)
+ end
+ local n=concat(r," ")
+ for i=first2,last2 do
+ r[#r+1]=tostring(t2[i])
+ end
+ if trace_stacker then
+ s.report("change: %s",n)
+ end
+ return n
+ end
+end
+function stacker.new(name)
+ local report=logs.reporter("stacker",name or nil)
+ local s
+ local stack={}
+ local list={}
+ local ids={}
+ local hash={}
+ local hashing=true
+ local function push(...)
+ for i=1,select("#",...) do
+ insert(stack,(select(i,...)))
+ end
+ if hashing then
+ local c=concat(stack,"|")
+ local n=hash[c]
+ if not n then
+ n=#list+1
+ hash[c]=n
+ list[n]=fastcopy(stack)
+ end
+ insert(ids,n)
+ return n
+ else
+ local n=#list+1
+ list[n]=fastcopy(stack)
+ insert(ids,n)
+ return n
+ end
+ end
+ local function pop()
+ remove(stack)
+ remove(ids)
+ return ids[#ids] or s.unset or -1
+ end
+ local function clean()
+ if #stack==0 then
+ if trace_stacker then
+ s.report("%s list entries, %s stack entries",#list,#stack)
+ end
+ end
+ end
+ local tops={}
+ local top=nil
+ local switch=nil
+ local function resolve_reset(mode)
+ if #tops>0 then
+ report("resetting %s left-over states of %a",#tops,name)
+ end
+ tops={}
+ top=nil
+ switch=nil
+ end
+ local function resolve_begin(mode)
+ if mode then
+ switch=mode=="switch"
+ else
+ switch=s.mode=="switch"
+ end
+ top={ switch=switch }
+ insert(tops,top)
+ end
+ local function resolve_step(ti)
+ local result=nil
+ local noftop=top and #top or 0
+ if ti>0 then
+ local current=list[ti]
+ if current then
+ local noflist=#current
+ local nofsame=0
+ if noflist>noftop then
+ for i=1,noflist do
+ if current[i]==top[i] then
+ nofsame=i
+ else
+ break
+ end
+ end
+ else
+ for i=1,noflist do
+ if current[i]==top[i] then
+ nofsame=i
+ else
+ break
+ end
+ end
+ end
+ local plus=nofsame+1
+ if plus<=noftop then
+ if plus<=noflist then
+ if switch then
+ result=s.change(s,top,plus,noftop,current,nofsame,noflist)
+ else
+ result=s.change(s,top,plus,noftop,current,plus,noflist)
+ end
+ else
+ if switch then
+ result=s.change(s,top,plus,noftop,current,nofsame,noflist)
+ else
+ result=s.stop(s,top,plus,noftop)
+ end
+ end
+ elseif plus<=noflist then
+ if switch then
+ result=s.start(s,current,nofsame,noflist)
+ else
+ result=s.start(s,current,plus,noflist)
+ end
+ end
+ top=current
+ else
+ if 1<=noftop then
+ result=s.stop(s,top,1,noftop)
+ end
+ top={}
+ end
+ return result
+ else
+ if 1<=noftop then
+ result=s.stop(s,top,1,noftop)
+ end
+ top={}
+ return result
+ end
+ end
+ local function resolve_end()
+ if #tops>0 then
+ local result=s.stop(s,top,1,#top)
+ remove(tops)
+ top=tops[#tops]
+ switch=top and top.switch
+ return result
+ end
+ end
+ local function resolve(t)
+ resolve_begin()
+ for i=1,#t do
+ resolve_step(t[i])
+ end
+ resolve_end()
+ end
+ s={
+ name=name or "unknown",
+ unset=-1,
+ report=report,
+ start=start,
+ stop=stop,
+ change=change,
+ push=push,
+ pop=pop,
+ clean=clean,
+ resolve=resolve,
+ resolve_begin=resolve_begin,
+ resolve_step=resolve_step,
+ resolve_end=resolve_end,
+ resolve_reset=resolve_reset,
+ }
+ return s
+end
+
+end -- closure
diff --git a/macros/luatex/generic/lualibs/lualibs-file.lua b/macros/luatex/generic/lualibs/lualibs-file.lua
new file mode 100644
index 0000000000..1b039a4386
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-file.lua
@@ -0,0 +1,738 @@
+if not modules then modules = { } end modules ['l-file'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- needs a cleanup
+
+file = file or { }
+local file = file
+
+if not lfs then
+ lfs = optionalrequire("lfs")
+end
+
+-- -- see later
+--
+-- if not lfs then
+--
+-- lfs = {
+-- getcurrentdir = function()
+-- return "."
+-- end,
+-- attributes = function()
+-- return nil
+-- end,
+-- isfile = function(name)
+-- local f = io.open(name,'rb')
+-- if f then
+-- f:close()
+-- return true
+-- end
+-- end,
+-- isdir = function(name)
+-- print("you need to load lfs")
+-- return false
+-- end
+-- }
+--
+-- elseif not lfs.isfile then
+--
+-- local attributes = lfs.attributes
+--
+-- function lfs.isdir(name)
+-- return attributes(name,"mode") == "directory"
+-- end
+--
+-- function lfs.isfile(name)
+-- return attributes(name,"mode") == "file"
+-- end
+--
+-- -- function lfs.isdir(name)
+-- -- local a = attributes(name)
+-- -- return a and a.mode == "directory"
+-- -- end
+--
+-- -- function lfs.isfile(name)
+-- -- local a = attributes(name)
+-- -- return a and a.mode == "file"
+-- -- end
+--
+-- end
+
+local insert, concat = table.insert, table.concat
+local match, find, gmatch = string.match, string.find, string.gmatch
+local lpegmatch = lpeg.match
+local getcurrentdir, attributes = lfs.currentdir, lfs.attributes
+local checkedsplit = string.checkedsplit
+
+local P, R, S, C, Cs, Cp, Cc, Ct = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cp, lpeg.Cc, lpeg.Ct
+
+-- better this way:
+
+local attributes = lfs.attributes
+
+function lfs.isdir(name)
+ return attributes(name,"mode") == "directory"
+end
+
+function lfs.isfile(name)
+ local a = attributes(name,"mode")
+ return a == "file" or a == "link" or nil
+end
+
+function lfs.isfound(name)
+ local a = attributes(name,"mode")
+ return (a == "file" or a == "link") and name or nil
+end
+
+if sandbox then
+ sandbox.redefine(lfs.isfile,"lfs.isfile")
+ sandbox.redefine(lfs.isdir, "lfs.isdir")
+ sandbox.redefine(lfs.isfound, "lfs.isfound")
+end
+
+local colon = P(":")
+local period = P(".")
+local periods = P("..")
+local fwslash = P("/")
+local bwslash = P("\\")
+local slashes = S("\\/")
+local noperiod = 1-period
+local noslashes = 1-slashes
+local name = noperiod^1
+local suffix = period/"" * (1-period-slashes)^1 * -1
+
+----- pattern = C((noslashes^0 * slashes^1)^1)
+local pattern = C((1 - (slashes^1 * noslashes^1 * -1))^1) * P(1) -- there must be a more efficient way
+
+local function pathpart(name,default)
+ return name and lpegmatch(pattern,name) or default or ""
+end
+
+local pattern = (noslashes^0 * slashes)^1 * C(noslashes^1) * -1
+
+local function basename(name)
+ return name and lpegmatch(pattern,name) or name
+end
+
+-- print(pathpart("file"))
+-- print(pathpart("dir/file"))
+-- print(pathpart("/dir/file"))
+-- print(basename("file"))
+-- print(basename("dir/file"))
+-- print(basename("/dir/file"))
+
+local pattern = (noslashes^0 * slashes^1)^0 * Cs((1-suffix)^1) * suffix^0
+
+local function nameonly(name)
+ return name and lpegmatch(pattern,name) or name
+end
+
+local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * C(noperiod^1) * -1
+
+local function suffixonly(name)
+ return name and lpegmatch(pattern,name) or ""
+end
+
+local pattern = (noslashes^0 * slashes)^0 * noperiod^1 * ((period * C(noperiod^1))^1) * -1 + Cc("")
+
+local function suffixesonly(name)
+ if name then
+ return lpegmatch(pattern,name)
+ else
+ return ""
+ end
+end
+
+file.pathpart = pathpart
+file.basename = basename
+file.nameonly = nameonly
+file.suffixonly = suffixonly
+file.suffix = suffixonly
+file.suffixesonly = suffixesonly
+file.suffixes = suffixesonly
+
+file.dirname = pathpart -- obsolete
+file.extname = suffixonly -- obsolete
+
+-- actually these are schemes
+
+local drive = C(R("az","AZ")) * colon
+local path = C((noslashes^0 * slashes)^0)
+local suffix = period * C(P(1-period)^0 * P(-1))
+local base = C((1-suffix)^0)
+local rest = C(P(1)^0)
+
+drive = drive + Cc("")
+path = path + Cc("")
+base = base + Cc("")
+suffix = suffix + Cc("")
+
+local pattern_a = drive * path * base * suffix
+local pattern_b = path * base * suffix
+local pattern_c = C(drive * path) * C(base * suffix) -- trick: two extra captures
+local pattern_d = path * rest
+
+function file.splitname(str,splitdrive)
+ if not str then
+ -- error
+ elseif splitdrive then
+ return lpegmatch(pattern_a,str) -- returns drive, path, base, suffix
+ else
+ return lpegmatch(pattern_b,str) -- returns path, base, suffix
+ end
+end
+
+function file.splitbase(str)
+ if str then
+ return lpegmatch(pattern_d,str) -- returns path, base+suffix (path has / appended, might change at some point)
+ else
+ return "", str -- assume no path
+ end
+end
+
+---- stripslash = C((1 - P("/")^1*P(-1))^0)
+
+function file.nametotable(str,splitdrive)
+ if str then
+ local path, drive, subpath, name, base, suffix = lpegmatch(pattern_c,str)
+ -- if path ~= "" then
+ -- path = lpegmatch(stripslash,path) -- unfortunate hack, maybe this becomes default
+ -- end
+ if splitdrive then
+ return {
+ path = path,
+ drive = drive,
+ subpath = subpath,
+ name = name,
+ base = base,
+ suffix = suffix,
+ }
+ else
+ return {
+ path = path,
+ name = name,
+ base = base,
+ suffix = suffix,
+ }
+ end
+ end
+end
+
+-- print(file.splitname("file"))
+-- print(file.splitname("dir/file"))
+-- print(file.splitname("/dir/file"))
+-- print(file.splitname("file"))
+-- print(file.splitname("dir/file"))
+-- print(file.splitname("/dir/file"))
+
+-- inspect(file.nametotable("file.ext"))
+-- inspect(file.nametotable("dir/file.ext"))
+-- inspect(file.nametotable("/dir/file.ext"))
+-- inspect(file.nametotable("file.ext"))
+-- inspect(file.nametotable("dir/file.ext"))
+-- inspect(file.nametotable("/dir/file.ext"))
+
+----- pattern = Cs(((period * noperiod^1 * -1) / "" + 1)^1)
+local pattern = Cs(((period * (1-period-slashes)^1 * -1) / "" + 1)^1)
+
+function file.removesuffix(name)
+ return name and lpegmatch(pattern,name)
+end
+
+-- local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * Cp() * noperiod^1 * -1
+--
+-- function file.addsuffix(name, suffix)
+-- local p = lpegmatch(pattern,name)
+-- if p then
+-- return name
+-- else
+-- return name .. "." .. suffix
+-- end
+-- end
+
+local suffix = period/"" * (1-period-slashes)^1 * -1
+local pattern = Cs((noslashes^0 * slashes^1)^0 * ((1-suffix)^1)) * Cs(suffix)
+
+function file.addsuffix(filename,suffix,criterium)
+ if not filename or not suffix or suffix == "" then
+ return filename
+ elseif criterium == true then
+ return filename .. "." .. suffix
+ elseif not criterium then
+ local n, s = lpegmatch(pattern,filename)
+ if not s or s == "" then
+ return filename .. "." .. suffix
+ else
+ return filename
+ end
+ else
+ local n, s = lpegmatch(pattern,filename)
+ if s and s ~= "" then
+ local t = type(criterium)
+ if t == "table" then
+ -- keep if in criterium
+ for i=1,#criterium do
+ if s == criterium[i] then
+ return filename
+ end
+ end
+ elseif t == "string" then
+ -- keep if criterium
+ if s == criterium then
+ return filename
+ end
+ end
+ end
+ return (n or filename) .. "." .. suffix
+ end
+end
+
+-- print("1 " .. file.addsuffix("name","new") .. " -> name.new")
+-- print("2 " .. file.addsuffix("name.old","new") .. " -> name.old")
+-- print("3 " .. file.addsuffix("name.old","new",true) .. " -> name.old.new")
+-- print("4 " .. file.addsuffix("name.old","new","new") .. " -> name.new")
+-- print("5 " .. file.addsuffix("name.old","new","old") .. " -> name.old")
+-- print("6 " .. file.addsuffix("name.old","new","foo") .. " -> name.new")
+-- print("7 " .. file.addsuffix("name.old","new",{"foo","bar"}) .. " -> name.new")
+-- print("8 " .. file.addsuffix("name.old","new",{"old","bar"}) .. " -> name.old")
+
+local suffix = period * (1-period-slashes)^1 * -1
+local pattern = Cs((1-suffix)^0)
+
+function file.replacesuffix(name,suffix)
+ if name and suffix and suffix ~= "" then
+ return lpegmatch(pattern,name) .. "." .. suffix
+ else
+ return name
+ end
+end
+
+--
+
+local reslasher = lpeg.replacer(P("\\"),"/")
+
+function file.reslash(str)
+ return str and lpegmatch(reslasher,str)
+end
+
+-- We should be able to use:
+--
+-- local writable = P(1) * P("w") * Cc(true)
+--
+-- function file.is_writable(name)
+-- local a = attributes(name) or attributes(pathpart(name,"."))
+-- return a and lpegmatch(writable,a.permissions) or false
+-- end
+--
+-- But after some testing Taco and I came up with the more robust
+-- variant:
+
+if lfs.isreadablefile and lfs.iswritablefile then
+
+ file.is_readable = lfs.isreadablefile
+ file.is_writable = lfs.iswritablefile
+
+else
+
+ function file.is_writable(name)
+ if not name then
+ -- error
+ elseif lfs.isdir(name) then
+ name = name .. "/m_t_x_t_e_s_t.tmp"
+ local f = io.open(name,"wb")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ elseif lfs.isfile(name) then
+ local f = io.open(name,"ab")
+ if f then
+ f:close()
+ return true
+ end
+ else
+ local f = io.open(name,"ab")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ end
+ return false
+ end
+
+ local readable = P("r") * Cc(true)
+
+ function file.is_readable(name)
+ if name then
+ local a = attributes(name)
+ return a and lpegmatch(readable,a.permissions) or false
+ else
+ return false
+ end
+ end
+
+end
+
+file.isreadable = file.is_readable -- depricated
+file.iswritable = file.is_writable -- depricated
+
+function file.size(name)
+ if name then
+ local a = attributes(name)
+ return a and a.size or 0
+ else
+ return 0
+ end
+end
+
+function file.splitpath(str,separator) -- string .. reslash is a bonus (we could do a direct split)
+ return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
+end
+
+function file.joinpath(tab,separator) -- table
+ return tab and concat(tab,separator or io.pathseparator) -- can have trailing //
+end
+
+local someslash = S("\\/")
+local stripper = Cs(P(fwslash)^0/"" * reslasher)
+local isnetwork = someslash * someslash * (1-someslash)
+ + (1-fwslash-colon)^1 * colon
+local isroot = fwslash^1 * -1
+local hasroot = fwslash^1
+
+local reslasher = lpeg.replacer(S("\\/"),"/")
+local deslasher = lpeg.replacer(S("\\/")^1,"/")
+
+-- If we have a network or prefix then there is a change that we end up with two
+-- // in the middle ... we could prevent this if we (1) expand prefixes: and (2)
+-- split and rebuild as url. Of course we could assume no network paths (which
+-- makes sense) adn assume either mapped drives (windows) or mounts (unix) but
+-- then we still have to deal with urls ... anyhow, multiple // are never a real
+-- problem but just ugly.
+
+-- function file.join(...)
+-- local lst = { ... }
+-- local one = lst[1]
+-- if lpegmatch(isnetwork,one) then
+-- local one = lpegmatch(reslasher,one)
+-- local two = lpegmatch(deslasher,concat(lst,"/",2))
+-- if lpegmatch(hasroot,two) then
+-- return one .. two
+-- else
+-- return one .. "/" .. two
+-- end
+-- elseif lpegmatch(isroot,one) then
+-- local two = lpegmatch(deslasher,concat(lst,"/",2))
+-- if lpegmatch(hasroot,two) then
+-- return two
+-- else
+-- return "/" .. two
+-- end
+-- elseif one == "" then
+-- return lpegmatch(stripper,concat(lst,"/",2))
+-- else
+-- return lpegmatch(deslasher,concat(lst,"/"))
+-- end
+-- end
+
+function file.join(one, two, three, ...)
+ if not two then
+ return one == "" and one or lpegmatch(reslasher,one)
+ end
+ if one == "" then
+ return lpegmatch(stripper,three and concat({ two, three, ... },"/") or two)
+ end
+ if lpegmatch(isnetwork,one) then
+ local one = lpegmatch(reslasher,one)
+ local two = lpegmatch(deslasher,three and concat({ two, three, ... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return one .. two
+ else
+ return one .. "/" .. two
+ end
+ elseif lpegmatch(isroot,one) then
+ local two = lpegmatch(deslasher,three and concat({ two, three, ... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return two
+ else
+ return "/" .. two
+ end
+ else
+ return lpegmatch(deslasher,concat({ one, two, three, ... },"/"))
+ end
+end
+
+-- or we can use this:
+--
+-- function file.join(...)
+-- local n = select("#",...)
+-- local one = select(1,...)
+-- if n == 1 then
+-- return one == "" and one or lpegmatch(stripper,one)
+-- end
+-- if one == "" then
+-- return lpegmatch(stripper,n > 2 and concat({ ... },"/",2) or select(2,...))
+-- end
+-- if lpegmatch(isnetwork,one) then
+-- local one = lpegmatch(reslasher,one)
+-- local two = lpegmatch(deslasher,n > 2 and concat({ ... },"/",2) or select(2,...))
+-- if lpegmatch(hasroot,two) then
+-- return one .. two
+-- else
+-- return one .. "/" .. two
+-- end
+-- elseif lpegmatch(isroot,one) then
+-- local two = lpegmatch(deslasher,n > 2 and concat({ ... },"/",2) or select(2,...))
+-- if lpegmatch(hasroot,two) then
+-- return two
+-- else
+-- return "/" .. two
+-- end
+-- else
+-- return lpegmatch(deslasher,concat({ ... },"/"))
+-- end
+-- end
+
+-- print(file.join("c:/whatever"))
+-- print(file.join("c:/whatever","name"))
+-- print(file.join("//","/y"))
+-- print(file.join("/","/y"))
+-- print(file.join("","/y"))
+-- print(file.join("/x/","/y"))
+-- print(file.join("x/","/y"))
+-- print(file.join("http://","/y"))
+-- print(file.join("http://a","/y"))
+-- print(file.join("http:///a","/y"))
+-- print(file.join("//nas-1","/y"))
+-- print(file.join("//nas-1/a/b/c","/y"))
+-- print(file.join("\\\\nas-1\\a\\b\\c","\\y"))
+
+-- The previous one fails on "a.b/c" so Taco came up with a split based
+-- variant. After some skyping we got it sort of compatible with the old
+-- one. After that the anchoring to currentdir was added in a better way.
+-- Of course there are some optimizations too. Finally we had to deal with
+-- windows drive prefixes and things like sys://. Eventually gsubs and
+-- finds were replaced by lpegs.
+
+local drivespec = R("az","AZ")^1 * colon
+local anchors = fwslash
+ + drivespec
+local untouched = periods
+ + (1-period)^1 * P(-1)
+local mswindrive = Cs(drivespec * (bwslash/"/" + fwslash)^0)
+local mswinuncpath = (bwslash + fwslash) * (bwslash + fwslash) * Cc("//")
+local splitstarter = (mswindrive + mswinuncpath + Cc(false))
+ * Ct(lpeg.splitat(S("/\\")^1))
+local absolute = fwslash
+
+function file.collapsepath(str,anchor) -- anchor: false|nil, true, "."
+ if not str then
+ return
+ end
+ if anchor == true and not lpegmatch(anchors,str) then
+ str = getcurrentdir() .. "/" .. str
+ end
+ if str == "" or str =="." then
+ return "."
+ elseif lpegmatch(untouched,str) then
+ return lpegmatch(reslasher,str)
+ end
+ local starter, oldelements = lpegmatch(splitstarter,str)
+ local newelements = { }
+ local i = #oldelements
+ while i > 0 do
+ local element = oldelements[i]
+ if element == '.' then
+ -- do nothing
+ elseif element == '..' then
+ local n = i - 1
+ while n > 0 do
+ local element = oldelements[n]
+ if element ~= '..' and element ~= '.' then
+ oldelements[n] = '.'
+ break
+ else
+ n = n - 1
+ end
+ end
+ if n < 1 then
+ insert(newelements,1,'..')
+ end
+ elseif element ~= "" then
+ insert(newelements,1,element)
+ end
+ i = i - 1
+ end
+ if #newelements == 0 then
+ return starter or "."
+ elseif starter then
+ return starter .. concat(newelements, '/')
+ elseif lpegmatch(absolute,str) then
+ return "/" .. concat(newelements,'/')
+ else
+ newelements = concat(newelements, '/')
+ if anchor == "." and find(str,"^%./") then
+ return "./" .. newelements
+ else
+ return newelements
+ end
+ end
+end
+
+-- local function test(str,...)
+-- print(string.format("%-20s %-15s %-30s %-20s",str,file.collapsepath(str),file.collapsepath(str,true),file.collapsepath(str,".")))
+-- end
+-- test("a/b.c/d") test("b.c/d") test("b.c/..")
+-- test("/") test("c:/..") test("sys://..")
+-- test("") test("./") test(".") test("..") test("./..") test("../..")
+-- test("a") test("./a") test("/a") test("a/../..")
+-- test("a/./b/..") test("a/aa/../b/bb") test("a/.././././b/..") test("a/./././b/..")
+-- test("a/b/c/../..") test("./a/b/c/../..") test("a/b/c/../..")
+-- test("./a")
+-- test([[\\a.b.c\d\e]])
+
+local validchars = R("az","09","AZ","--","..")
+local pattern_a = lpeg.replacer(1-validchars)
+local pattern_a = Cs((validchars + P(1)/"-")^1)
+local whatever = P("-")^0 / ""
+local pattern_b = Cs(whatever * (1 - whatever * -1)^1)
+
+function file.robustname(str,strict)
+ if str then
+ str = lpegmatch(pattern_a,str) or str
+ if strict then
+ return lpegmatch(pattern_b,str) or str -- two step is cleaner (less backtracking)
+ else
+ return str
+ end
+ end
+end
+
+local loaddata = io.loaddata
+local savedata = io.savedata
+
+file.readdata = loaddata
+file.savedata = savedata
+
+function file.copy(oldname,newname)
+ if oldname and newname then
+ local data = loaddata(oldname)
+ if data and data ~= "" then
+ savedata(newname,data)
+ end
+ end
+end
+
+-- also rewrite previous
+
+local letter = R("az","AZ") + S("_-+")
+local separator = P("://")
+
+local qualified = period^0 * fwslash
+ + letter * colon
+ + letter^1 * separator
+ + letter^1 * fwslash
+local rootbased = fwslash
+ + letter * colon
+
+lpeg.patterns.qualified = qualified
+lpeg.patterns.rootbased = rootbased
+
+-- ./name ../name /name c: :// name/name
+
+function file.is_qualified_path(filename)
+ return filename and lpegmatch(qualified,filename) ~= nil
+end
+
+function file.is_rootbased_path(filename)
+ return filename and lpegmatch(rootbased,filename) ~= nil
+end
+
+-- function test(t) for k, v in next, t do print(v, "=>", file.splitname(v)) end end
+--
+-- test { "c:", "c:/aa", "c:/aa/bb", "c:/aa/bb/cc", "c:/aa/bb/cc.dd", "c:/aa/bb/cc.dd.ee" }
+-- test { "c:", "c:aa", "c:aa/bb", "c:aa/bb/cc", "c:aa/bb/cc.dd", "c:aa/bb/cc.dd.ee" }
+-- test { "/aa", "/aa/bb", "/aa/bb/cc", "/aa/bb/cc.dd", "/aa/bb/cc.dd.ee" }
+-- test { "aa", "aa/bb", "aa/bb/cc", "aa/bb/cc.dd", "aa/bb/cc.dd.ee" }
+
+-- -- maybe:
+--
+-- if os.type == "windows" then
+-- local currentdir = getcurrentdir
+-- function getcurrentdir()
+-- return lpegmatch(reslasher,currentdir())
+-- end
+-- end
+
+-- for myself:
+
+function file.strip(name,dir)
+ if name then
+ local b, a = match(name,"^(.-)" .. dir .. "(.*)$")
+ return a ~= "" and a or name
+ end
+end
+
+-- local debuglist = {
+-- "pathpart", "basename", "nameonly", "suffixonly", "suffix", "dirname", "extname",
+-- "addsuffix", "removesuffix", "replacesuffix", "join",
+-- "strip","collapsepath", "joinpath", "splitpath",
+-- }
+
+-- for i=1,#debuglist do
+-- local name = debuglist[i]
+-- local f = file[name]
+-- file[name] = function(...)
+-- print(name,f(...))
+-- return f(...)
+-- end
+-- end
+
+-- a goodie: a dumb version of mkdirs (not used in context itself, only
+-- in generic usage)
+
+function lfs.mkdirs(path)
+ local full = ""
+ for sub in gmatch(path,"(/*[^\\/]+)") do -- accepts leading c: and /
+ full = full .. sub
+ -- lfs.isdir("/foo") mistakenly returns true on windows so
+ -- so we don't test and just make as that one is not too picky
+ lfs.mkdir(full)
+ end
+end
+
+-- here is oen i ran into when messign around with xavante code (keppler project)
+-- where it's called in_base .. no gain in using lpeg here
+
+function file.withinbase(path) -- don't go beyond root
+ local l = 0
+ if not find(path,"^/") then
+ path = "/" .. path
+ end
+ for dir in gmatch(path,"/([^/]+)") do
+ if dir == ".." then
+ l = l - 1
+ elseif dir ~= "." then
+ l = l + 1
+ end
+ if l < 0 then
+ return false
+ end
+ end
+ return true
+end
+
+-- not used in context but was in luatex once:
+
+local symlinkattributes = lfs.symlinkattributes
+
+function lfs.readlink(name)
+ return symlinkattributes(name,"target") or nil
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-function.lua b/macros/luatex/generic/lualibs/lualibs-function.lua
new file mode 100644
index 0000000000..7ded8ceecd
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-function.lua
@@ -0,0 +1,11 @@
+if not modules then modules = { } end modules ['l-functions'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+functions = functions or { }
+
+function functions.dummy() end
diff --git a/macros/luatex/generic/lualibs/lualibs-gzip.lua b/macros/luatex/generic/lualibs/lualibs-gzip.lua
new file mode 100644
index 0000000000..5100e47222
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-gzip.lua
@@ -0,0 +1,54 @@
+if not modules then modules = { } end modules ['l-gzip'] = {
+ version = 1.001,
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+if not gzip then
+
+ -- no fallback yet
+
+ return
+
+end
+
+local suffix, suffixes = file.suffix, file.suffixes
+
+function gzip.load(filename)
+ local f = io.open(filename,"rb")
+ if not f then
+ -- invalid file
+ elseif suffix(filename) == "gz" then
+ f:close()
+ local g = gzip.open(filename,"rb")
+ if g then
+ local str = g:read("*all")
+ g:close()
+ return str
+ end
+ else
+ local str = f:read("*all")
+ f:close()
+ return str
+ end
+end
+
+function gzip.save(filename,data)
+ if suffix(filename) ~= "gz" then
+ filename = filename .. ".gz"
+ end
+ local f = io.open(filename,"wb")
+ if f then
+ local s = zlib.compress(data or "",9,nil,15+16)
+ f:write(s)
+ f:close()
+ return #s
+ end
+end
+
+function gzip.suffix(filename)
+ local suffix, extra = suffixes(filename)
+ local gzipped = extra == "gz"
+ return suffix, gzipped
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-io.lua b/macros/luatex/generic/lualibs/lualibs-io.lua
new file mode 100644
index 0000000000..fa3ad3c4cd
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-io.lua
@@ -0,0 +1,473 @@
+if not modules then modules = { } end modules ['l-io'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local io = io
+local open, flush, write, read = io.open, io.flush, io.write, io.read
+local byte, find, gsub, format = string.byte, string.find, string.gsub, string.format
+local concat = table.concat
+----- floor = math.floor
+local type = type
+
+if string.find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator, io.pathseparator = "\\", ";"
+else
+ io.fileseparator, io.pathseparator = "/" , ":"
+end
+
+-- local function readall(f)
+-- return f:read("*all")
+-- end
+
+-- The next one is upto 50% faster on large files and less memory consumption due
+-- to less intermediate large allocations. This phenomena was discussed on the
+-- luatex dev list.
+
+local large = 0x01000000 -- 2^24 16.777.216
+local medium = 0x00100000 -- 2^20 1.048.576
+local small = 0x00020000 -- 2^17 131.072
+
+-- local function readall(f)
+-- local size = f:seek("end")
+-- if size == 0 then
+-- return ""
+-- end
+-- f:seek("set",0)
+-- if size < medium then
+-- return f:read('*all')
+-- else
+-- local step = (size > large) and large or (floor(size/(medium)) * small)
+-- local data = { }
+-- while true do
+-- local r = f:read(step)
+-- if not r then
+-- return concat(data)
+-- else
+-- data[#data+1] = r
+-- end
+-- end
+-- end
+-- end
+
+local function readall(f)
+ -- return f:read("*all")
+ local size = f:seek("end")
+ if size > 0 then
+ f:seek("set",0)
+ return f:read(size)
+ else
+ return ""
+ end
+end
+
+io.readall = readall
+
+function io.loaddata(filename,textmode) -- return nil if empty
+ local f = open(filename,(textmode and 'r') or 'rb')
+ if f then
+ local size = f:seek("end")
+ local data = nil
+ if size > 0 then
+ -- data = f:read("*all")
+ f:seek("set",0)
+ data = f:read(size)
+ end
+ f:close()
+ return data
+ end
+end
+
+-- function io.copydata(source,target,action)
+-- local f = open(source,"rb")
+-- if f then
+-- local g = open(target,"wb")
+-- if g then
+-- local size = f:seek("end")
+-- if size == 0 then
+-- -- empty
+-- else
+-- f:seek("set",0)
+-- if size < medium then
+-- local data = f:read('*all')
+-- if action then
+-- data = action(data)
+-- end
+-- if data then
+-- g:write(data)
+-- end
+-- else
+-- local step = (size > large) and large or (floor(size/(medium)) * small)
+-- while true do
+-- local data = f:read(step)
+-- if data then
+-- if action then
+-- data = action(data)
+-- end
+-- if data then
+-- g:write(data)
+-- end
+-- else
+-- break
+-- end
+-- end
+-- end
+-- end
+-- g:close()
+-- end
+-- f:close()
+-- flush()
+-- end
+-- end
+
+function io.copydata(source,target,action)
+ local f = open(source,"rb")
+ if f then
+ local g = open(target,"wb")
+ if g then
+ local size = f:seek("end")
+ if size > 0 then
+ -- local data = f:read('*all')
+ f:seek("set",0)
+ local data = f:read(size)
+ if action then
+ data = action(data)
+ end
+ if data then
+ g:write(data)
+ end
+ end
+ g:close()
+ end
+ f:close()
+ flush()
+ end
+end
+
+function io.savedata(filename,data,joiner)
+ local f = open(filename,"wb")
+ if f then
+ if type(data) == "table" then
+ f:write(concat(data,joiner or ""))
+ elseif type(data) == "function" then
+ data(f)
+ else
+ f:write(data or "")
+ end
+ f:close()
+ flush()
+ return true
+ else
+ return false
+ end
+end
+
+-- we can also chunk this one if needed: io.lines(filename,chunksize,"*l")
+
+-- ffi.readline
+
+if fio and fio.readline then
+
+ local readline = fio.readline
+
+ function io.loadlines(filename,n) -- return nil if empty
+ local f = open(filename,'r')
+ if not f then
+ -- no file
+ elseif n then
+ local lines = { }
+ for i=1,n do
+ local line = readline(f)
+ if line then
+ lines[i] = line
+ else
+ break
+ end
+ end
+ f:close()
+ lines = concat(lines,"\n")
+ if #lines > 0 then
+ return lines
+ end
+ else
+ local line = readline(f)
+ f:close()
+ if line and #line > 0 then
+ return line
+ end
+ end
+ end
+
+else
+
+ function io.loadlines(filename,n) -- return nil if empty
+ local f = open(filename,'r')
+ if not f then
+ -- no file
+ elseif n then
+ local lines = { }
+ for i=1,n do
+ local line = f:read("*lines")
+ if line then
+ lines[i] = line
+ else
+ break
+ end
+ end
+ f:close()
+ lines = concat(lines,"\n")
+ if #lines > 0 then
+ return lines
+ end
+ else
+ local line = f:read("*line") or ""
+ f:close()
+ if #line > 0 then
+ return line
+ end
+ end
+ end
+
+end
+
+function io.loadchunk(filename,n)
+ local f = open(filename,'rb')
+ if f then
+ local data = f:read(n or 1024)
+ f:close()
+ if #data > 0 then
+ return data
+ end
+ end
+end
+
+function io.exists(filename)
+ local f = open(filename)
+ if f == nil then
+ return false
+ else
+ f:close()
+ return true
+ end
+end
+
+function io.size(filename)
+ local f = open(filename)
+ if f == nil then
+ return 0
+ else
+ local s = f:seek("end")
+ f:close()
+ return s
+ end
+end
+
+local function noflines(f)
+ if type(f) == "string" then
+ local f = open(filename)
+ if f then
+ local n = f and noflines(f) or 0
+ f:close()
+ return n
+ else
+ return 0
+ end
+ else
+ -- todo: load and lpeg
+ local n = 0
+ for _ in f:lines() do
+ n = n + 1
+ end
+ f:seek('set',0)
+ return n
+ end
+end
+
+io.noflines = noflines
+
+-- inlined is faster ... beware, better use util-fil
+
+local nextchar = {
+ [ 4] = function(f)
+ return f:read(1,1,1,1)
+ end,
+ [ 2] = function(f)
+ return f:read(1,1)
+ end,
+ [ 1] = function(f)
+ return f:read(1)
+ end,
+ [-2] = function(f)
+ local a, b = f:read(1,1)
+ return b, a
+ end,
+ [-4] = function(f)
+ local a, b, c, d = f:read(1,1,1,1)
+ return d, c, b, a
+ end
+}
+
+function io.characters(f,n)
+ if f then
+ return nextchar[n or 1], f
+ end
+end
+
+local nextbyte = {
+ [4] = function(f)
+ local a, b, c, d = f:read(1,1,1,1)
+ if d then
+ return byte(a), byte(b), byte(c), byte(d)
+ end
+ end,
+ [3] = function(f)
+ local a, b, c = f:read(1,1,1)
+ if b then
+ return byte(a), byte(b), byte(c)
+ end
+ end,
+ [2] = function(f)
+ local a, b = f:read(1,1)
+ if b then
+ return byte(a), byte(b)
+ end
+ end,
+ [1] = function (f)
+ local a = f:read(1)
+ if a then
+ return byte(a)
+ end
+ end,
+ [-2] = function (f)
+ local a, b = f:read(1,1)
+ if b then
+ return byte(b), byte(a)
+ end
+ end,
+ [-3] = function(f)
+ local a, b, c = f:read(1,1,1)
+ if b then
+ return byte(c), byte(b), byte(a)
+ end
+ end,
+ [-4] = function(f)
+ local a, b, c, d = f:read(1,1,1,1)
+ if d then
+ return byte(d), byte(c), byte(b), byte(a)
+ end
+ end
+}
+
+function io.bytes(f,n)
+ if f then
+ return nextbyte[n or 1], f
+ else
+ return nil, nil
+ end
+end
+
+function io.ask(question,default,options)
+ while true do
+ write(question)
+ if options then
+ write(format(" [%s]",concat(options,"|")))
+ end
+ if default then
+ write(format(" [%s]",default))
+ end
+ write(format(" "))
+ flush()
+ local answer = read()
+ answer = gsub(answer,"^%s*(.*)%s*$","%1")
+ if answer == "" and default then
+ return default
+ elseif not options then
+ return answer
+ else
+ for k=1,#options do
+ if options[k] == answer then
+ return answer
+ end
+ end
+ local pattern = "^" .. answer
+ for k=1,#options do
+ local v = options[k]
+ if find(v,pattern) then
+ return v
+ end
+ end
+ end
+ end
+end
+
+local function readnumber(f,n,m) -- to be replaced
+ if m then
+ f:seek("set",n)
+ n = m
+ end
+ if n == 1 then
+ return byte(f:read(1))
+ elseif n == 2 then
+ local a, b = byte(f:read(2),1,2)
+ return 0x100 * a + b
+ elseif n == 3 then
+ local a, b, c = byte(f:read(3),1,3)
+ return 0x10000 * a + 0x100 * b + c
+ elseif n == 4 then
+ local a, b, c, d = byte(f:read(4),1,4)
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+ elseif n == 8 then
+ local a, b = readnumber(f,4), readnumber(f,4)
+ return 0x100 * a + b
+ elseif n == 12 then
+ local a, b, c = readnumber(f,4), readnumber(f,4), readnumber(f,4)
+ return 0x10000 * a + 0x100 * b + c
+ elseif n == -2 then
+ local b, a = byte(f:read(2),1,2)
+ return 0x100 * a + b
+ elseif n == -3 then
+ local c, b, a = byte(f:read(3),1,3)
+ return 0x10000 * a + 0x100 * b + c
+ elseif n == -4 then
+ local d, c, b, a = byte(f:read(4),1,4)
+ return 0x1000000 * a + 0x10000 * b + 0x100*c + d
+ elseif n == -8 then
+ local h, g, f, e, d, c, b, a = byte(f:read(8),1,8)
+ return 0x100000000000000 * a + 0x1000000000000 * b + 0x10000000000 * c + 0x100000000 * d +
+ 0x1000000 * e + 0x10000 * f + 0x100 * g + h
+ else
+ return 0
+ end
+end
+
+io.readnumber = readnumber
+
+function io.readstring(f,n,m)
+ if m then
+ f:seek("set",n)
+ n = m
+ end
+ local str = gsub(f:read(n),"\000","")
+ return str
+end
+
+-- This works quite ok:
+--
+-- function io.piped(command,writer)
+-- local pipe = io.popen(command)
+-- -- for line in pipe:lines() do
+-- -- print(line)
+-- -- end
+-- while true do
+-- local line = pipe:read(1)
+-- if not line then
+-- break
+-- elseif line ~= "\n" then
+-- writer(line)
+-- end
+-- end
+-- return pipe:close() -- ok, status, (error)code
+-- end
diff --git a/macros/luatex/generic/lualibs/lualibs-lpeg.lua b/macros/luatex/generic/lualibs/lualibs-lpeg.lua
new file mode 100644
index 0000000000..51bc1d3df3
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-lpeg.lua
@@ -0,0 +1,1196 @@
+if not modules then modules = { } end modules ['l-lpeg'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- we can get too many captures (e.g. on largexml files) which makes me wonder
+-- if P(foo)/"" can't be simplfied to N(foo) i.e. some direct instruction to the
+-- lpeg virtual machine to ignore it
+
+-- lpeg 12 vs lpeg 10: slower compilation, similar parsing speed (i need to check
+-- if i can use new features like capture / 2 and .B (at first sight the xml
+-- parser is some 5% slower)
+
+-- lpeg.P("abc") is faster than lpeg.P("a") * lpeg.P("b") * lpeg.P("c")
+
+-- a new lpeg fails on a #(1-P(":")) test and really needs a + P(-1)
+
+-- move utf -> l-unicode
+-- move string -> l-string or keep it here
+
+-- lpeg.B : backward without consumption
+-- lpeg.F = getmetatable(lpeg.P(1)).__len : forward without consumption
+
+
+lpeg = require("lpeg") -- does lpeg register itself global?
+
+local lpeg = lpeg
+
+-- The latest lpeg doesn't have print any more, and even the new ones are not
+-- available by default (only when debug mode is enabled), which is a pitty as
+-- as it helps nailing down bottlenecks. Performance seems comparable: some 10%
+-- slower pattern compilation, same parsing speed, although,
+--
+-- local p = lpeg.C(lpeg.P(1)^0 * lpeg.P(-1))
+-- local a = string.rep("123",100)
+-- lpeg.match(p,a)
+--
+-- seems slower and is also still suboptimal (i.e. a match that runs from begin
+-- to end, one of the cases where string matchers win).
+
+if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end
+
+-- tracing (only used when we encounter a problem in integration of lpeg in luatex)
+
+-- some code will move to unicode and string
+
+-- local lpmatch = lpeg.match
+-- local lpprint = lpeg.print
+-- local lpp = lpeg.P
+-- local lpr = lpeg.R
+-- local lps = lpeg.S
+-- local lpc = lpeg.C
+-- local lpb = lpeg.B
+-- local lpv = lpeg.V
+-- local lpcf = lpeg.Cf
+-- local lpcb = lpeg.Cb
+-- local lpcg = lpeg.Cg
+-- local lpct = lpeg.Ct
+-- local lpcs = lpeg.Cs
+-- local lpcc = lpeg.Cc
+-- local lpcmt = lpeg.Cmt
+-- local lpcarg = lpeg.Carg
+
+-- function lpeg.match(l,...) print("LPEG MATCH") lpprint(l) return lpmatch(l,...) end
+
+-- function lpeg.P (l) local p = lpp (l) print("LPEG P =") lpprint(l) return p end
+-- function lpeg.R (l) local p = lpr (l) print("LPEG R =") lpprint(l) return p end
+-- function lpeg.S (l) local p = lps (l) print("LPEG S =") lpprint(l) return p end
+-- function lpeg.C (l) local p = lpc (l) print("LPEG C =") lpprint(l) return p end
+-- function lpeg.B (l) local p = lpb (l) print("LPEG B =") lpprint(l) return p end
+-- function lpeg.V (l) local p = lpv (l) print("LPEG V =") lpprint(l) return p end
+-- function lpeg.Cf (l) local p = lpcf (l) print("LPEG Cf =") lpprint(l) return p end
+-- function lpeg.Cb (l) local p = lpcb (l) print("LPEG Cb =") lpprint(l) return p end
+-- function lpeg.Cg (l) local p = lpcg (l) print("LPEG Cg =") lpprint(l) return p end
+-- function lpeg.Ct (l) local p = lpct (l) print("LPEG Ct =") lpprint(l) return p end
+-- function lpeg.Cs (l) local p = lpcs (l) print("LPEG Cs =") lpprint(l) return p end
+-- function lpeg.Cc (l) local p = lpcc (l) print("LPEG Cc =") lpprint(l) return p end
+-- function lpeg.Cmt (l) local p = lpcmt (l) print("LPEG Cmt =") lpprint(l) return p end
+-- function lpeg.Carg (l) local p = lpcarg(l) print("LPEG Carg =") lpprint(l) return p end
+
+local type, next, tostring = type, next, tostring
+local byte, char, gmatch, format = string.byte, string.char, string.gmatch, string.format
+----- mod, div = math.mod, math.div
+local floor = math.floor
+
+local P, R, S, V, Ct, C, Cs, Cc, Cp, Cmt = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Cp, lpeg.Cmt
+local lpegtype, lpegmatch, lpegprint = lpeg.type, lpeg.match, lpeg.print
+
+-- let's start with an inspector:
+
+if setinspector then
+ setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
+end
+
+-- Beware, we predefine a bunch of patterns here and one reason for doing so
+-- is that we get consistent behaviour in some of the visualizers.
+
+lpeg.patterns = lpeg.patterns or { } -- so that we can share
+local patterns = lpeg.patterns
+
+local anything = P(1)
+local endofstring = P(-1)
+local alwaysmatched = P(true)
+
+patterns.anything = anything
+patterns.endofstring = endofstring
+patterns.beginofstring = alwaysmatched
+patterns.alwaysmatched = alwaysmatched
+
+local sign = S('+-')
+local zero = P('0')
+local digit = R('09')
+local digits = digit^1
+local octdigit = R("07")
+local octdigits = octdigit^1
+local lowercase = R("az")
+local uppercase = R("AZ")
+local underscore = P("_")
+local hexdigit = digit + lowercase + uppercase
+local hexdigits = hexdigit^1
+local cr, lf, crlf = P("\r"), P("\n"), P("\r\n")
+----- newline = crlf + S("\r\n") -- cr + lf
+local newline = P("\r") * (P("\n") + P(true)) + P("\n") -- P("\r")^-1 * P("\n")^-1
+local escaped = P("\\") * anything
+local squote = P("'")
+local dquote = P('"')
+local space = P(" ")
+local period = P(".")
+local comma = P(",")
+
+local utfbom_32_be = P('\000\000\254\255') -- 00 00 FE FF
+local utfbom_32_le = P('\255\254\000\000') -- FF FE 00 00
+local utfbom_16_be = P('\254\255') -- FE FF
+local utfbom_16_le = P('\255\254') -- FF FE
+local utfbom_8 = P('\239\187\191') -- EF BB BF
+local utfbom = utfbom_32_be + utfbom_32_le
+ + utfbom_16_be + utfbom_16_le
+ + utfbom_8
+local utftype = utfbom_32_be * Cc("utf-32-be") + utfbom_32_le * Cc("utf-32-le")
+ + utfbom_16_be * Cc("utf-16-be") + utfbom_16_le * Cc("utf-16-le")
+ + utfbom_8 * Cc("utf-8") + alwaysmatched * Cc("utf-8") -- assume utf8
+local utfstricttype = utfbom_32_be * Cc("utf-32-be") + utfbom_32_le * Cc("utf-32-le")
+ + utfbom_16_be * Cc("utf-16-be") + utfbom_16_le * Cc("utf-16-le")
+ + utfbom_8 * Cc("utf-8")
+local utfoffset = utfbom_32_be * Cc(4) + utfbom_32_le * Cc(4)
+ + utfbom_16_be * Cc(2) + utfbom_16_le * Cc(2)
+ + utfbom_8 * Cc(3) + Cc(0)
+
+local utf8next = R("\128\191")
+
+patterns.utfbom_32_be = utfbom_32_be
+patterns.utfbom_32_le = utfbom_32_le
+patterns.utfbom_16_be = utfbom_16_be
+patterns.utfbom_16_le = utfbom_16_le
+patterns.utfbom_8 = utfbom_8
+
+patterns.utf_16_be_nl = P("\000\r\000\n") + P("\000\r") + P("\000\n") -- P("\000\r") * (P("\000\n") + P(true)) + P("\000\n")
+patterns.utf_16_le_nl = P("\r\000\n\000") + P("\r\000") + P("\n\000") -- P("\r\000") * (P("\n\000") + P(true)) + P("\n\000")
+
+patterns.utf_32_be_nl = P("\000\000\000\r\000\000\000\n") + P("\000\000\000\r") + P("\000\000\000\n")
+patterns.utf_32_le_nl = P("\r\000\000\000\n\000\000\000") + P("\r\000\000\000") + P("\n\000\000\000")
+
+patterns.utf8one = R("\000\127")
+patterns.utf8two = R("\194\223") * utf8next
+patterns.utf8three = R("\224\239") * utf8next * utf8next
+patterns.utf8four = R("\240\244") * utf8next * utf8next * utf8next
+patterns.utfbom = utfbom
+patterns.utftype = utftype
+patterns.utfstricttype = utfstricttype
+patterns.utfoffset = utfoffset
+
+local utf8char = patterns.utf8one + patterns.utf8two + patterns.utf8three + patterns.utf8four
+local validutf8char = utf8char^0 * endofstring * Cc(true) + Cc(false)
+
+local utf8character = P(1) * R("\128\191")^0 -- unchecked but fast
+
+patterns.utf8 = utf8char
+patterns.utf8char = utf8char
+patterns.utf8character = utf8character -- this one can be used in most cases so we might use that one
+patterns.validutf8 = validutf8char
+patterns.validutf8char = validutf8char
+
+local eol = S("\n\r")
+local spacer = S(" \t\f\v") -- + char(0xc2, 0xa0) if we want utf (cf mail roberto)
+local whitespace = eol + spacer
+local nonspacer = 1 - spacer
+local nonwhitespace = 1 - whitespace
+
+patterns.eol = eol
+patterns.spacer = spacer
+patterns.whitespace = whitespace
+patterns.nonspacer = nonspacer
+patterns.nonwhitespace = nonwhitespace
+
+local stripper = spacer ^0 * C((spacer ^0 * nonspacer ^1)^0) -- from example by roberto
+local fullstripper = whitespace^0 * C((whitespace^0 * nonwhitespace^1)^0)
+
+----- collapser = Cs(spacer^0/"" * ((spacer^1 * endofstring / "") + (spacer^1/" ") + P(1))^0)
+local collapser = Cs(spacer^0/"" * nonspacer^0 * ((spacer^0/" " * nonspacer^1)^0))
+local nospacer = Cs((whitespace^1/"" + nonwhitespace^1)^0)
+
+local b_collapser = Cs( whitespace^0 /"" * (nonwhitespace^1 + whitespace^1/" ")^0)
+local e_collapser = Cs((whitespace^1 * endofstring/"" + nonwhitespace^1 + whitespace^1/" ")^0)
+local m_collapser = Cs( (nonwhitespace^1 + whitespace^1/" ")^0)
+
+local b_stripper = Cs( spacer^0 /"" * (nonspacer^1 + spacer^1/" ")^0)
+local e_stripper = Cs((spacer^1 * endofstring/"" + nonspacer^1 + spacer^1/" ")^0)
+local m_stripper = Cs( (nonspacer^1 + spacer^1/" ")^0)
+
+patterns.stripper = stripper
+patterns.fullstripper = fullstripper
+patterns.collapser = collapser
+patterns.nospacer = nospacer
+
+patterns.b_collapser = b_collapser
+patterns.m_collapser = m_collapser
+patterns.e_collapser = e_collapser
+
+patterns.b_stripper = b_stripper
+patterns.m_stripper = m_stripper
+patterns.e_stripper = e_stripper
+
+patterns.lowercase = lowercase
+patterns.uppercase = uppercase
+patterns.letter = patterns.lowercase + patterns.uppercase
+patterns.space = space
+patterns.tab = P("\t")
+patterns.spaceortab = patterns.space + patterns.tab
+patterns.newline = newline
+patterns.emptyline = newline^1
+patterns.equal = P("=")
+patterns.comma = comma
+patterns.commaspacer = comma * spacer^0
+patterns.period = period
+patterns.colon = P(":")
+patterns.semicolon = P(";")
+patterns.underscore = underscore
+patterns.escaped = escaped
+patterns.squote = squote
+patterns.dquote = dquote
+patterns.nosquote = (escaped + (1-squote))^0
+patterns.nodquote = (escaped + (1-dquote))^0
+patterns.unsingle = (squote/"") * patterns.nosquote * (squote/"") -- will change to C in the middle
+patterns.undouble = (dquote/"") * patterns.nodquote * (dquote/"") -- will change to C in the middle
+patterns.unquoted = patterns.undouble + patterns.unsingle -- more often undouble
+patterns.unspacer = ((patterns.spacer^1)/"")^0
+
+patterns.singlequoted = squote * patterns.nosquote * squote
+patterns.doublequoted = dquote * patterns.nodquote * dquote
+patterns.quoted = patterns.doublequoted + patterns.singlequoted
+
+patterns.digit = digit
+patterns.digits = digits
+patterns.octdigit = octdigit
+patterns.octdigits = octdigits
+patterns.hexdigit = hexdigit
+patterns.hexdigits = hexdigits
+patterns.sign = sign
+patterns.cardinal = digits
+patterns.integer = sign^-1 * digits
+patterns.unsigned = digit^0 * period * digits
+patterns.float = sign^-1 * patterns.unsigned
+patterns.cunsigned = digit^0 * comma * digits
+patterns.cpunsigned = digit^0 * (period + comma) * digits
+patterns.cfloat = sign^-1 * patterns.cunsigned
+patterns.cpfloat = sign^-1 * patterns.cpunsigned
+patterns.number = patterns.float + patterns.integer
+patterns.cnumber = patterns.cfloat + patterns.integer
+patterns.cpnumber = patterns.cpfloat + patterns.integer
+patterns.oct = zero * octdigits -- hm is this ok
+patterns.octal = patterns.oct
+patterns.HEX = zero * P("X") * (digit+uppercase)^1
+patterns.hex = zero * P("x") * (digit+lowercase)^1
+patterns.hexadecimal = zero * S("xX") * hexdigits
+
+patterns.hexafloat = sign^-1
+ * zero * S("xX")
+ * (hexdigit^0 * period * hexdigits + hexdigits * period * hexdigit^0 + hexdigits)
+ * (S("pP") * sign^-1 * hexdigits)^-1
+patterns.decafloat = sign^-1
+ * (digit^0 * period * digits + digits * period * digit^0 + digits)
+ * S("eE") * sign^-1 * digits
+
+patterns.propername = (uppercase + lowercase + underscore) * (uppercase + lowercase + underscore + digit)^0 * endofstring
+
+patterns.somecontent = (anything - newline - space)^1 -- (utf8char - newline - space)^1
+patterns.beginline = #(1-newline)
+
+patterns.longtostring = Cs(whitespace^0/"" * ((patterns.quoted + nonwhitespace^1 + whitespace^1/"" * (endofstring + Cc(" ")))^0))
+
+-- local function anywhere(pattern) -- slightly adapted from website
+-- return P { P(pattern) + 1 * V(1) }
+-- end
+
+function anywhere(pattern) -- faster
+ return (1-P(pattern))^0 * P(pattern)
+end
+
+lpeg.anywhere = anywhere
+
+function lpeg.instringchecker(p)
+ p = anywhere(p)
+ return function(str)
+ return lpegmatch(p,str) and true or false
+ end
+end
+
+-- function lpeg.splitter(pattern, action)
+-- return (((1-P(pattern))^1)/action+1)^0
+-- end
+
+-- function lpeg.tsplitter(pattern, action)
+-- return Ct((((1-P(pattern))^1)/action+1)^0)
+-- end
+
+function lpeg.splitter(pattern, action)
+ if action then
+ return (((1-P(pattern))^1)/action+1)^0
+ else
+ return (Cs((1-P(pattern))^1)+1)^0
+ end
+end
+
+function lpeg.tsplitter(pattern, action)
+ if action then
+ return Ct((((1-P(pattern))^1)/action+1)^0)
+ else
+ return Ct((Cs((1-P(pattern))^1)+1)^0)
+ end
+end
+
+-- probleem: separator can be lpeg and that does not hash too well, but
+-- it's quite okay as the key is then not garbage collected
+
+local splitters_s, splitters_m, splitters_t = { }, { }, { }
+
+local function splitat(separator,single)
+ local splitter = (single and splitters_s[separator]) or splitters_m[separator]
+ if not splitter then
+ separator = P(separator)
+ local other = C((1 - separator)^0)
+ if single then
+ local any = anything
+ splitter = other * (separator * C(any^0) + "") -- ?
+ splitters_s[separator] = splitter
+ else
+ splitter = other * (separator * other)^0
+ splitters_m[separator] = splitter
+ end
+ end
+ return splitter
+end
+
+local function tsplitat(separator)
+ local splitter = splitters_t[separator]
+ if not splitter then
+ splitter = Ct(splitat(separator))
+ splitters_t[separator] = splitter
+ end
+ return splitter
+end
+
+lpeg.splitat = splitat
+lpeg.tsplitat = tsplitat
+
+function string.splitup(str,separator)
+ if not separator then
+ separator = ","
+ end
+ return lpegmatch(splitters_m[separator] or splitat(separator),str)
+end
+
+-- local p = splitat("->",false) print(lpegmatch(p,"oeps->what->more")) -- oeps what more
+-- local p = splitat("->",true) print(lpegmatch(p,"oeps->what->more")) -- oeps what->more
+-- local p = splitat("->",false) print(lpegmatch(p,"oeps")) -- oeps
+-- local p = splitat("->",true) print(lpegmatch(p,"oeps")) -- oeps
+
+local cache = { }
+
+function lpeg.split(separator,str)
+ local c = cache[separator]
+ if not c then
+ c = tsplitat(separator)
+ cache[separator] = c
+ end
+ return lpegmatch(c,str)
+end
+
+function string.split(str,separator)
+ if separator then
+ local c = cache[separator]
+ if not c then
+ c = tsplitat(separator)
+ cache[separator] = c
+ end
+ return lpegmatch(c,str)
+ else
+ return { str }
+ end
+end
+
+local spacing = patterns.spacer^0 * newline -- sort of strip
+local empty = spacing * Cc("")
+local nonempty = Cs((1-spacing)^1) * spacing^-1
+local content = (empty + nonempty)^1
+
+patterns.textline = content
+
+local linesplitter = tsplitat(newline)
+
+patterns.linesplitter = linesplitter
+
+function string.splitlines(str)
+ return lpegmatch(linesplitter,str)
+end
+
+-- lpeg.splitters = cache -- no longer public
+
+local cache = { }
+
+function lpeg.checkedsplit(separator,str)
+ local c = cache[separator]
+ if not c then
+ separator = P(separator)
+ local other = C((1 - separator)^1)
+ c = Ct(separator^0 * other * (separator^1 * other)^0)
+ cache[separator] = c
+ end
+ return lpegmatch(c,str)
+end
+
+function string.checkedsplit(str,separator)
+ local c = cache[separator]
+ if not c then
+ separator = P(separator)
+ local other = C((1 - separator)^1)
+ c = Ct(separator^0 * other * (separator^1 * other)^0)
+ cache[separator] = c
+ end
+ return lpegmatch(c,str)
+end
+
+-- from roberto's site:
+
+local function f2(s) local c1, c2 = byte(s,1,2) return c1 * 64 + c2 - 12416 end
+local function f3(s) local c1, c2, c3 = byte(s,1,3) return (c1 * 64 + c2) * 64 + c3 - 925824 end
+local function f4(s) local c1, c2, c3, c4 = byte(s,1,4) return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168 end
+
+local utf8byte = patterns.utf8one/byte + patterns.utf8two/f2 + patterns.utf8three/f3 + patterns.utf8four/f4
+
+patterns.utf8byte = utf8byte
+
+--~ local str = " a b c d "
+
+--~ local s = lpeg.stripper(lpeg.R("az")) print("["..lpegmatch(s,str).."]")
+--~ local s = lpeg.keeper(lpeg.R("az")) print("["..lpegmatch(s,str).."]")
+--~ local s = lpeg.stripper("ab") print("["..lpegmatch(s,str).."]")
+--~ local s = lpeg.keeper("ab") print("["..lpegmatch(s,str).."]")
+
+local cache = { }
+
+function lpeg.stripper(str)
+ if type(str) == "string" then
+ local s = cache[str]
+ if not s then
+ s = Cs(((S(str)^1)/"" + 1)^0)
+ cache[str] = s
+ end
+ return s
+ else
+ return Cs(((str^1)/"" + 1)^0)
+ end
+end
+
+local cache = { }
+
+function lpeg.keeper(str)
+ if type(str) == "string" then
+ local s = cache[str]
+ if not s then
+ s = Cs((((1-S(str))^1)/"" + 1)^0)
+ cache[str] = s
+ end
+ return s
+ else
+ return Cs((((1-str)^1)/"" + 1)^0)
+ end
+end
+
+function lpeg.frontstripper(str) -- or pattern (yet undocumented)
+ return (P(str) + P(true)) * Cs(anything^0)
+end
+
+function lpeg.endstripper(str) -- or pattern (yet undocumented)
+ return Cs((1 - P(str) * endofstring)^0)
+end
+
+-- Just for fun I looked at the used bytecode and
+-- p = (p and p + pp) or pp gets one more (testset).
+
+-- todo: cache when string
+
+function lpeg.replacer(one,two,makefunction,isutf) -- in principle we should sort the keys
+ local pattern
+ local u = isutf and utf8char or 1
+ if type(one) == "table" then
+ local no = #one
+ local p = P(false)
+ if no == 0 then
+ for k, v in next, one do
+ p = p + P(k) / v
+ end
+ pattern = Cs((p + u)^0)
+ elseif no == 1 then
+ local o = one[1]
+ one, two = P(o[1]), o[2]
+ -- pattern = Cs(((1-one)^1 + one/two)^0)
+ pattern = Cs((one/two + u)^0)
+ else
+ for i=1,no do
+ local o = one[i]
+ p = p + P(o[1]) / o[2]
+ end
+ pattern = Cs((p + u)^0)
+ end
+ else
+ pattern = Cs((P(one)/(two or "") + u)^0)
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
+ end
+ else
+ return pattern
+ end
+end
+
+-- local pattern1 = P(1-P(pattern))^0 * P(pattern) : test for not nil
+-- local pattern2 = (P(pattern) * Cc(true) + P(1))^0 : test for true (could be faster, but not much)
+
+function lpeg.finder(lst,makefunction,isutf) -- beware: slower than find with 'patternless finds'
+ local pattern
+ if type(lst) == "table" then
+ pattern = P(false)
+ if #lst == 0 then
+ for k, v in next, lst do
+ pattern = pattern + P(k) -- ignore key, so we can use a replacer table
+ end
+ else
+ for i=1,#lst do
+ pattern = pattern + P(lst[i])
+ end
+ end
+ else
+ pattern = P(lst)
+ end
+ if isutf then
+ pattern = ((utf8char or 1)-pattern)^0 * pattern
+ else
+ pattern = (1-pattern)^0 * pattern
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
+ end
+ else
+ return pattern
+ end
+end
+
+-- print(lpeg.match(lpeg.replacer("e","a"),"test test"))
+-- print(lpeg.match(lpeg.replacer{{"e","a"}},"test test"))
+-- print(lpeg.match(lpeg.replacer({ e = "a", t = "x" }),"test test"))
+
+local splitters_f, splitters_s = { }, { }
+
+function lpeg.firstofsplit(separator) -- always return value
+ local splitter = splitters_f[separator]
+ if not splitter then
+ local pattern = P(separator)
+ splitter = C((1 - pattern)^0)
+ splitters_f[separator] = splitter
+ end
+ return splitter
+end
+
+function lpeg.secondofsplit(separator) -- nil if not split
+ local splitter = splitters_s[separator]
+ if not splitter then
+ local pattern = P(separator)
+ splitter = (1 - pattern)^0 * pattern * C(anything^0)
+ splitters_s[separator] = splitter
+ end
+ return splitter
+end
+
+local splitters_s, splitters_p = { }, { }
+
+function lpeg.beforesuffix(separator) -- nil if nothing but empty is ok
+ local splitter = splitters_s[separator]
+ if not splitter then
+ local pattern = P(separator)
+ splitter = C((1 - pattern)^0) * pattern * endofstring
+ splitters_s[separator] = splitter
+ end
+ return splitter
+end
+
+function lpeg.afterprefix(separator) -- nil if nothing but empty is ok
+ local splitter = splitters_p[separator]
+ if not splitter then
+ local pattern = P(separator)
+ splitter = pattern * C(anything^0)
+ splitters_p[separator] = splitter
+ end
+ return splitter
+end
+
+function lpeg.balancer(left,right)
+ left, right = P(left), P(right)
+ return P { left * ((1 - left - right) + V(1))^0 * right }
+end
+
+-- print(1,lpegmatch(lpeg.firstofsplit(":"),"bc:de"))
+-- print(2,lpegmatch(lpeg.firstofsplit(":"),":de")) -- empty
+-- print(3,lpegmatch(lpeg.firstofsplit(":"),"bc"))
+-- print(4,lpegmatch(lpeg.secondofsplit(":"),"bc:de"))
+-- print(5,lpegmatch(lpeg.secondofsplit(":"),"bc:")) -- empty
+-- print(6,lpegmatch(lpeg.secondofsplit(":",""),"bc"))
+-- print(7,lpegmatch(lpeg.secondofsplit(":"),"bc"))
+-- print(9,lpegmatch(lpeg.secondofsplit(":","123"),"bc"))
+
+-- this was slower but lpeg has been sped up in the meantime, so we no longer
+-- use this (still seems somewhat faster on long strings)
+--
+-- local nany = utf8char/""
+--
+-- function lpeg.counter(pattern)
+-- pattern = Cs((P(pattern)/" " + nany)^0)
+-- return function(str)
+-- return #lpegmatch(pattern,str)
+-- end
+-- end
+
+function lpeg.counter(pattern,action)
+ local n = 0
+ local pattern = (P(pattern) / function() n = n + 1 end + anything)^0
+ ----- pattern = (P(pattern) * (P(true) / function() n = n + 1 end) + anything)^0
+ ----- pattern = (P(pattern) * P(function() n = n + 1 end) + anything)^0
+ if action then
+ return function(str) n = 0 ; lpegmatch(pattern,str) ; action(n) end
+ else
+ return function(str) n = 0 ; lpegmatch(pattern,str) ; return n end
+ end
+end
+
+-- lpeg.print(lpeg.R("ab","cd","gh"))
+-- lpeg.print(lpeg.P("a","b","c"))
+-- lpeg.print(lpeg.S("a","b","c"))
+
+-- print(lpeg.count("äáàa",lpeg.P("á") + lpeg.P("à")))
+-- print(lpeg.count("äáàa",lpeg.UP("áà")))
+-- print(lpeg.count("äáàa",lpeg.US("àá")))
+-- print(lpeg.count("äáàa",lpeg.UR("aá")))
+-- print(lpeg.count("äáàa",lpeg.UR("àá")))
+-- print(lpeg.count("äáàa",lpeg.UR(0x0000,0xFFFF)))
+
+function lpeg.is_lpeg(p)
+ return p and lpegtype(p) == "pattern"
+end
+
+function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then") -- assume proper order
+ if type(list) ~= "table" then
+ list = { list, ... }
+ end
+ -- table.sort(list) -- longest match first
+ local p = P(list[1])
+ for l=2,#list do
+ p = p + P(list[l])
+ end
+ return p
+end
+
+-- For the moment here, but it might move to utilities. Beware, we need to
+-- have the longest keyword first, so 'aaa' comes beforte 'aa' which is why we
+-- loop back from the end cq. prepend.
+
+local sort = table.sort
+
+local function copyindexed(old)
+ local new = { }
+ for i=1,#old do
+ new[i] = old
+ end
+ return new
+end
+
+local function sortedkeys(tab)
+ local keys, s = { }, 0
+ for key,_ in next, tab do
+ s = s + 1
+ keys[s] = key
+ end
+ sort(keys)
+ return keys
+end
+
+function lpeg.append(list,pp,delayed,checked)
+ local p = pp
+ if #list > 0 then
+ local keys = copyindexed(list)
+ sort(keys)
+ for i=#keys,1,-1 do
+ local k = keys[i]
+ if p then
+ p = P(k) + p
+ else
+ p = P(k)
+ end
+ end
+ elseif delayed then -- hm, it looks like the lpeg parser resolves anyway
+ local keys = sortedkeys(list)
+ if p then
+ for i=1,#keys,1 do
+ local k = keys[i]
+ local v = list[k]
+ p = P(k)/list + p
+ end
+ else
+ for i=1,#keys do
+ local k = keys[i]
+ local v = list[k]
+ if p then
+ p = P(k) + p
+ else
+ p = P(k)
+ end
+ end
+ if p then
+ p = p / list
+ end
+ end
+ elseif checked then
+ -- problem: substitution gives a capture
+ local keys = sortedkeys(list)
+ for i=1,#keys do
+ local k = keys[i]
+ local v = list[k]
+ if p then
+ if k == v then
+ p = P(k) + p
+ else
+ p = P(k)/v + p
+ end
+ else
+ if k == v then
+ p = P(k)
+ else
+ p = P(k)/v
+ end
+ end
+ end
+ else
+ local keys = sortedkeys(list)
+ for i=1,#keys do
+ local k = keys[i]
+ local v = list[k]
+ if p then
+ p = P(k)/v + p
+ else
+ p = P(k)/v
+ end
+ end
+ end
+ return p
+end
+
+-- inspect(lpeg.append({ a = "1", aa = "1", aaa = "1" } ,nil,true))
+-- inspect(lpeg.append({ ["degree celsius"] = "1", celsius = "1", degree = "1" } ,nil,true))
+
+-- function lpeg.exact_match(words,case_insensitive)
+-- local pattern = concat(words)
+-- if case_insensitive then
+-- local pattern = S(upper(characters)) + S(lower(characters))
+-- local list = { }
+-- for i=1,#words do
+-- list[lower(words[i])] = true
+-- end
+-- return Cmt(pattern^1, function(_,i,s)
+-- return list[lower(s)] and i
+-- end)
+-- else
+-- local pattern = S(concat(words))
+-- local list = { }
+-- for i=1,#words do
+-- list[words[i]] = true
+-- end
+-- return Cmt(pattern^1, function(_,i,s)
+-- return list[s] and i
+-- end)
+-- end
+-- end
+
+-- experiment:
+
+local p_false = P(false)
+local p_true = P(true)
+
+-- local function collapse(t,x)
+-- if type(t) ~= "table" then
+-- return t, x
+-- else
+-- local n = next(t)
+-- if n == nil then
+-- return t, x
+-- elseif next(t,n) == nil then
+-- -- one entry
+-- local k = n
+-- local v = t[k]
+-- if type(v) == "table" then
+-- return collapse(v,x..k)
+-- else
+-- return v, x .. k
+-- end
+-- else
+-- local tt = { }
+-- for k, v in next, t do
+-- local vv, kk = collapse(v,k)
+-- tt[kk] = vv
+-- end
+-- return tt, x
+-- end
+-- end
+-- end
+
+local lower = utf and utf.lower or string.lower
+local upper = utf and utf.upper or string.upper
+
+function lpeg.setutfcasers(l,u)
+ lower = l or lower
+ upper = u or upper
+end
+
+local function make1(t,rest)
+ local p = p_false
+ local keys = sortedkeys(t)
+ for i=1,#keys do
+ local k = keys[i]
+ if k ~= "" then
+ local v = t[k]
+ if v == true then
+ p = p + P(k) * p_true
+ elseif v == false then
+ -- can't happen
+ else
+ p = p + P(k) * make1(v,v[""])
+ end
+ end
+ end
+ if rest then
+ p = p + p_true
+ end
+ return p
+end
+
+local function make2(t,rest) -- only ascii
+ local p = p_false
+ local keys = sortedkeys(t)
+ for i=1,#keys do
+ local k = keys[i]
+ if k ~= "" then
+ local v = t[k]
+ if v == true then
+ p = p + (P(lower(k))+P(upper(k))) * p_true
+ elseif v == false then
+ -- can't happen
+ else
+ p = p + (P(lower(k))+P(upper(k))) * make2(v,v[""])
+ end
+ end
+ end
+ if rest then
+ p = p + p_true
+ end
+ return p
+end
+
+local function utfchartabletopattern(list,insensitive) -- goes to util-lpg
+ local tree = { }
+ local n = #list
+ if n == 0 then
+ for s in next, list do
+ local t = tree
+ local p, pk
+ for c in gmatch(s,".") do
+ if t == true then
+ t = { [c] = true, [""] = true }
+ p[pk] = t
+ p = t
+ t = false
+ elseif t == false then
+ t = { [c] = false }
+ p[pk] = t
+ p = t
+ t = false
+ else
+ local tc = t[c]
+ if not tc then
+ tc = false
+ t[c] = false
+ end
+ p = t
+ t = tc
+ end
+ pk = c
+ end
+ if t == false then
+ p[pk] = true
+ elseif t == true then
+ -- okay
+ else
+ t[""] = true
+ end
+ end
+ else
+ for i=1,n do
+ local s = list[i]
+ local t = tree
+ local p, pk
+ for c in gmatch(s,".") do
+ if t == true then
+ t = { [c] = true, [""] = true }
+ p[pk] = t
+ p = t
+ t = false
+ elseif t == false then
+ t = { [c] = false }
+ p[pk] = t
+ p = t
+ t = false
+ else
+ local tc = t[c]
+ if not tc then
+ tc = false
+ t[c] = false
+ end
+ p = t
+ t = tc
+ end
+ pk = c
+ end
+ if t == false then
+ p[pk] = true
+ elseif t == true then
+ -- okay
+ else
+ t[""] = true
+ end
+ end
+ end
+ -- collapse(tree,"") -- needs testing, maybe optional, slightly faster because P("x")*P("X") seems slower than P"(xX") (why)
+ -- inspect(tree)
+ return (insensitive and make2 or make1)(tree)
+end
+
+lpeg.utfchartabletopattern = utfchartabletopattern
+
+function lpeg.utfreplacer(list,insensitive)
+ local pattern = Cs((utfchartabletopattern(list,insensitive)/list + utf8character)^0)
+ return function(str)
+ return lpegmatch(pattern,str) or str
+ end
+end
+
+-- local t = { "start", "stoep", "staart", "paard" }
+-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1)
+
+-- local t = { "a", "abc", "ac", "abe", "abxyz", "xy", "bef","aa" }
+-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1)
+
+-- inspect(lpegmatch(p,"a")=="A")
+-- inspect(lpegmatch(p,"aa")=="AA")
+-- inspect(lpegmatch(p,"aaaa")=="AAAA")
+-- inspect(lpegmatch(p,"ac")=="AC")
+-- inspect(lpegmatch(p,"bc")=="bc")
+-- inspect(lpegmatch(p,"zzbczz")=="zzbczz")
+-- inspect(lpegmatch(p,"zzabezz")=="zzABEzz")
+-- inspect(lpegmatch(p,"ab")=="Ab")
+-- inspect(lpegmatch(p,"abc")=="ABC")
+-- inspect(lpegmatch(p,"abe")=="ABE")
+-- inspect(lpegmatch(p,"xa")=="xA")
+-- inspect(lpegmatch(p,"bx")=="bx")
+-- inspect(lpegmatch(p,"bax")=="bAx")
+-- inspect(lpegmatch(p,"abxyz")=="ABXYZ")
+-- inspect(lpegmatch(p,"foobarbefcrap")=="foobArBEFcrAp")
+
+-- local t = { ["^"] = 1, ["^^"] = 2, ["^^^"] = 3, ["^^^^"] = 4 }
+-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/t + 1)^1)
+-- inspect(lpegmatch(p," ^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^ ^^^^^^^ "))
+
+-- local t = { ["^^"] = 2, ["^^^"] = 3, ["^^^^"] = 4 }
+-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/t + 1)^1)
+-- inspect(lpegmatch(p," ^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^ ^^^^^^^ "))
+
+-- lpeg.utfchartabletopattern {
+-- utfchar(0x00A0), -- nbsp
+-- utfchar(0x2000), -- enquad
+-- utfchar(0x2001), -- emquad
+-- utfchar(0x2002), -- enspace
+-- utfchar(0x2003), -- emspace
+-- utfchar(0x2004), -- threeperemspace
+-- utfchar(0x2005), -- fourperemspace
+-- utfchar(0x2006), -- sixperemspace
+-- utfchar(0x2007), -- figurespace
+-- utfchar(0x2008), -- punctuationspace
+-- utfchar(0x2009), -- breakablethinspace
+-- utfchar(0x200A), -- hairspace
+-- utfchar(0x200B), -- zerowidthspace
+-- utfchar(0x202F), -- narrownobreakspace
+-- utfchar(0x205F), -- math thinspace
+-- }
+
+-- a few handy ones:
+--
+-- faster than find(str,"[\n\r]") when match and # > 7 and always faster when # > 3
+
+patterns.containseol = lpeg.finder(eol) -- (1-eol)^0 * eol
+
+-- The next pattern^n variant is based on an approach suggested
+-- by Roberto: constructing a big repetition in chunks.
+--
+-- Being sparse is not needed, and only complicate matters and
+-- the number of redundant entries is not that large.
+
+local function nextstep(n,step,result)
+ local m = n % step -- mod(n,step)
+ local d = floor(n/step) -- div(n,step)
+ if d > 0 then
+ local v = V(tostring(step))
+ local s = result.start
+ for i=1,d do
+ if s then
+ s = v * s
+ else
+ s = v
+ end
+ end
+ result.start = s
+ end
+ if step > 1 and result.start then
+ local v = V(tostring(step/2))
+ result[tostring(step)] = v * v
+ end
+ if step > 0 then
+ return nextstep(m,step/2,result)
+ else
+ return result
+ end
+end
+
+function lpeg.times(pattern,n)
+ return P(nextstep(n,2^16,{ "start", ["1"] = pattern }))
+end
+
+-- local p = lpeg.Cs((1 - lpeg.times(lpeg.P("AB"),25))^1)
+-- local s = "12" .. string.rep("AB",20) .. "34" .. string.rep("AB",30) .. "56"
+-- inspect(p)
+-- print(lpeg.match(p,s))
+
+-- moved here (before util-str)
+
+do
+
+ local trailingzeros = zero^0 * -digit -- suggested by Roberto
+ local stripper = Cs((
+ digits * (
+ period * trailingzeros / ""
+ + period * (digit - trailingzeros)^1 * (trailingzeros / "")
+ ) + 1
+ )^0)
+
+ lpeg.patterns.stripzeros = stripper -- multiple in string
+
+ local nonzero = digit - zero
+ local trailingzeros = zero^1 * endofstring
+ local stripper = Cs( (1-period)^0 * (
+ period * trailingzeros/""
+ + period * (nonzero^1 + (trailingzeros/"") + zero^1)^0
+ + endofstring
+ ))
+
+ lpeg.patterns.stripzero = stripper -- slightly more efficient but expects a float !
+
+ -- local sample = "bla 11.00 bla 11 bla 0.1100 bla 1.00100 bla 0.00 bla 0.001 bla 1.1100 bla 0.100100100 bla 0.00100100100"
+ -- collectgarbage("collect")
+ -- str = string.rep(sample,10000)
+ -- local ts = os.clock()
+ -- lpegmatch(stripper,str)
+ -- print(#str, os.clock()-ts, lpegmatch(stripper,sample))
+
+end
+
+-- for practical reasons we keep this here:
+
+local byte_to_HEX = { }
+local byte_to_hex = { }
+local byte_to_dec = { } -- for md5
+local hex_to_byte = { }
+
+for i=0,255 do
+ local H = format("%02X",i)
+ local h = format("%02x",i)
+ local d = format("%03i",i)
+ local c = char(i)
+ byte_to_HEX[c] = H
+ byte_to_hex[c] = h
+ byte_to_dec[c] = d
+ hex_to_byte[h] = c
+ hex_to_byte[H] = c
+end
+
+local hextobyte = P(2)/hex_to_byte
+local bytetoHEX = P(1)/byte_to_HEX
+local bytetohex = P(1)/byte_to_hex
+local bytetodec = P(1)/byte_to_dec
+local hextobytes = Cs(hextobyte^0)
+local bytestoHEX = Cs(bytetoHEX^0)
+local bytestohex = Cs(bytetohex^0)
+local bytestodec = Cs(bytetodec^0)
+
+patterns.hextobyte = hextobyte
+patterns.bytetoHEX = bytetoHEX
+patterns.bytetohex = bytetohex
+patterns.bytetodec = bytetodec
+patterns.hextobytes = hextobytes
+patterns.bytestoHEX = bytestoHEX
+patterns.bytestohex = bytestohex
+patterns.bytestodec = bytestodec
+
+function string.toHEX(s)
+ if not s or s == "" then
+ return s
+ else
+ return lpegmatch(bytestoHEX,s)
+ end
+end
+
+function string.tohex(s)
+ if not s or s == "" then
+ return s
+ else
+ return lpegmatch(bytestohex,s)
+ end
+end
+
+function string.todec(s)
+ if not s or s == "" then
+ return s
+ else
+ return lpegmatch(bytestodec,s)
+ end
+end
+
+function string.tobytes(s)
+ if not s or s == "" then
+ return s
+ else
+ return lpegmatch(hextobytes,s)
+ end
+end
+
+-- local h = "ADFE0345"
+-- local b = lpegmatch(patterns.hextobytes,h)
+-- print(h,b,string.tohex(b),string.toHEX(b))
+
+local patterns = { } -- can be made weak
+
+local function containsws(what)
+ local p = patterns[what]
+ if not p then
+ local p1 = P(what) * (whitespace + endofstring) * Cc(true)
+ local p2 = whitespace * P(p1)
+ p = P(p1) + P(1-p2)^0 * p2 + Cc(false)
+ patterns[what] = p
+ end
+ return p
+end
+
+lpeg.containsws = containsws
+
+function string.containsws(str,what)
+ return lpegmatch(patterns[what] or containsws(what),str)
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-lua.lua b/macros/luatex/generic/lualibs/lualibs-lua.lua
new file mode 100644
index 0000000000..6e9606e849
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-lua.lua
@@ -0,0 +1,259 @@
+if not modules then modules = { } end modules ['l-lua'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- potential issues with 5.3:
+
+-- i'm not sure yet if the int/float change is good for luatex
+
+-- math.min
+-- math.max
+-- tostring
+-- tonumber
+-- utf.*
+-- bit32
+
+local next, type, tonumber = next, type, tonumber
+
+-- compatibility hacks and helpers
+
+LUAMAJORVERSION, LUAMINORVERSION = string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
+
+LUAMAJORVERSION = tonumber(LUAMAJORVERSION) or 5
+LUAMINORVERSION = tonumber(LUAMINORVERSION) or 1
+LUAVERSION = LUAMAJORVERSION + LUAMINORVERSION/10
+
+if LUAVERSION < 5.2 and jit then
+ --
+ -- we want loadstring cum suis to behave like 5.2
+ --
+ MINORVERSION = 2
+ LUAVERSION = 5.2
+end
+
+-- lpeg
+
+if not lpeg then
+ lpeg = require("lpeg")
+end
+
+-- if utf8 then
+-- utf8lua = utf8
+-- utf8 = nil
+-- end
+
+-- basics:
+
+if loadstring then
+
+ local loadnormal = load
+
+ function load(first,...)
+ if type(first) == "string" then
+ return loadstring(first,...)
+ else
+ return loadnormal(first,...)
+ end
+ end
+
+else
+
+ loadstring = load
+
+end
+
+-- table:
+
+-- At some point it was announced that i[pairs would be dropped, which makes
+-- sense. As we already used the for loop and # in most places the impact on
+-- ConTeXt was not that large; the remaining ipairs already have been replaced.
+-- Hm, actually ipairs was retained, but we no longer use it anyway (nor
+-- pairs).
+--
+-- Just in case, we provide the fallbacks as discussed in Programming
+-- in Lua (http://www.lua.org/pil/7.3.html):
+
+if not ipairs then
+
+ -- for k, v in ipairs(t) do ... end
+ -- for k=1,#t do local v = t[k] ... end
+
+ local function iterate(a,i)
+ i = i + 1
+ local v = a[i]
+ if v ~= nil then
+ return i, v --, nil
+ end
+ end
+
+ function ipairs(a)
+ return iterate, a, 0
+ end
+
+end
+
+if not pairs then
+
+ -- for k, v in pairs(t) do ... end
+ -- for k, v in next, t do ... end
+
+ function pairs(t)
+ return next, t -- , nil
+ end
+
+end
+
+-- The unpack function has been moved to the table table, and for compatiility
+-- reasons we provide both now.
+
+if not table.unpack then
+
+ table.unpack = _G.unpack
+
+elseif not unpack then
+
+ _G.unpack = table.unpack
+
+end
+
+-- package:
+
+-- if not package.seachers then
+--
+-- package.searchers = package.loaders -- 5.2
+--
+-- elseif not package.loaders then
+--
+-- package.loaders = package.searchers
+--
+-- end
+
+if not package.loaders then -- brr, searchers is a special "loadlib function" userdata type
+
+ package.loaders = package.searchers
+
+end
+
+-- moved from util-deb to here:
+
+local print, select, tostring = print, select, tostring
+
+local inspectors = { }
+
+function setinspector(kind,inspector) -- global function
+ inspectors[kind] = inspector
+end
+
+function inspect(...) -- global function
+ for s=1,select("#",...) do
+ local value = select(s,...)
+ if value == nil then
+ print("nil")
+ else
+ local done = false
+ -- type driven (table)
+ local kind = type(value)
+ local inspector = inspectors[kind]
+ if inspector then
+ done = inspector(value)
+ if done then
+ break
+ end
+ end
+ -- whatever driven (token, node, ...)
+ for kind, inspector in next, inspectors do
+ done = inspector(value)
+ if done then
+ break
+ end
+ end
+ if not done then
+ print(tostring(value))
+ end
+ end
+ end
+end
+
+--
+
+local dummy = function() end
+
+function optionalrequire(...)
+ local ok, result = xpcall(require,dummy,...)
+ if ok then
+ return result
+ end
+end
+
+-- nice for non ascii scripts (this might move):
+
+if lua then
+ lua.mask = load([[τεχ = 1]]) and "utf" or "ascii"
+end
+
+local flush = io.flush
+
+if flush then
+
+ local execute = os.execute if execute then function os.execute(...) flush() return execute(...) end end
+ local exec = os.exec if exec then function os.exec (...) flush() return exec (...) end end
+ local spawn = os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
+ local popen = io.popen if popen then function io.popen (...) flush() return popen (...) end end
+
+end
+
+-- new
+
+FFISUPPORTED = type(ffi) == "table" and ffi.os ~= "" and ffi.arch ~= "" and ffi.load
+
+if not FFISUPPORTED then
+
+ -- Maybe we should check for LUATEXENGINE but that's also a bit tricky as we still
+ -- can have a weird ffi library laying around. Checking for presence of 'jit' is
+ -- also not robust. So for now we hope for the best.
+
+ local okay ; okay, ffi = pcall(require,"ffi")
+
+ FFISUPPORTED = type(ffi) == "table" and ffi.os ~= "" and ffi.arch ~= "" and ffi.load
+
+end
+
+if not FFISUPPORTED then
+ ffi = nil
+elseif not ffi.number then
+ ffi.number = tonumber
+end
+
+-- if not bit32 then -- and utf8 then
+-- -- bit32 = load ( [[ -- replacement code with 5.3 syntax so that 5.2 doesn't bark on it ]] )
+-- bit32 = require("l-bit32")
+-- end
+
+-- We need this due a bug in luatex socket loading:
+
+-- local loaded = package.loaded
+--
+-- if not loaded["socket"] then loaded["socket"] = loaded["socket.core"] end
+-- if not loaded["mime"] then loaded["mime"] = loaded["mime.core"] end
+--
+-- if not socket.mime then socket.mime = package.loaded["mime"] end
+--
+-- if not loaded["socket.mime"] then loaded["socket.mime"] = socket.mime end
+-- if not loaded["socket.http"] then loaded["socket.http"] = socket.http end
+-- if not loaded["socket.ftp"] then loaded["socket.ftp"] = socket.ftp end
+-- if not loaded["socket.smtp"] then loaded["socket.smtp"] = socket.smtp end
+-- if not loaded["socket.tp"] then loaded["socket.tp"] = socket.tp end
+-- if not loaded["socket.url"] then loaded["socket.url"] = socket.url end
+
+if LUAVERSION > 5.3 then
+ -- collectgarbage("collect")
+ -- collectgarbage("generational") -- crashes on unix
+end
+
+if status and os.setenv then
+ os.setenv("engine",string.lower(status.luatex_engine or "unknown"))
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-math.lua b/macros/luatex/generic/lualibs/lualibs-math.lua
new file mode 100644
index 0000000000..e5668a5db0
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-math.lua
@@ -0,0 +1,149 @@
+if not modules then modules = { } end modules ['l-math'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+if not math.ceiling then
+
+ math.ceiling = math.ceil
+
+end
+
+if not math.round then
+
+ local floor = math.floor
+
+ function math.round(x) return floor(x + 0.5) end
+
+end
+
+if not math.div then
+
+ local floor = math.floor
+
+ function math.div(n,m) return floor(n/m) end
+
+end
+
+if not math.mod then
+
+ function math.mod(n,m) return n % m end
+
+end
+
+if not math.sind then
+
+ local sin, cos, tan = math.sin, math.cos, math.tan
+
+ local pipi = 2*math.pi/360
+
+ function math.sind(d) return sin(d*pipi) end
+ function math.cosd(d) return cos(d*pipi) end
+ function math.tand(d) return tan(d*pipi) end
+
+end
+
+if not math.odd then
+
+ function math.odd (n) return n % 2 ~= 0 end
+ function math.even(n) return n % 2 == 0 end
+
+end
+
+if not math.cosh then
+
+ local exp = math.exp
+
+ function math.cosh(x)
+ local xx = exp(x)
+ return (xx+1/xx)/2
+ end
+ function math.sinh(x)
+ local xx = exp(x)
+ return (xx-1/xx)/2
+ end
+ function math.tanh(x)
+ local xx = exp(x)
+ return (xx-1/xx)/(xx+1/xx)
+ end
+
+end
+
+if not math.pow then
+
+ function math.pow(x,y)
+ return x^y
+ end
+
+end
+
+if not math.atan2 then
+
+ math.atan2 = math.atan
+
+end
+
+if not math.ldexp then
+
+ function math.ldexp(x,e)
+ return x * 2.0^e
+ end
+
+end
+
+-- if not math.frexp then
+--
+-- -- not a oneliner so use a math library instead
+--
+-- function math.frexp(x,e)
+-- -- returns m and e such that x = m2e, e is an integer and the absolute
+-- -- value of m is in the range [0.5, 1) (or zero when x is zero)
+-- end
+--
+-- end
+
+if not math.log10 then
+
+ local log = math.log
+
+ function math.log10(x)
+ return log(x,10)
+ end
+
+end
+
+if not math.type then
+
+ function math.type()
+ return "float"
+ end
+
+end
+
+if not math.tointeger then
+
+ math.mininteger = -0x4FFFFFFFFFFF
+ math.maxinteger = 0x4FFFFFFFFFFF
+
+ local floor = math.floor
+
+ function math.tointeger(n)
+ local f = floor(n)
+ return f == n and f or nil
+ end
+
+end
+
+if not math.ult then
+
+ local floor = math.floor
+
+ function math.tointeger(m,n)
+ -- not ok but i'm not motivated to look into it now
+ return floor(m) < floor(n) -- unsigned comparison needed
+ end
+
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-md5.lua b/macros/luatex/generic/lualibs/lualibs-md5.lua
new file mode 100644
index 0000000000..6758fa4444
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-md5.lua
@@ -0,0 +1,110 @@
+if not modules then modules = { } end modules ['l-md5'] = {
+ version = 1.001,
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This also provides file checksums and checkers.
+
+if not md5 then
+ md5 = optionalrequire("md5")
+end
+
+if not md5 then
+ md5 = {
+ sum = function(str) print("error: md5 is not loaded (sum ignored)") return str end,
+ sumhexa = function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
+ }
+end
+
+local md5, file = md5, file
+local gsub = string.gsub
+
+-- local gsub, format, byte = string.gsub, string.format, string.byte
+--
+-- local function convert(str,fmt)
+-- return (gsub(md5sum(str),".",function(chr) return format(fmt,byte(chr)) end))
+-- end
+--
+-- if not md5.HEX then function md5.HEX(str) return convert(str,"%02X") end end
+-- if not md5.hex then function md5.hex(str) return convert(str,"%02x") end end
+-- if not md5.dec then function md5.dec(str) return convert(str,"%03i") end end
+
+do
+
+ local patterns = lpeg and lpeg.patterns
+
+ if patterns then
+
+ local bytestoHEX = patterns.bytestoHEX
+ local bytestohex = patterns.bytestohex
+ local bytestodec = patterns.bytestodec
+
+ local lpegmatch = lpeg.match
+ local md5sum = md5.sum
+
+ if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
+ if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
+ if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
+
+ md5.sumhexa = md5.hex
+ md5.sumHEXA = md5.HEX
+
+ end
+
+end
+
+function file.needsupdating(oldname,newname,threshold) -- size modification access change
+ local oldtime = lfs.attributes(oldname,"modification")
+ if oldtime then
+ local newtime = lfs.attributes(newname,"modification")
+ if not newtime then
+ return true -- no new file, so no updating needed
+ elseif newtime >= oldtime then
+ return false -- new file definitely needs updating
+ elseif oldtime - newtime < (threshold or 1) then
+ return false -- new file is probably still okay
+ else
+ return true -- new file has to be updated
+ end
+ else
+ return false -- no old file, so no updating needed
+ end
+end
+
+file.needs_updating = file.needsupdating
+
+function file.syncmtimes(oldname,newname)
+ local oldtime = lfs.attributes(oldname,"modification")
+ if oldtime and lfs.isfile(newname) then
+ lfs.touch(newname,oldtime,oldtime)
+ end
+end
+
+function file.checksum(name)
+ if md5 then
+ local data = io.loaddata(name)
+ if data then
+ return md5.HEX(data)
+ end
+ end
+ return nil
+end
+
+function file.loadchecksum(name)
+ if md5 then
+ local data = io.loaddata(name .. ".md5")
+ return data and (gsub(data,"%s",""))
+ end
+ return nil
+end
+
+function file.savechecksum(name,checksum)
+ if not checksum then checksum = file.checksum(name) end
+ if checksum then
+ io.savedata(name .. ".md5",checksum)
+ return checksum
+ end
+ return nil
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-number.lua b/macros/luatex/generic/lualibs/lualibs-number.lua
new file mode 100644
index 0000000000..9fd2f82f78
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-number.lua
@@ -0,0 +1,241 @@
+if not modules then modules = { } end modules ['l-number'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this module will be replaced when we have the bit library .. the number based sets
+-- might go away
+
+local tostring, tonumber = tostring, tonumber
+local format, floor, match, rep = string.format, math.floor, string.match, string.rep
+local concat, insert = table.concat, table.insert
+local lpegmatch = lpeg.match
+local floor = math.floor
+
+number = number or { }
+local number = number
+
+-- begin obsolete code --
+
+-- if bit32 then
+--
+-- local btest, bor = bit32.btest, bit32.bor
+--
+-- function number.bit(p)
+-- return 2 ^ (p - 1) -- 1-based indexing
+-- end
+--
+-- number.hasbit = btest
+-- number.setbit = bor
+--
+-- function number.setbit(x,p) -- why not bor?
+-- return btest(x,p) and x or x + p
+-- end
+--
+-- function number.clearbit(x,p)
+-- return btest(x,p) and x - p or x
+-- end
+--
+-- else
+--
+-- -- http://ricilake.blogspot.com/2007/10/iterating-bits-in-lua.html
+--
+-- function number.bit(p)
+-- return 2 ^ (p - 1) -- 1-based indexing
+-- end
+--
+-- function number.hasbit(x, p) -- typical call: if hasbit(x, bit(3)) then ...
+-- return x % (p + p) >= p
+-- end
+--
+-- function number.setbit(x, p)
+-- return (x % (p + p) >= p) and x or x + p
+-- end
+--
+-- function number.clearbit(x, p)
+-- return (x % (p + p) >= p) and x - p or x
+-- end
+--
+-- end
+
+-- end obsolete code --
+
+-- print(number.tobitstring(8))
+-- print(number.tobitstring(14))
+-- print(number.tobitstring(66))
+-- print(number.tobitstring(0x00))
+-- print(number.tobitstring(0xFF))
+-- print(number.tobitstring(46260767936,4))
+
+if bit32 then
+
+ local bextract = bit32.extract
+
+ local t = {
+ "0", "0", "0", "0", "0", "0", "0", "0",
+ "0", "0", "0", "0", "0", "0", "0", "0",
+ "0", "0", "0", "0", "0", "0", "0", "0",
+ "0", "0", "0", "0", "0", "0", "0", "0",
+ }
+
+ function number.tobitstring(b,m,w)
+ if not w then
+ w = 32
+ end
+ local n = w
+ for i=0,w-1 do
+ local v = bextract(b,i)
+ local k = w - i
+ if v == 1 then
+ n = k
+ t[k] = "1"
+ else
+ t[k] = "0"
+ end
+ end
+ if w then
+ return concat(t,"",1,w)
+ elseif m then
+ m = 33 - m * 8
+ if m < 1 then
+ m = 1
+ end
+ return concat(t,"",1,m)
+ elseif n < 8 then
+ return concat(t)
+ elseif n < 16 then
+ return concat(t,"",9)
+ elseif n < 24 then
+ return concat(t,"",17)
+ else
+ return concat(t,"",25)
+ end
+ end
+
+else
+
+ function number.tobitstring(n,m)
+ if n > 0 then
+ local t = { }
+ while n > 0 do
+ insert(t,1,n % 2 > 0 and 1 or 0)
+ n = floor(n/2)
+ end
+ local nn = 8 - #t % 8
+ if nn > 0 and nn < 8 then
+ for i=1,nn do
+ insert(t,1,0)
+ end
+ end
+ if m then
+ m = m * 8 - #t
+ if m > 0 then
+ insert(t,1,rep("0",m))
+ end
+ end
+ return concat(t)
+ elseif m then
+ rep("00000000",m)
+ else
+ return "00000000"
+ end
+ end
+
+end
+
+function number.valid(str,default)
+ return tonumber(str) or default or nil
+end
+
+function number.toevenhex(n)
+ local s = format("%X",n)
+ if #s % 2 == 0 then
+ return s
+ else
+ return "0" .. s
+ end
+end
+
+-- -- a,b,c,d,e,f = number.toset(100101)
+-- --
+-- -- function number.toset(n)
+-- -- return match(tostring(n),"(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)")
+-- -- end
+-- --
+-- -- -- the lpeg way is slower on 8 digits, but faster on 4 digits, some 7.5%
+-- -- -- on
+-- --
+-- -- for i=1,1000000 do
+-- -- local a,b,c,d,e,f,g,h = number.toset(12345678)
+-- -- local a,b,c,d = number.toset(1234)
+-- -- local a,b,c = number.toset(123)
+-- -- local a,b,c = number.toset("123")
+-- -- end
+--
+-- local one = lpeg.C(1-lpeg.S('')/tonumber)^1
+--
+-- function number.toset(n)
+-- return lpegmatch(one,tostring(n))
+-- end
+--
+-- -- function number.bits(n,zero)
+-- -- local t, i = { }, (zero and 0) or 1
+-- -- while n > 0 do
+-- -- local m = n % 2
+-- -- if m > 0 then
+-- -- insert(t,1,i)
+-- -- end
+-- -- n = floor(n/2)
+-- -- i = i + 1
+-- -- end
+-- -- return t
+-- -- end
+-- --
+-- -- -- a bit faster
+--
+-- local function bits(n,i,...)
+-- if n > 0 then
+-- local m = n % 2
+-- local n = floor(n/2)
+-- if m > 0 then
+-- return bits(n, i+1, i, ...)
+-- else
+-- return bits(n, i+1, ...)
+-- end
+-- else
+-- return ...
+-- end
+-- end
+--
+-- function number.bits(n)
+-- return { bits(n,1) }
+-- end
+
+function number.bytetodecimal(b)
+ local d = floor(b * 100 / 255 + 0.5)
+ if d > 100 then
+ return 100
+ elseif d < -100 then
+ return -100
+ else
+ return d
+ end
+end
+
+function number.decimaltobyte(d)
+ local b = floor(d * 255 / 100 + 0.5)
+ if b > 255 then
+ return 255
+ elseif b < -255 then
+ return -255
+ else
+ return b
+ end
+end
+
+function number.idiv(i,d)
+ return floor(i/d) -- i//d in 5.3
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-os.lua b/macros/luatex/generic/lualibs/lualibs-os.lua
new file mode 100644
index 0000000000..aa04e254df
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-os.lua
@@ -0,0 +1,655 @@
+if not modules then modules = { } end modules ['l-os'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This file deals with some operating system issues. Please don't bother me
+-- with the pros and cons of operating systems as they all have their flaws
+-- and benefits. Bashing one of them won't help solving problems and fixing
+-- bugs faster and is a waste of time and energy.
+--
+-- path separators: / or \ ... we can use / everywhere
+-- suffixes : dll so exe <none> ... no big deal
+-- quotes : we can use "" in most cases
+-- expansion : unless "" are used * might give side effects
+-- piping/threads : somewhat different for each os
+-- locations : specific user file locations and settings can change over time
+--
+-- os.type : windows | unix (new, we already guessed os.platform)
+-- os.name : windows | msdos | linux | macosx | solaris | .. | generic (new)
+-- os.platform : extended os.name with architecture
+
+-- os.sleep() => socket.sleep()
+-- math.randomseed(tonumber(string.sub(string.reverse(tostring(math.floor(socket.gettime()*10000))),1,6)))
+
+local os = os
+local date, time = os.date, os.time
+local find, format, gsub, upper, gmatch = string.find, string.format, string.gsub, string.upper, string.gmatch
+local concat = table.concat
+local random, ceil, randomseed = math.random, math.ceil, math.randomseed
+local rawget, rawset, type, getmetatable, setmetatable, tonumber, tostring = rawget, rawset, type, getmetatable, setmetatable, tonumber, tostring
+
+-- This check needs to happen real early on. Todo: we can pick it up from the commandline
+-- if we pass --binpath= (which is useful anyway)
+
+do
+ local selfdir = os.selfdir
+ if selfdir == "" then
+ selfdir = nil
+ end
+ if not selfdir then
+ -- We need a fallback plan so let's see what we get.
+ if arg then
+ -- passed by mtx-context ... saves network access
+ for i=1,#arg do
+ local a = arg[i]
+ if find(a,"^%-%-[c:]*texmfbinpath=") then
+ selfdir = gsub(a,"^.-=","")
+ break
+ end
+ end
+ end
+ if not selfdir then
+ selfdir = os.selfbin or "luatex"
+ if find(selfdir,"[/\\]") then
+ selfdir = gsub(selfdir,"[/\\][^/\\]*$","")
+ elseif os.getenv then
+ local path = os.getenv("PATH")
+ local name = gsub(selfdir,"^.*[/\\][^/\\]","")
+ local patt = "[^:]+"
+ if os.type == "windows" then
+ patt = "[^;]+"
+ name = name .. ".exe"
+ end
+ local isfile
+ if lfs then
+ -- we're okay as lfs is assumed present
+ local attributes = lfs.attributes
+ isfile = function(name)
+ local a = attributes(name,"mode")
+ return a == "file" or a == "link" or nil
+ end
+ else
+ -- we're not okay and much will not work as we miss lfs
+ local open = io.open
+ isfile = function(name)
+ local f = open(name)
+ if f then
+ f:close()
+ return true
+ end
+ end
+ end
+ for p in gmatch(path,patt) do
+ -- possible speedup: there must be tex in 'p'
+ if isfile(p .. "/" .. name) then
+ selfdir = p
+ break
+ end
+ end
+ end
+ end
+ -- let's hope we're okay now
+ os.selfdir = selfdir or "."
+ end
+end
+-- print(os.selfdir) os.exit()
+
+-- The following code permits traversing the environment table, at least in luatex. Internally all
+-- environment names are uppercase.
+
+-- The randomseed in Lua is not that random, although this depends on the operating system as well
+-- as the binary (Luatex is normally okay). But to be sure we set the seed anyway. It will be better
+-- in Lua 5.4 (according to the announcements.)
+
+math.initialseed = tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
+
+randomseed(math.initialseed)
+
+if not os.__getenv__ then
+
+ os.__getenv__ = os.getenv
+ os.__setenv__ = os.setenv
+
+ if os.env then
+
+ local osgetenv = os.getenv
+ local ossetenv = os.setenv
+ local osenv = os.env local _ = osenv.PATH -- initialize the table
+
+ function os.setenv(k,v)
+ if v == nil then
+ v = ""
+ end
+ local K = upper(k)
+ osenv[K] = v
+ if type(v) == "table" then
+ v = concat(v,";") -- path
+ end
+ ossetenv(K,v)
+ end
+
+ function os.getenv(k)
+ local K = upper(k)
+ local v = osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
+ if v == "" then
+ return nil
+ else
+ return v
+ end
+ end
+
+ else
+
+ local ossetenv = os.setenv
+ local osgetenv = os.getenv
+ local osenv = { }
+
+ function os.setenv(k,v)
+ if v == nil then
+ v = ""
+ end
+ local K = upper(k)
+ osenv[K] = v
+ end
+
+ function os.getenv(k)
+ local K = upper(k)
+ local v = osenv[K] or osgetenv(K) or osgetenv(k)
+ if v == "" then
+ return nil
+ else
+ return v
+ end
+ end
+
+ local function __index(t,k)
+ return os.getenv(k)
+ end
+ local function __newindex(t,k,v)
+ os.setenv(k,v)
+ end
+
+ os.env = { }
+
+ setmetatable(os.env, { __index = __index, __newindex = __newindex } )
+
+ end
+
+end
+
+-- end of environment hack
+
+local execute = os.execute
+local iopopen = io.popen
+
+local function resultof(command)
+ local handle = iopopen(command,"r") -- already has flush
+ if handle then
+ local result = handle:read("*all") or ""
+ handle:close()
+ return result
+ else
+ return ""
+ end
+end
+
+os.resultof = resultof
+
+function os.pipeto(command)
+ return iopopen(command,"w") -- already has flush
+end
+
+if not io.fileseparator then
+ if find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator, io.pathseparator, os.type = "\\", ";", os.type or "windows"
+ else
+ io.fileseparator, io.pathseparator, os.type = "/" , ":", os.type or "unix"
+ end
+end
+
+os.type = os.type or (io.pathseparator == ";" and "windows") or "unix"
+os.name = os.name or (os.type == "windows" and "mswin" ) or "linux"
+
+if os.type == "windows" then
+ os.libsuffix, os.binsuffix, os.binsuffixes = 'dll', 'exe', { 'exe', 'cmd', 'bat' }
+else
+ os.libsuffix, os.binsuffix, os.binsuffixes = 'so', '', { '' }
+end
+
+local launchers = {
+ windows = "start %s",
+ macosx = "open %s",
+ unix = "xdg-open %s &> /dev/null &",
+}
+
+function os.launch(str)
+ local command = format(launchers[os.name] or launchers.unix,str)
+ -- todo: pcall
+-- print(command)
+ execute(command)
+end
+
+local gettimeofday = os.gettimeofday or os.clock
+os.gettimeofday = gettimeofday
+
+local startuptime = gettimeofday()
+
+function os.runtime()
+ return gettimeofday() - startuptime
+end
+
+-- print(os.gettimeofday()-os.time())
+-- os.sleep(1.234)
+-- print (">>",os.runtime())
+-- print(os.date("%H:%M:%S",os.gettimeofday()))
+-- print(os.date("%H:%M:%S",os.time()))
+
+-- no need for function anymore as we have more clever code and helpers now
+-- this metatable trickery might as well disappear
+
+local resolvers = os.resolvers or { }
+os.resolvers = resolvers
+
+setmetatable(os, { __index = function(t,k)
+ local r = resolvers[k]
+ return r and r(t,k) or nil -- no memoize
+end })
+
+-- we can use HOSTTYPE on some platforms
+
+local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or ""
+
+-- local function guess()
+-- local architecture = resultof("uname -m") or ""
+-- if architecture ~= "" then
+-- return architecture
+-- end
+-- architecture = os.getenv("HOSTTYPE") or ""
+-- if architecture ~= "" then
+-- return architecture
+-- end
+-- return resultof("echo $HOSTTYPE") or ""
+-- end
+
+-- os.bits = 32 | 64
+
+-- os.uname()
+-- sysname
+-- machine
+-- release
+-- version
+-- nodename
+
+if platform ~= "" then
+
+ os.platform = platform
+
+elseif os.type == "windows" then
+
+ -- we could set the variable directly, no function needed here
+
+ -- PROCESSOR_ARCHITECTURE : binary platform
+ -- PROCESSOR_ARCHITEW6432 : OS platform
+
+ -- mswin-64 is now win64
+
+ function resolvers.platform(t,k)
+ local architecture = os.getenv("PROCESSOR_ARCHITECTURE") or ""
+ local platform = ""
+ if find(architecture,"AMD64",1,true) then
+ platform = "win64"
+ else
+ platform = "mswin"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
+elseif name == "linux" then
+
+ function resolvers.platform(t,k)
+ -- we sometimes have HOSTTYPE set so let's check that first
+ local architecture = os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform = os.getenv("MTX_PLATFORM") or ""
+ local musl = find(os.selfdir or "","linuxmusl")
+ if platform ~= "" then
+ -- we're done
+ elseif find(architecture,"x86_64",1,true) then
+ platform = musl and "linuxmusl" or "linux-64"
+ elseif find(architecture,"ppc",1,true) then
+ platform = "linux-ppc"
+ else
+ platform = musl and "linuxmusl" or "linux"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
+elseif name == "macosx" then
+
+ --[[
+ Identifying the architecture of OSX is quite a mess and this
+ is the best we can come up with. For some reason $HOSTTYPE is
+ a kind of pseudo environment variable, not known to the current
+ environment. And yes, uname cannot be trusted either, so there
+ is a change that you end up with a 32 bit run on a 64 bit system.
+ Also, some proper 64 bit intel macs are too cheap (low-end) and
+ therefore not permitted to run the 64 bit kernel.
+ ]]--
+
+ function resolvers.platform(t,k)
+ -- local platform = ""
+ -- local architecture = os.getenv("HOSTTYPE") or ""
+ -- if architecture == "" then
+ -- architecture = resultof("echo $HOSTTYPE") or ""
+ -- end
+ local architecture = resultof("echo $HOSTTYPE") or ""
+ local platform = ""
+ if architecture == "" then
+ -- print("\nI have no clue what kind of OSX you're running so let's assume an 32 bit intel.\n")
+ platform = "osx-intel"
+ elseif find(architecture,"i386",1,true) then
+ platform = "osx-intel"
+ elseif find(architecture,"x86_64",1,true) then
+ platform = "osx-64"
+ else
+ platform = "osx-ppc"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
+elseif name == "sunos" then
+
+ function resolvers.platform(t,k)
+ local architecture = resultof("uname -m") or ""
+ local platform = ""
+ if find(architecture,"sparc",1,true) then
+ platform = "solaris-sparc"
+ else -- if architecture == 'i86pc'
+ platform = "solaris-intel"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
+elseif name == "freebsd" then
+
+ function resolvers.platform(t,k)
+ local architecture = resultof("uname -m") or ""
+ local platform = ""
+ if find(architecture,"amd64",1,true) then
+ platform = "freebsd-amd64"
+ else
+ platform = "freebsd"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
+elseif name == "kfreebsd" then
+
+ function resolvers.platform(t,k)
+ -- we sometimes have HOSTTYPE set so let's check that first
+ local architecture = os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform = ""
+ if find(architecture,"x86_64",1,true) then
+ platform = "kfreebsd-amd64"
+ else
+ platform = "kfreebsd-i386"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
+else
+
+ -- platform = "linux"
+ -- os.setenv("MTX_PLATFORM",platform)
+ -- os.platform = platform
+
+ function resolvers.platform(t,k)
+ local platform = "linux"
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
+end
+
+os.newline = name == "windows" and "\013\010" or "\010" -- crlf or lf
+
+function resolvers.bits(t,k)
+ local bits = find(os.platform,"64",1,true) and 64 or 32
+ os.bits = bits
+ return bits
+end
+
+-- beware, we set the randomseed
+
+-- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the
+-- version number as well as two reserved bits. All other bits are set using a random or pseudorandom
+-- data source. Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal
+-- digits x and hexadecimal digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479.
+--
+-- as we don't call this function too often there is not so much risk on repetition
+
+local t = { 8, 9, "a", "b" }
+
+function os.uuid()
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
+end
+
+local d
+
+function os.timezone(delta)
+ d = d or tonumber(tonumber(date("%H")-date("!%H")))
+ if delta then
+ if d > 0 then
+ return format("+%02i:00",d)
+ else
+ return format("-%02i:00",-d)
+ end
+ else
+ return 1
+ end
+end
+
+local timeformat = format("%%s%s",os.timezone(true))
+local dateformat = "!%Y-%m-%d %H:%M:%S"
+local lasttime = nil
+local lastdate = nil
+
+function os.fulltime(t,default)
+ t = t and tonumber(t) or 0
+ if t > 0 then
+ -- valid time
+ elseif default then
+ return default
+ else
+ t = time()
+ end
+ if t ~= lasttime then
+ lasttime = t
+ lastdate = format(timeformat,date(dateformat))
+ end
+ return lastdate
+end
+
+local dateformat = "%Y-%m-%d %H:%M:%S"
+local lasttime = nil
+local lastdate = nil
+
+function os.localtime(t,default)
+ t = t and tonumber(t) or 0
+ if t > 0 then
+ -- valid time
+ elseif default then
+ return default
+ else
+ t = time()
+ end
+ if t ~= lasttime then
+ lasttime = t
+ lastdate = date(dateformat,t)
+ end
+ return lastdate
+end
+
+function os.converttime(t,default)
+ local t = tonumber(t)
+ if t and t > 0 then
+ return date(dateformat,t)
+ else
+ return default or "-"
+ end
+end
+
+local memory = { }
+
+local function which(filename)
+ local fullname = memory[filename]
+ if fullname == nil then
+ local suffix = file.suffix(filename)
+ local suffixes = suffix == "" and os.binsuffixes or { suffix }
+ for directory in gmatch(os.getenv("PATH"),"[^" .. io.pathseparator .."]+") do
+ local df = file.join(directory,filename)
+ for i=1,#suffixes do
+ local dfs = file.addsuffix(df,suffixes[i])
+ if io.exists(dfs) then
+ fullname = dfs
+ break
+ end
+ end
+ end
+ if not fullname then
+ fullname = false
+ end
+ memory[filename] = fullname
+ end
+ return fullname
+end
+
+os.which = which
+os.where = which
+
+function os.today()
+ return date("!*t") -- table with values
+end
+
+function os.now()
+ return date("!%Y-%m-%d %H:%M:%S") -- 2011-12-04 14:59:12
+end
+
+-- if not os.sleep and socket then
+-- os.sleep = socket.sleep
+-- end
+
+if not os.sleep then
+ local socket = socket
+ function os.sleep(n)
+ if not socket then
+ -- so we delay ... if os.sleep is really needed then one should also
+ -- be sure that socket can be found
+ socket = require("socket")
+ end
+ socket.sleep(n)
+ end
+end
+
+-- print(os.which("inkscape.exe"))
+-- print(os.which("inkscape"))
+-- print(os.which("gs.exe"))
+-- print(os.which("ps2pdf"))
+
+-- These are moved from core-con.lua (as I needed them elsewhere).
+
+local function isleapyear(year) -- timed for bram's cs practicum
+ -- return (year % 400 == 0) or (year % 100 ~= 0 and year % 4 == 0) -- 3:4:1600:1900 = 9.9 : 8.2 : 5.0 : 6.8 (29.9)
+ return (year % 4 == 0) and (year % 100 ~= 0 or year % 400 == 0) -- 3:4:1600:1900 = 5.1 : 6.5 : 8.1 : 10.2 (29.9)
+ -- return (year % 4 == 0) and (year % 400 == 0 or year % 100 ~= 0) -- 3:4:1600:1900 = 5.2 : 8.5 : 6.8 : 10.1 (30.6)
+end
+
+os.isleapyear = isleapyear
+
+-- nicer:
+--
+-- local days = {
+-- [false] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+-- [true] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+-- }
+--
+-- local function nofdays(year,month)
+-- return days[isleapyear(year)][month]
+-- return month == 2 and isleapyear(year) and 29 or days[month]
+-- end
+--
+-- more efficient:
+
+local days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+
+local function nofdays(year,month)
+ if not month then
+ return isleapyear(year) and 365 or 364
+ else
+ return month == 2 and isleapyear(year) and 29 or days[month]
+ end
+end
+
+os.nofdays = nofdays
+
+function os.weekday(day,month,year)
+ return date("%w",time { year = year, month = month, day = day }) + 1
+end
+
+function os.validdate(year,month,day)
+ -- we assume that all three values are set
+ -- year is always ok, even if lua has a 1970 time limit
+ if month < 1 then
+ month = 1
+ elseif month > 12 then
+ month = 12
+ end
+ if day < 1 then
+ day = 1
+ else
+ local max = nofdays(year,month)
+ if day > max then
+ day = max
+ end
+ end
+ return year, month, day
+end
+
+local osexit = os.exit
+local exitcode = nil
+
+function os.setexitcode(code)
+ exitcode = code
+end
+
+function os.exit(c)
+ if exitcode ~= nil then
+ return osexit(exitcode)
+ end
+ if c ~= nil then
+ return osexit(c)
+ end
+ return osexit()
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-package.lua b/macros/luatex/generic/lualibs/lualibs-package.lua
new file mode 100644
index 0000000000..0dd71e5eca
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-package.lua
@@ -0,0 +1,400 @@
+if not modules then modules = { } end modules ['l-package'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- Code moved from data-lua and changed into a plug-in.
+
+-- We overload the regular loader. We do so because we operate mostly in
+-- tds and use our own loader code. Alternatively we could use a more
+-- extensive definition of package.path and package.cpath but even then
+-- we're not done. Also, we now have better tracing.
+--
+-- -- local mylib = require("libtest")
+-- -- local mysql = require("luasql.mysql")
+
+local type = type
+local gsub, format, find = string.gsub, string.format, string.find
+local insert, remove = table.insert, table.remove
+
+local P, S, Cs, lpegmatch = lpeg.P, lpeg.S, lpeg.Cs, lpeg.match
+
+local package = package
+local searchers = package.searchers or package.loaders
+
+-------.loaders = nil -- old stuff that we don't want
+-------.seeall = nil -- old stuff that we don't want
+
+-- dummies
+
+local filejoin = file and file.join or function(path,name) return path .. "/" .. name end
+local isreadable = file and file.is_readable or function(name) local f = io.open(name) if f then f:close() return true end end
+local addsuffix = file and file.addsuffix or function(name,suffix) return name .. "." .. suffix end
+
+-- local separator, concatinator, placeholder, pathofexecutable, ignorebefore = string.match(package.config,"(.-)\n(.-)\n(.-)\n(.-)\n(.-)\n")
+--
+-- local config = {
+-- separator = separator, -- \ or /
+-- concatinator = concatinator, -- ;
+-- placeholder = placeholder, -- ? becomes name
+-- pathofexecutable = pathofexecutable, -- ! becomes executables dir (on windows)
+-- ignorebefore = ignorebefore, -- - remove all before this when making lua_open
+-- }
+
+local function cleanpath(path) -- hm, don't we have a helper for this?
+ return path
+end
+
+local pattern = Cs((((1-S("\\/"))^0 * (S("\\/")^1/"/"))^0 * (P(".")^1/"/"+P(1))^1) * -1)
+
+local function lualibfile(name)
+ return lpegmatch(pattern,name) or name
+end
+
+local offset = luarocks and 1 or 0 -- todo: also check other extras
+
+local helpers = package.helpers or {
+ cleanpath = cleanpath,
+ lualibfile = lualibfile,
+ trace = false,
+ report = function(...) print(format(...)) end,
+ builtin = {
+ ["preload table"] = searchers[1+offset], -- special case, built-in libs
+ ["path specification"] = searchers[2+offset],
+ ["cpath specification"] = searchers[3+offset],
+ ["all in one fallback"] = searchers[4+offset], -- special case, combined libs
+ },
+ methods = {
+ },
+ sequence = {
+ "already loaded",
+ "preload table",
+ "qualified path", -- beware, lua itself doesn't handle qualified paths (prepends ./)
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
+ }
+}
+
+package.helpers = helpers
+
+local methods = helpers.methods
+local builtin = helpers.builtin
+
+-- extra tds/ctx paths ... a bit of overhead for efficient tracing
+
+local extraluapaths = { }
+local extralibpaths = { }
+local luapaths = nil -- delayed
+local libpaths = nil -- delayed
+local oldluapath = nil
+local oldlibpath = nil
+
+local nofextralua = -1
+local nofextralib = -1
+local nofpathlua = -1
+local nofpathlib = -1
+
+local function listpaths(what,paths)
+ local nofpaths = #paths
+ if nofpaths > 0 then
+ for i=1,nofpaths do
+ helpers.report("using %s path %i: %s",what,i,paths[i])
+ end
+ else
+ helpers.report("no %s paths defined",what)
+ end
+ return nofpaths
+end
+
+local function getextraluapaths()
+ if helpers.trace and #extraluapaths ~= nofextralua then
+ nofextralua = listpaths("extra lua",extraluapaths)
+ end
+ return extraluapaths
+end
+
+local function getextralibpaths()
+ if helpers.trace and #extralibpaths ~= nofextralib then
+ nofextralib = listpaths("extra lib",extralibpaths)
+ end
+ return extralibpaths
+end
+
+local function getluapaths()
+ local luapath = package.path or ""
+ if oldluapath ~= luapath then
+ luapaths = file.splitpath(luapath,";")
+ oldluapath = luapath
+ nofpathlua = -1
+ end
+ if helpers.trace and #luapaths ~= nofpathlua then
+ nofpathlua = listpaths("builtin lua",luapaths)
+ end
+ return luapaths
+end
+
+local function getlibpaths()
+ local libpath = package.cpath or ""
+ if oldlibpath ~= libpath then
+ libpaths = file.splitpath(libpath,";")
+ oldlibpath = libpath
+ nofpathlib = -1
+ end
+ if helpers.trace and #libpaths ~= nofpathlib then
+ nofpathlib = listpaths("builtin lib",libpaths)
+ end
+ return libpaths
+end
+
+package.luapaths = getluapaths
+package.libpaths = getlibpaths
+package.extraluapaths = getextraluapaths
+package.extralibpaths = getextralibpaths
+
+local hashes = {
+ lua = { },
+ lib = { },
+}
+
+local function registerpath(tag,what,target,...)
+ local pathlist = { ... }
+ local cleanpath = helpers.cleanpath
+ local trace = helpers.trace
+ local report = helpers.report
+ local hash = hashes[what]
+ --
+ local function add(path)
+ local path = cleanpath(path)
+ if not hash[path] then
+ target[#target+1] = path
+ hash[path] = true
+ if trace then
+ report("registered %s path %s: %s",tag,#target,path)
+ end
+ else
+ if trace then
+ report("duplicate %s path: %s",tag,path)
+ end
+ end
+ end
+ --
+ for p=1,#pathlist do
+ local path = pathlist[p]
+ if type(path) == "table" then
+ for i=1,#path do
+ add(path[i])
+ end
+ else
+ add(path)
+ end
+ end
+end
+
+local function pushpath(tag,what,target,path)
+ local path = helpers.cleanpath(path)
+ insert(target,1,path)
+ if helpers.trace then
+ helpers.report("pushing %s path in front: %s",tag,path)
+ end
+end
+
+local function poppath(tag,what,target)
+ local path = remove(target,1)
+ if helpers.trace then
+ if path then
+ helpers.report("popping %s path from front: %s",tag,path)
+ else
+ helpers.report("no %s path to pop",tag)
+ end
+ end
+end
+
+helpers.registerpath = registerpath
+
+function package.extraluapath(...)
+ registerpath("extra lua","lua",extraluapaths,...)
+end
+function package.pushluapath(path)
+ pushpath("extra lua","lua",extraluapaths,path)
+end
+function package.popluapath()
+ poppath("extra lua","lua",extraluapaths)
+end
+
+function package.extralibpath(...)
+ registerpath("extra lib","lib",extralibpaths,...)
+end
+function package.pushlibpath(path)
+ pushpath("extra lib","lib",extralibpaths,path)
+end
+function package.poplibpath()
+ poppath("extra lib","lua",extralibpaths)
+end
+
+-- lib loader (used elsewhere)
+
+local function loadedaslib(resolved,rawname) -- todo: strip all before first -
+ local base = gsub(rawname,"%.","_")
+ -- so, we can do a require("foo/bar") and initialize bar
+ -- local base = gsub(file.basename(rawname),"%.","_")
+ local init = "luaopen_" .. gsub(base,"%.","_")
+ if helpers.trace then
+ helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+ end
+ return package.loadlib(resolved,init)
+end
+
+helpers.loadedaslib = loadedaslib
+
+-- wrapped and new loaders
+
+local function loadedbypath(name,rawname,paths,islib,what)
+ local trace = helpers.trace
+ for p=1,#paths do
+ local path = paths[p]
+ local resolved = filejoin(path,name)
+ if trace then
+ helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
+ end
+ if isreadable(resolved) then
+ if trace then
+ helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
+ end
+ end
+end
+
+helpers.loadedbypath = loadedbypath
+
+local function loadedbyname(name,rawname)
+ if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
+ local trace=helpers.trace
+ if trace then
+ helpers.report("qualified name, identifying '%s'",what,name)
+ end
+ if isreadable(name) then
+ if trace then
+ helpers.report("qualified name, '%s' found",what,name)
+ end
+ return loadfile(name)
+ end
+ end
+end
+
+helpers.loadedbyname = loadedbyname
+
+methods["already loaded"] = function(name)
+ return package.loaded[name]
+end
+
+methods["preload table"] = function(name)
+ return builtin["preload table"](name)
+end
+
+methods["qualified path"]=function(name)
+ return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
+end
+
+methods["lua extra list"] = function(name)
+ return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
+end
+
+methods["lib extra list"] = function(name)
+ return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true, "lib")
+end
+
+methods["path specification"] = function(name)
+ getluapaths() -- triggers list building and tracing
+ return builtin["path specification"](name)
+end
+
+methods["cpath specification"] = function(name)
+ getlibpaths() -- triggers list building and tracing
+ return builtin["cpath specification"](name)
+end
+
+methods["all in one fallback"] = function(name)
+ return builtin["all in one fallback"](name)
+end
+
+methods["not loaded"] = function(name)
+ if helpers.trace then
+ helpers.report("unable to locate '%s'",name or "?")
+ end
+ return nil
+end
+
+local level = 0
+local used = { }
+
+helpers.traceused = false
+
+function helpers.loaded(name)
+ local sequence = helpers.sequence
+ level = level + 1
+ for i=1,#sequence do
+ local method = sequence[i]
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
+ end
+ local result, rest = methods[method](name)
+ if type(result) == "function" then
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
+ end
+ if helpers.traceused then
+ used[#used+1] = { level = level, name = name }
+ end
+ level = level - 1
+ return result, rest
+ end
+ end
+ -- safeguard, we never come here
+ level = level - 1
+ return nil
+end
+
+function helpers.showused()
+ local n = #used
+ if n > 0 then
+ helpers.report("%s libraries loaded:",n)
+ helpers.report()
+ for i=1,n do
+ local u = used[i]
+ helpers.report("%i %a",u.level,u.name)
+ end
+ helpers.report()
+ end
+end
+
+function helpers.unload(name)
+ if helpers.trace then
+ if package.loaded[name] then
+ helpers.report("unloading, name '%s', %s",name,"done")
+ else
+ helpers.report("unloading, name '%s', %s",name,"not loaded")
+ end
+ end
+ package.loaded[name] = nil
+end
+
+-- overloading require does not work out well so we need to push it in
+-- front ..
+
+table.insert(searchers,1,helpers.loaded)
+
+if context then
+ package.path = ""
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-set.lua b/macros/luatex/generic/lualibs/lualibs-set.lua
new file mode 100644
index 0000000000..2370f0139f
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-set.lua
@@ -0,0 +1,87 @@
+if not modules then modules = { } end modules ['l-set'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This will become obsolete when we have the bitset library embedded.
+
+set = set or { }
+
+local nums = { }
+local tabs = { }
+local concat = table.concat
+local next, type = next, type
+
+set.create = table.tohash
+
+function set.tonumber(t)
+ if next(t) then
+ local s = ""
+ -- we could save mem by sorting, but it slows down
+ for k, v in next, t do
+ if v then
+ -- why bother about the leading space
+ s = s .. " " .. k
+ end
+ end
+ local n = nums[s]
+ if not n then
+ n = #tabs + 1
+ tabs[n] = t
+ nums[s] = n
+ end
+ return n
+ else
+ return 0
+ end
+end
+
+function set.totable(n)
+ if n == 0 then
+ return { }
+ else
+ return tabs[n] or { }
+ end
+end
+
+function set.tolist(n)
+ if n == 0 or not tabs[n] then
+ return ""
+ else
+ local t, n = { }, 0
+ for k, v in next, tabs[n] do
+ if v then
+ n = n + 1
+ t[n] = k
+ end
+ end
+ return concat(t," ")
+ end
+end
+
+function set.contains(n,s)
+ if type(n) == "table" then
+ return n[s]
+ elseif n == 0 then
+ return false
+ else
+ local t = tabs[n]
+ return t and t[s]
+ end
+end
+
+--~ local c = set.create{'aap','noot','mies'}
+--~ local s = set.tonumber(c)
+--~ local t = set.totable(s)
+--~ print(t['aap'])
+--~ local c = set.create{'zus','wim','jet'}
+--~ local s = set.tonumber(c)
+--~ local t = set.totable(s)
+--~ print(t['aap'])
+--~ print(t['jet'])
+--~ print(set.contains(t,'jet'))
+--~ print(set.contains(t,'aap'))
+
diff --git a/macros/luatex/generic/lualibs/lualibs-string.lua b/macros/luatex/generic/lualibs/lualibs-string.lua
new file mode 100644
index 0000000000..1dee85e289
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-string.lua
@@ -0,0 +1,244 @@
+if not modules then modules = { } end modules ['l-string'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local string = string
+local sub, gmatch, format, char, byte, rep, lower = string.sub, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower
+local lpegmatch, patterns = lpeg.match, lpeg.patterns
+local P, S, C, Ct, Cc, Cs = lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cs
+
+-- Some functions are already defined in l-lpeg and maybe some from here will
+-- move there (unless we also expose caches).
+
+-- if not string.split then
+--
+-- function string.split(str,pattern)
+-- local t = { }
+-- if str ~= "" then
+-- local n = 1
+-- for s in gmatch(str..pattern,"(.-)"..pattern) do
+-- t[n] = s
+-- n = n + 1
+-- end
+-- end
+-- return t
+-- end
+--
+-- end
+
+-- function string.unquoted(str)
+-- return (gsub(str,"^([\"\'])(.*)%1$","%2")) -- interesting pattern
+-- end
+
+local unquoted = patterns.squote * C(patterns.nosquote) * patterns.squote
+ + patterns.dquote * C(patterns.nodquote) * patterns.dquote
+
+function string.unquoted(str)
+ return lpegmatch(unquoted,str) or str
+end
+
+-- print(string.unquoted("test"))
+-- print(string.unquoted([["t\"est"]]))
+-- print(string.unquoted([["t\"est"x]]))
+-- print(string.unquoted("\'test\'"))
+-- print(string.unquoted('"test"'))
+-- print(string.unquoted('"test"'))
+
+function string.quoted(str)
+ return format("%q",str) -- always double quote
+end
+
+function string.count(str,pattern) -- variant 3
+ local n = 0
+ for _ in gmatch(str,pattern) do -- not for utf
+ n = n + 1
+ end
+ return n
+end
+
+function string.limit(str,n,sentinel) -- not utf proof
+ if #str > n then
+ sentinel = sentinel or "..."
+ return sub(str,1,(n-#sentinel)) .. sentinel
+ else
+ return str
+ end
+end
+
+local stripper = patterns.stripper
+local fullstripper = patterns.fullstripper
+local collapser = patterns.collapser
+local nospacer = patterns.nospacer
+local longtostring = patterns.longtostring
+
+function string.strip(str)
+ return str and lpegmatch(stripper,str) or ""
+end
+
+function string.fullstrip(str)
+ return str and lpegmatch(fullstripper,str) or ""
+end
+
+function string.collapsespaces(str)
+ return str and lpegmatch(collapser,str) or ""
+end
+
+function string.nospaces(str)
+ return str and lpegmatch(nospacer,str) or ""
+end
+
+function string.longtostring(str)
+ return str and lpegmatch(longtostring,str) or ""
+end
+
+-- function string.is_empty(str)
+-- return not find(str,"%S")
+-- end
+
+local pattern = P(" ")^0 * P(-1) -- maybe also newlines
+
+-- patterns.onlyspaces = pattern
+
+function string.is_empty(str)
+ if not str or str == "" then
+ return true
+ else
+ return lpegmatch(pattern,str) and true or false
+ end
+end
+
+-- if not string.escapedpattern then
+--
+-- local patterns_escapes = {
+-- ["%"] = "%%",
+-- ["."] = "%.",
+-- ["+"] = "%+", ["-"] = "%-", ["*"] = "%*",
+-- ["["] = "%[", ["]"] = "%]",
+-- ["("] = "%(", [")"] = "%)",
+-- -- ["{"] = "%{", ["}"] = "%}"
+-- -- ["^"] = "%^", ["$"] = "%$",
+-- }
+--
+-- local simple_escapes = {
+-- ["-"] = "%-",
+-- ["."] = "%.",
+-- ["?"] = ".",
+-- ["*"] = ".*",
+-- }
+--
+-- function string.escapedpattern(str,simple)
+-- return (gsub(str,".",simple and simple_escapes or patterns_escapes))
+-- end
+--
+-- function string.topattern(str,lowercase,strict)
+-- if str == "" then
+-- return ".*"
+-- else
+-- str = gsub(str,".",simple_escapes)
+-- if lowercase then
+-- str = lower(str)
+-- end
+-- if strict then
+-- return "^" .. str .. "$"
+-- else
+-- return str
+-- end
+-- end
+-- end
+--
+-- end
+
+--- needs checking
+
+local anything = patterns.anything
+local moreescapes = Cc("%") * S(".-+%?()[]*$^{}")
+local allescapes = Cc("%") * S(".-+%?()[]*") -- also {} and ^$ ?
+local someescapes = Cc("%") * S(".-+%()[]") -- also {} and ^$ ?
+local matchescapes = Cc(".") * S("*?") -- wildcard and single match
+
+local pattern_m = Cs ( ( moreescapes + anything )^0 )
+local pattern_a = Cs ( ( allescapes + anything )^0 )
+local pattern_b = Cs ( ( someescapes + matchescapes + anything )^0 )
+local pattern_c = Cs ( Cc("^") * ( someescapes + matchescapes + anything )^0 * Cc("$") )
+
+function string.escapedpattern(str,simple)
+ return lpegmatch(simple and pattern_b or pattern_a,str)
+end
+
+function string.topattern(str,lowercase,strict)
+ if str == "" or type(str) ~= "string" then
+ return ".*"
+ elseif strict == "all" then
+ str = lpegmatch(pattern_m,str)
+ elseif strict then
+ str = lpegmatch(pattern_c,str)
+ else
+ str = lpegmatch(pattern_b,str)
+ end
+ if lowercase then
+ return lower(str)
+ else
+ return str
+ end
+end
+
+-- print(string.escapedpattern("abc*234",true))
+-- print(string.escapedpattern("12+34*.tex",false))
+-- print(string.escapedpattern("12+34*.tex",true))
+-- print(string.topattern ("12+34*.tex",false,false))
+-- print(string.topattern ("12+34*.tex",false,true))
+
+function string.valid(str,default)
+ return (type(str) == "string" and str ~= "" and str) or default or nil
+end
+
+-- handy fallback
+
+string.itself = function(s) return s end
+
+-- also handy (see utf variant)
+
+local pattern_c = Ct( C(1) ^0) -- string and not utf !
+local pattern_b = Ct((C(1)/byte)^0)
+
+function string.totable(str,bytes)
+ return lpegmatch(bytes and pattern_b or pattern_c,str)
+end
+
+-- handy from within tex:
+
+local replacer = lpeg.replacer("@","%%") -- Watch the escaped % in lpeg!
+
+function string.tformat(fmt,...)
+ return format(lpegmatch(replacer,fmt),...)
+end
+
+-- obsolete names:
+
+string.quote = string.quoted
+string.unquote = string.unquoted
+
+-- new
+
+if not string.bytetable then -- used in font-cff.lua
+
+ local limit = 5000 -- we can go to 8000 in luajit and much higher in lua if needed
+
+ function string.bytetable(str) -- from a string
+ local n = #str
+ if n > limit then
+ local t = { byte(str,1,limit) }
+ for i=limit+1,n do
+ t[i] = byte(str,i)
+ end
+ return t
+ else
+ return { byte(str,1,n) }
+ end
+ end
+
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-table.lua b/macros/luatex/generic/lualibs/lualibs-table.lua
new file mode 100644
index 0000000000..cffdcc23e2
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-table.lua
@@ -0,0 +1,1471 @@
+if not modules then modules = { } end modules ['l-table'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type, next, tostring, tonumber, select = type, next, tostring, tonumber, select
+local table, string = table, string
+local concat, sort = table.concat, table.sort
+local format, lower, dump = string.format, string.lower, string.dump
+local getmetatable, setmetatable = getmetatable, setmetatable
+local lpegmatch, patterns = lpeg.match, lpeg.patterns
+local floor = math.floor
+
+-- extra functions, some might go (when not used)
+--
+-- we could serialize using %a but that won't work well is in the code we mostly use
+-- floats and as such we get unequality e.g. in version comparisons
+
+local stripper = patterns.stripper
+
+function table.getn(t)
+ return t and #t -- for very old times sake
+end
+
+function table.strip(tab)
+ local lst = { }
+ local l = 0
+ for i=1,#tab do
+ local s = lpegmatch(stripper,tab[i]) or ""
+ if s == "" then
+ -- skip this one
+ else
+ l = l + 1
+ lst[l] = s
+ end
+ end
+ return lst
+end
+
+function table.keys(t)
+ if t then
+ local keys = { }
+ local k = 0
+ for key in next, t do
+ k = k + 1
+ keys[k] = key
+ end
+ return keys
+ else
+ return { }
+ end
+end
+
+-- local function compare(a,b)
+-- local ta = type(a) -- needed, else 11 < 2
+-- local tb = type(b) -- needed, else 11 < 2
+-- if ta == tb and ta == "number" then
+-- return a < b
+-- else
+-- return tostring(a) < tostring(b) -- not that efficient
+-- end
+-- end
+
+-- local function compare(a,b)
+-- local ta = type(a) -- needed, else 11 < 2
+-- local tb = type(b) -- needed, else 11 < 2
+-- if ta == tb and (ta == "number" or ta == "string") then
+-- return a < b
+-- else
+-- return tostring(a) < tostring(b) -- not that efficient
+-- end
+-- end
+
+-- local function sortedkeys(tab)
+-- if tab then
+-- local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed
+-- for key in next, tab do
+-- s = s + 1
+-- srt[s] = key
+-- if category == 3 then
+-- -- no further check
+-- else
+-- local tkey = type(key)
+-- if tkey == "string" then
+-- category = (category == 2 and 3) or 1
+-- elseif tkey == "number" then
+-- category = (category == 1 and 3) or 2
+-- else
+-- category = 3
+-- end
+-- end
+-- end
+-- if category == 0 or category == 3 then
+-- sort(srt,compare)
+-- else
+-- sort(srt)
+-- end
+-- return srt
+-- else
+-- return { }
+-- end
+-- end
+
+-- local function compare(a,b)
+-- local ta = type(a) -- needed, else 11 < 2
+-- local tb = type(b) -- needed, else 11 < 2
+-- if ta == tb and (ta == "number" or ta == "string") then
+-- return a < b
+-- else
+-- return tostring(a) < tostring(b) -- not that efficient
+-- end
+-- end
+
+-- local function compare(a,b)
+-- local ta = type(a) -- needed, else 11 < 2
+-- if ta == "number" or ta == "string" then
+-- local tb = type(b) -- needed, else 11 < 2
+-- if ta == tb then
+-- return a < b
+-- end
+-- end
+-- return tostring(a) < tostring(b) -- not that efficient
+-- end
+
+local function compare(a,b)
+ local ta = type(a) -- needed, else 11 < 2
+ if ta == "number" then
+ local tb = type(b) -- needed, else 11 < 2
+ if ta == tb then
+ return a < b
+ elseif tb == "string" then
+ return tostring(a) < b
+ end
+ elseif ta == "string" then
+ local tb = type(b) -- needed, else 11 < 2
+ if ta == tb then
+ return a < b
+ else
+ return a < tostring(b)
+ end
+ end
+ return tostring(a) < tostring(b) -- not that efficient
+end
+
+local function sortedkeys(tab)
+ if tab then
+ local srt = { }
+ local category = 0 -- 0=unknown 1=string, 2=number 3=mixed
+ local s = 0
+ for key in next, tab do
+ s = s + 1
+ srt[s] = key
+ if category ~= 3 then
+ local tkey = type(key)
+ if category == 1 then
+ if tkey ~= "string" then
+ category = 3
+ end
+ elseif category == 2 then
+ if tkey ~= "number" then
+ category = 3
+ end
+ else
+ if tkey == "string" then
+ category = 1
+ elseif tkey == "number" then
+ category = 2
+ else
+ category = 3
+ end
+ end
+ end
+ end
+ if s < 2 then
+ -- nothing to sort
+ elseif category == 3 then
+ sort(srt,compare)
+ else
+ sort(srt)
+ end
+ return srt
+ else
+ return { }
+ end
+end
+
+local function sortedhashonly(tab)
+ if tab then
+ local srt = { }
+ local s = 0
+ for key in next, tab do
+ if type(key) == "string" then
+ s = s + 1
+ srt[s] = key
+ end
+ end
+ if s > 1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return { }
+ end
+end
+
+local function sortedindexonly(tab)
+ if tab then
+ local srt = { }
+ local s = 0
+ for key in next, tab do
+ if type(key) == "number" then
+ s = s + 1
+ srt[s] = key
+ end
+ end
+ if s > 1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return { }
+ end
+end
+
+local function sortedhashkeys(tab,cmp) -- fast one
+ if tab then
+ local srt = { }
+ local s = 0
+ for key in next, tab do
+ if key then
+ s= s + 1
+ srt[s] = key
+ end
+ end
+ if s > 1 then
+ sort(srt,cmp)
+ end
+ return srt
+ else
+ return { }
+ end
+end
+
+function table.allkeys(t)
+ local keys = { }
+ for k, v in next, t do
+ for k in next, v do
+ keys[k] = true
+ end
+ end
+ return sortedkeys(keys)
+end
+
+table.sortedkeys = sortedkeys
+table.sortedhashonly = sortedhashonly
+table.sortedindexonly = sortedindexonly
+table.sortedhashkeys = sortedhashkeys
+
+local function nothing() end
+
+local function sortedhash(t,cmp)
+ if t then
+ local s
+ if cmp then
+ -- it would be nice if the sort function would accept a third argument (or nicer, an optional first)
+ s = sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s = sortedkeys(t) -- the robust one
+ end
+ local m = #s
+ if m == 1 then
+ return next, t
+ elseif m > 0 then
+ local n = 0
+ return function()
+ if n < m then
+ n = n + 1
+ local k = s[n]
+ return k, t[k]
+ end
+ end
+ end
+ end
+ return nothing
+end
+
+table.sortedhash = sortedhash
+table.sortedpairs = sortedhash -- obsolete
+
+function table.append(t,list)
+ local n = #t
+ for i=1,#list do
+ n = n + 1
+ t[n] = list[i]
+ end
+ return t
+end
+
+function table.prepend(t, list)
+ local nl = #list
+ local nt = nl + #t
+ for i=#t,1,-1 do
+ t[nt] = t[i]
+ nt = nt - 1
+ end
+ for i=1,#list do
+ t[i] = list[i]
+ end
+ return t
+end
+
+-- function table.merge(t, ...) -- first one is target
+-- t = t or { }
+-- local lst = { ... }
+-- for i=1,#lst do
+-- for k, v in next, lst[i] do
+-- t[k] = v
+-- end
+-- end
+-- return t
+-- end
+
+function table.merge(t, ...) -- first one is target
+ if not t then
+ t = { }
+ end
+ for i=1,select("#",...) do
+ for k, v in next, (select(i,...)) do
+ t[k] = v
+ end
+ end
+ return t
+end
+
+-- function table.merged(...)
+-- local tmp, lst = { }, { ... }
+-- for i=1,#lst do
+-- for k, v in next, lst[i] do
+-- tmp[k] = v
+-- end
+-- end
+-- return tmp
+-- end
+
+function table.merged(...)
+ local t = { }
+ for i=1,select("#",...) do
+ for k, v in next, (select(i,...)) do
+ t[k] = v
+ end
+ end
+ return t
+end
+
+-- function table.imerge(t, ...)
+-- local lst, nt = { ... }, #t
+-- for i=1,#lst do
+-- local nst = lst[i]
+-- for j=1,#nst do
+-- nt = nt + 1
+-- t[nt] = nst[j]
+-- end
+-- end
+-- return t
+-- end
+
+function table.imerge(t, ...)
+ local nt = #t
+ for i=1,select("#",...) do
+ local nst = select(i,...)
+ for j=1,#nst do
+ nt = nt + 1
+ t[nt] = nst[j]
+ end
+ end
+ return t
+end
+
+-- function table.imerged(...)
+-- local tmp, ntmp, lst = { }, 0, {...}
+-- for i=1,#lst do
+-- local nst = lst[i]
+-- for j=1,#nst do
+-- ntmp = ntmp + 1
+-- tmp[ntmp] = nst[j]
+-- end
+-- end
+-- return tmp
+-- end
+
+function table.imerged(...)
+ local tmp = { }
+ local ntmp = 0
+ for i=1,select("#",...) do
+ local nst = select(i,...)
+ for j=1,#nst do
+ ntmp = ntmp + 1
+ tmp[ntmp] = nst[j]
+ end
+ end
+ return tmp
+end
+
+local function fastcopy(old,metatabletoo) -- fast one
+ if old then
+ local new = { }
+ for k, v in next, old do
+ if type(v) == "table" then
+ new[k] = fastcopy(v,metatabletoo) -- was just table.copy
+ else
+ new[k] = v
+ end
+ end
+ if metatabletoo then
+ -- optional second arg
+ local mt = getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ end
+ return new
+ else
+ return { }
+ end
+end
+
+-- todo : copy without metatable
+
+local function copy(t,tables) -- taken from lua wiki, slightly adapted
+ if not tables then
+ tables = { }
+ end
+ local tcopy = { }
+ if not tables[t] then
+ tables[t] = tcopy
+ end
+ for i,v in next, t do -- brrr, what happens with sparse indexed
+ if type(i) == "table" then
+ if tables[i] then
+ i = tables[i]
+ else
+ i = copy(i,tables)
+ end
+ end
+ if type(v) ~= "table" then
+ tcopy[i] = v
+ elseif tables[v] then
+ tcopy[i] = tables[v]
+ else
+ tcopy[i] = copy(v,tables)
+ end
+ end
+ local mt = getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
+end
+
+table.fastcopy = fastcopy
+table.copy = copy
+
+function table.derive(parent) -- for the moment not public
+ local child = { }
+ if parent then
+ setmetatable(child,{ __index = parent })
+ end
+ return child
+end
+
+function table.tohash(t,value)
+ local h = { }
+ if t then
+ if value == nil then value = true end
+ for _, v in next, t do
+ h[v] = value
+ end
+ end
+ return h
+end
+
+function table.fromhash(t)
+ local hsh = { }
+ local h = 0
+ for k, v in next, t do
+ if v then
+ h = h + 1
+ hsh[h] = k
+ end
+ end
+ return hsh
+end
+
+local noquotes, hexify, handle, compact, inline, functions, metacheck
+
+local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
+ 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if',
+ 'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while',
+ 'NaN', 'goto',
+}
+
+-- local function is_simple_table(t)
+-- if #t > 0 then
+-- local n = 0
+-- for _,v in next, t do
+-- n = n + 1
+-- end
+-- if n == #t then
+-- local tt, nt = { }, 0
+-- for i=1,#t do
+-- local v = t[i]
+-- local tv = type(v)
+-- if tv == "number" then
+-- nt = nt + 1
+-- if hexify then
+-- tt[nt] = format("0x%X",v)
+-- else
+-- tt[nt] = tostring(v) -- tostring not needed
+-- end
+-- elseif tv == "string" then
+-- nt = nt + 1
+-- tt[nt] = format("%q",v)
+-- elseif tv == "boolean" then
+-- nt = nt + 1
+-- tt[nt] = v and "true" or "false"
+-- else
+-- return nil
+-- end
+-- end
+-- return tt
+-- end
+-- end
+-- return nil
+-- end
+
+-- local function is_simple_table(t)
+-- local nt = #t
+-- if nt > 0 then
+-- local n = 0
+-- for _,v in next, t do
+-- n = n + 1
+-- -- if type(v) == "table" then
+-- -- return nil
+-- -- end
+-- end
+-- if n == nt then
+-- local tt = { }
+-- for i=1,nt do
+-- local v = t[i]
+-- local tv = type(v)
+-- if tv == "number" then
+-- if hexify then
+-- tt[i] = format("0x%X",v)
+-- else
+-- tt[i] = tostring(v) -- tostring not needed
+-- end
+-- elseif tv == "string" then
+-- tt[i] = format("%q",v)
+-- elseif tv == "boolean" then
+-- tt[i] = v and "true" or "false"
+-- else
+-- return nil
+-- end
+-- end
+-- return tt
+-- end
+-- end
+-- return nil
+-- end
+
+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
+ for _, v in next, t do
+ n = n + 1
+ if type(v) == "table" then
+ return nil
+ end
+ end
+ -- local haszero = t[0]
+ local haszero = rawget(t,0) -- don't trigger meta
+ if n == nt then
+ local tt = { }
+ for i=1,nt do
+ local v = t[i]
+ local tv = type(v)
+ if tv == "number" then
+ -- tt[i] = v -- not needed tostring(v)
+ if hexify then
+ tt[i] = format("0x%X",v)
+ else
+ tt[i] = v -- not needed tostring(v)
+ end
+ elseif tv == "string" then
+ tt[i] = format("%q",v) -- f_string(v)
+ elseif tv == "boolean" then
+ tt[i] = v and "true" or "false"
+ else
+ return nil
+ end
+ end
+ return tt
+ elseif haszero and (n == nt + 1) then
+ local tt = { }
+ for i=0,nt do
+ local v = t[i]
+ local tv = type(v)
+ if tv == "number" then
+ -- tt[i+1] = v -- not needed tostring(v)
+ if hexify then
+ tt[i+1] = format("0x%X",v)
+ else
+ tt[i+1] = v -- not needed tostring(v)
+ end
+ elseif tv == "string" then
+ tt[i+1] = format("%q",v) -- f_string(v)
+ elseif tv == "boolean" then
+ tt[i+1] = v and "true" or "false"
+ else
+ return nil
+ end
+ end
+ tt[1] = "[0] = " .. tt[1]
+ return tt
+ end
+ end
+ return nil
+end
+
+table.is_simple_table = is_simple_table
+
+-- Because this is a core function of mkiv I moved some function calls
+-- inline.
+--
+-- twice as fast in a test:
+--
+-- local propername = lpeg.P(lpeg.R("AZ","az","__") * lpeg.R("09","AZ","az", "__")^0 * lpeg.P(-1) )
+
+-- problem: there no good number_to_string converter with the best resolution
+
+-- probably using .. is faster than format
+-- maybe split in a few cases (yes/no hexify)
+
+-- todo: %g faster on numbers than %s
+
+-- we can speed this up with repeaters and formatters but we haven't defined them
+-- yet
+
+local propername = patterns.propername -- was find(name,"^%a[%w%_]*$")
+
+local function dummy() end
+
+local function do_serialize(root,name,depth,level,indexed)
+ if level > 0 then
+ depth = depth .. " "
+ if indexed then
+ handle(format("%s{",depth))
+ else
+ local tn = type(name)
+ if tn == "number" then
+ if hexify then
+ handle(format("%s[0x%X]={",depth,name))
+ else
+ handle(format("%s[%s]={",depth,name))
+ end
+ elseif tn == "string" then
+ if noquotes and not reserved[name] and lpegmatch(propername,name) then
+ handle(format("%s%s={",depth,name))
+ else
+ handle(format("%s[%q]={",depth,name))
+ end
+ elseif tn == "boolean" then
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
+ else
+ handle(format("%s{",depth))
+ end
+ end
+ end
+ -- we could check for k (index) being number (cardinal)
+ if root and next(root) ~= nil then
+ local first = nil
+ local last = 0
+ if compact then
+ last = #root
+ for k=1,last do
+ -- if root[k] == nil then
+ if rawget(root,k) == nil then
+ last = k - 1
+ break
+ end
+ end
+ if last > 0 then
+ first = 1
+ end
+ end
+ local sk = sortedkeys(root)
+ for i=1,#sk do
+ local k = sk[i]
+ local v = root[k]
+ local tv = type(v)
+ local tk = type(k)
+ if compact and first and tk == "number" and k >= first and k <= last then
+ if tv == "number" then
+ if hexify then
+ handle(format("%s 0x%X,",depth,v))
+ else
+ handle(format("%s %s,",depth,v)) -- %.99g
+ end
+ elseif tv == "string" then
+ handle(format("%s %q,",depth,v))
+ elseif tv == "table" then
+ if next(v) == nil then
+ handle(format("%s {},",depth))
+ elseif inline then -- and #t > 0
+ local st = is_simple_table(v,hexify)
+ if st then
+ handle(format("%s { %s },",depth,concat(st,", ")))
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ elseif tv == "boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv == "function" then
+ if functions then
+ handle(format('%s load(%q),',depth,dump(v))) -- maybe strip
+ else
+ handle(format('%s "function",',depth))
+ end
+ else
+ handle(format("%s %q,",depth,tostring(v)))
+ end
+ elseif k == "__p__" then -- parent
+ if false then
+ handle(format("%s __p__=nil,",depth))
+ end
+ elseif tv == "number" then
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
+ end
+ elseif tk == "boolean" then
+ if hexify then
+ handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ else
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) -- %.99g
+ end
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ if hexify then
+ handle(format("%s %s=0x%X,",depth,k,v))
+ else
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
+ end
+ else
+ if hexify then
+ handle(format("%s [%q]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
+ end
+ end
+ elseif tv == "string" then
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,v))
+ else
+ handle(format("%s [%s]=%q,",depth,k,v))
+ end
+ elseif tk == "boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,v))
+ else
+ handle(format("%s [%q]=%q,",depth,k,v))
+ end
+ elseif tv == "table" then
+ if next(v) == nil then
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]={},",depth,k))
+ else
+ handle(format("%s [%s]={},",depth,k))
+ end
+ elseif tk == "boolean" then
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={},",depth,k))
+ else
+ handle(format("%s [%q]={},",depth,k))
+ end
+ elseif inline then
+ local st = is_simple_table(v,hexify)
+ if st then
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+ end
+ elseif tk == "boolean" then
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
+ elseif tv == "boolean" then
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tk == "boolean" then
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tv == "function" then
+ if functions then
+ local getinfo = debug and debug.getinfo
+ if getinfo then
+ local f = getinfo(v).what == "C" and dump(dummy) or dump(v) -- maybe strip
+ -- local f = getinfo(v).what == "C" and dump(function(...) return v(...) end) or dump(v) -- maybe strip
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%s]=load(%q),",depth,k,f))
+ end
+ elseif tk == "boolean" then
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%q]=load(%q),",depth,k,f))
+ end
+ end
+ end
+ else
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+ end
+ elseif tk == "boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
+ end
+ end
+ end
+ end
+ if level > 0 then
+ handle(format("%s},",depth))
+ end
+end
+
+-- replacing handle by a direct t[#t+1] = ... (plus test) is not much
+-- faster (0.03 on 1.00 for zapfino.tma)
+
+local function serialize(_handle,root,name,specification) -- handle wins
+ local tname = type(name)
+ if type(specification) == "table" then
+ noquotes = specification.noquotes
+ hexify = specification.hexify
+ handle = _handle or specification.handle or print
+ functions = specification.functions
+ compact = specification.compact
+ inline = specification.inline and compact
+ metacheck = specification.metacheck
+ if functions == nil then
+ functions = true
+ end
+ if compact == nil then
+ compact = true
+ end
+ if inline == nil then
+ inline = compact
+ end
+ if metacheck == nil then
+ metacheck = true
+ end
+ else
+ noquotes = false
+ hexify = false
+ handle = _handle or print
+ compact = true
+ inline = true
+ functions = true
+ metacheck = true
+ end
+ if tname == "string" then
+ if name == "return" then
+ handle("return {")
+ else
+ handle(name .. "={")
+ end
+ elseif tname == "number" then
+ if hexify then
+ handle(format("[0x%X]={",name))
+ else
+ handle("[" .. name .. "]={")
+ end
+ elseif tname == "boolean" then
+ if name then
+ handle("return {")
+ else
+ handle("{")
+ end
+ else
+ handle("t={")
+ end
+ if root then
+ -- The dummy access will initialize a table that has a delayed initialization
+ -- using a metatable. (maybe explicitly test for metatable). This can crash on
+ -- metatables that check the index against a number.
+ if metacheck and getmetatable(root) then
+ local dummy = root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_ = nil
+ end
+ -- Let's forget about empty tables.
+ if next(root) ~= nil then
+ do_serialize(root,name,"",0)
+ end
+ end
+ handle("}")
+end
+
+-- A version with formatters is some 20% faster than using format (because formatters are
+-- much faster) but of course, inlining the format using .. is then again faster .. anyway,
+-- as we do some pretty printing as well there is not that much to gain unless we make a
+-- 'fast' ugly variant as well. But, we would have to move the formatter to l-string then.
+
+-- name:
+--
+-- true : return { }
+-- false : { }
+-- nil : t = { }
+-- string : string = { }
+-- "return" : return { }
+-- number : [number] = { }
+
+function table.serialize(root,name,specification)
+ local t = { }
+ local n = 0
+ local function flush(s)
+ n = n + 1
+ t[n] = s
+ end
+ serialize(flush,root,name,specification)
+ return concat(t,"\n")
+end
+
+-- local a = { e = { 1,2,3,4,5,6}, a = 1, b = 2, c = "ccc", d = { a = 1, b = 2, c = "ccc", d = { a = 1, b = 2, c = "ccc" } } }
+-- local t = os.clock()
+-- for i=1,10000 do
+-- table.serialize(a)
+-- end
+-- print(os.clock()-t,table.serialize(a))
+
+table.tohandle = serialize
+
+local maxtab = 2*1024
+
+function table.tofile(filename,root,name,specification)
+ local f = io.open(filename,'w')
+ if f then
+ if maxtab > 1 then
+ local t = { }
+ local n = 0
+ local function flush(s)
+ n = n + 1
+ t[n] = s
+ if n > maxtab then
+ f:write(concat(t,"\n"),"\n") -- hm, write(sometable) should be nice
+ t = { } -- we could recycle t if needed
+ n = 0
+ end
+ end
+ serialize(flush,root,name,specification)
+ f:write(concat(t,"\n"),"\n")
+ else
+ local function flush(s)
+ f:write(s,"\n")
+ end
+ serialize(flush,root,name,specification)
+ end
+ f:close()
+ io.flush()
+ end
+end
+
+local function flattened(t,f,depth) -- also handles { nil, 1, nil, 2 }
+ if f == nil then
+ f = { }
+ depth = 0xFFFF
+ elseif tonumber(f) then
+ -- assume that only two arguments are given
+ depth = f
+ f = { }
+ elseif not depth then
+ depth = 0xFFFF
+ end
+ for k, v in next, t do
+ if type(k) ~= "number" then
+ if depth > 0 and type(v) == "table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1] = v
+ end
+ end
+ end
+ for k=1,#t do
+ local v = t[k]
+ if depth > 0 and type(v) == "table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1] = v
+ end
+ end
+ return f
+end
+
+table.flattened = flattened
+
+local function collapsed(t,f,h)
+ if f == nil then
+ f = { }
+ h = { }
+ end
+ for k=1,#t do
+ local v = t[k]
+ if type(v) == "table" then
+ collapsed(v,f,h)
+ elseif not h[v] then
+ f[#f+1] = v
+ h[v] = true
+ end
+ end
+ return f
+end
+
+local function collapsedhash(t,h)
+ if h == nil then
+ h = { }
+ end
+ for k=1,#t do
+ local v = t[k]
+ if type(v) == "table" then
+ collapsedhash(v,h)
+ else
+ h[v] = true
+ end
+ end
+ return h
+end
+
+table.collapsed = collapsed -- 20% faster than unique(collapsed(t))
+table.collapsedhash = collapsedhash
+
+local function unnest(t,f) -- only used in mk, for old times sake
+ if not f then -- and only relevant for token lists
+ f = { } -- this one can become obsolete
+ end
+ for i=1,#t do
+ local v = t[i]
+ if type(v) == "table" then
+ if type(v[1]) == "table" then
+ unnest(v,f)
+ else
+ f[#f+1] = v
+ end
+ else
+ f[#f+1] = v
+ end
+ end
+ return f
+end
+
+function table.unnest(t) -- bad name
+ return unnest(t)
+end
+
+local function are_equal(a,b,n,m) -- indexed
+ if a == b then
+ return true
+ elseif a and b and #a == #b then
+ if not n then
+ n = 1
+ end
+ if not m then
+ m = #a
+ end
+ for i=n,m do
+ local ai, bi = a[i], b[i]
+ if ai==bi then
+ -- same
+ elseif type(ai) == "table" and type(bi) == "table" then
+ if not are_equal(ai,bi) then
+ return false
+ end
+ else
+ return false
+ end
+ end
+ return true
+ else
+ return false
+ end
+end
+
+local function identical(a,b) -- assumes same structure
+ if a ~= b then
+ for ka, va in next, a do
+ local vb = b[ka]
+ if va == vb then
+ -- same
+ elseif type(va) == "table" and type(vb) == "table" then
+ if not identical(va,vb) then
+ return false
+ end
+ else
+ return false
+ end
+ end
+ end
+ return true
+end
+
+table.identical = identical
+table.are_equal = are_equal
+
+local function sparse(old,nest,keeptables)
+ local new = { }
+ for k, v in next, old do
+ if not (v == "" or v == false) then
+ if nest and type(v) == "table" then
+ v = sparse(v,nest)
+ if keeptables or next(v) ~= nil then
+ new[k] = v
+ end
+ else
+ new[k] = v
+ end
+ end
+ end
+ return new
+end
+
+table.sparse = sparse
+
+function table.compact(t)
+ return sparse(t,true,true)
+end
+
+function table.contains(t, v)
+ if t then
+ for i=1, #t do
+ if t[i] == v then
+ return i
+ end
+ end
+ end
+ return false
+end
+
+function table.count(t)
+ local n = 0
+ for k, v in next, t do
+ n = n + 1
+ end
+ return n
+end
+
+function table.swapped(t,s) -- hash, we need to make sure we don't mess up next
+ local n = { }
+ if s then
+ for k, v in next, s do
+ n[k] = v
+ end
+ end
+ for k, v in next, t do
+ n[v] = k
+ end
+ return n
+end
+
+function table.hashed(t) -- list, add hash to index (save because we are not yet mixed
+ for i=1,#t do
+ t[t[i]] = i
+ end
+ return t
+end
+
+function table.mirrored(t) -- hash, we need to make sure we don't mess up next
+ local n = { }
+ for k, v in next, t do
+ n[v] = k
+ n[k] = v
+ end
+ return n
+end
+
+function table.reversed(t)
+ if t then
+ local tt = { }
+ local tn = #t
+ if tn > 0 then
+ local ttn = 0
+ for i=tn,1,-1 do
+ ttn = ttn + 1
+ tt[ttn] = t[i]
+ end
+ end
+ return tt
+ end
+end
+
+function table.reverse(t) -- check with 5.3 ?
+ if t then
+ local n = #t
+ local m = n + 1
+ for i=1,floor(n/2) do -- maybe just n//2
+ local j = m - i
+ t[i], t[j] = t[j], t[i]
+ end
+ return t
+ end
+end
+
+-- This one is for really simple cases where need a hash from a table.
+
+local function sequenced(t,sep,simple)
+ if not t then
+ return ""
+ elseif type(t) ~= "table" then
+ return t -- handy fallback
+ end
+ local n = #t
+ local s = { }
+ if n > 0 then
+ -- indexed
+ for i=1,n do
+ local v = t[i]
+ if type(v) == "table" then
+ s[i] = "{" .. sequenced(v,sep,simple) .. "}"
+ else
+ s[i] = tostring(t[i])
+ end
+ end
+ else
+ -- hashed
+ n = 0
+ for k, v in sortedhash(t) do
+ if simple then
+ if v == true then
+ n = n + 1
+ s[n] = k
+ elseif v and v~= "" then
+ n = n + 1
+ if type(v) == "table" then
+ s[n] = k .. "={" .. sequenced(v,sep,simple) .. "}"
+ else
+ s[n] = k .. "=" .. tostring(v)
+ end
+ end
+ else
+ n = n + 1
+ if type(v) == "table" then
+ s[n] = k .. "={" .. sequenced(v,sep,simple) .. "}"
+ else
+ s[n] = k .. "=" .. tostring(v)
+ end
+ end
+ end
+ end
+ if sep == true then
+ return "{ " .. concat(s,", ") .. " }"
+ else
+ return concat(s,sep or " | ")
+ end
+end
+
+table.sequenced = sequenced
+
+function table.print(t,...)
+ if type(t) ~= "table" then
+ print(tostring(t))
+ else
+ serialize(print,t,...)
+ end
+end
+
+if setinspector then
+ setinspector("table",function(v) if type(v) == "table" then serialize(print,v,"table") return true end end)
+end
+
+-- -- -- obsolete but we keep them for a while and might comment them later -- -- --
+
+-- roughly: copy-loop : unpack : sub == 0.9 : 0.4 : 0.45 (so in critical apps, use unpack)
+
+function table.sub(t,i,j)
+ return { unpack(t,i,j) }
+end
+
+-- slower than #t on indexed tables (#t only returns the size of the numerically indexed slice)
+
+function table.is_empty(t)
+ return not t or next(t) == nil
+end
+
+function table.has_one_entry(t)
+ return t and next(t,next(t)) == nil
+end
+
+-- new (rather basic, not indexed and nested)
+
+function table.loweredkeys(t) -- maybe utf
+ local l = { }
+ for k, v in next, t do
+ l[lower(k)] = v
+ end
+ return l
+end
+
+-- new, might move (maybe duplicate)
+
+function table.unique(old)
+ local hash = { }
+ local new = { }
+ local n = 0
+ for i=1,#old do
+ local oi = old[i]
+ if not hash[oi] then
+ n = n + 1
+ new[n] = oi
+ hash[oi] = true
+ end
+ end
+ return new
+end
+
+function table.sorted(t,...)
+ sort(t,...)
+ return t -- still sorts in-place
+end
+
+--
+
+function table.values(t,s) -- optional sort flag
+ if t then
+ local values = { }
+ local keys = { }
+ local v = 0
+ for key, value in next, t do
+ if not keys[value] then
+ v = v + 1
+ values[v] = value
+ keys[k] = key
+ end
+ end
+ if s then
+ sort(values)
+ end
+ return values
+ else
+ return { }
+ end
+end
+
+-- maybe this will move to util-tab.lua
+
+-- for k, v in table.filtered(t,pattern) do ... end
+-- for k, v in table.filtered(t,pattern,true) do ... end
+-- for k, v in table.filtered(t,pattern,true,cmp) do ... end
+
+function table.filtered(t,pattern,sort,cmp)
+ if t and type(pattern) == "string" then
+ if sort then
+ local s
+ if cmp then
+ -- it would be nice if the sort function would accept a third argument (or nicer, an optional first)
+ s = sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s = sortedkeys(t) -- the robust one
+ end
+ local n = 0
+ local m = #s
+ local function kv(s)
+ while n < m do
+ n = n + 1
+ local k = s[n]
+ if find(k,pattern) then
+ return k, t[k]
+ end
+ end
+ end
+ return kv, s
+ else
+ local n = next(t)
+ local function iterator()
+ while n ~= nil do
+ local k = n
+ n = next(t,k)
+ if find(k,pattern) then
+ return k, t[k]
+ end
+ end
+ end
+ return iterator, t
+ end
+ else
+ return nothing
+ end
+end
+
+-- lua 5.3:
+
+if not table.move then
+
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1 ~= a2 then
+ for i=f,e do
+ a2[t] = a1[i]
+ t = t + 1
+ end
+ return a2
+ else
+ t = t + e - f
+ for i=e,f,-1 do
+ a1[t] = a1[i]
+ t = t - 1
+ end
+ return a1
+ end
+ end
+
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-trac-inf.lua b/macros/luatex/generic/lualibs/lualibs-trac-inf.lua
new file mode 100644
index 0000000000..24ebc52499
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-trac-inf.lua
@@ -0,0 +1,313 @@
+if not modules then modules = { } end modules ['trac-inf'] = {
+ version = 1.001,
+ comment = "companion to trac-inf.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- As we want to protect the global tables, we no longer store the timing
+-- in the tables themselves but in a hidden timers table so that we don't
+-- get warnings about assignments. This is more efficient than using rawset
+-- and rawget.
+
+local type, tonumber, select = type, tonumber, select
+local format, lower, find = string.format, string.lower, string.find
+local concat = table.concat
+local clock = os.gettimeofday or os.clock -- should go in environment
+
+local setmetatableindex = table.setmetatableindex
+local serialize = table.serialize
+local formatters = string.formatters
+
+statistics = statistics or { }
+local statistics = statistics
+
+statistics.enable = true
+statistics.threshold = 0.01
+
+local statusinfo, n, registered, timers = { }, 0, { }, { }
+
+setmetatableindex(timers,function(t,k)
+ local v = { timing = 0, loadtime = 0, offset = 0 }
+ t[k] = v
+ return v
+end)
+
+local function hastiming(instance)
+ return instance and timers[instance]
+end
+
+local function resettiming(instance)
+ timers[instance or "notimer"] = { timing = 0, loadtime = 0, offset = 0 }
+end
+
+local ticks = clock
+local seconds = function(n) return n or 0 end
+
+-- if FFISUPPORTED and ffi and os.type == "windows" then
+--
+-- local okay, kernel = pcall(ffi.load,"kernel32")
+--
+-- if kernel then
+--
+-- local tonumber = ffi.number or tonumber
+--
+-- ffi.cdef[[
+-- int QueryPerformanceFrequency(int64_t *lpFrequency);
+-- int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+-- ]]
+--
+-- local target = ffi.new("__int64[1]")
+--
+-- ticks = function()
+-- if kernel.QueryPerformanceCounter(target) == 1 then
+-- return tonumber(target[0])
+-- else
+-- return 0
+-- end
+-- end
+--
+-- local target = ffi.new("__int64[1]")
+--
+-- seconds = function(ticks)
+-- if kernel.QueryPerformanceFrequency(target) == 1 then
+-- return ticks / tonumber(target[0])
+-- else
+-- return 0
+-- end
+-- end
+--
+-- end
+--
+-- end
+
+local function starttiming(instance,reset)
+ local timer = timers[instance or "notimer"]
+ local it = timer.timing
+ if reset then
+ it = 0
+ timer.loadtime = 0
+ end
+ if it == 0 then
+ timer.starttime = ticks()
+ if not timer.loadtime then
+ timer.loadtime = 0
+ end
+ end
+ timer.timing = it + 1
+end
+
+local function stoptiming(instance)
+ local timer = timers[instance or "notimer"]
+ local it = timer.timing
+ if it > 1 then
+ timer.timing = it - 1
+ else
+ local starttime = timer.starttime
+ if starttime and starttime > 0 then
+ local stoptime = ticks()
+ local loadtime = stoptime - starttime
+ timer.stoptime = stoptime
+ timer.loadtime = timer.loadtime + loadtime
+ timer.timing = 0
+ timer.starttime = 0
+ return loadtime
+ end
+ end
+ return 0
+end
+
+local function benchmarktimer(instance)
+ local timer = timers[instance or "notimer"]
+ local it = timer.timing
+ if it > 1 then
+ timer.timing = it - 1
+ else
+ local starttime = timer.starttime
+ if starttime and starttime > 0 then
+ timer.offset = ticks() - starttime
+ else
+ timer.offset = 0
+ end
+ end
+end
+
+local function elapsed(instance)
+ if type(instance) == "number" then
+ return instance
+ else
+ local timer = timers[instance or "notimer"]
+ return timer and seconds(timer.loadtime - 2*(timer.offset or 0)) or 0
+ end
+end
+
+local function currenttime(instance)
+ if type(instance) == "number" then
+ return instance
+ else
+ local timer = timers[instance or "notimer"]
+ local it = timer.timing
+ if it > 1 then
+ -- whatever
+ else
+ local starttime = timer.starttime
+ if starttime and starttime > 0 then
+ return seconds(timer.loadtime + ticks() - starttime - 2*(timer.offset or 0))
+ end
+ end
+ return 0
+ end
+end
+
+local function elapsedtime(instance)
+ return format("%0.3f",elapsed(instance))
+end
+
+local function elapsedindeed(instance)
+ return elapsed(instance) > statistics.threshold
+end
+
+local function elapsedseconds(instance,rest) -- returns nil if 0 seconds
+ if elapsedindeed(instance) then
+ return format("%0.3f seconds %s", elapsed(instance),rest or "")
+ end
+end
+
+statistics.hastiming = hastiming
+statistics.resettiming = resettiming
+statistics.starttiming = starttiming
+statistics.stoptiming = stoptiming
+statistics.currenttime = currenttime
+statistics.elapsed = elapsed
+statistics.elapsedtime = elapsedtime
+statistics.elapsedindeed = elapsedindeed
+statistics.elapsedseconds = elapsedseconds
+statistics.benchmarktimer = benchmarktimer
+
+-- general function .. we might split this module
+
+function statistics.register(tag,fnc)
+ if statistics.enable and type(fnc) == "function" then
+ local rt = registered[tag] or (#statusinfo + 1)
+ statusinfo[rt] = { tag, fnc }
+ registered[tag] = rt
+ if #tag > n then n = #tag end
+ end
+end
+
+local report = logs.reporter("mkiv lua stats")
+
+function statistics.show()
+ if statistics.enable then
+ -- this code will move
+ local register = statistics.register
+ register("used platform", function()
+ return format("%s, type: %s, binary subtree: %s",
+ os.platform or "unknown",os.type or "unknown", environment.texos or "unknown")
+ end)
+ -- register("luatex banner", function()
+ -- return lower(status.banner)
+ -- end)
+ if LUATEXENGINE == "luametatex" then
+ register("used engine", function()
+ return format("%s version %s, functionality level %s, format id %s",
+ LUATEXENGINE, LUATEXVERSION, LUATEXFUNCTIONALITY, LUATEXFORMATID)
+ end)
+ else
+ register("used engine", function()
+ return format("%s version %s with functionality level %s, banner: %s",
+ LUATEXENGINE, LUATEXVERSION, LUATEXFUNCTIONALITY, lower(status.banner))
+ end)
+ end
+ register("control sequences", function()
+ return format("%s of %s + %s", status.cs_count, status.hash_size,status.hash_extra)
+ end)
+ register("callbacks", statistics.callbacks)
+ if TEXENGINE == "luajittex" and JITSUPPORTED then
+ local jitstatus = jit.status
+ if jitstatus then
+ local jitstatus = { jitstatus() }
+ if jitstatus[1] then
+ register("luajit options", concat(jitstatus," ",2))
+ end
+ end
+ end
+ -- so far
+ -- collectgarbage("collect")
+ register("lua properties",function()
+ local hashchar = tonumber(status.luatex_hashchars)
+ local mask = lua.mask or "ascii"
+ return format("engine: %s %s, used memory: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
+ jit and "luajit" or "lua",
+ LUAVERSION,
+ statistics.memused(),
+ hashchar and 2^hashchar or "unknown",
+ mask,
+ mask == "utf" and "τεχ" or "tex")
+ end)
+ register("runtime",statistics.runtime)
+ logs.newline() -- initial newline
+ for i=1,#statusinfo do
+ local s = statusinfo[i]
+ local r = s[2]()
+ if r then
+ report("%s: %s",s[1],r)
+ end
+ end
+ -- logs.newline() -- final newline
+ statistics.enable = false
+ end
+end
+
+function statistics.memused() -- no math.round yet -)
+ local round = math.round or math.floor
+ return format("%s MB, ctx: %s MB, max: %s MB)",
+ round(collectgarbage("count")/1000),
+ round(status.luastate_bytes/1000000),
+ status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"
+ )
+end
+
+starttiming(statistics)
+
+function statistics.formatruntime(runtime) -- indirect so it can be overloaded and
+ return format("%s seconds", runtime) -- indeed that happens in cure-uti.lua
+end
+
+function statistics.runtime()
+ stoptiming(statistics)
+ -- stoptiming(statistics) -- somehow we can start the timer twice, but where
+ local runtime = lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
+end
+
+local report = logs.reporter("system")
+
+function statistics.timed(action,all)
+ starttiming("run")
+ action()
+ stoptiming("run")
+ local runtime = tonumber(elapsedtime("run"))
+ if all then
+ local alltime = tonumber(lua.getruntime and lua.getruntime() or elapsedtime(statistics))
+ if alltime and alltime > 0 then
+ report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime)
+ return
+ end
+ end
+ report("total runtime: %0.3f seconds",runtime)
+end
+
+-- goodie
+
+function statistics.tracefunction(base,tag,...)
+ for i=1,select("#",...) do
+ local name = select(i,...)
+ local stat = { }
+ local func = base[name]
+ setmetatableindex(stat,function(t,k) t[k] = 0 return 0 end)
+ base[name] = function(n,k,v) stat[k] = stat[k] + 1 return func(n,k,v) end
+ statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
+ end
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-unicode.lua b/macros/luatex/generic/lualibs/lualibs-unicode.lua
new file mode 100644
index 0000000000..73d1eb7660
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-unicode.lua
@@ -0,0 +1,1405 @@
+if not modules then modules = { } end modules ['l-unicode'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- floor(b/256) => rshift(b, 8)
+-- floor(b/1024) => rshift(b,10)
+
+-- in lua 5.3:
+
+-- utf8.char(···) : concatinated
+-- utf8.charpatt : "[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
+-- utf8.codes(s) : for p, c in utf8.codes(s) do body end
+-- utf8.codepoint(s [, i [, j]])
+-- utf8.len(s [, i])
+-- utf8.offset(s, n [, i])
+
+-- todo: utf.sub replacement (used in syst-aux)
+-- we put these in the utf namespace:
+
+-- used : byte char len lower sub upper
+-- not used : dump find format gmatch gfind gsub match rep reverse
+
+-- utf = utf or (unicode and unicode.utf8) or { }
+
+-- not supported:
+--
+-- dump, find, format, gfind, gmatch, gsub, lower, match, rep, reverse, upper
+
+utf = utf or { }
+-- unicode = nil
+
+if not string.utfcharacters then
+
+ -- New: this gmatch hack is taken from the Lua 5.2 book. It's about two times slower
+ -- than the built-in string.utfcharacters.
+
+ local gmatch = string.gmatch
+
+ function string.characters(str)
+ return gmatch(str,".[\128-\191]*")
+ end
+
+
+end
+
+utf.characters = string.utfcharacters
+
+-- string.utfvalues
+-- string.utfcharacters
+-- string.characters
+-- string.characterpairs
+-- string.bytes
+-- string.bytepairs
+-- string.utflength
+-- string.utfvalues
+-- string.utfcharacters
+
+local type = type
+local char, byte, format, sub, gmatch = string.char, string.byte, string.format, string.sub, string.gmatch
+local concat = table.concat
+local P, C, R, Cs, Ct, Cmt, Cc, Carg, Cp = lpeg.P, lpeg.C, lpeg.R, lpeg.Cs, lpeg.Ct, lpeg.Cmt, lpeg.Cc, lpeg.Carg, lpeg.Cp
+
+local lpegmatch = lpeg.match
+local patterns = lpeg.patterns
+local tabletopattern = lpeg.utfchartabletopattern
+
+local bytepairs = string.bytepairs
+
+local finder = lpeg.finder
+local replacer = lpeg.replacer
+
+local p_utftype = patterns.utftype
+local p_utfstricttype = patterns.utfstricttype
+local p_utfoffset = patterns.utfoffset
+local p_utf8character = patterns.utf8character
+local p_utf8char = patterns.utf8char
+local p_utf8byte = patterns.utf8byte
+local p_utfbom = patterns.utfbom
+local p_newline = patterns.newline
+local p_whitespace = patterns.whitespace
+
+-- if not unicode then
+-- unicode = { utf = utf } -- for a while
+-- end
+
+if not utf.char then
+
+ utf.char = string.utfcharacter or (utf8 and utf8.char)
+
+ if not utf.char then
+
+ -- no multiples
+
+ local char = string.char
+
+ if bit32 then
+
+ local rshift = bit32.rshift
+
+ function utf.char(n)
+ if n < 0x80 then
+ -- 0aaaaaaa : 0x80
+ return char(n)
+ elseif n < 0x800 then
+ -- 110bbbaa : 0xC0 : n >> 6
+ -- 10aaaaaa : 0x80 : n & 0x3F
+ return char(
+ 0xC0 + rshift(n,6),
+ 0x80 + (n % 0x40)
+ )
+ elseif n < 0x10000 then
+ -- 1110bbbb : 0xE0 : n >> 12
+ -- 10bbbbaa : 0x80 : (n >> 6) & 0x3F
+ -- 10aaaaaa : 0x80 : n & 0x3F
+ return char(
+ 0xE0 + rshift(n,12),
+ 0x80 + (rshift(n,6) % 0x40),
+ 0x80 + (n % 0x40)
+ )
+ elseif n < 0x200000 then
+ -- 11110ccc : 0xF0 : n >> 18
+ -- 10ccbbbb : 0x80 : (n >> 12) & 0x3F
+ -- 10bbbbaa : 0x80 : (n >> 6) & 0x3F
+ -- 10aaaaaa : 0x80 : n & 0x3F
+ -- dddd : ccccc - 1
+ return char(
+ 0xF0 + rshift(n,18),
+ 0x80 + (rshift(n,12) % 0x40),
+ 0x80 + (rshift(n,6) % 0x40),
+ 0x80 + (n % 0x40)
+ )
+ else
+ return ""
+ end
+ end
+
+ else
+
+ local floor = math.floor
+
+ function utf.char(n)
+ if n < 0x80 then
+ return char(n)
+ elseif n < 0x800 then
+ return char(
+ 0xC0 + floor(n/0x40),
+ 0x80 + (n % 0x40)
+ )
+ elseif n < 0x10000 then
+ return char(
+ 0xE0 + floor(n/0x1000),
+ 0x80 + (floor(n/0x40) % 0x40),
+ 0x80 + (n % 0x40)
+ )
+ elseif n < 0x200000 then
+ return char(
+ 0xF0 + floor(n/0x40000),
+ 0x80 + (floor(n/0x1000) % 0x40),
+ 0x80 + (floor(n/0x40) % 0x40),
+ 0x80 + (n % 0x40)
+ )
+ else
+ return ""
+ end
+ end
+
+ end
+
+ end
+
+end
+
+if not utf.byte then
+
+ utf.byte = string.utfvalue or (utf8 and utf8.codepoint)
+
+ if not utf.byte then
+
+ function utf.byte(c)
+ return lpegmatch(p_utf8byte,c)
+ end
+
+ end
+
+end
+
+local utfchar, utfbyte = utf.char, utf.byte
+
+-- As we want to get rid of the (unmaintained) utf library we implement our own
+-- variants (in due time an independent module):
+
+function utf.filetype(data)
+ return data and lpegmatch(p_utftype,data) or "unknown"
+end
+
+local toentities = Cs (
+ (
+ patterns.utf8one
+ + (
+ patterns.utf8two
+ + patterns.utf8three
+ + patterns.utf8four
+ ) / function(s) local b = utfbyte(s) if b < 127 then return s else return format("&#%X;",b) end end
+ )^0
+)
+
+patterns.toentities = toentities
+
+function utf.toentities(str)
+ return lpegmatch(toentities,str)
+end
+
+-- local utfchr = { } -- 60K -> 2.638 M extra mem but currently not called that often (on latin)
+--
+-- setmetatable(utfchr, { __index = function(t,k) local v = utfchar(k) t[k] = v return v end } )
+--
+-- collectgarbage("collect")
+-- local u = collectgarbage("count")*1024
+-- local t = os.clock()
+-- for i=1,1000 do
+-- for i=1,600 do
+-- local a = utfchr[i]
+-- end
+-- end
+-- print(os.clock()-t,collectgarbage("count")*1024-u)
+
+-- collectgarbage("collect")
+-- local t = os.clock()
+-- for i=1,1000 do
+-- for i=1,600 do
+-- local a = utfchar(i)
+-- end
+-- end
+-- print(os.clock()-t,collectgarbage("count")*1024-u)
+
+-- local byte = string.byte
+-- local utfchar = utf.char
+
+local one = P(1)
+local two = C(1) * C(1)
+local four = C(R(utfchar(0xD8),utfchar(0xFF))) * C(1) * C(1) * C(1)
+
+local pattern = P("\254\255") * Cs( (
+ four / function(a,b,c,d)
+ local ab = 0xFF * byte(a) + byte(b)
+ local cd = 0xFF * byte(c) + byte(d)
+ return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
+ end
+ + two / function(a,b)
+ return utfchar(byte(a)*256 + byte(b))
+ end
+ + one
+ )^1 )
+ + P("\255\254") * Cs( (
+ four / function(b,a,d,c)
+ local ab = 0xFF * byte(a) + byte(b)
+ local cd = 0xFF * byte(c) + byte(d)
+ return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
+ end
+ + two / function(b,a)
+ return utfchar(byte(a)*256 + byte(b))
+ end
+ + one
+ )^1 )
+
+function string.toutf(s) -- in string namespace
+ return lpegmatch(pattern,s) or s -- todo: utf32
+end
+
+local validatedutf = Cs (
+ (
+ patterns.utf8one
+ + patterns.utf8two
+ + patterns.utf8three
+ + patterns.utf8four
+ + P(1) / "�"
+ )^0
+)
+
+patterns.validatedutf = validatedutf
+
+function utf.is_valid(str)
+ return type(str) == "string" and lpegmatch(validatedutf,str) or false
+end
+
+if not utf.len then
+
+ utf.len = string.utflength or (utf8 and utf8.len)
+
+ if not utf.len then
+
+ -- -- alternative 1: 0.77
+ --
+ -- local utfcharcounter = utfbom^-1 * Cs((p_utf8character/'!')^0)
+ --
+ -- function utf.len(str)
+ -- return #lpegmatch(utfcharcounter,str or "")
+ -- end
+ --
+ -- -- alternative 2: 1.70
+ --
+ -- local n = 0
+ --
+ -- local utfcharcounter = utfbom^-1 * (p_utf8character/function() n = n + 1 end)^0 -- slow
+ --
+ -- function utf.length(str)
+ -- n = 0
+ -- lpegmatch(utfcharcounter,str or "")
+ -- return n
+ -- end
+ --
+ -- -- alternative 3: 0.24 (native unicode.utf8.len: 0.047)
+
+ -- local n = 0
+ --
+ -- -- local utfcharcounter = lpeg.patterns.utfbom^-1 * P ( ( Cp() * (
+ -- -- patterns.utf8one ^1 * Cc(1)
+ -- -- + patterns.utf8two ^1 * Cc(2)
+ -- -- + patterns.utf8three^1 * Cc(3)
+ -- -- + patterns.utf8four ^1 * Cc(4) ) * Cp() / function(f,d,t) n = n + (t - f)/d end
+ -- -- )^0 ) -- just as many captures as below
+ --
+ -- -- local utfcharcounter = lpeg.patterns.utfbom^-1 * P ( (
+ -- -- (Cmt(patterns.utf8one ^1,function(_,_,s) n = n + #s return true end))
+ -- -- + (Cmt(patterns.utf8two ^1,function(_,_,s) n = n + #s/2 return true end))
+ -- -- + (Cmt(patterns.utf8three^1,function(_,_,s) n = n + #s/3 return true end))
+ -- -- + (Cmt(patterns.utf8four ^1,function(_,_,s) n = n + #s/4 return true end))
+ -- -- )^0 ) -- not interesting as it creates strings but sometimes faster
+ --
+ -- -- The best so far:
+ --
+ -- local utfcharcounter = utfbom^-1 * P ( (
+ -- Cp() * (patterns.utf8one )^1 * Cp() / function(f,t) n = n + t - f end
+ -- + Cp() * (patterns.utf8two )^1 * Cp() / function(f,t) n = n + (t - f)/2 end
+ -- + Cp() * (patterns.utf8three)^1 * Cp() / function(f,t) n = n + (t - f)/3 end
+ -- + Cp() * (patterns.utf8four )^1 * Cp() / function(f,t) n = n + (t - f)/4 end
+ -- )^0 )
+
+ -- function utf.len(str)
+ -- n = 0
+ -- lpegmatch(utfcharcounter,str or "")
+ -- return n
+ -- end
+
+ local n, f = 0, 1
+
+ local utfcharcounter = patterns.utfbom^-1 * Cmt (
+ Cc(1) * patterns.utf8one ^1
+ + Cc(2) * patterns.utf8two ^1
+ + Cc(3) * patterns.utf8three^1
+ + Cc(4) * patterns.utf8four ^1,
+ function(_,t,d) -- due to Cc no string captures, so faster
+ n = n + (t - f)/d
+ f = t
+ return true
+ end
+ )^0
+
+ function utf.len(str)
+ n, f = 0, 1
+ lpegmatch(utfcharcounter,str or "")
+ return n
+ end
+
+ -- -- these are quite a bit slower:
+
+ -- utfcharcounter = utfbom^-1 * (Cmt(P(1) * R("\128\191")^0, function() n = n + 1 return true end))^0 -- 50+ times slower
+ -- utfcharcounter = utfbom^-1 * (Cmt(P(1), function() n = n + 1 return true end) * R("\128\191")^0)^0 -- 50- times slower
+
+ end
+
+end
+
+utf.length = utf.len
+
+if not utf.sub then
+
+ -- inefficient as lpeg just copies ^n
+
+ -- local function sub(str,start,stop)
+ -- local pattern = p_utf8character^-(start-1) * C(p_utf8character^-(stop-start+1))
+ -- inspect(pattern)
+ -- return lpegmatch(pattern,str) or ""
+ -- end
+
+ -- local b, e, n, first, last = 0, 0, 0, 0, 0
+ --
+ -- local function slide(s,p)
+ -- n = n + 1
+ -- if n == first then
+ -- b = p
+ -- if not last then
+ -- return nil
+ -- end
+ -- end
+ -- if n == last then
+ -- e = p
+ -- return nil
+ -- else
+ -- return p
+ -- end
+ -- end
+ --
+ -- local pattern = Cmt(p_utf8character,slide)^0
+ --
+ -- function utf.sub(str,start,stop) -- todo: from the end
+ -- if not start then
+ -- return str
+ -- end
+ -- b, e, n, first, last = 0, 0, 0, start, stop
+ -- lpegmatch(pattern,str)
+ -- if not stop then
+ -- return sub(str,b)
+ -- else
+ -- return sub(str,b,e-1)
+ -- end
+ -- end
+
+ -- print(utf.sub("Hans Hagen is my name"))
+ -- print(utf.sub("Hans Hagen is my name",5))
+ -- print(utf.sub("Hans Hagen is my name",5,10))
+
+ local utflength = utf.length
+
+ -- also negative indices, upto 10 times slower than a c variant
+
+ local b, e, n, first, last = 0, 0, 0, 0, 0
+
+ local function slide_zero(s,p)
+ n = n + 1
+ if n >= last then
+ e = p - 1
+ else
+ return p
+ end
+ end
+
+ local function slide_one(s,p)
+ n = n + 1
+ if n == first then
+ b = p
+ end
+ if n >= last then
+ e = p - 1
+ else
+ return p
+ end
+ end
+
+ local function slide_two(s,p)
+ n = n + 1
+ if n == first then
+ b = p
+ else
+ return true
+ end
+ end
+
+ local pattern_zero = Cmt(p_utf8character,slide_zero)^0
+ local pattern_one = Cmt(p_utf8character,slide_one )^0
+ local pattern_two = Cmt(p_utf8character,slide_two )^0
+
+ local pattern_first = C(p_utf8character)
+
+ function utf.sub(str,start,stop)
+ if not start then
+ return str
+ end
+ if start == 0 then
+ start = 1
+ end
+ if not stop then
+ if start < 0 then
+ local l = utflength(str) -- we can inline this function if needed
+ start = l + start
+ else
+ start = start - 1
+ end
+ b, n, first = 0, 0, start
+ lpegmatch(pattern_two,str)
+ if n >= first then
+ return sub(str,b)
+ else
+ return ""
+ end
+ end
+ if start < 0 or stop < 0 then
+ local l = utf.length(str)
+ if start < 0 then
+ start = l + start
+ if start <= 0 then
+ start = 1
+ else
+ start = start + 1
+ end
+ end
+ if stop < 0 then
+ stop = l + stop
+ if stop == 0 then
+ stop = 1
+ else
+ stop = stop + 1
+ end
+ end
+ end
+ if start == 1 and stop == 1 then
+ return lpegmatch(pattern_first,str) or ""
+ elseif start > stop then
+ return ""
+ elseif start > 1 then
+ b, e, n, first, last = 0, 0, 0, start - 1, stop
+ lpegmatch(pattern_one,str)
+ if n >= first and e == 0 then
+ e = #str
+ end
+ return sub(str,b,e)
+ else
+ b, e, n, last = 1, 0, 0, stop
+ lpegmatch(pattern_zero,str)
+ if e == 0 then
+ e = #str
+ end
+ return sub(str,b,e)
+ end
+ end
+
+ -- local n = 100000
+ -- local str = string.rep("123456àáâãäå",100)
+ --
+ -- for i=-15,15,1 do
+ -- for j=-15,15,1 do
+ -- if utf.xsub(str,i,j) ~= utf.sub(str,i,j) then
+ -- print("error",i,j,"l>"..utf.xsub(str,i,j),"s>"..utf.sub(str,i,j))
+ -- end
+ -- end
+ -- if utf.xsub(str,i) ~= utf.sub(str,i) then
+ -- print("error",i,"l>"..utf.xsub(str,i),"s>"..utf.sub(str,i))
+ -- end
+ -- end
+
+ -- print(" 1, 7",utf.xsub(str, 1, 7),utf.sub(str, 1, 7))
+ -- print(" 0, 7",utf.xsub(str, 0, 7),utf.sub(str, 0, 7))
+ -- print(" 0, 9",utf.xsub(str, 0, 9),utf.sub(str, 0, 9))
+ -- print(" 4 ",utf.xsub(str, 4 ),utf.sub(str, 4 ))
+ -- print(" 0 ",utf.xsub(str, 0 ),utf.sub(str, 0 ))
+ -- print(" 0, 0",utf.xsub(str, 0, 0),utf.sub(str, 0, 0))
+ -- print(" 4, 4",utf.xsub(str, 4, 4),utf.sub(str, 4, 4))
+ -- print(" 4, 0",utf.xsub(str, 4, 0),utf.sub(str, 4, 0))
+ -- print("-3, 0",utf.xsub(str,-3, 0),utf.sub(str,-3, 0))
+ -- print(" 0,-3",utf.xsub(str, 0,-3),utf.sub(str, 0,-3))
+ -- print(" 5,-3",utf.xsub(str,-5,-3),utf.sub(str,-5,-3))
+ -- print("-3 ",utf.xsub(str,-3 ),utf.sub(str,-3 ))
+
+end
+
+-- a replacement for simple gsubs:
+
+-- function utf.remapper(mapping)
+-- local pattern = Cs((p_utf8character/mapping)^0)
+-- return function(str)
+-- if not str or str == "" then
+-- return ""
+-- else
+-- return lpegmatch(pattern,str)
+-- end
+-- end, pattern
+-- end
+
+function utf.remapper(mapping,option,action) -- static also returns a pattern
+ local variant = type(mapping)
+ if variant == "table" then
+ action = action or mapping
+ if option == "dynamic" then
+ local pattern = false
+ table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern = false end)
+ return function(str)
+ if not str or str == "" then
+ return ""
+ else
+ if not pattern then
+ pattern = Cs((tabletopattern(mapping)/action + p_utf8character)^0)
+ end
+ return lpegmatch(pattern,str)
+ end
+ end
+ elseif option == "pattern" then
+ return Cs((tabletopattern(mapping)/action + p_utf8character)^0)
+ -- elseif option == "static" then
+ else
+ local pattern = Cs((tabletopattern(mapping)/action + p_utf8character)^0)
+ return function(str)
+ if not str or str == "" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
+ end
+ end, pattern
+ end
+ elseif variant == "function" then
+ if option == "pattern" then
+ return Cs((p_utf8character/mapping + p_utf8character)^0)
+ else
+ local pattern = Cs((p_utf8character/mapping + p_utf8character)^0)
+ return function(str)
+ if not str or str == "" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
+ end
+ end, pattern
+ end
+ else
+ -- is actually an error
+ return function(str)
+ return str or ""
+ end
+ end
+end
+
+-- local remap = utf.remapper { a = 'd', b = "c", c = "b", d = "a" }
+-- print(remap("abcd 1234 abcd"))
+
+function utf.replacer(t) -- no precheck, always string builder
+ local r = replacer(t,false,false,true)
+ return function(str)
+ return lpegmatch(r,str)
+ end
+end
+
+function utf.subtituter(t) -- with precheck and no building if no match
+ local f = finder (t)
+ local r = replacer(t,false,false,true)
+ return function(str)
+ local i = lpegmatch(f,str)
+ if not i then
+ return str
+ elseif i > #str then
+ return str
+ else
+ -- return sub(str,1,i-2) .. lpegmatch(r,str,i-1) -- slower
+ return lpegmatch(r,str)
+ end
+ end
+end
+
+-- inspect(utf.split("a b c d"))
+-- inspect(utf.split("a b c d",true))
+
+local utflinesplitter = p_utfbom^-1 * lpeg.tsplitat(p_newline)
+local utfcharsplitter_ows = p_utfbom^-1 * Ct(C(p_utf8character)^0)
+local utfcharsplitter_iws = p_utfbom^-1 * Ct((p_whitespace^1 + C(p_utf8character))^0)
+local utfcharsplitter_raw = Ct(C(p_utf8character)^0)
+
+patterns.utflinesplitter = utflinesplitter
+
+function utf.splitlines(str)
+ return lpegmatch(utflinesplitter,str or "")
+end
+
+function utf.split(str,ignorewhitespace) -- new
+ if ignorewhitespace then
+ return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+ return lpegmatch(utfcharsplitter_ows,str or "")
+ end
+end
+
+function utf.totable(str) -- keeps bom
+ return lpegmatch(utfcharsplitter_raw,str)
+end
+
+-- 0 EF BB BF UTF-8
+-- 1 FF FE UTF-16-little-endian
+-- 2 FE FF UTF-16-big-endian
+-- 3 FF FE 00 00 UTF-32-little-endian
+-- 4 00 00 FE FF UTF-32-big-endian
+--
+-- \000 fails in <= 5.0 but is valid in >=5.1 where %z is depricated
+
+-- utf.name = {
+-- [0] = 'utf-8',
+-- [1] = 'utf-16-le',
+-- [2] = 'utf-16-be',
+-- [3] = 'utf-32-le',
+-- [4] = 'utf-32-be'
+-- }
+--
+-- function utf.magic(f)
+-- local str = f:read(4)
+-- if not str then
+-- f:seek('set')
+-- return 0
+-- -- elseif find(str,"^%z%z\254\255") then -- depricated
+-- -- elseif find(str,"^\000\000\254\255") then -- not permitted and bugged
+-- elseif find(str,"\000\000\254\255",1,true) then -- seems to work okay (TH)
+-- return 4
+-- -- elseif find(str,"^\255\254%z%z") then -- depricated
+-- -- elseif find(str,"^\255\254\000\000") then -- not permitted and bugged
+-- elseif find(str,"\255\254\000\000",1,true) then -- seems to work okay (TH)
+-- return 3
+-- elseif find(str,"^\254\255") then
+-- f:seek('set',2)
+-- return 2
+-- elseif find(str,"^\255\254") then
+-- f:seek('set',2)
+-- return 1
+-- elseif find(str,"^\239\187\191") then
+-- f:seek('set',3)
+-- return 0
+-- else
+-- f:seek('set')
+-- return 0
+-- end
+-- end
+
+function utf.magic(f) -- not used
+ local str = f:read(4) or ""
+ local off = lpegmatch(p_utfoffset,str)
+ if off < 4 then
+ f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
+end
+
+local utf16_to_utf8_be, utf16_to_utf8_le
+local utf32_to_utf8_be, utf32_to_utf8_le
+
+local utf_16_be_getbom = patterns.utfbom_16_be^-1
+local utf_16_le_getbom = patterns.utfbom_16_le^-1
+local utf_32_be_getbom = patterns.utfbom_32_be^-1
+local utf_32_le_getbom = patterns.utfbom_32_le^-1
+
+local utf_16_be_linesplitter = utf_16_be_getbom * lpeg.tsplitat(patterns.utf_16_be_nl)
+local utf_16_le_linesplitter = utf_16_le_getbom * lpeg.tsplitat(patterns.utf_16_le_nl)
+local utf_32_be_linesplitter = utf_32_be_getbom * lpeg.tsplitat(patterns.utf_32_be_nl)
+local utf_32_le_linesplitter = utf_32_le_getbom * lpeg.tsplitat(patterns.utf_32_le_nl)
+
+-- we have three possibilities: bytepairs (using tables), gmatch (using tables), gsub and
+-- lpeg. Bytepairs are the fastert but as soon as we need to remove bombs and so the gain
+-- is less due to more testing. Also, we seldom have to convert utf16 so we don't care to
+-- much about a few milliseconds more runtime. The lpeg variant is upto 20% slower but
+-- still pretty fast.
+--
+-- for historic resone we keep the bytepairs variants around .. beware they don't grab the
+-- bom like the lpegs do so they're not dropins in the functions that follow
+--
+-- utf16_to_utf8_be = function(s)
+-- if not s then
+-- return nil
+-- elseif s == "" then
+-- return ""
+-- end
+-- local result, r, more = { }, 0, 0
+-- for left, right in bytepairs(s) do
+-- if right then
+-- local now = 256*left + right
+-- if more > 0 then
+-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong
+-- more = 0
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- elseif now >= 0xD800 and now <= 0xDBFF then
+-- more = now
+-- else
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- end
+-- end
+-- end
+-- return concat(result)
+-- end
+--
+-- local utf16_to_utf8_be_t = function(t)
+-- if not t then
+-- return nil
+-- elseif type(t) == "string" then
+-- t = lpegmatch(utf_16_be_linesplitter,t)
+-- end
+-- local result = { } -- we reuse result
+-- for i=1,#t do
+-- local s = t[i]
+-- if s ~= "" then
+-- local r, more = 0, 0
+-- for left, right in bytepairs(s) do
+-- if right then
+-- local now = 256*left + right
+-- if more > 0 then
+-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000
+-- more = 0
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- elseif now >= 0xD800 and now <= 0xDBFF then
+-- more = now
+-- else
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- end
+-- end
+-- end
+-- t[i] = concat(result,"",1,r) -- we reused tmp, hence t
+-- end
+-- end
+-- return t
+-- end
+--
+-- utf16_to_utf8_le = function(s)
+-- if not s then
+-- return nil
+-- elseif s == "" then
+-- return ""
+-- end
+-- local result, r, more = { }, 0, 0
+-- for left, right in bytepairs(s) do
+-- if right then
+-- local now = 256*right + left
+-- if more > 0 then
+-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000
+-- more = 0
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- elseif now >= 0xD800 and now <= 0xDBFF then
+-- more = now
+-- else
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- end
+-- end
+-- end
+-- return concat(result)
+-- end
+--
+-- local utf16_to_utf8_le_t = function(t)
+-- if not t then
+-- return nil
+-- elseif type(t) == "string" then
+-- t = lpegmatch(utf_16_le_linesplitter,t)
+-- end
+-- local result = { } -- we reuse result
+-- for i=1,#t do
+-- local s = t[i]
+-- if s ~= "" then
+-- local r, more = 0, 0
+-- for left, right in bytepairs(s) do
+-- if right then
+-- local now = 256*right + left
+-- if more > 0 then
+-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000
+-- more = 0
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- elseif now >= 0xD800 and now <= 0xDBFF then
+-- more = now
+-- else
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- end
+-- end
+-- end
+-- t[i] = concat(result,"",1,r) -- we reused tmp, hence t
+-- end
+-- end
+-- return t
+-- end
+--
+-- local utf32_to_utf8_be_t = function(t)
+-- if not t then
+-- return nil
+-- elseif type(t) == "string" then
+-- t = lpegmatch(utflinesplitter,t)
+-- end
+-- local result = { } -- we reuse result
+-- for i=1,#t do
+-- local r, more = 0, -1
+-- for a,b in bytepairs(t[i]) do
+-- if a and b then
+-- if more < 0 then
+-- more = 256*256*256*a + 256*256*b
+-- else
+-- r = r + 1
+-- result[t] = utfchar(more + 256*a + b)
+-- more = -1
+-- end
+-- else
+-- break
+-- end
+-- end
+-- t[i] = concat(result,"",1,r)
+-- end
+-- return t
+-- end
+--
+-- local utf32_to_utf8_le_t = function(t)
+-- if not t then
+-- return nil
+-- elseif type(t) == "string" then
+-- t = lpegmatch(utflinesplitter,t)
+-- end
+-- local result = { } -- we reuse result
+-- for i=1,#t do
+-- local r, more = 0, -1
+-- for a,b in bytepairs(t[i]) do
+-- if a and b then
+-- if more < 0 then
+-- more = 256*b + a
+-- else
+-- r = r + 1
+-- result[t] = utfchar(more + 256*256*256*b + 256*256*a)
+-- more = -1
+-- end
+-- else
+-- break
+-- end
+-- end
+-- t[i] = concat(result,"",1,r)
+-- end
+-- return t
+-- end
+
+local more = 0
+
+local p_utf16_to_utf8_be = C(1) * C(1) /function(left,right)
+ local now = 256*byte(left) + byte(right)
+ if more > 0 then
+ now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000
+ more = 0
+ return utfchar(now)
+ elseif now >= 0xD800 and now <= 0xDBFF then
+ more = now
+ return "" -- else the c's end up in the stream
+ else
+ return utfchar(now)
+ end
+end
+
+local p_utf16_to_utf8_le = C(1) * C(1) /function(right,left)
+ local now = 256*byte(left) + byte(right)
+ if more > 0 then
+ now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000
+ more = 0
+ return utfchar(now)
+ elseif now >= 0xD800 and now <= 0xDBFF then
+ more = now
+ return "" -- else the c's end up in the stream
+ else
+ return utfchar(now)
+ end
+end
+local p_utf32_to_utf8_be = C(1) * C(1) * C(1) * C(1) /function(a,b,c,d)
+ return utfchar(256*256*256*byte(a) + 256*256*byte(b) + 256*byte(c) + byte(d))
+end
+
+local p_utf32_to_utf8_le = C(1) * C(1) * C(1) * C(1) /function(a,b,c,d)
+ return utfchar(256*256*256*byte(d) + 256*256*byte(c) + 256*byte(b) + byte(a))
+end
+
+p_utf16_to_utf8_be = P(true) / function() more = 0 end * utf_16_be_getbom * Cs(p_utf16_to_utf8_be^0)
+p_utf16_to_utf8_le = P(true) / function() more = 0 end * utf_16_le_getbom * Cs(p_utf16_to_utf8_le^0)
+p_utf32_to_utf8_be = P(true) / function() more = 0 end * utf_32_be_getbom * Cs(p_utf32_to_utf8_be^0)
+p_utf32_to_utf8_le = P(true) / function() more = 0 end * utf_32_le_getbom * Cs(p_utf32_to_utf8_le^0)
+
+patterns.utf16_to_utf8_be = p_utf16_to_utf8_be
+patterns.utf16_to_utf8_le = p_utf16_to_utf8_le
+patterns.utf32_to_utf8_be = p_utf32_to_utf8_be
+patterns.utf32_to_utf8_le = p_utf32_to_utf8_le
+
+utf16_to_utf8_be = function(s)
+ if s and s ~= "" then
+ return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+ return s
+ end
+end
+
+local utf16_to_utf8_be_t = function(t)
+ if not t then
+ return nil
+ elseif type(t) == "string" then
+ t = lpegmatch(utf_16_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s = t[i]
+ if s ~= "" then
+ t[i] = lpegmatch(p_utf16_to_utf8_be,s)
+ end
+ end
+ return t
+end
+
+utf16_to_utf8_le = function(s)
+ if s and s ~= "" then
+ return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+ return s
+ end
+end
+
+local utf16_to_utf8_le_t = function(t)
+ if not t then
+ return nil
+ elseif type(t) == "string" then
+ t = lpegmatch(utf_16_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s = t[i]
+ if s ~= "" then
+ t[i] = lpegmatch(p_utf16_to_utf8_le,s)
+ end
+ end
+ return t
+end
+
+utf32_to_utf8_be = function(s)
+ if s and s ~= "" then
+ return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+ return s
+ end
+end
+
+local utf32_to_utf8_be_t = function(t)
+ if not t then
+ return nil
+ elseif type(t) == "string" then
+ t = lpegmatch(utf_32_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s = t[i]
+ if s ~= "" then
+ t[i] = lpegmatch(p_utf32_to_utf8_be,s)
+ end
+ end
+ return t
+end
+
+utf32_to_utf8_le = function(s)
+ if s and s ~= "" then
+ return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+ return s
+ end
+end
+
+local utf32_to_utf8_le_t = function(t)
+ if not t then
+ return nil
+ elseif type(t) == "string" then
+ t = lpegmatch(utf_32_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s = t[i]
+ if s ~= "" then
+ t[i] = lpegmatch(p_utf32_to_utf8_le,s)
+ end
+ end
+ return t
+end
+
+utf.utf16_to_utf8_le_t = utf16_to_utf8_le_t
+utf.utf16_to_utf8_be_t = utf16_to_utf8_be_t
+utf.utf32_to_utf8_le_t = utf32_to_utf8_le_t
+utf.utf32_to_utf8_be_t = utf32_to_utf8_be_t
+
+utf.utf16_to_utf8_le = utf16_to_utf8_le
+utf.utf16_to_utf8_be = utf16_to_utf8_be
+utf.utf32_to_utf8_le = utf32_to_utf8_le
+utf.utf32_to_utf8_be = utf32_to_utf8_be
+
+function utf.utf8_to_utf8_t(t)
+ return type(t) == "string" and lpegmatch(utflinesplitter,t) or t
+end
+
+function utf.utf16_to_utf8_t(t,endian)
+ return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
+end
+
+function utf.utf32_to_utf8_t(t,endian)
+ return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
+end
+
+local function little(b)
+ if b < 0x10000 then
+ return char(b%256,rshift(b,8))
+ else
+ b = b - 0x10000
+ local b1 = rshift(b,10) + 0xD800
+ local b2 = b%1024 + 0xDC00
+ return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
+end
+
+local function big(b)
+ if b < 0x10000 then
+ return char(rshift(b,8),b%256)
+ else
+ b = b - 0x10000
+ local b1 = rshift(b,10) + 0xD800
+ local b2 = b%1024 + 0xDC00
+ return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
+end
+
+local l_remap = Cs((p_utf8byte/little+P(1)/"")^0)
+local b_remap = Cs((p_utf8byte/big +P(1)/"")^0)
+
+local function utf8_to_utf16_be(str,nobom)
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255) .. lpegmatch(b_remap,str)
+ end
+end
+
+local function utf8_to_utf16_le(str,nobom)
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254) .. lpegmatch(l_remap,str)
+ end
+end
+
+utf.utf8_to_utf16_be = utf8_to_utf16_be
+utf.utf8_to_utf16_le = utf8_to_utf16_le
+
+function utf.utf8_to_utf16(str,littleendian,nobom)
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
+end
+
+local pattern = Cs (
+ (p_utf8byte / function(unicode ) return format( "0x%04X", unicode) end) *
+ (p_utf8byte * Carg(1) / function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
+)
+
+function utf.tocodes(str,separator)
+ return lpegmatch(pattern,str,1,separator or " ")
+end
+
+function utf.ustring(s)
+ return format("U+%05X",type(s) == "number" and s or utfbyte(s))
+end
+
+function utf.xstring(s)
+ return format("0x%05X",type(s) == "number" and s or utfbyte(s))
+end
+
+function utf.toeight(str)
+ if not str or str == "" then
+ return nil
+ end
+ local utftype = lpegmatch(p_utfstricttype,str)
+ if utftype == "utf-8" then
+ return sub(str,4) -- remove the bom
+ elseif utftype == "utf-16-be" then
+ return utf16_to_utf8_be(str) -- bom gets removed
+ elseif utftype == "utf-16-le" then
+ return utf16_to_utf8_le(str) -- bom gets removed
+ else
+ return str
+ end
+end
+
+--
+
+do
+
+ local p_nany = p_utf8character / ""
+ local cache = { }
+
+ function utf.count(str,what)
+ if type(what) == "string" then
+ local p = cache[what]
+ if not p then
+ p = Cs((P(what)/" " + p_nany)^0)
+ cache[p] = p
+ end
+ return #lpegmatch(p,str)
+ else -- 4 times slower but still faster than / function
+ return #lpegmatch(Cs((P(what)/" " + p_nany)^0),str)
+ end
+ end
+
+end
+
+if not string.utfvalues then
+
+ -- So, a logical next step is to check for the values variant. It over five times
+ -- slower than the built-in string.utfvalues. I optimized it a bit for n=0,1.
+
+ ----- wrap, yield, gmatch = coroutine.wrap, coroutine.yield, string.gmatch
+ local find = string.find
+
+ local dummy = function()
+ -- we share this one
+ end
+
+ -- function string.utfvalues(str)
+ -- local n = #str
+ -- if n == 0 then
+ -- return wrap(dummy)
+ -- elseif n == 1 then
+ -- return wrap(function() yield(utfbyte(str)) end)
+ -- else
+ -- return wrap(function() for s in gmatch(str,".[\128-\191]*") do
+ -- yield(utfbyte(s))
+ -- end end)
+ -- end
+ -- end
+ --
+ -- faster:
+
+ function string.utfvalues(str)
+ local n = #str
+ if n == 0 then
+ return dummy
+ elseif n == 1 then
+ return function() return utfbyte(str) end
+ else
+ local p = 1
+ -- local n = #str
+ return function()
+ -- if p <= n then -- slower than the last find
+ local b, e = find(str,".[\128-\191]*",p)
+ if b then
+ p = e + 1
+ return utfbyte(sub(str,b,e))
+ end
+ -- end
+ end
+ end
+ end
+
+ -- slower:
+ --
+ -- local pattern = C(p_utf8character) * Cp()
+ -- ----- pattern = p_utf8character/utfbyte * Cp()
+ -- ----- pattern = p_utf8byte * Cp()
+ --
+ -- function string.utfvalues(str) -- one of the cases where a find is faster than an lpeg
+ -- local n = #str
+ -- if n == 0 then
+ -- return dummy
+ -- elseif n == 1 then
+ -- return function() return utfbyte(str) end
+ -- else
+ -- local p = 1
+ -- return function()
+ -- local s, e = lpegmatch(pattern,str,p)
+ -- if e then
+ -- p = e
+ -- return utfbyte(s)
+ -- -- return s
+ -- end
+ -- end
+ -- end
+ -- end
+
+end
+
+utf.values = string.utfvalues
+
+function utf.chrlen(u) -- u is number
+ return
+ (u < 0x80 and 1) or
+ (u < 0xE0 and 2) or
+ (u < 0xF0 and 3) or
+ (u < 0xF8 and 4) or
+ (u < 0xFC and 5) or
+ (u < 0xFE and 6) or 0
+end
+
+-- hashing saves a little but not that much in practice
+--
+-- local utf32 = table.setmetatableindex(function(t,k) local v = toutf32(k) t[k] = v return v end)
+
+if bit32 then
+
+ local extract = bit32.extract
+ local char = string.char
+
+ function utf.toutf32string(n)
+ if n <= 0xFF then
+ return
+ char(n) ..
+ "\000\000\000"
+ elseif n <= 0xFFFF then
+ return
+ char(extract(n, 0,8)) ..
+ char(extract(n, 8,8)) ..
+ "\000\000"
+ elseif n <= 0xFFFFFF then
+ return
+ char(extract(n, 0,8)) ..
+ char(extract(n, 8,8)) ..
+ char(extract(n,16,8)) ..
+ "\000"
+ else
+ return
+ char(extract(n, 0,8)) ..
+ char(extract(n, 8,8)) ..
+ char(extract(n,16,8)) ..
+ char(extract(n,24,8))
+ end
+ end
+
+end
+
+-- goodie:
+
+local len = utf.len
+local rep = rep
+
+function string.utfpadd(s,n)
+ if n and n ~= 0 then
+ local l = len(s)
+ if n > 0 then
+ local d = n - l
+ if d > 0 then
+ return rep(c or " ",d) .. s
+ end
+ else
+ local d = - n - l
+ if d > 0 then
+ return s .. rep(c or " ",d)
+ end
+ end
+ end
+ return s
+end
+
+-- goodies
+
+do
+
+ local utfcharacters = utf.characters or string.utfcharacters
+ local utfchar = utf.char or string.utfcharacter
+
+ lpeg.UP = P
+
+ if utfcharacters then
+
+ function lpeg.US(str)
+ local p = P(false)
+ for uc in utfcharacters(str) do
+ p = p + P(uc)
+ end
+ return p
+ end
+
+ else
+
+ function lpeg.US(str)
+ local p = P(false)
+ local f = function(uc)
+ p = p + P(uc)
+ end
+ lpegmatch((p_utf8char/f)^0,str)
+ return p
+ end
+
+ end
+
+ local range = p_utf8byte * p_utf8byte + Cc(false) -- utf8byte is already a capture
+
+ function lpeg.UR(str,more)
+ local first, last
+ if type(str) == "number" then
+ first = str
+ last = more or first
+ else
+ first, last = lpegmatch(range,str)
+ if not last then
+ return P(str)
+ end
+ end
+ if first == last then
+ return P(str)
+ end
+ if not utfchar then
+ utfchar = utf.char -- maybe delayed
+ end
+ if utfchar and (last - first < 8) then -- a somewhat arbitrary criterium
+ local p = P(false)
+ for i=first,last do
+ p = p + P(utfchar(i))
+ end
+ return p -- nil when invalid range
+ else
+ local f = function(b)
+ return b >= first and b <= last
+ end
+ -- tricky, these nested captures
+ return p_utf8byte / f -- nil when invalid range
+ end
+ end
+
+ -- print(lpeg.match(lpeg.Cs((C(lpeg.UR("αω"))/{ ["χ"] = "OEPS" })^0),"αωχαω"))
+
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-url.lua b/macros/luatex/generic/lualibs/lualibs-url.lua
new file mode 100644
index 0000000000..6f834d778d
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-url.lua
@@ -0,0 +1,431 @@
+if not modules then modules = { } end modules ['l-url'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local char, format, byte = string.char, string.format, string.byte
+local concat = table.concat
+local tonumber, type, next = tonumber, type, next
+local P, C, R, S, Cs, Cc, Ct, Cf, Cg, V = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Cf, lpeg.Cg, lpeg.V
+local lpegmatch, lpegpatterns, replacer = lpeg.match, lpeg.patterns, lpeg.replacer
+local sortedhash = table.sortedhash
+
+-- from wikipedia:
+--
+-- foo://username:password@example.com:8042/over/there/index.dtb?type=animal;name=narwhal#nose
+-- \_/ \_______________/ \_________/ \__/ \___/ \_/ \______________________/ \__/
+-- | | | | | | | |
+-- | userinfo hostname port | | query fragment
+-- | \________________________________/\_____________|____|/
+-- scheme | | | |
+-- | authority path | |
+-- | | |
+-- | path interpretable as filename
+-- | ___________|____________ |
+-- / \ / \ |
+-- urn:example:animal:ferret:nose interpretable as extension
+--
+-- also nice: http://url.spec.whatwg.org/ (maybe some day ...)
+
+url = url or { }
+local url = url
+
+local unescapes = { }
+local escapes = { }
+
+setmetatable(unescapes, { __index = function(t,k)
+ local v = char(tonumber(k,16))
+ t[k] = v
+ return v
+end })
+
+setmetatable(escapes, { __index = function(t,k)
+ local v = format("%%%02X",byte(k))
+ t[k] = v
+ return v
+end })
+
+-- okay:
+
+local colon = P(":")
+local qmark = P("?")
+local hash = P("#")
+local slash = P("/")
+local atsign = P("@")
+local percent = P("%")
+local endofstring = P(-1)
+local hexdigit = R("09","AF","af")
+local plus = P("+")
+local nothing = Cc("")
+local okay = R("09","AZ","az") + S("-_.,:=+*~!'()@&$")
+
+local escapedchar = (percent * C(hexdigit * hexdigit)) / unescapes
+local unescapedchar = P(1) / escapes
+local escaped = (plus / " ") + escapedchar -- so no loc://foo++.tex
+local noslash = P("/") / ""
+local plustospace = P("+")/" "
+
+local decoder = Cs( (
+ plustospace
+ + escapedchar
+ + P("\r\n")/"\n"
+ + P(1)
+ )^0 )
+local encoder = Cs( (
+ R("09","AZ","az")^1
+ + S("-./_")^1
+ + P(" ")/"+"
+ + P("\n")/"\r\n"
+ + unescapedchar
+ )^0 )
+
+lpegpatterns.urldecoder = decoder
+lpegpatterns.urlencoder = encoder
+
+function url.decode (str) return str and lpegmatch(decoder, str) or str end
+function url.encode (str) return str and lpegmatch(encoder, str) or str end
+function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
+
+-- we assume schemes with more than 1 character (in order to avoid problems with windows disks)
+-- we also assume that when we have a scheme, we also have an authority
+--
+-- maybe we should already split the query (better for unescaping as = & can be part of a value
+
+local schemestr = Cs((escaped+(1-colon-slash-qmark-hash))^2)
+local authoritystr = Cs((escaped+(1- slash-qmark-hash))^0)
+local pathstr = Cs((escaped+(1- qmark-hash))^0)
+----- querystr = Cs((escaped+(1- hash))^0)
+local querystr = Cs(( (1- hash))^0)
+local fragmentstr = Cs((escaped+(1- endofstring))^0)
+
+local scheme = schemestr * colon + nothing
+local authority = slash * slash * authoritystr + nothing
+local path = slash * pathstr + nothing
+local query = qmark * querystr + nothing
+local fragment = hash * fragmentstr + nothing
+
+local validurl = scheme * authority * path * query * fragment
+local parser = Ct(validurl)
+
+lpegpatterns.url = validurl
+lpegpatterns.urlsplitter = parser
+
+local escaper = Cs((R("09","AZ","az")^1 + P(" ")/"%%20" + S("-./_:")^1 + P(1) / escapes)^0) -- space happens most
+local unescaper = Cs((escapedchar + 1)^0)
+local getcleaner = Cs((P("+++")/"%%2B" + P("+")/"%%20" + P(1))^1)
+
+lpegpatterns.urlunescaped = escapedchar
+lpegpatterns.urlescaper = escaper
+lpegpatterns.urlunescaper = unescaper
+lpegpatterns.urlgetcleaner = getcleaner
+
+function url.unescapeget(str)
+ return lpegmatch(getcleaner,str)
+end
+
+-- todo: reconsider Ct as we can as well have five return values (saves a table)
+-- so we can have two parsers, one with and one without
+
+local function split(str)
+ return (type(str) == "string" and lpegmatch(parser,str)) or str
+end
+
+local isscheme = schemestr * colon * slash * slash -- this test also assumes authority
+
+local function hasscheme(str)
+ if str then
+ local scheme = lpegmatch(isscheme,str) -- at least one character
+ return scheme ~= "" and scheme or false
+ else
+ return false
+ end
+end
+
+--~ print(hasscheme("home:"))
+--~ print(hasscheme("home://"))
+
+-- todo: cache them
+
+local rootletter = R("az","AZ")
+ + S("_-+")
+local separator = P("://")
+local qualified = P(".")^0 * P("/")
+ + rootletter * P(":")
+ + rootletter^1 * separator
+ + rootletter^1 * P("/")
+local rootbased = P("/")
+ + rootletter * P(":")
+
+local barswapper = replacer("|",":")
+local backslashswapper = replacer("\\","/")
+
+-- queries:
+
+local equal = P("=")
+local amp = P("&")
+local key = Cs(((plustospace + escapedchar + 1) - equal )^0)
+local value = Cs(((plustospace + escapedchar + 1) - amp - endofstring)^0)
+
+local splitquery = Cf ( Ct("") * P { "sequence",
+ sequence = V("pair") * (amp * V("pair"))^0,
+ pair = Cg(key * equal * value),
+}, rawset)
+
+-- hasher
+
+local userpart = (1-atsign-colon)^1
+local serverpart = (1-colon)^1
+local splitauthority = ((Cs(userpart) * colon * Cs(userpart) + Cs(userpart) * Cc(nil)) * atsign + Cc(nil) * Cc(nil))
+ * Cs(serverpart) * (colon * (serverpart/tonumber) + Cc(nil))
+
+local function hashed(str) -- not yet ok (/test?test)
+ if not str or str == "" then
+ return {
+ scheme = "invalid",
+ original = str,
+ }
+ end
+ local detailed = split(str)
+ local rawscheme = ""
+ local rawquery = ""
+ local somescheme = false
+ local somequery = false
+ if detailed then
+ rawscheme = detailed[1]
+ rawquery = detailed[4]
+ somescheme = rawscheme ~= ""
+ somequery = rawquery ~= ""
+ end
+ if not somescheme and not somequery then
+ return {
+ scheme = "file",
+ authority = "",
+ path = str,
+ query = "",
+ fragment = "",
+ original = str,
+ noscheme = true,
+ filename = str,
+ }
+ end
+ -- not always a filename but handy anyway
+ local authority = detailed[2]
+ local path = detailed[3]
+ local filename -- = nil
+ local username -- = nil
+ local password -- = nil
+ local host -- = nil
+ local port -- = nil
+ if authority ~= "" then
+ -- these can be invalid
+ username, password, host, port = lpegmatch(splitauthority,authority)
+ end
+ if authority == "" then
+ filename = path
+ elseif path == "" then
+ filename = ""
+ else
+ -- this one can be can be invalid
+ filename = authority .. "/" .. path
+ end
+ return {
+ scheme = rawscheme,
+ authority = authority,
+ path = path,
+ query = lpegmatch(unescaper,rawquery), -- unescaped, but possible conflict with & and =
+ queries = lpegmatch(splitquery,rawquery), -- split first and then unescaped
+ fragment = detailed[5],
+ original = str,
+ noscheme = false,
+ filename = filename,
+ --
+ host = host,
+ port = port,
+ -- usename = username,
+ -- password = password,
+ }
+end
+
+-- inspect(hashed())
+-- inspect(hashed(""))
+-- inspect(hashed("template:///test"))
+-- inspect(hashed("template:///test++.whatever"))
+-- inspect(hashed("template:///test%2B%2B.whatever"))
+-- inspect(hashed("template:///test%x.whatever"))
+-- inspect(hashed("tem%2Bplate:///test%x.whatever"))
+
+-- Here we assume:
+--
+-- files: /// = relative
+-- files: //// = absolute (!)
+
+--~ table.print(hashed("file://c:/opt/tex/texmf-local")) -- c:/opt/tex/texmf-local
+--~ table.print(hashed("file://opt/tex/texmf-local" )) -- opt/tex/texmf-local
+--~ table.print(hashed("file:///opt/tex/texmf-local" )) -- opt/tex/texmf-local
+--~ table.print(hashed("file:////opt/tex/texmf-local" )) -- /opt/tex/texmf-local
+--~ table.print(hashed("file:///./opt/tex/texmf-local" )) -- ./opt/tex/texmf-local
+
+--~ table.print(hashed("c:/opt/tex/texmf-local" )) -- c:/opt/tex/texmf-local
+--~ table.print(hashed("opt/tex/texmf-local" )) -- opt/tex/texmf-local
+--~ table.print(hashed("/opt/tex/texmf-local" )) -- /opt/tex/texmf-local
+
+url.split = split
+url.hasscheme = hasscheme
+url.hashed = hashed
+
+function url.addscheme(str,scheme) -- no authority
+ if hasscheme(str) then
+ return str
+ elseif not scheme then
+ return "file:///" .. str
+ else
+ return scheme .. ":///" .. str
+ end
+end
+
+function url.construct(hash) -- dodo: we need to escape !
+ local result, r = { }, 0
+ local scheme = hash.scheme
+ local authority = hash.authority
+ local path = hash.path
+ local queries = hash.queries
+ local fragment = hash.fragment
+ if scheme and scheme ~= "" then
+ r = r + 1 ; result[r] = lpegmatch(escaper,scheme)
+ r = r + 1 ; result[r] = "://"
+ end
+ if authority and authority ~= "" then
+ r = r + 1 ; result[r] = lpegmatch(escaper,authority)
+ end
+ if path and path ~= "" then
+ r = r + 1 ; result[r] = "/"
+ r = r + 1 ; result[r] = lpegmatch(escaper,path)
+ end
+ if queries then
+ local done = false
+ for k, v in sortedhash(queries) do
+ r = r + 1 ; result[r] = done and "&" or "?"
+ r = r + 1 ; result[r] = lpegmatch(escaper,k) -- is this escaped
+ r = r + 1 ; result[r] = "="
+ r = r + 1 ; result[r] = lpegmatch(escaper,v) -- is this escaped
+ done = true
+ end
+ end
+ if fragment and fragment ~= "" then
+ r = r + 1 ; result[r] = "#"
+ r = r + 1 ; result[r] = lpegmatch(escaper,fragment)
+ end
+ return concat(result)
+end
+
+local pattern = Cs(slash^-1/"" * R("az","AZ") * ((S(":|")/":") + P(":")) * slash * P(1)^0)
+
+function url.filename(filename)
+ local spec = hashed(filename)
+ local path = spec.path
+ return (spec.scheme == "file" and path and lpegmatch(pattern,path)) or filename
+end
+
+-- print(url.filename("/c|/test"))
+-- print(url.filename("/c/test"))
+-- print(url.filename("file:///t:/sources/cow.svg"))
+
+local function escapestring(str)
+ return lpegmatch(escaper,str)
+end
+
+url.escape = escapestring
+
+function url.query(str)
+ if type(str) == "string" then
+ return lpegmatch(splitquery,str) or ""
+ else
+ return str
+ end
+end
+
+function url.toquery(data)
+ local td = type(data)
+ if td == "string" then
+ return #str and escape(data) or nil -- beware of double escaping
+ elseif td == "table" then
+ if next(data) then
+ local t = { }
+ for k, v in next, data do
+ t[#t+1] = format("%s=%s",k,escapestring(v))
+ end
+ return concat(t,"&")
+ end
+ else
+ -- nil is a signal that no query
+ end
+end
+
+-- /test/ | /test | test/ | test => test
+
+local pattern = Cs(noslash^0 * (1 - noslash * P(-1))^0)
+
+function url.barepath(path)
+ if not path or path == "" then
+ return ""
+ else
+ return lpegmatch(pattern,path)
+ end
+end
+
+-- print(url.barepath("/test"),url.barepath("test/"),url.barepath("/test/"),url.barepath("test"))
+-- print(url.barepath("/x/yz"),url.barepath("x/yz/"),url.barepath("/x/yz/"),url.barepath("x/yz"))
+
+--~ print(url.filename("file:///c:/oeps.txt"))
+--~ print(url.filename("c:/oeps.txt"))
+--~ print(url.filename("file:///oeps.txt"))
+--~ print(url.filename("file:///etc/test.txt"))
+--~ print(url.filename("/oeps.txt"))
+
+--~ from the spec on the web (sort of):
+
+--~ local function test(str)
+--~ local t = url.hashed(str)
+--~ t.constructed = url.construct(t)
+--~ print(table.serialize(t))
+--~ end
+
+--~ inspect(url.hashed("http://www.pragma-ade.com/test%20test?test=test%20test&x=123%3d45"))
+--~ inspect(url.hashed("http://www.pragma-ade.com/test%20test?test=test%20test&x=123%3d45"))
+
+--~ test("sys:///./colo-rgb")
+
+--~ test("/data/site/output/q2p-develop/resources/ecaboperception4_res/topicresources/58313733/figuur-cow.jpg")
+--~ test("file:///M:/q2p/develop/output/q2p-develop/resources/ecaboperception4_res/topicresources/58313733")
+--~ test("M:/q2p/develop/output/q2p-develop/resources/ecaboperception4_res/topicresources/58313733")
+--~ test("file:///q2p/develop/output/q2p-develop/resources/ecaboperception4_res/topicresources/58313733")
+--~ test("/q2p/develop/output/q2p-develop/resources/ecaboperception4_res/topicresources/58313733")
+
+--~ test("file:///cow%20with%20spaces")
+--~ test("file:///cow%20with%20spaces.pdf")
+--~ test("cow%20with%20spaces.pdf")
+--~ test("some%20file")
+--~ test("/etc/passwords")
+--~ test("http://www.myself.com/some%20words.html")
+--~ test("file:///c:/oeps.txt")
+--~ test("file:///c|/oeps.txt")
+--~ test("file:///etc/oeps.txt")
+--~ test("file://./etc/oeps.txt")
+--~ test("file:////etc/oeps.txt")
+--~ test("ftp://ftp.is.co.za/rfc/rfc1808.txt")
+--~ test("http://www.ietf.org/rfc/rfc2396.txt")
+--~ test("ldap://[2001:db8::7]/c=GB?objectClass?one#what")
+--~ test("mailto:John.Doe@example.com")
+--~ test("news:comp.infosystems.www.servers.unix")
+--~ test("tel:+1-816-555-1212")
+--~ test("telnet://192.0.2.16:80/")
+--~ test("urn:oasis:names:specification:docbook:dtd:xml:4.1.2")
+--~ test("http://www.pragma-ade.com/spaced%20name")
+
+--~ test("zip:///oeps/oeps.zip#bla/bla.tex")
+--~ test("zip:///oeps/oeps.zip?bla/bla.tex")
+
+--~ table.print(url.hashed("/test?test"))
diff --git a/macros/luatex/generic/lualibs/lualibs-util-deb.lua b/macros/luatex/generic/lualibs/lualibs-util-deb.lua
new file mode 100644
index 0000000000..bd94b6d01e
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-util-deb.lua
@@ -0,0 +1,348 @@
+if not modules then modules = { } end modules ['util-deb'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- the <anonymous> tag is kind of generic and used for functions that are not
+-- bound to a variable, like node.new, node.copy etc (contrary to for instance
+-- node.has_attribute which is bound to a has_attribute local variable in mkiv)
+
+local type, next, tostring, tonumber = type, next, tostring, tonumber
+local format, find, sub, gsub = string.format, string.find, string.sub, string.gsub
+local insert, remove, sort = table.insert, table.remove, table.sort
+local setmetatableindex = table.setmetatableindex
+
+utilities = utilities or { }
+local debugger = utilities.debugger or { }
+utilities.debugger = debugger
+
+local report = logs.reporter("debugger")
+
+local ticks = os.gettimeofday or os.clock
+local seconds = function(n) return n or 0 end
+local overhead = 0
+local dummycalls = 10*1000
+local nesting = 0
+local names = { }
+
+local initialize = false
+
+if lua.getpreciseticks then
+
+ initialize = function()
+ ticks = lua.getpreciseticks
+ seconds = lua.getpreciseseconds
+ initialize = false
+ end
+
+elseif not (FFISUPPORTED and ffi) then
+
+ -- we have no precise timer
+
+elseif os.type == "windows" then
+
+ initialize = function()
+ local kernel = ffilib("kernel32","system") -- no checking
+ if kernel then
+ local tonumber = ffi.number or tonumber
+ ffi.cdef[[
+ int QueryPerformanceFrequency(int64_t *lpFrequency);
+ int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+ ]]
+ local target = ffi.new("__int64[1]")
+ ticks = function()
+ if kernel.QueryPerformanceCounter(target) == 1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ local target = ffi.new("__int64[1]")
+ seconds = function(ticks)
+ if kernel.QueryPerformanceFrequency(target) == 1 then
+ return ticks / tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ end
+ initialize = false
+ end
+
+elseif os.type == "unix" then
+
+ -- for the values: echo '#include <time.h>' > foo.h; gcc -dM -E foo.h
+
+ initialize = function()
+ local C = ffi.C
+ local tonumber = ffi.number or tonumber
+ ffi.cdef [[
+ /* what a mess */
+ typedef int clk_id_t;
+ typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
+ typedef struct timespec { long sec; long nsec; } ctx_timespec;
+ int clock_gettime(clk_id_t timerid, struct timespec *t);
+ ]]
+ local target = ffi.new("ctx_timespec[?]",1)
+ local clock = C.CLOCK_PROCESS_CPUTIME_ID
+ ticks = function ()
+ C.clock_gettime(clock,target)
+ return tonumber(target[0].sec*1000000000 + target[0].nsec)
+ end
+ seconds = function(ticks)
+ return ticks/1000000000
+ end
+ initialize = false
+ end
+
+end
+
+setmetatableindex(names,function(t,name)
+ local v = setmetatableindex(function(t,source)
+ local v = setmetatableindex(function(t,line)
+ local v = { total = 0, count = 0, nesting = 0 }
+ t[line] = v
+ return v
+ end)
+ t[source] = v
+ return v
+ end)
+ t[name] = v
+ return v
+end)
+
+local getinfo = nil
+local sethook = nil
+
+local function hook(where)
+ local f = getinfo(2,"nSl")
+ if f then
+ local source = f.short_src
+ if not source then
+ return
+ end
+ local line = f.linedefined or 0
+ local name = f.name
+ if not name then
+ local what = f.what
+ if what == "C" then
+ name = "<anonymous>"
+ else
+ name = f.namewhat or what or "<unknown>"
+ end
+ end
+ local data = names[name][source][line]
+ if where == "call" then
+ local nesting = data.nesting
+ if nesting == 0 then
+ data.count = data.count + 1
+ insert(data,ticks())
+ data.nesting = 1
+ else
+ data.nesting = nesting + 1
+ end
+ elseif where == "return" then
+ local nesting = data.nesting
+ if nesting == 1 then
+ local t = remove(data)
+ if t then
+ data.total = data.total + ticks() - t
+ end
+ data.nesting = 0
+ else
+ data.nesting = nesting - 1
+ end
+ end
+ end
+end
+
+function debugger.showstats(printer,threshold)
+ local printer = printer or report
+ local calls = 0
+ local functions = 0
+ local dataset = { }
+ local length = 0
+ local realtime = 0
+ local totaltime = 0
+ local threshold = threshold or 0
+ for name, sources in next, names do
+ for source, lines in next, sources do
+ for line, data in next, lines do
+ local count = data.count
+ if count > threshold then
+ if #name > length then
+ length = #name
+ end
+ local total = data.total
+ local real = total
+ if real > 0 then
+ real = total - (count * overhead / dummycalls)
+ if real < 0 then
+ real = 0
+ end
+ realtime = realtime + real
+ end
+ totaltime = totaltime + total
+ if line < 0 then
+ line = 0
+ end
+ -- if name = "a" then
+ -- -- weird name
+ -- end
+ dataset[#dataset+1] = { real, total, count, name, source, line }
+ end
+ end
+ end
+ end
+ sort(dataset,function(a,b)
+ if a[1] == b[1] then
+ if a[2] == b[2] then
+ if a[3] == b[3] then
+ if a[4] == b[4] then
+ if a[5] == b[5] then
+ return a[6] < b[6]
+ else
+ return a[5] < b[5]
+ end
+ else
+ return a[4] < b[4]
+ end
+ else
+ return b[3] < a[3]
+ end
+ else
+ return b[2] < a[2]
+ end
+ else
+ return b[1] < a[1]
+ end
+ end)
+ if length > 50 then
+ length = 50
+ end
+ local fmt = string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-" .. length .. "s %4i %s"]
+ for i=1,#dataset do
+ local data = dataset[i]
+ local real = data[1]
+ local total = data[2]
+ local count = data[3]
+ local name = data[4]
+ local source = data[5]
+ local line = data[6]
+ calls = calls + count
+ functions = functions + 1
+ name = gsub(name,"%s+"," ")
+ if #name > length then
+ name = sub(name,1,length)
+ end
+ printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
+ end
+ printer("")
+ printer(format("functions : %i", functions))
+ printer(format("calls : %i", calls))
+ printer(format("overhead : %f", seconds(overhead/1000)))
+
+ -- table.save("luatex-profile.lua",names)
+end
+
+local function getdebug()
+ if sethook and getinfo then
+ return
+ end
+ if not debug then
+ local okay
+ okay, debug = pcall(require,"debug")
+ end
+ if type(debug) ~= "table" then
+ return
+ end
+ getinfo = debug.getinfo
+ sethook = debug.sethook
+ if type(getinfo) ~= "function" then
+ getinfo = nil
+ end
+ if type(sethook) ~= "function" then
+ sethook = nil
+ end
+end
+
+function debugger.savestats(filename,threshold)
+ local f = io.open(filename,'w')
+ if f then
+ debugger.showstats(function(str) f:write(str,"\n") end,threshold)
+ f:close()
+ end
+end
+
+function debugger.enable()
+ getdebug()
+ if sethook and getinfo and nesting == 0 then
+ running = true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t = ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead = ticks() - t
+ end
+ if nesting > 0 then
+ nesting = nesting + 1
+ end
+end
+
+function debugger.disable()
+ if nesting > 0 then
+ nesting = nesting - 1
+ end
+ if sethook and getinfo and nesting == 0 then
+ sethook()
+ end
+end
+
+-- debugger.enable()
+--
+-- print(math.sin(1*.5))
+-- print(math.sin(1*.5))
+-- print(math.sin(1*.5))
+-- print(math.sin(1*.5))
+-- print(math.sin(1*.5))
+--
+-- debugger.disable()
+--
+-- print("")
+-- debugger.showstats()
+-- print("")
+-- debugger.showstats(print,3)
+--
+-- from the lua book:
+
+local function showtraceback(rep) -- from lua site / adapted
+ getdebug()
+ if getinfo then
+ local level = 2 -- we don't want this function to be reported
+ local reporter = rep or report
+ while true do
+ local info = getinfo(level, "Sl")
+ if not info then
+ break
+ elseif info.what == "C" then
+ reporter("%2i : %s",level-1,"C function")
+ else
+ reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
+ end
+ level = level + 1
+ end
+ end
+end
+
+debugger.showtraceback = showtraceback
+-- debug.showtraceback = showtraceback
+
+-- showtraceback()
diff --git a/macros/luatex/generic/lualibs/lualibs-util-dim.lua b/macros/luatex/generic/lualibs/lualibs-util-dim.lua
new file mode 100644
index 0000000000..76b5fd20bb
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-util-dim.lua
@@ -0,0 +1,456 @@
+if not modules then modules = { } end modules ['util-dim'] = {
+ version = 1.001,
+ comment = "support for dimensions",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>Internally <l n='luatex'/> work with scaled point, which are
+represented by integers. However, in practice, at east at the
+<l n='tex'/> end we work with more generic units like points (pt). Going
+from scaled points (numbers) to one of those units can be
+done by using the conversion factors collected in the following
+table.</p>
+--ldx]]--
+
+local format, match, gsub, type, setmetatable = string.format, string.match, string.gsub, type, setmetatable
+local P, S, R, Cc, C, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.Cc, lpeg.C, lpeg.match
+
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+local formatters = string.formatters
+
+local texget = tex and tex.get or function() return 65536*10*100 end
+
+local p_stripzeros = lpeg.patterns.stripzeros
+
+--this might become another namespace
+
+number = number or { }
+local number = number
+
+number.tonumberf = function(n) return lpegmatch(p_stripzeros,format("%.20f",n)) end
+number.tonumberg = function(n) return format("%.20g",n) end
+
+local dimenfactors = allocate {
+ ["pt"] = 1/65536,
+ ["in"] = ( 100/ 7227)/65536,
+ ["cm"] = ( 254/ 7227)/65536,
+ ["mm"] = ( 2540/ 7227)/65536,
+ ["sp"] = 1, -- 65536 sp in 1pt
+ ["bp"] = ( 7200/ 7227)/65536,
+ ["pc"] = ( 1/ 12)/65536,
+ ["dd"] = ( 1157/ 1238)/65536,
+ ["cc"] = ( 1157/14856)/65536,
+ ["nd"] = (20320/21681)/65536,
+ ["nc"] = ( 5080/65043)/65536
+}
+
+-- print(table.serialize(dimenfactors))
+--
+-- %.99g:
+--
+-- t={
+-- ["bp"]=1.5201782378580324e-005,
+-- ["cc"]=1.1883696112892098e-006,
+-- ["cm"]=5.3628510057769479e-007,
+-- ["dd"]=1.4260435335470516e-005,
+-- ["em"]=0.000152587890625,
+-- ["ex"]=6.103515625e-005,
+-- ["in"]=2.1113586636917117e-007,
+-- ["mm"]=5.3628510057769473e-008,
+-- ["nc"]=1.1917446679504327e-006,
+-- ["nd"]=1.4300936015405194e-005,
+-- ["pc"]=1.2715657552083333e-006,
+-- ["pt"]=1.52587890625e-005,
+-- ["sp"]=1,
+-- }
+--
+-- patched %s and tonumber
+--
+-- t={
+-- ["bp"]=0.00001520178238,
+-- ["cc"]=0.00000118836961,
+-- ["cm"]=0.0000005362851,
+-- ["dd"]=0.00001426043534,
+-- ["em"]=0.00015258789063,
+-- ["ex"]=0.00006103515625,
+-- ["in"]=0.00000021113587,
+-- ["mm"]=0.00000005362851,
+-- ["nc"]=0.00000119174467,
+-- ["nd"]=0.00001430093602,
+-- ["pc"]=0.00000127156576,
+-- ["pt"]=0.00001525878906,
+-- ["sp"]=1,
+-- }
+
+--[[ldx--
+<p>A conversion function that takes a number, unit (string) and optional
+format (string) is implemented using this table.</p>
+--ldx]]--
+
+local f_none = formatters["%s%s"]
+local f_true = formatters["%0.5F%s"]
+
+local function numbertodimen(n,unit,fmt) -- will be redefined later !
+ if type(n) == 'string' then
+ return n
+ else
+ unit = unit or 'pt'
+ n = n * dimenfactors[unit]
+ if not fmt then
+ fmt = f_none(n,unit)
+ elseif fmt == true then
+ fmt = f_true(n,unit)
+ else
+ return formatters[fmt](n,unit)
+ end
+ end
+end
+
+--[[ldx--
+<p>We collect a bunch of converters in the <type>number</type> namespace.</p>
+--ldx]]--
+
+number.maxdimen = 1073741823
+number.todimen = numbertodimen
+number.dimenfactors = dimenfactors
+
+function number.topoints (n,fmt) return numbertodimen(n,"pt",fmt) end
+function number.toinches (n,fmt) return numbertodimen(n,"in",fmt) end
+function number.tocentimeters (n,fmt) return numbertodimen(n,"cm",fmt) end
+function number.tomillimeters (n,fmt) return numbertodimen(n,"mm",fmt) end
+function number.toscaledpoints(n,fmt) return numbertodimen(n,"sp",fmt) end
+function number.toscaledpoints(n) return n .. "sp" end
+function number.tobasepoints (n,fmt) return numbertodimen(n,"bp",fmt) end
+function number.topicas (n,fmt) return numbertodimen(n "pc",fmt) end
+function number.todidots (n,fmt) return numbertodimen(n,"dd",fmt) end
+function number.tociceros (n,fmt) return numbertodimen(n,"cc",fmt) end
+function number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end
+function number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end
+
+--[[ldx--
+<p>More interesting it to implement a (sort of) dimen datatype, one
+that permits calculations too. First we define a function that
+converts a string to scaledpoints. We use <l n='lpeg'/>. We capture
+a number and optionally a unit. When no unit is given a constant
+capture takes place.</p>
+--ldx]]--
+
+local amount = (S("+-")^0 * R("09")^0 * P(".")^0 * R("09")^0) + Cc("0")
+local unit = R("az")^1 + P("%")
+
+local dimenpair = amount/tonumber * (unit^1/dimenfactors + Cc(1)) -- tonumber is new
+
+lpeg.patterns.dimenpair = dimenpair
+
+local splitter = amount/tonumber * C(unit^1)
+
+function number.splitdimen(str)
+ return lpegmatch(splitter,str)
+end
+
+--[[ldx--
+<p>We use a metatable to intercept errors. When no key is found in
+the table with factors, the metatable will be consulted for an
+alternative index function.</p>
+--ldx]]--
+
+setmetatableindex(dimenfactors, function(t,s)
+ -- error("wrong dimension: " .. (s or "?")) -- better a message
+ return false
+end)
+
+--[[ldx--
+<p>We redefine the following function later on, so we comment it
+here (which saves us bytecodes.</p>
+--ldx]]--
+
+-- function string.todimen(str)
+-- if type(str) == "number" then
+-- return str
+-- else
+-- local value, unit = lpegmatch(dimenpair,str)
+-- return value/unit
+-- end
+-- end
+--
+-- local stringtodimen = string.todimen
+
+local stringtodimen -- assigned later (commenting saves bytecode)
+
+local amount = S("+-")^0 * R("09")^0 * S(".,")^0 * R("09")^0
+local unit = P("pt") + P("cm") + P("mm") + P("sp") + P("bp") + P("in") +
+ P("pc") + P("dd") + P("cc") + P("nd") + P("nc")
+
+local validdimen = amount * unit
+
+lpeg.patterns.validdimen = validdimen
+
+--[[ldx--
+<p>This converter accepts calls like:</p>
+
+<typing>
+string.todimen("10")
+string.todimen(".10")
+string.todimen("10.0")
+string.todimen("10.0pt")
+string.todimen("10pt")
+string.todimen("10.0pt")
+</typing>
+
+<p>With this in place, we can now implement a proper datatype for dimensions, one
+that permits us to do this:</p>
+
+<typing>
+s = dimen "10pt" + dimen "20pt" + dimen "200pt"
+ - dimen "100sp" / 10 + "20pt" + "0pt"
+</typing>
+
+<p>We create a local metatable for this new type:</p>
+--ldx]]--
+
+local dimensions = { }
+
+--[[ldx--
+<p>The main (and globally) visible representation of a dimen is defined next: it is
+a one-element table. The unit that is returned from the match is normally a number
+(one of the previously defined factors) but we also accept functions. Later we will
+see why. This function is redefined later.</p>
+--ldx]]--
+
+-- function dimen(a)
+-- if a then
+-- local ta= type(a)
+-- if ta == "string" then
+-- local value, unit = lpegmatch(pattern,a)
+-- if type(unit) == "function" then
+-- k = value/unit()
+-- else
+-- k = value/unit
+-- end
+-- a = k
+-- elseif ta == "table" then
+-- a = a[1]
+-- end
+-- return setmetatable({ a }, dimensions)
+-- else
+-- return setmetatable({ 0 }, dimensions)
+-- end
+-- end
+
+--[[ldx--
+<p>This function return a small hash with a metatable attached. It is
+through this metatable that we can do the calculations. We could have
+shared some of the code but for reasons of speed we don't.</p>
+--ldx]]--
+
+function dimensions.__add(a, b)
+ local ta, tb = type(a), type(b)
+ if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
+ if tb == "string" then b = stringtodimen(b) elseif tb == "table" then b = b[1] end
+ return setmetatable({ a + b }, dimensions)
+end
+
+function dimensions.__sub(a, b)
+ local ta, tb = type(a), type(b)
+ if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
+ if tb == "string" then b = stringtodimen(b) elseif tb == "table" then b = b[1] end
+ return setmetatable({ a - b }, dimensions)
+end
+
+function dimensions.__mul(a, b)
+ local ta, tb = type(a), type(b)
+ if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
+ if tb == "string" then b = stringtodimen(b) elseif tb == "table" then b = b[1] end
+ return setmetatable({ a * b }, dimensions)
+end
+
+function dimensions.__div(a, b)
+ local ta, tb = type(a), type(b)
+ if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
+ if tb == "string" then b = stringtodimen(b) elseif tb == "table" then b = b[1] end
+ return setmetatable({ a / b }, dimensions)
+end
+
+function dimensions.__unm(a)
+ local ta = type(a)
+ if ta == "string" then a = stringtodimen(a) elseif ta == "table" then a = a[1] end
+ return setmetatable({ - a }, dimensions)
+end
+
+--[[ldx--
+<p>It makes no sense to implement the power and modulo function but
+the next two do make sense because they permits is code like:</p>
+
+<typing>
+local a, b = dimen "10pt", dimen "11pt"
+...
+if a > b then
+ ...
+end
+</typing>
+--ldx]]--
+
+-- makes no sense: dimensions.__pow and dimensions.__mod
+
+function dimensions.__lt(a, b)
+ return a[1] < b[1]
+end
+
+function dimensions.__eq(a, b)
+ return a[1] == b[1]
+end
+
+--[[ldx--
+<p>We also need to provide a function for conversion to string (so that
+we can print dimensions). We print them as points, just like <l n='tex'/>.</p>
+--ldx]]--
+
+function dimensions.__tostring(a)
+ return a[1]/65536 .. "pt" -- instead of todimen(a[1])
+end
+
+--[[ldx--
+<p>Since it does not take much code, we also provide a way to access
+a few accessors</p>
+
+<typing>
+print(dimen().pt)
+print(dimen().sp)
+</typing>
+--ldx]]--
+
+function dimensions.__index(tab,key)
+ local d = dimenfactors[key]
+ if not d then
+ error("illegal property of dimen: " .. key)
+ d = 1
+ end
+ return 1/d
+end
+
+--[[ldx--
+<p>In the converter from string to dimension we support functions as
+factors. This is because in <l n='tex'/> we have a few more units:
+<type>ex</type> and <type>em</type>. These are not constant factors but
+depend on the current font. They are not defined by default, but need
+an explicit function call. This is because at the moment that this code
+is loaded, the relevant tables that hold the functions needed may not
+yet be available.</p>
+--ldx]]--
+
+ dimenfactors["ex"] = 4 * 1/65536 -- 4pt
+ dimenfactors["em"] = 10 * 1/65536 -- 10pt
+-- dimenfactors["%"] = 4 * 1/65536 -- 400pt/100
+
+--[[ldx--
+<p>The previous code is rather efficient (also thanks to <l n='lpeg'/>) but we
+can speed it up by caching converted dimensions. On my machine (2008) the following
+loop takes about 25.5 seconds.</p>
+
+<typing>
+for i=1,1000000 do
+ local s = dimen "10pt" + dimen "20pt" + dimen "200pt"
+ - dimen "100sp" / 10 + "20pt" + "0pt"
+end
+</typing>
+
+<p>When we cache converted strings this becomes 16.3 seconds. In order not
+to waste too much memory on it, we tag the values of the cache as being
+week which mean that the garbage collector will collect them in a next
+sweep. This means that in most cases the speed up is mostly affecting the
+current couple of calculations and as such the speed penalty is small.</p>
+
+<p>We redefine two previous defined functions that can benefit from
+this:</p>
+--ldx]]--
+
+local known = { } setmetatable(known, { __mode = "v" })
+
+function dimen(a)
+ if a then
+ local ta= type(a)
+ if ta == "string" then
+ local k = known[a]
+ if k then
+ a = k
+ else
+ local value, unit = lpegmatch(dimenpair,a)
+ if value and unit then
+ k = value/unit -- to be considered: round
+ else
+ k = 0
+ end
+ known[a] = k
+ a = k
+ end
+ elseif ta == "table" then
+ a = a[1]
+ end
+ return setmetatable({ a }, dimensions)
+ else
+ return setmetatable({ 0 }, dimensions)
+ end
+end
+
+function string.todimen(str) -- maybe use tex.sp when available
+ local t = type(str)
+ if t == "number" then
+ return str
+ else
+ local k = known[str]
+ if not k then
+ if t == "string" then
+ local value, unit = lpegmatch(dimenpair,str)
+ if value and unit then
+ k = value/unit -- to be considered: round
+ else
+ k = 0
+ end
+ else
+ k = 0
+ end
+ known[str] = k
+ end
+ return k
+ end
+end
+
+-- local known = { }
+--
+-- function string.todimen(str) -- maybe use tex.sp
+-- local k = known[str]
+-- if not k then
+-- k = tex.sp(str)
+-- known[str] = k
+-- end
+-- return k
+-- end
+
+stringtodimen = string.todimen -- local variable defined earlier
+
+function number.toscaled(d)
+ return format("%0.5f",d/0x10000) -- 2^16
+end
+
+--[[ldx--
+<p>In a similar fashion we can define a glue datatype. In that case we
+probably use a hash instead of a one-element table.</p>
+--ldx]]--
+
+--[[ldx--
+<p>Goodie:s</p>
+--ldx]]--
+
+function number.percent(n,d) -- will be cleaned up once luatex 0.30 is out
+ d = d or texget("hsize")
+ if type(d) == "string" then
+ d = stringtodimen(d)
+ end
+ return (n/100) * d
+end
+
+number["%"] = number.percent
diff --git a/macros/luatex/generic/lualibs/lualibs-util-fil.lua b/macros/luatex/generic/lualibs/lualibs-util-fil.lua
new file mode 100644
index 0000000000..d568a2e1fd
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-util-fil.lua
@@ -0,0 +1,382 @@
+if not modules then modules = { } end modules ['util-fil'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local byte = string.byte
+local char = string.char
+
+-- Here are a few helpers (the starting point were old ones I used for parsing
+-- flac files). In Lua 5.3 we can probably do this better. Some code will move
+-- here.
+
+utilities = utilities or { }
+local files = { }
+utilities.files = files
+
+local zerobased = { }
+
+function files.open(filename,zb)
+ local f = io.open(filename,"rb")
+ if f then
+ zerobased[f] = zb or false
+ end
+ return f
+end
+
+function files.close(f)
+ zerobased[f] = nil
+ f:close()
+end
+
+function files.size(f)
+ local current = f:seek()
+ local size = f:seek("end")
+ f:seek("set",current)
+ return size
+end
+
+files.getsize = files.size
+
+function files.setposition(f,n)
+ if zerobased[f] then
+ f:seek("set",n)
+ else
+ f:seek("set",n - 1)
+ end
+end
+
+function files.getposition(f)
+ if zerobased[f] then
+ return f:seek()
+ else
+ return f:seek() + 1
+ end
+end
+
+function files.look(f,n,chars)
+ local p = f:seek()
+ local s = f:read(n)
+ f:seek("set",p)
+ if chars then
+ return s
+ else
+ return byte(s,1,#s)
+ end
+end
+
+function files.skip(f,n)
+ if n == 1 then
+ f:read(n)
+ else
+ f:seek("set",f:seek()+n)
+ end
+end
+
+function files.readbyte(f)
+ return byte(f:read(1))
+end
+
+function files.readbytes(f,n)
+ return byte(f:read(n),1,n)
+end
+
+function files.readbytetable(f,n)
+ -- return { byte(f:read(n),1,n) }
+ local s = f:read(n or 1)
+ return { byte(s,1,#s) } -- best use the real length
+end
+
+function files.readchar(f)
+ return f:read(1)
+end
+
+function files.readstring(f,n)
+ return f:read(n or 1)
+end
+
+function files.readinteger1(f) -- one byte
+ local n = byte(f:read(1))
+ if n >= 0x80 then
+ return n - 0x100
+ else
+ return n
+ end
+end
+
+files.readcardinal1 = files.readbyte -- one byte
+files.readcardinal = files.readcardinal1
+files.readinteger = files.readinteger1
+files.readsignedbyte = files.readinteger1
+
+function files.readcardinal2(f)
+ local a, b = byte(f:read(2),1,2)
+ return 0x100 * a + b
+end
+
+function files.readcardinal2le(f)
+ local b, a = byte(f:read(2),1,2)
+ return 0x100 * a + b
+end
+
+function files.readinteger2(f)
+ local a, b = byte(f:read(2),1,2)
+ if a >= 0x80 then
+ return 0x100 * a + b - 0x10000
+ else
+ return 0x100 * a + b
+ end
+end
+
+function files.readinteger2le(f)
+ local b, a = byte(f:read(2),1,2)
+ if a >= 0x80 then
+ return 0x100 * a + b - 0x10000
+ else
+ return 0x100 * a + b
+ end
+end
+
+function files.readcardinal3(f)
+ local a, b, c = byte(f:read(3),1,3)
+ return 0x10000 * a + 0x100 * b + c
+end
+
+function files.readcardinal3le(f)
+ local c, b, a = byte(f:read(3),1,3)
+ return 0x10000 * a + 0x100 * b + c
+end
+
+function files.readinteger3(f)
+ local a, b, c = byte(f:read(3),1,3)
+ if a >= 0x80 then
+ return 0x10000 * a + 0x100 * b + c - 0x1000000
+ else
+ return 0x10000 * a + 0x100 * b + c
+ end
+end
+
+function files.readinteger3le(f)
+ local c, b, a = byte(f:read(3),1,3)
+ if a >= 0x80 then
+ return 0x10000 * a + 0x100 * b + c - 0x1000000
+ else
+ return 0x10000 * a + 0x100 * b + c
+ end
+end
+
+function files.readcardinal4(f)
+ local a, b, c, d = byte(f:read(4),1,4)
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+end
+
+function files.readcardinal4le(f)
+ local d, c, b, a = byte(f:read(4),1,4)
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+end
+
+function files.readinteger4(f)
+ local a, b, c, d = byte(f:read(4),1,4)
+ if a >= 0x80 then
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000
+ else
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+ end
+end
+
+function files.readinteger4le(f)
+ local d, c, b, a = byte(f:read(4),1,4)
+ if a >= 0x80 then
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000
+ else
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+ end
+end
+
+-- function files.readfixed2(f)
+-- local a, b = byte(f:read(2),1,2)
+-- if a >= 0x80 then
+-- return (0x100 * a + b - 0x10000)/256.0
+-- else
+-- return (0x100 * a + b)/256.0
+-- end
+-- end
+
+function files.readfixed2(f)
+ local a, b = byte(f:read(2),1,2)
+ if a >= 0x80 then
+ return (a - 0x100) + b/0x100
+ else
+ return (a ) + b/0x100
+ end
+end
+
+-- (real) (n>>16) + ((n&0xffff)/65536.0))
+
+-- function files.readfixed4(f)
+-- local a, b, c, d = byte(f:read(4),1,4)
+-- if a >= 0x80 then
+-- return (0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000)/65536.0
+-- else
+-- return (0x1000000 * a + 0x10000 * b + 0x100 * c + d)/65536.0
+-- end
+-- end
+
+function files.readfixed4(f)
+ local a, b, c, d = byte(f:read(4),1,4)
+ if a >= 0x80 then
+ return (0x100 * a + b - 0x10000) + (0x100 * c + d)/0x10000
+ else
+ return (0x100 * a + b ) + (0x100 * c + d)/0x10000
+ end
+end
+
+-- (real) ((n<<16)>>(16+14)) + ((n&0x3fff)/16384.0))
+
+if bit32 then
+
+ local extract = bit32.extract
+ local band = bit32.band
+
+ function files.read2dot14(f)
+ local a, b = byte(f:read(2),1,2)
+ if a >= 0x80 then
+ local n = -(0x100 * a + b)
+ return - (extract(n,14,2) + (band(n,0x3FFF) / 16384.0))
+ else
+ local n = 0x100 * a + b
+ return (extract(n,14,2) + (band(n,0x3FFF) / 16384.0))
+ end
+ end
+
+end
+
+function files.skipshort(f,n)
+ f:read(2*(n or 1))
+end
+
+function files.skiplong(f,n)
+ f:read(4*(n or 1))
+end
+
+-- writers (kind of slow)
+
+if bit32 then
+
+ local rshift = bit32.rshift
+
+ function files.writecardinal2(f,n)
+ local a = char(n % 256)
+ n = rshift(n,8)
+ local b = char(n % 256)
+ f:write(b,a)
+ end
+
+else
+
+ local floor = math.floor
+
+ function files.writecardinal2(f,n)
+ local a = char(n % 256)
+ n = floor(n/256)
+ local b = char(n % 256)
+ f:write(b,a)
+ end
+
+end
+
+function files.writecardinal4(f,n)
+ local a = char(n % 256)
+ n = rshift(n,8)
+ local b = char(n % 256)
+ n = rshift(n,8)
+ local c = char(n % 256)
+ n = rshift(n,8)
+ local d = char(n % 256)
+ f:write(d,c,b,a)
+end
+
+function files.writestring(f,s)
+ f:write(char(byte(s,1,#s)))
+end
+
+function files.writebyte(f,b)
+ f:write(char(b))
+end
+
+if fio and fio.readcardinal1 then
+
+ files.readcardinal1 = fio.readcardinal1
+ files.readcardinal2 = fio.readcardinal2
+ files.readcardinal3 = fio.readcardinal3
+ files.readcardinal4 = fio.readcardinal4
+ files.readinteger1 = fio.readinteger1
+ files.readinteger2 = fio.readinteger2
+ files.readinteger3 = fio.readinteger3
+ files.readinteger4 = fio.readinteger4
+ files.readfixed2 = fio.readfixed2
+ files.readfixed4 = fio.readfixed4
+ files.read2dot14 = fio.read2dot14
+ files.setposition = fio.setposition
+ files.getposition = fio.getposition
+
+ files.readbyte = files.readcardinal1
+ files.readsignedbyte = files.readinteger1
+ files.readcardinal = files.readcardinal1
+ files.readinteger = files.readinteger1
+
+ local skipposition = fio.skipposition
+ files.skipposition = skipposition
+
+ files.readbytes = fio.readbytes
+ files.readbytetable = fio.readbytetable
+
+ function files.skipshort(f,n)
+ skipposition(f,2*(n or 1))
+ end
+
+ function files.skiplong(f,n)
+ skipposition(f,4*(n or 1))
+ end
+
+end
+
+if fio and fio.readcardinaltable then
+
+ files.readcardinaltable = fio.readcardinaltable
+ files.readintegertable = fio.readintegertable
+
+else
+
+ local readcardinal1 = files.readcardinal1
+ local readcardinal2 = files.readcardinal2
+ local readcardinal3 = files.readcardinal3
+ local readcardinal4 = files.readcardinal4
+
+ function files.readcardinaltable(f,n,b)
+ local t = { }
+ if b == 1 then for i=1,n do t[i] = readcardinal1(f) end
+ elseif b == 2 then for i=1,n do t[i] = readcardinal2(f) end
+ elseif b == 3 then for i=1,n do t[i] = readcardinal3(f) end
+ elseif b == 4 then for i=1,n do t[i] = readcardinal4(f) end end
+ return t
+ end
+
+ local readinteger1 = files.readinteger1
+ local readinteger2 = files.readinteger2
+ local readinteger3 = files.readinteger3
+ local readinteger4 = files.readinteger4
+
+ function files.readintegertable(f,n,b)
+ local t = { }
+ if b == 1 then for i=1,n do t[i] = readinteger1(f) end
+ elseif b == 2 then for i=1,n do t[i] = readinteger2(f) end
+ elseif b == 3 then for i=1,n do t[i] = readinteger3(f) end
+ elseif b == 4 then for i=1,n do t[i] = readinteger4(f) end end
+ return t
+ end
+
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-util-jsn.lua b/macros/luatex/generic/lualibs/lualibs-util-jsn.lua
new file mode 100644
index 0000000000..8da3518979
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-util-jsn.lua
@@ -0,0 +1,443 @@
+if not modules then modules = { } end modules ['util-jsn'] = {
+ version = 1.001,
+ comment = "companion to m-json.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- Of course we could make a nice complete parser with proper error messages but
+-- as json is generated programmatically errors are systematic and we can assume
+-- a correct stream. If not, we have some fatal error anyway. So, we can just rely
+-- on strings being strings (apart from the unicode escape which is not in 5.1) and
+-- as we first catch known types we just assume that anything else is a number.
+--
+-- Reminder for me: check usage in framework and extend when needed. Also document
+-- it in the cld lib documentation.
+--
+-- Upgraded for handling the somewhat more fax server templates.
+
+local P, V, R, S, C, Cc, Cs, Ct, Cf, Cg = lpeg.P, lpeg.V, lpeg.R, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cf, lpeg.Cg
+local lpegmatch = lpeg.match
+local format, gsub = string.format, string.gsub
+local formatters = string.formatters
+local utfchar = utf.char
+local concat, sortedkeys = table.concat, table.sortedkeys
+
+local tonumber, tostring, rawset, type, next = tonumber, tostring, rawset, type, next
+
+local json = utilities.json or { }
+utilities.json = json
+
+do
+
+ -- \\ \/ \b \f \n \r \t \uHHHH
+
+ local lbrace = P("{")
+ local rbrace = P("}")
+ local lparent = P("[")
+ local rparent = P("]")
+ local comma = P(",")
+ local colon = P(":")
+ local dquote = P('"')
+
+ local whitespace = lpeg.patterns.whitespace
+ local optionalws = whitespace^0
+
+ local escapes = {
+ ["b"] = "\010",
+ ["f"] = "\014",
+ ["n"] = "\n",
+ ["r"] = "\r",
+ ["t"] = "\t",
+ }
+
+ -- todo: also handle larger utf16
+
+ local escape_un = P("\\u")/"" * (C(R("09","AF","af")^-4) / function(s)
+ return utfchar(tonumber(s,16))
+ end)
+
+ local escape_bs = P([[\]]) / "" * (P(1) / escapes) -- if not found then P(1) is returned i.e. the to be escaped char
+
+ local jstring = dquote * Cs((escape_un + escape_bs + (1-dquote))^0) * dquote
+ local jtrue = P("true") * Cc(true)
+ local jfalse = P("false") * Cc(false)
+ local jnull = P("null") * Cc(nil)
+ local jnumber = (1-whitespace-rparent-rbrace-comma)^1 / tonumber
+
+ local key = jstring
+
+ local jsonconverter = { "value",
+ hash = lbrace * Cf(Ct("") * (V("pair") * (comma * V("pair"))^0 + optionalws),rawset) * rbrace,
+ pair = Cg(optionalws * key * optionalws * colon * V("value")),
+ array = Ct(lparent * (V("value") * (comma * V("value"))^0 + optionalws) * rparent),
+ -- value = optionalws * (jstring + V("hash") + V("array") + jtrue + jfalse + jnull + jnumber + #rparent) * optionalws,
+ value = optionalws * (jstring + V("hash") + V("array") + jtrue + jfalse + jnull + jnumber) * optionalws,
+ }
+
+ -- local jsonconverter = { "value",
+ -- hash = lbrace * Cf(Ct("") * (V("pair") * (comma * V("pair"))^0 + optionalws),rawset) * rbrace,
+ -- pair = Cg(optionalws * V("string") * optionalws * colon * V("value")),
+ -- array = Ct(lparent * (V("value") * (comma * V("value"))^0 + optionalws) * rparent),
+ -- string = jstring,
+ -- value = optionalws * (V("string") + V("hash") + V("array") + jtrue + jfalse + jnull + jnumber) * optionalws,
+ -- }
+
+ -- lpeg.print(jsonconverter) -- size 181
+
+ function json.tolua(str)
+ return lpegmatch(jsonconverter,str)
+ end
+
+ function json.load(filename)
+ local data = io.loaddata(filename)
+ if data then
+ return lpegmatch(jsonconverter,data)
+ end
+ end
+
+end
+
+do
+
+ -- It's pretty bad that JSON doesn't allow the trailing comma ... it's a
+ -- typical example of a spec that then forces all generators to check for
+ -- this. It's a way to make sure programmers keep jobs.
+
+ local escaper
+
+ local f_start_hash = formatters[ '%w{' ]
+ local f_start_array = formatters[ '%w[' ]
+ local f_start_hash_new = formatters[ "\n" .. '%w{' ]
+ local f_start_array_new = formatters[ "\n" .. '%w[' ]
+ local f_start_hash_key = formatters[ "\n" .. '%w"%s" : {' ]
+ local f_start_array_key = formatters[ "\n" .. '%w"%s" : [' ]
+
+ local f_stop_hash = formatters[ "\n" .. '%w}' ]
+ local f_stop_array = formatters[ "\n" .. '%w]' ]
+
+ local f_key_val_seq = formatters[ "\n" .. '%w"%s" : %s' ]
+ local f_key_val_str = formatters[ "\n" .. '%w"%s" : "%s"' ]
+ local f_key_val_num = f_key_val_seq
+ local f_key_val_yes = formatters[ "\n" .. '%w"%s" : true' ]
+ local f_key_val_nop = formatters[ "\n" .. '%w"%s" : false' ]
+ local f_key_val_null = formatters[ "\n" .. '%w"%s" : null' ]
+
+ local f_val_num = formatters[ "\n" .. '%w%s' ]
+ local f_val_str = formatters[ "\n" .. '%w"%s"' ]
+ local f_val_yes = formatters[ "\n" .. '%wtrue' ]
+ local f_val_nop = formatters[ "\n" .. '%wfalse' ]
+ local f_val_null = formatters[ "\n" .. '%wnull' ]
+ local f_val_empty = formatters[ "\n" .. '%w{ }' ]
+ local f_val_seq = f_val_num
+
+ -- no empty tables because unknown if table or hash
+
+ local t = { }
+ local n = 0
+
+ local function is_simple_table(tt) -- also used in util-tab so maybe public
+ local l = #tt
+ if l > 0 then
+ for i=1,l do
+ if type(tt[i]) == "table" then
+ return false
+ end
+ end
+ local nn = n
+ n = n + 1 t[n] = "[ "
+ for i=1,l do
+ if i > 1 then
+ n = n + 1 t[n] = ", "
+ end
+ local v = tt[i]
+ local tv = type(v)
+ if tv == "number" then
+ n = n + 1 t[n] = v
+ elseif tv == "string" then
+ n = n + 1 t[n] = '"'
+ n = n + 1 t[n] = lpegmatch(escaper,v) or v
+ n = n + 1 t[n] = '"'
+ elseif tv == "boolean" then
+ n = n + 1 t[n] = v and "true" or "false"
+ elseif v then
+ n = n + 1 t[n] = tostring(v)
+ else
+ n = n + 1 t[n] = "null"
+ end
+ end
+ n = n + 1 t[n] = " ]"
+ local s = concat(t,"",nn+1,n)
+ n = nn
+ return s
+ end
+ return false
+ end
+
+ local function tojsonpp(root,name,depth,level,size)
+ if root then
+ local indexed = size > 0
+ n = n + 1
+ if level == 0 then
+ if indexed then
+ t[n] = f_start_array(depth)
+ else
+ t[n] = f_start_hash(depth)
+ end
+ elseif name then
+ if tn == "string" then
+ name = lpegmatch(escaper,name) or name
+ elseif tn ~= "number" then
+ name = tostring(name)
+ end
+ if indexed then
+ t[n] = f_start_array_key(depth,name)
+ else
+ t[n] = f_start_hash_key(depth,name)
+ end
+ else
+ if indexed then
+ t[n] = f_start_array_new(depth)
+ else
+ t[n] = f_start_hash_new(depth)
+ end
+ end
+ depth = depth + 1
+ if indexed then -- indexed
+ for i=1,size do
+ if i > 1 then
+ n = n + 1 t[n] = ","
+ end
+ local v = root[i]
+ local tv = type(v)
+ if tv == "number" then
+ n = n + 1 t[n] = f_val_num(depth,v)
+ elseif tv == "string" then
+ v = lpegmatch(escaper,v) or v
+ n = n + 1 t[n] = f_val_str(depth,v)
+ elseif tv == "table" then
+ if next(v) then
+ local st = is_simple_table(v)
+ if st then
+ n = n + 1 t[n] = f_val_seq(depth,st)
+ else
+ tojsonpp(v,nil,depth,level+1,#v)
+ end
+ else
+ n = n + 1
+ t[n] = f_val_empty(depth)
+ end
+ elseif tv == "boolean" then
+ n = n + 1
+ if v then
+ t[n] = f_val_yes(depth,v)
+ else
+ t[n] = f_val_nop(depth,v)
+ end
+ else
+ n = n + 1
+ t[n] = f_val_null(depth)
+ end
+ end
+ elseif next(root) then
+ local sk = sortedkeys(root)
+ for i=1,#sk do
+ if i > 1 then
+ n = n + 1 t[n] = ","
+ end
+ local k = sk[i]
+ local v = root[k]
+ local tv = type(v)
+ local tk = type(k)
+ if tv == "number" then
+ if tk == "number" then
+ n = n + 1 t[n] = f_key_val_num(depth,k,v)
+ elseif tk == "string" then
+ k = lpegmatch(escaper,k) or k
+ n = n + 1 t[n] = f_key_val_num(depth,k,v)
+ end
+ elseif tv == "string" then
+ if tk == "number" then
+ v = lpegmatch(escaper,v) or v
+ n = n + 1 t[n] = f_key_val_str(depth,k,v)
+ elseif tk == "string" then
+ k = lpegmatch(escaper,k) or k
+ v = lpegmatch(escaper,v) or v
+ n = n + 1 t[n] = f_key_val_str(depth,k,v)
+ end
+ elseif tv == "table" then
+ local l = #v
+ if l > 0 then
+ local st = is_simple_table(v)
+ if not st then
+ tojsonpp(v,k,depth,level+1,l)
+ elseif tk == "number" then
+ n = n + 1 t[n] = f_key_val_seq(depth,k,st)
+ elseif tk == "string" then
+ k = lpegmatch(escaper,k) or k
+ n = n + 1 t[n] = f_key_val_seq(depth,k,st)
+ end
+ elseif next(v) then
+ tojsonpp(v,k,depth,level+1,0)
+ end
+ elseif tv == "boolean" then
+ if tk == "number" then
+ n = n + 1
+ if v then
+ t[n] = f_key_val_yes(depth,k)
+ else
+ t[n] = f_key_val_nop(depth,k)
+ end
+ elseif tk == "string" then
+ k = lpegmatch(escaper,k) or k
+ n = n + 1
+ if v then
+ t[n] = f_key_val_yes(depth,k)
+ else
+ t[n] = f_key_val_nop(depth,k)
+ end
+ end
+ else
+ if tk == "number" then
+ n = n + 1
+ t[n] = f_key_val_null(depth,k)
+ elseif tk == "string" then
+ k = lpegmatch(escaper,k) or k
+ n = n + 1
+ t[n] = f_key_val_null(depth,k)
+ end
+ end
+ end
+ end
+ n = n + 1
+ if indexed then
+ t[n] = f_stop_array(depth-1)
+ else
+ t[n] = f_stop_hash(depth-1)
+ end
+ end
+ end
+
+ local function tojson(value,n)
+ local kind = type(value)
+ if kind == "table" then
+ local done = false
+ local size = #value
+ if size == 0 then
+ for k, v in next, value do
+ if done then
+ -- n = n + 1 ; t[n] = ","
+ n = n + 1 ; t[n] = ',"'
+ else
+ -- n = n + 1 ; t[n] = "{"
+ n = n + 1 ; t[n] = '{"'
+ done = true
+ end
+ n = n + 1 ; t[n] = lpegmatch(escaper,k) or k
+ n = n + 1 ; t[n] = '":'
+ t, n = tojson(v,n)
+ end
+ if done then
+ n = n + 1 ; t[n] = "}"
+ else
+ n = n + 1 ; t[n] = "{}"
+ end
+ elseif size == 1 then
+ -- we can optimize for non tables
+ n = n + 1 ; t[n] = "["
+ t, n = tojson(value[1],n)
+ n = n + 1 ; t[n] = "]"
+ else
+ for i=1,size do
+ if done then
+ n = n + 1 ; t[n] = ","
+ else
+ n = n + 1 ; t[n] = "["
+ done = true
+ end
+ t, n = tojson(value[i],n)
+ end
+ n = n + 1 ; t[n] = "]"
+ end
+ elseif kind == "string" then
+ n = n + 1 ; t[n] = '"'
+ n = n + 1 ; t[n] = lpegmatch(escaper,value) or value
+ n = n + 1 ; t[n] = '"'
+ elseif kind == "number" then
+ n = n + 1 ; t[n] = value
+ elseif kind == "boolean" then
+ n = n + 1 ; t[n] = tostring(value)
+ else
+ n = n + 1 ; t[n] = "null"
+ end
+ return t, n
+ end
+
+ -- escaping keys can become an option
+
+ local function jsontostring(value,pretty)
+ -- todo optimize for non table
+ local kind = type(value)
+ if kind == "table" then
+ if not escaper then
+ local escapes = {
+ ["\\"] = "\\u005C",
+ ["\""] = "\\u0022",
+ }
+ for i=0,0x1F do
+ escapes[utfchar(i)] = format("\\u%04X",i)
+ end
+ escaper = Cs( (
+ (R('\0\x20') + S('\"\\')) / escapes
+ + P(1)
+ )^1 )
+
+ end
+ -- local to the closure (saves wrapping and local functions)
+ t = { }
+ n = 0
+ if pretty then
+ tojsonpp(value,name,0,0,#value)
+ value = concat(t,"",1,n)
+ else
+ t, n = tojson(value,0)
+ value = concat(t,"",1,n)
+ end
+ t = nil
+ n = 0
+ return value
+ elseif kind == "string" or kind == "number" then
+ return lpegmatch(escaper,value) or value
+ else
+ return tostring(value)
+ end
+ end
+
+ json.tostring = jsontostring
+
+ function json.tojson(value)
+ return jsontostring(value,true)
+ end
+
+end
+
+-- local tmp = [[ { "t\nt t" : "foo bar", "a" : true, "b" : [ 123 , 456E-10, { "a" : true, "b" : [ 123 , 456 ] } ] } ]]
+-- tmp = json.tolua(tmp)
+-- inspect(tmp)
+-- tmp = json.tostring(tmp,true)
+-- inspect(tmp)
+-- tmp = json.tolua(tmp)
+-- inspect(tmp)
+-- tmp = json.tostring(tmp)
+-- inspect(tmp)
+-- inspect(json.tostring(true))
+
+-- local s = [[\foo"bar"]]
+-- local j = json.tostring { s = s }
+-- local l = json.tolua(j)
+-- inspect(j)
+-- inspect(l)
+-- print(s==l.s)
+
+return json
diff --git a/macros/luatex/generic/lualibs/lualibs-util-lua.lua b/macros/luatex/generic/lualibs/lualibs-util-lua.lua
new file mode 100644
index 0000000000..f7e6e4f313
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-util-lua.lua
@@ -0,0 +1,212 @@
+if not modules then modules = { } end modules ['util-lua'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ comment = "the strip code is written by Peter Cawley",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- we will remove the 5.1 code some day soon
+
+local rep, sub, byte, dump, format = string.rep, string.sub, string.byte, string.dump, string.format
+local load, loadfile, type, collectgarbage = load, loadfile, type, collectgarbage
+
+utilities = utilities or {}
+utilities.lua = utilities.lua or { }
+local luautilities = utilities.lua
+
+local report_lua = logs.reporter("system","lua")
+local report_mem = logs.reporter("system","lua memory")
+
+local tracestripping = false
+local tracememory = false
+luautilities.stripcode = true -- support stripping when asked for
+luautilities.alwaysstripcode = false -- saves 1 meg on 7 meg compressed format file (2012.08.12)
+luautilities.nofstrippedchunks = 0
+luautilities.nofstrippedbytes = 0
+local strippedchunks = { } -- allocate()
+luautilities.strippedchunks = strippedchunks
+
+luautilities.suffixes = {
+ tma = "tma",
+ tmc = (CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 and "tmd") or (jit and "tmb") or "tmc",
+ lua = "lua",
+ luc = (CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 and "lud") or (jit and "lub") or "luc",
+ lui = "lui",
+ luv = "luv",
+ luj = "luj",
+ tua = "tua",
+ tuc = "tuc",
+}
+
+-- environment.loadpreprocessedfile can be set to a preprocessor
+
+local function register(name) -- makes no sense runtime
+ if tracestripping then
+ report_lua("stripped bytecode from %a",name or "unknown")
+ end
+ strippedchunks[#strippedchunks+1] = name
+ luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1
+end
+
+local function stupidcompile(luafile,lucfile,strip)
+ local code = io.loaddata(luafile)
+ if code and code ~= "" then
+ code = load(code)
+ if code then
+ code = dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
+ if code and code ~= "" then
+ register(name)
+ io.savedata(lucfile,code)
+ return true, 0
+ end
+ else
+ report_lua("fatal error %a in file %a",1,luafile)
+ end
+ else
+ report_lua("fatal error %a in file %a",2,luafile)
+ end
+ return false, 0
+end
+
+-- quite subtle ... doing this wrong incidentally can give more bytes
+
+function luautilities.loadedluacode(fullname,forcestrip,name,macros)
+ -- quite subtle ... doing this wrong incidentally can give more bytes
+ name = name or fullname
+ if macros then
+ macros = lua.macros
+ end
+ local code, message
+ if macros then
+ code, message = macros.loaded(fullname,true,false)
+ else
+ code, message = loadfile(fullname)
+ end
+ if code then
+ code()
+ else
+ report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
+ code, message = loadfile(fullname)
+ end
+ if forcestrip and luautilities.stripcode then
+ if type(forcestrip) == "function" then
+ forcestrip = forcestrip(fullname)
+ end
+ if forcestrip or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)), 0
+ else
+ return code, 0
+ end
+ elseif luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)), 0
+ else
+ return code, 0
+ end
+end
+
+function luautilities.strippedloadstring(code,name,forcestrip) -- not executed
+ local code, message = load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)), 0 -- not yet executed
+ else
+ return code, 0
+ end
+end
+
+function luautilities.loadstring(code,name) -- not executed
+ local code, message = load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ return code, 0
+end
+
+function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true
+ report_lua("compiling %a into %a",luafile,lucfile)
+ os.remove(lucfile)
+ local done = stupidcompile(luafile,lucfile,strip ~= false)
+ if done then
+ report_lua("dumping %a into %a stripped",luafile,lucfile)
+ if cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+ report_lua("removing %a",luafile)
+ os.remove(luafile)
+ end
+ end
+ return done
+end
+
+function luautilities.loadstripped(...)
+ local l = load(...)
+ if l then
+ return load(dump(l,true))
+ end
+end
+
+-- local getmetatable, type = getmetatable, type
+--
+-- local types = { }
+--
+-- function luautilities.registerdatatype(d,name)
+-- types[getmetatable(d)] = name
+-- end
+--
+-- function luautilities.datatype(d)
+-- local t = type(d)
+-- if t == "userdata" then
+-- local m = getmetatable(d)
+-- return m and types[m] or "userdata"
+-- else
+-- return t
+-- end
+-- end
+--
+-- luautilities.registerdatatype(lpeg.P("!"),"lpeg")
+--
+-- print(luautilities.datatype(lpeg.P("oeps")))
+
+-- These finalizers will only be invoked when we have a proper lua_close
+-- call (which is not happening in luatex tex node yes) or finish with an
+-- os.exit(n,true).
+
+local finalizers = { }
+
+setmetatable(finalizers, {
+ __gc = function(t)
+ for i=1,#t do
+ pcall(t[i]) -- let's not crash
+ end
+ end
+} )
+
+function luautilities.registerfinalizer(f)
+ finalizers[#finalizers+1] = f
+end
+
+function luautilities.checkmemory(previous,threshold,trace) -- threshold in MB
+ local current = collectgarbage("count")
+ if previous then
+ local checked = (threshold or 64)*1024
+ local delta = current - previous
+ if current - previous > checked then
+ collectgarbage("collect")
+ local afterwards = collectgarbage("count")
+ if trace or tracememory then
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
+ previous/1024,current/1024,delta/1024,threshold,afterwards)
+ end
+ return afterwards
+ elseif trace or tracememory then
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
+ previous/1024,current/1024,delta/1024,threshold)
+ end
+ end
+ return current
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-util-prs.lua b/macros/luatex/generic/lualibs/lualibs-util-prs.lua
new file mode 100644
index 0000000000..3154bf6c28
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-util-prs.lua
@@ -0,0 +1,804 @@
+if not modules then modules = { } end modules ['util-prs'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local lpeg, table, string = lpeg, table, string
+local P, R, V, S, C, Ct, Cs, Carg, Cc, Cg, Cf, Cp = lpeg.P, lpeg.R, lpeg.V, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg, lpeg.Cc, lpeg.Cg, lpeg.Cf, lpeg.Cp
+local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
+local concat, gmatch, find = table.concat, string.gmatch, string.find
+local tostring, type, next, rawset = tostring, type, next, rawset
+local mod, div = math.mod, math.div
+
+utilities = utilities or {}
+local parsers = utilities.parsers or { }
+utilities.parsers = parsers
+local patterns = parsers.patterns or { }
+parsers.patterns = patterns
+
+local setmetatableindex = table.setmetatableindex
+local sortedhash = table.sortedhash
+local sortedkeys = table.sortedkeys
+local tohash = table.tohash
+
+local hashes = { }
+parsers.hashes = hashes
+-- we share some patterns
+
+local digit = R("09")
+local space = P(' ')
+local equal = P("=")
+local colon = P(":")
+local comma = P(",")
+local lbrace = P("{")
+local rbrace = P("}")
+local lparent = P("(")
+local rparent = P(")")
+local lbracket = P("[")
+local rbracket = P("]")
+local period = S(".")
+local punctuation = S(".,:;")
+local spacer = lpegpatterns.spacer
+local whitespace = lpegpatterns.whitespace
+local newline = lpegpatterns.newline
+local anything = lpegpatterns.anything
+local endofstring = lpegpatterns.endofstring
+
+local nobrace = 1 - (lbrace + rbrace )
+local noparent = 1 - (lparent + rparent)
+local nobracket = 1 - (lbracket + rbracket)
+
+-- we could use a Cf Cg construct
+
+local escape, left, right = P("\\"), P('{'), P('}')
+
+lpegpatterns.balanced = P {
+ [1] = ((escape * (left+right)) + (1 - (left+right)) + V(2))^0,
+ [2] = left * V(1) * right
+}
+
+local nestedbraces = P { lbrace * (nobrace + V(1))^0 * rbrace }
+local nestedparents = P { lparent * (noparent + V(1))^0 * rparent }
+local nestedbrackets = P { lbracket * (nobracket + V(1))^0 * rbracket }
+local spaces = space^0
+local argument = Cs((lbrace/"") * ((nobrace + nestedbraces)^0) * (rbrace/""))
+local content = (1-endofstring)^0
+
+lpegpatterns.nestedbraces = nestedbraces -- no capture
+lpegpatterns.nestedparents = nestedparents -- no capture
+lpegpatterns.nested = nestedbraces -- no capture
+lpegpatterns.argument = argument -- argument after e.g. =
+lpegpatterns.content = content -- rest after e.g =
+
+local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace
+ + C((nestedbraces + (1-comma))^0)
+
+local key = C((1-equal-comma)^1)
+local pattern_a = (space+comma)^0 * (key * equal * value + key * C(""))
+local pattern_c = (space+comma)^0 * (key * equal * value)
+local pattern_d = (space+comma)^0 * (key * (equal+colon) * value + key * C(""))
+
+local key = C((1-space-equal-comma)^1)
+local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * value) + C("")))
+
+-- "a=1, b=2, c=3, d={a{b,c}d}, e=12345, f=xx{a{b,c}d}xx, g={}" : outer {} removes, leading spaces ignored
+
+local hash = { }
+
+local function set(key,value)
+ hash[key] = value
+end
+
+local pattern_a_s = (pattern_a/set)^1
+local pattern_b_s = (pattern_b/set)^1
+local pattern_c_s = (pattern_c/set)^1
+local pattern_d_s = (pattern_d/set)^1
+
+patterns.settings_to_hash_a = pattern_a_s
+patterns.settings_to_hash_b = pattern_b_s
+patterns.settings_to_hash_c = pattern_c_s
+patterns.settings_to_hash_d = pattern_d_s
+
+function parsers.make_settings_to_hash_pattern(set,how)
+ if how == "strict" then
+ return (pattern_c/set)^1
+ elseif how == "tolerant" then
+ return (pattern_b/set)^1
+ else
+ return (pattern_a/set)^1
+ end
+end
+
+function parsers.settings_to_hash(str,existing)
+ if not str or str == "" then
+ return { }
+ elseif type(str) == "table" then
+ if existing then
+ for k, v in next, str do
+ existing[k] = v
+ end
+ return exiting
+ else
+ return str
+ end
+ else
+ hash = existing or { }
+ lpegmatch(pattern_a_s,str)
+ return hash
+ end
+end
+
+function parsers.settings_to_hash_colon_too(str)
+ if not str or str == "" then
+ return { }
+ elseif type(str) == "table" then
+ return str
+ else
+ hash = { }
+ lpegmatch(pattern_d_s,str)
+ return hash
+ end
+end
+
+function parsers.settings_to_hash_tolerant(str,existing)
+ if not str or str == "" then
+ return { }
+ elseif type(str) == "table" then
+ if existing then
+ for k, v in next, str do
+ existing[k] = v
+ end
+ return exiting
+ else
+ return str
+ end
+ else
+ hash = existing or { }
+ lpegmatch(pattern_b_s,str)
+ return hash
+ end
+end
+
+function parsers.settings_to_hash_strict(str,existing)
+ if not str or str == "" then
+ return nil
+ elseif type(str) == "table" then
+ if existing then
+ for k, v in next, str do
+ existing[k] = v
+ end
+ return exiting
+ else
+ return str
+ end
+ elseif str and str ~= "" then
+ hash = existing or { }
+ lpegmatch(pattern_c_s,str)
+ return next(hash) and hash
+ end
+end
+
+local separator = comma * space^0
+local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace
+ + C((nestedbraces + (1-comma))^0)
+local pattern = spaces * Ct(value*(separator*value)^0)
+
+-- "aap, {noot}, mies" : outer {} removed, leading spaces ignored
+
+patterns.settings_to_array = pattern
+
+-- we could use a weak table as cache
+
+function parsers.settings_to_array(str,strict)
+ if not str or str == "" then
+ return { }
+ elseif type(str) == "table" then
+ return str
+ elseif strict then
+ if find(str,"{",1,true) then
+ return lpegmatch(pattern,str)
+ else
+ return { str }
+ end
+ elseif find(str,",",1,true) then
+ return lpegmatch(pattern,str)
+ else
+ return { str }
+ end
+end
+
+function parsers.settings_to_numbers(str)
+ if not str or str == "" then
+ return { }
+ end
+ if type(str) == "table" then
+ -- fall through
+ elseif find(str,",",1,true) then
+ str = lpegmatch(pattern,str)
+ else
+ return { tonumber(str) }
+ end
+ for i=1,#str do
+ str[i] = tonumber(str[i])
+ end
+ return str
+end
+
+local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace
+ + C((nestedbraces + nestedbrackets + nestedparents + (1-comma))^0)
+local pattern = spaces * Ct(value*(separator*value)^0)
+
+function parsers.settings_to_array_obey_fences(str)
+ return lpegmatch(pattern,str)
+end
+
+-- inspect(parsers.settings_to_array_obey_fences("url(http://a,b.c)"))
+
+-- this one also strips end spaces before separators
+--
+-- "{123} , 456 " -> "123" "456"
+
+-- local separator = space^0 * comma * space^0
+-- local value = P(lbrace * C((nobrace + nestedbraces)^0) * rbrace)
+-- + C((nestedbraces + (1-(space^0*(comma+P(-1)))))^0)
+-- local withvalue = Carg(1) * value / function(f,s) return f(s) end
+-- local pattern_a = spaces * Ct(value*(separator*value)^0)
+-- local pattern_b = spaces * withvalue * (separator*withvalue)^0
+
+local cache_a = { }
+local cache_b = { }
+
+function parsers.groupedsplitat(symbol,withaction)
+ if not symbol then
+ symbol = ","
+ end
+ local pattern = (withaction and cache_b or cache_a)[symbol]
+ if not pattern then
+ local symbols = S(symbol)
+ local separator = space^0 * symbols * space^0
+ local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace
+ + C((nestedbraces + (1-(space^0*(symbols+P(-1)))))^0)
+ if withaction then
+ local withvalue = Carg(1) * value / function(f,s) return f(s) end
+ pattern = spaces * withvalue * (separator*withvalue)^0
+ cache_b[symbol] = pattern
+ else
+ pattern = spaces * Ct(value*(separator*value)^0)
+ cache_a[symbol] = pattern
+ end
+ end
+ return pattern
+end
+
+local pattern_a = parsers.groupedsplitat(",",false)
+local pattern_b = parsers.groupedsplitat(",",true)
+
+function parsers.stripped_settings_to_array(str)
+ if not str or str == "" then
+ return { }
+ else
+ return lpegmatch(pattern_a,str)
+ end
+end
+
+function parsers.process_stripped_settings(str,action)
+ if not str or str == "" then
+ return { }
+ else
+ return lpegmatch(pattern_b,str,1,action)
+ end
+end
+
+-- parsers.process_stripped_settings("{123} , 456 ",function(s) print("["..s.."]") end)
+-- parsers.process_stripped_settings("123 , 456 ",function(s) print("["..s.."]") end)
+
+local function set(t,v)
+ t[#t+1] = v
+end
+
+local value = P(Carg(1)*value) / set
+local pattern = value*(separator*value)^0 * Carg(1)
+
+function parsers.add_settings_to_array(t,str)
+ return lpegmatch(pattern,str,nil,t)
+end
+
+function parsers.hash_to_string(h,separator,yes,no,strict,omit)
+ if h then
+ local t = { }
+ local tn = 0
+ local s = sortedkeys(h)
+ omit = omit and tohash(omit)
+ for i=1,#s do
+ local key = s[i]
+ if not omit or not omit[key] then
+ local value = h[key]
+ if type(value) == "boolean" then
+ if yes and no then
+ if value then
+ tn = tn + 1
+ t[tn] = key .. '=' .. yes
+ elseif not strict then
+ tn = tn + 1
+ t[tn] = key .. '=' .. no
+ end
+ elseif value or not strict then
+ tn = tn + 1
+ t[tn] = key .. '=' .. tostring(value)
+ end
+ else
+ tn = tn + 1
+ t[tn] = key .. '=' .. value
+ end
+ end
+ end
+ return concat(t,separator or ",")
+ else
+ return ""
+ end
+end
+
+function parsers.array_to_string(a,separator)
+ if a then
+ return concat(a,separator or ",")
+ else
+ return ""
+ end
+end
+
+-- function parsers.settings_to_set(str,t) -- tohash? -- todo: lpeg -- duplicate anyway
+-- if str then
+-- t = t or { }
+-- for s in gmatch(str,"[^, ]+") do -- space added
+-- t[s] = true
+-- end
+-- return t
+-- else
+-- return { }
+-- end
+-- end
+
+local pattern = Cf(Ct("") * Cg(C((1-S(", "))^1) * S(", ")^0 * Cc(true))^1,rawset)
+
+function parsers.settings_to_set(str)
+ return str and lpegmatch(pattern,str) or { }
+end
+
+hashes.settings_to_set = table.setmetatableindex(function(t,k) -- experiment, not public
+ local v = k and lpegmatch(pattern,k) or { }
+ t[k] = v
+ return v
+end)
+
+getmetatable(hashes.settings_to_set).__mode = "kv" -- could be an option (maybe sharing makes sense)
+
+function parsers.simple_hash_to_string(h, separator)
+ local t = { }
+ local tn = 0
+ for k, v in sortedhash(h) do
+ if v then
+ tn = tn + 1
+ t[tn] = k
+ end
+ end
+ return concat(t,separator or ",")
+end
+
+-- for mtx-context etc: aaaa bbbb cccc=dddd eeee=ffff
+
+local str = Cs(lpegpatterns.unquoted) + C((1-whitespace-equal)^1)
+local setting = Cf( Carg(1) * (whitespace^0 * Cg(str * whitespace^0 * (equal * whitespace^0 * str + Cc(""))))^1,rawset)
+local splitter = setting^1
+
+function parsers.options_to_hash(str,target)
+ return str and lpegmatch(splitter,str,1,target or { }) or { }
+end
+
+local splitter = lpeg.tsplitat(" ")
+
+function parsers.options_to_array(str)
+ return str and lpegmatch(splitter,str) or { }
+end
+
+-- for chem (currently one level)
+
+local value = P(lbrace * C((nobrace + nestedbraces)^0) * rbrace)
+ + C(digit^1 * lparent * (noparent + nestedparents)^1 * rparent)
+ + C((nestedbraces + (1-comma))^1)
+local pattern_a = spaces * Ct(value*(separator*value)^0)
+
+local function repeater(n,str)
+ if not n then
+ return str
+ else
+ local s = lpegmatch(pattern_a,str)
+ if n == 1 then
+ return unpack(s)
+ else
+ local t = { }
+ local tn = 0
+ for i=1,n do
+ for j=1,#s do
+ tn = tn + 1
+ t[tn] = s[j]
+ end
+ end
+ return unpack(t)
+ end
+ end
+end
+
+local value = P(lbrace * C((nobrace + nestedbraces)^0) * rbrace)
+ + (C(digit^1)/tonumber * lparent * Cs((noparent + nestedparents)^1) * rparent) / repeater
+ + C((nestedbraces + (1-comma))^1)
+local pattern_b = spaces * Ct(value*(separator*value)^0)
+
+function parsers.settings_to_array_with_repeat(str,expand) -- beware: "" => { }
+ if expand then
+ return lpegmatch(pattern_b,str) or { }
+ else
+ return lpegmatch(pattern_a,str) or { }
+ end
+end
+
+--
+
+local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace
+local pattern = Ct((space + value)^0)
+
+function parsers.arguments_to_table(str)
+ return lpegmatch(pattern,str)
+end
+
+-- temporary here (unoptimized)
+
+function parsers.getparameters(self,class,parentclass,settings)
+ local sc = self[class]
+ if not sc then
+ sc = { }
+ self[class] = sc
+ if parentclass then
+ local sp = self[parentclass]
+ if not sp then
+ sp = { }
+ self[parentclass] = sp
+ end
+ setmetatableindex(sc,sp)
+ end
+ end
+ parsers.settings_to_hash(settings,sc)
+end
+
+function parsers.listitem(str)
+ return gmatch(str,"[^, ]+")
+end
+
+--
+
+local pattern = Cs { "start",
+ start = V("one") + V("two") + V("three"),
+ rest = (Cc(",") * V("thousand"))^0 * (P(".") + endofstring) * anything^0,
+ thousand = digit * digit * digit,
+ one = digit * V("rest"),
+ two = digit * digit * V("rest"),
+ three = V("thousand") * V("rest"),
+}
+
+lpegpatterns.splitthousands = pattern -- maybe better in the parsers namespace ?
+
+function parsers.splitthousands(str)
+ return lpegmatch(pattern,str) or str
+end
+
+-- print(parsers.splitthousands("11111111111.11"))
+
+local optionalwhitespace = whitespace^0
+
+lpegpatterns.words = Ct((Cs((1-punctuation-whitespace)^1) + anything)^1)
+lpegpatterns.sentences = Ct((optionalwhitespace * Cs((1-period)^0 * period))^1)
+lpegpatterns.paragraphs = Ct((optionalwhitespace * Cs((whitespace^1*endofstring/"" + 1 - (spacer^0*newline*newline))^1))^1)
+
+-- local str = " Word1 word2. \n Word3 word4. \n\n Word5 word6.\n "
+-- inspect(lpegmatch(lpegpatterns.paragraphs,str))
+-- inspect(lpegmatch(lpegpatterns.sentences,str))
+-- inspect(lpegmatch(lpegpatterns.words,str))
+
+-- handy for k="v" [, ] k="v"
+
+local dquote = P('"')
+local equal = P('=')
+local escape = P('\\')
+local separator = S(' ,')
+
+local key = C((1-equal)^1)
+local value = dquote * C((1-dquote-escape*dquote)^0) * dquote
+
+----- pattern = Cf(Ct("") * Cg(key * equal * value) * separator^0,rawset)^0 * P(-1) -- was wrong
+local pattern = Cf(Ct("") * (Cg(key * equal * value) * separator^0)^1,rawset)^0 * P(-1)
+
+function parsers.keq_to_hash(str)
+ if str and str ~= "" then
+ return lpegmatch(pattern,str)
+ else
+ return { }
+ end
+end
+
+-- inspect(lpeg.match(pattern,[[key="value" foo="bar"]]))
+
+local defaultspecification = { separator = ",", quote = '"' }
+
+-- this version accepts multiple separators and quotes as used in the
+-- database module
+
+function parsers.csvsplitter(specification)
+ specification = specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator = specification.separator
+ local quotechar = specification.quote
+ local separator = S(separator ~= "" and separator or ",")
+ local whatever = C((1 - separator - newline)^0)
+ if quotechar and quotechar ~= "" then
+ local quotedata = nil
+ for chr in gmatch(quotechar,".") do
+ local quotechar = P(chr)
+ local quoteword = quotechar * C((1 - quotechar)^0) * quotechar
+ if quotedata then
+ quotedata = quotedata + quoteword
+ else
+ quotedata = quoteword
+ end
+ end
+ whatever = quotedata + whatever
+ end
+ local parser = Ct((Ct(whatever * (separator * whatever)^0) * S("\n\r")^1)^0 )
+ return function(data)
+ return lpegmatch(parser,data)
+ end
+end
+
+-- and this is a slightly patched version of a version posted by Philipp Gesang
+
+-- local mycsvsplitter = parsers.rfc4180splitter()
+
+-- local crap = [[
+-- first,second,third,fourth
+-- "1","2","3","4"
+-- "a","b","c","d"
+-- "foo","bar""baz","boogie","xyzzy"
+-- ]]
+
+-- local list, names = mycsvsplitter(crap,true) inspect(list) inspect(names)
+-- local list, names = mycsvsplitter(crap) inspect(list) inspect(names)
+
+function parsers.rfc4180splitter(specification)
+ specification = specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator = specification.separator --> rfc: COMMA
+ local quotechar = P(specification.quote) --> DQUOTE
+ local dquotechar = quotechar * quotechar --> 2DQUOTE
+ / specification.quote
+ local separator = S(separator ~= "" and separator or ",")
+ local escaped = quotechar
+ * Cs((dquotechar + (1 - quotechar))^0)
+ * quotechar
+ local non_escaped = C((1 - quotechar - newline - separator)^1)
+ local field = escaped + non_escaped + Cc("")
+ local record = Ct(field * (separator * field)^1)
+ local headerline = record * Cp()
+ local morerecords = (newline^(specification.strict and -1 or 1) * record)^0
+ local headeryes = Ct(morerecords)
+ local headernop = Ct(record * morerecords)
+ return function(data,getheader)
+ if getheader then
+ local header, position = lpegmatch(headerline,data)
+ local data = lpegmatch(headeryes,data,position)
+ return data, header
+ else
+ return lpegmatch(headernop,data)
+ end
+ end
+end
+
+-- parsers.stepper("1,7-",9,function(i) print(">>>",i) end)
+-- parsers.stepper("1-3,7,8,9")
+-- parsers.stepper("1-3,6,7",function(i) print(">>>",i) end)
+-- parsers.stepper(" 1 : 3, ,7 ")
+-- parsers.stepper("1:4,9:13,24:*",30)
+
+local function ranger(first,last,n,action)
+ if not first then
+ -- forget about it
+ elseif last == true then
+ for i=first,n or first do
+ action(i)
+ end
+ elseif last then
+ for i=first,last do
+ action(i)
+ end
+ else
+ action(first)
+ end
+end
+
+local cardinal = lpegpatterns.cardinal / tonumber
+local spacers = lpegpatterns.spacer^0
+local endofstring = lpegpatterns.endofstring
+
+local stepper = spacers * ( cardinal * ( spacers * S(":-") * spacers * ( cardinal + Cc(true) ) + Cc(false) )
+ * Carg(1) * Carg(2) / ranger * S(", ")^0 )^1
+
+local stepper = spacers * ( cardinal * ( spacers * S(":-") * spacers * ( cardinal + (P("*") + endofstring) * Cc(true) ) + Cc(false) )
+ * Carg(1) * Carg(2) / ranger * S(", ")^0 )^1 * endofstring -- we're sort of strict (could do without endofstring)
+
+function parsers.stepper(str,n,action)
+ if type(n) == "function" then
+ lpegmatch(stepper,str,1,false,n or print)
+ else
+ lpegmatch(stepper,str,1,n,action or print)
+ end
+end
+
+--
+
+local pattern_math = Cs((P("%")/"\\percent " + P("^") * Cc("{") * lpegpatterns.integer * Cc("}") + anything)^0)
+local pattern_text = Cs((P("%")/"\\percent " + (P("^")/"\\high") * Cc("{") * lpegpatterns.integer * Cc("}") + anything)^0)
+
+patterns.unittotex = pattern
+
+function parsers.unittotex(str,textmode)
+ return lpegmatch(textmode and pattern_text or pattern_math,str)
+end
+
+local pattern = Cs((P("^") / "<sup>" * lpegpatterns.integer * Cc("</sup>") + anything)^0)
+
+function parsers.unittoxml(str)
+ return lpegmatch(pattern,str)
+end
+
+-- print(parsers.unittotex("10^-32 %"),utilities.parsers.unittoxml("10^32 %"))
+
+local cache = { }
+local spaces = lpegpatterns.space^0
+local dummy = function() end
+
+setmetatableindex(cache,function(t,k)
+ local separator = P(k)
+ local value = (1-separator)^0
+ local pattern = spaces * C(value) * separator^0 * Cp()
+ t[k] = pattern
+ return pattern
+end)
+
+local commalistiterator = cache[","]
+
+function parsers.iterator(str,separator)
+ local n = #str
+ if n == 0 then
+ return dummy
+ else
+ local pattern = separator and cache[separator] or commalistiterator
+ local p = 1
+ return function()
+ if p <= n then
+ local s, e = lpegmatch(pattern,str,p)
+ if e then
+ p = e
+ return s
+ end
+ end
+ end
+ end
+end
+
+-- for s in parsers.iterator("a b c,b,c") do
+-- print(s)
+-- end
+
+local function initialize(t,name)
+ local source = t[name]
+ if source then
+ local result = { }
+ for k, v in next, t[name] do
+ result[k] = v
+ end
+ return result
+ else
+ return { }
+ end
+end
+
+local function fetch(t,name)
+ return t[name] or { }
+end
+
+local function process(result,more)
+ for k, v in next, more do
+ result[k] = v
+ end
+ return result
+end
+
+local name = C((1-S(", "))^1)
+local parser = (Carg(1) * name / initialize) * (S(", ")^1 * (Carg(1) * name / fetch))^0
+local merge = Cf(parser,process)
+
+function parsers.mergehashes(hash,list)
+ return lpegmatch(merge,list,1,hash)
+end
+
+-- local t = {
+-- aa = { alpha = 1, beta = 2, gamma = 3, },
+-- bb = { alpha = 4, beta = 5, delta = 6, },
+-- cc = { epsilon = 3 },
+-- }
+--
+-- inspect(parsers.mergehashes(t,"aa, bb, cc"))
+
+function parsers.runtime(time)
+ if not time then
+ time = os.runtime()
+ end
+ local days = div(time,24*60*60)
+ time = mod(time,24*60*60)
+ local hours = div(time,60*60)
+ time = mod(time,60*60)
+ local minutes = div(time,60)
+ local seconds = mod(time,60)
+ return days, hours, minutes, seconds
+end
+
+--
+
+local spacing = whitespace^0
+local apply = P("->")
+local method = C((1-apply)^1)
+local token = lbrace * C((1-rbrace)^1) * rbrace + C(anything^1)
+
+local pattern = spacing * (method * spacing * apply + Carg(1)) * spacing * token
+
+function parsers.splitmethod(str,default)
+ if str then
+ return lpegmatch(pattern,str,1,default or false)
+ else
+ return default or false, ""
+ end
+end
+
+-- print(parsers.splitmethod(" foo -> {bar} "))
+-- print(parsers.splitmethod("foo->{bar}"))
+-- print(parsers.splitmethod("foo->bar"))
+-- print(parsers.splitmethod("foo"))
+-- print(parsers.splitmethod("{foo}"))
+-- print(parsers.splitmethod())
+
+local p_year = lpegpatterns.digit^4 / tonumber
+
+local pattern = Cf( Ct("") *
+ (
+ ( Cg(Cc("year") * p_year)
+ * S("-/") * Cg(Cc("month") * cardinal)
+ * S("-/") * Cg(Cc("day") * cardinal)
+ ) +
+ ( Cg(Cc("day") * cardinal)
+ * S("-/") * Cg(Cc("month") * cardinal)
+ * S("-/") * Cg(Cc("year") * p_year)
+ )
+ )
+ * P(" ") * Cg(Cc("hour") * cardinal)
+ * P(":") * Cg(Cc("min") * cardinal)
+ * (P(":") * Cg(Cc("sec") * cardinal))^-1
+, rawset)
+
+lpegpatterns.splittime = pattern
+
+function parsers.totime(str)
+ return lpegmatch(pattern,str)
+end
+
+-- print(os.time(parsers.totime("2019-03-05 12:12:12")))
+-- print(os.time(parsers.totime("2019/03/05 12:12:12")))
+-- print(os.time(parsers.totime("05-03-2019 12:12:12")))
+-- print(os.time(parsers.totime("05/03/2019 12:12:12")))
diff --git a/macros/luatex/generic/lualibs/lualibs-util-sta.lua b/macros/luatex/generic/lualibs/lualibs-util-sta.lua
new file mode 100644
index 0000000000..7819395f69
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-util-sta.lua
@@ -0,0 +1,352 @@
+if not modules then modules = { } end modules ['util-sta'] = {
+ version = 1.001,
+ comment = "companion to util-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local insert, remove, fastcopy, concat = table.insert, table.remove, table.fastcopy, table.concat
+local format = string.format
+local select, tostring = select, tostring
+
+local trace_stacker = false trackers.register("stacker.resolve", function(v) trace_stacker = v end)
+
+local stacker = stacker or { }
+
+utilities.stacker = stacker
+
+local function start(s,t,first,last)
+ if s.mode == "switch" then
+ local n = tostring(t[last])
+ if trace_stacker then
+ s.report("start: %s",n)
+ end
+ return n
+ else
+ local r = { }
+ for i=first,last do
+ r[#r+1] = tostring(t[i])
+ end
+ local n = concat(r," ")
+ if trace_stacker then
+ s.report("start: %s",n)
+ end
+ return n
+ end
+end
+
+local function stop(s,t,first,last)
+ if s.mode == "switch" then
+ local n = tostring(false)
+ if trace_stacker then
+ s.report("stop: %s",n)
+ end
+ return n
+ else
+ local r = { }
+ for i=last,first,-1 do
+ r[#r+1] = tostring(false)
+ end
+ local n = concat(r," ")
+ if trace_stacker then
+ s.report("stop: %s",n)
+ end
+ return n
+ end
+end
+
+local function change(s,t1,first1,last1,t2,first2,last2)
+ if s.mode == "switch" then
+ local n = tostring(t2[last2])
+ if trace_stacker then
+ s.report("change: %s",n)
+ end
+ return n
+ else
+ local r = { }
+ for i=last1,first1,-1 do
+ r[#r+1] = tostring(false)
+ end
+ local n = concat(r," ")
+ for i=first2,last2 do
+ r[#r+1] = tostring(t2[i])
+ end
+ if trace_stacker then
+ s.report("change: %s",n)
+ end
+ return n
+ end
+end
+
+function stacker.new(name)
+
+ local report = logs.reporter("stacker",name or nil)
+
+ local s
+
+ local stack = { }
+ local list = { }
+ local ids = { }
+ local hash = { }
+
+ local hashing = true
+
+ local function push(...)
+ for i=1,select("#",...) do
+ insert(stack,(select(i,...))) -- watch the ()
+ end
+ if hashing then
+ local c = concat(stack,"|")
+ local n = hash[c]
+ if not n then
+ n = #list+1
+ hash[c] = n
+ list[n] = fastcopy(stack)
+ end
+ insert(ids,n)
+ return n
+ else
+ local n = #list+1
+ list[n] = fastcopy(stack)
+ insert(ids,n)
+ return n
+ end
+ end
+
+ local function pop()
+ remove(stack)
+ remove(ids)
+ return ids[#ids] or s.unset or -1
+ end
+
+ local function clean()
+ if #stack == 0 then
+ if trace_stacker then
+ s.report("%s list entries, %s stack entries",#list,#stack)
+ end
+ end
+ end
+
+ local tops = { }
+ local top = nil
+ local switch = nil
+
+ local function resolve_reset(mode)
+ if #tops > 0 then
+ report("resetting %s left-over states of %a",#tops,name)
+ end
+ tops = { }
+ top = nil
+ switch = nil
+ end
+
+ local function resolve_begin(mode)
+ if mode then
+ switch = mode == "switch"
+ else
+ switch = s.mode == "switch"
+ end
+ top = { switch = switch }
+ insert(tops,top)
+ end
+
+ local function resolve_step(ti) -- keep track of changes outside function !
+ -- todo: optimize for n=1 etc
+ local result = nil
+ local noftop = top and #top or 0
+ if ti > 0 then
+ local current = list[ti]
+ if current then
+ local noflist = #current
+ local nofsame = 0
+ if noflist > noftop then
+ for i=1,noflist do
+ if current[i] == top[i] then
+ nofsame = i
+ else
+ break
+ end
+ end
+ else
+ for i=1,noflist do
+ if current[i] == top[i] then
+ nofsame = i
+ else
+ break
+ end
+ end
+ end
+ local plus = nofsame + 1
+ if plus <= noftop then
+ if plus <= noflist then
+ if switch then
+ result = s.change(s,top,plus,noftop,current,nofsame,noflist)
+ else
+ result = s.change(s,top,plus,noftop,current,plus,noflist)
+ end
+ else
+ if switch then
+ result = s.change(s,top,plus,noftop,current,nofsame,noflist)
+ else
+ result = s.stop(s,top,plus,noftop)
+ end
+ end
+ elseif plus <= noflist then
+ if switch then
+ result = s.start(s,current,nofsame,noflist)
+ else
+ result = s.start(s,current,plus,noflist)
+ end
+ end
+ top = current
+ else
+ if 1 <= noftop then
+ result = s.stop(s,top,1,noftop)
+ end
+ top = { }
+ end
+ return result
+ else
+ if 1 <= noftop then
+ result = s.stop(s,top,1,noftop)
+ end
+ top = { }
+ return result
+ end
+ end
+
+ local function resolve_end()
+ -- resolve_step(s.unset)
+ if #tops > 0 then -- was #top brrr
+ local result = s.stop(s,top,1,#top)
+ remove(tops)
+ top = tops[#tops]
+ switch = top and top.switch
+ return result
+ end
+ end
+
+ local function resolve(t)
+ resolve_begin()
+ for i=1,#t do
+ resolve_step(t[i])
+ end
+ resolve_end()
+ end
+
+ s = {
+ name = name or "unknown",
+ unset = -1,
+ report = report,
+ start = start,
+ stop = stop,
+ change = change,
+ push = push,
+ pop = pop,
+ clean = clean,
+ resolve = resolve,
+ resolve_begin = resolve_begin,
+ resolve_step = resolve_step,
+ resolve_end = resolve_end,
+ resolve_reset = resolve_reset,
+ }
+
+ return s -- we can overload functions
+
+end
+
+-- local s = utilities.stacker.new("demo")
+--
+-- local unset = s.unset
+-- local push = s.push
+-- local pop = s.pop
+--
+-- local t = {
+-- unset,
+-- unset,
+-- push("a"), -- a
+-- push("b","c"), -- a b c
+-- pop(), -- a b
+-- push("d"), -- a b d
+-- pop(), -- a b
+-- unset,
+-- pop(), -- a
+-- pop(), -- b
+-- unset,
+-- unset,
+-- }
+--
+-- s.resolve(t)
+
+-- demostacker = utilities.stacker.new("demos")
+--
+-- local whatever = {
+-- one = "1 0 0 RG 1 0 0 rg",
+-- two = "1 1 0 RG 1 1 0 rg",
+-- [false] = "0 G 0 g",
+-- }
+--
+-- local concat = table.concat
+--
+-- local pageliteral = nodes.pool.pageliteral
+--
+-- function demostacker.start(s,t,first,last)
+-- local n = whatever[t[last]]
+-- -- s.report("start: %s",n)
+-- return pageliteral(n)
+-- end
+--
+-- function demostacker.stop(s,t,first,last)
+-- local n = whatever[false]
+-- -- s.report("stop: %s",n)
+-- return pageliteral(n)
+-- end
+--
+-- function demostacker.change(s,t1,first1,last1,t2,first2,last2)
+-- local n = whatever[t2[last2]]
+-- -- s.report("change: %s",n)
+-- return pageliteral(n)
+-- end
+--
+-- demostacker.mode = "switch"
+--
+-- local whatever = {
+-- one = "/OC /test1 BDC",
+-- two = "/OC /test2 BDC",
+-- [false] = "EMC",
+-- }
+--
+-- demostacker = utilities.stacker.new("demos")
+--
+-- function demostacker.start(s,t,first,last)
+-- local r = { }
+-- for i=first,last do
+-- r[#r+1] = whatever[t[i]]
+-- end
+-- -- s.report("start: %s",concat(r," "))
+-- return pageliteral(concat(r," "))
+-- end
+--
+-- function demostacker.stop(s,t,first,last)
+-- local r = { }
+-- for i=last,first,-1 do
+-- r[#r+1] = whatever[false]
+-- end
+-- -- s.report("stop: %s",concat(r," "))
+-- return pageliteral(concat(r," "))
+-- end
+--
+-- function demostacker.change(s,t1,first1,last1,t2,first2,last2)
+-- local r = { }
+-- for i=last1,first1,-1 do
+-- r[#r+1] = whatever[false]
+-- end
+-- for i=first2,last2 do
+-- r[#r+1] = whatever[t2[i]]
+-- end
+-- -- s.report("change: %s",concat(r," "))
+-- return pageliteral(concat(r," "))
+-- end
+--
+-- demostacker.mode = "stack"
diff --git a/macros/luatex/generic/lualibs/lualibs-util-sto.lua b/macros/luatex/generic/lualibs/lualibs-util-sto.lua
new file mode 100644
index 0000000000..a08d25ced1
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-util-sto.lua
@@ -0,0 +1,282 @@
+if not modules then modules = { } end modules ['util-sto'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local setmetatable, getmetatable, rawset, type = setmetatable, getmetatable, rawset, type
+
+utilities = utilities or { }
+utilities.storage = utilities.storage or { }
+local storage = utilities.storage
+
+function storage.mark(t)
+ if not t then
+ print("\nfatal error: storage cannot be marked\n")
+ os.exit()
+ return
+ end
+ local m = getmetatable(t)
+ if not m then
+ m = { }
+ setmetatable(t,m)
+ end
+ m.__storage__ = true
+ return t
+end
+
+function storage.allocate(t)
+ t = t or { }
+ local m = getmetatable(t)
+ if not m then
+ m = { }
+ setmetatable(t,m)
+ end
+ m.__storage__ = true
+ return t
+end
+
+function storage.marked(t)
+ local m = getmetatable(t)
+ return m and m.__storage__
+end
+
+function storage.checked(t)
+ if not t then
+ report("\nfatal error: storage has not been allocated\n")
+ os.exit()
+ return
+ end
+ return t
+end
+
+-- function utilities.storage.delay(parent,name,filename)
+-- local m = getmetatable(parent)
+-- m.__list[name] = filename
+-- end
+--
+-- function utilities.storage.predefine(parent)
+-- local list = { }
+-- local m = getmetatable(parent) or {
+-- __list = list,
+-- __index = function(t,k)
+-- local l = require(list[k])
+-- t[k] = l
+-- return l
+-- end
+-- }
+-- setmetatable(parent,m)
+-- end
+--
+-- bla = { }
+-- utilities.storage.predefine(bla)
+-- utilities.storage.delay(bla,"test","oepsoeps")
+-- local t = bla.test
+-- table.print(t)
+-- print(t.a)
+
+function storage.setinitializer(data,initialize)
+ local m = getmetatable(data) or { }
+ m.__index = function(data,k)
+ m.__index = nil -- so that we can access the entries during initializing
+ initialize()
+ return data[k]
+ end
+ setmetatable(data, m)
+end
+
+local keyisvalue = { __index = function(t,k)
+ t[k] = k
+ return k
+end }
+
+function storage.sparse(t)
+ t = t or { }
+ setmetatable(t,keyisvalue)
+ return t
+end
+
+-- table namespace ?
+
+local function f_empty () return "" end -- t,k
+local function f_self (t,k) t[k] = k return k end
+local function f_table (t,k) local v = { } t[k] = v return v end
+local function f_number(t,k) t[k] = 0 return 0 end -- t,k,v
+local function f_ignore() end -- t,k,v
+
+local f_index = {
+ ["empty"] = f_empty,
+ ["self"] = f_self,
+ ["table"] = f_table,
+ ["number"] = f_number,
+}
+
+function table.setmetatableindex(t,f)
+ if type(t) ~= "table" then
+ f, t = t, { }
+ end
+ local m = getmetatable(t)
+ local i = f_index[f] or f
+ if m then
+ m.__index = i
+ else
+ setmetatable(t,{ __index = i })
+ end
+ return t
+end
+
+local f_index = {
+ ["ignore"] = f_ignore,
+}
+
+function table.setmetatablenewindex(t,f)
+ if type(t) ~= "table" then
+ f, t = t, { }
+ end
+ local m = getmetatable(t)
+ local i = f_index[f] or f
+ if m then
+ m.__newindex = i
+ else
+ setmetatable(t,{ __newindex = i })
+ end
+ return t
+end
+
+function table.setmetatablecall(t,f)
+ if type(t) ~= "table" then
+ f, t = t, { }
+ end
+ local m = getmetatable(t)
+ if m then
+ m.__call = f
+ else
+ setmetatable(t,{ __call = f })
+ end
+ return t
+end
+
+-- the manual is somewhat fuzzy about this but suggests that one can best
+-- set all fields before assigning a metatable
+
+function table.setmetatableindices(t,f,n,c)
+ if type(t) ~= "table" then
+ f, t = t, { }
+ end
+ local m = getmetatable(t)
+ local i = f_index[f] or f
+ if m then
+ m.__index = i
+ m.__newindex = n
+ m.__call = c
+ else
+ setmetatable(t,{
+ __index = i,
+ __newindex = n,
+ __call = c,
+ })
+ end
+ return t
+end
+
+function table.setmetatablekey(t,key,value)
+ local m = getmetatable(t)
+ if not m then
+ m = { }
+ setmetatable(t,m)
+ end
+ m[key] = value
+ return t
+end
+
+function table.getmetatablekey(t,key,value)
+ local m = getmetatable(t)
+ return m and m[key]
+end
+
+function table.makeweak(t)
+ if not t then
+ t = { }
+ end
+ local m = getmetatable(t)
+ if m then
+ m.__mode = "v"
+ else
+ setmetatable(t,{ __mode = "v" })
+ end
+ return t
+end
+
+-- Problem: we have no __next (which is ok as it would probably slow down lua) so
+-- we cannot loop over the keys.
+
+-- local parametersets = table.autokeys()
+--
+-- parametersets.foo.bar = function(t,k) return "OEPS" end
+-- parametersets.foo.foo = "SPEO"
+-- parametersets.crap = { a = "a", b = table.autokey { function() return "b" end } }
+--
+-- print(parametersets.foo.bar)
+-- print(parametersets.foo.foo)
+-- print(parametersets.crap.b)
+-- print(parametersets.crap.b[1])
+
+-- function table.autotables(t)
+-- local t = t or { }
+-- local m = getmetatable(t)
+-- if not m then
+-- m = { }
+-- setmetatable(t,m)
+-- end
+-- m.__newindex = function(t,k,p)
+-- local v = { }
+-- local m = {
+-- __index = function(t,k)
+-- local v = p[k]
+-- if type(v) == "function" then
+-- return v(t,k) -- so we can have multiple arguments
+-- else
+-- return v
+-- end
+-- end,
+-- __newindex = function(t,k,v)
+-- p[k] = v
+-- end,
+-- __len = function(t)
+-- return #p
+-- end,
+-- }
+-- setmetatable(v,m)
+-- rawset(t,k,v)
+-- return v
+-- end
+-- m.__index = function(t,k)
+-- local v = { }
+-- t[k] = v -- calls newindex
+-- return v
+-- end
+-- return t
+-- end
+--
+-- function table.autokeys(p)
+-- local t = { }
+-- setmetatable(t, {
+-- __newindex = function(t,k,v)
+-- p[k] = v
+-- end,
+-- __index = function(t,k)
+-- local v = p[k]
+-- if type(v) == "function" then
+-- return v(t,k) -- so we can have multiple arguments
+-- else
+-- return v
+-- end
+-- end,
+-- __len = function(t)
+-- return #p
+-- end,
+-- })
+-- return t
+-- end
diff --git a/macros/luatex/generic/lualibs/lualibs-util-str.lua b/macros/luatex/generic/lualibs/lualibs-util-str.lua
new file mode 100644
index 0000000000..ad22302df0
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-util-str.lua
@@ -0,0 +1,1461 @@
+if not modules then modules = { } end modules ['util-str'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+utilities = utilities or { }
+utilities.strings = utilities.strings or { }
+local strings = utilities.strings
+
+local format, gsub, rep, sub, find = string.format, string.gsub, string.rep, string.sub, string.find
+local load, dump = load, string.dump
+local tonumber, type, tostring, next, setmetatable = tonumber, type, tostring, next, setmetatable
+local unpack, concat = table.unpack, table.concat
+local P, V, C, S, R, Ct, Cs, Cp, Carg, Cc = lpeg.P, lpeg.V, lpeg.C, lpeg.S, lpeg.R, lpeg.Ct, lpeg.Cs, lpeg.Cp, lpeg.Carg, lpeg.Cc
+local patterns, lpegmatch = lpeg.patterns, lpeg.match
+local utfchar, utfbyte, utflen = utf.char, utf.byte, utf.len
+
+----- loadstripped = utilities.lua.loadstripped
+----- setmetatableindex = table.setmetatableindex
+
+local loadstripped = function(str,shortcuts)
+ if shortcuts then
+ return load(dump(load(str),true),nil,nil,shortcuts)
+ else
+ return load(dump(load(str),true))
+ end
+end
+
+-- todo: make a special namespace for the formatter
+
+if not number then number = { } end -- temp hack for luatex-fonts
+
+local stripzero = patterns.stripzero
+local stripzeros = patterns.stripzeros
+local newline = patterns.newline
+local endofstring = patterns.endofstring
+local anything = patterns.anything
+local whitespace = patterns.whitespace
+local space = patterns.space
+local spacer = patterns.spacer
+local spaceortab = patterns.spaceortab
+local digit = patterns.digit
+local sign = patterns.sign
+local period = patterns.period
+
+-- local function points(n)
+-- n = tonumber(n)
+-- return (not n or n == 0) and "0pt" or lpegmatch(stripzeros,format("%.5fpt",n/65536))
+-- end
+
+-- local function basepoints(n)
+-- n = tonumber(n)
+-- return (not n or n == 0) and "0bp" or lpegmatch(stripzeros,format("%.5fbp", n*(7200/7227)/65536))
+-- end
+
+local ptf = 1 / 65536
+local bpf = (7200/7227) / 65536
+
+local function points(n)
+ if n == 0 then
+ return "0pt"
+ end
+ n = tonumber(n)
+ if not n or n == 0 then
+ return "0pt"
+ end
+ n = n * ptf
+ if n % 1 == 0 then
+ return format("%ipt",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fpt",n)) -- plural as we need to keep the pt
+end
+
+local function basepoints(n)
+ if n == 0 then
+ return "0pt"
+ end
+ n = tonumber(n)
+ if not n or n == 0 then
+ return "0pt"
+ end
+ n = n * bpf
+ if n % 1 == 0 then
+ return format("%ibp",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fbp",n)) -- plural as we need to keep the pt
+end
+
+number.points = points
+number.basepoints = basepoints
+
+-- str = " \n \ntest \n test\ntest "
+-- print("["..string.gsub(string.collapsecrlf(str),"\n","+").."]")
+
+local rubish = spaceortab^0 * newline
+local anyrubish = spaceortab + newline
+local stripped = (spaceortab^1 / "") * newline
+local leading = rubish^0 / ""
+local trailing = (anyrubish^1 * endofstring) / ""
+local redundant = rubish^3 / "\n"
+
+local pattern = Cs(leading * (trailing + redundant + stripped + anything)^0)
+
+function strings.collapsecrlf(str)
+ return lpegmatch(pattern,str)
+end
+
+-- The following functions might end up in another namespace.
+
+local repeaters = { } -- watch how we also moved the -1 in depth-1 to the creator
+
+function strings.newrepeater(str,offset)
+ offset = offset or 0
+ local s = repeaters[str]
+ if not s then
+ s = { }
+ repeaters[str] = s
+ end
+ local t = s[offset]
+ if t then
+ return t
+ end
+ t = { }
+ setmetatable(t, { __index = function(t,k)
+ if not k then
+ return ""
+ end
+ local n = k + offset
+ local s = n > 0 and rep(str,n) or ""
+ t[k] = s
+ return s
+ end })
+ s[offset] = t
+ return t
+end
+
+-- local dashes = strings.newrepeater("--",-1)
+-- print(dashes[2],dashes[3],dashes[1])
+
+local extra, tab, start = 0, 0, 4, 0
+
+local nspaces = strings.newrepeater(" ")
+
+string.nspaces = nspaces
+
+local pattern =
+ Carg(1) / function(t)
+ extra, tab, start = 0, t or 7, 1
+ end
+ * Cs((
+ Cp() * patterns.tab / function(position)
+ local current = (position - start + 1) + extra
+ local spaces = tab-(current-1) % tab
+ if spaces > 0 then
+ extra = extra + spaces - 1
+ return nspaces[spaces] -- rep(" ",spaces)
+ else
+ return ""
+ end
+ end
+ + newline * Cp() / function(position)
+ extra, start = 0, position
+ end
+ + anything
+ )^1)
+
+function strings.tabtospace(str,tab)
+ -- no real gain in first checking if a \t is there
+ return lpegmatch(pattern,str,1,tab or 7)
+end
+
+function string.utfpadding(s,n)
+ if not n or n == 0 then
+ return ""
+ end
+ local l = utflen(s)
+ if n > 0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
+end
+
+-- local t = {
+-- "1234567123456712345671234567",
+-- "\tb\tc",
+-- "a\tb\tc",
+-- "aa\tbb\tcc",
+-- "aaa\tbbb\tccc",
+-- "aaaa\tbbbb\tcccc",
+-- "aaaaa\tbbbbb\tccccc",
+-- "aaaaaa\tbbbbbb\tcccccc\n aaaaaa\tbbbbbb\tcccccc",
+-- "one\n two\nxxx three\nxx four\nx five\nsix",
+-- }
+-- for k=1,#t do
+-- print(strings.tabtospace(t[k]))
+-- end
+
+-- todo: lpeg
+
+-- function strings.striplong(str) -- strips all leading spaces
+-- str = gsub(str,"^%s*","")
+-- str = gsub(str,"[\n\r]+ *","\n")
+-- return str
+-- end
+
+local optionalspace = spacer^0
+local nospace = optionalspace/""
+local endofline = nospace * newline
+
+local stripend = (whitespace^1 * endofstring)/""
+
+local normalline = (nospace * ((1-optionalspace*(newline+endofstring))^1) * nospace)
+
+local stripempty = endofline^1/""
+local normalempty = endofline^1
+local singleempty = endofline * (endofline^0/"")
+local doubleempty = endofline * endofline^-1 * (endofline^0/"")
+local stripstart = stripempty^0
+
+local intospace = whitespace^1/" "
+local noleading = whitespace^1/""
+local notrailing = noleading * endofstring
+
+local p_prune_normal = Cs ( stripstart * ( stripend + normalline + normalempty )^0 )
+local p_prune_collapse = Cs ( stripstart * ( stripend + normalline + doubleempty )^0 )
+local p_prune_noempty = Cs ( stripstart * ( stripend + normalline + singleempty )^0 )
+local p_prune_intospace = Cs ( noleading * ( notrailing + intospace + 1 )^0 )
+local p_retain_normal = Cs ( ( normalline + normalempty )^0 )
+local p_retain_collapse = Cs ( ( normalline + doubleempty )^0 )
+local p_retain_noempty = Cs ( ( normalline + singleempty )^0 )
+
+-- function striplines(str,prune,collapse,noempty)
+-- if prune then
+-- if noempty then
+-- return lpegmatch(p_prune_noempty,str) or str
+-- elseif collapse then
+-- return lpegmatch(p_prune_collapse,str) or str
+-- else
+-- return lpegmatch(p_prune_normal,str) or str
+-- end
+-- else
+-- if noempty then
+-- return lpegmatch(p_retain_noempty,str) or str
+-- elseif collapse then
+-- return lpegmatch(p_retain_collapse,str) or str
+-- else
+-- return lpegmatch(p_retain_normal,str) or str
+-- end
+-- end
+-- end
+
+local striplinepatterns = {
+ ["prune"] = p_prune_normal,
+ ["prune and collapse"] = p_prune_collapse, -- default
+ ["prune and no empty"] = p_prune_noempty,
+ ["prune and to space"] = p_prune_intospace,
+ ["retain"] = p_retain_normal,
+ ["retain and collapse"] = p_retain_collapse,
+ ["retain and no empty"] = p_retain_noempty,
+ ["collapse"] = patterns.collapser,
+}
+
+setmetatable(striplinepatterns,{ __index = function(t,k) return p_prune_collapse end })
+
+strings.striplinepatterns = striplinepatterns
+
+function strings.striplines(str,how)
+ return str and lpegmatch(striplinepatterns[how],str) or str
+end
+
+function strings.collapse(str) -- maybe also in strings
+ return str and lpegmatch(p_prune_intospace,str) or str
+end
+
+-- also see: string.collapsespaces
+
+strings.striplong = strings.striplines -- for old times sake
+
+-- local str = table.concat( {
+-- " ",
+-- " aap",
+-- " noot mies",
+-- " ",
+-- " ",
+-- " zus wim jet",
+-- "zus wim jet",
+-- " zus wim jet",
+-- " ",
+-- }, "\n")
+--
+-- local str = table.concat( {
+-- " aaaa",
+-- " bb",
+-- " cccccc",
+-- " ",
+-- }, "\n")
+--
+-- for k, v in table.sortedhash(utilities.strings.striplinepatterns) do
+-- logs.report("stripper","method: %s, result: [[%s]]",k,utilities.strings.striplines(str,k))
+-- end
+
+-- inspect(strings.striplong([[
+-- aaaa
+-- bb
+-- cccccc
+-- ]]))
+
+function strings.nice(str)
+ str = gsub(str,"[:%-+_]+"," ") -- maybe more
+ return str
+end
+
+-- Work in progress. Interesting is that compared to the built-in this is faster in
+-- luatex than in luajittex where we have a comparable speed. It only makes sense
+-- to use the formatter when a (somewhat) complex format is used a lot. Each formatter
+-- is a function so there is some overhead and not all formatted output is worth that
+-- overhead. Keep in mind that there is an extra function call involved. In principle
+-- we end up with a string concatination so one could inline such a sequence but often
+-- at the cost of less readabinity. So, it's a sort of (visual) compromise. Of course
+-- there is the benefit of more variants. (Concerning the speed: a simple format like
+-- %05fpt is better off with format than with a formatter, but as soon as you put
+-- something in front formatters become faster. Passing the pt as extra argument makes
+-- formatters behave better. Of course this is rather implementation dependent. Also,
+-- when a specific format is only used a few times the overhead in creating it is not
+-- compensated by speed.)
+--
+-- More info can be found in cld-mkiv.pdf so here I stick to a simple list.
+--
+-- integer %...i number
+-- integer %...d number
+-- unsigned %...u number -- not used
+-- character %...c number
+-- hexadecimal %...x number
+-- HEXADECIMAL %...X number
+-- octal %...o number
+-- string %...s string number
+-- float %...f number
+-- checked float %...F number
+-- exponential %...e number
+-- exponential %...E number
+-- stripped e %...j number
+-- stripped E %...J number
+-- autofloat %...g number
+-- autofloat %...G number
+-- utf character %...c number
+-- force tostring %...S any
+-- force tostring %Q any
+-- force tonumber %N number (strip leading zeros)
+-- signed number %I number
+-- rounded number %r number
+-- 0xhexadecimal %...h character number
+-- 0xHEXADECIMAL %...H character number
+-- U+hexadecimal %...u character number
+-- U+HEXADECIMAL %...U character number
+-- points %p number (scaled points)
+-- basepoints %b number (scaled points)
+-- table concat %...t table
+-- table concat %{.}t table
+-- serialize %...T sequenced (no nested tables)
+-- serialize %{.}T sequenced (no nested tables)
+-- boolean (logic) %l boolean
+-- BOOLEAN %L boolean
+-- whitespace %...w number
+-- whitespace %...W (fixed)
+-- automatic %...a 'whatever' (string, table, ...)
+-- automatic %...A "whatever" (string, table, ...)
+-- zap %...z skip
+-- stripped %...N %...N
+-- comma/period real %...m
+-- period/comma real %...M
+-- formatted float %...k n.m
+
+local n = 0
+
+-- we are somewhat sloppy in parsing prefixes as it's not that critical
+
+-- hard to avoid but we can collect them in a private namespace if needed
+
+-- inline the next two makes no sense as we only use this in logging
+
+local sequenced = table.sequenced
+
+function string.autodouble(s,sep)
+ if s == nil then
+ return '""'
+ end
+ local t = type(s)
+ if t == "number" then
+ return tostring(s) -- tostring not really needed
+ end
+ if t == "table" then
+ return ('"' .. sequenced(s,sep or ",") .. '"')
+ end
+ return ('"' .. tostring(s) .. '"')
+end
+
+function string.autosingle(s,sep)
+ if s == nil then
+ return "''"
+ end
+ local t = type(s)
+ if t == "number" then
+ return tostring(s) -- tostring not really needed
+ end
+ if t == "table" then
+ return ("'" .. sequenced(s,sep or ",") .. "'")
+ end
+ return ("'" .. tostring(s) .. "'")
+end
+
+local tracedchars = { [0] =
+ -- the regular bunch
+ "[null]", "[soh]", "[stx]", "[etx]", "[eot]", "[enq]", "[ack]", "[bel]",
+ "[bs]", "[ht]", "[lf]", "[vt]", "[ff]", "[cr]", "[so]", "[si]",
+ "[dle]", "[dc1]", "[dc2]", "[dc3]", "[dc4]", "[nak]", "[syn]", "[etb]",
+ "[can]", "[em]", "[sub]", "[esc]", "[fs]", "[gs]", "[rs]", "[us]",
+ -- plus space
+ "[space]", -- 0x20
+}
+
+string.tracedchars = tracedchars
+strings.tracers = tracedchars
+
+function string.tracedchar(b)
+ -- todo: table
+ if type(b) == "number" then
+ return tracedchars[b] or (utfchar(b) .. " (U+" .. format("%05X",b) .. ")")
+ else
+ local c = utfbyte(b)
+ return tracedchars[c] or (b .. " (U+" .. (c and format("%05X",c) or "?????") .. ")")
+ end
+end
+
+function number.signed(i)
+ if i > 0 then
+ return "+", i
+ else
+ return "-", -i
+ end
+end
+
+-- maybe to util-num
+
+local two = digit * digit
+local three = two * digit
+local prefix = (Carg(1) * three)^1
+
+local splitter = Cs (
+ (((1 - (three^1 * period))^1 + C(three)) * prefix + C((1-period)^1))
+ * (anything/"" * Carg(2)) * C(2)
+)
+
+local splitter3 = Cs (
+ three * prefix * endofstring +
+ two * prefix * endofstring +
+ digit * prefix * endofstring +
+ three +
+ two +
+ digit
+)
+
+patterns.formattednumber = splitter
+
+function number.formatted(n,sep1,sep2)
+ if sep1 == false then
+ if type(n) == "number" then
+ n = tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n) == "number" then
+ n = format("%0.2f",n)
+ end
+ if sep1 == true then
+ return lpegmatch(splitter,n,1,".",",")
+ elseif sep1 == "." then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
+ elseif sep1 == "," then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
+ else
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
+ end
+ end
+end
+
+-- print(number.formatted(1))
+-- print(number.formatted(12))
+-- print(number.formatted(123))
+-- print(number.formatted(1234))
+-- print(number.formatted(12345))
+-- print(number.formatted(123456))
+-- print(number.formatted(1234567))
+-- print(number.formatted(12345678))
+-- print(number.formatted(12345678,true))
+-- print(number.formatted(1,false))
+-- print(number.formatted(12,false))
+-- print(number.formatted(123,false))
+-- print(number.formatted(1234,false))
+-- print(number.formatted(12345,false))
+-- print(number.formatted(123456,false))
+-- print(number.formatted(1234567,false))
+-- print(number.formatted(12345678,false))
+-- print(number.formatted(1234.56,"!","?"))
+
+local p = Cs(
+ P("-")^0
+ * (P("0")^1/"")^0
+ * (1-period)^0
+ * (period * P("0")^1 * endofstring/"" + period^0)
+ * P(1-P("0")^1*endofstring)^0
+ )
+
+function number.compactfloat(n,fmt)
+ if n == 0 then
+ return "0"
+ elseif n == 1 then
+ return "1"
+ end
+ n = lpegmatch(p,format(fmt or "%0.3f",n))
+ if n == "." or n == "" or n == "-" then
+ return "0"
+ end
+ return n
+end
+
+local zero = P("0")^1 / ""
+local plus = P("+") / ""
+local minus = P("-")
+local separator = period
+local trailing = zero^1 * #S("eE")
+local exponent = (S("eE") * (plus + Cs((minus * zero^0 * endofstring)/"") + minus) * zero^0 * (endofstring * Cc("0") + anything^1))
+local pattern_a = Cs(minus^0 * digit^1 * (separator/"" * trailing + separator * (trailing + digit)^0) * exponent)
+local pattern_b = Cs((exponent + anything)^0)
+
+function number.sparseexponent(f,n)
+ if not n then
+ n = f
+ f = "%e"
+ end
+ local tn = type(n)
+ if tn == "string" then -- cast to number
+ local m = tonumber(n)
+ if m then
+ return lpegmatch((f == "%e" or f == "%E") and pattern_a or pattern_b,format(f,m))
+ end
+ elseif tn == "number" then
+ return lpegmatch((f == "%e" or f == "%E") and pattern_a or pattern_b,format(f,n))
+ end
+ return tostring(n)
+end
+
+local hf = { }
+local hs = { }
+
+setmetatable(hf, { __index = function(t,k)
+ local v = "%." .. k .. "f"
+ t[k] = v
+ return v
+end } )
+
+setmetatable(hs, { __index = function(t,k)
+ local v = "%" .. k .. "s"
+ t[k] = v
+ return v
+end } )
+
+function number.formattedfloat(n,b,a)
+ local s = format(hf[a],n)
+ local l = (b or 0) + (a or 0) + 1
+ if #s < l then
+ return format(hs[l],s)
+ else
+ return s
+ end
+end
+
+local template = [[
+%s
+%s
+return function(%s) return %s end
+]]
+
+-- this might move
+
+local pattern = Cs(Cc('"') * (
+ (1-S('"\\\n\r'))^1
+ + P('"') / '\\"'
+ + P('\\') / '\\\\'
+ + P('\n') / '\\n'
+ + P('\r') / '\\r'
+)^0 * Cc('"'))
+
+patterns.escapedquotes = pattern
+
+function string.escapedquotes(s)
+ return lpegmatch(pattern,s)
+end
+
+-- print(string.escapedquotes('1\\23\n"'))
+
+-- but for now here
+
+local preamble = ""
+
+local environment = {
+ global = global or _G,
+ lpeg = lpeg,
+ type = type,
+ tostring = tostring,
+ tonumber = tonumber,
+ format = string.format,
+ concat = table.concat,
+ signed = number.signed,
+ points = number.points,
+ basepoints = number.basepoints,
+ utfchar = utf.char,
+ utfbyte = utf.byte,
+ lpegmatch = lpeg.match,
+ nspaces = string.nspaces,
+ utfpadding = string.utfpadding,
+ tracedchar = string.tracedchar,
+ autosingle = string.autosingle,
+ autodouble = string.autodouble,
+ sequenced = table.sequenced,
+ formattednumber = number.formatted,
+ sparseexponent = number.sparseexponent,
+ formattedfloat = number.formattedfloat,
+ stripzero = patterns.stripzero,
+ stripzeros = patterns.stripzeros,
+ escapedquotes = string.escapedquotes,
+
+ FORMAT = string.f9,
+}
+
+-- -- --
+
+local arguments = { "a1" } -- faster than previously used (select(n,...))
+
+setmetatable(arguments, { __index =
+ function(t,k)
+ local v = t[k-1] .. ",a" .. k
+ t[k] = v
+ return v
+ end
+})
+
+local prefix_any = C((sign + space + period + digit)^0)
+local prefix_sub = (C((sign + digit)^0) + Cc(0))
+ * period
+ * (C((sign + digit)^0) + Cc(0))
+local prefix_tab = P("{") * C((1-P("}"))^0) * P("}") + C((1-R("az","AZ","09","%%"))^0)
+
+-- we've split all cases as then we can optimize them (let's omit the fuzzy u)
+
+-- todo: replace outer formats in next by ..
+
+local format_s = function(f)
+ n = n + 1
+ if f and f ~= "" then
+ return format("format('%%%ss',a%s)",f,n)
+ else -- best no tostring in order to stay compatible (.. does a selective tostring too)
+ return format("(a%s or '')",n) -- goodie: nil check
+ end
+end
+
+local format_S = function(f) -- can be optimized
+ n = n + 1
+ if f and f ~= "" then
+ return format("format('%%%ss',tostring(a%s))",f,n)
+ else
+ return format("tostring(a%s)",n)
+ end
+end
+
+local format_right = function(f)
+ n = n + 1
+ f = tonumber(f)
+ if not f or f == 0 then
+ return format("(a%s or '')",n)
+ elseif f > 0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
+end
+
+local format_left = function(f)
+ n = n + 1
+ f = tonumber(f)
+ if not f or f == 0 then
+ return format("(a%s or '')",n)
+ end
+ if f < 0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
+end
+
+local format_q = function()
+ n = n + 1
+ -- lua 5.3 has a different q than lua 5.2 (which does a tostring on numbers)
+ -- return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
+ return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+ -- return format("(a%s ~= nil and escapedquotes(tostring(a%s)) or '')",n,n)
+end
+
+local format_Q = function() -- fast escaping
+ n = n + 1
+-- return format("format('%%q',tostring(a%s))",n)
+ return format("escapedquotes(tostring(a%s))",n)
+end
+
+local format_i = function(f)
+ n = n + 1
+ if f and f ~= "" then
+ return format("format('%%%si',a%s)",f,n)
+ else
+ return format("format('%%i',a%s)",n) -- why not just tostring()
+ end
+end
+
+local format_d = format_i
+
+local format_I = function(f)
+ n = n + 1
+ return format("format('%%s%%%si',signed(a%s))",f,n)
+end
+
+local format_f = function(f)
+ n = n + 1
+ return format("format('%%%sf',a%s)",f,n)
+end
+
+-- The next one formats an integer as integer and very small values as zero. This is needed
+-- for pdf backend code.
+--
+-- 1.23 % 1 : 0.23
+-- - 1.23 % 1 : 0.77
+--
+-- We could probably use just %s with integers but who knows what Lua 5.3 will do? So let's
+-- for the moment use %i.
+
+local format_F = function(f) -- beware, no cast to number
+ n = n + 1
+ if not f or f == "" then
+ return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
+ else
+ return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
+ end
+end
+
+-- if string.f9 then
+-- format_F = function(f) -- beware, no cast to number
+-- n = n + 1
+-- if not f or f == "" then
+-- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or FORMAT(a%s))",n,n,n,n,n)
+-- else
+-- return format("((a%s %% 1 == 0) and format('%%i',a%s) or FORMAT(a%s,'%%%sf'))",n,n,n,f)
+-- end
+-- end
+-- end
+
+local format_k = function(b,a) -- slow
+ n = n + 1
+ return format("formattedfloat(a%s,%s,%s)",n,b or 0,a or 0)
+end
+
+local format_g = function(f)
+ n = n + 1
+ return format("format('%%%sg',a%s)",f,n)
+end
+
+local format_G = function(f)
+ n = n + 1
+ return format("format('%%%sG',a%s)",f,n)
+end
+
+local format_e = function(f)
+ n = n + 1
+ return format("format('%%%se',a%s)",f,n)
+end
+
+local format_E = function(f)
+ n = n + 1
+ return format("format('%%%sE',a%s)",f,n)
+end
+
+local format_j = function(f)
+ n = n + 1
+ return format("sparseexponent('%%%se',a%s)",f,n)
+end
+
+local format_J = function(f)
+ n = n + 1
+ return format("sparseexponent('%%%sE',a%s)",f,n)
+end
+
+local format_x = function(f)
+ n = n + 1
+ return format("format('%%%sx',a%s)",f,n)
+end
+
+local format_X = function(f)
+ n = n + 1
+ return format("format('%%%sX',a%s)",f,n)
+end
+
+local format_o = function(f)
+ n = n + 1
+ return format("format('%%%so',a%s)",f,n)
+end
+
+local format_c = function()
+ n = n + 1
+ return format("utfchar(a%s)",n)
+end
+
+local format_C = function()
+ n = n + 1
+ return format("tracedchar(a%s)",n)
+end
+
+local format_r = function(f)
+ n = n + 1
+ return format("format('%%%s.0f',a%s)",f,n)
+end
+
+local format_h = function(f)
+ n = n + 1
+ if f == "-" then
+ f = sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ end
+end
+
+local format_H = function(f)
+ n = n + 1
+ if f == "-" then
+ f = sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ end
+end
+
+local format_u = function(f)
+ n = n + 1
+ if f == "-" then
+ f = sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ else
+ return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ end
+end
+
+local format_U = function(f)
+ n = n + 1
+ if f == "-" then
+ f = sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ else
+ return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ end
+end
+
+local format_p = function()
+ n = n + 1
+ return format("points(a%s)",n)
+end
+
+local format_b = function()
+ n = n + 1
+ return format("basepoints(a%s)",n)
+end
+
+local format_t = function(f)
+ n = n + 1
+ if f and f ~= "" then
+ return format("concat(a%s,%q)",n,f)
+ else
+ return format("concat(a%s)",n)
+ end
+end
+
+local format_T = function(f)
+ n = n + 1
+ if f and f ~= "" then
+ return format("sequenced(a%s,%q)",n,f)
+ else
+ return format("sequenced(a%s)",n)
+ end
+end
+
+local format_l = function()
+ n = n + 1
+ return format("(a%s and 'true' or 'false')",n)
+end
+
+local format_L = function()
+ n = n + 1
+ return format("(a%s and 'TRUE' or 'FALSE')",n)
+end
+
+local format_n = function() -- strips leading and trailing zeros and removes .0
+ n = n + 1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+end
+
+-- local format_N = function() -- strips leading and trailing zeros (also accepts string)
+-- n = n + 1
+-- return format("tostring(tonumber(a%s) or a%s)",n,n)
+-- end
+
+-- local format_N = function(f) -- strips leading and trailing zeros
+-- n = n + 1
+-- -- stripzero (singular) as we only have a number
+-- if not f or f == "" then
+-- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or ((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%.9f',a%s)))",n,n,n,n,n)
+-- else
+-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+-- end
+-- end
+
+-- local format_N = function(f) -- strips leading and trailing zeros
+-- n = n + 1
+-- -- stripzero (singular) as we only have a number
+-- if not f or f == "" then
+-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or ((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or lpegmatch(stripzero,format('%%.9f',a%s)))",n,n,n,n,n)
+-- else
+-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+-- end
+-- end
+
+local format_N = function(f) -- strips leading and trailing zeros
+ n = n + 1
+ -- stripzero (singular) as we only have a number
+ if not f or f == "" then
+ f = ".9"
+ end -- always a leading number !
+ return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+end
+
+local format_a = function(f)
+ n = n + 1
+ if f and f ~= "" then
+ return format("autosingle(a%s,%q)",n,f)
+ else
+ return format("autosingle(a%s)",n)
+ end
+end
+
+local format_A = function(f)
+ n = n + 1
+ if f and f ~= "" then
+ return format("autodouble(a%s,%q)",n,f)
+ else
+ return format("autodouble(a%s)",n)
+ end
+end
+
+local format_w = function(f) -- handy when doing depth related indent
+ n = n + 1
+ f = tonumber(f)
+ if f then -- not that useful
+ return format("nspaces[%s+a%s]",f,n) -- no real need for tonumber
+ else
+ return format("nspaces[a%s]",n) -- no real need for tonumber
+ end
+end
+
+local format_W = function(f) -- handy when doing depth related indent
+ return format("nspaces[%s]",tonumber(f) or 0)
+end
+
+local format_m = function(f)
+ n = n + 1
+ if not f or f == "" then
+ f = ","
+ end
+ if f == "0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,".")]],n,f)
+ end
+end
+
+local format_M = function(f)
+ n = n + 1
+ if not f or f == "" then
+ f = "."
+ end
+ if f == "0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,",")]],n,f)
+ end
+end
+
+--
+
+local format_z = function(f)
+ n = n + (tonumber(f) or 1)
+ return "''" -- okay, not that efficient to append '' but a special case anyway
+end
+
+--
+
+-- local strip
+--
+-- local format_Z = function(f)
+-- n = n + 1
+-- if not f or f == "" then
+-- f = ".9"
+-- end
+-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or (strip and lpegmatch(stripzero,format('%%%sf',a%s))) or format('%%%sf',a%s))",n,n,f,n,f,n)
+-- end
+--
+-- function strings.stripformatterzeros()
+-- strip = true
+-- end
+
+-- add(formatters,"texexp", [[texexp(...)]], "local texexp = metapost.texexp")
+--
+-- add(formatters,"foo:bar",[[foo(...)]], { foo = function(...) print(...) return "!" end })
+-- print(string.formatters["foo %3!foo:bar! bar"](1,2,3))
+
+
+local format_rest = function(s)
+ return format("%q",s) -- catches " and \n and such
+end
+
+-- local format_extension = function(extensions,f,name)
+-- local extension = extensions[name] or "tostring(%s)"
+-- local f = tonumber(f) or 1
+-- local w = find(extension,"%.%.%.")
+-- if f == 0 then
+-- if w then
+-- extension = gsub(extension,"%.%.%.","")
+-- end
+-- return extension
+-- elseif f == 1 then
+-- if w then
+-- extension = gsub(extension,"%.%.%.","%%s")
+-- end
+-- n = n + 1
+-- local a = "a" .. n
+-- return format(extension,a,a) -- maybe more times?
+-- elseif f < 0 then
+-- local a = "a" .. (n + f + 1)
+-- return format(extension,a,a)
+-- else
+-- if w then
+-- extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+-- end
+-- -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
+-- -- cache we don't save much and there are hardly any extensions anyway
+-- local t = { }
+-- for i=1,f do
+-- n = n + 1
+-- -- t[#t+1] = "a" .. n
+-- t[i] = "a" .. n
+-- end
+-- return format(extension,unpack(t))
+-- end
+-- end
+
+local format_extension = function(extensions,f,name)
+ local extension = extensions[name] or "tostring(%s)"
+ local f = tonumber(f) or 1
+ local w = find(extension,"%.%.%.")
+ if w then
+ -- we have a wildcard
+ if f == 0 then
+ extension = gsub(extension,"%.%.%.","")
+ return extension
+ elseif f == 1 then
+ extension = gsub(extension,"%.%.%.","%%s")
+ n = n + 1
+ local a = "a" .. n
+ return format(extension,a,a) -- maybe more times?
+ elseif f < 0 then
+ local a = "a" .. (n + f + 1)
+ return format(extension,a,a)
+ else
+ extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+ -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
+ -- cache we don't save much and there are hardly any extensions anyway
+ local t = { }
+ for i=1,f do
+ n = n + 1
+ -- t[#t+1] = "a" .. n
+ t[i] = "a" .. n
+ end
+ return format(extension,unpack(t))
+ end
+ else
+ extension = gsub(extension,"%%s",function()
+ n = n + 1
+ return "a" .. n
+ end)
+ return extension
+ end
+end
+
+-- aA b cC d eE f gG hH iI jJ lL mM N o p qQ r sS tT uU wW xX z
+
+-- extensions : %!tag!
+
+-- can be made faster but not called that often
+
+local builder = Cs { "start",
+ start = (
+ (
+ P("%") / ""
+ * (
+ V("!") -- new
+ + V("s") + V("q")
+ + V("i") + V("d")
+ + V("f") + V("F") + V("g") + V("G") + V("e") + V("E")
+ + V("x") + V("X") + V("o")
+ --
+ + V("c")
+ + V("C")
+ + V("S") -- new
+ + V("Q") -- new
+ + V("n") -- new
+ + V("N") -- new
+ + V("k") -- new
+ --
+ + V("r")
+ + V("h") + V("H") + V("u") + V("U")
+ + V("p") + V("b")
+ + V("t") + V("T")
+ + V("l") + V("L")
+ + V("I")
+ + V("w") -- new
+ + V("W") -- new
+ + V("a") -- new
+ + V("A") -- new
+ + V("j") + V("J") -- stripped e E
+ + V("m") + V("M") -- new (formatted number)
+ + V("z") -- new
+ --
+ + V(">") -- left padding
+ + V("<") -- right padding
+ --
+ -- + V("?") -- ignored, probably messed up %
+ )
+ + V("*")
+ )
+ * (endofstring + Carg(1))
+ )^0,
+ --
+ ["s"] = (prefix_any * P("s")) / format_s, -- %s => regular %s (string)
+ ["q"] = (prefix_any * P("q")) / format_q, -- %q => regular %q (quoted string)
+ ["i"] = (prefix_any * P("i")) / format_i, -- %i => regular %i (integer)
+ ["d"] = (prefix_any * P("d")) / format_d, -- %d => regular %d (integer)
+ ["f"] = (prefix_any * P("f")) / format_f, -- %f => regular %f (float)
+ ["F"] = (prefix_any * P("F")) / format_F, -- %F => regular %f (float) but 0/1 check
+ ["g"] = (prefix_any * P("g")) / format_g, -- %g => regular %g (float)
+ ["G"] = (prefix_any * P("G")) / format_G, -- %G => regular %G (float)
+ ["e"] = (prefix_any * P("e")) / format_e, -- %e => regular %e (float)
+ ["E"] = (prefix_any * P("E")) / format_E, -- %E => regular %E (float)
+ ["x"] = (prefix_any * P("x")) / format_x, -- %x => regular %x (hexadecimal)
+ ["X"] = (prefix_any * P("X")) / format_X, -- %X => regular %X (HEXADECIMAL)
+ ["o"] = (prefix_any * P("o")) / format_o, -- %o => regular %o (octal)
+ --
+ ["S"] = (prefix_any * P("S")) / format_S, -- %S => %s (tostring)
+ ["Q"] = (prefix_any * P("Q")) / format_Q, -- %Q => %q (tostring)
+ ["n"] = (prefix_any * P("n")) / format_n, -- %n => tonumber (strips leading and trailing zeros, as well as .0, expects number)
+ ["N"] = (prefix_any * P("N")) / format_N, -- %N => tonumber (strips leading and trailing zeros, also takes string)
+ ["k"] = (prefix_sub * P("k")) / format_k, -- %k => like f but with n.m
+ ["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular)
+ ["C"] = (prefix_any * P("C")) / format_C, -- %c => U+.... utf character
+ --
+ ["r"] = (prefix_any * P("r")) / format_r, -- %r => round
+ ["h"] = (prefix_any * P("h")) / format_h, -- %h => 0x0a1b2 (when - no 0x) was v
+ ["H"] = (prefix_any * P("H")) / format_H, -- %H => 0x0A1B2 (when - no 0x) was V
+ ["u"] = (prefix_any * P("u")) / format_u, -- %u => u+0a1b2 (when - no u+)
+ ["U"] = (prefix_any * P("U")) / format_U, -- %U => U+0A1B2 (when - no U+)
+ ["p"] = (prefix_any * P("p")) / format_p, -- %p => 12.345pt / maybe: P (and more units)
+ ["b"] = (prefix_any * P("b")) / format_b, -- %b => 12.342bp / maybe: B (and more units)
+ ["t"] = (prefix_tab * P("t")) / format_t, -- %t => concat
+ ["T"] = (prefix_tab * P("T")) / format_T, -- %t => sequenced
+ ["l"] = (prefix_any * P("l")) / format_l, -- %l => boolean
+ ["L"] = (prefix_any * P("L")) / format_L, -- %L => BOOLEAN
+ ["I"] = (prefix_any * P("I")) / format_I, -- %I => signed integer
+ --
+ ["w"] = (prefix_any * P("w")) / format_w, -- %w => n spaces (optional prefix is added)
+ ["W"] = (prefix_any * P("W")) / format_W, -- %W => mandate prefix, no specifier
+ --
+ ["j"] = (prefix_any * P("j")) / format_j, -- %j => %e (float) stripped exponent (irrational)
+ ["J"] = (prefix_any * P("J")) / format_J, -- %J => %E (float) stripped exponent (irrational)
+ --
+ ["m"] = (prefix_any * P("m")) / format_m, -- %m => xxx.xxx.xxx,xx (optional prefix instead of .)
+ ["M"] = (prefix_any * P("M")) / format_M, -- %M => xxx,xxx,xxx.xx (optional prefix instead of ,)
+ --
+ ["z"] = (prefix_any * P("z")) / format_z, -- %z => skip n arguments
+ -- ["Z"] = (prefix_any * P("Z")) / format_Z, -- %Z => optionally strip zeros
+ --
+ ["a"] = (prefix_any * P("a")) / format_a, -- %a => '...' (forces tostring)
+ ["A"] = (prefix_any * P("A")) / format_A, -- %A => "..." (forces tostring)
+ --
+ ["<"] = (prefix_any * P("<")) / format_left,
+ [">"] = (prefix_any * P(">")) / format_right,
+ --
+ ["*"] = Cs(((1-P("%"))^1 + P("%%")/"%%")^1) / format_rest, -- rest (including %%)
+ ["?"] = Cs(((1-P("%"))^1 )^1) / format_rest, -- rest (including %%)
+ --
+ ["!"] = Carg(2) * prefix_any * P("!") * C((1-P("!"))^1) * P("!") / format_extension,
+}
+
+-- We can be clever and only alias what is needed:
+
+local xx = setmetatable({ }, { __index = function(t,k) local v = format("%02x",k) t[k] = v return v end })
+local XX = setmetatable({ }, { __index = function(t,k) local v = format("%02X",k) t[k] = v return v end })
+
+local preset = {
+ ["%02x"] = function(n) return xx[n] end,
+ ["%02X"] = function(n) return XX[n] end,
+}
+
+local direct =
+ P("%") * (sign + space + period + digit)^0 * S("sqidfgGeExXo") * endofstring
+ / [[local format = string.format return function(str) return format("%0",str) end]]
+
+local function make(t,str)
+ local f = preset[str]
+ if f then
+ return f
+ end
+ local p = lpegmatch(direct,str)
+ if p then
+ -- print("builder 1 >",p)
+ f = loadstripped(p)()
+ else
+ n = 0 -- used in patterns
+ -- p = lpegmatch(builder,str,1,"..",t._extensions_) -- after this we know n
+ p = lpegmatch(builder,str,1,t._connector_,t._extensions_) -- after this we know n
+ if n > 0 then
+ p = format(template,preamble,t._preamble_,arguments[n],p)
+ -- print("builder 2 >",p)
+ f = loadstripped(p,t._environment_)() -- t._environment is not populated (was experiment)
+ else
+ f = function() return str end
+ end
+ end
+ -- if jit then jit.on(f,true) end
+ t[str] = f
+ return f
+end
+
+-- -- collect periodically
+--
+-- local threshold = 1000 -- max nof cached formats
+--
+-- local function make(t,str)
+-- local f = rawget(t,str)
+-- if f then
+-- return f
+-- end
+-- local parent = t._t_
+-- if parent._n_ > threshold then
+-- local m = { _t_ = parent }
+-- getmetatable(parent).__index = m
+-- setmetatable(m, { __index = make })
+-- else
+-- parent._n_ = parent._n_ + 1
+-- end
+-- local f
+-- local p = lpegmatch(direct,str)
+-- if p then
+-- f = loadstripped(p)()
+-- else
+-- n = 0
+-- p = lpegmatch(builder,str,1,"..",parent._extensions_) -- after this we know n
+-- if n > 0 then
+-- p = format(template,preamble,parent._preamble_,arguments[n],p)
+-- -- print("builder>",p)
+-- f = loadstripped(p)()
+-- else
+-- f = function() return str end
+-- end
+-- end
+-- t[str] = f
+-- return f
+-- end
+
+local function use(t,fmt,...)
+ return t[fmt](...)
+end
+
+strings.formatters = { }
+
+-- we cannot make these tables weak, unless we start using an indirect
+-- table (metatable) in which case we could better keep a count and
+-- clear that table when a threshold is reached
+
+-- _connector_ is an experiment
+
+function strings.formatters.new(noconcat)
+ local e = { } -- better make a copy as we can overload
+ for k, v in next, environment do
+ e[k] = v
+ end
+ local t = {
+ _type_ = "formatter",
+ _connector_ = noconcat and "," or "..",
+ _extensions_ = { },
+ _preamble_ = "",
+ _environment_ = e,
+ }
+ setmetatable(t, { __index = make, __call = use })
+ return t
+end
+
+local formatters = strings.formatters.new() -- the default instance
+
+string.formatters = formatters -- in the main string namespace
+string.formatter = function(str,...) return formatters[str](...) end -- sometimes nicer name
+
+local function add(t,name,template,preamble)
+ if type(t) == "table" and t._type_ == "formatter" then
+ t._extensions_[name] = template or "%s"
+ if type(preamble) == "string" then
+ t._preamble_ = preamble .. "\n" .. t._preamble_ -- so no overload !
+ elseif type(preamble) == "table" then
+ for k, v in next, preamble do
+ t._environment_[k] = v
+ end
+ end
+ end
+end
+
+strings.formatters.add = add
+
+-- registered in the default instance (should we fall back on this one?)
+
+patterns.xmlescape = Cs((P("<")/"&lt;" + P(">")/"&gt;" + P("&")/"&amp;" + P('"')/"&quot;" + anything)^0)
+patterns.texescape = Cs((C(S("#$%\\{}"))/"\\%1" + anything)^0)
+patterns.luaescape = Cs(((1-S('"\n'))^1 + P('"')/'\\"' + P('\n')/'\\n"')^0) -- maybe also \0
+patterns.luaquoted = Cs(Cc('"') * ((1-S('"\n'))^1 + P('"')/'\\"' + P('\n')/'\\n"')^0 * Cc('"'))
+
+-- escaping by lpeg is faster for strings without quotes, slower on a string with quotes, but
+-- faster again when other q-escapables are found (the ones we don't need to escape)
+
+add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape = patterns.xmlescape })
+add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape = patterns.texescape })
+add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape = patterns.luaescape })
+
+-- -- yes or no:
+--
+-- local function make(t,str)
+-- local f
+-- local p = lpegmatch(direct,str)
+-- if p then
+-- f = loadstripped(p)()
+-- else
+-- n = 0
+-- p = lpegmatch(builder,str,1,",") -- after this we know n
+-- if n > 0 then
+-- p = format(template,template_shortcuts,arguments[n],p)
+-- f = loadstripped(p)()
+-- else
+-- f = function() return str end
+-- end
+-- end
+-- t[str] = f
+-- return f
+-- end
+--
+-- local formatteds = string.formatteds or { }
+-- string.formatteds = formatteds
+--
+-- setmetatable(formatteds, { __index = make, __call = use })
+
+-- This is a somewhat silly one used in commandline reconstruction but the older
+-- method, using a combination of fine, gsub, quoted and unquoted was not that
+-- reliable.
+--
+-- '"foo"bar \"and " whatever"' => "foo\"bar \"and \" whatever"
+-- 'foo"bar \"and " whatever' => "foo\"bar \"and \" whatever"
+
+local dquote = patterns.dquote -- P('"')
+local equote = patterns.escaped + dquote / '\\"' + 1
+local cquote = Cc('"')
+
+local pattern =
+ Cs(dquote * (equote - P(-2))^0 * dquote) -- we keep the outer but escape unescaped ones
+ + Cs(cquote * (equote - space)^0 * space * equote^0 * cquote) -- we escape unescaped ones
+
+function string.optionalquoted(str)
+ return lpegmatch(pattern,str) or str
+end
+
+local pattern = Cs((newline / (os.newline or "\r") + 1)^0)
+
+function string.replacenewlines(str)
+ return lpegmatch(pattern,str)
+end
+
+--
+
+function strings.newcollector()
+ local result, r = { }, 0
+ return
+ function(fmt,str,...) -- write
+ r = r + 1
+ result[r] = str == nil and fmt or formatters[fmt](str,...)
+ end,
+ function(connector) -- flush
+ if result then
+ local str = concat(result,connector)
+ result, r = { }, 0
+ return str
+ end
+ end
+end
+
+--
+
+local f_16_16 = formatters["%0.5N"]
+
+function number.to16dot16(n)
+ return f_16_16(n/65536.0)
+end
+
+--
+
+if not string.explode then
+
+ local tsplitat = lpeg.tsplitat
+
+ local p_utf = patterns.utf8character
+ local p_check = C(p_utf) * (P("+") * Cc(true))^0
+ local p_split = Ct(C(p_utf)^0)
+ local p_space = Ct((C(1-P(" ")^1) + P(" ")^1)^0)
+
+ function string.explode(str,symbol)
+ if symbol == "" then
+ return lpegmatch(p_split,str)
+ elseif symbol then
+ local a, b = lpegmatch(p_check,symbol)
+ if b then
+ return lpegmatch(tsplitat(P(a)^1),str)
+ else
+ return lpegmatch(tsplitat(a),str)
+ end
+ else
+ return lpegmatch(p_space,str)
+ end
+ end
+
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-util-tab.lua b/macros/luatex/generic/lualibs/lualibs-util-tab.lua
new file mode 100644
index 0000000000..f970d8ace0
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-util-tab.lua
@@ -0,0 +1,874 @@
+if not modules then modules = { } end modules ['util-tab'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+utilities = utilities or {}
+utilities.tables = utilities.tables or { }
+local tables = utilities.tables
+
+local format, gmatch, gsub, sub = string.format, string.gmatch, string.gsub, string.sub
+local concat, insert, remove, sort = table.concat, table.insert, table.remove, table.sort
+local setmetatable, getmetatable, tonumber, tostring, rawget = setmetatable, getmetatable, tonumber, tostring, rawget
+local type, next, rawset, tonumber, tostring, load, select = type, next, rawset, tonumber, tostring, load, select
+local lpegmatch, P, Cs, Cc = lpeg.match, lpeg.P, lpeg.Cs, lpeg.Cc
+local sortedkeys, sortedpairs = table.sortedkeys, table.sortedpairs
+local formatters = string.formatters
+local utftoeight = utf.toeight
+
+local splitter = lpeg.tsplitat(".")
+
+function utilities.tables.definetable(target,nofirst,nolast) -- defines undefined tables
+ local composed = nil
+ local t = { }
+ local snippets = lpegmatch(splitter,target)
+ for i=1,#snippets - (nolast and 1 or 0) do
+ local name = snippets[i]
+ if composed then
+ composed = composed .. "." .. name
+ t[#t+1] = formatters["if not %s then %s = { } end"](composed,composed)
+ else
+ composed = name
+ if not nofirst then
+ t[#t+1] = formatters["%s = %s or { }"](composed,composed)
+ end
+ end
+ end
+ if composed then
+ if nolast then
+ composed = composed .. "." .. snippets[#snippets]
+ end
+ return concat(t,"\n"), composed -- could be shortcut
+ else
+ return "", target
+ end
+end
+
+-- local t = tables.definedtable("a","b","c","d")
+
+function tables.definedtable(...)
+ local t = _G
+ for i=1,select("#",...) do
+ local li = select(i,...)
+ local tl = t[li]
+ if not tl then
+ tl = { }
+ t[li] = tl
+ end
+ t = tl
+ end
+ return t
+end
+
+function tables.accesstable(target,root)
+ local t = root or _G
+ for name in gmatch(target,"([^%.]+)") do
+ t = t[name]
+ if not t then
+ return
+ end
+ end
+ return t
+end
+
+function tables.migratetable(target,v,root)
+ local t = root or _G
+ local names = lpegmatch(splitter,target)
+ for i=1,#names-1 do
+ local name = names[i]
+ t[name] = t[name] or { }
+ t = t[name]
+ if not t then
+ return
+ end
+ end
+ t[names[#names]] = v
+end
+
+function tables.removevalue(t,value) -- todo: n
+ if value then
+ for i=1,#t do
+ if t[i] == value then
+ remove(t,i)
+ -- remove all, so no: return
+ end
+ end
+ end
+end
+
+function tables.replacevalue(t,oldvalue,newvalue)
+ if oldvalue and newvalue then
+ for i=1,#t do
+ if t[i] == oldvalue then
+ t[i] = newvalue
+ -- replace all, so no: return
+ end
+ end
+ end
+end
+
+function tables.insertbeforevalue(t,value,extra)
+ for i=1,#t do
+ if t[i] == extra then
+ remove(t,i)
+ end
+ end
+ for i=1,#t do
+ if t[i] == value then
+ insert(t,i,extra)
+ return
+ end
+ end
+ insert(t,1,extra)
+end
+
+function tables.insertaftervalue(t,value,extra)
+ for i=1,#t do
+ if t[i] == extra then
+ remove(t,i)
+ end
+ end
+ for i=1,#t do
+ if t[i] == value then
+ insert(t,i+1,extra)
+ return
+ end
+ end
+ insert(t,#t+1,extra)
+end
+
+-- experimental
+
+local escape = Cs(Cc('"') * ((P('"')/'""' + P(1))^0) * Cc('"'))
+
+function table.tocsv(t,specification)
+ if t and #t > 0 then
+ local result = { }
+ local r = { }
+ specification = specification or { }
+ local fields = specification.fields
+ if type(fields) ~= "string" then
+ fields = sortedkeys(t[1])
+ end
+ local separator = specification.separator or ","
+ local noffields = #fields
+ if specification.preamble == true then
+ for f=1,noffields do
+ r[f] = lpegmatch(escape,tostring(fields[f]))
+ end
+ result[1] = concat(r,separator)
+ end
+ for i=1,#t do
+ local ti = t[i]
+ for f=1,noffields do
+ local field = ti[fields[f]]
+ if type(field) == "string" then
+ r[f] = lpegmatch(escape,field)
+ else
+ r[f] = tostring(field)
+ end
+ end
+ -- result[#result+1] = concat(r,separator)
+ result[i+1] = concat(r,separator)
+ end
+ return concat(result,"\n")
+ else
+ return ""
+ end
+end
+
+-- local nspaces = utilities.strings.newrepeater(" ")
+-- local escape = Cs((P("<")/"&lt;" + P(">")/"&gt;" + P("&")/"&amp;" + P(1))^0)
+--
+-- local function toxml(t,d,result,step)
+-- for k, v in sortedpairs(t) do
+-- local s = nspaces[d]
+-- local tk = type(k)
+-- local tv = type(v)
+-- if tv == "table" then
+-- if tk == "number" then
+-- result[#result+1] = format("%s<entry n='%s'>",s,k)
+-- toxml(v,d+step,result,step)
+-- result[#result+1] = format("%s</entry>",s,k)
+-- else
+-- result[#result+1] = format("%s<%s>",s,k)
+-- toxml(v,d+step,result,step)
+-- result[#result+1] = format("%s</%s>",s,k)
+-- end
+-- elseif tv == "string" then
+-- if tk == "number" then
+-- result[#result+1] = format("%s<entry n='%s'>%s</entry>",s,k,lpegmatch(escape,v),k)
+-- else
+-- result[#result+1] = format("%s<%s>%s</%s>",s,k,lpegmatch(escape,v),k)
+-- end
+-- elseif tk == "number" then
+-- result[#result+1] = format("%s<entry n='%s'>%s</entry>",s,k,tostring(v),k)
+-- else
+-- result[#result+1] = format("%s<%s>%s</%s>",s,k,tostring(v),k)
+-- end
+-- end
+-- end
+--
+-- much faster
+
+local nspaces = utilities.strings.newrepeater(" ")
+
+local function toxml(t,d,result,step)
+ local r = #result
+ for k, v in sortedpairs(t) do
+ local s = nspaces[d] -- inlining this is somewhat faster but gives more formatters
+ local tk = type(k)
+ local tv = type(v)
+ if tv == "table" then
+ if tk == "number" then
+ r = r + 1 result[r] = formatters["%s<entry n='%s'>"](s,k)
+ toxml(v,d+step,result,step)
+ r = r + 1 result[r] = formatters["%s</entry>"](s,k)
+ else
+ r = r + 1 result[r] = formatters["%s<%s>"](s,k)
+ toxml(v,d+step,result,step)
+ r = r + 1 result[r] = formatters["%s</%s>"](s,k)
+ end
+ elseif tv == "string" then
+ if tk == "number" then
+ r = r + 1 result[r] = formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
+ else
+ r = r + 1 result[r] = formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
+ end
+ elseif tk == "number" then
+ r = r + 1 result[r] = formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
+ else
+ r = r + 1 result[r] = formatters["%s<%s>%S</%s>"](s,k,v,k)
+ end
+ end
+end
+
+-- function table.toxml(t,name,nobanner,indent,spaces)
+-- local noroot = name == false
+-- local result = (nobanner or noroot) and { } or { "<?xml version='1.0' standalone='yes' ?>" }
+-- local indent = rep(" ",indent or 0)
+-- local spaces = rep(" ",spaces or 1)
+-- if noroot then
+-- toxml( t, inndent, result, spaces)
+-- else
+-- toxml( { [name or "root"] = t }, indent, result, spaces)
+-- end
+-- return concat(result,"\n")
+-- end
+
+function table.toxml(t,specification)
+ specification = specification or { }
+ local name = specification.name
+ local noroot = name == false
+ local result = (specification.nobanner or noroot) and { } or { "<?xml version='1.0' standalone='yes' ?>" }
+ local indent = specification.indent or 0
+ local spaces = specification.spaces or 1
+ if noroot then
+ toxml( t, indent, result, spaces)
+ else
+ toxml( { [name or "data"] = t }, indent, result, spaces)
+ end
+ return concat(result,"\n")
+end
+
+-- also experimental
+
+-- encapsulate(table,utilities.tables)
+-- encapsulate(table,utilities.tables,true)
+-- encapsulate(table,true)
+
+function tables.encapsulate(core,capsule,protect)
+ if type(capsule) ~= "table" then
+ protect = true
+ capsule = { }
+ end
+ for key, value in next, core do
+ if capsule[key] then
+ print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
+ os.exit()
+ else
+ capsule[key] = value
+ end
+ end
+ if protect then
+ for key, value in next, core do
+ core[key] = nil
+ end
+ setmetatable(core, {
+ __index = capsule,
+ __newindex = function(t,key,value)
+ if capsule[key] then
+ print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
+ os.exit()
+ else
+ rawset(t,key,value)
+ end
+ end
+ } )
+ end
+end
+
+-- best keep [%q] keys (as we have some in older applications i.e. saving user data (otherwise
+-- we also need to check for reserved words)
+
+local f_hashed_string = formatters["[%Q]=%Q,"]
+local f_hashed_number = formatters["[%Q]=%s,"]
+local f_hashed_boolean = formatters["[%Q]=%l,"]
+local f_hashed_table = formatters["[%Q]="]
+
+local f_indexed_string = formatters["[%s]=%Q,"]
+local f_indexed_number = formatters["[%s]=%s,"]
+local f_indexed_boolean = formatters["[%s]=%l,"]
+local f_indexed_table = formatters["[%s]="]
+
+local f_ordered_string = formatters["%Q,"]
+local f_ordered_number = formatters["%s,"]
+local f_ordered_boolean = formatters["%l,"]
+
+function table.fastserialize(t,prefix) -- todo, move local function out
+
+ -- prefix should contain the =
+ -- not sorted
+ -- only number and string indices (currently)
+
+ local r = { type(prefix) == "string" and prefix or "return" }
+ local m = 1
+ local function fastserialize(t,outer) -- no mixes
+ local n = #t
+ m = m + 1
+ r[m] = "{"
+ if n > 0 then
+ for i=0,n do
+ local v = t[i]
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_ordered_string(v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_ordered_number(v)
+ elseif tv == "table" then
+ fastserialize(v)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_ordered_boolean(v)
+ end
+ end
+ end
+ for k, v in next, t do
+ local tk = type(k)
+ if tk == "number" then
+ if k > n or k < 0 then
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_indexed_string(k,v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_indexed_number(k,v)
+ elseif tv == "table" then
+ m = m + 1 r[m] = f_indexed_table(k)
+ fastserialize(v)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_indexed_boolean(k,v)
+ end
+ end
+ else
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_hashed_string(k,v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_hashed_number(k,v)
+ elseif tv == "table" then
+ m = m + 1 r[m] = f_hashed_table(k)
+ fastserialize(v)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_hashed_boolean(k,v)
+ end
+ end
+ end
+ m = m + 1
+ if outer then
+ r[m] = "}"
+ else
+ r[m] = "},"
+ end
+ return r
+ end
+ return concat(fastserialize(t,true))
+end
+
+function table.deserialize(str)
+ if not str or str == "" then
+ return
+ end
+ local code = load(str)
+ if not code then
+ return
+ end
+ code = code()
+ if not code then
+ return
+ end
+ return code
+end
+
+-- inspect(table.fastserialize { a = 1, b = { 4, { 5, 6 } }, c = { d = 7, e = 'f"g\nh' } })
+
+function table.load(filename,loader)
+ if filename then
+ local t = (loader or io.loaddata)(filename)
+ if t and t ~= "" then
+ local t = utftoeight(t)
+ t = load(t)
+ if type(t) == "function" then
+ t = t()
+ if type(t) == "table" then
+ return t
+ end
+ end
+ end
+ end
+end
+
+function table.save(filename,t,n,...)
+ io.savedata(filename,table.serialize(t,n == nil and true or n,...)) -- no frozen table.serialize
+end
+
+local f_key_value = formatters["%s=%q"]
+local f_add_table = formatters[" {%t},\n"]
+local f_return_table = formatters["return {\n%t}"]
+
+local function slowdrop(t) -- maybe less memory (intermediate concat)
+ local r = { }
+ local l = { }
+ for i=1,#t do
+ local ti = t[i]
+ local j = 0
+ for k, v in next, ti do
+ j = j + 1
+ l[j] = f_key_value(k,v)
+ end
+ r[i] = f_add_table(l)
+ end
+ return f_return_table(r)
+end
+
+local function fastdrop(t)
+ local r = { "return {\n" }
+ local m = 1
+ for i=1,#t do
+ local ti = t[i]
+ m = m + 1 r[m] = " {"
+ for k, v in next, ti do
+ m = m + 1 r[m] = f_key_value(k,v)
+ end
+ m = m + 1 r[m] = "},\n"
+ end
+ m = m + 1
+ r[m] = "}"
+ return concat(r)
+end
+
+function table.drop(t,slow) -- only { { a=2 }, {a=3} } -- for special cases
+ if #t == 0 then
+ return "return { }"
+ elseif slow == true then
+ return slowdrop(t) -- less memory
+ else
+ return fastdrop(t) -- some 15% faster
+ end
+end
+
+-- inspect(table.drop({ { a=2 }, {a=3} }))
+-- inspect(table.drop({ { a=2 }, {a=3} },true))
+
+-- function table.autokey(t,k) -- replaced
+-- local v = { }
+-- t[k] = v
+-- return v
+-- end
+
+local selfmapper = { __index = function(t,k) t[k] = k return k end }
+
+function table.twowaymapper(t) -- takes a 0/1 .. n indexed table and returns
+ if not t then -- it with string-numbers as indices + reverse
+ t = { } -- mapping (all strings) .. used in cvs etc but
+ else -- typically a helper that one forgets about
+ local zero = rawget(t,0) -- so it might move someplace else
+ for i=zero and 0 or 1,#t do
+ local ti = t[i] -- t[1] = "one"
+ if ti then
+ local i = tostring(i)
+ t[i] = ti -- t["1"] = "one"
+ t[ti] = i -- t["one"] = "1"
+ end
+ end
+ end
+ -- setmetatableindex(t,"key")
+ setmetatable(t,selfmapper)
+ return t
+end
+
+-- The next version is somewhat faster, although in practice one will seldom
+-- serialize a lot using this one. Often the above variants are more efficient.
+-- If we would really need this a lot, we could hash q keys, or just not used
+-- indented code.
+
+-- char-def.lua : 0.53 -> 0.38
+-- husayni.tma : 0.28 -> 0.19
+
+local f_start_key_idx = formatters["%w{"]
+local f_start_key_num = formatters["%w[%s]={"]
+local f_start_key_str = formatters["%w[%q]={"]
+local f_start_key_boo = formatters["%w[%l]={"]
+local f_start_key_nop = formatters["%w{"]
+
+local f_stop = formatters["%w},"]
+
+local f_key_num_value_num = formatters["%w[%s]=%s,"]
+local f_key_str_value_num = formatters["%w[%Q]=%s,"]
+local f_key_boo_value_num = formatters["%w[%l]=%s,"]
+
+local f_key_num_value_str = formatters["%w[%s]=%Q,"]
+local f_key_str_value_str = formatters["%w[%Q]=%Q,"]
+local f_key_boo_value_str = formatters["%w[%l]=%Q,"]
+
+local f_key_num_value_boo = formatters["%w[%s]=%l,"]
+local f_key_str_value_boo = formatters["%w[%Q]=%l,"]
+local f_key_boo_value_boo = formatters["%w[%l]=%l,"]
+
+local f_key_num_value_not = formatters["%w[%s]={},"]
+local f_key_str_value_not = formatters["%w[%Q]={},"]
+local f_key_boo_value_not = formatters["%w[%l]={},"]
+
+local f_key_num_value_seq = formatters["%w[%s]={ %, t },"]
+local f_key_str_value_seq = formatters["%w[%Q]={ %, t },"]
+local f_key_boo_value_seq = formatters["%w[%l]={ %, t },"]
+
+local f_val_num = formatters["%w%s,"]
+local f_val_str = formatters["%w%Q,"]
+local f_val_boo = formatters["%w%l,"]
+local f_val_not = formatters["%w{},"]
+local f_val_seq = formatters["%w{ %, t },"]
+local f_fin_seq = formatters[" %, t }"]
+
+local f_table_return = formatters["return {"]
+local f_table_name = formatters["%s={"]
+local f_table_direct = formatters["{"]
+local f_table_entry = formatters["[%Q]={"]
+local f_table_finish = formatters["}"]
+
+----- f_string = formatters["%q"]
+
+local spaces = utilities.strings.newrepeater(" ")
+
+local original_serialize = table.serialize -- the extensive one, the one we started with
+
+-- there is still room for optimization: index run, key run, but i need to check with the
+-- latest lua for the value of #n (with holes) .. anyway for tracing purposes we want
+-- indices / keys being sorted, so it will never be real fast
+
+local is_simple_table = table.is_simple_table
+
+-- local function is_simple_table(t)
+-- local nt = #t
+-- if nt > 0 then
+-- local n = 0
+-- for _, v in next, t do
+-- n = n + 1
+-- if type(v) == "table" then
+-- return nil
+-- end
+-- end
+-- -- local haszero = t[0]
+-- local haszero = rawget(t,0) -- don't trigger meta
+-- if n == nt then
+-- local tt = { }
+-- for i=1,nt do
+-- local v = t[i]
+-- local tv = type(v)
+-- if tv == "number" then
+-- tt[i] = v -- not needed tostring(v)
+-- elseif tv == "string" then
+-- tt[i] = format("%q",v) -- f_string(v)
+-- elseif tv == "boolean" then
+-- tt[i] = v and "true" or "false"
+-- else
+-- return nil
+-- end
+-- end
+-- return tt
+-- elseif haszero and (n == nt + 1) then
+-- local tt = { }
+-- for i=0,nt do
+-- local v = t[i]
+-- local tv = type(v)
+-- if tv == "number" then
+-- tt[i+1] = v -- not needed tostring(v)
+-- elseif tv == "string" then
+-- tt[i+1] = format("%q",v) -- f_string(v)
+-- elseif tv == "boolean" then
+-- tt[i+1] = v and "true" or "false"
+-- else
+-- return nil
+-- end
+-- end
+-- tt[1] = "[0] = " .. tt[1]
+-- return tt
+-- end
+-- end
+-- return nil
+-- end
+
+-- In order to overcome the luajit (65K constant) limitation I tried a split approach,
+-- i.e. outputting the first level tables as locals but that failed with large cjk
+-- fonts too so I removed that ... just use luatex instead.
+
+local function serialize(root,name,specification)
+
+ if type(specification) == "table" then
+ return original_serialize(root,name,specification) -- the original one
+ end
+
+ local t -- = { }
+ local n = 1
+ local unknown = false
+
+ local function do_serialize(root,name,depth,level,indexed)
+ if level > 0 then
+ n = n + 1
+ if indexed then
+ t[n] = f_start_key_idx(depth)
+ else
+ local tn = type(name)
+ if tn == "number" then
+ t[n] = f_start_key_num(depth,name)
+ elseif tn == "string" then
+ t[n] = f_start_key_str(depth,name)
+ elseif tn == "boolean" then
+ t[n] = f_start_key_boo(depth,name)
+ else
+ t[n] = f_start_key_nop(depth)
+ end
+ end
+ depth = depth + 1
+ end
+ -- we could check for k (index) being number (cardinal)
+ if root and next(root) ~= nil then
+ local first = nil
+ local last = #root
+ if last > 0 then
+ for k=1,last do
+ if rawget(root,k) == nil then
+ -- if root[k] == nil then
+ last = k - 1
+ break
+ end
+ end
+ if last > 0 then
+ first = 1
+ end
+ end
+ local sk = sortedkeys(root)
+ for i=1,#sk do
+ local k = sk[i]
+ local v = root[k]
+ local tv = type(v)
+ local tk = type(k)
+ if first and tk == "number" and k <= last and k >= first then
+ if tv == "number" then
+ n = n + 1 t[n] = f_val_num(depth,v)
+ elseif tv == "string" then
+ n = n + 1 t[n] = f_val_str(depth,v)
+ elseif tv == "table" then
+ if next(v) == nil then -- tricky as next is unpredictable in a hash
+ n = n + 1 t[n] = f_val_not(depth)
+ else
+ local st = is_simple_table(v)
+ if st then
+ n = n + 1 t[n] = f_val_seq(depth,st)
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ end
+ elseif tv == "boolean" then
+ n = n + 1 t[n] = f_val_boo(depth,v)
+ elseif unknown then
+ n = n + 1 t[n] = f_val_str(depth,tostring(v))
+ end
+ elseif tv == "number" then
+ if tk == "number" then
+ n = n + 1 t[n] = f_key_num_value_num(depth,k,v)
+ elseif tk == "string" then
+ n = n + 1 t[n] = f_key_str_value_num(depth,k,v)
+ elseif tk == "boolean" then
+ n = n + 1 t[n] = f_key_boo_value_num(depth,k,v)
+ elseif unknown then
+ n = n + 1 t[n] = f_key_str_value_num(depth,tostring(k),v)
+ end
+ elseif tv == "string" then
+ if tk == "number" then
+ n = n + 1 t[n] = f_key_num_value_str(depth,k,v)
+ elseif tk == "string" then
+ n = n + 1 t[n] = f_key_str_value_str(depth,k,v)
+ elseif tk == "boolean" then
+ n = n + 1 t[n] = f_key_boo_value_str(depth,k,v)
+ elseif unknown then
+ n = n + 1 t[n] = f_key_str_value_str(depth,tostring(k),v)
+ end
+ elseif tv == "table" then
+ if next(v) == nil then
+ if tk == "number" then
+ n = n + 1 t[n] = f_key_num_value_not(depth,k)
+ elseif tk == "string" then
+ n = n + 1 t[n] = f_key_str_value_not(depth,k)
+ elseif tk == "boolean" then
+ n = n + 1 t[n] = f_key_boo_value_not(depth,k)
+ elseif unknown then
+ n = n + 1 t[n] = f_key_str_value_not(depth,tostring(k))
+ end
+ else
+ local st = is_simple_table(v)
+ if not st then
+ do_serialize(v,k,depth,level+1)
+ elseif tk == "number" then
+ n = n + 1 t[n] = f_key_num_value_seq(depth,k,st)
+ elseif tk == "string" then
+ n = n + 1 t[n] = f_key_str_value_seq(depth,k,st)
+ elseif tk == "boolean" then
+ n = n + 1 t[n] = f_key_boo_value_seq(depth,k,st)
+ elseif unknown then
+ n = n + 1 t[n] = f_key_str_value_seq(depth,tostring(k),st)
+ end
+ end
+ elseif tv == "boolean" then
+ if tk == "number" then
+ n = n + 1 t[n] = f_key_num_value_boo(depth,k,v)
+ elseif tk == "string" then
+ n = n + 1 t[n] = f_key_str_value_boo(depth,k,v)
+ elseif tk == "boolean" then
+ n = n + 1 t[n] = f_key_boo_value_boo(depth,k,v)
+ elseif unknown then
+ n = n + 1 t[n] = f_key_str_value_boo(depth,tostring(k),v)
+ end
+ else
+ if tk == "number" then
+ n = n + 1 t[n] = f_key_num_value_str(depth,k,tostring(v))
+ elseif tk == "string" then
+ n = n + 1 t[n] = f_key_str_value_str(depth,k,tostring(v))
+ elseif tk == "boolean" then
+ n = n + 1 t[n] = f_key_boo_value_str(depth,k,tostring(v))
+ elseif unknown then
+ n = n + 1 t[n] = f_key_str_value_str(depth,tostring(k),tostring(v))
+ end
+ end
+ end
+ end
+ if level > 0 then
+ n = n + 1 t[n] = f_stop(depth-1)
+ end
+ end
+
+ local tname = type(name)
+
+ if tname == "string" then
+ if name == "return" then
+ t = { f_table_return() }
+ else
+ t = { f_table_name(name) }
+ end
+ elseif tname == "number" then
+ t = { f_table_entry(name) }
+ elseif tname == "boolean" then
+ if name then
+ t = { f_table_return() }
+ else
+ t = { f_table_direct() }
+ end
+ else
+ t = { f_table_name("t") }
+ end
+
+ if root then
+ -- The dummy access will initialize a table that has a delayed initialization
+ -- using a metatable. (maybe explicitly test for metatable). This can crash on
+ -- metatables that check the index against a number.
+ if getmetatable(root) then -- todo: make this an option, maybe even per subtable
+ local dummy = root._w_h_a_t_e_v_e_r_ -- needed
+ root._w_h_a_t_e_v_e_r_ = nil
+ end
+ -- Let's forget about empty tables.
+ if next(root) ~= nil then
+ local st = is_simple_table(root)
+ if st then
+ return t[1] .. f_fin_seq(st) -- todo: move up and in one go
+ else
+ do_serialize(root,name,1,0)
+ end
+ end
+ end
+ n = n + 1
+ t[n] = f_table_finish()
+ return concat(t,"\n")
+end
+
+table.serialize = serialize
+
+if setinspector then
+ setinspector("table",function(v)
+ if type(v) == "table" then
+ print(serialize(v,"table",{ metacheck = false }))
+ return true
+ end
+ end)
+end
+
+-- ordered hashes (for now here but in the table namespace):
+
+-- local t = table.orderedhash()
+--
+-- t["1"] = { "a", "b" }
+-- t["2"] = { }
+-- t["2a"] = { "a", "c", "d" }
+--
+-- for k, v in table.ordered(t) do
+-- ...
+-- end
+
+local mt = {
+ __newindex = function(t,k,v)
+ local n = t.last + 1
+ t.last = n
+ t.list[n] = k
+ t.hash[k] = v
+ end,
+ __index = function(t,k)
+ return t.hash[k]
+ end,
+ __len = function(t)
+ return t.last
+ end,
+}
+
+function table.orderedhash()
+ return setmetatable({ list = { }, hash = { }, last = 0 }, mt)
+end
+
+function table.ordered(t)
+ local n = t.last
+ if n > 0 then
+ local l = t.list
+ local i = 1
+ local h = t.hash
+ local f = function()
+ if i <= n then
+ local k = i
+ local v = h[l[k]]
+ i = i + 1
+ return k, v
+ end
+ end
+ return f, 1, h[l[1]]
+ else
+ return function() end
+ end
+end
diff --git a/macros/luatex/generic/lualibs/lualibs-util-tpl.lua b/macros/luatex/generic/lualibs/lualibs-util-tpl.lua
new file mode 100644
index 0000000000..57d7df3a91
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs-util-tpl.lua
@@ -0,0 +1,215 @@
+if not modules then modules = { } end modules ['util-tpl'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This is experimental code. Coming from dos and windows, I've always used %whatever%
+-- as template variables so let's stick to it. After all, it's easy to parse and stands
+-- out well. A double %% is turned into a regular %.
+
+utilities.templates = utilities.templates or { }
+local templates = utilities.templates
+
+local trace_template = false trackers.register("templates.trace",function(v) trace_template = v end)
+local report_template = logs.reporter("template")
+
+local tostring, next = tostring, next
+local format, sub, byte = string.format, string.sub, string.byte
+local P, C, R, Cs, Cc, Carg, lpegmatch, lpegpatterns = lpeg.P, lpeg.C, lpeg.R, lpeg.Cs, lpeg.Cc, lpeg.Carg, lpeg.match, lpeg.patterns
+
+-- todo: make installable template.new
+
+local replacer
+
+local function replacekey(k,t,how,recursive)
+ local v = t[k]
+ if not v then
+ if trace_template then
+ report_template("unknown key %a",k)
+ end
+ return ""
+ else
+ v = tostring(v)
+ if trace_template then
+ report_template("setting key %a to value %a",k,v)
+ end
+ if recursive then
+ return lpegmatch(replacer,v,1,t,how,recursive)
+ else
+ return v
+ end
+ end
+end
+
+local sqlescape = lpeg.replacer {
+ { "'", "''" },
+ { "\\", "\\\\" },
+ { "\r\n", "\\n" },
+ { "\r", "\\n" },
+ -- { "\t", "\\t" },
+}
+
+local sqlquoted = Cs(Cc("'") * sqlescape * Cc("'"))
+
+lpegpatterns.sqlescape = sqlescape
+lpegpatterns.sqlquoted = sqlquoted
+
+-- escapeset : \0\1\2\3\4\5\6\7\8\9\10\11\12\13\14\15\16\17\18\19\20\21\22\23\24\25\26\27\28\29\30\31\"\\\127
+-- test string: [[1\0\31test23"\\]] .. string.char(19) .. "23"
+--
+-- slow:
+--
+-- local luaescape = lpeg.replacer {
+-- { '"', [[\"]] },
+-- { '\\', [[\\]] },
+-- { R("\0\9") * #R("09"), function(s) return "\\00" .. byte(s) end },
+-- { R("\10\31") * #R("09"), function(s) return "\\0" .. byte(s) end },
+-- { R("\0\31") , function(s) return "\\" .. byte(s) end },
+-- }
+--
+-- slightly faster:
+
+-- local luaescape = Cs ((
+-- P('"' ) / [[\"]] +
+-- P('\\') / [[\\]] +
+-- Cc("\\00") * (R("\0\9") / byte) * #R("09") +
+-- Cc("\\0") * (R("\10\31") / byte) * #R("09") +
+-- Cc("\\") * (R("\0\31") / byte) +
+-- P(1)
+-- )^0)
+
+----- xmlescape = lpegpatterns.xmlescape
+----- texescape = lpegpatterns.texescape
+local luaescape = lpegpatterns.luaescape
+----- sqlquoted = lpegpatterns.sqlquoted
+----- luaquoted = lpegpatterns.luaquoted
+
+local escapers = {
+ lua = function(s)
+ -- return sub(format("%q",s),2,-2)
+ return lpegmatch(luaescape,s)
+ end,
+ sql = function(s)
+ return lpegmatch(sqlescape,s)
+ end,
+}
+
+local quotedescapers = {
+ lua = function(s)
+ -- return lpegmatch(luaquoted,s)
+ return format("%q",s)
+ end,
+ sql = function(s)
+ return lpegmatch(sqlquoted,s)
+ end,
+}
+
+local luaescaper = escapers.lua
+local quotedluaescaper = quotedescapers.lua
+
+local function replacekeyunquoted(s,t,how,recurse) -- ".. \" "
+ if how == false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper = how and escapers[how] or luaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
+end
+
+local function replacekeyquoted(s,t,how,recurse) -- ".. \" "
+ if how == false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper = how and quotedescapers[how] or quotedluaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
+end
+
+local function replaceoptional(l,m,r,t,how,recurse)
+ local v = t[l]
+ return v and v ~= "" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
+end
+
+local single = P("%") -- test %test% test : resolves test
+local double = P("%%") -- test 10%% test : %% becomes %
+local lquoted = P("%[") -- test '%[test]%' test : resolves to test with escaped "'s
+local rquoted = P("]%") --
+local lquotedq = P("%(") -- test %(test)% test : resolves to 'test' with escaped "'s
+local rquotedq = P(")%") --
+
+local escape = double / '%%'
+local nosingle = single / ''
+local nodouble = double / ''
+local nolquoted = lquoted / ''
+local norquoted = rquoted / ''
+local nolquotedq = lquotedq / ''
+local norquotedq = rquotedq / ''
+
+local noloptional = P("%?") / ''
+local noroptional = P("?%") / ''
+local nomoptional = P(":") / ''
+
+
+local args = Carg(1) * Carg(2) * Carg(3)
+local key = nosingle * ((C((1-nosingle )^1) * args) / replacekey ) * nosingle
+local quoted = nolquotedq * ((C((1-norquotedq )^1) * args) / replacekeyquoted ) * norquotedq
+local unquoted = nolquoted * ((C((1-norquoted )^1) * args) / replacekeyunquoted) * norquoted
+local optional = noloptional * ((C((1-nomoptional)^1) * nomoptional * C((1-noroptional)^1) * args) / replaceoptional) * noroptional
+local any = P(1)
+
+ replacer = Cs((unquoted + quoted + escape + optional + key + any)^0)
+
+local function replace(str,mapping,how,recurse)
+ if mapping and str then
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ else
+ return str
+ end
+end
+
+-- print(replace("test '%[x]%' test",{ x = [[a 'x'  a]] }))
+-- print(replace("test '%x%' test",{ x = [[a "x"  a]] }))
+-- print(replace([[test "%[x]%" test]],{ x = [[a "x"  a]] }))
+-- print(replace("test '%[x]%' test",{ x = true }))
+-- print(replace("test '%[x]%' test",{ x = [[a 'x'  a]], y = "oeps" },'sql'))
+-- print(replace("test '%[x]%' test",{ x = [[a '%y%'  a]], y = "oeps" },'sql',true))
+-- print(replace([[test %[x]% test]],{ x = [[a "x"  a]]}))
+-- print(replace([[test %(x)% test]],{ x = [[a "x"  a]]}))
+-- print(replace([[convert %?x: -x "%x%" ?% %?y: -y "%y%" ?%]],{ x = "yes" }))
+
+templates.replace = replace
+
+function templates.replacer(str,how,recurse) -- reads nicer
+ return function(mapping)
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ end
+end
+
+-- local cmd = templates.replacer([[foo %bar%]]) print(cmd { bar = "foo" })
+
+function templates.load(filename,mapping,how,recurse)
+ local data = io.loaddata(filename) or ""
+ if mapping and next(mapping) then
+ return replace(data,mapping,how,recurse)
+ else
+ return data
+ end
+end
+
+function templates.resolve(t,mapping,how,recurse)
+ if not mapping then
+ mapping = t
+ end
+ for k, v in next, t do
+ t[k] = replace(v,mapping,how,recurse)
+ end
+ return t
+end
+
+-- inspect(utilities.templates.replace("test %one% test", { one = "%two%", two = "two" }))
+-- inspect(utilities.templates.resolve({ one = "%two%", two = "two", three = "%three%" }))
+-- inspect(utilities.templates.replace("test %one% test", { one = "%two%", two = "two" },false,true))
+-- inspect(utilities.templates.replace("test %one% test", { one = "%two%", two = "two" },false))
diff --git a/macros/luatex/generic/lualibs/lualibs.dtx b/macros/luatex/generic/lualibs/lualibs.dtx
new file mode 100644
index 0000000000..8c302400f1
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs.dtx
@@ -0,0 +1,813 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2009--2019 by
+%
+% PRAGMA ADE / ConTeXt Development Team
+% The LuaLaTeX Dev Team
+%
+% See ConTeXt's mreadme.pdf for the license.
+%
+% This work consists of the main source file lualibs.dtx
+% and the derived files lualibs.lua, lualibs-basic.lua,
+% and lualibs-extended.lua.
+%
+% Unpacking:
+% tex lualibs.dtx
+%
+% Documentation:
+% lualatex lualibs.dtx
+%
+% The class ltxdoc loads the configuration file ltxdoc.cfg
+% if available. Here you can specify further options, e.g.
+% use A4 as paper format:
+% \PassOptionsToClass{a4paper}{article}
+%
+%
+%
+%<*ignore>
+\begingroup
+ \def\x{LaTeX2e}%
+\expandafter\endgroup
+\ifcase 0\ifx\install y1\fi\expandafter
+ \ifx\csname processbatchFile\endcsname\relax\else1\fi
+ \ifx\fmtname\x\else 1\fi\relax
+\else\csname fi\endcsname
+%</ignore>
+%<*install>
+\input docstrip.tex
+\Msg{************************************************************************}
+\Msg{* Installation}
+\Msg{* Package: lualibs 2019-08-11 v2.67 Lua additional functions.}
+\Msg{************************************************************************}
+
+\keepsilent
+\askforoverwritefalse
+
+\let\MetaPrefix\relax
+
+\preamble
+This is a generated file.
+
+Copyright (C) 2009--2018 by
+ PRAGMA ADE / ConTeXt Development Team
+ The LuaLaTeX Dev Team
+
+See ConTeXt's mreadme.pdf for the license.
+
+This work consists of the main source file lualibs.dtx
+and the derived files lualibs.lua, lualibs-basic.lua,
+and lualibs-extended.lua.
+
+\endpreamble
+
+% The following hacks are to generate a lua file with lua comments starting by
+% -- instead of %%
+
+\def\MetaPrefix{-- }
+
+\def\luapostamble{%
+ \MetaPrefix^^J%
+ \MetaPrefix\space End of File `\outFileName'.%
+}
+
+\def\currentpostamble{\luapostamble}%
+
+\generate{%
+ \usedir{tex/luatex/lualibs}%
+ \file{lualibs.lua}{\from{lualibs.dtx}{lualibs}}%
+}
+
+\generate{%
+ \usedir{tex/luatex/lualibs}%
+ \file{lualibs-basic.lua}{\from{lualibs.dtx}{basic}}%
+}
+
+\generate{%
+ \usedir{tex/luatex/lualibs}%
+ \file{lualibs-extended.lua}{\from{lualibs.dtx}{extended}}%
+}
+
+\obeyspaces
+\Msg{************************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* files into a directory searched by TeX:}
+\Msg{*}
+\Msg{* lualibs.lua, lualibs-basic.lua, lualibs-extended.lua}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesFile{lualibs.drv}
+ [2019/08/11 v2.67 Lua Libraries.]
+\documentclass{ltxdoc}
+\usepackage{fancyvrb,xspace}
+\usepackage[x11names]{xcolor}
+%
+\def\primarycolor{DodgerBlue4} %%-> rgb 16 78 139 | #104e8b
+\def\secondarycolor{Goldenrod4} %%-> rgb 139 105 200 | #8b6914
+%
+\usepackage[
+ bookmarks=true,
+ colorlinks=true,
+ linkcolor=\primarycolor,
+ urlcolor=\secondarycolor,
+ citecolor=\primarycolor,
+ pdftitle={The lualibs package},
+ pdfsubject={Port of the ConTeXt Lua libraries},
+ pdfauthor={Elie Roux & Philipp Gesang},
+ pdfkeywords={luatex, lualatex, unicode, opentype}
+]{hyperref}
+\newcommand*\email[1]{\href{mailto:#1}{#1}}
+\usepackage{fontspec}
+\setmainfont[
+ Numbers=OldStyle,
+ Ligatures=TeX,
+]{Linux Libertine O}
+\setmonofont [Ligatures=TeX,Scale=MatchLowercase] {Liberation Mono}
+\setsansfont [Ligatures=TeX,Scale=MatchLowercase] {Iwona Medium}
+\usepackage{metalogo}
+\EnableCrossrefs
+\CodelineIndex
+\newcommand\TEX {\TeX\xspace}
+\newcommand\LATEX {\LaTeX\xspace}
+\newcommand\LUA {Lua\xspace}
+\newcommand\LUATEX {\LuaTeX\xspace}
+\newcommand\CONTEXT {Con\TeX t\xspace}
+
+\def\definehighlight[#1][#2]%
+ {\ifcsname #1\endcsname\else
+ \expandafter\def\csname #1\endcsname%
+ {\bgroup#2\csname #1_indeed\endcsname}
+ \expandafter\def\csname #1_indeed\endcsname##1%
+ {##1\egroup}%
+ \fi}
+
+\def\restoreunderscore{\catcode`\_=12\relax}
+
+\definehighlight [fileent][\ttfamily\restoreunderscore] %% files, dirs
+\definehighlight [texmacro][\sffamily\itshape\textbackslash] %% cs
+\definehighlight [luaident][\sffamily\itshape\restoreunderscore] %% lua identifiers
+\definehighlight [identifier][\sffamily] %% names
+\definehighlight [abbrev][\rmfamily\scshape] %% acronyms
+\definehighlight [emphasis][\rmfamily\slshape] %% level 1 emph
+
+\usepackage{titlesec}
+\def\movecountertomargin#1{\llap{\rmfamily\upshape#1\hskip2em}}
+\def\zeropoint{0pt}
+%% we don’t have to grab attention like a child
+\titleformat \part
+ {\normalsize\bfseries}
+ {\movecountertomargin\thepart} \zeropoint {}
+\titleformat \section
+ {\normalsize\scshape}%% no \word; life is full of disappointments
+ {\movecountertomargin\thesection} \zeropoint {}
+\titleformat \subsection
+ {\small\itshape}
+ {\movecountertomargin\thesubsection} \zeropoint {}
+\renewcommand\partname{Part}%% gets rid of the stupid “file†heading
+
+\usepackage{tocloft}
+\renewcommand \cftpartfont {\rmfamily\upshape}
+\renewcommand \cftsecfont {\rmfamily\upshape}
+\renewcommand \cftsubsecfont {\rmfamily\upshape}
+\setlength \cftbeforepartskip {1ex}
+\setlength \cftbeforesecskip {1ex}
+
+\begin{document}
+ \DocInput{lualibs.dtx}%
+\end{document}
+%</driver>
+% \fi
+% \CheckSum{0}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+% \GetFileInfo{lualibs.drv}
+%
+% \title{The \identifier{lualibs} package}
+% \date{2019/08/11 v2.67}
+% \author{Élie Roux · \email{elie.roux@telecom-bretagne.eu}\\
+% Philipp Gesang · \email{phg@phi-gamma.net}\\
+% Ulrike Fischer · \email{fischer@troubleshooting-tex.de}\\
+% }
+%
+% \maketitle
+%
+% \begin{abstract}
+% Additional \LUA functions taken from the \verb|l-*| and \verb|util-*| files
+% of \CONTEXT.
+% For an introduction on this package (among others), please refer
+% to the document \fileent{lualatex-doc.pdf}.
+% \end{abstract}
+%
+% \tableofcontents
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \part{Package Description}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \section{Overview}
+%
+% \LUA is a very minimal language, and it does only have a minimal standard
+% library. The aim of this package is to provide an extended standard library,
+% to be used by various \LUATEX packages. The code is specific to \LUATEX
+% and depends on \LUATEX functions and modules not available in regular lua.
+%
+% \noindent The code is derived from \CONTEXT libraries.
+%
+% \section{Usage}
+%
+% You can either load the \identifier{lualibs} module, which will in turn load
+% one of two sets of libraries provided by this package: |require("lualibs")|, or
+% explicitly load the modules you need, e.g.: |require("lualibs-table")|,
+% please note that some modules depend on others.
+%
+% \subsection{Loading Library Collections}
+%
+% The libraries are split into a \identifier{basic} and an
+% \identifier{extended} collection.
+% Though neither initialization time nor memory consumption will be noticably
+% impacted,\footnote{%
+% Note that in terms of code this is only a small fraction of what
+% \CONTEXT loads with every run.
+% }
+% the \identifier{lualibs} package can skip loading of the latter on demand.
+% The \luaident{config} table needs to be present prior to loading the
+% package for this to work (in the future this may be achieved by an option of
+% \texmacro{usepackage}) for \LATEX users).
+% In the \verb|lualibs| field, set \verb|load_extended| to false:
+%
+% \begin{quote}\begin{verbatim}
+% \directlua{
+% --- 1) create config table safely
+% config = config or { }
+% config.lualibs = config.lualibs or { }
+%
+% --- 2) unset the load_extended entry
+% config.lualibs.load_extended = false
+%
+% --- 3) load the lualibs
+% require "lualibs"
+% }
+% \end{verbatim}\end{quote}
+%
+% However, there is no guarantee that the \identifier{extended} set remains
+% permanently excluded.
+% Re-loading the package at a later point will cancel this option and possibly
+% add the missing libraries.
+%
+% \subsection{Loading libraries Individually}
+% In order to load the \fileent{table} module you would actually have to prepare
+% it as follows:
+%
+% \begin{quote}\begin{verbatim}
+% require"lualibs-lua"
+% require"lualibs-lpeg"
+% require"lualibs-table"
+% \end{verbatim}\end{quote}
+%
+% \noindent
+% If your code is run by the \fileent{texlua} intepreter, you will need to
+% initialize \luaident{kpse} library so that |require()| can find files
+% under \abbrev{texmf} tree: |kpse.set_program_name("luatex")|.
+%
+% \section{Files}
+%
+% The \identifier{lualibs} bundle contains files from two \CONTEXT \LUA
+% library categories: The generic auxiliary functions (original file prefix:
+% |l-|) together form something close to a standard libary. Most of these are
+% extensions of an existing namespace, like for instance |l-table.lua| which
+% adds full-fledged serialization capabilities to the \LUA table library.
+% They were imported under the \identifier{lualibs}-prefix and are contained
+% in the \identifier{basic} collection.
+% (For a list see table~\ref{tab:basic}.)
+%
+% \begin{table}[t]
+% \hrule
+% \centering
+% \caption{The \identifier{basic} set.}
+% \vskip1em
+% \begin{tabular}{l l l}
+% \identifier{lualibs} name & \CONTEXT name & primary purpose \\[1ex]
+% lualibs-lua.lua & l-lua.lua & compatibility \\
+% lualibs-package.lua & l-package.lua & \LUA file loaders \\
+% lualibs-lpeg.lua & l-lpeg.lua & patterns \\
+% lualibs-function.lua & l-function.lua & defines a dummy function \\
+% lualibs-string.lua & l-string.lua & string manipulation \\
+% lualibs-table.lua & l-table.lua & serialization, conversion \\
+% lualibs-boolean.lua & l-boolean.lua & boolean converter \\
+% lualibs-number.lua & l-number.lua & bit operations \\
+% lualibs-math.lua & l-math.lua & math functions \\
+% lualibs-io.lua & l-io.lua & reading and writing files \\
+% lualibs-os.lua & l-os.lua & platform specific code \\
+% lualibs-file.lua & l-file.lua & filesystem operations \\
+% lualibs-gzip.lua & l-gzip.lua & wrapper for \identifier{lgzip} \\
+% lualibs-md5.lua & l-md5.lua & checksum functions \\
+% lualibs-dir.lua & l-dir.lua & directory handling \\
+% lualibs-unicode.lua & l-unicode.lua & utf and unicode \\
+% lualibs-url.lua & l-url.lua & url handling \\
+% lualibs-set.lua & l-set.lua & sets \\[1ex]
+% \end{tabular}
+% \label{tab:basic}
+% \hrule
+% \end{table}
+%
+% The \identifier{extended} category comprises a selection of files mostly from
+% the utilities namespace (|util-|; cf. table~\ref{tab:extended}).
+% Their purpose is more specific and at times quite low-level.
+% Additionally, the file \fileent{trac-inf.lua} has been included because it is
+% essential to some of the code loaded subsequently.
+%
+% \begin{table}[t]
+% \hrule
+% \centering
+% \caption{The \identifier{extended} set.}
+% \vskip1em
+% \begin{tabular}{l l l}
+% \identifier{lualibs} name & \CONTEXT name & primary purpose \\[1ex]
+% lualibs-util-str.lua & util-str.lua & extra |string| functions \\
+% lualibs-util-fil.lua & util-fil.lua & extra |file| functions \\
+% lualibs-util-tab.lua & util-tab.lua & extra |table| functions \\
+% lualibs-util-sto.lua & util-sto.lua & table allocation \\
+% lualibs-util-prs.lua & util-sto.lua & miscellaneous parsers \\
+% lualibs-util-dim.lua & util-dim.lua & conversion between dimensions \\
+% lualibs-trac-inf.lua & trac-inf.lua & timing, statistics \\
+% lualibs-util-lua.lua & util-lua.lua & operations on bytecode \\
+% lualibs-util-deb.lua & util-deb.lua & extra |debug| functionality \\
+% lualibs-util-tpl.lua & util-tpl.lua & templating \\
+% lualibs-util-sta.lua & util-sta.lua & stacker (e.~g. for \abbrev{pdf}) \\
+% lualibs-util-jsn.lua & util-jsn.lua & conversion to and from json \\[1ex]
+% \end{tabular}
+% \label{tab:extended}
+% \hrule
+% \end{table}
+%
+% \section{Packaging}
+%
+% By default, \identifier{lualibs} will not load the libraries individually.
+% Instead, it includes two \emphasis{merged packages} that have been compiled
+% from the original files.
+% This is achieved by means of \identifier{mtx-package}, a script for bundling
+% \LUA code shipped with \CONTEXT.
+% This concatenates the code of several \LUA files into a single file that is
+% both easier to distribute and loading marginally faster.
+% \identifier{mtx-package} ensures that the code from each file gets its
+% own closure and strips newlines and comments, resulting in a smaller payload.
+% Another package that relies on it heavily is the font loader as contained in
+% \identifier{luaotfload} and \identifier{luatex-fonts}.
+% \identifier{Luaotfload}, a port of the \CONTEXT fontloader for Plain and
+% \LATEX, has a hard dependency on the functionality provided by the %
+% \identifier{Lualibs} package. The packages should not be updated independently.
+%
+% If \CONTEXT is installed on the system, the merge files can be created
+% by running:
+%
+% \begin{quote}\begin{verbatim}
+% mtxrun --script package --merge lualibs-basic.lua
+% mtxrun --script package --merge lualibs-extended.lua
+% \end{verbatim}\end{quote}
+%
+% \noindent
+% Of course there is a make target for that:
+%
+% \begin{quote}\begin{verbatim}
+% make merge
+% \end{verbatim}\end{quote}
+% \noindent
+% will take care of assembling the packages from the files distributed with
+% \identifier{lualibs}.
+%
+% For this to work, the syntax of the \LUA file needs to be well-formed:
+% files that should be merged must be included via a function
+% \verb|loadmodule()|.
+% It doesn’t matter if the function actually does something; a dummy will
+% suffice.
+% Also, the argument to \verb|loadmodule()| must be wrapped in parentheses.
+% This rule is quite convenient, actually, since it allows excluding files
+% from the merge while still using \verb|loadmodule()| consistently.
+%
+% \begin{quote}\begin{verbatim}
+% ...
+% loadmodule("my-lua-file.lua") -- <= will be merged
+% loadmodule('my-2nd-file.lua') -- <= will be merged
+% loadmodule "my-3rd-file.lua" -- <= will be ignored
+% ...
+% \end{verbatim}\end{quote}
+%
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \part{\fileent{lualibs.lua}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \iffalse
+%<*lualibs>
+% \fi
+% \begin{macrocode}
+lualibs = lualibs or { }
+
+lualibs.module_info = {
+ name = "lualibs",
+ version = "2.67", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "ConTeXt Lua standard libraries.",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "See ConTeXt's mreadme.pdf for the license",
+}
+
+% \end{macrocode}
+% The behavior of the lualibs can be configured to some extent.
+% \begin{itemize}
+% \item Based on the parameter \verb|lualibs.prefer_merged|, the
+% libraries can be loaded via the included merged packages or
+% the individual files.
+% \item Two classes of libraries are distinguished, mainly because
+% of a similar distinction in \CONTEXT, but also to make
+% loading of the less fundamental functionality optional.
+% While the “basic†collection is always loaded, the
+% configuration setting \verb|lualibs.load_extended| triggers
+% inclusion of the extended collection.
+% \item Verbosity can be increased via the \verb|verbose| switch.
+% \end{itemize}
+%
+% \begin{macrocode}
+
+config = config or { }
+config.lualibs = config.lualibs or { }
+
+if config.lualibs.prefer_merged ~= nil then
+ lualibs.prefer_merged = config.lualibs.prefer_merged
+else
+ lualibs.prefer_merged = true
+end
+
+if config.lualibs.load_extended ~= nil then
+ lualibs.load_extended = config.lualibs.load_extended
+else
+ lualibs.load_extended = true
+end
+
+if config.lualibs.verbose ~= nil then
+ config.lualibs.verbose = config.lualibs.verbose
+else
+ config.lualibs.verbose = false
+end
+
+% \end{macrocode}
+% The lualibs may be loaded in scripts.
+% To account for the different environment, fallbacks for
+% the luatexbase facilities are installed.
+%
+% \begin{macrocode}
+
+local dofile = dofile
+local kpsefind_file = kpse.find_file
+local stringformat = string.format
+local texiowrite_nl = texio.write_nl
+
+local find_file, error, warn, info
+do
+ local _error, _warn, _info
+ if luatexbase and luatexbase.provides_module then
+ _error, _warn, _info = luatexbase.provides_module(lualibs.module_info)
+ else
+ _error, _warn, _info = texiowrite_nl, texiowrite_nl, texiowrite_nl
+ end
+
+ if lualibs.verbose then
+ error, warn, info = _error, _warn, _info
+ else
+ local dummylogger = function ( ) end
+ error, warn, info = _error, dummylogger, dummylogger
+ end
+ lualibs.error, lualibs.warn, lualibs.info = error, warn, info
+end
+
+if status.kpse_used == 0 then
+ kpse.set_program_name("luatex")
+end
+
+find_file = kpsefind_file
+
+% \end{macrocode}
+% The lualibs load a merged package by default.
+% In order to create one of these, the meta file that includes the
+% libraries must satisfy certain assumptions \verb|mtx-package| makes
+% about the coding style.
+% Most important is that the functions that indicates which files
+% to include must go by the name \verb|loadmodule()|.
+% For this reason we define a \verb|loadmodule()| function as a
+% wrapper around \verb|dofile()|.
+%
+% \begin{macrocode}
+
+local loadmodule = loadmodule or function (name, t)
+ if not t then t = "library" end
+ local filepath = find_file(name, "lua")
+ if not filepath or filepath == "" then
+ warn(stringformat("Could not locate %s “%sâ€.", t, name))
+ return false
+ end
+ dofile(filepath)
+ return true
+end
+
+lualibs.loadmodule = loadmodule
+
+% \end{macrocode}
+% The separation of the “basic†from the “extended†sets coincides
+% with the split into luat-bas.mkiv and luat-lib.mkiv.
+%
+% \begin{macrocode}
+
+if lualibs.basic_loaded ~= true
+or config.lualibs.force_reload == true
+then
+ loadmodule"lualibs-basic.lua"
+ loadmodule"lualibs-compat.lua" --- restore stuff gone since v1.*
+end
+
+if lualibs.load_extended == true
+and lualibs.extended_loaded ~= true
+or config.lualibs.force_reload == true
+then
+ loadmodule"lualibs-extended.lua"
+end
+
+--- This restores the default of loading everything should a package
+--- have requested otherwise. Will be gone once there is a canonical
+--- interface for parameterized loading of libraries.
+config.lualibs.load_extended = true
+
+-- vim:tw=71:sw=2:ts=2:expandtab
+
+% \end{macrocode}
+%
+% \iffalse
+%</lualibs>
+% \fi
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \part{\fileent{lualibs-basic.lua}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \iffalse
+%<*basic>
+% \fi
+% \begin{macrocode}
+lualibs = lualibs or { }
+local info = lualibs.info
+local loadmodule = lualibs.loadmodule
+
+local lualibs_basic_module = {
+ name = "lualibs-basic",
+ version = "2.67", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "ConTeXt Lua libraries -- basic collection.",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "See ConTeXt's mreadme.pdf for the license",
+}
+
+local loaded = false --- track success of package loading
+
+if lualibs.prefer_merged then
+ info"Loading merged package for collection “basicâ€."
+ loaded = loadmodule('lualibs-basic-merged.lua')
+else
+ info"Ignoring merged packages."
+ info"Falling back to individual libraries from collection “basicâ€."
+end
+
+% \end{macrocode}
+% \verb|mtx-package| expects the files to be included by
+% \verb|loadmodule|.
+% If run on this file, it will create \verb|lualibs-basic-merged.lua|
+% from all the files mentioned in the next block.
+%
+% \begin{macrocode}
+
+if loaded == false then
+ loadmodule("lualibs-lua.lua")
+ loadmodule("lualibs-package.lua")
+ loadmodule("lualibs-lpeg.lua")
+ loadmodule("lualibs-function.lua")
+ loadmodule("lualibs-string.lua")
+ loadmodule("lualibs-table.lua")
+ loadmodule("lualibs-boolean.lua")
+ loadmodule("lualibs-number.lua")
+ loadmodule("lualibs-math.lua")
+ loadmodule("lualibs-io.lua")
+ loadmodule("lualibs-os.lua")
+ loadmodule("lualibs-file.lua")
+ loadmodule("lualibs-gzip.lua")
+ loadmodule("lualibs-md5.lua")
+ loadmodule("lualibs-dir.lua")
+ loadmodule("lualibs-unicode.lua")
+ loadmodule("lualibs-url.lua")
+ loadmodule("lualibs-set.lua")
+end
+
+lualibs.basic_loaded = true
+-- vim:tw=71:sw=2:ts=2:expandtab
+
+% \end{macrocode}
+%
+% \iffalse
+%</basic>
+% \fi
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \part{\fileent{lualibs-extended.lua}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \iffalse
+%<*extended>
+% \fi
+% \begin{macrocode}
+lualibs = lualibs or { }
+
+% \end{macrocode}
+% Loading the \emph{extended} set requires a tad more effort, but
+% it’s well invested.
+%
+% Since we only want the functionality, we have to simulate parts
+% of a running \CONTEXT environment, above all logging, that some
+% of the more involved libraries cannot be loaded without.
+% Also, one utility file cannot be packaged because it returns a
+% table which would preclude loading of later code.
+% Thus, we remove it from the natural loading chain (it is not
+% critical) and append it at the end.
+%
+% \begin{macrocode}
+
+local lualibs_extended_module = {
+ name = "lualibs-extended",
+ version = "2.67", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "ConTeXt Lua libraries -- extended collection.",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "See ConTeXt's mreadme.pdf for the license",
+}
+
+
+local stringformat = string.format
+local loadmodule = lualibs.loadmodule
+local texiowrite = texio.write
+local texiowrite_nl = texio.write_nl
+
+% \end{macrocode}
+% Here we define some functions that fake the elaborate
+% logging/tracking mechanism Context provides.
+%
+% \begin{macrocode}
+
+local error, logger, mklog
+if luatexbase and luatexbase.provides_module then
+ --- TODO test how those work out when running tex
+ local __error,_,_,__logger =
+ luatexbase.provides_module(lualibs_extended_module)
+ error = __error
+ logger = __logger
+ mklog = function ( ) return logger end
+else
+ mklog = function (t)
+ local prefix = stringformat("[%s] ", t)
+ return function (...)
+ texiowrite_nl(prefix)
+ texiowrite (stringformat(...))
+ end
+ end
+ error = mklog"ERROR"
+ logger = mklog"INFO"
+end
+
+local info = lualibs.info
+
+% \end{macrocode}
+% We temporarily put our own global table in place and restore
+% whatever we overloaded afterwards.
+%
+% \CONTEXT\ modules each have a custom logging mechanism that can be
+% enabled for debugging.
+% In order to fake the presence of this facility we need to define at
+% least the function \verb|logs.reporter|.
+% For now it’s sufficient to make it a reference to \verb|mklog| as
+% defined above.
+%
+% \begin{macrocode}
+
+local dummy_function = function ( ) end
+local newline = function ( ) texiowrite_nl"" end
+
+local fake_logs = function (name)
+ return {
+ name = name,
+ enable = dummy_function,
+ disable = dummy_function,
+ reporter = mklog,
+ newline = newline
+ }
+end
+
+local fake_trackers = function (name)
+ return {
+ name = name,
+ enable = dummy_function,
+ disable = dummy_function,
+ register = mklog,
+ newline = newline,
+ }
+end
+
+local backup_store = { }
+
+local fake_context = function ( )
+ if logs then backup_store.logs = logs end
+ if trackers then backup_store.trackers = trackers end
+ logs = fake_logs"logs"
+ trackers = fake_trackers"trackers"
+end
+
+
+% \end{macrocode}
+% Restore a backed up logger if appropriate.
+%
+% \begin{macrocode}
+local unfake_context = function ( )
+ if backup_store then
+ local bl, bt = backup_store.logs, backup_store.trackers
+ if bl then logs = bl end
+ if bt then trackers = bt end
+ end
+end
+
+fake_context()
+
+local loaded = false
+if lualibs.prefer_merged then
+ info"Loading merged package for collection “extendedâ€."
+ loaded = loadmodule('lualibs-extended-merged.lua')
+else
+ info"Ignoring merged packages."
+ info"Falling back to individual libraries from collection “extendedâ€."
+end
+
+if loaded == false then
+ loadmodule("lualibs-util-str.lua")--- string formatters (fast)
+ loadmodule("lualibs-util-fil.lua")--- extra file helpers
+ loadmodule("lualibs-util-tab.lua")--- extended table operations
+ loadmodule("lualibs-util-sto.lua")--- storage (hash allocation)
+ ----------("lualibs-util-pck.lua")---!packers; necessary?
+ ----------("lualibs-util-seq.lua")---!sequencers (function chaining)
+ ----------("lualibs-util-mrg.lua")---!only relevant in mtx-package
+ loadmodule("lualibs-util-prs.lua")--- miscellaneous parsers; cool. cool cool cool
+ ----------("lualibs-util-fmt.lua")---!column formatter (rarely used)
+ loadmodule("lualibs-util-dim.lua")--- conversions between dimensions
+ loadmodule("lualibs-util-jsn.lua")--- JSON parser
+
+ ----------("lualibs-trac-set.lua")---!generalization of trackers
+ ----------("lualibs-trac-log.lua")---!logging
+ loadmodule("lualibs-trac-inf.lua")--- timing/statistics
+ loadmodule("lualibs-util-lua.lua")--- operations on lua bytecode
+ loadmodule("lualibs-util-deb.lua")--- extra debugging
+ loadmodule("lualibs-util-tpl.lua")--- templating
+ loadmodule("lualibs-util-sta.lua")--- stacker (for writing pdf)
+end
+
+unfake_context() --- TODO check if this works at runtime
+
+lualibs.extended_loaded = true
+-- vim:tw=71:sw=2:ts=2:expandtab
+
+% \end{macrocode}
+%
+% \iffalse
+%</extended>
+% \fi
+%
+% \Finale
+\endinput
diff --git a/macros/luatex/generic/lualibs/lualibs.pdf b/macros/luatex/generic/lualibs/lualibs.pdf
new file mode 100644
index 0000000000..ad1ee3061b
--- /dev/null
+++ b/macros/luatex/generic/lualibs/lualibs.pdf
Binary files differ
diff --git a/macros/luatex/generic/luamplib/Makefile b/macros/luatex/generic/luamplib/Makefile
new file mode 100644
index 0000000000..a842e2c30b
--- /dev/null
+++ b/macros/luatex/generic/luamplib/Makefile
@@ -0,0 +1,96 @@
+NAME = luamplib
+FORMAT = luatex
+
+DTX = $(NAME).dtx
+DOC = $(NAME).pdf
+STY = $(NAME).sty
+LUA = $(NAME).lua
+TEST = test-$(NAME)-plain.tex test-$(NAME)-latex.tex
+
+UNPACKED = $(STY) $(LUA)
+GENERATED = $(UNPACKED) $(DOC)
+SOURCES = $(DTX) README NEWS Makefile $(TEST)
+
+DOCFILES = $(DOC) $(TEST) README NEWS
+SRCFILES = $(DTX) Makefile
+RUNFILES = $(STY) $(LUA)
+
+ALL = $(SRCFILES) $(DOCFILES) $(RUNFILES)
+
+RUNDIR = $(TEXMFDIR)/tex/$(FORMAT)/$(NAME)
+DOCDIR = $(TEXMFDIR)/doc/$(FORMAT)/$(NAME)
+SRCDIR = $(TEXMFDIR)/source/$(FORMAT)/$(NAME)
+TEXMFDIR = $(shell kpsewhich --var-value TEXMFHOME)
+
+CTAN_ZIP = $(NAME).zip
+TDS_ZIP = $(NAME).tds.zip
+ZIPS = $(CTAN_ZIP) $(TDS_ZIP)
+
+all: $(GENERATED)
+doc: $(DOC)
+unpack: $(UNPACKED)
+ctan: check $(CTAN_ZIP)
+tds: $(TDS_ZIP)
+world: all ctan
+
+.PHONY: all doc unpack ctan tds check world
+
+%.pdf: %.dtx
+ latexmk -lualatex -recorder- -silent $< >/dev/null
+
+$(UNPACKED): $(DTX)
+ luatex -interaction=batchmode $< >/dev/null
+
+check: $(UNPACKED)
+ luatex -interaction=batchmode test-$(NAME)-plain.tex >/dev/null
+ lualatex -interaction=batchmode test-$(NAME)-latex.tex >/dev/null
+ ! grep "blank space" test-$(NAME)-plain.log
+ ! grep "blank space" test-$(NAME)-latex.log
+
+$(CTAN_ZIP): $(SOURCES) $(DOC) $(TDS_ZIP)
+ @echo "Making $@ for CTAN upload."
+ @$(RM) -- $@
+ @mkdir -p $(NAME)
+ @cp -f $(SOURCES) $(DOC) $(NAME)
+ @zip -q -9 -r $@ $(TDS_ZIP) $(NAME)
+ @$(RM) -r $(NAME)
+
+define run-install
+@mkdir -p $(RUNDIR) && cp $(RUNFILES) $(RUNDIR)
+@mkdir -p $(DOCDIR) && cp $(DOCFILES) $(DOCDIR)
+@mkdir -p $(SRCDIR) && cp $(SRCFILES) $(SRCDIR)
+endef
+
+$(TDS_ZIP): TEXMFDIR=./tmp-texmf
+$(TDS_ZIP): $(ALL)
+ @echo "Making TDS-ready archive $@."
+ @$(RM) -- $@
+ @if test -e $(TEXMFDIR); then echo 'bad TEXMFDIR'; false; fi
+ $(run-install)
+ @cd $(TEXMFDIR) && zip -q -9 ../$@ -r .
+ @$(RM) -r -- $(TEXMFDIR)
+
+.PHONY: install clean mrproper help
+
+install: check $(ALL)
+ @echo "Installing in '$(TEXMFDIR)'."
+ $(run-install)
+
+clean:
+ @latexmk -silent -c $(DTX) *.tex >/dev/null
+ @rm -f -- *.log test*.pdf
+
+mrproper: clean
+ @rm -f -- $(GENERATED) $(ZIPS)
+
+help:
+ @echo '$(NAME) makefile targets:'
+ @echo ' help - (this message)'
+ @echo ' all - (default target) all generated files'
+ @echo ' world - synonymous for ctan'
+ @echo ' unpack - extract all files'
+ @echo ' doc - compile documentation'
+ @echo ' ctan - run check & generate archive for CTAN'
+ @echo ' tds - generate a TDS compliant archive'
+ @echo ' check - run the test files'
+ @echo ' install TEXMFDIR=<path> - install in <path>'
diff --git a/macros/luatex/generic/luamplib/NEWS b/macros/luatex/generic/luamplib/NEWS
new file mode 100644
index 0000000000..22279f9c35
--- /dev/null
+++ b/macros/luatex/generic/luamplib/NEWS
@@ -0,0 +1,202 @@
+ History of the luamplib package
+
+2019/03/26 2.20.1
+ * '\mpdim' and '\mpcolor' are allowed, even if '\mplibverbatim' is enabled.
+
+2019/03/20 2.20.0
+ * huge changes, but mostly internal, so apparently not much difference
+ from previous version.
+ * '\mplibforcehmode' makes mplibcode typeset in horizontal mode.
+ '\mplibnoforcehmode' reverts the setting. The latter is default.
+ * '\mpliblegacybehavior{disable}' triggers a new mode of processing
+ verbatimtex .. etex: along with btex .. etex, they will be processed
+ sequentially one by one. Old behavior, being default, can be restored
+ by declaring '\mpliblegacybehavior{enable}'.
+ Incidentally, verbatimtex .. etex in MP input files is honored
+ from this version, save those that contain '\documentclass'
+ or '\begin{document}' etc, which is totally ignored.
+
+2018/09/27 2.12.5
+ * change dash.offset pattern from "%i" to "%f" (PR #77)
+ * remove unnecessary variables that go back to context (issue #76)
+
+2018/04/16 2.12.4
+ * workaround issue #74 relating to PATH limitation
+ * substitute InconsolataN font for Liberation Mono in the manual
+
+2018/04/06 2.12.3
+ * step copyright year
+ * remove a line relating graphictext hindrance
+
+2018/01/04 2.12.2
+ * workaround issue #70 "Labels outside beginfig...endfig are not inherited"
+ * address issue #71 "metafun problem: arrow tips are not filled"
+ by importing luatex-mplib.lua from context beta.
+
+2017/06/02 2.12.1
+ * when \mplibglobaltextext{enable} is declared, metapost variables
+ containing btex ... etex labels can be inherited across code chunks.
+ Of course, \mplibcodeinherit should also be switched on.
+
+2016/03/31 2.11.3
+ * fix a bug regarding nested mplibcode environments (issue #63)
+
+2016/01/02 2.11.2
+ * updates for luatex 0.87
+
+2015/10/02 2.11.1
+ * adapts to latex 2015/10/01 and luatexbase v1.0
+ * allows `btex ... etex' and `verbatimtex ... etex' even when
+ `\mplibverbatim{enable}' is declared.
+
+2015/08/01 2.11.0
+ * after `\mplibverbatim{enable}', contents of mplibcode environment
+ will be read verbatim. So `btex ... etex', `verbatimtex ... etex',
+ `\mpdim', `\mpcolor' are not allowed and all TeX commands will be
+ fed literally into mplib library.
+ * allow access to type1 fonts, which means we can use glyph
+ operator now (luatex rev 5266)
+ * color transparency is now compatible with pgf package and
+ beamer class as well. (luatex 0.80+ is recommended)
+
+2015/03/26 2.10.1
+ * fix bug #55 regarding hash token
+
+2015/03/20 2.10.0
+ * TeX code in `VerbatimTeX()' between `beginfig();' and `endfig;'
+ will be inserted after flushing out the mplib figure.
+ * `\mpcolor' command accepts optional argument: for instance,
+ `\mpcolor[HTML]{FF0000}'.
+
+2015/01/26 2.9.1
+ * fix a bug reported by Herbert Schulz via luatex mailing list
+ (http://tug.org/pipermail/luatex/2015-January/005054.html)
+
+2015/01/05 2.9.0
+ * after declaring `\mplibcodeinherit{enable}', each mplib code chunks
+ will inherit variables/constants/macros defined by previous chunks.
+ On the contrary, the default value `\mplibcodeinherit{disable}' will
+ treat each code chunks as an independent instance, never being affected
+ by other code chunks.
+
+2014/07/04 2.8.1
+ * support color package on plain tex.
+ * fix a failure at `btex \% etex'.
+
+2014/06/17 2.8.0
+ * support color/xcolor/spotcolor packages.
+ On LaTeX, color names or expressions of color/xcolor packages
+ can be used inside mplibcode environment with the command
+ \mpcolor{<color expression>}.
+
+2014/04/25 2.7.0
+ * support DVIPDFMx
+ * default directory for cache is now '$TEXMFVAR/luamplib_cache'
+ * internal changes following LuaTeX engine v0.79 and luatexbase
+ package v0.7
+ * [fix] avoid luatex crash under math_mode 'decimal'
+
+2014/03/26 2.6.1
+ * now luamplib does not disregard 'show' command, even if
+ 'luamplib.showlog' is false. Incidentally, it does not raise
+ error, but just prints a warning, even if output contains
+ no figure.
+ * fix a bug wrt color, which might come to the fore under
+ math mode 'double' or 'decimal'.
+
+2014/03/08 2.6.0
+ * new macro \mplibtextextlabel{enable} enables string labels typeset
+ with textext() instead of infont operator. Every string label
+ thereafter will be typeset with current TeX font.
+ * fixed a bug wrt btex ... etex parsing (issue #39)
+ * [doc] added a mention about \MPllx, \MPlly, \MPurx, and \MPury.
+
+2014/03/01 2.5.3
+ * using \mplibcachedir{<directory path>}, users can change the
+ directory for storing cache files. By default, it is the directory
+ where pdf output file is saved.
+ * at the end of package loading, luamplib searches 'luamplib.cfg',
+ and, when found, reads the file in automatically.
+
+2014/02/24 2.5.2
+ * new macros \mplibmakenocache{...} and \mplibcancelnocache{...} to
+ register/unregister those .mp files that do not need caches.
+ These macros affect the compilation speed only.
+ * added a hack to support graph.mp (in fact, format.mp)
+ * [fix] luamplib now respects percent sign if it is enclosed by quotes.
+
+2014/02/19 2.5
+ * btex ... etex input from external *.mp files will also be processed
+ by luamplib. However, verbatimtex ... etex will be entirely ignored
+ in this case.
+
+2014/02/02 2.4
+ * implemented "numbersystem" option. Default value "scaled" can be
+ changed by declaring \mplibnumbersystem{double}. For details, see
+ http://github.com/lualatex/luamplib/issues/21
+
+2014/01/20 2.3
+ * \everymplib, \everyendmplib: macros that redefine token lists
+ \everymplibtoks and \everyendmplibtoks. These will be
+ automatically inserted at the beginning and ending (respectively)
+ of each and every mplib code.
+ * naked TeX codes, includig \mpdim{...}, are allowed inside
+ mplibcode environment. Refer the manual of gmp package for
+ details.
+
+2013/12/30 2.2
+ * start to support transparency/shading under metafun format.
+ * verbatimtex ... etex just before beginfig() is not ignored.
+ Using this macro, each mplib box can be moved horizontally and/or
+ vertically.
+
+2013/12/23 2.1.1
+ * fix a bug wrt "withoutcolor" option
+ * fix a bug wrt "char <number> infont <font>" picture
+ * bypass some ConTeXt commands which raise errors under metafun format
+ * ignore "fontmapfile <filename>" which isn't needed in mplib
+
+2013/12/19 2.1
+ * Do not ignore "withcolor" option for textext and normal text object
+ * verbatimtex ... etex is now just ignored, not raising error
+
+2013/12/11 2.03
+ * implemented textext() macro which is identical to TEX() from TEX.mp.
+ TEX() is a synonym of textext().
+ * fix a bug regarding tex-text box inside for...endfor loop,
+ reported at http://www.ktug.org/xe/index.php?document_srl=178050
+
+2013/09/24 2.01
+ * fix bug reported by Stephan Hennig: wrong baseline of tex-text box
+
+2013/05/07 2.0
+ * Update with current ConTeXt code
+ * Adding the possibility of btex...etex commands (Kim)
+
+2011/12/09 1.09
+ * Fix bug reported by Paul Vojta: spurious spaces.
+
+2011/06/23 1.08
+ * Fix bug reported by Rolf Dieterich: <, >, TAB anywhere in a luacode
+ environment caused errors. The character ` was affected too.
+
+2010/12/28 1.07
+ * fix two bugs reported by Arno Trautmann that made the package crash with
+ luatex 0.65 (mp 1.5+).
+ * remove support for using .mem files (to fix the second bug)
+
+2010/10/17 v1.06
+ * bugfix from Hans (bad function name)
+
+2010/10/10 v1.05
+ * adapt to luatexbase v0.3
+
+2010/08/02 v1.04
+ * fixing a bug in LaTeX's detection (made Tikz fail)
+ * setting luamplib-luatex as the default name for the format, it's the case
+ in TeXLive 2010
+ * adding two test files in the git repository
+
+2010/05/10 v1.03
+ * adaptation to the new luatexbase package
+
diff --git a/macros/luatex/generic/luamplib/README b/macros/luatex/generic/luamplib/README
new file mode 100644
index 0000000000..9518912982
--- /dev/null
+++ b/macros/luatex/generic/luamplib/README
@@ -0,0 +1,62 @@
+ The luamplib generic package.
+
+
+This package allows typesetting of metapost natively in the TeX documents
+thanks to the LuaTeX mplib library. It works in PDF or DVI mode, but
+DVIPDFMx is the only DVI tool currently supported.
+
+This package is developed on <http://github.com/lualatex/luamplib>.
+
+
+Installation
+------------
+
+Here are the recommended installation methods (preferred first).
+
+1. If you are using TeX Live 2008 or later, use 'tlmgr install luamplib'.
+Alternatively, try your (TeX or Linux) distribution's package management system.
+
+2. a. Grab the sources from CTAN or github.
+ b. Run 'make install TEXMFDIR=/path/to/texmf'.
+ c. You may need to update some filename database after, see your TeX
+distribution's manual for details.
+
+3. Try to figure it out by looking at the Makefile and comments in the sources.
+
+
+Manifest
+--------
+
+Source files:
+ luamplib.dtx single file source & doc
+
+Derived files:
+ luamplib.pdf documentation
+ luamplib.sty package
+ luamplib.lua lua code used by the package
+
+
+License
+-------
+
+The luamplib bundle, as a derived work of ConTeXt, is distributed under the
+GNU GPLv2 license:
+
+ <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
+
+This license requires the license itself to be distributed with the work. For
+its full text see the documentation in luamplib.pdf.
+
+
+ DISCLAIMER
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; version 2.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ See headers of each source file for copyright details.
diff --git a/macros/luatex/generic/luamplib/luamplib.dtx b/macros/luatex/generic/luamplib/luamplib.dtx
new file mode 100644
index 0000000000..8524830d78
--- /dev/null
+++ b/macros/luatex/generic/luamplib/luamplib.dtx
@@ -0,0 +1,2713 @@
+% \iffalse meta-comment -- by the way, this file contains UTF-8
+%
+% Copyright (C) 2008-2019 by Hans Hagen, Taco Hoekwater, Elie Roux,
+% Manuel Pégourié-Gonnard, Philipp Gesang and Kim Dohyun.
+% Currently maintained by the LuaLaTeX development team.
+% Support: <lualatex-dev@tug.org>
+%
+% This work is under the GPL v2.0 license.
+%
+% This work consists of the main source file luamplib.dtx
+% and the derived files
+% luamplib.sty, luamplib.lua and luamplib.pdf.
+%
+% Unpacking:
+% tex luamplib.dtx
+%
+% Documentation:
+% lualatex luamplib.dtx
+%
+%<*ignore>
+\begingroup
+ \def\x{LaTeX2e}%
+\expandafter\endgroup
+\ifcase 0\ifx\install y1\fi\expandafter
+ \ifx\csname processbatchFile\endcsname\relax\else1\fi
+ \ifx\fmtname\x\else 1\fi\relax
+\else\csname fi\endcsname
+%</ignore>
+%<*install>
+\input docstrip.tex
+\Msg{************************************************************************}
+\Msg{* Installation}
+\Msg{* Package: luamplib - metapost package for LuaTeX.}
+\Msg{************************************************************************}
+
+\keepsilent
+\askforoverwritefalse
+
+\let\MetaPrefix\relax
+
+\preamble
+
+See source file '\inFileName' for licencing and contact information.
+
+\endpreamble
+
+\let\MetaPrefix\DoubleperCent
+
+\generate{%
+ \usedir{tex/luatex/luamplib}%
+ \file{luamplib.sty}{\from{luamplib.dtx}{package}}%
+}
+
+\def\MetaPrefix{-- }
+
+\def\luapostamble{%
+ \MetaPrefix^^J%
+ \MetaPrefix\space End of File `\outFileName'.%
+}
+
+\def\currentpostamble{\luapostamble}%
+
+\generate{%
+ \usedir{tex/luatex/luamplib}%
+ \file{luamplib.lua}{\from{luamplib.dtx}{lua}}%
+}
+
+\obeyspaces
+\Msg{************************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* files into a directory searched by TeX:}
+\Msg{*}
+\Msg{* luamplib.sty luamplib.lua}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesFile{luamplib.drv}%
+ [2019/03/26 v2.20.1 Interface for using the mplib library]%
+\documentclass{ltxdoc}
+\usepackage{metalogo,multicol,mdwlist,fancyvrb,xspace}
+\usepackage[x11names]{xcolor}
+%
+\def\primarycolor{DodgerBlue4} %%-> rgb 16 78 139 | #104e8b
+\def\secondarycolor{Goldenrod4} %%-> rgb 139 105 200 | #8b6914
+%
+\usepackage[
+ bookmarks=true,
+ colorlinks=true,
+ linkcolor=\primarycolor,
+ urlcolor=\secondarycolor,
+ citecolor=\primarycolor,
+ pdftitle={The luamplib package},
+ pdfsubject={Interface for using the mplib library},
+ pdfauthor={Hans Hagen, Taco Hoekwater, Elie Roux, Philipp Gesang & Kim Dohyun},
+ pdfkeywords={luatex, lualatex, mplib, metapost}
+]{hyperref}
+\usepackage{fontspec}
+\setmainfont[
+ Numbers = OldStyle,
+ Ligatures = TeX,
+ BoldFont = {Linux Libertine O Bold},
+ ItalicFont = {Linux Libertine O Italic},
+ SlantedFont = {Linux Libertine O Italic},
+]{Linux Libertine O}
+\setmonofont[Ligatures=TeX,Scale=MatchLowercase]{InconsolataN}
+%setsansfont[Ligatures=TeX]{Linux Biolinum O}
+\setsansfont[Ligatures=TeX,Scale=MatchLowercase]{Iwona Medium}
+%setmathfont{XITS Math}
+
+\usepackage{hologo}
+
+\newcommand\ConTeXt {Con\TeX t\xspace}
+
+\newcommand*\email [1] {<\href{mailto:#1}{#1}>}
+\newcommand \file {\nolinkurl}
+\newcommand \pk {\textsf}
+
+\begin{document}
+ \DocInput{luamplib.dtx}%
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{0}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+% \title{The \textsf{luamplib} package}
+% \author{Hans Hagen, Taco Hoekwater, Elie Roux, Philipp Gesang and Kim Dohyun\\
+% Maintainer: LuaLaTeX Maintainers ---
+% Support: \email{lualatex-dev@tug.org}}
+% \date{2019/03/26 v2.20.1}
+%
+% \maketitle
+%
+% \begin{abstract}
+% Package to have metapost code typeset directly in a document with \LuaTeX.
+% \end{abstract}
+%
+% \section{Documentation}
+%
+% This packages aims at providing a simple way to typeset directly metapost
+% code in a document with \LuaTeX. \LuaTeX\ is built with the lua
+% \texttt{mplib} library, that runs metapost code. This package is basically a
+% wrapper (in Lua) for the Lua \texttt{mplib} functions and some \TeX\
+% functions to have the output of the \texttt{mplib} functions in the pdf.
+%
+% In the past,
+% the package required PDF mode in order to output something.
+% Starting with version 2.7 it works in DVI mode as well, though
+% DVIPDFMx is the only DVI tool currently supported.
+%
+% The metapost figures are put in a \TeX\ \texttt{hbox} with dimensions
+% adjusted to the metapost code.
+%
+% Using this package is easy: in Plain, type your metapost code between the
+% macros \cs{mplibcode} and \cs{endmplibcode}, and in \LaTeX\ in the
+% \texttt{mplibcode} environment.
+%
+% The code is from the \texttt{luatex-mplib.lua} and \texttt{luatex-mplib.tex} files
+% from \ConTeXt, they have been adapted to \LaTeX\ and Plain by Elie Roux and
+% Philipp Gesang, new functionalities have been added by Kim Dohyun.
+% The changes are:
+%
+% \begin{itemize}
+% \item a \LaTeX\ environment
+% \item all \TeX\ macros start by |mplib|
+% \item use of luatexbase for errors, warnings and declaration
+% \item possibility to use |btex ... etex| to typeset \TeX\ code.
+% |textext()| is a more versatile macro equivalent to |TEX()| from TEX.mp.
+% |TEX()| is also allowed and is a synomym of |textext()|.\par\smallskip
+% \textsc{n.b.} Since v2.5, |btex ... etex| input from external |mp| files
+% will also be processed by \textsf{luamplib}.\par\smallskip
+% \textsc{n.b.} Since v2.20, |verbatimtex ... etex| from external |mp| files
+% will be also processed by \textsf{luamplib}. Warning: This is a change
+% from previous version.
+% \end{itemize}
+%
+% Some more changes and cautions are:
+%
+% \paragraph{\cs{mplibforcehmode}}
+% When this macro is declared, every mplibcode figure box will be
+% typeset in horizontal mode, so \cs{centering}, \cs{raggedleft} etc
+% will have effects. |\mplibnoforcehmode|, being default, reverts this
+% setting.
+%
+% \paragraph{\cs{mpliblegacybehavior\{enable\}}}
+% By default, |\mpliblegacybehavior{enable}| is already declared,
+% in which case
+% a |verbatimtex ... etex| that comes just before |beginfig()|
+% is not ignored, but the \TeX\ code will be inserted before the
+% following mplib hbox. Using this command,
+% each mplib box can be freely moved horizontally and/or vertically.
+% Also, a box number might be assigned to mplib box, allowing it to be
+% reused later (see test files).
+% \begin{verbatim}
+% \mplibcode
+% verbatimtex \moveright 3cm etex; beginfig(0); ... endfig;
+% verbatimtex \leavevmode etex; beginfig(1); ... endfig;
+% verbatimtex \leavevmode\lower 1ex etex; beginfig(2); ... endfig;
+% verbatimtex \endgraf\moveright 1cm etex; beginfig(3); ... endfig;
+% \endmplibcode
+% \end{verbatim}
+% \textsc{n.b.} \cs{endgraf} should be used instead of \cs{par} inside
+% |verbatimtex ... etex|.
+%
+% By contrast, \TeX\ code in |VerbatimTeX(...)| or |verbatimtex ... etex|
+% between |beginfig()| and |endfig| will be inserted
+% after flushing out the mplib figure.
+% \begin{verbatim}
+% \mplibcode
+% D := sqrt(2)**7;
+% beginfig(0);
+% draw fullcircle scaled D;
+% VerbatimTeX("\gdef\Dia{" & decimal D & "}");
+% endfig;
+% \endmplibcode
+% diameter: \Dia bp.
+% \end{verbatim}
+%
+% \paragraph{\cs{mpliblegacybehavior\{disable\}}}
+% If |\mpliblegacybehavior{disabled}| is declared by user, any
+% |verbatimtex ... etex| will be executed, along with |btex ... etex|,
+% sequentially one by one.
+% So, some \TeX\ code in |verbatimtex ... etex| will have effects on
+% |btex ... etex| codes that follows.
+% \begin{verbatim}
+% \begin{mplibcode}
+% beginfig(0);
+% draw btex ABC etex;
+% verbatimtex \bfseries etex;
+% draw btex DEF etex shifted (1cm,0); % bold face
+% draw btex GHI etex shifted (2cm,0); % bold face
+% endfig;
+% \end{mplibcode}
+% \end{verbatim}
+%
+% \paragraph{About figure box metrics}
+% Notice that, after each figure is processed, macro \cs{MPwidth} stores
+% the width value of latest figure; \cs{MPheight}, the height value.
+% Incidentally, also note that \cs{MPllx}, \cs{MPlly}, \cs{MPurx}, and
+% \cs{MPury} store the bounding box information of latest figure
+% without the unit |bp|.
+%
+% \paragraph{\cs{everymplib}, \cs{everyendmplib}}
+% Since v2.3, new macros \cs{everymplib} and \cs{everyendmplib} redefine
+% token lists \cs{everymplibtoks} and \cs{everyendmplibtoks} respectively,
+% which will
+% be automatically inserted at the beginning and ending of each mplib code.
+% \begin{verbatim}
+% \everymplib{ beginfig(0); }
+% \everyendmplib{ endfig; }
+% \mplibcode % beginfig/endfig not needed
+% draw fullcircle scaled 1cm;
+% \endmplibcode
+% \end{verbatim}
+%
+% \paragraph{\cs{mpdim}}
+% Since v2.3, \cs{mpdim} and other raw \TeX\ commands are allowed
+% inside mplib code. This feature is inpired by gmp.sty authored by
+% Enrico Gregorio. Please refer the manual of gmp package for details.
+% \begin{verbatim}
+% \begin{mplibcode}
+% draw origin--(\mpdim{\linewidth},0) withpen pencircle scaled 4
+% dashed evenly scaled 4 withcolor \mpcolor{orange};
+% \end{mplibcode}
+% \end{verbatim}
+% \textsc{n.b.} Users should not use the protected variant of
+% |btex ... etex| as provided by gmp package. As \textsf{luamplib}
+% automatically protects \TeX\ code inbetween, \cs{btex} is not supported
+% here.
+%
+% \paragraph{\cs{mpcolor}}
+% With \cs{mpcolor} command, color names or expressions of
+% \textsf{color}/\textsf{xcolor} packages can be used inside mplibcode
+% enviroment, though \textsf{luamplib} does not automatically load these
+% packages. See the example code above. For spot colors, \textsf{(x)spotcolor}
+% (in PDF mode) and \textsf{xespotcolor} (in DVI mode) packages are supported
+% as well.
+%
+% \paragraph{\cs{mplibnumbersystem}}
+% Users can choose |numbersystem| option since v2.4.
+% The default value |scaled| can be changed to |double| or |decimal|
+% by declaring |\mplibnumbersystem{double}| or |\mplibnumbersystem{decimal}|.
+% For details see
+% \url{http://github.com/lualatex/luamplib/issues/21}.
+%
+% \paragraph{Settings regarding cache files}
+% To support |btex ... etex| in external |.mp| files, \textsf{luamplib}
+% inspects the content of each and every |.mp| input files and makes caches
+% if nececcsary, before returning their paths to \LuaTeX's mplib library.
+% This would make the compilation time longer wastefully, as most |.mp| files
+% do not contain |btex ... etex| command. So \textsf{luamplib} provides
+% macros as follows, so that users can give instruction about files
+% that do not require this functionality.
+% \begin{itemize}
+% \item |\mplibmakenocache{<filename>[,<filename>,...]}|
+% \item |\mplibcancelnocache{<filename>[,<filename>,...]}|
+% \end{itemize}
+% where |<filename>| is a file name excluding |.mp| extension.
+% Note that |.mp| files under |$TEXMFMAIN/metapost/base| and
+% |$TEXMFMAIN/metapost/context/base| are already registered by default.
+%
+% By default, cache files will be stored in |$TEXMFVAR/luamplib_cache| or,
+% if it's not available, in the same directory as where pdf/dvi output file
+% is saved. This however can be changed by the command
+% |\mplibcachedir{<directory path>}|, where tilde (|~|) is interpreted
+% as the user's home directory (on a windows machine as well).
+% As backslashes (|\|) should be escaped by users, it would be easier to use
+% slashes (|/|) instead.
+%
+% \paragraph{\cs{mplibtextextlabel}}
+% Starting with v2.6, |\mplibtextextlabel{enable}| enables
+% string labels typeset via |textext()| instead of |infont| operator.
+% So, |label("my text",origin)| thereafter is exactly the same as
+% |label(textext("my text"),origin)|. \textsc{n.b.} In the background,
+% \textsf{luamplib} redefines |infont| operator so that the right side
+% argument (the font part) is totally ignored. Every string label
+% therefore will be typeset with current \TeX\ font.
+% Also take care of |char| operator in the left side argument,
+% as this might bring unpermitted characters into \TeX.
+%
+% \paragraph{\cs{mplibcodeinherit}}
+% Starting with v2.9, |\mplibcodeinherit{enable}| enables the inheritance
+% of variables, constants, and macros defined by previous |mplibcode| chunks.
+% On the contrary, the default value |\mplibcodeinherit{disable}| will make
+% each code chunks being treated as an independent instance, and never
+% affected by previous code chunks.
+%
+% \paragraph{\cs{mplibglobaltextext}}
+% To inherit |btex ... etex| labels as well as metapost variables,
+% it is necessary to declare \cs{mplibglobaltextext\{enable\}} in advance.
+% On this case, be careful that normal \TeX\ boxes can conflict with
+% |btex ... etex| boxes, though this would occur very rarely.
+% Notwithstanding the danger, it is a `must' option to activate
+% \cs{mplibglobaltextext} if you want to use |graph.mp|
+% with \cs{mplibcodeinherit} functionality.
+% \begin{verbatim}
+% \mplibcodeinherit{enable}
+% \mplibglobaltextext{enable}
+% \everymplib{ beginfig(0);} \everyendmplib{ endfig;}
+% \mplibcode
+% label(btex $\sqrt{2}$ etex, origin);
+% draw fullcircle scaled 20;
+% picture pic; pic := currentpicture;
+% \endmplibcode
+% \mplibcode
+% currentpicture := pic scaled 2;
+% \endmplibcode
+% \end{verbatim}
+%
+% \paragraph{\cs{mplibverbatim}}
+% Starting with v2.11, users can issue |\mplibverbatim{enable}|, after which
+% the contents of mplibcode environment will be read verbatim. As a result,
+% except for |\mpdim| and |\mpcolor|, all other \TeX\ commands outside
+% |btex ... etex| or |verbatimtex ... etex| are not expanded and will be fed
+% literally into the mplib process.
+%
+% \paragraph{luamplib.cfg}
+% At the end of package loading, \textsf{luamplib} searches
+% |luamplib.cfg| and, if found, reads the file in automatically.
+% Frequently used settings such as \cs{everymplib} or \cs{mplibforcehmode}
+% are suitable for going into this file.
+%
+% \bigskip
+%
+% There are (basically) two formats for metapost: \emph{plain} and
+% \emph{metafun}. By default, the \emph{plain} format is used, but you can set
+% the format to be used by future figures at any time using
+% \cs{mplibsetformat}\marg{format name}.
+%
+% \section{Implementation}
+%
+% \subsection{Lua module}
+%
+% \iffalse
+%<*lua>
+% \fi
+%
+% \begin{macrocode}
+
+luatexbase.provides_module {
+ name = "luamplib",
+ version = "2.20.1",
+ date = "2019/03/26",
+ description = "Lua package to typeset Metapost with LuaTeX's MPLib.",
+}
+
+local format, abs = string.format, math.abs
+
+local err = function(...) return luatexbase.module_error ("luamplib", format(...)) end
+local warn = function(...) return luatexbase.module_warning("luamplib", format(...)) end
+local info = function(...) return luatexbase.module_info ("luamplib", format(...)) end
+
+% \end{macrocode}
+%
+% Use the |luamplib| namespace, since |mplib| is for the metapost library
+% itself. \ConTeXt{} uses |metapost|.
+% \begin{macrocode}
+luamplib = luamplib or { }
+local luamplib = luamplib
+
+luamplib.showlog = luamplib.showlog or false
+luamplib.lastlog = ""
+
+% \end{macrocode}
+%
+% This module is a stripped down version of libraries that are used by
+% \ConTeXt. Provide a few ``shortcuts'' expected by the imported code.
+% \begin{macrocode}
+local tableconcat = table.concat
+local texsprint = tex.sprint
+local textprint = tex.tprint
+
+local texget = tex.get
+local texgettoks = tex.gettoks
+local texgetbox = tex.getbox
+local texruntoks = tex.runtoks
+% \end{macrocode}
+%
+% We don't use |tex.scantoks| anymore. See below reagrding |tex.runtoks|.
+% \begin{verbatim}
+% local texscantoks = tex.scantoks
+% \end{verbatim}
+% \begin{macrocode}
+
+if not texruntoks then
+ err("Your LuaTeX version is too old. Please upgrade it to the latest")
+end
+
+local mplib = require ('mplib')
+local kpse = require ('kpse')
+local lfs = require ('lfs')
+
+local lfsattributes = lfs.attributes
+local lfsisdir = lfs.isdir
+local lfsmkdir = lfs.mkdir
+local lfstouch = lfs.touch
+local ioopen = io.open
+
+% \end{macrocode}
+%
+% Some helper functions, prepared for the case when |l-file| etc
+% is not loaded.
+% \begin{macrocode}
+local file = file or { }
+local replacesuffix = file.replacesuffix or function(filename, suffix)
+ return (filename:gsub("%.[%a%d]+$","")) .. "." .. suffix
+end
+local stripsuffix = file.stripsuffix or function(filename)
+ return (filename:gsub("%.[%a%d]+$",""))
+end
+
+local is_writable = file.is_writable or function(name)
+ if lfsisdir(name) then
+ name = name .. "/_luam_plib_temp_file_"
+ local fh = ioopen(name,"w")
+ if fh then
+ fh:close(); os.remove(name)
+ return true
+ end
+ end
+end
+local mk_full_path = lfs.mkdirs or function(path)
+ local full = ""
+ for sub in path:gmatch("(/*[^\\/]+)") do
+ full = full .. sub
+ lfsmkdir(full)
+ end
+end
+
+% \end{macrocode}
+%
+% |btex ... etex| in input |.mp| files will be replaced in finder.
+% Because of the limitation of MPLib regarding |make_text|,
+% we might have to make cache files modified from input files.
+% \begin{macrocode}
+local luamplibtime = kpse.find_file("luamplib.lua")
+luamplibtime = luamplibtime and lfsattributes(luamplibtime,"modification")
+
+local currenttime = os.time()
+
+local outputdir
+if lfstouch then
+ local texmfvar = kpse.expand_var('$TEXMFVAR')
+ if texmfvar and texmfvar ~= "" and texmfvar ~= '$TEXMFVAR' then
+ for _,dir in next, texmfvar:explode(os.type == "windows" and ";" or ":") do
+ if not lfsisdir(dir) then
+ mk_full_path(dir)
+ end
+ if is_writable(dir) then
+ local cached = format("%s/luamplib_cache",dir)
+ lfsmkdir(cached)
+ outputdir = cached
+ break
+ end
+ end
+ end
+end
+if not outputdir then
+ outputdir = "."
+ for _,v in ipairs(arg) do
+ local t = v:match("%-output%-directory=(.+)")
+ if t then
+ outputdir = t
+ break
+ end
+ end
+end
+
+function luamplib.getcachedir(dir)
+ dir = dir:gsub("##","#")
+ dir = dir:gsub("^~",
+ os.type == "windows" and os.getenv("UserProfile") or os.getenv("HOME"))
+ if lfstouch and dir then
+ if lfsisdir(dir) then
+ if is_writable(dir) then
+ luamplib.cachedir = dir
+ else
+ warn("Directory '"..dir.."' is not writable!")
+ end
+ else
+ warn("Directory '"..dir.."' does not exist!")
+ end
+ end
+end
+
+% \end{macrocode}
+%
+% Some basic MetaPost files not necessary to make cache files.
+% \begin{macrocode}
+local noneedtoreplace = {
+ ["boxes.mp"] = true, -- ["format.mp"] = true,
+ ["graph.mp"] = true, ["marith.mp"] = true, ["mfplain.mp"] = true,
+ ["mpost.mp"] = true, ["plain.mp"] = true, ["rboxes.mp"] = true,
+ ["sarith.mp"] = true, ["string.mp"] = true, -- ["TEX.mp"] = true,
+ ["metafun.mp"] = true, ["metafun.mpiv"] = true, ["mp-abck.mpiv"] = true,
+ ["mp-apos.mpiv"] = true, ["mp-asnc.mpiv"] = true, ["mp-bare.mpiv"] = true,
+ ["mp-base.mpiv"] = true, ["mp-blob.mpiv"] = true, ["mp-butt.mpiv"] = true,
+ ["mp-char.mpiv"] = true, ["mp-chem.mpiv"] = true, ["mp-core.mpiv"] = true,
+ ["mp-crop.mpiv"] = true, ["mp-figs.mpiv"] = true, ["mp-form.mpiv"] = true,
+ ["mp-func.mpiv"] = true, ["mp-grap.mpiv"] = true, ["mp-grid.mpiv"] = true,
+ ["mp-grph.mpiv"] = true, ["mp-idea.mpiv"] = true, ["mp-luas.mpiv"] = true,
+ ["mp-mlib.mpiv"] = true, ["mp-node.mpiv"] = true, ["mp-page.mpiv"] = true,
+ ["mp-shap.mpiv"] = true, ["mp-step.mpiv"] = true, ["mp-text.mpiv"] = true,
+ ["mp-tool.mpiv"] = true,
+}
+luamplib.noneedtoreplace = noneedtoreplace
+
+% \end{macrocode}
+%
+% |format.mp| is much complicated, so specially treated.
+% \begin{macrocode}
+local function replaceformatmp(file,newfile,ofmodify)
+ local fh = ioopen(file,"r")
+ if not fh then return file end
+ local data = fh:read("*all"); fh:close()
+ fh = ioopen(newfile,"w")
+ if not fh then return file end
+ fh:write(
+ "let normalinfont = infont;\n",
+ "primarydef str infont name = rawtextext(str) enddef;\n",
+ data,
+ "vardef Fmant_(expr x) = rawtextext(decimal abs x) enddef;\n",
+ "vardef Fexp_(expr x) = rawtextext(\"$^{\"&decimal x&\"}$\") enddef;\n",
+ "let infont = normalinfont;\n"
+ ); fh:close()
+ lfstouch(newfile,currenttime,ofmodify)
+ return newfile
+end
+
+% \end{macrocode}
+%
+% Replace |btex ... etex| and |verbatimtex ... etex| in input files,
+% if needed.
+% \begin{macrocode}
+local name_b = "%f[%a_]"
+local name_e = "%f[^%a_]"
+local btex_etex = name_b.."btex"..name_e.."%s*(.-)%s*"..name_b.."etex"..name_e
+local verbatimtex_etex = name_b.."verbatimtex"..name_e.."%s*(.-)%s*"..name_b.."etex"..name_e
+
+local function replaceinputmpfile (name,file)
+ local ofmodify = lfsattributes(file,"modification")
+ if not ofmodify then return file end
+ local cachedir = luamplib.cachedir or outputdir
+ local newfile = name:gsub("%W","_")
+ newfile = cachedir .."/luamplib_input_"..newfile
+ if newfile and luamplibtime then
+ local nf = lfsattributes(newfile)
+ if nf and nf.mode == "file" and
+ ofmodify == nf.modification and luamplibtime < nf.access then
+ return nf.size == 0 and file or newfile
+ end
+ end
+
+ if name == "format.mp" then return replaceformatmp(file,newfile,ofmodify) end
+
+ local fh = ioopen(file,"r")
+ if not fh then return file end
+ local data = fh:read("*all"); fh:close()
+
+% \end{macrocode}
+%
+% ``|etex|'' must be followed by a space or semicolon as specified in
+% \LuaTeX\ manual, which is not the case of standalone MetaPost though.
+% \begin{macrocode}
+ local count,cnt = 0,0
+ data, cnt = data:gsub(btex_etex, "btex %1 etex ") -- space
+ count = count + cnt
+ data, cnt = data:gsub(verbatimtex_etex, "verbatimtex %1 etex;") -- semicolon
+ count = count + cnt
+
+ if count == 0 then
+ noneedtoreplace[name] = true
+ fh = ioopen(newfile,"w");
+ if fh then
+ fh:close()
+ lfstouch(newfile,currenttime,ofmodify)
+ end
+ return file
+ end
+
+ fh = ioopen(newfile,"w")
+ if not fh then return file end
+ fh:write(data); fh:close()
+ lfstouch(newfile,currenttime,ofmodify)
+ return newfile
+end
+
+% \end{macrocode}
+%
+% As the finder function for MPLib, use the |kpse| library and
+% make it behave like as if MetaPost was used. And replace it with
+% cache files if needed.
+% \begin{macrocode}
+local mpkpse = kpse.new(arg[0], "mpost")
+
+local special_ftype = {
+ pfb = "type1 fonts",
+ enc = "enc files",
+}
+
+local function finder(name, mode, ftype)
+ if mode == "w" then
+ return name
+ else
+ ftype = special_ftype[ftype] or ftype
+ local file = mpkpse:find_file(name,ftype)
+ if file then
+ if not lfstouch or ftype ~= "mp" or noneedtoreplace[name] then
+ return file
+ end
+ return replaceinputmpfile(name,file)
+ end
+ return mpkpse:find_file(name, name:match("%a+$"))
+ end
+end
+luamplib.finder = finder
+
+% \end{macrocode}
+%
+% Create and load MPLib instances.
+% We do not support ancient version of MPLib any more.
+% (Don't know which version of MPLib started to support
+% |make_text| and |run_script|; let the users find it.)
+% \begin{macrocode}
+if tonumber(mplib.version()) <= 1.50 then
+ err("luamplib no longer supports mplib v1.50 or lower. "..
+ "Please upgrade to the latest version of LuaTeX")
+end
+
+local preamble = [[
+ boolean mplib ; mplib := true ;
+ let dump = endinput ;
+ let normalfontsize = fontsize;
+ input %s ;
+]]
+
+local function luamplibresetlastlog()
+ luamplib.lastlog = ""
+end
+
+local function reporterror (result)
+ if not result then
+ err("no result object returned")
+ else
+ local t, e, l = result.term, result.error, result.log
+ local log = t or l or "no-term"
+ log = log:gsub("^%s+","\n")
+ luamplib.lastlog = luamplib.lastlog .. "\n" .. (l or t or "no-log")
+ if result.status > 0 then
+ warn("%s",log)
+ if result.status > 1 then
+ err("%s",e or "see above messages")
+ end
+ end
+ return log
+ end
+end
+
+local function luamplibload (name)
+ local mpx = mplib.new {
+ ini_version = true,
+ find_file = luamplib.finder,
+% \end{macrocode}
+%
+% Make use of |make_text| and |run_script|, which will co-operate
+% with \LuaTeX's |tex.runtoks|. And we
+% provide |numbersystem| option since v2.4. Default value ``|scaled|''
+% can be changed by declaring |\mplibnumbersystem{double}|
+% or |\mplibnumbersystem{decimal}|.
+% See \url{https://github.com/lualatex/luamplib/issues/21}.
+% \begin{macrocode}
+ make_text = luamplib.maketext,
+ run_script = luamplib.runscript,
+ math_mode = luamplib.numbersystem,
+ extensions = 1,
+ }
+% \end{macrocode}
+%
+% Append our own MetaPost preamble to the preamble above.
+% \begin{macrocode}
+ local preamble = preamble .. luamplib.mplibcodepreamble
+ if luamplib.legacy_verbatimtex then
+ preamble = preamble .. luamplib.legacyverbatimtexpreamble
+ end
+ if luamplib.textextlabel then
+ preamble = preamble .. luamplib.textextlabelpreamble
+ end
+ local result
+ if not mpx then
+ result = { status = 99, error = "out of memory"}
+ else
+ result = mpx:execute(format(preamble, replacesuffix(name,"mp")))
+ end
+ reporterror(result)
+ return mpx, result
+end
+
+% \end{macrocode}
+%
+% |plain| or |metafun|,
+% though we cannot support |metafun| format fully.
+% \begin{macrocode}
+local currentformat = "plain"
+
+local function setformat (name)
+ currentformat = name
+end
+luamplib.setformat = setformat
+
+% \end{macrocode}
+%
+% Here, excute each |mplibcode| data,
+% ie |\begin{mplibcode} ... \end{mplibcode}|.
+% \begin{macrocode}
+local function process_indeed (mpx, data)
+ local converted, result = false, {}
+ if mpx and data then
+ result = mpx:execute(data)
+ local log = reporterror(result)
+ if log then
+ if luamplib.showlog then
+ info("%s",luamplib.lastlog)
+ luamplibresetlastlog()
+ elseif result.fig then
+% \end{macrocode}
+%
+% v2.6.1: now luamplib does not disregard |show| command,
+% even when |luamplib.showlog| is false. Incidentally,
+% it does not raise error but just prints a warning,
+% even if output has no figure.
+% \begin{macrocode}
+ if log:find("\n>>") then info("%s",log) end
+ converted = luamplib.convert(result)
+ else
+ info("%s",log)
+ warn("No figure output. Maybe no beginfig/endfig")
+ end
+ end
+ else
+ err("Mem file unloadable. Maybe generated with a different version of mplib?")
+ end
+ return converted, result
+end
+
+% \end{macrocode}
+%
+% v2.9 has introduced the concept of ``code inherit''
+% \begin{macrocode}
+luamplib.codeinherit = false
+local mplibinstances = {}
+
+local function process (data)
+% \end{macrocode}
+%
+% The workaround of issue \#70 seems to be unnecessary, as we use
+% |make_text| now.
+% \begin{verbatim}
+% if not data:find(name_b.."beginfig%s*%([%+%-%s]*%d[%.%d%s]*%)") then
+% data = data .. "beginfig(-1);endfig;"
+% end
+% \end{verbatim}
+% \begin{macrocode}
+ local standalone = not luamplib.codeinherit
+ local currfmt = currentformat .. (luamplib.numbersystem or "scaled")
+ .. tostring(luamplib.textextlabel) .. tostring(luamplib.legacy_verbatimtex)
+ local mpx = mplibinstances[currfmt]
+ if mpx and standalone then
+ mpx:finish()
+ end
+ if standalone or not mpx then
+ mpx = luamplibload(currentformat)
+ mplibinstances[currfmt] = mpx
+ end
+ return process_indeed(mpx, data)
+end
+
+% \end{macrocode}
+%
+% |make_text| and some |run_script| uses \LuaTeX's |tex.runtoks|,
+% which made possible running \TeX\ code snippets inside |\directlua|.
+% \begin{macrocode}
+local catlatex = luatexbase.registernumber("catcodetable@latex")
+local catat11 = luatexbase.registernumber("catcodetable@atletter")
+
+% \end{macrocode}
+%
+% |tex.scantoks| sometimes fail to read catcode properly, especially
+% |\#|, |\&|, or |\%|. After some experiment, we dropped using it.
+% Instead, a function containing |tex.script| seems to work nicely.
+% \begin{verbatim}
+% local function run_tex_code_no_use (str, cat)
+% cat = cat or catlatex
+% texscantoks("mplibtmptoks", cat, str)
+% texruntoks("mplibtmptoks")
+% end
+% \end{verbatim}
+% \begin{macrocode}
+local function run_tex_code (str, cat)
+ cat = cat or catlatex
+ texruntoks(function() texsprint(cat, str) end)
+end
+
+% \end{macrocode}
+%
+% Indefinite number of boxes are needed for |btex ... etex|.
+% So starts at somewhat huge number of box registry. Of course,
+% this may conflict with other packages using many many boxes.
+% (When |codeinherit| feature is enabled, boxes must be globally defined.)
+% But I don't know any reliable way to escape this danger.
+% \begin{macrocode}
+local tex_box_id = 2047
+% \end{macrocode}
+%
+% For conversion of |sp| to |bp|.
+% \begin{macrocode}
+local factor = 65536*(7227/7200)
+
+local function process_tex_text (str)
+ if str then
+ tex_box_id = tex_box_id + 1
+ local global = luamplib.globaltextext and "\\global" or ""
+ run_tex_code(format("%s\\setbox%i\\hbox{%s}", global, tex_box_id, str))
+ local box = texgetbox(tex_box_id)
+ local wd = box.width / factor
+ local ht = box.height / factor
+ local dp = box.depth / factor
+ return format("image(addto currentpicture doublepath unitsquare "..
+ "xscaled %f yscaled %f shifted (0,-%f) "..
+ "withprescript \"mplibtexboxid=%i:%f:%f\")",
+ wd, ht+dp, dp, tex_box_id, wd, ht+dp)
+ end
+ return ""
+end
+
+% \end{macrocode}
+%
+% Make |color| or |xcolor|'s color expressions usable,
+% with \cs{mpcolor} or |mplibcolor|
+% \begin{macrocode}
+local function process_color (str)
+ if str then
+ if not str:find("{.-}") then
+ str = format("{%s}",str)
+ end
+ run_tex_code(format(
+ "\\def\\set@color{\\toks0\\expandafter{\\current@color}}\\color %s", str),
+ catat11)
+ return format("1 withprescript \"MPlibOverrideColor=%s\"", texgettoks(0))
+ end
+ return ""
+end
+
+% \end{macrocode}
+%
+% \cs{mpdim} is expanded before MPLib process, so code below will not be
+% used for |mplibcode| data. But who knows anyone would want it
+% in |.mp| input file. If then, you can say |mplibdimen(".5\textwidth")|
+% for example.
+% \begin{macrocode}
+local function process_dimen (str)
+ if str then
+ str = str:gsub("{(.+)}","%1")
+ run_tex_code(format("\\toks0\\expandafter{\\the\\dimexpr %s\\relax}", str))
+ return format("begingroup %s endgroup", texgettoks(0))
+ end
+ return ""
+end
+
+% \end{macrocode}
+%
+% Newly introduced method of processing |verbatimtex ... etex|.
+% Used when |\mpliblegacybehavior{false}| is declared.
+% \begin{macrocode}
+local function process_verbatimtex_text (str)
+ if str then
+ run_tex_code(str)
+ end
+ return ""
+end
+
+% \end{macrocode}
+%
+% For legacy verbatimtex process.
+% |verbatimtex ... etex| before |beginfig()| is not ignored,
+% but the \TeX\ code is inserted just before the mplib box. And
+% \TeX\ code inside |beginfig() ... endfig| is inserted after the mplib box.
+% \begin{macrocode}
+local tex_code_pre_mplib = {}
+luamplib.figid = 1
+luamplib.in_the_fig = false
+
+local function legacy_mplibcode_reset ()
+ tex_code_pre_mplib = {}
+ luamplib.figid = 1
+end
+
+local function process_verbatimtex_prefig (str)
+ if str then
+ tex_code_pre_mplib[luamplib.figid] = str
+ end
+ return ""
+end
+
+local function process_verbatimtex_infig (str)
+ if str then
+ return format("special \"postmplibverbtex=%s\";", str)
+ end
+ return ""
+end
+
+local runscript_funcs = {
+ luamplibtext = process_tex_text,
+ luamplibcolor = process_color,
+ luamplibdimen = process_dimen,
+ luamplibprefig = process_verbatimtex_prefig,
+ luamplibinfig = process_verbatimtex_infig,
+ luamplibverbtex = process_verbatimtex_text,
+}
+
+% \end{macrocode}
+%
+% For |metafun| format. see issue \#79.
+% \begin{macrocode}
+mp = mp or {}
+local mp = mp
+mp.mf_path_reset = mp.mf_path_reset or function() end
+mp.mf_finish_saving_data = mp.mf_finish_saving_data or function() end
+
+% \end{macrocode}
+%
+% A function from \ConTeXt\ general.
+% \begin{macrocode}
+local function mpprint(buffer,...)
+ for i=1,select("#",...) do
+ local value = select(i,...)
+ if value ~= nil then
+ local t = type(value)
+ if t == "number" then
+ buffer[#buffer+1] = format("%.16f",value)
+ elseif t == "string" then
+ buffer[#buffer+1] = value
+ elseif t == "table" then
+ buffer[#buffer+1] = "(" .. tableconcat(value,",") .. ")"
+ else -- boolean or whatever
+ buffer[#buffer+1] = tostring(value)
+ end
+ end
+ end
+end
+
+function luamplib.runscript (code)
+ local id, str = code:match("(.-){(.+)}")
+ if id and str and str ~= "" then
+ local f = runscript_funcs[id]
+ if f then
+ local t = f(str)
+ if t then return t end
+ end
+ end
+ local f = loadstring(code)
+ if type(f) == "function" then
+ local buffer = {}
+ function mp.print(...)
+ mpprint(buffer,...)
+ end
+ f()
+ return tableconcat(buffer,"")
+ end
+ return ""
+end
+
+% \end{macrocode}
+%
+% |make_text| must be one liner, so comment sign is not allowed.
+% \begin{macrocode}
+local function protecttexcontents (str)
+ return str:gsub("\\%%", "\0PerCent\0")
+ :gsub("%%.-\n", "")
+ :gsub("%%.-$", "")
+ :gsub("%zPerCent%z", "\\%%")
+ :gsub("%s+", " ")
+end
+
+luamplib.legacy_verbatimtex = true
+
+function luamplib.maketext (str, what)
+ if str and str ~= "" then
+ str = protecttexcontents(str)
+ if what == 1 then
+ if not str:find("\\documentclass"..name_e) and
+ not str:find("\\begin%s*{document}") and
+ not str:find("\\documentstyle"..name_e) and
+ not str:find("\\usepackage"..name_e) then
+ if luamplib.legacy_verbatimtex then
+ if luamplib.in_the_fig then
+ return process_verbatimtex_infig(str)
+ else
+ return process_verbatimtex_prefig(str)
+ end
+ else
+ return process_verbatimtex_text(str)
+ end
+ end
+ else
+ return process_tex_text(str)
+ end
+ end
+ return ""
+end
+
+% \end{macrocode}
+%
+% Our MetaPost preambles
+% \begin{macrocode}
+local mplibcodepreamble = [[
+texscriptmode := 2;
+def rawtextext (expr t) = runscript("luamplibtext{"&t&"}") enddef;
+def mplibcolor (expr t) = runscript("luamplibcolor{"&t&"}") enddef;
+def mplibdimen (expr t) = runscript("luamplibdimen{"&t&"}") enddef;
+def VerbatimTeX (expr t) = runscript("luamplibverbtex{"&t&"}") enddef;
+if known context_mlib:
+ defaultfont := "cmtt10";
+ let infont = normalinfont;
+ let fontsize = normalfontsize;
+ vardef thelabel@#(expr p,z) =
+ if string p :
+ thelabel@#(p infont defaultfont scaled defaultscale,z)
+ else :
+ p shifted (z + labeloffset*mfun_laboff@# -
+ (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p +
+ (1-mfun_labxf@#-mfun_labyf@#)*llcorner p))
+ fi
+ enddef;
+ def graphictext primary filename =
+ if (readfrom filename = EOF):
+ errmessage "Please prepare '"&filename&"' in advance with"&
+ " 'pstoedit -ssp -dt -f mpost yourfile.ps "&filename&"'";
+ fi
+ closefrom filename;
+ def data_mpy_file = filename enddef;
+ mfun_do_graphic_text (filename)
+ enddef;
+else:
+ vardef textext@# (text t) = rawtextext (t) enddef;
+fi
+def externalfigure primary filename =
+ draw rawtextext("\includegraphics{"& filename &"}")
+enddef;
+def TEX = textext enddef;
+]]
+luamplib.mplibcodepreamble = mplibcodepreamble
+
+local legacyverbatimtexpreamble = [[
+def specialVerbatimTeX (text t) = runscript("luamplibprefig{"&t&"}") enddef;
+def normalVerbatimTeX (text t) = runscript("luamplibinfig{"&t&"}") enddef;
+let VerbatimTeX = specialVerbatimTeX;
+extra_beginfig := extra_beginfig & " let VerbatimTeX = normalVerbatimTeX;"&
+ "runscript(" &ditto& "luamplib.in_the_fig=true" &ditto& ");";
+extra_endfig := extra_endfig & " let VerbatimTeX = specialVerbatimTeX;"&
+ "runscript(" &ditto&
+ "luamplib.in_the_fig=false luamplib.figid=luamplib.figid+1" &ditto& ");";
+]]
+luamplib.legacyverbatimtexpreamble = legacyverbatimtexpreamble
+
+local textextlabelpreamble = [[
+primarydef s infont f = rawtextext(s) enddef;
+def fontsize expr f =
+ begingroup
+ save size; numeric size;
+ size := mplibdimen("1em");
+ if size = 0: 10pt else: size fi
+ endgroup
+enddef;
+]]
+luamplib.textextlabelpreamble = textextlabelpreamble
+
+% \end{macrocode}
+%
+% When \cs{mplibverbatim} is enabled, do not expand |mplibcode| data.
+% \begin{macrocode}
+luamplib.verbatiminput = false
+
+% \end{macrocode}
+%
+% Do not expand |btex ... etex|, |verbatimtex ... etex|, and
+% string expressions.
+% \begin{macrocode}
+local function protect_expansion (str)
+ if str then
+ str = str:gsub("\\","\1Control\1")
+ :gsub("%%","\1Comment\1")
+ :gsub("#", "\1HashSign\1")
+ :gsub("{", "\1LBrace\1")
+ :gsub("}", "\1RBrace\1")
+ return format("\\unexpanded{%s}",str)
+ end
+end
+
+local function unprotect_expansion (str)
+ if str then
+ return str:gsub("\1Control\1", "\\")
+ :gsub("\1Comment\1", "%%")
+ :gsub("\1HashSign\1","#")
+ :gsub("\1LBrace\1", "{")
+ :gsub("\1RBrace\1", "}")
+ end
+end
+
+local function process_mplibcode (data)
+% \end{macrocode}
+%
+% This is needed for legacy behavior regarding |verbatimtex|
+% \begin{macrocode}
+ legacy_mplibcode_reset()
+
+ local everymplib = texgettoks('everymplibtoks') or ''
+ local everyendmplib = texgettoks('everyendmplibtoks') or ''
+ data = format("\n%s\n%s\n%s\n",everymplib, data, everyendmplib)
+ data = data:gsub("\r","\n")
+
+ data = data:gsub("\\mpcolor%s+(.-%b{})","mplibcolor(\"%1\")")
+ data = data:gsub("\\mpdim%s+(%b{})", "mplibdimen(\"%1\")")
+ data = data:gsub("\\mpdim%s+(\\%a+)","mplibdimen(\"%1\")")
+
+ data = data:gsub(btex_etex, function(str)
+ return format("btex %s etex ", -- space
+ luamplib.verbatiminput and str or protect_expansion(str))
+ end)
+ data = data:gsub(verbatimtex_etex, function(str)
+ return format("verbatimtex %s etex;", -- semicolon
+ luamplib.verbatiminput and str or protect_expansion(str))
+ end)
+
+% \end{macrocode}
+%
+% If not |mplibverbatim|, expand |mplibcode| data,
+% so that users can use \TeX\ codes in it.
+% It has turned out that no comment sign is allowed.
+% \begin{macrocode}
+ if not luamplib.verbatiminput then
+ data = data:gsub("\".-\"", protect_expansion)
+ data = data:gsub("%%.-\n","")
+ run_tex_code(format("\\toks0\\expanded{{%s}}",data))
+ data = texgettoks(0)
+% \end{macrocode}
+%
+% Next line to address issue \#55
+% \begin{macrocode}
+ data = data:gsub("##", "#")
+ data = data:gsub("\".-\"", unprotect_expansion)
+ data = data:gsub(btex_etex, function(str)
+ return format("btex %s etex", unprotect_expansion(str))
+ end)
+ data = data:gsub(verbatimtex_etex, function(str)
+ return format("verbatimtex %s etex", unprotect_expansion(str))
+ end)
+ end
+
+ process(data)
+end
+luamplib.process_mplibcode = process_mplibcode
+
+% \end{macrocode}
+%
+% For parsing |prescript| materials.
+% \begin{macrocode}
+local further_split_keys = {
+ ["mplibtexboxid"] = true,
+ ["sh_color_a"] = true,
+ ["sh_color_b"] = true,
+}
+
+local function script2table(s)
+ local t = {}
+ for _,i in ipairs(s:explode("\13+")) do
+ local k,v = i:match("(.-)=(.*)") -- v may contain = or empty.
+ if k and v and k ~= "" then
+ if further_split_keys[k] then
+ t[k] = v:explode(":")
+ else
+ t[k] = v
+ end
+ end
+ end
+ return t
+end
+
+% \end{macrocode}
+%
+% Codes below for inserting PDF lieterals are mostly from ConTeXt general,
+% with small changes when needed.
+% \begin{macrocode}
+local function getobjects(result,figure,f)
+ return figure:objects()
+end
+
+local function convert(result, flusher)
+ luamplib.flush(result, flusher)
+ return true -- done
+end
+luamplib.convert = convert
+
+local function pdf_startfigure(n,llx,lly,urx,ury)
+ texsprint(format("\\mplibstarttoPDF{%f}{%f}{%f}{%f}",llx,lly,urx,ury))
+end
+
+local function pdf_stopfigure()
+ texsprint("\\mplibstoptoPDF")
+end
+
+% \end{macrocode}
+%
+% |tex.tprint| with catcode regime -2, as sometimes |#| gets doubled
+% in the argument of pdfliteral.
+% \begin{macrocode}
+local function pdf_literalcode(fmt,...) -- table
+ textprint({"\\mplibtoPDF{"},{-2,format(fmt,...)},{"}"})
+end
+
+local function pdf_textfigure(font,size,text,width,height,depth)
+ text = text:gsub(".",function(c)
+ return format("\\hbox{\\char%i}",string.byte(c)) -- kerning happens in metapost
+ end)
+ texsprint(format("\\mplibtextext{%s}{%f}{%s}{%s}{%f}",font,size,text,0,-( 7200/ 7227)/65536*depth))
+end
+
+local bend_tolerance = 131/65536
+
+local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1
+
+local function pen_characteristics(object)
+ local t = mplib.pen_info(object)
+ rx, ry, sx, sy, tx, ty = t.rx, t.ry, t.sx, t.sy, t.tx, t.ty
+ divider = sx*sy - rx*ry
+ return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), t.width
+end
+
+local function concat(px, py) -- no tx, ty here
+ return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider
+end
+
+local function curved(ith,pth)
+ local d = pth.left_x - ith.right_x
+ if abs(ith.right_x - ith.x_coord - d) <= bend_tolerance and abs(pth.x_coord - pth.left_x - d) <= bend_tolerance then
+ d = pth.left_y - ith.right_y
+ if abs(ith.right_y - ith.y_coord - d) <= bend_tolerance and abs(pth.y_coord - pth.left_y - d) <= bend_tolerance then
+ return false
+ end
+ end
+ return true
+end
+
+local function flushnormalpath(path,open)
+ local pth, ith
+ for i=1,#path do
+ pth = path[i]
+ if not ith then
+ pdf_literalcode("%f %f m",pth.x_coord,pth.y_coord)
+ elseif curved(ith,pth) then
+ pdf_literalcode("%f %f %f %f %f %f c",ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord)
+ else
+ pdf_literalcode("%f %f l",pth.x_coord,pth.y_coord)
+ end
+ ith = pth
+ end
+ if not open then
+ local one = path[1]
+ if curved(pth,one) then
+ pdf_literalcode("%f %f %f %f %f %f c",pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord )
+ else
+ pdf_literalcode("%f %f l",one.x_coord,one.y_coord)
+ end
+ elseif #path == 1 then -- special case .. draw point
+ local one = path[1]
+ pdf_literalcode("%f %f l",one.x_coord,one.y_coord)
+ end
+end
+
+local function flushconcatpath(path,open)
+ pdf_literalcode("%f %f %f %f %f %f cm", sx, rx, ry, sy, tx ,ty)
+ local pth, ith
+ for i=1,#path do
+ pth = path[i]
+ if not ith then
+ pdf_literalcode("%f %f m",concat(pth.x_coord,pth.y_coord))
+ elseif curved(ith,pth) then
+ local a, b = concat(ith.right_x,ith.right_y)
+ local c, d = concat(pth.left_x,pth.left_y)
+ pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord))
+ else
+ pdf_literalcode("%f %f l",concat(pth.x_coord, pth.y_coord))
+ end
+ ith = pth
+ end
+ if not open then
+ local one = path[1]
+ if curved(pth,one) then
+ local a, b = concat(pth.right_x,pth.right_y)
+ local c, d = concat(one.left_x,one.left_y)
+ pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord))
+ else
+ pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord))
+ end
+ elseif #path == 1 then -- special case .. draw point
+ local one = path[1]
+ pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord))
+ end
+end
+
+% \end{macrocode}
+%
+% |dvipdfmx| is supported, though nobody seems to use it.
+% \begin{macrocode}
+local pdfoutput = tonumber(texget("outputmode")) or tonumber(texget("pdfoutput"))
+local pdfmode = pdfoutput > 0
+
+local function start_pdf_code()
+ if pdfmode then
+ pdf_literalcode("q")
+ else
+ texsprint("\\special{pdf:bcontent}") -- dvipdfmx
+ end
+end
+local function stop_pdf_code()
+ if pdfmode then
+ pdf_literalcode("Q")
+ else
+ texsprint("\\special{pdf:econtent}") -- dvipdfmx
+ end
+end
+
+% \end{macrocode}
+%
+% Now we process hboxes created from |btex ... etex| or
+% |textext(...)| or |TEX(...)|, all being the same internally.
+% \begin{macrocode}
+local function put_tex_boxes (object,prescript)
+ local box = prescript.mplibtexboxid
+ local n,tw,th = box[1],tonumber(box[2]),tonumber(box[3])
+ if n and tw and th then
+ local op = object.path
+ local first, second, fourth = op[1], op[2], op[4]
+ local tx, ty = first.x_coord, first.y_coord
+ local sx, rx, ry, sy = 1, 0, 0, 1
+ if tw ~= 0 then
+ sx = (second.x_coord - tx)/tw
+ rx = (second.y_coord - ty)/tw
+ if sx == 0 then sx = 0.00001 end
+ end
+ if th ~= 0 then
+ sy = (fourth.y_coord - ty)/th
+ ry = (fourth.x_coord - tx)/th
+ if sy == 0 then sy = 0.00001 end
+ end
+ start_pdf_code()
+ pdf_literalcode("%f %f %f %f %f %f cm",sx,rx,ry,sy,tx,ty)
+ texsprint(format("\\mplibputtextbox{%i}",n))
+ stop_pdf_code()
+ end
+end
+
+% \end{macrocode}
+%
+% Colors and Transparency
+% \begin{macrocode}
+local pdf_objs = {}
+local token, getpageres, setpageres = newtoken or token
+local pgf = { bye = "pgfutil@everybye", extgs = "pgf@sys@addpdfresource@extgs@plain" }
+
+if pdfmode then -- repect luaotfload-colors
+ getpageres = pdf.getpageresources or function() return pdf.pageresources end
+ setpageres = pdf.setpageresources or function(s) pdf.pageresources = s end
+else
+ texsprint("\\special{pdf:obj @MPlibTr<<>>}",
+ "\\special{pdf:obj @MPlibSh<<>>}")
+end
+
+local function update_pdfobjs (os)
+ local on = pdf_objs[os]
+ if on then
+ return on,false
+ end
+ if pdfmode then
+ on = pdf.immediateobj(os)
+ else
+ on = pdf_objs.cnt or 0
+ pdf_objs.cnt = on + 1
+ end
+ pdf_objs[os] = on
+ return on,true
+end
+
+local transparancy_modes = { [0] = "Normal",
+ "Normal", "Multiply", "Screen", "Overlay",
+ "SoftLight", "HardLight", "ColorDodge", "ColorBurn",
+ "Darken", "Lighten", "Difference", "Exclusion",
+ "Hue", "Saturation", "Color", "Luminosity",
+ "Compatible",
+}
+
+local function update_tr_res(res,mode,opaq)
+ local os = format("<</BM /%s/ca %.3f/CA %.3f/AIS false>>",mode,opaq,opaq)
+ local on, new = update_pdfobjs(os)
+ if new then
+ if pdfmode then
+ res = format("%s/MPlibTr%i %i 0 R",res,on,on)
+ else
+ if pgf.loaded then
+ texsprint(format("\\csname %s\\endcsname{/MPlibTr%i%s}", pgf.extgs, on, os))
+ else
+ texsprint(format("\\special{pdf:put @MPlibTr<</MPlibTr%i%s>>}",on,os))
+ end
+ end
+ end
+ return res,on
+end
+
+local function tr_pdf_pageresources(mode,opaq)
+ if token and pgf.bye and not pgf.loaded then
+ pgf.loaded = token.create(pgf.bye).cmdname == "assign_toks"
+ pgf.bye = pgf.loaded and pgf.bye
+ end
+ local res, on_on, off_on = "", nil, nil
+ res, off_on = update_tr_res(res, "Normal", 1)
+ res, on_on = update_tr_res(res, mode, opaq)
+ if pdfmode then
+ if res ~= "" then
+ if pgf.loaded then
+ texsprint(format("\\csname %s\\endcsname{%s}", pgf.extgs, res))
+ else
+ local tpr, n = getpageres() or "", 0
+ tpr, n = tpr:gsub("/ExtGState<<", "%1"..res)
+ if n == 0 then
+ tpr = format("%s/ExtGState<<%s>>", tpr, res)
+ end
+ setpageres(tpr)
+ end
+ end
+ else
+ if not pgf.loaded then
+ texsprint(format("\\special{pdf:put @resources<</ExtGState @MPlibTr>>}"))
+ end
+ end
+ return on_on, off_on
+end
+
+% \end{macrocode}
+%
+% Shading with |metafun| format. (maybe legacy way)
+% \begin{macrocode}
+local shading_res
+
+local function shading_initialize ()
+ shading_res = {}
+ if pdfmode and luatexbase.callbacktypes.finish_pdffile then -- ltluatex
+ local shading_obj = pdf.reserveobj()
+ setpageres(format("%s/Shading %i 0 R",getpageres() or "",shading_obj))
+ luatexbase.add_to_callback("finish_pdffile", function()
+ pdf.immediateobj(shading_obj,format("<<%s>>",tableconcat(shading_res)))
+ end, "luamplib.finish_pdffile")
+ pdf_objs.finishpdf = true
+ end
+end
+
+local function sh_pdfpageresources(shtype,domain,colorspace,colora,colorb,coordinates)
+ if not shading_res then shading_initialize() end
+ local os = format("<</FunctionType 2/Domain [ %s ]/C0 [ %s ]/C1 [ %s ]/N 1>>",
+ domain, colora, colorb)
+ local funcobj = pdfmode and format("%i 0 R",update_pdfobjs(os)) or os
+ os = format("<</ShadingType %i/ColorSpace /%s/Function %s/Coords [ %s ]/Extend [ true true ]/AntiAlias true>>",
+ shtype, colorspace, funcobj, coordinates)
+ local on, new = update_pdfobjs(os)
+ if pdfmode then
+ if new then
+ local res = format("/MPlibSh%i %i 0 R", on, on)
+ if pdf_objs.finishpdf then
+ shading_res[#shading_res+1] = res
+ else
+ local pageres = getpageres() or ""
+ if not pageres:find("/Shading<<.*>>") then
+ pageres = pageres.."/Shading<<>>"
+ end
+ pageres = pageres:gsub("/Shading<<","%1"..res)
+ setpageres(pageres)
+ end
+ end
+ else
+ if new then
+ texsprint(format("\\special{pdf:put @MPlibSh<</MPlibSh%i%s>>}",on,os))
+ end
+ texsprint(format("\\special{pdf:put @resources<</Shading @MPlibSh>>}"))
+ end
+ return on
+end
+
+local function color_normalize(ca,cb)
+ if #cb == 1 then
+ if #ca == 4 then
+ cb[1], cb[2], cb[3], cb[4] = 0, 0, 0, 1-cb[1]
+ else -- #ca = 3
+ cb[1], cb[2], cb[3] = cb[1], cb[1], cb[1]
+ end
+ elseif #cb == 3 then -- #ca == 4
+ cb[1], cb[2], cb[3], cb[4] = 1-cb[1], 1-cb[2], 1-cb[3], 0
+ end
+end
+
+local prev_override_color
+
+local function do_preobj_color(object,prescript)
+% \end{macrocode}
+%
+% transparency
+% \begin{macrocode}
+ local opaq = prescript and prescript.tr_transparency
+ local tron_no, troff_no
+ if opaq then
+ local mode = prescript.tr_alternative or 1
+ mode = transparancy_modes[tonumber(mode)]
+ tron_no, troff_no = tr_pdf_pageresources(mode,opaq)
+ pdf_literalcode("/MPlibTr%i gs",tron_no)
+ end
+% \end{macrocode}
+%
+% color
+% \begin{macrocode}
+ local override = prescript and prescript.MPlibOverrideColor
+ if override then
+ if pdfmode then
+ pdf_literalcode(override)
+ override = nil
+ else
+ texsprint(format("\\special{color push %s}",override))
+ prev_override_color = override
+ end
+ else
+ local cs = object.color
+ if cs and #cs > 0 then
+ pdf_literalcode(luamplib.colorconverter(cs))
+ prev_override_color = nil
+ elseif not pdfmode then
+ override = prev_override_color
+ if override then
+ texsprint(format("\\special{color push %s}",override))
+ end
+ end
+ end
+% \end{macrocode}
+%
+% shading
+% \begin{macrocode}
+ local sh_type = prescript and prescript.sh_type
+ if sh_type then
+ local domain = prescript.sh_domain
+ local centera = prescript.sh_center_a:explode()
+ local centerb = prescript.sh_center_b:explode()
+ for _,t in pairs({centera,centerb}) do
+ for i,v in ipairs(t) do
+ t[i] = format("%f",v)
+ end
+ end
+ centera = tableconcat(centera," ")
+ centerb = tableconcat(centerb," ")
+ local colora = prescript.sh_color_a or {0};
+ local colorb = prescript.sh_color_b or {1};
+ for _,t in pairs({colora,colorb}) do
+ for i,v in ipairs(t) do
+ t[i] = format("%.3f",v)
+ end
+ end
+ if #colora > #colorb then
+ color_normalize(colora,colorb)
+ elseif #colorb > #colora then
+ color_normalize(colorb,colora)
+ end
+ local colorspace
+ if #colorb == 1 then colorspace = "DeviceGray"
+ elseif #colorb == 3 then colorspace = "DeviceRGB"
+ elseif #colorb == 4 then colorspace = "DeviceCMYK"
+ else return troff_no,override
+ end
+ colora = tableconcat(colora, " ")
+ colorb = tableconcat(colorb, " ")
+ local shade_no
+ if sh_type == "linear" then
+ local coordinates = tableconcat({centera,centerb}," ")
+ shade_no = sh_pdfpageresources(2,domain,colorspace,colora,colorb,coordinates)
+ elseif sh_type == "circular" then
+ local radiusa = format("%f",prescript.sh_radius_a)
+ local radiusb = format("%f",prescript.sh_radius_b)
+ local coordinates = tableconcat({centera,radiusa,centerb,radiusb}," ")
+ shade_no = sh_pdfpageresources(3,domain,colorspace,colora,colorb,coordinates)
+ end
+ pdf_literalcode("q /Pattern cs")
+ return troff_no,override,shade_no
+ end
+ return troff_no,override
+end
+
+local function do_postobj_color(tr,over,sh)
+ if sh then
+ pdf_literalcode("W n /MPlibSh%s sh Q",sh)
+ end
+ if over then
+ texsprint("\\special{color pop}")
+ end
+ if tr then
+ pdf_literalcode("/MPlibTr%i gs",tr)
+ end
+end
+
+% \end{macrocode}
+%
+% Finally, flush figures by inserting PDF literals.
+% \begin{macrocode}
+local function flush(result,flusher)
+ if result then
+ local figures = result.fig
+ if figures then
+ for f=1, #figures do
+ info("flushing figure %s",f)
+ local figure = figures[f]
+ local objects = getobjects(result,figure,f)
+ local fignum = tonumber(figure:filename():match("([%d]+)$") or figure:charcode() or 0)
+ local miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
+ local bbox = figure:boundingbox()
+ local llx, lly, urx, ury = bbox[1], bbox[2], bbox[3], bbox[4] -- faster than unpack
+ if urx < llx then
+% \end{macrocode}
+%
+% luamplib silently ignores this invalid figure for those
+% that do not contain |beginfig ... endfig|. (issue \#70)
+% Original code of ConTeXt general was:
+% \begin{verbatim}
+% -- invalid
+% pdf_startfigure(fignum,0,0,0,0)
+% pdf_stopfigure()
+% \end{verbatim}
+% \begin{macrocode}
+ else
+% \end{macrocode}
+%
+% For legacy behavior. Insert `pre-fig' \TeX\ code here, and
+% prepare a table for `in-fig' codes.
+% \begin{macrocode}
+ if tex_code_pre_mplib[f] then
+ texsprint(tex_code_pre_mplib[f])
+ end
+ local TeX_code_bot = {}
+ pdf_startfigure(fignum,llx,lly,urx,ury)
+ start_pdf_code()
+ if objects then
+ local savedpath = nil
+ local savedhtap = nil
+ for o=1,#objects do
+ local object = objects[o]
+ local objecttype = object.type
+% \end{macrocode}
+%
+% The following 5 lines are part of |btex...etex| patch.
+% Again, colors are processed at this stage.
+% \begin{macrocode}
+ local prescript = object.prescript
+ prescript = prescript and script2table(prescript) -- prescript is now a table
+ local tr_opaq,cr_over,shade_no = do_preobj_color(object,prescript)
+ if prescript and prescript.mplibtexboxid then
+ put_tex_boxes(object,prescript)
+ elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then --skip
+ elseif objecttype == "start_clip" then
+ local evenodd = not object.istext and object.postscript == "evenodd"
+ start_pdf_code()
+ flushnormalpath(object.path,false)
+ pdf_literalcode(evenodd and "W* n" or "W n")
+ elseif objecttype == "stop_clip" then
+ stop_pdf_code()
+ miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
+ elseif objecttype == "special" then
+% \end{macrocode}
+%
+% Collect \TeX\ codes that will be executed after flushing.
+% Legacy behavior.
+% \begin{macrocode}
+ if prescript and prescript.postmplibverbtex then
+ TeX_code_bot[#TeX_code_bot+1] = prescript.postmplibverbtex
+ end
+ elseif objecttype == "text" then
+ local ot = object.transform -- 3,4,5,6,1,2
+ start_pdf_code()
+ pdf_literalcode("%f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2])
+ pdf_textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth)
+ stop_pdf_code()
+ else
+ local evenodd, collect, both = false, false, false
+ local postscript = object.postscript
+ if not object.istext then
+ if postscript == "evenodd" then
+ evenodd = true
+ elseif postscript == "collect" then
+ collect = true
+ elseif postscript == "both" then
+ both = true
+ elseif postscript == "eoboth" then
+ evenodd = true
+ both = true
+ end
+ end
+ if collect then
+ if not savedpath then
+ savedpath = { object.path or false }
+ savedhtap = { object.htap or false }
+ else
+ savedpath[#savedpath+1] = object.path or false
+ savedhtap[#savedhtap+1] = object.htap or false
+ end
+ else
+ local ml = object.miterlimit
+ if ml and ml ~= miterlimit then
+ miterlimit = ml
+ pdf_literalcode("%f M",ml)
+ end
+ local lj = object.linejoin
+ if lj and lj ~= linejoin then
+ linejoin = lj
+ pdf_literalcode("%i j",lj)
+ end
+ local lc = object.linecap
+ if lc and lc ~= linecap then
+ linecap = lc
+ pdf_literalcode("%i J",lc)
+ end
+ local dl = object.dash
+ if dl then
+ local d = format("[%s] %f d",tableconcat(dl.dashes or {}," "),dl.offset)
+ if d ~= dashed then
+ dashed = d
+ pdf_literalcode(dashed)
+ end
+ elseif dashed then
+ pdf_literalcode("[] 0 d")
+ dashed = false
+ end
+ local path = object.path
+ local transformed, penwidth = false, 1
+ local open = path and path[1].left_type and path[#path].right_type
+ local pen = object.pen
+ if pen then
+ if pen.type == 'elliptical' then
+ transformed, penwidth = pen_characteristics(object) -- boolean, value
+ pdf_literalcode("%f w",penwidth)
+ if objecttype == 'fill' then
+ objecttype = 'both'
+ end
+ else -- calculated by mplib itself
+ objecttype = 'fill'
+ end
+ end
+ if transformed then
+ start_pdf_code()
+ end
+ if path then
+ if savedpath then
+ for i=1,#savedpath do
+ local path = savedpath[i]
+ if transformed then
+ flushconcatpath(path,open)
+ else
+ flushnormalpath(path,open)
+ end
+ end
+ savedpath = nil
+ end
+ if transformed then
+ flushconcatpath(path,open)
+ else
+ flushnormalpath(path,open)
+ end
+% \end{macrocode}
+%
+% Change from ConTeXt general: there was color stuffs.
+% \begin{macrocode}
+ if not shade_no then -- conflict with shading
+ if objecttype == "fill" then
+ pdf_literalcode(evenodd and "h f*" or "h f")
+ elseif objecttype == "outline" then
+ if both then
+ pdf_literalcode(evenodd and "h B*" or "h B")
+ else
+ pdf_literalcode(open and "S" or "h S")
+ end
+ elseif objecttype == "both" then
+ pdf_literalcode(evenodd and "h B*" or "h B")
+ end
+ end
+ end
+ if transformed then
+ stop_pdf_code()
+ end
+ local path = object.htap
+ if path then
+ if transformed then
+ start_pdf_code()
+ end
+ if savedhtap then
+ for i=1,#savedhtap do
+ local path = savedhtap[i]
+ if transformed then
+ flushconcatpath(path,open)
+ else
+ flushnormalpath(path,open)
+ end
+ end
+ savedhtap = nil
+ evenodd = true
+ end
+ if transformed then
+ flushconcatpath(path,open)
+ else
+ flushnormalpath(path,open)
+ end
+ if objecttype == "fill" then
+ pdf_literalcode(evenodd and "h f*" or "h f")
+ elseif objecttype == "outline" then
+ pdf_literalcode(open and "S" or "h S")
+ elseif objecttype == "both" then
+ pdf_literalcode(evenodd and "h B*" or "h B")
+ end
+ if transformed then
+ stop_pdf_code()
+ end
+ end
+ end
+ end
+% \end{macrocode}
+%
+% Added to ConTeXt general: color stuff.
+% And execute legacy |verbatimtex| code.
+% \begin{macrocode}
+ do_postobj_color(tr_opaq,cr_over,shade_no)
+ end
+ end
+ stop_pdf_code()
+ pdf_stopfigure()
+ if #TeX_code_bot > 0 then texsprint(TeX_code_bot) end
+ end
+ end
+ end
+ end
+end
+luamplib.flush = flush
+
+local function colorconverter(cr)
+ local n = #cr
+ if n == 4 then
+ local c, m, y, k = cr[1], cr[2], cr[3], cr[4]
+ return format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G"
+ elseif n == 3 then
+ local r, g, b = cr[1], cr[2], cr[3]
+ return format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G"
+ else
+ local s = cr[1]
+ return format("%.3f g %.3f G",s,s), "0 g 0 G"
+ end
+end
+luamplib.colorconverter = colorconverter
+% \end{macrocode}
+%
+% \iffalse
+%</lua>
+% \fi
+%
+% \subsection{\texorpdfstring{\TeX}{TeX} package}
+%
+%
+% \iffalse
+%<*package>
+% \fi
+%
+% First we need to load some packages.
+%
+% \begin{macrocode}
+\bgroup\expandafter\expandafter\expandafter\egroup
+\expandafter\ifx\csname selectfont\endcsname\relax
+ \input ltluatex
+\else
+ \NeedsTeXFormat{LaTeX2e}
+ \ProvidesPackage{luamplib}
+ [2019/03/26 v2.20.1 mplib package for LuaTeX]
+ \ifx\newluafunction\@undefined
+ \input ltluatex
+ \fi
+\fi
+% \end{macrocode}
+%
+% Loading of lua code.
+% \begin{macrocode}
+\directlua{require("luamplib")}
+% \end{macrocode}
+%
+% Support older engine. Seems we don't need it, but no harm.
+% \begin{macrocode}
+\ifx\scantextokens\undefined
+ \let\scantextokens\luatexscantextokens
+\fi
+\ifx\pdfoutput\undefined
+ \let\pdfoutput\outputmode
+ \protected\def\pdfliteral{\pdfextension literal}
+\fi
+% \end{macrocode}
+%
+% Set the format for metapost.
+% \begin{macrocode}
+\def\mplibsetformat#1{\directlua{luamplib.setformat("#1")}}
+% \end{macrocode}
+%
+% luamplib works in both PDF and DVI mode,
+% but only DVIPDFMx is supported currently among a number of DVI tools.
+% So we output a warning.
+% \begin{macrocode}
+\ifnum\pdfoutput>0
+ \let\mplibtoPDF\pdfliteral
+\else
+ \def\mplibtoPDF#1{\special{pdf:literal direct #1}}
+ \ifcsname PackageWarning\endcsname
+ \PackageWarning{luamplib}{take dvipdfmx path, no support for other dvi tools currently.}
+ \else
+ \write128{}
+ \write128{luamplib Warning: take dvipdfmx path, no support for other dvi tools currently.}
+ \write128{}
+ \fi
+\fi
+% \end{macrocode}
+%
+% Make |mplibcode| typesetted always in horizontal mode.
+% \begin{macrocode}
+\def\mplibforcehmode{\let\mplibhmodeornot\leavevmode}
+\def\mplibnoforcehmode{\let\mplibhmodeornot\relax}
+\mplibnoforcehmode
+% \end{macrocode}
+%
+% Catcode. We want to allow comment sign in |mplibcode|.
+% \begin{macrocode}
+\def\mplibsetupcatcodes{%
+ \mplibhmodeornot %catcode`\{=12 %catcode`\}=12
+ \catcode`\#=12 \catcode`\^=12 \catcode`\~=12 \catcode`\_=12
+ \catcode`\&=12 \catcode`\$=12 \catcode`\%=12 \catcode`\^^M=12 \endlinechar=10
+}
+% \end{macrocode}
+%
+% Make |btex...etex| box zero-metric.
+% \begin{macrocode}
+\def\mplibputtextbox#1{\vbox to 0pt{\vss\hbox to 0pt{\raise\dp#1\copy#1\hss}}}
+% \end{macrocode}
+%
+% As we have changed |^^J| catcode, the last line containing
+% |\end{mplibcode}| has |\n| at the end. Replace it with |^^M|.
+% \begin{macrocode}
+\newcount\mplibstartlineno
+\def\mplibpostmpcatcodes{%
+ \catcode`\{=12 \catcode`\}=12 \catcode`\#=12 \catcode`\%=12 }
+\def\mplibreplacenewlinebr{%
+ \begingroup \mplibpostmpcatcodes \mplibdoreplacenewlinebr}
+\begingroup\lccode`\~=`\^^M \lowercase{\endgroup
+ \def\mplibdoreplacenewlinebr#1^^J{\endgroup\scantextokens{{}#1~}}}
+% \end{macrocode}
+%
+% The Plain-specific stuff.
+% \begin{macrocode}
+\bgroup\expandafter\expandafter\expandafter\egroup
+\expandafter\ifx\csname selectfont\endcsname\relax
+\def\mplibreplacenewlinecs{%
+ \begingroup \mplibpostmpcatcodes \mplibdoreplacenewlinecs}
+\begingroup\lccode`\~=`\^^M \lowercase{\endgroup
+ \def\mplibdoreplacenewlinecs#1^^J{\endgroup\scantextokens{\relax#1~}}}
+\def\mplibcode{%
+ \mplibstartlineno\inputlineno
+ \begingroup
+ \begingroup
+ \mplibsetupcatcodes
+ \mplibdocode
+}
+\long\def\mplibdocode#1\endmplibcode{%
+ \endgroup
+ \directlua{luamplib.process_mplibcode([===[\unexpanded{#1}]===])}%
+ \endgroup
+ \ifnum\mplibstartlineno<\inputlineno\expandafter\mplibreplacenewlinecs\fi
+}
+\else
+% \end{macrocode}
+%
+% The \LaTeX-specific part: a new environment.
+% \begin{macrocode}
+\newenvironment{mplibcode}{%
+ \global\mplibstartlineno\inputlineno
+ \toks@{}\ltxdomplibcode
+}{}
+\def\ltxdomplibcode{%
+ \begingroup
+ \mplibsetupcatcodes
+ \ltxdomplibcodeindeed
+}
+\def\mplib@mplibcode{mplibcode}
+\long\def\ltxdomplibcodeindeed#1\end#2{%
+ \endgroup
+ \toks@\expandafter{\the\toks@#1}%
+ \def\mplibtemp@a{#2}%
+ \ifx\mplib@mplibcode\mplibtemp@a
+ \directlua{luamplib.process_mplibcode([===[\the\toks@]===])}%
+ \end{mplibcode}%
+ \ifnum\mplibstartlineno<\inputlineno
+ \expandafter\expandafter\expandafter\mplibreplacenewlinebr
+ \fi
+ \else
+ \toks@\expandafter{\the\toks@\end{#2}}\expandafter\ltxdomplibcode
+ \fi
+}
+\fi
+% \end{macrocode}
+%
+% User settings.
+% \begin{macrocode}
+\def\mpliblegacybehavior#1{\directlua{
+ local s = string.lower("#1")
+ if s == "enable" or s == "true" or s == "yes" then
+ luamplib.legacy_verbatimtex = true
+ else
+ luamplib.legacy_verbatimtex = false
+ end
+}}
+\def\mplibverbatim#1{\directlua{
+ local s = string.lower("#1")
+ if s == "enable" or s == "true" or s == "yes" then
+ luamplib.verbatiminput = true
+ else
+ luamplib.verbatiminput = false
+ end
+}}
+% \end{macrocode}
+%
+% \cs{everymplib} \& \cs{everyendmplib}: macros redefining
+% \cs{everymplibtoks} \& \cs{everyendmplibtoks} respectively
+% \begin{macrocode}
+\newtoks\mplibtmptoks
+\newtoks\everymplibtoks
+\newtoks\everyendmplibtoks
+\protected\def\everymplib{%
+ \mplibstartlineno\inputlineno
+ \begingroup
+ \mplibsetupcatcodes
+ \mplibdoeverymplib
+}
+\long\def\mplibdoeverymplib#1{%
+ \endgroup
+ \everymplibtoks{#1}%
+ \ifnum\mplibstartlineno<\inputlineno\expandafter\mplibreplacenewlinebr\fi
+}
+\protected\def\everyendmplib{%
+ \mplibstartlineno\inputlineno
+ \begingroup
+ \mplibsetupcatcodes
+ \mplibdoeveryendmplib
+}
+\long\def\mplibdoeveryendmplib#1{%
+ \endgroup
+ \everyendmplibtoks{#1}%
+ \ifnum\mplibstartlineno<\inputlineno\expandafter\mplibreplacenewlinebr\fi
+}
+% \end{macrocode}
+%
+% Allow \TeX\ dimen macros in |mplibcode|. But now |runscript| does the job.
+% \begin{verbatim}
+% \def\mpdim#1{ begingroup \the\dimexpr #1\relax\space endgroup }% gmp.sty
+% \end{verbatim}
+%
+% MPLib's number system. Now |binary| has gone away.
+% \begin{macrocode}
+\def\mplibnumbersystem#1{\directlua{
+ local t = "#1"
+ if t == "binary" then t = "decimal" end
+ luamplib.numbersystem = t
+}}
+% \end{macrocode}
+%
+% Settings for |.mp| cache files.
+% \begin{macrocode}
+\def\mplibmakenocache#1{\mplibdomakenocache #1,*,}
+\def\mplibdomakenocache#1,{%
+ \ifx\empty#1\empty
+ \expandafter\mplibdomakenocache
+ \else
+ \ifx*#1\else
+ \directlua{luamplib.noneedtoreplace["#1.mp"]=true}%
+ \expandafter\expandafter\expandafter\mplibdomakenocache
+ \fi
+ \fi
+}
+\def\mplibcancelnocache#1{\mplibdocancelnocache #1,*,}
+\def\mplibdocancelnocache#1,{%
+ \ifx\empty#1\empty
+ \expandafter\mplibdocancelnocache
+ \else
+ \ifx*#1\else
+ \directlua{luamplib.noneedtoreplace["#1.mp"]=false}%
+ \expandafter\expandafter\expandafter\mplibdocancelnocache
+ \fi
+ \fi
+}
+\def\mplibcachedir#1{\directlua{luamplib.getcachedir("\unexpanded{#1}")}}
+% \end{macrocode}
+%
+% More user settings.
+% \begin{macrocode}
+\def\mplibtextextlabel#1{\directlua{
+ local s = string.lower("#1")
+ if s == "enable" or s == "true" or s == "yes" then
+ luamplib.textextlabel = true
+ else
+ luamplib.textextlabel = false
+ end
+}}
+\def\mplibcodeinherit#1{\directlua{
+ local s = string.lower("#1")
+ if s == "enable" or s == "true" or s == "yes" then
+ luamplib.codeinherit = true
+ else
+ luamplib.codeinherit = false
+ end
+}}
+\def\mplibglobaltextext#1{\directlua{
+ local s = string.lower("#1")
+ if s == "enable" or s == "true" or s == "yes" then
+ luamplib.globaltextext = true
+ else
+ luamplib.globaltextext = false
+ end
+}}
+% \end{macrocode}
+%
+% The followings are from ConTeXt general, mostly.
+% % We use a dedicated scratchbox.
+% \begin{macrocode}
+\ifx\mplibscratchbox\undefined \newbox\mplibscratchbox \fi
+% \end{macrocode}
+%
+% We encapsulate the litterals.
+% \begin{macrocode}
+\def\mplibstarttoPDF#1#2#3#4{%
+ \hbox\bgroup
+ \xdef\MPllx{#1}\xdef\MPlly{#2}%
+ \xdef\MPurx{#3}\xdef\MPury{#4}%
+ \xdef\MPwidth{\the\dimexpr#3bp-#1bp\relax}%
+ \xdef\MPheight{\the\dimexpr#4bp-#2bp\relax}%
+ \parskip0pt%
+ \leftskip0pt%
+ \parindent0pt%
+ \everypar{}%
+ \setbox\mplibscratchbox\vbox\bgroup
+ \noindent
+}
+\def\mplibstoptoPDF{%
+ \egroup %
+ \setbox\mplibscratchbox\hbox %
+ {\hskip-\MPllx bp%
+ \raise-\MPlly bp%
+ \box\mplibscratchbox}%
+ \setbox\mplibscratchbox\vbox to \MPheight
+ {\vfill
+ \hsize\MPwidth
+ \wd\mplibscratchbox0pt%
+ \ht\mplibscratchbox0pt%
+ \dp\mplibscratchbox0pt%
+ \box\mplibscratchbox}%
+ \wd\mplibscratchbox\MPwidth
+ \ht\mplibscratchbox\MPheight
+ \box\mplibscratchbox
+ \egroup
+}
+% \end{macrocode}
+%
+% Text items have a special handler.
+% \begin{macrocode}
+\def\mplibtextext#1#2#3#4#5{%
+ \begingroup
+ \setbox\mplibscratchbox\hbox
+ {\font\temp=#1 at #2bp%
+ \temp
+ #3}%
+ \setbox\mplibscratchbox\hbox
+ {\hskip#4 bp%
+ \raise#5 bp%
+ \box\mplibscratchbox}%
+ \wd\mplibscratchbox0pt%
+ \ht\mplibscratchbox0pt%
+ \dp\mplibscratchbox0pt%
+ \box\mplibscratchbox
+ \endgroup
+}
+% \end{macrocode}
+%
+% Input |luamplib.cfg| when it exists.
+% \begin{macrocode}
+\openin0=luamplib.cfg
+\ifeof0 \else
+ \closein0
+ \input luamplib.cfg
+\fi
+% \end{macrocode}
+%
+% That's all folks!
+%
+% \iffalse
+%</package>
+% \fi
+%
+% \clearpage
+% \section{The GNU GPL License v2}
+%
+% The GPL requires the complete license text to be distributed along
+% with the code. I recommend the canonical source, instead:
+% \url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html}.
+% But if you insist on an included copy, here it is.
+% You might want to zoom in.
+%
+% \newsavebox{\gpl}
+% \begin{lrbox}{\gpl}
+% \begin{minipage}{3\textwidth}
+% \columnsep=3\columnsep
+% \begin{multicols}{3}
+% \begin{center}
+% {\Large GNU GENERAL PUBLIC LICENSE\par}
+% \bigskip
+% {Version 2, June 1991}
+% \end{center}
+%
+% \begin{center}
+% {\parindent 0in
+%
+% Copyright \textcopyright\ 1989, 1991 Free Software Foundation, Inc.
+%
+% \bigskip
+%
+% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+%
+% \bigskip
+%
+% Everyone is permitted to copy and distribute verbatim copies
+% of this license document, but changing it is not allowed.
+% }
+% \end{center}
+%
+% \begin{center}
+% {\bf\large Preamble}
+% \end{center}
+%
+%
+% The licenses for most software are designed to take away your freedom to
+% share and change it. By contrast, the GNU General Public License is
+% intended to guarantee your freedom to share and change free software---to
+% make sure the software is free for all its users. This General Public
+% License applies to most of the Free Software Foundation's software and to
+% any other program whose authors commit to using it. (Some other Free
+% Software Foundation software is covered by the GNU Library General Public
+% License instead.) You can apply it to your programs, too.
+%
+% When we speak of free software, we are referring to freedom, not price.
+% Our General Public Licenses are designed to make sure that you have the
+% freedom to distribute copies of free software (and charge for this service
+% if you wish), that you receive source code or can get it if you want it,
+% that you can change the software or use pieces of it in new free programs;
+% and that you know you can do these things.
+%
+% To protect your rights, we need to make restrictions that forbid anyone to
+% deny you these rights or to ask you to surrender the rights. These
+% restrictions translate to certain responsibilities for you if you
+% distribute copies of the software, or if you modify it.
+%
+% For example, if you distribute copies of such a program, whether gratis or
+% for a fee, you must give the recipients all the rights that you have. You
+% must make sure that they, too, receive or can get the source code. And
+% you must show them these terms so they know their rights.
+%
+% We protect your rights with two steps: (1) copyright the software, and (2)
+% offer you this license which gives you legal permission to copy,
+% distribute and/or modify the software.
+%
+% Also, for each author's protection and ours, we want to make certain that
+% everyone understands that there is no warranty for this free software. If
+% the software is modified by someone else and passed on, we want its
+% recipients to know that what they have is not the original, so that any
+% problems introduced by others will not reflect on the original authors'
+% reputations.
+%
+% Finally, any free program is threatened constantly by software patents.
+% We wish to avoid the danger that redistributors of a free program will
+% individually obtain patent licenses, in effect making the program
+% proprietary. To prevent this, we have made it clear that any patent must
+% be licensed for everyone's free use or not licensed at all.
+%
+% The precise terms and conditions for copying, distribution and
+% modification follow.
+%
+% \begin{center}
+% {\Large \sc Terms and Conditions For Copying, Distribution and
+% Modification}
+% \end{center}
+%
+% \begin{enumerate}
+% \item
+% This License applies to any program or other work which contains a notice
+% placed by the copyright holder saying it may be distributed under the
+% terms of this General Public License. The ``Program'', below, refers to
+% any such program or work, and a ``work based on the Program'' means either
+% the Program or any derivative work under copyright law: that is to say, a
+% work containing the Program or a portion of it, either verbatim or with
+% modifications and/or translated into another language. (Hereinafter,
+% translation is included without limitation in the term ``modification''.)
+% Each licensee is addressed as ``you''.
+%
+% Activities other than copying, distribution and modification are not
+% covered by this License; they are outside its scope. The act of
+% running the Program is not restricted, and the output from the Program
+% is covered only if its contents constitute a work based on the
+% Program (independent of having been made by running the Program).
+% Whether that is true depends on what the Program does.
+%
+% \item You may copy and distribute verbatim copies of the Program's source
+% code as you receive it, in any medium, provided that you conspicuously
+% and appropriately publish on each copy an appropriate copyright notice
+% and disclaimer of warranty; keep intact all the notices that refer to
+% this License and to the absence of any warranty; and give any other
+% recipients of the Program a copy of this License along with the Program.
+%
+% You may charge a fee for the physical act of transferring a copy, and you
+% may at your option offer warranty protection in exchange for a fee.
+%
+% \item
+% You may modify your copy or copies of the Program or any portion
+% of it, thus forming a work based on the Program, and copy and
+% distribute such modifications or work under the terms of Section 1
+% above, provided that you also meet all of these conditions:
+%
+% \begin{enumerate}
+%
+% \item
+% You must cause the modified files to carry prominent notices stating that
+% you changed the files and the date of any change.
+%
+% \item
+% You must cause any work that you distribute or publish, that in
+% whole or in part contains or is derived from the Program or any
+% part thereof, to be licensed as a whole at no charge to all third
+% parties under the terms of this License.
+%
+% \item
+% If the modified program normally reads commands interactively
+% when run, you must cause it, when started running for such
+% interactive use in the most ordinary way, to print or display an
+% announcement including an appropriate copyright notice and a
+% notice that there is no warranty (or else, saying that you provide
+% a warranty) and that users may redistribute the program under
+% these conditions, and telling the user how to view a copy of this
+% License. (Exception: if the Program itself is interactive but
+% does not normally print such an announcement, your work based on
+% the Program is not required to print an announcement.)
+%
+% \end{enumerate}
+%
+%
+% These requirements apply to the modified work as a whole. If
+% identifiable sections of that work are not derived from the Program,
+% and can be reasonably considered independent and separate works in
+% themselves, then this License, and its terms, do not apply to those
+% sections when you distribute them as separate works. But when you
+% distribute the same sections as part of a whole which is a work based
+% on the Program, the distribution of the whole must be on the terms of
+% this License, whose permissions for other licensees extend to the
+% entire whole, and thus to each and every part regardless of who wrote it.
+%
+% Thus, it is not the intent of this section to claim rights or contest
+% your rights to work written entirely by you; rather, the intent is to
+% exercise the right to control the distribution of derivative or
+% collective works based on the Program.
+%
+% In addition, mere aggregation of another work not based on the Program
+% with the Program (or with a work based on the Program) on a volume of
+% a storage or distribution medium does not bring the other work under
+% the scope of this License.
+%
+% \item
+% You may copy and distribute the Program (or a work based on it,
+% under Section 2) in object code or executable form under the terms of
+% Sections 1 and 2 above provided that you also do one of the following:
+%
+% \begin{enumerate}
+%
+% \item
+%
+% Accompany it with the complete corresponding machine-readable
+% source code, which must be distributed under the terms of Sections
+% 1 and 2 above on a medium customarily used for software interchange; or,
+%
+% \item
+%
+% Accompany it with a written offer, valid for at least three
+% years, to give any third party, for a charge no more than your
+% cost of physically performing source distribution, a complete
+% machine-readable copy of the corresponding source code, to be
+% distributed under the terms of Sections 1 and 2 above on a medium
+% customarily used for software interchange; or,
+%
+% \item
+%
+% Accompany it with the information you received as to the offer
+% to distribute corresponding source code. (This alternative is
+% allowed only for noncommercial distribution and only if you
+% received the program in object code or executable form with such
+% an offer, in accord with Subsection b above.)
+%
+% \end{enumerate}
+%
+%
+% The source code for a work means the preferred form of the work for
+% making modifications to it. For an executable work, complete source
+% code means all the source code for all modules it contains, plus any
+% associated interface definition files, plus the scripts used to
+% control compilation and installation of the executable. However, as a
+% special exception, the source code distributed need not include
+% anything that is normally distributed (in either source or binary
+% form) with the major components (compiler, kernel, and so on) of the
+% operating system on which the executable runs, unless that component
+% itself accompanies the executable.
+%
+% If distribution of executable or object code is made by offering
+% access to copy from a designated place, then offering equivalent
+% access to copy the source code from the same place counts as
+% distribution of the source code, even though third parties are not
+% compelled to copy the source along with the object code.
+%
+% \item
+% You may not copy, modify, sublicense, or distribute the Program
+% except as expressly provided under this License. Any attempt
+% otherwise to copy, modify, sublicense or distribute the Program is
+% void, and will automatically terminate your rights under this License.
+% However, parties who have received copies, or rights, from you under
+% this License will not have their licenses terminated so long as such
+% parties remain in full compliance.
+%
+% \item
+% You are not required to accept this License, since you have not
+% signed it. However, nothing else grants you permission to modify or
+% distribute the Program or its derivative works. These actions are
+% prohibited by law if you do not accept this License. Therefore, by
+% modifying or distributing the Program (or any work based on the
+% Program), you indicate your acceptance of this License to do so, and
+% all its terms and conditions for copying, distributing or modifying
+% the Program or works based on it.
+%
+% \item
+% Each time you redistribute the Program (or any work based on the
+% Program), the recipient automatically receives a license from the
+% original licensor to copy, distribute or modify the Program subject to
+% these terms and conditions. You may not impose any further
+% restrictions on the recipients' exercise of the rights granted herein.
+% You are not responsible for enforcing compliance by third parties to
+% this License.
+%
+% \item
+% If, as a consequence of a court judgment or allegation of patent
+% infringement or for any other reason (not limited to patent issues),
+% conditions are imposed on you (whether by court order, agreement or
+% otherwise) that contradict the conditions of this License, they do not
+% excuse you from the conditions of this License. If you cannot
+% distribute so as to satisfy simultaneously your obligations under this
+% License and any other pertinent obligations, then as a consequence you
+% may not distribute the Program at all. For example, if a patent
+% license would not permit royalty-free redistribution of the Program by
+% all those who receive copies directly or indirectly through you, then
+% the only way you could satisfy both it and this License would be to
+% refrain entirely from distribution of the Program.
+%
+% If any portion of this section is held invalid or unenforceable under
+% any particular circumstance, the balance of the section is intended to
+% apply and the section as a whole is intended to apply in other
+% circumstances.
+%
+% It is not the purpose of this section to induce you to infringe any
+% patents or other property right claims or to contest validity of any
+% such claims; this section has the sole purpose of protecting the
+% integrity of the free software distribution system, which is
+% implemented by public license practices. Many people have made
+% generous contributions to the wide range of software distributed
+% through that system in reliance on consistent application of that
+% system; it is up to the author/donor to decide if he or she is willing
+% to distribute software through any other system and a licensee cannot
+% impose that choice.
+%
+% This section is intended to make thoroughly clear what is believed to
+% be a consequence of the rest of this License.
+%
+% \item
+% If the distribution and/or use of the Program is restricted in
+% certain countries either by patents or by copyrighted interfaces, the
+% original copyright holder who places the Program under this License
+% may add an explicit geographical distribution limitation excluding
+% those countries, so that distribution is permitted only in or among
+% countries not thus excluded. In such case, this License incorporates
+% the limitation as if written in the body of this License.
+%
+% \item
+% The Free Software Foundation may publish revised and/or new versions
+% of the General Public License from time to time. Such new versions will
+% be similar in spirit to the present version, but may differ in detail to
+% address new problems or concerns.
+%
+% Each version is given a distinguishing version number. If the Program
+% specifies a version number of this License which applies to it and ``any
+% later version'', you have the option of following the terms and conditions
+% either of that version or of any later version published by the Free
+% Software Foundation. If the Program does not specify a version number of
+% this License, you may choose any version ever published by the Free Software
+% Foundation.
+%
+% \item
+% If you wish to incorporate parts of the Program into other free
+% programs whose distribution conditions are different, write to the author
+% to ask for permission. For software which is copyrighted by the Free
+% Software Foundation, write to the Free Software Foundation; we sometimes
+% make exceptions for this. Our decision will be guided by the two goals
+% of preserving the free status of all derivatives of our free software and
+% of promoting the sharing and reuse of software generally.
+%
+% \begin{center}
+% {\Large\sc
+% No Warranty
+% }
+% \end{center}
+%
+% \item
+% {\sc Because the program is licensed free of charge, there is no warranty
+% for the program, to the extent permitted by applicable law. Except when
+% otherwise stated in writing the copyright holders and/or other parties
+% provide the program ``as is'' without warranty of any kind, either expressed
+% or implied, including, but not limited to, the implied warranties of
+% merchantability and fitness for a particular purpose. The entire risk as
+% to the quality and performance of the program is with you. Should the
+% program prove defective, you assume the cost of all necessary servicing,
+% repair or correction.}
+%
+% \item
+% {\sc In no event unless required by applicable law or agreed to in writing
+% will any copyright holder, or any other party who may modify and/or
+% redistribute the program as permitted above, be liable to you for damages,
+% including any general, special, incidental or consequential damages arising
+% out of the use or inability to use the program (including but not limited
+% to loss of data or data being rendered inaccurate or losses sustained by
+% you or third parties or a failure of the program to operate with any other
+% programs), even if such holder or other party has been advised of the
+% possibility of such damages.}
+%
+% \end{enumerate}
+%
+%
+% \begin{center}
+% {\Large\sc End of Terms and Conditions}
+% \end{center}
+%
+%
+% \pagebreak[2]
+%
+% \section*{Appendix: How to Apply These Terms to Your New Programs}
+%
+% If you develop a new program, and you want it to be of the greatest
+% possible use to the public, the best way to achieve this is to make it
+% free software which everyone can redistribute and change under these
+% terms.
+%
+% To do so, attach the following notices to the program. It is safest to
+% attach them to the start of each source file to most effectively convey
+% the exclusion of warranty; and each file should have at least the
+% ``copyright'' line and a pointer to where the full notice is found.
+%
+% \begin{quote}
+% one line to give the program's name and a brief idea of what it does. \\
+% Copyright (C) yyyy name of author \\
+%
+% This program is free software; you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation; either version 2 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program; if not, write to the Free Software
+% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+% \end{quote}
+%
+% Also add information on how to contact you by electronic and paper mail.
+%
+% If the program is interactive, make it output a short notice like this
+% when it starts in an interactive mode:
+%
+% \begin{quote}
+% Gnomovision version 69, Copyright (C) yyyy name of author \\
+% Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. \\
+% This is free software, and you are welcome to redistribute it
+% under certain conditions; type `show c' for details.
+% \end{quote}
+%
+%
+% The hypothetical commands {\tt show w} and {\tt show c} should show the
+% appropriate parts of the General Public License. Of course, the commands
+% you use may be called something other than {\tt show w} and {\tt show c};
+% they could even be mouse-clicks or menu items---whatever suits your
+% program.
+%
+% You should also get your employer (if you work as a programmer) or your
+% school, if any, to sign a ``copyright disclaimer'' for the program, if
+% necessary. Here is a sample; alter the names:
+%
+% \begin{quote}
+% Yoyodyne, Inc., hereby disclaims all copyright interest in the program \\
+% `Gnomovision' (which makes passes at compilers) written by James Hacker. \\
+%
+% signature of Ty Coon, 1 April 1989 \\
+% Ty Coon, President of Vice
+% \end{quote}
+%
+%
+% This General Public License does not permit incorporating your program
+% into proprietary programs. If your program is a subroutine library, you
+% may consider it more useful to permit linking proprietary applications
+% with the library. If this is what you want to do, use the GNU Library
+% General Public License instead of this License.
+%
+% \end{multicols}
+% \end{minipage}
+% \end{lrbox}
+%
+% \begin{center}
+% \scalebox{0.33}{\usebox{\gpl}}
+% \end{center}
+%
+% \Finale
+\endinput
diff --git a/macros/luatex/generic/luamplib/luamplib.pdf b/macros/luatex/generic/luamplib/luamplib.pdf
new file mode 100644
index 0000000000..96852e5d3f
--- /dev/null
+++ b/macros/luatex/generic/luamplib/luamplib.pdf
Binary files differ
diff --git a/macros/luatex/generic/luamplib/test-luamplib-latex.tex b/macros/luatex/generic/luamplib/test-luamplib-latex.tex
new file mode 100644
index 0000000000..237a289748
--- /dev/null
+++ b/macros/luatex/generic/luamplib/test-luamplib-latex.tex
@@ -0,0 +1,164 @@
+\documentclass{article}
+\usepackage{luamplib}
+\usepackage{xcolor}
+\everymplib{ beginfig(0); }
+\everyendmplib{ endfig; }
+\mpliblegacybehavior{true}%
+\begin{document}
+\tracingcommands1
+A%
+\begin{mplibcode}
+%% test all printable ascii chars in comments
+%% ( 2 < F P Z d n x
+%% ) 3 = G Q [ e o y
+%% * 4 > H R \ f p z
+%% ! + 5 ? I S ] g q {
+%% " , 6 @ J T ^ h r |
+%% # - 7 A K U _ i s }
+%% $ . 8 B L V ` j t ~
+%% % / 9 C M W a k u DEL
+%% & 0 : D N X b l v
+%% ´ 1 ; E O Y c m w
+ fill fullcircle scaled 20; %% actual <tab> to make sure it works
+\end{mplibcode}%
+B\par
+\everymplib{}\everyendmplib{}% reset toks
+A%
+\begin{mplibcode}
+verbatimtex \lower.2em etex
+beginfig(0);
+draw origin--(1cm,0) withcolor \mpcolor{teal};
+draw btex g etex withcolor \mpcolor{orange};
+draw btex\tracingcommands0
+ multi%
+ \begin{huge}line\end{huge}%
+ texcode
+ with \%
+ etex shifted (10,0);
+draw bbox currentpicture;
+endfig;
+
+beginfig(18);
+numeric u;
+u = 1cm;
+draw (0,2u)--(0,0)--(4u,0);
+pickup pencircle scaled 1pt;
+draw (0,0){up}
+ for i=1 upto 8: ..(i/2,sqrt(i/2))*u endfor;
+label.lrt(btex $\sqrt x$ etex, (3,sqrt 3)*u);
+label.bot(btex $x$ etex, (2u,0));
+label.lft(btex $y$ etex, (0,u));
+endfig;
+\end{mplibcode}%
+B\par
+A%
+\begin{mplibcode}
+beginfig(2);
+numeric u; u=1cm;
+z1=-z2=(-u,0);
+for i = 1 upto 3:
+ draw z1..(0, i*u)..z2;
+ label.top(TEX("$e_{" & decimal(i) & "}$"), (0, i*u))
+ withcolor \mpcolor{red!70!blue};
+endfor;
+endfig;
+\end{mplibcode}%
+B\par\leavevmode
+\mplibcodeinherit{enable}%
+\mplibglobaltextext{enable}%
+\everymplib{ beginfig(0);}\everyendmplib{ endfig;}%
+\begin{mplibcode}
+ label(btex $\sqrt{2}$ etex, origin);
+ draw fullcircle scaled 20;
+ picture pic; pic := currentpicture;
+\end{mplibcode}%
+\begin{mplibcode}
+ currentpicture := pic scaled 2;
+\end{mplibcode}%
+\everymplib{}\everyendmplib{}%
+\mplibcodeinherit{disable}%
+\mplibglobaltextext{disable}\par
+\mplibsetformat{metafun}%
+\begin{mplibcode}
+verbatimtex \moveright 0.4\hsize etex
+beginfig(0);
+path p; p:= fullcircle scaled 2cm yshifted .5cm;
+fill p withcolor transparent("normal", 0.5, red);
+fill p rotated 120 withcolor transparent("normal", 0.5, green);
+fill p rotated 240 withcolor transparent("normal", 0.5, blue);
+endfig;
+verbatimtex \leavevmode etex
+picture p; p := btex MetaPost etex scaled 2;
+beginfig(1);
+linear_shade(bbox p,0,blue,.7white);
+draw p withcolor white;
+endfig;
+verbatimtex \kern10pt etex
+beginfig(2);
+circular_shade(bbox p,0,blue,.7white);
+draw p withcolor white;
+endfig;
+\end{mplibcode}%
+
+\newbox\mympbox
+\begin{mplibcode}
+verbatimtex \global\setbox\mympbox etex
+beginfig(0);
+breadth=.667\mpdim\linewidth;
+height=2pt;
+x1=0; x2=x6=.333x4; x5=x3=.667x4;
+x4=breadth;
+y1=y4=height/2; y2=y3=height; y5=y6=0;
+fill z1--z2--z3--z4--z5--z6--cycle;
+endfig;
+\end{mplibcode}%
+\copy\mympbox
+\copy\mympbox
+\copy\mympbox
+\copy\mympbox
+
+\mplibnumbersystem{double}%
+\begin{mplibcode}
+beginfig(0);
+u := 10**5*(10**-4);
+draw unitsquare scaled u;
+endfig;
+\end{mplibcode}%
+\mplibsetformat{plain}%
+\begin{mplibcode}
+ input graph;
+ beginfig(0);
+ draw begingraph(100,100);
+ gdraw (10,10)--(30,35)--(50,25)--(70,80)--(90,90);
+ autogrid(otick.bot,);
+ for y=20,40,60,80:
+ grid.lft(format("%e",1000y), y) withcolor .85white;
+ endfor
+ endgraph;
+ endfig;
+\end{mplibcode}%
+\mplibtextextlabel{enable}%
+\begin{mplibcode}
+beginfig(0);
+dotlabel.rt("$\sqrt2$",origin);
+endfig;
+\end{mplibcode}%
+\leavevmode
+\begin{mplibcode}
+ D := sqrt(2)**7;
+ beginfig(0);
+ draw fullcircle scaled D;
+ VerbatimTeX("\gdef\Dia{" & decimal D & "}");
+ endfig;
+\end{mplibcode}%
+diameter:\Dia bp.%
+\begin{mplibcode}
+ vardef rotatedlabel@#(expr str, loc, angl) =
+ draw thelabel@#(str, loc) rotatedaround(loc, angl)
+ enddef;
+
+ beginfig(1);
+ rotatedlabel.top(textext("Rotated!"), origin, 45);
+ endfig;
+\end{mplibcode}%
+\end{document}
diff --git a/macros/luatex/generic/luamplib/test-luamplib-plain.tex b/macros/luatex/generic/luamplib/test-luamplib-plain.tex
new file mode 100644
index 0000000000..2161cf2f76
--- /dev/null
+++ b/macros/luatex/generic/luamplib/test-luamplib-plain.tex
@@ -0,0 +1,162 @@
+\input miniltx
+\input color
+\definecolor{orange}{rgb}{1,0.5,0}
+\input luamplib.sty
+\mpliblegacybehavior{true}%
+\everymplib{ beginfig(0); }\everyendmplib{ endfig; }
+\tracingcommands1
+A%
+\mplibcode
+%% test all printable ascii chars in comments
+%% ( 2 < F P Z d n x
+%% ) 3 = G Q [ e o y
+%% * 4 > H R \ f p z
+%% ! + 5 ? I S ] g q {
+%% " , 6 @ J T ^ h r |
+%% # - 7 A K U _ i s }
+%% $ . 8 B L V ` j t ~
+%% % / 9 C M W a k u DEL
+%% & 0 : D N X b l v
+%% ´ 1 ; E O Y c m w
+ fill fullcircle scaled 20;
+\endmplibcode
+B\par
+\everymplib{}\everyendmplib{}% reset toks
+A%
+\mplibcode
+verbatimtex \lower.2em etex
+beginfig(0);
+draw origin--(1cm,0) withcolor red;
+draw btex g etex withcolor blue;
+draw btex\tracingcommands0 multi
+ line
+ tex code
+ 100 \% color
+ etex shifted (20,0);
+draw textext("\tracingcommands0 textext 50\% color") shifted (10,-10) withcolor .5white;
+draw bbox currentpicture;
+endfig;
+
+beginfig(18);
+numeric u;
+u = 1cm;
+draw (0,2u)--(0,0)--(4u,0);
+pickup pencircle scaled 1pt;
+draw (0,0){up}
+ for i=1 upto 8: ..(i/2,sqrt(i/2))*u endfor;
+label.lrt(btex $\sqrt x$ etex, (3,sqrt 3)*u);
+label.bot(btex $x$ etex, (2u,0));
+label.lft(btex $y$ etex, (0,u));
+endfig;
+\endmplibcode
+B\par
+A%
+\mplibcode
+beginfig(2);
+numeric u; u=1cm;
+z1=-z2=(-u,0);
+for i = 1 upto 3:
+ draw z1..(0, i*u)..z2;
+ label.top(TEX("$e_{" & decimal(i) & "}$"), (0, i*u)) withcolor \mpcolor{orange};
+endfor;
+endfig;
+\endmplibcode
+B\par\leavevmode
+\mplibcodeinherit{enable}%
+\mplibglobaltextext{enable}%
+\everymplib{ beginfig(0);}\everyendmplib{ endfig;}%
+\mplibcode
+ label(btex $\sqrt{2}$ etex, origin);
+ draw fullcircle scaled 20;
+ picture pic; pic := currentpicture;
+\endmplibcode
+\mplibcode
+ currentpicture := pic scaled 2;
+\endmplibcode
+\everymplib{}\everyendmplib{}%
+\mplibcodeinherit{disable}%
+\mplibglobaltextext{disable}\par
+\mplibsetformat{metafun}%
+\mplibcode
+verbatimtex \moveright 0.4\hsize etex
+beginfig(0);
+path p; p:= fullcircle scaled 2cm yshifted .5cm;
+fill p withcolor transparent("normal", 0.5, red);
+fill p rotated 120 withcolor transparent("normal", 0.5, green);
+fill p rotated 240 withcolor transparent("normal", 0.5, blue);
+endfig;
+verbatimtex \leavevmode etex
+picture p; p := btex MetaPost etex scaled 2;
+beginfig(1);
+linear_shade(bbox p,0,blue,.7white);
+draw p withcolor white;
+endfig;
+verbatimtex \kern10pt etex
+beginfig(2);
+circular_shade(bbox p,0,blue,.7white);
+draw p withcolor white;
+endfig;
+\endmplibcode
+
+\newbox\mympbox
+\mplibcode
+verbatimtex \global\setbox\mympbox etex
+beginfig(0);
+breadth=.667\mpdim\hsize;
+height=2pt;
+x1=0; x2=x6=.333x4; x5=x3=.667x4;
+x4=breadth;
+y1=y4=height/2; y2=y3=height; y5=y6=0;
+fill z1--z2--z3--z4--z5--z6--cycle;
+endfig;
+\endmplibcode
+\copy\mympbox
+\copy\mympbox
+\copy\mympbox
+\copy\mympbox
+
+\mplibnumbersystem{double}%
+\mplibcode
+beginfig(0);
+u := 10**5*(10**-4);
+draw unitsquare scaled u;
+endfig;
+\endmplibcode
+\mplibsetformat{plain}%
+\mplibcode
+ input graph;
+ beginfig(0);
+ draw begingraph(100,100);
+ gdraw (10,10)--(30,35)--(50,25)--(70,80)--(90,90);
+ autogrid(otick.bot,);
+ for y=20,40,60,80:
+ grid.lft(format("%e",1000y), y) withcolor .85white;
+ endfor
+ endgraph;
+ endfig;
+\endmplibcode
+\mplibtextextlabel{enable}%
+\mplibcode
+beginfig(0);
+dotlabel.rt("$\sqrt2$",origin);
+endfig;
+\endmplibcode
+\leavevmode
+\mplibcode
+ D := sqrt(2)**7;
+ beginfig(0);
+ draw fullcircle scaled D;
+ VerbatimTeX("\gdef\Dia{" & decimal D & "}");
+ endfig;
+\endmplibcode
+diameter:\Dia bp.%
+\mplibcode
+ vardef rotatedlabel@#(expr str, loc, angl) =
+ draw thelabel@#(str, loc) rotatedaround(loc, angl)
+ enddef;
+
+ beginfig(1);
+ rotatedlabel.top(textext("Rotated!"), origin, 45);
+ endfig;
+\endmplibcode
+\bye
diff --git a/macros/luatex/generic/luaotfload/COPYING b/macros/luatex/generic/luaotfload/COPYING
new file mode 100644
index 0000000000..d769b3faa1
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/COPYING
@@ -0,0 +1,350 @@
+Context, where the fontloader Luaotfload is built around originates, is
+licensed under the GPL version 2.0 (exactly). As a derived work, anything
+Luaotflaod adds to that is also subject to the same license at the same
+version. The “any later version†clause as used by the FSF in the license text
+*does not apply* to either Context or Luaotfload, despite being kept around in
+the license text given below.
+
+-------------------------------------------------------------------------------
+ LICENSE TEXT BELOW
+-------------------------------------------------------------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/macros/luatex/generic/luaotfload/NEWS b/macros/luatex/generic/luaotfload/NEWS
new file mode 100644
index 0000000000..aa6b4ca7d7
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/NEWS
@@ -0,0 +1,343 @@
+Change History
+--------------
+2019-08-11 luaotfload v2.991
+ * fix issue #88
+
+2019-08-11 luaotfload v2.99
+ * some clean up
+ * fix a bug in luaotfload.aux.resolve_fontname() (issue #76)
+ * removed dependency on slnunicode (PR#72)
+ * sync with context files from 2019-08-11
+
+2019-06-20 luaotfload v2.98
+ * add embolden key
+ * add missing char detection issue #65
+ * sync with context files from 2019-07-04
+
+2019-05-18 luaotfload v2.97
+ * fix issue #47
+ * fix whatsits interfering with letterspacing (issue #53)
+ * fix luaotfload-tool switches version and find not working correctly (PR#59)
+ * fix luaotfload-tool support of ttc fonts (PR#58)
+ * sync with context files from 2019-05-18 (improves handling of large fonts, see e.g. issue #55 and PR#58)
+
+2019-01-28 luaotfload v2.96
+ * repaired broken letterspace (issue #38)
+ * changed handling of spaces in letterspacing
+ * changed handling of ligatures in letterspacing
+ * corrected detection of bold fonts (issue #41)
+
+2019-01-28 luaotfload v2.95
+ * imported context files of 2019-01-28
+ * changed bold indification (for lucida demi bold) (issue #33)
+ * changed handling of tex file (issue #35)
+ * changed resolver code (pr #36)
+
+2019-01-14 luaotfload v2.94
+ * imported context files of 2018-12-19
+ * removed luaotfload-characters from init - use the basics-chr instead.
+ * allow custom fontloaders through the mode-key https://github.com/u-fischer/luaotfload/pull/25
+ * resolved issue #29
+
+2018-10-28 luaotfload v2.93
+ * reinserted forgotten man files
+ * unified and improved version/module info for automatic tagging
+
+
+2018-10-21 luaotfload v2.92
+ * better deva support, issue #9
+ * test for --safer and abort, issue #12
+ * newest context files
+ * correct file: syntax for tfm files, issue #11.
+
+2018-10-03 luaotfload v2.91
+ * solved copy & paste of variant glyphs, https://tex.stackexchange.com/questions/451442/localized-glyphs-locl-have-unicode-value-ufffd
+ * solved problem with PUA no longer accessible with \char, see https://github.com/u-fischer/luaotfload/issues/7
+
+2018-09-21 luaotfload v2.9
+ * added various testfiles for the l3build system/travis tests to the github repository
+ * solved a bug regarding directions https://github.com/u-fischer/lua-font-pond/issues/12
+ * adapted luaotfload-letterspace to new fontloader
+ * solved the case problem see https://github.com/u-fischer/lua-font-pond/issues/6
+ * Fix parsing of font.conf see https://github.com/lualatex/luaotfload/pull/420
+ * imported new versions of the context files - fontloader is compatible with luatex 1.08 again
+ * adapted the files list
+ * created a luaotfload-filelist.lua which describes the files of the package
+ * removed some not functional files
+ * adapted mkstatus to use the new file list.
+
+2017-01-29, luaotfload v2.8:
+ * Latest fontloader code.
+ * Support for Luatex 1.0.
+ * Integration of the extended AFM handler.
+ * Fixes to font family assignment.
+ * Skip initialization if Luaotfload is already loaded.
+ * Optical sizes advertised by fonts treated as big points.
+
+2016/04/21, luaotfload v2.7:
+ * Rework lookup chaining.
+ * Combining glyphs from different fonts (``combo: ...`` requests).
+ * Glyph fallbacks.
+ * Latest fontloader code.
+ * Adapt packaging to changed upstream file layout.
+ * Remove support for builtin Fontforge libraries (this includes the PFA,
+ PFB, DFONT, and feature file readers).
+ * Allow configuration of anonymous lookups.
+
+2015/12/09, luaotfload v2.6
+ * Add ``sign`` target to makefile for automated package signing.
+ * Add ``--dumpconf`` option to luaotfload-tool for generating configuration
+ files.
+ * Move fontloader files to subtree src/fontloader.
+ * New script ``mkimport`` facilitates maintainance of code imported from
+ Context.
+ * Revised letterspacing, now utilizing the ``node.direct`` interface.
+ * Revized colorization of fonts, utilizing ``node.direct`` (Dohyun Kim).
+ * Colorization was moved to the ``post_linebreak_filter`` stage.
+ * Move remaining functionality from ``luaotfload-override`` into
+ initialization.
+ * Write names index if fonts were removed.
+ * Separate module loading from initialization.
+ * Custom fontloader package with the files from Lualibs removed.
+ * Swappable fontloader via configuration option.
+ * Lualibs are now a dependency when used in a TeX run as well.
+ * Respect interword spaces when letterspacing.
+
+2014/07/13, luaotfload v2.5
+ * Remove legacy code.
+ * Remove compatibility with the old mkluatexfontdb script.
+ * Remove test directory. Use https://bitbucket.org/phg/lua-la-tex-tests
+ instead.
+ * Remove luaotfload.lua from luaotfload.dtx; it is now a separate file
+ luaotfload-main.lua.
+ * Standard source tree structure: the code is now located in the ./doc,
+ ./scripts, ./src, ./build, and ./misc directories.
+ * Move the heavier LPEG parsers from luaotfload-features (syntax) and
+ luaotfload-database (fontconfig) into the new file
+ luaotfload-parsers.lua.
+ * Move logging routines from luaotfload-override in to luaotfload-log.
+ * Scan local font files (``--local`` flag to luaotfload-tool, flag
+ ``scan_local`` during TeX run).
+ * Add bisection mode (``--bisect``) to luaotfload-tool.
+ * Add functions for accessing the database: ``aux.font_index()`` and
+ ``aux.read_font_index()``.
+ * Distinguish XDG configuration paths (Reuben Thomas)
+ * Optional configuration via rc files.
+ * Configure default features via configuration file.
+
+2013/12/31, luaotfload v2.4
+ * Additional self-tests, now in separate file (luaotfload-diagnostics.lua)
+ * Better path and directory handling, especially on Windows
+ * database now indexes Type1 fonts (PFA, PFB) and makes them accessible
+ with style modifiers (requires --format=+pfa,pfb option to luaotfload-tool)
+ * Test runner (script mktests)
+ * New luaotfload-tool option: ``--no-reload``
+ * ``luaotfload-tool --find`` now understands request syntax
+ * text (Lua script) version of the font index is filtered through gzip by
+ default, the ``--no-compress`` option of luaotfload-tool will prevent
+ this
+ * rename ``luaotfload-merged.lua`` (the fontloader package from Context)
+ to ``luaotfload-fontloader.lua``
+ * Treat arguments of the ``letterspace`` option as percentages; add
+ ``kernfactor`` option that behaves as before.
+ * Remove imported version of typo-krn.lua. Xetex-style per-font
+ letterspacing is now the canonical method.
+ * Merge functionality from extralibs (fake Context layer) into
+ luaotfload-letterspace.lua as it is only needed there anyways.
+
+2013/07/10, luaotfload v2.3a
+ * Detect LuaJIT interpreter (LuaJITTeX)
+ * Self-test functionality for luaotfload-tool.lua (option ``--diagnose``)
+
+2013/07/03, luaotfload v2.3:
+ * New experimental lookups: ``kpse`` (kpathsea), ``my`` (callback)
+ * Precedence of texmf over system fonts can be requested
+ using the ``--prefer-texmf`` option of luaotfload-tool
+ * Resolve file names to full paths at later stage
+ * Rewrite the output of ``\fontname`` via ``patch_font`` callback
+ * Allow blacklisting directories
+ * Drop compatibility layer
+ * Remove dependency on luaotfload-lib-dir (references to dir.glob() and
+ dir.mkdirs())
+ * luaotfload-tool now displays extensive information about a font if given
+ the argument --inspect
+
+2013/05/20, luaotfload v2.2:
+ * There is now a central, non-personal dev repo on github:
+ https://github.com/lualatex/luaotfload
+ * Synchronisation with ConTeXt from TeXLive 2013, inducing
+ backward-incompatible changes in the font structure. A
+ backward-compatibility layer has been added for the current
+ versions of fontspec, unicode-math and microtype, but it should
+ disapear in a future version.
+ * Synchronisation with ConTeXt is now easier and can be done by just
+ updating luaotfload-merged.lua (<= luatex-fonts-merged.lua from
+ the LuaTeX-Plain format)
+ * Improved and extended documentation
+ * Font filenames are stored in the database (file: lookups more efficient)
+ * Optional caching of name: lookups (uses separate cache file)
+ * Rewriting and increased fidelity of XeTeX emulation
+ * Renaming mkluatexfontdb into luaotfload-tool (the old behavior is kept if
+ the script is symlinked or renamed mkluatexfontdb)
+ * Added options to luaotfload-tool for simple database queries
+ * Logging facilities have been rewritten and allow for more granularity
+ * All files have been renamed, abandoning cryptic acronyms; also
+ the new prefix is "luaotfload" (<= "otfl")
+ * The Adobe Glyph List (font-age.lua) is now built via script (mkglyphlist)
+ * Hans adapted the font loader to several of our requests (attribute
+ allocation, custom merged package name etc.)
+ * Auxiliary functions for package authors
+ * Man page for luaotfload-tool
+ * Unsupported v1.3 codebase is included in the luaotfload-*lua files. Crude,
+ but effective way to support older Luatex binaries
+ * implemented basic cache control/stats option for luaotfload-tool
+ * Character list is generated from char-def.lua (mkcharacters)
+
+2013/04/27, luaotfload v1.3:
+ * blacklisting lingoes.ttf (segfaults)
+ * unblacklisting ttc fonts (warning: may break LuaTeX < 0.65)
+ * fixing font cache file name with non-ascii characters
+
+2013/04/25, luaotfload v1.29:
+ * Reverting the unified resolver, as the database was rebuilt too often
+ which made the compilation longer. This will come back improved
+ in the next version, hopefully for TeXLive 2013.
+ * Fix resolving of Libertine Mono
+ * Fix a bug that made fontconfig files not parsed when OSFONTDIR is set
+
+2013/04/11, luaotfload v1.28:
+ * Adapting to LuaTeX 0.75
+ * Fix small documentation issues in mkluatexfontdb
+ * Fix possible infite loop with fontconfig config files references
+ * Adding semibold synonym for bold
+ * file:xxx syntax now uses the same search function as name: which
+ make more fonts recognized
+
+2012/05/28, luaotfload v1.27:
+ * Fix "endless loop in charlist" with some OpenType math fonts
+
+2012/03/27, luaotfload v1.26:
+ * Enable setting italic correction values by default
+ * Fix finding demibold italic fonts
+
+2011/04/21, luaotfload v1.25:
+ * Fix bug loading *.dfont fonts
+ * Misc. documentation fixes
+ * Fix the need to manually delete font cache when feature file is changed
+ * Hack to support Demi fonts
+
+2011/02/16, luaotfload v1.24:
+ * Fix infinite loop first time creating a name list
+
+2011/02/04, luaotfload v1.23:
+ * Fix a typo breaking fonts.names.scan()
+
+2011/01/25, luaotfload v1.22:
+ * Remove --database-dir and --sys options from mkluatexfontdb
+ * Provide a "luaotfload.patch_font" callback for on the fly patching of fonts
+ * Some documentation improvements
+
+2010/11/11, luaotfload v1.21:
+ * Adapt to luatexbase v3.0
+
+2010/10/16, luaotfload v1.20:
+ * Make cache directory creation more robust
+ * Fix GPOS mark placement in left-to-right direction
+ * Reject fonts missing 'names' table
+ * Sanitize color value before attempting to use it
+
+2010/09/12, luaotfload v1.19:
+ * fix LaTeX's detection (made Tikz fail under a non-LaTeX format)
+
+2010/07/15, luaotfload v1.18:
+ * fix for \overwithdelims and brothers
+
+2010/07/14, luaotfload v1.17:
+ * allow stylistic sets features in base mode
+ * don't scale percent math constants
+
+2010/07/12, luaotfload v1.16:
+ * support keys prefixed by "+", for compatibility with XeTeX
+ * remove the progress bar from mkluatexfontdb, it is of little use now
+ * minor code a documentation cleanups
+
+2010/06/28, luaotfload v1.15:
+ * anum feature did not work as advertised
+ * add system shipped TTC fonts on Mac OS X to the blacklist, until the
+ culprit ones are isolated
+
+2010/06/25, luaotfload v1.14:
+ * fix mkluatexfontdb which was broken in the last version
+ * support general font blacklisting feature
+ * temporally re-enable ttc fonts on Mac OS X
+ * make sure mkluatexfontdb in verbose mode prints font filename before
+ attempting to load it
+
+2010/06/24, luaotfload v1.13:
+ * fix typo in font cache path
+
+2010/06/18, luaotfload v1.12:
+ * populate MathConstants table for OpenType math fonts, now such fonts
+ can be really used in math mode.
+ * sync with ConTeXt beta 2010.06.18
+ * change cache dir to $TEXMFCACHE/luatex-cache/generic
+
+2010/06/09, luaotfload v1.11:
+ * when asking for a font with style that doesn't exist, we would return
+ nothing, now we fallback to the regular font
+
+2010/06/07, luaotfload v1.10:
+ * provide a fonts.names.scan(dir) function that temporally loads fonts
+ from the specified dir into the names database
+ * Log loaded font file before attempting to open it
+ * fix XeTeX's square brackets syntax so that it doesn't trigger database
+ update
+ * fix loading fonts with absolute path
+ * add \fontdimen8 support, for XeTeX compatibility
+ * be more verbose when updating the font database
+ * improve fonts.conf parsing
+ * make sure when a TFM font is requested we don't end up loading a non-TFM
+ font with a similar name instead
+ * Remove --fc-cache option from mkluatexfontdb.lua, since we no longer use
+ fontconfig tools
+ * misc. bug fixes
+
+2010/05/30, luaotfload v1.09:
+ * the last release didn't even load
+ * fix passing --destdir to mkluatexfontdb
+
+2010/05/28, luaotfload v1.08a:
+ * revert experimental code that was committed by mistake
+
+2010/05/28, luaotfload v1.08:
+ * fix misc. bugs with system fonts scanning
+ * parse fontconfig configuration directly, no longer dependant on 'fc-list'
+ * now if no font names database is found, luaotfload will generate it, also
+ it will force an update of the database if the asked font can not be
+ found
+ * avoid loading non-tfm fonts when the user asks for tfm font
+ * update the documentation
+ * blacklist .ttc and LastResort font on mac.
+ * sync with ConTeXt beta 2010.05.22
+ * fix attribute handling
+ * clarify license
+ * misc. bug fixes
+
+2010/05/10, luaotfload v1.07:
+ * using the new luatexbase package
+ * synchronizing with latest ConTeXt stable 2010.05.08
+ * adding support for microtypography
+ * adding support for color and transparency
+ * adding a script to generate a font database with TeX and system fonts
+ * more verbose log file
+
+2010/02/07, luaotfload v1.06a:
+ * more complete tlig and trep
+ * defaults options changed to "+ccmp;+locl;+rlig;+liga;+clig;+kern;
+ +mark;+mkmk;"
+ * supporting windows absolute path
+
+2009/12/01, luaotfload v1.06:
+ * synchronizing with ConTeXt stable 2009.11.26
+ * adding backward compatibility with LuaTeX 0.40.6
+
diff --git a/macros/luatex/generic/luaotfload/README.md b/macros/luatex/generic/luaotfload/README.md
new file mode 100644
index 0000000000..e59852f294
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/README.md
@@ -0,0 +1,103 @@
+# The Luaotfload Package
+
+VERSION: 2.991
+
+DATE: 2019-08-11
+
+
+## Description
+
+Luaotfload is an adaptation of the ConTeXt font loading system for the Plain
+and LaTeX formats. It allows OpenType fonts to be loaded with font features
+accessible using an extended font request syntax while providing compatibility
+with XeTeX. By indexing metadata in a database it facilitates loading fonts by
+their proper names instead of file names.
+
+Luaotfload may be loaded in Plain LuaTeX with "\input luaotfload.sty" and in
+LuaLaTeX with "\usepackage{luaotfload}". LuaLaTeX users may be interested in
+the fontspec package which provides a high-level interface to the functionality
+provided by this package.
+
+Please see the documentation luaotfload.pdf for more information.
+
+## Maintenance
+
+This package is currently maintained at
+<https://github.com/u-fischer/luaotfload>.
+
+Issues can be reported at the issue tracker or at the old issue tracker on
+<http://github.com/lualatex/luaotfload>.
+
+The development for LuaLaTeX is discussed on the lualatex-dev mailing list. See
+<http://www.tug.org/mailman/listinfo/lualatex-dev> for details.
+
+
+## Responsible Persons
+
+The following people have contributed to this package.
+
+- Khaled Hosny <khaledhosny@eglug.org>
+- Elie Roux <elie.roux@telecom-bretagne.eu>
+- Will Robertson <will.robertson@latex-project.org>
+- Philipp Gesang <phg@phi-gamma.net>
+- Dohyun Kim <nomosnomos@gmail.com>
+- Reuben Thomas <https://github.com/rrthomas>
+- Joseph Wright <joseph.wright@morningstar2.co.uk>
+- Manuel Pégourié-Gonnard <mpg@elzevir.fr>
+- Olof-Joachim Frahm <olof@macrolet.net>
+- Patrick Gundlach <gundlach@speedata.de>
+- Philipp Stephani <st_philipp@yahoo.de>
+- David Carlisle <d.p.carlisle@gmail.com>
+- Yan Zhou @zhouyan
+- Ulrike Fischer <fischer@troubleshooting-tex.de>
+- Marcel Krüger <https://github.com/zauguin>
+
+## Installation
+
+1. Install the current version with the package management tools of your TeX system.
+ If you want to install manually: there is a tds-zip file which can be unpacked in a texmf tree.
+
+2. If you want to try the development version download the texmf folder in the development branch.
+ at <https://github.com/u-fischer/luaotfload>
+
+3. Manual installation:
+ * luaotfload-tool.lua belongs in scripts/luatex/luaotfload
+ * fontloader-reference-load-order.tex and fontloader-reference-load-order.lua are source files and can got in source or doc
+ * the other lua-files and the sty belong in tex/luatex/luaotfload
+ * luaotfload.conf.5 and luaotfload-tool.1 belong in doc/man
+ * the rest in doc/luatex/luaotfload
+
+## Documentation
+
+* The main documentation is luaotfload-latex.pdf.
+* luaotfload.conf.5 and luaotfload-tool.1 are man-files, their sources are the rst-files.
+* README.md, NEWS and COPYING contain what their name says.
+* The rest are input files.
+
+
+
+
+## License
+
+The luaotfload bundle, as a derived work of ConTeXt, is distributed under the
+GNU GPLv2 license:
+
+ <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
+
+This license requires the license itself to be distributed with the work. For
+its full text see the documentation in luaotfload.pdf.
+
+
+## DISCLAIMER
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; version 2.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ See headers of each source file for copyright details.
+
diff --git a/macros/luatex/generic/luaotfload/filegraph.pdf b/macros/luatex/generic/luaotfload/filegraph.pdf
new file mode 100644
index 0000000000..e5807ca3ca
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/filegraph.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/filegraph.tex b/macros/luatex/generic/luaotfload/filegraph.tex
new file mode 100644
index 0000000000..297816671a
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/filegraph.tex
@@ -0,0 +1,266 @@
+% !Mode:: "TeX:EN:UTF-8:Main"
+%created with by @marmot 14.09.2018
+%
+\documentclass[border=3.14mm,tikz]{standalone}
+\usetikzlibrary{fit,matrix,positioning,arrows.meta,decorations.text,shapes.callouts}
+\pgfdeclarelayer{background}
+\pgfdeclarelayer{container}
+\pgfdeclarelayer{foreground}
+\pgfsetlayers{container,background,main,foreground}
+\usepackage {fontspec}
+\usepackage {unicode-math}
+\usepackage{tikzmarmots,tikzducks}
+
+\setmainfont[
+% Numbers = OldStyle, %% buggy with font cache
+ Ligatures = TeX,
+ BoldFont = {Linux Libertine O Bold},
+ ItalicFont = {Linux Libertine O Italic},
+ SlantedFont = {Linux Libertine O Italic},
+]{Linux Libertine O}
+\setmonofont[Ligatures=TeX,Scale=MatchLowercase]{InconsolataN-Regular.otf}
+%setsansfont[Ligatures=TeX]{Linux Biolinum O}
+\setsansfont[Ligatures=TeX,Scale=MatchLowercase]{Iwona Medium}
+
+\usepackage{luacode}
+\begin{luacode}
+require("luaotfload-filelist.lua")
+
+function printctxfontlist ()
+ t= luaotfload.filelist.selectctxfontentries (luaotfload.filelist.data)
+ for i,v in ipairs (t) do
+ tex.sprint("\\mbox{"..v.name..v.ext.."} ")
+ end
+end
+
+function printctxlibslist ()
+ t= luaotfload.filelist.selectctxlibsentries (luaotfload.filelist.data)
+ local rowcnt = 0
+ local sep = "&"
+ for i,v in ipairs (t) do
+ rowcnt = rowcnt + 1
+ if rowcnt % 4 == 0 then sep = "\\\\" else sep = "&" end
+ tex.sprint("\\mbox{"..v.name..v.ext.."}".. sep)
+ end
+end
+
+function printctxgenericlist ()
+ t= luaotfload.filelist.selectctxgeneusedentries (luaotfload.filelist.data)
+ local rowcnt = 0
+ local sep = "&"
+ for i,v in ipairs (t) do
+ rowcnt = rowcnt + 1
+ if rowcnt % 2 == 0 then sep = "\\\\" else sep = "&" end
+ tex.sprint("\\mbox{"..v.ctxpref..v.name..v.ext.."}".. sep)
+ end
+end
+
+
+function printlibrarylist ()
+ t = luaotfload.filelist.selectlollibentries (luaotfload.filelist.data)
+ local rowcnt = 0
+ local sep = "&"
+ for i,v in ipairs (t) do
+ rowcnt = rowcnt + 1
+ if rowcnt % 2 == 0 then sep = "\\\\" else sep = "&" end
+ tex.sprint("\\mbox{"..v.gitpref..v.name..v.ext.."}".. sep)
+ end
+ if rowcnt % 2 == 1 then tex.sprint("\\\\") end -- if odd number we must end the matrix
+end
+
+function printscriptlist ()
+ t = luaotfload.filelist.selectlolscrentries (luaotfload.filelist.data)
+ for i,v in ipairs ( t ) do
+ if v.kind == 8 then
+ tex.sprint( v.name .."\\\\")
+ end
+ end
+end
+
+\end{luacode}
+\begin{document}
+\begin{tikzpicture}[rounded corners,basic/.style={inner
+sep=9pt,font=\ttfamily,align=center}]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% text nodes
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% m1
+\matrix [matrix of nodes,font=\ttfamily,nodes={anchor=base west},
+label={[name=mL1,font=\itshape]above:Luaotfload Libraries}] (m1)
+{%
+%<<<<<<<<<<<<<<<<
+\directlua{printlibrarylist()}
+%>>>>>>>>>>>>>>>>
+};
+% m2
+\node[right=4.2cm of m1,fill=gray!20,draw=gray!30,dashed,basic] (m2) {luaotfload-blacklist.cnf};
+% m3
+\matrix [below=2cm of m1,matrix of nodes,font=\ttfamily,nodes={anchor=base west},
+label={[name=mL3,font=\itshape,anchor=south]above:Lualibs -- Lua Libraries from Context}] (m3)
+{%
+%<<<<<<<<<<<<<<<<
+\directlua{printctxlibslist ()}
+%>>>>>>>>>>>>>>>>
+};
+% m4
+\node[left=2cm of m3,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm] (m4) {luaotfload-main.lua};
+% m5
+\node[fill=gray!20,draw=gray!30,dashed,basic,inner sep=6mm,anchor=south west] at (m3.south -|
+m2.west)(m5){%
+%<<<<<<<<<<<<<<<<
+luaotfload-names.lua.gz\\
+luaotfload-names.luc
+%>>>>>>>>>>>>>>>>
+};
+% m6
+\node[below=3cm of m3,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm] (m6){luaotfload-init.lua};
+% m7
+\node[above right=0.5cm and 2.5cm of m6,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm] (m7){luaotfload-log.lua};
+% m8
+\matrix [below left=1cm and 2cm of m6,matrix of nodes,font=\ttfamily,
+row sep=5mm,
+nodes={inner sep=3mm,fill=orange!10,rounded corners},
+label={[name=mL8,font=\it]above:Fontloader}] (m8)
+{%
+%<<<<<<<<<<<<<<<<
+fontloader-basics-gen.lua\\
+fontloader-YY-MM-DD.lua\\
+%<<<<<<<<<<<<<<<<
+};
+% m9
+\node [below right=1cm and 2cm of m6,font=\ttfamily,
+inner sep=3mm,text width=7.3cm,align=left,
+label={[name=mL9,font=\itshape]Font and Node Libraries from Context}] (m9)
+{\spaceskip=1.5em \raggedright
+%%<<<<<<<<<<<<<<<<
+\directlua{printctxfontlist()}
+%>>>>>>>>>>>>>>>>
+};
+% m10
+\node [below=1cm of m9,font=\ttfamily,
+inner sep=3mm,text width=7.3cm,align=center,
+label={[name=mL10,font=\itshape]Font Loader (LuaTeX-Fonts)}] (m10)
+{\tabcolsep=0.5em
+ \begin{tabular}{@{}ll@{}}
+%<<<<<<<<<<<<<<<<
+\directlua{printctxgenericlist ()}
+%>>>>>>>>>>>>>>>>
+ \end{tabular}
+};
+% m11
+\node [above=1cm of m9] (m11) {Merged libraries};
+% m12
+\matrix [below=4cm of m6,xshift=-1cm,matrix of nodes,font=\ttfamily,
+row sep=5mm,
+nodes={inner sep=3mm,fill=gray!10,rounded corners,text width=3cm,align=center},
+label={[name=mL12,font=\sffamily]above:Standalone scripts}] (m12)
+{%
+%<<<<<<<<<<<<<<<<
+\directlua{printscriptlist ()}
+%>>>>>>>>>>>>>>>>
+};
+% m13
+\node[below=1.2cm of m10,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm] (m13)
+{%
+%<<<<<<<<<<<<<<<<
+luaotfload-glyphlist.lua
+%>>>>>>>>>>>>>>>>
+};
+% m14
+\node[below=0.8cm of m13,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm] (m14)
+{%
+%<<<<<<<<<<<<<<<<
+luaotfload-characters.lua
+%>>>>>>>>>>>>>>>>
+};
+% m15
+\node[below=3cm of m8,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm]
+(m15) {%
+%<<<<<<<<<<<<<<<<
+luaotfload-tool.lua
+%>>>>>>>>>>>>>>>>
+};
+% m16
+\node[below=1cm of m15,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm]
+(m16) {%
+%<<<<<<<<<<<<<<<<
+luaotfload-diagnostics.lua
+%>>>>>>>>>>>>>>>>
+};
+% m17
+\node[below=2cm of m16,xshift=3cm,fill=gray!20,draw=gray!30,dashed,basic,inner sep=6pt]
+(m17) {%
+%<<<<<<<<<<<<<<<<
+luaotfload-status.lua
+%>>>>>>>>>>>>>>>>
+};
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% envelopes
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{pgfonlayer}{background}
+%M1
+\node[fill=gray!10,fit=(m1)(mL1),rounded corners=0](mF1){};
+%M3
+\node[fill=blue!10,fit=(m3)(mL3),rounded corners=0](mF3){};
+%M9
+\node[fill=purple!10,fit=(m9)(mL9)](mF9){};
+%M10
+\node[fill=purple!10,fit=(m10)(mL10)](mF10){};
+\end{pgfonlayer}
+\begin{pgfonlayer}{container}
+%M1
+\node[fill=gray!20,fit=(mF1)](M1){};
+%M3
+\node[fill=blue!20,fit=(mF3)](M3){};
+%M8
+\node[fill=orange!20,fit=(m8)(mL8)](mF8){};
+%M11
+\node[fill=purple!20,fit=(m11)(mF9)(mF10)](M11){};
+%M11
+\node[top color=gray!40,bottom color=red!60!black,fit=(mL12)(m12)](M12){};
+\end{pgfonlayer}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% arrows
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{scope}[font=\sffamily,>={Triangle[open]},annotate/.style={postaction={decorate,decoration={text along path,text
+align=center,raise=2pt,text={|\sffamily| #1}}}}]
+\draw[->,annotate=luaotfload-database.lua] (M1) -- (m2);
+\draw[->,annotate=main()] (m4) -- (M1);
+\draw[->] (m4) -- (M3);
+\draw[->,annotate=luaotfload-database.lua] (M1.-15) to[out=0,in=90] (m5);
+\draw[->,annotate=main()] (m4) to[out=-70,in=120] (m6);
+\draw[->,annotate=init{{\_}}early()] (m6) to[out=45,in=190] (m7);
+\draw[<-,annotate=init{{\_}}early()] (m8-1-1) to[in=-150,out=0] (m6);
+\draw[<-,annotate=init{{\_}}main()] (m8-2-1) to[in=-100,out=4] (m6);
+\draw[->,annotate=unmerged] (m6) to[out=0,in=180] (mF9.150);
+\draw[->,dashed,annotate=merged] (m8-2-1) to[out=0,in=180] (mF9.170);
+\draw[->,dashed,annotate=pulls] (m12-1-1) to[out=0,in=180] (mF9);
+\draw[->,dashed,annotate=pulls] (m12-1-1) to[out=0,in=180] (mF10);
+\draw[<-,dashed,annotate=merges] (m8-2-1) to[out=-45,in=180] (m12-1-1);
+\draw[->] (mF10) to node[midway,left]{luatex-fonts-enc.lua} (m13);
+\draw[->] (mF10.-30) to[out=-60,in=50]node[pos=0.3,right]{ luaotfload-auxiliary.lua} (m14.15);
+\draw[->,dashed,annotate=generates from glyphlist.txt] (m12-2-1) to[out=0,in=180] (m13);
+\draw[->,dashed,annotate=generates from Context's char-def.lua] (m12-3-1) to[out=0,in=180] (m14);
+\draw[->,dashed,annotate={{-}{-}update}] (m15) to[out=130,in=-80] ++ (-3.5,4)
+to[out=100,in=-110] ++ (0,2)
+to[out=70,in=-165] (m5);
+\draw[->,annotate=version information] (m15) to[out=-170,in=90] ++(-3.5,-3)
+to[out=-90,in=180] (m17);
+\draw[->] (m15) -- node[midway,right]{-\,-diagnose} (m16);
+\draw[->,annotate=hash files] (m16) -- (m17);
+\draw[<-,dashed,annotate=generates from distribution files] (m17)
+to[out=0,in=-135] ++(5,1) to[out=45,in=0] (m12-4-1);
+\end{scope}
+
+\begin{scope}[shift={([xshift=2cm,yshift=-3cm]current bounding box.north west)},sharp corners]
+\marmot;
+\duck[invisible];
+\node[anchor=south,draw,text width=3cm,shape=rectangle callout,font=\sffamily\scriptsize,align=center]
+at ([yshift=1cm,xshift=-0.5cm]bill)
+{It looks complicated\\ because it is complicated!};
+%
+\end{scope}
+
+\end{tikzpicture}
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/generic/luaotfload/fontloader-2019-08-11.lua b/macros/luatex/generic/luaotfload/fontloader-2019-08-11.lua
new file mode 100644
index 0000000000..b4d3f3ce12
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-2019-08-11.lua
@@ -0,0 +1,34169 @@
+--[[info-----------------------------------------------------------------------
+ Luaotfload fontloader package
+ build 2019-08-13 18:34:34
+-------------------------------------------------------------------------------
+
+ © 2019 PRAGMA ADE / ConTeXt Development Team
+
+ The code in this file is provided under the GPL v2.0 license. See the
+ file COPYING in the Luaotfload repository for details.
+
+ Report bugs to github.com/u-fischer/luaotfload
+
+ This file has been assembled from components taken from Context. See
+ the Luaotfload documentation for details:
+
+ $ texdoc luaotfload
+ $ man 1 luaotfload-tool
+ $ man 5 luaotfload.conf
+
+ Included files:
+
+ · fontloader-data-con.lua
+ · fontloader-basics-nod.lua
+ · fontloader-basics-chr.lua
+ · fontloader-font-ini.lua
+ · fontloader-fonts-mis.lua
+ · fontloader-font-con.lua
+ · fontloader-fonts-enc.lua
+ · fontloader-font-cid.lua
+ · fontloader-font-map.lua
+ · fontloader-font-vfc.lua
+ · fontloader-font-otr.lua
+ · fontloader-font-oti.lua
+ · fontloader-font-ott.lua
+ · fontloader-font-cff.lua
+ · fontloader-font-ttf.lua
+ · fontloader-font-dsp.lua
+ · fontloader-font-oup.lua
+ · fontloader-font-otl.lua
+ · fontloader-font-oto.lua
+ · fontloader-font-otj.lua
+ · fontloader-font-ota.lua
+ · fontloader-font-ots.lua
+ · fontloader-font-osd.lua
+ · fontloader-font-ocl.lua
+ · fontloader-font-otc.lua
+ · fontloader-font-onr.lua
+ · fontloader-font-one.lua
+ · fontloader-font-afk.lua
+ · fontloader-fonts-tfm.lua
+ · fontloader-font-lua.lua
+ · fontloader-font-def.lua
+ · fontloader-fonts-def.lua
+ · fontloader-fonts-ext.lua
+ · fontloader-font-imp-tex.lua
+ · fontloader-font-imp-ligatures.lua
+ · fontloader-font-imp-italics.lua
+ · fontloader-font-imp-effects.lua
+ · fontloader-fonts-lig.lua
+ · fontloader-fonts-gbn.lua
+
+--info]]-----------------------------------------------------------------------
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “data-con†7ce546725b1550f655c78ac9d69419ca] ---
+
+if not modules then modules={} end modules ['data-con']={
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local format,lower,gsub=string.format,string.lower,string.gsub
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
+local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
+containers=containers or {}
+local containers=containers
+containers.usecache=true
+local report_containers=logs.reporter("resolvers","containers")
+local allocated={}
+local mt={
+ __index=function(t,k)
+ if k=="writable" then
+ local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
+ t.writable=writable
+ return writable
+ elseif k=="readables" then
+ local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
+ t.readables=readables
+ return readables
+ end
+ end,
+ __storage__=true
+}
+function containers.define(category,subcategory,version,enabled)
+ if category and subcategory then
+ local c=allocated[category]
+ if not c then
+ c={}
+ allocated[category]=c
+ end
+ local s=c[subcategory]
+ if not s then
+ s={
+ category=category,
+ subcategory=subcategory,
+ storage={},
+ enabled=enabled,
+ version=version or math.pi,
+ trace=false,
+ }
+ setmetatable(s,mt)
+ c[subcategory]=s
+ end
+ return s
+ end
+end
+function containers.is_usable(container,name)
+ return container.enabled and caches and caches.is_writable(container.writable,name)
+end
+function containers.is_valid(container,name)
+ if name and name~="" then
+ local storage=container.storage[name]
+ return storage and storage.cache_version==container.version
+ else
+ return false
+ end
+end
+function containers.read(container,name)
+ local storage=container.storage
+ local stored=storage[name]
+ if not stored and container.enabled and caches and containers.usecache then
+ stored=caches.loaddata(container.readables,name,container.writable)
+ if stored and stored.cache_version==container.version then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","load",container.subcategory,name)
+ end
+ else
+ stored=nil
+ end
+ storage[name]=stored
+ elseif stored then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
+ end
+ end
+ return stored
+end
+function containers.write(container,name,data)
+ if data then
+ data.cache_version=container.version
+ if container.enabled and caches then
+ local unique,shared=data.unique,data.shared
+ data.unique,data.shared=nil,nil
+ caches.savedata(container.writable,name,data)
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","save",container.subcategory,name)
+ end
+ data.unique,data.shared=unique,shared
+ end
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","store",container.subcategory,name)
+ end
+ container.storage[name]=data
+ end
+ return data
+end
+function containers.content(container,name)
+ return container.storage[name]
+end
+function containers.cleanname(name)
+ return (gsub(lower(name),"[^%w\128-\255]+","-"))
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “data-conâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “basics-nod†65064d03c2650a1761ee13ebd9e1400a] ---
+
+if not modules then modules={} end modules ['luatex-fonts-nod']={
+ version=1.001,
+ comment="companion to luatex-fonts.lua",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+ os.exit()
+end
+if tex.attribute[0]~=0 then
+ texio.write_nl("log","!")
+ texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be")
+ texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special")
+ texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.")
+ texio.write_nl("log","!")
+ tex.attribute[0]=0
+end
+attributes=attributes or {}
+attributes.unsetvalue=-0x7FFFFFFF
+local numbers,last={},127
+attributes.private=attributes.private or function(name)
+ local number=numbers[name]
+ if not number then
+ if last<255 then
+ last=last+1
+ end
+ number=last
+ numbers[name]=number
+ end
+ return number
+end
+nodes={}
+nodes.handlers={}
+local nodecodes={}
+local glyphcodes=node.subtypes("glyph")
+local disccodes=node.subtypes("disc")
+for k,v in next,node.types() do
+ v=string.gsub(v,"_","")
+ nodecodes[k]=v
+ nodecodes[v]=k
+end
+for k,v in next,glyphcodes do
+ glyphcodes[v]=k
+end
+for k,v in next,disccodes do
+ disccodes[v]=k
+end
+nodes.nodecodes=nodecodes
+nodes.glyphcodes=glyphcodes
+nodes.disccodes=disccodes
+nodes.handlers.protectglyphs=node.protect_glyphs
+nodes.handlers.unprotectglyphs=node.unprotect_glyphs
+local direct=node.direct
+local nuts={}
+nodes.nuts=nuts
+local tonode=direct.tonode
+local tonut=direct.todirect
+nodes.tonode=tonode
+nodes.tonut=tonut
+nuts.tonode=tonode
+nuts.tonut=tonut
+nuts.getattr=direct.get_attribute
+nuts.getboth=direct.getboth
+nuts.getchar=direct.getchar
+nuts.getcomponents=direct.getcomponents
+nuts.getdirection=direct.getdirection
+nuts.getdisc=direct.getdisc
+nuts.getfield=direct.getfield
+nuts.getfont=direct.getfont
+nuts.getid=direct.getid
+nuts.getkern=direct.getkern
+nuts.getlist=direct.getlist
+nuts.getnext=direct.getnext
+nuts.getoffsets=direct.getoffsets
+nuts.getprev=direct.getprev
+nuts.getsubtype=direct.getsubtype
+nuts.getwidth=direct.getwidth
+nuts.setattr=direct.setfield
+nuts.setboth=direct.setboth
+nuts.setchar=direct.setchar
+nuts.setcomponents=direct.setcomponents
+nuts.setdirection=direct.setdirection
+nuts.setdisc=direct.setdisc
+nuts.setfield=setfield
+nuts.setkern=direct.setkern
+nuts.setlink=direct.setlink
+nuts.setlist=direct.setlist
+nuts.setnext=direct.setnext
+nuts.setoffsets=direct.setoffsets
+nuts.setprev=direct.setprev
+nuts.setsplit=direct.setsplit
+nuts.setsubtype=direct.setsubtype
+nuts.setwidth=direct.setwidth
+nuts.getglyphdata=nuts.getattr
+nuts.setglyphdata=nuts.setattr
+nuts.ischar=direct.is_char
+nuts.isglyph=direct.is_glyph
+nuts.copy=direct.copy
+nuts.copy_list=direct.copy_list
+nuts.copy_node=direct.copy
+nuts.delete=direct.delete
+nuts.end_of_math=direct.end_of_math
+nuts.flush=direct.flush
+nuts.flush_list=direct.flush_list
+nuts.flush_node=direct.flush_node
+nuts.free=direct.free
+nuts.insert_after=direct.insert_after
+nuts.insert_before=direct.insert_before
+nuts.is_node=direct.is_node
+nuts.kerning=direct.kerning
+nuts.ligaturing=direct.ligaturing
+nuts.new=direct.new
+nuts.remove=direct.remove
+nuts.tail=direct.tail
+nuts.traverse=direct.traverse
+nuts.traverse_char=direct.traverse_char
+nuts.traverse_glyph=direct.traverse_glyph
+nuts.traverse_id=direct.traverse_id
+local propertydata=direct.get_properties_table()
+nodes.properties={ data=propertydata }
+if direct.set_properties_mode then
+ direct.set_properties_mode(true,true)
+ function direct.set_properties_mode() end
+end
+nuts.getprop=function(n,k)
+ local p=propertydata[n]
+ if p then
+ return p[k]
+ end
+end
+nuts.setprop=function(n,k,v)
+ if v then
+ local p=propertydata[n]
+ if p then
+ p[k]=v
+ else
+ propertydata[n]={ [k]=v }
+ end
+ end
+end
+nodes.setprop=nodes.setproperty
+nodes.getprop=nodes.getproperty
+local setprev=nuts.setprev
+local setnext=nuts.setnext
+local getnext=nuts.getnext
+local setlink=nuts.setlink
+local getfield=nuts.getfield
+local setfield=nuts.setfield
+local getcomponents=nuts.getcomponents
+local setcomponents=nuts.setcomponents
+local find_tail=nuts.tail
+local flush_list=nuts.flush_list
+local flush_node=nuts.flush_node
+local traverse_id=nuts.traverse_id
+local copy_node=nuts.copy_node
+local glyph_code=nodes.nodecodes.glyph
+function nuts.copy_no_components(g,copyinjection)
+ local components=getcomponents(g)
+ if components then
+ setcomponents(g)
+ local n=copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ setcomponents(g,components)
+ return n
+ else
+ local n=copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ return n
+ end
+end
+function nuts.copy_only_glyphs(current)
+ local head=nil
+ local previous=nil
+ for n in traverse_id(glyph_code,current) do
+ n=copy_node(n)
+ if head then
+ setlink(previous,n)
+ else
+ head=n
+ end
+ previous=n
+ end
+ return head
+end
+nuts.uses_font=direct.uses_font
+do
+ local dummy=tonut(node.new("glyph"))
+ nuts.traversers={
+ glyph=nuts.traverse_id(nodecodes.glyph,dummy),
+ glue=nuts.traverse_id(nodecodes.glue,dummy),
+ disc=nuts.traverse_id(nodecodes.disc,dummy),
+ boundary=nuts.traverse_id(nodecodes.boundary,dummy),
+ char=nuts.traverse_char(dummy),
+ node=nuts.traverse(dummy),
+ }
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “basics-nodâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “basics-chr†58b7ef0c486e06090b362971b9f85e27] ---
+
+
+characters=characters or {}
+characters.blockrange={}
+characters.classifiers={
+ [768]=5,
+ [769]=5,
+ [770]=5,
+ [771]=5,
+ [772]=5,
+ [773]=5,
+ [774]=5,
+ [775]=5,
+ [776]=5,
+ [777]=5,
+ [778]=5,
+ [779]=5,
+ [780]=5,
+ [781]=5,
+ [782]=5,
+ [783]=5,
+ [784]=5,
+ [785]=5,
+ [786]=5,
+ [787]=5,
+ [788]=5,
+ [789]=5,
+ [790]=5,
+ [791]=5,
+ [792]=5,
+ [793]=5,
+ [794]=5,
+ [795]=5,
+ [796]=5,
+ [797]=5,
+ [798]=5,
+ [799]=5,
+ [800]=5,
+ [801]=5,
+ [802]=5,
+ [803]=5,
+ [804]=5,
+ [805]=5,
+ [806]=5,
+ [807]=5,
+ [808]=5,
+ [809]=5,
+ [810]=5,
+ [811]=5,
+ [812]=5,
+ [813]=5,
+ [814]=5,
+ [815]=5,
+ [816]=5,
+ [817]=5,
+ [818]=5,
+ [819]=5,
+ [820]=5,
+ [821]=5,
+ [822]=5,
+ [823]=5,
+ [824]=5,
+ [825]=5,
+ [826]=5,
+ [827]=5,
+ [828]=5,
+ [829]=5,
+ [830]=5,
+ [831]=5,
+ [832]=5,
+ [833]=5,
+ [834]=5,
+ [835]=5,
+ [836]=5,
+ [837]=5,
+ [838]=5,
+ [839]=5,
+ [840]=5,
+ [841]=5,
+ [842]=5,
+ [843]=5,
+ [844]=5,
+ [845]=5,
+ [846]=5,
+ [847]=5,
+ [848]=5,
+ [849]=5,
+ [850]=5,
+ [851]=5,
+ [852]=5,
+ [853]=5,
+ [854]=5,
+ [855]=5,
+ [856]=5,
+ [857]=5,
+ [858]=5,
+ [859]=5,
+ [860]=5,
+ [861]=5,
+ [862]=5,
+ [863]=5,
+ [864]=5,
+ [865]=5,
+ [866]=5,
+ [867]=5,
+ [868]=5,
+ [869]=5,
+ [870]=5,
+ [871]=5,
+ [872]=5,
+ [873]=5,
+ [874]=5,
+ [875]=5,
+ [876]=5,
+ [877]=5,
+ [878]=5,
+ [879]=5,
+ [1155]=5,
+ [1156]=5,
+ [1157]=5,
+ [1158]=5,
+ [1159]=5,
+ [1425]=5,
+ [1426]=5,
+ [1427]=5,
+ [1428]=5,
+ [1429]=5,
+ [1430]=5,
+ [1431]=5,
+ [1432]=5,
+ [1433]=5,
+ [1434]=5,
+ [1435]=5,
+ [1436]=5,
+ [1437]=5,
+ [1438]=5,
+ [1439]=5,
+ [1440]=5,
+ [1441]=5,
+ [1442]=5,
+ [1443]=5,
+ [1444]=5,
+ [1445]=5,
+ [1446]=5,
+ [1447]=5,
+ [1448]=5,
+ [1449]=5,
+ [1450]=5,
+ [1451]=5,
+ [1452]=5,
+ [1453]=5,
+ [1454]=5,
+ [1455]=5,
+ [1456]=5,
+ [1457]=5,
+ [1458]=5,
+ [1459]=5,
+ [1460]=5,
+ [1461]=5,
+ [1462]=5,
+ [1463]=5,
+ [1464]=5,
+ [1465]=5,
+ [1466]=5,
+ [1467]=5,
+ [1468]=5,
+ [1469]=5,
+ [1471]=5,
+ [1473]=5,
+ [1474]=5,
+ [1476]=5,
+ [1477]=5,
+ [1479]=5,
+ [1536]=4,
+ [1537]=4,
+ [1538]=4,
+ [1539]=4,
+ [1540]=4,
+ [1541]=4,
+ [1542]=6,
+ [1543]=6,
+ [1544]=4,
+ [1545]=6,
+ [1546]=6,
+ [1547]=4,
+ [1548]=6,
+ [1549]=6,
+ [1550]=6,
+ [1551]=6,
+ [1552]=5,
+ [1553]=5,
+ [1554]=5,
+ [1555]=5,
+ [1556]=5,
+ [1557]=5,
+ [1558]=5,
+ [1559]=5,
+ [1560]=5,
+ [1561]=5,
+ [1562]=5,
+ [1563]=6,
+ [1564]=6,
+ [1566]=6,
+ [1567]=6,
+ [1568]=2,
+ [1569]=4,
+ [1570]=3,
+ [1571]=3,
+ [1572]=3,
+ [1573]=3,
+ [1574]=2,
+ [1575]=3,
+ [1576]=2,
+ [1577]=3,
+ [1578]=2,
+ [1579]=2,
+ [1580]=2,
+ [1581]=2,
+ [1582]=2,
+ [1583]=3,
+ [1584]=3,
+ [1585]=3,
+ [1586]=3,
+ [1587]=2,
+ [1588]=2,
+ [1589]=2,
+ [1590]=2,
+ [1591]=2,
+ [1592]=2,
+ [1593]=2,
+ [1594]=2,
+ [1595]=2,
+ [1596]=2,
+ [1597]=2,
+ [1598]=2,
+ [1599]=2,
+ [1600]=2,
+ [1601]=2,
+ [1602]=2,
+ [1603]=2,
+ [1604]=2,
+ [1605]=2,
+ [1606]=2,
+ [1607]=2,
+ [1608]=3,
+ [1609]=2,
+ [1610]=2,
+ [1611]=5,
+ [1612]=5,
+ [1613]=5,
+ [1614]=5,
+ [1615]=5,
+ [1616]=5,
+ [1617]=5,
+ [1618]=5,
+ [1619]=5,
+ [1620]=5,
+ [1621]=5,
+ [1622]=5,
+ [1623]=5,
+ [1624]=5,
+ [1625]=5,
+ [1626]=5,
+ [1627]=5,
+ [1628]=5,
+ [1629]=5,
+ [1630]=5,
+ [1631]=5,
+ [1632]=6,
+ [1633]=6,
+ [1634]=6,
+ [1635]=6,
+ [1636]=6,
+ [1637]=6,
+ [1638]=6,
+ [1639]=6,
+ [1640]=6,
+ [1641]=6,
+ [1642]=6,
+ [1643]=6,
+ [1644]=6,
+ [1645]=6,
+ [1646]=2,
+ [1647]=2,
+ [1648]=5,
+ [1649]=3,
+ [1650]=3,
+ [1651]=3,
+ [1652]=4,
+ [1653]=3,
+ [1654]=3,
+ [1655]=3,
+ [1656]=2,
+ [1657]=2,
+ [1658]=2,
+ [1659]=2,
+ [1660]=2,
+ [1661]=2,
+ [1662]=2,
+ [1663]=2,
+ [1664]=2,
+ [1665]=2,
+ [1666]=2,
+ [1667]=2,
+ [1668]=2,
+ [1669]=2,
+ [1670]=2,
+ [1671]=2,
+ [1672]=3,
+ [1673]=3,
+ [1674]=3,
+ [1675]=3,
+ [1676]=3,
+ [1677]=3,
+ [1678]=3,
+ [1679]=3,
+ [1680]=3,
+ [1681]=3,
+ [1682]=3,
+ [1683]=3,
+ [1684]=3,
+ [1685]=3,
+ [1686]=3,
+ [1687]=3,
+ [1688]=3,
+ [1689]=3,
+ [1690]=2,
+ [1691]=2,
+ [1692]=2,
+ [1693]=2,
+ [1694]=2,
+ [1695]=2,
+ [1696]=2,
+ [1697]=2,
+ [1698]=2,
+ [1699]=2,
+ [1700]=2,
+ [1701]=2,
+ [1702]=2,
+ [1703]=2,
+ [1704]=2,
+ [1705]=2,
+ [1706]=2,
+ [1707]=2,
+ [1708]=2,
+ [1709]=2,
+ [1710]=2,
+ [1711]=2,
+ [1712]=2,
+ [1713]=2,
+ [1714]=2,
+ [1715]=2,
+ [1716]=2,
+ [1717]=2,
+ [1718]=2,
+ [1719]=2,
+ [1720]=2,
+ [1721]=2,
+ [1722]=2,
+ [1723]=2,
+ [1724]=2,
+ [1725]=2,
+ [1726]=2,
+ [1727]=2,
+ [1728]=3,
+ [1729]=2,
+ [1730]=2,
+ [1731]=3,
+ [1732]=3,
+ [1733]=3,
+ [1734]=3,
+ [1735]=3,
+ [1736]=3,
+ [1737]=3,
+ [1738]=3,
+ [1739]=3,
+ [1740]=2,
+ [1741]=3,
+ [1742]=2,
+ [1743]=3,
+ [1744]=2,
+ [1745]=2,
+ [1746]=3,
+ [1747]=3,
+ [1748]=6,
+ [1749]=3,
+ [1750]=5,
+ [1751]=5,
+ [1752]=5,
+ [1753]=5,
+ [1754]=5,
+ [1755]=5,
+ [1756]=5,
+ [1757]=4,
+ [1758]=6,
+ [1759]=5,
+ [1760]=5,
+ [1761]=5,
+ [1762]=5,
+ [1763]=5,
+ [1764]=5,
+ [1765]=6,
+ [1766]=6,
+ [1767]=5,
+ [1768]=5,
+ [1769]=6,
+ [1770]=5,
+ [1771]=5,
+ [1772]=5,
+ [1773]=5,
+ [1774]=3,
+ [1775]=3,
+ [1776]=6,
+ [1777]=6,
+ [1778]=6,
+ [1779]=6,
+ [1780]=6,
+ [1781]=6,
+ [1782]=6,
+ [1783]=6,
+ [1784]=6,
+ [1785]=6,
+ [1786]=2,
+ [1787]=2,
+ [1788]=2,
+ [1789]=6,
+ [1790]=6,
+ [1791]=2,
+ [1792]=6,
+ [1793]=6,
+ [1794]=6,
+ [1795]=6,
+ [1796]=6,
+ [1797]=6,
+ [1798]=6,
+ [1799]=6,
+ [1800]=6,
+ [1801]=6,
+ [1802]=6,
+ [1803]=6,
+ [1804]=6,
+ [1805]=6,
+ [1808]=3,
+ [1809]=5,
+ [1810]=2,
+ [1811]=2,
+ [1812]=2,
+ [1813]=3,
+ [1814]=3,
+ [1815]=3,
+ [1816]=3,
+ [1817]=3,
+ [1818]=2,
+ [1819]=2,
+ [1820]=2,
+ [1821]=2,
+ [1822]=3,
+ [1823]=2,
+ [1824]=2,
+ [1825]=2,
+ [1826]=2,
+ [1827]=2,
+ [1828]=2,
+ [1829]=2,
+ [1830]=2,
+ [1831]=2,
+ [1832]=3,
+ [1833]=2,
+ [1834]=3,
+ [1835]=2,
+ [1836]=3,
+ [1837]=2,
+ [1838]=2,
+ [1839]=3,
+ [1840]=5,
+ [1841]=5,
+ [1842]=5,
+ [1843]=5,
+ [1844]=5,
+ [1845]=5,
+ [1846]=5,
+ [1847]=5,
+ [1848]=5,
+ [1849]=5,
+ [1850]=5,
+ [1851]=5,
+ [1852]=5,
+ [1853]=5,
+ [1854]=5,
+ [1855]=5,
+ [1856]=5,
+ [1857]=5,
+ [1858]=5,
+ [1859]=5,
+ [1860]=5,
+ [1861]=5,
+ [1862]=5,
+ [1863]=5,
+ [1864]=5,
+ [1865]=5,
+ [1866]=5,
+ [1869]=3,
+ [1870]=2,
+ [1871]=2,
+ [1872]=2,
+ [1873]=2,
+ [1874]=2,
+ [1875]=2,
+ [1876]=2,
+ [1877]=2,
+ [1878]=2,
+ [1879]=2,
+ [1880]=2,
+ [1881]=3,
+ [1882]=3,
+ [1883]=3,
+ [1884]=2,
+ [1885]=2,
+ [1886]=2,
+ [1887]=2,
+ [1888]=2,
+ [1889]=2,
+ [1890]=2,
+ [1891]=2,
+ [1892]=2,
+ [1893]=2,
+ [1894]=2,
+ [1895]=2,
+ [1896]=2,
+ [1897]=2,
+ [1898]=2,
+ [1899]=3,
+ [1900]=3,
+ [1901]=2,
+ [1902]=2,
+ [1903]=2,
+ [1904]=2,
+ [1905]=3,
+ [1906]=2,
+ [1907]=3,
+ [1908]=3,
+ [1909]=2,
+ [1910]=2,
+ [1911]=2,
+ [1912]=3,
+ [1913]=3,
+ [1914]=2,
+ [1915]=2,
+ [1916]=2,
+ [1917]=2,
+ [1918]=2,
+ [1919]=2,
+ [1958]=5,
+ [1959]=5,
+ [1960]=5,
+ [1961]=5,
+ [1962]=5,
+ [1963]=5,
+ [1964]=5,
+ [1965]=5,
+ [1966]=5,
+ [1967]=5,
+ [1968]=5,
+ [1984]=6,
+ [1985]=6,
+ [1986]=6,
+ [1987]=6,
+ [1988]=6,
+ [1989]=6,
+ [1990]=6,
+ [1991]=6,
+ [1992]=6,
+ [1993]=6,
+ [1994]=2,
+ [1995]=2,
+ [1996]=2,
+ [1997]=2,
+ [1998]=2,
+ [1999]=2,
+ [2000]=2,
+ [2001]=2,
+ [2002]=2,
+ [2003]=2,
+ [2004]=2,
+ [2005]=2,
+ [2006]=2,
+ [2007]=2,
+ [2008]=2,
+ [2009]=2,
+ [2010]=2,
+ [2011]=2,
+ [2012]=2,
+ [2013]=2,
+ [2014]=2,
+ [2015]=2,
+ [2016]=2,
+ [2017]=2,
+ [2018]=2,
+ [2019]=2,
+ [2020]=2,
+ [2021]=2,
+ [2022]=2,
+ [2023]=2,
+ [2024]=2,
+ [2025]=2,
+ [2026]=2,
+ [2027]=5,
+ [2028]=5,
+ [2029]=5,
+ [2030]=5,
+ [2031]=5,
+ [2032]=5,
+ [2033]=5,
+ [2034]=5,
+ [2035]=5,
+ [2036]=6,
+ [2037]=6,
+ [2038]=6,
+ [2039]=6,
+ [2040]=6,
+ [2041]=6,
+ [2042]=2,
+ [2045]=5,
+ [2046]=6,
+ [2047]=6,
+ [2070]=5,
+ [2071]=5,
+ [2072]=5,
+ [2073]=5,
+ [2075]=5,
+ [2076]=5,
+ [2077]=5,
+ [2078]=5,
+ [2079]=5,
+ [2080]=5,
+ [2081]=5,
+ [2082]=5,
+ [2083]=5,
+ [2085]=5,
+ [2086]=5,
+ [2087]=5,
+ [2089]=5,
+ [2090]=5,
+ [2091]=5,
+ [2092]=5,
+ [2093]=5,
+ [2112]=3,
+ [2113]=2,
+ [2114]=2,
+ [2115]=2,
+ [2116]=2,
+ [2117]=2,
+ [2118]=3,
+ [2119]=3,
+ [2120]=2,
+ [2121]=3,
+ [2122]=2,
+ [2123]=2,
+ [2124]=2,
+ [2125]=2,
+ [2126]=2,
+ [2127]=2,
+ [2128]=2,
+ [2129]=2,
+ [2130]=2,
+ [2131]=2,
+ [2132]=3,
+ [2133]=2,
+ [2134]=4,
+ [2135]=4,
+ [2136]=4,
+ [2137]=5,
+ [2138]=5,
+ [2139]=5,
+ [2144]=2,
+ [2145]=4,
+ [2146]=2,
+ [2147]=2,
+ [2148]=2,
+ [2149]=2,
+ [2150]=4,
+ [2151]=3,
+ [2152]=2,
+ [2153]=3,
+ [2154]=3,
+ [2208]=2,
+ [2209]=2,
+ [2210]=2,
+ [2211]=2,
+ [2212]=2,
+ [2213]=2,
+ [2214]=2,
+ [2215]=2,
+ [2216]=2,
+ [2217]=2,
+ [2218]=3,
+ [2219]=3,
+ [2220]=3,
+ [2221]=4,
+ [2222]=3,
+ [2223]=2,
+ [2224]=2,
+ [2225]=3,
+ [2226]=3,
+ [2227]=2,
+ [2228]=2,
+ [2230]=2,
+ [2231]=2,
+ [2232]=2,
+ [2233]=3,
+ [2234]=2,
+ [2235]=2,
+ [2236]=2,
+ [2237]=2,
+ [2259]=5,
+ [2260]=5,
+ [2261]=5,
+ [2262]=5,
+ [2263]=5,
+ [2264]=5,
+ [2265]=5,
+ [2266]=5,
+ [2267]=5,
+ [2268]=5,
+ [2269]=5,
+ [2270]=5,
+ [2271]=5,
+ [2272]=5,
+ [2273]=5,
+ [2274]=4,
+ [2275]=5,
+ [2276]=5,
+ [2277]=5,
+ [2278]=5,
+ [2279]=5,
+ [2280]=5,
+ [2281]=5,
+ [2282]=5,
+ [2283]=5,
+ [2284]=5,
+ [2285]=5,
+ [2286]=5,
+ [2287]=5,
+ [2288]=5,
+ [2289]=5,
+ [2290]=5,
+ [2291]=5,
+ [2292]=5,
+ [2293]=5,
+ [2294]=5,
+ [2295]=5,
+ [2296]=5,
+ [2297]=5,
+ [2298]=5,
+ [2299]=5,
+ [2300]=5,
+ [2301]=5,
+ [2302]=5,
+ [2303]=5,
+ [2304]=5,
+ [2305]=5,
+ [2306]=5,
+ [2362]=5,
+ [2364]=5,
+ [2369]=5,
+ [2370]=5,
+ [2371]=5,
+ [2372]=5,
+ [2373]=5,
+ [2374]=5,
+ [2375]=5,
+ [2376]=5,
+ [2381]=5,
+ [2385]=5,
+ [2386]=5,
+ [2387]=5,
+ [2388]=5,
+ [2389]=5,
+ [2390]=5,
+ [2391]=5,
+ [2402]=5,
+ [2403]=5,
+ [2433]=5,
+ [2492]=5,
+ [2497]=5,
+ [2498]=5,
+ [2499]=5,
+ [2500]=5,
+ [2509]=5,
+ [2530]=5,
+ [2531]=5,
+ [2558]=5,
+ [2561]=5,
+ [2562]=5,
+ [2620]=5,
+ [2625]=5,
+ [2626]=5,
+ [2631]=5,
+ [2632]=5,
+ [2635]=5,
+ [2636]=5,
+ [2637]=5,
+ [2641]=5,
+ [2672]=5,
+ [2673]=5,
+ [2677]=5,
+ [2689]=5,
+ [2690]=5,
+ [2748]=5,
+ [2753]=5,
+ [2754]=5,
+ [2755]=5,
+ [2756]=5,
+ [2757]=5,
+ [2759]=5,
+ [2760]=5,
+ [2765]=5,
+ [2786]=5,
+ [2787]=5,
+ [2810]=5,
+ [2811]=5,
+ [2812]=5,
+ [2813]=5,
+ [2814]=5,
+ [2815]=5,
+ [2817]=5,
+ [2876]=5,
+ [2879]=5,
+ [2881]=5,
+ [2882]=5,
+ [2883]=5,
+ [2884]=5,
+ [2893]=5,
+ [2902]=5,
+ [2914]=5,
+ [2915]=5,
+ [2946]=5,
+ [3008]=5,
+ [3021]=5,
+ [3072]=5,
+ [3076]=5,
+ [3134]=5,
+ [3135]=5,
+ [3136]=5,
+ [3142]=5,
+ [3143]=5,
+ [3144]=5,
+ [3146]=5,
+ [3147]=5,
+ [3148]=5,
+ [3149]=5,
+ [3157]=5,
+ [3158]=5,
+ [3170]=5,
+ [3171]=5,
+ [3201]=5,
+ [3260]=5,
+ [3263]=5,
+ [3270]=5,
+ [3276]=5,
+ [3277]=5,
+ [3298]=5,
+ [3299]=5,
+ [3328]=5,
+ [3329]=5,
+ [3387]=5,
+ [3388]=5,
+ [3393]=5,
+ [3394]=5,
+ [3395]=5,
+ [3396]=5,
+ [3405]=5,
+ [3426]=5,
+ [3427]=5,
+ [3530]=5,
+ [3538]=5,
+ [3539]=5,
+ [3540]=5,
+ [3542]=5,
+ [3633]=5,
+ [3636]=5,
+ [3637]=5,
+ [3638]=5,
+ [3639]=5,
+ [3640]=5,
+ [3641]=5,
+ [3642]=5,
+ [3655]=5,
+ [3656]=5,
+ [3657]=5,
+ [3658]=5,
+ [3659]=5,
+ [3660]=5,
+ [3661]=5,
+ [3662]=5,
+ [3761]=5,
+ [3764]=5,
+ [3765]=5,
+ [3766]=5,
+ [3767]=5,
+ [3768]=5,
+ [3769]=5,
+ [3770]=5,
+ [3771]=5,
+ [3772]=5,
+ [3784]=5,
+ [3785]=5,
+ [3786]=5,
+ [3787]=5,
+ [3788]=5,
+ [3789]=5,
+ [3864]=5,
+ [3865]=5,
+ [3893]=5,
+ [3895]=5,
+ [3897]=5,
+ [3953]=5,
+ [3954]=5,
+ [3955]=5,
+ [3956]=5,
+ [3957]=5,
+ [3958]=5,
+ [3959]=5,
+ [3960]=5,
+ [3961]=5,
+ [3962]=5,
+ [3963]=5,
+ [3964]=5,
+ [3965]=5,
+ [3966]=5,
+ [3968]=5,
+ [3969]=5,
+ [3970]=5,
+ [3971]=5,
+ [3972]=5,
+ [3974]=5,
+ [3975]=5,
+ [3981]=5,
+ [3982]=5,
+ [3983]=5,
+ [3984]=5,
+ [3985]=5,
+ [3986]=5,
+ [3987]=5,
+ [3988]=5,
+ [3989]=5,
+ [3990]=5,
+ [3991]=5,
+ [3993]=5,
+ [3994]=5,
+ [3995]=5,
+ [3996]=5,
+ [3997]=5,
+ [3998]=5,
+ [3999]=5,
+ [4000]=5,
+ [4001]=5,
+ [4002]=5,
+ [4003]=5,
+ [4004]=5,
+ [4005]=5,
+ [4006]=5,
+ [4007]=5,
+ [4008]=5,
+ [4009]=5,
+ [4010]=5,
+ [4011]=5,
+ [4012]=5,
+ [4013]=5,
+ [4014]=5,
+ [4015]=5,
+ [4016]=5,
+ [4017]=5,
+ [4018]=5,
+ [4019]=5,
+ [4020]=5,
+ [4021]=5,
+ [4022]=5,
+ [4023]=5,
+ [4024]=5,
+ [4025]=5,
+ [4026]=5,
+ [4027]=5,
+ [4028]=5,
+ [4038]=5,
+ [4141]=5,
+ [4142]=5,
+ [4143]=5,
+ [4144]=5,
+ [4146]=5,
+ [4147]=5,
+ [4148]=5,
+ [4149]=5,
+ [4150]=5,
+ [4151]=5,
+ [4153]=5,
+ [4154]=5,
+ [4157]=5,
+ [4158]=5,
+ [4184]=5,
+ [4185]=5,
+ [4190]=5,
+ [4191]=5,
+ [4192]=5,
+ [4209]=5,
+ [4210]=5,
+ [4211]=5,
+ [4212]=5,
+ [4226]=5,
+ [4229]=5,
+ [4230]=5,
+ [4237]=5,
+ [4253]=5,
+ [4957]=5,
+ [4958]=5,
+ [4959]=5,
+ [5906]=5,
+ [5907]=5,
+ [5908]=5,
+ [5938]=5,
+ [5939]=5,
+ [5940]=5,
+ [5970]=5,
+ [5971]=5,
+ [6002]=5,
+ [6003]=5,
+ [6071]=5,
+ [6072]=5,
+ [6073]=5,
+ [6074]=5,
+ [6075]=5,
+ [6076]=5,
+ [6077]=5,
+ [6086]=5,
+ [6089]=5,
+ [6090]=5,
+ [6091]=5,
+ [6092]=5,
+ [6093]=5,
+ [6094]=5,
+ [6095]=5,
+ [6096]=5,
+ [6097]=5,
+ [6098]=5,
+ [6099]=5,
+ [6109]=5,
+ [6150]=4,
+ [6151]=2,
+ [6154]=2,
+ [6155]=5,
+ [6156]=5,
+ [6157]=5,
+ [6158]=4,
+ [6176]=2,
+ [6177]=2,
+ [6178]=2,
+ [6179]=2,
+ [6180]=2,
+ [6181]=2,
+ [6182]=2,
+ [6183]=2,
+ [6184]=2,
+ [6185]=2,
+ [6186]=2,
+ [6187]=2,
+ [6188]=2,
+ [6189]=2,
+ [6190]=2,
+ [6191]=2,
+ [6192]=2,
+ [6193]=2,
+ [6194]=2,
+ [6195]=2,
+ [6196]=2,
+ [6197]=2,
+ [6198]=2,
+ [6199]=2,
+ [6200]=2,
+ [6201]=2,
+ [6202]=2,
+ [6203]=2,
+ [6204]=2,
+ [6205]=2,
+ [6206]=2,
+ [6207]=2,
+ [6208]=2,
+ [6209]=2,
+ [6210]=2,
+ [6211]=2,
+ [6212]=2,
+ [6213]=2,
+ [6214]=2,
+ [6215]=2,
+ [6216]=2,
+ [6217]=2,
+ [6218]=2,
+ [6219]=2,
+ [6220]=2,
+ [6221]=2,
+ [6222]=2,
+ [6223]=2,
+ [6224]=2,
+ [6225]=2,
+ [6226]=2,
+ [6227]=2,
+ [6228]=2,
+ [6229]=2,
+ [6230]=2,
+ [6231]=2,
+ [6232]=2,
+ [6233]=2,
+ [6234]=2,
+ [6235]=2,
+ [6236]=2,
+ [6237]=2,
+ [6238]=2,
+ [6239]=2,
+ [6240]=2,
+ [6241]=2,
+ [6242]=2,
+ [6243]=2,
+ [6244]=2,
+ [6245]=2,
+ [6246]=2,
+ [6247]=2,
+ [6248]=2,
+ [6249]=2,
+ [6250]=2,
+ [6251]=2,
+ [6252]=2,
+ [6253]=2,
+ [6254]=2,
+ [6255]=2,
+ [6256]=2,
+ [6257]=2,
+ [6258]=2,
+ [6259]=2,
+ [6260]=2,
+ [6261]=2,
+ [6262]=2,
+ [6263]=2,
+ [6264]=2,
+ [6272]=4,
+ [6273]=4,
+ [6274]=4,
+ [6275]=4,
+ [6276]=4,
+ [6279]=2,
+ [6280]=2,
+ [6281]=2,
+ [6282]=2,
+ [6283]=2,
+ [6284]=2,
+ [6285]=2,
+ [6286]=2,
+ [6287]=2,
+ [6288]=2,
+ [6289]=2,
+ [6290]=2,
+ [6291]=2,
+ [6292]=2,
+ [6293]=2,
+ [6294]=2,
+ [6295]=2,
+ [6296]=2,
+ [6297]=2,
+ [6298]=2,
+ [6299]=2,
+ [6300]=2,
+ [6301]=2,
+ [6302]=2,
+ [6303]=2,
+ [6304]=2,
+ [6305]=2,
+ [6306]=2,
+ [6307]=2,
+ [6308]=2,
+ [6309]=2,
+ [6310]=2,
+ [6311]=2,
+ [6312]=2,
+ [6313]=5,
+ [6314]=2,
+ [6432]=5,
+ [6433]=5,
+ [6434]=5,
+ [6439]=5,
+ [6440]=5,
+ [6450]=5,
+ [6457]=5,
+ [6458]=5,
+ [6459]=5,
+ [6679]=5,
+ [6680]=5,
+ [6742]=5,
+ [6744]=5,
+ [6745]=5,
+ [6746]=5,
+ [6747]=5,
+ [6748]=5,
+ [6749]=5,
+ [6750]=5,
+ [6752]=5,
+ [6754]=5,
+ [6757]=5,
+ [6758]=5,
+ [6759]=5,
+ [6760]=5,
+ [6761]=5,
+ [6762]=5,
+ [6763]=5,
+ [6764]=5,
+ [6771]=5,
+ [6772]=5,
+ [6773]=5,
+ [6774]=5,
+ [6775]=5,
+ [6776]=5,
+ [6777]=5,
+ [6778]=5,
+ [6779]=5,
+ [6780]=5,
+ [6783]=5,
+ [6832]=5,
+ [6833]=5,
+ [6834]=5,
+ [6835]=5,
+ [6836]=5,
+ [6837]=5,
+ [6838]=5,
+ [6839]=5,
+ [6840]=5,
+ [6841]=5,
+ [6842]=5,
+ [6843]=5,
+ [6844]=5,
+ [6845]=5,
+ [6912]=5,
+ [6913]=5,
+ [6914]=5,
+ [6915]=5,
+ [6964]=5,
+ [6966]=5,
+ [6967]=5,
+ [6968]=5,
+ [6969]=5,
+ [6970]=5,
+ [6972]=5,
+ [6978]=5,
+ [7019]=5,
+ [7020]=5,
+ [7021]=5,
+ [7022]=5,
+ [7023]=5,
+ [7024]=5,
+ [7025]=5,
+ [7026]=5,
+ [7027]=5,
+ [7040]=5,
+ [7041]=5,
+ [7074]=5,
+ [7075]=5,
+ [7076]=5,
+ [7077]=5,
+ [7080]=5,
+ [7081]=5,
+ [7083]=5,
+ [7142]=5,
+ [7144]=5,
+ [7145]=5,
+ [7149]=5,
+ [7151]=5,
+ [7152]=5,
+ [7153]=5,
+ [7212]=5,
+ [7213]=5,
+ [7214]=5,
+ [7215]=5,
+ [7216]=5,
+ [7217]=5,
+ [7218]=5,
+ [7219]=5,
+ [7222]=5,
+ [7223]=5,
+ [7376]=5,
+ [7377]=5,
+ [7378]=5,
+ [7380]=5,
+ [7381]=5,
+ [7382]=5,
+ [7383]=5,
+ [7384]=5,
+ [7385]=5,
+ [7386]=5,
+ [7387]=5,
+ [7388]=5,
+ [7389]=5,
+ [7390]=5,
+ [7391]=5,
+ [7392]=5,
+ [7394]=5,
+ [7395]=5,
+ [7396]=5,
+ [7397]=5,
+ [7398]=5,
+ [7399]=5,
+ [7400]=5,
+ [7405]=5,
+ [7412]=5,
+ [7416]=5,
+ [7417]=5,
+ [7616]=5,
+ [7617]=5,
+ [7618]=5,
+ [7619]=5,
+ [7620]=5,
+ [7621]=5,
+ [7622]=5,
+ [7623]=5,
+ [7624]=5,
+ [7625]=5,
+ [7626]=5,
+ [7627]=5,
+ [7628]=5,
+ [7629]=5,
+ [7630]=5,
+ [7631]=5,
+ [7632]=5,
+ [7633]=5,
+ [7634]=5,
+ [7635]=5,
+ [7636]=5,
+ [7637]=5,
+ [7638]=5,
+ [7639]=5,
+ [7640]=5,
+ [7641]=5,
+ [7642]=5,
+ [7643]=5,
+ [7644]=5,
+ [7645]=5,
+ [7646]=5,
+ [7647]=5,
+ [7648]=5,
+ [7649]=5,
+ [7650]=5,
+ [7651]=5,
+ [7652]=5,
+ [7653]=5,
+ [7654]=5,
+ [7655]=5,
+ [7656]=5,
+ [7657]=5,
+ [7658]=5,
+ [7659]=5,
+ [7660]=5,
+ [7661]=5,
+ [7662]=5,
+ [7663]=5,
+ [7664]=5,
+ [7665]=5,
+ [7666]=5,
+ [7667]=5,
+ [7668]=5,
+ [7669]=5,
+ [7670]=5,
+ [7671]=5,
+ [7672]=5,
+ [7673]=5,
+ [7675]=5,
+ [7676]=5,
+ [7677]=5,
+ [7678]=5,
+ [7679]=5,
+ [8204]=4,
+ [8205]=2,
+ [8239]=4,
+ [8294]=4,
+ [8295]=4,
+ [8296]=4,
+ [8297]=4,
+ [8400]=5,
+ [8401]=5,
+ [8402]=5,
+ [8403]=5,
+ [8404]=5,
+ [8405]=5,
+ [8406]=5,
+ [8407]=5,
+ [8408]=5,
+ [8409]=5,
+ [8410]=5,
+ [8411]=5,
+ [8412]=5,
+ [8417]=5,
+ [8421]=5,
+ [8422]=5,
+ [8423]=5,
+ [8424]=5,
+ [8425]=5,
+ [8426]=5,
+ [8427]=5,
+ [8428]=5,
+ [8429]=5,
+ [8430]=5,
+ [8431]=5,
+ [8432]=5,
+ [11503]=5,
+ [11504]=5,
+ [11505]=5,
+ [11647]=5,
+ [11744]=5,
+ [11745]=5,
+ [11746]=5,
+ [11747]=5,
+ [11748]=5,
+ [11749]=5,
+ [11750]=5,
+ [11751]=5,
+ [11752]=5,
+ [11753]=5,
+ [11754]=5,
+ [11755]=5,
+ [11756]=5,
+ [11757]=5,
+ [11758]=5,
+ [11759]=5,
+ [11760]=5,
+ [11761]=5,
+ [11762]=5,
+ [11763]=5,
+ [11764]=5,
+ [11765]=5,
+ [11766]=5,
+ [11767]=5,
+ [11768]=5,
+ [11769]=5,
+ [11770]=5,
+ [11771]=5,
+ [11772]=5,
+ [11773]=5,
+ [11774]=5,
+ [11775]=5,
+ [12330]=5,
+ [12331]=5,
+ [12332]=5,
+ [12333]=5,
+ [12334]=5,
+ [12335]=5,
+ [12441]=5,
+ [12442]=5,
+ [42607]=5,
+ [42612]=5,
+ [42613]=5,
+ [42614]=5,
+ [42615]=5,
+ [42616]=5,
+ [42617]=5,
+ [42618]=5,
+ [42619]=5,
+ [42620]=5,
+ [42621]=5,
+ [42654]=5,
+ [42655]=5,
+ [42736]=5,
+ [42737]=5,
+ [43014]=5,
+ [43019]=5,
+ [43045]=5,
+ [43046]=5,
+ [43072]=2,
+ [43073]=2,
+ [43074]=2,
+ [43075]=2,
+ [43076]=2,
+ [43077]=2,
+ [43078]=2,
+ [43079]=2,
+ [43080]=2,
+ [43081]=2,
+ [43082]=2,
+ [43083]=2,
+ [43084]=2,
+ [43085]=2,
+ [43086]=2,
+ [43087]=2,
+ [43088]=2,
+ [43089]=2,
+ [43090]=2,
+ [43091]=2,
+ [43092]=2,
+ [43093]=2,
+ [43094]=2,
+ [43095]=2,
+ [43096]=2,
+ [43097]=2,
+ [43098]=2,
+ [43099]=2,
+ [43100]=2,
+ [43101]=2,
+ [43102]=2,
+ [43103]=2,
+ [43104]=2,
+ [43105]=2,
+ [43106]=2,
+ [43107]=2,
+ [43108]=2,
+ [43109]=2,
+ [43110]=2,
+ [43111]=2,
+ [43112]=2,
+ [43113]=2,
+ [43114]=2,
+ [43115]=2,
+ [43116]=2,
+ [43117]=2,
+ [43118]=2,
+ [43119]=2,
+ [43120]=2,
+ [43121]=2,
+ [43122]=1,
+ [43123]=4,
+ [43204]=5,
+ [43205]=5,
+ [43232]=5,
+ [43233]=5,
+ [43234]=5,
+ [43235]=5,
+ [43236]=5,
+ [43237]=5,
+ [43238]=5,
+ [43239]=5,
+ [43240]=5,
+ [43241]=5,
+ [43242]=5,
+ [43243]=5,
+ [43244]=5,
+ [43245]=5,
+ [43246]=5,
+ [43247]=5,
+ [43248]=5,
+ [43249]=5,
+ [43263]=5,
+ [43302]=5,
+ [43303]=5,
+ [43304]=5,
+ [43305]=5,
+ [43306]=5,
+ [43307]=5,
+ [43308]=5,
+ [43309]=5,
+ [43335]=5,
+ [43336]=5,
+ [43337]=5,
+ [43338]=5,
+ [43339]=5,
+ [43340]=5,
+ [43341]=5,
+ [43342]=5,
+ [43343]=5,
+ [43344]=5,
+ [43345]=5,
+ [43392]=5,
+ [43393]=5,
+ [43394]=5,
+ [43443]=5,
+ [43446]=5,
+ [43447]=5,
+ [43448]=5,
+ [43449]=5,
+ [43452]=5,
+ [43493]=5,
+ [43561]=5,
+ [43562]=5,
+ [43563]=5,
+ [43564]=5,
+ [43565]=5,
+ [43566]=5,
+ [43569]=5,
+ [43570]=5,
+ [43573]=5,
+ [43574]=5,
+ [43587]=5,
+ [43596]=5,
+ [43644]=5,
+ [43696]=5,
+ [43698]=5,
+ [43699]=5,
+ [43700]=5,
+ [43703]=5,
+ [43704]=5,
+ [43710]=5,
+ [43711]=5,
+ [43713]=5,
+ [43756]=5,
+ [43757]=5,
+ [43766]=5,
+ [44005]=5,
+ [44008]=5,
+ [44013]=5,
+ [64286]=5,
+ [65056]=5,
+ [65057]=5,
+ [65058]=5,
+ [65059]=5,
+ [65060]=5,
+ [65061]=5,
+ [65062]=5,
+ [65063]=5,
+ [65064]=5,
+ [65065]=5,
+ [65066]=5,
+ [65067]=5,
+ [65068]=5,
+ [65069]=5,
+ [65070]=5,
+ [65071]=5,
+ [66045]=5,
+ [66272]=5,
+ [66422]=5,
+ [66423]=5,
+ [66424]=5,
+ [66425]=5,
+ [66426]=5,
+ [68097]=5,
+ [68098]=5,
+ [68099]=5,
+ [68101]=5,
+ [68102]=5,
+ [68108]=5,
+ [68109]=5,
+ [68110]=5,
+ [68111]=5,
+ [68152]=5,
+ [68153]=5,
+ [68154]=5,
+ [68159]=5,
+ [68288]=2,
+ [68289]=2,
+ [68290]=2,
+ [68291]=2,
+ [68292]=2,
+ [68293]=3,
+ [68294]=4,
+ [68295]=3,
+ [68296]=4,
+ [68297]=3,
+ [68298]=3,
+ [68299]=4,
+ [68300]=4,
+ [68301]=1,
+ [68302]=3,
+ [68303]=3,
+ [68304]=3,
+ [68305]=3,
+ [68306]=3,
+ [68307]=2,
+ [68308]=2,
+ [68309]=2,
+ [68310]=2,
+ [68311]=1,
+ [68312]=2,
+ [68313]=2,
+ [68314]=2,
+ [68315]=2,
+ [68316]=2,
+ [68317]=3,
+ [68318]=2,
+ [68319]=2,
+ [68320]=2,
+ [68321]=3,
+ [68322]=4,
+ [68323]=4,
+ [68324]=3,
+ [68325]=5,
+ [68326]=5,
+ [68331]=2,
+ [68332]=2,
+ [68333]=2,
+ [68334]=2,
+ [68335]=3,
+ [68480]=2,
+ [68481]=3,
+ [68482]=2,
+ [68483]=3,
+ [68484]=3,
+ [68485]=3,
+ [68486]=2,
+ [68487]=2,
+ [68488]=2,
+ [68489]=3,
+ [68490]=2,
+ [68491]=2,
+ [68492]=3,
+ [68493]=2,
+ [68494]=3,
+ [68495]=3,
+ [68496]=2,
+ [68497]=3,
+ [68521]=3,
+ [68522]=3,
+ [68523]=3,
+ [68524]=3,
+ [68525]=2,
+ [68526]=2,
+ [68527]=4,
+ [68864]=1,
+ [68865]=2,
+ [68866]=2,
+ [68867]=2,
+ [68868]=2,
+ [68869]=2,
+ [68870]=2,
+ [68871]=2,
+ [68872]=2,
+ [68873]=2,
+ [68874]=2,
+ [68875]=2,
+ [68876]=2,
+ [68877]=2,
+ [68878]=2,
+ [68879]=2,
+ [68880]=2,
+ [68881]=2,
+ [68882]=2,
+ [68883]=2,
+ [68884]=2,
+ [68885]=2,
+ [68886]=2,
+ [68887]=2,
+ [68888]=2,
+ [68889]=2,
+ [68890]=2,
+ [68891]=2,
+ [68892]=2,
+ [68893]=2,
+ [68894]=2,
+ [68895]=2,
+ [68896]=2,
+ [68897]=2,
+ [68898]=3,
+ [68899]=2,
+ [68900]=5,
+ [68901]=5,
+ [68902]=5,
+ [68903]=5,
+ [69424]=2,
+ [69425]=2,
+ [69426]=2,
+ [69427]=3,
+ [69428]=2,
+ [69429]=2,
+ [69430]=2,
+ [69431]=2,
+ [69432]=2,
+ [69433]=2,
+ [69434]=2,
+ [69435]=2,
+ [69436]=2,
+ [69437]=2,
+ [69438]=2,
+ [69439]=2,
+ [69440]=2,
+ [69441]=2,
+ [69442]=2,
+ [69443]=2,
+ [69444]=2,
+ [69445]=4,
+ [69446]=5,
+ [69447]=5,
+ [69448]=5,
+ [69449]=5,
+ [69450]=5,
+ [69451]=5,
+ [69452]=5,
+ [69453]=5,
+ [69454]=5,
+ [69455]=5,
+ [69456]=5,
+ [69457]=2,
+ [69458]=2,
+ [69459]=2,
+ [69460]=3,
+ [69633]=5,
+ [69688]=5,
+ [69689]=5,
+ [69690]=5,
+ [69691]=5,
+ [69692]=5,
+ [69693]=5,
+ [69694]=5,
+ [69695]=5,
+ [69696]=5,
+ [69697]=5,
+ [69698]=5,
+ [69699]=5,
+ [69700]=5,
+ [69701]=5,
+ [69702]=5,
+ [69759]=5,
+ [69760]=5,
+ [69761]=5,
+ [69811]=5,
+ [69812]=5,
+ [69813]=5,
+ [69814]=5,
+ [69817]=5,
+ [69818]=5,
+ [69821]=4,
+ [69837]=4,
+ [69888]=5,
+ [69889]=5,
+ [69890]=5,
+ [69927]=5,
+ [69928]=5,
+ [69929]=5,
+ [69930]=5,
+ [69931]=5,
+ [69933]=5,
+ [69934]=5,
+ [69935]=5,
+ [69936]=5,
+ [69937]=5,
+ [69938]=5,
+ [69939]=5,
+ [69940]=5,
+ [70003]=5,
+ [70016]=5,
+ [70017]=5,
+ [70070]=5,
+ [70071]=5,
+ [70072]=5,
+ [70073]=5,
+ [70074]=5,
+ [70075]=5,
+ [70076]=5,
+ [70077]=5,
+ [70078]=5,
+ [70090]=5,
+ [70091]=5,
+ [70092]=5,
+ [70191]=5,
+ [70192]=5,
+ [70193]=5,
+ [70196]=5,
+ [70198]=5,
+ [70199]=5,
+ [70206]=5,
+ [70367]=5,
+ [70371]=5,
+ [70372]=5,
+ [70373]=5,
+ [70374]=5,
+ [70375]=5,
+ [70376]=5,
+ [70377]=5,
+ [70378]=5,
+ [70400]=5,
+ [70401]=5,
+ [70459]=5,
+ [70460]=5,
+ [70464]=5,
+ [70502]=5,
+ [70503]=5,
+ [70504]=5,
+ [70505]=5,
+ [70506]=5,
+ [70507]=5,
+ [70508]=5,
+ [70512]=5,
+ [70513]=5,
+ [70514]=5,
+ [70515]=5,
+ [70516]=5,
+ [70712]=5,
+ [70713]=5,
+ [70714]=5,
+ [70715]=5,
+ [70716]=5,
+ [70717]=5,
+ [70718]=5,
+ [70719]=5,
+ [70722]=5,
+ [70723]=5,
+ [70724]=5,
+ [70726]=5,
+ [70750]=5,
+ [70835]=5,
+ [70836]=5,
+ [70837]=5,
+ [70838]=5,
+ [70839]=5,
+ [70840]=5,
+ [70842]=5,
+ [70847]=5,
+ [70848]=5,
+ [70850]=5,
+ [70851]=5,
+ [71090]=5,
+ [71091]=5,
+ [71092]=5,
+ [71093]=5,
+ [71100]=5,
+ [71101]=5,
+ [71103]=5,
+ [71104]=5,
+ [71132]=5,
+ [71133]=5,
+ [71219]=5,
+ [71220]=5,
+ [71221]=5,
+ [71222]=5,
+ [71223]=5,
+ [71224]=5,
+ [71225]=5,
+ [71226]=5,
+ [71229]=5,
+ [71231]=5,
+ [71232]=5,
+ [71339]=5,
+ [71341]=5,
+ [71344]=5,
+ [71345]=5,
+ [71346]=5,
+ [71347]=5,
+ [71348]=5,
+ [71349]=5,
+ [71351]=5,
+ [71453]=5,
+ [71454]=5,
+ [71455]=5,
+ [71458]=5,
+ [71459]=5,
+ [71460]=5,
+ [71461]=5,
+ [71463]=5,
+ [71464]=5,
+ [71465]=5,
+ [71466]=5,
+ [71467]=5,
+ [71727]=5,
+ [71728]=5,
+ [71729]=5,
+ [71730]=5,
+ [71731]=5,
+ [71732]=5,
+ [71733]=5,
+ [71734]=5,
+ [71735]=5,
+ [71737]=5,
+ [71738]=5,
+ [72148]=5,
+ [72149]=5,
+ [72150]=5,
+ [72151]=5,
+ [72154]=5,
+ [72155]=5,
+ [72160]=5,
+ [72193]=5,
+ [72194]=5,
+ [72195]=5,
+ [72196]=5,
+ [72197]=5,
+ [72198]=5,
+ [72201]=5,
+ [72202]=5,
+ [72243]=5,
+ [72244]=5,
+ [72245]=5,
+ [72246]=5,
+ [72247]=5,
+ [72248]=5,
+ [72251]=5,
+ [72252]=5,
+ [72253]=5,
+ [72254]=5,
+ [72263]=5,
+ [72273]=5,
+ [72274]=5,
+ [72275]=5,
+ [72276]=5,
+ [72277]=5,
+ [72278]=5,
+ [72281]=5,
+ [72282]=5,
+ [72283]=5,
+ [72330]=5,
+ [72331]=5,
+ [72332]=5,
+ [72333]=5,
+ [72334]=5,
+ [72335]=5,
+ [72336]=5,
+ [72337]=5,
+ [72338]=5,
+ [72339]=5,
+ [72340]=5,
+ [72341]=5,
+ [72342]=5,
+ [72344]=5,
+ [72345]=5,
+ [72752]=5,
+ [72753]=5,
+ [72754]=5,
+ [72755]=5,
+ [72756]=5,
+ [72757]=5,
+ [72758]=5,
+ [72760]=5,
+ [72761]=5,
+ [72762]=5,
+ [72763]=5,
+ [72764]=5,
+ [72765]=5,
+ [72767]=5,
+ [72850]=5,
+ [72851]=5,
+ [72852]=5,
+ [72853]=5,
+ [72854]=5,
+ [72855]=5,
+ [72856]=5,
+ [72857]=5,
+ [72858]=5,
+ [72859]=5,
+ [72860]=5,
+ [72861]=5,
+ [72862]=5,
+ [72863]=5,
+ [72864]=5,
+ [72865]=5,
+ [72866]=5,
+ [72867]=5,
+ [72868]=5,
+ [72869]=5,
+ [72870]=5,
+ [72871]=5,
+ [72874]=5,
+ [72875]=5,
+ [72876]=5,
+ [72877]=5,
+ [72878]=5,
+ [72879]=5,
+ [72880]=5,
+ [72882]=5,
+ [72883]=5,
+ [72885]=5,
+ [72886]=5,
+ [73009]=5,
+ [73010]=5,
+ [73011]=5,
+ [73012]=5,
+ [73013]=5,
+ [73014]=5,
+ [73018]=5,
+ [73020]=5,
+ [73021]=5,
+ [73023]=5,
+ [73024]=5,
+ [73025]=5,
+ [73026]=5,
+ [73027]=5,
+ [73028]=5,
+ [73029]=5,
+ [73031]=5,
+ [73104]=5,
+ [73105]=5,
+ [73109]=5,
+ [73111]=5,
+ [73459]=5,
+ [73460]=5,
+ [92912]=5,
+ [92913]=5,
+ [92914]=5,
+ [92915]=5,
+ [92916]=5,
+ [92976]=5,
+ [92977]=5,
+ [92978]=5,
+ [92979]=5,
+ [92980]=5,
+ [92981]=5,
+ [92982]=5,
+ [94031]=5,
+ [94095]=5,
+ [94096]=5,
+ [94097]=5,
+ [94098]=5,
+ [113821]=5,
+ [113822]=5,
+ [119143]=5,
+ [119144]=5,
+ [119145]=5,
+ [119163]=5,
+ [119164]=5,
+ [119165]=5,
+ [119166]=5,
+ [119167]=5,
+ [119168]=5,
+ [119169]=5,
+ [119170]=5,
+ [119173]=5,
+ [119174]=5,
+ [119175]=5,
+ [119176]=5,
+ [119177]=5,
+ [119178]=5,
+ [119179]=5,
+ [119210]=5,
+ [119211]=5,
+ [119212]=5,
+ [119213]=5,
+ [119362]=5,
+ [119363]=5,
+ [119364]=5,
+ [121344]=5,
+ [121345]=5,
+ [121346]=5,
+ [121347]=5,
+ [121348]=5,
+ [121349]=5,
+ [121350]=5,
+ [121351]=5,
+ [121352]=5,
+ [121353]=5,
+ [121354]=5,
+ [121355]=5,
+ [121356]=5,
+ [121357]=5,
+ [121358]=5,
+ [121359]=5,
+ [121360]=5,
+ [121361]=5,
+ [121362]=5,
+ [121363]=5,
+ [121364]=5,
+ [121365]=5,
+ [121366]=5,
+ [121367]=5,
+ [121368]=5,
+ [121369]=5,
+ [121370]=5,
+ [121371]=5,
+ [121372]=5,
+ [121373]=5,
+ [121374]=5,
+ [121375]=5,
+ [121376]=5,
+ [121377]=5,
+ [121378]=5,
+ [121379]=5,
+ [121380]=5,
+ [121381]=5,
+ [121382]=5,
+ [121383]=5,
+ [121384]=5,
+ [121385]=5,
+ [121386]=5,
+ [121387]=5,
+ [121388]=5,
+ [121389]=5,
+ [121390]=5,
+ [121391]=5,
+ [121392]=5,
+ [121393]=5,
+ [121394]=5,
+ [121395]=5,
+ [121396]=5,
+ [121397]=5,
+ [121398]=5,
+ [121403]=5,
+ [121404]=5,
+ [121405]=5,
+ [121406]=5,
+ [121407]=5,
+ [121408]=5,
+ [121409]=5,
+ [121410]=5,
+ [121411]=5,
+ [121412]=5,
+ [121413]=5,
+ [121414]=5,
+ [121415]=5,
+ [121416]=5,
+ [121417]=5,
+ [121418]=5,
+ [121419]=5,
+ [121420]=5,
+ [121421]=5,
+ [121422]=5,
+ [121423]=5,
+ [121424]=5,
+ [121425]=5,
+ [121426]=5,
+ [121427]=5,
+ [121428]=5,
+ [121429]=5,
+ [121430]=5,
+ [121431]=5,
+ [121432]=5,
+ [121433]=5,
+ [121434]=5,
+ [121435]=5,
+ [121436]=5,
+ [121437]=5,
+ [121438]=5,
+ [121439]=5,
+ [121440]=5,
+ [121441]=5,
+ [121442]=5,
+ [121443]=5,
+ [121444]=5,
+ [121445]=5,
+ [121446]=5,
+ [121447]=5,
+ [121448]=5,
+ [121449]=5,
+ [121450]=5,
+ [121451]=5,
+ [121452]=5,
+ [121461]=5,
+ [121476]=5,
+ [121499]=5,
+ [121500]=5,
+ [121501]=5,
+ [121502]=5,
+ [121503]=5,
+ [121505]=5,
+ [121506]=5,
+ [121507]=5,
+ [121508]=5,
+ [121509]=5,
+ [121510]=5,
+ [121511]=5,
+ [121512]=5,
+ [121513]=5,
+ [121514]=5,
+ [121515]=5,
+ [121516]=5,
+ [121517]=5,
+ [121518]=5,
+ [121519]=5,
+ [122880]=5,
+ [122881]=5,
+ [122882]=5,
+ [122883]=5,
+ [122884]=5,
+ [122885]=5,
+ [122886]=5,
+ [122888]=5,
+ [122889]=5,
+ [122890]=5,
+ [122891]=5,
+ [122892]=5,
+ [122893]=5,
+ [122894]=5,
+ [122895]=5,
+ [122896]=5,
+ [122897]=5,
+ [122898]=5,
+ [122899]=5,
+ [122900]=5,
+ [122901]=5,
+ [122902]=5,
+ [122903]=5,
+ [122904]=5,
+ [122907]=5,
+ [122908]=5,
+ [122909]=5,
+ [122910]=5,
+ [122911]=5,
+ [122912]=5,
+ [122913]=5,
+ [122915]=5,
+ [122916]=5,
+ [122918]=5,
+ [122919]=5,
+ [122920]=5,
+ [122921]=5,
+ [122922]=5,
+ [123184]=5,
+ [123185]=5,
+ [123186]=5,
+ [123187]=5,
+ [123188]=5,
+ [123189]=5,
+ [123190]=5,
+ [123628]=5,
+ [123629]=5,
+ [123630]=5,
+ [123631]=5,
+ [125136]=5,
+ [125137]=5,
+ [125138]=5,
+ [125139]=5,
+ [125140]=5,
+ [125141]=5,
+ [125142]=5,
+ [125184]=2,
+ [125185]=2,
+ [125186]=2,
+ [125187]=2,
+ [125188]=2,
+ [125189]=2,
+ [125190]=2,
+ [125191]=2,
+ [125192]=2,
+ [125193]=2,
+ [125194]=2,
+ [125195]=2,
+ [125196]=2,
+ [125197]=2,
+ [125198]=2,
+ [125199]=2,
+ [125200]=2,
+ [125201]=2,
+ [125202]=2,
+ [125203]=2,
+ [125204]=2,
+ [125205]=2,
+ [125206]=2,
+ [125207]=2,
+ [125208]=2,
+ [125209]=2,
+ [125210]=2,
+ [125211]=2,
+ [125212]=2,
+ [125213]=2,
+ [125214]=2,
+ [125215]=2,
+ [125216]=2,
+ [125217]=2,
+ [125218]=2,
+ [125219]=2,
+ [125220]=2,
+ [125221]=2,
+ [125222]=2,
+ [125223]=2,
+ [125224]=2,
+ [125225]=2,
+ [125226]=2,
+ [125227]=2,
+ [125228]=2,
+ [125229]=2,
+ [125230]=2,
+ [125231]=2,
+ [125232]=2,
+ [125233]=2,
+ [125234]=2,
+ [125235]=2,
+ [125236]=2,
+ [125237]=2,
+ [125238]=2,
+ [125239]=2,
+ [125240]=2,
+ [125241]=2,
+ [125242]=2,
+ [125243]=2,
+ [125244]=2,
+ [125245]=2,
+ [125246]=2,
+ [125247]=2,
+ [125248]=2,
+ [125249]=2,
+ [125250]=2,
+ [125251]=2,
+ [125252]=5,
+ [125253]=5,
+ [125254]=5,
+ [125255]=5,
+ [125256]=5,
+ [125257]=5,
+ [125258]=5,
+ [1042752]=5,
+}
+characters.indicgroups={
+ ["above_mark"]={
+ [2304]=true,
+ [2305]=true,
+ [2306]=true,
+ [2362]=true,
+ [2373]=true,
+ [2374]=true,
+ [2375]=true,
+ [2376]=true,
+ [2385]=true,
+ [2387]=true,
+ [2388]=true,
+ [2389]=true,
+ [2631]=true,
+ [2632]=true,
+ [2635]=true,
+ [2636]=true,
+ [2690]=true,
+ [2757]=true,
+ [2759]=true,
+ [2760]=true,
+ [2879]=true,
+ [3008]=true,
+ [3021]=true,
+ [3134]=true,
+ [3135]=true,
+ [3136]=true,
+ [3142]=true,
+ [3143]=true,
+ [3146]=true,
+ [3147]=true,
+ [3148]=true,
+ [3149]=true,
+ [3263]=true,
+ [3270]=true,
+ [3406]=true,
+ [4141]=true,
+ [4142]=true,
+ [4146]=true,
+ [4147]=true,
+ [4148]=true,
+ [4149]=true,
+ [4150]=true,
+ [4154]=true,
+ [4209]=true,
+ [4210]=true,
+ [4211]=true,
+ [4212]=true,
+ [4229]=true,
+ [4230]=true,
+ [4253]=true,
+ [43232]=true,
+ [43233]=true,
+ [43234]=true,
+ [43235]=true,
+ [43236]=true,
+ [43237]=true,
+ [43238]=true,
+ [43239]=true,
+ [43240]=true,
+ [43241]=true,
+ [43242]=true,
+ [43243]=true,
+ [43244]=true,
+ [43245]=true,
+ [43246]=true,
+ [43247]=true,
+ [43248]=true,
+ [43249]=true,
+ [43493]=true,
+ [43644]=true,
+ },
+ ["after_half"]={},
+ ["after_main"]={
+ [2864]=true,
+ [2879]=true,
+ [2902]=true,
+ [3376]=true,
+ },
+ ["after_postscript"]={
+ [2433]=true,
+ [2494]=true,
+ [2496]=true,
+ [2519]=true,
+ [2561]=true,
+ [2562]=true,
+ [2622]=true,
+ [2624]=true,
+ [2625]=true,
+ [2626]=true,
+ [2672]=true,
+ [2673]=true,
+ [2735]=true,
+ [2750]=true,
+ [2752]=true,
+ [2753]=true,
+ [2754]=true,
+ [2755]=true,
+ [2756]=true,
+ [2761]=true,
+ [2763]=true,
+ [2764]=true,
+ [2786]=true,
+ [2787]=true,
+ [2878]=true,
+ [2880]=true,
+ [2903]=true,
+ [2992]=true,
+ [3006]=true,
+ [3007]=true,
+ [3009]=true,
+ [3010]=true,
+ [3031]=true,
+ [3120]=true,
+ [3248]=true,
+ [3390]=true,
+ [3391]=true,
+ [3392]=true,
+ [3393]=true,
+ [3394]=true,
+ [3395]=true,
+ [3415]=true,
+ },
+ ["after_subscript"]={
+ [2366]=true,
+ [2368]=true,
+ [2369]=true,
+ [2370]=true,
+ [2371]=true,
+ [2372]=true,
+ [2373]=true,
+ [2374]=true,
+ [2375]=true,
+ [2376]=true,
+ [2377]=true,
+ [2378]=true,
+ [2379]=true,
+ [2380]=true,
+ [2402]=true,
+ [2403]=true,
+ [2480]=true,
+ [2497]=true,
+ [2498]=true,
+ [2499]=true,
+ [2500]=true,
+ [2530]=true,
+ [2531]=true,
+ [2544]=true,
+ [2631]=true,
+ [2632]=true,
+ [2635]=true,
+ [2636]=true,
+ [2757]=true,
+ [2759]=true,
+ [2760]=true,
+ [2881]=true,
+ [2882]=true,
+ [2883]=true,
+ [3008]=true,
+ [3139]=true,
+ [3140]=true,
+ [3267]=true,
+ [3268]=true,
+ [3285]=true,
+ [3286]=true,
+ },
+ ["anudatta"]={
+ [2386]=true,
+ },
+ ["before_half"]={
+ [2367]=true,
+ [2382]=true,
+ [2495]=true,
+ [2503]=true,
+ [2504]=true,
+ [2623]=true,
+ [2751]=true,
+ [2887]=true,
+ },
+ ["before_main"]={
+ [3014]=true,
+ [3015]=true,
+ [3016]=true,
+ [3398]=true,
+ [3399]=true,
+ [3400]=true,
+ },
+ ["before_postscript"]={
+ [2352]=true,
+ [2736]=true,
+ },
+ ["before_subscript"]={
+ [2608]=true,
+ [2817]=true,
+ [3134]=true,
+ [3135]=true,
+ [3136]=true,
+ [3137]=true,
+ [3138]=true,
+ [3142]=true,
+ [3143]=true,
+ [3146]=true,
+ [3147]=true,
+ [3148]=true,
+ [3157]=true,
+ [3158]=true,
+ [3262]=true,
+ [3263]=true,
+ [3265]=true,
+ [3266]=true,
+ [3270]=true,
+ [3276]=true,
+ [3298]=true,
+ [3299]=true,
+ },
+ ["below_mark"]={
+ [2364]=true,
+ [2369]=true,
+ [2370]=true,
+ [2371]=true,
+ [2372]=true,
+ [2381]=true,
+ [2386]=true,
+ [2390]=true,
+ [2391]=true,
+ [2402]=true,
+ [2403]=true,
+ [2492]=true,
+ [2497]=true,
+ [2498]=true,
+ [2499]=true,
+ [2500]=true,
+ [2509]=true,
+ [2620]=true,
+ [2625]=true,
+ [2626]=true,
+ [2637]=true,
+ [2748]=true,
+ [2753]=true,
+ [2754]=true,
+ [2755]=true,
+ [2756]=true,
+ [2765]=true,
+ [2876]=true,
+ [2881]=true,
+ [2882]=true,
+ [2883]=true,
+ [2884]=true,
+ [2893]=true,
+ [2914]=true,
+ [2915]=true,
+ [3009]=true,
+ [3010]=true,
+ [3170]=true,
+ [3171]=true,
+ [3260]=true,
+ [3286]=true,
+ [3298]=true,
+ [3299]=true,
+ [3426]=true,
+ [3427]=true,
+ [4143]=true,
+ [4144]=true,
+ [4151]=true,
+ [4153]=true,
+ [4157]=true,
+ [4158]=true,
+ [4184]=true,
+ [4185]=true,
+ [4190]=true,
+ [4191]=true,
+ [4192]=true,
+ [4226]=true,
+ [4237]=true,
+ },
+ ["consonant"]={
+ [2325]=true,
+ [2326]=true,
+ [2327]=true,
+ [2328]=true,
+ [2329]=true,
+ [2330]=true,
+ [2331]=true,
+ [2332]=true,
+ [2333]=true,
+ [2334]=true,
+ [2335]=true,
+ [2336]=true,
+ [2337]=true,
+ [2338]=true,
+ [2339]=true,
+ [2340]=true,
+ [2341]=true,
+ [2342]=true,
+ [2343]=true,
+ [2344]=true,
+ [2345]=true,
+ [2346]=true,
+ [2347]=true,
+ [2348]=true,
+ [2349]=true,
+ [2350]=true,
+ [2351]=true,
+ [2352]=true,
+ [2353]=true,
+ [2354]=true,
+ [2355]=true,
+ [2356]=true,
+ [2357]=true,
+ [2358]=true,
+ [2359]=true,
+ [2360]=true,
+ [2361]=true,
+ [2392]=true,
+ [2393]=true,
+ [2394]=true,
+ [2395]=true,
+ [2396]=true,
+ [2397]=true,
+ [2398]=true,
+ [2399]=true,
+ [2424]=true,
+ [2425]=true,
+ [2426]=true,
+ [2453]=true,
+ [2454]=true,
+ [2455]=true,
+ [2456]=true,
+ [2457]=true,
+ [2458]=true,
+ [2459]=true,
+ [2460]=true,
+ [2461]=true,
+ [2462]=true,
+ [2463]=true,
+ [2464]=true,
+ [2465]=true,
+ [2466]=true,
+ [2467]=true,
+ [2468]=true,
+ [2469]=true,
+ [2470]=true,
+ [2471]=true,
+ [2472]=true,
+ [2474]=true,
+ [2475]=true,
+ [2476]=true,
+ [2477]=true,
+ [2478]=true,
+ [2479]=true,
+ [2480]=true,
+ [2482]=true,
+ [2486]=true,
+ [2487]=true,
+ [2488]=true,
+ [2489]=true,
+ [2510]=true,
+ [2524]=true,
+ [2525]=true,
+ [2527]=true,
+ [2581]=true,
+ [2582]=true,
+ [2583]=true,
+ [2584]=true,
+ [2585]=true,
+ [2586]=true,
+ [2587]=true,
+ [2588]=true,
+ [2589]=true,
+ [2590]=true,
+ [2591]=true,
+ [2592]=true,
+ [2593]=true,
+ [2594]=true,
+ [2595]=true,
+ [2596]=true,
+ [2597]=true,
+ [2598]=true,
+ [2599]=true,
+ [2600]=true,
+ [2602]=true,
+ [2603]=true,
+ [2604]=true,
+ [2605]=true,
+ [2606]=true,
+ [2607]=true,
+ [2608]=true,
+ [2610]=true,
+ [2611]=true,
+ [2613]=true,
+ [2614]=true,
+ [2616]=true,
+ [2617]=true,
+ [2649]=true,
+ [2650]=true,
+ [2651]=true,
+ [2652]=true,
+ [2654]=true,
+ [2709]=true,
+ [2710]=true,
+ [2711]=true,
+ [2712]=true,
+ [2713]=true,
+ [2714]=true,
+ [2715]=true,
+ [2716]=true,
+ [2717]=true,
+ [2718]=true,
+ [2719]=true,
+ [2720]=true,
+ [2721]=true,
+ [2722]=true,
+ [2723]=true,
+ [2724]=true,
+ [2725]=true,
+ [2726]=true,
+ [2727]=true,
+ [2728]=true,
+ [2730]=true,
+ [2731]=true,
+ [2732]=true,
+ [2733]=true,
+ [2734]=true,
+ [2735]=true,
+ [2736]=true,
+ [2738]=true,
+ [2739]=true,
+ [2741]=true,
+ [2742]=true,
+ [2743]=true,
+ [2744]=true,
+ [2745]=true,
+ [2837]=true,
+ [2838]=true,
+ [2839]=true,
+ [2840]=true,
+ [2841]=true,
+ [2842]=true,
+ [2843]=true,
+ [2844]=true,
+ [2845]=true,
+ [2846]=true,
+ [2847]=true,
+ [2848]=true,
+ [2849]=true,
+ [2850]=true,
+ [2851]=true,
+ [2852]=true,
+ [2853]=true,
+ [2854]=true,
+ [2855]=true,
+ [2856]=true,
+ [2858]=true,
+ [2859]=true,
+ [2860]=true,
+ [2861]=true,
+ [2862]=true,
+ [2863]=true,
+ [2864]=true,
+ [2866]=true,
+ [2867]=true,
+ [2869]=true,
+ [2870]=true,
+ [2871]=true,
+ [2872]=true,
+ [2873]=true,
+ [2908]=true,
+ [2909]=true,
+ [2929]=true,
+ [2965]=true,
+ [2969]=true,
+ [2970]=true,
+ [2972]=true,
+ [2974]=true,
+ [2975]=true,
+ [2979]=true,
+ [2980]=true,
+ [2984]=true,
+ [2985]=true,
+ [2986]=true,
+ [2990]=true,
+ [2991]=true,
+ [2992]=true,
+ [2993]=true,
+ [2994]=true,
+ [2995]=true,
+ [2996]=true,
+ [2997]=true,
+ [2998]=true,
+ [2999]=true,
+ [3000]=true,
+ [3001]=true,
+ [3093]=true,
+ [3094]=true,
+ [3095]=true,
+ [3096]=true,
+ [3097]=true,
+ [3098]=true,
+ [3099]=true,
+ [3100]=true,
+ [3101]=true,
+ [3102]=true,
+ [3103]=true,
+ [3104]=true,
+ [3105]=true,
+ [3106]=true,
+ [3107]=true,
+ [3108]=true,
+ [3109]=true,
+ [3110]=true,
+ [3111]=true,
+ [3112]=true,
+ [3114]=true,
+ [3115]=true,
+ [3116]=true,
+ [3117]=true,
+ [3118]=true,
+ [3119]=true,
+ [3120]=true,
+ [3121]=true,
+ [3122]=true,
+ [3123]=true,
+ [3124]=true,
+ [3125]=true,
+ [3126]=true,
+ [3127]=true,
+ [3128]=true,
+ [3129]=true,
+ [3133]=true,
+ [3221]=true,
+ [3222]=true,
+ [3223]=true,
+ [3224]=true,
+ [3225]=true,
+ [3226]=true,
+ [3227]=true,
+ [3228]=true,
+ [3229]=true,
+ [3230]=true,
+ [3231]=true,
+ [3232]=true,
+ [3233]=true,
+ [3234]=true,
+ [3235]=true,
+ [3236]=true,
+ [3237]=true,
+ [3238]=true,
+ [3239]=true,
+ [3240]=true,
+ [3242]=true,
+ [3243]=true,
+ [3244]=true,
+ [3245]=true,
+ [3246]=true,
+ [3247]=true,
+ [3248]=true,
+ [3249]=true,
+ [3250]=true,
+ [3251]=true,
+ [3253]=true,
+ [3254]=true,
+ [3255]=true,
+ [3256]=true,
+ [3257]=true,
+ [3294]=true,
+ [3349]=true,
+ [3350]=true,
+ [3351]=true,
+ [3352]=true,
+ [3353]=true,
+ [3354]=true,
+ [3355]=true,
+ [3356]=true,
+ [3357]=true,
+ [3358]=true,
+ [3359]=true,
+ [3360]=true,
+ [3361]=true,
+ [3362]=true,
+ [3363]=true,
+ [3364]=true,
+ [3365]=true,
+ [3366]=true,
+ [3367]=true,
+ [3368]=true,
+ [3369]=true,
+ [3370]=true,
+ [3371]=true,
+ [3372]=true,
+ [3373]=true,
+ [3374]=true,
+ [3375]=true,
+ [3376]=true,
+ [3377]=true,
+ [3378]=true,
+ [3379]=true,
+ [3380]=true,
+ [3381]=true,
+ [3382]=true,
+ [3383]=true,
+ [3384]=true,
+ [3385]=true,
+ [3386]=true,
+ [4096]=true,
+ [4097]=true,
+ [4098]=true,
+ [4099]=true,
+ [4100]=true,
+ [4101]=true,
+ [4102]=true,
+ [4103]=true,
+ [4104]=true,
+ [4105]=true,
+ [4106]=true,
+ [4107]=true,
+ [4108]=true,
+ [4109]=true,
+ [4110]=true,
+ [4111]=true,
+ [4112]=true,
+ [4113]=true,
+ [4114]=true,
+ [4115]=true,
+ [4116]=true,
+ [4117]=true,
+ [4118]=true,
+ [4119]=true,
+ [4120]=true,
+ [4121]=true,
+ [4122]=true,
+ [4123]=true,
+ [4124]=true,
+ [4125]=true,
+ [4126]=true,
+ [4127]=true,
+ [4128]=true,
+ [4155]=true,
+ [4156]=true,
+ [4157]=true,
+ [4158]=true,
+ [4159]=true,
+ [4176]=true,
+ [4177]=true,
+ [4186]=true,
+ [4187]=true,
+ [4188]=true,
+ [4189]=true,
+ [4190]=true,
+ [4191]=true,
+ [4192]=true,
+ [4193]=true,
+ [4197]=true,
+ [4198]=true,
+ [4206]=true,
+ [4207]=true,
+ [4208]=true,
+ [4213]=true,
+ [4214]=true,
+ [4215]=true,
+ [4216]=true,
+ [4217]=true,
+ [4218]=true,
+ [4219]=true,
+ [4220]=true,
+ [4221]=true,
+ [4222]=true,
+ [4223]=true,
+ [4224]=true,
+ [4225]=true,
+ [4226]=true,
+ [4238]=true,
+ [43488]=true,
+ [43489]=true,
+ [43490]=true,
+ [43491]=true,
+ [43492]=true,
+ [43495]=true,
+ [43496]=true,
+ [43497]=true,
+ [43498]=true,
+ [43499]=true,
+ [43500]=true,
+ [43501]=true,
+ [43502]=true,
+ [43503]=true,
+ [43514]=true,
+ [43515]=true,
+ [43516]=true,
+ [43517]=true,
+ [43518]=true,
+ [43616]=true,
+ [43617]=true,
+ [43618]=true,
+ [43619]=true,
+ [43620]=true,
+ [43621]=true,
+ [43622]=true,
+ [43623]=true,
+ [43624]=true,
+ [43625]=true,
+ [43626]=true,
+ [43628]=true,
+ [43629]=true,
+ [43630]=true,
+ [43631]=true,
+ [43633]=true,
+ [43634]=true,
+ [43635]=true,
+ [43636]=true,
+ [43637]=true,
+ [43638]=true,
+ [43642]=true,
+ [43646]=true,
+ [43647]=true,
+ },
+ ["dependent_vowel"]={
+ [2362]=true,
+ [2363]=true,
+ [2366]=true,
+ [2367]=true,
+ [2368]=true,
+ [2369]=true,
+ [2370]=true,
+ [2371]=true,
+ [2372]=true,
+ [2373]=true,
+ [2374]=true,
+ [2375]=true,
+ [2376]=true,
+ [2377]=true,
+ [2378]=true,
+ [2379]=true,
+ [2380]=true,
+ [2382]=true,
+ [2383]=true,
+ [2389]=true,
+ [2390]=true,
+ [2391]=true,
+ [2402]=true,
+ [2403]=true,
+ [2494]=true,
+ [2495]=true,
+ [2497]=true,
+ [2498]=true,
+ [2499]=true,
+ [2500]=true,
+ [2503]=true,
+ [2504]=true,
+ [2507]=true,
+ [2508]=true,
+ [2622]=true,
+ [2623]=true,
+ [2624]=true,
+ [2625]=true,
+ [2626]=true,
+ [2631]=true,
+ [2632]=true,
+ [2635]=true,
+ [2636]=true,
+ [2750]=true,
+ [2751]=true,
+ [2752]=true,
+ [2753]=true,
+ [2754]=true,
+ [2755]=true,
+ [2756]=true,
+ [2757]=true,
+ [2759]=true,
+ [2760]=true,
+ [2761]=true,
+ [2763]=true,
+ [2764]=true,
+ [2878]=true,
+ [2879]=true,
+ [2880]=true,
+ [2881]=true,
+ [2882]=true,
+ [2883]=true,
+ [2884]=true,
+ [2887]=true,
+ [2888]=true,
+ [2891]=true,
+ [2892]=true,
+ [2914]=true,
+ [2915]=true,
+ [3006]=true,
+ [3007]=true,
+ [3008]=true,
+ [3009]=true,
+ [3010]=true,
+ [3014]=true,
+ [3015]=true,
+ [3016]=true,
+ [3018]=true,
+ [3019]=true,
+ [3020]=true,
+ [3134]=true,
+ [3135]=true,
+ [3136]=true,
+ [3137]=true,
+ [3138]=true,
+ [3139]=true,
+ [3140]=true,
+ [3142]=true,
+ [3143]=true,
+ [3144]=true,
+ [3146]=true,
+ [3147]=true,
+ [3148]=true,
+ [3170]=true,
+ [3171]=true,
+ [3262]=true,
+ [3263]=true,
+ [3264]=true,
+ [3265]=true,
+ [3266]=true,
+ [3267]=true,
+ [3268]=true,
+ [3270]=true,
+ [3271]=true,
+ [3272]=true,
+ [3274]=true,
+ [3275]=true,
+ [3276]=true,
+ [3285]=true,
+ [3286]=true,
+ [3298]=true,
+ [3299]=true,
+ [3390]=true,
+ [3391]=true,
+ [3392]=true,
+ [3393]=true,
+ [3394]=true,
+ [3395]=true,
+ [3396]=true,
+ [3398]=true,
+ [3399]=true,
+ [3400]=true,
+ [3402]=true,
+ [3403]=true,
+ [3404]=true,
+ [3415]=true,
+ [3426]=true,
+ [3427]=true,
+ [4139]=true,
+ [4140]=true,
+ [4141]=true,
+ [4142]=true,
+ [4143]=true,
+ [4144]=true,
+ [4145]=true,
+ [4146]=true,
+ [4147]=true,
+ [4148]=true,
+ [4149]=true,
+ [4182]=true,
+ [4183]=true,
+ [4184]=true,
+ [4185]=true,
+ [4194]=true,
+ [4199]=true,
+ [4200]=true,
+ [4209]=true,
+ [4210]=true,
+ [4211]=true,
+ [4212]=true,
+ [4227]=true,
+ [4228]=true,
+ [4229]=true,
+ [4230]=true,
+ [4252]=true,
+ [4253]=true,
+ [43493]=true,
+ },
+ ["halant"]={
+ [2381]=true,
+ [2509]=true,
+ [2637]=true,
+ [2765]=true,
+ [2893]=true,
+ [3021]=true,
+ [3149]=true,
+ [3277]=true,
+ [3405]=true,
+ },
+ ["independent_vowel"]={
+ [2308]=true,
+ [2309]=true,
+ [2310]=true,
+ [2311]=true,
+ [2312]=true,
+ [2313]=true,
+ [2314]=true,
+ [2315]=true,
+ [2316]=true,
+ [2317]=true,
+ [2318]=true,
+ [2319]=true,
+ [2320]=true,
+ [2321]=true,
+ [2322]=true,
+ [2323]=true,
+ [2324]=true,
+ [2400]=true,
+ [2401]=true,
+ [2418]=true,
+ [2419]=true,
+ [2420]=true,
+ [2421]=true,
+ [2422]=true,
+ [2423]=true,
+ [2437]=true,
+ [2438]=true,
+ [2439]=true,
+ [2440]=true,
+ [2441]=true,
+ [2442]=true,
+ [2443]=true,
+ [2444]=true,
+ [2447]=true,
+ [2448]=true,
+ [2451]=true,
+ [2452]=true,
+ [2528]=true,
+ [2529]=true,
+ [2530]=true,
+ [2531]=true,
+ [2565]=true,
+ [2566]=true,
+ [2567]=true,
+ [2568]=true,
+ [2569]=true,
+ [2570]=true,
+ [2575]=true,
+ [2576]=true,
+ [2579]=true,
+ [2580]=true,
+ [2693]=true,
+ [2694]=true,
+ [2695]=true,
+ [2696]=true,
+ [2697]=true,
+ [2698]=true,
+ [2699]=true,
+ [2700]=true,
+ [2701]=true,
+ [2703]=true,
+ [2704]=true,
+ [2705]=true,
+ [2707]=true,
+ [2708]=true,
+ [2784]=true,
+ [2785]=true,
+ [2786]=true,
+ [2787]=true,
+ [2821]=true,
+ [2822]=true,
+ [2823]=true,
+ [2824]=true,
+ [2825]=true,
+ [2826]=true,
+ [2827]=true,
+ [2828]=true,
+ [2831]=true,
+ [2832]=true,
+ [2835]=true,
+ [2836]=true,
+ [2912]=true,
+ [2913]=true,
+ [2949]=true,
+ [2950]=true,
+ [2951]=true,
+ [2952]=true,
+ [2953]=true,
+ [2954]=true,
+ [2958]=true,
+ [2959]=true,
+ [2960]=true,
+ [2962]=true,
+ [2963]=true,
+ [2964]=true,
+ [3077]=true,
+ [3078]=true,
+ [3079]=true,
+ [3080]=true,
+ [3081]=true,
+ [3082]=true,
+ [3083]=true,
+ [3084]=true,
+ [3086]=true,
+ [3087]=true,
+ [3088]=true,
+ [3090]=true,
+ [3091]=true,
+ [3092]=true,
+ [3168]=true,
+ [3169]=true,
+ [3205]=true,
+ [3206]=true,
+ [3207]=true,
+ [3208]=true,
+ [3209]=true,
+ [3210]=true,
+ [3211]=true,
+ [3212]=true,
+ [3214]=true,
+ [3215]=true,
+ [3216]=true,
+ [3218]=true,
+ [3219]=true,
+ [3220]=true,
+ [3296]=true,
+ [3297]=true,
+ [3333]=true,
+ [3334]=true,
+ [3335]=true,
+ [3336]=true,
+ [3337]=true,
+ [3338]=true,
+ [3339]=true,
+ [3340]=true,
+ [3342]=true,
+ [3343]=true,
+ [3344]=true,
+ [3346]=true,
+ [3347]=true,
+ [3348]=true,
+ [3423]=true,
+ [3424]=true,
+ [3425]=true,
+ [4129]=true,
+ [4130]=true,
+ [4131]=true,
+ [4132]=true,
+ [4133]=true,
+ [4134]=true,
+ [4135]=true,
+ [4136]=true,
+ [4137]=true,
+ [4138]=true,
+ [4178]=true,
+ [4179]=true,
+ [4180]=true,
+ [4181]=true,
+ },
+ ["nukta"]={
+ [2364]=true,
+ [2492]=true,
+ [2620]=true,
+ [2748]=true,
+ [2876]=true,
+ [3260]=true,
+ },
+ ["post_mark"]={
+ [2307]=true,
+ [2363]=true,
+ [2366]=true,
+ [2368]=true,
+ [2377]=true,
+ [2378]=true,
+ [2379]=true,
+ [2380]=true,
+ [2383]=true,
+ [2494]=true,
+ [2496]=true,
+ [2622]=true,
+ [2624]=true,
+ [2750]=true,
+ [2752]=true,
+ [2761]=true,
+ [2763]=true,
+ [2764]=true,
+ [2878]=true,
+ [2880]=true,
+ [3006]=true,
+ [3007]=true,
+ [3137]=true,
+ [3138]=true,
+ [3139]=true,
+ [3140]=true,
+ [3262]=true,
+ [3265]=true,
+ [3266]=true,
+ [3267]=true,
+ [3268]=true,
+ [3276]=true,
+ [3285]=true,
+ [3390]=true,
+ [3391]=true,
+ [3392]=true,
+ [3393]=true,
+ [3394]=true,
+ [3395]=true,
+ [3396]=true,
+ [3415]=true,
+ [4139]=true,
+ [4140]=true,
+ [4152]=true,
+ [4155]=true,
+ [4182]=true,
+ [4183]=true,
+ [4194]=true,
+ [4195]=true,
+ [4196]=true,
+ [4199]=true,
+ [4200]=true,
+ [4201]=true,
+ [4202]=true,
+ [4203]=true,
+ [4204]=true,
+ [4205]=true,
+ [4227]=true,
+ [4231]=true,
+ [4232]=true,
+ [4233]=true,
+ [4234]=true,
+ [4235]=true,
+ [4236]=true,
+ [4239]=true,
+ [4250]=true,
+ [4251]=true,
+ [4252]=true,
+ [43643]=true,
+ [43645]=true,
+ },
+ ["pre_mark"]={
+ [2367]=true,
+ [2382]=true,
+ [2495]=true,
+ [2503]=true,
+ [2504]=true,
+ [2623]=true,
+ [2751]=true,
+ [2887]=true,
+ [3014]=true,
+ [3015]=true,
+ [3016]=true,
+ [3398]=true,
+ [3399]=true,
+ [3400]=true,
+ [4145]=true,
+ [4228]=true,
+ },
+ ["ra"]={
+ [2352]=true,
+ [2480]=true,
+ [2544]=true,
+ [2608]=true,
+ [2736]=true,
+ [2864]=true,
+ [2992]=true,
+ [3120]=true,
+ [3248]=true,
+ [3376]=true,
+ },
+ ["stress_tone_mark"]={
+ [2385]=true,
+ [2386]=true,
+ [2387]=true,
+ [2388]=true,
+ [4151]=true,
+ [4195]=true,
+ [4196]=true,
+ [4201]=true,
+ [4202]=true,
+ [4203]=true,
+ [4204]=true,
+ [4205]=true,
+ [4231]=true,
+ [4232]=true,
+ [4233]=true,
+ [4234]=true,
+ [4235]=true,
+ [4236]=true,
+ [4237]=true,
+ [4239]=true,
+ [4250]=true,
+ [4251]=true,
+ [43643]=true,
+ [43644]=true,
+ [43645]=true,
+ },
+ ["twopart_mark"]={
+ [2507]={ 2503,2494 },
+ [2508]={ 2503,2519 },
+ [2888]={ 2887,2902 },
+ [2891]={ 2887,2878 },
+ [2892]={ 2887,2903 },
+ [3018]={ 3014,3006 },
+ [3019]={ 3015,3006 },
+ [3020]={ 3014,3031 },
+ [3144]={ 3142,3158 },
+ [3264]={ 3263,3285 },
+ [3271]={ 3270,3285 },
+ [3272]={ 3270,3286 },
+ [3274]={ 3270,3266 },
+ [3275]={ 3274,3285 },
+ [3402]={ 3398,3390 },
+ [3403]={ 3399,3390 },
+ [3404]={ 3398,3415 },
+ },
+ ["vowel_modifier"]={
+ [2304]=true,
+ [2305]=true,
+ [2306]=true,
+ [2307]=true,
+ [2433]=true,
+ [3330]=true,
+ [3331]=true,
+ [4150]=true,
+ [4152]=true,
+ [4153]=true,
+ [4154]=true,
+ [43232]=true,
+ [43233]=true,
+ [43234]=true,
+ [43235]=true,
+ [43236]=true,
+ [43237]=true,
+ [43238]=true,
+ [43239]=true,
+ [43240]=true,
+ [43241]=true,
+ [43242]=true,
+ [43243]=true,
+ [43244]=true,
+ [43245]=true,
+ [43246]=true,
+ [43247]=true,
+ [43249]=true,
+ },
+}
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “basics-chrâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ini†4299a02110bbd7c0d27e131235c5319d] ---
+
+if not modules then modules={} end modules ['font-ini']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local allocate=utilities.storage.allocate
+local sortedhash=table.sortedhash
+fonts=fonts or {}
+local fonts=fonts
+local identifiers=allocate()
+fonts.hashes=fonts.hashes or { identifiers=identifiers }
+fonts.tables=fonts.tables or {}
+fonts.helpers=fonts.helpers or {}
+fonts.tracers=fonts.tracers or {}
+fonts.specifiers=fonts.specifiers or {}
+fonts.analyzers={}
+fonts.readers={}
+fonts.definers={ methods={} }
+fonts.loggers={ register=function() end }
+if context then
+ font.originaleach=font.each
+ function font.each()
+ return sortedhash(identifiers)
+ end
+ fontloader=nil
+end
+fonts.privateoffsets={
+ textbase=0xF0000,
+ textextrabase=0xFD000,
+ mathextrabase=0xFE000,
+ mathbase=0xFF000,
+ keepnames=false,
+}
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-iniâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-mis†bc9eb43c27f63ce9d0fff67e104fe1c6] ---
+
+if not modules then modules={} end modules ['luatex-font-mis']={
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+ os.exit()
+end
+local currentfont=font.current
+local hashes=fonts.hashes
+local identifiers=hashes.identifiers or {}
+local marks=hashes.marks or {}
+hashes.identifiers=identifiers
+hashes.marks=marks
+table.setmetatableindex(marks,function(t,k)
+ if k==true then
+ return marks[currentfont()]
+ else
+ local resources=identifiers[k].resources or {}
+ local marks=resources.marks or {}
+ t[k]=marks
+ return marks
+ end
+end)
+function font.each()
+ return table.sortedhash(fonts.hashes.identifiers)
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-misâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-con†ca733211a0555d9a93b1e2f7ebc937d3] ---
+
+if not modules then modules={} end modules ['font-con']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,tostring,tonumber,rawget=next,tostring,tonumber,rawget
+local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find
+local sort,insert,concat=table.sort,table.insert,table.concat
+local sortedkeys,sortedhash,serialize,fastcopy=table.sortedkeys,table.sortedhash,table.serialize,table.fastcopy
+local derivetable=table.derive
+local ioflush=io.flush
+local round=math.round
+local setmetatable,getmetatable,rawget,rawset=setmetatable,getmetatable,rawget,rawset
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end)
+local report_defining=logs.reporter("fonts","defining")
+local fonts=fonts
+local constructors=fonts.constructors or {}
+fonts.constructors=constructors
+local handlers=fonts.handlers or {}
+fonts.handlers=handlers
+local allocate=utilities.storage.allocate
+local setmetatableindex=table.setmetatableindex
+constructors.dontembed=allocate()
+constructors.autocleanup=true
+constructors.namemode="fullpath"
+constructors.version=1.01
+constructors.cache=containers.define("fonts","constructors",constructors.version,false)
+constructors.privateoffset=fonts.privateoffsets.textbase or 0xF0000
+constructors.cacheintex=true
+constructors.addtounicode=true
+local designsizes=allocate()
+constructors.designsizes=designsizes
+local loadedfonts=allocate()
+constructors.loadedfonts=loadedfonts
+local factors={
+ pt=65536.0,
+ bp=65781.8,
+}
+function constructors.setfactor(f)
+ constructors.factor=factors[f or 'pt'] or factors.pt
+end
+constructors.setfactor()
+function constructors.scaled(scaledpoints,designsize)
+ if scaledpoints<0 then
+ local factor=constructors.factor
+ if designsize then
+ if designsize>factor then
+ return (- scaledpoints/1000)*designsize
+ else
+ return (- scaledpoints/1000)*designsize*factor
+ end
+ else
+ return (- scaledpoints/1000)*10*factor
+ end
+ else
+ return scaledpoints
+ end
+end
+function constructors.getprivate(tfmdata)
+ local properties=tfmdata.properties
+ local private=properties.private
+ properties.private=private+1
+ return private
+end
+function constructors.setmathparameter(tfmdata,name,value)
+ local m=tfmdata.mathparameters
+ local c=tfmdata.MathConstants
+ if m then
+ m[name]=value
+ end
+ if c and c~=m then
+ c[name]=value
+ end
+end
+function constructors.getmathparameter(tfmdata,name)
+ local p=tfmdata.mathparameters or tfmdata.MathConstants
+ if p then
+ return p[name]
+ end
+end
+function constructors.cleanuptable(tfmdata)
+ if constructors.autocleanup and tfmdata.properties.virtualized then
+ for k,v in next,tfmdata.characters do
+ if v.commands then v.commands=nil end
+ end
+ end
+end
+function constructors.calculatescale(tfmdata,scaledpoints)
+ local parameters=tfmdata.parameters
+ if scaledpoints<0 then
+ scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize)
+ end
+ return scaledpoints,scaledpoints/(parameters.units or 1000)
+end
+local unscaled={
+ ScriptPercentScaleDown=true,
+ ScriptScriptPercentScaleDown=true,
+ RadicalDegreeBottomRaisePercent=true,
+ NoLimitSupFactor=true,
+ NoLimitSubFactor=true,
+}
+function constructors.assignmathparameters(target,original)
+ local mathparameters=original.mathparameters
+ if mathparameters and next(mathparameters) then
+ local targetparameters=target.parameters
+ local targetproperties=target.properties
+ local targetmathparameters={}
+ local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor
+ for name,value in next,mathparameters do
+ if unscaled[name] then
+ targetmathparameters[name]=value
+ else
+ targetmathparameters[name]=value*factor
+ end
+ end
+ if not targetmathparameters.FractionDelimiterSize then
+ targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size
+ end
+ if not mathparameters.FractionDelimiterDisplayStyleSize then
+ targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size
+ end
+ target.mathparameters=targetmathparameters
+ end
+end
+function constructors.beforecopyingcharacters(target,original)
+end
+function constructors.aftercopyingcharacters(target,original)
+end
+constructors.sharefonts=false
+constructors.nofsharedfonts=0
+local sharednames={}
+function constructors.trytosharefont(target,tfmdata)
+ if constructors.sharefonts then
+ local characters=target.characters
+ local n=1
+ local t={ target.psname }
+ local u=sortedkeys(characters)
+ for i=1,#u do
+ local k=u[i]
+ n=n+1;t[n]=k
+ n=n+1;t[n]=characters[k].index or k
+ end
+ local h=md5.HEX(concat(t," "))
+ local s=sharednames[h]
+ if s then
+ if trace_defining then
+ report_defining("font %a uses backend resources of font %a",target.fullname,s)
+ end
+ target.fullname=s
+ constructors.nofsharedfonts=constructors.nofsharedfonts+1
+ target.properties.sharedwith=s
+ else
+ sharednames[h]=target.fullname
+ end
+ end
+end
+local synonyms={
+ exheight="x_height",
+ xheight="x_height",
+ ex="x_height",
+ emwidth="quad",
+ em="quad",
+ spacestretch="space_stretch",
+ stretch="space_stretch",
+ spaceshrink="space_shrink",
+ shrink="space_shrink",
+ extraspace="extra_space",
+ xspace="extra_space",
+ slantperpoint="slant",
+}
+function constructors.enhanceparameters(parameters)
+ local mt=getmetatable(parameters)
+ local getter=function(t,k)
+ if not k then
+ return nil
+ end
+ local s=synonyms[k]
+ if s then
+ return rawget(t,s) or (mt and mt[s]) or nil
+ end
+ if k=="spacing" then
+ return {
+ width=t.space,
+ stretch=t.space_stretch,
+ shrink=t.space_shrink,
+ extra=t.extra_space,
+ }
+ end
+ return mt and mt[k] or nil
+ end
+ local setter=function(t,k,v)
+ if not k then
+ return 0
+ end
+ local s=synonyms[k]
+ if s then
+ rawset(t,s,v)
+ elseif k=="spacing" then
+ if type(v)=="table" then
+ rawset(t,"space",v.width or 0)
+ rawset(t,"space_stretch",v.stretch or 0)
+ rawset(t,"space_shrink",v.shrink or 0)
+ rawset(t,"extra_space",v.extra or 0)
+ end
+ else
+ rawset(t,k,v)
+ end
+ end
+ setmetatable(parameters,{
+ __index=getter,
+ __newindex=setter,
+ })
+end
+local function mathkerns(v,vdelta)
+ local k={}
+ for i=1,#v do
+ local entry=v[i]
+ local height=entry.height
+ local kern=entry.kern
+ k[i]={
+ height=height and vdelta*height or 0,
+ kern=kern and vdelta*kern or 0,
+ }
+ end
+ return k
+end
+local psfake=0
+local function fixedpsname(psname,fallback)
+ local usedname=psname
+ if psname and psname~="" then
+ if find(psname," ",1,true) then
+ usedname=gsub(psname,"[%s]+","-")
+ else
+ end
+ elseif not fallback or fallback=="" then
+ psfake=psfake+1
+ psname="fakename-"..psfake
+ else
+ psname=fallback
+ usedname=gsub(psname,"[^a-zA-Z0-9]+","-")
+ end
+ return usedname,psname~=usedname
+end
+function constructors.scale(tfmdata,specification)
+ local target={}
+ if tonumber(specification) then
+ specification={ size=specification }
+ end
+ target.specification=specification
+ local scaledpoints=specification.size
+ local relativeid=specification.relativeid
+ local properties=tfmdata.properties or {}
+ local goodies=tfmdata.goodies or {}
+ local resources=tfmdata.resources or {}
+ local descriptions=tfmdata.descriptions or {}
+ local characters=tfmdata.characters or {}
+ local changed=tfmdata.changed or {}
+ local shared=tfmdata.shared or {}
+ local parameters=tfmdata.parameters or {}
+ local mathparameters=tfmdata.mathparameters or {}
+ local targetcharacters={}
+ local targetdescriptions=derivetable(descriptions)
+ local targetparameters=derivetable(parameters)
+ local targetproperties=derivetable(properties)
+ local targetgoodies=goodies
+ target.characters=targetcharacters
+ target.descriptions=targetdescriptions
+ target.parameters=targetparameters
+ target.properties=targetproperties
+ target.goodies=targetgoodies
+ target.shared=shared
+ target.resources=resources
+ target.unscaled=tfmdata
+ local mathsize=tonumber(specification.mathsize) or 0
+ local textsize=tonumber(specification.textsize) or scaledpoints
+ local forcedsize=tonumber(parameters.mathsize ) or 0
+ local extrafactor=tonumber(specification.factor ) or 1
+ if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then
+ scaledpoints=parameters.scriptpercentage*textsize/100
+ elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then
+ scaledpoints=parameters.scriptscriptpercentage*textsize/100
+ elseif forcedsize>1000 then
+ scaledpoints=forcedsize
+ else
+ end
+ targetparameters.mathsize=mathsize
+ targetparameters.textsize=textsize
+ targetparameters.forcedsize=forcedsize
+ targetparameters.extrafactor=extrafactor
+ local addtounicode=constructors.addtounicode
+ local tounicode=fonts.mappings.tounicode
+ local unknowncode=tounicode(0xFFFD)
+ local defaultwidth=resources.defaultwidth or 0
+ local defaultheight=resources.defaultheight or 0
+ local defaultdepth=resources.defaultdepth or 0
+ local units=parameters.units or 1000
+ targetproperties.language=properties.language or "dflt"
+ targetproperties.script=properties.script or "dflt"
+ targetproperties.mode=properties.mode or "base"
+ local askedscaledpoints=scaledpoints
+ local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification)
+ local hdelta=delta
+ local vdelta=delta
+ target.designsize=parameters.designsize
+ target.units=units
+ target.units_per_em=units
+ local direction=properties.direction or tfmdata.direction or 0
+ target.direction=direction
+ properties.direction=direction
+ target.size=scaledpoints
+ target.encodingbytes=properties.encodingbytes or 1
+ target.embedding=properties.embedding or "subset"
+ target.tounicode=1
+ target.cidinfo=properties.cidinfo
+ target.format=properties.format
+ target.cache=constructors.cacheintex and "yes" or "renew"
+ local fontname=properties.fontname or tfmdata.fontname
+ local fullname=properties.fullname or tfmdata.fullname
+ local filename=properties.filename or tfmdata.filename
+ local psname=properties.psname or tfmdata.psname
+ local name=properties.name or tfmdata.name
+ local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename))
+ target.fontname=fontname
+ target.fullname=fullname
+ target.filename=filename
+ target.psname=psname
+ target.name=name
+ properties.fontname=fontname
+ properties.fullname=fullname
+ properties.filename=filename
+ properties.psname=psname
+ properties.name=name
+ local expansion=parameters.expansion
+ if expansion then
+ target.stretch=expansion.stretch
+ target.shrink=expansion.shrink
+ target.step=expansion.step
+ end
+ local slantfactor=parameters.slantfactor or 0
+ if slantfactor~=0 then
+ target.slant=slantfactor*1000
+ else
+ target.slant=0
+ end
+ local extendfactor=parameters.extendfactor or 0
+ if extendfactor~=0 and extendfactor~=1 then
+ hdelta=hdelta*extendfactor
+ target.extend=extendfactor*1000
+ else
+ target.extend=1000
+ end
+ local squeezefactor=parameters.squeezefactor or 0
+ if squeezefactor~=0 and squeezefactor~=1 then
+ vdelta=vdelta*squeezefactor
+ target.squeeze=squeezefactor*1000
+ else
+ target.squeeze=1000
+ end
+ local mode=parameters.mode or 0
+ if mode~=0 then
+ target.mode=mode
+ end
+ local width=parameters.width or 0
+ if width~=0 then
+ target.width=width*delta*1000/655360
+ end
+ targetparameters.factor=delta
+ targetparameters.hfactor=hdelta
+ targetparameters.vfactor=vdelta
+ targetparameters.size=scaledpoints
+ targetparameters.units=units
+ targetparameters.scaledpoints=askedscaledpoints
+ targetparameters.mode=mode
+ targetparameters.width=width
+ local isvirtual=properties.virtualized or tfmdata.type=="virtual"
+ local hasquality=parameters.expansion or parameters.protrusion
+ local hasitalics=properties.hasitalics
+ local autoitalicamount=properties.autoitalicamount
+ local stackmath=not properties.nostackmath
+ local haskerns=properties.haskerns or properties.mode=="base"
+ local hasligatures=properties.hasligatures or properties.mode=="base"
+ local realdimensions=properties.realdimensions
+ local writingmode=properties.writingmode or "horizontal"
+ local identity=properties.identity or "horizontal"
+ local vfonts=target.fonts
+ if vfonts and #vfonts>0 then
+ target.fonts=fastcopy(vfonts)
+ elseif isvirtual then
+ target.fonts={ { id=0 } }
+ end
+ if changed and not next(changed) then
+ changed=false
+ end
+ target.type=isvirtual and "virtual" or "real"
+ target.writingmode=writingmode=="vertical" and "vertical" or "horizontal"
+ target.identity=identity=="vertical" and "vertical" or "horizontal"
+ target.postprocessors=tfmdata.postprocessors
+ local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt
+ local targetspace=(parameters.space or parameters[2] or 0)*hdelta
+ local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta
+ local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta
+ local targetx_height=(parameters.x_height or parameters[5] or 0)*vdelta
+ local targetquad=(parameters.quad or parameters[6] or 0)*hdelta
+ local targetextra_space=(parameters.extra_space or parameters[7] or 0)*hdelta
+ targetparameters.slant=targetslant
+ targetparameters.space=targetspace
+ targetparameters.space_stretch=targetspace_stretch
+ targetparameters.space_shrink=targetspace_shrink
+ targetparameters.x_height=targetx_height
+ targetparameters.quad=targetquad
+ targetparameters.extra_space=targetextra_space
+ local ascender=parameters.ascender
+ if ascender then
+ targetparameters.ascender=delta*ascender
+ end
+ local descender=parameters.descender
+ if descender then
+ targetparameters.descender=delta*descender
+ end
+ constructors.enhanceparameters(targetparameters)
+ local protrusionfactor=(targetquad~=0 and 1000/targetquad) or 0
+ local scaledwidth=defaultwidth*hdelta
+ local scaledheight=defaultheight*vdelta
+ local scaleddepth=defaultdepth*vdelta
+ local hasmath=(properties.hasmath or next(mathparameters)) and true
+ if hasmath then
+ constructors.assignmathparameters(target,tfmdata)
+ properties.hasmath=true
+ target.nomath=false
+ target.MathConstants=target.mathparameters
+ else
+ properties.hasmath=false
+ target.nomath=true
+ target.mathparameters=nil
+ end
+ if hasmath then
+ local mathitalics=properties.mathitalics
+ if mathitalics==false then
+ if trace_defining then
+ report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename)
+ end
+ hasitalics=false
+ autoitalicamount=false
+ end
+ else
+ local textitalics=properties.textitalics
+ if textitalics==false then
+ if trace_defining then
+ report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename)
+ end
+ hasitalics=false
+ autoitalicamount=false
+ end
+ end
+ if trace_defining then
+ report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a",
+ name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta,
+ hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled")
+ end
+ constructors.beforecopyingcharacters(target,tfmdata)
+ local sharedkerns={}
+ for unicode,character in next,characters do
+ local chr,description,index
+ if changed then
+ local c=changed[unicode]
+ if c and c~=unicode then
+ if c then
+ description=descriptions[c] or descriptions[unicode] or character
+ character=characters[c] or character
+ index=description.index or c
+ else
+ description=descriptions[unicode] or character
+ index=description.index or unicode
+ end
+ else
+ description=descriptions[unicode] or character
+ index=description.index or unicode
+ end
+ else
+ description=descriptions[unicode] or character
+ index=description.index or unicode
+ end
+ local width=description.width
+ local height=description.height
+ local depth=description.depth
+ local isunicode=description.unicode
+ if realdimensions then
+ if not height or height==0 then
+ local bb=description.boundingbox
+ local ht=bb[4]
+ if ht~=0 then
+ height=ht
+ end
+ if not depth or depth==0 then
+ local dp=-bb[2]
+ if dp~=0 then
+ depth=dp
+ end
+ end
+ elseif not depth or depth==0 then
+ local dp=-description.boundingbox[2]
+ if dp~=0 then
+ depth=dp
+ end
+ end
+ end
+ if width then width=hdelta*width else width=scaledwidth end
+ if height then height=vdelta*height else height=scaledheight end
+ if depth and depth~=0 then
+ depth=delta*depth
+ if isunicode then
+ chr={
+ index=index,
+ height=height,
+ depth=depth,
+ width=width,
+ unicode=isunicode,
+ }
+ else
+ chr={
+ index=index,
+ height=height,
+ depth=depth,
+ width=width,
+ }
+ end
+ else
+ if isunicode then
+ chr={
+ index=index,
+ height=height,
+ width=width,
+ unicode=isunicode,
+ }
+ else
+ chr={
+ index=index,
+ height=height,
+ width=width,
+ }
+ end
+ end
+ if addtounicode then
+ chr.tounicode=isunicode and tounicode(isunicode) or unknowncode
+ end
+ if hasquality then
+ local ve=character.expansion_factor
+ if ve then
+ chr.expansion_factor=ve*1000
+ end
+ local vl=character.left_protruding
+ if vl then
+ chr.left_protruding=protrusionfactor*width*vl
+ end
+ local vr=character.right_protruding
+ if vr then
+ chr.right_protruding=protrusionfactor*width*vr
+ end
+ end
+ if hasmath then
+ local vn=character.next
+ if vn then
+ chr.next=vn
+ else
+ local vv=character.vert_variants
+ if vv then
+ local t={}
+ for i=1,#vv do
+ local vvi=vv[i]
+ local s=vvi["start"] or 0
+ local e=vvi["end"] or 0
+ local a=vvi["advance"] or 0
+ t[i]={
+ ["start"]=s==0 and 0 or s*vdelta,
+ ["end"]=e==0 and 0 or e*vdelta,
+ ["advance"]=a==0 and 0 or a*vdelta,
+ ["extender"]=vvi["extender"],
+ ["glyph"]=vvi["glyph"],
+ }
+ end
+ chr.vert_variants=t
+ else
+ local hv=character.horiz_variants
+ if hv then
+ local t={}
+ for i=1,#hv do
+ local hvi=hv[i]
+ local s=hvi["start"] or 0
+ local e=hvi["end"] or 0
+ local a=hvi["advance"] or 0
+ t[i]={
+ ["start"]=s==0 and 0 or s*hdelta,
+ ["end"]=e==0 and 0 or e*hdelta,
+ ["advance"]=a==0 and 0 or a*hdelta,
+ ["extender"]=hvi["extender"],
+ ["glyph"]=hvi["glyph"],
+ }
+ end
+ chr.horiz_variants=t
+ end
+ end
+ end
+ local vi=character.vert_italic
+ if vi and vi~=0 then
+ chr.vert_italic=vi*hdelta
+ end
+ local va=character.accent
+ if va then
+ chr.top_accent=vdelta*va
+ end
+ if stackmath then
+ local mk=character.mathkerns
+ if mk then
+ local tr=mk.topright
+ local tl=mk.topleft
+ local br=mk.bottomright
+ local bl=mk.bottomleft
+ chr.mathkern={
+ top_right=tr and mathkerns(tr,vdelta) or nil,
+ top_left=tl and mathkerns(tl,vdelta) or nil,
+ bottom_right=br and mathkerns(br,vdelta) or nil,
+ bottom_left=bl and mathkerns(bl,vdelta) or nil,
+ }
+ end
+ end
+ if hasitalics then
+ local vi=character.italic
+ if vi and vi~=0 then
+ chr.italic=vi*hdelta
+ end
+ end
+ elseif autoitalicamount then
+ local vi=description.italic
+ if not vi then
+ local bb=description.boundingbox
+ if bb then
+ local vi=bb[3]-description.width+autoitalicamount
+ if vi>0 then
+ chr.italic=vi*hdelta
+ end
+ else
+ end
+ elseif vi~=0 then
+ chr.italic=vi*hdelta
+ end
+ elseif hasitalics then
+ local vi=character.italic
+ if vi and vi~=0 then
+ chr.italic=vi*hdelta
+ end
+ end
+ if haskerns then
+ local vk=character.kerns
+ if vk then
+ local s=sharedkerns[vk]
+ if not s then
+ s={}
+ for k,v in next,vk do s[k]=v*hdelta end
+ sharedkerns[vk]=s
+ end
+ chr.kerns=s
+ end
+ end
+ if hasligatures then
+ local vl=character.ligatures
+ if vl then
+ if true then
+ chr.ligatures=vl
+ else
+ local tt={}
+ for i,l in next,vl do
+ tt[i]=l
+ end
+ chr.ligatures=tt
+ end
+ end
+ end
+ if isvirtual then
+ local vc=character.commands
+ if vc then
+ local ok=false
+ for i=1,#vc do
+ local key=vc[i][1]
+ if key=="right" or key=="down" or key=="rule" then
+ ok=true
+ break
+ end
+ end
+ if ok then
+ local tt={}
+ for i=1,#vc do
+ local ivc=vc[i]
+ local key=ivc[1]
+ if key=="right" then
+ tt[i]={ key,ivc[2]*hdelta }
+ elseif key=="down" then
+ tt[i]={ key,ivc[2]*vdelta }
+ elseif key=="rule" then
+ tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta }
+ else
+ tt[i]=ivc
+ end
+ end
+ chr.commands=tt
+ else
+ chr.commands=vc
+ end
+ end
+ end
+ targetcharacters[unicode]=chr
+ end
+ properties.setitalics=hasitalics
+ constructors.aftercopyingcharacters(target,tfmdata)
+ constructors.trytosharefont(target,tfmdata)
+ local vfonts=target.fonts
+ if isvirtual or target.type=="virtual" or properties.virtualized then
+ properties.virtualized=true
+ target.type="virtual"
+ if not vfonts or #vfonts==0 then
+ target.fonts={ { id=0 } }
+ end
+ elseif vfonts then
+ properties.virtualized=true
+ target.type="virtual"
+ if #vfonts==0 then
+ target.fonts={ { id=0 } }
+ end
+ end
+ return target
+end
+function constructors.finalize(tfmdata)
+ if tfmdata.properties and tfmdata.properties.finalized then
+ return
+ end
+ if not tfmdata.characters then
+ return nil
+ end
+ if not tfmdata.goodies then
+ tfmdata.goodies={}
+ end
+ local parameters=tfmdata.parameters
+ if not parameters then
+ return nil
+ end
+ if not parameters.expansion then
+ parameters.expansion={
+ stretch=tfmdata.stretch or 0,
+ shrink=tfmdata.shrink or 0,
+ step=tfmdata.step or 0,
+ }
+ end
+ if not parameters.size then
+ parameters.size=tfmdata.size
+ end
+ if not parameters.mode then
+ parameters.mode=0
+ end
+ if not parameters.width then
+ parameters.width=0
+ end
+ if not parameters.slantfactor then
+ parameters.slantfactor=(tfmdata.slant or 0)/1000
+ end
+ if not parameters.extendfactor then
+ parameters.extendfactor=(tfmdata.extend or 1000)/1000
+ end
+ if not parameters.squeezefactor then
+ parameters.squeezefactor=(tfmdata.squeeze or 1000)/1000
+ end
+ local designsize=parameters.designsize
+ if designsize then
+ parameters.minsize=tfmdata.minsize or designsize
+ parameters.maxsize=tfmdata.maxsize or designsize
+ else
+ designsize=factors.pt*10
+ parameters.designsize=designsize
+ parameters.minsize=designsize
+ parameters.maxsize=designsize
+ end
+ parameters.minsize=tfmdata.minsize or parameters.designsize
+ parameters.maxsize=tfmdata.maxsize or parameters.designsize
+ if not parameters.units then
+ parameters.units=tfmdata.units or tfmdata.units_per_em or 1000
+ end
+ if not tfmdata.descriptions then
+ local descriptions={}
+ setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end)
+ tfmdata.descriptions=descriptions
+ end
+ local properties=tfmdata.properties
+ if not properties then
+ properties={}
+ tfmdata.properties=properties
+ end
+ if not properties.virtualized then
+ properties.virtualized=tfmdata.type=="virtual"
+ end
+ properties.fontname=properties.fontname or tfmdata.fontname
+ properties.filename=properties.filename or tfmdata.filename
+ properties.fullname=properties.fullname or tfmdata.fullname
+ properties.name=properties.name or tfmdata.name
+ properties.psname=properties.psname or tfmdata.psname
+ properties.encodingbytes=tfmdata.encodingbytes or 1
+ properties.embedding=tfmdata.embedding or "subset"
+ properties.tounicode=tfmdata.tounicode or 1
+ properties.cidinfo=tfmdata.cidinfo or nil
+ properties.format=tfmdata.format or "type1"
+ properties.direction=tfmdata.direction or 0
+ properties.writingmode=tfmdata.writingmode or "horizontal"
+ properties.identity=tfmdata.identity or "horizontal"
+ properties.usedbitmap=tfmdata.usedbitmap
+ if not tfmdata.resources then
+ tfmdata.resources={}
+ end
+ if not tfmdata.shared then
+ tfmdata.shared={}
+ end
+ if not properties.hasmath then
+ properties.hasmath=not tfmdata.nomath
+ end
+ tfmdata.MathConstants=nil
+ tfmdata.postprocessors=nil
+ tfmdata.fontname=nil
+ tfmdata.filename=nil
+ tfmdata.fullname=nil
+ tfmdata.name=nil
+ tfmdata.psname=nil
+ tfmdata.encodingbytes=nil
+ tfmdata.embedding=nil
+ tfmdata.tounicode=nil
+ tfmdata.cidinfo=nil
+ tfmdata.format=nil
+ tfmdata.direction=nil
+ tfmdata.type=nil
+ tfmdata.nomath=nil
+ tfmdata.designsize=nil
+ tfmdata.size=nil
+ tfmdata.stretch=nil
+ tfmdata.shrink=nil
+ tfmdata.step=nil
+ tfmdata.slant=nil
+ tfmdata.extend=nil
+ tfmdata.squeeze=nil
+ tfmdata.mode=nil
+ tfmdata.width=nil
+ tfmdata.units=nil
+ tfmdata.units_per_em=nil
+ tfmdata.cache=nil
+ properties.finalized=true
+ return tfmdata
+end
+local hashmethods={}
+constructors.hashmethods=hashmethods
+function constructors.hashfeatures(specification)
+ local features=specification.features
+ if features then
+ local t,n={},0
+ for category,list in sortedhash(features) do
+ if next(list) then
+ local hasher=hashmethods[category]
+ if hasher then
+ local hash=hasher(list)
+ if hash then
+ n=n+1
+ t[n]=category..":"..hash
+ end
+ end
+ end
+ end
+ if n>0 then
+ return concat(t," & ")
+ end
+ end
+ return "unknown"
+end
+hashmethods.normal=function(list)
+ local s={}
+ local n=0
+ for k,v in next,list do
+ if not k then
+ elseif k=="number" or k=="features" then
+ else
+ n=n+1
+ if type(v)=="table" then
+ local t={}
+ local m=0
+ for k,v in next,v do
+ m=m+1
+ t[m]=k..'='..tostring(v)
+ end
+ s[n]=k..'={'..concat(t,",").."}"
+ else
+ s[n]=k..'='..tostring(v)
+ end
+ end
+ end
+ if n>0 then
+ sort(s)
+ return concat(s,"+")
+ end
+end
+function constructors.hashinstance(specification,force)
+ local hash=specification.hash
+ local size=specification.size
+ local fallbacks=specification.fallbacks
+ if force or not hash then
+ hash=constructors.hashfeatures(specification)
+ specification.hash=hash
+ end
+ if size<1000 and designsizes[hash] then
+ size=round(constructors.scaled(size,designsizes[hash]))
+ else
+ size=round(size)
+ end
+ specification.size=size
+ if fallbacks then
+ return hash..' @ '..size..' @ '..fallbacks
+ else
+ return hash..' @ '..size
+ end
+end
+function constructors.setname(tfmdata,specification)
+ if constructors.namemode=="specification" then
+ local specname=specification.specification
+ if specname then
+ tfmdata.properties.name=specname
+ if trace_defining then
+ report_otf("overloaded fontname %a",specname)
+ end
+ end
+ end
+end
+function constructors.checkedfilename(data)
+ local foundfilename=data.foundfilename
+ if not foundfilename then
+ local askedfilename=data.filename or ""
+ if askedfilename~="" then
+ askedfilename=resolvers.resolve(askedfilename)
+ foundfilename=resolvers.findbinfile(askedfilename,"") or ""
+ if foundfilename=="" then
+ report_defining("source file %a is not found",askedfilename)
+ foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or ""
+ if foundfilename~="" then
+ report_defining("using source file %a due to cache mismatch",foundfilename)
+ end
+ end
+ end
+ data.foundfilename=foundfilename
+ end
+ return foundfilename
+end
+local formats=allocate()
+fonts.formats=formats
+setmetatableindex(formats,function(t,k)
+ local l=lower(k)
+ if rawget(t,k) then
+ t[k]=l
+ return l
+ end
+ return rawget(t,file.suffix(l))
+end)
+do
+ local function setindeed(mode,source,target,group,name,position)
+ local action=source[mode]
+ if not action then
+ return
+ end
+ local t=target[mode]
+ if not t then
+ report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode)
+ os.exit()
+ elseif position then
+ insert(t,position,{ name=name,action=action })
+ else
+ for i=1,#t do
+ local ti=t[i]
+ if ti.name==name then
+ ti.action=action
+ return
+ end
+ end
+ insert(t,{ name=name,action=action })
+ end
+ end
+ local function set(group,name,target,source)
+ target=target[group]
+ if not target then
+ report_defining("fatal target error in setting feature %a, group %a",name,group)
+ os.exit()
+ end
+ local source=source[group]
+ if not source then
+ report_defining("fatal source error in setting feature %a, group %a",name,group)
+ os.exit()
+ end
+ local position=source.position
+ setindeed("node",source,target,group,name,position)
+ setindeed("base",source,target,group,name,position)
+ setindeed("plug",source,target,group,name,position)
+ end
+ local function register(where,specification)
+ local name=specification.name
+ if name and name~="" then
+ local default=specification.default
+ local description=specification.description
+ local initializers=specification.initializers
+ local processors=specification.processors
+ local manipulators=specification.manipulators
+ local modechecker=specification.modechecker
+ if default then
+ where.defaults[name]=default
+ end
+ if description and description~="" then
+ where.descriptions[name]=description
+ end
+ if initializers then
+ set('initializers',name,where,specification)
+ end
+ if processors then
+ set('processors',name,where,specification)
+ end
+ if manipulators then
+ set('manipulators',name,where,specification)
+ end
+ if modechecker then
+ where.modechecker=modechecker
+ end
+ end
+ end
+ constructors.registerfeature=register
+ function constructors.getfeatureaction(what,where,mode,name)
+ what=handlers[what].features
+ if what then
+ where=what[where]
+ if where then
+ mode=where[mode]
+ if mode then
+ for i=1,#mode do
+ local m=mode[i]
+ if m.name==name then
+ return m.action
+ end
+ end
+ end
+ end
+ end
+ end
+ local newfeatures={}
+ constructors.newfeatures=newfeatures
+ constructors.features=newfeatures
+ local function setnewfeatures(what)
+ local handler=handlers[what]
+ local features=handler.features
+ if not features then
+ local tables=handler.tables
+ local statistics=handler.statistics
+ features=allocate {
+ defaults={},
+ descriptions=tables and tables.features or {},
+ used=statistics and statistics.usedfeatures or {},
+ initializers={ base={},node={},plug={} },
+ processors={ base={},node={},plug={} },
+ manipulators={ base={},node={},plug={} },
+ }
+ features.register=function(specification) return register(features,specification) end
+ handler.features=features
+ end
+ return features
+ end
+ setmetatable(newfeatures,{
+ __call=function(t,k) local v=t[k] return v end,
+ __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end,
+ })
+end
+do
+ local newhandler={}
+ constructors.handlers=newhandler
+ constructors.newhandler=newhandler
+ local function setnewhandler(what)
+ local handler=handlers[what]
+ if not handler then
+ handler={}
+ handlers[what]=handler
+ end
+ return handler
+ end
+ setmetatable(newhandler,{
+ __call=function(t,k) local v=t[k] return v end,
+ __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end,
+ })
+end
+do
+ local newenhancer={}
+ constructors.enhancers=newenhancer
+ constructors.newenhancer=newenhancer
+ local function setnewenhancer(format)
+ local handler=handlers[format]
+ local enhancers=handler.enhancers
+ if not enhancers then
+ local actions=allocate()
+ local before=allocate()
+ local after=allocate()
+ local order=allocate()
+ local known={}
+ local nofsteps=0
+ local patches={ before=before,after=after }
+ local trace=false
+ local report=logs.reporter("fonts",format.." enhancing")
+ trackers.register(format..".loading",function(v) trace=v end)
+ local function enhance(name,data,filename,raw)
+ local enhancer=actions[name]
+ if enhancer then
+ if trace then
+ report("apply enhancement %a to file %a",name,filename)
+ ioflush()
+ end
+ enhancer(data,filename,raw)
+ else
+ end
+ end
+ local function apply(data,filename,raw)
+ local basename=file.basename(lower(filename))
+ if trace then
+ report("%s enhancing file %a","start",filename)
+ end
+ ioflush()
+ for e=1,nofsteps do
+ local enhancer=order[e]
+ local b=before[enhancer]
+ if b then
+ for pattern,action in next,b do
+ if find(basename,pattern) then
+ action(data,filename,raw)
+ end
+ end
+ end
+ enhance(enhancer,data,filename,raw)
+ local a=after[enhancer]
+ if a then
+ for pattern,action in next,a do
+ if find(basename,pattern) then
+ action(data,filename,raw)
+ end
+ end
+ end
+ ioflush()
+ end
+ if trace then
+ report("%s enhancing file %a","stop",filename)
+ end
+ ioflush()
+ end
+ local function register(what,action)
+ if action then
+ if actions[what] then
+ else
+ nofsteps=nofsteps+1
+ order[nofsteps]=what
+ known[what]=nofsteps
+ end
+ actions[what]=action
+ else
+ report("bad enhancer %a",what)
+ end
+ end
+ local function patch(what,where,pattern,action)
+ local pw=patches[what]
+ if pw then
+ local ww=pw[where]
+ if ww then
+ ww[pattern]=action
+ else
+ pw[where]={ [pattern]=action }
+ if not known[where] then
+ nofsteps=nofsteps+1
+ order[nofsteps]=where
+ known[where]=nofsteps
+ end
+ end
+ end
+ end
+ enhancers={
+ register=register,
+ apply=apply,
+ patch=patch,
+ report=report,
+ patches={
+ register=patch,
+ report=report,
+ },
+ }
+ handler.enhancers=enhancers
+ end
+ return enhancers
+ end
+ setmetatable(newenhancer,{
+ __call=function(t,k) local v=t[k] return v end,
+ __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end,
+ })
+end
+function constructors.checkedfeatures(what,features)
+ local defaults=handlers[what].features.defaults
+ if features and next(features) then
+ features=fastcopy(features)
+ for key,value in next,defaults do
+ if features[key]==nil then
+ features[key]=value
+ end
+ end
+ return features
+ else
+ return fastcopy(defaults)
+ end
+end
+function constructors.initializefeatures(what,tfmdata,features,trace,report)
+ if features and next(features) then
+ local properties=tfmdata.properties or {}
+ local whathandler=handlers[what]
+ local whatfeatures=whathandler.features
+ local whatmodechecker=whatfeatures.modechecker
+ local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base"
+ properties.mode=mode
+ features.mode=mode
+ local done={}
+ while true do
+ local redo=false
+ local initializers=whatfeatures.initializers[mode]
+ if initializers then
+ for i=1,#initializers do
+ local step=initializers[i]
+ local feature=step.name
+ local value=features[feature]
+ if not value then
+ elseif done[feature] then
+ else
+ local action=step.action
+ if trace then
+ report("initializing feature %a to %a for mode %a for font %a",feature,
+ value,mode,tfmdata.properties.fullname)
+ end
+ action(tfmdata,value,features)
+ if mode~=properties.mode or mode~=features.mode then
+ if whatmodechecker then
+ properties.mode=whatmodechecker(tfmdata,features,properties.mode)
+ features.mode=properties.mode
+ end
+ if mode~=properties.mode then
+ mode=properties.mode
+ redo=true
+ end
+ end
+ done[feature]=true
+ end
+ if redo then
+ break
+ end
+ end
+ if not redo then
+ break
+ end
+ else
+ break
+ end
+ end
+ properties.mode=mode
+ return true
+ else
+ return false
+ end
+end
+function constructors.collectprocessors(what,tfmdata,features,trace,report)
+ local processes={}
+ local nofprocesses=0
+ if features and next(features) then
+ local properties=tfmdata.properties
+ local whathandler=handlers[what]
+ local whatfeatures=whathandler.features
+ local whatprocessors=whatfeatures.processors
+ local mode=properties.mode
+ local processors=whatprocessors[mode]
+ if processors then
+ for i=1,#processors do
+ local step=processors[i]
+ local feature=step.name
+ if features[feature] then
+ local action=step.action
+ if trace then
+ report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname)
+ end
+ if action then
+ nofprocesses=nofprocesses+1
+ processes[nofprocesses]=action
+ end
+ end
+ end
+ elseif trace then
+ report("no feature processors for mode %a for font %a",mode,properties.fullname)
+ end
+ end
+ return processes
+end
+function constructors.applymanipulators(what,tfmdata,features,trace,report)
+ if features and next(features) then
+ local properties=tfmdata.properties
+ local whathandler=handlers[what]
+ local whatfeatures=whathandler.features
+ local whatmanipulators=whatfeatures.manipulators
+ local mode=properties.mode
+ local manipulators=whatmanipulators[mode]
+ if manipulators then
+ for i=1,#manipulators do
+ local step=manipulators[i]
+ local feature=step.name
+ local value=features[feature]
+ if value then
+ local action=step.action
+ if trace then
+ report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname)
+ end
+ if action then
+ action(tfmdata,feature,value)
+ end
+ end
+ end
+ end
+ end
+end
+function constructors.addcoreunicodes(unicodes)
+ if not unicodes then
+ unicodes={}
+ end
+ unicodes.space=0x0020
+ unicodes.hyphen=0x002D
+ unicodes.zwj=0x200D
+ unicodes.zwnj=0x200C
+ return unicodes
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-conâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-enc†3e71a54297e8f85a1ac438bb0f20dd79] ---
+
+if not modules then modules={} end modules ['luatex-font-enc']={
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+ os.exit()
+end
+local fonts=fonts
+local encodings={}
+fonts.encodings=encodings
+encodings.agl={}
+encodings.known={}
+setmetatable(encodings.agl,{ __index=function(t,k)
+ if k=="unicodes" then
+ logs.report("fonts","loading (extended) adobe glyph list")
+ local unicodes=dofile(resolvers.findfile("font-age.lua"))
+ encodings.agl={ unicodes=unicodes }
+ return unicodes
+ else
+ return nil
+ end
+end })
+encodings.cache=containers.define("fonts","enc",encodings.version,true)
+function encodings.load(filename)
+ local name=file.removesuffix(filename)
+ local data=containers.read(encodings.cache,name)
+ if data then
+ return data
+ end
+ local vector,tag,hash,unicodes={},"",{},{}
+ local foundname=resolvers.findfile(filename,'enc')
+ if foundname and foundname~="" then
+ local ok,encoding,size=resolvers.loadbinfile(foundname)
+ if ok and encoding then
+ encoding=string.gsub(encoding,"%%(.-)\n","")
+ local unicoding=encodings.agl.unicodes
+ local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def")
+ local i=0
+ for ch in string.gmatch(vec,"/([%a%d%.]+)") do
+ if ch~=".notdef" then
+ vector[i]=ch
+ if not hash[ch] then
+ hash[ch]=i
+ else
+ end
+ local u=unicoding[ch]
+ if u then
+ unicodes[u]=i
+ end
+ end
+ i=i+1
+ end
+ end
+ end
+ local data={
+ name=name,
+ tag=tag,
+ vector=vector,
+ hash=hash,
+ unicodes=unicodes
+ }
+ return containers.write(encodings.cache,name,data)
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-encâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-cid†4d87988efa86020a14708ee03c23415f] ---
+
+if not modules then modules={} end modules ['font-cid']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local format,match,lower=string.format,string.match,string.lower
+local tonumber=tonumber
+local P,S,R,C,V,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.match
+local fonts,logs,trackers=fonts,logs,trackers
+local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
+local report_otf=logs.reporter("fonts","otf loading")
+local cid={}
+fonts.cid=cid
+local cidmap={}
+local cidmax=10
+local number=C(R("09","af","AF")^1)
+local space=S(" \n\r\t")
+local spaces=space^0
+local period=P(".")
+local periods=period*period
+local name=P("/")*C((1-space)^1)
+local unicodes,names={},{}
+local function do_one(a,b)
+ unicodes[tonumber(a)]=tonumber(b,16)
+end
+local function do_range(a,b,c)
+ c=tonumber(c,16)
+ for i=tonumber(a),tonumber(b) do
+ unicodes[i]=c
+ c=c+1
+ end
+end
+local function do_name(a,b)
+ names[tonumber(a)]=b
+end
+local grammar=P { "start",
+ start=number*spaces*number*V("series"),
+ series=(spaces*(V("one")+V("range")+V("named")))^1,
+ one=(number*spaces*number)/do_one,
+ range=(number*periods*number*spaces*number)/do_range,
+ named=(number*spaces*name)/do_name
+}
+local function loadcidfile(filename)
+ local data=io.loaddata(filename)
+ if data then
+ unicodes,names={},{}
+ lpegmatch(grammar,data)
+ local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$")
+ return {
+ supplement=supplement,
+ registry=registry,
+ ordering=ordering,
+ filename=filename,
+ unicodes=unicodes,
+ names=names,
+ }
+ end
+end
+cid.loadfile=loadcidfile
+local template="%s-%s-%s.cidmap"
+local function locate(registry,ordering,supplement)
+ local filename=format(template,registry,ordering,supplement)
+ local hashname=lower(filename)
+ local found=cidmap[hashname]
+ if not found then
+ if trace_loading then
+ report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename)
+ end
+ local fullname=resolvers.findfile(filename,'cid') or ""
+ if fullname~="" then
+ found=loadcidfile(fullname)
+ if found then
+ if trace_loading then
+ report_otf("using cidmap file %a",filename)
+ end
+ cidmap[hashname]=found
+ found.usedname=file.basename(filename)
+ end
+ end
+ end
+ return found
+end
+function cid.getmap(specification)
+ if not specification then
+ report_otf("invalid cidinfo specification, table expected")
+ return
+ end
+ local registry=specification.registry
+ local ordering=specification.ordering
+ local supplement=specification.supplement
+ local filename=format(registry,ordering,supplement)
+ local lowername=lower(filename)
+ local found=cidmap[lowername]
+ if found then
+ return found
+ end
+ if ordering=="Identity" then
+ local found={
+ supplement=supplement,
+ registry=registry,
+ ordering=ordering,
+ filename=filename,
+ unicodes={},
+ names={},
+ }
+ cidmap[lowername]=found
+ return found
+ end
+ if trace_loading then
+ report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement)
+ end
+ found=locate(registry,ordering,supplement)
+ if not found then
+ local supnum=tonumber(supplement)
+ local cidnum=nil
+ if supnum<cidmax then
+ for s=supnum+1,cidmax do
+ local c=locate(registry,ordering,s)
+ if c then
+ found,cidnum=c,s
+ break
+ end
+ end
+ end
+ if not found and supnum>0 then
+ for s=supnum-1,0,-1 do
+ local c=locate(registry,ordering,s)
+ if c then
+ found,cidnum=c,s
+ break
+ end
+ end
+ end
+ registry=lower(registry)
+ ordering=lower(ordering)
+ if found and cidnum>0 then
+ for s=0,cidnum-1 do
+ local filename=format(template,registry,ordering,s)
+ if not cidmap[filename] then
+ cidmap[filename]=found
+ end
+ end
+ end
+ end
+ return found
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-cidâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-map†f486746e90fe972de4b73e208ac7cbb2] ---
+
+if not modules then modules={} end modules ['font-map']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local tonumber,next,type=tonumber,next,type
+local match,format,find,concat,gsub,lower=string.match,string.format,string.find,table.concat,string.gsub,string.lower
+local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match
+local formatters=string.formatters
+local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
+local rshift=bit32.rshift
+local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end)
+local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end)
+local report_fonts=logs.reporter("fonts","loading")
+local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end)
+local fonts=fonts or {}
+local mappings=fonts.mappings or {}
+fonts.mappings=mappings
+local allocate=utilities.storage.allocate
+local hex=R("AF","af","09")
+local hexfour=(hex*hex*hex^-2)/function(s) return tonumber(s,16) end
+local hexsix=(hex*hex*hex^-4)/function(s) return tonumber(s,16) end
+local dec=(R("09")^1)/tonumber
+local period=P(".")
+local unicode=(P("uni")+P("UNI"))*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true))
+local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true))
+local index=P("index")*dec*Cc(false)
+local parser=unicode+ucode+index
+local parsers={}
+local function makenameparser(str)
+ if not str or str=="" then
+ return parser
+ else
+ local p=parsers[str]
+ if not p then
+ p=P(str)*period*dec*Cc(false)
+ parsers[str]=p
+ end
+ return p
+ end
+end
+local f_single=formatters["%04X"]
+local f_double=formatters["%04X%04X"]
+local function tounicode16(unicode)
+ if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then
+ return f_single(unicode)
+ else
+ unicode=unicode-0x10000
+ return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+ end
+end
+local function tounicode16sequence(unicodes)
+ local t={}
+ for l=1,#unicodes do
+ local u=unicodes[l]
+ if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then
+ t[l]=f_single(u)
+ else
+ u=u-0x10000
+ t[l]=f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
+ end
+ end
+ return concat(t)
+end
+local unknown=f_single(0xFFFD)
+local hash={}
+local conc={}
+table.setmetatableindex(hash,function(t,k)
+ if k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then
+ v=f_single(k)
+ else
+ local k=k-0x10000
+ v=f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
+ end
+ t[k]=v
+ return v
+end)
+local function tounicode(k)
+ if type(k)=="table" then
+ local n=#k
+ for l=1,n do
+ conc[l]=hash[k[l]]
+ end
+ return concat(conc,"",1,n)
+ elseif k>=0x00E000 and k<=0x00F8FF then
+ return unknown
+ elseif k>=0x0F0000 and k<=0x0FFFFF then
+ return unknown
+ elseif k>=0x100000 and k<=0x10FFFF then
+ return unknown
+ else
+ return hash[k]
+ end
+end
+local function fromunicode16(str)
+ if #str==4 then
+ return tonumber(str,16)
+ else
+ local l,r=match(str,"(....)(....)")
+ return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00
+ end
+end
+mappings.makenameparser=makenameparser
+mappings.tounicode=tounicode
+mappings.tounicode16=tounicode16
+mappings.tounicode16sequence=tounicode16sequence
+mappings.fromunicode16=fromunicode16
+local ligseparator=P("_")
+local varseparator=P(".")
+local namesplitter=Ct(C((1-ligseparator-varseparator)^1)*(ligseparator*C((1-ligseparator-varseparator)^1))^0)
+do
+ local overloads={
+ IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 },
+ ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 },
+ ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 },
+ fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 },
+ fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 },
+ ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 },
+ ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 },
+ fj={ name="f_j",unicode={ 0x66,0x6A } },
+ fk={ name="f_k",unicode={ 0x66,0x6B } },
+ }
+ local o=allocate {}
+ for k,v in next,overloads do
+ local name=v.name
+ local mess=v.mess
+ if name then
+ o[name]=v
+ end
+ if mess then
+ o[mess]=v
+ end
+ o[k]=v
+ end
+ mappings.overloads=o
+end
+function mappings.addtounicode(data,filename,checklookups,forceligatures)
+ local resources=data.resources
+ local unicodes=resources.unicodes
+ if not unicodes then
+ if trace_mapping then
+ report_fonts("no unicode list, quitting tounicode for %a",filename)
+ end
+ return
+ end
+ local properties=data.properties
+ local descriptions=data.descriptions
+ local overloads=mappings.overloads
+ unicodes['space']=unicodes['space'] or 32
+ unicodes['hyphen']=unicodes['hyphen'] or 45
+ unicodes['zwj']=unicodes['zwj'] or 0x200D
+ unicodes['zwnj']=unicodes['zwnj'] or 0x200C
+ local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+ local unicodevector=fonts.encodings.agl.unicodes or {}
+ local contextvector=fonts.encodings.agl.ctxcodes or {}
+ local missing={}
+ local nofmissing=0
+ local oparser=nil
+ local cidnames=nil
+ local cidcodes=nil
+ local cidinfo=properties.cidinfo
+ local usedmap=cidinfo and fonts.cid.getmap(cidinfo)
+ local uparser=makenameparser()
+ if usedmap then
+ oparser=usedmap and makenameparser(cidinfo.ordering)
+ cidnames=usedmap.names
+ cidcodes=usedmap.unicodes
+ end
+ local ns=0
+ local nl=0
+ local dlist=sortedkeys(descriptions)
+ for i=1,#dlist do
+ local du=dlist[i]
+ local glyph=descriptions[du]
+ local name=glyph.name
+ if name then
+ local overload=overloads[name] or overloads[du]
+ if overload then
+ glyph.unicode=overload.unicode
+ else
+ local gu=glyph.unicode
+ if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then
+ local unicode=unicodevector[name] or contextvector[name]
+ if unicode then
+ glyph.unicode=unicode
+ ns=ns+1
+ end
+ if (not unicode) and usedmap then
+ local foundindex=lpegmatch(oparser,name)
+ if foundindex then
+ unicode=cidcodes[foundindex]
+ if unicode then
+ glyph.unicode=unicode
+ ns=ns+1
+ else
+ local reference=cidnames[foundindex]
+ if reference then
+ local foundindex=lpegmatch(oparser,reference)
+ if foundindex then
+ unicode=cidcodes[foundindex]
+ if unicode then
+ glyph.unicode=unicode
+ ns=ns+1
+ end
+ end
+ if not unicode or unicode=="" then
+ local foundcodes,multiple=lpegmatch(uparser,reference)
+ if foundcodes then
+ glyph.unicode=foundcodes
+ if multiple then
+ nl=nl+1
+ unicode=true
+ else
+ ns=ns+1
+ unicode=foundcodes
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if not unicode or unicode=="" then
+ local split=lpegmatch(namesplitter,name)
+ local nsplit=split and #split or 0
+ if nsplit==0 then
+ elseif nsplit==1 then
+ local base=split[1]
+ local u=unicodes[base] or unicodevector[base] or contextvector[name]
+ if not u then
+ elseif type(u)=="table" then
+ if u[1]<private then
+ unicode=u
+ glyph.unicode=unicode
+ end
+ elseif u<private then
+ unicode=u
+ glyph.unicode=unicode
+ end
+ else
+ local t={}
+ local n=0
+ for l=1,nsplit do
+ local base=split[l]
+ local u=unicodes[base] or unicodevector[base] or contextvector[name]
+ if not u then
+ break
+ elseif type(u)=="table" then
+ if u[1]>=private then
+ break
+ end
+ n=n+1
+ t[n]=u[1]
+ else
+ if u>=private then
+ break
+ end
+ n=n+1
+ t[n]=u
+ end
+ end
+ if n>0 then
+ if n==1 then
+ unicode=t[1]
+ else
+ unicode=t
+ end
+ glyph.unicode=unicode
+ end
+ end
+ nl=nl+1
+ end
+ if not unicode or unicode=="" then
+ local foundcodes,multiple=lpegmatch(uparser,name)
+ if foundcodes then
+ glyph.unicode=foundcodes
+ if multiple then
+ nl=nl+1
+ unicode=true
+ else
+ ns=ns+1
+ unicode=foundcodes
+ end
+ end
+ end
+ local r=overloads[unicode]
+ if r then
+ unicode=r.unicode
+ glyph.unicode=unicode
+ end
+ if not unicode then
+ missing[du]=true
+ nofmissing=nofmissing+1
+ end
+ else
+ end
+ end
+ else
+ local overload=overloads[du]
+ if overload then
+ glyph.unicode=overload.unicode
+ elseif not glyph.unicode then
+ missing[du]=true
+ nofmissing=nofmissing+1
+ end
+ end
+ end
+ if type(checklookups)=="function" then
+ checklookups(data,missing,nofmissing)
+ end
+ local unicoded=0
+ local collected=fonts.handlers.otf.readers.getcomponents(data)
+ local function resolve(glyph,u)
+ local n=#u
+ for i=1,n do
+ if u[i]>private then
+ n=0
+ break
+ end
+ end
+ if n>0 then
+ if n>1 then
+ glyph.unicode=u
+ else
+ glyph.unicode=u[1]
+ end
+ unicoded=unicoded+1
+ end
+ end
+ if not collected then
+ elseif forceligatures or force_ligatures then
+ for i=1,#dlist do
+ local du=dlist[i]
+ if du>=private or (du>=0xE000 and du<=0xF8FF) then
+ local u=collected[du]
+ if u then
+ resolve(descriptions[du],u)
+ end
+ end
+ end
+ else
+ for i=1,#dlist do
+ local du=dlist[i]
+ if du>=private or (du>=0xE000 and du<=0xF8FF) then
+ local glyph=descriptions[du]
+ if glyph.class=="ligature" and not glyph.unicode then
+ local u=collected[du]
+ if u then
+ resolve(glyph,u)
+ end
+ end
+ end
+ end
+ end
+ if trace_mapping and unicoded>0 then
+ report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded)
+ end
+ if trace_mapping then
+ for i=1,#dlist do
+ local du=dlist[i]
+ local glyph=descriptions[du]
+ local name=glyph.name or "-"
+ local index=glyph.index or 0
+ local unicode=glyph.unicode
+ if unicode then
+ if type(unicode)=="table" then
+ local unicodes={}
+ for i=1,#unicode do
+ unicodes[i]=formatters("%U",unicode[i])
+ end
+ report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes)
+ else
+ report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode)
+ end
+ else
+ report_fonts("internal slot %U, name %a, unicode %U",index,name,du)
+ end
+ end
+ end
+ if trace_loading and (ns>0 or nl>0) then
+ report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns)
+ end
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-mapâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-vfc†94937140f2c909e9c831ba021f1ab303] ---
+
+if not modules then modules={} end modules ['font-vfc']={
+ version=1.001,
+ comment="companion to font-ini.mkiv and hand-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local select,type=select,type
+local insert=table.insert
+local fonts=fonts
+local helpers=fonts.helpers
+local setmetatableindex=table.setmetatableindex
+local makeweak=table.makeweak
+local push={ "push" }
+local pop={ "pop" }
+local dummy={ "comment" }
+function helpers.prependcommands(commands,...)
+ insert(commands,1,push)
+ for i=select("#",...),1,-1 do
+ local s=(select(i,...))
+ if s then
+ insert(commands,1,s)
+ end
+ end
+ insert(commands,pop)
+ return commands
+end
+function helpers.appendcommands(commands,...)
+ insert(commands,1,push)
+ insert(commands,pop)
+ for i=1,select("#",...) do
+ local s=(select(i,...))
+ if s then
+ insert(commands,s)
+ end
+ end
+ return commands
+end
+function helpers.prependcommandtable(commands,t)
+ insert(commands,1,push)
+ for i=#t,1,-1 do
+ local s=t[i]
+ if s then
+ insert(commands,1,s)
+ end
+ end
+ insert(commands,pop)
+ return commands
+end
+function helpers.appendcommandtable(commands,t)
+ insert(commands,1,push)
+ insert(commands,pop)
+ for i=1,#t do
+ local s=t[i]
+ if s then
+ insert(commands,s)
+ end
+ end
+ return commands
+end
+local char=setmetatableindex(function(t,k)
+ local v={ "slot",0,k }
+ t[k]=v
+ return v
+end)
+local right=setmetatableindex(function(t,k)
+ local v={ "right",k }
+ t[k]=v
+ return v
+end)
+local left=setmetatableindex(function(t,k)
+ local v={ "right",-k }
+ t[k]=v
+ return v
+end)
+local down=setmetatableindex(function(t,k)
+ local v={ "down",k }
+ t[k]=v
+ return v
+end)
+local up=setmetatableindex(function(t,k)
+ local v={ "down",-k }
+ t[k]=v
+ return v
+end)
+helpers.commands=utilities.storage.allocate {
+ char=char,
+ right=right,
+ left=left,
+ down=down,
+ up=up,
+ push=push,
+ pop=pop,
+ dummy=dummy,
+}
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-vfcâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otr†b1c03925c949027c86f781785fa7a208] ---
+
+if not modules then modules={} end modules ['font-otr']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type,tonumber=next,type,tonumber
+local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub
+local fullstrip=string.fullstrip
+local floor,round=math.floor,math.round
+local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt
+local lpegmatch=lpeg.match
+local rshift=bit32.rshift
+local setmetatableindex=table.setmetatableindex
+local sortedkeys=table.sortedkeys
+local sortedhash=table.sortedhash
+local stripstring=string.nospaces
+local utf16_to_utf8_be=utf.utf16_to_utf8_be
+local report=logs.reporter("otf reader")
+local report_cmap=logs.reporter("otf reader","cmap")
+local trace_cmap=false trackers.register("otf.cmap",function(v) trace_cmap=v end)
+local trace_cmap_details=false trackers.register("otf.cmap.details",function(v) trace_cmap_details=v end)
+fonts=fonts or {}
+local handlers=fonts.handlers or {}
+fonts.handlers=handlers
+local otf=handlers.otf or {}
+handlers.otf=otf
+local readers=otf.readers or {}
+otf.readers=readers
+local streamreader=utilities.files
+local streamwriter=utilities.files
+readers.streamreader=streamreader
+readers.streamwriter=streamwriter
+local openfile=streamreader.open
+local closefile=streamreader.close
+local setposition=streamreader.setposition
+local skipshort=streamreader.skipshort
+local readbytes=streamreader.readbytes
+local readstring=streamreader.readstring
+local readbyte=streamreader.readcardinal1
+local readushort=streamreader.readcardinal2
+local readuint=streamreader.readcardinal3
+local readulong=streamreader.readcardinal4
+local readshort=streamreader.readinteger2
+local readlong=streamreader.readinteger4
+local readfixed=streamreader.readfixed4
+local read2dot14=streamreader.read2dot14
+local readfword=readshort
+local readufword=readushort
+local readoffset=readushort
+local readcardinaltable=streamreader.readcardinaltable
+local readintegertable=streamreader.readintegertable
+function streamreader.readtag(f)
+ return lower(stripstring(readstring(f,4)))
+end
+local short=2
+local ushort=2
+local ulong=4
+directives.register("fonts.streamreader",function()
+ streamreader=utilities.streams
+ openfile=streamreader.open
+ closefile=streamreader.close
+ setposition=streamreader.setposition
+ skipshort=streamreader.skipshort
+ readbytes=streamreader.readbytes
+ readstring=streamreader.readstring
+ readbyte=streamreader.readcardinal1
+ readushort=streamreader.readcardinal2
+ readuint=streamreader.readcardinal3
+ readulong=streamreader.readcardinal4
+ readshort=streamreader.readinteger2
+ readlong=streamreader.readinteger4
+ readfixed=streamreader.readfixed4
+ read2dot14=streamreader.read2dot14
+ readfword=readshort
+ readufword=readushort
+ readoffset=readushort
+ readcardinaltable=streamreader.readcardinaltable
+ readintegertable=streamreader.readintegertable
+ function streamreader.readtag(f)
+ return lower(stripstring(readstring(f,4)))
+ end
+end)
+local function readlongdatetime(f)
+ local a,b,c,d,e,f,g,h=readbytes(f,8)
+ return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+end
+local tableversion=0.004
+readers.tableversion=tableversion
+local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+local reservednames={ [0]="copyright",
+ "family",
+ "subfamily",
+ "uniqueid",
+ "fullname",
+ "version",
+ "postscriptname",
+ "trademark",
+ "manufacturer",
+ "designer",
+ "description",
+ "vendorurl",
+ "designerurl",
+ "license",
+ "licenseurl",
+ "reserved",
+ "typographicfamily",
+ "typographicsubfamily",
+ "compatiblefullname",
+ "sampletext",
+ "cidfindfontname",
+ "wwsfamily",
+ "wwssubfamily",
+ "lightbackgroundpalette",
+ "darkbackgroundpalette",
+ "variationspostscriptnameprefix",
+}
+local platforms={ [0]="unicode",
+ "macintosh",
+ "iso",
+ "windows",
+ "custom",
+}
+local encodings={
+ unicode={ [0]="unicode 1.0 semantics",
+ "unicode 1.1 semantics",
+ "iso/iec 10646",
+ "unicode 2.0 bmp",
+ "unicode 2.0 full",
+ "unicode variation sequences",
+ "unicode full repertoire",
+ },
+ macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian",
+ "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada",
+ "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian",
+ "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi",
+ "uninterpreted",
+ },
+ iso={ [0]="7-bit ascii",
+ "iso 10646",
+ "iso 8859-1",
+ },
+ windows={ [0]="symbol",
+ "unicode bmp",
+ "shiftjis",
+ "prc",
+ "big5",
+ "wansung",
+ "johab",
+ "reserved 7",
+ "reserved 8",
+ "reserved 9",
+ "unicode ucs-4",
+ },
+ custom={
+ }
+}
+local decoders={
+ unicode={},
+ macintosh={},
+ iso={},
+ windows={
+ ["unicode semantics"]=utf16_to_utf8_be,
+ ["unicode bmp"]=utf16_to_utf8_be,
+ ["unicode full"]=utf16_to_utf8_be,
+ ["unicode 1.0 semantics"]=utf16_to_utf8_be,
+ ["unicode 1.1 semantics"]=utf16_to_utf8_be,
+ ["unicode 2.0 bmp"]=utf16_to_utf8_be,
+ ["unicode 2.0 full"]=utf16_to_utf8_be,
+ ["unicode variation sequences"]=utf16_to_utf8_be,
+ ["unicode full repertoire"]=utf16_to_utf8_be,
+ },
+ custom={},
+}
+local languages={
+ unicode={
+ [ 0]="english",
+ },
+ macintosh={
+ [ 0]="english",
+ },
+ iso={},
+ windows={
+ [0x0409]="english - united states",
+ },
+ custom={},
+}
+local standardromanencoding={ [0]=
+ "notdef",".null","nonmarkingreturn","space","exclam","quotedbl",
+ "numbersign","dollar","percent","ampersand","quotesingle","parenleft",
+ "parenright","asterisk","plus","comma","hyphen","period","slash",
+ "zero","one","two","three","four","five","six","seven","eight",
+ "nine","colon","semicolon","less","equal","greater","question","at",
+ "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O",
+ "P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft",
+ "backslash","bracketright","asciicircum","underscore","grave","a","b",
+ "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q",
+ "r","s","t","u","v","w","x","y","z","braceleft","bar",
+ "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute",
+ "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex",
+ "adieresis","atilde","aring","ccedilla","eacute","egrave",
+ "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis",
+ "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute",
+ "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling",
+ "section","bullet","paragraph","germandbls","registered","copyright",
+ "trademark","acute","dieresis","notequal","AE","Oslash","infinity",
+ "plusminus","lessequal","greaterequal","yen","mu","partialdiff",
+ "summation","product","pi","integral","ordfeminine","ordmasculine",
+ "Omega","ae","oslash","questiondown","exclamdown","logicalnot",
+ "radical","florin","approxequal","Delta","guillemotleft",
+ "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde",
+ "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright",
+ "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis",
+ "fraction","currency","guilsinglleft","guilsinglright","fi","fl",
+ "daggerdbl","periodcentered","quotesinglbase","quotedblbase",
+ "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave",
+ "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex",
+ "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi",
+ "circumflex","tilde","macron","breve","dotaccent","ring","cedilla",
+ "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron",
+ "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn",
+ "thorn","minus","multiply","onesuperior","twosuperior","threesuperior",
+ "onehalf","onequarter","threequarters","franc","Gbreve","gbreve",
+ "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron",
+ "dcroat",
+}
+local weights={
+ [100]="thin",
+ [200]="extralight",
+ [300]="light",
+ [400]="normal",
+ [500]="medium",
+ [600]="semibold",
+ [700]="bold",
+ [800]="extrabold",
+ [900]="black",
+}
+local widths={
+ [1]="ultracondensed",
+ [2]="extracondensed",
+ [3]="condensed",
+ [4]="semicondensed",
+ [5]="normal",
+ [6]="semiexpanded",
+ [7]="expanded",
+ [8]="extraexpanded",
+ [9]="ultraexpanded",
+}
+setmetatableindex(weights,function(t,k)
+ local r=floor((k+50)/100)*100
+ local v=(r>900 and "black") or rawget(t,r) or "normal"
+ return v
+end)
+setmetatableindex(widths,function(t,k)
+ return "normal"
+end)
+local panoseweights={
+ [ 0]="normal",
+ [ 1]="normal",
+ [ 2]="verylight",
+ [ 3]="light",
+ [ 4]="thin",
+ [ 5]="book",
+ [ 6]="medium",
+ [ 7]="demi",
+ [ 8]="bold",
+ [ 9]="heavy",
+ [10]="black",
+}
+local panosewidths={
+ [ 0]="normal",
+ [ 1]="normal",
+ [ 2]="normal",
+ [ 3]="normal",
+ [ 4]="normal",
+ [ 5]="expanded",
+ [ 6]="condensed",
+ [ 7]="veryexpanded",
+ [ 8]="verycondensed",
+ [ 9]="monospaced",
+}
+local helpers={}
+readers.helpers=helpers
+local function gotodatatable(f,fontdata,tag,criterium)
+ if criterium and f then
+ local tables=fontdata.tables
+ if tables then
+ local datatable=tables[tag]
+ if datatable then
+ local tableoffset=datatable.offset
+ setposition(f,tableoffset)
+ return tableoffset
+ end
+ else
+ report("no tables")
+ end
+ end
+end
+local function reportskippedtable(f,fontdata,tag,criterium)
+ if criterium and f then
+ local tables=fontdata.tables
+ if tables then
+ local datatable=tables[tag]
+ if datatable then
+ report("loading of table %a skipped",tag)
+ end
+ else
+ report("no tables")
+ end
+ end
+end
+local function setvariabledata(fontdata,tag,data)
+ local variabledata=fontdata.variabledata
+ if variabledata then
+ variabledata[tag]=data
+ else
+ fontdata.variabledata={ [tag]=data }
+ end
+end
+helpers.gotodatatable=gotodatatable
+helpers.setvariabledata=setvariabledata
+helpers.reportskippedtable=reportskippedtable
+local platformnames={
+ postscriptname=true,
+ fullname=true,
+ family=true,
+ subfamily=true,
+ typographicfamily=true,
+ typographicsubfamily=true,
+ compatiblefullname=true,
+}
+local platformextras={
+ uniqueid=true,
+ version=true,
+ copyright=true,
+ license=true,
+ licenseurl=true,
+ manufacturer=true,
+ vendorurl=true,
+}
+function readers.name(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"name",true)
+ if tableoffset then
+ local format=readushort(f)
+ local nofnames=readushort(f)
+ local offset=readushort(f)
+ local start=tableoffset+offset
+ local namelists={
+ unicode={},
+ windows={},
+ macintosh={},
+ }
+ for i=1,nofnames do
+ local platform=platforms[readushort(f)]
+ if platform then
+ local namelist=namelists[platform]
+ if namelist then
+ local encoding=readushort(f)
+ local language=readushort(f)
+ local encodings=encodings[platform]
+ local languages=languages[platform]
+ if encodings and languages then
+ local encoding=encodings[encoding]
+ local language=languages[language]
+ if encoding and language then
+ local index=readushort(f)
+ local name=reservednames[index]
+ namelist[#namelist+1]={
+ platform=platform,
+ encoding=encoding,
+ language=language,
+ name=name,
+ index=index,
+ length=readushort(f),
+ offset=start+readushort(f),
+ }
+ else
+ skipshort(f,3)
+ end
+ else
+ skipshort(f,3)
+ end
+ else
+ skipshort(f,5)
+ end
+ else
+ skipshort(f,5)
+ end
+ end
+ local names={}
+ local done={}
+ local extras={}
+ local function decoded(platform,encoding,content)
+ local decoder=decoders[platform]
+ if decoder then
+ decoder=decoder[encoding]
+ end
+ if decoder then
+ return decoder(content)
+ else
+ return content
+ end
+ end
+ local function filter(platform,e,l)
+ local namelist=namelists[platform]
+ for i=1,#namelist do
+ local name=namelist[i]
+ local nametag=name.name
+ local index=name.index
+ if not done[nametag or i] then
+ local encoding=name.encoding
+ local language=name.language
+ if (not e or encoding==e) and (not l or language==l) then
+ setposition(f,name.offset)
+ local content=decoded(platform,encoding,readstring(f,name.length))
+ if nametag then
+ names[nametag]={
+ content=content,
+ platform=platform,
+ encoding=encoding,
+ language=language,
+ }
+ end
+ extras[index]=content
+ done[nametag or i]=true
+ end
+ end
+ end
+ end
+ filter("windows","unicode bmp","english - united states")
+ filter("macintosh","roman","english")
+ filter("windows")
+ filter("macintosh")
+ filter("unicode")
+ fontdata.names=names
+ fontdata.extras=extras
+ if specification.platformnames then
+ local collected={}
+ local platformextras=specification.platformextras and platformextras
+ for platform,namelist in next,namelists do
+ local filtered=false
+ for i=1,#namelist do
+ local entry=namelist[i]
+ local name=entry.name
+ if platformnames[name] or (platformextras and platformextras[name]) then
+ setposition(f,entry.offset)
+ local content=decoded(platform,entry.encoding,readstring(f,entry.length))
+ if filtered then
+ filtered[name]=content
+ else
+ filtered={ [name]=content }
+ end
+ end
+ end
+ if filtered then
+ collected[platform]=filtered
+ end
+ end
+ fontdata.platformnames=collected
+ end
+ else
+ fontdata.names={}
+ end
+end
+local validutf=lpeg.patterns.validutf8
+local function getname(fontdata,key)
+ local names=fontdata.names
+ if names then
+ local value=names[key]
+ if value then
+ local content=value.content
+ return lpegmatch(validutf,content) and content or nil
+ end
+ end
+end
+readers["os/2"]=function(f,fontdata)
+ local tableoffset=gotodatatable(f,fontdata,"os/2",true)
+ if tableoffset then
+ local version=readushort(f)
+ local windowsmetrics={
+ version=version,
+ averagewidth=readshort(f),
+ weightclass=readushort(f),
+ widthclass=readushort(f),
+ fstype=readushort(f),
+ subscriptxsize=readshort(f),
+ subscriptysize=readshort(f),
+ subscriptxoffset=readshort(f),
+ subscriptyoffset=readshort(f),
+ superscriptxsize=readshort(f),
+ superscriptysize=readshort(f),
+ superscriptxoffset=readshort(f),
+ superscriptyoffset=readshort(f),
+ strikeoutsize=readshort(f),
+ strikeoutpos=readshort(f),
+ familyclass=readshort(f),
+ panose={ readbytes(f,10) },
+ unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) },
+ vendor=readstring(f,4),
+ fsselection=readushort(f),
+ firstcharindex=readushort(f),
+ lastcharindex=readushort(f),
+ typoascender=readshort(f),
+ typodescender=readshort(f),
+ typolinegap=readshort(f),
+ winascent=readushort(f),
+ windescent=readushort(f),
+ }
+ if version>=1 then
+ windowsmetrics.codepageranges={ readulong(f),readulong(f) }
+ end
+ if version>=2 then
+ windowsmetrics.xheight=readshort(f)
+ windowsmetrics.capheight=readshort(f)
+ windowsmetrics.defaultchar=readushort(f)
+ windowsmetrics.breakchar=readushort(f)
+ end
+ windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass]
+ windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass]
+ windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]]
+ windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]]
+ fontdata.windowsmetrics=windowsmetrics
+ else
+ fontdata.windowsmetrics={}
+ end
+end
+readers.head=function(f,fontdata)
+ local tableoffset=gotodatatable(f,fontdata,"head",true)
+ if tableoffset then
+ local version=readulong(f)
+ local fontversion=readulong(f)
+ local fontheader={
+ version=version,
+ fontversion=number.to16dot16(fontversion),
+ fontversionnumber=fontversion,
+ checksum=readushort(f)*0x10000+readushort(f),
+ magic=readulong(f),
+ flags=readushort(f),
+ units=readushort(f),
+ created=readlongdatetime(f),
+ modified=readlongdatetime(f),
+ xmin=readshort(f),
+ ymin=readshort(f),
+ xmax=readshort(f),
+ ymax=readshort(f),
+ macstyle=readushort(f),
+ smallpixels=readushort(f),
+ directionhint=readshort(f),
+ indextolocformat=readshort(f),
+ glyphformat=readshort(f),
+ }
+ fontdata.fontheader=fontheader
+ else
+ fontdata.fontheader={}
+ end
+ fontdata.nofglyphs=0
+end
+readers.hhea=function(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details)
+ if tableoffset then
+ fontdata.horizontalheader={
+ version=readulong(f),
+ ascender=readfword(f),
+ descender=readfword(f),
+ linegap=readfword(f),
+ maxadvancewidth=readufword(f),
+ minleftsidebearing=readfword(f),
+ minrightsidebearing=readfword(f),
+ maxextent=readfword(f),
+ caretsloperise=readshort(f),
+ caretsloperun=readshort(f),
+ caretoffset=readshort(f),
+ reserved_1=readshort(f),
+ reserved_2=readshort(f),
+ reserved_3=readshort(f),
+ reserved_4=readshort(f),
+ metricdataformat=readshort(f),
+ nofmetrics=readushort(f),
+ }
+ else
+ fontdata.horizontalheader={
+ nofmetrics=0,
+ }
+ end
+end
+readers.vhea=function(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details)
+ if tableoffset then
+ fontdata.verticalheader={
+ version=readulong(f),
+ ascender=readfword(f),
+ descender=readfword(f),
+ linegap=readfword(f),
+ maxadvanceheight=readufword(f),
+ mintopsidebearing=readfword(f),
+ minbottomsidebearing=readfword(f),
+ maxextent=readfword(f),
+ caretsloperise=readshort(f),
+ caretsloperun=readshort(f),
+ caretoffset=readshort(f),
+ reserved_1=readshort(f),
+ reserved_2=readshort(f),
+ reserved_3=readshort(f),
+ reserved_4=readshort(f),
+ metricdataformat=readshort(f),
+ nofmetrics=readushort(f),
+ }
+ else
+ fontdata.verticalheader={
+ nofmetrics=0,
+ }
+ end
+end
+readers.maxp=function(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details)
+ if tableoffset then
+ local version=readulong(f)
+ local nofglyphs=readushort(f)
+ fontdata.nofglyphs=nofglyphs
+ if version==0x00005000 then
+ fontdata.maximumprofile={
+ version=version,
+ nofglyphs=nofglyphs,
+ }
+ elseif version==0x00010000 then
+ fontdata.maximumprofile={
+ version=version,
+ nofglyphs=nofglyphs,
+ points=readushort(f),
+ contours=readushort(f),
+ compositepoints=readushort(f),
+ compositecontours=readushort(f),
+ zones=readushort(f),
+ twilightpoints=readushort(f),
+ storage=readushort(f),
+ functiondefs=readushort(f),
+ instructiondefs=readushort(f),
+ stackelements=readushort(f),
+ sizeofinstructions=readushort(f),
+ componentelements=readushort(f),
+ componentdepth=readushort(f),
+ }
+ else
+ fontdata.maximumprofile={
+ version=version,
+ nofglyphs=0,
+ }
+ end
+ end
+end
+readers.hmtx=function(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs)
+ if tableoffset then
+ local horizontalheader=fontdata.horizontalheader
+ local nofmetrics=horizontalheader.nofmetrics
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs
+ local width=0
+ local leftsidebearing=0
+ for i=0,nofmetrics-1 do
+ local glyph=glyphs[i]
+ width=readshort(f)
+ leftsidebearing=readshort(f)
+ if width~=0 then
+ glyph.width=width
+ end
+ end
+ for i=nofmetrics,nofglyphs-1 do
+ local glyph=glyphs[i]
+ if width~=0 then
+ glyph.width=width
+ end
+ end
+ end
+end
+readers.vmtx=function(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs)
+ if tableoffset then
+ local verticalheader=fontdata.verticalheader
+ local nofmetrics=verticalheader.nofmetrics
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs
+ local vheight=0
+ local vdefault=verticalheader.ascender-verticalheader.descender
+ local topsidebearing=0
+ for i=0,nofmetrics-1 do
+ local glyph=glyphs[i]
+ vheight=readushort(f)
+ topsidebearing=readshort(f)
+ if vheight~=0 and vheight~=vdefault then
+ glyph.vheight=vheight
+ end
+ if topsidebearing~=0 then
+ glyph.tsb=topsidebearing
+ end
+ end
+ for i=nofmetrics,nofglyphs-1 do
+ local glyph=glyphs[i]
+ if vheight~=0 and vheight~=vdefault then
+ glyph.vheight=vheight
+ end
+ end
+ end
+end
+readers.vorg=function(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"vorg",specification.glyphs)
+end
+readers.post=function(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"post",true)
+ if tableoffset then
+ local version=readulong(f)
+ fontdata.postscript={
+ version=version,
+ italicangle=round(1000*readfixed(f))/1000,
+ underlineposition=readfword(f),
+ underlinethickness=readfword(f),
+ monospaced=readulong(f),
+ minmemtype42=readulong(f),
+ maxmemtype42=readulong(f),
+ minmemtype1=readulong(f),
+ maxmemtype1=readulong(f),
+ }
+ if not specification.glyphs then
+ elseif version==0x00010000 then
+ for index=0,#standardromanencoding do
+ glyphs[index].name=standardromanencoding[index]
+ end
+ elseif version==0x00020000 then
+ local glyphs=fontdata.glyphs
+ local nofglyphs=readushort(f)
+ local indices={}
+ local names={}
+ local maxnames=0
+ for i=0,nofglyphs-1 do
+ local nameindex=readushort(f)
+ if nameindex>=258 then
+ maxnames=maxnames+1
+ nameindex=nameindex-257
+ indices[nameindex]=i
+ else
+ glyphs[i].name=standardromanencoding[nameindex]
+ end
+ end
+ for i=1,maxnames do
+ local mapping=indices[i]
+ if not mapping then
+ report("quit post name fetching at %a of %a: %s",i,maxnames,"no index")
+ break
+ else
+ local length=readbyte(f)
+ if length>0 then
+ glyphs[mapping].name=readstring(f,length)
+ else
+ report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow")
+ break
+ end
+ end
+ end
+ end
+ else
+ fontdata.postscript={}
+ end
+end
+readers.cff=function(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cff",specification.glyphs)
+end
+local formatreaders={}
+local duplicatestoo=true
+local sequence={
+ { 3,1,4 },
+ { 3,10,12 },
+ { 0,3,4 },
+ { 0,3,12 },
+ { 0,1,4 },
+ { 0,1,12 },
+ { 0,0,6 },
+ { 3,0,6 },
+ { 3,0,4 },
+ { 0,5,14 },
+ { 0,4,12 },
+ { 3,10,13 },
+}
+local supported={}
+for i=1,#sequence do
+ local si=sequence[i]
+ local sp,se,sf=si[1],si[2],si[3]
+ local p=supported[sp]
+ if not p then
+ p={}
+ supported[sp]=p
+ end
+ local e=p[se]
+ if not e then
+ e={}
+ p[se]=e
+ end
+ e[sf]=true
+end
+formatreaders[4]=function(f,fontdata,offset)
+ setposition(f,offset+2)
+ local length=readushort(f)
+ local language=readushort(f)
+ local nofsegments=readushort(f)/2
+ skipshort(f,3)
+ local mapping=fontdata.mapping
+ local glyphs=fontdata.glyphs
+ local duplicates=fontdata.duplicates
+ local nofdone=0
+ local endchars=readcardinaltable(f,nofsegments,ushort)
+ local reserved=readushort(f)
+ local startchars=readcardinaltable(f,nofsegments,ushort)
+ local deltas=readcardinaltable(f,nofsegments,ushort)
+ local offsets=readcardinaltable(f,nofsegments,ushort)
+ local size=(length-2*2-5*2-4*2*nofsegments)/2
+ local indices=readcardinaltable(f,size-1,ushort)
+ for segment=1,nofsegments do
+ local startchar=startchars[segment]
+ local endchar=endchars[segment]
+ local offset=offsets[segment]
+ local delta=deltas[segment]
+ if startchar==0xFFFF and endchar==0xFFFF then
+ elseif startchar==0xFFFF and offset==0 then
+ elseif offset==0xFFFF then
+ elseif offset==0 then
+ if trace_cmap_details then
+ report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536)
+ end
+ for unicode=startchar,endchar do
+ local index=(unicode+delta)%65536
+ if index and index>0 then
+ local glyph=glyphs[index]
+ if glyph then
+ local gu=glyph.unicode
+ if not gu then
+ glyph.unicode=unicode
+ nofdone=nofdone+1
+ elseif gu~=unicode then
+ if duplicatestoo then
+ local d=duplicates[gu]
+ if d then
+ d[unicode]=true
+ else
+ duplicates[gu]={ [unicode]=true }
+ end
+ else
+ report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name)
+ end
+ end
+ if not mapping[index] then
+ mapping[index]=unicode
+ end
+ end
+ end
+ end
+ else
+ local shift=(segment-nofsegments+offset/2)-startchar
+ if trace_cmap_details then
+ report_cmap("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536)
+ end
+ for unicode=startchar,endchar do
+ local slot=shift+unicode
+ local index=indices[slot]
+ if index and index>0 then
+ index=(index+delta)%65536
+ local glyph=glyphs[index]
+ if glyph then
+ local gu=glyph.unicode
+ if not gu then
+ glyph.unicode=unicode
+ nofdone=nofdone+1
+ elseif gu~=unicode then
+ if duplicatestoo then
+ local d=duplicates[gu]
+ if d then
+ d[unicode]=true
+ else
+ duplicates[gu]={ [unicode]=true }
+ end
+ else
+ report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name)
+ end
+ end
+ if not mapping[index] then
+ mapping[index]=unicode
+ end
+ end
+ end
+ end
+ end
+ end
+ return nofdone
+end
+formatreaders[6]=function(f,fontdata,offset)
+ setposition(f,offset)
+ local format=readushort(f)
+ local length=readushort(f)
+ local language=readushort(f)
+ local mapping=fontdata.mapping
+ local glyphs=fontdata.glyphs
+ local duplicates=fontdata.duplicates
+ local start=readushort(f)
+ local count=readushort(f)
+ local stop=start+count-1
+ local nofdone=0
+ if trace_cmap_details then
+ report_cmap("format 6 from %C to %C",2,start,stop)
+ end
+ for unicode=start,stop do
+ local index=readushort(f)
+ if index>0 then
+ local glyph=glyphs[index]
+ if glyph then
+ local gu=glyph.unicode
+ if not gu then
+ glyph.unicode=unicode
+ nofdone=nofdone+1
+ elseif gu~=unicode then
+ end
+ if not mapping[index] then
+ mapping[index]=unicode
+ end
+ end
+ end
+ end
+ return nofdone
+end
+formatreaders[12]=function(f,fontdata,offset)
+ setposition(f,offset+2+2+4+4)
+ local mapping=fontdata.mapping
+ local glyphs=fontdata.glyphs
+ local duplicates=fontdata.duplicates
+ local nofgroups=readulong(f)
+ local nofdone=0
+ for i=1,nofgroups do
+ local first=readulong(f)
+ local last=readulong(f)
+ local index=readulong(f)
+ if trace_cmap_details then
+ report_cmap("format 12 from %C to %C starts at index %i",first,last,index)
+ end
+ for unicode=first,last do
+ local glyph=glyphs[index]
+ if glyph then
+ local gu=glyph.unicode
+ if not gu then
+ glyph.unicode=unicode
+ nofdone=nofdone+1
+ elseif gu~=unicode then
+ local d=duplicates[gu]
+ if d then
+ d[unicode]=true
+ else
+ duplicates[gu]={ [unicode]=true }
+ end
+ end
+ if not mapping[index] then
+ mapping[index]=unicode
+ end
+ end
+ index=index+1
+ end
+ end
+ return nofdone
+end
+formatreaders[13]=function(f,fontdata,offset)
+ setposition(f,offset+2+2+4+4)
+ local mapping=fontdata.mapping
+ local glyphs=fontdata.glyphs
+ local duplicates=fontdata.duplicates
+ local nofgroups=readulong(f)
+ local nofdone=0
+ for i=1,nofgroups do
+ local first=readulong(f)
+ local last=readulong(f)
+ local index=readulong(f)
+ if first<privateoffset then
+ if trace_cmap_details then
+ report_cmap("format 13 from %C to %C get index %i",first,last,index)
+ end
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=first
+ glyph.unicode=unicode
+ first=first+1
+ end
+ local list=duplicates[unicode]
+ mapping[index]=unicode
+ if not list then
+ list={}
+ duplicates[unicode]=list
+ end
+ if last>=privateoffset then
+ local limit=privateoffset-1
+ report("format 13 from %C to %C pruned to %C",first,last,limit)
+ last=limit
+ end
+ for unicode=first,last do
+ list[unicode]=true
+ end
+ nofdone=nofdone+last-first+1
+ else
+ report("format 13 from %C to %C ignored",first,last)
+ end
+ end
+ return nofdone
+end
+formatreaders[14]=function(f,fontdata,offset)
+ if offset and offset~=0 then
+ setposition(f,offset)
+ local format=readushort(f)
+ local length=readulong(f)
+ local nofrecords=readulong(f)
+ local records={}
+ local variants={}
+ local nofdone=0
+ fontdata.variants=variants
+ for i=1,nofrecords do
+ records[i]={
+ selector=readuint(f),
+ default=readulong(f),
+ other=readulong(f),
+ }
+ end
+ for i=1,nofrecords do
+ local record=records[i]
+ local selector=record.selector
+ local default=record.default
+ local other=record.other
+ local other=record.other
+ if other~=0 then
+ setposition(f,offset+other)
+ local mapping={}
+ local count=readulong(f)
+ for i=1,count do
+ mapping[readuint(f)]=readushort(f)
+ end
+ nofdone=nofdone+count
+ variants[selector]=mapping
+ end
+ end
+ return nofdone
+ else
+ return 0
+ end
+end
+local function checkcmap(f,fontdata,records,platform,encoding,format)
+ local pdata=records[platform]
+ if not pdata then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","no platform",platform,encoding,format)
+ end
+ return 0
+ end
+ local edata=pdata[encoding]
+ if not edata then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","no encoding",platform,encoding,format)
+ end
+ return 0
+ end
+ local fdata=edata[format]
+ if not fdata then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","no format",platform,encoding,format)
+ end
+ return 0
+ elseif type(fdata)~="number" then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","already done",platform,encoding,format)
+ end
+ return 0
+ end
+ edata[format]=true
+ local reader=formatreaders[format]
+ if not reader then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","unsupported format",platform,encoding,format)
+ end
+ return 0
+ end
+ local n=reader(f,fontdata,fdata) or 0
+ if trace_cmap_details or trace_cmap then
+ local p=platforms[platform]
+ local e=encodings[p]
+ report_cmap("checked, platform %i (%s), encoding %i (%s), format %i, new unicodes %i",
+ platform,p,encoding,e and e[encoding] or "?",format,n)
+ end
+ return n
+end
+function readers.cmap(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local noftables=readushort(f)
+ local records={}
+ local unicodecid=false
+ local variantcid=false
+ local variants={}
+ local duplicates=fontdata.duplicates or {}
+ fontdata.duplicates=duplicates
+ for i=1,noftables do
+ local platform=readushort(f)
+ local encoding=readushort(f)
+ local offset=readulong(f)
+ local record=records[platform]
+ if not record then
+ records[platform]={
+ [encoding]={
+ offsets={ offset },
+ formats={},
+ }
+ }
+ else
+ local subtables=record[encoding]
+ if not subtables then
+ record[encoding]={
+ offsets={ offset },
+ formats={},
+ }
+ else
+ local offsets=subtables.offsets
+ offsets[#offsets+1]=offset
+ end
+ end
+ end
+ if trace_cmap then
+ report("found cmaps:")
+ end
+ for platform,record in sortedhash(records) do
+ local p=platforms[platform]
+ local e=encodings[p]
+ local sp=supported[platform]
+ local ps=p or "?"
+ if trace_cmap then
+ if sp then
+ report(" platform %i: %s",platform,ps)
+ else
+ report(" platform %i: %s (unsupported)",platform,ps)
+ end
+ end
+ for encoding,subtables in sortedhash(record) do
+ local se=sp and sp[encoding]
+ local es=e and e[encoding] or "?"
+ if trace_cmap then
+ if se then
+ report(" encoding %i: %s",encoding,es)
+ else
+ report(" encoding %i: %s (unsupported)",encoding,es)
+ end
+ end
+ local offsets=subtables.offsets
+ local formats=subtables.formats
+ for i=1,#offsets do
+ local offset=tableoffset+offsets[i]
+ setposition(f,offset)
+ formats[readushort(f)]=offset
+ end
+ record[encoding]=formats
+ if trace_cmap then
+ local list=sortedkeys(formats)
+ for i=1,#list do
+ if not (se and se[list[i]]) then
+ list[i]=list[i].." (unsupported)"
+ end
+ end
+ report(" formats: % t",list)
+ end
+ end
+ end
+ local ok=false
+ for i=1,#sequence do
+ local si=sequence[i]
+ local sp,se,sf=si[1],si[2],si[3]
+ if checkcmap(f,fontdata,records,sp,se,sf)>0 then
+ ok=true
+ end
+ end
+ if not ok then
+ report("no useable unicode cmap found")
+ end
+ fontdata.cidmaps={
+ version=version,
+ noftables=noftables,
+ records=records,
+ }
+ else
+ fontdata.cidmaps={}
+ end
+end
+function readers.loca(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"loca",specification.glyphs)
+end
+function readers.glyf(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"glyf",specification.glyphs)
+end
+function readers.colr(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"colr",specification.glyphs)
+end
+function readers.cpal(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cpal",specification.glyphs)
+end
+function readers.svg(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"svg",specification.glyphs)
+end
+function readers.sbix(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"sbix",specification.glyphs)
+end
+function readers.cbdt(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cbdt",specification.glyphs)
+end
+function readers.cblc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cblc",specification.glyphs)
+end
+function readers.ebdt(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"ebdt",specification.glyphs)
+end
+function readers.ebsc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"ebsc",specification.glyphs)
+end
+function readers.eblc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"eblc",specification.glyphs)
+end
+function readers.kern(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns)
+ if tableoffset then
+ local version=readushort(f)
+ local noftables=readushort(f)
+ for i=1,noftables do
+ local version=readushort(f)
+ local length=readushort(f)
+ local coverage=readushort(f)
+ local format=rshift(coverage,8)
+ if format==0 then
+ local nofpairs=readushort(f)
+ local searchrange=readushort(f)
+ local entryselector=readushort(f)
+ local rangeshift=readushort(f)
+ local kerns={}
+ local glyphs=fontdata.glyphs
+ for i=1,nofpairs do
+ local left=readushort(f)
+ local right=readushort(f)
+ local kern=readfword(f)
+ local glyph=glyphs[left]
+ local kerns=glyph.kerns
+ if kerns then
+ kerns[right]=kern
+ else
+ glyph.kerns={ [right]=kern }
+ end
+ end
+ elseif format==2 then
+ report("todo: kern classes")
+ else
+ report("todo: kerns")
+ end
+ end
+ end
+end
+function readers.gdef(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"gdef",specification.details)
+end
+function readers.gsub(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"gsub",specification.details)
+end
+function readers.gpos(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"gpos",specification.details)
+end
+function readers.math(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"math",specification.details)
+end
+local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames)
+ local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata
+ local names=fontdata.names
+ local info=nil
+ if names then
+ local metrics=fontdata.windowsmetrics or {}
+ local postscript=fontdata.postscript or {}
+ local fontheader=fontdata.fontheader or {}
+ local cffinfo=fontdata.cffinfo or {}
+ local verticalheader=fontdata.verticalheader or {}
+ local filename=fontdata.filename
+ local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight)
+ local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width )
+ local fontname=getname(fontdata,"postscriptname")
+ local fullname=getname(fontdata,"fullname")
+ local family=getname(fontdata,"family")
+ local subfamily=getname(fontdata,"subfamily")
+ local familyname=getname(fontdata,"typographicfamily")
+ local subfamilyname=getname(fontdata,"typographicsubfamily")
+ local compatiblename=getname(fontdata,"compatiblefullname")
+ if rawfamilynames then
+ else
+ if not familyname then familyname=family end
+ if not subfamilyname then subfamilyname=subfamily end
+ end
+ if platformnames then
+ platformnames=fontdata.platformnames
+ end
+ if instancenames then
+ local variabledata=fontdata.variabledata
+ if variabledata then
+ local instances=variabledata and variabledata.instances
+ if instances then
+ instancenames={}
+ for i=1,#instances do
+ instancenames[i]=lower(stripstring(instances[i].subfamily))
+ end
+ else
+ instancenames=nil
+ end
+ else
+ instancenames=nil
+ end
+ end
+ info={
+ subfontindex=fontdata.subfontindex or sub or 0,
+ version=getname(fontdata,"version"),
+ fontname=fontname,
+ fullname=fullname,
+ family=family,
+ subfamily=subfamily,
+ familyname=familyname,
+ subfamilyname=subfamilyname,
+ compatiblename=compatiblename,
+ weight=weight and lower(weight),
+ width=width and lower(width),
+ pfmweight=metrics.weightclass or 400,
+ pfmwidth=metrics.widthclass or 5,
+ panosewidth=metrics.panosewidth,
+ panoseweight=metrics.panoseweight,
+ italicangle=postscript.italicangle or 0,
+ units=fontheader.units or 0,
+ designsize=fontdata.designsize,
+ minsize=fontdata.minsize,
+ maxsize=fontdata.maxsize,
+ boundingbox=fontheader and { fontheader.xmin or 0,fontheader.ymin or 0,fontheader.xmax or 0,fontheader.ymax or 0 } or nil,
+ monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced",
+ averagewidth=metrics.averagewidth,
+ xheight=metrics.xheight,
+ capheight=metrics.capheight or fontdata.maxy,
+ ascender=metrics.typoascender,
+ descender=metrics.typodescender,
+ platformnames=platformnames or nil,
+ instancenames=instancenames or nil,
+ tableoffsets=fontdata.tableoffsets,
+ defaultvheight=(verticalheader.ascender or 0)-(verticalheader.descender or 0)
+ }
+ if metricstoo then
+ local keys={
+ "version",
+ "ascender","descender","linegap",
+ "maxadvancewidth","maxadvanceheight","maxextent",
+ "minbottomsidebearing","mintopsidebearing",
+ }
+ local h=fontdata.horizontalheader or {}
+ local v=fontdata.verticalheader or {}
+ if h then
+ local th={}
+ local tv={}
+ for i=1,#keys do
+ local key=keys[i]
+ th[key]=h[key] or 0
+ tv[key]=v[key] or 0
+ end
+ info.horizontalmetrics=th
+ info.verticalmetrics=tv
+ end
+ end
+ elseif n then
+ info={
+ filename=fontdata.filename,
+ comment="there is no info for subfont "..n,
+ }
+ else
+ info={
+ filename=fontdata.filename,
+ comment="there is no info",
+ }
+ end
+ return info
+end
+local function loadtables(f,specification,offset)
+ if offset then
+ setposition(f,offset)
+ end
+ local tables={}
+ local basename=file.basename(specification.filename)
+ local filesize=specification.filesize
+ local filetime=specification.filetime
+ local fontdata={
+ filename=basename,
+ filesize=filesize,
+ filetime=filetime,
+ version=readstring(f,4),
+ noftables=readushort(f),
+ searchrange=readushort(f),
+ entryselector=readushort(f),
+ rangeshift=readushort(f),
+ tables=tables,
+ foundtables=false,
+ }
+ for i=1,fontdata.noftables do
+ local tag=lower(stripstring(readstring(f,4)))
+ local checksum=readushort(f)*0x10000+readushort(f)
+ local offset=readulong(f)
+ local length=readulong(f)
+ if offset+length>filesize then
+ report("bad %a table in file %a",tag,basename)
+ end
+ tables[tag]={
+ checksum=checksum,
+ offset=offset,
+ length=length,
+ }
+ end
+ fontdata.foundtables=sortedkeys(tables)
+ if tables.cff or tables.cff2 then
+ fontdata.format="opentype"
+ else
+ fontdata.format="truetype"
+ end
+ return fontdata,tables
+end
+local function prepareglyps(fontdata)
+ local glyphs=setmetatableindex(function(t,k)
+ local v={
+ index=k,
+ }
+ t[k]=v
+ return v
+ end)
+ fontdata.glyphs=glyphs
+ fontdata.mapping={}
+end
+local function readtable(tag,f,fontdata,specification,...)
+ local reader=readers[tag]
+ if reader then
+ reader(f,fontdata,specification,...)
+ end
+end
+local variablefonts_supported=(context and true) or (logs and logs.application and true) or false
+local function readdata(f,offset,specification)
+ local fontdata,tables=loadtables(f,specification,offset)
+ if specification.glyphs then
+ prepareglyps(fontdata)
+ end
+ if not variablefonts_supported then
+ specification.instance=nil
+ specification.variable=nil
+ specification.factors=nil
+ end
+ fontdata.temporary={}
+ readtable("name",f,fontdata,specification)
+ local askedname=specification.askedname
+ if askedname then
+ local fullname=getname(fontdata,"fullname") or ""
+ local cleanname=gsub(askedname,"[^a-zA-Z0-9]","")
+ local foundname=gsub(fullname,"[^a-zA-Z0-9]","")
+ if lower(cleanname)~=lower(foundname) then
+ return
+ end
+ end
+ readtable("stat",f,fontdata,specification)
+ readtable("avar",f,fontdata,specification)
+ readtable("fvar",f,fontdata,specification)
+ if variablefonts_supported then
+ local variabledata=fontdata.variabledata
+ if variabledata then
+ local instances=variabledata.instances
+ local axis=variabledata.axis
+ if axis and (not instances or #instances==0) then
+ instances={}
+ variabledata.instances=instances
+ local function add(n,subfamily,value)
+ local values={}
+ for i=1,#axis do
+ local a=axis[i]
+ values[i]={
+ axis=a.tag,
+ value=i==n and value or a.default,
+ }
+ end
+ instances[#instances+1]={
+ subfamily=subfamily,
+ values=values,
+ }
+ end
+ for i=1,#axis do
+ local a=axis[i]
+ local tag=a.tag
+ add(i,"default"..tag,a.default)
+ add(i,"minimum"..tag,a.minimum)
+ add(i,"maximum"..tag,a.maximum)
+ end
+ end
+ end
+ if not specification.factors then
+ local instance=specification.instance
+ if type(instance)=="string" then
+ local factors=helpers.getfactors(fontdata,instance)
+ 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)
+ if factors then
+ specification.factors=factors
+ fontdata.factors=factors
+ end
+ else
+ end
+ end
+ end
+ readtable("os/2",f,fontdata,specification)
+ readtable("head",f,fontdata,specification)
+ readtable("maxp",f,fontdata,specification)
+ readtable("hhea",f,fontdata,specification)
+ readtable("vhea",f,fontdata,specification)
+ readtable("hmtx",f,fontdata,specification)
+ readtable("vmtx",f,fontdata,specification)
+ readtable("vorg",f,fontdata,specification)
+ readtable("post",f,fontdata,specification)
+ readtable("mvar",f,fontdata,specification)
+ readtable("hvar",f,fontdata,specification)
+ readtable("vvar",f,fontdata,specification)
+ readtable("gdef",f,fontdata,specification)
+ readtable("cff",f,fontdata,specification)
+ readtable("cff2",f,fontdata,specification)
+ readtable("cmap",f,fontdata,specification)
+ readtable("loca",f,fontdata,specification)
+ readtable("glyf",f,fontdata,specification)
+ readtable("colr",f,fontdata,specification)
+ readtable("cpal",f,fontdata,specification)
+ readtable("svg",f,fontdata,specification)
+ readtable("sbix",f,fontdata,specification)
+ readtable("cbdt",f,fontdata,specification)
+ readtable("cblc",f,fontdata,specification)
+ readtable("ebdt",f,fontdata,specification)
+ readtable("eblc",f,fontdata,specification)
+ readtable("kern",f,fontdata,specification)
+ readtable("gsub",f,fontdata,specification)
+ readtable("gpos",f,fontdata,specification)
+ readtable("math",f,fontdata,specification)
+ fontdata.locations=nil
+ fontdata.cidmaps=nil
+ fontdata.dictionaries=nil
+ if specification.tableoffsets then
+ fontdata.tableoffsets=tables
+ setmetatableindex(tables,{
+ version=fontdata.version,
+ noftables=fontdata.noftables,
+ searchrange=fontdata.searchrange,
+ entryselector=fontdata.entryselector,
+ rangeshift=fontdata.rangeshift,
+ })
+ end
+ return fontdata
+end
+local function loadfontdata(specification)
+ local filename=specification.filename
+ local fileattr=lfs.attributes(filename)
+ local filesize=fileattr and fileattr.size or 0
+ local filetime=fileattr and fileattr.modification or 0
+ local f=openfile(filename,true)
+ if not f then
+ report("unable to open %a",filename)
+ elseif filesize==0 then
+ report("empty file %a",filename)
+ closefile(f)
+ else
+ specification.filesize=filesize
+ specification.filetime=filetime
+ local version=readstring(f,4)
+ local fontdata=nil
+ if version=="OTTO" or version=="true" or version=="\0\1\0\0" then
+ fontdata=readdata(f,0,specification)
+ elseif version=="ttcf" then
+ local subfont=tonumber(specification.subfont)
+ local ttcversion=readulong(f)
+ local nofsubfonts=readulong(f)
+ local offsets=readcardinaltable(f,nofsubfonts,ulong)
+ if subfont then
+ if subfont>=1 and subfont<=nofsubfonts then
+ fontdata=readdata(f,offsets[subfont],specification)
+ else
+ report("no subfont %a in file %a",subfont,filename)
+ end
+ else
+ subfont=specification.subfont
+ if type(subfont)=="string" and subfont~="" then
+ specification.askedname=subfont
+ for i=1,nofsubfonts do
+ fontdata=readdata(f,offsets[i],specification)
+ if fontdata then
+ fontdata.subfontindex=i
+ report("subfont named %a has index %a",subfont,i)
+ break
+ end
+ end
+ if not fontdata then
+ report("no subfont named %a",subfont)
+ end
+ else
+ local subfonts={}
+ fontdata={
+ filename=filename,
+ filesize=filesize,
+ filetime=filetime,
+ version=version,
+ subfonts=subfonts,
+ ttcversion=ttcversion,
+ nofsubfonts=nofsubfonts,
+ }
+ for i=1,nofsubfonts do
+ subfonts[i]=readdata(f,offsets[i],specification)
+ end
+ end
+ end
+ else
+ report("unknown version %a in file %a",version,filename)
+ end
+ closefile(f)
+ return fontdata or {}
+ end
+end
+local function loadfont(specification,n,instance)
+ if type(specification)=="string" then
+ specification={
+ filename=specification,
+ info=true,
+ details=true,
+ glyphs=true,
+ shapes=true,
+ kerns=true,
+ variable=true,
+ globalkerns=true,
+ lookups=true,
+ subfont=n or true,
+ tounicode=false,
+ instance=instance
+ }
+ end
+ if specification.shapes or specification.lookups or specification.kerns then
+ specification.glyphs=true
+ end
+ if specification.glyphs then
+ specification.details=true
+ end
+ if specification.details then
+ specification.info=true
+ end
+ if specification.platformnames then
+ specification.platformnames=true
+ end
+ if specification.instance or instance then
+ specification.variable=true
+ specification.instance=specification.instance or instance
+ end
+ local function message(str)
+ report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback())
+ end
+ local ok,result=xpcall(loadfontdata,message,specification)
+ if ok then
+ return result
+ end
+end
+function readers.loadshapes(filename,n,instance,streams)
+ local fontdata=loadfont {
+ filename=filename,
+ shapes=true,
+ streams=streams,
+ variable=true,
+ subfont=n,
+ instance=instance,
+ }
+ if fontdata then
+ for k,v in next,fontdata.glyphs do
+ v.class=nil
+ v.index=nil
+ v.math=nil
+ end
+ local names=fontdata.names
+ if names then
+ for k,v in next,names do
+ names[k]=fullstrip(v.content)
+ end
+ end
+ end
+ return fontdata and {
+ filename=filename,
+ format=fontdata.format,
+ glyphs=fontdata.glyphs,
+ units=fontdata.fontheader.units,
+ cffinfo=fontdata.cffinfo,
+ fontheader=fontdata.fontheader,
+ horizontalheader=fontdata.horizontalheader,
+ verticalheader=fontdata.verticalheader,
+ maximumprofile=fontdata.maximumprofile,
+ names=fontdata.names,
+ postscript=fontdata.postscript,
+ } or {
+ filename=filename,
+ format="unknown",
+ glyphs={},
+ units=0,
+ }
+end
+function readers.loadfont(filename,n,instance)
+ local fontdata=loadfont {
+ filename=filename,
+ glyphs=true,
+ shapes=false,
+ lookups=true,
+ variable=true,
+ subfont=n,
+ instance=instance,
+ }
+ if fontdata then
+ return {
+ tableversion=tableversion,
+ creator="context mkiv",
+ size=fontdata.filesize,
+ time=fontdata.filetime,
+ glyphs=fontdata.glyphs,
+ descriptions=fontdata.descriptions,
+ format=fontdata.format,
+ goodies={},
+ metadata=getinfo(fontdata,n,false,false,true,true),
+ properties={
+ hasitalics=fontdata.hasitalics or false,
+ maxcolorclass=fontdata.maxcolorclass,
+ hascolor=fontdata.hascolor or false,
+ instance=fontdata.instance,
+ factors=fontdata.factors,
+ },
+ resources={
+ filename=filename,
+ private=privateoffset,
+ duplicates=fontdata.duplicates or {},
+ features=fontdata.features or {},
+ sublookups=fontdata.sublookups or {},
+ marks=fontdata.marks or {},
+ markclasses=fontdata.markclasses or {},
+ marksets=fontdata.marksets or {},
+ sequences=fontdata.sequences or {},
+ variants=fontdata.variants,
+ version=getname(fontdata,"version"),
+ cidinfo=fontdata.cidinfo,
+ mathconstants=fontdata.mathconstants,
+ colorpalettes=fontdata.colorpalettes,
+ svgshapes=fontdata.svgshapes,
+ pngshapes=fontdata.pngshapes,
+ variabledata=fontdata.variabledata,
+ foundtables=fontdata.foundtables,
+ },
+ }
+ end
+end
+function readers.getinfo(filename,specification)
+ local subfont=nil
+ local platformnames=false
+ local rawfamilynames=false
+ local instancenames=true
+ local tableoffsets=false
+ if type(specification)=="table" then
+ subfont=tonumber(specification.subfont)
+ platformnames=specification.platformnames
+ rawfamilynames=specification.rawfamilynames
+ tableoffsets=specification.tableoffsets
+ else
+ subfont=tonumber(specification)
+ end
+ local fontdata=loadfont {
+ filename=filename,
+ details=true,
+ platformnames=platformnames,
+ instancenames=true,
+ tableoffsets=tableoffsets,
+ }
+ if fontdata then
+ local subfonts=fontdata.subfonts
+ if not subfonts then
+ return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames)
+ elseif not subfont then
+ local info={}
+ for i=1,#subfonts do
+ info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames)
+ end
+ return info
+ elseif subfont>=1 and subfont<=#subfonts then
+ return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames)
+ else
+ return {
+ filename=filename,
+ comment="there is no subfont "..subfont.." in this file"
+ }
+ end
+ else
+ return {
+ filename=filename,
+ comment="the file cannot be opened for reading",
+ }
+ end
+end
+function readers.rehash(fontdata,hashmethod)
+ report("the %a helper is not yet implemented","rehash")
+end
+function readers.checkhash(fontdata)
+ report("the %a helper is not yet implemented","checkhash")
+end
+function readers.pack(fontdata,hashmethod)
+ report("the %a helper is not yet implemented","pack")
+end
+function readers.unpack(fontdata)
+ report("the %a helper is not yet implemented","unpack")
+end
+function readers.expand(fontdata)
+ report("the %a helper is not yet implemented","unpack")
+end
+function readers.compact(fontdata)
+ report("the %a helper is not yet implemented","compact")
+end
+local extenders={}
+function readers.registerextender(extender)
+ extenders[#extenders+1]=extender
+end
+function readers.extend(fontdata)
+ for i=1,#extenders do
+ local extender=extenders[i]
+ local name=extender.name or "unknown"
+ local action=extender.action
+ if action then
+ action(fontdata)
+ end
+ end
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otrâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oti†dbae7722baae24d917a17176553825cf] ---
+
+if not modules then modules={} end modules ['font-oti']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local lower=string.lower
+local fonts=fonts
+local constructors=fonts.constructors
+local otf=constructors.handlers.otf
+local otffeatures=constructors.features.otf
+local registerotffeature=otffeatures.register
+local otftables=otf.tables or {}
+otf.tables=otftables
+local allocate=utilities.storage.allocate
+registerotffeature {
+ name="features",
+ description="initialization of feature handler",
+ default=true,
+}
+local function setmode(tfmdata,value)
+ if value then
+ tfmdata.properties.mode=lower(value)
+ end
+end
+otf.modeinitializer=setmode
+local function setlanguage(tfmdata,value)
+ if value then
+ local cleanvalue=lower(value)
+ local languages=otftables and otftables.languages
+ local properties=tfmdata.properties
+ if not languages then
+ properties.language=cleanvalue
+ elseif languages[value] then
+ properties.language=cleanvalue
+ else
+ properties.language="dflt"
+ end
+ end
+end
+local function setscript(tfmdata,value)
+ if value then
+ local cleanvalue=lower(value)
+ local scripts=otftables and otftables.scripts
+ local properties=tfmdata.properties
+ if not scripts then
+ properties.script=cleanvalue
+ elseif scripts[value] then
+ properties.script=cleanvalue
+ else
+ properties.script="dflt"
+ end
+ end
+end
+registerotffeature {
+ name="mode",
+ description="mode",
+ initializers={
+ base=setmode,
+ node=setmode,
+ plug=setmode,
+ }
+}
+registerotffeature {
+ name="language",
+ description="language",
+ initializers={
+ base=setlanguage,
+ node=setlanguage,
+ plug=setlanguage,
+ }
+}
+registerotffeature {
+ name="script",
+ description="script",
+ initializers={
+ base=setscript,
+ node=setscript,
+ plug=setscript,
+ }
+}
+otftables.featuretypes=allocate {
+ gpos_single="position",
+ gpos_pair="position",
+ gpos_cursive="position",
+ gpos_mark2base="position",
+ gpos_mark2ligature="position",
+ gpos_mark2mark="position",
+ gpos_context="position",
+ gpos_contextchain="position",
+ gsub_single="substitution",
+ gsub_multiple="substitution",
+ gsub_alternate="substitution",
+ gsub_ligature="substitution",
+ gsub_context="substitution",
+ gsub_contextchain="substitution",
+ gsub_reversecontextchain="substitution",
+ gsub_reversesub="substitution",
+}
+function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts)
+ if featuretype=="position" then
+ local default=scripts.dflt
+ if default then
+ if autoscript=="position" or autoscript==true then
+ return default
+ else
+ report_otf("script feature %s not applied, enable default positioning")
+ end
+ else
+ end
+ elseif featuretype=="substitution" then
+ local default=scripts.dflt
+ if default then
+ if autoscript=="substitution" or autoscript==true then
+ return default
+ end
+ end
+ end
+end
+function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
+ if featuretype=="position" then
+ local default=languages.dflt
+ if default then
+ if autolanguage=="position" or autolanguage==true then
+ return default
+ else
+ report_otf("language feature %s not applied, enable default positioning")
+ end
+ else
+ end
+ elseif featuretype=="substitution" then
+ local default=languages.dflt
+ if default then
+ if autolanguage=="substitution" or autolanguage==true then
+ return default
+ end
+ end
+ end
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otiâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ott†aba6d8335a5f38a5a62d3631492f3392] ---
+
+if not modules then modules={} end modules ["font-ott"]={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
+}
+local type,next,tonumber,tostring,rawget,rawset=type,next,tonumber,tostring,rawget,rawset
+local gsub,lower,format,match,gmatch,find=string.gsub,string.lower,string.format,string.match,string.gmatch,string.find
+local sequenced=table.sequenced
+local is_boolean=string.is_boolean
+local setmetatableindex=table.setmetatableindex
+local setmetatablenewindex=table.setmetatablenewindex
+local allocate=utilities.storage.allocate
+local fonts=fonts
+local otf=fonts.handlers.otf
+local otffeatures=otf.features
+local tables=otf.tables or {}
+otf.tables=tables
+local statistics=otf.statistics or {}
+otf.statistics=statistics
+local scripts=allocate {
+ ["adlm"]="adlam",
+ ["aghb"]="caucasian albanian",
+ ["ahom"]="ahom",
+ ["arab"]="arabic",
+ ["armi"]="imperial aramaic",
+ ["armn"]="armenian",
+ ["avst"]="avestan",
+ ["bali"]="balinese",
+ ["bamu"]="bamum",
+ ["bass"]="bassa vah",
+ ["batk"]="batak",
+ ["beng"]="bengali",
+ ["bhks"]="bhaiksuki",
+ ["bng2"]="bengali variant 2",
+ ["bopo"]="bopomofo",
+ ["brah"]="brahmi",
+ ["brai"]="braille",
+ ["bugi"]="buginese",
+ ["buhd"]="buhid",
+ ["byzm"]="byzantine music",
+ ["cakm"]="chakma",
+ ["cans"]="canadian syllabics",
+ ["cari"]="carian",
+ ["cham"]="cham",
+ ["cher"]="cherokee",
+ ["copt"]="coptic",
+ ["cprt"]="cypriot syllabary",
+ ["cyrl"]="cyrillic",
+ ["dev2"]="devanagari variant 2",
+ ["deva"]="devanagari",
+ ["dogr"]="dogra",
+ ["dsrt"]="deseret",
+ ["dupl"]="duployan",
+ ["egyp"]="egyptian heiroglyphs",
+ ["elba"]="elbasan",
+ ["ethi"]="ethiopic",
+ ["geor"]="georgian",
+ ["gjr2"]="gujarati variant 2",
+ ["glag"]="glagolitic",
+ ["gong"]="gunjala gondi",
+ ["gonm"]="masaram gondi",
+ ["goth"]="gothic",
+ ["gran"]="grantha",
+ ["grek"]="greek",
+ ["gujr"]="gujarati",
+ ["gur2"]="gurmukhi variant 2",
+ ["guru"]="gurmukhi",
+ ["hang"]="hangul",
+ ["hani"]="cjk ideographic",
+ ["hano"]="hanunoo",
+ ["hatr"]="hatran",
+ ["hebr"]="hebrew",
+ ["hluw"]="anatolian hieroglyphs",
+ ["hmng"]="pahawh hmong",
+ ["hung"]="old hungarian",
+ ["ital"]="old italic",
+ ["jamo"]="hangul jamo",
+ ["java"]="javanese",
+ ["kali"]="kayah li",
+ ["kana"]="hiragana and katakana",
+ ["khar"]="kharosthi",
+ ["khmr"]="khmer",
+ ["khoj"]="khojki",
+ ["knd2"]="kannada variant 2",
+ ["knda"]="kannada",
+ ["kthi"]="kaithi",
+ ["lana"]="tai tham",
+ ["lao" ]="lao",
+ ["latn"]="latin",
+ ["lepc"]="lepcha",
+ ["limb"]="limbu",
+ ["lina"]="linear a",
+ ["linb"]="linear b",
+ ["lisu"]="lisu",
+ ["lyci"]="lycian",
+ ["lydi"]="lydian",
+ ["mahj"]="mahajani",
+ ["maka"]="makasar",
+ ["mand"]="mandaic and mandaean",
+ ["mani"]="manichaean",
+ ["marc"]="marchen",
+ ["math"]="mathematical alphanumeric symbols",
+ ["medf"]="medefaidrin",
+ ["mend"]="mende kikakui",
+ ["merc"]="meroitic cursive",
+ ["mero"]="meroitic hieroglyphs",
+ ["mlm2"]="malayalam variant 2",
+ ["mlym"]="malayalam",
+ ["modi"]="modi",
+ ["mong"]="mongolian",
+ ["mroo"]="mro",
+ ["mtei"]="meitei Mayek",
+ ["mult"]="multani",
+ ["musc"]="musical symbols",
+ ["mym2"]="myanmar variant 2",
+ ["mymr"]="myanmar",
+ ["narb"]="old north arabian",
+ ["nbat"]="nabataean",
+ ["newa"]="newa",
+ ["nko" ]='n"ko',
+ ["nshu"]="nüshu",
+ ["ogam"]="ogham",
+ ["olck"]="ol chiki",
+ ["orkh"]="old turkic and orkhon runic",
+ ["ory2"]="odia variant 2",
+ ["orya"]="oriya",
+ ["osge"]="osage",
+ ["osma"]="osmanya",
+ ["palm"]="palmyrene",
+ ["pauc"]="pau cin hau",
+ ["perm"]="old permic",
+ ["phag"]="phags-pa",
+ ["phli"]="inscriptional pahlavi",
+ ["phlp"]="psalter pahlavi",
+ ["phnx"]="phoenician",
+ ["plrd"]="miao",
+ ["prti"]="inscriptional parthian",
+ ["rjng"]="rejang",
+ ["rohg"]="hanifi rohingya",
+ ["runr"]="runic",
+ ["samr"]="samaritan",
+ ["sarb"]="old south arabian",
+ ["saur"]="saurashtra",
+ ["sgnw"]="sign writing",
+ ["shaw"]="shavian",
+ ["shrd"]="sharada",
+ ["sidd"]="siddham",
+ ["sind"]="khudawadi",
+ ["sinh"]="sinhala",
+ ["sogd"]="sogdian",
+ ["sogo"]="old sogdian",
+ ["sora"]="sora sompeng",
+ ["soyo"]="soyombo",
+ ["sund"]="sundanese",
+ ["sylo"]="syloti nagri",
+ ["syrc"]="syriac",
+ ["tagb"]="tagbanwa",
+ ["takr"]="takri",
+ ["tale"]="tai le",
+ ["talu"]="tai lu",
+ ["taml"]="tamil",
+ ["tang"]="tangut",
+ ["tavt"]="tai viet",
+ ["tel2"]="telugu variant 2",
+ ["telu"]="telugu",
+ ["tfng"]="tifinagh",
+ ["tglg"]="tagalog",
+ ["thaa"]="thaana",
+ ["thai"]="thai",
+ ["tibt"]="tibetan",
+ ["tirh"]="tirhuta",
+ ["tml2"]="tamil variant 2",
+ ["ugar"]="ugaritic cuneiform",
+ ["vai" ]="vai",
+ ["wara"]="warang citi",
+ ["xpeo"]="old persian cuneiform",
+ ["xsux"]="sumero-akkadian cuneiform",
+ ["yi" ]="yi",
+ ["zanb"]="zanabazar square",
+}
+local languages=allocate {
+ ["aba" ]="abaza",
+ ["abk" ]="abkhazian",
+ ["ach" ]="acholi",
+ ["acr" ]="achi",
+ ["ady" ]="adyghe",
+ ["afk" ]="afrikaans",
+ ["afr" ]="afar",
+ ["agw" ]="agaw",
+ ["aio" ]="aiton",
+ ["aka" ]="akan",
+ ["als" ]="alsatian",
+ ["alt" ]="altai",
+ ["amh" ]="amharic",
+ ["ang" ]="anglo-saxon",
+ ["apph"]="phonetic transcription—americanist conventions",
+ ["ara" ]="arabic",
+ ["arg" ]="aragonese",
+ ["ari" ]="aari",
+ ["ark" ]="rakhine",
+ ["asm" ]="assamese",
+ ["ast" ]="asturian",
+ ["ath" ]="athapaskan",
+ ["avr" ]="avar",
+ ["awa" ]="awadhi",
+ ["aym" ]="aymara",
+ ["azb" ]="torki",
+ ["aze" ]="azerbaijani",
+ ["bad" ]="badaga",
+ ["bad0"]="banda",
+ ["bag" ]="baghelkhandi",
+ ["bal" ]="balkar",
+ ["ban" ]="balinese",
+ ["bar" ]="bavarian",
+ ["bau" ]="baulé",
+ ["bbc" ]="batak toba",
+ ["bbr" ]="berber",
+ ["bch" ]="bench",
+ ["bcr" ]="bible cree",
+ ["bdy" ]="bandjalang",
+ ["bel" ]="belarussian",
+ ["bem" ]="bemba",
+ ["ben" ]="bengali",
+ ["bgc" ]="haryanvi",
+ ["bgq" ]="bagri",
+ ["bgr" ]="bulgarian",
+ ["bhi" ]="bhili",
+ ["bho" ]="bhojpuri",
+ ["bik" ]="bikol",
+ ["bil" ]="bilen",
+ ["bis" ]="bislama",
+ ["bjj" ]="kanauji",
+ ["bkf" ]="blackfoot",
+ ["bli" ]="baluchi",
+ ["blk" ]="pa'o karen",
+ ["bln" ]="balante",
+ ["blt" ]="balti",
+ ["bmb" ]="bambara (bamanankan)",
+ ["bml" ]="bamileke",
+ ["bos" ]="bosnian",
+ ["bpy" ]="bishnupriya manipuri",
+ ["bre" ]="breton",
+ ["brh" ]="brahui",
+ ["bri" ]="braj bhasha",
+ ["brm" ]="burmese",
+ ["brx" ]="bodo",
+ ["bsh" ]="bashkir",
+ ["bsk" ]="burushaski",
+ ["bti" ]="beti",
+ ["bts" ]="batak simalungun",
+ ["bug" ]="bugis",
+ ["byv" ]="medumba",
+ ["cak" ]="kaqchikel",
+ ["cat" ]="catalan",
+ ["cbk" ]="zamboanga chavacano",
+ ["cchn"]="chinantec",
+ ["ceb" ]="cebuano",
+ ["cgg" ]="chiga",
+ ["cha" ]="chamorro",
+ ["che" ]="chechen",
+ ["chg" ]="chaha gurage",
+ ["chh" ]="chattisgarhi",
+ ["chi" ]="chichewa (chewa, nyanja)",
+ ["chk" ]="chukchi",
+ ["chk0"]="chuukese",
+ ["cho" ]="choctaw",
+ ["chp" ]="chipewyan",
+ ["chr" ]="cherokee",
+ ["chu" ]="chuvash",
+ ["chy" ]="cheyenne",
+ ["cja" ]="western cham",
+ ["cjm" ]="eastern cham",
+ ["cmr" ]="comorian",
+ ["cop" ]="coptic",
+ ["cor" ]="cornish",
+ ["cos" ]="corsican",
+ ["cpp" ]="creoles",
+ ["cre" ]="cree",
+ ["crr" ]="carrier",
+ ["crt" ]="crimean tatar",
+ ["csb" ]="kashubian",
+ ["csl" ]="church slavonic",
+ ["csy" ]="czech",
+ ["ctg" ]="chittagonian",
+ ["cuk" ]="san blas kuna",
+ ["dan" ]="danish",
+ ["dar" ]="dargwa",
+ ["dax" ]="dayi",
+ ["dcr" ]="woods cree",
+ ["deu" ]="german",
+ ["dgo" ]="dogri",
+ ["dgr" ]="dogri",
+ ["dhg" ]="dhangu",
+ ["dhv" ]="divehi (dhivehi, maldivian)",
+ ["diq" ]="dimli",
+ ["div" ]="divehi (dhivehi, maldivian)",
+ ["djr" ]="zarma",
+ ["djr0"]="djambarrpuyngu",
+ ["dng" ]="dangme",
+ ["dnj" ]="dan",
+ ["dnk" ]="dinka",
+ ["dri" ]="dari",
+ ["duj" ]="dhuwal",
+ ["dun" ]="dungan",
+ ["dzn" ]="dzongkha",
+ ["ebi" ]="ebira",
+ ["ecr" ]="eastern cree",
+ ["edo" ]="edo",
+ ["efi" ]="efik",
+ ["ell" ]="greek",
+ ["emk" ]="eastern maninkakan",
+ ["eng" ]="english",
+ ["erz" ]="erzya",
+ ["esp" ]="spanish",
+ ["esu" ]="central yupik",
+ ["eti" ]="estonian",
+ ["euq" ]="basque",
+ ["evk" ]="evenki",
+ ["evn" ]="even",
+ ["ewe" ]="ewe",
+ ["fan" ]="french antillean",
+ ["fan0"]=" fang",
+ ["far" ]="persian",
+ ["fat" ]="fanti",
+ ["fin" ]="finnish",
+ ["fji" ]="fijian",
+ ["fle" ]="dutch (flemish)",
+ ["fmp" ]="fe’fe’",
+ ["fne" ]="forest nenets",
+ ["fon" ]="fon",
+ ["fos" ]="faroese",
+ ["fra" ]="french",
+ ["frc" ]="cajun french",
+ ["fri" ]="frisian",
+ ["frl" ]="friulian",
+ ["frp" ]="arpitan",
+ ["fta" ]="futa",
+ ["ful" ]="fulah",
+ ["fuv" ]="nigerian fulfulde",
+ ["gad" ]="ga",
+ ["gae" ]="scottish gaelic (gaelic)",
+ ["gag" ]="gagauz",
+ ["gal" ]="galician",
+ ["gar" ]="garshuni",
+ ["gaw" ]="garhwali",
+ ["gez" ]="ge'ez",
+ ["gih" ]="githabul",
+ ["gil" ]="gilyak",
+ ["gil0"]="kiribati (gilbertese)",
+ ["gkp" ]="kpelle (guinea)",
+ ["glk" ]="gilaki",
+ ["gmz" ]="gumuz",
+ ["gnn" ]="gumatj",
+ ["gog" ]="gogo",
+ ["gon" ]="gondi",
+ ["grn" ]="greenlandic",
+ ["gro" ]="garo",
+ ["gua" ]="guarani",
+ ["guc" ]="wayuu",
+ ["guf" ]="gupapuyngu",
+ ["guj" ]="gujarati",
+ ["guz" ]="gusii",
+ ["hai" ]="haitian (haitian creole)",
+ ["hal" ]="halam",
+ ["har" ]="harauti",
+ ["hau" ]="hausa",
+ ["haw" ]="hawaiian",
+ ["hay" ]="haya",
+ ["haz" ]="hazaragi",
+ ["hbn" ]="hammer-banna",
+ ["her" ]="herero",
+ ["hil" ]="hiligaynon",
+ ["hin" ]="hindi",
+ ["hma" ]="high mari",
+ ["hmn" ]="hmong",
+ ["hmo" ]="hiri motu",
+ ["hnd" ]="hindko",
+ ["ho" ]="ho",
+ ["hri" ]="harari",
+ ["hrv" ]="croatian",
+ ["hun" ]="hungarian",
+ ["hye" ]="armenian",
+ ["hye0"]="armenian east",
+ ["iba" ]="iban",
+ ["ibb" ]="ibibio",
+ ["ibo" ]="igbo",
+ ["ido" ]="ido",
+ ["ijo" ]="ijo languages",
+ ["ile" ]="interlingue",
+ ["ilo" ]="ilokano",
+ ["ina" ]="interlingua",
+ ["ind" ]="indonesian",
+ ["ing" ]="ingush",
+ ["inu" ]="inuktitut",
+ ["ipk" ]="inupiat",
+ ["ipph"]="phonetic transcription—ipa conventions",
+ ["iri" ]="irish",
+ ["irt" ]="irish traditional",
+ ["isl" ]="icelandic",
+ ["ism" ]="inari sami",
+ ["ita" ]="italian",
+ ["iwr" ]="hebrew",
+ ["jam" ]="jamaican creole",
+ ["jan" ]="japanese",
+ ["jav" ]="javanese",
+ ["jbo" ]="lojban",
+ ["jct" ]="krymchak",
+ ["jii" ]="yiddish",
+ ["jud" ]="ladino",
+ ["jul" ]="jula",
+ ["kab" ]="kabardian",
+ ["kab0"]="kabyle",
+ ["kac" ]="kachchi",
+ ["kal" ]="kalenjin",
+ ["kan" ]="kannada",
+ ["kar" ]="karachay",
+ ["kat" ]="georgian",
+ ["kaz" ]="kazakh",
+ ["kde" ]="makonde",
+ ["kea" ]="kabuverdianu (crioulo)",
+ ["keb" ]="kebena",
+ ["kek" ]="kekchi",
+ ["kge" ]="khutsuri georgian",
+ ["kha" ]="khakass",
+ ["khk" ]="khanty-kazim",
+ ["khm" ]="khmer",
+ ["khs" ]="khanty-shurishkar",
+ ["kht" ]="khamti shan",
+ ["khv" ]="khanty-vakhi",
+ ["khw" ]="khowar",
+ ["kik" ]="kikuyu (gikuyu)",
+ ["kir" ]="kirghiz (kyrgyz)",
+ ["kis" ]="kisii",
+ ["kiu" ]="kirmanjki",
+ ["kjd" ]="southern kiwai",
+ ["kjp" ]="eastern pwo karen",
+ ["kjz" ]="bumthangkha",
+ ["kkn" ]="kokni",
+ ["klm" ]="kalmyk",
+ ["kmb" ]="kamba",
+ ["kmn" ]="kumaoni",
+ ["kmo" ]="komo",
+ ["kms" ]="komso",
+ ["kmz" ]="khorasani turkic",
+ ["knr" ]="kanuri",
+ ["kod" ]="kodagu",
+ ["koh" ]="korean old hangul",
+ ["kok" ]="konkani",
+ ["kom" ]="komi",
+ ["kon" ]="kikongo",
+ ["kon0"]="kongo",
+ ["kop" ]="komi-permyak",
+ ["kor" ]="korean",
+ ["kos" ]="kosraean",
+ ["koz" ]="komi-zyrian",
+ ["kpl" ]="kpelle",
+ ["kri" ]="krio",
+ ["krk" ]="karakalpak",
+ ["krl" ]="karelian",
+ ["krm" ]="karaim",
+ ["krn" ]="karen",
+ ["krt" ]="koorete",
+ ["ksh" ]="kashmiri",
+ ["ksh0"]="ripuarian",
+ ["ksi" ]="khasi",
+ ["ksm" ]="kildin sami",
+ ["ksw" ]="s’gaw karen",
+ ["kua" ]="kuanyama",
+ ["kui" ]="kui",
+ ["kul" ]="kulvi",
+ ["kum" ]="kumyk",
+ ["kur" ]="kurdish",
+ ["kuu" ]="kurukh",
+ ["kuy" ]="kuy",
+ ["kyk" ]="koryak",
+ ["kyu" ]="western kayah",
+ ["lad" ]="ladin",
+ ["lah" ]="lahuli",
+ ["lak" ]="lak",
+ ["lam" ]="lambani",
+ ["lao" ]="lao",
+ ["lat" ]="latin",
+ ["laz" ]="laz",
+ ["lcr" ]="l-cree",
+ ["ldk" ]="ladakhi",
+ ["lez" ]="lezgi",
+ ["lij" ]="ligurian",
+ ["lim" ]="limburgish",
+ ["lin" ]="lingala",
+ ["lis" ]="lisu",
+ ["ljp" ]="lampung",
+ ["lki" ]="laki",
+ ["lma" ]="low mari",
+ ["lmb" ]="limbu",
+ ["lmo" ]="lombard",
+ ["lmw" ]="lomwe",
+ ["lom" ]="loma",
+ ["lrc" ]="luri",
+ ["lsb" ]="lower sorbian",
+ ["lsm" ]="lule sami",
+ ["lth" ]="lithuanian",
+ ["ltz" ]="luxembourgish",
+ ["lua" ]="luba-lulua",
+ ["lub" ]="luba-katanga",
+ ["lug" ]="ganda",
+ ["luh" ]="luyia",
+ ["luo" ]="luo",
+ ["lvi" ]="latvian",
+ ["mad" ]="madura",
+ ["mag" ]="magahi",
+ ["mah" ]="marshallese",
+ ["maj" ]="majang",
+ ["mak" ]="makhuwa",
+ ["mal" ]="malayalam reformed",
+ ["mam" ]="mam",
+ ["man" ]="mansi",
+ ["map" ]="mapudungun",
+ ["mar" ]="marathi",
+ ["maw" ]="marwari",
+ ["mbn" ]="mbundu",
+ ["mbo" ]="mbo",
+ ["mch" ]="manchu",
+ ["mcr" ]="moose cree",
+ ["mde" ]="mende",
+ ["mdr" ]="mandar",
+ ["men" ]="me'en",
+ ["mer" ]="meru",
+ ["mfa" ]="pattani malay",
+ ["mfe" ]="morisyen",
+ ["min" ]="minangkabau",
+ ["miz" ]="mizo",
+ ["mkd" ]="macedonian",
+ ["mkr" ]="makasar",
+ ["mkw" ]="kituba",
+ ["mle" ]="male",
+ ["mlg" ]="malagasy",
+ ["mln" ]="malinke",
+ ["mlr" ]="malayalam reformed",
+ ["mly" ]="malay",
+ ["mnd" ]="mandinka",
+ ["mng" ]="mongolian",
+ ["mni" ]="manipuri",
+ ["mnk" ]="maninka",
+ ["mnx" ]="manx",
+ ["moh" ]="mohawk",
+ ["mok" ]="moksha",
+ ["mol" ]="moldavian",
+ ["mon" ]="mon",
+ ["mor" ]="moroccan",
+ ["mos" ]="mossi",
+ ["mri" ]="maori",
+ ["mth" ]="maithili",
+ ["mts" ]="maltese",
+ ["mun" ]="mundari",
+ ["mus" ]="muscogee",
+ ["mwl" ]="mirandese",
+ ["mww" ]="hmong daw",
+ ["myn" ]="mayan",
+ ["mzn" ]="mazanderani",
+ ["nag" ]="naga-assamese",
+ ["nah" ]="nahuatl",
+ ["nan" ]="nanai",
+ ["nap" ]="neapolitan",
+ ["nas" ]="naskapi",
+ ["nau" ]="nauruan",
+ ["nav" ]="navajo",
+ ["ncr" ]="n-cree",
+ ["ndb" ]="ndebele",
+ ["ndc" ]="ndau",
+ ["ndg" ]="ndonga",
+ ["nds" ]="low saxon",
+ ["nep" ]="nepali",
+ ["new" ]="newari",
+ ["nga" ]="ngbaka",
+ ["ngr" ]="nagari",
+ ["nhc" ]="norway house cree",
+ ["nis" ]="nisi",
+ ["niu" ]="niuean",
+ ["nkl" ]="nyankole",
+ ["nko" ]="n'ko",
+ ["nld" ]="dutch",
+ ["noe" ]="nimadi",
+ ["nog" ]="nogai",
+ ["nor" ]="norwegian",
+ ["nov" ]="novial",
+ ["nsm" ]="northern sami",
+ ["nso" ]="sotho, northern",
+ ["nta" ]="northern tai",
+ ["nto" ]="esperanto",
+ ["nym" ]="nyamwezi",
+ ["nyn" ]="norwegian nynorsk",
+ ["nza" ]="mbembe tigon",
+ ["oci" ]="occitan",
+ ["ocr" ]="oji-cree",
+ ["ojb" ]="ojibway",
+ ["ori" ]="odia",
+ ["oro" ]="oromo",
+ ["oss" ]="ossetian",
+ ["paa" ]="palestinian aramaic",
+ ["pag" ]="pangasinan",
+ ["pal" ]="pali",
+ ["pam" ]="pampangan",
+ ["pan" ]="punjabi",
+ ["pap" ]="palpa",
+ ["pap0"]="papiamentu",
+ ["pas" ]="pashto",
+ ["pau" ]="palauan",
+ ["pcc" ]="bouyei",
+ ["pcd" ]="picard",
+ ["pdc" ]="pennsylvania german",
+ ["pgr" ]="polytonic greek",
+ ["phk" ]="phake",
+ ["pih" ]="norfolk",
+ ["pil" ]="filipino",
+ ["plg" ]="palaung",
+ ["plk" ]="polish",
+ ["pms" ]="piemontese",
+ ["pnb" ]="western panjabi",
+ ["poh" ]="pocomchi",
+ ["pon" ]="pohnpeian",
+ ["pro" ]="provencal",
+ ["ptg" ]="portuguese",
+ ["pwo" ]="western pwo karen",
+ ["qin" ]="chin",
+ ["quc" ]="k’iche’",
+ ["quh" ]="quechua (bolivia)",
+ ["quz" ]="quechua",
+ ["qvi" ]="quechua (ecuador)",
+ ["qwh" ]="quechua (peru)",
+ ["raj" ]="rajasthani",
+ ["rar" ]="rarotongan",
+ ["rbu" ]="russian buriat",
+ ["rcr" ]="r-cree",
+ ["rej" ]="rejang",
+ ["ria" ]="riang",
+ ["rif" ]="tarifit",
+ ["rit" ]="ritarungo",
+ ["rkw" ]="arakwal",
+ ["rms" ]="romansh",
+ ["rmy" ]="vlax romani",
+ ["rom" ]="romanian",
+ ["roy" ]="romany",
+ ["rsy" ]="rusyn",
+ ["rtm" ]="rotuman",
+ ["rua" ]="kinyarwanda",
+ ["run" ]="rundi",
+ ["rup" ]="aromanian",
+ ["rus" ]="russian",
+ ["sad" ]="sadri",
+ ["san" ]="sanskrit",
+ ["sas" ]="sasak",
+ ["sat" ]="santali",
+ ["say" ]="sayisi",
+ ["scn" ]="sicilian",
+ ["sco" ]="scots",
+ ["scs" ]="north slavey",
+ ["sek" ]="sekota",
+ ["sel" ]="selkup",
+ ["sga" ]="old irish",
+ ["sgo" ]="sango",
+ ["sgs" ]="samogitian",
+ ["shi" ]="tachelhit",
+ ["shn" ]="shan",
+ ["sib" ]="sibe",
+ ["sid" ]="sidamo",
+ ["sig" ]="silte gurage",
+ ["sks" ]="skolt sami",
+ ["sky" ]="slovak",
+ ["sla" ]="slavey",
+ ["slv" ]="slovenian",
+ ["sml" ]="somali",
+ ["smo" ]="samoan",
+ ["sna" ]="sena",
+ ["sna0"]="shona",
+ ["snd" ]="sindhi",
+ ["snh" ]="sinhala (sinhalese)",
+ ["snk" ]="soninke",
+ ["sog" ]="sodo gurage",
+ ["sop" ]="songe",
+ ["sot" ]="sotho, southern",
+ ["sqi" ]="albanian",
+ ["srb" ]="serbian",
+ ["srd" ]="sardinian",
+ ["srk" ]="saraiki",
+ ["srr" ]="serer",
+ ["ssl" ]="south slavey",
+ ["ssm" ]="southern sami",
+ ["stq" ]="saterland frisian",
+ ["suk" ]="sukuma",
+ ["sun" ]="sundanese",
+ ["sur" ]="suri",
+ ["sva" ]="svan",
+ ["sve" ]="swedish",
+ ["swa" ]="swadaya aramaic",
+ ["swk" ]="swahili",
+ ["swz" ]="swati",
+ ["sxt" ]="sutu",
+ ["sxu" ]="upper saxon",
+ ["syl" ]="sylheti",
+ ["syr" ]="syriac",
+ ["syre"]="estrangela syriac",
+ ["syrj"]="western syriac",
+ ["syrn"]="eastern syriac",
+ ["szl" ]="silesian",
+ ["tab" ]="tabasaran",
+ ["taj" ]="tajiki",
+ ["tam" ]="tamil",
+ ["tat" ]="tatar",
+ ["tcr" ]="th-cree",
+ ["tdd" ]="dehong dai",
+ ["tel" ]="telugu",
+ ["tet" ]="tetum",
+ ["tgl" ]="tagalog",
+ ["tgn" ]="tongan",
+ ["tgr" ]="tigre",
+ ["tgy" ]="tigrinya",
+ ["tha" ]="thai",
+ ["tht" ]="tahitian",
+ ["tib" ]="tibetan",
+ ["tiv" ]="tiv",
+ ["tkm" ]="turkmen",
+ ["tmh" ]="tamashek",
+ ["tmn" ]="temne",
+ ["tna" ]="tswana",
+ ["tne" ]="tundra nenets",
+ ["tng" ]="tonga",
+ ["tod" ]="todo",
+ ["tod0"]="toma",
+ ["tpi" ]="tok pisin",
+ ["trk" ]="turkish",
+ ["tsg" ]="tsonga",
+ ["tsj" ]="tshangla",
+ ["tua" ]="turoyo aramaic",
+ ["tul" ]="tulu",
+ ["tum" ]="tulu",
+ ["tuv" ]="tuvin",
+ ["tvl" ]="tuvalu",
+ ["twi" ]="twi",
+ ["tyz" ]="tày",
+ ["tzm" ]="tamazight",
+ ["tzo" ]="tzotzil",
+ ["udm" ]="udmurt",
+ ["ukr" ]="ukrainian",
+ ["umb" ]="umbundu",
+ ["urd" ]="urdu",
+ ["usb" ]="upper sorbian",
+ ["uyg" ]="uyghur",
+ ["uzb" ]="uzbek",
+ ["vec" ]="venetian",
+ ["ven" ]="venda",
+ ["vit" ]="vietnamese",
+ ["vol" ]="volapük",
+ ["vro" ]="võro",
+ ["wa" ]="wa",
+ ["wag" ]="wagdi",
+ ["war" ]="waray-waray",
+ ["wcr" ]="west-cree",
+ ["wel" ]="welsh",
+ ["wlf" ]="wolof",
+ ["wln" ]="walloon",
+ ["wtm" ]="mewati",
+ ["xbd" ]="lü",
+ ["xhs" ]="xhosa",
+ ["xjb" ]="minjangbal",
+ ["xkf" ]="khengkha",
+ ["xog" ]="soga",
+ ["xpe" ]="kpelle (liberia)",
+ ["yak" ]="sakha",
+ ["yao" ]="yao",
+ ["yap" ]="yapese",
+ ["yba" ]="yoruba",
+ ["ycr" ]="y-cree",
+ ["yic" ]="yi classic",
+ ["yim" ]="yi modern",
+ ["zea" ]="zealandic",
+ ["zgh" ]="standard morrocan tamazigh",
+ ["zha" ]="zhuang",
+ ["zhh" ]="chinese, hong kong sar",
+ ["zhp" ]="chinese phonetic",
+ ["zhs" ]="chinese simplified",
+ ["zht" ]="chinese traditional",
+ ["znd" ]="zande",
+ ["zul" ]="zulu",
+ ["zza" ]="zazaki",
+}
+local features=allocate {
+ ["aalt"]="access all alternates",
+ ["abvf"]="above-base forms",
+ ["abvm"]="above-base mark positioning",
+ ["abvs"]="above-base substitutions",
+ ["afrc"]="alternative fractions",
+ ["akhn"]="akhands",
+ ["blwf"]="below-base forms",
+ ["blwm"]="below-base mark positioning",
+ ["blws"]="below-base substitutions",
+ ["c2pc"]="petite capitals from capitals",
+ ["c2sc"]="small capitals from capitals",
+ ["calt"]="contextual alternates",
+ ["case"]="case-sensitive forms",
+ ["ccmp"]="glyph composition/decomposition",
+ ["cfar"]="conjunct form after ro",
+ ["cjct"]="conjunct forms",
+ ["clig"]="contextual ligatures",
+ ["cpct"]="centered cjk punctuation",
+ ["cpsp"]="capital spacing",
+ ["cswh"]="contextual swash",
+ ["curs"]="cursive positioning",
+ ["dflt"]="default processing",
+ ["dist"]="distances",
+ ["dlig"]="discretionary ligatures",
+ ["dnom"]="denominators",
+ ["dtls"]="dotless forms",
+ ["expt"]="expert forms",
+ ["falt"]="final glyph alternates",
+ ["fin2"]="terminal forms #2",
+ ["fin3"]="terminal forms #3",
+ ["fina"]="terminal forms",
+ ["flac"]="flattened accents over capitals",
+ ["frac"]="fractions",
+ ["fwid"]="full width",
+ ["half"]="half forms",
+ ["haln"]="halant forms",
+ ["halt"]="alternate half width",
+ ["hist"]="historical forms",
+ ["hkna"]="horizontal kana alternates",
+ ["hlig"]="historical ligatures",
+ ["hngl"]="hangul",
+ ["hojo"]="hojo kanji forms",
+ ["hwid"]="half width",
+ ["init"]="initial forms",
+ ["isol"]="isolated forms",
+ ["ital"]="italics",
+ ["jalt"]="justification alternatives",
+ ["jp04"]="jis2004 forms",
+ ["jp78"]="jis78 forms",
+ ["jp83"]="jis83 forms",
+ ["jp90"]="jis90 forms",
+ ["kern"]="kerning",
+ ["lfbd"]="left bounds",
+ ["liga"]="standard ligatures",
+ ["ljmo"]="leading jamo forms",
+ ["lnum"]="lining figures",
+ ["locl"]="localized forms",
+ ["ltra"]="left-to-right alternates",
+ ["ltrm"]="left-to-right mirrored forms",
+ ["mark"]="mark positioning",
+ ["med2"]="medial forms #2",
+ ["medi"]="medial forms",
+ ["mgrk"]="mathematical greek",
+ ["mkmk"]="mark to mark positioning",
+ ["mset"]="mark positioning via substitution",
+ ["nalt"]="alternate annotation forms",
+ ["nlck"]="nlc kanji forms",
+ ["nukt"]="nukta forms",
+ ["numr"]="numerators",
+ ["onum"]="old style figures",
+ ["opbd"]="optical bounds",
+ ["ordn"]="ordinals",
+ ["ornm"]="ornaments",
+ ["palt"]="proportional alternate width",
+ ["pcap"]="petite capitals",
+ ["pkna"]="proportional kana",
+ ["pnum"]="proportional figures",
+ ["pref"]="pre-base forms",
+ ["pres"]="pre-base substitutions",
+ ["pstf"]="post-base forms",
+ ["psts"]="post-base substitutions",
+ ["pwid"]="proportional widths",
+ ["qwid"]="quarter widths",
+ ["rand"]="randomize",
+ ["rclt"]="required contextual alternates",
+ ["rkrf"]="rakar forms",
+ ["rlig"]="required ligatures",
+ ["rphf"]="reph form",
+ ["rtbd"]="right bounds",
+ ["rtla"]="right-to-left alternates",
+ ["rtlm"]="right to left mirrored forms",
+ ["rvrn"]="required variation alternates",
+ ["ruby"]="ruby notation forms",
+ ["salt"]="stylistic alternates",
+ ["sinf"]="scientific inferiors",
+ ["size"]="optical size",
+ ["smcp"]="small capitals",
+ ["smpl"]="simplified forms",
+ ["ssty"]="script style",
+ ["stch"]="stretching glyph decomposition",
+ ["subs"]="subscript",
+ ["sups"]="superscript",
+ ["swsh"]="swash",
+ ["titl"]="titling",
+ ["tjmo"]="trailing jamo forms",
+ ["tnam"]="traditional name forms",
+ ["tnum"]="tabular figures",
+ ["trad"]="traditional forms",
+ ["twid"]="third widths",
+ ["unic"]="unicase",
+ ["valt"]="alternate vertical metrics",
+ ["vatu"]="vattu variants",
+ ["vert"]="vertical writing",
+ ["vhal"]="alternate vertical half metrics",
+ ["vjmo"]="vowel jamo forms",
+ ["vkna"]="vertical kana alternates",
+ ["vkrn"]="vertical kerning",
+ ["vpal"]="proportional alternate vertical metrics",
+ ["vrtr"]="vertical alternates for rotation",
+ ["vrt2"]="vertical rotation",
+ ["zero"]="slashed zero",
+ ["trep"]="traditional tex replacements",
+ ["tlig"]="traditional tex ligatures",
+ ["ss.."]="stylistic set ..",
+ ["cv.."]="character variant ..",
+ ["js.."]="justification ..",
+ ["dv.."]="devanagari ..",
+ ["ml.."]="malayalam ..",
+}
+local baselines=allocate {
+ ["hang"]="hanging baseline",
+ ["icfb"]="ideographic character face bottom edge baseline",
+ ["icft"]="ideographic character face tope edige baseline",
+ ["ideo"]="ideographic em-box bottom edge baseline",
+ ["idtp"]="ideographic em-box top edge baseline",
+ ["math"]="mathematical centered baseline",
+ ["romn"]="roman baseline"
+}
+tables.scripts=scripts
+tables.languages=languages
+tables.features=features
+tables.baselines=baselines
+local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end)
+local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end)
+local report_checks=logs.reporter("fonts","checks")
+if otffeatures.features then
+ for k,v in next,otffeatures.features do
+ features[k]=v
+ end
+ otffeatures.features=features
+end
+local function swapped(h)
+ local r={}
+ for k,v in next,h do
+ r[gsub(v,"[^a-z0-9]","")]=k
+ end
+ return r
+end
+local verbosescripts=allocate(swapped(scripts ))
+local verboselanguages=allocate(swapped(languages))
+local verbosefeatures=allocate(swapped(features ))
+local verbosebaselines=allocate(swapped(baselines))
+local function resolve(t,k)
+ if k then
+ k=gsub(lower(k),"[^a-z0-9]","")
+ local v=rawget(t,k)
+ if v then
+ return v
+ end
+ end
+end
+setmetatableindex(verbosescripts,resolve)
+setmetatableindex(verboselanguages,resolve)
+setmetatableindex(verbosefeatures,resolve)
+setmetatableindex(verbosebaselines,resolve)
+setmetatableindex(scripts,function(t,k)
+ if k then
+ k=lower(k)
+ if k=="dflt" then
+ return k
+ end
+ local v=rawget(t,k)
+ if v then
+ return v
+ end
+ k=gsub(k," ","")
+ v=rawget(t,v)
+ if v then
+ return v
+ elseif acceptscripts then
+ report_checks("registering extra script %a",k)
+ rawset(t,k,k)
+ return k
+ end
+ end
+ return "dflt"
+end)
+setmetatableindex(languages,function(t,k)
+ if k then
+ k=lower(k)
+ if k=="dflt" then
+ return k
+ end
+ local v=rawget(t,k)
+ if v then
+ return v
+ end
+ k=gsub(k," ","")
+ v=rawget(t,v)
+ if v then
+ return v
+ elseif acceptlanguages then
+ report_checks("registering extra language %a",k)
+ rawset(t,k,k)
+ return k
+ end
+ end
+ return "dflt"
+end)
+if setmetatablenewindex then
+ setmetatablenewindex(languages,"ignore")
+ setmetatablenewindex(scripts,"ignore")
+ setmetatablenewindex(baselines,"ignore")
+end
+local function resolve(t,k)
+ if k then
+ k=lower(k)
+ local v=rawget(t,k)
+ if v then
+ return v
+ end
+ k=gsub(k," ","")
+ local v=rawget(t,k)
+ if v then
+ return v
+ end
+ local tag,dd=match(k,"(..)(%d+)")
+ if tag and dd then
+ local v=rawget(t,tag)
+ if v then
+ return v
+ else
+ local v=rawget(t,tag.."..")
+ if v then
+ return (gsub(v,"%.%.",tonumber(dd)))
+ end
+ end
+ end
+ end
+ return k
+end
+setmetatableindex(features,resolve)
+local function assign(t,k,v)
+ if k and v then
+ v=lower(v)
+ rawset(t,k,v)
+ end
+end
+if setmetatablenewindex then
+ setmetatablenewindex(features,assign)
+end
+local checkers={
+ rand=function(v)
+ return v==true and "random" or v
+ end
+}
+if not storage then
+ return
+end
+local usedfeatures=statistics.usedfeatures or {}
+statistics.usedfeatures=usedfeatures
+table.setmetatableindex(usedfeatures,function(t,k) if k then local v={} t[k]=v return v end end)
+storage.register("fonts/otf/usedfeatures",usedfeatures,"fonts.handlers.otf.statistics.usedfeatures" )
+local normalizedaxis=otf.readers.helpers.normalizedaxis or function(s) return s end
+function otffeatures.normalize(features,wrap)
+ if features then
+ local h={}
+ for key,value in next,features do
+ local k=lower(key)
+ if k=="language" then
+ local v=gsub(lower(value),"[^a-z0-9]","")
+ h.language=rawget(verboselanguages,v) or (languages[v] and v) or "dflt"
+ elseif k=="script" then
+ local v=gsub(lower(value),"[^a-z0-9]","")
+ h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt"
+ elseif k=="axis" then
+ h[k]=normalizedaxis(value)
+ if not callbacks.supported.glyph_stream_provider then
+ h.variableshapes=true
+ end
+ else
+ local uk=usedfeatures[key]
+ local uv=uk[value]
+ if uv then
+ else
+ uv=tonumber(value)
+ if uv then
+ elseif type(value)=="string" then
+ local b=is_boolean(value)
+ if type(b)=="nil" then
+ if wrap and find(value,",") then
+ uv="{"..lower(value).."}"
+ else
+ uv=lower(value)
+ end
+ else
+ uv=b
+ end
+ elseif type(value)=="table" then
+ uv=sequenced(t,",")
+ else
+ uv=value
+ end
+ if not rawget(features,k) then
+ k=rawget(verbosefeatures,k) or k
+ end
+ local c=checkers[k]
+ if c then
+ uv=c(uv) or vc
+ end
+ uk[value]=uv
+ end
+ h[k]=uv
+ end
+ end
+ return h
+ end
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ottâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-cff†98d5a660ea803b65cb883c009ecf3c0b] ---
+
+if not modules then modules={} end modules ['font-cff']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type,tonumber,rawget=next,type,tonumber,rawget
+local byte,char,gmatch=string.byte,string.char,string.gmatch
+local concat,remove,unpack=table.concat,table.remove,table.unpack
+local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max
+local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct
+local lpegmatch=lpeg.match
+local formatters=string.formatters
+local bytetable=string.bytetable
+local idiv=number.idiv
+local rshift,band,extract=bit32.rshift,bit32.band,bit32.extract
+local readers=fonts.handlers.otf.readers
+local streamreader=readers.streamreader
+local readstring=streamreader.readstring
+local readbyte=streamreader.readcardinal1
+local readushort=streamreader.readcardinal2
+local readuint=streamreader.readcardinal3
+local readulong=streamreader.readcardinal4
+local setposition=streamreader.setposition
+local getposition=streamreader.getposition
+local readbytetable=streamreader.readbytetable
+directives.register("fonts.streamreader",function()
+ streamreader=utilities.streams
+ readstring=streamreader.readstring
+ readbyte=streamreader.readcardinal1
+ readushort=streamreader.readcardinal2
+ readuint=streamreader.readcardinal3
+ readulong=streamreader.readcardinal4
+ setposition=streamreader.setposition
+ getposition=streamreader.getposition
+ readbytetable=streamreader.readbytetable
+end)
+local setmetatableindex=table.setmetatableindex
+local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end)
+local report=logs.reporter("otf reader","cff")
+local parsedictionaries
+local parsecharstring
+local parsecharstrings
+local resetcharstrings
+local parseprivates
+local startparsing
+local stopparsing
+local defaultstrings={ [0]=
+ ".notdef","space","exclam","quotedbl","numbersign","dollar","percent",
+ "ampersand","quoteright","parenleft","parenright","asterisk","plus",
+ "comma","hyphen","period","slash","zero","one","two","three","four",
+ "five","six","seven","eight","nine","colon","semicolon","less",
+ "equal","greater","question","at","A","B","C","D","E","F","G","H",
+ "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W",
+ "X","Y","Z","bracketleft","backslash","bracketright","asciicircum",
+ "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j",
+ "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y",
+ "z","braceleft","bar","braceright","asciitilde","exclamdown","cent",
+ "sterling","fraction","yen","florin","section","currency",
+ "quotesingle","quotedblleft","guillemotleft","guilsinglleft",
+ "guilsinglright","fi","fl","endash","dagger","daggerdbl",
+ "periodcentered","paragraph","bullet","quotesinglbase","quotedblbase",
+ "quotedblright","guillemotright","ellipsis","perthousand","questiondown",
+ "grave","acute","circumflex","tilde","macron","breve","dotaccent",
+ "dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash",
+ "AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae",
+ "dotlessi","lslash","oslash","oe","germandbls","onesuperior",
+ "logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn",
+ "onequarter","divide","brokenbar","degree","thorn","threequarters",
+ "twosuperior","registered","minus","eth","multiply","threesuperior",
+ "copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring",
+ "Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave",
+ "Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute",
+ "Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute",
+ "Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron",
+ "aacute","acircumflex","adieresis","agrave","aring","atilde",
+ "ccedilla","eacute","ecircumflex","edieresis","egrave","iacute",
+ "icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex",
+ "odieresis","ograve","otilde","scaron","uacute","ucircumflex",
+ "udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall",
+ "Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall",
+ "Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader",
+ "onedotenleader","zerooldstyle","oneoldstyle","twooldstyle",
+ "threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle",
+ "sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior",
+ "threequartersemdash","periodsuperior","questionsmall","asuperior",
+ "bsuperior","centsuperior","dsuperior","esuperior","isuperior",
+ "lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior",
+ "tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior",
+ "Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall",
+ "Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall",
+ "Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall",
+ "Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall",
+ "Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah",
+ "Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall",
+ "Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall",
+ "Dotaccentsmall","Macronsmall","figuredash","hypheninferior",
+ "Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth",
+ "threeeighths","fiveeighths","seveneighths","onethird","twothirds",
+ "zerosuperior","foursuperior","fivesuperior","sixsuperior",
+ "sevensuperior","eightsuperior","ninesuperior","zeroinferior",
+ "oneinferior","twoinferior","threeinferior","fourinferior",
+ "fiveinferior","sixinferior","seveninferior","eightinferior",
+ "nineinferior","centinferior","dollarinferior","periodinferior",
+ "commainferior","Agravesmall","Aacutesmall","Acircumflexsmall",
+ "Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall",
+ "Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall",
+ "Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall",
+ "Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall",
+ "Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall",
+ "Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall",
+ "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003",
+ "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold",
+}
+local cffreaders={
+ readbyte,
+ readushort,
+ readuint,
+ readulong,
+}
+local function readheader(f)
+ local offset=getposition(f)
+ local major=readbyte(f)
+ local header={
+ offset=offset,
+ major=major,
+ minor=readbyte(f),
+ size=readbyte(f),
+ }
+ if major==1 then
+ header.dsize=readbyte(f)
+ elseif major==2 then
+ header.dsize=readushort(f)
+ else
+ end
+ setposition(f,offset+header.size)
+ return header
+end
+local function readlengths(f,longcount)
+ local count=longcount and readulong(f) or readushort(f)
+ if count==0 then
+ return {}
+ end
+ local osize=readbyte(f)
+ local read=cffreaders[osize]
+ if not read then
+ report("bad offset size: %i",osize)
+ return {}
+ end
+ local lengths={}
+ local previous=read(f)
+ for i=1,count do
+ local offset=read(f)
+ local length=offset-previous
+ if length<0 then
+ report("bad offset: %i",length)
+ length=0
+ end
+ lengths[i]=length
+ previous=offset
+ end
+ return lengths
+end
+local function readfontnames(f)
+ local names=readlengths(f)
+ for i=1,#names do
+ names[i]=readstring(f,names[i])
+ end
+ return names
+end
+local function readtopdictionaries(f)
+ local dictionaries=readlengths(f)
+ for i=1,#dictionaries do
+ dictionaries[i]=readstring(f,dictionaries[i])
+ end
+ return dictionaries
+end
+local function readstrings(f)
+ local lengths=readlengths(f)
+ local strings=setmetatableindex({},defaultstrings)
+ local index=#defaultstrings
+ for i=1,#lengths do
+ index=index+1
+ strings[index]=readstring(f,lengths[i])
+ end
+ return strings
+end
+do
+ local stack={}
+ local top=0
+ local result={}
+ local strings={}
+ local p_single=P("\00")/function()
+ result.version=strings[stack[top]] or "unset"
+ top=0
+ end+P("\01")/function()
+ result.notice=strings[stack[top]] or "unset"
+ top=0
+ end+P("\02")/function()
+ result.fullname=strings[stack[top]] or "unset"
+ top=0
+ end+P("\03")/function()
+ result.familyname=strings[stack[top]] or "unset"
+ top=0
+ end+P("\04")/function()
+ result.weight=strings[stack[top]] or "unset"
+ top=0
+ end+P("\05")/function()
+ result.fontbbox={ unpack(stack,1,4) }
+ top=0
+ end+P("\06")/function()
+ result.bluevalues={ unpack(stack,1,top) }
+ top=0
+ end+P("\07")/function()
+ result.otherblues={ unpack(stack,1,top) }
+ top=0
+ end+P("\08")/function()
+ result.familyblues={ unpack(stack,1,top) }
+ top=0
+ end+P("\09")/function()
+ result.familyotherblues={ unpack(stack,1,top) }
+ top=0
+ end+P("\10")/function()
+ result.strhw=stack[top]
+ top=0
+ end+P("\11")/function()
+ result.strvw=stack[top]
+ top=0
+ end+P("\13")/function()
+ result.uniqueid=stack[top]
+ top=0
+ end+P("\14")/function()
+ result.xuid=concat(stack,"",1,top)
+ top=0
+ end+P("\15")/function()
+ result.charset=stack[top]
+ top=0
+ end+P("\16")/function()
+ result.encoding=stack[top]
+ top=0
+ end+P("\17")/function()
+ result.charstrings=stack[top]
+ top=0
+ end+P("\18")/function()
+ result.private={
+ size=stack[top-1],
+ offset=stack[top],
+ }
+ top=0
+ end+P("\19")/function()
+ result.subroutines=stack[top]
+ top=0
+ end+P("\20")/function()
+ result.defaultwidthx=stack[top]
+ top=0
+ end+P("\21")/function()
+ result.nominalwidthx=stack[top]
+ top=0
+ end
++P("\24")/function()
+ result.vstore=stack[top]
+ top=0
+ end+P("\25")/function()
+ result.maxstack=stack[top]
+ top=0
+ end
+ local p_double=P("\12")*(
+ P("\00")/function()
+ result.copyright=stack[top]
+ top=0
+ end+P("\01")/function()
+ result.monospaced=stack[top]==1 and true or false
+ top=0
+ end+P("\02")/function()
+ result.italicangle=stack[top]
+ top=0
+ end+P("\03")/function()
+ result.underlineposition=stack[top]
+ top=0
+ end+P("\04")/function()
+ result.underlinethickness=stack[top]
+ top=0
+ end+P("\05")/function()
+ result.painttype=stack[top]
+ top=0
+ end+P("\06")/function()
+ result.charstringtype=stack[top]
+ top=0
+ end+P("\07")/function()
+ result.fontmatrix={ unpack(stack,1,6) }
+ top=0
+ end+P("\08")/function()
+ result.strokewidth=stack[top]
+ top=0
+ end+P("\09")/function()
+ result.bluescale=stack[top]
+ top=0
+ end+P("\10")/function()
+ result.bluesnap=stack[top]
+ top=0
+ end+P("\11")/function()
+ result.bluefuzz=stack[top]
+ top=0
+ end+P("\12")/function()
+ result.stemsnaph={ unpack(stack,1,top) }
+ top=0
+ end+P("\13")/function()
+ result.stemsnapv={ unpack(stack,1,top) }
+ top=0
+ end+P("\20")/function()
+ result.syntheticbase=stack[top]
+ top=0
+ end+P("\21")/function()
+ result.postscript=strings[stack[top]] or "unset"
+ top=0
+ end+P("\22")/function()
+ result.basefontname=strings[stack[top]] or "unset"
+ top=0
+ end+P("\21")/function()
+ result.basefontblend=stack[top]
+ top=0
+ end+P("\30")/function()
+ result.cid.registry=strings[stack[top-2]] or "unset"
+ result.cid.ordering=strings[stack[top-1]] or "unset"
+ result.cid.supplement=stack[top]
+ top=0
+ end+P("\31")/function()
+ result.cid.fontversion=stack[top]
+ top=0
+ end+P("\32")/function()
+ result.cid.fontrevision=stack[top]
+ top=0
+ end+P("\33")/function()
+ result.cid.fonttype=stack[top]
+ top=0
+ end+P("\34")/function()
+ result.cid.count=stack[top]
+ top=0
+ end+P("\35")/function()
+ result.cid.uidbase=stack[top]
+ top=0
+ end+P("\36")/function()
+ result.cid.fdarray=stack[top]
+ top=0
+ end+P("\37")/function()
+ result.cid.fdselect=stack[top]
+ top=0
+ end+P("\38")/function()
+ result.cid.fontname=strings[stack[top]] or "unset"
+ top=0
+ end
+ )
+ local remap={
+ ["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0",
+ ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="1.",["\x1B"]="1E",["\x1C"]="1E-",["\x1D"]="1",["\x1E"]="1-",["\x1F"]="1",
+ ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="2.",["\x2B"]="2E",["\x2C"]="2E-",["\x2D"]="2",["\x2E"]="2-",["\x2F"]="2",
+ ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="3.",["\x3B"]="3E",["\x3C"]="3E-",["\x3D"]="3",["\x3E"]="3-",["\x3F"]="3",
+ ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="4.",["\x4B"]="4E",["\x4C"]="4E-",["\x4D"]="4",["\x4E"]="4-",["\x4F"]="4",
+ ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="5.",["\x5B"]="5E",["\x5C"]="5E-",["\x5D"]="5",["\x5E"]="5-",["\x5F"]="5",
+ ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="6.",["\x6B"]="6E",["\x6C"]="6E-",["\x6D"]="6",["\x6E"]="6-",["\x6F"]="6",
+ ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="7.",["\x7B"]="7E",["\x7C"]="7E-",["\x7D"]="7",["\x7E"]="7-",["\x7F"]="7",
+ ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="8.",["\x8B"]="8E",["\x8C"]="8E-",["\x8D"]="8",["\x8E"]="8-",["\x8F"]="8",
+ ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="9.",["\x9B"]="9E",["\x9C"]="9E-",["\x9D"]="9",["\x9E"]="9-",["\x9F"]="9",
+ ["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".",
+ ["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E",
+ ["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-",
+ ["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-",
+ }
+ local p_last=S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")+R("\xF0\xFF")
+ local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0*(P(1)/remap))/function(n)
+ top=top+1
+ stack[top]=tonumber(n) or 0
+ end
+ local p_byte=C(R("\32\246"))/function(b0)
+ top=top+1
+ stack[top]=byte(b0)-139
+ end
+ local p_positive=C(R("\247\250"))*C(1)/function(b0,b1)
+ top=top+1
+ stack[top]=(byte(b0)-247)*256+byte(b1)+108
+ end
+ local p_negative=C(R("\251\254"))*C(1)/function(b0,b1)
+ top=top+1
+ stack[top]=-(byte(b0)-251)*256-byte(b1)-108
+ end
+ local p_short=P("\28")*C(1)*C(1)/function(b1,b2)
+ top=top+1
+ local n=0x100*byte(b1)+byte(b2)
+ if n>=0x8000 then
+ stack[top]=n-0xFFFF-1
+ else
+ stack[top]=n
+ end
+ end
+ local p_long=P("\29")*C(1)*C(1)*C(1)*C(1)/function(b1,b2,b3,b4)
+ top=top+1
+ local n=0x1000000*byte(b1)+0x10000*byte(b2)+0x100*byte(b3)+byte(b4)
+ if n>=0x8000000 then
+ stack[top]=n-0xFFFFFFFF-1
+ else
+ stack[top]=n
+ end
+ end
+ local p_unsupported=P(1)/function(detail)
+ top=0
+ end
+ local p_dictionary=(
+ p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported
+ )^1
+ parsedictionaries=function(data,dictionaries,what)
+ stack={}
+ strings=data.strings
+ for i=1,#dictionaries do
+ top=0
+ result=what=="cff" and {
+ monospaced=false,
+ italicangle=0,
+ underlineposition=-100,
+ underlinethickness=50,
+ painttype=0,
+ charstringtype=2,
+ fontmatrix={ 0.001,0,0,0.001,0,0 },
+ fontbbox={ 0,0,0,0 },
+ strokewidth=0,
+ charset=0,
+ encoding=0,
+ cid={
+ fontversion=0,
+ fontrevision=0,
+ fonttype=0,
+ count=8720,
+ }
+ } or {
+ charstringtype=2,
+ charset=0,
+ vstore=0,
+ cid={
+ },
+ }
+ lpegmatch(p_dictionary,dictionaries[i])
+ dictionaries[i]=result
+ end
+ result={}
+ top=0
+ stack={}
+ end
+ parseprivates=function(data,dictionaries)
+ stack={}
+ strings=data.strings
+ for i=1,#dictionaries do
+ local private=dictionaries[i].private
+ if private and private.data then
+ top=0
+ result={
+ forcebold=false,
+ languagegroup=0,
+ expansionfactor=0.06,
+ initialrandomseed=0,
+ subroutines=0,
+ defaultwidthx=0,
+ nominalwidthx=0,
+ cid={
+ },
+ }
+ lpegmatch(p_dictionary,private.data)
+ private.data=result
+ end
+ end
+ result={}
+ top=0
+ stack={}
+ end
+ local x=0
+ local y=0
+ local width=false
+ local r=0
+ local stems=0
+ local globalbias=0
+ local localbias=0
+ local nominalwidth=0
+ local defaultwidth=0
+ local charset=false
+ local globals=false
+ local locals=false
+ local depth=1
+ local xmin=0
+ local xmax=0
+ local ymin=0
+ local ymax=0
+ local checked=false
+ local keepcurve=false
+ local version=2
+ local regions=false
+ local nofregions=0
+ local region=false
+ local factors=false
+ local axis=false
+ local vsindex=0
+ local function showstate(where)
+ report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top)
+ end
+ local function showvalue(where,value,showstack)
+ if showstack then
+ report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top)
+ else
+ report("%w%-10s : %s",depth*2,where,tostring(value))
+ end
+ end
+ local function xymoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
+ end
+ if checked then
+ if x>xmax then xmax=x elseif x<xmin then xmin=x end
+ if y>ymax then ymax=y elseif y<ymin then ymin=y end
+ else
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ end
+ end
+ local function xmoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif x>xmax then
+ xmax=x
+ elseif x<xmin then
+ xmin=x
+ end
+ end
+ local function ymoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif y>ymax then
+ ymax=y
+ elseif y<ymin then
+ ymin=y
+ end
+ end
+ local function moveto()
+ if trace_charstrings then
+ showstate("moveto")
+ end
+ top=0
+ xymoveto()
+ end
+ local function xylineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if checked then
+ if x>xmax then xmax=x elseif x<xmin then xmin=x end
+ if y>ymax then ymax=y elseif y<ymin then ymin=y end
+ else
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ end
+ end
+ local function xlineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif x>xmax then
+ xmax=x
+ elseif x<xmin then
+ xmin=x
+ end
+ end
+ local function ylineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif y>ymax then
+ ymax=y
+ elseif y<ymin then
+ ymin=y
+ end
+ end
+ local function xycurveto(x1,y1,x2,y2,x3,y3)
+ if trace_charstrings then
+ showstate("curveto")
+ end
+ if keepcurve then
+ r=r+1
+ result[r]={ x1,y1,x2,y2,x3,y3,"c" }
+ end
+ if checked then
+ if x1>xmax then xmax=x1 elseif x1<xmin then xmin=x1 end
+ if y1>ymax then ymax=y1 elseif y1<ymin then ymin=y1 end
+ else
+ xmin=x1
+ ymin=y1
+ xmax=x1
+ ymax=y1
+ checked=true
+ end
+ if x2>xmax then xmax=x2 elseif x2<xmin then xmin=x2 end
+ if y2>ymax then ymax=y2 elseif y2<ymin then ymin=y2 end
+ if x3>xmax then xmax=x3 elseif x3<xmin then xmin=x3 end
+ if y3>ymax then ymax=y3 elseif y3<ymin then ymin=y3 end
+ end
+ local function rmoveto()
+ if not width then
+ if top>2 then
+ width=stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
+ end
+ else
+ width=true
+ end
+ end
+ if trace_charstrings then
+ showstate("rmoveto")
+ end
+ x=x+stack[top-1]
+ y=y+stack[top]
+ top=0
+ xymoveto()
+ end
+ local function hmoveto()
+ if not width then
+ if top>1 then
+ width=stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
+ end
+ else
+ width=true
+ end
+ end
+ if trace_charstrings then
+ showstate("hmoveto")
+ end
+ x=x+stack[top]
+ top=0
+ xmoveto()
+ end
+ local function vmoveto()
+ if not width then
+ if top>1 then
+ width=stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
+ end
+ else
+ width=true
+ end
+ end
+ if trace_charstrings then
+ showstate("vmoveto")
+ end
+ y=y+stack[top]
+ top=0
+ ymoveto()
+ end
+ local function rlineto()
+ if trace_charstrings then
+ showstate("rlineto")
+ end
+ for i=1,top,2 do
+ x=x+stack[i]
+ y=y+stack[i+1]
+ xylineto()
+ end
+ top=0
+ end
+ local function hlineto()
+ if trace_charstrings then
+ showstate("hlineto")
+ end
+ if top==1 then
+ x=x+stack[1]
+ xlineto()
+ else
+ local swap=true
+ for i=1,top do
+ if swap then
+ x=x+stack[i]
+ xlineto()
+ swap=false
+ else
+ y=y+stack[i]
+ ylineto()
+ swap=true
+ end
+ end
+ end
+ top=0
+ end
+ local function vlineto()
+ if trace_charstrings then
+ showstate("vlineto")
+ end
+ if top==1 then
+ y=y+stack[1]
+ ylineto()
+ else
+ local swap=false
+ for i=1,top do
+ if swap then
+ x=x+stack[i]
+ xlineto()
+ swap=false
+ else
+ y=y+stack[i]
+ ylineto()
+ swap=true
+ end
+ end
+ end
+ top=0
+ end
+ local function rrcurveto()
+ if trace_charstrings then
+ showstate("rrcurveto")
+ end
+ for i=1,top,6 do
+ local ax=x+stack[i]
+ local ay=y+stack[i+1]
+ local bx=ax+stack[i+2]
+ local by=ay+stack[i+3]
+ x=bx+stack[i+4]
+ y=by+stack[i+5]
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ top=0
+ end
+ local function hhcurveto()
+ if trace_charstrings then
+ showstate("hhcurveto")
+ end
+ local s=1
+ if top%2~=0 then
+ y=y+stack[1]
+ s=2
+ end
+ for i=s,top,4 do
+ local ax=x+stack[i]
+ local ay=y
+ local bx=ax+stack[i+1]
+ local by=ay+stack[i+2]
+ x=bx+stack[i+3]
+ y=by
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ top=0
+ end
+ local function vvcurveto()
+ if trace_charstrings then
+ showstate("vvcurveto")
+ end
+ local s=1
+ local d=0
+ if top%2~=0 then
+ d=stack[1]
+ s=2
+ end
+ for i=s,top,4 do
+ local ax=x+d
+ local ay=y+stack[i]
+ local bx=ax+stack[i+1]
+ local by=ay+stack[i+2]
+ x=bx
+ y=by+stack[i+3]
+ xycurveto(ax,ay,bx,by,x,y)
+ d=0
+ end
+ top=0
+ end
+ local function xxcurveto(swap)
+ local last=top%4~=0 and stack[top]
+ if last then
+ top=top-1
+ end
+ for i=1,top,4 do
+ local ax,ay,bx,by
+ if swap then
+ ax=x+stack[i]
+ ay=y
+ bx=ax+stack[i+1]
+ by=ay+stack[i+2]
+ y=by+stack[i+3]
+ if last and i+3==top then
+ x=bx+last
+ else
+ x=bx
+ end
+ swap=false
+ else
+ ax=x
+ ay=y+stack[i]
+ bx=ax+stack[i+1]
+ by=ay+stack[i+2]
+ x=bx+stack[i+3]
+ if last and i+3==top then
+ y=by+last
+ else
+ y=by
+ end
+ swap=true
+ end
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ top=0
+ end
+ local function hvcurveto()
+ if trace_charstrings then
+ showstate("hvcurveto")
+ end
+ xxcurveto(true)
+ end
+ local function vhcurveto()
+ if trace_charstrings then
+ showstate("vhcurveto")
+ end
+ xxcurveto(false)
+ end
+ local function rcurveline()
+ if trace_charstrings then
+ showstate("rcurveline")
+ end
+ for i=1,top-2,6 do
+ local ax=x+stack[i]
+ local ay=y+stack[i+1]
+ local bx=ax+stack[i+2]
+ local by=ay+stack[i+3]
+ x=bx+stack[i+4]
+ y=by+stack[i+5]
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ x=x+stack[top-1]
+ y=y+stack[top]
+ xylineto()
+ top=0
+ end
+ local function rlinecurve()
+ if trace_charstrings then
+ showstate("rlinecurve")
+ end
+ if top>6 then
+ for i=1,top-6,2 do
+ x=x+stack[i]
+ y=y+stack[i+1]
+ xylineto()
+ end
+ end
+ local ax=x+stack[top-5]
+ local ay=y+stack[top-4]
+ local bx=ax+stack[top-3]
+ local by=ay+stack[top-2]
+ x=bx+stack[top-1]
+ y=by+stack[top]
+ xycurveto(ax,ay,bx,by,x,y)
+ top=0
+ end
+ local function flex()
+ if trace_charstrings then
+ showstate("flex")
+ end
+ local ax=x+stack[1]
+ local ay=y+stack[2]
+ local bx=ax+stack[3]
+ local by=ay+stack[4]
+ local cx=bx+stack[5]
+ local cy=by+stack[6]
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx=cx+stack[7]
+ local dy=cy+stack[8]
+ local ex=dx+stack[9]
+ local ey=dy+stack[10]
+ x=ex+stack[11]
+ y=ey+stack[12]
+ xycurveto(dx,dy,ex,ey,x,y)
+ top=0
+ end
+ local function hflex()
+ if trace_charstrings then
+ showstate("hflex")
+ end
+ local ax=x+stack[1]
+ local ay=y
+ local bx=ax+stack[2]
+ local by=ay+stack[3]
+ local cx=bx+stack[4]
+ local cy=by
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx=cx+stack[5]
+ local dy=by
+ local ex=dx+stack[6]
+ local ey=y
+ x=ex+stack[7]
+ xycurveto(dx,dy,ex,ey,x,y)
+ top=0
+ end
+ local function hflex1()
+ if trace_charstrings then
+ showstate("hflex1")
+ end
+ local ax=x+stack[1]
+ local ay=y+stack[2]
+ local bx=ax+stack[3]
+ local by=ay+stack[4]
+ local cx=bx+stack[5]
+ local cy=by
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx=cx+stack[6]
+ local dy=by
+ local ex=dx+stack[7]
+ local ey=dy+stack[8]
+ x=ex+stack[9]
+ xycurveto(dx,dy,ex,ey,x,y)
+ top=0
+ end
+ local function flex1()
+ if trace_charstrings then
+ showstate("flex1")
+ end
+ local ax=x+stack[1]
+ local ay=y+stack[2]
+ local bx=ax+stack[3]
+ local by=ay+stack[4]
+ local cx=bx+stack[5]
+ local cy=by+stack[6]
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx=cx+stack[7]
+ local dy=cy+stack[8]
+ local ex=dx+stack[9]
+ local ey=dy+stack[10]
+ if abs(ex-x)>abs(ey-y) then
+ x=ex+stack[11]
+ else
+ y=ey+stack[11]
+ end
+ xycurveto(dx,dy,ex,ey,x,y)
+ top=0
+ end
+ local function getstem()
+ if top==0 then
+ elseif top%2~=0 then
+ if width then
+ remove(stack,1)
+ else
+ width=remove(stack,1)
+ if trace_charstrings then
+ showvalue("width",width)
+ end
+ end
+ top=top-1
+ end
+ if trace_charstrings then
+ showstate("stem")
+ end
+ stems=stems+idiv(top,2)
+ top=0
+ end
+ local function getmask()
+ if top==0 then
+ elseif top%2~=0 then
+ if width then
+ remove(stack,1)
+ else
+ width=remove(stack,1)
+ if trace_charstrings then
+ showvalue("width",width)
+ end
+ end
+ top=top-1
+ end
+ if trace_charstrings then
+ showstate(operator==19 and "hintmark" or "cntrmask")
+ end
+ stems=stems+idiv(top,2)
+ top=0
+ if stems==0 then
+ elseif stems<=8 then
+ return 1
+ else
+ return idiv(stems+7,8)
+ end
+ end
+ local function unsupported(t)
+ if trace_charstrings then
+ showstate("unsupported "..t)
+ end
+ top=0
+ end
+ local function unsupportedsub(t)
+ if trace_charstrings then
+ showstate("unsupported sub "..t)
+ end
+ top=0
+ end
+ local function getstem3()
+ if trace_charstrings then
+ showstate("stem3")
+ end
+ top=0
+ end
+ local function divide()
+ if version==1 then
+ local d=stack[top]
+ top=top-1
+ stack[top]=stack[top]/d
+ end
+ end
+ local function closepath()
+ if version==1 then
+ if trace_charstrings then
+ showstate("closepath")
+ end
+ end
+ top=0
+ end
+ local function hsbw()
+ if version==1 then
+ if trace_charstrings then
+ showstate("hsbw")
+ end
+ width=stack[top]
+ end
+ top=0
+ end
+ local function seac()
+ if version==1 then
+ if trace_charstrings then
+ showstate("seac")
+ end
+ end
+ top=0
+ end
+ local function sbw()
+ if version==1 then
+ if trace_charstrings then
+ showstate("sbw")
+ end
+ width=stack[top-1]
+ end
+ top=0
+ end
+ local function callothersubr()
+ if version==1 then
+ if trace_charstrings then
+ showstate("callothersubr (unsupported)")
+ end
+ end
+ top=0
+ end
+ local function pop()
+ if version==1 then
+ if trace_charstrings then
+ showstate("pop (unsupported)")
+ end
+ top=top+1
+ stack[top]=0
+ else
+ top=0
+ end
+ end
+ local function setcurrentpoint()
+ if version==1 then
+ if trace_charstrings then
+ showstate("pop (unsupported)")
+ end
+ x=x+stack[top-1]
+ y=y+stack[top]
+ end
+ top=0
+ end
+ local reginit=false
+ local function updateregions(n)
+ if regions then
+ local current=regions[n] or regions[1]
+ nofregions=#current
+ if axis and n~=reginit then
+ factors={}
+ for i=1,nofregions do
+ local region=current[i]
+ local s=1
+ for j=1,#axis do
+ local f=axis[j]
+ local r=region[j]
+ local start=r.start
+ local peak=r.peak
+ local stop=r.stop
+ if start>peak or peak>stop then
+ elseif start<0 and stop>0 and peak~=0 then
+ elseif peak==0 then
+ elseif f<start or f>stop then
+ s=0
+ break
+ elseif f<peak then
+ s=s*(f-start)/(peak-start)
+ elseif f>peak then
+ s=s*(stop-f)/(stop-peak)
+ else
+ end
+ end
+ factors[i]=s
+ end
+ end
+ end
+ reginit=n
+ end
+ local function setvsindex()
+ local vsindex=stack[top]
+ if trace_charstrings then
+ showstate(formatters["vsindex %i"](vsindex))
+ end
+ updateregions(vsindex)
+ top=top-1
+ end
+ local function blend()
+ local n=stack[top]
+ top=top-1
+ if axis then
+ if trace_charstrings then
+ local t=top-nofregions*n
+ local m=t-n
+ for i=1,n do
+ local k=m+i
+ local d=m+n+(i-1)*nofregions
+ local old=stack[k]
+ local new=old
+ for r=1,nofregions do
+ new=new+stack[d+r]*factors[r]
+ end
+ stack[k]=new
+ showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new))
+ end
+ top=t
+ elseif n==1 then
+ top=top-nofregions
+ local v=stack[top]
+ for r=1,nofregions do
+ v=v+stack[top+r]*factors[r]
+ end
+ stack[top]=v
+ else
+ top=top-nofregions*n
+ local d=top
+ local k=top-n
+ for i=1,n do
+ k=k+1
+ local v=stack[k]
+ for r=1,nofregions do
+ v=v+stack[d+r]*factors[r]
+ end
+ stack[k]=v
+ d=d+nofregions
+ end
+ end
+ else
+ end
+ end
+ local actions={ [0]=unsupported,
+ getstem,
+ unsupported,
+ getstem,
+ vmoveto,
+ rlineto,
+ hlineto,
+ vlineto,
+ rrcurveto,
+ unsupported,
+ unsupported,
+ unsupported,
+ unsupported,
+ hsbw,
+ unsupported,
+ setvsindex,
+ blend,
+ unsupported,
+ getstem,
+ getmask,
+ getmask,
+ rmoveto,
+ hmoveto,
+ getstem,
+ rcurveline,
+ rlinecurve,
+ vvcurveto,
+ hhcurveto,
+ unsupported,
+ unsupported,
+ vhcurveto,
+ hvcurveto,
+ }
+ local subactions={
+ [000]=dotsection,
+ [001]=getstem3,
+ [002]=getstem3,
+ [006]=seac,
+ [007]=sbw,
+ [012]=divide,
+ [016]=callothersubr,
+ [017]=pop,
+ [033]=setcurrentpoint,
+ [034]=hflex,
+ [035]=flex,
+ [036]=hflex1,
+ [037]=flex1,
+ }
+ local chars=setmetatableindex(function (t,k)
+ local v=char(k)
+ t[k]=v
+ return v
+ end)
+ local c_endchar=chars[14]
+ local encode={}
+ setmetatableindex(encode,function(t,i)
+ for i=-2048,-1130 do
+ t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+ end
+ for i=-1131,-108 do
+ local v=0xFB00-i-108
+ t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF))
+ end
+ for i=-107,107 do
+ t[i]=chars[i+139]
+ end
+ for i=108,1131 do
+ local v=0xF700+i-108
+ t[i]=char(extract(v,8,8),extract(v,0,8))
+ end
+ for i=1132,2048 do
+ t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+ end
+ setmetatableindex(encode,function(t,k)
+ local r=round(k)
+ local v=rawget(t,r)
+ if v then
+ return v
+ end
+ local v1=floor(k)
+ local v2=floor((k-v1)*0x10000)
+ return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8))
+ end)
+ return t[i]
+ end)
+ readers.cffencoder=encode
+ local function p_setvsindex()
+ local vsindex=stack[top]
+ updateregions(vsindex)
+ top=top-1
+ end
+ local function p_blend()
+ local n=stack[top]
+ top=top-1
+ if not axis then
+ elseif n==1 then
+ top=top-nofregions
+ local v=stack[top]
+ for r=1,nofregions do
+ v=v+stack[top+r]*factors[r]
+ end
+ stack[top]=round(v)
+ else
+ top=top-nofregions*n
+ local d=top
+ local k=top-n
+ for i=1,n do
+ k=k+1
+ local v=stack[k]
+ for r=1,nofregions do
+ v=v+stack[d+r]*factors[r]
+ end
+ stack[k]=round(v)
+ d=d+nofregions
+ end
+ end
+ end
+ local function p_getstem()
+ local n=0
+ if top%2~=0 then
+ n=1
+ end
+ if top>n then
+ stems=stems+idiv(top-n,2)
+ end
+ end
+ local function p_getmask()
+ local n=0
+ if top%2~=0 then
+ n=1
+ end
+ if top>n then
+ stems=stems+idiv(top-n,2)
+ end
+ if stems==0 then
+ return 0
+ elseif stems<=8 then
+ return 1
+ else
+ return idiv(stems+7,8)
+ end
+ end
+ local process
+ local function call(scope,list,bias)
+ depth=depth+1
+ if top==0 then
+ showstate(formatters["unknown %s call %s"](scope,"?"))
+ top=0
+ else
+ local index=stack[top]+bias
+ top=top-1
+ if trace_charstrings then
+ showvalue(scope,index,true)
+ end
+ local tab=list[index]
+ if tab then
+ process(tab)
+ else
+ showstate(formatters["unknown %s call %s"](scope,index))
+ top=0
+ end
+ end
+ depth=depth-1
+ end
+ local justpass=false
+ process=function(tab)
+ local i=1
+ local n=#tab
+ while i<=n do
+ local t=tab[i]
+ if t>=32 then
+ top=top+1
+ if t<=246 then
+ stack[top]=t-139
+ i=i+1
+ elseif t<=250 then
+ stack[top]=t*256-63124+tab[i+1]
+ i=i+2
+ elseif t<=254 then
+ stack[top]=-t*256+64148-tab[i+1]
+ i=i+2
+ else
+ local n=0x100*tab[i+1]+tab[i+2]
+ if n>=0x8000 then
+ stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF
+ else
+ stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF
+ end
+ i=i+5
+ end
+ elseif t==28 then
+ top=top+1
+ local n=0x100*tab[i+1]+tab[i+2]
+ if n>=0x8000 then
+ stack[top]=n-0x10000
+ else
+ stack[top]=n
+ end
+ i=i+3
+ elseif t==11 then
+ if trace_charstrings then
+ showstate("return")
+ end
+ return
+ elseif t==10 then
+ call("local",locals,localbias)
+ i=i+1
+ elseif t==14 then
+ if width then
+ elseif top>0 then
+ width=stack[1]
+ if trace_charstrings then
+ showvalue("width",width)
+ end
+ else
+ width=true
+ end
+ if trace_charstrings then
+ showstate("endchar")
+ end
+ return
+ elseif t==29 then
+ call("global",globals,globalbias)
+ i=i+1
+ elseif t==12 then
+ i=i+1
+ local t=tab[i]
+ if justpass then
+ if t>=34 and t<=37 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ r=r+1;result[r]=chars[12]
+ r=r+1;result[r]=chars[t]
+ top=0
+ else
+ local a=subactions[t]
+ if a then
+ a(t)
+ else
+ top=0
+ end
+ end
+ else
+ local a=subactions[t]
+ if a then
+ a(t)
+ else
+ if trace_charstrings then
+ showvalue("<subaction>",t)
+ end
+ top=0
+ end
+ end
+ i=i+1
+ elseif justpass then
+ if t==15 then
+ p_setvsindex()
+ i=i+1
+ elseif t==16 then
+ local s=p_blend() or 0
+ i=i+s+1
+ elseif t==1 or t==3 or t==18 or operation==23 then
+ p_getstem()
+if true then
+ if top>0 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ top=0
+ end
+ r=r+1;result[r]=chars[t]
+else
+ top=0
+end
+ i=i+1
+ elseif t==19 or t==20 then
+ local s=p_getmask() or 0
+if true then
+ if top>0 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ top=0
+ end
+ r=r+1;result[r]=chars[t]
+ for j=1,s do
+ i=i+1
+ r=r+1;result[r]=chars[tab[i]]
+ end
+else
+ i=i+s
+ top=0
+end
+ i=i+1
+ elseif t==9 then
+ top=0
+ i=i+1
+ elseif t==13 then
+ local s=hsbw() or 0
+ i=i+s+1
+ else
+ if top>0 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ top=0
+ end
+ r=r+1;result[r]=chars[t]
+ i=i+1
+ end
+ else
+ local a=actions[t]
+ if a then
+ local s=a(t)
+ if s then
+ i=i+s+1
+ else
+ i=i+1
+ end
+ else
+ if trace_charstrings then
+ showvalue("<action>",t)
+ end
+ top=0
+ i=i+1
+ end
+ end
+ end
+ end
+ local function setbias(globals,locals,nobias)
+ if nobias then
+ return 0,0
+ else
+ local g=#globals
+ local l=#locals
+ return
+ ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1,
+ ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1
+ end
+ end
+ local function processshape(tab,index)
+ if not tab then
+ glyphs[index]={
+ boundingbox={ 0,0,0,0 },
+ width=0,
+ name=charset and charset[index] or nil,
+ }
+ return
+ end
+ tab=bytetable(tab)
+ x=0
+ y=0
+ width=false
+ r=0
+ top=0
+ stems=0
+ result={}
+ xmin=0
+ xmax=0
+ ymin=0
+ ymax=0
+ checked=false
+ if trace_charstrings then
+ report("glyph: %i",index)
+ report("data : % t",tab)
+ end
+ if regions then
+ updateregions(vsindex)
+ end
+ process(tab)
+ local boundingbox={
+ round(xmin),
+ round(ymin),
+ round(xmax),
+ round(ymax),
+ }
+ if width==true or width==false then
+ width=defaultwidth
+ else
+ width=nominalwidth+width
+ end
+ local glyph=glyphs[index]
+ if justpass then
+ r=r+1
+ result[r]=c_endchar
+ local stream=concat(result)
+ if glyph then
+ glyph.stream=stream
+ else
+ glyphs[index]={ stream=stream }
+ end
+ elseif glyph then
+ glyph.segments=keepcurve~=false and result or nil
+ glyph.boundingbox=boundingbox
+ if not glyph.width then
+ glyph.width=width
+ end
+ if charset and not glyph.name then
+ glyph.name=charset[index]
+ end
+ elseif keepcurve then
+ glyphs[index]={
+ segments=result,
+ boundingbox=boundingbox,
+ width=width,
+ name=charset and charset[index] or nil,
+ }
+ else
+ glyphs[index]={
+ boundingbox=boundingbox,
+ width=width,
+ name=charset and charset[index] or nil,
+ }
+ end
+ if trace_charstrings then
+ report("width : %s",tostring(width))
+ report("boundingbox: % t",boundingbox)
+ end
+ end
+ startparsing=function(fontdata,data,streams)
+ reginit=false
+ axis=false
+ regions=data.regions
+ justpass=streams==true
+ if regions then
+ regions={ regions }
+ axis=data.factors or false
+ end
+ end
+ stopparsing=function(fontdata,data)
+ stack={}
+ glyphs=false
+ result={}
+ top=0
+ locals=false
+ globals=false
+ strings=false
+ end
+ local function setwidths(private)
+ if not private then
+ return 0,0
+ end
+ local privatedata=private.data
+ if not privatedata then
+ return 0,0
+ end
+ return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0
+ end
+ parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams,nobias)
+ local dictionary=data.dictionaries[1]
+ local charstrings=dictionary.charstrings
+ keepcurve=doshapes
+ version=tversion
+ strings=data.strings
+ globals=data.routines or {}
+ locals=dictionary.subroutines or {}
+ charset=dictionary.charset
+ vsindex=dictionary.vsindex or 0
+ glyphs=glphs or {}
+ globalbias,localbias=setbias(globals,locals,nobias)
+ nominalwidth,defaultwidth=setwidths(dictionary.private)
+ if charstrings then
+ startparsing(fontdata,data,streams)
+ for index=1,#charstrings do
+ processshape(charstrings[index],index-1)
+ end
+ stopparsing(fontdata,data)
+ else
+ report("no charstrings")
+ end
+ return glyphs
+ end
+ parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams)
+ keepcurve=doshapes
+ version=tversion
+ strings=data.strings
+ globals=data.routines or {}
+ locals=dictionary.subroutines or {}
+ charset=false
+ vsindex=dictionary.vsindex or 0
+ glyphs=glphs or {}
+ justpass=streams==true
+ globalbias,localbias=setbias(globals,locals,nobias)
+ nominalwidth,defaultwidth=setwidths(dictionary.private)
+ processshape(tab,index-1)
+ end
+end
+local function readglobals(f,data)
+ local routines=readlengths(f)
+ for i=1,#routines do
+ routines[i]=readbytetable(f,routines[i])
+ end
+ data.routines=routines
+end
+local function readencodings(f,data)
+ data.encodings={}
+end
+local function readcharsets(f,data,dictionary)
+ local header=data.header
+ local strings=data.strings
+ local nofglyphs=data.nofglyphs
+ local charsetoffset=dictionary.charset
+ if charsetoffset and charsetoffset~=0 then
+ setposition(f,header.offset+charsetoffset)
+ local format=readbyte(f)
+ local charset={ [0]=".notdef" }
+ dictionary.charset=charset
+ if format==0 then
+ for i=1,nofglyphs do
+ charset[i]=strings[readushort(f)]
+ end
+ elseif format==1 or format==2 then
+ local readcount=format==1 and readbyte or readushort
+ local i=1
+ while i<=nofglyphs do
+ local sid=readushort(f)
+ local n=readcount(f)
+ for s=sid,sid+n do
+ charset[i]=strings[s]
+ i=i+1
+ if i>nofglyphs then
+ break
+ end
+ end
+ end
+ else
+ report("cff parser: unsupported charset format %a",format)
+ end
+ else
+ dictionary.nocharset=true
+ dictionary.charset=nil
+ end
+end
+local function readprivates(f,data)
+ local header=data.header
+ local dictionaries=data.dictionaries
+ local private=dictionaries[1].private
+ if private then
+ setposition(f,header.offset+private.offset)
+ private.data=readstring(f,private.size)
+ end
+end
+local function readlocals(f,data,dictionary)
+ local header=data.header
+ local private=dictionary.private
+ if private then
+ local subroutineoffset=private.data.subroutines
+ if subroutineoffset~=0 then
+ setposition(f,header.offset+private.offset+subroutineoffset)
+ local subroutines=readlengths(f)
+ for i=1,#subroutines do
+ subroutines[i]=readbytetable(f,subroutines[i])
+ end
+ dictionary.subroutines=subroutines
+ private.data.subroutines=nil
+ else
+ dictionary.subroutines={}
+ end
+ else
+ dictionary.subroutines={}
+ end
+end
+local function readcharstrings(f,data,what)
+ local header=data.header
+ local dictionaries=data.dictionaries
+ local dictionary=dictionaries[1]
+ local stringtype=dictionary.charstringtype
+ local offset=dictionary.charstrings
+ if type(offset)~="number" then
+ elseif stringtype==2 then
+ setposition(f,header.offset+offset)
+ local charstrings=readlengths(f,what=="cff2")
+ local nofglyphs=#charstrings
+ for i=1,nofglyphs do
+ charstrings[i]=readstring(f,charstrings[i])
+ end
+ data.nofglyphs=nofglyphs
+ dictionary.charstrings=charstrings
+ else
+ report("unsupported charstr type %i",stringtype)
+ data.nofglyphs=0
+ dictionary.charstrings={}
+ end
+end
+local function readcidprivates(f,data)
+ local header=data.header
+ local dictionaries=data.dictionaries[1].cid.dictionaries
+ for i=1,#dictionaries do
+ local dictionary=dictionaries[i]
+ local private=dictionary.private
+ if private then
+ setposition(f,header.offset+private.offset)
+ private.data=readstring(f,private.size)
+ end
+ end
+ parseprivates(data,dictionaries)
+end
+readers.parsecharstrings=parsecharstrings
+local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
+ local dictionaries=data.dictionaries
+ local dictionary=dictionaries[1]
+ readglobals(f,data)
+ readcharstrings(f,data,version)
+ if version=="cff2" then
+ dictionary.charset=nil
+ else
+ readencodings(f,data)
+ readcharsets(f,data,dictionary)
+ end
+ readprivates(f,data)
+ parseprivates(data,data.dictionaries)
+ readlocals(f,data,dictionary)
+ startparsing(fontdata,data,streams)
+ parsecharstrings(fontdata,data,glyphs,doshapes,version,streams)
+ stopparsing(fontdata,data)
+end
+local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
+ local header=data.header
+ local dictionaries=data.dictionaries
+ local dictionary=dictionaries[1]
+ local cid=dictionary.cid
+ local cidselect=cid and cid.fdselect
+ readglobals(f,data)
+ readcharstrings(f,data,version)
+ if version~="cff2" then
+ readencodings(f,data)
+ end
+ local charstrings=dictionary.charstrings
+ local fdindex={}
+ local nofglyphs=data.nofglyphs
+ local maxindex=-1
+ setposition(f,header.offset+cidselect)
+ local format=readbyte(f)
+ if format==1 then
+ for i=0,nofglyphs do
+ local index=readbyte(f)
+ fdindex[i]=index
+ if index>maxindex then
+ maxindex=index
+ end
+ end
+ elseif format==3 then
+ local nofranges=readushort(f)
+ local first=readushort(f)
+ local index=readbyte(f)
+ while true do
+ local last=readushort(f)
+ if index>maxindex then
+ maxindex=index
+ end
+ for i=first,last do
+ fdindex[i]=index
+ end
+ if last>=nofglyphs then
+ break
+ else
+ first=last+1
+ index=readbyte(f)
+ end
+ end
+ else
+ end
+ if maxindex>=0 then
+ local cidarray=cid.fdarray
+ if cidarray then
+ setposition(f,header.offset+cidarray)
+ local dictionaries=readlengths(f)
+ for i=1,#dictionaries do
+ dictionaries[i]=readstring(f,dictionaries[i])
+ end
+ parsedictionaries(data,dictionaries)
+ cid.dictionaries=dictionaries
+ readcidprivates(f,data)
+ for i=1,#dictionaries do
+ readlocals(f,data,dictionaries[i])
+ end
+ startparsing(fontdata,data,streams)
+ for i=1,#charstrings do
+ parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version,streams)
+ end
+ stopparsing(fontdata,data)
+ else
+ report("no cid array")
+ end
+ end
+end
+local gotodatatable=readers.helpers.gotodatatable
+local function cleanup(data,dictionaries)
+end
+function readers.cff(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs)
+ if tableoffset then
+ local header=readheader(f)
+ if header.major~=1 then
+ report("only version %s is supported for table %a",1,"cff")
+ return
+ end
+ local glyphs=fontdata.glyphs
+ local names=readfontnames(f)
+ local dictionaries=readtopdictionaries(f)
+ local strings=readstrings(f)
+ local data={
+ header=header,
+ names=names,
+ dictionaries=dictionaries,
+ strings=strings,
+ nofglyphs=fontdata.nofglyphs,
+ }
+ parsedictionaries(data,dictionaries,"cff")
+ local dic=dictionaries[1]
+ local cid=dic.cid
+ local cffinfo={
+ familyname=dic.familyname,
+ fullname=dic.fullname,
+ boundingbox=dic.boundingbox,
+ weight=dic.weight,
+ italicangle=dic.italicangle,
+ underlineposition=dic.underlineposition,
+ underlinethickness=dic.underlinethickness,
+ defaultwidth=dic.defaultwidthx,
+ nominalwidth=dic.nominalwidthx,
+ monospaced=dic.monospaced,
+ }
+ fontdata.cidinfo=cid and {
+ registry=cid.registry,
+ ordering=cid.ordering,
+ supplement=cid.supplement,
+ }
+ fontdata.cffinfo=cffinfo
+ local all=specification.shapes or specification.streams or false
+ if specification.glyphs or all then
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
+ else
+ readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
+ end
+ end
+ local private=dic.private
+ if private then
+ local data=private.data
+ if type(data)=="table" then
+ cffinfo.defaultwidth=data.defaultwidthx or cffinfo.defaultwidth
+ cffinfo.nominalwidth=data.nominalwidthx or cffinfo.nominalwidth
+ cffinfo.bluevalues=data.bluevalues
+ cffinfo.otherblues=data.otherblues
+ cffinfo.familyblues=data.familyblues
+ cffinfo.familyotherblues=data.familyotherblues
+ cffinfo.bluescale=data.bluescale
+ cffinfo.blueshift=data.blueshift
+ cffinfo.bluefuzz=data.bluefuzz
+ cffinfo.stdhw=data.stdhw
+ cffinfo.stdvw=data.stdvw
+ end
+ end
+ cleanup(data,dictionaries)
+ end
+end
+function readers.cff2(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"cff2",specification.glyphs)
+ if tableoffset then
+ local header=readheader(f)
+ if header.major~=2 then
+ report("only version %s is supported for table %a",2,"cff2")
+ return
+ end
+ local glyphs=fontdata.glyphs
+ local dictionaries={ readstring(f,header.dsize) }
+ local data={
+ header=header,
+ dictionaries=dictionaries,
+ nofglyphs=fontdata.nofglyphs,
+ }
+ parsedictionaries(data,dictionaries,"cff2")
+ 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 specification.streams or false
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
+ else
+ readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
+ end
+ cleanup(data,dictionaries)
+ end
+end
+function readers.cffcheck(filename)
+ local f=io.open(filename,"rb")
+ if f then
+ local fontdata={
+ glyphs={},
+ }
+ local header=readheader(f)
+ if header.major~=1 then
+ report("only version %s is supported for table %a",1,"cff")
+ return
+ end
+ local names=readfontnames(f)
+ local dictionaries=readtopdictionaries(f)
+ local strings=readstrings(f)
+ local glyphs={}
+ local data={
+ header=header,
+ names=names,
+ dictionaries=dictionaries,
+ strings=strings,
+ glyphs=glyphs,
+ nofglyphs=0,
+ }
+ parsedictionaries(data,dictionaries,"cff")
+ local cid=data.dictionaries[1].cid
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,false)
+ else
+ readnoselect(f,fontdata,data,glyphs,false)
+ end
+ return data
+ end
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-cffâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ttf†44e61cef50dab9b1aaf48130f9367c34] ---
+
+if not modules then modules={} end modules ['font-ttf']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type,unpack=next,type,unpack
+local band,rshift=bit32.band,bit32.rshift
+local sqrt,round=math.sqrt,math.round
+local char,rep=string.char,string.rep
+local concat=table.concat
+local idiv=number.idiv
+local setmetatableindex=table.setmetatableindex
+local report=logs.reporter("otf reader","ttf")
+local trace_deltas=false
+local readers=fonts.handlers.otf.readers
+local streamreader=readers.streamreader
+local setposition=streamreader.setposition
+local getposition=streamreader.getposition
+local skipbytes=streamreader.skip
+local readbyte=streamreader.readcardinal1
+local readushort=streamreader.readcardinal2
+local readulong=streamreader.readcardinal4
+local readchar=streamreader.readinteger1
+local readshort=streamreader.readinteger2
+local read2dot14=streamreader.read2dot14
+local readinteger=streamreader.readinteger1
+local readcardinaltable=streamreader.readcardinaltable
+local readintegertable=streamreader.readintegertable
+directives.register("fonts.streamreader",function()
+ streamreader=utilities.streams
+ setposition=streamreader.setposition
+ getposition=streamreader.getposition
+ skipbytes=streamreader.skip
+ readbyte=streamreader.readcardinal1
+ readushort=streamreader.readcardinal2
+ readulong=streamreader.readcardinal4
+ readchar=streamreader.readinteger1
+ readshort=streamreader.readinteger2
+ read2dot14=streamreader.read2dot14
+ readinteger=streamreader.readinteger1
+ readcardinaltable=streamreader.readcardinaltable
+ readintegertable=streamreader.readintegertable
+end)
+local short=2
+local ushort=2
+local ulong=4
+local helpers=readers.helpers
+local gotodatatable=helpers.gotodatatable
+local function mergecomposites(glyphs,shapes)
+ local function merge(index,shape,components)
+ local contours={}
+ local points={}
+ local nofcontours=0
+ local nofpoints=0
+ local offset=0
+ local deltas=shape.deltas
+ for i=1,#components do
+ local component=components[i]
+ local subindex=component.index
+ local subshape=shapes[subindex]
+ local subcontours=subshape.contours
+ local subpoints=subshape.points
+ if not subcontours then
+ local subcomponents=subshape.components
+ if subcomponents then
+ subcontours,subpoints=merge(subindex,subshape,subcomponents)
+ end
+ end
+ if subpoints then
+ local matrix=component.matrix
+ local xscale=matrix[1]
+ local xrotate=matrix[2]
+ local yrotate=matrix[3]
+ local yscale=matrix[4]
+ local xoffset=matrix[5]
+ local yoffset=matrix[6]
+ local count=#subpoints
+ if xscale==1 and yscale==1 and xrotate==0 and yrotate==0 then
+ for i=1,count do
+ local p=subpoints[i]
+ nofpoints=nofpoints+1
+ points[nofpoints]={
+ p[1]+xoffset,
+ p[2]+yoffset,
+ p[3]
+ }
+ end
+ else
+ for i=1,count do
+ local p=subpoints[i]
+ local x=p[1]
+ local y=p[2]
+ nofpoints=nofpoints+1
+ points[nofpoints]={
+ xscale*x+xrotate*y+xoffset,
+ yscale*y+yrotate*x+yoffset,
+ p[3]
+ }
+ end
+ end
+ local subcount=#subcontours
+ if subcount==1 then
+ nofcontours=nofcontours+1
+ contours[nofcontours]=offset+subcontours[1]
+ else
+ for i=1,#subcontours do
+ nofcontours=nofcontours+1
+ contours[nofcontours]=offset+subcontours[i]
+ end
+ end
+ offset=offset+count
+ else
+ report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex)
+ end
+ end
+ shape.points=points
+ shape.contours=contours
+ shape.components=nil
+ return contours,points
+ end
+ for index=0,#glyphs-1 do
+ local shape=shapes[index]
+ if shape then
+ local components=shape.components
+ if components then
+ merge(index,shape,components)
+ end
+ end
+ end
+end
+local function readnothing(f)
+ return {
+ type="nothing",
+ }
+end
+local function curveto(m_x,m_y,l_x,l_y,r_x,r_y)
+ return
+ l_x+2/3*(m_x-l_x),l_y+2/3*(m_y-l_y),
+ r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y),
+ r_x,r_y,"c"
+end
+local function applyaxis(glyph,shape,deltas,dowidth)
+ local points=shape.points
+ if points then
+ local nofpoints=#points
+ local h=nofpoints+2
+ local l=nofpoints+1
+ local dw=0
+ local dl=0
+ for i=1,#deltas do
+ local deltaset=deltas[i]
+ local xvalues=deltaset.xvalues
+ local yvalues=deltaset.yvalues
+ local dpoints=deltaset.points
+ local factor=deltaset.factor
+ if dpoints then
+ local nofdpoints=#dpoints
+ for i=1,nofdpoints do
+ local d=dpoints[i]
+ local p=points[d]
+ if p then
+ if xvalues then
+ local x=xvalues[i]
+ if x and x~=0 then
+ p[1]=p[1]+factor*x
+ end
+ end
+ if yvalues then
+ local y=yvalues[i]
+ if y and y~=0 then
+ p[2]=p[2]+factor*y
+ end
+ end
+ elseif dowidth then
+ if d==h then
+ local x=xvalues[i]
+ if x then
+ dw=dw+factor*x
+ end
+ elseif d==l then
+ local x=xvalues[i]
+ if x then
+ dl=dl+factor*x
+ end
+ end
+ end
+ end
+ else
+ for i=1,nofpoints do
+ local p=points[i]
+ if xvalues then
+ local x=xvalues[i]
+ if x and x~=0 then
+ p[1]=p[1]+factor*x
+ end
+ end
+ if yvalues then
+ local y=yvalues[i]
+ if y and y~=0 then
+ p[2]=p[2]+factor*y
+ end
+ end
+ end
+ if dowidth then
+ local x=xvalues[h]
+ if x then
+ dw=dw+factor*x
+ end
+ local x=xvalues[l]
+ if x then
+ dl=dl+factor*x
+ end
+ end
+ end
+ end
+ if dowidth then
+ local width=glyph.width or 0
+ glyph.width=width+dw-dl
+ end
+ else
+ report("no points for glyph %a",glyph.name)
+ end
+end
+local quadratic=false
+local function contours2outlines_normal(glyphs,shapes)
+ for index=0,#glyphs-1 do
+ local shape=shapes[index]
+ if shape then
+ local glyph=glyphs[index]
+ local contours=shape.contours
+ local points=shape.points
+ if contours then
+ local nofcontours=#contours
+ local segments={}
+ local nofsegments=0
+ glyph.segments=segments
+ if nofcontours>0 then
+ local px=0
+ local py=0
+ local first=1
+ for i=1,nofcontours do
+ local last=contours[i]
+ if last>=first then
+ local first_pt=points[first]
+ local first_on=first_pt[3]
+ if first==last then
+ first_pt[3]="m"
+ nofsegments=nofsegments+1
+ segments[nofsegments]=first_pt
+ else
+ local first_on=first_pt[3]
+ local last_pt=points[last]
+ local last_on=last_pt[3]
+ local start=1
+ local control_pt=false
+ if first_on then
+ start=2
+ else
+ if last_on then
+ first_pt=last_pt
+ else
+ first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false }
+ end
+ control_pt=first_pt
+ end
+ local x=first_pt[1]
+ local y=first_pt[2]
+ if not done then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ done=true
+ end
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x,y,"m" }
+ if not quadratic then
+ px=x
+ py=y
+ end
+ local previous_pt=first_pt
+ for i=first,last do
+ local current_pt=points[i]
+ local current_on=current_pt[3]
+ local previous_on=previous_pt[3]
+ if previous_on then
+ if current_on then
+ local x,y=current_pt[1],current_pt[2]
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x,y,"l" }
+ if not quadratic then
+ px,py=x,y
+ end
+ else
+ control_pt=current_pt
+ end
+ elseif current_on then
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ local x2=current_pt[1]
+ local y2=current_pt[2]
+ nofsegments=nofsegments+1
+ if quadratic then
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ control_pt=false
+ else
+ local x2=(previous_pt[1]+current_pt[1])/2
+ local y2=(previous_pt[2]+current_pt[2])/2
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ nofsegments=nofsegments+1
+ if quadratic then
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ control_pt=current_pt
+ end
+ previous_pt=current_pt
+ end
+ if first_pt==last_pt then
+ else
+ nofsegments=nofsegments+1
+ local x2=first_pt[1]
+ local y2=first_pt[2]
+ if not control_pt then
+ segments[nofsegments]={ x2,y2,"l" }
+ elseif quadratic then
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ else
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ end
+ end
+ end
+ first=last+1
+ end
+ end
+ end
+ end
+ end
+end
+local function contours2outlines_shaped(glyphs,shapes,keepcurve)
+ for index=0,#glyphs-1 do
+ local shape=shapes[index]
+ if shape then
+ local glyph=glyphs[index]
+ local contours=shape.contours
+ local points=shape.points
+ if contours then
+ local nofcontours=#contours
+ local segments=keepcurve and {} or nil
+ local nofsegments=0
+ if keepcurve then
+ glyph.segments=segments
+ end
+ if nofcontours>0 then
+ local xmin,ymin,xmax,ymax,done=0,0,0,0,false
+ local px,py=0,0
+ local first=1
+ for i=1,nofcontours do
+ local last=contours[i]
+ if last>=first then
+ local first_pt=points[first]
+ local first_on=first_pt[3]
+ if first==last then
+ if keepcurve then
+ first_pt[3]="m"
+ nofsegments=nofsegments+1
+ segments[nofsegments]=first_pt
+ end
+ else
+ local first_on=first_pt[3]
+ local last_pt=points[last]
+ local last_on=last_pt[3]
+ local start=1
+ local control_pt=false
+ if first_on then
+ start=2
+ else
+ if last_on then
+ first_pt=last_pt
+ else
+ first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false }
+ end
+ control_pt=first_pt
+ end
+ local x=first_pt[1]
+ local y=first_pt[2]
+ if not done then
+ xmin,ymin,xmax,ymax=x,y,x,y
+ done=true
+ else
+ if x<xmin then xmin=x elseif x>xmax then xmax=x end
+ if y<ymin then ymin=y elseif y>ymax then ymax=y end
+ end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x,y,"m" }
+ end
+ if not quadratic then
+ px=x
+ py=y
+ end
+ local previous_pt=first_pt
+ for i=first,last do
+ local current_pt=points[i]
+ local current_on=current_pt[3]
+ local previous_on=previous_pt[3]
+ if previous_on then
+ if current_on then
+ local x=current_pt[1]
+ local y=current_pt[2]
+ if x<xmin then xmin=x elseif x>xmax then xmax=x end
+ if y<ymin then ymin=y elseif y>ymax then ymax=y end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x,y,"l" }
+ end
+ if not quadratic then
+ px=x
+ py=y
+ end
+ else
+ control_pt=current_pt
+ end
+ elseif current_on then
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ local x2=current_pt[1]
+ local y2=current_pt[2]
+ if quadratic then
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ end
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
+ if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
+ if px<xmin then xmin=px elseif px>xmax then xmax=px end
+ if py<ymin then ymin=py elseif py>ymax then ymax=py end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ end
+ control_pt=false
+ else
+ local x2=(previous_pt[1]+current_pt[1])/2
+ local y2=(previous_pt[2]+current_pt[2])/2
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ if quadratic then
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ end
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
+ if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
+ if px<xmin then xmin=px elseif px>xmax then xmax=px end
+ if py<ymin then ymin=py elseif py>ymax then ymax=py end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ end
+ control_pt=current_pt
+ end
+ previous_pt=current_pt
+ end
+ if first_pt==last_pt then
+ elseif not control_pt then
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ first_pt[1],first_pt[2],"l" }
+ end
+ else
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ local x2=first_pt[1]
+ local y2=first_pt[2]
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if quadratic then
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ end
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
+ if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
+ if px<xmin then xmin=px elseif px>xmax then xmax=px end
+ if py<ymin then ymin=py elseif py>ymax then ymax=py end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ end
+ end
+ end
+ end
+ first=last+1
+ end
+ glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) }
+ end
+ end
+ end
+ end
+end
+local c_zero=char(0)
+local s_zero=char(0,0)
+local function toushort(n)
+ return char(band(rshift(n,8),0xFF),band(n,0xFF))
+end
+local function toshort(n)
+ if n<0 then
+ n=n+0x10000
+ end
+ return char(band(rshift(n,8),0xFF),band(n,0xFF))
+end
+local chars=setmetatableindex(function(t,k)
+ for i=0,255 do local v=char(i) t[i]=v end return t[k]
+end)
+local function repackpoints(glyphs,shapes)
+ local noboundingbox={ 0,0,0,0 }
+ local result={}
+ local xpoints={}
+ local ypoints={}
+ for index=0,#glyphs-1 do
+ local shape=shapes[index]
+ if shape then
+ local r=0
+ local glyph=glyphs[index]
+ local contours=shape.contours
+ local nofcontours=contours and #contours or 0
+ local boundingbox=glyph.boundingbox or noboundingbox
+ r=r+1 result[r]=toshort(nofcontours)
+ r=r+1 result[r]=toshort(boundingbox[1])
+ r=r+1 result[r]=toshort(boundingbox[2])
+ r=r+1 result[r]=toshort(boundingbox[3])
+ r=r+1 result[r]=toshort(boundingbox[4])
+ if nofcontours>0 then
+ for i=1,nofcontours do
+ r=r+1 result[r]=toshort(contours[i]-1)
+ end
+ r=r+1 result[r]=s_zero
+ local points=shape.points
+ local currentx=0
+ local currenty=0
+ local x=0
+ local y=0
+ local lastflag=nil
+ local nofflags=0
+ for i=1,#points do
+ local pt=points[i]
+ local px=pt[1]
+ local py=pt[2]
+ local fl=pt[3] and 0x01 or 0x00
+ if px==currentx then
+ fl=fl+0x10
+ else
+ local dx=round(px-currentx)
+ x=x+1
+ if dx<-255 or dx>255 then
+ xpoints[x]=toshort(dx)
+ elseif dx<0 then
+ fl=fl+0x02
+ xpoints[x]=chars[-dx]
+ elseif dx>0 then
+ fl=fl+0x12
+ xpoints[x]=chars[dx]
+ else
+ fl=fl+0x02
+ xpoints[x]=c_zero
+ end
+ end
+ if py==currenty then
+ fl=fl+0x20
+ else
+ local dy=round(py-currenty)
+ y=y+1
+ if dy<-255 or dy>255 then
+ ypoints[y]=toshort(dy)
+ elseif dy<0 then
+ fl=fl+0x04
+ ypoints[y]=chars[-dy]
+ elseif dy>0 then
+ fl=fl+0x24
+ ypoints[y]=chars[dy]
+ else
+ fl=fl+0x04
+ ypoints[y]=c_zero
+ end
+ end
+ currentx=px
+ currenty=py
+ if lastflag==fl then
+ if nofflags==255 then
+ lastflag=lastflag+0x08
+ r=r+1 result[r]=char(lastflag,nofflags-1)
+ nofflags=1
+ lastflag=fl
+ else
+ nofflags=nofflags+1
+ end
+ else
+ if nofflags==1 then
+ r=r+1 result[r]=chars[lastflag]
+ elseif nofflags==2 then
+ r=r+1 result[r]=char(lastflag,lastflag)
+ elseif nofflags>2 then
+ lastflag=lastflag+0x08
+ r=r+1 result[r]=char(lastflag,nofflags-1)
+ end
+ nofflags=1
+ lastflag=fl
+ end
+ end
+ if nofflags==1 then
+ r=r+1 result[r]=chars[lastflag]
+ elseif nofflags==2 then
+ r=r+1 result[r]=char(lastflag,lastflag)
+ elseif nofflags>2 then
+ lastflag=lastflag+0x08
+ r=r+1 result[r]=char(lastflag,nofflags-1)
+ end
+ r=r+1 result[r]=concat(xpoints,"",1,x)
+ r=r+1 result[r]=concat(ypoints,"",1,y)
+ end
+ local stream=concat(result,"",1,r)
+ local length=#stream
+ local padding=idiv(length+3,4)*4-length
+ if padding>0 then
+ if padding==1 then
+ padding="\0"
+ elseif padding==2 then
+ padding="\0\0"
+ else
+ padding="\0\0\0"
+ end
+ padding=stream..padding
+ end
+ glyph.stream=stream
+ end
+ end
+end
+local flags={}
+local function readglyph(f,nofcontours)
+ local points={}
+ local contours={}
+ for i=1,nofcontours do
+ contours[i]=readshort(f)+1
+ end
+ local nofpoints=contours[nofcontours]
+ local nofinstructions=readushort(f)
+ skipbytes(f,nofinstructions)
+ local i=1
+ while i<=nofpoints do
+ local flag=readbyte(f)
+ flags[i]=flag
+ if band(flag,0x08)~=0 then
+ local n=readbyte(f)
+ if n==1 then
+ i=i+1
+ flags[i]=flag
+ else
+ for j=1,n do
+ i=i+1
+ flags[i]=flag
+ end
+ end
+ end
+ i=i+1
+ end
+ local x=0
+ for i=1,nofpoints do
+ local flag=flags[i]
+ if band(flag,0x02)~=0 then
+ if band(flag,0x10)~=0 then
+ x=x+readbyte(f)
+ else
+ x=x-readbyte(f)
+ end
+ elseif band(flag,0x10)~=0 then
+ else
+ x=x+readshort(f)
+ end
+ points[i]={ x,0,band(flag,0x01)~=0 }
+ end
+ local y=0
+ for i=1,nofpoints do
+ local flag=flags[i]
+ if band(flag,0x04)~=0 then
+ if band(flag,0x20)~=0 then
+ y=y+readbyte(f)
+ else
+ y=y-readbyte(f)
+ end
+ elseif band(flag,0x20)~=0 then
+ else
+ y=y+readshort(f)
+ end
+ points[i][2]=y
+ end
+ return {
+ type="glyph",
+ points=points,
+ contours=contours,
+ nofpoints=nofpoints,
+ }
+end
+local function readcomposite(f)
+ local components={}
+ local nofcomponents=0
+ local instructions=false
+ while true do
+ local flags=readushort(f)
+ local index=readushort(f)
+ local f_xyarg=band(flags,0x0002)~=0
+ local f_offset=band(flags,0x0800)~=0
+ local xscale=1
+ local xrotate=0
+ local yrotate=0
+ local yscale=1
+ local xoffset=0
+ local yoffset=0
+ local base=false
+ local reference=false
+ if f_xyarg then
+ if band(flags,0x0001)~=0 then
+ xoffset=readshort(f)
+ yoffset=readshort(f)
+ else
+ xoffset=readchar(f)
+ yoffset=readchar(f)
+ end
+ else
+ if band(flags,0x0001)~=0 then
+ base=readshort(f)
+ reference=readshort(f)
+ else
+ base=readchar(f)
+ reference=readchar(f)
+ end
+ end
+ if band(flags,0x0008)~=0 then
+ xscale=read2dot14(f)
+ yscale=xscale
+ if f_xyarg and f_offset then
+ xoffset=xoffset*xscale
+ yoffset=yoffset*yscale
+ end
+ elseif band(flags,0x0040)~=0 then
+ xscale=read2dot14(f)
+ yscale=read2dot14(f)
+ if f_xyarg and f_offset then
+ xoffset=xoffset*xscale
+ yoffset=yoffset*yscale
+ end
+ elseif band(flags,0x0080)~=0 then
+ xscale=read2dot14(f)
+ xrotate=read2dot14(f)
+ yrotate=read2dot14(f)
+ yscale=read2dot14(f)
+ if f_xyarg and f_offset then
+ xoffset=xoffset*sqrt(xscale^2+xrotate^2)
+ yoffset=yoffset*sqrt(yrotate^2+yscale^2)
+ end
+ end
+ nofcomponents=nofcomponents+1
+ components[nofcomponents]={
+ index=index,
+ usemine=band(flags,0x0200)~=0,
+ round=band(flags,0x0006)~=0,
+ base=base,
+ reference=reference,
+ matrix={ xscale,xrotate,yrotate,yscale,xoffset,yoffset },
+ }
+ if band(flags,0x0100)~=0 then
+ instructions=true
+ end
+ if band(flags,0x0020)==0 then
+ break
+ end
+ end
+ return {
+ type="composite",
+ components=components,
+ }
+end
+function readers.loca(f,fontdata,specification)
+ if specification.glyphs then
+ local datatable=fontdata.tables.loca
+ if datatable then
+ local offset=fontdata.tables.glyf.offset
+ local format=fontdata.fontheader.indextolocformat
+ local profile=fontdata.maximumprofile
+ local nofglyphs=profile and profile.nofglyphs
+ local locations={}
+ setposition(f,datatable.offset)
+ if format==1 then
+ if not nofglyphs then
+ nofglyphs=idiv(datatable.length,4)-1
+ end
+ for i=0,nofglyphs do
+ locations[i]=offset+readulong(f)
+ end
+ fontdata.nofglyphs=nofglyphs
+ else
+ if not nofglyphs then
+ nofglyphs=idiv(datatable.length,2)-1
+ end
+ for i=0,nofglyphs do
+ locations[i]=offset+readushort(f)*2
+ end
+ end
+ fontdata.nofglyphs=nofglyphs
+ fontdata.locations=locations
+ end
+ end
+end
+function readers.glyf(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"glyf",specification.glyphs)
+ if tableoffset then
+ local locations=fontdata.locations
+ if locations then
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs
+ local filesize=fontdata.filesize
+ local nothing={ 0,0,0,0 }
+ local shapes={}
+ local loadshapes=specification.shapes or specification.instance or specification.streams
+ for index=0,nofglyphs-1 do
+ local location=locations[index]
+ local length=locations[index+1]-location
+ if location>=filesize then
+ report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1)
+ fontdata.nofglyphs=index-1
+ fontdata.badfont=true
+ break
+ elseif length>0 then
+ setposition(f,location)
+ local nofcontours=readshort(f)
+ glyphs[index].boundingbox={
+ readshort(f),
+ readshort(f),
+ readshort(f),
+ readshort(f),
+ }
+ if not loadshapes then
+ elseif nofcontours==0 then
+ shapes[index]=readnothing(f)
+ elseif nofcontours>0 then
+ shapes[index]=readglyph(f,nofcontours)
+ else
+ shapes[index]=readcomposite(f,nofcontours)
+ end
+ else
+ if loadshapes then
+ shapes[index]=readnothing(f)
+ end
+ glyphs[index].boundingbox=nothing
+ end
+ end
+ if loadshapes then
+ if readers.gvar then
+ readers.gvar(f,fontdata,specification,glyphs,shapes)
+ end
+ mergecomposites(glyphs,shapes)
+ if specification.instance then
+ if specification.streams then
+ repackpoints(glyphs,shapes)
+ else
+ contours2outlines_shaped(glyphs,shapes,specification.shapes)
+ end
+ elseif specification.shapes then
+ if specification.streams then
+ repackpoints(glyphs,shapes)
+ else
+ contours2outlines_normal(glyphs,shapes)
+ end
+ elseif specification.streams then
+ repackpoints(glyphs,shapes)
+ end
+ end
+ end
+ end
+end
+local function readtuplerecord(f,nofaxis)
+ local record={}
+ for i=1,nofaxis do
+ record[i]=read2dot14(f)
+ end
+ return record
+end
+local function readpoints(f)
+ local count=readbyte(f)
+ if count==0 then
+ return nil,0
+ else
+ if count<128 then
+ elseif band(count,0x80)~=0 then
+ count=band(count,0x7F)*256+readbyte(f)
+ else
+ end
+ local points={}
+ local p=0
+ local n=1
+ while p<count do
+ local control=readbyte(f)
+ local runreader=band(control,0x80)~=0 and readushort or readbyte
+ local runlength=band(control,0x7F)
+ for i=1,runlength+1 do
+ n=n+runreader(f)
+ p=p+1
+ points[p]=n
+ end
+ end
+ return points,p
+ end
+end
+local function readdeltas(f,nofpoints)
+ local deltas={}
+ local p=0
+ local z=0
+ while nofpoints>0 do
+ local control=readbyte(f)
+if not control then
+ break
+end
+ local allzero=band(control,0x80)~=0
+ local runlength=band(control,0x3F)+1
+ if allzero then
+ z=z+runlength
+ else
+ local runreader=band(control,0x40)~=0 and readshort or readinteger
+ if z>0 then
+ for i=1,z do
+ p=p+1
+ deltas[p]=0
+ end
+ z=0
+ end
+ for i=1,runlength do
+ p=p+1
+ deltas[p]=runreader(f)
+ end
+ end
+ nofpoints=nofpoints-runlength
+ end
+ if p>0 then
+ return deltas
+ else
+ end
+end
+local function readdeltas(f,nofpoints)
+ local deltas={}
+ local p=0
+ while nofpoints>0 do
+ local control=readbyte(f)
+ if control then
+ local allzero=band(control,0x80)~=0
+ local runlength=band(control,0x3F)+1
+ if allzero then
+ for i=1,runlength do
+ p=p+1
+ deltas[p]=0
+ end
+ else
+ local runreader=band(control,0x40)~=0 and readshort or readinteger
+ for i=1,runlength do
+ p=p+1
+ deltas[p]=runreader(f)
+ end
+ end
+ nofpoints=nofpoints-runlength
+ else
+ break
+ end
+ end
+ if p>0 then
+ return deltas
+ else
+ end
+end
+function readers.gvar(f,fontdata,specification,glyphdata,shapedata)
+ local instance=specification.instance
+ if not instance then
+ return
+ end
+ local factors=specification.factors
+ if not factors then
+ return
+ end
+ local tableoffset=gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes)
+ if tableoffset then
+ local version=readulong(f)
+ local nofaxis=readushort(f)
+ local noftuples=readushort(f)
+ local tupleoffset=tableoffset+readulong(f)
+ local nofglyphs=readushort(f)
+ local flags=readushort(f)
+ local dataoffset=tableoffset+readulong(f)
+ local data={}
+ local tuples={}
+ local glyphdata=fontdata.glyphs
+ local dowidth=not fontdata.variabledata.hvarwidths
+ if band(flags,0x0001)~=0 then
+ for i=1,nofglyphs+1 do
+ data[i]=dataoffset+readulong(f)
+ end
+ else
+ for i=1,nofglyphs+1 do
+ data[i]=dataoffset+2*readushort(f)
+ end
+ end
+ if noftuples>0 then
+ setposition(f,tupleoffset)
+ for i=1,noftuples do
+ tuples[i]=readtuplerecord(f,nofaxis)
+ end
+ end
+ local nextoffset=false
+ local startoffset=data[1]
+ for i=1,nofglyphs do
+ nextoffset=data[i+1]
+ local glyph=glyphdata[i-1]
+ local name=trace_deltas and glyph.name
+ if startoffset==nextoffset then
+ if name then
+ report("no deltas for glyph %a",name)
+ end
+ else
+ local shape=shapedata[i-1]
+ if not shape then
+ if name then
+ report("no shape for glyph %a",name)
+ end
+ else
+ lastoffset=startoffset
+ setposition(f,startoffset)
+ local flags=readushort(f)
+ local count=band(flags,0x0FFF)
+ local offset=startoffset+readushort(f)
+ local deltas={}
+ local allpoints=(shape.nofpoints or 0)
+ local shared=false
+ local nofshared=0
+ if band(flags,0x8000)~=0 then
+ local current=getposition(f)
+ setposition(f,offset)
+ shared,nofshared=readpoints(f)
+ offset=getposition(f)
+ setposition(f,current)
+ end
+ for j=1,count do
+ local size=readushort(f)
+ local flags=readushort(f)
+ local index=band(flags,0x0FFF)
+ local haspeak=band(flags,0x8000)~=0
+ local intermediate=band(flags,0x4000)~=0
+ local private=band(flags,0x2000)~=0
+ local peak=nil
+ local start=nil
+ local stop=nil
+ local xvalues=nil
+ local yvalues=nil
+ local points=shared
+ local nofpoints=nofshared
+ if haspeak then
+ peak=readtuplerecord(f,nofaxis)
+ else
+ if index+1>#tuples then
+ report("error, bad tuple index",index)
+ end
+ peak=tuples[index+1]
+ end
+ if intermediate then
+ start=readtuplerecord(f,nofaxis)
+ stop=readtuplerecord(f,nofaxis)
+ end
+ if size>0 then
+ local current=getposition(f)
+ setposition(f,offset)
+ if private then
+ points,nofpoints=readpoints(f)
+ end
+ if nofpoints==0 then
+ nofpoints=allpoints+4
+ end
+ if nofpoints>0 then
+ xvalues=readdeltas(f,nofpoints)
+ yvalues=readdeltas(f,nofpoints)
+ end
+ offset=offset+size
+ setposition(f,current)
+ end
+ if not xvalues and not yvalues then
+ points=nil
+ end
+ local s=1
+ for i=1,nofaxis do
+ local f=factors[i]
+ local peak=peak and peak [i] or 0
+ local start=start and start[i] or (peak<0 and peak or 0)
+ local stop=stop and stop [i] or (peak>0 and peak or 0)
+ if start>peak or peak>stop then
+ elseif start<0 and stop>0 and peak~=0 then
+ elseif peak==0 then
+ elseif f<start or f>stop then
+ s=0
+ break
+ elseif f<peak then
+ s=s*(f-start)/(peak-start)
+ elseif f>peak then
+ s=s*(stop-f)/(stop-peak)
+ else
+ end
+ end
+ if s==0 then
+ if name then
+ report("no deltas applied for glyph %a",name)
+ end
+ else
+ deltas[#deltas+1]={
+ factor=s,
+ points=points,
+ xvalues=xvalues,
+ yvalues=yvalues,
+ }
+ end
+ end
+ if shape.type=="glyph" then
+ applyaxis(glyph,shape,deltas,dowidth)
+ else
+ shape.deltas=deltas
+ end
+ end
+ end
+ startoffset=nextoffset
+ end
+ end
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ttfâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-dsp†b5bf2f1c198e027a0d4ededcdf3947b4] ---
+
+if not modules then modules={} end modules ['font-dsp']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type,tonumber=next,type,tonumber
+local band=bit32.band
+local extract=bit32.extract
+local bor=bit32.bor
+local lshift=bit32.lshift
+local rshift=bit32.rshift
+local gsub=string.gsub
+local lower=string.lower
+local sub=string.sub
+local strip=string.strip
+local tohash=table.tohash
+local concat=table.concat
+local copy=table.copy
+local reversed=table.reversed
+local sort=table.sort
+local insert=table.insert
+local round=math.round
+local settings_to_hash=utilities.parsers.settings_to_hash_colon_too
+local setmetatableindex=table.setmetatableindex
+local formatters=string.formatters
+local sortedkeys=table.sortedkeys
+local sortedhash=table.sortedhash
+local sequenced=table.sequenced
+local report=logs.reporter("otf reader")
+local readers=fonts.handlers.otf.readers
+local streamreader=readers.streamreader
+local setposition=streamreader.setposition
+local getposition=streamreader.getposition
+local readuinteger=streamreader.readcardinal1
+local readushort=streamreader.readcardinal2
+local readulong=streamreader.readcardinal4
+local readinteger=streamreader.readinteger1
+local readshort=streamreader.readinteger2
+local readstring=streamreader.readstring
+local readtag=streamreader.readtag
+local readbytes=streamreader.readbytes
+local readfixed=streamreader.readfixed4
+local read2dot14=streamreader.read2dot14
+local skipshort=streamreader.skipshort
+local skipbytes=streamreader.skip
+local readbytetable=streamreader.readbytetable
+local readbyte=streamreader.readbyte
+local readcardinaltable=streamreader.readcardinaltable
+local readintegertable=streamreader.readintegertable
+local readfword=readshort
+local short=2
+local ushort=2
+local ulong=4
+directives.register("fonts.streamreader",function()
+ streamreader=utilities.streams
+ setposition=streamreader.setposition
+ getposition=streamreader.getposition
+ readuinteger=streamreader.readcardinal1
+ readushort=streamreader.readcardinal2
+ readulong=streamreader.readcardinal4
+ readinteger=streamreader.readinteger1
+ readshort=streamreader.readinteger2
+ readstring=streamreader.readstring
+ readtag=streamreader.readtag
+ readbytes=streamreader.readbytes
+ readfixed=streamreader.readfixed4
+ read2dot14=streamreader.read2dot14
+ skipshort=streamreader.skipshort
+ skipbytes=streamreader.skip
+ readbytetable=streamreader.readbytetable
+ readbyte=streamreader.readbyte
+ readcardinaltable=streamreader.readcardinaltable
+ readintegertable=streamreader.readintegertable
+ readfword=readshort
+end)
+local gsubhandlers={}
+local gposhandlers={}
+readers.gsubhandlers=gsubhandlers
+readers.gposhandlers=gposhandlers
+local helpers=readers.helpers
+local gotodatatable=helpers.gotodatatable
+local setvariabledata=helpers.setvariabledata
+local lookupidoffset=-1
+local classes={
+ "base",
+ "ligature",
+ "mark",
+ "component",
+}
+local gsubtypes={
+ "single",
+ "multiple",
+ "alternate",
+ "ligature",
+ "context",
+ "chainedcontext",
+ "extension",
+ "reversechainedcontextsingle",
+}
+local gpostypes={
+ "single",
+ "pair",
+ "cursive",
+ "marktobase",
+ "marktoligature",
+ "marktomark",
+ "context",
+ "chainedcontext",
+ "extension",
+}
+local chaindirections={
+ context=0,
+ chainedcontext=1,
+ reversechainedcontextsingle=-1,
+}
+local function setmetrics(data,where,tag,d)
+ local w=data[where]
+ if w then
+ local v=w[tag]
+ if v then
+ w[tag]=v+d
+ end
+ end
+end
+local variabletags={
+ hasc=function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end,
+ hdsc=function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end,
+ hlgp=function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end,
+ hcla=function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end,
+ hcld=function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end,
+ vasc=function(data,d) setmetrics(data,"vhea not done","ascent",d) end,
+ vdsc=function(data,d) setmetrics(data,"vhea not done","descent",d) end,
+ vlgp=function(data,d) setmetrics(data,"vhea not done","linegap",d) end,
+ xhgt=function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end,
+ cpht=function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end,
+ sbxs=function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end,
+ sbys=function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end,
+ sbxo=function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end,
+ sbyo=function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end,
+ spxs=function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end,
+ spys=function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end,
+ spxo=function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end,
+ spyo=function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end,
+ strs=function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end,
+ stro=function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end,
+ unds=function(data,d) setmetrics(data,"postscript","underlineposition",d) end,
+ undo=function(data,d) setmetrics(data,"postscript","underlinethickness",d) end,
+}
+local read_cardinal={
+ streamreader.readcardinal1,
+ streamreader.readcardinal2,
+ streamreader.readcardinal3,
+ streamreader.readcardinal4,
+}
+local read_integer={
+ streamreader.readinteger1,
+ streamreader.readinteger2,
+ streamreader.readinteger3,
+ streamreader.readinteger4,
+}
+local lookupnames={
+ gsub={
+ single="gsub_single",
+ multiple="gsub_multiple",
+ alternate="gsub_alternate",
+ ligature="gsub_ligature",
+ context="gsub_context",
+ chainedcontext="gsub_contextchain",
+ reversechainedcontextsingle="gsub_reversecontextchain",
+ },
+ gpos={
+ single="gpos_single",
+ pair="gpos_pair",
+ cursive="gpos_cursive",
+ marktobase="gpos_mark2base",
+ marktoligature="gpos_mark2ligature",
+ marktomark="gpos_mark2mark",
+ context="gpos_context",
+ chainedcontext="gpos_contextchain",
+ }
+}
+local lookupflags=setmetatableindex(function(t,k)
+ local v={
+ band(k,0x0008)~=0 and true or false,
+ band(k,0x0004)~=0 and true or false,
+ band(k,0x0002)~=0 and true or false,
+ band(k,0x0001)~=0 and true or false,
+ }
+ t[k]=v
+ return v
+end)
+local function axistofactors(str)
+ local t=settings_to_hash(str)
+ for k,v in next,t do
+ t[k]=tonumber(v) or v
+ end
+ return t
+end
+local hash=table.setmetatableindex(function(t,k)
+ local v=sequenced(axistofactors(k),",")
+ t[k]=v
+ return v
+end)
+helpers.normalizedaxishash=hash
+local cleanname=fonts.names and fonts.names.cleanname or function(name)
+ return name and (gsub(lower(name),"[^%a%d]","")) or nil
+end
+helpers.cleanname=cleanname
+function helpers.normalizedaxis(str)
+ return hash[str] or str
+end
+local function getaxisscale(segments,minimum,default,maximum,user)
+ if not minimum or not default or not maximum then
+ return false
+ end
+ if user<minimum then
+ user=minimum
+ elseif user>maximum then
+ user=maximum
+ end
+ if user<default then
+ default=- (default-user)/(default-minimum)
+ elseif user>default then
+ default=(user-default)/(maximum-default)
+ else
+ default=0
+ end
+ if not segments then
+ return default
+ end
+ local e
+ for i=1,#segments do
+ local s=segments[i]
+ if type(s)~="number" then
+ report("using default axis scale")
+ return default
+ elseif s[1]>=default then
+ if s[2]==default then
+ return default
+ else
+ e=i
+ break
+ end
+ end
+ end
+ if e then
+ local b=segments[e-1]
+ local e=segments[e]
+ return b[2]+(e[2]-b[2])*(default-b[1])/(e[1]-b[1])
+ else
+ return false
+ end
+end
+local function getfactors(data,instancespec)
+ if instancespec==true then
+ elseif type(instancespec)~="string" or instancespec=="" then
+ return
+ end
+ local variabledata=data.variabledata
+ if not variabledata then
+ return
+ end
+ local instances=variabledata.instances
+ local axis=variabledata.axis
+ local segments=variabledata.segments
+ if instances and axis then
+ local values
+ if instancespec==true then
+ values={}
+ for i=1,#axis do
+ values[i]={
+ value=axis[i].default,
+ }
+ end
+ else
+ for i=1,#instances do
+ local instance=instances[i]
+ if cleanname(instance.subfamily)==instancespec then
+ values=instance.values
+ break
+ end
+ end
+ end
+ if values then
+ local factors={}
+ for i=1,#axis do
+ local a=axis[i]
+ factors[i]=getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value)
+ end
+ return factors
+ end
+ local values=axistofactors(hash[instancespec] or instancespec)
+ if values then
+ local factors={}
+ for i=1,#axis do
+ local a=axis[i]
+ local d=a.default
+ factors[i]=getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d)
+ end
+ return factors
+ end
+ end
+end
+local function getscales(regions,factors)
+ local scales={}
+ for i=1,#regions do
+ local region=regions[i]
+ local s=1
+ for j=1,#region do
+ local axis=region[j]
+ local f=factors[j]
+ local start=axis.start
+ local peak=axis.peak
+ local stop=axis.stop
+ if start>peak or peak>stop then
+ elseif start<0 and stop>0 and peak~=0 then
+ elseif peak==0 then
+ elseif f<start or f>stop then
+ s=0
+ break
+ elseif f<peak then
+ s=s*(f-start)/(peak-start)
+ elseif f>peak then
+ s=s*(stop-f)/(stop-peak)
+ else
+ end
+ end
+ scales[i]=s
+ end
+ return scales
+end
+helpers.getaxisscale=getaxisscale
+helpers.getfactors=getfactors
+helpers.getscales=getscales
+helpers.axistofactors=axistofactors
+local function readvariationdata(f,storeoffset,factors)
+ local position=getposition(f)
+ setposition(f,storeoffset)
+ local format=readushort(f)
+ local regionoffset=storeoffset+readulong(f)
+ local nofdeltadata=readushort(f)
+ local deltadata=readcardinaltable(f,nofdeltadata,ulong)
+ setposition(f,regionoffset)
+ local nofaxis=readushort(f)
+ local nofregions=readushort(f)
+ local regions={}
+ for i=1,nofregions do
+ local t={}
+ for i=1,nofaxis do
+ t[i]={
+ start=read2dot14(f),
+ peak=read2dot14(f),
+ stop=read2dot14(f),
+ }
+ end
+ regions[i]=t
+ end
+ if factors then
+ for i=1,nofdeltadata do
+ setposition(f,storeoffset+deltadata[i])
+ local nofdeltasets=readushort(f)
+ local nofshorts=readushort(f)
+ local nofregions=readushort(f)
+ local usedregions={}
+ local deltas={}
+ for i=1,nofregions do
+ usedregions[i]=regions[readushort(f)+1]
+ end
+ for i=1,nofdeltasets do
+ local t=readintegertable(f,nofshorts,short)
+ for i=nofshorts+1,nofregions do
+ t[i]=readinteger(f)
+ end
+ deltas[i]=t
+ end
+ deltadata[i]={
+ regions=usedregions,
+ deltas=deltas,
+ scales=factors and getscales(usedregions,factors) or nil,
+ }
+ end
+ end
+ setposition(f,position)
+ return regions,deltadata
+end
+helpers.readvariationdata=readvariationdata
+local function readcoverage(f,offset,simple)
+ setposition(f,offset)
+ local coverageformat=readushort(f)
+ if coverageformat==1 then
+ local nofcoverage=readushort(f)
+ if simple then
+ if nofcoverage==1 then
+ return { readushort(f) }
+ elseif nofcoverage==2 then
+ return { readushort(f),readushort(f) }
+ else
+ return readcardinaltable(f,nofcoverage,ushort)
+ end
+ elseif nofcoverage==1 then
+ return { [readushort(f)]=0 }
+ elseif nofcoverage==2 then
+ return { [readushort(f)]=0,[readushort(f)]=1 }
+ else
+ local coverage={}
+ for i=0,nofcoverage-1 do
+ coverage[readushort(f)]=i
+ end
+ return coverage
+ end
+ elseif coverageformat==2 then
+ local nofranges=readushort(f)
+ local coverage={}
+ local n=simple and 1 or 0
+ for i=1,nofranges do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local coverindex=readushort(f)
+ if simple then
+ for i=firstindex,lastindex do
+ coverage[n]=i
+ n=n+1
+ end
+ else
+ for i=firstindex,lastindex do
+ coverage[i]=n
+ n=n+1
+ end
+ end
+ end
+ return coverage
+ else
+ report("unknown coverage format %a ",coverageformat)
+ return {}
+ end
+end
+local function readclassdef(f,offset,preset)
+ setposition(f,offset)
+ local classdefformat=readushort(f)
+ local classdef={}
+ if type(preset)=="number" then
+ for k=0,preset-1 do
+ classdef[k]=1
+ end
+ end
+ if classdefformat==1 then
+ local index=readushort(f)
+ local nofclassdef=readushort(f)
+ for i=1,nofclassdef do
+ classdef[index]=readushort(f)+1
+ index=index+1
+ end
+ elseif classdefformat==2 then
+ local nofranges=readushort(f)
+ local n=0
+ for i=1,nofranges do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local class=readushort(f)+1
+ for i=firstindex,lastindex do
+ classdef[i]=class
+ end
+ end
+ else
+ report("unknown classdef format %a ",classdefformat)
+ end
+ if type(preset)=="table" then
+ for k in next,preset do
+ if not classdef[k] then
+ classdef[k]=1
+ end
+ end
+ end
+ return classdef
+end
+local function classtocoverage(defs)
+ if defs then
+ local list={}
+ for index,class in next,defs do
+ local c=list[class]
+ if c then
+ c[#c+1]=index
+ else
+ list[class]={ index }
+ end
+ end
+ return list
+ end
+end
+local skips={ [0]=0,
+ 1,
+ 1,
+ 2,
+ 1,
+ 2,
+ 2,
+ 3,
+ 2,
+ 2,
+ 3,
+ 2,
+ 3,
+ 3,
+ 4,
+}
+local function readvariation(f,offset)
+ local p=getposition(f)
+ setposition(f,offset)
+ local outer=readushort(f)
+ local inner=readushort(f)
+ local format=readushort(f)
+ setposition(f,p)
+ if format==0x8000 then
+ return outer,inner
+ end
+end
+local function readposition(f,format,mainoffset,getdelta)
+ if format==0 then
+ return false
+ end
+ if format==0x04 then
+ local h=readshort(f)
+ if h==0 then
+ return true
+ else
+ return { 0,0,h,0 }
+ end
+ end
+ if format==0x05 then
+ local x=readshort(f)
+ local h=readshort(f)
+ if x==0 and h==0 then
+ return true
+ else
+ return { x,0,h,0 }
+ end
+ end
+ if format==0x44 then
+ local h=readshort(f)
+ if getdelta then
+ local d=readshort(f)
+ if d>0 then
+ local outer,inner=readvariation(f,mainoffset+d)
+ if outer then
+ h=h+getdelta(outer,inner)
+ end
+ end
+ else
+ skipshort(f,1)
+ end
+ if h==0 then
+ return true
+ else
+ return { 0,0,h,0 }
+ end
+ end
+ local x=band(format,0x1)~=0 and readshort(f) or 0
+ local y=band(format,0x2)~=0 and readshort(f) or 0
+ local h=band(format,0x4)~=0 and readshort(f) or 0
+ local v=band(format,0x8)~=0 and readshort(f) or 0
+ if format>=0x10 then
+ local X=band(format,0x10)~=0 and skipshort(f) or 0
+ local Y=band(format,0x20)~=0 and skipshort(f) or 0
+ local H=band(format,0x40)~=0 and skipshort(f) or 0
+ local V=band(format,0x80)~=0 and skipshort(f) or 0
+ local s=skips[extract(format,4,4)]
+ if s>0 then
+ skipshort(f,s)
+ end
+ if getdelta then
+ if X>0 then
+ local outer,inner=readvariation(f,mainoffset+X)
+ if outer then
+ x=x+getdelta(outer,inner)
+ end
+ end
+ if Y>0 then
+ local outer,inner=readvariation(f,mainoffset+Y)
+ if outer then
+ y=y+getdelta(outer,inner)
+ end
+ end
+ if H>0 then
+ local outer,inner=readvariation(f,mainoffset+H)
+ if outer then
+ h=h+getdelta(outer,inner)
+ end
+ end
+ if V>0 then
+ local outer,inner=readvariation(f,mainoffset+V)
+ if outer then
+ v=v+getdelta(outer,inner)
+ end
+ end
+ end
+ return { x,y,h,v }
+ elseif x==0 and y==0 and h==0 and v==0 then
+ return true
+ else
+ return { x,y,h,v }
+ end
+end
+local function readanchor(f,offset,getdelta)
+ if not offset or offset==0 then
+ return nil
+ end
+ setposition(f,offset)
+ local format=readshort(f)
+ local x=readshort(f)
+ local y=readshort(f)
+ if format==3 then
+ if getdelta then
+ local X=readshort(f)
+ local Y=readshort(f)
+ if X>0 then
+ local outer,inner=readvariation(f,offset+X)
+ if outer then
+ x=x+getdelta(outer,inner)
+ end
+ end
+ if Y>0 then
+ local outer,inner=readvariation(f,offset+Y)
+ if outer then
+ y=y+getdelta(outer,inner)
+ end
+ end
+ else
+ skipshort(f,2)
+ end
+ return { x,y }
+ else
+ return { x,y }
+ end
+end
+local function readfirst(f,offset)
+ if offset then
+ setposition(f,offset)
+ end
+ return { readushort(f) }
+end
+function readarray(f,offset)
+ if offset then
+ setposition(f,offset)
+ end
+ local n=readushort(f)
+ if n==1 then
+ return { readushort(f) },1
+ elseif n>0 then
+ return readcardinaltable(f,n,ushort),n
+ end
+end
+local function readcoveragearray(f,offset,t,simple)
+ if not t then
+ return nil
+ end
+ local n=#t
+ if n==0 then
+ return nil
+ end
+ for i=1,n do
+ t[i]=readcoverage(f,offset+t[i],simple)
+ end
+ return t
+end
+local function covered(subset,all)
+ local used,u
+ for i=1,#subset do
+ local s=subset[i]
+ if all[s] then
+ if used then
+ u=u+1
+ used[u]=s
+ else
+ u=1
+ used={ s }
+ end
+ end
+ end
+ return used
+end
+local function readlookuparray(f,noflookups,nofcurrent)
+ local lookups={}
+ if noflookups>0 then
+ local length=0
+ for i=1,noflookups do
+ local index=readushort(f)+1
+ if index>length then
+ length=index
+ end
+ 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
+ lookups[index]=false
+ end
+ end
+ end
+ return lookups
+end
+local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local subclasssets=readarray(f)
+ local rules={}
+ if subclasssets then
+ coverage=readcoverage(f,tableoffset+coverage,true)
+ for i=1,#subclasssets do
+ local offset=subclasssets[i]
+ if offset>0 then
+ local firstcoverage=coverage[i]
+ local rulesoffset=tableoffset+offset
+ local subclassrules=readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset+subclassrules[rule])
+ local nofcurrent=readushort(f)
+ local noflookups=readushort(f)
+ local current={ { firstcoverage } }
+ for i=2,nofcurrent do
+ current[i]={ readushort(f) }
+ end
+ local lookups=readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1]={
+ current=current,
+ lookups=lookups
+ }
+ end
+ end
+ end
+ else
+ report("empty subclassset in %a subtype %i","unchainedcontext",subtype)
+ end
+ return {
+ format="glyphs",
+ rules=rules,
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local currentclassdef=readushort(f)
+ local subclasssets=readarray(f)
+ local rules={}
+ if subclasssets then
+ coverage=readcoverage(f,tableoffset+coverage)
+ currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage)
+ local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs)
+ for class=1,#subclasssets do
+ local offset=subclasssets[class]
+ if offset>0 then
+ local firstcoverage=currentclasses[class]
+ if firstcoverage then
+ firstcoverage=covered(firstcoverage,coverage)
+ if firstcoverage then
+ local rulesoffset=tableoffset+offset
+ local subclassrules=readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset+subclassrules[rule])
+ local nofcurrent=readushort(f)
+ local noflookups=readushort(f)
+ local current={ firstcoverage }
+ for i=2,nofcurrent do
+ current[i]=currentclasses[readushort(f)+1]
+ end
+ local lookups=readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1]={
+ current=current,
+ lookups=lookups
+ }
+ end
+ else
+ report("no coverage")
+ end
+ else
+ report("no coverage class")
+ end
+ end
+ end
+ else
+ report("empty subclassset in %a subtype %i","unchainedcontext",subtype)
+ end
+ return {
+ format="class",
+ rules=rules,
+ }
+ elseif subtype==3 then
+ local nofglyphs=readushort(f)
+ local noflookups=readushort(f)
+ local current=readcardinaltable(f,nofglyphs,ushort)
+ local lookups=readlookuparray(f,noflookups,#current)
+ current=readcoveragearray(f,tableoffset,current,true)
+ return {
+ format="coverage",
+ rules={
+ {
+ current=current,
+ lookups=lookups,
+ }
+ }
+ }
+ else
+ report("unsupported subtype %a in %a %s",subtype,"unchainedcontext",what)
+ end
+end
+local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local subclasssets=readarray(f)
+ local rules={}
+ if subclasssets then
+ coverage=readcoverage(f,tableoffset+coverage,true)
+ for i=1,#subclasssets do
+ local offset=subclasssets[i]
+ if offset>0 then
+ local firstcoverage=coverage[i]
+ local rulesoffset=tableoffset+offset
+ local subclassrules=readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset+subclassrules[rule])
+ local nofbefore=readushort(f)
+ local before
+ if nofbefore>0 then
+ before={}
+ for i=1,nofbefore do
+ before[i]={ readushort(f) }
+ end
+ end
+ local nofcurrent=readushort(f)
+ local current={ { firstcoverage } }
+ for i=2,nofcurrent do
+ current[i]={ readushort(f) }
+ end
+ local nofafter=readushort(f)
+ local after
+ if nofafter>0 then
+ after={}
+ for i=1,nofafter do
+ after[i]={ readushort(f) }
+ end
+ end
+ local noflookups=readushort(f)
+ local lookups=readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1]={
+ before=before,
+ current=current,
+ after=after,
+ lookups=lookups,
+ }
+ end
+ end
+ end
+ else
+ report("empty subclassset in %a subtype %i","chainedcontext",subtype)
+ end
+ return {
+ format="glyphs",
+ rules=rules,
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local beforeclassdef=readushort(f)
+ local currentclassdef=readushort(f)
+ local afterclassdef=readushort(f)
+ local subclasssets=readarray(f)
+ local rules={}
+ if subclasssets then
+ local coverage=readcoverage(f,tableoffset+coverage)
+ local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef,nofglyphs)
+ local currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage)
+ local afterclassdef=readclassdef(f,tableoffset+afterclassdef,nofglyphs)
+ local beforeclasses=classtocoverage(beforeclassdef,fontdata.glyphs)
+ local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs)
+ local afterclasses=classtocoverage(afterclassdef,fontdata.glyphs)
+ for class=1,#subclasssets do
+ local offset=subclasssets[class]
+ if offset>0 then
+ local firstcoverage=currentclasses[class]
+ if firstcoverage then
+ firstcoverage=covered(firstcoverage,coverage)
+ if firstcoverage then
+ local rulesoffset=tableoffset+offset
+ local subclassrules=readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset+subclassrules[rule])
+ local nofbefore=readushort(f)
+ local before
+ if nofbefore>0 then
+ before={}
+ for i=1,nofbefore do
+ before[i]=beforeclasses[readushort(f)+1]
+ end
+ end
+ local nofcurrent=readushort(f)
+ local current={ firstcoverage }
+ for i=2,nofcurrent do
+ current[i]=currentclasses[readushort(f)+1]
+ end
+ local nofafter=readushort(f)
+ local after
+ if nofafter>0 then
+ after={}
+ for i=1,nofafter do
+ after[i]=afterclasses[readushort(f)+1]
+ end
+ end
+ local noflookups=readushort(f)
+ local lookups=readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1]={
+ before=before,
+ current=current,
+ after=after,
+ lookups=lookups,
+ }
+ end
+ else
+ report("no coverage")
+ end
+ else
+ report("class is not covered")
+ end
+ end
+ end
+ else
+ report("empty subclassset in %a subtype %i","chainedcontext",subtype)
+ end
+ return {
+ format="class",
+ rules=rules,
+ }
+ elseif subtype==3 then
+ local before=readarray(f)
+ local current=readarray(f)
+ local after=readarray(f)
+ local noflookups=readushort(f)
+ local lookups=readlookuparray(f,noflookups,#current)
+ before=readcoveragearray(f,tableoffset,before,true)
+ current=readcoveragearray(f,tableoffset,current,true)
+ after=readcoveragearray(f,tableoffset,after,true)
+ return {
+ format="coverage",
+ rules={
+ {
+ before=before,
+ current=current,
+ after=after,
+ lookups=lookups,
+ }
+ }
+ }
+ else
+ report("unsupported subtype %a in %a %s",subtype,"chainedcontext",what)
+ end
+end
+local function extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,types,handlers,what)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local lookuptype=types[readushort(f)]
+ local faroffset=readulong(f)
+ local handler=handlers[lookuptype]
+ if handler then
+ return handler(f,fontdata,lookupid,tableoffset+faroffset,0,glyphs,nofglyphs),lookuptype
+ else
+ report("no handler for lookuptype %a subtype %a in %s %s",lookuptype,subtype,what,"extension")
+ end
+ else
+ report("unsupported subtype %a in %s %s",subtype,what,"extension")
+ end
+end
+function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local delta=readshort(f)
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index in next,coverage do
+ local newindex=(index+delta)%65536
+ if index>nofglyphs or newindex>nofglyphs then
+ report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs)
+ coverage[index]=nil
+ else
+ coverage[index]=newindex
+ end
+ end
+ return {
+ coverage=coverage
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local nofreplacements=readushort(f)
+ local replacements=readcardinaltable(f,nofreplacements,ushort)
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ newindex=newindex+1
+ if index>nofglyphs or newindex>nofglyphs then
+ report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs)
+ coverage[index]=nil
+ else
+ coverage[index]=replacements[newindex]
+ end
+ end
+ return {
+ coverage=coverage
+ }
+ else
+ report("unsupported subtype %a in %a substitution",subtype,"single")
+ end
+end
+local function sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local nofsequence=readushort(f)
+ local sequences=readcardinaltable(f,nofsequence,ushort)
+ for i=1,nofsequence do
+ setposition(f,tableoffset+sequences[i])
+ sequences[i]=readcardinaltable(f,readushort(f),ushort)
+ end
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ newindex=newindex+1
+ if index>nofglyphs or newindex>nofglyphs then
+ report("invalid index in %s format %i: %i -> %i (max %i)",what,subtype,index,newindex,nofglyphs)
+ coverage[index]=nil
+ else
+ coverage[index]=sequences[newindex]
+ end
+ end
+ return {
+ coverage=coverage
+ }
+ else
+ report("unsupported subtype %a in %a substitution",subtype,what)
+ end
+end
+function gsubhandlers.multiple(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"multiple")
+end
+function gsubhandlers.alternate(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"alternate")
+end
+function gsubhandlers.ligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local nofsets=readushort(f)
+ local ligatures=readcardinaltable(f,nofsets,ushort)
+ for i=1,nofsets do
+ local offset=lookupoffset+offset+ligatures[i]
+ setposition(f,offset)
+ local n=readushort(f)
+ if n==1 then
+ ligatures[i]={ offset+readushort(f) }
+ else
+ local l={}
+ for i=1,n do
+ l[i]=offset+readushort(f)
+ end
+ ligatures[i]=l
+ end
+ end
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ local hash={}
+ local ligatures=ligatures[newindex+1]
+ for i=1,#ligatures do
+ local offset=ligatures[i]
+ setposition(f,offset)
+ local lig=readushort(f)
+ local cnt=readushort(f)
+ local hsh=hash
+ for i=2,cnt do
+ local c=readushort(f)
+ local h=hsh[c]
+ if not h then
+ h={}
+ hsh[c]=h
+ end
+ hsh=h
+ end
+ hsh.ligature=lig
+ end
+ coverage[index]=hash
+ end
+ return {
+ coverage=coverage
+ }
+ else
+ report("unsupported subtype %a in %a substitution",subtype,"ligature")
+ end
+end
+function gsubhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"context"
+end
+function gsubhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"chainedcontext"
+end
+function gsubhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gsubtypes,gsubhandlers,"substitution")
+end
+function gsubhandlers.reversechainedcontextsingle(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local current=readfirst(f)
+ local before=readarray(f)
+ local after=readarray(f)
+ local replacements=readarray(f)
+ current=readcoveragearray(f,tableoffset,current,true)
+ before=readcoveragearray(f,tableoffset,before,true)
+ after=readcoveragearray(f,tableoffset,after,true)
+ return {
+ format="reversecoverage",
+ rules={
+ {
+ before=before,
+ current=current,
+ after=after,
+ replacements=replacements,
+ }
+ }
+ },"reversechainedcontextsingle"
+ else
+ report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle")
+ end
+end
+local function readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta)
+ local done={}
+ for i=1,#sets do
+ local offset=sets[i]
+ local reused=done[offset]
+ if not reused then
+ offset=tableoffset+offset
+ setposition(f,offset)
+ local n=readushort(f)
+ reused={}
+ for i=1,n do
+ reused[i]={
+ readushort(f),
+ readposition(f,format1,offset,getdelta),
+ readposition(f,format2,offset,getdelta),
+ }
+ end
+ done[offset]=reused
+ end
+ sets[i]=reused
+ end
+ return sets
+end
+local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,mainoffset,getdelta)
+ local classlist1={}
+ for i=1,nofclasses1 do
+ local classlist2={}
+ classlist1[i]=classlist2
+ for j=1,nofclasses2 do
+ local one=readposition(f,format1,mainoffset,getdelta)
+ local two=readposition(f,format2,mainoffset,getdelta)
+ if one or two then
+ classlist2[j]={ one,two }
+ else
+ classlist2[j]=false
+ end
+ end
+ end
+ return classlist1
+end
+function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ local getdelta=fontdata.temporary.getdelta
+ if subtype==1 then
+ local coverage=readushort(f)
+ local format=readushort(f)
+ local value=readposition(f,format,tableoffset,getdelta)
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ coverage[index]=value
+ end
+ return {
+ format="single",
+ coverage=coverage,
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local format=readushort(f)
+ local nofvalues=readushort(f)
+ local values={}
+ for i=1,nofvalues do
+ values[i]=readposition(f,format,tableoffset,getdelta)
+ end
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ coverage[index]=values[newindex+1]
+ end
+ return {
+ format="single",
+ coverage=coverage,
+ }
+ else
+ report("unsupported subtype %a in %a positioning",subtype,"single")
+ end
+end
+function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ local getdelta=fontdata.temporary.getdelta
+ if subtype==1 then
+ local coverage=readushort(f)
+ local format1=readushort(f)
+ local format2=readushort(f)
+ local sets=readarray(f)
+ sets=readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta)
+ coverage=readcoverage(f,tableoffset+coverage)
+ local shared={}
+ for index,newindex in next,coverage do
+ local set=sets[newindex+1]
+ local hash={}
+ for i=1,#set do
+ local value=set[i]
+ if value then
+ local other=value[1]
+ local share=shared[value]
+ if share==nil then
+ local first=value[2]
+ local second=value[3]
+ if first or second then
+ share={ first,second or nil }
+ else
+ share=false
+ end
+ shared[value]=share
+ end
+ hash[other]=share or nil
+ end
+ end
+ coverage[index]=hash
+ end
+ return {
+ shared=shared and true or nil,
+ format="pair",
+ coverage=coverage,
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local format1=readushort(f)
+ local format2=readushort(f)
+ local classdef1=readushort(f)
+ local classdef2=readushort(f)
+ local nofclasses1=readushort(f)
+ local nofclasses2=readushort(f)
+ local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta)
+ coverage=readcoverage(f,tableoffset+coverage)
+ classdef1=readclassdef(f,tableoffset+classdef1,coverage)
+ classdef2=readclassdef(f,tableoffset+classdef2,nofglyphs)
+ local usedcoverage={}
+ local shared={}
+ for g1,c1 in next,classdef1 do
+ if coverage[g1] then
+ local l1=classlist[c1]
+ if l1 then
+ local hash={}
+ for paired,class in next,classdef2 do
+ local offsets=l1[class]
+ if offsets then
+ local first=offsets[1]
+ local second=offsets[2]
+ if first or second then
+ local s1=shared[first]
+ if s1==nil then
+ s1={}
+ shared[first]=s1
+ end
+ local s2=s1[second]
+ if s2==nil then
+ s2={ first,second or nil }
+ s1[second]=s2
+ end
+ hash[paired]=s2
+ end
+ end
+ end
+ usedcoverage[g1]=hash
+ end
+ end
+ end
+ return {
+ shared=shared and true or nil,
+ format="pair",
+ coverage=usedcoverage,
+ }
+ elseif subtype==3 then
+ report("yet unsupported subtype %a in %a positioning",subtype,"pair")
+ else
+ report("unsupported subtype %a in %a positioning",subtype,"pair")
+ end
+end
+function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ local getdelta=fontdata.temporary.getdelta
+ if subtype==1 then
+ local coverage=tableoffset+readushort(f)
+ local nofrecords=readushort(f)
+ local records={}
+ for i=1,nofrecords do
+ local entry=readushort(f)
+ local exit=readushort(f)
+ records[i]={
+ entry~=0 and (tableoffset+entry) or false,
+ exit~=0 and (tableoffset+exit ) or nil,
+ }
+ end
+ local cc=(fontdata.temporary.cursivecount or 0)+1
+ fontdata.temporary.cursivecount=cc
+ cc="cc-"..cc
+ coverage=readcoverage(f,coverage)
+ for i=1,nofrecords do
+ local r=records[i]
+ records[i]={
+ cc,
+ readanchor(f,r[1],getdelta) or false,
+ readanchor(f,r[2],getdelta) or nil,
+ }
+ end
+ for index,newindex in next,coverage do
+ coverage[index]=records[newindex+1]
+ end
+ return {
+ coverage=coverage,
+ }
+ else
+ report("unsupported subtype %a in %a positioning",subtype,"cursive")
+ end
+end
+local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,ligature)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ local getdelta=fontdata.temporary.getdelta
+ if subtype==1 then
+ local markcoverage=tableoffset+readushort(f)
+ local basecoverage=tableoffset+readushort(f)
+ local nofclasses=readushort(f)
+ local markoffset=tableoffset+readushort(f)
+ local baseoffset=tableoffset+readushort(f)
+ local markcoverage=readcoverage(f,markcoverage)
+ local basecoverage=readcoverage(f,basecoverage,true)
+ setposition(f,markoffset)
+ local markclasses={}
+ local nofmarkclasses=readushort(f)
+ local lastanchor=fontdata.lastanchor or 0
+ local usedanchors={}
+ for i=1,nofmarkclasses do
+ local class=readushort(f)+1
+ local offset=readushort(f)
+ if offset==0 then
+ markclasses[i]=false
+ else
+ markclasses[i]={ class,markoffset+offset }
+ end
+ usedanchors[class]=true
+ end
+ for i=1,nofmarkclasses do
+ local mc=markclasses[i]
+ if mc then
+ mc[2]=readanchor(f,mc[2],getdelta)
+ end
+ end
+ setposition(f,baseoffset)
+ local nofbaserecords=readushort(f)
+ local baserecords={}
+ if ligature then
+ for i=1,nofbaserecords do
+ local offset=readushort(f)
+ if offset==0 then
+ baserecords[i]=false
+ else
+ baserecords[i]=baseoffset+offset
+ end
+ end
+ for i=1,nofbaserecords do
+ local recordoffset=baserecords[i]
+ if recordoffset then
+ setposition(f,recordoffset)
+ local nofcomponents=readushort(f)
+ local components={}
+ for i=1,nofcomponents do
+ local classes={}
+ for i=1,nofclasses do
+ local offset=readushort(f)
+ if offset~=0 then
+ classes[i]=recordoffset+offset
+ else
+ classes[i]=false
+ end
+ end
+ components[i]=classes
+ end
+ baserecords[i]=components
+ end
+ end
+ local baseclasses={}
+ for i=1,nofclasses do
+ baseclasses[i]={}
+ end
+ for i=1,nofbaserecords do
+ local components=baserecords[i]
+ if components then
+ local b=basecoverage[i]
+ for c=1,#components do
+ local classes=components[c]
+ if classes then
+ for i=1,nofclasses do
+ local anchor=readanchor(f,classes[i],getdelta)
+ local bclass=baseclasses[i]
+ local bentry=bclass[b]
+ if bentry then
+ bentry[c]=anchor
+ else
+ bclass[b]={ [c]=anchor }
+ end
+ end
+ end
+ end
+ end
+ end
+ for index,newindex in next,markcoverage do
+ markcoverage[index]=markclasses[newindex+1] or nil
+ end
+ return {
+ format="ligature",
+ baseclasses=baseclasses,
+ coverage=markcoverage,
+ }
+ else
+ for i=1,nofbaserecords do
+ local r={}
+ for j=1,nofclasses do
+ local offset=readushort(f)
+ if offset==0 then
+ r[j]=false
+ else
+ r[j]=baseoffset+offset
+ end
+ end
+ baserecords[i]=r
+ end
+ local baseclasses={}
+ for i=1,nofclasses do
+ baseclasses[i]={}
+ end
+ for i=1,nofbaserecords do
+ local r=baserecords[i]
+ local b=basecoverage[i]
+ for j=1,nofclasses do
+ baseclasses[j][b]=readanchor(f,r[j],getdelta)
+ end
+ end
+ for index,newindex in next,markcoverage do
+ markcoverage[index]=markclasses[newindex+1] or nil
+ end
+ return {
+ format="base",
+ baseclasses=baseclasses,
+ coverage=markcoverage,
+ }
+ end
+ else
+ report("unsupported subtype %a in",subtype)
+ end
+end
+function gposhandlers.marktobase(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+end
+function gposhandlers.marktoligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,true)
+end
+function gposhandlers.marktomark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+end
+function gposhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"context"
+end
+function gposhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"chainedcontext"
+end
+function gposhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gpostypes,gposhandlers,"positioning")
+end
+do
+ local plugins={}
+ function plugins.size(f,fontdata,tableoffset,feature)
+ if fontdata.designsize then
+ else
+ local function check(offset)
+ setposition(f,offset)
+ local designsize=readushort(f)
+ if designsize>0 then
+ local fontstyleid=readushort(f)
+ local guimenuid=readushort(f)
+ local minsize=readushort(f)
+ local maxsize=readushort(f)
+ if minsize==0 and maxsize==0 and fontstyleid==0 and guimenuid==0 then
+ minsize=designsize
+ maxsize=designsize
+ end
+ if designsize>=minsize and designsize<=maxsize then
+ return minsize,maxsize,designsize
+ end
+ end
+ end
+ local minsize,maxsize,designsize=check(tableoffset+feature.offset+feature.parameters)
+ if not designsize then
+ minsize,maxsize,designsize=check(tableoffset+feature.parameters)
+ if designsize then
+ report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?")
+ else
+ report("bad size feature in %a,",fontdata.filename or "?")
+ end
+ end
+ if designsize then
+ fontdata.minsize=minsize
+ fontdata.maxsize=maxsize
+ fontdata.designsize=designsize
+ end
+ end
+ end
+ local function reorderfeatures(fontdata,scripts,features)
+ local scriptlangs={}
+ local featurehash={}
+ local featureorder={}
+ for script,languages in next,scripts do
+ for language,record in next,languages do
+ local hash={}
+ local list=record.featureindices
+ for k=1,#list do
+ local index=list[k]
+ local feature=features[index]
+ local lookups=feature.lookups
+ local tag=feature.tag
+ if tag then
+ hash[tag]=true
+ end
+ if lookups then
+ for i=1,#lookups do
+ local lookup=lookups[i]
+ local o=featureorder[lookup]
+ if o then
+ local okay=true
+ for i=1,#o do
+ if o[i]==tag then
+ okay=false
+ break
+ end
+ end
+ if okay then
+ o[#o+1]=tag
+ end
+ else
+ featureorder[lookup]={ tag }
+ end
+ local f=featurehash[lookup]
+ if f then
+ local h=f[tag]
+ if h then
+ local s=h[script]
+ if s then
+ s[language]=true
+ else
+ h[script]={ [language]=true }
+ end
+ else
+ f[tag]={ [script]={ [language]=true } }
+ end
+ else
+ featurehash[lookup]={ [tag]={ [script]={ [language]=true } } }
+ end
+ local h=scriptlangs[tag]
+ if h then
+ local s=h[script]
+ if s then
+ s[language]=true
+ else
+ h[script]={ [language]=true }
+ end
+ else
+ scriptlangs[tag]={ [script]={ [language]=true } }
+ end
+ end
+ end
+ end
+ end
+ end
+ return scriptlangs,featurehash,featureorder
+ end
+ local function readscriplan(f,fontdata,scriptoffset)
+ setposition(f,scriptoffset)
+ local nofscripts=readushort(f)
+ local scripts={}
+ for i=1,nofscripts do
+ scripts[readtag(f)]=scriptoffset+readushort(f)
+ end
+ local languagesystems=setmetatableindex("table")
+ for script,offset in next,scripts do
+ setposition(f,offset)
+ local defaultoffset=readushort(f)
+ local noflanguages=readushort(f)
+ local languages={}
+ if defaultoffset>0 then
+ languages.dflt=languagesystems[offset+defaultoffset]
+ end
+ for i=1,noflanguages do
+ local language=readtag(f)
+ local offset=offset+readushort(f)
+ languages[language]=languagesystems[offset]
+ end
+ scripts[script]=languages
+ end
+ for offset,usedfeatures in next,languagesystems do
+ if offset>0 then
+ setposition(f,offset)
+ local featureindices={}
+ usedfeatures.featureindices=featureindices
+ usedfeatures.lookuporder=readushort(f)
+ usedfeatures.requiredindex=readushort(f)
+ local noffeatures=readushort(f)
+ for i=1,noffeatures do
+ featureindices[i]=readushort(f)+1
+ end
+ end
+ end
+ return scripts
+ end
+ local function readfeatures(f,fontdata,featureoffset)
+ setposition(f,featureoffset)
+ local features={}
+ local noffeatures=readushort(f)
+ for i=1,noffeatures do
+ features[i]={
+ tag=readtag(f),
+ offset=readushort(f)
+ }
+ end
+ for i=1,noffeatures do
+ local feature=features[i]
+ local offset=featureoffset+feature.offset
+ setposition(f,offset)
+ local parameters=readushort(f)
+ local noflookups=readushort(f)
+ if noflookups>0 then
+ local lookups=readcardinaltable(f,noflookups,ushort)
+ feature.lookups=lookups
+ for j=1,noflookups do
+ lookups[j]=lookups[j]+1
+ end
+ end
+ if parameters>0 then
+ feature.parameters=parameters
+ local plugin=plugins[feature.tag]
+ if plugin then
+ plugin(f,fontdata,featureoffset,feature)
+ end
+ end
+ end
+ return features
+ end
+ local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder)
+ setposition(f,lookupoffset)
+ local noflookups=readushort(f)
+ local lookups=readcardinaltable(f,noflookups,ushort)
+ for lookupid=1,noflookups do
+ local offset=lookups[lookupid]
+ setposition(f,lookupoffset+offset)
+ local subtables={}
+ local typebits=readushort(f)
+ local flagbits=readushort(f)
+ local lookuptype=lookuptypes[typebits]
+ local lookupflags=lookupflags[flagbits]
+ local nofsubtables=readushort(f)
+ for j=1,nofsubtables do
+ subtables[j]=offset+readushort(f)
+ end
+ local markclass=band(flagbits,0x0010)~=0
+ if markclass then
+ markclass=readushort(f)
+ end
+ local markset=rshift(flagbits,8)
+ if markset>0 then
+ markclass=markset
+ end
+ lookups[lookupid]={
+ type=lookuptype,
+ flags=lookupflags,
+ name=lookupid,
+ subtables=subtables,
+ markclass=markclass,
+ features=featurehash[lookupid],
+ order=featureorder[lookupid],
+ }
+ end
+ return lookups
+ end
+ local f_lookupname=formatters["%s_%s_%s"]
+ local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset)
+ local sequences=fontdata.sequences or {}
+ local sublookuplist=fontdata.sublookups or {}
+ fontdata.sequences=sequences
+ fontdata.sublookups=sublookuplist
+ local nofsublookups=#sublookuplist
+ local nofsequences=#sequences
+ local lastsublookup=nofsublookups
+ local lastsequence=nofsequences
+ local lookupnames=lookupnames[what]
+ local sublookuphash={}
+ local sublookupcheck={}
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs or #glyphs
+ local noflookups=#lookups
+ local lookupprefix=sub(what,2,2)
+ local usedlookups=false
+ for lookupid=1,noflookups do
+ local lookup=lookups[lookupid]
+ local lookuptype=lookup.type
+ local subtables=lookup.subtables
+ local features=lookup.features
+ local handler=lookuphandlers[lookuptype]
+ if handler then
+ local nofsubtables=#subtables
+ local order=lookup.order
+ local flags=lookup.flags
+ if flags[1] then flags[1]="mark" end
+ if flags[2] then flags[2]="ligature" end
+ if flags[3] then flags[3]="base" end
+ local markclass=lookup.markclass
+ if nofsubtables>0 then
+ local steps={}
+ local nofsteps=0
+ local oldtype=nil
+ for s=1,nofsubtables do
+ local step,lt=handler(f,fontdata,lookupid,lookupoffset,subtables[s],glyphs,nofglyphs)
+ if lt then
+ lookuptype=lt
+ if oldtype and lt~=oldtype then
+ report("messy %s lookup type %a and %a",what,lookuptype,oldtype)
+ end
+ oldtype=lookuptype
+ end
+ if not step then
+ report("unsupported %s lookup type %a",what,lookuptype)
+ else
+ nofsteps=nofsteps+1
+ steps[nofsteps]=step
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local before=rule.before
+ local current=rule.current
+ local after=rule.after
+ local replacements=rule.replacements
+ if before then
+ for i=1,#before do
+ before[i]=tohash(before[i])
+ end
+ rule.before=reversed(before)
+ end
+ if current then
+ if replacements then
+ local first=current[1]
+ local hash={}
+ local repl={}
+ for i=1,#first do
+ local c=first[i]
+ hash[c]=true
+ repl[c]=replacements[i]
+ end
+ rule.current={ hash }
+ rule.replacements=repl
+ else
+ for i=1,#current do
+ current[i]=tohash(current[i])
+ end
+ end
+ else
+ end
+ if after then
+ for i=1,#after do
+ after[i]=tohash(after[i])
+ end
+ end
+ if usedlookups then
+ local lookups=rule.lookups
+ if lookups then
+ for k,v in next,lookups do
+ if v then
+ for k,v in next,v do
+ usedlookups[v]=usedlookups[v]+1
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if nofsteps~=nofsubtables then
+ report("bogus subtables removed in %s lookup type %a",what,lookuptype)
+ end
+ lookuptype=lookupnames[lookuptype] or lookuptype
+ if features then
+ nofsequences=nofsequences+1
+ local l={
+ index=nofsequences,
+ name=f_lookupname(lookupprefix,"s",lookupid+lookupidoffset),
+ steps=steps,
+ nofsteps=nofsteps,
+ type=lookuptype,
+ markclass=markclass or nil,
+ flags=flags,
+ order=order,
+ features=features,
+ }
+ sequences[nofsequences]=l
+ lookup.done=l
+ else
+ nofsublookups=nofsublookups+1
+ local l={
+ index=nofsublookups,
+ name=f_lookupname(lookupprefix,"l",lookupid+lookupidoffset),
+ steps=steps,
+ nofsteps=nofsteps,
+ type=lookuptype,
+ markclass=markclass or nil,
+ flags=flags,
+ }
+ sublookuplist[nofsublookups]=l
+ sublookuphash[lookupid]=nofsublookups
+ sublookupcheck[lookupid]=0
+ lookup.done=l
+ end
+ else
+ report("no subtables for lookup %a",lookupid)
+ end
+ else
+ report("no handler for lookup %a with type %a",lookupid,lookuptype)
+ end
+ end
+ if usedlookups then
+ report("used %s lookups: % t",what,sortedkeys(usedlookups))
+ end
+ local reported={}
+ local function report_issue(i,what,sequence,kind)
+ local name=sequence.name
+ if not reported[name] then
+ report("rule %i in %s lookup %a has %s lookups",i,what,name,kind)
+ reported[name]=true
+ end
+ end
+ for i=lastsequence+1,nofsequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ for i=1,#steps do
+ local step=steps[i]
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local rlookups=rule.lookups
+ if not rlookups then
+ report_issue(i,what,sequence,"no")
+ elseif not next(rlookups) then
+ rule.lookups=nil
+ else
+ local length=#rlookups
+ for index=1,length do
+ 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
+ local l={
+ 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(l)
+ 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
+ sublookupcheck[lookupid]=sublookupcheck[lookupid]+1
+ end
+ if h then
+ noffound=noffound+1
+ found[noffound]=h
+ end
+ end
+ end
+ rlookups[index]=noffound>0 and found or false
+ else
+ rlookups[index]=false
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ for i,n in sortedhash(sublookupcheck) do
+ local l=lookups[i]
+ local t=l.type
+ if n==0 and t~="extension" then
+ local d=l.done
+ report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t)
+ end
+ end
+ end
+ local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
+ setposition(f,variationsoffset)
+ local version=readulong(f)
+ local nofrecords=readulong(f)
+ local records={}
+ for i=1,nofrecords do
+ records[i]={
+ conditions=readulong(f),
+ substitutions=readulong(f),
+ }
+ end
+ for i=1,nofrecords do
+ local record=records[i]
+ local offset=record.conditions
+ if offset==0 then
+ record.condition=nil
+ record.matchtype="always"
+ else
+ local offset=variationsoffset+offset
+ setposition(f,offset)
+ local nofconditions=readushort(f)
+ local conditions={}
+ for i=1,nofconditions do
+ conditions[i]=offset+readulong(f)
+ end
+ record.conditions=conditions
+ record.matchtype="condition"
+ end
+ end
+ for i=1,nofrecords do
+ local record=records[i]
+ if record.matchtype=="condition" then
+ local conditions=record.conditions
+ for i=1,#conditions do
+ setposition(f,conditions[i])
+ conditions[i]={
+ format=readushort(f),
+ axis=readushort(f),
+ minvalue=read2dot14(f),
+ maxvalue=read2dot14(f),
+ }
+ end
+ end
+ end
+ for i=1,nofrecords do
+ local record=records[i]
+ local offset=record.substitutions
+ if offset==0 then
+ record.substitutions={}
+ else
+ setposition(f,variationsoffset+offset)
+ local version=readulong(f)
+ local nofsubstitutions=readushort(f)
+ local substitutions={}
+ for i=1,nofsubstitutions do
+ substitutions[readushort(f)]=readulong(f)
+ end
+ for index,alternates in sortedhash(substitutions) do
+ if index==0 then
+ record.substitutions=false
+ else
+ local tableoffset=variationsoffset+offset+alternates
+ setposition(f,tableoffset)
+ local parameters=readulong(f)
+ local noflookups=readushort(f)
+ local lookups=readcardinaltable(f,noflookups,ushort)
+ record.substitutions=lookups
+ end
+ end
+ end
+ end
+ setvariabledata(fontdata,"features",records)
+ end
+ local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo)
+ local tableoffset=gotodatatable(f,fontdata,what,true)
+ if tableoffset then
+ local version=readulong(f)
+ local scriptoffset=tableoffset+readushort(f)
+ local featureoffset=tableoffset+readushort(f)
+ local lookupoffset=tableoffset+readushort(f)
+ local variationsoffset=version>0x00010000 and (tableoffset+readulong(f)) or 0
+ if not scriptoffset then
+ return
+ end
+ local scripts=readscriplan(f,fontdata,scriptoffset)
+ local features=readfeatures(f,fontdata,featureoffset)
+ local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features)
+ if fontdata.features then
+ fontdata.features[what]=scriptlangs
+ else
+ fontdata.features={ [what]=scriptlangs }
+ end
+ if not lookupstoo then
+ return
+ end
+ local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder)
+ if lookups then
+ resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset)
+ end
+ if variationsoffset>0 then
+ loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
+ end
+ end
+ end
+ local function checkkerns(f,fontdata,specification)
+ local datatable=fontdata.tables.kern
+ if not datatable then
+ return
+ end
+ local features=fontdata.features
+ local gposfeatures=features and features.gpos
+ local name
+ if not gposfeatures or not gposfeatures.kern then
+ name="kern"
+ elseif specification.globalkerns then
+ name="globalkern"
+ else
+ report("ignoring global kern table, using gpos kern feature")
+ return
+ end
+ setposition(f,datatable.offset)
+ local version=readushort(f)
+ local noftables=readushort(f)
+ if noftables>1 then
+ report("adding global kern table as gpos feature %a",name)
+ local kerns=setmetatableindex("table")
+ for i=1,noftables do
+ local version=readushort(f)
+ local length=readushort(f)
+ local coverage=readushort(f)
+ local format=rshift(coverage,8)
+ if format==0 then
+ local nofpairs=readushort(f)
+ local searchrange=readushort(f)
+ local entryselector=readushort(f)
+ local rangeshift=readushort(f)
+ for i=1,nofpairs do
+ kerns[readushort(f)][readushort(f)]=readfword(f)
+ end
+ elseif format==2 then
+ else
+ end
+ end
+ local feature={ dflt={ dflt=true } }
+ if not features then
+ fontdata.features={ gpos={ [name]=feature } }
+ elseif not gposfeatures then
+ fontdata.features.gpos={ [name]=feature }
+ else
+ gposfeatures[name]=feature
+ end
+ local sequences=fontdata.sequences
+ if not sequences then
+ sequences={}
+ fontdata.sequences=sequences
+ end
+ local nofsequences=#sequences+1
+ sequences[nofsequences]={
+ index=nofsequences,
+ name=name,
+ steps={
+ {
+ coverage=kerns,
+ format="kern",
+ },
+ },
+ nofsteps=1,
+ type="gpos_pair",
+ flags={ false,false,false,false },
+ order={ name },
+ features={ [name]=feature },
+ }
+ else
+ report("ignoring empty kern table of feature %a",name)
+ end
+ end
+ function readers.gsub(f,fontdata,specification)
+ if specification.details then
+ readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups)
+ end
+ end
+ function readers.gpos(f,fontdata,specification)
+ if specification.details then
+ readscripts(f,fontdata,"gpos",gpostypes,gposhandlers,specification.lookups)
+ if specification.lookups then
+ checkkerns(f,fontdata,specification)
+ end
+ end
+ end
+end
+function readers.gdef(f,fontdata,specification)
+ if not specification.glyphs then
+ return
+ end
+ local datatable=fontdata.tables.gdef
+ if datatable then
+ local tableoffset=datatable.offset
+ setposition(f,tableoffset)
+ local version=readulong(f)
+ local classoffset=readushort(f)
+ local attachmentoffset=readushort(f)
+ local ligaturecarets=readushort(f)
+ local markclassoffset=readushort(f)
+ local marksetsoffset=version>=0x00010002 and readushort(f) or 0
+ local varsetsoffset=version>=0x00010003 and readulong(f) or 0
+ local glyphs=fontdata.glyphs
+ local marks={}
+ local markclasses=setmetatableindex("table")
+ local marksets=setmetatableindex("table")
+ fontdata.marks=marks
+ fontdata.markclasses=markclasses
+ fontdata.marksets=marksets
+ if classoffset~=0 then
+ setposition(f,tableoffset+classoffset)
+ local classformat=readushort(f)
+ if classformat==1 then
+ local firstindex=readushort(f)
+ local lastindex=firstindex+readushort(f)-1
+ for index=firstindex,lastindex do
+ local class=classes[readushort(f)]
+ if class=="mark" then
+ marks[index]=true
+ end
+ glyphs[index].class=class
+ end
+ elseif classformat==2 then
+ local nofranges=readushort(f)
+ for i=1,nofranges do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local class=classes[readushort(f)]
+ if class then
+ for index=firstindex,lastindex do
+ glyphs[index].class=class
+ if class=="mark" then
+ marks[index]=true
+ end
+ end
+ end
+ end
+ end
+ end
+ if markclassoffset~=0 then
+ setposition(f,tableoffset+markclassoffset)
+ local classformat=readushort(f)
+ if classformat==1 then
+ local firstindex=readushort(f)
+ local lastindex=firstindex+readushort(f)-1
+ for index=firstindex,lastindex do
+ markclasses[readushort(f)][index]=true
+ end
+ elseif classformat==2 then
+ local nofranges=readushort(f)
+ for i=1,nofranges do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local class=markclasses[readushort(f)]
+ for index=firstindex,lastindex do
+ class[index]=true
+ end
+ end
+ end
+ end
+ if marksetsoffset~=0 then
+ marksetsoffset=tableoffset+marksetsoffset
+ setposition(f,marksetsoffset)
+ local format=readushort(f)
+ if format==1 then
+ local nofsets=readushort(f)
+ local sets=readcardinaltable(f,nofsets,ulong)
+ for i=1,nofsets do
+ local offset=sets[i]
+ if offset~=0 then
+ marksets[i]=readcoverage(f,marksetsoffset+offset)
+ end
+ end
+ end
+ end
+ local factors=specification.factors
+ if (specification.variable or factors) and varsetsoffset~=0 then
+ local regions,deltas=readvariationdata(f,tableoffset+varsetsoffset,factors)
+ if factors then
+ fontdata.temporary.getdelta=function(outer,inner)
+ local delta=deltas[outer+1]
+ if delta then
+ local d=delta.deltas[inner+1]
+ if d then
+ local scales=delta.scales
+ local dd=0
+ for i=1,#scales do
+ local di=d[i]
+ if di then
+ dd=dd+scales[i]*di
+ else
+ break
+ end
+ end
+ return round(dd)
+ end
+ end
+ return 0
+ end
+ end
+ end
+ end
+end
+local function readmathvalue(f)
+ local v=readshort(f)
+ skipshort(f,1)
+ return v
+end
+local function readmathconstants(f,fontdata,offset)
+ setposition(f,offset)
+ fontdata.mathconstants={
+ ScriptPercentScaleDown=readshort(f),
+ ScriptScriptPercentScaleDown=readshort(f),
+ DelimitedSubFormulaMinHeight=readushort(f),
+ DisplayOperatorMinHeight=readushort(f),
+ MathLeading=readmathvalue(f),
+ AxisHeight=readmathvalue(f),
+ AccentBaseHeight=readmathvalue(f),
+ FlattenedAccentBaseHeight=readmathvalue(f),
+ SubscriptShiftDown=readmathvalue(f),
+ SubscriptTopMax=readmathvalue(f),
+ SubscriptBaselineDropMin=readmathvalue(f),
+ SuperscriptShiftUp=readmathvalue(f),
+ SuperscriptShiftUpCramped=readmathvalue(f),
+ SuperscriptBottomMin=readmathvalue(f),
+ SuperscriptBaselineDropMax=readmathvalue(f),
+ SubSuperscriptGapMin=readmathvalue(f),
+ SuperscriptBottomMaxWithSubscript=readmathvalue(f),
+ SpaceAfterScript=readmathvalue(f),
+ UpperLimitGapMin=readmathvalue(f),
+ UpperLimitBaselineRiseMin=readmathvalue(f),
+ LowerLimitGapMin=readmathvalue(f),
+ LowerLimitBaselineDropMin=readmathvalue(f),
+ StackTopShiftUp=readmathvalue(f),
+ StackTopDisplayStyleShiftUp=readmathvalue(f),
+ StackBottomShiftDown=readmathvalue(f),
+ StackBottomDisplayStyleShiftDown=readmathvalue(f),
+ StackGapMin=readmathvalue(f),
+ StackDisplayStyleGapMin=readmathvalue(f),
+ StretchStackTopShiftUp=readmathvalue(f),
+ StretchStackBottomShiftDown=readmathvalue(f),
+ StretchStackGapAboveMin=readmathvalue(f),
+ StretchStackGapBelowMin=readmathvalue(f),
+ FractionNumeratorShiftUp=readmathvalue(f),
+ FractionNumeratorDisplayStyleShiftUp=readmathvalue(f),
+ FractionDenominatorShiftDown=readmathvalue(f),
+ FractionDenominatorDisplayStyleShiftDown=readmathvalue(f),
+ FractionNumeratorGapMin=readmathvalue(f),
+ FractionNumeratorDisplayStyleGapMin=readmathvalue(f),
+ FractionRuleThickness=readmathvalue(f),
+ FractionDenominatorGapMin=readmathvalue(f),
+ FractionDenominatorDisplayStyleGapMin=readmathvalue(f),
+ SkewedFractionHorizontalGap=readmathvalue(f),
+ SkewedFractionVerticalGap=readmathvalue(f),
+ OverbarVerticalGap=readmathvalue(f),
+ OverbarRuleThickness=readmathvalue(f),
+ OverbarExtraAscender=readmathvalue(f),
+ UnderbarVerticalGap=readmathvalue(f),
+ UnderbarRuleThickness=readmathvalue(f),
+ UnderbarExtraDescender=readmathvalue(f),
+ RadicalVerticalGap=readmathvalue(f),
+ RadicalDisplayStyleVerticalGap=readmathvalue(f),
+ RadicalRuleThickness=readmathvalue(f),
+ RadicalExtraAscender=readmathvalue(f),
+ RadicalKernBeforeDegree=readmathvalue(f),
+ RadicalKernAfterDegree=readmathvalue(f),
+ RadicalDegreeBottomRaisePercent=readshort(f),
+ }
+end
+local function readmathglyphinfo(f,fontdata,offset)
+ setposition(f,offset)
+ local italics=readushort(f)
+ local accents=readushort(f)
+ local extensions=readushort(f)
+ local kerns=readushort(f)
+ local glyphs=fontdata.glyphs
+ if italics~=0 then
+ setposition(f,offset+italics)
+ local coverage=readushort(f)
+ local nofglyphs=readushort(f)
+ coverage=readcoverage(f,offset+italics+coverage,true)
+ setposition(f,offset+italics+4)
+ for i=1,nofglyphs do
+ local italic=readmathvalue(f)
+ if italic~=0 then
+ local glyph=glyphs[coverage[i]]
+ local math=glyph.math
+ if not math then
+ glyph.math={ italic=italic }
+ else
+ math.italic=italic
+ end
+ end
+ end
+ fontdata.hasitalics=true
+ end
+ if accents~=0 then
+ setposition(f,offset+accents)
+ local coverage=readushort(f)
+ local nofglyphs=readushort(f)
+ coverage=readcoverage(f,offset+accents+coverage,true)
+ setposition(f,offset+accents+4)
+ for i=1,nofglyphs do
+ local accent=readmathvalue(f)
+ if accent~=0 then
+ local glyph=glyphs[coverage[i]]
+ local math=glyph.math
+ if not math then
+ glyph.math={ accent=accent }
+ else
+ math.accent=accent
+ end
+ end
+ end
+ end
+ if extensions~=0 then
+ setposition(f,offset+extensions)
+ end
+ if kerns~=0 then
+ local kernoffset=offset+kerns
+ setposition(f,kernoffset)
+ local coverage=readushort(f)
+ local nofglyphs=readushort(f)
+ if nofglyphs>0 then
+ local function get(offset)
+ setposition(f,kernoffset+offset)
+ local n=readushort(f)
+ if n==0 then
+ local k=readmathvalue(f)
+ if k==0 then
+ else
+ return { { kern=k } }
+ end
+ else
+ local l={}
+ for i=1,n do
+ l[i]={ height=readmathvalue(f) }
+ end
+ for i=1,n do
+ l[i].kern=readmathvalue(f)
+ end
+ l[n+1]={ kern=readmathvalue(f) }
+ return l
+ end
+ end
+ local kernsets={}
+ for i=1,nofglyphs do
+ local topright=readushort(f)
+ local topleft=readushort(f)
+ local bottomright=readushort(f)
+ local bottomleft=readushort(f)
+ kernsets[i]={
+ topright=topright~=0 and topright or nil,
+ topleft=topleft~=0 and topleft or nil,
+ bottomright=bottomright~=0 and bottomright or nil,
+ bottomleft=bottomleft~=0 and bottomleft or nil,
+ }
+ end
+ coverage=readcoverage(f,kernoffset+coverage,true)
+ for i=1,nofglyphs do
+ local kernset=kernsets[i]
+ if next(kernset) then
+ local k=kernset.topright if k then kernset.topright=get(k) end
+ local k=kernset.topleft if k then kernset.topleft=get(k) end
+ local k=kernset.bottomright if k then kernset.bottomright=get(k) end
+ local k=kernset.bottomleft if k then kernset.bottomleft=get(k) end
+ if next(kernset) then
+ local glyph=glyphs[coverage[i]]
+ local math=glyph.math
+ if math then
+ math.kerns=kernset
+ else
+ glyph.math={ kerns=kernset }
+ end
+ end
+ end
+ end
+ end
+ end
+end
+local function readmathvariants(f,fontdata,offset)
+ setposition(f,offset)
+ local glyphs=fontdata.glyphs
+ local minoverlap=readushort(f)
+ local vcoverage=readushort(f)
+ local hcoverage=readushort(f)
+ local vnofglyphs=readushort(f)
+ local hnofglyphs=readushort(f)
+ local vconstruction=readcardinaltable(f,vnofglyphs,ushort)
+ local hconstruction=readcardinaltable(f,hnofglyphs,ushort)
+ fontdata.mathconstants.MinConnectorOverlap=minoverlap
+ local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic)
+ if coverage~=0 and nofglyphs>0 then
+ local coverage=readcoverage(f,offset+coverage,true)
+ for i=1,nofglyphs do
+ local c=construction[i]
+ if c~=0 then
+ local index=coverage[i]
+ local glyph=glyphs[index]
+ local math=glyph.math
+ setposition(f,offset+c)
+ local assembly=readushort(f)
+ local nofvariants=readushort(f)
+ if nofvariants>0 then
+ local variants,v=nil,0
+ for i=1,nofvariants do
+ local variant=readushort(f)
+ if variant==index then
+ elseif variants then
+ v=v+1
+ variants[v]=variant
+ else
+ v=1
+ variants={ variant }
+ end
+ skipshort(f)
+ end
+ if not variants then
+ elseif not math then
+ math={ [kvariants]=variants }
+ glyph.math=math
+ else
+ math[kvariants]=variants
+ end
+ end
+ if assembly~=0 then
+ setposition(f,offset+c+assembly)
+ local italic=readmathvalue(f)
+ local nofparts=readushort(f)
+ local parts={}
+ for i=1,nofparts do
+ local p={
+ glyph=readushort(f),
+ start=readushort(f),
+ ["end"]=readushort(f),
+ advance=readushort(f),
+ }
+ local flags=readushort(f)
+ if band(flags,0x0001)~=0 then
+ p.extender=1
+ end
+ parts[i]=p
+ end
+ if not math then
+ math={
+ [kparts]=parts
+ }
+ glyph.math=math
+ else
+ math[kparts]=parts
+ end
+ if italic and italic~=0 then
+ math[kitalic]=italic
+ end
+ end
+ end
+ end
+ end
+ end
+ get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic")
+ get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic")
+end
+function readers.math(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"math",specification.glyphs)
+ if tableoffset then
+ local version=readulong(f)
+ local constants=readushort(f)
+ local glyphinfo=readushort(f)
+ local variants=readushort(f)
+ if constants==0 then
+ report("the math table of %a has no constants",fontdata.filename)
+ else
+ readmathconstants(f,fontdata,tableoffset+constants)
+ end
+ if glyphinfo~=0 then
+ readmathglyphinfo(f,fontdata,tableoffset+glyphinfo)
+ end
+ if variants~=0 then
+ readmathvariants(f,fontdata,tableoffset+variants)
+ end
+ end
+end
+function readers.colr(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"colr",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ if version~=0 then
+ report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename)
+ return
+ end
+ if not fontdata.tables.cpal then
+ report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal")
+ fontdata.colorpalettes={}
+ end
+ local glyphs=fontdata.glyphs
+ local nofglyphs=readushort(f)
+ local baseoffset=readulong(f)
+ local layeroffset=readulong(f)
+ local noflayers=readushort(f)
+ local layerrecords={}
+ local maxclass=0
+ setposition(f,tableoffset+layeroffset)
+ for i=1,noflayers do
+ local slot=readushort(f)
+ local class=readushort(f)
+ if class<0xFFFF then
+ class=class+1
+ if class>maxclass then
+ maxclass=class
+ end
+ end
+ layerrecords[i]={
+ slot=slot,
+ class=class,
+ }
+ end
+ fontdata.maxcolorclass=maxclass
+ setposition(f,tableoffset+baseoffset)
+ for i=0,nofglyphs-1 do
+ local glyphindex=readushort(f)
+ local firstlayer=readushort(f)
+ local noflayers=readushort(f)
+ local t={}
+ for i=1,noflayers do
+ t[i]=layerrecords[firstlayer+i]
+ end
+ glyphs[glyphindex].colors=t
+ end
+ end
+ fontdata.hascolor=true
+end
+function readers.cpal(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"cpal",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local nofpaletteentries=readushort(f)
+ local nofpalettes=readushort(f)
+ local nofcolorrecords=readushort(f)
+ local firstcoloroffset=readulong(f)
+ local colorrecords={}
+ local palettes=readcardinaltable(f,nofpalettes,ushort)
+ if version==1 then
+ local palettettypesoffset=readulong(f)
+ local palettelabelsoffset=readulong(f)
+ local paletteentryoffset=readulong(f)
+ end
+ setposition(f,tableoffset+firstcoloroffset)
+ for i=1,nofcolorrecords do
+ local b,g,r,a=readbytes(f,4)
+ colorrecords[i]={
+ r,g,b,a~=255 and a or nil,
+ }
+ end
+ for i=1,nofpalettes do
+ local p={}
+ local o=palettes[i]
+ for j=1,nofpaletteentries do
+ p[j]=colorrecords[o+j]
+ end
+ palettes[i]=p
+ end
+ fontdata.colorpalettes=palettes
+ end
+end
+function readers.svg(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local glyphs=fontdata.glyphs
+ local indexoffset=tableoffset+readulong(f)
+ local reserved=readulong(f)
+ setposition(f,indexoffset)
+ local nofentries=readushort(f)
+ local entries={}
+ for i=1,nofentries do
+ entries[i]={
+ first=readushort(f),
+ last=readushort(f),
+ offset=indexoffset+readulong(f),
+ length=readulong(f),
+ }
+ end
+ for i=1,nofentries do
+ local entry=entries[i]
+ setposition(f,entry.offset)
+ entries[i]={
+ first=entry.first,
+ last=entry.last,
+ data=readstring(f,entry.length)
+ }
+ end
+ fontdata.svgshapes=entries
+ end
+ fontdata.hascolor=true
+end
+function readers.sbix(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"sbix",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local flags=readushort(f)
+ local nofstrikes=readulong(f)
+ local strikes={}
+ local nofglyphs=fontdata.nofglyphs
+ for i=1,nofstrikes do
+ strikes[i]=readulong(f)
+ end
+ local shapes={}
+ local done=0
+ for i=1,nofstrikes do
+ local strikeoffset=strikes[i]+tableoffset
+ setposition(f,strikeoffset)
+ strikes[i]={
+ ppem=readushort(f),
+ ppi=readushort(f),
+ offset=strikeoffset
+ }
+ end
+ sort(strikes,function(a,b)
+ if b.ppem==a.ppem then
+ return b.ppi<a.ppi
+ else
+ return b.ppem<a.ppem
+ end
+ end)
+ local glyphs={}
+ for i=1,nofstrikes do
+ local strike=strikes[i]
+ local strikeppem=strike.ppem
+ local strikeppi=strike.ppi
+ local strikeoffset=strike.offset
+ setposition(f,strikeoffset)
+ for i=0,nofglyphs do
+ glyphs[i]=readulong(f)
+ end
+ local glyphoffset=glyphs[0]
+ for i=0,nofglyphs-1 do
+ local nextoffset=glyphs[i+1]
+ if not shapes[i] then
+ local datasize=nextoffset-glyphoffset
+ if datasize>0 then
+ setposition(f,strikeoffset+glyphoffset)
+ shapes[i]={
+ x=readshort(f),
+ y=readshort(f),
+ tag=readtag(f),
+ data=readstring(f,datasize-8),
+ ppem=strikeppem,
+ ppi=strikeppi,
+ }
+ done=done+1
+ if done==nofglyphs then
+ break
+ end
+ end
+ end
+ glyphoffset=nextoffset
+ end
+ end
+ fontdata.pngshapes=shapes
+ end
+end
+do
+ local function getmetrics(f)
+ return {
+ ascender=readinteger(f),
+ descender=readinteger(f),
+ widthmax=readuinteger(f),
+ caretslopedumerator=readinteger(f),
+ caretslopedenominator=readinteger(f),
+ caretoffset=readinteger(f),
+ minorigin=readinteger(f),
+ minadvance=readinteger(f),
+ maxbefore=readinteger(f),
+ minafter=readinteger(f),
+ pad1=readinteger(f),
+ pad2=readinteger(f),
+ }
+ end
+ local function getbigmetrics(f)
+ return {
+ height=readuinteger(f),
+ width=readuinteger(f),
+ horiBearingX=readinteger(f),
+ horiBearingY=readinteger(f),
+ horiAdvance=readuinteger(f),
+ vertBearingX=readinteger(f),
+ vertBearingY=readinteger(f),
+ vertAdvance=readuinteger(f),
+ }
+ end
+ local function getsmallmetrics(f)
+ return {
+ height=readuinteger(f),
+ width=readuinteger(f),
+ bearingX=readinteger(f),
+ bearingY=readinteger(f),
+ advance=readuinteger(f),
+ }
+ end
+ function readers.cblc(f,fontdata,specification)
+ local ctdttableoffset=gotodatatable(f,fontdata,"cbdt",specification.glyphs)
+ if not ctdttableoffset then
+ return
+ end
+ local cblctableoffset=gotodatatable(f,fontdata,"cblc",specification.glyphs)
+ if cblctableoffset then
+ local majorversion=readushort(f)
+ local minorversion=readushort(f)
+ local nofsizetables=readulong(f)
+ local sizetables={}
+ local shapes={}
+ local subtables={}
+ for i=1,nofsizetables do
+ sizetables[i]={
+ subtables=readulong(f),
+ indexsize=readulong(f),
+ nofsubtables=readulong(f),
+ colorref=readulong(f),
+ hormetrics=getmetrics(f),
+ vermetrics=getmetrics(f),
+ firstindex=readushort(f),
+ lastindex=readushort(f),
+ ppemx=readbyte(f),
+ ppemy=readbyte(f),
+ bitdepth=readbyte(f),
+ flags=readbyte(f),
+ }
+ end
+ sort(sizetables,function(a,b)
+ if b.ppemx==a.ppemx then
+ return b.bitdepth<a.bitdepth
+ else
+ return b.ppemx<a.ppemx
+ end
+ end)
+ for i=1,nofsizetables do
+ local s=sizetables[i]
+ local d=false
+ for j=s.firstindex,s.lastindex do
+ if not shapes[j] then
+ shapes[j]=i
+ d=true
+ end
+ end
+ if d then
+ s.used=true
+ end
+ end
+ for i=1,nofsizetables do
+ local s=sizetables[i]
+ if s.used then
+ local offset=s.subtables
+ setposition(f,cblctableoffset+offset)
+ for j=1,s.nofsubtables do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local tableoffset=readulong(f)+offset
+ for k=firstindex,lastindex do
+ if shapes[k]==i then
+ local s=subtables[tableoffset]
+ if not s then
+ s={
+ firstindex=firstindex,
+ lastindex=lastindex,
+ }
+ subtables[tableoffset]=s
+ end
+ shapes[k]=s
+ end
+ end
+ end
+ end
+ end
+ for offset,subtable in sortedhash(subtables) do
+ local tabletype=readushort(f)
+ subtable.format=readushort(f)
+ local baseoffset=readulong(f)+ctdttableoffset
+ local offsets={}
+ local metrics=nil
+ if tabletype==1 then
+ for i=subtable.firstindex,subtable.lastindex do
+ offsets[i]=readulong(f)+baseoffset
+ end
+ skipbytes(f,4)
+ elseif tabletype==2 then
+ local size=readulong(f)
+ local done=baseoffset
+ metrics=getbigmetrics(f)
+ for i=subtable.firstindex,subtable.lastindex do
+ offsets[i]=done
+ done=done+size
+ end
+ elseif tabletype==3 then
+ local n=subtable.lastindex-subtable.firstindex+2
+ for i=subtable.firstindex,subtable.lastindex do
+ offsets[i]=readushort(f)+baseoffset
+ end
+ if math.odd(n) then
+ skipbytes(f,4)
+ else
+ skipbytes(f,2)
+ end
+ elseif tabletype==4 then
+ for i=1,readulong(f) do
+ offsets[readushort(f)]=readushort(f)+baseoffset
+ end
+ elseif tabletype==5 then
+ local size=readulong(f)
+ local done=baseoffset
+ metrics=getbigmetrics(f)
+ local n=readulong(f)
+ for i=1,n do
+ offsets[readushort(f)]=done
+ done=done+size
+ end
+ if math.odd(n) then
+ skipbytes(f,2)
+ end
+ else
+ return
+ end
+ subtable.offsets=offsets
+ subtable.metrics=metrics
+ end
+ local default={ width=0,height=0 }
+ local glyphs=fontdata.glyphs
+ for index,subtable in sortedhash(shapes) do
+ if type(subtable)=="table" then
+ local data=nil
+ local metrics=default
+ local format=subtable.format
+ local offset=subtable.offsets[index]
+ setposition(f,offset)
+ if format==17 then
+ metrics=getsmallmetrics(f)
+ data=readstring(f,readulong(f))
+ elseif format==18 then
+ metrics=getbigmetrics(f)
+ data=readstring(f,readulong(f))
+ elseif format==19 then
+ metrics=subtable.metrics
+ data=readstring(f,readulong(f))
+ else
+ end
+ local x=metrics.width
+ local y=metrics.height
+ shapes[index]={
+ x=x,
+ y=y,
+ data=data,
+ }
+ local glyph=glyphs[index]
+ if not glyph.boundingbox then
+ local width=glyph.width
+ local height=width*y/x
+ glyph.boundingbox={ 0,0,width,height }
+ end
+ else
+ shapes[index]={
+ x=0,
+ y=0,
+ data="",
+ }
+ end
+ end
+ fontdata.pngshapes=shapes
+ end
+ end
+ function readers.cbdt(f,fontdata,specification)
+ end
+end
+function readers.stat(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"stat",true)
+ if tableoffset then
+ local extras=fontdata.extras
+ local version=readulong(f)
+ local axissize=readushort(f)
+ local nofaxis=readushort(f)
+ local axisoffset=readulong(f)
+ local nofvalues=readushort(f)
+ local valuesoffset=readulong(f)
+ local fallbackname=extras[readushort(f)]
+ local axis={}
+ local values={}
+ setposition(f,tableoffset+axisoffset)
+ for i=1,nofaxis do
+ local tag=readtag(f)
+ axis[i]={
+ tag=tag,
+ name=lower(extras[readushort(f)] or tag),
+ ordering=readushort(f),
+ variants={}
+ }
+ end
+ setposition(f,tableoffset+valuesoffset)
+ for i=1,nofvalues do
+ values[i]=readushort(f)
+ end
+ for i=1,nofvalues do
+ setposition(f,tableoffset+valuesoffset+values[i])
+ local format=readushort(f)
+ local index=readushort(f)+1
+ local flags=readushort(f)
+ local name=lower(extras[readushort(f)] or "no name")
+ local value=readfixed(f)
+ local variant
+ if format==1 then
+ variant={
+ flags=flags,
+ name=name,
+ value=value,
+ }
+ elseif format==2 then
+ variant={
+ flags=flags,
+ name=name,
+ value=value,
+ minimum=readfixed(f),
+ maximum=readfixed(f),
+ }
+ elseif format==3 then
+ variant={
+ flags=flags,
+ name=name,
+ value=value,
+ link=readfixed(f),
+ }
+ end
+ insert(axis[index].variants,variant)
+ end
+ sort(axis,function(a,b)
+ return a.ordering<b.ordering
+ end)
+ for i=1,#axis do
+ local a=axis[i]
+ sort(a.variants,function(a,b)
+ return a.name<b.name
+ end)
+ a.ordering=nil
+ end
+ setvariabledata(fontdata,"designaxis",axis)
+ setvariabledata(fontdata,"fallbackname",fallbackname)
+ end
+end
+function readers.avar(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"avar",true)
+ if tableoffset then
+ local function collect()
+ local nofvalues=readushort(f)
+ local values={}
+ local lastfrom=false
+ local lastto=false
+ for i=1,nofvalues do
+ local from=read2dot14(f)
+ local to=read2dot14(f)
+ if lastfrom and from<=lastfrom then
+ elseif lastto and to>=lastto then
+ else
+ values[#values+1]={ from,to }
+ lastfrom,lastto=from,to
+ end
+ end
+ nofvalues=#values
+ if nofvalues>2 then
+ local some=values[1]
+ if some[1]==-1 and some[2]==-1 then
+ some=values[nofvalues]
+ if some[1]==1 and some[2]==1 then
+ for i=2,nofvalues-1 do
+ some=values[i]
+ if some[1]==0 and some[2]==0 then
+ return values
+ end
+ end
+ end
+ end
+ end
+ return false
+ end
+ local version=readulong(f)
+ local reserved=readushort(f)
+ local nofaxis=readushort(f)
+ local segments={}
+ for i=1,nofaxis do
+ segments[i]=collect()
+ end
+ setvariabledata(fontdata,"segments",segments)
+ end
+end
+function readers.fvar(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"fvar",true)
+ if tableoffset then
+ local version=readulong(f)
+ local offsettoaxis=tableoffset+readushort(f)
+ local reserved=skipshort(f)
+ local nofaxis=readushort(f)
+ local sizeofaxis=readushort(f)
+ local nofinstances=readushort(f)
+ local sizeofinstances=readushort(f)
+ local extras=fontdata.extras
+ local axis={}
+ local instances={}
+ setposition(f,offsettoaxis)
+ for i=1,nofaxis do
+ axis[i]={
+ tag=readtag(f),
+ minimum=readfixed(f),
+ default=readfixed(f),
+ maximum=readfixed(f),
+ flags=readushort(f),
+ name=lower(extras[readushort(f)] or "bad name"),
+ }
+ local n=sizeofaxis-20
+ if n>0 then
+ skipbytes(f,n)
+ elseif n<0 then
+ end
+ end
+ local nofbytes=2+2+2+nofaxis*4
+ local readpsname=nofbytes<=sizeofinstances
+ local skippable=sizeofinstances-nofbytes
+ for i=1,nofinstances do
+ local subfamid=readushort(f)
+ local flags=readushort(f)
+ local values={}
+ for i=1,nofaxis do
+ values[i]={
+ axis=axis[i].tag,
+ value=readfixed(f),
+ }
+ end
+ local psnameid=readpsname and readushort(f) or 0xFFFF
+ if subfamid==2 or subfamid==17 then
+ elseif subfamid==0xFFFF then
+ subfamid=nil
+ elseif subfamid<=256 or subfamid>=32768 then
+ subfamid=nil
+ end
+ if psnameid==6 then
+ elseif psnameid==0xFFFF then
+ psnameid=nil
+ elseif psnameid<=256 or psnameid>=32768 then
+ psnameid=nil
+ end
+ instances[i]={
+ subfamily=extras[subfamid],
+ psname=psnameid and extras[psnameid] or nil,
+ values=values,
+ }
+ if skippable>0 then
+ skipbytes(f,skippable)
+ end
+ end
+ setvariabledata(fontdata,"axis",axis)
+ setvariabledata(fontdata,"instances",instances)
+ end
+end
+function readers.hvar(f,fontdata,specification)
+ local factors=specification.factors
+ if not factors then
+ return
+ end
+ local tableoffset=gotodatatable(f,fontdata,"hvar",specification.variable)
+ if not tableoffset then
+ return
+ end
+ local version=readulong(f)
+ local variationoffset=tableoffset+readulong(f)
+ local advanceoffset=tableoffset+readulong(f)
+ local lsboffset=tableoffset+readulong(f)
+ local rsboffset=tableoffset+readulong(f)
+ local regions={}
+ local variations={}
+ local innerindex={}
+ local outerindex={}
+ if variationoffset>0 then
+ regions,deltas=readvariationdata(f,variationoffset,factors)
+ end
+ if not regions then
+ return
+ end
+ if advanceoffset>0 then
+ setposition(f,advanceoffset)
+ local format=readushort(f)
+ local mapcount=readushort(f)
+ local entrysize=rshift(band(format,0x0030),4)+1
+ local nofinnerbits=band(format,0x000F)+1
+ local innermask=lshift(1,nofinnerbits)-1
+ local readcardinal=read_cardinal[entrysize]
+ for i=0,mapcount-1 do
+ local mapdata=readcardinal(f)
+ outerindex[i]=rshift(mapdata,nofinnerbits)
+ innerindex[i]=band(mapdata,innermask)
+ end
+ setvariabledata(fontdata,"hvarwidths",true)
+ local glyphs=fontdata.glyphs
+ for i=0,fontdata.nofglyphs-1 do
+ local glyph=glyphs[i]
+ local width=glyph.width
+ if width then
+ local outer=outerindex[i] or 0
+ local inner=innerindex[i] or i
+ if outer and inner then
+ local delta=deltas[outer+1]
+ if delta then
+ local d=delta.deltas[inner+1]
+ if d then
+ local scales=delta.scales
+ local deltaw=0
+ for i=1,#scales do
+ local di=d[i]
+ if di then
+ deltaw=deltaw+scales[i]*di
+ else
+ break
+ end
+ end
+ glyph.width=width+round(deltaw)
+ end
+ end
+ end
+ end
+ end
+ end
+end
+function readers.vvar(f,fontdata,specification)
+ if not specification.variable then
+ return
+ end
+end
+function readers.mvar(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"mvar",specification.variable)
+ if tableoffset then
+ local version=readulong(f)
+ local reserved=skipshort(f,1)
+ local recordsize=readushort(f)
+ local nofrecords=readushort(f)
+ local offsettostore=tableoffset+readushort(f)
+ local dimensions={}
+ local factors=specification.factors
+ if factors then
+ local regions,deltas=readvariationdata(f,offsettostore,factors)
+ for i=1,nofrecords do
+ local tag=readtag(f)
+ local var=variabletags[tag]
+ if var then
+ local outer=readushort(f)
+ local inner=readushort(f)
+ local delta=deltas[outer+1]
+ if delta then
+ local d=delta.deltas[inner+1]
+ if d then
+ local scales=delta.scales
+ local dd=0
+ for i=1,#scales do
+ dd=dd+scales[i]*d[i]
+ end
+ var(fontdata,round(dd))
+ end
+ end
+ else
+ skipshort(f,2)
+ end
+ if recordsize>8 then
+ skipbytes(recordsize-8)
+ end
+ end
+ end
+ end
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-dspâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oup†669e479e716999edc626a1f045bd76fa] ---
+
+if not modules then modules={} end modules ['font-oup']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type=next,type
+local P,R,S=lpeg.P,lpeg.R,lpeg.S
+local lpegmatch=lpeg.match
+local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack
+local formatters=string.formatters
+local sortedkeys=table.sortedkeys
+local sortedhash=table.sortedhash
+local tohash=table.tohash
+local setmetatableindex=table.setmetatableindex
+local report_error=logs.reporter("otf reader","error")
+local report_markwidth=logs.reporter("otf reader","markwidth")
+local report_cleanup=logs.reporter("otf reader","cleanup")
+local report_optimizations=logs.reporter("otf reader","merges")
+local report_unicodes=logs.reporter("otf reader","unicodes")
+local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end)
+local trace_cleanup=false trackers.register("otf.cleanups",function(v) trace_cleanups=v end)
+local trace_optimizations=false trackers.register("otf.optimizations",function(v) trace_optimizations=v end)
+local trace_unicodes=false trackers.register("otf.unicodes",function(v) trace_unicodes=v end)
+local readers=fonts.handlers.otf.readers
+local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+local f_private=formatters["P%05X"]
+local f_unicode=formatters["U%05X"]
+local f_index=formatters["I%05X"]
+local f_character_y=formatters["%C"]
+local f_character_n=formatters["[ %C ]"]
+local check_duplicates=true
+local check_soft_hyphen=true
+directives.register("otf.checksofthyphen",function(v)
+ check_soft_hyphen=v
+end)
+local function replaced(list,index,replacement)
+ if type(list)=="number" then
+ return replacement
+ elseif type(replacement)=="table" then
+ local t={}
+ local n=index-1
+ for i=1,n do
+ t[i]=list[i]
+ end
+ for i=1,#replacement do
+ n=n+1
+ t[n]=replacement[i]
+ end
+ for i=index+1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ else
+ list[index]=replacement
+ return list
+ end
+end
+local function unifyresources(fontdata,indices)
+ local descriptions=fontdata.descriptions
+ local resources=fontdata.resources
+ if not descriptions or not resources then
+ return
+ end
+ local nofindices=#indices
+ local variants=fontdata.resources.variants
+ if variants then
+ for selector,unicodes in next,variants do
+ for unicode,index in next,unicodes do
+ unicodes[unicode]=indices[index]
+ end
+ end
+ end
+ local function remark(marks)
+ if marks then
+ local newmarks={}
+ for k,v in next,marks do
+ local u=indices[k]
+ if u then
+ newmarks[u]=v
+ elseif trace_optimizations then
+ report_optimizations("discarding mark %i",k)
+ end
+ end
+ return newmarks
+ end
+ end
+ local marks=resources.marks
+ if marks then
+ resources.marks=remark(marks)
+ end
+ local markclasses=resources.markclasses
+ if markclasses then
+ for class,marks in next,markclasses do
+ markclasses[class]=remark(marks)
+ end
+ end
+ local marksets=resources.marksets
+ if marksets then
+ for class,marks in next,marksets do
+ marksets[class]=remark(marks)
+ end
+ end
+ local done={}
+ local duplicates=check_duplicates and resources.duplicates
+ if duplicates and not next(duplicates) then
+ duplicates=false
+ end
+ local function recover(cover)
+ for i=1,#cover do
+ local c=cover[i]
+ if not done[c] then
+ local t={}
+ for k,v in next,c do
+ local ug=indices[k]
+ if ug then
+ t[ug]=v
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices)
+ end
+ end
+ cover[i]=t
+ done[c]=d
+ end
+ end
+ end
+ local function recursed(c,kind)
+ local t={}
+ for g,d in next,c do
+ if type(d)=="table" then
+ local ug=indices[g]
+ if ug then
+ t[ug]=recursed(d,kind)
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices)
+ end
+ else
+ t[g]=indices[d]
+ end
+ end
+ return t
+ end
+ local function unifythem(sequences)
+ if not sequences then
+ return
+ end
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local features=sequence.features
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gsub_single" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ local ud1=indices[d1]
+ if ud1 then
+ t1[ug1]=ud1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=ud1
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices)
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=indices[d1]
+ else
+ report_error("fuzzy case %i in unifying %s: %i",2,kind,g1)
+ end
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ local t2=done[d1]
+ if not t2 then
+ t2={}
+ for g2,d2 in next,d1 do
+ local ug2=indices[g2]
+ if ug2 then
+ t2[ug2]=d2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices)
+ end
+ end
+ done[d1]=t2
+ end
+ t1[ug1]=t2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gsub_ligature" then
+ local c=step.coverage
+ if c then
+ step.coverage=recursed(c,kind)
+ end
+ elseif kind=="gsub_alternate" or kind=="gsub_multiple" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ for i=1,#d1 do
+ local d1i=d1[i]
+ local d1u=indices[d1i]
+ if d1u then
+ d1[i]=d1u
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices)
+ end
+ end
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=copy(d1)
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ for i=1,#d1 do
+ local d1i=d1[i]
+ local d1u=indices[d1i]
+ if d1u then
+ d1[i]=d1u
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices)
+ end
+ end
+ t1[indices[g1]]=d1
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gpos_single" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=d1
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ local c=step.baseclasses
+ if c then
+ local t1=done[c]
+ if not t1 then
+ for g1,d1 in next,c do
+ local t2=done[d1]
+ if not t2 then
+ t2={}
+ for g2,d2 in next,d1 do
+ local ug2=indices[g2]
+ if ug2 then
+ t2[ug2]=d2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices)
+ end
+ end
+ done[d1]=t2
+ end
+ c[g1]=t2
+ end
+ done[c]=c
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=copy(d1)
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local before=rule.before if before then recover(before) end
+ local after=rule.after if after then recover(after) end
+ local current=rule.current if current then recover(current) end
+ local replacements=rule.replacements
+ if replacements then
+ if not done[replacements] then
+ local r={}
+ for k,v in next,replacements do
+ r[indices[k]]=indices[v]
+ end
+ rule.replacements=r
+ done[replacements]=r
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ unifythem(resources.sequences)
+ unifythem(resources.sublookups)
+end
+local function copyduplicates(fontdata)
+ if check_duplicates then
+ local descriptions=fontdata.descriptions
+ local resources=fontdata.resources
+ local duplicates=resources.duplicates
+ if check_soft_hyphen then
+ local ds=descriptions[0xAD]
+ if not ds or ds.width==0 then
+ if ds then
+ descriptions[0xAD]=nil
+ if trace_unicodes then
+ report_unicodes("patching soft hyphen")
+ end
+ else
+ if trace_unicodes then
+ report_unicodes("adding soft hyphen")
+ end
+ end
+ if not duplicates then
+ duplicates={}
+ resources.duplicates=duplicates
+ end
+ local dh=duplicates[0x2D]
+ if dh then
+ dh[#dh+1]={ [0xAD]=true }
+ else
+ duplicates[0x2D]={ [0xAD]=true }
+ end
+ end
+ end
+ if duplicates then
+ for u,d in next,duplicates do
+ local du=descriptions[u]
+ if du then
+ local t={ f_character_y(u),"@",f_index(du.index),"->" }
+ local n=0
+ local m=25
+ for u in next,d do
+ if descriptions[u] then
+ if n<m then
+ t[n+4]=f_character_n(u)
+ end
+ else
+ local c=copy(du)
+ c.unicode=u
+ descriptions[u]=c
+ if n<m then
+ t[n+4]=f_character_y(u)
+ end
+ end
+ n=n+1
+ end
+ if trace_unicodes then
+ if n<=m then
+ report_unicodes("%i : % t",n,t)
+ else
+ report_unicodes("%i : % t ...",n,t)
+ end
+ end
+ else
+ end
+ end
+ end
+ end
+end
+local ignore={
+ ["notdef"]=true,
+ [".notdef"]=true,
+ ["null"]=true,
+ [".null"]=true,
+ ["nonmarkingreturn"]=true,
+}
+local function checklookups(fontdata,missing,nofmissing)
+ local descriptions=fontdata.descriptions
+ local resources=fontdata.resources
+ if missing and nofmissing and nofmissing<=0 then
+ return
+ end
+ local singles={}
+ local alternates={}
+ local ligatures={}
+ if not missing then
+ missing={}
+ nofmissing=0
+ for u,d in next,descriptions do
+ if not d.unicode then
+ nofmissing=nofmissing+1
+ missing[u]=true
+ end
+ end
+ end
+ local function collectthem(sequences)
+ if not sequences then
+ return
+ end
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gsub_single" then
+ local c=step.coverage
+ if c then
+ singles[#singles+1]=c
+ end
+ elseif kind=="gsub_alternate" then
+ local c=step.coverage
+ if c then
+ alternates[#alternates+1]=c
+ end
+ elseif kind=="gsub_ligature" then
+ local c=step.coverage
+ if c then
+ ligatures[#ligatures+1]=c
+ end
+ end
+ end
+ end
+ end
+ end
+ collectthem(resources.sequences)
+ collectthem(resources.sublookups)
+ local loops=0
+ while true do
+ loops=loops+1
+ local old=nofmissing
+ for i=1,#singles do
+ local c=singles[i]
+ for g1,g2 in next,c do
+ if missing[g1] then
+ local u2=descriptions[g2].unicode
+ if u2 then
+ missing[g1]=false
+ descriptions[g1].unicode=u2
+ nofmissing=nofmissing-1
+ end
+ end
+ if missing[g2] then
+ local u1=descriptions[g1].unicode
+ if u1 then
+ missing[g2]=false
+ descriptions[g2].unicode=u1
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ end
+ for i=1,#alternates do
+ local c=alternates[i]
+ for g1,d1 in next,c do
+ if missing[g1] then
+ for i=1,#d1 do
+ local g2=d1[i]
+ local u2=descriptions[g2].unicode
+ if u2 then
+ missing[g1]=false
+ descriptions[g1].unicode=u2
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ if not missing[g1] then
+ for i=1,#d1 do
+ local g2=d1[i]
+ if missing[g2] then
+ local u1=descriptions[g1].unicode
+ if u1 then
+ missing[g2]=false
+ descriptions[g2].unicode=u1
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ end
+ end
+ end
+ if nofmissing<=0 then
+ if trace_unicodes then
+ report_unicodes("all missings done in %s loops",loops)
+ end
+ return
+ elseif old==nofmissing then
+ break
+ end
+ end
+ local t,n
+ local function recursed(c)
+ for g,d in next,c do
+ if g~="ligature" then
+ local u=descriptions[g].unicode
+ if u then
+ n=n+1
+ t[n]=u
+ recursed(d)
+ n=n-1
+ end
+ elseif missing[d] then
+ local l={}
+ local m=0
+ for i=1,n do
+ local u=t[i]
+ if type(u)=="table" then
+ for i=1,#u do
+ m=m+1
+ l[m]=u[i]
+ end
+ else
+ m=m+1
+ l[m]=u
+ end
+ end
+ missing[d]=false
+ descriptions[d].unicode=l
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ if nofmissing>0 then
+ t={}
+ n=0
+ local loops=0
+ while true do
+ loops=loops+1
+ local old=nofmissing
+ for i=1,#ligatures do
+ recursed(ligatures[i])
+ end
+ if nofmissing<=0 then
+ if trace_unicodes then
+ report_unicodes("all missings done in %s loops",loops)
+ end
+ return
+ elseif old==nofmissing then
+ break
+ end
+ end
+ t=nil
+ n=0
+ end
+ if trace_unicodes and nofmissing>0 then
+ local done={}
+ for i,r in next,missing do
+ if r then
+ local data=descriptions[i]
+ local name=data and data.name or f_index(i)
+ if not ignore[name] then
+ done[name]=true
+ end
+ end
+ end
+ if next(done) then
+ report_unicodes("not unicoded: % t",sortedkeys(done))
+ end
+ end
+end
+local function unifymissing(fontdata)
+ if not fonts.mappings then
+ require("font-map")
+ require("font-agl")
+ end
+ local unicodes={}
+ local resources=fontdata.resources
+ resources.unicodes=unicodes
+ for unicode,d in next,fontdata.descriptions do
+ if unicode<privateoffset then
+ local name=d.name
+ if name then
+ unicodes[name]=unicode
+ end
+ end
+ end
+ fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups)
+ resources.unicodes=nil
+end
+local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000
+local puafirst=0xE000
+local pualast=0xF8FF
+local function unifyglyphs(fontdata,usenames)
+ local private=fontdata.private or privateoffset
+ local glyphs=fontdata.glyphs
+ local indices={}
+ local descriptions={}
+ local names=usenames and {}
+ local resources=fontdata.resources
+ local zero=glyphs[0]
+ local zerocode=zero.unicode
+ if not zerocode then
+ zerocode=private
+ zero.unicode=zerocode
+ private=private+1
+ end
+ descriptions[zerocode]=zero
+ if names then
+ local name=glyphs[0].name or f_private(zerocode)
+ indices[0]=name
+ names[name]=zerocode
+ else
+ indices[0]=zerocode
+ end
+ if names then
+ for index=1,#glyphs do
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ private=private+1
+ elseif unicode>=firstprivate then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ private=private+1
+ elseif unicode>=puafirst and unicode<=pualast then
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ elseif descriptions[unicode] then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ private=private+1
+ else
+ local name=glyph.name or f_unicode(unicode)
+ indices[index]=name
+ names[name]=unicode
+ end
+ descriptions[unicode]=glyph
+ end
+ elseif trace_unicodes then
+ for index=1,#glyphs do
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=firstprivate then
+ local name=glyph.name
+ if name then
+ report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private)
+ else
+ report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private)
+ end
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=puafirst and unicode<=pualast then
+ local name=glyph.name
+ if name then
+ report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index)
+ else
+ report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index)
+ end
+ indices[index]=unicode
+ elseif descriptions[unicode] then
+ local name=glyph.name
+ if name then
+ report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index)
+ else
+ report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index)
+ end
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ else
+ indices[index]=unicode
+ end
+ descriptions[unicode]=glyph
+ end
+ else
+ for index=1,#glyphs do
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=firstprivate then
+ local name=glyph.name
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=puafirst and unicode<=pualast then
+ local name=glyph.name
+ indices[index]=unicode
+ elseif descriptions[unicode] then
+ local name=glyph.name
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ else
+ indices[index]=unicode
+ end
+ descriptions[unicode]=glyph
+ end
+ end
+ for index=1,#glyphs do
+ local math=glyphs[index].math
+ if math then
+ local list=math.vparts
+ if list then
+ for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
+ end
+ local list=math.hparts
+ if list then
+ for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
+ end
+ local list=math.vvariants
+ if list then
+ for i=1,#list do list[i]=indices[list[i]] end
+ end
+ local list=math.hvariants
+ if list then
+ for i=1,#list do list[i]=indices[list[i]] end
+ end
+ end
+ end
+ local colorpalettes=resources.colorpalettes
+ if colorpalettes then
+ for index=1,#glyphs do
+ local colors=glyphs[index].colors
+ if colors then
+ for i=1,#colors do
+ local c=colors[i]
+ c.slot=indices[c.slot]
+ end
+ end
+ end
+ end
+ fontdata.private=private
+ fontdata.glyphs=nil
+ fontdata.names=names
+ fontdata.descriptions=descriptions
+ fontdata.hashmethod=hashmethod
+ return indices,names
+end
+local p_crappyname do
+ local p_hex=R("af","AF","09")
+ local p_digit=R("09")
+ local p_done=S("._-")^0+P(-1)
+ local p_alpha=R("az","AZ")
+ local p_ALPHA=R("AZ")
+ p_crappyname=(
+ lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1
++lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1
++lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1
++p_digit*p_hex^3+p_alpha*p_digit^1
++P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1
+ )*p_done
+end
+local forcekeep=false
+directives.register("otf.keepnames",function(v)
+ report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
+ forcekeep=v
+end)
+local function stripredundant(fontdata)
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ local n=0
+ local c=0
+ if (not context and fonts.privateoffsets.keepnames) or forcekeep then
+ for unicode,d in next,descriptions do
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ else
+ for unicode,d in next,descriptions do
+ local name=d.name
+ if name and lpegmatch(p_crappyname,name) then
+ d.name=nil
+ n=n+1
+ end
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ end
+ if trace_cleanup then
+ if n>0 then
+ report_cleanup("%s bogus names removed (verbose unicode)",n)
+ end
+ if c>0 then
+ report_cleanup("%s base class tags removed (default is base)",c)
+ end
+ end
+ end
+end
+readers.stripredundant=stripredundant
+function readers.getcomponents(fontdata)
+ local resources=fontdata.resources
+ if resources then
+ local sequences=resources.sequences
+ if sequences then
+ local collected={}
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ if sequence.type=="gsub_ligature" then
+ local steps=sequence.steps
+ if steps then
+ local l={}
+ local function traverse(p,k,v)
+ if k=="ligature" then
+ collected[v]={ unpack(l) }
+ else
+ insert(l,k)
+ for k,vv in next,v do
+ traverse(p,k,vv)
+ end
+ remove(l)
+ end
+ end
+ for i=1,#steps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ traverse(k,k,v)
+ end
+ end
+ end
+ end
+ end
+ end
+ if next(collected) then
+ while true do
+ local done=false
+ for k,v in next,collected do
+ for i=1,#v do
+ local vi=v[i]
+ if vi==k then
+ collected[k]=nil
+ break
+ else
+ local c=collected[vi]
+ if c then
+ done=true
+ local t={}
+ local n=i-1
+ for j=1,n do
+ t[j]=v[j]
+ end
+ for j=1,#c do
+ n=n+1
+ t[n]=c[j]
+ end
+ for j=i+1,#v do
+ n=n+1
+ t[n]=v[j]
+ end
+ collected[k]=t
+ break
+ end
+ end
+ end
+ end
+ if not done then
+ break
+ end
+ end
+ return collected
+ end
+ end
+ end
+end
+readers.unifymissing=unifymissing
+function readers.rehash(fontdata,hashmethod)
+ if not (fontdata and fontdata.glyphs) then
+ return
+ end
+ if hashmethod=="indices" then
+ fontdata.hashmethod="indices"
+ elseif hashmethod=="names" then
+ fontdata.hashmethod="names"
+ local indices=unifyglyphs(fontdata,true)
+ unifyresources(fontdata,indices)
+ copyduplicates(fontdata)
+ unifymissing(fontdata)
+ else
+ fontdata.hashmethod="unicodes"
+ local indices=unifyglyphs(fontdata)
+ unifyresources(fontdata,indices)
+ copyduplicates(fontdata)
+ unifymissing(fontdata)
+ stripredundant(fontdata)
+ end
+end
+function readers.checkhash(fontdata)
+ local hashmethod=fontdata.hashmethod
+ if hashmethod=="unicodes" then
+ fontdata.names=nil
+ elseif hashmethod=="names" and fontdata.names then
+ unifyresources(fontdata,fontdata.names)
+ copyduplicates(fontdata)
+ fontdata.hashmethod="unicodes"
+ fontdata.names=nil
+ else
+ readers.rehash(fontdata,"unicodes")
+ end
+end
+function readers.addunicodetable(fontdata)
+ local resources=fontdata.resources
+ local unicodes=resources.unicodes
+ if not unicodes then
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ unicodes={}
+ resources.unicodes=unicodes
+ for u,d in next,descriptions do
+ local n=d.name
+ if n then
+ unicodes[n]=u
+ end
+ end
+ end
+ end
+end
+local concat,sort=table.concat,table.sort
+local next,type,tostring=next,type,tostring
+local criterium=1
+local threshold=0
+local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end)
+local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
+local report_otf=logs.reporter("fonts","otf loading")
+local function tabstr_normal(t)
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k..">"..tabstr_normal(v)
+ elseif v==true then
+ s[n]=k.."+"
+ elseif v then
+ s[n]=k.."="..v
+ else
+ s[n]=k.."-"
+ end
+ end
+ if n==0 then
+ return ""
+ elseif n==1 then
+ return s[1]
+ else
+ sort(s)
+ return concat(s,",")
+ end
+end
+local function tabstr_flat(t)
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ s[n]=k.."="..v
+ end
+ if n==0 then
+ return ""
+ elseif n==1 then
+ return s[1]
+ else
+ sort(s)
+ return concat(s,",")
+ end
+end
+local function tabstr_mixed(t)
+ local s={}
+ local n=#t
+ if n==0 then
+ return ""
+ elseif n==1 then
+ local k=t[1]
+ if k==true then
+ return "++"
+ elseif k==false then
+ return "--"
+ else
+ return tostring(k)
+ end
+ else
+ for i=1,n do
+ local k=t[i]
+ if k==true then
+ s[i]="++"
+ elseif k==false then
+ s[i]="--"
+ else
+ s[i]=k
+ end
+ end
+ return concat(s,",")
+ end
+end
+local function tabstr_boolean(t)
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ if v then
+ s[n]=k.."+"
+ else
+ s[n]=k.."-"
+ end
+ end
+ if n==0 then
+ return ""
+ elseif n==1 then
+ return s[1]
+ else
+ sort(s)
+ return concat(s,",")
+ end
+end
+function readers.pack(data)
+ if data then
+ local h,t,c={},{},{}
+ local hh,tt,cc={},{},{}
+ local nt,ntt=0,0
+ local function pack_normal(v)
+ local tag=tabstr_normal(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_normal_cc(v)
+ local tag=tabstr_normal(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ v[1]=0
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_flat(v)
+ local tag=tabstr_flat(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_indexed(v)
+ local tag=concat(v," ")
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_mixed(v)
+ local tag=tabstr_mixed(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_boolean(v)
+ local tag=tabstr_boolean(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_final(v)
+ if c[v]<=criterium then
+ return t[v]
+ else
+ local hv=hh[v]
+ if hv then
+ return hv
+ else
+ ntt=ntt+1
+ tt[ntt]=t[v]
+ hh[v]=ntt
+ cc[ntt]=c[v]
+ return ntt
+ end
+ end
+ end
+ local function pack_final_cc(v)
+ if c[v]<=criterium then
+ return t[v]
+ else
+ local hv=hh[v]
+ if hv then
+ return hv
+ else
+ ntt=ntt+1
+ tt[ntt]=t[v]
+ hh[v]=ntt
+ cc[ntt]=c[v]
+ return ntt
+ end
+ end
+ end
+ local function success(stage,pass)
+ if nt==0 then
+ if trace_loading or trace_packing then
+ report_otf("pack quality: nothing to pack")
+ end
+ return false
+ elseif nt>=threshold then
+ local one=0
+ local two=0
+ local rest=0
+ if pass==1 then
+ for k,v in next,c do
+ if v==1 then
+ one=one+1
+ elseif v==2 then
+ two=two+1
+ else
+ rest=rest+1
+ end
+ end
+ else
+ for k,v in next,cc do
+ if v>20 then
+ rest=rest+1
+ elseif v>10 then
+ two=two+1
+ else
+ one=one+1
+ end
+ end
+ data.tables=tt
+ end
+ if trace_loading or trace_packing then
+ report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)",
+ stage,pass,one+two+rest,one,two,rest,criterium)
+ end
+ return true
+ else
+ if trace_loading or trace_packing then
+ report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)",
+ stage,pass,nt,threshold)
+ end
+ return false
+ end
+ end
+ local function packers(pass)
+ if pass==1 then
+ return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc
+ else
+ return pack_final,pack_final,pack_final,pack_final,pack_final,pack_final_cc
+ end
+ end
+ local resources=data.resources
+ local sequences=resources.sequences
+ local sublookups=resources.sublookups
+ local features=resources.features
+ local palettes=resources.colorpalettes
+ local variable=resources.variabledata
+ local chardata=characters and characters.data
+ local descriptions=data.descriptions or data.glyphs
+ if not descriptions then
+ return
+ end
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 1, pass %s",pass)
+ end
+ local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
+ for unicode,description in next,descriptions do
+ local boundingbox=description.boundingbox
+ if boundingbox then
+ description.boundingbox=pack_indexed(boundingbox)
+ end
+ local math=description.math
+ if math then
+ local kerns=math.kerns
+ if kerns then
+ for tag,kern in next,kerns do
+ kerns[tag]=pack_normal(kern)
+ end
+ end
+ end
+ end
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local order=sequence.order
+ local features=sequence.features
+ local flags=sequence.flags
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format~="pair" then
+ for g1,d1 in next,c do
+ c[g1]=pack_normal(d1)
+ end
+ elseif step.shared then
+ local shared={}
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ if not shared[d2] then
+ local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end
+ local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end
+ shared[d2]=true
+ end
+ end
+ end
+ if pass==2 then
+ step.shared=nil
+ end
+ else
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end
+ local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end
+ end
+ end
+ end
+ end
+ elseif kind=="gpos_single" then
+ local c=step.coverage
+ if c then
+ if step.format=="single" then
+ for g1,d1 in next,c do
+ if d1 and d1~=true then
+ c[g1]=pack_indexed(d1)
+ end
+ end
+ else
+ step.coverage=pack_normal(c)
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local f=d1[2] if f then d1[2]=pack_indexed(f) end
+ local s=d1[3] if s then d1[3]=pack_indexed(s) end
+ end
+ end
+ elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ d1[g2]=pack_indexed(d2)
+ end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ d1[2]=pack_indexed(d1[2])
+ end
+ end
+ elseif kind=="gpos_mark2ligature" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ for g3,d3 in next,d2 do
+ d2[g3]=pack_indexed(d3)
+ end
+ end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ d1[2]=pack_indexed(d1[2])
+ end
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ 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.replacements if r then rule.replacements=pack_flat (r) end
+ end
+ end
+ end
+ end
+ if order then
+ sequence.order=pack_indexed(order)
+ end
+ if features then
+ for script,feature in next,features do
+ features[script]=pack_normal(feature)
+ end
+ end
+ if flags then
+ sequence.flags=pack_normal(flags)
+ end
+ end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+ if features then
+ for k,list in next,features do
+ for feature,spec in next,list do
+ list[feature]=pack_normal(spec)
+ end
+ end
+ end
+ if palettes then
+ for i=1,#palettes do
+ local p=palettes[i]
+ for j=1,#p do
+ p[j]=pack_indexed(p[j])
+ end
+ end
+ end
+ if variable then
+ local instances=variable.instances
+ if instances then
+ for i=1,#instances do
+ local v=instances[i].values
+ for j=1,#v do
+ v[j]=pack_normal(v[j])
+ end
+ end
+ end
+ local function packdeltas(main)
+ if main then
+ local deltas=main.deltas
+ if deltas then
+ for i=1,#deltas do
+ local di=deltas[i]
+ local d=di.deltas
+ for j=1,#d do
+ d[j]=pack_indexed(d[j])
+ end
+ di.regions=pack_indexed(di.regions)
+ end
+ end
+ local regions=main.regions
+ if regions then
+ for i=1,#regions do
+ local r=regions[i]
+ for j=1,#r do
+ r[j]=pack_normal(r[j])
+ end
+ end
+ end
+ end
+ end
+ packdeltas(variable.global)
+ packdeltas(variable.horizontal)
+ packdeltas(variable.vertical)
+ packdeltas(variable.metrics)
+ end
+ if not success(1,pass) then
+ return
+ end
+ end
+ if nt>0 then
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 2, pass %s",pass)
+ end
+ local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
+ for unicode,description in next,descriptions do
+ local math=description.math
+ if math then
+ local kerns=math.kerns
+ if kerns then
+ math.kerns=pack_normal(kerns)
+ end
+ end
+ end
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local features=sequence.features
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ d1[g2]=pack_normal(d2)
+ end
+ end
+ end
+ end
+ elseif kind=="gpos_mark2ligature" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ d1[g2]=pack_normal(d2)
+ end
+ end
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local r=rule.before if r then rule.before=pack_normal(r) end
+ local r=rule.after if r then rule.after=pack_normal(r) end
+ local r=rule.current if r then rule.current=pack_normal(r) end
+ end
+ end
+ end
+ end
+ if features then
+ sequence.features=pack_normal(features)
+ end
+ end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+ if variable then
+ local function unpackdeltas(main)
+ if main then
+ local regions=main.regions
+ if regions then
+ main.regions=pack_normal(regions)
+ end
+ end
+ end
+ unpackdeltas(variable.global)
+ unpackdeltas(variable.horizontal)
+ unpackdeltas(variable.vertical)
+ unpackdeltas(variable.metrics)
+ end
+ end
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 3, pass %s",pass)
+ end
+ local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local features=sequence.features
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ c[g1]=pack_normal(d1)
+ end
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ c[g1]=pack_normal_cc(d1)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+ end
+ end
+ end
+end
+local unpacked_mt={
+ __index=function(t,k)
+ t[k]=false
+ return k
+ end
+}
+function readers.unpack(data)
+ if data then
+ local tables=data.tables
+ if tables then
+ local resources=data.resources
+ local descriptions=data.descriptions or data.glyphs
+ local sequences=resources.sequences
+ local sublookups=resources.sublookups
+ local features=resources.features
+ local palettes=resources.colorpalettes
+ local variable=resources.variabledata
+ local unpacked={}
+ setmetatable(unpacked,unpacked_mt)
+ for unicode,description in next,descriptions do
+ local tv=tables[description.boundingbox]
+ if tv then
+ description.boundingbox=tv
+ end
+ local math=description.math
+ if math then
+ local kerns=math.kerns
+ if kerns then
+ local tm=tables[kerns]
+ if tm then
+ math.kerns=tm
+ kerns=unpacked[tm]
+ end
+ if kerns then
+ for k,kern in next,kerns do
+ local tv=tables[kern]
+ if tv then
+ kerns[k]=tv
+ end
+ end
+ end
+ end
+ end
+ end
+ local function unpackthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local order=sequence.order
+ local features=sequence.features
+ local flags=sequence.flags
+ local markclass=sequence.markclass
+ if features then
+ local tv=tables[features]
+ if tv then
+ sequence.features=tv
+ features=tv
+ end
+ for script,feature in next,features do
+ local tv=tables[feature]
+ if tv then
+ features[script]=tv
+ end
+ end
+ end
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ d1=tv
+ end
+ for g2,d2 in next,d1 do
+ local tv=tables[d2]
+ if tv then
+ d1[g2]=tv
+ d2=tv
+ end
+ local f=tables[d2[1]] if f then d2[1]=f end
+ local s=tables[d2[2]] if s then d2[2]=s end
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ end
+ end
+ end
+ end
+ elseif kind=="gpos_single" then
+ local c=step.coverage
+ if c then
+ if step.format=="single" then
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ end
+ end
+ else
+ local tv=tables[c]
+ if tv then
+ step.coverage=tv
+ end
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ d1=tv
+ c[g1]=d1
+ end
+ local f=tables[d1[2]] if f then d1[2]=f end
+ local s=tables[d1[3]] if s then d1[3]=s end
+ end
+ end
+ elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ local tv=tables[d2]
+ if tv then
+ d1[g2]=tv
+ end
+ end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local tv=tables[d1[2]]
+ if tv then
+ d1[2]=tv
+ end
+ end
+ end
+ elseif kind=="gpos_mark2ligature" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ local tv=tables[d2]
+ if tv then
+ d2=tv
+ d1[g2]=d2
+ end
+ for g3,d3 in next,d2 do
+ local tv=tables[d2[g3]]
+ if tv then
+ d2[g3]=tv
+ end
+ end
+ end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local tv=tables[d1[2]]
+ if tv then
+ d1[2]=tv
+ end
+ end
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local before=rule.before
+ if before then
+ local tv=tables[before]
+ if tv then
+ rule.before=tv
+ before=tv
+ end
+ for i=1,#before do
+ local tv=tables[before[i]]
+ if tv then
+ before[i]=tv
+ end
+ end
+ end
+ local after=rule.after
+ if after then
+ local tv=tables[after]
+ if tv then
+ rule.after=tv
+ after=tv
+ end
+ for i=1,#after do
+ local tv=tables[after[i]]
+ if tv then
+ after[i]=tv
+ end
+ end
+ end
+ local current=rule.current
+ if current then
+ local tv=tables[current]
+ if tv then
+ rule.current=tv
+ current=tv
+ end
+ for i=1,#current do
+ local tv=tables[current[i]]
+ if tv then
+ current[i]=tv
+ end
+ end
+ end
+ local replacements=rule.replacements
+ if replacements then
+ local tv=tables[replacements]
+ if tv then
+ rule.replacements=tv
+ end
+ end
+ end
+ end
+ end
+ end
+ if order then
+ local tv=tables[order]
+ if tv then
+ sequence.order=tv
+ end
+ end
+ if flags then
+ local tv=tables[flags]
+ if tv then
+ sequence.flags=tv
+ end
+ end
+ end
+ end
+ if sequences then
+ unpackthem(sequences)
+ end
+ if sublookups then
+ unpackthem(sublookups)
+ end
+ if features then
+ for k,list in next,features do
+ for feature,spec in next,list do
+ local tv=tables[spec]
+ if tv then
+ list[feature]=tv
+ end
+ end
+ end
+ end
+ if palettes then
+ for i=1,#palettes do
+ local p=palettes[i]
+ for j=1,#p do
+ local tv=tables[p[j]]
+ if tv then
+ p[j]=tv
+ end
+ end
+ end
+ end
+ if variable then
+ local instances=variable.instances
+ if instances then
+ for i=1,#instances do
+ local v=instances[i].values
+ for j=1,#v do
+ local tv=tables[v[j]]
+ if tv then
+ v[j]=tv
+ end
+ end
+ end
+ end
+ local function unpackdeltas(main)
+ if main then
+ local deltas=main.deltas
+ if deltas then
+ for i=1,#deltas do
+ local di=deltas[i]
+ local d=di.deltas
+ local r=di.regions
+ for j=1,#d do
+ local tv=tables[d[j]]
+ if tv then
+ d[j]=tv
+ end
+ end
+ local tv=di.regions
+ if tv then
+ di.regions=tv
+ end
+ end
+ end
+ local regions=main.regions
+ if regions then
+ local tv=tables[regions]
+ if tv then
+ main.regions=tv
+ regions=tv
+ end
+ for i=1,#regions do
+ local r=regions[i]
+ for j=1,#r do
+ local tv=tables[r[j]]
+ if tv then
+ r[j]=tv
+ end
+ end
+ end
+ end
+ end
+ end
+ unpackdeltas(variable.global)
+ unpackdeltas(variable.horizontal)
+ unpackdeltas(variable.vertical)
+ unpackdeltas(variable.metrics)
+ end
+ data.tables=nil
+ end
+ end
+end
+local mt={
+ __index=function(t,k)
+ if k=="height" then
+ local ht=t.boundingbox[4]
+ return ht<0 and 0 or ht
+ elseif k=="depth" then
+ local dp=-t.boundingbox[2]
+ return dp<0 and 0 or dp
+ elseif k=="width" then
+ return 0
+ elseif k=="name" then
+ return forcenotdef and ".notdef"
+ end
+ end
+}
+local function sameformat(sequence,steps,first,nofsteps,kind)
+ return true
+end
+local function mergesteps_1(lookup,strict)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if strict then
+ local f=first.format
+ for i=2,nofsteps do
+ if steps[i].format~=f then
+ if trace_optimizations then
+ report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
+ end
+ return 0
+ end
+ end
+ end
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ if not target[k] then
+ target[k]=v
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function mergesteps_2(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if strict then
+ local f=first.format
+ for i=2,nofsteps do
+ if steps[i].format~=f then
+ if trace_optimizations then
+ report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
+ end
+ return 0
+ end
+ end
+ end
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=target[k]
+ if tk then
+ for kk,vv in next,v do
+ if tk[kk]==nil then
+ tk[kk]=vv
+ end
+ end
+ else
+ target[k]=v
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function mergesteps_3(lookup,strict)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local coverage={}
+ for i=1,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=coverage[k]
+ if tk then
+ if trace_optimizations then
+ report_optimizations("quitting merge due to multiple checks")
+ end
+ return nofsteps
+ else
+ coverage[k]=v
+ end
+ end
+ end
+ end
+ local first=steps[1]
+ local baseclasses={}
+ for i=1,nofsteps do
+ local offset=i*10
+ local step=steps[i]
+ for k,v in sortedhash(step.baseclasses) do
+ baseclasses[offset+k]=v
+ end
+ for k,v in next,step.coverage do
+ v[1]=offset+v[1]
+ end
+ end
+ first.baseclasses=baseclasses
+ first.coverage=coverage
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function nested(old,new)
+ for k,v in next,old do
+ if k=="ligature" then
+ if not new.ligature then
+ new.ligature=v
+ end
+ else
+ local n=new[k]
+ if n then
+ nested(v,n)
+ else
+ new[k]=v
+ end
+ end
+ end
+end
+local function mergesteps_4(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=target[k]
+ if tk then
+ nested(v,tk)
+ else
+ target[k]=v
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function mergesteps_5(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ local hash=nil
+ for k,v in next,target do
+ hash=v[1]
+ break
+ end
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=target[k]
+ if tk then
+ if not tk[2] then
+ tk[2]=v[2]
+ end
+ if not tk[3] then
+ tk[3]=v[3]
+ end
+ else
+ target[k]=v
+ v[1]=hash
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function checkkerns(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local kerned=0
+ for i=1,nofsteps do
+ local step=steps[i]
+ if step.format=="pair" then
+ local coverage=step.coverage
+ local kerns=true
+ for g1,d1 in next,coverage do
+ if d1==true then
+ elseif not d1 then
+ elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then
+ kerns=false
+ break
+ end
+ end
+ if kerns then
+ if trace_optimizations then
+ report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
+ end
+ local c={}
+ for g1,d1 in next,coverage do
+ if d1 and d1~=true then
+ c[g1]=d1[3]
+ end
+ end
+ step.coverage=c
+ step.format="move"
+ kerned=kerned+1
+ end
+ end
+ end
+ return kerned
+end
+local function checkpairs(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local kerned=0
+ local function onlykerns(step)
+ local coverage=step.coverage
+ for g1,d1 in next,coverage do
+ for g2,d2 in next,d1 do
+ if d2[2] then
+ return false
+ else
+ local v=d2[1]
+ if v==true then
+ elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then
+ return false
+ end
+ end
+ end
+ end
+ return coverage
+ end
+ for i=1,nofsteps do
+ local step=steps[i]
+ if step.format=="pair" then
+ local coverage=onlykerns(step)
+ if coverage then
+ if trace_optimizations then
+ report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
+ end
+ for g1,d1 in next,coverage do
+ local d={}
+ for g2,d2 in next,d1 do
+ local v=d2[1]
+ if v==true then
+ elseif v then
+ d[g2]=v[3]
+ end
+ end
+ coverage[g1]=d
+ end
+ step.format="move"
+ kerned=kerned+1
+ end
+ end
+ end
+ return kerned
+end
+local compact_pairs=true
+local compact_singles=true
+local merge_pairs=true
+local merge_singles=true
+local merge_substitutions=true
+local merge_alternates=true
+local merge_multiples=true
+local merge_ligatures=true
+local merge_cursives=true
+local merge_marks=true
+directives.register("otf.compact.pairs",function(v) compact_pairs=v end)
+directives.register("otf.compact.singles",function(v) compact_singles=v end)
+directives.register("otf.merge.pairs",function(v) merge_pairs=v end)
+directives.register("otf.merge.singles",function(v) merge_singles=v end)
+directives.register("otf.merge.substitutions",function(v) merge_substitutions=v end)
+directives.register("otf.merge.alternates",function(v) merge_alternates=v end)
+directives.register("otf.merge.multiples",function(v) merge_multiples=v end)
+directives.register("otf.merge.ligatures",function(v) merge_ligatures=v end)
+directives.register("otf.merge.cursives",function(v) merge_cursives=v end)
+directives.register("otf.merge.marks",function(v) merge_marks=v end)
+function readers.compact(data)
+ if not data or data.compacted then
+ return
+ else
+ data.compacted=true
+ end
+ local resources=data.resources
+ local merged=0
+ local kerned=0
+ local allsteps=0
+ local function compact(what)
+ local lookups=resources[what]
+ if lookups then
+ for i=1,#lookups do
+ local lookup=lookups[i]
+ local nofsteps=lookup.nofsteps
+ local kind=lookup.type
+ allsteps=allsteps+nofsteps
+ if nofsteps>1 then
+ local merg=merged
+ if kind=="gsub_single" then
+ if merge_substitutions then
+ merged=merged+mergesteps_1(lookup)
+ end
+ elseif kind=="gsub_alternate" then
+ if merge_alternates then
+ merged=merged+mergesteps_1(lookup)
+ end
+ elseif kind=="gsub_multiple" then
+ if merge_multiples then
+ merged=merged+mergesteps_1(lookup)
+ end
+ elseif kind=="gsub_ligature" then
+ if merge_ligatures then
+ merged=merged+mergesteps_4(lookup)
+ end
+ elseif kind=="gpos_single" then
+ if merge_singles then
+ merged=merged+mergesteps_1(lookup,true)
+ end
+ if compact_singles then
+ kerned=kerned+checkkerns(lookup)
+ end
+ elseif kind=="gpos_pair" then
+ if merge_pairs then
+ merged=merged+mergesteps_2(lookup)
+ end
+ if compact_pairs then
+ kerned=kerned+checkpairs(lookup)
+ end
+ elseif kind=="gpos_cursive" then
+ if merge_cursives then
+ merged=merged+mergesteps_5(lookup)
+ end
+ elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then
+ if merge_marks then
+ merged=merged+mergesteps_3(lookup)
+ end
+ end
+ if merg~=merged then
+ lookup.merged=true
+ end
+ elseif nofsteps==1 then
+ local kern=kerned
+ if kind=="gpos_single" then
+ if compact_singles then
+ kerned=kerned+checkkerns(lookup)
+ end
+ elseif kind=="gpos_pair" then
+ if compact_pairs then
+ kerned=kerned+checkpairs(lookup)
+ end
+ end
+ if kern~=kerned then
+ end
+ end
+ end
+ elseif trace_optimizations then
+ report_optimizations("no lookups in %a",what)
+ end
+ end
+ compact("sequences")
+ compact("sublookups")
+ if trace_optimizations then
+ if merged>0 then
+ report_optimizations("%i steps of %i removed due to merging",merged,allsteps)
+ end
+ if kerned>0 then
+ report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps)
+ end
+ end
+end
+local function mergesteps(t,k)
+ if k=="merged" then
+ local merged={}
+ for i=1,#t do
+ local step=t[i]
+ local coverage=step.coverage
+ for k in next,coverage do
+ local m=merged[k]
+ if m then
+ m[2]=i
+ else
+ merged[k]={ i,i }
+ end
+ end
+ end
+ t.merged=merged
+ return merged
+ end
+end
+local function checkmerge(sequence)
+ local steps=sequence.steps
+ if steps then
+ setmetatableindex(steps,mergesteps)
+ end
+end
+local function checkflags(sequence,resources)
+ if not sequence.skiphash then
+ local flags=sequence.flags
+ if flags then
+ local skipmark=flags[1]
+ local skipligature=flags[2]
+ local skipbase=flags[3]
+ local markclass=sequence.markclass
+ local skipsome=skipmark or skipligature or skipbase or markclass or false
+ if skipsome then
+ sequence.skiphash=setmetatableindex(function(t,k)
+ local c=resources.classes[k]
+ local v=c==skipmark
+ or (markclass and c=="mark" and not markclass[k])
+ or c==skipligature
+ or c==skipbase
+ or false
+ t[k]=v
+ return v
+ end)
+ else
+ sequence.skiphash=false
+ end
+ else
+ sequence.skiphash=false
+ end
+ end
+end
+local function checksteps(sequence)
+ local steps=sequence.steps
+ if steps then
+ for i=1,#steps do
+ steps[i].index=i
+ end
+ end
+end
+if fonts.helpers then
+ fonts.helpers.checkmerge=checkmerge
+ fonts.helpers.checkflags=checkflags
+ fonts.helpers.checksteps=checksteps
+end
+function readers.expand(data)
+ if not data or data.expanded then
+ return
+ else
+ data.expanded=true
+ end
+ local resources=data.resources
+ local sublookups=resources.sublookups
+ local sequences=resources.sequences
+ local markclasses=resources.markclasses
+ local descriptions=data.descriptions
+ if descriptions then
+ local defaultwidth=resources.defaultwidth or 0
+ local defaultheight=resources.defaultheight or 0
+ local defaultdepth=resources.defaultdepth or 0
+ local basename=trace_markwidth and file.basename(resources.filename)
+ for u,d in next,descriptions do
+ local bb=d.boundingbox
+ local wd=d.width
+ if not wd then
+ d.width=defaultwidth
+ elseif trace_markwidth and wd~=0 and d.class=="mark" then
+ report_markwidth("mark %a with width %b found in %a",d.name or "<noname>",wd,basename)
+ end
+ if bb then
+ local ht=bb[4]
+ local dp=-bb[2]
+ if ht==0 or ht<0 then
+ else
+ d.height=ht
+ end
+ if dp==0 or dp<0 then
+ else
+ d.depth=dp
+ end
+ end
+ end
+ end
+ local function expandlookups(sequences)
+ if sequences then
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ if steps then
+ local nofsteps=sequence.nofsteps
+ local kind=sequence.type
+ local markclass=sequence.markclass
+ if markclass then
+ if not markclasses then
+ report_warning("missing markclasses")
+ sequence.markclass=false
+ else
+ sequence.markclass=markclasses[markclass]
+ end
+ end
+ for i=1,nofsteps do
+ local step=steps[i]
+ local baseclasses=step.baseclasses
+ if baseclasses then
+ local coverage=step.coverage
+ for k,v in next,coverage do
+ v[1]=baseclasses[v[1]]
+ end
+ elseif kind=="gpos_cursive" then
+ local coverage=step.coverage
+ for k,v in next,coverage do
+ v[1]=coverage
+ end
+ end
+ local rules=step.rules
+ if rules then
+ local rulehash={ n=0 }
+ local rulesize=0
+ local coverage={}
+ local lookuptype=sequence.type
+ local nofrules=#rules
+ step.coverage=coverage
+ for currentrule=1,nofrules do
+ local rule=rules[currentrule]
+ local current=rule.current
+ local before=rule.before
+ local after=rule.after
+ local replacements=rule.replacements or false
+ local sequence={}
+ local nofsequences=0
+ if before then
+ for n=1,#before do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=before[n]
+ end
+ end
+ local start=nofsequences+1
+ for n=1,#current do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=current[n]
+ end
+ local stop=nofsequences
+ if after then
+ for n=1,#after do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=after[n]
+ end
+ end
+ local lookups=rule.lookups or false
+ local subtype=nil
+ if lookups then
+ 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
+ end
+ end
+ end
+ if sequence[1] then
+ sequence.n=#sequence
+ local ruledata={
+ currentrule,
+ lookuptype,
+ sequence,
+ start,
+ stop,
+ lookups,
+ replacements,
+ subtype,
+ }
+ rulesize=rulesize+1
+ rulehash[rulesize]=ruledata
+ rulehash.n=rulesize
+ if true then
+ for unic in next,sequence[start] do
+ local cu=coverage[unic]
+ if cu then
+ local n=#cu+1
+ cu[n]=ruledata
+ cu.n=n
+ else
+ coverage[unic]={ ruledata,n=1 }
+ end
+ end
+ else
+ for unic in next,sequence[start] do
+ local cu=coverage[unic]
+ if cu then
+ else
+ coverage[unic]=rulehash
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ checkmerge(sequence)
+ checkflags(sequence,resources)
+ checksteps(sequence)
+ end
+ end
+ end
+ end
+ expandlookups(sequences)
+ expandlookups(sublookups)
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oupâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otl†940f9c5ad84f4968a8488f4da2d15e2d] ---
+
+if not modules then modules={} end modules ['font-otl']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
+}
+local lower=string.lower
+local type,next,tonumber,tostring,unpack=type,next,tonumber,tostring,unpack
+local abs=math.abs
+local derivetable=table.derive
+local formatters=string.formatters
+local setmetatableindex=table.setmetatableindex
+local allocate=utilities.storage.allocate
+local registertracker=trackers.register
+local registerdirective=directives.register
+local starttiming=statistics.starttiming
+local stoptiming=statistics.stoptiming
+local elapsedtime=statistics.elapsedtime
+local findbinfile=resolvers.findbinfile
+local trace_loading=false registertracker("otf.loading",function(v) trace_loading=v end)
+local trace_features=false registertracker("otf.features",function(v) trace_features=v end)
+local trace_defining=false registertracker("fonts.defining",function(v) trace_defining=v end)
+local report_otf=logs.reporter("fonts","otf loading")
+local fonts=fonts
+local otf=fonts.handlers.otf
+otf.version=3.109
+otf.cache=containers.define("fonts","otl",otf.version,true)
+otf.svgcache=containers.define("fonts","svg",otf.version,true)
+otf.pngcache=containers.define("fonts","png",otf.version,true)
+otf.pdfcache=containers.define("fonts","pdf",otf.version,true)
+otf.svgenabled=false
+otf.pngenabled=false
+local otfreaders=otf.readers
+local hashes=fonts.hashes
+local definers=fonts.definers
+local readers=fonts.readers
+local constructors=fonts.constructors
+local otffeatures=constructors.features.otf
+local registerotffeature=otffeatures.register
+local otfenhancers=constructors.enhancers.otf
+local registerotfenhancer=otfenhancers.register
+local forceload=false
+local cleanup=0
+local syncspace=true
+local forcenotdef=false
+local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes
+local wildcard="*"
+local default="dflt"
+local formats=fonts.formats
+formats.otf="opentype"
+formats.ttf="truetype"
+formats.ttc="truetype"
+registerdirective("fonts.otf.loader.cleanup",function(v) cleanup=tonumber(v) or (v and 1) or 0 end)
+registerdirective("fonts.otf.loader.force",function(v) forceload=v end)
+registerdirective("fonts.otf.loader.syncspace",function(v) syncspace=v end)
+registerdirective("fonts.otf.loader.forcenotdef",function(v) forcenotdef=v end)
+registerotfenhancer("check extra features",function() end)
+local checkmemory=utilities.lua and utilities.lua.checkmemory
+local threshold=100
+local tracememory=false
+registertracker("fonts.otf.loader.memory",function(v) tracememory=v end)
+if not checkmemory then
+ local collectgarbage=collectgarbage
+ checkmemory=function(previous,threshold)
+ local current=collectgarbage("count")
+ if previous then
+ local checked=(threshold or 64)*1024
+ if current-previous>checked then
+ collectgarbage("collect")
+ current=collectgarbage("count")
+ end
+ end
+ return current
+ end
+end
+function otf.load(filename,sub,instance)
+ local base=file.basename(file.removesuffix(filename))
+ local name=file.removesuffix(base)
+ local attr=lfs.attributes(filename)
+ local size=attr and attr.size or 0
+ local time=attr and attr.modification or 0
+ if sub=="" then
+ sub=false
+ end
+ local hash=name
+ if sub then
+ hash=hash.."-"..sub
+ end
+ if instance then
+ hash=hash.."-"..instance
+ end
+ hash=containers.cleanname(hash)
+ local data=containers.read(otf.cache,hash)
+ local reload=not data or data.size~=size or data.time~=time or data.tableversion~=otfreaders.tableversion
+ if forceload then
+ report_otf("forced reload of %a due to hard coded flag",filename)
+ reload=true
+ end
+ if reload then
+ report_otf("loading %a, hash %a",filename,hash)
+ starttiming(otfreaders,true)
+ data=otfreaders.loadfont(filename,sub or 1,instance)
+ if data then
+ local used=checkmemory()
+ local resources=data.resources
+ local svgshapes=resources.svgshapes
+ local pngshapes=resources.pngshapes
+ if cleanup==0 then
+ checkmemory(used,threshold,tracememory)
+ end
+ if svgshapes then
+ resources.svgshapes=nil
+ if otf.svgenabled then
+ local timestamp=os.date()
+ containers.write(otf.svgcache,hash,{
+ svgshapes=svgshapes,
+ timestamp=timestamp,
+ })
+ data.properties.svg={
+ hash=hash,
+ timestamp=timestamp,
+ }
+ end
+ if cleanup>1 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ end
+ if pngshapes then
+ resources.pngshapes=nil
+ if otf.pngenabled then
+ local timestamp=os.date()
+ containers.write(otf.pngcache,hash,{
+ pngshapes=pngshapes,
+ timestamp=timestamp,
+ })
+ data.properties.png={
+ hash=hash,
+ timestamp=timestamp,
+ }
+ end
+ if cleanup>1 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ end
+ otfreaders.compact(data)
+ if cleanup==0 then
+ checkmemory(used,threshold,tracememory)
+ end
+ otfreaders.rehash(data,"unicodes")
+ otfreaders.addunicodetable(data)
+ otfreaders.extend(data)
+ if cleanup==0 then
+ checkmemory(used,threshold,tracememory)
+ end
+ otfreaders.pack(data)
+ report_otf("loading done")
+ report_otf("saving %a in cache",filename)
+ data=containers.write(otf.cache,hash,data)
+ if cleanup>1 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ stoptiming(otfreaders)
+ if elapsedtime then
+ report_otf("loading, optimizing, packing and caching time %s",elapsedtime(otfreaders))
+ end
+ if cleanup>3 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ data=containers.read(otf.cache,hash)
+ if cleanup>2 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ else
+ stoptiming(otfreaders)
+ data=nil
+ report_otf("loading failed due to read error")
+ end
+ end
+ if data then
+ if trace_defining then
+ report_otf("loading from cache using hash %a",hash)
+ end
+ otfreaders.unpack(data)
+ otfreaders.expand(data)
+ otfreaders.addunicodetable(data)
+ otfenhancers.apply(data,filename,data)
+ if applyruntimefixes then
+ applyruntimefixes(filename,data)
+ end
+ data.metadata.math=data.resources.mathconstants
+ local classes=data.resources.classes
+ if not classes then
+ local descriptions=data.descriptions
+ classes=setmetatableindex(function(t,k)
+ local d=descriptions[k]
+ local v=(d and d.class or "base") or false
+ t[k]=v
+ return v
+ end)
+ data.resources.classes=classes
+ end
+ end
+ return data
+end
+function otf.setfeatures(tfmdata,features)
+ local okay=constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf)
+ if okay then
+ return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf)
+ else
+ return {}
+ end
+end
+local function copytotfm(data,cache_id)
+ if data then
+ local metadata=data.metadata
+ local properties=derivetable(data.properties)
+ local descriptions=derivetable(data.descriptions)
+ local goodies=derivetable(data.goodies)
+ local characters={}
+ local parameters={}
+ local mathparameters={}
+ local resources=data.resources
+ local unicodes=resources.unicodes
+ local spaceunits=500
+ local spacer="space"
+ local designsize=metadata.designsize or 100
+ local minsize=metadata.minsize or designsize
+ local maxsize=metadata.maxsize or designsize
+ local mathspecs=metadata.math
+ if designsize==0 then
+ designsize=100
+ minsize=100
+ maxsize=100
+ end
+ if mathspecs then
+ for name,value in next,mathspecs do
+ mathparameters[name]=value
+ end
+ end
+ for unicode in next,data.descriptions do
+ characters[unicode]={}
+ end
+ if mathspecs then
+ for unicode,character in next,characters do
+ local d=descriptions[unicode]
+ local m=d.math
+ if m then
+ local italic=m.italic
+ local vitalic=m.vitalic
+ local variants=m.hvariants
+ local parts=m.hparts
+ if variants then
+ local c=character
+ for i=1,#variants do
+ local un=variants[i]
+ c.next=un
+ c=characters[un]
+ end
+ c.horiz_variants=parts
+ elseif parts then
+ character.horiz_variants=parts
+ italic=m.hitalic
+ end
+ local variants=m.vvariants
+ local parts=m.vparts
+ if variants then
+ local c=character
+ for i=1,#variants do
+ local un=variants[i]
+ c.next=un
+ c=characters[un]
+ end
+ c.vert_variants=parts
+ elseif parts then
+ character.vert_variants=parts
+ end
+ if italic and italic~=0 then
+ character.italic=italic
+ end
+ if vitalic and vitalic~=0 then
+ character.vert_italic=vitalic
+ end
+ local accent=m.accent
+ if accent then
+ character.accent=accent
+ end
+ local kerns=m.kerns
+ if kerns then
+ character.mathkerns=kerns
+ end
+ end
+ end
+ end
+ local filename=constructors.checkedfilename(resources)
+ local fontname=metadata.fontname
+ local fullname=metadata.fullname or fontname
+ local psname=fontname or fullname
+ local subfont=metadata.subfontindex
+ local units=metadata.units or 1000
+ if units==0 then
+ units=1000
+ metadata.units=1000
+ report_otf("changing %a units to %a",0,units)
+ end
+ local monospaced=metadata.monospaced
+ local charwidth=metadata.averagewidth
+ local charxheight=metadata.xheight
+ local italicangle=metadata.italicangle
+ local hasitalics=metadata.hasitalics
+ properties.monospaced=monospaced
+ properties.hasitalics=hasitalics
+ parameters.italicangle=italicangle
+ parameters.charwidth=charwidth
+ parameters.charxheight=charxheight
+ local space=0x0020
+ local emdash=0x2014
+ if monospaced then
+ if descriptions[space] then
+ spaceunits,spacer=descriptions[space].width,"space"
+ end
+ if not spaceunits and descriptions[emdash] then
+ spaceunits,spacer=descriptions[emdash].width,"emdash"
+ end
+ if not spaceunits and charwidth then
+ spaceunits,spacer=charwidth,"charwidth"
+ end
+ else
+ if descriptions[space] then
+ spaceunits,spacer=descriptions[space].width,"space"
+ end
+ if not spaceunits and descriptions[emdash] then
+ spaceunits,spacer=descriptions[emdash].width/2,"emdash/2"
+ end
+ if not spaceunits and charwidth then
+ spaceunits,spacer=charwidth,"charwidth"
+ end
+ end
+ spaceunits=tonumber(spaceunits) or units/2
+ parameters.slant=0
+ parameters.space=spaceunits
+ parameters.space_stretch=1*units/2
+ parameters.space_shrink=1*units/3
+ parameters.x_height=2*units/5
+ parameters.quad=units
+ if spaceunits<2*units/5 then
+ end
+ if italicangle and italicangle~=0 then
+ parameters.italicangle=italicangle
+ parameters.italicfactor=math.cos(math.rad(90+italicangle))
+ parameters.slant=- math.tan(italicangle*math.pi/180)
+ end
+ if monospaced then
+ parameters.space_stretch=0
+ parameters.space_shrink=0
+ elseif syncspace then
+ parameters.space_stretch=spaceunits/2
+ parameters.space_shrink=spaceunits/3
+ end
+ parameters.extra_space=parameters.space_shrink
+ if charxheight then
+ parameters.x_height=charxheight
+ else
+ local x=0x0078
+ if x then
+ local x=descriptions[x]
+ if x then
+ parameters.x_height=x.height
+ end
+ end
+ end
+ parameters.designsize=(designsize/10)*65536
+ parameters.minsize=(minsize/10)*65536
+ parameters.maxsize=(maxsize/10)*65536
+ parameters.ascender=abs(metadata.ascender or 0)
+ parameters.descender=abs(metadata.descender or 0)
+ parameters.units=units
+ parameters.vheight=metadata.defaultvheight
+ properties.space=spacer
+ properties.encodingbytes=2
+ properties.format=data.format or formats.otf
+ properties.filename=filename
+ properties.fontname=fontname
+ properties.fullname=fullname
+ properties.psname=psname
+ properties.name=filename or fullname
+ properties.subfont=subfont
+ properties.private=properties.private or data.private or privateoffset
+ return {
+ characters=characters,
+ descriptions=descriptions,
+ parameters=parameters,
+ mathparameters=mathparameters,
+ resources=resources,
+ properties=properties,
+ goodies=goodies,
+ }
+ end
+end
+local converters={
+ woff={
+ cachename="webfonts",
+ action=otf.readers.woff2otf,
+ }
+}
+local function checkconversion(specification)
+ local filename=specification.filename
+ local converter=converters[lower(file.suffix(filename))]
+ if converter then
+ local base=file.basename(filename)
+ local name=file.removesuffix(base)
+ local attr=lfs.attributes(filename)
+ local size=attr and attr.size or 0
+ local time=attr and attr.modification or 0
+ if size>0 then
+ local cleanname=containers.cleanname(name)
+ local cachename=caches.setfirstwritablefile(cleanname,converter.cachename)
+ if not io.exists(cachename) or (time~=lfs.attributes(cachename).modification) then
+ report_otf("caching font %a in %a",filename,cachename)
+ converter.action(filename,cachename)
+ lfs.touch(cachename,time,time)
+ end
+ specification.filename=cachename
+ end
+ end
+end
+local function otftotfm(specification)
+ local cache_id=specification.hash
+ local tfmdata=containers.read(constructors.cache,cache_id)
+ if not tfmdata then
+ checkconversion(specification)
+ local name=specification.name
+ local sub=specification.sub
+ local subindex=specification.subindex
+ local filename=specification.filename
+ local features=specification.features.normal
+ local instance=specification.instance or (features and features.axis)
+ local rawdata=otf.load(filename,sub,instance)
+ if rawdata and next(rawdata) then
+ local descriptions=rawdata.descriptions
+ rawdata.lookuphash={}
+ tfmdata=copytotfm(rawdata,cache_id)
+ if tfmdata and next(tfmdata) then
+ local features=constructors.checkedfeatures("otf",features)
+ local shared=tfmdata.shared
+ if not shared then
+ shared={}
+ tfmdata.shared=shared
+ end
+ shared.rawdata=rawdata
+ shared.dynamics={}
+ tfmdata.changed={}
+ shared.features=features
+ shared.processes=otf.setfeatures(tfmdata,features)
+ end
+ end
+ containers.write(constructors.cache,cache_id,tfmdata)
+ end
+ return tfmdata
+end
+local function read_from_otf(specification)
+ local tfmdata=otftotfm(specification)
+ if tfmdata then
+ tfmdata.properties.name=specification.name
+ tfmdata.properties.sub=specification.sub
+ tfmdata=constructors.scale(tfmdata,specification)
+ local allfeatures=tfmdata.shared.features or specification.features.normal
+ constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf)
+ constructors.setname(tfmdata,specification)
+ fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification)
+ end
+ return tfmdata
+end
+local function checkmathsize(tfmdata,mathsize)
+ local mathdata=tfmdata.shared.rawdata.metadata.math
+ local mathsize=tonumber(mathsize)
+ if mathdata then
+ local parameters=tfmdata.parameters
+ parameters.scriptpercentage=mathdata.ScriptPercentScaleDown
+ parameters.scriptscriptpercentage=mathdata.ScriptScriptPercentScaleDown
+ parameters.mathsize=mathsize
+ end
+end
+registerotffeature {
+ name="mathsize",
+ description="apply mathsize specified in the font",
+ initializers={
+ base=checkmathsize,
+ node=checkmathsize,
+ }
+}
+function otf.collectlookups(rawdata,kind,script,language)
+ if not kind then
+ return
+ end
+ if not script then
+ script=default
+ end
+ if not language then
+ language=default
+ end
+ local lookupcache=rawdata.lookupcache
+ if not lookupcache then
+ lookupcache={}
+ rawdata.lookupcache=lookupcache
+ end
+ local kindlookup=lookupcache[kind]
+ if not kindlookup then
+ kindlookup={}
+ lookupcache[kind]=kindlookup
+ end
+ local scriptlookup=kindlookup[script]
+ if not scriptlookup then
+ scriptlookup={}
+ kindlookup[script]=scriptlookup
+ end
+ local languagelookup=scriptlookup[language]
+ if not languagelookup then
+ local sequences=rawdata.resources.sequences
+ local featuremap={}
+ local featurelist={}
+ if sequences then
+ for s=1,#sequences do
+ local sequence=sequences[s]
+ local features=sequence.features
+ if features then
+ features=features[kind]
+ if features then
+ features=features[script] or features[wildcard]
+ if features then
+ features=features[language] or features[wildcard]
+ if features then
+ if not featuremap[sequence] then
+ featuremap[sequence]=true
+ featurelist[#featurelist+1]=sequence
+ end
+ end
+ end
+ end
+ end
+ end
+ if #featurelist==0 then
+ featuremap,featurelist=false,false
+ end
+ else
+ featuremap,featurelist=false,false
+ end
+ languagelookup={ featuremap,featurelist }
+ scriptlookup[language]=languagelookup
+ end
+ return unpack(languagelookup)
+end
+local function getgsub(tfmdata,k,kind,value)
+ local shared=tfmdata.shared
+ local rawdata=shared and shared.rawdata
+ if rawdata then
+ local sequences=rawdata.resources.sequences
+ if sequences then
+ local properties=tfmdata.properties
+ local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language)
+ if validlookups then
+ for i=1,#lookuplist do
+ local lookup=lookuplist[i]
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ for i=1,nofsteps do
+ local coverage=steps[i].coverage
+ if coverage then
+ local found=coverage[k]
+ if found then
+ return found,lookup.type
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+otf.getgsub=getgsub
+function otf.getsubstitution(tfmdata,k,kind,value)
+ local found,kind=getgsub(tfmdata,k,kind,value)
+ if not found then
+ elseif kind=="gsub_single" then
+ return found
+ elseif kind=="gsub_alternate" then
+ local choice=tonumber(value) or 1
+ return found[choice] or found[1] or k
+ end
+ return k
+end
+otf.getalternate=otf.getsubstitution
+function otf.getmultiple(tfmdata,k,kind)
+ local found,kind=getgsub(tfmdata,k,kind)
+ if found and kind=="gsub_multiple" then
+ return found
+ end
+ return { k }
+end
+function otf.getkern(tfmdata,left,right,kind)
+ local kerns=getgsub(tfmdata,left,kind or "kern",true)
+ if kerns then
+ local found=kerns[right]
+ local kind=type(found)
+ if kind=="table" then
+ found=found[1][3]
+ elseif kind~="number" then
+ found=false
+ end
+ if found then
+ return found*tfmdata.parameters.factor
+ end
+ end
+ return 0
+end
+local function check_otf(forced,specification,suffix)
+ local name=specification.name
+ if forced then
+ name=specification.forcedname
+ end
+ local fullname=findbinfile(name,suffix) or ""
+ if fullname=="" then
+ fullname=fonts.names.getfilename(name,suffix) or ""
+ end
+ if fullname~="" and not fonts.names.ignoredfile(fullname) then
+ specification.filename=fullname
+ return read_from_otf(specification)
+ end
+end
+local function opentypereader(specification,suffix)
+ local forced=specification.forced or ""
+ if formats[forced] then
+ return check_otf(true,specification,forced)
+ else
+ return check_otf(false,specification,suffix)
+ end
+end
+readers.opentype=opentypereader
+function readers.otf(specification) return opentypereader(specification,"otf") end
+function readers.ttf(specification) return opentypereader(specification,"ttf") end
+function readers.ttc(specification) return opentypereader(specification,"ttf") end
+function readers.woff(specification)
+ checkconversion(specification)
+ opentypereader(specification,"")
+end
+function otf.scriptandlanguage(tfmdata,attr)
+ local properties=tfmdata.properties
+ return properties.script or "dflt",properties.language or "dflt"
+end
+local function justset(coverage,unicode,replacement)
+ coverage[unicode]=replacement
+end
+otf.coverup={
+ stepkey="steps",
+ actions={
+ chainsubstitution=justset,
+ chainposition=justset,
+ substitution=justset,
+ alternate=justset,
+ multiple=justset,
+ kern=justset,
+ pair=justset,
+ single=justset,
+ ligature=function(coverage,unicode,ligature)
+ local first=ligature[1]
+ local tree=coverage[first]
+ if not tree then
+ tree={}
+ coverage[first]=tree
+ end
+ for i=2,#ligature do
+ local l=ligature[i]
+ local t=tree[l]
+ if not t then
+ t={}
+ tree[l]=t
+ end
+ tree=t
+ end
+ tree.ligature=unicode
+ end,
+ },
+ register=function(coverage,featuretype,format)
+ return {
+ format=format,
+ coverage=coverage,
+ }
+ end
+}
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otlâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oto†52804afd96f4be005f513a012b874668] ---
+
+if not modules then modules={} end modules ['font-oto']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local concat,unpack=table.concat,table.unpack
+local insert,remove=table.insert,table.remove
+local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip
+local type,next,tonumber,tostring,rawget=type,next,tonumber,tostring,rawget
+local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end)
+local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end)
+local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end)
+local trace_alternatives=false trackers.register("otf.alternatives",function(v) trace_alternatives=v end)
+local trace_ligatures=false trackers.register("otf.ligatures",function(v) trace_ligatures=v end)
+local trace_kerns=false trackers.register("otf.kerns",function(v) trace_kerns=v end)
+local trace_preparing=false trackers.register("otf.preparing",function(v) trace_preparing=v end)
+local report_prepare=logs.reporter("fonts","otf prepare")
+local fonts=fonts
+local otf=fonts.handlers.otf
+local otffeatures=otf.features
+local registerotffeature=otffeatures.register
+otf.defaultbasealternate="none"
+local getprivate=fonts.constructors.getprivate
+local wildcard="*"
+local default="dflt"
+local formatters=string.formatters
+local f_unicode=formatters["%U"]
+local f_uniname=formatters["%U (%s)"]
+local f_unilist=formatters["% t (% t)"]
+local function gref(descriptions,n)
+ if type(n)=="number" then
+ local name=descriptions[n].name
+ if name then
+ return f_uniname(n,name)
+ else
+ return f_unicode(n)
+ end
+ elseif n then
+ local num={}
+ local nam={}
+ local j=0
+ for i=1,#n do
+ local ni=n[i]
+ if tonumber(ni) then
+ j=j+1
+ local di=descriptions[ni]
+ num[j]=f_unicode(ni)
+ nam[j]=di and di.name or "-"
+ end
+ end
+ return f_unilist(num,nam)
+ else
+ return "<error in base mode tracing>"
+ end
+end
+local function cref(feature,sequence)
+ return formatters["feature %a, type %a, chain lookup %a"](feature,sequence.type,sequence.name)
+end
+local function report_substitution(feature,sequence,descriptions,unicode,substitution)
+ if unicode==substitution then
+ report_prepare("%s: base substitution %s maps onto itself",
+ cref(feature,sequence),
+ gref(descriptions,unicode))
+ else
+ report_prepare("%s: base substitution %s => %S",
+ cref(feature,sequence),
+ gref(descriptions,unicode),
+ gref(descriptions,substitution))
+ end
+end
+local function report_alternate(feature,sequence,descriptions,unicode,replacement,value,comment)
+ if unicode==replacement then
+ report_prepare("%s: base alternate %s maps onto itself",
+ cref(feature,sequence),
+ gref(descriptions,unicode))
+ else
+ report_prepare("%s: base alternate %s => %s (%S => %S)",
+ cref(feature,sequence),
+ gref(descriptions,unicode),
+ replacement and gref(descriptions,replacement),
+ value,
+ comment)
+ end
+end
+local function report_ligature(feature,sequence,descriptions,unicode,ligature)
+ report_prepare("%s: base ligature %s => %S",
+ cref(feature,sequence),
+ gref(descriptions,ligature),
+ gref(descriptions,unicode))
+end
+local function report_kern(feature,sequence,descriptions,unicode,otherunicode,value)
+ report_prepare("%s: base kern %s + %s => %S",
+ cref(feature,sequence),
+ gref(descriptions,unicode),
+ gref(descriptions,otherunicode),
+ value)
+end
+local basehash,basehashes,applied={},1,{}
+local function registerbasehash(tfmdata)
+ local properties=tfmdata.properties
+ local hash=concat(applied," ")
+ local base=basehash[hash]
+ if not base then
+ basehashes=basehashes+1
+ base=basehashes
+ basehash[hash]=base
+ end
+ properties.basehash=base
+ properties.fullname=(properties.fullname or properties.name).."-"..base
+ applied={}
+end
+local function registerbasefeature(feature,value)
+ applied[#applied+1]=feature.."="..tostring(value)
+end
+local function makefake(tfmdata,name,present)
+ local private=getprivate(tfmdata)
+ local character={ intermediate=true,ligatures={} }
+ resources.unicodes[name]=private
+ tfmdata.characters[private]=character
+ tfmdata.descriptions[private]={ name=name }
+ present[name]=private
+ return character
+end
+local function make_1(present,tree,name)
+ for k,v in next,tree do
+ if k=="ligature" then
+ present[name]=v
+ else
+ make_1(present,v,name.."_"..k)
+ end
+ end
+end
+local function make_2(present,tfmdata,characters,tree,name,preceding,unicode,done)
+ for k,v in next,tree do
+ if k=="ligature" then
+ local character=characters[preceding]
+ if not character then
+ if trace_baseinit then
+ report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding)
+ end
+ character=makefake(tfmdata,name,present)
+ end
+ local ligatures=character.ligatures
+ if ligatures then
+ ligatures[unicode]={ char=v }
+ else
+ character.ligatures={ [unicode]={ char=v } }
+ end
+ if done then
+ local d=done[name]
+ if not d then
+ done[name]={ "dummy",v }
+ else
+ d[#d+1]=v
+ end
+ end
+ else
+ local code=present[name] or unicode
+ local name=name.."_"..k
+ make_2(present,tfmdata,characters,v,name,code,k,done)
+ end
+ end
+end
+local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist)
+ local characters=tfmdata.characters
+ local descriptions=tfmdata.descriptions
+ local resources=tfmdata.resources
+ local changed=tfmdata.changed
+ local ligatures={}
+ local alternate=tonumber(value) or true and 1
+ local defaultalt=otf.defaultbasealternate
+ local trace_singles=trace_baseinit and trace_singles
+ local trace_alternatives=trace_baseinit and trace_alternatives
+ local trace_ligatures=trace_baseinit and trace_ligatures
+ if not changed then
+ changed={}
+ tfmdata.changed=changed
+ end
+ for i=1,#lookuplist do
+ local sequence=lookuplist[i]
+ local steps=sequence.steps
+ local kind=sequence.type
+ if kind=="gsub_single" then
+ for i=1,#steps do
+ for unicode,data in next,steps[i].coverage do
+ if unicode~=data then
+ changed[unicode]=data
+ end
+ if trace_singles then
+ report_substitution(feature,sequence,descriptions,unicode,data)
+ end
+ end
+ end
+ elseif kind=="gsub_alternate" then
+ for i=1,#steps do
+ for unicode,data in next,steps[i].coverage do
+ local replacement=data[alternate]
+ if replacement then
+ if unicode~=replacement then
+ changed[unicode]=replacement
+ end
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal")
+ end
+ elseif defaultalt=="first" then
+ replacement=data[1]
+ if unicode~=replacement then
+ changed[unicode]=replacement
+ end
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
+ end
+ elseif defaultalt=="last" then
+ replacement=data[#data]
+ if unicode~=replacement then
+ changed[unicode]=replacement
+ end
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
+ end
+ else
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,"unknown")
+ end
+ end
+ end
+ end
+ elseif kind=="gsub_ligature" then
+ for i=1,#steps do
+ for unicode,data in next,steps[i].coverage do
+ ligatures[#ligatures+1]={ unicode,data,"" }
+ if trace_ligatures then
+ report_ligature(feature,sequence,descriptions,unicode,data)
+ end
+ end
+ end
+ end
+ end
+ local nofligatures=#ligatures
+ if nofligatures>0 then
+ local characters=tfmdata.characters
+ local present={}
+ local done=trace_baseinit and trace_ligatures and {}
+ for i=1,nofligatures do
+ local ligature=ligatures[i]
+ local unicode=ligature[1]
+ local tree=ligature[2]
+ make_1(present,tree,"ctx_"..unicode)
+ end
+ for i=1,nofligatures do
+ local ligature=ligatures[i]
+ local unicode=ligature[1]
+ local tree=ligature[2]
+ local lookupname=ligature[3]
+ make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence)
+ end
+ end
+end
+local function preparepositionings(tfmdata,feature,value,validlookups,lookuplist)
+ local characters=tfmdata.characters
+ local descriptions=tfmdata.descriptions
+ local resources=tfmdata.resources
+ local properties=tfmdata.properties
+ local traceindeed=trace_baseinit and trace_kerns
+ for i=1,#lookuplist do
+ local sequence=lookuplist[i]
+ local steps=sequence.steps
+ local kind=sequence.type
+ local format=sequence.format
+ if kind=="gpos_pair" then
+ for i=1,#steps do
+ local step=steps[i]
+ local format=step.format
+ if format=="kern" or format=="move" then
+ for unicode,data in next,steps[i].coverage do
+ local character=characters[unicode]
+ local kerns=character.kerns
+ if not kerns then
+ kerns={}
+ character.kerns=kerns
+ end
+ if traceindeed then
+ for otherunicode,kern in next,data do
+ if not kerns[otherunicode] and kern~=0 then
+ kerns[otherunicode]=kern
+ report_kern(feature,sequence,descriptions,unicode,otherunicode,kern)
+ end
+ end
+ else
+ for otherunicode,kern in next,data do
+ if not kerns[otherunicode] and kern~=0 then
+ kerns[otherunicode]=kern
+ end
+ end
+ end
+ end
+ else
+ for unicode,data in next,steps[i].coverage do
+ local character=characters[unicode]
+ local kerns=character.kerns
+ for otherunicode,kern in next,data do
+ local other=kern[2]
+ if other==true or (not other and not (kerns and kerns[otherunicode])) then
+ local kern=kern[1]
+ if kern==true then
+ elseif kern[1]~=0 or kern[2]~=0 or kern[4]~=0 then
+ else
+ kern=kern[3]
+ if kern~=0 then
+ if kerns then
+ kerns[otherunicode]=kern
+ else
+ kerns={ [otherunicode]=kern }
+ character.kerns=kerns
+ end
+ if traceindeed then
+ report_kern(feature,sequence,descriptions,unicode,otherunicode,kern)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+local function initializehashes(tfmdata)
+end
+local function checkmathreplacements(tfmdata,fullname,fixitalics)
+ if tfmdata.mathparameters then
+ local characters=tfmdata.characters
+ local changed=tfmdata.changed
+ if next(changed) then
+ if trace_preparing or trace_baseinit then
+ report_prepare("checking math replacements for %a",fullname)
+ end
+ for unicode,replacement in next,changed do
+ local u=characters[unicode]
+ local r=characters[replacement]
+ if u and r then
+ local n=u.next
+ local v=u.vert_variants
+ local h=u.horiz_variants
+ if fixitalics then
+ local ui=u.italic
+ if ui and not r.italic then
+ if trace_preparing then
+ report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement)
+ end
+ r.italic=ui
+ end
+ end
+ if n and not r.next then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement)
+ end
+ r.next=n
+ end
+ if v and not r.vert_variants then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement)
+ end
+ r.vert_variants=v
+ end
+ if h and not r.horiz_variants then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement)
+ end
+ r.horiz_variants=h
+ end
+ else
+ if trace_preparing then
+ report_prepare("error replacing %C by %U",unicode,replacement)
+ end
+ end
+ end
+ end
+ end
+end
+local function featuresinitializer(tfmdata,value)
+ if true then
+ local starttime=trace_preparing and os.clock()
+ local features=tfmdata.shared.features
+ local fullname=tfmdata.properties.fullname or "?"
+ if features then
+ initializehashes(tfmdata)
+ local collectlookups=otf.collectlookups
+ local rawdata=tfmdata.shared.rawdata
+ local properties=tfmdata.properties
+ local script=properties.script
+ local language=properties.language
+ local rawresources=rawdata.resources
+ local rawfeatures=rawresources and rawresources.features
+ local basesubstitutions=rawfeatures and rawfeatures.gsub
+ local basepositionings=rawfeatures and rawfeatures.gpos
+ local substitutionsdone=false
+ local positioningsdone=false
+ if basesubstitutions or basepositionings then
+ local sequences=tfmdata.resources.sequences
+ for s=1,#sequences do
+ local sequence=sequences[s]
+ local sfeatures=sequence.features
+ if sfeatures then
+ local order=sequence.order
+ if order then
+ for i=1,#order do
+ local feature=order[i]
+ local value=features[feature]
+ if value then
+ local validlookups,lookuplist=collectlookups(rawdata,feature,script,language)
+ if not validlookups then
+ elseif basesubstitutions and basesubstitutions[feature] then
+ if trace_preparing then
+ report_prepare("filtering base %s feature %a for %a with value %a","sub",feature,fullname,value)
+ end
+ preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist)
+ registerbasefeature(feature,value)
+ substitutionsdone=true
+ elseif basepositionings and basepositionings[feature] then
+ if trace_preparing then
+ report_prepare("filtering base %a feature %a for %a with value %a","pos",feature,fullname,value)
+ end
+ preparepositionings(tfmdata,feature,value,validlookups,lookuplist)
+ registerbasefeature(feature,value)
+ positioningsdone=true
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if substitutionsdone then
+ checkmathreplacements(tfmdata,fullname,features.fixitalics)
+ end
+ registerbasehash(tfmdata)
+ end
+ if trace_preparing then
+ report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname)
+ end
+ end
+end
+registerotffeature {
+ name="features",
+ description="features",
+ default=true,
+ initializers={
+ base=featuresinitializer,
+ }
+}
+otf.basemodeinitializer=featuresinitializer
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otoâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otj†66c7a910d95d4a52b81061de776898e1] ---
+
+if not modules then modules={} end modules ['font-otj']={
+ version=1.001,
+ comment="companion to font-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
+}
+if not nodes.properties then return end
+local next,rawget,tonumber=next,rawget,tonumber
+local fastcopy=table.fastcopy
+local registertracker=trackers.register
+local registerdirective=directives.register
+local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end)
+local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end)
+local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end)
+local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end)
+local report_injections=logs.reporter("fonts","injections")
+local report_spaces=logs.reporter("fonts","spaces")
+local attributes,nodes,node=attributes,nodes,node
+fonts=fonts
+local hashes=fonts.hashes
+local fontdata=hashes.identifiers
+local fontmarks=hashes.marks
+nodes.injections=nodes.injections or {}
+local injections=nodes.injections
+local tracers=nodes.tracers
+local setcolor=tracers and tracers.colors.set
+local resetcolor=tracers and tracers.colors.reset
+local nodecodes=nodes.nodecodes
+local glyph_code=nodecodes.glyph
+local disc_code=nodecodes.disc
+local kern_code=nodecodes.kern
+local glue_code=nodecodes.glue
+local nuts=nodes.nuts
+local nodepool=nuts.pool
+local tonode=nuts.tonode
+local tonut=nuts.tonut
+local setfield=nuts.setfield
+local getnext=nuts.getnext
+local getprev=nuts.getprev
+local getid=nuts.getid
+local getfont=nuts.getfont
+local getchar=nuts.getchar
+local getoffsets=nuts.getoffsets
+local getboth=nuts.getboth
+local getdisc=nuts.getdisc
+local setdisc=nuts.setdisc
+local setoffsets=nuts.setoffsets
+local ischar=nuts.ischar
+local getkern=nuts.getkern
+local setkern=nuts.setkern
+local setlink=nuts.setlink
+local setwidth=nuts.setwidth
+local getwidth=nuts.getwidth
+local nextchar=nuts.traversers.char
+local nextglue=nuts.traversers.glue
+local insert_node_before=nuts.insert_before
+local insert_node_after=nuts.insert_after
+local properties=nodes.properties.data
+local fontkern=nuts.pool and nuts.pool.fontkern
+local italickern=nuts.pool and nuts.pool.italickern
+local useitalickerns=false
+directives.register("fonts.injections.useitalics",function(v)
+ if v then
+ report_injections("using italics for space kerns (tracing only)")
+ end
+ useitalickerns=v
+end)
+do if not fontkern then
+ local thekern=nuts.new("kern",0)
+ local setkern=nuts.setkern
+ local copy_node=nuts.copy_node
+ fontkern=function(k)
+ local n=copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
+end end
+do if not italickern then
+ local thekern=nuts.new("kern",3)
+ local setkern=nuts.setkern
+ local copy_node=nuts.copy_node
+ italickern=function(k)
+ local n=copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
+end end
+function injections.installnewkern() end
+local nofregisteredkerns=0
+local nofregisteredpositions=0
+local nofregisteredmarks=0
+local nofregisteredcursives=0
+local keepregisteredcounts=false
+function injections.keepcounts()
+ keepregisteredcounts=true
+end
+function injections.resetcounts()
+ nofregisteredkerns=0
+ nofregisteredpositions=0
+ nofregisteredmarks=0
+ nofregisteredcursives=0
+ keepregisteredcounts=false
+end
+function injections.reset(n)
+ local p=rawget(properties,n)
+ if p then
+ p.injections=false
+ else
+ properties[n]=false
+ end
+end
+function injections.copy(target,source)
+ local sp=rawget(properties,source)
+ if sp then
+ local tp=rawget(properties,target)
+ local si=sp.injections
+ if si then
+ si=fastcopy(si)
+ if tp then
+ tp.injections=si
+ else
+ properties[target]={
+ injections=si,
+ }
+ end
+ elseif tp then
+ tp.injections=false
+ else
+ properties[target]={ injections={} }
+ end
+ else
+ local tp=rawget(properties,target)
+ if tp then
+ tp.injections=false
+ else
+ properties[target]=false
+ end
+ end
+end
+function injections.setligaindex(n,index)
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections
+ if i then
+ i.ligaindex=index
+ else
+ p.injections={
+ ligaindex=index
+ }
+ end
+ else
+ properties[n]={
+ injections={
+ ligaindex=index
+ }
+ }
+ end
+end
+function injections.getligaindex(n,default)
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections
+ if i then
+ return i.ligaindex or default
+ end
+ end
+ return default
+end
+function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext,r2lflag)
+ local dx=factor*(exit[1]-entry[1])
+ local dy=-factor*(exit[2]-entry[2])
+ local ws=tfmstart.width
+ local wn=tfmnext.width
+ nofregisteredcursives=nofregisteredcursives+1
+ if rlmode<0 then
+ dx=-(dx+wn)
+ else
+ dx=dx-ws
+ end
+ if dx==0 then
+ dx=0
+ end
+ local p=rawget(properties,start)
+ if p then
+ local i=p.injections
+ if i then
+ i.cursiveanchor=true
+ else
+ p.injections={
+ cursiveanchor=true,
+ }
+ end
+ else
+ properties[start]={
+ injections={
+ cursiveanchor=true,
+ },
+ }
+ end
+ local p=rawget(properties,nxt)
+ if p then
+ local i=p.injections
+ if i then
+ i.cursivex=dx
+ i.cursivey=dy
+ else
+ p.injections={
+ cursivex=dx,
+ cursivey=dy,
+ }
+ end
+ else
+ properties[nxt]={
+ injections={
+ cursivex=dx,
+ cursivey=dy,
+ },
+ }
+ end
+ return dx,dy,nofregisteredcursives
+end
+function injections.setposition(kind,current,factor,rlmode,spec,injection)
+ local x=factor*(spec[1] or 0)
+ local y=factor*(spec[2] or 0)
+ local w=factor*(spec[3] or 0)
+ local h=factor*(spec[4] or 0)
+ if x~=0 or w~=0 or y~=0 or h~=0 then
+ local yoffset=y-h
+ local leftkern=x
+ local rightkern=w-x
+ if leftkern~=0 or rightkern~=0 or yoffset~=0 then
+ nofregisteredpositions=nofregisteredpositions+1
+ if rlmode and rlmode<0 then
+ leftkern,rightkern=rightkern,leftkern
+ end
+ if not injection then
+ injection="injections"
+ end
+ local p=rawget(properties,current)
+ if p then
+ local i=p[injection]
+ if i then
+ if leftkern~=0 then
+ i.leftkern=(i.leftkern or 0)+leftkern
+ end
+ if rightkern~=0 then
+ i.rightkern=(i.rightkern or 0)+rightkern
+ end
+ if yoffset~=0 then
+ i.yoffset=(i.yoffset or 0)+yoffset
+ end
+ elseif leftkern~=0 or rightkern~=0 then
+ p[injection]={
+ leftkern=leftkern,
+ rightkern=rightkern,
+ yoffset=yoffset,
+ }
+ else
+ p[injection]={
+ yoffset=yoffset,
+ }
+ end
+ elseif leftkern~=0 or rightkern~=0 then
+ properties[current]={
+ [injection]={
+ leftkern=leftkern,
+ rightkern=rightkern,
+ yoffset=yoffset,
+ },
+ }
+ else
+ properties[current]={
+ [injection]={
+ yoffset=yoffset,
+ },
+ }
+ end
+ return x,y,w,h,nofregisteredpositions
+ end
+ end
+ return x,y,w,h
+end
+function injections.setkern(current,factor,rlmode,x,injection)
+ local dx=factor*x
+ if dx~=0 then
+ nofregisteredkerns=nofregisteredkerns+1
+ local p=rawget(properties,current)
+ if not injection then
+ injection="injections"
+ end
+ if p then
+ local i=p[injection]
+ if i then
+ i.leftkern=dx+(i.leftkern or 0)
+ else
+ p[injection]={
+ leftkern=dx,
+ }
+ end
+ else
+ properties[current]={
+ [injection]={
+ leftkern=dx,
+ },
+ }
+ end
+ return dx,nofregisteredkerns
+ else
+ return 0,0
+ end
+end
+function injections.setmove(current,factor,rlmode,x,injection)
+ local dx=factor*x
+ if dx~=0 then
+ nofregisteredkerns=nofregisteredkerns+1
+ local p=rawget(properties,current)
+ if not injection then
+ injection="injections"
+ end
+ if rlmode and rlmode<0 then
+ if p then
+ local i=p[injection]
+ if i then
+ i.rightkern=dx+(i.rightkern or 0)
+ else
+ p[injection]={
+ rightkern=dx,
+ }
+ end
+ else
+ properties[current]={
+ [injection]={
+ rightkern=dx,
+ },
+ }
+ end
+ else
+ if p then
+ local i=p[injection]
+ if i then
+ i.leftkern=dx+(i.leftkern or 0)
+ else
+ p[injection]={
+ leftkern=dx,
+ }
+ end
+ else
+ properties[current]={
+ [injection]={
+ leftkern=dx,
+ },
+ }
+ end
+ end
+ return dx,nofregisteredkerns
+ else
+ return 0,0
+ end
+end
+function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark)
+ local dx=factor*(ba[1]-ma[1])
+ local dy=factor*(ba[2]-ma[2])
+ nofregisteredmarks=nofregisteredmarks+1
+ if rlmode>=0 then
+ dx=tfmbase.width-dx
+ end
+ local p=rawget(properties,start)
+ if p then
+ local i=p.injections
+ if i then
+ if i.markmark then
+ else
+ i.markx=dx
+ i.marky=dy
+ i.markdir=rlmode or 0
+ i.markbase=nofregisteredmarks
+ i.markbasenode=base
+ i.markmark=mkmk
+ i.checkmark=checkmark
+ end
+ else
+ p.injections={
+ markx=dx,
+ marky=dy,
+ markdir=rlmode or 0,
+ markbase=nofregisteredmarks,
+ markbasenode=base,
+ markmark=mkmk,
+ checkmark=checkmark,
+ }
+ end
+ else
+ properties[start]={
+ injections={
+ markx=dx,
+ marky=dy,
+ markdir=rlmode or 0,
+ markbase=nofregisteredmarks,
+ markbasenode=base,
+ markmark=mkmk,
+ checkmark=checkmark,
+ },
+ }
+ end
+ return dx,dy,nofregisteredmarks
+end
+local function dir(n)
+ return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset"
+end
+local function showchar(n,nested)
+ local char=getchar(n)
+ report_injections("%wfont %s, char %U, glyph %c",nested and 2 or 0,getfont(n),char,char)
+end
+local function show(n,what,nested,symbol)
+ if n then
+ local p=rawget(properties,n)
+ if p then
+ local i=p[what]
+ if i then
+ local leftkern=i.leftkern or 0
+ local rightkern=i.rightkern or 0
+ local yoffset=i.yoffset or 0
+ local markx=i.markx or 0
+ local marky=i.marky or 0
+ local markdir=i.markdir or 0
+ local markbase=i.markbase or 0
+ local cursivex=i.cursivex or 0
+ local cursivey=i.cursivey or 0
+ local ligaindex=i.ligaindex or 0
+ local cursbase=i.cursiveanchor
+ local margin=nested and 4 or 2
+ if rightkern~=0 or yoffset~=0 then
+ report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset)
+ elseif leftkern~=0 then
+ report_injections("%w%s kern: dx %p",margin,symbol,leftkern)
+ end
+ if markx~=0 or marky~=0 or markbase~=0 then
+ report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase~=0 and "yes" or "no")
+ end
+ if cursivex~=0 or cursivey~=0 then
+ if cursbase then
+ report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ else
+ report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ end
+ elseif cursbase then
+ report_injections("%w%s curs: base",margin,symbol)
+ end
+ if ligaindex~=0 then
+ report_injections("%w%s liga: index %i",margin,symbol,ligaindex)
+ end
+ end
+ end
+ end
+end
+local function showsub(n,what,where)
+ report_injections("begin subrun: %s",where)
+ for n in nextchar,n do
+ showchar(n,where)
+ show(n,what,where," ")
+ end
+ report_injections("end subrun")
+end
+local function trace(head,where)
+ report_injections()
+ report_injections("begin run %s: %s kerns, %s positions, %s marks and %s cursives registered",
+ where or "",nofregisteredkerns,nofregisteredpositions,nofregisteredmarks,nofregisteredcursives)
+ local n=head
+ while n do
+ local id=getid(n)
+ if id==glyph_code then
+ showchar(n)
+ show(n,"injections",false," ")
+ show(n,"preinjections",false,"<")
+ show(n,"postinjections",false,">")
+ show(n,"replaceinjections",false,"=")
+ show(n,"emptyinjections",false,"*")
+ elseif id==disc_code then
+ local pre,post,replace=getdisc(n)
+ if pre then
+ showsub(pre,"preinjections","pre")
+ end
+ if post then
+ showsub(post,"postinjections","post")
+ end
+ if replace then
+ showsub(replace,"replaceinjections","replace")
+ end
+ show(n,"emptyinjections",false,"*")
+ end
+ n=getnext(n)
+ end
+ report_injections("end run")
+end
+local function show_result(head)
+ local current=head
+ local skipping=false
+ while current do
+ local id=getid(current)
+ if id==glyph_code then
+ local w=getwidth(current)
+ local x,y=getoffsets(current)
+ report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y)
+ skipping=false
+ elseif id==kern_code then
+ report_injections("kern: %p",getkern(current))
+ skipping=false
+ elseif not skipping then
+ report_injections()
+ skipping=true
+ end
+ current=getnext(current)
+ end
+ report_injections()
+end
+local function inject_kerns_only(head,where)
+ if trace_injections then
+ trace(head,"kerns")
+ end
+ local current=head
+ local prev=nil
+ local next=nil
+ local prevdisc=nil
+ local pre=nil
+ local post=nil
+ local replace=nil
+ local pretail=nil
+ local posttail=nil
+ local replacetail=nil
+ while current do
+ local next=getnext(current)
+ local char,id=ischar(current)
+ if char then
+ local p=rawget(properties,current)
+ if p then
+ local i=p.injections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ head=insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if prevdisc then
+ local done=false
+ if post then
+ local i=p.postinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(posttail,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ if replace then
+ local i=p.replaceinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(replacetail,fontkern(leftkern))
+ done=true
+ end
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=fontkern(leftkern)
+ done=true
+ end
+ end
+ end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
+ end
+ end
+ end
+ prevdisc=nil
+ elseif char==false then
+ prevdisc=nil
+ elseif id==disc_code then
+ pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
+ local done=false
+ if pre then
+ for n in nextchar,pre do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.preinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ pre=insert_node_before(pre,n,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if post then
+ for n in nextchar,post do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.postinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ post=insert_node_before(post,n,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if replace then
+ for n in nextchar,replace do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.replaceinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=insert_node_before(replace,n,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if done then
+ setdisc(current,pre,post,replace)
+ end
+ prevdisc=current
+ else
+ prevdisc=nil
+ end
+ prev=current
+ current=next
+ end
+ if keepregisteredcounts then
+ keepregisteredcounts=false
+ else
+ nofregisteredkerns=0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
+end
+local function inject_positions_only(head,where)
+ if trace_injections then
+ trace(head,"positions")
+ end
+ local current=head
+ local prev=nil
+ local next=nil
+ local prevdisc=nil
+ local prevglyph=nil
+ local pre=nil
+ local post=nil
+ local replace=nil
+ local pretail=nil
+ local posttail=nil
+ local replacetail=nil
+ while current do
+ local next=getnext(current)
+ local char,id=ischar(current)
+ if char then
+ local p=rawget(properties,current)
+ if p then
+ local i=p.injections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(current,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ local rightkern=i.rightkern
+ if leftkern and leftkern~=0 then
+ if rightkern and leftkern==-rightkern then
+ setoffsets(current,leftkern,false)
+ rightkern=0
+ else
+ head=insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if rightkern and rightkern~=0 then
+ insert_node_after(head,current,fontkern(rightkern))
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ if next and getid(next)==disc_code then
+ if replace then
+ else
+ replace=fontkern(rightkern)
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if prevdisc then
+ local done=false
+ if post then
+ local i=p.postinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(posttail,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ if replace then
+ local i=p.replaceinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(replacetail,fontkern(leftkern))
+ done=true
+ end
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=fontkern(leftkern)
+ done=true
+ end
+ end
+ end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
+ end
+ end
+ end
+ prevdisc=nil
+ prevglyph=current
+ elseif char==false then
+ prevdisc=nil
+ prevglyph=current
+ elseif id==disc_code then
+ pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
+ local done=false
+ if pre then
+ for n in nextchar,pre do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.preinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ pre=insert_node_before(pre,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(pre,n,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if post then
+ for n in nextchar,post do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.postinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ post=insert_node_before(post,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(post,n,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if replace then
+ for n in nextchar,replace do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.replaceinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=insert_node_before(replace,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(replace,n,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if prevglyph then
+ if pre then
+ local p=rawget(properties,prevglyph)
+ if p then
+ local i=p.preinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ pre=insert_node_before(pre,pre,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ if replace then
+ local p=rawget(properties,prevglyph)
+ if p then
+ local i=p.replaceinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ replace=insert_node_before(replace,replace,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if done then
+ setdisc(current,pre,post,replace)
+ end
+ prevglyph=nil
+ prevdisc=current
+ else
+ prevglyph=nil
+ prevdisc=nil
+ end
+ prev=current
+ current=next
+ end
+ if keepregisteredcounts then
+ keepregisteredcounts=false
+ else
+ nofregisteredpositions=0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
+end
+local function showoffset(n,flag)
+ local x,y=getoffsets(n)
+ if x~=0 or y~=0 then
+ setcolor(n,"darkgray")
+ end
+end
+local function inject_everything(head,where)
+ if trace_injections then
+ trace(head,"everything")
+ end
+ local hascursives=nofregisteredcursives>0
+ local hasmarks=nofregisteredmarks>0
+ local current=head
+ local last=nil
+ local prev=nil
+ local next=nil
+ local prevdisc=nil
+ local prevglyph=nil
+ local pre=nil
+ local post=nil
+ local replace=nil
+ local pretail=nil
+ local posttail=nil
+ local replacetail=nil
+ local cursiveanchor=nil
+ local minc=0
+ local maxc=0
+ local glyphs={}
+ local marks={}
+ local nofmarks=0
+ local function processmark(p,n,pn)
+ local px,py=getoffsets(p)
+ local nx,ny=getoffsets(n)
+ local ox=0
+ local rightkern=nil
+ local pp=rawget(properties,p)
+ if pp then
+ pp=pp.injections
+ if pp then
+ rightkern=pp.rightkern
+ end
+ end
+ local markdir=pn.markdir
+ if rightkern then
+ ox=px-(pn.markx or 0)-rightkern
+ if markdir and markdir<0 then
+ if not pn.markmark then
+ ox=ox+(pn.leftkern or 0)
+ end
+ else
+ if false then
+ local leftkern=pp.leftkern
+ if leftkern then
+ ox=ox-leftkern
+ end
+ end
+ end
+ else
+ ox=px-(pn.markx or 0)
+ if markdir and markdir<0 then
+ if not pn.markmark then
+ local leftkern=pn.leftkern
+ if leftkern then
+ ox=ox+leftkern
+ end
+ end
+ end
+ if pn.checkmark then
+ local wn=getwidth(n)
+ if wn and wn~=0 then
+ wn=wn/2
+ if trace_injections then
+ report_injections("correcting non zero width mark %C",getchar(n))
+ end
+ insert_node_before(n,n,fontkern(-wn))
+ insert_node_after(n,n,fontkern(-wn))
+ end
+ end
+ end
+ local oy=ny+py+(pn.marky or 0)
+ if not pn.markmark then
+ local yoffset=pn.yoffset
+ if yoffset then
+ oy=oy+yoffset
+ end
+ end
+ setoffsets(n,ox,oy)
+ if trace_marks then
+ showoffset(n,true)
+ end
+ end
+ while current do
+ local next=getnext(current)
+ local char,id=ischar(current)
+ if char then
+ local p=rawget(properties,current)
+ if p then
+ local i=p.injections
+ if i then
+ local pm=i.markbasenode
+ if pm then
+ nofmarks=nofmarks+1
+ marks[nofmarks]=current
+ else
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(current,false,yoffset)
+ end
+ if hascursives then
+ local cursivex=i.cursivex
+ if cursivex then
+ if cursiveanchor then
+ if cursivex~=0 then
+ i.leftkern=(i.leftkern or 0)+cursivex
+ end
+ if maxc==0 then
+ minc=1
+ maxc=1
+ glyphs[1]=cursiveanchor
+ else
+ maxc=maxc+1
+ glyphs[maxc]=cursiveanchor
+ end
+ properties[cursiveanchor].cursivedy=i.cursivey
+ last=current
+ else
+ maxc=0
+ end
+ elseif maxc>0 then
+ local nx,ny=getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti=glyphs[i]
+ ny=ny+properties[ti].cursivedy
+ setoffsets(ti,false,ny)
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ maxc=0
+ cursiveanchor=nil
+ end
+ if i.cursiveanchor then
+ cursiveanchor=current
+ else
+ if maxc>0 then
+ local nx,ny=getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti=glyphs[i]
+ ny=ny+properties[ti].cursivedy
+ setoffsets(ti,false,ny)
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ maxc=0
+ end
+ cursiveanchor=nil
+ end
+ end
+ local leftkern=i.leftkern
+ local rightkern=i.rightkern
+ if leftkern and leftkern~=0 then
+ if rightkern and leftkern==-rightkern then
+ setoffsets(current,leftkern,false)
+ rightkern=0
+ else
+ head=insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if rightkern and rightkern~=0 then
+ insert_node_after(head,current,fontkern(rightkern))
+ end
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ if next and getid(next)==disc_code then
+ if replace then
+ else
+ replace=fontkern(rightkern)
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if prevdisc then
+ if p then
+ local done=false
+ if post then
+ local i=p.postinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(posttail,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ if replace then
+ local i=p.replaceinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(replacetail,fontkern(leftkern))
+ done=true
+ end
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=fontkern(leftkern)
+ done=true
+ end
+ end
+ end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
+ end
+ end
+ end
+ else
+ if hascursives and maxc>0 then
+ local nx,ny=getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti=glyphs[i]
+ ny=ny+properties[ti].cursivedy
+ local xi,yi=getoffsets(ti)
+ setoffsets(ti,xi,yi+ny)
+ end
+ maxc=0
+ cursiveanchor=nil
+ end
+ end
+ prevdisc=nil
+ prevglyph=current
+ elseif char==false then
+ prevdisc=nil
+ prevglyph=current
+ elseif id==disc_code then
+ pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
+ local done=false
+ if pre then
+ for n in nextchar,pre do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.preinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ pre=insert_node_before(pre,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(pre,n,fontkern(rightkern))
+ done=true
+ end
+ if hasmarks then
+ local pm=i.markbasenode
+ if pm then
+ processmark(pm,n,i)
+ end
+ end
+ end
+ end
+ end
+ end
+ if post then
+ for n in nextchar,post do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.postinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ post=insert_node_before(post,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(post,n,fontkern(rightkern))
+ done=true
+ end
+ if hasmarks then
+ local pm=i.markbasenode
+ if pm then
+ processmark(pm,n,i)
+ end
+ end
+ end
+ end
+ end
+ end
+ if replace then
+ for n in nextchar,replace do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.replaceinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=insert_node_before(replace,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(replace,n,fontkern(rightkern))
+ done=true
+ end
+ if hasmarks then
+ local pm=i.markbasenode
+ if pm then
+ processmark(pm,n,i)
+ end
+ end
+ end
+ end
+ end
+ end
+ if prevglyph then
+ if pre then
+ local p=rawget(properties,prevglyph)
+ if p then
+ local i=p.preinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ pre=insert_node_before(pre,pre,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ if replace then
+ local p=rawget(properties,prevglyph)
+ if p then
+ local i=p.replaceinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ replace=insert_node_before(replace,replace,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if done then
+ setdisc(current,pre,post,replace)
+ end
+ prevglyph=nil
+ prevdisc=current
+ else
+ prevglyph=nil
+ prevdisc=nil
+ end
+ prev=current
+ current=next
+ end
+ if hascursives and maxc>0 then
+ local nx,ny=getoffsets(last)
+ for i=maxc,minc,-1 do
+ local ti=glyphs[i]
+ ny=ny+properties[ti].cursivedy
+ setoffsets(ti,false,ny)
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ end
+ if nofmarks>0 then
+ for i=1,nofmarks do
+ local m=marks[i]
+ local p=rawget(properties,m)
+ local i=p.injections
+ local b=i.markbasenode
+ processmark(b,m,i)
+ end
+ elseif hasmarks then
+ end
+ if keepregisteredcounts then
+ keepregisteredcounts=false
+ else
+ nofregisteredkerns=0
+ nofregisteredpositions=0
+ nofregisteredmarks=0
+ nofregisteredcursives=0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
+end
+local triggers=false
+function nodes.injections.setspacekerns(font,sequence)
+ if triggers then
+ triggers[font]=sequence
+ else
+ triggers={ [font]=sequence }
+ end
+end
+local getthreshold
+if context then
+ local threshold=1
+ local parameters=fonts.hashes.parameters
+ directives.register("otf.threshold",function(v) threshold=tonumber(v) or 1 end)
+ getthreshold=function(font)
+ local p=parameters[font]
+ local f=p.factor
+ local s=p.spacing
+ local t=threshold*(s and s.width or p.space or 0)-2
+ return t>0 and t or 0,f
+ end
+else
+ injections.threshold=0
+ getthreshold=function(font)
+ local p=fontdata[font].parameters
+ local f=p.factor
+ local s=p.spacing
+ local t=injections.threshold*(s and s.width or p.space or 0)-2
+ return t>0 and t or 0,f
+ end
+end
+injections.getthreshold=getthreshold
+function injections.isspace(n,threshold,id)
+ if (id or getid(n))==glue_code then
+ local w=getwidth(n)
+ if threshold and w>threshold then
+ return 32
+ end
+ end
+end
+local getspaceboth=getboth
+function injections.installgetspaceboth(gb)
+ getspaceboth=gb or getboth
+end
+local function injectspaces(head)
+ if not triggers then
+ return head
+ end
+ local lastfont=nil
+ local spacekerns=nil
+ local leftkerns=nil
+ local rightkerns=nil
+ local factor=0
+ local threshold=0
+ local leftkern=false
+ local rightkern=false
+ local function updatefont(font,trig)
+ leftkerns=trig.left
+ rightkerns=trig.right
+ lastfont=font
+ threshold,
+ factor=getthreshold(font)
+ end
+ for n in nextglue,head do
+ local prev,next=getspaceboth(n)
+ local prevchar=prev and ischar(prev)
+ local nextchar=next and ischar(next)
+ if nextchar then
+ local font=getfont(next)
+ local trig=triggers[font]
+ if trig then
+ if lastfont~=font then
+ updatefont(font,trig)
+ end
+ if rightkerns then
+ rightkern=rightkerns[nextchar]
+ end
+ end
+ end
+ if prevchar then
+ local font=getfont(prev)
+ local trig=triggers[font]
+ if trig then
+ if lastfont~=font then
+ updatefont(font,trig)
+ end
+ if leftkerns then
+ leftkern=leftkerns[prevchar]
+ end
+ end
+ end
+ if leftkern then
+ local old=getwidth(n)
+ if old>threshold then
+ if rightkern then
+ if useitalickerns then
+ local lnew=leftkern*factor
+ local rnew=rightkern*factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar)
+ end
+ head=insert_node_before(head,n,italickern(lnew))
+ insert_node_after(head,n,italickern(rnew))
+ else
+ local new=old+(leftkern+rightkern)*factor
+ if trace_spaces then
+ report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar)
+ end
+ setwidth(n,new)
+ end
+ rightkern=false
+ else
+ if useitalickerns then
+ local new=leftkern*factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p]",prevchar,old,new)
+ end
+ insert_node_after(head,n,italickern(new))
+ else
+ local new=old+leftkern*factor
+ if trace_spaces then
+ report_spaces("%C [%p -> %p]",prevchar,old,new)
+ end
+ setwidth(n,new)
+ end
+ end
+ end
+ leftkern=false
+ elseif rightkern then
+ local old=getwidth(n)
+ if old>threshold then
+ if useitalickerns then
+ local new=rightkern*factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p]",nextchar,old,new)
+ end
+ insert_node_after(head,n,italickern(new))
+ else
+ local new=old+rightkern*factor
+ if trace_spaces then
+ report_spaces("[%p -> %p] %C",nextchar,old,new)
+ end
+ setwidth(n,new)
+ end
+ end
+ rightkern=false
+ end
+ end
+ triggers=false
+ return head
+end
+function injections.handler(head,where)
+ if triggers then
+ head=injectspaces(head)
+ end
+ if nofregisteredmarks>0 or nofregisteredcursives>0 then
+ if trace_injections then
+ report_injections("injection variant %a","everything")
+ end
+ return inject_everything(head,where)
+ elseif nofregisteredpositions>0 then
+ if trace_injections then
+ report_injections("injection variant %a","positions")
+ end
+ return inject_positions_only(head,where)
+ elseif nofregisteredkerns>0 then
+ if trace_injections then
+ report_injections("injection variant %a","kerns")
+ end
+ return inject_kerns_only(head,where)
+ else
+ return head
+ end
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otjâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ota†d6dfb94563d6a52675e274b2e673e4a6] ---
+
+if not modules then modules={} end modules ['font-ota']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local type=type
+if not trackers then trackers={ register=function() end } end
+local fonts,nodes,node=fonts,nodes,node
+local allocate=utilities.storage.allocate
+local otf=fonts.handlers.otf
+local analyzers=fonts.analyzers
+local initializers=allocate()
+local methods=allocate()
+analyzers.initializers=initializers
+analyzers.methods=methods
+local a_state=attributes.private('state')
+local nuts=nodes.nuts
+local tonut=nuts.tonut
+local getnext=nuts.getnext
+local getprev=nuts.getprev
+local getprev=nuts.getprev
+local getprop=nuts.getprop
+local setprop=nuts.setprop
+local getsubtype=nuts.getsubtype
+local getchar=nuts.getchar
+local ischar=nuts.ischar
+local end_of_math=nuts.end_of_math
+local nodecodes=nodes.nodecodes
+local disc_code=nodecodes.disc
+local math_code=nodecodes.math
+local fontdata=fonts.hashes.identifiers
+local categories=characters and characters.categories or {}
+local chardata=characters and characters.data
+local otffeatures=fonts.constructors.features.otf
+local registerotffeature=otffeatures.register
+local s_init=1 local s_rphf=7
+local s_medi=2 local s_half=8
+local s_fina=3 local s_pref=9
+local s_isol=4 local s_blwf=10
+local s_mark=5 local s_pstf=11
+local s_rest=6
+local states=allocate {
+ init=s_init,
+ medi=s_medi,
+ med2=s_medi,
+ fina=s_fina,
+ fin2=s_fina,
+ fin3=s_fina,
+ isol=s_isol,
+ mark=s_mark,
+ rest=s_rest,
+ rphf=s_rphf,
+ half=s_half,
+ pref=s_pref,
+ blwf=s_blwf,
+ pstf=s_pstf,
+}
+local features=allocate {
+ init=s_init,
+ medi=s_medi,
+ med2=s_medi,
+ fina=s_fina,
+ fin2=s_fina,
+ fin3=s_fina,
+ isol=s_isol,
+ rphf=s_rphf,
+ half=s_half,
+ pref=s_pref,
+ blwf=s_blwf,
+ pstf=s_pstf,
+}
+analyzers.states=states
+analyzers.features=features
+analyzers.useunicodemarks=false
+function analyzers.setstate(head,font)
+ local useunicodemarks=analyzers.useunicodemarks
+ local tfmdata=fontdata[font]
+ local descriptions=tfmdata.descriptions
+ local first,last,current,n,done=nil,nil,head,0,false
+ current=tonut(current)
+ while current do
+ local char,id=ischar(current,font)
+ if char and not getprop(current,a_state) then
+ done=true
+ local d=descriptions[char]
+ if d then
+ if d.class=="mark" then
+ done=true
+ setprop(current,a_state,s_mark)
+ elseif useunicodemarks and categories[char]=="mn" then
+ done=true
+ setprop(current,a_state,s_mark)
+ elseif n==0 then
+ first,last,n=current,current,1
+ setprop(current,a_state,s_init)
+ else
+ last,n=current,n+1
+ setprop(current,a_state,s_medi)
+ end
+ else
+ if first and first==last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ first,last,n=nil,nil,0
+ end
+ elseif char==false then
+ if first and first==last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ first,last,n=nil,nil,0
+ if id==math_code then
+ current=end_of_math(current)
+ end
+ elseif id==disc_code then
+ setprop(current,a_state,s_medi)
+ last=current
+ else
+ if first and first==last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ first,last,n=nil,nil,0
+ if id==math_code then
+ current=end_of_math(current)
+ end
+ end
+ current=getnext(current)
+ end
+ if first and first==last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ return head,done
+end
+local function analyzeinitializer(tfmdata,value)
+ local script,language=otf.scriptandlanguage(tfmdata)
+ local action=initializers[script]
+ if not action then
+ elseif type(action)=="function" then
+ return action(tfmdata,value)
+ else
+ local action=action[language]
+ if action then
+ return action(tfmdata,value)
+ end
+ end
+end
+local function analyzeprocessor(head,font,attr)
+ local tfmdata=fontdata[font]
+ local script,language=otf.scriptandlanguage(tfmdata,attr)
+ local action=methods[script]
+ if not action then
+ elseif type(action)=="function" then
+ return action(head,font,attr)
+ else
+ action=action[language]
+ if action then
+ return action(head,font,attr)
+ end
+ end
+ return head,false
+end
+registerotffeature {
+ name="analyze",
+ description="analysis of character classes",
+ default=true,
+ initializers={
+ node=analyzeinitializer,
+ },
+ processors={
+ position=1,
+ node=analyzeprocessor,
+ }
+}
+methods.latn=analyzers.setstate
+local arab_warned={}
+local function warning(current,what)
+ local char=getchar(current)
+ if not arab_warned[char] then
+ log.report("analyze","arab: character %C has no %a class",char,what)
+ arab_warned[char]=true
+ end
+end
+local mappers=allocate {
+ l=s_init,
+ d=s_medi,
+ c=s_medi,
+ r=s_fina,
+ u=s_isol,
+}
+local classifiers=characters.classifiers
+if not classifiers then
+ local f_arabic,l_arabic=characters.blockrange("arabic")
+ local f_syriac,l_syriac=characters.blockrange("syriac")
+ local f_mandiac,l_mandiac=characters.blockrange("mandiac")
+ local f_nko,l_nko=characters.blockrange("nko")
+ local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda")
+ classifiers=table.setmetatableindex(function(t,k)
+ if type(k)=="number" then
+ local c=chardata[k]
+ local v=false
+ if c then
+ local arabic=c.arabic
+ if arabic then
+ v=mappers[arabic]
+ if not v then
+ log.report("analyze","error in mapping arabic %C",k)
+ v=false
+ end
+ elseif (k>=f_arabic and k<=l_arabic) or
+ (k>=f_syriac and k<=l_syriac) or
+ (k>=f_mandiac and k<=l_mandiac) or
+ (k>=f_nko and k<=l_nko) or
+ (k>=f_ext_a and k<=l_ext_a) then
+ if categories[k]=="mn" then
+ v=s_mark
+ else
+ v=s_rest
+ end
+ end
+ end
+ t[k]=v
+ return v
+ end
+ end)
+ characters.classifiers=classifiers
+end
+function methods.arab(head,font,attr)
+ local first,last,c_first,c_last
+ local current=head
+ local done=false
+ current=tonut(current)
+ while current do
+ local char,id=ischar(current,font)
+ if char and not getprop(current,a_state) then
+ done=true
+ local classifier=classifiers[char]
+ if not classifier then
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first,last=nil,nil
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first=nil
+ end
+ elseif classifier==s_mark then
+ setprop(current,a_state,s_mark)
+ elseif classifier==s_isol then
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first,last=nil,nil
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first=nil
+ end
+ setprop(current,a_state,s_isol)
+ elseif classifier==s_medi then
+ if first then
+ last=current
+ c_last=classifier
+ setprop(current,a_state,s_medi)
+ else
+ setprop(current,a_state,s_init)
+ first=current
+ c_first=classifier
+ end
+ elseif classifier==s_fina then
+ if last then
+ if getprop(last,a_state)~=s_init then
+ setprop(last,a_state,s_medi)
+ end
+ setprop(current,a_state,s_fina)
+ first,last=nil,nil
+ elseif first then
+ setprop(current,a_state,s_fina)
+ first=nil
+ else
+ setprop(current,a_state,s_isol)
+ end
+ else
+ setprop(current,a_state,s_rest)
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first,last=nil,nil
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first=nil
+ end
+ end
+ else
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first,last=nil,nil
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first=nil
+ end
+ if id==math_code then
+ current=end_of_math(current)
+ end
+ end
+ current=getnext(current)
+ end
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ end
+ return head,done
+end
+methods.syrc=methods.arab
+methods.mand=methods.arab
+methods.nko=methods.arab
+directives.register("otf.analyze.useunicodemarks",function(v)
+ analyzers.useunicodemarks=v
+end)
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otaâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ots†d5504847a278385cd0d20ecf1b3d59cc] ---
+
+if not modules then modules={} end modules ['font-ots']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
+}
+local type,next,tonumber=type,next,tonumber
+local random=math.random
+local formatters=string.formatters
+local insert=table.insert
+local registertracker=trackers.register
+local logs=logs
+local trackers=trackers
+local nodes=nodes
+local attributes=attributes
+local fonts=fonts
+local otf=fonts.handlers.otf
+local tracers=nodes.tracers
+local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end)
+local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end)
+local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end)
+local trace_ligatures=false registertracker("otf.ligatures",function(v) trace_ligatures=v end)
+local trace_contexts=false registertracker("otf.contexts",function(v) trace_contexts=v end)
+local trace_marks=false registertracker("otf.marks",function(v) trace_marks=v end)
+local trace_kerns=false registertracker("otf.kerns",function(v) trace_kerns=v end)
+local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursive=v end)
+local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end)
+local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end)
+local trace_details=false registertracker("otf.details",function(v) trace_details=v end)
+local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end)
+local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end)
+local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end)
+local trace_chains=false registertracker("otf.chains",function(v) trace_chains=v end)
+local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end)
+local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end)
+local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end)
+local forcediscretionaries=false
+local forcepairadvance=false
+directives.register("otf.forcediscretionaries",function(v)
+ forcediscretionaries=v
+end)
+directives.register("otf.forcepairadvance",function(v)
+ forcepairadvance=v
+end)
+local report_direct=logs.reporter("fonts","otf direct")
+local report_subchain=logs.reporter("fonts","otf subchain")
+local report_chain=logs.reporter("fonts","otf chain")
+local report_process=logs.reporter("fonts","otf process")
+local report_warning=logs.reporter("fonts","otf warning")
+local report_run=logs.reporter("fonts","otf run")
+registertracker("otf.substitutions","otf.singles","otf.multiples","otf.alternatives","otf.ligatures")
+registertracker("otf.positions","otf.marks","otf.kerns","otf.cursive")
+registertracker("otf.actions","otf.substitutions","otf.positions")
+registertracker("otf.sample","otf.steps","otf.substitutions","otf.positions","otf.analyzing")
+registertracker("otf.sample.silent","otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing")
+local nuts=nodes.nuts
+local getfield=nuts.getfield
+local getnext=nuts.getnext
+local setnext=nuts.setnext
+local getprev=nuts.getprev
+local setprev=nuts.setprev
+local getboth=nuts.getboth
+local setboth=nuts.setboth
+local getid=nuts.getid
+local getprop=nuts.getprop
+local setprop=nuts.setprop
+local getsubtype=nuts.getsubtype
+local setsubtype=nuts.setsubtype
+local getchar=nuts.getchar
+local setchar=nuts.setchar
+local getdisc=nuts.getdisc
+local setdisc=nuts.setdisc
+local setlink=nuts.setlink
+local getcomponents=nuts.getcomponents
+local setcomponents=nuts.setcomponents
+local getwidth=nuts.getwidth
+local getattr=nuts.getattr
+local getglyphdata=nuts.getglyphdata
+local ischar=nuts.ischar
+local isglyph=nuts.isglyph
+local usesfont=nuts.uses_font
+local insert_node_after=nuts.insert_after
+local copy_node=nuts.copy
+local copy_node_list=nuts.copy_list
+local remove_node=nuts.remove
+local find_node_tail=nuts.tail
+local flush_node_list=nuts.flush_list
+local flush_node=nuts.flush_node
+local end_of_math=nuts.end_of_math
+local setmetatable=setmetatable
+local setmetatableindex=table.setmetatableindex
+local nextnode=nuts.traversers.node
+local nodecodes=nodes.nodecodes
+local glyphcodes=nodes.glyphcodes
+local disccodes=nodes.disccodes
+local glyph_code=nodecodes.glyph
+local glue_code=nodecodes.glue
+local disc_code=nodecodes.disc
+local math_code=nodecodes.math
+local dir_code=nodecodes.dir
+local localpar_code=nodecodes.localpar
+local discretionarydisc_code=disccodes.discretionary
+local ligatureglyph_code=glyphcodes.ligature
+local a_state=attributes.private('state')
+local a_noligature=attributes.private("noligature")
+local injections=nodes.injections
+local setmark=injections.setmark
+local setcursive=injections.setcursive
+local setkern=injections.setkern
+local setmove=injections.setmove
+local setposition=injections.setposition
+local resetinjection=injections.reset
+local copyinjection=injections.copy
+local setligaindex=injections.setligaindex
+local getligaindex=injections.getligaindex
+local fontdata=fonts.hashes.identifiers
+local fontfeatures=fonts.hashes.features
+local otffeatures=fonts.constructors.features.otf
+local registerotffeature=otffeatures.register
+local onetimemessage=fonts.loggers.onetimemessage or function() end
+local getrandom=utilities and utilities.randomizer and utilities.randomizer.get
+otf.defaultnodealternate="none"
+local tfmdata=false
+local characters=false
+local descriptions=false
+local marks=false
+local classes=false
+local currentfont=false
+local factor=0
+local threshold=0
+local checkmarks=false
+local discs=false
+local spaces=false
+local sweepnode=nil
+local sweephead={}
+local notmatchpre={}
+local notmatchpost={}
+local notmatchreplace={}
+local handlers={}
+local isspace=injections.isspace
+local getthreshold=injections.getthreshold
+local checkstep=(tracers and tracers.steppers.check) or function() end
+local registerstep=(tracers and tracers.steppers.register) or function() end
+local registermessage=(tracers and tracers.steppers.message) or function() end
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ if trace_steps=="silent" then
+ return
+ end
+ end
+ report_direct(...)
+end
+local function logwarning(...)
+ report_direct(...)
+end
+local gref do
+ local f_unicode=formatters["U+%X"]
+ local f_uniname=formatters["U+%X (%s)"]
+ local f_unilist=formatters["% t"]
+ gref=function(n)
+ if type(n)=="number" then
+ local description=descriptions[n]
+ local name=description and description.name
+ if name then
+ return f_uniname(n,name)
+ else
+ return f_unicode(n)
+ end
+ elseif n then
+ local t={}
+ for i=1,#n do
+ local ni=n[i]
+ if tonumber(ni) then
+ local di=descriptions[ni]
+ local nn=di and di.name
+ if nn then
+ t[#t+1]=f_uniname(ni,nn)
+ else
+ t[#t+1]=f_unicode(ni)
+ end
+ end
+ end
+ return f_unilist(t)
+ else
+ return "<error in node mode tracing>"
+ end
+ end
+end
+local function cref(dataset,sequence,index)
+ if not dataset then
+ return "no valid dataset"
+ end
+ local merged=sequence.merged and "merged " or ""
+ if index then
+ return formatters["feature %a, type %a, %schain lookup %a, index %a"](
+ dataset[4],sequence.type,merged,sequence.name,index)
+ else
+ return formatters["feature %a, type %a, %schain lookup %a"](
+ dataset[4],sequence.type,merged,sequence.name)
+ end
+end
+local function pref(dataset,sequence)
+ return formatters["feature %a, type %a, %slookup %a"](
+ dataset[4],sequence.type,sequence.merged and "merged " or "",sequence.name)
+end
+local function mref(rlmode)
+ if not rlmode or rlmode>=0 then
+ return "l2r"
+ else
+ return "r2l"
+ end
+end
+local function flattendisk(head,disc)
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
+ local prev,next=getboth(disc)
+ local ishead=head==disc
+ setdisc(disc)
+ flush_node(disc)
+ if pre then
+ flush_node_list(pre)
+ end
+ if post then
+ flush_node_list(post)
+ end
+ if ishead then
+ if replace then
+ if next then
+ setlink(replacetail,next)
+ end
+ return replace,replace
+ elseif next then
+ return next,next
+ else
+ end
+ else
+ if replace then
+ if next then
+ setlink(replacetail,next)
+ end
+ setlink(prev,replace)
+ return head,replace
+ else
+ setlink(prev,next)
+ return head,next
+ end
+ end
+end
+local function appenddisc(disc,list)
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
+ local posthead=list
+ local replacehead=copy_node_list(list)
+ if post then
+ setlink(posttail,posthead)
+ else
+ post=posthead
+ end
+ if replace then
+ setlink(replacetail,replacehead)
+ else
+ replace=replacehead
+ end
+ setdisc(disc,pre,post,replace)
+end
+local copy_no_components=nuts.copy_no_components
+local copy_only_glyphs=nuts.copy_only_glyphs
+local set_components=setcomponents
+local take_components=getcomponents
+local function count_components(start,marks)
+ local char=isglyph(start)
+ if char then
+ if getsubtype(start)==ligatureglyph_code then
+ local i=0
+ local components=getcomponents(start)
+ while components do
+ i=i+count_components(components,marks)
+ components=getnext(components)
+ end
+ return i
+ elseif not marks[char] then
+ return 1
+ end
+ end
+ return 0
+end
+local function markstoligature(head,start,stop,char)
+ if start==stop and getchar(start)==char then
+ return head,start
+ else
+ local prev=getprev(start)
+ local next=getnext(stop)
+ setprev(start)
+ setnext(stop)
+ local base=copy_no_components(start,copyinjection)
+ if head==start then
+ head=base
+ end
+ resetinjection(base)
+ setchar(base,char)
+ setsubtype(base,ligatureglyph_code)
+ set_components(base,start)
+ setlink(prev,base,next)
+ return head,base
+ end
+end
+local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks)
+ if getattr(start,a_noligature)==1 then
+ return head,start
+ end
+ if start==stop and getchar(start)==char then
+ resetinjection(start)
+ setchar(start,char)
+ return head,start
+ end
+ local prev=getprev(start)
+ local next=getnext(stop)
+ local comp=start
+ setprev(start)
+ setnext(stop)
+ local base=copy_no_components(start,copyinjection)
+ if start==head then
+ head=base
+ end
+ resetinjection(base)
+ setchar(base,char)
+ setsubtype(base,ligatureglyph_code)
+ set_components(base,comp)
+ setlink(prev,base,next)
+ if not discfound then
+ local deletemarks=not skiphash or hasmarks
+ local components=start
+ local baseindex=0
+ local componentindex=0
+ local head=base
+ local current=base
+ while start do
+ local char=getchar(start)
+ if not marks[char] then
+ baseindex=baseindex+componentindex
+ componentindex=count_components(start,marks)
+ elseif not deletemarks then
+ setligaindex(start,baseindex+getligaindex(start,componentindex))
+ if trace_marks then
+ logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ end
+ local n=copy_node(start)
+ copyinjection(n,start)
+ head,current=insert_node_after(head,current,n)
+ elseif trace_marks then
+ logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char))
+ end
+ start=getnext(start)
+ end
+ local start=getnext(current)
+ while start do
+ local char=ischar(start)
+ if char then
+ if marks[char] then
+ setligaindex(start,baseindex+getligaindex(start,componentindex))
+ if trace_marks then
+ logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ end
+ start=getnext(start)
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ else
+ local discprev,discnext=getboth(discfound)
+ if discprev and discnext then
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true)
+ if not replace then
+ local prev=getprev(base)
+ local comp=take_components(base)
+ local copied=copy_only_glyphs(comp)
+ if pre then
+ setlink(discprev,pre)
+ else
+ setnext(discprev)
+ end
+ pre=comp
+ if post then
+ setlink(posttail,discnext)
+ setprev(post)
+ else
+ post=discnext
+ setprev(discnext)
+ end
+ setlink(prev,discfound,next)
+ setboth(base)
+ set_components(base,copied)
+ replace=base
+ if forcediscretionaries then
+ setdisc(discfound,pre,post,replace,discretionarydisc_code)
+ else
+ setdisc(discfound,pre,post,replace)
+ end
+ base=prev
+ end
+ end
+ end
+ return head,base
+end
+local function multiple_glyphs(head,start,multiple,skiphash,what,stop)
+ local nofmultiples=#multiple
+ if nofmultiples>0 then
+ resetinjection(start)
+ setchar(start,multiple[1])
+ if nofmultiples>1 then
+ local sn=getnext(start)
+ for k=2,nofmultiples do
+ local n=copy_node(start)
+ resetinjection(n)
+ setchar(n,multiple[k])
+ insert_node_after(head,start,n)
+ start=n
+ end
+ if what==true then
+ elseif what>1 then
+ local m=multiple[nofmultiples]
+ for i=2,what do
+ local n=copy_node(start)
+ resetinjection(n)
+ setchar(n,m)
+ insert_node_after(head,start,n)
+ start=n
+ end
+ end
+ end
+ return head,start,true
+ else
+ if trace_multiples then
+ logprocess("no multiple for %s",gref(getchar(start)))
+ end
+ return head,start,false
+ end
+end
+local function get_alternative_glyph(start,alternatives,value)
+ local n=#alternatives
+ if n==1 then
+ return alternatives[1],trace_alternatives and "1 (only one present)"
+ elseif value=="random" then
+ local r=getrandom and getrandom("glyph",1,n) or random(1,n)
+ return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r)
+ elseif value=="first" then
+ return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1)
+ elseif value=="last" then
+ return alternatives[n],trace_alternatives and formatters["value %a, taking %a"](value,n)
+ end
+ value=value==true and 1 or tonumber(value)
+ if type(value)~="number" then
+ return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,1)
+ end
+ if value>n then
+ local defaultalt=otf.defaultnodealternate
+ if defaultalt=="first" then
+ return alternatives[n],trace_alternatives and formatters["invalid value %s, taking %a"](value,1)
+ elseif defaultalt=="last" then
+ return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,n)
+ else
+ return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range")
+ end
+ elseif value==0 then
+ return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change")
+ elseif value<1 then
+ return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1)
+ else
+ return alternatives[value],trace_alternatives and formatters["value %a, taking %a"](value,value)
+ end
+end
+function handlers.gsub_single(head,start,dataset,sequence,replacement)
+ if trace_singles then
+ logprocess("%s: replacing %s by single %s",pref(dataset,sequence),gref(getchar(start)),gref(replacement))
+ end
+ resetinjection(start)
+ setchar(start,replacement)
+ return head,start,true
+end
+function handlers.gsub_alternate(head,start,dataset,sequence,alternative)
+ local kind=dataset[4]
+ local what=dataset[1]
+ local value=what==true and tfmdata.shared.features[kind] or what
+ local choice,comment=get_alternative_glyph(start,alternative,value)
+ if choice then
+ if trace_alternatives then
+ logprocess("%s: replacing %s by alternative %a to %s, %s",pref(dataset,sequence),gref(getchar(start)),gref(choice),comment)
+ end
+ resetinjection(start)
+ setchar(start,choice)
+ else
+ if trace_alternatives then
+ logwarning("%s: no variant %a for %s, %s",pref(dataset,sequence),value,gref(getchar(start)),comment)
+ end
+ end
+ return head,start,true
+end
+function handlers.gsub_multiple(head,start,dataset,sequence,multiple,rlmode,skiphash)
+ if trace_multiples then
+ logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple))
+ end
+ return multiple_glyphs(head,start,multiple,skiphash,dataset[1])
+end
+function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skiphash)
+ local current=getnext(start)
+ if not current then
+ return head,start,false,nil
+ end
+ local stop=nil
+ local startchar=getchar(start)
+ if skiphash and skiphash[startchar] then
+ while current do
+ local char=ischar(current,currentfont)
+ if char then
+ local lg=ligature[char]
+ if lg then
+ stop=current
+ ligature=lg
+ current=getnext(current)
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if stop then
+ local lig=ligature.ligature
+ if lig then
+ if trace_ligatures then
+ local stopchar=getchar(stop)
+ head,start=markstoligature(head,start,stop,lig)
+ logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start)))
+ else
+ head,start=markstoligature(head,start,stop,lig)
+ end
+ return head,start,true,false
+ else
+ end
+ end
+ else
+ local discfound=false
+ local hasmarks=marks[startchar]
+ while current do
+ local char,id=ischar(current,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ current=getnext(current)
+ else
+ local lg=ligature[char]
+ if lg then
+ if marks[char] then
+ hasmarks=true
+ end
+ stop=current
+ ligature=lg
+ current=getnext(current)
+ else
+ break
+ end
+ end
+ elseif char==false then
+ break
+ elseif id==disc_code then
+ discfound=current
+ break
+ else
+ break
+ end
+ end
+ if discfound then
+ local pre,post,replace=getdisc(discfound)
+ local match
+ if replace then
+ local char=ischar(replace,currentfont)
+ if char and ligature[char] then
+ match=true
+ end
+ end
+ if not match and pre then
+ local char=ischar(pre,currentfont)
+ if char and ligature[char] then
+ match=true
+ end
+ end
+ if not match and not pre or not replace then
+ local n=getnext(discfound)
+ local char=ischar(n,currentfont)
+ if char and ligature[char] then
+ match=true
+ end
+ end
+ if match then
+ local ishead=head==start
+ local prev=getprev(start)
+ if stop then
+ setnext(stop)
+ local copy=copy_node_list(start)
+ local tail=stop
+ local liat=find_node_tail(copy)
+ if pre then
+ setlink(liat,pre)
+ end
+ if replace then
+ setlink(tail,replace)
+ end
+ pre=copy
+ replace=start
+ else
+ setnext(start)
+ local copy=copy_node(start)
+ if pre then
+ setlink(copy,pre)
+ end
+ if replace then
+ setlink(start,replace)
+ end
+ pre=copy
+ replace=start
+ end
+ setdisc(discfound,pre,post,replace)
+ if prev then
+ setlink(prev,discfound)
+ else
+ setprev(discfound)
+ head=discfound
+ end
+ start=discfound
+ return head,start,true,true
+ end
+ end
+ local lig=ligature.ligature
+ if lig then
+ if stop then
+ if trace_ligatures then
+ local stopchar=getchar(stop)
+ head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
+ logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig))
+ else
+ head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
+ end
+ else
+ resetinjection(start)
+ setchar(start,lig)
+ if trace_ligatures then
+ logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig))
+ end
+ end
+ return head,start,true,false
+ else
+ end
+ end
+ return head,start,false,false
+end
+function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
+ local startchar=getchar(start)
+ local format=step.format
+ if format=="single" or type(kerns)=="table" then
+ local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else
+ local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
+ end
+ end
+ return head,start,true
+end
+function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
+ local snext=getnext(start)
+ if not snext then
+ return head,start,false
+ else
+ local prev=start
+ while snext do
+ local nextchar=ischar(snext,currentfont)
+ if nextchar then
+ if skiphash and skiphash[nextchar] then
+ prev=snext
+ snext=getnext(snext)
+ else
+ local krn=kerns[nextchar]
+ if not krn then
+ break
+ end
+ local format=step.format
+ if format=="pair" then
+ local a=krn[1]
+ local b=krn[2]
+ if a==true then
+ elseif a then
+ local x,y,w,h=setposition(1,start,factor,rlmode,a,injection)
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ end
+ if b==true then
+ start=snext
+ elseif b then
+ local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection)
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ start=snext
+ elseif forcepairadvance then
+ start=snext
+ end
+ return head,start,true
+ elseif krn~=0 then
+ local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
+ if trace_kerns then
+ logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
+ end
+ return head,start,true
+ else
+ break
+ end
+ end
+ else
+ break
+ end
+ end
+ return head,start,false
+ end
+end
+function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash)
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local base=getprev(start)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base=getprev(base)
+ if base then
+ basechar=ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
+ end
+ return head,start,false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
+ end
+ return head,start,false
+ end
+ end
+ end
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)",
+ pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head,start,true
+ elseif trace_bugs then
+ logwarning("%s: mark %s is not anchored to %s",pref(dataset,sequence),gref(markchar),gref(basechar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
+ return head,start,false
+end
+function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlmode,skiphash)
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local base=getprev(start)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base=getprev(base)
+ if base then
+ basechar=ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
+ end
+ return head,start,false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
+ end
+ return head,start,false
+ end
+ end
+ end
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ if ma then
+ local index=getligaindex(start)
+ ba=ba[index]
+ if ba then
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, index %s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)",
+ pref(dataset,sequence),index,bound,gref(markchar),gref(basechar),index,dx,dy)
+ end
+ return head,start,true
+ else
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(dataset,sequence),gref(markchar),gref(basechar),index)
+ end
+ end
+ end
+ elseif trace_bugs then
+ onetimemessage(currentfont,basechar,"no base anchors",report_fonts)
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
+ return head,start,false
+end
+function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode,skiphash)
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local base=getprev(start)
+ local slc=getligaindex(start)
+ if slc then
+ while base do
+ local blc=getligaindex(base)
+ if blc and blc~=slc then
+ base=getprev(base)
+ else
+ break
+ end
+ end
+ end
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)",
+ pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head,start,true
+ end
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
+ return head,start,false
+end
+function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,skiphash,step)
+ local startchar=getchar(start)
+ if marks[startchar] then
+ if trace_cursive then
+ logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar))
+ end
+ else
+ local nxt=getnext(start)
+ while nxt do
+ local nextchar=ischar(nxt,currentfont)
+ if not nextchar then
+ break
+ elseif marks[nextchar] then
+ nxt=getnext(nxt)
+ else
+ local exit=exitanchors[3]
+ if exit then
+ local entry=exitanchors[1][nextchar]
+ if entry then
+ entry=entry[2]
+ if entry then
+ local r2lflag=sequence.flags[4]
+ local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag)
+ if trace_cursive then
+ logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode))
+ end
+ return head,start,true
+ end
+ end
+ end
+ break
+ end
+ end
+ end
+ return head,start,false
+end
+local chainprocs={}
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ if trace_steps=="silent" then
+ return
+ end
+ end
+ report_subchain(...)
+end
+local logwarning=report_subchain
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ if trace_steps=="silent" then
+ return
+ end
+ end
+ report_chain(...)
+end
+local logwarning=report_chain
+local function reversesub(head,start,stop,dataset,sequence,replacements,rlmode,skiphash)
+ local char=getchar(start)
+ local replacement=replacements[char]
+ if replacement then
+ if trace_singles then
+ logprocess("%s: single reverse replacement of %s by %s",cref(dataset,sequence),gref(char),gref(replacement))
+ end
+ resetinjection(start)
+ setchar(start,replacement)
+ return head,start,true
+ else
+ return head,start,false
+ end
+end
+chainprocs.reversesub=reversesub
+local function reportzerosteps(dataset,sequence)
+ logwarning("%s: no steps",cref(dataset,sequence))
+end
+local function reportmoresteps(dataset,sequence)
+ logwarning("%s: more than 1 step",cref(dataset,sequence))
+end
+local function getmapping(dataset,sequence,currentlookup)
+ local steps=currentlookup.steps
+ local nofsteps=currentlookup.nofsteps
+ if nofsteps==0 then
+ reportzerosteps(dataset,sequence)
+ currentlookup.mapping=false
+ return false
+ else
+ if nofsteps>1 then
+ reportmoresteps(dataset,sequence)
+ end
+ local mapping=steps[1].coverage
+ currentlookup.mapping=mapping
+ currentlookup.format=steps[1].format
+ return mapping
+ end
+end
+function chainprocs.gsub_remove(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ if trace_chains then
+ logprocess("%s: removing character %s",cref(dataset,sequence,chainindex),gref(getchar(start)))
+ end
+ head,start=remove_node(head,start,true)
+ return head,getprev(start),true
+end
+function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local current=start
+ while current do
+ local currentchar=ischar(current)
+ if currentchar then
+ local replacement=mapping[currentchar]
+ if not replacement or replacement=="" then
+ if trace_bugs then
+ logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar))
+ end
+ else
+ if trace_singles then
+ logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement))
+ end
+ resetinjection(current)
+ setchar(current,replacement)
+ end
+ return head,start,true
+ elseif currentchar==false then
+ break
+ elseif current==stop then
+ break
+ else
+ current=getnext(current)
+ end
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local kind=dataset[4]
+ local what=dataset[1]
+ local value=what==true and tfmdata.shared.features[kind] or what
+ local current=start
+ while current do
+ local currentchar=ischar(current)
+ if currentchar then
+ local alternatives=mapping[currentchar]
+ if alternatives then
+ local choice,comment=get_alternative_glyph(current,alternatives,value)
+ if choice then
+ if trace_alternatives then
+ logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(currentchar),choice,gref(choice),comment)
+ end
+ resetinjection(start)
+ setchar(start,choice)
+ else
+ if trace_alternatives then
+ logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(currentchar),comment)
+ end
+ end
+ end
+ return head,start,true
+ elseif currentchar==false then
+ break
+ elseif current==stop then
+ break
+ else
+ current=getnext(current)
+ end
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local replacement=mapping[startchar]
+ if not replacement or replacement=="" then
+ if trace_bugs then
+ logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar))
+ end
+ else
+ if trace_multiples then
+ logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement))
+ end
+ return multiple_glyphs(head,start,replacement,skiphash,dataset[1],stop)
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local ligatures=mapping[startchar]
+ if not ligatures then
+ if trace_bugs then
+ logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar))
+ end
+ else
+ local hasmarks=marks[startchar]
+ local current=getnext(start)
+ local discfound=false
+ local last=stop
+ local nofreplacements=1
+ while current do
+ local id=getid(current)
+ if id==disc_code then
+ if not discfound then
+ discfound=current
+ end
+ if current==stop then
+ break
+ else
+ current=getnext(current)
+ end
+ else
+ local schar=getchar(current)
+ if skiphash and skiphash[schar] then
+ current=getnext(current)
+ else
+ local lg=ligatures[schar]
+ if lg then
+ ligatures=lg
+ last=current
+ nofreplacements=nofreplacements+1
+ if marks[char] then
+ hasmarks=true
+ end
+ if current==stop then
+ break
+ else
+ current=getnext(current)
+ end
+ else
+ break
+ end
+ end
+ end
+ end
+ local ligature=ligatures.ligature
+ if ligature then
+ if chainindex then
+ stop=last
+ end
+ if trace_ligatures then
+ if start==stop then
+ logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature))
+ else
+ logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature))
+ end
+ end
+ head,start=toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks)
+ return head,start,true,nofreplacements,discfound
+ elseif trace_bugs then
+ if start==stop then
+ logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar))
+ else
+ logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)))
+ end
+ end
+ end
+ end
+ return head,start,false,0,false
+end
+function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local kerns=mapping[startchar]
+ if kerns then
+ local format=currentlookup.format
+ if format=="single" then
+ local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else
+ local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ end
+ end
+ return head,start,true
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local snext=getnext(start)
+ if snext then
+ local startchar=getchar(start)
+ local kerns=mapping[startchar]
+ if kerns then
+ local prev=start
+ while snext do
+ local nextchar=ischar(snext,currentfont)
+ if not nextchar then
+ break
+ end
+ if skiphash and skiphash[nextchar] then
+ prev=snext
+ snext=getnext(snext)
+ else
+ local krn=kerns[nextchar]
+ if not krn then
+ break
+ end
+ local format=currentlookup.format
+ if format=="pair" then
+ local a=krn[1]
+ local b=krn[2]
+ if a==true then
+ elseif a then
+ local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections")
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ if b==true then
+ start=snext
+ elseif b then
+ local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections")
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ start=snext
+ elseif forcepairadvance then
+ start=snext
+ end
+ return head,start,true
+ elseif krn~=0 then
+ local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn)
+ if trace_kerns then
+ logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
+ end
+ return head,start,true
+ else
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local markanchors=mapping[markchar]
+ if markanchors then
+ local base=getprev(start)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base=getprev(base)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
+ end
+ return head,start,false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
+ end
+ return head,start,false
+ end
+ end
+ end
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ if ma then
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)",
+ cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head,start,true
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar))
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local markanchors=mapping[markchar]
+ if markanchors then
+ local base=getprev(start)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base=getprev(base)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1)
+ end
+ return head,start,false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2)
+ end
+ return head,start,false
+ end
+ end
+ end
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ if ma then
+ local index=getligaindex(start)
+ ba=ba[index]
+ if ba then
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)",
+ cref(dataset,sequence),a or bound,gref(markchar),gref(basechar),index,dx,dy)
+ end
+ return head,start,true
+ end
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar))
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local markanchors=mapping[markchar]
+ if markanchors then
+ local base=getprev(start)
+ local slc=getligaindex(start)
+ if slc then
+ while base do
+ local blc=getligaindex(base)
+ if blc and blc~=slc then
+ base=getprev(base)
+ else
+ break
+ end
+ end
+ end
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ if ma then
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)",
+ cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head,start,true
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar))
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local exitanchors=mapping[startchar]
+ if exitanchors then
+ if marks[startchar] then
+ if trace_cursive then
+ logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar))
+ end
+ else
+ local nxt=getnext(start)
+ while nxt do
+ local nextchar=ischar(nxt,currentfont)
+ if not nextchar then
+ break
+ elseif marks[nextchar] then
+ nxt=getnext(nxt)
+ else
+ local exit=exitanchors[3]
+ if exit then
+ local entry=exitanchors[1][nextchar]
+ if entry then
+ entry=entry[2]
+ if entry then
+ local r2lflag=sequence.flags[4]
+ local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag)
+ if trace_cursive then
+ logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode))
+ end
+ return head,start,true
+ end
+ end
+ elseif trace_bugs then
+ onetimemessage(currentfont,startchar,"no entry anchors",report_fonts)
+ end
+ break
+ end
+ end
+ end
+ elseif trace_cursive and trace_details then
+ logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone)
+ end
+ end
+ return head,start,false
+end
+local function show_skip(dataset,sequence,char,ck,class)
+ logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2])
+end
+local userkern=nuts.pool and nuts.pool.newkern
+do if not userkern then
+ local thekern=nuts.new("kern",1)
+ local setkern=nuts.setkern
+ userkern=function(k)
+ local n=copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
+end end
+local function checked(head)
+ local current=head
+ while current do
+ if getid(current)==glue_code then
+ local kern=userkern(getwidth(current))
+ if head==current then
+ local next=getnext(current)
+ if next then
+ setlink(kern,next)
+ end
+ flush_node(current)
+ head=kern
+ current=next
+ else
+ local prev,next=getboth(current)
+ setlink(prev,kern,next)
+ flush_node(current)
+ current=next
+ end
+ else
+ current=getnext(current)
+ end
+ end
+ return head
+end
+local function setdiscchecked(d,pre,post,replace)
+ if pre then pre=checked(pre) end
+ if post then post=checked(post) end
+ if replace then replace=checked(replace) end
+ setdisc(d,pre,post,replace)
+end
+local noflags={ false,false,false,false }
+local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
+ local size=ck[5]-ck[4]+1
+ local chainlookups=ck[6]
+ local done=false
+ if chainlookups then
+ if size==1 then
+ local chainlookup=chainlookups[1]
+ 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,skiphash)
+ if ok then
+ done=true
+ end
+ else
+ logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind)
+ end
+ end
+ else
+ local i=1
+ local laststart=start
+ local nofchainlookups=#chainlookups
+ while start do
+ if skiphash then
+ while start do
+ local char=ischar(start,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ end
+ local chainlookup=chainlookups[i]
+ if chainlookup then
+ 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,skiphash,i)
+ if ok then
+ done=true
+ if n and n>1 and i+n>nofchainlookups then
+ i=size
+ break
+ end
+ end
+ else
+ logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
+ end
+ end
+ else
+ end
+ i=i+1
+ if i>size or not start then
+ break
+ elseif start then
+ laststart=start
+ start=getnext(start)
+ end
+ end
+ if not start then
+ start=laststart
+ end
+ end
+ else
+ local replacements=ck[7]
+ if replacements then
+ head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode,skiphash)
+ else
+ done=true
+ if trace_contexts then
+ logprocess("%s: skipping match",cref(dataset,sequence))
+ end
+ end
+ end
+ return head,start,done
+end
+local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
+ if not start then
+ return head,start,false
+ end
+ local startishead=start==head
+ local seq=ck[3]
+ local f=ck[4]
+ local l=ck[5]
+ local s=#seq
+ local done=false
+ local sweepnode=sweepnode
+ local sweeptype=sweeptype
+ local sweepoverflow=false
+ local keepdisc=not sweepnode
+ local lookaheaddisc=nil
+ local backtrackdisc=nil
+ local current=start
+ local last=start
+ local prev=getprev(start)
+ local hasglue=false
+ local i=f
+ while i<=l do
+ local id=getid(current)
+ if id==glyph_code then
+ i=i+1
+ last=current
+ current=getnext(current)
+ elseif id==glue_code then
+ i=i+1
+ last=current
+ current=getnext(current)
+ hasglue=true
+ elseif id==disc_code then
+ if keepdisc then
+ keepdisc=false
+ lookaheaddisc=current
+ local replace=getfield(current,"replace")
+ if not replace then
+ sweepoverflow=true
+ sweepnode=current
+ current=getnext(current)
+ else
+ while replace and i<=l do
+ if getid(replace)==glyph_code then
+ i=i+1
+ end
+ replace=getnext(replace)
+ end
+ current=getnext(replace)
+ end
+ last=current
+ else
+ head,current=flattendisk(head,current)
+ end
+ else
+ last=current
+ current=getnext(current)
+ end
+ if current then
+ elseif sweepoverflow then
+ break
+ elseif sweeptype=="post" or sweeptype=="replace" then
+ current=getnext(sweepnode)
+ if current then
+ sweeptype=nil
+ sweepoverflow=true
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if sweepoverflow then
+ local prev=current and getprev(current)
+ if not current or prev~=sweepnode then
+ local head=getnext(sweepnode)
+ local tail=nil
+ if prev then
+ tail=prev
+ setprev(current,sweepnode)
+ else
+ tail=find_node_tail(head)
+ end
+ setnext(sweepnode,current)
+ setprev(head)
+ setnext(tail)
+ appenddisc(sweepnode,head)
+ end
+ end
+ if l<s then
+ local i=l
+ local t=sweeptype=="post" or sweeptype=="replace"
+ while current and i<s do
+ local id=getid(current)
+ if id==glyph_code then
+ i=i+1
+ current=getnext(current)
+ elseif id==glue_code then
+ i=i+1
+ current=getnext(current)
+ hasglue=true
+ elseif id==disc_code then
+ if keepdisc then
+ keepdisc=false
+ if notmatchpre[current]~=notmatchreplace[current] then
+ lookaheaddisc=current
+ end
+ local replace=getfield(current,"replace")
+ while replace and i<s do
+ if getid(replace)==glyph_code then
+ i=i+1
+ end
+ replace=getnext(replace)
+ end
+ current=getnext(current)
+ elseif notmatchpre[current]~=notmatchreplace[current] then
+ head,current=flattendisk(head,current)
+ else
+ current=getnext(current)
+ end
+ else
+ current=getnext(current)
+ end
+ if not current and t then
+ current=getnext(sweepnode)
+ if current then
+ sweeptype=nil
+ end
+ end
+ end
+ end
+ if f>1 then
+ local current=prev
+ local i=f
+ local t=sweeptype=="pre" or sweeptype=="replace"
+ if not current and t and current==checkdisk then
+ current=getprev(sweepnode)
+ end
+ while current and i>1 do
+ local id=getid(current)
+ if id==glyph_code then
+ i=i-1
+ elseif id==glue_code then
+ i=i-1
+ hasglue=true
+ elseif id==disc_code then
+ if keepdisc then
+ keepdisc=false
+ if notmatchpost[current]~=notmatchreplace[current] then
+ backtrackdisc=current
+ end
+ local replace=getfield(current,"replace")
+ while replace and i>1 do
+ if getid(replace)==glyph_code then
+ i=i-1
+ end
+ replace=getnext(replace)
+ end
+ elseif notmatchpost[current]~=notmatchreplace[current] then
+ head,current=flattendisk(head,current)
+ end
+ end
+ current=getprev(current)
+ if t and current==checkdisk then
+ current=getprev(sweepnode)
+ end
+ end
+ end
+ local done=false
+ if lookaheaddisc then
+ local cf=start
+ local cl=getprev(lookaheaddisc)
+ local cprev=getprev(start)
+ local insertedmarks=0
+ while cprev do
+ local char=ischar(cf,currentfont)
+ if char and marks[char] then
+ insertedmarks=insertedmarks+1
+ cf=cprev
+ startishead=cf==head
+ cprev=getprev(cprev)
+ else
+ break
+ end
+ end
+ setlink(cprev,lookaheaddisc)
+ setprev(cf)
+ setnext(cl)
+ if startishead then
+ head=lookaheaddisc
+ end
+ local pre,post,replace=getdisc(lookaheaddisc)
+ local new=copy_node_list(cf)
+ local cnew=new
+ if pre then
+ setlink(find_node_tail(cf),pre)
+ end
+ if replace then
+ local tail=find_node_tail(new)
+ setlink(tail,replace)
+ end
+ for i=1,insertedmarks do
+ cnew=getnext(cnew)
+ end
+ cl=start
+ local clast=cnew
+ for i=f,l do
+ cl=getnext(cl)
+ clast=getnext(clast)
+ end
+ if not notmatchpre[lookaheaddisc] then
+ local ok=false
+ cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ if not notmatchreplace[lookaheaddisc] then
+ local ok=false
+ new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ if hasglue then
+ setdiscchecked(lookaheaddisc,cf,post,new)
+ else
+ setdisc(lookaheaddisc,cf,post,new)
+ end
+ start=getprev(lookaheaddisc)
+ sweephead[cf]=getnext(clast) or false
+ sweephead[new]=getnext(cl) or false
+ elseif backtrackdisc then
+ local cf=getnext(backtrackdisc)
+ local cl=start
+ local cnext=getnext(start)
+ local insertedmarks=0
+ while cnext do
+ local char=ischar(cnext,currentfont)
+ if char and marks[char] then
+ insertedmarks=insertedmarks+1
+ cl=cnext
+ cnext=getnext(cnext)
+ else
+ break
+ end
+ end
+ setlink(backtrackdisc,cnext)
+ setprev(cf)
+ setnext(cl)
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true)
+ local new=copy_node_list(cf)
+ local cnew=find_node_tail(new)
+ for i=1,insertedmarks do
+ cnew=getprev(cnew)
+ end
+ local clast=cnew
+ for i=f,l do
+ clast=getnext(clast)
+ end
+ if not notmatchpost[backtrackdisc] then
+ local ok=false
+ cf,start,ok=chainrun(cf,start,last,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ if not notmatchreplace[backtrackdisc] then
+ local ok=false
+ new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ if post then
+ setlink(posttail,cf)
+ else
+ post=cf
+ end
+ if replace then
+ setlink(replacetail,new)
+ else
+ replace=new
+ end
+ if hasglue then
+ setdiscchecked(backtrackdisc,pre,post,replace)
+ else
+ setdisc(backtrackdisc,pre,post,replace)
+ end
+ start=getprev(backtrackdisc)
+ sweephead[post]=getnext(clast) or false
+ sweephead[replace]=getnext(last) or false
+ else
+ local ok=false
+ head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ return head,start,done
+end
+local function chaintrac(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode)
+ local rule=ck[1]
+ local lookuptype=ck[8] or ck[2]
+ local nofseq=#ck[3]
+ local first=ck[4]
+ local last=ck[5]
+ local char=getchar(start)
+ logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping",
+ cref(dataset,sequence),rule,match and "matches" or "nomatch",
+ gref(char),first-1,last-first+1,nofseq-last,lookuptype,
+ discseen and "" or "no ",sweepnode and "" or "not ")
+end
+local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash)
+ local sweepnode=sweepnode
+ local sweeptype=sweeptype
+ local postreplace
+ local prereplace
+ local checkdisc
+ local discseen
+ if sweeptype then
+ if sweeptype=="replace" then
+ postreplace=true
+ prereplace=true
+ else
+ postreplace=sweeptype=="post"
+ prereplace=sweeptype=="pre"
+ end
+ checkdisc=getprev(head)
+ end
+ local currentfont=currentfont
+ local skipped
+ local startprev,
+ startnext=getboth(start)
+ local done
+ local nofcontexts=contexts.n
+ local startchar=nofcontext==1 or ischar(start,currentfont)
+ for k=1,nofcontexts do
+ local ck=contexts[k]
+ local seq=ck[3]
+ local f=ck[4]
+ if not startchar or not seq[f][startchar] then
+ goto next
+ end
+ local s=seq.n
+ local l=ck[5]
+ local current=start
+ local last=start
+ if l>f then
+ local discfound
+ local n=f+1
+ last=startnext
+ while n<=l do
+ if postreplace and not last then
+ last=getnext(sweepnode)
+ sweeptype=nil
+ end
+ if last then
+ local char,id=ischar(last,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped=true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ last=getnext(last)
+ elseif seq[n][char] then
+ if n<l then
+ last=getnext(last)
+ end
+ n=n+1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif char==false then
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif id==disc_code then
+ discseen=true
+ discfound=last
+ notmatchpre[last]=nil
+ notmatchpost[last]=true
+ notmatchreplace[last]=nil
+ local pre,post,replace=getdisc(last)
+ if pre then
+ local n=n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n=n+1
+ if n>l then
+ break
+ end
+ pre=getnext(pre)
+ else
+ notmatchpre[last]=true
+ break
+ end
+ end
+ else
+ notmatchpre[last]=true
+ end
+ if replace then
+ while replace do
+ if seq[n][getchar(replace)] then
+ n=n+1
+ if n>l then
+ break
+ end
+ replace=getnext(replace)
+ else
+ notmatchreplace[last]=true
+ if notmatchpre[last] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ if notmatchpre[last] then
+ goto next
+ end
+ end
+ last=getnext(last)
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+ end
+ if f>1 then
+ if startprev then
+ local prev=startprev
+ if prereplace and prev==checkdisc then
+ prev=getprev(sweepnode)
+ end
+ if prev then
+ local discfound
+ local n=f-1
+ while n>=1 do
+ if prev then
+ local char,id=ischar(prev,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped=true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ prev=getprev(prev)
+ elseif seq[n][char] then
+ if n>1 then
+ prev=getprev(prev)
+ end
+ n=n-1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpost[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif char==false then
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpost[discfound] then
+ goto next
+ end
+ else
+ goto next
+ end
+ break
+ elseif id==disc_code then
+ discseen=true
+ discfound=prev
+ notmatchpre[prev]=true
+ notmatchpost[prev]=nil
+ notmatchreplace[prev]=nil
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true)
+ if pre~=start and post~=start and replace~=start then
+ if post then
+ local n=n
+ while posttail do
+ if seq[n][getchar(posttail)] then
+ n=n-1
+ if posttail==post or n<1 then
+ break
+ else
+ posttail=getprev(posttail)
+ end
+ else
+ notmatchpost[prev]=true
+ break
+ end
+ end
+ if n>=1 then
+ notmatchpost[prev]=true
+ end
+ else
+ notmatchpost[prev]=true
+ end
+ if replace then
+ while replacetail do
+ if seq[n][getchar(replacetail)] then
+ n=n-1
+ if replacetail==replace or n<1 then
+ break
+ else
+ replacetail=getprev(replacetail)
+ end
+ else
+ notmatchreplace[prev]=true
+ if notmatchpost[prev] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ else
+ end
+ end
+ prev=getprev(prev)
+ elseif id==glue_code then
+ local sn=seq[n]
+ if (sn[32] and spaces[prev]) or sn[0xFFFC] then
+ n=n-1
+ prev=getprev(prev)
+ else
+ goto next
+ end
+ elseif seq[n][0xFFFC] then
+ n=n-1
+ prev=getprev(prev)
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+ if s>l then
+ local current=last and getnext(last)
+ if not current and postreplace then
+ current=getnext(sweepnode)
+ end
+ if current then
+ local discfound
+ local n=l+1
+ while n<=s do
+ if current then
+ local char,id=ischar(current,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped=true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ current=getnext(current)
+ elseif seq[n][char] then
+ if n<s then
+ current=getnext(current)
+ end
+ n=n+1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif char==false then
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif id==disc_code then
+ discseen=true
+ discfound=current
+ notmatchpre[current]=nil
+ notmatchpost[current]=true
+ notmatchreplace[current]=nil
+ local pre,post,replace=getdisc(current)
+ if pre then
+ local n=n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n=n+1
+ if n>s then
+ break
+ else
+ pre=getnext(pre)
+ end
+ else
+ notmatchpre[current]=true
+ break
+ end
+ end
+ if n<=s then
+ notmatchpre[current]=true
+ end
+ else
+ notmatchpre[current]=true
+ end
+ if replace then
+ while replace do
+ if seq[n][getchar(replace)] then
+ n=n+1
+ if n>s then
+ break
+ else
+ replace=getnext(replace)
+ end
+ else
+ notmatchreplace[current]=true
+ if notmatchpre[current] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ else
+ end
+ current=getnext(current)
+ elseif id==glue_code then
+ local sn=seq[n]
+ if (sn[32] and spaces[current]) or sn[0xFFFC] then
+ n=n+1
+ current=getnext(current)
+ else
+ goto next
+ end
+ elseif seq[n][0xFFFC] then
+ n=n+1
+ current=getnext(current)
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+ else
+ goto next
+ end
+ end
+ if trace_contexts then
+ chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode)
+ end
+ if discseen or sweepnode then
+ head,start,done=chaindisk(head,start,dataset,sequence,rlmode,skipped and skiphash,ck)
+ else
+ head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck)
+ end
+ if done then
+ break
+ end
+ ::next::
+ end
+ if discseen then
+ notmatchpre={}
+ notmatchpost={}
+ notmatchreplace={}
+ end
+ return head,start,done
+end
+handlers.gsub_context=handle_contextchain
+handlers.gsub_contextchain=handle_contextchain
+handlers.gsub_reversecontextchain=handle_contextchain
+handlers.gpos_contextchain=handle_contextchain
+handlers.gpos_context=handle_contextchain
+local function chained_contextchain(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash)
+ local steps=currentlookup.steps
+ local nofsteps=currentlookup.nofsteps
+ if nofsteps>1 then
+ reportmoresteps(dataset,sequence)
+ end
+ local l=steps[1].coverage[getchar(start)]
+ if l then
+ return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash)
+ else
+ return head,start,false
+ end
+end
+chainprocs.gsub_context=chained_contextchain
+chainprocs.gsub_contextchain=chained_contextchain
+chainprocs.gsub_reversecontextchain=chained_contextchain
+chainprocs.gpos_contextchain=chained_contextchain
+chainprocs.gpos_context=chained_contextchain
+local missing=setmetatableindex("table")
+local logwarning=report_process
+local resolved={}
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ if trace_steps=="silent" then
+ return
+ end
+ end
+ report_process(...)
+end
+local sequencelists=setmetatableindex(function(t,font)
+ local sequences=fontdata[font].resources.sequences
+ if not sequences or not next(sequences) then
+ sequences=false
+ end
+ t[font]=sequences
+ return sequences
+end)
+do
+ local autofeatures=fonts.analyzers.features
+ local featuretypes=otf.tables.featuretypes
+ local defaultscript=otf.features.checkeddefaultscript
+ local defaultlanguage=otf.features.checkeddefaultlanguage
+ local wildcard="*"
+ local default="dflt"
+ local function initialize(sequence,script,language,enabled,autoscript,autolanguage)
+ local features=sequence.features
+ if features then
+ local order=sequence.order
+ if order then
+ local featuretype=featuretypes[sequence.type or "unknown"]
+ for i=1,#order do
+ local kind=order[i]
+ local valid=enabled[kind]
+ if valid then
+ local scripts=features[kind]
+ local languages=scripts and (
+ scripts[script] or
+ scripts[wildcard] or
+ (autoscript and defaultscript(featuretype,autoscript,scripts))
+ )
+ local enabled=languages and (
+ languages[language] or
+ languages[wildcard] or
+ (autolanguage and defaultlanguage(featuretype,autolanguage,languages))
+ )
+ if enabled then
+ return { valid,autofeatures[kind] or false,sequence,kind }
+ end
+ end
+ end
+ else
+ end
+ end
+ return false
+ end
+ function otf.dataset(tfmdata,font)
+ local shared=tfmdata.shared
+ local properties=tfmdata.properties
+ local language=properties.language or "dflt"
+ local script=properties.script or "dflt"
+ local enabled=shared.features
+ local autoscript=enabled and enabled.autoscript
+ local autolanguage=enabled and enabled.autolanguage
+ local res=resolved[font]
+ if not res then
+ res={}
+ resolved[font]=res
+ end
+ local rs=res[script]
+ if not rs then
+ rs={}
+ res[script]=rs
+ end
+ local rl=rs[language]
+ if not rl then
+ rl={
+ }
+ rs[language]=rl
+ local sequences=tfmdata.resources.sequences
+ if sequences then
+ for s=1,#sequences do
+ local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage)
+ if v then
+ rl[#rl+1]=v
+ end
+ end
+ end
+ end
+ return rl
+ end
+end
+local function report_disc(what,n)
+ report_run("%s: %s > %s",what,n,languages.serializediscretionary(n))
+end
+local function kernrun(disc,k_run,font,attr,...)
+ if trace_kernruns then
+ report_disc("kern",disc)
+ end
+ local prev,next=getboth(disc)
+ local nextstart=next
+ local done=false
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
+ local prevmarks=prev
+ while prevmarks do
+ local char=ischar(prevmarks,font)
+ if char and marks[char] then
+ prevmarks=getprev(prevmarks)
+ else
+ break
+ end
+ end
+ if prev and not ischar(prev,font) then
+ prev=false
+ end
+ if next and not ischar(next,font) then
+ next=false
+ end
+ if pre then
+ if k_run(pre,"injections",nil,font,attr,...) then
+ done=true
+ end
+ if prev then
+ setlink(prev,pre)
+ if k_run(prevmarks,"preinjections",pre,font,attr,...) then
+ done=true
+ end
+ setprev(pre)
+ setlink(prev,disc)
+ end
+ end
+ if post then
+ if k_run(post,"injections",nil,font,attr,...) then
+ done=true
+ end
+ if next then
+ setlink(posttail,next)
+ if k_run(posttail,"postinjections",next,font,attr,...) then
+ done=true
+ end
+ setnext(posttail)
+ setlink(disc,next)
+ end
+ end
+ if replace then
+ if k_run(replace,"injections",nil,font,attr,...) then
+ done=true
+ end
+ if prev then
+ setlink(prev,replace)
+ if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then
+ done=true
+ end
+ setprev(replace)
+ setlink(prev,disc)
+ end
+ if next then
+ setlink(replacetail,next)
+ if k_run(replacetail,"replaceinjections",next,font,attr,...) then
+ done=true
+ end
+ setnext(replacetail)
+ setlink(disc,next)
+ end
+ elseif prev and next then
+ setlink(prev,next)
+ if k_run(prevmarks,"emptyinjections",next,font,attr,...) then
+ done=true
+ end
+ setlink(prev,disc,next)
+ end
+ if done and trace_testruns then
+ report_disc("done",disc)
+ end
+ return nextstart,done
+end
+local function comprun(disc,c_run,...)
+ if trace_compruns then
+ report_disc("comp",disc)
+ end
+ local pre,post,replace=getdisc(disc)
+ local renewed=false
+ if pre then
+ sweepnode=disc
+ sweeptype="pre"
+ local new,done=c_run(pre,...)
+ if done then
+ pre=new
+ renewed=true
+ end
+ end
+ if post then
+ sweepnode=disc
+ sweeptype="post"
+ local new,done=c_run(post,...)
+ if done then
+ post=new
+ renewed=true
+ end
+ end
+ if replace then
+ sweepnode=disc
+ sweeptype="replace"
+ local new,done=c_run(replace,...)
+ if done then
+ replace=new
+ renewed=true
+ end
+ end
+ sweepnode=nil
+ sweeptype=nil
+ if renewed then
+ if trace_testruns then
+ report_disc("done",disc)
+ end
+ setdisc(disc,pre,post,replace)
+ end
+ return getnext(disc),renewed
+end
+local function testrun(disc,t_run,c_run,...)
+ if trace_testruns then
+ report_disc("test",disc)
+ end
+ local prev,next=getboth(disc)
+ if not next then
+ return
+ end
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
+ local renewed=false
+ if (post or replace) then
+ if post then
+ setlink(posttail,next)
+ else
+ post=next
+ end
+ if replace then
+ setlink(replacetail,next)
+ else
+ replace=next
+ end
+ local d_post=t_run(post,next,...)
+ local d_replace=t_run(replace,next,...)
+ if d_post>0 or d_replace>0 then
+ local d=d_replace>d_post and d_replace or d_post
+ local head=getnext(disc)
+ local tail=head
+ for i=2,d do
+ local nx=getnext(tail)
+ local id=getid(nx)
+ if id==disc_code then
+ head,tail=flattendisk(head,nx)
+ elseif id==glyph_code then
+ tail=nx
+ else
+ break
+ end
+ end
+ next=getnext(tail)
+ setnext(tail)
+ setprev(head)
+ local new=copy_node_list(head)
+ if posttail then
+ setlink(posttail,head)
+ else
+ post=head
+ end
+ if replacetail then
+ setlink(replacetail,new)
+ else
+ replace=new
+ end
+ else
+ if posttail then
+ setnext(posttail)
+ else
+ post=nil
+ end
+ if replacetail then
+ setnext(replacetail)
+ else
+ replace=nil
+ end
+ end
+ setlink(disc,next)
+ end
+ if trace_testruns then
+ report_disc("more",disc)
+ end
+ if pre then
+ sweepnode=disc
+ sweeptype="pre"
+ local new,ok=c_run(pre,...)
+ if ok then
+ pre=new
+ renewed=true
+ end
+ end
+ if post then
+ sweepnode=disc
+ sweeptype="post"
+ local new,ok=c_run(post,...)
+ if ok then
+ post=new
+ renewed=true
+ end
+ end
+ if replace then
+ sweepnode=disc
+ sweeptype="replace"
+ local new,ok=c_run(replace,...)
+ if ok then
+ replace=new
+ renewed=true
+ end
+ end
+ sweepnode=nil
+ sweeptype=nil
+ if renewed then
+ setdisc(disc,pre,post,replace)
+ if trace_testruns then
+ report_disc("done",disc)
+ end
+ end
+ return getnext(disc),renewed
+end
+local nesting=0
+local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ local done=false
+ local sweep=sweephead[head]
+ if sweep then
+ start=sweep
+ sweephead[head]=false
+ else
+ start=head
+ end
+ while start do
+ local char,id=ischar(start,font)
+ if char then
+ local a
+ if attr then
+ a=getglyphdata(start)
+ end
+ if not a or (a==attr) then
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ done=true
+ end
+ end
+ if start then
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ elseif char==false then
+ return head,done
+ elseif sweep then
+ return head,done
+ else
+ start=getnext(start)
+ end
+ end
+ return head,done
+end
+local function t_run_single(start,stop,font,attr,lookupcache)
+ local lastd=nil
+ while start~=stop do
+ local char=ischar(start,font)
+ if char then
+ local a
+ if attr then
+ a=getglyphdata(start)
+ end
+ local startnext=getnext(start)
+ if not a or (a==attr) then
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local s=startnext
+ local ss=nil
+ local sstop=s==stop
+ if not s then
+ s=ss
+ ss=nil
+ end
+ while getid(s)==disc_code do
+ ss=getnext(s)
+ s=getfield(s,"replace")
+ if not s then
+ s=ss
+ ss=nil
+ end
+ end
+ local l=nil
+ local d=0
+ while s do
+ local char=ischar(s,font)
+ if char then
+ local lg=lookupmatch[char]
+ if lg then
+ if sstop then
+ d=1
+ elseif d>0 then
+ d=d+1
+ end
+ l=lg
+ s=getnext(s)
+ sstop=s==stop
+ if not s then
+ s=ss
+ ss=nil
+ end
+ while getid(s)==disc_code do
+ ss=getnext(s)
+ s=getfield(s,"replace")
+ if not s then
+ s=ss
+ ss=nil
+ end
+ end
+lookupmatch=lg
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if l and l.ligature then
+ lastd=d
+ end
+ else
+ end
+ else
+ end
+ if lastd then
+ return lastd
+ end
+ start=startnext
+ else
+ break
+ end
+ end
+ return 0
+end
+local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ local a
+ if attr then
+ a=getglyphdata(sub)
+ end
+ if not a or (a==attr) then
+ for n in nextnode,sub do
+ if n==last then
+ break
+ end
+ local char=ischar(n)
+ if char then
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection)
+ if ok then
+ return true
+ end
+ end
+ end
+ end
+ end
+end
+local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ local done=false
+ local sweep=sweephead[head]
+ if sweep then
+ start=sweep
+ sweephead[head]=false
+ else
+ start=head
+ end
+ while start do
+ local char=ischar(start,font)
+ if char then
+ local a
+ if attr then
+ a=getglyphdata(start)
+ end
+ if not a or (a==attr) then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ done=true
+ break
+ elseif not start then
+ break
+ end
+ end
+ end
+ if start then
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ elseif char==false then
+ return head,done
+ elseif sweep then
+ return head,done
+ else
+ start=getnext(start)
+ end
+ end
+ return head,done
+end
+local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
+ local lastd=nil
+ while start~=stop do
+ local char=ischar(start,font)
+ if char then
+ local a
+ if attr then
+ a=getglyphdata(start)
+ end
+ local startnext=getnext(start)
+ if not a or (a==attr) then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local s=startnext
+ local ss=nil
+ local sstop=s==stop
+ if not s then
+ s=ss
+ ss=nil
+ end
+ while getid(s)==disc_code do
+ ss=getnext(s)
+ s=getfield(s,"replace")
+ if not s then
+ s=ss
+ ss=nil
+ end
+ end
+ local l=nil
+ local d=0
+ while s do
+ local char=ischar(s)
+ if char then
+ local lg=lookupmatch[char]
+ if lg then
+ if sstop then
+ d=1
+ elseif d>0 then
+ d=d+1
+ end
+ l=lg
+ s=getnext(s)
+ sstop=s==stop
+ if not s then
+ s=ss
+ ss=nil
+ end
+ while getid(s)==disc_code do
+ ss=getnext(s)
+ s=getfield(s,"replace")
+ if not s then
+ s=ss
+ ss=nil
+ end
+ end
+lookupmatch=lg
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if l and l.ligature then
+ lastd=d
+ end
+ end
+ end
+ else
+ end
+ if lastd then
+ return lastd
+ end
+ start=startnext
+ else
+ break
+ end
+ end
+ return 0
+end
+local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ local a
+ if attr then
+ a=getglyphdata(sub)
+ end
+ if not a or (a==attr) then
+ for n in nextnode,sub do
+ if n==last then
+ break
+ end
+ local char=ischar(n)
+ if char then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection)
+ if ok then
+ return true
+ end
+ end
+ end
+ end
+ end
+ end
+end
+local txtdirstate,pardirstate do
+ local getdirection=nuts.getdirection
+ local lefttoright=0
+ local righttoleft=1
+ txtdirstate=function(start,stack,top,rlparmode)
+ local dir,pop=getdirection(start)
+ if pop then
+ if top==1 then
+ return 0,rlparmode
+ else
+ top=top-1
+ if stack[top]==righttoleft then
+ return top,-1
+ else
+ return top,1
+ end
+ end
+ elseif dir==lefttoright then
+ top=top+1
+ stack[top]=lefttoright
+ return top,1
+ elseif dir==righttoleft then
+ top=top+1
+ stack[top]=righttoleft
+ return top,-1
+ else
+ return top,rlparmode
+ end
+ end
+ pardirstate=function(start)
+ local dir=getdirection(start)
+ if dir==lefttoright then
+ return 1,1
+ elseif dir==righttoleft then
+ return -1,-1
+ elseif dir=="TLT" then
+ return 1,1
+ elseif dir=="TRT" then
+ return -1,-1
+ else
+ return 0,0
+ end
+ end
+end
+otf.helpers=otf.helpers or {}
+otf.helpers.txtdirstate=txtdirstate
+otf.helpers.pardirstate=pardirstate
+do
+ local fastdisc=true
+ local testdics=false
+ directives.register("otf.fastdisc",function(v) fastdisc=v end)
+ local otfdataset=nil
+ local getfastdisc={ __index=function(t,k)
+ local v=usesfont(k,currentfont)
+ t[k]=v
+ return v
+ end }
+ local getfastspace={ __index=function(t,k)
+ local v=isspace(k,threshold) or false
+ t[k]=v
+ return v
+ end }
+ function otf.featuresprocessor(head,font,attr,direction,n)
+ local sequences=sequencelists[font]
+ nesting=nesting+1
+ if nesting==1 then
+ currentfont=font
+ tfmdata=fontdata[font]
+ descriptions=tfmdata.descriptions
+ characters=tfmdata.characters
+ local resources=tfmdata.resources
+ marks=resources.marks
+ classes=resources.classes
+ threshold,
+ factor=getthreshold(font)
+ checkmarks=tfmdata.properties.checkmarks
+ if not otfdataset then
+ otfdataset=otf.dataset
+ end
+ discs=fastdisc and n and n>1 and setmetatable({},getfastdisc)
+ spaces=setmetatable({},getfastspace)
+ elseif currentfont~=font then
+ report_warning("nested call with a different font, level %s, quitting",nesting)
+ nesting=nesting-1
+ return head,false
+ end
+ if trace_steps then
+ checkstep(head)
+ end
+ local initialrl=0
+ if getid(head)==localpar_code and getsubtype(head)==0 then
+ initialrl=pardirstate(head)
+ elseif direction==1 or direction=="TRT" then
+ initialrl=-1
+ end
+ local datasets=otfdataset(tfmdata,font,attr)
+ local dirstack={ nil }
+ sweephead={}
+ for s=1,#datasets do
+ local dataset=datasets[s]
+ local attribute=dataset[2]
+ local sequence=dataset[3]
+ local rlparmode=initialrl
+ local topstack=0
+ local typ=sequence.type
+ local gpossing=typ=="gpos_single" or typ=="gpos_pair"
+ local forcetestrun=typ=="gsub_ligature"
+ local handler=handlers[typ]
+ local steps=sequence.steps
+ local nofsteps=sequence.nofsteps
+ local skiphash=sequence.skiphash
+ if not steps then
+ local h,ok=handler(head,dataset,sequence,initialrl,font,attr)
+ if h and h~=head then
+ head=h
+ end
+ elseif typ=="gsub_reversecontextchain" then
+ local start=find_node_tail(head)
+ local rlmode=0
+ local merged=steps.merged
+ while start do
+ local char=ischar(start,font)
+ if char then
+ local m=merged[char]
+ if m then
+ local a
+ if attr then
+ a=getglyphdata(start)
+ end
+ if not a or (a==attr) then
+ for i=m[1],m[2] do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ break
+ end
+ end
+ end
+ if start then
+ start=getprev(start)
+ end
+ else
+ start=getprev(start)
+ end
+ else
+ start=getprev(start)
+ end
+ else
+ start=getprev(start)
+ end
+ end
+ else
+ local start=head
+ local rlmode=initialrl
+ if nofsteps==1 then
+ local step=steps[1]
+ local lookupcache=step.coverage
+ while start do
+ local char,id=ischar(start,font)
+ if char then
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local a
+ if attr then
+ if getglyphdata(start)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ a=true
+ end
+ elseif not attribute or getprop(start,a_state)==attribute then
+ a=true
+ end
+ if a then
+ local ok,df
+ head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if df then
+ elseif start then
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ end
+ elseif char==false or id==glue_code then
+ start=getnext(start)
+ elseif id==disc_code then
+ if not discs or discs[start]==true then
+ local ok
+ if gpossing then
+ start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ elseif forcetestrun then
+ start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ else
+ start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ end
+ else
+ start=getnext(start)
+ end
+ elseif id==math_code then
+ start=getnext(end_of_math(start))
+ elseif id==dir_code then
+ topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
+ start=getnext(start)
+ else
+ start=getnext(start)
+ end
+ end
+ else
+ local merged=steps.merged
+ while start do
+ local char,id=ischar(start,font)
+ if char then
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
+ local m=merged[char]
+ if m then
+ local a
+ if attr then
+ if getglyphdata(start)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ a=true
+ end
+ elseif not attribute or getprop(start,a_state)==attribute then
+ a=true
+ end
+ if a then
+ local ok,df
+ for i=m[1],m[2] do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if df then
+ break
+ elseif ok then
+ break
+ elseif not start then
+ break
+ end
+ end
+ end
+ if df then
+ elseif start then
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ end
+ elseif char==false or id==glue_code then
+ start=getnext(start)
+ elseif id==disc_code then
+ if not discs or discs[start]==true then
+ local ok
+ if gpossing then
+ start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ elseif forcetestrun then
+ start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ else
+ start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ end
+ else
+ start=getnext(start)
+ end
+ elseif id==math_code then
+ start=getnext(end_of_math(start))
+ elseif id==dir_code then
+ topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
+ start=getnext(start)
+ else
+ start=getnext(start)
+ end
+ end
+ end
+ end
+ if trace_steps then
+ registerstep(head)
+ end
+ end
+ nesting=nesting-1
+ return head
+ end
+ function otf.datasetpositionprocessor(head,font,direction,dataset)
+ currentfont=font
+ tfmdata=fontdata[font]
+ descriptions=tfmdata.descriptions
+ characters=tfmdata.characters
+ local resources=tfmdata.resources
+ marks=resources.marks
+ classes=resources.classes
+ threshold,
+ factor=getthreshold(font)
+ checkmarks=tfmdata.properties.checkmarks
+ if type(dataset)=="number" then
+ dataset=otfdataset(tfmdata,font,0)[dataset]
+ end
+ local sequence=dataset[3]
+ local typ=sequence.type
+ local handler=handlers[typ]
+ local steps=sequence.steps
+ local nofsteps=sequence.nofsteps
+ local done=false
+ local dirstack={ nil }
+ local start=head
+ local initialrl=(direction==1 or direction=="TRT") and -1 or 0
+ local rlmode=initialrl
+ local rlparmode=initialrl
+ local topstack=0
+ local merged=steps.merged
+ local position=0
+ while start do
+ local char,id=ischar(start,font)
+ if char then
+ position=position+1
+ local m=merged[char]
+ if m then
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
+ for i=m[1],m[2] do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ break
+ elseif not start then
+ break
+ end
+ end
+ end
+ if start then
+ start=getnext(start)
+ end
+ end
+ else
+ start=getnext(start)
+ end
+ elseif char==false or id==glue_code then
+ start=getnext(start)
+ elseif id==math_code then
+ start=getnext(end_of_math(start))
+ elseif id==dir_code then
+ topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
+ start=getnext(start)
+ else
+ start=getnext(start)
+ end
+ end
+ return head
+ end
+end
+local plugins={}
+otf.plugins=plugins
+local report=logs.reporter("fonts")
+function otf.registerplugin(name,f)
+ if type(name)=="string" and type(f)=="function" then
+ plugins[name]={ name,f }
+ report()
+ report("plugin %a has been loaded, please be aware of possible side effects",name)
+ report()
+ if logs.pushtarget then
+ logs.pushtarget("log")
+ end
+ report("Plugins are not officially supported unless stated otherwise. This is because")
+ report("they bypass the regular font handling and therefore some features in ConTeXt")
+ report("(especially those related to fonts) might not work as expected or might not work")
+ report("at all. Some plugins are for testing and development only and might change")
+ report("whenever we feel the need for it.")
+ report()
+ if logs.poptarget then
+ logs.poptarget()
+ end
+ end
+end
+function otf.plugininitializer(tfmdata,value)
+ if type(value)=="string" then
+ tfmdata.shared.plugin=plugins[value]
+ end
+end
+function otf.pluginprocessor(head,font,attr,direction)
+ local s=fontdata[font].shared
+ local p=s and s.plugin
+ if p then
+ if trace_plugins then
+ report_process("applying plugin %a",p[1])
+ end
+ return p[2](head,font,attr,direction)
+ else
+ return head,false
+ end
+end
+function otf.featuresinitializer(tfmdata,value)
+end
+registerotffeature {
+ name="features",
+ description="features",
+ default=true,
+ initializers={
+ position=1,
+ node=otf.featuresinitializer,
+ plug=otf.plugininitializer,
+ },
+ processors={
+ node=otf.featuresprocessor,
+ plug=otf.pluginprocessor,
+ }
+}
+otf.handlers=handlers
+local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end
+local tag="kern"
+if fontfeatures then
+ function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr)
+ local features=fontfeatures[font]
+ local enabled=features and features.spacekern and features[tag]
+ if enabled then
+ setspacekerns(font,sequence)
+ end
+ return head,enabled
+ end
+else
+ function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr)
+ local shared=fontdata[font].shared
+ local features=shared and shared.features
+ local enabled=features and features.spacekern and features[tag]
+ if enabled then
+ setspacekerns(font,sequence)
+ end
+ return head,enabled
+ end
+end
+local function hasspacekerns(data)
+ local resources=data.resources
+ local sequences=resources.sequences
+ local validgpos=resources.features.gpos
+ if validgpos and sequences then
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ if steps and sequence.features[tag] then
+ local kind=sequence.type
+ if kind=="gpos_pair" or kind=="gpos_single" then
+ for i=1,#steps do
+ local step=steps[i]
+ local coverage=step.coverage
+ local rules=step.rules
+ if rules then
+ elseif not coverage then
+ elseif kind=="gpos_single" then
+ elseif kind=="gpos_pair" then
+ local format=step.format
+ if format=="move" or format=="kern" then
+ local kerns=coverage[32]
+ if kerns then
+ return true
+ end
+ for k,v in next,coverage do
+ if v[32] then
+ return true
+ end
+ end
+ elseif format=="pair" then
+ local kerns=coverage[32]
+ if kerns then
+ for k,v in next,kerns do
+ local one=v[1]
+ if one and one~=true then
+ return true
+ end
+ end
+ end
+ for k,v in next,coverage do
+ local kern=v[32]
+ if kern then
+ local one=kern[1]
+ if one and one~=true then
+ return true
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return false
+end
+otf.readers.registerextender {
+ name="spacekerns",
+ action=function(data)
+ data.properties.hasspacekerns=hasspacekerns(data)
+ end
+}
+local function spaceinitializer(tfmdata,value)
+ local resources=tfmdata.resources
+ local spacekerns=resources and resources.spacekerns
+ if value and spacekerns==nil then
+ local rawdata=tfmdata.shared and tfmdata.shared.rawdata
+ local properties=rawdata.properties
+ if properties and properties.hasspacekerns then
+ local sequences=resources.sequences
+ local validgpos=resources.features.gpos
+ if validgpos and sequences then
+ local left={}
+ local right={}
+ local last=0
+ local feat=nil
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ if steps then
+ local kern=sequence.features[tag]
+ if kern then
+ local kind=sequence.type
+ if kind=="gpos_pair" or kind=="gpos_single" then
+ if feat then
+ for script,languages in next,kern do
+ local f=feat[script]
+ if f then
+ for l in next,languages do
+ f[l]=true
+ end
+ else
+ feat[script]=languages
+ end
+ end
+ else
+ feat=kern
+ end
+ for i=1,#steps do
+ local step=steps[i]
+ local coverage=step.coverage
+ local rules=step.rules
+ if rules then
+ elseif not coverage then
+ elseif kind=="gpos_single" then
+ elseif kind=="gpos_pair" then
+ local format=step.format
+ if format=="move" or format=="kern" then
+ local kerns=coverage[32]
+ if kerns then
+ for k,v in next,kerns do
+ right[k]=v
+ end
+ end
+ for k,v in next,coverage do
+ local kern=v[32]
+ if kern then
+ left[k]=kern
+ end
+ end
+ elseif format=="pair" then
+ local kerns=coverage[32]
+ if kerns then
+ for k,v in next,kerns do
+ local one=v[1]
+ if one and one~=true then
+ right[k]=one[3]
+ end
+ end
+ end
+ for k,v in next,coverage do
+ local kern=v[32]
+ if kern then
+ local one=kern[1]
+ if one and one~=true then
+ left[k]=one[3]
+ end
+ end
+ end
+ end
+ end
+ end
+ last=i
+ end
+ else
+ end
+ end
+ end
+ left=next(left) and left or false
+ right=next(right) and right or false
+ if left or right then
+ spacekerns={
+ left=left,
+ right=right,
+ }
+ if last>0 then
+ local triggersequence={
+ features={ [tag]=feat or { dflt={ dflt=true,} } },
+ flags=noflags,
+ name="trigger_space_kerns",
+ order={ tag },
+ type="trigger_space_kerns",
+ left=left,
+ right=right,
+ }
+ insert(sequences,last,triggersequence)
+ end
+ end
+ end
+ end
+ resources.spacekerns=spacekerns
+ end
+ return spacekerns
+end
+registerotffeature {
+ name="spacekern",
+ description="space kern injection",
+ default=true,
+ initializers={
+ node=spaceinitializer,
+ },
+}
+local function markinitializer(tfmdata,value)
+ local properties=tfmdata.properties
+ properties.checkmarks=value
+end
+registerotffeature {
+ name="checkmarks",
+ description="check mark widths",
+ default=true,
+ initializers={
+ node=markinitializer,
+ },
+}
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otsâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-osd†79eb2fc4a71364fd73c8b996a109f5df] ---
+
+if not modules then modules={} end modules ['font-osd']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Kai Eigner, TAT Zetwerk / Hans Hagen, PRAGMA ADE",
+ copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local insert,imerge,copy,tohash=table.insert,table.imerge,table.copy,table.tohash
+local next,type=next,type
+local report=logs.reporter("otf","devanagari")
+fonts=fonts or {}
+fonts.analyzers=fonts.analyzers or {}
+fonts.analyzers.methods=fonts.analyzers.methods or { node={ otf={} } }
+local otf=fonts.handlers.otf
+local handlers=otf.handlers
+local methods=fonts.analyzers.methods
+local otffeatures=fonts.constructors.features.otf
+local registerotffeature=otffeatures.register
+local nuts=nodes.nuts
+local getnext=nuts.getnext
+local getprev=nuts.getprev
+local getboth=nuts.getboth
+local getid=nuts.getid
+local getchar=nuts.getchar
+local getfont=nuts.getfont
+local getsubtype=nuts.getsubtype
+local setlink=nuts.setlink
+local setnext=nuts.setnext
+local setprev=nuts.setprev
+local setchar=nuts.setchar
+local getprop=nuts.getprop
+local setprop=nuts.setprop
+local ischar=nuts.ischar
+local insert_node_after=nuts.insert_after
+local copy_node=nuts.copy
+local remove_node=nuts.remove
+local flush_list=nuts.flush_list
+local flush_node=nuts.flush_node
+local copyinjection=nodes.injections.copy
+local unsetvalue=attributes.unsetvalue
+local fontdata=fonts.hashes.identifiers
+local a_state=attributes.private('state')
+local a_syllabe=attributes.private('syllabe')
+local dotted_circle=0x25CC
+local c_nbsp=0x00A0
+local c_zwnj=0x200C
+local c_zwj=0x200D
+local states=fonts.analyzers.states
+local s_rphf=states.rphf
+local s_half=states.half
+local s_pref=states.pref
+local s_blwf=states.blwf
+local s_pstf=states.pstf
+local s_init=states.init
+local replace_all_nbsp=nil
+replace_all_nbsp=function(head)
+ replace_all_nbsp=typesetters and typesetters.characters and typesetters.characters.replacenbspaces or function(head)
+ return head
+ end
+ return replace_all_nbsp(head)
+end
+local processcharacters=nil
+if context then
+ local fontprocesses=fonts.hashes.processes
+ function processcharacters(head,font)
+ local processors=fontprocesses[font]
+ for i=1,#processors do
+ head=processors[i](head,font,0)
+ end
+ return head
+ end
+else
+ function processcharacters(head,font)
+ local processors=fontdata[font].shared.processes
+ for i=1,#processors do
+ head=processors[i](head,font,0)
+ end
+ return head
+ end
+end
+local indicgroups=characters and characters.indicgroups
+if not indicgroups and characters then
+ local indic={
+ c={},
+ i={},
+ d={},
+ m={},
+ s={},
+ o={},
+ }
+ local indicmarks={
+ l={},
+ t={},
+ b={},
+ r={},
+ s={},
+ }
+ local indicclasses={
+ nukta={},
+ halant={},
+ ra={},
+ anudatta={},
+ }
+ local indicorders={
+ bp={},
+ ap={},
+ bs={},
+ as={},
+ bh={},
+ ah={},
+ bm={},
+ am={},
+ }
+ for k,v in next,characters.data do
+ local i=v.indic
+ if i then
+ indic[i][k]=true
+ i=v.indicmark
+ if i then
+ if i=="s" then
+ local s=v.specials
+ indicmarks[i][k]={ s[2],s[3] }
+ else
+ indicmarks[i][k]=true
+ end
+ end
+ i=v.indicclass
+ if i then
+ indicclasses[i][k]=true
+ end
+ i=v.indicorder
+ if i then
+ indicorders[i][k]=true
+ end
+ end
+ end
+ indicgroups={
+ consonant=indic.c,
+ independent_vowel=indic.i,
+ dependent_vowel=indic.d,
+ vowel_modifier=indic.m,
+ stress_tone_mark=indic.s,
+ pre_mark=indicmarks.l,
+ above_mark=indicmarks.t,
+ below_mark=indicmarks.b,
+ post_mark=indicmarks.r,
+ twopart_mark=indicmarks.s,
+ nukta=indicclasses.nukta,
+ halant=indicclasses.halant,
+ ra=indicclasses.ra,
+ anudatta=indicclasses.anudatta,
+ before_postscript=indicorders.bp,
+ after_postscript=indicorders.ap,
+ before_half=indicorders.bh,
+ after_half=indicorders.ah,
+ before_subscript=indicorders.bs,
+ after_subscript=indicorders.as,
+ before_main=indicorders.bm,
+ after_main=indicorders.am,
+ }
+ indic=nil
+ indicmarks=nil
+ indicclasses=nil
+ indicorders=nil
+ characters.indicgroups=indicgroups
+end
+local consonant=indicgroups.consonant
+local independent_vowel=indicgroups.independent_vowel
+local dependent_vowel=indicgroups.dependent_vowel
+local vowel_modifier=indicgroups.vowel_modifier
+local stress_tone_mark=indicgroups.stress_tone_mark
+local pre_mark=indicgroups.pre_mark
+local above_mark=indicgroups.above_mark
+local below_mark=indicgroups.below_mark
+local post_mark=indicgroups.post_mark
+local twopart_mark=indicgroups.twopart_mark
+local nukta=indicgroups.nukta
+local halant=indicgroups.halant
+local ra=indicgroups.ra
+local anudatta=indicgroups.anudatta
+local before_postscript=indicgroups.before_postscript
+local after_postscript=indicgroups.after_postscript
+local before_half=indicgroups.before_half
+local after_half=indicgroups.after_half
+local before_subscript=indicgroups.before_subscript
+local after_subscript=indicgroups.after_subscript
+local before_main=indicgroups.before_main
+local after_main=indicgroups.after_main
+local mark_four=table.merged (
+ pre_mark,
+ above_mark,
+ below_mark,
+ post_mark
+)
+local mark_above_below_post=table.merged (
+ above_mark,
+ below_mark,
+ post_mark
+)
+local zw_char={
+ [c_zwnj]=true,
+ [c_zwj ]=true,
+}
+local dflt_true={
+ dflt=true,
+}
+local two_defaults={}
+local one_defaults={}
+local false_flags={ false,false,false,false }
+local sequence_reorder_matras={
+ features={ dv01=two_defaults },
+ flags=false_flags,
+ name="dv01_reorder_matras",
+ order={ "dv01" },
+ type="devanagari_reorder_matras",
+ nofsteps=1,
+ steps={
+ {
+ coverage=pre_mark,
+ }
+ }
+}
+local sequence_reorder_reph={
+ features={ dv02=two_defaults },
+ flags=false_flags,
+ name="dv02_reorder_reph",
+ order={ "dv02" },
+ type="devanagari_reorder_reph",
+ nofsteps=1,
+ steps={
+ {
+ coverage={},
+ }
+ }
+}
+local sequence_reorder_pre_base_reordering_consonants={
+ features={ dv03=one_defaults },
+ flags=false_flags,
+ name="dv03_reorder_pre_base_reordering_consonants",
+ order={ "dv03" },
+ type="devanagari_reorder_pre_base_reordering_consonants",
+ nofsteps=1,
+ steps={
+ {
+ coverage={},
+ }
+ }
+}
+local sequence_remove_joiners={
+ features={ dv04=one_defaults },
+ flags=false_flags,
+ name="dv04_remove_joiners",
+ order={ "dv04" },
+ type="devanagari_remove_joiners",
+ nofsteps=1,
+ steps={
+ {
+ coverage=zw_char,
+ },
+ }
+}
+local basic_shaping_forms={
+ akhn=true,
+ blwf=true,
+ cjct=true,
+ half=true,
+ nukt=true,
+ pref=true,
+ pstf=true,
+ rkrf=true,
+ rphf=true,
+ vatu=true,
+ locl=true,
+}
+local valid={
+ abvs=true,
+ akhn=true,
+ blwf=true,
+ calt=true,
+ cjct=true,
+ half=true,
+ haln=true,
+ nukt=true,
+ pref=true,
+ pres=true,
+ pstf=true,
+ psts=true,
+ rkrf=true,
+ rphf=true,
+ vatu=true,
+ pres=true,
+ abvs=true,
+ blws=true,
+ psts=true,
+ haln=true,
+ calt=true,
+ locl=true,
+}
+local scripts={}
+local scripts_one={ "deva","mlym","beng","gujr","guru","knda","orya","taml","telu" }
+local scripts_two={ "dev2","mlm2","bng2","gjr2","gur2","knd2","ory2","tml2","tel2" }
+local nofscripts=#scripts_one
+for i=1,nofscripts do
+ local one=scripts_one[i]
+ local two=scripts_two[i]
+ scripts[one]=true
+ scripts[two]=true
+ two_defaults[two]=dflt_true
+ one_defaults[one]=dflt_true
+ one_defaults[two]=dflt_true
+end
+local function valid_one(s) for i=1,nofscripts do if s[scripts_one[i]] then return true end end end
+local function valid_two(s) for i=1,nofscripts do if s[scripts_two[i]] then return true end end end
+local function initializedevanagi(tfmdata)
+ local script,language=otf.scriptandlanguage(tfmdata,attr)
+ if scripts[script] then
+ local resources=tfmdata.resources
+ local devanagari=resources.devanagari
+ if not devanagari then
+ report("adding devanagari features to font")
+ local gsubfeatures=resources.features.gsub
+ local sequences=resources.sequences
+ local sharedfeatures=tfmdata.shared.features
+ gsubfeatures["dv01"]=two_defaults
+ gsubfeatures["dv02"]=two_defaults
+ gsubfeatures["dv03"]=one_defaults
+ gsubfeatures["dv04"]=one_defaults
+ local reorder_pre_base_reordering_consonants=copy(sequence_reorder_pre_base_reordering_consonants)
+ local reorder_reph=copy(sequence_reorder_reph)
+ local reorder_matras=copy(sequence_reorder_matras)
+ local remove_joiners=copy(sequence_remove_joiners)
+ local lastmatch=0
+ for s=1,#sequences do
+ local features=sequences[s].features
+ if features then
+ for k,v in next,features do
+ if k=="locl" then
+ local steps=sequences[s].steps
+ local nofsteps=sequences[s].nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ for k,v in next,pre_mark do
+ local locl=coverage[k]
+ if locl then
+ if #locl>0 then
+ for j=1,#locl do
+ local ck=locl[j]
+ local f=ck[4]
+ local chainlookups=ck[6]
+ if chainlookups then
+ local chainlookup=chainlookups[f]
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ local steps=chainstep.steps
+ local nofsteps=chainstep.nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ locl=coverage[k]
+ end
+ end
+ end
+ end
+ end
+ end
+ if locl then
+ reorder_matras.steps[1].coverage[locl]=true
+ end
+ end
+ end
+ end
+ end
+ end
+ if basic_shaping_forms[k] then
+ lastmatch=lastmatch+1
+ if s~=lastmatch then
+ table.insert(sequences,lastmatch,table.remove(sequences,s))
+ end
+ end
+ end
+ end
+ end
+ local insertindex=lastmatch+1
+ if tfmdata.properties.language then
+ dflt_true[tfmdata.properties.language]=true
+ end
+ insert(sequences,insertindex,reorder_pre_base_reordering_consonants)
+ insert(sequences,insertindex,reorder_reph)
+ insert(sequences,insertindex,reorder_matras)
+ insert(sequences,insertindex,remove_joiners)
+ local blwfcache={}
+ local vatucache={}
+ local pstfcache={}
+ local seqsubset={}
+ local rephstep={
+ coverage={}
+ }
+ local devanagari={
+ reph=false,
+ vattu=false,
+ blwfcache=blwfcache,
+ vatucache=vatucache,
+ pstfcache=pstfcache,
+ seqsubset=seqsubset,
+ reorderreph=rephstep,
+ }
+ reorder_reph.steps={ rephstep }
+ local pre_base_reordering_consonants={}
+ reorder_pre_base_reordering_consonants.steps[1].coverage=pre_base_reordering_consonants
+ resources.devanagari=devanagari
+ for s=1,#sequences do
+ local sequence=sequences[s]
+ local steps=sequence.steps
+ local nofsteps=sequence.nofsteps
+ local features=sequence.features
+ local has_rphf=features.rphf
+ local has_blwf=features.blwf
+ local has_vatu=features.vatu
+ local has_pstf=features.pstf
+ if has_rphf and has_rphf[script] then
+ devanagari.reph=true
+ elseif (has_blwf and has_blwf[script] ) or (has_vatu and has_vatu[script] ) then
+ devanagari.vattu=true
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ for k,v in next,coverage do
+ for h,w in next,halant do
+ if v[h] then
+ if not blwfcache[k] then
+ blwfcache[k]=v
+ end
+ end
+ if has_vatu and has_vatu[script] and not vatucache[k] then
+ vatucache[k]=v
+ end
+ end
+ end
+ end
+ end
+ elseif has_pstf and has_pstf[script] then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ for k,v in next,coverage do
+ if not pstfcache[k] then
+ pstfcache[k]=v
+ end
+ end
+ for k,v in next,ra do
+ local r=coverage[k]
+ if r then
+ local found=false
+ if #r>0 then
+ for j=1,#r do
+ local ck=r[j]
+ local f=ck[4]
+ local chainlookups=ck[6]
+ if chainlookups and chainlookups[f] then
+ local chainlookup=chainlookups[f]
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ local steps=chainstep.steps
+ local nofsteps=chainstep.nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ local h=coverage[k]
+ if h then
+ for k,v in next,h do
+ found=v and v.ligature
+ if found then
+ pre_base_reordering_consonants[found]=true
+ break
+ end
+ end
+ if found then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ else
+ for k,v in next,r do
+ found=v and v.ligature
+ if found then
+ pre_base_reordering_consonants[found]=true
+ break
+ end
+ end
+ end
+ if found then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ for kind,spec in next,features do
+ if valid[kind] and valid_two(spec)then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ local reph,rephbase=false,false
+ if kind=="rphf" then
+ for k,v in next,ra do
+ local r=coverage[k]
+ if r then
+ rephbase=k
+ local h=false
+ if #r>0 then
+ for j=1,#r do
+ local ck=r[j]
+ local f=ck[4]
+ local chainlookups=ck[6]
+ if chainlookups then
+ local chainlookup=chainlookups[f]
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ local steps=chainstep.steps
+ local nofsteps=chainstep.nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ local r=coverage[k]
+ if r then
+ for k,v in next,halant do
+ local h=r[k]
+ if h then
+ reph=h.ligature or false
+ break
+ end
+ end
+ if h then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ else
+ for k,v in next,halant do
+ local h=r[k]
+ if h then
+ reph=h.ligature or false
+ break
+ end
+ end
+ end
+ if reph then
+ break
+ end
+ end
+ end
+ end
+ seqsubset[#seqsubset+1]={ kind,coverage,reph,rephbase }
+ end
+ end
+ end
+ if kind=="pref" then
+ local steps=sequence.steps
+ local nofsteps=sequence.nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ for k,v in next,halant do
+ local h=coverage[k]
+ if h then
+ local found=false
+ if #h>0 then
+ for j=1,#h do
+ local ck=h[j]
+ local f=ck[4]
+ local chainlookups=ck[6]
+ if chainlookups then
+ local chainlookup=chainlookups[f]
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ local steps=chainstep.steps
+ local nofsteps=chainstep.nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ local h=coverage[k]
+ if h then
+ for k,v in next,h do
+ found=v and v.ligature
+ if found then
+ pre_base_reordering_consonants[found]=true
+ break
+ end
+ end
+ if found then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ else
+ for k,v in next,h do
+ found=v and v.ligature
+ if found then
+ pre_base_reordering_consonants[found]=true
+ break
+ end
+ end
+ end
+ if found then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if two_defaults[script] then
+ sharedfeatures["dv01"]=true
+ sharedfeatures["dv02"]=true
+ sharedfeatures["dv03"]=true
+ sharedfeatures["dv04"]=true
+ elseif one_defaults[script] then
+ sharedfeatures["dv03"]=true
+ sharedfeatures["dv04"]=true
+ end
+ if script=="mlym" or script=="taml" then
+ devanagari.left_matra_before_base=true
+ end
+ end
+ end
+end
+registerotffeature {
+ name="devanagari",
+ description="inject additional features",
+ default=true,
+ initializers={
+ node=initializedevanagi,
+ },
+}
+local show_syntax_errors=false
+local function inject_syntax_error(head,current,char)
+ local signal=copy_node(current)
+ copyinjection(signal,current)
+ if pre_mark[char] then
+ setchar(signal,dotted_circle)
+ else
+ setchar(current,dotted_circle)
+ end
+ return insert_node_after(head,current,signal)
+end
+local function initialize_one(font,attr)
+ local tfmdata=fontdata[font]
+ local datasets=otf.dataset(tfmdata,font,attr)
+ local devanagaridata=datasets.devanagari
+ if not devanagaridata then
+ devanagaridata={
+ reph=false,
+ vattu=false,
+ blwfcache={},
+ vatucache={},
+ pstfcache={},
+ }
+ datasets.devanagari=devanagaridata
+ local resources=tfmdata.resources
+ local devanagari=resources.devanagari
+ for s=1,#datasets do
+ local dataset=datasets[s]
+ if dataset and dataset[1] then
+ local kind=dataset[4]
+ if kind=="rphf" then
+ devanagaridata.reph=true
+ elseif kind=="blwf" or kind=="vatu" then
+ devanagaridata.vattu=true
+ devanagaridata.blwfcache=devanagari.blwfcache
+ devanagaridata.vatucache=devanagari.vatucache
+ devanagaridata.pstfcache=devanagari.pstfcache
+ end
+ end
+ end
+ end
+ return devanagaridata.reph,devanagaridata.vattu,devanagaridata.blwfcache,devanagaridata.vatucache,devanagaridata.pstfcache
+end
+local function contextchain(contexts,n)
+ local char=getchar(n)
+ for k=1,#contexts do
+ local ck=contexts[k]
+ local seq=ck[3]
+ local f=ck[4]
+ local l=ck[5]
+ if (l-f)==1 and seq[f+1][char] then
+ local ok=true
+ local c=n
+ for i=l+1,#seq do
+ c=getnext(c)
+ if not c or not seq[i][ischar(c)] then
+ ok=false
+ break
+ end
+ end
+ if ok then
+ c=getprev(n)
+ for i=1,f-1 do
+ c=getprev(c)
+ if not c or not seq[f-i][ischar(c)] then
+ ok=false
+ end
+ end
+ end
+ if ok then
+ return true
+ end
+ end
+ end
+ return false
+end
+local function order_matras(c)
+ local cn=getnext(c)
+ local char=getchar(cn)
+ while dependent_vowel[char] do
+ local next=getnext(cn)
+ local cc=c
+ local cchar=getchar(cc)
+ while cc~=cn do
+ if (above_mark[char] and (below_mark[cchar] or post_mark[cchar])) or (below_mark[char] and (post_mark[cchar])) then
+ local prev,next=getboth(cn)
+ if next then
+ setprev(next,prev)
+ end
+ setnext(prev,next)
+ setnext(getprev(cc),cn)
+ setprev(cn,getprev(cc))
+ setnext(cn,cc)
+ setprev(cc,cn)
+ break
+ end
+ cc=getnext(cc)
+ cchar=getchar(cc)
+ end
+ cn=next
+ char=getchar(cn)
+ end
+end
+local function reorder_one(head,start,stop,font,attr,nbspaces)
+ local reph,vattu,blwfcache,vatucache,pstfcache=initialize_one(font,attr)
+ local devanagari=fontdata[font].resources.devanagari
+ local current=start
+ local n=getnext(start)
+ local base=nil
+ local firstcons=nil
+ local lastcons=nil
+ local basefound=false
+ if reph and ra[getchar(start)] and halant[getchar(n)] then
+ if n==stop then
+ return head,stop,nbspaces
+ end
+ if getchar(getnext(n))==c_zwj then
+ current=start
+ else
+ current=getnext(n)
+ setprop(start,a_state,s_rphf)
+ end
+ end
+ if getchar(current)==c_nbsp then
+ if current==stop then
+ stop=getprev(stop)
+ head=remove_node(head,current)
+ flush_node(current)
+ return head,stop,nbspaces
+ else
+ nbspaces=nbspaces+1
+ base=current
+ firstcons=current
+ lastcons=current
+ current=getnext(current)
+ if current~=stop then
+ local char=getchar(current)
+ if nukta[char] then
+ current=getnext(current)
+ char=getchar(current)
+ end
+ if char==c_zwj and current~=stop then
+ local next=getnext(current)
+ if next~=stop and halant[getchar(next)] then
+ current=next
+ next=getnext(current)
+ local tmp=next and getnext(next) or nil
+ local changestop=next==stop
+ local tempcurrent=copy_node(next)
+ copyinjection(tempcurrent,next)
+ local nextcurrent=copy_node(current)
+ copyinjection(nextcurrent,current)
+ setlink(tempcurrent,nextcurrent)
+ setprop(tempcurrent,a_state,s_blwf)
+ tempcurrent=processcharacters(tempcurrent,font)
+ setprop(tempcurrent,a_state,unsetvalue)
+ if getchar(next)==getchar(tempcurrent) then
+ flush_list(tempcurrent)
+ if show_syntax_errors then
+ head,current=inject_syntax_error(head,current,char)
+ end
+ else
+ setchar(current,getchar(tempcurrent))
+ local freenode=getnext(current)
+ setlink(current,tmp)
+ flush_node(freenode)
+ flush_list(tempcurrent)
+ if changestop then
+ stop=current
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ while not basefound do
+ local char=getchar(current)
+ if consonant[char] then
+ setprop(current,a_state,s_half)
+ if not firstcons then
+ firstcons=current
+ end
+ lastcons=current
+ if not base then
+ base=current
+ elseif blwfcache[char] then
+ setprop(current,a_state,s_blwf)
+ elseif pstfcache[char] then
+ setprop(current,a_state,s_pstf)
+ else
+ base=current
+ end
+ end
+ basefound=current==stop
+ current=getnext(current)
+ end
+ if base~=lastcons then
+ local np=base
+ local n=getnext(base)
+ local ch=getchar(n)
+ if nukta[ch] then
+ np=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ if halant[ch] then
+ if lastcons~=stop then
+ local ln=getnext(lastcons)
+ if nukta[getchar(ln)] then
+ lastcons=ln
+ end
+ end
+ local nn=getnext(n)
+ local ln=getnext(lastcons)
+ setlink(np,nn)
+ setnext(lastcons,n)
+ if ln then
+ setprev(ln,n)
+ end
+ setnext(n,ln)
+ setprev(n,lastcons)
+ if lastcons==stop then
+ stop=n
+ end
+ end
+ end
+ n=getnext(start)
+ if n~=stop and ra[getchar(start)] and halant[getchar(n)] and not zw_char[getchar(getnext(n))] then
+ local matra=base
+ if base~=stop then
+ local next=getnext(base)
+ if dependent_vowel[getchar(next)] then
+ matra=next
+ end
+ end
+ local sp=getprev(start)
+ local nn=getnext(n)
+ local mn=getnext(matra)
+ setlink(sp,nn)
+ setlink(matra,start)
+ setlink(n,mn)
+ if head==start then
+ head=nn
+ end
+ start=nn
+ if matra==stop then
+ stop=n
+ end
+ end
+ local current=start
+ while current~=stop do
+ local next=getnext(current)
+ if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then
+ setprop(current,a_state,unsetvalue)
+ end
+ current=next
+ end
+ if base~=stop and getprop(base,a_state) then
+ local next=getnext(base)
+ if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then
+ setprop(base,a_state,unsetvalue)
+ end
+ end
+ local current,allreordered,moved=start,false,{ [base]=true }
+ local a,b,p,bn=base,base,base,getnext(base)
+ if base~=stop and nukta[getchar(bn)] then
+ a,b,p=bn,bn,bn
+ end
+ while not allreordered do
+ local c=current
+ local n=getnext(current)
+ local l=nil
+ if c~=stop then
+ local ch=getchar(n)
+ if nukta[ch] then
+ c=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ if c~=stop then
+ if halant[ch] then
+ c=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ local tpm=twopart_mark[ch]
+ while tpm do
+ local extra=copy_node(n)
+ copyinjection(extra,n)
+ ch=tpm[1]
+ setchar(n,ch)
+ setchar(extra,tpm[2])
+ head=insert_node_after(head,current,extra)
+ tpm=twopart_mark[ch]
+ end
+ while c~=stop and dependent_vowel[ch] do
+ c=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ if c~=stop then
+ if vowel_modifier[ch] then
+ c=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ if c~=stop and stress_tone_mark[ch] then
+ c=n
+ n=getnext(n)
+ end
+ end
+ end
+ end
+ local bp=getprev(firstcons)
+ local cn=getnext(current)
+ local last=getnext(c)
+ while cn~=last do
+ if pre_mark[getchar(cn)] then
+ if devanagari.left_matra_before_base then
+ local prev,next=getboth(cn)
+ setlink(prev,next)
+ if cn==stop then
+ stop=getprev(cn)
+ end
+ if base==start then
+ if head==start then
+ head=cn
+ end
+ start=cn
+ end
+ setlink(getprev(base),cn)
+ setlink(cn,base)
+ cn=next
+ else
+ if bp then
+ setnext(bp,cn)
+ end
+ local prev,next=getboth(cn)
+ if next then
+ setprev(next,prev)
+ end
+ setnext(prev,next)
+ if cn==stop then
+ stop=prev
+ end
+ setprev(cn,bp)
+ setlink(cn,firstcons)
+ if firstcons==start then
+ if head==start then
+ head=cn
+ end
+ start=cn
+ end
+ cn=next
+ end
+ elseif current~=base and dependent_vowel[getchar(cn)] then
+ local prev,next=getboth(cn)
+ if next then
+ setprev(next,prev)
+ end
+ setnext(prev,next)
+ if cn==stop then
+ stop=prev
+ end
+ setlink(b,cn,getnext(b))
+ order_matras(cn)
+ cn=next
+ elseif current==base and dependent_vowel[getchar(cn)] then
+ local cnn=getnext(cn)
+ order_matras(cn)
+ cn=cnn
+ while cn~=last and dependent_vowel[getchar(cn)] do
+ cn=getnext(cn)
+ end
+ else
+ cn=getnext(cn)
+ end
+ end
+ allreordered=c==stop
+ current=getnext(c)
+ end
+ if reph or vattu then
+ local current,cns=start,nil
+ while current~=stop do
+ local c=current
+ local n=getnext(current)
+ if ra[getchar(current)] and halant[getchar(n)] then
+ c=n
+ n=getnext(n)
+ local b,bn=base,base
+ while bn~=stop do
+ local next=getnext(bn)
+ if dependent_vowel[getchar(next)] then
+ b=next
+ end
+ bn=next
+ end
+ if getprop(current,a_state)==s_rphf then
+ if b~=current then
+ if current==start then
+ if head==start then
+ head=n
+ end
+ start=n
+ end
+ if b==stop then
+ stop=c
+ end
+ local prev=getprev(current)
+ setlink(prev,n)
+ local next=getnext(b)
+ setlink(c,next)
+ setlink(b,current)
+ end
+ elseif cns and getnext(cns)~=current then
+ local cp=getprev(current)
+ local cnsn=getnext(cns)
+ setlink(cp,n)
+ setlink(cns,current)
+ setlink(c,cnsn)
+ if c==stop then
+ stop=cp
+ break
+ end
+ current=getprev(n)
+ end
+ else
+ local char=getchar(current)
+ if consonant[char] then
+ cns=current
+ local next=getnext(cns)
+ if halant[getchar(next)] then
+ cns=next
+ end
+ if not vatucache[char] then
+ next=getnext(cns)
+ while dependent_vowel[getchar(next)] do
+ cns=next
+ next=getnext(cns)
+ end
+ end
+ elseif char==c_nbsp then
+ nbspaces=nbspaces+1
+ cns=current
+ local next=getnext(cns)
+ if halant[getchar(next)] then
+ cns=next
+ end
+ if not vatucache[char] then
+ next=getnext(cns)
+ while dependent_vowel[getchar(next)] do
+ cns=next
+ next=getnext(cns)
+ end
+ end
+ end
+ end
+ current=getnext(current)
+ end
+ end
+ if getchar(base)==c_nbsp then
+ nbspaces=nbspaces-1
+ if base==stop then
+ stop=getprev(stop)
+ end
+ head=remove_node(head,base)
+ flush_node(base)
+ end
+ return head,stop,nbspaces
+end
+function handlers.devanagari_reorder_matras(head,start)
+ local current=start
+ local startfont=getfont(start)
+ local startattr=getprop(start,a_syllabe)
+ while current do
+ local char=ischar(current,startfont)
+ local next=getnext(current)
+ if char and getprop(current,a_syllabe)==startattr then
+ if halant[char] then
+ if next then
+ local char=ischar(next,startfont)
+ if char and zw_char[char] and getprop(next,a_syllabe)==startattr then
+ current=next
+ next=getnext(current)
+ end
+ end
+ local startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(start,next)
+ setlink(current,start)
+ start=startnext
+ break
+ end
+ else
+ break
+ end
+ current=next
+ end
+ return head,start,true
+end
+local rephbase={}
+function handlers.devanagari_reorder_reph(head,start)
+ local current=getnext(start)
+ local startnext=nil
+ local startprev=nil
+ local startfont=getfont(start)
+ local startattr=getprop(start,a_syllabe)
+ ::step_1::
+ local char=ischar(start,startfont)
+ local rephbase=rephbase[startfont][char]
+ if char and after_subscript[rephbase] then
+ goto step_5
+ end
+ ::step_2::
+ if char and not after_postscript[rephbase] then
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ if halant[char] then
+ local next=getnext(current)
+ if next then
+ local nextchar=ischar(next,startfont)
+ if nextchar and zw_char[nextchar] and getprop(next,a_syllabe)==startattr then
+ current=next
+ next=getnext(current)
+ end
+ end
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(start,next)
+ setlink(current,start)
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ break
+ end
+ current=getnext(current)
+ else
+ break
+ end
+ end
+ end
+ ::step_3::
+ if not startnext then
+ if char and after_main[rephbase] then
+ current=getnext(start)
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ if consonant[char] and not getprop(current,a_state)==s_pref then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(current,start)
+ setlink(start,getnext(current))
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ break
+ end
+ current=getnext(current)
+ else
+ break
+ end
+ end
+ end
+ end
+ ::step_4::
+ if not startnext then
+ if char and before_postscript[rephbase] then
+ current=getnext(start)
+ local c=nil
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ if getprop(current,a_state)==s_pstf then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(getprev(current),start)
+ setlink(start,current)
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ break
+ elseif not c and (vowel_modifier[char] or stress_tone_mark[char] ) then
+ c=current
+ end
+ current=getnext(current)
+ else
+ if c then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(getprev(c),start)
+ setlink(start,c)
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ end
+ break
+ end
+ end
+ end
+ end
+ ::step_5::
+ if not startnext then
+ current=getnext(start)
+ local c=nil
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ local state=getprop(current,a_state)
+ if before_subscript[rephbase] and (state==s_blwf or state==s_pstf) then
+ c=current
+ elseif after_subscript[rephbase] and (state==s_pstf) then
+ c=current
+ end
+ current=getnext(current)
+ else
+ break
+ end
+ end
+ if c then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(getprev(c),start)
+ setlink(start,c)
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ end
+ end
+ ::step_6::
+ if not startnext then
+ current=start
+ local next=getnext(current)
+ while next do
+ local nextchar=ischar(next,startfont)
+ if nextchar and getprop(next,a_syllabe)==startattr then
+ current=next
+ next=getnext(current)
+ else
+ break
+ end
+ end
+ if start~=current then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(start,getnext(current))
+ setlink(current,start)
+ start=startnext
+ end
+ end
+ return head,start,true
+end
+local reordered_pre_base_reordering_consonants={}
+function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start)
+ if reordered_pre_base_reordering_consonants[start] then
+ return head,start,true
+ end
+ local current=start
+ local startfont=getfont(start)
+ local startattr=getprop(start,a_syllabe)
+ while current do
+ local char=ischar(current,startfont)
+ local next=getnext(current)
+ if char and getprop(current,a_syllabe)==startattr then
+ if halant[char] then
+ if next then
+ local char=ischar(next,startfont)
+ if char and zw_char[char] and getprop(next,a_syllabe)==startattr then
+ current=next
+ next=getnext(current)
+ end
+ end
+ local startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(start,next)
+ setlink(current,start)
+ reordered_pre_base_reordering_consonants[start]=true
+ start=startnext
+ return head,start,true
+ end
+ else
+ break
+ end
+ current=next
+ end
+ local startattr=getprop(start,a_syllabe)
+ local current=getprev(start)
+ while current and getprop(current,a_syllabe)==startattr do
+ local char=ischar(current)
+ if (not dependent_vowel[char] and not getprop(current,a_state) or getprop(current,a_state)==s_init) then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ if current==head then
+ setlink(start,current)
+ head=start
+ else
+ setlink(getprev(current),start)
+ setlink(start,current)
+ end
+ reordered_pre_base_reordering_consonants[start]=true
+ start=startnext
+ break
+ end
+ current=getprev(current)
+ end
+ return head,start,true
+end
+function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replacement)
+ local stop=getnext(start)
+ local font=getfont(start)
+ local last=start
+ while stop do
+ local char=ischar(stop,font)
+ if char and (char==c_zwnj or char==c_zwj) then
+ last=stop
+ stop=getnext(stop)
+ else
+ break
+ end
+ end
+ local prev=getprev(start)
+ if stop then
+ setnext(last)
+ setlink(prev,stop)
+ elseif prev then
+ setnext(prev)
+ end
+ if head==start then
+ head=stop
+ end
+ flush_list(start)
+ return head,stop,true
+end
+local function initialize_two(font,attr)
+ local devanagari=fontdata[font].resources.devanagari
+ if devanagari then
+ return devanagari.seqsubset or {},devanagari.reorderreph or {}
+ else
+ return {},{}
+ end
+end
+local function reorder_two(head,start,stop,font,attr,nbspaces)
+ local seqsubset,reorderreph=initialize_two(font,attr)
+ local halfpos=nil
+ local basepos=nil
+ local subpos=nil
+ local postpos=nil
+ reorderreph.coverage={}
+ rephbase[font]={}
+ for i=1,#seqsubset do
+ local subset=seqsubset[i]
+ local kind=subset[1]
+ local lookupcache=subset[2]
+ if kind=="rphf" then
+ reorderreph.coverage[subset[3]]=true
+ rephbase[font][subset[3]]=subset[4]
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ if found[getchar(next)] or contextchain(found,next) then
+ local afternext=next~=stop and getnext(next)
+ if afternext and zw_char[getchar(afternext)] then
+ current=afternext
+ elseif current==start then
+ setprop(current,a_state,s_rphf)
+ current=next
+ else
+ current=next
+ end
+ end
+ end
+ end
+ current=getnext(current)
+ end
+ elseif kind=="pref" then
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ if found[getchar(next)] or contextchain(found,next) then
+ if (not getprop(current,a_state) and not getprop(next,a_state)) then
+ setprop(current,a_state,s_pref)
+ setprop(next,a_state,s_pref)
+ current=next
+ end
+ end
+ end
+ end
+ current=getnext(current)
+ end
+ elseif kind=="half" then
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ if found[getchar(next)] or contextchain(found,next) then
+ if next~=stop and getchar(getnext(next))==c_zwnj then
+ current=next
+ elseif (not getprop(current,a_state)) then
+ setprop(current,a_state,s_half)
+ if not halfpos then
+ halfpos=current
+ end
+ end
+ current=getnext(current)
+ end
+ end
+ end
+ current=getnext(current)
+ end
+ elseif kind=="blwf" or kind=="vatu" then
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ if found[getchar(next)] or contextchain(found,next) then
+ if (not getprop(current,a_state) and not getprop(next,a_state)) then
+ setprop(current,a_state,s_blwf)
+ setprop(next,a_state,s_blwf)
+ current=next
+ subpos=current
+ end
+ end
+ end
+ end
+ current=getnext(current)
+ end
+ elseif kind=="pstf" then
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ if found[getchar(next)] or contextchain(found,next) then
+ if (not getprop(current,a_state) and not getprop(next,a_state)) then
+ setprop(current,a_state,s_pstf)
+ setprop(next,a_state,s_pstf)
+ current=next
+ postpos=current
+ end
+ end
+ end
+ end
+ current=getnext(current)
+ end
+ end
+ end
+ local current,base,firstcons=start,nil,nil
+ if getprop(start,a_state)==s_rphf then
+ current=getnext(getnext(start))
+ end
+ if current~=getnext(stop) and getchar(current)==c_nbsp then
+ if current==stop then
+ stop=getprev(stop)
+ head=remove_node(head,current)
+ flush_node(current)
+ return head,stop,nbspaces
+ else
+ nbspaces=nbspaces+1
+ base=current
+ current=getnext(current)
+ if current~=stop then
+ local char=getchar(current)
+ if nukta[char] then
+ current=getnext(current)
+ char=getchar(current)
+ end
+ if char==c_zwj then
+ local next=getnext(current)
+ if current~=stop and next~=stop and halant[getchar(next)] then
+ current=next
+ next=getnext(current)
+ local tmp=getnext(next)
+ local changestop=next==stop
+ setnext(next)
+ setprop(current,a_state,s_pref)
+ current=processcharacters(current,font)
+ setprop(current,a_state,s_blwf)
+ current=processcharacters(current,font)
+ setprop(current,a_state,s_pstf)
+ current=processcharacters(current,font)
+ setprop(current,a_state,unsetvalue)
+ if halant[getchar(current)] then
+ setnext(getnext(current),tmp)
+ if show_syntax_errors then
+ head,current=inject_syntax_error(head,current,char)
+ end
+ else
+ setnext(current,tmp)
+ if changestop then
+ stop=current
+ end
+ end
+ end
+ end
+ end
+ end
+ else
+ local last=getnext(stop)
+ while current~=last do
+ local next=getnext(current)
+ if consonant[getchar(current)] then
+ if not (current~=stop and next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwj) then
+ if not firstcons then
+ firstcons=current
+ end
+ local a=getprop(current,a_state)
+ if not (a==s_blwf or a==s_pstf or (a~=s_rphf and a~=s_blwf and ra[getchar(current)])) then
+ base=current
+ end
+ end
+ end
+ current=next
+ end
+ if not base then
+ base=firstcons
+ end
+ end
+ if not base then
+ if getprop(start,a_state)==s_rphf then
+ setprop(start,a_state,unsetvalue)
+ end
+ return head,stop,nbspaces
+ else
+ if getprop(base,a_state) then
+ setprop(base,a_state,unsetvalue)
+ end
+ basepos=base
+ end
+ if not halfpos then
+ halfpos=base
+ end
+ if not subpos then
+ subpos=base
+ end
+ if not postpos then
+ postpos=subpos or base
+ end
+ local moved={}
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ local char=getchar(current)
+ local target=nil
+ local cn=getnext(current)
+ local tpm=twopart_mark[char]
+ while tpm do
+ local extra=copy_node(current)
+ copyinjection(extra,current)
+ char=tpm[1]
+ setchar(current,char)
+ setchar(extra,tpm[2])
+ head=insert_node_after(head,current,extra)
+ tpm=twopart_mark[char]
+ end
+ if not moved[current] and dependent_vowel[char] then
+ if pre_mark[char] then
+ moved[current]=true
+ local prev,next=getboth(current)
+ setlink(prev,next)
+ if current==stop then
+ stop=getprev(current)
+ end
+ local pos
+ if before_main[char] then
+ pos=basepos
+ else
+ pos=halfpos
+ end
+ local ppos=getprev(pos)
+ while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) do
+ if getprop(ppos,a_state)==s_pref then
+ pos=ppos
+ end
+ ppos=getprev(ppos)
+ end
+ local ppos=getprev(pos)
+ while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) and halant[ischar(ppos)] do
+ ppos=getprev(ppos)
+ if ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) and consonant[ischar(ppos)] then
+ pos=ppos
+ ppos=getprev(ppos)
+ else
+ break
+ end
+ end
+ if pos==start then
+ if head==start then
+ head=current
+ end
+ start=current
+ end
+ setlink(getprev(pos),current)
+ setlink(current,pos)
+ elseif above_mark[char] then
+ target=basepos
+ if subpos==basepos then
+ subpos=current
+ end
+ if postpos==basepos then
+ postpos=current
+ end
+ basepos=current
+ elseif below_mark[char] then
+ target=subpos
+ if postpos==subpos then
+ postpos=current
+ end
+ subpos=current
+ elseif post_mark[char] then
+ local n=getnext(postpos)
+ while n do
+ local v=ischar(n,font)
+ if nukta[v] or stress_tone_mark[v] or vowel_modifier[v] then
+ postpos=n
+ else
+ break
+ end
+ n=getnext(n)
+ end
+ target=postpos
+ postpos=current
+ end
+ if mark_above_below_post[char] then
+ local prev=getprev(current)
+ if prev~=target then
+ local next=getnext(current)
+ setlink(prev,next)
+ if current==stop then
+ stop=prev
+ end
+ setlink(current,getnext(target))
+ setlink(target,current)
+ end
+ end
+ end
+ current=cn
+ end
+ local current=getnext(start)
+ local last=getnext(stop)
+ while current~=last do
+ local char=getchar(current)
+ local cn=getnext(current)
+ if halant[char] and ra[ischar(cn)] and getprop(cn,a_state)~=s_rphf and getprop(cn,a_state)~=s_blwf then
+ if after_main[ischar(cn)] then
+ local prev=getprev(current)
+ local next=getnext(cn)
+ local bpn=getnext(basepos)
+ while bpn and dependent_vowel[ischar(bpn)] do
+ basepos=bpn
+ bpn=getnext(bpn)
+ end
+ if basepos~=prev then
+ setlink(prev,next)
+ setlink(cn,getnext(basepos))
+ setlink(basepos,current)
+ if cn==stop then
+ stop=prev
+ end
+ cn=next
+ end
+ end
+ end
+ current=cn
+ end
+ local current=start
+ local c=nil
+ while current~=stop do
+ local char=getchar(current)
+ if halant[char] or stress_tone_mark[char] then
+ if not c then
+ c=current
+ end
+ else
+ c=nil
+ end
+ local next=getnext(current)
+ if c and nukta[getchar(next)] then
+ if head==c then
+ head=next
+ end
+ if stop==next then
+ stop=current
+ end
+ setlink(getprev(c),next)
+ local nextnext=getnext(next)
+ setnext(current,nextnext)
+ local nextnextnext=getnext(nextnext)
+ if nextnextnext then
+ setprev(nextnextnext,current)
+ end
+ setlink(nextnext,c)
+ end
+ if stop==current then break end
+ current=getnext(current)
+ end
+ if getchar(base)==c_nbsp then
+ if base==stop then
+ stop=getprev(stop)
+ end
+ nbspaces=nbspaces-1
+ head=remove_node(head,base)
+ flush_node(base)
+ end
+ return head,stop,nbspaces
+end
+local separator={}
+imerge(separator,consonant)
+imerge(separator,independent_vowel)
+imerge(separator,dependent_vowel)
+imerge(separator,vowel_modifier)
+imerge(separator,stress_tone_mark)
+for k,v in next,nukta do separator[k]=true end
+for k,v in next,halant do separator[k]=true end
+local function analyze_next_chars_one(c,font,variant)
+ local n=getnext(c)
+ if not n then
+ return c
+ end
+ if variant==1 then
+ local v=ischar(n,font)
+ if v and nukta[v] then
+ n=getnext(n)
+ if n then
+ v=ischar(n,font)
+ end
+ end
+ if n and v then
+ local nn=getnext(n)
+ if nn then
+ local vv=ischar(nn,font)
+ if vv then
+ local nnn=getnext(nn)
+ if nnn then
+ local vvv=ischar(nnn,font)
+ if vvv then
+ if vv==c_zwj and consonant[vvv] then
+ c=nnn
+ elseif (vv==c_zwnj or vv==c_zwj) and halant[vvv] then
+ local nnnn=getnext(nnn)
+ if nnnn then
+ local vvvv=ischar(nnnn,font)
+ if vvvv and consonant[vvvv] then
+ c=nnnn
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ elseif variant==2 then
+ local v=ischar(n,font)
+ if v and nukta[v] then
+ c=n
+ end
+ n=getnext(c)
+ if n then
+ v=ischar(n,font)
+ if v then
+ local nn=getnext(n)
+ if nn then
+ local vv=ischar(nn,font)
+ if vv and zw_char[v] then
+ n=nn
+ v=vv
+ nn=getnext(nn)
+ vv=nn and ischar(nn,font)
+ end
+ if vv and halant[v] and consonant[vv] then
+ c=nn
+ end
+ end
+ end
+ end
+ end
+ local n=getnext(c)
+ if not n then
+ return c
+ end
+ local v=ischar(n,font)
+ if not v then
+ return c
+ end
+ local already_pre_mark
+ local already_above_mark
+ local already_below_mark
+ local already_post_mark
+ while dependent_vowel[v] do
+ local vowels=twopart_mark[v] or { v }
+ for k,v in next,vowels do
+ if pre_mark[v] and not already_pre_mark then
+ already_pre_mark=true
+ elseif above_mark[v] and not already_above_mark then
+ already_above_mark=true
+ elseif below_mark[v] and not already_below_mark then
+ already_below_mark=true
+ elseif post_mark[v] and not already_post_mark then
+ already_post_mark=true
+ else
+ return c
+ end
+ end
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if nukta[v] then
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if halant[v] then
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if vowel_modifier[v] then
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ return n
+ else
+ return c
+ end
+end
+local function analyze_next_chars_two(c,font)
+ local n=getnext(c)
+ if not n then
+ return c
+ end
+ local v=ischar(n,font)
+ if v and nukta[v] then
+ c=n
+ end
+ n=c
+ while true do
+ local nn=getnext(n)
+ if nn then
+ local vv=ischar(nn,font)
+ if vv then
+ if halant[vv] then
+ n=nn
+ local nnn=getnext(nn)
+ if nnn then
+ local vvv=ischar(nnn,font)
+ if vvv and zw_char[vvv] then
+ n=nnn
+ end
+ end
+ elseif vv==c_zwnj or vv==c_zwj then
+ local nnn=getnext(nn)
+ if nnn then
+ local vvv=ischar(nnn,font)
+ if vvv and halant[vvv] then
+ n=nnn
+ end
+ end
+ else
+ break
+ end
+ local nn=getnext(n)
+ if nn then
+ local vv=ischar(nn,font)
+ if vv and consonant[vv] then
+ n=nn
+ local nnn=getnext(nn)
+ if nnn then
+ local vvv=ischar(nnn,font)
+ if vvv and nukta[vvv] then
+ n=nnn
+ end
+ end
+ c=n
+ else
+ break
+ end
+ else
+ break
+ end
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if not c then
+ return
+ end
+ local n=getnext(c)
+ if not n then
+ return c
+ end
+ local v=ischar(n,font)
+ if not v then
+ return c
+ end
+ if anudatta[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if halant[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ if v==c_zwnj or v==c_zwj then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ else
+ local already_pre_mark
+ local already_above_mark
+ local already_below_mark
+ local already_post_mark
+ while dependent_vowel[v] do
+ local vowels=twopart_mark[v] or { v }
+ for k,v in next,vowels do
+ if pre_mark[v] and not already_pre_mark then
+ already_pre_mark=true
+ elseif above_mark[v] and not already_above_mark then
+ already_above_mark=true
+ elseif below_mark[v] and not already_below_mark then
+ already_below_mark=true
+ elseif post_mark[v] and not already_post_mark then
+ already_post_mark=true
+ else
+ return c
+ end
+ end
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if nukta[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if halant[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ end
+ if vowel_modifier[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ return n
+ else
+ return c
+ end
+end
+local function method_one(head,font,attr)
+ local current=head
+ local start=true
+ local done=false
+ local nbspaces=0
+ local syllabe=0
+ while current do
+ local char=ischar(current,font)
+ if char then
+ done=true
+ local syllablestart=current
+ local syllableend=nil
+ local c=current
+ local n=getnext(c)
+ local first=char
+ if n and ra[first] then
+ local second=ischar(n,font)
+ if second and halant[second] then
+ local n=getnext(n)
+ if n then
+ local third=ischar(n,font)
+ if third then
+ c=n
+ first=third
+ end
+ end
+ end
+ end
+ local standalone=first==c_nbsp
+ if standalone then
+ local prev=getprev(current)
+ if prev then
+ local prevchar=ischar(prev,font)
+ if not prevchar then
+ elseif not separator[prevchar] then
+ else
+ standalone=false
+ end
+ else
+ end
+ end
+ if standalone then
+ local syllableend=analyze_next_chars_one(c,font,2)
+ current=getnext(syllableend)
+ if syllablestart~=syllableend then
+ head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces)
+ current=getnext(current)
+ end
+ else
+ if consonant[char] then
+ local prevc=true
+ while prevc do
+ prevc=false
+ local n=getnext(current)
+ if not n then
+ break
+ end
+ local v=ischar(n,font)
+ if not v then
+ break
+ end
+ if nukta[v] then
+ n=getnext(n)
+ if not n then
+ break
+ end
+ v=ischar(n,font)
+ if not v then
+ break
+ end
+ end
+ if halant[v] then
+ n=getnext(n)
+ if not n then
+ break
+ end
+ v=ischar(n,font)
+ if not v then
+ break
+ end
+ if v==c_zwnj or v==c_zwj then
+ n=getnext(n)
+ if not n then
+ break
+ end
+ v=ischar(n,font)
+ if not v then
+ break
+ end
+ end
+ if consonant[v] then
+ prevc=true
+ current=n
+ end
+ end
+ end
+ local n=getnext(current)
+ if n then
+ local v=ischar(n,font)
+ if v and nukta[v] then
+ current=n
+ n=getnext(current)
+ end
+ end
+ syllableend=current
+ current=n
+ if current then
+ local v=ischar(current,font)
+ if not v then
+ elseif halant[v] then
+ local n=getnext(current)
+ if n then
+ local v=ischar(n,font)
+ if v and zw_char[v] then
+ syllableend=n
+ current=getnext(n)
+ else
+ syllableend=current
+ current=n
+ end
+ else
+ syllableend=current
+ current=n
+ end
+ else
+ if dependent_vowel[v] then
+ syllableend=current
+ current=getnext(current)
+ v=ischar(current,font)
+ end
+ if v and vowel_modifier[v] then
+ syllableend=current
+ current=getnext(current)
+ v=ischar(current,font)
+ end
+ if v and stress_tone_mark[v] then
+ syllableend=current
+ current=getnext(current)
+ end
+ end
+ end
+ if syllablestart~=syllableend then
+ if syllableend then
+ syllabe=syllabe+1
+ local c=syllablestart
+ local n=getnext(syllableend)
+ while c~=n do
+ setprop(c,a_syllabe,syllabe)
+ c=getnext(c)
+ end
+ end
+ head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces)
+ current=getnext(current)
+ end
+ elseif independent_vowel[char] then
+ syllableend=current
+ current=getnext(current)
+ if current then
+ local v=ischar(current,font)
+ if v then
+ if vowel_modifier[v] then
+ syllableend=current
+ current=getnext(current)
+ v=ischar(current,font)
+ end
+ if v and stress_tone_mark[v] then
+ syllableend=current
+ current=getnext(current)
+ end
+ end
+ end
+ else
+ if show_syntax_errors then
+ local mark=mark_four[char]
+ if mark then
+ head,current=inject_syntax_error(head,current,char)
+ end
+ end
+ current=getnext(current)
+ end
+ end
+ else
+ current=getnext(current)
+ end
+ start=false
+ end
+ if nbspaces>0 then
+ head=replace_all_nbsp(head)
+ end
+ current=head
+ local n=0
+ while current do
+ local char=ischar(current,font)
+ if char then
+ if n==0 and not getprop(current,a_state) then
+ setprop(current,a_state,s_init)
+ end
+ n=n+1
+ else
+ n=0
+ end
+ current=getnext(current)
+ end
+ return head,done
+end
+local function method_two(head,font,attr)
+ local current=head
+ local start=true
+ local done=false
+ local syllabe=0
+ local nbspaces=0
+ while current do
+ local syllablestart=nil
+ local syllableend=nil
+ local char=ischar(current,font)
+ if char then
+ done=true
+ syllablestart=current
+ local c=current
+ local n=getnext(current)
+ if n and ra[char] then
+ local nextchar=ischar(n,font)
+ if nextchar and halant[nextchar] then
+ local n=getnext(n)
+ if n then
+ local nextnextchar=ischar(n,font)
+ if nextnextchar then
+ c=n
+ char=nextnextchar
+ end
+ end
+ end
+ end
+ if independent_vowel[char] then
+ current=analyze_next_chars_one(c,font,1)
+ syllableend=current
+ else
+ local standalone=char==c_nbsp
+ if standalone then
+ nbspaces=nbspaces+1
+ local p=getprev(current)
+ if not p then
+ elseif ischar(p,font) then
+ elseif not separator[getchar(p)] then
+ else
+ standalone=false
+ end
+ end
+ if standalone then
+ current=analyze_next_chars_one(c,font,2)
+ syllableend=current
+ elseif consonant[getchar(current)] then
+ current=analyze_next_chars_two(current,font)
+ syllableend=current
+ end
+ end
+ end
+ if syllableend then
+ syllabe=syllabe+1
+ local c=syllablestart
+ local n=getnext(syllableend)
+ while c~=n do
+ setprop(c,a_syllabe,syllabe)
+ c=getnext(c)
+ end
+ end
+ if syllableend and syllablestart~=syllableend then
+ head,current,nbspaces=reorder_two(head,syllablestart,syllableend,font,attr,nbspaces)
+ end
+ if not syllableend and show_syntax_errors then
+ local char=ischar(current,font)
+ if char and not getprop(current,a_state) then
+ local mark=mark_four[char]
+ if mark then
+ head,current=inject_syntax_error(head,current,char)
+ end
+ end
+ end
+ start=false
+ current=getnext(current)
+ end
+ if nbspaces>0 then
+ head=replace_all_nbsp(head)
+ end
+ current=head
+ local n=0
+ while current do
+ local char=ischar(current,font)
+ if char then
+ if n==0 and not getprop(current,a_state) then
+ setprop(current,a_state,s_init)
+ end
+ n=n+1
+ else
+ n=0
+ end
+ current=getnext(current)
+ end
+ return head,done
+end
+for i=1,nofscripts do
+ methods[scripts_one[i]]=method_one
+ methods[scripts_two[i]]=method_two
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-osdâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ocl†b720867fb19a23f0b50377efd2a3c54a] ---
+
+if not modules then modules={} end modules ['font-ocl']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local tostring,tonumber,next=tostring,tonumber,next
+local round,max=math.round,math.round
+local sortedkeys,sortedhash=table.sortedkeys,table.sortedhash
+local setmetatableindex=table.setmetatableindex
+local formatters=string.formatters
+local tounicode=fonts.mappings.tounicode
+local helpers=fonts.helpers
+local charcommand=helpers.commands.char
+local rightcommand=helpers.commands.right
+local leftcommand=helpers.commands.left
+local downcommand=helpers.commands.down
+local otf=fonts.handlers.otf
+local f_color=formatters["%.3f %.3f %.3f rg"]
+local f_gray=formatters["%.3f g"]
+if context then
+ local startactualtext=nil
+ local stopactualtext=nil
+ function otf.getactualtext(s)
+ if not startactualtext then
+ startactualtext=backends.codeinjections.startunicodetoactualtextdirect
+ stopactualtext=backends.codeinjections.stopunicodetoactualtextdirect
+ end
+ return startactualtext(s),stopactualtext()
+ end
+else
+ local tounicode=fonts.mappings.tounicode16
+ function otf.getactualtext(s)
+ return
+ "/Span << /ActualText <feff"..s.."> >> BDC",
+ "EMC"
+ end
+end
+local sharedpalettes={}
+local hash=setmetatableindex(function(t,k)
+ local v={ "pdf","direct",k }
+ t[k]=v
+ return v
+end)
+if context then
+ local colors=attributes.list[attributes.private('color')] or {}
+ local transparencies=attributes.list[attributes.private('transparency')] or {}
+ function otf.registerpalette(name,values)
+ sharedpalettes[name]=values
+ local color=lpdf.color
+ local transparency=lpdf.transparency
+ local register=colors.register
+ for i=1,#values do
+ local v=values[i]
+ if v=="textcolor" then
+ values[i]=false
+ else
+ local c=nil
+ local t=nil
+ if type(v)=="table" then
+ c=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
+ c=colors[v]
+ t=transparencies[v]
+ end
+ if c and t then
+ values[i]=hash[color(1,c).." "..transparency(t)]
+ elseif c then
+ values[i]=hash[color(1,c)]
+ elseif t then
+ values[i]=hash[color(1,t)]
+ end
+ end
+ end
+ end
+else
+ function otf.registerpalette(name,values)
+ sharedpalettes[name]=values
+ for i=1,#values do
+ local v=values[i]
+ if v then
+ 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
+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 start={ "pdf","mode","font" }
+local push={ "pdf","page","q" }
+local pop={ "pdf","page","Q" }
+local function initialize(tfmdata,kind,value)
+ if value then
+ local resources=tfmdata.resources
+ local palettes=resources.colorpalettes
+ if palettes then
+ local converted=resources.converted
+ if not converted then
+ converted=setmetatableindex(convert)
+ resources.converted=converted
+ end
+ local colorvalues=sharedpalettes[value]
+ local default=false
+ if colorvalues then
+ default=colorvalues[#colorvalues]
+ else
+ colorvalues=converted[palettes[tonumber(value) or 1] or palettes[1]] or {}
+ end
+ local classes=#colorvalues
+ if classes==0 then
+ return
+ end
+ local characters=tfmdata.characters
+ local descriptions=tfmdata.descriptions
+ local properties=tfmdata.properties
+ properties.virtualized=true
+ tfmdata.fonts={
+ { id=0 }
+ }
+ local getactualtext=otf.getactualtext
+ local b,e=getactualtext(tounicode(0xFFFD))
+ local actualb={ "pdf","page",b }
+ local actuale={ "pdf","page",e }
+ for unicode,character in next,characters do
+ local description=descriptions[unicode]
+ if description then
+ local colorlist=description.colors
+ if colorlist then
+ local u=description.unicode or characters[unicode].unicode
+ local w=character.width or 0
+ local s=#colorlist
+ local goback=w~=0 and leftcommand[w] or nil
+ local t={
+ start,
+ not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }
+ }
+ local n=2
+ local l=nil
+ local f=false
+ for i=1,s do
+ local entry=colorlist[i]
+ local v=colorvalues[entry.class] or default
+ if v and l~=v then
+ if f then
+ n=n+1 t[n]=pop
+ end
+ n=n+1 t[n]=push
+ f=true
+ n=n+1 t[n]=v
+ l=v
+ else
+ if f then
+ n=n+1 t[n]=pop
+ end
+ f=false
+ l=nil
+ end
+ n=n+1 t[n]=charcommand[entry.slot]
+ if s>1 and i<s and goback then
+ n=n+1 t[n]=goback
+ end
+ end
+ if f then
+ n=n+1 t[n]=pop
+ end
+ n=n+1 t[n]=actuale
+ character.commands=t
+ end
+ end
+ end
+ end
+ end
+end
+fonts.handlers.otf.features.register {
+ name="colr",
+ description="color glyphs",
+ manipulators={
+ base=initialize,
+ node=initialize,
+ }
+}
+do
+ local nofstreams=0
+ local f_name=formatters[ [[pdf-glyph-%05i]] ]
+ local f_used=context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ]
+ local hashed={}
+ local cache={}
+ local openpdf=pdfe.new
+ function otf.storepdfdata(pdf)
+ local done=hashed[pdf]
+ if not done then
+ nofstreams=nofstreams+1
+ local f=f_name(nofstreams)
+ local n=openpdf(pdf,#pdf,f)
+ done=f_used(n)
+ hashed[pdf]=done
+ end
+ return done
+ end
+end
+local function pdftovirtual(tfmdata,pdfshapes,kind)
+ if not tfmdata or not pdfshapes or not kind then
+ return
+ end
+ local characters=tfmdata.characters
+ local properties=tfmdata.properties
+ local parameters=tfmdata.parameters
+ local hfactor=parameters.hfactor
+ properties.virtualized=true
+ tfmdata.fonts={
+ { id=0 }
+ }
+ local getactualtext=otf.getactualtext
+ local storepdfdata=otf.storepdfdata
+ local b,e=getactualtext(tounicode(0xFFFD))
+ local actualb={ "pdf","page",b }
+ local actuale={ "pdf","page",e }
+ local vfimage=lpdf and lpdf.vfimage or function(wd,ht,dp,data,name)
+ local name=storepdfdata(data)
+ return { "image",{ filename=name,width=wd,height=ht,depth=dp } }
+ end
+ for unicode,character in sortedhash(characters) do
+ local index=character.index
+ if index then
+ local pdf=pdfshapes[index]
+ local typ=type(pdf)
+ local data=nil
+ local dx=nil
+ local dy=nil
+ if typ=="table" then
+ data=pdf.data
+ dx=pdf.dx or 0
+ dy=pdf.dy or 0
+ elseif typ=="string" then
+ data=pdf
+ dx=0
+ dy=0
+ end
+ if data then
+ local bt=unicode and getactualtext(unicode)
+ local wd=character.width or 0
+ local ht=character.height or 0
+ local dp=character.depth or 0
+ character.commands={
+ not unicode and actualb or { "pdf","page",(getactualtext(unicode)) },
+ downcommand[dp+dy*hfactor],
+ rightcommand[dx*hfactor],
+ vfimage(wd,ht,dp,data,name),
+ actuale,
+ }
+ character[kind]=true
+ end
+ end
+ end
+end
+local otfsvg=otf.svg or {}
+otf.svg=otfsvg
+otf.svgenabled=true
+do
+ local report_svg=logs.reporter("fonts","svg conversion")
+ local loaddata=io.loaddata
+ local savedata=io.savedata
+ local remove=os.remove
+ if context and xml.convert then
+ local xmlconvert=xml.convert
+ local xmlfirst=xml.first
+ function otfsvg.filterglyph(entry,index)
+ local svg=xmlconvert(entry.data)
+ local root=svg and xmlfirst(svg,"/svg[@id='glyph"..index.."']")
+ local data=root and tostring(root)
+ return data
+ end
+ else
+ function otfsvg.filterglyph(entry,index)
+ return entry.data
+ end
+ end
+ local runner=sandbox and sandbox.registerrunner {
+ name="otfsvg",
+ program="inkscape",
+ method="pipeto",
+ template="--shell > temp-otf-svg-shape.log",
+ reporter=report_svg,
+ }
+ if not runner then
+ runner=function()
+ return io.open("inkscape --shell > temp-otf-svg-shape.log","w")
+ end
+ end
+ function otfsvg.topdf(svgshapes)
+ local pdfshapes={}
+ local inkscape=runner()
+ if inkscape then
+ local nofshapes=#svgshapes
+ local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"]
+ local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"]
+ local f_convert=formatters["%s --export-pdf=%s\n"]
+ local filterglyph=otfsvg.filterglyph
+ local nofdone=0
+ report_svg("processing %i svg containers",nofshapes)
+ statistics.starttiming()
+ for i=1,nofshapes do
+ local entry=svgshapes[i]
+ for index=entry.first,entry.last do
+ local data=filterglyph(entry,index)
+ if data and data~="" then
+ local svgfile=f_svgfile(index)
+ local pdffile=f_pdffile(index)
+ savedata(svgfile,data)
+ inkscape:write(f_convert(svgfile,pdffile))
+ pdfshapes[index]=true
+ nofdone=nofdone+1
+ if nofdone%100==0 then
+ report_svg("%i shapes processed",nofdone)
+ end
+ end
+ end
+ end
+ inkscape:write("quit\n")
+ inkscape:close()
+ report_svg("processing %i pdf results",nofshapes)
+ for index in next,pdfshapes do
+ local svgfile=f_svgfile(index)
+ local pdffile=f_pdffile(index)
+ pdfshapes[index]=loaddata(pdffile)
+ remove(svgfile)
+ remove(pdffile)
+ end
+ statistics.stoptiming()
+ if statistics.elapsedseconds then
+ report_svg("svg conversion time %s",statistics.elapsedseconds() or "-")
+ end
+ end
+ return pdfshapes
+ end
+end
+local function initializesvg(tfmdata,kind,value)
+ if value and otf.svgenabled then
+ local svg=tfmdata.properties.svg
+ local hash=svg and svg.hash
+ local timestamp=svg and svg.timestamp
+ if not hash then
+ return
+ end
+ local pdffile=containers.read(otf.pdfcache,hash)
+ local pdfshapes=pdffile and pdffile.pdfshapes
+ if not pdfshapes or pdffile.timestamp~=timestamp then
+ local svgfile=containers.read(otf.svgcache,hash)
+ local svgshapes=svgfile and svgfile.svgshapes
+ pdfshapes=svgshapes and otfsvg.topdf(svgshapes) or {}
+ containers.write(otf.pdfcache,hash,{
+ pdfshapes=pdfshapes,
+ timestamp=timestamp,
+ })
+ end
+ pdftovirtual(tfmdata,pdfshapes,"svg")
+ end
+end
+fonts.handlers.otf.features.register {
+ name="svg",
+ description="svg glyphs",
+ manipulators={
+ base=initializesvg,
+ node=initializesvg,
+ }
+}
+local otfpng=otf.png or {}
+otf.png=otfpng
+otf.pngenabled=true
+do
+ local report_png=logs.reporter("fonts","png conversion")
+ local loaddata=io.loaddata
+ local savedata=io.savedata
+ local remove=os.remove
+ local runner=sandbox and sandbox.registerrunner {
+ name="otfpng",
+ program="gm",
+ template="convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log",
+ }
+ if not runner then
+ runner=function()
+ return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log")
+ end
+ end
+ function otfpng.topdf(pngshapes)
+ local pdfshapes={}
+ local pngfile="temp-otf-png-shape.png"
+ local pdffile="temp-otf-png-shape.pdf"
+ local nofdone=0
+ local indices=sortedkeys(pngshapes)
+ local nofindices=#indices
+ report_png("processing %i png containers",nofindices)
+ statistics.starttiming()
+ for i=1,nofindices do
+ local index=indices[i]
+ local entry=pngshapes[index]
+ local data=entry.data
+ local x=entry.x
+ local y=entry.y
+ savedata(pngfile,data)
+ runner()
+ pdfshapes[index]={
+ x=x~=0 and x or nil,
+ y=y~=0 and y or nil,
+ data=loaddata(pdffile),
+ }
+ nofdone=nofdone+1
+ if nofdone%100==0 then
+ report_png("%i shapes processed",nofdone)
+ end
+ end
+ report_png("processing %i pdf results",nofindices)
+ remove(pngfile)
+ remove(pdffile)
+ statistics.stoptiming()
+ if statistics.elapsedseconds then
+ report_png("png conversion time %s",statistics.elapsedseconds() or "-")
+ end
+ return pdfshapes
+ end
+end
+local function initializepng(tfmdata,kind,value)
+ if value and otf.pngenabled then
+ local png=tfmdata.properties.png
+ local hash=png and png.hash
+ local timestamp=png and png.timestamp
+ if not hash then
+ return
+ end
+ local pdffile=containers.read(otf.pdfcache,hash)
+ local pdfshapes=pdffile and pdffile.pdfshapes
+ if not pdfshapes or pdffile.timestamp~=timestamp then
+ local pngfile=containers.read(otf.pngcache,hash)
+ local pngshapes=pngfile and pngfile.pngshapes
+ pdfshapes=pngshapes and otfpng.topdf(pngshapes) or {}
+ containers.write(otf.pdfcache,hash,{
+ pdfshapes=pdfshapes,
+ timestamp=timestamp,
+ })
+ end
+ pdftovirtual(tfmdata,pdfshapes,"png")
+ end
+end
+fonts.handlers.otf.features.register {
+ name="sbix",
+ description="sbix glyphs",
+ manipulators={
+ base=initializepng,
+ node=initializepng,
+ }
+}
+fonts.handlers.otf.features.register {
+ name="cblc",
+ description="cblc glyphs",
+ manipulators={
+ base=initializepng,
+ node=initializepng,
+ }
+}
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oclâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otc†95a4ff28ba4afb55a978a4aecfd688bf] ---
+
+if not modules then modules={} end modules ['font-otc']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local insert,sortedkeys,sortedhash,tohash=table.insert,table.sortedkeys,table.sortedhash,table.tohash
+local type,next,tonumber=type,next,tonumber
+local lpegmatch=lpeg.match
+local utfbyte,utflen=utf.byte,utf.len
+local sortedhash=table.sortedhash
+local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
+local report_otf=logs.reporter("fonts","otf loading")
+local fonts=fonts
+local otf=fonts.handlers.otf
+local registerotffeature=otf.features.register
+local setmetatableindex=table.setmetatableindex
+local checkmerge=fonts.helpers.checkmerge
+local checkflags=fonts.helpers.checkflags
+local checksteps=fonts.helpers.checksteps
+local normalized={
+ substitution="substitution",
+ single="substitution",
+ ligature="ligature",
+ alternate="alternate",
+ multiple="multiple",
+ kern="kern",
+ pair="pair",
+ single="single",
+ chainsubstitution="chainsubstitution",
+ chainposition="chainposition",
+}
+local types={
+ substitution="gsub_single",
+ ligature="gsub_ligature",
+ alternate="gsub_alternate",
+ multiple="gsub_multiple",
+ kern="gpos_pair",
+ pair="gpos_pair",
+ single="gpos_single",
+ chainsubstitution="gsub_contextchain",
+ chainposition="gpos_contextchain",
+}
+local names={
+ gsub_single="gsub",
+ gsub_multiple="gsub",
+ gsub_alternate="gsub",
+ gsub_ligature="gsub",
+ gsub_context="gsub",
+ gsub_contextchain="gsub",
+ gsub_reversecontextchain="gsub",
+ gpos_single="gpos",
+ gpos_pair="gpos",
+ gpos_cursive="gpos",
+ gpos_mark2base="gpos",
+ gpos_mark2ligature="gpos",
+ gpos_mark2mark="gpos",
+ gpos_context="gpos",
+ gpos_contextchain="gpos",
+}
+setmetatableindex(types,function(t,k) t[k]=k return k end)
+local everywhere={ ["*"]={ ["*"]=true } }
+local noflags={ false,false,false,false }
+local function getrange(sequences,category)
+ local count=#sequences
+ local first=nil
+ local last=nil
+ for i=1,count do
+ local t=sequences[i].type
+ if t and names[t]==category then
+ if not first then
+ first=i
+ end
+ last=i
+ end
+ end
+ return first or 1,last or count
+end
+local function validspecification(specification,name)
+ local dataset=specification.dataset
+ if dataset then
+ elseif specification[1] then
+ dataset=specification
+ specification={ dataset=dataset }
+ else
+ dataset={ { data=specification.data } }
+ specification.data=nil
+ specification.dataset=dataset
+ end
+ local first=dataset[1]
+ if first then
+ first=first.data
+ end
+ if not first then
+ report_otf("invalid feature specification, no dataset")
+ return
+ end
+ if type(name)~="string" then
+ name=specification.name or first.name
+ end
+ if type(name)~="string" then
+ report_otf("invalid feature specification, no name")
+ return
+ end
+ local n=#dataset
+ if n>0 then
+ for i=1,n do
+ setmetatableindex(dataset[i],specification)
+ end
+ return specification,name
+ end
+end
+local function addfeature(data,feature,specifications)
+ if not specifications then
+ report_otf("missing specification")
+ return
+ end
+ local descriptions=data.descriptions
+ local resources=data.resources
+ local features=resources.features
+ local sequences=resources.sequences
+ if not features or not sequences then
+ report_otf("missing specification")
+ return
+ end
+ local alreadydone=resources.alreadydone
+ if not alreadydone then
+ alreadydone={}
+ resources.alreadydone=alreadydone
+ end
+ if alreadydone[specifications] then
+ return
+ else
+ alreadydone[specifications]=true
+ end
+ local fontfeatures=resources.features or everywhere
+ local unicodes=resources.unicodes
+ local splitter=lpeg.splitter(" ",unicodes)
+ local done=0
+ local skip=0
+ local aglunicodes=false
+ local specifications=validspecification(specifications,feature)
+ if not specifications then
+ return
+ end
+ local p=lpeg.P("P")*(lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)*lpeg.P(-1)
+ local function tounicode(code)
+ if not code then
+ return
+ end
+ if type(code)=="number" then
+ return code
+ end
+ local u=unicodes[code]
+ if u then
+ return u
+ end
+ if utflen(code)==1 then
+ u=utfbyte(code)
+ if u then
+ return u
+ end
+ end
+ local u=lpegmatch(p,code)
+ if u then
+ return u
+ end
+ if not aglunicodes then
+ aglunicodes=fonts.encodings.agl.unicodes
+ end
+ local u=aglunicodes[code]
+ if u then
+ return u
+ end
+ end
+ local coverup=otf.coverup
+ local coveractions=coverup.actions
+ local stepkey=coverup.stepkey
+ local register=coverup.register
+ local function prepare_substitution(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ else
+ if type(replacement)=="table" then
+ replacement=replacement[1]
+ end
+ replacement=tounicode(replacement)
+ if replacement and descriptions[replacement] then
+ cover(coverage,unicode,replacement)
+ done=done+1
+ else
+ skip=skip+1
+ end
+ end
+ end
+ return coverage
+ end
+ local function prepare_alternate(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ elseif type(replacement)=="table" then
+ local r={}
+ for i=1,#replacement do
+ local u=tounicode(replacement[i])
+ r[i]=(nocheck or descriptions[u]) and u or unicode
+ end
+ cover(coverage,unicode,r)
+ done=done+1
+ else
+ local u=tounicode(replacement)
+ if u then
+ cover(coverage,unicode,{ u })
+ done=done+1
+ else
+ skip=skip+1
+ end
+ end
+ end
+ return coverage
+ end
+ local function prepare_multiple(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ elseif type(replacement)=="table" then
+ local r={}
+ local n=0
+ for i=1,#replacement do
+ local u=tounicode(replacement[i])
+ if nocheck or descriptions[u] then
+ n=n+1
+ r[n]=u
+ end
+ end
+ if n>0 then
+ cover(coverage,unicode,r)
+ done=done+1
+ else
+ skip=skip+1
+ end
+ else
+ local u=tounicode(replacement)
+ if u then
+ cover(coverage,unicode,{ u })
+ done=done+1
+ else
+ skip=skip+1
+ end
+ end
+ end
+ return coverage
+ end
+ local function prepare_ligature(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,ligature in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ else
+ if type(ligature)=="string" then
+ ligature={ lpegmatch(splitter,ligature) }
+ end
+ local present=true
+ for i=1,#ligature do
+ local l=ligature[i]
+ local u=tounicode(l)
+ if nocheck or descriptions[u] then
+ ligature[i]=u
+ else
+ present=false
+ break
+ end
+ end
+ if present then
+ cover(coverage,unicode,ligature)
+ done=done+1
+ else
+ skip=skip+1
+ end
+ end
+ end
+ return coverage
+ end
+ local function resetspacekerns()
+ data.properties.hasspacekerns=true
+ data.resources .spacekerns=nil
+ end
+ local function prepare_kern(list,featuretype)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ local isspace=false
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if description and type(replacement)=="table" then
+ local r={}
+ for k,v in next,replacement do
+ local u=tounicode(k)
+ if u then
+ r[u]=v
+ if u==32 then
+ isspace=true
+ end
+ end
+ end
+ if next(r) then
+ cover(coverage,unicode,r)
+ done=done+1
+ if unicode==32 then
+ isspace=true
+ end
+ else
+ skip=skip+1
+ end
+ else
+ skip=skip+1
+ end
+ end
+ if isspace then
+ resetspacekerns()
+ end
+ return coverage
+ end
+ local function prepare_pair(list,featuretype)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ if cover then
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if description and type(replacement)=="table" then
+ local r={}
+ for k,v in next,replacement do
+ local u=tounicode(k)
+ if u then
+ r[u]=v
+ if u==32 then
+ isspace=true
+ end
+ end
+ end
+ if next(r) then
+ cover(coverage,unicode,r)
+ done=done+1
+ if unicode==32 then
+ isspace=true
+ end
+ else
+ skip=skip+1
+ end
+ else
+ skip=skip+1
+ end
+ end
+ if isspace then
+ resetspacekerns()
+ end
+ else
+ report_otf("unknown cover type %a",featuretype)
+ end
+ return coverage
+ end
+ local prepare_single=prepare_pair
+ local function prepare_chain(list,featuretype,sublookups)
+ local rules=list.rules
+ local coverage={}
+ if rules then
+ local rulehash={}
+ local rulesize=0
+ local lookuptype=types[featuretype]
+ for nofrules=1,#rules do
+ local rule=rules[nofrules]
+ local current=rule.current
+ local before=rule.before
+ local after=rule.after
+ local replacements=rule.replacements or false
+ local sequence={}
+ local nofsequences=0
+ if before then
+ for n=1,#before do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=before[n]
+ end
+ end
+ local start=nofsequences+1
+ for n=1,#current do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=current[n]
+ end
+ local stop=nofsequences
+ if after then
+ for n=1,#after do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=after[n]
+ end
+ end
+ local lookups=rule.lookups or false
+ local subtype=nil
+ if lookups and sublookups then
+ for k,v in sortedhash(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 }
+ if not subtype then
+ subtype=lookup.type
+ end
+ elseif v==0 then
+ lookups[k]={ { type="gsub_remove" } }
+ else
+ lookups[k]=false
+ end
+ else
+ lookups[k]=false
+ end
+ end
+ end
+ if nofsequences>0 then
+ local hashed={}
+ for i=1,nofsequences do
+ local t={}
+ local s=sequence[i]
+ for i=1,#s do
+ local u=tounicode(s[i])
+ if u then
+ t[u]=true
+ end
+ end
+ hashed[i]=t
+ end
+ sequence=hashed
+ rulesize=rulesize+1
+ rulehash[rulesize]={
+ nofrules,
+ lookuptype,
+ sequence,
+ start,
+ stop,
+ lookups,
+ replacements,
+ subtype,
+ }
+ for unic in sortedhash(sequence[start]) do
+ local cu=coverage[unic]
+ if not cu then
+ coverage[unic]=rulehash
+ end
+ end
+ sequence.n=nofsequences
+ end
+ end
+ rulehash.n=rulesize
+ end
+ return coverage
+ end
+ local dataset=specifications.dataset
+ local function report(name,category,position,first,last,sequences)
+ report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]",
+ name,category,position,first,last,1,#sequences)
+ end
+ local function inject(specification,sequences,sequence,first,last,category,name)
+ local position=specification.position or false
+ if not position then
+ position=specification.prepend
+ if position==true then
+ if trace_loading then
+ report(name,category,first,first,last,sequences)
+ end
+ insert(sequences,first,sequence)
+ return
+ end
+ end
+ if not position then
+ position=specification.append
+ if position==true then
+ if trace_loading then
+ report(name,category,last+1,first,last,sequences)
+ end
+ insert(sequences,last+1,sequence)
+ return
+ end
+ end
+ local kind=type(position)
+ if kind=="string" then
+ local index=false
+ for i=first,last do
+ local s=sequences[i]
+ local f=s.features
+ if f then
+ for k in sortedhash(f) do
+ if k==position then
+ index=i
+ break
+ end
+ end
+ if index then
+ break
+ end
+ end
+ end
+ if index then
+ position=index
+ else
+ position=last+1
+ end
+ elseif kind=="number" then
+ if position<0 then
+ position=last-position+1
+ end
+ if position>last then
+ position=last+1
+ elseif position<first then
+ position=first
+ end
+ else
+ position=last+1
+ end
+ if trace_loading then
+ report(name,category,position,first,last,sequences)
+ end
+ insert(sequences,position,sequence)
+ end
+ for s=1,#dataset do
+ local specification=dataset[s]
+ local valid=specification.valid
+ local feature=specification.name or feature
+ if not feature or feature=="" then
+ report_otf("no valid name given for extra feature")
+ elseif not valid or valid(data,specification,feature) then
+ local initialize=specification.initialize
+ if initialize then
+ specification.initialize=initialize(specification,data) and initialize or nil
+ end
+ local askedfeatures=specification.features or everywhere
+ local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
+ local featuretype=normalized[specification.type or "substitution"] or "substitution"
+ local featureflags=specification.flags or noflags
+ local nocheck=specification.nocheck
+ local futuresteps=specification.futuresteps
+ local featureorder=specification.order or { feature }
+ local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0
+ local nofsteps=0
+ local steps={}
+ local sublookups=specification.lookups
+ local category=nil
+ checkflags(specification,resources)
+ if sublookups then
+ local s={}
+ for i=1,#sublookups do
+ local specification=sublookups[i]
+ local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
+ local featuretype=normalized[specification.type or "substitution"] or "substitution"
+ local featureflags=specification.flags or noflags
+ local nofsteps=0
+ local steps={}
+ for i=1,#askedsteps do
+ local list=askedsteps[i]
+ local coverage=nil
+ local format=nil
+ if featuretype=="substitution" then
+ coverage=prepare_substitution(list,featuretype,nocheck)
+ elseif featuretype=="ligature" then
+ coverage=prepare_ligature(list,featuretype,nocheck)
+ elseif featuretype=="alternate" then
+ coverage=prepare_alternate(list,featuretype,nocheck)
+ elseif featuretype=="multiple" then
+ coverage=prepare_multiple(list,featuretype,nocheck)
+ elseif featuretype=="kern" or featuretype=="move" then
+ format=featuretype
+ coverage=prepare_kern(list,featuretype)
+ elseif featuretype=="pair" then
+ format="pair"
+ coverage=prepare_pair(list,featuretype)
+ elseif featuretype=="single" then
+ format="single"
+ coverage=prepare_single(list,featuretype)
+ end
+ if coverage and next(coverage) then
+ nofsteps=nofsteps+1
+ steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
+ end
+ end
+ checkmerge(specification)
+ checksteps(specification)
+ s[i]={
+ [stepkey]=steps,
+ nofsteps=nofsteps,
+ flags=featureflags,
+ type=types[featuretype],
+ }
+ end
+ sublookups=s
+ end
+ for i=1,#askedsteps do
+ local list=askedsteps[i]
+ local coverage=nil
+ local format=nil
+ if featuretype=="substitution" then
+ category="gsub"
+ coverage=prepare_substitution(list,featuretype,nocheck)
+ elseif featuretype=="ligature" then
+ category="gsub"
+ coverage=prepare_ligature(list,featuretype,nocheck)
+ elseif featuretype=="alternate" then
+ category="gsub"
+ coverage=prepare_alternate(list,featuretype,nocheck)
+ elseif featuretype=="multiple" then
+ category="gsub"
+ coverage=prepare_multiple(list,featuretype,nocheck)
+ elseif featuretype=="kern" or featuretype=="move" then
+ category="gpos"
+ format=featuretype
+ coverage=prepare_kern(list,featuretype)
+ elseif featuretype=="pair" then
+ category="gpos"
+ format="pair"
+ coverage=prepare_pair(list,featuretype)
+ elseif featuretype=="single" then
+ category="gpos"
+ format="single"
+ coverage=prepare_single(list,featuretype)
+ elseif featuretype=="chainsubstitution" then
+ category="gsub"
+ coverage=prepare_chain(list,featuretype,sublookups)
+ elseif featuretype=="chainposition" then
+ category="gpos"
+ coverage=prepare_chain(list,featuretype,sublookups)
+ else
+ report_otf("not registering feature %a, unknown category",feature)
+ return
+ end
+ if coverage and next(coverage) then
+ nofsteps=nofsteps+1
+ steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
+ end
+ end
+ if nofsteps>0 then
+ for k,v in next,askedfeatures do
+ if v[1] then
+ askedfeatures[k]=tohash(v)
+ end
+ end
+ if featureflags[1] then featureflags[1]="mark" end
+ if featureflags[2] then featureflags[2]="ligature" end
+ if featureflags[3] then featureflags[3]="base" end
+ local steptype=types[featuretype]
+ local sequence={
+ chain=featurechain,
+ features={ [feature]=askedfeatures },
+ flags=featureflags,
+ name=feature,
+ order=featureorder,
+ [stepkey]=steps,
+ nofsteps=nofsteps,
+ type=steptype,
+ }
+ checkflags(sequence,resources)
+ checkmerge(sequence)
+ checksteps(sequence)
+ local first,last=getrange(sequences,category)
+ inject(specification,sequences,sequence,first,last,category,feature)
+ local features=fontfeatures[category]
+ if not features then
+ features={}
+ fontfeatures[category]=features
+ end
+ local k=features[feature]
+ if not k then
+ k={}
+ features[feature]=k
+ end
+ for script,languages in next,askedfeatures do
+ local kk=k[script]
+ if not kk then
+ kk={}
+ k[script]=kk
+ end
+ for language,value in next,languages do
+ kk[language]=value
+ end
+ end
+ end
+ end
+ end
+ if trace_loading then
+ report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip)
+ end
+end
+otf.enhancers.addfeature=addfeature
+local extrafeatures={}
+local knownfeatures={}
+function otf.addfeature(name,specification)
+ if type(name)=="table" then
+ specification=name
+ end
+ if type(specification)~="table" then
+ report_otf("invalid feature specification, no valid table")
+ return
+ end
+ specification,name=validspecification(specification,name)
+ if name and specification then
+ local slot=knownfeatures[name]
+ if not slot then
+ slot=#extrafeatures+1
+ knownfeatures[name]=slot
+ elseif specification.overload==false then
+ slot=#extrafeatures+1
+ knownfeatures[name]=slot
+ else
+ end
+ specification.name=name
+ extrafeatures[slot]=specification
+ end
+end
+local function enhance(data,filename,raw)
+ for slot=1,#extrafeatures do
+ local specification=extrafeatures[slot]
+ addfeature(data,specification.name,specification)
+ end
+end
+otf.enhancers.enhance=enhance
+otf.enhancers.register("check extra features",enhance)
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otcâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-onr†d4d2449b4084e6afb1837ae5835082cc] ---
+
+if not modules then modules={} end modules ['font-onr']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local fonts,logs,trackers,resolvers=fonts,logs,trackers,resolvers
+local next,type,tonumber,rawget,rawset=next,type,tonumber,rawget,rawset
+local match,lower,gsub,strip,find=string.match,string.lower,string.gsub,string.strip,string.find
+local char,byte,sub=string.char,string.byte,string.sub
+local abs=math.abs
+local bxor,rshift=bit32.bxor,bit32.rshift
+local P,S,R,V,Cmt,C,Ct,Cs,Carg,Cf,Cg,Cc=lpeg.P,lpeg.S,lpeg.R,lpeg.V,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg,lpeg.Cc
+local lpegmatch,patterns=lpeg.match,lpeg.patterns
+local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
+local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
+local report_afm=logs.reporter("fonts","afm loading")
+local report_pfb=logs.reporter("fonts","pfb loading")
+local handlers=fonts.handlers
+local afm=handlers.afm or {}
+handlers.afm=afm
+local readers=afm.readers or {}
+afm.readers=readers
+afm.version=1.513
+local get_indexes,get_shapes
+do
+ local decrypt
+ do
+ local r,c1,c2,n=0,0,0,0
+ local function step(c)
+ local cipher=byte(c)
+ local plain=bxor(cipher,rshift(r,8))
+ r=((cipher+r)*c1+c2)%65536
+ return char(plain)
+ end
+ decrypt=function(binary,initial,seed)
+ r,c1,c2,n=initial,52845,22719,seed
+ binary=gsub(binary,".",step)
+ return sub(binary,n+1)
+ end
+ end
+ local charstrings=P("/CharStrings")
+ local subroutines=P("/Subrs")
+ local encoding=P("/Encoding")
+ local dup=P("dup")
+ local put=P("put")
+ local array=P("array")
+ local name=P("/")*C((R("az","AZ","09")+S("-_."))^1)
+ local digits=R("09")^1
+ local cardinal=digits/tonumber
+ local spaces=P(" ")^1
+ local spacing=patterns.whitespace^0
+ local routines,vector,chars,n,m
+ local initialize=function(str,position,size)
+ n=0
+ m=size
+ return position+1
+ end
+ local setroutine=function(str,position,index,size,filename)
+ if routines[index] then
+ return false
+ end
+ local forward=position+size
+ local stream=decrypt(sub(str,position+1,forward),4330,4)
+ routines[index]={ byte(stream,1,#stream) }
+ n=n+1
+ if n>=m then
+ return #str
+ end
+ return forward+1
+ end
+ local setvector=function(str,position,name,size,filename)
+ local forward=position+tonumber(size)
+ if n>=m then
+ return #str
+ elseif forward<#str then
+ if n==0 and name~=".notdef" then
+ report_pfb("reserving .notdef at index 0 in %a",filename)
+ n=n+1
+ end
+ vector[n]=name
+ n=n+1
+ return forward
+ else
+ return #str
+ end
+ end
+ local setshapes=function(str,position,name,size,filename)
+ local forward=position+tonumber(size)
+ local stream=sub(str,position+1,forward)
+ if n>m then
+ return #str
+ elseif forward<#str then
+ if n==0 and name~=".notdef" then
+ report_pfb("reserving .notdef at index 0 in %a",filename)
+ n=n+1
+ end
+ vector[n]=name
+ n=n+1
+ chars [n]=decrypt(stream,4330,4)
+ return forward
+ else
+ return #str
+ end
+ end
+ local p_rd=spacing*(P("RD")+P("-|"))
+ local p_np=spacing*(P("NP")+P("|"))
+ local p_nd=spacing*(P("ND")+P("|"))
+ local p_filterroutines=
+ (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd*Carg(1),setroutine)*p_np+(1-p_nd))^1
+ local p_filtershapes=
+ (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd*Carg(1),setshapes)*p_nd+P(1))^1
+ local p_filternames=Ct (
+ (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*Carg(1),setvector)+P(1))^1
+ )
+ local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf(
+ Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1
+,rawset)
+ local key=spacing*P("/")*R("az","AZ")
+ local str=spacing*Cs { (P("(")/"")*((1-P("\\(")-P("\\)")-S("()"))+V(1))^0*(P(")")/"") }
+ local num=spacing*(R("09")+S("+-."))^1/tonumber
+ local arr=spacing*Ct (S("[{")*(num)^0*spacing*S("]}"))
+ local boo=spacing*(P("true")*Cc(true)+P("false")*Cc(false))
+ local nam=spacing*P("/")*Cs(R("az","AZ")^1)
+ local p_filtermetadata=(
+ P("/")*Carg(1)*((
+ C("version")*str+C("Copyright")*str+C("Notice")*str+C("FullName")*str+C("FamilyName")*str+C("Weight")*str+C("ItalicAngle")*num+C("isFixedPitch")*boo+C("UnderlinePosition")*num+C("UnderlineThickness")*num+C("FontName")*nam+C("FontMatrix")*arr+C("FontBBox")*arr
+ ) )/function(t,k,v) t[lower(k)]=v end+P(1)
+ )^0*Carg(1)
+ local function loadpfbvector(filename,shapestoo,streams)
+ local data=io.loaddata(resolvers.findfile(filename))
+ if not data then
+ report_pfb("no data in %a",filename)
+ return
+ end
+ if not (find(data,"!PS-AdobeFont-",1,true) or find(data,"%!FontType1",1,true)) then
+ report_pfb("no font in %a",filename)
+ return
+ end
+ local ascii,binary=match(data,"(.*)eexec%s+......(.*)")
+ if not binary then
+ report_pfb("no binary data in %a",filename)
+ return
+ end
+ binary=decrypt(binary,55665,4)
+ local names={}
+ local encoding=lpegmatch(p_filterencoding,ascii)
+ local metadata=lpegmatch(p_filtermetadata,ascii,1,{})
+ local glyphs={}
+ routines,vector,chars={},{},{}
+ if shapestoo or streams then
+ lpegmatch(p_filterroutines,binary,1,filename)
+ lpegmatch(p_filtershapes,binary,1,filename)
+ local data={
+ dictionaries={
+ {
+ charstrings=chars,
+ charset=vector,
+ subroutines=routines,
+ }
+ },
+ }
+ fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,"cff",streams,true)
+ else
+ lpegmatch(p_filternames,binary,1,filename)
+ end
+ names=vector
+ routines,vector,chars=nil,nil,nil
+ return names,encoding,glyphs,metadata
+ end
+ local pfb=handlers.pfb or {}
+ handlers.pfb=pfb
+ pfb.loadvector=loadpfbvector
+ get_indexes=function(data,pfbname)
+ local vector=loadpfbvector(pfbname)
+ if vector then
+ local characters=data.characters
+ if trace_loading then
+ report_afm("getting index data from %a",pfbname)
+ end
+ for index=0,#vector do
+ local name=vector[index]
+ local char=characters[name]
+ if char then
+ if trace_indexing then
+ report_afm("glyph %a has index %a",name,index)
+ end
+ char.index=index
+ else
+ if trace_indexing then
+ report_afm("glyph %a has index %a but no data",name,index)
+ end
+ end
+ end
+ end
+ end
+ get_shapes=function(pfbname)
+ local vector,encoding,glyphs=loadpfbvector(pfbname,true)
+ return glyphs
+ end
+end
+local spacer=patterns.spacer
+local whitespace=patterns.whitespace
+local lineend=patterns.newline
+local spacing=spacer^0
+local number=spacing*S("+-")^-1*(R("09")+S("."))^1/tonumber
+local name=spacing*C((1-whitespace)^1)
+local words=spacing*((1-lineend)^1/strip)
+local rest=(1-lineend)^0
+local fontdata=Carg(1)
+local semicolon=spacing*P(";")
+local plus=spacing*P("plus")*number
+local minus=spacing*P("minus")*number
+local function addkernpair(data,one,two,value)
+ local chr=data.characters[one]
+ if chr then
+ local kerns=chr.kerns
+ if kerns then
+ kerns[two]=tonumber(value)
+ else
+ chr.kerns={ [two]=tonumber(value) }
+ end
+ end
+end
+local p_kernpair=(fontdata*P("KPX")*name*name*number)/addkernpair
+local chr=false
+local ind=0
+local function start(data,version)
+ data.metadata.afmversion=version
+ ind=0
+ chr={}
+end
+local function stop()
+ ind=0
+ chr=false
+end
+local function setindex(i)
+ if i<0 then
+ ind=ind+1
+ else
+ ind=i
+ end
+ chr={
+ index=ind
+ }
+end
+local function setwidth(width)
+ chr.width=width
+end
+local function setname(data,name)
+ data.characters[name]=chr
+end
+local function setboundingbox(boundingbox)
+ chr.boundingbox=boundingbox
+end
+local function setligature(plus,becomes)
+ local ligatures=chr.ligatures
+ if ligatures then
+ ligatures[plus]=becomes
+ else
+ chr.ligatures={ [plus]=becomes }
+ end
+end
+local p_charmetric=((
+ P("C")*number/setindex+P("WX")*number/setwidth+P("N")*fontdata*name/setname+P("B")*Ct((number)^4)/setboundingbox+P("L")*(name)^2/setligature
+ )*semicolon )^1
+local p_charmetrics=P("StartCharMetrics")*number*(p_charmetric+(1-P("EndCharMetrics")))^0*P("EndCharMetrics")
+local p_kernpairs=P("StartKernPairs")*number*(p_kernpair+(1-P("EndKernPairs" )))^0*P("EndKernPairs" )
+local function set_1(data,key,a) data.metadata[lower(key)]=a end
+local function set_2(data,key,a,b) data.metadata[lower(key)]={ a,b } end
+local function set_3(data,key,a,b,c) data.metadata[lower(key)]={ a,b,c } end
+local p_parameters=P(false)+fontdata*((P("FontName")+P("FullName")+P("FamilyName"))/lower)*words/function(data,key,value)
+ data.metadata[key]=value
+ end+fontdata*((P("Weight")+P("Version"))/lower)*name/function(data,key,value)
+ data.metadata[key]=value
+ end+fontdata*P("IsFixedPitch")*name/function(data,pitch)
+ data.metadata.monospaced=toboolean(pitch,true)
+ end+fontdata*P("FontBBox")*Ct(number^4)/function(data,boundingbox)
+ data.metadata.boundingbox=boundingbox
+ end+fontdata*((P("CharWidth")+P("CapHeight")+P("XHeight")+P("Descender")+P("Ascender")+P("ItalicAngle"))/lower)*number/function(data,key,value)
+ data.metadata[key]=value
+ end+P("Comment")*spacing*(P(false)+(fontdata*C("DESIGNSIZE")*number*rest)/set_1
++(fontdata*C("TFM designsize")*number*rest)/set_1+(fontdata*C("DesignSize")*number*rest)/set_1+(fontdata*C("CODINGSCHEME")*words*rest)/set_1
++(fontdata*C("CHECKSUM")*number*words*rest)/set_1
++(fontdata*C("SPACE")*number*plus*minus*rest)/set_3
++(fontdata*C("QUAD")*number*rest)/set_1
++(fontdata*C("EXTRASPACE")*number*rest)/set_1
++(fontdata*C("NUM")*number*number*number*rest)/set_3
++(fontdata*C("DENOM")*number*number*rest)/set_2
++(fontdata*C("SUP")*number*number*number*rest)/set_3
++(fontdata*C("SUB")*number*number*rest)/set_2
++(fontdata*C("SUPDROP")*number*rest)/set_1
++(fontdata*C("SUBDROP")*number*rest)/set_1
++(fontdata*C("DELIM")*number*number*rest)/set_2
++(fontdata*C("AXISHEIGHT")*number*rest)/set_1
+ )
+local fullparser=(P("StartFontMetrics")*fontdata*name/start )*(p_charmetrics+p_kernpairs+p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop )
+local infoparser=(P("StartFontMetrics")*fontdata*name/start )*(p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop )
+local function read(filename,parser)
+ local afmblob=io.loaddata(filename)
+ if afmblob then
+ local data={
+ resources={
+ filename=resolvers.unresolve(filename),
+ version=afm.version,
+ creator="context mkiv",
+ },
+ properties={
+ hasitalics=false,
+ },
+ goodies={},
+ metadata={
+ filename=file.removesuffix(file.basename(filename))
+ },
+ characters={
+ },
+ descriptions={
+ },
+ }
+ if trace_loading then
+ report_afm("parsing afm file %a",filename)
+ end
+ lpegmatch(parser,afmblob,1,data)
+ return data
+ else
+ if trace_loading then
+ report_afm("no valid afm file %a",filename)
+ end
+ return nil
+ end
+end
+function readers.loadfont(afmname,pfbname)
+ local data=read(resolvers.findfile(afmname),fullparser)
+ if data then
+ if not pfbname or pfbname=="" then
+ pfbname=resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb"))
+ end
+ if pfbname and pfbname~="" then
+ data.resources.filename=resolvers.unresolve(pfbname)
+ get_indexes(data,pfbname)
+ return data
+ else
+ report_afm("no pfb file for %a",afmname)
+ end
+ end
+end
+function readers.loadshapes(filename)
+ local fullname=resolvers.findfile(filename) or ""
+ if fullname=="" then
+ return {
+ filename="not found: "..filename,
+ glyphs={}
+ }
+ else
+ return {
+ filename=fullname,
+ format="opentype",
+ glyphs=get_shapes(fullname) or {},
+ units=1000,
+ }
+ end
+end
+function readers.getinfo(filename)
+ local data=read(resolvers.findfile(filename),infoparser)
+ if data then
+ return data.metadata
+ end
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-onrâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-one†987c5c5ed3754ad2feab80985067d59e] ---
+
+if not modules then modules={} end modules ['font-one']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local fonts,logs,trackers,containers,resolvers=fonts,logs,trackers,containers,resolvers
+local next,type,tonumber,rawget=next,type,tonumber,rawget
+local match,gsub=string.match,string.gsub
+local abs=math.abs
+local P,S,R,Cmt,C,Ct,Cs,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg
+local lpegmatch,patterns=lpeg.match,lpeg.patterns
+local sortedhash=table.sortedhash
+local trace_features=false trackers.register("afm.features",function(v) trace_features=v end)
+local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
+local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local report_afm=logs.reporter("fonts","afm loading")
+local setmetatableindex=table.setmetatableindex
+local derivetable=table.derive
+local findbinfile=resolvers.findbinfile
+local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+local definers=fonts.definers
+local readers=fonts.readers
+local constructors=fonts.constructors
+local afm=constructors.handlers.afm
+local pfb=constructors.handlers.pfb
+local otf=fonts.handlers.otf
+local otfreaders=otf.readers
+local otfenhancers=otf.enhancers
+local afmfeatures=constructors.features.afm
+local registerafmfeature=afmfeatures.register
+local afmenhancers=constructors.enhancers.afm
+local registerafmenhancer=afmenhancers.register
+afm.version=1.513
+afm.cache=containers.define("fonts","one",afm.version,true)
+afm.autoprefixed=true
+afm.helpdata={}
+afm.syncspace=true
+local overloads=fonts.mappings.overloads
+local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes
+function afm.load(filename)
+ filename=resolvers.findfile(filename,'afm') or ""
+ if filename~="" and not fonts.names.ignoredfile(filename) then
+ local name=file.removesuffix(file.basename(filename))
+ local data=containers.read(afm.cache,name)
+ local attr=lfs.attributes(filename)
+ local size=attr and attr.size or 0
+ local time=attr and attr.modification or 0
+ local pfbfile=file.replacesuffix(name,"pfb")
+ local pfbname=resolvers.findfile(pfbfile,"pfb") or ""
+ if pfbname=="" then
+ pfbname=resolvers.findfile(file.basename(pfbfile),"pfb") or ""
+ end
+ local pfbsize=0
+ local pfbtime=0
+ if pfbname~="" then
+ local attr=lfs.attributes(pfbname)
+ pfbsize=attr.size or 0
+ pfbtime=attr.modification or 0
+ end
+ if not data or data.size~=size or data.time~=time or data.pfbsize~=pfbsize or data.pfbtime~=pfbtime then
+ report_afm("reading %a",filename)
+ data=afm.readers.loadfont(filename,pfbname)
+ if data then
+ afmenhancers.apply(data,filename)
+ fonts.mappings.addtounicode(data,filename)
+ otfreaders.stripredundant(data)
+ otfreaders.pack(data)
+ data.size=size
+ data.time=time
+ data.pfbsize=pfbsize
+ data.pfbtime=pfbtime
+ report_afm("saving %a in cache",name)
+ data=containers.write(afm.cache,name,data)
+ data=containers.read(afm.cache,name)
+ end
+ end
+ if data then
+ otfreaders.unpack(data)
+ otfreaders.expand(data)
+ otfreaders.addunicodetable(data)
+ otfenhancers.apply(data,filename,data)
+ if applyruntimefixes then
+ applyruntimefixes(filename,data)
+ end
+ end
+ return data
+ end
+end
+local uparser=fonts.mappings.makenameparser()
+local function enhance_unify_names(data,filename)
+ local unicodevector=fonts.encodings.agl.unicodes
+ local unicodes={}
+ local names={}
+ local private=data.private or privateoffset
+ local descriptions=data.descriptions
+ for name,blob in sortedhash(data.characters) do
+ local code=unicodevector[name]
+ if not code then
+ code=lpegmatch(uparser,name)
+ if type(code)~="number" then
+ code=private
+ private=private+1
+ report_afm("assigning private slot %U for unknown glyph name %a",code,name)
+ end
+ end
+ local index=blob.index
+ unicodes[name]=code
+ names[name]=index
+ blob.name=name
+ descriptions[code]={
+ boundingbox=blob.boundingbox,
+ width=blob.width,
+ kerns=blob.kerns,
+ index=index,
+ name=name,
+ }
+ end
+ for unicode,description in next,descriptions do
+ local kerns=description.kerns
+ if kerns then
+ local krn={}
+ for name,kern in next,kerns do
+ local unicode=unicodes[name]
+ if unicode then
+ krn[unicode]=kern
+ else
+ end
+ end
+ description.kerns=krn
+ end
+ end
+ data.characters=nil
+ data.private=private
+ local resources=data.resources
+ local filename=resources.filename or file.removesuffix(file.basename(filename))
+ resources.filename=resolvers.unresolve(filename)
+ resources.unicodes=unicodes
+ resources.marks={}
+end
+local everywhere={ ["*"]={ ["*"]=true } }
+local noflags={ false,false,false,false }
+local function enhance_normalize_features(data)
+ local ligatures=setmetatableindex("table")
+ local kerns=setmetatableindex("table")
+ local extrakerns=setmetatableindex("table")
+ for u,c in next,data.descriptions do
+ local l=c.ligatures
+ local k=c.kerns
+ local e=c.extrakerns
+ if l then
+ ligatures[u]=l
+ for u,v in next,l do
+ l[u]={ ligature=v }
+ end
+ c.ligatures=nil
+ end
+ if k then
+ kerns[u]=k
+ for u,v in next,k do
+ k[u]=v
+ end
+ c.kerns=nil
+ end
+ if e then
+ extrakerns[u]=e
+ for u,v in next,e do
+ e[u]=v
+ end
+ c.extrakerns=nil
+ end
+ end
+ local features={
+ gpos={},
+ gsub={},
+ }
+ local sequences={
+ }
+ if next(ligatures) then
+ features.gsub.liga=everywhere
+ data.properties.hasligatures=true
+ sequences[#sequences+1]={
+ features={
+ liga=everywhere,
+ },
+ flags=noflags,
+ name="s_s_0",
+ nofsteps=1,
+ order={ "liga" },
+ type="gsub_ligature",
+ steps={
+ {
+ coverage=ligatures,
+ },
+ },
+ }
+ end
+ if next(kerns) then
+ features.gpos.kern=everywhere
+ data.properties.haskerns=true
+ sequences[#sequences+1]={
+ features={
+ kern=everywhere,
+ },
+ flags=noflags,
+ name="p_s_0",
+ nofsteps=1,
+ order={ "kern" },
+ type="gpos_pair",
+ steps={
+ {
+ format="kern",
+ coverage=kerns,
+ },
+ },
+ }
+ end
+ if next(extrakerns) then
+ features.gpos.extrakerns=everywhere
+ data.properties.haskerns=true
+ sequences[#sequences+1]={
+ features={
+ extrakerns=everywhere,
+ },
+ flags=noflags,
+ name="p_s_1",
+ nofsteps=1,
+ order={ "extrakerns" },
+ type="gpos_pair",
+ steps={
+ {
+ format="kern",
+ coverage=extrakerns,
+ },
+ },
+ }
+ end
+ data.resources.features=features
+ data.resources.sequences=sequences
+end
+local function enhance_fix_names(data)
+ for k,v in next,data.descriptions do
+ local n=v.name
+ local r=overloads[n]
+ if r then
+ local name=r.name
+ if trace_indexing then
+ report_afm("renaming characters %a to %a",n,name)
+ end
+ v.name=name
+ v.unicode=r.unicode
+ end
+ end
+end
+local addthem=function(rawdata,ligatures)
+ if ligatures then
+ local descriptions=rawdata.descriptions
+ local resources=rawdata.resources
+ local unicodes=resources.unicodes
+ for ligname,ligdata in next,ligatures do
+ local one=descriptions[unicodes[ligname]]
+ if one then
+ for _,pair in next,ligdata do
+ local two=unicodes[pair[1]]
+ local three=unicodes[pair[2]]
+ if two and three then
+ local ol=one.ligatures
+ if ol then
+ if not ol[two] then
+ ol[two]=three
+ end
+ else
+ one.ligatures={ [two]=three }
+ end
+ end
+ end
+ end
+ end
+ end
+end
+local function enhance_add_ligatures(rawdata)
+ addthem(rawdata,afm.helpdata.ligatures)
+end
+local function enhance_add_extra_kerns(rawdata)
+ local descriptions=rawdata.descriptions
+ local resources=rawdata.resources
+ local unicodes=resources.unicodes
+ local function do_it_left(what)
+ if what then
+ for unicode,description in next,descriptions do
+ local kerns=description.kerns
+ if kerns then
+ local extrakerns
+ for complex,simple in next,what do
+ complex=unicodes[complex]
+ simple=unicodes[simple]
+ if complex and simple then
+ local ks=kerns[simple]
+ if ks and not kerns[complex] then
+ if extrakerns then
+ extrakerns[complex]=ks
+ else
+ extrakerns={ [complex]=ks }
+ end
+ end
+ end
+ end
+ if extrakerns then
+ description.extrakerns=extrakerns
+ end
+ end
+ end
+ end
+ end
+ local function do_it_copy(what)
+ if what then
+ for complex,simple in next,what do
+ complex=unicodes[complex]
+ simple=unicodes[simple]
+ if complex and simple then
+ local complexdescription=descriptions[complex]
+ if complexdescription then
+ local simpledescription=descriptions[complex]
+ if simpledescription then
+ local extrakerns
+ local kerns=simpledescription.kerns
+ if kerns then
+ for unicode,kern in next,kerns do
+ if extrakerns then
+ extrakerns[unicode]=kern
+ else
+ extrakerns={ [unicode]=kern }
+ end
+ end
+ end
+ local extrakerns=simpledescription.extrakerns
+ if extrakerns then
+ for unicode,kern in next,extrakerns do
+ if extrakerns then
+ extrakerns[unicode]=kern
+ else
+ extrakerns={ [unicode]=kern }
+ end
+ end
+ end
+ if extrakerns then
+ complexdescription.extrakerns=extrakerns
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ do_it_left(afm.helpdata.leftkerned)
+ do_it_left(afm.helpdata.bothkerned)
+ do_it_copy(afm.helpdata.bothkerned)
+ do_it_copy(afm.helpdata.rightkerned)
+end
+local function adddimensions(data)
+ if data then
+ for unicode,description in next,data.descriptions do
+ local bb=description.boundingbox
+ if bb then
+ local ht=bb[4]
+ local dp=-bb[2]
+ if ht==0 or ht<0 then
+ else
+ description.height=ht
+ end
+ if dp==0 or dp<0 then
+ else
+ description.depth=dp
+ end
+ end
+ end
+ end
+end
+local function copytotfm(data)
+ if data and data.descriptions then
+ local metadata=data.metadata
+ local resources=data.resources
+ local properties=derivetable(data.properties)
+ local descriptions=derivetable(data.descriptions)
+ local goodies=derivetable(data.goodies)
+ local characters={}
+ local parameters={}
+ local unicodes=resources.unicodes
+ for unicode,description in next,data.descriptions do
+ characters[unicode]={}
+ end
+ local filename=constructors.checkedfilename(resources)
+ local fontname=metadata.fontname or metadata.fullname
+ local fullname=metadata.fullname or metadata.fontname
+ local endash=0x2013
+ local emdash=0x2014
+ local space=0x0020
+ local spacer="space"
+ local spaceunits=500
+ local monospaced=metadata.monospaced
+ local charwidth=metadata.charwidth
+ local italicangle=metadata.italicangle
+ local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight
+ properties.monospaced=monospaced
+ parameters.italicangle=italicangle
+ parameters.charwidth=charwidth
+ parameters.charxheight=charxheight
+ local d_endash=descriptions[endash]
+ local d_emdash=descriptions[emdash]
+ local d_space=descriptions[space]
+ if not d_space or d_space==0 then
+ d_space=d_endash
+ end
+ if d_space then
+ spaceunits,spacer=d_space.width or 0,"space"
+ end
+ if properties.monospaced then
+ if spaceunits==0 and d_emdash then
+ spaceunits,spacer=d_emdash.width or 0,"emdash"
+ end
+ else
+ if spaceunits==0 and d_endash then
+ spaceunits,spacer=d_emdash.width or 0,"endash"
+ end
+ end
+ if spaceunits==0 and charwidth then
+ spaceunits,spacer=charwidth or 0,"charwidth"
+ end
+ if spaceunits==0 then
+ spaceunits=tonumber(spaceunits) or 500
+ end
+ if spaceunits==0 then
+ spaceunits=500
+ end
+ parameters.slant=0
+ parameters.space=spaceunits
+ parameters.space_stretch=500
+ parameters.space_shrink=333
+ parameters.x_height=400
+ parameters.quad=1000
+ if italicangle and italicangle~=0 then
+ parameters.italicangle=italicangle
+ parameters.italicfactor=math.cos(math.rad(90+italicangle))
+ parameters.slant=- math.tan(italicangle*math.pi/180)
+ end
+ if monospaced then
+ parameters.space_stretch=0
+ parameters.space_shrink=0
+ elseif afm.syncspace then
+ parameters.space_stretch=spaceunits/2
+ parameters.space_shrink=spaceunits/3
+ end
+ parameters.extra_space=parameters.space_shrink
+ if charxheight then
+ parameters.x_height=charxheight
+ else
+ local x=0x0078
+ if x then
+ local x=descriptions[x]
+ if x then
+ parameters.x_height=x.height
+ end
+ end
+ end
+ if metadata.sup then
+ local dummy={ 0,0,0 }
+ parameters[ 1]=metadata.designsize or 0
+ parameters[ 2]=metadata.checksum or 0
+ parameters[ 3],
+ parameters[ 4],
+ parameters[ 5]=unpack(metadata.space or dummy)
+ parameters[ 6]=metadata.quad or 0
+ parameters[ 7]=metadata.extraspace or 0
+ parameters[ 8],
+ parameters[ 9],
+ parameters[10]=unpack(metadata.num or dummy)
+ parameters[11],
+ parameters[12]=unpack(metadata.denom or dummy)
+ parameters[13],
+ parameters[14],
+ parameters[15]=unpack(metadata.sup or dummy)
+ parameters[16],
+ parameters[17]=unpack(metadata.sub or dummy)
+ parameters[18]=metadata.supdrop or 0
+ parameters[19]=metadata.subdrop or 0
+ parameters[20],
+ parameters[21]=unpack(metadata.delim or dummy)
+ parameters[22]=metadata.axisheight or 0
+ end
+ parameters.designsize=(metadata.designsize or 10)*65536
+ parameters.ascender=abs(metadata.ascender or 0)
+ parameters.descender=abs(metadata.descender or 0)
+ parameters.units=1000
+ properties.spacer=spacer
+ properties.encodingbytes=2
+ properties.format=fonts.formats[filename] or "type1"
+ properties.filename=filename
+ properties.fontname=fontname
+ properties.fullname=fullname
+ properties.psname=fullname
+ properties.name=filename or fullname or fontname
+ properties.private=properties.private or data.private or privateoffset
+ if next(characters) then
+ return {
+ characters=characters,
+ descriptions=descriptions,
+ parameters=parameters,
+ resources=resources,
+ properties=properties,
+ goodies=goodies,
+ }
+ end
+ end
+ return nil
+end
+function afm.setfeatures(tfmdata,features)
+ local okay=constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm)
+ if okay then
+ return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm)
+ else
+ return {}
+ end
+end
+local function addtables(data)
+ local resources=data.resources
+ local lookuptags=resources.lookuptags
+ local unicodes=resources.unicodes
+ if not lookuptags then
+ lookuptags={}
+ resources.lookuptags=lookuptags
+ end
+ setmetatableindex(lookuptags,function(t,k)
+ local v=type(k)=="number" and ("lookup "..k) or k
+ t[k]=v
+ return v
+ end)
+ if not unicodes then
+ unicodes={}
+ resources.unicodes=unicodes
+ setmetatableindex(unicodes,function(t,k)
+ setmetatableindex(unicodes,nil)
+ for u,d in next,data.descriptions do
+ local n=d.name
+ if n then
+ t[n]=u
+ end
+ end
+ return rawget(t,k)
+ end)
+ end
+ constructors.addcoreunicodes(unicodes)
+end
+local function afmtotfm(specification)
+ local afmname=specification.filename or specification.name
+ if specification.forced=="afm" or specification.format=="afm" then
+ if trace_loading then
+ report_afm("forcing afm format for %a",afmname)
+ end
+ else
+ local tfmname=findbinfile(afmname,"ofm") or ""
+ if tfmname~="" then
+ if trace_loading then
+ report_afm("fallback from afm to tfm for %a",afmname)
+ end
+ return
+ end
+ end
+ if afmname~="" then
+ local features=constructors.checkedfeatures("afm",specification.features.normal)
+ specification.features.normal=features
+ constructors.hashinstance(specification,true)
+ specification=definers.resolve(specification)
+ local cache_id=specification.hash
+ local tfmdata=containers.read(constructors.cache,cache_id)
+ if not tfmdata then
+ local rawdata=afm.load(afmname)
+ if rawdata and next(rawdata) then
+ addtables(rawdata)
+ adddimensions(rawdata)
+ tfmdata=copytotfm(rawdata)
+ if tfmdata and next(tfmdata) then
+ local shared=tfmdata.shared
+ if not shared then
+ shared={}
+ tfmdata.shared=shared
+ end
+ shared.rawdata=rawdata
+ shared.dynamics={}
+ tfmdata.changed={}
+ shared.features=features
+ shared.processes=afm.setfeatures(tfmdata,features)
+ end
+ elseif trace_loading then
+ report_afm("no (valid) afm file found with name %a",afmname)
+ end
+ tfmdata=containers.write(constructors.cache,cache_id,tfmdata)
+ end
+ return tfmdata
+ end
+end
+local function read_from_afm(specification)
+ local tfmdata=afmtotfm(specification)
+ if tfmdata then
+ tfmdata.properties.name=specification.name
+ tfmdata=constructors.scale(tfmdata,specification)
+ local allfeatures=tfmdata.shared.features or specification.features.normal
+ constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm)
+ fonts.loggers.register(tfmdata,'afm',specification)
+ end
+ return tfmdata
+end
+registerafmfeature {
+ name="mode",
+ description="mode",
+ initializers={
+ base=otf.modeinitializer,
+ node=otf.modeinitializer,
+ }
+}
+registerafmfeature {
+ name="features",
+ description="features",
+ default=true,
+ initializers={
+ node=otf.nodemodeinitializer,
+ base=otf.basemodeinitializer,
+ },
+ processors={
+ node=otf.featuresprocessor,
+ }
+}
+fonts.formats.afm="type1"
+fonts.formats.pfb="type1"
+local function check_afm(specification,fullname)
+ local foundname=findbinfile(fullname,'afm') or ""
+ if foundname=="" then
+ foundname=fonts.names.getfilename(fullname,"afm") or ""
+ end
+ if fullname and foundname=="" and afm.autoprefixed then
+ local encoding,shortname=match(fullname,"^(.-)%-(.*)$")
+ if encoding and shortname and fonts.encodings.known[encoding] then
+ shortname=findbinfile(shortname,'afm') or ""
+ if shortname~="" then
+ foundname=shortname
+ if trace_defining then
+ report_afm("stripping encoding prefix from filename %a",afmname)
+ end
+ end
+ end
+ end
+ if foundname~="" then
+ specification.filename=foundname
+ specification.format="afm"
+ return read_from_afm(specification)
+ end
+end
+function readers.afm(specification,method)
+ local fullname=specification.filename or ""
+ local tfmdata=nil
+ if fullname=="" then
+ local forced=specification.forced or ""
+ if forced~="" then
+ tfmdata=check_afm(specification,specification.name.."."..forced)
+ end
+ if not tfmdata then
+ local check_tfm=readers.check_tfm
+ method=(check_tfm and (method or definers.method or "afm or tfm")) or "afm"
+ if method=="tfm" then
+ tfmdata=check_tfm(specification,specification.name)
+ elseif method=="afm" then
+ tfmdata=check_afm(specification,specification.name)
+ elseif method=="tfm or afm" then
+ tfmdata=check_tfm(specification,specification.name) or check_afm(specification,specification.name)
+ else
+ tfmdata=check_afm(specification,specification.name) or check_tfm(specification,specification.name)
+ end
+ end
+ else
+ tfmdata=check_afm(specification,fullname)
+ end
+ return tfmdata
+end
+function readers.pfb(specification,method)
+ local original=specification.specification
+ if trace_defining then
+ report_afm("using afm reader for %a",original)
+ end
+ specification.forced="afm"
+ local function swap(name)
+ local value=specification[swap]
+ if value then
+ specification[swap]=gsub("%.pfb",".afm",1)
+ end
+ end
+ swap("filename")
+ swap("fullname")
+ swap("forcedname")
+ swap("specification")
+ return readers.afm(specification,method)
+end
+registerafmenhancer("unify names",enhance_unify_names)
+registerafmenhancer("add ligatures",enhance_add_ligatures)
+registerafmenhancer("add extra kerns",enhance_add_extra_kerns)
+registerafmenhancer("normalize features",enhance_normalize_features)
+registerafmenhancer("check extra features",otfenhancers.enhance)
+registerafmenhancer("fix names",enhance_fix_names)
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oneâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-afk†54d554530e75c57c56ee76234724e26d] ---
+
+if not modules then modules={} end modules ['font-afk']={
+ version=1.001,
+ comment="companion to font-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
+ dataonly=true,
+}
+local allocate=utilities.storage.allocate
+fonts.handlers.afm.helpdata={
+ ligatures=allocate {
+ ['f']={
+ { 'f','ff' },
+ { 'i','fi' },
+ { 'l','fl' },
+ },
+ ['ff']={
+ { 'i','ffi' }
+ },
+ ['fi']={
+ { 'i','fii' }
+ },
+ ['fl']={
+ { 'i','fli' }
+ },
+ ['s']={
+ { 't','st' }
+ },
+ ['i']={
+ { 'j','ij' }
+ },
+ },
+ texligatures=allocate {
+ ['quoteleft']={
+ { 'quoteleft','quotedblleft' }
+ },
+ ['quoteright']={
+ { 'quoteright','quotedblright' }
+ },
+ ['hyphen']={
+ { 'hyphen','endash' }
+ },
+ ['endash']={
+ { 'hyphen','emdash' }
+ }
+ },
+ leftkerned=allocate {
+ AEligature="A",aeligature="a",
+ OEligature="O",oeligature="o",
+ IJligature="I",ijligature="i",
+ AE="A",ae="a",
+ OE="O",oe="o",
+ IJ="I",ij="i",
+ Ssharp="S",ssharp="s",
+ },
+ rightkerned=allocate {
+ AEligature="E",aeligature="e",
+ OEligature="E",oeligature="e",
+ IJligature="J",ijligature="j",
+ AE="E",ae="e",
+ OE="E",oe="e",
+ IJ="J",ij="j",
+ Ssharp="S",ssharp="s",
+ },
+ bothkerned=allocate {
+ Acircumflex="A",acircumflex="a",
+ Ccircumflex="C",ccircumflex="c",
+ Ecircumflex="E",ecircumflex="e",
+ Gcircumflex="G",gcircumflex="g",
+ Hcircumflex="H",hcircumflex="h",
+ Icircumflex="I",icircumflex="i",
+ Jcircumflex="J",jcircumflex="j",
+ Ocircumflex="O",ocircumflex="o",
+ Scircumflex="S",scircumflex="s",
+ Ucircumflex="U",ucircumflex="u",
+ Wcircumflex="W",wcircumflex="w",
+ Ycircumflex="Y",ycircumflex="y",
+ Agrave="A",agrave="a",
+ Egrave="E",egrave="e",
+ Igrave="I",igrave="i",
+ Ograve="O",ograve="o",
+ Ugrave="U",ugrave="u",
+ Ygrave="Y",ygrave="y",
+ Atilde="A",atilde="a",
+ Itilde="I",itilde="i",
+ Otilde="O",otilde="o",
+ Utilde="U",utilde="u",
+ Ntilde="N",ntilde="n",
+ Adiaeresis="A",adiaeresis="a",Adieresis="A",adieresis="a",
+ Ediaeresis="E",ediaeresis="e",Edieresis="E",edieresis="e",
+ Idiaeresis="I",idiaeresis="i",Idieresis="I",idieresis="i",
+ Odiaeresis="O",odiaeresis="o",Odieresis="O",odieresis="o",
+ Udiaeresis="U",udiaeresis="u",Udieresis="U",udieresis="u",
+ Ydiaeresis="Y",ydiaeresis="y",Ydieresis="Y",ydieresis="y",
+ Aacute="A",aacute="a",
+ Cacute="C",cacute="c",
+ Eacute="E",eacute="e",
+ Iacute="I",iacute="i",
+ Lacute="L",lacute="l",
+ Nacute="N",nacute="n",
+ Oacute="O",oacute="o",
+ Racute="R",racute="r",
+ Sacute="S",sacute="s",
+ Uacute="U",uacute="u",
+ Yacute="Y",yacute="y",
+ Zacute="Z",zacute="z",
+ Dstroke="D",dstroke="d",
+ Hstroke="H",hstroke="h",
+ Tstroke="T",tstroke="t",
+ Cdotaccent="C",cdotaccent="c",
+ Edotaccent="E",edotaccent="e",
+ Gdotaccent="G",gdotaccent="g",
+ Idotaccent="I",idotaccent="i",
+ Zdotaccent="Z",zdotaccent="z",
+ Amacron="A",amacron="a",
+ Emacron="E",emacron="e",
+ Imacron="I",imacron="i",
+ Omacron="O",omacron="o",
+ Umacron="U",umacron="u",
+ Ccedilla="C",ccedilla="c",
+ Kcedilla="K",kcedilla="k",
+ Lcedilla="L",lcedilla="l",
+ Ncedilla="N",ncedilla="n",
+ Rcedilla="R",rcedilla="r",
+ Scedilla="S",scedilla="s",
+ Tcedilla="T",tcedilla="t",
+ Ohungarumlaut="O",ohungarumlaut="o",
+ Uhungarumlaut="U",uhungarumlaut="u",
+ Aogonek="A",aogonek="a",
+ Eogonek="E",eogonek="e",
+ Iogonek="I",iogonek="i",
+ Uogonek="U",uogonek="u",
+ Aring="A",aring="a",
+ Uring="U",uring="u",
+ Abreve="A",abreve="a",
+ Ebreve="E",ebreve="e",
+ Gbreve="G",gbreve="g",
+ Ibreve="I",ibreve="i",
+ Obreve="O",obreve="o",
+ Ubreve="U",ubreve="u",
+ Ccaron="C",ccaron="c",
+ Dcaron="D",dcaron="d",
+ Ecaron="E",ecaron="e",
+ Lcaron="L",lcaron="l",
+ Ncaron="N",ncaron="n",
+ Rcaron="R",rcaron="r",
+ Scaron="S",scaron="s",
+ Tcaron="T",tcaron="t",
+ Zcaron="Z",zcaron="z",
+ dotlessI="I",dotlessi="i",
+ dotlessJ="J",dotlessj="j",
+ AEligature="AE",aeligature="ae",AE="AE",ae="ae",
+ OEligature="OE",oeligature="oe",OE="OE",oe="oe",
+ IJligature="IJ",ijligature="ij",IJ="IJ",ij="ij",
+ Lstroke="L",lstroke="l",Lslash="L",lslash="l",
+ Ostroke="O",ostroke="o",Oslash="O",oslash="o",
+ Ssharp="SS",ssharp="ss",
+ Aumlaut="A",aumlaut="a",
+ Eumlaut="E",eumlaut="e",
+ Iumlaut="I",iumlaut="i",
+ Oumlaut="O",oumlaut="o",
+ Uumlaut="U",uumlaut="u",
+ }
+}
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-afkâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-tfm†3bbba3214fd0b8c6f35ad85592fc2917] ---
+
+if not modules then modules={} end modules ['luatex-fonts-tfm']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type=next,type
+local match,format=string.match,string.format
+local concat,sortedhash=table.concat,table.sortedhash
+local idiv=number.idiv
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end)
+local report_defining=logs.reporter("fonts","defining")
+local report_tfm=logs.reporter("fonts","tfm loading")
+local findbinfile=resolvers.findbinfile
+local setmetatableindex=table.setmetatableindex
+local fonts=fonts
+local handlers=fonts.handlers
+local helpers=fonts.helpers
+local readers=fonts.readers
+local constructors=fonts.constructors
+local encodings=fonts.encodings
+local tfm=constructors.handlers.tfm
+tfm.version=1.000
+tfm.maxnestingdepth=5
+tfm.maxnestingsize=65536*1024
+local otf=fonts.handlers.otf
+local otfenhancers=otf.enhancers
+local tfmfeatures=constructors.features.tfm
+local registertfmfeature=tfmfeatures.register
+local tfmenhancers=constructors.enhancers.tfm
+local registertfmenhancer=tfmenhancers.register
+local charcommand=helpers.commands.char
+constructors.resolvevirtualtoo=false
+fonts.formats.tfm="type1"
+fonts.formats.ofm="type1"
+function tfm.setfeatures(tfmdata,features)
+ local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm)
+ if okay then
+ return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm)
+ else
+ return {}
+ end
+end
+local depth={}
+local loadtfm=font.read_tfm
+local loadvf=font.read_vf
+local function read_from_tfm(specification)
+ local filename=specification.filename
+ local size=specification.size
+ depth[filename]=(depth[filename] or 0)+1
+ if trace_defining then
+ report_defining("loading tfm file %a at size %s",filename,size)
+ end
+ local tfmdata=loadtfm(filename,size)
+ if tfmdata then
+ local features=specification.features and specification.features.normal or {}
+ local features=constructors.checkedfeatures("tfm",features)
+ specification.features.normal=features
+ local newtfmdata=(depth[filename]==1) and tfm.reencode(tfmdata,specification)
+ if newtfmdata then
+ tfmdata=newtfmdata
+ end
+ local resources=tfmdata.resources or {}
+ local properties=tfmdata.properties or {}
+ local parameters=tfmdata.parameters or {}
+ local shared=tfmdata.shared or {}
+ shared.features=features
+ shared.resources=resources
+ properties.name=tfmdata.name
+ properties.fontname=tfmdata.fontname
+ properties.psname=tfmdata.psname
+ properties.fullname=tfmdata.fullname
+ properties.filename=specification.filename
+ properties.format=tfmdata.format or fonts.formats.tfm
+ properties.usedbitmap=tfmdata.usedbitmap
+ tfmdata.properties=properties
+ tfmdata.resources=resources
+ tfmdata.parameters=parameters
+ tfmdata.shared=shared
+ shared.rawdata={ resources=resources }
+ shared.features=features
+ if newtfmdata then
+ if not resources.marks then
+ resources.marks={}
+ end
+ if not resources.sequences then
+ resources.sequences={}
+ end
+ if not resources.features then
+ resources.features={
+ gsub={},
+ gpos={},
+ }
+ end
+ if not tfmdata.changed then
+ tfmdata.changed={}
+ end
+ if not tfmdata.descriptions then
+ tfmdata.descriptions=tfmdata.characters
+ end
+ otf.readers.addunicodetable(tfmdata)
+ tfmenhancers.apply(tfmdata,filename)
+ constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm)
+ otf.readers.unifymissing(tfmdata)
+ fonts.mappings.addtounicode(tfmdata,filename)
+ tfmdata.tounicode=1
+ local tounicode=fonts.mappings.tounicode
+ for unicode,v in next,tfmdata.characters do
+ local u=v.unicode
+ if u then
+ v.tounicode=tounicode(u)
+ end
+ end
+ if tfmdata.usedbitmap then
+ tfm.addtounicode(tfmdata)
+ end
+ end
+ shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil
+ if size<0 then
+ size=idiv(65536*-size,100)
+ end
+ parameters.factor=1
+ parameters.units=1000
+ parameters.size=size
+ parameters.slant=parameters.slant or parameters[1] or 0
+ parameters.space=parameters.space or parameters[2] or 0
+ parameters.space_stretch=parameters.space_stretch or parameters[3] or 0
+ parameters.space_shrink=parameters.space_shrink or parameters[4] or 0
+ parameters.x_height=parameters.x_height or parameters[5] or 0
+ parameters.quad=parameters.quad or parameters[6] or 0
+ parameters.extra_space=parameters.extra_space or parameters[7] or 0
+ constructors.enhanceparameters(parameters)
+ properties.private=properties.private or tfmdata.private or privateoffset
+ if newtfmdata then
+ elseif constructors.resolvevirtualtoo then
+ fonts.loggers.register(tfmdata,file.suffix(filename),specification)
+ local vfname=findbinfile(specification.name,'ovf')
+ if vfname and vfname~="" then
+ local vfdata=loadvf(vfname,size)
+ if vfdata then
+ local chars=tfmdata.characters
+ for k,v in next,vfdata.characters do
+ chars[k].commands=v.commands
+ end
+ properties.virtualized=true
+ tfmdata.fonts=vfdata.fonts
+ tfmdata.type="virtual"
+ local fontlist=vfdata.fonts
+ local name=file.nameonly(filename)
+ for i=1,#fontlist do
+ local n=fontlist[i].name
+ local s=fontlist[i].size
+ local d=depth[filename]
+ s=constructors.scaled(s,vfdata.designsize)
+ if d>tfm.maxnestingdepth then
+ report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth)
+ fontlist[i]={ id=0 }
+ elseif (d>1) and (s>tfm.maxnestingsize) then
+ report_defining("virtual font %a exceeds size %s",n,s)
+ fontlist[i]={ id=0 }
+ else
+ local t,id=constructors.readanddefine(n,s)
+ fontlist[i]={ id=id }
+ end
+ end
+ end
+ end
+ end
+ properties.haskerns=true
+ properties.hasligatures=true
+ properties.hasitalics=true
+ resources.unicodes={}
+ resources.lookuptags={}
+ depth[filename]=depth[filename]-1
+ return tfmdata
+ else
+ depth[filename]=depth[filename]-1
+ end
+end
+local function check_tfm(specification,fullname)
+ local foundname=findbinfile(fullname,'tfm') or ""
+ if foundname=="" then
+ foundname=findbinfile(fullname,'ofm') or ""
+ end
+ if foundname=="" then
+ foundname=fonts.names.getfilename(fullname,"tfm") or ""
+ end
+ if foundname~="" then
+ specification.filename=foundname
+ specification.format="ofm"
+ return read_from_tfm(specification)
+ elseif trace_defining then
+ report_defining("loading tfm with name %a fails",specification.name)
+ end
+end
+readers.check_tfm=check_tfm
+function readers.tfm(specification)
+ local fullname=specification.filename or ""
+ if fullname=="" then
+ local forced=specification.forced or ""
+ if forced~="" then
+ fullname=specification.name.."."..forced
+ else
+ fullname=specification.name
+ end
+ end
+ return check_tfm(specification,fullname)
+end
+readers.ofm=readers.tfm
+do
+ local outfiles={}
+ local tfmcache=table.setmetatableindex(function(t,tfmdata)
+ local id=font.define(tfmdata)
+ t[tfmdata]=id
+ return id
+ end)
+ local encdone=table.setmetatableindex("table")
+ function tfm.reencode(tfmdata,specification)
+ local features=specification.features
+ if not features then
+ return
+ end
+ local features=features.normal
+ if not features then
+ return
+ end
+ local tfmfile=file.basename(tfmdata.name)
+ local encfile=features.reencode
+ local pfbfile=features.pfbfile
+ local bitmap=features.bitmap
+ if not encfile then
+ return
+ end
+ local pfbfile=outfiles[tfmfile]
+ if pfbfile==nil then
+ if bitmap then
+ pfbfile=false
+ elseif type(pfbfile)~="string" then
+ pfbfile=tfmfile
+ end
+ if type(pfbfile)=="string" then
+ pfbfile=file.addsuffix(pfbfile,"pfb")
+ report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile)
+ else
+ report_tfm("using bitmap shapes for %a",tfmfile)
+ pfbfile=false
+ end
+ outfiles[tfmfile]=pfbfile
+ end
+ local encoding=false
+ local vector=false
+ if type(pfbfile)=="string" then
+ local pfb=constructors.handlers.pfb
+ if pfb and pfb.loadvector then
+ local v,e=pfb.loadvector(pfbfile)
+ if v then
+ vector=v
+ end
+ if e then
+ encoding=e
+ end
+ end
+ end
+ if type(encfile)=="string" and encfile~="auto" then
+ encoding=fonts.encodings.load(file.addsuffix(encfile,"enc"))
+ if encoding then
+ encoding=encoding.vector
+ end
+ end
+ if not encoding then
+ report_tfm("bad encoding for %a, quitting",tfmfile)
+ return
+ end
+ local unicoding=fonts.encodings.agl and fonts.encodings.agl.unicodes
+ local virtualid=tfmcache[tfmdata]
+ local tfmdata=table.copy(tfmdata)
+ local characters={}
+ local originals=tfmdata.characters
+ local indices={}
+ local parentfont={ "font",1 }
+ local private=tfmdata.privateoffset or constructors.privateoffset
+ local reported=encdone[tfmfile][encfile]
+ local backmap=vector and table.swapped(vector)
+ local done={}
+ for index,name in sortedhash(encoding) do
+ local unicode=unicoding[name]
+ local original=originals[index]
+ if original then
+ if unicode then
+ original.unicode=unicode
+ else
+ unicode=private
+ private=private+1
+ if not reported then
+ report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode)
+ end
+ end
+ characters[unicode]=original
+ indices[index]=unicode
+ original.name=name
+ if backmap then
+ original.index=backmap[name]
+ else
+ original.commands={ parentfont,charcommand[index] }
+ original.oindex=index
+ end
+ done[name]=true
+ elseif not done[name] then
+ report_tfm("bad index %a in font %a with name %a",index,tfmfile,name)
+ end
+ end
+ encdone[tfmfile][encfile]=true
+ for k,v in next,characters do
+ local kerns=v.kerns
+ if kerns then
+ local t={}
+ for k,v in next,kerns do
+ local i=indices[k]
+ if i then
+ t[i]=v
+ end
+ end
+ v.kerns=next(t) and t or nil
+ end
+ local ligatures=v.ligatures
+ if ligatures then
+ local t={}
+ for k,v in next,ligatures do
+ local i=indices[k]
+ if i then
+ t[i]=v
+ v.char=indices[v.char]
+ end
+ end
+ v.ligatures=next(t) and t or nil
+ end
+ end
+ tfmdata.fonts={ { id=virtualid } }
+ tfmdata.characters=characters
+ tfmdata.fullname=tfmdata.fullname or tfmdata.name
+ tfmdata.psname=file.nameonly(pfbfile or tfmdata.name)
+ tfmdata.filename=pfbfile
+ tfmdata.encodingbytes=2
+ tfmdata.format="type1"
+ tfmdata.tounicode=1
+ tfmdata.embedding="subset"
+ tfmdata.usedbitmap=bitmap and virtualid
+ tfmdata.private=private
+ return tfmdata
+ end
+end
+do
+ local template=[[
+/CIDInit /ProcSet findresource begin
+ 12 dict begin
+ begincmap
+ /CIDSystemInfo << /Registry (TeX) /Ordering (bitmap-%s) /Supplement 0 >> def
+ /CMapName /TeX-bitmap-%s def
+ /CMapType 2 def
+ 1 begincodespacerange
+ <00> <FF>
+ endcodespacerange
+ %s beginbfchar
+%s
+ endbfchar
+ endcmap
+CMapName currentdict /CMap defineresource pop end
+end
+end
+]]
+ local flushstreamobject=lpdf and lpdf.flushstreamobject
+ local setfontattributes=lpdf and lpdf.setfontattributes
+ if not flushstreamobject then
+ flushstreamobject=function(data)
+ return pdf.obj { immediate=true,type="stream",string=data }
+ end
+ end
+ if not setfontattributes then
+ setfontattributes=function(id,data)
+ return pdf.setfontattributes(id,data)
+ end
+ end
+ function tfm.addtounicode(tfmdata)
+ local id=tfmdata.usedbitmap
+ local map={}
+ local char={}
+ for k,v in next,tfmdata.characters do
+ local index=v.oindex
+ local tounicode=v.tounicode
+ if index and tounicode then
+ map[index]=tounicode
+ end
+ end
+ for k,v in sortedhash(map) do
+ char[#char+1]=format("<%02X> <%s>",k,v)
+ end
+ char=concat(char,"\n")
+ local stream=format(template,id,id,#char,char)
+ local reference=flushstreamobject(stream,nil,true)
+ setfontattributes(id,format("/ToUnicode %i 0 R",reference))
+ end
+end
+do
+ local everywhere={ ["*"]={ ["*"]=true } }
+ local noflags={ false,false,false,false }
+ local function enhance_normalize_features(data)
+ local ligatures=setmetatableindex("table")
+ local kerns=setmetatableindex("table")
+ local characters=data.characters
+ for u,c in next,characters do
+ local l=c.ligatures
+ local k=c.kerns
+ if l then
+ ligatures[u]=l
+ for u,v in next,l do
+ l[u]={ ligature=v.char }
+ end
+ c.ligatures=nil
+ end
+ if k then
+ kerns[u]=k
+ for u,v in next,k do
+ k[u]=v
+ end
+ c.kerns=nil
+ end
+ end
+ for u,l in next,ligatures do
+ for k,v in next,l do
+ local vl=v.ligature
+ local dl=ligatures[vl]
+ if dl then
+ for kk,vv in next,dl do
+ v[kk]=vv
+ end
+ end
+ end
+ end
+ local features={
+ gpos={},
+ gsub={},
+ }
+ local sequences={
+ }
+ if next(ligatures) then
+ features.gsub.liga=everywhere
+ data.properties.hasligatures=true
+ sequences[#sequences+1]={
+ features={
+ liga=everywhere,
+ },
+ flags=noflags,
+ name="s_s_0",
+ nofsteps=1,
+ order={ "liga" },
+ type="gsub_ligature",
+ steps={
+ {
+ coverage=ligatures,
+ },
+ },
+ }
+ end
+ if next(kerns) then
+ features.gpos.kern=everywhere
+ data.properties.haskerns=true
+ sequences[#sequences+1]={
+ features={
+ kern=everywhere,
+ },
+ flags=noflags,
+ name="p_s_0",
+ nofsteps=1,
+ order={ "kern" },
+ type="gpos_pair",
+ steps={
+ {
+ format="kern",
+ coverage=kerns,
+ },
+ },
+ }
+ end
+ data.resources.features=features
+ data.resources.sequences=sequences
+ data.shared.resources=data.shared.resources or resources
+ end
+ registertfmenhancer("normalize features",enhance_normalize_features)
+ registertfmenhancer("check extra features",otfenhancers.enhance)
+end
+registertfmfeature {
+ name="mode",
+ description="mode",
+ initializers={
+ base=otf.modeinitializer,
+ node=otf.modeinitializer,
+ }
+}
+registertfmfeature {
+ name="features",
+ description="features",
+ default=true,
+ initializers={
+ base=otf.basemodeinitializer,
+ node=otf.nodemodeinitializer,
+ },
+ processors={
+ node=otf.featuresprocessor,
+ }
+}
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-tfmâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-lua†55b281fb98f7bd848fc19928f376f647] ---
+
+if not modules then modules={} end modules ['font-lua']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local report_lua=logs.reporter("fonts","lua loading")
+local fonts=fonts
+local readers=fonts.readers
+fonts.formats.lua="lua"
+local function check_lua(specification,fullname)
+ local fullname=resolvers.findfile(fullname) or ""
+ if fullname~="" then
+ local loader=loadfile(fullname)
+ loader=loader and loader()
+ return loader and loader(specification)
+ end
+end
+readers.check_lua=check_lua
+function readers.lua(specification)
+ local original=specification.specification
+ if trace_defining then
+ report_lua("using lua reader for %a",original)
+ end
+ local fullname=specification.filename or ""
+ if fullname=="" then
+ local forced=specification.forced or ""
+ if forced~="" then
+ fullname=specification.name.."."..forced
+ else
+ fullname=specification.name
+ end
+ end
+ return check_lua(specification,fullname)
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-luaâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-def†f66c365dae4499f982d8bf16e5d37de3] ---
+
+if not modules then modules={} end modules ['font-def']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local lower,gsub=string.lower,string.gsub
+local tostring,next=tostring,next
+local lpegmatch=lpeg.match
+local suffixonly,removesuffix,basename=file.suffix,file.removesuffix,file.basename
+local formatters=string.formatters
+local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
+local allocate=utilities.storage.allocate
+local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end)
+local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end)
+trackers.register("fonts.loading","fonts.defining","otf.loading","afm.loading","tfm.loading")
+local report_defining=logs.reporter("fonts","defining")
+local fonts=fonts
+local fontdata=fonts.hashes.identifiers
+local readers=fonts.readers
+local definers=fonts.definers
+local specifiers=fonts.specifiers
+local constructors=fonts.constructors
+local fontgoodies=fonts.goodies
+readers.sequence=allocate { 'otf','ttf','afm','tfm','lua' }
+local variants=allocate()
+specifiers.variants=variants
+definers.methods=definers.methods or {}
+local internalized=allocate()
+local lastdefined=nil
+local loadedfonts=constructors.loadedfonts
+local designsizes=constructors.designsizes
+local resolvefile=fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end
+local function makespecification(specification,lookup,name,sub,method,detail,size)
+ size=size or 655360
+ if not lookup or lookup=="" then
+ lookup=definers.defaultlookup
+ end
+ if trace_defining then
+ report_defining("specification %a, lookup %a, name %a, sub %a, method %a, detail %a",
+ specification,lookup,name,sub,method,detail)
+ end
+ local t={
+ lookup=lookup,
+ specification=specification,
+ size=size,
+ name=name,
+ sub=sub,
+ method=method,
+ detail=detail,
+ resolved="",
+ forced="",
+ features={},
+ }
+ return t
+end
+definers.makespecification=makespecification
+if context then
+ local splitter,splitspecifiers=nil,""
+ local P,C,S,Cc,Cs=lpeg.P,lpeg.C,lpeg.S,lpeg.Cc,lpeg.Cs
+ local left=P("(")
+ local right=P(")")
+ local colon=P(":")
+ local space=P(" ")
+ local lbrace=P("{")
+ local rbrace=P("}")
+ definers.defaultlookup="file"
+ local prefixpattern=P(false)
+ local function addspecifier(symbol)
+ splitspecifiers=splitspecifiers..symbol
+ local method=S(splitspecifiers)
+ local lookup=C(prefixpattern)*colon
+ local sub=left*C(P(1-left-right-method)^1)*right
+ local specification=C(method)*C(P(1)^1)
+ local name=Cs((lbrace/"")*(1-rbrace)^1*(rbrace/"")+(1-sub-specification)^1)
+ splitter=P((lookup+Cc(""))*name*(sub+Cc(""))*(specification+Cc("")))
+ end
+ local function addlookup(str)
+ prefixpattern=prefixpattern+P(str)
+ end
+ definers.addlookup=addlookup
+ addlookup("file")
+ addlookup("name")
+ addlookup("spec")
+ local function getspecification(str)
+ return lpegmatch(splitter,str or "")
+ end
+ definers.getspecification=getspecification
+ function definers.registersplit(symbol,action,verbosename)
+ addspecifier(symbol)
+ variants[symbol]=action
+ if verbosename then
+ variants[verbosename]=action
+ end
+ end
+ function definers.analyze(specification,size)
+ local lookup,name,sub,method,detail=getspecification(specification or "")
+ return makespecification(specification,lookup,name,sub,method,detail,size)
+ end
+end
+definers.resolvers=definers.resolvers or {}
+local resolvers=definers.resolvers
+function resolvers.file(specification)
+ local name=resolvefile(specification.name)
+ local suffix=lower(suffixonly(name))
+ if fonts.formats[suffix] then
+ specification.forced=suffix
+ specification.forcedname=name
+ specification.name=removesuffix(name)
+ else
+ specification.name=name
+ end
+end
+function resolvers.name(specification)
+ local resolve=fonts.names.resolve
+ if resolve then
+ local resolved,sub,subindex,instance=resolve(specification.name,specification.sub,specification)
+ if resolved then
+ specification.resolved=resolved
+ specification.sub=sub
+ specification.subindex=subindex
+ if instance then
+ specification.instance=instance
+ local features=specification.features
+ if not features then
+ features={}
+ specification.features=features
+ end
+ local normal=features.normal
+ if not normal then
+ normal={}
+ features.normal=normal
+ end
+ normal.instance=instance
+ end
+ local suffix=lower(suffixonly(resolved))
+ if fonts.formats[suffix] then
+ specification.forced=suffix
+ specification.forcedname=resolved
+ specification.name=removesuffix(resolved)
+ else
+ specification.name=resolved
+ end
+ end
+ else
+ resolvers.file(specification)
+ end
+end
+function resolvers.spec(specification)
+ local resolvespec=fonts.names.resolvespec
+ if resolvespec then
+ local resolved,sub,subindex=resolvespec(specification.name,specification.sub,specification)
+ if resolved then
+ specification.resolved=resolved
+ specification.sub=sub
+ specification.subindex=subindex
+ specification.forced=lower(suffixonly(resolved))
+ specification.forcedname=resolved
+ specification.name=removesuffix(resolved)
+ end
+ else
+ resolvers.name(specification)
+ end
+end
+function definers.resolve(specification)
+ if not specification.resolved or specification.resolved=="" then
+ local r=resolvers[specification.lookup]
+ if r then
+ r(specification)
+ end
+ end
+ if specification.forced=="" then
+ specification.forced=nil
+ specification.forcedname=nil
+ end
+ specification.hash=lower(specification.name..' @ '..constructors.hashfeatures(specification))
+ if specification.sub and specification.sub~="" then
+ specification.hash=specification.sub..' @ '..specification.hash
+ end
+ return specification
+end
+function definers.applypostprocessors(tfmdata)
+ local postprocessors=tfmdata.postprocessors
+ if postprocessors then
+ local properties=tfmdata.properties
+ for i=1,#postprocessors do
+ local extrahash=postprocessors[i](tfmdata)
+ if type(extrahash)=="string" and extrahash~="" then
+ extrahash=gsub(lower(extrahash),"[^a-z]","-")
+ properties.fullname=formatters["%s-%s"](properties.fullname,extrahash)
+ end
+ end
+ end
+ return tfmdata
+end
+local function checkembedding(tfmdata)
+ local properties=tfmdata.properties
+ local embedding
+ if directive_embedall then
+ embedding="full"
+ elseif properties and properties.filename and constructors.dontembed[properties.filename] then
+ embedding="no"
+ else
+ embedding="subset"
+ end
+ if properties then
+ properties.embedding=embedding
+ else
+ tfmdata.properties={ embedding=embedding }
+ end
+ tfmdata.embedding=embedding
+end
+local function checkfeatures(tfmdata)
+ local resources=tfmdata.resources
+ local shared=tfmdata.shared
+ if resources and shared then
+ local features=resources.features
+ local usedfeatures=shared.features
+ if features and usedfeatures then
+ local usedlanguage=usedfeatures.language or "dflt"
+ local usedscript=usedfeatures.script or "dflt"
+ local function check(what)
+ if what then
+ local foundlanguages={}
+ for feature,scripts in next,what do
+ if usedscript=="auto" or scripts["*"] then
+ elseif not scripts[usedscript] then
+ else
+ for script,languages in next,scripts do
+ if languages["*"] then
+ elseif context and not languages[usedlanguage] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,usedlanguage)
+ end
+ end
+ end
+ for script,languages in next,scripts do
+ for language in next,languages do
+ foundlanguages[language]=true
+ end
+ end
+ end
+ if false then
+ foundlanguages["*"]=nil
+ foundlanguages=sortedkeys(foundlanguages)
+ for feature,scripts in sortedhash(what) do
+ for script,languages in next,scripts do
+ if not languages["*"] then
+ for i=1,#foundlanguages do
+ local language=foundlanguages[i]
+ if context and not languages[language] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,language)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ check(features.gsub)
+ check(features.gpos)
+ end
+ end
+end
+function definers.loadfont(specification)
+ local hash=constructors.hashinstance(specification)
+ local tfmdata=loadedfonts[hash]
+ if not tfmdata then
+ local forced=specification.forced or ""
+ if forced~="" then
+ local reader=readers[lower(forced)]
+ tfmdata=reader and reader(specification)
+ if not tfmdata then
+ report_defining("forced type %a of %a not found",forced,specification.name)
+ end
+ else
+ local sequence=readers.sequence
+ for s=1,#sequence do
+ local reader=sequence[s]
+ if readers[reader] then
+ if trace_defining then
+ report_defining("trying (reader sequence driven) type %a for %a with file %a",reader,specification.name,specification.filename)
+ end
+ tfmdata=readers[reader](specification)
+ if tfmdata then
+ break
+ else
+ specification.filename=nil
+ end
+ end
+ end
+ end
+ if tfmdata then
+ tfmdata=definers.applypostprocessors(tfmdata)
+ checkembedding(tfmdata)
+ loadedfonts[hash]=tfmdata
+ designsizes[specification.hash]=tfmdata.parameters.designsize
+ checkfeatures(tfmdata)
+ end
+ end
+ if not tfmdata then
+ report_defining("font with asked name %a is not found using lookup %a",specification.name,specification.lookup)
+ end
+ return tfmdata
+end
+function constructors.readanddefine(name,size)
+ local specification=definers.analyze(name,size)
+ local method=specification.method
+ if method and variants[method] then
+ specification=variants[method](specification)
+ end
+ specification=definers.resolve(specification)
+ local hash=constructors.hashinstance(specification)
+ local id=definers.registered(hash)
+ if not id then
+ local tfmdata=definers.loadfont(specification)
+ if tfmdata then
+ tfmdata.properties.hash=hash
+ id=font.define(tfmdata)
+ definers.register(tfmdata,id)
+ else
+ id=0
+ end
+ end
+ return fontdata[id],id
+end
+function definers.current()
+ return lastdefined
+end
+function definers.registered(hash)
+ local id=internalized[hash]
+ return id,id and fontdata[id]
+end
+function definers.register(tfmdata,id)
+ if tfmdata and id then
+ local hash=tfmdata.properties.hash
+ if not hash then
+ report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?")
+ elseif not internalized[hash] then
+ internalized[hash]=id
+ if trace_defining then
+ report_defining("registering font, id %s, hash %a",id,hash)
+ end
+ fontdata[id]=tfmdata
+ end
+ end
+end
+function definers.read(specification,size,id)
+ statistics.starttiming(fonts)
+ if type(specification)=="string" then
+ specification=definers.analyze(specification,size)
+ end
+ local method=specification.method
+ if method and variants[method] then
+ specification=variants[method](specification)
+ end
+ specification=definers.resolve(specification)
+ local hash=constructors.hashinstance(specification)
+ local tfmdata=definers.registered(hash)
+ if tfmdata then
+ if trace_defining then
+ report_defining("already hashed: %s",hash)
+ end
+ else
+ tfmdata=definers.loadfont(specification)
+ if tfmdata then
+ if trace_defining then
+ report_defining("loaded and hashed: %s",hash)
+ end
+ tfmdata.properties.hash=hash
+ if id then
+ definers.register(tfmdata,id)
+ end
+ else
+ if trace_defining then
+ report_defining("not loaded and hashed: %s",hash)
+ end
+ end
+ end
+ lastdefined=tfmdata or id
+ if not tfmdata then
+ report_defining("unknown font %a, loading aborted",specification.name)
+ elseif trace_defining and type(tfmdata)=="table" then
+ local properties=tfmdata.properties or {}
+ local parameters=tfmdata.parameters or {}
+ report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a",
+ properties.format or "unknown",id or "-",properties.name,parameters.size,properties.encodingbytes,
+ properties.encodingname,properties.fullname,basename(properties.filename))
+ end
+ statistics.stoptiming(fonts)
+ return tfmdata
+end
+function font.getfont(id)
+ return fontdata[id]
+end
+callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)")
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-defâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-def†5ad79120ebc5e60f4d322fb3ee13bffe] ---
+
+if not modules then modules={} end modules ['luatex-fonts-def']={
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+ os.exit()
+end
+local fonts=fonts
+fonts.constructors.namemode="specification"
+function fonts.definers.getspecification(str)
+ return "",str,"",":",str
+end
+local list={}
+local function issome () list.lookup='name' end
+local function isfile () list.lookup='file' end
+local function isname () list.lookup='name' end
+local function thename(s) list.name=s end
+local function issub (v) list.sub=v end
+local function iscrap (s) list.crap=string.lower(s) end
+local function iskey (k,v) list[k]=v end
+local function istrue (s) list[s]=true end
+local function isfalse(s) list[s]=false end
+local P,S,R,C,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs
+local spaces=P(" ")^0
+local namespec=Cs((P("{")/"")*(1-S("}"))^0*(P("}")/"")+(1-S("/:("))^0)
+local crapspec=spaces*P("/")*(((1-P(":"))^0)/iscrap)*spaces
+local filename_1=P("file:")/isfile*(namespec/thename)
+local filename_2=P("[")*P(true)/isfile*(((1-P("]"))^0)/thename)*P("]")
+local fontname_1=P("name:")/isname*(namespec/thename)
+local fontname_2=P(true)/issome*(namespec/thename)
+local sometext=R("az","AZ","09")^1
+local somekey=R("az","AZ","09")^1
+local somevalue=(P("{")/"")*(1-P("}"))^0*(P("}")/"")+(1-S(";"))^1
+local truevalue=P("+")*spaces*(sometext/istrue)
+local falsevalue=P("-")*spaces*(sometext/isfalse)
+local keyvalue=(C(somekey)*spaces*P("=")*spaces*C(somevalue))/iskey
+local somevalue=sometext/istrue
+local subvalue=P("(")*(C(P(1-S("()"))^1)/issub)*P(")")
+local option=spaces*(keyvalue+falsevalue+truevalue+somevalue)*spaces
+local options=P(":")*spaces*(P(";")^0*option)^0
+local pattern=(filename_1+filename_2+fontname_1+fontname_2)*subvalue^0*crapspec^0*options^0
+function fonts.definers.analyze(str,size)
+ local specification=fonts.definers.makespecification(str,nil,nil,nil,":",nil,size)
+ list={}
+ lpeg.match(pattern,str)
+ list.crap=nil
+ if list.name then
+ specification.name=list.name
+ list.name=nil
+ end
+ if list.lookup then
+ specification.lookup=list.lookup
+ list.lookup=nil
+ end
+ if list.sub then
+ specification.sub=list.sub
+ list.sub=nil
+ end
+ specification.features.normal=fonts.handlers.otf.features.normalize(list)
+ list=nil
+ return specification
+end
+function fonts.definers.applypostprocessors(tfmdata)
+ local postprocessors=tfmdata.postprocessors
+ if postprocessors then
+ for i=1,#postprocessors do
+ local extrahash=postprocessors[i](tfmdata)
+ if type(extrahash)=="string" and extrahash~="" then
+ extrahash=string.gsub(lower(extrahash),"[^a-z]","-")
+ tfmdata.properties.fullname=format("%s-%s",tfmdata.properties.fullname,extrahash)
+ end
+ end
+ end
+ return tfmdata
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-defâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-ext†01015ab3758cdc2af29394e6d502a91a] ---
+
+if not modules then modules={} end modules ['luatex-fonts-ext']={
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+ os.exit()
+end
+local byte=string.byte
+local fonts=fonts
+local handlers=fonts.handlers
+local otf=handlers.otf
+local afm=handlers.afm
+local registerotffeature=otf.features.register
+local registerafmfeature=afm.features.register
+function fonts.loggers.onetimemessage() end
+fonts.protrusions=fonts.protrusions or {}
+fonts.protrusions.setups=fonts.protrusions.setups or {}
+local setups=fonts.protrusions.setups
+setups['default']={
+ factor=1,
+ left=1,
+ right=1,
+ [0x002C]={ 0,1 },
+ [0x002E]={ 0,1 },
+ [0x003A]={ 0,1 },
+ [0x003B]={ 0,1 },
+ [0x002D]={ 0,1 },
+ [0x2013]={ 0,0.50 },
+ [0x2014]={ 0,0.33 },
+ [0x3001]={ 0,1 },
+ [0x3002]={ 0,1 },
+ [0x060C]={ 0,1 },
+ [0x061B]={ 0,1 },
+ [0x06D4]={ 0,1 },
+}
+local function initializeprotrusion(tfmdata,value)
+ if value then
+ local setup=setups[value]
+ if setup then
+ local factor,left,right=setup.factor or 1,setup.left or 1,setup.right or 1
+ local emwidth=tfmdata.parameters.quad
+ tfmdata.parameters.protrusion={
+ auto=true,
+ }
+ for i,chr in next,tfmdata.characters do
+ local v,pl,pr=setup[i],nil,nil
+ if v then
+ pl,pr=v[1],v[2]
+ end
+ if pl and pl~=0 then chr.left_protruding=left*pl*factor end
+ if pr and pr~=0 then chr.right_protruding=right*pr*factor end
+ end
+ end
+ end
+end
+local specification={
+ name="protrusion",
+ description="shift characters into the left and or right margin",
+ initializers={
+ base=initializeprotrusion,
+ node=initializeprotrusion,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+fonts.expansions=fonts.expansions or {}
+fonts.expansions.setups=fonts.expansions.setups or {}
+local setups=fonts.expansions.setups
+setups['default']={
+ stretch=2,
+ shrink=2,
+ step=.5,
+ factor=1,
+ [byte('A')]=0.5,[byte('B')]=0.7,[byte('C')]=0.7,[byte('D')]=0.5,[byte('E')]=0.7,
+ [byte('F')]=0.7,[byte('G')]=0.5,[byte('H')]=0.7,[byte('K')]=0.7,[byte('M')]=0.7,
+ [byte('N')]=0.7,[byte('O')]=0.5,[byte('P')]=0.7,[byte('Q')]=0.5,[byte('R')]=0.7,
+ [byte('S')]=0.7,[byte('U')]=0.7,[byte('W')]=0.7,[byte('Z')]=0.7,
+ [byte('a')]=0.7,[byte('b')]=0.7,[byte('c')]=0.7,[byte('d')]=0.7,[byte('e')]=0.7,
+ [byte('g')]=0.7,[byte('h')]=0.7,[byte('k')]=0.7,[byte('m')]=0.7,[byte('n')]=0.7,
+ [byte('o')]=0.7,[byte('p')]=0.7,[byte('q')]=0.7,[byte('s')]=0.7,[byte('u')]=0.7,
+ [byte('w')]=0.7,[byte('z')]=0.7,
+ [byte('2')]=0.7,[byte('3')]=0.7,[byte('6')]=0.7,[byte('8')]=0.7,[byte('9')]=0.7,
+}
+local function initializeexpansion(tfmdata,value)
+ if value then
+ local setup=setups[value]
+ if setup then
+ local factor=setup.factor or 1
+ tfmdata.parameters.expansion={
+ stretch=10*(setup.stretch or 0),
+ shrink=10*(setup.shrink or 0),
+ step=10*(setup.step or 0),
+ auto=true,
+ }
+ for i,chr in next,tfmdata.characters do
+ local v=setup[i]
+ if v and v~=0 then
+ chr.expansion_factor=v*factor
+ else
+ chr.expansion_factor=factor
+ end
+ end
+ end
+ end
+end
+local specification={
+ name="expansion",
+ description="apply hz optimization",
+ initializers={
+ base=initializeexpansion,
+ node=initializeexpansion,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+if not otf.features.normalize then
+ otf.features.normalize=function(t)
+ if t.rand then
+ t.rand="random"
+ end
+ return t
+ end
+end
+function fonts.helpers.nametoslot(name)
+ local t=type(name)
+ if t=="string" then
+ local tfmdata=fonts.hashes.identifiers[currentfont()]
+ local shared=tfmdata and tfmdata.shared
+ local fntdata=shared and shared.rawdata
+ return fntdata and fntdata.resources.unicodes[name]
+ elseif t=="number" then
+ return n
+ end
+end
+fonts.encodings=fonts.encodings or {}
+local reencodings={}
+fonts.encodings.reencodings=reencodings
+local function specialreencode(tfmdata,value)
+ local encoding=value and reencodings[value]
+ if encoding then
+ local temp={}
+ local char=tfmdata.characters
+ for k,v in next,encoding do
+ temp[k]=char[v]
+ end
+ for k,v in next,temp do
+ char[k]=temp[k]
+ end
+ return string.format("reencoded:%s",value)
+ end
+end
+local function initialize(tfmdata,value)
+ tfmdata.postprocessors=tfmdata.postprocessors or {}
+ table.insert(tfmdata.postprocessors,
+ function(tfmdata)
+ return specialreencode(tfmdata,value)
+ end
+ )
+end
+registerotffeature {
+ name="reencode",
+ description="reencode characters",
+ manipulators={
+ base=initialize,
+ node=initialize,
+ }
+}
+local function initialize(tfmdata,key,value)
+ if value then
+ tfmdata.mathparameters=nil
+ end
+end
+registerotffeature {
+ name="ignoremathconstants",
+ description="ignore math constants table",
+ initializers={
+ base=initialize,
+ node=initialize,
+ }
+}
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-extâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-tex†77c374b0ef00c2fb12188ec42beb4257] ---
+
+if not modules then modules={} end modules ['font-imp-tex']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next=next
+local fonts=fonts
+local otf=fonts.handlers.otf
+local registerotffeature=otf.features.register
+local addotffeature=otf.addfeature
+local specification={
+ type="ligature",
+ order={ "tlig" },
+ prepend=true,
+ data={
+ [0x2013]={ 0x002D,0x002D },
+ [0x2014]={ 0x002D,0x002D,0x002D },
+ },
+}
+addotffeature("tlig",specification)
+registerotffeature {
+ name="tlig",
+ description="tex ligatures",
+}
+local specification={
+ type="substitution",
+ order={ "trep" },
+ prepend=true,
+ data={
+ [0x0027]=0x2019,
+ },
+}
+addotffeature("trep",specification)
+registerotffeature {
+ name="trep",
+ description="tex replacements",
+}
+local anum_arabic={
+ [0x0030]=0x0660,
+ [0x0031]=0x0661,
+ [0x0032]=0x0662,
+ [0x0033]=0x0663,
+ [0x0034]=0x0664,
+ [0x0035]=0x0665,
+ [0x0036]=0x0666,
+ [0x0037]=0x0667,
+ [0x0038]=0x0668,
+ [0x0039]=0x0669,
+}
+local anum_persian={
+ [0x0030]=0x06F0,
+ [0x0031]=0x06F1,
+ [0x0032]=0x06F2,
+ [0x0033]=0x06F3,
+ [0x0034]=0x06F4,
+ [0x0035]=0x06F5,
+ [0x0036]=0x06F6,
+ [0x0037]=0x06F7,
+ [0x0038]=0x06F8,
+ [0x0039]=0x06F9,
+}
+local function valid(data)
+ local features=data.resources.features
+ if features then
+ for k,v in next,features do
+ for k,v in next,v do
+ if v.arab then
+ return true
+ end
+ end
+ end
+ end
+end
+local specification={
+ {
+ type="substitution",
+ features={ arab={ urd=true,dflt=true } },
+ order={ "anum" },
+ data=anum_arabic,
+ valid=valid,
+ },
+ {
+ type="substitution",
+ features={ arab={ urd=true } },
+ order={ "anum" },
+ data=anum_persian,
+ valid=valid,
+ },
+}
+addotffeature("anum",specification)
+registerotffeature {
+ name="anum",
+ description="arabic digits",
+}
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-texâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-ligatures†043daa4fcccf2560868da359d71d3a4a] ---
+
+if not modules then modules={} end modules ['font-imp-ligatures']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local lpegmatch=lpeg.match
+local utfsplit=utf.split
+local settings_to_array=utilities.parsers.settings_to_array
+local fonts=fonts
+local otf=fonts.handlers.otf
+local registerotffeature=otf.features.register
+local addotffeature=otf.addfeature
+local lookups={}
+local protect={}
+local revert={}
+local zwjchar=0x200C
+local zwj={ zwjchar }
+addotffeature {
+ name="blockligatures",
+ type="chainsubstitution",
+ nocheck=true,
+ prepend=true,
+ future=true,
+ lookups={
+ {
+ type="multiple",
+ data=lookups,
+ },
+ },
+ data={
+ rules=protect,
+ }
+}
+addotffeature {
+ name="blockligatures",
+ type="chainsubstitution",
+ nocheck=true,
+ append=true,
+ overload=false,
+ lookups={
+ {
+ type="ligature",
+ data=lookups,
+ },
+ },
+ data={
+ rules=revert,
+ }
+}
+registerotffeature {
+ name='blockligatures',
+ description='block certain ligatures',
+}
+local splitter=lpeg.splitat(":")
+local function blockligatures(str)
+ local t=settings_to_array(str)
+ for i=1,#t do
+ local ti=t[i]
+ local before,current,after=lpegmatch(splitter,ti)
+ if current and after then
+ if before then
+ before=utfsplit(before)
+ for i=1,#before do
+ before[i]={ before[i] }
+ end
+ end
+ if current then
+ current=utfsplit(current)
+ end
+ if after then
+ after=utfsplit(after)
+ for i=1,#after do
+ after[i]={ after[i] }
+ end
+ end
+ else
+ before=nil
+ current=utfsplit(ti)
+ after=nil
+ end
+ if #current>1 then
+ local one=current[1]
+ local two=current[2]
+ lookups[one]={ one,zwjchar }
+ local one={ one }
+ local two={ two }
+ local new=#protect+1
+ protect[new]={
+ before=before,
+ current={ one,two },
+ after=after,
+ lookups={ 1 },
+ }
+ revert[new]={
+ current={ one,zwj },
+ after={ two },
+ lookups={ 1 },
+ }
+ end
+ end
+end
+otf.helpers.blockligatures=blockligatures
+if context then
+ interfaces.implement {
+ name="blockligatures",
+ arguments="string",
+ actions=blockligatures,
+ }
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-ligaturesâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-italics†fe1ca80fb5ea4a2f8d2d5c484e7ba913] ---
+
+if not modules then modules={} end modules ['font-imp-italics']={
+ version=1.001,
+ comment="companion to font-ini.mkiv and hand-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next=next
+local fonts=fonts
+local handlers=fonts.handlers
+local registerotffeature=handlers.otf.features.register
+local registerafmfeature=handlers.afm.features.register
+local function initialize(tfmdata,key,value)
+ for unicode,character in next,tfmdata.characters do
+ local olditalic=character.italic
+ if olditalic and olditalic~=0 then
+ character.width=character.width+olditalic
+ character.italic=0
+ end
+ end
+end
+local specification={
+ name="italicwidths",
+ description="add italic to width",
+ manipulators={
+ base=initialize,
+ node=initialize,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+local function initialize(tfmdata,value)
+ if value then
+ local parameters=tfmdata.parameters
+ local italicangle=parameters.italicangle
+ if italicangle and italicangle~=0 then
+ local properties=tfmdata.properties
+ local factor=tonumber(value) or 1
+ properties.hasitalics=true
+ properties.autoitalicamount=factor*(parameters.uwidth or 40)/2
+ end
+ end
+end
+local specification={
+ name="itlc",
+ description="italic correction",
+ initializers={
+ base=initialize,
+ node=initialize,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+if context then
+ local function initialize(tfmdata,value)
+ tfmdata.properties.textitalics=toboolean(value)
+ end
+ local specification={
+ name="textitalics",
+ description="use alternative text italic correction",
+ initializers={
+ base=initialize,
+ node=initialize,
+ }
+ }
+ registerotffeature(specification)
+ registerafmfeature(specification)
+end
+if context then
+ local letter=characters.is_letter
+ local always=true
+ local function collapseitalics(tfmdata,key,value)
+ local threshold=value==true and 100 or tonumber(value)
+ if threshold and threshold>0 then
+ if threshold>100 then
+ threshold=100
+ end
+ for unicode,data in next,tfmdata.characters do
+ if always or letter[unicode] or letter[data.unicode] then
+ local italic=data.italic
+ if italic and italic~=0 then
+ local width=data.width
+ if width and width~=0 then
+ local delta=threshold*italic/100
+ data.width=width+delta
+ data.italic=italic-delta
+ end
+ end
+ end
+ end
+ end
+ end
+ local dimensions_specification={
+ name="collapseitalics",
+ description="collapse italics",
+ manipulators={
+ base=collapseitalics,
+ node=collapseitalics,
+ }
+ }
+ registerotffeature(dimensions_specification)
+ registerafmfeature(dimensions_specification)
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-italicsâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-effects†73a660359a0ec71e44cc2b7225a715ac] ---
+
+if not modules then modules={} end modules ['font-imp-effects']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type,tonumber=next,type,tonumber
+local is_boolean=string.is_boolean
+local fonts=fonts
+local handlers=fonts.handlers
+local registerotffeature=handlers.otf.features.register
+local registerafmfeature=handlers.afm.features.register
+local settings_to_hash=utilities.parsers.settings_to_hash_colon_too
+local helpers=fonts.helpers
+local prependcommands=helpers.prependcommands
+local charcommand=helpers.commands.char
+local leftcommand=helpers.commands.left
+local rightcommand=helpers.commands.right
+local upcommand=helpers.commands.up
+local downcommand=helpers.commands.down
+local dummycommand=helpers.commands.dummy
+local report_effect=logs.reporter("fonts","effect")
+local report_slant=logs.reporter("fonts","slant")
+local report_extend=logs.reporter("fonts","extend")
+local report_squeeze=logs.reporter("fonts","squeeze")
+local trace=false
+trackers.register("fonts.effect",function(v) trace=v end)
+trackers.register("fonts.slant",function(v) trace=v end)
+trackers.register("fonts.extend",function(v) trace=v end)
+trackers.register("fonts.squeeze",function(v) trace=v end)
+local function initializeslant(tfmdata,value)
+ value=tonumber(value)
+ if not value then
+ value=0
+ elseif value>1 then
+ value=1
+ elseif value<-1 then
+ value=-1
+ end
+ if trace then
+ report_slant("applying %0.3f",value)
+ end
+ tfmdata.parameters.slantfactor=value
+end
+local specification={
+ name="slant",
+ description="slant glyphs",
+ initializers={
+ base=initializeslant,
+ node=initializeslant,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+local function initializeextend(tfmdata,value)
+ value=tonumber(value)
+ if not value then
+ value=0
+ elseif value>10 then
+ value=10
+ elseif value<-10 then
+ value=-10
+ end
+ if trace then
+ report_extend("applying %0.3f",value)
+ end
+ tfmdata.parameters.extendfactor=value
+end
+local specification={
+ name="extend",
+ description="scale glyphs horizontally",
+ initializers={
+ base=initializeextend,
+ node=initializeextend,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+local function initializesqueeze(tfmdata,value)
+ value=tonumber(value)
+ if not value then
+ value=0
+ elseif value>10 then
+ value=10
+ elseif value<-10 then
+ value=-10
+ end
+ if trace then
+ report_squeeze("applying %0.3f",value)
+ end
+ tfmdata.parameters.squeezefactor=value
+end
+local specification={
+ name="squeeze",
+ description="scale glyphs vertically",
+ initializers={
+ base=initializesqueeze,
+ node=initializesqueeze,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+local effects={
+ inner=0,
+ normal=0,
+ outer=1,
+ outline=1,
+ both=2,
+ hidden=3,
+}
+local function initializeeffect(tfmdata,value)
+ local spec
+ if type(value)=="number" then
+ spec={ width=value }
+ else
+ spec=settings_to_hash(value)
+ end
+ local effect=spec.effect or "both"
+ local width=tonumber(spec.width) or 0
+ local mode=effects[effect]
+ if not mode then
+ report_effect("invalid effect %a",effect)
+ elseif width==0 and mode==0 then
+ report_effect("invalid width %a for effect %a",width,effect)
+ else
+ local parameters=tfmdata.parameters
+ local properties=tfmdata.properties
+ parameters.mode=mode
+ parameters.width=width*1000
+ if is_boolean(spec.auto)==true then
+ local squeeze=1-width/20
+ local average=(1-squeeze)*width*100
+ spec.squeeze=squeeze
+ spec.extend=1+width/2
+ spec.wdelta=average
+ spec.hdelta=average/2
+ spec.ddelta=average/2
+ spec.vshift=average/2
+ end
+ local factor=tonumber(spec.factor) or 0
+ local hfactor=tonumber(spec.hfactor) or factor
+ local vfactor=tonumber(spec.vfactor) or factor
+ local delta=tonumber(spec.delta) or 1
+ local wdelta=tonumber(spec.wdelta) or delta
+ local hdelta=tonumber(spec.hdelta) or delta
+ local ddelta=tonumber(spec.ddelta) or hdelta
+ local vshift=tonumber(spec.vshift) or 0
+ local slant=spec.slant
+ local extend=spec.extend
+ local squeeze=spec.squeeze
+ if slant then
+ initializeslant(tfmdata,slant)
+ end
+ if extend then
+ initializeextend(tfmdata,extend)
+ end
+ if squeeze then
+ initializesqueeze(tfmdata,squeeze)
+ end
+ properties.effect={
+ effect=effect,
+ width=width,
+ factor=factor,
+ hfactor=hfactor,
+ vfactor=vfactor,
+ wdelta=wdelta,
+ hdelta=hdelta,
+ ddelta=ddelta,
+ vshift=vshift,
+ slant=tfmdata.parameters.slantfactor,
+ extend=tfmdata.parameters.extendfactor,
+ squeeze=tfmdata.parameters.squeezefactor,
+ }
+ end
+end
+local rules={
+ "RadicalRuleThickness",
+ "OverbarRuleThickness",
+ "FractionRuleThickness",
+ "UnderbarRuleThickness",
+}
+local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
+ if delta~=0 then
+ for i=1,#rules do
+ local name=rules[i]
+ local value=mathparameters[name]
+ if value then
+ mathparameters[name]=(squeeze or 1)*(value+dx)
+ end
+ end
+ end
+end
+local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
+ local function wdpatch(char)
+ if wsnap~=0 then
+ char.width=char.width+wdelta/2
+ end
+ end
+ local function htpatch(char)
+ if hsnap~=0 then
+ local height=char.height
+ if height then
+ char.height=char.height+2*dy
+ end
+ end
+ end
+ local character=characters[0x221A]
+ if character and character.next then
+ local char=character
+ local next=character.next
+ wdpatch(char)
+ htpatch(char)
+ while next do
+ char=characters[next]
+ wdpatch(char)
+ htpatch(char)
+ next=char.next
+ end
+ if char then
+ local v=char.vert_variants
+ if v then
+ local top=v[#v]
+ if top then
+ local char=characters[top.glyph]
+ htpatch(char)
+ end
+ end
+ end
+ end
+end
+local function manipulateeffect(tfmdata)
+ local effect=tfmdata.properties.effect
+ if effect then
+ local characters=tfmdata.characters
+ local parameters=tfmdata.parameters
+ local mathparameters=tfmdata.mathparameters
+ local multiplier=effect.width*100
+ local factor=parameters.factor
+ local hfactor=parameters.hfactor
+ local vfactor=parameters.vfactor
+ local wdelta=effect.wdelta*hfactor*multiplier
+ local hdelta=effect.hdelta*vfactor*multiplier
+ local ddelta=effect.ddelta*vfactor*multiplier
+ local vshift=effect.vshift*vfactor*multiplier
+ local squeeze=effect.squeeze
+ local hshift=wdelta/2
+ local dx=multiplier*vfactor
+ local dy=vshift
+ local factor=(1+effect.factor)*factor
+ local hfactor=(1+effect.hfactor)*hfactor
+ local vfactor=(1+effect.vfactor)*vfactor
+ local vshift=vshift~=0 and upcommand[vshift] or false
+ for unicode,character in next,characters do
+ local oldwidth=character.width
+ local oldheight=character.height
+ local olddepth=character.depth
+ if oldwidth and oldwidth>0 then
+ character.width=oldwidth+wdelta
+ local commands=character.commands
+ local hshift=rightcommand[hshift]
+ if vshift then
+ if commands then
+ prependcommands (commands,
+ hshift,
+ vshift
+ )
+ else
+ character.commands={
+ hshift,
+ vshift,
+ charcommand[unicode]
+ }
+ end
+ else
+ if commands then
+ prependcommands (commands,
+ hshift
+ )
+ else
+ character.commands={
+ hshift,
+ charcommand[unicode]
+ }
+ end
+ end
+ end
+ if oldheight and oldheight>0 then
+ character.height=oldheight+hdelta
+ end
+ if olddepth and olddepth>0 then
+ character.depth=olddepth+ddelta
+ end
+ end
+ if mathparameters then
+ setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
+ setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
+ end
+ parameters.factor=factor
+ parameters.hfactor=hfactor
+ parameters.vfactor=vfactor
+ if trace then
+ report_effect("applying")
+ report_effect(" effect : %s",effect.effect)
+ report_effect(" width : %s => %s",effect.width,multiplier)
+ report_effect(" factor : %s => %s",effect.factor,factor )
+ report_effect(" hfactor : %s => %s",effect.hfactor,hfactor)
+ report_effect(" vfactor : %s => %s",effect.vfactor,vfactor)
+ report_effect(" wdelta : %s => %s",effect.wdelta,wdelta)
+ report_effect(" hdelta : %s => %s",effect.hdelta,hdelta)
+ report_effect(" ddelta : %s => %s",effect.ddelta,ddelta)
+ end
+ end
+end
+local specification={
+ name="effect",
+ description="apply effects to glyphs",
+ initializers={
+ base=initializeeffect,
+ node=initializeeffect,
+ },
+ manipulators={
+ base=manipulateeffect,
+ node=manipulateeffect,
+ },
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+local function initializeoutline(tfmdata,value)
+ value=tonumber(value)
+ if not value then
+ value=0
+ else
+ value=tonumber(value) or 0
+ end
+ local parameters=tfmdata.parameters
+ local properties=tfmdata.properties
+ parameters.mode=effects.outline
+ parameters.width=value*1000
+ properties.effect={
+ effect=effect,
+ width=width,
+ }
+end
+local specification={
+ name="outline",
+ description="outline glyphs",
+ initializers={
+ base=initializeoutline,
+ node=initializeoutline,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-effectsâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-lig†b9dbe77ce747d4c35bb2a20ffbe5aa51] ---
+
+
+fonts.handlers.otf.addfeature {
+ ["dataset"]={
+ {
+ ["data"]={
+ ["À"]={ "A","̀" },
+ ["Ã"]={ "A","Ì" },
+ ["Â"]={ "A","̂" },
+ ["Ã"]={ "A","̃" },
+ ["Ä"]={ "A","̈" },
+ ["Ã…"]={ "A","ÌŠ" },
+ ["Ç"]={ "C","̧" },
+ ["È"]={ "E","̀" },
+ ["É"]={ "E","Ì" },
+ ["Ê"]={ "E","̂" },
+ ["Ë"]={ "E","̈" },
+ ["Ì"]={ "I","̀" },
+ ["Ã"]={ "I","Ì" },
+ ["ÃŽ"]={ "I","Ì‚" },
+ ["Ã"]={ "I","̈" },
+ ["Ñ"]={ "N","̃" },
+ ["Ã’"]={ "O","Ì€" },
+ ["Ó"]={ "O","Ì" },
+ ["Ô"]={ "O","̂" },
+ ["Õ"]={ "O","̃" },
+ ["Ö"]={ "O","̈" },
+ ["Ù"]={ "U","̀" },
+ ["Ú"]={ "U","Ì" },
+ ["Û"]={ "U","̂" },
+ ["Ü"]={ "U","̈" },
+ ["Ã"]={ "Y","Ì" },
+ ["à"]={ "a","̀" },
+ ["á"]={ "a","Ì" },
+ ["â"]={ "a","̂" },
+ ["ã"]={ "a","̃" },
+ ["ä"]={ "a","̈" },
+ ["Ã¥"]={ "a","ÌŠ" },
+ ["ç"]={ "c","̧" },
+ ["è"]={ "e","̀" },
+ ["é"]={ "e","Ì" },
+ ["ê"]={ "e","̂" },
+ ["ë"]={ "e","̈" },
+ ["ì"]={ "i","̀" },
+ ["í"]={ "i","Ì" },
+ ["î"]={ "i","̂" },
+ ["ï"]={ "i","̈" },
+ ["ñ"]={ "n","̃" },
+ ["ò"]={ "o","̀" },
+ ["ó"]={ "o","Ì" },
+ ["ô"]={ "o","̂" },
+ ["õ"]={ "o","̃" },
+ ["ö"]={ "o","̈" },
+ ["ù"]={ "u","̀" },
+ ["ú"]={ "u","Ì" },
+ ["û"]={ "u","̂" },
+ ["ü"]={ "u","̈" },
+ ["ý"]={ "y","Ì" },
+ ["ÿ"]={ "y","̈" },
+ ["Ä€"]={ "A","Ì„" },
+ ["Ä"]={ "a","Ì„" },
+ ["Ă"]={ "A","̆" },
+ ["ă"]={ "a","̆" },
+ ["Ą"]={ "A","̨" },
+ ["ą"]={ "a","̨" },
+ ["Ć"]={ "C","Ì" },
+ ["ć"]={ "c","Ì" },
+ ["Ĉ"]={ "C","̂" },
+ ["ĉ"]={ "c","̂" },
+ ["Ċ"]={ "C","̇" },
+ ["ċ"]={ "c","̇" },
+ ["Č"]={ "C","̌" },
+ ["Ä"]={ "c","ÌŒ" },
+ ["Ď"]={ "D","̌" },
+ ["Ä"]={ "d","ÌŒ" },
+ ["Ä’"]={ "E","Ì„" },
+ ["Ä“"]={ "e","Ì„" },
+ ["Ĕ"]={ "E","̆" },
+ ["ĕ"]={ "e","̆" },
+ ["Ė"]={ "E","̇" },
+ ["ė"]={ "e","̇" },
+ ["Ę"]={ "E","̨" },
+ ["ę"]={ "e","̨" },
+ ["Ě"]={ "E","̌" },
+ ["ě"]={ "e","̌" },
+ ["Ĝ"]={ "G","̂" },
+ ["Ä"]={ "g","Ì‚" },
+ ["Ğ"]={ "G","̆" },
+ ["ğ"]={ "g","̆" },
+ ["Ġ"]={ "G","̇" },
+ ["ġ"]={ "g","̇" },
+ ["Ģ"]={ "G","̧" },
+ ["ģ"]={ "g","̧" },
+ ["Ĥ"]={ "H","̂" },
+ ["Ä¥"]={ "h","Ì‚" },
+ ["Ĩ"]={ "I","̃" },
+ ["ĩ"]={ "i","̃" },
+ ["Ī"]={ "I","̄" },
+ ["Ä«"]={ "i","Ì„" },
+ ["Ĭ"]={ "I","̆" },
+ ["ĭ"]={ "i","̆" },
+ ["Į"]={ "I","̨" },
+ ["į"]={ "i","̨" },
+ ["İ"]={ "I","̇" },
+ ["Ä´"]={ "J","Ì‚" },
+ ["ĵ"]={ "j","̂" },
+ ["Ķ"]={ "K","̧" },
+ ["ķ"]={ "k","̧" },
+ ["Ĺ"]={ "L","Ì" },
+ ["ĺ"]={ "l","Ì" },
+ ["Ļ"]={ "L","̧" },
+ ["ļ"]={ "l","̧" },
+ ["Ľ"]={ "L","̌" },
+ ["ľ"]={ "l","̌" },
+ ["Ń"]={ "N","Ì" },
+ ["Å„"]={ "n","Ì" },
+ ["Ņ"]={ "N","̧" },
+ ["ņ"]={ "n","̧" },
+ ["Ň"]={ "N","̌" },
+ ["ň"]={ "n","̌" },
+ ["Ō"]={ "O","̄" },
+ ["Å"]={ "o","Ì„" },
+ ["Ŏ"]={ "O","̆" },
+ ["Å"]={ "o","̆" },
+ ["Å"]={ "O","Ì‹" },
+ ["Å‘"]={ "o","Ì‹" },
+ ["Å”"]={ "R","Ì" },
+ ["Å•"]={ "r","Ì" },
+ ["Ŗ"]={ "R","̧" },
+ ["ŗ"]={ "r","̧" },
+ ["Ř"]={ "R","̌" },
+ ["ř"]={ "r","̌" },
+ ["Åš"]={ "S","Ì" },
+ ["Å›"]={ "s","Ì" },
+ ["Ŝ"]={ "S","̂" },
+ ["Å"]={ "s","Ì‚" },
+ ["Ş"]={ "S","̧" },
+ ["ş"]={ "s","̧" },
+ ["Š"]={ "S","̌" },
+ ["š"]={ "s","̌" },
+ ["Ţ"]={ "T","̧" },
+ ["ţ"]={ "t","̧" },
+ ["Ť"]={ "T","̌" },
+ ["ť"]={ "t","̌" },
+ ["Ũ"]={ "U","̃" },
+ ["ũ"]={ "u","̃" },
+ ["Ū"]={ "U","̄" },
+ ["Å«"]={ "u","Ì„" },
+ ["Ŭ"]={ "U","̆" },
+ ["ŭ"]={ "u","̆" },
+ ["Å®"]={ "U","ÌŠ" },
+ ["ů"]={ "u","̊" },
+ ["Å°"]={ "U","Ì‹" },
+ ["ű"]={ "u","̋" },
+ ["Ų"]={ "U","̨" },
+ ["ų"]={ "u","̨" },
+ ["Å´"]={ "W","Ì‚" },
+ ["ŵ"]={ "w","̂" },
+ ["Ŷ"]={ "Y","̂" },
+ ["Å·"]={ "y","Ì‚" },
+ ["Ÿ"]={ "Y","̈" },
+ ["Ź"]={ "Z","Ì" },
+ ["ź"]={ "z","Ì" },
+ ["Ż"]={ "Z","̇" },
+ ["ż"]={ "z","̇" },
+ ["Ž"]={ "Z","̌" },
+ ["ž"]={ "z","̌" },
+ ["Æ "]={ "O","Ì›" },
+ ["Æ¡"]={ "o","Ì›" },
+ ["Ư"]={ "U","̛" },
+ ["Æ°"]={ "u","Ì›" },
+ ["Ç"]={ "A","ÌŒ" },
+ ["ǎ"]={ "a","̌" },
+ ["Ç"]={ "I","ÌŒ" },
+ ["Ç"]={ "i","ÌŒ" },
+ ["Ǒ"]={ "O","̌" },
+ ["ǒ"]={ "o","̌" },
+ ["Ǔ"]={ "U","̌" },
+ ["ǔ"]={ "u","̌" },
+ ["Ǖ"]={ "Ü","̄" },
+ ["ǖ"]={ "ü","̄" },
+ ["Ç—"]={ "Ãœ","Ì" },
+ ["ǘ"]={ "ü","Ì" },
+ ["Ǚ"]={ "Ü","̌" },
+ ["ǚ"]={ "ü","̌" },
+ ["Ǜ"]={ "Ü","̀" },
+ ["ǜ"]={ "ü","̀" },
+ ["Ǟ"]={ "Ä","̄" },
+ ["ǟ"]={ "ä","̄" },
+ ["Ǡ"]={ "Ȧ","̄" },
+ ["ǡ"]={ "ȧ","̄" },
+ ["Ǣ"]={ "Æ","̄" },
+ ["ǣ"]={ "æ","̄" },
+ ["Ǧ"]={ "G","̌" },
+ ["ǧ"]={ "g","̌" },
+ ["Ǩ"]={ "K","̌" },
+ ["ǩ"]={ "k","̌" },
+ ["Ǫ"]={ "O","̨" },
+ ["ǫ"]={ "o","̨" },
+ ["Ǭ"]={ "Ǫ","̄" },
+ ["Ç­"]={ "Ç«","Ì„" },
+ ["Ǯ"]={ "Ʒ","̌" },
+ ["ǯ"]={ "ʒ","̌" },
+ ["ǰ"]={ "j","̌" },
+ ["Ç´"]={ "G","Ì" },
+ ["ǵ"]={ "g","Ì" },
+ ["Ǹ"]={ "N","̀" },
+ ["ǹ"]={ "n","̀" },
+ ["Ǻ"]={ "Ã…","Ì" },
+ ["Ç»"]={ "Ã¥","Ì" },
+ ["Ǽ"]={ "Æ","Ì" },
+ ["ǽ"]={ "æ","Ì" },
+ ["Ǿ"]={ "Ø","Ì" },
+ ["Ç¿"]={ "ø","Ì" },
+ ["È€"]={ "A","Ì" },
+ ["È"]={ "a","Ì" },
+ ["È‚"]={ "A","Ì‘" },
+ ["ȃ"]={ "a","̑" },
+ ["È„"]={ "E","Ì" },
+ ["È…"]={ "e","Ì" },
+ ["Ȇ"]={ "E","̑" },
+ ["ȇ"]={ "e","̑" },
+ ["Ȉ"]={ "I","Ì" },
+ ["ȉ"]={ "i","Ì" },
+ ["ÈŠ"]={ "I","Ì‘" },
+ ["È‹"]={ "i","Ì‘" },
+ ["ÈŒ"]={ "O","Ì" },
+ ["È"]={ "o","Ì" },
+ ["ÈŽ"]={ "O","Ì‘" },
+ ["È"]={ "o","Ì‘" },
+ ["È"]={ "R","Ì" },
+ ["È‘"]={ "r","Ì" },
+ ["È’"]={ "R","Ì‘" },
+ ["È“"]={ "r","Ì‘" },
+ ["È”"]={ "U","Ì" },
+ ["È•"]={ "u","Ì" },
+ ["È–"]={ "U","Ì‘" },
+ ["È—"]={ "u","Ì‘" },
+ ["Ș"]={ "S","̦" },
+ ["ș"]={ "s","̦" },
+ ["Ț"]={ "T","̦" },
+ ["ț"]={ "t","̦" },
+ ["Ȟ"]={ "H","̌" },
+ ["ȟ"]={ "h","̌" },
+ ["Ȧ"]={ "A","̇" },
+ ["ȧ"]={ "a","̇" },
+ ["Ȩ"]={ "E","̧" },
+ ["ȩ"]={ "e","̧" },
+ ["Ȫ"]={ "Ö","̄" },
+ ["ȫ"]={ "ö","̄" },
+ ["Ȭ"]={ "Õ","̄" },
+ ["ȭ"]={ "õ","̄" },
+ ["Ȯ"]={ "O","̇" },
+ ["ȯ"]={ "o","̇" },
+ ["È°"]={ "È®","Ì„" },
+ ["ȱ"]={ "ȯ","̄" },
+ ["Ȳ"]={ "Y","̄" },
+ ["ȳ"]={ "y","̄" },
+ ["Í„"]={ "̈","Ì" },
+ ["Î…"]={ "¨","Ì" },
+ ["Ά"]={ "Α","Ì" },
+ ["Έ"]={ "Ε","Ì" },
+ ["Ή"]={ "Η","Ì" },
+ ["Ί"]={ "Ι","Ì" },
+ ["ÎŒ"]={ "Ο","Ì" },
+ ["ÎŽ"]={ "Î¥","Ì" },
+ ["Î"]={ "Ω","Ì" },
+ ["Î"]={ "ÏŠ","Ì" },
+ ["Ϊ"]={ "Ι","̈" },
+ ["Ϋ"]={ "Υ","̈" },
+ ["ά"]={ "α","Ì" },
+ ["έ"]={ "ε","Ì" },
+ ["ή"]={ "η","Ì" },
+ ["ί"]={ "ι","Ì" },
+ ["ΰ"]={ "Ï‹","Ì" },
+ ["ϊ"]={ "ι","̈" },
+ ["ϋ"]={ "υ","̈" },
+ ["ÏŒ"]={ "ο","Ì" },
+ ["Ï"]={ "Ï…","Ì" },
+ ["ÏŽ"]={ "ω","Ì" },
+ ["Ï“"]={ "Ï’","Ì" },
+ ["ϔ"]={ "ϒ","̈" },
+ ["Ѐ"]={ "Е","̀" },
+ ["Ð"]={ "Е","̈" },
+ ["Ѓ"]={ "Г","Ì" },
+ ["Ї"]={ "І","̈" },
+ ["ÐŒ"]={ "К","Ì" },
+ ["Ð"]={ "И","Ì€" },
+ ["Ў"]={ "У","̆" },
+ ["Й"]={ "И","̆" },
+ ["й"]={ "и","̆" },
+ ["Ñ"]={ "е","Ì€" },
+ ["ё"]={ "е","̈" },
+ ["Ñ“"]={ "г","Ì" },
+ ["ї"]={ "і","̈" },
+ ["Ñœ"]={ "к","Ì" },
+ ["Ñ"]={ "и","Ì€" },
+ ["ў"]={ "у","̆" },
+ ["Ѷ"]={ "Ñ´","Ì" },
+ ["Ñ·"]={ "ѵ","Ì" },
+ ["Ó"]={ "Ж","̆" },
+ ["ӂ"]={ "ж","̆" },
+ ["Ó"]={ "Ð","̆" },
+ ["ӑ"]={ "а","̆" },
+ ["Ó’"]={ "Ð","̈" },
+ ["ӓ"]={ "а","̈" },
+ ["Ӗ"]={ "Е","̆" },
+ ["ӗ"]={ "е","̆" },
+ ["Ӛ"]={ "Ә","̈" },
+ ["ӛ"]={ "ә","̈" },
+ ["Ӝ"]={ "Ж","̈" },
+ ["Ó"]={ "ж","̈" },
+ ["Ӟ"]={ "З","̈" },
+ ["ӟ"]={ "з","̈" },
+ ["Ӣ"]={ "И","̄" },
+ ["ӣ"]={ "и","̄" },
+ ["Ӥ"]={ "И","̈" },
+ ["ӥ"]={ "и","̈" },
+ ["Ӧ"]={ "О","̈" },
+ ["ӧ"]={ "о","̈" },
+ ["Ӫ"]={ "Ө","̈" },
+ ["ӫ"]={ "ө","̈" },
+ ["Ӭ"]={ "Э","̈" },
+ ["Ó­"]={ "Ñ","̈" },
+ ["Ӯ"]={ "У","̄" },
+ ["ӯ"]={ "у","̄" },
+ ["Ӱ"]={ "У","̈" },
+ ["ӱ"]={ "у","̈" },
+ ["Ӳ"]={ "У","̋" },
+ ["ӳ"]={ "у","̋" },
+ ["Ӵ"]={ "Ч","̈" },
+ ["ӵ"]={ "ч","̈" },
+ ["Ӹ"]={ "Ы","̈" },
+ ["ӹ"]={ "ы","̈" },
+ ["آ"]={ "ا","ٓ" },
+ ["أ"]={ "ا","ٔ" },
+ ["ؤ"]={ "و","ٔ" },
+ ["إ"]={ "ا","ٕ" },
+ ["ئ"]={ "ي","ٔ" },
+ ["Û€"]={ "Û•","Ù”" },
+ ["Û‚"]={ "Û","Ù”" },
+ ["Û“"]={ "Û’","Ù”" },
+ ["ऩ"]={ "न","़" },
+ ["ऱ"]={ "र","़" },
+ ["ऴ"]={ "ळ","़" },
+ ["क़"]={ "क","़" },
+ ["ख़"]={ "ख","़" },
+ ["ग़"]={ "ग","़" },
+ ["ज़"]={ "ज","़" },
+ ["ड़"]={ "ड","़" },
+ ["à¥"]={ "ढ","़" },
+ ["फ़"]={ "फ","़" },
+ ["य़"]={ "य","़" },
+ ["ো"]={ "ে","া" },
+ ["ৌ"]={ "ে","ৗ" },
+ ["ড়"]={ "ড","়" },
+ ["à§"]={ "ঢ","়" },
+ ["য়"]={ "য","়" },
+ ["ਲ਼"]={ "ਲ","਼" },
+ ["ਸ਼"]={ "ਸ","਼" },
+ ["ਖ਼"]={ "ਖ","਼" },
+ ["ਗ਼"]={ "ਗ","਼" },
+ ["ਜ਼"]={ "ਜ","਼" },
+ ["ਫ਼"]={ "ਫ","਼" },
+ ["à­ˆ"]={ "à­‡","à­–" },
+ ["ୋ"]={ "େ","ା" },
+ ["ୌ"]={ "େ","ୗ" },
+ ["ଡ଼"]={ "ଡ","଼" },
+ ["à­"]={ "ଢ","଼" },
+ ["ஔ"]={ "ஒ","ௗ" },
+ ["ொ"]={ "ெ","ா" },
+ ["ோ"]={ "ே","ா" },
+ ["ௌ"]={ "ெ","ௗ" },
+ ["ై"]={ "ె","ౖ" },
+ ["ೀ"]={ "ಿ","ೕ" },
+ ["ೇ"]={ "ೆ","ೕ" },
+ ["ೈ"]={ "ೆ","ೖ" },
+ ["ೊ"]={ "ೆ","ೂ" },
+ ["ೋ"]={ "ೊ","ೕ" },
+ ["ൊ"]={ "െ","ാ" },
+ ["ോ"]={ "േ","ാ" },
+ ["ൌ"]={ "െ","ൗ" },
+ ["à·š"]={ "à·™","à·Š" },
+ ["à·œ"]={ "à·™","à·" },
+ ["à·"]={ "à·œ","à·Š" },
+ ["à·ž"]={ "à·™","à·Ÿ" },
+ ["གྷ"]={ "ག","ྷ" },
+ ["à½"]={ "ཌ","ྷ" },
+ ["དྷ"]={ "ད","ྷ" },
+ ["བྷ"]={ "བ","ྷ" },
+ ["ཛྷ"]={ "ཛ","ྷ" },
+ ["ཀྵ"]={ "ཀ","ྵ" },
+ ["ཱི"]={ "ཱ","ི" },
+ ["ཱུ"]={ "ཱ","ུ" },
+ ["ྲྀ"]={ "ྲ","ྀ" },
+ ["ླྀ"]={ "ླ","ྀ" },
+ ["à¾"]={ "ཱ","ྀ" },
+ ["ྒྷ"]={ "ྒ","ྷ" },
+ ["à¾"]={ "ྜ","ྷ" },
+ ["ྡྷ"]={ "ྡ","ྷ" },
+ ["ྦྷ"]={ "ྦ","ྷ" },
+ ["ྫྷ"]={ "ྫ","ྷ" },
+ ["ྐྵ"]={ "à¾","ྵ" },
+ ["ဦ"]={ "ဥ","ီ" },
+ ["ᬆ"]={ "ᬅ","ᬵ" },
+ ["ᬈ"]={ "ᬇ","ᬵ" },
+ ["ᬊ"]={ "ᬉ","ᬵ" },
+ ["ᬌ"]={ "ᬋ","ᬵ" },
+ ["ᬎ"]={ "á¬","ᬵ" },
+ ["ᬒ"]={ "ᬑ","ᬵ" },
+ ["ᬻ"]={ "ᬺ","ᬵ" },
+ ["ᬽ"]={ "ᬼ","ᬵ" },
+ ["ᭀ"]={ "ᬾ","ᬵ" },
+ ["á­"]={ "ᬿ","ᬵ" },
+ ["ᭃ"]={ "ᭂ","ᬵ" },
+ ["Ḁ"]={ "A","̥" },
+ ["á¸"]={ "a","Ì¥" },
+ ["Ḃ"]={ "B","̇" },
+ ["ḃ"]={ "b","̇" },
+ ["Ḅ"]={ "B","̣" },
+ ["ḅ"]={ "b","̣" },
+ ["Ḇ"]={ "B","̱" },
+ ["ḇ"]={ "b","̱" },
+ ["Ḉ"]={ "Ç","Ì" },
+ ["ḉ"]={ "ç","Ì" },
+ ["Ḋ"]={ "D","̇" },
+ ["ḋ"]={ "d","̇" },
+ ["Ḍ"]={ "D","̣" },
+ ["á¸"]={ "d","Ì£" },
+ ["Ḏ"]={ "D","̱" },
+ ["á¸"]={ "d","̱" },
+ ["á¸"]={ "D","̧" },
+ ["ḑ"]={ "d","̧" },
+ ["Ḓ"]={ "D","̭" },
+ ["ḓ"]={ "d","̭" },
+ ["Ḕ"]={ "Ē","̀" },
+ ["ḕ"]={ "ē","̀" },
+ ["Ḗ"]={ "Ä’","Ì" },
+ ["ḗ"]={ "Ä“","Ì" },
+ ["Ḙ"]={ "E","̭" },
+ ["ḙ"]={ "e","̭" },
+ ["Ḛ"]={ "E","̰" },
+ ["ḛ"]={ "e","̰" },
+ ["Ḝ"]={ "Ȩ","̆" },
+ ["á¸"]={ "È©","̆" },
+ ["Ḟ"]={ "F","̇" },
+ ["ḟ"]={ "f","̇" },
+ ["Ḡ"]={ "G","̄" },
+ ["ḡ"]={ "g","̄" },
+ ["Ḣ"]={ "H","̇" },
+ ["ḣ"]={ "h","̇" },
+ ["Ḥ"]={ "H","̣" },
+ ["ḥ"]={ "h","̣" },
+ ["Ḧ"]={ "H","̈" },
+ ["ḧ"]={ "h","̈" },
+ ["Ḩ"]={ "H","̧" },
+ ["ḩ"]={ "h","̧" },
+ ["Ḫ"]={ "H","̮" },
+ ["ḫ"]={ "h","̮" },
+ ["Ḭ"]={ "I","̰" },
+ ["ḭ"]={ "i","̰" },
+ ["Ḯ"]={ "Ã","Ì" },
+ ["ḯ"]={ "ï","Ì" },
+ ["Ḱ"]={ "K","Ì" },
+ ["ḱ"]={ "k","Ì" },
+ ["Ḳ"]={ "K","̣" },
+ ["ḳ"]={ "k","̣" },
+ ["Ḵ"]={ "K","̱" },
+ ["ḵ"]={ "k","̱" },
+ ["Ḷ"]={ "L","̣" },
+ ["ḷ"]={ "l","̣" },
+ ["Ḹ"]={ "Ḷ","̄" },
+ ["ḹ"]={ "ḷ","̄" },
+ ["Ḻ"]={ "L","̱" },
+ ["ḻ"]={ "l","̱" },
+ ["Ḽ"]={ "L","̭" },
+ ["ḽ"]={ "l","̭" },
+ ["Ḿ"]={ "M","Ì" },
+ ["ḿ"]={ "m","Ì" },
+ ["Ṁ"]={ "M","̇" },
+ ["á¹"]={ "m","̇" },
+ ["Ṃ"]={ "M","̣" },
+ ["ṃ"]={ "m","̣" },
+ ["Ṅ"]={ "N","̇" },
+ ["ṅ"]={ "n","̇" },
+ ["Ṇ"]={ "N","̣" },
+ ["ṇ"]={ "n","̣" },
+ ["Ṉ"]={ "N","̱" },
+ ["ṉ"]={ "n","̱" },
+ ["Ṋ"]={ "N","̭" },
+ ["ṋ"]={ "n","̭" },
+ ["Ṍ"]={ "Õ","Ì" },
+ ["á¹"]={ "õ","Ì" },
+ ["Ṏ"]={ "Õ","̈" },
+ ["á¹"]={ "õ","̈" },
+ ["á¹"]={ "ÅŒ","Ì€" },
+ ["ṑ"]={ "Å","Ì€" },
+ ["á¹’"]={ "ÅŒ","Ì" },
+ ["ṓ"]={ "Å","Ì" },
+ ["á¹”"]={ "P","Ì" },
+ ["ṕ"]={ "p","Ì" },
+ ["Ṗ"]={ "P","̇" },
+ ["ṗ"]={ "p","̇" },
+ ["Ṙ"]={ "R","̇" },
+ ["ṙ"]={ "r","̇" },
+ ["Ṛ"]={ "R","̣" },
+ ["á¹›"]={ "r","Ì£" },
+ ["Ṝ"]={ "Ṛ","̄" },
+ ["á¹"]={ "á¹›","Ì„" },
+ ["Ṟ"]={ "R","̱" },
+ ["ṟ"]={ "r","̱" },
+ ["Ṡ"]={ "S","̇" },
+ ["ṡ"]={ "s","̇" },
+ ["á¹¢"]={ "S","Ì£" },
+ ["á¹£"]={ "s","Ì£" },
+ ["Ṥ"]={ "Ś","̇" },
+ ["ṥ"]={ "ś","̇" },
+ ["Ṧ"]={ "Š","̇" },
+ ["ṧ"]={ "š","̇" },
+ ["Ṩ"]={ "Ṣ","̇" },
+ ["ṩ"]={ "ṣ","̇" },
+ ["Ṫ"]={ "T","̇" },
+ ["ṫ"]={ "t","̇" },
+ ["Ṭ"]={ "T","̣" },
+ ["á¹­"]={ "t","Ì£" },
+ ["Ṯ"]={ "T","̱" },
+ ["ṯ"]={ "t","̱" },
+ ["á¹°"]={ "T","Ì­" },
+ ["á¹±"]={ "t","Ì­" },
+ ["Ṳ"]={ "U","̤" },
+ ["ṳ"]={ "u","̤" },
+ ["á¹´"]={ "U","Ì°" },
+ ["á¹µ"]={ "u","Ì°" },
+ ["Ṷ"]={ "U","̭" },
+ ["á¹·"]={ "u","Ì­" },
+ ["Ṹ"]={ "Ũ","Ì" },
+ ["á¹¹"]={ "Å©","Ì" },
+ ["Ṻ"]={ "Ū","̈" },
+ ["ṻ"]={ "ū","̈" },
+ ["Ṽ"]={ "V","̃" },
+ ["ṽ"]={ "v","̃" },
+ ["á¹¾"]={ "V","Ì£" },
+ ["ṿ"]={ "v","̣" },
+ ["Ẁ"]={ "W","̀" },
+ ["áº"]={ "w","Ì€" },
+ ["Ẃ"]={ "W","Ì" },
+ ["ẃ"]={ "w","Ì" },
+ ["Ẅ"]={ "W","̈" },
+ ["ẅ"]={ "w","̈" },
+ ["Ẇ"]={ "W","̇" },
+ ["ẇ"]={ "w","̇" },
+ ["Ẉ"]={ "W","̣" },
+ ["ẉ"]={ "w","̣" },
+ ["Ẋ"]={ "X","̇" },
+ ["ẋ"]={ "x","̇" },
+ ["Ẍ"]={ "X","̈" },
+ ["áº"]={ "x","̈" },
+ ["Ẏ"]={ "Y","̇" },
+ ["áº"]={ "y","̇" },
+ ["áº"]={ "Z","Ì‚" },
+ ["ẑ"]={ "z","̂" },
+ ["Ẓ"]={ "Z","̣" },
+ ["ẓ"]={ "z","̣" },
+ ["Ẕ"]={ "Z","̱" },
+ ["ẕ"]={ "z","̱" },
+ ["ẖ"]={ "h","̱" },
+ ["ẗ"]={ "t","̈" },
+ ["ẘ"]={ "w","̊" },
+ ["ẙ"]={ "y","̊" },
+ ["ẛ"]={ "ſ","̇" },
+ ["Ạ"]={ "A","̣" },
+ ["ạ"]={ "a","̣" },
+ ["Ả"]={ "A","̉" },
+ ["ả"]={ "a","̉" },
+ ["Ấ"]={ "Â","Ì" },
+ ["ấ"]={ "â","Ì" },
+ ["Ầ"]={ "Â","̀" },
+ ["ầ"]={ "â","̀" },
+ ["Ẩ"]={ "Â","̉" },
+ ["ẩ"]={ "â","̉" },
+ ["Ẫ"]={ "Â","̃" },
+ ["ẫ"]={ "â","̃" },
+ ["Ậ"]={ "Ạ","̂" },
+ ["ậ"]={ "ạ","̂" },
+ ["Ắ"]={ "Ä‚","Ì" },
+ ["ắ"]={ "ă","Ì" },
+ ["Ằ"]={ "Ă","̀" },
+ ["ằ"]={ "ă","̀" },
+ ["Ẳ"]={ "Ă","̉" },
+ ["ẳ"]={ "ă","̉" },
+ ["Ẵ"]={ "Ă","̃" },
+ ["ẵ"]={ "ă","̃" },
+ ["Ặ"]={ "Ạ","̆" },
+ ["ặ"]={ "ạ","̆" },
+ ["Ẹ"]={ "E","̣" },
+ ["ẹ"]={ "e","̣" },
+ ["Ẻ"]={ "E","̉" },
+ ["ẻ"]={ "e","̉" },
+ ["Ẽ"]={ "E","̃" },
+ ["ẽ"]={ "e","̃" },
+ ["Ế"]={ "Ê","Ì" },
+ ["ế"]={ "ê","Ì" },
+ ["Ề"]={ "Ê","̀" },
+ ["á»"]={ "ê","Ì€" },
+ ["Ể"]={ "Ê","̉" },
+ ["ể"]={ "ê","̉" },
+ ["Ễ"]={ "Ê","̃" },
+ ["ễ"]={ "ê","̃" },
+ ["Ệ"]={ "Ẹ","̂" },
+ ["ệ"]={ "ẹ","̂" },
+ ["Ỉ"]={ "I","̉" },
+ ["ỉ"]={ "i","̉" },
+ ["Ị"]={ "I","̣" },
+ ["ị"]={ "i","̣" },
+ ["Ọ"]={ "O","̣" },
+ ["á»"]={ "o","Ì£" },
+ ["Ỏ"]={ "O","̉" },
+ ["á»"]={ "o","̉" },
+ ["á»"]={ "Ô","Ì" },
+ ["ố"]={ "ô","Ì" },
+ ["Ồ"]={ "Ô","̀" },
+ ["ồ"]={ "ô","̀" },
+ ["Ổ"]={ "Ô","̉" },
+ ["ổ"]={ "ô","̉" },
+ ["Ỗ"]={ "Ô","̃" },
+ ["ỗ"]={ "ô","̃" },
+ ["Ộ"]={ "Ọ","̂" },
+ ["á»™"]={ "á»","Ì‚" },
+ ["Ớ"]={ "Æ ","Ì" },
+ ["á»›"]={ "Æ¡","Ì" },
+ ["Ờ"]={ "Ơ","̀" },
+ ["á»"]={ "Æ¡","Ì€" },
+ ["Ở"]={ "Ơ","̉" },
+ ["ở"]={ "ơ","̉" },
+ ["Ỡ"]={ "Ơ","̃" },
+ ["ỡ"]={ "ơ","̃" },
+ ["Ợ"]={ "Ơ","̣" },
+ ["ợ"]={ "ơ","̣" },
+ ["Ụ"]={ "U","̣" },
+ ["ụ"]={ "u","̣" },
+ ["Ủ"]={ "U","̉" },
+ ["ủ"]={ "u","̉" },
+ ["Ứ"]={ "Ư","Ì" },
+ ["ứ"]={ "Æ°","Ì" },
+ ["Ừ"]={ "Ư","̀" },
+ ["ừ"]={ "ư","̀" },
+ ["Ử"]={ "Ư","̉" },
+ ["ử"]={ "ư","̉" },
+ ["Ữ"]={ "Ư","̃" },
+ ["ữ"]={ "ư","̃" },
+ ["Ự"]={ "Ư","̣" },
+ ["á»±"]={ "Æ°","Ì£" },
+ ["Ỳ"]={ "Y","̀" },
+ ["ỳ"]={ "y","̀" },
+ ["á»´"]={ "Y","Ì£" },
+ ["ỵ"]={ "y","̣" },
+ ["Ỷ"]={ "Y","̉" },
+ ["ỷ"]={ "y","̉" },
+ ["Ỹ"]={ "Y","̃" },
+ ["ỹ"]={ "y","̃" },
+ ["ἀ"]={ "α","̓" },
+ ["á¼"]={ "α","Ì”" },
+ ["ἂ"]={ "ἀ","̀" },
+ ["ἃ"]={ "á¼","Ì€" },
+ ["ἄ"]={ "á¼€","Ì" },
+ ["á¼…"]={ "á¼","Ì" },
+ ["ἆ"]={ "ἀ","͂" },
+ ["ἇ"]={ "á¼","Í‚" },
+ ["Ἀ"]={ "Α","̓" },
+ ["Ἁ"]={ "Α","̔" },
+ ["Ἂ"]={ "Ἀ","̀" },
+ ["Ἃ"]={ "Ἁ","̀" },
+ ["Ἄ"]={ "Ἀ","Ì" },
+ ["á¼"]={ "Ἁ","Ì" },
+ ["Ἆ"]={ "Ἀ","͂" },
+ ["á¼"]={ "Ἁ","Í‚" },
+ ["á¼"]={ "ε","Ì“" },
+ ["ἑ"]={ "ε","̔" },
+ ["á¼’"]={ "á¼","Ì€" },
+ ["ἓ"]={ "ἑ","̀" },
+ ["á¼”"]={ "á¼","Ì" },
+ ["ἕ"]={ "ἑ","Ì" },
+ ["Ἐ"]={ "Ε","̓" },
+ ["Ἑ"]={ "Ε","̔" },
+ ["Ἒ"]={ "Ἐ","̀" },
+ ["á¼›"]={ "á¼™","Ì€" },
+ ["Ἔ"]={ "Ἐ","Ì" },
+ ["á¼"]={ "á¼™","Ì" },
+ ["ἠ"]={ "η","̓" },
+ ["ἡ"]={ "η","̔" },
+ ["á¼¢"]={ "á¼ ","Ì€" },
+ ["ἣ"]={ "ἡ","̀" },
+ ["ἤ"]={ "á¼ ","Ì" },
+ ["á¼¥"]={ "ἡ","Ì" },
+ ["ἦ"]={ "ἠ","͂" },
+ ["ἧ"]={ "ἡ","͂" },
+ ["Ἠ"]={ "Η","̓" },
+ ["Ἡ"]={ "Η","̔" },
+ ["Ἢ"]={ "Ἠ","̀" },
+ ["Ἣ"]={ "Ἡ","̀" },
+ ["Ἤ"]={ "Ἠ","Ì" },
+ ["á¼­"]={ "Ἡ","Ì" },
+ ["Ἦ"]={ "Ἠ","͂" },
+ ["Ἧ"]={ "Ἡ","͂" },
+ ["ἰ"]={ "ι","̓" },
+ ["ἱ"]={ "ι","̔" },
+ ["á¼²"]={ "á¼°","Ì€" },
+ ["á¼³"]={ "á¼±","Ì€" },
+ ["á¼´"]={ "á¼°","Ì" },
+ ["á¼µ"]={ "á¼±","Ì" },
+ ["ἶ"]={ "ἰ","͂" },
+ ["á¼·"]={ "á¼±","Í‚" },
+ ["Ἰ"]={ "Ι","̓" },
+ ["Ἱ"]={ "Ι","̔" },
+ ["Ἲ"]={ "Ἰ","̀" },
+ ["á¼»"]={ "á¼¹","Ì€" },
+ ["á¼¼"]={ "Ἰ","Ì" },
+ ["á¼½"]={ "á¼¹","Ì" },
+ ["Ἶ"]={ "Ἰ","͂" },
+ ["Ἷ"]={ "Ἱ","͂" },
+ ["ὀ"]={ "ο","̓" },
+ ["á½"]={ "ο","Ì”" },
+ ["ὂ"]={ "ὀ","̀" },
+ ["ὃ"]={ "á½","Ì€" },
+ ["ὄ"]={ "á½€","Ì" },
+ ["á½…"]={ "á½","Ì" },
+ ["Ὀ"]={ "Ο","̓" },
+ ["Ὁ"]={ "Ο","̔" },
+ ["Ὂ"]={ "Ὀ","̀" },
+ ["Ὃ"]={ "Ὁ","̀" },
+ ["Ὄ"]={ "Ὀ","Ì" },
+ ["á½"]={ "Ὁ","Ì" },
+ ["á½"]={ "Ï…","Ì“" },
+ ["ὑ"]={ "υ","̔" },
+ ["á½’"]={ "á½","Ì€" },
+ ["ὓ"]={ "ὑ","̀" },
+ ["á½”"]={ "á½","Ì" },
+ ["ὕ"]={ "ὑ","Ì" },
+ ["á½–"]={ "á½","Í‚" },
+ ["ὗ"]={ "ὑ","͂" },
+ ["á½™"]={ "Î¥","Ì”" },
+ ["á½›"]={ "á½™","Ì€" },
+ ["á½"]={ "á½™","Ì" },
+ ["Ὗ"]={ "Ὑ","͂" },
+ ["ὠ"]={ "ω","̓" },
+ ["ὡ"]={ "ω","̔" },
+ ["á½¢"]={ "á½ ","Ì€" },
+ ["ὣ"]={ "ὡ","̀" },
+ ["ὤ"]={ "á½ ","Ì" },
+ ["á½¥"]={ "ὡ","Ì" },
+ ["ὦ"]={ "ὠ","͂" },
+ ["ὧ"]={ "ὡ","͂" },
+ ["Ὠ"]={ "Ω","̓" },
+ ["Ὡ"]={ "Ω","̔" },
+ ["Ὢ"]={ "Ὠ","̀" },
+ ["Ὣ"]={ "Ὡ","̀" },
+ ["Ὤ"]={ "Ὠ","Ì" },
+ ["á½­"]={ "Ὡ","Ì" },
+ ["Ὦ"]={ "Ὠ","͂" },
+ ["Ὧ"]={ "Ὡ","͂" },
+ ["ὰ"]={ "α","̀" },
+ ["ὲ"]={ "ε","̀" },
+ ["ὴ"]={ "η","̀" },
+ ["ὶ"]={ "ι","̀" },
+ ["ὸ"]={ "ο","̀" },
+ ["ὺ"]={ "υ","̀" },
+ ["ὼ"]={ "ω","̀" },
+ ["á¾€"]={ "á¼€","Í…" },
+ ["á¾"]={ "á¼","Í…" },
+ ["ᾂ"]={ "ἂ","ͅ" },
+ ["ᾃ"]={ "ἃ","ͅ" },
+ ["ᾄ"]={ "ἄ","ͅ" },
+ ["á¾…"]={ "á¼…","Í…" },
+ ["ᾆ"]={ "ἆ","ͅ" },
+ ["ᾇ"]={ "ἇ","ͅ" },
+ ["ᾈ"]={ "Ἀ","ͅ" },
+ ["ᾉ"]={ "Ἁ","ͅ" },
+ ["ᾊ"]={ "Ἂ","ͅ" },
+ ["ᾋ"]={ "Ἃ","ͅ" },
+ ["ᾌ"]={ "Ἄ","ͅ" },
+ ["á¾"]={ "á¼","Í…" },
+ ["ᾎ"]={ "Ἆ","ͅ" },
+ ["á¾"]={ "á¼","Í…" },
+ ["á¾"]={ "á¼ ","Í…" },
+ ["ᾑ"]={ "ἡ","ͅ" },
+ ["á¾’"]={ "á¼¢","Í…" },
+ ["ᾓ"]={ "ἣ","ͅ" },
+ ["ᾔ"]={ "ἤ","ͅ" },
+ ["ᾕ"]={ "ἥ","ͅ" },
+ ["ᾖ"]={ "ἦ","ͅ" },
+ ["ᾗ"]={ "ἧ","ͅ" },
+ ["ᾘ"]={ "Ἠ","ͅ" },
+ ["ᾙ"]={ "Ἡ","ͅ" },
+ ["ᾚ"]={ "Ἢ","ͅ" },
+ ["ᾛ"]={ "Ἣ","ͅ" },
+ ["ᾜ"]={ "Ἤ","ͅ" },
+ ["á¾"]={ "á¼­","Í…" },
+ ["ᾞ"]={ "Ἦ","ͅ" },
+ ["ᾟ"]={ "Ἧ","ͅ" },
+ ["á¾ "]={ "á½ ","Í…" },
+ ["ᾡ"]={ "ὡ","ͅ" },
+ ["á¾¢"]={ "á½¢","Í…" },
+ ["á¾£"]={ "á½£","Í…" },
+ ["ᾤ"]={ "ὤ","ͅ" },
+ ["á¾¥"]={ "á½¥","Í…" },
+ ["ᾦ"]={ "ὦ","ͅ" },
+ ["ᾧ"]={ "ὧ","ͅ" },
+ ["ᾨ"]={ "Ὠ","ͅ" },
+ ["ᾩ"]={ "Ὡ","ͅ" },
+ ["ᾪ"]={ "Ὢ","ͅ" },
+ ["ᾫ"]={ "Ὣ","ͅ" },
+ ["ᾬ"]={ "Ὤ","ͅ" },
+ ["á¾­"]={ "á½­","Í…" },
+ ["á¾®"]={ "á½®","Í…" },
+ ["ᾯ"]={ "Ὧ","ͅ" },
+ ["ᾰ"]={ "α","̆" },
+ ["ᾱ"]={ "α","̄" },
+ ["á¾²"]={ "á½°","Í…" },
+ ["ᾳ"]={ "α","ͅ" },
+ ["ᾴ"]={ "ά","ͅ" },
+ ["ᾶ"]={ "α","͂" },
+ ["ᾷ"]={ "ᾶ","ͅ" },
+ ["Ᾰ"]={ "Α","̆" },
+ ["Ᾱ"]={ "Α","̄" },
+ ["Ὰ"]={ "Α","̀" },
+ ["ᾼ"]={ "Α","ͅ" },
+ ["á¿"]={ "¨","Í‚" },
+ ["á¿‚"]={ "á½´","Í…" },
+ ["ῃ"]={ "η","ͅ" },
+ ["ῄ"]={ "ή","ͅ" },
+ ["ῆ"]={ "η","͂" },
+ ["ῇ"]={ "ῆ","ͅ" },
+ ["Ὲ"]={ "Ε","̀" },
+ ["Ὴ"]={ "Η","̀" },
+ ["ῌ"]={ "Η","ͅ" },
+ ["á¿"]={ "᾿","Ì€" },
+ ["á¿Ž"]={ "᾿","Ì" },
+ ["á¿"]={ "᾿","Í‚" },
+ ["á¿"]={ "ι","̆" },
+ ["ῑ"]={ "ι","̄" },
+ ["á¿’"]={ "ÏŠ","Ì€" },
+ ["ῖ"]={ "ι","͂" },
+ ["á¿—"]={ "ÏŠ","Í‚" },
+ ["Ῐ"]={ "Ι","̆" },
+ ["Ῑ"]={ "Ι","̄" },
+ ["Ὶ"]={ "Ι","̀" },
+ ["á¿"]={ "῾","Ì€" },
+ ["á¿ž"]={ "῾","Ì" },
+ ["῟"]={ "῾","͂" },
+ ["ῠ"]={ "υ","̆" },
+ ["á¿¡"]={ "Ï…","Ì„" },
+ ["á¿¢"]={ "Ï‹","Ì€" },
+ ["ῤ"]={ "Ï","Ì“" },
+ ["á¿¥"]={ "Ï","Ì”" },
+ ["ῦ"]={ "υ","͂" },
+ ["ῧ"]={ "ϋ","͂" },
+ ["Ῠ"]={ "Υ","̆" },
+ ["á¿©"]={ "Î¥","Ì„" },
+ ["Ὺ"]={ "Υ","̀" },
+ ["Ῥ"]={ "Ρ","̔" },
+ ["῭"]={ "¨","̀" },
+ ["ῲ"]={ "ὼ","ͅ" },
+ ["ῳ"]={ "ω","ͅ" },
+ ["á¿´"]={ "ÏŽ","Í…" },
+ ["ῶ"]={ "ω","͂" },
+ ["ῷ"]={ "ῶ","ͅ" },
+ ["Ὸ"]={ "Ο","̀" },
+ ["Ὼ"]={ "Ω","̀" },
+ ["ῼ"]={ "Ω","ͅ" },
+ ["↚"]={ "â†","̸" },
+ ["↛"]={ "→","̸" },
+ ["↮"]={ "↔","̸" },
+ ["â‡"]={ "â‡","̸" },
+ ["⇎"]={ "⇔","̸" },
+ ["â‡"]={ "⇒","̸" },
+ ["∄"]={ "∃","̸" },
+ ["∉"]={ "∈","̸" },
+ ["∌"]={ "∋","̸" },
+ ["∤"]={ "∣","̸" },
+ ["∦"]={ "∥","̸" },
+ ["â‰"]={ "∼","̸" },
+ ["≄"]={ "≃","̸" },
+ ["≇"]={ "≅","̸" },
+ ["≉"]={ "≈","̸" },
+ ["≠"]={ "=","̸" },
+ ["≢"]={ "≡","̸" },
+ ["≭"]={ "â‰","̸" },
+ ["≮"]={ "<","̸" },
+ ["≯"]={ ">","̸" },
+ ["≰"]={ "≤","̸" },
+ ["≱"]={ "≥","̸" },
+ ["≴"]={ "≲","̸" },
+ ["≵"]={ "≳","̸" },
+ ["≸"]={ "≶","̸" },
+ ["≹"]={ "≷","̸" },
+ ["⊀"]={ "≺","̸" },
+ ["âŠ"]={ "≻","̸" },
+ ["⊄"]={ "⊂","̸" },
+ ["⊅"]={ "⊃","̸" },
+ ["⊈"]={ "⊆","̸" },
+ ["⊉"]={ "⊇","̸" },
+ ["⊬"]={ "⊢","̸" },
+ ["⊭"]={ "⊨","̸" },
+ ["⊮"]={ "⊩","̸" },
+ ["⊯"]={ "⊫","̸" },
+ ["⋠"]={ "≼","̸" },
+ ["⋡"]={ "≽","̸" },
+ ["⋢"]={ "⊑","̸" },
+ ["⋣"]={ "⊒","̸" },
+ ["⋪"]={ "⊲","̸" },
+ ["⋫"]={ "⊳","̸" },
+ ["⋬"]={ "⊴","̸" },
+ ["⋭"]={ "⊵","̸" },
+ ["â«œ"]={ "â«","̸" },
+ ["ãŒ"]={ "ã‹","ã‚™" },
+ ["ãŽ"]={ "ã","ã‚™" },
+ ["ã"]={ "ã","ã‚™" },
+ ["ã’"]={ "ã‘","ã‚™" },
+ ["ã”"]={ "ã“","ã‚™" },
+ ["ã–"]={ "ã•","ã‚™" },
+ ["ã˜"]={ "ã—","ã‚™" },
+ ["ãš"]={ "ã™","ã‚™" },
+ ["ãœ"]={ "ã›","ã‚™" },
+ ["ãž"]={ "ã","ã‚™" },
+ ["ã "]={ "ãŸ","ã‚™" },
+ ["ã¢"]={ "ã¡","ã‚™" },
+ ["ã¥"]={ "ã¤","ã‚™" },
+ ["ã§"]={ "ã¦","ã‚™" },
+ ["ã©"]={ "ã¨","ã‚™" },
+ ["ã°"]={ "ã¯","ã‚™" },
+ ["ã±"]={ "ã¯","ã‚š" },
+ ["ã³"]={ "ã²","ã‚™" },
+ ["ã´"]={ "ã²","ã‚š" },
+ ["ã¶"]={ "ãµ","ã‚™" },
+ ["ã·"]={ "ãµ","ã‚š" },
+ ["ã¹"]={ "ã¸","ã‚™" },
+ ["ãº"]={ "ã¸","ã‚š" },
+ ["ã¼"]={ "ã»","ã‚™" },
+ ["ã½"]={ "ã»","ã‚š" },
+ ["ã‚”"]={ "ã†","ã‚™" },
+ ["ã‚ž"]={ "ã‚","ã‚™" },
+ ["ガ"]={ "カ","゙" },
+ ["ã‚®"]={ "ã‚­","ã‚™" },
+ ["グ"]={ "ク","゙" },
+ ["ゲ"]={ "ケ","゙" },
+ ["ゴ"]={ "コ","゙" },
+ ["ザ"]={ "サ","゙" },
+ ["ジ"]={ "シ","゙" },
+ ["ズ"]={ "ス","゙" },
+ ["ゼ"]={ "セ","゙" },
+ ["ゾ"]={ "ソ","゙" },
+ ["ダ"]={ "タ","゙" },
+ ["ヂ"]={ "ãƒ","ã‚™" },
+ ["ヅ"]={ "ツ","゙" },
+ ["デ"]={ "テ","゙" },
+ ["ド"]={ "ト","゙" },
+ ["ãƒ"]={ "ãƒ","ã‚™" },
+ ["パ"]={ "ãƒ","ã‚š" },
+ ["ビ"]={ "ヒ","゙" },
+ ["ピ"]={ "ヒ","゚" },
+ ["ブ"]={ "フ","゙" },
+ ["プ"]={ "フ","゚" },
+ ["ベ"]={ "ヘ","゙" },
+ ["ペ"]={ "ヘ","゚" },
+ ["ボ"]={ "ホ","゙" },
+ ["ãƒ"]={ "ホ","ã‚š" },
+ ["ヴ"]={ "ウ","゙" },
+ ["ヷ"]={ "ワ","゙" },
+ ["ヸ"]={ "ヰ","゙" },
+ ["ヹ"]={ "ヱ","゙" },
+ ["ヺ"]={ "ヲ","゙" },
+ ["ヾ"]={ "ヽ","゙" },
+ ["ï¬"]={ "×™","Ö´" },
+ ["ײַ"]={ "ײ","ַ" },
+ ["שׁ"]={ "ש","×" },
+ ["שׂ"]={ "ש","ׂ" },
+ ["שּׁ"]={ "ï­‰","×" },
+ ["שּׂ"]={ "שּ","ׂ" },
+ ["אַ"]={ "×","Ö·" },
+ ["אָ"]={ "×","Ö¸" },
+ ["אּ"]={ "×","Ö¼" },
+ ["בּ"]={ "ב","ּ" },
+ ["גּ"]={ "ג","ּ" },
+ ["דּ"]={ "ד","ּ" },
+ ["הּ"]={ "ה","ּ" },
+ ["וּ"]={ "ו","ּ" },
+ ["זּ"]={ "ז","ּ" },
+ ["טּ"]={ "ט","ּ" },
+ ["יּ"]={ "י","ּ" },
+ ["ךּ"]={ "ך","ּ" },
+ ["כּ"]={ "כ","ּ" },
+ ["לּ"]={ "ל","ּ" },
+ ["מּ"]={ "מ","ּ" },
+ ["ï­€"]={ "× ","Ö¼" },
+ ["ï­"]={ "ס","Ö¼" },
+ ["ï­ƒ"]={ "×£","Ö¼" },
+ ["פּ"]={ "פ","ּ" },
+ ["צּ"]={ "צ","ּ" },
+ ["קּ"]={ "ק","ּ" },
+ ["רּ"]={ "ר","ּ" },
+ ["שּ"]={ "ש","ּ" },
+ ["תּ"]={ "ת","ּ" },
+ ["וֹ"]={ "ו","ֹ" },
+ ["בֿ"]={ "ב","ֿ" },
+ ["ï­"]={ "×›","Ö¿" },
+ ["פֿ"]={ "פ","ֿ" },
+ ["𑂚"]={ "𑂙","𑂺" },
+ ["𑂜"]={ "𑂛","𑂺" },
+ ["𑂫"]={ "𑂥","𑂺" },
+ ["𑄮"]={ "𑄱","𑄧" },
+ ["𑄯"]={ "𑄲","𑄧" },
+ ["ð‘‹"]={ "ð‘‡","𑌾" },
+ ["ð‘Œ"]={ "ð‘‡","ð‘—" },
+ ["ð‘’»"]={ "ð‘’¹","ð‘’º" },
+ ["ð‘’¼"]={ "ð‘’¹","ð‘’°" },
+ ["ð‘’¾"]={ "ð‘’¹","ð‘’½" },
+ ["ð‘–º"]={ "ð‘–¸","ð‘–¯" },
+ ["ð‘–»"]={ "ð‘–¹","ð‘–¯" },
+ ["ð…ž"]={ "ð…—","ð…¥" },
+ ["ð…Ÿ"]={ "ð…˜","ð…¥" },
+ ["ð… "]={ "ð…Ÿ","ð…®" },
+ ["ð…¡"]={ "ð…Ÿ","ð…¯" },
+ ["ð…¢"]={ "ð…Ÿ","ð…°" },
+ ["ð…£"]={ "ð…Ÿ","ð…±" },
+ ["ð…¤"]={ "ð…Ÿ","ð…²" },
+ ["ð†»"]={ "ð†¹","ð…¥" },
+ ["ð†¼"]={ "ð†º","ð…¥" },
+ ["ð†½"]={ "ð†»","ð…®" },
+ ["ð†¾"]={ "ð†¼","ð…®" },
+ ["ð†¿"]={ "ð†»","ð…¯" },
+ ["ð‡€"]={ "ð†¼","ð…¯" },
+ },
+ },
+ {
+ ["data"]={
+ ["À"]={ "A","̀" },
+ ["Ã"]={ "A","Ì" },
+ ["Â"]={ "A","̂" },
+ ["Ã"]={ "A","̃" },
+ ["Ä"]={ "A","̈" },
+ ["Ã…"]={ "A","ÌŠ" },
+ ["Ç"]={ "C","̧" },
+ ["È"]={ "E","̀" },
+ ["É"]={ "E","Ì" },
+ ["Ê"]={ "E","̂" },
+ ["Ë"]={ "E","̈" },
+ ["Ì"]={ "I","̀" },
+ ["Ã"]={ "I","Ì" },
+ ["ÃŽ"]={ "I","Ì‚" },
+ ["Ã"]={ "I","̈" },
+ ["Ñ"]={ "N","̃" },
+ ["Ã’"]={ "O","Ì€" },
+ ["Ó"]={ "O","Ì" },
+ ["Ô"]={ "O","̂" },
+ ["Õ"]={ "O","̃" },
+ ["Ö"]={ "O","̈" },
+ ["Ù"]={ "U","̀" },
+ ["Ú"]={ "U","Ì" },
+ ["Û"]={ "U","̂" },
+ ["Ü"]={ "U","̈" },
+ ["Ã"]={ "Y","Ì" },
+ ["à"]={ "a","̀" },
+ ["á"]={ "a","Ì" },
+ ["â"]={ "a","̂" },
+ ["ã"]={ "a","̃" },
+ ["ä"]={ "a","̈" },
+ ["Ã¥"]={ "a","ÌŠ" },
+ ["ç"]={ "c","̧" },
+ ["è"]={ "e","̀" },
+ ["é"]={ "e","Ì" },
+ ["ê"]={ "e","̂" },
+ ["ë"]={ "e","̈" },
+ ["ì"]={ "i","̀" },
+ ["í"]={ "i","Ì" },
+ ["î"]={ "i","̂" },
+ ["ï"]={ "i","̈" },
+ ["ñ"]={ "n","̃" },
+ ["ò"]={ "o","̀" },
+ ["ó"]={ "o","Ì" },
+ ["ô"]={ "o","̂" },
+ ["õ"]={ "o","̃" },
+ ["ö"]={ "o","̈" },
+ ["ù"]={ "u","̀" },
+ ["ú"]={ "u","Ì" },
+ ["û"]={ "u","̂" },
+ ["ü"]={ "u","̈" },
+ ["ý"]={ "y","Ì" },
+ ["ÿ"]={ "y","̈" },
+ ["Ä€"]={ "A","Ì„" },
+ ["Ä"]={ "a","Ì„" },
+ ["Ă"]={ "A","̆" },
+ ["ă"]={ "a","̆" },
+ ["Ą"]={ "A","̨" },
+ ["ą"]={ "a","̨" },
+ ["Ć"]={ "C","Ì" },
+ ["ć"]={ "c","Ì" },
+ ["Ĉ"]={ "C","̂" },
+ ["ĉ"]={ "c","̂" },
+ ["Ċ"]={ "C","̇" },
+ ["ċ"]={ "c","̇" },
+ ["Č"]={ "C","̌" },
+ ["Ä"]={ "c","ÌŒ" },
+ ["Ď"]={ "D","̌" },
+ ["Ä"]={ "d","ÌŒ" },
+ ["Ä’"]={ "E","Ì„" },
+ ["Ä“"]={ "e","Ì„" },
+ ["Ĕ"]={ "E","̆" },
+ ["ĕ"]={ "e","̆" },
+ ["Ė"]={ "E","̇" },
+ ["ė"]={ "e","̇" },
+ ["Ę"]={ "E","̨" },
+ ["ę"]={ "e","̨" },
+ ["Ě"]={ "E","̌" },
+ ["ě"]={ "e","̌" },
+ ["Ĝ"]={ "G","̂" },
+ ["Ä"]={ "g","Ì‚" },
+ ["Ğ"]={ "G","̆" },
+ ["ğ"]={ "g","̆" },
+ ["Ġ"]={ "G","̇" },
+ ["ġ"]={ "g","̇" },
+ ["Ģ"]={ "G","̧" },
+ ["ģ"]={ "g","̧" },
+ ["Ĥ"]={ "H","̂" },
+ ["Ä¥"]={ "h","Ì‚" },
+ ["Ĩ"]={ "I","̃" },
+ ["ĩ"]={ "i","̃" },
+ ["Ī"]={ "I","̄" },
+ ["Ä«"]={ "i","Ì„" },
+ ["Ĭ"]={ "I","̆" },
+ ["ĭ"]={ "i","̆" },
+ ["Į"]={ "I","̨" },
+ ["į"]={ "i","̨" },
+ ["İ"]={ "I","̇" },
+ ["Ä´"]={ "J","Ì‚" },
+ ["ĵ"]={ "j","̂" },
+ ["Ķ"]={ "K","̧" },
+ ["ķ"]={ "k","̧" },
+ ["Ĺ"]={ "L","Ì" },
+ ["ĺ"]={ "l","Ì" },
+ ["Ļ"]={ "L","̧" },
+ ["ļ"]={ "l","̧" },
+ ["Ľ"]={ "L","̌" },
+ ["ľ"]={ "l","̌" },
+ ["Ń"]={ "N","Ì" },
+ ["Å„"]={ "n","Ì" },
+ ["Ņ"]={ "N","̧" },
+ ["ņ"]={ "n","̧" },
+ ["Ň"]={ "N","̌" },
+ ["ň"]={ "n","̌" },
+ ["Ō"]={ "O","̄" },
+ ["Å"]={ "o","Ì„" },
+ ["Ŏ"]={ "O","̆" },
+ ["Å"]={ "o","̆" },
+ ["Å"]={ "O","Ì‹" },
+ ["Å‘"]={ "o","Ì‹" },
+ ["Å”"]={ "R","Ì" },
+ ["Å•"]={ "r","Ì" },
+ ["Ŗ"]={ "R","̧" },
+ ["ŗ"]={ "r","̧" },
+ ["Ř"]={ "R","̌" },
+ ["ř"]={ "r","̌" },
+ ["Åš"]={ "S","Ì" },
+ ["Å›"]={ "s","Ì" },
+ ["Ŝ"]={ "S","̂" },
+ ["Å"]={ "s","Ì‚" },
+ ["Ş"]={ "S","̧" },
+ ["ş"]={ "s","̧" },
+ ["Š"]={ "S","̌" },
+ ["š"]={ "s","̌" },
+ ["Ţ"]={ "T","̧" },
+ ["ţ"]={ "t","̧" },
+ ["Ť"]={ "T","̌" },
+ ["ť"]={ "t","̌" },
+ ["Ũ"]={ "U","̃" },
+ ["ũ"]={ "u","̃" },
+ ["Ū"]={ "U","̄" },
+ ["Å«"]={ "u","Ì„" },
+ ["Ŭ"]={ "U","̆" },
+ ["ŭ"]={ "u","̆" },
+ ["Å®"]={ "U","ÌŠ" },
+ ["ů"]={ "u","̊" },
+ ["Å°"]={ "U","Ì‹" },
+ ["ű"]={ "u","̋" },
+ ["Ų"]={ "U","̨" },
+ ["ų"]={ "u","̨" },
+ ["Å´"]={ "W","Ì‚" },
+ ["ŵ"]={ "w","̂" },
+ ["Ŷ"]={ "Y","̂" },
+ ["Å·"]={ "y","Ì‚" },
+ ["Ÿ"]={ "Y","̈" },
+ ["Ź"]={ "Z","Ì" },
+ ["ź"]={ "z","Ì" },
+ ["Ż"]={ "Z","̇" },
+ ["ż"]={ "z","̇" },
+ ["Ž"]={ "Z","̌" },
+ ["ž"]={ "z","̌" },
+ ["Æ "]={ "O","Ì›" },
+ ["Æ¡"]={ "o","Ì›" },
+ ["Ư"]={ "U","̛" },
+ ["Æ°"]={ "u","Ì›" },
+ ["Ç"]={ "A","ÌŒ" },
+ ["ǎ"]={ "a","̌" },
+ ["Ç"]={ "I","ÌŒ" },
+ ["Ç"]={ "i","ÌŒ" },
+ ["Ǒ"]={ "O","̌" },
+ ["ǒ"]={ "o","̌" },
+ ["Ǔ"]={ "U","̌" },
+ ["ǔ"]={ "u","̌" },
+ ["Ǖ"]={ "Ü","̄" },
+ ["ǖ"]={ "ü","̄" },
+ ["Ç—"]={ "Ãœ","Ì" },
+ ["ǘ"]={ "ü","Ì" },
+ ["Ǚ"]={ "Ü","̌" },
+ ["ǚ"]={ "ü","̌" },
+ ["Ǜ"]={ "Ü","̀" },
+ ["ǜ"]={ "ü","̀" },
+ ["Ǟ"]={ "Ä","̄" },
+ ["ǟ"]={ "ä","̄" },
+ ["Ǡ"]={ "Ȧ","̄" },
+ ["ǡ"]={ "ȧ","̄" },
+ ["Ǣ"]={ "Æ","̄" },
+ ["ǣ"]={ "æ","̄" },
+ ["Ǧ"]={ "G","̌" },
+ ["ǧ"]={ "g","̌" },
+ ["Ǩ"]={ "K","̌" },
+ ["ǩ"]={ "k","̌" },
+ ["Ǫ"]={ "O","̨" },
+ ["ǫ"]={ "o","̨" },
+ ["Ǭ"]={ "Ǫ","̄" },
+ ["Ç­"]={ "Ç«","Ì„" },
+ ["Ǯ"]={ "Ʒ","̌" },
+ ["ǯ"]={ "ʒ","̌" },
+ ["ǰ"]={ "j","̌" },
+ ["Ç´"]={ "G","Ì" },
+ ["ǵ"]={ "g","Ì" },
+ ["Ǹ"]={ "N","̀" },
+ ["ǹ"]={ "n","̀" },
+ ["Ǻ"]={ "Ã…","Ì" },
+ ["Ç»"]={ "Ã¥","Ì" },
+ ["Ǽ"]={ "Æ","Ì" },
+ ["ǽ"]={ "æ","Ì" },
+ ["Ǿ"]={ "Ø","Ì" },
+ ["Ç¿"]={ "ø","Ì" },
+ ["È€"]={ "A","Ì" },
+ ["È"]={ "a","Ì" },
+ ["È‚"]={ "A","Ì‘" },
+ ["ȃ"]={ "a","̑" },
+ ["È„"]={ "E","Ì" },
+ ["È…"]={ "e","Ì" },
+ ["Ȇ"]={ "E","̑" },
+ ["ȇ"]={ "e","̑" },
+ ["Ȉ"]={ "I","Ì" },
+ ["ȉ"]={ "i","Ì" },
+ ["ÈŠ"]={ "I","Ì‘" },
+ ["È‹"]={ "i","Ì‘" },
+ ["ÈŒ"]={ "O","Ì" },
+ ["È"]={ "o","Ì" },
+ ["ÈŽ"]={ "O","Ì‘" },
+ ["È"]={ "o","Ì‘" },
+ ["È"]={ "R","Ì" },
+ ["È‘"]={ "r","Ì" },
+ ["È’"]={ "R","Ì‘" },
+ ["È“"]={ "r","Ì‘" },
+ ["È”"]={ "U","Ì" },
+ ["È•"]={ "u","Ì" },
+ ["È–"]={ "U","Ì‘" },
+ ["È—"]={ "u","Ì‘" },
+ ["Ș"]={ "S","̦" },
+ ["ș"]={ "s","̦" },
+ ["Ț"]={ "T","̦" },
+ ["ț"]={ "t","̦" },
+ ["Ȟ"]={ "H","̌" },
+ ["ȟ"]={ "h","̌" },
+ ["Ȧ"]={ "A","̇" },
+ ["ȧ"]={ "a","̇" },
+ ["Ȩ"]={ "E","̧" },
+ ["ȩ"]={ "e","̧" },
+ ["Ȫ"]={ "Ö","̄" },
+ ["ȫ"]={ "ö","̄" },
+ ["Ȭ"]={ "Õ","̄" },
+ ["ȭ"]={ "õ","̄" },
+ ["Ȯ"]={ "O","̇" },
+ ["ȯ"]={ "o","̇" },
+ ["È°"]={ "È®","Ì„" },
+ ["ȱ"]={ "ȯ","̄" },
+ ["Ȳ"]={ "Y","̄" },
+ ["ȳ"]={ "y","̄" },
+ ["Í„"]={ "̈","Ì" },
+ ["Î…"]={ "¨","Ì" },
+ ["Ά"]={ "Α","Ì" },
+ ["Έ"]={ "Ε","Ì" },
+ ["Ή"]={ "Η","Ì" },
+ ["Ί"]={ "Ι","Ì" },
+ ["ÎŒ"]={ "Ο","Ì" },
+ ["ÎŽ"]={ "Î¥","Ì" },
+ ["Î"]={ "Ω","Ì" },
+ ["Î"]={ "ÏŠ","Ì" },
+ ["Ϊ"]={ "Ι","̈" },
+ ["Ϋ"]={ "Υ","̈" },
+ ["ά"]={ "α","Ì" },
+ ["έ"]={ "ε","Ì" },
+ ["ή"]={ "η","Ì" },
+ ["ί"]={ "ι","Ì" },
+ ["ΰ"]={ "Ï‹","Ì" },
+ ["ϊ"]={ "ι","̈" },
+ ["ϋ"]={ "υ","̈" },
+ ["ÏŒ"]={ "ο","Ì" },
+ ["Ï"]={ "Ï…","Ì" },
+ ["ÏŽ"]={ "ω","Ì" },
+ ["Ï“"]={ "Ï’","Ì" },
+ ["ϔ"]={ "ϒ","̈" },
+ ["Ѐ"]={ "Е","̀" },
+ ["Ð"]={ "Е","̈" },
+ ["Ѓ"]={ "Г","Ì" },
+ ["Ї"]={ "І","̈" },
+ ["ÐŒ"]={ "К","Ì" },
+ ["Ð"]={ "И","Ì€" },
+ ["Ў"]={ "У","̆" },
+ ["Й"]={ "И","̆" },
+ ["й"]={ "и","̆" },
+ ["Ñ"]={ "е","Ì€" },
+ ["ё"]={ "е","̈" },
+ ["Ñ“"]={ "г","Ì" },
+ ["ї"]={ "і","̈" },
+ ["Ñœ"]={ "к","Ì" },
+ ["Ñ"]={ "и","Ì€" },
+ ["ў"]={ "у","̆" },
+ ["Ѷ"]={ "Ñ´","Ì" },
+ ["Ñ·"]={ "ѵ","Ì" },
+ ["Ó"]={ "Ж","̆" },
+ ["ӂ"]={ "ж","̆" },
+ ["Ó"]={ "Ð","̆" },
+ ["ӑ"]={ "а","̆" },
+ ["Ó’"]={ "Ð","̈" },
+ ["ӓ"]={ "а","̈" },
+ ["Ӗ"]={ "Е","̆" },
+ ["ӗ"]={ "е","̆" },
+ ["Ӛ"]={ "Ә","̈" },
+ ["ӛ"]={ "ә","̈" },
+ ["Ӝ"]={ "Ж","̈" },
+ ["Ó"]={ "ж","̈" },
+ ["Ӟ"]={ "З","̈" },
+ ["ӟ"]={ "з","̈" },
+ ["Ӣ"]={ "И","̄" },
+ ["ӣ"]={ "и","̄" },
+ ["Ӥ"]={ "И","̈" },
+ ["ӥ"]={ "и","̈" },
+ ["Ӧ"]={ "О","̈" },
+ ["ӧ"]={ "о","̈" },
+ ["Ӫ"]={ "Ө","̈" },
+ ["ӫ"]={ "ө","̈" },
+ ["Ӭ"]={ "Э","̈" },
+ ["Ó­"]={ "Ñ","̈" },
+ ["Ӯ"]={ "У","̄" },
+ ["ӯ"]={ "у","̄" },
+ ["Ӱ"]={ "У","̈" },
+ ["ӱ"]={ "у","̈" },
+ ["Ӳ"]={ "У","̋" },
+ ["ӳ"]={ "у","̋" },
+ ["Ӵ"]={ "Ч","̈" },
+ ["ӵ"]={ "ч","̈" },
+ ["Ӹ"]={ "Ы","̈" },
+ ["ӹ"]={ "ы","̈" },
+ ["آ"]={ "ا","ٓ" },
+ ["أ"]={ "ا","ٔ" },
+ ["ؤ"]={ "و","ٔ" },
+ ["إ"]={ "ا","ٕ" },
+ ["ئ"]={ "ي","ٔ" },
+ ["Û€"]={ "Û•","Ù”" },
+ ["Û‚"]={ "Û","Ù”" },
+ ["Û“"]={ "Û’","Ù”" },
+ ["ऩ"]={ "न","़" },
+ ["ऱ"]={ "र","़" },
+ ["ऴ"]={ "ळ","़" },
+ ["क़"]={ "क","़" },
+ ["ख़"]={ "ख","़" },
+ ["ग़"]={ "ग","़" },
+ ["ज़"]={ "ज","़" },
+ ["ड़"]={ "ड","़" },
+ ["à¥"]={ "ढ","़" },
+ ["फ़"]={ "फ","़" },
+ ["य़"]={ "य","़" },
+ ["ো"]={ "ে","া" },
+ ["ৌ"]={ "ে","ৗ" },
+ ["ড়"]={ "ড","়" },
+ ["à§"]={ "ঢ","়" },
+ ["য়"]={ "য","়" },
+ ["ਲ਼"]={ "ਲ","਼" },
+ ["ਸ਼"]={ "ਸ","਼" },
+ ["ਖ਼"]={ "ਖ","਼" },
+ ["ਗ਼"]={ "ਗ","਼" },
+ ["ਜ਼"]={ "ਜ","਼" },
+ ["ਫ਼"]={ "ਫ","਼" },
+ ["à­ˆ"]={ "à­‡","à­–" },
+ ["ୋ"]={ "େ","ା" },
+ ["ୌ"]={ "େ","ୗ" },
+ ["ଡ଼"]={ "ଡ","଼" },
+ ["à­"]={ "ଢ","଼" },
+ ["ஔ"]={ "ஒ","ௗ" },
+ ["ொ"]={ "ெ","ா" },
+ ["ோ"]={ "ே","ா" },
+ ["ௌ"]={ "ெ","ௗ" },
+ ["ై"]={ "ె","ౖ" },
+ ["ೀ"]={ "ಿ","ೕ" },
+ ["ೇ"]={ "ೆ","ೕ" },
+ ["ೈ"]={ "ೆ","ೖ" },
+ ["ೊ"]={ "ೆ","ೂ" },
+ ["ೋ"]={ "ೊ","ೕ" },
+ ["ൊ"]={ "െ","ാ" },
+ ["ോ"]={ "േ","ാ" },
+ ["ൌ"]={ "െ","ൗ" },
+ ["à·š"]={ "à·™","à·Š" },
+ ["à·œ"]={ "à·™","à·" },
+ ["à·"]={ "à·œ","à·Š" },
+ ["à·ž"]={ "à·™","à·Ÿ" },
+ ["གྷ"]={ "ག","ྷ" },
+ ["à½"]={ "ཌ","ྷ" },
+ ["དྷ"]={ "ད","ྷ" },
+ ["བྷ"]={ "བ","ྷ" },
+ ["ཛྷ"]={ "ཛ","ྷ" },
+ ["ཀྵ"]={ "ཀ","ྵ" },
+ ["ཱི"]={ "ཱ","ི" },
+ ["ཱུ"]={ "ཱ","ུ" },
+ ["ྲྀ"]={ "ྲ","ྀ" },
+ ["ླྀ"]={ "ླ","ྀ" },
+ ["à¾"]={ "ཱ","ྀ" },
+ ["ྒྷ"]={ "ྒ","ྷ" },
+ ["à¾"]={ "ྜ","ྷ" },
+ ["ྡྷ"]={ "ྡ","ྷ" },
+ ["ྦྷ"]={ "ྦ","ྷ" },
+ ["ྫྷ"]={ "ྫ","ྷ" },
+ ["ྐྵ"]={ "à¾","ྵ" },
+ ["ဦ"]={ "ဥ","ီ" },
+ ["ᬆ"]={ "ᬅ","ᬵ" },
+ ["ᬈ"]={ "ᬇ","ᬵ" },
+ ["ᬊ"]={ "ᬉ","ᬵ" },
+ ["ᬌ"]={ "ᬋ","ᬵ" },
+ ["ᬎ"]={ "á¬","ᬵ" },
+ ["ᬒ"]={ "ᬑ","ᬵ" },
+ ["ᬻ"]={ "ᬺ","ᬵ" },
+ ["ᬽ"]={ "ᬼ","ᬵ" },
+ ["ᭀ"]={ "ᬾ","ᬵ" },
+ ["á­"]={ "ᬿ","ᬵ" },
+ ["ᭃ"]={ "ᭂ","ᬵ" },
+ ["Ḁ"]={ "A","̥" },
+ ["á¸"]={ "a","Ì¥" },
+ ["Ḃ"]={ "B","̇" },
+ ["ḃ"]={ "b","̇" },
+ ["Ḅ"]={ "B","̣" },
+ ["ḅ"]={ "b","̣" },
+ ["Ḇ"]={ "B","̱" },
+ ["ḇ"]={ "b","̱" },
+ ["Ḉ"]={ "Ç","Ì" },
+ ["ḉ"]={ "ç","Ì" },
+ ["Ḋ"]={ "D","̇" },
+ ["ḋ"]={ "d","̇" },
+ ["Ḍ"]={ "D","̣" },
+ ["á¸"]={ "d","Ì£" },
+ ["Ḏ"]={ "D","̱" },
+ ["á¸"]={ "d","̱" },
+ ["á¸"]={ "D","̧" },
+ ["ḑ"]={ "d","̧" },
+ ["Ḓ"]={ "D","̭" },
+ ["ḓ"]={ "d","̭" },
+ ["Ḕ"]={ "Ē","̀" },
+ ["ḕ"]={ "ē","̀" },
+ ["Ḗ"]={ "Ä’","Ì" },
+ ["ḗ"]={ "Ä“","Ì" },
+ ["Ḙ"]={ "E","̭" },
+ ["ḙ"]={ "e","̭" },
+ ["Ḛ"]={ "E","̰" },
+ ["ḛ"]={ "e","̰" },
+ ["Ḝ"]={ "Ȩ","̆" },
+ ["á¸"]={ "È©","̆" },
+ ["Ḟ"]={ "F","̇" },
+ ["ḟ"]={ "f","̇" },
+ ["Ḡ"]={ "G","̄" },
+ ["ḡ"]={ "g","̄" },
+ ["Ḣ"]={ "H","̇" },
+ ["ḣ"]={ "h","̇" },
+ ["Ḥ"]={ "H","̣" },
+ ["ḥ"]={ "h","̣" },
+ ["Ḧ"]={ "H","̈" },
+ ["ḧ"]={ "h","̈" },
+ ["Ḩ"]={ "H","̧" },
+ ["ḩ"]={ "h","̧" },
+ ["Ḫ"]={ "H","̮" },
+ ["ḫ"]={ "h","̮" },
+ ["Ḭ"]={ "I","̰" },
+ ["ḭ"]={ "i","̰" },
+ ["Ḯ"]={ "Ã","Ì" },
+ ["ḯ"]={ "ï","Ì" },
+ ["Ḱ"]={ "K","Ì" },
+ ["ḱ"]={ "k","Ì" },
+ ["Ḳ"]={ "K","̣" },
+ ["ḳ"]={ "k","̣" },
+ ["Ḵ"]={ "K","̱" },
+ ["ḵ"]={ "k","̱" },
+ ["Ḷ"]={ "L","̣" },
+ ["ḷ"]={ "l","̣" },
+ ["Ḹ"]={ "Ḷ","̄" },
+ ["ḹ"]={ "ḷ","̄" },
+ ["Ḻ"]={ "L","̱" },
+ ["ḻ"]={ "l","̱" },
+ ["Ḽ"]={ "L","̭" },
+ ["ḽ"]={ "l","̭" },
+ ["Ḿ"]={ "M","Ì" },
+ ["ḿ"]={ "m","Ì" },
+ ["Ṁ"]={ "M","̇" },
+ ["á¹"]={ "m","̇" },
+ ["Ṃ"]={ "M","̣" },
+ ["ṃ"]={ "m","̣" },
+ ["Ṅ"]={ "N","̇" },
+ ["ṅ"]={ "n","̇" },
+ ["Ṇ"]={ "N","̣" },
+ ["ṇ"]={ "n","̣" },
+ ["Ṉ"]={ "N","̱" },
+ ["ṉ"]={ "n","̱" },
+ ["Ṋ"]={ "N","̭" },
+ ["ṋ"]={ "n","̭" },
+ ["Ṍ"]={ "Õ","Ì" },
+ ["á¹"]={ "õ","Ì" },
+ ["Ṏ"]={ "Õ","̈" },
+ ["á¹"]={ "õ","̈" },
+ ["á¹"]={ "ÅŒ","Ì€" },
+ ["ṑ"]={ "Å","Ì€" },
+ ["á¹’"]={ "ÅŒ","Ì" },
+ ["ṓ"]={ "Å","Ì" },
+ ["á¹”"]={ "P","Ì" },
+ ["ṕ"]={ "p","Ì" },
+ ["Ṗ"]={ "P","̇" },
+ ["ṗ"]={ "p","̇" },
+ ["Ṙ"]={ "R","̇" },
+ ["ṙ"]={ "r","̇" },
+ ["Ṛ"]={ "R","̣" },
+ ["á¹›"]={ "r","Ì£" },
+ ["Ṝ"]={ "Ṛ","̄" },
+ ["á¹"]={ "á¹›","Ì„" },
+ ["Ṟ"]={ "R","̱" },
+ ["ṟ"]={ "r","̱" },
+ ["Ṡ"]={ "S","̇" },
+ ["ṡ"]={ "s","̇" },
+ ["á¹¢"]={ "S","Ì£" },
+ ["á¹£"]={ "s","Ì£" },
+ ["Ṥ"]={ "Ś","̇" },
+ ["ṥ"]={ "ś","̇" },
+ ["Ṧ"]={ "Š","̇" },
+ ["ṧ"]={ "š","̇" },
+ ["Ṩ"]={ "Ṣ","̇" },
+ ["ṩ"]={ "ṣ","̇" },
+ ["Ṫ"]={ "T","̇" },
+ ["ṫ"]={ "t","̇" },
+ ["Ṭ"]={ "T","̣" },
+ ["á¹­"]={ "t","Ì£" },
+ ["Ṯ"]={ "T","̱" },
+ ["ṯ"]={ "t","̱" },
+ ["á¹°"]={ "T","Ì­" },
+ ["á¹±"]={ "t","Ì­" },
+ ["Ṳ"]={ "U","̤" },
+ ["ṳ"]={ "u","̤" },
+ ["á¹´"]={ "U","Ì°" },
+ ["á¹µ"]={ "u","Ì°" },
+ ["Ṷ"]={ "U","̭" },
+ ["á¹·"]={ "u","Ì­" },
+ ["Ṹ"]={ "Ũ","Ì" },
+ ["á¹¹"]={ "Å©","Ì" },
+ ["Ṻ"]={ "Ū","̈" },
+ ["ṻ"]={ "ū","̈" },
+ ["Ṽ"]={ "V","̃" },
+ ["ṽ"]={ "v","̃" },
+ ["á¹¾"]={ "V","Ì£" },
+ ["ṿ"]={ "v","̣" },
+ ["Ẁ"]={ "W","̀" },
+ ["áº"]={ "w","Ì€" },
+ ["Ẃ"]={ "W","Ì" },
+ ["ẃ"]={ "w","Ì" },
+ ["Ẅ"]={ "W","̈" },
+ ["ẅ"]={ "w","̈" },
+ ["Ẇ"]={ "W","̇" },
+ ["ẇ"]={ "w","̇" },
+ ["Ẉ"]={ "W","̣" },
+ ["ẉ"]={ "w","̣" },
+ ["Ẋ"]={ "X","̇" },
+ ["ẋ"]={ "x","̇" },
+ ["Ẍ"]={ "X","̈" },
+ ["áº"]={ "x","̈" },
+ ["Ẏ"]={ "Y","̇" },
+ ["áº"]={ "y","̇" },
+ ["áº"]={ "Z","Ì‚" },
+ ["ẑ"]={ "z","̂" },
+ ["Ẓ"]={ "Z","̣" },
+ ["ẓ"]={ "z","̣" },
+ ["Ẕ"]={ "Z","̱" },
+ ["ẕ"]={ "z","̱" },
+ ["ẖ"]={ "h","̱" },
+ ["ẗ"]={ "t","̈" },
+ ["ẘ"]={ "w","̊" },
+ ["ẙ"]={ "y","̊" },
+ ["ẛ"]={ "ſ","̇" },
+ ["Ạ"]={ "A","̣" },
+ ["ạ"]={ "a","̣" },
+ ["Ả"]={ "A","̉" },
+ ["ả"]={ "a","̉" },
+ ["Ấ"]={ "Â","Ì" },
+ ["ấ"]={ "â","Ì" },
+ ["Ầ"]={ "Â","̀" },
+ ["ầ"]={ "â","̀" },
+ ["Ẩ"]={ "Â","̉" },
+ ["ẩ"]={ "â","̉" },
+ ["Ẫ"]={ "Â","̃" },
+ ["ẫ"]={ "â","̃" },
+ ["Ậ"]={ "Ạ","̂" },
+ ["ậ"]={ "ạ","̂" },
+ ["Ắ"]={ "Ä‚","Ì" },
+ ["ắ"]={ "ă","Ì" },
+ ["Ằ"]={ "Ă","̀" },
+ ["ằ"]={ "ă","̀" },
+ ["Ẳ"]={ "Ă","̉" },
+ ["ẳ"]={ "ă","̉" },
+ ["Ẵ"]={ "Ă","̃" },
+ ["ẵ"]={ "ă","̃" },
+ ["Ặ"]={ "Ạ","̆" },
+ ["ặ"]={ "ạ","̆" },
+ ["Ẹ"]={ "E","̣" },
+ ["ẹ"]={ "e","̣" },
+ ["Ẻ"]={ "E","̉" },
+ ["ẻ"]={ "e","̉" },
+ ["Ẽ"]={ "E","̃" },
+ ["ẽ"]={ "e","̃" },
+ ["Ế"]={ "Ê","Ì" },
+ ["ế"]={ "ê","Ì" },
+ ["Ề"]={ "Ê","̀" },
+ ["á»"]={ "ê","Ì€" },
+ ["Ể"]={ "Ê","̉" },
+ ["ể"]={ "ê","̉" },
+ ["Ễ"]={ "Ê","̃" },
+ ["ễ"]={ "ê","̃" },
+ ["Ệ"]={ "Ẹ","̂" },
+ ["ệ"]={ "ẹ","̂" },
+ ["Ỉ"]={ "I","̉" },
+ ["ỉ"]={ "i","̉" },
+ ["Ị"]={ "I","̣" },
+ ["ị"]={ "i","̣" },
+ ["Ọ"]={ "O","̣" },
+ ["á»"]={ "o","Ì£" },
+ ["Ỏ"]={ "O","̉" },
+ ["á»"]={ "o","̉" },
+ ["á»"]={ "Ô","Ì" },
+ ["ố"]={ "ô","Ì" },
+ ["Ồ"]={ "Ô","̀" },
+ ["ồ"]={ "ô","̀" },
+ ["Ổ"]={ "Ô","̉" },
+ ["ổ"]={ "ô","̉" },
+ ["Ỗ"]={ "Ô","̃" },
+ ["ỗ"]={ "ô","̃" },
+ ["Ộ"]={ "Ọ","̂" },
+ ["á»™"]={ "á»","Ì‚" },
+ ["Ớ"]={ "Æ ","Ì" },
+ ["á»›"]={ "Æ¡","Ì" },
+ ["Ờ"]={ "Ơ","̀" },
+ ["á»"]={ "Æ¡","Ì€" },
+ ["Ở"]={ "Ơ","̉" },
+ ["ở"]={ "ơ","̉" },
+ ["Ỡ"]={ "Ơ","̃" },
+ ["ỡ"]={ "ơ","̃" },
+ ["Ợ"]={ "Ơ","̣" },
+ ["ợ"]={ "ơ","̣" },
+ ["Ụ"]={ "U","̣" },
+ ["ụ"]={ "u","̣" },
+ ["Ủ"]={ "U","̉" },
+ ["ủ"]={ "u","̉" },
+ ["Ứ"]={ "Ư","Ì" },
+ ["ứ"]={ "Æ°","Ì" },
+ ["Ừ"]={ "Ư","̀" },
+ ["ừ"]={ "ư","̀" },
+ ["Ử"]={ "Ư","̉" },
+ ["ử"]={ "ư","̉" },
+ ["Ữ"]={ "Ư","̃" },
+ ["ữ"]={ "ư","̃" },
+ ["Ự"]={ "Ư","̣" },
+ ["á»±"]={ "Æ°","Ì£" },
+ ["Ỳ"]={ "Y","̀" },
+ ["ỳ"]={ "y","̀" },
+ ["á»´"]={ "Y","Ì£" },
+ ["ỵ"]={ "y","̣" },
+ ["Ỷ"]={ "Y","̉" },
+ ["ỷ"]={ "y","̉" },
+ ["Ỹ"]={ "Y","̃" },
+ ["ỹ"]={ "y","̃" },
+ ["ἀ"]={ "α","̓" },
+ ["á¼"]={ "α","Ì”" },
+ ["ἂ"]={ "ἀ","̀" },
+ ["ἃ"]={ "á¼","Ì€" },
+ ["ἄ"]={ "á¼€","Ì" },
+ ["á¼…"]={ "á¼","Ì" },
+ ["ἆ"]={ "ἀ","͂" },
+ ["ἇ"]={ "á¼","Í‚" },
+ ["Ἀ"]={ "Α","̓" },
+ ["Ἁ"]={ "Α","̔" },
+ ["Ἂ"]={ "Ἀ","̀" },
+ ["Ἃ"]={ "Ἁ","̀" },
+ ["Ἄ"]={ "Ἀ","Ì" },
+ ["á¼"]={ "Ἁ","Ì" },
+ ["Ἆ"]={ "Ἀ","͂" },
+ ["á¼"]={ "Ἁ","Í‚" },
+ ["á¼"]={ "ε","Ì“" },
+ ["ἑ"]={ "ε","̔" },
+ ["á¼’"]={ "á¼","Ì€" },
+ ["ἓ"]={ "ἑ","̀" },
+ ["á¼”"]={ "á¼","Ì" },
+ ["ἕ"]={ "ἑ","Ì" },
+ ["Ἐ"]={ "Ε","̓" },
+ ["Ἑ"]={ "Ε","̔" },
+ ["Ἒ"]={ "Ἐ","̀" },
+ ["á¼›"]={ "á¼™","Ì€" },
+ ["Ἔ"]={ "Ἐ","Ì" },
+ ["á¼"]={ "á¼™","Ì" },
+ ["ἠ"]={ "η","̓" },
+ ["ἡ"]={ "η","̔" },
+ ["á¼¢"]={ "á¼ ","Ì€" },
+ ["ἣ"]={ "ἡ","̀" },
+ ["ἤ"]={ "á¼ ","Ì" },
+ ["á¼¥"]={ "ἡ","Ì" },
+ ["ἦ"]={ "ἠ","͂" },
+ ["ἧ"]={ "ἡ","͂" },
+ ["Ἠ"]={ "Η","̓" },
+ ["Ἡ"]={ "Η","̔" },
+ ["Ἢ"]={ "Ἠ","̀" },
+ ["Ἣ"]={ "Ἡ","̀" },
+ ["Ἤ"]={ "Ἠ","Ì" },
+ ["á¼­"]={ "Ἡ","Ì" },
+ ["Ἦ"]={ "Ἠ","͂" },
+ ["Ἧ"]={ "Ἡ","͂" },
+ ["ἰ"]={ "ι","̓" },
+ ["ἱ"]={ "ι","̔" },
+ ["á¼²"]={ "á¼°","Ì€" },
+ ["á¼³"]={ "á¼±","Ì€" },
+ ["á¼´"]={ "á¼°","Ì" },
+ ["á¼µ"]={ "á¼±","Ì" },
+ ["ἶ"]={ "ἰ","͂" },
+ ["á¼·"]={ "á¼±","Í‚" },
+ ["Ἰ"]={ "Ι","̓" },
+ ["Ἱ"]={ "Ι","̔" },
+ ["Ἲ"]={ "Ἰ","̀" },
+ ["á¼»"]={ "á¼¹","Ì€" },
+ ["á¼¼"]={ "Ἰ","Ì" },
+ ["á¼½"]={ "á¼¹","Ì" },
+ ["Ἶ"]={ "Ἰ","͂" },
+ ["Ἷ"]={ "Ἱ","͂" },
+ ["ὀ"]={ "ο","̓" },
+ ["á½"]={ "ο","Ì”" },
+ ["ὂ"]={ "ὀ","̀" },
+ ["ὃ"]={ "á½","Ì€" },
+ ["ὄ"]={ "á½€","Ì" },
+ ["á½…"]={ "á½","Ì" },
+ ["Ὀ"]={ "Ο","̓" },
+ ["Ὁ"]={ "Ο","̔" },
+ ["Ὂ"]={ "Ὀ","̀" },
+ ["Ὃ"]={ "Ὁ","̀" },
+ ["Ὄ"]={ "Ὀ","Ì" },
+ ["á½"]={ "Ὁ","Ì" },
+ ["á½"]={ "Ï…","Ì“" },
+ ["ὑ"]={ "υ","̔" },
+ ["á½’"]={ "á½","Ì€" },
+ ["ὓ"]={ "ὑ","̀" },
+ ["á½”"]={ "á½","Ì" },
+ ["ὕ"]={ "ὑ","Ì" },
+ ["á½–"]={ "á½","Í‚" },
+ ["ὗ"]={ "ὑ","͂" },
+ ["á½™"]={ "Î¥","Ì”" },
+ ["á½›"]={ "á½™","Ì€" },
+ ["á½"]={ "á½™","Ì" },
+ ["Ὗ"]={ "Ὑ","͂" },
+ ["ὠ"]={ "ω","̓" },
+ ["ὡ"]={ "ω","̔" },
+ ["á½¢"]={ "á½ ","Ì€" },
+ ["ὣ"]={ "ὡ","̀" },
+ ["ὤ"]={ "á½ ","Ì" },
+ ["á½¥"]={ "ὡ","Ì" },
+ ["ὦ"]={ "ὠ","͂" },
+ ["ὧ"]={ "ὡ","͂" },
+ ["Ὠ"]={ "Ω","̓" },
+ ["Ὡ"]={ "Ω","̔" },
+ ["Ὢ"]={ "Ὠ","̀" },
+ ["Ὣ"]={ "Ὡ","̀" },
+ ["Ὤ"]={ "Ὠ","Ì" },
+ ["á½­"]={ "Ὡ","Ì" },
+ ["Ὦ"]={ "Ὠ","͂" },
+ ["Ὧ"]={ "Ὡ","͂" },
+ ["ὰ"]={ "α","̀" },
+ ["ὲ"]={ "ε","̀" },
+ ["ὴ"]={ "η","̀" },
+ ["ὶ"]={ "ι","̀" },
+ ["ὸ"]={ "ο","̀" },
+ ["ὺ"]={ "υ","̀" },
+ ["ὼ"]={ "ω","̀" },
+ ["á¾€"]={ "á¼€","Í…" },
+ ["á¾"]={ "á¼","Í…" },
+ ["ᾂ"]={ "ἂ","ͅ" },
+ ["ᾃ"]={ "ἃ","ͅ" },
+ ["ᾄ"]={ "ἄ","ͅ" },
+ ["á¾…"]={ "á¼…","Í…" },
+ ["ᾆ"]={ "ἆ","ͅ" },
+ ["ᾇ"]={ "ἇ","ͅ" },
+ ["ᾈ"]={ "Ἀ","ͅ" },
+ ["ᾉ"]={ "Ἁ","ͅ" },
+ ["ᾊ"]={ "Ἂ","ͅ" },
+ ["ᾋ"]={ "Ἃ","ͅ" },
+ ["ᾌ"]={ "Ἄ","ͅ" },
+ ["á¾"]={ "á¼","Í…" },
+ ["ᾎ"]={ "Ἆ","ͅ" },
+ ["á¾"]={ "á¼","Í…" },
+ ["á¾"]={ "á¼ ","Í…" },
+ ["ᾑ"]={ "ἡ","ͅ" },
+ ["á¾’"]={ "á¼¢","Í…" },
+ ["ᾓ"]={ "ἣ","ͅ" },
+ ["ᾔ"]={ "ἤ","ͅ" },
+ ["ᾕ"]={ "ἥ","ͅ" },
+ ["ᾖ"]={ "ἦ","ͅ" },
+ ["ᾗ"]={ "ἧ","ͅ" },
+ ["ᾘ"]={ "Ἠ","ͅ" },
+ ["ᾙ"]={ "Ἡ","ͅ" },
+ ["ᾚ"]={ "Ἢ","ͅ" },
+ ["ᾛ"]={ "Ἣ","ͅ" },
+ ["ᾜ"]={ "Ἤ","ͅ" },
+ ["á¾"]={ "á¼­","Í…" },
+ ["ᾞ"]={ "Ἦ","ͅ" },
+ ["ᾟ"]={ "Ἧ","ͅ" },
+ ["á¾ "]={ "á½ ","Í…" },
+ ["ᾡ"]={ "ὡ","ͅ" },
+ ["á¾¢"]={ "á½¢","Í…" },
+ ["á¾£"]={ "á½£","Í…" },
+ ["ᾤ"]={ "ὤ","ͅ" },
+ ["á¾¥"]={ "á½¥","Í…" },
+ ["ᾦ"]={ "ὦ","ͅ" },
+ ["ᾧ"]={ "ὧ","ͅ" },
+ ["ᾨ"]={ "Ὠ","ͅ" },
+ ["ᾩ"]={ "Ὡ","ͅ" },
+ ["ᾪ"]={ "Ὢ","ͅ" },
+ ["ᾫ"]={ "Ὣ","ͅ" },
+ ["ᾬ"]={ "Ὤ","ͅ" },
+ ["á¾­"]={ "á½­","Í…" },
+ ["á¾®"]={ "á½®","Í…" },
+ ["ᾯ"]={ "Ὧ","ͅ" },
+ ["ᾰ"]={ "α","̆" },
+ ["ᾱ"]={ "α","̄" },
+ ["á¾²"]={ "á½°","Í…" },
+ ["ᾳ"]={ "α","ͅ" },
+ ["ᾴ"]={ "ά","ͅ" },
+ ["ᾶ"]={ "α","͂" },
+ ["ᾷ"]={ "ᾶ","ͅ" },
+ ["Ᾰ"]={ "Α","̆" },
+ ["Ᾱ"]={ "Α","̄" },
+ ["Ὰ"]={ "Α","̀" },
+ ["ᾼ"]={ "Α","ͅ" },
+ ["á¿"]={ "¨","Í‚" },
+ ["á¿‚"]={ "á½´","Í…" },
+ ["ῃ"]={ "η","ͅ" },
+ ["ῄ"]={ "ή","ͅ" },
+ ["ῆ"]={ "η","͂" },
+ ["ῇ"]={ "ῆ","ͅ" },
+ ["Ὲ"]={ "Ε","̀" },
+ ["Ὴ"]={ "Η","̀" },
+ ["ῌ"]={ "Η","ͅ" },
+ ["á¿"]={ "᾿","Ì€" },
+ ["á¿Ž"]={ "᾿","Ì" },
+ ["á¿"]={ "᾿","Í‚" },
+ ["á¿"]={ "ι","̆" },
+ ["ῑ"]={ "ι","̄" },
+ ["á¿’"]={ "ÏŠ","Ì€" },
+ ["ῖ"]={ "ι","͂" },
+ ["á¿—"]={ "ÏŠ","Í‚" },
+ ["Ῐ"]={ "Ι","̆" },
+ ["Ῑ"]={ "Ι","̄" },
+ ["Ὶ"]={ "Ι","̀" },
+ ["á¿"]={ "῾","Ì€" },
+ ["á¿ž"]={ "῾","Ì" },
+ ["῟"]={ "῾","͂" },
+ ["ῠ"]={ "υ","̆" },
+ ["á¿¡"]={ "Ï…","Ì„" },
+ ["á¿¢"]={ "Ï‹","Ì€" },
+ ["ῤ"]={ "Ï","Ì“" },
+ ["á¿¥"]={ "Ï","Ì”" },
+ ["ῦ"]={ "υ","͂" },
+ ["ῧ"]={ "ϋ","͂" },
+ ["Ῠ"]={ "Υ","̆" },
+ ["á¿©"]={ "Î¥","Ì„" },
+ ["Ὺ"]={ "Υ","̀" },
+ ["Ῥ"]={ "Ρ","̔" },
+ ["῭"]={ "¨","̀" },
+ ["ῲ"]={ "ὼ","ͅ" },
+ ["ῳ"]={ "ω","ͅ" },
+ ["á¿´"]={ "ÏŽ","Í…" },
+ ["ῶ"]={ "ω","͂" },
+ ["ῷ"]={ "ῶ","ͅ" },
+ ["Ὸ"]={ "Ο","̀" },
+ ["Ὼ"]={ "Ω","̀" },
+ ["ῼ"]={ "Ω","ͅ" },
+ ["↚"]={ "â†","̸" },
+ ["↛"]={ "→","̸" },
+ ["↮"]={ "↔","̸" },
+ ["â‡"]={ "â‡","̸" },
+ ["⇎"]={ "⇔","̸" },
+ ["â‡"]={ "⇒","̸" },
+ ["∄"]={ "∃","̸" },
+ ["∉"]={ "∈","̸" },
+ ["∌"]={ "∋","̸" },
+ ["∤"]={ "∣","̸" },
+ ["∦"]={ "∥","̸" },
+ ["â‰"]={ "∼","̸" },
+ ["≄"]={ "≃","̸" },
+ ["≇"]={ "≅","̸" },
+ ["≉"]={ "≈","̸" },
+ ["≠"]={ "=","̸" },
+ ["≢"]={ "≡","̸" },
+ ["≭"]={ "â‰","̸" },
+ ["≮"]={ "<","̸" },
+ ["≯"]={ ">","̸" },
+ ["≰"]={ "≤","̸" },
+ ["≱"]={ "≥","̸" },
+ ["≴"]={ "≲","̸" },
+ ["≵"]={ "≳","̸" },
+ ["≸"]={ "≶","̸" },
+ ["≹"]={ "≷","̸" },
+ ["⊀"]={ "≺","̸" },
+ ["âŠ"]={ "≻","̸" },
+ ["⊄"]={ "⊂","̸" },
+ ["⊅"]={ "⊃","̸" },
+ ["⊈"]={ "⊆","̸" },
+ ["⊉"]={ "⊇","̸" },
+ ["⊬"]={ "⊢","̸" },
+ ["⊭"]={ "⊨","̸" },
+ ["⊮"]={ "⊩","̸" },
+ ["⊯"]={ "⊫","̸" },
+ ["⋠"]={ "≼","̸" },
+ ["⋡"]={ "≽","̸" },
+ ["⋢"]={ "⊑","̸" },
+ ["⋣"]={ "⊒","̸" },
+ ["⋪"]={ "⊲","̸" },
+ ["⋫"]={ "⊳","̸" },
+ ["⋬"]={ "⊴","̸" },
+ ["⋭"]={ "⊵","̸" },
+ ["â«œ"]={ "â«","̸" },
+ ["ãŒ"]={ "ã‹","ã‚™" },
+ ["ãŽ"]={ "ã","ã‚™" },
+ ["ã"]={ "ã","ã‚™" },
+ ["ã’"]={ "ã‘","ã‚™" },
+ ["ã”"]={ "ã“","ã‚™" },
+ ["ã–"]={ "ã•","ã‚™" },
+ ["ã˜"]={ "ã—","ã‚™" },
+ ["ãš"]={ "ã™","ã‚™" },
+ ["ãœ"]={ "ã›","ã‚™" },
+ ["ãž"]={ "ã","ã‚™" },
+ ["ã "]={ "ãŸ","ã‚™" },
+ ["ã¢"]={ "ã¡","ã‚™" },
+ ["ã¥"]={ "ã¤","ã‚™" },
+ ["ã§"]={ "ã¦","ã‚™" },
+ ["ã©"]={ "ã¨","ã‚™" },
+ ["ã°"]={ "ã¯","ã‚™" },
+ ["ã±"]={ "ã¯","ã‚š" },
+ ["ã³"]={ "ã²","ã‚™" },
+ ["ã´"]={ "ã²","ã‚š" },
+ ["ã¶"]={ "ãµ","ã‚™" },
+ ["ã·"]={ "ãµ","ã‚š" },
+ ["ã¹"]={ "ã¸","ã‚™" },
+ ["ãº"]={ "ã¸","ã‚š" },
+ ["ã¼"]={ "ã»","ã‚™" },
+ ["ã½"]={ "ã»","ã‚š" },
+ ["ã‚”"]={ "ã†","ã‚™" },
+ ["ã‚ž"]={ "ã‚","ã‚™" },
+ ["ガ"]={ "カ","゙" },
+ ["ã‚®"]={ "ã‚­","ã‚™" },
+ ["グ"]={ "ク","゙" },
+ ["ゲ"]={ "ケ","゙" },
+ ["ゴ"]={ "コ","゙" },
+ ["ザ"]={ "サ","゙" },
+ ["ジ"]={ "シ","゙" },
+ ["ズ"]={ "ス","゙" },
+ ["ゼ"]={ "セ","゙" },
+ ["ゾ"]={ "ソ","゙" },
+ ["ダ"]={ "タ","゙" },
+ ["ヂ"]={ "ãƒ","ã‚™" },
+ ["ヅ"]={ "ツ","゙" },
+ ["デ"]={ "テ","゙" },
+ ["ド"]={ "ト","゙" },
+ ["ãƒ"]={ "ãƒ","ã‚™" },
+ ["パ"]={ "ãƒ","ã‚š" },
+ ["ビ"]={ "ヒ","゙" },
+ ["ピ"]={ "ヒ","゚" },
+ ["ブ"]={ "フ","゙" },
+ ["プ"]={ "フ","゚" },
+ ["ベ"]={ "ヘ","゙" },
+ ["ペ"]={ "ヘ","゚" },
+ ["ボ"]={ "ホ","゙" },
+ ["ãƒ"]={ "ホ","ã‚š" },
+ ["ヴ"]={ "ウ","゙" },
+ ["ヷ"]={ "ワ","゙" },
+ ["ヸ"]={ "ヰ","゙" },
+ ["ヹ"]={ "ヱ","゙" },
+ ["ヺ"]={ "ヲ","゙" },
+ ["ヾ"]={ "ヽ","゙" },
+ ["ï¬"]={ "×™","Ö´" },
+ ["ײַ"]={ "ײ","ַ" },
+ ["שׁ"]={ "ש","×" },
+ ["שׂ"]={ "ש","ׂ" },
+ ["שּׁ"]={ "ï­‰","×" },
+ ["שּׂ"]={ "שּ","ׂ" },
+ ["אַ"]={ "×","Ö·" },
+ ["אָ"]={ "×","Ö¸" },
+ ["אּ"]={ "×","Ö¼" },
+ ["בּ"]={ "ב","ּ" },
+ ["גּ"]={ "ג","ּ" },
+ ["דּ"]={ "ד","ּ" },
+ ["הּ"]={ "ה","ּ" },
+ ["וּ"]={ "ו","ּ" },
+ ["זּ"]={ "ז","ּ" },
+ ["טּ"]={ "ט","ּ" },
+ ["יּ"]={ "י","ּ" },
+ ["ךּ"]={ "ך","ּ" },
+ ["כּ"]={ "כ","ּ" },
+ ["לּ"]={ "ל","ּ" },
+ ["מּ"]={ "מ","ּ" },
+ ["ï­€"]={ "× ","Ö¼" },
+ ["ï­"]={ "ס","Ö¼" },
+ ["ï­ƒ"]={ "×£","Ö¼" },
+ ["פּ"]={ "פ","ּ" },
+ ["צּ"]={ "צ","ּ" },
+ ["קּ"]={ "ק","ּ" },
+ ["רּ"]={ "ר","ּ" },
+ ["שּ"]={ "ש","ּ" },
+ ["תּ"]={ "ת","ּ" },
+ ["וֹ"]={ "ו","ֹ" },
+ ["בֿ"]={ "ב","ֿ" },
+ ["ï­"]={ "×›","Ö¿" },
+ ["פֿ"]={ "פ","ֿ" },
+ ["𑂚"]={ "𑂙","𑂺" },
+ ["𑂜"]={ "𑂛","𑂺" },
+ ["𑂫"]={ "𑂥","𑂺" },
+ ["𑄮"]={ "𑄱","𑄧" },
+ ["𑄯"]={ "𑄲","𑄧" },
+ ["ð‘‹"]={ "ð‘‡","𑌾" },
+ ["ð‘Œ"]={ "ð‘‡","ð‘—" },
+ ["ð‘’»"]={ "ð‘’¹","ð‘’º" },
+ ["ð‘’¼"]={ "ð‘’¹","ð‘’°" },
+ ["ð‘’¾"]={ "ð‘’¹","ð‘’½" },
+ ["ð‘–º"]={ "ð‘–¸","ð‘–¯" },
+ ["ð‘–»"]={ "ð‘–¹","ð‘–¯" },
+ ["ð…ž"]={ "ð…—","ð…¥" },
+ ["ð…Ÿ"]={ "ð…˜","ð…¥" },
+ ["ð… "]={ "ð…Ÿ","ð…®" },
+ ["ð…¡"]={ "ð…Ÿ","ð…¯" },
+ ["ð…¢"]={ "ð…Ÿ","ð…°" },
+ ["ð…£"]={ "ð…Ÿ","ð…±" },
+ ["ð…¤"]={ "ð…Ÿ","ð…²" },
+ ["ð†»"]={ "ð†¹","ð…¥" },
+ ["ð†¼"]={ "ð†º","ð…¥" },
+ ["ð†½"]={ "ð†»","ð…®" },
+ ["ð†¾"]={ "ð†¼","ð…®" },
+ ["ð†¿"]={ "ð†»","ð…¯" },
+ ["ð‡€"]={ "ð†¼","ð…¯" },
+ },
+ },
+ },
+ ["name"]="collapse",
+ ["prepend"]=true,
+ ["type"]="ligature",
+}
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-ligâ€] ---
+
+
+do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-gbn†d25472d54c4841db43a745764a63533e] ---
+
+if not modules then modules={} end modules ['luatex-fonts-gbn']={
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+ os.exit()
+end
+local next=next
+local fonts=fonts
+local nodes=nodes
+local nuts=nodes.nuts
+local traverse_id=nuts.traverse_id
+local flush_node=nuts.flush_node
+local glyph_code=nodes.nodecodes.glyph
+local disc_code=nodes.nodecodes.disc
+local tonode=nuts.tonode
+local tonut=nuts.tonut
+local getfont=nuts.getfont
+local getchar=nuts.getchar
+local getid=nuts.getid
+local getboth=nuts.getboth
+local getprev=nuts.getprev
+local getnext=nuts.getnext
+local getdisc=nuts.getdisc
+local setchar=nuts.setchar
+local setlink=nuts.setlink
+local setprev=nuts.setprev
+local n_ligaturing=node.ligaturing
+local n_kerning=node.kerning
+local d_ligaturing=nuts.ligaturing
+local d_kerning=nuts.kerning
+local basemodepass=true
+local function l_warning() logs.report("fonts","don't call 'node.ligaturing' directly") l_warning=nil end
+local function k_warning() logs.report("fonts","don't call 'node.kerning' directly") k_warning=nil end
+function node.ligaturing(...)
+ if basemodepass and l_warning then
+ l_warning()
+ end
+ return n_ligaturing(...)
+end
+function node.kerning(...)
+ if basemodepass and k_warning then
+ k_warning()
+ end
+ return n_kerning(...)
+end
+function nuts.ligaturing(...)
+ if basemodepass and l_warning then
+ l_warning()
+ end
+ return d_ligaturing(...)
+end
+function nuts.kerning(...)
+ if basemodepass and k_warning then
+ k_warning()
+ end
+ return d_kerning(...)
+end
+function nodes.handlers.setbasemodepass(v)
+ basemodepass=v
+end
+local function nodepass(head,groupcode,size,packtype,direction)
+ local fontdata=fonts.hashes.identifiers
+ if fontdata then
+ local usedfonts={}
+ local basefonts={}
+ local prevfont=nil
+ local basefont=nil
+ local variants=nil
+ local redundant=nil
+ local nofused=0
+ for n in traverse_id(glyph_code,head) do
+ local font=getfont(n)
+ if font~=prevfont then
+ if basefont then
+ basefont[2]=getprev(n)
+ end
+ prevfont=font
+ local used=usedfonts[font]
+ if not used then
+ local tfmdata=fontdata[font]
+ if tfmdata then
+ local shared=tfmdata.shared
+ if shared then
+ local processors=shared.processes
+ if processors and #processors>0 then
+ usedfonts[font]=processors
+ nofused=nofused+1
+ elseif basemodepass then
+ basefont={ n,nil }
+ basefonts[#basefonts+1]=basefont
+ end
+ end
+ local resources=tfmdata.resources
+ variants=resources and resources.variants
+ variants=variants and next(variants) and variants or false
+ end
+ else
+ local tfmdata=fontdata[prevfont]
+ if tfmdata then
+ local resources=tfmdata.resources
+ variants=resources and resources.variants
+ variants=variants and next(variants) and variants or false
+ end
+ end
+ end
+ if variants then
+ local char=getchar(n)
+ if (char>=0xFE00 and char<=0xFE0F) or (char>=0xE0100 and char<=0xE01EF) then
+ local hash=variants[char]
+ if hash then
+ local p=getprev(n)
+ if p and getid(p)==glyph_code then
+ local variant=hash[getchar(p)]
+ if variant then
+ setchar(p,variant)
+ end
+ end
+ end
+ if not redundant then
+ redundant={ n }
+ else
+ redundant[#redundant+1]=n
+ end
+ end
+ end
+ end
+ local nofbasefonts=#basefonts
+ if redundant then
+ for i=1,#redundant do
+ local r=redundant[i]
+ local p,n=getboth(r)
+ if r==head then
+ head=n
+ setprev(n)
+ else
+ setlink(p,n)
+ end
+ if nofbasefonts>0 then
+ for i=1,nofbasefonts do
+ local bi=basefonts[i]
+ if r==bi[1] then
+ bi[1]=n
+ end
+ if r==bi[2] then
+ bi[2]=n
+ end
+ end
+ end
+ flush_node(r)
+ end
+ end
+ for d in traverse_id(disc_code,head) do
+ local _,_,r=getdisc(d)
+ if r then
+ for n in traverse_id(glyph_code,r) do
+ local font=getfont(n)
+ if font~=prevfont then
+ prevfont=font
+ local used=usedfonts[font]
+ if not used then
+ local tfmdata=fontdata[font]
+ if tfmdata then
+ local shared=tfmdata.shared
+ if shared then
+ local processors=shared.processes
+ if processors and #processors>0 then
+ usedfonts[font]=processors
+ nofused=nofused+1
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if next(usedfonts) then
+ for font,processors in next,usedfonts do
+ for i=1,#processors do
+ head=processors[i](head,font,0,direction,nofused) or head
+ end
+ end
+ end
+ if basemodepass and nofbasefonts>0 then
+ for i=1,nofbasefonts do
+ local range=basefonts[i]
+ local start=range[1]
+ local stop=range[2]
+ if start then
+ local front=head==start
+ local prev,next
+ if stop then
+ next=getnext(stop)
+ start,stop=d_ligaturing(start,stop)
+ start,stop=d_kerning(start,stop)
+ else
+ prev=getprev(start)
+ start=d_ligaturing(start)
+ start=d_kerning(start)
+ end
+ if prev then
+ setlink(prev,start)
+ end
+ if next then
+ setlink(stop,next)
+ end
+ if front and head~=start then
+ head=start
+ end
+ end
+ end
+ end
+ end
+ return head
+end
+local function basepass(head)
+ if basemodepass then
+ head=d_ligaturing(head)
+ head=d_kerning(head)
+ end
+ return head
+end
+local protectpass=node.direct.protect_glyphs
+local injectpass=nodes.injections.handler
+function nodes.handlers.nodepass(head,...)
+ if head then
+ return tonode(nodepass(tonut(head),...))
+ end
+end
+function nodes.handlers.basepass(head)
+ if head then
+ return tonode(basepass(tonut(head)))
+ end
+end
+function nodes.handlers.injectpass(head)
+ if head then
+ return tonode(injectpass(tonut(head)))
+ end
+end
+function nodes.handlers.protectpass(head)
+ if head then
+ protectpass(tonut(head))
+ return head
+ end
+end
+function nodes.simple_font_handler(head,groupcode,size,packtype,direction)
+ if head then
+ head=tonut(head)
+ head=nodepass(head,groupcode,size,packtype,direction)
+ head=injectpass(head)
+ if not basemodepass then
+ head=basepass(head)
+ end
+ protectpass(head)
+ head=tonode(head)
+ end
+ return head
+end
+
+end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-gbnâ€] ---
+
+
+--- vim:ft=lua:sw=2:ts=8:et:tw=79
diff --git a/macros/luatex/generic/luaotfload/fontloader-basics-chr.lua b/macros/luatex/generic/luaotfload/fontloader-basics-chr.lua
new file mode 100644
index 0000000000..0ac0eab14e
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-basics-chr.lua
@@ -0,0 +1,3619 @@
+-- automatically generated from context data (luatex-basics-prepare.tex)
+
+characters = characters or { }
+
+-- dummies
+
+characters.blockrange = { }
+
+-- classifiers needed for analysis
+
+characters.classifiers={
+ [768]=5,
+ [769]=5,
+ [770]=5,
+ [771]=5,
+ [772]=5,
+ [773]=5,
+ [774]=5,
+ [775]=5,
+ [776]=5,
+ [777]=5,
+ [778]=5,
+ [779]=5,
+ [780]=5,
+ [781]=5,
+ [782]=5,
+ [783]=5,
+ [784]=5,
+ [785]=5,
+ [786]=5,
+ [787]=5,
+ [788]=5,
+ [789]=5,
+ [790]=5,
+ [791]=5,
+ [792]=5,
+ [793]=5,
+ [794]=5,
+ [795]=5,
+ [796]=5,
+ [797]=5,
+ [798]=5,
+ [799]=5,
+ [800]=5,
+ [801]=5,
+ [802]=5,
+ [803]=5,
+ [804]=5,
+ [805]=5,
+ [806]=5,
+ [807]=5,
+ [808]=5,
+ [809]=5,
+ [810]=5,
+ [811]=5,
+ [812]=5,
+ [813]=5,
+ [814]=5,
+ [815]=5,
+ [816]=5,
+ [817]=5,
+ [818]=5,
+ [819]=5,
+ [820]=5,
+ [821]=5,
+ [822]=5,
+ [823]=5,
+ [824]=5,
+ [825]=5,
+ [826]=5,
+ [827]=5,
+ [828]=5,
+ [829]=5,
+ [830]=5,
+ [831]=5,
+ [832]=5,
+ [833]=5,
+ [834]=5,
+ [835]=5,
+ [836]=5,
+ [837]=5,
+ [838]=5,
+ [839]=5,
+ [840]=5,
+ [841]=5,
+ [842]=5,
+ [843]=5,
+ [844]=5,
+ [845]=5,
+ [846]=5,
+ [847]=5,
+ [848]=5,
+ [849]=5,
+ [850]=5,
+ [851]=5,
+ [852]=5,
+ [853]=5,
+ [854]=5,
+ [855]=5,
+ [856]=5,
+ [857]=5,
+ [858]=5,
+ [859]=5,
+ [860]=5,
+ [861]=5,
+ [862]=5,
+ [863]=5,
+ [864]=5,
+ [865]=5,
+ [866]=5,
+ [867]=5,
+ [868]=5,
+ [869]=5,
+ [870]=5,
+ [871]=5,
+ [872]=5,
+ [873]=5,
+ [874]=5,
+ [875]=5,
+ [876]=5,
+ [877]=5,
+ [878]=5,
+ [879]=5,
+ [1155]=5,
+ [1156]=5,
+ [1157]=5,
+ [1158]=5,
+ [1159]=5,
+ [1425]=5,
+ [1426]=5,
+ [1427]=5,
+ [1428]=5,
+ [1429]=5,
+ [1430]=5,
+ [1431]=5,
+ [1432]=5,
+ [1433]=5,
+ [1434]=5,
+ [1435]=5,
+ [1436]=5,
+ [1437]=5,
+ [1438]=5,
+ [1439]=5,
+ [1440]=5,
+ [1441]=5,
+ [1442]=5,
+ [1443]=5,
+ [1444]=5,
+ [1445]=5,
+ [1446]=5,
+ [1447]=5,
+ [1448]=5,
+ [1449]=5,
+ [1450]=5,
+ [1451]=5,
+ [1452]=5,
+ [1453]=5,
+ [1454]=5,
+ [1455]=5,
+ [1456]=5,
+ [1457]=5,
+ [1458]=5,
+ [1459]=5,
+ [1460]=5,
+ [1461]=5,
+ [1462]=5,
+ [1463]=5,
+ [1464]=5,
+ [1465]=5,
+ [1466]=5,
+ [1467]=5,
+ [1468]=5,
+ [1469]=5,
+ [1471]=5,
+ [1473]=5,
+ [1474]=5,
+ [1476]=5,
+ [1477]=5,
+ [1479]=5,
+ [1536]=4,
+ [1537]=4,
+ [1538]=4,
+ [1539]=4,
+ [1540]=4,
+ [1541]=4,
+ [1542]=6,
+ [1543]=6,
+ [1544]=4,
+ [1545]=6,
+ [1546]=6,
+ [1547]=4,
+ [1548]=6,
+ [1549]=6,
+ [1550]=6,
+ [1551]=6,
+ [1552]=5,
+ [1553]=5,
+ [1554]=5,
+ [1555]=5,
+ [1556]=5,
+ [1557]=5,
+ [1558]=5,
+ [1559]=5,
+ [1560]=5,
+ [1561]=5,
+ [1562]=5,
+ [1563]=6,
+ [1564]=6,
+ [1566]=6,
+ [1567]=6,
+ [1568]=2,
+ [1569]=4,
+ [1570]=3,
+ [1571]=3,
+ [1572]=3,
+ [1573]=3,
+ [1574]=2,
+ [1575]=3,
+ [1576]=2,
+ [1577]=3,
+ [1578]=2,
+ [1579]=2,
+ [1580]=2,
+ [1581]=2,
+ [1582]=2,
+ [1583]=3,
+ [1584]=3,
+ [1585]=3,
+ [1586]=3,
+ [1587]=2,
+ [1588]=2,
+ [1589]=2,
+ [1590]=2,
+ [1591]=2,
+ [1592]=2,
+ [1593]=2,
+ [1594]=2,
+ [1595]=2,
+ [1596]=2,
+ [1597]=2,
+ [1598]=2,
+ [1599]=2,
+ [1600]=2,
+ [1601]=2,
+ [1602]=2,
+ [1603]=2,
+ [1604]=2,
+ [1605]=2,
+ [1606]=2,
+ [1607]=2,
+ [1608]=3,
+ [1609]=2,
+ [1610]=2,
+ [1611]=5,
+ [1612]=5,
+ [1613]=5,
+ [1614]=5,
+ [1615]=5,
+ [1616]=5,
+ [1617]=5,
+ [1618]=5,
+ [1619]=5,
+ [1620]=5,
+ [1621]=5,
+ [1622]=5,
+ [1623]=5,
+ [1624]=5,
+ [1625]=5,
+ [1626]=5,
+ [1627]=5,
+ [1628]=5,
+ [1629]=5,
+ [1630]=5,
+ [1631]=5,
+ [1632]=6,
+ [1633]=6,
+ [1634]=6,
+ [1635]=6,
+ [1636]=6,
+ [1637]=6,
+ [1638]=6,
+ [1639]=6,
+ [1640]=6,
+ [1641]=6,
+ [1642]=6,
+ [1643]=6,
+ [1644]=6,
+ [1645]=6,
+ [1646]=2,
+ [1647]=2,
+ [1648]=5,
+ [1649]=3,
+ [1650]=3,
+ [1651]=3,
+ [1652]=4,
+ [1653]=3,
+ [1654]=3,
+ [1655]=3,
+ [1656]=2,
+ [1657]=2,
+ [1658]=2,
+ [1659]=2,
+ [1660]=2,
+ [1661]=2,
+ [1662]=2,
+ [1663]=2,
+ [1664]=2,
+ [1665]=2,
+ [1666]=2,
+ [1667]=2,
+ [1668]=2,
+ [1669]=2,
+ [1670]=2,
+ [1671]=2,
+ [1672]=3,
+ [1673]=3,
+ [1674]=3,
+ [1675]=3,
+ [1676]=3,
+ [1677]=3,
+ [1678]=3,
+ [1679]=3,
+ [1680]=3,
+ [1681]=3,
+ [1682]=3,
+ [1683]=3,
+ [1684]=3,
+ [1685]=3,
+ [1686]=3,
+ [1687]=3,
+ [1688]=3,
+ [1689]=3,
+ [1690]=2,
+ [1691]=2,
+ [1692]=2,
+ [1693]=2,
+ [1694]=2,
+ [1695]=2,
+ [1696]=2,
+ [1697]=2,
+ [1698]=2,
+ [1699]=2,
+ [1700]=2,
+ [1701]=2,
+ [1702]=2,
+ [1703]=2,
+ [1704]=2,
+ [1705]=2,
+ [1706]=2,
+ [1707]=2,
+ [1708]=2,
+ [1709]=2,
+ [1710]=2,
+ [1711]=2,
+ [1712]=2,
+ [1713]=2,
+ [1714]=2,
+ [1715]=2,
+ [1716]=2,
+ [1717]=2,
+ [1718]=2,
+ [1719]=2,
+ [1720]=2,
+ [1721]=2,
+ [1722]=2,
+ [1723]=2,
+ [1724]=2,
+ [1725]=2,
+ [1726]=2,
+ [1727]=2,
+ [1728]=3,
+ [1729]=2,
+ [1730]=2,
+ [1731]=3,
+ [1732]=3,
+ [1733]=3,
+ [1734]=3,
+ [1735]=3,
+ [1736]=3,
+ [1737]=3,
+ [1738]=3,
+ [1739]=3,
+ [1740]=2,
+ [1741]=3,
+ [1742]=2,
+ [1743]=3,
+ [1744]=2,
+ [1745]=2,
+ [1746]=3,
+ [1747]=3,
+ [1748]=6,
+ [1749]=3,
+ [1750]=5,
+ [1751]=5,
+ [1752]=5,
+ [1753]=5,
+ [1754]=5,
+ [1755]=5,
+ [1756]=5,
+ [1757]=4,
+ [1758]=6,
+ [1759]=5,
+ [1760]=5,
+ [1761]=5,
+ [1762]=5,
+ [1763]=5,
+ [1764]=5,
+ [1765]=6,
+ [1766]=6,
+ [1767]=5,
+ [1768]=5,
+ [1769]=6,
+ [1770]=5,
+ [1771]=5,
+ [1772]=5,
+ [1773]=5,
+ [1774]=3,
+ [1775]=3,
+ [1776]=6,
+ [1777]=6,
+ [1778]=6,
+ [1779]=6,
+ [1780]=6,
+ [1781]=6,
+ [1782]=6,
+ [1783]=6,
+ [1784]=6,
+ [1785]=6,
+ [1786]=2,
+ [1787]=2,
+ [1788]=2,
+ [1789]=6,
+ [1790]=6,
+ [1791]=2,
+ [1792]=6,
+ [1793]=6,
+ [1794]=6,
+ [1795]=6,
+ [1796]=6,
+ [1797]=6,
+ [1798]=6,
+ [1799]=6,
+ [1800]=6,
+ [1801]=6,
+ [1802]=6,
+ [1803]=6,
+ [1804]=6,
+ [1805]=6,
+ [1808]=3,
+ [1809]=5,
+ [1810]=2,
+ [1811]=2,
+ [1812]=2,
+ [1813]=3,
+ [1814]=3,
+ [1815]=3,
+ [1816]=3,
+ [1817]=3,
+ [1818]=2,
+ [1819]=2,
+ [1820]=2,
+ [1821]=2,
+ [1822]=3,
+ [1823]=2,
+ [1824]=2,
+ [1825]=2,
+ [1826]=2,
+ [1827]=2,
+ [1828]=2,
+ [1829]=2,
+ [1830]=2,
+ [1831]=2,
+ [1832]=3,
+ [1833]=2,
+ [1834]=3,
+ [1835]=2,
+ [1836]=3,
+ [1837]=2,
+ [1838]=2,
+ [1839]=3,
+ [1840]=5,
+ [1841]=5,
+ [1842]=5,
+ [1843]=5,
+ [1844]=5,
+ [1845]=5,
+ [1846]=5,
+ [1847]=5,
+ [1848]=5,
+ [1849]=5,
+ [1850]=5,
+ [1851]=5,
+ [1852]=5,
+ [1853]=5,
+ [1854]=5,
+ [1855]=5,
+ [1856]=5,
+ [1857]=5,
+ [1858]=5,
+ [1859]=5,
+ [1860]=5,
+ [1861]=5,
+ [1862]=5,
+ [1863]=5,
+ [1864]=5,
+ [1865]=5,
+ [1866]=5,
+ [1869]=3,
+ [1870]=2,
+ [1871]=2,
+ [1872]=2,
+ [1873]=2,
+ [1874]=2,
+ [1875]=2,
+ [1876]=2,
+ [1877]=2,
+ [1878]=2,
+ [1879]=2,
+ [1880]=2,
+ [1881]=3,
+ [1882]=3,
+ [1883]=3,
+ [1884]=2,
+ [1885]=2,
+ [1886]=2,
+ [1887]=2,
+ [1888]=2,
+ [1889]=2,
+ [1890]=2,
+ [1891]=2,
+ [1892]=2,
+ [1893]=2,
+ [1894]=2,
+ [1895]=2,
+ [1896]=2,
+ [1897]=2,
+ [1898]=2,
+ [1899]=3,
+ [1900]=3,
+ [1901]=2,
+ [1902]=2,
+ [1903]=2,
+ [1904]=2,
+ [1905]=3,
+ [1906]=2,
+ [1907]=3,
+ [1908]=3,
+ [1909]=2,
+ [1910]=2,
+ [1911]=2,
+ [1912]=3,
+ [1913]=3,
+ [1914]=2,
+ [1915]=2,
+ [1916]=2,
+ [1917]=2,
+ [1918]=2,
+ [1919]=2,
+ [1958]=5,
+ [1959]=5,
+ [1960]=5,
+ [1961]=5,
+ [1962]=5,
+ [1963]=5,
+ [1964]=5,
+ [1965]=5,
+ [1966]=5,
+ [1967]=5,
+ [1968]=5,
+ [1984]=6,
+ [1985]=6,
+ [1986]=6,
+ [1987]=6,
+ [1988]=6,
+ [1989]=6,
+ [1990]=6,
+ [1991]=6,
+ [1992]=6,
+ [1993]=6,
+ [1994]=2,
+ [1995]=2,
+ [1996]=2,
+ [1997]=2,
+ [1998]=2,
+ [1999]=2,
+ [2000]=2,
+ [2001]=2,
+ [2002]=2,
+ [2003]=2,
+ [2004]=2,
+ [2005]=2,
+ [2006]=2,
+ [2007]=2,
+ [2008]=2,
+ [2009]=2,
+ [2010]=2,
+ [2011]=2,
+ [2012]=2,
+ [2013]=2,
+ [2014]=2,
+ [2015]=2,
+ [2016]=2,
+ [2017]=2,
+ [2018]=2,
+ [2019]=2,
+ [2020]=2,
+ [2021]=2,
+ [2022]=2,
+ [2023]=2,
+ [2024]=2,
+ [2025]=2,
+ [2026]=2,
+ [2027]=5,
+ [2028]=5,
+ [2029]=5,
+ [2030]=5,
+ [2031]=5,
+ [2032]=5,
+ [2033]=5,
+ [2034]=5,
+ [2035]=5,
+ [2036]=6,
+ [2037]=6,
+ [2038]=6,
+ [2039]=6,
+ [2040]=6,
+ [2041]=6,
+ [2042]=2,
+ [2045]=5,
+ [2046]=6,
+ [2047]=6,
+ [2070]=5,
+ [2071]=5,
+ [2072]=5,
+ [2073]=5,
+ [2075]=5,
+ [2076]=5,
+ [2077]=5,
+ [2078]=5,
+ [2079]=5,
+ [2080]=5,
+ [2081]=5,
+ [2082]=5,
+ [2083]=5,
+ [2085]=5,
+ [2086]=5,
+ [2087]=5,
+ [2089]=5,
+ [2090]=5,
+ [2091]=5,
+ [2092]=5,
+ [2093]=5,
+ [2112]=3,
+ [2113]=2,
+ [2114]=2,
+ [2115]=2,
+ [2116]=2,
+ [2117]=2,
+ [2118]=3,
+ [2119]=3,
+ [2120]=2,
+ [2121]=3,
+ [2122]=2,
+ [2123]=2,
+ [2124]=2,
+ [2125]=2,
+ [2126]=2,
+ [2127]=2,
+ [2128]=2,
+ [2129]=2,
+ [2130]=2,
+ [2131]=2,
+ [2132]=3,
+ [2133]=2,
+ [2134]=4,
+ [2135]=4,
+ [2136]=4,
+ [2137]=5,
+ [2138]=5,
+ [2139]=5,
+ [2144]=2,
+ [2145]=4,
+ [2146]=2,
+ [2147]=2,
+ [2148]=2,
+ [2149]=2,
+ [2150]=4,
+ [2151]=3,
+ [2152]=2,
+ [2153]=3,
+ [2154]=3,
+ [2208]=2,
+ [2209]=2,
+ [2210]=2,
+ [2211]=2,
+ [2212]=2,
+ [2213]=2,
+ [2214]=2,
+ [2215]=2,
+ [2216]=2,
+ [2217]=2,
+ [2218]=3,
+ [2219]=3,
+ [2220]=3,
+ [2221]=4,
+ [2222]=3,
+ [2223]=2,
+ [2224]=2,
+ [2225]=3,
+ [2226]=3,
+ [2227]=2,
+ [2228]=2,
+ [2230]=2,
+ [2231]=2,
+ [2232]=2,
+ [2233]=3,
+ [2234]=2,
+ [2235]=2,
+ [2236]=2,
+ [2237]=2,
+ [2259]=5,
+ [2260]=5,
+ [2261]=5,
+ [2262]=5,
+ [2263]=5,
+ [2264]=5,
+ [2265]=5,
+ [2266]=5,
+ [2267]=5,
+ [2268]=5,
+ [2269]=5,
+ [2270]=5,
+ [2271]=5,
+ [2272]=5,
+ [2273]=5,
+ [2274]=4,
+ [2275]=5,
+ [2276]=5,
+ [2277]=5,
+ [2278]=5,
+ [2279]=5,
+ [2280]=5,
+ [2281]=5,
+ [2282]=5,
+ [2283]=5,
+ [2284]=5,
+ [2285]=5,
+ [2286]=5,
+ [2287]=5,
+ [2288]=5,
+ [2289]=5,
+ [2290]=5,
+ [2291]=5,
+ [2292]=5,
+ [2293]=5,
+ [2294]=5,
+ [2295]=5,
+ [2296]=5,
+ [2297]=5,
+ [2298]=5,
+ [2299]=5,
+ [2300]=5,
+ [2301]=5,
+ [2302]=5,
+ [2303]=5,
+ [2304]=5,
+ [2305]=5,
+ [2306]=5,
+ [2362]=5,
+ [2364]=5,
+ [2369]=5,
+ [2370]=5,
+ [2371]=5,
+ [2372]=5,
+ [2373]=5,
+ [2374]=5,
+ [2375]=5,
+ [2376]=5,
+ [2381]=5,
+ [2385]=5,
+ [2386]=5,
+ [2387]=5,
+ [2388]=5,
+ [2389]=5,
+ [2390]=5,
+ [2391]=5,
+ [2402]=5,
+ [2403]=5,
+ [2433]=5,
+ [2492]=5,
+ [2497]=5,
+ [2498]=5,
+ [2499]=5,
+ [2500]=5,
+ [2509]=5,
+ [2530]=5,
+ [2531]=5,
+ [2558]=5,
+ [2561]=5,
+ [2562]=5,
+ [2620]=5,
+ [2625]=5,
+ [2626]=5,
+ [2631]=5,
+ [2632]=5,
+ [2635]=5,
+ [2636]=5,
+ [2637]=5,
+ [2641]=5,
+ [2672]=5,
+ [2673]=5,
+ [2677]=5,
+ [2689]=5,
+ [2690]=5,
+ [2748]=5,
+ [2753]=5,
+ [2754]=5,
+ [2755]=5,
+ [2756]=5,
+ [2757]=5,
+ [2759]=5,
+ [2760]=5,
+ [2765]=5,
+ [2786]=5,
+ [2787]=5,
+ [2810]=5,
+ [2811]=5,
+ [2812]=5,
+ [2813]=5,
+ [2814]=5,
+ [2815]=5,
+ [2817]=5,
+ [2876]=5,
+ [2879]=5,
+ [2881]=5,
+ [2882]=5,
+ [2883]=5,
+ [2884]=5,
+ [2893]=5,
+ [2902]=5,
+ [2914]=5,
+ [2915]=5,
+ [2946]=5,
+ [3008]=5,
+ [3021]=5,
+ [3072]=5,
+ [3076]=5,
+ [3134]=5,
+ [3135]=5,
+ [3136]=5,
+ [3142]=5,
+ [3143]=5,
+ [3144]=5,
+ [3146]=5,
+ [3147]=5,
+ [3148]=5,
+ [3149]=5,
+ [3157]=5,
+ [3158]=5,
+ [3170]=5,
+ [3171]=5,
+ [3201]=5,
+ [3260]=5,
+ [3263]=5,
+ [3270]=5,
+ [3276]=5,
+ [3277]=5,
+ [3298]=5,
+ [3299]=5,
+ [3328]=5,
+ [3329]=5,
+ [3387]=5,
+ [3388]=5,
+ [3393]=5,
+ [3394]=5,
+ [3395]=5,
+ [3396]=5,
+ [3405]=5,
+ [3426]=5,
+ [3427]=5,
+ [3530]=5,
+ [3538]=5,
+ [3539]=5,
+ [3540]=5,
+ [3542]=5,
+ [3633]=5,
+ [3636]=5,
+ [3637]=5,
+ [3638]=5,
+ [3639]=5,
+ [3640]=5,
+ [3641]=5,
+ [3642]=5,
+ [3655]=5,
+ [3656]=5,
+ [3657]=5,
+ [3658]=5,
+ [3659]=5,
+ [3660]=5,
+ [3661]=5,
+ [3662]=5,
+ [3761]=5,
+ [3764]=5,
+ [3765]=5,
+ [3766]=5,
+ [3767]=5,
+ [3768]=5,
+ [3769]=5,
+ [3770]=5,
+ [3771]=5,
+ [3772]=5,
+ [3784]=5,
+ [3785]=5,
+ [3786]=5,
+ [3787]=5,
+ [3788]=5,
+ [3789]=5,
+ [3864]=5,
+ [3865]=5,
+ [3893]=5,
+ [3895]=5,
+ [3897]=5,
+ [3953]=5,
+ [3954]=5,
+ [3955]=5,
+ [3956]=5,
+ [3957]=5,
+ [3958]=5,
+ [3959]=5,
+ [3960]=5,
+ [3961]=5,
+ [3962]=5,
+ [3963]=5,
+ [3964]=5,
+ [3965]=5,
+ [3966]=5,
+ [3968]=5,
+ [3969]=5,
+ [3970]=5,
+ [3971]=5,
+ [3972]=5,
+ [3974]=5,
+ [3975]=5,
+ [3981]=5,
+ [3982]=5,
+ [3983]=5,
+ [3984]=5,
+ [3985]=5,
+ [3986]=5,
+ [3987]=5,
+ [3988]=5,
+ [3989]=5,
+ [3990]=5,
+ [3991]=5,
+ [3993]=5,
+ [3994]=5,
+ [3995]=5,
+ [3996]=5,
+ [3997]=5,
+ [3998]=5,
+ [3999]=5,
+ [4000]=5,
+ [4001]=5,
+ [4002]=5,
+ [4003]=5,
+ [4004]=5,
+ [4005]=5,
+ [4006]=5,
+ [4007]=5,
+ [4008]=5,
+ [4009]=5,
+ [4010]=5,
+ [4011]=5,
+ [4012]=5,
+ [4013]=5,
+ [4014]=5,
+ [4015]=5,
+ [4016]=5,
+ [4017]=5,
+ [4018]=5,
+ [4019]=5,
+ [4020]=5,
+ [4021]=5,
+ [4022]=5,
+ [4023]=5,
+ [4024]=5,
+ [4025]=5,
+ [4026]=5,
+ [4027]=5,
+ [4028]=5,
+ [4038]=5,
+ [4141]=5,
+ [4142]=5,
+ [4143]=5,
+ [4144]=5,
+ [4146]=5,
+ [4147]=5,
+ [4148]=5,
+ [4149]=5,
+ [4150]=5,
+ [4151]=5,
+ [4153]=5,
+ [4154]=5,
+ [4157]=5,
+ [4158]=5,
+ [4184]=5,
+ [4185]=5,
+ [4190]=5,
+ [4191]=5,
+ [4192]=5,
+ [4209]=5,
+ [4210]=5,
+ [4211]=5,
+ [4212]=5,
+ [4226]=5,
+ [4229]=5,
+ [4230]=5,
+ [4237]=5,
+ [4253]=5,
+ [4957]=5,
+ [4958]=5,
+ [4959]=5,
+ [5906]=5,
+ [5907]=5,
+ [5908]=5,
+ [5938]=5,
+ [5939]=5,
+ [5940]=5,
+ [5970]=5,
+ [5971]=5,
+ [6002]=5,
+ [6003]=5,
+ [6071]=5,
+ [6072]=5,
+ [6073]=5,
+ [6074]=5,
+ [6075]=5,
+ [6076]=5,
+ [6077]=5,
+ [6086]=5,
+ [6089]=5,
+ [6090]=5,
+ [6091]=5,
+ [6092]=5,
+ [6093]=5,
+ [6094]=5,
+ [6095]=5,
+ [6096]=5,
+ [6097]=5,
+ [6098]=5,
+ [6099]=5,
+ [6109]=5,
+ [6150]=4,
+ [6151]=2,
+ [6154]=2,
+ [6155]=5,
+ [6156]=5,
+ [6157]=5,
+ [6158]=4,
+ [6176]=2,
+ [6177]=2,
+ [6178]=2,
+ [6179]=2,
+ [6180]=2,
+ [6181]=2,
+ [6182]=2,
+ [6183]=2,
+ [6184]=2,
+ [6185]=2,
+ [6186]=2,
+ [6187]=2,
+ [6188]=2,
+ [6189]=2,
+ [6190]=2,
+ [6191]=2,
+ [6192]=2,
+ [6193]=2,
+ [6194]=2,
+ [6195]=2,
+ [6196]=2,
+ [6197]=2,
+ [6198]=2,
+ [6199]=2,
+ [6200]=2,
+ [6201]=2,
+ [6202]=2,
+ [6203]=2,
+ [6204]=2,
+ [6205]=2,
+ [6206]=2,
+ [6207]=2,
+ [6208]=2,
+ [6209]=2,
+ [6210]=2,
+ [6211]=2,
+ [6212]=2,
+ [6213]=2,
+ [6214]=2,
+ [6215]=2,
+ [6216]=2,
+ [6217]=2,
+ [6218]=2,
+ [6219]=2,
+ [6220]=2,
+ [6221]=2,
+ [6222]=2,
+ [6223]=2,
+ [6224]=2,
+ [6225]=2,
+ [6226]=2,
+ [6227]=2,
+ [6228]=2,
+ [6229]=2,
+ [6230]=2,
+ [6231]=2,
+ [6232]=2,
+ [6233]=2,
+ [6234]=2,
+ [6235]=2,
+ [6236]=2,
+ [6237]=2,
+ [6238]=2,
+ [6239]=2,
+ [6240]=2,
+ [6241]=2,
+ [6242]=2,
+ [6243]=2,
+ [6244]=2,
+ [6245]=2,
+ [6246]=2,
+ [6247]=2,
+ [6248]=2,
+ [6249]=2,
+ [6250]=2,
+ [6251]=2,
+ [6252]=2,
+ [6253]=2,
+ [6254]=2,
+ [6255]=2,
+ [6256]=2,
+ [6257]=2,
+ [6258]=2,
+ [6259]=2,
+ [6260]=2,
+ [6261]=2,
+ [6262]=2,
+ [6263]=2,
+ [6264]=2,
+ [6272]=4,
+ [6273]=4,
+ [6274]=4,
+ [6275]=4,
+ [6276]=4,
+ [6279]=2,
+ [6280]=2,
+ [6281]=2,
+ [6282]=2,
+ [6283]=2,
+ [6284]=2,
+ [6285]=2,
+ [6286]=2,
+ [6287]=2,
+ [6288]=2,
+ [6289]=2,
+ [6290]=2,
+ [6291]=2,
+ [6292]=2,
+ [6293]=2,
+ [6294]=2,
+ [6295]=2,
+ [6296]=2,
+ [6297]=2,
+ [6298]=2,
+ [6299]=2,
+ [6300]=2,
+ [6301]=2,
+ [6302]=2,
+ [6303]=2,
+ [6304]=2,
+ [6305]=2,
+ [6306]=2,
+ [6307]=2,
+ [6308]=2,
+ [6309]=2,
+ [6310]=2,
+ [6311]=2,
+ [6312]=2,
+ [6313]=5,
+ [6314]=2,
+ [6432]=5,
+ [6433]=5,
+ [6434]=5,
+ [6439]=5,
+ [6440]=5,
+ [6450]=5,
+ [6457]=5,
+ [6458]=5,
+ [6459]=5,
+ [6679]=5,
+ [6680]=5,
+ [6742]=5,
+ [6744]=5,
+ [6745]=5,
+ [6746]=5,
+ [6747]=5,
+ [6748]=5,
+ [6749]=5,
+ [6750]=5,
+ [6752]=5,
+ [6754]=5,
+ [6757]=5,
+ [6758]=5,
+ [6759]=5,
+ [6760]=5,
+ [6761]=5,
+ [6762]=5,
+ [6763]=5,
+ [6764]=5,
+ [6771]=5,
+ [6772]=5,
+ [6773]=5,
+ [6774]=5,
+ [6775]=5,
+ [6776]=5,
+ [6777]=5,
+ [6778]=5,
+ [6779]=5,
+ [6780]=5,
+ [6783]=5,
+ [6832]=5,
+ [6833]=5,
+ [6834]=5,
+ [6835]=5,
+ [6836]=5,
+ [6837]=5,
+ [6838]=5,
+ [6839]=5,
+ [6840]=5,
+ [6841]=5,
+ [6842]=5,
+ [6843]=5,
+ [6844]=5,
+ [6845]=5,
+ [6912]=5,
+ [6913]=5,
+ [6914]=5,
+ [6915]=5,
+ [6964]=5,
+ [6966]=5,
+ [6967]=5,
+ [6968]=5,
+ [6969]=5,
+ [6970]=5,
+ [6972]=5,
+ [6978]=5,
+ [7019]=5,
+ [7020]=5,
+ [7021]=5,
+ [7022]=5,
+ [7023]=5,
+ [7024]=5,
+ [7025]=5,
+ [7026]=5,
+ [7027]=5,
+ [7040]=5,
+ [7041]=5,
+ [7074]=5,
+ [7075]=5,
+ [7076]=5,
+ [7077]=5,
+ [7080]=5,
+ [7081]=5,
+ [7083]=5,
+ [7142]=5,
+ [7144]=5,
+ [7145]=5,
+ [7149]=5,
+ [7151]=5,
+ [7152]=5,
+ [7153]=5,
+ [7212]=5,
+ [7213]=5,
+ [7214]=5,
+ [7215]=5,
+ [7216]=5,
+ [7217]=5,
+ [7218]=5,
+ [7219]=5,
+ [7222]=5,
+ [7223]=5,
+ [7376]=5,
+ [7377]=5,
+ [7378]=5,
+ [7380]=5,
+ [7381]=5,
+ [7382]=5,
+ [7383]=5,
+ [7384]=5,
+ [7385]=5,
+ [7386]=5,
+ [7387]=5,
+ [7388]=5,
+ [7389]=5,
+ [7390]=5,
+ [7391]=5,
+ [7392]=5,
+ [7394]=5,
+ [7395]=5,
+ [7396]=5,
+ [7397]=5,
+ [7398]=5,
+ [7399]=5,
+ [7400]=5,
+ [7405]=5,
+ [7412]=5,
+ [7416]=5,
+ [7417]=5,
+ [7616]=5,
+ [7617]=5,
+ [7618]=5,
+ [7619]=5,
+ [7620]=5,
+ [7621]=5,
+ [7622]=5,
+ [7623]=5,
+ [7624]=5,
+ [7625]=5,
+ [7626]=5,
+ [7627]=5,
+ [7628]=5,
+ [7629]=5,
+ [7630]=5,
+ [7631]=5,
+ [7632]=5,
+ [7633]=5,
+ [7634]=5,
+ [7635]=5,
+ [7636]=5,
+ [7637]=5,
+ [7638]=5,
+ [7639]=5,
+ [7640]=5,
+ [7641]=5,
+ [7642]=5,
+ [7643]=5,
+ [7644]=5,
+ [7645]=5,
+ [7646]=5,
+ [7647]=5,
+ [7648]=5,
+ [7649]=5,
+ [7650]=5,
+ [7651]=5,
+ [7652]=5,
+ [7653]=5,
+ [7654]=5,
+ [7655]=5,
+ [7656]=5,
+ [7657]=5,
+ [7658]=5,
+ [7659]=5,
+ [7660]=5,
+ [7661]=5,
+ [7662]=5,
+ [7663]=5,
+ [7664]=5,
+ [7665]=5,
+ [7666]=5,
+ [7667]=5,
+ [7668]=5,
+ [7669]=5,
+ [7670]=5,
+ [7671]=5,
+ [7672]=5,
+ [7673]=5,
+ [7675]=5,
+ [7676]=5,
+ [7677]=5,
+ [7678]=5,
+ [7679]=5,
+ [8204]=4,
+ [8205]=2,
+ [8239]=4,
+ [8294]=4,
+ [8295]=4,
+ [8296]=4,
+ [8297]=4,
+ [8400]=5,
+ [8401]=5,
+ [8402]=5,
+ [8403]=5,
+ [8404]=5,
+ [8405]=5,
+ [8406]=5,
+ [8407]=5,
+ [8408]=5,
+ [8409]=5,
+ [8410]=5,
+ [8411]=5,
+ [8412]=5,
+ [8417]=5,
+ [8421]=5,
+ [8422]=5,
+ [8423]=5,
+ [8424]=5,
+ [8425]=5,
+ [8426]=5,
+ [8427]=5,
+ [8428]=5,
+ [8429]=5,
+ [8430]=5,
+ [8431]=5,
+ [8432]=5,
+ [11503]=5,
+ [11504]=5,
+ [11505]=5,
+ [11647]=5,
+ [11744]=5,
+ [11745]=5,
+ [11746]=5,
+ [11747]=5,
+ [11748]=5,
+ [11749]=5,
+ [11750]=5,
+ [11751]=5,
+ [11752]=5,
+ [11753]=5,
+ [11754]=5,
+ [11755]=5,
+ [11756]=5,
+ [11757]=5,
+ [11758]=5,
+ [11759]=5,
+ [11760]=5,
+ [11761]=5,
+ [11762]=5,
+ [11763]=5,
+ [11764]=5,
+ [11765]=5,
+ [11766]=5,
+ [11767]=5,
+ [11768]=5,
+ [11769]=5,
+ [11770]=5,
+ [11771]=5,
+ [11772]=5,
+ [11773]=5,
+ [11774]=5,
+ [11775]=5,
+ [12330]=5,
+ [12331]=5,
+ [12332]=5,
+ [12333]=5,
+ [12334]=5,
+ [12335]=5,
+ [12441]=5,
+ [12442]=5,
+ [42607]=5,
+ [42612]=5,
+ [42613]=5,
+ [42614]=5,
+ [42615]=5,
+ [42616]=5,
+ [42617]=5,
+ [42618]=5,
+ [42619]=5,
+ [42620]=5,
+ [42621]=5,
+ [42654]=5,
+ [42655]=5,
+ [42736]=5,
+ [42737]=5,
+ [43014]=5,
+ [43019]=5,
+ [43045]=5,
+ [43046]=5,
+ [43072]=2,
+ [43073]=2,
+ [43074]=2,
+ [43075]=2,
+ [43076]=2,
+ [43077]=2,
+ [43078]=2,
+ [43079]=2,
+ [43080]=2,
+ [43081]=2,
+ [43082]=2,
+ [43083]=2,
+ [43084]=2,
+ [43085]=2,
+ [43086]=2,
+ [43087]=2,
+ [43088]=2,
+ [43089]=2,
+ [43090]=2,
+ [43091]=2,
+ [43092]=2,
+ [43093]=2,
+ [43094]=2,
+ [43095]=2,
+ [43096]=2,
+ [43097]=2,
+ [43098]=2,
+ [43099]=2,
+ [43100]=2,
+ [43101]=2,
+ [43102]=2,
+ [43103]=2,
+ [43104]=2,
+ [43105]=2,
+ [43106]=2,
+ [43107]=2,
+ [43108]=2,
+ [43109]=2,
+ [43110]=2,
+ [43111]=2,
+ [43112]=2,
+ [43113]=2,
+ [43114]=2,
+ [43115]=2,
+ [43116]=2,
+ [43117]=2,
+ [43118]=2,
+ [43119]=2,
+ [43120]=2,
+ [43121]=2,
+ [43122]=1,
+ [43123]=4,
+ [43204]=5,
+ [43205]=5,
+ [43232]=5,
+ [43233]=5,
+ [43234]=5,
+ [43235]=5,
+ [43236]=5,
+ [43237]=5,
+ [43238]=5,
+ [43239]=5,
+ [43240]=5,
+ [43241]=5,
+ [43242]=5,
+ [43243]=5,
+ [43244]=5,
+ [43245]=5,
+ [43246]=5,
+ [43247]=5,
+ [43248]=5,
+ [43249]=5,
+ [43263]=5,
+ [43302]=5,
+ [43303]=5,
+ [43304]=5,
+ [43305]=5,
+ [43306]=5,
+ [43307]=5,
+ [43308]=5,
+ [43309]=5,
+ [43335]=5,
+ [43336]=5,
+ [43337]=5,
+ [43338]=5,
+ [43339]=5,
+ [43340]=5,
+ [43341]=5,
+ [43342]=5,
+ [43343]=5,
+ [43344]=5,
+ [43345]=5,
+ [43392]=5,
+ [43393]=5,
+ [43394]=5,
+ [43443]=5,
+ [43446]=5,
+ [43447]=5,
+ [43448]=5,
+ [43449]=5,
+ [43452]=5,
+ [43493]=5,
+ [43561]=5,
+ [43562]=5,
+ [43563]=5,
+ [43564]=5,
+ [43565]=5,
+ [43566]=5,
+ [43569]=5,
+ [43570]=5,
+ [43573]=5,
+ [43574]=5,
+ [43587]=5,
+ [43596]=5,
+ [43644]=5,
+ [43696]=5,
+ [43698]=5,
+ [43699]=5,
+ [43700]=5,
+ [43703]=5,
+ [43704]=5,
+ [43710]=5,
+ [43711]=5,
+ [43713]=5,
+ [43756]=5,
+ [43757]=5,
+ [43766]=5,
+ [44005]=5,
+ [44008]=5,
+ [44013]=5,
+ [64286]=5,
+ [65056]=5,
+ [65057]=5,
+ [65058]=5,
+ [65059]=5,
+ [65060]=5,
+ [65061]=5,
+ [65062]=5,
+ [65063]=5,
+ [65064]=5,
+ [65065]=5,
+ [65066]=5,
+ [65067]=5,
+ [65068]=5,
+ [65069]=5,
+ [65070]=5,
+ [65071]=5,
+ [66045]=5,
+ [66272]=5,
+ [66422]=5,
+ [66423]=5,
+ [66424]=5,
+ [66425]=5,
+ [66426]=5,
+ [68097]=5,
+ [68098]=5,
+ [68099]=5,
+ [68101]=5,
+ [68102]=5,
+ [68108]=5,
+ [68109]=5,
+ [68110]=5,
+ [68111]=5,
+ [68152]=5,
+ [68153]=5,
+ [68154]=5,
+ [68159]=5,
+ [68288]=2,
+ [68289]=2,
+ [68290]=2,
+ [68291]=2,
+ [68292]=2,
+ [68293]=3,
+ [68294]=4,
+ [68295]=3,
+ [68296]=4,
+ [68297]=3,
+ [68298]=3,
+ [68299]=4,
+ [68300]=4,
+ [68301]=1,
+ [68302]=3,
+ [68303]=3,
+ [68304]=3,
+ [68305]=3,
+ [68306]=3,
+ [68307]=2,
+ [68308]=2,
+ [68309]=2,
+ [68310]=2,
+ [68311]=1,
+ [68312]=2,
+ [68313]=2,
+ [68314]=2,
+ [68315]=2,
+ [68316]=2,
+ [68317]=3,
+ [68318]=2,
+ [68319]=2,
+ [68320]=2,
+ [68321]=3,
+ [68322]=4,
+ [68323]=4,
+ [68324]=3,
+ [68325]=5,
+ [68326]=5,
+ [68331]=2,
+ [68332]=2,
+ [68333]=2,
+ [68334]=2,
+ [68335]=3,
+ [68480]=2,
+ [68481]=3,
+ [68482]=2,
+ [68483]=3,
+ [68484]=3,
+ [68485]=3,
+ [68486]=2,
+ [68487]=2,
+ [68488]=2,
+ [68489]=3,
+ [68490]=2,
+ [68491]=2,
+ [68492]=3,
+ [68493]=2,
+ [68494]=3,
+ [68495]=3,
+ [68496]=2,
+ [68497]=3,
+ [68521]=3,
+ [68522]=3,
+ [68523]=3,
+ [68524]=3,
+ [68525]=2,
+ [68526]=2,
+ [68527]=4,
+ [68864]=1,
+ [68865]=2,
+ [68866]=2,
+ [68867]=2,
+ [68868]=2,
+ [68869]=2,
+ [68870]=2,
+ [68871]=2,
+ [68872]=2,
+ [68873]=2,
+ [68874]=2,
+ [68875]=2,
+ [68876]=2,
+ [68877]=2,
+ [68878]=2,
+ [68879]=2,
+ [68880]=2,
+ [68881]=2,
+ [68882]=2,
+ [68883]=2,
+ [68884]=2,
+ [68885]=2,
+ [68886]=2,
+ [68887]=2,
+ [68888]=2,
+ [68889]=2,
+ [68890]=2,
+ [68891]=2,
+ [68892]=2,
+ [68893]=2,
+ [68894]=2,
+ [68895]=2,
+ [68896]=2,
+ [68897]=2,
+ [68898]=3,
+ [68899]=2,
+ [68900]=5,
+ [68901]=5,
+ [68902]=5,
+ [68903]=5,
+ [69424]=2,
+ [69425]=2,
+ [69426]=2,
+ [69427]=3,
+ [69428]=2,
+ [69429]=2,
+ [69430]=2,
+ [69431]=2,
+ [69432]=2,
+ [69433]=2,
+ [69434]=2,
+ [69435]=2,
+ [69436]=2,
+ [69437]=2,
+ [69438]=2,
+ [69439]=2,
+ [69440]=2,
+ [69441]=2,
+ [69442]=2,
+ [69443]=2,
+ [69444]=2,
+ [69445]=4,
+ [69446]=5,
+ [69447]=5,
+ [69448]=5,
+ [69449]=5,
+ [69450]=5,
+ [69451]=5,
+ [69452]=5,
+ [69453]=5,
+ [69454]=5,
+ [69455]=5,
+ [69456]=5,
+ [69457]=2,
+ [69458]=2,
+ [69459]=2,
+ [69460]=3,
+ [69633]=5,
+ [69688]=5,
+ [69689]=5,
+ [69690]=5,
+ [69691]=5,
+ [69692]=5,
+ [69693]=5,
+ [69694]=5,
+ [69695]=5,
+ [69696]=5,
+ [69697]=5,
+ [69698]=5,
+ [69699]=5,
+ [69700]=5,
+ [69701]=5,
+ [69702]=5,
+ [69759]=5,
+ [69760]=5,
+ [69761]=5,
+ [69811]=5,
+ [69812]=5,
+ [69813]=5,
+ [69814]=5,
+ [69817]=5,
+ [69818]=5,
+ [69821]=4,
+ [69837]=4,
+ [69888]=5,
+ [69889]=5,
+ [69890]=5,
+ [69927]=5,
+ [69928]=5,
+ [69929]=5,
+ [69930]=5,
+ [69931]=5,
+ [69933]=5,
+ [69934]=5,
+ [69935]=5,
+ [69936]=5,
+ [69937]=5,
+ [69938]=5,
+ [69939]=5,
+ [69940]=5,
+ [70003]=5,
+ [70016]=5,
+ [70017]=5,
+ [70070]=5,
+ [70071]=5,
+ [70072]=5,
+ [70073]=5,
+ [70074]=5,
+ [70075]=5,
+ [70076]=5,
+ [70077]=5,
+ [70078]=5,
+ [70090]=5,
+ [70091]=5,
+ [70092]=5,
+ [70191]=5,
+ [70192]=5,
+ [70193]=5,
+ [70196]=5,
+ [70198]=5,
+ [70199]=5,
+ [70206]=5,
+ [70367]=5,
+ [70371]=5,
+ [70372]=5,
+ [70373]=5,
+ [70374]=5,
+ [70375]=5,
+ [70376]=5,
+ [70377]=5,
+ [70378]=5,
+ [70400]=5,
+ [70401]=5,
+ [70459]=5,
+ [70460]=5,
+ [70464]=5,
+ [70502]=5,
+ [70503]=5,
+ [70504]=5,
+ [70505]=5,
+ [70506]=5,
+ [70507]=5,
+ [70508]=5,
+ [70512]=5,
+ [70513]=5,
+ [70514]=5,
+ [70515]=5,
+ [70516]=5,
+ [70712]=5,
+ [70713]=5,
+ [70714]=5,
+ [70715]=5,
+ [70716]=5,
+ [70717]=5,
+ [70718]=5,
+ [70719]=5,
+ [70722]=5,
+ [70723]=5,
+ [70724]=5,
+ [70726]=5,
+ [70750]=5,
+ [70835]=5,
+ [70836]=5,
+ [70837]=5,
+ [70838]=5,
+ [70839]=5,
+ [70840]=5,
+ [70842]=5,
+ [70847]=5,
+ [70848]=5,
+ [70850]=5,
+ [70851]=5,
+ [71090]=5,
+ [71091]=5,
+ [71092]=5,
+ [71093]=5,
+ [71100]=5,
+ [71101]=5,
+ [71103]=5,
+ [71104]=5,
+ [71132]=5,
+ [71133]=5,
+ [71219]=5,
+ [71220]=5,
+ [71221]=5,
+ [71222]=5,
+ [71223]=5,
+ [71224]=5,
+ [71225]=5,
+ [71226]=5,
+ [71229]=5,
+ [71231]=5,
+ [71232]=5,
+ [71339]=5,
+ [71341]=5,
+ [71344]=5,
+ [71345]=5,
+ [71346]=5,
+ [71347]=5,
+ [71348]=5,
+ [71349]=5,
+ [71351]=5,
+ [71453]=5,
+ [71454]=5,
+ [71455]=5,
+ [71458]=5,
+ [71459]=5,
+ [71460]=5,
+ [71461]=5,
+ [71463]=5,
+ [71464]=5,
+ [71465]=5,
+ [71466]=5,
+ [71467]=5,
+ [71727]=5,
+ [71728]=5,
+ [71729]=5,
+ [71730]=5,
+ [71731]=5,
+ [71732]=5,
+ [71733]=5,
+ [71734]=5,
+ [71735]=5,
+ [71737]=5,
+ [71738]=5,
+ [72148]=5,
+ [72149]=5,
+ [72150]=5,
+ [72151]=5,
+ [72154]=5,
+ [72155]=5,
+ [72160]=5,
+ [72193]=5,
+ [72194]=5,
+ [72195]=5,
+ [72196]=5,
+ [72197]=5,
+ [72198]=5,
+ [72201]=5,
+ [72202]=5,
+ [72243]=5,
+ [72244]=5,
+ [72245]=5,
+ [72246]=5,
+ [72247]=5,
+ [72248]=5,
+ [72251]=5,
+ [72252]=5,
+ [72253]=5,
+ [72254]=5,
+ [72263]=5,
+ [72273]=5,
+ [72274]=5,
+ [72275]=5,
+ [72276]=5,
+ [72277]=5,
+ [72278]=5,
+ [72281]=5,
+ [72282]=5,
+ [72283]=5,
+ [72330]=5,
+ [72331]=5,
+ [72332]=5,
+ [72333]=5,
+ [72334]=5,
+ [72335]=5,
+ [72336]=5,
+ [72337]=5,
+ [72338]=5,
+ [72339]=5,
+ [72340]=5,
+ [72341]=5,
+ [72342]=5,
+ [72344]=5,
+ [72345]=5,
+ [72752]=5,
+ [72753]=5,
+ [72754]=5,
+ [72755]=5,
+ [72756]=5,
+ [72757]=5,
+ [72758]=5,
+ [72760]=5,
+ [72761]=5,
+ [72762]=5,
+ [72763]=5,
+ [72764]=5,
+ [72765]=5,
+ [72767]=5,
+ [72850]=5,
+ [72851]=5,
+ [72852]=5,
+ [72853]=5,
+ [72854]=5,
+ [72855]=5,
+ [72856]=5,
+ [72857]=5,
+ [72858]=5,
+ [72859]=5,
+ [72860]=5,
+ [72861]=5,
+ [72862]=5,
+ [72863]=5,
+ [72864]=5,
+ [72865]=5,
+ [72866]=5,
+ [72867]=5,
+ [72868]=5,
+ [72869]=5,
+ [72870]=5,
+ [72871]=5,
+ [72874]=5,
+ [72875]=5,
+ [72876]=5,
+ [72877]=5,
+ [72878]=5,
+ [72879]=5,
+ [72880]=5,
+ [72882]=5,
+ [72883]=5,
+ [72885]=5,
+ [72886]=5,
+ [73009]=5,
+ [73010]=5,
+ [73011]=5,
+ [73012]=5,
+ [73013]=5,
+ [73014]=5,
+ [73018]=5,
+ [73020]=5,
+ [73021]=5,
+ [73023]=5,
+ [73024]=5,
+ [73025]=5,
+ [73026]=5,
+ [73027]=5,
+ [73028]=5,
+ [73029]=5,
+ [73031]=5,
+ [73104]=5,
+ [73105]=5,
+ [73109]=5,
+ [73111]=5,
+ [73459]=5,
+ [73460]=5,
+ [92912]=5,
+ [92913]=5,
+ [92914]=5,
+ [92915]=5,
+ [92916]=5,
+ [92976]=5,
+ [92977]=5,
+ [92978]=5,
+ [92979]=5,
+ [92980]=5,
+ [92981]=5,
+ [92982]=5,
+ [94031]=5,
+ [94095]=5,
+ [94096]=5,
+ [94097]=5,
+ [94098]=5,
+ [113821]=5,
+ [113822]=5,
+ [119143]=5,
+ [119144]=5,
+ [119145]=5,
+ [119163]=5,
+ [119164]=5,
+ [119165]=5,
+ [119166]=5,
+ [119167]=5,
+ [119168]=5,
+ [119169]=5,
+ [119170]=5,
+ [119173]=5,
+ [119174]=5,
+ [119175]=5,
+ [119176]=5,
+ [119177]=5,
+ [119178]=5,
+ [119179]=5,
+ [119210]=5,
+ [119211]=5,
+ [119212]=5,
+ [119213]=5,
+ [119362]=5,
+ [119363]=5,
+ [119364]=5,
+ [121344]=5,
+ [121345]=5,
+ [121346]=5,
+ [121347]=5,
+ [121348]=5,
+ [121349]=5,
+ [121350]=5,
+ [121351]=5,
+ [121352]=5,
+ [121353]=5,
+ [121354]=5,
+ [121355]=5,
+ [121356]=5,
+ [121357]=5,
+ [121358]=5,
+ [121359]=5,
+ [121360]=5,
+ [121361]=5,
+ [121362]=5,
+ [121363]=5,
+ [121364]=5,
+ [121365]=5,
+ [121366]=5,
+ [121367]=5,
+ [121368]=5,
+ [121369]=5,
+ [121370]=5,
+ [121371]=5,
+ [121372]=5,
+ [121373]=5,
+ [121374]=5,
+ [121375]=5,
+ [121376]=5,
+ [121377]=5,
+ [121378]=5,
+ [121379]=5,
+ [121380]=5,
+ [121381]=5,
+ [121382]=5,
+ [121383]=5,
+ [121384]=5,
+ [121385]=5,
+ [121386]=5,
+ [121387]=5,
+ [121388]=5,
+ [121389]=5,
+ [121390]=5,
+ [121391]=5,
+ [121392]=5,
+ [121393]=5,
+ [121394]=5,
+ [121395]=5,
+ [121396]=5,
+ [121397]=5,
+ [121398]=5,
+ [121403]=5,
+ [121404]=5,
+ [121405]=5,
+ [121406]=5,
+ [121407]=5,
+ [121408]=5,
+ [121409]=5,
+ [121410]=5,
+ [121411]=5,
+ [121412]=5,
+ [121413]=5,
+ [121414]=5,
+ [121415]=5,
+ [121416]=5,
+ [121417]=5,
+ [121418]=5,
+ [121419]=5,
+ [121420]=5,
+ [121421]=5,
+ [121422]=5,
+ [121423]=5,
+ [121424]=5,
+ [121425]=5,
+ [121426]=5,
+ [121427]=5,
+ [121428]=5,
+ [121429]=5,
+ [121430]=5,
+ [121431]=5,
+ [121432]=5,
+ [121433]=5,
+ [121434]=5,
+ [121435]=5,
+ [121436]=5,
+ [121437]=5,
+ [121438]=5,
+ [121439]=5,
+ [121440]=5,
+ [121441]=5,
+ [121442]=5,
+ [121443]=5,
+ [121444]=5,
+ [121445]=5,
+ [121446]=5,
+ [121447]=5,
+ [121448]=5,
+ [121449]=5,
+ [121450]=5,
+ [121451]=5,
+ [121452]=5,
+ [121461]=5,
+ [121476]=5,
+ [121499]=5,
+ [121500]=5,
+ [121501]=5,
+ [121502]=5,
+ [121503]=5,
+ [121505]=5,
+ [121506]=5,
+ [121507]=5,
+ [121508]=5,
+ [121509]=5,
+ [121510]=5,
+ [121511]=5,
+ [121512]=5,
+ [121513]=5,
+ [121514]=5,
+ [121515]=5,
+ [121516]=5,
+ [121517]=5,
+ [121518]=5,
+ [121519]=5,
+ [122880]=5,
+ [122881]=5,
+ [122882]=5,
+ [122883]=5,
+ [122884]=5,
+ [122885]=5,
+ [122886]=5,
+ [122888]=5,
+ [122889]=5,
+ [122890]=5,
+ [122891]=5,
+ [122892]=5,
+ [122893]=5,
+ [122894]=5,
+ [122895]=5,
+ [122896]=5,
+ [122897]=5,
+ [122898]=5,
+ [122899]=5,
+ [122900]=5,
+ [122901]=5,
+ [122902]=5,
+ [122903]=5,
+ [122904]=5,
+ [122907]=5,
+ [122908]=5,
+ [122909]=5,
+ [122910]=5,
+ [122911]=5,
+ [122912]=5,
+ [122913]=5,
+ [122915]=5,
+ [122916]=5,
+ [122918]=5,
+ [122919]=5,
+ [122920]=5,
+ [122921]=5,
+ [122922]=5,
+ [123184]=5,
+ [123185]=5,
+ [123186]=5,
+ [123187]=5,
+ [123188]=5,
+ [123189]=5,
+ [123190]=5,
+ [123628]=5,
+ [123629]=5,
+ [123630]=5,
+ [123631]=5,
+ [125136]=5,
+ [125137]=5,
+ [125138]=5,
+ [125139]=5,
+ [125140]=5,
+ [125141]=5,
+ [125142]=5,
+ [125184]=2,
+ [125185]=2,
+ [125186]=2,
+ [125187]=2,
+ [125188]=2,
+ [125189]=2,
+ [125190]=2,
+ [125191]=2,
+ [125192]=2,
+ [125193]=2,
+ [125194]=2,
+ [125195]=2,
+ [125196]=2,
+ [125197]=2,
+ [125198]=2,
+ [125199]=2,
+ [125200]=2,
+ [125201]=2,
+ [125202]=2,
+ [125203]=2,
+ [125204]=2,
+ [125205]=2,
+ [125206]=2,
+ [125207]=2,
+ [125208]=2,
+ [125209]=2,
+ [125210]=2,
+ [125211]=2,
+ [125212]=2,
+ [125213]=2,
+ [125214]=2,
+ [125215]=2,
+ [125216]=2,
+ [125217]=2,
+ [125218]=2,
+ [125219]=2,
+ [125220]=2,
+ [125221]=2,
+ [125222]=2,
+ [125223]=2,
+ [125224]=2,
+ [125225]=2,
+ [125226]=2,
+ [125227]=2,
+ [125228]=2,
+ [125229]=2,
+ [125230]=2,
+ [125231]=2,
+ [125232]=2,
+ [125233]=2,
+ [125234]=2,
+ [125235]=2,
+ [125236]=2,
+ [125237]=2,
+ [125238]=2,
+ [125239]=2,
+ [125240]=2,
+ [125241]=2,
+ [125242]=2,
+ [125243]=2,
+ [125244]=2,
+ [125245]=2,
+ [125246]=2,
+ [125247]=2,
+ [125248]=2,
+ [125249]=2,
+ [125250]=2,
+ [125251]=2,
+ [125252]=5,
+ [125253]=5,
+ [125254]=5,
+ [125255]=5,
+ [125256]=5,
+ [125257]=5,
+ [125258]=5,
+ [1042752]=5,
+}
+
+characters.indicgroups={
+ ["above_mark"]={
+ [2304]=true,
+ [2305]=true,
+ [2306]=true,
+ [2362]=true,
+ [2373]=true,
+ [2374]=true,
+ [2375]=true,
+ [2376]=true,
+ [2385]=true,
+ [2387]=true,
+ [2388]=true,
+ [2389]=true,
+ [2631]=true,
+ [2632]=true,
+ [2635]=true,
+ [2636]=true,
+ [2690]=true,
+ [2757]=true,
+ [2759]=true,
+ [2760]=true,
+ [2879]=true,
+ [3008]=true,
+ [3021]=true,
+ [3134]=true,
+ [3135]=true,
+ [3136]=true,
+ [3142]=true,
+ [3143]=true,
+ [3146]=true,
+ [3147]=true,
+ [3148]=true,
+ [3149]=true,
+ [3263]=true,
+ [3270]=true,
+ [3406]=true,
+ [4141]=true,
+ [4142]=true,
+ [4146]=true,
+ [4147]=true,
+ [4148]=true,
+ [4149]=true,
+ [4150]=true,
+ [4154]=true,
+ [4209]=true,
+ [4210]=true,
+ [4211]=true,
+ [4212]=true,
+ [4229]=true,
+ [4230]=true,
+ [4253]=true,
+ [43232]=true,
+ [43233]=true,
+ [43234]=true,
+ [43235]=true,
+ [43236]=true,
+ [43237]=true,
+ [43238]=true,
+ [43239]=true,
+ [43240]=true,
+ [43241]=true,
+ [43242]=true,
+ [43243]=true,
+ [43244]=true,
+ [43245]=true,
+ [43246]=true,
+ [43247]=true,
+ [43248]=true,
+ [43249]=true,
+ [43493]=true,
+ [43644]=true,
+ },
+ ["after_half"]={},
+ ["after_main"]={
+ [2864]=true,
+ [2879]=true,
+ [2902]=true,
+ [3376]=true,
+ },
+ ["after_postscript"]={
+ [2433]=true,
+ [2494]=true,
+ [2496]=true,
+ [2519]=true,
+ [2561]=true,
+ [2562]=true,
+ [2622]=true,
+ [2624]=true,
+ [2625]=true,
+ [2626]=true,
+ [2672]=true,
+ [2673]=true,
+ [2735]=true,
+ [2750]=true,
+ [2752]=true,
+ [2753]=true,
+ [2754]=true,
+ [2755]=true,
+ [2756]=true,
+ [2761]=true,
+ [2763]=true,
+ [2764]=true,
+ [2786]=true,
+ [2787]=true,
+ [2878]=true,
+ [2880]=true,
+ [2903]=true,
+ [2992]=true,
+ [3006]=true,
+ [3007]=true,
+ [3009]=true,
+ [3010]=true,
+ [3031]=true,
+ [3120]=true,
+ [3248]=true,
+ [3390]=true,
+ [3391]=true,
+ [3392]=true,
+ [3393]=true,
+ [3394]=true,
+ [3395]=true,
+ [3415]=true,
+ },
+ ["after_subscript"]={
+ [2366]=true,
+ [2368]=true,
+ [2369]=true,
+ [2370]=true,
+ [2371]=true,
+ [2372]=true,
+ [2373]=true,
+ [2374]=true,
+ [2375]=true,
+ [2376]=true,
+ [2377]=true,
+ [2378]=true,
+ [2379]=true,
+ [2380]=true,
+ [2402]=true,
+ [2403]=true,
+ [2480]=true,
+ [2497]=true,
+ [2498]=true,
+ [2499]=true,
+ [2500]=true,
+ [2530]=true,
+ [2531]=true,
+ [2544]=true,
+ [2631]=true,
+ [2632]=true,
+ [2635]=true,
+ [2636]=true,
+ [2757]=true,
+ [2759]=true,
+ [2760]=true,
+ [2881]=true,
+ [2882]=true,
+ [2883]=true,
+ [3008]=true,
+ [3139]=true,
+ [3140]=true,
+ [3267]=true,
+ [3268]=true,
+ [3285]=true,
+ [3286]=true,
+ },
+ ["anudatta"]={
+ [2386]=true,
+ },
+ ["before_half"]={
+ [2367]=true,
+ [2382]=true,
+ [2495]=true,
+ [2503]=true,
+ [2504]=true,
+ [2623]=true,
+ [2751]=true,
+ [2887]=true,
+ },
+ ["before_main"]={
+ [3014]=true,
+ [3015]=true,
+ [3016]=true,
+ [3398]=true,
+ [3399]=true,
+ [3400]=true,
+ },
+ ["before_postscript"]={
+ [2352]=true,
+ [2736]=true,
+ },
+ ["before_subscript"]={
+ [2608]=true,
+ [2817]=true,
+ [3134]=true,
+ [3135]=true,
+ [3136]=true,
+ [3137]=true,
+ [3138]=true,
+ [3142]=true,
+ [3143]=true,
+ [3146]=true,
+ [3147]=true,
+ [3148]=true,
+ [3157]=true,
+ [3158]=true,
+ [3262]=true,
+ [3263]=true,
+ [3265]=true,
+ [3266]=true,
+ [3270]=true,
+ [3276]=true,
+ [3298]=true,
+ [3299]=true,
+ },
+ ["below_mark"]={
+ [2364]=true,
+ [2369]=true,
+ [2370]=true,
+ [2371]=true,
+ [2372]=true,
+ [2381]=true,
+ [2386]=true,
+ [2390]=true,
+ [2391]=true,
+ [2402]=true,
+ [2403]=true,
+ [2492]=true,
+ [2497]=true,
+ [2498]=true,
+ [2499]=true,
+ [2500]=true,
+ [2509]=true,
+ [2620]=true,
+ [2625]=true,
+ [2626]=true,
+ [2637]=true,
+ [2748]=true,
+ [2753]=true,
+ [2754]=true,
+ [2755]=true,
+ [2756]=true,
+ [2765]=true,
+ [2876]=true,
+ [2881]=true,
+ [2882]=true,
+ [2883]=true,
+ [2884]=true,
+ [2893]=true,
+ [2914]=true,
+ [2915]=true,
+ [3009]=true,
+ [3010]=true,
+ [3170]=true,
+ [3171]=true,
+ [3260]=true,
+ [3286]=true,
+ [3298]=true,
+ [3299]=true,
+ [3426]=true,
+ [3427]=true,
+ [4143]=true,
+ [4144]=true,
+ [4151]=true,
+ [4153]=true,
+ [4157]=true,
+ [4158]=true,
+ [4184]=true,
+ [4185]=true,
+ [4190]=true,
+ [4191]=true,
+ [4192]=true,
+ [4226]=true,
+ [4237]=true,
+ },
+ ["consonant"]={
+ [2325]=true,
+ [2326]=true,
+ [2327]=true,
+ [2328]=true,
+ [2329]=true,
+ [2330]=true,
+ [2331]=true,
+ [2332]=true,
+ [2333]=true,
+ [2334]=true,
+ [2335]=true,
+ [2336]=true,
+ [2337]=true,
+ [2338]=true,
+ [2339]=true,
+ [2340]=true,
+ [2341]=true,
+ [2342]=true,
+ [2343]=true,
+ [2344]=true,
+ [2345]=true,
+ [2346]=true,
+ [2347]=true,
+ [2348]=true,
+ [2349]=true,
+ [2350]=true,
+ [2351]=true,
+ [2352]=true,
+ [2353]=true,
+ [2354]=true,
+ [2355]=true,
+ [2356]=true,
+ [2357]=true,
+ [2358]=true,
+ [2359]=true,
+ [2360]=true,
+ [2361]=true,
+ [2392]=true,
+ [2393]=true,
+ [2394]=true,
+ [2395]=true,
+ [2396]=true,
+ [2397]=true,
+ [2398]=true,
+ [2399]=true,
+ [2424]=true,
+ [2425]=true,
+ [2426]=true,
+ [2453]=true,
+ [2454]=true,
+ [2455]=true,
+ [2456]=true,
+ [2457]=true,
+ [2458]=true,
+ [2459]=true,
+ [2460]=true,
+ [2461]=true,
+ [2462]=true,
+ [2463]=true,
+ [2464]=true,
+ [2465]=true,
+ [2466]=true,
+ [2467]=true,
+ [2468]=true,
+ [2469]=true,
+ [2470]=true,
+ [2471]=true,
+ [2472]=true,
+ [2474]=true,
+ [2475]=true,
+ [2476]=true,
+ [2477]=true,
+ [2478]=true,
+ [2479]=true,
+ [2480]=true,
+ [2482]=true,
+ [2486]=true,
+ [2487]=true,
+ [2488]=true,
+ [2489]=true,
+ [2510]=true,
+ [2524]=true,
+ [2525]=true,
+ [2527]=true,
+ [2581]=true,
+ [2582]=true,
+ [2583]=true,
+ [2584]=true,
+ [2585]=true,
+ [2586]=true,
+ [2587]=true,
+ [2588]=true,
+ [2589]=true,
+ [2590]=true,
+ [2591]=true,
+ [2592]=true,
+ [2593]=true,
+ [2594]=true,
+ [2595]=true,
+ [2596]=true,
+ [2597]=true,
+ [2598]=true,
+ [2599]=true,
+ [2600]=true,
+ [2602]=true,
+ [2603]=true,
+ [2604]=true,
+ [2605]=true,
+ [2606]=true,
+ [2607]=true,
+ [2608]=true,
+ [2610]=true,
+ [2611]=true,
+ [2613]=true,
+ [2614]=true,
+ [2616]=true,
+ [2617]=true,
+ [2649]=true,
+ [2650]=true,
+ [2651]=true,
+ [2652]=true,
+ [2654]=true,
+ [2709]=true,
+ [2710]=true,
+ [2711]=true,
+ [2712]=true,
+ [2713]=true,
+ [2714]=true,
+ [2715]=true,
+ [2716]=true,
+ [2717]=true,
+ [2718]=true,
+ [2719]=true,
+ [2720]=true,
+ [2721]=true,
+ [2722]=true,
+ [2723]=true,
+ [2724]=true,
+ [2725]=true,
+ [2726]=true,
+ [2727]=true,
+ [2728]=true,
+ [2730]=true,
+ [2731]=true,
+ [2732]=true,
+ [2733]=true,
+ [2734]=true,
+ [2735]=true,
+ [2736]=true,
+ [2738]=true,
+ [2739]=true,
+ [2741]=true,
+ [2742]=true,
+ [2743]=true,
+ [2744]=true,
+ [2745]=true,
+ [2837]=true,
+ [2838]=true,
+ [2839]=true,
+ [2840]=true,
+ [2841]=true,
+ [2842]=true,
+ [2843]=true,
+ [2844]=true,
+ [2845]=true,
+ [2846]=true,
+ [2847]=true,
+ [2848]=true,
+ [2849]=true,
+ [2850]=true,
+ [2851]=true,
+ [2852]=true,
+ [2853]=true,
+ [2854]=true,
+ [2855]=true,
+ [2856]=true,
+ [2858]=true,
+ [2859]=true,
+ [2860]=true,
+ [2861]=true,
+ [2862]=true,
+ [2863]=true,
+ [2864]=true,
+ [2866]=true,
+ [2867]=true,
+ [2869]=true,
+ [2870]=true,
+ [2871]=true,
+ [2872]=true,
+ [2873]=true,
+ [2908]=true,
+ [2909]=true,
+ [2929]=true,
+ [2965]=true,
+ [2969]=true,
+ [2970]=true,
+ [2972]=true,
+ [2974]=true,
+ [2975]=true,
+ [2979]=true,
+ [2980]=true,
+ [2984]=true,
+ [2985]=true,
+ [2986]=true,
+ [2990]=true,
+ [2991]=true,
+ [2992]=true,
+ [2993]=true,
+ [2994]=true,
+ [2995]=true,
+ [2996]=true,
+ [2997]=true,
+ [2998]=true,
+ [2999]=true,
+ [3000]=true,
+ [3001]=true,
+ [3093]=true,
+ [3094]=true,
+ [3095]=true,
+ [3096]=true,
+ [3097]=true,
+ [3098]=true,
+ [3099]=true,
+ [3100]=true,
+ [3101]=true,
+ [3102]=true,
+ [3103]=true,
+ [3104]=true,
+ [3105]=true,
+ [3106]=true,
+ [3107]=true,
+ [3108]=true,
+ [3109]=true,
+ [3110]=true,
+ [3111]=true,
+ [3112]=true,
+ [3114]=true,
+ [3115]=true,
+ [3116]=true,
+ [3117]=true,
+ [3118]=true,
+ [3119]=true,
+ [3120]=true,
+ [3121]=true,
+ [3122]=true,
+ [3123]=true,
+ [3124]=true,
+ [3125]=true,
+ [3126]=true,
+ [3127]=true,
+ [3128]=true,
+ [3129]=true,
+ [3133]=true,
+ [3221]=true,
+ [3222]=true,
+ [3223]=true,
+ [3224]=true,
+ [3225]=true,
+ [3226]=true,
+ [3227]=true,
+ [3228]=true,
+ [3229]=true,
+ [3230]=true,
+ [3231]=true,
+ [3232]=true,
+ [3233]=true,
+ [3234]=true,
+ [3235]=true,
+ [3236]=true,
+ [3237]=true,
+ [3238]=true,
+ [3239]=true,
+ [3240]=true,
+ [3242]=true,
+ [3243]=true,
+ [3244]=true,
+ [3245]=true,
+ [3246]=true,
+ [3247]=true,
+ [3248]=true,
+ [3249]=true,
+ [3250]=true,
+ [3251]=true,
+ [3253]=true,
+ [3254]=true,
+ [3255]=true,
+ [3256]=true,
+ [3257]=true,
+ [3294]=true,
+ [3349]=true,
+ [3350]=true,
+ [3351]=true,
+ [3352]=true,
+ [3353]=true,
+ [3354]=true,
+ [3355]=true,
+ [3356]=true,
+ [3357]=true,
+ [3358]=true,
+ [3359]=true,
+ [3360]=true,
+ [3361]=true,
+ [3362]=true,
+ [3363]=true,
+ [3364]=true,
+ [3365]=true,
+ [3366]=true,
+ [3367]=true,
+ [3368]=true,
+ [3369]=true,
+ [3370]=true,
+ [3371]=true,
+ [3372]=true,
+ [3373]=true,
+ [3374]=true,
+ [3375]=true,
+ [3376]=true,
+ [3377]=true,
+ [3378]=true,
+ [3379]=true,
+ [3380]=true,
+ [3381]=true,
+ [3382]=true,
+ [3383]=true,
+ [3384]=true,
+ [3385]=true,
+ [3386]=true,
+ [4096]=true,
+ [4097]=true,
+ [4098]=true,
+ [4099]=true,
+ [4100]=true,
+ [4101]=true,
+ [4102]=true,
+ [4103]=true,
+ [4104]=true,
+ [4105]=true,
+ [4106]=true,
+ [4107]=true,
+ [4108]=true,
+ [4109]=true,
+ [4110]=true,
+ [4111]=true,
+ [4112]=true,
+ [4113]=true,
+ [4114]=true,
+ [4115]=true,
+ [4116]=true,
+ [4117]=true,
+ [4118]=true,
+ [4119]=true,
+ [4120]=true,
+ [4121]=true,
+ [4122]=true,
+ [4123]=true,
+ [4124]=true,
+ [4125]=true,
+ [4126]=true,
+ [4127]=true,
+ [4128]=true,
+ [4155]=true,
+ [4156]=true,
+ [4157]=true,
+ [4158]=true,
+ [4159]=true,
+ [4176]=true,
+ [4177]=true,
+ [4186]=true,
+ [4187]=true,
+ [4188]=true,
+ [4189]=true,
+ [4190]=true,
+ [4191]=true,
+ [4192]=true,
+ [4193]=true,
+ [4197]=true,
+ [4198]=true,
+ [4206]=true,
+ [4207]=true,
+ [4208]=true,
+ [4213]=true,
+ [4214]=true,
+ [4215]=true,
+ [4216]=true,
+ [4217]=true,
+ [4218]=true,
+ [4219]=true,
+ [4220]=true,
+ [4221]=true,
+ [4222]=true,
+ [4223]=true,
+ [4224]=true,
+ [4225]=true,
+ [4226]=true,
+ [4238]=true,
+ [43488]=true,
+ [43489]=true,
+ [43490]=true,
+ [43491]=true,
+ [43492]=true,
+ [43495]=true,
+ [43496]=true,
+ [43497]=true,
+ [43498]=true,
+ [43499]=true,
+ [43500]=true,
+ [43501]=true,
+ [43502]=true,
+ [43503]=true,
+ [43514]=true,
+ [43515]=true,
+ [43516]=true,
+ [43517]=true,
+ [43518]=true,
+ [43616]=true,
+ [43617]=true,
+ [43618]=true,
+ [43619]=true,
+ [43620]=true,
+ [43621]=true,
+ [43622]=true,
+ [43623]=true,
+ [43624]=true,
+ [43625]=true,
+ [43626]=true,
+ [43628]=true,
+ [43629]=true,
+ [43630]=true,
+ [43631]=true,
+ [43633]=true,
+ [43634]=true,
+ [43635]=true,
+ [43636]=true,
+ [43637]=true,
+ [43638]=true,
+ [43642]=true,
+ [43646]=true,
+ [43647]=true,
+ },
+ ["dependent_vowel"]={
+ [2362]=true,
+ [2363]=true,
+ [2366]=true,
+ [2367]=true,
+ [2368]=true,
+ [2369]=true,
+ [2370]=true,
+ [2371]=true,
+ [2372]=true,
+ [2373]=true,
+ [2374]=true,
+ [2375]=true,
+ [2376]=true,
+ [2377]=true,
+ [2378]=true,
+ [2379]=true,
+ [2380]=true,
+ [2382]=true,
+ [2383]=true,
+ [2389]=true,
+ [2390]=true,
+ [2391]=true,
+ [2402]=true,
+ [2403]=true,
+ [2494]=true,
+ [2495]=true,
+ [2497]=true,
+ [2498]=true,
+ [2499]=true,
+ [2500]=true,
+ [2503]=true,
+ [2504]=true,
+ [2507]=true,
+ [2508]=true,
+ [2622]=true,
+ [2623]=true,
+ [2624]=true,
+ [2625]=true,
+ [2626]=true,
+ [2631]=true,
+ [2632]=true,
+ [2635]=true,
+ [2636]=true,
+ [2750]=true,
+ [2751]=true,
+ [2752]=true,
+ [2753]=true,
+ [2754]=true,
+ [2755]=true,
+ [2756]=true,
+ [2757]=true,
+ [2759]=true,
+ [2760]=true,
+ [2761]=true,
+ [2763]=true,
+ [2764]=true,
+ [2878]=true,
+ [2879]=true,
+ [2880]=true,
+ [2881]=true,
+ [2882]=true,
+ [2883]=true,
+ [2884]=true,
+ [2887]=true,
+ [2888]=true,
+ [2891]=true,
+ [2892]=true,
+ [2914]=true,
+ [2915]=true,
+ [3006]=true,
+ [3007]=true,
+ [3008]=true,
+ [3009]=true,
+ [3010]=true,
+ [3014]=true,
+ [3015]=true,
+ [3016]=true,
+ [3018]=true,
+ [3019]=true,
+ [3020]=true,
+ [3134]=true,
+ [3135]=true,
+ [3136]=true,
+ [3137]=true,
+ [3138]=true,
+ [3139]=true,
+ [3140]=true,
+ [3142]=true,
+ [3143]=true,
+ [3144]=true,
+ [3146]=true,
+ [3147]=true,
+ [3148]=true,
+ [3170]=true,
+ [3171]=true,
+ [3262]=true,
+ [3263]=true,
+ [3264]=true,
+ [3265]=true,
+ [3266]=true,
+ [3267]=true,
+ [3268]=true,
+ [3270]=true,
+ [3271]=true,
+ [3272]=true,
+ [3274]=true,
+ [3275]=true,
+ [3276]=true,
+ [3285]=true,
+ [3286]=true,
+ [3298]=true,
+ [3299]=true,
+ [3390]=true,
+ [3391]=true,
+ [3392]=true,
+ [3393]=true,
+ [3394]=true,
+ [3395]=true,
+ [3396]=true,
+ [3398]=true,
+ [3399]=true,
+ [3400]=true,
+ [3402]=true,
+ [3403]=true,
+ [3404]=true,
+ [3415]=true,
+ [3426]=true,
+ [3427]=true,
+ [4139]=true,
+ [4140]=true,
+ [4141]=true,
+ [4142]=true,
+ [4143]=true,
+ [4144]=true,
+ [4145]=true,
+ [4146]=true,
+ [4147]=true,
+ [4148]=true,
+ [4149]=true,
+ [4182]=true,
+ [4183]=true,
+ [4184]=true,
+ [4185]=true,
+ [4194]=true,
+ [4199]=true,
+ [4200]=true,
+ [4209]=true,
+ [4210]=true,
+ [4211]=true,
+ [4212]=true,
+ [4227]=true,
+ [4228]=true,
+ [4229]=true,
+ [4230]=true,
+ [4252]=true,
+ [4253]=true,
+ [43493]=true,
+ },
+ ["halant"]={
+ [2381]=true,
+ [2509]=true,
+ [2637]=true,
+ [2765]=true,
+ [2893]=true,
+ [3021]=true,
+ [3149]=true,
+ [3277]=true,
+ [3405]=true,
+ },
+ ["independent_vowel"]={
+ [2308]=true,
+ [2309]=true,
+ [2310]=true,
+ [2311]=true,
+ [2312]=true,
+ [2313]=true,
+ [2314]=true,
+ [2315]=true,
+ [2316]=true,
+ [2317]=true,
+ [2318]=true,
+ [2319]=true,
+ [2320]=true,
+ [2321]=true,
+ [2322]=true,
+ [2323]=true,
+ [2324]=true,
+ [2400]=true,
+ [2401]=true,
+ [2418]=true,
+ [2419]=true,
+ [2420]=true,
+ [2421]=true,
+ [2422]=true,
+ [2423]=true,
+ [2437]=true,
+ [2438]=true,
+ [2439]=true,
+ [2440]=true,
+ [2441]=true,
+ [2442]=true,
+ [2443]=true,
+ [2444]=true,
+ [2447]=true,
+ [2448]=true,
+ [2451]=true,
+ [2452]=true,
+ [2528]=true,
+ [2529]=true,
+ [2530]=true,
+ [2531]=true,
+ [2565]=true,
+ [2566]=true,
+ [2567]=true,
+ [2568]=true,
+ [2569]=true,
+ [2570]=true,
+ [2575]=true,
+ [2576]=true,
+ [2579]=true,
+ [2580]=true,
+ [2693]=true,
+ [2694]=true,
+ [2695]=true,
+ [2696]=true,
+ [2697]=true,
+ [2698]=true,
+ [2699]=true,
+ [2700]=true,
+ [2701]=true,
+ [2703]=true,
+ [2704]=true,
+ [2705]=true,
+ [2707]=true,
+ [2708]=true,
+ [2784]=true,
+ [2785]=true,
+ [2786]=true,
+ [2787]=true,
+ [2821]=true,
+ [2822]=true,
+ [2823]=true,
+ [2824]=true,
+ [2825]=true,
+ [2826]=true,
+ [2827]=true,
+ [2828]=true,
+ [2831]=true,
+ [2832]=true,
+ [2835]=true,
+ [2836]=true,
+ [2912]=true,
+ [2913]=true,
+ [2949]=true,
+ [2950]=true,
+ [2951]=true,
+ [2952]=true,
+ [2953]=true,
+ [2954]=true,
+ [2958]=true,
+ [2959]=true,
+ [2960]=true,
+ [2962]=true,
+ [2963]=true,
+ [2964]=true,
+ [3077]=true,
+ [3078]=true,
+ [3079]=true,
+ [3080]=true,
+ [3081]=true,
+ [3082]=true,
+ [3083]=true,
+ [3084]=true,
+ [3086]=true,
+ [3087]=true,
+ [3088]=true,
+ [3090]=true,
+ [3091]=true,
+ [3092]=true,
+ [3168]=true,
+ [3169]=true,
+ [3205]=true,
+ [3206]=true,
+ [3207]=true,
+ [3208]=true,
+ [3209]=true,
+ [3210]=true,
+ [3211]=true,
+ [3212]=true,
+ [3214]=true,
+ [3215]=true,
+ [3216]=true,
+ [3218]=true,
+ [3219]=true,
+ [3220]=true,
+ [3296]=true,
+ [3297]=true,
+ [3333]=true,
+ [3334]=true,
+ [3335]=true,
+ [3336]=true,
+ [3337]=true,
+ [3338]=true,
+ [3339]=true,
+ [3340]=true,
+ [3342]=true,
+ [3343]=true,
+ [3344]=true,
+ [3346]=true,
+ [3347]=true,
+ [3348]=true,
+ [3423]=true,
+ [3424]=true,
+ [3425]=true,
+ [4129]=true,
+ [4130]=true,
+ [4131]=true,
+ [4132]=true,
+ [4133]=true,
+ [4134]=true,
+ [4135]=true,
+ [4136]=true,
+ [4137]=true,
+ [4138]=true,
+ [4178]=true,
+ [4179]=true,
+ [4180]=true,
+ [4181]=true,
+ },
+ ["nukta"]={
+ [2364]=true,
+ [2492]=true,
+ [2620]=true,
+ [2748]=true,
+ [2876]=true,
+ [3260]=true,
+ },
+ ["post_mark"]={
+ [2307]=true,
+ [2363]=true,
+ [2366]=true,
+ [2368]=true,
+ [2377]=true,
+ [2378]=true,
+ [2379]=true,
+ [2380]=true,
+ [2383]=true,
+ [2494]=true,
+ [2496]=true,
+ [2622]=true,
+ [2624]=true,
+ [2750]=true,
+ [2752]=true,
+ [2761]=true,
+ [2763]=true,
+ [2764]=true,
+ [2878]=true,
+ [2880]=true,
+ [3006]=true,
+ [3007]=true,
+ [3137]=true,
+ [3138]=true,
+ [3139]=true,
+ [3140]=true,
+ [3262]=true,
+ [3265]=true,
+ [3266]=true,
+ [3267]=true,
+ [3268]=true,
+ [3276]=true,
+ [3285]=true,
+ [3390]=true,
+ [3391]=true,
+ [3392]=true,
+ [3393]=true,
+ [3394]=true,
+ [3395]=true,
+ [3396]=true,
+ [3415]=true,
+ [4139]=true,
+ [4140]=true,
+ [4152]=true,
+ [4155]=true,
+ [4182]=true,
+ [4183]=true,
+ [4194]=true,
+ [4195]=true,
+ [4196]=true,
+ [4199]=true,
+ [4200]=true,
+ [4201]=true,
+ [4202]=true,
+ [4203]=true,
+ [4204]=true,
+ [4205]=true,
+ [4227]=true,
+ [4231]=true,
+ [4232]=true,
+ [4233]=true,
+ [4234]=true,
+ [4235]=true,
+ [4236]=true,
+ [4239]=true,
+ [4250]=true,
+ [4251]=true,
+ [4252]=true,
+ [43643]=true,
+ [43645]=true,
+ },
+ ["pre_mark"]={
+ [2367]=true,
+ [2382]=true,
+ [2495]=true,
+ [2503]=true,
+ [2504]=true,
+ [2623]=true,
+ [2751]=true,
+ [2887]=true,
+ [3014]=true,
+ [3015]=true,
+ [3016]=true,
+ [3398]=true,
+ [3399]=true,
+ [3400]=true,
+ [4145]=true,
+ [4228]=true,
+ },
+ ["ra"]={
+ [2352]=true,
+ [2480]=true,
+ [2544]=true,
+ [2608]=true,
+ [2736]=true,
+ [2864]=true,
+ [2992]=true,
+ [3120]=true,
+ [3248]=true,
+ [3376]=true,
+ },
+ ["stress_tone_mark"]={
+ [2385]=true,
+ [2386]=true,
+ [2387]=true,
+ [2388]=true,
+ [4151]=true,
+ [4195]=true,
+ [4196]=true,
+ [4201]=true,
+ [4202]=true,
+ [4203]=true,
+ [4204]=true,
+ [4205]=true,
+ [4231]=true,
+ [4232]=true,
+ [4233]=true,
+ [4234]=true,
+ [4235]=true,
+ [4236]=true,
+ [4237]=true,
+ [4239]=true,
+ [4250]=true,
+ [4251]=true,
+ [43643]=true,
+ [43644]=true,
+ [43645]=true,
+ },
+ ["twopart_mark"]={
+ [2507]={ 2503, 2494 },
+ [2508]={ 2503, 2519 },
+ [2888]={ 2887, 2902 },
+ [2891]={ 2887, 2878 },
+ [2892]={ 2887, 2903 },
+ [3018]={ 3014, 3006 },
+ [3019]={ 3015, 3006 },
+ [3020]={ 3014, 3031 },
+ [3144]={ 3142, 3158 },
+ [3264]={ 3263, 3285 },
+ [3271]={ 3270, 3285 },
+ [3272]={ 3270, 3286 },
+ [3274]={ 3270, 3266 },
+ [3275]={ 3274, 3285 },
+ [3402]={ 3398, 3390 },
+ [3403]={ 3399, 3390 },
+ [3404]={ 3398, 3415 },
+ },
+ ["vowel_modifier"]={
+ [2304]=true,
+ [2305]=true,
+ [2306]=true,
+ [2307]=true,
+ [2433]=true,
+ [3330]=true,
+ [3331]=true,
+ [4150]=true,
+ [4152]=true,
+ [4153]=true,
+ [4154]=true,
+ [43232]=true,
+ [43233]=true,
+ [43234]=true,
+ [43235]=true,
+ [43236]=true,
+ [43237]=true,
+ [43238]=true,
+ [43239]=true,
+ [43240]=true,
+ [43241]=true,
+ [43242]=true,
+ [43243]=true,
+ [43244]=true,
+ [43245]=true,
+ [43246]=true,
+ [43247]=true,
+ [43249]=true,
+ },
+}
+
+-- done, uncomment for testing:
+
+-- return characters.indicgroups
diff --git a/macros/luatex/generic/luaotfload/fontloader-basics-gen.lua b/macros/luatex/generic/luaotfload/fontloader-basics-gen.lua
new file mode 100644
index 0000000000..3959ca0222
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-basics-gen.lua
@@ -0,0 +1,479 @@
+if not modules then modules = { } end modules ['luat-basics-gen'] = {
+ version = 1.100,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+if context then
+ os.exit()
+end
+
+-- We could load a few more of the general context libraries but it would
+-- not make plain / latex users more happy I guess. So, we stick to some
+-- placeholders.
+
+local match, gmatch, gsub, lower = string.match, string.gmatch, string.gsub, string.lower
+local formatters, split, format, dump = string.formatters, string.split, string.format, string.dump
+local loadfile, type = loadfile, type
+local setmetatable, getmetatable, collectgarbage = setmetatable, getmetatable, collectgarbage
+local floor = math.floor
+
+local dummyfunction = function()
+end
+
+local dummyreporter = function(c)
+ return function(f,...)
+ local r = texio.reporter or texio.write_nl
+ if f then
+ r(c .. " : " .. (formatters or format)(f,...))
+ else
+ r("")
+ end
+ end
+end
+
+local dummyreport = function(c,f,...)
+ local r = texio.reporter or texio.write_nl
+ if f then
+ r(c .. " : " .. (formatters or format)(f,...))
+ else
+ r("")
+ end
+end
+
+statistics = {
+ register = dummyfunction,
+ starttiming = dummyfunction,
+ stoptiming = dummyfunction,
+ elapsedtime = nil,
+}
+
+directives = {
+ register = dummyfunction,
+ enable = dummyfunction,
+ disable = dummyfunction,
+}
+
+trackers = {
+ register = dummyfunction,
+ enable = dummyfunction,
+ disable = dummyfunction,
+}
+
+experiments = {
+ register = dummyfunction,
+ enable = dummyfunction,
+ disable = dummyfunction,
+}
+
+storage = { -- probably no longer needed
+ register = dummyfunction,
+ shared = { },
+}
+
+logs = {
+ new = dummyreporter,
+ reporter = dummyreporter,
+ messenger = dummyreporter,
+ report = dummyreport,
+}
+
+callbacks = {
+ register = function(n,f)
+ return callback.register(n,f)
+ end,
+}
+
+utilities = utilities or { }
+
+utilities.storage = utilities.storage or {
+ allocate = function(t)
+ return t or { }
+ end,
+ mark = function(t)
+ return t or { }
+ end,
+}
+
+utilities.parsers = utilities.parsers or {
+ -- these are less flexible than in context but ok
+ -- for generic purpose
+ settings_to_array = function(s)
+ return split(s,",")
+ end,
+ settings_to_hash = function(s)
+ local t = { }
+ for k, v in gmatch(s,"([^%s,=]+)=([^%s,]+)") do
+ t[k] = v
+ end
+ return t
+ end,
+ settings_to_hash_colon_too = function(s)
+ local t = { }
+ for k, v in gmatch(s,"([^%s,=:]+)[=:]([^%s,]+)") do
+ t[k] = v
+ end
+ return t
+ end,
+}
+
+characters = characters or {
+ data = { }
+}
+
+-- we need to cheat a bit here
+
+texconfig.kpse_init = true
+
+resolvers = resolvers or { } -- no fancy file helpers used
+
+local remapper = {
+ otf = "opentype fonts",
+ ttf = "truetype fonts",
+ ttc = "truetype fonts",
+ cid = "cid maps",
+ cidmap = "cid maps",
+ -- fea = "font feature files", -- no longer supported
+ pfb = "type1 fonts", -- needed for vector loading
+ afm = "afm",
+ enc = "enc files",
+ lua = "tex",
+}
+
+function resolvers.findfile(name,fileformat)
+ name = gsub(name,"\\","/")
+ if not fileformat or fileformat == "" then
+ fileformat = file.suffix(name)
+ if fileformat == "" then
+ fileformat = "tex"
+ end
+ end
+ fileformat = lower(fileformat)
+ fileformat = remapper[fileformat] or fileformat
+ local found = kpse.find_file(name,fileformat)
+ if not found or found == "" then
+ found = kpse.find_file(name,"other text files")
+ end
+ return found
+end
+
+resolvers.findbinfile = resolvers.findfile
+
+function resolvers.loadbinfile(filename,filetype)
+ local data = io.loaddata(filename)
+ return true, data, #data
+end
+
+function resolvers.resolve(s)
+ return s
+end
+
+function resolvers.unresolve(s)
+ return s
+end
+
+-- Caches ... I will make a real stupid version some day when I'm in the
+-- mood. After all, the generic code does not need the more advanced
+-- ConTeXt features. Cached data is not shared between ConTeXt and other
+-- usage as I don't want any dependency at all. Also, ConTeXt might have
+-- different needs and tricks added.
+
+--~ containers.usecache = true
+
+caches = { }
+
+local writable = nil
+local readables = { }
+local usingjit = jit
+
+if not caches.namespace or caches.namespace == "" or caches.namespace == "context" then
+ caches.namespace = 'generic'
+end
+
+do
+
+ -- standard context tree setup
+
+ local cachepaths = kpse.expand_var('$TEXMFCACHE') or ""
+
+ -- quite like tex live or so (the weird $TEXMFCACHE test seems to be needed on miktex)
+
+ if cachepaths == "" or cachepaths == "$TEXMFCACHE" then
+ cachepaths = kpse.expand_var('$TEXMFVAR') or ""
+ end
+
+ -- this also happened to be used (the weird $TEXMFVAR test seems to be needed on miktex)
+
+ if cachepaths == "" or cachepaths == "$TEXMFVAR" then
+ cachepaths = kpse.expand_var('$VARTEXMF') or ""
+ end
+
+ -- and this is a last resort (hm, we could use TEMP or TEMPDIR)
+
+ if cachepaths == "" then
+ local fallbacks = { "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" }
+ for i=1,#fallbacks do
+ cachepaths = os.getenv(fallbacks[i]) or ""
+ if cachepath ~= "" and lfs.isdir(cachepath) then
+ break
+ end
+ end
+ end
+
+ if cachepaths == "" then
+ cachepaths = "."
+ end
+
+ cachepaths = split(cachepaths,os.type == "windows" and ";" or ":")
+
+ for i=1,#cachepaths do
+ local cachepath = cachepaths[i]
+ if not lfs.isdir(cachepath) then
+ lfs.mkdirs(cachepath) -- needed for texlive and latex
+ if lfs.isdir(cachepath) then
+ logs.report("system","creating cache path '%s'",cachepath)
+ end
+ end
+ if file.is_writable(cachepath) then
+ writable = file.join(cachepath,"luatex-cache")
+ lfs.mkdir(writable)
+ writable = file.join(writable,caches.namespace)
+ lfs.mkdir(writable)
+ break
+ end
+ end
+
+ for i=1,#cachepaths do
+ if file.is_readable(cachepaths[i]) then
+ readables[#readables+1] = file.join(cachepaths[i],"luatex-cache",caches.namespace)
+ end
+ end
+
+ if not writable then
+ logs.report("system","no writeable cache path, quiting")
+ os.exit()
+ elseif #readables == 0 then
+ logs.report("system","no readable cache path, quiting")
+ os.exit()
+ elseif #readables == 1 and readables[1] == writable then
+ logs.report("system","using cache '%s'",writable)
+ else
+ logs.report("system","using write cache '%s'",writable)
+ logs.report("system","using read cache '%s'",table.concat(readables," "))
+ end
+
+end
+
+function caches.getwritablepath(category,subcategory)
+ local path = file.join(writable,category)
+ lfs.mkdir(path)
+ path = file.join(path,subcategory)
+ lfs.mkdir(path)
+ return path
+end
+
+function caches.getreadablepaths(category,subcategory)
+ local t = { }
+ for i=1,#readables do
+ t[i] = file.join(readables[i],category,subcategory)
+ end
+ return t
+end
+
+local function makefullname(path,name)
+ if path and path ~= "" then
+ return file.addsuffix(file.join(path,name),"lua"), file.addsuffix(file.join(path,name),usingjit and "lub" or "luc")
+ end
+end
+
+function caches.is_writable(path,name)
+ local fullname = makefullname(path,name)
+ return fullname and file.is_writable(fullname)
+end
+
+function caches.loaddata(readables,name,writable)
+ for i=1,#readables do
+ local path = readables[i]
+ local loader = false
+ local luaname, lucname = makefullname(path,name)
+ if lfs.isfile(lucname) then
+ logs.report("system","loading luc file '%s'",lucname)
+ loader = loadfile(lucname)
+ end
+ if not loader and lfs.isfile(luaname) then
+ -- can be different paths when we read a file database from disk
+ local luacrap, lucname = makefullname(writable,name)
+ logs.report("system","compiling luc file '%s'",lucname)
+ if lfs.isfile(lucname) then
+ loader = loadfile(lucname)
+ end
+ caches.compile(data,luaname,lucname)
+ if lfs.isfile(lucname) then
+ logs.report("system","loading luc file '%s'",lucname)
+ loader = loadfile(lucname)
+ else
+ logs.report("system","error in loading luc file '%s'",lucname)
+ end
+ if not loader then
+ logs.report("system","loading lua file '%s'",luaname)
+ loader = loadfile(luaname)
+ else
+ logs.report("system","error in loading lua file '%s'",luaname)
+ end
+ end
+ if loader then
+ loader = loader()
+ collectgarbage("step")
+ return loader
+ end
+ end
+ return false
+end
+
+function caches.savedata(path,name,data)
+ local luaname, lucname = makefullname(path,name)
+ if luaname then
+ logs.report("system","saving lua file '%s'",luaname)
+ table.tofile(luaname,data,true)
+ if lucname and type(caches.compile) == "function" then
+ os.remove(lucname) -- better be safe
+ logs.report("system","saving luc file '%s'",lucname)
+ caches.compile(data,luaname,lucname)
+ end
+ end
+end
+
+-- The method here is slightly different from the one we have in context. We
+-- also use different suffixes as we don't want any clashes (sharing cache
+-- files is not that handy as context moves on faster.)
+
+function caches.compile(data,luaname,lucname)
+ local d = io.loaddata(luaname)
+ if not d or d == "" then
+ d = table.serialize(data,true) -- slow
+ end
+ if d and d ~= "" then
+ local f = io.open(lucname,'wb')
+ if f then
+ local s = loadstring(d)
+ if s then
+ f:write(dump(s,true))
+ end
+ f:close()
+ end
+ end
+end
+
+-- simplfied version:
+
+function table.setmetatableindex(t,f)
+ if type(t) ~= "table" then
+ f, t = t, { }
+ end
+ local m = getmetatable(t)
+ if f == "table" then
+ f = function(t,k) local v = { } t[k] = v return v end
+ end
+ if m then
+ m.__index = f
+ else
+ setmetatable(t,{ __index = f })
+ end
+ return t
+end
+
+function table.makeweak(t)
+ local m = getmetatable(t)
+ if m then
+ m.__mode = "v"
+ else
+ setmetatable(t,{ __mode = "v" })
+ end
+ return t
+end
+
+-- helper for plain:
+
+arguments = { }
+
+if arg then
+ for i=1,#arg do
+ local k, v = match(arg[i],"^%-%-([^=]+)=?(.-)$")
+ if k and v then
+ arguments[k] = v
+ end
+ end
+end
+
+-- another one
+
+if not number.idiv then
+ function number.idiv(i,d)
+ return floor(i/d) -- i//d in 5.3
+ end
+end
+
+-- hook into unicode
+
+local u = unicode and unicode.utf8
+
+if u then
+
+ utf.lower = u.lower
+ utf.upper = u.upper
+ utf.char = u.char
+ utf.byte = u.byte
+ utf.len = u.len
+
+ -- needed on font-*
+
+ if lpeg.setutfcasers then
+ lpeg.setutfcasers(u.lower,u.upper)
+ end
+
+ -- needed on font-otr
+
+ local bytepairs = string.bytepairs
+ local utfchar = utf.char
+ local concat = table.concat
+
+ function utf.utf16_to_utf8_be(s)
+ if not s then
+ return nil
+ elseif s == "" then
+ return ""
+ end
+ local result, r, more = { }, 0, 0
+ for left, right in bytepairs(s) do
+ if right then
+ local now = 256*left + right
+ if more > 0 then
+ now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000
+ more = 0
+ r = r + 1
+ result[r] = utfchar(now)
+ elseif now >= 0xD800 and now <= 0xDBFF then
+ more = now
+ else
+ r = r + 1
+ result[r] = utfchar(now)
+ end
+ end
+ end
+ return concat(result)
+ end
+
+ local characters = string.utfcharacters
+
+ function utf.split(str)
+ local t, n = { }, 0
+ for s in characters(str) do
+ n = n + 1
+ t[n] = s
+ end
+ return t
+ end
+
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua b/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua
new file mode 100644
index 0000000000..418b9d69d4
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua
@@ -0,0 +1,263 @@
+if not modules then modules = { } end modules ['luatex-fonts-nod'] = {
+ version = 1.001,
+ comment = "companion to luatex-fonts.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+if context then
+ os.exit()
+end
+
+-- Don't depend on code here as it is only needed to complement the font handler
+-- code. I will move some to another namespace as I don't see other macro packages
+-- use the context logic. It's a subset anyway. More will be stripped.
+
+-- Attributes:
+
+if tex.attribute[0] ~= 0 then
+
+ texio.write_nl("log","!")
+ texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be")
+ texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special")
+ texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.")
+ texio.write_nl("log","!")
+
+ tex.attribute[0] = 0 -- else no features
+
+end
+
+attributes = attributes or { }
+attributes.unsetvalue = -0x7FFFFFFF
+
+local numbers, last = { }, 127
+
+attributes.private = attributes.private or function(name)
+ local number = numbers[name]
+ if not number then
+ if last < 255 then
+ last = last + 1
+ end
+ number = last
+ numbers[name] = number
+ end
+ return number
+end
+
+-- Nodes (a subset of context so that we don't get too much unused code):
+
+nodes = { }
+nodes.handlers = { }
+
+local nodecodes = { }
+local glyphcodes = node.subtypes("glyph")
+local disccodes = node.subtypes("disc")
+
+for k, v in next, node.types() do
+ v = string.gsub(v,"_","")
+ nodecodes[k] = v
+ nodecodes[v] = k
+end
+for k, v in next, glyphcodes do
+ glyphcodes[v] = k
+end
+for k, v in next, disccodes do
+ disccodes[v] = k
+end
+
+nodes.nodecodes = nodecodes
+nodes.glyphcodes = glyphcodes
+nodes.disccodes = disccodes
+
+nodes.handlers.protectglyphs = node.protect_glyphs -- beware: nodes!
+nodes.handlers.unprotectglyphs = node.unprotect_glyphs -- beware: nodes!
+
+-- in generic code, at least for some time, we stay nodes, while in context
+-- we can go nuts (e.g. experimental); this split permits us us keep code
+-- used elsewhere stable but at the same time play around in context
+
+-- much of this will go away .. it's part of the context interface and not
+-- officially in luatex-*.lua
+
+local direct = node.direct
+local nuts = { }
+nodes.nuts = nuts
+
+local tonode = direct.tonode
+local tonut = direct.todirect
+
+nodes.tonode = tonode
+nodes.tonut = tonut
+
+nuts.tonode = tonode
+nuts.tonut = tonut
+
+nuts.getattr = direct.get_attribute
+nuts.getboth = direct.getboth
+nuts.getchar = direct.getchar
+nuts.getcomponents = direct.getcomponents
+nuts.getdirection = direct.getdirection
+nuts.getdisc = direct.getdisc
+nuts.getfield = direct.getfield
+nuts.getfont = direct.getfont
+nuts.getid = direct.getid
+nuts.getkern = direct.getkern
+nuts.getlist = direct.getlist
+nuts.getnext = direct.getnext
+nuts.getoffsets = direct.getoffsets
+nuts.getprev = direct.getprev
+nuts.getsubtype = direct.getsubtype
+nuts.getwidth = direct.getwidth
+nuts.setattr = direct.setfield
+nuts.setboth = direct.setboth
+nuts.setchar = direct.setchar
+nuts.setcomponents = direct.setcomponents
+nuts.setdirection = direct.setdirection
+nuts.setdisc = direct.setdisc
+nuts.setfield = setfield
+nuts.setkern = direct.setkern
+nuts.setlink = direct.setlink
+nuts.setlist = direct.setlist
+nuts.setnext = direct.setnext
+nuts.setoffsets = direct.setoffsets
+nuts.setprev = direct.setprev
+nuts.setsplit = direct.setsplit
+nuts.setsubtype = direct.setsubtype
+nuts.setwidth = direct.setwidth
+
+nuts.getglyphdata = nuts.getattr
+nuts.setglyphdata = nuts.setattr
+
+nuts.ischar = direct.is_char
+nuts.isglyph = direct.is_glyph
+
+nuts.copy = direct.copy
+nuts.copy_list = direct.copy_list
+nuts.copy_node = direct.copy
+nuts.delete = direct.delete
+nuts.end_of_math = direct.end_of_math
+nuts.flush = direct.flush
+nuts.flush_list = direct.flush_list
+nuts.flush_node = direct.flush_node
+nuts.free = direct.free
+nuts.insert_after = direct.insert_after
+nuts.insert_before = direct.insert_before
+nuts.is_node = direct.is_node
+nuts.kerning = direct.kerning
+nuts.ligaturing = direct.ligaturing
+nuts.new = direct.new
+nuts.remove = direct.remove
+nuts.tail = direct.tail
+nuts.traverse = direct.traverse
+nuts.traverse_char = direct.traverse_char
+nuts.traverse_glyph = direct.traverse_glyph
+nuts.traverse_id = direct.traverse_id
+
+-- properties as used in the (new) injector:
+
+local propertydata = direct.get_properties_table()
+nodes.properties = { data = propertydata }
+
+if direct.set_properties_mode then
+ direct.set_properties_mode(true,true)
+ function direct.set_properties_mode() end
+end
+
+nuts.getprop = function(n,k)
+ local p = propertydata[n]
+ if p then
+ return p[k]
+ end
+end
+
+nuts.setprop = function(n,k,v)
+ if v then
+ local p = propertydata[n]
+ if p then
+ p[k] = v
+ else
+ propertydata[n] = { [k] = v }
+ end
+ end
+end
+
+nodes.setprop = nodes.setproperty
+nodes.getprop = nodes.getproperty
+
+-- a few helpers (we need to keep 'm in sync with context) .. some day components
+-- might go so here we isolate them
+
+local setprev = nuts.setprev
+local setnext = nuts.setnext
+local getnext = nuts.getnext
+local setlink = nuts.setlink
+local getfield = nuts.getfield
+local setfield = nuts.setfield
+local getcomponents = nuts.getcomponents
+local setcomponents = nuts.setcomponents
+
+local find_tail = nuts.tail
+local flush_list = nuts.flush_list
+local flush_node = nuts.flush_node
+local traverse_id = nuts.traverse_id
+local copy_node = nuts.copy_node
+
+local glyph_code = nodes.nodecodes.glyph
+
+function nuts.copy_no_components(g,copyinjection)
+ local components = getcomponents(g)
+ if components then
+ setcomponents(g)
+ local n = copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ setcomponents(g,components)
+ -- maybe also upgrade the subtype but we don't use it anyway
+ return n
+ else
+ local n = copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ return n
+ end
+end
+
+function nuts.copy_only_glyphs(current)
+ local head = nil
+ local previous = nil
+ for n in traverse_id(glyph_code,current) do
+ n = copy_node(n)
+ if head then
+ setlink(previous,n)
+ else
+ head = n
+ end
+ previous = n
+ end
+ return head
+end
+
+nuts.uses_font = direct.uses_font
+
+do
+
+ -- another poor mans substitute ... i will move these to a more protected
+ -- namespace .. experimental hack
+
+ local dummy = tonut(node.new("glyph"))
+
+ nuts.traversers = {
+ glyph = nuts.traverse_id(nodecodes.glyph,dummy),
+ glue = nuts.traverse_id(nodecodes.glue,dummy),
+ disc = nuts.traverse_id(nodecodes.disc,dummy),
+ boundary = nuts.traverse_id(nodecodes.boundary,dummy),
+
+ char = nuts.traverse_char(dummy),
+
+ node = nuts.traverse(dummy),
+ }
+
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-data-con.lua b/macros/luatex/generic/luaotfload/fontloader-data-con.lua
new file mode 100644
index 0000000000..c79fca7c5c
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-data-con.lua
@@ -0,0 +1,138 @@
+if not modules then modules = { } end modules ['data-con'] = {
+ version = 1.100,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, lower, gsub = string.format, string.lower, string.gsub
+
+local trace_cache = false trackers.register("resolvers.cache", function(v) trace_cache = v end)
+local trace_containers = false trackers.register("resolvers.containers", function(v) trace_containers = v end)
+local trace_storage = false trackers.register("resolvers.storage", function(v) trace_storage = v end)
+
+--[[ldx--
+<p>Once we found ourselves defining similar cache constructs
+several times, containers were introduced. Containers are used
+to collect tables in memory and reuse them when possible based
+on (unique) hashes (to be provided by the calling function).</p>
+
+<p>Caching to disk is disabled by default. Version numbers are
+stored in the saved table which makes it possible to change the
+table structures without bothering about the disk cache.</p>
+
+<p>Examples of usage can be found in the font related code.</p>
+--ldx]]--
+
+containers = containers or { }
+local containers = containers
+containers.usecache = true
+
+local report_containers = logs.reporter("resolvers","containers")
+
+local allocated = { }
+
+local mt = {
+ __index = function(t,k)
+ if k == "writable" then
+ local writable = caches.getwritablepath(t.category,t.subcategory) or { "." }
+ t.writable = writable
+ return writable
+ elseif k == "readables" then
+ local readables = caches.getreadablepaths(t.category,t.subcategory) or { "." }
+ t.readables = readables
+ return readables
+ end
+ end,
+ __storage__ = true
+}
+
+function containers.define(category, subcategory, version, enabled)
+ if category and subcategory then
+ local c = allocated[category]
+ if not c then
+ c = { }
+ allocated[category] = c
+ end
+ local s = c[subcategory]
+ if not s then
+ s = {
+ category = category,
+ subcategory = subcategory,
+ storage = { },
+ enabled = enabled,
+ version = version or math.pi, -- after all, this is TeX
+ trace = false,
+ -- writable = caches.getwritablepath and caches.getwritablepath (category,subcategory) or { "." },
+ -- readables = caches.getreadablepaths and caches.getreadablepaths(category,subcategory) or { "." },
+ }
+ setmetatable(s,mt)
+ c[subcategory] = s
+ end
+ return s
+ end
+end
+
+function containers.is_usable(container,name)
+ return container.enabled and caches and caches.is_writable(container.writable, name)
+end
+
+function containers.is_valid(container,name)
+ if name and name ~= "" then
+ local storage = container.storage[name]
+ return storage and storage.cache_version == container.version
+ else
+ return false
+ end
+end
+
+function containers.read(container,name)
+ local storage = container.storage
+ local stored = storage[name]
+ if not stored and container.enabled and caches and containers.usecache then
+ stored = caches.loaddata(container.readables,name,container.writable)
+ if stored and stored.cache_version == container.version then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","load",container.subcategory,name)
+ end
+ else
+ stored = nil
+ end
+ storage[name] = stored
+ elseif stored then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
+ end
+ end
+ return stored
+end
+
+function containers.write(container, name, data)
+ if data then
+ data.cache_version = container.version
+ if container.enabled and caches then
+ local unique, shared = data.unique, data.shared
+ data.unique, data.shared = nil, nil
+ caches.savedata(container.writable, name, data)
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","save",container.subcategory,name)
+ end
+ data.unique, data.shared = unique, shared
+ end
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","store",container.subcategory,name)
+ end
+ container.storage[name] = data
+ end
+ return data
+end
+
+function containers.content(container,name)
+ return container.storage[name]
+end
+
+function containers.cleanname(name)
+ -- return (gsub(lower(name),"[^%w]+","-"))
+ return (gsub(lower(name),"[^%w\128-\255]+","-")) -- more utf friendly
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-afk.lua b/macros/luatex/generic/luaotfload/fontloader-font-afk.lua
new file mode 100644
index 0000000000..761016d348
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-afk.lua
@@ -0,0 +1,200 @@
+if not modules then modules = { } end modules ['font-afk'] = {
+ version = 1.001,
+ comment = "companion to font-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+ dataonly = true,
+}
+
+--[[ldx--
+<p>For ligatures, only characters with a code smaller than 128 make sense,
+anything larger is encoding dependent. An interesting complication is that a
+character can be in an encoding twice but is hashed once.</p>
+--ldx]]--
+
+local allocate = utilities.storage.allocate
+
+fonts.handlers.afm.helpdata = {
+ ligatures = allocate { -- okay, nowadays we could parse the name but type 1 fonts
+ ['f'] = { -- don't have that many ligatures anyway
+ { 'f', 'ff' },
+ { 'i', 'fi' },
+ { 'l', 'fl' },
+ },
+ ['ff'] = {
+ { 'i', 'ffi' }
+ },
+ ['fi'] = {
+ { 'i', 'fii' }
+ },
+ ['fl'] = {
+ { 'i', 'fli' }
+ },
+ ['s'] = {
+ { 't', 'st' }
+ },
+ ['i'] = {
+ { 'j', 'ij' }
+ },
+ },
+ texligatures = allocate {
+ -- ['space'] = {
+ -- { 'L', 'Lslash' },
+ -- { 'l', 'lslash' }
+ -- },
+ -- ['question'] = {
+ -- { 'quoteleft', 'questiondown' }
+ -- },
+ -- ['exclam'] = {
+ -- { 'quoteleft', 'exclamdown' }
+ -- },
+ ['quoteleft'] = {
+ { 'quoteleft', 'quotedblleft' }
+ },
+ ['quoteright'] = {
+ { 'quoteright', 'quotedblright' }
+ },
+ ['hyphen'] = {
+ { 'hyphen', 'endash' }
+ },
+ ['endash'] = {
+ { 'hyphen', 'emdash' }
+ }
+ },
+ leftkerned = allocate {
+ AEligature = "A", aeligature = "a",
+ OEligature = "O", oeligature = "o",
+ IJligature = "I", ijligature = "i",
+ AE = "A", ae = "a",
+ OE = "O", oe = "o",
+ IJ = "I", ij = "i",
+ Ssharp = "S", ssharp = "s",
+ },
+ rightkerned = allocate {
+ AEligature = "E", aeligature = "e",
+ OEligature = "E", oeligature = "e",
+ IJligature = "J", ijligature = "j",
+ AE = "E", ae = "e",
+ OE = "E", oe = "e",
+ IJ = "J", ij = "j",
+ Ssharp = "S", ssharp = "s",
+ },
+ bothkerned = allocate {
+ Acircumflex = "A", acircumflex = "a",
+ Ccircumflex = "C", ccircumflex = "c",
+ Ecircumflex = "E", ecircumflex = "e",
+ Gcircumflex = "G", gcircumflex = "g",
+ Hcircumflex = "H", hcircumflex = "h",
+ Icircumflex = "I", icircumflex = "i",
+ Jcircumflex = "J", jcircumflex = "j",
+ Ocircumflex = "O", ocircumflex = "o",
+ Scircumflex = "S", scircumflex = "s",
+ Ucircumflex = "U", ucircumflex = "u",
+ Wcircumflex = "W", wcircumflex = "w",
+ Ycircumflex = "Y", ycircumflex = "y",
+
+ Agrave = "A", agrave = "a",
+ Egrave = "E", egrave = "e",
+ Igrave = "I", igrave = "i",
+ Ograve = "O", ograve = "o",
+ Ugrave = "U", ugrave = "u",
+ Ygrave = "Y", ygrave = "y",
+
+ Atilde = "A", atilde = "a",
+ Itilde = "I", itilde = "i",
+ Otilde = "O", otilde = "o",
+ Utilde = "U", utilde = "u",
+ Ntilde = "N", ntilde = "n",
+
+ Adiaeresis = "A", adiaeresis = "a", Adieresis = "A", adieresis = "a",
+ Ediaeresis = "E", ediaeresis = "e", Edieresis = "E", edieresis = "e",
+ Idiaeresis = "I", idiaeresis = "i", Idieresis = "I", idieresis = "i",
+ Odiaeresis = "O", odiaeresis = "o", Odieresis = "O", odieresis = "o",
+ Udiaeresis = "U", udiaeresis = "u", Udieresis = "U", udieresis = "u",
+ Ydiaeresis = "Y", ydiaeresis = "y", Ydieresis = "Y", ydieresis = "y",
+
+ Aacute = "A", aacute = "a",
+ Cacute = "C", cacute = "c",
+ Eacute = "E", eacute = "e",
+ Iacute = "I", iacute = "i",
+ Lacute = "L", lacute = "l",
+ Nacute = "N", nacute = "n",
+ Oacute = "O", oacute = "o",
+ Racute = "R", racute = "r",
+ Sacute = "S", sacute = "s",
+ Uacute = "U", uacute = "u",
+ Yacute = "Y", yacute = "y",
+ Zacute = "Z", zacute = "z",
+
+ Dstroke = "D", dstroke = "d",
+ Hstroke = "H", hstroke = "h",
+ Tstroke = "T", tstroke = "t",
+
+ Cdotaccent = "C", cdotaccent = "c",
+ Edotaccent = "E", edotaccent = "e",
+ Gdotaccent = "G", gdotaccent = "g",
+ Idotaccent = "I", idotaccent = "i",
+ Zdotaccent = "Z", zdotaccent = "z",
+
+ Amacron = "A", amacron = "a",
+ Emacron = "E", emacron = "e",
+ Imacron = "I", imacron = "i",
+ Omacron = "O", omacron = "o",
+ Umacron = "U", umacron = "u",
+
+ Ccedilla = "C", ccedilla = "c",
+ Kcedilla = "K", kcedilla = "k",
+ Lcedilla = "L", lcedilla = "l",
+ Ncedilla = "N", ncedilla = "n",
+ Rcedilla = "R", rcedilla = "r",
+ Scedilla = "S", scedilla = "s",
+ Tcedilla = "T", tcedilla = "t",
+
+ Ohungarumlaut = "O", ohungarumlaut = "o",
+ Uhungarumlaut = "U", uhungarumlaut = "u",
+
+ Aogonek = "A", aogonek = "a",
+ Eogonek = "E", eogonek = "e",
+ Iogonek = "I", iogonek = "i",
+ Uogonek = "U", uogonek = "u",
+
+ Aring = "A", aring = "a",
+ Uring = "U", uring = "u",
+
+ Abreve = "A", abreve = "a",
+ Ebreve = "E", ebreve = "e",
+ Gbreve = "G", gbreve = "g",
+ Ibreve = "I", ibreve = "i",
+ Obreve = "O", obreve = "o",
+ Ubreve = "U", ubreve = "u",
+
+ Ccaron = "C", ccaron = "c",
+ Dcaron = "D", dcaron = "d",
+ Ecaron = "E", ecaron = "e",
+ Lcaron = "L", lcaron = "l",
+ Ncaron = "N", ncaron = "n",
+ Rcaron = "R", rcaron = "r",
+ Scaron = "S", scaron = "s",
+ Tcaron = "T", tcaron = "t",
+ Zcaron = "Z", zcaron = "z",
+
+ dotlessI = "I", dotlessi = "i",
+ dotlessJ = "J", dotlessj = "j",
+
+ AEligature = "AE", aeligature = "ae", AE = "AE", ae = "ae",
+ OEligature = "OE", oeligature = "oe", OE = "OE", oe = "oe",
+ IJligature = "IJ", ijligature = "ij", IJ = "IJ", ij = "ij",
+
+ Lstroke = "L", lstroke = "l", Lslash = "L", lslash = "l",
+ Ostroke = "O", ostroke = "o", Oslash = "O", oslash = "o",
+
+ Ssharp = "SS", ssharp = "ss",
+
+ Aumlaut = "A", aumlaut = "a",
+ Eumlaut = "E", eumlaut = "e",
+ Iumlaut = "I", iumlaut = "i",
+ Oumlaut = "O", oumlaut = "o",
+ Uumlaut = "U", uumlaut = "u",
+ }
+}
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-cff.lua b/macros/luatex/generic/luaotfload/fontloader-font-cff.lua
new file mode 100644
index 0000000000..a19acc1a1d
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-cff.lua
@@ -0,0 +1,2483 @@
+if not modules then modules = { } end modules ['font-cff'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo: option.outlines
+-- todo: option.boundingbox
+-- per charstring (less memory)
+
+-- This is a heavy one as it is a rather packed format. We don't need al the information
+-- now but we might need it later (who know what magic we can do with metapost). So at
+-- some point this might become a module. We just follow Adobe Technical Notes #5176 and
+-- #5177. In case of doubt I looked in the fontforge code that comes with LuaTeX but
+-- it's not the easiest source to read (and doesn't cover cff2).
+
+-- For now we save the segments in a list of segments with the operator last in an entry
+-- because that reflects the original. But it might make more sense to use a single array
+-- per segment. For pdf a simple concat works ok, but for other purposes a operator first
+-- flush is nicer.
+--
+-- In retrospect I could have looked into the backend code of LuaTeX but it never
+-- occurred to me that parsing charstrings was needed there (which has to to
+-- with merging subroutines and flattening, not so much with calculations.) On
+-- the other hand, we can now feed back cff2 stuff.
+
+local next, type, tonumber, rawget = next, type, tonumber, rawget
+local byte, char, gmatch = string.byte, string.char, string.gmatch
+local concat, remove, unpack = table.concat, table.remove, table.unpack
+local floor, abs, round, ceil, min, max = math.floor, math.abs, math.round, math.ceil, math.min, math.max
+local P, C, R, S, C, Cs, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct
+local lpegmatch = lpeg.match
+local formatters = string.formatters
+local bytetable = string.bytetable
+local idiv = number.idiv
+local rshift, band, extract = bit32.rshift, bit32.band, bit32.extract
+
+local readers = fonts.handlers.otf.readers
+local streamreader = readers.streamreader
+
+local readstring = streamreader.readstring
+local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer
+local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer
+local readuint = streamreader.readcardinal3 -- 24-bit unsigned integer
+local readulong = streamreader.readcardinal4 -- 32-bit unsigned integer
+local setposition = streamreader.setposition
+local getposition = streamreader.getposition
+local readbytetable = streamreader.readbytetable
+
+directives.register("fonts.streamreader",function()
+
+ streamreader = utilities.streams
+
+ readstring = streamreader.readstring
+ readbyte = streamreader.readcardinal1
+ readushort = streamreader.readcardinal2
+ readuint = streamreader.readcardinal3
+ readulong = streamreader.readcardinal4
+ setposition = streamreader.setposition
+ getposition = streamreader.getposition
+ readbytetable = streamreader.readbytetable
+
+end)
+
+local setmetatableindex = table.setmetatableindex
+
+local trace_charstrings = false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings = v end)
+local report = logs.reporter("otf reader","cff")
+
+local parsedictionaries
+local parsecharstring
+local parsecharstrings
+local resetcharstrings
+local parseprivates
+local startparsing
+local stopparsing
+
+local defaultstrings = { [0] = -- taken from ff
+ ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent",
+ "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus",
+ "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four",
+ "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less",
+ "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H",
+ "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
+ "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum",
+ "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
+ "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y",
+ "z", "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent",
+ "sterling", "fraction", "yen", "florin", "section", "currency",
+ "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft",
+ "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl",
+ "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase",
+ "quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown",
+ "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent",
+ "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "emdash",
+ "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae",
+ "dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior",
+ "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn",
+ "onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters",
+ "twosuperior", "registered", "minus", "eth", "multiply", "threesuperior",
+ "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring",
+ "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave",
+ "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute",
+ "Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute",
+ "Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron",
+ "aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde",
+ "ccedilla", "eacute", "ecircumflex", "edieresis", "egrave", "iacute",
+ "icircumflex", "idieresis", "igrave", "ntilde", "oacute", "ocircumflex",
+ "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex",
+ "udieresis", "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall",
+ "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall",
+ "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader",
+ "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle",
+ "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle",
+ "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior",
+ "threequartersemdash", "periodsuperior", "questionsmall", "asuperior",
+ "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior",
+ "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
+ "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", "parenrightinferior",
+ "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall",
+ "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall",
+ "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
+ "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall",
+ "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah",
+ "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall",
+ "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall",
+ "Dotaccentsmall", "Macronsmall", "figuredash", "hypheninferior",
+ "Ogoneksmall", "Ringsmall", "Cedillasmall", "questiondownsmall", "oneeighth",
+ "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds",
+ "zerosuperior", "foursuperior", "fivesuperior", "sixsuperior",
+ "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior",
+ "oneinferior", "twoinferior", "threeinferior", "fourinferior",
+ "fiveinferior", "sixinferior", "seveninferior", "eightinferior",
+ "nineinferior", "centinferior", "dollarinferior", "periodinferior",
+ "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall",
+ "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall",
+ "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall",
+ "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall",
+ "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall",
+ "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall",
+ "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall",
+ "Thornsmall", "Ydieresissmall", "001.000", "001.001", "001.002", "001.003",
+ "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold",
+}
+
+local cffreaders = {
+ readbyte,
+ readushort,
+ readuint,
+ readulong,
+}
+
+-- The header contains information about its own size.
+
+local function readheader(f)
+ local offset = getposition(f)
+ local major = readbyte(f)
+ local header = {
+ offset = offset,
+ major = major,
+ minor = readbyte(f),
+ size = readbyte(f), -- headersize
+ }
+ if major == 1 then
+ header.dsize = readbyte(f) -- list of dict offsets
+ elseif major == 2 then
+ header.dsize = readushort(f) -- topdict size
+ else
+ -- I'm probably no longer around by then and we use AI's to
+ -- handle this kind of stuff, if we typeset documents at all.
+ end
+ setposition(f,offset+header.size)
+ return header
+end
+
+-- The indexes all look the same, so we share a loader. We could pass a handler
+-- and run over the array but why bother, we only have a few uses.
+
+local function readlengths(f,longcount)
+ local count = longcount and readulong(f) or readushort(f)
+ if count == 0 then
+ return { }
+ end
+ local osize = readbyte(f)
+ local read = cffreaders[osize]
+ if not read then
+ report("bad offset size: %i",osize)
+ return { }
+ end
+ local lengths = { }
+ local previous = read(f)
+ for i=1,count do
+ local offset = read(f)
+ local length = offset - previous
+ if length < 0 then
+ report("bad offset: %i",length)
+ length = 0
+ end
+ lengths[i] = length
+ previous = offset
+ end
+ return lengths
+end
+
+-- There can be subfonts so names is an array. However, in our case it's always
+-- one font. The same is true for the top dictionaries. Watch how we only load
+-- the dictionary string as for interpretation we need to have the strings loaded
+-- as well.
+
+local function readfontnames(f)
+ local names = readlengths(f)
+ for i=1,#names do
+ names[i] = readstring(f,names[i])
+ end
+ return names
+end
+
+local function readtopdictionaries(f)
+ local dictionaries = readlengths(f)
+ for i=1,#dictionaries do
+ dictionaries[i] = readstring(f,dictionaries[i])
+ end
+ return dictionaries
+end
+
+-- Strings are added to a list of standard strings so we start the font specific
+-- one with an offset. Strings are shared so we have one table.
+
+local function readstrings(f)
+ local lengths = readlengths(f)
+ local strings = setmetatableindex({ }, defaultstrings)
+ local index = #defaultstrings
+ for i=1,#lengths do
+ index = index + 1
+ strings[index] = readstring(f,lengths[i])
+ end
+ return strings
+end
+
+-- Parsing the dictionaries is delayed till we have the strings loaded. The parser
+-- is stack based so the operands come before the operator (like in postscript).
+
+-- local function delta(t)
+-- local n = #t
+-- if n > 1 then
+-- local p = t[1]
+-- for i=2,n do
+-- local c = t[i]
+-- t[i] = c + p
+-- p = c
+-- end
+-- end
+-- end
+
+do
+
+ -- We use a closure so that we don't need to pass too much around. For cff2 we can
+ -- at some point use a simple version as there is less.
+
+ local stack = { }
+ local top = 0
+ local result = { }
+ local strings = { }
+
+ local p_single =
+ P("\00") / function()
+ result.version = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\01") / function()
+ result.notice = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\02") / function()
+ result.fullname = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\03") / function()
+ result.familyname = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\04") / function()
+ result.weight = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\05") / function()
+ result.fontbbox = { unpack(stack,1,4) }
+ top = 0
+ end
+ + P("\06") / function()
+ result.bluevalues = { unpack(stack,1,top) }
+ top = 0
+ end
+ + P("\07") / function()
+ result.otherblues = { unpack(stack,1,top) }
+ top = 0
+ end
+ + P("\08") / function()
+ result.familyblues = { unpack(stack,1,top) }
+ top = 0
+ end
+ + P("\09") / function()
+ result.familyotherblues = { unpack(stack,1,top) }
+ top = 0
+ end
+ + P("\10") / function()
+ result.strhw = stack[top]
+ top = 0
+ end
+ + P("\11") / function()
+ result.strvw = stack[top]
+ top = 0
+ end
+ + P("\13") / function()
+ result.uniqueid = stack[top]
+ top = 0
+ end
+ + P("\14") / function()
+ result.xuid = concat(stack,"",1,top)
+ top = 0
+ end
+ + P("\15") / function()
+ result.charset = stack[top]
+ top = 0
+ end
+ + P("\16") / function()
+ result.encoding = stack[top]
+ top = 0
+ end
+ + P("\17") / function() -- valid cff2
+ result.charstrings = stack[top]
+ top = 0
+ end
+ + P("\18") / function()
+ result.private = {
+ size = stack[top-1],
+ offset = stack[top],
+ }
+ top = 0
+ end
+ + P("\19") / function()
+ result.subroutines = stack[top]
+ top = 0 -- new, forgotten ?
+ end
+ + P("\20") / function()
+ result.defaultwidthx = stack[top]
+ top = 0 -- new, forgotten ?
+ end
+ + P("\21") / function()
+ result.nominalwidthx = stack[top]
+ top = 0 -- new, forgotten ?
+ end
+ -- + P("\22") / function() -- reserved
+ -- end
+ -- + P("\23") / function() -- reserved
+ -- end
+ + P("\24") / function() -- new in cff2
+ result.vstore = stack[top]
+ top = 0
+ end
+ + P("\25") / function() -- new in cff2
+ result.maxstack = stack[top]
+ top = 0
+ end
+ -- + P("\26") / function() -- reserved
+ -- end
+ -- + P("\27") / function() -- reserved
+ -- end
+
+ local p_double = P("\12") * (
+ P("\00") / function()
+ result.copyright = stack[top]
+ top = 0
+ end
+ + P("\01") / function()
+ result.monospaced = stack[top] == 1 and true or false -- isfixedpitch
+ top = 0
+ end
+ + P("\02") / function()
+ result.italicangle = stack[top]
+ top = 0
+ end
+ + P("\03") / function()
+ result.underlineposition = stack[top]
+ top = 0
+ end
+ + P("\04") / function()
+ result.underlinethickness = stack[top]
+ top = 0
+ end
+ + P("\05") / function()
+ result.painttype = stack[top]
+ top = 0
+ end
+ + P("\06") / function()
+ result.charstringtype = stack[top]
+ top = 0
+ end
+ + P("\07") / function() -- valid cff2
+ result.fontmatrix = { unpack(stack,1,6) }
+ top = 0
+ end
+ + P("\08") / function()
+ result.strokewidth = stack[top]
+ top = 0
+ end
+ + P("\09") / function()
+ result.bluescale = stack[top]
+ top = 0
+ end
+ + P("\10") / function()
+ result.bluesnap = stack[top]
+ top = 0
+ end
+ + P("\11") / function()
+ result.bluefuzz = stack[top]
+ top = 0
+ end
+ + P("\12") / function()
+ result.stemsnaph = { unpack(stack,1,top) }
+ top = 0
+ end
+ + P("\13") / function()
+ result.stemsnapv = { unpack(stack,1,top) }
+ top = 0
+ end
+ + P("\20") / function()
+ result.syntheticbase = stack[top]
+ top = 0
+ end
+ + P("\21") / function()
+ result.postscript = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\22") / function()
+ result.basefontname = strings[stack[top]] or "unset"
+ top = 0
+ end
+ + P("\21") / function()
+ result.basefontblend = stack[top]
+ top = 0
+ end
+ + P("\30") / function()
+ result.cid.registry = strings[stack[top-2]] or "unset"
+ result.cid.ordering = strings[stack[top-1]] or "unset"
+ result.cid.supplement = stack[top]
+ top = 0
+ end
+ + P("\31") / function()
+ result.cid.fontversion = stack[top]
+ top = 0
+ end
+ + P("\32") / function()
+ result.cid.fontrevision= stack[top]
+ top = 0
+ end
+ + P("\33") / function()
+ result.cid.fonttype = stack[top]
+ top = 0
+ end
+ + P("\34") / function()
+ result.cid.count = stack[top]
+ top = 0
+ end
+ + P("\35") / function()
+ result.cid.uidbase = stack[top]
+ top = 0
+ end
+ + P("\36") / function() -- valid cff2
+ result.cid.fdarray = stack[top]
+ top = 0
+ end
+ + P("\37") / function() -- valid cff2
+ result.cid.fdselect = stack[top]
+ top = 0
+ end
+ + P("\38") / function()
+ result.cid.fontname = strings[stack[top]] or "unset"
+ top = 0
+ end
+ )
+
+ -- Some lpeg fun ... a first variant split the byte and made a new string but
+ -- the second variant is much faster. Not that it matters much as we don't see
+ -- such numbers often.
+
+ local remap = {
+ ["\x00"] = "00", ["\x01"] = "01", ["\x02"] = "02", ["\x03"] = "03", ["\x04"] = "04", ["\x05"] = "05", ["\x06"] = "06", ["\x07"] = "07", ["\x08"] = "08", ["\x09"] = "09", ["\x0A"] = "0.", ["\x0B"] = "0E", ["\x0C"] = "0E-", ["\x0D"] = "0", ["\x0E"] = "0-", ["\x0F"] = "0",
+ ["\x10"] = "10", ["\x11"] = "11", ["\x12"] = "12", ["\x13"] = "13", ["\x14"] = "14", ["\x15"] = "15", ["\x16"] = "16", ["\x17"] = "17", ["\x18"] = "18", ["\x19"] = "19", ["\x1A"] = "1.", ["\x1B"] = "1E", ["\x1C"] = "1E-", ["\x1D"] = "1", ["\x1E"] = "1-", ["\x1F"] = "1",
+ ["\x20"] = "20", ["\x21"] = "21", ["\x22"] = "22", ["\x23"] = "23", ["\x24"] = "24", ["\x25"] = "25", ["\x26"] = "26", ["\x27"] = "27", ["\x28"] = "28", ["\x29"] = "29", ["\x2A"] = "2.", ["\x2B"] = "2E", ["\x2C"] = "2E-", ["\x2D"] = "2", ["\x2E"] = "2-", ["\x2F"] = "2",
+ ["\x30"] = "30", ["\x31"] = "31", ["\x32"] = "32", ["\x33"] = "33", ["\x34"] = "34", ["\x35"] = "35", ["\x36"] = "36", ["\x37"] = "37", ["\x38"] = "38", ["\x39"] = "39", ["\x3A"] = "3.", ["\x3B"] = "3E", ["\x3C"] = "3E-", ["\x3D"] = "3", ["\x3E"] = "3-", ["\x3F"] = "3",
+ ["\x40"] = "40", ["\x41"] = "41", ["\x42"] = "42", ["\x43"] = "43", ["\x44"] = "44", ["\x45"] = "45", ["\x46"] = "46", ["\x47"] = "47", ["\x48"] = "48", ["\x49"] = "49", ["\x4A"] = "4.", ["\x4B"] = "4E", ["\x4C"] = "4E-", ["\x4D"] = "4", ["\x4E"] = "4-", ["\x4F"] = "4",
+ ["\x50"] = "50", ["\x51"] = "51", ["\x52"] = "52", ["\x53"] = "53", ["\x54"] = "54", ["\x55"] = "55", ["\x56"] = "56", ["\x57"] = "57", ["\x58"] = "58", ["\x59"] = "59", ["\x5A"] = "5.", ["\x5B"] = "5E", ["\x5C"] = "5E-", ["\x5D"] = "5", ["\x5E"] = "5-", ["\x5F"] = "5",
+ ["\x60"] = "60", ["\x61"] = "61", ["\x62"] = "62", ["\x63"] = "63", ["\x64"] = "64", ["\x65"] = "65", ["\x66"] = "66", ["\x67"] = "67", ["\x68"] = "68", ["\x69"] = "69", ["\x6A"] = "6.", ["\x6B"] = "6E", ["\x6C"] = "6E-", ["\x6D"] = "6", ["\x6E"] = "6-", ["\x6F"] = "6",
+ ["\x70"] = "70", ["\x71"] = "71", ["\x72"] = "72", ["\x73"] = "73", ["\x74"] = "74", ["\x75"] = "75", ["\x76"] = "76", ["\x77"] = "77", ["\x78"] = "78", ["\x79"] = "79", ["\x7A"] = "7.", ["\x7B"] = "7E", ["\x7C"] = "7E-", ["\x7D"] = "7", ["\x7E"] = "7-", ["\x7F"] = "7",
+ ["\x80"] = "80", ["\x81"] = "81", ["\x82"] = "82", ["\x83"] = "83", ["\x84"] = "84", ["\x85"] = "85", ["\x86"] = "86", ["\x87"] = "87", ["\x88"] = "88", ["\x89"] = "89", ["\x8A"] = "8.", ["\x8B"] = "8E", ["\x8C"] = "8E-", ["\x8D"] = "8", ["\x8E"] = "8-", ["\x8F"] = "8",
+ ["\x90"] = "90", ["\x91"] = "91", ["\x92"] = "92", ["\x93"] = "93", ["\x94"] = "94", ["\x95"] = "95", ["\x96"] = "96", ["\x97"] = "97", ["\x98"] = "98", ["\x99"] = "99", ["\x9A"] = "9.", ["\x9B"] = "9E", ["\x9C"] = "9E-", ["\x9D"] = "9", ["\x9E"] = "9-", ["\x9F"] = "9",
+ ["\xA0"] = ".0", ["\xA1"] = ".1", ["\xA2"] = ".2", ["\xA3"] = ".3", ["\xA4"] = ".4", ["\xA5"] = ".5", ["\xA6"] = ".6", ["\xA7"] = ".7", ["\xA8"] = ".8", ["\xA9"] = ".9", ["\xAA"] = "..", ["\xAB"] = ".E", ["\xAC"] = ".E-", ["\xAD"] = ".", ["\xAE"] = ".-", ["\xAF"] = ".",
+ ["\xB0"] = "E0", ["\xB1"] = "E1", ["\xB2"] = "E2", ["\xB3"] = "E3", ["\xB4"] = "E4", ["\xB5"] = "E5", ["\xB6"] = "E6", ["\xB7"] = "E7", ["\xB8"] = "E8", ["\xB9"] = "E9", ["\xBA"] = "E.", ["\xBB"] = "EE", ["\xBC"] = "EE-", ["\xBD"] = "E", ["\xBE"] = "E-", ["\xBF"] = "E",
+ ["\xC0"] = "E-0", ["\xC1"] = "E-1", ["\xC2"] = "E-2", ["\xC3"] = "E-3", ["\xC4"] = "E-4", ["\xC5"] = "E-5", ["\xC6"] = "E-6", ["\xC7"] = "E-7", ["\xC8"] = "E-8", ["\xC9"] = "E-9", ["\xCA"] = "E-.", ["\xCB"] = "E-E", ["\xCC"] = "E-E-", ["\xCD"] = "E-", ["\xCE"] = "E--", ["\xCF"] = "E-",
+ ["\xD0"] = "-0", ["\xD1"] = "-1", ["\xD2"] = "-2", ["\xD3"] = "-3", ["\xD4"] = "-4", ["\xD5"] = "-5", ["\xD6"] = "-6", ["\xD7"] = "-7", ["\xD8"] = "-8", ["\xD9"] = "-9", ["\xDA"] = "-.", ["\xDB"] = "-E", ["\xDC"] = "-E-", ["\xDD"] = "-", ["\xDE"] = "--", ["\xDF"] = "-",
+ }
+
+ local p_last = S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")
+ + R("\xF0\xFF")
+
+ local p_nibbles = P("\30") * Cs(((1-p_last)/remap)^0 * (P(1)/remap)) / function(n)
+ -- 0-9=digit a=. b=E c=E- d=reserved e=- f=finish
+ top = top + 1
+ stack[top] = tonumber(n) or 0
+ end
+
+ local p_byte = C(R("\32\246")) / function(b0)
+ -- -107 .. +107
+ top = top + 1
+ stack[top] = byte(b0) - 139
+ end
+
+ local p_positive = C(R("\247\250")) * C(1) / function(b0,b1)
+ -- +108 .. +1131
+ top = top + 1
+ stack[top] = (byte(b0)-247)*256 + byte(b1) + 108
+ end
+
+ local p_negative = C(R("\251\254")) * C(1) / function(b0,b1)
+ -- -1131 .. -108
+ top = top + 1
+ stack[top] = -(byte(b0)-251)*256 - byte(b1) - 108
+ end
+
+ local p_short = P("\28") * C(1) * C(1) / function(b1,b2)
+ -- -32768 .. +32767 : b1<<8 | b2
+ top = top + 1
+ local n = 0x100 * byte(b1) + byte(b2)
+ if n >= 0x8000 then
+ stack[top] = n - 0xFFFF - 1
+ else
+ stack[top] = n
+ end
+ end
+
+ local p_long = P("\29") * C(1) * C(1) * C(1) * C(1) / function(b1,b2,b3,b4)
+ -- -2^31 .. +2^31-1 : b1<<24 | b2<<16 | b3<<8 | b4
+ top = top + 1
+ local n = 0x1000000 * byte(b1) + 0x10000 * byte(b2) + 0x100 * byte(b3) + byte(b4)
+ if n >= 0x8000000 then
+ stack[top] = n - 0xFFFFFFFF - 1
+ else
+ stack[top] = n
+ end
+ end
+
+ local p_unsupported = P(1) / function(detail)
+ top = 0
+ end
+
+ local p_dictionary = (
+ p_byte
+ + p_positive
+ + p_negative
+ + p_short
+ + p_long
+ + p_nibbles
+ + p_single
+ + p_double
+ + p_unsupported
+ )^1
+
+ parsedictionaries = function(data,dictionaries,what)
+ stack = { }
+ strings = data.strings
+ for i=1,#dictionaries do
+ top = 0
+ result = what == "cff" and {
+ monospaced = false,
+ italicangle = 0,
+ underlineposition = -100,
+ underlinethickness = 50,
+ painttype = 0,
+ charstringtype = 2,
+ fontmatrix = { 0.001, 0, 0, 0.001, 0, 0 },
+ fontbbox = { 0, 0, 0, 0 },
+ strokewidth = 0,
+ charset = 0,
+ encoding = 0,
+ cid = {
+ fontversion = 0,
+ fontrevision = 0,
+ fonttype = 0,
+ count = 8720,
+ }
+ } or {
+ charstringtype = 2,
+ charset = 0,
+ vstore = 0,
+ cid = {
+ -- nothing yet
+ },
+ }
+ lpegmatch(p_dictionary,dictionaries[i])
+ dictionaries[i] = result
+ end
+ --
+ result = { }
+ top = 0
+ stack = { }
+ end
+
+ parseprivates = function(data,dictionaries)
+ stack = { }
+ strings = data.strings
+ for i=1,#dictionaries do
+ local private = dictionaries[i].private
+ if private and private.data then
+ top = 0
+ result = {
+ forcebold = false,
+ languagegroup = 0,
+ expansionfactor = 0.06,
+ initialrandomseed = 0,
+ subroutines = 0,
+ defaultwidthx = 0,
+ nominalwidthx = 0,
+ cid = {
+ -- actually an error
+ },
+ }
+ lpegmatch(p_dictionary,private.data)
+ private.data = result
+ end
+ end
+ result = { }
+ top = 0
+ stack = { }
+ end
+
+ -- All bezier curves have 6 points with successive pairs relative to
+ -- the previous pair. Some can be left out and are then copied or zero
+ -- (optimization).
+ --
+ -- We are not really interested in all the details of a glyph because we
+ -- only need to calculate the boundingbox. So, todo: a quick no result but
+ -- calculate only variant.
+ --
+ -- The conversion is straightforward and the specification os clear once
+ -- you understand that the x and y needs to be updates each step. It's also
+ -- quite easy to test because in mp a shape will look bad when a few variables
+ -- are swapped. But still there might be bugs down here because not all
+ -- variants are seen in a font so far. We are less compact that the ff code
+ -- because there quite some variants are done in one helper with a lot of
+ -- testing for states.
+
+ local x = 0
+ local y = 0
+ local width = false
+ local r = 0
+ local stems = 0
+ local globalbias = 0
+ local localbias = 0
+ local nominalwidth = 0
+ local defaultwidth = 0
+ local charset = false
+ local globals = false
+ local locals = false
+ local depth = 1
+ local xmin = 0
+ local xmax = 0
+ local ymin = 0
+ local ymax = 0
+ local checked = false
+ local keepcurve = false
+ local version = 2
+ local regions = false
+ local nofregions = 0
+ local region = false
+ local factors = false
+ local axis = false
+ local vsindex = 0
+
+ local function showstate(where)
+ report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top)
+ end
+
+ local function showvalue(where,value,showstack)
+ if showstack then
+ report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top)
+ else
+ report("%w%-10s : %s",depth*2,where,tostring(value))
+ end
+ end
+
+ -- All these indirect calls make this run slower but it's cleaner this way
+ -- and we cache the result. As we moved the boundingbox code inline we gain
+ -- some back. I inlined some of then and a bit speed can be gained by more
+ -- inlining but not that much.
+
+ local function xymoveto()
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "m" }
+ end
+ if checked then
+ if x > xmax then xmax = x elseif x < xmin then xmin = x end
+ if y > ymax then ymax = y elseif y < ymin then ymin = y end
+ else
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ end
+ end
+
+ local function xmoveto() -- slight speedup
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "m" }
+ end
+ if not checked then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ elseif x > xmax then
+ xmax = x
+ elseif x < xmin then
+ xmin = x
+ end
+ end
+
+ local function ymoveto() -- slight speedup
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "m" }
+ end
+ if not checked then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ elseif y > ymax then
+ ymax = y
+ elseif y < ymin then
+ ymin = y
+ end
+ end
+
+ local function moveto()
+ if trace_charstrings then
+ showstate("moveto")
+ end
+ top = 0 -- forgotten
+ xymoveto()
+ end
+
+ local function xylineto() -- we could inline, no blend
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "l" }
+ end
+ if checked then
+ if x > xmax then xmax = x elseif x < xmin then xmin = x end
+ if y > ymax then ymax = y elseif y < ymin then ymin = y end
+ else
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ end
+ end
+
+ local function xlineto() -- slight speedup
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "l" }
+ end
+ if not checked then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ elseif x > xmax then
+ xmax = x
+ elseif x < xmin then
+ xmin = x
+ end
+ end
+
+ local function ylineto() -- slight speedup
+ if keepcurve then
+ r = r + 1
+ result[r] = { x, y, "l" }
+ end
+ if not checked then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ checked = true
+ elseif y > ymax then
+ ymax = y
+ elseif y < ymin then
+ ymin = y
+ end
+ end
+
+ local function xycurveto(x1,y1,x2,y2,x3,y3) -- called local so no blend here
+ if trace_charstrings then
+ showstate("curveto")
+ end
+ if keepcurve then
+ r = r + 1
+ result[r] = { x1, y1, x2, y2, x3, y3, "c" }
+ end
+ if checked then
+ if x1 > xmax then xmax = x1 elseif x1 < xmin then xmin = x1 end
+ if y1 > ymax then ymax = y1 elseif y1 < ymin then ymin = y1 end
+ else
+ xmin = x1
+ ymin = y1
+ xmax = x1
+ ymax = y1
+ checked = true
+ end
+ if x2 > xmax then xmax = x2 elseif x2 < xmin then xmin = x2 end
+ if y2 > ymax then ymax = y2 elseif y2 < ymin then ymin = y2 end
+ if x3 > xmax then xmax = x3 elseif x3 < xmin then xmin = x3 end
+ if y3 > ymax then ymax = y3 elseif y3 < ymin then ymin = y3 end
+ end
+
+ local function rmoveto()
+ if not width then
+ if top > 2 then
+ width = stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
+ end
+ else
+ width = true
+ end
+ end
+ if trace_charstrings then
+ showstate("rmoveto")
+ end
+ x = x + stack[top-1] -- dx1
+ y = y + stack[top] -- dy1
+ top = 0
+ xymoveto()
+ end
+
+ local function hmoveto()
+ if not width then
+ if top > 1 then
+ width = stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
+ end
+ else
+ width = true
+ end
+ end
+ if trace_charstrings then
+ showstate("hmoveto")
+ end
+ x = x + stack[top] -- dx1
+ top = 0
+ xmoveto()
+ end
+
+ local function vmoveto()
+ if not width then
+ if top > 1 then
+ width = stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
+ end
+ else
+ width = true
+ end
+ end
+ if trace_charstrings then
+ showstate("vmoveto")
+ end
+ y = y + stack[top] -- dy1
+ top = 0
+ ymoveto()
+ end
+
+ local function rlineto()
+ if trace_charstrings then
+ showstate("rlineto")
+ end
+ for i=1,top,2 do
+ x = x + stack[i] -- dxa
+ y = y + stack[i+1] -- dya
+ xylineto()
+ end
+ top = 0
+ end
+
+ local function hlineto() -- x (y,x)+ | (x,y)+
+ if trace_charstrings then
+ showstate("hlineto")
+ end
+ if top == 1 then
+ x = x + stack[1]
+ xlineto()
+ else
+ local swap = true
+ for i=1,top do
+ if swap then
+ x = x + stack[i]
+ xlineto()
+ swap = false
+ else
+ y = y + stack[i]
+ ylineto()
+ swap = true
+ end
+ end
+ end
+ top = 0
+ end
+
+ local function vlineto() -- y (x,y)+ | (y,x)+
+ if trace_charstrings then
+ showstate("vlineto")
+ end
+ if top == 1 then
+ y = y + stack[1]
+ ylineto()
+ else
+ local swap = false
+ for i=1,top do
+ if swap then
+ x = x + stack[i]
+ xlineto()
+ swap = false
+ else
+ y = y + stack[i]
+ ylineto()
+ swap = true
+ end
+ end
+ end
+ top = 0
+ end
+
+ local function rrcurveto()
+ if trace_charstrings then
+ showstate("rrcurveto")
+ end
+ for i=1,top,6 do
+ local ax = x + stack[i] -- dxa
+ local ay = y + stack[i+1] -- dya
+ local bx = ax + stack[i+2] -- dxb
+ local by = ay + stack[i+3] -- dyb
+ x = bx + stack[i+4] -- dxc
+ y = by + stack[i+5] -- dyc
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ top = 0
+ end
+
+ local function hhcurveto()
+ if trace_charstrings then
+ showstate("hhcurveto")
+ end
+ local s = 1
+ if top % 2 ~= 0 then
+ y = y + stack[1] -- dy1
+ s = 2
+ end
+ for i=s,top,4 do
+ local ax = x + stack[i] -- dxa
+ local ay = y
+ local bx = ax + stack[i+1] -- dxb
+ local by = ay + stack[i+2] -- dyb
+ x = bx + stack[i+3] -- dxc
+ y = by
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ top = 0
+ end
+
+ local function vvcurveto()
+ if trace_charstrings then
+ showstate("vvcurveto")
+ end
+ local s = 1
+ local d = 0
+ if top % 2 ~= 0 then
+ d = stack[1] -- dx1
+ s = 2
+ end
+ for i=s,top,4 do
+ local ax = x + d
+ local ay = y + stack[i] -- dya
+ local bx = ax + stack[i+1] -- dxb
+ local by = ay + stack[i+2] -- dyb
+ x = bx
+ y = by + stack[i+3] -- dyc
+ xycurveto(ax,ay,bx,by,x,y)
+ d = 0
+ end
+ top = 0
+ end
+
+ local function xxcurveto(swap)
+ local last = top % 4 ~= 0 and stack[top]
+ if last then
+ top = top - 1
+ end
+ for i=1,top,4 do
+ local ax, ay, bx, by
+ if swap then
+ ax = x + stack[i]
+ ay = y
+ bx = ax + stack[i+1]
+ by = ay + stack[i+2]
+ y = by + stack[i+3]
+ if last and i+3 == top then
+ x = bx + last
+ else
+ x = bx
+ end
+ swap = false
+ else
+ ax = x
+ ay = y + stack[i]
+ bx = ax + stack[i+1]
+ by = ay + stack[i+2]
+ x = bx + stack[i+3]
+ if last and i+3 == top then
+ y = by + last
+ else
+ y = by
+ end
+ swap = true
+ end
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ top = 0
+ end
+
+ local function hvcurveto()
+ if trace_charstrings then
+ showstate("hvcurveto")
+ end
+ xxcurveto(true)
+ end
+
+ local function vhcurveto()
+ if trace_charstrings then
+ showstate("vhcurveto")
+ end
+ xxcurveto(false)
+ end
+
+ local function rcurveline()
+ if trace_charstrings then
+ showstate("rcurveline")
+ end
+ for i=1,top-2,6 do
+ local ax = x + stack[i] -- dxa
+ local ay = y + stack[i+1] -- dya
+ local bx = ax + stack[i+2] -- dxb
+ local by = ay + stack[i+3] -- dyb
+ x = bx + stack[i+4] -- dxc
+ y = by + stack[i+5] -- dyc
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ x = x + stack[top-1] -- dxc
+ y = y + stack[top] -- dyc
+ xylineto()
+ top = 0
+ end
+
+ local function rlinecurve()
+ if trace_charstrings then
+ showstate("rlinecurve")
+ end
+ if top > 6 then
+ for i=1,top-6,2 do
+ x = x + stack[i]
+ y = y + stack[i+1]
+ xylineto()
+ end
+ end
+ local ax = x + stack[top-5]
+ local ay = y + stack[top-4]
+ local bx = ax + stack[top-3]
+ local by = ay + stack[top-2]
+ x = bx + stack[top-1]
+ y = by + stack[top]
+ xycurveto(ax,ay,bx,by,x,y)
+ top = 0
+ end
+
+ -- flex is not yet tested! no loop
+
+ local function flex() -- fd not used
+ if trace_charstrings then
+ showstate("flex")
+ end
+ local ax = x + stack[1] -- dx1
+ local ay = y + stack[2] -- dy1
+ local bx = ax + stack[3] -- dx2
+ local by = ay + stack[4] -- dy2
+ local cx = bx + stack[5] -- dx3
+ local cy = by + stack[6] -- dy3
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx = cx + stack[7] -- dx4
+ local dy = cy + stack[8] -- dy4
+ local ex = dx + stack[9] -- dx5
+ local ey = dy + stack[10] -- dy5
+ x = ex + stack[11] -- dx6
+ y = ey + stack[12] -- dy6
+ xycurveto(dx,dy,ex,ey,x,y)
+ top = 0
+ end
+
+ local function hflex()
+ if trace_charstrings then
+ showstate("hflex")
+ end
+ local ax = x + stack[1] -- dx1
+ local ay = y
+ local bx = ax + stack[2] -- dx2
+ local by = ay + stack[3] -- dy2
+ local cx = bx + stack[4] -- dx3
+ local cy = by
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx = cx + stack[5] -- dx4
+ local dy = by
+ local ex = dx + stack[6] -- dx5
+ local ey = y
+ x = ex + stack[7] -- dx6
+ xycurveto(dx,dy,ex,ey,x,y)
+ top = 0
+ end
+
+ local function hflex1()
+ if trace_charstrings then
+ showstate("hflex1")
+ end
+ local ax = x + stack[1] -- dx1
+ local ay = y + stack[2] -- dy1
+ local bx = ax + stack[3] -- dx2
+ local by = ay + stack[4] -- dy2
+ local cx = bx + stack[5] -- dx3
+ local cy = by
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx = cx + stack[6] -- dx4
+ local dy = by
+ local ex = dx + stack[7] -- dx5
+ local ey = dy + stack[8] -- dy5
+ x = ex + stack[9] -- dx6
+ xycurveto(dx,dy,ex,ey,x,y)
+ top = 0
+ end
+
+ local function flex1()
+ if trace_charstrings then
+ showstate("flex1")
+ end
+ local ax = x + stack[1] --dx1
+ local ay = y + stack[2] --dy1
+ local bx = ax + stack[3] --dx2
+ local by = ay + stack[4] --dy2
+ local cx = bx + stack[5] --dx3
+ local cy = by + stack[6] --dy3
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx = cx + stack[7] --dx4
+ local dy = cy + stack[8] --dy4
+ local ex = dx + stack[9] --dx5
+ local ey = dy + stack[10] --dy5
+ if abs(ex - x) > abs(ey - y) then -- spec: abs(dx) > abs(dy)
+ x = ex + stack[11]
+ else
+ y = ey + stack[11]
+ end
+ xycurveto(dx,dy,ex,ey,x,y)
+ top = 0
+ end
+
+ local function getstem()
+ if top == 0 then
+ -- bad
+ elseif top % 2 ~= 0 then
+ if width then
+ remove(stack,1)
+ else
+ width = remove(stack,1)
+ if trace_charstrings then
+ showvalue("width",width)
+ end
+ end
+ top = top - 1
+ end
+ if trace_charstrings then
+ showstate("stem")
+ end
+ stems = stems + idiv(top,2)
+ top = 0
+ end
+
+ local function getmask()
+ if top == 0 then
+ -- bad
+ elseif top % 2 ~= 0 then
+ if width then
+ remove(stack,1)
+ else
+ width = remove(stack,1)
+ if trace_charstrings then
+ showvalue("width",width)
+ end
+ end
+ top = top - 1
+ end
+ if trace_charstrings then
+ showstate(operator == 19 and "hintmark" or "cntrmask")
+ end
+ stems = stems + idiv(top,2)
+ top = 0
+ if stems == 0 then
+ -- forget about it
+ elseif stems <= 8 then
+ return 1
+ else
+ -- return floor((stems+7)/8)
+ return idiv(stems+7,8)
+ end
+ end
+
+ local function unsupported(t)
+ if trace_charstrings then
+ showstate("unsupported " .. t)
+ end
+ top = 0
+ end
+
+ local function unsupportedsub(t)
+ if trace_charstrings then
+ showstate("unsupported sub " .. t)
+ end
+ top = 0
+ end
+
+ -- type 1 (not used in type 2)
+
+ local function getstem3()
+ if trace_charstrings then
+ showstate("stem3")
+ end
+ top = 0
+ end
+
+ local function divide()
+ if version == 1 then
+ local d = stack[top]
+ top = top - 1
+ stack[top] = stack[top] / d
+ end
+ end
+
+ local function closepath()
+ if version == 1 then
+ if trace_charstrings then
+ showstate("closepath")
+ end
+ end
+ top = 0
+ end
+
+ local function hsbw()
+ if version == 1 then
+ if trace_charstrings then
+ showstate("hsbw")
+ end
+ -- lsb = stack[top-1]
+ width = stack[top]
+ end
+ top = 0
+ end
+
+ local function seac()
+ if version == 1 then
+ if trace_charstrings then
+ showstate("seac")
+ end
+ end
+ top = 0
+ end
+
+ local function sbw()
+ if version == 1 then
+ if trace_charstrings then
+ showstate("sbw")
+ end
+ width = stack[top-1]
+ end
+ top = 0
+ end
+
+ -- these are probably used for special cases i.e. call out to postscript
+
+ local function callothersubr()
+ if version == 1 then
+ -- we don't support this (ok, we could mimick these othersubs)
+ if trace_charstrings then
+ showstate("callothersubr (unsupported)")
+ end
+ end
+ top = 0
+ end
+
+ local function pop()
+ if version == 1 then
+ -- we don't support this
+ if trace_charstrings then
+ showstate("pop (unsupported)")
+ end
+ top = top + 1
+ stack[top] = 0 -- a dummy
+ else
+ top = 0
+ end
+ end
+
+ local function setcurrentpoint()
+ if version == 1 then
+ -- we don't support this
+ if trace_charstrings then
+ showstate("pop (unsupported)")
+ end
+ x = x + stack[top-1]
+ y = y + stack[top]
+ end
+ top = 0
+ end
+
+ -- So far for unsupported postscript. Now some cff2 magic. As I still need
+ -- to wrap my head around the rather complex variable font specification
+ -- with regions and axis, the following approach kind of works but is more
+ -- some trial and error trick. It's still not clear how much of the complex
+ -- truetype description applies to cff.
+
+ local reginit = false
+
+ local function updateregions(n) -- n + 1
+ if regions then
+ local current = regions[n] or regions[1]
+ nofregions = #current
+ if axis and n ~= reginit then
+ factors = { }
+ for i=1,nofregions do
+ local region = current[i]
+ local s = 1
+ for j=1,#axis do
+ local f = axis[j]
+ local r = region[j]
+ local start = r.start
+ local peak = r.peak
+ local stop = r.stop
+ if start > peak or peak > stop then
+ -- * 1
+ elseif start < 0 and stop > 0 and peak ~= 0 then
+ -- * 1
+ elseif peak == 0 then
+ -- * 1
+ elseif f < start or f > stop then
+ -- * 0
+ s = 0
+ break
+ elseif f < peak then
+ s = s * (f - start) / (peak - start)
+ elseif f > peak then
+ s = s * (stop - f) / (stop - peak)
+ else
+ -- * 1
+ end
+ end
+ factors[i] = s
+ end
+ end
+ end
+ reginit = n
+ end
+
+ local function setvsindex()
+ local vsindex = stack[top]
+ if trace_charstrings then
+ showstate(formatters["vsindex %i"](vsindex))
+ end
+ updateregions(vsindex)
+ top = top - 1
+ end
+
+ local function blend()
+ local n = stack[top]
+ top = top - 1
+ if axis then
+ -- x (r1x,r2x,r3x)
+ -- (x,y) (r1x,r2x,r3x) (r1y,r2y,r3y)
+ if trace_charstrings then
+ local t = top - nofregions * n
+ local m = t - n
+ for i=1,n do
+ local k = m + i
+ local d = m + n + (i-1)*nofregions
+ local old = stack[k]
+ local new = old
+ for r=1,nofregions do
+ new = new + stack[d+r] * factors[r]
+ end
+ stack[k] = new
+ showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new))
+ end
+ top = t
+ elseif n == 1 then
+ top = top - nofregions
+ local v = stack[top]
+ for r=1,nofregions do
+ v = v + stack[top+r] * factors[r]
+ end
+ stack[top] = v
+ else
+ top = top - nofregions * n
+ local d = top
+ local k = top - n
+ for i=1,n do
+ k = k + 1
+ local v = stack[k]
+ for r=1,nofregions do
+ v = v + stack[d+r] * factors[r]
+ end
+ stack[k] = v
+ d = d + nofregions
+ end
+ end
+ else
+ -- error
+ end
+ end
+
+ -- Bah, we cannot use a fast lpeg because a hint has an unknown size and a
+ -- runtime capture cannot handle that well.
+
+ local actions = { [0] =
+ unsupported, -- 0
+ getstem, -- 1 -- hstem
+ unsupported, -- 2
+ getstem, -- 3 -- vstem
+ vmoveto, -- 4
+ rlineto, -- 5
+ hlineto, -- 6
+ vlineto, -- 7
+ rrcurveto, -- 8
+ unsupported, -- 9 -- closepath
+ unsupported, -- 10 -- calllocal,
+ unsupported, -- 11 -- callreturn,
+ unsupported, -- 12 -- elsewhere
+ hsbw, -- 13 -- hsbw (type 1 cff)
+ unsupported, -- 14 -- endchar,
+ setvsindex, -- 15 -- cff2
+ blend, -- 16 -- cff2
+ unsupported, -- 17
+ getstem, -- 18 -- hstemhm
+ getmask, -- 19 -- hintmask
+ getmask, -- 20 -- cntrmask
+ rmoveto, -- 21
+ hmoveto, -- 22
+ getstem, -- 23 -- vstemhm
+ rcurveline, -- 24
+ rlinecurve, -- 25
+ vvcurveto, -- 26
+ hhcurveto, -- 27
+ unsupported, -- 28 -- elsewhere
+ unsupported, -- 29 -- elsewhere
+ vhcurveto, -- 30
+ hvcurveto, -- 31
+ }
+
+ local subactions = {
+ -- cff 1
+ [000] = dotsection,
+ [001] = getstem3,
+ [002] = getstem3,
+ [006] = seac,
+ [007] = sbw,
+ [012] = divide,
+ [016] = callothersubr,
+ [017] = pop,
+ [033] = setcurrentpoint,
+ -- cff 2
+ [034] = hflex,
+ [035] = flex,
+ [036] = hflex1,
+ [037] = flex1,
+ }
+
+ local chars = setmetatableindex(function (t,k)
+ local v = char(k)
+ t[k] = v
+ return v
+ end)
+
+ local c_endchar = chars[14]
+
+ -- todo: round in blend
+
+ local encode = { }
+
+ -- this eventually can become a helper
+
+ setmetatableindex(encode,function(t,i)
+ for i=-2048,-1130 do
+ t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+ end
+ for i=-1131,-108 do
+ local v = 0xFB00 - i - 108
+ t[i] = char(band(rshift(v,8),0xFF),band(v,0xFF))
+ end
+ for i=-107,107 do
+ t[i] = chars[i + 139]
+ end
+ for i=108,1131 do
+ local v = 0xF700 + i - 108
+-- t[i] = char(band(rshift(v,8),0xFF),band(v,0xFF))
+ t[i] = char(extract(v,8,8),extract(v,0,8))
+ end
+ for i=1132,2048 do
+ t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+ end
+ setmetatableindex(encode,function(t,k)
+ -- 16.16-bit signed fixed value
+ local r = round(k)
+ local v = rawget(t,r)
+ if v then
+ return v
+ end
+ local v1 = floor(k)
+ local v2 = floor((k - v1) * 0x10000)
+ return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8))
+ end)
+ return t[i]
+ end)
+
+ readers.cffencoder = encode
+
+ local function p_setvsindex()
+ local vsindex = stack[top]
+ updateregions(vsindex)
+ top = top - 1
+ end
+
+ local function p_blend()
+ -- leaves n values on stack
+ local n = stack[top]
+ top = top - 1
+ if not axis then
+ -- fatal error
+ elseif n == 1 then
+ top = top - nofregions
+ local v = stack[top]
+ for r=1,nofregions do
+ v = v + stack[top+r] * factors[r]
+ end
+ stack[top] = round(v)
+ else
+ top = top - nofregions * n
+ local d = top
+ local k = top - n
+ for i=1,n do
+ k = k + 1
+ local v = stack[k]
+ for r=1,nofregions do
+ v = v + stack[d+r] * factors[r]
+ end
+ stack[k] = round(v)
+ d = d + nofregions
+ end
+ end
+ end
+
+ local function p_getstem()
+ local n = 0
+ if top % 2 ~= 0 then
+ n = 1
+ end
+ if top > n then
+ stems = stems + idiv(top-n,2)
+ end
+ end
+
+ local function p_getmask()
+ local n = 0
+ if top % 2 ~= 0 then
+ n = 1
+ end
+ if top > n then
+ stems = stems + idiv(top-n,2)
+ end
+ if stems == 0 then
+ return 0
+ elseif stems <= 8 then
+ return 1
+ else
+ return idiv(stems+7,8)
+ end
+ end
+
+ -- end of experiment
+
+ local process
+
+ local function call(scope,list,bias) -- ,process)
+ depth = depth + 1
+ if top == 0 then
+ showstate(formatters["unknown %s call %s"](scope,"?"))
+ top = 0
+ else
+ local index = stack[top] + bias
+ top = top - 1
+ if trace_charstrings then
+ showvalue(scope,index,true)
+ end
+ local tab = list[index]
+ if tab then
+ process(tab)
+ else
+ showstate(formatters["unknown %s call %s"](scope,index))
+ top = 0
+ end
+ end
+ depth = depth - 1
+ end
+
+ -- precompiling and reuse is much slower than redoing the calls
+
+ local justpass = false
+
+ -- local function decode(str)
+ -- local a, b, c, d, e = byte(str,1,5)
+ -- if a == 28 then
+ -- if c then
+ -- local n = 0x100 * b + c
+ -- if n >= 0x8000 then
+ -- return n - 0x10000
+ -- else
+ -- return n
+ -- end
+ -- end
+ -- elseif a < 32 then
+ -- return false
+ -- elseif a <= 246 then
+ -- return a - 139
+ -- elseif a <= 250 then
+ -- if b then
+ -- return a*256 - 63124 + b
+ -- end
+ -- elseif a <= 254 then
+ -- if b then
+ -- return -a*256 + 64148 - b
+ -- end
+ -- else
+ -- if e then
+ -- local n = 0x100 * b + c
+ -- if n >= 0x8000 then
+ -- return n - 0x10000 + (0x100 * d + e)/0xFFFF
+ -- else
+ -- return n + (0x100 * d + e)/0xFFFF
+ -- end
+ -- end
+ -- end
+ -- return false
+ -- end
+
+ process = function(tab)
+ local i = 1
+ local n = #tab
+ while i <= n do
+ local t = tab[i]
+ if t >= 32 then
+ top = top + 1
+ if t <= 246 then
+ -- -107 .. +107
+ stack[top] = t - 139
+ i = i + 1
+ elseif t <= 250 then
+ -- +108 .. +1131
+ -- stack[top] = (t-247)*256 + tab[i+1] + 108
+ -- stack[top] = t*256 - 247*256 + tab[i+1] + 108
+ stack[top] = t*256 - 63124 + tab[i+1]
+ i = i + 2
+ elseif t <= 254 then
+ -- -1131 .. -108
+ -- stack[top] = -(t-251)*256 - tab[i+1] - 108
+ -- stack[top] = -t*256 + 251*256 - tab[i+1] - 108
+ stack[top] = -t*256 + 64148 - tab[i+1]
+ i = i + 2
+ else
+ -- a 16.16 float
+ local n = 0x100 * tab[i+1] + tab[i+2]
+ if n >= 0x8000 then
+ stack[top] = n - 0x10000 + (0x100 * tab[i+3] + tab[i+4])/0xFFFF
+ else
+ stack[top] = n + (0x100 * tab[i+3] + tab[i+4])/0xFFFF
+ end
+ i = i + 5
+ end
+ elseif t == 28 then
+ -- -32768 .. +32767 : b1<<8 | b2
+ top = top + 1
+ local n = 0x100 * tab[i+1] + tab[i+2]
+ if n >= 0x8000 then
+ -- stack[top] = n - 0xFFFF - 1
+ stack[top] = n - 0x10000
+ else
+ stack[top] = n
+ end
+ i = i + 3
+ elseif t == 11 then -- not in cff2
+ if trace_charstrings then
+ showstate("return")
+ end
+ return
+ elseif t == 10 then
+ call("local",locals,localbias) -- ,process)
+ i = i + 1
+ elseif t == 14 then -- not in cff2
+ if width then
+ -- okay
+ elseif top > 0 then
+ width = stack[1]
+ if trace_charstrings then
+ showvalue("width",width)
+ end
+ else
+ width = true
+ end
+ if trace_charstrings then
+ showstate("endchar")
+ end
+ return
+ elseif t == 29 then
+ call("global",globals,globalbias) -- ,process)
+ i = i + 1
+ elseif t == 12 then
+ i = i + 1
+ local t = tab[i]
+ if justpass then
+ if t >= 34 and t <= 37 then -- flexes
+ for i=1,top do
+ r = r + 1 ; result[r] = encode[stack[i]]
+ end
+ r = r + 1 ; result[r] = chars[12]
+ r = r + 1 ; result[r] = chars[t]
+ top = 0
+ else
+ local a = subactions[t]
+ if a then
+ a(t)
+ else
+ top = 0
+ end
+ end
+ else
+ local a = subactions[t]
+ if a then
+ a(t)
+ else
+ if trace_charstrings then
+ showvalue("<subaction>",t)
+ end
+ top = 0
+ end
+ end
+ i = i + 1
+ elseif justpass then
+ -- todo: local a = passactions
+ if t == 15 then
+ p_setvsindex()
+ i = i + 1
+ elseif t == 16 then
+ local s = p_blend() or 0
+ i = i + s + 1
+ -- cff 1: (when cff2 strip them)
+ elseif t == 1 or t == 3 or t == 18 or operation == 23 then
+ p_getstem() -- at the start
+if true then
+ if top > 0 then
+ for i=1,top do
+ r = r + 1 ; result[r] = encode[stack[i]]
+ end
+ top = 0
+ end
+ r = r + 1 ; result[r] = chars[t]
+else
+ top = 0
+end
+ i = i + 1
+ -- cff 1: (when cff2 strip them)
+ elseif t == 19 or t == 20 then
+ local s = p_getmask() or 0 -- after the stems
+if true then
+ if top > 0 then
+ for i=1,top do
+ r = r + 1 ; result[r] = encode[stack[i]]
+ end
+ top = 0
+ end
+ r = r + 1 ; result[r] = chars[t]
+ for j=1,s do
+ i = i + 1
+ r = r + 1 ; result[r] = chars[tab[i]]
+ end
+else
+ i = i + s
+ top = 0
+end
+ i = i + 1
+ -- cff 1: closepath
+ elseif t == 9 then
+ top = 0
+ i = i + 1
+ elseif t == 13 then
+ local s = hsbw() or 0
+ i = i + s + 1
+ else
+ if top > 0 then
+ for i=1,top do
+ r = r + 1 ; result[r] = encode[stack[i]]
+ end
+ top = 0
+ end
+ r = r + 1 ; result[r] = chars[t]
+ i = i + 1
+ end
+ else
+ local a = actions[t]
+ if a then
+ local s = a(t)
+ if s then
+ i = i + s + 1
+ else
+ i = i + 1
+ end
+ else
+ if trace_charstrings then
+ showvalue("<action>",t)
+ end
+ top = 0
+ i = i + 1
+ end
+ end
+ end
+ end
+
+ -- local function calculatebounds(segments,x,y)
+ -- local nofsegments = #segments
+ -- if nofsegments == 0 then
+ -- return { x, y, x, y }
+ -- else
+ -- local xmin = 10000
+ -- local xmax = -10000
+ -- local ymin = 10000
+ -- local ymax = -10000
+ -- if x < xmin then xmin = x end
+ -- if x > xmax then xmax = x end
+ -- if y < ymin then ymin = y end
+ -- if y > ymax then ymax = y end
+ -- -- we now have a reasonable start so we could
+ -- -- simplify the next checks
+ -- for i=1,nofsegments do
+ -- local s = segments[i]
+ -- local x = s[1]
+ -- local y = s[2]
+ -- if x < xmin then xmin = x end
+ -- if x > xmax then xmax = x end
+ -- if y < ymin then ymin = y end
+ -- if y > ymax then ymax = y end
+ -- if s[#s] == "c" then -- "curveto"
+ -- local x = s[3]
+ -- local y = s[4]
+ -- if x < xmin then xmin = x elseif x > xmax then xmax = x end
+ -- if y < ymin then ymin = y elseif y > ymax then ymax = y end
+ -- local x = s[5]
+ -- local y = s[6]
+ -- if x < xmin then xmin = x elseif x > xmax then xmax = x end
+ -- if y < ymin then ymin = y elseif y > ymax then ymax = y end
+ -- end
+ -- end
+ -- return { round(xmin), round(ymin), round(xmax), round(ymax) } -- doesn't make ceil more sense
+ -- end
+ -- end
+
+ local function setbias(globals,locals,nobias)
+ if nobias then
+ return 0, 0
+ else
+ local g = #globals
+ local l = #locals
+ return
+ ((g < 1240 and 107) or (g < 33900 and 1131) or 32768) + 1,
+ ((l < 1240 and 107) or (l < 33900 and 1131) or 32768) + 1
+ end
+ end
+
+ local function processshape(tab,index)
+
+ if not tab then
+ glyphs[index] = {
+ boundingbox = { 0, 0, 0, 0 },
+ width = 0,
+ name = charset and charset[index] or nil,
+ }
+ return
+ end
+
+ tab = bytetable(tab)
+
+ x = 0
+ y = 0
+ width = false
+ r = 0
+ top = 0
+ stems = 0
+ result = { } -- we could reuse it when only boundingbox calculations are needed
+
+ xmin = 0
+ xmax = 0
+ ymin = 0
+ ymax = 0
+ checked = false
+ if trace_charstrings then
+ report("glyph: %i",index)
+ report("data : % t",tab)
+ end
+
+ if regions then
+ updateregions(vsindex)
+ end
+
+ process(tab)
+
+ local boundingbox = {
+ round(xmin),
+ round(ymin),
+ round(xmax),
+ round(ymax),
+ }
+
+ if width == true or width == false then
+ width = defaultwidth
+ else
+ width = nominalwidth + width
+ end
+
+ local glyph = glyphs[index] -- can be autodefined in otr
+ if justpass then
+ 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
+ glyphs[index] = { stream = stream }
+ end
+ elseif glyph then
+ glyph.segments = keepcurve ~= false and result or nil
+ glyph.boundingbox = boundingbox
+ if not glyph.width then
+ glyph.width = width
+ end
+ if charset and not glyph.name then
+ glyph.name = charset[index]
+ end
+ -- glyph.sidebearing = 0 -- todo
+ elseif keepcurve then
+ glyphs[index] = {
+ segments = result,
+ boundingbox = boundingbox,
+ width = width,
+ name = charset and charset[index] or nil,
+ -- sidebearing = 0,
+ }
+ else
+ glyphs[index] = {
+ boundingbox = boundingbox,
+ width = width,
+ name = charset and charset[index] or nil,
+ }
+ end
+
+ if trace_charstrings then
+ report("width : %s",tostring(width))
+ report("boundingbox: % t",boundingbox)
+ end
+
+ end
+
+ startparsing = function(fontdata,data,streams)
+ reginit = false
+ axis = false
+ regions = data.regions
+ justpass = streams == true
+ if regions then
+ regions = { regions } -- needs checking
+ axis = data.factors or false
+ end
+ end
+
+ stopparsing = function(fontdata,data)
+ stack = { }
+ glyphs = false
+ result = { }
+ top = 0
+ locals = false
+ globals = false
+ strings = false
+ end
+
+ local function setwidths(private)
+ if not private then
+ return 0, 0
+ end
+ local privatedata = private.data
+ if not privatedata then
+ return 0, 0
+ end
+ return privatedata.nominalwidthx or 0, privatedata.defaultwidthx or 0
+ end
+
+ parsecharstrings = function(fontdata,data,glphs,doshapes,tversion,streams,nobias)
+
+ local dictionary = data.dictionaries[1]
+ local charstrings = dictionary.charstrings
+
+ keepcurve = doshapes
+ version = tversion
+ strings = data.strings
+ globals = data.routines or { }
+ locals = dictionary.subroutines or { }
+ charset = dictionary.charset
+ vsindex = dictionary.vsindex or 0
+ glyphs = glphs or { }
+
+ globalbias, localbias = setbias(globals,locals,nobias)
+ nominalwidth, defaultwidth = setwidths(dictionary.private)
+
+ if charstrings then
+ startparsing(fontdata,data,streams)
+ for index=1,#charstrings do
+ processshape(charstrings[index],index-1)
+-- charstrings[index] = nil -- free memory (what if used more often?)
+ end
+ stopparsing(fontdata,data)
+ else
+ report("no charstrings")
+ end
+ return glyphs
+ end
+
+ parsecharstring = function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams)
+
+ keepcurve = doshapes
+ version = tversion
+ strings = data.strings
+ globals = data.routines or { }
+ locals = dictionary.subroutines or { }
+ charset = false
+ vsindex = dictionary.vsindex or 0
+ glyphs = glphs or { }
+
+ justpass = streams == true
+
+ globalbias, localbias = setbias(globals,locals,nobias)
+ nominalwidth, defaultwidth = setwidths(dictionary.private)
+
+ processshape(tab,index-1)
+
+ -- return glyphs[index]
+ end
+
+end
+
+local function readglobals(f,data)
+ local routines = readlengths(f)
+ for i=1,#routines do
+ routines[i] = readbytetable(f,routines[i])
+ end
+ data.routines = routines
+end
+
+local function readencodings(f,data)
+ data.encodings = { }
+end
+
+local function readcharsets(f,data,dictionary)
+ local header = data.header
+ local strings = data.strings
+ local nofglyphs = data.nofglyphs
+ local charsetoffset = dictionary.charset
+ if charsetoffset and charsetoffset ~= 0 then
+ setposition(f,header.offset+charsetoffset)
+ local format = readbyte(f)
+ local charset = { [0] = ".notdef" }
+ dictionary.charset = charset
+ if format == 0 then
+ for i=1,nofglyphs do
+ charset[i] = strings[readushort(f)]
+ end
+ elseif format == 1 or format == 2 then
+ local readcount = format == 1 and readbyte or readushort
+ local i = 1
+ while i <= nofglyphs do
+ local sid = readushort(f)
+ local n = readcount(f)
+ for s=sid,sid+n do
+ charset[i] = strings[s]
+ i = i + 1
+ if i > nofglyphs then
+ break
+ end
+ end
+ end
+ else
+ report("cff parser: unsupported charset format %a",format)
+ end
+ else
+ dictionary.nocharset = true
+ dictionary.charset = nil
+ end
+end
+
+local function readprivates(f,data)
+ local header = data.header
+ local dictionaries = data.dictionaries
+ local private = dictionaries[1].private
+ if private then
+ setposition(f,header.offset+private.offset)
+ private.data = readstring(f,private.size)
+ end
+end
+
+local function readlocals(f,data,dictionary)
+ local header = data.header
+ local private = dictionary.private
+ if private then
+ local subroutineoffset = private.data.subroutines
+ if subroutineoffset ~= 0 then
+ setposition(f,header.offset+private.offset+subroutineoffset)
+ local subroutines = readlengths(f)
+ for i=1,#subroutines do
+ subroutines[i] = readbytetable(f,subroutines[i])
+ end
+ dictionary.subroutines = subroutines
+ private.data.subroutines = nil
+ else
+ dictionary.subroutines = { }
+ end
+ else
+ dictionary.subroutines = { }
+ end
+end
+
+-- These charstrings are little programs and described in: Technical Note #5177. A truetype
+-- font has only one dictionary.
+
+local function readcharstrings(f,data,what)
+ local header = data.header
+ local dictionaries = data.dictionaries
+ local dictionary = dictionaries[1]
+ local stringtype = dictionary.charstringtype
+ local offset = dictionary.charstrings
+ if type(offset) ~= "number" then
+ -- weird
+ elseif stringtype == 2 then
+ setposition(f,header.offset+offset)
+ -- could be a metatable .. delayed loading
+ local charstrings = readlengths(f,what=="cff2")
+ local nofglyphs = #charstrings
+ for i=1,nofglyphs do
+ charstrings[i] = readstring(f,charstrings[i])
+ end
+ data.nofglyphs = nofglyphs
+ dictionary.charstrings = charstrings
+ else
+ report("unsupported charstr type %i",stringtype)
+ data.nofglyphs = 0
+ dictionary.charstrings = { }
+ end
+end
+
+-- cid (maybe do this stepwise so less mem) -- share with above
+
+local function readcidprivates(f,data)
+ local header = data.header
+ local dictionaries = data.dictionaries[1].cid.dictionaries
+ for i=1,#dictionaries do
+ local dictionary = dictionaries[i]
+ local private = dictionary.private
+ if private then
+ setposition(f,header.offset+private.offset)
+ private.data = readstring(f,private.size)
+ end
+ end
+ parseprivates(data,dictionaries)
+end
+
+readers.parsecharstrings = parsecharstrings -- used in font-onr.lua (type 1)
+
+local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
+ local dictionaries = data.dictionaries
+ local dictionary = dictionaries[1]
+ readglobals(f,data)
+ readcharstrings(f,data,version)
+ if version == "cff2" then
+ dictionary.charset = nil
+ else
+ readencodings(f,data)
+ readcharsets(f,data,dictionary)
+ end
+ readprivates(f,data)
+ parseprivates(data,data.dictionaries)
+ readlocals(f,data,dictionary)
+ startparsing(fontdata,data,streams)
+ parsecharstrings(fontdata,data,glyphs,doshapes,version,streams)
+ stopparsing(fontdata,data)
+end
+
+local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
+ local header = data.header
+ local dictionaries = data.dictionaries
+ local dictionary = dictionaries[1]
+ local cid = dictionary.cid
+ local cidselect = cid and cid.fdselect
+ readglobals(f,data)
+ readcharstrings(f,data,version)
+ if version ~= "cff2" then
+ readencodings(f,data)
+ end
+ local charstrings = dictionary.charstrings
+ local fdindex = { }
+ local nofglyphs = data.nofglyphs
+ local maxindex = -1
+ setposition(f,header.offset+cidselect)
+ local format = readbyte(f)
+ if format == 1 then
+ for i=0,nofglyphs do -- notdef included (needs checking)
+ local index = readbyte(f)
+ fdindex[i] = index
+ if index > maxindex then
+ maxindex = index
+ end
+ end
+ elseif format == 3 then
+ local nofranges = readushort(f)
+ local first = readushort(f)
+ local index = readbyte(f)
+ while true do
+ local last = readushort(f)
+ if index > maxindex then
+ maxindex = index
+ end
+ for i=first,last do
+ fdindex[i] = index
+ end
+ if last >= nofglyphs then
+ break
+ else
+ first = last + 1
+ index = readbyte(f)
+ end
+ end
+ else
+ -- unsupported format
+ end
+ -- hm, always
+ if maxindex >= 0 then
+ local cidarray = cid.fdarray
+ if cidarray then
+ setposition(f,header.offset+cidarray)
+ local dictionaries = readlengths(f)
+ for i=1,#dictionaries do
+ dictionaries[i] = readstring(f,dictionaries[i])
+ end
+ parsedictionaries(data,dictionaries)
+ cid.dictionaries = dictionaries
+ readcidprivates(f,data)
+ for i=1,#dictionaries do
+ readlocals(f,data,dictionaries[i])
+ end
+ startparsing(fontdata,data,streams)
+ for i=1,#charstrings do
+ parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version,streams)
+-- charstrings[i] = nil
+ end
+ stopparsing(fontdata,data)
+ else
+ report("no cid array")
+ end
+ end
+end
+
+local gotodatatable = readers.helpers.gotodatatable
+
+local function cleanup(data,dictionaries)
+ -- for i=1,#dictionaries do
+ -- local d = dictionaries[i]
+ -- d.subroutines = nil
+ -- end
+ -- data.strings = nil
+ -- if data then
+ -- data.charstrings = nil
+ -- data.routines = nil
+ -- end
+end
+
+function readers.cff(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs)
+ if tableoffset then
+ local header = readheader(f)
+ if header.major ~= 1 then
+ report("only version %s is supported for table %a",1,"cff")
+ return
+ end
+ local glyphs = fontdata.glyphs
+ local names = readfontnames(f)
+ local dictionaries = readtopdictionaries(f)
+ local strings = readstrings(f)
+ local data = {
+ header = header,
+ names = names,
+ dictionaries = dictionaries,
+ strings = strings,
+ nofglyphs = fontdata.nofglyphs,
+ }
+ --
+ parsedictionaries(data,dictionaries,"cff")
+ --
+ local dic = dictionaries[1]
+ local cid = dic.cid
+ --
+ local cffinfo = {
+ familyname = dic.familyname,
+ fullname = dic.fullname,
+ boundingbox = dic.boundingbox,
+ weight = dic.weight,
+ italicangle = dic.italicangle,
+ underlineposition = dic.underlineposition,
+ underlinethickness = dic.underlinethickness,
+ defaultwidth = dic.defaultwidthx,
+ nominalwidth = dic.nominalwidthx,
+ monospaced = dic.monospaced,
+ }
+ fontdata.cidinfo = cid and {
+ registry = cid.registry,
+ ordering = cid.ordering,
+ supplement = cid.supplement,
+ }
+ fontdata.cffinfo = cffinfo
+ --
+ local all = specification.shapes or specification.streams or false
+ if specification.glyphs or all then
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
+ else
+ readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
+ end
+ end
+ local private = dic.private
+ if private then
+ local data = private.data
+ if type(data) == "table" then
+ cffinfo.defaultwidth = data.defaultwidthx or cffinfo.defaultwidth
+ cffinfo.nominalwidth = data.nominalwidthx or cffinfo.nominalwidth
+ cffinfo.bluevalues = data.bluevalues
+ cffinfo.otherblues = data.otherblues
+ cffinfo.familyblues = data.familyblues
+ cffinfo.familyotherblues = data.familyotherblues
+ cffinfo.bluescale = data.bluescale
+ cffinfo.blueshift = data.blueshift
+ cffinfo.bluefuzz = data.bluefuzz
+ cffinfo.stdhw = data.stdhw
+ cffinfo.stdvw = data.stdvw
+ end
+ end
+ cleanup(data,dictionaries)
+ end
+end
+
+function readers.cff2(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"cff2",specification.glyphs)
+ if tableoffset then
+ local header = readheader(f)
+ if header.major ~= 2 then
+ report("only version %s is supported for table %a",2,"cff2")
+ return
+ end
+ local glyphs = fontdata.glyphs
+ local dictionaries = { readstring(f,header.dsize) }
+ local data = {
+ header = header,
+ dictionaries = dictionaries,
+ nofglyphs = fontdata.nofglyphs,
+ }
+ --
+ parsedictionaries(data,dictionaries,"cff2")
+ --
+ 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
+ local all = specification.shapes or specification.streams or false
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
+ else
+ readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
+ end
+ cleanup(data,dictionaries)
+ end
+end
+
+-- temporary helper needed for checking backend patches
+
+function readers.cffcheck(filename)
+ local f = io.open(filename,"rb")
+ if f then
+ local fontdata = {
+ glyphs = { },
+ }
+ local header = readheader(f)
+ if header.major ~= 1 then
+ report("only version %s is supported for table %a",1,"cff")
+ return
+ end
+ local names = readfontnames(f)
+ local dictionaries = readtopdictionaries(f)
+ local strings = readstrings(f)
+ local glyphs = { }
+ local data = {
+ header = header,
+ names = names,
+ dictionaries = dictionaries,
+ strings = strings,
+ glyphs = glyphs,
+ nofglyphs = 0,
+ }
+ --
+ parsedictionaries(data,dictionaries,"cff")
+ --
+ local cid = data.dictionaries[1].cid
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,false)
+ else
+ readnoselect(f,fontdata,data,glyphs,false)
+ end
+ return data
+ end
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-cid.lua b/macros/luatex/generic/luaotfload/fontloader-font-cid.lua
new file mode 100644
index 0000000000..781bc9fec9
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-cid.lua
@@ -0,0 +1,177 @@
+if not modules then modules = { } end modules ['font-cid'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, match, lower = string.format, string.match, string.lower
+local tonumber = tonumber
+local P, S, R, C, V, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.match
+
+local fonts, logs, trackers = fonts, logs, trackers
+
+local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
+
+local report_otf = logs.reporter("fonts","otf loading")
+
+local cid = { }
+fonts.cid = cid
+
+local cidmap = { }
+local cidmax = 10
+
+-- original string parser: 0.109, lpeg parser: 0.036 seconds for Adobe-CNS1-4.cidmap
+--
+-- 18964 18964 (leader)
+-- 0 /.notdef
+-- 1..95 0020
+-- 99 3000
+
+local number = C(R("09","af","AF")^1)
+local space = S(" \n\r\t")
+local spaces = space^0
+local period = P(".")
+local periods = period * period
+local name = P("/") * C((1-space)^1)
+
+local unicodes, names = { }, { } -- we could use Carg now
+
+local function do_one(a,b)
+ unicodes[tonumber(a)] = tonumber(b,16)
+end
+
+local function do_range(a,b,c)
+ c = tonumber(c,16)
+ for i=tonumber(a),tonumber(b) do
+ unicodes[i] = c
+ c = c + 1
+ end
+end
+
+local function do_name(a,b)
+ names[tonumber(a)] = b
+end
+
+local grammar = P { "start",
+ start = number * spaces * number * V("series"),
+ series = (spaces * (V("one") + V("range") + V("named")))^1,
+ one = (number * spaces * number) / do_one,
+ range = (number * periods * number * spaces * number) / do_range,
+ named = (number * spaces * name) / do_name
+}
+
+local function loadcidfile(filename)
+ local data = io.loaddata(filename)
+ if data then
+ unicodes, names = { }, { }
+ lpegmatch(grammar,data)
+ local supplement, registry, ordering = match(filename,"^(.-)%-(.-)%-()%.(.-)$")
+ return {
+ supplement = supplement,
+ registry = registry,
+ ordering = ordering,
+ filename = filename,
+ unicodes = unicodes,
+ names = names,
+ }
+ end
+end
+
+cid.loadfile = loadcidfile -- we use the frozen variant
+local template = "%s-%s-%s.cidmap"
+
+local function locate(registry,ordering,supplement)
+ local filename = format(template,registry,ordering,supplement)
+ local hashname = lower(filename)
+ local found = cidmap[hashname]
+ if not found then
+ if trace_loading then
+ report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename)
+ end
+ local fullname = resolvers.findfile(filename,'cid') or ""
+ if fullname ~= "" then
+ found = loadcidfile(fullname)
+ if found then
+ if trace_loading then
+ report_otf("using cidmap file %a",filename)
+ end
+ cidmap[hashname] = found
+ found.usedname = file.basename(filename)
+ end
+ end
+ end
+ return found
+end
+
+-- cf Arthur R. we can safely scan upwards since cids are downward compatible
+
+function cid.getmap(specification)
+ if not specification then
+ report_otf("invalid cidinfo specification, table expected")
+ return
+ end
+ local registry = specification.registry
+ local ordering = specification.ordering
+ local supplement = specification.supplement
+ local filename = format(registry,ordering,supplement)
+ local lowername = lower(filename)
+ local found = cidmap[lowername]
+ if found then
+ return found
+ end
+ if ordering == "Identity" then
+ local found = {
+ supplement = supplement,
+ registry = registry,
+ ordering = ordering,
+ filename = filename,
+ unicodes = { },
+ names = { },
+ }
+ cidmap[lowername] = found
+ return found
+ end
+ -- check for already loaded file
+ if trace_loading then
+ report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement)
+ end
+ found = locate(registry,ordering,supplement)
+ if not found then
+ local supnum = tonumber(supplement)
+ local cidnum = nil
+ -- next highest (alternatively we could start high)
+ if supnum < cidmax then
+ for s=supnum+1,cidmax do
+ local c = locate(registry,ordering,s)
+ if c then
+ found, cidnum = c, s
+ break
+ end
+ end
+ end
+ -- next lowest (least worse fit)
+ if not found and supnum > 0 then
+ for s=supnum-1,0,-1 do
+ local c = locate(registry,ordering,s)
+ if c then
+ found, cidnum = c, s
+ break
+ end
+ end
+ end
+ -- prevent further lookups -- somewhat tricky
+ registry = lower(registry)
+ ordering = lower(ordering)
+ if found and cidnum > 0 then
+ for s=0,cidnum-1 do
+ local filename = format(template,registry,ordering,s)
+ if not cidmap[filename] then
+ cidmap[filename] = found
+ end
+ end
+ end
+ end
+ return found
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-con.lua b/macros/luatex/generic/luaotfload/fontloader-font-con.lua
new file mode 100644
index 0000000000..9c1e825fa2
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-con.lua
@@ -0,0 +1,1711 @@
+if not modules then modules = { } end modules ['font-con'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- some names of table entries will be changed (no _)
+
+local next, tostring, tonumber, rawget = next, tostring, tonumber, rawget
+local format, match, lower, gsub, find = string.format, string.match, string.lower, string.gsub, string.find
+local sort, insert, concat = table.sort, table.insert, table.concat
+local sortedkeys, sortedhash, serialize, fastcopy = table.sortedkeys, table.sortedhash, table.serialize, table.fastcopy
+local derivetable = table.derive
+local ioflush = io.flush
+local round = math.round
+local setmetatable, getmetatable, rawget, rawset = setmetatable, getmetatable, rawget, rawset
+
+local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+local trace_scaling = false trackers.register("fonts.scaling", function(v) trace_scaling = v end)
+
+local report_defining = logs.reporter("fonts","defining")
+
+-- watch out: no negative depths and negative eights permitted in regular fonts
+
+--[[ldx--
+<p>Here we only implement a few helper functions.</p>
+--ldx]]--
+
+local fonts = fonts
+local constructors = fonts.constructors or { }
+fonts.constructors = constructors
+local handlers = fonts.handlers or { } -- can have preloaded tables
+fonts.handlers = handlers
+
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+
+-- will be directives
+
+constructors.dontembed = allocate()
+constructors.autocleanup = true
+constructors.namemode = "fullpath" -- will be a function
+
+constructors.version = 1.01
+constructors.cache = containers.define("fonts", "constructors", constructors.version, false)
+
+constructors.privateoffset = fonts.privateoffsets.textbase or 0xF0000
+constructors.cacheintex = true -- so we see the original table in fonts.font
+
+constructors.addtounicode = true
+
+-- This might become an interface:
+
+local designsizes = allocate()
+constructors.designsizes = designsizes
+local loadedfonts = allocate()
+constructors.loadedfonts = loadedfonts
+
+--[[ldx--
+<p>We need to normalize the scale factor (in scaled points). This has to
+do with the fact that <l n='tex'/> uses a negative multiple of 1000 as
+a signal for a font scaled based on the design size.</p>
+--ldx]]--
+
+local factors = {
+ pt = 65536.0,
+ bp = 65781.8,
+}
+
+function constructors.setfactor(f)
+ constructors.factor = factors[f or 'pt'] or factors.pt
+end
+
+constructors.setfactor()
+
+function constructors.scaled(scaledpoints, designsize) -- handles designsize in sp as well
+ if scaledpoints < 0 then
+ local factor = constructors.factor
+ if designsize then
+ if designsize > factor then -- or just 1000 / when? mp?
+ return (- scaledpoints/1000) * designsize -- sp's
+ else
+ return (- scaledpoints/1000) * designsize * factor
+ end
+ else
+ return (- scaledpoints/1000) * 10 * factor
+ end
+ else
+ return scaledpoints
+ end
+end
+
+function constructors.getprivate(tfmdata)
+ local properties = tfmdata.properties
+ local private = properties.private
+ properties.private = private + 1
+ return private
+end
+
+function constructors.setmathparameter(tfmdata,name,value)
+ local m = tfmdata.mathparameters
+ local c = tfmdata.MathConstants
+ if m then
+ m[name] = value
+ end
+ if c and c ~= m then
+ c[name] = value
+ end
+end
+
+function constructors.getmathparameter(tfmdata,name)
+ local p = tfmdata.mathparameters or tfmdata.MathConstants
+ if p then
+ return p[name]
+ end
+end
+
+--[[ldx--
+<p>Beware, the boundingbox is passed as reference so we may not overwrite it
+in the process; numbers are of course copies. Here 65536 equals 1pt. (Due to
+excessive memory usage in CJK fonts, we no longer pass the boundingbox.)</p>
+--ldx]]--
+
+-- The scaler is only used for otf and afm and virtual fonts. If a virtual font has italic
+-- correction make sure to set the hasitalics flag. Some more flags will be added in the
+-- future.
+
+--[[ldx--
+<p>The reason why the scaler was originally split, is that for a while we experimented
+with a helper function. However, in practice the <l n='api'/> calls are too slow to
+make this profitable and the <l n='lua'/> based variant was just faster. A days
+wasted day but an experience richer.</p>
+--ldx]]--
+
+-- we can get rid of the tfm instance when we have fast access to the
+-- scaled character dimensions at the tex end, e.g. a fontobject.width
+-- actually we already have some of that now as virtual keys in glyphs
+--
+-- flushing the kern and ligature tables from memory saves a lot (only
+-- base mode) but it complicates vf building where the new characters
+-- demand this data .. solution: functions that access them
+
+function constructors.cleanuptable(tfmdata)
+ if constructors.autocleanup and tfmdata.properties.virtualized then
+ for k, v in next, tfmdata.characters do
+ if v.commands then v.commands = nil end
+ -- if v.kerns then v.kerns = nil end
+ end
+ end
+end
+
+-- experimental, sharing kerns (unscaled and scaled) saves memory
+-- local sharedkerns, basekerns = constructors.check_base_kerns(tfmdata)
+-- loop over descriptions (afm and otf have descriptions, tfm not)
+-- there is no need (yet) to assign a value to chr.tonunicode
+
+-- constructors.prepare_base_kerns(tfmdata) -- optimalization
+
+-- we have target.name=metricfile and target.fullname=RealName and target.filename=diskfilename
+-- when collapsing fonts, luatex looks as both target.name and target.fullname as ttc files
+-- can have multiple subfonts
+
+function constructors.calculatescale(tfmdata,scaledpoints)
+ local parameters = tfmdata.parameters
+ if scaledpoints < 0 then
+ scaledpoints = (- scaledpoints/1000) * (tfmdata.designsize or parameters.designsize) -- already in sp
+ end
+ return scaledpoints, scaledpoints / (parameters.units or 1000) -- delta
+end
+
+local unscaled = {
+ ScriptPercentScaleDown = true,
+ ScriptScriptPercentScaleDown = true,
+ RadicalDegreeBottomRaisePercent = true,
+ NoLimitSupFactor = true,
+ NoLimitSubFactor = true,
+}
+
+function constructors.assignmathparameters(target,original) -- simple variant, not used in context
+ -- when a tfm file is loaded, it has already been scaled
+ -- and it never enters the scaled so this is otf only and
+ -- even then we do some extra in the context math plugins
+ local mathparameters = original.mathparameters
+ if mathparameters and next(mathparameters) then
+ local targetparameters = target.parameters
+ local targetproperties = target.properties
+ local targetmathparameters = { }
+ local factor = targetproperties.math_is_scaled and 1 or targetparameters.factor
+ for name, value in next, mathparameters do
+ if unscaled[name] then
+ targetmathparameters[name] = value
+ else
+ targetmathparameters[name] = value * factor
+ end
+ end
+ if not targetmathparameters.FractionDelimiterSize then
+ targetmathparameters.FractionDelimiterSize = 1.01 * targetparameters.size
+ end
+ if not mathparameters.FractionDelimiterDisplayStyleSize then
+ targetmathparameters.FractionDelimiterDisplayStyleSize = 2.40 * targetparameters.size
+ end
+ target.mathparameters = targetmathparameters
+ end
+end
+
+function constructors.beforecopyingcharacters(target,original)
+ -- can be used for additional tweaking
+end
+
+function constructors.aftercopyingcharacters(target,original)
+ -- can be used for additional tweaking
+end
+
+-- It's probably ok to hash just the indices because there is not that much
+-- chance that one will shift slots and leave the others unset then. Anyway,
+-- there is of course some overhead here, but it might as well get compensated
+-- by less time spent on including the font resource twice. For the moment
+-- we default to false, so a macro package has to enable it explicitly. In
+-- LuaTeX the fullname is used to identify a font as being unique.
+
+constructors.sharefonts = false
+constructors.nofsharedfonts = 0
+local sharednames = { }
+
+function constructors.trytosharefont(target,tfmdata)
+ if constructors.sharefonts then -- not robust !
+ local characters = target.characters
+ local n = 1
+ local t = { target.psname }
+ local u = sortedkeys(characters)
+ for i=1,#u do
+ local k = u[i]
+ n = n + 1 ; t[n] = k
+ n = n + 1 ; t[n] = characters[k].index or k
+ end
+ local h = md5.HEX(concat(t," "))
+ local s = sharednames[h]
+ if s then
+ if trace_defining then
+ report_defining("font %a uses backend resources of font %a",target.fullname,s)
+ end
+ target.fullname = s
+ constructors.nofsharedfonts = constructors.nofsharedfonts + 1
+ target.properties.sharedwith = s
+ else
+ sharednames[h] = target.fullname
+ end
+ end
+end
+
+-- function constructors.enhanceparameters(parameters)
+-- local xheight = parameters.x_height
+-- local quad = parameters.quad
+-- local space = parameters.space
+-- local stretch = parameters.space_stretch
+-- local shrink = parameters.space_shrink
+-- local extra = parameters.extra_space
+-- local slant = parameters.slant
+-- -- synonyms
+-- parameters.xheight = xheight
+-- parameters.spacestretch = stretch
+-- parameters.spaceshrink = shrink
+-- parameters.extraspace = extra
+-- parameters.em = quad
+-- parameters.ex = xheight
+-- parameters.slantperpoint = slant
+-- parameters.spacing = {
+-- width = space,
+-- stretch = stretch,
+-- shrink = shrink,
+-- extra = extra,
+-- }
+-- end
+
+local synonyms = {
+ exheight = "x_height",
+ xheight = "x_height",
+ ex = "x_height",
+ emwidth = "quad",
+ em = "quad",
+ spacestretch = "space_stretch",
+ stretch = "space_stretch",
+ spaceshrink = "space_shrink",
+ shrink = "space_shrink",
+ extraspace = "extra_space",
+ xspace = "extra_space",
+ slantperpoint = "slant",
+}
+
+function constructors.enhanceparameters(parameters)
+ local mt = getmetatable(parameters)
+ local getter = function(t,k)
+ if not k then
+ return nil
+ end
+ local s = synonyms[k]
+ if s then
+ return rawget(t,s) or (mt and mt[s]) or nil
+ end
+ if k == "spacing" then
+ return {
+ width = t.space,
+ stretch = t.space_stretch,
+ shrink = t.space_shrink,
+ extra = t.extra_space,
+ }
+ end
+ return mt and mt[k] or nil
+ end
+ local setter = function(t,k,v)
+ if not k then
+ return 0
+ end
+ local s = synonyms[k]
+ if s then
+ rawset(t,s,v)
+ elseif k == "spacing" then
+ if type(v) == "table" then
+ rawset(t,"space",v.width or 0)
+ rawset(t,"space_stretch",v.stretch or 0)
+ rawset(t,"space_shrink",v.shrink or 0)
+ rawset(t,"extra_space",v.extra or 0)
+ end
+ else
+ rawset(t,k,v)
+ end
+ end
+ setmetatable(parameters, {
+ __index = getter,
+ __newindex = setter,
+ })
+end
+
+local function mathkerns(v,vdelta)
+ local k = { }
+ for i=1,#v do
+ local entry = v[i]
+ local height = entry.height
+ local kern = entry.kern
+ k[i] = {
+ height = height and vdelta*height or 0,
+ kern = kern and vdelta*kern or 0,
+ }
+ end
+ return k
+end
+
+local psfake = 0
+
+local function fixedpsname(psname,fallback)
+ local usedname = psname
+ if psname and psname ~= "" then
+ if find(psname," ",1,true) then
+ usedname = gsub(psname,"[%s]+","-")
+ else
+ -- we assume that the name is sane enough (we might sanitize completely some day)
+ end
+ elseif not fallback or fallback == "" then
+ psfake = psfake + 1
+ psname = "fakename-" .. psfake
+ else
+ -- filenames can be a mess so we do a drastic cleanup
+ psname = fallback
+ usedname = gsub(psname,"[^a-zA-Z0-9]+","-")
+ end
+ return usedname, psname ~= usedname
+end
+
+function constructors.scale(tfmdata,specification)
+ local target = { } -- the new table
+ --
+ if tonumber(specification) then
+ specification = { size = specification }
+ end
+ target.specification = specification
+ --
+ local scaledpoints = specification.size
+ local relativeid = specification.relativeid
+ --
+ local properties = tfmdata.properties or { }
+ local goodies = tfmdata.goodies or { }
+ local resources = tfmdata.resources or { }
+ local descriptions = tfmdata.descriptions or { } -- bad news if empty
+ local characters = tfmdata.characters or { } -- bad news if empty
+ local changed = tfmdata.changed or { } -- for base mode
+ local shared = tfmdata.shared or { }
+ local parameters = tfmdata.parameters or { }
+ local mathparameters = tfmdata.mathparameters or { }
+ --
+ local targetcharacters = { }
+ local targetdescriptions = derivetable(descriptions)
+ local targetparameters = derivetable(parameters)
+ local targetproperties = derivetable(properties)
+ local targetgoodies = goodies -- we need to loop so no metatable
+ target.characters = targetcharacters
+ target.descriptions = targetdescriptions
+ target.parameters = targetparameters
+ -- target.mathparameters = targetmathparameters -- happens elsewhere
+ target.properties = targetproperties
+ target.goodies = targetgoodies
+ target.shared = shared
+ target.resources = resources
+ target.unscaled = tfmdata -- the original unscaled one
+ --
+ -- specification.mathsize : 1=text 2=script 3=scriptscript
+ -- specification.textsize : natural (text)size
+ -- parameters.mathsize : 1=text 2=script 3=scriptscript >1000 enforced size (feature value other than yes)
+ --
+ local mathsize = tonumber(specification.mathsize) or 0
+ local textsize = tonumber(specification.textsize) or scaledpoints
+ local forcedsize = tonumber(parameters.mathsize ) or 0 -- can be set by the feature "mathsize"
+ local extrafactor = tonumber(specification.factor ) or 1
+ if (mathsize == 2 or forcedsize == 2) and parameters.scriptpercentage then
+ scaledpoints = parameters.scriptpercentage * textsize / 100
+ elseif (mathsize == 3 or forcedsize == 3) and parameters.scriptscriptpercentage then
+ scaledpoints = parameters.scriptscriptpercentage * textsize / 100
+ elseif forcedsize > 1000 then -- safeguard
+ scaledpoints = forcedsize
+ else
+ -- in context x and xx also use mathsize
+ end
+ targetparameters.mathsize = mathsize -- context specific
+ targetparameters.textsize = textsize -- context specific
+ targetparameters.forcedsize = forcedsize -- context specific
+ targetparameters.extrafactor = extrafactor -- context specific
+ --
+ local addtounicode = constructors.addtounicode
+ --
+ local tounicode = fonts.mappings.tounicode
+ local unknowncode = tounicode(0xFFFD)
+ --
+ local defaultwidth = resources.defaultwidth or 0
+ local defaultheight = resources.defaultheight or 0
+ local defaultdepth = resources.defaultdepth or 0
+ local units = parameters.units or 1000
+ --
+ -- boundary keys are no longer needed as we now have a string 'right_boundary'
+ -- that can be used in relevant tables (kerns and ligatures) ... not that I ever
+ -- used them
+ --
+ -- boundarychar_label = 0, -- not needed
+ -- boundarychar = 65536, -- there is now a string 'right_boundary'
+ -- false_boundarychar = 65536, -- produces invalid tfm in luatex
+ --
+ targetproperties.language = properties.language or "dflt" -- inherited
+ targetproperties.script = properties.script or "dflt" -- inherited
+ targetproperties.mode = properties.mode or "base" -- inherited
+ --
+ local askedscaledpoints = scaledpoints
+ local scaledpoints, delta = constructors.calculatescale(tfmdata,scaledpoints,nil,specification) -- no shortcut, dan be redefined
+ --
+ local hdelta = delta
+ local vdelta = delta
+ --
+ target.designsize = parameters.designsize -- not really needed so it might become obsolete
+ target.units = units
+ target.units_per_em = units -- just a trigger for the backend
+ --
+ local direction = properties.direction or tfmdata.direction or 0 -- pointless, as we don't use omf fonts at all
+ target.direction = direction
+ properties.direction = direction
+ --
+ target.size = scaledpoints
+ --
+ target.encodingbytes = properties.encodingbytes or 1
+ target.embedding = properties.embedding or "subset"
+ target.tounicode = 1
+ target.cidinfo = properties.cidinfo
+ target.format = properties.format
+ target.cache = constructors.cacheintex and "yes" or "renew"
+ --
+ local fontname = properties.fontname or tfmdata.fontname
+ local fullname = properties.fullname or tfmdata.fullname
+ local filename = properties.filename or tfmdata.filename
+ local psname = properties.psname or tfmdata.psname
+ local name = properties.name or tfmdata.name
+ --
+ -- The psname used in pdf file as well as for selecting subfont in ttc although
+ -- we don't need that subfont look up here (mapfile stuff).
+ --
+ local psname, psfixed = fixedpsname(psname,fontname or fullname or file.nameonly(filename))
+ --
+ target.fontname = fontname
+ target.fullname = fullname
+ target.filename = filename
+ target.psname = psname
+ target.name = name
+ --
+ properties.fontname = fontname
+ properties.fullname = fullname
+ properties.filename = filename
+ properties.psname = psname
+ properties.name = name
+ -- expansion (hz)
+ local expansion = parameters.expansion
+ if expansion then
+ target.stretch = expansion.stretch
+ target.shrink = expansion.shrink
+ target.step = expansion.step
+ end
+ -- slanting
+ local slantfactor = parameters.slantfactor or 0
+ if slantfactor ~= 0 then
+ target.slant = slantfactor * 1000
+ else
+ target.slant = 0
+ end
+ -- widening
+ local extendfactor = parameters.extendfactor or 0
+ if extendfactor ~= 0 and extendfactor ~= 1 then
+ hdelta = hdelta * extendfactor
+ target.extend = extendfactor * 1000
+ else
+ target.extend = 1000 -- extent ?
+ end
+ -- squeezing
+ local squeezefactor = parameters.squeezefactor or 0
+ if squeezefactor ~= 0 and squeezefactor ~= 1 then
+ vdelta = vdelta * squeezefactor
+ target.squeeze = squeezefactor * 1000
+ else
+ target.squeeze = 1000 -- extent ?
+ end
+ -- effects
+ local mode = parameters.mode or 0
+ if mode ~= 0 then
+ target.mode = mode
+ end
+ local width = parameters.width or 0
+ if width ~= 0 then
+ target.width = width * delta * 1000 / 655360
+ end
+ --
+ targetparameters.factor = delta
+ targetparameters.hfactor = hdelta
+ targetparameters.vfactor = vdelta
+ targetparameters.size = scaledpoints
+ targetparameters.units = units
+ targetparameters.scaledpoints = askedscaledpoints
+ targetparameters.mode = mode
+ targetparameters.width = width
+ --
+ local isvirtual = properties.virtualized or tfmdata.type == "virtual"
+ local hasquality = parameters.expansion or parameters.protrusion
+ local hasitalics = properties.hasitalics
+ local autoitalicamount = properties.autoitalicamount
+ local stackmath = not properties.nostackmath
+ local haskerns = properties.haskerns or properties.mode == "base" -- we can have afm in node mode
+ local hasligatures = properties.hasligatures or properties.mode == "base" -- we can have afm in node mode
+ local realdimensions = properties.realdimensions
+ local writingmode = properties.writingmode or "horizontal"
+ local identity = properties.identity or "horizontal"
+ --
+ local vfonts = target.fonts
+ if vfonts and #vfonts > 0 then
+ target.fonts = fastcopy(vfonts) -- maybe we virtualize more afterwards
+ elseif isvirtual then
+ target.fonts = { { id = 0 } } -- catch error
+ end
+ --
+ if changed and not next(changed) then
+ changed = false
+ end
+ --
+ target.type = isvirtual and "virtual" or "real"
+ target.writingmode = writingmode == "vertical" and "vertical" or "horizontal"
+ target.identity = identity == "vertical" and "vertical" or "horizontal"
+ --
+ target.postprocessors = tfmdata.postprocessors
+ --
+ local targetslant = (parameters.slant or parameters[1] or 0) * factors.pt -- per point
+ local targetspace = (parameters.space or parameters[2] or 0) * hdelta
+ local targetspace_stretch = (parameters.space_stretch or parameters[3] or 0) * hdelta
+ local targetspace_shrink = (parameters.space_shrink or parameters[4] or 0) * hdelta
+ local targetx_height = (parameters.x_height or parameters[5] or 0) * vdelta
+ local targetquad = (parameters.quad or parameters[6] or 0) * hdelta
+ local targetextra_space = (parameters.extra_space or parameters[7] or 0) * hdelta
+ --
+ targetparameters.slant = targetslant -- slantperpoint
+ targetparameters.space = targetspace
+ targetparameters.space_stretch = targetspace_stretch
+ targetparameters.space_shrink = targetspace_shrink
+ targetparameters.x_height = targetx_height
+ targetparameters.quad = targetquad
+ targetparameters.extra_space = targetextra_space
+ --
+ local ascender = parameters.ascender
+ if ascender then
+ targetparameters.ascender = delta * ascender
+ end
+ local descender = parameters.descender
+ if descender then
+ targetparameters.descender = delta * descender
+ end
+ --
+ constructors.enhanceparameters(targetparameters) -- official copies for us, now virtual
+ --
+ local protrusionfactor = (targetquad ~= 0 and 1000/targetquad) or 0
+ local scaledwidth = defaultwidth * hdelta
+ local scaledheight = defaultheight * vdelta
+ local scaleddepth = defaultdepth * vdelta
+ --
+ local hasmath = (properties.hasmath or next(mathparameters)) and true
+ --
+ if hasmath then
+ constructors.assignmathparameters(target,tfmdata) -- does scaling and whatever is needed
+ properties.hasmath = true
+ target.nomath = false
+ target.MathConstants = target.mathparameters
+ else
+ properties.hasmath = false
+ target.nomath = true
+ target.mathparameters = nil -- nop
+ end
+ --
+ -- Here we support some context specific trickery (this might move to a plugin). During the
+ -- transition to opentype the engine had troubles with italics so we had some additional code
+ -- for fixing that. In node mode (text) we don't care much if italics gets passed because
+ -- the engine does nothign with them then.
+ --
+ if hasmath then
+ local mathitalics = properties.mathitalics
+ if mathitalics == false then
+ if trace_defining then
+ report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename)
+ end
+ hasitalics = false
+ autoitalicamount = false
+ end
+ else
+ local textitalics = properties.textitalics
+ if textitalics == false then
+ if trace_defining then
+ report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename)
+ end
+ hasitalics = false
+ autoitalicamount = false
+ end
+ end
+ --
+ -- end of context specific trickery
+ --
+ if trace_defining then
+ report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a",
+ name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta,
+ hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled")
+ end
+ --
+ constructors.beforecopyingcharacters(target,tfmdata)
+ --
+ local sharedkerns = { }
+ --
+ -- we can have a dumb mode (basemode without math etc) that skips most
+ --
+ for unicode, character in next, characters do
+ local chr, description, index
+ if changed then
+ local c = changed[unicode]
+ if c and c ~= unicode then
+ if c then
+ description = descriptions[c] or descriptions[unicode] or character
+ character = characters[c] or character
+ index = description.index or c
+ else
+ description = descriptions[unicode] or character
+ index = description.index or unicode
+ end
+ else
+ description = descriptions[unicode] or character
+ index = description.index or unicode
+ end
+ else
+ description = descriptions[unicode] or character
+ index = description.index or unicode
+ end
+ local width = description.width
+ local height = description.height
+ local depth = description.depth
+ local isunicode = description.unicode
+ if realdimensions then
+ -- this is mostly for checking issues
+ if not height or height == 0 then
+ local bb = description.boundingbox
+ local ht = bb[4]
+ if ht ~= 0 then
+ height = ht
+ end
+ if not depth or depth == 0 then
+ local dp = -bb[2]
+ if dp ~= 0 then
+ depth = dp
+ end
+ end
+ elseif not depth or depth == 0 then
+ local dp = -description.boundingbox[2]
+ if dp ~= 0 then
+ depth = dp
+ end
+ end
+ end
+ if width then width = hdelta*width else width = scaledwidth end
+ if height then height = vdelta*height else height = scaledheight end
+ -- if depth then depth = vdelta*depth else depth = scaleddepth end
+ if depth and depth ~= 0 then
+ depth = delta*depth
+ if isunicode then
+ chr = {
+ index = index,
+ height = height,
+ depth = depth,
+ width = width,
+ unicode = isunicode,
+ }
+ else
+ chr = {
+ index = index,
+ height = height,
+ depth = depth,
+ width = width,
+ }
+ end
+ else
+ if isunicode then
+ chr = {
+ index = index,
+ height = height,
+ width = width,
+ unicode = isunicode,
+ }
+ else
+ chr = {
+ index = index,
+ height = height,
+ width = width,
+ }
+ end
+ end
+ if addtounicode then
+ chr.tounicode = isunicode and tounicode(isunicode) or unknowncode
+ end
+ if hasquality then
+ -- we could move these calculations elsewhere (saves calculations)
+ local ve = character.expansion_factor
+ if ve then
+ chr.expansion_factor = ve*1000 -- expansionfactor, hm, can happen elsewhere
+ end
+ local vl = character.left_protruding
+ if vl then
+ chr.left_protruding = protrusionfactor*width*vl
+ end
+ local vr = character.right_protruding
+ if vr then
+ chr.right_protruding = protrusionfactor*width*vr
+ end
+ end
+ --
+ if hasmath then
+ --
+ -- todo, just operate on descriptions.math
+ local vn = character.next
+ if vn then
+ chr.next = vn
+ else
+ local vv = character.vert_variants
+ if vv then
+ local t = { }
+ for i=1,#vv do
+ local vvi = vv[i]
+ local s = vvi["start"] or 0
+ local e = vvi["end"] or 0
+ local a = vvi["advance"] or 0
+ t[i] = { -- zero check nicer for 5.3
+ ["start"] = s == 0 and 0 or s * vdelta,
+ ["end"] = e == 0 and 0 or e * vdelta,
+ ["advance"] = a == 0 and 0 or a * vdelta,
+ ["extender"] = vvi["extender"],
+ ["glyph"] = vvi["glyph"],
+ }
+ end
+ chr.vert_variants = t
+ else
+ local hv = character.horiz_variants
+ if hv then
+ local t = { }
+ for i=1,#hv do
+ local hvi = hv[i]
+ local s = hvi["start"] or 0
+ local e = hvi["end"] or 0
+ local a = hvi["advance"] or 0
+ t[i] = { -- zero check nicer for 5.3
+ ["start"] = s == 0 and 0 or s * hdelta,
+ ["end"] = e == 0 and 0 or e * hdelta,
+ ["advance"] = a == 0 and 0 or a * hdelta,
+ ["extender"] = hvi["extender"],
+ ["glyph"] = hvi["glyph"],
+ }
+ end
+ chr.horiz_variants = t
+ end
+ end
+ -- todo also check mathitalics (or that one can go away)
+ end
+ local vi = character.vert_italic
+ if vi and vi ~= 0 then
+ chr.vert_italic = vi*hdelta
+ end
+ local va = character.accent
+ if va then
+ chr.top_accent = vdelta*va
+ end
+ if stackmath then
+ local mk = character.mathkerns
+ if mk then
+ local tr = mk.topright
+ local tl = mk.topleft
+ local br = mk.bottomright
+ local bl = mk.bottomleft
+ chr.mathkern = { -- singular -> should be patched in luatex !
+ top_right = tr and mathkerns(tr,vdelta) or nil,
+ top_left = tl and mathkerns(tl,vdelta) or nil,
+ bottom_right = br and mathkerns(br,vdelta) or nil,
+ bottom_left = bl and mathkerns(bl,vdelta) or nil,
+ }
+ end
+ end
+ if hasitalics then
+ local vi = character.italic
+ if vi and vi ~= 0 then
+ chr.italic = vi*hdelta
+ end
+ end
+ elseif autoitalicamount then -- itlc feature
+ local vi = description.italic
+ if not vi then
+ local bb = description.boundingbox
+ if bb then
+ local vi = bb[3] - description.width + autoitalicamount
+ if vi > 0 then -- < 0 indicates no overshoot or a very small auto italic
+ chr.italic = vi*hdelta
+ end
+ else
+ -- report_defining("no boundingbox for character %C in font %a, fullname %a, filename %a",unicode,name,fullname,filename)
+ end
+ elseif vi ~= 0 then
+ chr.italic = vi*hdelta
+ end
+ elseif hasitalics then -- unlikely
+ local vi = character.italic
+ if vi and vi ~= 0 then
+ chr.italic = vi*hdelta
+ end
+ end
+ if haskerns then
+ local vk = character.kerns
+ if vk then
+ local s = sharedkerns[vk]
+ if not s then
+ s = { }
+ for k,v in next, vk do s[k] = v*hdelta end
+ sharedkerns[vk] = s
+ end
+ chr.kerns = s
+ end
+ end
+ if hasligatures then
+ local vl = character.ligatures
+ if vl then
+ if true then
+ chr.ligatures = vl -- shared
+ else
+ local tt = { }
+ for i, l in next, vl do
+ tt[i] = l
+ end
+ chr.ligatures = tt
+ end
+ end
+ end
+ if isvirtual then
+ local vc = character.commands
+ if vc then
+ -- we assume non scaled commands here
+ -- tricky .. we need to scale pseudo math glyphs too
+ -- which is why we deal with rules too
+ local ok = false
+ for i=1,#vc do
+ local key = vc[i][1]
+ if key == "right" or key == "down" or key == "rule" then
+ ok = true
+ break
+ end
+ end
+ if ok then
+ local tt = { }
+ for i=1,#vc do
+ local ivc = vc[i]
+ local key = ivc[1]
+ if key == "right" then
+ tt[i] = { key, ivc[2]*hdelta }
+ elseif key == "down" then
+ tt[i] = { key, ivc[2]*vdelta }
+ elseif key == "rule" then
+ tt[i] = { key, ivc[2]*vdelta, ivc[3]*hdelta }
+ else -- not comment
+ tt[i] = ivc -- shared since in cache and untouched
+ end
+ end
+ chr.commands = tt
+ else
+ chr.commands = vc
+ end
+ -- chr.index = nil
+ end
+ end
+ targetcharacters[unicode] = chr
+ end
+ --
+ properties.setitalics = hasitalics -- for postprocessing
+ --
+ constructors.aftercopyingcharacters(target,tfmdata)
+ --
+ constructors.trytosharefont(target,tfmdata)
+ --
+ -- catch inconsistencies
+ --
+ local vfonts = target.fonts
+ if isvirtual or target.type == "virtual" or properties.virtualized then
+ properties.virtualized = true
+ target.type = "virtual"
+ if not vfonts or #vfonts == 0 then
+ target.fonts = { { id = 0 } }
+ end
+ elseif vfonts then
+ properties.virtualized = true
+ target.type = "virtual"
+ if #vfonts == 0 then
+ target.fonts = { { id = 0 } }
+ end
+ end
+ --
+ return target
+end
+
+function constructors.finalize(tfmdata)
+ if tfmdata.properties and tfmdata.properties.finalized then
+ return
+ end
+ --
+ if not tfmdata.characters then
+ return nil
+ end
+ --
+ if not tfmdata.goodies then
+ tfmdata.goodies = { } -- context specific
+ end
+ --
+ local parameters = tfmdata.parameters
+ if not parameters then
+ return nil
+ end
+ --
+ if not parameters.expansion then
+ parameters.expansion = {
+ stretch = tfmdata.stretch or 0,
+ shrink = tfmdata.shrink or 0,
+ step = tfmdata.step or 0,
+ }
+ end
+ --
+ if not parameters.size then
+ parameters.size = tfmdata.size
+ end
+ --
+ if not parameters.mode then
+ parameters.mode = 0
+ end
+ --
+ if not parameters.width then
+ parameters.width = 0
+ end
+ --
+ if not parameters.slantfactor then
+ parameters.slantfactor = (tfmdata.slant or 0)/1000
+ end
+ --
+ if not parameters.extendfactor then
+ parameters.extendfactor = (tfmdata.extend or 1000)/1000
+ end
+ --
+ if not parameters.squeezefactor then
+ parameters.squeezefactor = (tfmdata.squeeze or 1000)/1000
+ end
+ --
+ local designsize = parameters.designsize
+ if designsize then
+ parameters.minsize = tfmdata.minsize or designsize
+ parameters.maxsize = tfmdata.maxsize or designsize
+ else
+ designsize = factors.pt * 10
+ parameters.designsize = designsize
+ parameters.minsize = designsize
+ parameters.maxsize = designsize
+ end
+ parameters.minsize = tfmdata.minsize or parameters.designsize
+ parameters.maxsize = tfmdata.maxsize or parameters.designsize
+ --
+ if not parameters.units then
+ parameters.units = tfmdata.units or tfmdata.units_per_em or 1000
+ end
+ --
+ if not tfmdata.descriptions then
+ local descriptions = { } -- yes or no
+ setmetatableindex(descriptions, function(t,k) local v = { } t[k] = v return v end)
+ tfmdata.descriptions = descriptions
+ end
+ --
+ local properties = tfmdata.properties
+ if not properties then
+ properties = { }
+ tfmdata.properties = properties
+ end
+ --
+ if not properties.virtualized then
+ properties.virtualized = tfmdata.type == "virtual"
+ end
+ --
+ properties.fontname = properties.fontname or tfmdata.fontname
+ properties.filename = properties.filename or tfmdata.filename
+ properties.fullname = properties.fullname or tfmdata.fullname
+ properties.name = properties.name or tfmdata.name
+ properties.psname = properties.psname or tfmdata.psname
+ --
+ properties.encodingbytes = tfmdata.encodingbytes or 1
+ properties.embedding = tfmdata.embedding or "subset"
+ properties.tounicode = tfmdata.tounicode or 1
+ properties.cidinfo = tfmdata.cidinfo or nil
+ properties.format = tfmdata.format or "type1"
+ properties.direction = tfmdata.direction or 0
+ properties.writingmode = tfmdata.writingmode or "horizontal"
+ properties.identity = tfmdata.identity or "horizontal"
+ properties.usedbitmap = tfmdata.usedbitmap
+ --
+ if not tfmdata.resources then
+ tfmdata.resources = { }
+ end
+ if not tfmdata.shared then
+ tfmdata.shared = { }
+ end
+ --
+ -- tfmdata.fonts
+ -- tfmdata.unscaled
+ --
+ if not properties.hasmath then
+ properties.hasmath = not tfmdata.nomath
+ end
+ --
+ tfmdata.MathConstants = nil
+ tfmdata.postprocessors = nil
+ --
+ tfmdata.fontname = nil
+ tfmdata.filename = nil
+ tfmdata.fullname = nil
+ tfmdata.name = nil -- most tricky part
+ tfmdata.psname = nil
+ --
+ tfmdata.encodingbytes = nil
+ tfmdata.embedding = nil
+ tfmdata.tounicode = nil
+ tfmdata.cidinfo = nil
+ tfmdata.format = nil
+ tfmdata.direction = nil
+ tfmdata.type = nil
+ tfmdata.nomath = nil
+ tfmdata.designsize = nil
+ --
+ tfmdata.size = nil
+ tfmdata.stretch = nil
+ tfmdata.shrink = nil
+ tfmdata.step = nil
+ tfmdata.slant = nil
+ tfmdata.extend = nil
+ tfmdata.squeeze = nil
+ tfmdata.mode = nil
+ tfmdata.width = nil
+ tfmdata.units = nil
+ tfmdata.units_per_em = nil
+ --
+ tfmdata.cache = nil
+ --
+ properties.finalized = true
+ --
+ return tfmdata
+end
+
+--[[ldx--
+<p>A unique hash value is generated by:</p>
+--ldx]]--
+
+local hashmethods = { }
+constructors.hashmethods = hashmethods
+
+function constructors.hashfeatures(specification) -- will be overloaded
+ local features = specification.features
+ if features then
+ local t, n = { }, 0
+ for category, list in sortedhash(features) do
+ if next(list) then
+ local hasher = hashmethods[category]
+ if hasher then
+ local hash = hasher(list)
+ if hash then
+ n = n + 1
+ t[n] = category .. ":" .. hash
+ end
+ end
+ end
+ end
+ if n > 0 then
+ return concat(t," & ")
+ end
+ end
+ return "unknown"
+end
+
+hashmethods.normal = function(list)
+ local s = { }
+ local n = 0
+ for k, v in next, list do
+ if not k then
+ -- no need to add to hash
+ elseif k == "number" or k == "features" then
+ -- no need to add to hash (maybe we need a skip list)
+ else
+ n = n + 1
+ if type(v) == "table" then
+ -- table.sequenced
+ local t = { }
+ local m = 0
+ for k, v in next, v do
+ m = m + 1
+ t[m] = k .. '=' .. tostring(v)
+ end
+ s[n] = k .. '={' .. concat(t,",") .. "}"
+ else
+ s[n] = k .. '=' .. tostring(v)
+ end
+ end
+ end
+ if n > 0 then
+ sort(s)
+ return concat(s,"+")
+ end
+end
+
+--[[ldx--
+<p>In principle we can share tfm tables when we are in need for a font, but then
+we need to define a font switch as an id/attr switch which is no fun, so in that
+case users can best use dynamic features ... so, we will not use that speedup. Okay,
+when we get rid of base mode we can optimize even further by sharing, but then we
+loose our testcases for <l n='luatex'/>.</p>
+--ldx]]--
+
+function constructors.hashinstance(specification,force)
+ local hash = specification.hash
+ local size = specification.size
+ local fallbacks = specification.fallbacks
+ if force or not hash then
+ hash = constructors.hashfeatures(specification)
+ specification.hash = hash
+ end
+ if size < 1000 and designsizes[hash] then
+ size = round(constructors.scaled(size,designsizes[hash]))
+ else
+ size = round(size)
+ end
+ specification.size = size
+ if fallbacks then
+ return hash .. ' @ ' .. size .. ' @ ' .. fallbacks
+ else
+ return hash .. ' @ ' .. size
+ end
+end
+
+function constructors.setname(tfmdata,specification) -- todo: get specification from tfmdata
+ if constructors.namemode == "specification" then
+ -- not to be used in context !
+ local specname = specification.specification
+ if specname then
+ tfmdata.properties.name = specname
+ if trace_defining then
+ report_otf("overloaded fontname %a",specname)
+ end
+ end
+ end
+end
+
+function constructors.checkedfilename(data)
+ local foundfilename = data.foundfilename
+ if not foundfilename then
+ local askedfilename = data.filename or ""
+ if askedfilename ~= "" then
+ askedfilename = resolvers.resolve(askedfilename) -- no shortcut
+ foundfilename = resolvers.findbinfile(askedfilename,"") or ""
+ if foundfilename == "" then
+ report_defining("source file %a is not found",askedfilename)
+ foundfilename = resolvers.findbinfile(file.basename(askedfilename),"") or ""
+ if foundfilename ~= "" then
+ report_defining("using source file %a due to cache mismatch",foundfilename)
+ end
+ end
+ end
+ data.foundfilename = foundfilename
+ end
+ return foundfilename
+end
+
+local formats = allocate()
+fonts.formats = formats
+
+setmetatableindex(formats, function(t,k)
+ local l = lower(k)
+ if rawget(t,k) then
+ t[k] = l
+ return l
+ end
+ return rawget(t,file.suffix(l))
+end)
+
+do
+
+ local function setindeed(mode,source,target,group,name,position)
+ local action = source[mode]
+ if not action then
+ return
+ end
+ local t = target[mode]
+ if not t then
+ report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode)
+ os.exit()
+ elseif position then
+ -- todo: remove existing
+ insert(t, position, { name = name, action = action })
+ else
+ for i=1,#t do
+ local ti = t[i]
+ if ti.name == name then
+ ti.action = action
+ return
+ end
+ end
+ insert(t, { name = name, action = action })
+ end
+ end
+
+ local function set(group,name,target,source)
+ target = target[group]
+ if not target then
+ report_defining("fatal target error in setting feature %a, group %a",name,group)
+ os.exit()
+ end
+ local source = source[group]
+ if not source then
+ report_defining("fatal source error in setting feature %a, group %a",name,group)
+ os.exit()
+ end
+ local position = source.position
+ setindeed("node",source,target,group,name,position)
+ setindeed("base",source,target,group,name,position)
+ setindeed("plug",source,target,group,name,position)
+ end
+
+ local function register(where,specification)
+ local name = specification.name
+ if name and name ~= "" then
+ local default = specification.default
+ local description = specification.description
+ local initializers = specification.initializers
+ local processors = specification.processors
+ local manipulators = specification.manipulators
+ local modechecker = specification.modechecker
+ if default then
+ where.defaults[name] = default
+ end
+ if description and description ~= "" then
+ where.descriptions[name] = description
+ end
+ if initializers then
+ set('initializers',name,where,specification)
+ end
+ if processors then
+ set('processors', name,where,specification)
+ end
+ if manipulators then
+ set('manipulators',name,where,specification)
+ end
+ if modechecker then
+ where.modechecker = modechecker
+ end
+ end
+ end
+
+ constructors.registerfeature = register
+
+ function constructors.getfeatureaction(what,where,mode,name)
+ what = handlers[what].features
+ if what then
+ where = what[where]
+ if where then
+ mode = where[mode]
+ if mode then
+ for i=1,#mode do
+ local m = mode[i]
+ if m.name == name then
+ return m.action
+ end
+ end
+ end
+ end
+ end
+ end
+
+ local newfeatures = { }
+ constructors.newfeatures = newfeatures -- downward compatible
+ constructors.features = newfeatures
+
+ local function setnewfeatures(what)
+ local handler = handlers[what]
+ local features = handler.features
+ if not features then
+ local tables = handler.tables -- can be preloaded
+ local statistics = handler.statistics -- can be preloaded
+ features = allocate {
+ defaults = { },
+ descriptions = tables and tables.features or { },
+ used = statistics and statistics.usedfeatures or { },
+ initializers = { base = { }, node = { }, plug = { } },
+ processors = { base = { }, node = { }, plug = { } },
+ manipulators = { base = { }, node = { }, plug = { } },
+ }
+ features.register = function(specification) return register(features,specification) end
+ handler.features = features -- will also become hidden
+ end
+ return features
+ end
+
+ setmetatable(newfeatures, {
+ __call = function(t,k) local v = t[k] return v end,
+ __index = function(t,k) local v = setnewfeatures(k) t[k] = v return v end,
+ })
+
+end
+
+do
+
+ local newhandler = { }
+ constructors.handlers = newhandler -- downward compatible
+ constructors.newhandler = newhandler
+
+ local function setnewhandler(what) -- could be a metatable newindex
+ local handler = handlers[what]
+ if not handler then
+ handler = { }
+ handlers[what] = handler
+ end
+ return handler
+ end
+
+ setmetatable(newhandler, {
+ __call = function(t,k) local v = t[k] return v end,
+ __index = function(t,k) local v = setnewhandler(k) t[k] = v return v end,
+ })
+
+end
+
+do
+ -- a pitty that we need to be generic as we have nicer mechanisms for this ...
+
+ local newenhancer = { }
+ constructors.enhancers = newenhancer
+ constructors.newenhancer = newenhancer
+
+ local function setnewenhancer(format)
+
+ local handler = handlers[format]
+ local enhancers = handler.enhancers
+
+ if not enhancers then
+
+ local actions = allocate() -- no need to allocate thee
+ local before = allocate()
+ local after = allocate()
+ local order = allocate()
+ local known = { }
+ local nofsteps = 0
+ local patches = { before = before, after = after }
+
+ local trace = false
+ local report = logs.reporter("fonts",format .. " enhancing")
+
+ trackers.register(format .. ".loading", function(v) trace = v end)
+
+ local function enhance(name,data,filename,raw)
+ local enhancer = actions[name]
+ if enhancer then
+ if trace then
+ report("apply enhancement %a to file %a",name,filename)
+ ioflush()
+ end
+ enhancer(data,filename,raw)
+ else
+ -- no message as we can have private ones
+ end
+ end
+
+ local function apply(data,filename,raw)
+ local basename = file.basename(lower(filename))
+ if trace then
+ report("%s enhancing file %a","start",filename)
+ end
+ ioflush() -- we want instant messages
+ for e=1,nofsteps do
+ local enhancer = order[e]
+ local b = before[enhancer]
+ if b then
+ for pattern, action in next, b do
+ if find(basename,pattern) then
+ action(data,filename,raw)
+ end
+ end
+ end
+ enhance(enhancer,data,filename,raw) -- we have one installed: check extra features
+ local a = after[enhancer]
+ if a then
+ for pattern, action in next, a do
+ if find(basename,pattern) then
+ action(data,filename,raw)
+ end
+ end
+ end
+ ioflush() -- we want instant messages
+ end
+ if trace then
+ report("%s enhancing file %a","stop",filename)
+ end
+ ioflush() -- we want instant messages
+ end
+
+ local function register(what,action)
+ if action then
+ if actions[what] then
+ -- overloading, e.g."check extra features"
+ else
+ nofsteps = nofsteps + 1
+ order[nofsteps] = what
+ known[what] = nofsteps
+ end
+ actions[what] = action
+ else
+ report("bad enhancer %a",what)
+ end
+ end
+
+ -- We used to have a lot of enhancers but no longer with the new font loader. The order of enhancers
+ -- is the order of definition. The before/after patches are there for old times sake and happen
+ -- before or after a (named) enhancer. An example of a set enhancer is "check extra features" so one
+ -- one set patches before or after that is applied. Unknown enhancers are auto-registered. It's a bit
+ -- messy but we keep it for compatibility reasons.
+ --
+ -- fonts.handlers.otf.enhancers.patches.register("before","some patches","somefont",function(data,filename)
+ -- print("!!!!!!!") -- before | after
+ -- end)
+ --
+ -- fonts.handlers.otf.enhancers.register("more patches",function(data,filename)
+ -- print("???????") -- enhance
+ -- end)
+
+ local function patch(what,where,pattern,action)
+ local pw = patches[what]
+ if pw then
+ local ww = pw[where]
+ if ww then
+ ww[pattern] = action
+ else
+ pw[where] = { [pattern] = action }
+ if not known[where] then
+ nofsteps = nofsteps + 1
+ order[nofsteps] = where
+ known[where] = nofsteps
+ end
+ end
+ end
+ end
+
+ enhancers = {
+ register = register,
+ apply = apply,
+ patch = patch,
+ report = report,
+ patches = {
+ register = patch,
+ report = report,
+ }, -- for old times sake
+ }
+
+ handler.enhancers = enhancers
+ end
+ return enhancers
+ end
+
+ setmetatable(newenhancer, {
+ __call = function(t,k) local v = t[k] return v end,
+ __index = function(t,k) local v = setnewenhancer(k) t[k] = v return v end,
+ })
+
+end
+
+--[[ldx--
+<p>We need to check for default features. For this we provide
+a helper function.</p>
+--ldx]]--
+
+function constructors.checkedfeatures(what,features)
+ local defaults = handlers[what].features.defaults
+ if features and next(features) then
+ features = fastcopy(features) -- can be inherited (mt) but then no loops possible
+ for key, value in next, defaults do
+ if features[key] == nil then
+ features[key] = value
+ end
+ end
+ return features
+ else
+ return fastcopy(defaults) -- we can change features in place
+ end
+end
+
+-- before scaling
+
+function constructors.initializefeatures(what,tfmdata,features,trace,report)
+ if features and next(features) then
+ local properties = tfmdata.properties or { } -- brrr
+ local whathandler = handlers[what]
+ local whatfeatures = whathandler.features
+ local whatmodechecker = whatfeatures.modechecker
+ -- properties.mode can be enforces (for instance in font-otd)
+ local mode = properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base"
+ properties.mode = mode -- also status
+ features.mode = mode -- both properties.mode or features.mode can be changed
+ --
+ local done = { }
+ while true do
+ local redo = false
+ local initializers = whatfeatures.initializers[mode]
+ if initializers then
+ for i=1,#initializers do
+ local step = initializers[i]
+ local feature = step.name
+-- we could intercept mode here .. needs a rewrite of this whole loop then but it's cleaner that way
+ local value = features[feature]
+ if not value then
+ -- disabled
+ elseif done[feature] then
+ -- already done
+ else
+ local action = step.action
+ if trace then
+ report("initializing feature %a to %a for mode %a for font %a",feature,
+ value,mode,tfmdata.properties.fullname)
+ end
+ action(tfmdata,value,features) -- can set mode (e.g. goodies) so it can trigger a restart
+ if mode ~= properties.mode or mode ~= features.mode then
+ if whatmodechecker then
+ properties.mode = whatmodechecker(tfmdata,features,properties.mode) -- force checking
+ features.mode = properties.mode
+ end
+ if mode ~= properties.mode then
+ mode = properties.mode
+ redo = true
+ end
+ end
+ done[feature] = true
+ end
+ if redo then
+ break
+ end
+ end
+ if not redo then
+ break
+ end
+ else
+ break
+ end
+ end
+ properties.mode = mode -- to be sure
+ return true
+ else
+ return false
+ end
+end
+
+-- while typesetting
+
+function constructors.collectprocessors(what,tfmdata,features,trace,report)
+ local processes = { }
+ local nofprocesses = 0
+ if features and next(features) then
+ local properties = tfmdata.properties
+ local whathandler = handlers[what]
+ local whatfeatures = whathandler.features
+ local whatprocessors = whatfeatures.processors
+ local mode = properties.mode
+ local processors = whatprocessors[mode]
+ if processors then
+ for i=1,#processors do
+ local step = processors[i]
+ local feature = step.name
+ if features[feature] then
+ local action = step.action
+ if trace then
+ report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname)
+ end
+ if action then
+ nofprocesses = nofprocesses + 1
+ processes[nofprocesses] = action
+ end
+ end
+ end
+ elseif trace then
+ report("no feature processors for mode %a for font %a",mode,properties.fullname)
+ end
+ end
+ return processes
+end
+
+-- after scaling
+
+function constructors.applymanipulators(what,tfmdata,features,trace,report)
+ if features and next(features) then
+ local properties = tfmdata.properties
+ local whathandler = handlers[what]
+ local whatfeatures = whathandler.features
+ local whatmanipulators = whatfeatures.manipulators
+ local mode = properties.mode
+ local manipulators = whatmanipulators[mode]
+ if manipulators then
+ for i=1,#manipulators do
+ local step = manipulators[i]
+ local feature = step.name
+ local value = features[feature]
+ if value then
+ local action = step.action
+ if trace then
+ report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname)
+ end
+ if action then
+ action(tfmdata,feature,value)
+ end
+ end
+ end
+ end
+ end
+end
+
+function constructors.addcoreunicodes(unicodes) -- maybe make this a metatable if used at all
+ if not unicodes then
+ unicodes = { }
+ end
+ unicodes.space = 0x0020
+ unicodes.hyphen = 0x002D
+ unicodes.zwj = 0x200D
+ unicodes.zwnj = 0x200C
+ return unicodes
+end
+
+-- -- keep for a while: old tounicode code
+--
+-- if changed then
+-- -- basemode hack (we try to catch missing tounicodes, e.g. needed for ssty in math cambria)
+-- local c = changed[unicode]
+-- if c then
+-- -- local ligatures = character.ligatures -- the original ligatures (as we cannot rely on remapping)
+-- description = descriptions[c] or descriptions[unicode] or character
+-- character = characters[c] or character
+-- index = description.index or c
+-- if tounicode then
+-- touni = tounicode[index] -- nb: index!
+-- if not touni then -- goodie
+-- local d = descriptions[unicode] or characters[unicode]
+-- local i = d.index or unicode
+-- touni = tounicode[i] -- nb: index!
+-- end
+-- end
+-- -- if ligatures and not character.ligatures then
+-- -- character.ligatures = ligatures -- the original targets (for now at least.. see libertine smallcaps)
+-- -- end
+-- else
+-- description = descriptions[unicode] or character
+-- index = description.index or unicode
+-- if tounicode then
+-- touni = tounicode[index] -- nb: index!
+-- end
+-- end
+-- else
+-- description = descriptions[unicode] or character
+-- index = description.index or unicode
+-- if tounicode then
+-- touni = tounicode[index] -- nb: index!
+-- end
+-- end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-def.lua b/macros/luatex/generic/luaotfload/fontloader-font-def.lua
new file mode 100644
index 0000000000..f3d0f81871
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-def.lua
@@ -0,0 +1,536 @@
+if not modules then modules = { } end modules ['font-def'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- We can overload some of the definers.functions so we don't local them.
+
+local lower, gsub = string.lower, string.gsub
+local tostring, next = tostring, next
+local lpegmatch = lpeg.match
+local suffixonly, removesuffix, basename = file.suffix, file.removesuffix, file.basename
+local formatters = string.formatters
+local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys
+
+local allocate = utilities.storage.allocate
+
+local trace_defining = false trackers .register("fonts.defining", function(v) trace_defining = v end)
+local directive_embedall = false directives.register("fonts.embedall", function(v) directive_embedall = v end)
+
+trackers.register("fonts.loading", "fonts.defining", "otf.loading", "afm.loading", "tfm.loading")
+
+local report_defining = logs.reporter("fonts","defining")
+
+--[[ldx--
+<p>Here we deal with defining fonts. We do so by intercepting the
+default loader that only handles <l n='tfm'/>.</p>
+--ldx]]--
+
+local fonts = fonts
+local fontdata = fonts.hashes.identifiers
+local readers = fonts.readers
+local definers = fonts.definers
+local specifiers = fonts.specifiers
+local constructors = fonts.constructors
+local fontgoodies = fonts.goodies
+
+readers.sequence = allocate { 'otf', 'ttf', 'afm', 'tfm', 'lua' } -- dfont ttc
+
+local variants = allocate()
+specifiers.variants = variants
+
+definers.methods = definers.methods or { }
+
+local internalized = allocate() -- internal tex numbers (private)
+local lastdefined = nil -- we don't want this one to end up in s-tra-02
+
+local loadedfonts = constructors.loadedfonts
+local designsizes = constructors.designsizes
+
+-- not in generic (some day I'll make two defs, one for context, one for generic)
+
+local resolvefile = fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end
+
+--[[ldx--
+<p>We hardly gain anything when we cache the final (pre scaled)
+<l n='tfm'/> table. But it can be handy for debugging, so we no
+longer carry this code along. Also, we now have quite some reference
+to other tables so we would end up with lots of catches.</p>
+--ldx]]--
+
+--[[ldx--
+<p>We can prefix a font specification by <type>name:</type> or
+<type>file:</type>. The first case will result in a lookup in the
+synonym table.</p>
+
+<typing>
+[ name: | file: ] identifier [ separator [ specification ] ]
+</typing>
+
+<p>The following function split the font specification into components
+and prepares a table that will move along as we proceed.</p>
+--ldx]]--
+
+-- beware, we discard additional specs
+--
+-- method:name method:name(sub) method:name(sub)*spec method:name*spec
+-- name name(sub) name(sub)*spec name*spec
+-- name@spec*oeps
+
+local function makespecification(specification,lookup,name,sub,method,detail,size)
+ size = size or 655360
+ if not lookup or lookup == "" then
+ lookup = definers.defaultlookup
+ end
+ if trace_defining then
+ report_defining("specification %a, lookup %a, name %a, sub %a, method %a, detail %a",
+ specification, lookup, name, sub, method, detail)
+ end
+ local t = {
+ lookup = lookup, -- forced type
+ specification = specification, -- full specification
+ size = size, -- size in scaled points or -1000*n
+ name = name, -- font or filename
+ sub = sub, -- subfont (eg in ttc)
+ method = method, -- specification method
+ detail = detail, -- specification
+ resolved = "", -- resolved font name
+ forced = "", -- forced loader
+ features = { }, -- preprocessed features
+ }
+ return t
+end
+
+definers.makespecification = makespecification
+
+if context then
+
+ local splitter, splitspecifiers = nil, "" -- not so nice
+
+ local P, C, S, Cc, Cs = lpeg.P, lpeg.C, lpeg.S, lpeg.Cc, lpeg.Cs
+
+ local left = P("(")
+ local right = P(")")
+ local colon = P(":")
+ local space = P(" ")
+ local lbrace = P("{")
+ local rbrace = P("}")
+
+ definers.defaultlookup = "file"
+
+ local prefixpattern = P(false)
+
+ local function addspecifier(symbol)
+ splitspecifiers = splitspecifiers .. symbol
+ local method = S(splitspecifiers)
+ local lookup = C(prefixpattern) * colon
+ local sub = left * C(P(1-left-right-method)^1) * right
+ local specification = C(method) * C(P(1)^1)
+ local name = Cs((lbrace/"") * (1-rbrace)^1 * (rbrace/"") + (1-sub-specification)^1)
+ splitter = P((lookup + Cc("")) * name * (sub + Cc("")) * (specification + Cc("")))
+ end
+
+ local function addlookup(str)
+ prefixpattern = prefixpattern + P(str)
+ end
+
+ definers.addlookup = addlookup
+
+ addlookup("file")
+ addlookup("name")
+ addlookup("spec")
+
+ local function getspecification(str)
+ return lpegmatch(splitter,str or "") -- weird catch
+ end
+
+ definers.getspecification = getspecification
+
+ function definers.registersplit(symbol,action,verbosename)
+ addspecifier(symbol)
+ variants[symbol] = action
+ if verbosename then
+ variants[verbosename] = action
+ end
+ end
+
+ function definers.analyze(specification, size)
+ -- can be optimized with locals
+ local lookup, name, sub, method, detail = getspecification(specification or "")
+ return makespecification(specification, lookup, name, sub, method, detail, size)
+ end
+
+end
+
+--[[ldx--
+<p>We can resolve the filename using the next function:</p>
+--ldx]]--
+
+definers.resolvers = definers.resolvers or { }
+local resolvers = definers.resolvers
+
+-- todo: reporter
+
+function resolvers.file(specification)
+ local name = resolvefile(specification.name) -- catch for renames
+ local suffix = lower(suffixonly(name))
+ if fonts.formats[suffix] then
+ specification.forced = suffix
+ specification.forcedname = name
+ specification.name = removesuffix(name)
+ else
+ specification.name = name -- can be resolved
+ end
+end
+
+function resolvers.name(specification)
+ local resolve = fonts.names.resolve
+ if resolve then
+ local resolved, sub, subindex, instance = resolve(specification.name,specification.sub,specification) -- we pass specification for overloaded versions
+ if resolved then
+ specification.resolved = resolved
+ specification.sub = sub
+ specification.subindex = subindex
+ -- new, needed for experiments
+ if instance then
+ specification.instance = instance
+ local features = specification.features
+ if not features then
+ features = { }
+ specification.features = features
+ end
+ local normal = features.normal
+ if not normal then
+ normal = { }
+ features.normal = normal
+ end
+ normal.instance = instance
+ -- if not callbacks.supported.glyph_stream_provider then
+ -- normal.variableshapes = true -- for the moment
+ -- end
+ end
+ --
+ local suffix = lower(suffixonly(resolved))
+ if fonts.formats[suffix] then
+ specification.forced = suffix
+ specification.forcedname = resolved
+ specification.name = removesuffix(resolved)
+ else
+ specification.name = resolved
+ end
+ end
+ else
+ resolvers.file(specification)
+ end
+end
+
+function resolvers.spec(specification)
+ local resolvespec = fonts.names.resolvespec
+ if resolvespec then
+ local resolved, sub, subindex = resolvespec(specification.name,specification.sub,specification) -- we pass specification for overloaded versions
+ if resolved then
+ specification.resolved = resolved
+ specification.sub = sub
+ specification.subindex = subindex
+ specification.forced = lower(suffixonly(resolved))
+ specification.forcedname = resolved
+ specification.name = removesuffix(resolved)
+ end
+ else
+ resolvers.name(specification)
+ end
+end
+
+function definers.resolve(specification)
+ if not specification.resolved or specification.resolved == "" then -- resolved itself not per se in mapping hash
+ local r = resolvers[specification.lookup]
+ if r then
+ r(specification)
+ end
+ end
+ if specification.forced == "" then
+ specification.forced = nil
+ specification.forcedname = nil
+ end
+ specification.hash = lower(specification.name .. ' @ ' .. constructors.hashfeatures(specification))
+ if specification.sub and specification.sub ~= "" then
+ specification.hash = specification.sub .. ' @ ' .. specification.hash
+ end
+ return specification
+end
+
+--[[ldx--
+<p>The main read function either uses a forced reader (as determined by
+a lookup) or tries to resolve the name using the list of readers.</p>
+
+<p>We need to cache when possible. We do cache raw tfm data (from <l
+n='tfm'/>, <l n='afm'/> or <l n='otf'/>). After that we can cache based
+on specificstion (name) and size, that is, <l n='tex'/> only needs a number
+for an already loaded fonts. However, it may make sense to cache fonts
+before they're scaled as well (store <l n='tfm'/>'s with applied methods
+and features). However, there may be a relation between the size and
+features (esp in virtual fonts) so let's not do that now.</p>
+
+<p>Watch out, here we do load a font, but we don't prepare the
+specification yet.</p>
+--ldx]]--
+
+-- very experimental:
+
+function definers.applypostprocessors(tfmdata)
+ local postprocessors = tfmdata.postprocessors
+ if postprocessors then
+ local properties = tfmdata.properties
+ for i=1,#postprocessors do
+ local extrahash = postprocessors[i](tfmdata) -- after scaling etc
+ if type(extrahash) == "string" and extrahash ~= "" then
+ -- e.g. a reencoding needs this
+ extrahash = gsub(lower(extrahash),"[^a-z]","-")
+ properties.fullname = formatters["%s-%s"](properties.fullname,extrahash)
+ end
+ end
+ end
+ return tfmdata
+end
+
+-- function definers.applypostprocessors(tfmdata)
+-- return tfmdata
+-- end
+
+local function checkembedding(tfmdata)
+ local properties = tfmdata.properties
+ local embedding
+ if directive_embedall then
+ embedding = "full"
+ elseif properties and properties.filename and constructors.dontembed[properties.filename] then
+ embedding = "no"
+ else
+ embedding = "subset"
+ end
+ if properties then
+ properties.embedding = embedding
+ else
+ tfmdata.properties = { embedding = embedding }
+ end
+ tfmdata.embedding = embedding
+end
+
+local function checkfeatures(tfmdata)
+ local resources = tfmdata.resources
+ local shared = tfmdata.shared
+ if resources and shared then
+ local features = resources.features
+ local usedfeatures = shared.features
+ if features and usedfeatures then
+ local usedlanguage = usedfeatures.language or "dflt"
+ local usedscript = usedfeatures.script or "dflt"
+ local function check(what)
+ if what then
+ local foundlanguages = { }
+ for feature, scripts in next, what do
+ if usedscript == "auto" or scripts["*"] then
+ -- ok
+ elseif not scripts[usedscript] then
+ -- report_defining("font %!font:name!, feature %a, no script %a",
+ -- tfmdata,feature,usedscript)
+ else
+ for script, languages in next, scripts do
+ if languages["*"] then
+ -- ok
+ elseif context and not languages[usedlanguage] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,usedlanguage)
+ end
+ end
+ end
+ for script, languages in next, scripts do
+ for language in next, languages do
+ foundlanguages[language] = true
+ end
+ end
+ end
+ if false then
+ foundlanguages["*"] = nil
+ foundlanguages = sortedkeys(foundlanguages)
+ for feature, scripts in sortedhash(what) do
+ for script, languages in next, scripts do
+ if not languages["*"] then
+ for i=1,#foundlanguages do
+ local language = foundlanguages[i]
+ if context and not languages[language] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,language)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ check(features.gsub)
+ check(features.gpos)
+ end
+ end
+end
+
+function definers.loadfont(specification)
+ local hash = constructors.hashinstance(specification)
+ -- todo: also hash by instance / factors
+ local tfmdata = loadedfonts[hash] -- hashes by size !
+ if not tfmdata then
+ -- normally context will not end up here often (if so there is an issue somewhere)
+ local forced = specification.forced or ""
+ if forced ~= "" then
+ local reader = readers[lower(forced)] -- normally forced is already lowered
+ tfmdata = reader and reader(specification)
+ if not tfmdata then
+ report_defining("forced type %a of %a not found",forced,specification.name)
+ end
+ else
+ local sequence = readers.sequence -- can be overloaded so only a shortcut here
+ for s=1,#sequence do
+ local reader = sequence[s]
+ if readers[reader] then -- we skip not loaded readers
+ if trace_defining then
+ report_defining("trying (reader sequence driven) type %a for %a with file %a",reader,specification.name,specification.filename)
+ end
+ tfmdata = readers[reader](specification)
+ if tfmdata then
+ break
+ else
+ specification.filename = nil
+ end
+ end
+ end
+ end
+ if tfmdata then
+ tfmdata = definers.applypostprocessors(tfmdata)
+ checkembedding(tfmdata) -- todo: general postprocessor
+ loadedfonts[hash] = tfmdata
+ designsizes[specification.hash] = tfmdata.parameters.designsize
+ checkfeatures(tfmdata)
+ end
+ end
+ if not tfmdata then
+ report_defining("font with asked name %a is not found using lookup %a",specification.name,specification.lookup)
+ end
+ return tfmdata
+end
+
+function constructors.readanddefine(name,size) -- no id -- maybe a dummy first
+ local specification = definers.analyze(name,size)
+ local method = specification.method
+ if method and variants[method] then
+ specification = variants[method](specification)
+ end
+ specification = definers.resolve(specification)
+ local hash = constructors.hashinstance(specification)
+ local id = definers.registered(hash)
+ if not id then
+ local tfmdata = definers.loadfont(specification)
+ if tfmdata then
+ tfmdata.properties.hash = hash
+ id = font.define(tfmdata)
+ definers.register(tfmdata,id)
+ else
+ id = 0 -- signal
+ end
+ end
+ return fontdata[id], id
+end
+
+--[[ldx--
+<p>So far the specifiers. Now comes the real definer. Here we cache
+based on id's. Here we also intercept the virtual font handler. Since
+it evolved stepwise I may rewrite this bit (combine code).</p>
+
+In the previously defined reader (the one resulting in a <l n='tfm'/>
+table) we cached the (scaled) instances. Here we cache them again, but
+this time based on id. We could combine this in one cache but this does
+not gain much. By the way, passing id's back to in the callback was
+introduced later in the development.</p>
+--ldx]]--
+
+function definers.current() -- or maybe current
+ return lastdefined
+end
+
+function definers.registered(hash)
+ local id = internalized[hash]
+ return id, id and fontdata[id]
+end
+
+function definers.register(tfmdata,id)
+ if tfmdata and id then
+ local hash = tfmdata.properties.hash
+ if not hash then
+ report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?")
+ elseif not internalized[hash] then
+ internalized[hash] = id
+ if trace_defining then
+ report_defining("registering font, id %s, hash %a",id,hash)
+ end
+ fontdata[id] = tfmdata
+ end
+ end
+end
+
+function definers.read(specification,size,id) -- id can be optional, name can already be table
+ statistics.starttiming(fonts)
+ if type(specification) == "string" then
+ specification = definers.analyze(specification,size)
+ end
+ local method = specification.method
+ if method and variants[method] then
+ specification = variants[method](specification)
+ end
+ specification = definers.resolve(specification)
+ local hash = constructors.hashinstance(specification)
+ local tfmdata = definers.registered(hash) -- id
+ if tfmdata then
+ if trace_defining then
+ report_defining("already hashed: %s",hash)
+ end
+ else
+ tfmdata = definers.loadfont(specification) -- can be overloaded
+ if tfmdata then
+ if trace_defining then
+ report_defining("loaded and hashed: %s",hash)
+ end
+ tfmdata.properties.hash = hash
+ if id then
+ definers.register(tfmdata,id)
+ end
+ else
+ if trace_defining then
+ report_defining("not loaded and hashed: %s",hash)
+ end
+ end
+ end
+ lastdefined = tfmdata or id -- todo ! ! ! ! !
+ if not tfmdata then -- or id?
+ report_defining( "unknown font %a, loading aborted",specification.name)
+ elseif trace_defining and type(tfmdata) == "table" then
+ local properties = tfmdata.properties or { }
+ local parameters = tfmdata.parameters or { }
+ report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a",
+ properties.format or "unknown", id or "-", properties.name, parameters.size, properties.encodingbytes,
+ properties.encodingname, properties.fullname, basename(properties.filename))
+ end
+ statistics.stoptiming(fonts)
+ return tfmdata
+end
+
+function font.getfont(id)
+ return fontdata[id] -- otherwise issues
+end
+
+--[[ldx--
+<p>We overload the <l n='tfm'/> reader.</p>
+--ldx]]--
+
+callbacks.register('define_font', definers.read, "definition of fonts (tfmdata preparation)")
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
new file mode 100644
index 0000000000..79749741c3
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
@@ -0,0 +1,3902 @@
+if not modules then modules = { } end modules ['font-dsp'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- many 0,0 entry/exit
+
+-- This loader went through a few iterations. First I made a ff compatible one so
+-- that we could do some basic checking. Also some verbosity was added (named
+-- glyphs). Eventually all that was dropped for a context friendly format, simply
+-- because keeping the different table models in sync too to much time. I have the
+-- old file somewhere. A positive side effect is that we get an (upto) much smaller
+-- smaller tma/tmc file. In the end the loader will be not much slower than the
+-- c based ff one.
+
+-- Being binary encoded, an opentype is rather compact. When expanded into a Lua table
+-- quite some memory can be used. This is very noticeable in the ff loader, which for
+-- a good reason uses a verbose format. However, when we use that data we create a couple
+-- of hashes. In the Lua loader we create these hashes directly, which save quite some
+-- memory.
+--
+-- We convert a font file only once and then cache it. Before creating the cached instance
+-- packing takes place: common tables get shared. After (re)loading and unpacking we then
+-- get a rather efficient internal representation of the font. In the new loader there is a
+-- pitfall. Because we use some common coverage magic we put a bit more information in
+-- the mark and cursive coverage tables than strickly needed: a reference to the coverage
+-- itself. This permits a fast lookup of the second glyph involved. In the marks we
+-- expand the class indicator to a class hash, in the cursive we use a placeholder that gets
+-- a self reference. This means that we cannot pack these subtables unless we add a unique
+-- id per entry (the same one per coverage) and that makes the tables larger. Because only a
+-- few fonts benefit from this, I decided to not do this. Experiments demonstrated that it
+-- only gives a few percent gain (on for instance husayni we can go from 845K to 828K
+-- bytecode). Better stay conceptually clean than messy compact.
+
+-- When we can reduce all basic lookups to one step we might safe a bit in the processing
+-- so then only chains are multiple.
+
+-- I used to flatten kerns here but that has been moved elsewhere because it polutes the code
+-- here and can be done fast afterwards. One can even wonder if it makes sense to do it as we
+-- pack anyway. In a similar fashion the unique placeholders in anchors in marks have been
+-- removed because packing doesn't save much there anyway.
+
+-- Although we have a bit more efficient tables in the cached files, the internals are still
+-- pretty similar. And although we have a slightly more direct coverage access the processing
+-- of node lists is not noticeable faster for latin texts, but for arabic we gain some 10%
+-- (and could probably gain a bit more).
+
+-- All this packing in the otf format is somewhat obsessive as nowadays 4K resolution
+-- multi-gig videos pass through our networks and storage and memory is abundant.
+
+-- Although we use a few table readers there i sno real gain in there (apart from having
+-- less code. After all there are often not that many demanding features.
+
+local next, type, tonumber = next, type, tonumber
+local band = bit32.band
+local extract = bit32.extract
+local bor = bit32.bor
+local lshift = bit32.lshift
+local rshift = bit32.rshift
+local gsub = string.gsub
+local lower = string.lower
+local sub = string.sub
+local strip = string.strip
+local tohash = table.tohash
+local concat = table.concat
+local copy = table.copy
+local reversed = table.reversed
+local sort = table.sort
+local insert = table.insert
+local round = math.round
+
+local settings_to_hash = utilities.parsers.settings_to_hash_colon_too
+local setmetatableindex = table.setmetatableindex
+local formatters = string.formatters
+local sortedkeys = table.sortedkeys
+local sortedhash = table.sortedhash
+local sequenced = table.sequenced
+
+local report = logs.reporter("otf reader")
+
+local readers = fonts.handlers.otf.readers
+local streamreader = readers.streamreader
+
+local setposition = streamreader.setposition
+local getposition = streamreader.getposition
+local readuinteger = streamreader.readcardinal1
+local readushort = streamreader.readcardinal2
+local readulong = streamreader.readcardinal4
+local readinteger = streamreader.readinteger1
+local readshort = streamreader.readinteger2
+local readstring = streamreader.readstring
+local readtag = streamreader.readtag
+local readbytes = streamreader.readbytes
+local readfixed = streamreader.readfixed4
+local read2dot14 = streamreader.read2dot14
+local skipshort = streamreader.skipshort
+local skipbytes = streamreader.skip
+local readbytetable = streamreader.readbytetable
+local readbyte = streamreader.readbyte
+local readcardinaltable = streamreader.readcardinaltable
+local readintegertable = streamreader.readintegertable
+local readfword = readshort
+
+local short = 2
+local ushort = 2
+local ulong = 4
+
+directives.register("fonts.streamreader",function()
+
+ streamreader = utilities.streams
+
+ setposition = streamreader.setposition
+ getposition = streamreader.getposition
+ readuinteger = streamreader.readcardinal1
+ readushort = streamreader.readcardinal2
+ readulong = streamreader.readcardinal4
+ readinteger = streamreader.readinteger1
+ readshort = streamreader.readinteger2
+ readstring = streamreader.readstring
+ readtag = streamreader.readtag
+ readbytes = streamreader.readbytes
+ readfixed = streamreader.readfixed4
+ read2dot14 = streamreader.read2dot14
+ skipshort = streamreader.skipshort
+ skipbytes = streamreader.skip
+ readbytetable = streamreader.readbytetable
+ readbyte = streamreader.readbyte
+ readcardinaltable = streamreader.readcardinaltable
+ readintegertable = streamreader.readintegertable
+ readfword = readshort
+
+end)
+
+local gsubhandlers = { }
+local gposhandlers = { }
+
+readers.gsubhandlers = gsubhandlers
+readers.gposhandlers = gposhandlers
+
+local helpers = readers.helpers
+local gotodatatable = helpers.gotodatatable
+local setvariabledata = helpers.setvariabledata
+
+local lookupidoffset = -1 -- will become 1 when we migrate (only -1 for comparign with old)
+
+local classes = {
+ "base",
+ "ligature",
+ "mark",
+ "component",
+}
+
+local gsubtypes = {
+ "single",
+ "multiple",
+ "alternate",
+ "ligature",
+ "context",
+ "chainedcontext",
+ "extension",
+ "reversechainedcontextsingle",
+}
+
+local gpostypes = {
+ "single",
+ "pair",
+ "cursive",
+ "marktobase",
+ "marktoligature",
+ "marktomark",
+ "context",
+ "chainedcontext",
+ "extension",
+}
+
+local chaindirections = {
+ context = 0,
+ chainedcontext = 1,
+ reversechainedcontextsingle = -1,
+}
+
+local function setmetrics(data,where,tag,d)
+ local w = data[where]
+ if w then
+ local v = w[tag]
+ if v then
+ -- it looks like some fonts set the value and not the delta
+ -- report("adding %s to %s.%s value %s",d,where,tag,v)
+ w[tag] = v + d
+ end
+ end
+end
+
+local variabletags = {
+ hasc = function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end,
+ hdsc = function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end,
+ hlgp = function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end,
+ hcla = function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end,
+ hcld = function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end,
+ vasc = function(data,d) setmetrics(data,"vhea not done","ascent",d) end,
+ vdsc = function(data,d) setmetrics(data,"vhea not done","descent",d) end,
+ vlgp = function(data,d) setmetrics(data,"vhea not done","linegap",d) end,
+ xhgt = function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end,
+ cpht = function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end,
+ sbxs = function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end,
+ sbys = function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end,
+ sbxo = function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end,
+ sbyo = function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end,
+ spxs = function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end,
+ spys = function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end,
+ spxo = function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end,
+ spyo = function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end,
+ strs = function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end,
+ stro = function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end,
+ unds = function(data,d) setmetrics(data,"postscript","underlineposition",d) end,
+ undo = function(data,d) setmetrics(data,"postscript","underlinethickness",d) end,
+}
+
+local read_cardinal = {
+ streamreader.readcardinal1,
+ streamreader.readcardinal2,
+ streamreader.readcardinal3,
+ streamreader.readcardinal4,
+}
+
+local read_integer = {
+ streamreader.readinteger1,
+ streamreader.readinteger2,
+ streamreader.readinteger3,
+ streamreader.readinteger4,
+}
+
+-- Traditionally we use these unique names (so that we can flatten the lookup list
+-- (we create subsets runtime) but I will adapt the old code to newer names.
+
+-- chainsub
+-- reversesub
+
+local lookupnames = {
+ gsub = {
+ single = "gsub_single",
+ multiple = "gsub_multiple",
+ alternate = "gsub_alternate",
+ ligature = "gsub_ligature",
+ context = "gsub_context",
+ chainedcontext = "gsub_contextchain",
+ reversechainedcontextsingle = "gsub_reversecontextchain", -- reversesub
+ },
+ gpos = {
+ single = "gpos_single",
+ pair = "gpos_pair",
+ cursive = "gpos_cursive",
+ marktobase = "gpos_mark2base",
+ marktoligature = "gpos_mark2ligature",
+ marktomark = "gpos_mark2mark",
+ context = "gpos_context",
+ chainedcontext = "gpos_contextchain",
+ }
+}
+
+-- keep this as reference:
+--
+-- local lookupbits = {
+-- [0x0001] = "righttoleft",
+-- [0x0002] = "ignorebaseglyphs",
+-- [0x0004] = "ignoreligatures",
+-- [0x0008] = "ignoremarks",
+-- [0x0010] = "usemarkfilteringset",
+-- [0x00E0] = "reserved",
+-- [0xFF00] = "markattachmenttype",
+-- }
+--
+-- local lookupstate = setmetatableindex(function(t,k)
+-- local v = { }
+-- for kk, vv in next, lookupbits do
+-- if band(k,kk) ~= 0 then
+-- v[vv] = true
+-- end
+-- end
+-- t[k] = v
+-- return v
+-- end)
+
+local lookupflags = setmetatableindex(function(t,k)
+ local v = {
+ band(k,0x0008) ~= 0 and true or false, -- ignoremarks
+ band(k,0x0004) ~= 0 and true or false, -- ignoreligatures
+ band(k,0x0002) ~= 0 and true or false, -- ignorebaseglyphs
+ band(k,0x0001) ~= 0 and true or false, -- r2l
+ }
+ t[k] = v
+ return v
+end)
+
+-- Variation stores: it's not entirely clear if the regions are a shared
+-- resource (it looks like they are). Anyway, we play safe and use a
+-- share.
+
+-- values can be anything the min/max permits so we can either think of
+-- real values of a fraction along the axis (probably easier)
+
+-- wght:400,wdth:100,ital:1
+
+local function axistofactors(str)
+ local t = settings_to_hash(str)
+ for k, v in next, t do
+ t[k] = tonumber(v) or v -- this also normalizes numbers itself
+ end
+ return t
+end
+
+local hash = table.setmetatableindex(function(t,k)
+ local v = sequenced(axistofactors(k),",")
+ t[k] = v
+ return v
+end)
+
+helpers.normalizedaxishash = hash
+
+local cleanname = fonts.names and fonts.names.cleanname or function(name)
+ return name and (gsub(lower(name),"[^%a%d]","")) or nil
+end
+
+helpers.cleanname = cleanname
+
+function helpers.normalizedaxis(str)
+ return hash[str] or str
+end
+
+-- contradicting spec ... (signs) so i'll check it and fix it once we have
+-- proper fonts
+
+local function getaxisscale(segments,minimum,default,maximum,user)
+ --
+ -- returns the right values cf example in standard
+ --
+ if not minimum or not default or not maximum then
+ return false
+ end
+ if user < minimum then
+ user = minimum
+ elseif user > maximum then
+ user = maximum
+ end
+ if user < default then
+ default = - (default - user) / (default - minimum)
+ elseif user > default then
+ default = (user - default) / (maximum - default)
+ else
+ default = 0
+ end
+ if not segments then
+ return default
+ end
+ local e
+ for i=1,#segments do
+ local s = segments[i]
+ if type(s) ~= "number" then
+ report("using default axis scale")
+ return default
+ elseif s[1] >= default then
+ if s[2] == default then
+ return default
+ else
+ e = i
+ break
+ end
+ end
+ end
+ if e then
+ local b = segments[e-1]
+ local e = segments[e]
+ return b[2] + (e[2] - b[2]) * (default - b[1]) / (e[1] - b[1])
+ else
+ return false
+ end
+end
+
+local function getfactors(data,instancespec)
+ if instancespec == true then
+ -- take default
+ elseif type(instancespec) ~= "string" or instancespec == "" then
+ return
+ end
+ local variabledata = data.variabledata
+ if not variabledata then
+ return
+ end
+ local instances = variabledata.instances
+ local axis = variabledata.axis
+ local segments = variabledata.segments
+ if instances and axis then
+ local values
+ if instancespec == true then
+ -- first instance:
+ -- values = instances[1].values
+ -- axis defaults:
+ values = { }
+ for i=1,#axis do
+ values[i] = {
+ -- axis = axis[i].tag,
+ value = axis[i].default,
+ }
+ end
+
+ else
+ for i=1,#instances do
+ local instance = instances[i]
+ if cleanname(instance.subfamily) == instancespec then
+ values = instance.values
+ break
+ end
+ end
+ end
+ if values then
+ local factors = { }
+ for i=1,#axis do
+ local a = axis[i]
+ factors[i] = getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value)
+ end
+ return factors
+ end
+ local values = axistofactors(hash[instancespec] or instancespec)
+ if values then
+ local factors = { }
+ for i=1,#axis do
+ local a = axis[i]
+ local d = a.default
+ factors[i] = getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d)
+ end
+ return factors
+ end
+ end
+end
+
+local function getscales(regions,factors)
+ local scales = { }
+ for i=1,#regions do
+ local region = regions[i]
+ local s = 1
+ for j=1,#region do
+ local axis = region[j]
+ local f = factors[j]
+ local start = axis.start
+ local peak = axis.peak
+ local stop = axis.stop
+ -- get rid of these tests, false flag
+ if start > peak or peak > stop then
+ -- * 1
+ elseif start < 0 and stop > 0 and peak ~= 0 then
+ -- * 1
+ elseif peak == 0 then
+ -- * 1
+ elseif f < start or f > stop then
+ -- * 0
+ s = 0
+ break
+ elseif f < peak then
+ -- s = - s * (f - start) / (peak - start)
+ s = s * (f - start) / (peak - start)
+ elseif f > peak then
+ s = s * (stop - f) / (stop - peak)
+ else
+ -- * 1
+ end
+ end
+ scales[i] = s
+ end
+ return scales
+end
+
+helpers.getaxisscale = getaxisscale
+helpers.getfactors = getfactors
+helpers.getscales = getscales
+helpers.axistofactors = axistofactors
+
+local function readvariationdata(f,storeoffset,factors) -- store
+ local position = getposition(f)
+ setposition(f,storeoffset)
+ -- header
+ local format = readushort(f)
+ local regionoffset = storeoffset + readulong(f)
+ local nofdeltadata = readushort(f)
+ local deltadata = readcardinaltable(f,nofdeltadata,ulong)
+ -- regions
+ setposition(f,regionoffset)
+ local nofaxis = readushort(f)
+ local nofregions = readushort(f)
+ local regions = { }
+ for i=1,nofregions do -- 0
+ local t = { }
+ for i=1,nofaxis do
+ t[i] = { -- maybe no keys, just 1..3
+ start = read2dot14(f),
+ peak = read2dot14(f),
+ stop = read2dot14(f),
+ }
+ end
+ regions[i] = t
+ end
+ -- deltas
+ if factors then
+ for i=1,nofdeltadata do
+ setposition(f,storeoffset+deltadata[i])
+ local nofdeltasets = readushort(f)
+ local nofshorts = readushort(f)
+ local nofregions = readushort(f)
+ local usedregions = { }
+ local deltas = { }
+ for i=1,nofregions do
+ usedregions[i] = regions[readushort(f)+1]
+ end
+ -- we could test before and save a for
+ for i=1,nofdeltasets do
+ local t = readintegertable(f,nofshorts,short)
+ for i=nofshorts+1,nofregions do
+ t[i] = readinteger(f)
+ end
+ deltas[i] = t
+ end
+ deltadata[i] = {
+ regions = usedregions,
+ deltas = deltas,
+ scales = factors and getscales(usedregions,factors) or nil,
+ }
+ end
+ end
+ setposition(f,position)
+ return regions, deltadata
+end
+
+helpers.readvariationdata = readvariationdata
+
+-- Beware: only use the simple variant if we don't set keys/values (otherwise too many entries). We
+-- could also have a variant that applies a function but there is no real benefit in this.
+
+local function readcoverage(f,offset,simple)
+ setposition(f,offset)
+ local coverageformat = readushort(f)
+ if coverageformat == 1 then
+ local nofcoverage = readushort(f)
+ if simple then
+ -- often 1 or 2
+ if nofcoverage == 1 then
+ return { readushort(f) }
+ elseif nofcoverage == 2 then
+ return { readushort(f), readushort(f) }
+ else
+ return readcardinaltable(f,nofcoverage,ushort)
+ end
+ elseif nofcoverage == 1 then
+ return { [readushort(f)] = 0 }
+ elseif nofcoverage == 2 then
+ return { [readushort(f)] = 0, [readushort(f)] = 1 }
+ else
+ local coverage = { }
+ for i=0,nofcoverage-1 do
+ coverage[readushort(f)] = i -- index in record
+ end
+ return coverage
+ end
+ elseif coverageformat == 2 then
+ local nofranges = readushort(f)
+ local coverage = { }
+ local n = simple and 1 or 0 -- needs checking
+ for i=1,nofranges do
+ local firstindex = readushort(f)
+ local lastindex = readushort(f)
+ local coverindex = readushort(f)
+ if simple then
+ for i=firstindex,lastindex do
+ coverage[n] = i
+ n = n + 1
+ end
+ else
+ for i=firstindex,lastindex do
+ coverage[i] = n
+ n = n + 1
+ end
+ end
+ end
+ return coverage
+ else
+ report("unknown coverage format %a ",coverageformat)
+ return { }
+ end
+end
+
+local function readclassdef(f,offset,preset)
+ setposition(f,offset)
+ local classdefformat = readushort(f)
+ local classdef = { }
+ if type(preset) == "number" then
+ for k=0,preset-1 do
+ classdef[k] = 1
+ end
+ end
+ if classdefformat == 1 then
+ local index = readushort(f)
+ local nofclassdef = readushort(f)
+ for i=1,nofclassdef do
+ classdef[index] = readushort(f) + 1
+ index = index + 1
+ end
+ elseif classdefformat == 2 then
+ local nofranges = readushort(f)
+ local n = 0
+ for i=1,nofranges do
+ local firstindex = readushort(f)
+ local lastindex = readushort(f)
+ local class = readushort(f) + 1
+ for i=firstindex,lastindex do
+ classdef[i] = class
+ end
+ end
+ else
+ report("unknown classdef format %a ",classdefformat)
+ end
+ if type(preset) == "table" then
+ for k in next, preset do
+ if not classdef[k] then
+ classdef[k] = 1
+ end
+ end
+ end
+ return classdef
+end
+
+local function classtocoverage(defs)
+ if defs then
+ local list = { }
+ for index, class in next, defs do
+ local c = list[class]
+ if c then
+ c[#c+1] = index
+ else
+ list[class] = { index }
+ end
+ end
+ return list
+ end
+end
+
+-- extra readers
+
+local skips = { [0] =
+ 0, -- ----
+ 1, -- ---x
+ 1, -- --y-
+ 2, -- --yx
+ 1, -- -h--
+ 2, -- -h-x
+ 2, -- -hy-
+ 3, -- -hyx
+ 2, -- v--x
+ 2, -- v-y-
+ 3, -- v-yx
+ 2, -- vh--
+ 3, -- vh-x
+ 3, -- vhy-
+ 4, -- vhyx
+}
+
+-- We can assume that 0 is nothing and in fact we can start at 1 as
+-- usual in Lua to make sure of that.
+
+local function readvariation(f,offset)
+ local p = getposition(f)
+ setposition(f,offset)
+ local outer = readushort(f)
+ local inner = readushort(f)
+ local format = readushort(f)
+ setposition(f,p)
+ if format == 0x8000 then
+ return outer, inner
+ end
+end
+
+local function readposition(f,format,mainoffset,getdelta)
+ if format == 0 then
+ return false
+ end
+ -- a few happen often
+ if format == 0x04 then
+ local h = readshort(f)
+ if h == 0 then
+ return true -- all zero
+ else
+ return { 0, 0, h, 0 }
+ end
+ end
+ if format == 0x05 then
+ local x = readshort(f)
+ local h = readshort(f)
+ if x == 0 and h == 0 then
+ return true -- all zero
+ else
+ return { x, 0, h, 0 }
+ end
+ end
+ if format == 0x44 then
+ local h = readshort(f)
+ if getdelta then
+ local d = readshort(f) -- short or ushort
+ if d > 0 then
+ local outer, inner = readvariation(f,mainoffset+d)
+ if outer then
+ h = h + getdelta(outer,inner)
+ end
+ end
+ else
+ skipshort(f,1)
+ end
+ if h == 0 then
+ return true -- all zero
+ else
+ return { 0, 0, h, 0 }
+ end
+ end
+ --
+ -- todo:
+ --
+ -- if format == 0x55 then
+ -- local x = readshort(f)
+ -- local h = readshort(f)
+ -- ....
+ -- end
+ --
+ local x = band(format,0x1) ~= 0 and readshort(f) or 0 -- x placement
+ local y = band(format,0x2) ~= 0 and readshort(f) or 0 -- y placement
+ local h = band(format,0x4) ~= 0 and readshort(f) or 0 -- h advance
+ local v = band(format,0x8) ~= 0 and readshort(f) or 0 -- v advance
+ if format >= 0x10 then
+ local X = band(format,0x10) ~= 0 and skipshort(f) or 0
+ local Y = band(format,0x20) ~= 0 and skipshort(f) or 0
+ local H = band(format,0x40) ~= 0 and skipshort(f) or 0
+ local V = band(format,0x80) ~= 0 and skipshort(f) or 0
+ local s = skips[extract(format,4,4)]
+ if s > 0 then
+ skipshort(f,s)
+ end
+ if getdelta then
+ if X > 0 then
+ local outer, inner = readvariation(f,mainoffset+X)
+ if outer then
+ x = x + getdelta(outer,inner)
+ end
+ end
+ if Y > 0 then
+ local outer, inner = readvariation(f,mainoffset+Y)
+ if outer then
+ y = y + getdelta(outer,inner)
+ end
+ end
+ if H > 0 then
+ local outer, inner = readvariation(f,mainoffset+H)
+ if outer then
+ h = h + getdelta(outer,inner)
+ end
+ end
+ if V > 0 then
+ local outer, inner = readvariation(f,mainoffset+V)
+ if outer then
+ v = v + getdelta(outer,inner)
+ end
+ end
+ end
+ return { x, y, h, v }
+ elseif x == 0 and y == 0 and h == 0 and v == 0 then
+ return true -- all zero
+ else
+ return { x, y, h, v }
+ end
+end
+
+local function readanchor(f,offset,getdelta) -- maybe also ignore 0's as in pos
+ if not offset or offset == 0 then
+ return nil -- false
+ end
+ setposition(f,offset)
+ -- no need to skip as we position each
+ local format = readshort(f) -- 1: x y 2: x y index 3 x y X Y
+ local x = readshort(f)
+ local y = readshort(f)
+ if format == 3 then
+ if getdelta then
+ local X = readshort(f)
+ local Y = readshort(f)
+ if X > 0 then
+ local outer, inner = readvariation(f,offset+X)
+ if outer then
+ x = x + getdelta(outer,inner)
+ end
+ end
+ if Y > 0 then
+ local outer, inner = readvariation(f,offset+Y)
+ if outer then
+ y = y + getdelta(outer,inner)
+ end
+ end
+ else
+ skipshort(f,2)
+ end
+ return { x, y } -- , { xindex, yindex }
+ else
+ return { x, y }
+ end
+end
+
+-- common handlers: inlining can be faster but we cache anyway
+-- so we don't bother too much about speed here
+
+local function readfirst(f,offset)
+ if offset then
+ setposition(f,offset)
+ end
+ return { readushort(f) }
+end
+
+-- quite often 0, 1, 2
+
+function readarray(f,offset)
+ if offset then
+ setposition(f,offset)
+ end
+ local n = readushort(f)
+ if n == 1 then
+ return { readushort(f) }, 1
+ elseif n > 0 then
+ return readcardinaltable(f,n,ushort), n
+ end
+end
+
+local function readcoveragearray(f,offset,t,simple)
+ if not t then
+ return nil
+ end
+ local n = #t
+ if n == 0 then
+ return nil
+ end
+ for i=1,n do
+ t[i] = readcoverage(f,offset+t[i],simple)
+ end
+ return t
+end
+
+local function covered(subset,all)
+ local used, u
+ for i=1,#subset do
+ local s = subset[i]
+ if all[s] then
+ if used then
+ u = u + 1
+ used[u] = s
+ else
+ u = 1
+ used = { s }
+ end
+ end
+ end
+ return used
+end
+
+-- We generalize the chained lookups so that we can do with only one handler
+-- when processing them.
+
+-- pruned
+
+local function readlookuparray(f,noflookups,nofcurrent)
+ local lookups = { }
+ if noflookups > 0 then
+ local length = 0
+ for i=1,noflookups do
+ local index = readushort(f) + 1
+ if index > length then
+ length = index
+ end
+ 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
+ lookups[index] = false
+ end
+ end
+ -- if length > nofcurrent then
+ -- report("more lookups than currently matched characters")
+ -- end
+ end
+ return lookups
+end
+
+-- not pruned
+--
+-- local function readlookuparray(f,noflookups,nofcurrent)
+-- local lookups = { }
+-- for i=1,nofcurrent do
+-- lookups[i] = false
+-- end
+-- for i=1,noflookups do
+-- local index = readushort(f) + 1
+-- if index > nofcurrent then
+-- report("more lookups than currently matched characters")
+-- for i=nofcurrent+1,index-1 do
+-- lookups[i] = false
+-- end
+-- nofcurrent = index
+-- end
+-- lookups[index] = readushort(f) + 1
+-- end
+-- return lookups
+-- end
+
+local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
+ local tableoffset = lookupoffset + offset
+ setposition(f,tableoffset)
+ local subtype = readushort(f)
+ if subtype == 1 then
+ local coverage = readushort(f)
+ local subclasssets = readarray(f)
+ local rules = { }
+ if subclasssets then
+ coverage = readcoverage(f,tableoffset+coverage,true)
+ for i=1,#subclasssets do
+ local offset = subclasssets[i]
+ if offset > 0 then
+ local firstcoverage = coverage[i]
+ local rulesoffset = tableoffset + offset
+ local subclassrules = readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset + subclassrules[rule])
+ local nofcurrent = readushort(f)
+ local noflookups = readushort(f)
+ local current = { { firstcoverage } }
+ for i=2,nofcurrent do
+ current[i] = { readushort(f) }
+ end
+ local lookups = readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1] = {
+ current = current,
+ lookups = lookups
+ }
+ end
+ end
+ end
+ else
+ report("empty subclassset in %a subtype %i","unchainedcontext",subtype)
+ end
+ return {
+ format = "glyphs",
+ rules = rules,
+ }
+ elseif subtype == 2 then
+ -- We expand the classes as later on we do a pack over the whole table so then we get
+ -- back efficiency. This way we can also apply the coverage to the first current.
+ local coverage = readushort(f)
+ local currentclassdef = readushort(f)
+ local subclasssets = readarray(f)
+ local rules = { }
+ if subclasssets then
+ coverage = readcoverage(f,tableoffset + coverage)
+ currentclassdef = readclassdef(f,tableoffset + currentclassdef,coverage)
+ local currentclasses = classtocoverage(currentclassdef,fontdata.glyphs)
+ for class=1,#subclasssets do
+ local offset = subclasssets[class]
+ if offset > 0 then
+ local firstcoverage = currentclasses[class]
+ if firstcoverage then
+ firstcoverage = covered(firstcoverage,coverage) -- bonus
+ if firstcoverage then
+ local rulesoffset = tableoffset + offset
+ local subclassrules = readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset + subclassrules[rule])
+ local nofcurrent = readushort(f)
+ local noflookups = readushort(f)
+ local current = { firstcoverage }
+ for i=2,nofcurrent do
+ current[i] = currentclasses[readushort(f) + 1]
+ end
+ local lookups = readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1] = {
+ current = current,
+ lookups = lookups
+ }
+ end
+ else
+ report("no coverage")
+ end
+ else
+ report("no coverage class")
+ end
+ end
+ end
+ else
+ report("empty subclassset in %a subtype %i","unchainedcontext",subtype)
+ end
+ return {
+ format = "class",
+ rules = rules,
+ }
+ elseif subtype == 3 then
+ local nofglyphs = readushort(f)
+ local noflookups = readushort(f)
+ local current = readcardinaltable(f,nofglyphs,ushort)
+ local lookups = readlookuparray(f,noflookups,#current)
+ current = readcoveragearray(f,tableoffset,current,true)
+ return {
+ format = "coverage",
+ rules = {
+ {
+ current = current,
+ lookups = lookups,
+ }
+ }
+ }
+ else
+ report("unsupported subtype %a in %a %s",subtype,"unchainedcontext",what)
+ end
+end
+
+-- todo: optimize for n=1 ?
+
+-- class index needs checking, probably no need for +1
+
+local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
+ local tableoffset = lookupoffset + offset
+ setposition(f,tableoffset)
+ local subtype = readushort(f)
+ if subtype == 1 then
+ local coverage = readushort(f)
+ local subclasssets = readarray(f)
+ local rules = { }
+ if subclasssets then
+ coverage = readcoverage(f,tableoffset+coverage,true)
+ for i=1,#subclasssets do
+ local offset = subclasssets[i]
+ if offset > 0 then
+ local firstcoverage = coverage[i]
+ local rulesoffset = tableoffset + offset
+ local subclassrules = readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset + subclassrules[rule])
+ local nofbefore = readushort(f)
+ local before
+ if nofbefore > 0 then
+ before = { }
+ for i=1,nofbefore do
+ before[i] = { readushort(f) }
+ end
+ end
+ local nofcurrent = readushort(f)
+ local current = { { firstcoverage } }
+ for i=2,nofcurrent do
+ current[i] = { readushort(f) }
+ end
+ local nofafter = readushort(f)
+ local after
+ if nofafter > 0 then
+ after = { }
+ for i=1,nofafter do
+ after[i] = { readushort(f) }
+ end
+ end
+ local noflookups = readushort(f)
+ local lookups = readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1] = {
+ before = before,
+ current = current,
+ after = after,
+ lookups = lookups,
+ }
+ end
+ end
+ end
+ else
+ report("empty subclassset in %a subtype %i","chainedcontext",subtype)
+ end
+ return {
+ format = "glyphs",
+ rules = rules,
+ }
+ elseif subtype == 2 then
+ local coverage = readushort(f)
+ local beforeclassdef = readushort(f)
+ local currentclassdef = readushort(f)
+ local afterclassdef = readushort(f)
+ local subclasssets = readarray(f)
+ local rules = { }
+ if subclasssets then
+ local coverage = readcoverage(f,tableoffset + coverage)
+ local beforeclassdef = readclassdef(f,tableoffset + beforeclassdef,nofglyphs)
+ local currentclassdef = readclassdef(f,tableoffset + currentclassdef,coverage)
+ local afterclassdef = readclassdef(f,tableoffset + afterclassdef,nofglyphs)
+ local beforeclasses = classtocoverage(beforeclassdef,fontdata.glyphs)
+ local currentclasses = classtocoverage(currentclassdef,fontdata.glyphs)
+ local afterclasses = classtocoverage(afterclassdef,fontdata.glyphs)
+ for class=1,#subclasssets do
+ local offset = subclasssets[class]
+ if offset > 0 then
+ local firstcoverage = currentclasses[class]
+ if firstcoverage then
+ firstcoverage = covered(firstcoverage,coverage) -- bonus
+ if firstcoverage then
+ local rulesoffset = tableoffset + offset
+ local subclassrules = readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ -- watch out, in context we first get the counts and then the arrays while
+ -- here we get them mixed
+ setposition(f,rulesoffset + subclassrules[rule])
+ local nofbefore = readushort(f)
+ local before
+ if nofbefore > 0 then
+ before = { }
+ for i=1,nofbefore do
+ before[i] = beforeclasses[readushort(f) + 1]
+ end
+ end
+ local nofcurrent = readushort(f)
+ local current = { firstcoverage }
+ for i=2,nofcurrent do
+ current[i] = currentclasses[readushort(f)+ 1]
+ end
+ local nofafter = readushort(f)
+ local after
+ if nofafter > 0 then
+ after = { }
+ for i=1,nofafter do
+ after[i] = afterclasses[readushort(f) + 1]
+ end
+ end
+ -- no sequence index here (so why in context as it saves nothing)
+ local noflookups = readushort(f)
+ local lookups = readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1] = {
+ before = before,
+ current = current,
+ after = after,
+ lookups = lookups,
+ }
+ end
+ else
+ report("no coverage")
+ end
+ else
+ report("class is not covered")
+ end
+ end
+ end
+ else
+ report("empty subclassset in %a subtype %i","chainedcontext",subtype)
+ end
+ return {
+ format = "class",
+ rules = rules,
+ }
+ elseif subtype == 3 then
+ local before = readarray(f)
+ local current = readarray(f)
+ local after = readarray(f)
+ local noflookups = readushort(f)
+ local lookups = readlookuparray(f,noflookups,#current)
+ before = readcoveragearray(f,tableoffset,before,true)
+ current = readcoveragearray(f,tableoffset,current,true)
+ after = readcoveragearray(f,tableoffset,after,true)
+ return {
+ format = "coverage",
+ rules = {
+ {
+ before = before,
+ current = current,
+ after = after,
+ lookups = lookups,
+ }
+ }
+ }
+ else
+ report("unsupported subtype %a in %a %s",subtype,"chainedcontext",what)
+ end
+end
+
+local function extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,types,handlers,what)
+ local tableoffset = lookupoffset + offset
+ setposition(f,tableoffset)
+ local subtype = readushort(f)
+ if subtype == 1 then
+ local lookuptype = types[readushort(f)]
+ local faroffset = readulong(f)
+ local handler = handlers[lookuptype]
+ if handler then
+ -- maybe we can just pass one offset (or tableoffset first)
+ return handler(f,fontdata,lookupid,tableoffset + faroffset,0,glyphs,nofglyphs), lookuptype
+ else
+ report("no handler for lookuptype %a subtype %a in %s %s",lookuptype,subtype,what,"extension")
+ end
+ else
+ report("unsupported subtype %a in %s %s",subtype,what,"extension")
+ end
+end
+
+-- gsub handlers
+
+function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset = lookupoffset + offset
+ setposition(f,tableoffset)
+ local subtype = readushort(f)
+ if subtype == 1 then
+ local coverage = readushort(f)
+ local delta = readshort(f) -- can be negative
+ local coverage = readcoverage(f,tableoffset+coverage) -- not simple as we need to set key/value anyway
+ for index in next, coverage do
+ local newindex = (index + delta) % 65536 -- modulo is new in 1.8.3
+ if index > nofglyphs or newindex > nofglyphs then
+ report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs)
+ coverage[index] = nil
+ else
+ coverage[index] = newindex
+ end
+ end
+ return {
+ coverage = coverage
+ }
+ elseif subtype == 2 then -- in streamreader a seek and fetch is faster than a temp table
+ local coverage = readushort(f)
+ local nofreplacements = readushort(f)
+ local replacements = readcardinaltable(f,nofreplacements,ushort)
+ local coverage = readcoverage(f,tableoffset + coverage) -- not simple as we need to set key/value anyway
+ for index, newindex in next, coverage do
+ newindex = newindex + 1
+ if index > nofglyphs or newindex > nofglyphs then
+ report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs)
+ coverage[index] = nil
+ else
+ coverage[index] = replacements[newindex]
+ end
+ end
+ return {
+ coverage = coverage
+ }
+ else
+ report("unsupported subtype %a in %a substitution",subtype,"single")
+ end
+end
+
+-- we see coverage format 0x300 in some old ms fonts
+
+local function sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
+ local tableoffset = lookupoffset + offset
+ setposition(f,tableoffset)
+ local subtype = readushort(f)
+ if subtype == 1 then
+ local coverage = readushort(f)
+ local nofsequence = readushort(f)
+ local sequences = readcardinaltable(f,nofsequence,ushort)
+ for i=1,nofsequence do
+ setposition(f,tableoffset + sequences[i])
+ sequences[i] = readcardinaltable(f,readushort(f),ushort)
+ end
+ local coverage = readcoverage(f,tableoffset + coverage)
+ for index, newindex in next, coverage do
+ newindex = newindex + 1
+ if index > nofglyphs or newindex > nofglyphs then
+ report("invalid index in %s format %i: %i -> %i (max %i)",what,subtype,index,newindex,nofglyphs)
+ coverage[index] = nil
+ else
+ coverage[index] = sequences[newindex]
+ end
+ end
+ return {
+ coverage = coverage
+ }
+ else
+ report("unsupported subtype %a in %a substitution",subtype,what)
+ end
+end
+
+function gsubhandlers.multiple(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"multiple")
+end
+
+function gsubhandlers.alternate(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"alternate")
+end
+
+function gsubhandlers.ligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset = lookupoffset + offset
+ setposition(f,tableoffset)
+ local subtype = readushort(f)
+ if subtype == 1 then
+ local coverage = readushort(f)
+ local nofsets = readushort(f)
+ local ligatures = readcardinaltable(f,nofsets,ushort)
+ for i=1,nofsets do
+ local offset = lookupoffset + offset + ligatures[i]
+ setposition(f,offset)
+ local n = readushort(f)
+ if n == 1 then
+ ligatures[i] = { offset + readushort(f) }
+ else
+ local l = { }
+ for i=1,n do
+ l[i] = offset + readushort(f)
+ end
+ ligatures[i] = l
+ end
+ end
+ local coverage = readcoverage(f,tableoffset + coverage)
+ for index, newindex in next, coverage do
+ local hash = { }
+ local ligatures = ligatures[newindex+1]
+ for i=1,#ligatures do
+ local offset = ligatures[i]
+ setposition(f,offset)
+ local lig = readushort(f)
+ local cnt = readushort(f)
+ local hsh = hash
+ for i=2,cnt do
+ local c = readushort(f)
+ local h = hsh[c]
+ if not h then
+ h = { }
+ hsh[c] = h
+ end
+ hsh = h
+ end
+ hsh.ligature = lig
+ end
+ coverage[index] = hash
+ end
+ return {
+ coverage = coverage
+ }
+ else
+ report("unsupported subtype %a in %a substitution",subtype,"ligature")
+ end
+end
+
+function gsubhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"), "context"
+end
+
+function gsubhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"), "chainedcontext"
+end
+
+function gsubhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gsubtypes,gsubhandlers,"substitution")
+end
+
+function gsubhandlers.reversechainedcontextsingle(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset = lookupoffset + offset
+ setposition(f,tableoffset)
+ local subtype = readushort(f)
+ if subtype == 1 then -- NEEDS CHECKING
+ local current = readfirst(f)
+ local before = readarray(f)
+ local after = readarray(f)
+ local replacements = readarray(f)
+ current = readcoveragearray(f,tableoffset,current,true)
+ before = readcoveragearray(f,tableoffset,before,true)
+ after = readcoveragearray(f,tableoffset,after,true)
+ return {
+ format = "reversecoverage", -- reversesub
+ rules = {
+ {
+ before = before,
+ current = current,
+ after = after,
+ replacements = replacements,
+ }
+ }
+ }, "reversechainedcontextsingle"
+ else
+ report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle")
+ end
+end
+
+-- gpos handlers
+
+local function readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta)
+ local done = { }
+ for i=1,#sets do
+ local offset = sets[i]
+ local reused = done[offset]
+ if not reused then
+ offset = tableoffset + offset
+ setposition(f,offset)
+ local n = readushort(f)
+ reused = { }
+ for i=1,n do
+ reused[i] = {
+ readushort(f), -- second glyph id
+ readposition(f,format1,offset,getdelta),
+ readposition(f,format2,offset,getdelta),
+ }
+ end
+ done[offset] = reused
+ end
+ sets[i] = reused
+ end
+ return sets
+end
+
+local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,mainoffset,getdelta)
+ local classlist1 = { }
+ for i=1,nofclasses1 do
+ local classlist2 = { }
+ classlist1[i] = classlist2
+ for j=1,nofclasses2 do
+ local one = readposition(f,format1,mainoffset,getdelta)
+ local two = readposition(f,format2,mainoffset,getdelta)
+ if one or two then
+ classlist2[j] = { one, two }
+ else
+ classlist2[j] = false
+ end
+ end
+ end
+ return classlist1
+end
+
+-- no real gain in kerns as we pack
+
+function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset = lookupoffset + offset
+ setposition(f,tableoffset)
+ local subtype = readushort(f)
+ local getdelta = fontdata.temporary.getdelta
+ if subtype == 1 then
+ local coverage = readushort(f)
+ local format = readushort(f)
+ local value = readposition(f,format,tableoffset,getdelta)
+ local coverage = readcoverage(f,tableoffset+coverage)
+ for index, newindex in next, coverage do
+ coverage[index] = value -- will be packed and shared anyway
+ end
+ return {
+ format = "single",
+ coverage = coverage,
+ }
+ elseif subtype == 2 then
+ local coverage = readushort(f)
+ local format = readushort(f)
+ local nofvalues = readushort(f)
+ local values = { }
+ for i=1,nofvalues do
+ values[i] = readposition(f,format,tableoffset,getdelta)
+ end
+ local coverage = readcoverage(f,tableoffset+coverage)
+ for index, newindex in next, coverage do
+ coverage[index] = values[newindex+1]
+ end
+ return {
+ format = "single",
+ coverage = coverage,
+ }
+ else
+ report("unsupported subtype %a in %a positioning",subtype,"single")
+ end
+end
+
+-- this needs checking! if no second pair then another advance over the list
+
+-- ValueFormat1 applies to the ValueRecord of the first glyph in each pair. ValueRecords for all first glyphs must use ValueFormat1. If ValueFormat1 is set to zero (0), the corresponding glyph has no ValueRecord and, therefore, should not be repositioned.
+-- ValueFormat2 applies to the ValueRecord of the second glyph in each pair. ValueRecords for all second glyphs must use ValueFormat2. If ValueFormat2 is set to null, then the second glyph of the pair is the “next†glyph for which a lookup should be performed.
+
+-- local simple = {
+-- [true] = { [true] = { true, true }, [false] = { true } },
+-- [false] = { [true] = { false, true }, [false] = { false } },
+-- }
+
+-- function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+-- local tableoffset = lookupoffset + offset
+-- setposition(f,tableoffset)
+-- local subtype = readushort(f)
+-- local getdelta = fontdata.temporary.getdelta
+-- if subtype == 1 then
+-- local coverage = readushort(f)
+-- local format1 = readushort(f)
+-- local format2 = readushort(f)
+-- local sets = readarray(f)
+-- sets = readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta)
+-- coverage = readcoverage(f,tableoffset + coverage)
+-- local shared = { } -- partial sparse, when set also needs to be handled in the packer
+-- for index, newindex in next, coverage do
+-- local set = sets[newindex+1]
+-- local hash = { }
+-- for i=1,#set do
+-- local value = set[i]
+-- if value then
+-- local other = value[1]
+-- if shared then
+-- local s = shared[value]
+-- if s == nil then
+-- local first = value[2]
+-- local second = value[3]
+-- if first or second then
+-- s = { first, second or nil } -- needs checking
+-- else
+-- s = false
+-- end
+-- shared[value] = s
+-- end
+-- hash[other] = s or nil
+-- else
+-- local first = value[2]
+-- local second = value[3]
+-- if first or second then
+-- hash[other] = { first, second or nil } -- needs checking
+-- else
+-- hash[other] = nil -- what if set, maybe warning
+-- end
+-- end
+-- end
+-- end
+-- coverage[index] = hash
+-- end
+-- return {
+-- shared = shared and true or nil,
+-- format = "pair",
+-- coverage = coverage,
+-- }
+-- elseif subtype == 2 then
+-- local coverage = readushort(f)
+-- local format1 = readushort(f)
+-- local format2 = readushort(f)
+-- local classdef1 = readushort(f)
+-- local classdef2 = readushort(f)
+-- local nofclasses1 = readushort(f) -- incl class 0
+-- local nofclasses2 = readushort(f) -- incl class 0
+-- local classlist = readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta)
+-- coverage = readcoverage(f,tableoffset+coverage)
+-- classdef1 = readclassdef(f,tableoffset+classdef1,coverage)
+-- classdef2 = readclassdef(f,tableoffset+classdef2,nofglyphs)
+-- local usedcoverage = { }
+-- local shared = { } -- partial sparse, when set also needs to be handled in the packer
+-- for g1, c1 in next, classdef1 do
+-- if coverage[g1] then
+-- local l1 = classlist[c1]
+-- if l1 then
+-- local hash = { }
+-- for paired, class in next, classdef2 do
+-- local offsets = l1[class]
+-- if offsets then
+-- local first = offsets[1]
+-- local second = offsets[2]
+-- if first or second then
+-- if shared then
+-- local s1 = shared[first]
+-- if s1 == nil then
+-- s1 = { }
+-- shared[first] = s1
+-- end
+-- local s2 = s1[second]
+-- if s2 == nil then
+-- s2 = { first, second or nil }
+-- s1[second] = s2
+-- end
+-- hash[paired] = s2
+-- else
+-- hash[paired] = { first, second or nil }
+-- end
+-- else
+-- -- upto the next lookup for this combination
+-- end
+-- end
+-- end
+-- usedcoverage[g1] = hash
+-- end
+-- end
+-- end
+-- return {
+-- shared = shared and true or nil,
+-- format = "pair",
+-- coverage = usedcoverage,
+-- }
+-- elseif subtype == 3 then
+-- report("yet unsupported subtype %a in %a positioning",subtype,"pair")
+-- else
+-- report("unsupported subtype %a in %a positioning",subtype,"pair")
+-- end
+-- end
+
+function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset = lookupoffset + offset
+ setposition(f,tableoffset)
+ local subtype = readushort(f)
+ local getdelta = fontdata.temporary.getdelta
+ if subtype == 1 then
+ local coverage = readushort(f)
+ local format1 = readushort(f)
+ local format2 = readushort(f)
+ local sets = readarray(f)
+ sets = readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta)
+ coverage = readcoverage(f,tableoffset + coverage)
+ local shared = { } -- partial sparse, when set also needs to be handled in the packer
+ for index, newindex in next, coverage do
+ local set = sets[newindex+1]
+ local hash = { }
+ for i=1,#set do
+ local value = set[i]
+ if value then
+ local other = value[1]
+ local share = shared[value]
+ if share == nil then
+ local first = value[2]
+ local second = value[3]
+ if first or second then
+ share = { first, second or nil } -- needs checking
+ else
+ share = false
+ end
+ shared[value] = share
+ end
+ hash[other] = share or nil -- really overload ?
+ end
+ end
+ coverage[index] = hash
+ end
+ return {
+ shared = shared and true or nil,
+ format = "pair",
+ coverage = coverage,
+ }
+ elseif subtype == 2 then
+ local coverage = readushort(f)
+ local format1 = readushort(f)
+ local format2 = readushort(f)
+ local classdef1 = readushort(f)
+ local classdef2 = readushort(f)
+ local nofclasses1 = readushort(f) -- incl class 0
+ local nofclasses2 = readushort(f) -- incl class 0
+ local classlist = readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta)
+ coverage = readcoverage(f,tableoffset+coverage)
+ classdef1 = readclassdef(f,tableoffset+classdef1,coverage)
+ classdef2 = readclassdef(f,tableoffset+classdef2,nofglyphs)
+ local usedcoverage = { }
+ local shared = { } -- partial sparse, when set also needs to be handled in the packer
+ for g1, c1 in next, classdef1 do
+ if coverage[g1] then
+ local l1 = classlist[c1]
+ if l1 then
+ local hash = { }
+ for paired, class in next, classdef2 do
+ local offsets = l1[class]
+ if offsets then
+ local first = offsets[1]
+ local second = offsets[2]
+ if first or second then
+ local s1 = shared[first]
+ if s1 == nil then
+ s1 = { }
+ shared[first] = s1
+ end
+ local s2 = s1[second]
+ if s2 == nil then
+ s2 = { first, second or nil }
+ s1[second] = s2
+ end
+ hash[paired] = s2
+ end
+ end
+ end
+ usedcoverage[g1] = hash
+ end
+ end
+ end
+ return {
+ shared = shared and true or nil,
+ format = "pair",
+ coverage = usedcoverage,
+ }
+ elseif subtype == 3 then
+ report("yet unsupported subtype %a in %a positioning",subtype,"pair")
+ else
+ report("unsupported subtype %a in %a positioning",subtype,"pair")
+ end
+end
+
+function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset = lookupoffset + offset
+ setposition(f,tableoffset)
+ local subtype = readushort(f)
+ local getdelta = fontdata.temporary.getdelta
+ if subtype == 1 then
+ local coverage = tableoffset + readushort(f)
+ local nofrecords = readushort(f)
+ local records = { }
+ for i=1,nofrecords do
+ local entry = readushort(f)
+ local exit = readushort(f)
+ records[i] = {
+ -- entry = entry ~= 0 and (tableoffset + entry) or false,
+ -- exit = exit ~= 0 and (tableoffset + exit ) or nil,
+ entry ~= 0 and (tableoffset + entry) or false,
+ exit ~= 0 and (tableoffset + exit ) or nil,
+ }
+ end
+ -- slot 1 will become hash after loading and it must be unique because we
+ -- pack the tables (packed we turn the cc-* into a zero)
+ local cc = (fontdata.temporary.cursivecount or 0) + 1
+ fontdata.temporary.cursivecount = cc
+ cc = "cc-" .. cc
+ coverage = readcoverage(f,coverage)
+ for i=1,nofrecords do
+ local r = records[i]
+ records[i] = {
+ -- 1,
+ cc,
+ -- readanchor(f,r.entry,getdelta) or false,
+ -- readanchor(f,r.exit, getdelta) or nil,
+ readanchor(f,r[1],getdelta) or false,
+ readanchor(f,r[2],getdelta) or nil,
+ }
+ end
+ for index, newindex in next, coverage do
+ coverage[index] = records[newindex+1]
+ end
+ return {
+ coverage = coverage,
+ }
+ else
+ report("unsupported subtype %a in %a positioning",subtype,"cursive")
+ end
+end
+
+local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,ligature)
+ local tableoffset = lookupoffset + offset
+ setposition(f,tableoffset)
+ local subtype = readushort(f)
+ local getdelta = fontdata.temporary.getdelta
+ if subtype == 1 then
+ -- we are one based, not zero
+ local markcoverage = tableoffset + readushort(f)
+ local basecoverage = tableoffset + readushort(f)
+ local nofclasses = readushort(f)
+ local markoffset = tableoffset + readushort(f)
+ local baseoffset = tableoffset + readushort(f)
+ --
+ local markcoverage = readcoverage(f,markcoverage)
+ local basecoverage = readcoverage(f,basecoverage,true) -- TO BE CHECKED: true
+ --
+ setposition(f,markoffset)
+ local markclasses = { }
+ local nofmarkclasses = readushort(f)
+ --
+ local lastanchor = fontdata.lastanchor or 0
+ local usedanchors = { }
+ --
+ for i=1,nofmarkclasses do
+ local class = readushort(f) + 1
+ local offset = readushort(f)
+ if offset == 0 then
+ markclasses[i] = false
+ else
+ markclasses[i] = { class, markoffset + offset }
+ end
+ usedanchors[class] = true
+ end
+ for i=1,nofmarkclasses do
+ local mc = markclasses[i]
+ if mc then
+ mc[2] = readanchor(f,mc[2],getdelta)
+ end
+ end
+ --
+ setposition(f,baseoffset)
+ local nofbaserecords = readushort(f)
+ local baserecords = { }
+ --
+ if ligature then
+ -- 3 components
+ -- 1 : class .. nofclasses -- NULL when empty
+ -- 2 : class .. nofclasses -- NULL when empty
+ -- 3 : class .. nofclasses -- NULL when empty
+ for i=1,nofbaserecords do -- here i is the class
+ local offset = readushort(f)
+ if offset == 0 then
+ baserecords[i] = false
+ else
+ baserecords[i] = baseoffset + offset
+ end
+ end
+ for i=1,nofbaserecords do
+ local recordoffset = baserecords[i]
+ if recordoffset then
+ setposition(f,recordoffset)
+ local nofcomponents = readushort(f)
+ local components = { }
+ for i=1,nofcomponents do
+ local classes = { }
+ for i=1,nofclasses do
+ local offset = readushort(f)
+ if offset ~= 0 then
+ classes[i] = recordoffset + offset
+ else
+ classes[i] = false
+ end
+ end
+ components[i] = classes
+ end
+ baserecords[i] = components
+ end
+ end
+ local baseclasses = { } -- setmetatableindex("table")
+ for i=1,nofclasses do
+ baseclasses[i] = { }
+ end
+ for i=1,nofbaserecords do
+ local components = baserecords[i]
+ if components then
+ local b = basecoverage[i]
+ for c=1,#components do
+ local classes = components[c]
+ if classes then
+ for i=1,nofclasses do
+ local anchor = readanchor(f,classes[i],getdelta)
+ local bclass = baseclasses[i]
+ local bentry = bclass[b]
+ if bentry then
+ bentry[c] = anchor
+ else
+ bclass[b]= { [c] = anchor }
+ end
+ end
+ end
+ end
+ end
+ end
+ for index, newindex in next, markcoverage do
+ markcoverage[index] = markclasses[newindex+1] or nil
+ end
+ return {
+ format = "ligature",
+ baseclasses = baseclasses,
+ coverage = markcoverage,
+ }
+ else
+ for i=1,nofbaserecords do
+ local r = { }
+ for j=1,nofclasses do
+ local offset = readushort(f)
+ if offset == 0 then
+ r[j] = false
+ else
+ r[j] = baseoffset + offset
+ end
+ end
+ baserecords[i] = r
+ end
+ local baseclasses = { } -- setmetatableindex("table")
+ for i=1,nofclasses do
+ baseclasses[i] = { }
+ end
+ for i=1,nofbaserecords do
+ local r = baserecords[i]
+ local b = basecoverage[i]
+ for j=1,nofclasses do
+ baseclasses[j][b] = readanchor(f,r[j],getdelta)
+ end
+ end
+ for index, newindex in next, markcoverage do
+ markcoverage[index] = markclasses[newindex+1] or nil
+ end
+ -- we could actually already calculate the displacement if we want
+ return {
+ format = "base",
+ baseclasses = baseclasses,
+ coverage = markcoverage,
+ }
+ end
+ else
+ report("unsupported subtype %a in",subtype)
+ end
+
+end
+
+function gposhandlers.marktobase(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+end
+
+function gposhandlers.marktoligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,true)
+end
+
+function gposhandlers.marktomark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+end
+
+function gposhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"), "context"
+end
+
+function gposhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"), "chainedcontext"
+end
+
+function gposhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gpostypes,gposhandlers,"positioning")
+end
+
+-- main loader
+
+do
+
+ local plugins = { }
+
+ function plugins.size(f,fontdata,tableoffset,feature)
+ if fontdata.designsize then
+ -- yes, there are fonts with multiple size entries ... it probably relates
+ -- to the other two fields (menu entries in some language)
+ else
+ local function check(offset)
+ setposition(f,offset)
+ local designsize = readushort(f)
+ if designsize > 0 then -- we could also have a threshold
+ local fontstyleid = readushort(f)
+ local guimenuid = readushort(f)
+ local minsize = readushort(f)
+ local maxsize = readushort(f)
+ if minsize == 0 and maxsize == 0 and fontstyleid == 0 and guimenuid == 0 then
+ minsize = designsize
+ maxsize = designsize
+ end
+ if designsize >= minsize and designsize <= maxsize then
+ return minsize, maxsize, designsize
+ end
+ end
+ end
+ local minsize, maxsize, designsize = check(tableoffset+feature.offset+feature.parameters)
+ if not designsize then
+ -- some old adobe fonts have: tableoffset+feature.parameters and we could
+ -- use some heuristic but why bother ... this extra check will be removed
+ -- some day and/or when we run into an issue
+ minsize, maxsize, designsize = check(tableoffset+feature.parameters)
+ if designsize then
+ report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?")
+ else
+ report("bad size feature in %a,",fontdata.filename or "?")
+ end
+ end
+ if designsize then
+ fontdata.minsize = minsize
+ fontdata.maxsize = maxsize
+ fontdata.designsize = designsize
+ end
+ end
+ end
+
+ -- function plugins.rvrn(f,fontdata,tableoffset,feature)
+ -- -- todo, at least a message
+ -- end
+
+ -- feature order needs checking ... as we loop over a hash ... however, in the file
+ -- they are sorted so order is not that relevant
+
+ local function reorderfeatures(fontdata,scripts,features)
+ local scriptlangs = { }
+ local featurehash = { }
+ local featureorder = { }
+ for script, languages in next, scripts do
+ for language, record in next, languages do
+ local hash = { }
+ local list = record.featureindices
+ for k=1,#list do
+ local index = list[k]
+ local feature = features[index]
+ local lookups = feature.lookups
+ local tag = feature.tag
+ if tag then
+ hash[tag] = true
+ end
+ if lookups then
+ for i=1,#lookups do
+ local lookup = lookups[i]
+ local o = featureorder[lookup]
+ if o then
+ local okay = true
+ for i=1,#o do
+ if o[i] == tag then
+ okay = false
+ break
+ end
+ end
+ if okay then
+ o[#o+1] = tag
+ end
+ else
+ featureorder[lookup] = { tag }
+ end
+ local f = featurehash[lookup]
+ if f then
+ local h = f[tag]
+ if h then
+ local s = h[script]
+ if s then
+ s[language] = true
+ else
+ h[script] = { [language] = true }
+ end
+ else
+ f[tag] = { [script] = { [language] = true } }
+ end
+ else
+ featurehash[lookup] = { [tag] = { [script] = { [language] = true } } }
+ end
+ --
+ local h = scriptlangs[tag]
+ if h then
+ local s = h[script]
+ if s then
+ s[language] = true
+ else
+ h[script] = { [language] = true }
+ end
+ else
+ scriptlangs[tag] = { [script] = { [language] = true } }
+ end
+ end
+ end
+ end
+ end
+ end
+ return scriptlangs, featurehash, featureorder
+ end
+
+ local function readscriplan(f,fontdata,scriptoffset)
+ setposition(f,scriptoffset)
+ local nofscripts = readushort(f)
+ local scripts = { }
+ for i=1,nofscripts do
+ scripts[readtag(f)] = scriptoffset + readushort(f)
+ end
+ -- script list -> language system info
+ local languagesystems = setmetatableindex("table")
+ for script, offset in next, scripts do
+ setposition(f,offset)
+ local defaultoffset = readushort(f)
+ local noflanguages = readushort(f)
+ local languages = { }
+ if defaultoffset > 0 then
+ languages.dflt = languagesystems[offset + defaultoffset]
+ end
+ for i=1,noflanguages do
+ local language = readtag(f)
+ local offset = offset + readushort(f)
+ languages[language] = languagesystems[offset]
+ end
+ scripts[script] = languages
+ end
+ -- script list -> language system info -> feature list
+ for offset, usedfeatures in next, languagesystems do
+ if offset > 0 then
+ setposition(f,offset)
+ local featureindices = { }
+ usedfeatures.featureindices = featureindices
+ usedfeatures.lookuporder = readushort(f) -- reserved, not used (yet)
+ usedfeatures.requiredindex = readushort(f) -- relates to required (can be 0xFFFF)
+ local noffeatures = readushort(f)
+ for i=1,noffeatures do
+ featureindices[i] = readushort(f) + 1
+ end
+ end
+ end
+ return scripts
+ end
+
+ local function readfeatures(f,fontdata,featureoffset)
+ setposition(f,featureoffset)
+ local features = { }
+ local noffeatures = readushort(f)
+ for i=1,noffeatures do
+ -- also shared?
+ features[i] = {
+ tag = readtag(f),
+ offset = readushort(f)
+ }
+ end
+ --
+ for i=1,noffeatures do
+ local feature = features[i]
+ local offset = featureoffset+feature.offset
+ setposition(f,offset)
+ local parameters = readushort(f) -- feature.parameters
+ local noflookups = readushort(f)
+ if noflookups > 0 then
+-- local lookups = { }
+-- feature.lookups = lookups
+-- for j=1,noflookups do
+-- lookups[j] = readushort(f) + 1
+-- end
+ local lookups = readcardinaltable(f,noflookups,ushort)
+ feature.lookups = lookups
+ for j=1,noflookups do
+ lookups[j] = lookups[j] + 1
+ end
+ end
+ if parameters > 0 then
+ feature.parameters = parameters
+ local plugin = plugins[feature.tag]
+ if plugin then
+ plugin(f,fontdata,featureoffset,feature)
+ end
+ end
+ end
+ return features
+ end
+
+ local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder)
+ setposition(f,lookupoffset)
+ local noflookups = readushort(f)
+ local lookups = readcardinaltable(f,noflookups,ushort)
+ for lookupid=1,noflookups do
+ local offset = lookups[lookupid]
+ setposition(f,lookupoffset+offset)
+ local subtables = { }
+ local typebits = readushort(f)
+ local flagbits = readushort(f)
+ local lookuptype = lookuptypes[typebits]
+ local lookupflags = lookupflags[flagbits]
+ local nofsubtables = readushort(f)
+ for j=1,nofsubtables do
+ subtables[j] = offset + readushort(f) -- we can probably put lookupoffset here
+ end
+ -- which one wins?
+ local markclass = band(flagbits,0x0010) ~= 0 -- usemarkfilteringset
+ if markclass then
+ markclass = readushort(f) -- + 1
+ end
+ local markset = rshift(flagbits,8)
+ if markset > 0 then
+ markclass = markset -- + 1
+ end
+ lookups[lookupid] = {
+ type = lookuptype,
+ -- chain = chaindirections[lookuptype] or nil,
+ flags = lookupflags,
+ name = lookupid,
+ subtables = subtables,
+ markclass = markclass,
+ features = featurehash[lookupid], -- not if extension
+ order = featureorder[lookupid],
+ }
+ end
+ return lookups
+ end
+
+ local f_lookupname = formatters["%s_%s_%s"]
+
+ local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset)
+
+ local sequences = fontdata.sequences or { }
+ local sublookuplist = fontdata.sublookups or { }
+ fontdata.sequences = sequences
+ fontdata.sublookups = sublookuplist
+ local nofsublookups = #sublookuplist
+ local nofsequences = #sequences -- 0
+ local lastsublookup = nofsublookups
+ local lastsequence = nofsequences
+ local lookupnames = lookupnames[what]
+ local sublookuphash = { }
+ local sublookupcheck = { }
+ local glyphs = fontdata.glyphs
+ local nofglyphs = fontdata.nofglyphs or #glyphs
+ local noflookups = #lookups
+ local lookupprefix = sub(what,2,2) -- g[s|p][ub|os]
+ --
+ local usedlookups = false -- setmetatableindex("number")
+ --
+ for lookupid=1,noflookups do
+ local lookup = lookups[lookupid]
+ local lookuptype = lookup.type
+ local subtables = lookup.subtables
+ local features = lookup.features
+ local handler = lookuphandlers[lookuptype]
+ if handler then
+ local nofsubtables = #subtables
+ local order = lookup.order
+ local flags = lookup.flags
+ -- this is expected in the font handler (faster checking)
+ if flags[1] then flags[1] = "mark" end
+ if flags[2] then flags[2] = "ligature" end
+ if flags[3] then flags[3] = "base" end
+ --
+ local markclass = lookup.markclass
+ -- local chain = lookup.chain
+ if nofsubtables > 0 then
+ local steps = { }
+ local nofsteps = 0
+ local oldtype = nil
+ for s=1,nofsubtables do
+ local step, lt = handler(f,fontdata,lookupid,lookupoffset,subtables[s],glyphs,nofglyphs)
+ if lt then
+ lookuptype = lt
+ if oldtype and lt ~= oldtype then
+ report("messy %s lookup type %a and %a",what,lookuptype,oldtype)
+ end
+ oldtype = lookuptype
+ end
+ if not step then
+ report("unsupported %s lookup type %a",what,lookuptype)
+ else
+ nofsteps = nofsteps + 1
+ steps[nofsteps] = step
+ local rules = step.rules
+ if rules then
+ for i=1,#rules do
+ local rule = rules[i]
+ local before = rule.before
+ local current = rule.current
+ local after = rule.after
+ local replacements = rule.replacements
+ if before then
+ for i=1,#before do
+ before[i] = tohash(before[i])
+ end
+ -- as with original ctx ff loader
+ rule.before = reversed(before)
+ end
+ if current then
+ if replacements then
+ -- We have a reverse lookup and therefore only one current entry. We might need
+ -- to reverse the order in the before and after lists so that needs checking.
+ local first = current[1]
+ local hash = { }
+ local repl = { }
+ for i=1,#first do
+ local c = first[i]
+ hash[c] = true
+ repl[c] = replacements[i]
+ end
+ rule.current = { hash }
+ rule.replacements = repl
+ else
+ for i=1,#current do
+ current[i] = tohash(current[i])
+ end
+ end
+ else
+ -- weird lookup
+ end
+ if after then
+ for i=1,#after do
+ after[i] = tohash(after[i])
+ end
+ end
+ if usedlookups then
+ local lookups = rule.lookups
+ if lookups then
+ for k, v in next, lookups do
+ if v then
+ for k, v in next, v do
+ usedlookups[v] = usedlookups[v] + 1
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if nofsteps ~= nofsubtables then
+ report("bogus subtables removed in %s lookup type %a",what,lookuptype)
+ end
+ lookuptype = lookupnames[lookuptype] or lookuptype
+ if features then
+ nofsequences = nofsequences + 1
+ -- report("registering %i as sequence step %i",lookupid,nofsequences)
+ local l = {
+ index = nofsequences,
+ name = f_lookupname(lookupprefix,"s",lookupid+lookupidoffset),
+ steps = steps,
+ nofsteps = nofsteps,
+ type = lookuptype,
+ markclass = markclass or nil,
+ flags = flags,
+ -- chain = chain,
+ order = order,
+ features = features,
+ }
+ sequences[nofsequences] = l
+ lookup.done = l
+ else
+ nofsublookups = nofsublookups + 1
+ -- report("registering %i as sublookup %i",lookupid,nofsublookups)
+ local l = {
+ index = nofsublookups,
+ name = f_lookupname(lookupprefix,"l",lookupid+lookupidoffset),
+ steps = steps,
+ nofsteps = nofsteps,
+ type = lookuptype,
+ markclass = markclass or nil,
+ flags = flags,
+ -- chain = chain,
+ }
+ sublookuplist[nofsublookups] = l
+ sublookuphash[lookupid] = nofsublookups
+ sublookupcheck[lookupid] = 0
+ lookup.done = l
+ end
+ else
+ report("no subtables for lookup %a",lookupid)
+ end
+ else
+ report("no handler for lookup %a with type %a",lookupid,lookuptype)
+ end
+ end
+
+ if usedlookups then
+ report("used %s lookups: % t",what,sortedkeys(usedlookups))
+ end
+
+ -- When we have a context, we have sublookups that resolve into lookups for which we need to
+ -- know the type. We split the main lookuptable in two parts: sequences (the main lookups)
+ -- and subtable lookups (simple specs with no features). We could keep them merged and might do
+ -- that once we only use this loader. Then we can also move the simple specs into the sequence.
+ -- After all, we pack afterwards.
+
+ local reported = { }
+
+ local function report_issue(i,what,sequence,kind)
+ local name = sequence.name
+ if not reported[name] then
+ report("rule %i in %s lookup %a has %s lookups",i,what,name,kind)
+ reported[name] = true
+ end
+ end
+
+ for i=lastsequence+1,nofsequences do
+ local sequence = sequences[i]
+ local steps = sequence.steps
+ for i=1,#steps do
+ local step = steps[i]
+ local rules = step.rules
+ if rules then
+ for i=1,#rules do
+ local rule = rules[i]
+ local rlookups = rule.lookups
+ if not rlookups then
+ report_issue(i,what,sequence,"no")
+ elseif not next(rlookups) then
+ -- can be ok as it aborts a chain sequence
+ -- report_issue(i,what,sequence,"empty")
+ rule.lookups = nil
+ else
+ -- 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 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)
+ local l = {
+ 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(l) -- 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
+ sublookupcheck[lookupid] = sublookupcheck[lookupid] + 1
+ end
+ if h then
+ noffound = noffound + 1
+ found[noffound] = h
+ end
+ end
+ end
+ rlookups[index] = noffound > 0 and found or false
+ else
+ rlookups[index] = false
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ for i, n in sortedhash(sublookupcheck) do
+ local l = lookups[i]
+ local t = l.type
+ if n == 0 and t ~= "extension" then
+ local d = l.done
+ report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t)
+ end
+ end
+
+ end
+
+ local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
+ setposition(f,variationsoffset)
+ local version = readulong(f) -- two times readushort
+ local nofrecords = readulong(f)
+ local records = { }
+ for i=1,nofrecords do
+ records[i] = {
+ conditions = readulong(f),
+ substitutions = readulong(f),
+ }
+ end
+ for i=1,nofrecords do
+ local record = records[i]
+ local offset = record.conditions
+ if offset == 0 then
+ record.condition = nil
+ record.matchtype = "always"
+ else
+ local offset = variationsoffset+offset
+ setposition(f,offset)
+ local nofconditions = readushort(f)
+ local conditions = { }
+ for i=1,nofconditions do
+ conditions[i] = offset + readulong(f)
+ end
+ record.conditions = conditions
+ record.matchtype = "condition"
+ end
+ end
+ for i=1,nofrecords do
+ local record = records[i]
+ if record.matchtype == "condition" then
+ local conditions = record.conditions
+ for i=1,#conditions do
+ setposition(f,conditions[i])
+ conditions[i] = {
+ format = readushort(f),
+ axis = readushort(f),
+ minvalue = read2dot14(f),
+ maxvalue = read2dot14(f),
+ }
+ end
+ end
+ end
+
+ for i=1,nofrecords do
+ local record = records[i]
+ local offset = record.substitutions
+ if offset == 0 then
+ record.substitutions = { }
+ else
+ setposition(f,variationsoffset + offset)
+ local version = readulong(f)
+ local nofsubstitutions = readushort(f)
+ local substitutions = { }
+ for i=1,nofsubstitutions do
+ substitutions[readushort(f)] = readulong(f)
+ end
+ for index, alternates in sortedhash(substitutions) do
+ if index == 0 then
+ record.substitutions = false
+ else
+ local tableoffset = variationsoffset + offset + alternates
+ setposition(f,tableoffset)
+ local parameters = readulong(f) -- feature parameters
+ local noflookups = readushort(f)
+ local lookups = readcardinaltable(f,noflookups,ushort) -- not sure what to do with these
+ -- todo : resolve to proper lookups
+ record.substitutions = lookups
+ end
+ end
+ end
+ end
+ setvariabledata(fontdata,"features",records)
+ end
+
+ local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo)
+ local tableoffset = gotodatatable(f,fontdata,what,true)
+ if tableoffset then
+ local version = readulong(f)
+ local scriptoffset = tableoffset + readushort(f)
+ local featureoffset = tableoffset + readushort(f)
+ local lookupoffset = tableoffset + readushort(f)
+ local variationsoffset = version > 0x00010000 and (tableoffset + readulong(f)) or 0
+ if not scriptoffset then
+ return
+ end
+ local scripts = readscriplan(f,fontdata,scriptoffset)
+ local features = readfeatures(f,fontdata,featureoffset)
+ --
+ local scriptlangs, featurehash, featureorder = reorderfeatures(fontdata,scripts,features)
+ --
+ if fontdata.features then
+ fontdata.features[what] = scriptlangs
+ else
+ fontdata.features = { [what] = scriptlangs }
+ end
+ --
+ if not lookupstoo then
+ return
+ end
+ --
+ local lookups = readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder)
+ --
+ if lookups then
+ resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset)
+ end
+ --
+ if variationsoffset > 0 then
+ loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
+ end
+ end
+ end
+
+ local function checkkerns(f,fontdata,specification)
+ local datatable = fontdata.tables.kern
+ if not datatable then
+ return -- no kerns
+ end
+ local features = fontdata.features
+ local gposfeatures = features and features.gpos
+ local name
+ if not gposfeatures or not gposfeatures.kern then
+ name = "kern"
+ elseif specification.globalkerns then
+ name = "globalkern"
+ else
+ report("ignoring global kern table, using gpos kern feature")
+ return
+ end
+ setposition(f,datatable.offset)
+ local version = readushort(f)
+ local noftables = readushort(f)
+ if noftables > 1 then
+ report("adding global kern table as gpos feature %a",name)
+ local kerns = setmetatableindex("table")
+ for i=1,noftables do
+ local version = readushort(f)
+ local length = readushort(f)
+ local coverage = readushort(f)
+ -- bit 8-15 of coverage: format 0 or 2
+ local format = rshift(coverage,8) -- is this ok
+ if format == 0 then
+ local nofpairs = readushort(f)
+ local searchrange = readushort(f)
+ local entryselector = readushort(f)
+ local rangeshift = readushort(f)
+ for i=1,nofpairs do
+ kerns[readushort(f)][readushort(f)] = readfword(f)
+ end
+ elseif format == 2 then
+ -- apple specific so let's ignore it
+ else
+ -- not supported by ms
+ end
+ end
+ local feature = { dflt = { dflt = true } }
+ if not features then
+ fontdata.features = { gpos = { [name] = feature } }
+ elseif not gposfeatures then
+ fontdata.features.gpos = { [name] = feature }
+ else
+ gposfeatures[name] = feature
+ end
+ local sequences = fontdata.sequences
+ if not sequences then
+ sequences = { }
+ fontdata.sequences = sequences
+ end
+ local nofsequences = #sequences + 1
+ sequences[nofsequences] = {
+ index = nofsequences,
+ name = name,
+ steps = {
+ {
+ coverage = kerns,
+ format = "kern",
+ },
+ },
+ nofsteps = 1,
+ type = "gpos_pair",
+ flags = { false, false, false, false },
+ order = { name },
+ features = { [name] = feature },
+ }
+ else
+ report("ignoring empty kern table of feature %a",name)
+ end
+ end
+
+ function readers.gsub(f,fontdata,specification)
+ if specification.details then
+ readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups)
+ end
+ end
+
+ function readers.gpos(f,fontdata,specification)
+ if specification.details then
+ readscripts(f,fontdata,"gpos",gpostypes,gposhandlers,specification.lookups)
+ if specification.lookups then
+ checkkerns(f,fontdata,specification)
+ end
+ end
+ end
+
+end
+
+function readers.gdef(f,fontdata,specification)
+ if not specification.glyphs then
+ return
+ end
+ local datatable = fontdata.tables.gdef
+ if datatable then
+ local tableoffset = datatable.offset
+ setposition(f,tableoffset)
+ local version = readulong(f)
+ local classoffset = readushort(f)
+ local attachmentoffset = readushort(f) -- used for bitmaps
+ local ligaturecarets = readushort(f) -- used in editors (maybe nice for tracing)
+ local markclassoffset = readushort(f)
+ local marksetsoffset = version >= 0x00010002 and readushort(f) or 0
+ local varsetsoffset = version >= 0x00010003 and readulong(f) or 0
+ local glyphs = fontdata.glyphs
+ local marks = { }
+ local markclasses = setmetatableindex("table")
+ local marksets = setmetatableindex("table")
+ fontdata.marks = marks
+ fontdata.markclasses = markclasses
+ fontdata.marksets = marksets
+ -- class definitions
+ if classoffset ~= 0 then
+ setposition(f,tableoffset + classoffset)
+ local classformat = readushort(f)
+ if classformat == 1 then
+ local firstindex = readushort(f)
+ local lastindex = firstindex + readushort(f) - 1
+ for index=firstindex,lastindex do
+ local class = classes[readushort(f)]
+ if class == "mark" then
+ marks[index] = true
+ end
+ glyphs[index].class = class
+ end
+ elseif classformat == 2 then
+ local nofranges = readushort(f)
+ for i=1,nofranges do
+ local firstindex = readushort(f)
+ local lastindex = readushort(f)
+ local class = classes[readushort(f)]
+ if class then
+ for index=firstindex,lastindex do
+ glyphs[index].class = class
+ if class == "mark" then
+ marks[index] = true
+ end
+ end
+ end
+ end
+ end
+ end
+ -- mark classes
+ if markclassoffset ~= 0 then
+ setposition(f,tableoffset + markclassoffset)
+ local classformat = readushort(f)
+ if classformat == 1 then
+ local firstindex = readushort(f)
+ local lastindex = firstindex + readushort(f) - 1
+ for index=firstindex,lastindex do
+ markclasses[readushort(f)][index] = true
+ end
+ elseif classformat == 2 then
+ local nofranges = readushort(f)
+ for i=1,nofranges do
+ local firstindex = readushort(f)
+ local lastindex = readushort(f)
+ local class = markclasses[readushort(f)]
+ for index=firstindex,lastindex do
+ class[index] = true
+ end
+ end
+ end
+ end
+ -- mark sets : todo: just make the same as class sets above
+ if marksetsoffset ~= 0 then
+ marksetsoffset = tableoffset + marksetsoffset
+ setposition(f,marksetsoffset)
+ local format = readushort(f)
+ if format == 1 then
+ local nofsets = readushort(f)
+ local sets = readcardinaltable(f,nofsets,ulong)
+ for i=1,nofsets do
+ local offset = sets[i]
+ if offset ~= 0 then
+ marksets[i] = readcoverage(f,marksetsoffset+offset)
+ end
+ end
+ end
+ end
+
+ local factors = specification.factors
+
+ if (specification.variable or factors) and varsetsoffset ~= 0 then
+
+ local regions, deltas = readvariationdata(f,tableoffset+varsetsoffset,factors)
+
+ -- setvariabledata(fontdata,"gregions",regions)
+
+ if factors then
+ fontdata.temporary.getdelta = function(outer,inner)
+ local delta = deltas[outer+1]
+ if delta then
+ local d = delta.deltas[inner+1]
+ if d then
+ local scales = delta.scales
+ local dd = 0
+ for i=1,#scales do
+ local di = d[i]
+ if di then
+ dd = dd + scales[i] * di
+ else
+ break
+ end
+ end
+ return round(dd)
+ end
+ end
+ return 0
+ end
+ end
+
+ end
+ end
+end
+
+-- We keep this code here instead of font-otm.lua because we need coverage
+-- helpers. Okay, these helpers could go to the main reader file some day.
+
+local function readmathvalue(f)
+ local v = readshort(f)
+ skipshort(f,1) -- offset to device table
+ return v
+end
+
+local function readmathconstants(f,fontdata,offset)
+ setposition(f,offset)
+ fontdata.mathconstants = {
+ ScriptPercentScaleDown = readshort(f),
+ ScriptScriptPercentScaleDown = readshort(f),
+ DelimitedSubFormulaMinHeight = readushort(f),
+ DisplayOperatorMinHeight = readushort(f),
+ MathLeading = readmathvalue(f),
+ AxisHeight = readmathvalue(f),
+ AccentBaseHeight = readmathvalue(f),
+ FlattenedAccentBaseHeight = readmathvalue(f),
+ SubscriptShiftDown = readmathvalue(f),
+ SubscriptTopMax = readmathvalue(f),
+ SubscriptBaselineDropMin = readmathvalue(f),
+ SuperscriptShiftUp = readmathvalue(f),
+ SuperscriptShiftUpCramped = readmathvalue(f),
+ SuperscriptBottomMin = readmathvalue(f),
+ SuperscriptBaselineDropMax = readmathvalue(f),
+ SubSuperscriptGapMin = readmathvalue(f),
+ SuperscriptBottomMaxWithSubscript = readmathvalue(f),
+ SpaceAfterScript = readmathvalue(f),
+ UpperLimitGapMin = readmathvalue(f),
+ UpperLimitBaselineRiseMin = readmathvalue(f),
+ LowerLimitGapMin = readmathvalue(f),
+ LowerLimitBaselineDropMin = readmathvalue(f),
+ StackTopShiftUp = readmathvalue(f),
+ StackTopDisplayStyleShiftUp = readmathvalue(f),
+ StackBottomShiftDown = readmathvalue(f),
+ StackBottomDisplayStyleShiftDown = readmathvalue(f),
+ StackGapMin = readmathvalue(f),
+ StackDisplayStyleGapMin = readmathvalue(f),
+ StretchStackTopShiftUp = readmathvalue(f),
+ StretchStackBottomShiftDown = readmathvalue(f),
+ StretchStackGapAboveMin = readmathvalue(f),
+ StretchStackGapBelowMin = readmathvalue(f),
+ FractionNumeratorShiftUp = readmathvalue(f),
+ FractionNumeratorDisplayStyleShiftUp = readmathvalue(f),
+ FractionDenominatorShiftDown = readmathvalue(f),
+ FractionDenominatorDisplayStyleShiftDown = readmathvalue(f),
+ FractionNumeratorGapMin = readmathvalue(f),
+ FractionNumeratorDisplayStyleGapMin = readmathvalue(f),
+ FractionRuleThickness = readmathvalue(f),
+ FractionDenominatorGapMin = readmathvalue(f),
+ FractionDenominatorDisplayStyleGapMin = readmathvalue(f),
+ SkewedFractionHorizontalGap = readmathvalue(f),
+ SkewedFractionVerticalGap = readmathvalue(f),
+ OverbarVerticalGap = readmathvalue(f),
+ OverbarRuleThickness = readmathvalue(f),
+ OverbarExtraAscender = readmathvalue(f),
+ UnderbarVerticalGap = readmathvalue(f),
+ UnderbarRuleThickness = readmathvalue(f),
+ UnderbarExtraDescender = readmathvalue(f),
+ RadicalVerticalGap = readmathvalue(f),
+ RadicalDisplayStyleVerticalGap = readmathvalue(f),
+ RadicalRuleThickness = readmathvalue(f),
+ RadicalExtraAscender = readmathvalue(f),
+ RadicalKernBeforeDegree = readmathvalue(f),
+ RadicalKernAfterDegree = readmathvalue(f),
+ RadicalDegreeBottomRaisePercent = readshort(f),
+ }
+end
+
+local function readmathglyphinfo(f,fontdata,offset)
+ setposition(f,offset)
+ local italics = readushort(f)
+ local accents = readushort(f)
+ local extensions = readushort(f)
+ local kerns = readushort(f)
+ local glyphs = fontdata.glyphs
+ if italics ~= 0 then
+ setposition(f,offset+italics)
+ local coverage = readushort(f)
+ local nofglyphs = readushort(f)
+ coverage = readcoverage(f,offset+italics+coverage,true)
+ setposition(f,offset+italics+4)
+ for i=1,nofglyphs do
+ local italic = readmathvalue(f)
+ if italic ~= 0 then
+ local glyph = glyphs[coverage[i]]
+ local math = glyph.math
+ if not math then
+ glyph.math = { italic = italic }
+ else
+ math.italic = italic
+ end
+ end
+ end
+ fontdata.hasitalics = true
+ end
+ if accents ~= 0 then
+ setposition(f,offset+accents)
+ local coverage = readushort(f)
+ local nofglyphs = readushort(f)
+ coverage = readcoverage(f,offset+accents+coverage,true)
+ setposition(f,offset+accents+4)
+ for i=1,nofglyphs do
+ local accent = readmathvalue(f)
+ if accent ~= 0 then
+ local glyph = glyphs[coverage[i]]
+ local math = glyph.math
+ if not math then
+ glyph.math = { accent = accent }
+ else
+ math.accent = accent
+ end
+ end
+ end
+ end
+ if extensions ~= 0 then
+ setposition(f,offset+extensions)
+ end
+ if kerns ~= 0 then
+ local kernoffset = offset + kerns
+ setposition(f,kernoffset)
+ local coverage = readushort(f)
+ local nofglyphs = readushort(f)
+ if nofglyphs > 0 then
+ local function get(offset)
+ setposition(f,kernoffset+offset)
+ local n = readushort(f)
+ if n == 0 then
+ local k = readmathvalue(f)
+ if k == 0 then
+ -- no need for it (happens sometimes)
+ else
+ return { { kern = k } }
+ end
+ else
+ local l = { }
+ for i=1,n do
+ l[i] = { height = readmathvalue(f) }
+ end
+ for i=1,n do
+ l[i].kern = readmathvalue(f)
+ end
+ l[n+1] = { kern = readmathvalue(f) }
+ return l
+ end
+ end
+ local kernsets = { }
+ for i=1,nofglyphs do
+ local topright = readushort(f)
+ local topleft = readushort(f)
+ local bottomright = readushort(f)
+ local bottomleft = readushort(f)
+ kernsets[i] = {
+ topright = topright ~= 0 and topright or nil,
+ topleft = topleft ~= 0 and topleft or nil,
+ bottomright = bottomright ~= 0 and bottomright or nil,
+ bottomleft = bottomleft ~= 0 and bottomleft or nil,
+ }
+ end
+ coverage = readcoverage(f,kernoffset+coverage,true)
+ for i=1,nofglyphs do
+ local kernset = kernsets[i]
+ if next(kernset) then
+ local k = kernset.topright if k then kernset.topright = get(k) end
+ local k = kernset.topleft if k then kernset.topleft = get(k) end
+ local k = kernset.bottomright if k then kernset.bottomright = get(k) end
+ local k = kernset.bottomleft if k then kernset.bottomleft = get(k) end
+ if next(kernset) then
+ local glyph = glyphs[coverage[i]]
+ local math = glyph.math
+ if math then
+ math.kerns = kernset
+ else
+ glyph.math = { kerns = kernset }
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+local function readmathvariants(f,fontdata,offset)
+ setposition(f,offset)
+ local glyphs = fontdata.glyphs
+ local minoverlap = readushort(f)
+ local vcoverage = readushort(f)
+ local hcoverage = readushort(f)
+ local vnofglyphs = readushort(f)
+ local hnofglyphs = readushort(f)
+ local vconstruction = readcardinaltable(f,vnofglyphs,ushort)
+ local hconstruction = readcardinaltable(f,hnofglyphs,ushort)
+
+ fontdata.mathconstants.MinConnectorOverlap = minoverlap
+
+ -- variants[i] = {
+ -- glyph = readushort(f),
+ -- advance = readushort(f),
+ -- }
+
+ local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic)
+ if coverage ~= 0 and nofglyphs > 0 then
+ local coverage = readcoverage(f,offset+coverage,true)
+ for i=1,nofglyphs do
+ local c = construction[i]
+ if c ~= 0 then
+ local index = coverage[i]
+ local glyph = glyphs[index]
+ local math = glyph.math
+ setposition(f,offset+c)
+ local assembly = readushort(f)
+ local nofvariants = readushort(f)
+ if nofvariants > 0 then
+ local variants, v = nil, 0
+ for i=1,nofvariants do
+ local variant = readushort(f)
+ if variant == index then
+ -- ignore
+ elseif variants then
+ v = v + 1
+ variants[v] = variant
+ else
+ v = 1
+ variants = { variant }
+ end
+ skipshort(f)
+ end
+ if not variants then
+ -- only self
+ elseif not math then
+ math = { [kvariants] = variants }
+ glyph.math = math
+ else
+ math[kvariants] = variants
+ end
+ end
+ if assembly ~= 0 then
+ setposition(f,offset + c + assembly)
+ local italic = readmathvalue(f)
+ local nofparts = readushort(f)
+ local parts = { }
+ for i=1,nofparts do
+ local p = {
+ glyph = readushort(f),
+ start = readushort(f),
+ ["end"] = readushort(f),
+ advance = readushort(f),
+ }
+ local flags = readushort(f)
+ if band(flags,0x0001) ~= 0 then
+ p.extender = 1 -- true
+ end
+ parts[i] = p
+ end
+ if not math then
+ math = {
+ [kparts] = parts
+ }
+ glyph.math = math
+ else
+ math[kparts] = parts
+ end
+ if italic and italic ~= 0 then
+ math[kitalic] = italic
+ end
+ end
+ end
+ end
+ end
+ end
+
+ get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic")
+ get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic")
+end
+
+function readers.math(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"math",specification.glyphs)
+ if tableoffset then
+ local version = readulong(f)
+ -- if version ~= 0x00010000 then
+ -- report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"math",fontdata.filename)
+ -- return
+ -- end
+ local constants = readushort(f)
+ local glyphinfo = readushort(f)
+ local variants = readushort(f)
+ if constants == 0 then
+ report("the math table of %a has no constants",fontdata.filename)
+ else
+ readmathconstants(f,fontdata,tableoffset+constants)
+ end
+ if glyphinfo ~= 0 then
+ readmathglyphinfo(f,fontdata,tableoffset+glyphinfo)
+ end
+ if variants ~= 0 then
+ readmathvariants(f,fontdata,tableoffset+variants)
+ end
+ end
+end
+
+function readers.colr(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"colr",specification.glyphs)
+ if tableoffset then
+ local version = readushort(f)
+ if version ~= 0 then
+ report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename)
+ return
+ end
+ if not fontdata.tables.cpal then
+ report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal")
+ fontdata.colorpalettes = { }
+ end
+ local glyphs = fontdata.glyphs
+ local nofglyphs = readushort(f)
+ local baseoffset = readulong(f)
+ local layeroffset = readulong(f)
+ local noflayers = readushort(f)
+ local layerrecords = { }
+ local maxclass = 0
+ -- The special value 0xFFFF is foreground (but we index from 1). It
+ -- more looks like indices into a palette so 'class' is a better name
+ -- than 'palette'.
+ setposition(f,tableoffset + layeroffset)
+ for i=1,noflayers do
+ local slot = readushort(f)
+ local class = readushort(f)
+ if class < 0xFFFF then
+ class = class + 1
+ if class > maxclass then
+ maxclass = class
+ end
+ end
+ layerrecords[i] = {
+ slot = slot,
+ class = class,
+ }
+ end
+ fontdata.maxcolorclass = maxclass
+ setposition(f,tableoffset + baseoffset)
+ for i=0,nofglyphs-1 do
+ local glyphindex = readushort(f)
+ local firstlayer = readushort(f)
+ local noflayers = readushort(f)
+ local t = { }
+ for i=1,noflayers do
+ t[i] = layerrecords[firstlayer+i]
+ end
+ glyphs[glyphindex].colors = t
+ end
+ end
+ fontdata.hascolor = true
+end
+
+function readers.cpal(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"cpal",specification.glyphs)
+ if tableoffset then
+ local version = readushort(f)
+ -- if version > 1 then
+ -- report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"cpal",fontdata.filename)
+ -- return
+ -- end
+ local nofpaletteentries = readushort(f)
+ local nofpalettes = readushort(f)
+ local nofcolorrecords = readushort(f)
+ local firstcoloroffset = readulong(f)
+ local colorrecords = { }
+ local palettes = readcardinaltable(f,nofpalettes,ushort)
+ if version == 1 then
+ -- used for guis
+ local palettettypesoffset = readulong(f)
+ local palettelabelsoffset = readulong(f)
+ local paletteentryoffset = readulong(f)
+ end
+ setposition(f,tableoffset+firstcoloroffset)
+ for i=1,nofcolorrecords do
+ local b, g, r, a = readbytes(f,4)
+ colorrecords[i] = {
+ r, g, b, a ~= 255 and a or nil,
+ }
+ end
+ for i=1,nofpalettes do
+ local p = { }
+ local o = palettes[i]
+ for j=1,nofpaletteentries do
+ p[j] = colorrecords[o+j]
+ end
+ palettes[i] = p
+ end
+ fontdata.colorpalettes = palettes
+ end
+end
+
+function readers.svg(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"svg",specification.glyphs)
+ if tableoffset then
+ local version = readushort(f)
+ -- if version ~= 0 then
+ -- report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"svg",fontdata.filename)
+ -- return
+ -- end
+ local glyphs = fontdata.glyphs
+ local indexoffset = tableoffset + readulong(f)
+ local reserved = readulong(f)
+ setposition(f,indexoffset)
+ local nofentries = readushort(f)
+ local entries = { }
+ for i=1,nofentries do
+ entries[i] = {
+ first = readushort(f),
+ last = readushort(f),
+ offset = indexoffset + readulong(f),
+ length = readulong(f),
+ }
+ end
+ for i=1,nofentries do
+ local entry = entries[i]
+ setposition(f,entry.offset)
+ entries[i] = {
+ first = entry.first,
+ last = entry.last,
+ data = readstring(f,entry.length)
+ }
+ end
+ fontdata.svgshapes = entries
+ end
+ fontdata.hascolor = true
+end
+
+function readers.sbix(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"sbix",specification.glyphs)
+ if tableoffset then
+ local version = readushort(f)
+ local flags = readushort(f)
+ local nofstrikes = readulong(f)
+ local strikes = { }
+ local nofglyphs = fontdata.nofglyphs
+ for i=1,nofstrikes do
+ strikes[i] = readulong(f)
+ end
+ local shapes = { }
+ local done = 0
+ for i=1,nofstrikes do
+ local strikeoffset = strikes[i] + tableoffset
+ setposition(f,strikeoffset)
+ strikes[i] = {
+ ppem = readushort(f),
+ ppi = readushort(f),
+ offset = strikeoffset
+ }
+ end
+ -- highest first
+ sort(strikes,function(a,b)
+ if b.ppem == a.ppem then
+ return b.ppi < a.ppi
+ else
+ return b.ppem < a.ppem
+ end
+ end)
+ local glyphs = { }
+ for i=1,nofstrikes do
+ local strike = strikes[i]
+ local strikeppem = strike.ppem
+ local strikeppi = strike.ppi
+ local strikeoffset = strike.offset
+ setposition(f,strikeoffset)
+ for i=0,nofglyphs do
+ glyphs[i] = readulong(f)
+ end
+ local glyphoffset = glyphs[0]
+ for i=0,nofglyphs-1 do
+ local nextoffset = glyphs[i+1]
+ if not shapes[i] then
+ local datasize = nextoffset - glyphoffset
+ if datasize > 0 then
+ setposition(f,strikeoffset + glyphoffset)
+ shapes[i] = {
+ x = readshort(f),
+ y = readshort(f),
+ tag = readtag(f), -- maybe for tracing
+ data = readstring(f,datasize-8),
+ ppem = strikeppem, -- not used, for tracing
+ ppi = strikeppi, -- not used, for tracing
+ }
+ done = done + 1
+ if done == nofglyphs then
+ break
+ end
+ end
+ end
+ glyphoffset = nextoffset
+ end
+ end
+ fontdata.pngshapes = shapes
+ end
+end
+
+-- Another bitmap (so not that useful) format. But Luigi found a font that
+-- has them , so ...
+
+do
+
+ local function getmetrics(f)
+ return {
+ ascender = readinteger(f),
+ descender = readinteger(f),
+ widthmax = readuinteger(f),
+ caretslopedumerator = readinteger(f),
+ caretslopedenominator = readinteger(f),
+ caretoffset = readinteger(f),
+ minorigin = readinteger(f),
+ minadvance = readinteger(f),
+ maxbefore = readinteger(f),
+ minafter = readinteger(f),
+ pad1 = readinteger(f),
+ pad2 = readinteger(f),
+ }
+ end
+
+ -- bad names
+
+ local function getbigmetrics(f)
+ -- bigmetrics, maybe just skip 9 bytes
+ return {
+ height = readuinteger(f),
+ width = readuinteger(f),
+ horiBearingX = readinteger(f),
+ horiBearingY = readinteger(f),
+ horiAdvance = readuinteger(f),
+ vertBearingX = readinteger(f),
+ vertBearingY = readinteger(f),
+ vertAdvance = readuinteger(f),
+ }
+ end
+
+ local function getsmallmetrics(f)
+ -- smallmetrics, maybe just skip 5 bytes
+ return {
+ height = readuinteger(f),
+ width = readuinteger(f),
+ bearingX = readinteger(f),
+ bearingY = readinteger(f),
+ advance = readuinteger(f),
+ }
+ end
+
+ function readers.cblc(f,fontdata,specification)
+ -- should we delay this ?
+ local ctdttableoffset = gotodatatable(f,fontdata,"cbdt",specification.glyphs)
+ if not ctdttableoffset then
+ return
+ end
+ local cblctableoffset = gotodatatable(f,fontdata,"cblc",specification.glyphs)
+ if cblctableoffset then
+ local majorversion = readushort(f)
+ local minorversion = readushort(f)
+ local nofsizetables = readulong(f)
+ local sizetables = { }
+ local shapes = { }
+ local subtables = { }
+ for i=1,nofsizetables do
+ sizetables[i] = {
+ subtables = readulong(f),
+ indexsize = readulong(f),
+ nofsubtables = readulong(f),
+ colorref = readulong(f),
+ hormetrics = getmetrics(f),
+ vermetrics = getmetrics(f),
+ firstindex = readushort(f),
+ lastindex = readushort(f),
+ ppemx = readbyte(f),
+ ppemy = readbyte(f),
+ bitdepth = readbyte(f),
+ flags = readbyte(f),
+ }
+ end
+ sort(sizetables,function(a,b)
+ if b.ppemx == a.ppemx then
+ return b.bitdepth < a.bitdepth
+ else
+ return b.ppemx < a.ppemx
+ end
+ end)
+ for i=1,nofsizetables do
+ local s = sizetables[i]
+ local d = false
+ for j=s.firstindex,s.lastindex do
+ if not shapes[j] then
+ shapes[j] = i
+ d = true
+ end
+ end
+ if d then
+ s.used = true
+ end
+ end
+ for i=1,nofsizetables do
+ local s = sizetables[i]
+ if s.used then
+ local offset = s.subtables
+ setposition(f,cblctableoffset+offset)
+ for j=1,s.nofsubtables do
+ local firstindex = readushort(f)
+ local lastindex = readushort(f)
+ local tableoffset = readulong(f) + offset
+ for k=firstindex,lastindex do
+ if shapes[k] == i then
+ local s = subtables[tableoffset]
+ if not s then
+ s = {
+ firstindex = firstindex,
+ lastindex = lastindex,
+ }
+ subtables[tableoffset] = s
+ end
+ shapes[k] = s
+ end
+ end
+ end
+ end
+ end
+
+ -- there is no need to sort in string stream but we have a nicer trace
+ -- if needed
+
+ for offset, subtable in sortedhash(subtables) do
+ local tabletype = readushort(f)
+ subtable.format = readushort(f)
+ local baseoffset = readulong(f) + ctdttableoffset
+ local offsets = { }
+ local metrics = nil
+ if tabletype == 1 then
+ -- we have the usual one more to get the size
+ for i=subtable.firstindex,subtable.lastindex do
+ offsets[i] = readulong(f) + baseoffset
+ end
+ skipbytes(f,4)
+ elseif tabletype == 2 then
+ local size = readulong(f)
+ local done = baseoffset
+ metrics = getbigmetrics(f)
+ for i=subtable.firstindex,subtable.lastindex do
+ offsets[i] = done
+ done = done + size
+ end
+ elseif tabletype == 3 then
+ -- we have the usual one more to get the size
+ local n = subtable.lastindex - subtable.firstindex + 2
+ for i=subtable.firstindex,subtable.lastindex do
+ offsets[i] = readushort(f) + baseoffset
+ end
+ if math.odd(n) then
+ skipbytes(f,4)
+ else
+ skipbytes(f,2)
+ end
+ elseif tabletype == 4 then
+ for i=1,readulong(f) do
+ offsets[readushort(f)] = readushort(f) + baseoffset
+ end
+ elseif tabletype == 5 then
+ local size = readulong(f)
+ local done = baseoffset
+ metrics = getbigmetrics(f)
+ local n = readulong(f)
+ for i=1,n do
+ offsets[readushort(f)] = done
+ done = done + size
+ end
+ if math.odd(n) then
+ skipbytes(f,2)
+ end
+ else
+ return -- unsupported format
+ end
+ subtable.offsets = offsets
+ subtable.metrics = metrics
+ end
+
+ -- we only support a few sensible types ... there are hardly any fonts so
+ -- why are there so many variants ... not the best spec
+
+ local default = { width = 0, height = 0 }
+ local glyphs = fontdata.glyphs
+
+ for index, subtable in sortedhash(shapes) do
+ if type(subtable) == "table" then
+ local data = nil
+ local metrics = default
+ local format = subtable.format
+ local offset = subtable.offsets[index]
+ setposition(f,offset)
+ if format == 17 then
+ metrics = getsmallmetrics(f)
+ data = readstring(f,readulong(f))
+ elseif format == 18 then
+ metrics = getbigmetrics(f)
+ data = readstring(f,readulong(f))
+ elseif format == 19 then
+ metrics = subtable.metrics
+ data = readstring(f,readulong(f))
+ else
+ -- forget about it
+ end
+ local x = metrics.width
+ local y = metrics.height
+ shapes[index] = {
+ -- maybe some metrics
+ x = x,
+ y = y,
+ data = data,
+ }
+ -- I'll look into this in more details when needed
+ -- as we can use the bearings to get better boxes.
+ local glyph = glyphs[index]
+ if not glyph.boundingbox then
+ local width = glyph.width
+ local height = width * y/x
+ glyph.boundingbox = { 0, 0, width, height }
+ end
+
+ else
+ shapes[index] = {
+ x = 0,
+ y = 0,
+ data = "",
+ }
+ end
+ end
+
+ fontdata.pngshapes = shapes -- we cheat
+ end
+ end
+
+ function readers.cbdt(f,fontdata,specification)
+ -- local tableoffset = gotodatatable(f,fontdata,"ctdt",specification.glyphs)
+ -- if tableoffset then
+ -- local majorversion = readushort(f)
+ -- local minorversion = readushort(f)
+ -- end
+ end
+
+ -- function readers.ebdt(f,fontdata,specification)
+ -- if specification.glyphs then
+ -- end
+ -- end
+
+ -- function readers.ebsc(f,fontdata,specification)
+ -- if specification.glyphs then
+ -- end
+ -- end
+
+ -- function readers.eblc(f,fontdata,specification)
+ -- if specification.glyphs then
+ -- end
+ -- end
+
+end
+
+-- + AVAR : optional
+-- + CFF2 : otf outlines
+-- - CVAR : ttf hinting, not needed
+-- + FVAR : the variations
+-- + GVAR : ttf outline changes
+-- + HVAR : horizontal changes
+-- + MVAR : metric changes
+-- + STAT : relations within fonts
+-- * VVAR : vertical changes
+--
+-- * BASE : extra baseline adjustments
+-- - GASP : not needed
+-- + GDEF : not needed (carets)
+-- + GPOS : adapted device tables (needed?)
+-- + GSUB : new table
+-- + NAME : 25 added
+
+function readers.stat(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"stat",true) -- specification.variable
+ if tableoffset then
+ local extras = fontdata.extras
+ local version = readulong(f) -- 0x00010000
+ local axissize = readushort(f)
+ local nofaxis = readushort(f)
+ local axisoffset = readulong(f)
+ local nofvalues = readushort(f)
+ local valuesoffset = readulong(f)
+ local fallbackname = extras[readushort(f)] -- beta fonts mess up
+ local axis = { }
+ local values = { }
+ setposition(f,tableoffset+axisoffset)
+ for i=1,nofaxis do
+ local tag = readtag(f)
+ axis[i] = {
+ tag = tag,
+ name = lower(extras[readushort(f)] or tag),
+ ordering = readushort(f), -- maybe gaps
+ variants = { }
+ }
+ end
+ -- flags:
+ --
+ -- 0x0001 : OlderSiblingFontAttribute
+ -- 0x0002 : ElidableAxisValueName
+ -- 0xFFFC : reservedFlags
+ --
+ setposition(f,tableoffset+valuesoffset)
+ for i=1,nofvalues do
+ values[i] = readushort(f)
+ end
+ for i=1,nofvalues do
+ setposition(f,tableoffset + valuesoffset + values[i])
+ local format = readushort(f)
+ local index = readushort(f) + 1
+ local flags = readushort(f)
+ local name = lower(extras[readushort(f)] or "no name")
+ local value = readfixed(f)
+ local variant
+ if format == 1 then
+ variant = {
+ flags = flags,
+ name = name,
+ value = value,
+ }
+ elseif format == 2 then
+ variant = {
+ flags = flags,
+ name = name,
+ value = value,
+ minimum = readfixed(f),
+ maximum = readfixed(f),
+ }
+ elseif format == 3 then
+ variant = {
+ flags = flags,
+ name = name,
+ value = value,
+ link = readfixed(f),
+ }
+ end
+ insert(axis[index].variants,variant)
+ end
+ sort(axis,function(a,b)
+ return a.ordering < b.ordering
+ end)
+ for i=1,#axis do
+ local a = axis[i]
+ sort(a.variants,function(a,b)
+ return a.name < b.name
+ end)
+ a.ordering = nil
+ end
+ setvariabledata(fontdata,"designaxis",axis)
+ setvariabledata(fontdata,"fallbackname",fallbackname)
+ end
+end
+
+-- The avar table is optional and used in combination with fvar. Given the
+-- detailed explanation about bad values we expect the worst and do some
+-- checking.
+
+function readers.avar(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"avar",true) -- specification.variable
+ if tableoffset then
+
+ local function collect()
+ local nofvalues = readushort(f)
+ local values = { }
+ local lastfrom = false
+ local lastto = false
+ for i=1,nofvalues do
+ local from = read2dot14(f)
+ local to = read2dot14(f)
+ if lastfrom and from <= lastfrom then
+ -- ignore
+ elseif lastto and to >= lastto then
+ -- ignore
+ else
+ values[#values+1] = { from, to }
+ lastfrom, lastto = from, to
+ end
+ end
+ nofvalues = #values
+ if nofvalues > 2 then
+ local some = values[1]
+ if some[1] == -1 and some[2] == -1 then
+ some = values[nofvalues]
+ if some[1] == 1 and some[2] == 1 then
+ for i=2,nofvalues-1 do
+ some = values[i]
+ if some[1] == 0 and some[2] == 0 then
+ return values
+ end
+ end
+ end
+ end
+ end
+ return false
+ end
+
+ local version = readulong(f) -- 0x00010000
+ local reserved = readushort(f)
+ local nofaxis = readushort(f)
+ local segments = { }
+ for i=1,nofaxis do
+ segments[i] = collect()
+ end
+ setvariabledata(fontdata,"segments",segments)
+ end
+end
+
+function readers.fvar(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"fvar",true) -- specification.variable or specification.instancenames
+ if tableoffset then
+ local version = readulong(f) -- 0x00010000
+ local offsettoaxis = tableoffset + readushort(f)
+ local reserved = skipshort(f)
+ -- pair 1
+ local nofaxis = readushort(f)
+ local sizeofaxis = readushort(f)
+ -- pair 2
+ local nofinstances = readushort(f)
+ local sizeofinstances = readushort(f)
+ --
+ local extras = fontdata.extras
+ local axis = { }
+ local instances = { }
+ --
+ setposition(f,offsettoaxis)
+ --
+ for i=1,nofaxis do
+ axis[i] = {
+ tag = readtag(f), -- ital opsz slnt wdth wght
+ minimum = readfixed(f),
+ default = readfixed(f),
+ maximum = readfixed(f),
+ flags = readushort(f),
+ name = lower(extras[readushort(f)] or "bad name"),
+ }
+ local n = sizeofaxis - 20
+ if n > 0 then
+ skipbytes(f,n)
+ elseif n < 0 then
+ -- error
+ end
+ end
+ --
+ local nofbytes = 2 + 2 + 2 + nofaxis * 4
+ local readpsname = nofbytes <= sizeofinstances
+ local skippable = sizeofinstances - nofbytes
+ for i=1,nofinstances do
+ local subfamid = readushort(f)
+ local flags = readushort(f) -- 0, not used yet
+ local values = { }
+ for i=1,nofaxis do
+ values[i] = {
+ axis = axis[i].tag,
+ value = readfixed(f),
+ }
+ end
+ local psnameid = readpsname and readushort(f) or 0xFFFF
+ if subfamid == 2 or subfamid == 17 then
+ -- okay
+ elseif subfamid == 0xFFFF then
+ subfamid = nil
+ elseif subfamid <= 256 or subfamid >= 32768 then
+ subfamid = nil -- actually an error
+ end
+ if psnameid == 6 then
+ -- okay
+ elseif psnameid == 0xFFFF then
+ psnameid = nil
+ elseif psnameid <= 256 or psnameid >= 32768 then
+ psnameid = nil -- actually an error
+ end
+ instances[i] = {
+ -- flags = flags,
+ subfamily = extras[subfamid],
+ psname = psnameid and extras[psnameid] or nil,
+ values = values,
+ }
+ if skippable > 0 then
+ skipbytes(f,skippable)
+ end
+ end
+ setvariabledata(fontdata,"axis",axis)
+ setvariabledata(fontdata,"instances",instances)
+ end
+end
+
+function readers.hvar(f,fontdata,specification)
+ local factors = specification.factors
+ if not factors then
+ return
+ end
+ local tableoffset = gotodatatable(f,fontdata,"hvar",specification.variable)
+ if not tableoffset then
+ return
+ end
+
+ local version = readulong(f) -- 0x00010000
+ local variationoffset = tableoffset + readulong(f) -- the store
+ local advanceoffset = tableoffset + readulong(f)
+ local lsboffset = tableoffset + readulong(f)
+ local rsboffset = tableoffset + readulong(f)
+
+ local regions = { }
+ local variations = { }
+ local innerindex = { } -- size is mapcount
+ local outerindex = { } -- size is mapcount
+
+ if variationoffset > 0 then
+ regions, deltas = readvariationdata(f,variationoffset,factors)
+ end
+
+ if not regions then
+ -- for now .. what to do ?
+ return
+ end
+
+ if advanceoffset > 0 then
+ --
+ -- innerIndexBitCountMask = 0x000F
+ -- mapEntrySizeMask = 0x0030
+ -- reservedFlags = 0xFFC0
+ --
+ -- outerIndex = entry >> ((entryFormat & innerIndexBitCountMask) + 1)
+ -- innerIndex = entry & ((1 << ((entryFormat & innerIndexBitCountMask) + 1)) - 1)
+ --
+ setposition(f,advanceoffset)
+ local format = readushort(f) -- todo: check
+ local mapcount = readushort(f)
+ local entrysize = rshift(band(format,0x0030),4) + 1
+ local nofinnerbits = band(format,0x000F) + 1 -- n of inner bits
+ local innermask = lshift(1,nofinnerbits) - 1
+ local readcardinal = read_cardinal[entrysize] -- 1 upto 4 bytes
+ for i=0,mapcount-1 do
+ local mapdata = readcardinal(f)
+ outerindex[i] = rshift(mapdata,nofinnerbits)
+ innerindex[i] = band(mapdata,innermask)
+ end
+ -- use last entry when no match i
+ setvariabledata(fontdata,"hvarwidths",true)
+ local glyphs = fontdata.glyphs
+ for i=0,fontdata.nofglyphs-1 do
+ local glyph = glyphs[i]
+ local width = glyph.width
+ if width then
+ local outer = outerindex[i] or 0
+ local inner = innerindex[i] or i
+ if outer and inner then -- not needed
+ local delta = deltas[outer+1]
+ if delta then
+ local d = delta.deltas[inner+1]
+ if d then
+ local scales = delta.scales
+ local deltaw = 0
+ for i=1,#scales do
+ local di = d[i]
+ if di then
+ deltaw = deltaw + scales[i] * di
+ else
+ break -- can't happen
+ end
+ end
+-- report("index: %i, outer: %i, inner: %i, deltas: %|t, scales: %|t, width: %i, delta %i",
+-- i,outer,inner,d,scales,width,round(deltaw))
+ glyph.width = width + round(deltaw)
+ end
+ end
+ end
+ end
+ end
+
+ end
+
+ -- if lsboffset > 0 then
+ -- -- we don't use left side bearings
+ -- end
+
+ -- if rsboffset > 0 then
+ -- -- we don't use right side bearings
+ -- end
+
+ -- setvariabledata(fontdata,"hregions",regions)
+
+end
+
+function readers.vvar(f,fontdata,specification)
+ if not specification.variable then
+ return
+ end
+end
+
+function readers.mvar(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"mvar",specification.variable)
+ if tableoffset then
+ local version = readulong(f) -- 0x00010000
+ local reserved = skipshort(f,1)
+ local recordsize = readushort(f)
+ local nofrecords = readushort(f)
+ local offsettostore = tableoffset + readushort(f)
+ local dimensions = { }
+ local factors = specification.factors
+ if factors then
+ local regions, deltas = readvariationdata(f,offsettostore,factors)
+ for i=1,nofrecords do
+ local tag = readtag(f)
+ local var = variabletags[tag]
+ if var then
+ local outer = readushort(f)
+ local inner = readushort(f)
+ local delta = deltas[outer+1]
+ if delta then
+ local d = delta.deltas[inner+1]
+ if d then
+ local scales = delta.scales
+ local dd = 0
+ for i=1,#scales do
+ dd = dd + scales[i] * d[i]
+ end
+ var(fontdata,round(dd))
+ end
+ end
+ else
+ skipshort(f,2)
+ end
+ if recordsize > 8 then -- 4 + 2 + 2
+ skipbytes(recordsize-8)
+ end
+ end
+ end
+ -- setvariabledata(fontdata,"mregions",regions)
+ end
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua b/macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua
new file mode 100644
index 0000000000..cc6e4c0bf8
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua
@@ -0,0 +1,414 @@
+if not modules then modules = { } end modules ['font-imp-effects'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo: pickup from goodies: if type(effect) then ...
+
+local next, type, tonumber = next, type, tonumber
+local is_boolean = string.is_boolean
+
+local fonts = fonts
+
+local handlers = fonts.handlers
+local registerotffeature = handlers.otf.features.register
+local registerafmfeature = handlers.afm.features.register
+
+local settings_to_hash = utilities.parsers.settings_to_hash_colon_too
+
+local helpers = fonts.helpers
+local prependcommands = helpers.prependcommands
+local charcommand = helpers.commands.char
+local leftcommand = helpers.commands.left
+local rightcommand = helpers.commands.right
+local upcommand = helpers.commands.up
+local downcommand = helpers.commands.down
+local dummycommand = helpers.commands.dummy
+
+----- constructors = fonts.constructors
+----- getmathparameter = constructors.getmathparameter
+----- setmathparameter = constructors.setmathparameter
+
+local report_effect = logs.reporter("fonts","effect")
+local report_slant = logs.reporter("fonts","slant")
+local report_extend = logs.reporter("fonts","extend")
+local report_squeeze = logs.reporter("fonts","squeeze")
+
+local trace = false
+
+trackers.register("fonts.effect", function(v) trace = v end)
+trackers.register("fonts.slant", function(v) trace = v end)
+trackers.register("fonts.extend", function(v) trace = v end)
+trackers.register("fonts.squeeze",function(v) trace = v end)
+
+local function initializeslant(tfmdata,value)
+ value = tonumber(value)
+ if not value then
+ value = 0
+ elseif value > 1 then
+ value = 1
+ elseif value < -1 then
+ value = -1
+ end
+ if trace then
+ report_slant("applying %0.3f",value)
+ end
+ tfmdata.parameters.slantfactor = value
+end
+
+local specification = {
+ name = "slant",
+ description = "slant glyphs",
+ initializers = {
+ base = initializeslant,
+ node = initializeslant,
+ }
+}
+
+registerotffeature(specification)
+registerafmfeature(specification)
+
+local function initializeextend(tfmdata,value)
+ value = tonumber(value)
+ if not value then
+ value = 0
+ elseif value > 10 then
+ value = 10
+ elseif value < -10 then
+ value = -10
+ end
+ if trace then
+ report_extend("applying %0.3f",value)
+ end
+ tfmdata.parameters.extendfactor = value
+end
+
+local specification = {
+ name = "extend",
+ description = "scale glyphs horizontally",
+ initializers = {
+ base = initializeextend,
+ node = initializeextend,
+ }
+}
+
+registerotffeature(specification)
+registerafmfeature(specification)
+
+local function initializesqueeze(tfmdata,value)
+ value = tonumber(value)
+ if not value then
+ value = 0
+ elseif value > 10 then
+ value = 10
+ elseif value < -10 then
+ value = -10
+ end
+ if trace then
+ report_squeeze("applying %0.3f",value)
+ end
+ tfmdata.parameters.squeezefactor = value
+end
+
+local specification = {
+ name = "squeeze",
+ description = "scale glyphs vertically",
+ initializers = {
+ base = initializesqueeze,
+ node = initializesqueeze,
+ }
+}
+
+registerotffeature(specification)
+registerafmfeature(specification)
+
+local effects = {
+ inner = 0,
+ normal = 0,
+ outer = 1,
+ outline = 1,
+ both = 2,
+ hidden = 3,
+}
+
+local function initializeeffect(tfmdata,value)
+ local spec
+ if type(value) == "number" then
+ spec = { width = value }
+ else
+ spec = settings_to_hash(value)
+ end
+ local effect = spec.effect or "both"
+ local width = tonumber(spec.width) or 0
+ local mode = effects[effect]
+ if not mode then
+ report_effect("invalid effect %a",effect)
+ elseif width == 0 and mode == 0 then
+ report_effect("invalid width %a for effect %a",width,effect)
+ else
+ local parameters = tfmdata.parameters
+ local properties = tfmdata.properties
+ parameters.mode = mode
+ parameters.width = width * 1000
+ if is_boolean(spec.auto) == true then
+ local squeeze = 1 - width/20
+ local average = (1 - squeeze) * width * 100
+ spec.squeeze = squeeze
+ spec.extend = 1 + width/2
+ spec.wdelta = average
+ spec.hdelta = average/2
+ spec.ddelta = average/2
+ spec.vshift = average/2
+ end
+ local factor = tonumber(spec.factor) or 0
+ local hfactor = tonumber(spec.hfactor) or factor
+ local vfactor = tonumber(spec.vfactor) or factor
+ local delta = tonumber(spec.delta) or 1
+ local wdelta = tonumber(spec.wdelta) or delta
+ local hdelta = tonumber(spec.hdelta) or delta
+ local ddelta = tonumber(spec.ddelta) or hdelta
+ local vshift = tonumber(spec.vshift) or 0
+ local slant = spec.slant
+ local extend = spec.extend
+ local squeeze = spec.squeeze
+ if slant then
+ initializeslant(tfmdata,slant)
+ end
+ if extend then
+ initializeextend(tfmdata,extend)
+ end
+ if squeeze then
+ initializesqueeze(tfmdata,squeeze)
+ end
+ properties.effect = {
+ effect = effect,
+ width = width,
+ factor = factor,
+ hfactor = hfactor,
+ vfactor = vfactor,
+ wdelta = wdelta,
+ hdelta = hdelta,
+ ddelta = ddelta,
+ vshift = vshift,
+ slant = tfmdata.parameters.slantfactor,
+ extend = tfmdata.parameters.extendfactor,
+ squeeze = tfmdata.parameters.squeezefactor,
+ }
+ end
+end
+
+local rules = {
+ "RadicalRuleThickness",
+ "OverbarRuleThickness",
+ "FractionRuleThickness",
+ "UnderbarRuleThickness",
+}
+
+-- local commands = char.commands
+-- if commands then
+-- local command = commands[1]
+-- if command and command[1] == "right" then
+-- commands[1] = rightcommand[command[2]-snap]
+-- end
+-- end
+
+local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
+ if delta ~= 0 then
+ for i=1,#rules do
+ local name = rules[i]
+ local value = mathparameters[name]
+ if value then
+ mathparameters[name] = (squeeze or 1) * (value + dx)
+ end
+ end
+ end
+end
+
+local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
+
+ local function wdpatch(char)
+ if wsnap ~= 0 then
+ char.width = char.width + wdelta/2
+ end
+ end
+
+ local function htpatch(char)
+ if hsnap ~= 0 then
+ local height = char.height
+ if height then
+ char.height = char.height + 2 * dy
+ end
+ end
+ end
+
+ local character = characters[0x221A]
+
+ if character and character.next then
+-- print("base char",0x221A,table.sequenced(character))
+ local char = character
+ local next = character.next
+ wdpatch(char)
+ htpatch(char)
+ while next do
+ char = characters[next]
+ wdpatch(char)
+ htpatch(char)
+-- print("next char",next,table.sequenced(char))
+ next = char.next
+ end
+ if char then
+ local v = char.vert_variants
+ if v then
+ local top = v[#v]
+ if top then
+ local char = characters[top.glyph]
+-- print("top char",top.glyph,table.sequenced(char))
+ htpatch(char)
+ end
+ end
+ end
+ end
+end
+
+-- local show_effect = { "lua", function(f,c)
+-- report_effect("font id %i, char %C",f,c)
+-- inspect(fonts.hashes.characters[f][c])
+-- end }
+
+-- local show_effect = { "lua", "print('!')" }
+
+local function manipulateeffect(tfmdata)
+ local effect = tfmdata.properties.effect
+ if effect then
+ local characters = tfmdata.characters
+ local parameters = tfmdata.parameters
+ local mathparameters = tfmdata.mathparameters
+ local multiplier = effect.width * 100
+ local factor = parameters.factor
+ local hfactor = parameters.hfactor
+ local vfactor = parameters.vfactor
+ local wdelta = effect.wdelta * hfactor * multiplier
+ local hdelta = effect.hdelta * vfactor * multiplier
+ local ddelta = effect.ddelta * vfactor * multiplier
+ local vshift = effect.vshift * vfactor * multiplier
+ local squeeze = effect.squeeze
+ local hshift = wdelta / 2
+ local dx = multiplier * vfactor
+ local dy = vshift
+ local factor = (1 + effect.factor) * factor
+ local hfactor = (1 + effect.hfactor) * hfactor
+ local vfactor = (1 + effect.vfactor) * vfactor
+ local vshift = vshift ~= 0 and upcommand[vshift] or false
+ for unicode, character in next, characters do
+ local oldwidth = character.width
+ local oldheight = character.height
+ local olddepth = character.depth
+ if oldwidth and oldwidth > 0 then
+ character.width = oldwidth + wdelta
+ local commands = character.commands
+ local hshift = rightcommand[hshift]
+ if vshift then
+ if commands then
+ prependcommands ( commands,
+-- show_effect,
+ hshift,
+ vshift
+ )
+ else
+ character.commands = {
+-- show_effect,
+ hshift,
+ vshift,
+ charcommand[unicode]
+ }
+ end
+ else
+ if commands then
+ prependcommands ( commands,
+-- show_effect,
+ hshift
+ )
+ else
+ character.commands = {
+-- show_effect,
+ hshift,
+ charcommand[unicode]
+ }
+ end
+ end
+ end
+ if oldheight and oldheight > 0 then
+ character.height = oldheight + hdelta
+ end
+ if olddepth and olddepth > 0 then
+ character.depth = olddepth + ddelta
+ end
+ end
+ if mathparameters then
+ setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
+ setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
+ end
+ parameters.factor = factor
+ parameters.hfactor = hfactor
+ parameters.vfactor = vfactor
+ if trace then
+ report_effect("applying")
+ report_effect(" effect : %s", effect.effect)
+ report_effect(" width : %s => %s", effect.width, multiplier)
+ report_effect(" factor : %s => %s", effect.factor, factor )
+ report_effect(" hfactor : %s => %s", effect.hfactor,hfactor)
+ report_effect(" vfactor : %s => %s", effect.vfactor,vfactor)
+ report_effect(" wdelta : %s => %s", effect.wdelta, wdelta)
+ report_effect(" hdelta : %s => %s", effect.hdelta, hdelta)
+ report_effect(" ddelta : %s => %s", effect.ddelta, ddelta)
+ end
+ end
+end
+
+local specification = {
+ name = "effect",
+ description = "apply effects to glyphs",
+ initializers = {
+ base = initializeeffect,
+ node = initializeeffect,
+ },
+ manipulators = {
+ base = manipulateeffect,
+ node = manipulateeffect,
+ },
+}
+
+registerotffeature(specification)
+registerafmfeature(specification)
+
+local function initializeoutline(tfmdata,value)
+ value = tonumber(value)
+ if not value then
+ value = 0
+ else
+ value = tonumber(value) or 0
+ end
+ local parameters = tfmdata.parameters
+ local properties = tfmdata.properties
+ parameters.mode = effects.outline
+ parameters.width = value * 1000
+ properties.effect = {
+ effect = effect,
+ width = width,
+ }
+end
+
+local specification = {
+ name = "outline",
+ description = "outline glyphs",
+ initializers = {
+ base = initializeoutline,
+ node = initializeoutline,
+ }
+}
+
+registerotffeature(specification)
+registerafmfeature(specification)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua b/macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua
new file mode 100644
index 0000000000..83c785d387
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua
@@ -0,0 +1,147 @@
+if not modules then modules = { } end modules ['font-imp-italics'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv and hand-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local next = next
+
+local fonts = fonts
+local handlers = fonts.handlers
+local registerotffeature = handlers.otf.features.register
+local registerafmfeature = handlers.afm.features.register
+
+local function initialize(tfmdata,key,value)
+ for unicode, character in next, tfmdata.characters do
+ local olditalic = character.italic
+ if olditalic and olditalic ~= 0 then
+ character.width = character.width + olditalic
+ character.italic = 0
+ end
+ end
+end
+
+local specification = {
+ name = "italicwidths",
+ description = "add italic to width",
+ manipulators = {
+ base = initialize,
+ node = initialize, -- only makes sense for math
+ }
+}
+
+registerotffeature(specification)
+registerafmfeature(specification)
+
+local function initialize(tfmdata,value) -- hm, always value
+ if value then
+ -- the magic 40 and it formula come from Dohyun Kim but we might need another guess
+ local parameters = tfmdata.parameters
+ local italicangle = parameters.italicangle
+ if italicangle and italicangle ~= 0 then
+ local properties = tfmdata.properties
+ local factor = tonumber(value) or 1
+ properties.hasitalics = true
+ properties.autoitalicamount = factor * (parameters.uwidth or 40)/2
+ end
+ end
+end
+
+local specification = {
+ name = "itlc",
+ description = "italic correction",
+ initializers = {
+ base = initialize,
+ node = initialize,
+ }
+}
+
+registerotffeature(specification)
+registerafmfeature(specification)
+
+if context then
+
+ local function initialize(tfmdata,value) -- yes no delay
+ tfmdata.properties.textitalics = toboolean(value)
+ end
+
+ local specification = {
+ name = "textitalics",
+ description = "use alternative text italic correction",
+ initializers = {
+ base = initialize,
+ node = initialize,
+ }
+ }
+
+ registerotffeature(specification)
+ registerafmfeature(specification)
+
+end
+
+-- no longer used
+
+-- if context then
+--
+-- -- local function initializemathitalics(tfmdata,value) -- yes no delay
+-- -- tfmdata.properties.mathitalics = toboolean(value)
+-- -- end
+-- --
+-- -- local specification = {
+-- -- name = "mathitalics",
+-- -- description = "use alternative math italic correction",
+-- -- initializers = {
+-- -- base = initializemathitalics,
+-- -- node = initializemathitalics,
+-- -- }
+-- -- }
+-- --
+-- -- registerotffeature(specification)
+-- -- registerafmfeature(specification)
+--
+-- end
+
+-- -- also not used, only when testing
+
+if context then
+
+ local letter = characters.is_letter
+ local always = true
+
+ local function collapseitalics(tfmdata,key,value)
+ local threshold = value == true and 100 or tonumber(value)
+ if threshold and threshold > 0 then
+ if threshold > 100 then
+ threshold = 100
+ end
+ for unicode, data in next, tfmdata.characters do
+ if always or letter[unicode] or letter[data.unicode] then
+ local italic = data.italic
+ if italic and italic ~= 0 then
+ local width = data.width
+ if width and width ~= 0 then
+ local delta = threshold * italic / 100
+ data.width = width + delta
+ data.italic = italic - delta
+ end
+ end
+ end
+ end
+ end
+ end
+
+ local dimensions_specification = {
+ name = "collapseitalics",
+ description = "collapse italics",
+ manipulators = {
+ base = collapseitalics,
+ node = collapseitalics,
+ }
+ }
+
+ registerotffeature(dimensions_specification)
+ registerafmfeature(dimensions_specification)
+
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua b/macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua
new file mode 100644
index 0000000000..091eb5d4b4
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua
@@ -0,0 +1,136 @@
+if not modules then modules = { } end modules ['font-imp-ligatures'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local lpegmatch = lpeg.match
+local utfsplit = utf.split
+local settings_to_array = utilities.parsers.settings_to_array
+
+local fonts = fonts
+local otf = fonts.handlers.otf
+local registerotffeature = otf.features.register
+local addotffeature = otf.addfeature
+
+-- This is a quick and dirty hack.
+
+local lookups = { }
+local protect = { }
+local revert = { }
+local zwjchar = 0x200C
+local zwj = { zwjchar }
+
+addotffeature {
+ name = "blockligatures",
+ type = "chainsubstitution",
+ nocheck = true, -- because there is no 0x200C in the font
+ prepend = true, -- make sure we do it early
+ future = true, -- avoid nilling due to no steps yet
+ lookups = {
+ {
+ type = "multiple",
+ data = lookups,
+ },
+ },
+ data = {
+ rules = protect,
+ }
+}
+
+addotffeature {
+ name = "blockligatures",
+ type = "chainsubstitution",
+ nocheck = true, -- because there is no 0x200C in the font
+ append = true, -- this is done late
+ overload = false, -- we don't want to overload the previous definition
+ lookups = {
+ {
+ type = "ligature",
+ data = lookups,
+ },
+ },
+ data = {
+ rules = revert,
+ }
+}
+
+registerotffeature {
+ name = 'blockligatures',
+ description = 'block certain ligatures',
+}
+
+local splitter = lpeg.splitat(":")
+
+local function blockligatures(str)
+
+ local t = settings_to_array(str)
+
+ for i=1,#t do
+ local ti = t[i]
+ local before, current, after = lpegmatch(splitter,ti)
+ if current and after then -- before is returned when no match
+ -- experimental joke
+ if before then
+ before = utfsplit(before)
+ for i=1,#before do
+ before[i] = { before[i] }
+ end
+ end
+ if current then
+ current = utfsplit(current)
+ end
+ if after then
+ after = utfsplit(after)
+ for i=1,#after do
+ after[i] = { after[i] }
+ end
+ end
+ else
+ before = nil
+ current = utfsplit(ti)
+ after = nil
+ end
+ if #current > 1 then
+ local one = current[1]
+ local two = current[2]
+ lookups[one] = { one, zwjchar }
+ local one = { one }
+ local two = { two }
+ local new = #protect + 1
+ protect[new] = {
+ before = before,
+ current = { one, two },
+ after = after,
+ lookups = { 1 }, -- not shared !
+ }
+ revert[new] = {
+ -- before = before,
+ current = { one, zwj },
+ -- after = { two, unpack(after) },
+ after = { two },
+ lookups = { 1 }, -- not shared !
+ }
+ end
+ end
+end
+
+-- blockligatures("\0\0")
+
+otf.helpers.blockligatures = blockligatures
+
+-- blockligatures("fi,ff")
+-- blockligatures("fl")
+-- blockligatures("u:fl:age")
+
+if context then
+
+ interfaces.implement {
+ name = "blockligatures",
+ arguments = "string",
+ actions = blockligatures,
+ }
+
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua b/macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua
new file mode 100644
index 0000000000..b4b9a7b694
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua
@@ -0,0 +1,144 @@
+if not modules then modules = { } end modules ['font-imp-tex'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local next = next
+
+local fonts = fonts
+local otf = fonts.handlers.otf
+local registerotffeature = otf.features.register
+local addotffeature = otf.addfeature
+
+-- tlig (we need numbers for some fonts so ...)
+
+local specification = {
+ type = "ligature",
+ order = { "tlig" },
+ prepend = true,
+ data = {
+ -- endash = "hyphen hyphen",
+ -- emdash = "hyphen hyphen hyphen",
+ [0x2013] = { 0x002D, 0x002D },
+ [0x2014] = { 0x002D, 0x002D, 0x002D },
+ -- quotedblleft = "quoteleft quoteleft",
+ -- quotedblright = "quoteright quoteright",
+ -- quotedblleft = "grave grave",
+ -- quotedblright = "quotesingle quotesingle",
+ -- quotedblbase = "comma comma",
+ },
+}
+
+addotffeature("tlig",specification)
+
+registerotffeature {
+ -- this makes it a known feature (in tables)
+ name = "tlig",
+ description = "tex ligatures",
+}
+
+-- trep
+
+local specification = {
+ type = "substitution",
+ order = { "trep" },
+ prepend = true,
+ data = {
+ -- [0x0022] = 0x201D,
+ [0x0027] = 0x2019,
+ -- [0x0060] = 0x2018,
+ },
+}
+
+addotffeature("trep",specification)
+
+registerotffeature {
+ -- this makes it a known feature (in tables)
+ name = "trep",
+ description = "tex replacements",
+}
+
+-- some day this will be moved to font-imp-scripts.lua
+
+-- anum
+
+local anum_arabic = {
+ [0x0030] = 0x0660,
+ [0x0031] = 0x0661,
+ [0x0032] = 0x0662,
+ [0x0033] = 0x0663,
+ [0x0034] = 0x0664,
+ [0x0035] = 0x0665,
+ [0x0036] = 0x0666,
+ [0x0037] = 0x0667,
+ [0x0038] = 0x0668,
+ [0x0039] = 0x0669,
+}
+
+local anum_persian = {
+ [0x0030] = 0x06F0,
+ [0x0031] = 0x06F1,
+ [0x0032] = 0x06F2,
+ [0x0033] = 0x06F3,
+ [0x0034] = 0x06F4,
+ [0x0035] = 0x06F5,
+ [0x0036] = 0x06F6,
+ [0x0037] = 0x06F7,
+ [0x0038] = 0x06F8,
+ [0x0039] = 0x06F9,
+}
+
+local function valid(data)
+ local features = data.resources.features
+ if features then
+ for k, v in next, features do
+ for k, v in next, v do
+ if v.arab then
+ return true
+ end
+ end
+ end
+ end
+end
+
+local specification = {
+ {
+ type = "substitution",
+ features = { arab = { urd = true, dflt = true } },
+ order = { "anum" },
+ data = anum_arabic,
+ valid = valid,
+ },
+ {
+ type = "substitution",
+ features = { arab = { urd = true } },
+ order = { "anum" },
+ data = anum_persian,
+ valid = valid,
+ },
+}
+
+addotffeature("anum",specification)
+
+registerotffeature {
+ -- this makes it a known feature (in tables)
+ name = "anum",
+ description = "arabic digits",
+}
+
+-- -- example:
+--
+-- fonts.handlers.otf.addfeature {
+-- name = "hangulfix",
+-- type = "substitution",
+-- features = { ["hang"] = { ["*"] = true } },
+-- data = {
+-- [0x1160] = 0x119E,
+-- },
+-- order = { "hangulfix" },
+-- flags = { },
+-- prepend = true,
+-- })
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ini.lua b/macros/luatex/generic/luaotfload/fontloader-font-ini.lua
new file mode 100644
index 0000000000..462e30bf90
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ini.lua
@@ -0,0 +1,54 @@
+if not modules then modules = { } end modules ['font-ini'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>Not much is happening here.</p>
+--ldx]]--
+
+local allocate = utilities.storage.allocate
+local sortedhash = table.sortedhash
+
+fonts = fonts or { }
+local fonts = fonts
+
+local identifiers = allocate()
+
+fonts.hashes = fonts.hashes or { identifiers = identifiers }
+fonts.tables = fonts.tables or { }
+fonts.helpers = fonts.helpers or { }
+fonts.tracers = fonts.tracers or { } -- for the moment till we have move to moduledata
+fonts.specifiers = fonts.specifiers or { } -- in format !
+
+fonts.analyzers = { } -- not needed here
+fonts.readers = { }
+fonts.definers = { methods = { } }
+fonts.loggers = { register = function() end }
+
+if context then
+
+ font.originaleach = font.each
+
+ function font.each()
+ return sortedhash(identifiers)
+ end
+
+ fontloader = nil
+
+end
+
+-- Outside context one can bump textbase to some higher value but only the
+-- textbase given here is officially supported (read: bug testing etc will
+-- use the values below).
+
+fonts.privateoffsets = {
+ textbase = 0xF0000, -- used for hidden (opentype features)
+ textextrabase = 0xFD000, -- used for visible by name
+ mathextrabase = 0xFE000, -- used for visible by code
+ mathbase = 0xFF000, -- used for hidden (virtual math)
+ keepnames = false, -- when set to true names are always kept (not for context)
+}
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-lua.lua b/macros/luatex/generic/luaotfload/fontloader-font-lua.lua
new file mode 100644
index 0000000000..6fbbcf17e4
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-lua.lua
@@ -0,0 +1,46 @@
+if not modules then modules = { } end modules ['font-lua'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+
+local report_lua = logs.reporter("fonts","lua loading")
+
+local fonts = fonts
+local readers = fonts.readers
+fonts.formats.lua = "lua"
+
+-- we could add support for features here
+
+local function check_lua(specification,fullname)
+ -- standard tex file lookup
+ local fullname = resolvers.findfile(fullname) or ""
+ if fullname ~= "" then
+ local loader = loadfile(fullname)
+ loader = loader and loader()
+ return loader and loader(specification)
+ end
+end
+
+readers.check_lua = check_lua
+
+function readers.lua(specification)
+ local original = specification.specification
+ if trace_defining then
+ report_lua("using lua reader for %a",original)
+ end
+ local fullname = specification.filename or ""
+ if fullname == "" then
+ local forced = specification.forced or ""
+ if forced ~= "" then
+ fullname = specification.name .. "." .. forced
+ else
+ fullname = specification.name
+ end
+ end
+ return check_lua(specification,fullname)
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-map.lua b/macros/luatex/generic/luaotfload/fontloader-font-map.lua
new file mode 100644
index 0000000000..d931b822e5
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-map.lua
@@ -0,0 +1,693 @@
+if not modules then modules = { } end modules ['font-map'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local tonumber, next, type = tonumber, next, type
+
+local match, format, find, concat, gsub, lower = string.match, string.format, string.find, table.concat, string.gsub, string.lower
+local P, R, S, C, Ct, Cc, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.match
+local formatters = string.formatters
+local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys
+local rshift = bit32.rshift
+
+local trace_loading = false trackers.register("fonts.loading", function(v) trace_loading = v end)
+local trace_mapping = false trackers.register("fonts.mapping", function(v) trace_mapping = v end)
+
+local report_fonts = logs.reporter("fonts","loading") -- not otf only
+
+-- force_ligatures was true for a while so that these emoji's with bad names work too
+
+local force_ligatures = false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures = v end)
+
+local fonts = fonts or { }
+local mappings = fonts.mappings or { }
+fonts.mappings = mappings
+
+local allocate = utilities.storage.allocate
+
+--[[ldx--
+<p>Eventually this code will disappear because map files are kind
+of obsolete. Some code may move to runtime or auxiliary modules.</p>
+<p>The name to unciode related code will stay of course.</p>
+--ldx]]--
+
+-- local function loadlumtable(filename) -- will move to font goodies
+-- local lumname = file.replacesuffix(file.basename(filename),"lum")
+-- local lumfile = resolvers.findfile(lumname,"map") or ""
+-- if lumfile ~= "" and lfs.isfile(lumfile) then
+-- if trace_loading or trace_mapping then
+-- report_fonts("loading map table %a",lumfile)
+-- end
+-- lumunic = dofile(lumfile)
+-- return lumunic, lumfile
+-- end
+-- end
+
+local hex = R("AF","af","09")
+----- hexfour = (hex*hex*hex*hex) / function(s) return tonumber(s,16) end
+----- hexsix = (hex*hex*hex*hex*hex*hex) / function(s) return tonumber(s,16) end
+local hexfour = (hex*hex*hex^-2) / function(s) return tonumber(s,16) end
+local hexsix = (hex*hex*hex^-4) / function(s) return tonumber(s,16) end
+local dec = (R("09")^1) / tonumber
+local period = P(".")
+local unicode = (P("uni") + P("UNI")) * (hexfour * (period + P(-1)) * Cc(false) + Ct(hexfour^1) * Cc(true)) -- base planes
+local ucode = (P("u") + P("U") ) * (hexsix * (period + P(-1)) * Cc(false) + Ct(hexsix ^1) * Cc(true)) -- extended
+local index = P("index") * dec * Cc(false)
+
+local parser = unicode + ucode + index
+
+local parsers = { }
+
+local function makenameparser(str)
+ if not str or str == "" then
+ return parser
+ else
+ local p = parsers[str]
+ if not p then
+ p = P(str) * period * dec * Cc(false)
+ parsers[str] = p
+ end
+ return p
+ end
+end
+
+local f_single = formatters["%04X"]
+local f_double = formatters["%04X%04X"]
+
+-- floor(x/256) => rshift(x, 8)
+-- floor(x/1024) => rshift(x,10)
+
+-- 0.684 0.661 0,672 0.650 : cache at lua end (more mem)
+-- 0.682 0,672 0.698 0.657 : no cache (moderate mem i.e. lua strings)
+-- 0.644 0.647 0.655 0.645 : convert in c (less mem in theory)
+
+-- local tounicodes = table.setmetatableindex(function(t,unicode)
+-- local s
+-- if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
+-- s = f_single(unicode)
+-- else
+-- unicode = unicode - 0x10000
+-- s = f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+-- end
+-- t[unicode] = s
+-- return s
+-- end)
+--
+-- local function tounicode16(unicode,name)
+-- local s = tounicodes[unicode]
+-- if s then
+-- return s
+-- else
+-- report_fonts("can't convert %a in %a into tounicode",unicode,name)
+-- end
+-- end
+--
+-- local function tounicode16sequence(unicodes,name)
+-- local t = { }
+-- for l=1,#unicodes do
+-- local u = unicodes[l]
+-- local s = tounicodes[u]
+-- if s then
+-- t[l] = s
+-- else
+-- report_fonts ("can't convert %a in %a into tounicode",u,name)
+-- return
+-- end
+-- end
+-- return concat(t)
+-- end
+--
+-- local function tounicode(unicode,name)
+-- if type(unicode) == "table" then
+-- local t = { }
+-- for l=1,#unicode do
+-- local u = unicode[l]
+-- local s = tounicodes[u]
+-- if s then
+-- t[l] = s
+-- else
+-- report_fonts ("can't convert %a in %a into tounicode",u,name)
+-- return
+-- end
+-- end
+-- return concat(t)
+-- else
+-- local s = tounicodes[unicode]
+-- if s then
+-- return s
+-- else
+-- report_fonts("can't convert %a in %a into tounicode",unicode,name)
+-- end
+-- end
+-- end
+
+local function tounicode16(unicode)
+ if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
+ return f_single(unicode)
+ else
+ unicode = unicode - 0x10000
+ return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+ end
+end
+
+local function tounicode16sequence(unicodes)
+ local t = { }
+ for l=1,#unicodes do
+ local u = unicodes[l]
+ if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then
+ t[l] = f_single(u)
+ else
+ u = u - 0x10000
+ t[l] = f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
+ end
+ end
+ return concat(t)
+end
+
+-- local function tounicode(unicode)
+-- if type(unicode) == "table" then
+-- local t = { }
+-- for l=1,#unicode do
+-- local u = unicode[l]
+-- if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then
+-- t[l] = f_single(u)
+-- else
+-- u = u - 0x10000
+-- t[l] = f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
+-- end
+-- end
+-- return concat(t)
+-- else
+-- if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
+-- return f_single(unicode)
+-- else
+-- unicode = unicode - 0x10000
+-- return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+-- end
+-- end
+-- end
+
+local unknown = f_single(0xFFFD)
+
+-- local function tounicode(unicode)
+-- if type(unicode) == "table" then
+-- local t = { }
+-- for l=1,#unicode do
+-- t[l] = tounicode(unicode[l])
+-- end
+-- return concat(t)
+-- elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then
+-- return unknown
+-- elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then
+-- return unknown
+-- elseif unicode >= 0x100000 and unicode <= 0x10FFFF then
+-- return unknown
+-- elseif unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
+-- return f_single(unicode)
+-- else
+-- unicode = unicode - 0x10000
+-- return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+-- end
+-- end
+
+-- local hash = table.setmetatableindex(function(t,k)
+-- local v
+-- if k >= 0x00E000 and k <= 0x00F8FF then
+-- v = unknown
+-- elseif k >= 0x0F0000 and k <= 0x0FFFFF then
+-- v = unknown
+-- elseif k >= 0x100000 and k <= 0x10FFFF then
+-- v = unknown
+-- elseif k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then
+-- v = f_single(k)
+-- else
+-- local k = k - 0x10000
+-- v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
+-- end
+-- t[k] = v
+-- return v
+-- end)
+--
+-- table.makeweak(hash)
+--
+-- local function tounicode(unicode)
+-- if type(unicode) == "table" then
+-- local t = { }
+-- for l=1,#unicode do
+-- t[l] = hash[unicode[l]]
+-- end
+-- return concat(t)
+-- else
+-- return hash[unicode]
+-- end
+-- end
+
+local hash = { }
+local conc = { }
+
+-- table.makeweak(hash)
+
+-- table.setmetatableindex(hash,function(t,k)
+-- if type(k) == "table" then
+-- local n = #k
+-- for l=1,n do
+-- conc[l] = hash[k[l]]
+-- end
+-- return concat(conc,"",1,n)
+-- end
+-- local v
+-- if k >= 0x00E000 and k <= 0x00F8FF then
+-- v = unknown
+-- elseif k >= 0x0F0000 and k <= 0x0FFFFF then
+-- v = unknown
+-- elseif k >= 0x100000 and k <= 0x10FFFF then
+-- v = unknown
+-- elseif k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then
+-- v = f_single(k)
+-- else
+-- local k = k - 0x10000
+-- v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
+-- end
+-- t[k] = v
+-- return v
+-- end)
+--
+-- local function tounicode(unicode)
+-- return hash[unicode]
+-- end
+
+table.setmetatableindex(hash,function(t,k)
+ if k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then
+ v = f_single(k)
+ else
+ local k = k - 0x10000
+ v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
+ end
+ t[k] = v
+ return v
+end)
+
+local function tounicode(k)
+ if type(k) == "table" then
+ local n = #k
+ for l=1,n do
+ conc[l] = hash[k[l]]
+ end
+ return concat(conc,"",1,n)
+ elseif k >= 0x00E000 and k <= 0x00F8FF then
+ return unknown
+ elseif k >= 0x0F0000 and k <= 0x0FFFFF then
+ return unknown
+ elseif k >= 0x100000 and k <= 0x10FFFF then
+ return unknown
+ else
+ return hash[k]
+ end
+end
+
+local function fromunicode16(str)
+ if #str == 4 then
+ return tonumber(str,16)
+ else
+ local l, r = match(str,"(....)(....)")
+ -- return (tonumber(l,16))*0x400 + tonumber(r,16) - 0xDC00
+ return 0x10000 + (tonumber(l,16)-0xD800)*0x400 + tonumber(r,16) - 0xDC00
+ end
+end
+
+-- Slightly slower:
+--
+-- local p = C(4) * (C(4)^-1) / function(l,r)
+-- if r then
+-- return (tonumber(l,16))*0x400 + tonumber(r,16) - 0xDC00
+-- else
+-- return tonumber(l,16)
+-- end
+-- end
+--
+-- local function fromunicode16(str)
+-- return lpegmatch(p,str)
+-- end
+
+mappings.makenameparser = makenameparser
+mappings.tounicode = tounicode
+mappings.tounicode16 = tounicode16
+mappings.tounicode16sequence = tounicode16sequence
+mappings.fromunicode16 = fromunicode16
+
+-- mozilla emoji has bad lig names: name = gsub(name,"(u[a-f0-9_]+)%-([a-f0-9_]+)","%1_%2")
+
+local ligseparator = P("_")
+local varseparator = P(".")
+local namesplitter = Ct(C((1 - ligseparator - varseparator)^1) * (ligseparator * C((1 - ligseparator - varseparator)^1))^0)
+
+-- maybe: ff fi fl ffi ffl => f_f f_i f_l f_f_i f_f_l
+
+-- local function test(name)
+-- local split = lpegmatch(namesplitter,name)
+-- print(string.formatters["%s: [% t]"](name,split))
+-- end
+
+-- test("i.f_")
+-- test("this")
+-- test("this.that")
+-- test("japan1.123")
+-- test("such_so_more")
+-- test("such_so_more.that")
+
+-- to be completed .. for fonts that use unicodes for ligatures which
+-- is a actually a bad thing and should be avoided in the first place
+
+do
+
+ local overloads = {
+ IJ = { name = "I_J", unicode = { 0x49, 0x4A }, mess = 0x0132 },
+ ij = { name = "i_j", unicode = { 0x69, 0x6A }, mess = 0x0133 },
+ ff = { name = "f_f", unicode = { 0x66, 0x66 }, mess = 0xFB00 },
+ fi = { name = "f_i", unicode = { 0x66, 0x69 }, mess = 0xFB01 },
+ fl = { name = "f_l", unicode = { 0x66, 0x6C }, mess = 0xFB02 },
+ ffi = { name = "f_f_i", unicode = { 0x66, 0x66, 0x69 }, mess = 0xFB03 },
+ ffl = { name = "f_f_l", unicode = { 0x66, 0x66, 0x6C }, mess = 0xFB04 },
+ fj = { name = "f_j", unicode = { 0x66, 0x6A } },
+ fk = { name = "f_k", unicode = { 0x66, 0x6B } },
+
+ -- endash = { name = "endash", unicode = 0x2013, mess = 0x2013 },
+ -- emdash = { name = "emdash", unicode = 0x2014, mess = 0x2014 },
+ }
+
+ local o = allocate { }
+
+ for k, v in next, overloads do
+ local name = v.name
+ local mess = v.mess
+ if name then
+ o[name] = v
+ end
+ if mess then
+ o[mess] = v
+ end
+ o[k] = v
+ end
+
+ mappings.overloads = o
+
+end
+
+function mappings.addtounicode(data,filename,checklookups,forceligatures)
+ local resources = data.resources
+ local unicodes = resources.unicodes
+ if not unicodes then
+ if trace_mapping then
+ report_fonts("no unicode list, quitting tounicode for %a",filename)
+ end
+ return
+ end
+ local properties = data.properties
+ local descriptions = data.descriptions
+ local overloads = mappings.overloads
+ -- we need to move this code
+ unicodes['space'] = unicodes['space'] or 32
+ unicodes['hyphen'] = unicodes['hyphen'] or 45
+ unicodes['zwj'] = unicodes['zwj'] or 0x200D
+ unicodes['zwnj'] = unicodes['zwnj'] or 0x200C
+ --
+ local private = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF
+ local unicodevector = fonts.encodings.agl.unicodes or { } -- loaded runtime in context
+ local contextvector = fonts.encodings.agl.ctxcodes or { } -- loaded runtime in context
+ local missing = { }
+ local nofmissing = 0
+ local oparser = nil
+ local cidnames = nil
+ local cidcodes = nil
+ local cidinfo = properties.cidinfo
+ local usedmap = cidinfo and fonts.cid.getmap(cidinfo)
+ local uparser = makenameparser() -- hm, every time?
+ if usedmap then
+ oparser = usedmap and makenameparser(cidinfo.ordering)
+ cidnames = usedmap.names
+ cidcodes = usedmap.unicodes
+ end
+ local ns = 0
+ local nl = 0
+ --
+ -- in order to avoid differences between runs due to hash randomization we
+ -- run over a sorted list
+ --
+ local dlist = sortedkeys(descriptions)
+ --
+ -- for du, glyph in next, descriptions do
+ for i=1,#dlist do
+ local du = dlist[i]
+ local glyph = descriptions[du]
+ local name = glyph.name
+ if name then
+ local overload = overloads[name] or overloads[du]
+ if overload then
+ -- get rid of weird ligatures
+ -- glyph.name = overload.name
+ glyph.unicode = overload.unicode
+ else
+ local gu = glyph.unicode -- can already be set (number or table)
+ if not gu or gu == -1 or du >= private or (du >= 0xE000 and du <= 0xF8FF) or du == 0xFFFE or du == 0xFFFF then
+ local unicode = unicodevector[name] or contextvector[name]
+ if unicode then
+ glyph.unicode = unicode
+ ns = ns + 1
+ end
+ -- cidmap heuristics, beware, there is no guarantee for a match unless
+ -- the chain resolves
+ if (not unicode) and usedmap then
+ local foundindex = lpegmatch(oparser,name)
+ if foundindex then
+ unicode = cidcodes[foundindex] -- name to number
+ if unicode then
+ glyph.unicode = unicode
+ ns = ns + 1
+ else
+ local reference = cidnames[foundindex] -- number to name
+ if reference then
+ local foundindex = lpegmatch(oparser,reference)
+ if foundindex then
+ unicode = cidcodes[foundindex]
+ if unicode then
+ glyph.unicode = unicode
+ ns = ns + 1
+ end
+ end
+ if not unicode or unicode == "" then
+ local foundcodes, multiple = lpegmatch(uparser,reference)
+ if foundcodes then
+ glyph.unicode = foundcodes
+ if multiple then
+ nl = nl + 1
+ unicode = true
+ else
+ ns = ns + 1
+ unicode = foundcodes
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ -- a.whatever or a_b_c.whatever or a_b_c (no numbers) a.b_
+ --
+ -- It is not trivial to find a solution that suits all fonts. We tried several alternatives
+ -- and this one seems to work reasonable also with fonts that use less standardized naming
+ -- schemes. The extra private test is tested by KE and seems to work okay with non-typical
+ -- fonts as well.
+ --
+ if not unicode or unicode == "" then
+ local split = lpegmatch(namesplitter,name)
+ local nsplit = split and #split or 0 -- add if
+ if nsplit == 0 then
+ -- skip
+ elseif nsplit == 1 then
+ local base = split[1]
+ local u = unicodes[base] or unicodevector[base] or contextvector[name]
+ if not u then
+ -- skip
+ elseif type(u) == "table" then
+ -- unlikely
+ if u[1] < private then
+ unicode = u
+ glyph.unicode = unicode
+ end
+ elseif u < private then
+ unicode = u
+ glyph.unicode = unicode
+ end
+ else
+ local t = { }
+ local n = 0
+ for l=1,nsplit do
+ local base = split[l]
+ local u = unicodes[base] or unicodevector[base] or contextvector[name]
+ if not u then
+ break
+ elseif type(u) == "table" then
+ if u[1] >= private then
+ break
+ end
+ n = n + 1
+ t[n] = u[1]
+ else
+ if u >= private then
+ break
+ end
+ n = n + 1
+ t[n] = u
+ end
+ end
+ if n > 0 then
+ if n == 1 then
+ unicode = t[1]
+ else
+ unicode = t
+ end
+ glyph.unicode = unicode
+ end
+ end
+ nl = nl + 1
+ end
+ -- last resort (we might need to catch private here as well)
+ if not unicode or unicode == "" then
+ local foundcodes, multiple = lpegmatch(uparser,name)
+ if foundcodes then
+ glyph.unicode = foundcodes
+ if multiple then
+ nl = nl + 1
+ unicode = true
+ else
+ ns = ns + 1
+ unicode = foundcodes
+ end
+ end
+ end
+ -- check using substitutes and alternates
+ local r = overloads[unicode]
+ if r then
+ unicode = r.unicode
+ glyph.unicode = unicode
+ end
+ --
+ if not unicode then
+ missing[du] = true
+ nofmissing = nofmissing + 1
+ end
+ else
+ -- maybe a message or so
+ end
+ end
+ else
+ local overload = overloads[du]
+ if overload then
+ glyph.unicode = overload.unicode
+ elseif not glyph.unicode then
+ missing[du] = true
+ nofmissing = nofmissing + 1
+ end
+ end
+ end
+ if type(checklookups) == "function" then
+ checklookups(data,missing,nofmissing)
+ end
+
+ local unicoded = 0
+ local collected = fonts.handlers.otf.readers.getcomponents(data) -- neglectable overhead
+
+ local function resolve(glyph,u)
+ local n = #u
+ for i=1,n do
+ if u[i] > private then
+ n = 0
+ break
+ end
+ end
+ if n > 0 then
+ if n > 1 then
+ glyph.unicode = u
+ else
+ glyph.unicode = u[1]
+ end
+ unicoded = unicoded + 1
+ end
+ end
+
+ if not collected then
+ -- move on
+ elseif forceligatures or force_ligatures then
+ for i=1,#dlist do
+ local du = dlist[i]
+ if du >= private or (du >= 0xE000 and du <= 0xF8FF) then
+ local u = collected[du] -- always tables
+ if u then
+ resolve(descriptions[du],u)
+ end
+ end
+ end
+ else
+ for i=1,#dlist do
+ local du = dlist[i]
+ if du >= private or (du >= 0xE000 and du <= 0xF8FF) then
+ local glyph = descriptions[du]
+ if glyph.class == "ligature" and not glyph.unicode then
+ local u = collected[du] -- always tables
+ if u then
+ resolve(glyph,u)
+ end
+ end
+ end
+ end
+ end
+
+ if trace_mapping and unicoded > 0 then
+ report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded)
+ end
+ if trace_mapping then
+ -- for unic, glyph in sortedhash(descriptions) do
+ for i=1,#dlist do
+ local du = dlist[i]
+ local glyph = descriptions[du]
+ local name = glyph.name or "-"
+ local index = glyph.index or 0
+ local unicode = glyph.unicode
+ if unicode then
+ if type(unicode) == "table" then
+ local unicodes = { }
+ for i=1,#unicode do
+ unicodes[i] = formatters("%U",unicode[i])
+ end
+ report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes)
+ else
+ report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode)
+ end
+ else
+ report_fonts("internal slot %U, name %a, unicode %U",index,name,du)
+ end
+ end
+ end
+ if trace_loading and (ns > 0 or nl > 0) then
+ report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns)
+ end
+end
+
+-- local parser = makenameparser("Japan1")
+-- local parser = makenameparser()
+-- local function test(str)
+-- local b, a = lpegmatch(parser,str)
+-- print((a and table.serialize(b)) or b)
+-- end
+-- test("a.sc")
+-- test("a")
+-- test("uni1234")
+-- test("uni1234.xx")
+-- test("uni12349876")
+-- test("u123400987600")
+-- test("index1234")
+-- test("Japan1.123")
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ocl.lua b/macros/luatex/generic/luaotfload/fontloader-font-ocl.lua
new file mode 100644
index 0000000000..d79ed657e0
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ocl.lua
@@ -0,0 +1,670 @@
+if not modules then modules = { } end modules ['font-ocl'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo : user list of colors
+
+local tostring, tonumber, next = tostring, tonumber, next
+local round, max = math.round, math.round
+local sortedkeys, sortedhash = table.sortedkeys, table.sortedhash
+local setmetatableindex = table.setmetatableindex
+
+local formatters = string.formatters
+local tounicode = fonts.mappings.tounicode
+
+local helpers = fonts.helpers
+
+local charcommand = helpers.commands.char
+local rightcommand = helpers.commands.right
+local leftcommand = helpers.commands.left
+local downcommand = helpers.commands.down
+
+local otf = fonts.handlers.otf
+
+local f_color = formatters["%.3f %.3f %.3f rg"]
+local f_gray = formatters["%.3f g"]
+
+if context then
+
+ local startactualtext = nil
+ local stopactualtext = nil
+
+ function otf.getactualtext(s)
+ if not startactualtext then
+ startactualtext = backends.codeinjections.startunicodetoactualtextdirect
+ stopactualtext = backends.codeinjections.stopunicodetoactualtextdirect
+ end
+ return startactualtext(s), stopactualtext()
+ end
+
+else
+
+ local tounicode = fonts.mappings.tounicode16
+
+ function otf.getactualtext(s)
+ return
+ "/Span << /ActualText <feff" .. s .. "> >> BDC",
+ "EMC"
+ end
+
+end
+
+local sharedpalettes = { }
+
+local hash = setmetatableindex(function(t,k)
+ local v = { "pdf", "direct", k }
+ t[k] = v
+ return v
+end)
+
+if context then
+
+ -- \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray,textcolor] -- looks bad
+ -- \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray] -- looks okay
+
+ local colors = attributes.list[attributes.private('color')] or { }
+ local transparencies = attributes.list[attributes.private('transparency')] or { }
+
+ function otf.registerpalette(name,values)
+ sharedpalettes[name] = values
+ local color = lpdf.color
+ local transparency = lpdf.transparency
+ local register = colors.register
+ for i=1,#values do
+ local v = values[i]
+ if v == "textcolor" then
+ values[i] = false
+ else
+ local c = nil
+ local t = nil
+ if type(v) == "table" then
+ c = 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
+ c = colors[v]
+ t = transparencies[v]
+ end
+ if c and t then
+ values[i] = hash[color(1,c) .. " " .. transparency(t)]
+ elseif c then
+ values[i] = hash[color(1,c)]
+ elseif t then
+ values[i] = hash[color(1,t)]
+ end
+ end
+ end
+ end
+
+else -- for generic
+
+ function otf.registerpalette(name,values)
+ sharedpalettes[name] = values
+ for i=1,#values do
+ local v = values[i]
+ if v then
+ 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
+
+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. Okay, from
+-- now on we can use text as literal mode.
+
+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 start = { "pdf", "mode", "font" } -- force text mode (so get q Q right)
+----- stop = { "pdf", "mode", "page" } -- force page mode (else overlap)
+local push = { "pdf", "page", "q" }
+local pop = { "pdf", "page", "Q" }
+
+-- -- This one results in color directives inside BT ET but has less q Q pairs. It
+-- -- only shows the first glyph in acrobat and nothing more. No problem with other
+-- -- renderers.
+--
+-- local function initialize(tfmdata,kind,value) -- hm, always value
+-- if value then
+-- local resources = tfmdata.resources
+-- local palettes = resources.colorpalettes
+-- if palettes then
+-- --
+-- local converted = resources.converted
+-- if not converted then
+-- converted = 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
+-- --
+-- properties.virtualized = true
+-- tfmdata.fonts = {
+-- { id = 0 }
+-- }
+-- --
+-- local getactualtext = otf.getactualtext
+-- local default = colorvalues[#colorvalues]
+-- local b, e = getactualtext(tounicode(0xFFFD))
+-- local actualb = { "pdf", "page", b } -- saves tables
+-- local actuale = { "pdf", "page", e } -- saves tables
+-- --
+-- for unicode, character in next, characters do
+-- local description = descriptions[unicode]
+-- if description then
+-- local colorlist = description.colors
+-- if colorlist then
+-- local u = description.unicode or characters[unicode].unicode
+-- local w = character.width or 0
+-- local s = #colorlist
+-- local goback = w ~= 0 and leftcommand[w] or nil -- needs checking: are widths the same
+-- local t = {
+-- start,
+-- not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) }
+-- }
+-- local n = 2
+-- local l = nil
+-- n = n + 1 t[n] = push
+-- for i=1,s do
+-- local entry = colorlist[i]
+-- 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] = charcommand[entry.slot]
+-- if s > 1 and i < s and goback then
+-- n = n + 1 t[n] = goback
+-- end
+-- end
+-- n = n + 1 t[n] = pop
+-- n = n + 1 t[n] = actuale
+-- n = n + 1 t[n] = stop
+-- character.commands = t
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+--
+-- -- Here we have no color change in BT .. ET and more q Q pairs but even then acrobat
+-- -- fails displaying the overlays correctly. Other renderers do it right.
+
+local function initialize(tfmdata,kind,value)
+ if value then
+ local resources = tfmdata.resources
+ local palettes = resources.colorpalettes
+ if palettes then
+ --
+ local converted = resources.converted
+ if not converted then
+ converted = setmetatableindex(convert)
+ resources.converted = converted
+ end
+ local colorvalues = sharedpalettes[value]
+ local default = false -- so the text color (bad for icon overloads)
+ if colorvalues then
+ default = colorvalues[#colorvalues]
+ else
+ colorvalues = converted[palettes[tonumber(value) or 1] or palettes[1]] or { }
+ end
+ local classes = #colorvalues
+ if classes == 0 then
+ return
+ end
+ --
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local properties = tfmdata.properties
+ --
+ properties.virtualized = true
+ tfmdata.fonts = {
+ { id = 0 }
+ }
+ --
+ local getactualtext = otf.getactualtext
+ local b, e = getactualtext(tounicode(0xFFFD))
+ local actualb = { "pdf", "page", b } -- saves tables
+ local actuale = { "pdf", "page", e } -- saves tables
+ --
+ for unicode, character in next, characters do
+ local description = descriptions[unicode]
+ if description then
+ local colorlist = description.colors
+ if colorlist then
+ local u = description.unicode or characters[unicode].unicode
+ local w = character.width or 0
+ local s = #colorlist
+ local goback = w ~= 0 and leftcommand[w] or nil -- needs checking: are widths the same
+ local t = {
+ start, -- really needed
+ not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) }
+ }
+ local n = 2
+ local l = nil
+ local f = false
+ for i=1,s do
+ local entry = colorlist[i]
+ local v = colorvalues[entry.class] or default
+ if v and l ~= v then
+ if f then
+ n = n + 1 t[n] = pop
+ end
+ n = n + 1 t[n] = push
+ f = true
+ n = n + 1 t[n] = v
+ l = v
+ else
+ if f then
+ n = n + 1 t[n] = pop
+ end
+ f = false
+ l = nil
+ end
+ n = n + 1 t[n] = charcommand[entry.slot]
+ if s > 1 and i < s and goback then
+ n = n + 1 t[n] = goback
+ end
+ end
+ if f then
+ n = n + 1 t[n] = pop
+ end
+ n = n + 1 t[n] = actuale
+ -- n = n + 1 t[n] = stop -- not needed
+ character.commands = t
+ end
+ end
+ end
+ end
+ end
+end
+
+fonts.handlers.otf.features.register {
+ name = "colr",
+ description = "color glyphs",
+ manipulators = {
+ base = initialize,
+ node = initialize,
+ }
+}
+
+do
+
+ local nofstreams = 0
+ local f_name = formatters[ [[pdf-glyph-%05i]] ]
+ local f_used = context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ]
+ local hashed = { }
+ local cache = { }
+
+ local openpdf = pdfe.new
+ ----- prefix = "data:application/pdf,"
+
+ function otf.storepdfdata(pdf)
+ local done = hashed[pdf]
+ if not done then
+ nofstreams = nofstreams + 1
+ local f = f_name(nofstreams)
+ local n = openpdf(pdf,#pdf,f)
+ done = f_used(n)
+ hashed[pdf] = done
+ end
+ return done
+ end
+
+end
+
+-- I'll probably make a variant for context as we can do it more efficient there than in
+-- generic.
+
+local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = png|svg
+ if not tfmdata or not pdfshapes or not kind then
+ return
+ end
+ --
+ local characters = tfmdata.characters
+ local properties = tfmdata.properties
+ local parameters = tfmdata.parameters
+ local hfactor = parameters.hfactor
+ --
+ properties.virtualized = true
+ --
+ tfmdata.fonts = {
+ { id = 0 } -- not really needed
+ }
+ --
+ local getactualtext = otf.getactualtext
+ local storepdfdata = otf.storepdfdata
+ --
+ local b, e = getactualtext(tounicode(0xFFFD))
+ local actualb = { "pdf", "page", b } -- saves tables
+ local actuale = { "pdf", "page", e } -- saves tables
+ --
+ local vfimage = lpdf and lpdf.vfimage or function(wd,ht,dp,data,name)
+ -- needed for generic (if used there at all)
+ local name = storepdfdata(data)
+ return { "image", { filename = name, width = wd, height = ht, depth = dp } }
+ end
+ --
+ for unicode, character in sortedhash(characters) do -- sort is nicer for svg
+ local index = character.index
+ if index then
+ local pdf = pdfshapes[index]
+ local typ = type(pdf)
+ local data = nil
+ local dx = nil
+ local dy = nil
+ if typ == "table" then
+ data = pdf.data
+ dx = pdf.dx or 0
+ dy = pdf.dy or 0
+ elseif typ == "string" then
+ data = pdf
+ dx = 0
+ dy = 0
+ end
+ if data then
+ -- We can delay storage by a lua function in commands: but then we need to
+ -- be able to provide our own mem stream name (so that we can reserve it).
+ -- Anyway, we will do this different in a future version of context.
+ local bt = unicode and getactualtext(unicode)
+ local wd = character.width or 0
+ local ht = character.height or 0
+ local dp = character.depth or 0
+ -- The down and right will change too (we can move that elsewhere).
+ character.commands = {
+ not unicode and actualb or { "pdf", "page", (getactualtext(unicode)) },
+ downcommand[dp + dy * hfactor],
+ rightcommand[dx * hfactor],
+ vfimage(wd,ht,dp,data,name),
+ actuale,
+ }
+ character[kind] = true
+ end
+ end
+ end
+end
+
+local otfsvg = otf.svg or { }
+otf.svg = otfsvg
+otf.svgenabled = true
+
+do
+
+ local report_svg = logs.reporter("fonts","svg conversion")
+
+ local loaddata = io.loaddata
+ local savedata = io.savedata
+ local remove = os.remove
+
+ if context and xml.convert then
+
+ local xmlconvert = xml.convert
+ local xmlfirst = xml.first
+
+ function otfsvg.filterglyph(entry,index)
+ local svg = xmlconvert(entry.data)
+ local root = svg and xmlfirst(svg,"/svg[@id='glyph"..index.."']")
+ local data = root and tostring(root)
+ -- report_svg("data for glyph %04X: %s",index,data)
+ return data
+ end
+
+ else
+
+ function otfsvg.filterglyph(entry,index) -- can be overloaded
+ return entry.data
+ end
+
+ end
+
+ local runner = sandbox and sandbox.registerrunner {
+ name = "otfsvg",
+ program = "inkscape",
+ method = "pipeto",
+ template = "--shell > temp-otf-svg-shape.log",
+ reporter = report_svg,
+ }
+
+ if not runner then
+ --
+ -- poor mans variant for generic:
+ --
+ runner = function()
+ return io.open("inkscape --shell > temp-otf-svg-shape.log","w")
+ end
+ end
+
+ function otfsvg.topdf(svgshapes)
+ local pdfshapes = { }
+ local inkscape = runner()
+ if inkscape then
+ local nofshapes = #svgshapes
+ local f_svgfile = formatters["temp-otf-svg-shape-%i.svg"]
+ local f_pdffile = formatters["temp-otf-svg-shape-%i.pdf"]
+ local f_convert = formatters["%s --export-pdf=%s\n"]
+ local filterglyph = otfsvg.filterglyph
+ local nofdone = 0
+ report_svg("processing %i svg containers",nofshapes)
+ statistics.starttiming()
+ for i=1,nofshapes do
+ local entry = svgshapes[i]
+ for index=entry.first,entry.last do
+ local data = filterglyph(entry,index)
+ if data and data ~= "" then
+ local svgfile = f_svgfile(index)
+ local pdffile = f_pdffile(index)
+ savedata(svgfile,data)
+ inkscape:write(f_convert(svgfile,pdffile))
+ pdfshapes[index] = true
+ nofdone = nofdone + 1
+ if nofdone % 100 == 0 then
+ report_svg("%i shapes processed",nofdone)
+ end
+ end
+ end
+ end
+ inkscape:write("quit\n")
+ inkscape:close()
+ report_svg("processing %i pdf results",nofshapes)
+ for index in next, pdfshapes do
+ local svgfile = f_svgfile(index)
+ local pdffile = f_pdffile(index)
+ pdfshapes[index] = loaddata(pdffile)
+ remove(svgfile)
+ remove(pdffile)
+ end
+ statistics.stoptiming()
+ if statistics.elapsedseconds then
+ report_svg("svg conversion time %s",statistics.elapsedseconds() or "-")
+ end
+ end
+ return pdfshapes
+ end
+
+end
+
+local function initializesvg(tfmdata,kind,value) -- hm, always value
+ if value and otf.svgenabled then
+ local svg = tfmdata.properties.svg
+ local hash = svg and svg.hash
+ local timestamp = svg and svg.timestamp
+ if not hash then
+ return
+ end
+ local pdffile = containers.read(otf.pdfcache,hash)
+ local pdfshapes = pdffile and pdffile.pdfshapes
+ if not pdfshapes or pdffile.timestamp ~= timestamp then
+ local svgfile = containers.read(otf.svgcache,hash)
+ local svgshapes = svgfile and svgfile.svgshapes
+ pdfshapes = svgshapes and otfsvg.topdf(svgshapes) or { }
+ containers.write(otf.pdfcache, hash, {
+ pdfshapes = pdfshapes,
+ timestamp = timestamp,
+ })
+ end
+ pdftovirtual(tfmdata,pdfshapes,"svg")
+ end
+end
+
+fonts.handlers.otf.features.register {
+ name = "svg",
+ description = "svg glyphs",
+ manipulators = {
+ base = initializesvg,
+ node = initializesvg,
+ }
+}
+
+-- This can be done differently e.g. with ffi and gm and we can share code anway. Using
+-- batchmode in gm is not faster and as it accumulates we would need to flush all
+-- individual shapes. But ... in context lmtx (and maybe the backport) we will use
+-- a different and more efficient method anyway. I'm still wondering if I should
+-- keep color code in generic. Maybe it should be optional.
+
+local otfpng = otf.png or { }
+otf.png = otfpng
+otf.pngenabled = true
+
+do
+
+ local report_png = logs.reporter("fonts","png conversion")
+
+ local loaddata = io.loaddata
+ local savedata = io.savedata
+ local remove = os.remove
+
+ local runner = sandbox and sandbox.registerrunner {
+ name = "otfpng",
+ program = "gm",
+ template = "convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log",
+ -- reporter = report_png,
+ }
+
+ if not runner then
+ --
+ -- poor mans variant for generic:
+ --
+ runner = function()
+ return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log")
+ end
+ end
+
+ -- Alternatively we can create a single pdf file with -adjoin and then pick up pages from
+ -- that file but creating thousands of small files is no fun either.
+
+ function otfpng.topdf(pngshapes)
+ local pdfshapes = { }
+ local pngfile = "temp-otf-png-shape.png"
+ local pdffile = "temp-otf-png-shape.pdf"
+ local nofdone = 0
+ local indices = sortedkeys(pngshapes) -- can be sparse
+ local nofindices = #indices
+ report_png("processing %i png containers",nofindices)
+ statistics.starttiming()
+ for i=1,nofindices do
+ local index = indices[i]
+ local entry = pngshapes[index]
+ local data = entry.data -- or placeholder
+ local x = entry.x
+ local y = entry.y
+ savedata(pngfile,data)
+ runner()
+ pdfshapes[index] = {
+ x = x ~= 0 and x or nil,
+ y = y ~= 0 and y or nil,
+ data = loaddata(pdffile),
+ }
+ nofdone = nofdone + 1
+ if nofdone % 100 == 0 then
+ report_png("%i shapes processed",nofdone)
+ end
+ end
+ report_png("processing %i pdf results",nofindices)
+ remove(pngfile)
+ remove(pdffile)
+ statistics.stoptiming()
+ if statistics.elapsedseconds then
+ report_png("png conversion time %s",statistics.elapsedseconds() or "-")
+ end
+ return pdfshapes
+ end
+
+end
+
+-- This will change in a future version of context. More direct.
+
+local function initializepng(tfmdata,kind,value) -- hm, always value
+ if value and otf.pngenabled then
+ local png = tfmdata.properties.png
+ local hash = png and png.hash
+ local timestamp = png and png.timestamp
+ if not hash then
+ return
+ end
+ local pdffile = containers.read(otf.pdfcache,hash)
+ local pdfshapes = pdffile and pdffile.pdfshapes
+ if not pdfshapes or pdffile.timestamp ~= timestamp then
+ local pngfile = containers.read(otf.pngcache,hash)
+ local pngshapes = pngfile and pngfile.pngshapes
+ pdfshapes = pngshapes and otfpng.topdf(pngshapes) or { }
+ containers.write(otf.pdfcache, hash, {
+ pdfshapes = pdfshapes,
+ timestamp = timestamp,
+ })
+ end
+ --
+ pdftovirtual(tfmdata,pdfshapes,"png")
+ end
+end
+
+fonts.handlers.otf.features.register {
+ name = "sbix",
+ description = "sbix glyphs",
+ manipulators = {
+ base = initializepng,
+ node = initializepng,
+ }
+}
+
+fonts.handlers.otf.features.register {
+ name = "cblc",
+ description = "cblc glyphs",
+ manipulators = {
+ base = initializepng,
+ node = initializepng,
+ }
+}
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-one.lua b/macros/luatex/generic/luaotfload/fontloader-font-one.lua
new file mode 100644
index 0000000000..5387516b4d
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-one.lua
@@ -0,0 +1,842 @@
+if not modules then modules = { } end modules ['font-one'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>Some code may look a bit obscure but this has to do with the fact that we also use
+this code for testing and much code evolved in the transition from <l n='tfm'/> to
+<l n='afm'/> to <l n='otf'/>.</p>
+
+<p>The following code still has traces of intermediate font support where we handles
+font encodings. Eventually font encoding went away but we kept some code around in
+other modules.</p>
+
+<p>This version implements a node mode approach so that users can also more easily
+add features.</p>
+--ldx]]--
+
+local fonts, logs, trackers, containers, resolvers = fonts, logs, trackers, containers, resolvers
+
+local next, type, tonumber, rawget = next, type, tonumber, rawget
+local match, gsub = string.match, string.gsub
+local abs = math.abs
+local P, S, R, Cmt, C, Ct, Cs, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg
+local lpegmatch, patterns = lpeg.match, lpeg.patterns
+local sortedhash = table.sortedhash
+
+local trace_features = false trackers.register("afm.features", function(v) trace_features = v end)
+local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end)
+local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end)
+local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+
+local report_afm = logs.reporter("fonts","afm loading")
+
+local setmetatableindex = table.setmetatableindex
+local derivetable = table.derive
+
+local findbinfile = resolvers.findbinfile
+
+local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF
+
+local definers = fonts.definers
+local readers = fonts.readers
+local constructors = fonts.constructors
+
+local afm = constructors.handlers.afm
+local pfb = constructors.handlers.pfb
+local otf = fonts.handlers.otf
+
+local otfreaders = otf.readers
+local otfenhancers = otf.enhancers
+
+local afmfeatures = constructors.features.afm
+local registerafmfeature = afmfeatures.register
+
+local afmenhancers = constructors.enhancers.afm
+local registerafmenhancer = afmenhancers.register
+
+afm.version = 1.513 -- incrementing this number one up will force a re-cache
+afm.cache = containers.define("fonts", "one", afm.version, true)
+afm.autoprefixed = true -- this will become false some day (catches texnansi-blabla.*)
+
+afm.helpdata = { } -- set later on so no local for this
+afm.syncspace = true -- when true, nicer stretch values
+
+local overloads = fonts.mappings.overloads
+
+local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes
+
+--[[ldx--
+<p>We cache files. Caching is taken care of in the loader. We cheat a bit by adding
+ligatures and kern information to the afm derived data. That way we can set them faster
+when defining a font.</p>
+
+<p>We still keep the loading two phased: first we load the data in a traditional
+fashion and later we transform it to sequences. Then we apply some methods also
+used in opentype fonts (like <t>tlig</t>).</p>
+--ldx]]--
+
+function afm.load(filename)
+ filename = resolvers.findfile(filename,'afm') or ""
+ if filename ~= "" and not fonts.names.ignoredfile(filename) then
+ local name = file.removesuffix(file.basename(filename))
+ local data = containers.read(afm.cache,name)
+ local attr = lfs.attributes(filename)
+ local size = attr and attr.size or 0
+ local time = attr and attr.modification or 0
+ --
+ local pfbfile = file.replacesuffix(name,"pfb")
+ local pfbname = resolvers.findfile(pfbfile,"pfb") or ""
+ if pfbname == "" then
+ pfbname = resolvers.findfile(file.basename(pfbfile),"pfb") or ""
+ end
+ local pfbsize = 0
+ local pfbtime = 0
+ if pfbname ~= "" then
+ local attr = lfs.attributes(pfbname)
+ pfbsize = attr.size or 0
+ pfbtime = attr.modification or 0
+ end
+ if not data or data.size ~= size or data.time ~= time or data.pfbsize ~= pfbsize or data.pfbtime ~= pfbtime then
+ report_afm("reading %a",filename)
+ data = afm.readers.loadfont(filename,pfbname)
+ if data then
+ afmenhancers.apply(data,filename)
+ -- otfreaders.addunicodetable(data) -- only when not done yet
+ fonts.mappings.addtounicode(data,filename)
+ otfreaders.stripredundant(data)
+ -- otfreaders.extend(data)
+ otfreaders.pack(data)
+ data.size = size
+ data.time = time
+ data.pfbsize = pfbsize
+ data.pfbtime = pfbtime
+ report_afm("saving %a in cache",name)
+ -- data.resources.unicodes = nil -- consistent with otf but here we save not much
+ data = containers.write(afm.cache, name, data)
+ data = containers.read(afm.cache,name)
+ end
+ end
+ if data then
+ -- constructors.addcoreunicodes(unicodes)
+ otfreaders.unpack(data)
+ otfreaders.expand(data) -- inline tables
+ otfreaders.addunicodetable(data) -- only when not done yet
+ otfenhancers.apply(data,filename,data)
+ if applyruntimefixes then
+ applyruntimefixes(filename,data)
+ end
+ end
+ return data
+ end
+end
+
+-- we run a more advanced analyzer later on anyway
+
+local uparser = fonts.mappings.makenameparser() -- each time
+
+local function enhance_unify_names(data, filename)
+ local unicodevector = fonts.encodings.agl.unicodes -- loaded runtime in context
+ local unicodes = { }
+ local names = { }
+ local private = data.private or privateoffset
+ local descriptions = data.descriptions
+ for name, blob in sortedhash(data.characters) do -- sorting is nicer for privates
+ local code = unicodevector[name] -- or characters.name_to_unicode[name]
+ if not code then
+ code = lpegmatch(uparser,name)
+ if type(code) ~= "number" then
+ code = private
+ private = private + 1
+ report_afm("assigning private slot %U for unknown glyph name %a",code,name)
+ end
+ end
+ local index = blob.index
+ unicodes[name] = code
+ names[name] = index
+ blob.name = name
+ descriptions[code] = {
+ boundingbox = blob.boundingbox,
+ width = blob.width,
+ kerns = blob.kerns,
+ index = index,
+ name = name,
+ }
+ end
+ for unicode, description in next, descriptions do
+ local kerns = description.kerns
+ if kerns then
+ local krn = { }
+ for name, kern in next, kerns do
+ local unicode = unicodes[name]
+ if unicode then
+ krn[unicode] = kern
+ else
+ -- print(unicode,name)
+ end
+ end
+ description.kerns = krn
+ end
+ end
+ data.characters = nil
+ data.private = private
+ local resources = data.resources
+ local filename = resources.filename or file.removesuffix(file.basename(filename))
+ resources.filename = resolvers.unresolve(filename) -- no shortcut
+ resources.unicodes = unicodes -- name to unicode
+ resources.marks = { } -- todo
+ -- resources.names = names -- name to index
+end
+
+local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } }
+local noflags = { false, false, false, false }
+
+local function enhance_normalize_features(data)
+ local ligatures = setmetatableindex("table")
+ local kerns = setmetatableindex("table")
+ local extrakerns = setmetatableindex("table")
+ for u, c in next, data.descriptions do
+ local l = c.ligatures
+ local k = c.kerns
+ local e = c.extrakerns
+ if l then
+ ligatures[u] = l
+ for u, v in next, l do
+ l[u] = { ligature = v }
+ end
+ c.ligatures = nil
+ end
+ if k then
+ kerns[u] = k
+ for u, v in next, k do
+ k[u] = v -- { v, 0 }
+ end
+ c.kerns = nil
+ end
+ if e then
+ extrakerns[u] = e
+ for u, v in next, e do
+ e[u] = v -- { v, 0 }
+ end
+ c.extrakerns = nil
+ end
+ end
+ local features = {
+ gpos = { },
+ gsub = { },
+ }
+ local sequences = {
+ -- only filled ones
+ }
+ if next(ligatures) then
+ features.gsub.liga = everywhere
+ data.properties.hasligatures = true
+ sequences[#sequences+1] = {
+ features = {
+ liga = everywhere,
+ },
+ flags = noflags,
+ name = "s_s_0",
+ nofsteps = 1,
+ order = { "liga" },
+ type = "gsub_ligature",
+ steps = {
+ {
+ coverage = ligatures,
+ },
+ },
+ }
+ end
+ if next(kerns) then
+ features.gpos.kern = everywhere
+ data.properties.haskerns = true
+ sequences[#sequences+1] = {
+ features = {
+ kern = everywhere,
+ },
+ flags = noflags,
+ name = "p_s_0",
+ nofsteps = 1,
+ order = { "kern" },
+ type = "gpos_pair",
+ steps = {
+ {
+ format = "kern",
+ coverage = kerns,
+ },
+ },
+ }
+ end
+ if next(extrakerns) then
+ features.gpos.extrakerns = everywhere
+ data.properties.haskerns = true
+ sequences[#sequences+1] = {
+ features = {
+ extrakerns = everywhere,
+ },
+ flags = noflags,
+ name = "p_s_1",
+ nofsteps = 1,
+ order = { "extrakerns" },
+ type = "gpos_pair",
+ steps = {
+ {
+ format = "kern",
+ coverage = extrakerns,
+ },
+ },
+ }
+ end
+ -- todo: compress kerns
+ data.resources.features = features
+ data.resources.sequences = sequences
+end
+
+local function enhance_fix_names(data)
+ for k, v in next, data.descriptions do
+ local n = v.name
+ local r = overloads[n]
+ if r then
+ local name = r.name
+ if trace_indexing then
+ report_afm("renaming characters %a to %a",n,name)
+ end
+ v.name = name
+ v.unicode = r.unicode
+ end
+ end
+end
+
+--[[ldx--
+<p>These helpers extend the basic table with extra ligatures, texligatures
+and extra kerns. This saves quite some lookups later.</p>
+--ldx]]--
+
+local addthem = function(rawdata,ligatures)
+ if ligatures then
+ local descriptions = rawdata.descriptions
+ local resources = rawdata.resources
+ local unicodes = resources.unicodes
+ -- local names = resources.names
+ for ligname, ligdata in next, ligatures do
+ local one = descriptions[unicodes[ligname]]
+ if one then
+ for _, pair in next, ligdata do
+ local two = unicodes[pair[1]]
+ local three = unicodes[pair[2]]
+ if two and three then
+ local ol = one.ligatures
+ if ol then
+ if not ol[two] then
+ ol[two] = three
+ end
+ else
+ one.ligatures = { [two] = three }
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+local function enhance_add_ligatures(rawdata)
+ addthem(rawdata,afm.helpdata.ligatures)
+end
+
+--[[ldx--
+<p>We keep the extra kerns in separate kerning tables so that we can use
+them selectively.</p>
+--ldx]]--
+
+-- This is rather old code (from the beginning when we had only tfm). If
+-- we unify the afm data (now we have names all over the place) then
+-- we can use shcodes but there will be many more looping then. But we
+-- could get rid of the tables in char-cmp then. Als, in the generic version
+-- we don't use the character database. (Ok, we can have a context specific
+-- variant).
+
+local function enhance_add_extra_kerns(rawdata) -- using shcodes is not robust here
+ local descriptions = rawdata.descriptions
+ local resources = rawdata.resources
+ local unicodes = resources.unicodes
+ local function do_it_left(what)
+ if what then
+ for unicode, description in next, descriptions do
+ local kerns = description.kerns
+ if kerns then
+ local extrakerns
+ for complex, simple in next, what do
+ complex = unicodes[complex]
+ simple = unicodes[simple]
+ if complex and simple then
+ local ks = kerns[simple]
+ if ks and not kerns[complex] then
+ if extrakerns then
+ extrakerns[complex] = ks
+ else
+ extrakerns = { [complex] = ks }
+ end
+ end
+ end
+ end
+ if extrakerns then
+ description.extrakerns = extrakerns
+ end
+ end
+ end
+ end
+ end
+ local function do_it_copy(what)
+ if what then
+ for complex, simple in next, what do
+ complex = unicodes[complex]
+ simple = unicodes[simple]
+ if complex and simple then
+ local complexdescription = descriptions[complex]
+ if complexdescription then -- optional
+ local simpledescription = descriptions[complex]
+ if simpledescription then
+ local extrakerns
+ local kerns = simpledescription.kerns
+ if kerns then
+ for unicode, kern in next, kerns do
+ if extrakerns then
+ extrakerns[unicode] = kern
+ else
+ extrakerns = { [unicode] = kern }
+ end
+ end
+ end
+ local extrakerns = simpledescription.extrakerns
+ if extrakerns then
+ for unicode, kern in next, extrakerns do
+ if extrakerns then
+ extrakerns[unicode] = kern
+ else
+ extrakerns = { [unicode] = kern }
+ end
+ end
+ end
+ if extrakerns then
+ complexdescription.extrakerns = extrakerns
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ -- add complex with values of simplified when present
+ do_it_left(afm.helpdata.leftkerned)
+ do_it_left(afm.helpdata.bothkerned)
+ -- copy kerns from simple char to complex char unless set
+ do_it_copy(afm.helpdata.bothkerned)
+ do_it_copy(afm.helpdata.rightkerned)
+end
+
+--[[ldx--
+<p>The copying routine looks messy (and is indeed a bit messy).</p>
+--ldx]]--
+
+local function adddimensions(data) -- we need to normalize afm to otf i.e. indexed table instead of name
+ if data then
+ for unicode, description in next, data.descriptions do
+ local bb = description.boundingbox
+ if bb then
+ local ht = bb[4]
+ local dp = -bb[2]
+ if ht == 0 or ht < 0 then
+ -- no need to set it and no negative heights, nil == 0
+ else
+ description.height = ht
+ end
+ if dp == 0 or dp < 0 then
+ -- no negative depths and no negative depths, nil == 0
+ else
+ description.depth = dp
+ end
+ end
+ end
+ end
+end
+
+local function copytotfm(data)
+ if data and data.descriptions then
+ local metadata = data.metadata
+ local resources = data.resources
+ local properties = derivetable(data.properties)
+ local descriptions = derivetable(data.descriptions)
+ local goodies = derivetable(data.goodies)
+ local characters = { }
+ local parameters = { }
+ local unicodes = resources.unicodes
+ --
+ for unicode, description in next, data.descriptions do -- use parent table
+ characters[unicode] = { }
+ end
+ --
+ local filename = constructors.checkedfilename(resources)
+ local fontname = metadata.fontname or metadata.fullname
+ local fullname = metadata.fullname or metadata.fontname
+ local endash = 0x2013
+ local emdash = 0x2014
+ local space = 0x0020 -- space
+ local spacer = "space"
+ local spaceunits = 500
+ --
+ local monospaced = metadata.monospaced
+ local charwidth = metadata.charwidth
+ local italicangle = metadata.italicangle
+ local charxheight = metadata.xheight and metadata.xheight > 0 and metadata.xheight
+ properties.monospaced = monospaced
+ parameters.italicangle = italicangle
+ parameters.charwidth = charwidth
+ parameters.charxheight = charxheight
+ -- nearly the same as otf, catches
+ local d_endash = descriptions[endash]
+ local d_emdash = descriptions[emdash]
+ local d_space = descriptions[space]
+ if not d_space or d_space == 0 then
+ d_space = d_endash
+ end
+ if d_space then
+ spaceunits, spacer = d_space.width or 0, "space"
+ end
+ if properties.monospaced then
+ if spaceunits == 0 and d_emdash then
+ spaceunits, spacer = d_emdash.width or 0, "emdash"
+ end
+ else
+ if spaceunits == 0 and d_endash then
+ spaceunits, spacer = d_emdash.width or 0, "endash"
+ end
+ end
+ if spaceunits == 0 and charwidth then
+ spaceunits, spacer = charwidth or 0, "charwidth"
+ end
+ if spaceunits == 0 then
+ spaceunits = tonumber(spaceunits) or 500
+ end
+ if spaceunits == 0 then
+ spaceunits = 500
+ end
+ --
+ parameters.slant = 0
+ parameters.space = spaceunits
+ parameters.space_stretch = 500
+ parameters.space_shrink = 333
+ parameters.x_height = 400
+ parameters.quad = 1000
+ --
+ if italicangle and italicangle ~= 0 then
+ parameters.italicangle = italicangle
+ parameters.italicfactor = math.cos(math.rad(90+italicangle))
+ parameters.slant = - math.tan(italicangle*math.pi/180)
+ end
+ if monospaced then
+ parameters.space_stretch = 0
+ parameters.space_shrink = 0
+ elseif afm.syncspace then
+ parameters.space_stretch = spaceunits/2
+ parameters.space_shrink = spaceunits/3
+ end
+ parameters.extra_space = parameters.space_shrink
+ if charxheight then
+ parameters.x_height = charxheight
+ else
+ -- same as otf
+ local x = 0x0078 -- x
+ if x then
+ local x = descriptions[x]
+ if x then
+ parameters.x_height = x.height
+ end
+ end
+ --
+ end
+ --
+ if metadata.sup then
+ local dummy = { 0, 0, 0 }
+ parameters[ 1] = metadata.designsize or 0
+ parameters[ 2] = metadata.checksum or 0
+ parameters[ 3],
+ parameters[ 4],
+ parameters[ 5] = unpack(metadata.space or dummy)
+ parameters[ 6] = metadata.quad or 0
+ parameters[ 7] = metadata.extraspace or 0
+ parameters[ 8],
+ parameters[ 9],
+ parameters[10] = unpack(metadata.num or dummy)
+ parameters[11],
+ parameters[12] = unpack(metadata.denom or dummy)
+ parameters[13],
+ parameters[14],
+ parameters[15] = unpack(metadata.sup or dummy)
+ parameters[16],
+ parameters[17] = unpack(metadata.sub or dummy)
+ parameters[18] = metadata.supdrop or 0
+ parameters[19] = metadata.subdrop or 0
+ parameters[20],
+ parameters[21] = unpack(metadata.delim or dummy)
+ parameters[22] = metadata.axisheight or 0
+ end
+ --
+ parameters.designsize = (metadata.designsize or 10)*65536
+ parameters.ascender = abs(metadata.ascender or 0)
+ parameters.descender = abs(metadata.descender or 0)
+ parameters.units = 1000
+ --
+ properties.spacer = spacer
+ properties.encodingbytes = 2
+ properties.format = fonts.formats[filename] or "type1"
+ properties.filename = filename
+ properties.fontname = fontname
+ properties.fullname = fullname
+ properties.psname = fullname
+ properties.name = filename or fullname or fontname
+ properties.private = properties.private or data.private or privateoffset
+ --
+ if next(characters) then
+ return {
+ characters = characters,
+ descriptions = descriptions,
+ parameters = parameters,
+ resources = resources,
+ properties = properties,
+ goodies = goodies,
+ }
+ end
+ end
+ return nil
+end
+
+--[[ldx--
+<p>Originally we had features kind of hard coded for <l n='afm'/> files but since I
+expect to support more font formats, I decided to treat this fontformat like any
+other and handle features in a more configurable way.</p>
+--ldx]]--
+
+function afm.setfeatures(tfmdata,features)
+ local okay = constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm)
+ if okay then
+ return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm)
+ else
+ return { } -- will become false
+ end
+end
+
+local function addtables(data)
+ local resources = data.resources
+ local lookuptags = resources.lookuptags
+ local unicodes = resources.unicodes
+ if not lookuptags then
+ lookuptags = { }
+ resources.lookuptags = lookuptags
+ end
+ setmetatableindex(lookuptags,function(t,k)
+ local v = type(k) == "number" and ("lookup " .. k) or k
+ t[k] = v
+ return v
+ end)
+ if not unicodes then
+ unicodes = { }
+ resources.unicodes = unicodes
+ setmetatableindex(unicodes,function(t,k)
+ setmetatableindex(unicodes,nil)
+ for u, d in next, data.descriptions do
+ local n = d.name
+ if n then
+ t[n] = u
+ end
+ end
+ return rawget(t,k)
+ end)
+ end
+ constructors.addcoreunicodes(unicodes) -- do we really need this?
+end
+
+local function afmtotfm(specification)
+ local afmname = specification.filename or specification.name
+ if specification.forced == "afm" or specification.format == "afm" then -- move this one up
+ if trace_loading then
+ report_afm("forcing afm format for %a",afmname)
+ end
+ else
+ local tfmname = findbinfile(afmname,"ofm") or ""
+ if tfmname ~= "" then
+ if trace_loading then
+ report_afm("fallback from afm to tfm for %a",afmname)
+ end
+ return -- just that
+ end
+ end
+ if afmname ~= "" then
+ -- weird, isn't this already done then?
+ local features = constructors.checkedfeatures("afm",specification.features.normal)
+ specification.features.normal = features
+ constructors.hashinstance(specification,true) -- also weird here
+ --
+ specification = definers.resolve(specification) -- new, was forgotten
+ local cache_id = specification.hash
+ local tfmdata = containers.read(constructors.cache, cache_id) -- cache with features applied
+ if not tfmdata then
+ local rawdata = afm.load(afmname)
+ if rawdata and next(rawdata) then
+ addtables(rawdata)
+ adddimensions(rawdata)
+ tfmdata = copytotfm(rawdata)
+ if tfmdata and next(tfmdata) then
+ local shared = tfmdata.shared
+ if not shared then
+ shared = { }
+ tfmdata.shared = shared
+ end
+ shared.rawdata = rawdata
+ shared.dynamics = { }
+ tfmdata.changed = { }
+ shared.features = features
+ shared.processes = afm.setfeatures(tfmdata,features)
+ end
+ elseif trace_loading then
+ report_afm("no (valid) afm file found with name %a",afmname)
+ end
+ tfmdata = containers.write(constructors.cache,cache_id,tfmdata)
+ end
+ return tfmdata
+ end
+end
+
+--[[ldx--
+<p>As soon as we could intercept the <l n='tfm'/> reader, I implemented an
+<l n='afm'/> reader. Since traditional <l n='pdftex'/> could use <l n='opentype'/>
+fonts with <l n='afm'/> companions, the following method also could handle
+those cases, but now that we can handle <l n='opentype'/> directly we no longer
+need this features.</p>
+--ldx]]--
+
+local function read_from_afm(specification)
+ local tfmdata = afmtotfm(specification)
+ if tfmdata then
+ tfmdata.properties.name = specification.name
+ tfmdata = constructors.scale(tfmdata, specification)
+ local allfeatures = tfmdata.shared.features or specification.features.normal
+ constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm)
+ fonts.loggers.register(tfmdata,'afm',specification)
+ end
+ return tfmdata
+end
+
+--[[ldx--
+<p>We have the usual two modes and related features initializers and processors.</p>
+--ldx]]--
+
+registerafmfeature {
+ name = "mode",
+ description = "mode",
+ initializers = {
+ base = otf.modeinitializer,
+ node = otf.modeinitializer,
+ }
+}
+
+registerafmfeature {
+ name = "features",
+ description = "features",
+ default = true,
+ initializers = {
+ node = otf.nodemodeinitializer,
+ base = otf.basemodeinitializer,
+ },
+ processors = {
+ node = otf.featuresprocessor,
+ }
+}
+
+-- readers
+
+fonts.formats.afm = "type1"
+fonts.formats.pfb = "type1"
+
+local function check_afm(specification,fullname)
+ local foundname = findbinfile(fullname, 'afm') or "" -- just to be sure
+ if foundname == "" then
+ foundname = fonts.names.getfilename(fullname,"afm") or ""
+ end
+ if fullname and foundname == "" and afm.autoprefixed then
+ local encoding, shortname = match(fullname,"^(.-)%-(.*)$") -- context: encoding-name.*
+ if encoding and shortname and fonts.encodings.known[encoding] then
+ shortname = findbinfile(shortname,'afm') or "" -- just to be sure
+ if shortname ~= "" then
+ foundname = shortname
+ if trace_defining then
+ report_afm("stripping encoding prefix from filename %a",afmname)
+ end
+ end
+ end
+ end
+ if foundname ~= "" then
+ specification.filename = foundname
+ specification.format = "afm"
+ return read_from_afm(specification)
+ end
+end
+
+function readers.afm(specification,method)
+ local fullname = specification.filename or ""
+ local tfmdata = nil
+ if fullname == "" then
+ local forced = specification.forced or ""
+ if forced ~= "" then
+ tfmdata = check_afm(specification,specification.name .. "." .. forced)
+ end
+ if not tfmdata then
+ local check_tfm = readers.check_tfm
+ method = (check_tfm and (method or definers.method or "afm or tfm")) or "afm"
+ if method == "tfm" then
+ tfmdata = check_tfm(specification,specification.name)
+ elseif method == "afm" then
+ tfmdata = check_afm(specification,specification.name)
+ elseif method == "tfm or afm" then
+ tfmdata = check_tfm(specification,specification.name) or check_afm(specification,specification.name)
+ else -- method == "afm or tfm" or method == "" then
+ tfmdata = check_afm(specification,specification.name) or check_tfm(specification,specification.name)
+ end
+ end
+ else
+ tfmdata = check_afm(specification,fullname)
+ end
+ return tfmdata
+end
+
+function readers.pfb(specification,method) -- only called when forced
+ local original = specification.specification
+ if trace_defining then
+ report_afm("using afm reader for %a",original)
+ end
+ specification.forced = "afm"
+ local function swap(name)
+ local value = specification[swap]
+ if value then
+ specification[swap] = gsub("%.pfb",".afm",1)
+ end
+ end
+ swap("filename")
+ swap("fullname")
+ swap("forcedname")
+ swap("specification")
+ return readers.afm(specification,method)
+end
+
+-- now we register them
+
+registerafmenhancer("unify names", enhance_unify_names)
+registerafmenhancer("add ligatures", enhance_add_ligatures)
+registerafmenhancer("add extra kerns", enhance_add_extra_kerns)
+registerafmenhancer("normalize features", enhance_normalize_features)
+registerafmenhancer("check extra features", otfenhancers.enhance)
+registerafmenhancer("fix names", enhance_fix_names)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-onr.lua b/macros/luatex/generic/luaotfload/fontloader-font-onr.lua
new file mode 100644
index 0000000000..188aaf6449
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-onr.lua
@@ -0,0 +1,550 @@
+if not modules then modules = { } end modules ['font-onr'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>Some code may look a bit obscure but this has to do with the fact that we also use
+this code for testing and much code evolved in the transition from <l n='tfm'/> to
+<l n='afm'/> to <l n='otf'/>.</p>
+
+<p>The following code still has traces of intermediate font support where we handles
+font encodings. Eventually font encoding went away but we kept some code around in
+other modules.</p>
+
+<p>This version implements a node mode approach so that users can also more easily
+add features.</p>
+--ldx]]--
+
+local fonts, logs, trackers, resolvers = fonts, logs, trackers, resolvers
+
+local next, type, tonumber, rawget, rawset = next, type, tonumber, rawget, rawset
+local match, lower, gsub, strip, find = string.match, string.lower, string.gsub, string.strip, string.find
+local char, byte, sub = string.char, string.byte, string.sub
+local abs = math.abs
+local bxor, rshift = bit32.bxor, bit32.rshift
+local P, S, R, V, Cmt, C, Ct, Cs, Carg, Cf, Cg, Cc = lpeg.P, lpeg.S, lpeg.R, lpeg.V, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg, lpeg.Cf, lpeg.Cg, lpeg.Cc
+local lpegmatch, patterns = lpeg.match, lpeg.patterns
+
+local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end)
+local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end)
+
+local report_afm = logs.reporter("fonts","afm loading")
+local report_pfb = logs.reporter("fonts","pfb loading")
+
+local handlers = fonts.handlers
+local afm = handlers.afm or { }
+handlers.afm = afm
+local readers = afm.readers or { }
+afm.readers = readers
+
+afm.version = 1.513 -- incrementing this number one up will force a re-cache
+
+--[[ldx--
+<p>We start with the basic reader which we give a name similar to the built in <l n='tfm'/>
+and <l n='otf'/> reader.</p>
+<p>We use a new (unfinished) pfb loader but I see no differences between the old
+and new vectors (we actually had one bad vector with the old loader).</p>
+--ldx]]--
+
+local get_indexes, get_shapes
+
+do
+
+ local decrypt
+
+ do
+
+ local r, c1, c2, n = 0, 0, 0, 0
+
+ local function step(c)
+ local cipher = byte(c)
+ local plain = bxor(cipher,rshift(r,8))
+ r = ((cipher + r) * c1 + c2) % 65536
+ return char(plain)
+ end
+
+ decrypt = function(binary,initial,seed)
+ r, c1, c2, n = initial, 52845, 22719, seed
+ binary = gsub(binary,".",step)
+ return sub(binary,n+1)
+ end
+
+ -- local pattern = Cs((P(1) / step)^1)
+ --
+ -- decrypt = function(binary,initial,seed)
+ -- r, c1, c2, n = initial, 52845, 22719, seed
+ -- binary = lpegmatch(pattern,binary)
+ -- return sub(binary,n+1)
+ -- end
+
+ end
+
+ local charstrings = P("/CharStrings")
+ local subroutines = P("/Subrs")
+ local encoding = P("/Encoding")
+ local dup = P("dup")
+ local put = P("put")
+ local array = P("array")
+ local name = P("/") * C((R("az","AZ","09")+S("-_."))^1)
+ local digits = R("09")^1
+ local cardinal = digits / tonumber
+ local spaces = P(" ")^1
+ local spacing = patterns.whitespace^0
+
+ local routines, vector, chars, n, m
+
+ local initialize = function(str,position,size)
+ n = 0
+ m = size
+ return position + 1
+ end
+
+ local setroutine = function(str,position,index,size,filename)
+ if routines[index] then
+ -- we have passed the end
+ return false
+ end
+ local forward = position + size
+ local stream = decrypt(sub(str,position+1,forward),4330,4)
+ routines[index] = { byte(stream,1,#stream) }
+ n = n + 1
+ if n >= m then
+ -- m should be index now but can we assume ordering?
+ return #str
+ end
+ return forward + 1
+ end
+
+ local setvector = function(str,position,name,size,filename)
+ local forward = position + tonumber(size)
+ if n >= m then
+ return #str
+ elseif forward < #str then
+ if n == 0 and name ~= ".notdef" then
+ report_pfb("reserving .notdef at index 0 in %a",filename) -- luatex needs that
+ n = n + 1
+ end
+ vector[n] = name
+ n = n + 1
+ return forward
+ else
+ return #str
+ end
+ end
+
+ local setshapes = function(str,position,name,size,filename)
+ local forward = position + tonumber(size)
+ local stream = sub(str,position+1,forward)
+ if n > m then
+ return #str
+ elseif forward < #str then
+ if n == 0 and name ~= ".notdef" then
+ report_pfb("reserving .notdef at index 0 in %a",filename) -- luatex needs that
+ n = n + 1
+ end
+ vector[n] = name
+ n = n + 1
+ chars [n] = decrypt(stream,4330,4)
+ return forward
+ else
+ return #str
+ end
+ end
+
+ local p_rd = spacing * (P("RD") + P("-|"))
+ local p_np = spacing * (P("NP") + P( "|"))
+ local p_nd = spacing * (P("ND") + P( "|"))
+
+ local p_filterroutines = -- dup <i> <n> RD or -| <n encrypted bytes> NP or |
+ (1-subroutines)^0 * subroutines * spaces * Cmt(cardinal,initialize)
+ * (Cmt(cardinal * spaces * cardinal * p_rd * Carg(1), setroutine) * p_np + (1-p_nd))^1
+
+ local p_filtershapes = -- /foo <n> RD <n encrypted bytes> ND
+ (1-charstrings)^0 * charstrings * spaces * Cmt(cardinal,initialize)
+ * (Cmt(name * spaces * cardinal * p_rd * Carg(1) , setshapes) * p_nd + P(1))^1
+
+ local p_filternames = Ct (
+ (1-charstrings)^0 * charstrings * spaces * Cmt(cardinal,initialize)
+ * (Cmt(name * spaces * cardinal * Carg(1), setvector) + P(1))^1
+ )
+
+ -- /Encoding 256 array
+ -- 0 1 255 {1 index exch /.notdef put} for
+ -- dup 0 /Foo put
+
+ local p_filterencoding =
+ (1-encoding)^0 * encoding * spaces * digits * spaces * array * (1-dup)^0
+ * Cf(
+ Ct("") * Cg(spacing * dup * spaces * cardinal * spaces * name * spaces * put)^1
+ ,rawset)
+
+ -- if one of first 4 not 0-9A-F then binary else hex
+
+ local key = spacing * P("/") * R("az","AZ")
+ local str = spacing * Cs { (P("(")/"") * ((1 - P("\\(") - P("\\)") - S("()")) + V(1))^0 * (P(")")/"") }
+ local num = spacing * (R("09") + S("+-."))^1 / tonumber
+ local arr = spacing * Ct (S("[{") * (num)^0 * spacing * S("]}"))
+ local boo = spacing * (P("true") * Cc(true) + P("false") * Cc(false))
+ local nam = spacing * P("/") * Cs(R("az","AZ")^1)
+
+ local p_filtermetadata = (
+ P("/") * Carg(1) * ( (
+ C("version") * str
+ + C("Copyright") * str
+ + C("Notice") * str
+ + C("FullName") * str
+ + C("FamilyName") * str
+ + C("Weight") * str
+ + C("ItalicAngle") * num
+ + C("isFixedPitch") * boo
+ + C("UnderlinePosition") * num
+ + C("UnderlineThickness") * num
+ + C("FontName") * nam
+ + C("FontMatrix") * arr
+ + C("FontBBox") * arr
+ ) ) / function(t,k,v) t[lower(k)] = v end
+ + P(1)
+ )^0 * Carg(1)
+
+ local function loadpfbvector(filename,shapestoo,streams)
+ -- for the moment limited to encoding only
+
+ local data = io.loaddata(resolvers.findfile(filename))
+
+ if not data then
+ report_pfb("no data in %a",filename)
+ return
+ end
+
+ if not (find(data,"!PS-AdobeFont-",1,true) or find(data,"%!FontType1",1,true)) then
+ report_pfb("no font in %a",filename)
+ return
+ end
+
+ local ascii, binary = match(data,"(.*)eexec%s+......(.*)")
+
+ if not binary then
+ report_pfb("no binary data in %a",filename)
+ return
+ end
+
+ binary = decrypt(binary,55665,4)
+
+ local names = { }
+ local encoding = lpegmatch(p_filterencoding,ascii)
+ local metadata = lpegmatch(p_filtermetadata,ascii,1,{})
+ local glyphs = { }
+
+ routines, vector, chars = { }, { }, { }
+ if shapestoo or streams then
+ -- io.savedata("foo.txt",binary)
+ lpegmatch(p_filterroutines,binary,1,filename)
+ lpegmatch(p_filtershapes,binary,1,filename)
+ local data = {
+ dictionaries = {
+ {
+ charstrings = chars,
+ charset = vector,
+ subroutines = routines,
+ }
+ },
+ }
+ -- only cff 1 in type 1 fonts
+ fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,"cff",streams,true)
+ else
+ lpegmatch(p_filternames,binary,1,filename)
+ end
+
+ names = vector
+
+ routines, vector, chars = nil, nil, nil
+
+ return names, encoding, glyphs, metadata
+
+ end
+
+ local pfb = handlers.pfb or { }
+ handlers.pfb = pfb
+ pfb.loadvector = loadpfbvector
+
+ get_indexes = function(data,pfbname)
+ local vector = loadpfbvector(pfbname)
+ if vector then
+ local characters = data.characters
+ if trace_loading then
+ report_afm("getting index data from %a",pfbname)
+ end
+ for index=0,#vector do -- hm, zero, often space or notdef
+ local name = vector[index]
+ local char = characters[name]
+ if char then
+ if trace_indexing then
+ report_afm("glyph %a has index %a",name,index)
+ end
+ char.index = index
+ else
+ if trace_indexing then
+ report_afm("glyph %a has index %a but no data",name,index)
+ end
+ end
+ end
+ end
+ end
+
+ get_shapes = function(pfbname)
+ local vector, encoding, glyphs = loadpfbvector(pfbname,true)
+ return glyphs
+ end
+
+end
+
+--[[ldx--
+<p>We start with the basic reader which we give a name similar to the built in <l n='tfm'/>
+and <l n='otf'/> reader. We only need data that is relevant for our use. We don't support
+more complex arrangements like multiple master (obsolete), direction specific kerning, etc.</p>
+--ldx]]--
+
+local spacer = patterns.spacer
+local whitespace = patterns.whitespace
+local lineend = patterns.newline
+local spacing = spacer^0
+local number = spacing * S("+-")^-1 * (R("09") + S("."))^1 / tonumber
+local name = spacing * C((1 - whitespace)^1)
+local words = spacing * ((1 - lineend)^1 / strip)
+local rest = (1 - lineend)^0
+local fontdata = Carg(1)
+local semicolon = spacing * P(";")
+local plus = spacing * P("plus") * number
+local minus = spacing * P("minus") * number
+
+-- kern pairs
+
+local function addkernpair(data,one,two,value)
+ local chr = data.characters[one]
+ if chr then
+ local kerns = chr.kerns
+ if kerns then
+ kerns[two] = tonumber(value)
+ else
+ chr.kerns = { [two] = tonumber(value) }
+ end
+ end
+end
+
+local p_kernpair = (fontdata * P("KPX") * name * name * number) / addkernpair
+
+-- char metrics
+
+local chr = false
+local ind = 0
+
+local function start(data,version)
+ data.metadata.afmversion = version
+ ind = 0
+ chr = { }
+end
+
+local function stop()
+ ind = 0
+ chr = false
+end
+
+local function setindex(i)
+ if i < 0 then
+ ind = ind + 1 -- ?
+ else
+ ind = i
+ end
+ chr = {
+ index = ind
+ }
+end
+
+local function setwidth(width)
+ chr.width = width
+end
+
+local function setname(data,name)
+ data.characters[name] = chr
+end
+
+local function setboundingbox(boundingbox)
+ chr.boundingbox = boundingbox
+end
+
+local function setligature(plus,becomes)
+ local ligatures = chr.ligatures
+ if ligatures then
+ ligatures[plus] = becomes
+ else
+ chr.ligatures = { [plus] = becomes }
+ end
+end
+
+local p_charmetric = ( (
+ P("C") * number / setindex
+ + P("WX") * number / setwidth
+ + P("N") * fontdata * name / setname
+ + P("B") * Ct((number)^4) / setboundingbox
+ + P("L") * (name)^2 / setligature
+ ) * semicolon )^1
+
+local p_charmetrics = P("StartCharMetrics") * number * (p_charmetric + (1-P("EndCharMetrics")))^0 * P("EndCharMetrics")
+local p_kernpairs = P("StartKernPairs") * number * (p_kernpair + (1-P("EndKernPairs" )))^0 * P("EndKernPairs" )
+
+local function set_1(data,key,a) data.metadata[lower(key)] = a end
+local function set_2(data,key,a,b) data.metadata[lower(key)] = { a, b } end
+local function set_3(data,key,a,b,c) data.metadata[lower(key)] = { a, b, c } end
+
+-- Notice string
+-- EncodingScheme string
+-- MappingScheme integer
+-- EscChar integer
+-- CharacterSet string
+-- Characters integer
+-- IsBaseFont boolean
+-- VVector number number
+-- IsFixedV boolean
+
+local p_parameters = P(false)
+ + fontdata
+ * ((P("FontName") + P("FullName") + P("FamilyName"))/lower)
+ * words / function(data,key,value)
+ data.metadata[key] = value
+ end
+ + fontdata
+ * ((P("Weight") + P("Version"))/lower)
+ * name / function(data,key,value)
+ data.metadata[key] = value
+ end
+ + fontdata
+ * P("IsFixedPitch")
+ * name / function(data,pitch)
+ data.metadata.monospaced = toboolean(pitch,true)
+ end
+ + fontdata
+ * P("FontBBox")
+ * Ct(number^4) / function(data,boundingbox)
+ data.metadata.boundingbox = boundingbox
+ end
+ + fontdata
+ * ((P("CharWidth") + P("CapHeight") + P("XHeight") + P("Descender") + P("Ascender") + P("ItalicAngle"))/lower)
+ * number / function(data,key,value)
+ data.metadata[key] = value
+ end
+ + P("Comment") * spacing * ( P(false)
+ + (fontdata * C("DESIGNSIZE") * number * rest) / set_1 -- 1
+ + (fontdata * C("TFM designsize") * number * rest) / set_1
+ + (fontdata * C("DesignSize") * number * rest) / set_1
+ + (fontdata * C("CODINGSCHEME") * words * rest) / set_1 --
+ + (fontdata * C("CHECKSUM") * number * words * rest) / set_1 -- 2
+ + (fontdata * C("SPACE") * number * plus * minus * rest) / set_3 -- 3 4 5
+ + (fontdata * C("QUAD") * number * rest) / set_1 -- 6
+ + (fontdata * C("EXTRASPACE") * number * rest) / set_1 -- 7
+ + (fontdata * C("NUM") * number * number * number * rest) / set_3 -- 8 9 10
+ + (fontdata * C("DENOM") * number * number * rest) / set_2 -- 11 12
+ + (fontdata * C("SUP") * number * number * number * rest) / set_3 -- 13 14 15
+ + (fontdata * C("SUB") * number * number * rest) / set_2 -- 16 17
+ + (fontdata * C("SUPDROP") * number * rest) / set_1 -- 18
+ + (fontdata * C("SUBDROP") * number * rest) / set_1 -- 19
+ + (fontdata * C("DELIM") * number * number * rest) / set_2 -- 20 21
+ + (fontdata * C("AXISHEIGHT") * number * rest) / set_1 -- 22
+ )
+
+local fullparser = ( P("StartFontMetrics") * fontdata * name / start )
+ * ( p_charmetrics + p_kernpairs + p_parameters + (1-P("EndFontMetrics")) )^0
+ * ( P("EndFontMetrics") / stop )
+
+local infoparser = ( P("StartFontMetrics") * fontdata * name / start )
+ * ( p_parameters + (1-P("EndFontMetrics")) )^0
+ * ( P("EndFontMetrics") / stop )
+
+-- infoparser = ( P("StartFontMetrics") * fontdata * name / start )
+-- * ( p_parameters + (1-P("EndFontMetrics") - P("StartCharMetrics")) )^0
+-- * ( (P("EndFontMetrics") + P("StartCharMetrics")) / stop )
+
+local function read(filename,parser)
+ local afmblob = io.loaddata(filename)
+ if afmblob then
+ local data = {
+ resources = {
+ filename = resolvers.unresolve(filename),
+ version = afm.version,
+ creator = "context mkiv",
+ },
+ properties = {
+ hasitalics = false,
+ },
+ goodies = {
+ },
+ metadata = {
+ filename = file.removesuffix(file.basename(filename))
+ },
+ characters = {
+ -- a temporary store
+ },
+ descriptions = {
+ -- the final store
+ },
+ }
+ if trace_loading then
+ report_afm("parsing afm file %a",filename)
+ end
+ lpegmatch(parser,afmblob,1,data)
+ return data
+ else
+ if trace_loading then
+ report_afm("no valid afm file %a",filename)
+ end
+ return nil
+ end
+end
+
+function readers.loadfont(afmname,pfbname)
+ local data = read(resolvers.findfile(afmname),fullparser)
+ if data then
+ if not pfbname or pfbname == "" then
+ pfbname = resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb"))
+ end
+ if pfbname and pfbname ~= "" then
+ data.resources.filename = resolvers.unresolve(pfbname)
+ get_indexes(data,pfbname)
+ return data
+ else -- if trace_loading then
+ report_afm("no pfb file for %a",afmname)
+ -- better than loading the afm file: data.resources.filename = rawname
+ -- but that will still crash the backend so we just return nothing now
+ end
+ end
+end
+
+-- for now, todo: n and check with otf (no afm needed here)
+
+function readers.loadshapes(filename)
+ local fullname = resolvers.findfile(filename) or ""
+ if fullname == "" then
+ return {
+ filename = "not found: " .. filename,
+ glyphs = { }
+ }
+ else
+ return {
+ filename = fullname,
+ format = "opentype",
+ glyphs = get_shapes(fullname) or { },
+ units = 1000,
+ }
+ end
+end
+
+
+function readers.getinfo(filename)
+ local data = read(resolvers.findfile(filename),infoparser)
+ if data then
+ return data.metadata
+ end
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-osd.lua b/macros/luatex/generic/luaotfload/fontloader-font-osd.lua
new file mode 100644
index 0000000000..203c1d79d4
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-osd.lua
@@ -0,0 +1,2859 @@
+if not modules then modules = { } end modules ['font-osd'] = { -- script devanagari
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Kai Eigner, TAT Zetwerk / Hans Hagen, PRAGMA ADE",
+ copyright = "TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+
+-- we need to check nbsphash (context only)
+
+-- A few remarks:
+--
+-- This code is a partial rewrite of the code that deals with devanagari. The data
+-- and logic is by Kai Eigner and based based on Microsoft's OpenType specifications
+-- for specific scripts, but with a few improvements. More information can be found
+-- at:
+--
+-- deva: http://www.microsoft.com/typography/OpenType%20Dev/devanagari/introO.mspx
+-- dev2: http://www.microsoft.com/typography/OpenType%20Dev/devanagari/intro.mspx
+--
+-- Rajeesh Nambiar provided patches for the malayalam variant. Thanks to feedback
+-- from the mailing list some aspects could be improved.
+--
+-- As I touched nearly all code, reshuffled it, optimized a lot, etc. etc. (imagine
+-- how much can get messed up in over a week work) it could be that I introduced
+-- bugs. There is more to gain (esp in the functions applied to a range) but I'll do
+-- that when everything works as expected. Kai's original code is kept in
+-- font-odk.lua as a reference so blame me (HH) for bugs. (We no longer ship that
+-- file as the code below has diverted too much and in the meantime has more than
+-- doubled in size.)
+--
+-- Interesting is that Kai managed to write this on top of the existing otf handler.
+-- Only a few extensions were needed, like a few more analyzing states and dealing
+-- with changed head nodes in the core scanner as that only happens here. There's a
+-- lot going on here and it's only because I touched nearly all code that I got a
+-- bit of a picture of what happens. For in-depth knowledge one needs to consult
+-- Kai.
+--
+-- The rewrite mostly deals with efficiency, both in terms of speed and code. We
+-- also made sure that it suits generic use as well as use in ConTeXt. I removed
+-- some buglets but can as well have messed up the logic by doing this. For this we
+-- keep the original around as that serves as reference. Due to the lots of
+-- reshuffling glyphs quite some leaks occur(red) but once I'm satisfied with the
+-- rewrite I'll weed them. I also integrated initialization etc into the regular
+-- mechanisms.
+--
+-- In the meantime, we're down from 25.5-3.5=22 seconds to 17.7-3.5=14.2 seconds for
+-- a 100 page sample (mid 2012) with both variants so it's worth the effort. Some
+-- more speedup is to be expected. Due to the method chosen it will never be real
+-- fast. If I ever become a power user I'll have a go at some further speed up. I
+-- will rename some functions (and features) once we don't need to check the
+-- original code. We now use a special subset sequence for use inside the analyzer
+-- (after all we could can store this in the dataset and save redundant analysis).
+--
+-- By now we have yet another incremental improved version. In the end I might
+-- rewrite the code.
+--
+-- Hans Hagen, PRAGMA-ADE, Hasselt NL
+
+-- Todo:
+--
+-- Matras: according to Microsoft typography specifications "up to one of each type:
+-- pre-, above-, below- or post- base", but that does not seem to be right. It could
+-- become an option.
+--
+-- Resources:
+--
+-- The tables that we had here are now generated from char-def.lua or in the case of
+-- generic usage loaded from luatex-basics-chr.lua. Still a couple of entries need
+-- to be added to char-def.lua but finally I moved the indic specific tables there.
+-- For generic usage one can create the relevant resources by running:
+--
+-- context luatex-basics-prepare.tex
+--
+-- and an overview with:
+--
+-- context --global s-fonts-basics.mkiv
+--
+-- For now we have defined: bengali, devanagari, gujarati, gurmukhi, kannada,
+-- malayalam, oriya, tamil and tolugu but not all are checked. Also, some of the
+-- code below might need to be adapted to the extra scripts.
+
+local insert, imerge, copy, tohash = table.insert, table.imerge, table.copy, table.tohash
+local next, type = next, type
+
+local report = logs.reporter("otf","devanagari")
+
+fonts = fonts or { }
+fonts.analyzers = fonts.analyzers or { }
+fonts.analyzers.methods = fonts.analyzers.methods or { node = { otf = { } } }
+
+local otf = fonts.handlers.otf
+
+local handlers = otf.handlers
+local methods = fonts.analyzers.methods
+
+local otffeatures = fonts.constructors.features.otf
+local registerotffeature = otffeatures.register
+
+local nuts = nodes.nuts
+
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getboth = nuts.getboth
+local getid = nuts.getid
+local getchar = nuts.getchar
+local getfont = nuts.getfont
+local getsubtype = nuts.getsubtype
+local setlink = nuts.setlink
+local setnext = nuts.setnext
+local setprev = nuts.setprev
+local setchar = nuts.setchar
+local getprop = nuts.getprop
+local setprop = nuts.setprop
+
+local ischar = nuts.ischar
+
+local insert_node_after = nuts.insert_after
+local copy_node = nuts.copy
+local remove_node = nuts.remove
+local flush_list = nuts.flush_list
+local flush_node = nuts.flush_node
+
+local copyinjection = nodes.injections.copy -- KE: is this necessary? HH: probably not as positioning comes later and we rawget/set
+
+local unsetvalue = attributes.unsetvalue
+
+local fontdata = fonts.hashes.identifiers
+
+local a_state = attributes.private('state')
+local a_syllabe = attributes.private('syllabe')
+
+local dotted_circle = 0x25CC
+local c_nbsp = 0x00A0
+local c_zwnj = 0x200C
+local c_zwj = 0x200D
+
+local states = fonts.analyzers.states -- not features
+
+local s_rphf = states.rphf
+local s_half = states.half
+local s_pref = states.pref
+local s_blwf = states.blwf
+local s_pstf = states.pstf
+local s_init = states.init
+
+local replace_all_nbsp = nil
+
+replace_all_nbsp = function(head) -- delayed definition
+ replace_all_nbsp = typesetters and typesetters.characters and typesetters.characters.replacenbspaces or function(head)
+ return head
+ end
+ return replace_all_nbsp(head)
+end
+
+local processcharacters = nil
+
+if context then
+ local fontprocesses = fonts.hashes.processes
+ function processcharacters(head,font)
+ local processors = fontprocesses[font]
+ for i=1,#processors do
+ head = processors[i](head,font,0)
+ end
+ return head
+ end
+else
+ function processcharacters(head,font)
+ local processors = fontdata[font].shared.processes
+ for i=1,#processors do
+ head = processors[i](head,font,0)
+ end
+ return head
+ end
+end
+
+-- We can assume that script are not mixed in the source but if that is the case
+-- we might need to have consonants etc per script and initialize a local table
+-- pointing to the right one. But not now.
+
+local indicgroups = characters and characters.indicgroups
+
+if not indicgroups and characters then
+
+ local indic = {
+ c = { }, -- consonant
+ i = { }, -- independent vowel
+ d = { }, -- dependent vowel
+ m = { }, -- vowel modifier
+ s = { }, -- stress tone mark
+ o = { }, -- other
+ }
+
+ local indicmarks = {
+ l = { }, -- left | pre_mark
+ t = { }, -- top | above_mark
+ b = { }, -- bottom | below_mark
+ r = { }, -- right | post_mark
+ s = { }, -- split | twopart_mark
+ }
+
+ local indicclasses = {
+ nukta = { },
+ halant = { },
+ ra = { },
+ anudatta = { },
+ }
+
+ local indicorders = {
+ bp = { }, -- before_postscript
+ ap = { }, -- after_postscript
+ bs = { }, -- before_subscript
+ as = { }, -- after_subscript
+ bh = { }, -- before_half
+ ah = { }, -- after_half
+ bm = { }, -- before_main
+ am = { }, -- after_main
+ }
+
+ for k, v in next, characters.data do
+ local i = v.indic
+ if i then
+ indic[i][k] = true
+ i = v.indicmark
+ if i then
+ if i == "s" then
+ local s = v.specials
+ indicmarks[i][k] = { s[2], s[3] }
+ else
+ indicmarks[i][k] = true
+ end
+ end
+ i = v.indicclass
+ if i then
+ indicclasses[i][k] = true
+ end
+ i = v.indicorder
+ if i then
+ indicorders[i][k] = true
+ end
+ end
+ end
+
+ indicgroups = {
+ consonant = indic.c,
+ independent_vowel = indic.i,
+ dependent_vowel = indic.d,
+ vowel_modifier = indic.m,
+ stress_tone_mark = indic.s,
+ -- other = indic.o,
+ pre_mark = indicmarks.l,
+ above_mark = indicmarks.t,
+ below_mark = indicmarks.b,
+ post_mark = indicmarks.r,
+ twopart_mark = indicmarks.s,
+ nukta = indicclasses.nukta,
+ halant = indicclasses.halant,
+ ra = indicclasses.ra,
+ anudatta = indicclasses.anudatta,
+ before_postscript = indicorders.bp,
+ after_postscript = indicorders.ap,
+ before_half = indicorders.bh,
+ after_half = indicorders.ah,
+ before_subscript = indicorders.bs,
+ after_subscript = indicorders.as,
+ before_main = indicorders.bm,
+ after_main = indicorders.am,
+ }
+
+ indic = nil
+ indicmarks = nil
+ indicclasses = nil
+ indicorders = nil
+
+ characters.indicgroups = indicgroups
+
+end
+
+local consonant = indicgroups.consonant
+local independent_vowel = indicgroups.independent_vowel
+local dependent_vowel = indicgroups.dependent_vowel
+local vowel_modifier = indicgroups.vowel_modifier
+local stress_tone_mark = indicgroups.stress_tone_mark
+local pre_mark = indicgroups.pre_mark
+local above_mark = indicgroups.above_mark
+local below_mark = indicgroups.below_mark
+local post_mark = indicgroups.post_mark
+local twopart_mark = indicgroups.twopart_mark
+local nukta = indicgroups.nukta
+local halant = indicgroups.halant
+local ra = indicgroups.ra
+local anudatta = indicgroups.anudatta
+
+local before_postscript = indicgroups.before_postscript
+local after_postscript = indicgroups.after_postscript
+local before_half = indicgroups.before_half
+local after_half = indicgroups.after_half
+local before_subscript = indicgroups.before_subscript
+local after_subscript = indicgroups.after_subscript
+local before_main = indicgroups.before_main
+local after_main = indicgroups.after_main
+
+local mark_four = table.merged (
+ pre_mark,
+ above_mark,
+ below_mark,
+ post_mark
+)
+
+local mark_above_below_post = table.merged (
+ above_mark,
+ below_mark,
+ post_mark
+)
+
+-- We use some pseudo features as we need to manipulate the nodelist based
+-- on information in the font as well as already applied features. We can
+-- probably replace some of the code below by injecting 'real' features
+-- using the extension mechanism.
+
+local zw_char = { -- both_joiners_true
+ [c_zwnj] = true,
+ [c_zwj ] = true,
+}
+
+local dflt_true = {
+ dflt = true,
+}
+
+local two_defaults = { }
+local one_defaults = { }
+
+local false_flags = { false, false, false, false }
+
+local sequence_reorder_matras = {
+ features = { dv01 = two_defaults },
+ flags = false_flags,
+ name = "dv01_reorder_matras",
+ order = { "dv01" },
+ type = "devanagari_reorder_matras",
+ nofsteps = 1,
+ steps = {
+ {
+ coverage = pre_mark,
+ }
+ }
+}
+
+local sequence_reorder_reph = {
+ features = { dv02 = two_defaults },
+ flags = false_flags,
+ name = "dv02_reorder_reph",
+ order = { "dv02" },
+ type = "devanagari_reorder_reph",
+ nofsteps = 1,
+ steps = {
+ {
+ coverage = { },
+ }
+ }
+}
+
+local sequence_reorder_pre_base_reordering_consonants = {
+ features = { dv03 = one_defaults },
+ flags = false_flags,
+ name = "dv03_reorder_pre_base_reordering_consonants",
+ order = { "dv03" },
+ type = "devanagari_reorder_pre_base_reordering_consonants",
+ nofsteps = 1,
+ steps = {
+ {
+ coverage = { },
+ }
+ }
+}
+
+local sequence_remove_joiners = {
+ features = { dv04 = one_defaults },
+ flags = false_flags,
+ name = "dv04_remove_joiners",
+ order = { "dv04" },
+ type = "devanagari_remove_joiners",
+ nofsteps = 1,
+ steps = {
+ {
+ coverage = zw_char, -- both_joiners_true
+ },
+ }
+}
+
+-- Looping over feature twice as efficient as looping over basic forms (some
+-- 350 checks instead of 750 for one font). This is something to keep an eye on
+-- as it might depends on the font. Not that it's a bottleneck.
+
+local basic_shaping_forms = {
+ akhn = true,
+ blwf = true,
+ cjct = true,
+ half = true,
+ nukt = true,
+ pref = true,
+ pstf = true,
+ rkrf = true,
+ rphf = true,
+ vatu = true,
+ locl = true,
+}
+
+local valid = {
+ abvs = true,
+ akhn = true,
+ blwf = true,
+ calt = true,
+ cjct = true,
+ half = true,
+ haln = true,
+ nukt = true,
+ pref = true,
+ pres = true,
+ pstf = true,
+ psts = true,
+ rkrf = true,
+ rphf = true,
+ vatu = true,
+ pres = true,
+ abvs = true,
+ blws = true,
+ psts = true,
+ haln = true,
+ calt = true,
+ locl = true,
+}
+
+local scripts = { }
+
+local scripts_one = { "deva", "mlym", "beng", "gujr", "guru", "knda", "orya", "taml", "telu" }
+local scripts_two = { "dev2", "mlm2", "bng2", "gjr2", "gur2", "knd2", "ory2", "tml2", "tel2" }
+
+local nofscripts = #scripts_one
+
+for i=1,nofscripts do
+ local one = scripts_one[i]
+ local two = scripts_two[i]
+ scripts[one] = true
+ scripts[two] = true
+ two_defaults[two] = dflt_true
+ one_defaults[one] = dflt_true
+ one_defaults[two] = dflt_true
+end
+
+local function valid_one(s) for i=1,nofscripts do if s[scripts_one[i]] then return true end end end
+local function valid_two(s) for i=1,nofscripts do if s[scripts_two[i]] then return true end end end
+
+local function initializedevanagi(tfmdata)
+ local script, language = otf.scriptandlanguage(tfmdata,attr) -- todo: take fast variant
+ if scripts[script] then
+ local resources = tfmdata.resources
+ local devanagari = resources.devanagari
+ if not devanagari then
+ --
+ report("adding devanagari features to font")
+ --
+ local gsubfeatures = resources.features.gsub
+ local sequences = resources.sequences
+ local sharedfeatures = tfmdata.shared.features
+ --
+ gsubfeatures["dv01"] = two_defaults -- reorder matras
+ gsubfeatures["dv02"] = two_defaults -- reorder reph
+ gsubfeatures["dv03"] = one_defaults -- reorder pre base reordering consonants
+ gsubfeatures["dv04"] = one_defaults -- remove joiners
+ --
+ local reorder_pre_base_reordering_consonants = copy(sequence_reorder_pre_base_reordering_consonants)
+ local reorder_reph = copy(sequence_reorder_reph)
+ local reorder_matras = copy(sequence_reorder_matras)
+ local remove_joiners = copy(sequence_remove_joiners)
+
+ local lastmatch = 0
+ for s=1,#sequences do -- classify chars and make sure basic_shaping_forms come first
+ local features = sequences[s].features
+ if features then
+ for k, v in next, features do
+ if k == "locl" then
+ local steps = sequences[s].steps
+ local nofsteps = sequences[s].nofsteps
+ for i=1,nofsteps do
+ local step = steps[i]
+ local coverage = step.coverage
+ if coverage then
+ for k, v in next, pre_mark do
+ local locl = coverage[k]
+ if locl then
+ if #locl > 0 then --contextchain; KE: is this right?
+ for j=1,#locl do
+ local ck = locl[j]
+ local f = ck[4]
+ local chainlookups = ck[6]
+ if chainlookups then
+ local chainlookup = chainlookups[f]
+ for j=1,#chainlookup do
+ local chainstep = chainlookup[j]
+ local steps = chainstep.steps
+ local nofsteps = chainstep.nofsteps
+ for i=1,nofsteps do
+ local step = steps[i]
+ local coverage = step.coverage
+ if coverage then
+ locl = coverage[k]
+ end
+ end
+ end
+ end
+ end
+ end
+ if locl then
+ reorder_matras.steps[1].coverage[locl] = true
+ end
+ end
+ end
+ end
+ end
+ end
+ if basic_shaping_forms[k] then
+ lastmatch = lastmatch + 1
+ if s ~= lastmatch then
+ table.insert(sequences, lastmatch, table.remove(sequences, s))
+ end
+ end
+ end
+ end
+ end
+ local insertindex = lastmatch + 1
+ --
+ if tfmdata.properties.language then
+ dflt_true[tfmdata.properties.language] = true
+ end
+ --
+ insert(sequences,insertindex,reorder_pre_base_reordering_consonants)
+ insert(sequences,insertindex,reorder_reph)
+ insert(sequences,insertindex,reorder_matras)
+ insert(sequences,insertindex,remove_joiners)
+ --
+ local blwfcache = { }
+ local vatucache = { }
+ local pstfcache = { }
+ local seqsubset = { }
+ local rephstep = {
+ coverage = { } -- will be adapted each work
+ }
+ local devanagari = {
+ reph = false,
+ vattu = false,
+ blwfcache = blwfcache,
+ vatucache = vatucache,
+ pstfcache = pstfcache,
+ seqsubset = seqsubset,
+ reorderreph = rephstep,
+
+ }
+ --
+ reorder_reph.steps = { rephstep }
+ --
+ local pre_base_reordering_consonants = { }
+ reorder_pre_base_reordering_consonants.steps[1].coverage = pre_base_reordering_consonants
+ --
+ resources.devanagari = devanagari
+ --
+ for s=1,#sequences do
+ local sequence = sequences[s]
+ local steps = sequence.steps
+ local nofsteps = sequence.nofsteps
+ local features = sequence.features
+ local has_rphf = features.rphf
+ local has_blwf = features.blwf
+ local has_vatu = features.vatu
+ local has_pstf = features.pstf
+ if has_rphf and has_rphf[script] then
+ devanagari.reph = true
+ elseif (has_blwf and has_blwf[script] ) or (has_vatu and has_vatu[script] ) then
+ devanagari.vattu = true
+ for i=1,nofsteps do
+ local step = steps[i]
+ local coverage = step.coverage
+ if coverage then
+ for k, v in next, coverage do
+ for h, w in next, halant do
+ if v[h] then
+ if not blwfcache[k] then
+ blwfcache[k] = v
+ end
+ end
+ if has_vatu and has_vatu[script] and not vatucache[k] then
+ vatucache[k] = v
+ end
+ end
+ end
+ end
+ end
+ elseif has_pstf and has_pstf[script] then
+ for i=1,nofsteps do
+ local step = steps[i]
+ local coverage = step.coverage
+ if coverage then
+ for k, v in next, coverage do
+ if not pstfcache[k] then
+ pstfcache[k] = v
+ end
+ end
+ for k, v in next, ra do
+ local r = coverage[k]
+ if r then
+ local found = false
+ if #r > 0 then -- contextchain; KE: is this right?
+ for j=1,#r do
+ local ck = r[j]
+ local f = ck[4]
+ local chainlookups = ck[6]
+ if chainlookups and chainlookups[f] then --KE: why is check for chainlookups[f] necessacy???
+ local chainlookup = chainlookups[f]
+ for j=1,#chainlookup do
+ local chainstep = chainlookup[j]
+ local steps = chainstep.steps
+ local nofsteps = chainstep.nofsteps
+ for i=1,nofsteps do
+ local step = steps[i]
+ local coverage = step.coverage
+ if coverage then
+ local h = coverage[k]
+ if h then
+ for k, v in next, h do
+ found = v and v.ligature
+ if found then
+ pre_base_reordering_consonants[found] = true
+ break
+ end
+ end
+ if found then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ else
+ for k, v in next, r do
+ found = v and v.ligature
+ if found then
+ pre_base_reordering_consonants[found] = true
+ break
+ end
+ end
+ end
+ if found then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ for kind, spec in next, features do
+ if valid[kind] and valid_two(spec)then
+ for i=1,nofsteps do
+ local step = steps[i]
+ local coverage = step.coverage
+ if coverage then
+ local reph, rephbase = false, false
+ if kind == "rphf" then
+ -- rphf acts on consonant + halant
+ for k, v in next, ra do
+ local r = coverage[k]
+ if r then
+ rephbase = k
+ local h = false
+ if #r > 0 then --contextchain; KE: is this right?
+ for j=1,#r do
+ local ck = r[j]
+ local f = ck[4]
+ local chainlookups = ck[6]
+ if chainlookups then
+ local chainlookup = chainlookups[f]
+ for j=1,#chainlookup do
+ local chainstep = chainlookup[j]
+ local steps = chainstep.steps
+ local nofsteps = chainstep.nofsteps
+ for i=1,nofsteps do
+ local step = steps[i]
+ local coverage = step.coverage
+ if coverage then
+ local r = coverage[k]
+ if r then
+ for k, v in next, halant do
+ local h = r[k]
+ if h then
+ reph = h.ligature or false
+ break
+ end
+ end
+ if h then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ else
+ for k, v in next, halant do
+ local h = r[k]
+ if h then
+ reph = h.ligature or false
+ break
+ end
+ end
+ end
+ if reph then
+ break
+ end
+ end
+ end
+ end
+ seqsubset[#seqsubset+1] = { kind, coverage, reph, rephbase }
+ end
+ end
+ end
+ if kind == "pref" then
+ local steps = sequence.steps
+ local nofsteps = sequence.nofsteps
+ for i=1,nofsteps do
+ local step = steps[i]
+ local coverage = step.coverage
+ if coverage then
+ for k, v in next, halant do
+ local h = coverage[k]
+ if h then
+ local found = false
+ if #h > 0 then -- contextchain; KE: is this right?
+ for j=1,#h do
+ local ck = h[j]
+ local f = ck[4]
+ local chainlookups = ck[6]
+ if chainlookups then
+ local chainlookup = chainlookups[f]
+ for j=1,#chainlookup do
+ local chainstep = chainlookup[j]
+ local steps = chainstep.steps
+ local nofsteps = chainstep.nofsteps
+ for i=1,nofsteps do
+ local step = steps[i]
+ local coverage = step.coverage
+ if coverage then
+ local h = coverage[k]
+ if h then
+ for k, v in next, h do
+ found = v and v.ligature
+ if found then
+ pre_base_reordering_consonants[found] = true
+ break
+ end
+ end
+ if found then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ else
+ for k, v in next, h do
+ found = v and v.ligature
+ if found then
+ pre_base_reordering_consonants[found] = true
+ break
+ end
+ end
+ end
+ if found then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ --
+ if two_defaults[script] then
+ sharedfeatures["dv01"] = true -- dv01_reorder_matras
+ sharedfeatures["dv02"] = true -- dv02_reorder_reph
+ sharedfeatures["dv03"] = true -- dv03_reorder_pre_base_reordering_consonants
+ sharedfeatures["dv04"] = true -- dv04_remove_joiners
+ elseif one_defaults[script] then
+ sharedfeatures["dv03"] = true -- dv03_reorder_pre_base_reordering_consonants
+ sharedfeatures["dv04"] = true -- dv04_remove_joiners
+ end
+ if script == "mlym" or script == "taml" then
+ devanagari.left_matra_before_base = true
+ end
+ end
+ end
+end
+
+registerotffeature {
+ name = "devanagari",
+ description = "inject additional features",
+ default = true,
+ initializers = {
+ node = initializedevanagi,
+ },
+}
+
+local show_syntax_errors = false
+
+local function inject_syntax_error(head,current,char)
+ local signal = copy_node(current)
+ copyinjection(signal,current)
+ if pre_mark[char] then
+ setchar(signal,dotted_circle)
+ else
+ setchar(current,dotted_circle)
+ end
+ return insert_node_after(head,current,signal)
+end
+
+-- hm, this is applied to one character:
+
+local function initialize_one(font,attr) -- we need a proper hook into the dataset initializer
+
+ local tfmdata = fontdata[font]
+ local datasets = otf.dataset(tfmdata,font,attr) -- don't we know this one?
+ local devanagaridata = datasets.devanagari
+
+ if not devanagaridata then
+
+ devanagaridata = {
+ reph = false,
+ vattu = false,
+ blwfcache = { },
+ vatucache = { },
+ pstfcache = { },
+ }
+ datasets.devanagari = devanagaridata
+ local resources = tfmdata.resources
+ local devanagari = resources.devanagari
+
+ for s=1,#datasets do
+ local dataset = datasets[s]
+ if dataset and dataset[1] then -- value
+ local kind = dataset[4]
+ if kind == "rphf" then
+ -- deva
+ devanagaridata.reph = true
+ elseif kind == "blwf" or kind == "vatu" then
+ -- deva
+ devanagaridata.vattu = true
+ -- dev2
+ devanagaridata.blwfcache = devanagari.blwfcache
+ devanagaridata.vatucache = devanagari.vatucache
+ devanagaridata.pstfcache = devanagari.pstfcache
+ end
+ end
+ end
+
+ end
+
+ return devanagaridata.reph, devanagaridata.vattu, devanagaridata.blwfcache, devanagaridata.vatucache, devanagaridata.pstfcache
+
+end
+
+local function contextchain(contexts, n)
+ local char = getchar(n)
+ for k=1,#contexts do
+ local ck = contexts[k]
+ local seq = ck[3]
+ local f = ck[4]
+ local l = ck[5]
+ if (l - f) == 1 and seq[f+1][char] then
+ local ok = true
+ local c = n
+ for i=l+1,#seq do
+ c = getnext(c)
+ if not c or not seq[i][ischar(c)] then
+ ok = false
+ break
+ end
+ end
+ if ok then
+ c = getprev(n)
+ for i=1,f-1 do
+ c = getprev(c)
+ if not c or not seq[f-i][ischar(c)] then
+ ok = false
+ end
+ end
+ end
+ if ok then
+ return true
+ end
+ end
+ end
+ return false
+end
+
+local function order_matras(c)
+ local cn = getnext(c)
+ local char = getchar(cn)
+ while dependent_vowel[char] do
+ local next = getnext(cn)
+ local cc = c
+ local cchar = getchar(cc)
+ while cc ~= cn do
+ if (above_mark[char] and (below_mark[cchar] or post_mark[cchar])) or (below_mark[char] and (post_mark[cchar])) then
+ local prev, next = getboth(cn)
+ if next then
+ setprev(next,prev)
+ end
+ -- todo: setlink
+ setnext(prev,next)
+ setnext(getprev(cc),cn)
+ setprev(cn,getprev(cc))
+ setnext(cn,cc)
+ setprev(cc,cn)
+ break
+ end
+ cc = getnext(cc)
+ cchar = getchar(cc)
+ end
+ cn = next
+ char = getchar(cn)
+ end
+end
+
+local function reorder_one(head,start,stop,font,attr,nbspaces)
+
+ local reph, vattu, blwfcache, vatucache, pstfcache = initialize_one(font,attr) -- todo: a hash[font]
+
+ local devanagari = fontdata[font].resources.devanagari
+ local current = start
+ local n = getnext(start)
+ local base = nil
+ local firstcons = nil
+ local lastcons = nil
+ local basefound = false
+
+ if reph and ra[getchar(start)] and halant[getchar(n)] then
+ -- if syllable starts with Ra + H and script has 'Reph' then exclude Reph
+ -- from candidates for base consonants
+ if n == stop then
+ return head, stop, nbspaces
+ end
+ if getchar(getnext(n)) == c_zwj then
+ current = start
+ else
+ current = getnext(n)
+ setprop(start,a_state,s_rphf)
+ end
+ end
+
+ if getchar(current) == c_nbsp then
+ -- Stand Alone cluster
+ if current == stop then
+ stop = getprev(stop)
+ head = remove_node(head,current)
+ flush_node(current)
+ return head, stop, nbspaces
+ else
+ nbspaces = nbspaces + 1
+ base = current
+ firstcons = current
+ lastcons = current
+ current = getnext(current)
+ if current ~= stop then
+ local char = getchar(current)
+ if nukta[char] then
+ current = getnext(current)
+ char = getchar(current)
+ end
+ if char == c_zwj and current ~= stop then
+ local next = getnext(current)
+ if next ~= stop and halant[getchar(next)] then
+ current = next
+ next = getnext(current)
+ local tmp = next and getnext(next) or nil -- needs checking
+ local changestop = next == stop
+ local tempcurrent = copy_node(next)
+ copyinjection(tempcurrent,next)
+ local nextcurrent = copy_node(current)
+ copyinjection(nextcurrent,current) -- KE: necessary? HH: probably not as positioning comes later and we rawget/set
+ setlink(tempcurrent,nextcurrent)
+ setprop(tempcurrent,a_state,s_blwf)
+ tempcurrent = processcharacters(tempcurrent,font)
+ setprop(tempcurrent,a_state,unsetvalue)
+ if getchar(next) == getchar(tempcurrent) then
+ flush_list(tempcurrent)
+ if show_syntax_errors then
+ head, current = inject_syntax_error(head,current,char)
+ end
+ else
+ setchar(current,getchar(tempcurrent)) -- we assumes that the result of blwf consists of one node
+ local freenode = getnext(current)
+ setlink(current,tmp)
+ flush_node(freenode)
+ flush_list(tempcurrent)
+ if changestop then
+ stop = current
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ while not basefound do
+ -- find base consonant
+ local char = getchar(current)
+ if consonant[char] then
+ setprop(current,a_state,s_half)
+ if not firstcons then
+ firstcons = current
+ end
+ lastcons = current
+ if not base then
+ base = current
+ elseif blwfcache[char] then
+ -- consonant has below-base form
+ setprop(current,a_state,s_blwf)
+ elseif pstfcache[char] then
+ -- consonant has post-base form
+ setprop(current,a_state,s_pstf)
+ else
+ base = current
+ end
+ end
+ basefound = current == stop
+ current = getnext(current)
+ end
+
+ if base ~= lastcons then
+ -- if base consonant is not last one then move halant from base consonant to last one
+ local np = base
+ local n = getnext(base)
+ local ch = getchar(n)
+ if nukta[ch] then
+ np = n
+ n = getnext(n)
+ ch = getchar(n)
+ end
+ if halant[ch] then
+ if lastcons ~= stop then
+ local ln = getnext(lastcons)
+ if nukta[getchar(ln)] then
+ lastcons = ln
+ end
+ end
+ -- local np = getprev(n)
+ local nn = getnext(n)
+ local ln = getnext(lastcons) -- what if lastcons is nn ?
+ setlink(np,nn)
+ setnext(lastcons,n)
+ if ln then
+ setprev(ln,n)
+ end
+ setnext(n,ln)
+ setprev(n,lastcons)
+ if lastcons == stop then
+ stop = n
+ end
+ end
+ end
+
+ n = getnext(start)
+ if n ~= stop and ra[getchar(start)] and halant[getchar(n)] and not zw_char[getchar(getnext(n))] then
+ -- if syllable starts with Ra + H then move this combination so that it follows either:
+ -- the post-base 'matra' (if any) or the base consonant
+ local matra = base
+ if base ~= stop then
+ local next = getnext(base)
+ if dependent_vowel[getchar(next)] then
+ matra = next
+ end
+ end
+ -- [sp][start][n][nn] [matra|base][?]
+ -- [matra|base][start] [n][?] [sp][nn]
+ local sp = getprev(start)
+ local nn = getnext(n)
+ local mn = getnext(matra)
+ setlink(sp,nn)
+ setlink(matra,start)
+ setlink(n,mn)
+ if head == start then
+ head = nn
+ end
+ start = nn
+ if matra == stop then
+ stop = n
+ end
+ end
+
+ local current = start
+ while current ~= stop do
+ local next = getnext(current)
+ if next ~= stop and halant[getchar(next)] and getchar(getnext(next)) == c_zwnj then
+ setprop(current,a_state,unsetvalue)
+ end
+ current = next
+ end
+
+ if base ~= stop and getprop(base,a_state) then -- a_state can also be init
+ local next = getnext(base)
+ if halant[getchar(next)] and not (next ~= stop and getchar(getnext(next)) == c_zwj) then
+ setprop(base,a_state,unsetvalue)
+ end
+ end
+
+ -- split two- or three-part matras into their parts. Then, move the left 'matra' part to the beginning of the syllable.
+ -- classify consonants and 'matra' parts as pre-base, above-base (Reph), below-base or post-base, and group elements of the syllable (consonants and 'matras') according to this classification
+
+ local current, allreordered, moved = start, false, { [base] = true }
+ local a, b, p, bn = base, base, base, getnext(base)
+ if base ~= stop and nukta[getchar(bn)] then
+ a, b, p = bn, bn, bn
+ end
+ while not allreordered do
+ -- current is always consonant
+ local c = current
+ local n = getnext(current)
+ local l = nil -- used ?
+ if c ~= stop then
+ local ch = getchar(n)
+ if nukta[ch] then
+ c = n
+ n = getnext(n)
+ ch = getchar(n)
+ end
+ if c ~= stop then
+ if halant[ch] then
+ c = n
+ n = getnext(n)
+ ch = getchar(n)
+ end
+
+ local tpm = twopart_mark[ch]
+ while tpm do
+ local extra = copy_node(n)
+ copyinjection(extra,n)
+ ch = tpm[1]
+ setchar(n,ch)
+ setchar(extra,tpm[2])
+ head = insert_node_after(head,current,extra)
+ tpm = twopart_mark[ch]
+ end
+ while c ~= stop and dependent_vowel[ch] do
+ c = n
+ n = getnext(n)
+ ch = getchar(n)
+ end
+ if c ~= stop then
+ if vowel_modifier[ch] then
+ c = n
+ n = getnext(n)
+ ch = getchar(n)
+ end
+ if c ~= stop and stress_tone_mark[ch] then
+ c = n
+ n = getnext(n)
+ end
+ end
+ end
+ end
+ local bp = getprev(firstcons)
+ local cn = getnext(current)
+ local last = getnext(c)
+ while cn ~= last do
+ -- move pre-base matras...
+ if pre_mark[getchar(cn)] then
+ if devanagari.left_matra_before_base then
+ local prev, next = getboth(cn)
+ setlink(prev,next)
+ if cn == stop then
+ stop = getprev(cn)
+ end
+ if base == start then
+ if head == start then
+ head = cn
+ end
+ start = cn
+ end
+ setlink(getprev(base),cn)
+ setlink(cn,base)
+ -- setlink(getprev(base),cn,base) -- maybe
+ cn = next
+ else
+ if bp then
+ setnext(bp,cn)
+ end
+ local prev, next = getboth(cn)
+ if next then
+ setprev(next,prev)
+ end
+ setnext(prev,next)
+ if cn == stop then
+ stop = prev
+ end
+ setprev(cn,bp)
+ setlink(cn,firstcons)
+ if firstcons == start then
+ if head == start then
+ head = cn
+ end
+ start = cn
+ end
+ cn = next
+ end
+ elseif current ~= base and dependent_vowel[getchar(cn)] then
+ local prev, next = getboth(cn)
+ if next then
+ setprev(next,prev)
+ end
+ setnext(prev,next)
+ if cn == stop then
+ stop = prev
+ end
+ setlink(b,cn,getnext(b))
+ order_matras(cn)
+ cn = next
+ elseif current == base and dependent_vowel[getchar(cn)] then
+ local cnn = getnext(cn)
+ order_matras(cn)
+ cn = cnn
+ while cn ~= last and dependent_vowel[getchar(cn)] do
+ cn = getnext(cn)
+ end
+ else
+ cn = getnext(cn)
+ end
+ end
+ allreordered = c == stop
+ current = getnext(c)
+ end
+
+ if reph or vattu then
+ local current, cns = start, nil
+ while current ~= stop do
+ local c = current
+ local n = getnext(current)
+ if ra[getchar(current)] and halant[getchar(n)] then
+ c = n
+ n = getnext(n)
+ local b, bn = base, base
+ while bn ~= stop do
+ local next = getnext(bn)
+ if dependent_vowel[getchar(next)] then
+ b = next
+ end
+ bn = next
+ end
+ if getprop(current,a_state) == s_rphf then
+ -- position Reph (Ra + H) after post-base 'matra' (if any) since these
+ -- become marks on the 'matra', not on the base glyph
+ if b ~= current then
+ if current == start then
+ if head == start then
+ head = n
+ end
+ start = n
+ end
+ if b == stop then
+ stop = c
+ end
+ local prev = getprev(current)
+ setlink(prev,n)
+ local next = getnext(b)
+ setlink(c,next)
+ setlink(b,current)
+ end
+ elseif cns and getnext(cns) ~= current then -- todo: optimize next
+ -- position below-base Ra (vattu) following the consonants on which it is placed (either the base consonant or one of the pre-base consonants)
+ local cp = getprev(current)
+ local cnsn = getnext(cns)
+ setlink(cp,n)
+ setlink(cns,current)
+ setlink(c,cnsn)
+ if c == stop then
+ stop = cp
+ break
+ end
+ current = getprev(n)
+ end
+ else
+ local char = getchar(current)
+ if consonant[char] then
+ cns = current
+ local next = getnext(cns)
+ if halant[getchar(next)] then
+ cns = next
+ end
+ if not vatucache[char] then
+ next = getnext(cns)
+ while dependent_vowel[getchar(next)] do
+ cns = next
+ next = getnext(cns)
+ end
+ end
+ elseif char == c_nbsp then
+ nbspaces = nbspaces + 1
+ cns = current
+ local next = getnext(cns)
+ if halant[getchar(next)] then
+ cns = next
+ end
+ if not vatucache[char] then
+ next = getnext(cns)
+ while dependent_vowel[getchar(next)] do
+ cns = next
+ next = getnext(cns)
+ end
+ end
+ end
+ end
+ current = getnext(current)
+ end
+ end
+
+ if getchar(base) == c_nbsp then
+ nbspaces = nbspaces - 1
+ if base == stop then
+ stop = getprev(stop)
+ end
+ head = remove_node(head,base)
+ flush_node(base)
+ end
+
+ return head, stop, nbspaces
+end
+
+-- If a pre-base matra character had been reordered before applying basic features,
+-- the glyph can be moved closer to the main consonant based on whether half-forms had been formed.
+-- Actual position for the matra is defined as “after last standalone halant glyph,
+-- after initial matra position and before the main consonantâ€.
+-- If ZWJ or ZWNJ follow this halant, position is moved after it.
+
+-- so we break out ... this is only done for the first 'word' (if we feed words we can as
+-- well test for non glyph.
+
+function handlers.devanagari_reorder_matras(head,start) -- no leak
+ local current = start -- we could cache attributes here
+ local startfont = getfont(start)
+ local startattr = getprop(start,a_syllabe)
+ while current do
+ local char = ischar(current,startfont)
+ local next = getnext(current)
+ if char and getprop(current,a_syllabe) == startattr then
+ if halant[char] then -- a_state can also be init
+ if next then
+ local char = ischar(next,startfont)
+ if char and zw_char[char] and getprop(next,a_syllabe) == startattr then
+ current = next
+ next = getnext(current)
+ end
+ end
+ -- can be optimzied
+ local startnext = getnext(start)
+ head = remove_node(head,start)
+ setlink(start,next)
+ setlink(current,start)
+ -- setlink(current,start,next) -- maybe
+ start = startnext
+ break
+ -- elseif consonant[char] and ( not getprop(current,a_state) or getprop(current,a_state) == s_init) then
+ -- startnext = getnext(start)
+ -- head = remove_node(head,start)
+ -- if current == head then
+ -- setlink(start,current)
+ -- head = start
+ -- else
+ -- setlink(getprev(current),start)
+ -- setlink(start,current)
+ -- end
+ -- start = startnext
+ -- break
+ end
+ else
+ break
+ end
+ current = next
+ end
+ return head, start, true
+end
+
+-- Reph’s original position is always at the beginning of the syllable, (i.e. it is
+-- not reordered at the character reordering stage). However, it will be reordered
+-- according to the basic-forms shaping results. Possible positions for reph,
+-- depending on the script, are; after main, before post-base consonant forms, and
+-- after post-base consonant forms.
+
+-- In Devanagari reph has reordering position 'before postscript' and dev2 only
+-- follows step 2, 4, and 6.
+
+local rephbase = { }
+
+function handlers.devanagari_reorder_reph(head,start)
+ local current = getnext(start)
+ local startnext = nil
+ local startprev = nil
+ local startfont = getfont(start)
+ local startattr = getprop(start,a_syllabe)
+ --
+ ::step_1::
+ --
+ -- If reph should be positioned after post-base consonant forms, proceed to step 5.
+ --
+ local char = ischar(start,startfont)
+ local rephbase = rephbase[startfont][char]
+ if char and after_subscript[rephbase] then
+ goto step_5
+ end
+ --
+ ::step_2::
+ --
+ -- If the reph repositioning class is not after post-base: target position is after
+ -- the first explicit halant glyph between the first post-reph consonant and last
+ -- main consonant. If ZWJ or ZWNJ are following this halant, position is moved after
+ -- it. If such position is found, this is the target position. Otherwise, proceed to
+ -- the next step. Note: in old-implementation fonts, where classifications were
+ -- fixed in shaping engine, there was no case where reph position will be found on
+ -- this step.
+ --
+ if char and not after_postscript[rephbase] then
+ while current do
+ local char = ischar(current,startfont)
+ if char and getprop(current,a_syllabe) == startattr then
+ if halant[char] then
+ local next = getnext(current)
+ if next then
+ local nextchar = ischar(next,startfont)
+ if nextchar and zw_char[nextchar] and getprop(next,a_syllabe) == startattr then
+ current = next
+ next = getnext(current)
+ end
+ end
+ startnext = getnext(start)
+ head = remove_node(head,start)
+ setlink(start,next)
+ setlink(current,start)
+ -- setlink(current,start,next) -- maybe
+ start = startnext
+ startattr = getprop(start,a_syllabe)
+ break
+ end
+ current = getnext(current)
+ else
+ break
+ end
+ end
+ end
+ --
+ ::step_3::
+ --
+ -- If reph should be repositioned after the main consonant: find the first consonant
+ -- not ligated with main, or find the first consonant that is not a potential
+ -- pre-base reordering Ra.
+ --
+ if not startnext then
+ if char and after_main[rephbase] then
+ current = getnext(start)
+ while current do
+ local char = ischar(current,startfont)
+ if char and getprop(current,a_syllabe) == startattr then
+ if consonant[char] and not getprop(current,a_state) == s_pref then
+ startnext = getnext(start)
+ head = remove_node(head,start)
+ setlink(current,start)
+ setlink(start,getnext(current))
+ -- setlink(current,start,getnext(current)) -- maybe
+ start = startnext
+ startattr = getprop(start,a_syllabe)
+ break
+ end
+ current = getnext(current)
+ else
+ break
+ end
+ end
+ end
+ end
+ --
+ ::step_4::
+ --
+ -- If reph should be positioned before post-base consonant, find first post-base
+ -- classified consonant not ligated with main. If no consonant is found, the target
+ -- position should be before the first matra, syllable modifier sign or vedic sign.
+ --
+ if not startnext then
+ if char and before_postscript[rephbase] then
+ current = getnext(start)
+ local c = nil
+ while current do
+ local char = ischar(current,startfont)
+ if char and getprop(current,a_syllabe) == startattr then
+ if getprop(current,a_state) == s_pstf then -- post-base
+ startnext = getnext(start)
+ head = remove_node(head,start)
+ setlink(getprev(current),start)
+ setlink(start,current)
+ -- setlink(getprev(current),start,current) -- maybe
+ start = startnext
+ startattr = getprop(start,a_syllabe)
+ break
+ elseif not c and ( vowel_modifier[char] or stress_tone_mark[char] ) then
+ c = current
+ end
+ current = getnext(current)
+ else
+ if c then
+ startnext = getnext(start)
+ head = remove_node(head,start)
+ setlink(getprev(c),start)
+ setlink(start,c)
+ -- setlink(getprev(c),start,c) -- maybe
+ start = startnext
+ startattr = getprop(start,a_syllabe)
+ end
+ break
+ end
+ end
+ end
+ end
+ --
+ ::step_5::
+ --
+ -- If no consonant is found in steps 3 or 4, move reph to a position immediately
+ -- before the first post-base matra, syllable modifier sign or vedic sign that has a
+ -- reordering class after the intended reph position. For example, if the reordering
+ -- position for reph is post-main, it will skip above-base matras that also have a
+ -- post-main position.
+ --
+ if not startnext then
+ current = getnext(start)
+ local c = nil
+ while current do
+ local char = ischar(current,startfont)
+ if char and getprop(current,a_syllabe) == startattr then
+ local state = getprop(current,a_state)
+ if before_subscript[rephbase] and (state == s_blwf or state == s_pstf) then
+ c = current
+ elseif after_subscript[rephbase] and (state == s_pstf) then
+ c = current
+ end
+ current = getnext(current)
+ else
+ break
+ end
+ end
+ -- here we can loose the old start node: maybe best split cases
+ if c then
+ startnext = getnext(start)
+ head = remove_node(head,start)
+ setlink(getprev(c),start)
+ setlink(start,c)
+ -- setlink(getprev(c),start,c) -- maybe
+ -- end
+ start = startnext
+ startattr = getprop(start,a_syllabe)
+ end
+ end
+ --
+ ::step_6::
+ --
+ -- Otherwise, reorder reph to the end of the syllable.
+ --
+ if not startnext then
+ current = start
+ local next = getnext(current)
+ while next do
+ local nextchar = ischar(next,startfont)
+ if nextchar and getprop(next,a_syllabe) == startattr then
+ current = next
+ next = getnext(current)
+ else
+ break
+ end
+ end
+ if start ~= current then
+ startnext = getnext(start)
+ head = remove_node(head,start)
+ setlink(start,getnext(current))
+ setlink(current,start)
+ -- setlink(current,start,getnext(current)) -- maybe
+ start = startnext
+ end
+ end
+ --
+ return head, start, true
+end
+
+-- If a pre-base reordering consonant is found, reorder it according to the following rules:
+--
+-- 1 Only reorder a glyph produced by substitution during application of the feature. (Note
+-- that a font may shape a Ra consonant with the feature generally but block it in certain
+-- contexts.)
+-- 2 Try to find a target position the same way as for pre-base matra. If it is found, reorder
+-- pre-base consonant glyph.
+-- 3 If position is not found, reorder immediately before main consonant.
+
+-- Here we implement a few handlers:
+--
+-- function(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+-- return head, start, done
+-- end
+
+local reordered_pre_base_reordering_consonants = { } -- shared ? not reset ?
+
+function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start)
+ if reordered_pre_base_reordering_consonants[start] then
+ return head, start, true
+ end
+ local current = start -- we could cache attributes here
+ local startfont = getfont(start)
+ local startattr = getprop(start,a_syllabe)
+ while current do
+ local char = ischar(current,startfont)
+ local next = getnext(current)
+ if char and getprop(current,a_syllabe) == startattr then
+ if halant[char] then -- a_state can also be init
+ if next then
+ local char = ischar(next,startfont)
+ if char and zw_char[char] and getprop(next,a_syllabe) == startattr then
+ current = next
+ next = getnext(current)
+ end
+ end
+ -- can be optimzied
+ local startnext = getnext(start)
+ head = remove_node(head,start)
+ setlink(start,next)
+ setlink(current,start)
+ -- setlink(current,start,next) -- maybe
+ reordered_pre_base_reordering_consonants[start] = true
+ start = startnext
+ return head, start, true
+ -- elseif consonant[char] and ( not getprop(current,a_state) or getprop(current,a_state) == s_init) then
+ -- startnext = getnext(start)
+ -- head = remove_node(head,start)
+ -- if current == head then
+ -- setlink(start,current)
+ -- head = start
+ -- else
+ -- setlink(getprev(current),start)
+ -- setlink(start,current)
+ -- end
+ -- start = startnext
+ -- break
+ end
+ else
+ break
+ end
+ current = next
+ end
+
+ local startattr = getprop(start,a_syllabe)
+ local current = getprev(start)
+ while current and getprop(current,a_syllabe) == startattr do
+ local char = ischar(current)
+ if ( not dependent_vowel[char] and not getprop(current,a_state) or getprop(current,a_state) == s_init) then
+ startnext = getnext(start)
+ head = remove_node(head,start)
+ if current == head then
+ setlink(start,current)
+ head = start
+ else
+ setlink(getprev(current),start)
+ setlink(start,current)
+ end
+ reordered_pre_base_reordering_consonants[start] = true
+ start = startnext
+ break
+ end
+ current = getprev(current)
+ end
+
+ return head, start, true
+end
+
+function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replacement)
+ local stop = getnext(start)
+ local font = getfont(start)
+ local last = start
+ while stop do
+ local char = ischar(stop,font)
+ if char and (char == c_zwnj or char == c_zwj) then
+ last = stop
+ stop = getnext(stop)
+ else
+ break
+ end
+ end
+ local prev = getprev(start)
+ if stop then
+ setnext(last)
+ setlink(prev,stop)
+ elseif prev then
+ setnext(prev)
+ end
+ if head == start then
+ head = stop
+ end
+ flush_list(start)
+ return head, stop, true
+end
+
+local function initialize_two(font,attr)
+
+ local devanagari = fontdata[font].resources.devanagari
+
+ if devanagari then
+ return devanagari.seqsubset or { }, devanagari.reorderreph or { }
+ else
+ return { }, { }
+ end
+
+end
+
+-- this one will be merged into the caller: it saves a call, but we will then make function
+-- of the actions
+
+local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pass over (determine stop in sweep)
+ local seqsubset, reorderreph = initialize_two(font,attr)
+
+ local halfpos = nil
+ local basepos = nil
+ local subpos = nil
+ local postpos = nil
+
+ reorderreph.coverage = { }
+ rephbase[font] = { }
+
+ for i=1,#seqsubset do
+
+ -- this can be done more efficient, the last test and less getnext
+
+ local subset = seqsubset[i]
+ local kind = subset[1]
+ local lookupcache = subset[2]
+ if kind == "rphf" then
+ reorderreph.coverage[subset[3]] = true -- neat
+ rephbase[font][subset[3]] = subset[4]
+ local current = start
+ local last = getnext(stop)
+ while current ~= last do
+ if current ~= stop then
+ local c = getchar(current)
+ local found = lookupcache[c]
+ if found then
+ local next = getnext(current)
+ if found[getchar(next)] or contextchain(found, next) then --above-base: rphf Consonant + Halant
+ local afternext = next ~= stop and getnext(next)
+ if afternext and zw_char[getchar(afternext)] then -- ZWJ and ZWNJ prevent creation of reph
+ current = afternext -- getnext(next)
+ elseif current == start then
+ setprop(current,a_state,s_rphf)
+ current = next
+ else
+ current = next
+ end
+ end
+ end
+ end
+ current = getnext(current)
+ end
+ elseif kind == "pref" then
+ local current = start
+ local last = getnext(stop)
+ while current ~= last do
+ if current ~= stop then
+ local c = getchar(current)
+ local found = lookupcache[c]
+ if found then -- pre-base: pref Halant + Consonant
+ local next = getnext(current)
+ if found[getchar(next)] or contextchain(found, next) then
+ if (not getprop(current,a_state) and not getprop(next,a_state)) then --KE: a_state can also be init...
+ setprop(current,a_state,s_pref)
+ setprop(next,a_state,s_pref)
+ current = next
+ end
+ end
+ end
+ end
+ current = getnext(current)
+ end
+ elseif kind == "half" then -- half forms: half / Consonant + Halant
+ local current = start
+ local last = getnext(stop)
+ while current ~= last do
+ if current ~= stop then
+ local c = getchar(current)
+ local found = lookupcache[c]
+ if found then
+ local next = getnext(current)
+ if found[getchar(next)] or contextchain(found, next) then
+ if next ~= stop and getchar(getnext(next)) == c_zwnj then -- zwnj prevent creation of half
+ current = next
+ elseif (not getprop(current,a_state)) then --KE: a_state can also be init...
+ setprop(current,a_state,s_half)
+ if not halfpos then
+ halfpos = current
+ end
+ end
+ current = getnext(current)
+ end
+ end
+ end
+ current = getnext(current)
+ end
+ elseif kind == "blwf" or kind == "vatu" then -- below-base: blwf / Halant + Consonant
+ local current = start
+ local last = getnext(stop)
+ while current ~= last do
+ if current ~= stop then
+ local c = getchar(current)
+ local found = lookupcache[c]
+ if found then
+ local next = getnext(current)
+ if found[getchar(next)] or contextchain(found, next) then
+ if (not getprop(current,a_state) and not getprop(next,a_state)) then --KE: a_state can also be init...
+ setprop(current,a_state,s_blwf)
+ setprop(next,a_state,s_blwf)
+ current = next
+ subpos = current
+ end
+ end
+ end
+ end
+ current = getnext(current)
+ end
+ elseif kind == "pstf" then -- post-base: pstf / Halant + Consonant
+ local current = start
+ local last = getnext(stop)
+ while current ~= last do
+ if current ~= stop then
+ local c = getchar(current)
+ local found = lookupcache[c]
+ if found then
+ local next = getnext(current)
+ if found[getchar(next)] or contextchain(found, next) then
+ if (not getprop(current,a_state) and not getprop(next,a_state)) then --KE: a_state can also be init...
+ setprop(current,a_state,s_pstf)
+ setprop(next,a_state,s_pstf)
+ current = next
+ postpos = current
+ end
+ end
+ end
+ end
+ current = getnext(current)
+ end
+ end
+ end
+
+ local current, base, firstcons = start, nil, nil
+
+ if getprop(start,a_state) == s_rphf then
+ -- if syllable starts with Ra + H and script has 'Reph' then exclude Reph from candidates for base consonants
+ current = getnext(getnext(start))
+ end
+
+ if current ~= getnext(stop) and getchar(current) == c_nbsp then
+ -- Stand Alone cluster
+ if current == stop then
+ stop = getprev(stop)
+ head = remove_node(head,current)
+ flush_node(current)
+ return head, stop, nbspaces
+ else
+ nbspaces = nbspaces + 1
+ base = current
+ current = getnext(current)
+ if current ~= stop then
+ local char = getchar(current)
+ if nukta[char] then
+ current = getnext(current)
+ char = getchar(current)
+ end
+ if char == c_zwj then
+ local next = getnext(current)
+ if current ~= stop and next ~= stop and halant[getchar(next)] then
+ current = next
+ next = getnext(current)
+ local tmp = getnext(next)
+ local changestop = next == stop
+ setnext(next)
+ setprop(current,a_state,s_pref)
+ current = processcharacters(current,font)
+ setprop(current,a_state,s_blwf)
+ current = processcharacters(current,font)
+ setprop(current,a_state,s_pstf)
+ current = processcharacters(current,font)
+ setprop(current,a_state,unsetvalue)
+ if halant[getchar(current)] then
+ setnext(getnext(current),tmp)
+ if show_syntax_errors then
+ head, current = inject_syntax_error(head,current,char)
+ end
+ else
+ setnext(current,tmp) -- assumes that result of pref, blwf, or pstf consists of one node
+ if changestop then
+ stop = current
+ end
+ end
+ end
+ end
+ end
+ end
+ else -- not Stand Alone cluster
+ local last = getnext(stop)
+ while current ~= last do -- find base consonant
+ local next = getnext(current)
+ if consonant[getchar(current)] then
+ if not (current ~= stop and next ~= stop and halant[getchar(next)] and getchar(getnext(next)) == c_zwj) then
+ if not firstcons then
+ firstcons = current
+ end
+ -- check whether consonant has below-base or post-base form or is pre-base reordering Ra
+ local a = getprop(current,a_state)
+ if not (a == s_blwf or a == s_pstf or (a ~= s_rphf and a ~= s_blwf and ra[getchar(current)])) then
+ base = current
+ end
+ end
+ end
+ current = next
+ end
+ if not base then
+ base = firstcons
+ end
+ end
+
+ if not base then
+ if getprop(start,a_state) == s_rphf then
+ setprop(start,a_state,unsetvalue)
+ end
+ return head, stop, nbspaces
+ else
+ if getprop(base,a_state) then -- a_state can also be init
+ setprop(base,a_state,unsetvalue)
+ end
+ basepos = base
+ end
+ if not halfpos then
+ halfpos = base
+ end
+ if not subpos then
+ subpos = base
+ end
+ if not postpos then
+ postpos = subpos or base
+ end
+
+ -- Matra characters are classified and reordered by which consonant in a conjunct they have affinity for
+
+ local moved = { }
+ local current = start
+ local last = getnext(stop)
+ while current ~= last do
+ local char = getchar(current)
+ local target = nil
+ local cn = getnext(current)
+ -- not so efficient (needed for malayalam)
+ local tpm = twopart_mark[char]
+ while tpm do
+ local extra = copy_node(current)
+ copyinjection(extra,current)
+ char = tpm[1]
+ setchar(current,char)
+ setchar(extra,tpm[2])
+ head = insert_node_after(head,current,extra)
+ tpm = twopart_mark[char]
+ end
+ --
+ if not moved[current] and dependent_vowel[char] then
+ if pre_mark[char] then -- or: if before_main or before_half
+ moved[current] = true
+ -- can be helper to remove one node
+ local prev, next = getboth(current)
+ setlink(prev,next)
+ if current == stop then
+ stop = getprev(current)
+ end
+
+ local pos
+ if before_main[char] then
+ pos = basepos
+ -- basepos = current -- is this correct?
+ else
+ -- must be before_half
+ pos = halfpos
+ -- halfpos = current -- is this correct?
+ end
+
+ local ppos = getprev(pos) -- necessary?
+ while ppos and getprop(ppos,a_syllabe) == getprop(pos,a_syllabe) do
+ if getprop(ppos,a_state) == s_pref then
+ pos = ppos
+ end
+ ppos = getprev(ppos)
+ end
+
+ local ppos = getprev(pos) -- necessary?
+ while ppos and getprop(ppos,a_syllabe) == getprop(pos,a_syllabe) and halant[ischar(ppos)] do
+ ppos = getprev(ppos)
+ if ppos and getprop(ppos,a_syllabe) == getprop(pos,a_syllabe) and consonant[ischar(ppos)] then
+ pos = ppos
+ ppos = getprev(ppos)
+ else
+ break
+ end
+ end
+
+ if pos == start then
+ if head == start then
+ head = current
+ end
+ start = current
+ end
+ setlink(getprev(pos),current)
+ setlink(current,pos)
+ -- setlink(getprev(pos),current,pos) -- maybe
+ elseif above_mark[char] then
+ -- after main consonant
+ target = basepos
+ if subpos == basepos then
+ subpos = current
+ end
+ if postpos == basepos then
+ postpos = current
+ end
+ basepos = current
+ elseif below_mark[char] then
+ -- after subjoined consonants
+ target = subpos
+ if postpos == subpos then
+ postpos = current
+ end
+ subpos = current
+ elseif post_mark[char] then
+ -- after post-form consonant
+ local n = getnext(postpos) -- nukta and vedic sign come first - is that right? and also halant+ra
+ while n do
+ local v = ischar(n,font)
+ if nukta[v] or stress_tone_mark[v] or vowel_modifier[v] then
+ postpos = n
+ else
+ break
+ end
+ n = getnext(n)
+ end
+ target = postpos
+ postpos = current
+ end
+ if mark_above_below_post[char] then
+ local prev = getprev(current)
+ if prev ~= target then
+ local next = getnext(current)
+ setlink(prev,next)
+ if current == stop then
+ stop = prev
+ end
+ setlink(current,getnext(target))
+ setlink(target,current)
+ -- setlink(target,current,getnext(target)) -- maybe
+ end
+ end
+ end
+ current = cn
+ end
+
+ -- reorder halant+Ra
+
+ local current = getnext(start)
+ local last = getnext(stop)
+ while current ~= last do
+ local char = getchar(current)
+ local cn = getnext(current)
+ if halant[char] and ra[ischar(cn)] and getprop(cn,a_state) ~= s_rphf and getprop(cn,a_state) ~= s_blwf then
+ if after_main[ischar(cn)] then
+ local prev = getprev(current)
+ local next = getnext(cn)
+ local bpn = getnext(basepos)
+ while bpn and dependent_vowel[ischar(bpn)] do
+ basepos = bpn
+ bpn = getnext(bpn)
+ end
+ if basepos ~= prev then
+ setlink(prev,next)
+ setlink(cn, getnext(basepos))
+ setlink(basepos, current)
+ if cn == stop then
+ stop = prev
+ end
+ cn = next
+ end
+ end
+ -- after_postscript
+ -- after_subscript
+ -- before_postscript
+ -- before_subscript
+ end
+ current = cn
+ end
+
+ -- Reorder marks to canonical order: Adjacent nukta and halant or nukta and vedic sign are always repositioned if necessary, so that the nukta is first.
+
+ local current = start
+ local c = nil
+ while current ~= stop do
+ local char = getchar(current)
+ if halant[char] or stress_tone_mark[char] then
+ if not c then
+ c = current
+ end
+ else
+ c = nil
+ end
+ local next = getnext(current)
+ if c and nukta[getchar(next)] then
+ if head == c then
+ head = next
+ end
+ if stop == next then
+ stop = current
+ end
+ setlink(getprev(c),next)
+ local nextnext = getnext(next)
+ setnext(current,nextnext)
+ local nextnextnext = getnext(nextnext)
+ if nextnextnext then
+ setprev(nextnextnext,current)
+ end
+ setlink(nextnext,c)
+ end
+ if stop == current then break end
+ current = getnext(current)
+ end
+
+ if getchar(base) == c_nbsp then
+ if base == stop then
+ stop = getprev(stop)
+ end
+ nbspaces = nbspaces - 1
+ head = remove_node(head, base)
+ flush_node(base)
+ end
+
+ return head, stop, nbspaces
+end
+
+-- cleaned up and optimized ... needs checking (local, check order, fixes, extra hash, etc)
+
+local separator = { }
+
+imerge(separator,consonant)
+imerge(separator,independent_vowel)
+imerge(separator,dependent_vowel)
+imerge(separator,vowel_modifier)
+imerge(separator,stress_tone_mark)
+
+for k, v in next, nukta do separator[k] = true end
+for k, v in next, halant do separator[k] = true end
+
+local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowel
+ -- why two variants ... the comment suggests that it's the same ruleset
+ local n = getnext(c)
+ if not n then
+ return c
+ end
+ if variant == 1 then
+ local v = ischar(n,font)
+ if v and nukta[v] then
+ n = getnext(n)
+ if n then
+ v = ischar(n,font)
+ end
+ end
+ if n and v then
+ local nn = getnext(n)
+ if nn then
+ local vv = ischar(nn,font)
+ if vv then
+ local nnn = getnext(nn)
+ if nnn then
+ local vvv = ischar(nnn,font)
+ if vvv then
+ if vv == c_zwj and consonant[vvv] then
+ c = nnn
+ elseif (vv == c_zwnj or vv == c_zwj) and halant[vvv] then
+ local nnnn = getnext(nnn)
+ if nnnn then
+ local vvvv = ischar(nnnn,font)
+ if vvvv and consonant[vvvv] then
+ c = nnnn
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ elseif variant == 2 then
+ local v = ischar(n,font)
+ if v and nukta[v] then
+ c = n
+ end
+ n = getnext(c)
+ if n then
+ v = ischar(n,font)
+ if v then
+ local nn = getnext(n)
+ if nn then
+ local vv = ischar(nn,font)
+ if vv and zw_char[v] then
+ n = nn
+ v = vv
+ nn = getnext(nn)
+ vv = nn and ischar(nn,font)
+ end
+ if vv and halant[v] and consonant[vv] then
+ c = nn
+ end
+ end
+ end
+ end
+ end
+ -- c = ms_matra(c)
+ local n = getnext(c)
+ if not n then
+ return c
+ end
+ local v = ischar(n,font)
+ if not v then
+ return c
+ end
+ local already_pre_mark -- = false
+ local already_above_mark -- = false
+ local already_below_mark -- = false
+ local already_post_mark -- = false
+ while dependent_vowel[v] do
+ local vowels = twopart_mark[v] or { v }
+ for k, v in next, vowels do
+ if pre_mark[v] and not already_pre_mark then
+ already_pre_mark = true
+ elseif above_mark[v] and not already_above_mark then
+ already_above_mark = true
+ elseif below_mark[v] and not already_below_mark then
+ already_below_mark = true
+ elseif post_mark[v] and not already_post_mark then
+ already_post_mark = true
+ else
+ return c
+ end
+ end
+ c = getnext(c)
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if nukta[v] then
+ c = getnext(c)
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if halant[v] then
+ c = getnext(c)
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if vowel_modifier[v] then
+ c = getnext(c)
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ c = getnext(c)
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ return n
+ else
+ return c
+ end
+end
+
+local function analyze_next_chars_two(c,font)
+ local n = getnext(c)
+ if not n then
+ return c
+ end
+ local v = ischar(n,font)
+ if v and nukta[v] then
+ c = n
+ end
+ n = c
+ while true do
+ local nn = getnext(n)
+ if nn then
+ local vv = ischar(nn,font)
+ if vv then
+ if halant[vv] then
+ n = nn
+ local nnn = getnext(nn)
+ if nnn then
+ local vvv = ischar(nnn,font)
+ if vvv and zw_char[vvv] then
+ n = nnn
+ end
+ end
+ elseif vv == c_zwnj or vv == c_zwj then
+ -- n = nn -- not here (?)
+ local nnn = getnext(nn)
+ if nnn then
+ local vvv = ischar(nnn,font)
+ if vvv and halant[vvv] then
+ n = nnn
+ end
+ end
+ else
+ break
+ end
+ local nn = getnext(n)
+ if nn then
+ local vv = ischar(nn,font)
+ if vv and consonant[vv] then
+ n = nn
+ local nnn = getnext(nn)
+ if nnn then
+ local vvv = ischar(nnn,font)
+ if vvv and nukta[vvv] then
+ n = nnn
+ end
+ end
+ c = n
+ else
+ break
+ end
+ else
+ break
+ end
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ --
+ if not c then
+ -- This shouldn't happen I guess.
+ return
+ end
+ local n = getnext(c)
+ if not n then
+ return c
+ end
+ local v = ischar(n,font)
+ if not v then
+ return c
+ end
+ if anudatta[v] then
+ c = n
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if halant[v] then
+ c = n
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ if v == c_zwnj or v == c_zwj then
+ c = n
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ else
+ -- c = ms_matra(c)
+ -- same as one
+ local already_pre_mark -- = false
+ local already_above_mark -- = false
+ local already_below_mark -- = false
+ local already_post_mark -- = false
+ while dependent_vowel[v] do
+ local vowels = twopart_mark[v] or { v }
+ for k, v in next, vowels do
+ if pre_mark[v] and not already_pre_mark then
+ already_pre_mark = true
+ elseif above_mark[v] and not already_above_mark then
+ already_above_mark = true
+ elseif below_mark[v] and not already_below_mark then
+ already_below_mark = true
+ elseif post_mark[v] and not already_post_mark then
+ already_post_mark = true
+ else
+ return c
+ end
+ end
+ c = n
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if nukta[v] then
+ c = n
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if halant[v] then
+ c = n
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ end
+ -- same as one
+ if vowel_modifier[v] then
+ c = n
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ c = n
+ n = getnext(c)
+ if not n then
+ return c
+ end
+ v = ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ return n
+ else
+ return c
+ end
+end
+
+-- It looks like these two analyzers were written independently but they share
+-- a lot. Common code has been synced.
+
+local function method_one(head,font,attr)
+ local current = head
+ local start = true
+ local done = false
+ local nbspaces = 0
+ local syllabe = 0
+ while current do
+ local char = ischar(current,font)
+ if char then
+ done = true
+ local syllablestart = current
+ local syllableend = nil
+ local c = current
+ local n = getnext(c)
+ local first = char
+ if n and ra[first] then
+ local second = ischar(n,font)
+ if second and halant[second] then
+ local n = getnext(n)
+ if n then
+ local third = ischar(n,font)
+ if third then
+ c = n
+ first = third
+ end
+ end
+ end
+ end
+ local standalone = first == c_nbsp
+ if standalone then
+ local prev = getprev(current)
+ if prev then
+ local prevchar = ischar(prev,font)
+ if not prevchar then
+ -- different font or language so quite certainly a different word
+ elseif not separator[prevchar] then
+ -- something that separates words
+ else
+ standalone = false
+ end
+ else
+ -- begin of paragraph or box
+ end
+ end
+ if standalone then
+ -- stand alone cluster (at the start of the word only): #[Ra+H]+NBSP+[N]+[<[<ZWJ|ZWNJ>]+H+C>]+[{M}+[N]+[H]]+[SM]+[(VD)]
+ local syllableend = analyze_next_chars_one(c,font,2)
+ current = getnext(syllableend)
+ if syllablestart ~= syllableend then
+ head, current, nbspaces = reorder_one(head,syllablestart,syllableend,font,attr,nbspaces)
+ current = getnext(current)
+ end
+ else
+ -- we can delay the getsubtype(n) and getfont(n) and test for say halant first
+ -- as an table access is faster than two function calls (subtype and font are
+ -- pseudo fields) but the code becomes messy (unless we make it a function)
+ if consonant[char] then
+ -- syllable containing consonant
+ local prevc = true
+ while prevc do
+ prevc = false
+ local n = getnext(current)
+ if not n then
+ break
+ end
+ local v = ischar(n,font)
+ if not v then
+ break
+ end
+ if nukta[v] then
+ n = getnext(n)
+ if not n then
+ break
+ end
+ v = ischar(n,font)
+ if not v then
+ break
+ end
+ end
+ if halant[v] then
+ n = getnext(n)
+ if not n then
+ break
+ end
+ v = ischar(n,font)
+ if not v then
+ break
+ end
+ if v == c_zwnj or v == c_zwj then
+ n = getnext(n)
+ if not n then
+ break
+ end
+ v = ischar(n,font)
+ if not v then
+ break
+ end
+ end
+ if consonant[v] then
+ prevc = true
+ current = n
+ end
+ end
+ end
+ local n = getnext(current)
+ if n then
+ local v = ischar(n,font)
+ if v and nukta[v] then
+ -- nukta (not specified in Microsft Devanagari OpenType specification)
+ current = n
+ n = getnext(current)
+ end
+ end
+ syllableend = current
+ current = n
+ if current then
+ local v = ischar(current,font)
+ if not v then
+ -- skip
+ elseif halant[v] then
+ -- syllable containing consonant without vowels: {C + [Nukta] + H} + C + H
+ local n = getnext(current)
+ if n then
+ local v = ischar(n,font)
+ if v and zw_char[v] then
+ -- code collapsed, probably needs checking with intention
+ syllableend = n
+ current = getnext(n)
+ else
+ syllableend = current
+ current = n
+ end
+ else
+ syllableend = current
+ current = n
+ end
+ else
+ -- syllable containing consonant with vowels: {C + [Nukta] + H} + C + [M] + [VM] + [SM]
+ if dependent_vowel[v] then
+ syllableend = current
+ current = getnext(current)
+ v = ischar(current,font)
+ end
+ if v and vowel_modifier[v] then
+ syllableend = current
+ current = getnext(current)
+ v = ischar(current,font)
+ end
+ if v and stress_tone_mark[v] then
+ syllableend = current
+ current = getnext(current)
+ end
+ end
+ end
+ if syllablestart ~= syllableend then
+ if syllableend then
+ syllabe = syllabe + 1
+ local c = syllablestart
+ local n = getnext(syllableend)
+ while c ~= n do
+ setprop(c,a_syllabe,syllabe)
+ c = getnext(c)
+ end
+ end
+ head, current, nbspaces = reorder_one(head,syllablestart,syllableend,font,attr,nbspaces)
+ current = getnext(current)
+ end
+ elseif independent_vowel[char] then
+ -- syllable without consonants: VO + [VM] + [SM]
+ syllableend = current
+ current = getnext(current)
+ if current then
+ local v = ischar(current,font)
+ if v then
+ if vowel_modifier[v] then
+ syllableend = current
+ current = getnext(current)
+ v = ischar(current,font)
+ end
+ if v and stress_tone_mark[v] then
+ syllableend = current
+ current = getnext(current)
+ end
+ end
+ end
+ else
+ if show_syntax_errors then
+ local mark = mark_four[char]
+ if mark then
+ head, current = inject_syntax_error(head,current,char)
+ end
+ end
+ current = getnext(current)
+ end
+ end
+ else
+ current = getnext(current)
+ end
+ start = false
+ end
+
+ if nbspaces > 0 then
+ head = replace_all_nbsp(head)
+ end
+
+ current = head
+ local n = 0
+ while current do
+ local char = ischar(current,font)
+ if char then
+ if n == 0 and not getprop(current,a_state) then
+ setprop(current,a_state,s_init)
+ end
+ n = n + 1
+ else
+ n = 0
+ end
+ current = getnext(current)
+ end
+
+ return head, done
+end
+
+-- there is a good change that when we run into one with subtype < 256 that the rest is also done
+-- so maybe we can omit this check (it's pretty hard to get glyphs in the stream out of the blue)
+
+local function method_two(head,font,attr)
+ local current = head
+ local start = true
+ local done = false
+ local syllabe = 0
+ local nbspaces = 0
+ while current do
+ local syllablestart = nil
+ local syllableend = nil
+ local char = ischar(current,font)
+ if char then
+ done = true
+ syllablestart = current
+ local c = current
+ local n = getnext(current)
+ if n and ra[char] then
+ local nextchar = ischar(n,font)
+ if nextchar and halant[nextchar] then
+ local n = getnext(n)
+ if n then
+ local nextnextchar = ischar(n,font)
+ if nextnextchar then
+ c = n
+ char = nextnextchar
+ end
+ end
+ end
+ end
+ if independent_vowel[char] then
+ -- vowel-based syllable: [Ra+H]+V+[N]+[<[<ZWJ|ZWNJ>]+H+C|ZWJ+C>]+[{M}+[N]+[H]]+[SM]+[(VD)]
+ current = analyze_next_chars_one(c,font,1)
+ syllableend = current
+ else
+ local standalone = char == c_nbsp
+ if standalone then
+ nbspaces = nbspaces + 1
+ local p = getprev(current)
+ if not p then
+ -- begin of paragraph or box
+ elseif ischar(p,font) then
+ -- different font or language so quite certainly a different word
+ elseif not separator[getchar(p)] then
+ -- something that separates words
+ else
+ standalone = false
+ end
+ end
+ if standalone then
+ -- Stand Alone cluster (at the start of the word only): #[Ra+H]+NBSP+[N]+[<[<ZWJ|ZWNJ>]+H+C>]+[{M}+[N]+[H]]+[SM]+[(VD)]
+ current = analyze_next_chars_one(c,font,2)
+ syllableend = current
+ elseif consonant[getchar(current)] then
+ -- WHY current INSTEAD OF c ?
+
+ -- Consonant syllable: {C+[N]+<H+[<ZWNJ|ZWJ>]|<ZWNJ|ZWJ>+H>} + C+[N]+[A] + [< H+[<ZWNJ|ZWJ>] | {M}+[N]+[H]>]+[SM]+[(VD)]
+ current = analyze_next_chars_two(current,font) -- not c !
+ syllableend = current
+ end
+ end
+ end
+ if syllableend then
+ syllabe = syllabe + 1
+ local c = syllablestart
+ local n = getnext(syllableend)
+ while c ~= n do
+ setprop(c,a_syllabe,syllabe)
+ c = getnext(c)
+ end
+ end
+ if syllableend and syllablestart ~= syllableend then
+ head, current, nbspaces = reorder_two(head,syllablestart,syllableend,font,attr,nbspaces)
+ end
+ if not syllableend and show_syntax_errors then
+ local char = ischar(current,font)
+ if char and not getprop(current,a_state) then -- a_state can also be init
+ local mark = mark_four[char]
+ if mark then
+ head, current = inject_syntax_error(head,current,char)
+ end
+ end
+ end
+ start = false
+ current = getnext(current)
+ end
+
+ if nbspaces > 0 then
+ head = replace_all_nbsp(head)
+ end
+
+ current = head
+ local n = 0
+ while current do
+ local char = ischar(current,font)
+ if char then
+ if n == 0 and not getprop(current,a_state) then -- a_state can also be init
+ setprop(current,a_state,s_init)
+ end
+ n = n + 1
+ else
+ n = 0
+ end
+ current = getnext(current)
+ end
+
+ return head, done
+end
+
+for i=1,nofscripts do
+ methods[scripts_one[i]] = method_one
+ methods[scripts_two[i]] = method_two
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ota.lua b/macros/luatex/generic/luaotfload/fontloader-font-ota.lua
new file mode 100644
index 0000000000..3d217b3f4d
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ota.lua
@@ -0,0 +1,448 @@
+if not modules then modules = { } end modules ['font-ota'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- context only
+
+local type = type
+
+if not trackers then trackers = { register = function() end } end
+
+----- trace_analyzing = false trackers.register("otf.analyzing", function(v) trace_analyzing = v end)
+
+local fonts, nodes, node = fonts, nodes, node
+
+local allocate = utilities.storage.allocate
+
+local otf = fonts.handlers.otf
+
+local analyzers = fonts.analyzers
+local initializers = allocate()
+local methods = allocate()
+
+analyzers.initializers = initializers
+analyzers.methods = methods
+
+local a_state = attributes.private('state')
+
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getprev = nuts.getprev
+local getprop = nuts.getprop
+local setprop = nuts.setprop
+local getsubtype = nuts.getsubtype
+local getchar = nuts.getchar
+local ischar = nuts.ischar
+
+local end_of_math = nuts.end_of_math
+
+local nodecodes = nodes.nodecodes
+----- glyph_code = nodecodes.glyph
+local disc_code = nodecodes.disc
+local math_code = nodecodes.math
+
+local fontdata = fonts.hashes.identifiers
+local categories = characters and characters.categories or { } -- sorry, only in context
+local chardata = characters and characters.data
+
+local otffeatures = fonts.constructors.features.otf
+local registerotffeature = otffeatures.register
+
+--[[ldx--
+<p>Analyzers run per script and/or language and are needed in order to
+process features right.</p>
+--ldx]]--
+
+-- never use these numbers directly
+
+local s_init = 1 local s_rphf = 7
+local s_medi = 2 local s_half = 8
+local s_fina = 3 local s_pref = 9
+local s_isol = 4 local s_blwf = 10
+local s_mark = 5 local s_pstf = 11
+local s_rest = 6
+
+local states = allocate {
+ init = s_init,
+ medi = s_medi,
+ med2 = s_medi,
+ fina = s_fina,
+ fin2 = s_fina,
+ fin3 = s_fina,
+ isol = s_isol,
+ mark = s_mark,
+ rest = s_rest,
+ rphf = s_rphf,
+ half = s_half,
+ pref = s_pref,
+ blwf = s_blwf,
+ pstf = s_pstf,
+}
+
+local features = allocate {
+ init = s_init,
+ medi = s_medi,
+ med2 = s_medi,
+ fina = s_fina,
+ fin2 = s_fina,
+ fin3 = s_fina,
+ isol = s_isol,
+ -- mark = s_mark,
+ -- rest = s_rest,
+ rphf = s_rphf,
+ half = s_half,
+ pref = s_pref,
+ blwf = s_blwf,
+ pstf = s_pstf,
+}
+
+analyzers.states = states
+analyzers.features = features
+analyzers.useunicodemarks = false
+
+-- todo: analyzers per script/lang, cross font, so we need an font id hash -> script
+-- e.g. latin -> hyphenate, arab -> 1/2/3 analyze -- its own namespace
+
+-- done can go away as can tonut
+
+function analyzers.setstate(head,font)
+ local useunicodemarks = analyzers.useunicodemarks
+ local tfmdata = fontdata[font]
+ local descriptions = tfmdata.descriptions
+ local first, last, current, n, done = nil, nil, head, 0, false -- maybe make n boolean
+ current = tonut(current)
+ while current do
+ local char, id = ischar(current,font)
+ if char and not getprop(current,a_state) then
+ done = true
+ local d = descriptions[char]
+ if d then
+ if d.class == "mark" then
+ done = true
+ setprop(current,a_state,s_mark)
+ elseif useunicodemarks and categories[char] == "mn" then
+ done = true
+ setprop(current,a_state,s_mark)
+ elseif n == 0 then
+ first, last, n = current, current, 1
+ setprop(current,a_state,s_init)
+ else
+ last, n = current, n+1
+ setprop(current,a_state,s_medi)
+ end
+ else -- finish
+ if first and first == last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ first, last, n = nil, nil, 0
+ end
+ elseif char == false then
+ -- other font
+ if first and first == last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ first, last, n = nil, nil, 0
+ if id == math_code then
+ current = end_of_math(current)
+ end
+ elseif id == disc_code then
+ -- always in the middle .. it doesn't make much sense to assign a property
+ -- here ... we might at some point decide to flag the components when present
+ -- but even then it's kind of bogus
+ setprop(current,a_state,s_medi)
+ last = current
+ else -- finish
+ if first and first == last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ first, last, n = nil, nil, 0
+ if id == math_code then
+ current = end_of_math(current)
+ end
+ end
+ current = getnext(current)
+ end
+ if first and first == last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ return head, done
+end
+
+-- in the future we will use language/script attributes instead of the
+-- font related value, but then we also need dynamic features which is
+-- somewhat slower; and .. we need a chain of them
+
+local function analyzeinitializer(tfmdata,value) -- attr
+ local script, language = otf.scriptandlanguage(tfmdata) -- attr
+ local action = initializers[script]
+ if not action then
+ -- skip
+ elseif type(action) == "function" then
+ return action(tfmdata,value)
+ else
+ local action = action[language]
+ if action then
+ return action(tfmdata,value)
+ end
+ end
+end
+
+local function analyzeprocessor(head,font,attr)
+ local tfmdata = fontdata[font]
+ local script, language = otf.scriptandlanguage(tfmdata,attr)
+ local action = methods[script]
+ if not action then
+ -- skip
+ elseif type(action) == "function" then
+ return action(head,font,attr)
+ else
+ action = action[language]
+ if action then
+ return action(head,font,attr)
+ end
+ end
+ return head, false
+end
+
+registerotffeature {
+ name = "analyze",
+ description = "analysis of character classes",
+ default = true,
+ initializers = {
+ node = analyzeinitializer,
+ },
+ processors = {
+ position = 1,
+ node = analyzeprocessor,
+ }
+}
+
+-- latin
+
+methods.latn = analyzers.setstate
+-------.dflt = analyzers.setstate % can be an option or just the default
+
+local arab_warned = { }
+
+local function warning(current,what)
+ local char = getchar(current)
+ if not arab_warned[char] then
+ log.report("analyze","arab: character %C has no %a class",char,what)
+ arab_warned[char] = true
+ end
+end
+
+local mappers = allocate {
+ l = s_init, -- left
+ d = s_medi, -- double
+ c = s_medi, -- joiner
+ r = s_fina, -- right
+ u = s_isol, -- nonjoiner
+}
+
+-- we can also use this trick for devanagari
+
+local classifiers = characters.classifiers
+
+if not classifiers then
+
+ local f_arabic, l_arabic = characters.blockrange("arabic")
+ local f_syriac, l_syriac = characters.blockrange("syriac")
+ local f_mandiac, l_mandiac = characters.blockrange("mandiac")
+ local f_nko, l_nko = characters.blockrange("nko")
+ local f_ext_a, l_ext_a = characters.blockrange("arabicextendeda")
+
+ classifiers = table.setmetatableindex(function(t,k)
+ if type(k) == "number" then
+ local c = chardata[k]
+ local v = false
+ if c then
+ local arabic = c.arabic
+ if arabic then
+ v = mappers[arabic]
+ if not v then
+ log.report("analyze","error in mapping arabic %C",k)
+ -- error
+ v = false
+ end
+ elseif (k >= f_arabic and k <= l_arabic) or
+ (k >= f_syriac and k <= l_syriac) or
+ (k >= f_mandiac and k <= l_mandiac) or
+ (k >= f_nko and k <= l_nko) or
+ (k >= f_ext_a and k <= l_ext_a) then
+ if categories[k] == "mn" then
+ v = s_mark
+ else
+ v = s_rest
+ end
+ end
+ end
+ t[k] = v
+ return v
+ end
+ end)
+
+ characters.classifiers = classifiers
+
+end
+
+function methods.arab(head,font,attr)
+ local first, last, c_first, c_last
+ local current = head
+ local done = false
+ current = tonut(current)
+ while current do
+ local char, id = ischar(current,font)
+ if char and not getprop(current,a_state) then
+ done = true
+ local classifier = classifiers[char]
+ if not classifier then
+ if last then
+ if c_last == s_medi or c_last == s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first, last = nil, nil
+ elseif first then
+ if c_first == s_medi or c_first == s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first = nil
+ end
+ elseif classifier == s_mark then
+ setprop(current,a_state,s_mark)
+ elseif classifier == s_isol then
+ if last then
+ if c_last == s_medi or c_last == s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first, last = nil, nil
+ elseif first then
+ if c_first == s_medi or c_first == s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first = nil
+ end
+ setprop(current,a_state,s_isol)
+ elseif classifier == s_medi then
+ if first then
+ last = current
+ c_last = classifier
+ setprop(current,a_state,s_medi)
+ else
+ setprop(current,a_state,s_init)
+ first = current
+ c_first = classifier
+ end
+ elseif classifier == s_fina then
+ if last then
+ if getprop(last,a_state) ~= s_init then
+ setprop(last,a_state,s_medi)
+ end
+ setprop(current,a_state,s_fina)
+ first, last = nil, nil
+ elseif first then
+ -- if getprop(first,a_state) ~= s_init then
+ -- -- needs checking
+ -- setprop(first,a_state,s_medi)
+ -- end
+ setprop(current,a_state,s_fina)
+ first = nil
+ else
+ setprop(current,a_state,s_isol)
+ end
+ else -- classifier == s_rest
+ setprop(current,a_state,s_rest)
+ if last then
+ if c_last == s_medi or c_last == s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first, last = nil, nil
+ elseif first then
+ if c_first == s_medi or c_first == s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first = nil
+ end
+ end
+ else
+ if last then
+ if c_last == s_medi or c_last == s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first, last = nil, nil
+ elseif first then
+ if c_first == s_medi or c_first == s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first = nil
+ end
+ if id == math_code then -- a bit duplicate as we test for glyphs twice
+ current = end_of_math(current)
+ end
+ end
+ current = getnext(current)
+ end
+ if last then
+ if c_last == s_medi or c_last == s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ elseif first then
+ if c_first == s_medi or c_first == s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ end
+ return head, done
+end
+
+methods.syrc = methods.arab
+methods.mand = methods.arab
+methods.nko = methods.arab
+
+directives.register("otf.analyze.useunicodemarks",function(v)
+ analyzers.useunicodemarks = v
+end)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otc.lua b/macros/luatex/generic/luaotfload/fontloader-font-otc.lua
new file mode 100644
index 0000000000..a774a81c2c
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-otc.lua
@@ -0,0 +1,875 @@
+if not modules then modules = { } end modules ['font-otc'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local insert, sortedkeys, sortedhash, tohash = table.insert, table.sortedkeys, table.sortedhash, table.tohash
+local type, next, tonumber = type, next, tonumber
+local lpegmatch = lpeg.match
+local utfbyte, utflen = utf.byte, utf.len
+local sortedhash = table.sortedhash
+
+-- we assume that the other otf stuff is loaded already
+
+local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
+local report_otf = logs.reporter("fonts","otf loading")
+
+local fonts = fonts
+local otf = fonts.handlers.otf
+local registerotffeature = otf.features.register
+local setmetatableindex = table.setmetatableindex
+
+local checkmerge = fonts.helpers.checkmerge
+local checkflags = fonts.helpers.checkflags
+local checksteps = fonts.helpers.checksteps
+
+local normalized = {
+ substitution = "substitution",
+ single = "substitution",
+ ligature = "ligature",
+ alternate = "alternate",
+ multiple = "multiple",
+ kern = "kern",
+ pair = "pair",
+ single = "single",
+ chainsubstitution = "chainsubstitution",
+ chainposition = "chainposition",
+}
+
+local types = {
+ substitution = "gsub_single",
+ ligature = "gsub_ligature",
+ alternate = "gsub_alternate",
+ multiple = "gsub_multiple",
+ kern = "gpos_pair",
+ pair = "gpos_pair",
+ single = "gpos_single",
+ chainsubstitution = "gsub_contextchain",
+ chainposition = "gpos_contextchain",
+}
+
+local names = {
+ gsub_single = "gsub",
+ gsub_multiple = "gsub",
+ gsub_alternate = "gsub",
+ gsub_ligature = "gsub",
+ gsub_context = "gsub",
+ gsub_contextchain = "gsub",
+ gsub_reversecontextchain = "gsub",
+ gpos_single = "gpos",
+ gpos_pair = "gpos",
+ gpos_cursive = "gpos",
+ gpos_mark2base = "gpos",
+ gpos_mark2ligature = "gpos",
+ gpos_mark2mark = "gpos",
+ gpos_context = "gpos",
+ gpos_contextchain = "gpos",
+}
+
+setmetatableindex(types, function(t,k) t[k] = k return k end) -- "key"
+
+local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } }
+local noflags = { false, false, false, false }
+
+-- beware: shared, maybe we should copy the sequence
+
+local function getrange(sequences,category)
+ local count = #sequences
+ local first = nil
+ local last = nil
+ for i=1,count do
+ local t = sequences[i].type
+ if t and names[t] == category then
+ if not first then
+ first = i
+ end
+ last = i
+ end
+ end
+ return first or 1, last or count
+end
+
+local function validspecification(specification,name)
+ local dataset = specification.dataset
+ if dataset then
+ -- okay
+ elseif specification[1] then
+ dataset = specification
+ specification = { dataset = dataset }
+ else
+ dataset = { { data = specification.data } }
+ specification.data = nil
+ specification.dataset = dataset
+ end
+ local first = dataset[1]
+ if first then
+ first = first.data
+ end
+ if not first then
+ report_otf("invalid feature specification, no dataset")
+ return
+ end
+ if type(name) ~= "string" then
+ name = specification.name or first.name
+ end
+ if type(name) ~= "string" then
+ report_otf("invalid feature specification, no name")
+ return
+ end
+ local n = #dataset
+ if n > 0 then
+ for i=1,n do
+ setmetatableindex(dataset[i],specification)
+ end
+ return specification, name
+ end
+end
+
+local function addfeature(data,feature,specifications)
+
+ -- todo: add some validator / check code so that we're more tolerant to
+ -- user errors
+
+ if not specifications then
+ report_otf("missing specification")
+ return
+ end
+
+ local descriptions = data.descriptions
+ local resources = data.resources
+ local features = resources.features
+ local sequences = resources.sequences
+
+ if not features or not sequences then
+ report_otf("missing specification")
+ return
+ end
+
+ local alreadydone = resources.alreadydone
+ if not alreadydone then
+ alreadydone = { }
+ resources.alreadydone = alreadydone
+ end
+ if alreadydone[specifications] then
+ return
+ else
+ alreadydone[specifications] = true
+ end
+
+ -- feature has to be unique but the name entry wins eventually
+
+ local fontfeatures = resources.features or everywhere
+ local unicodes = resources.unicodes
+ local splitter = lpeg.splitter(" ",unicodes)
+ local done = 0
+ local skip = 0
+ local aglunicodes = false
+
+ local specifications = validspecification(specifications,feature)
+ if not specifications then
+ -- report_otf("invalid specification")
+ return
+ end
+
+ local p = lpeg.P("P")
+ * (lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)
+ * lpeg.P(-1)
+
+ local function tounicode(code)
+ if not code then
+ return
+ end
+ if type(code) == "number" then
+ return code
+ end
+ local u = unicodes[code]
+ if u then
+ -- unicodes[code] = u
+ return u
+ end
+ if utflen(code) == 1 then
+ u = utfbyte(code)
+ if u then
+ return u
+ end
+ end
+ local u = lpegmatch(p,code)
+ if u then
+ -- unicodes[code] = u
+ return u
+ end
+ if not aglunicodes then
+ aglunicodes = fonts.encodings.agl.unicodes -- delayed
+ end
+ local u = aglunicodes[code]
+ if u then
+ -- unicodes[code] = u
+ return u
+ end
+ end
+
+ local coverup = otf.coverup
+ local coveractions = coverup.actions
+ local stepkey = coverup.stepkey
+ local register = coverup.register
+
+ local function prepare_substitution(list,featuretype,nocheck)
+ local coverage = { }
+ local cover = coveractions[featuretype]
+ for code, replacement in next, list do
+ local unicode = tounicode(code)
+ local description = descriptions[unicode]
+ if not nocheck and not description then
+ skip = skip + 1
+ else
+ if type(replacement) == "table" then
+ replacement = replacement[1]
+ end
+ replacement = tounicode(replacement)
+ if replacement and descriptions[replacement] then
+ cover(coverage,unicode,replacement)
+ done = done + 1
+ else
+ skip = skip + 1
+ end
+ end
+ end
+ return coverage
+ end
+
+ local function prepare_alternate(list,featuretype,nocheck)
+ local coverage = { }
+ local cover = coveractions[featuretype]
+ for code, replacement in next, list do
+ local unicode = tounicode(code)
+ local description = descriptions[unicode]
+ if not nocheck and not description then
+ skip = skip + 1
+ elseif type(replacement) == "table" then
+ local r = { }
+ for i=1,#replacement do
+ local u = tounicode(replacement[i])
+ r[i] = (nocheck or descriptions[u]) and u or unicode
+ end
+ cover(coverage,unicode,r)
+ done = done + 1
+ else
+ local u = tounicode(replacement)
+ if u then
+ cover(coverage,unicode,{ u })
+ done = done + 1
+ else
+ skip = skip + 1
+ end
+ end
+ end
+ return coverage
+ end
+
+ local function prepare_multiple(list,featuretype,nocheck)
+ local coverage = { }
+ local cover = coveractions[featuretype]
+ for code, replacement in next, list do
+ local unicode = tounicode(code)
+ local description = descriptions[unicode]
+ if not nocheck and not description then
+ skip = skip + 1
+ elseif type(replacement) == "table" then
+ local r = { }
+ local n = 0
+ for i=1,#replacement do
+ local u = tounicode(replacement[i])
+ if nocheck or descriptions[u] then
+ n = n + 1
+ r[n] = u
+ end
+ end
+ if n > 0 then
+ cover(coverage,unicode,r)
+ done = done + 1
+ else
+ skip = skip + 1
+ end
+ else
+ local u = tounicode(replacement)
+ if u then
+ cover(coverage,unicode,{ u })
+ done = done + 1
+ else
+ skip = skip + 1
+ end
+ end
+ end
+ return coverage
+ end
+
+ local function prepare_ligature(list,featuretype,nocheck)
+ local coverage = { }
+ local cover = coveractions[featuretype]
+ for code, ligature in next, list do
+ local unicode = tounicode(code)
+ local description = descriptions[unicode]
+ if not nocheck and not description then
+ skip = skip + 1
+ else
+ if type(ligature) == "string" then
+ ligature = { lpegmatch(splitter,ligature) }
+ end
+ local present = true
+ for i=1,#ligature do
+ local l = ligature[i]
+ local u = tounicode(l)
+ if nocheck or descriptions[u] then
+ ligature[i] = u
+ else
+ present = false
+ break
+ end
+ end
+ if present then
+ cover(coverage,unicode,ligature)
+ done = done + 1
+ else
+ skip = skip + 1
+ end
+ end
+ end
+ return coverage
+ end
+
+ local function resetspacekerns()
+ -- a bit of a hack, this nil setting but it forces a
+ -- rehash of the resources needed .. the feature itself
+ -- should be a kern (at least for now)
+ data.properties.hasspacekerns = true
+ data.resources .spacekerns = nil
+ end
+
+ local function prepare_kern(list,featuretype)
+ local coverage = { }
+ local cover = coveractions[featuretype]
+ local isspace = false
+ for code, replacement in next, list do
+ local unicode = tounicode(code)
+ local description = descriptions[unicode]
+ if description and type(replacement) == "table" then
+ local r = { }
+ for k, v in next, replacement do
+ local u = tounicode(k)
+ if u then
+ r[u] = v
+ if u == 32 then
+ isspace = true
+ end
+ end
+ end
+ if next(r) then
+ cover(coverage,unicode,r)
+ done = done + 1
+ if unicode == 32 then
+ isspace = true
+ end
+ else
+ skip = skip + 1
+ end
+ else
+ skip = skip + 1
+ end
+ end
+ if isspace then
+ resetspacekerns()
+ end
+ return coverage
+ end
+
+ local function prepare_pair(list,featuretype)
+ local coverage = { }
+ local cover = coveractions[featuretype]
+ if cover then
+ for code, replacement in next, list do
+ local unicode = tounicode(code)
+ local description = descriptions[unicode]
+ if description and type(replacement) == "table" then
+ local r = { }
+ for k, v in next, replacement do
+ local u = tounicode(k)
+ if u then
+ r[u] = v
+ if u == 32 then
+ isspace = true
+ end
+ end
+ end
+ if next(r) then
+ cover(coverage,unicode,r)
+ done = done + 1
+ if unicode == 32 then
+ isspace = true
+ end
+ else
+ skip = skip + 1
+ end
+ else
+ skip = skip + 1
+ end
+ end
+ if isspace then
+ resetspacekerns()
+ end
+ else
+ report_otf("unknown cover type %a",featuretype)
+ end
+ return coverage
+ end
+
+ local prepare_single = prepare_pair -- we could have a better test on the spec
+
+ local function prepare_chain(list,featuretype,sublookups)
+ -- todo: coveractions
+ local rules = list.rules
+ local coverage = { }
+ if rules then
+ local rulehash = { }
+ local rulesize = 0
+ local lookuptype = types[featuretype]
+ for nofrules=1,#rules do
+ local rule = rules[nofrules]
+ local current = rule.current
+ local before = rule.before
+ local after = rule.after
+ local replacements = rule.replacements or false
+ local sequence = { }
+ local nofsequences = 0
+ if before then
+ for n=1,#before do
+ nofsequences = nofsequences + 1
+ sequence[nofsequences] = before[n]
+ end
+ end
+ local start = nofsequences + 1
+ for n=1,#current do
+ nofsequences = nofsequences + 1
+ sequence[nofsequences] = current[n]
+ end
+ local stop = nofsequences
+ if after then
+ for n=1,#after do
+ nofsequences = nofsequences + 1
+ sequence[nofsequences] = after[n]
+ end
+ end
+ local lookups = rule.lookups or false
+ local subtype = nil
+ if lookups and sublookups then
+ for k, v in sortedhash(lookups) do
+ 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 }
+ if not subtype then
+ subtype = lookup.type
+ end
+ elseif v == 0 then
+ lookups[k] = { { type = "gsub_remove" } }
+ else
+ lookups[k] = false -- { false } -- new
+ end
+ else
+ lookups[k] = false -- { false } -- new
+ end
+ end
+ end
+ if nofsequences > 0 then -- we merge coverage into one
+ -- we copy as we can have different fonts
+ local hashed = { }
+ for i=1,nofsequences do
+ local t = { }
+ local s = sequence[i]
+ for i=1,#s do
+ local u = tounicode(s[i])
+ if u then
+ t[u] = true
+ end
+ end
+ hashed[i] = t
+ end
+ sequence = hashed
+ -- now we create the rule
+ rulesize = rulesize + 1
+ rulehash[rulesize] = {
+ nofrules, -- 1
+ lookuptype, -- 2
+ sequence, -- 3
+ start, -- 4
+ stop, -- 5
+ lookups, -- 6 (6/7 also signal of what to do)
+ replacements, -- 7
+ subtype, -- 8
+ }
+-- for unic in next, sequence[start] do
+ for unic in sortedhash(sequence[start]) do
+ local cu = coverage[unic]
+ if not cu then
+ coverage[unic] = rulehash -- can now be done cleaner i think
+ end
+ end
+ sequence.n = nofsequences
+ end
+ end
+ rulehash.n = rulesize
+ end
+ return coverage
+ end
+
+ local dataset = specifications.dataset
+
+ local function report(name,category,position,first,last,sequences)
+ report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]",
+ name,category,position,first,last,1,#sequences)
+ end
+
+ local function inject(specification,sequences,sequence,first,last,category,name)
+ local position = specification.position or false
+ if not position then
+ position = specification.prepend
+ if position == true then
+ if trace_loading then
+ report(name,category,first,first,last,sequences)
+ end
+ insert(sequences,first,sequence)
+ return
+ end
+ end
+ if not position then
+ position = specification.append
+ if position == true then
+ if trace_loading then
+ report(name,category,last+1,first,last,sequences)
+ end
+ insert(sequences,last+1,sequence)
+ return
+ end
+ end
+ local kind = type(position)
+ if kind == "string" then
+ local index = false
+ for i=first,last do
+ local s = sequences[i]
+ local f = s.features
+ if f then
+ for k in sortedhash(f) do -- next, f do
+ if k == position then
+ index = i
+ break
+ end
+ end
+ if index then
+ break
+ end
+ end
+ end
+ if index then
+ position = index
+ else
+ position = last + 1
+ end
+ elseif kind == "number" then
+ if position < 0 then
+ position = last - position + 1
+ end
+ if position > last then
+ position = last + 1
+ elseif position < first then
+ position = first
+ end
+ else
+ position = last + 1
+ end
+ if trace_loading then
+ report(name,category,position,first,last,sequences)
+ end
+ insert(sequences,position,sequence)
+ end
+
+ for s=1,#dataset do
+ local specification = dataset[s]
+ local valid = specification.valid -- nowhere used
+ local feature = specification.name or feature
+ if not feature or feature == "" then
+ report_otf("no valid name given for extra feature")
+ elseif not valid or valid(data,specification,feature) then -- anum uses this
+ local initialize = specification.initialize
+ if initialize then
+ -- when false is returned we initialize only once
+ specification.initialize = initialize(specification,data) and initialize or nil
+ end
+ local askedfeatures = specification.features or everywhere
+ local askedsteps = specification.steps or specification.subtables or { specification.data } or { }
+ local featuretype = normalized[specification.type or "substitution"] or "substitution"
+ local featureflags = specification.flags or noflags
+ local nocheck = specification.nocheck
+ local futuresteps = specification.futuresteps
+ local featureorder = specification.order or { feature }
+ local featurechain = (featuretype == "chainsubstitution" or featuretype == "chainposition") and 1 or 0
+ local nofsteps = 0
+ local steps = { }
+ local sublookups = specification.lookups
+ local category = nil
+ --
+ checkflags(specification,resources)
+ --
+ if sublookups then
+ local s = { }
+ for i=1,#sublookups do
+ local specification = sublookups[i]
+ local askedsteps = specification.steps or specification.subtables or { specification.data } or { }
+ local featuretype = normalized[specification.type or "substitution"] or "substitution"
+ local featureflags = specification.flags or noflags
+ local nofsteps = 0
+ local steps = { }
+ for i=1,#askedsteps do
+ local list = askedsteps[i]
+ local coverage = nil
+ local format = nil
+ if featuretype == "substitution" then
+ coverage = prepare_substitution(list,featuretype,nocheck)
+ elseif featuretype == "ligature" then
+ coverage = prepare_ligature(list,featuretype,nocheck)
+ elseif featuretype == "alternate" then
+ coverage = prepare_alternate(list,featuretype,nocheck)
+ elseif featuretype == "multiple" then
+ coverage = prepare_multiple(list,featuretype,nocheck)
+ elseif featuretype == "kern" or featuretype == "move" then
+ format = featuretype
+ coverage = prepare_kern(list,featuretype)
+ elseif featuretype == "pair" then
+ format = "pair"
+ coverage = prepare_pair(list,featuretype)
+ elseif featuretype == "single" then
+ format = "single"
+ coverage = prepare_single(list,featuretype)
+ end
+ if coverage and next(coverage) then
+ nofsteps = nofsteps + 1
+ steps[nofsteps] = register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
+ end
+ end
+ --
+ checkmerge(specification)
+ checksteps(specification)
+ --
+ s[i] = {
+ [stepkey] = steps,
+ nofsteps = nofsteps,
+ flags = featureflags,
+ type = types[featuretype],
+ }
+ end
+ sublookups = s
+ end
+ for i=1,#askedsteps do
+ local list = askedsteps[i]
+ local coverage = nil
+ local format = nil
+ if featuretype == "substitution" then
+ category = "gsub"
+ coverage = prepare_substitution(list,featuretype,nocheck)
+ elseif featuretype == "ligature" then
+ category = "gsub"
+ coverage = prepare_ligature(list,featuretype,nocheck)
+ elseif featuretype == "alternate" then
+ category = "gsub"
+ coverage = prepare_alternate(list,featuretype,nocheck)
+ elseif featuretype == "multiple" then
+ category = "gsub"
+ coverage = prepare_multiple(list,featuretype,nocheck)
+ elseif featuretype == "kern" or featuretype == "move" then
+ category = "gpos"
+ format = featuretype
+ coverage = prepare_kern(list,featuretype)
+ elseif featuretype == "pair" then
+ category = "gpos"
+ format = "pair"
+ coverage = prepare_pair(list,featuretype)
+ elseif featuretype == "single" then
+ category = "gpos"
+ format = "single"
+ coverage = prepare_single(list,featuretype)
+ elseif featuretype == "chainsubstitution" then
+ category = "gsub"
+ coverage = prepare_chain(list,featuretype,sublookups)
+ elseif featuretype == "chainposition" then
+ category = "gpos"
+ coverage = prepare_chain(list,featuretype,sublookups)
+ else
+ report_otf("not registering feature %a, unknown category",feature)
+ return
+ end
+ if coverage and next(coverage) then
+ nofsteps = nofsteps + 1
+ steps[nofsteps] = register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
+ end
+ end
+ if nofsteps > 0 then
+ -- script = { lang1, lang2, lang3 } or script = { lang1 = true, ... }
+ for k, v in next, askedfeatures do
+ if v[1] then
+ askedfeatures[k] = tohash(v)
+ end
+ end
+ --
+ if featureflags[1] then featureflags[1] = "mark" end
+ if featureflags[2] then featureflags[2] = "ligature" end
+ if featureflags[3] then featureflags[3] = "base" end
+ local steptype = types[featuretype]
+ local sequence = {
+ chain = featurechain,
+ features = { [feature] = askedfeatures },
+ flags = featureflags,
+ name = feature, -- redundant
+ order = featureorder,
+ [stepkey] = steps,
+ nofsteps = nofsteps,
+ type = steptype,
+ }
+ --
+ checkflags(sequence,resources)
+ checkmerge(sequence)
+ checksteps(sequence)
+ -- position | prepend | append
+ local first, last = getrange(sequences,category)
+ inject(specification,sequences,sequence,first,last,category,feature)
+ -- register in metadata (merge as there can be a few)
+ local features = fontfeatures[category]
+ if not features then
+ features = { }
+ fontfeatures[category] = features
+ end
+ local k = features[feature]
+ if not k then
+ k = { }
+ features[feature] = k
+ end
+ --
+ for script, languages in next, askedfeatures do
+ local kk = k[script]
+ if not kk then
+ kk = { }
+ k[script] = kk
+ end
+ for language, value in next, languages do
+ kk[language] = value
+ end
+ end
+ end
+ end
+ end
+ if trace_loading then
+ report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip)
+ end
+end
+
+otf.enhancers.addfeature = addfeature
+
+local extrafeatures = { }
+local knownfeatures = { }
+
+function otf.addfeature(name,specification)
+ if type(name) == "table" then
+ specification = name
+ end
+ if type(specification) ~= "table" then
+ report_otf("invalid feature specification, no valid table")
+ return
+ end
+ specification, name = validspecification(specification,name)
+ if name and specification then
+ local slot = knownfeatures[name]
+ if not slot then
+ -- we have a new one
+ slot = #extrafeatures + 1
+ knownfeatures[name] = slot
+ elseif specification.overload == false then
+ -- we add an extre one
+ slot = #extrafeatures + 1
+ knownfeatures[name] = slot
+ else
+ -- we overload a previous one
+ end
+ specification.name = name -- to be sure
+ extrafeatures[slot] = specification
+ -- report_otf("adding feature %a @ %i",name,slot)
+ end
+end
+
+-- for feature, specification in next, extrafeatures do
+-- addfeature(data,feature,specification)
+-- end
+
+local function enhance(data,filename,raw)
+ for slot=1,#extrafeatures do
+ local specification = extrafeatures[slot]
+ addfeature(data,specification.name,specification)
+ end
+end
+
+otf.enhancers.enhance = enhance
+
+otf.enhancers.register("check extra features",enhance)
+
+-- fonts.handlers.otf.features.register {
+-- name = 'hangulfix',
+-- description = 'fixes for hangul',
+-- }
+
+-- fonts.handlers.otf.addfeature {
+-- name = "stest",
+-- type = "substitution",
+-- data = {
+-- a = "X",
+-- b = "P",
+-- }
+-- }
+-- fonts.handlers.otf.addfeature {
+-- name = "atest",
+-- type = "alternate",
+-- data = {
+-- a = { "X", "Y" },
+-- b = { "P", "Q" },
+-- }
+-- }
+-- fonts.handlers.otf.addfeature {
+-- name = "mtest",
+-- type = "multiple",
+-- data = {
+-- a = { "X", "Y" },
+-- b = { "P", "Q" },
+-- }
+-- }
+-- fonts.handlers.otf.addfeature {
+-- name = "ltest",
+-- type = "ligature",
+-- data = {
+-- X = { "a", "b" },
+-- Y = { "d", "a" },
+-- }
+-- }
+-- fonts.handlers.otf.addfeature {
+-- name = "ktest",
+-- type = "kern",
+-- data = {
+-- a = { b = -500 },
+-- }
+-- }
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-oti.lua b/macros/luatex/generic/luaotfload/fontloader-font-oti.lua
new file mode 100644
index 0000000000..4c6053be07
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-oti.lua
@@ -0,0 +1,262 @@
+if not modules then modules = { } end modules ['font-oti'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local lower = string.lower
+
+local fonts = fonts
+local constructors = fonts.constructors
+
+local otf = constructors.handlers.otf
+local otffeatures = constructors.features.otf
+local registerotffeature = otffeatures.register
+
+local otftables = otf.tables or { }
+otf.tables = otftables
+
+local allocate = utilities.storage.allocate
+
+registerotffeature {
+ name = "features",
+ description = "initialization of feature handler",
+ default = true,
+}
+
+-- these are later hooked into node and base initializaters
+
+local function setmode(tfmdata,value)
+ if value then
+ tfmdata.properties.mode = lower(value)
+ end
+end
+
+otf.modeinitializer = setmode
+
+local function setlanguage(tfmdata,value)
+ if value then
+ local cleanvalue = lower(value)
+ local languages = otftables and otftables.languages
+ local properties = tfmdata.properties
+ if not languages then
+ properties.language = cleanvalue
+ elseif languages[value] then
+ properties.language = cleanvalue
+ else
+ properties.language = "dflt"
+ end
+ end
+end
+
+local function setscript(tfmdata,value)
+ if value then
+ local cleanvalue = lower(value)
+ local scripts = otftables and otftables.scripts
+ local properties = tfmdata.properties
+ if not scripts then
+ properties.script = cleanvalue
+ elseif scripts[value] then
+ properties.script = cleanvalue
+ else
+ properties.script = "dflt"
+ end
+ end
+end
+
+registerotffeature {
+ name = "mode",
+ description = "mode",
+ initializers = {
+ base = setmode,
+ node = setmode,
+ plug = setmode,
+ }
+}
+
+registerotffeature {
+ name = "language",
+ description = "language",
+ initializers = {
+ base = setlanguage,
+ node = setlanguage,
+ plug = setlanguage,
+ }
+}
+
+registerotffeature {
+ name = "script",
+ description = "script",
+ initializers = {
+ base = setscript,
+ node = setscript,
+ plug = setscript,
+ }
+}
+
+-- here (as also in generic
+
+otftables.featuretypes = allocate {
+ gpos_single = "position",
+ gpos_pair = "position",
+ gpos_cursive = "position",
+ gpos_mark2base = "position",
+ gpos_mark2ligature = "position",
+ gpos_mark2mark = "position",
+ gpos_context = "position",
+ gpos_contextchain = "position",
+ gsub_single = "substitution",
+ gsub_multiple = "substitution",
+ gsub_alternate = "substitution",
+ gsub_ligature = "substitution",
+ gsub_context = "substitution",
+ gsub_contextchain = "substitution",
+ gsub_reversecontextchain = "substitution",
+ gsub_reversesub = "substitution",
+}
+
+function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts)
+ if featuretype == "position" then
+ local default = scripts.dflt
+ if default then
+ if autoscript == "position" or autoscript == true then
+ return default
+ else
+ report_otf("script feature %s not applied, enable default positioning")
+ end
+ else
+ -- no positioning at all
+ end
+ elseif featuretype == "substitution" then
+ local default = scripts.dflt
+ if default then
+ if autoscript == "substitution" or autoscript == true then
+ return default
+ end
+ end
+ end
+end
+
+function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
+ if featuretype == "position" then
+ local default = languages.dflt
+ if default then
+ if autolanguage == "position" or autolanguage == true then
+ return default
+ else
+ report_otf("language feature %s not applied, enable default positioning")
+ end
+ else
+ -- no positioning at all
+ end
+ elseif featuretype == "substitution" then
+ local default = languages.dflt
+ if default then
+ if autolanguage == "substitution" or autolanguage == true then
+ return default
+ end
+ end
+ end
+end
+
+-- the following might become available generic in due time but for now
+-- this is some context playground (development code)
+
+-- if not context then
+-- return
+-- end
+
+-- local helpers = otf.readers.helpers
+-- local axistofactors = helpers.axistofactors
+-- local normalizedaxis = helpers.normalizedaxis
+-- local getaxisscale = helpers.getaxisscale
+-- local cleanname = containers.cleanname
+
+-- local function validvariable(tfmdata)
+-- if tfmdata.properties.factors then
+-- return
+-- end
+-- local resources = tfmdata.resources
+-- local variabledata = resources and resources.variabledata
+-- if not variabledata then
+-- return
+-- end
+-- local instances = variabledata.instances
+-- local axis = variabledata.axis
+-- local segments = variabledata.segments
+-- if instances and axis then
+-- return instances, axis, segments
+-- end
+-- end
+
+-- local function initializeinstance(tfmdata,value)
+-- if type(value) == "string" then
+-- local instances, axis, segments = validvariable(tfmdata)
+-- if instances then
+-- local values
+-- for i=1,#instances do
+-- local instance = instances[i]
+-- if cleanname(instance.subfamily) == value then
+-- values = instance.values
+-- break
+-- end
+-- end
+-- if values then
+-- local factors = { }
+-- for i=1,#axis do
+-- local a = axis[i]
+-- factors[i] = getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value)
+-- end
+-- tfmdata.properties.instance = {
+-- hash = instance,
+-- factors = factors,
+-- }
+-- end
+-- else
+-- report("incomplete variable data")
+-- end
+-- end
+-- end
+
+-- local function initializeaxis(tfmdata,value)
+-- if type(value) == "string" then
+-- local instances, axis, segments = validvariable(tfmdata)
+-- if instances then
+-- local values = axistofactors(value)
+-- if values then
+-- local factors = { }
+-- for i=1,#axis do
+-- local a = axis[i]
+-- local d = a.default
+-- factors[i] = getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d)
+-- end
+-- tfmdata.properties.instance = {
+-- hash = cleanname(value),
+-- factors = factors,
+-- }
+-- end
+-- else
+-- report("incomplete variable data")
+-- end
+-- end
+-- end
+
+-- registerotffeature {
+-- name = "instance",
+-- description = "variation instance",
+-- initializers = {
+-- node = initializeinstance,
+-- base = initializeinstance,
+-- }
+-- }
+
+-- registerotffeature {
+-- name = "axis",
+-- description = "variation axis",
+-- initializers = {
+-- node = initializeaxis,
+-- base = initializeaxis,
+-- }
+-- }
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otj.lua b/macros/luatex/generic/luaotfload/fontloader-font-otj.lua
new file mode 100644
index 0000000000..2e7878d3df
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-otj.lua
@@ -0,0 +1,1755 @@
+if not modules then modules = { } end modules ['font-otj'] = {
+ version = 1.001,
+ comment = "companion to font-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+-- This property based variant is not faster but looks nicer than the attribute one. We
+-- need to use rawget (which is about 4 times slower than a direct access but we cannot
+-- get/set that one for our purpose! This version does a bit more with discretionaries
+-- (and Kai has tested it with his collection of weird fonts.)
+
+-- There is some duplicate code here (especially in the the pre/post/replace branches) but
+-- we go for speed. We could store a list of glyph and mark nodes when registering but it's
+-- cleaner to have an identification pass here. Also, I need to keep tracing in mind so
+-- being too clever here is dangerous.
+
+-- As we have a rawget on properties we don't need one on injections.
+
+-- The use_advance code was just a test and is meant for testing and manuals. There is no
+-- performance (or whatever) gain and using kerns is somewhat cleaner (at least for now).
+
+-- An alternative is to have a list per base of all marks and then do a run over the node
+-- list that resolves the accumulated l/r/x/y and then do an inject pass.
+
+-- if needed we can flag a kern node as immutable
+
+-- The thing with these positioning options is that it is not clear what Uniscribe does with
+-- the 2rl flag and we keep oscillating a between experiments.
+
+if not nodes.properties then return end
+
+local next, rawget, tonumber = next, rawget, tonumber
+local fastcopy = table.fastcopy
+
+local registertracker = trackers.register
+local registerdirective = directives.register
+
+local trace_injections = false registertracker("fonts.injections", function(v) trace_injections = v end)
+local trace_marks = false registertracker("fonts.injections.marks", function(v) trace_marks = v end)
+local trace_cursive = false registertracker("fonts.injections.cursive", function(v) trace_cursive = v end)
+local trace_spaces = false registertracker("fonts.injections.spaces", function(v) trace_spaces = v end)
+
+-- local fix_cursive_marks = false
+--
+-- registerdirective("fonts.injections.fixcursivemarks", function(v)
+-- fix_cursive_marks = v
+-- end)
+
+local report_injections = logs.reporter("fonts","injections")
+local report_spaces = logs.reporter("fonts","spaces")
+
+local attributes, nodes, node = attributes, nodes, node
+
+fonts = fonts
+local hashes = fonts.hashes
+local fontdata = hashes.identifiers
+local fontmarks = hashes.marks
+----- parameters = fonts.hashes.parameters -- not in generic
+----- resources = fonts.hashes.resources -- not in generic
+
+nodes.injections = nodes.injections or { }
+local injections = nodes.injections
+
+local tracers = nodes.tracers
+local setcolor = tracers and tracers.colors.set
+local resetcolor = tracers and tracers.colors.reset
+
+local nodecodes = nodes.nodecodes
+local glyph_code = nodecodes.glyph
+local disc_code = nodecodes.disc
+local kern_code = nodecodes.kern
+local glue_code = nodecodes.glue
+
+local nuts = nodes.nuts
+local nodepool = nuts.pool
+
+local tonode = nuts.tonode
+local tonut = nuts.tonut
+
+local setfield = nuts.setfield
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getid = nuts.getid
+local getfont = nuts.getfont
+local getchar = nuts.getchar
+local getoffsets = nuts.getoffsets
+local getboth = nuts.getboth
+local getdisc = nuts.getdisc
+local setdisc = nuts.setdisc
+local setoffsets = nuts.setoffsets
+local ischar = nuts.ischar
+local getkern = nuts.getkern
+local setkern = nuts.setkern
+local setlink = nuts.setlink
+local setwidth = nuts.setwidth
+local getwidth = nuts.getwidth
+
+----- traverse_id = nuts.traverse_id
+----- traverse_char = nuts.traverse_char
+local nextchar = nuts.traversers.char
+local nextglue = nuts.traversers.glue
+
+local insert_node_before = nuts.insert_before
+local insert_node_after = nuts.insert_after
+
+local properties = nodes.properties.data
+
+local fontkern = nuts.pool and nuts.pool.fontkern -- context
+local italickern = nuts.pool and nuts.pool.italickern -- context
+
+local useitalickerns = false
+
+directives.register("fonts.injections.useitalics", function(v)
+ if v then
+ report_injections("using italics for space kerns (tracing only)")
+ end
+ useitalickerns = v
+end)
+
+do if not fontkern then -- generic
+
+ local thekern = nuts.new("kern",0) -- fontkern
+ local setkern = nuts.setkern
+ local copy_node = nuts.copy_node
+
+ fontkern = function(k)
+ local n = copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
+
+end end
+
+do if not italickern then -- generic
+
+ local thekern = nuts.new("kern",3) -- italiccorrection
+ local setkern = nuts.setkern
+ local copy_node = nuts.copy_node
+
+ italickern = function(k)
+ local n = copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
+
+end end
+
+function injections.installnewkern() end -- obsolete
+
+local nofregisteredkerns = 0
+local nofregisteredpositions = 0
+local nofregisteredmarks = 0
+local nofregisteredcursives = 0
+local keepregisteredcounts = false
+
+function injections.keepcounts()
+ keepregisteredcounts = true
+end
+
+function injections.resetcounts()
+ nofregisteredkerns = 0
+ nofregisteredpositions = 0
+ nofregisteredmarks = 0
+ nofregisteredcursives = 0
+ keepregisteredcounts = false
+end
+
+-- We need to make sure that a possible metatable will not kick in unexpectedly.
+
+function injections.reset(n)
+ local p = rawget(properties,n)
+ if p then
+ p.injections = false -- { } -- nil should work too as we use rawget
+ else
+ properties[n] = false -- { injections = { } } -- nil should work too as we use rawget
+ end
+end
+
+function injections.copy(target,source)
+ local sp = rawget(properties,source)
+ if sp then
+ local tp = rawget(properties,target)
+ local si = sp.injections
+ if si then
+ si = fastcopy(si)
+ if tp then
+ tp.injections = si
+ else
+ properties[target] = {
+ injections = si,
+ }
+ end
+ elseif tp then
+ tp.injections = false -- { }
+ else
+ properties[target] = { injections = { } }
+ end
+ else
+ local tp = rawget(properties,target)
+ if tp then
+ tp.injections = false -- { }
+ else
+ properties[target] = false -- { injections = { } }
+ end
+ end
+end
+
+function injections.setligaindex(n,index) -- todo: don't set when 0
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections
+ if i then
+ i.ligaindex = index
+ else
+ p.injections = {
+ ligaindex = index
+ }
+ end
+ else
+ properties[n] = {
+ injections = {
+ ligaindex = index
+ }
+ }
+ end
+end
+
+function injections.getligaindex(n,default)
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections
+ if i then
+ return i.ligaindex or default
+ end
+ end
+ return default
+end
+
+function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext,r2lflag)
+
+ -- The standard says something about the r2lflag related to the first in a series:
+ --
+ -- When this bit is set, the last glyph in a given sequence to which the cursive
+ -- attachment lookup is applied, will be positioned on the baseline.
+ --
+ -- But it looks like we don't need to consider it.
+
+ local dx = factor*(exit[1]-entry[1])
+ local dy = -factor*(exit[2]-entry[2])
+ local ws = tfmstart.width
+ local wn = tfmnext.width
+ nofregisteredcursives = nofregisteredcursives + 1
+ if rlmode < 0 then
+ dx = -(dx + wn)
+ else
+ dx = dx - ws
+ end
+ if dx == 0 then
+ -- get rid of funny -0
+ dx = 0
+ end
+ --
+ local p = rawget(properties,start)
+ if p then
+ local i = p.injections
+ if i then
+ i.cursiveanchor = true
+ else
+ p.injections = {
+ cursiveanchor = true,
+ }
+ end
+ else
+ properties[start] = {
+ injections = {
+ cursiveanchor = true,
+ },
+ }
+ end
+ local p = rawget(properties,nxt)
+ if p then
+ local i = p.injections
+ if i then
+ i.cursivex = dx
+ i.cursivey = dy
+ else
+ p.injections = {
+ cursivex = dx,
+ cursivey = dy,
+ }
+ end
+ else
+ properties[nxt] = {
+ injections = {
+ cursivex = dx,
+ cursivey = dy,
+ },
+ }
+ end
+ return dx, dy, nofregisteredcursives
+end
+
+-- kind: 0=single 1=first of pair, 2=second of pair
+
+function injections.setposition(kind,current,factor,rlmode,spec,injection)
+ local x = factor * (spec[1] or 0)
+ local y = factor * (spec[2] or 0)
+ local w = factor * (spec[3] or 0)
+ local h = factor * (spec[4] or 0)
+ if x ~= 0 or w ~= 0 or y ~= 0 or h ~= 0 then -- okay?
+ local yoffset = y - h
+ local leftkern = x -- both kerns are set in a pair kern compared
+ local rightkern = w - x -- to normal kerns where we set only leftkern
+ if leftkern ~= 0 or rightkern ~= 0 or yoffset ~= 0 then
+ nofregisteredpositions = nofregisteredpositions + 1
+ if rlmode and rlmode < 0 then
+ leftkern, rightkern = rightkern, leftkern
+ end
+ if not injection then
+ injection = "injections"
+ end
+ local p = rawget(properties,current)
+ if p then
+ local i = p[injection]
+ if i then
+ if leftkern ~= 0 then
+ i.leftkern = (i.leftkern or 0) + leftkern
+ end
+ if rightkern ~= 0 then
+ i.rightkern = (i.rightkern or 0) + rightkern
+ end
+ if yoffset ~= 0 then
+ i.yoffset = (i.yoffset or 0) + yoffset
+ end
+ elseif leftkern ~= 0 or rightkern ~= 0 then
+ p[injection] = {
+ leftkern = leftkern,
+ rightkern = rightkern,
+ yoffset = yoffset,
+ }
+ else
+ p[injection] = {
+ yoffset = yoffset,
+ }
+ end
+ elseif leftkern ~= 0 or rightkern ~= 0 then
+ properties[current] = {
+ [injection] = {
+ leftkern = leftkern,
+ rightkern = rightkern,
+ yoffset = yoffset,
+ },
+ }
+ else
+ properties[current] = {
+ [injection] = {
+ yoffset = yoffset,
+ },
+ }
+ end
+ return x, y, w, h, nofregisteredpositions
+ end
+ end
+ return x, y, w, h -- no bound
+end
+
+-- The next one is used for simple kerns coming from a truetype kern table. The r2l
+-- variant variant needs checking but it is unlikely that a r2l script uses thsi
+-- feature.
+
+function injections.setkern(current,factor,rlmode,x,injection)
+ local dx = factor * x
+ if dx ~= 0 then
+ nofregisteredkerns = nofregisteredkerns + 1
+ local p = rawget(properties,current)
+ if not injection then
+ injection = "injections"
+ end
+ if p then
+ local i = p[injection]
+ if i then
+ i.leftkern = dx + (i.leftkern or 0)
+ else
+ p[injection] = {
+ leftkern = dx,
+ }
+ end
+ else
+ properties[current] = {
+ [injection] = {
+ leftkern = dx,
+ },
+ }
+ end
+ return dx, nofregisteredkerns
+ else
+ return 0, 0
+ end
+end
+
+-- This one is an optimization of pairs where we have only a "w" entry. This one is
+-- potentially different from the previous one wrt r2l. It needs checking. The
+-- optimization relates to smaller tma files.
+
+function injections.setmove(current,factor,rlmode,x,injection)
+ local dx = factor * x
+ if dx ~= 0 then
+ nofregisteredkerns = nofregisteredkerns + 1
+ local p = rawget(properties,current)
+ if not injection then
+ injection = "injections"
+ end
+ if rlmode and rlmode < 0 then
+ -- we need to swap with a single so then we also need to to it here
+ -- as move is just a simple single
+ if p then
+ local i = p[injection]
+ if i then
+ i.rightkern = dx + (i.rightkern or 0)
+ else
+ p[injection] = {
+ rightkern = dx,
+ }
+ end
+ else
+ properties[current] = {
+ [injection] = {
+ rightkern = dx,
+ },
+ }
+ end
+ else
+ if p then
+ local i = p[injection]
+ if i then
+ i.leftkern = dx + (i.leftkern or 0)
+ else
+ p[injection] = {
+ leftkern = dx,
+ }
+ end
+ else
+ properties[current] = {
+ [injection] = {
+ leftkern = dx,
+ },
+ }
+ end
+ end
+ return dx, nofregisteredkerns
+ else
+ return 0, 0
+ end
+end
+
+function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) -- ba=baseanchor, ma=markanchor
+ local dx = factor*(ba[1]-ma[1])
+ local dy = factor*(ba[2]-ma[2])
+ nofregisteredmarks = nofregisteredmarks + 1
+ if rlmode >= 0 then
+ dx = tfmbase.width - dx -- see later commented ox
+ end
+ local p = rawget(properties,start)
+ -- hm, dejavu serif does a sloppy mark2mark before mark2base
+ if p then
+ local i = p.injections
+ if i then
+ if i.markmark then
+ -- out of order mkmk: yes or no or option
+ else
+ -- if dx ~= 0 then
+ -- i.markx = dx
+ -- end
+ -- if y ~= 0 then
+ -- i.marky = dy
+ -- end
+ -- if rlmode then
+ -- i.markdir = rlmode
+ -- end
+ i.markx = dx
+ i.marky = dy
+ i.markdir = rlmode or 0
+ i.markbase = nofregisteredmarks
+ i.markbasenode = base
+ i.markmark = mkmk
+ i.checkmark = checkmark
+ end
+ else
+ p.injections = {
+ markx = dx,
+ marky = dy,
+ markdir = rlmode or 0,
+ markbase = nofregisteredmarks,
+ markbasenode = base,
+ markmark = mkmk,
+ checkmark = checkmark,
+ }
+ end
+ else
+ properties[start] = {
+ injections = {
+ markx = dx,
+ marky = dy,
+ markdir = rlmode or 0,
+ markbase = nofregisteredmarks,
+ markbasenode = base,
+ markmark = mkmk,
+ checkmark = checkmark,
+ },
+ }
+ end
+ return dx, dy, nofregisteredmarks
+end
+
+local function dir(n)
+ return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset"
+end
+
+local function showchar(n,nested)
+ local char = getchar(n)
+ report_injections("%wfont %s, char %U, glyph %c",nested and 2 or 0,getfont(n),char,char)
+end
+
+local function show(n,what,nested,symbol)
+ if n then
+ local p = rawget(properties,n)
+ if p then
+ local i = p[what]
+ if i then
+ local leftkern = i.leftkern or 0
+ local rightkern = i.rightkern or 0
+ local yoffset = i.yoffset or 0
+ local markx = i.markx or 0
+ local marky = i.marky or 0
+ local markdir = i.markdir or 0
+ local markbase = i.markbase or 0
+ local cursivex = i.cursivex or 0
+ local cursivey = i.cursivey or 0
+ local ligaindex = i.ligaindex or 0
+ local cursbase = i.cursiveanchor
+ local margin = nested and 4 or 2
+ --
+ if rightkern ~= 0 or yoffset ~= 0 then
+ report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset)
+ elseif leftkern ~= 0 then
+ report_injections("%w%s kern: dx %p",margin,symbol,leftkern)
+ end
+ if markx ~= 0 or marky ~= 0 or markbase ~= 0 then
+ report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase ~= 0 and "yes" or "no")
+ end
+ if cursivex ~= 0 or cursivey ~= 0 then
+ if cursbase then
+ report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ else
+ report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ end
+ elseif cursbase then
+ report_injections("%w%s curs: base",margin,symbol)
+ end
+ if ligaindex ~= 0 then
+ report_injections("%w%s liga: index %i",margin,symbol,ligaindex)
+ end
+ end
+ end
+ end
+end
+
+local function showsub(n,what,where)
+ report_injections("begin subrun: %s",where)
+ for n in nextchar, n do
+ showchar(n,where)
+ show(n,what,where," ")
+ end
+ report_injections("end subrun")
+end
+
+local function trace(head,where)
+ report_injections()
+ report_injections("begin run %s: %s kerns, %s positions, %s marks and %s cursives registered",
+ where or "",nofregisteredkerns,nofregisteredpositions,nofregisteredmarks,nofregisteredcursives)
+ local n = head
+ while n do
+ local id = getid(n)
+ if id == glyph_code then
+ showchar(n)
+ show(n,"injections",false," ")
+ show(n,"preinjections",false,"<")
+ show(n,"postinjections",false,">")
+ show(n,"replaceinjections",false,"=")
+ show(n,"emptyinjections",false,"*")
+ elseif id == disc_code then
+ local pre, post, replace = getdisc(n)
+ if pre then
+ showsub(pre,"preinjections","pre")
+ end
+ if post then
+ showsub(post,"postinjections","post")
+ end
+ if replace then
+ showsub(replace,"replaceinjections","replace")
+ end
+ show(n,"emptyinjections",false,"*")
+ end
+ n = getnext(n)
+ end
+ report_injections("end run")
+end
+
+local function show_result(head)
+ local current = head
+ local skipping = false
+ while current do
+ local id = getid(current)
+ if id == glyph_code then
+ local w = getwidth(current)
+ local x, y = getoffsets(current)
+ report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y)
+ skipping = false
+ elseif id == kern_code then
+ report_injections("kern: %p",getkern(current))
+ skipping = false
+ elseif not skipping then
+ report_injections()
+ skipping = true
+ end
+ current = getnext(current)
+ end
+ report_injections()
+end
+
+-- G +D-pre G
+-- D-post+
+-- +D-replace+
+--
+-- G +D-pre +D-pre
+-- D-post +D-post
+-- +D-replace +D-replace
+
+local function inject_kerns_only(head,where)
+ if trace_injections then
+ trace(head,"kerns")
+ end
+ local current = head
+ local prev = nil
+ local next = nil
+ local prevdisc = nil
+ -- local prevglyph = nil
+ local pre = nil -- saves a lookup
+ local post = nil -- saves a lookup
+ local replace = nil -- saves a lookup
+ local pretail = nil -- saves a lookup
+ local posttail = nil -- saves a lookup
+ local replacetail = nil -- saves a lookup
+ while current do
+ local next = getnext(current)
+ local char, id = ischar(current)
+ if char then
+ local p = rawget(properties,current)
+ if p then
+ local i = p.injections
+ if i then
+ -- left|glyph|right
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ head = insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if prevdisc then
+ local done = false
+ if post then
+ local i = p.postinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setlink(posttail,fontkern(leftkern))
+ done = true
+ end
+ end
+ end
+ if replace then
+ local i = p.replaceinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setlink(replacetail,fontkern(leftkern))
+ done = true
+ end
+ end
+ else
+ local i = p.emptyinjections
+ if i then
+ -- glyph|disc|glyph (special case)
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ replace = fontkern(leftkern)
+ done = true
+ end
+ end
+ end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
+ end
+ end
+ end
+ prevdisc = nil
+ -- prevglyph = current
+ elseif char == false then
+ -- other font
+ prevdisc = nil
+ -- prevglyph = current
+ elseif id == disc_code then
+ pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
+ local done = false
+ if pre then
+ -- left|pre glyphs|right
+ for n in nextchar, pre do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.preinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ pre = insert_node_before(pre,n,fontkern(leftkern))
+ done = true
+ end
+ end
+ end
+ end
+ end
+ if post then
+ -- left|post glyphs|right
+ for n in nextchar, post do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.postinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ post = insert_node_before(post,n,fontkern(leftkern))
+ done = true
+ end
+ end
+ end
+ end
+ end
+ if replace then
+ -- left|replace glyphs|right
+ for n in nextchar, replace do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.replaceinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ replace = insert_node_before(replace,n,fontkern(leftkern))
+ done = true
+ end
+ end
+ end
+ end
+ end
+ if done then
+ setdisc(current,pre,post,replace)
+ end
+ -- prevglyph = nil
+ prevdisc = current
+ else
+ -- prevglyph = nil
+ prevdisc = nil
+ end
+ prev = current
+ current = next
+ end
+ --
+ if keepregisteredcounts then
+ keepregisteredcounts = false
+ else
+ nofregisteredkerns = 0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
+end
+
+local function inject_positions_only(head,where)
+ if trace_injections then
+ trace(head,"positions")
+ end
+ local current = head
+ local prev = nil
+ local next = nil
+ local prevdisc = nil
+ local prevglyph = nil
+ local pre = nil -- saves a lookup
+ local post = nil -- saves a lookup
+ local replace = nil -- saves a lookup
+ local pretail = nil -- saves a lookup
+ local posttail = nil -- saves a lookup
+ local replacetail = nil -- saves a lookup
+ while current do
+ local next = getnext(current)
+ local char, id = ischar(current)
+ if char then
+ local p = rawget(properties,current)
+ if p then
+ local i = p.injections
+ if i then
+ -- left|glyph|right
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setoffsets(current,false,yoffset)
+ end
+ local leftkern = i.leftkern
+ local rightkern = i.rightkern
+ if leftkern and leftkern ~= 0 then
+ if rightkern and leftkern == -rightkern then
+ setoffsets(current,leftkern,false)
+ rightkern = 0
+ else
+ head = insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(head,current,fontkern(rightkern))
+ end
+ else
+ local i = p.emptyinjections
+ if i then
+ -- glyph|disc|glyph (special case)
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ if next and getid(next) == disc_code then
+ if replace then
+ -- error, we expect an empty one
+ else
+ -- KE setfield(next,"replace",fontkern(rightkern)) -- maybe also leftkern
+ replace = fontkern(rightkern) -- maybe also leftkern
+ done = true --KE
+ end
+ end
+ end
+ end
+ end
+ if prevdisc then
+ local done = false
+ if post then
+ local i = p.postinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setlink(posttail,fontkern(leftkern))
+ done = true
+ end
+ end
+ end
+ if replace then
+ local i = p.replaceinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setlink(replacetail,fontkern(leftkern))
+ done = true
+ end
+ end
+ else
+ local i = p.emptyinjections
+ if i then
+ -- new .. okay?
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ replace = fontkern(leftkern)
+ done = true
+ end
+ end
+ end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
+ end
+ end
+ end
+ prevdisc = nil
+ prevglyph = current
+ elseif char == false then
+ prevdisc = nil
+ prevglyph = current
+ elseif id == disc_code then
+ pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
+ local done = false
+ if pre then
+ -- left|pre glyphs|right
+ for n in nextchar, pre do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.preinjections
+ if i then
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ pre = insert_node_before(pre,n,fontkern(leftkern))
+ done = true
+ end
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(pre,n,fontkern(rightkern))
+ done = true
+ end
+ end
+ end
+ end
+ end
+ if post then
+ -- left|post glyphs|right
+ for n in nextchar, post do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.postinjections
+ if i then
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ post = insert_node_before(post,n,fontkern(leftkern))
+ done = true
+ end
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(post,n,fontkern(rightkern))
+ done = true
+ end
+ end
+ end
+ end
+ end
+ if replace then
+ -- left|replace glyphs|right
+ for n in nextchar, replace do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.replaceinjections
+ if i then
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ replace = insert_node_before(replace,n,fontkern(leftkern))
+ done = true
+ end
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(replace,n,fontkern(rightkern))
+ done = true
+ end
+ end
+ end
+ end
+ end
+ if prevglyph then
+ if pre then
+ local p = rawget(properties,prevglyph)
+ if p then
+ local i = p.preinjections
+ if i then
+ -- glyph|pre glyphs
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ pre = insert_node_before(pre,pre,fontkern(rightkern))
+ done = true
+ end
+ end
+ end
+ end
+ if replace then
+ local p = rawget(properties,prevglyph)
+ if p then
+ local i = p.replaceinjections
+ if i then
+ -- glyph|replace glyphs
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ replace = insert_node_before(replace,replace,fontkern(rightkern))
+ done = true
+ end
+ end
+ end
+ end
+ end
+ if done then
+ setdisc(current,pre,post,replace)
+ end
+ prevglyph = nil
+ prevdisc = current
+ else
+ prevglyph = nil
+ prevdisc = nil
+ end
+ prev = current
+ current = next
+ end
+ --
+ if keepregisteredcounts then
+ keepregisteredcounts = false
+ else
+ nofregisteredpositions = 0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
+end
+
+local function showoffset(n,flag)
+ local x, y = getoffsets(n)
+ if x ~= 0 or y ~= 0 then
+ setcolor(n,"darkgray")
+ end
+end
+
+local function inject_everything(head,where)
+ if trace_injections then
+ trace(head,"everything")
+ end
+ local hascursives = nofregisteredcursives > 0
+ local hasmarks = nofregisteredmarks > 0
+ --
+ local current = head
+ local last = nil
+ local prev = nil
+ local next = nil
+ local prevdisc = nil
+ local prevglyph = nil
+ local pre = nil -- saves a lookup
+ local post = nil -- saves a lookup
+ local replace = nil -- saves a lookup
+ local pretail = nil -- saves a lookup
+ local posttail = nil -- saves a lookup
+ local replacetail = nil -- saves a lookup
+ --
+ local cursiveanchor = nil
+ local minc = 0
+ local maxc = 0
+ local glyphs = { }
+ local marks = { }
+ local nofmarks = 0
+ --
+ -- local applyfix = hascursives and fix_cursive_marks
+ --
+ -- move out
+ --
+ local function processmark(p,n,pn) -- p = basenode
+ local px, py = getoffsets(p)
+ local nx, ny = getoffsets(n)
+ local ox = 0
+ local rightkern = nil
+ local pp = rawget(properties,p)
+ if pp then
+ pp = pp.injections
+ if pp then
+ rightkern = pp.rightkern
+ end
+ end
+ local markdir = pn.markdir
+ if rightkern then -- x and w ~= 0
+ ox = px - (pn.markx or 0) - rightkern
+ if markdir and markdir < 0 then
+ -- kern(w-x) glyph(p) kern(x) mark(n)
+ if not pn.markmark then
+ ox = ox + (pn.leftkern or 0)
+ end
+ else
+ -- kern(x) glyph(p) kern(w-x) mark(n)
+ --
+ -- According to Kai we don't need to handle leftkern here but I'm
+ -- pretty sure I've run into a case where it was needed so maybe
+ -- some day we need something more clever here.
+ --
+ -- maybe we need to apply both then
+ --
+ if false then
+ -- a mark with kerning (maybe husayni needs it )
+ local leftkern = pp.leftkern
+ if leftkern then
+ ox = ox - leftkern
+ end
+ end
+ end
+ else
+ ox = px - (pn.markx or 0)
+ if markdir and markdir < 0 then
+ if not pn.markmark then
+ local leftkern = pn.leftkern
+ if leftkern then
+ ox = ox + leftkern -- husayni needs it
+ end
+ end
+ end
+ if pn.checkmark then
+ local wn = getwidth(n) -- in arial marks have widths
+ if wn and wn ~= 0 then
+ wn = wn/2
+ if trace_injections then
+ report_injections("correcting non zero width mark %C",getchar(n))
+ end
+ -- -- bad: we should center
+ --
+ -- pn.leftkern = -wn
+ -- pn.rightkern = -wn
+ --
+ -- -- 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
+ --
+ -- todo: head and check for prev / next kern
+ --
+ insert_node_before(n,n,fontkern(-wn))
+ insert_node_after(n,n,fontkern(-wn))
+ end
+ end
+ end
+ local oy = ny + py + (pn.marky or 0)
+ if not pn.markmark then
+ local yoffset = pn.yoffset
+ if yoffset then
+ oy = oy + yoffset -- husayni needs it
+ end
+ end
+ setoffsets(n,ox,oy)
+ if trace_marks then
+ showoffset(n,true)
+ end
+ end
+ -- begin of temp fix --
+ -- local base = nil -- bah, some arabic fonts have no mark anchoring
+ -- end of temp fix --
+ while current do
+ local next = getnext(current)
+ local char, id = ischar(current)
+ if char then
+ local p = rawget(properties,current)
+ -- begin of temp fix --
+ -- if applyfix then
+ -- if not p then
+ -- local m = fontmarks[getfont(current)]
+ -- if m and m[char] then
+ -- if base then
+ -- p = { injections = { markbasenode = base } }
+ -- nofmarks = nofmarks + 1
+ -- marks[nofmarks] = current
+ -- properties[current] = p
+ -- hasmarks = true
+ -- end
+ -- else
+ -- base = current
+ -- end
+ -- end
+ -- end
+ -- end of temp fix
+ if p then
+ local i = p.injections
+ -- begin of temp fix --
+ -- if applyfix then
+ -- if not i then
+ -- local m = fontmarks[getfont(current)]
+ -- if m and m[char] then
+ -- if base then
+ -- i = { markbasenode = base }
+ -- nofmarks = nofmarks + 1
+ -- marks[nofmarks] = current
+ -- p.injections = i
+ -- hasmarks = true
+ -- end
+ -- else
+ -- base = current
+ -- end
+ -- end
+ -- end
+ -- end of temp fix --
+ if i then
+ local pm = i.markbasenode
+ -- begin of temp fix --
+ -- if applyfix then
+ -- if not pm then
+ -- local m = fontmarks[getfont(current)]
+ -- if m and m[char] then
+ -- if base then
+ -- pm = base
+ -- i.markbasenode = pm
+ -- hasmarks = true
+ -- end
+ -- else
+ -- base = current
+ -- end
+ -- else
+ -- base = current
+ -- end
+ -- end
+ -- end of temp fix --
+ if pm then
+ nofmarks = nofmarks + 1
+ marks[nofmarks] = current
+ else
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setoffsets(current,false,yoffset)
+ end
+ if hascursives then
+ local cursivex = i.cursivex
+ if cursivex then
+ if cursiveanchor then
+ if cursivex ~= 0 then
+ i.leftkern = (i.leftkern or 0) + cursivex
+ end
+ if maxc == 0 then
+ minc = 1
+ maxc = 1
+ glyphs[1] = cursiveanchor
+ else
+ maxc = maxc + 1
+ glyphs[maxc] = cursiveanchor
+ end
+ properties[cursiveanchor].cursivedy = i.cursivey -- cursiveprops
+ last = current
+ else
+ maxc = 0
+ end
+ elseif maxc > 0 then
+ local nx, ny = getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti = glyphs[i]
+ ny = ny + properties[ti].cursivedy
+ setoffsets(ti,false,ny) -- why not add ?
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ maxc = 0
+ cursiveanchor = nil
+ end
+ if i.cursiveanchor then
+ cursiveanchor = current -- no need for both now
+ else
+ if maxc > 0 then
+ local nx, ny = getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti = glyphs[i]
+ ny = ny + properties[ti].cursivedy
+ setoffsets(ti,false,ny) -- why not add ?
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ maxc = 0
+ end
+ cursiveanchor = nil
+ end
+ end
+ -- left|glyph|right
+ local leftkern = i.leftkern
+ local rightkern = i.rightkern
+ if leftkern and leftkern ~= 0 then
+ if rightkern and leftkern == -rightkern then
+ setoffsets(current,leftkern,false)
+ rightkern = 0
+ else
+ head = insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(head,current,fontkern(rightkern))
+ end
+ end
+ else
+ local i = p.emptyinjections
+ if i then
+ -- glyph|disc|glyph (special case)
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ if next and getid(next) == disc_code then
+ if replace then
+ -- error, we expect an empty one
+ else
+ replace = fontkern(rightkern)
+ done = true
+ end
+ end
+ end
+ end
+ end
+ if prevdisc then
+ if p then
+ local done = false
+ if post then
+ local i = p.postinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setlink(posttail,fontkern(leftkern))
+ done = true
+ end
+ end
+ end
+ if replace then
+ local i = p.replaceinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ setlink(replacetail,fontkern(leftkern))
+ done = true
+ end
+ end
+ else
+ local i = p.emptyinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ replace = fontkern(leftkern)
+ done = true
+ end
+ end
+ end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
+ end
+ end
+ end
+ else
+ -- cursive
+ if hascursives and maxc > 0 then
+ local nx, ny = getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti = glyphs[i]
+ ny = ny + properties[ti].cursivedy
+ local xi, yi = getoffsets(ti)
+ setoffsets(ti,xi,yi + ny) -- can be mark, we could use properties
+ end
+ maxc = 0
+ cursiveanchor = nil
+ end
+ end
+ prevdisc = nil
+ prevglyph = current
+ elseif char == false then
+ -- base = nil
+ prevdisc = nil
+ prevglyph = current
+ elseif id == disc_code then
+ -- base = nil
+ pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
+ local done = false
+ if pre then
+ -- left|pre glyphs|right
+ for n in nextchar, pre do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.preinjections
+ if i then
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ pre = insert_node_before(pre,n,fontkern(leftkern))
+ done = true
+ end
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(pre,n,fontkern(rightkern))
+ done = true
+ end
+ if hasmarks then
+ local pm = i.markbasenode
+ if pm then
+ processmark(pm,n,i)
+ end
+ end
+ end
+ end
+ end
+ end
+ if post then
+ -- left|post glyphs|right
+ for n in nextchar, post do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.postinjections
+ if i then
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ post = insert_node_before(post,n,fontkern(leftkern))
+ done = true
+ end
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(post,n,fontkern(rightkern))
+ done = true
+ end
+ if hasmarks then
+ local pm = i.markbasenode
+ if pm then
+ processmark(pm,n,i)
+ end
+ end
+ end
+ end
+ end
+ end
+ if replace then
+ -- left|replace glyphs|right
+ for n in nextchar, replace do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.replaceinjections
+ if i then
+ local yoffset = i.yoffset
+ if yoffset and yoffset ~= 0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ replace = insert_node_before(replace,n,fontkern(leftkern))
+ done = true
+ end
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ insert_node_after(replace,n,fontkern(rightkern))
+ done = true
+ end
+ if hasmarks then
+ local pm = i.markbasenode
+ if pm then
+ processmark(pm,n,i)
+ end
+ end
+ end
+ end
+ end
+ end
+ if prevglyph then
+ if pre then
+ local p = rawget(properties,prevglyph)
+ if p then
+ local i = p.preinjections
+ if i then
+ -- glyph|pre glyphs
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ pre = insert_node_before(pre,pre,fontkern(rightkern))
+ done = true
+ end
+ end
+ end
+ end
+ if replace then
+ local p = rawget(properties,prevglyph)
+ if p then
+ local i = p.replaceinjections
+ if i then
+ -- glyph|replace glyphs
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ replace = insert_node_before(replace,replace,fontkern(rightkern))
+ done = true
+ end
+ end
+ end
+ end
+ end
+ if done then
+ setdisc(current,pre,post,replace)
+ end
+ prevglyph = nil
+ prevdisc = current
+ else
+ -- base = nil
+ prevglyph = nil
+ prevdisc = nil
+ end
+ prev = current
+ current = next
+ end
+ -- cursive
+ if hascursives and maxc > 0 then
+ local nx, ny = getoffsets(last)
+ for i=maxc,minc,-1 do
+ local ti = glyphs[i]
+ ny = ny + properties[ti].cursivedy
+ setoffsets(ti,false,ny) -- why not add ?
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ end
+ --
+ if nofmarks > 0 then
+ for i=1,nofmarks do
+ local m = marks[i]
+ local p = rawget(properties,m)
+ local i = p.injections
+ local b = i.markbasenode
+ processmark(b,m,i)
+ end
+ elseif hasmarks then
+ -- sometyhing bad happened
+ end
+ --
+ if keepregisteredcounts then
+ keepregisteredcounts = false
+ else
+ nofregisteredkerns = 0
+ nofregisteredpositions = 0
+ nofregisteredmarks = 0
+ nofregisteredcursives = 0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
+end
+
+-- space triggers
+
+local triggers = false
+
+function nodes.injections.setspacekerns(font,sequence)
+ if triggers then
+ triggers[font] = sequence
+ else
+ triggers = { [font] = sequence }
+ end
+end
+
+local getthreshold
+
+if context then
+
+ local threshold = 1 -- todo: add a few methods for context
+ local parameters = fonts.hashes.parameters
+
+ directives.register("otf.threshold", function(v) threshold = tonumber(v) or 1 end)
+
+ getthreshold = function(font)
+ local p = parameters[font]
+ local f = p.factor
+ local s = p.spacing
+ local t = threshold * (s and s.width or p.space or 0) - 2
+ return t > 0 and t or 0, f
+ end
+
+else
+
+ injections.threshold = 0
+
+ getthreshold = function(font)
+ local p = fontdata[font].parameters
+ local f = p.factor
+ local s = p.spacing
+ local t = injections.threshold * (s and s.width or p.space or 0) - 2
+ return t > 0 and t or 0, f
+ end
+
+end
+
+injections.getthreshold = getthreshold
+
+function injections.isspace(n,threshold,id)
+ if (id or getid(n)) == glue_code then
+ local w = getwidth(n)
+ if threshold and w > threshold then -- was >=
+ return 32
+ end
+ end
+end
+
+-- We have a plugin so that Kai can use the next in plain. Such a plugin is rather application
+-- specific.
+--
+-- local getboth = nodes.direct.getboth
+-- local getid = nodes.direct.getid
+-- local getprev = nodes.direct.getprev
+-- local getnext = nodes.direct.getnext
+--
+-- local whatsit_code = nodes.nodecodes.whatsit
+-- local glyph_code = nodes.nodecodes.glyph
+--
+-- local function getspaceboth(n) -- fragile: what it prev/next has no width field
+-- local prev, next = getboth(n)
+-- while prev and (getid(prev) == whatsit_code or (getwidth(prev) == 0 and getid(prev) ~= glyph_code)) do
+-- prev = getprev(prev)
+-- end
+-- while next and (getid(next) == whatsit_code or (getwidth(next) == 0 and getid(next) ~= glyph_code)) do
+-- next = getnext(next)
+-- end
+-- end
+--
+-- injections.installgetspaceboth(getspaceboth)
+
+local getspaceboth = getboth
+
+function injections.installgetspaceboth(gb)
+ getspaceboth = gb or getboth
+end
+
+local function injectspaces(head)
+
+ if not triggers then
+ return head
+ end
+ local lastfont = nil
+ local spacekerns = nil
+ local leftkerns = nil
+ local rightkerns = nil
+ local factor = 0
+ local threshold = 0
+ local leftkern = false
+ local rightkern = false
+
+ local function updatefont(font,trig)
+ leftkerns = trig.left
+ rightkerns = trig.right
+ lastfont = font
+ threshold,
+ factor = getthreshold(font)
+ end
+
+ for n in nextglue, head do
+ local prev, next = getspaceboth(n)
+ local prevchar = prev and ischar(prev)
+ local nextchar = next and ischar(next)
+ if nextchar then
+ local font = getfont(next)
+ local trig = triggers[font]
+ if trig then
+ if lastfont ~= font then
+ updatefont(font,trig)
+ end
+ if rightkerns then
+ rightkern = rightkerns[nextchar]
+ end
+ end
+ end
+ if prevchar then
+ local font = getfont(prev)
+ local trig = triggers[font]
+ if trig then
+ if lastfont ~= font then
+ updatefont(font,trig)
+ end
+ if leftkerns then
+ leftkern = leftkerns[prevchar]
+ end
+ end
+ end
+ if leftkern then
+ local old = getwidth(n)
+ if old > threshold then
+ if rightkern then
+ if useitalickerns then
+ local lnew = leftkern * factor
+ local rnew = rightkern * factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar)
+ end
+ head = insert_node_before(head,n,italickern(lnew))
+ insert_node_after(head,n,italickern(rnew))
+ else
+ local new = old + (leftkern + rightkern) * factor
+ if trace_spaces then
+ report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar)
+ end
+ setwidth(n,new)
+ end
+ rightkern = false
+ else
+ if useitalickerns then
+ local new = leftkern * factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p]",prevchar,old,new)
+ end
+ insert_node_after(head,n,italickern(new)) -- tricky with traverse but ok
+ else
+ local new = old + leftkern * factor
+ if trace_spaces then
+ report_spaces("%C [%p -> %p]",prevchar,old,new)
+ end
+ setwidth(n,new)
+ end
+ end
+ end
+ leftkern = false
+ elseif rightkern then
+ local old = getwidth(n)
+ if old > threshold then
+ if useitalickerns then
+ local new = rightkern * factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p]",nextchar,old,new)
+ end
+ insert_node_after(head,n,italickern(new))
+ else
+ local new = old + rightkern * factor
+ if trace_spaces then
+ report_spaces("[%p -> %p] %C",nextchar,old,new)
+ end
+ setwidth(n,new)
+ end
+ end
+ rightkern = false
+ end
+ end
+
+ triggers = false
+
+ return head
+end
+
+--
+
+function injections.handler(head,where)
+ if triggers then
+ head = injectspaces(head)
+ end
+ -- todo: marks only run too
+ if nofregisteredmarks > 0 or nofregisteredcursives > 0 then
+ if trace_injections then
+ report_injections("injection variant %a","everything")
+ end
+ return inject_everything(head,where)
+ elseif nofregisteredpositions > 0 then
+ if trace_injections then
+ report_injections("injection variant %a","positions")
+ end
+ return inject_positions_only(head,where)
+ elseif nofregisteredkerns > 0 then
+ if trace_injections then
+ report_injections("injection variant %a","kerns")
+ end
+ return inject_kerns_only(head,where)
+ else
+ return head
+ end
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otl.lua b/macros/luatex/generic/luaotfload/fontloader-font-otl.lua
new file mode 100644
index 0000000000..f8cd8217cd
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-otl.lua
@@ -0,0 +1,857 @@
+if not modules then modules = { } end modules ['font-otl'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+-- After some experimenting with an alternative loader (one that is needed for
+-- getting outlines in mp) I decided not to be compatible with the old (built-in)
+-- one. The approach used in font-otn is as follows: we load the font in a compact
+-- format but still very compatible with the ff data structures. From there we
+-- create hashes to access the data efficiently. The implementation of feature
+-- processing is mostly based on looking at the data as organized in the glyphs and
+-- lookups as well as the specification. Keeping the lookup data in the glyphs is
+-- very instructive and handy for tracing. On the other hand hashing is what brings
+-- speed. So, the in the new approach (the old one will stay around too) we no
+-- longer keep data in the glyphs which saves us a (what in retrospect looks a bit
+-- like) a reconstruction step. It also means that the data format of the cached
+-- files changes. What method is used depends on that format. There is no fundamental
+-- change in processing, and not even in data organation. Most has to do with
+-- loading and storage.
+
+-- todo: less tounicodes
+
+local lower = string.lower
+local type, next, tonumber, tostring, unpack = type, next, tonumber, tostring, unpack
+local abs = math.abs
+local derivetable = table.derive
+local formatters = string.formatters
+
+local setmetatableindex = table.setmetatableindex
+local allocate = utilities.storage.allocate
+local registertracker = trackers.register
+local registerdirective = directives.register
+local starttiming = statistics.starttiming
+local stoptiming = statistics.stoptiming
+local elapsedtime = statistics.elapsedtime
+local findbinfile = resolvers.findbinfile
+
+----- trace_private = false registertracker("otf.private", function(v) trace_private = v end)
+----- trace_subfonts = false registertracker("otf.subfonts", function(v) trace_subfonts = v end)
+local trace_loading = false registertracker("otf.loading", function(v) trace_loading = v end)
+local trace_features = false registertracker("otf.features", function(v) trace_features = v end)
+----- trace_dynamics = false registertracker("otf.dynamics", function(v) trace_dynamics = v end)
+----- trace_sequences = false registertracker("otf.sequences", function(v) trace_sequences = v end)
+----- trace_markwidth = false registertracker("otf.markwidth", function(v) trace_markwidth = v end)
+local trace_defining = false registertracker("fonts.defining", function(v) trace_defining = v end)
+
+local report_otf = logs.reporter("fonts","otf loading")
+
+local fonts = fonts
+local otf = fonts.handlers.otf
+
+otf.version = 3.109 -- 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.pngcache = containers.define("fonts", "png", otf.version, true)
+otf.pdfcache = containers.define("fonts", "pdf", otf.version, true)
+
+otf.svgenabled = false
+otf.pngenabled = false
+
+local otfreaders = otf.readers
+
+local hashes = fonts.hashes
+local definers = fonts.definers
+local readers = fonts.readers
+local constructors = fonts.constructors
+
+local otffeatures = constructors.features.otf
+local registerotffeature = otffeatures.register
+
+local otfenhancers = constructors.enhancers.otf
+local registerotfenhancer = otfenhancers.register
+
+local forceload = false
+local cleanup = 0 -- mk: 0=885M 1=765M 2=735M (regular run 730M)
+local syncspace = true
+local forcenotdef = false
+
+local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF
+
+local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes
+
+local wildcard = "*"
+local default = "dflt"
+
+local formats = fonts.formats
+
+formats.otf = "opentype"
+formats.ttf = "truetype"
+formats.ttc = "truetype"
+
+registerdirective("fonts.otf.loader.cleanup", function(v) cleanup = tonumber(v) or (v and 1) or 0 end)
+registerdirective("fonts.otf.loader.force", function(v) forceload = v end)
+registerdirective("fonts.otf.loader.syncspace", function(v) syncspace = v end)
+registerdirective("fonts.otf.loader.forcenotdef", function(v) forcenotdef = v end)
+
+-- otfenhancers.patch("before","migrate metadata","cambria",function() end)
+
+registerotfenhancer("check extra features", function() end) -- placeholder
+
+-- Kai has memory problems on osx so here is an experiment (I only tested on windows as
+-- my test mac is old and gets no updates and is therefore rather useless.):
+
+local checkmemory = utilities.lua and utilities.lua.checkmemory
+local threshold = 100 -- MB
+local tracememory = false
+
+registertracker("fonts.otf.loader.memory",function(v) tracememory = v end)
+
+if not checkmemory then -- we need a generic plug (this code might move):
+
+ local collectgarbage = collectgarbage
+
+ checkmemory = function(previous,threshold) -- threshold in MB
+ local current = collectgarbage("count")
+ if previous then
+ local checked = (threshold or 64)*1024
+ if current - previous > checked then
+ collectgarbage("collect")
+ current = collectgarbage("count")
+ end
+ end
+ return current
+ end
+
+end
+
+function otf.load(filename,sub,instance)
+ local base = file.basename(file.removesuffix(filename))
+ local name = file.removesuffix(base) -- already no suffix
+ local attr = lfs.attributes(filename)
+ local size = attr and attr.size or 0
+ local time = attr and attr.modification or 0
+ -- sub can be number of string
+ if sub == "" then
+ sub = false
+ end
+ local hash = name
+ if sub then
+ hash = hash .. "-" .. sub
+ end
+ if instance then
+ hash = hash .. "-" .. instance
+ end
+ hash = containers.cleanname(hash)
+ local data = containers.read(otf.cache,hash)
+ local reload = not data or data.size ~= size or data.time ~= time or data.tableversion ~= otfreaders.tableversion
+ if forceload then
+ report_otf("forced reload of %a due to hard coded flag",filename)
+ reload = true
+ end
+ if reload then
+ report_otf("loading %a, hash %a",filename,hash)
+ --
+ starttiming(otfreaders,true)
+ data = otfreaders.loadfont(filename,sub or 1,instance) -- we can pass the number instead (if it comes from a name search)
+ if data then
+ -- todo: make this a plugin
+ local used = checkmemory()
+ local resources = data.resources
+ local svgshapes = resources.svgshapes
+ local pngshapes = resources.pngshapes
+ if cleanup == 0 then
+ checkmemory(used,threshold,tracememory)
+ end
+ if svgshapes then
+ resources.svgshapes = nil
+ if otf.svgenabled then
+ local timestamp = os.date()
+ -- work in progress ... a bit boring to do
+ containers.write(otf.svgcache,hash, {
+ svgshapes = svgshapes,
+ timestamp = timestamp,
+ })
+ data.properties.svg = {
+ hash = hash,
+ timestamp = timestamp,
+ }
+ end
+ if cleanup > 1 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ end
+ if pngshapes then
+ resources.pngshapes = nil
+ if otf.pngenabled then
+ local timestamp = os.date()
+ -- work in progress ... a bit boring to do
+ containers.write(otf.pngcache,hash, {
+ pngshapes = pngshapes,
+ timestamp = timestamp,
+ })
+ data.properties.png = {
+ hash = hash,
+ timestamp = timestamp,
+ }
+ end
+ if cleanup > 1 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ end
+ --
+ otfreaders.compact(data)
+ if cleanup == 0 then
+ checkmemory(used,threshold,tracememory)
+ end
+ otfreaders.rehash(data,"unicodes")
+ otfreaders.addunicodetable(data)
+ otfreaders.extend(data)
+ if cleanup == 0 then
+ checkmemory(used,threshold,tracememory)
+ end
+ otfreaders.pack(data)
+ report_otf("loading done")
+ report_otf("saving %a in cache",filename)
+ data = containers.write(otf.cache, hash, data)
+ if cleanup > 1 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ stoptiming(otfreaders)
+ if elapsedtime then
+ report_otf("loading, optimizing, packing and caching time %s", elapsedtime(otfreaders))
+ end
+ if cleanup > 3 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ data = containers.read(otf.cache,hash) -- this frees the old table and load the sparse one
+ if cleanup > 2 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ else
+ stoptiming(otfreaders)
+ data = nil
+ report_otf("loading failed due to read error")
+ end
+ end
+ if data then
+ if trace_defining then
+ report_otf("loading from cache using hash %a",hash)
+ end
+ --
+ otfreaders.unpack(data)
+ otfreaders.expand(data) -- inline tables
+ otfreaders.addunicodetable(data) -- only when not done yet
+ --
+ otfenhancers.apply(data,filename,data) -- in context one can also use treatments
+ --
+ -- constructors.addcoreunicodes(data.resources.unicodes) -- still needed ?
+ --
+ if applyruntimefixes then
+ applyruntimefixes(filename,data) -- e.g. see treatments.lfg
+ end
+ --
+ data.metadata.math = data.resources.mathconstants
+ --
+ -- delayed tables (experiment)
+ --
+ local classes = data.resources.classes
+ if not classes then
+ local descriptions = data.descriptions
+ classes = setmetatableindex(function(t,k)
+ local d = descriptions[k]
+ local v = (d and d.class or "base") or false
+ t[k] = v
+ return v
+ end)
+ data.resources.classes = classes
+ end
+ --
+ end
+
+ return data
+end
+
+-- modes: node, base, none
+
+function otf.setfeatures(tfmdata,features)
+ local okay = constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf)
+ if okay then
+ return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf)
+ else
+ return { } -- will become false
+ end
+end
+
+-- the first version made a top/mid/not extensible table, now we just
+-- pass on the variants data and deal with it in the tfm scaler (there
+-- is no longer an extensible table anyway)
+--
+-- we cannot share descriptions as virtual fonts might extend them (ok,
+-- we could use a cache with a hash
+--
+-- we already assign an empty table to characters as we can add for
+-- instance protruding info and loop over characters; one is not supposed
+-- to change descriptions and if one does so one should make a copy!
+
+local function copytotfm(data,cache_id)
+ if data then
+ local metadata = data.metadata
+ local properties = derivetable(data.properties)
+ local descriptions = derivetable(data.descriptions)
+ local goodies = derivetable(data.goodies)
+ local characters = { }
+ local parameters = { }
+ local mathparameters = { }
+ --
+ local resources = data.resources
+ local unicodes = resources.unicodes
+ local spaceunits = 500
+ local spacer = "space"
+ local designsize = metadata.designsize or 100
+ local minsize = metadata.minsize or designsize
+ local maxsize = metadata.maxsize or designsize
+ local mathspecs = metadata.math
+ --
+ if designsize == 0 then
+ designsize = 100
+ minsize = 100
+ maxsize = 100
+ end
+ if mathspecs then
+ for name, value in next, mathspecs do
+ mathparameters[name] = value
+ end
+ end
+ for unicode in next, data.descriptions do -- use parent table
+ characters[unicode] = { }
+ end
+ if mathspecs then
+ for unicode, character in next, characters do
+ local d = descriptions[unicode] -- we could use parent table here
+ local m = d.math
+ if m then
+ -- watch out: luatex uses horiz_variants for the parts
+ --
+ local italic = m.italic
+ local vitalic = m.vitalic
+ --
+ local variants = m.hvariants
+ local parts = m.hparts
+ if variants then
+ local c = character
+ for i=1,#variants do
+ -- local un = variants[i].glyph
+ local un = variants[i]
+ c.next = un
+ c = characters[un]
+ end -- c is now last in chain
+ c.horiz_variants = parts
+ elseif parts then
+ character.horiz_variants = parts
+ italic = m.hitalic
+ end
+ --
+ local variants = m.vvariants
+ local parts = m.vparts
+ if variants then
+ local c = character
+ for i=1,#variants do
+ -- local un = variants[i].glyph
+ local un = variants[i]
+ c.next = un
+ c = characters[un]
+ end -- c is now last in chain
+ c.vert_variants = parts
+ elseif parts then
+ character.vert_variants = parts
+ end
+ --
+ if italic and italic ~= 0 then
+ character.italic = italic
+ end
+ --
+ if vitalic and vitalic ~= 0 then
+ character.vert_italic = vitalic
+ end
+ --
+ local accent = m.accent -- taccent?
+ if accent then
+ character.accent = accent
+ end
+ --
+ local kerns = m.kerns
+ if kerns then
+ character.mathkerns = kerns
+ end
+ end
+ end
+ end
+ -- we need a runtime lookup because of running from cdrom or zip, brrr (shouldn't
+ -- we use the basename then?)
+ local filename = constructors.checkedfilename(resources)
+ local fontname = metadata.fontname
+ local fullname = metadata.fullname or fontname
+ local psname = fontname or fullname
+ local subfont = metadata.subfontindex
+ local units = metadata.units or 1000
+ --
+ if units == 0 then -- catch bugs in fonts
+ units = 1000 -- maybe 2000 when ttf
+ metadata.units = 1000
+ report_otf("changing %a units to %a",0,units)
+ end
+ --
+ local monospaced = metadata.monospaced
+ local charwidth = metadata.averagewidth -- or unset
+ local charxheight = metadata.xheight -- or unset
+ local italicangle = metadata.italicangle
+ local hasitalics = metadata.hasitalics
+ properties.monospaced = monospaced
+ properties.hasitalics = hasitalics
+ parameters.italicangle = italicangle
+ parameters.charwidth = charwidth
+ parameters.charxheight = charxheight
+ --
+ local space = 0x0020
+ local emdash = 0x2014
+ if monospaced then
+ if descriptions[space] then
+ spaceunits, spacer = descriptions[space].width, "space"
+ end
+ if not spaceunits and descriptions[emdash] then
+ spaceunits, spacer = descriptions[emdash].width, "emdash"
+ end
+ if not spaceunits and charwidth then
+ spaceunits, spacer = charwidth, "charwidth"
+ end
+ else
+ if descriptions[space] then
+ spaceunits, spacer = descriptions[space].width, "space"
+ end
+ if not spaceunits and descriptions[emdash] then
+ spaceunits, spacer = descriptions[emdash].width/2, "emdash/2"
+ end
+ if not spaceunits and charwidth then
+ spaceunits, spacer = charwidth, "charwidth"
+ end
+ end
+ spaceunits = tonumber(spaceunits) or units/2
+ --
+ parameters.slant = 0
+ parameters.space = spaceunits -- 3.333 (cmr10)
+ parameters.space_stretch = 1*units/2 -- 500 -- 1.666 (cmr10)
+ parameters.space_shrink = 1*units/3 -- 333 -- 1.111 (cmr10)
+ parameters.x_height = 2*units/5 -- 400
+ parameters.quad = units -- 1000
+ if spaceunits < 2*units/5 then
+ -- todo: warning
+ end
+ if italicangle and italicangle ~= 0 then
+ parameters.italicangle = italicangle
+ parameters.italicfactor = math.cos(math.rad(90+italicangle))
+ parameters.slant = - math.tan(italicangle*math.pi/180)
+ end
+ if monospaced then
+ parameters.space_stretch = 0
+ parameters.space_shrink = 0
+ elseif syncspace then --
+ parameters.space_stretch = spaceunits/2
+ parameters.space_shrink = spaceunits/3
+ end
+ parameters.extra_space = parameters.space_shrink -- 1.111 (cmr10)
+ if charxheight then
+ parameters.x_height = charxheight
+ else
+ local x = 0x0078
+ if x then
+ local x = descriptions[x]
+ if x then
+ parameters.x_height = x.height
+ end
+ end
+ end
+ --
+ parameters.designsize = (designsize/10)*65536
+ parameters.minsize = (minsize /10)*65536
+ parameters.maxsize = (maxsize /10)*65536
+ parameters.ascender = abs(metadata.ascender or 0)
+ parameters.descender = abs(metadata.descender or 0)
+ parameters.units = units
+ parameters.vheight = metadata.defaultvheight
+ --
+ properties.space = spacer
+ properties.encodingbytes = 2
+ properties.format = data.format or formats.otf
+ properties.filename = filename
+ properties.fontname = fontname
+ properties.fullname = fullname
+ properties.psname = psname
+ properties.name = filename or fullname
+ properties.subfont = subfont
+ --
+ -- properties.name = specification.name
+ -- properties.sub = specification.sub
+ --
+ properties.private = properties.private or data.private or privateoffset
+ --
+ return {
+ characters = characters,
+ descriptions = descriptions,
+ parameters = parameters,
+ mathparameters = mathparameters,
+ resources = resources,
+ properties = properties,
+ goodies = goodies,
+ }
+ end
+end
+
+-- These woff files are a kind of joke in a tex environment because one can simply convert
+-- them to ttf/otf and use them as such (after all, we cache them too). The successor format
+-- woff2 is more complex so there we can as well call an external converter which in the end
+-- makes this code kind of obsolete before it's even used. Although ... it might become a
+-- more general conversion plug in.
+
+local converters = {
+ woff = {
+ cachename = "webfonts",
+ action = otf.readers.woff2otf,
+ }
+}
+
+local function checkconversion(specification)
+ local filename = specification.filename
+ local converter = converters[lower(file.suffix(filename))]
+ if converter then
+ local base = file.basename(filename)
+ local name = file.removesuffix(base)
+ local attr = lfs.attributes(filename)
+ local size = attr and attr.size or 0
+ local time = attr and attr.modification or 0
+ if size > 0 then
+ local cleanname = containers.cleanname(name)
+ local cachename = caches.setfirstwritablefile(cleanname,converter.cachename)
+ if not io.exists(cachename) or (time ~= lfs.attributes(cachename).modification) then
+ report_otf("caching font %a in %a",filename,cachename)
+ converter.action(filename,cachename) -- todo infoonly
+ lfs.touch(cachename,time,time)
+ end
+ specification.filename = cachename
+ end
+ end
+end
+
+local function otftotfm(specification)
+ local cache_id = specification.hash
+ local tfmdata = containers.read(constructors.cache,cache_id)
+ if not tfmdata then
+
+ checkconversion(specification) -- for the moment here
+
+ local name = specification.name
+ local sub = specification.sub
+ local subindex = specification.subindex
+ local filename = specification.filename
+ local features = specification.features.normal
+ local instance = specification.instance or (features and features.axis)
+ local rawdata = otf.load(filename,sub,instance)
+ if rawdata and next(rawdata) then
+ local descriptions = rawdata.descriptions
+ rawdata.lookuphash = { } -- to be done
+ tfmdata = copytotfm(rawdata,cache_id)
+ if tfmdata and next(tfmdata) then
+ -- at this moment no characters are assigned yet, only empty slots
+ local features = constructors.checkedfeatures("otf",features)
+ local shared = tfmdata.shared
+ if not shared then
+ shared = { }
+ tfmdata.shared = shared
+ end
+ shared.rawdata = rawdata
+ -- shared.features = features -- default
+ shared.dynamics = { }
+ -- shared.processes = { }
+ tfmdata.changed = { }
+ shared.features = features
+ shared.processes = otf.setfeatures(tfmdata,features)
+ end
+ end
+ containers.write(constructors.cache,cache_id,tfmdata)
+ end
+ return tfmdata
+end
+
+local function read_from_otf(specification)
+ local tfmdata = otftotfm(specification)
+ if tfmdata then
+ -- this late ? .. needs checking
+ tfmdata.properties.name = specification.name
+ tfmdata.properties.sub = specification.sub
+ --
+ tfmdata = constructors.scale(tfmdata,specification)
+ local allfeatures = tfmdata.shared.features or specification.features.normal
+ constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf)
+ constructors.setname(tfmdata,specification) -- only otf?
+ fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification)
+ end
+ return tfmdata
+end
+
+local function checkmathsize(tfmdata,mathsize)
+ local mathdata = tfmdata.shared.rawdata.metadata.math
+ local mathsize = tonumber(mathsize)
+ if mathdata then -- we cannot use mathparameters as luatex will complain
+ local parameters = tfmdata.parameters
+ parameters.scriptpercentage = mathdata.ScriptPercentScaleDown
+ parameters.scriptscriptpercentage = mathdata.ScriptScriptPercentScaleDown
+ parameters.mathsize = mathsize -- only when a number !
+ end
+end
+
+registerotffeature {
+ name = "mathsize",
+ description = "apply mathsize specified in the font",
+ initializers = {
+ base = checkmathsize,
+ node = checkmathsize,
+ }
+}
+
+-- readers
+
+function otf.collectlookups(rawdata,kind,script,language)
+ if not kind then
+ return
+ end
+ if not script then
+ script = default
+ end
+ if not language then
+ language = default
+ end
+ local lookupcache = rawdata.lookupcache
+ if not lookupcache then
+ lookupcache = { }
+ rawdata.lookupcache = lookupcache
+ end
+ local kindlookup = lookupcache[kind]
+ if not kindlookup then
+ kindlookup = { }
+ lookupcache[kind] = kindlookup
+ end
+ local scriptlookup = kindlookup[script]
+ if not scriptlookup then
+ scriptlookup = { }
+ kindlookup[script] = scriptlookup
+ end
+ local languagelookup = scriptlookup[language]
+ if not languagelookup then
+ local sequences = rawdata.resources.sequences
+ local featuremap = { }
+ local featurelist = { }
+ if sequences then
+ for s=1,#sequences do
+ local sequence = sequences[s]
+ local features = sequence.features
+ if features then
+ features = features[kind]
+ if features then
+ -- features = features[script] or features[default] or features[wildcard]
+ features = features[script] or features[wildcard]
+ if features then
+ -- features = features[language] or features[default] or features[wildcard]
+ features = features[language] or features[wildcard]
+ if features then
+ if not featuremap[sequence] then
+ featuremap[sequence] = true
+ featurelist[#featurelist+1] = sequence
+ end
+ end
+ end
+ end
+ end
+ end
+ if #featurelist == 0 then
+ featuremap, featurelist = false, false
+ end
+ else
+ featuremap, featurelist = false, false
+ end
+ languagelookup = { featuremap, featurelist }
+ scriptlookup[language] = languagelookup
+ end
+ return unpack(languagelookup)
+end
+
+-- moved from font-oth.lua, todo: also afm
+
+local function getgsub(tfmdata,k,kind,value)
+ local shared = tfmdata.shared
+ local rawdata = shared and shared.rawdata
+ if rawdata then
+ local sequences = rawdata.resources.sequences
+ if sequences then
+ local properties = tfmdata.properties
+ local validlookups, lookuplist = otf.collectlookups(rawdata,kind,properties.script,properties.language)
+ if validlookups then
+ -- local choice = tonumber(value) or 1 -- no random here (yet)
+ for i=1,#lookuplist do
+ local lookup = lookuplist[i]
+ local steps = lookup.steps
+ local nofsteps = lookup.nofsteps
+ for i=1,nofsteps do
+ local coverage = steps[i].coverage
+ if coverage then
+ local found = coverage[k]
+ if found then
+ return found, lookup.type
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+otf.getgsub = getgsub -- returns value, gsub_kind
+
+function otf.getsubstitution(tfmdata,k,kind,value)
+ local found, kind = getgsub(tfmdata,k,kind,value)
+ if not found then
+ --
+ elseif kind == "gsub_single" then
+ return found
+ elseif kind == "gsub_alternate" then
+ local choice = tonumber(value) or 1 -- no random here (yet)
+ return found[choice] or found[1] or k
+ end
+ return k
+end
+
+otf.getalternate = otf.getsubstitution
+
+function otf.getmultiple(tfmdata,k,kind)
+ local found, kind = getgsub(tfmdata,k,kind)
+ if found and kind == "gsub_multiple" then
+ return found
+ end
+ return { k }
+end
+
+function otf.getkern(tfmdata,left,right,kind)
+ local kerns = getgsub(tfmdata,left,kind or "kern",true) -- for now we use getsub
+ if kerns then
+ local found = kerns[right]
+ local kind = type(found)
+ if kind == "table" then
+ found = found[1][3] -- can be more clever
+ elseif kind ~= "number" then
+ found = false
+ end
+ if found then
+ return found * tfmdata.parameters.factor
+ end
+ end
+ return 0
+end
+
+local function check_otf(forced,specification,suffix)
+ local name = specification.name
+ if forced then
+ name = specification.forcedname -- messy
+ end
+ local fullname = findbinfile(name,suffix) or ""
+ if fullname == "" then
+ fullname = fonts.names.getfilename(name,suffix) or ""
+ end
+ if fullname ~= "" and not fonts.names.ignoredfile(fullname) then
+ specification.filename = fullname
+ return read_from_otf(specification)
+ end
+end
+
+local function opentypereader(specification,suffix)
+ local forced = specification.forced or ""
+ if formats[forced] then
+ return check_otf(true,specification,forced)
+ else
+ return check_otf(false,specification,suffix)
+ end
+end
+
+readers.opentype = opentypereader -- kind of useless and obsolete
+
+function readers.otf(specification) return opentypereader(specification,"otf") end
+function readers.ttf(specification) return opentypereader(specification,"ttf") end
+function readers.ttc(specification) return opentypereader(specification,"ttf") end
+
+function readers.woff(specification)
+ checkconversion(specification)
+ opentypereader(specification,"")
+end
+
+-- this will be overloaded
+
+function otf.scriptandlanguage(tfmdata,attr)
+ local properties = tfmdata.properties
+ return properties.script or "dflt", properties.language or "dflt"
+end
+
+-- a little bit of abstraction
+
+local function justset(coverage,unicode,replacement)
+ coverage[unicode] = replacement
+end
+
+otf.coverup = {
+ stepkey = "steps",
+ actions = {
+ chainsubstitution = justset,
+ chainposition = justset,
+ substitution = justset,
+ alternate = justset,
+ multiple = justset,
+ kern = justset,
+ pair = justset,
+ single = justset,
+ ligature = function(coverage,unicode,ligature)
+ local first = ligature[1]
+ local tree = coverage[first]
+ if not tree then
+ tree = { }
+ coverage[first] = tree
+ end
+ for i=2,#ligature do
+ local l = ligature[i]
+ local t = tree[l]
+ if not t then
+ t = { }
+ tree[l] = t
+ end
+ tree = t
+ end
+ tree.ligature = unicode
+ end,
+ },
+ register = function(coverage,featuretype,format)
+ return {
+ format = format,
+ coverage = coverage,
+ }
+ end
+}
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-oto.lua b/macros/luatex/generic/luaotfload/fontloader-font-oto.lua
new file mode 100644
index 0000000000..4d112ac316
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-oto.lua
@@ -0,0 +1,542 @@
+if not modules then modules = { } end modules ['font-oto'] = { -- original tex
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local concat, unpack = table.concat, table.unpack
+local insert, remove = table.insert, table.remove
+local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip
+local type, next, tonumber, tostring, rawget = type, next, tonumber, tostring, rawget
+
+local trace_baseinit = false trackers.register("otf.baseinit", function(v) trace_baseinit = v end)
+local trace_singles = false trackers.register("otf.singles", function(v) trace_singles = v end)
+local trace_multiples = false trackers.register("otf.multiples", function(v) trace_multiples = v end)
+local trace_alternatives = false trackers.register("otf.alternatives", function(v) trace_alternatives = v end)
+local trace_ligatures = false trackers.register("otf.ligatures", function(v) trace_ligatures = v end)
+local trace_kerns = false trackers.register("otf.kerns", function(v) trace_kerns = v end)
+local trace_preparing = false trackers.register("otf.preparing", function(v) trace_preparing = v end)
+
+local report_prepare = logs.reporter("fonts","otf prepare")
+
+local fonts = fonts
+local otf = fonts.handlers.otf
+
+local otffeatures = otf.features
+local registerotffeature = otffeatures.register
+
+otf.defaultbasealternate = "none" -- first last
+
+local getprivate = fonts.constructors.getprivate
+
+local wildcard = "*"
+local default = "dflt"
+
+local formatters = string.formatters
+local f_unicode = formatters["%U"]
+local f_uniname = formatters["%U (%s)"]
+local f_unilist = formatters["% t (% t)"]
+
+local function gref(descriptions,n)
+ if type(n) == "number" then
+ local name = descriptions[n].name
+ if name then
+ return f_uniname(n,name)
+ else
+ return f_unicode(n)
+ end
+ elseif n then
+ local num = { }
+ local nam = { }
+ local j = 0
+ for i=1,#n do
+ local ni = n[i]
+ if tonumber(ni) then -- first is likely a key
+ j = j + 1
+ local di = descriptions[ni]
+ num[j] = f_unicode(ni)
+ nam[j] = di and di.name or "-"
+ end
+ end
+ return f_unilist(num,nam)
+ else
+ return "<error in base mode tracing>"
+ end
+end
+
+local function cref(feature,sequence)
+ return formatters["feature %a, type %a, chain lookup %a"](feature,sequence.type,sequence.name)
+end
+
+local function report_substitution(feature,sequence,descriptions,unicode,substitution)
+ if unicode == substitution then
+ report_prepare("%s: base substitution %s maps onto itself",
+ cref(feature,sequence),
+ gref(descriptions,unicode))
+ else
+ report_prepare("%s: base substitution %s => %S",
+ cref(feature,sequence),
+ gref(descriptions,unicode),
+ gref(descriptions,substitution))
+ end
+end
+
+local function report_alternate(feature,sequence,descriptions,unicode,replacement,value,comment)
+ if unicode == replacement then
+ report_prepare("%s: base alternate %s maps onto itself",
+ cref(feature,sequence),
+ gref(descriptions,unicode))
+ else
+ report_prepare("%s: base alternate %s => %s (%S => %S)",
+ cref(feature,sequence),
+ gref(descriptions,unicode),
+ replacement and gref(descriptions,replacement),
+ value,
+ comment)
+ end
+end
+
+local function report_ligature(feature,sequence,descriptions,unicode,ligature)
+ report_prepare("%s: base ligature %s => %S",
+ cref(feature,sequence),
+ gref(descriptions,ligature),
+ gref(descriptions,unicode))
+end
+
+local function report_kern(feature,sequence,descriptions,unicode,otherunicode,value)
+ report_prepare("%s: base kern %s + %s => %S",
+ cref(feature,sequence),
+ gref(descriptions,unicode),
+ gref(descriptions,otherunicode),
+ value)
+end
+
+-- We need to make sure that luatex sees the difference between base fonts that have
+-- different glyphs in the same slots in fonts that have the same fullname (or filename).
+-- LuaTeX will merge fonts eventually (and subset later on). If needed we can use a more
+-- verbose name as long as we don't use <()<>[]{}/%> and the length is < 128.
+
+local basehash, basehashes, applied = { }, 1, { }
+
+local function registerbasehash(tfmdata)
+ local properties = tfmdata.properties
+ local hash = concat(applied," ")
+ local base = basehash[hash]
+ if not base then
+ basehashes = basehashes + 1
+ base = basehashes
+ basehash[hash] = base
+ end
+ properties.basehash = base
+ properties.fullname = (properties.fullname or properties.name) .. "-" .. base
+ -- report_prepare("fullname base hash '%a, featureset %a",tfmdata.properties.fullname,hash)
+ applied = { }
+end
+
+local function registerbasefeature(feature,value)
+ applied[#applied+1] = feature .. "=" .. tostring(value)
+end
+
+-- The original basemode ligature builder used the names of components and did some expression
+-- juggling to get the chain right. The current variant starts with unicodes but still uses
+-- names to make the chain. This is needed because we have to create intermediates when needed
+-- but use predefined snippets when available. To some extend the current builder is more stupid
+-- but I don't worry that much about it as ligatures are rather predicatable.
+--
+-- Personally I think that an ff + i == ffi rule as used in for instance latin modern is pretty
+-- weird as no sane person will key that in and expect a glyph for that ligature plus the following
+-- character. Anyhow, as we need to deal with this, we do, but no guarantes are given.
+--
+-- latin modern dejavu
+--
+-- f+f 102 102 102 102
+-- f+i 102 105 102 105
+-- f+l 102 108 102 108
+-- f+f+i 102 102 105
+-- f+f+l 102 102 108 102 102 108
+-- ff+i 64256 105 64256 105
+-- ff+l 64256 108
+--
+-- As you can see here, latin modern is less complete than dejavu but
+-- in practice one will not notice it.
+--
+-- The while loop is needed because we need to resolve for instance pseudo names like
+-- hyphen_hyphen to endash so in practice we end up with a bit too many definitions but the
+-- overhead is neglectable. We can have changed[first] or changed[second] but it quickly becomes
+-- messy if we need to take that into account.
+
+local function makefake(tfmdata,name,present)
+ local private = getprivate(tfmdata)
+ local character = { intermediate = true, ligatures = { } }
+ resources.unicodes[name] = private
+ tfmdata.characters[private] = character
+ tfmdata.descriptions[private] = { name = name }
+ present[name] = private
+ return character
+end
+
+local function make_1(present,tree,name)
+ for k, v in next, tree do
+ if k == "ligature" then
+ present[name] = v
+ else
+ make_1(present,v,name .. "_" .. k)
+ end
+ end
+end
+
+local function make_2(present,tfmdata,characters,tree,name,preceding,unicode,done)
+ for k, v in next, tree do
+ if k == "ligature" then
+ local character = characters[preceding]
+ if not character then
+ if trace_baseinit then
+ report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding)
+ end
+ character = makefake(tfmdata,name,present)
+ end
+ local ligatures = character.ligatures
+ if ligatures then
+ ligatures[unicode] = { char = v }
+ else
+ character.ligatures = { [unicode] = { char = v } }
+ end
+ if done then
+ local d = done[name]
+ if not d then
+ done[name] = { "dummy", v }
+ else
+ d[#d+1] = v
+ end
+ end
+ else
+ local code = present[name] or unicode
+ local name = name .. "_" .. k
+ make_2(present,tfmdata,characters,v,name,code,k,done)
+ end
+ end
+end
+
+local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist)
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local resources = tfmdata.resources
+ local changed = tfmdata.changed
+
+ local ligatures = { }
+ local alternate = tonumber(value) or true and 1
+ local defaultalt = otf.defaultbasealternate
+
+ local trace_singles = trace_baseinit and trace_singles
+ local trace_alternatives = trace_baseinit and trace_alternatives
+ local trace_ligatures = trace_baseinit and trace_ligatures
+
+ -- A chain of changes is handled in font-con which is clesner because
+ -- we can have shared changes and such.
+
+ if not changed then
+ changed = { }
+ tfmdata.changed = changed
+ end
+
+ for i=1,#lookuplist do
+ local sequence = lookuplist[i]
+ local steps = sequence.steps
+ local kind = sequence.type
+ if kind == "gsub_single" then
+ for i=1,#steps do
+ for unicode, data in next, steps[i].coverage do
+ if unicode ~= data then
+ changed[unicode] = data
+ end
+ if trace_singles then
+ report_substitution(feature,sequence,descriptions,unicode,data)
+ end
+ end
+ end
+ elseif kind == "gsub_alternate" then
+ for i=1,#steps do
+ for unicode, data in next, steps[i].coverage do
+ local replacement = data[alternate]
+ if replacement then
+ if unicode ~= replacement then
+ changed[unicode] = replacement
+ end
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal")
+ end
+ elseif defaultalt == "first" then
+ replacement = data[1]
+ if unicode ~= replacement then
+ changed[unicode] = replacement
+ end
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
+ end
+ elseif defaultalt == "last" then
+ replacement = data[#data]
+ if unicode ~= replacement then
+ changed[unicode] = replacement
+ end
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
+ end
+ else
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,"unknown")
+ end
+ end
+ end
+ end
+ elseif kind == "gsub_ligature" then
+ for i=1,#steps do
+ for unicode, data in next, steps[i].coverage do
+ ligatures[#ligatures+1] = { unicode, data, "" } -- lookupname }
+ if trace_ligatures then
+ report_ligature(feature,sequence,descriptions,unicode,data)
+ end
+ end
+ end
+ end
+ end
+
+ local nofligatures = #ligatures
+
+ if nofligatures > 0 then
+ local characters = tfmdata.characters
+ local present = { }
+ local done = trace_baseinit and trace_ligatures and { }
+
+ for i=1,nofligatures do
+ local ligature = ligatures[i]
+ local unicode = ligature[1]
+ local tree = ligature[2]
+ make_1(present,tree,"ctx_"..unicode)
+ end
+
+ for i=1,nofligatures do
+ local ligature = ligatures[i]
+ local unicode = ligature[1]
+ local tree = ligature[2]
+ local lookupname = ligature[3]
+ make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence)
+ end
+
+ end
+
+end
+
+local function preparepositionings(tfmdata,feature,value,validlookups,lookuplist)
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local resources = tfmdata.resources
+ local properties = tfmdata.properties
+ local traceindeed = trace_baseinit and trace_kerns
+ -- check out this sharedkerns trickery
+ for i=1,#lookuplist do
+ local sequence = lookuplist[i]
+ local steps = sequence.steps
+ local kind = sequence.type
+ local format = sequence.format
+ if kind == "gpos_pair" then
+ for i=1,#steps do
+ local step = steps[i]
+ local format = step.format
+ if format == "kern" or format == "move" then
+ for unicode, data in next, steps[i].coverage do
+ local character = characters[unicode]
+ local kerns = character.kerns
+ if not kerns then
+ kerns = { }
+ character.kerns = kerns
+ end
+ if traceindeed then
+ for otherunicode, kern in next, data do
+ if not kerns[otherunicode] and kern ~= 0 then
+ kerns[otherunicode] = kern
+ report_kern(feature,sequence,descriptions,unicode,otherunicode,kern)
+ end
+ end
+ else
+ for otherunicode, kern in next, data do
+ if not kerns[otherunicode] and kern ~= 0 then
+ kerns[otherunicode] = kern
+ end
+ end
+ end
+ end
+ else
+ for unicode, data in next, steps[i].coverage do
+ local character = characters[unicode]
+ local kerns = character.kerns
+ for otherunicode, kern in next, data do
+ -- kern[2] is true (all zero) or a table
+ local other = kern[2]
+ if other == true or (not other and not (kerns and kerns[otherunicode])) then
+ local kern = kern[1]
+ if kern == true then
+ -- all zero
+ elseif kern[1] ~= 0 or kern[2] ~= 0 or kern[4] ~= 0 then
+ -- a complex pair not suitable for basemode
+ else
+ kern = kern[3]
+ if kern ~= 0 then
+ if kerns then
+ kerns[otherunicode] = kern
+ else
+ kerns = { [otherunicode] = kern }
+ character.kerns = kerns
+ end
+ if traceindeed then
+ report_kern(feature,sequence,descriptions,unicode,otherunicode,kern)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+end
+
+local function initializehashes(tfmdata)
+ -- already done
+end
+
+local function checkmathreplacements(tfmdata,fullname,fixitalics)
+ if tfmdata.mathparameters then
+ local characters = tfmdata.characters
+ local changed = tfmdata.changed
+ if next(changed) then
+ if trace_preparing or trace_baseinit then
+ report_prepare("checking math replacements for %a",fullname)
+ end
+ for unicode, replacement in next, changed do
+ local u = characters[unicode]
+ local r = characters[replacement]
+ if u and r then
+ local n = u.next
+ local v = u.vert_variants
+ local h = u.horiz_variants
+ if fixitalics then
+ -- quite some warnings on stix ...
+ local ui = u.italic
+ if ui and not r.italic then
+ if trace_preparing then
+ report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement)
+ end
+ r.italic = ui -- print(ui,ri)
+ end
+ end
+ if n and not r.next then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement)
+ end
+ r.next = n
+ end
+ if v and not r.vert_variants then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement)
+ end
+ r.vert_variants = v
+ end
+ if h and not r.horiz_variants then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement)
+ end
+ r.horiz_variants = h
+ end
+ else
+ if trace_preparing then
+ report_prepare("error replacing %C by %U",unicode,replacement)
+ end
+ end
+ end
+ end
+ end
+end
+
+local function featuresinitializer(tfmdata,value)
+ if true then -- value then
+ local starttime = trace_preparing and os.clock()
+ local features = tfmdata.shared.features
+ local fullname = tfmdata.properties.fullname or "?"
+ if features then
+ initializehashes(tfmdata)
+ local collectlookups = otf.collectlookups
+ local rawdata = tfmdata.shared.rawdata
+ local properties = tfmdata.properties
+ local script = properties.script
+ local language = properties.language
+ local rawresources = rawdata.resources
+ local rawfeatures = rawresources and rawresources.features
+ local basesubstitutions = rawfeatures and rawfeatures.gsub
+ local basepositionings = rawfeatures and rawfeatures.gpos
+ local substitutionsdone = false
+ local positioningsdone = false
+ --
+ if basesubstitutions or basepositionings then
+ local sequences = tfmdata.resources.sequences
+ for s=1,#sequences do
+ local sequence = sequences[s]
+ local sfeatures = sequence.features
+ if sfeatures then
+ local order = sequence.order
+ if order then
+ for i=1,#order do --
+ local feature = order[i]
+ local value = features[feature]
+ if value then
+ local validlookups, lookuplist = collectlookups(rawdata,feature,script,language)
+ if not validlookups then
+ -- skip
+ elseif basesubstitutions and basesubstitutions[feature] then
+ if trace_preparing then
+ report_prepare("filtering base %s feature %a for %a with value %a","sub",feature,fullname,value)
+ end
+ preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist)
+ registerbasefeature(feature,value)
+ substitutionsdone = true
+ elseif basepositionings and basepositionings[feature] then
+ if trace_preparing then
+ report_prepare("filtering base %a feature %a for %a with value %a","pos",feature,fullname,value)
+ end
+ preparepositionings(tfmdata,feature,value,validlookups,lookuplist)
+ registerbasefeature(feature,value)
+ positioningsdone = true
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ --
+ if substitutionsdone then
+ checkmathreplacements(tfmdata,fullname,features.fixitalics)
+ end
+ --
+ registerbasehash(tfmdata)
+ end
+ if trace_preparing then
+ report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname)
+ end
+ end
+end
+
+registerotffeature {
+ name = "features",
+ description = "features",
+ default = true,
+ initializers = {
+ -- position = 1, -- after setscript (temp hack ... we need to force script / language to 1
+ base = featuresinitializer,
+ }
+}
+
+otf.basemodeinitializer = featuresinitializer
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otr.lua b/macros/luatex/generic/luaotfload/fontloader-font-otr.lua
new file mode 100644
index 0000000000..4fe0a6a976
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-otr.lua
@@ -0,0 +1,2553 @@
+if not modules then modules = { } end modules ['font-otr'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- When looking into a cid font relates issue in the ff library I wondered if
+-- it made sense to use Lua to filter the information from the otf and ttf
+-- files. Quite some ff code relates to special fonts and in practice we only
+-- use rather normal opentype fonts.
+--
+-- The code here is based on the documentation (and examples) at the microsoft
+-- website. The code will be extended and improved stepwise. After some experiments
+-- I decided to convert to a format more suitable for the context font handler
+-- because it makes no sense to rehash all those lookups again.
+--
+-- Currently we can use this code for getting basic info about the font, loading
+-- shapes and loading the extensive table. I'm not sure if I will provide a ff
+-- compatible output as well (We're not that far from it as currently I can load
+-- all data reasonable fast.)
+
+-- We can omit redundant glyphs names i.e. ones that match the agl or
+-- are just a unicode string but it doesn't save that much. It will be an option
+-- some day.
+
+-- Optimizing the widths will be done anyway as it save quite some on a cjk font
+-- and the existing (old) code if okay.
+
+-- todo: more messages (only if really needed)
+--
+-- considered, in math:
+--
+-- start -> first (so we can skip the first same-size one)
+-- end -> last
+--
+-- Widths and weights are kind of messy: for instance lmmonolt has a pfmweight of
+-- 400 while it should be 300. So, for now we mostly stick to the old compromis.
+
+-- We don't really need all those language tables so they might be dropped some
+-- day.
+
+-- The new reader is faster on some aspects and slower on other. The memory footprint
+-- is lower. The string reader is a bit faster than the file reader. The new reader
+-- gives more efficient tables and has bit more analysis. In practice these times are
+-- not that relevant because we cache. The otf files take a it more time because we
+-- need to calculate the boundingboxes. In theory the processing of text should be
+-- somewhat faster especially for complex fonts with many lookups.
+--
+-- old new str reader
+-- lmroman12-regular.otf 0.103 0.203 0.195
+-- latinmodern-math.otf 0.454 0.768 0.712
+-- husayni.ttf 1.142 1.526 1.259
+--
+-- If there is demand I will consider making a ff compatible table dumper but it's
+-- probably more fun to provide a way to show features applied.
+
+-- I experimented a bit with f:readbyte(n) and f:readshort() and so and it is indeed
+-- faster but it might not be the real bottleneck as we still need to juggle data. It
+-- is probably more memory efficient as no intermediate strings are involved.
+
+-- if not characters then
+-- require("char-def")
+-- require("char-ini")
+-- end
+
+local next, type, tonumber = next, type, tonumber
+local byte, lower, char, gsub = string.byte, string.lower, string.char, string.gsub
+local fullstrip = string.fullstrip
+local floor, round = math.floor, math.round
+local P, R, S, C, Cs, Cc, Ct, Carg, Cmt = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Carg, lpeg.Cmt
+local lpegmatch = lpeg.match
+local rshift = bit32.rshift
+
+local setmetatableindex = table.setmetatableindex
+local sortedkeys = table.sortedkeys
+local sortedhash = table.sortedhash
+local stripstring = string.nospaces
+local utf16_to_utf8_be = utf.utf16_to_utf8_be
+
+local report = logs.reporter("otf reader")
+local report_cmap = logs.reporter("otf reader","cmap")
+
+local trace_cmap = false trackers.register("otf.cmap", function(v) trace_cmap = v end)
+local trace_cmap_details = false trackers.register("otf.cmap.details", function(v) trace_cmap_details = v end)
+
+fonts = fonts or { }
+local handlers = fonts.handlers or { }
+fonts.handlers = handlers
+local otf = handlers.otf or { }
+handlers.otf = otf
+local readers = otf.readers or { }
+otf.readers = readers
+
+----- streamreader = utilities.streams -- faster on big files (not true any longer)
+local streamreader = utilities.files -- faster on identify (also uses less memory)
+local streamwriter = utilities.files
+
+readers.streamreader = streamreader
+readers.streamwriter = streamwriter
+
+local openfile = streamreader.open
+local closefile = streamreader.close
+----- skipbytes = streamreader.skip
+local setposition = streamreader.setposition
+local skipshort = streamreader.skipshort
+local readbytes = streamreader.readbytes
+local readstring = streamreader.readstring
+local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer
+local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer
+local readuint = streamreader.readcardinal3 -- 24-bit unsigned integer
+local readulong = streamreader.readcardinal4 -- 32-bit unsigned integer
+----- readchar = streamreader.readinteger1 -- 8-bit signed integer
+local readshort = streamreader.readinteger2 -- 16-bit signed integer
+local readlong = streamreader.readinteger4 -- 32-bit unsigned integer
+local readfixed = streamreader.readfixed4
+local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14)
+local readfword = readshort -- 16-bit signed integer that describes a quantity in FUnits
+local readufword = readushort -- 16-bit unsigned integer that describes a quantity in FUnits
+local readoffset = readushort
+local readcardinaltable = streamreader.readcardinaltable
+local readintegertable = streamreader.readintegertable
+
+function streamreader.readtag(f)
+ return lower(stripstring(readstring(f,4)))
+end
+
+local short = 2
+local ushort = 2
+local ulong = 4
+
+directives.register("fonts.streamreader",function()
+
+ streamreader = utilities.streams
+
+ openfile = streamreader.open
+ closefile = streamreader.close
+ setposition = streamreader.setposition
+ skipshort = streamreader.skipshort
+ readbytes = streamreader.readbytes
+ readstring = streamreader.readstring
+ readbyte = streamreader.readcardinal1
+ readushort = streamreader.readcardinal2
+ readuint = streamreader.readcardinal3
+ readulong = streamreader.readcardinal4
+ readshort = streamreader.readinteger2
+ readlong = streamreader.readinteger4
+ readfixed = streamreader.readfixed4
+ read2dot14 = streamreader.read2dot14
+ readfword = readshort
+ readufword = readushort
+ readoffset = readushort
+ readcardinaltable = streamreader.readcardinaltable
+ readintegertable = streamreader.readintegertable
+
+ function streamreader.readtag(f)
+ return lower(stripstring(readstring(f,4)))
+ end
+
+end)
+
+-- date represented in number of seconds since 12:00 midnight, January 1, 1904. The value is represented as a
+-- signed 64-bit integer
+
+local function readlongdatetime(f)
+ local a, b, c, d, e, f, g, h = readbytes(f,8)
+ return 0x100000000 * d + 0x1000000 * e + 0x10000 * f + 0x100 * g + h
+end
+
+local tableversion = 0.004
+readers.tableversion = tableversion
+local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF
+
+-- We have quite some data tables. We are somewhat ff compatible with names but as I used
+-- the information from the microsoft site there can be differences. Eventually I might end
+-- up with a different ordering and naming.
+
+local reservednames = { [0] =
+ "copyright",
+ "family",
+ "subfamily",
+ "uniqueid",
+ "fullname",
+ "version",
+ "postscriptname",
+ "trademark",
+ "manufacturer",
+ "designer",
+ "description", -- descriptor in ff
+ "vendorurl",
+ "designerurl",
+ "license",
+ "licenseurl",
+ "reserved",
+ "typographicfamily", -- preffamilyname
+ "typographicsubfamily", -- prefmodifiers
+ "compatiblefullname", -- for mac
+ "sampletext",
+ "cidfindfontname",
+ "wwsfamily",
+ "wwssubfamily",
+ "lightbackgroundpalette",
+ "darkbackgroundpalette",
+ "variationspostscriptnameprefix",
+}
+
+-- more at: https://www.microsoft.com/typography/otspec/name.htm
+
+-- setmetatableindex(reservednames,function(t,k)
+-- local v = "name_" .. k
+-- t[k] = v
+-- return v
+-- end)
+
+local platforms = { [0] =
+ "unicode",
+ "macintosh",
+ "iso",
+ "windows",
+ "custom",
+}
+
+local encodings = {
+ -- these stay:
+ unicode = { [0] =
+ "unicode 1.0 semantics",
+ "unicode 1.1 semantics",
+ "iso/iec 10646",
+ "unicode 2.0 bmp", -- cmap subtable formats 0, 4, 6
+ "unicode 2.0 full", -- cmap subtable formats 0, 4, 6, 10, 12
+ "unicode variation sequences", -- cmap subtable format 14).
+ "unicode full repertoire", -- cmap subtable formats 0, 4, 6, 10, 12, 13
+ },
+ -- these can go:
+ macintosh = { [0] =
+ "roman", "japanese", "chinese (traditional)", "korean", "arabic", "hebrew", "greek", "russian",
+ "rsymbol", "devanagari", "gurmukhi", "gujarati", "oriya", "bengali", "tamil", "telugu", "kannada",
+ "malayalam", "sinhalese", "burmese", "khmer", "thai", "laotian", "georgian", "armenian",
+ "chinese (simplified)", "tibetan", "mongolian", "geez", "slavic", "vietnamese", "sindhi",
+ "uninterpreted",
+ },
+ -- these stay:
+ iso = { [0] =
+ "7-bit ascii",
+ "iso 10646",
+ "iso 8859-1",
+ },
+ -- these stay:
+ windows = { [0] =
+ "symbol",
+ "unicode bmp", -- this is utf16
+ "shiftjis",
+ "prc",
+ "big5",
+ "wansung",
+ "johab",
+ "reserved 7",
+ "reserved 8",
+ "reserved 9",
+ "unicode ucs-4",
+ },
+ custom = {
+ --custom: 0-255 : otf windows nt compatibility mapping
+ }
+}
+
+local decoders = {
+ unicode = { },
+ macintosh = { },
+ iso = { },
+ windows = {
+ -- maybe always utf16
+ ["unicode semantics"] = utf16_to_utf8_be,
+ ["unicode bmp"] = utf16_to_utf8_be,
+ ["unicode full"] = utf16_to_utf8_be,
+ ["unicode 1.0 semantics"] = utf16_to_utf8_be,
+ ["unicode 1.1 semantics"] = utf16_to_utf8_be,
+ ["unicode 2.0 bmp"] = utf16_to_utf8_be,
+ ["unicode 2.0 full"] = utf16_to_utf8_be,
+ ["unicode variation sequences"] = utf16_to_utf8_be,
+ ["unicode full repertoire"] = utf16_to_utf8_be,
+ },
+ custom = { },
+}
+
+-- This is bit over the top as we can just look for either windows, unicode or macintosh
+-- names (in that order). A font with no english name is probably a weird one anyway.
+
+local languages = {
+ -- these stay:
+ unicode = {
+ [ 0] = "english",
+ },
+ -- english can stay:
+ macintosh = {
+ [ 0] = "english",
+ -- [ 1] = "french",
+ -- [ 2] = "german",
+ -- [ 3] = "italian",
+ -- [ 4] = "dutch",
+ -- [ 5] = "swedish",
+ -- [ 6] = "spanish",
+ -- [ 7] = "danish",
+ -- [ 8] = "portuguese",
+ -- [ 9] = "norwegian",
+ -- [ 10] = "hebrew",
+ -- [ 11] = "japanese",
+ -- [ 12] = "arabic",
+ -- [ 13] = "finnish",
+ -- [ 14] = "greek",
+ -- [ 15] = "icelandic",
+ -- [ 16] = "maltese",
+ -- [ 17] = "turkish",
+ -- [ 18] = "croatian",
+ -- [ 19] = "chinese (traditional)",
+ -- [ 20] = "urdu",
+ -- [ 21] = "hindi",
+ -- [ 22] = "thai",
+ -- [ 23] = "korean",
+ -- [ 24] = "lithuanian",
+ -- [ 25] = "polish",
+ -- [ 26] = "hungarian",
+ -- [ 27] = "estonian",
+ -- [ 28] = "latvian",
+ -- [ 29] = "sami",
+ -- [ 30] = "faroese",
+ -- [ 31] = "farsi/persian",
+ -- [ 32] = "russian",
+ -- [ 33] = "chinese (simplified)",
+ -- [ 34] = "flemish",
+ -- [ 35] = "irish gaelic",
+ -- [ 36] = "albanian",
+ -- [ 37] = "romanian",
+ -- [ 38] = "czech",
+ -- [ 39] = "slovak",
+ -- [ 40] = "slovenian",
+ -- [ 41] = "yiddish",
+ -- [ 42] = "serbian",
+ -- [ 43] = "macedonian",
+ -- [ 44] = "bulgarian",
+ -- [ 45] = "ukrainian",
+ -- [ 46] = "byelorussian",
+ -- [ 47] = "uzbek",
+ -- [ 48] = "kazakh",
+ -- [ 49] = "azerbaijani (cyrillic script)",
+ -- [ 50] = "azerbaijani (arabic script)",
+ -- [ 51] = "armenian",
+ -- [ 52] = "georgian",
+ -- [ 53] = "moldavian",
+ -- [ 54] = "kirghiz",
+ -- [ 55] = "tajiki",
+ -- [ 56] = "turkmen",
+ -- [ 57] = "mongolian (mongolian script)",
+ -- [ 58] = "mongolian (cyrillic script)",
+ -- [ 59] = "pashto",
+ -- [ 60] = "kurdish",
+ -- [ 61] = "kashmiri",
+ -- [ 62] = "sindhi",
+ -- [ 63] = "tibetan",
+ -- [ 64] = "nepali",
+ -- [ 65] = "sanskrit",
+ -- [ 66] = "marathi",
+ -- [ 67] = "bengali",
+ -- [ 68] = "assamese",
+ -- [ 69] = "gujarati",
+ -- [ 70] = "punjabi",
+ -- [ 71] = "oriya",
+ -- [ 72] = "malayalam",
+ -- [ 73] = "kannada",
+ -- [ 74] = "tamil",
+ -- [ 75] = "telugu",
+ -- [ 76] = "sinhalese",
+ -- [ 77] = "burmese",
+ -- [ 78] = "khmer",
+ -- [ 79] = "lao",
+ -- [ 80] = "vietnamese",
+ -- [ 81] = "indonesian",
+ -- [ 82] = "tagalong",
+ -- [ 83] = "malay (roman script)",
+ -- [ 84] = "malay (arabic script)",
+ -- [ 85] = "amharic",
+ -- [ 86] = "tigrinya",
+ -- [ 87] = "galla",
+ -- [ 88] = "somali",
+ -- [ 89] = "swahili",
+ -- [ 90] = "kinyarwanda/ruanda",
+ -- [ 91] = "rundi",
+ -- [ 92] = "nyanja/chewa",
+ -- [ 93] = "malagasy",
+ -- [ 94] = "esperanto",
+ -- [128] = "welsh",
+ -- [129] = "basque",
+ -- [130] = "catalan",
+ -- [131] = "latin",
+ -- [132] = "quenchua",
+ -- [133] = "guarani",
+ -- [134] = "aymara",
+ -- [135] = "tatar",
+ -- [136] = "uighur",
+ -- [137] = "dzongkha",
+ -- [138] = "javanese (roman script)",
+ -- [139] = "sundanese (roman script)",
+ -- [140] = "galician",
+ -- [141] = "afrikaans",
+ -- [142] = "breton",
+ -- [143] = "inuktitut",
+ -- [144] = "scottish gaelic",
+ -- [145] = "manx gaelic",
+ -- [146] = "irish gaelic (with dot above)",
+ -- [147] = "tongan",
+ -- [148] = "greek (polytonic)",
+ -- [149] = "greenlandic",
+ -- [150] = "azerbaijani (roman script)",
+ },
+ -- these can stay:
+ iso = {
+ },
+ -- english can stay:
+ windows = {
+ -- [0x0436] = "afrikaans - south africa",
+ -- [0x041c] = "albanian - albania",
+ -- [0x0484] = "alsatian - france",
+ -- [0x045e] = "amharic - ethiopia",
+ -- [0x1401] = "arabic - algeria",
+ -- [0x3c01] = "arabic - bahrain",
+ -- [0x0c01] = "arabic - egypt",
+ -- [0x0801] = "arabic - iraq",
+ -- [0x2c01] = "arabic - jordan",
+ -- [0x3401] = "arabic - kuwait",
+ -- [0x3001] = "arabic - lebanon",
+ -- [0x1001] = "arabic - libya",
+ -- [0x1801] = "arabic - morocco",
+ -- [0x2001] = "arabic - oman",
+ -- [0x4001] = "arabic - qatar",
+ -- [0x0401] = "arabic - saudi arabia",
+ -- [0x2801] = "arabic - syria",
+ -- [0x1c01] = "arabic - tunisia",
+ -- [0x3801] = "arabic - u.a.e.",
+ -- [0x2401] = "arabic - yemen",
+ -- [0x042b] = "armenian - armenia",
+ -- [0x044d] = "assamese - india",
+ -- [0x082c] = "azeri (cyrillic) - azerbaijan",
+ -- [0x042c] = "azeri (latin) - azerbaijan",
+ -- [0x046d] = "bashkir - russia",
+ -- [0x042d] = "basque - basque",
+ -- [0x0423] = "belarusian - belarus",
+ -- [0x0845] = "bengali - bangladesh",
+ -- [0x0445] = "bengali - india",
+ -- [0x201a] = "bosnian (cyrillic) - bosnia and herzegovina",
+ -- [0x141a] = "bosnian (latin) - bosnia and herzegovina",
+ -- [0x047e] = "breton - france",
+ -- [0x0402] = "bulgarian - bulgaria",
+ -- [0x0403] = "catalan - catalan",
+ -- [0x0c04] = "chinese - hong kong s.a.r.",
+ -- [0x1404] = "chinese - macao s.a.r.",
+ -- [0x0804] = "chinese - people's republic of china",
+ -- [0x1004] = "chinese - singapore",
+ -- [0x0404] = "chinese - taiwan",
+ -- [0x0483] = "corsican - france",
+ -- [0x041a] = "croatian - croatia",
+ -- [0x101a] = "croatian (latin) - bosnia and herzegovina",
+ -- [0x0405] = "czech - czech republic",
+ -- [0x0406] = "danish - denmark",
+ -- [0x048c] = "dari - afghanistan",
+ -- [0x0465] = "divehi - maldives",
+ -- [0x0813] = "dutch - belgium",
+ -- [0x0413] = "dutch - netherlands",
+ -- [0x0c09] = "english - australia",
+ -- [0x2809] = "english - belize",
+ -- [0x1009] = "english - canada",
+ -- [0x2409] = "english - caribbean",
+ -- [0x4009] = "english - india",
+ -- [0x1809] = "english - ireland",
+ -- [0x2009] = "english - jamaica",
+ -- [0x4409] = "english - malaysia",
+ -- [0x1409] = "english - new zealand",
+ -- [0x3409] = "english - republic of the philippines",
+ -- [0x4809] = "english - singapore",
+ -- [0x1c09] = "english - south africa",
+ -- [0x2c09] = "english - trinidad and tobago",
+ -- [0x0809] = "english - united kingdom",
+ [0x0409] = "english - united states",
+ -- [0x3009] = "english - zimbabwe",
+ -- [0x0425] = "estonian - estonia",
+ -- [0x0438] = "faroese - faroe islands",
+ -- [0x0464] = "filipino - philippines",
+ -- [0x040b] = "finnish - finland",
+ -- [0x080c] = "french - belgium",
+ -- [0x0c0c] = "french - canada",
+ -- [0x040c] = "french - france",
+ -- [0x140c] = "french - luxembourg",
+ -- [0x180c] = "french - principality of monoco",
+ -- [0x100c] = "french - switzerland",
+ -- [0x0462] = "frisian - netherlands",
+ -- [0x0456] = "galician - galician",
+ -- [0x0437] = "georgian -georgia",
+ -- [0x0c07] = "german - austria",
+ -- [0x0407] = "german - germany",
+ -- [0x1407] = "german - liechtenstein",
+ -- [0x1007] = "german - luxembourg",
+ -- [0x0807] = "german - switzerland",
+ -- [0x0408] = "greek - greece",
+ -- [0x046f] = "greenlandic - greenland",
+ -- [0x0447] = "gujarati - india",
+ -- [0x0468] = "hausa (latin) - nigeria",
+ -- [0x040d] = "hebrew - israel",
+ -- [0x0439] = "hindi - india",
+ -- [0x040e] = "hungarian - hungary",
+ -- [0x040f] = "icelandic - iceland",
+ -- [0x0470] = "igbo - nigeria",
+ -- [0x0421] = "indonesian - indonesia",
+ -- [0x045d] = "inuktitut - canada",
+ -- [0x085d] = "inuktitut (latin) - canada",
+ -- [0x083c] = "irish - ireland",
+ -- [0x0434] = "isixhosa - south africa",
+ -- [0x0435] = "isizulu - south africa",
+ -- [0x0410] = "italian - italy",
+ -- [0x0810] = "italian - switzerland",
+ -- [0x0411] = "japanese - japan",
+ -- [0x044b] = "kannada - india",
+ -- [0x043f] = "kazakh - kazakhstan",
+ -- [0x0453] = "khmer - cambodia",
+ -- [0x0486] = "k'iche - guatemala",
+ -- [0x0487] = "kinyarwanda - rwanda",
+ -- [0x0441] = "kiswahili - kenya",
+ -- [0x0457] = "konkani - india",
+ -- [0x0412] = "korean - korea",
+ -- [0x0440] = "kyrgyz - kyrgyzstan",
+ -- [0x0454] = "lao - lao p.d.r.",
+ -- [0x0426] = "latvian - latvia",
+ -- [0x0427] = "lithuanian - lithuania",
+ -- [0x082e] = "lower sorbian - germany",
+ -- [0x046e] = "luxembourgish - luxembourg",
+ -- [0x042f] = "macedonian (fyrom) - former yugoslav republic of macedonia",
+ -- [0x083e] = "malay - brunei darussalam",
+ -- [0x043e] = "malay - malaysia",
+ -- [0x044c] = "malayalam - india",
+ -- [0x043a] = "maltese - malta",
+ -- [0x0481] = "maori - new zealand",
+ -- [0x047a] = "mapudungun - chile",
+ -- [0x044e] = "marathi - india",
+ -- [0x047c] = "mohawk - mohawk",
+ -- [0x0450] = "mongolian (cyrillic) - mongolia",
+ -- [0x0850] = "mongolian (traditional) - people's republic of china",
+ -- [0x0461] = "nepali - nepal",
+ -- [0x0414] = "norwegian (bokmal) - norway",
+ -- [0x0814] = "norwegian (nynorsk) - norway",
+ -- [0x0482] = "occitan - france",
+ -- [0x0448] = "odia (formerly oriya) - india",
+ -- [0x0463] = "pashto - afghanistan",
+ -- [0x0415] = "polish - poland",
+ -- [0x0416] = "portuguese - brazil",
+ -- [0x0816] = "portuguese - portugal",
+ -- [0x0446] = "punjabi - india",
+ -- [0x046b] = "quechua - bolivia",
+ -- [0x086b] = "quechua - ecuador",
+ -- [0x0c6b] = "quechua - peru",
+ -- [0x0418] = "romanian - romania",
+ -- [0x0417] = "romansh - switzerland",
+ -- [0x0419] = "russian - russia",
+ -- [0x243b] = "sami (inari) - finland",
+ -- [0x103b] = "sami (lule) - norway",
+ -- [0x143b] = "sami (lule) - sweden",
+ -- [0x0c3b] = "sami (northern) - finland",
+ -- [0x043b] = "sami (northern) - norway",
+ -- [0x083b] = "sami (northern) - sweden",
+ -- [0x203b] = "sami (skolt) - finland",
+ -- [0x183b] = "sami (southern) - norway",
+ -- [0x1c3b] = "sami (southern) - sweden",
+ -- [0x044f] = "sanskrit - india",
+ -- [0x1c1a] = "serbian (cyrillic) - bosnia and herzegovina",
+ -- [0x0c1a] = "serbian (cyrillic) - serbia",
+ -- [0x181a] = "serbian (latin) - bosnia and herzegovina",
+ -- [0x081a] = "serbian (latin) - serbia",
+ -- [0x046c] = "sesotho sa leboa - south africa",
+ -- [0x0432] = "setswana - south africa",
+ -- [0x045b] = "sinhala - sri lanka",
+ -- [0x041b] = "slovak - slovakia",
+ -- [0x0424] = "slovenian - slovenia",
+ -- [0x2c0a] = "spanish - argentina",
+ -- [0x400a] = "spanish - bolivia",
+ -- [0x340a] = "spanish - chile",
+ -- [0x240a] = "spanish - colombia",
+ -- [0x140a] = "spanish - costa rica",
+ -- [0x1c0a] = "spanish - dominican republic",
+ -- [0x300a] = "spanish - ecuador",
+ -- [0x440a] = "spanish - el salvador",
+ -- [0x100a] = "spanish - guatemala",
+ -- [0x480a] = "spanish - honduras",
+ -- [0x080a] = "spanish - mexico",
+ -- [0x4c0a] = "spanish - nicaragua",
+ -- [0x180a] = "spanish - panama",
+ -- [0x3c0a] = "spanish - paraguay",
+ -- [0x280a] = "spanish - peru",
+ -- [0x500a] = "spanish - puerto rico",
+ -- [0x0c0a] = "spanish (modern sort) - spain",
+ -- [0x040a] = "spanish (traditional sort) - spain",
+ -- [0x540a] = "spanish - united states",
+ -- [0x380a] = "spanish - uruguay",
+ -- [0x200a] = "spanish - venezuela",
+ -- [0x081d] = "sweden - finland",
+ -- [0x041d] = "swedish - sweden",
+ -- [0x045a] = "syriac - syria",
+ -- [0x0428] = "tajik (cyrillic) - tajikistan",
+ -- [0x085f] = "tamazight (latin) - algeria",
+ -- [0x0449] = "tamil - india",
+ -- [0x0444] = "tatar - russia",
+ -- [0x044a] = "telugu - india",
+ -- [0x041e] = "thai - thailand",
+ -- [0x0451] = "tibetan - prc",
+ -- [0x041f] = "turkish - turkey",
+ -- [0x0442] = "turkmen - turkmenistan",
+ -- [0x0480] = "uighur - prc",
+ -- [0x0422] = "ukrainian - ukraine",
+ -- [0x042e] = "upper sorbian - germany",
+ -- [0x0420] = "urdu - islamic republic of pakistan",
+ -- [0x0843] = "uzbek (cyrillic) - uzbekistan",
+ -- [0x0443] = "uzbek (latin) - uzbekistan",
+ -- [0x042a] = "vietnamese - vietnam",
+ -- [0x0452] = "welsh - united kingdom",
+ -- [0x0488] = "wolof - senegal",
+ -- [0x0485] = "yakut - russia",
+ -- [0x0478] = "yi - prc",
+ -- [0x046a] = "yoruba - nigeria",
+ },
+ custom = {
+ },
+}
+
+local standardromanencoding = { [0] = -- taken from wikipedia
+ "notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl",
+ "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft",
+ "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash",
+ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight",
+ "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at",
+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
+ "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft",
+ "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b",
+ "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q",
+ "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar",
+ "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", "Eacute",
+ "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex",
+ "adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave",
+ "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis",
+ "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute",
+ "ugrave", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling",
+ "section", "bullet", "paragraph", "germandbls", "registered", "copyright",
+ "trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity",
+ "plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff",
+ "summation", "product", "pi", "integral", "ordfeminine", "ordmasculine",
+ "Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot",
+ "radical", "florin", "approxequal", "Delta", "guillemotleft",
+ "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde",
+ "Otilde", "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright",
+ "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis",
+ "fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl",
+ "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase",
+ "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave",
+ "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex",
+ "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi",
+ "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla",
+ "hungarumlaut", "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron",
+ "Zcaron", "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn",
+ "thorn", "minus", "multiply", "onesuperior", "twosuperior", "threesuperior",
+ "onehalf", "onequarter", "threequarters", "franc", "Gbreve", "gbreve",
+ "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron", "ccaron",
+ "dcroat",
+}
+
+local weights = {
+ [100] = "thin",
+ [200] = "extralight",
+ [300] = "light",
+ [400] = "normal",
+ [500] = "medium",
+ [600] = "semibold", -- demi demibold
+ [700] = "bold",
+ [800] = "extrabold",
+ [900] = "black",
+}
+
+local widths = {
+ [1] = "ultracondensed",
+ [2] = "extracondensed",
+ [3] = "condensed",
+ [4] = "semicondensed",
+ [5] = "normal",
+ [6] = "semiexpanded",
+ [7] = "expanded",
+ [8] = "extraexpanded",
+ [9] = "ultraexpanded",
+}
+
+setmetatableindex(weights, function(t,k)
+ local r = floor((k + 50) / 100) * 100
+ local v = (r > 900 and "black") or rawget(t,r) or "normal"
+ return v
+end)
+
+setmetatableindex(widths,function(t,k)
+ return "normal"
+end)
+
+local panoseweights = {
+ [ 0] = "normal",
+ [ 1] = "normal",
+ [ 2] = "verylight",
+ [ 3] = "light",
+ [ 4] = "thin",
+ [ 5] = "book",
+ [ 6] = "medium",
+ [ 7] = "demi",
+ [ 8] = "bold",
+ [ 9] = "heavy",
+ [10] = "black",
+}
+
+local panosewidths = {
+ [ 0] = "normal",
+ [ 1] = "normal",
+ [ 2] = "normal",
+ [ 3] = "normal",
+ [ 4] = "normal",
+ [ 5] = "expanded",
+ [ 6] = "condensed",
+ [ 7] = "veryexpanded",
+ [ 8] = "verycondensed",
+ [ 9] = "monospaced",
+}
+
+-- We implement a reader per table.
+
+-- helper
+
+local helpers = { }
+readers.helpers = helpers
+
+local function gotodatatable(f,fontdata,tag,criterium)
+ if criterium and f then
+ local tables = fontdata.tables
+ if tables then
+ local datatable = tables[tag]
+ if datatable then
+ local tableoffset = datatable.offset
+ setposition(f,tableoffset)
+ return tableoffset
+ end
+ else
+ report("no tables")
+ end
+ end
+end
+
+local function reportskippedtable(f,fontdata,tag,criterium)
+ if criterium and f then
+ local tables = fontdata.tables
+ if tables then
+ local datatable = tables[tag]
+ if datatable then
+ report("loading of table %a skipped",tag)
+ end
+ else
+ report("no tables")
+ end
+ end
+end
+
+local function setvariabledata(fontdata,tag,data)
+ local variabledata = fontdata.variabledata
+ if variabledata then
+ variabledata[tag] = data
+ else
+ fontdata.variabledata = { [tag] = data }
+ end
+end
+
+helpers.gotodatatable = gotodatatable
+helpers.setvariabledata = setvariabledata
+helpers.reportskippedtable = reportskippedtable
+
+-- The name table is probably the first one to load. After all this one provides
+-- useful information about what we deal with. The complication is that we need
+-- to filter the best one available.
+
+local platformnames = {
+ postscriptname = true,
+ fullname = true,
+ family = true,
+ subfamily = true,
+ typographicfamily = true,
+ typographicsubfamily = true,
+ compatiblefullname = true,
+}
+
+local platformextras = {
+ uniqueid = true,
+ version = true,
+ copyright = true,
+ license = true,
+ licenseurl = true,
+ manufacturer = true,
+ vendorurl = true,
+}
+
+function readers.name(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"name",true)
+ if tableoffset then
+ local format = readushort(f)
+ local nofnames = readushort(f)
+ local offset = readushort(f)
+ -- we can also provide a raw list as extra, todo as option
+ local start = tableoffset + offset
+ local namelists = {
+ unicode = { },
+ windows = { },
+ macintosh = { },
+ -- iso = { },
+ -- windows = { },
+ }
+ for i=1,nofnames do
+ local platform = platforms[readushort(f)]
+ if platform then
+ local namelist = namelists[platform]
+ if namelist then
+ local encoding = readushort(f)
+ local language = readushort(f)
+ local encodings = encodings[platform]
+ local languages = languages[platform]
+ if encodings and languages then
+ local encoding = encodings[encoding]
+ local language = languages[language]
+ if encoding and language then
+ local index = readushort(f)
+ local name = reservednames[index]
+ namelist[#namelist+1] = {
+ platform = platform,
+ encoding = encoding,
+ language = language,
+ name = name,
+ index = index,
+ length = readushort(f),
+ offset = start + readushort(f),
+ }
+ else
+ skipshort(f,3)
+ end
+ else
+ skipshort(f,3)
+ end
+ else
+ skipshort(f,5)
+ end
+ else
+ skipshort(f,5)
+ end
+ end
+ -- if format == 1 then
+ -- local noftags = readushort(f)
+ -- for i=1,noftags do
+ -- local length = readushort(f)
+ -- local offset = readushort(f)
+ -- end
+ -- end
+ --
+ -- we need to choose one we like, for instance an unicode one
+ --
+ local names = { }
+ local done = { }
+ local extras = { }
+ --
+ -- there is quite some logic in ff ... hard to follow so we start simple
+ -- and extend when we run into it (todo: proper reverse hash) .. we're only
+ -- interested in english anyway
+ --
+ local function decoded(platform,encoding,content)
+ local decoder = decoders[platform]
+ if decoder then
+ decoder = decoder[encoding]
+ end
+ if decoder then
+ return decoder(content)
+ else
+ return content
+ end
+ end
+ --
+ local function filter(platform,e,l)
+ local namelist = namelists[platform]
+ for i=1,#namelist do
+ local name = namelist[i]
+ local nametag = name.name
+ local index = name.index
+ if not done[nametag or i] then
+ local encoding = name.encoding
+ local language = name.language
+ if (not e or encoding == e) and (not l or language == l) then
+ setposition(f,name.offset)
+ local content = decoded(platform,encoding,readstring(f,name.length))
+ if nametag then
+ names[nametag] = {
+ content = content,
+ platform = platform,
+ encoding = encoding,
+ language = language,
+ }
+ end
+ extras[index] = content
+ done[nametag or i] = true
+ end
+ end
+ end
+ end
+ --
+ filter("windows","unicode bmp","english - united states")
+ -- filter("unicode") -- which one ?
+ filter("macintosh","roman","english")
+ filter("windows")
+ filter("macintosh")
+ filter("unicode")
+ --
+ fontdata.names = names
+ fontdata.extras = extras
+ --
+ if specification.platformnames then
+ local collected = { }
+ local platformextras = specification.platformextras and platformextras
+ for platform, namelist in next, namelists do
+ local filtered = false
+ for i=1,#namelist do
+ local entry = namelist[i]
+ local name = entry.name
+ if platformnames[name] or (platformextras and platformextras[name]) then
+ setposition(f,entry.offset)
+ local content = decoded(platform,entry.encoding,readstring(f,entry.length))
+ if filtered then
+ filtered[name] = content
+ else
+ filtered = { [name] = content }
+ end
+ end
+ end
+ if filtered then
+ collected[platform] = filtered
+ end
+ end
+ fontdata.platformnames = collected
+ end
+ else
+ fontdata.names = { }
+ end
+end
+
+----- validutf = lpeg.patterns.utf8character^0 * P(-1)
+local validutf = lpeg.patterns.validutf8
+
+local function getname(fontdata,key)
+ local names = fontdata.names
+ if names then
+ local value = names[key]
+ if value then
+ local content = value.content
+ return lpegmatch(validutf,content) and content or nil
+ end
+ end
+end
+
+-- This table is an original windows (with its precursor os/2) table. In ff this one is
+-- part of the pfminfo table but here we keep it separate (for now). We will create a
+-- properties table afterwards.
+
+readers["os/2"] = function(f,fontdata)
+ local tableoffset = gotodatatable(f,fontdata,"os/2",true)
+ if tableoffset then
+ local version = readushort(f)
+ local windowsmetrics = {
+ version = version,
+ averagewidth = readshort(f), -- ushort?
+ weightclass = readushort(f),
+ widthclass = readushort(f),
+ fstype = readushort(f),
+ subscriptxsize = readshort(f),
+ subscriptysize = readshort(f),
+ subscriptxoffset = readshort(f),
+ subscriptyoffset = readshort(f),
+ superscriptxsize = readshort(f),
+ superscriptysize = readshort(f),
+ superscriptxoffset = readshort(f),
+ superscriptyoffset = readshort(f),
+ strikeoutsize = readshort(f),
+ strikeoutpos = readshort(f),
+ familyclass = readshort(f),
+ panose = { readbytes(f,10) },
+ unicoderanges = { readulong(f), readulong(f), readulong(f), readulong(f) },
+ vendor = readstring(f,4),
+ fsselection = readushort(f),
+ firstcharindex = readushort(f),
+ lastcharindex = readushort(f),
+ typoascender = readshort(f),
+ typodescender = readshort(f),
+ typolinegap = readshort(f),
+ winascent = readushort(f),
+ windescent = readushort(f),
+ }
+ if version >= 1 then
+ windowsmetrics.codepageranges = { readulong(f), readulong(f) }
+ end
+ if version >= 2 then
+ windowsmetrics.xheight = readshort(f)
+ windowsmetrics.capheight = readshort(f)
+ windowsmetrics.defaultchar = readushort(f)
+ windowsmetrics.breakchar = readushort(f)
+ -- windowsmetrics.maxcontexts = readushort(f)
+ -- windowsmetrics.loweropticalpointsize = readushort(f)
+ -- windowsmetrics.upperopticalpointsize = readushort(f)
+ end
+ --
+ -- todo: unicoderanges
+ --
+ windowsmetrics.weight = windowsmetrics.weightclass and weights[windowsmetrics.weightclass]
+ windowsmetrics.width = windowsmetrics.widthclass and widths [windowsmetrics.widthclass]
+ --
+ windowsmetrics.panoseweight = panoseweights[windowsmetrics.panose[3]]
+ windowsmetrics.panosewidth = panosewidths [windowsmetrics.panose[4]]
+ --
+ fontdata.windowsmetrics = windowsmetrics
+ else
+ fontdata.windowsmetrics = { }
+ end
+end
+
+readers.head = function(f,fontdata)
+ local tableoffset = gotodatatable(f,fontdata,"head",true)
+ if tableoffset then
+ local version = readulong(f)
+ local fontversion = readulong(f)
+ local fontheader = {
+ version = version,
+ fontversion = number.to16dot16(fontversion),
+ fontversionnumber = fontversion,
+ -- checksum = readulong(f),
+ checksum = readushort(f) * 0x10000 + readushort(f),
+ magic = readulong(f),
+ flags = readushort(f),
+ units = readushort(f),
+ created = readlongdatetime(f),
+ modified = readlongdatetime(f),
+ xmin = readshort(f),
+ ymin = readshort(f),
+ xmax = readshort(f),
+ ymax = readshort(f),
+ macstyle = readushort(f),
+ smallpixels = readushort(f),
+ directionhint = readshort(f),
+ indextolocformat = readshort(f),
+ glyphformat = readshort(f),
+ }
+ fontdata.fontheader = fontheader
+ else
+ fontdata.fontheader = { }
+ end
+ fontdata.nofglyphs = 0
+end
+
+-- This table is a rather simple one. No treatment of values is needed here. Most
+-- variables are not used but nofmetrics is quite important.
+
+readers.hhea = function(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"hhea",specification.details)
+ if tableoffset then
+ fontdata.horizontalheader = {
+ version = readulong(f),
+ ascender = readfword(f),
+ descender = readfword(f),
+ linegap = readfword(f),
+ maxadvancewidth = readufword(f),
+ minleftsidebearing = readfword(f),
+ minrightsidebearing = readfword(f),
+ maxextent = readfword(f),
+ caretsloperise = readshort(f),
+ caretsloperun = readshort(f),
+ caretoffset = readshort(f),
+ reserved_1 = readshort(f),
+ reserved_2 = readshort(f),
+ reserved_3 = readshort(f),
+ reserved_4 = readshort(f),
+ metricdataformat = readshort(f),
+ nofmetrics = readushort(f),
+ }
+ else
+ fontdata.horizontalheader = {
+ nofmetrics = 0,
+ }
+ end
+end
+
+readers.vhea = function(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"vhea",specification.details)
+ if tableoffset then
+ fontdata.verticalheader = {
+ version = readulong(f),
+ ascender = readfword(f),
+ descender = readfword(f),
+ linegap = readfword(f),
+ maxadvanceheight = readufword(f),
+ mintopsidebearing = readfword(f),
+ minbottomsidebearing = readfword(f),
+ maxextent = readfword(f),
+ caretsloperise = readshort(f),
+ caretsloperun = readshort(f),
+ caretoffset = readshort(f),
+ reserved_1 = readshort(f),
+ reserved_2 = readshort(f),
+ reserved_3 = readshort(f),
+ reserved_4 = readshort(f),
+ metricdataformat = readshort(f),
+ nofmetrics = readushort(f),
+ }
+ else
+ fontdata.verticalheader = {
+ nofmetrics = 0,
+ }
+ end
+end
+
+-- We probably never need all these variables, but we do need the nofglyphs when loading other
+-- tables. Again we use the microsoft names but see no reason to have "max" in each name.
+
+-- fontdata.maximumprofile can be bad
+
+readers.maxp = function(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"maxp",specification.details)
+ if tableoffset then
+ local version = readulong(f)
+ local nofglyphs = readushort(f)
+ fontdata.nofglyphs = nofglyphs
+ if version == 0x00005000 then
+ fontdata.maximumprofile = {
+ version = version,
+ nofglyphs = nofglyphs,
+ }
+ elseif version == 0x00010000 then
+ fontdata.maximumprofile = {
+ version = version,
+ nofglyphs = nofglyphs,
+ points = readushort(f),
+ contours = readushort(f),
+ compositepoints = readushort(f),
+ compositecontours = readushort(f),
+ zones = readushort(f),
+ twilightpoints = readushort(f),
+ storage = readushort(f),
+ functiondefs = readushort(f),
+ instructiondefs = readushort(f),
+ stackelements = readushort(f),
+ sizeofinstructions = readushort(f),
+ componentelements = readushort(f),
+ componentdepth = readushort(f),
+ }
+ else
+ fontdata.maximumprofile = {
+ version = version,
+ nofglyphs = 0,
+ }
+ end
+ end
+end
+
+-- Here we filter the (advance) widths (that can be different from the boundingbox width of
+-- course).
+
+readers.hmtx = function(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"hmtx",specification.glyphs)
+ if tableoffset then
+ local horizontalheader = fontdata.horizontalheader
+ local nofmetrics = horizontalheader.nofmetrics
+ local glyphs = fontdata.glyphs
+ local nofglyphs = fontdata.nofglyphs
+ local width = 0 -- advance
+ local leftsidebearing = 0
+ for i=0,nofmetrics-1 do
+ local glyph = glyphs[i]
+ width = readshort(f) -- readushort
+ leftsidebearing = readshort(f)
+ if width ~= 0 then
+ glyph.width = width
+ end
+ -- if leftsidebearing ~= 0 then
+ -- glyph.lsb = leftsidebearing
+ -- end
+ end
+ -- The next can happen in for instance a monospace font or in a cjk font
+ -- with fixed widths.
+ for i=nofmetrics,nofglyphs-1 do
+ local glyph = glyphs[i]
+ if width ~= 0 then
+ glyph.width = width
+ end
+ -- if leftsidebearing ~= 0 then
+ -- glyph.lsb = leftsidebearing
+ -- end
+ end
+ end
+end
+
+readers.vmtx = function(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"vmtx",specification.glyphs)
+ if tableoffset then
+ local verticalheader = fontdata.verticalheader
+ local nofmetrics = verticalheader.nofmetrics
+ local glyphs = fontdata.glyphs
+ local nofglyphs = fontdata.nofglyphs
+ local vheight = 0
+ local vdefault = verticalheader.ascender - verticalheader.descender
+ local topsidebearing = 0
+ for i=0,nofmetrics-1 do
+ local glyph = glyphs[i]
+ vheight = readushort(f)
+ topsidebearing = readshort(f)
+ if vheight ~= 0 and vheight ~= vdefault then
+ glyph.vheight = vheight
+ end
+ if topsidebearing ~= 0 then
+ glyph.tsb = topsidebearing
+ end
+ end
+ -- The next can happen in for instance a monospace font or in a cjk font
+ -- with fixed heights.
+ for i=nofmetrics,nofglyphs-1 do
+ local glyph = glyphs[i]
+ if vheight ~= 0 and vheight ~= vdefault then
+ glyph.vheight = vheight
+ end
+ end
+ end
+end
+
+readers.vorg = function(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"vorg",specification.glyphs)
+end
+
+-- The post table relates to postscript (printing) but has some relevant properties for other
+-- usage as well. We just use the names from the microsoft specification. The version 2.0
+-- description is somewhat fuzzy but it is a hybrid with overloads.
+
+readers.post = function(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"post",true)
+ if tableoffset then
+ local version = readulong(f)
+ fontdata.postscript = {
+ version = version,
+ italicangle = round(1000*readfixed(f))/1000,
+ underlineposition = readfword(f),
+ underlinethickness = readfword(f),
+ monospaced = readulong(f),
+ minmemtype42 = readulong(f),
+ maxmemtype42 = readulong(f),
+ minmemtype1 = readulong(f),
+ maxmemtype1 = readulong(f),
+ }
+ if not specification.glyphs then
+ -- enough done
+ elseif version == 0x00010000 then
+ -- mac encoding (258 glyphs)
+ for index=0,#standardromanencoding do
+ glyphs[index].name = standardromanencoding[index]
+ end
+ elseif version == 0x00020000 then
+ local glyphs = fontdata.glyphs
+ local nofglyphs = readushort(f)
+ local indices = { }
+ local names = { }
+ local maxnames = 0
+ for i=0,nofglyphs-1 do
+ local nameindex = readushort(f)
+ if nameindex >= 258 then
+ maxnames = maxnames + 1
+ nameindex = nameindex - 257
+ indices[nameindex] = i
+ else
+ glyphs[i].name = standardromanencoding[nameindex]
+ end
+ end
+ for i=1,maxnames do
+ local mapping = indices[i]
+ if not mapping then
+ report("quit post name fetching at %a of %a: %s",i,maxnames,"no index")
+ break
+ else
+ local length = readbyte(f)
+ if length > 0 then
+ glyphs[mapping].name = readstring(f,length)
+ else
+ report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow")
+ break
+ end
+ end
+ end
+ end
+ else
+ fontdata.postscript = { }
+ end
+end
+
+readers.cff = function(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cff",specification.glyphs)
+end
+
+-- Not all cmaps make sense .. e.g. dfont is obsolete and probably more are not relevant. Let's see
+-- what we run into. There is some weird calculation going on here because we offset in a table
+-- being a blob of memory or file. Anyway, I can't stand lunatic formats like this esp when there
+-- is no real gain.
+
+local formatreaders = { }
+local duplicatestoo = true
+
+local sequence = {
+ -- these is some provision against redundant loading
+ { 3, 1, 4 },
+ { 3, 10, 12 },
+ { 0, 3, 4 },
+ { 0, 3, 12 },
+ { 0, 1, 4 },
+ { 0, 1, 12 }, -- for some old mac fonts
+ { 0, 0, 6 },
+ { 3, 0, 6 },
+ { 3, 0, 4 }, -- for (likely) old crap
+ -- variants
+ { 0, 5, 14 },
+ -- last resort ranges
+ { 0, 4, 12 },
+ { 3, 10, 13 },
+}
+
+local supported = { }
+
+for i=1,#sequence do
+ local si = sequence[i]
+ local sp, se, sf = si[1], si[2], si[3]
+ local p = supported[sp]
+ if not p then
+ p = { }
+ supported[sp] = p
+ end
+ local e = p[se]
+ if not e then
+ e = { }
+ p[se] = e
+ end
+ e[sf] = true
+end
+
+formatreaders[4] = function(f,fontdata,offset)
+ setposition(f,offset+2) -- skip format
+ --
+ local length = readushort(f) -- in bytes of subtable
+ local language = readushort(f)
+ local nofsegments = readushort(f) / 2
+ --
+ skipshort(f,3) -- searchrange entryselector rangeshift
+ --
+ local mapping = fontdata.mapping
+ local glyphs = fontdata.glyphs
+ local duplicates = fontdata.duplicates
+ local nofdone = 0
+ local endchars = readcardinaltable(f,nofsegments,ushort)
+ local reserved = readushort(f) -- 0
+ local startchars = readcardinaltable(f,nofsegments,ushort)
+ local deltas = readcardinaltable(f,nofsegments,ushort)
+ local offsets = readcardinaltable(f,nofsegments,ushort)
+ -- format length language nofsegments searchrange entryselector rangeshift 4-tables
+ local size = (length - 2 * 2 - 5 * 2 - 4 * 2 * nofsegments) / 2
+ local indices = readcardinaltable(f,size-1,ushort)
+ --
+ for segment=1,nofsegments do
+ local startchar = startchars[segment]
+ local endchar = endchars[segment]
+ local offset = offsets[segment]
+ local delta = deltas[segment]
+ if startchar == 0xFFFF and endchar == 0xFFFF then
+ -- break
+ elseif startchar == 0xFFFF and offset == 0 then
+ -- break
+ elseif offset == 0xFFFF then
+ -- bad encoding
+ elseif offset == 0 then
+ if trace_cmap_details then
+ report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar + delta) % 65536)
+ end
+ for unicode=startchar,endchar do
+ local index = (unicode + delta) % 65536
+ if index and index > 0 then
+ local glyph = glyphs[index]
+ if glyph then
+ local gu = glyph.unicode
+ if not gu then
+ glyph.unicode = unicode
+ nofdone = nofdone + 1
+ elseif gu ~= unicode then
+ if duplicatestoo then
+ local d = duplicates[gu]
+ if d then
+ d[unicode] = true
+ else
+ duplicates[gu] = { [unicode] = true }
+ end
+ else
+ -- no duplicates ... weird side effects in lm
+ report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name)
+ end
+ end
+ if not mapping[index] then
+ mapping[index] = unicode
+ end
+ end
+ end
+ end
+ else
+ local shift = (segment-nofsegments+offset/2) - startchar
+ if trace_cmap_details then
+ report_cmap("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar + delta) % 65536)
+ end
+ for unicode=startchar,endchar do
+ local slot = shift + unicode
+ local index = indices[slot]
+ if index and index > 0 then
+ index = (index + delta) % 65536
+ local glyph = glyphs[index]
+ if glyph then
+ local gu = glyph.unicode
+ if not gu then
+ glyph.unicode = unicode
+ nofdone = nofdone + 1
+ elseif gu ~= unicode then
+ if duplicatestoo then
+ local d = duplicates[gu]
+ if d then
+ d[unicode] = true
+ else
+ duplicates[gu] = { [unicode] = true }
+ end
+ else
+ -- no duplicates ... weird side effects in lm
+ report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name)
+ end
+ end
+ if not mapping[index] then
+ mapping[index] = unicode
+ end
+ end
+ end
+ end
+ end
+ end
+ return nofdone
+end
+
+formatreaders[6] = function(f,fontdata,offset)
+ setposition(f,offset) -- + 2 + 2 + 2 -- skip format length language
+ local format = readushort(f)
+ local length = readushort(f)
+ local language = readushort(f)
+ local mapping = fontdata.mapping
+ local glyphs = fontdata.glyphs
+ local duplicates = fontdata.duplicates
+ local start = readushort(f)
+ local count = readushort(f)
+ local stop = start+count-1
+ local nofdone = 0
+ if trace_cmap_details then
+ report_cmap("format 6 from %C to %C",2,start,stop)
+ end
+ for unicode=start,stop do
+ local index = readushort(f)
+ if index > 0 then
+ local glyph = glyphs[index]
+ if glyph then
+ local gu = glyph.unicode
+ if not gu then
+ glyph.unicode = unicode
+ nofdone = nofdone + 1
+ elseif gu ~= unicode then
+ -- report("format 6 overloading %C to %C",gu,unicode)
+ -- glyph.unicode = unicode
+ -- no duplicates ... weird side effects in lm
+ end
+ if not mapping[index] then
+ mapping[index] = unicode
+ end
+ end
+ end
+ end
+ return nofdone
+end
+
+formatreaders[12] = function(f,fontdata,offset)
+ setposition(f,offset+2+2+4+4) -- skip format reserved length language
+ local mapping = fontdata.mapping
+ local glyphs = fontdata.glyphs
+ local duplicates = fontdata.duplicates
+ local nofgroups = readulong(f)
+ local nofdone = 0
+ for i=1,nofgroups do
+ local first = readulong(f)
+ local last = readulong(f)
+ local index = readulong(f)
+ if trace_cmap_details then
+ report_cmap("format 12 from %C to %C starts at index %i",first,last,index)
+ end
+ for unicode=first,last do
+ local glyph = glyphs[index]
+ if glyph then
+ local gu = glyph.unicode
+ if not gu then
+ glyph.unicode = unicode
+ nofdone = nofdone + 1
+ elseif gu ~= unicode then
+ -- e.g. sourcehan fonts need this
+ local d = duplicates[gu]
+ if d then
+ d[unicode] = true
+ else
+ duplicates[gu] = { [unicode] = true }
+ end
+ end
+ if not mapping[index] then
+ mapping[index] = unicode
+ end
+ end
+ index = index + 1
+ end
+ end
+ return nofdone
+end
+
+formatreaders[13] = function(f,fontdata,offset)
+ --
+ -- this vector is only used for simple fallback fonts
+ --
+ setposition(f,offset+2+2+4+4) -- skip format reserved length language
+ local mapping = fontdata.mapping
+ local glyphs = fontdata.glyphs
+ local duplicates = fontdata.duplicates
+ local nofgroups = readulong(f)
+ local nofdone = 0
+ for i=1,nofgroups do
+ local first = readulong(f)
+ local last = readulong(f)
+ local index = readulong(f)
+ if first < privateoffset then
+ if trace_cmap_details then
+ report_cmap("format 13 from %C to %C get index %i",first,last,index)
+ end
+ local glyph = glyphs[index]
+ local unicode = glyph.unicode
+ if not unicode then
+ unicode = first
+ glyph.unicode = unicode
+ first = first + 1
+ end
+ local list = duplicates[unicode]
+ mapping[index] = unicode
+ if not list then
+ list = { }
+ duplicates[unicode] = list
+ end
+ if last >= privateoffset then
+ local limit = privateoffset - 1
+ report("format 13 from %C to %C pruned to %C",first,last,limit)
+ last = limit
+ end
+ for unicode=first,last do
+ list[unicode] = true
+ end
+ nofdone = nofdone + last - first + 1
+ else
+ report("format 13 from %C to %C ignored",first,last)
+ end
+ end
+ return nofdone
+end
+
+formatreaders[14] = function(f,fontdata,offset)
+ if offset and offset ~= 0 then
+ setposition(f,offset)
+ local format = readushort(f)
+ local length = readulong(f)
+ local nofrecords = readulong(f)
+ local records = { }
+ local variants = { }
+ local nofdone = 0
+ fontdata.variants = variants
+ for i=1,nofrecords do
+ records[i] = {
+ selector = readuint(f),
+ default = readulong(f), -- default offset
+ other = readulong(f), -- non-default offset
+ }
+ end
+ for i=1,nofrecords do
+ local record = records[i]
+ local selector = record.selector
+ local default = record.default
+ local other = record.other
+ --
+ -- there is no need to map the defaults to themselves
+ --
+ -- if default ~= 0 then
+ -- setposition(f,offset+default)
+ -- local nofranges = readulong(f)
+ -- for i=1,nofranges do
+ -- local start = readuint(f)
+ -- local extra = readbyte(f)
+ -- for i=start,start+extra do
+ -- mapping[i] = i
+ -- end
+ -- end
+ -- end
+ local other = record.other
+ if other ~= 0 then
+ setposition(f,offset+other)
+ local mapping = { }
+ local count = readulong(f)
+ for i=1,count do
+ mapping[readuint(f)] = readushort(f)
+ end
+ nofdone = nofdone + count
+ variants[selector] = mapping
+ end
+ end
+ return nofdone
+ else
+ return 0
+ end
+end
+
+local function checkcmap(f,fontdata,records,platform,encoding,format)
+ local pdata = records[platform]
+ if not pdata then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","no platform",platform,encoding,format)
+ end
+ return 0
+ end
+ local edata = pdata[encoding]
+ if not edata then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","no encoding",platform,encoding,format)
+ end
+ return 0
+ end
+ local fdata = edata[format]
+ if not fdata then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","no format",platform,encoding,format)
+ end
+ return 0
+ elseif type(fdata) ~= "number" then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","already done",platform,encoding,format)
+ end
+ return 0
+ end
+ edata[format] = true -- done
+ local reader = formatreaders[format]
+ if not reader then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","unsupported format",platform,encoding,format)
+ end
+ return 0
+ end
+ local n = reader(f,fontdata,fdata) or 0
+ if trace_cmap_details or trace_cmap then
+ local p = platforms[platform]
+ local e = encodings[p]
+ report_cmap("checked, platform %i (%s), encoding %i (%s), format %i, new unicodes %i",
+ platform,p,encoding,e and e[encoding] or "?",format,n)
+ end
+ return n
+end
+
+function readers.cmap(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"cmap",specification.glyphs)
+ if tableoffset then
+ local version = readushort(f)
+ local noftables = readushort(f)
+ local records = { }
+ local unicodecid = false
+ local variantcid = false
+ local variants = { }
+ local duplicates = fontdata.duplicates or { }
+ fontdata.duplicates = duplicates
+ for i=1,noftables do
+ local platform = readushort(f)
+ local encoding = readushort(f)
+ local offset = readulong(f)
+ local record = records[platform]
+ if not record then
+ records[platform] = {
+ [encoding] = {
+ offsets = { offset },
+ formats = { },
+ }
+ }
+ else
+ local subtables = record[encoding]
+ if not subtables then
+ record[encoding] = {
+ offsets = { offset },
+ formats = { },
+ }
+ else
+ local offsets = subtables.offsets
+ offsets[#offsets+1] = offset
+ end
+ end
+ end
+ if trace_cmap then
+ report("found cmaps:")
+ end
+ for platform, record in sortedhash(records) do
+ local p = platforms[platform]
+ local e = encodings[p]
+ local sp = supported[platform]
+ local ps = p or "?"
+ if trace_cmap then
+ if sp then
+ report(" platform %i: %s",platform,ps)
+ else
+ report(" platform %i: %s (unsupported)",platform,ps)
+ end
+ end
+ for encoding, subtables in sortedhash(record) do
+ local se = sp and sp[encoding]
+ local es = e and e[encoding] or "?"
+ if trace_cmap then
+ if se then
+ report(" encoding %i: %s",encoding,es)
+ else
+ report(" encoding %i: %s (unsupported)",encoding,es)
+ end
+ end
+ local offsets = subtables.offsets
+ local formats = subtables.formats
+ for i=1,#offsets do
+ local offset = tableoffset + offsets[i]
+ setposition(f,offset)
+ formats[readushort(f)] = offset
+ end
+ record[encoding] = formats
+ if trace_cmap then
+ local list = sortedkeys(formats)
+ for i=1,#list do
+ if not (se and se[list[i]]) then
+ list[i] = list[i] .. " (unsupported)"
+ end
+ end
+ report(" formats: % t",list)
+ end
+ end
+ end
+ --
+ local ok = false
+ for i=1,#sequence do
+ local si = sequence[i]
+ local sp, se, sf = si[1], si[2], si[3]
+ if checkcmap(f,fontdata,records,sp,se,sf) > 0 then
+ ok = true
+ end
+ end
+ if not ok then
+ report("no useable unicode cmap found")
+ end
+ --
+ fontdata.cidmaps = {
+ version = version,
+ noftables = noftables,
+ records = records,
+ }
+ else
+ fontdata.cidmaps = { }
+ end
+end
+
+-- The glyf table depends on the loca table. We have one entry to much in the locations table (the
+-- last one is a dummy) because we need to calculate the size of a glyph blob from the delta,
+-- although we not need it in our usage (yet). We can remove the locations table when we're done.
+
+function readers.loca(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"loca",specification.glyphs)
+end
+
+function readers.glyf(f,fontdata,specification) -- part goes to cff module
+ reportskippedtable(f,fontdata,"glyf",specification.glyphs)
+end
+
+-- The MicroSoft variant is pretty clean and is supported (implemented elsewhere)
+-- just because I wanted to see how such a font looks like.
+
+function readers.colr(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"colr",specification.glyphs)
+end
+function readers.cpal(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cpal",specification.glyphs)
+end
+
+-- This one is also supported, if only because I could locate a proper font for
+-- testing.
+
+function readers.svg(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"svg",specification.glyphs)
+end
+
+-- There is a font from apple to test the next one. Will there be more? Anyhow,
+-- it's relatively easy to support, so I did it.
+
+function readers.sbix(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"sbix",specification.glyphs)
+end
+
+-- I'm only willing to look into the next variant if I see a decent and complete (!)
+-- font and more can show up. It makes no sense to waste time on ideas. Okay, the
+-- apple font also has these tables.
+
+function readers.cbdt(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cbdt",specification.glyphs)
+end
+function readers.cblc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cblc",specification.glyphs)
+end
+function readers.ebdt(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"ebdt",specification.glyphs)
+end
+function readers.ebsc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"ebsc",specification.glyphs)
+end
+function readers.eblc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"eblc",specification.glyphs)
+end
+
+-- Here we have a table that we really need for later processing although a more advanced gpos table
+-- can also be available. Todo: we need a 'fake' lookup for this (analogue to ff).
+
+function readers.kern(f,fontdata,specification)
+ local tableoffset = gotodatatable(f,fontdata,"kern",specification.kerns)
+ if tableoffset then
+ local version = readushort(f)
+ local noftables = readushort(f)
+ for i=1,noftables do
+ local version = readushort(f)
+ local length = readushort(f)
+ local coverage = readushort(f)
+ -- bit 8-15 of coverage: format 0 or 2
+ local format = rshift(coverage,8) -- is this ok?
+ if format == 0 then
+ local nofpairs = readushort(f)
+ local searchrange = readushort(f)
+ local entryselector = readushort(f)
+ local rangeshift = readushort(f)
+ local kerns = { }
+ local glyphs = fontdata.glyphs
+ for i=1,nofpairs do
+ local left = readushort(f)
+ local right = readushort(f)
+ local kern = readfword(f)
+ local glyph = glyphs[left]
+ local kerns = glyph.kerns
+ if kerns then
+ kerns[right] = kern
+ else
+ glyph.kerns = { [right] = kern }
+ end
+ end
+ elseif format == 2 then
+ report("todo: kern classes")
+ else
+ report("todo: kerns")
+ end
+ end
+ end
+end
+
+function readers.gdef(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"gdef",specification.details)
+end
+
+function readers.gsub(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"gsub",specification.details)
+end
+
+function readers.gpos(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"gpos",specification.details)
+end
+
+function readers.math(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"math",specification.details)
+end
+
+-- Now comes the loader. The order of reading these matters as we need to know
+-- some properties in order to read following tables. When details is true we also
+-- initialize the glyphs data.
+
+local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames)
+ local fontdata = sub and maindata.subfonts and maindata.subfonts[sub] or maindata
+ local names = fontdata.names
+ local info = nil
+ if names then
+ local metrics = fontdata.windowsmetrics or { }
+ local postscript = fontdata.postscript or { }
+ local fontheader = fontdata.fontheader or { }
+ local cffinfo = fontdata.cffinfo or { }
+ local verticalheader = fontdata.verticalheader or { }
+ local filename = fontdata.filename
+ local weight = getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight)
+ local width = getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width )
+ local fontname = getname(fontdata,"postscriptname")
+ local fullname = getname(fontdata,"fullname")
+ local family = getname(fontdata,"family")
+ local subfamily = getname(fontdata,"subfamily")
+ local familyname = getname(fontdata,"typographicfamily")
+ local subfamilyname = getname(fontdata,"typographicsubfamily")
+ local compatiblename = getname(fontdata,"compatiblefullname") -- kind of useless
+ if rawfamilynames then
+ -- for PG (for now, as i need to check / adapt context to catch a no-fallback case)
+ else
+ if not familyname then familyname = family end
+ if not subfamilyname then subfamilyname = subfamily end
+ end
+ if platformnames then
+ platformnames = fontdata.platformnames
+ end
+ if instancenames then
+ local variabledata = fontdata.variabledata
+ if variabledata then
+ local instances = variabledata and variabledata.instances
+ if instances then
+ instancenames = { }
+ for i=1,#instances do
+ instancenames[i] = lower(stripstring(instances[i].subfamily))
+ end
+ else
+ instancenames = nil
+ end
+ else
+ instancenames = nil
+ end
+ end
+ info = { -- we inherit some inconsistencies/choices from ff
+ subfontindex = fontdata.subfontindex or sub or 0,
+ -- filename = filename,
+ version = getname(fontdata,"version"),
+ -- format = fontdata.format,
+ fontname = fontname,
+ fullname = fullname,
+ -- cfffullname = cff.fullname,
+ family = family,
+ subfamily = subfamily,
+ familyname = familyname,
+ subfamilyname = subfamilyname,
+ compatiblename = compatiblename,
+ weight = weight and lower(weight),
+ width = width and lower(width),
+ pfmweight = metrics.weightclass or 400, -- will become weightclass
+ pfmwidth = metrics.widthclass or 5, -- will become widthclass
+ panosewidth = metrics.panosewidth,
+ panoseweight = metrics.panoseweight,
+ italicangle = postscript.italicangle or 0,
+ units = fontheader.units or 0,
+ designsize = fontdata.designsize,
+ minsize = fontdata.minsize,
+ maxsize = fontdata.maxsize,
+ boundingbox = fontheader and { fontheader.xmin or 0, fontheader.ymin or 0, fontheader.xmax or 0, fontheader.ymax or 0 } or nil,
+ monospaced = (tonumber(postscript.monospaced or 0) > 0) or metrics.panosewidth == "monospaced",
+ averagewidth = metrics.averagewidth,
+ xheight = metrics.xheight, -- can be missing
+ capheight = metrics.capheight or fontdata.maxy, -- can be missing
+ ascender = metrics.typoascender,
+ descender = metrics.typodescender,
+ platformnames = platformnames or nil,
+ instancenames = instancenames or nil,
+ tableoffsets = fontdata.tableoffsets,
+ defaultvheight = (verticalheader.ascender or 0) - (verticalheader.descender or 0)
+ }
+ if metricstoo then
+ local keys = {
+ "version",
+ "ascender", "descender", "linegap",
+ -- "caretoffset", "caretsloperise", "caretsloperun",
+ "maxadvancewidth", "maxadvanceheight", "maxextent",
+ -- "metricdataformat",
+ "minbottomsidebearing", "mintopsidebearing",
+ }
+ local h = fontdata.horizontalheader or { }
+ local v = fontdata.verticalheader or { }
+ if h then
+ local th = { }
+ local tv = { }
+ for i=1,#keys do
+ local key = keys[i]
+ th[key] = h[key] or 0
+ tv[key] = v[key] or 0
+ end
+ info.horizontalmetrics = th
+ info.verticalmetrics = tv
+ end
+ end
+ elseif n then
+ info = {
+ filename = fontdata.filename,
+ comment = "there is no info for subfont " .. n,
+ }
+ else
+ info = {
+ filename = fontdata.filename,
+ comment = "there is no info",
+ }
+ end
+ -- inspect(info)
+ return info
+end
+
+local function loadtables(f,specification,offset)
+ if offset then
+ setposition(f,offset)
+ end
+ local tables = { }
+ local basename = file.basename(specification.filename)
+ local filesize = specification.filesize
+ local filetime = specification.filetime
+ local fontdata = { -- some can/will go
+ filename = basename,
+ filesize = filesize,
+ filetime = filetime,
+ version = readstring(f,4),
+ noftables = readushort(f),
+ searchrange = readushort(f), -- not needed
+ entryselector = readushort(f), -- not needed
+ rangeshift = readushort(f), -- not needed
+ tables = tables,
+ foundtables = false,
+ }
+ for i=1,fontdata.noftables do
+ local tag = lower(stripstring(readstring(f,4)))
+ -- local checksum = readulong(f) -- not used
+ local checksum = readushort(f) * 0x10000 + readushort(f)
+ local offset = readulong(f)
+ local length = readulong(f)
+ if offset + length > filesize then
+ report("bad %a table in file %a",tag,basename)
+ end
+ tables[tag] = {
+ checksum = checksum,
+ offset = offset,
+ length = length,
+ }
+ end
+-- inspect(tables)
+ fontdata.foundtables = sortedkeys(tables)
+ if tables.cff or tables.cff2 then
+ fontdata.format = "opentype"
+ else
+ fontdata.format = "truetype"
+ end
+ return fontdata, tables
+end
+
+local function prepareglyps(fontdata)
+ local glyphs = setmetatableindex(function(t,k)
+ local v = {
+ -- maybe more defaults
+ index = k,
+ }
+ t[k] = v
+ return v
+ end)
+ fontdata.glyphs = glyphs
+ fontdata.mapping = { }
+end
+
+local function readtable(tag,f,fontdata,specification,...)
+ local reader = readers[tag]
+ if reader then
+ reader(f,fontdata,specification,...)
+ end
+end
+
+local variablefonts_supported = (context and true) or (logs and logs.application and true) or false
+
+local function readdata(f,offset,specification)
+
+ local fontdata, tables = loadtables(f,specification,offset)
+
+ if specification.glyphs then
+ prepareglyps(fontdata)
+ end
+
+ if not variablefonts_supported then
+ specification.instance = nil
+ specification.variable = nil
+ specification.factors = nil
+ end
+
+ fontdata.temporary = { }
+
+ readtable("name",f,fontdata,specification)
+
+ local askedname = specification.askedname
+ if askedname then
+ local fullname = getname(fontdata,"fullname") or ""
+ local cleanname = gsub(askedname,"[^a-zA-Z0-9]","")
+ local foundname = gsub(fullname,"[^a-zA-Z0-9]","")
+ if lower(cleanname) ~= lower(foundname) then
+ return -- keep searching
+ end
+ end
+
+ readtable("stat",f,fontdata,specification)
+ readtable("avar",f,fontdata,specification)
+ readtable("fvar",f,fontdata,specification)
+
+ if variablefonts_supported then
+
+ local variabledata = fontdata.variabledata
+
+ if variabledata then
+ local instances = variabledata.instances
+ local axis = variabledata.axis
+ if axis and (not instances or #instances == 0) then
+ instances = { }
+ variabledata.instances = instances
+ local function add(n,subfamily,value)
+ local values = { }
+ for i=1,#axis do
+ local a = axis[i]
+ values[i] = {
+ axis = a.tag,
+ value = i == n and value or a.default,
+ }
+ end
+ instances[#instances+1] = {
+ subfamily = subfamily,
+ values = values,
+ }
+ end
+ for i=1,#axis do
+ local a = axis[i]
+ local tag = a.tag
+ add(i,"default"..tag,a.default)
+ add(i,"minimum"..tag,a.minimum)
+ add(i,"maximum"..tag,a.maximum)
+ end
+ -- report("%i fake instances added",#instances)
+ end
+ end
+
+ if not specification.factors then
+ local instance = specification.instance
+ if type(instance) == "string" then
+ local factors = helpers.getfactors(fontdata,instance)
+ 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)
+ if factors then
+ specification.factors = factors
+ fontdata.factors = factors
+ -- report("factors: % t",factors)
+ -- else
+ -- report("bad factors")
+ end
+ else
+ -- report("unknown instance")
+ end
+ end
+
+ end
+
+ readtable("os/2",f,fontdata,specification)
+ readtable("head",f,fontdata,specification)
+ readtable("maxp",f,fontdata,specification)
+ readtable("hhea",f,fontdata,specification)
+ readtable("vhea",f,fontdata,specification)
+ readtable("hmtx",f,fontdata,specification)
+ readtable("vmtx",f,fontdata,specification)
+ readtable("vorg",f,fontdata,specification)
+ readtable("post",f,fontdata,specification)
+
+ readtable("mvar",f,fontdata,specification)
+ readtable("hvar",f,fontdata,specification)
+ readtable("vvar",f,fontdata,specification)
+
+ readtable("gdef",f,fontdata,specification)
+
+ readtable("cff" ,f,fontdata,specification)
+ readtable("cff2",f,fontdata,specification)
+
+ readtable("cmap",f,fontdata,specification)
+ readtable("loca",f,fontdata,specification) -- maybe load it in glyf
+ readtable("glyf",f,fontdata,specification) -- loads gvar
+
+ readtable("colr",f,fontdata,specification)
+ readtable("cpal",f,fontdata,specification)
+
+ readtable("svg" ,f,fontdata,specification)
+
+ readtable("sbix",f,fontdata,specification)
+
+ readtable("cbdt",f,fontdata,specification)
+ readtable("cblc",f,fontdata,specification)
+ readtable("ebdt",f,fontdata,specification)
+ readtable("eblc",f,fontdata,specification)
+
+ readtable("kern",f,fontdata,specification)
+ readtable("gsub",f,fontdata,specification)
+ readtable("gpos",f,fontdata,specification)
+
+ readtable("math",f,fontdata,specification)
+
+ fontdata.locations = nil
+ fontdata.cidmaps = nil
+ fontdata.dictionaries = nil
+ -- fontdata.cff = nil
+
+ if specification.tableoffsets then
+ fontdata.tableoffsets = tables
+ setmetatableindex(tables, {
+ version = fontdata.version,
+ noftables = fontdata.noftables,
+ searchrange = fontdata.searchrange,
+ entryselector = fontdata.entryselector,
+ rangeshift = fontdata.rangeshift,
+ })
+ end
+ return fontdata
+end
+
+local function loadfontdata(specification)
+ local filename = specification.filename
+ local fileattr = lfs.attributes(filename)
+ local filesize = fileattr and fileattr.size or 0
+ local filetime = fileattr and fileattr.modification or 0
+ local f = openfile(filename,true) -- zero based
+ if not f then
+ report("unable to open %a",filename)
+ elseif filesize == 0 then
+ report("empty file %a",filename)
+ closefile(f)
+ else
+ specification.filesize = filesize
+ specification.filetime = filetime
+ local version = readstring(f,4)
+ local fontdata = nil
+ if version == "OTTO" or version == "true" or version == "\0\1\0\0" then
+ fontdata = readdata(f,0,specification)
+ elseif version == "ttcf" then
+ local subfont = tonumber(specification.subfont)
+ local ttcversion = readulong(f)
+ local nofsubfonts = readulong(f)
+ local offsets = readcardinaltable(f,nofsubfonts,ulong)
+ if subfont then -- a number of not
+ if subfont >= 1 and subfont <= nofsubfonts then
+ fontdata = readdata(f,offsets[subfont],specification)
+ else
+ report("no subfont %a in file %a",subfont,filename)
+ end
+ else
+ subfont = specification.subfont
+ if type(subfont) == "string" and subfont ~= "" then
+ specification.askedname = subfont
+ for i=1,nofsubfonts do
+ fontdata = readdata(f,offsets[i],specification)
+ if fontdata then
+ fontdata.subfontindex = i
+ report("subfont named %a has index %a",subfont,i)
+ break
+ end
+ end
+ if not fontdata then
+ report("no subfont named %a",subfont)
+ end
+ else
+ local subfonts = { }
+ fontdata = {
+ filename = filename,
+ filesize = filesize,
+ filetime = filetime,
+ version = version,
+ subfonts = subfonts,
+ ttcversion = ttcversion,
+ nofsubfonts = nofsubfonts,
+ }
+ for i=1,nofsubfonts do
+ subfonts[i] = readdata(f,offsets[i],specification)
+ end
+ end
+ end
+ else
+ report("unknown version %a in file %a",version,filename)
+ end
+ closefile(f)
+ return fontdata or { }
+ end
+end
+
+local function loadfont(specification,n,instance)
+ if type(specification) == "string" then
+ specification = {
+ filename = specification,
+ info = true, -- always true (for now)
+ details = true,
+ glyphs = true,
+ shapes = true,
+ kerns = true,
+ variable = true,
+ globalkerns = true,
+ lookups = true,
+ -- true or number:
+ subfont = n or true,
+ tounicode = false,
+ instance = instance
+ }
+ end
+ -- if shapes only then
+ if specification.shapes or specification.lookups or specification.kerns then
+ specification.glyphs = true
+ end
+ if specification.glyphs then
+ specification.details = true
+ end
+ if specification.details then
+ specification.info = true -- not really used any more
+ end
+ if specification.platformnames then
+ specification.platformnames = true -- not really used any more
+ end
+ if specification.instance or instance then
+ specification.variable = true
+ specification.instance = specification.instance or instance
+ end
+ local function message(str)
+ report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback())
+ end
+ local ok, result = xpcall(loadfontdata,message,specification)
+ if ok then
+ return result
+ end
+-- return loadfontdata(specification)
+end
+
+-- we need even less, but we can have a 'detail' variant
+
+function readers.loadshapes(filename,n,instance,streams)
+ local fontdata = loadfont {
+ filename = filename,
+ shapes = true,
+ streams = streams,
+ variable = true,
+ subfont = n,
+ instance = instance,
+ }
+ if fontdata then
+ -- easier on luajit but still we can hit the 64 K stack constants issue
+ for k, v in next, fontdata.glyphs do
+ v.class = nil
+ v.index = nil
+ v.math = nil
+ -- v.name = nil
+ end
+ local names = fontdata.names
+ if names then
+ for k, v in next, names do
+ names[k] = fullstrip(v.content)
+ end
+ end
+ end
+ return fontdata and {
+ -- version = 0.123 -- todo
+ filename = filename,
+ format = fontdata.format,
+ glyphs = fontdata.glyphs,
+ units = fontdata.fontheader.units,
+ cffinfo = fontdata.cffinfo,
+ fontheader = fontdata.fontheader,
+ horizontalheader = fontdata.horizontalheader,
+ verticalheader = fontdata.verticalheader,
+ maximumprofile = fontdata.maximumprofile,
+ names = fontdata.names,
+ postscript = fontdata.postscript,
+ } or {
+ filename = filename,
+ format = "unknown",
+ glyphs = { },
+ units = 0,
+ }
+end
+
+function readers.loadfont(filename,n,instance)
+ local fontdata = loadfont {
+ filename = filename,
+ glyphs = true,
+ shapes = false,
+ lookups = true,
+ variable = true,
+ -- kerns = true,
+ -- globalkerns = true, -- only for testing, e.g. cambria has different gpos and kern
+ subfont = n,
+ instance = instance,
+ }
+ if fontdata then
+ return {
+ tableversion = tableversion,
+ creator = "context mkiv",
+ size = fontdata.filesize,
+ time = fontdata.filetime,
+ glyphs = fontdata.glyphs,
+ descriptions = fontdata.descriptions,
+ format = fontdata.format,
+ goodies = { },
+ metadata = getinfo(fontdata,n,false,false,true,true), -- no platformnames here !
+ properties = {
+ hasitalics = fontdata.hasitalics or false,
+ maxcolorclass = fontdata.maxcolorclass,
+ hascolor = fontdata.hascolor or false,
+ instance = fontdata.instance,
+ factors = fontdata.factors,
+ },
+ resources = {
+ -- filename = fontdata.filename,
+ filename = filename,
+ private = privateoffset,
+ duplicates = fontdata.duplicates or { },
+ features = fontdata.features or { }, -- we need to add these in the loader
+ sublookups = fontdata.sublookups or { }, -- we need to add these in the loader
+ marks = fontdata.marks or { }, -- we need to add these in the loader
+ markclasses = fontdata.markclasses or { }, -- we need to add these in the loader
+ marksets = fontdata.marksets or { }, -- we need to add these in the loader
+ sequences = fontdata.sequences or { }, -- we need to add these in the loader
+ variants = fontdata.variants, -- variant -> unicode -> glyph
+ version = getname(fontdata,"version"),
+ cidinfo = fontdata.cidinfo,
+ mathconstants = fontdata.mathconstants,
+ colorpalettes = fontdata.colorpalettes,
+ svgshapes = fontdata.svgshapes,
+ pngshapes = fontdata.pngshapes,
+ variabledata = fontdata.variabledata,
+ foundtables = fontdata.foundtables,
+ },
+ }
+ end
+end
+
+function readers.getinfo(filename,specification) -- string, nil|number|table
+ -- platformnames is optional and not used by context (a too unpredictable mess
+ -- that only add to the confusion) .. so it's only for checking things
+ local subfont = nil
+ local platformnames = false
+ local rawfamilynames = false
+ local instancenames = true
+ local tableoffsets = false
+ if type(specification) == "table" then
+ subfont = tonumber(specification.subfont)
+ platformnames = specification.platformnames
+ rawfamilynames = specification.rawfamilynames
+ tableoffsets = specification.tableoffsets
+ else
+ subfont = tonumber(specification)
+ end
+ local fontdata = loadfont {
+ filename = filename,
+ details = true,
+ platformnames = platformnames,
+ instancenames = true,
+ tableoffsets = tableoffsets,
+ -- rawfamilynames = rawfamilynames,
+ }
+ if fontdata then
+ local subfonts = fontdata.subfonts
+ if not subfonts then
+ return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames)
+ elseif not subfont then
+ local info = { }
+ for i=1,#subfonts do
+ info[i] = getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames)
+ end
+ return info
+ elseif subfont >= 1 and subfont <= #subfonts then
+ return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames)
+ else
+ return {
+ filename = filename,
+ comment = "there is no subfont " .. subfont .. " in this file"
+ }
+ end
+ else
+ return {
+ filename = filename,
+ comment = "the file cannot be opened for reading",
+ }
+ end
+end
+
+function readers.rehash(fontdata,hashmethod)
+ report("the %a helper is not yet implemented","rehash")
+end
+
+function readers.checkhash(fontdata)
+ report("the %a helper is not yet implemented","checkhash")
+end
+
+function readers.pack(fontdata,hashmethod)
+ report("the %a helper is not yet implemented","pack")
+end
+
+function readers.unpack(fontdata)
+ report("the %a helper is not yet implemented","unpack")
+end
+
+function readers.expand(fontdata)
+ report("the %a helper is not yet implemented","unpack")
+end
+
+function readers.compact(fontdata)
+ report("the %a helper is not yet implemented","compact")
+end
+
+-- plug in
+
+local extenders = { }
+
+function readers.registerextender(extender)
+ extenders[#extenders+1] = extender
+end
+
+function readers.extend(fontdata)
+ for i=1,#extenders do
+ local extender = extenders[i]
+ local name = extender.name or "unknown"
+ local action = extender.action
+ if action then
+ action(fontdata)
+ end
+ end
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
new file mode 100644
index 0000000000..6313022006
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
@@ -0,0 +1,4492 @@
+if not modules then modules = { } end modules ['font-ots'] = { -- sequences
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+--[[ldx--
+<p>This module is a bit more split up that I'd like but since we also want to test
+with plain <l n='tex'/> it has to be so. This module is part of <l n='context'/>
+and discussion about improvements and functionality mostly happens on the
+<l n='context'/> mailing list.</p>
+
+<p>The specification of OpenType is (or at least a decade ago was) kind of vague.
+Apart from a lack of a proper free specifications there's also the problem that
+Microsoft and Adobe may have their own interpretation of how and in what order to
+apply features. In general the Microsoft website has more detailed specifications
+and is a better reference. There is also some information in the FontForge help
+files. In the end we rely most on the Microsoft specification.</p>
+
+<p>Because there is so much possible, fonts might contain bugs and/or be made to
+work with certain rederers. These may evolve over time which may have the side
+effect that suddenly fonts behave differently. We don't want to catch all font
+issues.</p>
+
+<p>After a lot of experiments (mostly by Taco, me and Idris) the first implementation
+becaus quite useful. When it did most of what we wanted, a more optimized version
+evolved. Of course all errors are mine and of course the code can be improved. There
+are quite some optimizations going on here and processing speed is currently quite
+acceptable and has been improved over time. Many complex scripts are not yet supported
+yet, but I will look into them as soon as <l n='context'/> users ask for it.</p>
+
+<p>The specification leaves room for interpretation. In case of doubt the Microsoft
+implementation is the reference as it is the most complete one. As they deal with
+lots of scripts and fonts, Kai and Ivo did a lot of testing of the generic code and
+their suggestions help improve the code. I'm aware that not all border cases can be
+taken care of, unless we accept excessive runtime, and even then the interference
+with other mechanisms (like hyphenation) are not trivial.</p>
+
+<p>Especially discretionary handling has been improved much by Kai Eigner who uses complex
+(latin) fonts. The current implementation is a compromis between his patches and my code
+and in the meantime performance is quite ok. We cannot check all border cases without
+compromising speed but so far we're okay. Given good test cases we can probably improve
+it here and there. Especially chain lookups are non trivial with discretionaries but
+things got much better over time thanks to Kai.</p>
+
+<p>Glyphs are indexed not by unicode but in their own way. This is because there is no
+relationship with unicode at all, apart from the fact that a font might cover certain
+ranges of characters. One character can have multiple shapes. However, at the
+<l n='tex'/> end we use unicode so and all extra glyphs are mapped into a private
+space. This is needed because we need to access them and <l n='tex'/> has to include
+then in the output eventually.</p>
+
+<p>The initial data table is rather close to the open type specification and also not
+that different from the one produced by <l n='fontforge'/> but we uses hashes instead.
+In <l n='context'/> that table is packed (similar tables are shared) and cached on disk
+so that successive runs can use the optimized table (after loading the table is
+unpacked).</p>
+
+<p>This module is sparsely documented because it is has been a moving target. The
+table format of the reader changed a bit over time and we experiment a lot with
+different methods for supporting features. By now the structures are quite stable</p>
+
+<p>Incrementing the version number will force a re-cache. We jump the number by one
+when there's a fix in the reader or processing code that can result in different
+results.</p>
+
+<p>This code is also used outside context but in context it has to work with other
+mechanisms. Both put some constraints on the code here.</p>
+
+--ldx]]--
+
+-- Remark: We assume that cursives don't cross discretionaries which is okay because it
+-- is only used in semitic scripts.
+--
+-- Remark: We assume that marks precede base characters.
+--
+-- Remark: When complex ligatures extend into discs nodes we can get side effects. Normally
+-- this doesn't happen; ff\d{l}{l}{l} in lm works but ff\d{f}{f}{f}.
+--
+-- Todo: check if we copy attributes to disc nodes if needed.
+--
+-- Todo: it would be nice if we could get rid of components. In other places we can use
+-- the unicode properties. We can just keep a lua table.
+--
+-- Remark: We do some disc juggling where we need to keep in mind that the pre, post and
+-- replace fields can have prev pointers to a nesting node ... I wonder if that is still
+-- needed.
+--
+-- Remark: This is not possible:
+--
+-- \discretionary {alpha-} {betagammadelta}
+-- {\discretionary {alphabeta-} {gammadelta}
+-- {\discretionary {alphabetagamma-} {delta}
+-- {alphabetagammadelta}}}
+--
+-- Remark: Something is messed up: we have two mark / ligature indices, one at the
+-- injection end and one here ... this is based on KE's patches but there is something
+-- fishy there as I'm pretty sure that for husayni we need some connection (as it's much
+-- more complex than an average font) but I need proper examples of all cases, not of
+-- only some.
+--
+-- Remark: I wonder if indexed would be faster than unicoded. It would be a major
+-- rewrite to have char being unicode + an index field in glyph nodes. Also more
+-- assignments have to be made in order to keep things in sync. So, it's a no-go.
+--
+-- Remark: We can provide a fast loop when there are no disc nodes (tests show a 1%
+-- gain). Smaller functions might perform better cache-wise. But ... memory becomes
+-- faster anyway, so ...
+--
+-- Remark: Some optimizations made sense for 5.2 but seem less important for 5.3 but
+-- anyway served their purpose.
+--
+-- Todo: just (0=l2r and 1=r2l) or maybe (r2l = true)
+
+local type, next, tonumber = type, next, tonumber
+local random = math.random
+local formatters = string.formatters
+local insert = table.insert
+
+local registertracker = trackers.register
+
+local logs = logs
+local trackers = trackers
+local nodes = nodes
+local attributes = attributes
+local fonts = fonts
+
+local otf = fonts.handlers.otf
+local tracers = nodes.tracers
+
+local trace_singles = false registertracker("otf.singles", function(v) trace_singles = v end)
+local trace_multiples = false registertracker("otf.multiples", function(v) trace_multiples = v end)
+local trace_alternatives = false registertracker("otf.alternatives", function(v) trace_alternatives = v end)
+local trace_ligatures = false registertracker("otf.ligatures", function(v) trace_ligatures = v end)
+local trace_contexts = false registertracker("otf.contexts", function(v) trace_contexts = v end)
+local trace_marks = false registertracker("otf.marks", function(v) trace_marks = v end)
+local trace_kerns = false registertracker("otf.kerns", function(v) trace_kerns = v end)
+local trace_cursive = false registertracker("otf.cursive", function(v) trace_cursive = v end)
+local trace_preparing = false registertracker("otf.preparing", function(v) trace_preparing = v end)
+local trace_bugs = false registertracker("otf.bugs", function(v) trace_bugs = v end)
+local trace_details = false registertracker("otf.details", function(v) trace_details = v end)
+local trace_steps = false registertracker("otf.steps", function(v) trace_steps = v end)
+local trace_skips = false registertracker("otf.skips", function(v) trace_skips = v end)
+local trace_plugins = false registertracker("otf.plugins", function(v) trace_plugins = v end)
+local trace_chains = false registertracker("otf.chains", function(v) trace_chains = v end)
+
+local trace_kernruns = false registertracker("otf.kernruns", function(v) trace_kernruns = v end)
+----- trace_discruns = false registertracker("otf.discruns", function(v) trace_discruns = v end)
+local trace_compruns = false registertracker("otf.compruns", function(v) trace_compruns = v end)
+local trace_testruns = false registertracker("otf.testruns", function(v) trace_testruns = v end)
+
+local forcediscretionaries = false
+local forcepairadvance = false -- for testing
+
+directives.register("otf.forcediscretionaries",function(v)
+ forcediscretionaries = v
+end)
+
+directives.register("otf.forcepairadvance",function(v)
+ forcepairadvance = v
+end)
+
+local report_direct = logs.reporter("fonts","otf direct")
+local report_subchain = logs.reporter("fonts","otf subchain")
+local report_chain = logs.reporter("fonts","otf chain")
+local report_process = logs.reporter("fonts","otf process")
+local report_warning = logs.reporter("fonts","otf warning")
+local report_run = logs.reporter("fonts","otf run")
+
+registertracker("otf.substitutions", "otf.singles","otf.multiples","otf.alternatives","otf.ligatures")
+registertracker("otf.positions", "otf.marks","otf.kerns","otf.cursive")
+registertracker("otf.actions", "otf.substitutions","otf.positions")
+registertracker("otf.sample", "otf.steps","otf.substitutions","otf.positions","otf.analyzing")
+registertracker("otf.sample.silent", "otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing")
+
+local nuts = nodes.nuts
+
+local getfield = nuts.getfield
+local getnext = nuts.getnext
+local setnext = nuts.setnext
+local getprev = nuts.getprev
+local setprev = nuts.setprev
+local getboth = nuts.getboth
+local setboth = nuts.setboth
+local getid = nuts.getid
+local getprop = nuts.getprop
+local setprop = nuts.setprop
+local getsubtype = nuts.getsubtype
+local setsubtype = nuts.setsubtype
+local getchar = nuts.getchar
+local setchar = nuts.setchar
+local getdisc = nuts.getdisc
+local setdisc = nuts.setdisc
+local setlink = nuts.setlink
+local getcomponents = nuts.getcomponents -- the original one, not yet node-aux
+local setcomponents = nuts.setcomponents -- the original one, not yet node-aux
+local getwidth = nuts.getwidth
+local getattr = nuts.getattr
+
+local getglyphdata = nuts.getglyphdata
+
+local ischar = nuts.ischar
+local isglyph = nuts.isglyph
+local usesfont = nuts.uses_font
+
+local insert_node_after = nuts.insert_after
+local copy_node = nuts.copy
+local copy_node_list = nuts.copy_list
+local remove_node = nuts.remove
+local find_node_tail = nuts.tail
+local flush_node_list = nuts.flush_list
+local flush_node = nuts.flush_node
+local end_of_math = nuts.end_of_math
+
+local setmetatable = setmetatable
+local setmetatableindex = table.setmetatableindex
+
+local nextnode = nuts.traversers.node
+
+----- zwnj = 0x200C
+----- zwj = 0x200D
+
+local nodecodes = nodes.nodecodes
+local glyphcodes = nodes.glyphcodes
+local disccodes = nodes.disccodes
+
+local glyph_code = nodecodes.glyph
+local glue_code = nodecodes.glue
+local disc_code = nodecodes.disc
+local math_code = nodecodes.math
+local dir_code = nodecodes.dir
+local localpar_code = nodecodes.localpar
+
+local discretionarydisc_code = disccodes.discretionary
+local ligatureglyph_code = glyphcodes.ligature
+
+local a_state = attributes.private('state')
+local a_noligature = attributes.private("noligature")
+
+local injections = nodes.injections
+local setmark = injections.setmark
+local setcursive = injections.setcursive
+local setkern = injections.setkern
+local setmove = injections.setmove
+local setposition = injections.setposition
+local resetinjection = injections.reset
+local copyinjection = injections.copy
+local setligaindex = injections.setligaindex
+local getligaindex = injections.getligaindex
+
+local fontdata = fonts.hashes.identifiers
+local fontfeatures = fonts.hashes.features
+
+local otffeatures = fonts.constructors.features.otf
+local registerotffeature = otffeatures.register
+
+local onetimemessage = fonts.loggers.onetimemessage or function() end
+
+local getrandom = utilities and utilities.randomizer and utilities.randomizer.get
+
+otf.defaultnodealternate = "none" -- first last
+
+-- We use a few semi-global variables. The handler can be called nested but this assumes
+-- that the same font is used.
+
+local tfmdata = false
+local characters = false
+local descriptions = false
+local marks = false
+local classes = false
+local currentfont = false
+local factor = 0
+local threshold = 0
+local checkmarks = false
+
+local discs = false
+local spaces = false
+
+local sweepnode = nil
+local sweephead = { } -- we don't nil entries but false them (no collection and such)
+
+local notmatchpre = { } -- to be checked: can we use false instead of nil / what if a == b tests
+local notmatchpost = { } -- to be checked: can we use false instead of nil / what if a == b tests
+local notmatchreplace = { } -- to be checked: can we use false instead of nil / what if a == b tests
+
+local handlers = { }
+
+local isspace = injections.isspace
+local getthreshold = injections.getthreshold
+
+local checkstep = (tracers and tracers.steppers.check) or function() end
+local registerstep = (tracers and tracers.steppers.register) or function() end
+local registermessage = (tracers and tracers.steppers.message) or function() end
+
+-- local function checkdisccontent(d)
+-- local pre, post, replace = getdisc(d)
+-- if pre then for n in traverse_id(glue_code,pre) do report("pre: %s",nodes.idstostring(pre)) break end end
+-- if post then for n in traverse_id(glue_code,post) do report("pos: %s",nodes.idstostring(post)) break end end
+-- if replace then for n in traverse_id(glue_code,replace) do report("rep: %s",nodes.idstostring(replace)) break end end
+-- end
+
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ if trace_steps == "silent" then
+ return
+ end
+ end
+ report_direct(...)
+end
+
+local function logwarning(...)
+ report_direct(...)
+end
+
+local gref do
+
+ local f_unicode = formatters["U+%X"] -- was ["%U"]
+ local f_uniname = formatters["U+%X (%s)"] -- was ["%U (%s)"]
+ local f_unilist = formatters["% t"]
+
+ gref = function(n) -- currently the same as in font-otb
+ if type(n) == "number" then
+ local description = descriptions[n]
+ local name = description and description.name
+ if name then
+ return f_uniname(n,name)
+ else
+ return f_unicode(n)
+ end
+ elseif n then
+ local t = { }
+ for i=1,#n do
+ local ni = n[i]
+ if tonumber(ni) then -- later we will start at 2
+ local di = descriptions[ni]
+ local nn = di and di.name
+ if nn then
+ t[#t+1] = f_uniname(ni,nn)
+ else
+ t[#t+1] = f_unicode(ni)
+ end
+ end
+ end
+ return f_unilist(t)
+ else
+ return "<error in node mode tracing>"
+ end
+ end
+
+end
+
+local function cref(dataset,sequence,index)
+ if not dataset then
+ return "no valid dataset"
+ end
+ local merged = sequence.merged and "merged " or ""
+ if index then
+ return formatters["feature %a, type %a, %schain lookup %a, index %a"](
+ dataset[4],sequence.type,merged,sequence.name,index)
+ else
+ return formatters["feature %a, type %a, %schain lookup %a"](
+ dataset[4],sequence.type,merged,sequence.name)
+ end
+end
+
+local function pref(dataset,sequence)
+ return formatters["feature %a, type %a, %slookup %a"](
+ dataset[4],sequence.type,sequence.merged and "merged " or "",sequence.name)
+end
+
+local function mref(rlmode)
+ if not rlmode or rlmode >= 0 then
+ return "l2r"
+ else
+ return "r2l"
+ end
+end
+
+-- The next code is somewhat complicated by the fact that some fonts can have ligatures made
+-- from ligatures that themselves have marks. This was identified by Kai in for instance
+-- arabtype: KAF LAM SHADDA ALEF FATHA (0x0643 0x0644 0x0651 0x0627 0x064E). This becomes
+-- KAF LAM-ALEF with a SHADDA on the first and a FATHA op de second component. In a next
+-- iteration this becomes a KAF-LAM-ALEF with a SHADDA on the second and a FATHA on the
+-- third component.
+
+-- We can assume that languages that use marks are not hyphenated. We can also assume
+-- that at most one discretionary is present.
+
+-- We do need components in funny kerning mode but maybe I can better reconstruct then
+-- as we do have the font components info available; removing components makes the
+-- previous code much simpler. Also, later on copying and freeing becomes easier.
+-- However, for arabic we need to keep them around for the sake of mark placement
+-- and indices.
+
+local function flattendisk(head,disc)
+ local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true)
+ local prev, next = getboth(disc)
+ local ishead = head == disc
+ setdisc(disc)
+ flush_node(disc)
+ if pre then
+ flush_node_list(pre)
+ end
+ if post then
+ flush_node_list(post)
+ end
+ if ishead then
+ if replace then
+ if next then
+ setlink(replacetail,next)
+ end
+ return replace, replace
+ elseif next then
+ return next, next
+ else
+ -- return -- maybe warning
+ end
+ else
+ if replace then
+ if next then
+ setlink(replacetail,next)
+ end
+ setlink(prev,replace)
+ return head, replace
+ else
+ setlink(prev,next) -- checks for next anyway
+ return head, next
+ end
+ end
+end
+
+local function appenddisc(disc,list)
+ local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true)
+ local posthead = list
+ local replacehead = copy_node_list(list)
+ if post then
+ setlink(posttail,posthead)
+ else
+ post = posthead
+ end
+ if replace then
+ setlink(replacetail,replacehead)
+ else
+ replace = replacehead
+ end
+ setdisc(disc,pre,post,replace)
+end
+
+-- start is a mark and we need to keep that one
+
+local copy_no_components = nuts.copy_no_components
+local copy_only_glyphs = nuts.copy_only_glyphs
+
+local set_components = setcomponents
+local take_components = getcomponents
+
+local function count_components(start,marks)
+ local char = isglyph(start)
+ if char then
+ if getsubtype(start) == ligatureglyph_code then
+ local i = 0
+ local components = getcomponents(start)
+ while components do
+ i = i + count_components(components,marks)
+ components = getnext(components)
+ end
+ return i
+ elseif not marks[char] then
+ return 1
+ end
+ end
+ return 0
+end
+
+local function markstoligature(head,start,stop,char)
+ if start == stop and getchar(start) == char then
+ return head, start
+ else
+ local prev = getprev(start)
+ local next = getnext(stop)
+ setprev(start)
+ setnext(stop)
+ local base = copy_no_components(start,copyinjection)
+ if head == start then
+ head = base
+ end
+ resetinjection(base)
+ setchar(base,char)
+ setsubtype(base,ligatureglyph_code)
+ set_components(base,start)
+ setlink(prev,base,next)
+ return head, base
+ end
+end
+
+-- Remark for Kai: (some arabic fonts do mark + mark = other mark and such)
+--
+-- The hasmarks is needed for ligatures of marks that are part of a ligature in
+-- which case we assume that we can delete the marks anyway (we can always become
+-- more clever if needed) .. in fact the whole logic here should be redone. We're
+-- in the not discfound branch then. We now have skiphash too so we can be more
+-- selective if needed (todo).
+
+local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) -- brr head
+ if getattr(start,a_noligature) == 1 then
+ -- so we can do: e\noligature{ff}e e\noligature{f}fie (we only look at the first)
+ return head, start
+ end
+ if start == stop and getchar(start) == char then
+ resetinjection(start)
+ setchar(start,char)
+ return head, start
+ end
+ local prev = getprev(start)
+ local next = getnext(stop)
+ local comp = start
+ setprev(start)
+ setnext(stop)
+ local base = copy_no_components(start,copyinjection)
+ if start == head then
+ head = base
+ end
+ resetinjection(base)
+ setchar(base,char)
+ setsubtype(base,ligatureglyph_code)
+ set_components(base,comp)
+ setlink(prev,base,next)
+ if not discfound then
+ local deletemarks = not skiphash or hasmarks
+ local components = start
+ local baseindex = 0
+ local componentindex = 0
+ local head = base
+ local current = base
+ -- first we loop over the glyphs in start ... stop
+ while start do
+ local char = getchar(start)
+ if not marks[char] then
+ baseindex = baseindex + componentindex
+ componentindex = count_components(start,marks)
+ -- we can be more clever here: "not deletemarks or (skiphash and not skiphash[char])"
+ -- and such:
+ elseif not deletemarks then
+ -- we can get a loop when the font expects otherwise (i.e. unexpected deletemarks)
+ setligaindex(start,baseindex + getligaindex(start,componentindex))
+ if trace_marks then
+ logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ end
+ local n = copy_node(start)
+ copyinjection(n,start) -- is this ok ? we position later anyway
+ head, current = insert_node_after(head,current,n) -- unlikely that mark has components
+ elseif trace_marks then
+ logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char))
+ end
+ start = getnext(start)
+ end
+ -- we can have one accent as part of a lookup and another following
+ local start = getnext(current)
+ while start do
+ local char = ischar(start)
+ if char then
+ -- also something skiphash here?
+ if marks[char] then
+ setligaindex(start,baseindex + getligaindex(start,componentindex))
+ if trace_marks then
+ logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ end
+ start = getnext(start)
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ else
+ -- discfound ... forget about marks .. probably no scripts that hyphenate and have marks
+ local discprev, discnext = getboth(discfound)
+ if discprev and discnext then
+ -- we assume normalization in context, and don't care about generic ... especially
+ -- \- can give problems as there we can have a negative char but that won't match
+ -- anyway
+ local pre, post, replace, pretail, posttail, replacetail = getdisc(discfound,true)
+ if not replace then
+ local prev = getprev(base)
+ local comp = take_components(base)
+ local copied = copy_only_glyphs(comp)
+ if pre then
+ setlink(discprev,pre)
+ else
+ setnext(discprev) -- also blocks funny assignments
+ end
+ pre = comp
+ if post then
+ setlink(posttail,discnext)
+ setprev(post)
+ else
+ post = discnext
+ setprev(discnext) -- also blocks funny assignments
+ end
+ setlink(prev,discfound,next)
+ setboth(base)
+ -- here components have a pointer so we can't free it!
+ set_components(base,copied)
+ replace = base
+ if forcediscretionaries then
+ setdisc(discfound,pre,post,replace,discretionarydisc_code)
+ else
+ setdisc(discfound,pre,post,replace)
+ end
+ base = prev
+ end
+ end
+ end
+ return head, base
+end
+
+local function multiple_glyphs(head,start,multiple,skiphash,what,stop) -- what to do with skiphash matches here
+ local nofmultiples = #multiple
+ if nofmultiples > 0 then
+ resetinjection(start)
+ setchar(start,multiple[1])
+ if nofmultiples > 1 then
+ local sn = getnext(start)
+ for k=2,nofmultiples do
+ -- untested:
+ --
+ -- while ignoremarks and marks[getchar(sn)] then
+ -- local sn = getnext(sn)
+ -- end
+ local n = copy_node(start) -- ignore components
+ resetinjection(n)
+ setchar(n,multiple[k])
+ insert_node_after(head,start,n)
+ start = n
+ end
+ if what == true then
+ -- we're ok
+ elseif what > 1 then
+ local m = multiple[nofmultiples]
+ for i=2,what do
+ local n = copy_node(start) -- ignore components
+ resetinjection(n)
+ setchar(n,m)
+ insert_node_after(head,start,n)
+ start = n
+ end
+ end
+ end
+ return head, start, true
+ else
+ if trace_multiples then
+ logprocess("no multiple for %s",gref(getchar(start)))
+ end
+ return head, start, false
+ end
+end
+
+local function get_alternative_glyph(start,alternatives,value)
+ local n = #alternatives
+ if n == 1 then
+ -- we could actually change that into a gsub and save some memory in the
+ -- font loader but it makes tracing more messy
+ return alternatives[1], trace_alternatives and "1 (only one present)"
+ elseif value == "random" then
+ local r = getrandom and getrandom("glyph",1,n) or random(1,n)
+ return alternatives[r], trace_alternatives and formatters["value %a, taking %a"](value,r)
+ elseif value == "first" then
+ return alternatives[1], trace_alternatives and formatters["value %a, taking %a"](value,1)
+ elseif value == "last" then
+ return alternatives[n], trace_alternatives and formatters["value %a, taking %a"](value,n)
+ end
+ value = value == true and 1 or tonumber(value)
+ if type(value) ~= "number" then
+ return alternatives[1], trace_alternatives and formatters["invalid value %s, taking %a"](value,1)
+ end
+ -- local a = alternatives[value]
+ -- if a then
+ -- -- some kind of hash
+ -- return a, trace_alternatives and formatters["value %a, taking %a"](value,a)
+ -- end
+ if value > n then
+ local defaultalt = otf.defaultnodealternate
+ if defaultalt == "first" then
+ return alternatives[n], trace_alternatives and formatters["invalid value %s, taking %a"](value,1)
+ elseif defaultalt == "last" then
+ return alternatives[1], trace_alternatives and formatters["invalid value %s, taking %a"](value,n)
+ else
+ return false, trace_alternatives and formatters["invalid value %a, %s"](value,"out of range")
+ end
+ elseif value == 0 then
+ return getchar(start), trace_alternatives and formatters["invalid value %a, %s"](value,"no change")
+ elseif value < 1 then
+ return alternatives[1], trace_alternatives and formatters["invalid value %a, taking %a"](value,1)
+ else
+ return alternatives[value], trace_alternatives and formatters["value %a, taking %a"](value,value)
+ end
+end
+
+-- handlers
+
+function handlers.gsub_single(head,start,dataset,sequence,replacement)
+ if trace_singles then
+ logprocess("%s: replacing %s by single %s",pref(dataset,sequence),gref(getchar(start)),gref(replacement))
+ end
+ resetinjection(start)
+ setchar(start,replacement)
+ return head, start, true
+end
+
+function handlers.gsub_alternate(head,start,dataset,sequence,alternative)
+ local kind = dataset[4]
+ local what = dataset[1]
+ local value = what == true and tfmdata.shared.features[kind] or what
+ local choice, comment = get_alternative_glyph(start,alternative,value)
+ if choice then
+ if trace_alternatives then
+ logprocess("%s: replacing %s by alternative %a to %s, %s",pref(dataset,sequence),gref(getchar(start)),gref(choice),comment)
+ end
+ resetinjection(start)
+ setchar(start,choice)
+ else
+ if trace_alternatives then
+ logwarning("%s: no variant %a for %s, %s",pref(dataset,sequence),value,gref(getchar(start)),comment)
+ end
+ end
+ return head, start, true
+end
+
+function handlers.gsub_multiple(head,start,dataset,sequence,multiple,rlmode,skiphash)
+ if trace_multiples then
+ logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple))
+ end
+ return multiple_glyphs(head,start,multiple,skiphash,dataset[1])
+end
+
+-- Don't we deal with disc otherwise now? I need to check if the next one can be
+-- simplified. Anyway, it can be way messier: marks that get removed as well as
+-- marks that are kept.
+
+function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skiphash)
+ local current = getnext(start)
+ if not current then
+ return head, start, false, nil
+ end
+ local stop = nil
+ local startchar = getchar(start)
+ if skiphash and skiphash[startchar] then
+ while current do
+ local char = ischar(current,currentfont)
+ if char then
+ local lg = ligature[char]
+ if lg then
+ stop = current
+ ligature = lg
+ current = getnext(current)
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if stop then
+ local lig = ligature.ligature
+ if lig then
+ if trace_ligatures then
+ local stopchar = getchar(stop)
+ head, start = markstoligature(head,start,stop,lig)
+ logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start)))
+ else
+ head, start = markstoligature(head,start,stop,lig)
+ end
+ return head, start, true, false
+ else
+ -- ok, goto next lookup
+ end
+ end
+ else
+ local discfound = false
+ local hasmarks = marks[startchar]
+ while current do
+ local char, id = ischar(current,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ current = getnext(current)
+ else
+ local lg = ligature[char]
+ if lg then
+ if marks[char] then
+ hasmarks = true
+ end
+ stop = current -- needed for fake so outside then
+ ligature = lg
+ current = getnext(current)
+ else
+ break
+ end
+ end
+ elseif char == false then
+ -- kind of weird
+ break
+ elseif id == disc_code then
+ discfound = current
+ break
+ else
+ break
+ end
+ end
+ -- of{f-}{}{f}e o{f-}{}{f}fe o{-}{}{ff}e (oe and ff ligature)
+ -- we can end up here when we have a start run .. testruns start at a disc but
+ -- so here we have the other case: char + disc
+ if discfound then
+ -- don't assume marks in a disc and we don't run over a disc (for now)
+ local pre, post, replace = getdisc(discfound)
+ local match
+ if replace then
+ local char = ischar(replace,currentfont)
+ if char and ligature[char] then
+ match = true
+ end
+ end
+ if not match and pre then
+ local char = ischar(pre,currentfont)
+ if char and ligature[char] then
+ match = true
+ end
+ end
+ if not match and not pre or not replace then
+ local n = getnext(discfound)
+ local char = ischar(n,currentfont)
+ if char and ligature[char] then
+ match = true
+ end
+ end
+ if match then
+ -- we force a restart
+ local ishead = head == start
+ local prev = getprev(start)
+ if stop then
+ setnext(stop)
+ local copy = copy_node_list(start)
+ local tail = stop -- was: getprev(stop) -- Kai: needs checking on your samples
+ local liat = find_node_tail(copy)
+ if pre then
+ setlink(liat,pre)
+ end
+ if replace then
+ setlink(tail,replace)
+ end
+ pre = copy
+ replace = start
+ else
+ setnext(start)
+ local copy = copy_node(start)
+ if pre then
+ setlink(copy,pre)
+ end
+ if replace then
+ setlink(start,replace)
+ end
+ pre = copy
+ replace = start
+ end
+ setdisc(discfound,pre,post,replace)
+ if prev then
+ setlink(prev,discfound)
+ else
+ setprev(discfound)
+ head = discfound
+ end
+ start = discfound
+ return head, start, true, true
+ end
+ end
+ local lig = ligature.ligature
+ if lig then
+ if stop then
+ if trace_ligatures then
+ local stopchar = getchar(stop)
+ -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks)
+ head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
+ logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig))
+ else
+ -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks)
+ head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
+ end
+ else
+ -- weird but happens (in some arabic font)
+ resetinjection(start)
+ setchar(start,lig)
+ if trace_ligatures then
+ logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig))
+ end
+ end
+ return head, start, true, false
+ else
+ -- weird but happens, pseudo ligatures ... just the components
+ end
+ end
+ return head, start, false, false
+end
+
+function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
+ local startchar = getchar(start)
+ local format = step.format
+ if format == "single" or type(kerns) == "table" then -- the table check can go
+ local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else
+ local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
+ end
+ end
+ return head, start, true
+end
+
+function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
+ local snext = getnext(start)
+ if not snext then
+ return head, start, false
+ else
+ local prev = start
+ while snext do
+ local nextchar = ischar(snext,currentfont)
+ if nextchar then
+ if skiphash and skiphash[nextchar] then -- includes marks too when flag
+ prev = snext
+ snext = getnext(snext)
+ else
+ local krn = kerns[nextchar]
+ if not krn then
+ break
+ end
+ local format = step.format
+ if format == "pair" then
+ local a = krn[1]
+ local b = krn[2]
+ if a == true then
+ -- zero
+ elseif a then -- #a > 0
+ local x, y, w, h = setposition(1,start,factor,rlmode,a,injection)
+ if trace_kerns then
+ local startchar = getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ end
+ if b == true then
+ -- zero
+ start = snext -- cf spec
+ elseif b then -- #b > 0
+ local x, y, w, h = setposition(2,snext,factor,rlmode,b,injection)
+ if trace_kerns then
+ local startchar = getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ start = snext -- cf spec
+ elseif forcepairadvance then
+ start = snext -- for testing, not cf spec
+ end
+ return head, start, true
+ elseif krn ~= 0 then
+ local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
+ if trace_kerns then
+ logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
+ end
+ return head, start, true
+ else -- can't happen
+ break
+ end
+ end
+ else
+ break
+ end
+ end
+ return head, start, false
+ end
+end
+
+--[[ldx--
+<p>We get hits on a mark, but we're not sure if the it has to be applied so
+we need to explicitly test for basechar, baselig and basemark entries.</p>
+--ldx]]--
+
+function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash)
+ local markchar = getchar(start)
+ if marks[markchar] then
+ local base = getprev(start) -- [glyph] [start=mark]
+ if base then
+ local basechar = ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base = getprev(base)
+ if base then
+ basechar = ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
+ end
+ return head, start, false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
+ end
+ return head, start, false
+ end
+ end
+ end
+ local ba = markanchors[1][basechar]
+ if ba then
+ local ma = markanchors[2]
+ local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)",
+ pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head, start, true
+ elseif trace_bugs then
+ -- onetimemessage(currentfont,basechar,"no base anchors",report_fonts)
+ logwarning("%s: mark %s is not anchored to %s",pref(dataset,sequence),gref(markchar),gref(basechar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
+ return head, start, false
+end
+
+function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlmode,skiphash)
+ local markchar = getchar(start)
+ if marks[markchar] then
+ local base = getprev(start) -- [glyph] [optional marks] [start=mark]
+ if base then
+ local basechar = ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base = getprev(base)
+ if base then
+ basechar = ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
+ end
+ return head, start, false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
+ end
+ return head, start, false
+ end
+ end
+ end
+ local ba = markanchors[1][basechar]
+ if ba then
+ local ma = markanchors[2]
+ if ma then
+ local index = getligaindex(start)
+ ba = ba[index]
+ if ba then
+ local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, index %s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)",
+ pref(dataset,sequence),index,bound,gref(markchar),gref(basechar),index,dx,dy)
+ end
+ return head, start, true
+ else
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(dataset,sequence),gref(markchar),gref(basechar),index)
+ end
+ end
+ end
+ elseif trace_bugs then
+ -- logwarning("%s: char %s is missing in font",pref(dataset,sequence),gref(basechar))
+ onetimemessage(currentfont,basechar,"no base anchors",report_fonts)
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
+ return head, start, false
+end
+
+function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode,skiphash)
+ local markchar = getchar(start)
+ if marks[markchar] then
+ local base = getprev(start) -- [glyph] [basemark] [start=mark]
+ local slc = getligaindex(start)
+ if slc then -- a rather messy loop ... needs checking with husayni
+ while base do
+ local blc = getligaindex(base)
+ if blc and blc ~= slc then
+ base = getprev(base)
+ else
+ break
+ end
+ end
+ end
+ if base then
+ local basechar = ischar(base,currentfont)
+ if basechar then -- subtype test can go
+ local ba = markanchors[1][basechar] -- slot 1 has been made copy of the class hash
+ if ba then
+ local ma = markanchors[2]
+ local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)",
+ pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head, start, true
+ end
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
+ return head, start, false
+end
+
+function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,skiphash,step) -- to be checked
+ local startchar = getchar(start)
+ if marks[startchar] then
+ if trace_cursive then
+ logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar))
+ end
+ else
+ local nxt = getnext(start)
+ while nxt do
+ local nextchar = ischar(nxt,currentfont)
+ if not nextchar then
+ break
+ elseif marks[nextchar] then -- always sequence.flags[1]
+ nxt = getnext(nxt)
+ else
+ local exit = exitanchors[3]
+ if exit then
+ local entry = exitanchors[1][nextchar]
+ if entry then
+ entry = entry[2]
+ if entry then
+ local r2lflag = sequence.flags[4] -- mentioned in the standard
+ local dx, dy, bound = setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag)
+ if trace_cursive then
+ logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode))
+ end
+ return head, start, true
+ end
+ end
+ end
+ break
+ end
+ end
+ end
+ return head, start, false
+end
+
+--[[ldx--
+<p>I will implement multiple chain replacements once I run into a font that uses
+it. It's not that complex to handle.</p>
+--ldx]]--
+
+local chainprocs = { }
+
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ if trace_steps == "silent" then
+ return
+ end
+ end
+ report_subchain(...)
+end
+
+local logwarning = report_subchain
+
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ if trace_steps == "silent" then
+ return
+ end
+ end
+ report_chain(...)
+end
+
+local logwarning = report_chain
+
+-- We could share functions but that would lead to extra function calls with many
+-- arguments, redundant tests and confusing messages.
+
+-- The reversesub is a special case, which is why we need to store the replacements
+-- in a bit weird way. There is no lookup and the replacement comes from the lookup
+-- itself. It is meant mostly for dealing with Urdu.
+
+local function reversesub(head,start,stop,dataset,sequence,replacements,rlmode,skiphash)
+ local char = getchar(start)
+ local replacement = replacements[char]
+ if replacement then
+ if trace_singles then
+ logprocess("%s: single reverse replacement of %s by %s",cref(dataset,sequence),gref(char),gref(replacement))
+ end
+ resetinjection(start)
+ setchar(start,replacement)
+ return head, start, true
+ else
+ return head, start, false
+ end
+end
+
+
+chainprocs.reversesub = reversesub
+
+--[[ldx--
+<p>This chain stuff is somewhat tricky since we can have a sequence of actions to be
+applied: single, alternate, multiple or ligature where ligature can be an invalid
+one in the sense that it will replace multiple by one but not neccessary one that
+looks like the combination (i.e. it is the counterpart of multiple then). For
+example, the following is valid:</p>
+
+<typing>
+<line>xxxabcdexxx [single a->A][multiple b->BCD][ligature cde->E] xxxABCDExxx</line>
+</typing>
+
+<p>Therefore we we don't really do the replacement here already unless we have the
+single lookup case. The efficiency of the replacements can be improved by deleting
+as less as needed but that would also make the code even more messy.</p>
+--ldx]]--
+
+--[[ldx--
+<p>Here we replace start by a single variant.</p>
+--ldx]]--
+
+-- To be done (example needed): what if > 1 steps
+
+-- this is messy: do we need this disc checking also in alternaties?
+
+local function reportzerosteps(dataset,sequence)
+ logwarning("%s: no steps",cref(dataset,sequence))
+end
+
+local function reportmoresteps(dataset,sequence)
+ logwarning("%s: more than 1 step",cref(dataset,sequence))
+end
+
+-- local function reportbadsteps(dataset,sequence)
+-- logwarning("%s: bad step, no proper return values",cref(dataset,sequence))
+-- end
+
+local function getmapping(dataset,sequence,currentlookup)
+ local steps = currentlookup.steps
+ local nofsteps = currentlookup.nofsteps
+ if nofsteps == 0 then
+ reportzerosteps(dataset,sequence)
+ currentlookup.mapping = false
+ return false
+ else
+ if nofsteps > 1 then
+ reportmoresteps(dataset,sequence)
+ end
+ local mapping = steps[1].coverage
+ currentlookup.mapping = mapping
+ currentlookup.format = steps[1].format
+ return mapping
+ end
+end
+
+function chainprocs.gsub_remove(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ if trace_chains then
+ logprocess("%s: removing character %s",cref(dataset,sequence,chainindex),gref(getchar(start)))
+ end
+ head, start = remove_node(head,start,true)
+ return head, getprev(start), true
+end
+
+function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local current = start
+ while current do
+ local currentchar = ischar(current)
+ if currentchar then
+ local replacement = mapping[currentchar]
+ if not replacement or replacement == "" then
+ if trace_bugs then
+ logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar))
+ end
+ else
+ if trace_singles then
+ logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement))
+ end
+ resetinjection(current)
+ setchar(current,replacement)
+ end
+ return head, start, true
+ elseif currentchar == false then
+ -- can't happen
+ break
+ elseif current == stop then
+ break
+ else
+ current = getnext(current)
+ end
+ end
+ end
+ return head, start, false
+end
+
+--[[ldx--
+<p>Here we replace start by new glyph. First we delete the rest of the match.</p>
+--ldx]]--
+
+-- char_1 mark_1 -> char_x mark_1 (ignore marks)
+-- char_1 mark_1 -> char_x
+
+-- to be checked: do we always have just one glyph?
+-- we can also have alternates for marks
+-- marks come last anyway
+-- are there cases where we need to delete the mark
+
+function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local kind = dataset[4]
+ local what = dataset[1]
+ local value = what == true and tfmdata.shared.features[kind] or what -- todo: optimize in ctx
+ local current = start
+ while current do
+ local currentchar = ischar(current)
+ if currentchar then
+ local alternatives = mapping[currentchar]
+ if alternatives then
+ local choice, comment = get_alternative_glyph(current,alternatives,value)
+ if choice then
+ if trace_alternatives then
+ logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(currentchar),choice,gref(choice),comment)
+ end
+ resetinjection(start)
+ setchar(start,choice)
+ else
+ if trace_alternatives then
+ logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(currentchar),comment)
+ end
+ end
+ end
+ return head, start, true
+ elseif currentchar == false then
+ -- can't happen
+ break
+ elseif current == stop then
+ break
+ else
+ current = getnext(current)
+ end
+ end
+ end
+ return head, start, false
+end
+
+--[[ldx--
+<p>Here we replace start by a sequence of new glyphs.</p>
+--ldx]]--
+
+function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar = getchar(start)
+ local replacement = mapping[startchar]
+ if not replacement or replacement == "" then
+ if trace_bugs then
+ logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar))
+ end
+ else
+ if trace_multiples then
+ logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement))
+ end
+ return multiple_glyphs(head,start,replacement,skiphash,dataset[1],stop)
+ end
+ end
+ return head, start, false
+end
+
+--[[ldx--
+<p>When we replace ligatures we use a helper that handles the marks. I might change
+this function (move code inline and handle the marks by a separate function). We
+assume rather stupid ligatures (no complex disc nodes).</p>
+--ldx]]--
+
+-- compare to handlers.gsub_ligature which is more complex ... why
+
+function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar = getchar(start)
+ local ligatures = mapping[startchar]
+ if not ligatures then
+ if trace_bugs then
+ logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar))
+ end
+ else
+ local hasmarks = marks[startchar]
+ local current = getnext(start)
+ local discfound = false
+ local last = stop
+ local nofreplacements = 1
+ while current do
+ -- todo: ischar ... can there really be disc nodes here?
+ local id = getid(current)
+ if id == disc_code then
+ if not discfound then
+ discfound = current
+ end
+ if current == stop then
+ break -- okay? or before the disc
+ else
+ current = getnext(current)
+ end
+ else
+ local schar = getchar(current)
+ if skiphash and skiphash[schar] then -- marks
+ -- if current == stop then -- maybe add this
+ -- break
+ -- else
+ current = getnext(current)
+ -- end
+ else
+ local lg = ligatures[schar]
+ if lg then
+ ligatures = lg
+ last = current
+ nofreplacements = nofreplacements + 1
+ if marks[char] then
+ hasmarks = true
+ end
+ if current == stop then
+ break
+ else
+ current = getnext(current)
+ end
+ else
+ break
+ end
+ end
+ end
+ end
+ local ligature = ligatures.ligature
+ if ligature then
+ if chainindex then
+ stop = last
+ end
+ if trace_ligatures then
+ if start == stop then
+ logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature))
+ else
+ logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature))
+ end
+ end
+ head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks)
+ return head, start, true, nofreplacements, discfound
+ elseif trace_bugs then
+ if start == stop then
+ logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar))
+ else
+ logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)))
+ end
+ end
+ end
+ end
+ return head, start, false, 0, false
+end
+
+function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar = getchar(start)
+ local kerns = mapping[startchar]
+ if kerns then
+ local format = currentlookup.format
+ if format == "single" then
+ local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns) -- currentlookup.flags ?
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else -- needs checking .. maybe no kerns format for single
+ local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ end
+ end
+ return head, start, true
+ end
+ end
+ return head, start, false
+end
+
+function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) -- todo: injections ?
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local snext = getnext(start)
+ if snext then
+ local startchar = getchar(start)
+ local kerns = mapping[startchar] -- always 1 step
+ if kerns then
+ local prev = start
+ while snext do
+ local nextchar = ischar(snext,currentfont)
+ if not nextchar then
+ break
+ end
+ if skiphash and skiphash[nextchar] then
+ prev = snext
+ snext = getnext(snext)
+ else
+ local krn = kerns[nextchar]
+ if not krn then
+ break
+ end
+ local format = currentlookup.format
+ if format == "pair" then
+ local a = krn[1]
+ local b = krn[2]
+ if a == true then
+ -- zero
+ elseif a then
+ local x, y, w, h = setposition(1,start,factor,rlmode,a,"injections") -- currentlookups flags?
+ if trace_kerns then
+ local startchar = getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ if b == true then
+ -- zero
+ start = snext -- cf spec
+ elseif b then -- #b > 0
+ local x, y, w, h = setposition(2,snext,factor,rlmode,b,"injections")
+ if trace_kerns then
+ local startchar = getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ start = snext -- cf spec
+ elseif forcepairadvance then
+ start = snext -- for testing, not cf spec
+ end
+ return head, start, true
+ elseif krn ~= 0 then
+ local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn)
+ if trace_kerns then
+ logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
+ end
+ return head, start, true
+ else
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ return head, start, false
+end
+
+function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local markchar = getchar(start)
+ if marks[markchar] then
+ local markanchors = mapping[markchar] -- always 1 step
+ if markanchors then
+ local base = getprev(start) -- [glyph] [start=mark]
+ if base then
+ local basechar = ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base = getprev(base)
+ if base then
+ local basechar = ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
+ end
+ return head, start, false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
+ end
+ return head, start, false
+ end
+ end
+ end
+ local ba = markanchors[1][basechar]
+ if ba then
+ local ma = markanchors[2]
+ if ma then
+ local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)",
+ cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head, start, true
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar))
+ end
+ end
+ return head, start, false
+end
+
+function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local markchar = getchar(start)
+ if marks[markchar] then
+ local markanchors = mapping[markchar] -- always 1 step
+ if markanchors then
+ local base = getprev(start) -- [glyph] [optional marks] [start=mark]
+ if base then
+ local basechar = ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base = getprev(base)
+ if base then
+ local basechar = ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1)
+ end
+ return head, start, false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2)
+ end
+ return head, start, false
+ end
+ end
+ end
+ local ba = markanchors[1][basechar]
+ if ba then
+ local ma = markanchors[2]
+ if ma then
+ local index = getligaindex(start)
+ ba = ba[index]
+ if ba then
+ local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)",
+ cref(dataset,sequence),a or bound,gref(markchar),gref(basechar),index,dx,dy)
+ end
+ return head, start, true
+ end
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar))
+ end
+ end
+ return head, start, false
+end
+
+function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local markchar = getchar(start)
+ if marks[markchar] then
+ local markanchors = mapping[markchar] -- always 1 step
+ if markanchors then
+ local base = getprev(start) -- [glyph] [basemark] [start=mark]
+ local slc = getligaindex(start)
+ if slc then -- a rather messy loop ... needs checking with husayni
+ while base do
+ local blc = getligaindex(base)
+ if blc and blc ~= slc then
+ base = getprev(base)
+ else
+ break
+ end
+ end
+ end
+ if base then -- subtype test can go
+ local basechar = ischar(base,currentfont)
+ if basechar then
+ local ba = markanchors[1][basechar]
+ if ba then
+ local ma = markanchors[2]
+ if ma then
+ local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)",
+ cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head, start, true
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar))
+ end
+ end
+ return head, start, false
+end
+
+function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar = getchar(start)
+ local exitanchors = mapping[startchar] -- always 1 step
+ if exitanchors then
+ if marks[startchar] then
+ if trace_cursive then
+ logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar))
+ end
+ else
+ local nxt = getnext(start)
+ while nxt do
+ local nextchar = ischar(nxt,currentfont)
+ if not nextchar then
+ break
+ elseif marks[nextchar] then
+ -- should not happen (maybe warning)
+ nxt = getnext(nxt)
+ else
+ local exit = exitanchors[3]
+ if exit then
+ local entry = exitanchors[1][nextchar]
+ if entry then
+ entry = entry[2]
+ if entry then
+ local r2lflag = sequence.flags[4] -- mentioned in the standard
+ local dx, dy, bound = setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag)
+ if trace_cursive then
+ logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode))
+ end
+ return head, start, true
+ end
+ end
+ elseif trace_bugs then
+ onetimemessage(currentfont,startchar,"no entry anchors",report_fonts)
+ end
+ break
+ end
+ end
+ end
+ elseif trace_cursive and trace_details then
+ logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone)
+ end
+ end
+ return head, start, false
+end
+
+-- what pointer to return, spec says stop
+-- to be discussed ... is bidi changer a space?
+-- elseif char == zwnj and sequence[n][32] then -- brrr
+
+local function show_skip(dataset,sequence,char,ck,class)
+ logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2])
+end
+
+-- A previous version had disc collapsing code in the (single sub) handler plus some
+-- checking in the main loop, but that left the pre/post sequences undone. The best
+-- solution is to add some checking there and backtrack when a replace/post matches
+-- but it takes a bit of work to figure out an efficient way (this is what the
+-- sweep* names refer to). I might look into that variant one day again as it can
+-- replace some other code too. In that approach we can have a special version for
+-- gub and pos which gains some speed. This method does the test and passes info to
+-- the handlers. Here collapsing is handled in the main loop which also makes code
+-- elsewhere simpler (i.e. no need for the other special runners and disc code in
+-- ligature building). I also experimented with pushing preceding glyphs sequences
+-- in the replace/pre fields beforehand which saves checking afterwards but at the
+-- cost of duplicate glyphs (memory) but it's too much overhead (runtime).
+--
+-- In the meantime Kai had moved the code from the single chain into a more general
+-- handler and this one (renamed to chaindisk) is used now. I optimized the code a
+-- bit and brought it in sycn with the other code. Hopefully I didn't introduce
+-- errors. Note: this somewhat complex approach is meant for fonts that implement
+-- (for instance) ligatures by character replacement which to some extend is not
+-- that suitable for hyphenation. I also use some helpers. This method passes some
+-- states but reparses the list. There is room for a bit of speed up but that will
+-- be done in the context version. (In fact a partial rewrite of all code can bring
+-- some more efficiency.)
+--
+-- I didn't test it with extremes but successive disc nodes still can give issues
+-- but in order to handle that we need more complex code which also slows down even
+-- more. The main loop variant could deal with that: test, collapse, backtrack.
+
+local userkern = nuts.pool and nuts.pool.newkern -- context
+
+do if not userkern then -- generic
+
+ local thekern = nuts.new("kern",1) -- userkern
+ local setkern = nuts.setkern -- not injections.setkern
+
+ userkern = function(k)
+ local n = copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
+
+end end
+
+local function checked(head)
+ local current = head
+ while current do
+ if getid(current) == glue_code then
+ local kern = userkern(getwidth(current))
+ if head == current then
+ local next = getnext(current)
+ if next then
+ setlink(kern,next)
+ end
+ flush_node(current)
+ head = kern
+ current = next
+ else
+ local prev, next = getboth(current)
+ setlink(prev,kern,next)
+ flush_node(current)
+ current = next
+ end
+ else
+ current = getnext(current)
+ end
+ end
+ return head
+end
+
+local function setdiscchecked(d,pre,post,replace)
+ if pre then pre = checked(pre) end
+ if post then post = checked(post) end
+ if replace then replace = checked(replace) end
+ setdisc(d,pre,post,replace)
+end
+
+local noflags = { false, false, false, false }
+
+local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
+
+ local size = ck[5] - ck[4] + 1
+ local chainlookups = ck[6]
+ local done = false
+
+ -- current match
+ if chainlookups then
+ -- Lookups can be like { 1, false, 3 } or { false, 2 } or basically anything and
+ -- #lookups can be less than #current
+
+ if size == 1 then
+
+ -- if nofchainlookups > size then
+ -- -- bad rules
+ -- end
+
+ local chainlookup = chainlookups[1]
+ 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,skiphash)
+ if ok then
+ done = true
+ end
+ else
+ logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind)
+ end
+ end
+
+ else
+
+ -- See LookupType 5: Contextual Substitution Subtable. Now it becomes messy. The
+ -- easiest case is where #current maps on #lookups i.e. one-to-one. But what if
+ -- we have a ligature. Cf the spec we then need to advance one character but we
+ -- really need to test it as there are fonts out there that are fuzzy and have
+ -- too many lookups:
+ --
+ -- 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).
+
+ -- It's very unlikely that we will have skip classes here but still ... we seldom
+ -- enter this branch anyway.
+
+ local i = 1
+ local laststart = start
+ local nofchainlookups = #chainlookups -- useful?
+ while start do
+ if skiphash then -- hm, so we know we skip some
+ while start do
+ local char = ischar(start,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ start = getnext(start)
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ end
+ local chainlookup = chainlookups[i]
+ if chainlookup then
+ 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,skiphash,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
+ i = size -- prevents an advance
+ break
+ end
+ end
+ else
+ -- actually an error
+ logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
+ end
+ end
+ else
+ -- we skip but we could also delete as option .. what does an empty lookup actually mean
+ -- in opentype ... anyway, we could map it onto gsub_remove if needed
+ end
+ i = i + 1
+ if i > size or not start then
+ break
+ elseif start then
+ laststart = start
+ start = getnext(start)
+ end
+ end
+ if not start then
+ start = laststart
+ end
+
+ end
+ else
+ -- todo: needs checking for holes in the replacements
+ local replacements = ck[7]
+ if replacements then
+ head, start, done = reversesub(head,start,last,dataset,sequence,replacements,rlmode,skiphash)
+ else
+ done = true
+ if trace_contexts then
+ logprocess("%s: skipping match",cref(dataset,sequence))
+ end
+ end
+ end
+ return head, start, done
+end
+
+local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
+
+ if not start then
+ return head, start, false
+ end
+
+ local startishead = start == head
+ local seq = ck[3]
+ local f = ck[4]
+ local l = ck[5]
+ local s = #seq
+ local done = false
+ local sweepnode = sweepnode
+ local sweeptype = sweeptype
+ local sweepoverflow = false
+ local keepdisc = not sweepnode
+ local lookaheaddisc = nil
+ local backtrackdisc = nil
+ local current = start
+ local last = start
+ local prev = getprev(start)
+ local hasglue = false
+
+ -- fishy: so we can overflow and then go on in the sweep?
+ -- todo : id can also be glue_code as we checked spaces
+
+ local i = f
+ while i <= l do
+ local id = getid(current)
+ if id == glyph_code then
+ i = i + 1
+ last = current
+ current = getnext(current)
+ elseif id == glue_code then
+ i = i + 1
+ last = current
+ current = getnext(current)
+ hasglue = true
+ elseif id == disc_code then
+ if keepdisc then
+ keepdisc = false
+ lookaheaddisc = current
+ local replace = getfield(current,"replace")
+ if not replace then
+ sweepoverflow = true
+ sweepnode = current
+ current = getnext(current)
+ else
+ while replace and i <= l do
+ if getid(replace) == glyph_code then
+ i = i + 1
+ end
+ replace = getnext(replace)
+ end
+ current = getnext(replace)
+ end
+ last = current
+ else
+ head, current = flattendisk(head,current)
+ end
+ else
+ last = current
+ current = getnext(current)
+ end
+ if current then
+ -- go on
+ elseif sweepoverflow then
+ -- we already are following up on sweepnode
+ break
+ elseif sweeptype == "post" or sweeptype == "replace" then
+ current = getnext(sweepnode)
+ if current then
+ sweeptype = nil
+ sweepoverflow = true
+ else
+ break
+ end
+ else
+ break -- added
+ end
+ end
+
+ if sweepoverflow then
+ local prev = current and getprev(current)
+ if not current or prev ~= sweepnode then
+ local head = getnext(sweepnode)
+ local tail = nil
+ if prev then
+ tail = prev
+ setprev(current,sweepnode)
+ else
+ tail = find_node_tail(head)
+ end
+ setnext(sweepnode,current)
+ setprev(head)
+ setnext(tail)
+ appenddisc(sweepnode,head)
+ end
+ end
+
+ if l < s then
+ local i = l
+ local t = sweeptype == "post" or sweeptype == "replace"
+ while current and i < s do
+ local id = getid(current)
+ if id == glyph_code then
+ i = i + 1
+ current = getnext(current)
+ elseif id == glue_code then
+ i = i + 1
+ current = getnext(current)
+ hasglue = true
+ elseif id == disc_code then
+ if keepdisc then
+ keepdisc = false
+ if notmatchpre[current] ~= notmatchreplace[current] then
+ lookaheaddisc = current
+ end
+ -- we assume a simple text only replace (we could use nuts.count)
+ local replace = getfield(current,"replace")
+ while replace and i < s do
+ if getid(replace) == glyph_code then
+ i = i + 1
+ end
+ replace = getnext(replace)
+ end
+ current = getnext(current)
+ elseif notmatchpre[current] ~= notmatchreplace[current] then
+ head, current = flattendisk(head,current)
+ else
+ current = getnext(current) -- HH
+ end
+ else
+ current = getnext(current)
+ end
+ if not current and t then
+ current = getnext(sweepnode)
+ if current then
+ sweeptype = nil
+ end
+ end
+ end
+ end
+
+ if f > 1 then
+ local current = prev
+ local i = f
+ local t = sweeptype == "pre" or sweeptype == "replace"
+ if not current and t and current == checkdisk then
+ current = getprev(sweepnode)
+ end
+ while current and i > 1 do -- missing getprev added / moved outside
+ local id = getid(current)
+ if id == glyph_code then
+ i = i - 1
+ elseif id == glue_code then
+ i = i - 1
+ hasglue = true
+ elseif id == disc_code then
+ if keepdisc then
+ keepdisc = false
+ if notmatchpost[current] ~= notmatchreplace[current] then
+ backtrackdisc = current
+ end
+ -- we assume a simple text only replace (we could use nuts.count)
+ local replace = getfield(current,"replace")
+ while replace and i > 1 do
+ if getid(replace) == glyph_code then
+ i = i - 1
+ end
+ replace = getnext(replace)
+ end
+ elseif notmatchpost[current] ~= notmatchreplace[current] then
+ head, current = flattendisk(head,current)
+ end
+ end
+ current = getprev(current)
+ if t and current == checkdisk then
+ current = getprev(sweepnode)
+ end
+ end
+ end
+ local done = false
+
+ if lookaheaddisc then
+
+ local cf = start
+ local cl = getprev(lookaheaddisc)
+ local cprev = getprev(start)
+ local insertedmarks = 0
+
+ while cprev do
+ local char = ischar(cf,currentfont)
+ if char and marks[char] then
+ insertedmarks = insertedmarks + 1
+ cf = cprev
+ startishead = cf == head
+ cprev = getprev(cprev)
+ else
+ break
+ end
+ end
+ setlink(cprev,lookaheaddisc)
+ setprev(cf)
+ setnext(cl)
+ if startishead then
+ head = lookaheaddisc
+ end
+ local pre, post, replace = getdisc(lookaheaddisc)
+ local new = copy_node_list(cf) -- br, how often does that happen
+ local cnew = new
+ if pre then
+ setlink(find_node_tail(cf),pre)
+ end
+ if replace then
+ local tail = find_node_tail(new)
+ setlink(tail,replace)
+ end
+ for i=1,insertedmarks do
+ cnew = getnext(cnew)
+ end
+ cl = start
+ local clast = cnew
+ for i=f,l do
+ cl = getnext(cl)
+ clast = getnext(clast)
+ end
+ if not notmatchpre[lookaheaddisc] then
+ local ok = false
+ cf, start, ok = chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done = true
+ end
+ end
+ if not notmatchreplace[lookaheaddisc] then
+ local ok = false
+ new, cnew, ok = chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done = true
+ end
+ end
+ if hasglue then
+ setdiscchecked(lookaheaddisc,cf,post,new)
+ else
+ setdisc(lookaheaddisc,cf,post,new)
+ end
+ start = getprev(lookaheaddisc)
+ sweephead[cf] = getnext(clast) or false
+ sweephead[new] = getnext(cl) or false
+
+ elseif backtrackdisc then
+
+ local cf = getnext(backtrackdisc)
+ local cl = start
+ local cnext = getnext(start)
+ local insertedmarks = 0
+
+ while cnext do
+ local char = ischar(cnext,currentfont)
+ if char and marks[char] then
+ insertedmarks = insertedmarks + 1
+ cl = cnext
+ cnext = getnext(cnext)
+ else
+ break
+ end
+ end
+ setlink(backtrackdisc,cnext)
+ setprev(cf)
+ setnext(cl)
+ local pre, post, replace, pretail, posttail, replacetail = getdisc(backtrackdisc,true)
+ local new = copy_node_list(cf)
+ local cnew = find_node_tail(new)
+ for i=1,insertedmarks do
+ cnew = getprev(cnew)
+ end
+ local clast = cnew
+ for i=f,l do
+ clast = getnext(clast)
+ end
+ if not notmatchpost[backtrackdisc] then
+ local ok = false
+ cf, start, ok = chainrun(cf,start,last,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done = true
+ end
+ end
+ if not notmatchreplace[backtrackdisc] then
+ local ok = false
+ new, cnew, ok = chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done = true
+ end
+ end
+ if post then
+ setlink(posttail,cf)
+ else
+ post = cf
+ end
+ if replace then
+ setlink(replacetail,new)
+ else
+ replace = new
+ end
+ if hasglue then
+ setdiscchecked(backtrackdisc,pre,post,replace)
+ else
+ setdisc(backtrackdisc,pre,post,replace)
+ end
+ start = getprev(backtrackdisc)
+ sweephead[post] = getnext(clast) or false
+ sweephead[replace] = getnext(last) or false
+
+ else
+
+ local ok = false
+ head, start, ok = chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done = true
+ end
+
+ end
+
+ return head, start, done
+end
+
+local function chaintrac(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode)
+ local rule = ck[1]
+ local lookuptype = ck[8] or ck[2]
+ local nofseq = #ck[3]
+ local first = ck[4]
+ local last = ck[5]
+ local char = getchar(start)
+ logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping",
+ cref(dataset,sequence),rule,match and "matches" or "nomatch",
+ gref(char),first-1,last-first+1,nofseq-last,lookuptype,
+ discseen and "" or "no ", sweepnode and "" or "not ")
+end
+
+-- The next one is quite optimized but still somewhat slow, fonts like ebgaramond
+-- are real torture tests because they have many steps with one context (having
+-- multiple contexts makes more sense) also because we (can) reduce them. Instead of
+-- a match boolean variable and check for that I decided to use a goto with labels
+-- instead. This is one of the cases where it makes the code more readable and we
+-- might even gain a bit performance.
+
+-- when we have less replacements (lookups) then current matches we can push too much into
+-- the previous disc .. such be it (<before><disc><current=fl><after> with only f done)
+
+local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash)
+ -- optimizing for rlmode gains nothing
+ local sweepnode = sweepnode
+ local sweeptype = sweeptype
+ local postreplace
+ local prereplace
+ local checkdisc
+ local discseen -- = false
+ if sweeptype then
+ if sweeptype == "replace" then
+ postreplace = true
+ prereplace = true
+ else
+ postreplace = sweeptype == "post"
+ prereplace = sweeptype == "pre"
+ end
+ checkdisc = getprev(head)
+ end
+ local currentfont = currentfont
+
+ local skipped -- = false
+
+ local startprev,
+ startnext = getboth(start)
+ local done -- = false
+
+ -- we can have multiple hits and as we scan (currently) all we need to check
+ -- if we have a match ... contextchains have no real coverage table (with
+ -- unique entries)
+
+ -- fonts can have many steps (each doing one check) or many contexts
+
+ -- todo: make a per-char cache so that we have small contexts (when we have a context
+ -- n == 1 and otherwise it can be more so we can even distingish n == 1 or more)
+
+ local nofcontexts = contexts.n -- #contexts
+
+ local startchar = nofcontext == 1 or ischar(start,currentfont) -- only needed in a chain
+
+ for k=1,nofcontexts do -- does this disc mess work well with n > 1
+
+ local ck = contexts[k]
+ local seq = ck[3]
+ local f = ck[4] -- first current
+ if not startchar or not seq[f][startchar] then
+ -- report("no hit in %a at %i of %i contexts",sequence.type,k,nofcontexts)
+ goto next
+ end
+ local s = seq.n -- or #seq
+ local l = ck[5] -- last current
+ local current = start
+ local last = start
+
+ -- current match
+
+ if l > f then
+ -- before/current/after | before/current | current/after
+ local discfound -- = nil
+ local n = f + 1
+ last = startnext -- the second in current (first already matched)
+ while n <= l do
+ if postreplace and not last then
+ last = getnext(sweepnode)
+ sweeptype = nil
+ end
+ if last then
+ local char, id = ischar(last,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped = true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ last = getnext(last)
+ elseif seq[n][char] then
+ if n < l then
+ last = getnext(last)
+ end
+ n = n + 1
+ elseif discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif char == false then
+ if discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif id == disc_code then
+ -- elseif id == disc_code and (not discs or discs[last]) then
+ discseen = true
+ discfound = last
+ notmatchpre[last] = nil
+ notmatchpost[last] = true
+ notmatchreplace[last] = nil
+ local pre, post, replace = getdisc(last)
+ if pre then
+ local n = n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n = n + 1
+ if n > l then
+ break
+ end
+ pre = getnext(pre)
+ else
+ notmatchpre[last] = true
+ break
+ end
+ end
+ -- commented, for Kai to check
+ -- if n <= l then
+ -- notmatchpre[last] = true
+ -- end
+ else
+ notmatchpre[last] = true
+ end
+ if replace then
+ -- so far we never entered this branch
+ while replace do
+ if seq[n][getchar(replace)] then
+ n = n + 1
+ if n > l then
+ break
+ end
+ replace = getnext(replace)
+ else
+ notmatchreplace[last] = true
+ if notmatchpre[last] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ -- why here again
+ if notmatchpre[last] then
+ goto next
+ end
+ end
+ -- maybe only if match
+ last = getnext(last)
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+ end
+
+ -- before
+
+ if f > 1 then
+ if startprev then
+ local prev = startprev
+ if prereplace and prev == checkdisc then
+ prev = getprev(sweepnode)
+ end
+ if prev then
+ local discfound -- = nil
+ local n = f - 1
+ while n >= 1 do
+ if prev then
+ local char, id = ischar(prev,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped = true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ prev = getprev(prev)
+ elseif seq[n][char] then
+ if n > 1 then
+ prev = getprev(prev)
+ end
+ n = n - 1
+ elseif discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpost[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif char == false then
+ if discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpost[discfound] then
+ goto next
+ end
+ else
+ goto next
+ end
+ break
+ elseif id == disc_code then
+ -- elseif id == disc_code and (not discs or discs[prev]) then
+ -- the special case: f i where i becomes dottless i ..
+ discseen = true
+ discfound = prev
+ notmatchpre[prev] = true
+ notmatchpost[prev] = nil
+ notmatchreplace[prev] = nil
+ local pre, post, replace, pretail, posttail, replacetail = getdisc(prev,true)
+ -- weird test: needs checking
+ if pre ~= start and post ~= start and replace ~= start then
+ if post then
+ local n = n
+ while posttail do
+ if seq[n][getchar(posttail)] then
+ n = n - 1
+ if posttail == post or n < 1 then
+ break
+ else
+ posttail = getprev(posttail)
+ end
+ else
+ notmatchpost[prev] = true
+ break
+ end
+ end
+ if n >= 1 then
+ notmatchpost[prev] = true
+ end
+ else
+ notmatchpost[prev] = true
+ end
+ if replace then
+ -- we seldom enter this branch (e.g. on brill efficient)
+ while replacetail do
+ if seq[n][getchar(replacetail)] then
+ n = n - 1
+ if replacetail == replace or n < 1 then
+ break
+ else
+ replacetail = getprev(replacetail)
+ end
+ else
+ notmatchreplace[prev] = true
+ if notmatchpost[prev] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ else
+ -- notmatchreplace[prev] = true -- not according to Kai
+ end
+ end
+ prev = getprev(prev)
+ -- elseif id == glue_code and seq[n][32] and isspace(prev,threshold,id) then
+ -- elseif seq[n][32] and spaces[prev] then
+ -- n = n - 1
+ -- prev = getprev(prev)
+ elseif id == glue_code then
+ local sn = seq[n]
+ if (sn[32] and spaces[prev]) or sn[0xFFFC] then
+ n = n - 1
+ prev = getprev(prev)
+ else
+ goto next
+ end
+ elseif seq[n][0xFFFC] then
+ n = n - 1
+ prev = getprev(prev)
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+
+ -- after
+
+ if s > l then
+ local current = last and getnext(last)
+ if not current and postreplace then
+ current = getnext(sweepnode)
+ end
+ if current then
+ local discfound -- = nil
+ local n = l + 1
+ while n <= s do
+ if current then
+ local char, id = ischar(current,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped = true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ current = getnext(current) -- was absent
+ elseif seq[n][char] then
+ if n < s then -- new test
+ current = getnext(current) -- was absent
+ end
+ n = n + 1
+ elseif discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif char == false then
+ if discfound then
+ notmatchreplace[discfound] = true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif id == disc_code then
+ -- elseif id == disc_code and (not discs or discs[current]) then
+ discseen = true
+ discfound = current
+ notmatchpre[current] = nil
+ notmatchpost[current] = true
+ notmatchreplace[current] = nil
+ local pre, post, replace = getdisc(current)
+ if pre then
+ local n = n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n = n + 1
+ if n > s then
+ break
+ else
+ pre = getnext(pre)
+ end
+ else
+ notmatchpre[current] = true
+ break
+ end
+ end
+ if n <= s then
+ notmatchpre[current] = true
+ end
+ else
+ notmatchpre[current] = true
+ end
+ if replace then
+ -- so far we never entered this branch
+ while replace do
+ if seq[n][getchar(replace)] then
+ n = n + 1
+ if n > s then
+ break
+ else
+ replace = getnext(replace)
+ end
+ else
+ notmatchreplace[current] = true
+ if notmatchpre[current] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ else
+ -- notmatchreplace[current] = true -- not according to Kai
+ end
+ current = getnext(current)
+ elseif id == glue_code then
+ local sn = seq[n]
+ if (sn[32] and spaces[current]) or sn[0xFFFC] then
+ n = n + 1
+ current = getnext(current)
+ else
+ goto next
+ end
+ elseif seq[n][0xFFFC] then
+ n = n + 1
+ current = getnext(current)
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+ else
+ goto next
+ end
+ end
+
+ if trace_contexts then
+ chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode)
+ end
+ if discseen or sweepnode then
+ head, start, done = chaindisk(head,start,dataset,sequence,rlmode,skipped and skiphash,ck)
+ else
+ head, start, done = chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck)
+ end
+ if done then
+ break
+ -- else
+ -- next context
+ end
+ ::next::
+ -- if trace_chains then
+ -- chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,false,discseen,sweepnode)
+ -- end
+ end
+ if discseen then
+ notmatchpre = { }
+ notmatchpost = { }
+ notmatchreplace = { }
+ -- notmatchpre = { a = 1, b = 1 } notmatchpre .a = nil notmatchpre .b = nil
+ -- notmatchpost = { a = 1, b = 1 } notmatchpost .a = nil notmatchpost .b = nil
+ -- notmatchreplace = { a = 1, b = 1 } notmatchreplace.a = nil notmatchreplace.b = nil
+ end
+ return head, start, done
+end
+
+handlers.gsub_context = handle_contextchain
+handlers.gsub_contextchain = handle_contextchain
+handlers.gsub_reversecontextchain = handle_contextchain
+handlers.gpos_contextchain = handle_contextchain
+handlers.gpos_context = handle_contextchain
+
+-- this needs testing
+
+local function chained_contextchain(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash)
+ local steps = currentlookup.steps
+ local nofsteps = currentlookup.nofsteps
+ if nofsteps > 1 then
+ reportmoresteps(dataset,sequence)
+ end
+ -- probably wrong
+ local l = steps[1].coverage[getchar(start)]
+ if l then
+ return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash)
+ else
+ return head, start, false
+ end
+end
+
+chainprocs.gsub_context = chained_contextchain
+chainprocs.gsub_contextchain = chained_contextchain
+chainprocs.gsub_reversecontextchain = chained_contextchain
+chainprocs.gpos_contextchain = chained_contextchain
+chainprocs.gpos_context = chained_contextchain
+
+------------------------------
+
+-- experiment (needs no handler in font-otc so not now):
+--
+-- function otf.registerchainproc(name,f)
+-- -- chainprocs[name] = f
+-- chainprocs[name] = function(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash)
+-- local done = currentlookup.nofsteps > 0
+-- if not done then
+-- reportzerosteps(dataset,sequence)
+-- else
+-- head, start, done = f(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash)
+-- if not head or not start then
+-- reportbadsteps(dataset,sequence)
+-- end
+-- end
+-- return head, start, done
+-- end
+-- end
+
+local missing = setmetatableindex("table")
+local logwarning = report_process
+local resolved = { } -- we only resolve a font,script,language pair once
+
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ if trace_steps == "silent" then
+ return
+ end
+ end
+ report_process(...)
+end
+
+-- todo: pass all these 'locals' in a table
+
+local sequencelists = setmetatableindex(function(t,font)
+ local sequences = fontdata[font].resources.sequences
+ if not sequences or not next(sequences) then
+ sequences = false
+ end
+ t[font] = sequences
+ return sequences
+end)
+
+-- fonts.hashes.sequences = sequencelists
+
+do -- overcome local limit
+
+ local autofeatures = fonts.analyzers.features
+ local featuretypes = otf.tables.featuretypes
+ local defaultscript = otf.features.checkeddefaultscript
+ local defaultlanguage = otf.features.checkeddefaultlanguage
+
+ local wildcard = "*"
+ local default = "dflt"
+
+ local function initialize(sequence,script,language,enabled,autoscript,autolanguage)
+ local features = sequence.features
+ if features then
+ local order = sequence.order
+ if order then
+ local featuretype = featuretypes[sequence.type or "unknown"]
+ for i=1,#order do
+ local kind = order[i]
+ local valid = enabled[kind]
+ if valid then
+ local scripts = features[kind]
+ local languages = scripts and (
+ scripts[script] or
+ scripts[wildcard] or
+ (autoscript and defaultscript(featuretype,autoscript,scripts))
+ )
+ local enabled = languages and (
+ languages[language] or
+ languages[wildcard] or
+ (autolanguage and defaultlanguage(featuretype,autolanguage,languages))
+ )
+ if enabled then
+ return { valid, autofeatures[kind] or false, sequence, kind }
+ end
+ end
+ end
+ else
+ -- can't happen
+ end
+ end
+ return false
+ end
+
+ function otf.dataset(tfmdata,font) -- generic variant, overloaded in context
+ local shared = tfmdata.shared
+ local properties = tfmdata.properties
+ local language = properties.language or "dflt"
+ local script = properties.script or "dflt"
+ local enabled = shared.features
+ local autoscript = enabled and enabled.autoscript
+ local autolanguage = enabled and enabled.autolanguage
+ local res = resolved[font]
+ if not res then
+ res = { }
+ resolved[font] = res
+ end
+ local rs = res[script]
+ if not rs then
+ rs = { }
+ res[script] = rs
+ end
+ local rl = rs[language]
+ if not rl then
+ rl = {
+ -- indexed but we can also add specific data by key
+ }
+ rs[language] = rl
+ local sequences = tfmdata.resources.sequences
+ if sequences then
+ for s=1,#sequences do
+ local v = enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage)
+ if v then
+ rl[#rl+1] = v
+ end
+ end
+ end
+ end
+ return rl
+ end
+
+end
+
+-- Functions like kernrun, comprun etc evolved over time and in the end look rather
+-- complex. It's a bit of a compromis between extensive copying and creating subruns.
+-- The logic has been improved a lot by Kai and Ivo who use complex fonts which
+-- really helped to identify border cases on the one hand and get insight in the diverse
+-- ways fonts implement features (not always that consistent and efficient). At the same
+-- time I tried to keep the code relatively efficient so that the overhead in runtime
+-- stays acceptable.
+
+local function report_disc(what,n)
+ report_run("%s: %s > %s",what,n,languages.serializediscretionary(n))
+end
+
+local function kernrun(disc,k_run,font,attr,...)
+ --
+ -- we catch <font 1><disc font 2>
+ --
+ if trace_kernruns then
+ report_disc("kern",disc)
+ end
+ --
+ local prev, next = getboth(disc)
+ --
+ local nextstart = next
+ local done = false
+ --
+ local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true)
+ --
+ local prevmarks = prev
+ --
+ -- can be optional, because why on earth do we get a disc after a mark (okay, maybe when a ccmp
+ -- has happened but then it should be in the disc so basically this test indicates an error)
+ --
+ while prevmarks do
+ local char = ischar(prevmarks,font)
+ if char and marks[char] then
+ prevmarks = getprev(prevmarks)
+ else
+ break
+ end
+ end
+ --
+ if prev and not ischar(prev,font) then -- and (pre or replace)
+ prev = false
+ end
+ if next and not ischar(next,font) then -- and (post or replace)
+ next = false
+ end
+ --
+ -- we need to get rid of this nest mess some day .. has to be done otherwise
+ --
+ if pre then
+ if k_run(pre,"injections",nil,font,attr,...) then
+ done = true
+ end
+ if prev then
+ setlink(prev,pre)
+ if k_run(prevmarks,"preinjections",pre,font,attr,...) then -- or prev?
+ done = true
+ end
+ setprev(pre)
+ setlink(prev,disc)
+ end
+ end
+ --
+ if post then
+ if k_run(post,"injections",nil,font,attr,...) then
+ done = true
+ end
+ if next then
+ setlink(posttail,next)
+ if k_run(posttail,"postinjections",next,font,attr,...) then
+ done = true
+ end
+ setnext(posttail)
+ setlink(disc,next)
+ end
+ end
+ --
+ if replace then
+ if k_run(replace,"injections",nil,font,attr,...) then
+ done = true
+ end
+ if prev then
+ setlink(prev,replace)
+ if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then -- getnext(replace))
+ done = true
+ end
+ setprev(replace)
+ setlink(prev,disc)
+ end
+ if next then
+ setlink(replacetail,next)
+ if k_run(replacetail,"replaceinjections",next,font,attr,...) then
+ done = true
+ end
+ setnext(replacetail)
+ setlink(disc,next)
+ end
+ elseif prev and next then
+ setlink(prev,next)
+ if k_run(prevmarks,"emptyinjections",next,font,attr,...) then
+ done = true
+ end
+ setlink(prev,disc,next)
+ end
+ if done and trace_testruns then
+ report_disc("done",disc)
+ end
+ return nextstart, done
+end
+
+-- fonts like ebgaramond do ligatures this way (less efficient than e.g. dejavu which
+-- will do the testrun variant)
+
+local function comprun(disc,c_run,...) -- vararg faster than the whole list
+ if trace_compruns then
+ report_disc("comp",disc)
+ end
+ --
+ local pre, post, replace = getdisc(disc)
+ local renewed = false
+ --
+ if pre then
+ sweepnode = disc
+ sweeptype = "pre" -- in alternative code preinjections is used (also used then for properties, saves a variable)
+ local new, done = c_run(pre,...)
+ if done then
+ pre = new
+ renewed = true
+ end
+ end
+ --
+ if post then
+ sweepnode = disc
+ sweeptype = "post"
+ local new, done = c_run(post,...)
+ if done then
+ post = new
+ renewed = true
+ end
+ end
+ --
+ if replace then
+ sweepnode = disc
+ sweeptype = "replace"
+ local new, done = c_run(replace,...)
+ if done then
+ replace = new
+ renewed = true
+ end
+ end
+ --
+ sweepnode = nil
+ sweeptype = nil
+ if renewed then
+ if trace_testruns then
+ report_disc("done",disc)
+ end
+ setdisc(disc,pre,post,replace)
+ end
+ --
+ return getnext(disc), renewed
+end
+
+-- if we can hyphenate in a lig then unlikely a lig so we
+-- could have a option here to ignore lig
+
+local function testrun(disc,t_run,c_run,...)
+ if trace_testruns then
+ report_disc("test",disc)
+ end
+ local prev, next = getboth(disc)
+ if not next then
+ -- weird discretionary
+ return
+ end
+ local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true)
+ local renewed = false
+ if (post or replace) then -- and prev then -- hm, we can start with a disc
+ if post then
+ setlink(posttail,next)
+ else
+ post = next
+ end
+ if replace then
+ setlink(replacetail,next)
+ else
+ replace = next
+ end
+ local d_post = t_run(post,next,...)
+ local d_replace = t_run(replace,next,...)
+ if d_post > 0 or d_replace > 0 then
+ local d = d_replace > d_post and d_replace or d_post
+ local head = getnext(disc) -- is: next
+ local tail = head
+ for i=2,d do -- must start at 2 according to Kai
+ local nx = getnext(tail)
+ local id = getid(nx)
+ if id == disc_code then
+ head, tail = flattendisk(head,nx)
+ elseif id == glyph_code then
+ tail = nx
+ else
+ -- we can have overrun into a glue
+ break
+ end
+ end
+ next = getnext(tail)
+ setnext(tail)
+ setprev(head)
+ local new = copy_node_list(head)
+ if posttail then
+ setlink(posttail,head)
+ else
+ post = head
+ end
+ if replacetail then
+ setlink(replacetail,new)
+ else
+ replace = new
+ end
+ else
+ -- we stay inside the disc
+ if posttail then
+ setnext(posttail)
+ else
+ post = nil
+ end
+ if replacetail then
+ setnext(replacetail)
+ else
+ replace = nil
+ end
+ end
+ setlink(disc,next)
+ -- pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true)
+ end
+ --
+ -- like comprun
+ --
+ if trace_testruns then
+ report_disc("more",disc)
+ end
+ --
+ if pre then
+ sweepnode = disc
+ sweeptype = "pre"
+ local new, ok = c_run(pre,...)
+ if ok then
+ pre = new
+ renewed = true
+ end
+ end
+ --
+ if post then
+ sweepnode = disc
+ sweeptype = "post"
+ local new, ok = c_run(post,...)
+ if ok then
+ post = new
+ renewed = true
+ end
+ end
+ --
+ if replace then
+ sweepnode = disc
+ sweeptype = "replace"
+ local new, ok = c_run(replace,...)
+ if ok then
+ replace = new
+ renewed = true
+ end
+ end
+ --
+ sweepnode = nil
+ sweeptype = nil
+ if renewed then
+ setdisc(disc,pre,post,replace)
+ if trace_testruns then
+ report_disc("done",disc)
+ end
+ end
+ -- next can have changed (copied list)
+ return getnext(disc), renewed
+end
+
+-- We can make some assumptions with respect to discretionaries. First of all it is very
+-- unlikely that some of the analysis related attributes applies. Then we can also assume
+-- that the ConTeXt specific dynamic attribute is different, although we do use explicit
+-- discretionaries (maybe we need to tag those some day). So, at least for now, we don't
+-- have the following test in the sub runs:
+--
+-- -- local a = getglyhpdata(start)
+-- -- if a then
+-- -- a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
+-- -- else
+-- -- a = not attribute or getprop(start,a_state) == attribute
+-- -- end
+-- -- if a then
+--
+-- but use this instead:
+--
+-- -- local a = getglyphdata(start)
+-- -- if not a or (a == attr) then
+--
+-- and even that one is probably not needed. However, we can handle interesting
+-- cases now:
+--
+-- 1{2{\oldstyle\discretionary{3}{4}{5}}6}7\par
+-- 1{2\discretionary{3{\oldstyle3}}{{\oldstyle4}4}{5{\oldstyle5}5}6}7\par
+
+local nesting = 0
+
+local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ local done = false
+ local sweep = sweephead[head]
+ if sweep then
+ start = sweep
+ -- sweephead[head] = nil
+ sweephead[head] = false
+ else
+ start = head
+ end
+ while start do
+ local char, id = ischar(start,font)
+ if char then
+ local a -- happens often so no assignment is faster
+ if attr then
+ a = getglyphdata(start)
+ end
+ if not a or (a == attr) then
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ local ok
+ head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ done = true
+ end
+ end
+ if start then
+ start = getnext(start)
+ end
+ else
+ -- go on can be a mixed one
+ start = getnext(start)
+ end
+ elseif char == false then
+ return head, done
+ elseif sweep then
+ -- else we loose the rest
+ return head, done
+ else
+ -- in disc component
+ start = getnext(start)
+ end
+ end
+ return head, done
+end
+
+-- only replace?
+
+local function t_run_single(start,stop,font,attr,lookupcache)
+ local lastd = nil
+ while start ~= stop do
+ local char = ischar(start,font)
+ if char then
+ local a -- happens often so no assignment is faster
+ if attr then
+ a = getglyphdata(start)
+ end
+ local startnext = getnext(start)
+ if not a or (a == attr) then
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then -- hm, hyphens can match (tlig) so we need to really check
+ -- if we need more than ligatures we can outline the code and use functions
+ local s = startnext
+ local ss = nil
+ local sstop = s == stop
+ if not s then
+ s = ss
+ ss = nil
+ end
+ -- a bit weird: why multiple ... anyway we can't have a disc in a disc
+ -- how about post ... we can probably merge this into the while
+ while getid(s) == disc_code do
+ ss = getnext(s)
+ s = getfield(s,"replace")
+ if not s then
+ s = ss
+ ss = nil
+ end
+ end
+ local l = nil
+ local d = 0
+ while s do
+ local char = ischar(s,font)
+ if char then
+ local lg = lookupmatch[char]
+ if lg then
+ if sstop then
+ d = 1
+ elseif d > 0 then
+ d = d + 1
+ end
+ l = lg
+ s = getnext(s)
+ sstop = s == stop
+ if not s then
+ s = ss
+ ss = nil
+ end
+ while getid(s) == disc_code do
+ ss = getnext(s)
+ s = getfield(s,"replace")
+ if not s then
+ s = ss
+ ss = nil
+ end
+ end
+lookupmatch = lg
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if l and l.ligature then -- so we test for ligature
+ lastd = d
+ end
+-- why not: if not l then break elseif l.ligature then return d end
+ else
+-- why not: break
+ -- no match (yet)
+ end
+ else
+ -- go on can be a mixed one
+-- why not: break
+ end
+ if lastd then
+ return lastd
+ end
+ start = startnext
+ else
+ break
+ end
+ end
+ return 0
+end
+
+local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ local a -- happens often so no assignment is faster
+ if attr then
+ a = getglyphdata(sub)
+ end
+ if not a or (a == attr) then
+ for n in nextnode, sub do -- only gpos
+ if n == last then
+ break
+ end
+ local char = ischar(n)
+ if char then
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ local h, d, ok = handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection)
+ if ok then
+ return true
+ end
+ end
+ end
+ end
+ end
+end
+
+local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ local done = false
+ local sweep = sweephead[head]
+ if sweep then
+ start = sweep
+ -- sweephead[head] = nil
+ sweephead[head] = false
+ else
+ start = head
+ end
+ while start do
+ local char = ischar(start,font)
+ if char then
+ local a -- happens often so no assignment is faster
+ if attr then
+ a = getglyphdata(start)
+ end
+ if not a or (a == attr) then
+ for i=1,nofsteps do
+ local step = steps[i]
+ local lookupcache = step.coverage
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ -- we could move all code inline but that makes things even more unreadable
+ local ok
+ head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ done = true
+ break
+ elseif not start then
+ -- don't ask why ... shouldn't happen
+ break
+ end
+ end
+ end
+ if start then
+ start = getnext(start)
+ end
+ else
+ -- go on can be a mixed one
+ start = getnext(start)
+ end
+ elseif char == false then
+ -- whatever glyph
+ return head, done
+ elseif sweep then
+ -- else we loose the rest
+ return head, done
+ else
+ -- in disc component
+ start = getnext(start)
+ end
+ end
+ return head, done
+end
+
+local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
+ local lastd = nil
+ while start ~= stop do
+ local char = ischar(start,font)
+ if char then
+ local a -- happens often so no assignment is faster
+ if attr then
+ a = getglyphdata(start)
+ end
+ local startnext = getnext(start)
+ if not a or (a == attr) then
+ for i=1,nofsteps do
+ local step = steps[i]
+ local lookupcache = step.coverage
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ -- if we need more than ligatures we can outline the code and use functions
+ local s = startnext
+ local ss = nil
+ local sstop = s == stop
+ if not s then
+ s = ss
+ ss = nil
+ end
+ while getid(s) == disc_code do
+ ss = getnext(s)
+ s = getfield(s,"replace")
+ if not s then
+ s = ss
+ ss = nil
+ end
+ end
+ local l = nil
+ local d = 0
+ while s do
+ local char = ischar(s)
+ if char then
+ local lg = lookupmatch[char]
+ if lg then
+ if sstop then
+ d = 1
+ elseif d > 0 then
+ d = d + 1
+ end
+ l = lg
+ s = getnext(s)
+ sstop = s == stop
+ if not s then
+ s = ss
+ ss = nil
+ end
+ while getid(s) == disc_code do
+ ss = getnext(s)
+ s = getfield(s,"replace")
+ if not s then
+ s = ss
+ ss = nil
+ end
+ end
+lookupmatch = lg
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if l and l.ligature then
+ lastd = d
+ end
+ end
+ end
+ else
+ -- go on can be a mixed one
+ end
+ if lastd then
+ return lastd
+ end
+ start = startnext
+ else
+ break
+ end
+ end
+ return 0
+end
+
+local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ local a -- happens often so no assignment is faster
+ if attr then
+ a = getglyphdata(sub)
+ end
+ if not a or (a == attr) then
+ for n in nextnode, sub do -- only gpos
+ if n == last then
+ break
+ end
+ local char = ischar(n)
+ if char then
+ for i=1,nofsteps do
+ local step = steps[i]
+ local lookupcache = step.coverage
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ local h, d, ok = handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) -- sub was head
+ if ok then
+ return true
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+local txtdirstate, pardirstate do -- this might change (no need for nxt in pardirstate)
+
+ local getdirection = nuts.getdirection
+ local lefttoright = 0
+ local righttoleft = 1
+
+ txtdirstate = function(start,stack,top,rlparmode)
+ local dir, pop = getdirection(start)
+ if pop then
+ if top == 1 then
+ return 0, rlparmode
+ else
+ top = top - 1
+ if stack[top] == righttoleft then
+ return top, -1
+ else
+ return top, 1
+ end
+ end
+ elseif dir == lefttoright then
+ top = top + 1
+ stack[top] = lefttoright
+ return top, 1
+ elseif dir == righttoleft then
+ top = top + 1
+ stack[top] = righttoleft
+ return top, -1
+ else
+ return top, rlparmode
+ end
+ end
+
+ pardirstate = function(start)
+ local dir = getdirection(start)
+ if dir == lefttoright then
+ return 1, 1
+ elseif dir == righttoleft then
+ return -1, -1
+ -- for old times sake we we handle strings too
+ elseif dir == "TLT" then
+ return 1, 1
+ elseif dir == "TRT" then
+ return -1, -1
+ else
+ return 0, 0
+ end
+ end
+
+end
+
+-- These are non public helpers that can change without notice!
+
+otf.helpers = otf.helpers or { }
+otf.helpers.txtdirstate = txtdirstate
+otf.helpers.pardirstate = pardirstate
+
+-- This is the main loop. We run over the node list dealing with a specific font. The
+-- attribute is a context specific thing. We could work on sub start-stop ranges instead
+-- but I wonder if there is that much speed gain (experiments showed that it made not
+-- much sense) and we need to keep track of directions anyway. Also at some point I
+-- want to play with font interactions and then we do need the full sweeps. Apart from
+-- optimizations the principles of processing the features hasn't changed much since
+-- the beginning.
+
+do
+
+ -- reference:
+ --
+ -- local a = attr and getglyphdata(start)
+ -- if a then
+ -- a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
+ -- else
+ -- a = not attribute or getprop(start,a_state) == attribute
+ -- end
+ --
+ -- used:
+ --
+ -- local a -- happens often so no assignment is faster
+ -- if attr then
+ -- if getglyphdata(start) == attr and (not attribute or getprop(start,a_state) == attribute) then
+ -- a = true
+ -- end
+ -- elseif not attribute or getprop(start,a_state) == attribute then
+ -- a = true
+ -- end
+
+ -- This is a measurable experimental speedup (only with hyphenated text and multiple
+ -- fonts per processor call), especially for fonts with lots of contextual lookups.
+
+ local fastdisc = true
+ local testdics = false
+
+ directives.register("otf.fastdisc",function(v) fastdisc = v end) -- normally enabled
+
+ -- using a merged combined hash as first test saves some 30% on ebgaramond and
+ -- about 15% on arabtype .. then moving the a test also saves a bit (even when
+ -- often a is not set at all so that one is a bit debatable
+
+ local otfdataset = nil -- todo: make an installer
+
+ local getfastdisc = { __index = function(t,k)
+ local v = usesfont(k,currentfont)
+ t[k] = v
+ return v
+ end }
+
+ local getfastspace = { __index = function(t,k)
+ -- we don't pass the id so that one can overload isspace
+ local v = isspace(k,threshold) or false
+ t[k] = v
+ return v
+ end }
+
+ function otf.featuresprocessor(head,font,attr,direction,n)
+
+ local sequences = sequencelists[font] -- temp hack
+
+ nesting = nesting + 1
+
+ if nesting == 1 then
+ currentfont = font
+ tfmdata = fontdata[font]
+ descriptions = tfmdata.descriptions -- only needed in gref so we could pass node there instead
+ characters = tfmdata.characters -- but this branch is not entered that often anyway
+ local resources = tfmdata.resources
+ marks = resources.marks
+ classes = resources.classes
+ threshold,
+ factor = getthreshold(font)
+ checkmarks = tfmdata.properties.checkmarks
+
+ if not otfdataset then
+ otfdataset = otf.dataset
+ end
+
+ discs = fastdisc and n and n > 1 and setmetatable({},getfastdisc) -- maybe inline
+ spaces = setmetatable({},getfastspace)
+
+ elseif currentfont ~= font then
+
+ report_warning("nested call with a different font, level %s, quitting",nesting)
+ nesting = nesting - 1
+ return head, false
+
+ end
+
+ -- some 10% faster when no dynamics but hardly measureable on real runs .. but: it only
+ -- works when we have no other dynamics as otherwise the zero run will be applied to the
+ -- whole stream for which we then need to pass another variable which we won't
+
+ -- if attr == 0 then
+ -- attr = false
+ -- end
+
+ if trace_steps then
+ checkstep(head)
+ end
+
+ local initialrl = 0
+
+ if getid(head) == localpar_code and getsubtype(head) == 0 then
+ initialrl = pardirstate(head)
+ elseif direction == 1 or direction == "TRT" then
+ initialrl = -1
+ end
+
+ -- local done = false
+ local datasets = otfdataset(tfmdata,font,attr)
+ local dirstack = { nil } -- could move outside function but we can have local runs
+ sweephead = { }
+ -- sweephead = { a = 1, b = 1 } sweephead.a = nil sweephead.b = nil
+
+ -- Keeping track of the headnode is needed for devanagari. (I generalized it a bit
+ -- so that multiple cases are also covered.) We could prepend a temp node.
+
+ -- We don't goto the next node when a disc node is created so that we can then treat
+ -- the pre, post and replace. It's a bit of a hack but works out ok for most cases.
+
+ for s=1,#datasets do
+ local dataset = datasets[s]
+ local attribute = dataset[2]
+ local sequence = dataset[3] -- sequences[s] -- also dataset[5]
+ local rlparmode = initialrl
+ local topstack = 0
+ local typ = sequence.type
+ local gpossing = typ == "gpos_single" or typ == "gpos_pair" -- store in dataset
+ local forcetestrun = typ == "gsub_ligature" -- testrun is only for ligatures
+ local handler = handlers[typ] -- store in dataset
+ local steps = sequence.steps
+ local nofsteps = sequence.nofsteps
+ local skiphash = sequence.skiphash
+
+ if not steps then
+ -- This permits injection, watch the different arguments. Watch out, the arguments passed
+ -- are not frozen as we might extend or change this. Is this used at all apart from some
+ -- experiments?
+ local h, ok = handler(head,dataset,sequence,initialrl,font,attr) -- less arguments now
+ -- if ok then
+ -- done = true
+ -- end
+ if h and h ~= head then
+ head = h
+ end
+ elseif typ == "gsub_reversecontextchain" then
+ --
+ -- This might need a check: if we have #before or #after > 0 then we might need to reverse
+ -- the before and after lists in the loader. But first I need to see a font that uses multiple
+ -- matches.
+ --
+ local start = find_node_tail(head)
+ local rlmode = 0 -- how important is this .. do we need to check for dir?
+ local merged = steps.merged
+ while start do
+ local char = ischar(start,font)
+ if char then
+ local m = merged[char]
+ if m then
+ local a -- happens often so no assignment is faster
+ if attr then
+ a = getglyphdata(start)
+ end
+ if not a or (a == attr) then
+ for i=m[1],m[2] do
+ local step = steps[i]
+ -- for i=1,#m do
+ -- local step = m[i]
+ local lookupcache = step.coverage
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ local ok
+ head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ -- done = true
+ break
+ end
+ end
+ end
+ if start then
+ start = getprev(start)
+ end
+ else
+ start = getprev(start)
+ end
+ else
+ start = getprev(start)
+ end
+ else
+ start = getprev(start)
+ end
+ end
+ else
+ local start = head
+ local rlmode = initialrl
+ if nofsteps == 1 then -- happens often
+ local step = steps[1]
+ local lookupcache = step.coverage
+ while start do
+ local char, id = ischar(start,font)
+ if char then
+ if skiphash and skiphash[char] then -- we never needed it here but let's try
+ start = getnext(start)
+ else
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ local a -- happens often so no assignment is faster
+ if attr then
+ if getglyphdata(start) == attr and (not attribute or getprop(start,a_state) == attribute) then
+ a = true
+ end
+ elseif not attribute or getprop(start,a_state) == attribute then
+ a = true
+ end
+ if a then
+ local ok, df
+ head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ -- if ok then
+ -- done = true
+ -- end
+ if df then
+-- print("restart 1",typ)
+ elseif start then
+ start = getnext(start)
+ end
+ else
+ start = getnext(start)
+ end
+ else
+ start = getnext(start)
+ end
+ end
+ elseif char == false or id == glue_code then
+ -- a different font|state or glue (happens often)
+ start = getnext(start)
+ elseif id == disc_code then
+ if not discs or discs[start] == true then
+ local ok
+ if gpossing then
+ start, ok = kernrun(start,k_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ elseif forcetestrun then
+ start, ok = testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ else
+ start, ok = comprun(start,c_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ end
+ -- if ok then
+ -- done = true
+ -- end
+ else
+ start = getnext(start)
+ end
+ elseif id == math_code then
+ start = getnext(end_of_math(start))
+ elseif id == dir_code then
+ topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode)
+ start = getnext(start)
+ -- elseif id == localpar_code then
+ -- rlparmode, rlmode = pardirstate(start)
+ -- start = getnext(start)
+ else
+ start = getnext(start)
+ end
+ end
+ else
+ local merged = steps.merged
+ while start do
+ local char, id = ischar(start,font)
+ if char then
+ if skiphash and skiphash[char] then -- we never needed it here but let's try
+ start = getnext(start)
+ else
+ local m = merged[char]
+ if m then
+ local a -- happens often so no assignment is faster
+ if attr then
+ if getglyphdata(start) == attr and (not attribute or getprop(start,a_state) == attribute) then
+ a = true
+ end
+ elseif not attribute or getprop(start,a_state) == attribute then
+ a = true
+ end
+ if a then
+ local ok, df
+ for i=m[1],m[2] do
+ local step = steps[i]
+ -- for i=1,#m do
+ -- local step = m[i]
+ local lookupcache = step.coverage
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ -- we could move all code inline but that makes things even more unreadable
+-- local ok, df
+ head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if df then
+ break
+ elseif ok then
+ -- done = true
+ break
+ elseif not start then
+ -- don't ask why ... shouldn't happen
+ break
+ end
+ end
+ end
+ if df then
+-- print("restart 2",typ)
+ elseif start then
+ start = getnext(start)
+ end
+ else
+ start = getnext(start)
+ end
+ else
+ start = getnext(start)
+ end
+ end
+ elseif char == false or id == glue_code then
+ -- a different font|state or glue (happens often)
+ start = getnext(start)
+ elseif id == disc_code then
+ if not discs or discs[start] == true then
+ local ok
+ if gpossing then
+ start, ok = kernrun(start,k_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ elseif forcetestrun then
+ start, ok = testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ else
+ start, ok = comprun(start,c_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ end
+ -- if ok then
+ -- done = true
+ -- end
+ else
+ start = getnext(start)
+ end
+ elseif id == math_code then
+ start = getnext(end_of_math(start))
+ elseif id == dir_code then
+ topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode)
+ start = getnext(start)
+ -- elseif id == localpar_code then
+ -- rlparmode, rlmode = pardirstate(start)
+ -- start = getnext(start)
+ else
+ start = getnext(start)
+ end
+ end
+ end
+ end
+
+ if trace_steps then -- ?
+ registerstep(head)
+ end
+
+ end
+
+ nesting = nesting - 1
+
+ -- return head, done
+ return head
+ end
+
+ -- This is not an official helper and used for tracing experiments. It can be changed as I like
+ -- at any moment. At some point it might be used in a module that can help font development.
+
+ function otf.datasetpositionprocessor(head,font,direction,dataset)
+
+ currentfont = font
+ tfmdata = fontdata[font]
+ descriptions = tfmdata.descriptions -- only needed in gref so we could pass node there instead
+ characters = tfmdata.characters -- but this branch is not entered that often anyway
+ local resources = tfmdata.resources
+ marks = resources.marks
+ classes = resources.classes
+ threshold,
+ factor = getthreshold(font)
+ checkmarks = tfmdata.properties.checkmarks
+
+ if type(dataset) == "number" then
+ dataset = otfdataset(tfmdata,font,0)[dataset]
+ end
+
+ local sequence = dataset[3] -- sequences[s] -- also dataset[5]
+ local typ = sequence.type
+ -- local gpossing = typ == "gpos_single" or typ == "gpos_pair" -- store in dataset
+
+ -- gpos_contextchain gpos_context
+
+ -- if not gpossing then
+ -- return head, false
+ -- end
+
+ local handler = handlers[typ] -- store in dataset
+ local steps = sequence.steps
+ local nofsteps = sequence.nofsteps
+
+ local done = false
+ local dirstack = { nil } -- could move outside function but we can have local runs (maybe a few more nils)
+ local start = head
+ local initialrl = (direction == 1 or direction == "TRT") and -1 or 0
+ local rlmode = initialrl
+ local rlparmode = initialrl
+ local topstack = 0
+ local merged = steps.merged
+
+ -- local matches = false
+ local position = 0
+
+ while start do
+ local char, id = ischar(start,font)
+ if char then
+ position = position + 1
+ local m = merged[char]
+ if m then
+ if skiphash and skiphash[char] then -- we never needed it here but let's try
+ start = getnext(start)
+ else
+ for i=m[1],m[2] do
+ local step = steps[i]
+ local lookupcache = step.coverage
+ local lookupmatch = lookupcache[char]
+ if lookupmatch then
+ local ok
+ head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ -- if matches then
+ -- matches[position] = i
+ -- else
+ -- matches = { [position] = i }
+ -- end
+ break
+ elseif not start then
+ break
+ end
+ end
+ end
+ if start then
+ start = getnext(start)
+ end
+ end
+ else
+ start = getnext(start)
+ end
+ elseif char == false or id == glue_code then
+ -- a different font|state or glue (happens often)
+ start = getnext(start)
+ elseif id == math_code then
+ start = getnext(end_of_math(start))
+ elseif id == dir_code then
+ topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode)
+ start = getnext(start)
+ -- elseif id == localpar_code then
+ -- rlparmode, rlmode = pardirstate(start)
+ -- start = getnext(start)
+ else
+ start = getnext(start)
+ end
+ end
+
+ return head
+ end
+
+ -- end of experiment
+
+end
+
+-- so far
+
+local plugins = { }
+otf.plugins = plugins
+
+local report = logs.reporter("fonts")
+
+function otf.registerplugin(name,f)
+ if type(name) == "string" and type(f) == "function" then
+ plugins[name] = { name, f }
+ report()
+ report("plugin %a has been loaded, please be aware of possible side effects",name)
+ report()
+ if logs.pushtarget then
+ logs.pushtarget("log")
+ end
+ report("Plugins are not officially supported unless stated otherwise. This is because")
+ report("they bypass the regular font handling and therefore some features in ConTeXt")
+ report("(especially those related to fonts) might not work as expected or might not work")
+ report("at all. Some plugins are for testing and development only and might change")
+ report("whenever we feel the need for it.")
+ report()
+ if logs.poptarget then
+ logs.poptarget()
+ end
+ end
+end
+
+function otf.plugininitializer(tfmdata,value)
+ if type(value) == "string" then
+ tfmdata.shared.plugin = plugins[value]
+ end
+end
+
+function otf.pluginprocessor(head,font,attr,direction) -- n
+ local s = fontdata[font].shared
+ local p = s and s.plugin
+ if p then
+ if trace_plugins then
+ report_process("applying plugin %a",p[1])
+ end
+ return p[2](head,font,attr,direction)
+ else
+ return head, false
+ end
+end
+
+function otf.featuresinitializer(tfmdata,value)
+ -- nothing done here any more
+end
+
+registerotffeature {
+ name = "features",
+ description = "features",
+ default = true,
+ initializers = {
+ position = 1,
+ node = otf.featuresinitializer,
+ plug = otf.plugininitializer,
+ },
+ processors = {
+ node = otf.featuresprocessor,
+ plug = otf.pluginprocessor,
+ }
+}
+
+-- This can be used for extra handlers, but should be used with care! We implement one
+-- here but some more can be found in the osd (script devanagary) file. Now watch out:
+-- when a handlers has steps, it is called as the other ones, but when we have no steps,
+-- we use a different call:
+--
+-- function(head,dataset,sequence,initialrl,font,attr)
+-- return head, done
+-- end
+--
+-- Also see (!!).
+
+otf.handlers = handlers
+
+local setspacekerns = nodes.injections.setspacekerns if not setspacekerns then os.exit() end
+
+local tag = "kern" -- maybe some day a merge
+
+if fontfeatures then
+
+ function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr)
+ local features = fontfeatures[font]
+ local enabled = features and features.spacekern and features[tag]
+ if enabled then
+ setspacekerns(font,sequence)
+ end
+ return head, enabled
+ end
+
+else -- generic (no hashes)
+
+ function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr)
+ local shared = fontdata[font].shared
+ local features = shared and shared.features
+ local enabled = features and features.spacekern and features[tag]
+ if enabled then
+ setspacekerns(font,sequence)
+ end
+ return head, enabled
+ end
+
+end
+
+-- There are fonts out there that change the space but we don't do that kind of
+-- things in TeX.
+
+local function hasspacekerns(data)
+ local resources = data.resources
+ local sequences = resources.sequences
+ local validgpos = resources.features.gpos
+ if validgpos and sequences then
+ for i=1,#sequences do
+ local sequence = sequences[i]
+ local steps = sequence.steps
+ if steps and sequence.features[tag] then
+ local kind = sequence.type
+ if kind == "gpos_pair" or kind == "gpos_single" then
+ for i=1,#steps do
+ local step = steps[i]
+ local coverage = step.coverage
+ local rules = step.rules
+ if rules then
+ -- not now: analyze (simple) rules
+ elseif not coverage then
+ -- nothing to do
+ elseif kind == "gpos_single" then
+ -- maybe a message that we ignore
+ elseif kind == "gpos_pair" then
+ local format = step.format
+ if format == "move" or format == "kern" then
+ local kerns = coverage[32]
+ if kerns then
+ return true
+ end
+ for k, v in next, coverage do
+ if v[32] then
+ return true
+ end
+ end
+ elseif format == "pair" then
+ local kerns = coverage[32]
+ if kerns then
+ for k, v in next, kerns do
+ local one = v[1]
+ if one and one ~= true then
+ return true
+ end
+ end
+ end
+ for k, v in next, coverage do
+ local kern = v[32]
+ if kern then
+ local one = kern[1]
+ if one and one ~= true then
+ return true
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return false
+end
+
+otf.readers.registerextender {
+ name = "spacekerns",
+ action = function(data)
+ data.properties.hasspacekerns = hasspacekerns(data)
+ end
+}
+
+local function spaceinitializer(tfmdata,value) -- attr
+ local resources = tfmdata.resources
+ local spacekerns = resources and resources.spacekerns
+ if value and spacekerns == nil then
+ local rawdata = tfmdata.shared and tfmdata.shared.rawdata
+ local properties = rawdata.properties
+ if properties and properties.hasspacekerns then
+ local sequences = resources.sequences
+ local validgpos = resources.features.gpos
+ if validgpos and sequences then
+ local left = { }
+ local right = { }
+ local last = 0
+ local feat = nil
+ for i=1,#sequences do
+ local sequence = sequences[i]
+ local steps = sequence.steps
+ if steps then
+ -- we don't support space kerns in other features
+ local kern = sequence.features[tag]
+ if kern then
+ local kind = sequence.type
+ if kind == "gpos_pair" or kind == "gpos_single" then
+ if feat then
+ for script, languages in next, kern do
+ local f = feat[script]
+ if f then
+ for l in next, languages do
+ f[l] = true
+ end
+ else
+ feat[script] = languages
+ end
+ end
+ else
+ feat = kern
+ end
+ for i=1,#steps do
+ local step = steps[i]
+ local coverage = step.coverage
+ local rules = step.rules
+ if rules then
+ -- not now: analyze (simple) rules
+ elseif not coverage then
+ -- nothng to do
+ elseif kind == "gpos_single" then
+ -- makes no sense in TeX
+ elseif kind == "gpos_pair" then
+ local format = step.format
+ if format == "move" or format == "kern" then
+ local kerns = coverage[32]
+ if kerns then
+ for k, v in next, kerns do
+ right[k] = v
+ end
+ end
+ for k, v in next, coverage do
+ local kern = v[32]
+ if kern then
+ left[k] = kern
+ end
+ end
+ elseif format == "pair" then
+ local kerns = coverage[32]
+ if kerns then
+ for k, v in next, kerns do
+ local one = v[1]
+ if one and one ~= true then
+ right[k] = one[3]
+ end
+ end
+ end
+ for k, v in next, coverage do
+ local kern = v[32]
+ if kern then
+ local one = kern[1]
+ if one and one ~= true then
+ left[k] = one[3]
+ end
+ end
+ end
+ end
+ end
+ end
+ last = i
+ end
+ else
+ -- no steps ... needed for old one ... we could use the basekerns
+ -- instead
+ end
+ end
+ end
+ left = next(left) and left or false
+ right = next(right) and right or false
+ if left or right then
+ spacekerns = {
+ left = left,
+ right = right,
+ }
+ if last > 0 then
+ local triggersequence = {
+ -- no steps, see (!!)
+ features = { [tag] = feat or { dflt = { dflt = true, } } },
+ flags = noflags,
+ name = "trigger_space_kerns",
+ order = { tag },
+ type = "trigger_space_kerns",
+ left = left,
+ right = right,
+ }
+ insert(sequences,last,triggersequence)
+ end
+ end
+ end
+ end
+ resources.spacekerns = spacekerns
+ end
+ return spacekerns
+end
+
+registerotffeature {
+ name = "spacekern",
+ description = "space kern injection",
+ default = true,
+ initializers = {
+ node = spaceinitializer,
+ },
+}
+
+local function markinitializer(tfmdata,value)
+ local properties = tfmdata.properties
+ properties.checkmarks = value
+end
+
+registerotffeature {
+ name = "checkmarks",
+ description = "check mark widths",
+ default = true,
+ initializers = {
+ node = markinitializer,
+ },
+}
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ott.lua b/macros/luatex/generic/luaotfload/fontloader-font-ott.lua
new file mode 100644
index 0000000000..c9e467f225
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ott.lua
@@ -0,0 +1,1234 @@
+if not modules then modules = { } end modules ["font-ott"] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+ -- dataonly = true,
+}
+
+local type, next, tonumber, tostring, rawget, rawset = type, next, tonumber, tostring, rawget, rawset
+local gsub, lower, format, match, gmatch, find = string.gsub, string.lower, string.format, string.match, string.gmatch, string.find
+local sequenced = table.sequenced
+local is_boolean = string.is_boolean
+
+local setmetatableindex = table.setmetatableindex
+local setmetatablenewindex = table.setmetatablenewindex
+local allocate = utilities.storage.allocate
+
+local fonts = fonts
+local otf = fonts.handlers.otf
+local otffeatures = otf.features
+
+local tables = otf.tables or { }
+otf.tables = tables
+
+local statistics = otf.statistics or { }
+otf.statistics = statistics
+
+local scripts = allocate {
+ ["adlm"] = "adlam",
+ ["aghb"] = "caucasian albanian",
+ ["ahom"] = "ahom",
+ ["arab"] = "arabic",
+ ["armi"] = "imperial aramaic",
+ ["armn"] = "armenian",
+ ["avst"] = "avestan",
+ ["bali"] = "balinese",
+ ["bamu"] = "bamum",
+ ["bass"] = "bassa vah",
+ ["batk"] = "batak",
+ ["beng"] = "bengali",
+ ["bhks"] = "bhaiksuki",
+ ["bng2"] = "bengali variant 2",
+ ["bopo"] = "bopomofo",
+ ["brah"] = "brahmi",
+ ["brai"] = "braille",
+ ["bugi"] = "buginese",
+ ["buhd"] = "buhid",
+ ["byzm"] = "byzantine music",
+ ["cakm"] = "chakma",
+ ["cans"] = "canadian syllabics",
+ ["cari"] = "carian",
+ ["cham"] = "cham",
+ ["cher"] = "cherokee",
+ ["copt"] = "coptic",
+ ["cprt"] = "cypriot syllabary",
+ ["cyrl"] = "cyrillic",
+ ["dev2"] = "devanagari variant 2",
+ ["deva"] = "devanagari",
+ ["dogr"] = "dogra",
+ ["dsrt"] = "deseret",
+ ["dupl"] = "duployan",
+ ["egyp"] = "egyptian heiroglyphs",
+ ["elba"] = "elbasan",
+ ["ethi"] = "ethiopic",
+ ["geor"] = "georgian",
+ ["gjr2"] = "gujarati variant 2",
+ ["glag"] = "glagolitic",
+ ["gong"] = "gunjala gondi",
+ ["gonm"] = "masaram gondi",
+ ["goth"] = "gothic",
+ ["gran"] = "grantha",
+ ["grek"] = "greek",
+ ["gujr"] = "gujarati",
+ ["gur2"] = "gurmukhi variant 2",
+ ["guru"] = "gurmukhi",
+ ["hang"] = "hangul",
+ ["hani"] = "cjk ideographic",
+ ["hano"] = "hanunoo",
+ ["hatr"] = "hatran",
+ ["hebr"] = "hebrew",
+ ["hluw"] = "anatolian hieroglyphs",
+ ["hmng"] = "pahawh hmong",
+ ["hung"] = "old hungarian",
+ ["ital"] = "old italic",
+ ["jamo"] = "hangul jamo",
+ ["java"] = "javanese",
+ ["kali"] = "kayah li",
+ ["kana"] = "hiragana and katakana",
+ ["khar"] = "kharosthi",
+ ["khmr"] = "khmer",
+ ["khoj"] = "khojki",
+ ["knd2"] = "kannada variant 2",
+ ["knda"] = "kannada",
+ ["kthi"] = "kaithi",
+ ["lana"] = "tai tham",
+ ["lao" ] = "lao",
+ ["latn"] = "latin",
+ ["lepc"] = "lepcha",
+ ["limb"] = "limbu",
+ ["lina"] = "linear a",
+ ["linb"] = "linear b",
+ ["lisu"] = "lisu",
+ ["lyci"] = "lycian",
+ ["lydi"] = "lydian",
+ ["mahj"] = "mahajani",
+ ["maka"] = "makasar",
+ ["mand"] = "mandaic and mandaean",
+ ["mani"] = "manichaean",
+ ["marc"] = "marchen",
+ ["math"] = "mathematical alphanumeric symbols",
+ ["medf"] = "medefaidrin",
+ ["mend"] = "mende kikakui",
+ ["merc"] = "meroitic cursive",
+ ["mero"] = "meroitic hieroglyphs",
+ ["mlm2"] = "malayalam variant 2",
+ ["mlym"] = "malayalam",
+ ["modi"] = "modi",
+ ["mong"] = "mongolian",
+ ["mroo"] = "mro",
+ ["mtei"] = "meitei Mayek",
+ ["mult"] = "multani",
+ ["musc"] = "musical symbols",
+ ["mym2"] = "myanmar variant 2",
+ ["mymr"] = "myanmar",
+ ["narb"] = "old north arabian",
+ ["nbat"] = "nabataean",
+ ["newa"] = "newa",
+ ["nko" ] = 'n"ko',
+ ["nshu"] = "nüshu",
+ ["ogam"] = "ogham",
+ ["olck"] = "ol chiki",
+ ["orkh"] = "old turkic and orkhon runic",
+ ["ory2"] = "odia variant 2",
+ ["orya"] = "oriya",
+ ["osge"] = "osage",
+ ["osma"] = "osmanya",
+ ["palm"] = "palmyrene",
+ ["pauc"] = "pau cin hau",
+ ["perm"] = "old permic",
+ ["phag"] = "phags-pa",
+ ["phli"] = "inscriptional pahlavi",
+ ["phlp"] = "psalter pahlavi",
+ ["phnx"] = "phoenician",
+ ["plrd"] = "miao",
+ ["prti"] = "inscriptional parthian",
+ ["rjng"] = "rejang",
+ ["rohg"] = "hanifi rohingya",
+ ["runr"] = "runic",
+ ["samr"] = "samaritan",
+ ["sarb"] = "old south arabian",
+ ["saur"] = "saurashtra",
+ ["sgnw"] = "sign writing",
+ ["shaw"] = "shavian",
+ ["shrd"] = "sharada",
+ ["sidd"] = "siddham",
+ ["sind"] = "khudawadi",
+ ["sinh"] = "sinhala",
+ ["sogd"] = "sogdian",
+ ["sogo"] = "old sogdian",
+ ["sora"] = "sora sompeng",
+ ["soyo"] = "soyombo",
+ ["sund"] = "sundanese",
+ ["sylo"] = "syloti nagri",
+ ["syrc"] = "syriac",
+ ["tagb"] = "tagbanwa",
+ ["takr"] = "takri",
+ ["tale"] = "tai le",
+ ["talu"] = "tai lu",
+ ["taml"] = "tamil",
+ ["tang"] = "tangut",
+ ["tavt"] = "tai viet",
+ ["tel2"] = "telugu variant 2",
+ ["telu"] = "telugu",
+ ["tfng"] = "tifinagh",
+ ["tglg"] = "tagalog",
+ ["thaa"] = "thaana",
+ ["thai"] = "thai",
+ ["tibt"] = "tibetan",
+ ["tirh"] = "tirhuta",
+ ["tml2"] = "tamil variant 2",
+ ["ugar"] = "ugaritic cuneiform",
+ ["vai" ] = "vai",
+ ["wara"] = "warang citi",
+ ["xpeo"] = "old persian cuneiform",
+ ["xsux"] = "sumero-akkadian cuneiform",
+ ["yi" ] = "yi",
+ ["zanb"] = "zanabazar square",
+}
+
+local languages = allocate {
+ ["aba" ] = "abaza",
+ ["abk" ] = "abkhazian",
+ ["ach" ] = "acholi",
+ ["acr" ] = "achi",
+ ["ady" ] = "adyghe",
+ ["afk" ] = "afrikaans",
+ ["afr" ] = "afar",
+ ["agw" ] = "agaw",
+ ["aio" ] = "aiton",
+ ["aka" ] = "akan",
+ ["als" ] = "alsatian",
+ ["alt" ] = "altai",
+ ["amh" ] = "amharic",
+ ["ang" ] = "anglo-saxon",
+ ["apph"] = "phonetic transcription—americanist conventions",
+ ["ara" ] = "arabic",
+ ["arg" ] = "aragonese",
+ ["ari" ] = "aari",
+ ["ark" ] = "rakhine",
+ ["asm" ] = "assamese",
+ ["ast" ] = "asturian",
+ ["ath" ] = "athapaskan",
+ ["avr" ] = "avar",
+ ["awa" ] = "awadhi",
+ ["aym" ] = "aymara",
+ ["azb" ] = "torki",
+ ["aze" ] = "azerbaijani",
+ ["bad" ] = "badaga",
+ ["bad0"] = "banda",
+ ["bag" ] = "baghelkhandi",
+ ["bal" ] = "balkar",
+ ["ban" ] = "balinese",
+ ["bar" ] = "bavarian",
+ ["bau" ] = "baulé",
+ ["bbc" ] = "batak toba",
+ ["bbr" ] = "berber",
+ ["bch" ] = "bench",
+ ["bcr" ] = "bible cree",
+ ["bdy" ] = "bandjalang",
+ ["bel" ] = "belarussian",
+ ["bem" ] = "bemba",
+ ["ben" ] = "bengali",
+ ["bgc" ] = "haryanvi",
+ ["bgq" ] = "bagri",
+ ["bgr" ] = "bulgarian",
+ ["bhi" ] = "bhili",
+ ["bho" ] = "bhojpuri",
+ ["bik" ] = "bikol",
+ ["bil" ] = "bilen",
+ ["bis" ] = "bislama",
+ ["bjj" ] = "kanauji",
+ ["bkf" ] = "blackfoot",
+ ["bli" ] = "baluchi",
+ ["blk" ] = "pa'o karen",
+ ["bln" ] = "balante",
+ ["blt" ] = "balti",
+ ["bmb" ] = "bambara (bamanankan)",
+ ["bml" ] = "bamileke",
+ ["bos" ] = "bosnian",
+ ["bpy" ] = "bishnupriya manipuri",
+ ["bre" ] = "breton",
+ ["brh" ] = "brahui",
+ ["bri" ] = "braj bhasha",
+ ["brm" ] = "burmese",
+ ["brx" ] = "bodo",
+ ["bsh" ] = "bashkir",
+ ["bsk" ] = "burushaski",
+ ["bti" ] = "beti",
+ ["bts" ] = "batak simalungun",
+ ["bug" ] = "bugis",
+ ["byv" ] = "medumba",
+ ["cak" ] = "kaqchikel",
+ ["cat" ] = "catalan",
+ ["cbk" ] = "zamboanga chavacano",
+ ["cchn"] = "chinantec",
+ ["ceb" ] = "cebuano",
+ ["cgg" ] = "chiga",
+ ["cha" ] = "chamorro",
+ ["che" ] = "chechen",
+ ["chg" ] = "chaha gurage",
+ ["chh" ] = "chattisgarhi",
+ ["chi" ] = "chichewa (chewa, nyanja)",
+ ["chk" ] = "chukchi",
+ ["chk0"] = "chuukese",
+ ["cho" ] = "choctaw",
+ ["chp" ] = "chipewyan",
+ ["chr" ] = "cherokee",
+ ["chu" ] = "chuvash",
+ ["chy" ] = "cheyenne",
+ ["cja" ] = "western cham",
+ ["cjm" ] = "eastern cham",
+ ["cmr" ] = "comorian",
+ ["cop" ] = "coptic",
+ ["cor" ] = "cornish",
+ ["cos" ] = "corsican",
+ ["cpp" ] = "creoles",
+ ["cre" ] = "cree",
+ ["crr" ] = "carrier",
+ ["crt" ] = "crimean tatar",
+ ["csb" ] = "kashubian",
+ ["csl" ] = "church slavonic",
+ ["csy" ] = "czech",
+ ["ctg" ] = "chittagonian",
+ ["cuk" ] = "san blas kuna",
+ ["dan" ] = "danish",
+ ["dar" ] = "dargwa",
+ ["dax" ] = "dayi",
+ ["dcr" ] = "woods cree",
+ ["deu" ] = "german",
+ ["dgo" ] = "dogri",
+ ["dgr" ] = "dogri",
+ ["dhg" ] = "dhangu",
+ ["dhv" ] = "divehi (dhivehi, maldivian)",
+ ["diq" ] = "dimli",
+ ["div" ] = "divehi (dhivehi, maldivian)",
+ ["djr" ] = "zarma",
+ ["djr0"] = "djambarrpuyngu",
+ ["dng" ] = "dangme",
+ ["dnj" ] = "dan",
+ ["dnk" ] = "dinka",
+ ["dri" ] = "dari",
+ ["duj" ] = "dhuwal",
+ ["dun" ] = "dungan",
+ ["dzn" ] = "dzongkha",
+ ["ebi" ] = "ebira",
+ ["ecr" ] = "eastern cree",
+ ["edo" ] = "edo",
+ ["efi" ] = "efik",
+ ["ell" ] = "greek",
+ ["emk" ] = "eastern maninkakan",
+ ["eng" ] = "english",
+ ["erz" ] = "erzya",
+ ["esp" ] = "spanish",
+ ["esu" ] = "central yupik",
+ ["eti" ] = "estonian",
+ ["euq" ] = "basque",
+ ["evk" ] = "evenki",
+ ["evn" ] = "even",
+ ["ewe" ] = "ewe",
+ ["fan" ] = "french antillean",
+ ["fan0"] = " fang",
+ ["far" ] = "persian",
+ ["fat" ] = "fanti",
+ ["fin" ] = "finnish",
+ ["fji" ] = "fijian",
+ ["fle" ] = "dutch (flemish)",
+ ["fmp" ] = "fe’fe’",
+ ["fne" ] = "forest nenets",
+ ["fon" ] = "fon",
+ ["fos" ] = "faroese",
+ ["fra" ] = "french",
+ ["frc" ] = "cajun french",
+ ["fri" ] = "frisian",
+ ["frl" ] = "friulian",
+ ["frp" ] = "arpitan",
+ ["fta" ] = "futa",
+ ["ful" ] = "fulah",
+ ["fuv" ] = "nigerian fulfulde",
+ ["gad" ] = "ga",
+ ["gae" ] = "scottish gaelic (gaelic)",
+ ["gag" ] = "gagauz",
+ ["gal" ] = "galician",
+ ["gar" ] = "garshuni",
+ ["gaw" ] = "garhwali",
+ ["gez" ] = "ge'ez",
+ ["gih" ] = "githabul",
+ ["gil" ] = "gilyak",
+ ["gil0"] = "kiribati (gilbertese)",
+ ["gkp" ] = "kpelle (guinea)",
+ ["glk" ] = "gilaki",
+ ["gmz" ] = "gumuz",
+ ["gnn" ] = "gumatj",
+ ["gog" ] = "gogo",
+ ["gon" ] = "gondi",
+ ["grn" ] = "greenlandic",
+ ["gro" ] = "garo",
+ ["gua" ] = "guarani",
+ ["guc" ] = "wayuu",
+ ["guf" ] = "gupapuyngu",
+ ["guj" ] = "gujarati",
+ ["guz" ] = "gusii",
+ ["hai" ] = "haitian (haitian creole)",
+ ["hal" ] = "halam",
+ ["har" ] = "harauti",
+ ["hau" ] = "hausa",
+ ["haw" ] = "hawaiian",
+ ["hay" ] = "haya",
+ ["haz" ] = "hazaragi",
+ ["hbn" ] = "hammer-banna",
+ ["her" ] = "herero",
+ ["hil" ] = "hiligaynon",
+ ["hin" ] = "hindi",
+ ["hma" ] = "high mari",
+ ["hmn" ] = "hmong",
+ ["hmo" ] = "hiri motu",
+ ["hnd" ] = "hindko",
+ ["ho" ] = "ho",
+ ["hri" ] = "harari",
+ ["hrv" ] = "croatian",
+ ["hun" ] = "hungarian",
+ ["hye" ] = "armenian",
+ ["hye0"] = "armenian east",
+ ["iba" ] = "iban",
+ ["ibb" ] = "ibibio",
+ ["ibo" ] = "igbo",
+ ["ido" ] = "ido",
+ ["ijo" ] = "ijo languages",
+ ["ile" ] = "interlingue",
+ ["ilo" ] = "ilokano",
+ ["ina" ] = "interlingua",
+ ["ind" ] = "indonesian",
+ ["ing" ] = "ingush",
+ ["inu" ] = "inuktitut",
+ ["ipk" ] = "inupiat",
+ ["ipph"] = "phonetic transcription—ipa conventions",
+ ["iri" ] = "irish",
+ ["irt" ] = "irish traditional",
+ ["isl" ] = "icelandic",
+ ["ism" ] = "inari sami",
+ ["ita" ] = "italian",
+ ["iwr" ] = "hebrew",
+ ["jam" ] = "jamaican creole",
+ ["jan" ] = "japanese",
+ ["jav" ] = "javanese",
+ ["jbo" ] = "lojban",
+ ["jct" ] = "krymchak",
+ ["jii" ] = "yiddish",
+ ["jud" ] = "ladino",
+ ["jul" ] = "jula",
+ ["kab" ] = "kabardian",
+ ["kab0"] = "kabyle",
+ ["kac" ] = "kachchi",
+ ["kal" ] = "kalenjin",
+ ["kan" ] = "kannada",
+ ["kar" ] = "karachay",
+ ["kat" ] = "georgian",
+ ["kaz" ] = "kazakh",
+ ["kde" ] = "makonde",
+ ["kea" ] = "kabuverdianu (crioulo)",
+ ["keb" ] = "kebena",
+ ["kek" ] = "kekchi",
+ ["kge" ] = "khutsuri georgian",
+ ["kha" ] = "khakass",
+ ["khk" ] = "khanty-kazim",
+ ["khm" ] = "khmer",
+ ["khs" ] = "khanty-shurishkar",
+ ["kht" ] = "khamti shan",
+ ["khv" ] = "khanty-vakhi",
+ ["khw" ] = "khowar",
+ ["kik" ] = "kikuyu (gikuyu)",
+ ["kir" ] = "kirghiz (kyrgyz)",
+ ["kis" ] = "kisii",
+ ["kiu" ] = "kirmanjki",
+ ["kjd" ] = "southern kiwai",
+ ["kjp" ] = "eastern pwo karen",
+ ["kjz" ] = "bumthangkha",
+ ["kkn" ] = "kokni",
+ ["klm" ] = "kalmyk",
+ ["kmb" ] = "kamba",
+ ["kmn" ] = "kumaoni",
+ ["kmo" ] = "komo",
+ ["kms" ] = "komso",
+ ["kmz" ] = "khorasani turkic",
+ ["knr" ] = "kanuri",
+ ["kod" ] = "kodagu",
+ ["koh" ] = "korean old hangul",
+ ["kok" ] = "konkani",
+ ["kom" ] = "komi",
+ ["kon" ] = "kikongo",
+ ["kon0"] = "kongo",
+ ["kop" ] = "komi-permyak",
+ ["kor" ] = "korean",
+ ["kos" ] = "kosraean",
+ ["koz" ] = "komi-zyrian",
+ ["kpl" ] = "kpelle",
+ ["kri" ] = "krio",
+ ["krk" ] = "karakalpak",
+ ["krl" ] = "karelian",
+ ["krm" ] = "karaim",
+ ["krn" ] = "karen",
+ ["krt" ] = "koorete",
+ ["ksh" ] = "kashmiri",
+ ["ksh0"] = "ripuarian",
+ ["ksi" ] = "khasi",
+ ["ksm" ] = "kildin sami",
+ ["ksw" ] = "s’gaw karen",
+ ["kua" ] = "kuanyama",
+ ["kui" ] = "kui",
+ ["kul" ] = "kulvi",
+ ["kum" ] = "kumyk",
+ ["kur" ] = "kurdish",
+ ["kuu" ] = "kurukh",
+ ["kuy" ] = "kuy",
+ ["kyk" ] = "koryak",
+ ["kyu" ] = "western kayah",
+ ["lad" ] = "ladin",
+ ["lah" ] = "lahuli",
+ ["lak" ] = "lak",
+ ["lam" ] = "lambani",
+ ["lao" ] = "lao",
+ ["lat" ] = "latin",
+ ["laz" ] = "laz",
+ ["lcr" ] = "l-cree",
+ ["ldk" ] = "ladakhi",
+ ["lez" ] = "lezgi",
+ ["lij" ] = "ligurian",
+ ["lim" ] = "limburgish",
+ ["lin" ] = "lingala",
+ ["lis" ] = "lisu",
+ ["ljp" ] = "lampung",
+ ["lki" ] = "laki",
+ ["lma" ] = "low mari",
+ ["lmb" ] = "limbu",
+ ["lmo" ] = "lombard",
+ ["lmw" ] = "lomwe",
+ ["lom" ] = "loma",
+ ["lrc" ] = "luri",
+ ["lsb" ] = "lower sorbian",
+ ["lsm" ] = "lule sami",
+ ["lth" ] = "lithuanian",
+ ["ltz" ] = "luxembourgish",
+ ["lua" ] = "luba-lulua",
+ ["lub" ] = "luba-katanga",
+ ["lug" ] = "ganda",
+ ["luh" ] = "luyia",
+ ["luo" ] = "luo",
+ ["lvi" ] = "latvian",
+ ["mad" ] = "madura",
+ ["mag" ] = "magahi",
+ ["mah" ] = "marshallese",
+ ["maj" ] = "majang",
+ ["mak" ] = "makhuwa",
+ ["mal" ] = "malayalam reformed",
+ ["mam" ] = "mam",
+ ["man" ] = "mansi",
+ ["map" ] = "mapudungun",
+ ["mar" ] = "marathi",
+ ["maw" ] = "marwari",
+ ["mbn" ] = "mbundu",
+ ["mbo" ] = "mbo",
+ ["mch" ] = "manchu",
+ ["mcr" ] = "moose cree",
+ ["mde" ] = "mende",
+ ["mdr" ] = "mandar",
+ ["men" ] = "me'en",
+ ["mer" ] = "meru",
+ ["mfa" ] = "pattani malay",
+ ["mfe" ] = "morisyen",
+ ["min" ] = "minangkabau",
+ ["miz" ] = "mizo",
+ ["mkd" ] = "macedonian",
+ ["mkr" ] = "makasar",
+ ["mkw" ] = "kituba",
+ ["mle" ] = "male",
+ ["mlg" ] = "malagasy",
+ ["mln" ] = "malinke",
+ ["mlr" ] = "malayalam reformed",
+ ["mly" ] = "malay",
+ ["mnd" ] = "mandinka",
+ ["mng" ] = "mongolian",
+ ["mni" ] = "manipuri",
+ ["mnk" ] = "maninka",
+ ["mnx" ] = "manx",
+ ["moh" ] = "mohawk",
+ ["mok" ] = "moksha",
+ ["mol" ] = "moldavian",
+ ["mon" ] = "mon",
+ ["mor" ] = "moroccan",
+ ["mos" ] = "mossi",
+ ["mri" ] = "maori",
+ ["mth" ] = "maithili",
+ ["mts" ] = "maltese",
+ ["mun" ] = "mundari",
+ ["mus" ] = "muscogee",
+ ["mwl" ] = "mirandese",
+ ["mww" ] = "hmong daw",
+ ["myn" ] = "mayan",
+ ["mzn" ] = "mazanderani",
+ ["nag" ] = "naga-assamese",
+ ["nah" ] = "nahuatl",
+ ["nan" ] = "nanai",
+ ["nap" ] = "neapolitan",
+ ["nas" ] = "naskapi",
+ ["nau" ] = "nauruan",
+ ["nav" ] = "navajo",
+ ["ncr" ] = "n-cree",
+ ["ndb" ] = "ndebele",
+ ["ndc" ] = "ndau",
+ ["ndg" ] = "ndonga",
+ ["nds" ] = "low saxon",
+ ["nep" ] = "nepali",
+ ["new" ] = "newari",
+ ["nga" ] = "ngbaka",
+ ["ngr" ] = "nagari",
+ ["nhc" ] = "norway house cree",
+ ["nis" ] = "nisi",
+ ["niu" ] = "niuean",
+ ["nkl" ] = "nyankole",
+ ["nko" ] = "n'ko",
+ ["nld" ] = "dutch",
+ ["noe" ] = "nimadi",
+ ["nog" ] = "nogai",
+ ["nor" ] = "norwegian",
+ ["nov" ] = "novial",
+ ["nsm" ] = "northern sami",
+ ["nso" ] = "sotho, northern",
+ ["nta" ] = "northern tai",
+ ["nto" ] = "esperanto",
+ ["nym" ] = "nyamwezi",
+ ["nyn" ] = "norwegian nynorsk",
+ ["nza" ] = "mbembe tigon",
+ ["oci" ] = "occitan",
+ ["ocr" ] = "oji-cree",
+ ["ojb" ] = "ojibway",
+ ["ori" ] = "odia",
+ ["oro" ] = "oromo",
+ ["oss" ] = "ossetian",
+ ["paa" ] = "palestinian aramaic",
+ ["pag" ] = "pangasinan",
+ ["pal" ] = "pali",
+ ["pam" ] = "pampangan",
+ ["pan" ] = "punjabi",
+ ["pap" ] = "palpa",
+ ["pap0"] = "papiamentu",
+ ["pas" ] = "pashto",
+ ["pau" ] = "palauan",
+ ["pcc" ] = "bouyei",
+ ["pcd" ] = "picard",
+ ["pdc" ] = "pennsylvania german",
+ ["pgr" ] = "polytonic greek",
+ ["phk" ] = "phake",
+ ["pih" ] = "norfolk",
+ ["pil" ] = "filipino",
+ ["plg" ] = "palaung",
+ ["plk" ] = "polish",
+ ["pms" ] = "piemontese",
+ ["pnb" ] = "western panjabi",
+ ["poh" ] = "pocomchi",
+ ["pon" ] = "pohnpeian",
+ ["pro" ] = "provencal",
+ ["ptg" ] = "portuguese",
+ ["pwo" ] = "western pwo karen",
+ ["qin" ] = "chin",
+ ["quc" ] = "k’iche’",
+ ["quh" ] = "quechua (bolivia)",
+ ["quz" ] = "quechua",
+ ["qvi" ] = "quechua (ecuador)",
+ ["qwh" ] = "quechua (peru)",
+ ["raj" ] = "rajasthani",
+ ["rar" ] = "rarotongan",
+ ["rbu" ] = "russian buriat",
+ ["rcr" ] = "r-cree",
+ ["rej" ] = "rejang",
+ ["ria" ] = "riang",
+ ["rif" ] = "tarifit",
+ ["rit" ] = "ritarungo",
+ ["rkw" ] = "arakwal",
+ ["rms" ] = "romansh",
+ ["rmy" ] = "vlax romani",
+ ["rom" ] = "romanian",
+ ["roy" ] = "romany",
+ ["rsy" ] = "rusyn",
+ ["rtm" ] = "rotuman",
+ ["rua" ] = "kinyarwanda",
+ ["run" ] = "rundi",
+ ["rup" ] = "aromanian",
+ ["rus" ] = "russian",
+ ["sad" ] = "sadri",
+ ["san" ] = "sanskrit",
+ ["sas" ] = "sasak",
+ ["sat" ] = "santali",
+ ["say" ] = "sayisi",
+ ["scn" ] = "sicilian",
+ ["sco" ] = "scots",
+ ["scs" ] = "north slavey",
+ ["sek" ] = "sekota",
+ ["sel" ] = "selkup",
+ ["sga" ] = "old irish",
+ ["sgo" ] = "sango",
+ ["sgs" ] = "samogitian",
+ ["shi" ] = "tachelhit",
+ ["shn" ] = "shan",
+ ["sib" ] = "sibe",
+ ["sid" ] = "sidamo",
+ ["sig" ] = "silte gurage",
+ ["sks" ] = "skolt sami",
+ ["sky" ] = "slovak",
+ ["sla" ] = "slavey",
+ ["slv" ] = "slovenian",
+ ["sml" ] = "somali",
+ ["smo" ] = "samoan",
+ ["sna" ] = "sena",
+ ["sna0"] = "shona",
+ ["snd" ] = "sindhi",
+ ["snh" ] = "sinhala (sinhalese)",
+ ["snk" ] = "soninke",
+ ["sog" ] = "sodo gurage",
+ ["sop" ] = "songe",
+ ["sot" ] = "sotho, southern",
+ ["sqi" ] = "albanian",
+ ["srb" ] = "serbian",
+ ["srd" ] = "sardinian",
+ ["srk" ] = "saraiki",
+ ["srr" ] = "serer",
+ ["ssl" ] = "south slavey",
+ ["ssm" ] = "southern sami",
+ ["stq" ] = "saterland frisian",
+ ["suk" ] = "sukuma",
+ ["sun" ] = "sundanese",
+ ["sur" ] = "suri",
+ ["sva" ] = "svan",
+ ["sve" ] = "swedish",
+ ["swa" ] = "swadaya aramaic",
+ ["swk" ] = "swahili",
+ ["swz" ] = "swati",
+ ["sxt" ] = "sutu",
+ ["sxu" ] = "upper saxon",
+ ["syl" ] = "sylheti",
+ ["syr" ] = "syriac",
+ ["syre"] = "estrangela syriac",
+ ["syrj"] = "western syriac",
+ ["syrn"] = "eastern syriac",
+ ["szl" ] = "silesian",
+ ["tab" ] = "tabasaran",
+ ["taj" ] = "tajiki",
+ ["tam" ] = "tamil",
+ ["tat" ] = "tatar",
+ ["tcr" ] = "th-cree",
+ ["tdd" ] = "dehong dai",
+ ["tel" ] = "telugu",
+ ["tet" ] = "tetum",
+ ["tgl" ] = "tagalog",
+ ["tgn" ] = "tongan",
+ ["tgr" ] = "tigre",
+ ["tgy" ] = "tigrinya",
+ ["tha" ] = "thai",
+ ["tht" ] = "tahitian",
+ ["tib" ] = "tibetan",
+ ["tiv" ] = "tiv",
+ ["tkm" ] = "turkmen",
+ ["tmh" ] = "tamashek",
+ ["tmn" ] = "temne",
+ ["tna" ] = "tswana",
+ ["tne" ] = "tundra nenets",
+ ["tng" ] = "tonga",
+ ["tod" ] = "todo",
+ ["tod0"] = "toma",
+ ["tpi" ] = "tok pisin",
+ ["trk" ] = "turkish",
+ ["tsg" ] = "tsonga",
+ ["tsj" ] = "tshangla",
+ ["tua" ] = "turoyo aramaic",
+ ["tul" ] = "tulu",
+ ["tum" ] = "tulu",
+ ["tuv" ] = "tuvin",
+ ["tvl" ] = "tuvalu",
+ ["twi" ] = "twi",
+ ["tyz" ] = "tày",
+ ["tzm" ] = "tamazight",
+ ["tzo" ] = "tzotzil",
+ ["udm" ] = "udmurt",
+ ["ukr" ] = "ukrainian",
+ ["umb" ] = "umbundu",
+ ["urd" ] = "urdu",
+ ["usb" ] = "upper sorbian",
+ ["uyg" ] = "uyghur",
+ ["uzb" ] = "uzbek",
+ ["vec" ] = "venetian",
+ ["ven" ] = "venda",
+ ["vit" ] = "vietnamese",
+ ["vol" ] = "volapük",
+ ["vro" ] = "võro",
+ ["wa" ] = "wa",
+ ["wag" ] = "wagdi",
+ ["war" ] = "waray-waray",
+ ["wcr" ] = "west-cree",
+ ["wel" ] = "welsh",
+ ["wlf" ] = "wolof",
+ ["wln" ] = "walloon",
+ ["wtm" ] = "mewati",
+ ["xbd" ] = "lü",
+ ["xhs" ] = "xhosa",
+ ["xjb" ] = "minjangbal",
+ ["xkf" ] = "khengkha",
+ ["xog" ] = "soga",
+ ["xpe" ] = "kpelle (liberia)",
+ ["yak" ] = "sakha",
+ ["yao" ] = "yao",
+ ["yap" ] = "yapese",
+ ["yba" ] = "yoruba",
+ ["ycr" ] = "y-cree",
+ ["yic" ] = "yi classic",
+ ["yim" ] = "yi modern",
+ ["zea" ] = "zealandic",
+ ["zgh" ] = "standard morrocan tamazigh",
+ ["zha" ] = "zhuang",
+ ["zhh" ] = "chinese, hong kong sar",
+ ["zhp" ] = "chinese phonetic",
+ ["zhs" ] = "chinese simplified",
+ ["zht" ] = "chinese traditional",
+ ["znd" ] = "zande",
+ ["zul" ] = "zulu",
+ ["zza" ] = "zazaki",
+}
+
+
+local features = allocate {
+ ["aalt"] = "access all alternates",
+ ["abvf"] = "above-base forms",
+ ["abvm"] = "above-base mark positioning",
+ ["abvs"] = "above-base substitutions",
+ ["afrc"] = "alternative fractions",
+ ["akhn"] = "akhands",
+ ["blwf"] = "below-base forms",
+ ["blwm"] = "below-base mark positioning",
+ ["blws"] = "below-base substitutions",
+ ["c2pc"] = "petite capitals from capitals",
+ ["c2sc"] = "small capitals from capitals",
+ ["calt"] = "contextual alternates",
+ ["case"] = "case-sensitive forms",
+ ["ccmp"] = "glyph composition/decomposition",
+ ["cfar"] = "conjunct form after ro",
+ ["cjct"] = "conjunct forms",
+ ["clig"] = "contextual ligatures",
+ ["cpct"] = "centered cjk punctuation",
+ ["cpsp"] = "capital spacing",
+ ["cswh"] = "contextual swash",
+ ["curs"] = "cursive positioning",
+ ["dflt"] = "default processing",
+ ["dist"] = "distances",
+ ["dlig"] = "discretionary ligatures",
+ ["dnom"] = "denominators",
+ ["dtls"] = "dotless forms", -- math
+ ["expt"] = "expert forms",
+ ["falt"] = "final glyph alternates",
+ ["fin2"] = "terminal forms #2",
+ ["fin3"] = "terminal forms #3",
+ ["fina"] = "terminal forms",
+ ["flac"] = "flattened accents over capitals", -- math
+ ["frac"] = "fractions",
+ ["fwid"] = "full width",
+ ["half"] = "half forms",
+ ["haln"] = "halant forms",
+ ["halt"] = "alternate half width",
+ ["hist"] = "historical forms",
+ ["hkna"] = "horizontal kana alternates",
+ ["hlig"] = "historical ligatures",
+ ["hngl"] = "hangul",
+ ["hojo"] = "hojo kanji forms",
+ ["hwid"] = "half width",
+ ["init"] = "initial forms",
+ ["isol"] = "isolated forms",
+ ["ital"] = "italics",
+ ["jalt"] = "justification alternatives",
+ ["jp04"] = "jis2004 forms",
+ ["jp78"] = "jis78 forms",
+ ["jp83"] = "jis83 forms",
+ ["jp90"] = "jis90 forms",
+ ["kern"] = "kerning",
+ ["lfbd"] = "left bounds",
+ ["liga"] = "standard ligatures",
+ ["ljmo"] = "leading jamo forms",
+ ["lnum"] = "lining figures",
+ ["locl"] = "localized forms",
+ ["ltra"] = "left-to-right alternates",
+ ["ltrm"] = "left-to-right mirrored forms",
+ ["mark"] = "mark positioning",
+ ["med2"] = "medial forms #2",
+ ["medi"] = "medial forms",
+ ["mgrk"] = "mathematical greek",
+ ["mkmk"] = "mark to mark positioning",
+ ["mset"] = "mark positioning via substitution",
+ ["nalt"] = "alternate annotation forms",
+ ["nlck"] = "nlc kanji forms",
+ ["nukt"] = "nukta forms",
+ ["numr"] = "numerators",
+ ["onum"] = "old style figures",
+ ["opbd"] = "optical bounds",
+ ["ordn"] = "ordinals",
+ ["ornm"] = "ornaments",
+ ["palt"] = "proportional alternate width",
+ ["pcap"] = "petite capitals",
+ ["pkna"] = "proportional kana",
+ ["pnum"] = "proportional figures",
+ ["pref"] = "pre-base forms",
+ ["pres"] = "pre-base substitutions",
+ ["pstf"] = "post-base forms",
+ ["psts"] = "post-base substitutions",
+ ["pwid"] = "proportional widths",
+ ["qwid"] = "quarter widths",
+ ["rand"] = "randomize",
+ ["rclt"] = "required contextual alternates",
+ ["rkrf"] = "rakar forms",
+ ["rlig"] = "required ligatures",
+ ["rphf"] = "reph form",
+ ["rtbd"] = "right bounds",
+ ["rtla"] = "right-to-left alternates",
+ ["rtlm"] = "right to left mirrored forms",
+ ["rvrn"] = "required variation alternates",
+ ["ruby"] = "ruby notation forms",
+ ["salt"] = "stylistic alternates",
+ ["sinf"] = "scientific inferiors",
+ ["size"] = "optical size", -- now stat table
+ ["smcp"] = "small capitals",
+ ["smpl"] = "simplified forms",
+ -- ["ss01"] = "stylistic set 1",
+ -- ["ss02"] = "stylistic set 2",
+ -- ["ss03"] = "stylistic set 3",
+ -- ["ss04"] = "stylistic set 4",
+ -- ["ss05"] = "stylistic set 5",
+ -- ["ss06"] = "stylistic set 6",
+ -- ["ss07"] = "stylistic set 7",
+ -- ["ss08"] = "stylistic set 8",
+ -- ["ss09"] = "stylistic set 9",
+ -- ["ss10"] = "stylistic set 10",
+ -- ["ss11"] = "stylistic set 11",
+ -- ["ss12"] = "stylistic set 12",
+ -- ["ss13"] = "stylistic set 13",
+ -- ["ss14"] = "stylistic set 14",
+ -- ["ss15"] = "stylistic set 15",
+ -- ["ss16"] = "stylistic set 16",
+ -- ["ss17"] = "stylistic set 17",
+ -- ["ss18"] = "stylistic set 18",
+ -- ["ss19"] = "stylistic set 19",
+ -- ["ss20"] = "stylistic set 20",
+ ["ssty"] = "script style", -- math
+ ["stch"] = "stretching glyph decomposition",
+ ["subs"] = "subscript",
+ ["sups"] = "superscript",
+ ["swsh"] = "swash",
+ ["titl"] = "titling",
+ ["tjmo"] = "trailing jamo forms",
+ ["tnam"] = "traditional name forms",
+ ["tnum"] = "tabular figures",
+ ["trad"] = "traditional forms",
+ ["twid"] = "third widths",
+ ["unic"] = "unicase",
+ ["valt"] = "alternate vertical metrics",
+ ["vatu"] = "vattu variants",
+ ["vert"] = "vertical writing",
+ ["vhal"] = "alternate vertical half metrics",
+ ["vjmo"] = "vowel jamo forms",
+ ["vkna"] = "vertical kana alternates",
+ ["vkrn"] = "vertical kerning",
+ ["vpal"] = "proportional alternate vertical metrics",
+ ["vrtr"] = "vertical alternates for rotation",
+ ["vrt2"] = "vertical rotation",
+ ["zero"] = "slashed zero",
+
+ ["trep"] = "traditional tex replacements",
+ ["tlig"] = "traditional tex ligatures",
+
+ ["ss.."] = "stylistic set ..",
+ ["cv.."] = "character variant ..",
+ ["js.."] = "justification ..",
+
+ ["dv.."] = "devanagari ..", -- for internal use
+ ["ml.."] = "malayalam ..", -- for internal use
+
+}
+
+local baselines = allocate {
+ ["hang"] = "hanging baseline",
+ ["icfb"] = "ideographic character face bottom edge baseline",
+ ["icft"] = "ideographic character face tope edige baseline",
+ ["ideo"] = "ideographic em-box bottom edge baseline",
+ ["idtp"] = "ideographic em-box top edge baseline",
+ ["math"] = "mathematical centered baseline",
+ ["romn"] = "roman baseline"
+}
+
+tables.scripts = scripts
+tables.languages = languages
+tables.features = features
+tables.baselines = baselines
+
+local acceptscripts = true directives.register("otf.acceptscripts", function(v) acceptscripts = v end)
+local acceptlanguages = true directives.register("otf.acceptlanguages", function(v) acceptlanguages = v end)
+
+local report_checks = logs.reporter("fonts","checks")
+
+-- hm, we overload the metatables
+
+if otffeatures.features then
+ for k, v in next, otffeatures.features do
+ features[k] = v
+ end
+ otffeatures.features = features
+end
+
+local function swapped(h)
+ local r = { }
+ for k, v in next, h do
+ r[gsub(v,"[^a-z0-9]","")] = k -- is already lower
+ end
+ return r
+end
+
+local verbosescripts = allocate(swapped(scripts ))
+local verboselanguages = allocate(swapped(languages))
+local verbosefeatures = allocate(swapped(features ))
+local verbosebaselines = allocate(swapped(baselines))
+
+-- lets forget about trailing spaces
+
+local function resolve(t,k)
+ if k then
+ k = gsub(lower(k),"[^a-z0-9]","")
+ local v = rawget(t,k)
+ if v then
+ return v
+ end
+ end
+end
+
+setmetatableindex(verbosescripts, resolve)
+setmetatableindex(verboselanguages, resolve)
+setmetatableindex(verbosefeatures, resolve)
+setmetatableindex(verbosebaselines, resolve)
+
+-- We could optimize the next lookups by using an extra metatable and storing
+-- already found values but in practice there are not that many lookups so
+-- it's never a bottleneck.
+
+setmetatableindex(scripts, function(t,k)
+ if k then
+ k = lower(k)
+ if k == "dflt" then
+ return k
+ end
+ local v = rawget(t,k)
+ if v then
+ return v
+ end
+ k = gsub(k," ","")
+ v = rawget(t,v)
+ if v then
+ return v
+ elseif acceptscripts then
+ report_checks("registering extra script %a",k)
+ rawset(t,k,k)
+ return k
+ end
+ end
+ return "dflt"
+end)
+
+setmetatableindex(languages, function(t,k)
+ if k then
+ k = lower(k)
+ if k == "dflt" then
+ return k
+ end
+ local v = rawget(t,k)
+ if v then
+ return v
+ end
+ k = gsub(k," ","")
+ v = rawget(t,v)
+ if v then
+ return v
+ elseif acceptlanguages then
+ report_checks("registering extra language %a",k)
+ rawset(t,k,k)
+ return k
+ end
+ end
+ return "dflt"
+end)
+
+if setmetatablenewindex then
+
+ setmetatablenewindex(languages, "ignore")
+ setmetatablenewindex(scripts, "ignore")
+ setmetatablenewindex(baselines, "ignore")
+
+end
+
+local function resolve(t,k)
+ if k then
+ k = lower(k)
+ local v = rawget(t,k)
+ if v then
+ return v
+ end
+ k = gsub(k," ","")
+ local v = rawget(t,k)
+ if v then
+ return v
+ end
+ local tag, dd = match(k,"(..)(%d+)")
+ if tag and dd then
+ local v = rawget(t,tag)
+ if v then
+ return v -- return format(v,tonumber(dd)) -- old way
+ else
+ local v = rawget(t,tag.."..") -- nicer in overview
+ if v then
+ return (gsub(v,"%.%.",tonumber(dd))) -- new way
+ end
+ end
+ end
+ end
+ return k -- "dflt"
+end
+
+setmetatableindex(features, resolve)
+
+local function assign(t,k,v)
+ if k and v then
+ v = lower(v)
+ rawset(t,k,v) -- rawset ?
+ -- rawset(features,gsub(v,"[^a-z0-9]",""),k) -- why ? old code
+ end
+end
+
+if setmetatablenewindex then
+
+ setmetatablenewindex(features, assign)
+
+end
+
+local checkers = {
+ rand = function(v)
+ return v == true and "random" or v
+ end
+}
+
+-- Keep this:
+--
+-- function otf.features.normalize(features)
+-- if features then
+-- local h = { }
+-- for k, v in next, features do
+-- k = lower(k)
+-- if k == "language" then
+-- v = gsub(lower(v),"[^a-z0-9]","")
+-- h.language = rawget(verboselanguages,v) or (languages[v] and v) or "dflt" -- auto adds
+-- elseif k == "script" then
+-- v = gsub(lower(v),"[^a-z0-9]","")
+-- h.script = rawget(verbosescripts,v) or (scripts[v] and v) or "dflt" -- auto adds
+-- else
+-- if type(v) == "string" then
+-- local b = is_boolean(v)
+-- if type(b) == "nil" then
+-- v = tonumber(v) or lower(v)
+-- else
+-- v = b
+-- end
+-- end
+-- if not rawget(features,k) then
+-- k = rawget(verbosefeatures,k) or k
+-- end
+-- local c = checkers[k]
+-- h[k] = c and c(v) or v
+-- end
+-- end
+-- return h
+-- end
+-- end
+
+-- inspect(fonts.handlers.otf.statistics.usedfeatures)
+
+if not storage then
+ return
+end
+
+local usedfeatures = statistics.usedfeatures or { }
+statistics.usedfeatures = usedfeatures
+
+table.setmetatableindex(usedfeatures, function(t,k) if k then local v = { } t[k] = v return v end end) -- table.autotable
+
+storage.register("fonts/otf/usedfeatures", usedfeatures, "fonts.handlers.otf.statistics.usedfeatures" )
+
+local normalizedaxis = otf.readers.helpers.normalizedaxis or function(s) return s end
+
+function otffeatures.normalize(features,wrap) -- wrap is for context
+ if features then
+ local h = { }
+ for key, value in next, features do
+ local k = lower(key)
+ if k == "language" then
+ local v = gsub(lower(value),"[^a-z0-9]","")
+ h.language = rawget(verboselanguages,v) or (languages[v] and v) or "dflt" -- auto adds
+ elseif k == "script" then
+ local v = gsub(lower(value),"[^a-z0-9]","")
+ h.script = rawget(verbosescripts,v) or (scripts[v] and v) or "dflt" -- auto adds
+ elseif k == "axis" then
+ h[k] = normalizedaxis(value)
+ if not callbacks.supported.glyph_stream_provider then
+ h.variableshapes = true -- for the moment
+ end
+ else
+ local uk = usedfeatures[key]
+ local uv = uk[value]
+ if uv then
+ -- report_checks("feature value %a first seen at %a",value,key)
+ else
+ uv = tonumber(value) -- before boolean as there we also handle 0/1
+ if uv then
+ -- we're okay
+ elseif type(value) == "string" then
+ local b = is_boolean(value)
+ if type(b) == "nil" then
+ -- we do this elsewhere
+ --
+ -- if find(value,"=") then
+ -- local t = { }
+ -- for k, v in gmatch(value,"([^%s,=]+)%s*=%s*([^%s,=]+)") do
+ -- t[k] = tonumber(v) or v
+ -- end
+ -- if next(t) then
+ -- value = sequenced(t,",")
+ -- end
+ -- end
+ if wrap and find(value,",") then
+ uv = "{"..lower(value).."}"
+ else
+ uv = lower(value)
+ end
+ else
+ uv = b
+ end
+ elseif type(value) == "table" then
+ uv = sequenced(t,",")
+ else
+ uv = value
+ end
+ if not rawget(features,k) then
+ k = rawget(verbosefeatures,k) or k
+ end
+ local c = checkers[k]
+ if c then
+ uv = c(uv) or vc
+ end
+ uk[value] = uv
+ end
+ h[k] = uv
+ end
+ end
+ return h
+ end
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-oup.lua b/macros/luatex/generic/luaotfload/fontloader-font-oup.lua
new file mode 100644
index 0000000000..51b1c248f8
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-oup.lua
@@ -0,0 +1,3067 @@
+if not modules then modules = { } end modules ['font-oup'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local next, type = next, type
+local P, R, S = lpeg.P, lpeg.R, lpeg.S
+local lpegmatch = lpeg.match
+local insert, remove, copy, unpack = table.insert, table.remove, table.copy, table.unpack
+
+local formatters = string.formatters
+local sortedkeys = table.sortedkeys
+local sortedhash = table.sortedhash
+local tohash = table.tohash
+local setmetatableindex = table.setmetatableindex
+
+local report_error = logs.reporter("otf reader","error")
+local report_markwidth = logs.reporter("otf reader","markwidth")
+local report_cleanup = logs.reporter("otf reader","cleanup")
+local report_optimizations = logs.reporter("otf reader","merges")
+local report_unicodes = logs.reporter("otf reader","unicodes")
+
+local trace_markwidth = false trackers.register("otf.markwidth", function(v) trace_markwidth = v end)
+local trace_cleanup = false trackers.register("otf.cleanups", function(v) trace_cleanups = v end)
+local trace_optimizations = false trackers.register("otf.optimizations", function(v) trace_optimizations = v end)
+local trace_unicodes = false trackers.register("otf.unicodes", function(v) trace_unicodes = v end)
+
+local readers = fonts.handlers.otf.readers
+local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF
+
+local f_private = formatters["P%05X"]
+local f_unicode = formatters["U%05X"]
+local f_index = formatters["I%05X"]
+local f_character_y = formatters["%C"]
+local f_character_n = formatters["[ %C ]"]
+
+local check_duplicates = true -- can become an option (pseudo feature) / aways needed anyway
+local check_soft_hyphen = true -- can become an option (pseudo feature) / needed for tagging
+
+directives.register("otf.checksofthyphen",function(v)
+ check_soft_hyphen = v
+end)
+
+local function replaced(list,index,replacement)
+ if type(list) == "number" then
+ return replacement
+ elseif type(replacement) == "table" then
+ local t = { }
+ local n = index-1
+ for i=1,n do
+ t[i] = list[i]
+ end
+ for i=1,#replacement do
+ n = n + 1
+ t[n] = replacement[i]
+ end
+ for i=index+1,#list do
+ n = n + 1
+ t[n] = list[i]
+ end
+ else
+ list[index] = replacement
+ return list
+ end
+end
+
+local function unifyresources(fontdata,indices)
+ local descriptions = fontdata.descriptions
+ local resources = fontdata.resources
+ if not descriptions or not resources then
+ return
+ end
+ --
+ local nofindices = #indices
+ --
+ local variants = fontdata.resources.variants
+ if variants then
+ for selector, unicodes in next, variants do
+ for unicode, index in next, unicodes do
+ unicodes[unicode] = indices[index]
+ end
+ end
+ end
+ --
+ local function remark(marks)
+ if marks then
+ local newmarks = { }
+ for k, v in next, marks do
+ local u = indices[k]
+ if u then
+ newmarks[u] = v
+ elseif trace_optimizations then
+ report_optimizations("discarding mark %i",k)
+ end
+ end
+ return newmarks
+ end
+ end
+ --
+ local marks = resources.marks
+ if marks then
+ resources.marks = remark(marks)
+ end
+ --
+ local markclasses = resources.markclasses
+ if markclasses then
+ for class, marks in next, markclasses do
+ markclasses[class] = remark(marks)
+ end
+ end
+ --
+ local marksets = resources.marksets
+ if marksets then
+ for class, marks in next, marksets do
+ marksets[class] = remark(marks)
+ end
+ end
+ --
+ local done = { } -- we need to deal with shared !
+ --
+ local duplicates = check_duplicates and resources.duplicates
+ if duplicates and not next(duplicates) then
+ duplicates = false
+ end
+ --
+ local function recover(cover) -- can be packed
+ for i=1,#cover do
+ local c = cover[i]
+ if not done[c] then
+ local t = { }
+ for k, v in next, c do
+ local ug = indices[k]
+ if ug then
+ t[ug] = v
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices)
+ end
+ end
+ cover[i] = t
+ done[c] = d
+ end
+ end
+ end
+ --
+ local function recursed(c,kind) -- ligs are not packed
+ local t = { }
+ for g, d in next, c do
+ if type(d) == "table" then
+ local ug = indices[g]
+ if ug then
+ t[ug] = recursed(d,kind)
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices)
+ end
+ else
+ t[g] = indices[d] -- ligature
+ end
+ end
+ return t
+ end
+ --
+ -- the duplicates need checking (probably only in cjk fonts): currently we only check
+ -- gsub_single, gsub_alternate, gsub_multiple, gpos_single and gpos_cursive
+ --
+ local function unifythem(sequences)
+ if not sequences then
+ return
+ end
+ for i=1,#sequences do
+ local sequence = sequences[i]
+ local kind = sequence.type
+ local steps = sequence.steps
+ local features = sequence.features
+ if steps then
+ for i=1,#steps do
+ local step = steps[i]
+ if kind == "gsub_single" then
+ local c = step.coverage
+ if c then
+ local t1 = done[c]
+ if not t1 then
+ t1 = { }
+ if duplicates then
+ for g1, d1 in next, c do
+ local ug1 = indices[g1]
+ if ug1 then
+ local ud1 = indices[d1]
+ if ud1 then
+ t1[ug1] = ud1
+ local dg1 = duplicates[ug1]
+ if dg1 then
+ for u in next, dg1 do
+ t1[u] = ud1
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices)
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1, d1 in next, c do
+ local ug1 = indices[g1]
+ if ug1 then
+ t1[ug1] = indices[d1]
+ else
+ report_error("fuzzy case %i in unifying %s: %i",2,kind,g1)
+ end
+ end
+ end
+ done[c] = t1
+ end
+ step.coverage = t1
+ end
+ elseif kind == "gpos_pair" then
+ local c = step.coverage
+ if c then
+ local t1 = done[c]
+ if not t1 then
+ t1 = { }
+ for g1, d1 in next, c do
+ local ug1 = indices[g1]
+ if ug1 then
+ local t2 = done[d1]
+ if not t2 then
+ t2 = { }
+ for g2, d2 in next, d1 do
+ local ug2 = indices[g2]
+ if ug2 then
+ t2[ug2] = d2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices)
+ end
+ end
+ done[d1] = t2
+ end
+ t1[ug1] = t2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ done[c] = t1
+ end
+ step.coverage = t1
+ end
+ elseif kind == "gsub_ligature" then
+ local c = step.coverage
+ if c then
+ step.coverage = recursed(c,kind)
+ end
+ elseif kind == "gsub_alternate" or kind == "gsub_multiple" then
+ local c = step.coverage
+ if c then
+ local t1 = done[c]
+ if not t1 then
+ t1 = { }
+ if duplicates then
+ for g1, d1 in next, c do
+ for i=1,#d1 do
+ local d1i = d1[i]
+ local d1u = indices[d1i]
+ if d1u then
+ d1[i] = d1u
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices)
+ end
+ end
+ local ug1 = indices[g1]
+ if ug1 then
+ t1[ug1] = d1
+ local dg1 = duplicates[ug1]
+ if dg1 then
+ for u in next, dg1 do
+ t1[u] = copy(d1)
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1, d1 in next, c do
+ for i=1,#d1 do
+ local d1i = d1[i]
+ local d1u = indices[d1i]
+ if d1u then
+ d1[i] = d1u
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices)
+ end
+ end
+ t1[indices[g1]] = d1
+ end
+ end
+ done[c] = t1
+ end
+ step.coverage = t1
+ end
+ elseif kind == "gpos_single" then
+ local c = step.coverage
+ if c then
+ local t1 = done[c]
+ if not t1 then
+ t1 = { }
+ if duplicates then
+ for g1, d1 in next, c do
+ local ug1 = indices[g1]
+ if ug1 then
+ t1[ug1] = d1
+ local dg1 = duplicates[ug1]
+ if dg1 then
+ for u in next, dg1 do
+ t1[u] = d1
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1, d1 in next, c do
+ local ug1 = indices[g1]
+ if ug1 then
+ t1[ug1] = d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ end
+ done[c] = t1
+ end
+ step.coverage = t1
+ end
+ elseif kind == "gpos_mark2base" or kind == "gpos_mark2mark" or kind == "gpos_mark2ligature" then
+ local c = step.coverage
+ if c then
+ local t1 = done[c]
+ if not t1 then
+ t1 = { }
+ for g1, d1 in next, c do
+ local ug1 = indices[g1]
+ if ug1 then
+ t1[ug1] = d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ done[c] = t1
+ end
+ step.coverage = t1
+ end
+ local c = step.baseclasses
+ if c then
+ local t1 = done[c]
+ if not t1 then
+ for g1, d1 in next, c do
+ local t2 = done[d1]
+ if not t2 then
+ t2 = { }
+ for g2, d2 in next, d1 do
+ local ug2 = indices[g2]
+ if ug2 then
+ t2[ug2] = d2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices)
+ end
+ end
+ done[d1] = t2
+ end
+ c[g1] = t2
+ end
+ done[c] = c
+ end
+ end
+ elseif kind == "gpos_cursive" then
+ local c = step.coverage
+ if c then
+ local t1 = done[c]
+ if not t1 then
+ t1 = { }
+ if duplicates then
+ for g1, d1 in next, c do
+ local ug1 = indices[g1]
+ if ug1 then
+ t1[ug1] = d1
+ --
+ local dg1 = duplicates[ug1]
+ if dg1 then
+ -- probably needs a bit more
+ for u in next, dg1 do
+ t1[u] = copy(d1)
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1, d1 in next, c do
+ local ug1 = indices[g1]
+ if ug1 then
+ t1[ug1] = d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ end
+ done[c] = t1
+ end
+ step.coverage = t1
+ end
+ end
+ --
+ local rules = step.rules
+ if rules then
+ for i=1,#rules do
+ local rule = rules[i]
+ --
+ local before = rule.before if before then recover(before) end
+ local after = rule.after if after then recover(after) end
+ local current = rule.current if current then recover(current) end
+ --
+ local replacements = rule.replacements
+ if replacements then
+ if not done[replacements] then
+ local r = { }
+ for k, v in next, replacements do
+ r[indices[k]] = indices[v]
+ end
+ rule.replacements = r
+ done[replacements] = r
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ --
+ unifythem(resources.sequences)
+ unifythem(resources.sublookups)
+end
+
+local function copyduplicates(fontdata)
+ if check_duplicates then
+ local descriptions = fontdata.descriptions
+ local resources = fontdata.resources
+ local duplicates = resources.duplicates
+ if check_soft_hyphen then
+ -- ebgaramond has a zero width empty soft hyphen
+ -- antykwatorunsks lacks a soft hyphen
+ local ds = descriptions[0xAD]
+ if not ds or ds.width == 0 then
+ if ds then
+ descriptions[0xAD] = nil
+ if trace_unicodes then
+ report_unicodes("patching soft hyphen")
+ end
+ else
+ if trace_unicodes then
+ report_unicodes("adding soft hyphen")
+ end
+ end
+ if not duplicates then
+ duplicates = { }
+ resources.duplicates = duplicates
+ end
+ local dh = duplicates[0x2D]
+ if dh then
+ dh[#dh+1] = { [0xAD] = true }
+ else
+ duplicates[0x2D] = { [0xAD] = true }
+ end
+ end
+ end
+ if duplicates then
+ for u, d in next, duplicates do
+ local du = descriptions[u]
+ if du then
+ local t = { f_character_y(u), "@", f_index(du.index), "->" }
+ local n = 0
+ local m = 25
+ for u in next, d do
+ if descriptions[u] then
+ if n < m then
+ t[n+4] = f_character_n(u)
+ end
+ else
+ local c = copy(du)
+ c.unicode = u -- better this way
+ descriptions[u] = c
+ if n < m then
+ t[n+4] = f_character_y(u)
+ end
+ end
+ n = n + 1
+ end
+ if trace_unicodes then
+ if n <= m then
+ report_unicodes("%i : % t",n,t)
+ else
+ report_unicodes("%i : % t ...",n,t)
+ end
+ end
+ else
+ -- what a mess
+ end
+ end
+ end
+ end
+end
+
+local ignore = { -- should we fix them?
+ ["notdef"] = true,
+ [".notdef"] = true,
+ ["null"] = true,
+ [".null"] = true,
+ ["nonmarkingreturn"] = true,
+}
+
+
+local function checklookups(fontdata,missing,nofmissing)
+ local descriptions = fontdata.descriptions
+ local resources = fontdata.resources
+ if missing and nofmissing and nofmissing <= 0 then
+ return
+ end
+ --
+ local singles = { }
+ local alternates = { }
+ local ligatures = { }
+
+ if not missing then
+ missing = { }
+ nofmissing = 0
+ for u, d in next, descriptions do
+ if not d.unicode then
+ nofmissing = nofmissing + 1
+ missing[u] = true
+ end
+ end
+ end
+ local function collectthem(sequences)
+ if not sequences then
+ return
+ end
+ for i=1,#sequences do
+ local sequence = sequences[i]
+ local kind = sequence.type
+ local steps = sequence.steps
+ if steps then
+ for i=1,#steps do
+ local step = steps[i]
+ if kind == "gsub_single" then
+ local c = step.coverage
+ if c then
+ singles[#singles+1] = c
+ end
+ elseif kind == "gsub_alternate" then
+ local c = step.coverage
+ if c then
+ alternates[#alternates+1] = c
+ end
+ elseif kind == "gsub_ligature" then
+ local c = step.coverage
+ if c then
+ ligatures[#ligatures+1] = c
+ end
+ end
+ end
+ end
+ end
+ end
+
+ collectthem(resources.sequences)
+ collectthem(resources.sublookups)
+
+ local loops = 0
+ while true do
+ loops = loops + 1
+ local old = nofmissing
+ for i=1,#singles do
+ local c = singles[i]
+ for g1, g2 in next, c do
+ if missing[g1] then
+ local u2 = descriptions[g2].unicode
+ if u2 then
+ missing[g1] = false
+ descriptions[g1].unicode = u2
+ nofmissing = nofmissing - 1
+ end
+ end
+ if missing[g2] then
+ local u1 = descriptions[g1].unicode
+ if u1 then
+ missing[g2] = false
+ descriptions[g2].unicode = u1
+ nofmissing = nofmissing - 1
+ end
+ end
+ end
+ end
+ for i=1,#alternates do
+ local c = alternates[i]
+ -- maybe first a g1 loop and then a g2
+ for g1, d1 in next, c do
+ if missing[g1] then
+ for i=1,#d1 do
+ local g2 = d1[i]
+ local u2 = descriptions[g2].unicode
+ if u2 then
+ missing[g1] = false
+ descriptions[g1].unicode = u2
+ nofmissing = nofmissing - 1
+ end
+ end
+ end
+ if not missing[g1] then
+ for i=1,#d1 do
+ local g2 = d1[i]
+ if missing[g2] then
+ local u1 = descriptions[g1].unicode
+ if u1 then
+ missing[g2] = false
+ descriptions[g2].unicode = u1
+ nofmissing = nofmissing - 1
+ end
+ end
+ end
+ end
+ end
+ end
+ if nofmissing <= 0 then
+ if trace_unicodes then
+ report_unicodes("all missings done in %s loops",loops)
+ end
+ return
+ elseif old == nofmissing then
+ break
+ end
+ end
+
+ local t, n -- no need to insert/remove and allocate many times
+
+ local function recursed(c)
+ for g, d in next, c do
+ if g ~= "ligature" then
+ local u = descriptions[g].unicode
+ if u then
+ n = n + 1
+ t[n] = u
+ recursed(d)
+ n = n - 1
+ end
+ elseif missing[d] then
+ local l = { }
+ local m = 0
+ for i=1,n do
+ local u = t[i]
+ if type(u) == "table" then
+ for i=1,#u do
+ m = m + 1
+ l[m] = u[i]
+ end
+ else
+ m = m + 1
+ l[m] = u
+ end
+ end
+ missing[d] = false
+ descriptions[d].unicode = l
+ nofmissing = nofmissing - 1
+ end
+ end
+ end
+
+ if nofmissing > 0 then
+ t = { }
+ n = 0
+ local loops = 0
+ while true do
+ loops = loops + 1
+ local old = nofmissing
+ for i=1,#ligatures do
+ recursed(ligatures[i])
+ end
+ if nofmissing <= 0 then
+ if trace_unicodes then
+ report_unicodes("all missings done in %s loops",loops)
+ end
+ return
+ elseif old == nofmissing then
+ break
+ end
+ end
+ t = nil
+ n = 0
+ end
+
+ if trace_unicodes and nofmissing > 0 then
+ local done = { }
+ for i, r in next, missing do
+ if r then
+ local data = descriptions[i]
+ local name = data and data.name or f_index(i)
+ if not ignore[name] then
+ done[name] = true
+ end
+ end
+ end
+ if next(done) then
+ report_unicodes("not unicoded: % t",sortedkeys(done))
+ end
+ end
+end
+
+local function unifymissing(fontdata)
+ if not fonts.mappings then
+ require("font-map")
+ require("font-agl")
+ end
+ local unicodes = { }
+ local resources = fontdata.resources
+ resources.unicodes = unicodes
+ for unicode, d in next, fontdata.descriptions do
+ if unicode < privateoffset then
+ local name = d.name
+ if name then
+ unicodes[name] = unicode
+ end
+ end
+ end
+ fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups)
+ resources.unicodes = nil
+end
+
+local firstprivate = fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000
+local puafirst = 0xE000
+local pualast = 0xF8FF
+
+local function unifyglyphs(fontdata,usenames)
+ local private = fontdata.private or privateoffset
+ local glyphs = fontdata.glyphs
+ local indices = { }
+ local descriptions = { }
+ local names = usenames and { }
+ local resources = fontdata.resources
+ local zero = glyphs[0]
+ local zerocode = zero.unicode
+ if not zerocode then
+ zerocode = private
+ zero.unicode = zerocode
+ private = private + 1
+ end
+ descriptions[zerocode] = zero
+ if names then
+ local name = glyphs[0].name or f_private(zerocode)
+ indices[0] = name
+ names[name] = zerocode
+ else
+ indices[0] = zerocode
+ end
+ --
+ if names then
+ -- seldom uses, we don't issue message ... this branch might even go away
+ for index=1,#glyphs do
+ local glyph = glyphs[index]
+ local unicode = glyph.unicode -- this is the primary one
+ if not unicode then
+ unicode = private
+ local name = glyph.name or f_private(unicode)
+ indices[index] = name
+ names[name] = unicode
+ private = private + 1
+ elseif unicode >= firstprivate then
+ unicode = private
+ local name = glyph.name or f_private(unicode)
+ indices[index] = name
+ names[name] = unicode
+ private = private + 1
+ elseif unicode >= puafirst and unicode <= pualast then
+ local name = glyph.name or f_private(unicode)
+ indices[index] = name
+ names[name] = unicode
+ elseif descriptions[unicode] then
+ unicode = private
+ local name = glyph.name or f_private(unicode)
+ indices[index] = name
+ names[name] = unicode
+ private = private + 1
+ else
+ local name = glyph.name or f_unicode(unicode)
+ indices[index] = name
+ names[name] = unicode
+ end
+ descriptions[unicode] = glyph
+ end
+ elseif trace_unicodes then
+ for index=1,#glyphs do
+ local glyph = glyphs[index]
+ local unicode = glyph.unicode -- this is the primary one
+ if not unicode then
+ unicode = private
+ indices[index] = unicode
+ private = private + 1
+ elseif unicode >= firstprivate then
+ local name = glyph.name
+ if name then
+ report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private)
+ else
+ report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private)
+ end
+ unicode = private
+ indices[index] = unicode
+ private = private + 1
+ elseif unicode >= puafirst and unicode <= pualast then
+ local name = glyph.name
+ if name then
+ report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index)
+ else
+ report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index)
+ end
+ indices[index] = unicode
+ elseif descriptions[unicode] then
+ local name = glyph.name
+ if name then
+ report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index)
+ else
+ report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index)
+ end
+ unicode = private
+ indices[index] = unicode
+ private = private + 1
+ else
+ indices[index] = unicode
+ end
+ descriptions[unicode] = glyph
+ end
+ else
+ for index=1,#glyphs do
+ local glyph = glyphs[index]
+ local unicode = glyph.unicode -- this is the primary one
+ if not unicode then
+ unicode = private
+ indices[index] = unicode
+ private = private + 1
+ elseif unicode >= firstprivate then
+ local name = glyph.name
+ unicode = private
+ indices[index] = unicode
+ private = private + 1
+ elseif unicode >= puafirst and unicode <= pualast then
+ local name = glyph.name
+ indices[index] = unicode
+ elseif descriptions[unicode] then
+ local name = glyph.name
+ unicode = private
+ indices[index] = unicode
+ private = private + 1
+ else
+ indices[index] = unicode
+ end
+ descriptions[unicode] = glyph
+ end
+ end
+ --
+ for index=1,#glyphs do
+ local math = glyphs[index].math
+ if math then
+ local list = math.vparts
+ if list then
+ for i=1,#list do local l = list[i] l.glyph = indices[l.glyph] end
+ end
+ local list = math.hparts
+ if list then
+ for i=1,#list do local l = list[i] l.glyph = indices[l.glyph] end
+ end
+ local list = math.vvariants
+ if list then
+ -- for i=1,#list do local l = list[i] l.glyph = indices[l.glyph] end
+ for i=1,#list do list[i] = indices[list[i]] end
+ end
+ local list = math.hvariants
+ if list then
+ -- for i=1,#list do local l = list[i] l.glyph = indices[l.glyph] end
+ for i=1,#list do list[i] = indices[list[i]] end
+ end
+ end
+ end
+ --
+ local colorpalettes = resources.colorpalettes
+ if colorpalettes then
+ for index=1,#glyphs do
+ local colors = glyphs[index].colors
+ if colors then
+ for i=1,#colors do
+ local c = colors[i]
+ c.slot = indices[c.slot]
+ end
+ end
+ end
+ end
+ --
+ fontdata.private = private
+ fontdata.glyphs = nil
+ fontdata.names = names
+ fontdata.descriptions = descriptions
+ fontdata.hashmethod = hashmethod
+ --
+ return indices, names
+end
+
+local p_crappyname do
+
+ local p_hex = R("af","AF","09")
+ local p_digit = R("09")
+ local p_done = S("._-")^0 + P(-1)
+ local p_alpha = R("az","AZ")
+ local p_ALPHA = R("AZ")
+
+ p_crappyname = (
+ -- (P("uni") + P("UNI") + P("Uni") + P("U") + P("u"))
+ lpeg.utfchartabletopattern({ "uni", "u" },true)
+ * S("Xx_")^0
+ * p_hex^1
+ -- + (P("identity") + P("Identity") + P("IDENTITY") + P("glyph") + P("jamo"))
+ + lpeg.utfchartabletopattern({ "identity", "glyph", "jamo" },true)
+ * p_hex^1
+ -- + (P("index") + P("Index") + P("INDEX")+ P("afii"))
+ + lpeg.utfchartabletopattern({ "index", "afii" }, true)
+ * p_digit^1
+ -- also happens l
+ + p_digit
+ * p_hex^3
+ + p_alpha
+ * p_digit^1
+ -- sort of special
+ + P("aj")
+ * p_digit^1
+ + P("eh_")
+ * (p_digit^1 + p_ALPHA * p_digit^1)
+ + (1-P("_"))^1
+ * P("_uni")
+ * p_hex^1
+ + P("_")
+ * P(1)^1
+ ) * p_done
+
+end
+
+-- In context we only keep glyph names because of tracing and access by name
+-- so weird names make no sense.
+
+local forcekeep = false -- only for testing something
+
+directives.register("otf.keepnames",function(v)
+ report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
+ forcekeep = v
+end)
+
+local function stripredundant(fontdata)
+ local descriptions = fontdata.descriptions
+ if descriptions then
+ local n = 0
+ local c = 0
+ -- in context we always strip
+ if (not context and fonts.privateoffsets.keepnames) or forcekeep then
+ for unicode, d in next, descriptions do
+ if d.class == "base" then
+ d.class = nil
+ c = c + 1
+ end
+ end
+ else
+ for unicode, d in next, descriptions do
+ local name = d.name
+ if name and lpegmatch(p_crappyname,name) then
+ d.name = nil
+ n = n + 1
+ end
+ if d.class == "base" then
+ d.class = nil
+ c = c + 1
+ end
+ end
+ end
+ if trace_cleanup then
+ if n > 0 then
+ report_cleanup("%s bogus names removed (verbose unicode)",n)
+ end
+ if c > 0 then
+ report_cleanup("%s base class tags removed (default is base)",c)
+ end
+ end
+ end
+end
+
+readers.stripredundant = stripredundant
+
+function readers.getcomponents(fontdata) -- handy for resolving ligatures when names are missing
+ local resources = fontdata.resources
+ if resources then
+ local sequences = resources.sequences
+ if sequences then
+ local collected = { }
+ for i=1,#sequences do
+ local sequence = sequences[i]
+ if sequence.type == "gsub_ligature" then
+ local steps = sequence.steps
+ if steps then
+ local l = { }
+ local function traverse(p,k,v)
+ if k == "ligature" then
+ collected[v] = { unpack(l) }
+ else
+ insert(l,k)
+ for k, vv in next, v do
+ traverse(p,k,vv)
+ end
+ remove(l)
+ end
+ end
+ for i=1,#steps do
+ -- we actually had/have this in base mode
+ local c = steps[i].coverage
+ if c then
+ for k, v in next, c do
+ traverse(k,k,v)
+ end
+ end
+ end
+ end
+ end
+ end
+ if next(collected) then
+ -- remove self referring
+ -- for k, v in next, collected do
+ -- for i=1,#v do
+ -- local vi = v[i]
+ -- if vi == k then
+ -- -- report("removing self referring ligature @ slot %5X from collected (1)",k)
+ -- collected[k] = nil
+ -- end
+ -- end
+ -- end
+ while true do
+ local done = false
+ for k, v in next, collected do
+ for i=1,#v do
+ local vi = v[i]
+ if vi == k then
+ -- report("removing self referring ligature @ slot %5X from collected (2)",k)
+ collected[k] = nil
+ break
+ else
+ local c = collected[vi]
+ if c then
+ done = true
+ local t = { }
+ local n = i - 1
+ for j=1,n do
+ t[j] = v[j]
+ end
+ for j=1,#c do
+ n = n + 1
+ t[n] = c[j]
+ end
+ for j=i+1,#v do
+ n = n + 1
+ t[n] = v[j]
+ end
+ collected[k] = t
+ break
+ end
+ end
+ end
+ end
+ if not done then
+ break
+ end
+ end
+ return collected
+ end
+ end
+ end
+end
+
+readers.unifymissing = unifymissing
+
+function readers.rehash(fontdata,hashmethod) -- TODO: combine loops in one
+ if not (fontdata and fontdata.glyphs) then
+ return
+ end
+ if hashmethod == "indices" then
+ fontdata.hashmethod = "indices"
+ elseif hashmethod == "names" then
+ fontdata.hashmethod = "names"
+ local indices = unifyglyphs(fontdata,true)
+ unifyresources(fontdata,indices)
+ copyduplicates(fontdata)
+ unifymissing(fontdata)
+ -- stripredundant(fontdata)
+ else
+ fontdata.hashmethod = "unicodes"
+ local indices = unifyglyphs(fontdata)
+ unifyresources(fontdata,indices)
+ copyduplicates(fontdata)
+ unifymissing(fontdata)
+ stripredundant(fontdata)
+ end
+ -- maybe here components
+end
+
+function readers.checkhash(fontdata)
+ local hashmethod = fontdata.hashmethod
+ if hashmethod == "unicodes" then
+ fontdata.names = nil -- just to be sure
+ elseif hashmethod == "names" and fontdata.names then
+ unifyresources(fontdata,fontdata.names)
+ copyduplicates(fontdata)
+ fontdata.hashmethod = "unicodes"
+ fontdata.names = nil -- no need for it
+ else
+ readers.rehash(fontdata,"unicodes")
+ end
+end
+
+function readers.addunicodetable(fontdata)
+ local resources = fontdata.resources
+ local unicodes = resources.unicodes
+ if not unicodes then
+ local descriptions = fontdata.descriptions
+ if descriptions then
+ unicodes = { }
+ resources.unicodes = unicodes
+ for u, d in next, descriptions do
+ local n = d.name
+ if n then
+ unicodes[n] = u
+ end
+ end
+ end
+ end
+end
+
+-- for the moment here:
+
+local concat, sort = table.concat, table.sort
+local next, type, tostring = next, type, tostring
+
+local criterium = 1
+local threshold = 0
+
+local trace_packing = false trackers.register("otf.packing", function(v) trace_packing = v end)
+local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
+
+local report_otf = logs.reporter("fonts","otf loading")
+
+local function tabstr_normal(t)
+ local s = { }
+ local n = 0
+ for k, v in next, t do
+ n = n + 1
+ if type(v) == "table" then
+ s[n] = k .. ">" .. tabstr_normal(v)
+ elseif v == true then
+ s[n] = k .. "+" -- "=true"
+ elseif v then
+ s[n] = k .. "=" .. v
+ else
+ s[n] = k .. "-" -- "=false"
+ end
+ end
+ if n == 0 then
+ return ""
+ elseif n == 1 then
+ return s[1]
+ else
+ sort(s) -- costly but needed (occasional wrong hit otherwise)
+ return concat(s,",")
+ end
+end
+
+local function tabstr_flat(t)
+ local s = { }
+ local n = 0
+ for k, v in next, t do
+ n = n + 1
+ s[n] = k .. "=" .. v
+ end
+ if n == 0 then
+ return ""
+ elseif n == 1 then
+ return s[1]
+ else
+ sort(s) -- costly but needed (occasional wrong hit otherwise)
+ return concat(s,",")
+ end
+end
+
+local function tabstr_mixed(t) -- indexed
+ local s = { }
+ local n = #t
+ if n == 0 then
+ return ""
+ elseif n == 1 then
+ local k = t[1]
+ if k == true then
+ return "++" -- we need to distinguish from "true"
+ elseif k == false then
+ return "--" -- we need to distinguish from "false"
+ else
+ return tostring(k) -- number or string
+ end
+ else
+ for i=1,n do
+ local k = t[i]
+ if k == true then
+ s[i] = "++" -- we need to distinguish from "true"
+ elseif k == false then
+ s[i] = "--" -- we need to distinguish from "false"
+ else
+ s[i] = k -- number or string
+ end
+ end
+ return concat(s,",")
+ end
+end
+
+local function tabstr_boolean(t)
+ local s = { }
+ local n = 0
+ for k, v in next, t do
+ n = n + 1
+ if v then
+ s[n] = k .. "+"
+ else
+ s[n] = k .. "-"
+ end
+ end
+ if n == 0 then
+ return ""
+ elseif n == 1 then
+ return s[1]
+ else
+ sort(s) -- costly but needed (occasional wrong hit otherwise)
+ return concat(s,",")
+ end
+end
+
+-- beware: we cannot unpack and repack the same table because then sharing
+-- interferes (we could catch this if needed) .. so for now: save, reload
+-- and repack in such cases (never needed anyway) .. a tricky aspect is that
+-- we then need to sort more thanks to random hashing
+
+function readers.pack(data)
+
+ if data then
+
+ local h, t, c = { }, { }, { }
+ local hh, tt, cc = { }, { }, { }
+ local nt, ntt = 0, 0
+
+ local function pack_normal(v)
+ local tag = tabstr_normal(v)
+ local ht = h[tag]
+ if ht then
+ c[ht] = c[ht] + 1
+ return ht
+ else
+ nt = nt + 1
+ t[nt] = v
+ h[tag] = nt
+ c[nt] = 1
+ return nt
+ end
+ end
+
+ local function pack_normal_cc(v)
+ local tag = tabstr_normal(v)
+ local ht = h[tag]
+ if ht then
+ c[ht] = c[ht] + 1
+ return ht
+ else
+ v[1] = 0
+ nt = nt + 1
+ t[nt] = v
+ h[tag] = nt
+ c[nt] = 1
+ return nt
+ end
+ end
+
+ local function pack_flat(v)
+ local tag = tabstr_flat(v)
+ local ht = h[tag]
+ if ht then
+ c[ht] = c[ht] + 1
+ return ht
+ else
+ nt = nt + 1
+ t[nt] = v
+ h[tag] = nt
+ c[nt] = 1
+ return nt
+ end
+ end
+
+ local function pack_indexed(v)
+ local tag = concat(v," ")
+ local ht = h[tag]
+ if ht then
+ c[ht] = c[ht] + 1
+ return ht
+ else
+ nt = nt + 1
+ t[nt] = v
+ h[tag] = nt
+ c[nt] = 1
+ return nt
+ end
+ end
+
+ local function pack_mixed(v)
+ local tag = tabstr_mixed(v)
+ local ht = h[tag]
+ if ht then
+ c[ht] = c[ht] + 1
+ return ht
+ else
+ nt = nt + 1
+ t[nt] = v
+ h[tag] = nt
+ c[nt] = 1
+ return nt
+ end
+ end
+
+ -- saves a lot on noto sans
+
+ -- can be made more clever
+
+ local function pack_boolean(v)
+ local tag = tabstr_boolean(v)
+ local ht = h[tag]
+ if ht then
+ c[ht] = c[ht] + 1
+ return ht
+ else
+ nt = nt + 1
+ t[nt] = v
+ h[tag] = nt
+ c[nt] = 1
+ return nt
+ end
+ end
+
+ -- -- This was an experiment to see if we can bypass the luajit limits but loading is
+ -- -- still an issue due to other limits so we don't use this ... actually it can
+ -- -- prevent a luajittex crash but i don't care too much about that as we can't use
+ -- -- that engine anyway then.
+ --
+ -- local function check(t)
+ -- if type(t) == "table" then
+ -- local s = sortedkeys(t)
+ -- local n = #s
+ -- if n <= 10 then
+ -- return
+ -- end
+ -- local ranges = { }
+ -- local first, last
+ -- for i=1,#s do
+ -- local ti = s[i]
+ -- if not first then
+ -- first = ti
+ -- last = ti
+ -- elseif ti == last + 1 then
+ -- last = ti
+ -- elseif last - first < 10 then
+ -- -- we could permits a few exceptions
+ -- return
+ -- else
+ -- ranges[#ranges+1] = { first, last }
+ -- first, last = nil, nil
+ -- end
+ -- end
+ -- if #ranges > 0 then
+ -- return {
+ -- ranges = ranges
+ -- }
+ -- end
+ -- end
+ -- end
+ --
+ -- local function pack_boolean(v)
+ -- local tag
+ -- local r = check(v)
+ -- if r then
+ -- v = r
+ -- tag = tabstr_normal(v)
+ -- else
+ -- tag = tabstr_boolean(v)
+ -- end
+ -- local ht = h[tag]
+ -- if ht then
+ -- c[ht] = c[ht] + 1
+ -- return ht
+ -- else
+ -- nt = nt + 1
+ -- t[nt] = v
+ -- h[tag] = nt
+ -- c[nt] = 1
+ -- return nt
+ -- end
+ -- end
+
+ local function pack_final(v)
+ -- v == number
+ if c[v] <= criterium then
+ return t[v]
+ else
+ -- compact hash
+ local hv = hh[v]
+ if hv then
+ return hv
+ else
+ ntt = ntt + 1
+ tt[ntt] = t[v]
+ hh[v] = ntt
+ cc[ntt] = c[v]
+ return ntt
+ end
+ end
+ end
+
+ local function pack_final_cc(v)
+ -- v == number
+ if c[v] <= criterium then
+ return t[v]
+ else
+ -- compact hash
+ local hv = hh[v]
+ if hv then
+ return hv
+ else
+ ntt = ntt + 1
+ tt[ntt] = t[v]
+ hh[v] = ntt
+ cc[ntt] = c[v]
+ return ntt
+ end
+ end
+ end
+
+ local function success(stage,pass)
+ if nt == 0 then
+ if trace_loading or trace_packing then
+ report_otf("pack quality: nothing to pack")
+ end
+ return false
+ elseif nt >= threshold then
+ local one = 0
+ local two = 0
+ local rest = 0
+ if pass == 1 then
+ for k,v in next, c do
+ if v == 1 then
+ one = one + 1
+ elseif v == 2 then
+ two = two + 1
+ else
+ rest = rest + 1
+ end
+ end
+ else
+ for k,v in next, cc do
+ if v > 20 then
+ rest = rest + 1
+ elseif v > 10 then
+ two = two + 1
+ else
+ one = one + 1
+ end
+ end
+ data.tables = tt
+ end
+ if trace_loading or trace_packing then
+ report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)",
+ stage, pass, one+two+rest, one, two, rest, criterium)
+ end
+ return true
+ else
+ if trace_loading or trace_packing then
+ report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)",
+ stage, pass, nt, threshold)
+ end
+ return false
+ end
+ end
+
+ local function packers(pass)
+ if pass == 1 then
+ return pack_normal, pack_indexed, pack_flat, pack_boolean, pack_mixed, pack_normal_cc
+ else
+ return pack_final, pack_final, pack_final, pack_final, pack_final, pack_final_cc
+ end
+ end
+
+ local resources = data.resources
+ local sequences = resources.sequences
+ local sublookups = resources.sublookups
+ local features = resources.features
+ local palettes = resources.colorpalettes
+ local variable = resources.variabledata
+
+ local chardata = characters and characters.data
+ local descriptions = data.descriptions or data.glyphs
+
+ if not descriptions then
+ return
+ end
+
+ for pass=1,2 do
+
+ if trace_packing then
+ report_otf("start packing: stage 1, pass %s",pass)
+ end
+
+ local pack_normal, pack_indexed, pack_flat, pack_boolean, pack_mixed, pack_normal_cc = packers(pass)
+
+ for unicode, description in next, descriptions do
+ local boundingbox = description.boundingbox
+ if boundingbox then
+ description.boundingbox = pack_indexed(boundingbox)
+ end
+ local math = description.math
+ if math then
+ local kerns = math.kerns
+ if kerns then
+ for tag, kern in next, kerns do
+ kerns[tag] = pack_normal(kern)
+ end
+ end
+ end
+ -- if palettes then
+ -- local color = description.color
+ -- if color then
+ -- for i=1,#color do
+ -- color[i] = pack_normal(color[i])
+ -- end
+ -- end
+ -- end
+ end
+
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence = sequences[i]
+ local kind = sequence.type
+ local steps = sequence.steps
+ local order = sequence.order
+ local features = sequence.features
+ local flags = sequence.flags
+ if steps then
+ for i=1,#steps do
+ local step = steps[i]
+ if kind == "gpos_pair" then
+ local c = step.coverage
+ if c then
+ if step.format ~= "pair" then
+ for g1, d1 in next, c do
+ c[g1] = pack_normal(d1)
+ end
+ elseif step.shared then
+ -- This branch results from classes. We already share at the reader end. Maybe
+ -- the sharing should be moved there altogether but it becomes kind of messy
+ -- then. Here we're still wasting time because in the second pass we serialize
+ -- and hash. So we compromise. We could merge the two passes ...
+ local shared = { }
+ for g1, d1 in next, c do
+ for g2, d2 in next, d1 do
+ if not shared[d2] then
+ local f = d2[1] if f and f ~= true then d2[1] = pack_indexed(f) end
+ local s = d2[2] if s and s ~= true then d2[2] = pack_indexed(s) end
+ shared[d2] = true
+ end
+ end
+ end
+ if pass == 2 then
+ step.shared = nil -- weird, so dups
+ end
+ else
+ for g1, d1 in next, c do
+ for g2, d2 in next, d1 do
+ local f = d2[1] if f and f ~= true then d2[1] = pack_indexed(f) end
+ local s = d2[2] if s and s ~= true then d2[2] = pack_indexed(s) end
+ end
+ end
+ end
+ end
+ elseif kind == "gpos_single" then
+ local c = step.coverage
+ if c then
+ if step.format == "single" then
+ for g1, d1 in next, c do
+ if d1 and d1 ~= true then
+ c[g1] = pack_indexed(d1)
+ end
+ end
+ else
+ step.coverage = pack_normal(c)
+ end
+ end
+ elseif kind == "gpos_cursive" then
+ local c = step.coverage
+ if c then
+ for g1, d1 in next, c do
+ local f = d1[2] if f then d1[2] = pack_indexed(f) end
+ local s = d1[3] if s then d1[3] = pack_indexed(s) end
+ end
+ end
+ elseif kind == "gpos_mark2base" or kind == "gpos_mark2mark" then
+ local c = step.baseclasses
+ if c then
+ for g1, d1 in next, c do
+ for g2, d2 in next, d1 do
+ d1[g2] = pack_indexed(d2)
+ end
+ end
+ end
+ local c = step.coverage
+ if c then
+ for g1, d1 in next, c do
+ d1[2] = pack_indexed(d1[2])
+ end
+ end
+ elseif kind == "gpos_mark2ligature" then
+ local c = step.baseclasses
+ if c then
+ for g1, d1 in next, c do
+ for g2, d2 in next, d1 do
+ for g3, d3 in next, d2 do
+ d2[g3] = pack_indexed(d3)
+ end
+ end
+ end
+ end
+ local c = step.coverage
+ if c then
+ for g1, d1 in next, c do
+ d1[2] = pack_indexed(d1[2])
+ end
+ end
+ end
+ -- if ... chain ...
+ local rules = step.rules
+ if rules then
+ for i=1,#rules do
+ local rule = rules[i]
+ 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
+ end
+ end
+ if order then
+ sequence.order = pack_indexed(order)
+ end
+ if features then
+ for script, feature in next, features do
+ features[script] = pack_normal(feature)
+ end
+ end
+ if flags then
+ sequence.flags = pack_normal(flags)
+ end
+ end
+ end
+
+ if sequences then
+ packthem(sequences)
+ end
+
+ if sublookups then
+ packthem(sublookups)
+ end
+
+ if features then
+ for k, list in next, features do
+ for feature, spec in next, list do
+ list[feature] = pack_normal(spec)
+ end
+ end
+ end
+
+ if palettes then
+ for i=1,#palettes do
+ local p = palettes[i]
+ for j=1,#p do
+ p[j] = pack_indexed(p[j])
+ end
+ end
+
+ end
+
+ if variable then
+
+ -- todo: segments
+
+ local instances = variable.instances
+ if instances then
+ for i=1,#instances do
+ local v = instances[i].values
+ for j=1,#v do
+ v[j] = pack_normal(v[j])
+ end
+ end
+ end
+
+ local function packdeltas(main)
+ if main then
+ local deltas = main.deltas
+ if deltas then
+ for i=1,#deltas do
+ local di = deltas[i]
+ local d = di.deltas
+ -- local r = di.regions
+ for j=1,#d do
+ d[j] = pack_indexed(d[j])
+ end
+ di.regions = pack_indexed(di.regions)
+ end
+ end
+ local regions = main.regions
+ if regions then
+ for i=1,#regions do
+ local r = regions[i]
+ for j=1,#r do
+ r[j] = pack_normal(r[j])
+ end
+ end
+ end
+ end
+ end
+
+ packdeltas(variable.global)
+ packdeltas(variable.horizontal)
+ packdeltas(variable.vertical)
+ packdeltas(variable.metrics)
+
+ end
+
+ if not success(1,pass) then
+ return
+ end
+
+ end
+
+ if nt > 0 then
+
+ for pass=1,2 do
+
+ if trace_packing then
+ report_otf("start packing: stage 2, pass %s",pass)
+ end
+
+ local pack_normal, pack_indexed, pack_flat, pack_boolean, pack_mixed, pack_normal_cc = packers(pass)
+
+ for unicode, description in next, descriptions do
+ local math = description.math
+ if math then
+ local kerns = math.kerns
+ if kerns then
+ math.kerns = pack_normal(kerns)
+ end
+ end
+ end
+
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence = sequences[i]
+ local kind = sequence.type
+ local steps = sequence.steps
+ local features = sequence.features
+ if steps then
+ for i=1,#steps do
+ local step = steps[i]
+ if kind == "gpos_pair" then
+ local c = step.coverage
+ if c then
+ if step.format == "pair" then
+ for g1, d1 in next, c do
+ for g2, d2 in next, d1 do
+ d1[g2] = pack_normal(d2)
+ end
+ end
+ end
+ end
+ -- elseif kind == "gpos_cursive" then
+ -- local c = step.coverage -- new
+ -- if c then
+ -- for g1, d1 in next, c do
+ -- c[g1] = pack_normal_cc(d1)
+ -- end
+ -- end
+ elseif kind == "gpos_mark2ligature" then
+ local c = step.baseclasses -- new
+ if c then
+ for g1, d1 in next, c do
+ for g2, d2 in next, d1 do
+ d1[g2] = pack_normal(d2)
+ end
+ end
+ end
+ end
+ local rules = step.rules
+ if rules then
+ for i=1,#rules do
+ local rule = rules[i]
+ local r = rule.before if r then rule.before = pack_normal(r) end
+ local r = rule.after if r then rule.after = pack_normal(r) end
+ local r = rule.current if r then rule.current = pack_normal(r) end
+ end
+ end
+ end
+ end
+ if features then
+ sequence.features = pack_normal(features)
+ end
+ end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+ if variable then
+ local function unpackdeltas(main)
+ if main then
+ local regions = main.regions
+ if regions then
+ main.regions = pack_normal(regions)
+ end
+ end
+ end
+ unpackdeltas(variable.global)
+ unpackdeltas(variable.horizontal)
+ unpackdeltas(variable.vertical)
+ unpackdeltas(variable.metrics)
+ end
+ -- if not success(2,pass) then
+ -- -- return
+ -- end
+ end
+
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 3, pass %s",pass)
+ end
+
+ local pack_normal, pack_indexed, pack_flat, pack_boolean, pack_mixed, pack_normal_cc = packers(pass)
+
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence = sequences[i]
+ local kind = sequence.type
+ local steps = sequence.steps
+ local features = sequence.features
+ if steps then
+ for i=1,#steps do
+ local step = steps[i]
+ if kind == "gpos_pair" then
+ local c = step.coverage
+ if c then
+ if step.format == "pair" then
+ for g1, d1 in next, c do
+ c[g1] = pack_normal(d1)
+ end
+ end
+ end
+ elseif kind == "gpos_cursive" then
+ local c = step.coverage
+ if c then
+ for g1, d1 in next, c do
+ c[g1] = pack_normal_cc(d1)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+
+ end
+
+ end
+
+ end
+end
+
+local unpacked_mt = {
+ __index =
+ function(t,k)
+ t[k] = false
+ return k -- next time true
+ end
+}
+
+function readers.unpack(data)
+
+ if data then
+ local tables = data.tables
+ if tables then
+ local resources = data.resources
+ local descriptions = data.descriptions or data.glyphs
+ local sequences = resources.sequences
+ local sublookups = resources.sublookups
+ local features = resources.features
+ local palettes = resources.colorpalettes
+ local variable = resources.variabledata
+ local unpacked = { }
+ setmetatable(unpacked,unpacked_mt)
+ for unicode, description in next, descriptions do
+ local tv = tables[description.boundingbox]
+ if tv then
+ description.boundingbox = tv
+ end
+ local math = description.math
+ if math then
+ local kerns = math.kerns
+ if kerns then
+ local tm = tables[kerns]
+ if tm then
+ math.kerns = tm
+ kerns = unpacked[tm]
+ end
+ if kerns then
+ for k, kern in next, kerns do
+ local tv = tables[kern]
+ if tv then
+ kerns[k] = tv
+ end
+ end
+ end
+ end
+ end
+ -- if palettes then
+ -- local color = description.color
+ -- if color then
+ -- for i=1,#color do
+ -- local tv = tables[color[i]]
+ -- if tv then
+ -- color[i] = tv
+ -- end
+ -- end
+ -- end
+ -- end
+ end
+
+ -- local function expandranges(t,ranges)
+ -- for i=1,#ranges do
+ -- local r = ranges[i]
+ -- for k=r[1],r[2] do
+ -- t[k] = true
+ -- end
+ -- end
+ -- end
+
+ local function unpackthem(sequences)
+ for i=1,#sequences do
+ local sequence = sequences[i]
+ local kind = sequence.type
+ local steps = sequence.steps
+ local order = sequence.order
+ local features = sequence.features
+ local flags = sequence.flags
+ local markclass = sequence.markclass
+ if features then
+ local tv = tables[features]
+ if tv then
+ sequence.features = tv
+ features = tv
+ end
+ for script, feature in next, features do
+ local tv = tables[feature]
+ if tv then
+ features[script] = tv
+ end
+ end
+ end
+ if steps then
+ for i=1,#steps do
+ local step = steps[i]
+ if kind == "gpos_pair" then
+ local c = step.coverage
+ if c then
+ if step.format == "pair" then
+ for g1, d1 in next, c do
+ local tv = tables[d1]
+ if tv then
+ c[g1] = tv
+ d1 = tv
+ end
+ for g2, d2 in next, d1 do
+ local tv = tables[d2]
+ if tv then
+ d1[g2] = tv
+ d2 = tv
+ end
+ local f = tables[d2[1]] if f then d2[1] = f end
+ local s = tables[d2[2]] if s then d2[2] = s end
+ end
+ end
+ else
+ for g1, d1 in next, c do
+ local tv = tables[d1]
+ if tv then
+ c[g1] = tv
+ end
+ end
+ end
+ end
+ elseif kind == "gpos_single" then
+ local c = step.coverage
+ if c then
+ if step.format == "single" then
+ for g1, d1 in next, c do
+ local tv = tables[d1]
+ if tv then
+ c[g1] = tv
+ end
+ end
+ else
+ local tv = tables[c]
+ if tv then
+ step.coverage = tv
+ end
+ end
+ end
+ elseif kind == "gpos_cursive" then
+ local c = step.coverage
+ if c then
+ for g1, d1 in next, c do
+ local tv = tables[d1]
+ if tv then
+ d1 = tv
+ c[g1] = d1
+ end
+ local f = tables[d1[2]] if f then d1[2] = f end
+ local s = tables[d1[3]] if s then d1[3] = s end
+ end
+ end
+ elseif kind == "gpos_mark2base" or kind == "gpos_mark2mark" then
+ local c = step.baseclasses
+ if c then
+ for g1, d1 in next, c do
+ for g2, d2 in next, d1 do
+ local tv = tables[d2]
+ if tv then
+ d1[g2] = tv
+ end
+ end
+ end
+ end
+ local c = step.coverage
+ if c then
+ for g1, d1 in next, c do
+ local tv = tables[d1[2]]
+ if tv then
+ d1[2] = tv
+ end
+ end
+ end
+ elseif kind == "gpos_mark2ligature" then
+ local c = step.baseclasses
+ if c then
+ for g1, d1 in next, c do
+ for g2, d2 in next, d1 do
+ local tv = tables[d2] -- new
+ if tv then
+ d2 = tv
+ d1[g2] = d2
+ end
+ for g3, d3 in next, d2 do
+ local tv = tables[d2[g3]]
+ if tv then
+ d2[g3] = tv
+ end
+ end
+ end
+ end
+ end
+ local c = step.coverage
+ if c then
+ for g1, d1 in next, c do
+ local tv = tables[d1[2]]
+ if tv then
+ d1[2] = tv
+ end
+ end
+ end
+ end
+ local rules = step.rules
+ if rules then
+ for i=1,#rules do
+ local rule = rules[i]
+ local before = rule.before
+ if before then
+ local tv = tables[before]
+ if tv then
+ rule.before = tv
+ before = tv
+ end
+ for i=1,#before do
+ local tv = tables[before[i]]
+ if tv then
+ before[i] = tv
+ end
+ end
+ -- for i=1,#before do
+ -- local bi = before[i]
+ -- local tv = tables[bi]
+ -- if tv then
+ -- bi = tv
+ -- before[i] = bi
+ -- end
+ -- local ranges = bi.ranges
+ -- if ranges then
+ -- expandranges(bi,ranges)
+ -- end
+ -- end
+ end
+ local after = rule.after
+ if after then
+ local tv = tables[after]
+ if tv then
+ rule.after = tv
+ after = tv
+ end
+ for i=1,#after do
+ local tv = tables[after[i]]
+ if tv then
+ after[i] = tv
+ end
+ end
+ -- for i=1,#after do
+ -- local ai = after[i]
+ -- local tv = tables[ai]
+ -- if tv then
+ -- ai = tv
+ -- after[i] = ai
+ -- end
+ -- local ranges = ai.ranges
+ -- if ranges then
+ -- expandranges(ai,ranges)
+ -- end
+ -- end
+ end
+ local current = rule.current
+ if current then
+ local tv = tables[current]
+ if tv then
+ rule.current = tv
+ current = tv
+ end
+ for i=1,#current do
+ local tv = tables[current[i]]
+ if tv then
+ current[i] = tv
+ end
+ end
+ -- for i=1,#current do
+ -- local ci = current[i]
+ -- local tv = tables[ci]
+ -- if tv then
+ -- ci = tv
+ -- current[i] = ci
+ -- end
+ -- local ranges = ci.ranges
+ -- if ranges then
+ -- expandranges(ci,ranges)
+ -- 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]
+ if tv then
+ rule.replacements = tv
+ end
+ end
+ end
+ end
+ end
+ end
+ if order then
+ local tv = tables[order]
+ if tv then
+ sequence.order = tv
+ end
+ end
+ if flags then
+ local tv = tables[flags]
+ if tv then
+ sequence.flags = tv
+ end
+ end
+ end
+ end
+
+ if sequences then
+ unpackthem(sequences)
+ end
+
+ if sublookups then
+ unpackthem(sublookups)
+ end
+
+ if features then
+ for k, list in next, features do
+ for feature, spec in next, list do
+ local tv = tables[spec]
+ if tv then
+ list[feature] = tv
+ end
+ end
+ end
+ end
+
+ if palettes then
+ for i=1,#palettes do
+ local p = palettes[i]
+ for j=1,#p do
+ local tv = tables[p[j]]
+ if tv then
+ p[j] = tv
+ end
+ end
+ end
+ end
+
+ if variable then
+
+ -- todo: segments
+
+ local instances = variable.instances
+ if instances then
+ for i=1,#instances do
+ local v = instances[i].values
+ for j=1,#v do
+ local tv = tables[v[j]]
+ if tv then
+ v[j] = tv
+ end
+ end
+ end
+ end
+
+ local function unpackdeltas(main)
+ if main then
+ local deltas = main.deltas
+ if deltas then
+ for i=1,#deltas do
+ local di = deltas[i]
+ local d = di.deltas
+ local r = di.regions
+ for j=1,#d do
+ local tv = tables[d[j]]
+ if tv then
+ d[j] = tv
+ end
+ end
+ local tv = di.regions
+ if tv then
+ di.regions = tv
+ end
+ end
+ end
+ local regions = main.regions
+ if regions then
+ local tv = tables[regions]
+ if tv then
+ main.regions = tv
+ regions = tv
+ end
+ for i=1,#regions do
+ local r = regions[i]
+ for j=1,#r do
+ local tv = tables[r[j]]
+ if tv then
+ r[j] = tv
+ end
+ end
+ end
+ end
+ end
+ end
+
+ unpackdeltas(variable.global)
+ unpackdeltas(variable.horizontal)
+ unpackdeltas(variable.vertical)
+ unpackdeltas(variable.metrics)
+
+ end
+
+ data.tables = nil
+ end
+ end
+end
+
+local mt = {
+ __index = function(t,k) -- maybe set it
+ if k == "height" then
+ local ht = t.boundingbox[4]
+ return ht < 0 and 0 or ht
+ elseif k == "depth" then
+ local dp = -t.boundingbox[2]
+ return dp < 0 and 0 or dp
+ elseif k == "width" then
+ return 0
+ elseif k == "name" then -- or maybe uni*
+ return forcenotdef and ".notdef"
+ end
+ end
+}
+
+local function sameformat(sequence,steps,first,nofsteps,kind)
+ return true
+end
+
+local function mergesteps_1(lookup,strict)
+ local steps = lookup.steps
+ local nofsteps = lookup.nofsteps
+ local first = steps[1]
+ if strict then
+ local f = first.format
+ for i=2,nofsteps do
+ if steps[i].format ~= f then
+ if trace_optimizations then
+ report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
+ end
+ return 0
+ end
+ end
+ end
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target = first.coverage
+ for i=2,nofsteps do
+ local c = steps[i].coverage
+ if c then
+ for k, v in next, c do
+ if not target[k] then
+ target[k] = v
+ end
+ end
+ end
+ end
+ lookup.nofsteps = 1
+ lookup.merged = true
+ lookup.steps = { first }
+ return nofsteps - 1
+end
+
+local function mergesteps_2(lookup) -- pairs
+ -- this can be tricky as we can have a match on a mark with no marks skip flag
+ -- in which case with multiple steps a hit can prevent a next step while in the
+ -- merged case we can hit differently (a messy font then anyway)
+ local steps = lookup.steps
+ local nofsteps = lookup.nofsteps
+ local first = steps[1]
+ if strict then
+ local f = first.format
+ for i=2,nofsteps do
+ if steps[i].format ~= f then
+ if trace_optimizations then
+ report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
+ end
+ return 0
+ end
+ end
+ end
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target = first.coverage
+ for i=2,nofsteps do
+ local c = steps[i].coverage
+ if c then
+ for k, v in next, c do
+ local tk = target[k]
+ if tk then
+ for kk, vv in next, v do
+ if tk[kk] == nil then
+ tk[kk] = vv
+ end
+ end
+ else
+ target[k] = v
+ end
+ end
+ end
+ end
+ lookup.nofsteps = 1
+ lookup.merged = true
+ lookup.steps = { first }
+ return nofsteps - 1
+end
+
+-- we could have a coverage[first][second] = { } already here (because eventually
+-- we also have something like that after loading)
+
+local function mergesteps_3(lookup,strict) -- marks
+ local steps = lookup.steps
+ local nofsteps = lookup.nofsteps
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ -- check first
+ local coverage = { }
+ for i=1,nofsteps do
+ local c = steps[i].coverage
+ if c then
+ for k, v in next, c do
+ local tk = coverage[k] -- { class, { x, y } }
+ if tk then
+ if trace_optimizations then
+ report_optimizations("quitting merge due to multiple checks")
+ end
+ return nofsteps
+ else
+ coverage[k] = v
+ end
+ end
+ end
+ end
+ -- merge indeed
+ local first = steps[1]
+ local baseclasses = { } -- let's assume sparse step.baseclasses
+ for i=1,nofsteps do
+ local offset = i*10 -- we assume max 10 classes per step
+ local step = steps[i]
+ for k, v in sortedhash(step.baseclasses) do
+ baseclasses[offset+k] = v
+ end
+ for k, v in next, step.coverage do
+ v[1] = offset + v[1]
+ end
+ end
+ first.baseclasses = baseclasses
+ first.coverage = coverage
+ lookup.nofsteps = 1
+ lookup.merged = true
+ lookup.steps = { first }
+ return nofsteps - 1
+end
+
+local function nested(old,new)
+ for k, v in next, old do
+ if k == "ligature" then
+ if not new.ligature then
+ new.ligature = v
+ end
+ else
+ local n = new[k]
+ if n then
+ nested(v,n)
+ else
+ new[k] = v
+ end
+ end
+ end
+end
+
+local function mergesteps_4(lookup) -- ligatures
+ local steps = lookup.steps
+ local nofsteps = lookup.nofsteps
+ local first = steps[1]
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target = first.coverage
+ for i=2,nofsteps do
+ local c = steps[i].coverage
+ if c then
+ for k, v in next, c do
+ local tk = target[k]
+ if tk then
+ nested(v,tk)
+ else
+ target[k] = v
+ end
+ end
+ end
+ end
+ lookup.nofsteps = 1
+ lookup.steps = { first }
+ return nofsteps - 1
+end
+
+-- so we assume only one cursive entry and exit and even then the first one seems
+-- to win anyway: no exit or entry quite the lookup match and then we take the
+-- next step; this means that we can as well merge them
+
+local function mergesteps_5(lookup) -- cursive
+ local steps = lookup.steps
+ local nofsteps = lookup.nofsteps
+ local first = steps[1]
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target = first.coverage
+ local hash = nil
+ for k, v in next, target do
+ hash = v[1]
+ break
+ end
+ for i=2,nofsteps do
+ local c = steps[i].coverage
+ if c then
+ for k, v in next, c do
+ local tk = target[k]
+ if tk then
+ if not tk[2] then
+ tk[2] = v[2]
+ end
+ if not tk[3] then
+ tk[3] = v[3]
+ end
+ else
+ target[k] = v
+ v[1] = hash
+ end
+ end
+ end
+ end
+ lookup.nofsteps = 1
+ lookup.merged = true
+ lookup.steps = { first }
+ return nofsteps - 1
+end
+
+local function checkkerns(lookup)
+ local steps = lookup.steps
+ local nofsteps = lookup.nofsteps
+ local kerned = 0
+ for i=1,nofsteps do
+ local step = steps[i]
+ if step.format == "pair" then
+ local coverage = step.coverage
+ local kerns = true
+ for g1, d1 in next, coverage do
+ if d1 == true then
+ -- all zero
+ elseif not d1 then
+ -- null
+ elseif d1[1] ~= 0 or d1[2] ~= 0 or d1[4] ~= 0 then
+ kerns = false
+ break
+ end
+ end
+ if kerns then
+ if trace_optimizations then
+ report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
+ end
+ local c = { }
+ for g1, d1 in next, coverage do
+ if d1 and d1 ~= true then
+ c[g1] = d1[3]
+ end
+ end
+ step.coverage = c
+ step.format = "move"
+ kerned = kerned + 1
+ end
+ end
+ end
+ return kerned
+end
+
+-- There are several options to optimize but we have this somewhat fuzzy aspect of
+-- advancing (depending on the second of a pair) so we need to retain that information.
+--
+-- We can have:
+--
+-- true, nil|false
+--
+-- which effectively means: nothing to be done and advance to next (so not next of
+-- next) and because coverage should be not overlapping we can wipe these. However,
+-- checking for (true,nil) (false,nil) and omitting them doesn't gain much.
+
+-- Because we pack we cannot mix tables and numbers so we can only turn a whole set in
+-- format kern instead of pair.
+
+local function checkpairs(lookup)
+ local steps = lookup.steps
+ local nofsteps = lookup.nofsteps
+ local kerned = 0
+
+ local function onlykerns(step)
+ local coverage = step.coverage
+ for g1, d1 in next, coverage do
+ for g2, d2 in next, d1 do
+ if d2[2] then
+ --- true or { a, b, c, d }
+ return false
+ else
+ local v = d2[1]
+ if v == true then
+ -- all zero
+ elseif v and (v[1] ~= 0 or v[2] ~= 0 or v[4] ~= 0) then
+ return false
+ end
+ end
+ end
+ end
+ return coverage
+ end
+
+ for i=1,nofsteps do
+ local step = steps[i]
+ if step.format == "pair" then
+ local coverage = onlykerns(step)
+ if coverage then
+ if trace_optimizations then
+ report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
+ end
+ for g1, d1 in next, coverage do
+ local d = { }
+ for g2, d2 in next, d1 do
+ local v = d2[1]
+ if v == true then
+ -- ignore -- d1[g2] = nil
+ elseif v then
+ d[g2] = v[3] -- d1[g2] = v[3]
+ end
+ end
+ coverage[g1] = d
+ end
+ step.format = "move"
+ kerned = kerned + 1
+ end
+ end
+ end
+ return kerned
+end
+
+local compact_pairs = true
+local compact_singles = true
+
+local merge_pairs = true
+local merge_singles = true
+local merge_substitutions = true
+local merge_alternates = true
+local merge_multiples = true
+local merge_ligatures = true
+local merge_cursives = true
+local merge_marks = true
+
+directives.register("otf.compact.pairs", function(v) compact_pairs = v end)
+directives.register("otf.compact.singles", function(v) compact_singles = v end)
+
+directives.register("otf.merge.pairs", function(v) merge_pairs = v end)
+directives.register("otf.merge.singles", function(v) merge_singles = v end)
+directives.register("otf.merge.substitutions", function(v) merge_substitutions = v end)
+directives.register("otf.merge.alternates", function(v) merge_alternates = v end)
+directives.register("otf.merge.multiples", function(v) merge_multiples = v end)
+directives.register("otf.merge.ligatures", function(v) merge_ligatures = v end)
+directives.register("otf.merge.cursives", function(v) merge_cursives = v end)
+directives.register("otf.merge.marks", function(v) merge_marks = v end)
+
+function readers.compact(data)
+ if not data or data.compacted then
+ return
+ else
+ data.compacted = true
+ end
+ local resources = data.resources
+ local merged = 0
+ local kerned = 0
+ local allsteps = 0
+ local function compact(what)
+ local lookups = resources[what]
+ if lookups then
+ for i=1,#lookups do
+ local lookup = lookups[i]
+ local nofsteps = lookup.nofsteps
+ local kind = lookup.type
+ allsteps = allsteps + nofsteps
+ if nofsteps > 1 then
+ local merg = merged
+ if kind == "gsub_single" then
+ if merge_substitutions then
+ merged = merged + mergesteps_1(lookup)
+ end
+ elseif kind == "gsub_alternate" then
+ if merge_alternates then
+ merged = merged + mergesteps_1(lookup)
+ end
+ elseif kind == "gsub_multiple" then
+ if merge_multiples then
+ merged = merged + mergesteps_1(lookup)
+ end
+ elseif kind == "gsub_ligature" then
+ if merge_ligatures then
+ merged = merged + mergesteps_4(lookup)
+ end
+ elseif kind == "gpos_single" then
+ if merge_singles then
+ merged = merged + mergesteps_1(lookup,true)
+ end
+ if compact_singles then
+ kerned = kerned + checkkerns(lookup)
+ end
+ elseif kind == "gpos_pair" then
+ if merge_pairs then
+ merged = merged + mergesteps_2(lookup)
+ end
+ if compact_pairs then
+ kerned = kerned + checkpairs(lookup)
+ end
+ elseif kind == "gpos_cursive" then
+ if merge_cursives then
+ merged = merged + mergesteps_5(lookup)
+ end
+ elseif kind == "gpos_mark2mark" or kind == "gpos_mark2base" or kind == "gpos_mark2ligature" then
+ if merge_marks then
+ merged = merged + mergesteps_3(lookup)
+ end
+ end
+ if merg ~= merged then
+ lookup.merged = true
+ end
+ elseif nofsteps == 1 then
+ local kern = kerned
+ if kind == "gpos_single" then
+ if compact_singles then
+ kerned = kerned + checkkerns(lookup)
+ end
+ elseif kind == "gpos_pair" then
+ if compact_pairs then
+ kerned = kerned + checkpairs(lookup)
+ end
+ end
+ if kern ~= kerned then
+ -- lookup.kerned = true
+ end
+ end
+ end
+ elseif trace_optimizations then
+ report_optimizations("no lookups in %a",what)
+ end
+ end
+ compact("sequences")
+ compact("sublookups")
+ if trace_optimizations then
+ if merged > 0 then
+ report_optimizations("%i steps of %i removed due to merging",merged,allsteps)
+ end
+ if kerned > 0 then
+ report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps)
+ end
+ end
+end
+
+local function mergesteps(t,k)
+ if k == "merged" then
+ local merged = { }
+ for i=1,#t do
+ local step = t[i]
+ local coverage = step.coverage
+ for k in next, coverage do
+ local m = merged[k]
+ if m then
+ m[2] = i
+ -- m[#m+1] = step
+ else
+ merged[k] = { i, i }
+ -- merged[k] = { step }
+ end
+ end
+ end
+ t.merged = merged
+ return merged
+ end
+end
+
+local function checkmerge(sequence)
+ local steps = sequence.steps
+ if steps then
+ setmetatableindex(steps,mergesteps)
+ end
+end
+
+local function checkflags(sequence,resources)
+ if not sequence.skiphash then
+ local flags = sequence.flags
+ if flags then
+ local skipmark = flags[1]
+ local skipligature = flags[2]
+ local skipbase = flags[3]
+ local markclass = sequence.markclass
+ local skipsome = skipmark or skipligature or skipbase or markclass or false
+ if skipsome then
+ sequence.skiphash = setmetatableindex(function(t,k)
+ local c = resources.classes[k] -- delayed table
+ local v = c == skipmark
+ or (markclass and c == "mark" and not markclass[k])
+ or c == skipligature
+ or c == skipbase
+ or false
+ t[k] = v
+ return v
+ end)
+ else
+ sequence.skiphash = false
+ end
+ else
+ sequence.skiphash = false
+ end
+ end
+end
+
+local function checksteps(sequence)
+ local steps = sequence.steps
+ if steps then
+ for i=1,#steps do
+ steps[i].index = i
+ end
+ end
+end
+
+if fonts.helpers then
+ fonts.helpers.checkmerge = checkmerge
+ fonts.helpers.checkflags = checkflags
+ fonts.helpers.checksteps = checksteps -- has to happen last
+end
+
+function readers.expand(data)
+ if not data or data.expanded then
+ return
+ else
+ data.expanded = true
+ end
+ local resources = data.resources
+ local sublookups = resources.sublookups
+ local sequences = resources.sequences -- were one level up
+ local markclasses = resources.markclasses
+ local descriptions = data.descriptions
+ if descriptions then
+ local defaultwidth = resources.defaultwidth or 0
+ local defaultheight = resources.defaultheight or 0
+ local defaultdepth = resources.defaultdepth or 0
+ local basename = trace_markwidth and file.basename(resources.filename)
+ for u, d in next, descriptions do
+ local bb = d.boundingbox
+ local wd = d.width
+ if not wd then
+ -- or bb?
+ d.width = defaultwidth
+ elseif trace_markwidth and wd ~= 0 and d.class == "mark" then
+ report_markwidth("mark %a with width %b found in %a",d.name or "<noname>",wd,basename)
+ end
+ if bb then
+ local ht = bb[4]
+ local dp = -bb[2]
+ if ht == 0 or ht < 0 then
+ -- not set
+ else
+ d.height = ht
+ end
+ if dp == 0 or dp < 0 then
+ -- not set
+ else
+ d.depth = dp
+ end
+ end
+ end
+ end
+
+ -- using a merged combined hash as first test saves some 30% on ebgaramond and
+ -- about 15% on arabtype .. then moving the a test also saves a bit (even when
+ -- often a is not set at all so that one is a bit debatable
+
+ local function expandlookups(sequences)
+ if sequences then
+ -- we also need to do sublookups
+ for i=1,#sequences do
+ local sequence = sequences[i]
+ local steps = sequence.steps
+ if steps then
+ local nofsteps = sequence.nofsteps
+
+ local kind = sequence.type
+ local markclass = sequence.markclass
+ if markclass then
+ if not markclasses then
+ report_warning("missing markclasses")
+ sequence.markclass = false
+ else
+ sequence.markclass = markclasses[markclass]
+ end
+ end
+
+ for i=1,nofsteps do
+ local step = steps[i]
+ local baseclasses = step.baseclasses
+ if baseclasses then
+ local coverage = step.coverage
+ for k, v in next, coverage do
+ v[1] = baseclasses[v[1]] -- slot 1 is a placeholder
+ end
+ elseif kind == "gpos_cursive" then
+ local coverage = step.coverage
+ for k, v in next, coverage do
+ v[1] = coverage -- slot 1 is a placeholder
+ end
+ end
+ local rules = step.rules
+ if rules then
+ local rulehash = { n = 0 } -- is contexts in font-ots
+ local rulesize = 0
+ local coverage = { }
+ local lookuptype = sequence.type
+ local nofrules = #rules
+ step.coverage = coverage -- combined hits
+ for currentrule=1,nofrules do
+ local rule = rules[currentrule]
+ local current = rule.current
+ local before = rule.before
+ local after = rule.after
+ local replacements = rule.replacements or false
+ local sequence = { }
+ local nofsequences = 0
+ if before then
+ for n=1,#before do
+ nofsequences = nofsequences + 1
+ sequence[nofsequences] = before[n]
+ end
+ end
+ local start = nofsequences + 1
+ for n=1,#current do
+ nofsequences = nofsequences + 1
+ sequence[nofsequences] = current[n]
+ end
+ local stop = nofsequences
+ if after then
+ for n=1,#after do
+ nofsequences = nofsequences + 1
+ sequence[nofsequences] = after[n]
+ end
+ end
+ local lookups = rule.lookups or false
+ local subtype = nil
+ if lookups then
+ for i=1,#lookups do
+ local lookups = lookups[i]
+ if lookups then
+ for k, v in next, lookups do -- actually this one is indexed
+ local lookup = sublookups[v]
+ if lookup then
+ lookups[k] = lookup
+ if not subtype then
+ subtype = lookup.type
+ end
+ else
+ -- already expanded
+ end
+ end
+ end
+ end
+ end
+ if sequence[1] then -- we merge coverage into one
+ sequence.n = #sequence -- tiny speedup
+ local ruledata = {
+ currentrule, -- 1 -- original rule number, only use this for tracing!
+ lookuptype, -- 2
+ sequence, -- 3
+ start, -- 4
+ stop, -- 5
+ lookups, -- 6 (6/7 also signal of what to do)
+ replacements, -- 7
+ subtype, -- 8
+ }
+ --
+ -- possible optimization: per [unic] a rulehash, but beware:
+ -- contexts have unique coverage and chains can have multiple
+ -- hits (rules) per coverage entry
+ --
+ -- so: we can combine multiple steps as well as multiple rules
+ -- but that takes careful checking, in which case we can go the
+ -- step list approach and turn contexts into steps .. in fact,
+ -- if we turn multiple contexts into steps we're already ok as
+ -- steps gets a coverage hash by metatable
+ --
+ rulesize = rulesize + 1
+ rulehash[rulesize] = ruledata
+ rulehash.n = rulesize -- tiny speedup
+ --
+ if true then -- nofrules > 1
+
+ for unic in next, sequence[start] do
+ local cu = coverage[unic]
+ if cu then
+ local n = #cu+1
+ cu[n] = ruledata
+ cu.n = n
+ else
+ coverage[unic] = { ruledata, n = 1 }
+ end
+ end
+
+ else
+
+ for unic in next, sequence[start] do
+ local cu = coverage[unic]
+ if cu then
+ -- we can have a contextchains with many matches which we
+ -- can actually optimize
+ else
+ coverage[unic] = rulehash
+ end
+ end
+
+ end
+ end
+ end
+ end
+ end
+
+ checkmerge(sequence)
+ checkflags(sequence,resources)
+ checksteps(sequence)
+
+ end
+ end
+ end
+ end
+
+ expandlookups(sequences)
+ expandlookups(sublookups)
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua b/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
new file mode 100644
index 0000000000..651ede17e2
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
@@ -0,0 +1,1379 @@
+if not modules then modules = { } end modules ['font-ttf'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This version is different from previous in the sense that we no longer store
+-- contours but keep points and contours (endpoints) separate for a while
+-- because later on we need to apply deltas and that is easier on a list of
+-- points.
+
+-- The code is a bit messy. I looked at the ff code but it's messy too. It has
+-- to do with the fact that we need to look at points on the curve and control
+-- points in between. This also means that we start at point 2 and have to look
+-- at point 1 when we're at the end. We still use a ps like storage with the
+-- operator last in an entry. It's typical code that evolves stepwise till a
+-- point of no comprehension.
+
+-- For deltas we need a rather complex loop over points that can have holes and
+-- be less than nofpoints and even can have duplicates and also the x and y value
+-- lists can be shorter than etc. I need fonts in order to complete this simply
+-- because I need to visualize in order to understand (what the standard tries
+-- to explain).
+
+-- 0 point then none applied
+-- 1 points then applied to all
+-- otherwise inferred deltas using nearest
+-- if no lower point then use highest referenced point
+-- if no higher point then use lowest referenced point
+-- factor = (target-left)/(right-left)
+-- delta = (1-factor)*left + factor * right
+
+local next, type, unpack = next, type, unpack
+local band, rshift = bit32.band, bit32.rshift
+local sqrt, round = math.sqrt, math.round
+local char, rep = string.char, string.rep
+local concat = table.concat
+local idiv = number.idiv
+local setmetatableindex = table.setmetatableindex
+
+local report = logs.reporter("otf reader","ttf")
+
+local trace_deltas = false
+
+local readers = fonts.handlers.otf.readers
+local streamreader = readers.streamreader
+
+local setposition = streamreader.setposition
+local getposition = streamreader.getposition
+local skipbytes = streamreader.skip
+local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer
+local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer
+local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer
+local readchar = streamreader.readinteger1 -- 8-bit signed integer
+local readshort = streamreader.readinteger2 -- 16-bit signed integer
+local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14)
+local readinteger = streamreader.readinteger1
+local readcardinaltable = streamreader.readcardinaltable
+local readintegertable = streamreader.readintegertable
+
+directives.register("fonts.streamreader",function()
+
+ streamreader = utilities.streams
+
+ setposition = streamreader.setposition
+ getposition = streamreader.getposition
+ skipbytes = streamreader.skip
+ readbyte = streamreader.readcardinal1
+ readushort = streamreader.readcardinal2
+ readulong = streamreader.readcardinal4
+ readchar = streamreader.readinteger1
+ readshort = streamreader.readinteger2
+ read2dot14 = streamreader.read2dot14
+ readinteger = streamreader.readinteger1
+ readcardinaltable = streamreader.readcardinaltable
+ readintegertable = streamreader.readintegertable
+
+end)
+
+local short = 2
+local ushort = 2
+local ulong = 4
+
+local helpers = readers.helpers
+local gotodatatable = helpers.gotodatatable
+
+local function mergecomposites(glyphs,shapes)
+
+ -- todo : deltas
+
+ local function merge(index,shape,components)
+ local contours = { }
+ local points = { }
+ local nofcontours = 0
+ local nofpoints = 0
+ local offset = 0
+ local deltas = shape.deltas
+ for i=1,#components do
+ local component = components[i]
+ local subindex = component.index
+ local subshape = shapes[subindex]
+ local subcontours = subshape.contours
+ local subpoints = subshape.points
+ if not subcontours then
+ local subcomponents = subshape.components
+ if subcomponents then
+ subcontours, subpoints = merge(subindex,subshape,subcomponents)
+ end
+ end
+ if subpoints then
+ local matrix = component.matrix
+ local xscale = matrix[1]
+ local xrotate = matrix[2]
+ local yrotate = matrix[3]
+ local yscale = matrix[4]
+ local xoffset = matrix[5]
+ local yoffset = matrix[6]
+ local count = #subpoints
+ if xscale == 1 and yscale == 1 and xrotate == 0 and yrotate == 0 then
+ for i=1,count do
+ local p = subpoints[i]
+ nofpoints = nofpoints + 1
+ points[nofpoints] = {
+ p[1] + xoffset,
+ p[2] + yoffset,
+ p[3]
+ }
+ end
+ else
+ for i=1,count do
+ local p = subpoints[i]
+ local x = p[1]
+ local y = p[2]
+ nofpoints = nofpoints + 1
+ points[nofpoints] = {
+ xscale * x + xrotate * y + xoffset,
+ yscale * y + yrotate * x + yoffset,
+ p[3]
+ }
+ end
+ end
+ local subcount = #subcontours
+ if subcount == 1 then
+ nofcontours = nofcontours + 1
+ contours[nofcontours] = offset + subcontours[1]
+ else
+ for i=1,#subcontours do
+ nofcontours = nofcontours + 1
+ contours[nofcontours] = offset + subcontours[i]
+ end
+ end
+ offset = offset + count
+ else
+ report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex)
+ end
+ end
+ shape.points = points -- todo : phantom points
+ shape.contours = contours
+ shape.components = nil
+ return contours, points
+ end
+
+-- for index=1,#glyphs do
+ for index=0,#glyphs-1 do
+ local shape = shapes[index]
+ if shape then
+ local components = shape.components
+ if components then
+ merge(index,shape,components)
+ end
+ end
+ end
+
+end
+
+local function readnothing(f)
+ return {
+ type = "nothing",
+ }
+end
+
+-- begin of converter
+
+local function curveto(m_x,m_y,l_x,l_y,r_x,r_y) -- todo: inline this
+ return
+ l_x + 2/3 *(m_x-l_x), l_y + 2/3 *(m_y-l_y),
+ r_x + 2/3 *(m_x-r_x), r_y + 2/3 *(m_y-r_y),
+ r_x, r_y, "c"
+end
+
+-- We could omit the operator which saves some 10%:
+--
+-- #2=lineto #4=quadratic #6=cubic #3=moveto (with "m")
+--
+-- This is tricky ... something to do with phantom points .. however, the hvar
+-- and vvar tables should take care of the width .. the test font doesn't have
+-- those so here we go then (we need a flag for hvar).
+--
+-- h-advance left-side-bearing v-advance top-side-bearing
+--
+-- We had two loops (going backward) but can do it in one loop .. but maybe we
+-- should only accept fonts with proper hvar tables.
+
+local function applyaxis(glyph,shape,deltas,dowidth)
+ local points = shape.points
+ if points then
+ local nofpoints = #points
+ local h = nofpoints + 2 -- weird, the example font seems to have left first
+ local l = nofpoints + 1
+ ----- v = nofpoints + 3
+ ----- t = nofpoints + 4
+ local dw = 0
+ local dl = 0
+ for i=1,#deltas do
+ local deltaset = deltas[i]
+ local xvalues = deltaset.xvalues
+ local yvalues = deltaset.yvalues
+ local dpoints = deltaset.points
+ local factor = deltaset.factor
+ if dpoints then
+ -- todo: interpolate
+ local nofdpoints = #dpoints
+ for i=1,nofdpoints do
+ local d = dpoints[i]
+ local p = points[d]
+ if p then
+ if xvalues then
+ local x = xvalues[i]
+ if x and x ~= 0 then
+ p[1] = p[1] + factor * x
+ end
+ end
+ if yvalues then
+ local y = yvalues[i]
+ if y and y ~= 0 then
+ p[2] = p[2] + factor * y
+ end
+ end
+ elseif dowidth then
+ -- we've now ran into phantom points which is a bit fuzzy because:
+ -- are there gaps in there?
+ --
+ -- todo: move this outside the loop (when we can be sure of all 4 being there)
+ if d == h then
+ -- we have a phantom point hadvance
+ local x = xvalues[i]
+ if x then
+ dw = dw + factor * x
+ end
+ elseif d == l then
+ local x = xvalues[i]
+ if x then
+ dl = dl + factor * x
+ end
+ end
+ end
+ end
+ else
+ for i=1,nofpoints do
+ local p = points[i]
+ if xvalues then
+ local x = xvalues[i]
+ if x and x ~= 0 then
+ p[1] = p[1] + factor * x
+ end
+ end
+ if yvalues then
+ local y = yvalues[i]
+ if y and y ~= 0 then
+ p[2] = p[2] + factor * y
+ end
+ end
+ end
+ if dowidth then
+ local x = xvalues[h]
+ if x then
+ dw = dw + factor * x
+ end
+ local x = xvalues[l]
+ if x then
+ dl = dl + factor * x
+ end
+ end
+ end
+ end
+ -- for i=1,nofpoints do
+ -- local p = points[i]
+ -- p[1] = round(p[1])
+ -- p[2] = round(p[2])
+ -- end
+ if dowidth then
+ local width = glyph.width or 0
+ -- local lsb = glyph.lsb or 0
+ glyph.width = width + dw - dl
+ end
+ else
+ report("no points for glyph %a",glyph.name)
+ end
+end
+
+-- round or not ?
+
+-- local quadratic = true -- both methods work, todo: install a directive
+local quadratic = false
+
+local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox overhead
+-- for index=1,#glyphs do
+ for index=0,#glyphs-1 do
+ local shape = shapes[index]
+ if shape then
+ local glyph = glyphs[index]
+ local contours = shape.contours
+ local points = shape.points
+ if contours then
+ local nofcontours = #contours
+ local segments = { }
+ local nofsegments = 0
+ glyph.segments = segments
+ if nofcontours > 0 then
+ local px = 0
+ local py = 0
+ local first = 1
+ for i=1,nofcontours do
+ local last = contours[i]
+ if last >= first then
+ local first_pt = points[first]
+ local first_on = first_pt[3]
+ -- todo no new tables but reuse lineto and quadratic
+ if first == last then
+ first_pt[3] = "m" -- "moveto"
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = first_pt
+ else -- maybe also treat n == 2 special
+ local first_on = first_pt[3]
+ local last_pt = points[last]
+ local last_on = last_pt[3]
+ local start = 1
+ local control_pt = false
+ if first_on then
+ start = 2
+ else
+ if last_on then
+ first_pt = last_pt
+ else
+ first_pt = { (first_pt[1]+last_pt[1])/2, (first_pt[2]+last_pt[2])/2, false }
+ end
+ control_pt = first_pt
+ end
+ local x = first_pt[1]
+ local y = first_pt[2]
+ if not done then
+ xmin = x
+ ymin = y
+ xmax = x
+ ymax = y
+ done = true
+ end
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x, y, "m" } -- "moveto"
+ if not quadratic then
+ px = x
+ py = y
+ end
+ local previous_pt = first_pt
+ for i=first,last do
+ local current_pt = points[i]
+ local current_on = current_pt[3]
+ local previous_on = previous_pt[3]
+ if previous_on then
+ if current_on then
+ -- both normal points
+ local x, y = current_pt[1], current_pt[2]
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x, y, "l" } -- "lineto"
+ if not quadratic then
+ px, py = x, y
+ end
+ else
+ control_pt = current_pt
+ end
+ elseif current_on then
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ local x2 = current_pt[1]
+ local y2 = current_pt[2]
+ nofsegments = nofsegments + 1
+ if quadratic then
+ segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
+ else
+ x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
+ segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
+ end
+ control_pt = false
+ else
+ local x2 = (previous_pt[1]+current_pt[1])/2
+ local y2 = (previous_pt[2]+current_pt[2])/2
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ nofsegments = nofsegments + 1
+ if quadratic then
+ segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
+ else
+ x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
+ segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
+ end
+ control_pt = current_pt
+ end
+ previous_pt = current_pt
+ end
+ if first_pt == last_pt then
+ -- we're already done, probably a simple curve
+ else
+ nofsegments = nofsegments + 1
+ local x2 = first_pt[1]
+ local y2 = first_pt[2]
+ if not control_pt then
+ segments[nofsegments] = { x2, y2, "l" } -- "lineto"
+ elseif quadratic then
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
+ else
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
+ segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
+ -- px, py = x2, y2
+ end
+ end
+ end
+ end
+ first = last + 1
+ end
+ end
+ end
+ end
+ end
+end
+
+local function contours2outlines_shaped(glyphs,shapes,keepcurve)
+-- for index=1,#glyphs do
+ for index=0,#glyphs-1 do
+ local shape = shapes[index]
+ if shape then
+ local glyph = glyphs[index]
+ local contours = shape.contours
+ local points = shape.points
+ if contours then
+ local nofcontours = #contours
+ local segments = keepcurve and { } or nil
+ local nofsegments = 0
+ if keepcurve then
+ glyph.segments = segments
+ end
+ if nofcontours > 0 then
+ local xmin, ymin, xmax, ymax, done = 0, 0, 0, 0, false
+ local px, py = 0, 0 -- we could use these in calculations which saves a copy
+ local first = 1
+ for i=1,nofcontours do
+ local last = contours[i]
+ if last >= first then
+ local first_pt = points[first]
+ local first_on = first_pt[3]
+ -- todo no new tables but reuse lineto and quadratic
+ if first == last then
+ -- this can influence the boundingbox
+ if keepcurve then
+ first_pt[3] = "m" -- "moveto"
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = first_pt
+ end
+ else -- maybe also treat n == 2 special
+ local first_on = first_pt[3]
+ local last_pt = points[last]
+ local last_on = last_pt[3]
+ local start = 1
+ local control_pt = false
+ if first_on then
+ start = 2
+ else
+ if last_on then
+ first_pt = last_pt
+ else
+ first_pt = { (first_pt[1]+last_pt[1])/2, (first_pt[2]+last_pt[2])/2, false }
+ end
+ control_pt = first_pt
+ end
+ local x = first_pt[1]
+ local y = first_pt[2]
+ if not done then
+ xmin, ymin, xmax, ymax = x, y, x, y
+ done = true
+ else
+ if x < xmin then xmin = x elseif x > xmax then xmax = x end
+ if y < ymin then ymin = y elseif y > ymax then ymax = y end
+ end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x, y, "m" } -- "moveto"
+ end
+ if not quadratic then
+ px = x
+ py = y
+ end
+ local previous_pt = first_pt
+ for i=first,last do
+ local current_pt = points[i]
+ local current_on = current_pt[3]
+ local previous_on = previous_pt[3]
+ if previous_on then
+ if current_on then
+ -- both normal points
+ local x = current_pt[1]
+ local y = current_pt[2]
+ if x < xmin then xmin = x elseif x > xmax then xmax = x end
+ if y < ymin then ymin = y elseif y > ymax then ymax = y end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x, y, "l" } -- "lineto"
+ end
+ if not quadratic then
+ px = x
+ py = y
+ end
+ else
+ control_pt = current_pt
+ end
+ elseif current_on then
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ local x2 = current_pt[1]
+ local y2 = current_pt[2]
+ if quadratic then
+ if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end
+ if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
+ end
+ else
+ x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
+ if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end
+ if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end
+ if x2 < xmin then xmin = x2 elseif x2 > xmax then xmax = x2 end
+ if y2 < ymin then ymin = y2 elseif y2 > ymax then ymax = y2 end
+ if px < xmin then xmin = px elseif px > xmax then xmax = px end
+ if py < ymin then ymin = py elseif py > ymax then ymax = py end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
+ end
+ end
+ control_pt = false
+ else
+ local x2 = (previous_pt[1]+current_pt[1])/2
+ local y2 = (previous_pt[2]+current_pt[2])/2
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ if quadratic then
+ if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end
+ if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
+ end
+ else
+ x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
+ if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end
+ if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end
+ if x2 < xmin then xmin = x2 elseif x2 > xmax then xmax = x2 end
+ if y2 < ymin then ymin = y2 elseif y2 > ymax then ymax = y2 end
+ if px < xmin then xmin = px elseif px > xmax then xmax = px end
+ if py < ymin then ymin = py elseif py > ymax then ymax = py end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
+ end
+ end
+ control_pt = current_pt
+ end
+ previous_pt = current_pt
+ end
+ if first_pt == last_pt then
+ -- we're already done, probably a simple curve
+ elseif not control_pt then
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { first_pt[1], first_pt[2], "l" } -- "lineto"
+ end
+ else
+ local x1 = control_pt[1]
+ local y1 = control_pt[2]
+ local x2 = first_pt[1]
+ local y2 = first_pt[2]
+ if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end
+ if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end
+ if quadratic then
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto"
+ end
+ else
+ x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2)
+ if x2 < xmin then xmin = x2 elseif x2 > xmax then xmax = x2 end
+ if y2 < ymin then ymin = y2 elseif y2 > ymax then ymax = y2 end
+ if px < xmin then xmin = px elseif px > xmax then xmax = px end
+ if py < ymin then ymin = py elseif py > ymax then ymax = py end
+ if keepcurve then
+ nofsegments = nofsegments + 1
+ segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto"
+ end
+ -- px, py = x2, y2
+ end
+ end
+ end
+ end
+ first = last + 1
+ end
+ glyph.boundingbox = { round(xmin), round(ymin), round(xmax), round(ymax) }
+ end
+ end
+ end
+ end
+end
+
+-- optimize for zero
+
+local c_zero = char(0)
+local s_zero = char(0,0)
+
+-- local shorthash = setmetatableindex(function(t,k)
+-- t[k] = char(band(rshift(k,8),0xFF),band(k,0xFF)) return t[k]
+-- end)
+
+local function toushort(n)
+ return char(band(rshift(n,8),0xFF),band(n,0xFF))
+ -- return shorthash[n]
+end
+
+local function toshort(n)
+ if n < 0 then
+ n = n + 0x10000
+ end
+ return char(band(rshift(n,8),0xFF),band(n,0xFF))
+ -- return shorthash[n]
+end
+
+-- todo: we can reuse result, xpoints and ypoints
+
+local chars = setmetatableindex(function(t,k)
+ for i=0,255 do local v = char(i) t[i] = v end return t[k]
+end)
+
+local function repackpoints(glyphs,shapes)
+ local noboundingbox = { 0, 0, 0, 0 }
+ local result = { } -- reused
+ local xpoints = { } -- reused
+ local ypoints = { } -- reused
+ for index=0,#glyphs-1 do
+ local shape = shapes[index]
+ if shape then
+ local r = 0
+ local glyph = glyphs[index]
+ local contours = shape.contours
+ local nofcontours = contours and #contours or 0
+ local boundingbox = glyph.boundingbox or noboundingbox
+ r = r + 1 result[r] = toshort(nofcontours)
+ r = r + 1 result[r] = toshort(boundingbox[1]) -- xmin
+ r = r + 1 result[r] = toshort(boundingbox[2]) -- ymin
+ r = r + 1 result[r] = toshort(boundingbox[3]) -- xmax
+ r = r + 1 result[r] = toshort(boundingbox[4]) -- ymax
+ if nofcontours > 0 then
+ for i=1,nofcontours do
+ r = r + 1 result[r] = toshort(contours[i]-1)
+ end
+ r = r + 1 result[r] = s_zero -- no instructions
+ local points = shape.points
+ local currentx = 0
+ local currenty = 0
+ -- local xpoints = { }
+ -- local ypoints = { }
+ local x = 0
+ local y = 0
+ local lastflag = nil
+ local nofflags = 0
+ for i=1,#points do
+ local pt = points[i]
+ local px = pt[1]
+ local py = pt[2]
+ local fl = pt[3] and 0x01 or 0x00
+ if px == currentx then
+ fl = fl + 0x10
+ else
+ local dx = round(px - currentx)
+ x = x + 1
+ if dx < -255 or dx > 255 then
+ xpoints[x] = toshort(dx)
+ elseif dx < 0 then
+ fl = fl + 0x02
+ -- xpoints[x] = char(-dx)
+ xpoints[x] = chars[-dx]
+ elseif dx > 0 then
+ fl = fl + 0x12
+ -- xpoints[x] = char(dx)
+ xpoints[x] = chars[dx]
+ else
+ fl = fl + 0x02
+ xpoints[x] = c_zero
+ end
+ end
+ if py == currenty then
+ fl = fl + 0x20
+ else
+ local dy = round(py - currenty)
+ y = y + 1
+ if dy < -255 or dy > 255 then
+ ypoints[y] = toshort(dy)
+ elseif dy < 0 then
+ fl = fl + 0x04
+ -- ypoints[y] = char(-dy)
+ ypoints[y] = chars[-dy]
+ elseif dy > 0 then
+ fl = fl + 0x24
+ -- ypoints[y] = char(dy)
+ ypoints[y] = chars[dy]
+ else
+ fl = fl + 0x04
+ ypoints[y] = c_zero
+ end
+ end
+ currentx = px
+ currenty = py
+ if lastflag == fl then
+ if nofflags == 255 then
+ -- This happens in koeieletters!
+ lastflag = lastflag + 0x08
+ r = r + 1 result[r] = char(lastflag,nofflags-1)
+ nofflags = 1
+ lastflag = fl
+ else
+ nofflags = nofflags + 1
+ end
+ else -- if > 255
+ if nofflags == 1 then
+ -- r = r + 1 result[r] = char(lastflag)
+ r = r + 1 result[r] = chars[lastflag]
+ elseif nofflags == 2 then
+ r = r + 1 result[r] = char(lastflag,lastflag)
+ elseif nofflags > 2 then
+ lastflag = lastflag + 0x08
+ r = r + 1 result[r] = char(lastflag,nofflags-1)
+ end
+ nofflags = 1
+ lastflag = fl
+ end
+ end
+ if nofflags == 1 then
+ -- r = r + 1 result[r] = char(lastflag)
+ r = r + 1 result[r] = chars[lastflag]
+ elseif nofflags == 2 then
+ r = r + 1 result[r] = char(lastflag,lastflag)
+ elseif nofflags > 2 then
+ lastflag = lastflag + 0x08
+ r = r + 1 result[r] = char(lastflag,nofflags-1)
+ end
+ -- r = r + 1 result[r] = concat(xpoints)
+ -- r = r + 1 result[r] = concat(ypoints)
+ r = r + 1 result[r] = concat(xpoints,"",1,x)
+ r = r + 1 result[r] = concat(ypoints,"",1,y)
+ end
+ -- can be helper or delegated to user
+ local stream = concat(result,"",1,r)
+ local length = #stream
+ local padding = idiv(length+3,4) * 4 - length
+ if padding > 0 then
+ -- stream = stream .. rep("\0",padding) -- can be a repeater
+ if padding == 1 then
+ padding = "\0"
+ elseif padding == 2 then
+ padding = "\0\0"
+ else
+ padding = "\0\0\0"
+ end
+ padding = stream .. padding
+ end
+ glyph.stream = stream
+ end
+ end
+end
+
+-- end of converter
+
+local flags = { }
+
+local function readglyph(f,nofcontours) -- read deltas here, saves space
+ local points = { }
+ -- local instructions = { }
+ local contours = { } -- readintegertable(f,nofcontours,short)
+ for i=1,nofcontours do
+ contours[i] = readshort(f) + 1
+ end
+ local nofpoints = contours[nofcontours]
+ local nofinstructions = readushort(f)
+ skipbytes(f,nofinstructions)
+ -- because flags can repeat we don't know the amount ... in fact this is
+ -- not that efficient (small files but more mem)
+ local i = 1
+ while i <= nofpoints do
+ local flag = readbyte(f)
+ flags[i] = flag
+ if band(flag,0x08) ~= 0 then
+ local n = readbyte(f)
+ if n == 1 then
+ i = i + 1
+ flags[i] = flag
+ else
+ for j=1,n do
+ i = i + 1
+ flags[i] = flag
+ end
+ end
+ end
+ i = i + 1
+ end
+ -- first come the x coordinates, and next the y coordinates and they
+ -- can be repeated
+ local x = 0
+ for i=1,nofpoints do
+ local flag = flags[i]
+ -- local short = band(flag,0x04) ~= 0
+ -- local same = band(flag,0x20) ~= 0
+ if band(flag,0x02) ~= 0 then
+ if band(flag,0x10) ~= 0 then
+ x = x + readbyte(f)
+ else
+ x = x - readbyte(f)
+ end
+ elseif band(flag,0x10) ~= 0 then
+ -- copy
+ else
+ x = x + readshort(f)
+ end
+ points[i] = { x, 0, band(flag,0x01) ~= 0 }
+ end
+ local y = 0
+ for i=1,nofpoints do
+ local flag = flags[i]
+ -- local short = band(flag,0x04) ~= 0
+ -- local same = band(flag,0x20) ~= 0
+ if band(flag,0x04) ~= 0 then
+ if band(flag,0x20) ~= 0 then
+ y = y + readbyte(f)
+ else
+ y = y - readbyte(f)
+ end
+ elseif band(flag,0x20) ~= 0 then
+ -- copy
+ else
+ y = y + readshort(f)
+ end
+ points[i][2] = y
+ end
+ return {
+ type = "glyph",
+ points = points,
+ contours = contours,
+ nofpoints = nofpoints,
+ }
+end
+
+local function readcomposite(f)
+ local components = { }
+ local nofcomponents = 0
+ local instructions = false
+ while true do
+ local flags = readushort(f)
+ local index = readushort(f)
+ ----- f_words = band(flags,0x0001) ~= 0
+ local f_xyarg = band(flags,0x0002) ~= 0
+ ----- f_round = band(flags,0x0006) ~= 0 -- 2 + 4
+ ----- f_scale = band(flags,0x0008) ~= 0
+ ----- f_reserved = band(flags,0x0010) ~= 0
+ ----- f_more = band(flags,0x0020) ~= 0
+ ----- f_xyscale = band(flags,0x0040) ~= 0
+ ----- f_matrix = band(flags,0x0080) ~= 0
+ ----- f_instruct = band(flags,0x0100) ~= 0
+ ----- f_usemine = band(flags,0x0200) ~= 0
+ ----- f_overlap = band(flags,0x0400) ~= 0
+ local f_offset = band(flags,0x0800) ~= 0
+ ----- f_uoffset = band(flags,0x1000) ~= 0
+ local xscale = 1
+ local xrotate = 0
+ local yrotate = 0
+ local yscale = 1
+ local xoffset = 0
+ local yoffset = 0
+ local base = false
+ local reference = false
+ if f_xyarg then
+ if band(flags,0x0001) ~= 0 then -- f_words
+ xoffset = readshort(f)
+ yoffset = readshort(f)
+ else
+ xoffset = readchar(f) -- signed byte, stupid name
+ yoffset = readchar(f) -- signed byte, stupid name
+ end
+ else
+ if band(flags,0x0001) ~= 0 then -- f_words
+ base = readshort(f)
+ reference = readshort(f)
+ else
+ base = readchar(f) -- signed byte, stupid name
+ reference = readchar(f) -- signed byte, stupid name
+ end
+ end
+ if band(flags,0x0008) ~= 0 then -- f_scale
+ xscale = read2dot14(f)
+ yscale = xscale
+ if f_xyarg and f_offset then
+ xoffset = xoffset * xscale
+ yoffset = yoffset * yscale
+ end
+ elseif band(flags,0x0040) ~= 0 then -- f_xyscale
+ xscale = read2dot14(f)
+ yscale = read2dot14(f)
+ if f_xyarg and f_offset then
+ xoffset = xoffset * xscale
+ yoffset = yoffset * yscale
+ end
+ elseif band(flags,0x0080) ~= 0 then -- f_matrix
+ xscale = read2dot14(f)
+ xrotate = read2dot14(f)
+ yrotate = read2dot14(f)
+ yscale = read2dot14(f)
+ if f_xyarg and f_offset then
+ xoffset = xoffset * sqrt(xscale ^2 + xrotate^2)
+ yoffset = yoffset * sqrt(yrotate^2 + yscale ^2)
+ end
+ end
+ nofcomponents = nofcomponents + 1
+ components[nofcomponents] = {
+ index = index,
+ usemine = band(flags,0x0200) ~= 0, -- f_usemine
+ round = band(flags,0x0006) ~= 0, -- f_round,
+ base = base,
+ reference = reference,
+ matrix = { xscale, xrotate, yrotate, yscale, xoffset, yoffset },
+ }
+ if band(flags,0x0100) ~= 0 then
+ instructions = true
+ end
+ if band(flags,0x0020) == 0 then -- f_more
+ break
+ end
+ end
+ return {
+ type = "composite",
+ components = components,
+ }
+end
+
+-- function readers.cff(f,offset,glyphs,doshapes) -- false == no shapes (nil or true otherwise)
+
+-- The glyf table depends on the loca table. We have one entry to much
+-- in the locations table (the last one is a dummy) because we need to
+-- calculate the size of a glyph blob from the delta, although we not
+-- need it in our usage (yet). We can remove the locations table when
+-- we're done (todo: cleanup finalizer).
+
+function readers.loca(f,fontdata,specification)
+ if specification.glyphs then
+ local datatable = fontdata.tables.loca
+ if datatable then
+ -- locations are relative to the glypdata table (glyf)
+ local offset = fontdata.tables.glyf.offset
+ local format = fontdata.fontheader.indextolocformat
+ local profile = fontdata.maximumprofile
+ local nofglyphs = profile and profile.nofglyphs
+ local locations = { }
+ setposition(f,datatable.offset)
+ if format == 1 then
+ if not nofglyphs then
+ nofglyphs = idiv(datatable.length,4) - 1
+ end
+ for i=0,nofglyphs do
+ locations[i] = offset + readulong(f)
+ end
+ fontdata.nofglyphs = nofglyphs
+ else
+ if not nofglyphs then
+ nofglyphs = idiv(datatable.length,2) - 1
+ end
+ for i=0,nofglyphs do
+ locations[i] = offset + readushort(f) * 2
+ end
+ end
+ fontdata.nofglyphs = nofglyphs
+ fontdata.locations = locations
+ end
+ end
+end
+
+function readers.glyf(f,fontdata,specification) -- part goes to cff module
+ local tableoffset = gotodatatable(f,fontdata,"glyf",specification.glyphs)
+ if tableoffset then
+ local locations = fontdata.locations
+ if locations then
+ local glyphs = fontdata.glyphs
+ local nofglyphs = fontdata.nofglyphs
+ local filesize = fontdata.filesize
+ local nothing = { 0, 0, 0, 0 }
+ local shapes = { }
+ local loadshapes = specification.shapes or specification.instance or specification.streams
+ for index=0,nofglyphs-1 do
+ local location = locations[index]
+ local length = locations[index+1] - location
+ if location >= filesize then
+ report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1)
+ fontdata.nofglyphs = index - 1
+ fontdata.badfont = true
+ break
+ elseif length > 0 then
+ setposition(f,location)
+ local nofcontours = readshort(f)
+ glyphs[index].boundingbox = {
+ readshort(f), -- xmin
+ readshort(f), -- ymin
+ readshort(f), -- xmax
+ readshort(f), -- ymax
+ }
+ if not loadshapes then
+ -- save space
+ elseif nofcontours == 0 then
+ shapes[index] = readnothing(f)
+ elseif nofcontours > 0 then
+ shapes[index] = readglyph(f,nofcontours)
+ else
+ shapes[index] = readcomposite(f,nofcontours)
+ end
+ else
+ if loadshapes then
+ shapes[index] = readnothing(f)
+ end
+ glyphs[index].boundingbox = nothing
+ end
+ end
+ if loadshapes then
+ if readers.gvar then
+ readers.gvar(f,fontdata,specification,glyphs,shapes)
+ end
+ mergecomposites(glyphs,shapes)
+ if specification.instance then
+ if specification.streams then
+ repackpoints(glyphs,shapes)
+ else
+ contours2outlines_shaped(glyphs,shapes,specification.shapes)
+ end
+ elseif specification.shapes then
+ if specification.streams then
+ repackpoints(glyphs,shapes)
+ else
+ contours2outlines_normal(glyphs,shapes)
+ end
+ elseif specification.streams then
+ repackpoints(glyphs,shapes)
+ end
+ end
+ end
+ end
+end
+
+-- gvar is a bit crazy format and one can really wonder if the bit-jugling obscurity
+-- is still needed in these days .. cff is much nicer with these blends while the ttf
+-- coding variant looks quite horrible
+
+local function readtuplerecord(f,nofaxis)
+ local record = { }
+ for i=1,nofaxis do
+ record[i] = read2dot14(f)
+ end
+ return record
+end
+
+-- (1) the first is a real point the rest deltas
+-- (2) points can be present more than once (multiple deltas then)
+
+local function readpoints(f)
+ local count = readbyte(f)
+ if count == 0 then
+ -- second byte not used, deltas for all point numbers
+ return nil, 0 -- todo
+ else
+ if count < 128 then
+ -- no second byte, use count
+ elseif band(count,0x80) ~= 0 then
+ count = band(count,0x7F) * 256 + readbyte(f)
+ else
+ -- bad news
+ end
+ local points = { }
+ local p = 0
+ local n = 1 -- indices
+ while p < count do
+ local control = readbyte(f)
+ local runreader = band(control,0x80) ~= 0 and readushort or readbyte
+ local runlength = band(control,0x7F)
+ for i=1,runlength+1 do
+ n = n + runreader(f)
+ p = p + 1
+ points[p] = n
+ end
+ end
+ return points, p
+ end
+end
+
+local function readdeltas(f,nofpoints)
+ local deltas = { }
+ local p = 0
+ local z = 0
+ while nofpoints > 0 do
+ local control = readbyte(f)
+if not control then
+ break
+end
+ local allzero = band(control,0x80) ~= 0
+ local runlength = band(control,0x3F) + 1
+ if allzero then
+ z = z + runlength
+ else
+ local runreader = band(control,0x40) ~= 0 and readshort or readinteger
+ if z > 0 then
+ for i=1,z do
+ p = p + 1
+ deltas[p] = 0
+ end
+ z = 0
+ end
+ for i=1,runlength do
+ p = p + 1
+ deltas[p] = runreader(f)
+ end
+ end
+ nofpoints = nofpoints - runlength
+ end
+ -- saves space
+-- if z > 0 then
+-- for i=1,z do
+-- p = p + 1
+-- deltas[p] = 0
+-- end
+-- end
+ if p > 0 then
+ -- forget about trailing zeros
+ return deltas
+ else
+ -- forget about all zeros
+ end
+end
+
+local function readdeltas(f,nofpoints)
+ local deltas = { }
+ local p = 0
+ while nofpoints > 0 do
+ local control = readbyte(f)
+ if control then
+ local allzero = band(control,0x80) ~= 0
+ local runlength = band(control,0x3F) + 1
+ if allzero then
+ for i=1,runlength do
+ p = p + 1
+ deltas[p] = 0
+ end
+ else
+ local runreader = band(control,0x40) ~= 0 and readshort or readinteger
+ for i=1,runlength do
+ p = p + 1
+ deltas[p] = runreader(f)
+ end
+ end
+ nofpoints = nofpoints - runlength
+ else
+ -- it happens
+ break
+ end
+ end
+ -- saves space
+ if p > 0 then
+ return deltas
+ else
+ -- forget about all zeros
+ end
+end
+
+function readers.gvar(f,fontdata,specification,glyphdata,shapedata)
+ -- this is one of the messiest tables
+ local instance = specification.instance
+ if not instance then
+ return
+ end
+ local factors = specification.factors
+ if not factors then
+ return
+ end
+ local tableoffset = gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes)
+ if tableoffset then
+ local version = readulong(f) -- 1.0
+ local nofaxis = readushort(f)
+ local noftuples = readushort(f)
+ local tupleoffset = tableoffset + readulong(f)
+ local nofglyphs = readushort(f)
+ local flags = readushort(f)
+ local dataoffset = tableoffset + readulong(f)
+ local data = { }
+ local tuples = { }
+ local glyphdata = fontdata.glyphs
+ local dowidth = not fontdata.variabledata.hvarwidths
+ -- there is one more offset (so that one can calculate the size i suppose)
+ -- so we could test for overflows but we simply assume sane font files
+ if band(flags,0x0001) ~= 0 then
+ for i=1,nofglyphs+1 do
+ data[i] = dataoffset + readulong(f)
+ end
+ else
+ for i=1,nofglyphs+1 do
+ data[i] = dataoffset + 2*readushort(f)
+ end
+ end
+ --
+ if noftuples > 0 then
+ setposition(f,tupleoffset)
+ for i=1,noftuples do
+ tuples[i] = readtuplerecord(f,nofaxis)
+ end
+ end
+ local nextoffset = false
+ local startoffset = data[1]
+ for i=1,nofglyphs do -- hm one more cf spec
+ nextoffset = data[i+1]
+ local glyph = glyphdata[i-1]
+ local name = trace_deltas and glyph.name
+ if startoffset == nextoffset then
+ if name then
+ report("no deltas for glyph %a",name)
+ end
+ else
+ local shape = shapedata[i-1] -- todo 0
+ if not shape then
+ if name then
+ report("no shape for glyph %a",name)
+ end
+ else
+ lastoffset = startoffset
+ setposition(f,startoffset)
+ local flags = readushort(f)
+ local count = band(flags,0x0FFF)
+ local offset = startoffset + readushort(f) -- to serialized
+ local deltas = { }
+ local allpoints = (shape.nofpoints or 0) -- + 1
+ local shared = false
+ local nofshared = 0
+ if band(flags,0x8000) ~= 0 then -- has shared points
+ -- go to the packed stream (get them once)
+ local current = getposition(f)
+ setposition(f,offset)
+ shared, nofshared = readpoints(f)
+ offset = getposition(f)
+ setposition(f,current)
+ -- and back to the table
+ end
+ for j=1,count do
+ local size = readushort(f) -- check
+ local flags = readushort(f)
+ local index = band(flags,0x0FFF)
+ local haspeak = band(flags,0x8000) ~= 0
+ local intermediate = band(flags,0x4000) ~= 0
+ local private = band(flags,0x2000) ~= 0
+ local peak = nil
+ local start = nil
+ local stop = nil
+ local xvalues = nil
+ local yvalues = nil
+ local points = shared -- we default to shared
+ local nofpoints = nofshared -- we default to shared
+ -- local advance = 4
+ if haspeak then
+ peak = readtuplerecord(f,nofaxis)
+ -- advance = advance + 2*nofaxis
+ else
+ if index+1 > #tuples then
+ report("error, bad tuple index",index)
+ end
+ peak = tuples[index+1] -- hm, needs checking, only peak?
+ end
+ if intermediate then
+ start = readtuplerecord(f,nofaxis)
+ stop = readtuplerecord(f,nofaxis)
+ -- advance = advance + 4*nofaxis
+ end
+ -- get the deltas
+ if size > 0 then
+ local current = getposition(f)
+ -- goto the packed stream
+ setposition(f,offset)
+ if private then
+ points, nofpoints = readpoints(f)
+ end -- else
+ if nofpoints == 0 then
+ nofpoints = allpoints + 4
+ end
+ if nofpoints > 0 then
+ -- a nice test is to do only one
+ xvalues = readdeltas(f,nofpoints)
+ yvalues = readdeltas(f,nofpoints)
+ end
+ -- resync offset
+ offset = offset + size
+ -- back to the table
+ setposition(f,current)
+ end
+ if not xvalues and not yvalues then
+ points = nil
+ end
+ local s = 1
+ for i=1,nofaxis do
+ local f = factors[i]
+ local peak = peak and peak [i] or 0
+ -- local start = start and start[i] or 0
+ -- local stop = stop and stop [i] or 0
+ local start = start and start[i] or (peak < 0 and peak or 0)
+ local stop = stop and stop [i] or (peak > 0 and peak or 0)
+ -- do we really need these tests ... can't we assume sane values
+ if start > peak or peak > stop then
+ -- * 1
+ elseif start < 0 and stop > 0 and peak ~= 0 then
+ -- * 1
+ elseif peak == 0 then
+ -- * 1
+ elseif f < start or f > stop then
+ -- * 0
+ s = 0
+ break
+ elseif f < peak then
+-- s = - s * (f - start) / (peak - start)
+ s = s * (f - start) / (peak - start)
+ elseif f > peak then
+ s = s * (stop - f) / (stop - peak)
+ else
+ -- * 1
+ end
+ end
+ if s == 0 then
+ if name then
+ report("no deltas applied for glyph %a",name)
+ end
+ else
+ deltas[#deltas+1] = {
+ factor = s,
+ points = points,
+ xvalues = xvalues,
+ yvalues = yvalues,
+ }
+ end
+ end
+ if shape.type == "glyph" then
+ applyaxis(glyph,shape,deltas,dowidth)
+ else
+ -- todo: args_are_xy_values mess .. i have to be really bored
+ -- and motivated to deal with it
+ shape.deltas = deltas
+ end
+ end
+ end
+ startoffset = nextoffset
+ end
+ end
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-vfc.lua b/macros/luatex/generic/luaotfload/fontloader-font-vfc.lua
new file mode 100644
index 0000000000..dfe6b3afc4
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-font-vfc.lua
@@ -0,0 +1,123 @@
+if not modules then modules = { } end modules ['font-vfc'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv and hand-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local select, type = select, type
+local insert = table.insert
+
+local fonts = fonts
+local helpers = fonts.helpers
+
+local setmetatableindex = table.setmetatableindex
+local makeweak = table.makeweak
+
+-- Helpers dealing with virtual fonts: beware, these are final values so
+-- don't change the content of tables gotten this way!
+
+local push = { "push" }
+local pop = { "pop" }
+local dummy = { "comment" }
+
+function helpers.prependcommands(commands,...)
+ insert(commands,1,push)
+ for i=select("#",...),1,-1 do
+ local s = (select(i,...))
+ if s then
+ insert(commands,1,s)
+ end
+ end
+ insert(commands,pop)
+ return commands
+end
+
+function helpers.appendcommands(commands,...)
+ insert(commands,1,push)
+ insert(commands,pop)
+ for i=1,select("#",...) do
+ local s = (select(i,...))
+ if s then
+ insert(commands,s)
+ end
+ end
+ return commands
+end
+
+function helpers.prependcommandtable(commands,t)
+ insert(commands,1,push)
+ for i=#t,1,-1 do
+ local s = t[i]
+ if s then
+ insert(commands,1,s)
+ end
+ end
+ insert(commands,pop)
+ return commands
+end
+
+function helpers.appendcommandtable(commands,t)
+ insert(commands,1,push)
+ insert(commands,pop)
+ for i=1,#t do
+ local s = t[i]
+ if s then
+ insert(commands,s)
+ end
+ end
+ return commands
+end
+
+-- todo: maybe weak
+-- todo: maybe indirect so that we can't change them
+
+local char = setmetatableindex(function(t,k)
+ -- local v = { "char", k }
+ local v = { "slot", 0, k }
+ t[k] = v
+ return v
+end)
+
+local right = setmetatableindex(function(t,k)
+ local v = { "right", k }
+ t[k] = v
+ return v
+end)
+
+local left = setmetatableindex(function(t,k)
+ local v = { "right", -k }
+ t[k] = v
+ return v
+end)
+
+local down = setmetatableindex(function(t,k)
+ local v = { "down", k }
+ t[k] = v
+ return v
+end)
+
+local up = setmetatableindex(function(t,k)
+ local v = { "down", -k }
+ t[k] = v
+ return v
+end)
+
+-- makeweak(char)
+-- makeweak(right)
+-- makeweak(left)
+-- makeweak(up)
+-- makeweak(down)
+
+helpers.commands = utilities.storage.allocate {
+ char = char,
+ right = right,
+ left = left,
+ down = down,
+ up = up,
+ push = push,
+ pop = pop,
+ dummy = dummy,
+}
+
diff --git a/macros/luatex/generic/luaotfload/fontloader-fonts-def.lua b/macros/luatex/generic/luaotfload/fontloader-fonts-def.lua
new file mode 100644
index 0000000000..883451fb5e
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-fonts-def.lua
@@ -0,0 +1,98 @@
+if not modules then modules = { } end modules ['luatex-fonts-def'] = {
+ version = 1.001,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+if context then
+ os.exit()
+end
+
+local fonts = fonts
+
+-- A bit of tuning for definitions.
+
+fonts.constructors.namemode = "specification" -- somehow latex needs this (changed name!) => will change into an overload
+
+-- tricky: we sort of bypass the parser and directly feed all into
+-- the sub parser
+
+function fonts.definers.getspecification(str)
+ return "", str, "", ":", str
+end
+
+-- the generic name parser (different from context!)
+
+local list = { } -- we could pass Carg but let's keep the old one
+
+local function issome () list.lookup = 'name' end -- xetex mode prefers name (not in context!)
+local function isfile () list.lookup = 'file' end
+local function isname () list.lookup = 'name' end
+local function thename(s) list.name = s end
+local function issub (v) list.sub = v end
+local function iscrap (s) list.crap = string.lower(s) end
+local function iskey (k,v) list[k] = v end
+local function istrue (s) list[s] = true end
+local function isfalse(s) list[s] = false end
+
+local P, S, R, C, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs
+
+local spaces = P(" ")^0
+local namespec = Cs((P("{")/"") * (1-S("}"))^0 * (P("}")/"") + (1-S("/:("))^0)
+local crapspec = spaces * P("/") * (((1-P(":"))^0)/iscrap) * spaces
+local filename_1 = P("file:")/isfile * (namespec/thename)
+local filename_2 = P("[") * P(true)/isfile * (((1-P("]"))^0)/thename) * P("]")
+local fontname_1 = P("name:")/isname * (namespec/thename)
+local fontname_2 = P(true)/issome * (namespec/thename)
+local sometext = R("az","AZ","09")^1
+local somekey = R("az","AZ","09")^1
+local somevalue = (P("{")/"")*(1-P("}"))^0*(P("}")/"") + (1-S(";"))^1
+local truevalue = P("+") * spaces * (sometext/istrue)
+local falsevalue = P("-") * spaces * (sometext/isfalse)
+local keyvalue = (C(somekey) * spaces * P("=") * spaces * C(somevalue))/iskey
+local somevalue = sometext/istrue
+local subvalue = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim
+local option = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces
+local options = P(":") * spaces * (P(";")^0 * option)^0
+
+local pattern = (filename_1 + filename_2 + fontname_1 + fontname_2)
+ * subvalue^0 * crapspec^0 * options^0
+
+function fonts.definers.analyze(str,size)
+ local specification = fonts.definers.makespecification(str,nil,nil,nil,":",nil,size)
+ list = { }
+ lpeg.match(pattern,str)
+ list.crap = nil
+ if list.name then
+ specification.name = list.name
+ list.name = nil
+ end
+ if list.lookup then
+ specification.lookup = list.lookup
+ list.lookup = nil
+ end
+ if list.sub then
+ specification.sub = list.sub
+ list.sub = nil
+ end
+ specification.features.normal = fonts.handlers.otf.features.normalize(list)
+ list = nil
+ return specification
+end
+
+function fonts.definers.applypostprocessors(tfmdata)
+ local postprocessors = tfmdata.postprocessors
+ if postprocessors then
+ for i=1,#postprocessors do
+ local extrahash = postprocessors[i](tfmdata) -- after scaling etc
+ if type(extrahash) == "string" and extrahash ~= "" then
+ -- e.g. a reencoding needs this
+ extrahash = string.gsub(lower(extrahash),"[^a-z]","-")
+ tfmdata.properties.fullname = format("%s-%s",tfmdata.properties.fullname,extrahash)
+ end
+ end
+ end
+ return tfmdata
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-fonts-enc.lua b/macros/luatex/generic/luaotfload/fontloader-fonts-enc.lua
new file mode 100644
index 0000000000..2bc6b71bf4
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-fonts-enc.lua
@@ -0,0 +1,75 @@
+if not modules then modules = { } end modules ['luatex-font-enc'] = {
+ version = 1.001,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+if context then
+ os.exit()
+end
+
+local fonts = fonts
+local encodings = { }
+fonts.encodings = encodings
+encodings.agl = { }
+encodings.known = { }
+
+setmetatable(encodings.agl, { __index = function(t,k)
+ if k == "unicodes" then
+ logs.report("fonts","loading (extended) adobe glyph list")
+ local unicodes = dofile(resolvers.findfile("font-age.lua"))
+ encodings.agl = { unicodes = unicodes }
+ return unicodes
+ else
+ return nil
+ end
+end })
+
+-- adapted for generic
+
+encodings.cache = containers.define("fonts", "enc", encodings.version, true)
+
+function encodings.load(filename)
+ local name = file.removesuffix(filename)
+ local data = containers.read(encodings.cache,name)
+ if data then
+ return data
+ end
+ local vector, tag, hash, unicodes = { }, "", { }, { }
+ local foundname = resolvers.findfile(filename,'enc')
+ if foundname and foundname ~= "" then
+ local ok, encoding, size = resolvers.loadbinfile(foundname)
+ if ok and encoding then
+ encoding = string.gsub(encoding,"%%(.-)\n","")
+ local unicoding = encodings.agl.unicodes
+ local tag, vec = string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def")
+ local i = 0
+ for ch in string.gmatch(vec,"/([%a%d%.]+)") do
+ if ch ~= ".notdef" then
+ vector[i] = ch
+ if not hash[ch] then
+ hash[ch] = i
+ else
+ -- duplicate, play safe for tex ligs and take first
+ end
+ local u = unicoding[ch]
+ if u then
+ unicodes[u] = i
+ end
+ end
+ i = i + 1
+ end
+ end
+ end
+ local data = {
+ name = name,
+ tag = tag,
+ vector = vector,
+ hash = hash,
+ unicodes = unicodes
+ }
+ return containers.write(encodings.cache, name, data)
+end
+
diff --git a/macros/luatex/generic/luaotfload/fontloader-fonts-ext.lua b/macros/luatex/generic/luaotfload/fontloader-fonts-ext.lua
new file mode 100644
index 0000000000..aee43ec4b3
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-fonts-ext.lua
@@ -0,0 +1,244 @@
+if not modules then modules = { } end modules ['luatex-fonts-ext'] = {
+ version = 1.001,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+if context then
+ os.exit()
+end
+
+local byte = string.byte
+
+local fonts = fonts
+local handlers = fonts.handlers
+local otf = handlers.otf
+local afm = handlers.afm
+local registerotffeature = otf.features.register
+local registerafmfeature = afm.features.register
+
+-- extra generic stuff
+
+function fonts.loggers.onetimemessage() end
+
+-- done elsewhere
+--
+-- loadmodule('font-ext-imp-italic.lua')
+-- loadmodule('font-ext-imp-effect.lua')
+-- loadmodule('luatex-fonts-lig.lua')
+
+-- protrusion (simplified version)
+
+fonts.protrusions = fonts.protrusions or { }
+fonts.protrusions.setups = fonts.protrusions.setups or { }
+local setups = fonts.protrusions.setups
+
+setups['default'] = { -- demo vector
+
+ factor = 1,
+ left = 1,
+ right = 1,
+
+ [0x002C] = { 0, 1 }, -- comma
+ [0x002E] = { 0, 1 }, -- period
+ [0x003A] = { 0, 1 }, -- colon
+ [0x003B] = { 0, 1 }, -- semicolon
+ [0x002D] = { 0, 1 }, -- hyphen
+ [0x2013] = { 0, 0.50 }, -- endash
+ [0x2014] = { 0, 0.33 }, -- emdash
+ [0x3001] = { 0, 1 }, -- ideographic comma ã€
+ [0x3002] = { 0, 1 }, -- ideographic full stop 。
+ [0x060C] = { 0, 1 }, -- arabic comma ،
+ [0x061B] = { 0, 1 }, -- arabic semicolon Ø›
+ [0x06D4] = { 0, 1 }, -- arabic full stop Û”
+
+}
+
+local function initializeprotrusion(tfmdata,value)
+ if value then
+ local setup = setups[value]
+ if setup then
+ local factor, left, right = setup.factor or 1, setup.left or 1, setup.right or 1
+ local emwidth = tfmdata.parameters.quad
+ tfmdata.parameters.protrusion = {
+ auto = true,
+ }
+ for i, chr in next, tfmdata.characters do
+ local v, pl, pr = setup[i], nil, nil
+ if v then
+ pl, pr = v[1], v[2]
+ end
+ if pl and pl ~= 0 then chr.left_protruding = left *pl*factor end
+ if pr and pr ~= 0 then chr.right_protruding = right*pr*factor end
+ end
+ end
+ end
+end
+
+local specification = {
+ name = "protrusion",
+ description = "shift characters into the left and or right margin",
+ initializers = {
+ base = initializeprotrusion,
+ node = initializeprotrusion,
+ }
+}
+
+registerotffeature(specification)
+registerafmfeature(specification)
+
+-- expansion (simplified version)
+
+fonts.expansions = fonts.expansions or { }
+fonts.expansions.setups = fonts.expansions.setups or { }
+local setups = fonts.expansions.setups
+
+setups['default'] = { -- demo vector
+
+ stretch = 2,
+ shrink = 2,
+ step = .5,
+ factor = 1,
+
+ [byte('A')] = 0.5, [byte('B')] = 0.7, [byte('C')] = 0.7, [byte('D')] = 0.5, [byte('E')] = 0.7,
+ [byte('F')] = 0.7, [byte('G')] = 0.5, [byte('H')] = 0.7, [byte('K')] = 0.7, [byte('M')] = 0.7,
+ [byte('N')] = 0.7, [byte('O')] = 0.5, [byte('P')] = 0.7, [byte('Q')] = 0.5, [byte('R')] = 0.7,
+ [byte('S')] = 0.7, [byte('U')] = 0.7, [byte('W')] = 0.7, [byte('Z')] = 0.7,
+ [byte('a')] = 0.7, [byte('b')] = 0.7, [byte('c')] = 0.7, [byte('d')] = 0.7, [byte('e')] = 0.7,
+ [byte('g')] = 0.7, [byte('h')] = 0.7, [byte('k')] = 0.7, [byte('m')] = 0.7, [byte('n')] = 0.7,
+ [byte('o')] = 0.7, [byte('p')] = 0.7, [byte('q')] = 0.7, [byte('s')] = 0.7, [byte('u')] = 0.7,
+ [byte('w')] = 0.7, [byte('z')] = 0.7,
+ [byte('2')] = 0.7, [byte('3')] = 0.7, [byte('6')] = 0.7, [byte('8')] = 0.7, [byte('9')] = 0.7,
+}
+
+local function initializeexpansion(tfmdata,value)
+ if value then
+ local setup = setups[value]
+ if setup then
+ local factor = setup.factor or 1
+ tfmdata.parameters.expansion = {
+ stretch = 10 * (setup.stretch or 0),
+ shrink = 10 * (setup.shrink or 0),
+ step = 10 * (setup.step or 0),
+ auto = true,
+ }
+ for i, chr in next, tfmdata.characters do
+ local v = setup[i]
+ if v and v ~= 0 then
+ chr.expansion_factor = v*factor
+ else -- can be option
+ chr.expansion_factor = factor
+ end
+ end
+ end
+ end
+end
+
+local specification = {
+ name = "expansion",
+ description = "apply hz optimization",
+ initializers = {
+ base = initializeexpansion,
+ node = initializeexpansion,
+ }
+}
+
+registerotffeature(specification)
+registerafmfeature(specification)
+
+-- normalizer (generic only)
+
+if not otf.features.normalize then
+
+ otf.features.normalize = function(t)
+ if t.rand then
+ t.rand = "random"
+ end
+ return t
+ end
+
+end
+
+-- bonus
+
+function fonts.helpers.nametoslot(name)
+ local t = type(name)
+ if t == "string" then
+ local tfmdata = fonts.hashes.identifiers[currentfont()]
+ local shared = tfmdata and tfmdata.shared
+ local fntdata = shared and shared.rawdata
+ return fntdata and fntdata.resources.unicodes[name]
+ elseif t == "number" then
+ return n
+ end
+end
+
+-- \font\test=file:somefont:reencode=mymessup
+--
+-- fonts.encodings.reencodings.mymessup = {
+-- [109] = 110, -- m
+-- [110] = 109, -- n
+-- }
+
+-- reencoding (generic only)
+
+fonts.encodings = fonts.encodings or { }
+local reencodings = { }
+fonts.encodings.reencodings = reencodings
+
+local function specialreencode(tfmdata,value)
+ -- we forget about kerns as we assume symbols and we
+ -- could issue a message if ther are kerns but it's
+ -- a hack anyway so we odn't care too much here
+ local encoding = value and reencodings[value]
+ if encoding then
+ local temp = { }
+ local char = tfmdata.characters
+ for k, v in next, encoding do
+ temp[k] = char[v]
+ end
+ for k, v in next, temp do
+ char[k] = temp[k]
+ end
+ -- if we use the font otherwise luatex gets confused so
+ -- we return an additional hash component for fullname
+ return string.format("reencoded:%s",value)
+ end
+end
+
+local function initialize(tfmdata,value)
+ tfmdata.postprocessors = tfmdata.postprocessors or { }
+ table.insert(tfmdata.postprocessors,
+ function(tfmdata)
+ return specialreencode(tfmdata,value)
+ end
+ )
+end
+
+registerotffeature {
+ name = "reencode",
+ description = "reencode characters",
+ manipulators = {
+ base = initialize,
+ node = initialize,
+ }
+}
+
+-- math stuff (generic only)
+
+local function initialize(tfmdata,key,value)
+ if value then
+ tfmdata.mathparameters = nil
+ end
+end
+
+registerotffeature {
+ name = "ignoremathconstants",
+ description = "ignore math constants table",
+ initializers = {
+ base = initialize,
+ node = initialize,
+ }
+}
diff --git a/macros/luatex/generic/luaotfload/fontloader-fonts-gbn.lua b/macros/luatex/generic/luaotfload/fontloader-fonts-gbn.lua
new file mode 100644
index 0000000000..53be41c7ed
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-fonts-gbn.lua
@@ -0,0 +1,300 @@
+if not modules then modules = { } end modules ['luatex-fonts-gbn'] = {
+ version = 1.001,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- generic [base|node] mode handler
+
+if context then
+ os.exit()
+end
+
+local next = next
+
+local fonts = fonts
+local nodes = nodes
+
+local nuts = nodes.nuts -- context abstraction of direct nodes
+
+local traverse_id = nuts.traverse_id
+local flush_node = nuts.flush_node
+
+local glyph_code = nodes.nodecodes.glyph
+local disc_code = nodes.nodecodes.disc
+
+local tonode = nuts.tonode
+local tonut = nuts.tonut
+
+local getfont = nuts.getfont
+local getchar = nuts.getchar
+local getid = nuts.getid
+local getboth = nuts.getboth
+local getprev = nuts.getprev
+local getnext = nuts.getnext
+local getdisc = nuts.getdisc
+local setchar = nuts.setchar
+local setlink = nuts.setlink
+local setprev = nuts.setprev
+
+-- from now on we apply ligaturing and kerning here because it might interfere with complex
+-- opentype discretionary handling where the base ligature pass expect some weird extra
+-- pointers (which then confuse the tail slider that has some checking built in)
+
+local n_ligaturing = node.ligaturing
+local n_kerning = node.kerning
+
+local d_ligaturing = nuts.ligaturing
+local d_kerning = nuts.kerning
+
+local basemodepass = true
+
+local function l_warning() logs.report("fonts","don't call 'node.ligaturing' directly") l_warning = nil end
+local function k_warning() logs.report("fonts","don't call 'node.kerning' directly") k_warning = nil end
+
+function node.ligaturing(...)
+ if basemodepass and l_warning then
+ l_warning()
+ end
+ return n_ligaturing(...)
+end
+
+function node.kerning(...)
+ if basemodepass and k_warning then
+ k_warning()
+ end
+ return n_kerning(...)
+end
+
+function nuts.ligaturing(...)
+ if basemodepass and l_warning then
+ l_warning()
+ end
+ return d_ligaturing(...)
+end
+
+function nuts.kerning(...)
+ if basemodepass and k_warning then
+ k_warning()
+ end
+ return d_kerning(...)
+end
+
+-- direct.ligaturing = nuts.ligaturing
+-- direct.kerning = nuts.kerning
+
+function nodes.handlers.setbasemodepass(v)
+ basemodepass = v
+end
+
+local function nodepass(head,groupcode,size,packtype,direction)
+ local fontdata = fonts.hashes.identifiers
+ if fontdata then
+ local usedfonts = { }
+ local basefonts = { }
+ local prevfont = nil
+ local basefont = nil
+ local variants = nil
+ local redundant = nil
+ local nofused = 0
+ for n in traverse_id(glyph_code,head) do
+ local font = getfont(n)
+ if font ~= prevfont then
+ if basefont then
+ basefont[2] = getprev(n)
+ end
+ prevfont = font
+ local used = usedfonts[font]
+ if not used then
+ local tfmdata = fontdata[font] --
+ if tfmdata then
+ local shared = tfmdata.shared -- we need to check shared, only when same features
+ if shared then
+ local processors = shared.processes
+ if processors and #processors > 0 then
+ usedfonts[font] = processors
+ nofused = nofused + 1
+ elseif basemodepass then
+ basefont = { n, nil }
+ basefonts[#basefonts+1] = basefont
+ end
+ end
+ local resources = tfmdata.resources
+ variants = resources and resources.variants
+ variants = variants and next(variants) and variants or false
+ end
+ else
+ local tfmdata = fontdata[prevfont]
+ if tfmdata then
+ local resources = tfmdata.resources
+ variants = resources and resources.variants
+ variants = variants and next(variants) and variants or false
+ end
+ end
+ end
+ if variants then
+ local char = getchar(n)
+ if (char >= 0xFE00 and char <= 0xFE0F) or (char >= 0xE0100 and char <= 0xE01EF) then
+ local hash = variants[char]
+ if hash then
+ local p = getprev(n)
+ if p and getid(p) == glyph_code then
+ local variant = hash[getchar(p)]
+ if variant then
+ setchar(p,variant)
+ end
+ end
+ end
+ -- per generic user request we always remove selectors
+ if not redundant then
+ redundant = { n }
+ else
+ redundant[#redundant+1] = n
+ end
+ end
+ end
+ end
+ local nofbasefonts = #basefonts
+ if redundant then
+ for i=1,#redundant do
+ local r = redundant[i]
+ local p, n = getboth(r)
+ if r == head then
+ head = n
+ setprev(n)
+ else
+ setlink(p,n)
+ end
+ if nofbasefonts > 0 then
+ for i=1,nofbasefonts do
+ local bi = basefonts[i]
+ if r == bi[1] then
+ bi[1] = n
+ end
+ if r == bi[2] then
+ bi[2] = n
+ end
+ end
+ end
+ flush_node(r)
+ end
+ end
+ for d in traverse_id(disc_code,head) do
+ local _, _, r = getdisc(d)
+ if r then
+ for n in traverse_id(glyph_code,r) do
+ local font = getfont(n)
+ if font ~= prevfont then
+ prevfont = font
+ local used = usedfonts[font]
+ if not used then
+ local tfmdata = fontdata[font] --
+ if tfmdata then
+ local shared = tfmdata.shared -- we need to check shared, only when same features
+ if shared then
+ local processors = shared.processes
+ if processors and #processors > 0 then
+ usedfonts[font] = processors
+ nofused = nofused + 1
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if next(usedfonts) then
+ for font, processors in next, usedfonts do
+ for i=1,#processors do
+ head = processors[i](head,font,0,direction,nofused) or head
+ end
+ end
+ end
+ if basemodepass and nofbasefonts > 0 then
+ for i=1,nofbasefonts do
+ local range = basefonts[i]
+ local start = range[1]
+ local stop = range[2]
+ if start then
+ local front = head == start
+ local prev, next
+ if stop then
+ next = getnext(stop)
+ start, stop = d_ligaturing(start,stop)
+ start, stop = d_kerning(start,stop)
+ else
+ prev = getprev(start)
+ start = d_ligaturing(start)
+ start = d_kerning(start)
+ end
+ if prev then
+ setlink(prev,start)
+ end
+ if next then
+ setlink(stop,next)
+ end
+ if front and head ~= start then
+ head = start
+ end
+ end
+ end
+ end
+ end
+ return head
+end
+
+local function basepass(head)
+ if basemodepass then
+ head = d_ligaturing(head)
+ head = d_kerning(head)
+ end
+ return head
+end
+
+local protectpass = node.direct.protect_glyphs
+local injectpass = nodes.injections.handler
+
+-- This is the only official public interface and this one can be hooked into a callback (chain) and
+-- everything else can change!@ Functione being visibel doesn't mean that it's part of the api.
+
+function nodes.handlers.nodepass(head,...)
+ if head then
+ return tonode(nodepass(tonut(head),...))
+ end
+end
+
+function nodes.handlers.basepass(head)
+ if head then
+ return tonode(basepass(tonut(head)))
+ end
+end
+
+function nodes.handlers.injectpass(head)
+ if head then
+ return tonode(injectpass(tonut(head)))
+ end
+end
+
+function nodes.handlers.protectpass(head)
+ if head then
+ protectpass(tonut(head))
+ return head
+ end
+end
+
+function nodes.simple_font_handler(head,groupcode,size,packtype,direction)
+ if head then
+ head = tonut(head)
+ head = nodepass(head,groupcode,size,packtype,direction)
+ head = injectpass(head)
+ if not basemodepass then
+ head = basepass(head)
+ end
+ protectpass(head)
+ head = tonode(head)
+ end
+ return head
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-fonts-lig.lua b/macros/luatex/generic/luaotfload/fontloader-fonts-lig.lua
new file mode 100644
index 0000000000..4ce1265338
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-fonts-lig.lua
@@ -0,0 +1,2067 @@
+-- this file is generated by context
+
+fonts.handlers.otf.addfeature {
+ ["dataset"]={
+ {
+ ["data"]={
+ ["À"]={ "A", "̀" },
+ ["Ã"]={ "A", "Ì" },
+ ["Â"]={ "A", "̂" },
+ ["Ã"]={ "A", "̃" },
+ ["Ä"]={ "A", "̈" },
+ ["Ã…"]={ "A", "ÌŠ" },
+ ["Ç"]={ "C", "̧" },
+ ["È"]={ "E", "̀" },
+ ["É"]={ "E", "Ì" },
+ ["Ê"]={ "E", "̂" },
+ ["Ë"]={ "E", "̈" },
+ ["Ì"]={ "I", "̀" },
+ ["Ã"]={ "I", "Ì" },
+ ["ÃŽ"]={ "I", "Ì‚" },
+ ["Ã"]={ "I", "̈" },
+ ["Ñ"]={ "N", "̃" },
+ ["Ã’"]={ "O", "Ì€" },
+ ["Ó"]={ "O", "Ì" },
+ ["Ô"]={ "O", "̂" },
+ ["Õ"]={ "O", "̃" },
+ ["Ö"]={ "O", "̈" },
+ ["Ù"]={ "U", "̀" },
+ ["Ú"]={ "U", "Ì" },
+ ["Û"]={ "U", "̂" },
+ ["Ü"]={ "U", "̈" },
+ ["Ã"]={ "Y", "Ì" },
+ ["à"]={ "a", "̀" },
+ ["á"]={ "a", "Ì" },
+ ["â"]={ "a", "̂" },
+ ["ã"]={ "a", "̃" },
+ ["ä"]={ "a", "̈" },
+ ["Ã¥"]={ "a", "ÌŠ" },
+ ["ç"]={ "c", "̧" },
+ ["è"]={ "e", "̀" },
+ ["é"]={ "e", "Ì" },
+ ["ê"]={ "e", "̂" },
+ ["ë"]={ "e", "̈" },
+ ["ì"]={ "i", "̀" },
+ ["í"]={ "i", "Ì" },
+ ["î"]={ "i", "̂" },
+ ["ï"]={ "i", "̈" },
+ ["ñ"]={ "n", "̃" },
+ ["ò"]={ "o", "̀" },
+ ["ó"]={ "o", "Ì" },
+ ["ô"]={ "o", "̂" },
+ ["õ"]={ "o", "̃" },
+ ["ö"]={ "o", "̈" },
+ ["ù"]={ "u", "̀" },
+ ["ú"]={ "u", "Ì" },
+ ["û"]={ "u", "̂" },
+ ["ü"]={ "u", "̈" },
+ ["ý"]={ "y", "Ì" },
+ ["ÿ"]={ "y", "̈" },
+ ["Ä€"]={ "A", "Ì„" },
+ ["Ä"]={ "a", "Ì„" },
+ ["Ă"]={ "A", "̆" },
+ ["ă"]={ "a", "̆" },
+ ["Ą"]={ "A", "̨" },
+ ["ą"]={ "a", "̨" },
+ ["Ć"]={ "C", "Ì" },
+ ["ć"]={ "c", "Ì" },
+ ["Ĉ"]={ "C", "̂" },
+ ["ĉ"]={ "c", "̂" },
+ ["Ċ"]={ "C", "̇" },
+ ["ċ"]={ "c", "̇" },
+ ["Č"]={ "C", "̌" },
+ ["Ä"]={ "c", "ÌŒ" },
+ ["Ď"]={ "D", "̌" },
+ ["Ä"]={ "d", "ÌŒ" },
+ ["Ä’"]={ "E", "Ì„" },
+ ["Ä“"]={ "e", "Ì„" },
+ ["Ĕ"]={ "E", "̆" },
+ ["ĕ"]={ "e", "̆" },
+ ["Ė"]={ "E", "̇" },
+ ["ė"]={ "e", "̇" },
+ ["Ę"]={ "E", "̨" },
+ ["ę"]={ "e", "̨" },
+ ["Ě"]={ "E", "̌" },
+ ["ě"]={ "e", "̌" },
+ ["Ĝ"]={ "G", "̂" },
+ ["Ä"]={ "g", "Ì‚" },
+ ["Ğ"]={ "G", "̆" },
+ ["ğ"]={ "g", "̆" },
+ ["Ġ"]={ "G", "̇" },
+ ["ġ"]={ "g", "̇" },
+ ["Ģ"]={ "G", "̧" },
+ ["ģ"]={ "g", "̧" },
+ ["Ĥ"]={ "H", "̂" },
+ ["Ä¥"]={ "h", "Ì‚" },
+ ["Ĩ"]={ "I", "̃" },
+ ["ĩ"]={ "i", "̃" },
+ ["Ī"]={ "I", "̄" },
+ ["Ä«"]={ "i", "Ì„" },
+ ["Ĭ"]={ "I", "̆" },
+ ["ĭ"]={ "i", "̆" },
+ ["Į"]={ "I", "̨" },
+ ["į"]={ "i", "̨" },
+ ["İ"]={ "I", "̇" },
+ ["Ä´"]={ "J", "Ì‚" },
+ ["ĵ"]={ "j", "̂" },
+ ["Ķ"]={ "K", "̧" },
+ ["ķ"]={ "k", "̧" },
+ ["Ĺ"]={ "L", "Ì" },
+ ["ĺ"]={ "l", "Ì" },
+ ["Ļ"]={ "L", "̧" },
+ ["ļ"]={ "l", "̧" },
+ ["Ľ"]={ "L", "̌" },
+ ["ľ"]={ "l", "̌" },
+ ["Ń"]={ "N", "Ì" },
+ ["Å„"]={ "n", "Ì" },
+ ["Ņ"]={ "N", "̧" },
+ ["ņ"]={ "n", "̧" },
+ ["Ň"]={ "N", "̌" },
+ ["ň"]={ "n", "̌" },
+ ["Ō"]={ "O", "̄" },
+ ["Å"]={ "o", "Ì„" },
+ ["Ŏ"]={ "O", "̆" },
+ ["Å"]={ "o", "̆" },
+ ["Å"]={ "O", "Ì‹" },
+ ["Å‘"]={ "o", "Ì‹" },
+ ["Å”"]={ "R", "Ì" },
+ ["Å•"]={ "r", "Ì" },
+ ["Ŗ"]={ "R", "̧" },
+ ["ŗ"]={ "r", "̧" },
+ ["Ř"]={ "R", "̌" },
+ ["ř"]={ "r", "̌" },
+ ["Åš"]={ "S", "Ì" },
+ ["Å›"]={ "s", "Ì" },
+ ["Ŝ"]={ "S", "̂" },
+ ["Å"]={ "s", "Ì‚" },
+ ["Ş"]={ "S", "̧" },
+ ["ş"]={ "s", "̧" },
+ ["Š"]={ "S", "̌" },
+ ["š"]={ "s", "̌" },
+ ["Ţ"]={ "T", "̧" },
+ ["ţ"]={ "t", "̧" },
+ ["Ť"]={ "T", "̌" },
+ ["ť"]={ "t", "̌" },
+ ["Ũ"]={ "U", "̃" },
+ ["ũ"]={ "u", "̃" },
+ ["Ū"]={ "U", "̄" },
+ ["Å«"]={ "u", "Ì„" },
+ ["Ŭ"]={ "U", "̆" },
+ ["ŭ"]={ "u", "̆" },
+ ["Å®"]={ "U", "ÌŠ" },
+ ["ů"]={ "u", "̊" },
+ ["Å°"]={ "U", "Ì‹" },
+ ["ű"]={ "u", "̋" },
+ ["Ų"]={ "U", "̨" },
+ ["ų"]={ "u", "̨" },
+ ["Å´"]={ "W", "Ì‚" },
+ ["ŵ"]={ "w", "̂" },
+ ["Ŷ"]={ "Y", "̂" },
+ ["Å·"]={ "y", "Ì‚" },
+ ["Ÿ"]={ "Y", "̈" },
+ ["Ź"]={ "Z", "Ì" },
+ ["ź"]={ "z", "Ì" },
+ ["Ż"]={ "Z", "̇" },
+ ["ż"]={ "z", "̇" },
+ ["Ž"]={ "Z", "̌" },
+ ["ž"]={ "z", "̌" },
+ ["Æ "]={ "O", "Ì›" },
+ ["Æ¡"]={ "o", "Ì›" },
+ ["Ư"]={ "U", "̛" },
+ ["Æ°"]={ "u", "Ì›" },
+ ["Ç"]={ "A", "ÌŒ" },
+ ["ǎ"]={ "a", "̌" },
+ ["Ç"]={ "I", "ÌŒ" },
+ ["Ç"]={ "i", "ÌŒ" },
+ ["Ǒ"]={ "O", "̌" },
+ ["ǒ"]={ "o", "̌" },
+ ["Ǔ"]={ "U", "̌" },
+ ["ǔ"]={ "u", "̌" },
+ ["Ǖ"]={ "Ü", "̄" },
+ ["ǖ"]={ "ü", "̄" },
+ ["Ç—"]={ "Ãœ", "Ì" },
+ ["ǘ"]={ "ü", "Ì" },
+ ["Ǚ"]={ "Ü", "̌" },
+ ["ǚ"]={ "ü", "̌" },
+ ["Ǜ"]={ "Ü", "̀" },
+ ["ǜ"]={ "ü", "̀" },
+ ["Ǟ"]={ "Ä", "̄" },
+ ["ǟ"]={ "ä", "̄" },
+ ["Ǡ"]={ "Ȧ", "̄" },
+ ["ǡ"]={ "ȧ", "̄" },
+ ["Ǣ"]={ "Æ", "̄" },
+ ["ǣ"]={ "æ", "̄" },
+ ["Ǧ"]={ "G", "̌" },
+ ["ǧ"]={ "g", "̌" },
+ ["Ǩ"]={ "K", "̌" },
+ ["ǩ"]={ "k", "̌" },
+ ["Ǫ"]={ "O", "̨" },
+ ["ǫ"]={ "o", "̨" },
+ ["Ǭ"]={ "Ǫ", "̄" },
+ ["Ç­"]={ "Ç«", "Ì„" },
+ ["Ǯ"]={ "Ʒ", "̌" },
+ ["ǯ"]={ "ʒ", "̌" },
+ ["ǰ"]={ "j", "̌" },
+ ["Ç´"]={ "G", "Ì" },
+ ["ǵ"]={ "g", "Ì" },
+ ["Ǹ"]={ "N", "̀" },
+ ["ǹ"]={ "n", "̀" },
+ ["Ǻ"]={ "Ã…", "Ì" },
+ ["Ç»"]={ "Ã¥", "Ì" },
+ ["Ǽ"]={ "Æ", "Ì" },
+ ["ǽ"]={ "æ", "Ì" },
+ ["Ǿ"]={ "Ø", "Ì" },
+ ["Ç¿"]={ "ø", "Ì" },
+ ["È€"]={ "A", "Ì" },
+ ["È"]={ "a", "Ì" },
+ ["È‚"]={ "A", "Ì‘" },
+ ["ȃ"]={ "a", "̑" },
+ ["È„"]={ "E", "Ì" },
+ ["È…"]={ "e", "Ì" },
+ ["Ȇ"]={ "E", "̑" },
+ ["ȇ"]={ "e", "̑" },
+ ["Ȉ"]={ "I", "Ì" },
+ ["ȉ"]={ "i", "Ì" },
+ ["ÈŠ"]={ "I", "Ì‘" },
+ ["È‹"]={ "i", "Ì‘" },
+ ["ÈŒ"]={ "O", "Ì" },
+ ["È"]={ "o", "Ì" },
+ ["ÈŽ"]={ "O", "Ì‘" },
+ ["È"]={ "o", "Ì‘" },
+ ["È"]={ "R", "Ì" },
+ ["È‘"]={ "r", "Ì" },
+ ["È’"]={ "R", "Ì‘" },
+ ["È“"]={ "r", "Ì‘" },
+ ["È”"]={ "U", "Ì" },
+ ["È•"]={ "u", "Ì" },
+ ["È–"]={ "U", "Ì‘" },
+ ["È—"]={ "u", "Ì‘" },
+ ["Ș"]={ "S", "̦" },
+ ["ș"]={ "s", "̦" },
+ ["Ț"]={ "T", "̦" },
+ ["ț"]={ "t", "̦" },
+ ["Ȟ"]={ "H", "̌" },
+ ["ȟ"]={ "h", "̌" },
+ ["Ȧ"]={ "A", "̇" },
+ ["ȧ"]={ "a", "̇" },
+ ["Ȩ"]={ "E", "̧" },
+ ["ȩ"]={ "e", "̧" },
+ ["Ȫ"]={ "Ö", "̄" },
+ ["ȫ"]={ "ö", "̄" },
+ ["Ȭ"]={ "Õ", "̄" },
+ ["ȭ"]={ "õ", "̄" },
+ ["Ȯ"]={ "O", "̇" },
+ ["ȯ"]={ "o", "̇" },
+ ["È°"]={ "È®", "Ì„" },
+ ["ȱ"]={ "ȯ", "̄" },
+ ["Ȳ"]={ "Y", "̄" },
+ ["ȳ"]={ "y", "̄" },
+ ["Í„"]={ "̈", "Ì" },
+ ["Î…"]={ "¨", "Ì" },
+ ["Ά"]={ "Α", "Ì" },
+ ["Έ"]={ "Ε", "Ì" },
+ ["Ή"]={ "Η", "Ì" },
+ ["Ί"]={ "Ι", "Ì" },
+ ["ÎŒ"]={ "Ο", "Ì" },
+ ["ÎŽ"]={ "Î¥", "Ì" },
+ ["Î"]={ "Ω", "Ì" },
+ ["Î"]={ "ÏŠ", "Ì" },
+ ["Ϊ"]={ "Ι", "̈" },
+ ["Ϋ"]={ "Υ", "̈" },
+ ["ά"]={ "α", "Ì" },
+ ["έ"]={ "ε", "Ì" },
+ ["ή"]={ "η", "Ì" },
+ ["ί"]={ "ι", "Ì" },
+ ["ΰ"]={ "Ï‹", "Ì" },
+ ["ϊ"]={ "ι", "̈" },
+ ["ϋ"]={ "υ", "̈" },
+ ["ÏŒ"]={ "ο", "Ì" },
+ ["Ï"]={ "Ï…", "Ì" },
+ ["ÏŽ"]={ "ω", "Ì" },
+ ["Ï“"]={ "Ï’", "Ì" },
+ ["ϔ"]={ "ϒ", "̈" },
+ ["Ѐ"]={ "Е", "̀" },
+ ["Ð"]={ "Е", "̈" },
+ ["Ѓ"]={ "Г", "Ì" },
+ ["Ї"]={ "І", "̈" },
+ ["ÐŒ"]={ "К", "Ì" },
+ ["Ð"]={ "И", "Ì€" },
+ ["Ў"]={ "У", "̆" },
+ ["Й"]={ "И", "̆" },
+ ["й"]={ "и", "̆" },
+ ["Ñ"]={ "е", "Ì€" },
+ ["ё"]={ "е", "̈" },
+ ["Ñ“"]={ "г", "Ì" },
+ ["ї"]={ "і", "̈" },
+ ["Ñœ"]={ "к", "Ì" },
+ ["Ñ"]={ "и", "Ì€" },
+ ["ў"]={ "у", "̆" },
+ ["Ѷ"]={ "Ñ´", "Ì" },
+ ["Ñ·"]={ "ѵ", "Ì" },
+ ["Ó"]={ "Ж", "̆" },
+ ["ӂ"]={ "ж", "̆" },
+ ["Ó"]={ "Ð", "̆" },
+ ["ӑ"]={ "а", "̆" },
+ ["Ó’"]={ "Ð", "̈" },
+ ["ӓ"]={ "а", "̈" },
+ ["Ӗ"]={ "Е", "̆" },
+ ["ӗ"]={ "е", "̆" },
+ ["Ӛ"]={ "Ә", "̈" },
+ ["ӛ"]={ "ә", "̈" },
+ ["Ӝ"]={ "Ж", "̈" },
+ ["Ó"]={ "ж", "̈" },
+ ["Ӟ"]={ "З", "̈" },
+ ["ӟ"]={ "з", "̈" },
+ ["Ӣ"]={ "И", "̄" },
+ ["ӣ"]={ "и", "̄" },
+ ["Ӥ"]={ "И", "̈" },
+ ["ӥ"]={ "и", "̈" },
+ ["Ӧ"]={ "О", "̈" },
+ ["ӧ"]={ "о", "̈" },
+ ["Ӫ"]={ "Ө", "̈" },
+ ["ӫ"]={ "ө", "̈" },
+ ["Ӭ"]={ "Э", "̈" },
+ ["Ó­"]={ "Ñ", "̈" },
+ ["Ӯ"]={ "У", "̄" },
+ ["ӯ"]={ "у", "̄" },
+ ["Ӱ"]={ "У", "̈" },
+ ["ӱ"]={ "у", "̈" },
+ ["Ӳ"]={ "У", "̋" },
+ ["ӳ"]={ "у", "̋" },
+ ["Ӵ"]={ "Ч", "̈" },
+ ["ӵ"]={ "ч", "̈" },
+ ["Ӹ"]={ "Ы", "̈" },
+ ["ӹ"]={ "ы", "̈" },
+ ["آ"]={ "ا", "ٓ" },
+ ["أ"]={ "ا", "ٔ" },
+ ["ؤ"]={ "و", "ٔ" },
+ ["إ"]={ "ا", "ٕ" },
+ ["ئ"]={ "ي", "ٔ" },
+ ["Û€"]={ "Û•", "Ù”" },
+ ["Û‚"]={ "Û", "Ù”" },
+ ["Û“"]={ "Û’", "Ù”" },
+ ["ऩ"]={ "न", "़" },
+ ["ऱ"]={ "र", "़" },
+ ["ऴ"]={ "ळ", "़" },
+ ["क़"]={ "क", "़" },
+ ["ख़"]={ "ख", "़" },
+ ["ग़"]={ "ग", "़" },
+ ["ज़"]={ "ज", "़" },
+ ["ड़"]={ "ड", "़" },
+ ["à¥"]={ "ढ", "़" },
+ ["फ़"]={ "फ", "़" },
+ ["य़"]={ "य", "़" },
+ ["ো"]={ "ে", "া" },
+ ["ৌ"]={ "ে", "ৗ" },
+ ["ড়"]={ "ড", "়" },
+ ["à§"]={ "ঢ", "়" },
+ ["য়"]={ "য", "়" },
+ ["ਲ਼"]={ "ਲ", "਼" },
+ ["ਸ਼"]={ "ਸ", "਼" },
+ ["ਖ਼"]={ "ਖ", "਼" },
+ ["ਗ਼"]={ "ਗ", "਼" },
+ ["ਜ਼"]={ "ਜ", "਼" },
+ ["ਫ਼"]={ "ਫ", "਼" },
+ ["à­ˆ"]={ "à­‡", "à­–" },
+ ["ୋ"]={ "େ", "ା" },
+ ["ୌ"]={ "େ", "ୗ" },
+ ["ଡ଼"]={ "ଡ", "଼" },
+ ["à­"]={ "ଢ", "଼" },
+ ["ஔ"]={ "ஒ", "ௗ" },
+ ["ொ"]={ "ெ", "ா" },
+ ["ோ"]={ "ே", "ா" },
+ ["ௌ"]={ "ெ", "ௗ" },
+ ["ై"]={ "ె", "ౖ" },
+ ["ೀ"]={ "ಿ", "ೕ" },
+ ["ೇ"]={ "ೆ", "ೕ" },
+ ["ೈ"]={ "ೆ", "ೖ" },
+ ["ೊ"]={ "ೆ", "ೂ" },
+ ["ೋ"]={ "ೊ", "ೕ" },
+ ["ൊ"]={ "െ", "ാ" },
+ ["ോ"]={ "േ", "ാ" },
+ ["ൌ"]={ "െ", "ൗ" },
+ ["à·š"]={ "à·™", "à·Š" },
+ ["à·œ"]={ "à·™", "à·" },
+ ["à·"]={ "à·œ", "à·Š" },
+ ["à·ž"]={ "à·™", "à·Ÿ" },
+ ["གྷ"]={ "ག", "ྷ" },
+ ["à½"]={ "ཌ", "ྷ" },
+ ["དྷ"]={ "ད", "ྷ" },
+ ["བྷ"]={ "བ", "ྷ" },
+ ["ཛྷ"]={ "ཛ", "ྷ" },
+ ["ཀྵ"]={ "ཀ", "ྵ" },
+ ["ཱི"]={ "ཱ", "ི" },
+ ["ཱུ"]={ "ཱ", "ུ" },
+ ["ྲྀ"]={ "ྲ", "ྀ" },
+ ["ླྀ"]={ "ླ", "ྀ" },
+ ["à¾"]={ "ཱ", "ྀ" },
+ ["ྒྷ"]={ "ྒ", "ྷ" },
+ ["à¾"]={ "ྜ", "ྷ" },
+ ["ྡྷ"]={ "ྡ", "ྷ" },
+ ["ྦྷ"]={ "ྦ", "ྷ" },
+ ["ྫྷ"]={ "ྫ", "ྷ" },
+ ["ྐྵ"]={ "à¾", "ྵ" },
+ ["ဦ"]={ "ဥ", "ီ" },
+ ["ᬆ"]={ "ᬅ", "ᬵ" },
+ ["ᬈ"]={ "ᬇ", "ᬵ" },
+ ["ᬊ"]={ "ᬉ", "ᬵ" },
+ ["ᬌ"]={ "ᬋ", "ᬵ" },
+ ["ᬎ"]={ "á¬", "ᬵ" },
+ ["ᬒ"]={ "ᬑ", "ᬵ" },
+ ["ᬻ"]={ "ᬺ", "ᬵ" },
+ ["ᬽ"]={ "ᬼ", "ᬵ" },
+ ["ᭀ"]={ "ᬾ", "ᬵ" },
+ ["á­"]={ "ᬿ", "ᬵ" },
+ ["ᭃ"]={ "ᭂ", "ᬵ" },
+ ["Ḁ"]={ "A", "̥" },
+ ["á¸"]={ "a", "Ì¥" },
+ ["Ḃ"]={ "B", "̇" },
+ ["ḃ"]={ "b", "̇" },
+ ["Ḅ"]={ "B", "̣" },
+ ["ḅ"]={ "b", "̣" },
+ ["Ḇ"]={ "B", "̱" },
+ ["ḇ"]={ "b", "̱" },
+ ["Ḉ"]={ "Ç", "Ì" },
+ ["ḉ"]={ "ç", "Ì" },
+ ["Ḋ"]={ "D", "̇" },
+ ["ḋ"]={ "d", "̇" },
+ ["Ḍ"]={ "D", "̣" },
+ ["á¸"]={ "d", "Ì£" },
+ ["Ḏ"]={ "D", "̱" },
+ ["á¸"]={ "d", "̱" },
+ ["á¸"]={ "D", "̧" },
+ ["ḑ"]={ "d", "̧" },
+ ["Ḓ"]={ "D", "̭" },
+ ["ḓ"]={ "d", "̭" },
+ ["Ḕ"]={ "Ē", "̀" },
+ ["ḕ"]={ "ē", "̀" },
+ ["Ḗ"]={ "Ä’", "Ì" },
+ ["ḗ"]={ "Ä“", "Ì" },
+ ["Ḙ"]={ "E", "̭" },
+ ["ḙ"]={ "e", "̭" },
+ ["Ḛ"]={ "E", "̰" },
+ ["ḛ"]={ "e", "̰" },
+ ["Ḝ"]={ "Ȩ", "̆" },
+ ["á¸"]={ "È©", "̆" },
+ ["Ḟ"]={ "F", "̇" },
+ ["ḟ"]={ "f", "̇" },
+ ["Ḡ"]={ "G", "̄" },
+ ["ḡ"]={ "g", "̄" },
+ ["Ḣ"]={ "H", "̇" },
+ ["ḣ"]={ "h", "̇" },
+ ["Ḥ"]={ "H", "̣" },
+ ["ḥ"]={ "h", "̣" },
+ ["Ḧ"]={ "H", "̈" },
+ ["ḧ"]={ "h", "̈" },
+ ["Ḩ"]={ "H", "̧" },
+ ["ḩ"]={ "h", "̧" },
+ ["Ḫ"]={ "H", "̮" },
+ ["ḫ"]={ "h", "̮" },
+ ["Ḭ"]={ "I", "̰" },
+ ["ḭ"]={ "i", "̰" },
+ ["Ḯ"]={ "Ã", "Ì" },
+ ["ḯ"]={ "ï", "Ì" },
+ ["Ḱ"]={ "K", "Ì" },
+ ["ḱ"]={ "k", "Ì" },
+ ["Ḳ"]={ "K", "̣" },
+ ["ḳ"]={ "k", "̣" },
+ ["Ḵ"]={ "K", "̱" },
+ ["ḵ"]={ "k", "̱" },
+ ["Ḷ"]={ "L", "̣" },
+ ["ḷ"]={ "l", "̣" },
+ ["Ḹ"]={ "Ḷ", "̄" },
+ ["ḹ"]={ "ḷ", "̄" },
+ ["Ḻ"]={ "L", "̱" },
+ ["ḻ"]={ "l", "̱" },
+ ["Ḽ"]={ "L", "̭" },
+ ["ḽ"]={ "l", "̭" },
+ ["Ḿ"]={ "M", "Ì" },
+ ["ḿ"]={ "m", "Ì" },
+ ["Ṁ"]={ "M", "̇" },
+ ["á¹"]={ "m", "̇" },
+ ["Ṃ"]={ "M", "̣" },
+ ["ṃ"]={ "m", "̣" },
+ ["Ṅ"]={ "N", "̇" },
+ ["ṅ"]={ "n", "̇" },
+ ["Ṇ"]={ "N", "̣" },
+ ["ṇ"]={ "n", "̣" },
+ ["Ṉ"]={ "N", "̱" },
+ ["ṉ"]={ "n", "̱" },
+ ["Ṋ"]={ "N", "̭" },
+ ["ṋ"]={ "n", "̭" },
+ ["Ṍ"]={ "Õ", "Ì" },
+ ["á¹"]={ "õ", "Ì" },
+ ["Ṏ"]={ "Õ", "̈" },
+ ["á¹"]={ "õ", "̈" },
+ ["á¹"]={ "ÅŒ", "Ì€" },
+ ["ṑ"]={ "Å", "Ì€" },
+ ["á¹’"]={ "ÅŒ", "Ì" },
+ ["ṓ"]={ "Å", "Ì" },
+ ["á¹”"]={ "P", "Ì" },
+ ["ṕ"]={ "p", "Ì" },
+ ["Ṗ"]={ "P", "̇" },
+ ["ṗ"]={ "p", "̇" },
+ ["Ṙ"]={ "R", "̇" },
+ ["ṙ"]={ "r", "̇" },
+ ["Ṛ"]={ "R", "̣" },
+ ["á¹›"]={ "r", "Ì£" },
+ ["Ṝ"]={ "Ṛ", "̄" },
+ ["á¹"]={ "á¹›", "Ì„" },
+ ["Ṟ"]={ "R", "̱" },
+ ["ṟ"]={ "r", "̱" },
+ ["Ṡ"]={ "S", "̇" },
+ ["ṡ"]={ "s", "̇" },
+ ["á¹¢"]={ "S", "Ì£" },
+ ["á¹£"]={ "s", "Ì£" },
+ ["Ṥ"]={ "Ś", "̇" },
+ ["ṥ"]={ "ś", "̇" },
+ ["Ṧ"]={ "Š", "̇" },
+ ["ṧ"]={ "š", "̇" },
+ ["Ṩ"]={ "Ṣ", "̇" },
+ ["ṩ"]={ "ṣ", "̇" },
+ ["Ṫ"]={ "T", "̇" },
+ ["ṫ"]={ "t", "̇" },
+ ["Ṭ"]={ "T", "̣" },
+ ["á¹­"]={ "t", "Ì£" },
+ ["Ṯ"]={ "T", "̱" },
+ ["ṯ"]={ "t", "̱" },
+ ["á¹°"]={ "T", "Ì­" },
+ ["á¹±"]={ "t", "Ì­" },
+ ["Ṳ"]={ "U", "̤" },
+ ["ṳ"]={ "u", "̤" },
+ ["á¹´"]={ "U", "Ì°" },
+ ["á¹µ"]={ "u", "Ì°" },
+ ["Ṷ"]={ "U", "̭" },
+ ["á¹·"]={ "u", "Ì­" },
+ ["Ṹ"]={ "Ũ", "Ì" },
+ ["á¹¹"]={ "Å©", "Ì" },
+ ["Ṻ"]={ "Ū", "̈" },
+ ["ṻ"]={ "ū", "̈" },
+ ["Ṽ"]={ "V", "̃" },
+ ["ṽ"]={ "v", "̃" },
+ ["á¹¾"]={ "V", "Ì£" },
+ ["ṿ"]={ "v", "̣" },
+ ["Ẁ"]={ "W", "̀" },
+ ["áº"]={ "w", "Ì€" },
+ ["Ẃ"]={ "W", "Ì" },
+ ["ẃ"]={ "w", "Ì" },
+ ["Ẅ"]={ "W", "̈" },
+ ["ẅ"]={ "w", "̈" },
+ ["Ẇ"]={ "W", "̇" },
+ ["ẇ"]={ "w", "̇" },
+ ["Ẉ"]={ "W", "̣" },
+ ["ẉ"]={ "w", "̣" },
+ ["Ẋ"]={ "X", "̇" },
+ ["ẋ"]={ "x", "̇" },
+ ["Ẍ"]={ "X", "̈" },
+ ["áº"]={ "x", "̈" },
+ ["Ẏ"]={ "Y", "̇" },
+ ["áº"]={ "y", "̇" },
+ ["áº"]={ "Z", "Ì‚" },
+ ["ẑ"]={ "z", "̂" },
+ ["Ẓ"]={ "Z", "̣" },
+ ["ẓ"]={ "z", "̣" },
+ ["Ẕ"]={ "Z", "̱" },
+ ["ẕ"]={ "z", "̱" },
+ ["ẖ"]={ "h", "̱" },
+ ["ẗ"]={ "t", "̈" },
+ ["ẘ"]={ "w", "̊" },
+ ["ẙ"]={ "y", "̊" },
+ ["ẛ"]={ "ſ", "̇" },
+ ["Ạ"]={ "A", "̣" },
+ ["ạ"]={ "a", "̣" },
+ ["Ả"]={ "A", "̉" },
+ ["ả"]={ "a", "̉" },
+ ["Ấ"]={ "Â", "Ì" },
+ ["ấ"]={ "â", "Ì" },
+ ["Ầ"]={ "Â", "̀" },
+ ["ầ"]={ "â", "̀" },
+ ["Ẩ"]={ "Â", "̉" },
+ ["ẩ"]={ "â", "̉" },
+ ["Ẫ"]={ "Â", "̃" },
+ ["ẫ"]={ "â", "̃" },
+ ["Ậ"]={ "Ạ", "̂" },
+ ["ậ"]={ "ạ", "̂" },
+ ["Ắ"]={ "Ä‚", "Ì" },
+ ["ắ"]={ "ă", "Ì" },
+ ["Ằ"]={ "Ă", "̀" },
+ ["ằ"]={ "ă", "̀" },
+ ["Ẳ"]={ "Ă", "̉" },
+ ["ẳ"]={ "ă", "̉" },
+ ["Ẵ"]={ "Ă", "̃" },
+ ["ẵ"]={ "ă", "̃" },
+ ["Ặ"]={ "Ạ", "̆" },
+ ["ặ"]={ "ạ", "̆" },
+ ["Ẹ"]={ "E", "̣" },
+ ["ẹ"]={ "e", "̣" },
+ ["Ẻ"]={ "E", "̉" },
+ ["ẻ"]={ "e", "̉" },
+ ["Ẽ"]={ "E", "̃" },
+ ["ẽ"]={ "e", "̃" },
+ ["Ế"]={ "Ê", "Ì" },
+ ["ế"]={ "ê", "Ì" },
+ ["Ề"]={ "Ê", "̀" },
+ ["á»"]={ "ê", "Ì€" },
+ ["Ể"]={ "Ê", "̉" },
+ ["ể"]={ "ê", "̉" },
+ ["Ễ"]={ "Ê", "̃" },
+ ["ễ"]={ "ê", "̃" },
+ ["Ệ"]={ "Ẹ", "̂" },
+ ["ệ"]={ "ẹ", "̂" },
+ ["Ỉ"]={ "I", "̉" },
+ ["ỉ"]={ "i", "̉" },
+ ["Ị"]={ "I", "̣" },
+ ["ị"]={ "i", "̣" },
+ ["Ọ"]={ "O", "̣" },
+ ["á»"]={ "o", "Ì£" },
+ ["Ỏ"]={ "O", "̉" },
+ ["á»"]={ "o", "̉" },
+ ["á»"]={ "Ô", "Ì" },
+ ["ố"]={ "ô", "Ì" },
+ ["Ồ"]={ "Ô", "̀" },
+ ["ồ"]={ "ô", "̀" },
+ ["Ổ"]={ "Ô", "̉" },
+ ["ổ"]={ "ô", "̉" },
+ ["Ỗ"]={ "Ô", "̃" },
+ ["ỗ"]={ "ô", "̃" },
+ ["Ộ"]={ "Ọ", "̂" },
+ ["á»™"]={ "á»", "Ì‚" },
+ ["Ớ"]={ "Æ ", "Ì" },
+ ["á»›"]={ "Æ¡", "Ì" },
+ ["Ờ"]={ "Ơ", "̀" },
+ ["á»"]={ "Æ¡", "Ì€" },
+ ["Ở"]={ "Ơ", "̉" },
+ ["ở"]={ "ơ", "̉" },
+ ["Ỡ"]={ "Ơ", "̃" },
+ ["ỡ"]={ "ơ", "̃" },
+ ["Ợ"]={ "Ơ", "̣" },
+ ["ợ"]={ "ơ", "̣" },
+ ["Ụ"]={ "U", "̣" },
+ ["ụ"]={ "u", "̣" },
+ ["Ủ"]={ "U", "̉" },
+ ["ủ"]={ "u", "̉" },
+ ["Ứ"]={ "Ư", "Ì" },
+ ["ứ"]={ "Æ°", "Ì" },
+ ["Ừ"]={ "Ư", "̀" },
+ ["ừ"]={ "ư", "̀" },
+ ["Ử"]={ "Ư", "̉" },
+ ["ử"]={ "ư", "̉" },
+ ["Ữ"]={ "Ư", "̃" },
+ ["ữ"]={ "ư", "̃" },
+ ["Ự"]={ "Ư", "̣" },
+ ["á»±"]={ "Æ°", "Ì£" },
+ ["Ỳ"]={ "Y", "̀" },
+ ["ỳ"]={ "y", "̀" },
+ ["á»´"]={ "Y", "Ì£" },
+ ["ỵ"]={ "y", "̣" },
+ ["Ỷ"]={ "Y", "̉" },
+ ["ỷ"]={ "y", "̉" },
+ ["Ỹ"]={ "Y", "̃" },
+ ["ỹ"]={ "y", "̃" },
+ ["ἀ"]={ "α", "̓" },
+ ["á¼"]={ "α", "Ì”" },
+ ["ἂ"]={ "ἀ", "̀" },
+ ["ἃ"]={ "á¼", "Ì€" },
+ ["ἄ"]={ "á¼€", "Ì" },
+ ["á¼…"]={ "á¼", "Ì" },
+ ["ἆ"]={ "ἀ", "͂" },
+ ["ἇ"]={ "á¼", "Í‚" },
+ ["Ἀ"]={ "Α", "̓" },
+ ["Ἁ"]={ "Α", "̔" },
+ ["Ἂ"]={ "Ἀ", "̀" },
+ ["Ἃ"]={ "Ἁ", "̀" },
+ ["Ἄ"]={ "Ἀ", "Ì" },
+ ["á¼"]={ "Ἁ", "Ì" },
+ ["Ἆ"]={ "Ἀ", "͂" },
+ ["á¼"]={ "Ἁ", "Í‚" },
+ ["á¼"]={ "ε", "Ì“" },
+ ["ἑ"]={ "ε", "̔" },
+ ["á¼’"]={ "á¼", "Ì€" },
+ ["ἓ"]={ "ἑ", "̀" },
+ ["á¼”"]={ "á¼", "Ì" },
+ ["ἕ"]={ "ἑ", "Ì" },
+ ["Ἐ"]={ "Ε", "̓" },
+ ["Ἑ"]={ "Ε", "̔" },
+ ["Ἒ"]={ "Ἐ", "̀" },
+ ["á¼›"]={ "á¼™", "Ì€" },
+ ["Ἔ"]={ "Ἐ", "Ì" },
+ ["á¼"]={ "á¼™", "Ì" },
+ ["ἠ"]={ "η", "̓" },
+ ["ἡ"]={ "η", "̔" },
+ ["á¼¢"]={ "á¼ ", "Ì€" },
+ ["ἣ"]={ "ἡ", "̀" },
+ ["ἤ"]={ "á¼ ", "Ì" },
+ ["á¼¥"]={ "ἡ", "Ì" },
+ ["ἦ"]={ "ἠ", "͂" },
+ ["ἧ"]={ "ἡ", "͂" },
+ ["Ἠ"]={ "Η", "̓" },
+ ["Ἡ"]={ "Η", "̔" },
+ ["Ἢ"]={ "Ἠ", "̀" },
+ ["Ἣ"]={ "Ἡ", "̀" },
+ ["Ἤ"]={ "Ἠ", "Ì" },
+ ["á¼­"]={ "Ἡ", "Ì" },
+ ["Ἦ"]={ "Ἠ", "͂" },
+ ["Ἧ"]={ "Ἡ", "͂" },
+ ["ἰ"]={ "ι", "̓" },
+ ["ἱ"]={ "ι", "̔" },
+ ["á¼²"]={ "á¼°", "Ì€" },
+ ["á¼³"]={ "á¼±", "Ì€" },
+ ["á¼´"]={ "á¼°", "Ì" },
+ ["á¼µ"]={ "á¼±", "Ì" },
+ ["ἶ"]={ "ἰ", "͂" },
+ ["á¼·"]={ "á¼±", "Í‚" },
+ ["Ἰ"]={ "Ι", "̓" },
+ ["Ἱ"]={ "Ι", "̔" },
+ ["Ἲ"]={ "Ἰ", "̀" },
+ ["á¼»"]={ "á¼¹", "Ì€" },
+ ["á¼¼"]={ "Ἰ", "Ì" },
+ ["á¼½"]={ "á¼¹", "Ì" },
+ ["Ἶ"]={ "Ἰ", "͂" },
+ ["Ἷ"]={ "Ἱ", "͂" },
+ ["ὀ"]={ "ο", "̓" },
+ ["á½"]={ "ο", "Ì”" },
+ ["ὂ"]={ "ὀ", "̀" },
+ ["ὃ"]={ "á½", "Ì€" },
+ ["ὄ"]={ "á½€", "Ì" },
+ ["á½…"]={ "á½", "Ì" },
+ ["Ὀ"]={ "Ο", "̓" },
+ ["Ὁ"]={ "Ο", "̔" },
+ ["Ὂ"]={ "Ὀ", "̀" },
+ ["Ὃ"]={ "Ὁ", "̀" },
+ ["Ὄ"]={ "Ὀ", "Ì" },
+ ["á½"]={ "Ὁ", "Ì" },
+ ["á½"]={ "Ï…", "Ì“" },
+ ["ὑ"]={ "υ", "̔" },
+ ["á½’"]={ "á½", "Ì€" },
+ ["ὓ"]={ "ὑ", "̀" },
+ ["á½”"]={ "á½", "Ì" },
+ ["ὕ"]={ "ὑ", "Ì" },
+ ["á½–"]={ "á½", "Í‚" },
+ ["ὗ"]={ "ὑ", "͂" },
+ ["á½™"]={ "Î¥", "Ì”" },
+ ["á½›"]={ "á½™", "Ì€" },
+ ["á½"]={ "á½™", "Ì" },
+ ["Ὗ"]={ "Ὑ", "͂" },
+ ["ὠ"]={ "ω", "̓" },
+ ["ὡ"]={ "ω", "̔" },
+ ["á½¢"]={ "á½ ", "Ì€" },
+ ["ὣ"]={ "ὡ", "̀" },
+ ["ὤ"]={ "á½ ", "Ì" },
+ ["á½¥"]={ "ὡ", "Ì" },
+ ["ὦ"]={ "ὠ", "͂" },
+ ["ὧ"]={ "ὡ", "͂" },
+ ["Ὠ"]={ "Ω", "̓" },
+ ["Ὡ"]={ "Ω", "̔" },
+ ["Ὢ"]={ "Ὠ", "̀" },
+ ["Ὣ"]={ "Ὡ", "̀" },
+ ["Ὤ"]={ "Ὠ", "Ì" },
+ ["á½­"]={ "Ὡ", "Ì" },
+ ["Ὦ"]={ "Ὠ", "͂" },
+ ["Ὧ"]={ "Ὡ", "͂" },
+ ["ὰ"]={ "α", "̀" },
+ ["ὲ"]={ "ε", "̀" },
+ ["ὴ"]={ "η", "̀" },
+ ["ὶ"]={ "ι", "̀" },
+ ["ὸ"]={ "ο", "̀" },
+ ["ὺ"]={ "υ", "̀" },
+ ["ὼ"]={ "ω", "̀" },
+ ["á¾€"]={ "á¼€", "Í…" },
+ ["á¾"]={ "á¼", "Í…" },
+ ["ᾂ"]={ "ἂ", "ͅ" },
+ ["ᾃ"]={ "ἃ", "ͅ" },
+ ["ᾄ"]={ "ἄ", "ͅ" },
+ ["á¾…"]={ "á¼…", "Í…" },
+ ["ᾆ"]={ "ἆ", "ͅ" },
+ ["ᾇ"]={ "ἇ", "ͅ" },
+ ["ᾈ"]={ "Ἀ", "ͅ" },
+ ["ᾉ"]={ "Ἁ", "ͅ" },
+ ["ᾊ"]={ "Ἂ", "ͅ" },
+ ["ᾋ"]={ "Ἃ", "ͅ" },
+ ["ᾌ"]={ "Ἄ", "ͅ" },
+ ["á¾"]={ "á¼", "Í…" },
+ ["ᾎ"]={ "Ἆ", "ͅ" },
+ ["á¾"]={ "á¼", "Í…" },
+ ["á¾"]={ "á¼ ", "Í…" },
+ ["ᾑ"]={ "ἡ", "ͅ" },
+ ["á¾’"]={ "á¼¢", "Í…" },
+ ["ᾓ"]={ "ἣ", "ͅ" },
+ ["ᾔ"]={ "ἤ", "ͅ" },
+ ["ᾕ"]={ "ἥ", "ͅ" },
+ ["ᾖ"]={ "ἦ", "ͅ" },
+ ["ᾗ"]={ "ἧ", "ͅ" },
+ ["ᾘ"]={ "Ἠ", "ͅ" },
+ ["ᾙ"]={ "Ἡ", "ͅ" },
+ ["ᾚ"]={ "Ἢ", "ͅ" },
+ ["ᾛ"]={ "Ἣ", "ͅ" },
+ ["ᾜ"]={ "Ἤ", "ͅ" },
+ ["á¾"]={ "á¼­", "Í…" },
+ ["ᾞ"]={ "Ἦ", "ͅ" },
+ ["ᾟ"]={ "Ἧ", "ͅ" },
+ ["á¾ "]={ "á½ ", "Í…" },
+ ["ᾡ"]={ "ὡ", "ͅ" },
+ ["á¾¢"]={ "á½¢", "Í…" },
+ ["á¾£"]={ "á½£", "Í…" },
+ ["ᾤ"]={ "ὤ", "ͅ" },
+ ["á¾¥"]={ "á½¥", "Í…" },
+ ["ᾦ"]={ "ὦ", "ͅ" },
+ ["ᾧ"]={ "ὧ", "ͅ" },
+ ["ᾨ"]={ "Ὠ", "ͅ" },
+ ["ᾩ"]={ "Ὡ", "ͅ" },
+ ["ᾪ"]={ "Ὢ", "ͅ" },
+ ["ᾫ"]={ "Ὣ", "ͅ" },
+ ["ᾬ"]={ "Ὤ", "ͅ" },
+ ["á¾­"]={ "á½­", "Í…" },
+ ["á¾®"]={ "á½®", "Í…" },
+ ["ᾯ"]={ "Ὧ", "ͅ" },
+ ["ᾰ"]={ "α", "̆" },
+ ["ᾱ"]={ "α", "̄" },
+ ["á¾²"]={ "á½°", "Í…" },
+ ["ᾳ"]={ "α", "ͅ" },
+ ["ᾴ"]={ "ά", "ͅ" },
+ ["ᾶ"]={ "α", "͂" },
+ ["ᾷ"]={ "ᾶ", "ͅ" },
+ ["Ᾰ"]={ "Α", "̆" },
+ ["Ᾱ"]={ "Α", "̄" },
+ ["Ὰ"]={ "Α", "̀" },
+ ["ᾼ"]={ "Α", "ͅ" },
+ ["á¿"]={ "¨", "Í‚" },
+ ["á¿‚"]={ "á½´", "Í…" },
+ ["ῃ"]={ "η", "ͅ" },
+ ["ῄ"]={ "ή", "ͅ" },
+ ["ῆ"]={ "η", "͂" },
+ ["ῇ"]={ "ῆ", "ͅ" },
+ ["Ὲ"]={ "Ε", "̀" },
+ ["Ὴ"]={ "Η", "̀" },
+ ["ῌ"]={ "Η", "ͅ" },
+ ["á¿"]={ "᾿", "Ì€" },
+ ["á¿Ž"]={ "᾿", "Ì" },
+ ["á¿"]={ "᾿", "Í‚" },
+ ["á¿"]={ "ι", "̆" },
+ ["ῑ"]={ "ι", "̄" },
+ ["á¿’"]={ "ÏŠ", "Ì€" },
+ ["ῖ"]={ "ι", "͂" },
+ ["á¿—"]={ "ÏŠ", "Í‚" },
+ ["Ῐ"]={ "Ι", "̆" },
+ ["Ῑ"]={ "Ι", "̄" },
+ ["Ὶ"]={ "Ι", "̀" },
+ ["á¿"]={ "῾", "Ì€" },
+ ["á¿ž"]={ "῾", "Ì" },
+ ["῟"]={ "῾", "͂" },
+ ["ῠ"]={ "υ", "̆" },
+ ["á¿¡"]={ "Ï…", "Ì„" },
+ ["á¿¢"]={ "Ï‹", "Ì€" },
+ ["ῤ"]={ "Ï", "Ì“" },
+ ["á¿¥"]={ "Ï", "Ì”" },
+ ["ῦ"]={ "υ", "͂" },
+ ["ῧ"]={ "ϋ", "͂" },
+ ["Ῠ"]={ "Υ", "̆" },
+ ["á¿©"]={ "Î¥", "Ì„" },
+ ["Ὺ"]={ "Υ", "̀" },
+ ["Ῥ"]={ "Ρ", "̔" },
+ ["῭"]={ "¨", "̀" },
+ ["ῲ"]={ "ὼ", "ͅ" },
+ ["ῳ"]={ "ω", "ͅ" },
+ ["á¿´"]={ "ÏŽ", "Í…" },
+ ["ῶ"]={ "ω", "͂" },
+ ["ῷ"]={ "ῶ", "ͅ" },
+ ["Ὸ"]={ "Ο", "̀" },
+ ["Ὼ"]={ "Ω", "̀" },
+ ["ῼ"]={ "Ω", "ͅ" },
+ ["↚"]={ "â†", "̸" },
+ ["↛"]={ "→", "̸" },
+ ["↮"]={ "↔", "̸" },
+ ["â‡"]={ "â‡", "̸" },
+ ["⇎"]={ "⇔", "̸" },
+ ["â‡"]={ "⇒", "̸" },
+ ["∄"]={ "∃", "̸" },
+ ["∉"]={ "∈", "̸" },
+ ["∌"]={ "∋", "̸" },
+ ["∤"]={ "∣", "̸" },
+ ["∦"]={ "∥", "̸" },
+ ["â‰"]={ "∼", "̸" },
+ ["≄"]={ "≃", "̸" },
+ ["≇"]={ "≅", "̸" },
+ ["≉"]={ "≈", "̸" },
+ ["≠"]={ "=", "̸" },
+ ["≢"]={ "≡", "̸" },
+ ["≭"]={ "â‰", "̸" },
+ ["≮"]={ "<", "̸" },
+ ["≯"]={ ">", "̸" },
+ ["≰"]={ "≤", "̸" },
+ ["≱"]={ "≥", "̸" },
+ ["≴"]={ "≲", "̸" },
+ ["≵"]={ "≳", "̸" },
+ ["≸"]={ "≶", "̸" },
+ ["≹"]={ "≷", "̸" },
+ ["⊀"]={ "≺", "̸" },
+ ["âŠ"]={ "≻", "̸" },
+ ["⊄"]={ "⊂", "̸" },
+ ["⊅"]={ "⊃", "̸" },
+ ["⊈"]={ "⊆", "̸" },
+ ["⊉"]={ "⊇", "̸" },
+ ["⊬"]={ "⊢", "̸" },
+ ["⊭"]={ "⊨", "̸" },
+ ["⊮"]={ "⊩", "̸" },
+ ["⊯"]={ "⊫", "̸" },
+ ["⋠"]={ "≼", "̸" },
+ ["⋡"]={ "≽", "̸" },
+ ["⋢"]={ "⊑", "̸" },
+ ["⋣"]={ "⊒", "̸" },
+ ["⋪"]={ "⊲", "̸" },
+ ["⋫"]={ "⊳", "̸" },
+ ["⋬"]={ "⊴", "̸" },
+ ["⋭"]={ "⊵", "̸" },
+ ["â«œ"]={ "â«", "̸" },
+ ["ãŒ"]={ "ã‹", "ã‚™" },
+ ["ãŽ"]={ "ã", "ã‚™" },
+ ["ã"]={ "ã", "ã‚™" },
+ ["ã’"]={ "ã‘", "ã‚™" },
+ ["ã”"]={ "ã“", "ã‚™" },
+ ["ã–"]={ "ã•", "ã‚™" },
+ ["ã˜"]={ "ã—", "ã‚™" },
+ ["ãš"]={ "ã™", "ã‚™" },
+ ["ãœ"]={ "ã›", "ã‚™" },
+ ["ãž"]={ "ã", "ã‚™" },
+ ["ã "]={ "ãŸ", "ã‚™" },
+ ["ã¢"]={ "ã¡", "ã‚™" },
+ ["ã¥"]={ "ã¤", "ã‚™" },
+ ["ã§"]={ "ã¦", "ã‚™" },
+ ["ã©"]={ "ã¨", "ã‚™" },
+ ["ã°"]={ "ã¯", "ã‚™" },
+ ["ã±"]={ "ã¯", "ã‚š" },
+ ["ã³"]={ "ã²", "ã‚™" },
+ ["ã´"]={ "ã²", "ã‚š" },
+ ["ã¶"]={ "ãµ", "ã‚™" },
+ ["ã·"]={ "ãµ", "ã‚š" },
+ ["ã¹"]={ "ã¸", "ã‚™" },
+ ["ãº"]={ "ã¸", "ã‚š" },
+ ["ã¼"]={ "ã»", "ã‚™" },
+ ["ã½"]={ "ã»", "ã‚š" },
+ ["ã‚”"]={ "ã†", "ã‚™" },
+ ["ã‚ž"]={ "ã‚", "ã‚™" },
+ ["ガ"]={ "カ", "゙" },
+ ["ã‚®"]={ "ã‚­", "ã‚™" },
+ ["グ"]={ "ク", "゙" },
+ ["ゲ"]={ "ケ", "゙" },
+ ["ゴ"]={ "コ", "゙" },
+ ["ザ"]={ "サ", "゙" },
+ ["ジ"]={ "シ", "゙" },
+ ["ズ"]={ "ス", "゙" },
+ ["ゼ"]={ "セ", "゙" },
+ ["ゾ"]={ "ソ", "゙" },
+ ["ダ"]={ "タ", "゙" },
+ ["ヂ"]={ "ãƒ", "ã‚™" },
+ ["ヅ"]={ "ツ", "゙" },
+ ["デ"]={ "テ", "゙" },
+ ["ド"]={ "ト", "゙" },
+ ["ãƒ"]={ "ãƒ", "ã‚™" },
+ ["パ"]={ "ãƒ", "ã‚š" },
+ ["ビ"]={ "ヒ", "゙" },
+ ["ピ"]={ "ヒ", "゚" },
+ ["ブ"]={ "フ", "゙" },
+ ["プ"]={ "フ", "゚" },
+ ["ベ"]={ "ヘ", "゙" },
+ ["ペ"]={ "ヘ", "゚" },
+ ["ボ"]={ "ホ", "゙" },
+ ["ãƒ"]={ "ホ", "ã‚š" },
+ ["ヴ"]={ "ウ", "゙" },
+ ["ヷ"]={ "ワ", "゙" },
+ ["ヸ"]={ "ヰ", "゙" },
+ ["ヹ"]={ "ヱ", "゙" },
+ ["ヺ"]={ "ヲ", "゙" },
+ ["ヾ"]={ "ヽ", "゙" },
+ ["ï¬"]={ "×™", "Ö´" },
+ ["ײַ"]={ "ײ", "ַ" },
+ ["שׁ"]={ "ש", "×" },
+ ["שׂ"]={ "ש", "ׂ" },
+ ["שּׁ"]={ "ï­‰", "×" },
+ ["שּׂ"]={ "שּ", "ׂ" },
+ ["אַ"]={ "×", "Ö·" },
+ ["אָ"]={ "×", "Ö¸" },
+ ["אּ"]={ "×", "Ö¼" },
+ ["בּ"]={ "ב", "ּ" },
+ ["גּ"]={ "ג", "ּ" },
+ ["דּ"]={ "ד", "ּ" },
+ ["הּ"]={ "ה", "ּ" },
+ ["וּ"]={ "ו", "ּ" },
+ ["זּ"]={ "ז", "ּ" },
+ ["טּ"]={ "ט", "ּ" },
+ ["יּ"]={ "י", "ּ" },
+ ["ךּ"]={ "ך", "ּ" },
+ ["כּ"]={ "כ", "ּ" },
+ ["לּ"]={ "ל", "ּ" },
+ ["מּ"]={ "מ", "ּ" },
+ ["ï­€"]={ "× ", "Ö¼" },
+ ["ï­"]={ "ס", "Ö¼" },
+ ["ï­ƒ"]={ "×£", "Ö¼" },
+ ["פּ"]={ "פ", "ּ" },
+ ["צּ"]={ "צ", "ּ" },
+ ["קּ"]={ "ק", "ּ" },
+ ["רּ"]={ "ר", "ּ" },
+ ["שּ"]={ "ש", "ּ" },
+ ["תּ"]={ "ת", "ּ" },
+ ["וֹ"]={ "ו", "ֹ" },
+ ["בֿ"]={ "ב", "ֿ" },
+ ["ï­"]={ "×›", "Ö¿" },
+ ["פֿ"]={ "פ", "ֿ" },
+ ["𑂚"]={ "𑂙", "𑂺" },
+ ["𑂜"]={ "𑂛", "𑂺" },
+ ["𑂫"]={ "𑂥", "𑂺" },
+ ["𑄮"]={ "𑄱", "𑄧" },
+ ["𑄯"]={ "𑄲", "𑄧" },
+ ["ð‘‹"]={ "ð‘‡", "𑌾" },
+ ["ð‘Œ"]={ "ð‘‡", "ð‘—" },
+ ["ð‘’»"]={ "ð‘’¹", "ð‘’º" },
+ ["ð‘’¼"]={ "ð‘’¹", "ð‘’°" },
+ ["ð‘’¾"]={ "ð‘’¹", "ð‘’½" },
+ ["ð‘–º"]={ "ð‘–¸", "ð‘–¯" },
+ ["ð‘–»"]={ "ð‘–¹", "ð‘–¯" },
+ ["ð…ž"]={ "ð…—", "ð…¥" },
+ ["ð…Ÿ"]={ "ð…˜", "ð…¥" },
+ ["ð… "]={ "ð…Ÿ", "ð…®" },
+ ["ð…¡"]={ "ð…Ÿ", "ð…¯" },
+ ["ð…¢"]={ "ð…Ÿ", "ð…°" },
+ ["ð…£"]={ "ð…Ÿ", "ð…±" },
+ ["ð…¤"]={ "ð…Ÿ", "ð…²" },
+ ["ð†»"]={ "ð†¹", "ð…¥" },
+ ["ð†¼"]={ "ð†º", "ð…¥" },
+ ["ð†½"]={ "ð†»", "ð…®" },
+ ["ð†¾"]={ "ð†¼", "ð…®" },
+ ["ð†¿"]={ "ð†»", "ð…¯" },
+ ["ð‡€"]={ "ð†¼", "ð…¯" },
+ },
+ },
+ {
+ ["data"]={
+ ["À"]={ "A", "̀" },
+ ["Ã"]={ "A", "Ì" },
+ ["Â"]={ "A", "̂" },
+ ["Ã"]={ "A", "̃" },
+ ["Ä"]={ "A", "̈" },
+ ["Ã…"]={ "A", "ÌŠ" },
+ ["Ç"]={ "C", "̧" },
+ ["È"]={ "E", "̀" },
+ ["É"]={ "E", "Ì" },
+ ["Ê"]={ "E", "̂" },
+ ["Ë"]={ "E", "̈" },
+ ["Ì"]={ "I", "̀" },
+ ["Ã"]={ "I", "Ì" },
+ ["ÃŽ"]={ "I", "Ì‚" },
+ ["Ã"]={ "I", "̈" },
+ ["Ñ"]={ "N", "̃" },
+ ["Ã’"]={ "O", "Ì€" },
+ ["Ó"]={ "O", "Ì" },
+ ["Ô"]={ "O", "̂" },
+ ["Õ"]={ "O", "̃" },
+ ["Ö"]={ "O", "̈" },
+ ["Ù"]={ "U", "̀" },
+ ["Ú"]={ "U", "Ì" },
+ ["Û"]={ "U", "̂" },
+ ["Ü"]={ "U", "̈" },
+ ["Ã"]={ "Y", "Ì" },
+ ["à"]={ "a", "̀" },
+ ["á"]={ "a", "Ì" },
+ ["â"]={ "a", "̂" },
+ ["ã"]={ "a", "̃" },
+ ["ä"]={ "a", "̈" },
+ ["Ã¥"]={ "a", "ÌŠ" },
+ ["ç"]={ "c", "̧" },
+ ["è"]={ "e", "̀" },
+ ["é"]={ "e", "Ì" },
+ ["ê"]={ "e", "̂" },
+ ["ë"]={ "e", "̈" },
+ ["ì"]={ "i", "̀" },
+ ["í"]={ "i", "Ì" },
+ ["î"]={ "i", "̂" },
+ ["ï"]={ "i", "̈" },
+ ["ñ"]={ "n", "̃" },
+ ["ò"]={ "o", "̀" },
+ ["ó"]={ "o", "Ì" },
+ ["ô"]={ "o", "̂" },
+ ["õ"]={ "o", "̃" },
+ ["ö"]={ "o", "̈" },
+ ["ù"]={ "u", "̀" },
+ ["ú"]={ "u", "Ì" },
+ ["û"]={ "u", "̂" },
+ ["ü"]={ "u", "̈" },
+ ["ý"]={ "y", "Ì" },
+ ["ÿ"]={ "y", "̈" },
+ ["Ä€"]={ "A", "Ì„" },
+ ["Ä"]={ "a", "Ì„" },
+ ["Ă"]={ "A", "̆" },
+ ["ă"]={ "a", "̆" },
+ ["Ą"]={ "A", "̨" },
+ ["ą"]={ "a", "̨" },
+ ["Ć"]={ "C", "Ì" },
+ ["ć"]={ "c", "Ì" },
+ ["Ĉ"]={ "C", "̂" },
+ ["ĉ"]={ "c", "̂" },
+ ["Ċ"]={ "C", "̇" },
+ ["ċ"]={ "c", "̇" },
+ ["Č"]={ "C", "̌" },
+ ["Ä"]={ "c", "ÌŒ" },
+ ["Ď"]={ "D", "̌" },
+ ["Ä"]={ "d", "ÌŒ" },
+ ["Ä’"]={ "E", "Ì„" },
+ ["Ä“"]={ "e", "Ì„" },
+ ["Ĕ"]={ "E", "̆" },
+ ["ĕ"]={ "e", "̆" },
+ ["Ė"]={ "E", "̇" },
+ ["ė"]={ "e", "̇" },
+ ["Ę"]={ "E", "̨" },
+ ["ę"]={ "e", "̨" },
+ ["Ě"]={ "E", "̌" },
+ ["ě"]={ "e", "̌" },
+ ["Ĝ"]={ "G", "̂" },
+ ["Ä"]={ "g", "Ì‚" },
+ ["Ğ"]={ "G", "̆" },
+ ["ğ"]={ "g", "̆" },
+ ["Ġ"]={ "G", "̇" },
+ ["ġ"]={ "g", "̇" },
+ ["Ģ"]={ "G", "̧" },
+ ["ģ"]={ "g", "̧" },
+ ["Ĥ"]={ "H", "̂" },
+ ["Ä¥"]={ "h", "Ì‚" },
+ ["Ĩ"]={ "I", "̃" },
+ ["ĩ"]={ "i", "̃" },
+ ["Ī"]={ "I", "̄" },
+ ["Ä«"]={ "i", "Ì„" },
+ ["Ĭ"]={ "I", "̆" },
+ ["ĭ"]={ "i", "̆" },
+ ["Į"]={ "I", "̨" },
+ ["į"]={ "i", "̨" },
+ ["İ"]={ "I", "̇" },
+ ["Ä´"]={ "J", "Ì‚" },
+ ["ĵ"]={ "j", "̂" },
+ ["Ķ"]={ "K", "̧" },
+ ["ķ"]={ "k", "̧" },
+ ["Ĺ"]={ "L", "Ì" },
+ ["ĺ"]={ "l", "Ì" },
+ ["Ļ"]={ "L", "̧" },
+ ["ļ"]={ "l", "̧" },
+ ["Ľ"]={ "L", "̌" },
+ ["ľ"]={ "l", "̌" },
+ ["Ń"]={ "N", "Ì" },
+ ["Å„"]={ "n", "Ì" },
+ ["Ņ"]={ "N", "̧" },
+ ["ņ"]={ "n", "̧" },
+ ["Ň"]={ "N", "̌" },
+ ["ň"]={ "n", "̌" },
+ ["Ō"]={ "O", "̄" },
+ ["Å"]={ "o", "Ì„" },
+ ["Ŏ"]={ "O", "̆" },
+ ["Å"]={ "o", "̆" },
+ ["Å"]={ "O", "Ì‹" },
+ ["Å‘"]={ "o", "Ì‹" },
+ ["Å”"]={ "R", "Ì" },
+ ["Å•"]={ "r", "Ì" },
+ ["Ŗ"]={ "R", "̧" },
+ ["ŗ"]={ "r", "̧" },
+ ["Ř"]={ "R", "̌" },
+ ["ř"]={ "r", "̌" },
+ ["Åš"]={ "S", "Ì" },
+ ["Å›"]={ "s", "Ì" },
+ ["Ŝ"]={ "S", "̂" },
+ ["Å"]={ "s", "Ì‚" },
+ ["Ş"]={ "S", "̧" },
+ ["ş"]={ "s", "̧" },
+ ["Š"]={ "S", "̌" },
+ ["š"]={ "s", "̌" },
+ ["Ţ"]={ "T", "̧" },
+ ["ţ"]={ "t", "̧" },
+ ["Ť"]={ "T", "̌" },
+ ["ť"]={ "t", "̌" },
+ ["Ũ"]={ "U", "̃" },
+ ["ũ"]={ "u", "̃" },
+ ["Ū"]={ "U", "̄" },
+ ["Å«"]={ "u", "Ì„" },
+ ["Ŭ"]={ "U", "̆" },
+ ["ŭ"]={ "u", "̆" },
+ ["Å®"]={ "U", "ÌŠ" },
+ ["ů"]={ "u", "̊" },
+ ["Å°"]={ "U", "Ì‹" },
+ ["ű"]={ "u", "̋" },
+ ["Ų"]={ "U", "̨" },
+ ["ų"]={ "u", "̨" },
+ ["Å´"]={ "W", "Ì‚" },
+ ["ŵ"]={ "w", "̂" },
+ ["Ŷ"]={ "Y", "̂" },
+ ["Å·"]={ "y", "Ì‚" },
+ ["Ÿ"]={ "Y", "̈" },
+ ["Ź"]={ "Z", "Ì" },
+ ["ź"]={ "z", "Ì" },
+ ["Ż"]={ "Z", "̇" },
+ ["ż"]={ "z", "̇" },
+ ["Ž"]={ "Z", "̌" },
+ ["ž"]={ "z", "̌" },
+ ["Æ "]={ "O", "Ì›" },
+ ["Æ¡"]={ "o", "Ì›" },
+ ["Ư"]={ "U", "̛" },
+ ["Æ°"]={ "u", "Ì›" },
+ ["Ç"]={ "A", "ÌŒ" },
+ ["ǎ"]={ "a", "̌" },
+ ["Ç"]={ "I", "ÌŒ" },
+ ["Ç"]={ "i", "ÌŒ" },
+ ["Ǒ"]={ "O", "̌" },
+ ["ǒ"]={ "o", "̌" },
+ ["Ǔ"]={ "U", "̌" },
+ ["ǔ"]={ "u", "̌" },
+ ["Ǖ"]={ "Ü", "̄" },
+ ["ǖ"]={ "ü", "̄" },
+ ["Ç—"]={ "Ãœ", "Ì" },
+ ["ǘ"]={ "ü", "Ì" },
+ ["Ǚ"]={ "Ü", "̌" },
+ ["ǚ"]={ "ü", "̌" },
+ ["Ǜ"]={ "Ü", "̀" },
+ ["ǜ"]={ "ü", "̀" },
+ ["Ǟ"]={ "Ä", "̄" },
+ ["ǟ"]={ "ä", "̄" },
+ ["Ǡ"]={ "Ȧ", "̄" },
+ ["ǡ"]={ "ȧ", "̄" },
+ ["Ǣ"]={ "Æ", "̄" },
+ ["ǣ"]={ "æ", "̄" },
+ ["Ǧ"]={ "G", "̌" },
+ ["ǧ"]={ "g", "̌" },
+ ["Ǩ"]={ "K", "̌" },
+ ["ǩ"]={ "k", "̌" },
+ ["Ǫ"]={ "O", "̨" },
+ ["ǫ"]={ "o", "̨" },
+ ["Ǭ"]={ "Ǫ", "̄" },
+ ["Ç­"]={ "Ç«", "Ì„" },
+ ["Ǯ"]={ "Ʒ", "̌" },
+ ["ǯ"]={ "ʒ", "̌" },
+ ["ǰ"]={ "j", "̌" },
+ ["Ç´"]={ "G", "Ì" },
+ ["ǵ"]={ "g", "Ì" },
+ ["Ǹ"]={ "N", "̀" },
+ ["ǹ"]={ "n", "̀" },
+ ["Ǻ"]={ "Ã…", "Ì" },
+ ["Ç»"]={ "Ã¥", "Ì" },
+ ["Ǽ"]={ "Æ", "Ì" },
+ ["ǽ"]={ "æ", "Ì" },
+ ["Ǿ"]={ "Ø", "Ì" },
+ ["Ç¿"]={ "ø", "Ì" },
+ ["È€"]={ "A", "Ì" },
+ ["È"]={ "a", "Ì" },
+ ["È‚"]={ "A", "Ì‘" },
+ ["ȃ"]={ "a", "̑" },
+ ["È„"]={ "E", "Ì" },
+ ["È…"]={ "e", "Ì" },
+ ["Ȇ"]={ "E", "̑" },
+ ["ȇ"]={ "e", "̑" },
+ ["Ȉ"]={ "I", "Ì" },
+ ["ȉ"]={ "i", "Ì" },
+ ["ÈŠ"]={ "I", "Ì‘" },
+ ["È‹"]={ "i", "Ì‘" },
+ ["ÈŒ"]={ "O", "Ì" },
+ ["È"]={ "o", "Ì" },
+ ["ÈŽ"]={ "O", "Ì‘" },
+ ["È"]={ "o", "Ì‘" },
+ ["È"]={ "R", "Ì" },
+ ["È‘"]={ "r", "Ì" },
+ ["È’"]={ "R", "Ì‘" },
+ ["È“"]={ "r", "Ì‘" },
+ ["È”"]={ "U", "Ì" },
+ ["È•"]={ "u", "Ì" },
+ ["È–"]={ "U", "Ì‘" },
+ ["È—"]={ "u", "Ì‘" },
+ ["Ș"]={ "S", "̦" },
+ ["ș"]={ "s", "̦" },
+ ["Ț"]={ "T", "̦" },
+ ["ț"]={ "t", "̦" },
+ ["Ȟ"]={ "H", "̌" },
+ ["ȟ"]={ "h", "̌" },
+ ["Ȧ"]={ "A", "̇" },
+ ["ȧ"]={ "a", "̇" },
+ ["Ȩ"]={ "E", "̧" },
+ ["ȩ"]={ "e", "̧" },
+ ["Ȫ"]={ "Ö", "̄" },
+ ["ȫ"]={ "ö", "̄" },
+ ["Ȭ"]={ "Õ", "̄" },
+ ["ȭ"]={ "õ", "̄" },
+ ["Ȯ"]={ "O", "̇" },
+ ["ȯ"]={ "o", "̇" },
+ ["È°"]={ "È®", "Ì„" },
+ ["ȱ"]={ "ȯ", "̄" },
+ ["Ȳ"]={ "Y", "̄" },
+ ["ȳ"]={ "y", "̄" },
+ ["Í„"]={ "̈", "Ì" },
+ ["Î…"]={ "¨", "Ì" },
+ ["Ά"]={ "Α", "Ì" },
+ ["Έ"]={ "Ε", "Ì" },
+ ["Ή"]={ "Η", "Ì" },
+ ["Ί"]={ "Ι", "Ì" },
+ ["ÎŒ"]={ "Ο", "Ì" },
+ ["ÎŽ"]={ "Î¥", "Ì" },
+ ["Î"]={ "Ω", "Ì" },
+ ["Î"]={ "ÏŠ", "Ì" },
+ ["Ϊ"]={ "Ι", "̈" },
+ ["Ϋ"]={ "Υ", "̈" },
+ ["ά"]={ "α", "Ì" },
+ ["έ"]={ "ε", "Ì" },
+ ["ή"]={ "η", "Ì" },
+ ["ί"]={ "ι", "Ì" },
+ ["ΰ"]={ "Ï‹", "Ì" },
+ ["ϊ"]={ "ι", "̈" },
+ ["ϋ"]={ "υ", "̈" },
+ ["ÏŒ"]={ "ο", "Ì" },
+ ["Ï"]={ "Ï…", "Ì" },
+ ["ÏŽ"]={ "ω", "Ì" },
+ ["Ï“"]={ "Ï’", "Ì" },
+ ["ϔ"]={ "ϒ", "̈" },
+ ["Ѐ"]={ "Е", "̀" },
+ ["Ð"]={ "Е", "̈" },
+ ["Ѓ"]={ "Г", "Ì" },
+ ["Ї"]={ "І", "̈" },
+ ["ÐŒ"]={ "К", "Ì" },
+ ["Ð"]={ "И", "Ì€" },
+ ["Ў"]={ "У", "̆" },
+ ["Й"]={ "И", "̆" },
+ ["й"]={ "и", "̆" },
+ ["Ñ"]={ "е", "Ì€" },
+ ["ё"]={ "е", "̈" },
+ ["Ñ“"]={ "г", "Ì" },
+ ["ї"]={ "і", "̈" },
+ ["Ñœ"]={ "к", "Ì" },
+ ["Ñ"]={ "и", "Ì€" },
+ ["ў"]={ "у", "̆" },
+ ["Ѷ"]={ "Ñ´", "Ì" },
+ ["Ñ·"]={ "ѵ", "Ì" },
+ ["Ó"]={ "Ж", "̆" },
+ ["ӂ"]={ "ж", "̆" },
+ ["Ó"]={ "Ð", "̆" },
+ ["ӑ"]={ "а", "̆" },
+ ["Ó’"]={ "Ð", "̈" },
+ ["ӓ"]={ "а", "̈" },
+ ["Ӗ"]={ "Е", "̆" },
+ ["ӗ"]={ "е", "̆" },
+ ["Ӛ"]={ "Ә", "̈" },
+ ["ӛ"]={ "ә", "̈" },
+ ["Ӝ"]={ "Ж", "̈" },
+ ["Ó"]={ "ж", "̈" },
+ ["Ӟ"]={ "З", "̈" },
+ ["ӟ"]={ "з", "̈" },
+ ["Ӣ"]={ "И", "̄" },
+ ["ӣ"]={ "и", "̄" },
+ ["Ӥ"]={ "И", "̈" },
+ ["ӥ"]={ "и", "̈" },
+ ["Ӧ"]={ "О", "̈" },
+ ["ӧ"]={ "о", "̈" },
+ ["Ӫ"]={ "Ө", "̈" },
+ ["ӫ"]={ "ө", "̈" },
+ ["Ӭ"]={ "Э", "̈" },
+ ["Ó­"]={ "Ñ", "̈" },
+ ["Ӯ"]={ "У", "̄" },
+ ["ӯ"]={ "у", "̄" },
+ ["Ӱ"]={ "У", "̈" },
+ ["ӱ"]={ "у", "̈" },
+ ["Ӳ"]={ "У", "̋" },
+ ["ӳ"]={ "у", "̋" },
+ ["Ӵ"]={ "Ч", "̈" },
+ ["ӵ"]={ "ч", "̈" },
+ ["Ӹ"]={ "Ы", "̈" },
+ ["ӹ"]={ "ы", "̈" },
+ ["آ"]={ "ا", "ٓ" },
+ ["أ"]={ "ا", "ٔ" },
+ ["ؤ"]={ "و", "ٔ" },
+ ["إ"]={ "ا", "ٕ" },
+ ["ئ"]={ "ي", "ٔ" },
+ ["Û€"]={ "Û•", "Ù”" },
+ ["Û‚"]={ "Û", "Ù”" },
+ ["Û“"]={ "Û’", "Ù”" },
+ ["ऩ"]={ "न", "़" },
+ ["ऱ"]={ "र", "़" },
+ ["ऴ"]={ "ळ", "़" },
+ ["क़"]={ "क", "़" },
+ ["ख़"]={ "ख", "़" },
+ ["ग़"]={ "ग", "़" },
+ ["ज़"]={ "ज", "़" },
+ ["ड़"]={ "ड", "़" },
+ ["à¥"]={ "ढ", "़" },
+ ["फ़"]={ "फ", "़" },
+ ["य़"]={ "य", "़" },
+ ["ো"]={ "ে", "া" },
+ ["ৌ"]={ "ে", "ৗ" },
+ ["ড়"]={ "ড", "়" },
+ ["à§"]={ "ঢ", "়" },
+ ["য়"]={ "য", "়" },
+ ["ਲ਼"]={ "ਲ", "਼" },
+ ["ਸ਼"]={ "ਸ", "਼" },
+ ["ਖ਼"]={ "ਖ", "਼" },
+ ["ਗ਼"]={ "ਗ", "਼" },
+ ["ਜ਼"]={ "ਜ", "਼" },
+ ["ਫ਼"]={ "ਫ", "਼" },
+ ["à­ˆ"]={ "à­‡", "à­–" },
+ ["ୋ"]={ "େ", "ା" },
+ ["ୌ"]={ "େ", "ୗ" },
+ ["ଡ଼"]={ "ଡ", "଼" },
+ ["à­"]={ "ଢ", "଼" },
+ ["ஔ"]={ "ஒ", "ௗ" },
+ ["ொ"]={ "ெ", "ா" },
+ ["ோ"]={ "ே", "ா" },
+ ["ௌ"]={ "ெ", "ௗ" },
+ ["ై"]={ "ె", "ౖ" },
+ ["ೀ"]={ "ಿ", "ೕ" },
+ ["ೇ"]={ "ೆ", "ೕ" },
+ ["ೈ"]={ "ೆ", "ೖ" },
+ ["ೊ"]={ "ೆ", "ೂ" },
+ ["ೋ"]={ "ೊ", "ೕ" },
+ ["ൊ"]={ "െ", "ാ" },
+ ["ോ"]={ "േ", "ാ" },
+ ["ൌ"]={ "െ", "ൗ" },
+ ["à·š"]={ "à·™", "à·Š" },
+ ["à·œ"]={ "à·™", "à·" },
+ ["à·"]={ "à·œ", "à·Š" },
+ ["à·ž"]={ "à·™", "à·Ÿ" },
+ ["གྷ"]={ "ག", "ྷ" },
+ ["à½"]={ "ཌ", "ྷ" },
+ ["དྷ"]={ "ད", "ྷ" },
+ ["བྷ"]={ "བ", "ྷ" },
+ ["ཛྷ"]={ "ཛ", "ྷ" },
+ ["ཀྵ"]={ "ཀ", "ྵ" },
+ ["ཱི"]={ "ཱ", "ི" },
+ ["ཱུ"]={ "ཱ", "ུ" },
+ ["ྲྀ"]={ "ྲ", "ྀ" },
+ ["ླྀ"]={ "ླ", "ྀ" },
+ ["à¾"]={ "ཱ", "ྀ" },
+ ["ྒྷ"]={ "ྒ", "ྷ" },
+ ["à¾"]={ "ྜ", "ྷ" },
+ ["ྡྷ"]={ "ྡ", "ྷ" },
+ ["ྦྷ"]={ "ྦ", "ྷ" },
+ ["ྫྷ"]={ "ྫ", "ྷ" },
+ ["ྐྵ"]={ "à¾", "ྵ" },
+ ["ဦ"]={ "ဥ", "ီ" },
+ ["ᬆ"]={ "ᬅ", "ᬵ" },
+ ["ᬈ"]={ "ᬇ", "ᬵ" },
+ ["ᬊ"]={ "ᬉ", "ᬵ" },
+ ["ᬌ"]={ "ᬋ", "ᬵ" },
+ ["ᬎ"]={ "á¬", "ᬵ" },
+ ["ᬒ"]={ "ᬑ", "ᬵ" },
+ ["ᬻ"]={ "ᬺ", "ᬵ" },
+ ["ᬽ"]={ "ᬼ", "ᬵ" },
+ ["ᭀ"]={ "ᬾ", "ᬵ" },
+ ["á­"]={ "ᬿ", "ᬵ" },
+ ["ᭃ"]={ "ᭂ", "ᬵ" },
+ ["Ḁ"]={ "A", "̥" },
+ ["á¸"]={ "a", "Ì¥" },
+ ["Ḃ"]={ "B", "̇" },
+ ["ḃ"]={ "b", "̇" },
+ ["Ḅ"]={ "B", "̣" },
+ ["ḅ"]={ "b", "̣" },
+ ["Ḇ"]={ "B", "̱" },
+ ["ḇ"]={ "b", "̱" },
+ ["Ḉ"]={ "Ç", "Ì" },
+ ["ḉ"]={ "ç", "Ì" },
+ ["Ḋ"]={ "D", "̇" },
+ ["ḋ"]={ "d", "̇" },
+ ["Ḍ"]={ "D", "̣" },
+ ["á¸"]={ "d", "Ì£" },
+ ["Ḏ"]={ "D", "̱" },
+ ["á¸"]={ "d", "̱" },
+ ["á¸"]={ "D", "̧" },
+ ["ḑ"]={ "d", "̧" },
+ ["Ḓ"]={ "D", "̭" },
+ ["ḓ"]={ "d", "̭" },
+ ["Ḕ"]={ "Ē", "̀" },
+ ["ḕ"]={ "ē", "̀" },
+ ["Ḗ"]={ "Ä’", "Ì" },
+ ["ḗ"]={ "Ä“", "Ì" },
+ ["Ḙ"]={ "E", "̭" },
+ ["ḙ"]={ "e", "̭" },
+ ["Ḛ"]={ "E", "̰" },
+ ["ḛ"]={ "e", "̰" },
+ ["Ḝ"]={ "Ȩ", "̆" },
+ ["á¸"]={ "È©", "̆" },
+ ["Ḟ"]={ "F", "̇" },
+ ["ḟ"]={ "f", "̇" },
+ ["Ḡ"]={ "G", "̄" },
+ ["ḡ"]={ "g", "̄" },
+ ["Ḣ"]={ "H", "̇" },
+ ["ḣ"]={ "h", "̇" },
+ ["Ḥ"]={ "H", "̣" },
+ ["ḥ"]={ "h", "̣" },
+ ["Ḧ"]={ "H", "̈" },
+ ["ḧ"]={ "h", "̈" },
+ ["Ḩ"]={ "H", "̧" },
+ ["ḩ"]={ "h", "̧" },
+ ["Ḫ"]={ "H", "̮" },
+ ["ḫ"]={ "h", "̮" },
+ ["Ḭ"]={ "I", "̰" },
+ ["ḭ"]={ "i", "̰" },
+ ["Ḯ"]={ "Ã", "Ì" },
+ ["ḯ"]={ "ï", "Ì" },
+ ["Ḱ"]={ "K", "Ì" },
+ ["ḱ"]={ "k", "Ì" },
+ ["Ḳ"]={ "K", "̣" },
+ ["ḳ"]={ "k", "̣" },
+ ["Ḵ"]={ "K", "̱" },
+ ["ḵ"]={ "k", "̱" },
+ ["Ḷ"]={ "L", "̣" },
+ ["ḷ"]={ "l", "̣" },
+ ["Ḹ"]={ "Ḷ", "̄" },
+ ["ḹ"]={ "ḷ", "̄" },
+ ["Ḻ"]={ "L", "̱" },
+ ["ḻ"]={ "l", "̱" },
+ ["Ḽ"]={ "L", "̭" },
+ ["ḽ"]={ "l", "̭" },
+ ["Ḿ"]={ "M", "Ì" },
+ ["ḿ"]={ "m", "Ì" },
+ ["Ṁ"]={ "M", "̇" },
+ ["á¹"]={ "m", "̇" },
+ ["Ṃ"]={ "M", "̣" },
+ ["ṃ"]={ "m", "̣" },
+ ["Ṅ"]={ "N", "̇" },
+ ["ṅ"]={ "n", "̇" },
+ ["Ṇ"]={ "N", "̣" },
+ ["ṇ"]={ "n", "̣" },
+ ["Ṉ"]={ "N", "̱" },
+ ["ṉ"]={ "n", "̱" },
+ ["Ṋ"]={ "N", "̭" },
+ ["ṋ"]={ "n", "̭" },
+ ["Ṍ"]={ "Õ", "Ì" },
+ ["á¹"]={ "õ", "Ì" },
+ ["Ṏ"]={ "Õ", "̈" },
+ ["á¹"]={ "õ", "̈" },
+ ["á¹"]={ "ÅŒ", "Ì€" },
+ ["ṑ"]={ "Å", "Ì€" },
+ ["á¹’"]={ "ÅŒ", "Ì" },
+ ["ṓ"]={ "Å", "Ì" },
+ ["á¹”"]={ "P", "Ì" },
+ ["ṕ"]={ "p", "Ì" },
+ ["Ṗ"]={ "P", "̇" },
+ ["ṗ"]={ "p", "̇" },
+ ["Ṙ"]={ "R", "̇" },
+ ["ṙ"]={ "r", "̇" },
+ ["Ṛ"]={ "R", "̣" },
+ ["á¹›"]={ "r", "Ì£" },
+ ["Ṝ"]={ "Ṛ", "̄" },
+ ["á¹"]={ "á¹›", "Ì„" },
+ ["Ṟ"]={ "R", "̱" },
+ ["ṟ"]={ "r", "̱" },
+ ["Ṡ"]={ "S", "̇" },
+ ["ṡ"]={ "s", "̇" },
+ ["á¹¢"]={ "S", "Ì£" },
+ ["á¹£"]={ "s", "Ì£" },
+ ["Ṥ"]={ "Ś", "̇" },
+ ["ṥ"]={ "ś", "̇" },
+ ["Ṧ"]={ "Š", "̇" },
+ ["ṧ"]={ "š", "̇" },
+ ["Ṩ"]={ "Ṣ", "̇" },
+ ["ṩ"]={ "ṣ", "̇" },
+ ["Ṫ"]={ "T", "̇" },
+ ["ṫ"]={ "t", "̇" },
+ ["Ṭ"]={ "T", "̣" },
+ ["á¹­"]={ "t", "Ì£" },
+ ["Ṯ"]={ "T", "̱" },
+ ["ṯ"]={ "t", "̱" },
+ ["á¹°"]={ "T", "Ì­" },
+ ["á¹±"]={ "t", "Ì­" },
+ ["Ṳ"]={ "U", "̤" },
+ ["ṳ"]={ "u", "̤" },
+ ["á¹´"]={ "U", "Ì°" },
+ ["á¹µ"]={ "u", "Ì°" },
+ ["Ṷ"]={ "U", "̭" },
+ ["á¹·"]={ "u", "Ì­" },
+ ["Ṹ"]={ "Ũ", "Ì" },
+ ["á¹¹"]={ "Å©", "Ì" },
+ ["Ṻ"]={ "Ū", "̈" },
+ ["ṻ"]={ "ū", "̈" },
+ ["Ṽ"]={ "V", "̃" },
+ ["ṽ"]={ "v", "̃" },
+ ["á¹¾"]={ "V", "Ì£" },
+ ["ṿ"]={ "v", "̣" },
+ ["Ẁ"]={ "W", "̀" },
+ ["áº"]={ "w", "Ì€" },
+ ["Ẃ"]={ "W", "Ì" },
+ ["ẃ"]={ "w", "Ì" },
+ ["Ẅ"]={ "W", "̈" },
+ ["ẅ"]={ "w", "̈" },
+ ["Ẇ"]={ "W", "̇" },
+ ["ẇ"]={ "w", "̇" },
+ ["Ẉ"]={ "W", "̣" },
+ ["ẉ"]={ "w", "̣" },
+ ["Ẋ"]={ "X", "̇" },
+ ["ẋ"]={ "x", "̇" },
+ ["Ẍ"]={ "X", "̈" },
+ ["áº"]={ "x", "̈" },
+ ["Ẏ"]={ "Y", "̇" },
+ ["áº"]={ "y", "̇" },
+ ["áº"]={ "Z", "Ì‚" },
+ ["ẑ"]={ "z", "̂" },
+ ["Ẓ"]={ "Z", "̣" },
+ ["ẓ"]={ "z", "̣" },
+ ["Ẕ"]={ "Z", "̱" },
+ ["ẕ"]={ "z", "̱" },
+ ["ẖ"]={ "h", "̱" },
+ ["ẗ"]={ "t", "̈" },
+ ["ẘ"]={ "w", "̊" },
+ ["ẙ"]={ "y", "̊" },
+ ["ẛ"]={ "ſ", "̇" },
+ ["Ạ"]={ "A", "̣" },
+ ["ạ"]={ "a", "̣" },
+ ["Ả"]={ "A", "̉" },
+ ["ả"]={ "a", "̉" },
+ ["Ấ"]={ "Â", "Ì" },
+ ["ấ"]={ "â", "Ì" },
+ ["Ầ"]={ "Â", "̀" },
+ ["ầ"]={ "â", "̀" },
+ ["Ẩ"]={ "Â", "̉" },
+ ["ẩ"]={ "â", "̉" },
+ ["Ẫ"]={ "Â", "̃" },
+ ["ẫ"]={ "â", "̃" },
+ ["Ậ"]={ "Ạ", "̂" },
+ ["ậ"]={ "ạ", "̂" },
+ ["Ắ"]={ "Ä‚", "Ì" },
+ ["ắ"]={ "ă", "Ì" },
+ ["Ằ"]={ "Ă", "̀" },
+ ["ằ"]={ "ă", "̀" },
+ ["Ẳ"]={ "Ă", "̉" },
+ ["ẳ"]={ "ă", "̉" },
+ ["Ẵ"]={ "Ă", "̃" },
+ ["ẵ"]={ "ă", "̃" },
+ ["Ặ"]={ "Ạ", "̆" },
+ ["ặ"]={ "ạ", "̆" },
+ ["Ẹ"]={ "E", "̣" },
+ ["ẹ"]={ "e", "̣" },
+ ["Ẻ"]={ "E", "̉" },
+ ["ẻ"]={ "e", "̉" },
+ ["Ẽ"]={ "E", "̃" },
+ ["ẽ"]={ "e", "̃" },
+ ["Ế"]={ "Ê", "Ì" },
+ ["ế"]={ "ê", "Ì" },
+ ["Ề"]={ "Ê", "̀" },
+ ["á»"]={ "ê", "Ì€" },
+ ["Ể"]={ "Ê", "̉" },
+ ["ể"]={ "ê", "̉" },
+ ["Ễ"]={ "Ê", "̃" },
+ ["ễ"]={ "ê", "̃" },
+ ["Ệ"]={ "Ẹ", "̂" },
+ ["ệ"]={ "ẹ", "̂" },
+ ["Ỉ"]={ "I", "̉" },
+ ["ỉ"]={ "i", "̉" },
+ ["Ị"]={ "I", "̣" },
+ ["ị"]={ "i", "̣" },
+ ["Ọ"]={ "O", "̣" },
+ ["á»"]={ "o", "Ì£" },
+ ["Ỏ"]={ "O", "̉" },
+ ["á»"]={ "o", "̉" },
+ ["á»"]={ "Ô", "Ì" },
+ ["ố"]={ "ô", "Ì" },
+ ["Ồ"]={ "Ô", "̀" },
+ ["ồ"]={ "ô", "̀" },
+ ["Ổ"]={ "Ô", "̉" },
+ ["ổ"]={ "ô", "̉" },
+ ["Ỗ"]={ "Ô", "̃" },
+ ["ỗ"]={ "ô", "̃" },
+ ["Ộ"]={ "Ọ", "̂" },
+ ["á»™"]={ "á»", "Ì‚" },
+ ["Ớ"]={ "Æ ", "Ì" },
+ ["á»›"]={ "Æ¡", "Ì" },
+ ["Ờ"]={ "Ơ", "̀" },
+ ["á»"]={ "Æ¡", "Ì€" },
+ ["Ở"]={ "Ơ", "̉" },
+ ["ở"]={ "ơ", "̉" },
+ ["Ỡ"]={ "Ơ", "̃" },
+ ["ỡ"]={ "ơ", "̃" },
+ ["Ợ"]={ "Ơ", "̣" },
+ ["ợ"]={ "ơ", "̣" },
+ ["Ụ"]={ "U", "̣" },
+ ["ụ"]={ "u", "̣" },
+ ["Ủ"]={ "U", "̉" },
+ ["ủ"]={ "u", "̉" },
+ ["Ứ"]={ "Ư", "Ì" },
+ ["ứ"]={ "Æ°", "Ì" },
+ ["Ừ"]={ "Ư", "̀" },
+ ["ừ"]={ "ư", "̀" },
+ ["Ử"]={ "Ư", "̉" },
+ ["ử"]={ "ư", "̉" },
+ ["Ữ"]={ "Ư", "̃" },
+ ["ữ"]={ "ư", "̃" },
+ ["Ự"]={ "Ư", "̣" },
+ ["á»±"]={ "Æ°", "Ì£" },
+ ["Ỳ"]={ "Y", "̀" },
+ ["ỳ"]={ "y", "̀" },
+ ["á»´"]={ "Y", "Ì£" },
+ ["ỵ"]={ "y", "̣" },
+ ["Ỷ"]={ "Y", "̉" },
+ ["ỷ"]={ "y", "̉" },
+ ["Ỹ"]={ "Y", "̃" },
+ ["ỹ"]={ "y", "̃" },
+ ["ἀ"]={ "α", "̓" },
+ ["á¼"]={ "α", "Ì”" },
+ ["ἂ"]={ "ἀ", "̀" },
+ ["ἃ"]={ "á¼", "Ì€" },
+ ["ἄ"]={ "á¼€", "Ì" },
+ ["á¼…"]={ "á¼", "Ì" },
+ ["ἆ"]={ "ἀ", "͂" },
+ ["ἇ"]={ "á¼", "Í‚" },
+ ["Ἀ"]={ "Α", "̓" },
+ ["Ἁ"]={ "Α", "̔" },
+ ["Ἂ"]={ "Ἀ", "̀" },
+ ["Ἃ"]={ "Ἁ", "̀" },
+ ["Ἄ"]={ "Ἀ", "Ì" },
+ ["á¼"]={ "Ἁ", "Ì" },
+ ["Ἆ"]={ "Ἀ", "͂" },
+ ["á¼"]={ "Ἁ", "Í‚" },
+ ["á¼"]={ "ε", "Ì“" },
+ ["ἑ"]={ "ε", "̔" },
+ ["á¼’"]={ "á¼", "Ì€" },
+ ["ἓ"]={ "ἑ", "̀" },
+ ["á¼”"]={ "á¼", "Ì" },
+ ["ἕ"]={ "ἑ", "Ì" },
+ ["Ἐ"]={ "Ε", "̓" },
+ ["Ἑ"]={ "Ε", "̔" },
+ ["Ἒ"]={ "Ἐ", "̀" },
+ ["á¼›"]={ "á¼™", "Ì€" },
+ ["Ἔ"]={ "Ἐ", "Ì" },
+ ["á¼"]={ "á¼™", "Ì" },
+ ["ἠ"]={ "η", "̓" },
+ ["ἡ"]={ "η", "̔" },
+ ["á¼¢"]={ "á¼ ", "Ì€" },
+ ["ἣ"]={ "ἡ", "̀" },
+ ["ἤ"]={ "á¼ ", "Ì" },
+ ["á¼¥"]={ "ἡ", "Ì" },
+ ["ἦ"]={ "ἠ", "͂" },
+ ["ἧ"]={ "ἡ", "͂" },
+ ["Ἠ"]={ "Η", "̓" },
+ ["Ἡ"]={ "Η", "̔" },
+ ["Ἢ"]={ "Ἠ", "̀" },
+ ["Ἣ"]={ "Ἡ", "̀" },
+ ["Ἤ"]={ "Ἠ", "Ì" },
+ ["á¼­"]={ "Ἡ", "Ì" },
+ ["Ἦ"]={ "Ἠ", "͂" },
+ ["Ἧ"]={ "Ἡ", "͂" },
+ ["ἰ"]={ "ι", "̓" },
+ ["ἱ"]={ "ι", "̔" },
+ ["á¼²"]={ "á¼°", "Ì€" },
+ ["á¼³"]={ "á¼±", "Ì€" },
+ ["á¼´"]={ "á¼°", "Ì" },
+ ["á¼µ"]={ "á¼±", "Ì" },
+ ["ἶ"]={ "ἰ", "͂" },
+ ["á¼·"]={ "á¼±", "Í‚" },
+ ["Ἰ"]={ "Ι", "̓" },
+ ["Ἱ"]={ "Ι", "̔" },
+ ["Ἲ"]={ "Ἰ", "̀" },
+ ["á¼»"]={ "á¼¹", "Ì€" },
+ ["á¼¼"]={ "Ἰ", "Ì" },
+ ["á¼½"]={ "á¼¹", "Ì" },
+ ["Ἶ"]={ "Ἰ", "͂" },
+ ["Ἷ"]={ "Ἱ", "͂" },
+ ["ὀ"]={ "ο", "̓" },
+ ["á½"]={ "ο", "Ì”" },
+ ["ὂ"]={ "ὀ", "̀" },
+ ["ὃ"]={ "á½", "Ì€" },
+ ["ὄ"]={ "á½€", "Ì" },
+ ["á½…"]={ "á½", "Ì" },
+ ["Ὀ"]={ "Ο", "̓" },
+ ["Ὁ"]={ "Ο", "̔" },
+ ["Ὂ"]={ "Ὀ", "̀" },
+ ["Ὃ"]={ "Ὁ", "̀" },
+ ["Ὄ"]={ "Ὀ", "Ì" },
+ ["á½"]={ "Ὁ", "Ì" },
+ ["á½"]={ "Ï…", "Ì“" },
+ ["ὑ"]={ "υ", "̔" },
+ ["á½’"]={ "á½", "Ì€" },
+ ["ὓ"]={ "ὑ", "̀" },
+ ["á½”"]={ "á½", "Ì" },
+ ["ὕ"]={ "ὑ", "Ì" },
+ ["á½–"]={ "á½", "Í‚" },
+ ["ὗ"]={ "ὑ", "͂" },
+ ["á½™"]={ "Î¥", "Ì”" },
+ ["á½›"]={ "á½™", "Ì€" },
+ ["á½"]={ "á½™", "Ì" },
+ ["Ὗ"]={ "Ὑ", "͂" },
+ ["ὠ"]={ "ω", "̓" },
+ ["ὡ"]={ "ω", "̔" },
+ ["á½¢"]={ "á½ ", "Ì€" },
+ ["ὣ"]={ "ὡ", "̀" },
+ ["ὤ"]={ "á½ ", "Ì" },
+ ["á½¥"]={ "ὡ", "Ì" },
+ ["ὦ"]={ "ὠ", "͂" },
+ ["ὧ"]={ "ὡ", "͂" },
+ ["Ὠ"]={ "Ω", "̓" },
+ ["Ὡ"]={ "Ω", "̔" },
+ ["Ὢ"]={ "Ὠ", "̀" },
+ ["Ὣ"]={ "Ὡ", "̀" },
+ ["Ὤ"]={ "Ὠ", "Ì" },
+ ["á½­"]={ "Ὡ", "Ì" },
+ ["Ὦ"]={ "Ὠ", "͂" },
+ ["Ὧ"]={ "Ὡ", "͂" },
+ ["ὰ"]={ "α", "̀" },
+ ["ὲ"]={ "ε", "̀" },
+ ["ὴ"]={ "η", "̀" },
+ ["ὶ"]={ "ι", "̀" },
+ ["ὸ"]={ "ο", "̀" },
+ ["ὺ"]={ "υ", "̀" },
+ ["ὼ"]={ "ω", "̀" },
+ ["á¾€"]={ "á¼€", "Í…" },
+ ["á¾"]={ "á¼", "Í…" },
+ ["ᾂ"]={ "ἂ", "ͅ" },
+ ["ᾃ"]={ "ἃ", "ͅ" },
+ ["ᾄ"]={ "ἄ", "ͅ" },
+ ["á¾…"]={ "á¼…", "Í…" },
+ ["ᾆ"]={ "ἆ", "ͅ" },
+ ["ᾇ"]={ "ἇ", "ͅ" },
+ ["ᾈ"]={ "Ἀ", "ͅ" },
+ ["ᾉ"]={ "Ἁ", "ͅ" },
+ ["ᾊ"]={ "Ἂ", "ͅ" },
+ ["ᾋ"]={ "Ἃ", "ͅ" },
+ ["ᾌ"]={ "Ἄ", "ͅ" },
+ ["á¾"]={ "á¼", "Í…" },
+ ["ᾎ"]={ "Ἆ", "ͅ" },
+ ["á¾"]={ "á¼", "Í…" },
+ ["á¾"]={ "á¼ ", "Í…" },
+ ["ᾑ"]={ "ἡ", "ͅ" },
+ ["á¾’"]={ "á¼¢", "Í…" },
+ ["ᾓ"]={ "ἣ", "ͅ" },
+ ["ᾔ"]={ "ἤ", "ͅ" },
+ ["ᾕ"]={ "ἥ", "ͅ" },
+ ["ᾖ"]={ "ἦ", "ͅ" },
+ ["ᾗ"]={ "ἧ", "ͅ" },
+ ["ᾘ"]={ "Ἠ", "ͅ" },
+ ["ᾙ"]={ "Ἡ", "ͅ" },
+ ["ᾚ"]={ "Ἢ", "ͅ" },
+ ["ᾛ"]={ "Ἣ", "ͅ" },
+ ["ᾜ"]={ "Ἤ", "ͅ" },
+ ["á¾"]={ "á¼­", "Í…" },
+ ["ᾞ"]={ "Ἦ", "ͅ" },
+ ["ᾟ"]={ "Ἧ", "ͅ" },
+ ["á¾ "]={ "á½ ", "Í…" },
+ ["ᾡ"]={ "ὡ", "ͅ" },
+ ["á¾¢"]={ "á½¢", "Í…" },
+ ["á¾£"]={ "á½£", "Í…" },
+ ["ᾤ"]={ "ὤ", "ͅ" },
+ ["á¾¥"]={ "á½¥", "Í…" },
+ ["ᾦ"]={ "ὦ", "ͅ" },
+ ["ᾧ"]={ "ὧ", "ͅ" },
+ ["ᾨ"]={ "Ὠ", "ͅ" },
+ ["ᾩ"]={ "Ὡ", "ͅ" },
+ ["ᾪ"]={ "Ὢ", "ͅ" },
+ ["ᾫ"]={ "Ὣ", "ͅ" },
+ ["ᾬ"]={ "Ὤ", "ͅ" },
+ ["á¾­"]={ "á½­", "Í…" },
+ ["á¾®"]={ "á½®", "Í…" },
+ ["ᾯ"]={ "Ὧ", "ͅ" },
+ ["ᾰ"]={ "α", "̆" },
+ ["ᾱ"]={ "α", "̄" },
+ ["á¾²"]={ "á½°", "Í…" },
+ ["ᾳ"]={ "α", "ͅ" },
+ ["ᾴ"]={ "ά", "ͅ" },
+ ["ᾶ"]={ "α", "͂" },
+ ["ᾷ"]={ "ᾶ", "ͅ" },
+ ["Ᾰ"]={ "Α", "̆" },
+ ["Ᾱ"]={ "Α", "̄" },
+ ["Ὰ"]={ "Α", "̀" },
+ ["ᾼ"]={ "Α", "ͅ" },
+ ["á¿"]={ "¨", "Í‚" },
+ ["á¿‚"]={ "á½´", "Í…" },
+ ["ῃ"]={ "η", "ͅ" },
+ ["ῄ"]={ "ή", "ͅ" },
+ ["ῆ"]={ "η", "͂" },
+ ["ῇ"]={ "ῆ", "ͅ" },
+ ["Ὲ"]={ "Ε", "̀" },
+ ["Ὴ"]={ "Η", "̀" },
+ ["ῌ"]={ "Η", "ͅ" },
+ ["á¿"]={ "᾿", "Ì€" },
+ ["á¿Ž"]={ "᾿", "Ì" },
+ ["á¿"]={ "᾿", "Í‚" },
+ ["á¿"]={ "ι", "̆" },
+ ["ῑ"]={ "ι", "̄" },
+ ["á¿’"]={ "ÏŠ", "Ì€" },
+ ["ῖ"]={ "ι", "͂" },
+ ["á¿—"]={ "ÏŠ", "Í‚" },
+ ["Ῐ"]={ "Ι", "̆" },
+ ["Ῑ"]={ "Ι", "̄" },
+ ["Ὶ"]={ "Ι", "̀" },
+ ["á¿"]={ "῾", "Ì€" },
+ ["á¿ž"]={ "῾", "Ì" },
+ ["῟"]={ "῾", "͂" },
+ ["ῠ"]={ "υ", "̆" },
+ ["á¿¡"]={ "Ï…", "Ì„" },
+ ["á¿¢"]={ "Ï‹", "Ì€" },
+ ["ῤ"]={ "Ï", "Ì“" },
+ ["á¿¥"]={ "Ï", "Ì”" },
+ ["ῦ"]={ "υ", "͂" },
+ ["ῧ"]={ "ϋ", "͂" },
+ ["Ῠ"]={ "Υ", "̆" },
+ ["á¿©"]={ "Î¥", "Ì„" },
+ ["Ὺ"]={ "Υ", "̀" },
+ ["Ῥ"]={ "Ρ", "̔" },
+ ["῭"]={ "¨", "̀" },
+ ["ῲ"]={ "ὼ", "ͅ" },
+ ["ῳ"]={ "ω", "ͅ" },
+ ["á¿´"]={ "ÏŽ", "Í…" },
+ ["ῶ"]={ "ω", "͂" },
+ ["ῷ"]={ "ῶ", "ͅ" },
+ ["Ὸ"]={ "Ο", "̀" },
+ ["Ὼ"]={ "Ω", "̀" },
+ ["ῼ"]={ "Ω", "ͅ" },
+ ["↚"]={ "â†", "̸" },
+ ["↛"]={ "→", "̸" },
+ ["↮"]={ "↔", "̸" },
+ ["â‡"]={ "â‡", "̸" },
+ ["⇎"]={ "⇔", "̸" },
+ ["â‡"]={ "⇒", "̸" },
+ ["∄"]={ "∃", "̸" },
+ ["∉"]={ "∈", "̸" },
+ ["∌"]={ "∋", "̸" },
+ ["∤"]={ "∣", "̸" },
+ ["∦"]={ "∥", "̸" },
+ ["â‰"]={ "∼", "̸" },
+ ["≄"]={ "≃", "̸" },
+ ["≇"]={ "≅", "̸" },
+ ["≉"]={ "≈", "̸" },
+ ["≠"]={ "=", "̸" },
+ ["≢"]={ "≡", "̸" },
+ ["≭"]={ "â‰", "̸" },
+ ["≮"]={ "<", "̸" },
+ ["≯"]={ ">", "̸" },
+ ["≰"]={ "≤", "̸" },
+ ["≱"]={ "≥", "̸" },
+ ["≴"]={ "≲", "̸" },
+ ["≵"]={ "≳", "̸" },
+ ["≸"]={ "≶", "̸" },
+ ["≹"]={ "≷", "̸" },
+ ["⊀"]={ "≺", "̸" },
+ ["âŠ"]={ "≻", "̸" },
+ ["⊄"]={ "⊂", "̸" },
+ ["⊅"]={ "⊃", "̸" },
+ ["⊈"]={ "⊆", "̸" },
+ ["⊉"]={ "⊇", "̸" },
+ ["⊬"]={ "⊢", "̸" },
+ ["⊭"]={ "⊨", "̸" },
+ ["⊮"]={ "⊩", "̸" },
+ ["⊯"]={ "⊫", "̸" },
+ ["⋠"]={ "≼", "̸" },
+ ["⋡"]={ "≽", "̸" },
+ ["⋢"]={ "⊑", "̸" },
+ ["⋣"]={ "⊒", "̸" },
+ ["⋪"]={ "⊲", "̸" },
+ ["⋫"]={ "⊳", "̸" },
+ ["⋬"]={ "⊴", "̸" },
+ ["⋭"]={ "⊵", "̸" },
+ ["â«œ"]={ "â«", "̸" },
+ ["ãŒ"]={ "ã‹", "ã‚™" },
+ ["ãŽ"]={ "ã", "ã‚™" },
+ ["ã"]={ "ã", "ã‚™" },
+ ["ã’"]={ "ã‘", "ã‚™" },
+ ["ã”"]={ "ã“", "ã‚™" },
+ ["ã–"]={ "ã•", "ã‚™" },
+ ["ã˜"]={ "ã—", "ã‚™" },
+ ["ãš"]={ "ã™", "ã‚™" },
+ ["ãœ"]={ "ã›", "ã‚™" },
+ ["ãž"]={ "ã", "ã‚™" },
+ ["ã "]={ "ãŸ", "ã‚™" },
+ ["ã¢"]={ "ã¡", "ã‚™" },
+ ["ã¥"]={ "ã¤", "ã‚™" },
+ ["ã§"]={ "ã¦", "ã‚™" },
+ ["ã©"]={ "ã¨", "ã‚™" },
+ ["ã°"]={ "ã¯", "ã‚™" },
+ ["ã±"]={ "ã¯", "ã‚š" },
+ ["ã³"]={ "ã²", "ã‚™" },
+ ["ã´"]={ "ã²", "ã‚š" },
+ ["ã¶"]={ "ãµ", "ã‚™" },
+ ["ã·"]={ "ãµ", "ã‚š" },
+ ["ã¹"]={ "ã¸", "ã‚™" },
+ ["ãº"]={ "ã¸", "ã‚š" },
+ ["ã¼"]={ "ã»", "ã‚™" },
+ ["ã½"]={ "ã»", "ã‚š" },
+ ["ã‚”"]={ "ã†", "ã‚™" },
+ ["ã‚ž"]={ "ã‚", "ã‚™" },
+ ["ガ"]={ "カ", "゙" },
+ ["ã‚®"]={ "ã‚­", "ã‚™" },
+ ["グ"]={ "ク", "゙" },
+ ["ゲ"]={ "ケ", "゙" },
+ ["ゴ"]={ "コ", "゙" },
+ ["ザ"]={ "サ", "゙" },
+ ["ジ"]={ "シ", "゙" },
+ ["ズ"]={ "ス", "゙" },
+ ["ゼ"]={ "セ", "゙" },
+ ["ゾ"]={ "ソ", "゙" },
+ ["ダ"]={ "タ", "゙" },
+ ["ヂ"]={ "ãƒ", "ã‚™" },
+ ["ヅ"]={ "ツ", "゙" },
+ ["デ"]={ "テ", "゙" },
+ ["ド"]={ "ト", "゙" },
+ ["ãƒ"]={ "ãƒ", "ã‚™" },
+ ["パ"]={ "ãƒ", "ã‚š" },
+ ["ビ"]={ "ヒ", "゙" },
+ ["ピ"]={ "ヒ", "゚" },
+ ["ブ"]={ "フ", "゙" },
+ ["プ"]={ "フ", "゚" },
+ ["ベ"]={ "ヘ", "゙" },
+ ["ペ"]={ "ヘ", "゚" },
+ ["ボ"]={ "ホ", "゙" },
+ ["ãƒ"]={ "ホ", "ã‚š" },
+ ["ヴ"]={ "ウ", "゙" },
+ ["ヷ"]={ "ワ", "゙" },
+ ["ヸ"]={ "ヰ", "゙" },
+ ["ヹ"]={ "ヱ", "゙" },
+ ["ヺ"]={ "ヲ", "゙" },
+ ["ヾ"]={ "ヽ", "゙" },
+ ["ï¬"]={ "×™", "Ö´" },
+ ["ײַ"]={ "ײ", "ַ" },
+ ["שׁ"]={ "ש", "×" },
+ ["שׂ"]={ "ש", "ׂ" },
+ ["שּׁ"]={ "ï­‰", "×" },
+ ["שּׂ"]={ "שּ", "ׂ" },
+ ["אַ"]={ "×", "Ö·" },
+ ["אָ"]={ "×", "Ö¸" },
+ ["אּ"]={ "×", "Ö¼" },
+ ["בּ"]={ "ב", "ּ" },
+ ["גּ"]={ "ג", "ּ" },
+ ["דּ"]={ "ד", "ּ" },
+ ["הּ"]={ "ה", "ּ" },
+ ["וּ"]={ "ו", "ּ" },
+ ["זּ"]={ "ז", "ּ" },
+ ["טּ"]={ "ט", "ּ" },
+ ["יּ"]={ "י", "ּ" },
+ ["ךּ"]={ "ך", "ּ" },
+ ["כּ"]={ "כ", "ּ" },
+ ["לּ"]={ "ל", "ּ" },
+ ["מּ"]={ "מ", "ּ" },
+ ["ï­€"]={ "× ", "Ö¼" },
+ ["ï­"]={ "ס", "Ö¼" },
+ ["ï­ƒ"]={ "×£", "Ö¼" },
+ ["פּ"]={ "פ", "ּ" },
+ ["צּ"]={ "צ", "ּ" },
+ ["קּ"]={ "ק", "ּ" },
+ ["רּ"]={ "ר", "ּ" },
+ ["שּ"]={ "ש", "ּ" },
+ ["תּ"]={ "ת", "ּ" },
+ ["וֹ"]={ "ו", "ֹ" },
+ ["בֿ"]={ "ב", "ֿ" },
+ ["ï­"]={ "×›", "Ö¿" },
+ ["פֿ"]={ "פ", "ֿ" },
+ ["𑂚"]={ "𑂙", "𑂺" },
+ ["𑂜"]={ "𑂛", "𑂺" },
+ ["𑂫"]={ "𑂥", "𑂺" },
+ ["𑄮"]={ "𑄱", "𑄧" },
+ ["𑄯"]={ "𑄲", "𑄧" },
+ ["ð‘‹"]={ "ð‘‡", "𑌾" },
+ ["ð‘Œ"]={ "ð‘‡", "ð‘—" },
+ ["ð‘’»"]={ "ð‘’¹", "ð‘’º" },
+ ["ð‘’¼"]={ "ð‘’¹", "ð‘’°" },
+ ["ð‘’¾"]={ "ð‘’¹", "ð‘’½" },
+ ["ð‘–º"]={ "ð‘–¸", "ð‘–¯" },
+ ["ð‘–»"]={ "ð‘–¹", "ð‘–¯" },
+ ["ð…ž"]={ "ð…—", "ð…¥" },
+ ["ð…Ÿ"]={ "ð…˜", "ð…¥" },
+ ["ð… "]={ "ð…Ÿ", "ð…®" },
+ ["ð…¡"]={ "ð…Ÿ", "ð…¯" },
+ ["ð…¢"]={ "ð…Ÿ", "ð…°" },
+ ["ð…£"]={ "ð…Ÿ", "ð…±" },
+ ["ð…¤"]={ "ð…Ÿ", "ð…²" },
+ ["ð†»"]={ "ð†¹", "ð…¥" },
+ ["ð†¼"]={ "ð†º", "ð…¥" },
+ ["ð†½"]={ "ð†»", "ð…®" },
+ ["ð†¾"]={ "ð†¼", "ð…®" },
+ ["ð†¿"]={ "ð†»", "ð…¯" },
+ ["ð‡€"]={ "ð†¼", "ð…¯" },
+ },
+ },
+ },
+ ["name"]="collapse",
+ ["prepend"]=true,
+ ["type"]="ligature",
+}
diff --git a/macros/luatex/generic/luaotfload/fontloader-fonts-mis.lua b/macros/luatex/generic/luaotfload/fontloader-fonts-mis.lua
new file mode 100644
index 0000000000..b472b86dda
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-fonts-mis.lua
@@ -0,0 +1,35 @@
+if not modules then modules = { } end modules ['luatex-font-mis'] = {
+ version = 1.001,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+if context then
+ os.exit()
+end
+
+local currentfont = font.current
+
+local hashes = fonts.hashes
+local identifiers = hashes.identifiers or { }
+local marks = hashes.marks or { }
+
+hashes.identifiers = identifiers
+hashes.marks = marks
+
+table.setmetatableindex(marks,function(t,k)
+ if k == true then
+ return marks[currentfont()]
+ else
+ local resources = identifiers[k].resources or { }
+ local marks = resources.marks or { }
+ t[k] = marks
+ return marks
+ end
+end)
+
+function font.each()
+ return table.sortedhash(fonts.hashes.identifiers)
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-fonts-syn.lua b/macros/luatex/generic/luaotfload/fontloader-fonts-syn.lua
new file mode 100644
index 0000000000..2ec075434f
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-fonts-syn.lua
@@ -0,0 +1,104 @@
+if not modules then modules = { } end modules ['luatex-fonts-syn'] = {
+ version = 1.001,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+if context then
+ os.exit()
+end
+
+-- Generic font names support.
+--
+-- Watch out, the version number is the same as the one used in
+-- the mtx-fonts.lua function scripts.fonts.names as we use a
+-- simplified font database in the plain solution and by using
+-- a different number we're less dependent on context.
+--
+-- mtxrun --script font --reload --simple
+--
+-- The format of the file is as follows:
+--
+-- return {
+-- ["version"] = 1.001,
+-- ["cache_version"] = 1.001,
+-- ["mappings"] = {
+-- ["somettcfontone"] = { "Some TTC Font One", "SomeFontA.ttc", 1 },
+-- ["somettcfonttwo"] = { "Some TTC Font Two", "SomeFontA.ttc", 2 },
+-- ["somettffont"] = { "Some TTF Font", "SomeFontB.ttf" },
+-- ["someotffont"] = { "Some OTF Font", "SomeFontC.otf" },
+-- },
+-- }
+
+local fonts = fonts
+fonts.names = fonts.names or { }
+
+fonts.names.version = 1.001 -- not the same as in context but matches mtx-fonts --simple
+fonts.names.basename = "luatex-fonts-names"
+fonts.names.cache = containers.define("fonts","data",fonts.names.version,true)
+
+local data = nil
+local loaded = false
+
+local fileformats = { "lua", "tex", "other text files" }
+
+function fonts.names.reportmissingbase()
+ logs.report("fonts","missing font database, run: mtxrun --script fonts --reload --simple")
+ fonts.names.reportmissingbase = nil
+end
+
+function fonts.names.reportmissingname()
+ logs.report("fonts","unknown font in font database, run: mtxrun --script fonts --reload --simple")
+ fonts.names.reportmissingname = nil
+end
+
+function fonts.names.resolve(name,sub)
+ if not loaded then
+ local basename = fonts.names.basename
+ if basename and basename ~= "" then
+ data = containers.read(fonts.names.cache,basename)
+ if not data then
+ basename = file.addsuffix(basename,"lua")
+ for i=1,#fileformats do
+ local format = fileformats[i]
+ local foundname = resolvers.findfile(basename,format) or ""
+ if foundname ~= "" then
+ data = dofile(foundname)
+ logs.report("fonts","font database '%s' loaded",foundname)
+ break
+ end
+ end
+ end
+ end
+ loaded = true
+ end
+ if type(data) == "table" and data.version == fonts.names.version then
+ local condensed = string.gsub(string.lower(name),"[^%a%d]","")
+ local found = data.mappings and data.mappings[condensed]
+ if found then
+ local fontname, filename, subfont = found[1], found[2], found[3]
+ if subfont then
+ return filename, fontname
+ else
+ return filename, false
+ end
+ elseif fonts.names.reportmissingname then
+ fonts.names.reportmissingname()
+ return name, false -- fallback to filename
+ end
+ elseif fonts.names.reportmissingbase then
+ fonts.names.reportmissingbase()
+ end
+end
+
+fonts.names.resolvespec = fonts.names.resolve -- only supported in mkiv
+
+function fonts.names.getfilename(askedname,suffix) -- only supported in mkiv
+ return ""
+end
+
+function fonts.names.ignoredfile(filename) -- only supported in mkiv
+ return false -- will be overloaded
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-fonts-tfm.lua b/macros/luatex/generic/luaotfload/fontloader-fonts-tfm.lua
new file mode 100644
index 0000000000..0b6e09a8f9
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-fonts-tfm.lua
@@ -0,0 +1,654 @@
+if not modules then modules = { } end modules ['luatex-fonts-tfm'] = {
+ version = 1.001,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This is the generic tfm/vf loader. There are no fundamental differences with
+-- the one used in ConTeXt but we save some byte(codes) this way.
+
+local next, type = next, type
+local match, format = string.match, string.format
+local concat, sortedhash = table.concat, table.sortedhash
+local idiv = number.idiv
+
+local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+local trace_features = false trackers.register("tfm.features", function(v) trace_features = v end)
+
+local report_defining = logs.reporter("fonts","defining")
+local report_tfm = logs.reporter("fonts","tfm loading")
+
+local findbinfile = resolvers.findbinfile
+local setmetatableindex = table.setmetatableindex
+
+local fonts = fonts
+local handlers = fonts.handlers
+local helpers = fonts.helpers
+local readers = fonts.readers
+local constructors = fonts.constructors
+local encodings = fonts.encodings
+
+local tfm = constructors.handlers.tfm
+tfm.version = 1.000
+tfm.maxnestingdepth = 5
+tfm.maxnestingsize = 65536*1024
+
+local otf = fonts.handlers.otf
+local otfenhancers = otf.enhancers
+
+local tfmfeatures = constructors.features.tfm
+local registertfmfeature = tfmfeatures.register
+
+local tfmenhancers = constructors.enhancers.tfm
+local registertfmenhancer = tfmenhancers.register
+
+local charcommand = helpers.commands.char
+
+constructors.resolvevirtualtoo = false -- wil be set in font-ctx.lua
+
+fonts.formats.tfm = "type1" -- we need to have at least a value here
+fonts.formats.ofm = "type1" -- we need to have at least a value here
+
+function tfm.setfeatures(tfmdata,features)
+ local okay = constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm)
+ if okay then
+ return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm)
+ else
+ return { } -- will become false
+ end
+end
+
+local depth = { } -- table.setmetatableindex("number")
+
+local loadtfm = font.read_tfm
+local loadvf = font.read_vf
+
+local function read_from_tfm(specification)
+ local filename = specification.filename
+ local size = specification.size
+ depth[filename] = (depth[filename] or 0) + 1
+ if trace_defining then
+ report_defining("loading tfm file %a at size %s",filename,size)
+ end
+ local tfmdata = loadtfm(filename,size)
+ if tfmdata then
+
+ local features = specification.features and specification.features.normal or { }
+ local features = constructors.checkedfeatures("tfm",features)
+ specification.features.normal = features
+
+ -- If reencode returns a new table, we assume that we're doing something
+ -- special. An 'auto' reencode picks up its vector from the pfb file.
+
+ local newtfmdata = (depth[filename] == 1) and tfm.reencode(tfmdata,specification)
+ if newtfmdata then
+ tfmdata = newtfmdata
+ end
+
+ local resources = tfmdata.resources or { }
+ local properties = tfmdata.properties or { }
+ local parameters = tfmdata.parameters or { }
+ local shared = tfmdata.shared or { }
+ --
+ shared.features = features
+ shared.resources = resources
+ --
+ properties.name = tfmdata.name -- todo: fallback
+ properties.fontname = tfmdata.fontname -- todo: fallback
+ properties.psname = tfmdata.psname -- todo: fallback
+ properties.fullname = tfmdata.fullname -- todo: fallback
+ properties.filename = specification.filename -- todo: fallback
+ properties.format = tfmdata.format or fonts.formats.tfm -- better than nothing
+ properties.usedbitmap = tfmdata.usedbitmap
+ --
+ tfmdata.properties = properties
+ tfmdata.resources = resources
+ tfmdata.parameters = parameters
+ tfmdata.shared = shared
+ --
+ shared.rawdata = { resources = resources }
+ shared.features = features
+ --
+ -- The next branch is only entered when we have a proper encoded file i.e.
+ -- unicodes and such. It really nakes no sense to do feature juggling when
+ -- we have no names and unicodes.
+ --
+ if newtfmdata then
+ --
+ -- Some opentype processing assumes these to be present:
+ --
+ if not resources.marks then
+ resources.marks = { }
+ end
+ if not resources.sequences then
+ resources.sequences = { }
+ end
+ if not resources.features then
+ resources.features = {
+ gsub = { },
+ gpos = { },
+ }
+ end
+ if not tfmdata.changed then
+ tfmdata.changed = { }
+ end
+ if not tfmdata.descriptions then
+ tfmdata.descriptions = tfmdata.characters
+ end
+ --
+ -- It might be handy to have this:
+ --
+ otf.readers.addunicodetable(tfmdata)
+ --
+ -- We make a pseudo opentype font, e.g. kerns and ligatures etc:
+ --
+ tfmenhancers.apply(tfmdata,filename)
+ --
+ -- Now user stuff can kick in.
+ --
+ constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm)
+ --
+ -- As that can also mess with names and such, we are now ready for finalizing
+ -- the unicode information. This is a different order that for instance type one
+ -- (afm) files. First we try to deduce unicodes from already present information.
+ --
+ otf.readers.unifymissing(tfmdata)
+ --
+ -- Next we fill in the gaps, based on names from teh agl. Probably not much will
+ -- happen here.
+ --
+ fonts.mappings.addtounicode(tfmdata,filename)
+ --
+ -- The tounicode data is passed to the backend that constructs the vectors for us.
+ --
+ tfmdata.tounicode = 1
+ local tounicode = fonts.mappings.tounicode
+ for unicode, v in next, tfmdata.characters do
+ local u = v.unicode
+ if u then
+ v.tounicode = tounicode(u)
+ end
+ end
+ --
+ -- However, when we use a bitmap font those vectors can't be constructed because
+ -- that information is not carried with those fonts (there is no name info, nor
+ -- proper index info, nor unicodes at that end). So, we provide it ourselves.
+ --
+ if tfmdata.usedbitmap then
+ tfm.addtounicode(tfmdata)
+ end
+ end
+ --
+ shared.processes = next(features) and tfm.setfeatures(tfmdata,features) or nil
+ --
+ if size < 0 then
+ size = idiv(65536 * -size,100)
+ end
+ parameters.factor = 1 -- already scaled
+ parameters.units = 1000 -- just in case
+ parameters.size = size
+ parameters.slant = parameters.slant or parameters[1] or 0
+ parameters.space = parameters.space or parameters[2] or 0
+ parameters.space_stretch = parameters.space_stretch or parameters[3] or 0
+ parameters.space_shrink = parameters.space_shrink or parameters[4] or 0
+ parameters.x_height = parameters.x_height or parameters[5] or 0
+ parameters.quad = parameters.quad or parameters[6] or 0
+ parameters.extra_space = parameters.extra_space or parameters[7] or 0
+ --
+ constructors.enhanceparameters(parameters) -- official copies for us
+ --
+ properties.private = properties.private or tfmdata.private or privateoffset
+ --
+ if newtfmdata then
+ --
+ -- We do nothing as we assume flat tfm files. It would become real messy
+ -- otherwise and I don't have something for testing on my system anyway.
+ --
+ elseif constructors.resolvevirtualtoo then
+ fonts.loggers.register(tfmdata,file.suffix(filename),specification) -- strange, why here
+ local vfname = findbinfile(specification.name, 'ovf')
+ if vfname and vfname ~= "" then
+ local vfdata = loadvf(vfname,size)
+ if vfdata then
+ local chars = tfmdata.characters
+ for k,v in next, vfdata.characters do
+ chars[k].commands = v.commands
+ end
+ properties.virtualized = true
+ tfmdata.fonts = vfdata.fonts
+ tfmdata.type = "virtual" -- else nested calls with cummulative scaling
+ local fontlist = vfdata.fonts
+ local name = file.nameonly(filename)
+ for i=1,#fontlist do
+ local n = fontlist[i].name
+ local s = fontlist[i].size
+ local d = depth[filename]
+ s = constructors.scaled(s,vfdata.designsize)
+ if d > tfm.maxnestingdepth then
+ report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth)
+ fontlist[i] = { id = 0 }
+ elseif (d > 1) and (s > tfm.maxnestingsize) then
+ report_defining("virtual font %a exceeds size %s",n,s)
+ fontlist[i] = { id = 0 }
+ else
+ local t, id = constructors.readanddefine(n,s)
+ fontlist[i] = { id = id }
+ end
+ end
+ end
+ end
+ end
+ --
+ properties.haskerns = true
+ properties.hasligatures = true
+ properties.hasitalics = true
+ resources.unicodes = { }
+ resources.lookuptags = { }
+ --
+ depth[filename] = depth[filename] - 1
+ --
+ return tfmdata
+ else
+ depth[filename] = depth[filename] - 1
+ end
+end
+
+local function check_tfm(specification,fullname) -- we could split up like afm/otf
+ local foundname = findbinfile(fullname, 'tfm') or ""
+ if foundname == "" then
+ foundname = findbinfile(fullname, 'ofm') or "" -- not needed in context
+ end
+ if foundname == "" then
+ foundname = fonts.names.getfilename(fullname,"tfm") or ""
+ end
+ if foundname ~= "" then
+ specification.filename = foundname
+ specification.format = "ofm"
+ return read_from_tfm(specification)
+ elseif trace_defining then
+ report_defining("loading tfm with name %a fails",specification.name)
+ end
+end
+
+readers.check_tfm = check_tfm
+
+function readers.tfm(specification)
+ local fullname = specification.filename or ""
+ if fullname == "" then
+ local forced = specification.forced or ""
+ if forced ~= "" then
+ fullname = specification.name .. "." .. forced
+ else
+ fullname = specification.name
+ end
+ end
+ return check_tfm(specification,fullname)
+end
+
+readers.ofm = readers.tfm
+
+-- The reencoding acts upon the 'reencode' feature which can have values 'auto' or
+-- an enc file. You can also specify a 'pfbfile' feature (but it defaults to the
+-- tfm filename) and a 'bitmap' feature. When no enc file is givven (auto) we will
+-- get the vectors from the pfb file.
+
+do
+
+ local outfiles = { }
+
+ local tfmcache = table.setmetatableindex(function(t,tfmdata)
+ local id = font.define(tfmdata)
+ t[tfmdata] = id
+ return id
+ end)
+
+ local encdone = table.setmetatableindex("table")
+
+ function tfm.reencode(tfmdata,specification)
+
+ local features = specification.features
+
+ if not features then
+ return
+ end
+
+ local features = features.normal
+
+ if not features then
+ return
+ end
+
+ local tfmfile = file.basename(tfmdata.name)
+ local encfile = features.reencode -- or features.enc
+ local pfbfile = features.pfbfile -- or features.pfb
+ local bitmap = features.bitmap -- or features.pk
+
+ if not encfile then
+ return
+ end
+
+ local pfbfile = outfiles[tfmfile]
+
+ if pfbfile == nil then
+ if bitmap then
+ pfbfile = false
+ elseif type(pfbfile) ~= "string" then
+ pfbfile = tfmfile
+ end
+ if type(pfbfile) == "string" then
+ pfbfile = file.addsuffix(pfbfile,"pfb")
+ -- pdf.mapline(tfmfile .. "<" .. pfbfile)
+ report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile)
+ else
+ report_tfm("using bitmap shapes for %a",tfmfile)
+ pfbfile = false -- use bitmap
+ end
+ outfiles[tfmfile] = pfbfile
+ end
+
+ local encoding = false
+ local vector = false
+
+ if type(pfbfile) == "string" then
+ local pfb = constructors.handlers.pfb
+ if pfb and pfb.loadvector then
+ local v, e = pfb.loadvector(pfbfile)
+ if v then
+ vector = v
+ end
+ if e then
+ encoding = e
+ end
+ end
+ end
+ if type(encfile) == "string" and encfile ~= "auto" then
+ encoding = fonts.encodings.load(file.addsuffix(encfile,"enc"))
+ if encoding then
+ encoding = encoding.vector
+ end
+ end
+ if not encoding then
+ report_tfm("bad encoding for %a, quitting",tfmfile)
+ return
+ end
+
+ local unicoding = fonts.encodings.agl and fonts.encodings.agl.unicodes
+ local virtualid = tfmcache[tfmdata]
+ local tfmdata = table.copy(tfmdata) -- good enough for small fonts
+ local characters = { }
+ local originals = tfmdata.characters
+ local indices = { }
+ local parentfont = { "font", 1 }
+ local private = tfmdata.privateoffset or constructors.privateoffset
+ local reported = encdone[tfmfile][encfile]
+
+ -- create characters table
+
+ local backmap = vector and table.swapped(vector)
+ local done = { } -- prevent duplicate
+
+ for index, name in sortedhash(encoding) do -- predictable order
+ local unicode = unicoding[name]
+ local original = originals[index]
+ if original then
+ if unicode then
+ original.unicode = unicode
+ else
+ unicode = private
+ private = private + 1
+ if not reported then
+ report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode)
+ end
+ end
+ characters[unicode] = original
+ indices[index] = unicode
+ original.name = name -- so one can lookup weird names
+ if backmap then
+ original.index = backmap[name]
+ else -- probably bitmap
+ original.commands = { parentfont, charcommand[index] } -- or "slot"
+ original.oindex = index
+ end
+ done[name] = true
+ elseif not done[name] then
+ report_tfm("bad index %a in font %a with name %a",index,tfmfile,name)
+ end
+ end
+
+ encdone[tfmfile][encfile] = true
+
+ -- redo kerns and ligatures
+
+ for k, v in next, characters do
+ local kerns = v.kerns
+ if kerns then
+ local t = { }
+ for k, v in next, kerns do
+ local i = indices[k]
+ if i then
+ t[i] = v
+ end
+ end
+ v.kerns = next(t) and t or nil
+ end
+ local ligatures = v.ligatures
+ if ligatures then
+ local t = { }
+ for k, v in next, ligatures do
+ local i = indices[k]
+ if i then
+ t[i] = v
+ v.char = indices[v.char]
+ end
+ end
+ v.ligatures = next(t) and t or nil
+ end
+ end
+
+ -- wrap up
+
+ tfmdata.fonts = { { id = virtualid } }
+ tfmdata.characters = characters
+ tfmdata.fullname = tfmdata.fullname or tfmdata.name
+ tfmdata.psname = file.nameonly(pfbfile or tfmdata.name)
+ tfmdata.filename = pfbfile
+ tfmdata.encodingbytes = 2
+ -- tfmdata.format = bitmap and "type3" or "type1"
+ tfmdata.format = "type1"
+ tfmdata.tounicode = 1
+ tfmdata.embedding = "subset"
+ tfmdata.usedbitmap = bitmap and virtualid
+ tfmdata.private = private
+
+ return tfmdata
+ end
+
+end
+
+-- This code adds a ToUnicode vector for bitmap fonts. We don't bother about
+-- ranges because we have small fonts. it works ok with acrobat but fails with
+-- the other viewers (they get confused by the bitmaps I guess).
+
+do
+
+ local template = [[
+/CIDInit /ProcSet findresource begin
+ 12 dict begin
+ begincmap
+ /CIDSystemInfo << /Registry (TeX) /Ordering (bitmap-%s) /Supplement 0 >> def
+ /CMapName /TeX-bitmap-%s def
+ /CMapType 2 def
+ 1 begincodespacerange
+ <00> <FF>
+ endcodespacerange
+ %s beginbfchar
+%s
+ endbfchar
+ endcmap
+CMapName currentdict /CMap defineresource pop end
+end
+end
+]]
+
+ local flushstreamobject = lpdf and lpdf.flushstreamobject -- context
+ local setfontattributes = lpdf and lpdf.setfontattributes -- context
+
+ if not flushstreamobject then
+ flushstreamobject = function(data)
+ return pdf.obj { immediate = true, type = "stream", string = data } -- generic
+ end
+ end
+
+ if not setfontattributes then
+ setfontattributes = function(id,data)
+ return pdf.setfontattributes(id,data) -- generic
+ end
+ end
+
+ function tfm.addtounicode(tfmdata)
+ local id = tfmdata.usedbitmap
+ local map = { }
+ local char = { } -- no need for range, hardly used
+ for k, v in next, tfmdata.characters do
+ local index = v.oindex
+ local tounicode = v.tounicode
+ if index and tounicode then
+ map[index] = tounicode
+ end
+ end
+ for k, v in sortedhash(map) do
+ char[#char+1] = format("<%02X> <%s>",k,v)
+ end
+ char = concat(char,"\n")
+ local stream = format(template,id,id,#char,char)
+ local reference = flushstreamobject(stream,nil,true)
+ setfontattributes(id,format("/ToUnicode %i 0 R",reference))
+ end
+
+end
+
+-- Now we implement the regular features handlers. We need to convert the
+-- tfm specific structures to opentype structures. In basemode they are
+-- converted back so that is a bit of a waste but it's fast enough.
+
+do
+
+ local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } }
+ local noflags = { false, false, false, false }
+
+ local function enhance_normalize_features(data)
+ local ligatures = setmetatableindex("table")
+ local kerns = setmetatableindex("table")
+ local characters = data.characters
+ for u, c in next, characters do
+ local l = c.ligatures
+ local k = c.kerns
+ if l then
+ ligatures[u] = l
+ for u, v in next, l do
+ l[u] = { ligature = v.char }
+ end
+ c.ligatures = nil
+ end
+ if k then
+ kerns[u] = k
+ for u, v in next, k do
+ k[u] = v -- { v, 0 }
+ end
+ c.kerns = nil
+ end
+ end
+
+ for u, l in next, ligatures do
+ for k, v in next, l do
+ local vl = v.ligature
+ local dl = ligatures[vl]
+ if dl then
+ for kk, vv in next, dl do
+ v[kk] = vv -- table.copy(vv)
+ end
+ end
+ end
+ end
+
+ local features = {
+ gpos = { },
+ gsub = { },
+ }
+ local sequences = {
+ -- only filled ones
+ }
+ if next(ligatures) then
+ features.gsub.liga = everywhere
+ data.properties.hasligatures = true
+ sequences[#sequences+1] = {
+ features = {
+ liga = everywhere,
+ },
+ flags = noflags,
+ name = "s_s_0",
+ nofsteps = 1,
+ order = { "liga" },
+ type = "gsub_ligature",
+ steps = {
+ {
+ coverage = ligatures,
+ },
+ },
+ }
+ end
+ if next(kerns) then
+ features.gpos.kern = everywhere
+ data.properties.haskerns = true
+ sequences[#sequences+1] = {
+ features = {
+ kern = everywhere,
+ },
+ flags = noflags,
+ name = "p_s_0",
+ nofsteps = 1,
+ order = { "kern" },
+ type = "gpos_pair",
+ steps = {
+ {
+ format = "kern",
+ coverage = kerns,
+ },
+ },
+ }
+ end
+ data.resources.features = features
+ data.resources.sequences = sequences
+ data.shared.resources = data.shared.resources or resources
+ end
+
+ registertfmenhancer("normalize features", enhance_normalize_features)
+ registertfmenhancer("check extra features", otfenhancers.enhance)
+
+end
+
+-- As with type one (afm) loading, we just use the opentype ones:
+
+registertfmfeature {
+ name = "mode",
+ description = "mode",
+ initializers = {
+ base = otf.modeinitializer,
+ node = otf.modeinitializer,
+ }
+}
+
+registertfmfeature {
+ name = "features",
+ description = "features",
+ default = true,
+ initializers = {
+ base = otf.basemodeinitializer,
+ node = otf.nodemodeinitializer,
+ },
+ processors = {
+ node = otf.featuresprocessor,
+ }
+}
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-boolean.lua b/macros/luatex/generic/luaotfload/fontloader-l-boolean.lua
new file mode 100644
index 0000000000..8f18d4c003
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-l-boolean.lua
@@ -0,0 +1,69 @@
+if not modules then modules = { } end modules ['l-boolean'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type, tonumber = type, tonumber
+
+boolean = boolean or { }
+local boolean = boolean
+
+function boolean.tonumber(b)
+ if b then return 1 else return 0 end -- test and return or return
+end
+
+function toboolean(str,tolerant) -- global
+ if str == nil then
+ return false
+ elseif str == false then
+ return false
+ elseif str == true then
+ return true
+ elseif str == "true" then
+ return true
+ elseif str == "false" then
+ return false
+ elseif not tolerant then
+ return false
+ elseif str == 0 then
+ return false
+ elseif (tonumber(str) or 0) > 0 then
+ return true
+ else
+ return str == "yes" or str == "on" or str == "t"
+ end
+end
+
+string.toboolean = toboolean
+
+function string.booleanstring(str)
+ if str == "0" then
+ return false
+ elseif str == "1" then
+ return true
+ elseif str == "" then
+ return false
+ elseif str == "false" then
+ return false
+ elseif str == "true" then
+ return true
+ elseif (tonumber(str) or 0) > 0 then
+ return true
+ else
+ return str == "yes" or str == "on" or str == "t"
+ end
+end
+
+function string.is_boolean(str,default,strict)
+ if type(str) == "string" then
+ if str == "true" or str == "yes" or str == "on" or str == "t" or (not strict and str == "1") then
+ return true
+ elseif str == "false" or str == "no" or str == "off" or str == "f" or (not strict and str == "0") then
+ return false
+ end
+ end
+ return default
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-file.lua b/macros/luatex/generic/luaotfload/fontloader-l-file.lua
new file mode 100644
index 0000000000..1b039a4386
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-l-file.lua
@@ -0,0 +1,738 @@
+if not modules then modules = { } end modules ['l-file'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- needs a cleanup
+
+file = file or { }
+local file = file
+
+if not lfs then
+ lfs = optionalrequire("lfs")
+end
+
+-- -- see later
+--
+-- if not lfs then
+--
+-- lfs = {
+-- getcurrentdir = function()
+-- return "."
+-- end,
+-- attributes = function()
+-- return nil
+-- end,
+-- isfile = function(name)
+-- local f = io.open(name,'rb')
+-- if f then
+-- f:close()
+-- return true
+-- end
+-- end,
+-- isdir = function(name)
+-- print("you need to load lfs")
+-- return false
+-- end
+-- }
+--
+-- elseif not lfs.isfile then
+--
+-- local attributes = lfs.attributes
+--
+-- function lfs.isdir(name)
+-- return attributes(name,"mode") == "directory"
+-- end
+--
+-- function lfs.isfile(name)
+-- return attributes(name,"mode") == "file"
+-- end
+--
+-- -- function lfs.isdir(name)
+-- -- local a = attributes(name)
+-- -- return a and a.mode == "directory"
+-- -- end
+--
+-- -- function lfs.isfile(name)
+-- -- local a = attributes(name)
+-- -- return a and a.mode == "file"
+-- -- end
+--
+-- end
+
+local insert, concat = table.insert, table.concat
+local match, find, gmatch = string.match, string.find, string.gmatch
+local lpegmatch = lpeg.match
+local getcurrentdir, attributes = lfs.currentdir, lfs.attributes
+local checkedsplit = string.checkedsplit
+
+local P, R, S, C, Cs, Cp, Cc, Ct = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cp, lpeg.Cc, lpeg.Ct
+
+-- better this way:
+
+local attributes = lfs.attributes
+
+function lfs.isdir(name)
+ return attributes(name,"mode") == "directory"
+end
+
+function lfs.isfile(name)
+ local a = attributes(name,"mode")
+ return a == "file" or a == "link" or nil
+end
+
+function lfs.isfound(name)
+ local a = attributes(name,"mode")
+ return (a == "file" or a == "link") and name or nil
+end
+
+if sandbox then
+ sandbox.redefine(lfs.isfile,"lfs.isfile")
+ sandbox.redefine(lfs.isdir, "lfs.isdir")
+ sandbox.redefine(lfs.isfound, "lfs.isfound")
+end
+
+local colon = P(":")
+local period = P(".")
+local periods = P("..")
+local fwslash = P("/")
+local bwslash = P("\\")
+local slashes = S("\\/")
+local noperiod = 1-period
+local noslashes = 1-slashes
+local name = noperiod^1
+local suffix = period/"" * (1-period-slashes)^1 * -1
+
+----- pattern = C((noslashes^0 * slashes^1)^1)
+local pattern = C((1 - (slashes^1 * noslashes^1 * -1))^1) * P(1) -- there must be a more efficient way
+
+local function pathpart(name,default)
+ return name and lpegmatch(pattern,name) or default or ""
+end
+
+local pattern = (noslashes^0 * slashes)^1 * C(noslashes^1) * -1
+
+local function basename(name)
+ return name and lpegmatch(pattern,name) or name
+end
+
+-- print(pathpart("file"))
+-- print(pathpart("dir/file"))
+-- print(pathpart("/dir/file"))
+-- print(basename("file"))
+-- print(basename("dir/file"))
+-- print(basename("/dir/file"))
+
+local pattern = (noslashes^0 * slashes^1)^0 * Cs((1-suffix)^1) * suffix^0
+
+local function nameonly(name)
+ return name and lpegmatch(pattern,name) or name
+end
+
+local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * C(noperiod^1) * -1
+
+local function suffixonly(name)
+ return name and lpegmatch(pattern,name) or ""
+end
+
+local pattern = (noslashes^0 * slashes)^0 * noperiod^1 * ((period * C(noperiod^1))^1) * -1 + Cc("")
+
+local function suffixesonly(name)
+ if name then
+ return lpegmatch(pattern,name)
+ else
+ return ""
+ end
+end
+
+file.pathpart = pathpart
+file.basename = basename
+file.nameonly = nameonly
+file.suffixonly = suffixonly
+file.suffix = suffixonly
+file.suffixesonly = suffixesonly
+file.suffixes = suffixesonly
+
+file.dirname = pathpart -- obsolete
+file.extname = suffixonly -- obsolete
+
+-- actually these are schemes
+
+local drive = C(R("az","AZ")) * colon
+local path = C((noslashes^0 * slashes)^0)
+local suffix = period * C(P(1-period)^0 * P(-1))
+local base = C((1-suffix)^0)
+local rest = C(P(1)^0)
+
+drive = drive + Cc("")
+path = path + Cc("")
+base = base + Cc("")
+suffix = suffix + Cc("")
+
+local pattern_a = drive * path * base * suffix
+local pattern_b = path * base * suffix
+local pattern_c = C(drive * path) * C(base * suffix) -- trick: two extra captures
+local pattern_d = path * rest
+
+function file.splitname(str,splitdrive)
+ if not str then
+ -- error
+ elseif splitdrive then
+ return lpegmatch(pattern_a,str) -- returns drive, path, base, suffix
+ else
+ return lpegmatch(pattern_b,str) -- returns path, base, suffix
+ end
+end
+
+function file.splitbase(str)
+ if str then
+ return lpegmatch(pattern_d,str) -- returns path, base+suffix (path has / appended, might change at some point)
+ else
+ return "", str -- assume no path
+ end
+end
+
+---- stripslash = C((1 - P("/")^1*P(-1))^0)
+
+function file.nametotable(str,splitdrive)
+ if str then
+ local path, drive, subpath, name, base, suffix = lpegmatch(pattern_c,str)
+ -- if path ~= "" then
+ -- path = lpegmatch(stripslash,path) -- unfortunate hack, maybe this becomes default
+ -- end
+ if splitdrive then
+ return {
+ path = path,
+ drive = drive,
+ subpath = subpath,
+ name = name,
+ base = base,
+ suffix = suffix,
+ }
+ else
+ return {
+ path = path,
+ name = name,
+ base = base,
+ suffix = suffix,
+ }
+ end
+ end
+end
+
+-- print(file.splitname("file"))
+-- print(file.splitname("dir/file"))
+-- print(file.splitname("/dir/file"))
+-- print(file.splitname("file"))
+-- print(file.splitname("dir/file"))
+-- print(file.splitname("/dir/file"))
+
+-- inspect(file.nametotable("file.ext"))
+-- inspect(file.nametotable("dir/file.ext"))
+-- inspect(file.nametotable("/dir/file.ext"))
+-- inspect(file.nametotable("file.ext"))
+-- inspect(file.nametotable("dir/file.ext"))
+-- inspect(file.nametotable("/dir/file.ext"))
+
+----- pattern = Cs(((period * noperiod^1 * -1) / "" + 1)^1)
+local pattern = Cs(((period * (1-period-slashes)^1 * -1) / "" + 1)^1)
+
+function file.removesuffix(name)
+ return name and lpegmatch(pattern,name)
+end
+
+-- local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * Cp() * noperiod^1 * -1
+--
+-- function file.addsuffix(name, suffix)
+-- local p = lpegmatch(pattern,name)
+-- if p then
+-- return name
+-- else
+-- return name .. "." .. suffix
+-- end
+-- end
+
+local suffix = period/"" * (1-period-slashes)^1 * -1
+local pattern = Cs((noslashes^0 * slashes^1)^0 * ((1-suffix)^1)) * Cs(suffix)
+
+function file.addsuffix(filename,suffix,criterium)
+ if not filename or not suffix or suffix == "" then
+ return filename
+ elseif criterium == true then
+ return filename .. "." .. suffix
+ elseif not criterium then
+ local n, s = lpegmatch(pattern,filename)
+ if not s or s == "" then
+ return filename .. "." .. suffix
+ else
+ return filename
+ end
+ else
+ local n, s = lpegmatch(pattern,filename)
+ if s and s ~= "" then
+ local t = type(criterium)
+ if t == "table" then
+ -- keep if in criterium
+ for i=1,#criterium do
+ if s == criterium[i] then
+ return filename
+ end
+ end
+ elseif t == "string" then
+ -- keep if criterium
+ if s == criterium then
+ return filename
+ end
+ end
+ end
+ return (n or filename) .. "." .. suffix
+ end
+end
+
+-- print("1 " .. file.addsuffix("name","new") .. " -> name.new")
+-- print("2 " .. file.addsuffix("name.old","new") .. " -> name.old")
+-- print("3 " .. file.addsuffix("name.old","new",true) .. " -> name.old.new")
+-- print("4 " .. file.addsuffix("name.old","new","new") .. " -> name.new")
+-- print("5 " .. file.addsuffix("name.old","new","old") .. " -> name.old")
+-- print("6 " .. file.addsuffix("name.old","new","foo") .. " -> name.new")
+-- print("7 " .. file.addsuffix("name.old","new",{"foo","bar"}) .. " -> name.new")
+-- print("8 " .. file.addsuffix("name.old","new",{"old","bar"}) .. " -> name.old")
+
+local suffix = period * (1-period-slashes)^1 * -1
+local pattern = Cs((1-suffix)^0)
+
+function file.replacesuffix(name,suffix)
+ if name and suffix and suffix ~= "" then
+ return lpegmatch(pattern,name) .. "." .. suffix
+ else
+ return name
+ end
+end
+
+--
+
+local reslasher = lpeg.replacer(P("\\"),"/")
+
+function file.reslash(str)
+ return str and lpegmatch(reslasher,str)
+end
+
+-- We should be able to use:
+--
+-- local writable = P(1) * P("w") * Cc(true)
+--
+-- function file.is_writable(name)
+-- local a = attributes(name) or attributes(pathpart(name,"."))
+-- return a and lpegmatch(writable,a.permissions) or false
+-- end
+--
+-- But after some testing Taco and I came up with the more robust
+-- variant:
+
+if lfs.isreadablefile and lfs.iswritablefile then
+
+ file.is_readable = lfs.isreadablefile
+ file.is_writable = lfs.iswritablefile
+
+else
+
+ function file.is_writable(name)
+ if not name then
+ -- error
+ elseif lfs.isdir(name) then
+ name = name .. "/m_t_x_t_e_s_t.tmp"
+ local f = io.open(name,"wb")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ elseif lfs.isfile(name) then
+ local f = io.open(name,"ab")
+ if f then
+ f:close()
+ return true
+ end
+ else
+ local f = io.open(name,"ab")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ end
+ return false
+ end
+
+ local readable = P("r") * Cc(true)
+
+ function file.is_readable(name)
+ if name then
+ local a = attributes(name)
+ return a and lpegmatch(readable,a.permissions) or false
+ else
+ return false
+ end
+ end
+
+end
+
+file.isreadable = file.is_readable -- depricated
+file.iswritable = file.is_writable -- depricated
+
+function file.size(name)
+ if name then
+ local a = attributes(name)
+ return a and a.size or 0
+ else
+ return 0
+ end
+end
+
+function file.splitpath(str,separator) -- string .. reslash is a bonus (we could do a direct split)
+ return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
+end
+
+function file.joinpath(tab,separator) -- table
+ return tab and concat(tab,separator or io.pathseparator) -- can have trailing //
+end
+
+local someslash = S("\\/")
+local stripper = Cs(P(fwslash)^0/"" * reslasher)
+local isnetwork = someslash * someslash * (1-someslash)
+ + (1-fwslash-colon)^1 * colon
+local isroot = fwslash^1 * -1
+local hasroot = fwslash^1
+
+local reslasher = lpeg.replacer(S("\\/"),"/")
+local deslasher = lpeg.replacer(S("\\/")^1,"/")
+
+-- If we have a network or prefix then there is a change that we end up with two
+-- // in the middle ... we could prevent this if we (1) expand prefixes: and (2)
+-- split and rebuild as url. Of course we could assume no network paths (which
+-- makes sense) adn assume either mapped drives (windows) or mounts (unix) but
+-- then we still have to deal with urls ... anyhow, multiple // are never a real
+-- problem but just ugly.
+
+-- function file.join(...)
+-- local lst = { ... }
+-- local one = lst[1]
+-- if lpegmatch(isnetwork,one) then
+-- local one = lpegmatch(reslasher,one)
+-- local two = lpegmatch(deslasher,concat(lst,"/",2))
+-- if lpegmatch(hasroot,two) then
+-- return one .. two
+-- else
+-- return one .. "/" .. two
+-- end
+-- elseif lpegmatch(isroot,one) then
+-- local two = lpegmatch(deslasher,concat(lst,"/",2))
+-- if lpegmatch(hasroot,two) then
+-- return two
+-- else
+-- return "/" .. two
+-- end
+-- elseif one == "" then
+-- return lpegmatch(stripper,concat(lst,"/",2))
+-- else
+-- return lpegmatch(deslasher,concat(lst,"/"))
+-- end
+-- end
+
+function file.join(one, two, three, ...)
+ if not two then
+ return one == "" and one or lpegmatch(reslasher,one)
+ end
+ if one == "" then
+ return lpegmatch(stripper,three and concat({ two, three, ... },"/") or two)
+ end
+ if lpegmatch(isnetwork,one) then
+ local one = lpegmatch(reslasher,one)
+ local two = lpegmatch(deslasher,three and concat({ two, three, ... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return one .. two
+ else
+ return one .. "/" .. two
+ end
+ elseif lpegmatch(isroot,one) then
+ local two = lpegmatch(deslasher,three and concat({ two, three, ... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return two
+ else
+ return "/" .. two
+ end
+ else
+ return lpegmatch(deslasher,concat({ one, two, three, ... },"/"))
+ end
+end
+
+-- or we can use this:
+--
+-- function file.join(...)
+-- local n = select("#",...)
+-- local one = select(1,...)
+-- if n == 1 then
+-- return one == "" and one or lpegmatch(stripper,one)
+-- end
+-- if one == "" then
+-- return lpegmatch(stripper,n > 2 and concat({ ... },"/",2) or select(2,...))
+-- end
+-- if lpegmatch(isnetwork,one) then
+-- local one = lpegmatch(reslasher,one)
+-- local two = lpegmatch(deslasher,n > 2 and concat({ ... },"/",2) or select(2,...))
+-- if lpegmatch(hasroot,two) then
+-- return one .. two
+-- else
+-- return one .. "/" .. two
+-- end
+-- elseif lpegmatch(isroot,one) then
+-- local two = lpegmatch(deslasher,n > 2 and concat({ ... },"/",2) or select(2,...))
+-- if lpegmatch(hasroot,two) then
+-- return two
+-- else
+-- return "/" .. two
+-- end
+-- else
+-- return lpegmatch(deslasher,concat({ ... },"/"))
+-- end
+-- end
+
+-- print(file.join("c:/whatever"))
+-- print(file.join("c:/whatever","name"))
+-- print(file.join("//","/y"))
+-- print(file.join("/","/y"))
+-- print(file.join("","/y"))
+-- print(file.join("/x/","/y"))
+-- print(file.join("x/","/y"))
+-- print(file.join("http://","/y"))
+-- print(file.join("http://a","/y"))
+-- print(file.join("http:///a","/y"))
+-- print(file.join("//nas-1","/y"))
+-- print(file.join("//nas-1/a/b/c","/y"))
+-- print(file.join("\\\\nas-1\\a\\b\\c","\\y"))
+
+-- The previous one fails on "a.b/c" so Taco came up with a split based
+-- variant. After some skyping we got it sort of compatible with the old
+-- one. After that the anchoring to currentdir was added in a better way.
+-- Of course there are some optimizations too. Finally we had to deal with
+-- windows drive prefixes and things like sys://. Eventually gsubs and
+-- finds were replaced by lpegs.
+
+local drivespec = R("az","AZ")^1 * colon
+local anchors = fwslash
+ + drivespec
+local untouched = periods
+ + (1-period)^1 * P(-1)
+local mswindrive = Cs(drivespec * (bwslash/"/" + fwslash)^0)
+local mswinuncpath = (bwslash + fwslash) * (bwslash + fwslash) * Cc("//")
+local splitstarter = (mswindrive + mswinuncpath + Cc(false))
+ * Ct(lpeg.splitat(S("/\\")^1))
+local absolute = fwslash
+
+function file.collapsepath(str,anchor) -- anchor: false|nil, true, "."
+ if not str then
+ return
+ end
+ if anchor == true and not lpegmatch(anchors,str) then
+ str = getcurrentdir() .. "/" .. str
+ end
+ if str == "" or str =="." then
+ return "."
+ elseif lpegmatch(untouched,str) then
+ return lpegmatch(reslasher,str)
+ end
+ local starter, oldelements = lpegmatch(splitstarter,str)
+ local newelements = { }
+ local i = #oldelements
+ while i > 0 do
+ local element = oldelements[i]
+ if element == '.' then
+ -- do nothing
+ elseif element == '..' then
+ local n = i - 1
+ while n > 0 do
+ local element = oldelements[n]
+ if element ~= '..' and element ~= '.' then
+ oldelements[n] = '.'
+ break
+ else
+ n = n - 1
+ end
+ end
+ if n < 1 then
+ insert(newelements,1,'..')
+ end
+ elseif element ~= "" then
+ insert(newelements,1,element)
+ end
+ i = i - 1
+ end
+ if #newelements == 0 then
+ return starter or "."
+ elseif starter then
+ return starter .. concat(newelements, '/')
+ elseif lpegmatch(absolute,str) then
+ return "/" .. concat(newelements,'/')
+ else
+ newelements = concat(newelements, '/')
+ if anchor == "." and find(str,"^%./") then
+ return "./" .. newelements
+ else
+ return newelements
+ end
+ end
+end
+
+-- local function test(str,...)
+-- print(string.format("%-20s %-15s %-30s %-20s",str,file.collapsepath(str),file.collapsepath(str,true),file.collapsepath(str,".")))
+-- end
+-- test("a/b.c/d") test("b.c/d") test("b.c/..")
+-- test("/") test("c:/..") test("sys://..")
+-- test("") test("./") test(".") test("..") test("./..") test("../..")
+-- test("a") test("./a") test("/a") test("a/../..")
+-- test("a/./b/..") test("a/aa/../b/bb") test("a/.././././b/..") test("a/./././b/..")
+-- test("a/b/c/../..") test("./a/b/c/../..") test("a/b/c/../..")
+-- test("./a")
+-- test([[\\a.b.c\d\e]])
+
+local validchars = R("az","09","AZ","--","..")
+local pattern_a = lpeg.replacer(1-validchars)
+local pattern_a = Cs((validchars + P(1)/"-")^1)
+local whatever = P("-")^0 / ""
+local pattern_b = Cs(whatever * (1 - whatever * -1)^1)
+
+function file.robustname(str,strict)
+ if str then
+ str = lpegmatch(pattern_a,str) or str
+ if strict then
+ return lpegmatch(pattern_b,str) or str -- two step is cleaner (less backtracking)
+ else
+ return str
+ end
+ end
+end
+
+local loaddata = io.loaddata
+local savedata = io.savedata
+
+file.readdata = loaddata
+file.savedata = savedata
+
+function file.copy(oldname,newname)
+ if oldname and newname then
+ local data = loaddata(oldname)
+ if data and data ~= "" then
+ savedata(newname,data)
+ end
+ end
+end
+
+-- also rewrite previous
+
+local letter = R("az","AZ") + S("_-+")
+local separator = P("://")
+
+local qualified = period^0 * fwslash
+ + letter * colon
+ + letter^1 * separator
+ + letter^1 * fwslash
+local rootbased = fwslash
+ + letter * colon
+
+lpeg.patterns.qualified = qualified
+lpeg.patterns.rootbased = rootbased
+
+-- ./name ../name /name c: :// name/name
+
+function file.is_qualified_path(filename)
+ return filename and lpegmatch(qualified,filename) ~= nil
+end
+
+function file.is_rootbased_path(filename)
+ return filename and lpegmatch(rootbased,filename) ~= nil
+end
+
+-- function test(t) for k, v in next, t do print(v, "=>", file.splitname(v)) end end
+--
+-- test { "c:", "c:/aa", "c:/aa/bb", "c:/aa/bb/cc", "c:/aa/bb/cc.dd", "c:/aa/bb/cc.dd.ee" }
+-- test { "c:", "c:aa", "c:aa/bb", "c:aa/bb/cc", "c:aa/bb/cc.dd", "c:aa/bb/cc.dd.ee" }
+-- test { "/aa", "/aa/bb", "/aa/bb/cc", "/aa/bb/cc.dd", "/aa/bb/cc.dd.ee" }
+-- test { "aa", "aa/bb", "aa/bb/cc", "aa/bb/cc.dd", "aa/bb/cc.dd.ee" }
+
+-- -- maybe:
+--
+-- if os.type == "windows" then
+-- local currentdir = getcurrentdir
+-- function getcurrentdir()
+-- return lpegmatch(reslasher,currentdir())
+-- end
+-- end
+
+-- for myself:
+
+function file.strip(name,dir)
+ if name then
+ local b, a = match(name,"^(.-)" .. dir .. "(.*)$")
+ return a ~= "" and a or name
+ end
+end
+
+-- local debuglist = {
+-- "pathpart", "basename", "nameonly", "suffixonly", "suffix", "dirname", "extname",
+-- "addsuffix", "removesuffix", "replacesuffix", "join",
+-- "strip","collapsepath", "joinpath", "splitpath",
+-- }
+
+-- for i=1,#debuglist do
+-- local name = debuglist[i]
+-- local f = file[name]
+-- file[name] = function(...)
+-- print(name,f(...))
+-- return f(...)
+-- end
+-- end
+
+-- a goodie: a dumb version of mkdirs (not used in context itself, only
+-- in generic usage)
+
+function lfs.mkdirs(path)
+ local full = ""
+ for sub in gmatch(path,"(/*[^\\/]+)") do -- accepts leading c: and /
+ full = full .. sub
+ -- lfs.isdir("/foo") mistakenly returns true on windows so
+ -- so we don't test and just make as that one is not too picky
+ lfs.mkdir(full)
+ end
+end
+
+-- here is oen i ran into when messign around with xavante code (keppler project)
+-- where it's called in_base .. no gain in using lpeg here
+
+function file.withinbase(path) -- don't go beyond root
+ local l = 0
+ if not find(path,"^/") then
+ path = "/" .. path
+ end
+ for dir in gmatch(path,"/([^/]+)") do
+ if dir == ".." then
+ l = l - 1
+ elseif dir ~= "." then
+ l = l + 1
+ end
+ if l < 0 then
+ return false
+ end
+ end
+ return true
+end
+
+-- not used in context but was in luatex once:
+
+local symlinkattributes = lfs.symlinkattributes
+
+function lfs.readlink(name)
+ return symlinkattributes(name,"target") or nil
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-function.lua b/macros/luatex/generic/luaotfload/fontloader-l-function.lua
new file mode 100644
index 0000000000..7ded8ceecd
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-l-function.lua
@@ -0,0 +1,11 @@
+if not modules then modules = { } end modules ['l-functions'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+functions = functions or { }
+
+function functions.dummy() end
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-io.lua b/macros/luatex/generic/luaotfload/fontloader-l-io.lua
new file mode 100644
index 0000000000..fa3ad3c4cd
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-l-io.lua
@@ -0,0 +1,473 @@
+if not modules then modules = { } end modules ['l-io'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local io = io
+local open, flush, write, read = io.open, io.flush, io.write, io.read
+local byte, find, gsub, format = string.byte, string.find, string.gsub, string.format
+local concat = table.concat
+----- floor = math.floor
+local type = type
+
+if string.find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator, io.pathseparator = "\\", ";"
+else
+ io.fileseparator, io.pathseparator = "/" , ":"
+end
+
+-- local function readall(f)
+-- return f:read("*all")
+-- end
+
+-- The next one is upto 50% faster on large files and less memory consumption due
+-- to less intermediate large allocations. This phenomena was discussed on the
+-- luatex dev list.
+
+local large = 0x01000000 -- 2^24 16.777.216
+local medium = 0x00100000 -- 2^20 1.048.576
+local small = 0x00020000 -- 2^17 131.072
+
+-- local function readall(f)
+-- local size = f:seek("end")
+-- if size == 0 then
+-- return ""
+-- end
+-- f:seek("set",0)
+-- if size < medium then
+-- return f:read('*all')
+-- else
+-- local step = (size > large) and large or (floor(size/(medium)) * small)
+-- local data = { }
+-- while true do
+-- local r = f:read(step)
+-- if not r then
+-- return concat(data)
+-- else
+-- data[#data+1] = r
+-- end
+-- end
+-- end
+-- end
+
+local function readall(f)
+ -- return f:read("*all")
+ local size = f:seek("end")
+ if size > 0 then
+ f:seek("set",0)
+ return f:read(size)
+ else
+ return ""
+ end
+end
+
+io.readall = readall
+
+function io.loaddata(filename,textmode) -- return nil if empty
+ local f = open(filename,(textmode and 'r') or 'rb')
+ if f then
+ local size = f:seek("end")
+ local data = nil
+ if size > 0 then
+ -- data = f:read("*all")
+ f:seek("set",0)
+ data = f:read(size)
+ end
+ f:close()
+ return data
+ end
+end
+
+-- function io.copydata(source,target,action)
+-- local f = open(source,"rb")
+-- if f then
+-- local g = open(target,"wb")
+-- if g then
+-- local size = f:seek("end")
+-- if size == 0 then
+-- -- empty
+-- else
+-- f:seek("set",0)
+-- if size < medium then
+-- local data = f:read('*all')
+-- if action then
+-- data = action(data)
+-- end
+-- if data then
+-- g:write(data)
+-- end
+-- else
+-- local step = (size > large) and large or (floor(size/(medium)) * small)
+-- while true do
+-- local data = f:read(step)
+-- if data then
+-- if action then
+-- data = action(data)
+-- end
+-- if data then
+-- g:write(data)
+-- end
+-- else
+-- break
+-- end
+-- end
+-- end
+-- end
+-- g:close()
+-- end
+-- f:close()
+-- flush()
+-- end
+-- end
+
+function io.copydata(source,target,action)
+ local f = open(source,"rb")
+ if f then
+ local g = open(target,"wb")
+ if g then
+ local size = f:seek("end")
+ if size > 0 then
+ -- local data = f:read('*all')
+ f:seek("set",0)
+ local data = f:read(size)
+ if action then
+ data = action(data)
+ end
+ if data then
+ g:write(data)
+ end
+ end
+ g:close()
+ end
+ f:close()
+ flush()
+ end
+end
+
+function io.savedata(filename,data,joiner)
+ local f = open(filename,"wb")
+ if f then
+ if type(data) == "table" then
+ f:write(concat(data,joiner or ""))
+ elseif type(data) == "function" then
+ data(f)
+ else
+ f:write(data or "")
+ end
+ f:close()
+ flush()
+ return true
+ else
+ return false
+ end
+end
+
+-- we can also chunk this one if needed: io.lines(filename,chunksize,"*l")
+
+-- ffi.readline
+
+if fio and fio.readline then
+
+ local readline = fio.readline
+
+ function io.loadlines(filename,n) -- return nil if empty
+ local f = open(filename,'r')
+ if not f then
+ -- no file
+ elseif n then
+ local lines = { }
+ for i=1,n do
+ local line = readline(f)
+ if line then
+ lines[i] = line
+ else
+ break
+ end
+ end
+ f:close()
+ lines = concat(lines,"\n")
+ if #lines > 0 then
+ return lines
+ end
+ else
+ local line = readline(f)
+ f:close()
+ if line and #line > 0 then
+ return line
+ end
+ end
+ end
+
+else
+
+ function io.loadlines(filename,n) -- return nil if empty
+ local f = open(filename,'r')
+ if not f then
+ -- no file
+ elseif n then
+ local lines = { }
+ for i=1,n do
+ local line = f:read("*lines")
+ if line then
+ lines[i] = line
+ else
+ break
+ end
+ end
+ f:close()
+ lines = concat(lines,"\n")
+ if #lines > 0 then
+ return lines
+ end
+ else
+ local line = f:read("*line") or ""
+ f:close()
+ if #line > 0 then
+ return line
+ end
+ end
+ end
+
+end
+
+function io.loadchunk(filename,n)
+ local f = open(filename,'rb')
+ if f then
+ local data = f:read(n or 1024)
+ f:close()
+ if #data > 0 then
+ return data
+ end
+ end
+end
+
+function io.exists(filename)
+ local f = open(filename)
+ if f == nil then
+ return false
+ else
+ f:close()
+ return true
+ end
+end
+
+function io.size(filename)
+ local f = open(filename)
+ if f == nil then
+ return 0
+ else
+ local s = f:seek("end")
+ f:close()
+ return s
+ end
+end
+
+local function noflines(f)
+ if type(f) == "string" then
+ local f = open(filename)
+ if f then
+ local n = f and noflines(f) or 0
+ f:close()
+ return n
+ else
+ return 0
+ end
+ else
+ -- todo: load and lpeg
+ local n = 0
+ for _ in f:lines() do
+ n = n + 1
+ end
+ f:seek('set',0)
+ return n
+ end
+end
+
+io.noflines = noflines
+
+-- inlined is faster ... beware, better use util-fil
+
+local nextchar = {
+ [ 4] = function(f)
+ return f:read(1,1,1,1)
+ end,
+ [ 2] = function(f)
+ return f:read(1,1)
+ end,
+ [ 1] = function(f)
+ return f:read(1)
+ end,
+ [-2] = function(f)
+ local a, b = f:read(1,1)
+ return b, a
+ end,
+ [-4] = function(f)
+ local a, b, c, d = f:read(1,1,1,1)
+ return d, c, b, a
+ end
+}
+
+function io.characters(f,n)
+ if f then
+ return nextchar[n or 1], f
+ end
+end
+
+local nextbyte = {
+ [4] = function(f)
+ local a, b, c, d = f:read(1,1,1,1)
+ if d then
+ return byte(a), byte(b), byte(c), byte(d)
+ end
+ end,
+ [3] = function(f)
+ local a, b, c = f:read(1,1,1)
+ if b then
+ return byte(a), byte(b), byte(c)
+ end
+ end,
+ [2] = function(f)
+ local a, b = f:read(1,1)
+ if b then
+ return byte(a), byte(b)
+ end
+ end,
+ [1] = function (f)
+ local a = f:read(1)
+ if a then
+ return byte(a)
+ end
+ end,
+ [-2] = function (f)
+ local a, b = f:read(1,1)
+ if b then
+ return byte(b), byte(a)
+ end
+ end,
+ [-3] = function(f)
+ local a, b, c = f:read(1,1,1)
+ if b then
+ return byte(c), byte(b), byte(a)
+ end
+ end,
+ [-4] = function(f)
+ local a, b, c, d = f:read(1,1,1,1)
+ if d then
+ return byte(d), byte(c), byte(b), byte(a)
+ end
+ end
+}
+
+function io.bytes(f,n)
+ if f then
+ return nextbyte[n or 1], f
+ else
+ return nil, nil
+ end
+end
+
+function io.ask(question,default,options)
+ while true do
+ write(question)
+ if options then
+ write(format(" [%s]",concat(options,"|")))
+ end
+ if default then
+ write(format(" [%s]",default))
+ end
+ write(format(" "))
+ flush()
+ local answer = read()
+ answer = gsub(answer,"^%s*(.*)%s*$","%1")
+ if answer == "" and default then
+ return default
+ elseif not options then
+ return answer
+ else
+ for k=1,#options do
+ if options[k] == answer then
+ return answer
+ end
+ end
+ local pattern = "^" .. answer
+ for k=1,#options do
+ local v = options[k]
+ if find(v,pattern) then
+ return v
+ end
+ end
+ end
+ end
+end
+
+local function readnumber(f,n,m) -- to be replaced
+ if m then
+ f:seek("set",n)
+ n = m
+ end
+ if n == 1 then
+ return byte(f:read(1))
+ elseif n == 2 then
+ local a, b = byte(f:read(2),1,2)
+ return 0x100 * a + b
+ elseif n == 3 then
+ local a, b, c = byte(f:read(3),1,3)
+ return 0x10000 * a + 0x100 * b + c
+ elseif n == 4 then
+ local a, b, c, d = byte(f:read(4),1,4)
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+ elseif n == 8 then
+ local a, b = readnumber(f,4), readnumber(f,4)
+ return 0x100 * a + b
+ elseif n == 12 then
+ local a, b, c = readnumber(f,4), readnumber(f,4), readnumber(f,4)
+ return 0x10000 * a + 0x100 * b + c
+ elseif n == -2 then
+ local b, a = byte(f:read(2),1,2)
+ return 0x100 * a + b
+ elseif n == -3 then
+ local c, b, a = byte(f:read(3),1,3)
+ return 0x10000 * a + 0x100 * b + c
+ elseif n == -4 then
+ local d, c, b, a = byte(f:read(4),1,4)
+ return 0x1000000 * a + 0x10000 * b + 0x100*c + d
+ elseif n == -8 then
+ local h, g, f, e, d, c, b, a = byte(f:read(8),1,8)
+ return 0x100000000000000 * a + 0x1000000000000 * b + 0x10000000000 * c + 0x100000000 * d +
+ 0x1000000 * e + 0x10000 * f + 0x100 * g + h
+ else
+ return 0
+ end
+end
+
+io.readnumber = readnumber
+
+function io.readstring(f,n,m)
+ if m then
+ f:seek("set",n)
+ n = m
+ end
+ local str = gsub(f:read(n),"\000","")
+ return str
+end
+
+-- This works quite ok:
+--
+-- function io.piped(command,writer)
+-- local pipe = io.popen(command)
+-- -- for line in pipe:lines() do
+-- -- print(line)
+-- -- end
+-- while true do
+-- local line = pipe:read(1)
+-- if not line then
+-- break
+-- elseif line ~= "\n" then
+-- writer(line)
+-- end
+-- end
+-- return pipe:close() -- ok, status, (error)code
+-- end
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-lpeg.lua b/macros/luatex/generic/luaotfload/fontloader-l-lpeg.lua
new file mode 100644
index 0000000000..51bc1d3df3
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-l-lpeg.lua
@@ -0,0 +1,1196 @@
+if not modules then modules = { } end modules ['l-lpeg'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- we can get too many captures (e.g. on largexml files) which makes me wonder
+-- if P(foo)/"" can't be simplfied to N(foo) i.e. some direct instruction to the
+-- lpeg virtual machine to ignore it
+
+-- lpeg 12 vs lpeg 10: slower compilation, similar parsing speed (i need to check
+-- if i can use new features like capture / 2 and .B (at first sight the xml
+-- parser is some 5% slower)
+
+-- lpeg.P("abc") is faster than lpeg.P("a") * lpeg.P("b") * lpeg.P("c")
+
+-- a new lpeg fails on a #(1-P(":")) test and really needs a + P(-1)
+
+-- move utf -> l-unicode
+-- move string -> l-string or keep it here
+
+-- lpeg.B : backward without consumption
+-- lpeg.F = getmetatable(lpeg.P(1)).__len : forward without consumption
+
+
+lpeg = require("lpeg") -- does lpeg register itself global?
+
+local lpeg = lpeg
+
+-- The latest lpeg doesn't have print any more, and even the new ones are not
+-- available by default (only when debug mode is enabled), which is a pitty as
+-- as it helps nailing down bottlenecks. Performance seems comparable: some 10%
+-- slower pattern compilation, same parsing speed, although,
+--
+-- local p = lpeg.C(lpeg.P(1)^0 * lpeg.P(-1))
+-- local a = string.rep("123",100)
+-- lpeg.match(p,a)
+--
+-- seems slower and is also still suboptimal (i.e. a match that runs from begin
+-- to end, one of the cases where string matchers win).
+
+if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end
+
+-- tracing (only used when we encounter a problem in integration of lpeg in luatex)
+
+-- some code will move to unicode and string
+
+-- local lpmatch = lpeg.match
+-- local lpprint = lpeg.print
+-- local lpp = lpeg.P
+-- local lpr = lpeg.R
+-- local lps = lpeg.S
+-- local lpc = lpeg.C
+-- local lpb = lpeg.B
+-- local lpv = lpeg.V
+-- local lpcf = lpeg.Cf
+-- local lpcb = lpeg.Cb
+-- local lpcg = lpeg.Cg
+-- local lpct = lpeg.Ct
+-- local lpcs = lpeg.Cs
+-- local lpcc = lpeg.Cc
+-- local lpcmt = lpeg.Cmt
+-- local lpcarg = lpeg.Carg
+
+-- function lpeg.match(l,...) print("LPEG MATCH") lpprint(l) return lpmatch(l,...) end
+
+-- function lpeg.P (l) local p = lpp (l) print("LPEG P =") lpprint(l) return p end
+-- function lpeg.R (l) local p = lpr (l) print("LPEG R =") lpprint(l) return p end
+-- function lpeg.S (l) local p = lps (l) print("LPEG S =") lpprint(l) return p end
+-- function lpeg.C (l) local p = lpc (l) print("LPEG C =") lpprint(l) return p end
+-- function lpeg.B (l) local p = lpb (l) print("LPEG B =") lpprint(l) return p end
+-- function lpeg.V (l) local p = lpv (l) print("LPEG V =") lpprint(l) return p end
+-- function lpeg.Cf (l) local p = lpcf (l) print("LPEG Cf =") lpprint(l) return p end
+-- function lpeg.Cb (l) local p = lpcb (l) print("LPEG Cb =") lpprint(l) return p end
+-- function lpeg.Cg (l) local p = lpcg (l) print("LPEG Cg =") lpprint(l) return p end
+-- function lpeg.Ct (l) local p = lpct (l) print("LPEG Ct =") lpprint(l) return p end
+-- function lpeg.Cs (l) local p = lpcs (l) print("LPEG Cs =") lpprint(l) return p end
+-- function lpeg.Cc (l) local p = lpcc (l) print("LPEG Cc =") lpprint(l) return p end
+-- function lpeg.Cmt (l) local p = lpcmt (l) print("LPEG Cmt =") lpprint(l) return p end
+-- function lpeg.Carg (l) local p = lpcarg(l) print("LPEG Carg =") lpprint(l) return p end
+
+local type, next, tostring = type, next, tostring
+local byte, char, gmatch, format = string.byte, string.char, string.gmatch, string.format
+----- mod, div = math.mod, math.div
+local floor = math.floor
+
+local P, R, S, V, Ct, C, Cs, Cc, Cp, Cmt = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Cp, lpeg.Cmt
+local lpegtype, lpegmatch, lpegprint = lpeg.type, lpeg.match, lpeg.print
+
+-- let's start with an inspector:
+
+if setinspector then
+ setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
+end
+
+-- Beware, we predefine a bunch of patterns here and one reason for doing so
+-- is that we get consistent behaviour in some of the visualizers.
+
+lpeg.patterns = lpeg.patterns or { } -- so that we can share
+local patterns = lpeg.patterns
+
+local anything = P(1)
+local endofstring = P(-1)
+local alwaysmatched = P(true)
+
+patterns.anything = anything
+patterns.endofstring = endofstring
+patterns.beginofstring = alwaysmatched
+patterns.alwaysmatched = alwaysmatched
+
+local sign = S('+-')
+local zero = P('0')
+local digit = R('09')
+local digits = digit^1
+local octdigit = R("07")
+local octdigits = octdigit^1
+local lowercase = R("az")
+local uppercase = R("AZ")
+local underscore = P("_")
+local hexdigit = digit + lowercase + uppercase
+local hexdigits = hexdigit^1
+local cr, lf, crlf = P("\r"), P("\n"), P("\r\n")
+----- newline = crlf + S("\r\n") -- cr + lf
+local newline = P("\r") * (P("\n") + P(true)) + P("\n") -- P("\r")^-1 * P("\n")^-1
+local escaped = P("\\") * anything
+local squote = P("'")
+local dquote = P('"')
+local space = P(" ")
+local period = P(".")
+local comma = P(",")
+
+local utfbom_32_be = P('\000\000\254\255') -- 00 00 FE FF
+local utfbom_32_le = P('\255\254\000\000') -- FF FE 00 00
+local utfbom_16_be = P('\254\255') -- FE FF
+local utfbom_16_le = P('\255\254') -- FF FE
+local utfbom_8 = P('\239\187\191') -- EF BB BF
+local utfbom = utfbom_32_be + utfbom_32_le
+ + utfbom_16_be + utfbom_16_le
+ + utfbom_8
+local utftype = utfbom_32_be * Cc("utf-32-be") + utfbom_32_le * Cc("utf-32-le")
+ + utfbom_16_be * Cc("utf-16-be") + utfbom_16_le * Cc("utf-16-le")
+ + utfbom_8 * Cc("utf-8") + alwaysmatched * Cc("utf-8") -- assume utf8
+local utfstricttype = utfbom_32_be * Cc("utf-32-be") + utfbom_32_le * Cc("utf-32-le")
+ + utfbom_16_be * Cc("utf-16-be") + utfbom_16_le * Cc("utf-16-le")
+ + utfbom_8 * Cc("utf-8")
+local utfoffset = utfbom_32_be * Cc(4) + utfbom_32_le * Cc(4)
+ + utfbom_16_be * Cc(2) + utfbom_16_le * Cc(2)
+ + utfbom_8 * Cc(3) + Cc(0)
+
+local utf8next = R("\128\191")
+
+patterns.utfbom_32_be = utfbom_32_be
+patterns.utfbom_32_le = utfbom_32_le
+patterns.utfbom_16_be = utfbom_16_be
+patterns.utfbom_16_le = utfbom_16_le
+patterns.utfbom_8 = utfbom_8
+
+patterns.utf_16_be_nl = P("\000\r\000\n") + P("\000\r") + P("\000\n") -- P("\000\r") * (P("\000\n") + P(true)) + P("\000\n")
+patterns.utf_16_le_nl = P("\r\000\n\000") + P("\r\000") + P("\n\000") -- P("\r\000") * (P("\n\000") + P(true)) + P("\n\000")
+
+patterns.utf_32_be_nl = P("\000\000\000\r\000\000\000\n") + P("\000\000\000\r") + P("\000\000\000\n")
+patterns.utf_32_le_nl = P("\r\000\000\000\n\000\000\000") + P("\r\000\000\000") + P("\n\000\000\000")
+
+patterns.utf8one = R("\000\127")
+patterns.utf8two = R("\194\223") * utf8next
+patterns.utf8three = R("\224\239") * utf8next * utf8next
+patterns.utf8four = R("\240\244") * utf8next * utf8next * utf8next
+patterns.utfbom = utfbom
+patterns.utftype = utftype
+patterns.utfstricttype = utfstricttype
+patterns.utfoffset = utfoffset
+
+local utf8char = patterns.utf8one + patterns.utf8two + patterns.utf8three + patterns.utf8four
+local validutf8char = utf8char^0 * endofstring * Cc(true) + Cc(false)
+
+local utf8character = P(1) * R("\128\191")^0 -- unchecked but fast
+
+patterns.utf8 = utf8char
+patterns.utf8char = utf8char
+patterns.utf8character = utf8character -- this one can be used in most cases so we might use that one
+patterns.validutf8 = validutf8char
+patterns.validutf8char = validutf8char
+
+local eol = S("\n\r")
+local spacer = S(" \t\f\v") -- + char(0xc2, 0xa0) if we want utf (cf mail roberto)
+local whitespace = eol + spacer
+local nonspacer = 1 - spacer
+local nonwhitespace = 1 - whitespace
+
+patterns.eol = eol
+patterns.spacer = spacer
+patterns.whitespace = whitespace
+patterns.nonspacer = nonspacer
+patterns.nonwhitespace = nonwhitespace
+
+local stripper = spacer ^0 * C((spacer ^0 * nonspacer ^1)^0) -- from example by roberto
+local fullstripper = whitespace^0 * C((whitespace^0 * nonwhitespace^1)^0)
+
+----- collapser = Cs(spacer^0/"" * ((spacer^1 * endofstring / "") + (spacer^1/" ") + P(1))^0)
+local collapser = Cs(spacer^0/"" * nonspacer^0 * ((spacer^0/" " * nonspacer^1)^0))
+local nospacer = Cs((whitespace^1/"" + nonwhitespace^1)^0)
+
+local b_collapser = Cs( whitespace^0 /"" * (nonwhitespace^1 + whitespace^1/" ")^0)
+local e_collapser = Cs((whitespace^1 * endofstring/"" + nonwhitespace^1 + whitespace^1/" ")^0)
+local m_collapser = Cs( (nonwhitespace^1 + whitespace^1/" ")^0)
+
+local b_stripper = Cs( spacer^0 /"" * (nonspacer^1 + spacer^1/" ")^0)
+local e_stripper = Cs((spacer^1 * endofstring/"" + nonspacer^1 + spacer^1/" ")^0)
+local m_stripper = Cs( (nonspacer^1 + spacer^1/" ")^0)
+
+patterns.stripper = stripper
+patterns.fullstripper = fullstripper
+patterns.collapser = collapser
+patterns.nospacer = nospacer
+
+patterns.b_collapser = b_collapser
+patterns.m_collapser = m_collapser
+patterns.e_collapser = e_collapser
+
+patterns.b_stripper = b_stripper
+patterns.m_stripper = m_stripper
+patterns.e_stripper = e_stripper
+
+patterns.lowercase = lowercase
+patterns.uppercase = uppercase
+patterns.letter = patterns.lowercase + patterns.uppercase
+patterns.space = space
+patterns.tab = P("\t")
+patterns.spaceortab = patterns.space + patterns.tab
+patterns.newline = newline
+patterns.emptyline = newline^1
+patterns.equal = P("=")
+patterns.comma = comma
+patterns.commaspacer = comma * spacer^0
+patterns.period = period
+patterns.colon = P(":")
+patterns.semicolon = P(";")
+patterns.underscore = underscore
+patterns.escaped = escaped
+patterns.squote = squote
+patterns.dquote = dquote
+patterns.nosquote = (escaped + (1-squote))^0
+patterns.nodquote = (escaped + (1-dquote))^0
+patterns.unsingle = (squote/"") * patterns.nosquote * (squote/"") -- will change to C in the middle
+patterns.undouble = (dquote/"") * patterns.nodquote * (dquote/"") -- will change to C in the middle
+patterns.unquoted = patterns.undouble + patterns.unsingle -- more often undouble
+patterns.unspacer = ((patterns.spacer^1)/"")^0
+
+patterns.singlequoted = squote * patterns.nosquote * squote
+patterns.doublequoted = dquote * patterns.nodquote * dquote
+patterns.quoted = patterns.doublequoted + patterns.singlequoted
+
+patterns.digit = digit
+patterns.digits = digits
+patterns.octdigit = octdigit
+patterns.octdigits = octdigits
+patterns.hexdigit = hexdigit
+patterns.hexdigits = hexdigits
+patterns.sign = sign
+patterns.cardinal = digits
+patterns.integer = sign^-1 * digits
+patterns.unsigned = digit^0 * period * digits
+patterns.float = sign^-1 * patterns.unsigned
+patterns.cunsigned = digit^0 * comma * digits
+patterns.cpunsigned = digit^0 * (period + comma) * digits
+patterns.cfloat = sign^-1 * patterns.cunsigned
+patterns.cpfloat = sign^-1 * patterns.cpunsigned
+patterns.number = patterns.float + patterns.integer
+patterns.cnumber = patterns.cfloat + patterns.integer
+patterns.cpnumber = patterns.cpfloat + patterns.integer
+patterns.oct = zero * octdigits -- hm is this ok
+patterns.octal = patterns.oct
+patterns.HEX = zero * P("X") * (digit+uppercase)^1
+patterns.hex = zero * P("x") * (digit+lowercase)^1
+patterns.hexadecimal = zero * S("xX") * hexdigits
+
+patterns.hexafloat = sign^-1
+ * zero * S("xX")
+ * (hexdigit^0 * period * hexdigits + hexdigits * period * hexdigit^0 + hexdigits)
+ * (S("pP") * sign^-1 * hexdigits)^-1
+patterns.decafloat = sign^-1
+ * (digit^0 * period * digits + digits * period * digit^0 + digits)
+ * S("eE") * sign^-1 * digits
+
+patterns.propername = (uppercase + lowercase + underscore) * (uppercase + lowercase + underscore + digit)^0 * endofstring
+
+patterns.somecontent = (anything - newline - space)^1 -- (utf8char - newline - space)^1
+patterns.beginline = #(1-newline)
+
+patterns.longtostring = Cs(whitespace^0/"" * ((patterns.quoted + nonwhitespace^1 + whitespace^1/"" * (endofstring + Cc(" ")))^0))
+
+-- local function anywhere(pattern) -- slightly adapted from website
+-- return P { P(pattern) + 1 * V(1) }
+-- end
+
+function anywhere(pattern) -- faster
+ return (1-P(pattern))^0 * P(pattern)
+end
+
+lpeg.anywhere = anywhere
+
+function lpeg.instringchecker(p)
+ p = anywhere(p)
+ return function(str)
+ return lpegmatch(p,str) and true or false
+ end
+end
+
+-- function lpeg.splitter(pattern, action)
+-- return (((1-P(pattern))^1)/action+1)^0
+-- end
+
+-- function lpeg.tsplitter(pattern, action)
+-- return Ct((((1-P(pattern))^1)/action+1)^0)
+-- end
+
+function lpeg.splitter(pattern, action)
+ if action then
+ return (((1-P(pattern))^1)/action+1)^0
+ else
+ return (Cs((1-P(pattern))^1)+1)^0
+ end
+end
+
+function lpeg.tsplitter(pattern, action)
+ if action then
+ return Ct((((1-P(pattern))^1)/action+1)^0)
+ else
+ return Ct((Cs((1-P(pattern))^1)+1)^0)
+ end
+end
+
+-- probleem: separator can be lpeg and that does not hash too well, but
+-- it's quite okay as the key is then not garbage collected
+
+local splitters_s, splitters_m, splitters_t = { }, { }, { }
+
+local function splitat(separator,single)
+ local splitter = (single and splitters_s[separator]) or splitters_m[separator]
+ if not splitter then
+ separator = P(separator)
+ local other = C((1 - separator)^0)
+ if single then
+ local any = anything
+ splitter = other * (separator * C(any^0) + "") -- ?
+ splitters_s[separator] = splitter
+ else
+ splitter = other * (separator * other)^0
+ splitters_m[separator] = splitter
+ end
+ end
+ return splitter
+end
+
+local function tsplitat(separator)
+ local splitter = splitters_t[separator]
+ if not splitter then
+ splitter = Ct(splitat(separator))
+ splitters_t[separator] = splitter
+ end
+ return splitter
+end
+
+lpeg.splitat = splitat
+lpeg.tsplitat = tsplitat
+
+function string.splitup(str,separator)
+ if not separator then
+ separator = ","
+ end
+ return lpegmatch(splitters_m[separator] or splitat(separator),str)
+end
+
+-- local p = splitat("->",false) print(lpegmatch(p,"oeps->what->more")) -- oeps what more
+-- local p = splitat("->",true) print(lpegmatch(p,"oeps->what->more")) -- oeps what->more
+-- local p = splitat("->",false) print(lpegmatch(p,"oeps")) -- oeps
+-- local p = splitat("->",true) print(lpegmatch(p,"oeps")) -- oeps
+
+local cache = { }
+
+function lpeg.split(separator,str)
+ local c = cache[separator]
+ if not c then
+ c = tsplitat(separator)
+ cache[separator] = c
+ end
+ return lpegmatch(c,str)
+end
+
+function string.split(str,separator)
+ if separator then
+ local c = cache[separator]
+ if not c then
+ c = tsplitat(separator)
+ cache[separator] = c
+ end
+ return lpegmatch(c,str)
+ else
+ return { str }
+ end
+end
+
+local spacing = patterns.spacer^0 * newline -- sort of strip
+local empty = spacing * Cc("")
+local nonempty = Cs((1-spacing)^1) * spacing^-1
+local content = (empty + nonempty)^1
+
+patterns.textline = content
+
+local linesplitter = tsplitat(newline)
+
+patterns.linesplitter = linesplitter
+
+function string.splitlines(str)
+ return lpegmatch(linesplitter,str)
+end
+
+-- lpeg.splitters = cache -- no longer public
+
+local cache = { }
+
+function lpeg.checkedsplit(separator,str)
+ local c = cache[separator]
+ if not c then
+ separator = P(separator)
+ local other = C((1 - separator)^1)
+ c = Ct(separator^0 * other * (separator^1 * other)^0)
+ cache[separator] = c
+ end
+ return lpegmatch(c,str)
+end
+
+function string.checkedsplit(str,separator)
+ local c = cache[separator]
+ if not c then
+ separator = P(separator)
+ local other = C((1 - separator)^1)
+ c = Ct(separator^0 * other * (separator^1 * other)^0)
+ cache[separator] = c
+ end
+ return lpegmatch(c,str)
+end
+
+-- from roberto's site:
+
+local function f2(s) local c1, c2 = byte(s,1,2) return c1 * 64 + c2 - 12416 end
+local function f3(s) local c1, c2, c3 = byte(s,1,3) return (c1 * 64 + c2) * 64 + c3 - 925824 end
+local function f4(s) local c1, c2, c3, c4 = byte(s,1,4) return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168 end
+
+local utf8byte = patterns.utf8one/byte + patterns.utf8two/f2 + patterns.utf8three/f3 + patterns.utf8four/f4
+
+patterns.utf8byte = utf8byte
+
+--~ local str = " a b c d "
+
+--~ local s = lpeg.stripper(lpeg.R("az")) print("["..lpegmatch(s,str).."]")
+--~ local s = lpeg.keeper(lpeg.R("az")) print("["..lpegmatch(s,str).."]")
+--~ local s = lpeg.stripper("ab") print("["..lpegmatch(s,str).."]")
+--~ local s = lpeg.keeper("ab") print("["..lpegmatch(s,str).."]")
+
+local cache = { }
+
+function lpeg.stripper(str)
+ if type(str) == "string" then
+ local s = cache[str]
+ if not s then
+ s = Cs(((S(str)^1)/"" + 1)^0)
+ cache[str] = s
+ end
+ return s
+ else
+ return Cs(((str^1)/"" + 1)^0)
+ end
+end
+
+local cache = { }
+
+function lpeg.keeper(str)
+ if type(str) == "string" then
+ local s = cache[str]
+ if not s then
+ s = Cs((((1-S(str))^1)/"" + 1)^0)
+ cache[str] = s
+ end
+ return s
+ else
+ return Cs((((1-str)^1)/"" + 1)^0)
+ end
+end
+
+function lpeg.frontstripper(str) -- or pattern (yet undocumented)
+ return (P(str) + P(true)) * Cs(anything^0)
+end
+
+function lpeg.endstripper(str) -- or pattern (yet undocumented)
+ return Cs((1 - P(str) * endofstring)^0)
+end
+
+-- Just for fun I looked at the used bytecode and
+-- p = (p and p + pp) or pp gets one more (testset).
+
+-- todo: cache when string
+
+function lpeg.replacer(one,two,makefunction,isutf) -- in principle we should sort the keys
+ local pattern
+ local u = isutf and utf8char or 1
+ if type(one) == "table" then
+ local no = #one
+ local p = P(false)
+ if no == 0 then
+ for k, v in next, one do
+ p = p + P(k) / v
+ end
+ pattern = Cs((p + u)^0)
+ elseif no == 1 then
+ local o = one[1]
+ one, two = P(o[1]), o[2]
+ -- pattern = Cs(((1-one)^1 + one/two)^0)
+ pattern = Cs((one/two + u)^0)
+ else
+ for i=1,no do
+ local o = one[i]
+ p = p + P(o[1]) / o[2]
+ end
+ pattern = Cs((p + u)^0)
+ end
+ else
+ pattern = Cs((P(one)/(two or "") + u)^0)
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
+ end
+ else
+ return pattern
+ end
+end
+
+-- local pattern1 = P(1-P(pattern))^0 * P(pattern) : test for not nil
+-- local pattern2 = (P(pattern) * Cc(true) + P(1))^0 : test for true (could be faster, but not much)
+
+function lpeg.finder(lst,makefunction,isutf) -- beware: slower than find with 'patternless finds'
+ local pattern
+ if type(lst) == "table" then
+ pattern = P(false)
+ if #lst == 0 then
+ for k, v in next, lst do
+ pattern = pattern + P(k) -- ignore key, so we can use a replacer table
+ end
+ else
+ for i=1,#lst do
+ pattern = pattern + P(lst[i])
+ end
+ end
+ else
+ pattern = P(lst)
+ end
+ if isutf then
+ pattern = ((utf8char or 1)-pattern)^0 * pattern
+ else
+ pattern = (1-pattern)^0 * pattern
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
+ end
+ else
+ return pattern
+ end
+end
+
+-- print(lpeg.match(lpeg.replacer("e","a"),"test test"))
+-- print(lpeg.match(lpeg.replacer{{"e","a"}},"test test"))
+-- print(lpeg.match(lpeg.replacer({ e = "a", t = "x" }),"test test"))
+
+local splitters_f, splitters_s = { }, { }
+
+function lpeg.firstofsplit(separator) -- always return value
+ local splitter = splitters_f[separator]
+ if not splitter then
+ local pattern = P(separator)
+ splitter = C((1 - pattern)^0)
+ splitters_f[separator] = splitter
+ end
+ return splitter
+end
+
+function lpeg.secondofsplit(separator) -- nil if not split
+ local splitter = splitters_s[separator]
+ if not splitter then
+ local pattern = P(separator)
+ splitter = (1 - pattern)^0 * pattern * C(anything^0)
+ splitters_s[separator] = splitter
+ end
+ return splitter
+end
+
+local splitters_s, splitters_p = { }, { }
+
+function lpeg.beforesuffix(separator) -- nil if nothing but empty is ok
+ local splitter = splitters_s[separator]
+ if not splitter then
+ local pattern = P(separator)
+ splitter = C((1 - pattern)^0) * pattern * endofstring
+ splitters_s[separator] = splitter
+ end
+ return splitter
+end
+
+function lpeg.afterprefix(separator) -- nil if nothing but empty is ok
+ local splitter = splitters_p[separator]
+ if not splitter then
+ local pattern = P(separator)
+ splitter = pattern * C(anything^0)
+ splitters_p[separator] = splitter
+ end
+ return splitter
+end
+
+function lpeg.balancer(left,right)
+ left, right = P(left), P(right)
+ return P { left * ((1 - left - right) + V(1))^0 * right }
+end
+
+-- print(1,lpegmatch(lpeg.firstofsplit(":"),"bc:de"))
+-- print(2,lpegmatch(lpeg.firstofsplit(":"),":de")) -- empty
+-- print(3,lpegmatch(lpeg.firstofsplit(":"),"bc"))
+-- print(4,lpegmatch(lpeg.secondofsplit(":"),"bc:de"))
+-- print(5,lpegmatch(lpeg.secondofsplit(":"),"bc:")) -- empty
+-- print(6,lpegmatch(lpeg.secondofsplit(":",""),"bc"))
+-- print(7,lpegmatch(lpeg.secondofsplit(":"),"bc"))
+-- print(9,lpegmatch(lpeg.secondofsplit(":","123"),"bc"))
+
+-- this was slower but lpeg has been sped up in the meantime, so we no longer
+-- use this (still seems somewhat faster on long strings)
+--
+-- local nany = utf8char/""
+--
+-- function lpeg.counter(pattern)
+-- pattern = Cs((P(pattern)/" " + nany)^0)
+-- return function(str)
+-- return #lpegmatch(pattern,str)
+-- end
+-- end
+
+function lpeg.counter(pattern,action)
+ local n = 0
+ local pattern = (P(pattern) / function() n = n + 1 end + anything)^0
+ ----- pattern = (P(pattern) * (P(true) / function() n = n + 1 end) + anything)^0
+ ----- pattern = (P(pattern) * P(function() n = n + 1 end) + anything)^0
+ if action then
+ return function(str) n = 0 ; lpegmatch(pattern,str) ; action(n) end
+ else
+ return function(str) n = 0 ; lpegmatch(pattern,str) ; return n end
+ end
+end
+
+-- lpeg.print(lpeg.R("ab","cd","gh"))
+-- lpeg.print(lpeg.P("a","b","c"))
+-- lpeg.print(lpeg.S("a","b","c"))
+
+-- print(lpeg.count("äáàa",lpeg.P("á") + lpeg.P("à")))
+-- print(lpeg.count("äáàa",lpeg.UP("áà")))
+-- print(lpeg.count("äáàa",lpeg.US("àá")))
+-- print(lpeg.count("äáàa",lpeg.UR("aá")))
+-- print(lpeg.count("äáàa",lpeg.UR("àá")))
+-- print(lpeg.count("äáàa",lpeg.UR(0x0000,0xFFFF)))
+
+function lpeg.is_lpeg(p)
+ return p and lpegtype(p) == "pattern"
+end
+
+function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then") -- assume proper order
+ if type(list) ~= "table" then
+ list = { list, ... }
+ end
+ -- table.sort(list) -- longest match first
+ local p = P(list[1])
+ for l=2,#list do
+ p = p + P(list[l])
+ end
+ return p
+end
+
+-- For the moment here, but it might move to utilities. Beware, we need to
+-- have the longest keyword first, so 'aaa' comes beforte 'aa' which is why we
+-- loop back from the end cq. prepend.
+
+local sort = table.sort
+
+local function copyindexed(old)
+ local new = { }
+ for i=1,#old do
+ new[i] = old
+ end
+ return new
+end
+
+local function sortedkeys(tab)
+ local keys, s = { }, 0
+ for key,_ in next, tab do
+ s = s + 1
+ keys[s] = key
+ end
+ sort(keys)
+ return keys
+end
+
+function lpeg.append(list,pp,delayed,checked)
+ local p = pp
+ if #list > 0 then
+ local keys = copyindexed(list)
+ sort(keys)
+ for i=#keys,1,-1 do
+ local k = keys[i]
+ if p then
+ p = P(k) + p
+ else
+ p = P(k)
+ end
+ end
+ elseif delayed then -- hm, it looks like the lpeg parser resolves anyway
+ local keys = sortedkeys(list)
+ if p then
+ for i=1,#keys,1 do
+ local k = keys[i]
+ local v = list[k]
+ p = P(k)/list + p
+ end
+ else
+ for i=1,#keys do
+ local k = keys[i]
+ local v = list[k]
+ if p then
+ p = P(k) + p
+ else
+ p = P(k)
+ end
+ end
+ if p then
+ p = p / list
+ end
+ end
+ elseif checked then
+ -- problem: substitution gives a capture
+ local keys = sortedkeys(list)
+ for i=1,#keys do
+ local k = keys[i]
+ local v = list[k]
+ if p then
+ if k == v then
+ p = P(k) + p
+ else
+ p = P(k)/v + p
+ end
+ else
+ if k == v then
+ p = P(k)
+ else
+ p = P(k)/v
+ end
+ end
+ end
+ else
+ local keys = sortedkeys(list)
+ for i=1,#keys do
+ local k = keys[i]
+ local v = list[k]
+ if p then
+ p = P(k)/v + p
+ else
+ p = P(k)/v
+ end
+ end
+ end
+ return p
+end
+
+-- inspect(lpeg.append({ a = "1", aa = "1", aaa = "1" } ,nil,true))
+-- inspect(lpeg.append({ ["degree celsius"] = "1", celsius = "1", degree = "1" } ,nil,true))
+
+-- function lpeg.exact_match(words,case_insensitive)
+-- local pattern = concat(words)
+-- if case_insensitive then
+-- local pattern = S(upper(characters)) + S(lower(characters))
+-- local list = { }
+-- for i=1,#words do
+-- list[lower(words[i])] = true
+-- end
+-- return Cmt(pattern^1, function(_,i,s)
+-- return list[lower(s)] and i
+-- end)
+-- else
+-- local pattern = S(concat(words))
+-- local list = { }
+-- for i=1,#words do
+-- list[words[i]] = true
+-- end
+-- return Cmt(pattern^1, function(_,i,s)
+-- return list[s] and i
+-- end)
+-- end
+-- end
+
+-- experiment:
+
+local p_false = P(false)
+local p_true = P(true)
+
+-- local function collapse(t,x)
+-- if type(t) ~= "table" then
+-- return t, x
+-- else
+-- local n = next(t)
+-- if n == nil then
+-- return t, x
+-- elseif next(t,n) == nil then
+-- -- one entry
+-- local k = n
+-- local v = t[k]
+-- if type(v) == "table" then
+-- return collapse(v,x..k)
+-- else
+-- return v, x .. k
+-- end
+-- else
+-- local tt = { }
+-- for k, v in next, t do
+-- local vv, kk = collapse(v,k)
+-- tt[kk] = vv
+-- end
+-- return tt, x
+-- end
+-- end
+-- end
+
+local lower = utf and utf.lower or string.lower
+local upper = utf and utf.upper or string.upper
+
+function lpeg.setutfcasers(l,u)
+ lower = l or lower
+ upper = u or upper
+end
+
+local function make1(t,rest)
+ local p = p_false
+ local keys = sortedkeys(t)
+ for i=1,#keys do
+ local k = keys[i]
+ if k ~= "" then
+ local v = t[k]
+ if v == true then
+ p = p + P(k) * p_true
+ elseif v == false then
+ -- can't happen
+ else
+ p = p + P(k) * make1(v,v[""])
+ end
+ end
+ end
+ if rest then
+ p = p + p_true
+ end
+ return p
+end
+
+local function make2(t,rest) -- only ascii
+ local p = p_false
+ local keys = sortedkeys(t)
+ for i=1,#keys do
+ local k = keys[i]
+ if k ~= "" then
+ local v = t[k]
+ if v == true then
+ p = p + (P(lower(k))+P(upper(k))) * p_true
+ elseif v == false then
+ -- can't happen
+ else
+ p = p + (P(lower(k))+P(upper(k))) * make2(v,v[""])
+ end
+ end
+ end
+ if rest then
+ p = p + p_true
+ end
+ return p
+end
+
+local function utfchartabletopattern(list,insensitive) -- goes to util-lpg
+ local tree = { }
+ local n = #list
+ if n == 0 then
+ for s in next, list do
+ local t = tree
+ local p, pk
+ for c in gmatch(s,".") do
+ if t == true then
+ t = { [c] = true, [""] = true }
+ p[pk] = t
+ p = t
+ t = false
+ elseif t == false then
+ t = { [c] = false }
+ p[pk] = t
+ p = t
+ t = false
+ else
+ local tc = t[c]
+ if not tc then
+ tc = false
+ t[c] = false
+ end
+ p = t
+ t = tc
+ end
+ pk = c
+ end
+ if t == false then
+ p[pk] = true
+ elseif t == true then
+ -- okay
+ else
+ t[""] = true
+ end
+ end
+ else
+ for i=1,n do
+ local s = list[i]
+ local t = tree
+ local p, pk
+ for c in gmatch(s,".") do
+ if t == true then
+ t = { [c] = true, [""] = true }
+ p[pk] = t
+ p = t
+ t = false
+ elseif t == false then
+ t = { [c] = false }
+ p[pk] = t
+ p = t
+ t = false
+ else
+ local tc = t[c]
+ if not tc then
+ tc = false
+ t[c] = false
+ end
+ p = t
+ t = tc
+ end
+ pk = c
+ end
+ if t == false then
+ p[pk] = true
+ elseif t == true then
+ -- okay
+ else
+ t[""] = true
+ end
+ end
+ end
+ -- collapse(tree,"") -- needs testing, maybe optional, slightly faster because P("x")*P("X") seems slower than P"(xX") (why)
+ -- inspect(tree)
+ return (insensitive and make2 or make1)(tree)
+end
+
+lpeg.utfchartabletopattern = utfchartabletopattern
+
+function lpeg.utfreplacer(list,insensitive)
+ local pattern = Cs((utfchartabletopattern(list,insensitive)/list + utf8character)^0)
+ return function(str)
+ return lpegmatch(pattern,str) or str
+ end
+end
+
+-- local t = { "start", "stoep", "staart", "paard" }
+-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1)
+
+-- local t = { "a", "abc", "ac", "abe", "abxyz", "xy", "bef","aa" }
+-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1)
+
+-- inspect(lpegmatch(p,"a")=="A")
+-- inspect(lpegmatch(p,"aa")=="AA")
+-- inspect(lpegmatch(p,"aaaa")=="AAAA")
+-- inspect(lpegmatch(p,"ac")=="AC")
+-- inspect(lpegmatch(p,"bc")=="bc")
+-- inspect(lpegmatch(p,"zzbczz")=="zzbczz")
+-- inspect(lpegmatch(p,"zzabezz")=="zzABEzz")
+-- inspect(lpegmatch(p,"ab")=="Ab")
+-- inspect(lpegmatch(p,"abc")=="ABC")
+-- inspect(lpegmatch(p,"abe")=="ABE")
+-- inspect(lpegmatch(p,"xa")=="xA")
+-- inspect(lpegmatch(p,"bx")=="bx")
+-- inspect(lpegmatch(p,"bax")=="bAx")
+-- inspect(lpegmatch(p,"abxyz")=="ABXYZ")
+-- inspect(lpegmatch(p,"foobarbefcrap")=="foobArBEFcrAp")
+
+-- local t = { ["^"] = 1, ["^^"] = 2, ["^^^"] = 3, ["^^^^"] = 4 }
+-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/t + 1)^1)
+-- inspect(lpegmatch(p," ^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^ ^^^^^^^ "))
+
+-- local t = { ["^^"] = 2, ["^^^"] = 3, ["^^^^"] = 4 }
+-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/t + 1)^1)
+-- inspect(lpegmatch(p," ^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^ ^^^^^^^ "))
+
+-- lpeg.utfchartabletopattern {
+-- utfchar(0x00A0), -- nbsp
+-- utfchar(0x2000), -- enquad
+-- utfchar(0x2001), -- emquad
+-- utfchar(0x2002), -- enspace
+-- utfchar(0x2003), -- emspace
+-- utfchar(0x2004), -- threeperemspace
+-- utfchar(0x2005), -- fourperemspace
+-- utfchar(0x2006), -- sixperemspace
+-- utfchar(0x2007), -- figurespace
+-- utfchar(0x2008), -- punctuationspace
+-- utfchar(0x2009), -- breakablethinspace
+-- utfchar(0x200A), -- hairspace
+-- utfchar(0x200B), -- zerowidthspace
+-- utfchar(0x202F), -- narrownobreakspace
+-- utfchar(0x205F), -- math thinspace
+-- }
+
+-- a few handy ones:
+--
+-- faster than find(str,"[\n\r]") when match and # > 7 and always faster when # > 3
+
+patterns.containseol = lpeg.finder(eol) -- (1-eol)^0 * eol
+
+-- The next pattern^n variant is based on an approach suggested
+-- by Roberto: constructing a big repetition in chunks.
+--
+-- Being sparse is not needed, and only complicate matters and
+-- the number of redundant entries is not that large.
+
+local function nextstep(n,step,result)
+ local m = n % step -- mod(n,step)
+ local d = floor(n/step) -- div(n,step)
+ if d > 0 then
+ local v = V(tostring(step))
+ local s = result.start
+ for i=1,d do
+ if s then
+ s = v * s
+ else
+ s = v
+ end
+ end
+ result.start = s
+ end
+ if step > 1 and result.start then
+ local v = V(tostring(step/2))
+ result[tostring(step)] = v * v
+ end
+ if step > 0 then
+ return nextstep(m,step/2,result)
+ else
+ return result
+ end
+end
+
+function lpeg.times(pattern,n)
+ return P(nextstep(n,2^16,{ "start", ["1"] = pattern }))
+end
+
+-- local p = lpeg.Cs((1 - lpeg.times(lpeg.P("AB"),25))^1)
+-- local s = "12" .. string.rep("AB",20) .. "34" .. string.rep("AB",30) .. "56"
+-- inspect(p)
+-- print(lpeg.match(p,s))
+
+-- moved here (before util-str)
+
+do
+
+ local trailingzeros = zero^0 * -digit -- suggested by Roberto
+ local stripper = Cs((
+ digits * (
+ period * trailingzeros / ""
+ + period * (digit - trailingzeros)^1 * (trailingzeros / "")
+ ) + 1
+ )^0)
+
+ lpeg.patterns.stripzeros = stripper -- multiple in string
+
+ local nonzero = digit - zero
+ local trailingzeros = zero^1 * endofstring
+ local stripper = Cs( (1-period)^0 * (
+ period * trailingzeros/""
+ + period * (nonzero^1 + (trailingzeros/"") + zero^1)^0
+ + endofstring
+ ))
+
+ lpeg.patterns.stripzero = stripper -- slightly more efficient but expects a float !
+
+ -- local sample = "bla 11.00 bla 11 bla 0.1100 bla 1.00100 bla 0.00 bla 0.001 bla 1.1100 bla 0.100100100 bla 0.00100100100"
+ -- collectgarbage("collect")
+ -- str = string.rep(sample,10000)
+ -- local ts = os.clock()
+ -- lpegmatch(stripper,str)
+ -- print(#str, os.clock()-ts, lpegmatch(stripper,sample))
+
+end
+
+-- for practical reasons we keep this here:
+
+local byte_to_HEX = { }
+local byte_to_hex = { }
+local byte_to_dec = { } -- for md5
+local hex_to_byte = { }
+
+for i=0,255 do
+ local H = format("%02X",i)
+ local h = format("%02x",i)
+ local d = format("%03i",i)
+ local c = char(i)
+ byte_to_HEX[c] = H
+ byte_to_hex[c] = h
+ byte_to_dec[c] = d
+ hex_to_byte[h] = c
+ hex_to_byte[H] = c
+end
+
+local hextobyte = P(2)/hex_to_byte
+local bytetoHEX = P(1)/byte_to_HEX
+local bytetohex = P(1)/byte_to_hex
+local bytetodec = P(1)/byte_to_dec
+local hextobytes = Cs(hextobyte^0)
+local bytestoHEX = Cs(bytetoHEX^0)
+local bytestohex = Cs(bytetohex^0)
+local bytestodec = Cs(bytetodec^0)
+
+patterns.hextobyte = hextobyte
+patterns.bytetoHEX = bytetoHEX
+patterns.bytetohex = bytetohex
+patterns.bytetodec = bytetodec
+patterns.hextobytes = hextobytes
+patterns.bytestoHEX = bytestoHEX
+patterns.bytestohex = bytestohex
+patterns.bytestodec = bytestodec
+
+function string.toHEX(s)
+ if not s or s == "" then
+ return s
+ else
+ return lpegmatch(bytestoHEX,s)
+ end
+end
+
+function string.tohex(s)
+ if not s or s == "" then
+ return s
+ else
+ return lpegmatch(bytestohex,s)
+ end
+end
+
+function string.todec(s)
+ if not s or s == "" then
+ return s
+ else
+ return lpegmatch(bytestodec,s)
+ end
+end
+
+function string.tobytes(s)
+ if not s or s == "" then
+ return s
+ else
+ return lpegmatch(hextobytes,s)
+ end
+end
+
+-- local h = "ADFE0345"
+-- local b = lpegmatch(patterns.hextobytes,h)
+-- print(h,b,string.tohex(b),string.toHEX(b))
+
+local patterns = { } -- can be made weak
+
+local function containsws(what)
+ local p = patterns[what]
+ if not p then
+ local p1 = P(what) * (whitespace + endofstring) * Cc(true)
+ local p2 = whitespace * P(p1)
+ p = P(p1) + P(1-p2)^0 * p2 + Cc(false)
+ patterns[what] = p
+ end
+ return p
+end
+
+lpeg.containsws = containsws
+
+function string.containsws(str,what)
+ return lpegmatch(patterns[what] or containsws(what),str)
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-lua.lua b/macros/luatex/generic/luaotfload/fontloader-l-lua.lua
new file mode 100644
index 0000000000..6e9606e849
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-l-lua.lua
@@ -0,0 +1,259 @@
+if not modules then modules = { } end modules ['l-lua'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- potential issues with 5.3:
+
+-- i'm not sure yet if the int/float change is good for luatex
+
+-- math.min
+-- math.max
+-- tostring
+-- tonumber
+-- utf.*
+-- bit32
+
+local next, type, tonumber = next, type, tonumber
+
+-- compatibility hacks and helpers
+
+LUAMAJORVERSION, LUAMINORVERSION = string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
+
+LUAMAJORVERSION = tonumber(LUAMAJORVERSION) or 5
+LUAMINORVERSION = tonumber(LUAMINORVERSION) or 1
+LUAVERSION = LUAMAJORVERSION + LUAMINORVERSION/10
+
+if LUAVERSION < 5.2 and jit then
+ --
+ -- we want loadstring cum suis to behave like 5.2
+ --
+ MINORVERSION = 2
+ LUAVERSION = 5.2
+end
+
+-- lpeg
+
+if not lpeg then
+ lpeg = require("lpeg")
+end
+
+-- if utf8 then
+-- utf8lua = utf8
+-- utf8 = nil
+-- end
+
+-- basics:
+
+if loadstring then
+
+ local loadnormal = load
+
+ function load(first,...)
+ if type(first) == "string" then
+ return loadstring(first,...)
+ else
+ return loadnormal(first,...)
+ end
+ end
+
+else
+
+ loadstring = load
+
+end
+
+-- table:
+
+-- At some point it was announced that i[pairs would be dropped, which makes
+-- sense. As we already used the for loop and # in most places the impact on
+-- ConTeXt was not that large; the remaining ipairs already have been replaced.
+-- Hm, actually ipairs was retained, but we no longer use it anyway (nor
+-- pairs).
+--
+-- Just in case, we provide the fallbacks as discussed in Programming
+-- in Lua (http://www.lua.org/pil/7.3.html):
+
+if not ipairs then
+
+ -- for k, v in ipairs(t) do ... end
+ -- for k=1,#t do local v = t[k] ... end
+
+ local function iterate(a,i)
+ i = i + 1
+ local v = a[i]
+ if v ~= nil then
+ return i, v --, nil
+ end
+ end
+
+ function ipairs(a)
+ return iterate, a, 0
+ end
+
+end
+
+if not pairs then
+
+ -- for k, v in pairs(t) do ... end
+ -- for k, v in next, t do ... end
+
+ function pairs(t)
+ return next, t -- , nil
+ end
+
+end
+
+-- The unpack function has been moved to the table table, and for compatiility
+-- reasons we provide both now.
+
+if not table.unpack then
+
+ table.unpack = _G.unpack
+
+elseif not unpack then
+
+ _G.unpack = table.unpack
+
+end
+
+-- package:
+
+-- if not package.seachers then
+--
+-- package.searchers = package.loaders -- 5.2
+--
+-- elseif not package.loaders then
+--
+-- package.loaders = package.searchers
+--
+-- end
+
+if not package.loaders then -- brr, searchers is a special "loadlib function" userdata type
+
+ package.loaders = package.searchers
+
+end
+
+-- moved from util-deb to here:
+
+local print, select, tostring = print, select, tostring
+
+local inspectors = { }
+
+function setinspector(kind,inspector) -- global function
+ inspectors[kind] = inspector
+end
+
+function inspect(...) -- global function
+ for s=1,select("#",...) do
+ local value = select(s,...)
+ if value == nil then
+ print("nil")
+ else
+ local done = false
+ -- type driven (table)
+ local kind = type(value)
+ local inspector = inspectors[kind]
+ if inspector then
+ done = inspector(value)
+ if done then
+ break
+ end
+ end
+ -- whatever driven (token, node, ...)
+ for kind, inspector in next, inspectors do
+ done = inspector(value)
+ if done then
+ break
+ end
+ end
+ if not done then
+ print(tostring(value))
+ end
+ end
+ end
+end
+
+--
+
+local dummy = function() end
+
+function optionalrequire(...)
+ local ok, result = xpcall(require,dummy,...)
+ if ok then
+ return result
+ end
+end
+
+-- nice for non ascii scripts (this might move):
+
+if lua then
+ lua.mask = load([[τεχ = 1]]) and "utf" or "ascii"
+end
+
+local flush = io.flush
+
+if flush then
+
+ local execute = os.execute if execute then function os.execute(...) flush() return execute(...) end end
+ local exec = os.exec if exec then function os.exec (...) flush() return exec (...) end end
+ local spawn = os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
+ local popen = io.popen if popen then function io.popen (...) flush() return popen (...) end end
+
+end
+
+-- new
+
+FFISUPPORTED = type(ffi) == "table" and ffi.os ~= "" and ffi.arch ~= "" and ffi.load
+
+if not FFISUPPORTED then
+
+ -- Maybe we should check for LUATEXENGINE but that's also a bit tricky as we still
+ -- can have a weird ffi library laying around. Checking for presence of 'jit' is
+ -- also not robust. So for now we hope for the best.
+
+ local okay ; okay, ffi = pcall(require,"ffi")
+
+ FFISUPPORTED = type(ffi) == "table" and ffi.os ~= "" and ffi.arch ~= "" and ffi.load
+
+end
+
+if not FFISUPPORTED then
+ ffi = nil
+elseif not ffi.number then
+ ffi.number = tonumber
+end
+
+-- if not bit32 then -- and utf8 then
+-- -- bit32 = load ( [[ -- replacement code with 5.3 syntax so that 5.2 doesn't bark on it ]] )
+-- bit32 = require("l-bit32")
+-- end
+
+-- We need this due a bug in luatex socket loading:
+
+-- local loaded = package.loaded
+--
+-- if not loaded["socket"] then loaded["socket"] = loaded["socket.core"] end
+-- if not loaded["mime"] then loaded["mime"] = loaded["mime.core"] end
+--
+-- if not socket.mime then socket.mime = package.loaded["mime"] end
+--
+-- if not loaded["socket.mime"] then loaded["socket.mime"] = socket.mime end
+-- if not loaded["socket.http"] then loaded["socket.http"] = socket.http end
+-- if not loaded["socket.ftp"] then loaded["socket.ftp"] = socket.ftp end
+-- if not loaded["socket.smtp"] then loaded["socket.smtp"] = socket.smtp end
+-- if not loaded["socket.tp"] then loaded["socket.tp"] = socket.tp end
+-- if not loaded["socket.url"] then loaded["socket.url"] = socket.url end
+
+if LUAVERSION > 5.3 then
+ -- collectgarbage("collect")
+ -- collectgarbage("generational") -- crashes on unix
+end
+
+if status and os.setenv then
+ os.setenv("engine",string.lower(status.luatex_engine or "unknown"))
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-math.lua b/macros/luatex/generic/luaotfload/fontloader-l-math.lua
new file mode 100644
index 0000000000..e5668a5db0
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-l-math.lua
@@ -0,0 +1,149 @@
+if not modules then modules = { } end modules ['l-math'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+if not math.ceiling then
+
+ math.ceiling = math.ceil
+
+end
+
+if not math.round then
+
+ local floor = math.floor
+
+ function math.round(x) return floor(x + 0.5) end
+
+end
+
+if not math.div then
+
+ local floor = math.floor
+
+ function math.div(n,m) return floor(n/m) end
+
+end
+
+if not math.mod then
+
+ function math.mod(n,m) return n % m end
+
+end
+
+if not math.sind then
+
+ local sin, cos, tan = math.sin, math.cos, math.tan
+
+ local pipi = 2*math.pi/360
+
+ function math.sind(d) return sin(d*pipi) end
+ function math.cosd(d) return cos(d*pipi) end
+ function math.tand(d) return tan(d*pipi) end
+
+end
+
+if not math.odd then
+
+ function math.odd (n) return n % 2 ~= 0 end
+ function math.even(n) return n % 2 == 0 end
+
+end
+
+if not math.cosh then
+
+ local exp = math.exp
+
+ function math.cosh(x)
+ local xx = exp(x)
+ return (xx+1/xx)/2
+ end
+ function math.sinh(x)
+ local xx = exp(x)
+ return (xx-1/xx)/2
+ end
+ function math.tanh(x)
+ local xx = exp(x)
+ return (xx-1/xx)/(xx+1/xx)
+ end
+
+end
+
+if not math.pow then
+
+ function math.pow(x,y)
+ return x^y
+ end
+
+end
+
+if not math.atan2 then
+
+ math.atan2 = math.atan
+
+end
+
+if not math.ldexp then
+
+ function math.ldexp(x,e)
+ return x * 2.0^e
+ end
+
+end
+
+-- if not math.frexp then
+--
+-- -- not a oneliner so use a math library instead
+--
+-- function math.frexp(x,e)
+-- -- returns m and e such that x = m2e, e is an integer and the absolute
+-- -- value of m is in the range [0.5, 1) (or zero when x is zero)
+-- end
+--
+-- end
+
+if not math.log10 then
+
+ local log = math.log
+
+ function math.log10(x)
+ return log(x,10)
+ end
+
+end
+
+if not math.type then
+
+ function math.type()
+ return "float"
+ end
+
+end
+
+if not math.tointeger then
+
+ math.mininteger = -0x4FFFFFFFFFFF
+ math.maxinteger = 0x4FFFFFFFFFFF
+
+ local floor = math.floor
+
+ function math.tointeger(n)
+ local f = floor(n)
+ return f == n and f or nil
+ end
+
+end
+
+if not math.ult then
+
+ local floor = math.floor
+
+ function math.tointeger(m,n)
+ -- not ok but i'm not motivated to look into it now
+ return floor(m) < floor(n) -- unsigned comparison needed
+ end
+
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-string.lua b/macros/luatex/generic/luaotfload/fontloader-l-string.lua
new file mode 100644
index 0000000000..1dee85e289
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-l-string.lua
@@ -0,0 +1,244 @@
+if not modules then modules = { } end modules ['l-string'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local string = string
+local sub, gmatch, format, char, byte, rep, lower = string.sub, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower
+local lpegmatch, patterns = lpeg.match, lpeg.patterns
+local P, S, C, Ct, Cc, Cs = lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cs
+
+-- Some functions are already defined in l-lpeg and maybe some from here will
+-- move there (unless we also expose caches).
+
+-- if not string.split then
+--
+-- function string.split(str,pattern)
+-- local t = { }
+-- if str ~= "" then
+-- local n = 1
+-- for s in gmatch(str..pattern,"(.-)"..pattern) do
+-- t[n] = s
+-- n = n + 1
+-- end
+-- end
+-- return t
+-- end
+--
+-- end
+
+-- function string.unquoted(str)
+-- return (gsub(str,"^([\"\'])(.*)%1$","%2")) -- interesting pattern
+-- end
+
+local unquoted = patterns.squote * C(patterns.nosquote) * patterns.squote
+ + patterns.dquote * C(patterns.nodquote) * patterns.dquote
+
+function string.unquoted(str)
+ return lpegmatch(unquoted,str) or str
+end
+
+-- print(string.unquoted("test"))
+-- print(string.unquoted([["t\"est"]]))
+-- print(string.unquoted([["t\"est"x]]))
+-- print(string.unquoted("\'test\'"))
+-- print(string.unquoted('"test"'))
+-- print(string.unquoted('"test"'))
+
+function string.quoted(str)
+ return format("%q",str) -- always double quote
+end
+
+function string.count(str,pattern) -- variant 3
+ local n = 0
+ for _ in gmatch(str,pattern) do -- not for utf
+ n = n + 1
+ end
+ return n
+end
+
+function string.limit(str,n,sentinel) -- not utf proof
+ if #str > n then
+ sentinel = sentinel or "..."
+ return sub(str,1,(n-#sentinel)) .. sentinel
+ else
+ return str
+ end
+end
+
+local stripper = patterns.stripper
+local fullstripper = patterns.fullstripper
+local collapser = patterns.collapser
+local nospacer = patterns.nospacer
+local longtostring = patterns.longtostring
+
+function string.strip(str)
+ return str and lpegmatch(stripper,str) or ""
+end
+
+function string.fullstrip(str)
+ return str and lpegmatch(fullstripper,str) or ""
+end
+
+function string.collapsespaces(str)
+ return str and lpegmatch(collapser,str) or ""
+end
+
+function string.nospaces(str)
+ return str and lpegmatch(nospacer,str) or ""
+end
+
+function string.longtostring(str)
+ return str and lpegmatch(longtostring,str) or ""
+end
+
+-- function string.is_empty(str)
+-- return not find(str,"%S")
+-- end
+
+local pattern = P(" ")^0 * P(-1) -- maybe also newlines
+
+-- patterns.onlyspaces = pattern
+
+function string.is_empty(str)
+ if not str or str == "" then
+ return true
+ else
+ return lpegmatch(pattern,str) and true or false
+ end
+end
+
+-- if not string.escapedpattern then
+--
+-- local patterns_escapes = {
+-- ["%"] = "%%",
+-- ["."] = "%.",
+-- ["+"] = "%+", ["-"] = "%-", ["*"] = "%*",
+-- ["["] = "%[", ["]"] = "%]",
+-- ["("] = "%(", [")"] = "%)",
+-- -- ["{"] = "%{", ["}"] = "%}"
+-- -- ["^"] = "%^", ["$"] = "%$",
+-- }
+--
+-- local simple_escapes = {
+-- ["-"] = "%-",
+-- ["."] = "%.",
+-- ["?"] = ".",
+-- ["*"] = ".*",
+-- }
+--
+-- function string.escapedpattern(str,simple)
+-- return (gsub(str,".",simple and simple_escapes or patterns_escapes))
+-- end
+--
+-- function string.topattern(str,lowercase,strict)
+-- if str == "" then
+-- return ".*"
+-- else
+-- str = gsub(str,".",simple_escapes)
+-- if lowercase then
+-- str = lower(str)
+-- end
+-- if strict then
+-- return "^" .. str .. "$"
+-- else
+-- return str
+-- end
+-- end
+-- end
+--
+-- end
+
+--- needs checking
+
+local anything = patterns.anything
+local moreescapes = Cc("%") * S(".-+%?()[]*$^{}")
+local allescapes = Cc("%") * S(".-+%?()[]*") -- also {} and ^$ ?
+local someescapes = Cc("%") * S(".-+%()[]") -- also {} and ^$ ?
+local matchescapes = Cc(".") * S("*?") -- wildcard and single match
+
+local pattern_m = Cs ( ( moreescapes + anything )^0 )
+local pattern_a = Cs ( ( allescapes + anything )^0 )
+local pattern_b = Cs ( ( someescapes + matchescapes + anything )^0 )
+local pattern_c = Cs ( Cc("^") * ( someescapes + matchescapes + anything )^0 * Cc("$") )
+
+function string.escapedpattern(str,simple)
+ return lpegmatch(simple and pattern_b or pattern_a,str)
+end
+
+function string.topattern(str,lowercase,strict)
+ if str == "" or type(str) ~= "string" then
+ return ".*"
+ elseif strict == "all" then
+ str = lpegmatch(pattern_m,str)
+ elseif strict then
+ str = lpegmatch(pattern_c,str)
+ else
+ str = lpegmatch(pattern_b,str)
+ end
+ if lowercase then
+ return lower(str)
+ else
+ return str
+ end
+end
+
+-- print(string.escapedpattern("abc*234",true))
+-- print(string.escapedpattern("12+34*.tex",false))
+-- print(string.escapedpattern("12+34*.tex",true))
+-- print(string.topattern ("12+34*.tex",false,false))
+-- print(string.topattern ("12+34*.tex",false,true))
+
+function string.valid(str,default)
+ return (type(str) == "string" and str ~= "" and str) or default or nil
+end
+
+-- handy fallback
+
+string.itself = function(s) return s end
+
+-- also handy (see utf variant)
+
+local pattern_c = Ct( C(1) ^0) -- string and not utf !
+local pattern_b = Ct((C(1)/byte)^0)
+
+function string.totable(str,bytes)
+ return lpegmatch(bytes and pattern_b or pattern_c,str)
+end
+
+-- handy from within tex:
+
+local replacer = lpeg.replacer("@","%%") -- Watch the escaped % in lpeg!
+
+function string.tformat(fmt,...)
+ return format(lpegmatch(replacer,fmt),...)
+end
+
+-- obsolete names:
+
+string.quote = string.quoted
+string.unquote = string.unquoted
+
+-- new
+
+if not string.bytetable then -- used in font-cff.lua
+
+ local limit = 5000 -- we can go to 8000 in luajit and much higher in lua if needed
+
+ function string.bytetable(str) -- from a string
+ local n = #str
+ if n > limit then
+ local t = { byte(str,1,limit) }
+ for i=limit+1,n do
+ t[i] = byte(str,i)
+ end
+ return t
+ else
+ return { byte(str,1,n) }
+ end
+ end
+
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-table.lua b/macros/luatex/generic/luaotfload/fontloader-l-table.lua
new file mode 100644
index 0000000000..cffdcc23e2
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-l-table.lua
@@ -0,0 +1,1471 @@
+if not modules then modules = { } end modules ['l-table'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type, next, tostring, tonumber, select = type, next, tostring, tonumber, select
+local table, string = table, string
+local concat, sort = table.concat, table.sort
+local format, lower, dump = string.format, string.lower, string.dump
+local getmetatable, setmetatable = getmetatable, setmetatable
+local lpegmatch, patterns = lpeg.match, lpeg.patterns
+local floor = math.floor
+
+-- extra functions, some might go (when not used)
+--
+-- we could serialize using %a but that won't work well is in the code we mostly use
+-- floats and as such we get unequality e.g. in version comparisons
+
+local stripper = patterns.stripper
+
+function table.getn(t)
+ return t and #t -- for very old times sake
+end
+
+function table.strip(tab)
+ local lst = { }
+ local l = 0
+ for i=1,#tab do
+ local s = lpegmatch(stripper,tab[i]) or ""
+ if s == "" then
+ -- skip this one
+ else
+ l = l + 1
+ lst[l] = s
+ end
+ end
+ return lst
+end
+
+function table.keys(t)
+ if t then
+ local keys = { }
+ local k = 0
+ for key in next, t do
+ k = k + 1
+ keys[k] = key
+ end
+ return keys
+ else
+ return { }
+ end
+end
+
+-- local function compare(a,b)
+-- local ta = type(a) -- needed, else 11 < 2
+-- local tb = type(b) -- needed, else 11 < 2
+-- if ta == tb and ta == "number" then
+-- return a < b
+-- else
+-- return tostring(a) < tostring(b) -- not that efficient
+-- end
+-- end
+
+-- local function compare(a,b)
+-- local ta = type(a) -- needed, else 11 < 2
+-- local tb = type(b) -- needed, else 11 < 2
+-- if ta == tb and (ta == "number" or ta == "string") then
+-- return a < b
+-- else
+-- return tostring(a) < tostring(b) -- not that efficient
+-- end
+-- end
+
+-- local function sortedkeys(tab)
+-- if tab then
+-- local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed
+-- for key in next, tab do
+-- s = s + 1
+-- srt[s] = key
+-- if category == 3 then
+-- -- no further check
+-- else
+-- local tkey = type(key)
+-- if tkey == "string" then
+-- category = (category == 2 and 3) or 1
+-- elseif tkey == "number" then
+-- category = (category == 1 and 3) or 2
+-- else
+-- category = 3
+-- end
+-- end
+-- end
+-- if category == 0 or category == 3 then
+-- sort(srt,compare)
+-- else
+-- sort(srt)
+-- end
+-- return srt
+-- else
+-- return { }
+-- end
+-- end
+
+-- local function compare(a,b)
+-- local ta = type(a) -- needed, else 11 < 2
+-- local tb = type(b) -- needed, else 11 < 2
+-- if ta == tb and (ta == "number" or ta == "string") then
+-- return a < b
+-- else
+-- return tostring(a) < tostring(b) -- not that efficient
+-- end
+-- end
+
+-- local function compare(a,b)
+-- local ta = type(a) -- needed, else 11 < 2
+-- if ta == "number" or ta == "string" then
+-- local tb = type(b) -- needed, else 11 < 2
+-- if ta == tb then
+-- return a < b
+-- end
+-- end
+-- return tostring(a) < tostring(b) -- not that efficient
+-- end
+
+local function compare(a,b)
+ local ta = type(a) -- needed, else 11 < 2
+ if ta == "number" then
+ local tb = type(b) -- needed, else 11 < 2
+ if ta == tb then
+ return a < b
+ elseif tb == "string" then
+ return tostring(a) < b
+ end
+ elseif ta == "string" then
+ local tb = type(b) -- needed, else 11 < 2
+ if ta == tb then
+ return a < b
+ else
+ return a < tostring(b)
+ end
+ end
+ return tostring(a) < tostring(b) -- not that efficient
+end
+
+local function sortedkeys(tab)
+ if tab then
+ local srt = { }
+ local category = 0 -- 0=unknown 1=string, 2=number 3=mixed
+ local s = 0
+ for key in next, tab do
+ s = s + 1
+ srt[s] = key
+ if category ~= 3 then
+ local tkey = type(key)
+ if category == 1 then
+ if tkey ~= "string" then
+ category = 3
+ end
+ elseif category == 2 then
+ if tkey ~= "number" then
+ category = 3
+ end
+ else
+ if tkey == "string" then
+ category = 1
+ elseif tkey == "number" then
+ category = 2
+ else
+ category = 3
+ end
+ end
+ end
+ end
+ if s < 2 then
+ -- nothing to sort
+ elseif category == 3 then
+ sort(srt,compare)
+ else
+ sort(srt)
+ end
+ return srt
+ else
+ return { }
+ end
+end
+
+local function sortedhashonly(tab)
+ if tab then
+ local srt = { }
+ local s = 0
+ for key in next, tab do
+ if type(key) == "string" then
+ s = s + 1
+ srt[s] = key
+ end
+ end
+ if s > 1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return { }
+ end
+end
+
+local function sortedindexonly(tab)
+ if tab then
+ local srt = { }
+ local s = 0
+ for key in next, tab do
+ if type(key) == "number" then
+ s = s + 1
+ srt[s] = key
+ end
+ end
+ if s > 1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return { }
+ end
+end
+
+local function sortedhashkeys(tab,cmp) -- fast one
+ if tab then
+ local srt = { }
+ local s = 0
+ for key in next, tab do
+ if key then
+ s= s + 1
+ srt[s] = key
+ end
+ end
+ if s > 1 then
+ sort(srt,cmp)
+ end
+ return srt
+ else
+ return { }
+ end
+end
+
+function table.allkeys(t)
+ local keys = { }
+ for k, v in next, t do
+ for k in next, v do
+ keys[k] = true
+ end
+ end
+ return sortedkeys(keys)
+end
+
+table.sortedkeys = sortedkeys
+table.sortedhashonly = sortedhashonly
+table.sortedindexonly = sortedindexonly
+table.sortedhashkeys = sortedhashkeys
+
+local function nothing() end
+
+local function sortedhash(t,cmp)
+ if t then
+ local s
+ if cmp then
+ -- it would be nice if the sort function would accept a third argument (or nicer, an optional first)
+ s = sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s = sortedkeys(t) -- the robust one
+ end
+ local m = #s
+ if m == 1 then
+ return next, t
+ elseif m > 0 then
+ local n = 0
+ return function()
+ if n < m then
+ n = n + 1
+ local k = s[n]
+ return k, t[k]
+ end
+ end
+ end
+ end
+ return nothing
+end
+
+table.sortedhash = sortedhash
+table.sortedpairs = sortedhash -- obsolete
+
+function table.append(t,list)
+ local n = #t
+ for i=1,#list do
+ n = n + 1
+ t[n] = list[i]
+ end
+ return t
+end
+
+function table.prepend(t, list)
+ local nl = #list
+ local nt = nl + #t
+ for i=#t,1,-1 do
+ t[nt] = t[i]
+ nt = nt - 1
+ end
+ for i=1,#list do
+ t[i] = list[i]
+ end
+ return t
+end
+
+-- function table.merge(t, ...) -- first one is target
+-- t = t or { }
+-- local lst = { ... }
+-- for i=1,#lst do
+-- for k, v in next, lst[i] do
+-- t[k] = v
+-- end
+-- end
+-- return t
+-- end
+
+function table.merge(t, ...) -- first one is target
+ if not t then
+ t = { }
+ end
+ for i=1,select("#",...) do
+ for k, v in next, (select(i,...)) do
+ t[k] = v
+ end
+ end
+ return t
+end
+
+-- function table.merged(...)
+-- local tmp, lst = { }, { ... }
+-- for i=1,#lst do
+-- for k, v in next, lst[i] do
+-- tmp[k] = v
+-- end
+-- end
+-- return tmp
+-- end
+
+function table.merged(...)
+ local t = { }
+ for i=1,select("#",...) do
+ for k, v in next, (select(i,...)) do
+ t[k] = v
+ end
+ end
+ return t
+end
+
+-- function table.imerge(t, ...)
+-- local lst, nt = { ... }, #t
+-- for i=1,#lst do
+-- local nst = lst[i]
+-- for j=1,#nst do
+-- nt = nt + 1
+-- t[nt] = nst[j]
+-- end
+-- end
+-- return t
+-- end
+
+function table.imerge(t, ...)
+ local nt = #t
+ for i=1,select("#",...) do
+ local nst = select(i,...)
+ for j=1,#nst do
+ nt = nt + 1
+ t[nt] = nst[j]
+ end
+ end
+ return t
+end
+
+-- function table.imerged(...)
+-- local tmp, ntmp, lst = { }, 0, {...}
+-- for i=1,#lst do
+-- local nst = lst[i]
+-- for j=1,#nst do
+-- ntmp = ntmp + 1
+-- tmp[ntmp] = nst[j]
+-- end
+-- end
+-- return tmp
+-- end
+
+function table.imerged(...)
+ local tmp = { }
+ local ntmp = 0
+ for i=1,select("#",...) do
+ local nst = select(i,...)
+ for j=1,#nst do
+ ntmp = ntmp + 1
+ tmp[ntmp] = nst[j]
+ end
+ end
+ return tmp
+end
+
+local function fastcopy(old,metatabletoo) -- fast one
+ if old then
+ local new = { }
+ for k, v in next, old do
+ if type(v) == "table" then
+ new[k] = fastcopy(v,metatabletoo) -- was just table.copy
+ else
+ new[k] = v
+ end
+ end
+ if metatabletoo then
+ -- optional second arg
+ local mt = getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ end
+ return new
+ else
+ return { }
+ end
+end
+
+-- todo : copy without metatable
+
+local function copy(t,tables) -- taken from lua wiki, slightly adapted
+ if not tables then
+ tables = { }
+ end
+ local tcopy = { }
+ if not tables[t] then
+ tables[t] = tcopy
+ end
+ for i,v in next, t do -- brrr, what happens with sparse indexed
+ if type(i) == "table" then
+ if tables[i] then
+ i = tables[i]
+ else
+ i = copy(i,tables)
+ end
+ end
+ if type(v) ~= "table" then
+ tcopy[i] = v
+ elseif tables[v] then
+ tcopy[i] = tables[v]
+ else
+ tcopy[i] = copy(v,tables)
+ end
+ end
+ local mt = getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
+end
+
+table.fastcopy = fastcopy
+table.copy = copy
+
+function table.derive(parent) -- for the moment not public
+ local child = { }
+ if parent then
+ setmetatable(child,{ __index = parent })
+ end
+ return child
+end
+
+function table.tohash(t,value)
+ local h = { }
+ if t then
+ if value == nil then value = true end
+ for _, v in next, t do
+ h[v] = value
+ end
+ end
+ return h
+end
+
+function table.fromhash(t)
+ local hsh = { }
+ local h = 0
+ for k, v in next, t do
+ if v then
+ h = h + 1
+ hsh[h] = k
+ end
+ end
+ return hsh
+end
+
+local noquotes, hexify, handle, compact, inline, functions, metacheck
+
+local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
+ 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if',
+ 'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while',
+ 'NaN', 'goto',
+}
+
+-- local function is_simple_table(t)
+-- if #t > 0 then
+-- local n = 0
+-- for _,v in next, t do
+-- n = n + 1
+-- end
+-- if n == #t then
+-- local tt, nt = { }, 0
+-- for i=1,#t do
+-- local v = t[i]
+-- local tv = type(v)
+-- if tv == "number" then
+-- nt = nt + 1
+-- if hexify then
+-- tt[nt] = format("0x%X",v)
+-- else
+-- tt[nt] = tostring(v) -- tostring not needed
+-- end
+-- elseif tv == "string" then
+-- nt = nt + 1
+-- tt[nt] = format("%q",v)
+-- elseif tv == "boolean" then
+-- nt = nt + 1
+-- tt[nt] = v and "true" or "false"
+-- else
+-- return nil
+-- end
+-- end
+-- return tt
+-- end
+-- end
+-- return nil
+-- end
+
+-- local function is_simple_table(t)
+-- local nt = #t
+-- if nt > 0 then
+-- local n = 0
+-- for _,v in next, t do
+-- n = n + 1
+-- -- if type(v) == "table" then
+-- -- return nil
+-- -- end
+-- end
+-- if n == nt then
+-- local tt = { }
+-- for i=1,nt do
+-- local v = t[i]
+-- local tv = type(v)
+-- if tv == "number" then
+-- if hexify then
+-- tt[i] = format("0x%X",v)
+-- else
+-- tt[i] = tostring(v) -- tostring not needed
+-- end
+-- elseif tv == "string" then
+-- tt[i] = format("%q",v)
+-- elseif tv == "boolean" then
+-- tt[i] = v and "true" or "false"
+-- else
+-- return nil
+-- end
+-- end
+-- return tt
+-- end
+-- end
+-- return nil
+-- end
+
+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
+ for _, v in next, t do
+ n = n + 1
+ if type(v) == "table" then
+ return nil
+ end
+ end
+ -- local haszero = t[0]
+ local haszero = rawget(t,0) -- don't trigger meta
+ if n == nt then
+ local tt = { }
+ for i=1,nt do
+ local v = t[i]
+ local tv = type(v)
+ if tv == "number" then
+ -- tt[i] = v -- not needed tostring(v)
+ if hexify then
+ tt[i] = format("0x%X",v)
+ else
+ tt[i] = v -- not needed tostring(v)
+ end
+ elseif tv == "string" then
+ tt[i] = format("%q",v) -- f_string(v)
+ elseif tv == "boolean" then
+ tt[i] = v and "true" or "false"
+ else
+ return nil
+ end
+ end
+ return tt
+ elseif haszero and (n == nt + 1) then
+ local tt = { }
+ for i=0,nt do
+ local v = t[i]
+ local tv = type(v)
+ if tv == "number" then
+ -- tt[i+1] = v -- not needed tostring(v)
+ if hexify then
+ tt[i+1] = format("0x%X",v)
+ else
+ tt[i+1] = v -- not needed tostring(v)
+ end
+ elseif tv == "string" then
+ tt[i+1] = format("%q",v) -- f_string(v)
+ elseif tv == "boolean" then
+ tt[i+1] = v and "true" or "false"
+ else
+ return nil
+ end
+ end
+ tt[1] = "[0] = " .. tt[1]
+ return tt
+ end
+ end
+ return nil
+end
+
+table.is_simple_table = is_simple_table
+
+-- Because this is a core function of mkiv I moved some function calls
+-- inline.
+--
+-- twice as fast in a test:
+--
+-- local propername = lpeg.P(lpeg.R("AZ","az","__") * lpeg.R("09","AZ","az", "__")^0 * lpeg.P(-1) )
+
+-- problem: there no good number_to_string converter with the best resolution
+
+-- probably using .. is faster than format
+-- maybe split in a few cases (yes/no hexify)
+
+-- todo: %g faster on numbers than %s
+
+-- we can speed this up with repeaters and formatters but we haven't defined them
+-- yet
+
+local propername = patterns.propername -- was find(name,"^%a[%w%_]*$")
+
+local function dummy() end
+
+local function do_serialize(root,name,depth,level,indexed)
+ if level > 0 then
+ depth = depth .. " "
+ if indexed then
+ handle(format("%s{",depth))
+ else
+ local tn = type(name)
+ if tn == "number" then
+ if hexify then
+ handle(format("%s[0x%X]={",depth,name))
+ else
+ handle(format("%s[%s]={",depth,name))
+ end
+ elseif tn == "string" then
+ if noquotes and not reserved[name] and lpegmatch(propername,name) then
+ handle(format("%s%s={",depth,name))
+ else
+ handle(format("%s[%q]={",depth,name))
+ end
+ elseif tn == "boolean" then
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
+ else
+ handle(format("%s{",depth))
+ end
+ end
+ end
+ -- we could check for k (index) being number (cardinal)
+ if root and next(root) ~= nil then
+ local first = nil
+ local last = 0
+ if compact then
+ last = #root
+ for k=1,last do
+ -- if root[k] == nil then
+ if rawget(root,k) == nil then
+ last = k - 1
+ break
+ end
+ end
+ if last > 0 then
+ first = 1
+ end
+ end
+ local sk = sortedkeys(root)
+ for i=1,#sk do
+ local k = sk[i]
+ local v = root[k]
+ local tv = type(v)
+ local tk = type(k)
+ if compact and first and tk == "number" and k >= first and k <= last then
+ if tv == "number" then
+ if hexify then
+ handle(format("%s 0x%X,",depth,v))
+ else
+ handle(format("%s %s,",depth,v)) -- %.99g
+ end
+ elseif tv == "string" then
+ handle(format("%s %q,",depth,v))
+ elseif tv == "table" then
+ if next(v) == nil then
+ handle(format("%s {},",depth))
+ elseif inline then -- and #t > 0
+ local st = is_simple_table(v,hexify)
+ if st then
+ handle(format("%s { %s },",depth,concat(st,", ")))
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ elseif tv == "boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv == "function" then
+ if functions then
+ handle(format('%s load(%q),',depth,dump(v))) -- maybe strip
+ else
+ handle(format('%s "function",',depth))
+ end
+ else
+ handle(format("%s %q,",depth,tostring(v)))
+ end
+ elseif k == "__p__" then -- parent
+ if false then
+ handle(format("%s __p__=nil,",depth))
+ end
+ elseif tv == "number" then
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
+ end
+ elseif tk == "boolean" then
+ if hexify then
+ handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ else
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) -- %.99g
+ end
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ if hexify then
+ handle(format("%s %s=0x%X,",depth,k,v))
+ else
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
+ end
+ else
+ if hexify then
+ handle(format("%s [%q]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
+ end
+ end
+ elseif tv == "string" then
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,v))
+ else
+ handle(format("%s [%s]=%q,",depth,k,v))
+ end
+ elseif tk == "boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,v))
+ else
+ handle(format("%s [%q]=%q,",depth,k,v))
+ end
+ elseif tv == "table" then
+ if next(v) == nil then
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]={},",depth,k))
+ else
+ handle(format("%s [%s]={},",depth,k))
+ end
+ elseif tk == "boolean" then
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={},",depth,k))
+ else
+ handle(format("%s [%q]={},",depth,k))
+ end
+ elseif inline then
+ local st = is_simple_table(v,hexify)
+ if st then
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+ end
+ elseif tk == "boolean" then
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
+ elseif tv == "boolean" then
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tk == "boolean" then
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tv == "function" then
+ if functions then
+ local getinfo = debug and debug.getinfo
+ if getinfo then
+ local f = getinfo(v).what == "C" and dump(dummy) or dump(v) -- maybe strip
+ -- local f = getinfo(v).what == "C" and dump(function(...) return v(...) end) or dump(v) -- maybe strip
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%s]=load(%q),",depth,k,f))
+ end
+ elseif tk == "boolean" then
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%q]=load(%q),",depth,k,f))
+ end
+ end
+ end
+ else
+ if tk == "number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+ end
+ elseif tk == "boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
+ elseif tk ~= "string" then
+ -- ignore
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
+ end
+ end
+ end
+ end
+ if level > 0 then
+ handle(format("%s},",depth))
+ end
+end
+
+-- replacing handle by a direct t[#t+1] = ... (plus test) is not much
+-- faster (0.03 on 1.00 for zapfino.tma)
+
+local function serialize(_handle,root,name,specification) -- handle wins
+ local tname = type(name)
+ if type(specification) == "table" then
+ noquotes = specification.noquotes
+ hexify = specification.hexify
+ handle = _handle or specification.handle or print
+ functions = specification.functions
+ compact = specification.compact
+ inline = specification.inline and compact
+ metacheck = specification.metacheck
+ if functions == nil then
+ functions = true
+ end
+ if compact == nil then
+ compact = true
+ end
+ if inline == nil then
+ inline = compact
+ end
+ if metacheck == nil then
+ metacheck = true
+ end
+ else
+ noquotes = false
+ hexify = false
+ handle = _handle or print
+ compact = true
+ inline = true
+ functions = true
+ metacheck = true
+ end
+ if tname == "string" then
+ if name == "return" then
+ handle("return {")
+ else
+ handle(name .. "={")
+ end
+ elseif tname == "number" then
+ if hexify then
+ handle(format("[0x%X]={",name))
+ else
+ handle("[" .. name .. "]={")
+ end
+ elseif tname == "boolean" then
+ if name then
+ handle("return {")
+ else
+ handle("{")
+ end
+ else
+ handle("t={")
+ end
+ if root then
+ -- The dummy access will initialize a table that has a delayed initialization
+ -- using a metatable. (maybe explicitly test for metatable). This can crash on
+ -- metatables that check the index against a number.
+ if metacheck and getmetatable(root) then
+ local dummy = root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_ = nil
+ end
+ -- Let's forget about empty tables.
+ if next(root) ~= nil then
+ do_serialize(root,name,"",0)
+ end
+ end
+ handle("}")
+end
+
+-- A version with formatters is some 20% faster than using format (because formatters are
+-- much faster) but of course, inlining the format using .. is then again faster .. anyway,
+-- as we do some pretty printing as well there is not that much to gain unless we make a
+-- 'fast' ugly variant as well. But, we would have to move the formatter to l-string then.
+
+-- name:
+--
+-- true : return { }
+-- false : { }
+-- nil : t = { }
+-- string : string = { }
+-- "return" : return { }
+-- number : [number] = { }
+
+function table.serialize(root,name,specification)
+ local t = { }
+ local n = 0
+ local function flush(s)
+ n = n + 1
+ t[n] = s
+ end
+ serialize(flush,root,name,specification)
+ return concat(t,"\n")
+end
+
+-- local a = { e = { 1,2,3,4,5,6}, a = 1, b = 2, c = "ccc", d = { a = 1, b = 2, c = "ccc", d = { a = 1, b = 2, c = "ccc" } } }
+-- local t = os.clock()
+-- for i=1,10000 do
+-- table.serialize(a)
+-- end
+-- print(os.clock()-t,table.serialize(a))
+
+table.tohandle = serialize
+
+local maxtab = 2*1024
+
+function table.tofile(filename,root,name,specification)
+ local f = io.open(filename,'w')
+ if f then
+ if maxtab > 1 then
+ local t = { }
+ local n = 0
+ local function flush(s)
+ n = n + 1
+ t[n] = s
+ if n > maxtab then
+ f:write(concat(t,"\n"),"\n") -- hm, write(sometable) should be nice
+ t = { } -- we could recycle t if needed
+ n = 0
+ end
+ end
+ serialize(flush,root,name,specification)
+ f:write(concat(t,"\n"),"\n")
+ else
+ local function flush(s)
+ f:write(s,"\n")
+ end
+ serialize(flush,root,name,specification)
+ end
+ f:close()
+ io.flush()
+ end
+end
+
+local function flattened(t,f,depth) -- also handles { nil, 1, nil, 2 }
+ if f == nil then
+ f = { }
+ depth = 0xFFFF
+ elseif tonumber(f) then
+ -- assume that only two arguments are given
+ depth = f
+ f = { }
+ elseif not depth then
+ depth = 0xFFFF
+ end
+ for k, v in next, t do
+ if type(k) ~= "number" then
+ if depth > 0 and type(v) == "table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1] = v
+ end
+ end
+ end
+ for k=1,#t do
+ local v = t[k]
+ if depth > 0 and type(v) == "table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1] = v
+ end
+ end
+ return f
+end
+
+table.flattened = flattened
+
+local function collapsed(t,f,h)
+ if f == nil then
+ f = { }
+ h = { }
+ end
+ for k=1,#t do
+ local v = t[k]
+ if type(v) == "table" then
+ collapsed(v,f,h)
+ elseif not h[v] then
+ f[#f+1] = v
+ h[v] = true
+ end
+ end
+ return f
+end
+
+local function collapsedhash(t,h)
+ if h == nil then
+ h = { }
+ end
+ for k=1,#t do
+ local v = t[k]
+ if type(v) == "table" then
+ collapsedhash(v,h)
+ else
+ h[v] = true
+ end
+ end
+ return h
+end
+
+table.collapsed = collapsed -- 20% faster than unique(collapsed(t))
+table.collapsedhash = collapsedhash
+
+local function unnest(t,f) -- only used in mk, for old times sake
+ if not f then -- and only relevant for token lists
+ f = { } -- this one can become obsolete
+ end
+ for i=1,#t do
+ local v = t[i]
+ if type(v) == "table" then
+ if type(v[1]) == "table" then
+ unnest(v,f)
+ else
+ f[#f+1] = v
+ end
+ else
+ f[#f+1] = v
+ end
+ end
+ return f
+end
+
+function table.unnest(t) -- bad name
+ return unnest(t)
+end
+
+local function are_equal(a,b,n,m) -- indexed
+ if a == b then
+ return true
+ elseif a and b and #a == #b then
+ if not n then
+ n = 1
+ end
+ if not m then
+ m = #a
+ end
+ for i=n,m do
+ local ai, bi = a[i], b[i]
+ if ai==bi then
+ -- same
+ elseif type(ai) == "table" and type(bi) == "table" then
+ if not are_equal(ai,bi) then
+ return false
+ end
+ else
+ return false
+ end
+ end
+ return true
+ else
+ return false
+ end
+end
+
+local function identical(a,b) -- assumes same structure
+ if a ~= b then
+ for ka, va in next, a do
+ local vb = b[ka]
+ if va == vb then
+ -- same
+ elseif type(va) == "table" and type(vb) == "table" then
+ if not identical(va,vb) then
+ return false
+ end
+ else
+ return false
+ end
+ end
+ end
+ return true
+end
+
+table.identical = identical
+table.are_equal = are_equal
+
+local function sparse(old,nest,keeptables)
+ local new = { }
+ for k, v in next, old do
+ if not (v == "" or v == false) then
+ if nest and type(v) == "table" then
+ v = sparse(v,nest)
+ if keeptables or next(v) ~= nil then
+ new[k] = v
+ end
+ else
+ new[k] = v
+ end
+ end
+ end
+ return new
+end
+
+table.sparse = sparse
+
+function table.compact(t)
+ return sparse(t,true,true)
+end
+
+function table.contains(t, v)
+ if t then
+ for i=1, #t do
+ if t[i] == v then
+ return i
+ end
+ end
+ end
+ return false
+end
+
+function table.count(t)
+ local n = 0
+ for k, v in next, t do
+ n = n + 1
+ end
+ return n
+end
+
+function table.swapped(t,s) -- hash, we need to make sure we don't mess up next
+ local n = { }
+ if s then
+ for k, v in next, s do
+ n[k] = v
+ end
+ end
+ for k, v in next, t do
+ n[v] = k
+ end
+ return n
+end
+
+function table.hashed(t) -- list, add hash to index (save because we are not yet mixed
+ for i=1,#t do
+ t[t[i]] = i
+ end
+ return t
+end
+
+function table.mirrored(t) -- hash, we need to make sure we don't mess up next
+ local n = { }
+ for k, v in next, t do
+ n[v] = k
+ n[k] = v
+ end
+ return n
+end
+
+function table.reversed(t)
+ if t then
+ local tt = { }
+ local tn = #t
+ if tn > 0 then
+ local ttn = 0
+ for i=tn,1,-1 do
+ ttn = ttn + 1
+ tt[ttn] = t[i]
+ end
+ end
+ return tt
+ end
+end
+
+function table.reverse(t) -- check with 5.3 ?
+ if t then
+ local n = #t
+ local m = n + 1
+ for i=1,floor(n/2) do -- maybe just n//2
+ local j = m - i
+ t[i], t[j] = t[j], t[i]
+ end
+ return t
+ end
+end
+
+-- This one is for really simple cases where need a hash from a table.
+
+local function sequenced(t,sep,simple)
+ if not t then
+ return ""
+ elseif type(t) ~= "table" then
+ return t -- handy fallback
+ end
+ local n = #t
+ local s = { }
+ if n > 0 then
+ -- indexed
+ for i=1,n do
+ local v = t[i]
+ if type(v) == "table" then
+ s[i] = "{" .. sequenced(v,sep,simple) .. "}"
+ else
+ s[i] = tostring(t[i])
+ end
+ end
+ else
+ -- hashed
+ n = 0
+ for k, v in sortedhash(t) do
+ if simple then
+ if v == true then
+ n = n + 1
+ s[n] = k
+ elseif v and v~= "" then
+ n = n + 1
+ if type(v) == "table" then
+ s[n] = k .. "={" .. sequenced(v,sep,simple) .. "}"
+ else
+ s[n] = k .. "=" .. tostring(v)
+ end
+ end
+ else
+ n = n + 1
+ if type(v) == "table" then
+ s[n] = k .. "={" .. sequenced(v,sep,simple) .. "}"
+ else
+ s[n] = k .. "=" .. tostring(v)
+ end
+ end
+ end
+ end
+ if sep == true then
+ return "{ " .. concat(s,", ") .. " }"
+ else
+ return concat(s,sep or " | ")
+ end
+end
+
+table.sequenced = sequenced
+
+function table.print(t,...)
+ if type(t) ~= "table" then
+ print(tostring(t))
+ else
+ serialize(print,t,...)
+ end
+end
+
+if setinspector then
+ setinspector("table",function(v) if type(v) == "table" then serialize(print,v,"table") return true end end)
+end
+
+-- -- -- obsolete but we keep them for a while and might comment them later -- -- --
+
+-- roughly: copy-loop : unpack : sub == 0.9 : 0.4 : 0.45 (so in critical apps, use unpack)
+
+function table.sub(t,i,j)
+ return { unpack(t,i,j) }
+end
+
+-- slower than #t on indexed tables (#t only returns the size of the numerically indexed slice)
+
+function table.is_empty(t)
+ return not t or next(t) == nil
+end
+
+function table.has_one_entry(t)
+ return t and next(t,next(t)) == nil
+end
+
+-- new (rather basic, not indexed and nested)
+
+function table.loweredkeys(t) -- maybe utf
+ local l = { }
+ for k, v in next, t do
+ l[lower(k)] = v
+ end
+ return l
+end
+
+-- new, might move (maybe duplicate)
+
+function table.unique(old)
+ local hash = { }
+ local new = { }
+ local n = 0
+ for i=1,#old do
+ local oi = old[i]
+ if not hash[oi] then
+ n = n + 1
+ new[n] = oi
+ hash[oi] = true
+ end
+ end
+ return new
+end
+
+function table.sorted(t,...)
+ sort(t,...)
+ return t -- still sorts in-place
+end
+
+--
+
+function table.values(t,s) -- optional sort flag
+ if t then
+ local values = { }
+ local keys = { }
+ local v = 0
+ for key, value in next, t do
+ if not keys[value] then
+ v = v + 1
+ values[v] = value
+ keys[k] = key
+ end
+ end
+ if s then
+ sort(values)
+ end
+ return values
+ else
+ return { }
+ end
+end
+
+-- maybe this will move to util-tab.lua
+
+-- for k, v in table.filtered(t,pattern) do ... end
+-- for k, v in table.filtered(t,pattern,true) do ... end
+-- for k, v in table.filtered(t,pattern,true,cmp) do ... end
+
+function table.filtered(t,pattern,sort,cmp)
+ if t and type(pattern) == "string" then
+ if sort then
+ local s
+ if cmp then
+ -- it would be nice if the sort function would accept a third argument (or nicer, an optional first)
+ s = sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s = sortedkeys(t) -- the robust one
+ end
+ local n = 0
+ local m = #s
+ local function kv(s)
+ while n < m do
+ n = n + 1
+ local k = s[n]
+ if find(k,pattern) then
+ return k, t[k]
+ end
+ end
+ end
+ return kv, s
+ else
+ local n = next(t)
+ local function iterator()
+ while n ~= nil do
+ local k = n
+ n = next(t,k)
+ if find(k,pattern) then
+ return k, t[k]
+ end
+ end
+ end
+ return iterator, t
+ end
+ else
+ return nothing
+ end
+end
+
+-- lua 5.3:
+
+if not table.move then
+
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1 ~= a2 then
+ for i=f,e do
+ a2[t] = a1[i]
+ t = t + 1
+ end
+ return a2
+ else
+ t = t + e - f
+ for i=e,f,-1 do
+ a1[t] = a1[i]
+ t = t - 1
+ end
+ return a1
+ end
+ end
+
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-unicode.lua b/macros/luatex/generic/luaotfload/fontloader-l-unicode.lua
new file mode 100644
index 0000000000..13e0a3fa1c
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-l-unicode.lua
@@ -0,0 +1,1405 @@
+if not modules then modules = { } end modules ['l-unicode'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- floor(b/256) => rshift(b, 8)
+-- floor(b/1024) => rshift(b,10)
+
+-- in lua 5.3:
+
+-- utf8.char(···) : concatinated
+-- utf8.charpatt : "[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
+-- utf8.codes(s) : for p, c in utf8.codes(s) do body end
+-- utf8.codepoint(s [, i [, j]])
+-- utf8.len(s [, i])
+-- utf8.offset(s, n [, i])
+
+-- todo: utf.sub replacement (used in syst-aux)
+-- we put these in the utf namespace:
+
+-- used : byte char len lower sub upper
+-- not used : dump find format gmatch gfind gsub match rep reverse
+
+-- utf = utf or (unicode and unicode.utf8) or { }
+
+-- not supported:
+--
+-- dump, find, format, gfind, gmatch, gsub, lower, match, rep, reverse, upper
+
+utf = utf or { }
+unicode = nil
+
+if not string.utfcharacters then
+
+ -- New: this gmatch hack is taken from the Lua 5.2 book. It's about two times slower
+ -- than the built-in string.utfcharacters.
+
+ local gmatch = string.gmatch
+
+ function string.characters(str)
+ return gmatch(str,".[\128-\191]*")
+ end
+
+
+end
+
+utf.characters = string.utfcharacters
+
+-- string.utfvalues
+-- string.utfcharacters
+-- string.characters
+-- string.characterpairs
+-- string.bytes
+-- string.bytepairs
+-- string.utflength
+-- string.utfvalues
+-- string.utfcharacters
+
+local type = type
+local char, byte, format, sub, gmatch = string.char, string.byte, string.format, string.sub, string.gmatch
+local concat = table.concat
+local P, C, R, Cs, Ct, Cmt, Cc, Carg, Cp = lpeg.P, lpeg.C, lpeg.R, lpeg.Cs, lpeg.Ct, lpeg.Cmt, lpeg.Cc, lpeg.Carg, lpeg.Cp
+
+local lpegmatch = lpeg.match
+local patterns = lpeg.patterns
+local tabletopattern = lpeg.utfchartabletopattern
+
+local bytepairs = string.bytepairs
+
+local finder = lpeg.finder
+local replacer = lpeg.replacer
+
+local p_utftype = patterns.utftype
+local p_utfstricttype = patterns.utfstricttype
+local p_utfoffset = patterns.utfoffset
+local p_utf8character = patterns.utf8character
+local p_utf8char = patterns.utf8char
+local p_utf8byte = patterns.utf8byte
+local p_utfbom = patterns.utfbom
+local p_newline = patterns.newline
+local p_whitespace = patterns.whitespace
+
+-- if not unicode then
+-- unicode = { utf = utf } -- for a while
+-- end
+
+if not utf.char then
+
+ utf.char = string.utfcharacter or (utf8 and utf8.char)
+
+ if not utf.char then
+
+ -- no multiples
+
+ local char = string.char
+
+ if bit32 then
+
+ local rshift = bit32.rshift
+
+ function utf.char(n)
+ if n < 0x80 then
+ -- 0aaaaaaa : 0x80
+ return char(n)
+ elseif n < 0x800 then
+ -- 110bbbaa : 0xC0 : n >> 6
+ -- 10aaaaaa : 0x80 : n & 0x3F
+ return char(
+ 0xC0 + rshift(n,6),
+ 0x80 + (n % 0x40)
+ )
+ elseif n < 0x10000 then
+ -- 1110bbbb : 0xE0 : n >> 12
+ -- 10bbbbaa : 0x80 : (n >> 6) & 0x3F
+ -- 10aaaaaa : 0x80 : n & 0x3F
+ return char(
+ 0xE0 + rshift(n,12),
+ 0x80 + (rshift(n,6) % 0x40),
+ 0x80 + (n % 0x40)
+ )
+ elseif n < 0x200000 then
+ -- 11110ccc : 0xF0 : n >> 18
+ -- 10ccbbbb : 0x80 : (n >> 12) & 0x3F
+ -- 10bbbbaa : 0x80 : (n >> 6) & 0x3F
+ -- 10aaaaaa : 0x80 : n & 0x3F
+ -- dddd : ccccc - 1
+ return char(
+ 0xF0 + rshift(n,18),
+ 0x80 + (rshift(n,12) % 0x40),
+ 0x80 + (rshift(n,6) % 0x40),
+ 0x80 + (n % 0x40)
+ )
+ else
+ return ""
+ end
+ end
+
+ else
+
+ local floor = math.floor
+
+ function utf.char(n)
+ if n < 0x80 then
+ return char(n)
+ elseif n < 0x800 then
+ return char(
+ 0xC0 + floor(n/0x40),
+ 0x80 + (n % 0x40)
+ )
+ elseif n < 0x10000 then
+ return char(
+ 0xE0 + floor(n/0x1000),
+ 0x80 + (floor(n/0x40) % 0x40),
+ 0x80 + (n % 0x40)
+ )
+ elseif n < 0x200000 then
+ return char(
+ 0xF0 + floor(n/0x40000),
+ 0x80 + (floor(n/0x1000) % 0x40),
+ 0x80 + (floor(n/0x40) % 0x40),
+ 0x80 + (n % 0x40)
+ )
+ else
+ return ""
+ end
+ end
+
+ end
+
+ end
+
+end
+
+if not utf.byte then
+
+ utf.byte = string.utfvalue or (utf8 and utf8.codepoint)
+
+ if not utf.byte then
+
+ function utf.byte(c)
+ return lpegmatch(p_utf8byte,c)
+ end
+
+ end
+
+end
+
+local utfchar, utfbyte = utf.char, utf.byte
+
+-- As we want to get rid of the (unmaintained) utf library we implement our own
+-- variants (in due time an independent module):
+
+function utf.filetype(data)
+ return data and lpegmatch(p_utftype,data) or "unknown"
+end
+
+local toentities = Cs (
+ (
+ patterns.utf8one
+ + (
+ patterns.utf8two
+ + patterns.utf8three
+ + patterns.utf8four
+ ) / function(s) local b = utfbyte(s) if b < 127 then return s else return format("&#%X;",b) end end
+ )^0
+)
+
+patterns.toentities = toentities
+
+function utf.toentities(str)
+ return lpegmatch(toentities,str)
+end
+
+-- local utfchr = { } -- 60K -> 2.638 M extra mem but currently not called that often (on latin)
+--
+-- setmetatable(utfchr, { __index = function(t,k) local v = utfchar(k) t[k] = v return v end } )
+--
+-- collectgarbage("collect")
+-- local u = collectgarbage("count")*1024
+-- local t = os.clock()
+-- for i=1,1000 do
+-- for i=1,600 do
+-- local a = utfchr[i]
+-- end
+-- end
+-- print(os.clock()-t,collectgarbage("count")*1024-u)
+
+-- collectgarbage("collect")
+-- local t = os.clock()
+-- for i=1,1000 do
+-- for i=1,600 do
+-- local a = utfchar(i)
+-- end
+-- end
+-- print(os.clock()-t,collectgarbage("count")*1024-u)
+
+-- local byte = string.byte
+-- local utfchar = utf.char
+
+local one = P(1)
+local two = C(1) * C(1)
+local four = C(R(utfchar(0xD8),utfchar(0xFF))) * C(1) * C(1) * C(1)
+
+local pattern = P("\254\255") * Cs( (
+ four / function(a,b,c,d)
+ local ab = 0xFF * byte(a) + byte(b)
+ local cd = 0xFF * byte(c) + byte(d)
+ return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
+ end
+ + two / function(a,b)
+ return utfchar(byte(a)*256 + byte(b))
+ end
+ + one
+ )^1 )
+ + P("\255\254") * Cs( (
+ four / function(b,a,d,c)
+ local ab = 0xFF * byte(a) + byte(b)
+ local cd = 0xFF * byte(c) + byte(d)
+ return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
+ end
+ + two / function(b,a)
+ return utfchar(byte(a)*256 + byte(b))
+ end
+ + one
+ )^1 )
+
+function string.toutf(s) -- in string namespace
+ return lpegmatch(pattern,s) or s -- todo: utf32
+end
+
+local validatedutf = Cs (
+ (
+ patterns.utf8one
+ + patterns.utf8two
+ + patterns.utf8three
+ + patterns.utf8four
+ + P(1) / "�"
+ )^0
+)
+
+patterns.validatedutf = validatedutf
+
+function utf.is_valid(str)
+ return type(str) == "string" and lpegmatch(validatedutf,str) or false
+end
+
+if not utf.len then
+
+ utf.len = string.utflength or (utf8 and utf8.len)
+
+ if not utf.len then
+
+ -- -- alternative 1: 0.77
+ --
+ -- local utfcharcounter = utfbom^-1 * Cs((p_utf8character/'!')^0)
+ --
+ -- function utf.len(str)
+ -- return #lpegmatch(utfcharcounter,str or "")
+ -- end
+ --
+ -- -- alternative 2: 1.70
+ --
+ -- local n = 0
+ --
+ -- local utfcharcounter = utfbom^-1 * (p_utf8character/function() n = n + 1 end)^0 -- slow
+ --
+ -- function utf.length(str)
+ -- n = 0
+ -- lpegmatch(utfcharcounter,str or "")
+ -- return n
+ -- end
+ --
+ -- -- alternative 3: 0.24 (native unicode.utf8.len: 0.047)
+
+ -- local n = 0
+ --
+ -- -- local utfcharcounter = lpeg.patterns.utfbom^-1 * P ( ( Cp() * (
+ -- -- patterns.utf8one ^1 * Cc(1)
+ -- -- + patterns.utf8two ^1 * Cc(2)
+ -- -- + patterns.utf8three^1 * Cc(3)
+ -- -- + patterns.utf8four ^1 * Cc(4) ) * Cp() / function(f,d,t) n = n + (t - f)/d end
+ -- -- )^0 ) -- just as many captures as below
+ --
+ -- -- local utfcharcounter = lpeg.patterns.utfbom^-1 * P ( (
+ -- -- (Cmt(patterns.utf8one ^1,function(_,_,s) n = n + #s return true end))
+ -- -- + (Cmt(patterns.utf8two ^1,function(_,_,s) n = n + #s/2 return true end))
+ -- -- + (Cmt(patterns.utf8three^1,function(_,_,s) n = n + #s/3 return true end))
+ -- -- + (Cmt(patterns.utf8four ^1,function(_,_,s) n = n + #s/4 return true end))
+ -- -- )^0 ) -- not interesting as it creates strings but sometimes faster
+ --
+ -- -- The best so far:
+ --
+ -- local utfcharcounter = utfbom^-1 * P ( (
+ -- Cp() * (patterns.utf8one )^1 * Cp() / function(f,t) n = n + t - f end
+ -- + Cp() * (patterns.utf8two )^1 * Cp() / function(f,t) n = n + (t - f)/2 end
+ -- + Cp() * (patterns.utf8three)^1 * Cp() / function(f,t) n = n + (t - f)/3 end
+ -- + Cp() * (patterns.utf8four )^1 * Cp() / function(f,t) n = n + (t - f)/4 end
+ -- )^0 )
+
+ -- function utf.len(str)
+ -- n = 0
+ -- lpegmatch(utfcharcounter,str or "")
+ -- return n
+ -- end
+
+ local n, f = 0, 1
+
+ local utfcharcounter = patterns.utfbom^-1 * Cmt (
+ Cc(1) * patterns.utf8one ^1
+ + Cc(2) * patterns.utf8two ^1
+ + Cc(3) * patterns.utf8three^1
+ + Cc(4) * patterns.utf8four ^1,
+ function(_,t,d) -- due to Cc no string captures, so faster
+ n = n + (t - f)/d
+ f = t
+ return true
+ end
+ )^0
+
+ function utf.len(str)
+ n, f = 0, 1
+ lpegmatch(utfcharcounter,str or "")
+ return n
+ end
+
+ -- -- these are quite a bit slower:
+
+ -- utfcharcounter = utfbom^-1 * (Cmt(P(1) * R("\128\191")^0, function() n = n + 1 return true end))^0 -- 50+ times slower
+ -- utfcharcounter = utfbom^-1 * (Cmt(P(1), function() n = n + 1 return true end) * R("\128\191")^0)^0 -- 50- times slower
+
+ end
+
+end
+
+utf.length = utf.len
+
+if not utf.sub then
+
+ -- inefficient as lpeg just copies ^n
+
+ -- local function sub(str,start,stop)
+ -- local pattern = p_utf8character^-(start-1) * C(p_utf8character^-(stop-start+1))
+ -- inspect(pattern)
+ -- return lpegmatch(pattern,str) or ""
+ -- end
+
+ -- local b, e, n, first, last = 0, 0, 0, 0, 0
+ --
+ -- local function slide(s,p)
+ -- n = n + 1
+ -- if n == first then
+ -- b = p
+ -- if not last then
+ -- return nil
+ -- end
+ -- end
+ -- if n == last then
+ -- e = p
+ -- return nil
+ -- else
+ -- return p
+ -- end
+ -- end
+ --
+ -- local pattern = Cmt(p_utf8character,slide)^0
+ --
+ -- function utf.sub(str,start,stop) -- todo: from the end
+ -- if not start then
+ -- return str
+ -- end
+ -- b, e, n, first, last = 0, 0, 0, start, stop
+ -- lpegmatch(pattern,str)
+ -- if not stop then
+ -- return sub(str,b)
+ -- else
+ -- return sub(str,b,e-1)
+ -- end
+ -- end
+
+ -- print(utf.sub("Hans Hagen is my name"))
+ -- print(utf.sub("Hans Hagen is my name",5))
+ -- print(utf.sub("Hans Hagen is my name",5,10))
+
+ local utflength = utf.length
+
+ -- also negative indices, upto 10 times slower than a c variant
+
+ local b, e, n, first, last = 0, 0, 0, 0, 0
+
+ local function slide_zero(s,p)
+ n = n + 1
+ if n >= last then
+ e = p - 1
+ else
+ return p
+ end
+ end
+
+ local function slide_one(s,p)
+ n = n + 1
+ if n == first then
+ b = p
+ end
+ if n >= last then
+ e = p - 1
+ else
+ return p
+ end
+ end
+
+ local function slide_two(s,p)
+ n = n + 1
+ if n == first then
+ b = p
+ else
+ return true
+ end
+ end
+
+ local pattern_zero = Cmt(p_utf8character,slide_zero)^0
+ local pattern_one = Cmt(p_utf8character,slide_one )^0
+ local pattern_two = Cmt(p_utf8character,slide_two )^0
+
+ local pattern_first = C(p_utf8character)
+
+ function utf.sub(str,start,stop)
+ if not start then
+ return str
+ end
+ if start == 0 then
+ start = 1
+ end
+ if not stop then
+ if start < 0 then
+ local l = utflength(str) -- we can inline this function if needed
+ start = l + start
+ else
+ start = start - 1
+ end
+ b, n, first = 0, 0, start
+ lpegmatch(pattern_two,str)
+ if n >= first then
+ return sub(str,b)
+ else
+ return ""
+ end
+ end
+ if start < 0 or stop < 0 then
+ local l = utf.length(str)
+ if start < 0 then
+ start = l + start
+ if start <= 0 then
+ start = 1
+ else
+ start = start + 1
+ end
+ end
+ if stop < 0 then
+ stop = l + stop
+ if stop == 0 then
+ stop = 1
+ else
+ stop = stop + 1
+ end
+ end
+ end
+ if start == 1 and stop == 1 then
+ return lpegmatch(pattern_first,str) or ""
+ elseif start > stop then
+ return ""
+ elseif start > 1 then
+ b, e, n, first, last = 0, 0, 0, start - 1, stop
+ lpegmatch(pattern_one,str)
+ if n >= first and e == 0 then
+ e = #str
+ end
+ return sub(str,b,e)
+ else
+ b, e, n, last = 1, 0, 0, stop
+ lpegmatch(pattern_zero,str)
+ if e == 0 then
+ e = #str
+ end
+ return sub(str,b,e)
+ end
+ end
+
+ -- local n = 100000
+ -- local str = string.rep("123456àáâãäå",100)
+ --
+ -- for i=-15,15,1 do
+ -- for j=-15,15,1 do
+ -- if utf.xsub(str,i,j) ~= utf.sub(str,i,j) then
+ -- print("error",i,j,"l>"..utf.xsub(str,i,j),"s>"..utf.sub(str,i,j))
+ -- end
+ -- end
+ -- if utf.xsub(str,i) ~= utf.sub(str,i) then
+ -- print("error",i,"l>"..utf.xsub(str,i),"s>"..utf.sub(str,i))
+ -- end
+ -- end
+
+ -- print(" 1, 7",utf.xsub(str, 1, 7),utf.sub(str, 1, 7))
+ -- print(" 0, 7",utf.xsub(str, 0, 7),utf.sub(str, 0, 7))
+ -- print(" 0, 9",utf.xsub(str, 0, 9),utf.sub(str, 0, 9))
+ -- print(" 4 ",utf.xsub(str, 4 ),utf.sub(str, 4 ))
+ -- print(" 0 ",utf.xsub(str, 0 ),utf.sub(str, 0 ))
+ -- print(" 0, 0",utf.xsub(str, 0, 0),utf.sub(str, 0, 0))
+ -- print(" 4, 4",utf.xsub(str, 4, 4),utf.sub(str, 4, 4))
+ -- print(" 4, 0",utf.xsub(str, 4, 0),utf.sub(str, 4, 0))
+ -- print("-3, 0",utf.xsub(str,-3, 0),utf.sub(str,-3, 0))
+ -- print(" 0,-3",utf.xsub(str, 0,-3),utf.sub(str, 0,-3))
+ -- print(" 5,-3",utf.xsub(str,-5,-3),utf.sub(str,-5,-3))
+ -- print("-3 ",utf.xsub(str,-3 ),utf.sub(str,-3 ))
+
+end
+
+-- a replacement for simple gsubs:
+
+-- function utf.remapper(mapping)
+-- local pattern = Cs((p_utf8character/mapping)^0)
+-- return function(str)
+-- if not str or str == "" then
+-- return ""
+-- else
+-- return lpegmatch(pattern,str)
+-- end
+-- end, pattern
+-- end
+
+function utf.remapper(mapping,option,action) -- static also returns a pattern
+ local variant = type(mapping)
+ if variant == "table" then
+ action = action or mapping
+ if option == "dynamic" then
+ local pattern = false
+ table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern = false end)
+ return function(str)
+ if not str or str == "" then
+ return ""
+ else
+ if not pattern then
+ pattern = Cs((tabletopattern(mapping)/action + p_utf8character)^0)
+ end
+ return lpegmatch(pattern,str)
+ end
+ end
+ elseif option == "pattern" then
+ return Cs((tabletopattern(mapping)/action + p_utf8character)^0)
+ -- elseif option == "static" then
+ else
+ local pattern = Cs((tabletopattern(mapping)/action + p_utf8character)^0)
+ return function(str)
+ if not str or str == "" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
+ end
+ end, pattern
+ end
+ elseif variant == "function" then
+ if option == "pattern" then
+ return Cs((p_utf8character/mapping + p_utf8character)^0)
+ else
+ local pattern = Cs((p_utf8character/mapping + p_utf8character)^0)
+ return function(str)
+ if not str or str == "" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
+ end
+ end, pattern
+ end
+ else
+ -- is actually an error
+ return function(str)
+ return str or ""
+ end
+ end
+end
+
+-- local remap = utf.remapper { a = 'd', b = "c", c = "b", d = "a" }
+-- print(remap("abcd 1234 abcd"))
+
+function utf.replacer(t) -- no precheck, always string builder
+ local r = replacer(t,false,false,true)
+ return function(str)
+ return lpegmatch(r,str)
+ end
+end
+
+function utf.subtituter(t) -- with precheck and no building if no match
+ local f = finder (t)
+ local r = replacer(t,false,false,true)
+ return function(str)
+ local i = lpegmatch(f,str)
+ if not i then
+ return str
+ elseif i > #str then
+ return str
+ else
+ -- return sub(str,1,i-2) .. lpegmatch(r,str,i-1) -- slower
+ return lpegmatch(r,str)
+ end
+ end
+end
+
+-- inspect(utf.split("a b c d"))
+-- inspect(utf.split("a b c d",true))
+
+local utflinesplitter = p_utfbom^-1 * lpeg.tsplitat(p_newline)
+local utfcharsplitter_ows = p_utfbom^-1 * Ct(C(p_utf8character)^0)
+local utfcharsplitter_iws = p_utfbom^-1 * Ct((p_whitespace^1 + C(p_utf8character))^0)
+local utfcharsplitter_raw = Ct(C(p_utf8character)^0)
+
+patterns.utflinesplitter = utflinesplitter
+
+function utf.splitlines(str)
+ return lpegmatch(utflinesplitter,str or "")
+end
+
+function utf.split(str,ignorewhitespace) -- new
+ if ignorewhitespace then
+ return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+ return lpegmatch(utfcharsplitter_ows,str or "")
+ end
+end
+
+function utf.totable(str) -- keeps bom
+ return lpegmatch(utfcharsplitter_raw,str)
+end
+
+-- 0 EF BB BF UTF-8
+-- 1 FF FE UTF-16-little-endian
+-- 2 FE FF UTF-16-big-endian
+-- 3 FF FE 00 00 UTF-32-little-endian
+-- 4 00 00 FE FF UTF-32-big-endian
+--
+-- \000 fails in <= 5.0 but is valid in >=5.1 where %z is depricated
+
+-- utf.name = {
+-- [0] = 'utf-8',
+-- [1] = 'utf-16-le',
+-- [2] = 'utf-16-be',
+-- [3] = 'utf-32-le',
+-- [4] = 'utf-32-be'
+-- }
+--
+-- function utf.magic(f)
+-- local str = f:read(4)
+-- if not str then
+-- f:seek('set')
+-- return 0
+-- -- elseif find(str,"^%z%z\254\255") then -- depricated
+-- -- elseif find(str,"^\000\000\254\255") then -- not permitted and bugged
+-- elseif find(str,"\000\000\254\255",1,true) then -- seems to work okay (TH)
+-- return 4
+-- -- elseif find(str,"^\255\254%z%z") then -- depricated
+-- -- elseif find(str,"^\255\254\000\000") then -- not permitted and bugged
+-- elseif find(str,"\255\254\000\000",1,true) then -- seems to work okay (TH)
+-- return 3
+-- elseif find(str,"^\254\255") then
+-- f:seek('set',2)
+-- return 2
+-- elseif find(str,"^\255\254") then
+-- f:seek('set',2)
+-- return 1
+-- elseif find(str,"^\239\187\191") then
+-- f:seek('set',3)
+-- return 0
+-- else
+-- f:seek('set')
+-- return 0
+-- end
+-- end
+
+function utf.magic(f) -- not used
+ local str = f:read(4) or ""
+ local off = lpegmatch(p_utfoffset,str)
+ if off < 4 then
+ f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
+end
+
+local utf16_to_utf8_be, utf16_to_utf8_le
+local utf32_to_utf8_be, utf32_to_utf8_le
+
+local utf_16_be_getbom = patterns.utfbom_16_be^-1
+local utf_16_le_getbom = patterns.utfbom_16_le^-1
+local utf_32_be_getbom = patterns.utfbom_32_be^-1
+local utf_32_le_getbom = patterns.utfbom_32_le^-1
+
+local utf_16_be_linesplitter = utf_16_be_getbom * lpeg.tsplitat(patterns.utf_16_be_nl)
+local utf_16_le_linesplitter = utf_16_le_getbom * lpeg.tsplitat(patterns.utf_16_le_nl)
+local utf_32_be_linesplitter = utf_32_be_getbom * lpeg.tsplitat(patterns.utf_32_be_nl)
+local utf_32_le_linesplitter = utf_32_le_getbom * lpeg.tsplitat(patterns.utf_32_le_nl)
+
+-- we have three possibilities: bytepairs (using tables), gmatch (using tables), gsub and
+-- lpeg. Bytepairs are the fastert but as soon as we need to remove bombs and so the gain
+-- is less due to more testing. Also, we seldom have to convert utf16 so we don't care to
+-- much about a few milliseconds more runtime. The lpeg variant is upto 20% slower but
+-- still pretty fast.
+--
+-- for historic resone we keep the bytepairs variants around .. beware they don't grab the
+-- bom like the lpegs do so they're not dropins in the functions that follow
+--
+-- utf16_to_utf8_be = function(s)
+-- if not s then
+-- return nil
+-- elseif s == "" then
+-- return ""
+-- end
+-- local result, r, more = { }, 0, 0
+-- for left, right in bytepairs(s) do
+-- if right then
+-- local now = 256*left + right
+-- if more > 0 then
+-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong
+-- more = 0
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- elseif now >= 0xD800 and now <= 0xDBFF then
+-- more = now
+-- else
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- end
+-- end
+-- end
+-- return concat(result)
+-- end
+--
+-- local utf16_to_utf8_be_t = function(t)
+-- if not t then
+-- return nil
+-- elseif type(t) == "string" then
+-- t = lpegmatch(utf_16_be_linesplitter,t)
+-- end
+-- local result = { } -- we reuse result
+-- for i=1,#t do
+-- local s = t[i]
+-- if s ~= "" then
+-- local r, more = 0, 0
+-- for left, right in bytepairs(s) do
+-- if right then
+-- local now = 256*left + right
+-- if more > 0 then
+-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000
+-- more = 0
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- elseif now >= 0xD800 and now <= 0xDBFF then
+-- more = now
+-- else
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- end
+-- end
+-- end
+-- t[i] = concat(result,"",1,r) -- we reused tmp, hence t
+-- end
+-- end
+-- return t
+-- end
+--
+-- utf16_to_utf8_le = function(s)
+-- if not s then
+-- return nil
+-- elseif s == "" then
+-- return ""
+-- end
+-- local result, r, more = { }, 0, 0
+-- for left, right in bytepairs(s) do
+-- if right then
+-- local now = 256*right + left
+-- if more > 0 then
+-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000
+-- more = 0
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- elseif now >= 0xD800 and now <= 0xDBFF then
+-- more = now
+-- else
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- end
+-- end
+-- end
+-- return concat(result)
+-- end
+--
+-- local utf16_to_utf8_le_t = function(t)
+-- if not t then
+-- return nil
+-- elseif type(t) == "string" then
+-- t = lpegmatch(utf_16_le_linesplitter,t)
+-- end
+-- local result = { } -- we reuse result
+-- for i=1,#t do
+-- local s = t[i]
+-- if s ~= "" then
+-- local r, more = 0, 0
+-- for left, right in bytepairs(s) do
+-- if right then
+-- local now = 256*right + left
+-- if more > 0 then
+-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000
+-- more = 0
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- elseif now >= 0xD800 and now <= 0xDBFF then
+-- more = now
+-- else
+-- r = r + 1
+-- result[r] = utfchar(now)
+-- end
+-- end
+-- end
+-- t[i] = concat(result,"",1,r) -- we reused tmp, hence t
+-- end
+-- end
+-- return t
+-- end
+--
+-- local utf32_to_utf8_be_t = function(t)
+-- if not t then
+-- return nil
+-- elseif type(t) == "string" then
+-- t = lpegmatch(utflinesplitter,t)
+-- end
+-- local result = { } -- we reuse result
+-- for i=1,#t do
+-- local r, more = 0, -1
+-- for a,b in bytepairs(t[i]) do
+-- if a and b then
+-- if more < 0 then
+-- more = 256*256*256*a + 256*256*b
+-- else
+-- r = r + 1
+-- result[t] = utfchar(more + 256*a + b)
+-- more = -1
+-- end
+-- else
+-- break
+-- end
+-- end
+-- t[i] = concat(result,"",1,r)
+-- end
+-- return t
+-- end
+--
+-- local utf32_to_utf8_le_t = function(t)
+-- if not t then
+-- return nil
+-- elseif type(t) == "string" then
+-- t = lpegmatch(utflinesplitter,t)
+-- end
+-- local result = { } -- we reuse result
+-- for i=1,#t do
+-- local r, more = 0, -1
+-- for a,b in bytepairs(t[i]) do
+-- if a and b then
+-- if more < 0 then
+-- more = 256*b + a
+-- else
+-- r = r + 1
+-- result[t] = utfchar(more + 256*256*256*b + 256*256*a)
+-- more = -1
+-- end
+-- else
+-- break
+-- end
+-- end
+-- t[i] = concat(result,"",1,r)
+-- end
+-- return t
+-- end
+
+local more = 0
+
+local p_utf16_to_utf8_be = C(1) * C(1) /function(left,right)
+ local now = 256*byte(left) + byte(right)
+ if more > 0 then
+ now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000
+ more = 0
+ return utfchar(now)
+ elseif now >= 0xD800 and now <= 0xDBFF then
+ more = now
+ return "" -- else the c's end up in the stream
+ else
+ return utfchar(now)
+ end
+end
+
+local p_utf16_to_utf8_le = C(1) * C(1) /function(right,left)
+ local now = 256*byte(left) + byte(right)
+ if more > 0 then
+ now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000
+ more = 0
+ return utfchar(now)
+ elseif now >= 0xD800 and now <= 0xDBFF then
+ more = now
+ return "" -- else the c's end up in the stream
+ else
+ return utfchar(now)
+ end
+end
+local p_utf32_to_utf8_be = C(1) * C(1) * C(1) * C(1) /function(a,b,c,d)
+ return utfchar(256*256*256*byte(a) + 256*256*byte(b) + 256*byte(c) + byte(d))
+end
+
+local p_utf32_to_utf8_le = C(1) * C(1) * C(1) * C(1) /function(a,b,c,d)
+ return utfchar(256*256*256*byte(d) + 256*256*byte(c) + 256*byte(b) + byte(a))
+end
+
+p_utf16_to_utf8_be = P(true) / function() more = 0 end * utf_16_be_getbom * Cs(p_utf16_to_utf8_be^0)
+p_utf16_to_utf8_le = P(true) / function() more = 0 end * utf_16_le_getbom * Cs(p_utf16_to_utf8_le^0)
+p_utf32_to_utf8_be = P(true) / function() more = 0 end * utf_32_be_getbom * Cs(p_utf32_to_utf8_be^0)
+p_utf32_to_utf8_le = P(true) / function() more = 0 end * utf_32_le_getbom * Cs(p_utf32_to_utf8_le^0)
+
+patterns.utf16_to_utf8_be = p_utf16_to_utf8_be
+patterns.utf16_to_utf8_le = p_utf16_to_utf8_le
+patterns.utf32_to_utf8_be = p_utf32_to_utf8_be
+patterns.utf32_to_utf8_le = p_utf32_to_utf8_le
+
+utf16_to_utf8_be = function(s)
+ if s and s ~= "" then
+ return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+ return s
+ end
+end
+
+local utf16_to_utf8_be_t = function(t)
+ if not t then
+ return nil
+ elseif type(t) == "string" then
+ t = lpegmatch(utf_16_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s = t[i]
+ if s ~= "" then
+ t[i] = lpegmatch(p_utf16_to_utf8_be,s)
+ end
+ end
+ return t
+end
+
+utf16_to_utf8_le = function(s)
+ if s and s ~= "" then
+ return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+ return s
+ end
+end
+
+local utf16_to_utf8_le_t = function(t)
+ if not t then
+ return nil
+ elseif type(t) == "string" then
+ t = lpegmatch(utf_16_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s = t[i]
+ if s ~= "" then
+ t[i] = lpegmatch(p_utf16_to_utf8_le,s)
+ end
+ end
+ return t
+end
+
+utf32_to_utf8_be = function(s)
+ if s and s ~= "" then
+ return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+ return s
+ end
+end
+
+local utf32_to_utf8_be_t = function(t)
+ if not t then
+ return nil
+ elseif type(t) == "string" then
+ t = lpegmatch(utf_32_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s = t[i]
+ if s ~= "" then
+ t[i] = lpegmatch(p_utf32_to_utf8_be,s)
+ end
+ end
+ return t
+end
+
+utf32_to_utf8_le = function(s)
+ if s and s ~= "" then
+ return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+ return s
+ end
+end
+
+local utf32_to_utf8_le_t = function(t)
+ if not t then
+ return nil
+ elseif type(t) == "string" then
+ t = lpegmatch(utf_32_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s = t[i]
+ if s ~= "" then
+ t[i] = lpegmatch(p_utf32_to_utf8_le,s)
+ end
+ end
+ return t
+end
+
+utf.utf16_to_utf8_le_t = utf16_to_utf8_le_t
+utf.utf16_to_utf8_be_t = utf16_to_utf8_be_t
+utf.utf32_to_utf8_le_t = utf32_to_utf8_le_t
+utf.utf32_to_utf8_be_t = utf32_to_utf8_be_t
+
+utf.utf16_to_utf8_le = utf16_to_utf8_le
+utf.utf16_to_utf8_be = utf16_to_utf8_be
+utf.utf32_to_utf8_le = utf32_to_utf8_le
+utf.utf32_to_utf8_be = utf32_to_utf8_be
+
+function utf.utf8_to_utf8_t(t)
+ return type(t) == "string" and lpegmatch(utflinesplitter,t) or t
+end
+
+function utf.utf16_to_utf8_t(t,endian)
+ return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
+end
+
+function utf.utf32_to_utf8_t(t,endian)
+ return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
+end
+
+local function little(b)
+ if b < 0x10000 then
+ return char(b%256,rshift(b,8))
+ else
+ b = b - 0x10000
+ local b1 = rshift(b,10) + 0xD800
+ local b2 = b%1024 + 0xDC00
+ return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
+end
+
+local function big(b)
+ if b < 0x10000 then
+ return char(rshift(b,8),b%256)
+ else
+ b = b - 0x10000
+ local b1 = rshift(b,10) + 0xD800
+ local b2 = b%1024 + 0xDC00
+ return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
+end
+
+local l_remap = Cs((p_utf8byte/little+P(1)/"")^0)
+local b_remap = Cs((p_utf8byte/big +P(1)/"")^0)
+
+local function utf8_to_utf16_be(str,nobom)
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255) .. lpegmatch(b_remap,str)
+ end
+end
+
+local function utf8_to_utf16_le(str,nobom)
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254) .. lpegmatch(l_remap,str)
+ end
+end
+
+utf.utf8_to_utf16_be = utf8_to_utf16_be
+utf.utf8_to_utf16_le = utf8_to_utf16_le
+
+function utf.utf8_to_utf16(str,littleendian,nobom)
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
+end
+
+local pattern = Cs (
+ (p_utf8byte / function(unicode ) return format( "0x%04X", unicode) end) *
+ (p_utf8byte * Carg(1) / function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
+)
+
+function utf.tocodes(str,separator)
+ return lpegmatch(pattern,str,1,separator or " ")
+end
+
+function utf.ustring(s)
+ return format("U+%05X",type(s) == "number" and s or utfbyte(s))
+end
+
+function utf.xstring(s)
+ return format("0x%05X",type(s) == "number" and s or utfbyte(s))
+end
+
+function utf.toeight(str)
+ if not str or str == "" then
+ return nil
+ end
+ local utftype = lpegmatch(p_utfstricttype,str)
+ if utftype == "utf-8" then
+ return sub(str,4) -- remove the bom
+ elseif utftype == "utf-16-be" then
+ return utf16_to_utf8_be(str) -- bom gets removed
+ elseif utftype == "utf-16-le" then
+ return utf16_to_utf8_le(str) -- bom gets removed
+ else
+ return str
+ end
+end
+
+--
+
+do
+
+ local p_nany = p_utf8character / ""
+ local cache = { }
+
+ function utf.count(str,what)
+ if type(what) == "string" then
+ local p = cache[what]
+ if not p then
+ p = Cs((P(what)/" " + p_nany)^0)
+ cache[p] = p
+ end
+ return #lpegmatch(p,str)
+ else -- 4 times slower but still faster than / function
+ return #lpegmatch(Cs((P(what)/" " + p_nany)^0),str)
+ end
+ end
+
+end
+
+if not string.utfvalues then
+
+ -- So, a logical next step is to check for the values variant. It over five times
+ -- slower than the built-in string.utfvalues. I optimized it a bit for n=0,1.
+
+ ----- wrap, yield, gmatch = coroutine.wrap, coroutine.yield, string.gmatch
+ local find = string.find
+
+ local dummy = function()
+ -- we share this one
+ end
+
+ -- function string.utfvalues(str)
+ -- local n = #str
+ -- if n == 0 then
+ -- return wrap(dummy)
+ -- elseif n == 1 then
+ -- return wrap(function() yield(utfbyte(str)) end)
+ -- else
+ -- return wrap(function() for s in gmatch(str,".[\128-\191]*") do
+ -- yield(utfbyte(s))
+ -- end end)
+ -- end
+ -- end
+ --
+ -- faster:
+
+ function string.utfvalues(str)
+ local n = #str
+ if n == 0 then
+ return dummy
+ elseif n == 1 then
+ return function() return utfbyte(str) end
+ else
+ local p = 1
+ -- local n = #str
+ return function()
+ -- if p <= n then -- slower than the last find
+ local b, e = find(str,".[\128-\191]*",p)
+ if b then
+ p = e + 1
+ return utfbyte(sub(str,b,e))
+ end
+ -- end
+ end
+ end
+ end
+
+ -- slower:
+ --
+ -- local pattern = C(p_utf8character) * Cp()
+ -- ----- pattern = p_utf8character/utfbyte * Cp()
+ -- ----- pattern = p_utf8byte * Cp()
+ --
+ -- function string.utfvalues(str) -- one of the cases where a find is faster than an lpeg
+ -- local n = #str
+ -- if n == 0 then
+ -- return dummy
+ -- elseif n == 1 then
+ -- return function() return utfbyte(str) end
+ -- else
+ -- local p = 1
+ -- return function()
+ -- local s, e = lpegmatch(pattern,str,p)
+ -- if e then
+ -- p = e
+ -- return utfbyte(s)
+ -- -- return s
+ -- end
+ -- end
+ -- end
+ -- end
+
+end
+
+utf.values = string.utfvalues
+
+function utf.chrlen(u) -- u is number
+ return
+ (u < 0x80 and 1) or
+ (u < 0xE0 and 2) or
+ (u < 0xF0 and 3) or
+ (u < 0xF8 and 4) or
+ (u < 0xFC and 5) or
+ (u < 0xFE and 6) or 0
+end
+
+-- hashing saves a little but not that much in practice
+--
+-- local utf32 = table.setmetatableindex(function(t,k) local v = toutf32(k) t[k] = v return v end)
+
+if bit32 then
+
+ local extract = bit32.extract
+ local char = string.char
+
+ function utf.toutf32string(n)
+ if n <= 0xFF then
+ return
+ char(n) ..
+ "\000\000\000"
+ elseif n <= 0xFFFF then
+ return
+ char(extract(n, 0,8)) ..
+ char(extract(n, 8,8)) ..
+ "\000\000"
+ elseif n <= 0xFFFFFF then
+ return
+ char(extract(n, 0,8)) ..
+ char(extract(n, 8,8)) ..
+ char(extract(n,16,8)) ..
+ "\000"
+ else
+ return
+ char(extract(n, 0,8)) ..
+ char(extract(n, 8,8)) ..
+ char(extract(n,16,8)) ..
+ char(extract(n,24,8))
+ end
+ end
+
+end
+
+-- goodie:
+
+local len = utf.len
+local rep = rep
+
+function string.utfpadd(s,n)
+ if n and n ~= 0 then
+ local l = len(s)
+ if n > 0 then
+ local d = n - l
+ if d > 0 then
+ return rep(c or " ",d) .. s
+ end
+ else
+ local d = - n - l
+ if d > 0 then
+ return s .. rep(c or " ",d)
+ end
+ end
+ end
+ return s
+end
+
+-- goodies
+
+do
+
+ local utfcharacters = utf.characters or string.utfcharacters
+ local utfchar = utf.char or string.utfcharacter
+
+ lpeg.UP = P
+
+ if utfcharacters then
+
+ function lpeg.US(str)
+ local p = P(false)
+ for uc in utfcharacters(str) do
+ p = p + P(uc)
+ end
+ return p
+ end
+
+ else
+
+ function lpeg.US(str)
+ local p = P(false)
+ local f = function(uc)
+ p = p + P(uc)
+ end
+ lpegmatch((p_utf8char/f)^0,str)
+ return p
+ end
+
+ end
+
+ local range = p_utf8byte * p_utf8byte + Cc(false) -- utf8byte is already a capture
+
+ function lpeg.UR(str,more)
+ local first, last
+ if type(str) == "number" then
+ first = str
+ last = more or first
+ else
+ first, last = lpegmatch(range,str)
+ if not last then
+ return P(str)
+ end
+ end
+ if first == last then
+ return P(str)
+ end
+ if not utfchar then
+ utfchar = utf.char -- maybe delayed
+ end
+ if utfchar and (last - first < 8) then -- a somewhat arbitrary criterium
+ local p = P(false)
+ for i=first,last do
+ p = p + P(utfchar(i))
+ end
+ return p -- nil when invalid range
+ else
+ local f = function(b)
+ return b >= first and b <= last
+ end
+ -- tricky, these nested captures
+ return p_utf8byte / f -- nil when invalid range
+ end
+ end
+
+ -- print(lpeg.match(lpeg.Cs((C(lpeg.UR("αω"))/{ ["χ"] = "OEPS" })^0),"αωχαω"))
+
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua b/macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua
new file mode 100644
index 0000000000..85fe1ae975
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua
@@ -0,0 +1,349 @@
+if not modules then modules = { } end modules ['luatex-fonts'] = {
+ version = 1.001,
+ comment = "companion to luatex-fonts.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- A merged file is generated with:
+--
+-- mtxrun --script package --merge --stripcontext luatex-fonts.lua
+--
+-- A needed resource file is made by:
+--
+-- mtxrun --script context luatex-basics-prepare.tex
+--
+-- A font (generic) database is created with:
+--
+-- mtxrun --script font --reload --simple
+
+-- The following code isolates the generic context code from already defined or to be defined
+-- namespaces. This is the reference loader for plain tex. This generic code is also used in
+-- luaotfload which is a low level lualatex opentype font loader but somehow has gotten a bit
+-- too generic name / prefix, originally set up and maintained by Khaled Hosny. Currently that
+-- set of derived files is maintained by a larger team lead by Philipp Gesang so when there are
+-- issues with this code in latex, you can best contact him. It might make sense then to first
+-- check if context has the same issue. We do our best to keep the interface as clean as possible.
+--
+-- The code base is rather stable now, especially if you stay away from the non generic code. All
+-- relevant data is organized in tables within the main table of a font instance. There are a few
+-- places where in context other code is plugged in, but this does not affect the core code. Users
+-- can (given that their macro package provides this option) access the font data (characters,
+-- descriptions, properties, parameters, etc) of this main table. The documentation is part of
+-- context. There is also a manual for the helper libraries (maintained as part of the cld manuals).
+--
+-- Future versions will probably have some more specific context code removed, like tracing and
+-- obscure hooks, so that we have a more efficient version (and less files too). So, don't depend
+-- too much on low level code that is meant for context as it can change without notice. We might
+-- also add more helper code here, but that depends to what extend metatex (sidetrack of context)
+-- evolves into a low level layer (depends on time, as usual).
+
+-- The code here is the same as in context version 2015.09.11 but the rendering in context can be
+-- different from generic. This can be a side effect of additional callbacks, additional features
+-- and interferences between mechanisms between macro packages. We use the rendering in context
+-- and luatex-plain as reference for issues.
+
+utf = utf or (unicode and unicode.utf8) or { }
+
+-- We have some (global) hooks (for latex):
+
+if not non_generic_context then
+ non_generic_context = { }
+end
+
+if not non_generic_context.luatex_fonts then
+ non_generic_context.luatex_fonts = {
+ -- load_before = nil,
+ -- load_after = nil,
+ -- skip_loading = nil,
+ }
+end
+
+if not generic_context then
+ generic_context = { }
+end
+
+if not generic_context.push_namespaces then
+
+ function generic_context.push_namespaces()
+ -- logs.report("system","push namespace")
+ local normalglobal = { }
+ for k, v in next, _G do
+ normalglobal[k] = v
+ end
+ return normalglobal
+ end
+
+ function generic_context.pop_namespaces(normalglobal,isolate)
+ if normalglobal then
+ -- logs.report("system","pop namespace")
+ for k, v in next, _G do
+ if not normalglobal[k] then
+ generic_context[k] = v
+ if isolate then
+ _G[k] = nil
+ end
+ end
+ end
+ for k, v in next, normalglobal do
+ _G[k] = v
+ end
+ -- just to be sure:
+ setmetatable(generic_context,_G)
+ else
+ logs.report("system","fatal error: invalid pop of generic_context")
+ os.exit()
+ end
+ end
+
+end
+
+local whatever = generic_context.push_namespaces()
+
+-- We keep track of load time by storing the current time. That way we cannot be accused
+-- of slowing down loading too much. Anyhow, there is no reason for this library to perform
+-- slower in any other package as it does in context.
+--
+-- Please don't update to this version without proper testing. It might be that this version
+-- lags behind stock context and the only formal release takes place around tex live code
+-- freeze.
+
+local starttime = os.gettimeofday()
+
+-- As we don't use the context file searching, we need to initialize the kpse library. As the
+-- progname can be anything we will temporary switch to the context namespace if needed. Just
+-- adding the context paths to the path specification is somewhat faster.
+--
+-- Now, with lua 5.2 being used we might create a special ENV for this.
+
+-- kpse.set_program_name("luatex")
+
+-- One can define texio.reporter as alternative terminal/log writer. That's as far
+-- as I want to go with this.
+
+local ctxkpse = nil
+local verbose = true
+
+if not logs or not logs.report then
+ if not logs then
+ logs = { }
+ end
+ function logs.report(c,f,...)
+ local r = texio.reporter or texio.write_nl
+ if f then
+ r(c .. " : " .. string.format(f,...))
+ else
+ r("")
+ end
+ end
+end
+
+local function loadmodule(name,continue)
+ local foundname = kpse.find_file(name,"tex") or ""
+ if not foundname then
+ if not ctxkpse then
+ ctxkpse = kpse.new("luatex","context")
+ end
+ foundname = ctxkpse:find_file(name,"tex") or ""
+ end
+ if foundname == "" then
+ if not continue then
+ logs.report("system","unable to locate file '%s'",name)
+ os.exit()
+ end
+ else
+ if verbose then
+ logs.report("system","loading '%s'",foundname) -- no file.basename yet
+ end
+ dofile(foundname)
+ end
+end
+
+if non_generic_context.luatex_fonts.load_before then
+ loadmodule(non_generic_context.luatex_fonts.load_before,true)
+end
+
+if non_generic_context.luatex_fonts.skip_loading ~= true then
+
+ loadmodule('luatex-fonts-merged.lua',true)
+
+ if fonts then
+
+ if not fonts._merge_loaded_message_done_ then
+ texio.write_nl("log", "!")
+ texio.write_nl("log", "! I am using the merged version of 'luatex-fonts.lua' here. If")
+ texio.write_nl("log", "! you run into problems or experience unexpected behaviour, and")
+ texio.write_nl("log", "! if you have ConTeXt installed you can try to delete the file")
+ texio.write_nl("log", "! 'luatex-font-merged.lua' as I might then use the possibly")
+ texio.write_nl("log", "! updated libraries. The merged version is not supported as it")
+ texio.write_nl("log", "! is a frozen instance. Problems can be reported to the ConTeXt")
+ texio.write_nl("log", "! mailing list.")
+ texio.write_nl("log", "!")
+ end
+
+ fonts._merge_loaded_message_done_ = true
+
+ else
+
+ -- The following helpers are a bit overkill but I don't want to mess up
+ -- context code for the sake of general generality. Around version 1.0
+ -- there will be an official api defined.
+ --
+ -- So, I will strip these libraries and see what is really needed so that
+ -- we don't have this overhead in the generic modules. The next section
+ -- is only there for the packager, so stick to using luatex-fonts with
+ -- luatex-fonts-merged.lua and forget about the rest. The following list
+ -- might change without prior notice (for instance because we shuffled
+ -- code around).
+
+ loadmodule("l-lua.lua")
+ loadmodule("l-lpeg.lua")
+ loadmodule("l-function.lua")
+ loadmodule("l-string.lua")
+ loadmodule("l-table.lua")
+ loadmodule("l-io.lua")
+ loadmodule("l-file.lua")
+ loadmodule("l-boolean.lua")
+ loadmodule("l-math.lua")
+
+ -- A few slightly higher level support modules:
+
+ loadmodule("util-str.lua") -- future versions can ship without this one
+ loadmodule("util-fil.lua") -- future versions can ship without this one
+
+ -- The following modules contain code that is either not used at all
+ -- outside context or will fail when enabled due to lack of other
+ -- modules.
+
+ -- First we load a few helper modules. This is about the miminum needed
+ -- to let the font modules do their work. Don't depend on their functions
+ -- as we might strip them in future versions of this generic variant.
+
+ loadmodule('luatex-basics-gen.lua')
+ loadmodule('data-con.lua')
+
+ -- We do need some basic node support. The code in there is not for
+ -- general use as it might change.
+
+ loadmodule('luatex-basics-nod.lua')
+
+ -- We ship a resources needed for font handling (more might end up here).
+
+ loadmodule('luatex-basics-chr.lua')
+
+ -- Now come the font modules that deal with traditional tex fonts as well
+ -- as open type fonts.
+ --
+ -- The font database file (if used at all) must be put someplace visible
+ -- for kpse and is not shared with context. The mtx-fonts script can be
+ -- used to generate this file (using the --reload --force --simple option).
+
+ loadmodule('font-ini.lua')
+ loadmodule('luatex-fonts-mis.lua')
+ loadmodule('font-con.lua')
+ loadmodule('luatex-fonts-enc.lua')
+ loadmodule('font-cid.lua')
+ loadmodule('font-map.lua')
+
+ -- We use a bit simpler database because using the context one demands
+ -- loading more helper code and although it is more flexible (more ways
+ -- to resolve and so) it will never be uses in plain/latex anyway, so
+ -- let's stick to a simple approach.
+
+ loadmodule('luatex-fonts-syn.lua')
+
+ -- We need some helpers.
+
+ loadmodule('font-vfc.lua')
+
+ -- This is the bulk of opentype code.
+
+ loadmodule('font-otr.lua')
+ loadmodule('font-oti.lua')
+ loadmodule('font-ott.lua')
+ loadmodule('font-cff.lua')
+ loadmodule('font-ttf.lua')
+ loadmodule('font-dsp.lua')
+ loadmodule('font-oup.lua')
+ loadmodule('font-otl.lua')
+ loadmodule('font-oto.lua')
+ loadmodule('font-otj.lua')
+ loadmodule('font-ota.lua')
+ loadmodule('font-ots.lua')
+ loadmodule('font-osd.lua')
+ loadmodule('font-ocl.lua')
+ loadmodule('font-otc.lua')
+
+ -- The code for type one fonts.
+
+ loadmodule('font-onr.lua')
+ loadmodule('font-one.lua')
+ loadmodule('font-afk.lua')
+
+ -- And for traditional TeX fonts.
+
+ loadmodule('luatex-fonts-tfm.lua')
+
+ -- Some common code.
+
+ loadmodule('font-lua.lua')
+ loadmodule('font-def.lua')
+
+ -- We support xetex compatible specifiers (plain/latex only).
+
+ loadmodule('luatex-fonts-def.lua') -- was font-xtx.lua
+
+ -- Here come some additional features.
+
+ loadmodule('luatex-fonts-ext.lua')
+ loadmodule('font-imp-tex.lua')
+ loadmodule('font-imp-ligatures.lua')
+ loadmodule('font-imp-italics.lua')
+ loadmodule('font-imp-effects.lua')
+ loadmodule('luatex-fonts-lig.lua')
+
+ -- We need to plug into a callback and the following module implements the
+ -- handlers. Actual plugging in happens later.
+
+ loadmodule('luatex-fonts-gbn.lua')
+
+ end
+
+end
+
+if non_generic_context.luatex_fonts.load_after then
+ loadmodule(non_generic_context.luatex_fonts.load_after,true)
+end
+
+resolvers.loadmodule = loadmodule
+
+-- In order to deal with the fonts we need to initialize some callbacks. One can overload them later
+-- on if needed. First a bit of abstraction.
+
+generic_context.callback_ligaturing = false
+generic_context.callback_kerning = false
+generic_context.callback_pre_linebreak_filter = nodes.simple_font_handler
+generic_context.callback_hpack_filter = nodes.simple_font_handler
+generic_context.callback_define_font = fonts.definers.read
+
+-- The next ones can be done at a different moment if needed. You can create a generic_context namespace
+-- and set no_callbacks_yet to true, load this module, and enable the callbacks later. So, there is really
+-- *no* need to create a alternative for luatex-fonts.lua and luatex-fonts-merged.lua: just load this one
+-- and overload if needed.
+
+if not generic_context.no_callbacks_yet then
+
+ callback.register('ligaturing', generic_context.callback_ligaturing)
+ callback.register('kerning', generic_context.callback_kerning)
+ callback.register('pre_linebreak_filter', generic_context.callback_pre_linebreak_filter)
+ callback.register('hpack_filter', generic_context.callback_hpack_filter)
+ callback.register('define_font' , generic_context.callback_define_font)
+
+end
+
+-- We're done.
+
+logs.report("system","luatex-fonts.lua loaded in %0.3f seconds", os.gettimeofday()-starttime)
+
+generic_context.pop_namespaces(whatever)
diff --git a/macros/luatex/generic/luaotfload/fontloader-reference-load-order.tex b/macros/luatex/generic/luaotfload/fontloader-reference-load-order.tex
new file mode 100644
index 0000000000..7b457e9b4f
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-reference-load-order.tex
@@ -0,0 +1,140 @@
+%D \module
+%D [ file=luatex-fonts,
+%D version=2009.12.01,
+%D title=\LUATEX\ Support Macros,
+%D subtitle=Generic \OPENTYPE\ Font Handler,
+%D author=Hans Hagen,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+
+%D \subject{Welcome}
+%D
+%D This file is one of a set of basic functionality enhancements
+%D for \LUATEX\ derived from the \CONTEXT\ \MKIV\ code base. Please
+%D don't polute the \type {luatex-*} namespace with code not coming
+%D from the \CONTEXT\ development team as we may add more files.
+%D
+%D As this is an experimental setup, it might not always work out as
+%D expected. Around \LUATEX\ version 0.50 we expect the code to be
+%D more or less okay.
+%D
+%D This file implements a basic font system for a bare \LUATEX\
+%D system. By default \LUATEX\ only knows about the classic \TFM\
+%D fonts but it can read other font formats and pass them to \LUA.
+%D With some glue code one can then construct a suitable \TFM\
+%D representation that \LUATEX\ can work with. For more advanced font
+%D support a bit more code is needed that needs to be hooked
+%D into the callback mechanism.
+%D
+%D This file is currently rather simple: it just loads the \LUA\ file
+%D with the same name. An example of a \type {luatex.tex} file that is
+%D just plain \TEX:
+%D
+%D \starttyping
+%D \catcode`\{=1 % left brace is begin-group character
+%D \catcode`\}=2 % right brace is end-group character
+%D
+%D \input plain
+%D
+%D \everyjob\expandafter{\the\everyjob\input luatex-fonts\relax}
+%D
+%D \dump
+%D \stoptyping
+%D
+%D We could load the \LUA\ file in \type {\everyjob} but maybe some
+%D day we need more here.
+%D
+%D When defining a font you can use two prefixes. A \type {file:}
+%D prefix forced a file search, while a \type {name:} prefix will
+%D result in consulting the names database. Such a database can be
+%D generated with:
+%D
+%D \starttyping
+%D mtxrun --usekpse --script fonts --names
+%D \stoptyping
+%D
+%D This will generate a file \type {luatex-fonts-names.lua} that has
+%D to be placed in a location where it can be found by \KPSE. Beware:
+%D the \type {--kpseonly} flag is only used outside \CONTEXT\ and
+%D provides very limited functionality, just enough for this task.
+%D
+%D The code loaded here does not come out of thin air, but is mostly
+%D shared with \CONTEXT, however, in that macropackage we go beyond
+%D what is provided here. When you use the code packaged here you
+%D need to keep a few things in mind:
+%D
+%D \startitemize
+%D
+%D \item This subsystem will be extended, improved etc. in about the
+%D same pace as \CONTEXT\ \MKIV. However, because \CONTEXT\ provides a
+%D rather high level of integration not all features will be supported
+%D in the same quality. Use \CONTEXT\ if you want more goodies.
+%D
+%D \item There is no official \API\ yet, which means that using
+%D functions implemented here is at your own risk, in the sense that
+%D names and namespaces might change. There will be a minimal \API\
+%D defined once \LUATEX\ version 1.0 is out. Instead of patching the
+%D files it's better to overload functions if needed.
+%D
+%D \item The modules are not stripped too much, which makes it
+%D possible to benefit from improvements in the code that take place
+%D in the perspective of \CONTEXT\ development. They might be split a
+%D bit more in due time so the baseline might become smaller.
+%D
+%D \item The code is maintained and tested by the \CONTEXT\
+%D development team. As such it might be better suited for this macro
+%D package and integration in other systems might demand some
+%D additional wrapping. Problems can be reported to the team but as we
+%D use \CONTEXT\ \MKIV\ as baseline, you'd better check if the problem
+%D is a general \CONTEXT\ problem too.
+%D
+%D \item The more high level support for features that is provided in
+%D \CONTEXT\ is not part of the code loaded here as it makes no sense
+%D elsewhere. Some experimental features are not part of this code
+%D either but some might show up later.
+%D
+%D \item Math font support will be added but only in its basic form
+%D once that the Latin Modern and \TEX\ Gyre math fonts are
+%D available.
+%D
+%D \item At this moment the more nifty speed-ups are not enabled
+%D because they work in tandem with the alternative file handling
+%D that \CONTEXT\ uses. Maybe around \LUATEX\ 1.0 we will bring some
+%D speedup into this code too (if it pays off at all).
+%D
+%D \item The code defines a few global tables. If this code is used
+%D in a larger perspective then you can best make sure that no
+%D conflicts occur. The \CONTEXT\ package expects users to work in
+%D their own namespace (\type {userdata}, \type {thirddata}, \type
+%D {moduledata} or \type {document}. The team takes all freedom to
+%D use any table at the global level but will not use tables that are
+%D named after macro packages. Later the \CONTEXT\ might operate in
+%D a more controlled namespace but it has a low priority.
+%D
+%D \item There is some tracing code present but this is not enabled
+%D and not supported outside \CONTEXT\ either as it integrates quite
+%D tightly into \CONTEXT. In case of problems you can use \CONTEXT\
+%D for tracking down problems.
+%D
+%D \item Patching the code in distributions is dangerous as it might
+%D fix your problem but introduce new ones for \CONTEXT. So, best keep
+%D the original code as it is.
+%D
+%D \item Attributes are (automatically) taken from the range 127-255 so
+%D you'd best not use these yourself.
+%D
+%D \stopitemize
+%D
+%D If this all sounds a bit tricky, keep in mind that it makes no sense
+%D for us to maintain multiple code bases and we happen to use \CONTEXT.
+%D
+%D For more details about how the font subsystem works we refer to
+%D publications in \TEX\ related journals, the \CONTEXT\ documentation,
+%D and the \CONTEXT\ wiki.
+
+\directlua {
+ if not fonts then
+ dofile(kpse.find_file("luatex-fonts.lua","tex"))
+ end
+}
+
+\endinput
diff --git a/macros/luatex/generic/luaotfload/fontloader-reference.lua b/macros/luatex/generic/luaotfload/fontloader-reference.lua
new file mode 100644
index 0000000000..3120f45135
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-reference.lua
@@ -0,0 +1,38728 @@
+-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
+-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
+-- merge date : 08/11/19 20:03:46
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-lua']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type,tonumber=next,type,tonumber
+LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
+LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
+LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
+LUAVERSION=LUAMAJORVERSION+LUAMINORVERSION/10
+if LUAVERSION<5.2 and jit then
+ MINORVERSION=2
+ LUAVERSION=5.2
+end
+if not lpeg then
+ lpeg=require("lpeg")
+end
+if loadstring then
+ local loadnormal=load
+ function load(first,...)
+ if type(first)=="string" then
+ return loadstring(first,...)
+ else
+ return loadnormal(first,...)
+ end
+ end
+else
+ loadstring=load
+end
+if not ipairs then
+ local function iterate(a,i)
+ i=i+1
+ local v=a[i]
+ if v~=nil then
+ return i,v
+ end
+ end
+ function ipairs(a)
+ return iterate,a,0
+ end
+end
+if not pairs then
+ function pairs(t)
+ return next,t
+ end
+end
+if not table.unpack then
+ table.unpack=_G.unpack
+elseif not unpack then
+ _G.unpack=table.unpack
+end
+if not package.loaders then
+ package.loaders=package.searchers
+end
+local print,select,tostring=print,select,tostring
+local inspectors={}
+function setinspector(kind,inspector)
+ inspectors[kind]=inspector
+end
+function inspect(...)
+ for s=1,select("#",...) do
+ local value=select(s,...)
+ if value==nil then
+ print("nil")
+ else
+ local done=false
+ local kind=type(value)
+ local inspector=inspectors[kind]
+ if inspector then
+ done=inspector(value)
+ if done then
+ break
+ end
+ end
+ for kind,inspector in next,inspectors do
+ done=inspector(value)
+ if done then
+ break
+ end
+ end
+ if not done then
+ print(tostring(value))
+ end
+ end
+ end
+end
+local dummy=function() end
+function optionalrequire(...)
+ local ok,result=xpcall(require,dummy,...)
+ if ok then
+ return result
+ end
+end
+if lua then
+ lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
+end
+local flush=io.flush
+if flush then
+ local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
+ local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
+ local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
+ local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
+end
+FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
+if not FFISUPPORTED then
+ local okay;okay,ffi=pcall(require,"ffi")
+ FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
+end
+if not FFISUPPORTED then
+ ffi=nil
+elseif not ffi.number then
+ ffi.number=tonumber
+end
+if LUAVERSION>5.3 then
+end
+if status and os.setenv then
+ os.setenv("engine",string.lower(status.luatex_engine or "unknown"))
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-lpeg']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+lpeg=require("lpeg")
+local lpeg=lpeg
+if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end
+local type,next,tostring=type,next,tostring
+local byte,char,gmatch,format=string.byte,string.char,string.gmatch,string.format
+local floor=math.floor
+local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt
+local lpegtype,lpegmatch,lpegprint=lpeg.type,lpeg.match,lpeg.print
+if setinspector then
+ setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
+end
+lpeg.patterns=lpeg.patterns or {}
+local patterns=lpeg.patterns
+local anything=P(1)
+local endofstring=P(-1)
+local alwaysmatched=P(true)
+patterns.anything=anything
+patterns.endofstring=endofstring
+patterns.beginofstring=alwaysmatched
+patterns.alwaysmatched=alwaysmatched
+local sign=S('+-')
+local zero=P('0')
+local digit=R('09')
+local digits=digit^1
+local octdigit=R("07")
+local octdigits=octdigit^1
+local lowercase=R("az")
+local uppercase=R("AZ")
+local underscore=P("_")
+local hexdigit=digit+lowercase+uppercase
+local hexdigits=hexdigit^1
+local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
+local newline=P("\r")*(P("\n")+P(true))+P("\n")
+local escaped=P("\\")*anything
+local squote=P("'")
+local dquote=P('"')
+local space=P(" ")
+local period=P(".")
+local comma=P(",")
+local utfbom_32_be=P('\000\000\254\255')
+local utfbom_32_le=P('\255\254\000\000')
+local utfbom_16_be=P('\254\255')
+local utfbom_16_le=P('\255\254')
+local utfbom_8=P('\239\187\191')
+local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8
+local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8")
+local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")
+local utfoffset=utfbom_32_be*Cc(4)+utfbom_32_le*Cc(4)+utfbom_16_be*Cc(2)+utfbom_16_le*Cc(2)+utfbom_8*Cc(3)+Cc(0)
+local utf8next=R("\128\191")
+patterns.utfbom_32_be=utfbom_32_be
+patterns.utfbom_32_le=utfbom_32_le
+patterns.utfbom_16_be=utfbom_16_be
+patterns.utfbom_16_le=utfbom_16_le
+patterns.utfbom_8=utfbom_8
+patterns.utf_16_be_nl=P("\000\r\000\n")+P("\000\r")+P("\000\n")
+patterns.utf_16_le_nl=P("\r\000\n\000")+P("\r\000")+P("\n\000")
+patterns.utf_32_be_nl=P("\000\000\000\r\000\000\000\n")+P("\000\000\000\r")+P("\000\000\000\n")
+patterns.utf_32_le_nl=P("\r\000\000\000\n\000\000\000")+P("\r\000\000\000")+P("\n\000\000\000")
+patterns.utf8one=R("\000\127")
+patterns.utf8two=R("\194\223")*utf8next
+patterns.utf8three=R("\224\239")*utf8next*utf8next
+patterns.utf8four=R("\240\244")*utf8next*utf8next*utf8next
+patterns.utfbom=utfbom
+patterns.utftype=utftype
+patterns.utfstricttype=utfstricttype
+patterns.utfoffset=utfoffset
+local utf8char=patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four
+local validutf8char=utf8char^0*endofstring*Cc(true)+Cc(false)
+local utf8character=P(1)*R("\128\191")^0
+patterns.utf8=utf8char
+patterns.utf8char=utf8char
+patterns.utf8character=utf8character
+patterns.validutf8=validutf8char
+patterns.validutf8char=validutf8char
+local eol=S("\n\r")
+local spacer=S(" \t\f\v")
+local whitespace=eol+spacer
+local nonspacer=1-spacer
+local nonwhitespace=1-whitespace
+patterns.eol=eol
+patterns.spacer=spacer
+patterns.whitespace=whitespace
+patterns.nonspacer=nonspacer
+patterns.nonwhitespace=nonwhitespace
+local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
+local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0)
+local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
+local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0)
+local b_collapser=Cs(whitespace^0/""*(nonwhitespace^1+whitespace^1/" ")^0)
+local e_collapser=Cs((whitespace^1*endofstring/""+nonwhitespace^1+whitespace^1/" ")^0)
+local m_collapser=Cs((nonwhitespace^1+whitespace^1/" ")^0)
+local b_stripper=Cs(spacer^0/""*(nonspacer^1+spacer^1/" ")^0)
+local e_stripper=Cs((spacer^1*endofstring/""+nonspacer^1+spacer^1/" ")^0)
+local m_stripper=Cs((nonspacer^1+spacer^1/" ")^0)
+patterns.stripper=stripper
+patterns.fullstripper=fullstripper
+patterns.collapser=collapser
+patterns.nospacer=nospacer
+patterns.b_collapser=b_collapser
+patterns.m_collapser=m_collapser
+patterns.e_collapser=e_collapser
+patterns.b_stripper=b_stripper
+patterns.m_stripper=m_stripper
+patterns.e_stripper=e_stripper
+patterns.lowercase=lowercase
+patterns.uppercase=uppercase
+patterns.letter=patterns.lowercase+patterns.uppercase
+patterns.space=space
+patterns.tab=P("\t")
+patterns.spaceortab=patterns.space+patterns.tab
+patterns.newline=newline
+patterns.emptyline=newline^1
+patterns.equal=P("=")
+patterns.comma=comma
+patterns.commaspacer=comma*spacer^0
+patterns.period=period
+patterns.colon=P(":")
+patterns.semicolon=P(";")
+patterns.underscore=underscore
+patterns.escaped=escaped
+patterns.squote=squote
+patterns.dquote=dquote
+patterns.nosquote=(escaped+(1-squote))^0
+patterns.nodquote=(escaped+(1-dquote))^0
+patterns.unsingle=(squote/"")*patterns.nosquote*(squote/"")
+patterns.undouble=(dquote/"")*patterns.nodquote*(dquote/"")
+patterns.unquoted=patterns.undouble+patterns.unsingle
+patterns.unspacer=((patterns.spacer^1)/"")^0
+patterns.singlequoted=squote*patterns.nosquote*squote
+patterns.doublequoted=dquote*patterns.nodquote*dquote
+patterns.quoted=patterns.doublequoted+patterns.singlequoted
+patterns.digit=digit
+patterns.digits=digits
+patterns.octdigit=octdigit
+patterns.octdigits=octdigits
+patterns.hexdigit=hexdigit
+patterns.hexdigits=hexdigits
+patterns.sign=sign
+patterns.cardinal=digits
+patterns.integer=sign^-1*digits
+patterns.unsigned=digit^0*period*digits
+patterns.float=sign^-1*patterns.unsigned
+patterns.cunsigned=digit^0*comma*digits
+patterns.cpunsigned=digit^0*(period+comma)*digits
+patterns.cfloat=sign^-1*patterns.cunsigned
+patterns.cpfloat=sign^-1*patterns.cpunsigned
+patterns.number=patterns.float+patterns.integer
+patterns.cnumber=patterns.cfloat+patterns.integer
+patterns.cpnumber=patterns.cpfloat+patterns.integer
+patterns.oct=zero*octdigits
+patterns.octal=patterns.oct
+patterns.HEX=zero*P("X")*(digit+uppercase)^1
+patterns.hex=zero*P("x")*(digit+lowercase)^1
+patterns.hexadecimal=zero*S("xX")*hexdigits
+patterns.hexafloat=sign^-1*zero*S("xX")*(hexdigit^0*period*hexdigits+hexdigits*period*hexdigit^0+hexdigits)*(S("pP")*sign^-1*hexdigits)^-1
+patterns.decafloat=sign^-1*(digit^0*period*digits+digits*period*digit^0+digits)*S("eE")*sign^-1*digits
+patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring
+patterns.somecontent=(anything-newline-space)^1
+patterns.beginline=#(1-newline)
+patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0))
+function anywhere(pattern)
+ return (1-P(pattern))^0*P(pattern)
+end
+lpeg.anywhere=anywhere
+function lpeg.instringchecker(p)
+ p=anywhere(p)
+ return function(str)
+ return lpegmatch(p,str) and true or false
+ end
+end
+function lpeg.splitter(pattern,action)
+ if action then
+ return (((1-P(pattern))^1)/action+1)^0
+ else
+ return (Cs((1-P(pattern))^1)+1)^0
+ end
+end
+function lpeg.tsplitter(pattern,action)
+ if action then
+ return Ct((((1-P(pattern))^1)/action+1)^0)
+ else
+ return Ct((Cs((1-P(pattern))^1)+1)^0)
+ end
+end
+local splitters_s,splitters_m,splitters_t={},{},{}
+local function splitat(separator,single)
+ local splitter=(single and splitters_s[separator]) or splitters_m[separator]
+ if not splitter then
+ separator=P(separator)
+ local other=C((1-separator)^0)
+ if single then
+ local any=anything
+ splitter=other*(separator*C(any^0)+"")
+ splitters_s[separator]=splitter
+ else
+ splitter=other*(separator*other)^0
+ splitters_m[separator]=splitter
+ end
+ end
+ return splitter
+end
+local function tsplitat(separator)
+ local splitter=splitters_t[separator]
+ if not splitter then
+ splitter=Ct(splitat(separator))
+ splitters_t[separator]=splitter
+ end
+ return splitter
+end
+lpeg.splitat=splitat
+lpeg.tsplitat=tsplitat
+function string.splitup(str,separator)
+ if not separator then
+ separator=","
+ end
+ return lpegmatch(splitters_m[separator] or splitat(separator),str)
+end
+local cache={}
+function lpeg.split(separator,str)
+ local c=cache[separator]
+ if not c then
+ c=tsplitat(separator)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+function string.split(str,separator)
+ if separator then
+ local c=cache[separator]
+ if not c then
+ c=tsplitat(separator)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+ else
+ return { str }
+ end
+end
+local spacing=patterns.spacer^0*newline
+local empty=spacing*Cc("")
+local nonempty=Cs((1-spacing)^1)*spacing^-1
+local content=(empty+nonempty)^1
+patterns.textline=content
+local linesplitter=tsplitat(newline)
+patterns.linesplitter=linesplitter
+function string.splitlines(str)
+ return lpegmatch(linesplitter,str)
+end
+local cache={}
+function lpeg.checkedsplit(separator,str)
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+function string.checkedsplit(str,separator)
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
+local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
+local function f4(s) local c1,c2,c3,c4=byte(s,1,4) return ((c1*64+c2)*64+c3)*64+c4-63447168 end
+local utf8byte=patterns.utf8one/byte+patterns.utf8two/f2+patterns.utf8three/f3+patterns.utf8four/f4
+patterns.utf8byte=utf8byte
+local cache={}
+function lpeg.stripper(str)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs(((S(str)^1)/""+1)^0)
+ cache[str]=s
+ end
+ return s
+ else
+ return Cs(((str^1)/""+1)^0)
+ end
+end
+local cache={}
+function lpeg.keeper(str)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs((((1-S(str))^1)/""+1)^0)
+ cache[str]=s
+ end
+ return s
+ else
+ return Cs((((1-str)^1)/""+1)^0)
+ end
+end
+function lpeg.frontstripper(str)
+ return (P(str)+P(true))*Cs(anything^0)
+end
+function lpeg.endstripper(str)
+ return Cs((1-P(str)*endofstring)^0)
+end
+function lpeg.replacer(one,two,makefunction,isutf)
+ local pattern
+ local u=isutf and utf8char or 1
+ if type(one)=="table" then
+ local no=#one
+ local p=P(false)
+ if no==0 then
+ for k,v in next,one do
+ p=p+P(k)/v
+ end
+ pattern=Cs((p+u)^0)
+ elseif no==1 then
+ local o=one[1]
+ one,two=P(o[1]),o[2]
+ pattern=Cs((one/two+u)^0)
+ else
+ for i=1,no do
+ local o=one[i]
+ p=p+P(o[1])/o[2]
+ end
+ pattern=Cs((p+u)^0)
+ end
+ else
+ pattern=Cs((P(one)/(two or "")+u)^0)
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
+ end
+ else
+ return pattern
+ end
+end
+function lpeg.finder(lst,makefunction,isutf)
+ local pattern
+ if type(lst)=="table" then
+ pattern=P(false)
+ if #lst==0 then
+ for k,v in next,lst do
+ pattern=pattern+P(k)
+ end
+ else
+ for i=1,#lst do
+ pattern=pattern+P(lst[i])
+ end
+ end
+ else
+ pattern=P(lst)
+ end
+ if isutf then
+ pattern=((utf8char or 1)-pattern)^0*pattern
+ else
+ pattern=(1-pattern)^0*pattern
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
+ end
+ else
+ return pattern
+ end
+end
+local splitters_f,splitters_s={},{}
+function lpeg.firstofsplit(separator)
+ local splitter=splitters_f[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)
+ splitters_f[separator]=splitter
+ end
+ return splitter
+end
+function lpeg.secondofsplit(separator)
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=(1-pattern)^0*pattern*C(anything^0)
+ splitters_s[separator]=splitter
+ end
+ return splitter
+end
+local splitters_s,splitters_p={},{}
+function lpeg.beforesuffix(separator)
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)*pattern*endofstring
+ splitters_s[separator]=splitter
+ end
+ return splitter
+end
+function lpeg.afterprefix(separator)
+ local splitter=splitters_p[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=pattern*C(anything^0)
+ splitters_p[separator]=splitter
+ end
+ return splitter
+end
+function lpeg.balancer(left,right)
+ left,right=P(left),P(right)
+ return P { left*((1-left-right)+V(1))^0*right }
+end
+function lpeg.counter(pattern,action)
+ local n=0
+ local pattern=(P(pattern)/function() n=n+1 end+anything)^0
+ if action then
+ return function(str) n=0;lpegmatch(pattern,str);action(n) end
+ else
+ return function(str) n=0;lpegmatch(pattern,str);return n end
+ end
+end
+function lpeg.is_lpeg(p)
+ return p and lpegtype(p)=="pattern"
+end
+function lpeg.oneof(list,...)
+ if type(list)~="table" then
+ list={ list,... }
+ end
+ local p=P(list[1])
+ for l=2,#list do
+ p=p+P(list[l])
+ end
+ return p
+end
+local sort=table.sort
+local function copyindexed(old)
+ local new={}
+ for i=1,#old do
+ new[i]=old
+ end
+ return new
+end
+local function sortedkeys(tab)
+ local keys,s={},0
+ for key,_ in next,tab do
+ s=s+1
+ keys[s]=key
+ end
+ sort(keys)
+ return keys
+end
+function lpeg.append(list,pp,delayed,checked)
+ local p=pp
+ if #list>0 then
+ local keys=copyindexed(list)
+ sort(keys)
+ for i=#keys,1,-1 do
+ local k=keys[i]
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
+ end
+ elseif delayed then
+ local keys=sortedkeys(list)
+ if p then
+ for i=1,#keys,1 do
+ local k=keys[i]
+ local v=list[k]
+ p=P(k)/list+p
+ end
+ else
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
+ end
+ if p then
+ p=p/list
+ end
+ end
+ elseif checked then
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ if k==v then
+ p=P(k)+p
+ else
+ p=P(k)/v+p
+ end
+ else
+ if k==v then
+ p=P(k)
+ else
+ p=P(k)/v
+ end
+ end
+ end
+ else
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ p=P(k)/v+p
+ else
+ p=P(k)/v
+ end
+ end
+ end
+ return p
+end
+local p_false=P(false)
+local p_true=P(true)
+local lower=utf and utf.lower or string.lower
+local upper=utf and utf.upper or string.upper
+function lpeg.setutfcasers(l,u)
+ lower=l or lower
+ upper=u or upper
+end
+local function make1(t,rest)
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+P(k)*p_true
+ elseif v==false then
+ else
+ p=p+P(k)*make1(v,v[""])
+ end
+ end
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
+end
+local function make2(t,rest)
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+(P(lower(k))+P(upper(k)))*p_true
+ elseif v==false then
+ else
+ p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
+ end
+ end
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
+end
+local function utfchartabletopattern(list,insensitive)
+ local tree={}
+ local n=#list
+ if n==0 then
+ for s in next,list do
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
+ end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
+ end
+ else
+ for i=1,n do
+ local s=list[i]
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
+ end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
+ end
+ end
+ return (insensitive and make2 or make1)(tree)
+end
+lpeg.utfchartabletopattern=utfchartabletopattern
+function lpeg.utfreplacer(list,insensitive)
+ local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
+ return function(str)
+ return lpegmatch(pattern,str) or str
+ end
+end
+patterns.containseol=lpeg.finder(eol)
+local function nextstep(n,step,result)
+ local m=n%step
+ local d=floor(n/step)
+ if d>0 then
+ local v=V(tostring(step))
+ local s=result.start
+ for i=1,d do
+ if s then
+ s=v*s
+ else
+ s=v
+ end
+ end
+ result.start=s
+ end
+ if step>1 and result.start then
+ local v=V(tostring(step/2))
+ result[tostring(step)]=v*v
+ end
+ if step>0 then
+ return nextstep(m,step/2,result)
+ else
+ return result
+ end
+end
+function lpeg.times(pattern,n)
+ return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
+end
+do
+ local trailingzeros=zero^0*-digit
+ local stripper=Cs((
+ digits*(
+ period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
+ )+1
+ )^0)
+ lpeg.patterns.stripzeros=stripper
+ local nonzero=digit-zero
+ local trailingzeros=zero^1*endofstring
+ local stripper=Cs((1-period)^0*(
+ period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
+ ))
+ lpeg.patterns.stripzero=stripper
+end
+local byte_to_HEX={}
+local byte_to_hex={}
+local byte_to_dec={}
+local hex_to_byte={}
+for i=0,255 do
+ local H=format("%02X",i)
+ local h=format("%02x",i)
+ local d=format("%03i",i)
+ local c=char(i)
+ byte_to_HEX[c]=H
+ byte_to_hex[c]=h
+ byte_to_dec[c]=d
+ hex_to_byte[h]=c
+ hex_to_byte[H]=c
+end
+local hextobyte=P(2)/hex_to_byte
+local bytetoHEX=P(1)/byte_to_HEX
+local bytetohex=P(1)/byte_to_hex
+local bytetodec=P(1)/byte_to_dec
+local hextobytes=Cs(hextobyte^0)
+local bytestoHEX=Cs(bytetoHEX^0)
+local bytestohex=Cs(bytetohex^0)
+local bytestodec=Cs(bytetodec^0)
+patterns.hextobyte=hextobyte
+patterns.bytetoHEX=bytetoHEX
+patterns.bytetohex=bytetohex
+patterns.bytetodec=bytetodec
+patterns.hextobytes=hextobytes
+patterns.bytestoHEX=bytestoHEX
+patterns.bytestohex=bytestohex
+patterns.bytestodec=bytestodec
+function string.toHEX(s)
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestoHEX,s)
+ end
+end
+function string.tohex(s)
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestohex,s)
+ end
+end
+function string.todec(s)
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestodec,s)
+ end
+end
+function string.tobytes(s)
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(hextobytes,s)
+ end
+end
+local patterns={}
+local function containsws(what)
+ local p=patterns[what]
+ if not p then
+ local p1=P(what)*(whitespace+endofstring)*Cc(true)
+ local p2=whitespace*P(p1)
+ p=P(p1)+P(1-p2)^0*p2+Cc(false)
+ patterns[what]=p
+ end
+ return p
+end
+lpeg.containsws=containsws
+function string.containsws(str,what)
+ return lpegmatch(patterns[what] or containsws(what),str)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-functions']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+functions=functions or {}
+function functions.dummy() end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-string']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local string=string
+local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower
+local lpegmatch,patterns=lpeg.match,lpeg.patterns
+local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs
+local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote
+function string.unquoted(str)
+ return lpegmatch(unquoted,str) or str
+end
+function string.quoted(str)
+ return format("%q",str)
+end
+function string.count(str,pattern)
+ local n=0
+ for _ in gmatch(str,pattern) do
+ n=n+1
+ end
+ return n
+end
+function string.limit(str,n,sentinel)
+ if #str>n then
+ sentinel=sentinel or "..."
+ return sub(str,1,(n-#sentinel))..sentinel
+ else
+ return str
+ end
+end
+local stripper=patterns.stripper
+local fullstripper=patterns.fullstripper
+local collapser=patterns.collapser
+local nospacer=patterns.nospacer
+local longtostring=patterns.longtostring
+function string.strip(str)
+ return str and lpegmatch(stripper,str) or ""
+end
+function string.fullstrip(str)
+ return str and lpegmatch(fullstripper,str) or ""
+end
+function string.collapsespaces(str)
+ return str and lpegmatch(collapser,str) or ""
+end
+function string.nospaces(str)
+ return str and lpegmatch(nospacer,str) or ""
+end
+function string.longtostring(str)
+ return str and lpegmatch(longtostring,str) or ""
+end
+local pattern=P(" ")^0*P(-1)
+function string.is_empty(str)
+ if not str or str=="" then
+ return true
+ else
+ return lpegmatch(pattern,str) and true or false
+ end
+end
+local anything=patterns.anything
+local moreescapes=Cc("%")*S(".-+%?()[]*$^{}")
+local allescapes=Cc("%")*S(".-+%?()[]*")
+local someescapes=Cc("%")*S(".-+%()[]")
+local matchescapes=Cc(".")*S("*?")
+local pattern_m=Cs ((moreescapes+anything )^0 )
+local pattern_a=Cs ((allescapes+anything )^0 )
+local pattern_b=Cs ((someescapes+matchescapes+anything )^0 )
+local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") )
+function string.escapedpattern(str,simple)
+ return lpegmatch(simple and pattern_b or pattern_a,str)
+end
+function string.topattern(str,lowercase,strict)
+ if str=="" or type(str)~="string" then
+ return ".*"
+ elseif strict=="all" then
+ str=lpegmatch(pattern_m,str)
+ elseif strict then
+ str=lpegmatch(pattern_c,str)
+ else
+ str=lpegmatch(pattern_b,str)
+ end
+ if lowercase then
+ return lower(str)
+ else
+ return str
+ end
+end
+function string.valid(str,default)
+ return (type(str)=="string" and str~="" and str) or default or nil
+end
+string.itself=function(s) return s end
+local pattern_c=Ct(C(1)^0)
+local pattern_b=Ct((C(1)/byte)^0)
+function string.totable(str,bytes)
+ return lpegmatch(bytes and pattern_b or pattern_c,str)
+end
+local replacer=lpeg.replacer("@","%%")
+function string.tformat(fmt,...)
+ return format(lpegmatch(replacer,fmt),...)
+end
+string.quote=string.quoted
+string.unquote=string.unquoted
+if not string.bytetable then
+ local limit=5000
+ function string.bytetable(str)
+ local n=#str
+ if n>limit then
+ local t={ byte(str,1,limit) }
+ for i=limit+1,n do
+ t[i]=byte(str,i)
+ end
+ return t
+ else
+ return { byte(str,1,n) }
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-table']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local type,next,tostring,tonumber,select=type,next,tostring,tonumber,select
+local table,string=table,string
+local concat,sort=table.concat,table.sort
+local format,lower,dump=string.format,string.lower,string.dump
+local getmetatable,setmetatable=getmetatable,setmetatable
+local lpegmatch,patterns=lpeg.match,lpeg.patterns
+local floor=math.floor
+local stripper=patterns.stripper
+function table.getn(t)
+ return t and #t
+end
+function table.strip(tab)
+ local lst={}
+ local l=0
+ for i=1,#tab do
+ local s=lpegmatch(stripper,tab[i]) or ""
+ if s=="" then
+ else
+ l=l+1
+ lst[l]=s
+ end
+ end
+ return lst
+end
+function table.keys(t)
+ if t then
+ local keys={}
+ local k=0
+ for key in next,t do
+ k=k+1
+ keys[k]=key
+ end
+ return keys
+ else
+ return {}
+ end
+end
+local function compare(a,b)
+ local ta=type(a)
+ if ta=="number" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ elseif tb=="string" then
+ return tostring(a)<b
+ end
+ elseif ta=="string" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ else
+ return a<tostring(b)
+ end
+ end
+ return tostring(a)<tostring(b)
+end
+local function sortedkeys(tab)
+ if tab then
+ local srt={}
+ local category=0
+ local s=0
+ for key in next,tab do
+ s=s+1
+ srt[s]=key
+ if category~=3 then
+ local tkey=type(key)
+ if category==1 then
+ if tkey~="string" then
+ category=3
+ end
+ elseif category==2 then
+ if tkey~="number" then
+ category=3
+ end
+ else
+ if tkey=="string" then
+ category=1
+ elseif tkey=="number" then
+ category=2
+ else
+ category=3
+ end
+ end
+ end
+ end
+ if s<2 then
+ elseif category==3 then
+ sort(srt,compare)
+ else
+ sort(srt)
+ end
+ return srt
+ else
+ return {}
+ end
+end
+local function sortedhashonly(tab)
+ if tab then
+ local srt={}
+ local s=0
+ for key in next,tab do
+ if type(key)=="string" then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return {}
+ end
+end
+local function sortedindexonly(tab)
+ if tab then
+ local srt={}
+ local s=0
+ for key in next,tab do
+ if type(key)=="number" then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return {}
+ end
+end
+local function sortedhashkeys(tab,cmp)
+ if tab then
+ local srt={}
+ local s=0
+ for key in next,tab do
+ if key then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt,cmp)
+ end
+ return srt
+ else
+ return {}
+ end
+end
+function table.allkeys(t)
+ local keys={}
+ for k,v in next,t do
+ for k in next,v do
+ keys[k]=true
+ end
+ end
+ return sortedkeys(keys)
+end
+table.sortedkeys=sortedkeys
+table.sortedhashonly=sortedhashonly
+table.sortedindexonly=sortedindexonly
+table.sortedhashkeys=sortedhashkeys
+local function nothing() end
+local function sortedhash(t,cmp)
+ if t then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local m=#s
+ if m==1 then
+ return next,t
+ elseif m>0 then
+ local n=0
+ return function()
+ if n<m then
+ n=n+1
+ local k=s[n]
+ return k,t[k]
+ end
+ end
+ end
+ end
+ return nothing
+end
+table.sortedhash=sortedhash
+table.sortedpairs=sortedhash
+function table.append(t,list)
+ local n=#t
+ for i=1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ return t
+end
+function table.prepend(t,list)
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+ t[nt]=t[i]
+ nt=nt-1
+ end
+ for i=1,#list do
+ t[i]=list[i]
+ end
+ return t
+end
+function table.merge(t,...)
+ if not t then
+ t={}
+ end
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
+ end
+ end
+ return t
+end
+function table.merged(...)
+ local t={}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
+ end
+ end
+ return t
+end
+function table.imerge(t,...)
+ local nt=#t
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ nt=nt+1
+ t[nt]=nst[j]
+ end
+ end
+ return t
+end
+function table.imerged(...)
+ local tmp={}
+ local ntmp=0
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ ntmp=ntmp+1
+ tmp[ntmp]=nst[j]
+ end
+ end
+ return tmp
+end
+local function fastcopy(old,metatabletoo)
+ if old then
+ local new={}
+ for k,v in next,old do
+ if type(v)=="table" then
+ new[k]=fastcopy(v,metatabletoo)
+ else
+ new[k]=v
+ end
+ end
+ if metatabletoo then
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ end
+ return new
+ else
+ return {}
+ end
+end
+local function copy(t,tables)
+ if not tables then
+ tables={}
+ end
+ local tcopy={}
+ if not tables[t] then
+ tables[t]=tcopy
+ end
+ for i,v in next,t do
+ if type(i)=="table" then
+ if tables[i] then
+ i=tables[i]
+ else
+ i=copy(i,tables)
+ end
+ end
+ if type(v)~="table" then
+ tcopy[i]=v
+ elseif tables[v] then
+ tcopy[i]=tables[v]
+ else
+ tcopy[i]=copy(v,tables)
+ end
+ end
+ local mt=getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
+end
+table.fastcopy=fastcopy
+table.copy=copy
+function table.derive(parent)
+ local child={}
+ if parent then
+ setmetatable(child,{ __index=parent })
+ end
+ return child
+end
+function table.tohash(t,value)
+ local h={}
+ if t then
+ if value==nil then value=true end
+ for _,v in next,t do
+ h[v]=value
+ end
+ end
+ return h
+end
+function table.fromhash(t)
+ local hsh={}
+ local h=0
+ for k,v in next,t do
+ if v then
+ h=h+1
+ hsh[h]=k
+ end
+ end
+ return hsh
+end
+local noquotes,hexify,handle,compact,inline,functions,metacheck
+local reserved=table.tohash {
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
+}
+local function is_simple_table(t,hexify)
+ local nt=#t
+ if nt>0 then
+ local n=0
+ for _,v in next,t do
+ n=n+1
+ if type(v)=="table" then
+ return nil
+ end
+ end
+ local haszero=rawget(t,0)
+ if n==nt then
+ local tt={}
+ for i=1,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i]=format("0x%X",v)
+ else
+ tt[i]=v
+ end
+ elseif tv=="string" then
+ tt[i]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i]=v and "true" or "false"
+ else
+ return nil
+ end
+ end
+ return tt
+ elseif haszero and (n==nt+1) then
+ local tt={}
+ for i=0,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i+1]=format("0x%X",v)
+ else
+ tt[i+1]=v
+ end
+ elseif tv=="string" then
+ tt[i+1]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i+1]=v and "true" or "false"
+ else
+ return nil
+ end
+ end
+ tt[1]="[0] = "..tt[1]
+ return tt
+ end
+ end
+ return nil
+end
+table.is_simple_table=is_simple_table
+local propername=patterns.propername
+local function dummy() end
+local function do_serialize(root,name,depth,level,indexed)
+ if level>0 then
+ depth=depth.." "
+ if indexed then
+ handle(format("%s{",depth))
+ else
+ local tn=type(name)
+ if tn=="number" then
+ if hexify then
+ handle(format("%s[0x%X]={",depth,name))
+ else
+ handle(format("%s[%s]={",depth,name))
+ end
+ elseif tn=="string" then
+ if noquotes and not reserved[name] and lpegmatch(propername,name) then
+ handle(format("%s%s={",depth,name))
+ else
+ handle(format("%s[%q]={",depth,name))
+ end
+ elseif tn=="boolean" then
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
+ else
+ handle(format("%s{",depth))
+ end
+ end
+ end
+ if root and next(root)~=nil then
+ local first=nil
+ local last=0
+ if compact then
+ last=#root
+ for k=1,last do
+ if rawget(root,k)==nil then
+ last=k-1
+ break
+ end
+ end
+ if last>0 then
+ first=1
+ end
+ end
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if compact and first and tk=="number" and k>=first and k<=last then
+ if tv=="number" then
+ if hexify then
+ handle(format("%s 0x%X,",depth,v))
+ else
+ handle(format("%s %s,",depth,v))
+ end
+ elseif tv=="string" then
+ handle(format("%s %q,",depth,v))
+ elseif tv=="table" then
+ if next(v)==nil then
+ handle(format("%s {},",depth))
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ handle(format("%s { %s },",depth,concat(st,", ")))
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ elseif tv=="boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv=="function" then
+ if functions then
+ handle(format('%s load(%q),',depth,dump(v)))
+ else
+ handle(format('%s "function",',depth))
+ end
+ else
+ handle(format("%s %q,",depth,tostring(v)))
+ end
+ elseif k=="__p__" then
+ if false then
+ handle(format("%s __p__=nil,",depth))
+ end
+ elseif tv=="number" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ if hexify then
+ handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ else
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
+ end
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ if hexify then
+ handle(format("%s %s=0x%X,",depth,k,v))
+ else
+ handle(format("%s %s=%s,",depth,k,v))
+ end
+ else
+ if hexify then
+ handle(format("%s [%q]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v))
+ end
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,v))
+ else
+ handle(format("%s [%s]=%q,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,v))
+ else
+ handle(format("%s [%q]=%q,",depth,k,v))
+ end
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={},",depth,k))
+ else
+ handle(format("%s [%s]={},",depth,k))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={},",depth,k))
+ else
+ handle(format("%s [%q]={},",depth,k))
+ end
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tv=="function" then
+ if functions then
+ local getinfo=debug and debug.getinfo
+ if getinfo then
+ local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%s]=load(%q),",depth,k,f))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%q]=load(%q),",depth,k,f))
+ end
+ end
+ end
+ else
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
+ end
+ end
+ end
+ end
+ if level>0 then
+ handle(format("%s},",depth))
+ end
+end
+local function serialize(_handle,root,name,specification)
+ local tname=type(name)
+ if type(specification)=="table" then
+ noquotes=specification.noquotes
+ hexify=specification.hexify
+ handle=_handle or specification.handle or print
+ functions=specification.functions
+ compact=specification.compact
+ inline=specification.inline and compact
+ metacheck=specification.metacheck
+ if functions==nil then
+ functions=true
+ end
+ if compact==nil then
+ compact=true
+ end
+ if inline==nil then
+ inline=compact
+ end
+ if metacheck==nil then
+ metacheck=true
+ end
+ else
+ noquotes=false
+ hexify=false
+ handle=_handle or print
+ compact=true
+ inline=true
+ functions=true
+ metacheck=true
+ end
+ if tname=="string" then
+ if name=="return" then
+ handle("return {")
+ else
+ handle(name.."={")
+ end
+ elseif tname=="number" then
+ if hexify then
+ handle(format("[0x%X]={",name))
+ else
+ handle("["..name.."]={")
+ end
+ elseif tname=="boolean" then
+ if name then
+ handle("return {")
+ else
+ handle("{")
+ end
+ else
+ handle("t={")
+ end
+ if root then
+ if metacheck and getmetatable(root) then
+ local dummy=root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_=nil
+ end
+ if next(root)~=nil then
+ do_serialize(root,name,"",0)
+ end
+ end
+ handle("}")
+end
+function table.serialize(root,name,specification)
+ local t={}
+ local n=0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ end
+ serialize(flush,root,name,specification)
+ return concat(t,"\n")
+end
+table.tohandle=serialize
+local maxtab=2*1024
+function table.tofile(filename,root,name,specification)
+ local f=io.open(filename,'w')
+ if f then
+ if maxtab>1 then
+ local t={}
+ local n=0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ if n>maxtab then
+ f:write(concat(t,"\n"),"\n")
+ t={}
+ n=0
+ end
+ end
+ serialize(flush,root,name,specification)
+ f:write(concat(t,"\n"),"\n")
+ else
+ local function flush(s)
+ f:write(s,"\n")
+ end
+ serialize(flush,root,name,specification)
+ end
+ f:close()
+ io.flush()
+ end
+end
+local function flattened(t,f,depth)
+ if f==nil then
+ f={}
+ depth=0xFFFF
+ elseif tonumber(f) then
+ depth=f
+ f={}
+ elseif not depth then
+ depth=0xFFFF
+ end
+ for k,v in next,t do
+ if type(k)~="number" then
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
+ end
+ end
+ end
+ for k=1,#t do
+ local v=t[k]
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
+ end
+ end
+ return f
+end
+table.flattened=flattened
+local function collapsed(t,f,h)
+ if f==nil then
+ f={}
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsed(v,f,h)
+ elseif not h[v] then
+ f[#f+1]=v
+ h[v]=true
+ end
+ end
+ return f
+end
+local function collapsedhash(t,h)
+ if h==nil then
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsedhash(v,h)
+ else
+ h[v]=true
+ end
+ end
+ return h
+end
+table.collapsed=collapsed
+table.collapsedhash=collapsedhash
+local function unnest(t,f)
+ if not f then
+ f={}
+ end
+ for i=1,#t do
+ local v=t[i]
+ if type(v)=="table" then
+ if type(v[1])=="table" then
+ unnest(v,f)
+ else
+ f[#f+1]=v
+ end
+ else
+ f[#f+1]=v
+ end
+ end
+ return f
+end
+function table.unnest(t)
+ return unnest(t)
+end
+local function are_equal(a,b,n,m)
+ if a==b then
+ return true
+ elseif a and b and #a==#b then
+ if not n then
+ n=1
+ end
+ if not m then
+ m=#a
+ end
+ for i=n,m do
+ local ai,bi=a[i],b[i]
+ if ai==bi then
+ elseif type(ai)=="table" and type(bi)=="table" then
+ if not are_equal(ai,bi) then
+ return false
+ end
+ else
+ return false
+ end
+ end
+ return true
+ else
+ return false
+ end
+end
+local function identical(a,b)
+ if a~=b then
+ for ka,va in next,a do
+ local vb=b[ka]
+ if va==vb then
+ elseif type(va)=="table" and type(vb)=="table" then
+ if not identical(va,vb) then
+ return false
+ end
+ else
+ return false
+ end
+ end
+ end
+ return true
+end
+table.identical=identical
+table.are_equal=are_equal
+local function sparse(old,nest,keeptables)
+ local new={}
+ for k,v in next,old do
+ if not (v=="" or v==false) then
+ if nest and type(v)=="table" then
+ v=sparse(v,nest)
+ if keeptables or next(v)~=nil then
+ new[k]=v
+ end
+ else
+ new[k]=v
+ end
+ end
+ end
+ return new
+end
+table.sparse=sparse
+function table.compact(t)
+ return sparse(t,true,true)
+end
+function table.contains(t,v)
+ if t then
+ for i=1,#t do
+ if t[i]==v then
+ return i
+ end
+ end
+ end
+ return false
+end
+function table.count(t)
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ end
+ return n
+end
+function table.swapped(t,s)
+ local n={}
+ if s then
+ for k,v in next,s do
+ n[k]=v
+ end
+ end
+ for k,v in next,t do
+ n[v]=k
+ end
+ return n
+end
+function table.hashed(t)
+ for i=1,#t do
+ t[t[i]]=i
+ end
+ return t
+end
+function table.mirrored(t)
+ local n={}
+ for k,v in next,t do
+ n[v]=k
+ n[k]=v
+ end
+ return n
+end
+function table.reversed(t)
+ if t then
+ local tt={}
+ local tn=#t
+ if tn>0 then
+ local ttn=0
+ for i=tn,1,-1 do
+ ttn=ttn+1
+ tt[ttn]=t[i]
+ end
+ end
+ return tt
+ end
+end
+function table.reverse(t)
+ if t then
+ local n=#t
+ local m=n+1
+ for i=1,floor(n/2) do
+ local j=m-i
+ t[i],t[j]=t[j],t[i]
+ end
+ return t
+ end
+end
+local function sequenced(t,sep,simple)
+ if not t then
+ return ""
+ elseif type(t)~="table" then
+ return t
+ end
+ local n=#t
+ local s={}
+ if n>0 then
+ for i=1,n do
+ local v=t[i]
+ if type(v)=="table" then
+ s[i]="{"..sequenced(v,sep,simple).."}"
+ else
+ s[i]=tostring(t[i])
+ end
+ end
+ else
+ n=0
+ for k,v in sortedhash(t) do
+ if simple then
+ if v==true then
+ n=n+1
+ s[n]=k
+ elseif v and v~="" then
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
+ end
+ end
+ else
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
+ end
+ end
+ end
+ end
+ if sep==true then
+ return "{ "..concat(s,", ").." }"
+ else
+ return concat(s,sep or " | ")
+ end
+end
+table.sequenced=sequenced
+function table.print(t,...)
+ if type(t)~="table" then
+ print(tostring(t))
+ else
+ serialize(print,t,...)
+ end
+end
+if setinspector then
+ setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
+end
+function table.sub(t,i,j)
+ return { unpack(t,i,j) }
+end
+function table.is_empty(t)
+ return not t or next(t)==nil
+end
+function table.has_one_entry(t)
+ return t and next(t,next(t))==nil
+end
+function table.loweredkeys(t)
+ local l={}
+ for k,v in next,t do
+ l[lower(k)]=v
+ end
+ return l
+end
+function table.unique(old)
+ local hash={}
+ local new={}
+ local n=0
+ for i=1,#old do
+ local oi=old[i]
+ if not hash[oi] then
+ n=n+1
+ new[n]=oi
+ hash[oi]=true
+ end
+ end
+ return new
+end
+function table.sorted(t,...)
+ sort(t,...)
+ return t
+end
+function table.values(t,s)
+ if t then
+ local values={}
+ local keys={}
+ local v=0
+ for key,value in next,t do
+ if not keys[value] then
+ v=v+1
+ values[v]=value
+ keys[k]=key
+ end
+ end
+ if s then
+ sort(values)
+ end
+ return values
+ else
+ return {}
+ end
+end
+function table.filtered(t,pattern,sort,cmp)
+ if t and type(pattern)=="string" then
+ if sort then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local n=0
+ local m=#s
+ local function kv(s)
+ while n<m do
+ n=n+1
+ local k=s[n]
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return kv,s
+ else
+ local n=next(t)
+ local function iterator()
+ while n~=nil do
+ local k=n
+ n=next(t,k)
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return iterator,t
+ end
+ else
+ return nothing
+ end
+end
+if not table.move then
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1~=a2 then
+ for i=f,e do
+ a2[t]=a1[i]
+ t=t+1
+ end
+ return a2
+ else
+ t=t+e-f
+ for i=e,f,-1 do
+ a1[t]=a1[i]
+ t=t-1
+ end
+ return a1
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-io']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local io=io
+local open,flush,write,read=io.open,io.flush,io.write,io.read
+local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
+local concat=table.concat
+local type=type
+if string.find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator,io.pathseparator="\\",";"
+else
+ io.fileseparator,io.pathseparator="/",":"
+end
+local large=0x01000000
+local medium=0x00100000
+local small=0x00020000
+local function readall(f)
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ return f:read(size)
+ else
+ return ""
+ end
+end
+io.readall=readall
+function io.loaddata(filename,textmode)
+ local f=open(filename,(textmode and 'r') or 'rb')
+ if f then
+ local size=f:seek("end")
+ local data=nil
+ if size>0 then
+ f:seek("set",0)
+ data=f:read(size)
+ end
+ f:close()
+ return data
+ end
+end
+function io.copydata(source,target,action)
+ local f=open(source,"rb")
+ if f then
+ local g=open(target,"wb")
+ if g then
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ local data=f:read(size)
+ if action then
+ data=action(data)
+ end
+ if data then
+ g:write(data)
+ end
+ end
+ g:close()
+ end
+ f:close()
+ flush()
+ end
+end
+function io.savedata(filename,data,joiner)
+ local f=open(filename,"wb")
+ if f then
+ if type(data)=="table" then
+ f:write(concat(data,joiner or ""))
+ elseif type(data)=="function" then
+ data(f)
+ else
+ f:write(data or "")
+ end
+ f:close()
+ flush()
+ return true
+ else
+ return false
+ end
+end
+if fio and fio.readline then
+ local readline=fio.readline
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=readline(f)
+ if line then
+ lines[i]=line
+ else
+ break
+ end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=readline(f)
+ f:close()
+ if line and #line>0 then
+ return line
+ end
+ end
+ end
+else
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=f:read("*lines")
+ if line then
+ lines[i]=line
+ else
+ break
+ end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=f:read("*line") or ""
+ f:close()
+ if #line>0 then
+ return line
+ end
+ end
+ end
+end
+function io.loadchunk(filename,n)
+ local f=open(filename,'rb')
+ if f then
+ local data=f:read(n or 1024)
+ f:close()
+ if #data>0 then
+ return data
+ end
+ end
+end
+function io.exists(filename)
+ local f=open(filename)
+ if f==nil then
+ return false
+ else
+ f:close()
+ return true
+ end
+end
+function io.size(filename)
+ local f=open(filename)
+ if f==nil then
+ return 0
+ else
+ local s=f:seek("end")
+ f:close()
+ return s
+ end
+end
+local function noflines(f)
+ if type(f)=="string" then
+ local f=open(filename)
+ if f then
+ local n=f and noflines(f) or 0
+ f:close()
+ return n
+ else
+ return 0
+ end
+ else
+ local n=0
+ for _ in f:lines() do
+ n=n+1
+ end
+ f:seek('set',0)
+ return n
+ end
+end
+io.noflines=noflines
+local nextchar={
+ [ 4]=function(f)
+ return f:read(1,1,1,1)
+ end,
+ [ 2]=function(f)
+ return f:read(1,1)
+ end,
+ [ 1]=function(f)
+ return f:read(1)
+ end,
+ [-2]=function(f)
+ local a,b=f:read(1,1)
+ return b,a
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ return d,c,b,a
+ end
+}
+function io.characters(f,n)
+ if f then
+ return nextchar[n or 1],f
+ end
+end
+local nextbyte={
+ [4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(a),byte(b),byte(c),byte(d)
+ end
+ end,
+ [3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(a),byte(b),byte(c)
+ end
+ end,
+ [2]=function(f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(a),byte(b)
+ end
+ end,
+ [1]=function (f)
+ local a=f:read(1)
+ if a then
+ return byte(a)
+ end
+ end,
+ [-2]=function (f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(b),byte(a)
+ end
+ end,
+ [-3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(c),byte(b),byte(a)
+ end
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(d),byte(c),byte(b),byte(a)
+ end
+ end
+}
+function io.bytes(f,n)
+ if f then
+ return nextbyte[n or 1],f
+ else
+ return nil,nil
+ end
+end
+function io.ask(question,default,options)
+ while true do
+ write(question)
+ if options then
+ write(format(" [%s]",concat(options,"|")))
+ end
+ if default then
+ write(format(" [%s]",default))
+ end
+ write(format(" "))
+ flush()
+ local answer=read()
+ answer=gsub(answer,"^%s*(.*)%s*$","%1")
+ if answer=="" and default then
+ return default
+ elseif not options then
+ return answer
+ else
+ for k=1,#options do
+ if options[k]==answer then
+ return answer
+ end
+ end
+ local pattern="^"..answer
+ for k=1,#options do
+ local v=options[k]
+ if find(v,pattern) then
+ return v
+ end
+ end
+ end
+ end
+end
+local function readnumber(f,n,m)
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ if n==1 then
+ return byte(f:read(1))
+ elseif n==2 then
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==3 then
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==4 then
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==8 then
+ local a,b=readnumber(f,4),readnumber(f,4)
+ return 0x100*a+b
+ elseif n==12 then
+ local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
+ return 0x10000*a+0x100*b+c
+ elseif n==-2 then
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==-3 then
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==-4 then
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==-8 then
+ local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
+ return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+ else
+ return 0
+ end
+end
+io.readnumber=readnumber
+function io.readstring(f,n,m)
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ local str=gsub(f:read(n),"\000","")
+ return str
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-file']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+file=file or {}
+local file=file
+if not lfs then
+ lfs=optionalrequire("lfs")
+end
+local insert,concat=table.insert,table.concat
+local match,find,gmatch=string.match,string.find,string.gmatch
+local lpegmatch=lpeg.match
+local getcurrentdir,attributes=lfs.currentdir,lfs.attributes
+local checkedsplit=string.checkedsplit
+local P,R,S,C,Cs,Cp,Cc,Ct=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cp,lpeg.Cc,lpeg.Ct
+local attributes=lfs.attributes
+function lfs.isdir(name)
+ return attributes(name,"mode")=="directory"
+end
+function lfs.isfile(name)
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
+end
+function lfs.isfound(name)
+ local a=attributes(name,"mode")
+ return (a=="file" or a=="link") and name or nil
+end
+if sandbox then
+ sandbox.redefine(lfs.isfile,"lfs.isfile")
+ sandbox.redefine(lfs.isdir,"lfs.isdir")
+ sandbox.redefine(lfs.isfound,"lfs.isfound")
+end
+local colon=P(":")
+local period=P(".")
+local periods=P("..")
+local fwslash=P("/")
+local bwslash=P("\\")
+local slashes=S("\\/")
+local noperiod=1-period
+local noslashes=1-slashes
+local name=noperiod^1
+local suffix=period/""*(1-period-slashes)^1*-1
+local pattern=C((1-(slashes^1*noslashes^1*-1))^1)*P(1)
+local function pathpart(name,default)
+ return name and lpegmatch(pattern,name) or default or ""
+end
+local pattern=(noslashes^0*slashes)^1*C(noslashes^1)*-1
+local function basename(name)
+ return name and lpegmatch(pattern,name) or name
+end
+local pattern=(noslashes^0*slashes^1)^0*Cs((1-suffix)^1)*suffix^0
+local function nameonly(name)
+ return name and lpegmatch(pattern,name) or name
+end
+local pattern=(noslashes^0*slashes)^0*(noperiod^1*period)^1*C(noperiod^1)*-1
+local function suffixonly(name)
+ return name and lpegmatch(pattern,name) or ""
+end
+local pattern=(noslashes^0*slashes)^0*noperiod^1*((period*C(noperiod^1))^1)*-1+Cc("")
+local function suffixesonly(name)
+ if name then
+ return lpegmatch(pattern,name)
+ else
+ return ""
+ end
+end
+file.pathpart=pathpart
+file.basename=basename
+file.nameonly=nameonly
+file.suffixonly=suffixonly
+file.suffix=suffixonly
+file.suffixesonly=suffixesonly
+file.suffixes=suffixesonly
+file.dirname=pathpart
+file.extname=suffixonly
+local drive=C(R("az","AZ"))*colon
+local path=C((noslashes^0*slashes)^0)
+local suffix=period*C(P(1-period)^0*P(-1))
+local base=C((1-suffix)^0)
+local rest=C(P(1)^0)
+drive=drive+Cc("")
+path=path+Cc("")
+base=base+Cc("")
+suffix=suffix+Cc("")
+local pattern_a=drive*path*base*suffix
+local pattern_b=path*base*suffix
+local pattern_c=C(drive*path)*C(base*suffix)
+local pattern_d=path*rest
+function file.splitname(str,splitdrive)
+ if not str then
+ elseif splitdrive then
+ return lpegmatch(pattern_a,str)
+ else
+ return lpegmatch(pattern_b,str)
+ end
+end
+function file.splitbase(str)
+ if str then
+ return lpegmatch(pattern_d,str)
+ else
+ return "",str
+ end
+end
+function file.nametotable(str,splitdrive)
+ if str then
+ local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
+ if splitdrive then
+ return {
+ path=path,
+ drive=drive,
+ subpath=subpath,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
+ else
+ return {
+ path=path,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
+ end
+ end
+end
+local pattern=Cs(((period*(1-period-slashes)^1*-1)/""+1)^1)
+function file.removesuffix(name)
+ return name and lpegmatch(pattern,name)
+end
+local suffix=period/""*(1-period-slashes)^1*-1
+local pattern=Cs((noslashes^0*slashes^1)^0*((1-suffix)^1))*Cs(suffix)
+function file.addsuffix(filename,suffix,criterium)
+ if not filename or not suffix or suffix=="" then
+ return filename
+ elseif criterium==true then
+ return filename.."."..suffix
+ elseif not criterium then
+ local n,s=lpegmatch(pattern,filename)
+ if not s or s=="" then
+ return filename.."."..suffix
+ else
+ return filename
+ end
+ else
+ local n,s=lpegmatch(pattern,filename)
+ if s and s~="" then
+ local t=type(criterium)
+ if t=="table" then
+ for i=1,#criterium do
+ if s==criterium[i] then
+ return filename
+ end
+ end
+ elseif t=="string" then
+ if s==criterium then
+ return filename
+ end
+ end
+ end
+ return (n or filename).."."..suffix
+ end
+end
+local suffix=period*(1-period-slashes)^1*-1
+local pattern=Cs((1-suffix)^0)
+function file.replacesuffix(name,suffix)
+ if name and suffix and suffix~="" then
+ return lpegmatch(pattern,name).."."..suffix
+ else
+ return name
+ end
+end
+local reslasher=lpeg.replacer(P("\\"),"/")
+function file.reslash(str)
+ return str and lpegmatch(reslasher,str)
+end
+if lfs.isreadablefile and lfs.iswritablefile then
+ file.is_readable=lfs.isreadablefile
+ file.is_writable=lfs.iswritablefile
+else
+ function file.is_writable(name)
+ if not name then
+ elseif lfs.isdir(name) then
+ name=name.."/m_t_x_t_e_s_t.tmp"
+ local f=io.open(name,"wb")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ elseif lfs.isfile(name) then
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ return true
+ end
+ else
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ end
+ return false
+ end
+ local readable=P("r")*Cc(true)
+ function file.is_readable(name)
+ if name then
+ local a=attributes(name)
+ return a and lpegmatch(readable,a.permissions) or false
+ else
+ return false
+ end
+ end
+end
+file.isreadable=file.is_readable
+file.iswritable=file.is_writable
+function file.size(name)
+ if name then
+ local a=attributes(name)
+ return a and a.size or 0
+ else
+ return 0
+ end
+end
+function file.splitpath(str,separator)
+ return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
+end
+function file.joinpath(tab,separator)
+ return tab and concat(tab,separator or io.pathseparator)
+end
+local someslash=S("\\/")
+local stripper=Cs(P(fwslash)^0/""*reslasher)
+local isnetwork=someslash*someslash*(1-someslash)+(1-fwslash-colon)^1*colon
+local isroot=fwslash^1*-1
+local hasroot=fwslash^1
+local reslasher=lpeg.replacer(S("\\/"),"/")
+local deslasher=lpeg.replacer(S("\\/")^1,"/")
+function file.join(one,two,three,...)
+ if not two then
+ return one=="" and one or lpegmatch(reslasher,one)
+ end
+ if one=="" then
+ return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
+ end
+ if lpegmatch(isnetwork,one) then
+ local one=lpegmatch(reslasher,one)
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return one..two
+ else
+ return one.."/"..two
+ end
+ elseif lpegmatch(isroot,one) then
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return two
+ else
+ return "/"..two
+ end
+ else
+ return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+ end
+end
+local drivespec=R("az","AZ")^1*colon
+local anchors=fwslash+drivespec
+local untouched=periods+(1-period)^1*P(-1)
+local mswindrive=Cs(drivespec*(bwslash/"/"+fwslash)^0)
+local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//")
+local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
+local absolute=fwslash
+function file.collapsepath(str,anchor)
+ if not str then
+ return
+ end
+ if anchor==true and not lpegmatch(anchors,str) then
+ str=getcurrentdir().."/"..str
+ end
+ if str=="" or str=="." then
+ return "."
+ elseif lpegmatch(untouched,str) then
+ return lpegmatch(reslasher,str)
+ end
+ local starter,oldelements=lpegmatch(splitstarter,str)
+ local newelements={}
+ local i=#oldelements
+ while i>0 do
+ local element=oldelements[i]
+ if element=='.' then
+ elseif element=='..' then
+ local n=i-1
+ while n>0 do
+ local element=oldelements[n]
+ if element~='..' and element~='.' then
+ oldelements[n]='.'
+ break
+ else
+ n=n-1
+ end
+ end
+ if n<1 then
+ insert(newelements,1,'..')
+ end
+ elseif element~="" then
+ insert(newelements,1,element)
+ end
+ i=i-1
+ end
+ if #newelements==0 then
+ return starter or "."
+ elseif starter then
+ return starter..concat(newelements,'/')
+ elseif lpegmatch(absolute,str) then
+ return "/"..concat(newelements,'/')
+ else
+ newelements=concat(newelements,'/')
+ if anchor=="." and find(str,"^%./") then
+ return "./"..newelements
+ else
+ return newelements
+ end
+ end
+end
+local validchars=R("az","09","AZ","--","..")
+local pattern_a=lpeg.replacer(1-validchars)
+local pattern_a=Cs((validchars+P(1)/"-")^1)
+local whatever=P("-")^0/""
+local pattern_b=Cs(whatever*(1-whatever*-1)^1)
+function file.robustname(str,strict)
+ if str then
+ str=lpegmatch(pattern_a,str) or str
+ if strict then
+ return lpegmatch(pattern_b,str) or str
+ else
+ return str
+ end
+ end
+end
+local loaddata=io.loaddata
+local savedata=io.savedata
+file.readdata=loaddata
+file.savedata=savedata
+function file.copy(oldname,newname)
+ if oldname and newname then
+ local data=loaddata(oldname)
+ if data and data~="" then
+ savedata(newname,data)
+ end
+ end
+end
+local letter=R("az","AZ")+S("_-+")
+local separator=P("://")
+local qualified=period^0*fwslash+letter*colon+letter^1*separator+letter^1*fwslash
+local rootbased=fwslash+letter*colon
+lpeg.patterns.qualified=qualified
+lpeg.patterns.rootbased=rootbased
+function file.is_qualified_path(filename)
+ return filename and lpegmatch(qualified,filename)~=nil
+end
+function file.is_rootbased_path(filename)
+ return filename and lpegmatch(rootbased,filename)~=nil
+end
+function file.strip(name,dir)
+ if name then
+ local b,a=match(name,"^(.-)"..dir.."(.*)$")
+ return a~="" and a or name
+ end
+end
+function lfs.mkdirs(path)
+ local full=""
+ for sub in gmatch(path,"(/*[^\\/]+)") do
+ full=full..sub
+ lfs.mkdir(full)
+ end
+end
+function file.withinbase(path)
+ local l=0
+ if not find(path,"^/") then
+ path="/"..path
+ end
+ for dir in gmatch(path,"/([^/]+)") do
+ if dir==".." then
+ l=l-1
+ elseif dir~="." then
+ l=l+1
+ end
+ if l<0 then
+ return false
+ end
+ end
+ return true
+end
+local symlinkattributes=lfs.symlinkattributes
+function lfs.readlink(name)
+ return symlinkattributes(name,"target") or nil
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-boolean']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local type,tonumber=type,tonumber
+boolean=boolean or {}
+local boolean=boolean
+function boolean.tonumber(b)
+ if b then return 1 else return 0 end
+end
+function toboolean(str,tolerant)
+ if str==nil then
+ return false
+ elseif str==false then
+ return false
+ elseif str==true then
+ return true
+ elseif str=="true" then
+ return true
+ elseif str=="false" then
+ return false
+ elseif not tolerant then
+ return false
+ elseif str==0 then
+ return false
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
+end
+string.toboolean=toboolean
+function string.booleanstring(str)
+ if str=="0" then
+ return false
+ elseif str=="1" then
+ return true
+ elseif str=="" then
+ return false
+ elseif str=="false" then
+ return false
+ elseif str=="true" then
+ return true
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
+end
+function string.is_boolean(str,default,strict)
+ if type(str)=="string" then
+ if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
+ return true
+ elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
+ return false
+ end
+ end
+ return default
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['l-math']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if not math.ceiling then
+ math.ceiling=math.ceil
+end
+if not math.round then
+ local floor=math.floor
+ function math.round(x) return floor(x+0.5) end
+end
+if not math.div then
+ local floor=math.floor
+ function math.div(n,m) return floor(n/m) end
+end
+if not math.mod then
+ function math.mod(n,m) return n%m end
+end
+if not math.sind then
+ local sin,cos,tan=math.sin,math.cos,math.tan
+ local pipi=2*math.pi/360
+ function math.sind(d) return sin(d*pipi) end
+ function math.cosd(d) return cos(d*pipi) end
+ function math.tand(d) return tan(d*pipi) end
+end
+if not math.odd then
+ function math.odd (n) return n%2~=0 end
+ function math.even(n) return n%2==0 end
+end
+if not math.cosh then
+ local exp=math.exp
+ function math.cosh(x)
+ local xx=exp(x)
+ return (xx+1/xx)/2
+ end
+ function math.sinh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/2
+ end
+ function math.tanh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/(xx+1/xx)
+ end
+end
+if not math.pow then
+ function math.pow(x,y)
+ return x^y
+ end
+end
+if not math.atan2 then
+ math.atan2=math.atan
+end
+if not math.ldexp then
+ function math.ldexp(x,e)
+ return x*2.0^e
+ end
+end
+if not math.log10 then
+ local log=math.log
+ function math.log10(x)
+ return log(x,10)
+ end
+end
+if not math.type then
+ function math.type()
+ return "float"
+ end
+end
+if not math.tointeger then
+ math.mininteger=-0x4FFFFFFFFFFF
+ math.maxinteger=0x4FFFFFFFFFFF
+ local floor=math.floor
+ function math.tointeger(n)
+ local f=floor(n)
+ return f==n and f or nil
+ end
+end
+if not math.ult then
+ local floor=math.floor
+ function math.tointeger(m,n)
+ return floor(m)<floor(n)
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-str']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+utilities=utilities or {}
+utilities.strings=utilities.strings or {}
+local strings=utilities.strings
+local format,gsub,rep,sub,find=string.format,string.gsub,string.rep,string.sub,string.find
+local load,dump=load,string.dump
+local tonumber,type,tostring,next,setmetatable=tonumber,type,tostring,next,setmetatable
+local unpack,concat=table.unpack,table.concat
+local P,V,C,S,R,Ct,Cs,Cp,Carg,Cc=lpeg.P,lpeg.V,lpeg.C,lpeg.S,lpeg.R,lpeg.Ct,lpeg.Cs,lpeg.Cp,lpeg.Carg,lpeg.Cc
+local patterns,lpegmatch=lpeg.patterns,lpeg.match
+local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
+local loadstripped=function(str,shortcuts)
+ if shortcuts then
+ return load(dump(load(str),true),nil,nil,shortcuts)
+ else
+ return load(dump(load(str),true))
+ end
+end
+if not number then number={} end
+local stripzero=patterns.stripzero
+local stripzeros=patterns.stripzeros
+local newline=patterns.newline
+local endofstring=patterns.endofstring
+local anything=patterns.anything
+local whitespace=patterns.whitespace
+local space=patterns.space
+local spacer=patterns.spacer
+local spaceortab=patterns.spaceortab
+local digit=patterns.digit
+local sign=patterns.sign
+local period=patterns.period
+local ptf=1/65536
+local bpf=(7200/7227)/65536
+local function points(n)
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*ptf
+ if n%1==0 then
+ return format("%ipt",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fpt",n))
+end
+local function basepoints(n)
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*bpf
+ if n%1==0 then
+ return format("%ibp",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fbp",n))
+end
+number.points=points
+number.basepoints=basepoints
+local rubish=spaceortab^0*newline
+local anyrubish=spaceortab+newline
+local stripped=(spaceortab^1/"")*newline
+local leading=rubish^0/""
+local trailing=(anyrubish^1*endofstring)/""
+local redundant=rubish^3/"\n"
+local pattern=Cs(leading*(trailing+redundant+stripped+anything)^0)
+function strings.collapsecrlf(str)
+ return lpegmatch(pattern,str)
+end
+local repeaters={}
+function strings.newrepeater(str,offset)
+ offset=offset or 0
+ local s=repeaters[str]
+ if not s then
+ s={}
+ repeaters[str]=s
+ end
+ local t=s[offset]
+ if t then
+ return t
+ end
+ t={}
+ setmetatable(t,{ __index=function(t,k)
+ if not k then
+ return ""
+ end
+ local n=k+offset
+ local s=n>0 and rep(str,n) or ""
+ t[k]=s
+ return s
+ end })
+ s[offset]=t
+ return t
+end
+local extra,tab,start=0,0,4,0
+local nspaces=strings.newrepeater(" ")
+string.nspaces=nspaces
+local pattern=Carg(1)/function(t)
+ extra,tab,start=0,t or 7,1
+ end*Cs((
+ Cp()*patterns.tab/function(position)
+ local current=(position-start+1)+extra
+ local spaces=tab-(current-1)%tab
+ if spaces>0 then
+ extra=extra+spaces-1
+ return nspaces[spaces]
+ else
+ return ""
+ end
+ end+newline*Cp()/function(position)
+ extra,start=0,position
+ end+anything
+ )^1)
+function strings.tabtospace(str,tab)
+ return lpegmatch(pattern,str,1,tab or 7)
+end
+function string.utfpadding(s,n)
+ if not n or n==0 then
+ return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
+end
+local optionalspace=spacer^0
+local nospace=optionalspace/""
+local endofline=nospace*newline
+local stripend=(whitespace^1*endofstring)/""
+local normalline=(nospace*((1-optionalspace*(newline+endofstring))^1)*nospace)
+local stripempty=endofline^1/""
+local normalempty=endofline^1
+local singleempty=endofline*(endofline^0/"")
+local doubleempty=endofline*endofline^-1*(endofline^0/"")
+local stripstart=stripempty^0
+local intospace=whitespace^1/" "
+local noleading=whitespace^1/""
+local notrailing=noleading*endofstring
+local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 )
+local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 )
+local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 )
+local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
+local p_retain_normal=Cs ((normalline+normalempty )^0 )
+local p_retain_collapse=Cs ((normalline+doubleempty )^0 )
+local p_retain_noempty=Cs ((normalline+singleempty )^0 )
+local striplinepatterns={
+ ["prune"]=p_prune_normal,
+ ["prune and collapse"]=p_prune_collapse,
+ ["prune and no empty"]=p_prune_noempty,
+ ["prune and to space"]=p_prune_intospace,
+ ["retain"]=p_retain_normal,
+ ["retain and collapse"]=p_retain_collapse,
+ ["retain and no empty"]=p_retain_noempty,
+ ["collapse"]=patterns.collapser,
+}
+setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end })
+strings.striplinepatterns=striplinepatterns
+function strings.striplines(str,how)
+ return str and lpegmatch(striplinepatterns[how],str) or str
+end
+function strings.collapse(str)
+ return str and lpegmatch(p_prune_intospace,str) or str
+end
+strings.striplong=strings.striplines
+function strings.nice(str)
+ str=gsub(str,"[:%-+_]+"," ")
+ return str
+end
+local n=0
+local sequenced=table.sequenced
+function string.autodouble(s,sep)
+ if s==nil then
+ return '""'
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ('"'..sequenced(s,sep or ",")..'"')
+ end
+ return ('"'..tostring(s)..'"')
+end
+function string.autosingle(s,sep)
+ if s==nil then
+ return "''"
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ("'"..sequenced(s,sep or ",").."'")
+ end
+ return ("'"..tostring(s).."'")
+end
+local tracedchars={ [0]=
+ "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
+ "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
+ "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
+ "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
+ "[space]",
+}
+string.tracedchars=tracedchars
+strings.tracers=tracedchars
+function string.tracedchar(b)
+ if type(b)=="number" then
+ return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
+ else
+ local c=utfbyte(b)
+ return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
+ end
+end
+function number.signed(i)
+ if i>0 then
+ return "+",i
+ else
+ return "-",-i
+ end
+end
+local two=digit*digit
+local three=two*digit
+local prefix=(Carg(1)*three)^1
+local splitter=Cs (
+ (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
+)
+local splitter3=Cs (
+ three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
+)
+patterns.formattednumber=splitter
+function number.formatted(n,sep1,sep2)
+ if sep1==false then
+ if type(n)=="number" then
+ n=tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n)=="number" then
+ n=format("%0.2f",n)
+ end
+ if sep1==true then
+ return lpegmatch(splitter,n,1,".",",")
+ elseif sep1=="." then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
+ elseif sep1=="," then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
+ else
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
+ end
+ end
+end
+local p=Cs(
+ P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
+ )
+function number.compactfloat(n,fmt)
+ if n==0 then
+ return "0"
+ elseif n==1 then
+ return "1"
+ end
+ n=lpegmatch(p,format(fmt or "%0.3f",n))
+ if n=="." or n=="" or n=="-" then
+ return "0"
+ end
+ return n
+end
+local zero=P("0")^1/""
+local plus=P("+")/""
+local minus=P("-")
+local separator=period
+local trailing=zero^1*#S("eE")
+local exponent=(S("eE")*(plus+Cs((minus*zero^0*endofstring)/"")+minus)*zero^0*(endofstring*Cc("0")+anything^1))
+local pattern_a=Cs(minus^0*digit^1*(separator/""*trailing+separator*(trailing+digit)^0)*exponent)
+local pattern_b=Cs((exponent+anything)^0)
+function number.sparseexponent(f,n)
+ if not n then
+ n=f
+ f="%e"
+ end
+ local tn=type(n)
+ if tn=="string" then
+ local m=tonumber(n)
+ if m then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
+ end
+ elseif tn=="number" then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ end
+ return tostring(n)
+end
+local hf={}
+local hs={}
+setmetatable(hf,{ __index=function(t,k)
+ local v="%."..k.."f"
+ t[k]=v
+ return v
+end } )
+setmetatable(hs,{ __index=function(t,k)
+ local v="%"..k.."s"
+ t[k]=v
+ return v
+end } )
+function number.formattedfloat(n,b,a)
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
+end
+local template=[[
+%s
+%s
+return function(%s) return %s end
+]]
+local pattern=Cs(Cc('"')*(
+ (1-S('"\\\n\r'))^1+P('"')/'\\"'+P('\\')/'\\\\'+P('\n')/'\\n'+P('\r')/'\\r'
+)^0*Cc('"'))
+patterns.escapedquotes=pattern
+function string.escapedquotes(s)
+ return lpegmatch(pattern,s)
+end
+local preamble=""
+local environment={
+ global=global or _G,
+ lpeg=lpeg,
+ type=type,
+ tostring=tostring,
+ tonumber=tonumber,
+ format=string.format,
+ concat=table.concat,
+ signed=number.signed,
+ points=number.points,
+ basepoints=number.basepoints,
+ utfchar=utf.char,
+ utfbyte=utf.byte,
+ lpegmatch=lpeg.match,
+ nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
+ tracedchar=string.tracedchar,
+ autosingle=string.autosingle,
+ autodouble=string.autodouble,
+ sequenced=table.sequenced,
+ formattednumber=number.formatted,
+ sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat,
+ stripzero=patterns.stripzero,
+ stripzeros=patterns.stripzeros,
+ escapedquotes=string.escapedquotes,
+ FORMAT=string.f9,
+}
+local arguments={ "a1" }
+setmetatable(arguments,{ __index=function(t,k)
+ local v=t[k-1]..",a"..k
+ t[k]=v
+ return v
+ end
+})
+local prefix_any=C((sign+space+period+digit)^0)
+local prefix_sub=(C((sign+digit)^0)+Cc(0))*period*(C((sign+digit)^0)+Cc(0))
+local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
+local format_s=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("(a%s or '')",n)
+ end
+end
+local format_S=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',tostring(a%s))",f,n)
+ else
+ return format("tostring(a%s)",n)
+ end
+end
+local format_right=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ elseif f>0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
+end
+local format_left=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ end
+ if f<0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
+end
+local format_q=function()
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+end
+local format_Q=function()
+ n=n+1
+ return format("escapedquotes(tostring(a%s))",n)
+end
+local format_i=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%si',a%s)",f,n)
+ else
+ return format("format('%%i',a%s)",n)
+ end
+end
+local format_d=format_i
+local format_I=function(f)
+ n=n+1
+ return format("format('%%s%%%si',signed(a%s))",f,n)
+end
+local format_f=function(f)
+ n=n+1
+ return format("format('%%%sf',a%s)",f,n)
+end
+local format_F=function(f)
+ n=n+1
+ if not f or f=="" then
+ return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
+ else
+ return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
+ end
+end
+local format_k=function(b,a)
+ n=n+1
+ return format("formattedfloat(a%s,%s,%s)",n,b or 0,a or 0)
+end
+local format_g=function(f)
+ n=n+1
+ return format("format('%%%sg',a%s)",f,n)
+end
+local format_G=function(f)
+ n=n+1
+ return format("format('%%%sG',a%s)",f,n)
+end
+local format_e=function(f)
+ n=n+1
+ return format("format('%%%se',a%s)",f,n)
+end
+local format_E=function(f)
+ n=n+1
+ return format("format('%%%sE',a%s)",f,n)
+end
+local format_j=function(f)
+ n=n+1
+ return format("sparseexponent('%%%se',a%s)",f,n)
+end
+local format_J=function(f)
+ n=n+1
+ return format("sparseexponent('%%%sE',a%s)",f,n)
+end
+local format_x=function(f)
+ n=n+1
+ return format("format('%%%sx',a%s)",f,n)
+end
+local format_X=function(f)
+ n=n+1
+ return format("format('%%%sX',a%s)",f,n)
+end
+local format_o=function(f)
+ n=n+1
+ return format("format('%%%so',a%s)",f,n)
+end
+local format_c=function()
+ n=n+1
+ return format("utfchar(a%s)",n)
+end
+local format_C=function()
+ n=n+1
+ return format("tracedchar(a%s)",n)
+end
+local format_r=function(f)
+ n=n+1
+ return format("format('%%%s.0f',a%s)",f,n)
+end
+local format_h=function(f)
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
+end
+local format_H=function(f)
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
+end
+local format_u=function(f)
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
+end
+local format_U=function(f)
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
+end
+local format_p=function()
+ n=n+1
+ return format("points(a%s)",n)
+end
+local format_b=function()
+ n=n+1
+ return format("basepoints(a%s)",n)
+end
+local format_t=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("concat(a%s,%q)",n,f)
+ else
+ return format("concat(a%s)",n)
+ end
+end
+local format_T=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("sequenced(a%s,%q)",n,f)
+ else
+ return format("sequenced(a%s)",n)
+ end
+end
+local format_l=function()
+ n=n+1
+ return format("(a%s and 'true' or 'false')",n)
+end
+local format_L=function()
+ n=n+1
+ return format("(a%s and 'TRUE' or 'FALSE')",n)
+end
+local format_n=function()
+ n=n+1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+end
+local format_N=function(f)
+ n=n+1
+ if not f or f=="" then
+ f=".9"
+ end
+ return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+end
+local format_a=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("autosingle(a%s,%q)",n,f)
+ else
+ return format("autosingle(a%s)",n)
+ end
+end
+local format_A=function(f)
+ n=n+1
+ if f and f~="" then
+ return format("autodouble(a%s,%q)",n,f)
+ else
+ return format("autodouble(a%s)",n)
+ end
+end
+local format_w=function(f)
+ n=n+1
+ f=tonumber(f)
+ if f then
+ return format("nspaces[%s+a%s]",f,n)
+ else
+ return format("nspaces[a%s]",n)
+ end
+end
+local format_W=function(f)
+ return format("nspaces[%s]",tonumber(f) or 0)
+end
+local format_m=function(f)
+ n=n+1
+ if not f or f=="" then
+ f=","
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,".")]],n,f)
+ end
+end
+local format_M=function(f)
+ n=n+1
+ if not f or f=="" then
+ f="."
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,",")]],n,f)
+ end
+end
+local format_z=function(f)
+ n=n+(tonumber(f) or 1)
+ return "''"
+end
+local format_rest=function(s)
+ return format("%q",s)
+end
+local format_extension=function(extensions,f,name)
+ local extension=extensions[name] or "tostring(%s)"
+ local f=tonumber(f) or 1
+ local w=find(extension,"%.%.%.")
+ if w then
+ if f==0 then
+ extension=gsub(extension,"%.%.%.","")
+ return extension
+ elseif f==1 then
+ extension=gsub(extension,"%.%.%.","%%s")
+ n=n+1
+ local a="a"..n
+ return format(extension,a,a)
+ elseif f<0 then
+ local a="a"..(n+f+1)
+ return format(extension,a,a)
+ else
+ extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+ local t={}
+ for i=1,f do
+ n=n+1
+ t[i]="a"..n
+ end
+ return format(extension,unpack(t))
+ end
+ else
+ extension=gsub(extension,"%%s",function()
+ n=n+1
+ return "a"..n
+ end)
+ return extension
+ end
+end
+local builder=Cs { "start",
+ start=(
+ (
+ P("%")/""*(
+ V("!")
++V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
++V("c")+V("C")+V("S")
++V("Q")
++V("n")
++V("N")
++V("k")
++V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
++V("W")
++V("a")
++V("A")
++V("j")+V("J")
++V("m")+V("M")
++V("z")
++V(">")
++V("<")
+ )+V("*")
+ )*(endofstring+Carg(1))
+ )^0,
+ ["s"]=(prefix_any*P("s"))/format_s,
+ ["q"]=(prefix_any*P("q"))/format_q,
+ ["i"]=(prefix_any*P("i"))/format_i,
+ ["d"]=(prefix_any*P("d"))/format_d,
+ ["f"]=(prefix_any*P("f"))/format_f,
+ ["F"]=(prefix_any*P("F"))/format_F,
+ ["g"]=(prefix_any*P("g"))/format_g,
+ ["G"]=(prefix_any*P("G"))/format_G,
+ ["e"]=(prefix_any*P("e"))/format_e,
+ ["E"]=(prefix_any*P("E"))/format_E,
+ ["x"]=(prefix_any*P("x"))/format_x,
+ ["X"]=(prefix_any*P("X"))/format_X,
+ ["o"]=(prefix_any*P("o"))/format_o,
+ ["S"]=(prefix_any*P("S"))/format_S,
+ ["Q"]=(prefix_any*P("Q"))/format_Q,
+ ["n"]=(prefix_any*P("n"))/format_n,
+ ["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
+ ["c"]=(prefix_any*P("c"))/format_c,
+ ["C"]=(prefix_any*P("C"))/format_C,
+ ["r"]=(prefix_any*P("r"))/format_r,
+ ["h"]=(prefix_any*P("h"))/format_h,
+ ["H"]=(prefix_any*P("H"))/format_H,
+ ["u"]=(prefix_any*P("u"))/format_u,
+ ["U"]=(prefix_any*P("U"))/format_U,
+ ["p"]=(prefix_any*P("p"))/format_p,
+ ["b"]=(prefix_any*P("b"))/format_b,
+ ["t"]=(prefix_tab*P("t"))/format_t,
+ ["T"]=(prefix_tab*P("T"))/format_T,
+ ["l"]=(prefix_any*P("l"))/format_l,
+ ["L"]=(prefix_any*P("L"))/format_L,
+ ["I"]=(prefix_any*P("I"))/format_I,
+ ["w"]=(prefix_any*P("w"))/format_w,
+ ["W"]=(prefix_any*P("W"))/format_W,
+ ["j"]=(prefix_any*P("j"))/format_j,
+ ["J"]=(prefix_any*P("J"))/format_J,
+ ["m"]=(prefix_any*P("m"))/format_m,
+ ["M"]=(prefix_any*P("M"))/format_M,
+ ["z"]=(prefix_any*P("z"))/format_z,
+ ["a"]=(prefix_any*P("a"))/format_a,
+ ["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
+ ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
+ ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
+ ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
+}
+local xx=setmetatable({},{ __index=function(t,k) local v=format("%02x",k) t[k]=v return v end })
+local XX=setmetatable({},{ __index=function(t,k) local v=format("%02X",k) t[k]=v return v end })
+local preset={
+ ["%02x"]=function(n) return xx[n] end,
+ ["%02X"]=function(n) return XX[n] end,
+}
+local direct=P("%")*(sign+space+period+digit)^0*S("sqidfgGeExXo")*endofstring/[[local format = string.format return function(str) return format("%0",str) end]]
+local function make(t,str)
+ local f=preset[str]
+ if f then
+ return f
+ end
+ local p=lpegmatch(direct,str)
+ if p then
+ f=loadstripped(p)()
+ else
+ n=0
+ p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
+ if n>0 then
+ p=format(template,preamble,t._preamble_,arguments[n],p)
+ f=loadstripped(p,t._environment_)()
+ else
+ f=function() return str end
+ end
+ end
+ t[str]=f
+ return f
+end
+local function use(t,fmt,...)
+ return t[fmt](...)
+end
+strings.formatters={}
+function strings.formatters.new(noconcat)
+ local e={}
+ for k,v in next,environment do
+ e[k]=v
+ end
+ local t={
+ _type_="formatter",
+ _connector_=noconcat and "," or "..",
+ _extensions_={},
+ _preamble_="",
+ _environment_=e,
+ }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
+end
+local formatters=strings.formatters.new()
+string.formatters=formatters
+string.formatter=function(str,...) return formatters[str](...) end
+local function add(t,name,template,preamble)
+ if type(t)=="table" and t._type_=="formatter" then
+ t._extensions_[name]=template or "%s"
+ if type(preamble)=="string" then
+ t._preamble_=preamble.."\n"..t._preamble_
+ elseif type(preamble)=="table" then
+ for k,v in next,preamble do
+ t._environment_[k]=v
+ end
+ end
+ end
+end
+strings.formatters.add=add
+patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+anything)^0)
+patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+anything)^0)
+patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0)
+patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"'))
+add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=patterns.xmlescape })
+add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=patterns.texescape })
+add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=patterns.luaescape })
+local dquote=patterns.dquote
+local equote=patterns.escaped+dquote/'\\"'+1
+local cquote=Cc('"')
+local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
++Cs(cquote*(equote-space)^0*space*equote^0*cquote)
+function string.optionalquoted(str)
+ return lpegmatch(pattern,str) or str
+end
+local pattern=Cs((newline/(os.newline or "\r")+1)^0)
+function string.replacenewlines(str)
+ return lpegmatch(pattern,str)
+end
+function strings.newcollector()
+ local result,r={},0
+ return
+ function(fmt,str,...)
+ r=r+1
+ result[r]=str==nil and fmt or formatters[fmt](str,...)
+ end,
+ function(connector)
+ if result then
+ local str=concat(result,connector)
+ result,r={},0
+ return str
+ end
+ end
+end
+local f_16_16=formatters["%0.5N"]
+function number.to16dot16(n)
+ return f_16_16(n/65536.0)
+end
+if not string.explode then
+ local tsplitat=lpeg.tsplitat
+ local p_utf=patterns.utf8character
+ local p_check=C(p_utf)*(P("+")*Cc(true))^0
+ local p_split=Ct(C(p_utf)^0)
+ local p_space=Ct((C(1-P(" ")^1)+P(" ")^1)^0)
+ function string.explode(str,symbol)
+ if symbol=="" then
+ return lpegmatch(p_split,str)
+ elseif symbol then
+ local a,b=lpegmatch(p_check,symbol)
+ if b then
+ return lpegmatch(tsplitat(P(a)^1),str)
+ else
+ return lpegmatch(tsplitat(a),str)
+ end
+ else
+ return lpegmatch(p_space,str)
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['util-fil']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local tonumber=tonumber
+local byte=string.byte
+local char=string.char
+utilities=utilities or {}
+local files={}
+utilities.files=files
+local zerobased={}
+function files.open(filename,zb)
+ local f=io.open(filename,"rb")
+ if f then
+ zerobased[f]=zb or false
+ end
+ return f
+end
+function files.close(f)
+ zerobased[f]=nil
+ f:close()
+end
+function files.size(f)
+ local current=f:seek()
+ local size=f:seek("end")
+ f:seek("set",current)
+ return size
+end
+files.getsize=files.size
+function files.setposition(f,n)
+ if zerobased[f] then
+ f:seek("set",n)
+ else
+ f:seek("set",n-1)
+ end
+end
+function files.getposition(f)
+ if zerobased[f] then
+ return f:seek()
+ else
+ return f:seek()+1
+ end
+end
+function files.look(f,n,chars)
+ local p=f:seek()
+ local s=f:read(n)
+ f:seek("set",p)
+ if chars then
+ return s
+ else
+ return byte(s,1,#s)
+ end
+end
+function files.skip(f,n)
+ if n==1 then
+ f:read(n)
+ else
+ f:seek("set",f:seek()+n)
+ end
+end
+function files.readbyte(f)
+ return byte(f:read(1))
+end
+function files.readbytes(f,n)
+ return byte(f:read(n),1,n)
+end
+function files.readbytetable(f,n)
+ local s=f:read(n or 1)
+ return { byte(s,1,#s) }
+end
+function files.readchar(f)
+ return f:read(1)
+end
+function files.readstring(f,n)
+ return f:read(n or 1)
+end
+function files.readinteger1(f)
+ local n=byte(f:read(1))
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
+end
+files.readcardinal1=files.readbyte
+files.readcardinal=files.readcardinal1
+files.readinteger=files.readinteger1
+files.readsignedbyte=files.readinteger1
+function files.readcardinal2(f)
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
+end
+function files.readcardinal2le(f)
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
+end
+function files.readinteger2(f)
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
+end
+function files.readinteger2le(f)
+ local b,a=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
+end
+function files.readcardinal3(f)
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+end
+function files.readcardinal3le(f)
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+end
+function files.readinteger3(f)
+ local a,b,c=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
+end
+function files.readinteger3le(f)
+ local c,b,a=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
+end
+function files.readcardinal4(f)
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+end
+function files.readcardinal4le(f)
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+end
+function files.readinteger4(f)
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
+end
+function files.readinteger4le(f)
+ local d,c,b,a=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
+end
+function files.readfixed2(f)
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
+end
+function files.readfixed4(f)
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
+end
+if bit32 then
+ local extract=bit32.extract
+ local band=bit32.band
+ function files.read2dot14(f)
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+ else
+ local n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+ end
+ end
+end
+function files.skipshort(f,n)
+ f:read(2*(n or 1))
+end
+function files.skiplong(f,n)
+ f:read(4*(n or 1))
+end
+if bit32 then
+ local rshift=bit32.rshift
+ function files.writecardinal2(f,n)
+ local a=char(n%256)
+ n=rshift(n,8)
+ local b=char(n%256)
+ f:write(b,a)
+ end
+ function files.writecardinal4(f,n)
+ local a=char(n%256)
+ n=rshift(n,8)
+ local b=char(n%256)
+ n=rshift(n,8)
+ local c=char(n%256)
+ n=rshift(n,8)
+ local d=char(n%256)
+ f:write(d,c,b,a)
+ end
+ function files.writecardinal2le(f,n)
+ local a=char(n%256)
+ n=rshift(n,8)
+ local b=char(n%256)
+ f:write(a,b)
+ end
+ function files.writecardinal4le(f,n)
+ local a=char(n%256)
+ n=rshift(n,8)
+ local b=char(n%256)
+ n=rshift(n,8)
+ local c=char(n%256)
+ n=rshift(n,8)
+ local d=char(n%256)
+ f:write(a,b,c,d)
+ end
+else
+ local floor=math.floor
+ function files.writecardinal2(f,n)
+ local a=char(n%256)
+ n=floor(n/256)
+ local b=char(n%256)
+ f:write(b,a)
+ end
+ function files.writecardinal4(f,n)
+ local a=char(n%256)
+ n=floor(n/256)
+ local b=char(n%256)
+ n=floor(n/256)
+ local c=char(n%256)
+ n=floor(n/256)
+ local d=char(n%256)
+ f:write(d,c,b,a)
+ end
+ function files.writecardinal2le(f,n)
+ local a=char(n%256)
+ n=floor(n/256)
+ local b=char(n%256)
+ f:write(a,b)
+ end
+ function files.writecardinal4le(f,n)
+ local a=char(n%256)
+ n=floor(n/256)
+ local b=char(n%256)
+ n=floor(n/256)
+ local c=char(n%256)
+ n=floor(n/256)
+ local d=char(n%256)
+ f:write(a,b,c,d)
+ end
+end
+function files.writestring(f,s)
+ f:write(char(byte(s,1,#s)))
+end
+function files.writebyte(f,b)
+ f:write(char(b))
+end
+if fio and fio.readcardinal1 then
+ files.readcardinal1=fio.readcardinal1
+ files.readcardinal2=fio.readcardinal2
+ files.readcardinal3=fio.readcardinal3
+ files.readcardinal4=fio.readcardinal4
+ files.readcardinal1le=fio.readcardinal1le or files.readcardinal1le
+ files.readcardinal2le=fio.readcardinal2le or files.readcardinal2le
+ files.readcardinal3le=fio.readcardinal3le or files.readcardinal3le
+ files.readcardinal4le=fio.readcardinal4le or files.readcardinal4le
+ files.readinteger1=fio.readinteger1
+ files.readinteger2=fio.readinteger2
+ files.readinteger3=fio.readinteger3
+ files.readinteger4=fio.readinteger4
+ files.readinteger1le=fio.readinteger1le or files.readinteger1le
+ files.readinteger2le=fio.readinteger2le or files.readinteger2le
+ files.readinteger3le=fio.readinteger3le or files.readinteger3le
+ files.readinteger4le=fio.readinteger4le or files.readinteger4le
+ files.readfixed2=fio.readfixed2
+ files.readfixed4=fio.readfixed4
+ files.read2dot14=fio.read2dot14
+ files.setposition=fio.setposition
+ files.getposition=fio.getposition
+ files.readbyte=files.readcardinal1
+ files.readsignedbyte=files.readinteger1
+ files.readcardinal=files.readcardinal1
+ files.readinteger=files.readinteger1
+ local skipposition=fio.skipposition
+ files.skipposition=skipposition
+ files.readbytes=fio.readbytes
+ files.readbytetable=fio.readbytetable
+ function files.skipshort(f,n)
+ skipposition(f,2*(n or 1))
+ end
+ function files.skiplong(f,n)
+ skipposition(f,4*(n or 1))
+ end
+end
+if fio and fio.writecardinal1 then
+ files.writecardinal1=fio.writecardinal1
+ files.writecardinal2=fio.writecardinal2
+ files.writecardinal3=fio.writecardinal3
+ files.writecardinal4=fio.writecardinal4
+ files.writecardinal1le=fio.writecardinal1le
+ files.writecardinal2le=fio.writecardinal2le
+ files.writecardinal3le=fio.writecardinal3le
+ files.writecardinal4le=fio.writecardinal4le
+ files.writeinteger1=fio.writeinteger1 or fio.writecardinal1
+ files.writeinteger2=fio.writeinteger2 or fio.writecardinal2
+ files.writeinteger3=fio.writeinteger3 or fio.writecardinal3
+ files.writeinteger4=fio.writeinteger4 or fio.writecardinal4
+ files.writeinteger1le=files.writeinteger1le or fio.writecardinal1le
+ files.writeinteger2le=files.writeinteger2le or fio.writecardinal2le
+ files.writeinteger3le=files.writeinteger3le or fio.writecardinal3le
+ files.writeinteger4le=files.writeinteger4le or fio.writecardinal4le
+end
+if fio and fio.readcardinaltable then
+ files.readcardinaltable=fio.readcardinaltable
+ files.readintegertable=fio.readintegertable
+else
+ local readcardinal1=files.readcardinal1
+ local readcardinal2=files.readcardinal2
+ local readcardinal3=files.readcardinal3
+ local readcardinal4=files.readcardinal4
+ function files.readcardinaltable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readcardinal1(f) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
+ return t
+ end
+ local readinteger1=files.readinteger1
+ local readinteger2=files.readinteger2
+ local readinteger3=files.readinteger3
+ local readinteger4=files.readinteger4
+ function files.readintegertable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readinteger1(f) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
+ return t
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['luat-basics-gen']={
+ version=1.100,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+--removed
+
+end
+local match,gmatch,gsub,lower=string.match,string.gmatch,string.gsub,string.lower
+local formatters,split,format,dump=string.formatters,string.split,string.format,string.dump
+local loadfile,type=loadfile,type
+local setmetatable,getmetatable,collectgarbage=setmetatable,getmetatable,collectgarbage
+local floor=math.floor
+local dummyfunction=function()
+end
+local dummyreporter=function(c)
+ return function(f,...)
+ local r=texio.reporter or texio.write_nl
+ if f then
+ r(c.." : "..(formatters or format)(f,...))
+ else
+ r("")
+ end
+ end
+end
+local dummyreport=function(c,f,...)
+ local r=texio.reporter or texio.write_nl
+ if f then
+ r(c.." : "..(formatters or format)(f,...))
+ else
+ r("")
+ end
+end
+statistics={
+ register=dummyfunction,
+ starttiming=dummyfunction,
+ stoptiming=dummyfunction,
+ elapsedtime=nil,
+}
+directives={
+ register=dummyfunction,
+ enable=dummyfunction,
+ disable=dummyfunction,
+}
+trackers={
+ register=dummyfunction,
+ enable=dummyfunction,
+ disable=dummyfunction,
+}
+experiments={
+ register=dummyfunction,
+ enable=dummyfunction,
+ disable=dummyfunction,
+}
+storage={
+ register=dummyfunction,
+ shared={},
+}
+logs={
+ new=dummyreporter,
+ reporter=dummyreporter,
+ messenger=dummyreporter,
+ report=dummyreport,
+}
+callbacks={
+ register=function(n,f)
+ return callback.register(n,f)
+ end,
+}
+utilities=utilities or {}
+utilities.storage=utilities.storage or {
+ allocate=function(t)
+ return t or {}
+ end,
+ mark=function(t)
+ return t or {}
+ end,
+}
+utilities.parsers=utilities.parsers or {
+ settings_to_array=function(s)
+ return split(s,",")
+ end,
+ settings_to_hash=function(s)
+ local t={}
+ for k,v in gmatch(s,"([^%s,=]+)=([^%s,]+)") do
+ t[k]=v
+ end
+ return t
+ end,
+ settings_to_hash_colon_too=function(s)
+ local t={}
+ for k,v in gmatch(s,"([^%s,=:]+)[=:]([^%s,]+)") do
+ t[k]=v
+ end
+ return t
+ end,
+}
+characters=characters or {
+ data={}
+}
+texconfig.kpse_init=true
+resolvers=resolvers or {}
+local remapper={
+ otf="opentype fonts",
+ ttf="truetype fonts",
+ ttc="truetype fonts",
+ cid="cid maps",
+ cidmap="cid maps",
+ pfb="type1 fonts",
+ afm="afm",
+ enc="enc files",
+ lua="tex",
+}
+function resolvers.findfile(name,fileformat)
+ name=gsub(name,"\\","/")
+ if not fileformat or fileformat=="" then
+ fileformat=file.suffix(name)
+ if fileformat=="" then
+ fileformat="tex"
+ end
+ end
+ fileformat=lower(fileformat)
+ fileformat=remapper[fileformat] or fileformat
+ local found=kpse.find_file(name,fileformat)
+ if not found or found=="" then
+ found=kpse.find_file(name,"other text files")
+ end
+ return found
+end
+resolvers.findbinfile=resolvers.findfile
+function resolvers.loadbinfile(filename,filetype)
+ local data=io.loaddata(filename)
+ return true,data,#data
+end
+function resolvers.resolve(s)
+ return s
+end
+function resolvers.unresolve(s)
+ return s
+end
+caches={}
+local writable=nil
+local readables={}
+local usingjit=jit
+if not caches.namespace or caches.namespace=="" or caches.namespace=="context" then
+ caches.namespace='generic'
+end
+do
+ local cachepaths=kpse.expand_var('$TEXMFCACHE') or ""
+ if cachepaths=="" or cachepaths=="$TEXMFCACHE" then
+ cachepaths=kpse.expand_var('$TEXMFVAR') or ""
+ end
+ if cachepaths=="" or cachepaths=="$TEXMFVAR" then
+ cachepaths=kpse.expand_var('$VARTEXMF') or ""
+ end
+ if cachepaths=="" then
+ local fallbacks={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
+ for i=1,#fallbacks do
+ cachepaths=os.getenv(fallbacks[i]) or ""
+ if cachepath~="" and lfs.isdir(cachepath) then
+ break
+ end
+ end
+ end
+ if cachepaths=="" then
+ cachepaths="."
+ end
+ cachepaths=split(cachepaths,os.type=="windows" and ";" or ":")
+ for i=1,#cachepaths do
+ local cachepath=cachepaths[i]
+ if not lfs.isdir(cachepath) then
+ lfs.mkdirs(cachepath)
+ if lfs.isdir(cachepath) then
+ logs.report("system","creating cache path '%s'",cachepath)
+ end
+ end
+ if file.is_writable(cachepath) then
+ writable=file.join(cachepath,"luatex-cache")
+ lfs.mkdir(writable)
+ writable=file.join(writable,caches.namespace)
+ lfs.mkdir(writable)
+ break
+ end
+ end
+ for i=1,#cachepaths do
+ if file.is_readable(cachepaths[i]) then
+ readables[#readables+1]=file.join(cachepaths[i],"luatex-cache",caches.namespace)
+ end
+ end
+ if not writable then
+ logs.report("system","no writeable cache path, quiting")
+ os.exit()
+ elseif #readables==0 then
+ logs.report("system","no readable cache path, quiting")
+ os.exit()
+ elseif #readables==1 and readables[1]==writable then
+ logs.report("system","using cache '%s'",writable)
+ else
+ logs.report("system","using write cache '%s'",writable)
+ logs.report("system","using read cache '%s'",table.concat(readables," "))
+ end
+end
+function caches.getwritablepath(category,subcategory)
+ local path=file.join(writable,category)
+ lfs.mkdir(path)
+ path=file.join(path,subcategory)
+ lfs.mkdir(path)
+ return path
+end
+function caches.getreadablepaths(category,subcategory)
+ local t={}
+ for i=1,#readables do
+ t[i]=file.join(readables[i],category,subcategory)
+ end
+ return t
+end
+local function makefullname(path,name)
+ if path and path~="" then
+ return file.addsuffix(file.join(path,name),"lua"),file.addsuffix(file.join(path,name),usingjit and "lub" or "luc")
+ end
+end
+function caches.is_writable(path,name)
+ local fullname=makefullname(path,name)
+ return fullname and file.is_writable(fullname)
+end
+function caches.loaddata(readables,name,writable)
+ for i=1,#readables do
+ local path=readables[i]
+ local loader=false
+ local luaname,lucname=makefullname(path,name)
+ if lfs.isfile(lucname) then
+ logs.report("system","loading luc file '%s'",lucname)
+ loader=loadfile(lucname)
+ end
+ if not loader and lfs.isfile(luaname) then
+ local luacrap,lucname=makefullname(writable,name)
+ logs.report("system","compiling luc file '%s'",lucname)
+ if lfs.isfile(lucname) then
+ loader=loadfile(lucname)
+ end
+ caches.compile(data,luaname,lucname)
+ if lfs.isfile(lucname) then
+ logs.report("system","loading luc file '%s'",lucname)
+ loader=loadfile(lucname)
+ else
+ logs.report("system","error in loading luc file '%s'",lucname)
+ end
+ if not loader then
+ logs.report("system","loading lua file '%s'",luaname)
+ loader=loadfile(luaname)
+ else
+ logs.report("system","error in loading lua file '%s'",luaname)
+ end
+ end
+ if loader then
+ loader=loader()
+ collectgarbage("step")
+ return loader
+ end
+ end
+ return false
+end
+function caches.savedata(path,name,data)
+ local luaname,lucname=makefullname(path,name)
+ if luaname then
+ logs.report("system","saving lua file '%s'",luaname)
+ table.tofile(luaname,data,true)
+ if lucname and type(caches.compile)=="function" then
+ os.remove(lucname)
+ logs.report("system","saving luc file '%s'",lucname)
+ caches.compile(data,luaname,lucname)
+ end
+ end
+end
+function caches.compile(data,luaname,lucname)
+ local d=io.loaddata(luaname)
+ if not d or d=="" then
+ d=table.serialize(data,true)
+ end
+ if d and d~="" then
+ local f=io.open(lucname,'wb')
+ if f then
+ local s=loadstring(d)
+ if s then
+ f:write(dump(s,true))
+ end
+ f:close()
+ end
+ end
+end
+function table.setmetatableindex(t,f)
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ if f=="table" then
+ f=function(t,k) local v={} t[k]=v return v end
+ end
+ if m then
+ m.__index=f
+ else
+ setmetatable(t,{ __index=f })
+ end
+ return t
+end
+function table.makeweak(t)
+ local m=getmetatable(t)
+ if m then
+ m.__mode="v"
+ else
+ setmetatable(t,{ __mode="v" })
+ end
+ return t
+end
+arguments={}
+if arg then
+ for i=1,#arg do
+ local k,v=match(arg[i],"^%-%-([^=]+)=?(.-)$")
+ if k and v then
+ arguments[k]=v
+ end
+ end
+end
+if not number.idiv then
+ function number.idiv(i,d)
+ return floor(i/d)
+ end
+end
+local u=unicode and unicode.utf8
+if u then
+ utf.lower=u.lower
+ utf.upper=u.upper
+ utf.char=u.char
+ utf.byte=u.byte
+ utf.len=u.len
+ if lpeg.setutfcasers then
+ lpeg.setutfcasers(u.lower,u.upper)
+ end
+ local bytepairs=string.bytepairs
+ local utfchar=utf.char
+ local concat=table.concat
+ function utf.utf16_to_utf8_be(s)
+ if not s then
+ return nil
+ elseif s=="" then
+ return ""
+ end
+ local result,r,more={},0,0
+ for left,right in bytepairs(s) do
+ if right then
+ local now=256*left+right
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ r=r+1
+ result[r]=utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ else
+ r=r+1
+ result[r]=utfchar(now)
+ end
+ end
+ end
+ return concat(result)
+ end
+ local characters=string.utfcharacters
+ function utf.split(str)
+ local t,n={},0
+ for s in characters(str) do
+ n=n+1
+ t[n]=s
+ end
+ return t
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['data-con']={
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local format,lower,gsub=string.format,string.lower,string.gsub
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
+local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
+containers=containers or {}
+local containers=containers
+containers.usecache=true
+local report_containers=logs.reporter("resolvers","containers")
+local allocated={}
+local mt={
+ __index=function(t,k)
+ if k=="writable" then
+ local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
+ t.writable=writable
+ return writable
+ elseif k=="readables" then
+ local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
+ t.readables=readables
+ return readables
+ end
+ end,
+ __storage__=true
+}
+function containers.define(category,subcategory,version,enabled)
+ if category and subcategory then
+ local c=allocated[category]
+ if not c then
+ c={}
+ allocated[category]=c
+ end
+ local s=c[subcategory]
+ if not s then
+ s={
+ category=category,
+ subcategory=subcategory,
+ storage={},
+ enabled=enabled,
+ version=version or math.pi,
+ trace=false,
+ }
+ setmetatable(s,mt)
+ c[subcategory]=s
+ end
+ return s
+ end
+end
+function containers.is_usable(container,name)
+ return container.enabled and caches and caches.is_writable(container.writable,name)
+end
+function containers.is_valid(container,name)
+ if name and name~="" then
+ local storage=container.storage[name]
+ return storage and storage.cache_version==container.version
+ else
+ return false
+ end
+end
+function containers.read(container,name)
+ local storage=container.storage
+ local stored=storage[name]
+ if not stored and container.enabled and caches and containers.usecache then
+ stored=caches.loaddata(container.readables,name,container.writable)
+ if stored and stored.cache_version==container.version then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","load",container.subcategory,name)
+ end
+ else
+ stored=nil
+ end
+ storage[name]=stored
+ elseif stored then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
+ end
+ end
+ return stored
+end
+function containers.write(container,name,data)
+ if data then
+ data.cache_version=container.version
+ if container.enabled and caches then
+ local unique,shared=data.unique,data.shared
+ data.unique,data.shared=nil,nil
+ caches.savedata(container.writable,name,data)
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","save",container.subcategory,name)
+ end
+ data.unique,data.shared=unique,shared
+ end
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","store",container.subcategory,name)
+ end
+ container.storage[name]=data
+ end
+ return data
+end
+function containers.content(container,name)
+ return container.storage[name]
+end
+function containers.cleanname(name)
+ return (gsub(lower(name),"[^%w\128-\255]+","-"))
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['luatex-fonts-nod']={
+ version=1.001,
+ comment="companion to luatex-fonts.lua",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+--removed
+
+end
+if tex.attribute[0]~=0 then
+ texio.write_nl("log","!")
+ texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be")
+ texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special")
+ texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.")
+ texio.write_nl("log","!")
+ tex.attribute[0]=0
+end
+attributes=attributes or {}
+attributes.unsetvalue=-0x7FFFFFFF
+local numbers,last={},127
+attributes.private=attributes.private or function(name)
+ local number=numbers[name]
+ if not number then
+ if last<255 then
+ last=last+1
+ end
+ number=last
+ numbers[name]=number
+ end
+ return number
+end
+nodes={}
+nodes.handlers={}
+local nodecodes={}
+local glyphcodes=node.subtypes("glyph")
+local disccodes=node.subtypes("disc")
+for k,v in next,node.types() do
+ v=string.gsub(v,"_","")
+ nodecodes[k]=v
+ nodecodes[v]=k
+end
+for k,v in next,glyphcodes do
+ glyphcodes[v]=k
+end
+for k,v in next,disccodes do
+ disccodes[v]=k
+end
+nodes.nodecodes=nodecodes
+nodes.glyphcodes=glyphcodes
+nodes.disccodes=disccodes
+nodes.handlers.protectglyphs=node.protect_glyphs
+nodes.handlers.unprotectglyphs=node.unprotect_glyphs
+local direct=node.direct
+local nuts={}
+nodes.nuts=nuts
+local tonode=direct.tonode
+local tonut=direct.todirect
+nodes.tonode=tonode
+nodes.tonut=tonut
+nuts.tonode=tonode
+nuts.tonut=tonut
+nuts.getattr=direct.get_attribute
+nuts.getboth=direct.getboth
+nuts.getchar=direct.getchar
+nuts.getcomponents=direct.getcomponents
+nuts.getdirection=direct.getdirection
+nuts.getdisc=direct.getdisc
+nuts.getfield=direct.getfield
+nuts.getfont=direct.getfont
+nuts.getid=direct.getid
+nuts.getkern=direct.getkern
+nuts.getlist=direct.getlist
+nuts.getnext=direct.getnext
+nuts.getoffsets=direct.getoffsets
+nuts.getprev=direct.getprev
+nuts.getsubtype=direct.getsubtype
+nuts.getwidth=direct.getwidth
+nuts.setattr=direct.setfield
+nuts.setboth=direct.setboth
+nuts.setchar=direct.setchar
+nuts.setcomponents=direct.setcomponents
+nuts.setdirection=direct.setdirection
+nuts.setdisc=direct.setdisc
+nuts.setfield=setfield
+nuts.setkern=direct.setkern
+nuts.setlink=direct.setlink
+nuts.setlist=direct.setlist
+nuts.setnext=direct.setnext
+nuts.setoffsets=direct.setoffsets
+nuts.setprev=direct.setprev
+nuts.setsplit=direct.setsplit
+nuts.setsubtype=direct.setsubtype
+nuts.setwidth=direct.setwidth
+nuts.getglyphdata=nuts.getattr
+nuts.setglyphdata=nuts.setattr
+nuts.ischar=direct.is_char
+nuts.isglyph=direct.is_glyph
+nuts.copy=direct.copy
+nuts.copy_list=direct.copy_list
+nuts.copy_node=direct.copy
+nuts.delete=direct.delete
+nuts.end_of_math=direct.end_of_math
+nuts.flush=direct.flush
+nuts.flush_list=direct.flush_list
+nuts.flush_node=direct.flush_node
+nuts.free=direct.free
+nuts.insert_after=direct.insert_after
+nuts.insert_before=direct.insert_before
+nuts.is_node=direct.is_node
+nuts.kerning=direct.kerning
+nuts.ligaturing=direct.ligaturing
+nuts.new=direct.new
+nuts.remove=direct.remove
+nuts.tail=direct.tail
+nuts.traverse=direct.traverse
+nuts.traverse_char=direct.traverse_char
+nuts.traverse_glyph=direct.traverse_glyph
+nuts.traverse_id=direct.traverse_id
+local propertydata=direct.get_properties_table()
+nodes.properties={ data=propertydata }
+if direct.set_properties_mode then
+ direct.set_properties_mode(true,true)
+ function direct.set_properties_mode() end
+end
+nuts.getprop=function(n,k)
+ local p=propertydata[n]
+ if p then
+ return p[k]
+ end
+end
+nuts.setprop=function(n,k,v)
+ if v then
+ local p=propertydata[n]
+ if p then
+ p[k]=v
+ else
+ propertydata[n]={ [k]=v }
+ end
+ end
+end
+nodes.setprop=nodes.setproperty
+nodes.getprop=nodes.getproperty
+local setprev=nuts.setprev
+local setnext=nuts.setnext
+local getnext=nuts.getnext
+local setlink=nuts.setlink
+local getfield=nuts.getfield
+local setfield=nuts.setfield
+local getcomponents=nuts.getcomponents
+local setcomponents=nuts.setcomponents
+local find_tail=nuts.tail
+local flush_list=nuts.flush_list
+local flush_node=nuts.flush_node
+local traverse_id=nuts.traverse_id
+local copy_node=nuts.copy_node
+local glyph_code=nodes.nodecodes.glyph
+function nuts.copy_no_components(g,copyinjection)
+ local components=getcomponents(g)
+ if components then
+ setcomponents(g)
+ local n=copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ setcomponents(g,components)
+ return n
+ else
+ local n=copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ return n
+ end
+end
+function nuts.copy_only_glyphs(current)
+ local head=nil
+ local previous=nil
+ for n in traverse_id(glyph_code,current) do
+ n=copy_node(n)
+ if head then
+ setlink(previous,n)
+ else
+ head=n
+ end
+ previous=n
+ end
+ return head
+end
+nuts.uses_font=direct.uses_font
+do
+ local dummy=tonut(node.new("glyph"))
+ nuts.traversers={
+ glyph=nuts.traverse_id(nodecodes.glyph,dummy),
+ glue=nuts.traverse_id(nodecodes.glue,dummy),
+ disc=nuts.traverse_id(nodecodes.disc,dummy),
+ boundary=nuts.traverse_id(nodecodes.boundary,dummy),
+ char=nuts.traverse_char(dummy),
+ node=nuts.traverse(dummy),
+ }
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+
+characters=characters or {}
+characters.blockrange={}
+characters.classifiers={
+ [768]=5,
+ [769]=5,
+ [770]=5,
+ [771]=5,
+ [772]=5,
+ [773]=5,
+ [774]=5,
+ [775]=5,
+ [776]=5,
+ [777]=5,
+ [778]=5,
+ [779]=5,
+ [780]=5,
+ [781]=5,
+ [782]=5,
+ [783]=5,
+ [784]=5,
+ [785]=5,
+ [786]=5,
+ [787]=5,
+ [788]=5,
+ [789]=5,
+ [790]=5,
+ [791]=5,
+ [792]=5,
+ [793]=5,
+ [794]=5,
+ [795]=5,
+ [796]=5,
+ [797]=5,
+ [798]=5,
+ [799]=5,
+ [800]=5,
+ [801]=5,
+ [802]=5,
+ [803]=5,
+ [804]=5,
+ [805]=5,
+ [806]=5,
+ [807]=5,
+ [808]=5,
+ [809]=5,
+ [810]=5,
+ [811]=5,
+ [812]=5,
+ [813]=5,
+ [814]=5,
+ [815]=5,
+ [816]=5,
+ [817]=5,
+ [818]=5,
+ [819]=5,
+ [820]=5,
+ [821]=5,
+ [822]=5,
+ [823]=5,
+ [824]=5,
+ [825]=5,
+ [826]=5,
+ [827]=5,
+ [828]=5,
+ [829]=5,
+ [830]=5,
+ [831]=5,
+ [832]=5,
+ [833]=5,
+ [834]=5,
+ [835]=5,
+ [836]=5,
+ [837]=5,
+ [838]=5,
+ [839]=5,
+ [840]=5,
+ [841]=5,
+ [842]=5,
+ [843]=5,
+ [844]=5,
+ [845]=5,
+ [846]=5,
+ [847]=5,
+ [848]=5,
+ [849]=5,
+ [850]=5,
+ [851]=5,
+ [852]=5,
+ [853]=5,
+ [854]=5,
+ [855]=5,
+ [856]=5,
+ [857]=5,
+ [858]=5,
+ [859]=5,
+ [860]=5,
+ [861]=5,
+ [862]=5,
+ [863]=5,
+ [864]=5,
+ [865]=5,
+ [866]=5,
+ [867]=5,
+ [868]=5,
+ [869]=5,
+ [870]=5,
+ [871]=5,
+ [872]=5,
+ [873]=5,
+ [874]=5,
+ [875]=5,
+ [876]=5,
+ [877]=5,
+ [878]=5,
+ [879]=5,
+ [1155]=5,
+ [1156]=5,
+ [1157]=5,
+ [1158]=5,
+ [1159]=5,
+ [1425]=5,
+ [1426]=5,
+ [1427]=5,
+ [1428]=5,
+ [1429]=5,
+ [1430]=5,
+ [1431]=5,
+ [1432]=5,
+ [1433]=5,
+ [1434]=5,
+ [1435]=5,
+ [1436]=5,
+ [1437]=5,
+ [1438]=5,
+ [1439]=5,
+ [1440]=5,
+ [1441]=5,
+ [1442]=5,
+ [1443]=5,
+ [1444]=5,
+ [1445]=5,
+ [1446]=5,
+ [1447]=5,
+ [1448]=5,
+ [1449]=5,
+ [1450]=5,
+ [1451]=5,
+ [1452]=5,
+ [1453]=5,
+ [1454]=5,
+ [1455]=5,
+ [1456]=5,
+ [1457]=5,
+ [1458]=5,
+ [1459]=5,
+ [1460]=5,
+ [1461]=5,
+ [1462]=5,
+ [1463]=5,
+ [1464]=5,
+ [1465]=5,
+ [1466]=5,
+ [1467]=5,
+ [1468]=5,
+ [1469]=5,
+ [1471]=5,
+ [1473]=5,
+ [1474]=5,
+ [1476]=5,
+ [1477]=5,
+ [1479]=5,
+ [1536]=4,
+ [1537]=4,
+ [1538]=4,
+ [1539]=4,
+ [1540]=4,
+ [1541]=4,
+ [1542]=6,
+ [1543]=6,
+ [1544]=4,
+ [1545]=6,
+ [1546]=6,
+ [1547]=4,
+ [1548]=6,
+ [1549]=6,
+ [1550]=6,
+ [1551]=6,
+ [1552]=5,
+ [1553]=5,
+ [1554]=5,
+ [1555]=5,
+ [1556]=5,
+ [1557]=5,
+ [1558]=5,
+ [1559]=5,
+ [1560]=5,
+ [1561]=5,
+ [1562]=5,
+ [1563]=6,
+ [1564]=6,
+ [1566]=6,
+ [1567]=6,
+ [1568]=2,
+ [1569]=4,
+ [1570]=3,
+ [1571]=3,
+ [1572]=3,
+ [1573]=3,
+ [1574]=2,
+ [1575]=3,
+ [1576]=2,
+ [1577]=3,
+ [1578]=2,
+ [1579]=2,
+ [1580]=2,
+ [1581]=2,
+ [1582]=2,
+ [1583]=3,
+ [1584]=3,
+ [1585]=3,
+ [1586]=3,
+ [1587]=2,
+ [1588]=2,
+ [1589]=2,
+ [1590]=2,
+ [1591]=2,
+ [1592]=2,
+ [1593]=2,
+ [1594]=2,
+ [1595]=2,
+ [1596]=2,
+ [1597]=2,
+ [1598]=2,
+ [1599]=2,
+ [1600]=2,
+ [1601]=2,
+ [1602]=2,
+ [1603]=2,
+ [1604]=2,
+ [1605]=2,
+ [1606]=2,
+ [1607]=2,
+ [1608]=3,
+ [1609]=2,
+ [1610]=2,
+ [1611]=5,
+ [1612]=5,
+ [1613]=5,
+ [1614]=5,
+ [1615]=5,
+ [1616]=5,
+ [1617]=5,
+ [1618]=5,
+ [1619]=5,
+ [1620]=5,
+ [1621]=5,
+ [1622]=5,
+ [1623]=5,
+ [1624]=5,
+ [1625]=5,
+ [1626]=5,
+ [1627]=5,
+ [1628]=5,
+ [1629]=5,
+ [1630]=5,
+ [1631]=5,
+ [1632]=6,
+ [1633]=6,
+ [1634]=6,
+ [1635]=6,
+ [1636]=6,
+ [1637]=6,
+ [1638]=6,
+ [1639]=6,
+ [1640]=6,
+ [1641]=6,
+ [1642]=6,
+ [1643]=6,
+ [1644]=6,
+ [1645]=6,
+ [1646]=2,
+ [1647]=2,
+ [1648]=5,
+ [1649]=3,
+ [1650]=3,
+ [1651]=3,
+ [1652]=4,
+ [1653]=3,
+ [1654]=3,
+ [1655]=3,
+ [1656]=2,
+ [1657]=2,
+ [1658]=2,
+ [1659]=2,
+ [1660]=2,
+ [1661]=2,
+ [1662]=2,
+ [1663]=2,
+ [1664]=2,
+ [1665]=2,
+ [1666]=2,
+ [1667]=2,
+ [1668]=2,
+ [1669]=2,
+ [1670]=2,
+ [1671]=2,
+ [1672]=3,
+ [1673]=3,
+ [1674]=3,
+ [1675]=3,
+ [1676]=3,
+ [1677]=3,
+ [1678]=3,
+ [1679]=3,
+ [1680]=3,
+ [1681]=3,
+ [1682]=3,
+ [1683]=3,
+ [1684]=3,
+ [1685]=3,
+ [1686]=3,
+ [1687]=3,
+ [1688]=3,
+ [1689]=3,
+ [1690]=2,
+ [1691]=2,
+ [1692]=2,
+ [1693]=2,
+ [1694]=2,
+ [1695]=2,
+ [1696]=2,
+ [1697]=2,
+ [1698]=2,
+ [1699]=2,
+ [1700]=2,
+ [1701]=2,
+ [1702]=2,
+ [1703]=2,
+ [1704]=2,
+ [1705]=2,
+ [1706]=2,
+ [1707]=2,
+ [1708]=2,
+ [1709]=2,
+ [1710]=2,
+ [1711]=2,
+ [1712]=2,
+ [1713]=2,
+ [1714]=2,
+ [1715]=2,
+ [1716]=2,
+ [1717]=2,
+ [1718]=2,
+ [1719]=2,
+ [1720]=2,
+ [1721]=2,
+ [1722]=2,
+ [1723]=2,
+ [1724]=2,
+ [1725]=2,
+ [1726]=2,
+ [1727]=2,
+ [1728]=3,
+ [1729]=2,
+ [1730]=2,
+ [1731]=3,
+ [1732]=3,
+ [1733]=3,
+ [1734]=3,
+ [1735]=3,
+ [1736]=3,
+ [1737]=3,
+ [1738]=3,
+ [1739]=3,
+ [1740]=2,
+ [1741]=3,
+ [1742]=2,
+ [1743]=3,
+ [1744]=2,
+ [1745]=2,
+ [1746]=3,
+ [1747]=3,
+ [1748]=6,
+ [1749]=3,
+ [1750]=5,
+ [1751]=5,
+ [1752]=5,
+ [1753]=5,
+ [1754]=5,
+ [1755]=5,
+ [1756]=5,
+ [1757]=4,
+ [1758]=6,
+ [1759]=5,
+ [1760]=5,
+ [1761]=5,
+ [1762]=5,
+ [1763]=5,
+ [1764]=5,
+ [1765]=6,
+ [1766]=6,
+ [1767]=5,
+ [1768]=5,
+ [1769]=6,
+ [1770]=5,
+ [1771]=5,
+ [1772]=5,
+ [1773]=5,
+ [1774]=3,
+ [1775]=3,
+ [1776]=6,
+ [1777]=6,
+ [1778]=6,
+ [1779]=6,
+ [1780]=6,
+ [1781]=6,
+ [1782]=6,
+ [1783]=6,
+ [1784]=6,
+ [1785]=6,
+ [1786]=2,
+ [1787]=2,
+ [1788]=2,
+ [1789]=6,
+ [1790]=6,
+ [1791]=2,
+ [1792]=6,
+ [1793]=6,
+ [1794]=6,
+ [1795]=6,
+ [1796]=6,
+ [1797]=6,
+ [1798]=6,
+ [1799]=6,
+ [1800]=6,
+ [1801]=6,
+ [1802]=6,
+ [1803]=6,
+ [1804]=6,
+ [1805]=6,
+ [1808]=3,
+ [1809]=5,
+ [1810]=2,
+ [1811]=2,
+ [1812]=2,
+ [1813]=3,
+ [1814]=3,
+ [1815]=3,
+ [1816]=3,
+ [1817]=3,
+ [1818]=2,
+ [1819]=2,
+ [1820]=2,
+ [1821]=2,
+ [1822]=3,
+ [1823]=2,
+ [1824]=2,
+ [1825]=2,
+ [1826]=2,
+ [1827]=2,
+ [1828]=2,
+ [1829]=2,
+ [1830]=2,
+ [1831]=2,
+ [1832]=3,
+ [1833]=2,
+ [1834]=3,
+ [1835]=2,
+ [1836]=3,
+ [1837]=2,
+ [1838]=2,
+ [1839]=3,
+ [1840]=5,
+ [1841]=5,
+ [1842]=5,
+ [1843]=5,
+ [1844]=5,
+ [1845]=5,
+ [1846]=5,
+ [1847]=5,
+ [1848]=5,
+ [1849]=5,
+ [1850]=5,
+ [1851]=5,
+ [1852]=5,
+ [1853]=5,
+ [1854]=5,
+ [1855]=5,
+ [1856]=5,
+ [1857]=5,
+ [1858]=5,
+ [1859]=5,
+ [1860]=5,
+ [1861]=5,
+ [1862]=5,
+ [1863]=5,
+ [1864]=5,
+ [1865]=5,
+ [1866]=5,
+ [1869]=3,
+ [1870]=2,
+ [1871]=2,
+ [1872]=2,
+ [1873]=2,
+ [1874]=2,
+ [1875]=2,
+ [1876]=2,
+ [1877]=2,
+ [1878]=2,
+ [1879]=2,
+ [1880]=2,
+ [1881]=3,
+ [1882]=3,
+ [1883]=3,
+ [1884]=2,
+ [1885]=2,
+ [1886]=2,
+ [1887]=2,
+ [1888]=2,
+ [1889]=2,
+ [1890]=2,
+ [1891]=2,
+ [1892]=2,
+ [1893]=2,
+ [1894]=2,
+ [1895]=2,
+ [1896]=2,
+ [1897]=2,
+ [1898]=2,
+ [1899]=3,
+ [1900]=3,
+ [1901]=2,
+ [1902]=2,
+ [1903]=2,
+ [1904]=2,
+ [1905]=3,
+ [1906]=2,
+ [1907]=3,
+ [1908]=3,
+ [1909]=2,
+ [1910]=2,
+ [1911]=2,
+ [1912]=3,
+ [1913]=3,
+ [1914]=2,
+ [1915]=2,
+ [1916]=2,
+ [1917]=2,
+ [1918]=2,
+ [1919]=2,
+ [1958]=5,
+ [1959]=5,
+ [1960]=5,
+ [1961]=5,
+ [1962]=5,
+ [1963]=5,
+ [1964]=5,
+ [1965]=5,
+ [1966]=5,
+ [1967]=5,
+ [1968]=5,
+ [1984]=6,
+ [1985]=6,
+ [1986]=6,
+ [1987]=6,
+ [1988]=6,
+ [1989]=6,
+ [1990]=6,
+ [1991]=6,
+ [1992]=6,
+ [1993]=6,
+ [1994]=2,
+ [1995]=2,
+ [1996]=2,
+ [1997]=2,
+ [1998]=2,
+ [1999]=2,
+ [2000]=2,
+ [2001]=2,
+ [2002]=2,
+ [2003]=2,
+ [2004]=2,
+ [2005]=2,
+ [2006]=2,
+ [2007]=2,
+ [2008]=2,
+ [2009]=2,
+ [2010]=2,
+ [2011]=2,
+ [2012]=2,
+ [2013]=2,
+ [2014]=2,
+ [2015]=2,
+ [2016]=2,
+ [2017]=2,
+ [2018]=2,
+ [2019]=2,
+ [2020]=2,
+ [2021]=2,
+ [2022]=2,
+ [2023]=2,
+ [2024]=2,
+ [2025]=2,
+ [2026]=2,
+ [2027]=5,
+ [2028]=5,
+ [2029]=5,
+ [2030]=5,
+ [2031]=5,
+ [2032]=5,
+ [2033]=5,
+ [2034]=5,
+ [2035]=5,
+ [2036]=6,
+ [2037]=6,
+ [2038]=6,
+ [2039]=6,
+ [2040]=6,
+ [2041]=6,
+ [2042]=2,
+ [2045]=5,
+ [2046]=6,
+ [2047]=6,
+ [2070]=5,
+ [2071]=5,
+ [2072]=5,
+ [2073]=5,
+ [2075]=5,
+ [2076]=5,
+ [2077]=5,
+ [2078]=5,
+ [2079]=5,
+ [2080]=5,
+ [2081]=5,
+ [2082]=5,
+ [2083]=5,
+ [2085]=5,
+ [2086]=5,
+ [2087]=5,
+ [2089]=5,
+ [2090]=5,
+ [2091]=5,
+ [2092]=5,
+ [2093]=5,
+ [2112]=3,
+ [2113]=2,
+ [2114]=2,
+ [2115]=2,
+ [2116]=2,
+ [2117]=2,
+ [2118]=3,
+ [2119]=3,
+ [2120]=2,
+ [2121]=3,
+ [2122]=2,
+ [2123]=2,
+ [2124]=2,
+ [2125]=2,
+ [2126]=2,
+ [2127]=2,
+ [2128]=2,
+ [2129]=2,
+ [2130]=2,
+ [2131]=2,
+ [2132]=3,
+ [2133]=2,
+ [2134]=4,
+ [2135]=4,
+ [2136]=4,
+ [2137]=5,
+ [2138]=5,
+ [2139]=5,
+ [2144]=2,
+ [2145]=4,
+ [2146]=2,
+ [2147]=2,
+ [2148]=2,
+ [2149]=2,
+ [2150]=4,
+ [2151]=3,
+ [2152]=2,
+ [2153]=3,
+ [2154]=3,
+ [2208]=2,
+ [2209]=2,
+ [2210]=2,
+ [2211]=2,
+ [2212]=2,
+ [2213]=2,
+ [2214]=2,
+ [2215]=2,
+ [2216]=2,
+ [2217]=2,
+ [2218]=3,
+ [2219]=3,
+ [2220]=3,
+ [2221]=4,
+ [2222]=3,
+ [2223]=2,
+ [2224]=2,
+ [2225]=3,
+ [2226]=3,
+ [2227]=2,
+ [2228]=2,
+ [2230]=2,
+ [2231]=2,
+ [2232]=2,
+ [2233]=3,
+ [2234]=2,
+ [2235]=2,
+ [2236]=2,
+ [2237]=2,
+ [2259]=5,
+ [2260]=5,
+ [2261]=5,
+ [2262]=5,
+ [2263]=5,
+ [2264]=5,
+ [2265]=5,
+ [2266]=5,
+ [2267]=5,
+ [2268]=5,
+ [2269]=5,
+ [2270]=5,
+ [2271]=5,
+ [2272]=5,
+ [2273]=5,
+ [2274]=4,
+ [2275]=5,
+ [2276]=5,
+ [2277]=5,
+ [2278]=5,
+ [2279]=5,
+ [2280]=5,
+ [2281]=5,
+ [2282]=5,
+ [2283]=5,
+ [2284]=5,
+ [2285]=5,
+ [2286]=5,
+ [2287]=5,
+ [2288]=5,
+ [2289]=5,
+ [2290]=5,
+ [2291]=5,
+ [2292]=5,
+ [2293]=5,
+ [2294]=5,
+ [2295]=5,
+ [2296]=5,
+ [2297]=5,
+ [2298]=5,
+ [2299]=5,
+ [2300]=5,
+ [2301]=5,
+ [2302]=5,
+ [2303]=5,
+ [2304]=5,
+ [2305]=5,
+ [2306]=5,
+ [2362]=5,
+ [2364]=5,
+ [2369]=5,
+ [2370]=5,
+ [2371]=5,
+ [2372]=5,
+ [2373]=5,
+ [2374]=5,
+ [2375]=5,
+ [2376]=5,
+ [2381]=5,
+ [2385]=5,
+ [2386]=5,
+ [2387]=5,
+ [2388]=5,
+ [2389]=5,
+ [2390]=5,
+ [2391]=5,
+ [2402]=5,
+ [2403]=5,
+ [2433]=5,
+ [2492]=5,
+ [2497]=5,
+ [2498]=5,
+ [2499]=5,
+ [2500]=5,
+ [2509]=5,
+ [2530]=5,
+ [2531]=5,
+ [2558]=5,
+ [2561]=5,
+ [2562]=5,
+ [2620]=5,
+ [2625]=5,
+ [2626]=5,
+ [2631]=5,
+ [2632]=5,
+ [2635]=5,
+ [2636]=5,
+ [2637]=5,
+ [2641]=5,
+ [2672]=5,
+ [2673]=5,
+ [2677]=5,
+ [2689]=5,
+ [2690]=5,
+ [2748]=5,
+ [2753]=5,
+ [2754]=5,
+ [2755]=5,
+ [2756]=5,
+ [2757]=5,
+ [2759]=5,
+ [2760]=5,
+ [2765]=5,
+ [2786]=5,
+ [2787]=5,
+ [2810]=5,
+ [2811]=5,
+ [2812]=5,
+ [2813]=5,
+ [2814]=5,
+ [2815]=5,
+ [2817]=5,
+ [2876]=5,
+ [2879]=5,
+ [2881]=5,
+ [2882]=5,
+ [2883]=5,
+ [2884]=5,
+ [2893]=5,
+ [2902]=5,
+ [2914]=5,
+ [2915]=5,
+ [2946]=5,
+ [3008]=5,
+ [3021]=5,
+ [3072]=5,
+ [3076]=5,
+ [3134]=5,
+ [3135]=5,
+ [3136]=5,
+ [3142]=5,
+ [3143]=5,
+ [3144]=5,
+ [3146]=5,
+ [3147]=5,
+ [3148]=5,
+ [3149]=5,
+ [3157]=5,
+ [3158]=5,
+ [3170]=5,
+ [3171]=5,
+ [3201]=5,
+ [3260]=5,
+ [3263]=5,
+ [3270]=5,
+ [3276]=5,
+ [3277]=5,
+ [3298]=5,
+ [3299]=5,
+ [3328]=5,
+ [3329]=5,
+ [3387]=5,
+ [3388]=5,
+ [3393]=5,
+ [3394]=5,
+ [3395]=5,
+ [3396]=5,
+ [3405]=5,
+ [3426]=5,
+ [3427]=5,
+ [3530]=5,
+ [3538]=5,
+ [3539]=5,
+ [3540]=5,
+ [3542]=5,
+ [3633]=5,
+ [3636]=5,
+ [3637]=5,
+ [3638]=5,
+ [3639]=5,
+ [3640]=5,
+ [3641]=5,
+ [3642]=5,
+ [3655]=5,
+ [3656]=5,
+ [3657]=5,
+ [3658]=5,
+ [3659]=5,
+ [3660]=5,
+ [3661]=5,
+ [3662]=5,
+ [3761]=5,
+ [3764]=5,
+ [3765]=5,
+ [3766]=5,
+ [3767]=5,
+ [3768]=5,
+ [3769]=5,
+ [3770]=5,
+ [3771]=5,
+ [3772]=5,
+ [3784]=5,
+ [3785]=5,
+ [3786]=5,
+ [3787]=5,
+ [3788]=5,
+ [3789]=5,
+ [3864]=5,
+ [3865]=5,
+ [3893]=5,
+ [3895]=5,
+ [3897]=5,
+ [3953]=5,
+ [3954]=5,
+ [3955]=5,
+ [3956]=5,
+ [3957]=5,
+ [3958]=5,
+ [3959]=5,
+ [3960]=5,
+ [3961]=5,
+ [3962]=5,
+ [3963]=5,
+ [3964]=5,
+ [3965]=5,
+ [3966]=5,
+ [3968]=5,
+ [3969]=5,
+ [3970]=5,
+ [3971]=5,
+ [3972]=5,
+ [3974]=5,
+ [3975]=5,
+ [3981]=5,
+ [3982]=5,
+ [3983]=5,
+ [3984]=5,
+ [3985]=5,
+ [3986]=5,
+ [3987]=5,
+ [3988]=5,
+ [3989]=5,
+ [3990]=5,
+ [3991]=5,
+ [3993]=5,
+ [3994]=5,
+ [3995]=5,
+ [3996]=5,
+ [3997]=5,
+ [3998]=5,
+ [3999]=5,
+ [4000]=5,
+ [4001]=5,
+ [4002]=5,
+ [4003]=5,
+ [4004]=5,
+ [4005]=5,
+ [4006]=5,
+ [4007]=5,
+ [4008]=5,
+ [4009]=5,
+ [4010]=5,
+ [4011]=5,
+ [4012]=5,
+ [4013]=5,
+ [4014]=5,
+ [4015]=5,
+ [4016]=5,
+ [4017]=5,
+ [4018]=5,
+ [4019]=5,
+ [4020]=5,
+ [4021]=5,
+ [4022]=5,
+ [4023]=5,
+ [4024]=5,
+ [4025]=5,
+ [4026]=5,
+ [4027]=5,
+ [4028]=5,
+ [4038]=5,
+ [4141]=5,
+ [4142]=5,
+ [4143]=5,
+ [4144]=5,
+ [4146]=5,
+ [4147]=5,
+ [4148]=5,
+ [4149]=5,
+ [4150]=5,
+ [4151]=5,
+ [4153]=5,
+ [4154]=5,
+ [4157]=5,
+ [4158]=5,
+ [4184]=5,
+ [4185]=5,
+ [4190]=5,
+ [4191]=5,
+ [4192]=5,
+ [4209]=5,
+ [4210]=5,
+ [4211]=5,
+ [4212]=5,
+ [4226]=5,
+ [4229]=5,
+ [4230]=5,
+ [4237]=5,
+ [4253]=5,
+ [4957]=5,
+ [4958]=5,
+ [4959]=5,
+ [5906]=5,
+ [5907]=5,
+ [5908]=5,
+ [5938]=5,
+ [5939]=5,
+ [5940]=5,
+ [5970]=5,
+ [5971]=5,
+ [6002]=5,
+ [6003]=5,
+ [6071]=5,
+ [6072]=5,
+ [6073]=5,
+ [6074]=5,
+ [6075]=5,
+ [6076]=5,
+ [6077]=5,
+ [6086]=5,
+ [6089]=5,
+ [6090]=5,
+ [6091]=5,
+ [6092]=5,
+ [6093]=5,
+ [6094]=5,
+ [6095]=5,
+ [6096]=5,
+ [6097]=5,
+ [6098]=5,
+ [6099]=5,
+ [6109]=5,
+ [6150]=4,
+ [6151]=2,
+ [6154]=2,
+ [6155]=5,
+ [6156]=5,
+ [6157]=5,
+ [6158]=4,
+ [6176]=2,
+ [6177]=2,
+ [6178]=2,
+ [6179]=2,
+ [6180]=2,
+ [6181]=2,
+ [6182]=2,
+ [6183]=2,
+ [6184]=2,
+ [6185]=2,
+ [6186]=2,
+ [6187]=2,
+ [6188]=2,
+ [6189]=2,
+ [6190]=2,
+ [6191]=2,
+ [6192]=2,
+ [6193]=2,
+ [6194]=2,
+ [6195]=2,
+ [6196]=2,
+ [6197]=2,
+ [6198]=2,
+ [6199]=2,
+ [6200]=2,
+ [6201]=2,
+ [6202]=2,
+ [6203]=2,
+ [6204]=2,
+ [6205]=2,
+ [6206]=2,
+ [6207]=2,
+ [6208]=2,
+ [6209]=2,
+ [6210]=2,
+ [6211]=2,
+ [6212]=2,
+ [6213]=2,
+ [6214]=2,
+ [6215]=2,
+ [6216]=2,
+ [6217]=2,
+ [6218]=2,
+ [6219]=2,
+ [6220]=2,
+ [6221]=2,
+ [6222]=2,
+ [6223]=2,
+ [6224]=2,
+ [6225]=2,
+ [6226]=2,
+ [6227]=2,
+ [6228]=2,
+ [6229]=2,
+ [6230]=2,
+ [6231]=2,
+ [6232]=2,
+ [6233]=2,
+ [6234]=2,
+ [6235]=2,
+ [6236]=2,
+ [6237]=2,
+ [6238]=2,
+ [6239]=2,
+ [6240]=2,
+ [6241]=2,
+ [6242]=2,
+ [6243]=2,
+ [6244]=2,
+ [6245]=2,
+ [6246]=2,
+ [6247]=2,
+ [6248]=2,
+ [6249]=2,
+ [6250]=2,
+ [6251]=2,
+ [6252]=2,
+ [6253]=2,
+ [6254]=2,
+ [6255]=2,
+ [6256]=2,
+ [6257]=2,
+ [6258]=2,
+ [6259]=2,
+ [6260]=2,
+ [6261]=2,
+ [6262]=2,
+ [6263]=2,
+ [6264]=2,
+ [6272]=4,
+ [6273]=4,
+ [6274]=4,
+ [6275]=4,
+ [6276]=4,
+ [6279]=2,
+ [6280]=2,
+ [6281]=2,
+ [6282]=2,
+ [6283]=2,
+ [6284]=2,
+ [6285]=2,
+ [6286]=2,
+ [6287]=2,
+ [6288]=2,
+ [6289]=2,
+ [6290]=2,
+ [6291]=2,
+ [6292]=2,
+ [6293]=2,
+ [6294]=2,
+ [6295]=2,
+ [6296]=2,
+ [6297]=2,
+ [6298]=2,
+ [6299]=2,
+ [6300]=2,
+ [6301]=2,
+ [6302]=2,
+ [6303]=2,
+ [6304]=2,
+ [6305]=2,
+ [6306]=2,
+ [6307]=2,
+ [6308]=2,
+ [6309]=2,
+ [6310]=2,
+ [6311]=2,
+ [6312]=2,
+ [6313]=5,
+ [6314]=2,
+ [6432]=5,
+ [6433]=5,
+ [6434]=5,
+ [6439]=5,
+ [6440]=5,
+ [6450]=5,
+ [6457]=5,
+ [6458]=5,
+ [6459]=5,
+ [6679]=5,
+ [6680]=5,
+ [6742]=5,
+ [6744]=5,
+ [6745]=5,
+ [6746]=5,
+ [6747]=5,
+ [6748]=5,
+ [6749]=5,
+ [6750]=5,
+ [6752]=5,
+ [6754]=5,
+ [6757]=5,
+ [6758]=5,
+ [6759]=5,
+ [6760]=5,
+ [6761]=5,
+ [6762]=5,
+ [6763]=5,
+ [6764]=5,
+ [6771]=5,
+ [6772]=5,
+ [6773]=5,
+ [6774]=5,
+ [6775]=5,
+ [6776]=5,
+ [6777]=5,
+ [6778]=5,
+ [6779]=5,
+ [6780]=5,
+ [6783]=5,
+ [6832]=5,
+ [6833]=5,
+ [6834]=5,
+ [6835]=5,
+ [6836]=5,
+ [6837]=5,
+ [6838]=5,
+ [6839]=5,
+ [6840]=5,
+ [6841]=5,
+ [6842]=5,
+ [6843]=5,
+ [6844]=5,
+ [6845]=5,
+ [6912]=5,
+ [6913]=5,
+ [6914]=5,
+ [6915]=5,
+ [6964]=5,
+ [6966]=5,
+ [6967]=5,
+ [6968]=5,
+ [6969]=5,
+ [6970]=5,
+ [6972]=5,
+ [6978]=5,
+ [7019]=5,
+ [7020]=5,
+ [7021]=5,
+ [7022]=5,
+ [7023]=5,
+ [7024]=5,
+ [7025]=5,
+ [7026]=5,
+ [7027]=5,
+ [7040]=5,
+ [7041]=5,
+ [7074]=5,
+ [7075]=5,
+ [7076]=5,
+ [7077]=5,
+ [7080]=5,
+ [7081]=5,
+ [7083]=5,
+ [7142]=5,
+ [7144]=5,
+ [7145]=5,
+ [7149]=5,
+ [7151]=5,
+ [7152]=5,
+ [7153]=5,
+ [7212]=5,
+ [7213]=5,
+ [7214]=5,
+ [7215]=5,
+ [7216]=5,
+ [7217]=5,
+ [7218]=5,
+ [7219]=5,
+ [7222]=5,
+ [7223]=5,
+ [7376]=5,
+ [7377]=5,
+ [7378]=5,
+ [7380]=5,
+ [7381]=5,
+ [7382]=5,
+ [7383]=5,
+ [7384]=5,
+ [7385]=5,
+ [7386]=5,
+ [7387]=5,
+ [7388]=5,
+ [7389]=5,
+ [7390]=5,
+ [7391]=5,
+ [7392]=5,
+ [7394]=5,
+ [7395]=5,
+ [7396]=5,
+ [7397]=5,
+ [7398]=5,
+ [7399]=5,
+ [7400]=5,
+ [7405]=5,
+ [7412]=5,
+ [7416]=5,
+ [7417]=5,
+ [7616]=5,
+ [7617]=5,
+ [7618]=5,
+ [7619]=5,
+ [7620]=5,
+ [7621]=5,
+ [7622]=5,
+ [7623]=5,
+ [7624]=5,
+ [7625]=5,
+ [7626]=5,
+ [7627]=5,
+ [7628]=5,
+ [7629]=5,
+ [7630]=5,
+ [7631]=5,
+ [7632]=5,
+ [7633]=5,
+ [7634]=5,
+ [7635]=5,
+ [7636]=5,
+ [7637]=5,
+ [7638]=5,
+ [7639]=5,
+ [7640]=5,
+ [7641]=5,
+ [7642]=5,
+ [7643]=5,
+ [7644]=5,
+ [7645]=5,
+ [7646]=5,
+ [7647]=5,
+ [7648]=5,
+ [7649]=5,
+ [7650]=5,
+ [7651]=5,
+ [7652]=5,
+ [7653]=5,
+ [7654]=5,
+ [7655]=5,
+ [7656]=5,
+ [7657]=5,
+ [7658]=5,
+ [7659]=5,
+ [7660]=5,
+ [7661]=5,
+ [7662]=5,
+ [7663]=5,
+ [7664]=5,
+ [7665]=5,
+ [7666]=5,
+ [7667]=5,
+ [7668]=5,
+ [7669]=5,
+ [7670]=5,
+ [7671]=5,
+ [7672]=5,
+ [7673]=5,
+ [7675]=5,
+ [7676]=5,
+ [7677]=5,
+ [7678]=5,
+ [7679]=5,
+ [8204]=4,
+ [8205]=2,
+ [8239]=4,
+ [8294]=4,
+ [8295]=4,
+ [8296]=4,
+ [8297]=4,
+ [8400]=5,
+ [8401]=5,
+ [8402]=5,
+ [8403]=5,
+ [8404]=5,
+ [8405]=5,
+ [8406]=5,
+ [8407]=5,
+ [8408]=5,
+ [8409]=5,
+ [8410]=5,
+ [8411]=5,
+ [8412]=5,
+ [8417]=5,
+ [8421]=5,
+ [8422]=5,
+ [8423]=5,
+ [8424]=5,
+ [8425]=5,
+ [8426]=5,
+ [8427]=5,
+ [8428]=5,
+ [8429]=5,
+ [8430]=5,
+ [8431]=5,
+ [8432]=5,
+ [11503]=5,
+ [11504]=5,
+ [11505]=5,
+ [11647]=5,
+ [11744]=5,
+ [11745]=5,
+ [11746]=5,
+ [11747]=5,
+ [11748]=5,
+ [11749]=5,
+ [11750]=5,
+ [11751]=5,
+ [11752]=5,
+ [11753]=5,
+ [11754]=5,
+ [11755]=5,
+ [11756]=5,
+ [11757]=5,
+ [11758]=5,
+ [11759]=5,
+ [11760]=5,
+ [11761]=5,
+ [11762]=5,
+ [11763]=5,
+ [11764]=5,
+ [11765]=5,
+ [11766]=5,
+ [11767]=5,
+ [11768]=5,
+ [11769]=5,
+ [11770]=5,
+ [11771]=5,
+ [11772]=5,
+ [11773]=5,
+ [11774]=5,
+ [11775]=5,
+ [12330]=5,
+ [12331]=5,
+ [12332]=5,
+ [12333]=5,
+ [12334]=5,
+ [12335]=5,
+ [12441]=5,
+ [12442]=5,
+ [42607]=5,
+ [42612]=5,
+ [42613]=5,
+ [42614]=5,
+ [42615]=5,
+ [42616]=5,
+ [42617]=5,
+ [42618]=5,
+ [42619]=5,
+ [42620]=5,
+ [42621]=5,
+ [42654]=5,
+ [42655]=5,
+ [42736]=5,
+ [42737]=5,
+ [43014]=5,
+ [43019]=5,
+ [43045]=5,
+ [43046]=5,
+ [43072]=2,
+ [43073]=2,
+ [43074]=2,
+ [43075]=2,
+ [43076]=2,
+ [43077]=2,
+ [43078]=2,
+ [43079]=2,
+ [43080]=2,
+ [43081]=2,
+ [43082]=2,
+ [43083]=2,
+ [43084]=2,
+ [43085]=2,
+ [43086]=2,
+ [43087]=2,
+ [43088]=2,
+ [43089]=2,
+ [43090]=2,
+ [43091]=2,
+ [43092]=2,
+ [43093]=2,
+ [43094]=2,
+ [43095]=2,
+ [43096]=2,
+ [43097]=2,
+ [43098]=2,
+ [43099]=2,
+ [43100]=2,
+ [43101]=2,
+ [43102]=2,
+ [43103]=2,
+ [43104]=2,
+ [43105]=2,
+ [43106]=2,
+ [43107]=2,
+ [43108]=2,
+ [43109]=2,
+ [43110]=2,
+ [43111]=2,
+ [43112]=2,
+ [43113]=2,
+ [43114]=2,
+ [43115]=2,
+ [43116]=2,
+ [43117]=2,
+ [43118]=2,
+ [43119]=2,
+ [43120]=2,
+ [43121]=2,
+ [43122]=1,
+ [43123]=4,
+ [43204]=5,
+ [43205]=5,
+ [43232]=5,
+ [43233]=5,
+ [43234]=5,
+ [43235]=5,
+ [43236]=5,
+ [43237]=5,
+ [43238]=5,
+ [43239]=5,
+ [43240]=5,
+ [43241]=5,
+ [43242]=5,
+ [43243]=5,
+ [43244]=5,
+ [43245]=5,
+ [43246]=5,
+ [43247]=5,
+ [43248]=5,
+ [43249]=5,
+ [43263]=5,
+ [43302]=5,
+ [43303]=5,
+ [43304]=5,
+ [43305]=5,
+ [43306]=5,
+ [43307]=5,
+ [43308]=5,
+ [43309]=5,
+ [43335]=5,
+ [43336]=5,
+ [43337]=5,
+ [43338]=5,
+ [43339]=5,
+ [43340]=5,
+ [43341]=5,
+ [43342]=5,
+ [43343]=5,
+ [43344]=5,
+ [43345]=5,
+ [43392]=5,
+ [43393]=5,
+ [43394]=5,
+ [43443]=5,
+ [43446]=5,
+ [43447]=5,
+ [43448]=5,
+ [43449]=5,
+ [43452]=5,
+ [43493]=5,
+ [43561]=5,
+ [43562]=5,
+ [43563]=5,
+ [43564]=5,
+ [43565]=5,
+ [43566]=5,
+ [43569]=5,
+ [43570]=5,
+ [43573]=5,
+ [43574]=5,
+ [43587]=5,
+ [43596]=5,
+ [43644]=5,
+ [43696]=5,
+ [43698]=5,
+ [43699]=5,
+ [43700]=5,
+ [43703]=5,
+ [43704]=5,
+ [43710]=5,
+ [43711]=5,
+ [43713]=5,
+ [43756]=5,
+ [43757]=5,
+ [43766]=5,
+ [44005]=5,
+ [44008]=5,
+ [44013]=5,
+ [64286]=5,
+ [65056]=5,
+ [65057]=5,
+ [65058]=5,
+ [65059]=5,
+ [65060]=5,
+ [65061]=5,
+ [65062]=5,
+ [65063]=5,
+ [65064]=5,
+ [65065]=5,
+ [65066]=5,
+ [65067]=5,
+ [65068]=5,
+ [65069]=5,
+ [65070]=5,
+ [65071]=5,
+ [66045]=5,
+ [66272]=5,
+ [66422]=5,
+ [66423]=5,
+ [66424]=5,
+ [66425]=5,
+ [66426]=5,
+ [68097]=5,
+ [68098]=5,
+ [68099]=5,
+ [68101]=5,
+ [68102]=5,
+ [68108]=5,
+ [68109]=5,
+ [68110]=5,
+ [68111]=5,
+ [68152]=5,
+ [68153]=5,
+ [68154]=5,
+ [68159]=5,
+ [68288]=2,
+ [68289]=2,
+ [68290]=2,
+ [68291]=2,
+ [68292]=2,
+ [68293]=3,
+ [68294]=4,
+ [68295]=3,
+ [68296]=4,
+ [68297]=3,
+ [68298]=3,
+ [68299]=4,
+ [68300]=4,
+ [68301]=1,
+ [68302]=3,
+ [68303]=3,
+ [68304]=3,
+ [68305]=3,
+ [68306]=3,
+ [68307]=2,
+ [68308]=2,
+ [68309]=2,
+ [68310]=2,
+ [68311]=1,
+ [68312]=2,
+ [68313]=2,
+ [68314]=2,
+ [68315]=2,
+ [68316]=2,
+ [68317]=3,
+ [68318]=2,
+ [68319]=2,
+ [68320]=2,
+ [68321]=3,
+ [68322]=4,
+ [68323]=4,
+ [68324]=3,
+ [68325]=5,
+ [68326]=5,
+ [68331]=2,
+ [68332]=2,
+ [68333]=2,
+ [68334]=2,
+ [68335]=3,
+ [68480]=2,
+ [68481]=3,
+ [68482]=2,
+ [68483]=3,
+ [68484]=3,
+ [68485]=3,
+ [68486]=2,
+ [68487]=2,
+ [68488]=2,
+ [68489]=3,
+ [68490]=2,
+ [68491]=2,
+ [68492]=3,
+ [68493]=2,
+ [68494]=3,
+ [68495]=3,
+ [68496]=2,
+ [68497]=3,
+ [68521]=3,
+ [68522]=3,
+ [68523]=3,
+ [68524]=3,
+ [68525]=2,
+ [68526]=2,
+ [68527]=4,
+ [68864]=1,
+ [68865]=2,
+ [68866]=2,
+ [68867]=2,
+ [68868]=2,
+ [68869]=2,
+ [68870]=2,
+ [68871]=2,
+ [68872]=2,
+ [68873]=2,
+ [68874]=2,
+ [68875]=2,
+ [68876]=2,
+ [68877]=2,
+ [68878]=2,
+ [68879]=2,
+ [68880]=2,
+ [68881]=2,
+ [68882]=2,
+ [68883]=2,
+ [68884]=2,
+ [68885]=2,
+ [68886]=2,
+ [68887]=2,
+ [68888]=2,
+ [68889]=2,
+ [68890]=2,
+ [68891]=2,
+ [68892]=2,
+ [68893]=2,
+ [68894]=2,
+ [68895]=2,
+ [68896]=2,
+ [68897]=2,
+ [68898]=3,
+ [68899]=2,
+ [68900]=5,
+ [68901]=5,
+ [68902]=5,
+ [68903]=5,
+ [69424]=2,
+ [69425]=2,
+ [69426]=2,
+ [69427]=3,
+ [69428]=2,
+ [69429]=2,
+ [69430]=2,
+ [69431]=2,
+ [69432]=2,
+ [69433]=2,
+ [69434]=2,
+ [69435]=2,
+ [69436]=2,
+ [69437]=2,
+ [69438]=2,
+ [69439]=2,
+ [69440]=2,
+ [69441]=2,
+ [69442]=2,
+ [69443]=2,
+ [69444]=2,
+ [69445]=4,
+ [69446]=5,
+ [69447]=5,
+ [69448]=5,
+ [69449]=5,
+ [69450]=5,
+ [69451]=5,
+ [69452]=5,
+ [69453]=5,
+ [69454]=5,
+ [69455]=5,
+ [69456]=5,
+ [69457]=2,
+ [69458]=2,
+ [69459]=2,
+ [69460]=3,
+ [69633]=5,
+ [69688]=5,
+ [69689]=5,
+ [69690]=5,
+ [69691]=5,
+ [69692]=5,
+ [69693]=5,
+ [69694]=5,
+ [69695]=5,
+ [69696]=5,
+ [69697]=5,
+ [69698]=5,
+ [69699]=5,
+ [69700]=5,
+ [69701]=5,
+ [69702]=5,
+ [69759]=5,
+ [69760]=5,
+ [69761]=5,
+ [69811]=5,
+ [69812]=5,
+ [69813]=5,
+ [69814]=5,
+ [69817]=5,
+ [69818]=5,
+ [69821]=4,
+ [69837]=4,
+ [69888]=5,
+ [69889]=5,
+ [69890]=5,
+ [69927]=5,
+ [69928]=5,
+ [69929]=5,
+ [69930]=5,
+ [69931]=5,
+ [69933]=5,
+ [69934]=5,
+ [69935]=5,
+ [69936]=5,
+ [69937]=5,
+ [69938]=5,
+ [69939]=5,
+ [69940]=5,
+ [70003]=5,
+ [70016]=5,
+ [70017]=5,
+ [70070]=5,
+ [70071]=5,
+ [70072]=5,
+ [70073]=5,
+ [70074]=5,
+ [70075]=5,
+ [70076]=5,
+ [70077]=5,
+ [70078]=5,
+ [70090]=5,
+ [70091]=5,
+ [70092]=5,
+ [70191]=5,
+ [70192]=5,
+ [70193]=5,
+ [70196]=5,
+ [70198]=5,
+ [70199]=5,
+ [70206]=5,
+ [70367]=5,
+ [70371]=5,
+ [70372]=5,
+ [70373]=5,
+ [70374]=5,
+ [70375]=5,
+ [70376]=5,
+ [70377]=5,
+ [70378]=5,
+ [70400]=5,
+ [70401]=5,
+ [70459]=5,
+ [70460]=5,
+ [70464]=5,
+ [70502]=5,
+ [70503]=5,
+ [70504]=5,
+ [70505]=5,
+ [70506]=5,
+ [70507]=5,
+ [70508]=5,
+ [70512]=5,
+ [70513]=5,
+ [70514]=5,
+ [70515]=5,
+ [70516]=5,
+ [70712]=5,
+ [70713]=5,
+ [70714]=5,
+ [70715]=5,
+ [70716]=5,
+ [70717]=5,
+ [70718]=5,
+ [70719]=5,
+ [70722]=5,
+ [70723]=5,
+ [70724]=5,
+ [70726]=5,
+ [70750]=5,
+ [70835]=5,
+ [70836]=5,
+ [70837]=5,
+ [70838]=5,
+ [70839]=5,
+ [70840]=5,
+ [70842]=5,
+ [70847]=5,
+ [70848]=5,
+ [70850]=5,
+ [70851]=5,
+ [71090]=5,
+ [71091]=5,
+ [71092]=5,
+ [71093]=5,
+ [71100]=5,
+ [71101]=5,
+ [71103]=5,
+ [71104]=5,
+ [71132]=5,
+ [71133]=5,
+ [71219]=5,
+ [71220]=5,
+ [71221]=5,
+ [71222]=5,
+ [71223]=5,
+ [71224]=5,
+ [71225]=5,
+ [71226]=5,
+ [71229]=5,
+ [71231]=5,
+ [71232]=5,
+ [71339]=5,
+ [71341]=5,
+ [71344]=5,
+ [71345]=5,
+ [71346]=5,
+ [71347]=5,
+ [71348]=5,
+ [71349]=5,
+ [71351]=5,
+ [71453]=5,
+ [71454]=5,
+ [71455]=5,
+ [71458]=5,
+ [71459]=5,
+ [71460]=5,
+ [71461]=5,
+ [71463]=5,
+ [71464]=5,
+ [71465]=5,
+ [71466]=5,
+ [71467]=5,
+ [71727]=5,
+ [71728]=5,
+ [71729]=5,
+ [71730]=5,
+ [71731]=5,
+ [71732]=5,
+ [71733]=5,
+ [71734]=5,
+ [71735]=5,
+ [71737]=5,
+ [71738]=5,
+ [72148]=5,
+ [72149]=5,
+ [72150]=5,
+ [72151]=5,
+ [72154]=5,
+ [72155]=5,
+ [72160]=5,
+ [72193]=5,
+ [72194]=5,
+ [72195]=5,
+ [72196]=5,
+ [72197]=5,
+ [72198]=5,
+ [72201]=5,
+ [72202]=5,
+ [72243]=5,
+ [72244]=5,
+ [72245]=5,
+ [72246]=5,
+ [72247]=5,
+ [72248]=5,
+ [72251]=5,
+ [72252]=5,
+ [72253]=5,
+ [72254]=5,
+ [72263]=5,
+ [72273]=5,
+ [72274]=5,
+ [72275]=5,
+ [72276]=5,
+ [72277]=5,
+ [72278]=5,
+ [72281]=5,
+ [72282]=5,
+ [72283]=5,
+ [72330]=5,
+ [72331]=5,
+ [72332]=5,
+ [72333]=5,
+ [72334]=5,
+ [72335]=5,
+ [72336]=5,
+ [72337]=5,
+ [72338]=5,
+ [72339]=5,
+ [72340]=5,
+ [72341]=5,
+ [72342]=5,
+ [72344]=5,
+ [72345]=5,
+ [72752]=5,
+ [72753]=5,
+ [72754]=5,
+ [72755]=5,
+ [72756]=5,
+ [72757]=5,
+ [72758]=5,
+ [72760]=5,
+ [72761]=5,
+ [72762]=5,
+ [72763]=5,
+ [72764]=5,
+ [72765]=5,
+ [72767]=5,
+ [72850]=5,
+ [72851]=5,
+ [72852]=5,
+ [72853]=5,
+ [72854]=5,
+ [72855]=5,
+ [72856]=5,
+ [72857]=5,
+ [72858]=5,
+ [72859]=5,
+ [72860]=5,
+ [72861]=5,
+ [72862]=5,
+ [72863]=5,
+ [72864]=5,
+ [72865]=5,
+ [72866]=5,
+ [72867]=5,
+ [72868]=5,
+ [72869]=5,
+ [72870]=5,
+ [72871]=5,
+ [72874]=5,
+ [72875]=5,
+ [72876]=5,
+ [72877]=5,
+ [72878]=5,
+ [72879]=5,
+ [72880]=5,
+ [72882]=5,
+ [72883]=5,
+ [72885]=5,
+ [72886]=5,
+ [73009]=5,
+ [73010]=5,
+ [73011]=5,
+ [73012]=5,
+ [73013]=5,
+ [73014]=5,
+ [73018]=5,
+ [73020]=5,
+ [73021]=5,
+ [73023]=5,
+ [73024]=5,
+ [73025]=5,
+ [73026]=5,
+ [73027]=5,
+ [73028]=5,
+ [73029]=5,
+ [73031]=5,
+ [73104]=5,
+ [73105]=5,
+ [73109]=5,
+ [73111]=5,
+ [73459]=5,
+ [73460]=5,
+ [92912]=5,
+ [92913]=5,
+ [92914]=5,
+ [92915]=5,
+ [92916]=5,
+ [92976]=5,
+ [92977]=5,
+ [92978]=5,
+ [92979]=5,
+ [92980]=5,
+ [92981]=5,
+ [92982]=5,
+ [94031]=5,
+ [94095]=5,
+ [94096]=5,
+ [94097]=5,
+ [94098]=5,
+ [113821]=5,
+ [113822]=5,
+ [119143]=5,
+ [119144]=5,
+ [119145]=5,
+ [119163]=5,
+ [119164]=5,
+ [119165]=5,
+ [119166]=5,
+ [119167]=5,
+ [119168]=5,
+ [119169]=5,
+ [119170]=5,
+ [119173]=5,
+ [119174]=5,
+ [119175]=5,
+ [119176]=5,
+ [119177]=5,
+ [119178]=5,
+ [119179]=5,
+ [119210]=5,
+ [119211]=5,
+ [119212]=5,
+ [119213]=5,
+ [119362]=5,
+ [119363]=5,
+ [119364]=5,
+ [121344]=5,
+ [121345]=5,
+ [121346]=5,
+ [121347]=5,
+ [121348]=5,
+ [121349]=5,
+ [121350]=5,
+ [121351]=5,
+ [121352]=5,
+ [121353]=5,
+ [121354]=5,
+ [121355]=5,
+ [121356]=5,
+ [121357]=5,
+ [121358]=5,
+ [121359]=5,
+ [121360]=5,
+ [121361]=5,
+ [121362]=5,
+ [121363]=5,
+ [121364]=5,
+ [121365]=5,
+ [121366]=5,
+ [121367]=5,
+ [121368]=5,
+ [121369]=5,
+ [121370]=5,
+ [121371]=5,
+ [121372]=5,
+ [121373]=5,
+ [121374]=5,
+ [121375]=5,
+ [121376]=5,
+ [121377]=5,
+ [121378]=5,
+ [121379]=5,
+ [121380]=5,
+ [121381]=5,
+ [121382]=5,
+ [121383]=5,
+ [121384]=5,
+ [121385]=5,
+ [121386]=5,
+ [121387]=5,
+ [121388]=5,
+ [121389]=5,
+ [121390]=5,
+ [121391]=5,
+ [121392]=5,
+ [121393]=5,
+ [121394]=5,
+ [121395]=5,
+ [121396]=5,
+ [121397]=5,
+ [121398]=5,
+ [121403]=5,
+ [121404]=5,
+ [121405]=5,
+ [121406]=5,
+ [121407]=5,
+ [121408]=5,
+ [121409]=5,
+ [121410]=5,
+ [121411]=5,
+ [121412]=5,
+ [121413]=5,
+ [121414]=5,
+ [121415]=5,
+ [121416]=5,
+ [121417]=5,
+ [121418]=5,
+ [121419]=5,
+ [121420]=5,
+ [121421]=5,
+ [121422]=5,
+ [121423]=5,
+ [121424]=5,
+ [121425]=5,
+ [121426]=5,
+ [121427]=5,
+ [121428]=5,
+ [121429]=5,
+ [121430]=5,
+ [121431]=5,
+ [121432]=5,
+ [121433]=5,
+ [121434]=5,
+ [121435]=5,
+ [121436]=5,
+ [121437]=5,
+ [121438]=5,
+ [121439]=5,
+ [121440]=5,
+ [121441]=5,
+ [121442]=5,
+ [121443]=5,
+ [121444]=5,
+ [121445]=5,
+ [121446]=5,
+ [121447]=5,
+ [121448]=5,
+ [121449]=5,
+ [121450]=5,
+ [121451]=5,
+ [121452]=5,
+ [121461]=5,
+ [121476]=5,
+ [121499]=5,
+ [121500]=5,
+ [121501]=5,
+ [121502]=5,
+ [121503]=5,
+ [121505]=5,
+ [121506]=5,
+ [121507]=5,
+ [121508]=5,
+ [121509]=5,
+ [121510]=5,
+ [121511]=5,
+ [121512]=5,
+ [121513]=5,
+ [121514]=5,
+ [121515]=5,
+ [121516]=5,
+ [121517]=5,
+ [121518]=5,
+ [121519]=5,
+ [122880]=5,
+ [122881]=5,
+ [122882]=5,
+ [122883]=5,
+ [122884]=5,
+ [122885]=5,
+ [122886]=5,
+ [122888]=5,
+ [122889]=5,
+ [122890]=5,
+ [122891]=5,
+ [122892]=5,
+ [122893]=5,
+ [122894]=5,
+ [122895]=5,
+ [122896]=5,
+ [122897]=5,
+ [122898]=5,
+ [122899]=5,
+ [122900]=5,
+ [122901]=5,
+ [122902]=5,
+ [122903]=5,
+ [122904]=5,
+ [122907]=5,
+ [122908]=5,
+ [122909]=5,
+ [122910]=5,
+ [122911]=5,
+ [122912]=5,
+ [122913]=5,
+ [122915]=5,
+ [122916]=5,
+ [122918]=5,
+ [122919]=5,
+ [122920]=5,
+ [122921]=5,
+ [122922]=5,
+ [123184]=5,
+ [123185]=5,
+ [123186]=5,
+ [123187]=5,
+ [123188]=5,
+ [123189]=5,
+ [123190]=5,
+ [123628]=5,
+ [123629]=5,
+ [123630]=5,
+ [123631]=5,
+ [125136]=5,
+ [125137]=5,
+ [125138]=5,
+ [125139]=5,
+ [125140]=5,
+ [125141]=5,
+ [125142]=5,
+ [125184]=2,
+ [125185]=2,
+ [125186]=2,
+ [125187]=2,
+ [125188]=2,
+ [125189]=2,
+ [125190]=2,
+ [125191]=2,
+ [125192]=2,
+ [125193]=2,
+ [125194]=2,
+ [125195]=2,
+ [125196]=2,
+ [125197]=2,
+ [125198]=2,
+ [125199]=2,
+ [125200]=2,
+ [125201]=2,
+ [125202]=2,
+ [125203]=2,
+ [125204]=2,
+ [125205]=2,
+ [125206]=2,
+ [125207]=2,
+ [125208]=2,
+ [125209]=2,
+ [125210]=2,
+ [125211]=2,
+ [125212]=2,
+ [125213]=2,
+ [125214]=2,
+ [125215]=2,
+ [125216]=2,
+ [125217]=2,
+ [125218]=2,
+ [125219]=2,
+ [125220]=2,
+ [125221]=2,
+ [125222]=2,
+ [125223]=2,
+ [125224]=2,
+ [125225]=2,
+ [125226]=2,
+ [125227]=2,
+ [125228]=2,
+ [125229]=2,
+ [125230]=2,
+ [125231]=2,
+ [125232]=2,
+ [125233]=2,
+ [125234]=2,
+ [125235]=2,
+ [125236]=2,
+ [125237]=2,
+ [125238]=2,
+ [125239]=2,
+ [125240]=2,
+ [125241]=2,
+ [125242]=2,
+ [125243]=2,
+ [125244]=2,
+ [125245]=2,
+ [125246]=2,
+ [125247]=2,
+ [125248]=2,
+ [125249]=2,
+ [125250]=2,
+ [125251]=2,
+ [125252]=5,
+ [125253]=5,
+ [125254]=5,
+ [125255]=5,
+ [125256]=5,
+ [125257]=5,
+ [125258]=5,
+ [1042752]=5,
+}
+characters.indicgroups={
+ ["above_mark"]={
+ [2304]=true,
+ [2305]=true,
+ [2306]=true,
+ [2362]=true,
+ [2373]=true,
+ [2374]=true,
+ [2375]=true,
+ [2376]=true,
+ [2385]=true,
+ [2387]=true,
+ [2388]=true,
+ [2389]=true,
+ [2631]=true,
+ [2632]=true,
+ [2635]=true,
+ [2636]=true,
+ [2690]=true,
+ [2757]=true,
+ [2759]=true,
+ [2760]=true,
+ [2879]=true,
+ [3008]=true,
+ [3021]=true,
+ [3134]=true,
+ [3135]=true,
+ [3136]=true,
+ [3142]=true,
+ [3143]=true,
+ [3146]=true,
+ [3147]=true,
+ [3148]=true,
+ [3149]=true,
+ [3263]=true,
+ [3270]=true,
+ [3406]=true,
+ [4141]=true,
+ [4142]=true,
+ [4146]=true,
+ [4147]=true,
+ [4148]=true,
+ [4149]=true,
+ [4150]=true,
+ [4154]=true,
+ [4209]=true,
+ [4210]=true,
+ [4211]=true,
+ [4212]=true,
+ [4229]=true,
+ [4230]=true,
+ [4253]=true,
+ [43232]=true,
+ [43233]=true,
+ [43234]=true,
+ [43235]=true,
+ [43236]=true,
+ [43237]=true,
+ [43238]=true,
+ [43239]=true,
+ [43240]=true,
+ [43241]=true,
+ [43242]=true,
+ [43243]=true,
+ [43244]=true,
+ [43245]=true,
+ [43246]=true,
+ [43247]=true,
+ [43248]=true,
+ [43249]=true,
+ [43493]=true,
+ [43644]=true,
+ },
+ ["after_half"]={},
+ ["after_main"]={
+ [2864]=true,
+ [2879]=true,
+ [2902]=true,
+ [3376]=true,
+ },
+ ["after_postscript"]={
+ [2433]=true,
+ [2494]=true,
+ [2496]=true,
+ [2519]=true,
+ [2561]=true,
+ [2562]=true,
+ [2622]=true,
+ [2624]=true,
+ [2625]=true,
+ [2626]=true,
+ [2672]=true,
+ [2673]=true,
+ [2735]=true,
+ [2750]=true,
+ [2752]=true,
+ [2753]=true,
+ [2754]=true,
+ [2755]=true,
+ [2756]=true,
+ [2761]=true,
+ [2763]=true,
+ [2764]=true,
+ [2786]=true,
+ [2787]=true,
+ [2878]=true,
+ [2880]=true,
+ [2903]=true,
+ [2992]=true,
+ [3006]=true,
+ [3007]=true,
+ [3009]=true,
+ [3010]=true,
+ [3031]=true,
+ [3120]=true,
+ [3248]=true,
+ [3390]=true,
+ [3391]=true,
+ [3392]=true,
+ [3393]=true,
+ [3394]=true,
+ [3395]=true,
+ [3415]=true,
+ },
+ ["after_subscript"]={
+ [2366]=true,
+ [2368]=true,
+ [2369]=true,
+ [2370]=true,
+ [2371]=true,
+ [2372]=true,
+ [2373]=true,
+ [2374]=true,
+ [2375]=true,
+ [2376]=true,
+ [2377]=true,
+ [2378]=true,
+ [2379]=true,
+ [2380]=true,
+ [2402]=true,
+ [2403]=true,
+ [2480]=true,
+ [2497]=true,
+ [2498]=true,
+ [2499]=true,
+ [2500]=true,
+ [2530]=true,
+ [2531]=true,
+ [2544]=true,
+ [2631]=true,
+ [2632]=true,
+ [2635]=true,
+ [2636]=true,
+ [2757]=true,
+ [2759]=true,
+ [2760]=true,
+ [2881]=true,
+ [2882]=true,
+ [2883]=true,
+ [3008]=true,
+ [3139]=true,
+ [3140]=true,
+ [3267]=true,
+ [3268]=true,
+ [3285]=true,
+ [3286]=true,
+ },
+ ["anudatta"]={
+ [2386]=true,
+ },
+ ["before_half"]={
+ [2367]=true,
+ [2382]=true,
+ [2495]=true,
+ [2503]=true,
+ [2504]=true,
+ [2623]=true,
+ [2751]=true,
+ [2887]=true,
+ },
+ ["before_main"]={
+ [3014]=true,
+ [3015]=true,
+ [3016]=true,
+ [3398]=true,
+ [3399]=true,
+ [3400]=true,
+ },
+ ["before_postscript"]={
+ [2352]=true,
+ [2736]=true,
+ },
+ ["before_subscript"]={
+ [2608]=true,
+ [2817]=true,
+ [3134]=true,
+ [3135]=true,
+ [3136]=true,
+ [3137]=true,
+ [3138]=true,
+ [3142]=true,
+ [3143]=true,
+ [3146]=true,
+ [3147]=true,
+ [3148]=true,
+ [3157]=true,
+ [3158]=true,
+ [3262]=true,
+ [3263]=true,
+ [3265]=true,
+ [3266]=true,
+ [3270]=true,
+ [3276]=true,
+ [3298]=true,
+ [3299]=true,
+ },
+ ["below_mark"]={
+ [2364]=true,
+ [2369]=true,
+ [2370]=true,
+ [2371]=true,
+ [2372]=true,
+ [2381]=true,
+ [2386]=true,
+ [2390]=true,
+ [2391]=true,
+ [2402]=true,
+ [2403]=true,
+ [2492]=true,
+ [2497]=true,
+ [2498]=true,
+ [2499]=true,
+ [2500]=true,
+ [2509]=true,
+ [2620]=true,
+ [2625]=true,
+ [2626]=true,
+ [2637]=true,
+ [2748]=true,
+ [2753]=true,
+ [2754]=true,
+ [2755]=true,
+ [2756]=true,
+ [2765]=true,
+ [2876]=true,
+ [2881]=true,
+ [2882]=true,
+ [2883]=true,
+ [2884]=true,
+ [2893]=true,
+ [2914]=true,
+ [2915]=true,
+ [3009]=true,
+ [3010]=true,
+ [3170]=true,
+ [3171]=true,
+ [3260]=true,
+ [3286]=true,
+ [3298]=true,
+ [3299]=true,
+ [3426]=true,
+ [3427]=true,
+ [4143]=true,
+ [4144]=true,
+ [4151]=true,
+ [4153]=true,
+ [4157]=true,
+ [4158]=true,
+ [4184]=true,
+ [4185]=true,
+ [4190]=true,
+ [4191]=true,
+ [4192]=true,
+ [4226]=true,
+ [4237]=true,
+ },
+ ["consonant"]={
+ [2325]=true,
+ [2326]=true,
+ [2327]=true,
+ [2328]=true,
+ [2329]=true,
+ [2330]=true,
+ [2331]=true,
+ [2332]=true,
+ [2333]=true,
+ [2334]=true,
+ [2335]=true,
+ [2336]=true,
+ [2337]=true,
+ [2338]=true,
+ [2339]=true,
+ [2340]=true,
+ [2341]=true,
+ [2342]=true,
+ [2343]=true,
+ [2344]=true,
+ [2345]=true,
+ [2346]=true,
+ [2347]=true,
+ [2348]=true,
+ [2349]=true,
+ [2350]=true,
+ [2351]=true,
+ [2352]=true,
+ [2353]=true,
+ [2354]=true,
+ [2355]=true,
+ [2356]=true,
+ [2357]=true,
+ [2358]=true,
+ [2359]=true,
+ [2360]=true,
+ [2361]=true,
+ [2392]=true,
+ [2393]=true,
+ [2394]=true,
+ [2395]=true,
+ [2396]=true,
+ [2397]=true,
+ [2398]=true,
+ [2399]=true,
+ [2424]=true,
+ [2425]=true,
+ [2426]=true,
+ [2453]=true,
+ [2454]=true,
+ [2455]=true,
+ [2456]=true,
+ [2457]=true,
+ [2458]=true,
+ [2459]=true,
+ [2460]=true,
+ [2461]=true,
+ [2462]=true,
+ [2463]=true,
+ [2464]=true,
+ [2465]=true,
+ [2466]=true,
+ [2467]=true,
+ [2468]=true,
+ [2469]=true,
+ [2470]=true,
+ [2471]=true,
+ [2472]=true,
+ [2474]=true,
+ [2475]=true,
+ [2476]=true,
+ [2477]=true,
+ [2478]=true,
+ [2479]=true,
+ [2480]=true,
+ [2482]=true,
+ [2486]=true,
+ [2487]=true,
+ [2488]=true,
+ [2489]=true,
+ [2510]=true,
+ [2524]=true,
+ [2525]=true,
+ [2527]=true,
+ [2581]=true,
+ [2582]=true,
+ [2583]=true,
+ [2584]=true,
+ [2585]=true,
+ [2586]=true,
+ [2587]=true,
+ [2588]=true,
+ [2589]=true,
+ [2590]=true,
+ [2591]=true,
+ [2592]=true,
+ [2593]=true,
+ [2594]=true,
+ [2595]=true,
+ [2596]=true,
+ [2597]=true,
+ [2598]=true,
+ [2599]=true,
+ [2600]=true,
+ [2602]=true,
+ [2603]=true,
+ [2604]=true,
+ [2605]=true,
+ [2606]=true,
+ [2607]=true,
+ [2608]=true,
+ [2610]=true,
+ [2611]=true,
+ [2613]=true,
+ [2614]=true,
+ [2616]=true,
+ [2617]=true,
+ [2649]=true,
+ [2650]=true,
+ [2651]=true,
+ [2652]=true,
+ [2654]=true,
+ [2709]=true,
+ [2710]=true,
+ [2711]=true,
+ [2712]=true,
+ [2713]=true,
+ [2714]=true,
+ [2715]=true,
+ [2716]=true,
+ [2717]=true,
+ [2718]=true,
+ [2719]=true,
+ [2720]=true,
+ [2721]=true,
+ [2722]=true,
+ [2723]=true,
+ [2724]=true,
+ [2725]=true,
+ [2726]=true,
+ [2727]=true,
+ [2728]=true,
+ [2730]=true,
+ [2731]=true,
+ [2732]=true,
+ [2733]=true,
+ [2734]=true,
+ [2735]=true,
+ [2736]=true,
+ [2738]=true,
+ [2739]=true,
+ [2741]=true,
+ [2742]=true,
+ [2743]=true,
+ [2744]=true,
+ [2745]=true,
+ [2837]=true,
+ [2838]=true,
+ [2839]=true,
+ [2840]=true,
+ [2841]=true,
+ [2842]=true,
+ [2843]=true,
+ [2844]=true,
+ [2845]=true,
+ [2846]=true,
+ [2847]=true,
+ [2848]=true,
+ [2849]=true,
+ [2850]=true,
+ [2851]=true,
+ [2852]=true,
+ [2853]=true,
+ [2854]=true,
+ [2855]=true,
+ [2856]=true,
+ [2858]=true,
+ [2859]=true,
+ [2860]=true,
+ [2861]=true,
+ [2862]=true,
+ [2863]=true,
+ [2864]=true,
+ [2866]=true,
+ [2867]=true,
+ [2869]=true,
+ [2870]=true,
+ [2871]=true,
+ [2872]=true,
+ [2873]=true,
+ [2908]=true,
+ [2909]=true,
+ [2929]=true,
+ [2965]=true,
+ [2969]=true,
+ [2970]=true,
+ [2972]=true,
+ [2974]=true,
+ [2975]=true,
+ [2979]=true,
+ [2980]=true,
+ [2984]=true,
+ [2985]=true,
+ [2986]=true,
+ [2990]=true,
+ [2991]=true,
+ [2992]=true,
+ [2993]=true,
+ [2994]=true,
+ [2995]=true,
+ [2996]=true,
+ [2997]=true,
+ [2998]=true,
+ [2999]=true,
+ [3000]=true,
+ [3001]=true,
+ [3093]=true,
+ [3094]=true,
+ [3095]=true,
+ [3096]=true,
+ [3097]=true,
+ [3098]=true,
+ [3099]=true,
+ [3100]=true,
+ [3101]=true,
+ [3102]=true,
+ [3103]=true,
+ [3104]=true,
+ [3105]=true,
+ [3106]=true,
+ [3107]=true,
+ [3108]=true,
+ [3109]=true,
+ [3110]=true,
+ [3111]=true,
+ [3112]=true,
+ [3114]=true,
+ [3115]=true,
+ [3116]=true,
+ [3117]=true,
+ [3118]=true,
+ [3119]=true,
+ [3120]=true,
+ [3121]=true,
+ [3122]=true,
+ [3123]=true,
+ [3124]=true,
+ [3125]=true,
+ [3126]=true,
+ [3127]=true,
+ [3128]=true,
+ [3129]=true,
+ [3133]=true,
+ [3221]=true,
+ [3222]=true,
+ [3223]=true,
+ [3224]=true,
+ [3225]=true,
+ [3226]=true,
+ [3227]=true,
+ [3228]=true,
+ [3229]=true,
+ [3230]=true,
+ [3231]=true,
+ [3232]=true,
+ [3233]=true,
+ [3234]=true,
+ [3235]=true,
+ [3236]=true,
+ [3237]=true,
+ [3238]=true,
+ [3239]=true,
+ [3240]=true,
+ [3242]=true,
+ [3243]=true,
+ [3244]=true,
+ [3245]=true,
+ [3246]=true,
+ [3247]=true,
+ [3248]=true,
+ [3249]=true,
+ [3250]=true,
+ [3251]=true,
+ [3253]=true,
+ [3254]=true,
+ [3255]=true,
+ [3256]=true,
+ [3257]=true,
+ [3294]=true,
+ [3349]=true,
+ [3350]=true,
+ [3351]=true,
+ [3352]=true,
+ [3353]=true,
+ [3354]=true,
+ [3355]=true,
+ [3356]=true,
+ [3357]=true,
+ [3358]=true,
+ [3359]=true,
+ [3360]=true,
+ [3361]=true,
+ [3362]=true,
+ [3363]=true,
+ [3364]=true,
+ [3365]=true,
+ [3366]=true,
+ [3367]=true,
+ [3368]=true,
+ [3369]=true,
+ [3370]=true,
+ [3371]=true,
+ [3372]=true,
+ [3373]=true,
+ [3374]=true,
+ [3375]=true,
+ [3376]=true,
+ [3377]=true,
+ [3378]=true,
+ [3379]=true,
+ [3380]=true,
+ [3381]=true,
+ [3382]=true,
+ [3383]=true,
+ [3384]=true,
+ [3385]=true,
+ [3386]=true,
+ [4096]=true,
+ [4097]=true,
+ [4098]=true,
+ [4099]=true,
+ [4100]=true,
+ [4101]=true,
+ [4102]=true,
+ [4103]=true,
+ [4104]=true,
+ [4105]=true,
+ [4106]=true,
+ [4107]=true,
+ [4108]=true,
+ [4109]=true,
+ [4110]=true,
+ [4111]=true,
+ [4112]=true,
+ [4113]=true,
+ [4114]=true,
+ [4115]=true,
+ [4116]=true,
+ [4117]=true,
+ [4118]=true,
+ [4119]=true,
+ [4120]=true,
+ [4121]=true,
+ [4122]=true,
+ [4123]=true,
+ [4124]=true,
+ [4125]=true,
+ [4126]=true,
+ [4127]=true,
+ [4128]=true,
+ [4155]=true,
+ [4156]=true,
+ [4157]=true,
+ [4158]=true,
+ [4159]=true,
+ [4176]=true,
+ [4177]=true,
+ [4186]=true,
+ [4187]=true,
+ [4188]=true,
+ [4189]=true,
+ [4190]=true,
+ [4191]=true,
+ [4192]=true,
+ [4193]=true,
+ [4197]=true,
+ [4198]=true,
+ [4206]=true,
+ [4207]=true,
+ [4208]=true,
+ [4213]=true,
+ [4214]=true,
+ [4215]=true,
+ [4216]=true,
+ [4217]=true,
+ [4218]=true,
+ [4219]=true,
+ [4220]=true,
+ [4221]=true,
+ [4222]=true,
+ [4223]=true,
+ [4224]=true,
+ [4225]=true,
+ [4226]=true,
+ [4238]=true,
+ [43488]=true,
+ [43489]=true,
+ [43490]=true,
+ [43491]=true,
+ [43492]=true,
+ [43495]=true,
+ [43496]=true,
+ [43497]=true,
+ [43498]=true,
+ [43499]=true,
+ [43500]=true,
+ [43501]=true,
+ [43502]=true,
+ [43503]=true,
+ [43514]=true,
+ [43515]=true,
+ [43516]=true,
+ [43517]=true,
+ [43518]=true,
+ [43616]=true,
+ [43617]=true,
+ [43618]=true,
+ [43619]=true,
+ [43620]=true,
+ [43621]=true,
+ [43622]=true,
+ [43623]=true,
+ [43624]=true,
+ [43625]=true,
+ [43626]=true,
+ [43628]=true,
+ [43629]=true,
+ [43630]=true,
+ [43631]=true,
+ [43633]=true,
+ [43634]=true,
+ [43635]=true,
+ [43636]=true,
+ [43637]=true,
+ [43638]=true,
+ [43642]=true,
+ [43646]=true,
+ [43647]=true,
+ },
+ ["dependent_vowel"]={
+ [2362]=true,
+ [2363]=true,
+ [2366]=true,
+ [2367]=true,
+ [2368]=true,
+ [2369]=true,
+ [2370]=true,
+ [2371]=true,
+ [2372]=true,
+ [2373]=true,
+ [2374]=true,
+ [2375]=true,
+ [2376]=true,
+ [2377]=true,
+ [2378]=true,
+ [2379]=true,
+ [2380]=true,
+ [2382]=true,
+ [2383]=true,
+ [2389]=true,
+ [2390]=true,
+ [2391]=true,
+ [2402]=true,
+ [2403]=true,
+ [2494]=true,
+ [2495]=true,
+ [2497]=true,
+ [2498]=true,
+ [2499]=true,
+ [2500]=true,
+ [2503]=true,
+ [2504]=true,
+ [2507]=true,
+ [2508]=true,
+ [2622]=true,
+ [2623]=true,
+ [2624]=true,
+ [2625]=true,
+ [2626]=true,
+ [2631]=true,
+ [2632]=true,
+ [2635]=true,
+ [2636]=true,
+ [2750]=true,
+ [2751]=true,
+ [2752]=true,
+ [2753]=true,
+ [2754]=true,
+ [2755]=true,
+ [2756]=true,
+ [2757]=true,
+ [2759]=true,
+ [2760]=true,
+ [2761]=true,
+ [2763]=true,
+ [2764]=true,
+ [2878]=true,
+ [2879]=true,
+ [2880]=true,
+ [2881]=true,
+ [2882]=true,
+ [2883]=true,
+ [2884]=true,
+ [2887]=true,
+ [2888]=true,
+ [2891]=true,
+ [2892]=true,
+ [2914]=true,
+ [2915]=true,
+ [3006]=true,
+ [3007]=true,
+ [3008]=true,
+ [3009]=true,
+ [3010]=true,
+ [3014]=true,
+ [3015]=true,
+ [3016]=true,
+ [3018]=true,
+ [3019]=true,
+ [3020]=true,
+ [3134]=true,
+ [3135]=true,
+ [3136]=true,
+ [3137]=true,
+ [3138]=true,
+ [3139]=true,
+ [3140]=true,
+ [3142]=true,
+ [3143]=true,
+ [3144]=true,
+ [3146]=true,
+ [3147]=true,
+ [3148]=true,
+ [3170]=true,
+ [3171]=true,
+ [3262]=true,
+ [3263]=true,
+ [3264]=true,
+ [3265]=true,
+ [3266]=true,
+ [3267]=true,
+ [3268]=true,
+ [3270]=true,
+ [3271]=true,
+ [3272]=true,
+ [3274]=true,
+ [3275]=true,
+ [3276]=true,
+ [3285]=true,
+ [3286]=true,
+ [3298]=true,
+ [3299]=true,
+ [3390]=true,
+ [3391]=true,
+ [3392]=true,
+ [3393]=true,
+ [3394]=true,
+ [3395]=true,
+ [3396]=true,
+ [3398]=true,
+ [3399]=true,
+ [3400]=true,
+ [3402]=true,
+ [3403]=true,
+ [3404]=true,
+ [3415]=true,
+ [3426]=true,
+ [3427]=true,
+ [4139]=true,
+ [4140]=true,
+ [4141]=true,
+ [4142]=true,
+ [4143]=true,
+ [4144]=true,
+ [4145]=true,
+ [4146]=true,
+ [4147]=true,
+ [4148]=true,
+ [4149]=true,
+ [4182]=true,
+ [4183]=true,
+ [4184]=true,
+ [4185]=true,
+ [4194]=true,
+ [4199]=true,
+ [4200]=true,
+ [4209]=true,
+ [4210]=true,
+ [4211]=true,
+ [4212]=true,
+ [4227]=true,
+ [4228]=true,
+ [4229]=true,
+ [4230]=true,
+ [4252]=true,
+ [4253]=true,
+ [43493]=true,
+ },
+ ["halant"]={
+ [2381]=true,
+ [2509]=true,
+ [2637]=true,
+ [2765]=true,
+ [2893]=true,
+ [3021]=true,
+ [3149]=true,
+ [3277]=true,
+ [3405]=true,
+ },
+ ["independent_vowel"]={
+ [2308]=true,
+ [2309]=true,
+ [2310]=true,
+ [2311]=true,
+ [2312]=true,
+ [2313]=true,
+ [2314]=true,
+ [2315]=true,
+ [2316]=true,
+ [2317]=true,
+ [2318]=true,
+ [2319]=true,
+ [2320]=true,
+ [2321]=true,
+ [2322]=true,
+ [2323]=true,
+ [2324]=true,
+ [2400]=true,
+ [2401]=true,
+ [2418]=true,
+ [2419]=true,
+ [2420]=true,
+ [2421]=true,
+ [2422]=true,
+ [2423]=true,
+ [2437]=true,
+ [2438]=true,
+ [2439]=true,
+ [2440]=true,
+ [2441]=true,
+ [2442]=true,
+ [2443]=true,
+ [2444]=true,
+ [2447]=true,
+ [2448]=true,
+ [2451]=true,
+ [2452]=true,
+ [2528]=true,
+ [2529]=true,
+ [2530]=true,
+ [2531]=true,
+ [2565]=true,
+ [2566]=true,
+ [2567]=true,
+ [2568]=true,
+ [2569]=true,
+ [2570]=true,
+ [2575]=true,
+ [2576]=true,
+ [2579]=true,
+ [2580]=true,
+ [2693]=true,
+ [2694]=true,
+ [2695]=true,
+ [2696]=true,
+ [2697]=true,
+ [2698]=true,
+ [2699]=true,
+ [2700]=true,
+ [2701]=true,
+ [2703]=true,
+ [2704]=true,
+ [2705]=true,
+ [2707]=true,
+ [2708]=true,
+ [2784]=true,
+ [2785]=true,
+ [2786]=true,
+ [2787]=true,
+ [2821]=true,
+ [2822]=true,
+ [2823]=true,
+ [2824]=true,
+ [2825]=true,
+ [2826]=true,
+ [2827]=true,
+ [2828]=true,
+ [2831]=true,
+ [2832]=true,
+ [2835]=true,
+ [2836]=true,
+ [2912]=true,
+ [2913]=true,
+ [2949]=true,
+ [2950]=true,
+ [2951]=true,
+ [2952]=true,
+ [2953]=true,
+ [2954]=true,
+ [2958]=true,
+ [2959]=true,
+ [2960]=true,
+ [2962]=true,
+ [2963]=true,
+ [2964]=true,
+ [3077]=true,
+ [3078]=true,
+ [3079]=true,
+ [3080]=true,
+ [3081]=true,
+ [3082]=true,
+ [3083]=true,
+ [3084]=true,
+ [3086]=true,
+ [3087]=true,
+ [3088]=true,
+ [3090]=true,
+ [3091]=true,
+ [3092]=true,
+ [3168]=true,
+ [3169]=true,
+ [3205]=true,
+ [3206]=true,
+ [3207]=true,
+ [3208]=true,
+ [3209]=true,
+ [3210]=true,
+ [3211]=true,
+ [3212]=true,
+ [3214]=true,
+ [3215]=true,
+ [3216]=true,
+ [3218]=true,
+ [3219]=true,
+ [3220]=true,
+ [3296]=true,
+ [3297]=true,
+ [3333]=true,
+ [3334]=true,
+ [3335]=true,
+ [3336]=true,
+ [3337]=true,
+ [3338]=true,
+ [3339]=true,
+ [3340]=true,
+ [3342]=true,
+ [3343]=true,
+ [3344]=true,
+ [3346]=true,
+ [3347]=true,
+ [3348]=true,
+ [3423]=true,
+ [3424]=true,
+ [3425]=true,
+ [4129]=true,
+ [4130]=true,
+ [4131]=true,
+ [4132]=true,
+ [4133]=true,
+ [4134]=true,
+ [4135]=true,
+ [4136]=true,
+ [4137]=true,
+ [4138]=true,
+ [4178]=true,
+ [4179]=true,
+ [4180]=true,
+ [4181]=true,
+ },
+ ["nukta"]={
+ [2364]=true,
+ [2492]=true,
+ [2620]=true,
+ [2748]=true,
+ [2876]=true,
+ [3260]=true,
+ },
+ ["post_mark"]={
+ [2307]=true,
+ [2363]=true,
+ [2366]=true,
+ [2368]=true,
+ [2377]=true,
+ [2378]=true,
+ [2379]=true,
+ [2380]=true,
+ [2383]=true,
+ [2494]=true,
+ [2496]=true,
+ [2622]=true,
+ [2624]=true,
+ [2750]=true,
+ [2752]=true,
+ [2761]=true,
+ [2763]=true,
+ [2764]=true,
+ [2878]=true,
+ [2880]=true,
+ [3006]=true,
+ [3007]=true,
+ [3137]=true,
+ [3138]=true,
+ [3139]=true,
+ [3140]=true,
+ [3262]=true,
+ [3265]=true,
+ [3266]=true,
+ [3267]=true,
+ [3268]=true,
+ [3276]=true,
+ [3285]=true,
+ [3390]=true,
+ [3391]=true,
+ [3392]=true,
+ [3393]=true,
+ [3394]=true,
+ [3395]=true,
+ [3396]=true,
+ [3415]=true,
+ [4139]=true,
+ [4140]=true,
+ [4152]=true,
+ [4155]=true,
+ [4182]=true,
+ [4183]=true,
+ [4194]=true,
+ [4195]=true,
+ [4196]=true,
+ [4199]=true,
+ [4200]=true,
+ [4201]=true,
+ [4202]=true,
+ [4203]=true,
+ [4204]=true,
+ [4205]=true,
+ [4227]=true,
+ [4231]=true,
+ [4232]=true,
+ [4233]=true,
+ [4234]=true,
+ [4235]=true,
+ [4236]=true,
+ [4239]=true,
+ [4250]=true,
+ [4251]=true,
+ [4252]=true,
+ [43643]=true,
+ [43645]=true,
+ },
+ ["pre_mark"]={
+ [2367]=true,
+ [2382]=true,
+ [2495]=true,
+ [2503]=true,
+ [2504]=true,
+ [2623]=true,
+ [2751]=true,
+ [2887]=true,
+ [3014]=true,
+ [3015]=true,
+ [3016]=true,
+ [3398]=true,
+ [3399]=true,
+ [3400]=true,
+ [4145]=true,
+ [4228]=true,
+ },
+ ["ra"]={
+ [2352]=true,
+ [2480]=true,
+ [2544]=true,
+ [2608]=true,
+ [2736]=true,
+ [2864]=true,
+ [2992]=true,
+ [3120]=true,
+ [3248]=true,
+ [3376]=true,
+ },
+ ["stress_tone_mark"]={
+ [2385]=true,
+ [2386]=true,
+ [2387]=true,
+ [2388]=true,
+ [4151]=true,
+ [4195]=true,
+ [4196]=true,
+ [4201]=true,
+ [4202]=true,
+ [4203]=true,
+ [4204]=true,
+ [4205]=true,
+ [4231]=true,
+ [4232]=true,
+ [4233]=true,
+ [4234]=true,
+ [4235]=true,
+ [4236]=true,
+ [4237]=true,
+ [4239]=true,
+ [4250]=true,
+ [4251]=true,
+ [43643]=true,
+ [43644]=true,
+ [43645]=true,
+ },
+ ["twopart_mark"]={
+ [2507]={ 2503,2494 },
+ [2508]={ 2503,2519 },
+ [2888]={ 2887,2902 },
+ [2891]={ 2887,2878 },
+ [2892]={ 2887,2903 },
+ [3018]={ 3014,3006 },
+ [3019]={ 3015,3006 },
+ [3020]={ 3014,3031 },
+ [3144]={ 3142,3158 },
+ [3264]={ 3263,3285 },
+ [3271]={ 3270,3285 },
+ [3272]={ 3270,3286 },
+ [3274]={ 3270,3266 },
+ [3275]={ 3274,3285 },
+ [3402]={ 3398,3390 },
+ [3403]={ 3399,3390 },
+ [3404]={ 3398,3415 },
+ },
+ ["vowel_modifier"]={
+ [2304]=true,
+ [2305]=true,
+ [2306]=true,
+ [2307]=true,
+ [2433]=true,
+ [3330]=true,
+ [3331]=true,
+ [4150]=true,
+ [4152]=true,
+ [4153]=true,
+ [4154]=true,
+ [43232]=true,
+ [43233]=true,
+ [43234]=true,
+ [43235]=true,
+ [43236]=true,
+ [43237]=true,
+ [43238]=true,
+ [43239]=true,
+ [43240]=true,
+ [43241]=true,
+ [43242]=true,
+ [43243]=true,
+ [43244]=true,
+ [43245]=true,
+ [43246]=true,
+ [43247]=true,
+ [43249]=true,
+ },
+}
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-ini']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local allocate=utilities.storage.allocate
+local sortedhash=table.sortedhash
+fonts=fonts or {}
+local fonts=fonts
+local identifiers=allocate()
+fonts.hashes=fonts.hashes or { identifiers=identifiers }
+fonts.tables=fonts.tables or {}
+fonts.helpers=fonts.helpers or {}
+fonts.tracers=fonts.tracers or {}
+fonts.specifiers=fonts.specifiers or {}
+fonts.analyzers={}
+fonts.readers={}
+fonts.definers={ methods={} }
+fonts.loggers={ register=function() end }
+if context then
+
+--removed
+
+end
+fonts.privateoffsets={
+ textbase=0xF0000,
+ textextrabase=0xFD000,
+ mathextrabase=0xFE000,
+ mathbase=0xFF000,
+ keepnames=false,
+}
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['luatex-font-mis']={
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+--removed
+
+end
+local currentfont=font.current
+local hashes=fonts.hashes
+local identifiers=hashes.identifiers or {}
+local marks=hashes.marks or {}
+hashes.identifiers=identifiers
+hashes.marks=marks
+table.setmetatableindex(marks,function(t,k)
+ if k==true then
+ return marks[currentfont()]
+ else
+ local resources=identifiers[k].resources or {}
+ local marks=resources.marks or {}
+ t[k]=marks
+ return marks
+ end
+end)
+function font.each()
+ return table.sortedhash(fonts.hashes.identifiers)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-con']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,tostring,tonumber,rawget=next,tostring,tonumber,rawget
+local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find
+local sort,insert,concat=table.sort,table.insert,table.concat
+local sortedkeys,sortedhash,serialize,fastcopy=table.sortedkeys,table.sortedhash,table.serialize,table.fastcopy
+local derivetable=table.derive
+local ioflush=io.flush
+local round=math.round
+local setmetatable,getmetatable,rawget,rawset=setmetatable,getmetatable,rawget,rawset
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end)
+local report_defining=logs.reporter("fonts","defining")
+local fonts=fonts
+local constructors=fonts.constructors or {}
+fonts.constructors=constructors
+local handlers=fonts.handlers or {}
+fonts.handlers=handlers
+local allocate=utilities.storage.allocate
+local setmetatableindex=table.setmetatableindex
+constructors.dontembed=allocate()
+constructors.autocleanup=true
+constructors.namemode="fullpath"
+constructors.version=1.01
+constructors.cache=containers.define("fonts","constructors",constructors.version,false)
+constructors.privateoffset=fonts.privateoffsets.textbase or 0xF0000
+constructors.cacheintex=true
+constructors.addtounicode=true
+local designsizes=allocate()
+constructors.designsizes=designsizes
+local loadedfonts=allocate()
+constructors.loadedfonts=loadedfonts
+local factors={
+ pt=65536.0,
+ bp=65781.8,
+}
+function constructors.setfactor(f)
+ constructors.factor=factors[f or 'pt'] or factors.pt
+end
+constructors.setfactor()
+function constructors.scaled(scaledpoints,designsize)
+ if scaledpoints<0 then
+ local factor=constructors.factor
+ if designsize then
+ if designsize>factor then
+ return (- scaledpoints/1000)*designsize
+ else
+ return (- scaledpoints/1000)*designsize*factor
+ end
+ else
+ return (- scaledpoints/1000)*10*factor
+ end
+ else
+ return scaledpoints
+ end
+end
+function constructors.getprivate(tfmdata)
+ local properties=tfmdata.properties
+ local private=properties.private
+ properties.private=private+1
+ return private
+end
+function constructors.setmathparameter(tfmdata,name,value)
+ local m=tfmdata.mathparameters
+ local c=tfmdata.MathConstants
+ if m then
+ m[name]=value
+ end
+ if c and c~=m then
+ c[name]=value
+ end
+end
+function constructors.getmathparameter(tfmdata,name)
+ local p=tfmdata.mathparameters or tfmdata.MathConstants
+ if p then
+ return p[name]
+ end
+end
+function constructors.cleanuptable(tfmdata)
+ if constructors.autocleanup and tfmdata.properties.virtualized then
+ for k,v in next,tfmdata.characters do
+ if v.commands then v.commands=nil end
+ end
+ end
+end
+function constructors.calculatescale(tfmdata,scaledpoints)
+ local parameters=tfmdata.parameters
+ if scaledpoints<0 then
+ scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize)
+ end
+ return scaledpoints,scaledpoints/(parameters.units or 1000)
+end
+local unscaled={
+ ScriptPercentScaleDown=true,
+ ScriptScriptPercentScaleDown=true,
+ RadicalDegreeBottomRaisePercent=true,
+ NoLimitSupFactor=true,
+ NoLimitSubFactor=true,
+}
+function constructors.assignmathparameters(target,original)
+ local mathparameters=original.mathparameters
+ if mathparameters and next(mathparameters) then
+ local targetparameters=target.parameters
+ local targetproperties=target.properties
+ local targetmathparameters={}
+ local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor
+ for name,value in next,mathparameters do
+ if unscaled[name] then
+ targetmathparameters[name]=value
+ else
+ targetmathparameters[name]=value*factor
+ end
+ end
+ if not targetmathparameters.FractionDelimiterSize then
+ targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size
+ end
+ if not mathparameters.FractionDelimiterDisplayStyleSize then
+ targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size
+ end
+ target.mathparameters=targetmathparameters
+ end
+end
+function constructors.beforecopyingcharacters(target,original)
+end
+function constructors.aftercopyingcharacters(target,original)
+end
+constructors.sharefonts=false
+constructors.nofsharedfonts=0
+local sharednames={}
+function constructors.trytosharefont(target,tfmdata)
+ if constructors.sharefonts then
+ local characters=target.characters
+ local n=1
+ local t={ target.psname }
+ local u=sortedkeys(characters)
+ for i=1,#u do
+ local k=u[i]
+ n=n+1;t[n]=k
+ n=n+1;t[n]=characters[k].index or k
+ end
+ local h=md5.HEX(concat(t," "))
+ local s=sharednames[h]
+ if s then
+ if trace_defining then
+ report_defining("font %a uses backend resources of font %a",target.fullname,s)
+ end
+ target.fullname=s
+ constructors.nofsharedfonts=constructors.nofsharedfonts+1
+ target.properties.sharedwith=s
+ else
+ sharednames[h]=target.fullname
+ end
+ end
+end
+local synonyms={
+ exheight="x_height",
+ xheight="x_height",
+ ex="x_height",
+ emwidth="quad",
+ em="quad",
+ spacestretch="space_stretch",
+ stretch="space_stretch",
+ spaceshrink="space_shrink",
+ shrink="space_shrink",
+ extraspace="extra_space",
+ xspace="extra_space",
+ slantperpoint="slant",
+}
+function constructors.enhanceparameters(parameters)
+ local mt=getmetatable(parameters)
+ local getter=function(t,k)
+ if not k then
+ return nil
+ end
+ local s=synonyms[k]
+ if s then
+ return rawget(t,s) or (mt and mt[s]) or nil
+ end
+ if k=="spacing" then
+ return {
+ width=t.space,
+ stretch=t.space_stretch,
+ shrink=t.space_shrink,
+ extra=t.extra_space,
+ }
+ end
+ return mt and mt[k] or nil
+ end
+ local setter=function(t,k,v)
+ if not k then
+ return 0
+ end
+ local s=synonyms[k]
+ if s then
+ rawset(t,s,v)
+ elseif k=="spacing" then
+ if type(v)=="table" then
+ rawset(t,"space",v.width or 0)
+ rawset(t,"space_stretch",v.stretch or 0)
+ rawset(t,"space_shrink",v.shrink or 0)
+ rawset(t,"extra_space",v.extra or 0)
+ end
+ else
+ rawset(t,k,v)
+ end
+ end
+ setmetatable(parameters,{
+ __index=getter,
+ __newindex=setter,
+ })
+end
+local function mathkerns(v,vdelta)
+ local k={}
+ for i=1,#v do
+ local entry=v[i]
+ local height=entry.height
+ local kern=entry.kern
+ k[i]={
+ height=height and vdelta*height or 0,
+ kern=kern and vdelta*kern or 0,
+ }
+ end
+ return k
+end
+local psfake=0
+local function fixedpsname(psname,fallback)
+ local usedname=psname
+ if psname and psname~="" then
+ if find(psname," ",1,true) then
+ usedname=gsub(psname,"[%s]+","-")
+ else
+ end
+ elseif not fallback or fallback=="" then
+ psfake=psfake+1
+ psname="fakename-"..psfake
+ else
+ psname=fallback
+ usedname=gsub(psname,"[^a-zA-Z0-9]+","-")
+ end
+ return usedname,psname~=usedname
+end
+function constructors.scale(tfmdata,specification)
+ local target={}
+ if tonumber(specification) then
+ specification={ size=specification }
+ end
+ target.specification=specification
+ local scaledpoints=specification.size
+ local relativeid=specification.relativeid
+ local properties=tfmdata.properties or {}
+ local goodies=tfmdata.goodies or {}
+ local resources=tfmdata.resources or {}
+ local descriptions=tfmdata.descriptions or {}
+ local characters=tfmdata.characters or {}
+ local changed=tfmdata.changed or {}
+ local shared=tfmdata.shared or {}
+ local parameters=tfmdata.parameters or {}
+ local mathparameters=tfmdata.mathparameters or {}
+ local targetcharacters={}
+ local targetdescriptions=derivetable(descriptions)
+ local targetparameters=derivetable(parameters)
+ local targetproperties=derivetable(properties)
+ local targetgoodies=goodies
+ target.characters=targetcharacters
+ target.descriptions=targetdescriptions
+ target.parameters=targetparameters
+ target.properties=targetproperties
+ target.goodies=targetgoodies
+ target.shared=shared
+ target.resources=resources
+ target.unscaled=tfmdata
+ local mathsize=tonumber(specification.mathsize) or 0
+ local textsize=tonumber(specification.textsize) or scaledpoints
+ local forcedsize=tonumber(parameters.mathsize ) or 0
+ local extrafactor=tonumber(specification.factor ) or 1
+ if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then
+ scaledpoints=parameters.scriptpercentage*textsize/100
+ elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then
+ scaledpoints=parameters.scriptscriptpercentage*textsize/100
+ elseif forcedsize>1000 then
+ scaledpoints=forcedsize
+ else
+ end
+ targetparameters.mathsize=mathsize
+ targetparameters.textsize=textsize
+ targetparameters.forcedsize=forcedsize
+ targetparameters.extrafactor=extrafactor
+ local addtounicode=constructors.addtounicode
+ local tounicode=fonts.mappings.tounicode
+ local unknowncode=tounicode(0xFFFD)
+ local defaultwidth=resources.defaultwidth or 0
+ local defaultheight=resources.defaultheight or 0
+ local defaultdepth=resources.defaultdepth or 0
+ local units=parameters.units or 1000
+ targetproperties.language=properties.language or "dflt"
+ targetproperties.script=properties.script or "dflt"
+ targetproperties.mode=properties.mode or "base"
+ local askedscaledpoints=scaledpoints
+ local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification)
+ local hdelta=delta
+ local vdelta=delta
+ target.designsize=parameters.designsize
+ target.units=units
+ target.units_per_em=units
+ local direction=properties.direction or tfmdata.direction or 0
+ target.direction=direction
+ properties.direction=direction
+ target.size=scaledpoints
+ target.encodingbytes=properties.encodingbytes or 1
+ target.embedding=properties.embedding or "subset"
+ target.tounicode=1
+ target.cidinfo=properties.cidinfo
+ target.format=properties.format
+ target.cache=constructors.cacheintex and "yes" or "renew"
+ local fontname=properties.fontname or tfmdata.fontname
+ local fullname=properties.fullname or tfmdata.fullname
+ local filename=properties.filename or tfmdata.filename
+ local psname=properties.psname or tfmdata.psname
+ local name=properties.name or tfmdata.name
+ local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename))
+ target.fontname=fontname
+ target.fullname=fullname
+ target.filename=filename
+ target.psname=psname
+ target.name=name
+ properties.fontname=fontname
+ properties.fullname=fullname
+ properties.filename=filename
+ properties.psname=psname
+ properties.name=name
+ local expansion=parameters.expansion
+ if expansion then
+ target.stretch=expansion.stretch
+ target.shrink=expansion.shrink
+ target.step=expansion.step
+ end
+ local slantfactor=parameters.slantfactor or 0
+ if slantfactor~=0 then
+ target.slant=slantfactor*1000
+ else
+ target.slant=0
+ end
+ local extendfactor=parameters.extendfactor or 0
+ if extendfactor~=0 and extendfactor~=1 then
+ hdelta=hdelta*extendfactor
+ target.extend=extendfactor*1000
+ else
+ target.extend=1000
+ end
+ local squeezefactor=parameters.squeezefactor or 0
+ if squeezefactor~=0 and squeezefactor~=1 then
+ vdelta=vdelta*squeezefactor
+ target.squeeze=squeezefactor*1000
+ else
+ target.squeeze=1000
+ end
+ local mode=parameters.mode or 0
+ if mode~=0 then
+ target.mode=mode
+ end
+ local width=parameters.width or 0
+ if width~=0 then
+ target.width=width*delta*1000/655360
+ end
+ targetparameters.factor=delta
+ targetparameters.hfactor=hdelta
+ targetparameters.vfactor=vdelta
+ targetparameters.size=scaledpoints
+ targetparameters.units=units
+ targetparameters.scaledpoints=askedscaledpoints
+ targetparameters.mode=mode
+ targetparameters.width=width
+ local isvirtual=properties.virtualized or tfmdata.type=="virtual"
+ local hasquality=parameters.expansion or parameters.protrusion
+ local hasitalics=properties.hasitalics
+ local autoitalicamount=properties.autoitalicamount
+ local stackmath=not properties.nostackmath
+ local haskerns=properties.haskerns or properties.mode=="base"
+ local hasligatures=properties.hasligatures or properties.mode=="base"
+ local realdimensions=properties.realdimensions
+ local writingmode=properties.writingmode or "horizontal"
+ local identity=properties.identity or "horizontal"
+ local vfonts=target.fonts
+ if vfonts and #vfonts>0 then
+ target.fonts=fastcopy(vfonts)
+ elseif isvirtual then
+ target.fonts={ { id=0 } }
+ end
+ if changed and not next(changed) then
+ changed=false
+ end
+ target.type=isvirtual and "virtual" or "real"
+ target.writingmode=writingmode=="vertical" and "vertical" or "horizontal"
+ target.identity=identity=="vertical" and "vertical" or "horizontal"
+ target.postprocessors=tfmdata.postprocessors
+ local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt
+ local targetspace=(parameters.space or parameters[2] or 0)*hdelta
+ local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta
+ local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta
+ local targetx_height=(parameters.x_height or parameters[5] or 0)*vdelta
+ local targetquad=(parameters.quad or parameters[6] or 0)*hdelta
+ local targetextra_space=(parameters.extra_space or parameters[7] or 0)*hdelta
+ targetparameters.slant=targetslant
+ targetparameters.space=targetspace
+ targetparameters.space_stretch=targetspace_stretch
+ targetparameters.space_shrink=targetspace_shrink
+ targetparameters.x_height=targetx_height
+ targetparameters.quad=targetquad
+ targetparameters.extra_space=targetextra_space
+ local ascender=parameters.ascender
+ if ascender then
+ targetparameters.ascender=delta*ascender
+ end
+ local descender=parameters.descender
+ if descender then
+ targetparameters.descender=delta*descender
+ end
+ constructors.enhanceparameters(targetparameters)
+ local protrusionfactor=(targetquad~=0 and 1000/targetquad) or 0
+ local scaledwidth=defaultwidth*hdelta
+ local scaledheight=defaultheight*vdelta
+ local scaleddepth=defaultdepth*vdelta
+ local hasmath=(properties.hasmath or next(mathparameters)) and true
+ if hasmath then
+ constructors.assignmathparameters(target,tfmdata)
+ properties.hasmath=true
+ target.nomath=false
+ target.MathConstants=target.mathparameters
+ else
+ properties.hasmath=false
+ target.nomath=true
+ target.mathparameters=nil
+ end
+ if hasmath then
+ local mathitalics=properties.mathitalics
+ if mathitalics==false then
+ if trace_defining then
+ report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename)
+ end
+ hasitalics=false
+ autoitalicamount=false
+ end
+ else
+ local textitalics=properties.textitalics
+ if textitalics==false then
+ if trace_defining then
+ report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename)
+ end
+ hasitalics=false
+ autoitalicamount=false
+ end
+ end
+ if trace_defining then
+ report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a",
+ name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta,
+ hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled")
+ end
+ constructors.beforecopyingcharacters(target,tfmdata)
+ local sharedkerns={}
+ for unicode,character in next,characters do
+ local chr,description,index
+ if changed then
+ local c=changed[unicode]
+ if c and c~=unicode then
+ if c then
+ description=descriptions[c] or descriptions[unicode] or character
+ character=characters[c] or character
+ index=description.index or c
+ else
+ description=descriptions[unicode] or character
+ index=description.index or unicode
+ end
+ else
+ description=descriptions[unicode] or character
+ index=description.index or unicode
+ end
+ else
+ description=descriptions[unicode] or character
+ index=description.index or unicode
+ end
+ local width=description.width
+ local height=description.height
+ local depth=description.depth
+ local isunicode=description.unicode
+ if realdimensions then
+ if not height or height==0 then
+ local bb=description.boundingbox
+ local ht=bb[4]
+ if ht~=0 then
+ height=ht
+ end
+ if not depth or depth==0 then
+ local dp=-bb[2]
+ if dp~=0 then
+ depth=dp
+ end
+ end
+ elseif not depth or depth==0 then
+ local dp=-description.boundingbox[2]
+ if dp~=0 then
+ depth=dp
+ end
+ end
+ end
+ if width then width=hdelta*width else width=scaledwidth end
+ if height then height=vdelta*height else height=scaledheight end
+ if depth and depth~=0 then
+ depth=delta*depth
+ if isunicode then
+ chr={
+ index=index,
+ height=height,
+ depth=depth,
+ width=width,
+ unicode=isunicode,
+ }
+ else
+ chr={
+ index=index,
+ height=height,
+ depth=depth,
+ width=width,
+ }
+ end
+ else
+ if isunicode then
+ chr={
+ index=index,
+ height=height,
+ width=width,
+ unicode=isunicode,
+ }
+ else
+ chr={
+ index=index,
+ height=height,
+ width=width,
+ }
+ end
+ end
+ if addtounicode then
+ chr.tounicode=isunicode and tounicode(isunicode) or unknowncode
+ end
+ if hasquality then
+ local ve=character.expansion_factor
+ if ve then
+ chr.expansion_factor=ve*1000
+ end
+ local vl=character.left_protruding
+ if vl then
+ chr.left_protruding=protrusionfactor*width*vl
+ end
+ local vr=character.right_protruding
+ if vr then
+ chr.right_protruding=protrusionfactor*width*vr
+ end
+ end
+ if hasmath then
+ local vn=character.next
+ if vn then
+ chr.next=vn
+ else
+ local vv=character.vert_variants
+ if vv then
+ local t={}
+ for i=1,#vv do
+ local vvi=vv[i]
+ local s=vvi["start"] or 0
+ local e=vvi["end"] or 0
+ local a=vvi["advance"] or 0
+ t[i]={
+ ["start"]=s==0 and 0 or s*vdelta,
+ ["end"]=e==0 and 0 or e*vdelta,
+ ["advance"]=a==0 and 0 or a*vdelta,
+ ["extender"]=vvi["extender"],
+ ["glyph"]=vvi["glyph"],
+ }
+ end
+ chr.vert_variants=t
+ else
+ local hv=character.horiz_variants
+ if hv then
+ local t={}
+ for i=1,#hv do
+ local hvi=hv[i]
+ local s=hvi["start"] or 0
+ local e=hvi["end"] or 0
+ local a=hvi["advance"] or 0
+ t[i]={
+ ["start"]=s==0 and 0 or s*hdelta,
+ ["end"]=e==0 and 0 or e*hdelta,
+ ["advance"]=a==0 and 0 or a*hdelta,
+ ["extender"]=hvi["extender"],
+ ["glyph"]=hvi["glyph"],
+ }
+ end
+ chr.horiz_variants=t
+ end
+ end
+ end
+ local vi=character.vert_italic
+ if vi and vi~=0 then
+ chr.vert_italic=vi*hdelta
+ end
+ local va=character.accent
+ if va then
+ chr.top_accent=vdelta*va
+ end
+ if stackmath then
+ local mk=character.mathkerns
+ if mk then
+ local tr=mk.topright
+ local tl=mk.topleft
+ local br=mk.bottomright
+ local bl=mk.bottomleft
+ chr.mathkern={
+ top_right=tr and mathkerns(tr,vdelta) or nil,
+ top_left=tl and mathkerns(tl,vdelta) or nil,
+ bottom_right=br and mathkerns(br,vdelta) or nil,
+ bottom_left=bl and mathkerns(bl,vdelta) or nil,
+ }
+ end
+ end
+ if hasitalics then
+ local vi=character.italic
+ if vi and vi~=0 then
+ chr.italic=vi*hdelta
+ end
+ end
+ elseif autoitalicamount then
+ local vi=description.italic
+ if not vi then
+ local bb=description.boundingbox
+ if bb then
+ local vi=bb[3]-description.width+autoitalicamount
+ if vi>0 then
+ chr.italic=vi*hdelta
+ end
+ else
+ end
+ elseif vi~=0 then
+ chr.italic=vi*hdelta
+ end
+ elseif hasitalics then
+ local vi=character.italic
+ if vi and vi~=0 then
+ chr.italic=vi*hdelta
+ end
+ end
+ if haskerns then
+ local vk=character.kerns
+ if vk then
+ local s=sharedkerns[vk]
+ if not s then
+ s={}
+ for k,v in next,vk do s[k]=v*hdelta end
+ sharedkerns[vk]=s
+ end
+ chr.kerns=s
+ end
+ end
+ if hasligatures then
+ local vl=character.ligatures
+ if vl then
+ if true then
+ chr.ligatures=vl
+ else
+ local tt={}
+ for i,l in next,vl do
+ tt[i]=l
+ end
+ chr.ligatures=tt
+ end
+ end
+ end
+ if isvirtual then
+ local vc=character.commands
+ if vc then
+ local ok=false
+ for i=1,#vc do
+ local key=vc[i][1]
+ if key=="right" or key=="down" or key=="rule" then
+ ok=true
+ break
+ end
+ end
+ if ok then
+ local tt={}
+ for i=1,#vc do
+ local ivc=vc[i]
+ local key=ivc[1]
+ if key=="right" then
+ tt[i]={ key,ivc[2]*hdelta }
+ elseif key=="down" then
+ tt[i]={ key,ivc[2]*vdelta }
+ elseif key=="rule" then
+ tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta }
+ else
+ tt[i]=ivc
+ end
+ end
+ chr.commands=tt
+ else
+ chr.commands=vc
+ end
+ end
+ end
+ targetcharacters[unicode]=chr
+ end
+ properties.setitalics=hasitalics
+ constructors.aftercopyingcharacters(target,tfmdata)
+ constructors.trytosharefont(target,tfmdata)
+ local vfonts=target.fonts
+ if isvirtual or target.type=="virtual" or properties.virtualized then
+ properties.virtualized=true
+ target.type="virtual"
+ if not vfonts or #vfonts==0 then
+ target.fonts={ { id=0 } }
+ end
+ elseif vfonts then
+ properties.virtualized=true
+ target.type="virtual"
+ if #vfonts==0 then
+ target.fonts={ { id=0 } }
+ end
+ end
+ return target
+end
+function constructors.finalize(tfmdata)
+ if tfmdata.properties and tfmdata.properties.finalized then
+ return
+ end
+ if not tfmdata.characters then
+ return nil
+ end
+ if not tfmdata.goodies then
+ tfmdata.goodies={}
+ end
+ local parameters=tfmdata.parameters
+ if not parameters then
+ return nil
+ end
+ if not parameters.expansion then
+ parameters.expansion={
+ stretch=tfmdata.stretch or 0,
+ shrink=tfmdata.shrink or 0,
+ step=tfmdata.step or 0,
+ }
+ end
+ if not parameters.size then
+ parameters.size=tfmdata.size
+ end
+ if not parameters.mode then
+ parameters.mode=0
+ end
+ if not parameters.width then
+ parameters.width=0
+ end
+ if not parameters.slantfactor then
+ parameters.slantfactor=(tfmdata.slant or 0)/1000
+ end
+ if not parameters.extendfactor then
+ parameters.extendfactor=(tfmdata.extend or 1000)/1000
+ end
+ if not parameters.squeezefactor then
+ parameters.squeezefactor=(tfmdata.squeeze or 1000)/1000
+ end
+ local designsize=parameters.designsize
+ if designsize then
+ parameters.minsize=tfmdata.minsize or designsize
+ parameters.maxsize=tfmdata.maxsize or designsize
+ else
+ designsize=factors.pt*10
+ parameters.designsize=designsize
+ parameters.minsize=designsize
+ parameters.maxsize=designsize
+ end
+ parameters.minsize=tfmdata.minsize or parameters.designsize
+ parameters.maxsize=tfmdata.maxsize or parameters.designsize
+ if not parameters.units then
+ parameters.units=tfmdata.units or tfmdata.units_per_em or 1000
+ end
+ if not tfmdata.descriptions then
+ local descriptions={}
+ setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end)
+ tfmdata.descriptions=descriptions
+ end
+ local properties=tfmdata.properties
+ if not properties then
+ properties={}
+ tfmdata.properties=properties
+ end
+ if not properties.virtualized then
+ properties.virtualized=tfmdata.type=="virtual"
+ end
+ properties.fontname=properties.fontname or tfmdata.fontname
+ properties.filename=properties.filename or tfmdata.filename
+ properties.fullname=properties.fullname or tfmdata.fullname
+ properties.name=properties.name or tfmdata.name
+ properties.psname=properties.psname or tfmdata.psname
+ properties.encodingbytes=tfmdata.encodingbytes or 1
+ properties.embedding=tfmdata.embedding or "subset"
+ properties.tounicode=tfmdata.tounicode or 1
+ properties.cidinfo=tfmdata.cidinfo or nil
+ properties.format=tfmdata.format or "type1"
+ properties.direction=tfmdata.direction or 0
+ properties.writingmode=tfmdata.writingmode or "horizontal"
+ properties.identity=tfmdata.identity or "horizontal"
+ properties.usedbitmap=tfmdata.usedbitmap
+ if not tfmdata.resources then
+ tfmdata.resources={}
+ end
+ if not tfmdata.shared then
+ tfmdata.shared={}
+ end
+ if not properties.hasmath then
+ properties.hasmath=not tfmdata.nomath
+ end
+ tfmdata.MathConstants=nil
+ tfmdata.postprocessors=nil
+ tfmdata.fontname=nil
+ tfmdata.filename=nil
+ tfmdata.fullname=nil
+ tfmdata.name=nil
+ tfmdata.psname=nil
+ tfmdata.encodingbytes=nil
+ tfmdata.embedding=nil
+ tfmdata.tounicode=nil
+ tfmdata.cidinfo=nil
+ tfmdata.format=nil
+ tfmdata.direction=nil
+ tfmdata.type=nil
+ tfmdata.nomath=nil
+ tfmdata.designsize=nil
+ tfmdata.size=nil
+ tfmdata.stretch=nil
+ tfmdata.shrink=nil
+ tfmdata.step=nil
+ tfmdata.slant=nil
+ tfmdata.extend=nil
+ tfmdata.squeeze=nil
+ tfmdata.mode=nil
+ tfmdata.width=nil
+ tfmdata.units=nil
+ tfmdata.units_per_em=nil
+ tfmdata.cache=nil
+ properties.finalized=true
+ return tfmdata
+end
+local hashmethods={}
+constructors.hashmethods=hashmethods
+function constructors.hashfeatures(specification)
+ local features=specification.features
+ if features then
+ local t,n={},0
+ for category,list in sortedhash(features) do
+ if next(list) then
+ local hasher=hashmethods[category]
+ if hasher then
+ local hash=hasher(list)
+ if hash then
+ n=n+1
+ t[n]=category..":"..hash
+ end
+ end
+ end
+ end
+ if n>0 then
+ return concat(t," & ")
+ end
+ end
+ return "unknown"
+end
+hashmethods.normal=function(list)
+ local s={}
+ local n=0
+ for k,v in next,list do
+ if not k then
+ elseif k=="number" or k=="features" then
+ else
+ n=n+1
+ if type(v)=="table" then
+ local t={}
+ local m=0
+ for k,v in next,v do
+ m=m+1
+ t[m]=k..'='..tostring(v)
+ end
+ s[n]=k..'={'..concat(t,",").."}"
+ else
+ s[n]=k..'='..tostring(v)
+ end
+ end
+ end
+ if n>0 then
+ sort(s)
+ return concat(s,"+")
+ end
+end
+function constructors.hashinstance(specification,force)
+ local hash=specification.hash
+ local size=specification.size
+ local fallbacks=specification.fallbacks
+ if force or not hash then
+ hash=constructors.hashfeatures(specification)
+ specification.hash=hash
+ end
+ if size<1000 and designsizes[hash] then
+ size=round(constructors.scaled(size,designsizes[hash]))
+ else
+ size=round(size)
+ end
+ specification.size=size
+ if fallbacks then
+ return hash..' @ '..size..' @ '..fallbacks
+ else
+ return hash..' @ '..size
+ end
+end
+function constructors.setname(tfmdata,specification)
+ if constructors.namemode=="specification" then
+ local specname=specification.specification
+ if specname then
+ tfmdata.properties.name=specname
+ if trace_defining then
+ report_otf("overloaded fontname %a",specname)
+ end
+ end
+ end
+end
+function constructors.checkedfilename(data)
+ local foundfilename=data.foundfilename
+ if not foundfilename then
+ local askedfilename=data.filename or ""
+ if askedfilename~="" then
+ askedfilename=resolvers.resolve(askedfilename)
+ foundfilename=resolvers.findbinfile(askedfilename,"") or ""
+ if foundfilename=="" then
+ report_defining("source file %a is not found",askedfilename)
+ foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or ""
+ if foundfilename~="" then
+ report_defining("using source file %a due to cache mismatch",foundfilename)
+ end
+ end
+ end
+ data.foundfilename=foundfilename
+ end
+ return foundfilename
+end
+local formats=allocate()
+fonts.formats=formats
+setmetatableindex(formats,function(t,k)
+ local l=lower(k)
+ if rawget(t,k) then
+ t[k]=l
+ return l
+ end
+ return rawget(t,file.suffix(l))
+end)
+do
+ local function setindeed(mode,source,target,group,name,position)
+ local action=source[mode]
+ if not action then
+ return
+ end
+ local t=target[mode]
+ if not t then
+ report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode)
+ os.exit()
+ elseif position then
+ insert(t,position,{ name=name,action=action })
+ else
+ for i=1,#t do
+ local ti=t[i]
+ if ti.name==name then
+ ti.action=action
+ return
+ end
+ end
+ insert(t,{ name=name,action=action })
+ end
+ end
+ local function set(group,name,target,source)
+ target=target[group]
+ if not target then
+ report_defining("fatal target error in setting feature %a, group %a",name,group)
+ os.exit()
+ end
+ local source=source[group]
+ if not source then
+ report_defining("fatal source error in setting feature %a, group %a",name,group)
+ os.exit()
+ end
+ local position=source.position
+ setindeed("node",source,target,group,name,position)
+ setindeed("base",source,target,group,name,position)
+ setindeed("plug",source,target,group,name,position)
+ end
+ local function register(where,specification)
+ local name=specification.name
+ if name and name~="" then
+ local default=specification.default
+ local description=specification.description
+ local initializers=specification.initializers
+ local processors=specification.processors
+ local manipulators=specification.manipulators
+ local modechecker=specification.modechecker
+ if default then
+ where.defaults[name]=default
+ end
+ if description and description~="" then
+ where.descriptions[name]=description
+ end
+ if initializers then
+ set('initializers',name,where,specification)
+ end
+ if processors then
+ set('processors',name,where,specification)
+ end
+ if manipulators then
+ set('manipulators',name,where,specification)
+ end
+ if modechecker then
+ where.modechecker=modechecker
+ end
+ end
+ end
+ constructors.registerfeature=register
+ function constructors.getfeatureaction(what,where,mode,name)
+ what=handlers[what].features
+ if what then
+ where=what[where]
+ if where then
+ mode=where[mode]
+ if mode then
+ for i=1,#mode do
+ local m=mode[i]
+ if m.name==name then
+ return m.action
+ end
+ end
+ end
+ end
+ end
+ end
+ local newfeatures={}
+ constructors.newfeatures=newfeatures
+ constructors.features=newfeatures
+ local function setnewfeatures(what)
+ local handler=handlers[what]
+ local features=handler.features
+ if not features then
+ local tables=handler.tables
+ local statistics=handler.statistics
+ features=allocate {
+ defaults={},
+ descriptions=tables and tables.features or {},
+ used=statistics and statistics.usedfeatures or {},
+ initializers={ base={},node={},plug={} },
+ processors={ base={},node={},plug={} },
+ manipulators={ base={},node={},plug={} },
+ }
+ features.register=function(specification) return register(features,specification) end
+ handler.features=features
+ end
+ return features
+ end
+ setmetatable(newfeatures,{
+ __call=function(t,k) local v=t[k] return v end,
+ __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end,
+ })
+end
+do
+ local newhandler={}
+ constructors.handlers=newhandler
+ constructors.newhandler=newhandler
+ local function setnewhandler(what)
+ local handler=handlers[what]
+ if not handler then
+ handler={}
+ handlers[what]=handler
+ end
+ return handler
+ end
+ setmetatable(newhandler,{
+ __call=function(t,k) local v=t[k] return v end,
+ __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end,
+ })
+end
+do
+ local newenhancer={}
+ constructors.enhancers=newenhancer
+ constructors.newenhancer=newenhancer
+ local function setnewenhancer(format)
+ local handler=handlers[format]
+ local enhancers=handler.enhancers
+ if not enhancers then
+ local actions=allocate()
+ local before=allocate()
+ local after=allocate()
+ local order=allocate()
+ local known={}
+ local nofsteps=0
+ local patches={ before=before,after=after }
+ local trace=false
+ local report=logs.reporter("fonts",format.." enhancing")
+ trackers.register(format..".loading",function(v) trace=v end)
+ local function enhance(name,data,filename,raw)
+ local enhancer=actions[name]
+ if enhancer then
+ if trace then
+ report("apply enhancement %a to file %a",name,filename)
+ ioflush()
+ end
+ enhancer(data,filename,raw)
+ else
+ end
+ end
+ local function apply(data,filename,raw)
+ local basename=file.basename(lower(filename))
+ if trace then
+ report("%s enhancing file %a","start",filename)
+ end
+ ioflush()
+ for e=1,nofsteps do
+ local enhancer=order[e]
+ local b=before[enhancer]
+ if b then
+ for pattern,action in next,b do
+ if find(basename,pattern) then
+ action(data,filename,raw)
+ end
+ end
+ end
+ enhance(enhancer,data,filename,raw)
+ local a=after[enhancer]
+ if a then
+ for pattern,action in next,a do
+ if find(basename,pattern) then
+ action(data,filename,raw)
+ end
+ end
+ end
+ ioflush()
+ end
+ if trace then
+ report("%s enhancing file %a","stop",filename)
+ end
+ ioflush()
+ end
+ local function register(what,action)
+ if action then
+ if actions[what] then
+ else
+ nofsteps=nofsteps+1
+ order[nofsteps]=what
+ known[what]=nofsteps
+ end
+ actions[what]=action
+ else
+ report("bad enhancer %a",what)
+ end
+ end
+ local function patch(what,where,pattern,action)
+ local pw=patches[what]
+ if pw then
+ local ww=pw[where]
+ if ww then
+ ww[pattern]=action
+ else
+ pw[where]={ [pattern]=action }
+ if not known[where] then
+ nofsteps=nofsteps+1
+ order[nofsteps]=where
+ known[where]=nofsteps
+ end
+ end
+ end
+ end
+ enhancers={
+ register=register,
+ apply=apply,
+ patch=patch,
+ report=report,
+ patches={
+ register=patch,
+ report=report,
+ },
+ }
+ handler.enhancers=enhancers
+ end
+ return enhancers
+ end
+ setmetatable(newenhancer,{
+ __call=function(t,k) local v=t[k] return v end,
+ __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end,
+ })
+end
+function constructors.checkedfeatures(what,features)
+ local defaults=handlers[what].features.defaults
+ if features and next(features) then
+ features=fastcopy(features)
+ for key,value in next,defaults do
+ if features[key]==nil then
+ features[key]=value
+ end
+ end
+ return features
+ else
+ return fastcopy(defaults)
+ end
+end
+function constructors.initializefeatures(what,tfmdata,features,trace,report)
+ if features and next(features) then
+ local properties=tfmdata.properties or {}
+ local whathandler=handlers[what]
+ local whatfeatures=whathandler.features
+ local whatmodechecker=whatfeatures.modechecker
+ local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base"
+ properties.mode=mode
+ features.mode=mode
+ local done={}
+ while true do
+ local redo=false
+ local initializers=whatfeatures.initializers[mode]
+ if initializers then
+ for i=1,#initializers do
+ local step=initializers[i]
+ local feature=step.name
+ local value=features[feature]
+ if not value then
+ elseif done[feature] then
+ else
+ local action=step.action
+ if trace then
+ report("initializing feature %a to %a for mode %a for font %a",feature,
+ value,mode,tfmdata.properties.fullname)
+ end
+ action(tfmdata,value,features)
+ if mode~=properties.mode or mode~=features.mode then
+ if whatmodechecker then
+ properties.mode=whatmodechecker(tfmdata,features,properties.mode)
+ features.mode=properties.mode
+ end
+ if mode~=properties.mode then
+ mode=properties.mode
+ redo=true
+ end
+ end
+ done[feature]=true
+ end
+ if redo then
+ break
+ end
+ end
+ if not redo then
+ break
+ end
+ else
+ break
+ end
+ end
+ properties.mode=mode
+ return true
+ else
+ return false
+ end
+end
+function constructors.collectprocessors(what,tfmdata,features,trace,report)
+ local processes={}
+ local nofprocesses=0
+ if features and next(features) then
+ local properties=tfmdata.properties
+ local whathandler=handlers[what]
+ local whatfeatures=whathandler.features
+ local whatprocessors=whatfeatures.processors
+ local mode=properties.mode
+ local processors=whatprocessors[mode]
+ if processors then
+ for i=1,#processors do
+ local step=processors[i]
+ local feature=step.name
+ if features[feature] then
+ local action=step.action
+ if trace then
+ report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname)
+ end
+ if action then
+ nofprocesses=nofprocesses+1
+ processes[nofprocesses]=action
+ end
+ end
+ end
+ elseif trace then
+ report("no feature processors for mode %a for font %a",mode,properties.fullname)
+ end
+ end
+ return processes
+end
+function constructors.applymanipulators(what,tfmdata,features,trace,report)
+ if features and next(features) then
+ local properties=tfmdata.properties
+ local whathandler=handlers[what]
+ local whatfeatures=whathandler.features
+ local whatmanipulators=whatfeatures.manipulators
+ local mode=properties.mode
+ local manipulators=whatmanipulators[mode]
+ if manipulators then
+ for i=1,#manipulators do
+ local step=manipulators[i]
+ local feature=step.name
+ local value=features[feature]
+ if value then
+ local action=step.action
+ if trace then
+ report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname)
+ end
+ if action then
+ action(tfmdata,feature,value)
+ end
+ end
+ end
+ end
+ end
+end
+function constructors.addcoreunicodes(unicodes)
+ if not unicodes then
+ unicodes={}
+ end
+ unicodes.space=0x0020
+ unicodes.hyphen=0x002D
+ unicodes.zwj=0x200D
+ unicodes.zwnj=0x200C
+ return unicodes
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['luatex-font-enc']={
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+--removed
+
+end
+local fonts=fonts
+local encodings={}
+fonts.encodings=encodings
+encodings.agl={}
+encodings.known={}
+setmetatable(encodings.agl,{ __index=function(t,k)
+ if k=="unicodes" then
+ logs.report("fonts","loading (extended) adobe glyph list")
+ local unicodes=dofile(resolvers.findfile("font-age.lua"))
+ encodings.agl={ unicodes=unicodes }
+ return unicodes
+ else
+ return nil
+ end
+end })
+encodings.cache=containers.define("fonts","enc",encodings.version,true)
+function encodings.load(filename)
+ local name=file.removesuffix(filename)
+ local data=containers.read(encodings.cache,name)
+ if data then
+ return data
+ end
+ local vector,tag,hash,unicodes={},"",{},{}
+ local foundname=resolvers.findfile(filename,'enc')
+ if foundname and foundname~="" then
+ local ok,encoding,size=resolvers.loadbinfile(foundname)
+ if ok and encoding then
+ encoding=string.gsub(encoding,"%%(.-)\n","")
+ local unicoding=encodings.agl.unicodes
+ local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def")
+ local i=0
+ for ch in string.gmatch(vec,"/([%a%d%.]+)") do
+ if ch~=".notdef" then
+ vector[i]=ch
+ if not hash[ch] then
+ hash[ch]=i
+ else
+ end
+ local u=unicoding[ch]
+ if u then
+ unicodes[u]=i
+ end
+ end
+ i=i+1
+ end
+ end
+ end
+ local data={
+ name=name,
+ tag=tag,
+ vector=vector,
+ hash=hash,
+ unicodes=unicodes
+ }
+ return containers.write(encodings.cache,name,data)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-cid']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local format,match,lower=string.format,string.match,string.lower
+local tonumber=tonumber
+local P,S,R,C,V,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.match
+local fonts,logs,trackers=fonts,logs,trackers
+local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
+local report_otf=logs.reporter("fonts","otf loading")
+local cid={}
+fonts.cid=cid
+local cidmap={}
+local cidmax=10
+local number=C(R("09","af","AF")^1)
+local space=S(" \n\r\t")
+local spaces=space^0
+local period=P(".")
+local periods=period*period
+local name=P("/")*C((1-space)^1)
+local unicodes,names={},{}
+local function do_one(a,b)
+ unicodes[tonumber(a)]=tonumber(b,16)
+end
+local function do_range(a,b,c)
+ c=tonumber(c,16)
+ for i=tonumber(a),tonumber(b) do
+ unicodes[i]=c
+ c=c+1
+ end
+end
+local function do_name(a,b)
+ names[tonumber(a)]=b
+end
+local grammar=P { "start",
+ start=number*spaces*number*V("series"),
+ series=(spaces*(V("one")+V("range")+V("named")))^1,
+ one=(number*spaces*number)/do_one,
+ range=(number*periods*number*spaces*number)/do_range,
+ named=(number*spaces*name)/do_name
+}
+local function loadcidfile(filename)
+ local data=io.loaddata(filename)
+ if data then
+ unicodes,names={},{}
+ lpegmatch(grammar,data)
+ local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$")
+ return {
+ supplement=supplement,
+ registry=registry,
+ ordering=ordering,
+ filename=filename,
+ unicodes=unicodes,
+ names=names,
+ }
+ end
+end
+cid.loadfile=loadcidfile
+local template="%s-%s-%s.cidmap"
+local function locate(registry,ordering,supplement)
+ local filename=format(template,registry,ordering,supplement)
+ local hashname=lower(filename)
+ local found=cidmap[hashname]
+ if not found then
+ if trace_loading then
+ report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename)
+ end
+ local fullname=resolvers.findfile(filename,'cid') or ""
+ if fullname~="" then
+ found=loadcidfile(fullname)
+ if found then
+ if trace_loading then
+ report_otf("using cidmap file %a",filename)
+ end
+ cidmap[hashname]=found
+ found.usedname=file.basename(filename)
+ end
+ end
+ end
+ return found
+end
+function cid.getmap(specification)
+ if not specification then
+ report_otf("invalid cidinfo specification, table expected")
+ return
+ end
+ local registry=specification.registry
+ local ordering=specification.ordering
+ local supplement=specification.supplement
+ local filename=format(registry,ordering,supplement)
+ local lowername=lower(filename)
+ local found=cidmap[lowername]
+ if found then
+ return found
+ end
+ if ordering=="Identity" then
+ local found={
+ supplement=supplement,
+ registry=registry,
+ ordering=ordering,
+ filename=filename,
+ unicodes={},
+ names={},
+ }
+ cidmap[lowername]=found
+ return found
+ end
+ if trace_loading then
+ report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement)
+ end
+ found=locate(registry,ordering,supplement)
+ if not found then
+ local supnum=tonumber(supplement)
+ local cidnum=nil
+ if supnum<cidmax then
+ for s=supnum+1,cidmax do
+ local c=locate(registry,ordering,s)
+ if c then
+ found,cidnum=c,s
+ break
+ end
+ end
+ end
+ if not found and supnum>0 then
+ for s=supnum-1,0,-1 do
+ local c=locate(registry,ordering,s)
+ if c then
+ found,cidnum=c,s
+ break
+ end
+ end
+ end
+ registry=lower(registry)
+ ordering=lower(ordering)
+ if found and cidnum>0 then
+ for s=0,cidnum-1 do
+ local filename=format(template,registry,ordering,s)
+ if not cidmap[filename] then
+ cidmap[filename]=found
+ end
+ end
+ end
+ end
+ return found
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-map']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local tonumber,next,type=tonumber,next,type
+local match,format,find,concat,gsub,lower=string.match,string.format,string.find,table.concat,string.gsub,string.lower
+local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match
+local formatters=string.formatters
+local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
+local rshift=bit32.rshift
+local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end)
+local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end)
+local report_fonts=logs.reporter("fonts","loading")
+local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end)
+local fonts=fonts or {}
+local mappings=fonts.mappings or {}
+fonts.mappings=mappings
+local allocate=utilities.storage.allocate
+local hex=R("AF","af","09")
+local hexfour=(hex*hex*hex^-2)/function(s) return tonumber(s,16) end
+local hexsix=(hex*hex*hex^-4)/function(s) return tonumber(s,16) end
+local dec=(R("09")^1)/tonumber
+local period=P(".")
+local unicode=(P("uni")+P("UNI"))*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true))
+local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true))
+local index=P("index")*dec*Cc(false)
+local parser=unicode+ucode+index
+local parsers={}
+local function makenameparser(str)
+ if not str or str=="" then
+ return parser
+ else
+ local p=parsers[str]
+ if not p then
+ p=P(str)*period*dec*Cc(false)
+ parsers[str]=p
+ end
+ return p
+ end
+end
+local f_single=formatters["%04X"]
+local f_double=formatters["%04X%04X"]
+local function tounicode16(unicode)
+ if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then
+ return f_single(unicode)
+ else
+ unicode=unicode-0x10000
+ return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+ end
+end
+local function tounicode16sequence(unicodes)
+ local t={}
+ for l=1,#unicodes do
+ local u=unicodes[l]
+ if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then
+ t[l]=f_single(u)
+ else
+ u=u-0x10000
+ t[l]=f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
+ end
+ end
+ return concat(t)
+end
+local unknown=f_single(0xFFFD)
+local hash={}
+local conc={}
+table.setmetatableindex(hash,function(t,k)
+ if k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then
+ v=f_single(k)
+ else
+ local k=k-0x10000
+ v=f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
+ end
+ t[k]=v
+ return v
+end)
+local function tounicode(k)
+ if type(k)=="table" then
+ local n=#k
+ for l=1,n do
+ conc[l]=hash[k[l]]
+ end
+ return concat(conc,"",1,n)
+ elseif k>=0x00E000 and k<=0x00F8FF then
+ return unknown
+ elseif k>=0x0F0000 and k<=0x0FFFFF then
+ return unknown
+ elseif k>=0x100000 and k<=0x10FFFF then
+ return unknown
+ else
+ return hash[k]
+ end
+end
+local function fromunicode16(str)
+ if #str==4 then
+ return tonumber(str,16)
+ else
+ local l,r=match(str,"(....)(....)")
+ return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00
+ end
+end
+mappings.makenameparser=makenameparser
+mappings.tounicode=tounicode
+mappings.tounicode16=tounicode16
+mappings.tounicode16sequence=tounicode16sequence
+mappings.fromunicode16=fromunicode16
+local ligseparator=P("_")
+local varseparator=P(".")
+local namesplitter=Ct(C((1-ligseparator-varseparator)^1)*(ligseparator*C((1-ligseparator-varseparator)^1))^0)
+do
+ local overloads={
+ IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 },
+ ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 },
+ ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 },
+ fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 },
+ fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 },
+ ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 },
+ ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 },
+ fj={ name="f_j",unicode={ 0x66,0x6A } },
+ fk={ name="f_k",unicode={ 0x66,0x6B } },
+ }
+ local o=allocate {}
+ for k,v in next,overloads do
+ local name=v.name
+ local mess=v.mess
+ if name then
+ o[name]=v
+ end
+ if mess then
+ o[mess]=v
+ end
+ o[k]=v
+ end
+ mappings.overloads=o
+end
+function mappings.addtounicode(data,filename,checklookups,forceligatures)
+ local resources=data.resources
+ local unicodes=resources.unicodes
+ if not unicodes then
+ if trace_mapping then
+ report_fonts("no unicode list, quitting tounicode for %a",filename)
+ end
+ return
+ end
+ local properties=data.properties
+ local descriptions=data.descriptions
+ local overloads=mappings.overloads
+ unicodes['space']=unicodes['space'] or 32
+ unicodes['hyphen']=unicodes['hyphen'] or 45
+ unicodes['zwj']=unicodes['zwj'] or 0x200D
+ unicodes['zwnj']=unicodes['zwnj'] or 0x200C
+ local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+ local unicodevector=fonts.encodings.agl.unicodes or {}
+ local contextvector=fonts.encodings.agl.ctxcodes or {}
+ local missing={}
+ local nofmissing=0
+ local oparser=nil
+ local cidnames=nil
+ local cidcodes=nil
+ local cidinfo=properties.cidinfo
+ local usedmap=cidinfo and fonts.cid.getmap(cidinfo)
+ local uparser=makenameparser()
+ if usedmap then
+ oparser=usedmap and makenameparser(cidinfo.ordering)
+ cidnames=usedmap.names
+ cidcodes=usedmap.unicodes
+ end
+ local ns=0
+ local nl=0
+ local dlist=sortedkeys(descriptions)
+ for i=1,#dlist do
+ local du=dlist[i]
+ local glyph=descriptions[du]
+ local name=glyph.name
+ if name then
+ local overload=overloads[name] or overloads[du]
+ if overload then
+ glyph.unicode=overload.unicode
+ else
+ local gu=glyph.unicode
+ if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then
+ local unicode=unicodevector[name] or contextvector[name]
+ if unicode then
+ glyph.unicode=unicode
+ ns=ns+1
+ end
+ if (not unicode) and usedmap then
+ local foundindex=lpegmatch(oparser,name)
+ if foundindex then
+ unicode=cidcodes[foundindex]
+ if unicode then
+ glyph.unicode=unicode
+ ns=ns+1
+ else
+ local reference=cidnames[foundindex]
+ if reference then
+ local foundindex=lpegmatch(oparser,reference)
+ if foundindex then
+ unicode=cidcodes[foundindex]
+ if unicode then
+ glyph.unicode=unicode
+ ns=ns+1
+ end
+ end
+ if not unicode or unicode=="" then
+ local foundcodes,multiple=lpegmatch(uparser,reference)
+ if foundcodes then
+ glyph.unicode=foundcodes
+ if multiple then
+ nl=nl+1
+ unicode=true
+ else
+ ns=ns+1
+ unicode=foundcodes
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if not unicode or unicode=="" then
+ local split=lpegmatch(namesplitter,name)
+ local nsplit=split and #split or 0
+ if nsplit==0 then
+ elseif nsplit==1 then
+ local base=split[1]
+ local u=unicodes[base] or unicodevector[base] or contextvector[name]
+ if not u then
+ elseif type(u)=="table" then
+ if u[1]<private then
+ unicode=u
+ glyph.unicode=unicode
+ end
+ elseif u<private then
+ unicode=u
+ glyph.unicode=unicode
+ end
+ else
+ local t={}
+ local n=0
+ for l=1,nsplit do
+ local base=split[l]
+ local u=unicodes[base] or unicodevector[base] or contextvector[name]
+ if not u then
+ break
+ elseif type(u)=="table" then
+ if u[1]>=private then
+ break
+ end
+ n=n+1
+ t[n]=u[1]
+ else
+ if u>=private then
+ break
+ end
+ n=n+1
+ t[n]=u
+ end
+ end
+ if n>0 then
+ if n==1 then
+ unicode=t[1]
+ else
+ unicode=t
+ end
+ glyph.unicode=unicode
+ end
+ end
+ nl=nl+1
+ end
+ if not unicode or unicode=="" then
+ local foundcodes,multiple=lpegmatch(uparser,name)
+ if foundcodes then
+ glyph.unicode=foundcodes
+ if multiple then
+ nl=nl+1
+ unicode=true
+ else
+ ns=ns+1
+ unicode=foundcodes
+ end
+ end
+ end
+ local r=overloads[unicode]
+ if r then
+ unicode=r.unicode
+ glyph.unicode=unicode
+ end
+ if not unicode then
+ missing[du]=true
+ nofmissing=nofmissing+1
+ end
+ else
+ end
+ end
+ else
+ local overload=overloads[du]
+ if overload then
+ glyph.unicode=overload.unicode
+ elseif not glyph.unicode then
+ missing[du]=true
+ nofmissing=nofmissing+1
+ end
+ end
+ end
+ if type(checklookups)=="function" then
+ checklookups(data,missing,nofmissing)
+ end
+ local unicoded=0
+ local collected=fonts.handlers.otf.readers.getcomponents(data)
+ local function resolve(glyph,u)
+ local n=#u
+ for i=1,n do
+ if u[i]>private then
+ n=0
+ break
+ end
+ end
+ if n>0 then
+ if n>1 then
+ glyph.unicode=u
+ else
+ glyph.unicode=u[1]
+ end
+ unicoded=unicoded+1
+ end
+ end
+ if not collected then
+ elseif forceligatures or force_ligatures then
+ for i=1,#dlist do
+ local du=dlist[i]
+ if du>=private or (du>=0xE000 and du<=0xF8FF) then
+ local u=collected[du]
+ if u then
+ resolve(descriptions[du],u)
+ end
+ end
+ end
+ else
+ for i=1,#dlist do
+ local du=dlist[i]
+ if du>=private or (du>=0xE000 and du<=0xF8FF) then
+ local glyph=descriptions[du]
+ if glyph.class=="ligature" and not glyph.unicode then
+ local u=collected[du]
+ if u then
+ resolve(glyph,u)
+ end
+ end
+ end
+ end
+ end
+ if trace_mapping and unicoded>0 then
+ report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded)
+ end
+ if trace_mapping then
+ for i=1,#dlist do
+ local du=dlist[i]
+ local glyph=descriptions[du]
+ local name=glyph.name or "-"
+ local index=glyph.index or 0
+ local unicode=glyph.unicode
+ if unicode then
+ if type(unicode)=="table" then
+ local unicodes={}
+ for i=1,#unicode do
+ unicodes[i]=formatters("%U",unicode[i])
+ end
+ report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes)
+ else
+ report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode)
+ end
+ else
+ report_fonts("internal slot %U, name %a, unicode %U",index,name,du)
+ end
+ end
+ end
+ if trace_loading and (ns>0 or nl>0) then
+ report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns)
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['luatex-fonts-syn']={
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+--removed
+
+end
+local fonts=fonts
+fonts.names=fonts.names or {}
+fonts.names.version=1.001
+fonts.names.basename="luatex-fonts-names"
+fonts.names.cache=containers.define("fonts","data",fonts.names.version,true)
+local data=nil
+local loaded=false
+local fileformats={ "lua","tex","other text files" }
+function fonts.names.reportmissingbase()
+ logs.report("fonts","missing font database, run: mtxrun --script fonts --reload --simple")
+ fonts.names.reportmissingbase=nil
+end
+function fonts.names.reportmissingname()
+ logs.report("fonts","unknown font in font database, run: mtxrun --script fonts --reload --simple")
+ fonts.names.reportmissingname=nil
+end
+function fonts.names.resolve(name,sub)
+ if not loaded then
+ local basename=fonts.names.basename
+ if basename and basename~="" then
+ data=containers.read(fonts.names.cache,basename)
+ if not data then
+ basename=file.addsuffix(basename,"lua")
+ for i=1,#fileformats do
+ local format=fileformats[i]
+ local foundname=resolvers.findfile(basename,format) or ""
+ if foundname~="" then
+ data=dofile(foundname)
+ logs.report("fonts","font database '%s' loaded",foundname)
+ break
+ end
+ end
+ end
+ end
+ loaded=true
+ end
+ if type(data)=="table" and data.version==fonts.names.version then
+ local condensed=string.gsub(string.lower(name),"[^%a%d]","")
+ local found=data.mappings and data.mappings[condensed]
+ if found then
+ local fontname,filename,subfont=found[1],found[2],found[3]
+ if subfont then
+ return filename,fontname
+ else
+ return filename,false
+ end
+ elseif fonts.names.reportmissingname then
+ fonts.names.reportmissingname()
+ return name,false
+ end
+ elseif fonts.names.reportmissingbase then
+ fonts.names.reportmissingbase()
+ end
+end
+fonts.names.resolvespec=fonts.names.resolve
+function fonts.names.getfilename(askedname,suffix)
+ return ""
+end
+function fonts.names.ignoredfile(filename)
+ return false
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-vfc']={
+ version=1.001,
+ comment="companion to font-ini.mkiv and hand-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local select,type=select,type
+local insert=table.insert
+local fonts=fonts
+local helpers=fonts.helpers
+local setmetatableindex=table.setmetatableindex
+local makeweak=table.makeweak
+local push={ "push" }
+local pop={ "pop" }
+local dummy={ "comment" }
+function helpers.prependcommands(commands,...)
+ insert(commands,1,push)
+ for i=select("#",...),1,-1 do
+ local s=(select(i,...))
+ if s then
+ insert(commands,1,s)
+ end
+ end
+ insert(commands,pop)
+ return commands
+end
+function helpers.appendcommands(commands,...)
+ insert(commands,1,push)
+ insert(commands,pop)
+ for i=1,select("#",...) do
+ local s=(select(i,...))
+ if s then
+ insert(commands,s)
+ end
+ end
+ return commands
+end
+function helpers.prependcommandtable(commands,t)
+ insert(commands,1,push)
+ for i=#t,1,-1 do
+ local s=t[i]
+ if s then
+ insert(commands,1,s)
+ end
+ end
+ insert(commands,pop)
+ return commands
+end
+function helpers.appendcommandtable(commands,t)
+ insert(commands,1,push)
+ insert(commands,pop)
+ for i=1,#t do
+ local s=t[i]
+ if s then
+ insert(commands,s)
+ end
+ end
+ return commands
+end
+local char=setmetatableindex(function(t,k)
+ local v={ "slot",0,k }
+ t[k]=v
+ return v
+end)
+local right=setmetatableindex(function(t,k)
+ local v={ "right",k }
+ t[k]=v
+ return v
+end)
+local left=setmetatableindex(function(t,k)
+ local v={ "right",-k }
+ t[k]=v
+ return v
+end)
+local down=setmetatableindex(function(t,k)
+ local v={ "down",k }
+ t[k]=v
+ return v
+end)
+local up=setmetatableindex(function(t,k)
+ local v={ "down",-k }
+ t[k]=v
+ return v
+end)
+helpers.commands=utilities.storage.allocate {
+ char=char,
+ right=right,
+ left=left,
+ down=down,
+ up=up,
+ push=push,
+ pop=pop,
+ dummy=dummy,
+}
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-otr']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type,tonumber=next,type,tonumber
+local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub
+local fullstrip=string.fullstrip
+local floor,round=math.floor,math.round
+local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt
+local lpegmatch=lpeg.match
+local rshift=bit32.rshift
+local setmetatableindex=table.setmetatableindex
+local sortedkeys=table.sortedkeys
+local sortedhash=table.sortedhash
+local stripstring=string.nospaces
+local utf16_to_utf8_be=utf.utf16_to_utf8_be
+local report=logs.reporter("otf reader")
+local report_cmap=logs.reporter("otf reader","cmap")
+local trace_cmap=false trackers.register("otf.cmap",function(v) trace_cmap=v end)
+local trace_cmap_details=false trackers.register("otf.cmap.details",function(v) trace_cmap_details=v end)
+fonts=fonts or {}
+local handlers=fonts.handlers or {}
+fonts.handlers=handlers
+local otf=handlers.otf or {}
+handlers.otf=otf
+local readers=otf.readers or {}
+otf.readers=readers
+local streamreader=utilities.files
+local streamwriter=utilities.files
+readers.streamreader=streamreader
+readers.streamwriter=streamwriter
+local openfile=streamreader.open
+local closefile=streamreader.close
+local setposition=streamreader.setposition
+local skipshort=streamreader.skipshort
+local readbytes=streamreader.readbytes
+local readstring=streamreader.readstring
+local readbyte=streamreader.readcardinal1
+local readushort=streamreader.readcardinal2
+local readuint=streamreader.readcardinal3
+local readulong=streamreader.readcardinal4
+local readshort=streamreader.readinteger2
+local readlong=streamreader.readinteger4
+local readfixed=streamreader.readfixed4
+local read2dot14=streamreader.read2dot14
+local readfword=readshort
+local readufword=readushort
+local readoffset=readushort
+local readcardinaltable=streamreader.readcardinaltable
+local readintegertable=streamreader.readintegertable
+function streamreader.readtag(f)
+ return lower(stripstring(readstring(f,4)))
+end
+local short=2
+local ushort=2
+local ulong=4
+directives.register("fonts.streamreader",function()
+ streamreader=utilities.streams
+ openfile=streamreader.open
+ closefile=streamreader.close
+ setposition=streamreader.setposition
+ skipshort=streamreader.skipshort
+ readbytes=streamreader.readbytes
+ readstring=streamreader.readstring
+ readbyte=streamreader.readcardinal1
+ readushort=streamreader.readcardinal2
+ readuint=streamreader.readcardinal3
+ readulong=streamreader.readcardinal4
+ readshort=streamreader.readinteger2
+ readlong=streamreader.readinteger4
+ readfixed=streamreader.readfixed4
+ read2dot14=streamreader.read2dot14
+ readfword=readshort
+ readufword=readushort
+ readoffset=readushort
+ readcardinaltable=streamreader.readcardinaltable
+ readintegertable=streamreader.readintegertable
+ function streamreader.readtag(f)
+ return lower(stripstring(readstring(f,4)))
+ end
+end)
+local function readlongdatetime(f)
+ local a,b,c,d,e,f,g,h=readbytes(f,8)
+ return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+end
+local tableversion=0.004
+readers.tableversion=tableversion
+local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+local reservednames={ [0]="copyright",
+ "family",
+ "subfamily",
+ "uniqueid",
+ "fullname",
+ "version",
+ "postscriptname",
+ "trademark",
+ "manufacturer",
+ "designer",
+ "description",
+ "vendorurl",
+ "designerurl",
+ "license",
+ "licenseurl",
+ "reserved",
+ "typographicfamily",
+ "typographicsubfamily",
+ "compatiblefullname",
+ "sampletext",
+ "cidfindfontname",
+ "wwsfamily",
+ "wwssubfamily",
+ "lightbackgroundpalette",
+ "darkbackgroundpalette",
+ "variationspostscriptnameprefix",
+}
+local platforms={ [0]="unicode",
+ "macintosh",
+ "iso",
+ "windows",
+ "custom",
+}
+local encodings={
+ unicode={ [0]="unicode 1.0 semantics",
+ "unicode 1.1 semantics",
+ "iso/iec 10646",
+ "unicode 2.0 bmp",
+ "unicode 2.0 full",
+ "unicode variation sequences",
+ "unicode full repertoire",
+ },
+ macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian",
+ "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada",
+ "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian",
+ "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi",
+ "uninterpreted",
+ },
+ iso={ [0]="7-bit ascii",
+ "iso 10646",
+ "iso 8859-1",
+ },
+ windows={ [0]="symbol",
+ "unicode bmp",
+ "shiftjis",
+ "prc",
+ "big5",
+ "wansung",
+ "johab",
+ "reserved 7",
+ "reserved 8",
+ "reserved 9",
+ "unicode ucs-4",
+ },
+ custom={
+ }
+}
+local decoders={
+ unicode={},
+ macintosh={},
+ iso={},
+ windows={
+ ["unicode semantics"]=utf16_to_utf8_be,
+ ["unicode bmp"]=utf16_to_utf8_be,
+ ["unicode full"]=utf16_to_utf8_be,
+ ["unicode 1.0 semantics"]=utf16_to_utf8_be,
+ ["unicode 1.1 semantics"]=utf16_to_utf8_be,
+ ["unicode 2.0 bmp"]=utf16_to_utf8_be,
+ ["unicode 2.0 full"]=utf16_to_utf8_be,
+ ["unicode variation sequences"]=utf16_to_utf8_be,
+ ["unicode full repertoire"]=utf16_to_utf8_be,
+ },
+ custom={},
+}
+local languages={
+ unicode={
+ [ 0]="english",
+ },
+ macintosh={
+ [ 0]="english",
+ },
+ iso={},
+ windows={
+ [0x0409]="english - united states",
+ },
+ custom={},
+}
+local standardromanencoding={ [0]=
+ "notdef",".null","nonmarkingreturn","space","exclam","quotedbl",
+ "numbersign","dollar","percent","ampersand","quotesingle","parenleft",
+ "parenright","asterisk","plus","comma","hyphen","period","slash",
+ "zero","one","two","three","four","five","six","seven","eight",
+ "nine","colon","semicolon","less","equal","greater","question","at",
+ "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O",
+ "P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft",
+ "backslash","bracketright","asciicircum","underscore","grave","a","b",
+ "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q",
+ "r","s","t","u","v","w","x","y","z","braceleft","bar",
+ "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute",
+ "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex",
+ "adieresis","atilde","aring","ccedilla","eacute","egrave",
+ "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis",
+ "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute",
+ "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling",
+ "section","bullet","paragraph","germandbls","registered","copyright",
+ "trademark","acute","dieresis","notequal","AE","Oslash","infinity",
+ "plusminus","lessequal","greaterequal","yen","mu","partialdiff",
+ "summation","product","pi","integral","ordfeminine","ordmasculine",
+ "Omega","ae","oslash","questiondown","exclamdown","logicalnot",
+ "radical","florin","approxequal","Delta","guillemotleft",
+ "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde",
+ "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright",
+ "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis",
+ "fraction","currency","guilsinglleft","guilsinglright","fi","fl",
+ "daggerdbl","periodcentered","quotesinglbase","quotedblbase",
+ "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave",
+ "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex",
+ "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi",
+ "circumflex","tilde","macron","breve","dotaccent","ring","cedilla",
+ "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron",
+ "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn",
+ "thorn","minus","multiply","onesuperior","twosuperior","threesuperior",
+ "onehalf","onequarter","threequarters","franc","Gbreve","gbreve",
+ "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron",
+ "dcroat",
+}
+local weights={
+ [100]="thin",
+ [200]="extralight",
+ [300]="light",
+ [400]="normal",
+ [500]="medium",
+ [600]="semibold",
+ [700]="bold",
+ [800]="extrabold",
+ [900]="black",
+}
+local widths={
+ [1]="ultracondensed",
+ [2]="extracondensed",
+ [3]="condensed",
+ [4]="semicondensed",
+ [5]="normal",
+ [6]="semiexpanded",
+ [7]="expanded",
+ [8]="extraexpanded",
+ [9]="ultraexpanded",
+}
+setmetatableindex(weights,function(t,k)
+ local r=floor((k+50)/100)*100
+ local v=(r>900 and "black") or rawget(t,r) or "normal"
+ return v
+end)
+setmetatableindex(widths,function(t,k)
+ return "normal"
+end)
+local panoseweights={
+ [ 0]="normal",
+ [ 1]="normal",
+ [ 2]="verylight",
+ [ 3]="light",
+ [ 4]="thin",
+ [ 5]="book",
+ [ 6]="medium",
+ [ 7]="demi",
+ [ 8]="bold",
+ [ 9]="heavy",
+ [10]="black",
+}
+local panosewidths={
+ [ 0]="normal",
+ [ 1]="normal",
+ [ 2]="normal",
+ [ 3]="normal",
+ [ 4]="normal",
+ [ 5]="expanded",
+ [ 6]="condensed",
+ [ 7]="veryexpanded",
+ [ 8]="verycondensed",
+ [ 9]="monospaced",
+}
+local helpers={}
+readers.helpers=helpers
+local function gotodatatable(f,fontdata,tag,criterium)
+ if criterium and f then
+ local tables=fontdata.tables
+ if tables then
+ local datatable=tables[tag]
+ if datatable then
+ local tableoffset=datatable.offset
+ setposition(f,tableoffset)
+ return tableoffset
+ end
+ else
+ report("no tables")
+ end
+ end
+end
+local function reportskippedtable(f,fontdata,tag,criterium)
+ if criterium and f then
+ local tables=fontdata.tables
+ if tables then
+ local datatable=tables[tag]
+ if datatable then
+ report("loading of table %a skipped",tag)
+ end
+ else
+ report("no tables")
+ end
+ end
+end
+local function setvariabledata(fontdata,tag,data)
+ local variabledata=fontdata.variabledata
+ if variabledata then
+ variabledata[tag]=data
+ else
+ fontdata.variabledata={ [tag]=data }
+ end
+end
+helpers.gotodatatable=gotodatatable
+helpers.setvariabledata=setvariabledata
+helpers.reportskippedtable=reportskippedtable
+local platformnames={
+ postscriptname=true,
+ fullname=true,
+ family=true,
+ subfamily=true,
+ typographicfamily=true,
+ typographicsubfamily=true,
+ compatiblefullname=true,
+}
+local platformextras={
+ uniqueid=true,
+ version=true,
+ copyright=true,
+ license=true,
+ licenseurl=true,
+ manufacturer=true,
+ vendorurl=true,
+}
+function readers.name(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"name",true)
+ if tableoffset then
+ local format=readushort(f)
+ local nofnames=readushort(f)
+ local offset=readushort(f)
+ local start=tableoffset+offset
+ local namelists={
+ unicode={},
+ windows={},
+ macintosh={},
+ }
+ for i=1,nofnames do
+ local platform=platforms[readushort(f)]
+ if platform then
+ local namelist=namelists[platform]
+ if namelist then
+ local encoding=readushort(f)
+ local language=readushort(f)
+ local encodings=encodings[platform]
+ local languages=languages[platform]
+ if encodings and languages then
+ local encoding=encodings[encoding]
+ local language=languages[language]
+ if encoding and language then
+ local index=readushort(f)
+ local name=reservednames[index]
+ namelist[#namelist+1]={
+ platform=platform,
+ encoding=encoding,
+ language=language,
+ name=name,
+ index=index,
+ length=readushort(f),
+ offset=start+readushort(f),
+ }
+ else
+ skipshort(f,3)
+ end
+ else
+ skipshort(f,3)
+ end
+ else
+ skipshort(f,5)
+ end
+ else
+ skipshort(f,5)
+ end
+ end
+ local names={}
+ local done={}
+ local extras={}
+ local function decoded(platform,encoding,content)
+ local decoder=decoders[platform]
+ if decoder then
+ decoder=decoder[encoding]
+ end
+ if decoder then
+ return decoder(content)
+ else
+ return content
+ end
+ end
+ local function filter(platform,e,l)
+ local namelist=namelists[platform]
+ for i=1,#namelist do
+ local name=namelist[i]
+ local nametag=name.name
+ local index=name.index
+ if not done[nametag or i] then
+ local encoding=name.encoding
+ local language=name.language
+ if (not e or encoding==e) and (not l or language==l) then
+ setposition(f,name.offset)
+ local content=decoded(platform,encoding,readstring(f,name.length))
+ if nametag then
+ names[nametag]={
+ content=content,
+ platform=platform,
+ encoding=encoding,
+ language=language,
+ }
+ end
+ extras[index]=content
+ done[nametag or i]=true
+ end
+ end
+ end
+ end
+ filter("windows","unicode bmp","english - united states")
+ filter("macintosh","roman","english")
+ filter("windows")
+ filter("macintosh")
+ filter("unicode")
+ fontdata.names=names
+ fontdata.extras=extras
+ if specification.platformnames then
+ local collected={}
+ local platformextras=specification.platformextras and platformextras
+ for platform,namelist in next,namelists do
+ local filtered=false
+ for i=1,#namelist do
+ local entry=namelist[i]
+ local name=entry.name
+ if platformnames[name] or (platformextras and platformextras[name]) then
+ setposition(f,entry.offset)
+ local content=decoded(platform,entry.encoding,readstring(f,entry.length))
+ if filtered then
+ filtered[name]=content
+ else
+ filtered={ [name]=content }
+ end
+ end
+ end
+ if filtered then
+ collected[platform]=filtered
+ end
+ end
+ fontdata.platformnames=collected
+ end
+ else
+ fontdata.names={}
+ end
+end
+local validutf=lpeg.patterns.validutf8
+local function getname(fontdata,key)
+ local names=fontdata.names
+ if names then
+ local value=names[key]
+ if value then
+ local content=value.content
+ return lpegmatch(validutf,content) and content or nil
+ end
+ end
+end
+readers["os/2"]=function(f,fontdata)
+ local tableoffset=gotodatatable(f,fontdata,"os/2",true)
+ if tableoffset then
+ local version=readushort(f)
+ local windowsmetrics={
+ version=version,
+ averagewidth=readshort(f),
+ weightclass=readushort(f),
+ widthclass=readushort(f),
+ fstype=readushort(f),
+ subscriptxsize=readshort(f),
+ subscriptysize=readshort(f),
+ subscriptxoffset=readshort(f),
+ subscriptyoffset=readshort(f),
+ superscriptxsize=readshort(f),
+ superscriptysize=readshort(f),
+ superscriptxoffset=readshort(f),
+ superscriptyoffset=readshort(f),
+ strikeoutsize=readshort(f),
+ strikeoutpos=readshort(f),
+ familyclass=readshort(f),
+ panose={ readbytes(f,10) },
+ unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) },
+ vendor=readstring(f,4),
+ fsselection=readushort(f),
+ firstcharindex=readushort(f),
+ lastcharindex=readushort(f),
+ typoascender=readshort(f),
+ typodescender=readshort(f),
+ typolinegap=readshort(f),
+ winascent=readushort(f),
+ windescent=readushort(f),
+ }
+ if version>=1 then
+ windowsmetrics.codepageranges={ readulong(f),readulong(f) }
+ end
+ if version>=2 then
+ windowsmetrics.xheight=readshort(f)
+ windowsmetrics.capheight=readshort(f)
+ windowsmetrics.defaultchar=readushort(f)
+ windowsmetrics.breakchar=readushort(f)
+ end
+ windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass]
+ windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass]
+ windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]]
+ windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]]
+ fontdata.windowsmetrics=windowsmetrics
+ else
+ fontdata.windowsmetrics={}
+ end
+end
+readers.head=function(f,fontdata)
+ local tableoffset=gotodatatable(f,fontdata,"head",true)
+ if tableoffset then
+ local version=readulong(f)
+ local fontversion=readulong(f)
+ local fontheader={
+ version=version,
+ fontversion=number.to16dot16(fontversion),
+ fontversionnumber=fontversion,
+ checksum=readushort(f)*0x10000+readushort(f),
+ magic=readulong(f),
+ flags=readushort(f),
+ units=readushort(f),
+ created=readlongdatetime(f),
+ modified=readlongdatetime(f),
+ xmin=readshort(f),
+ ymin=readshort(f),
+ xmax=readshort(f),
+ ymax=readshort(f),
+ macstyle=readushort(f),
+ smallpixels=readushort(f),
+ directionhint=readshort(f),
+ indextolocformat=readshort(f),
+ glyphformat=readshort(f),
+ }
+ fontdata.fontheader=fontheader
+ else
+ fontdata.fontheader={}
+ end
+ fontdata.nofglyphs=0
+end
+readers.hhea=function(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details)
+ if tableoffset then
+ fontdata.horizontalheader={
+ version=readulong(f),
+ ascender=readfword(f),
+ descender=readfword(f),
+ linegap=readfword(f),
+ maxadvancewidth=readufword(f),
+ minleftsidebearing=readfword(f),
+ minrightsidebearing=readfword(f),
+ maxextent=readfword(f),
+ caretsloperise=readshort(f),
+ caretsloperun=readshort(f),
+ caretoffset=readshort(f),
+ reserved_1=readshort(f),
+ reserved_2=readshort(f),
+ reserved_3=readshort(f),
+ reserved_4=readshort(f),
+ metricdataformat=readshort(f),
+ nofmetrics=readushort(f),
+ }
+ else
+ fontdata.horizontalheader={
+ nofmetrics=0,
+ }
+ end
+end
+readers.vhea=function(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details)
+ if tableoffset then
+ fontdata.verticalheader={
+ version=readulong(f),
+ ascender=readfword(f),
+ descender=readfword(f),
+ linegap=readfword(f),
+ maxadvanceheight=readufword(f),
+ mintopsidebearing=readfword(f),
+ minbottomsidebearing=readfword(f),
+ maxextent=readfword(f),
+ caretsloperise=readshort(f),
+ caretsloperun=readshort(f),
+ caretoffset=readshort(f),
+ reserved_1=readshort(f),
+ reserved_2=readshort(f),
+ reserved_3=readshort(f),
+ reserved_4=readshort(f),
+ metricdataformat=readshort(f),
+ nofmetrics=readushort(f),
+ }
+ else
+ fontdata.verticalheader={
+ nofmetrics=0,
+ }
+ end
+end
+readers.maxp=function(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details)
+ if tableoffset then
+ local version=readulong(f)
+ local nofglyphs=readushort(f)
+ fontdata.nofglyphs=nofglyphs
+ if version==0x00005000 then
+ fontdata.maximumprofile={
+ version=version,
+ nofglyphs=nofglyphs,
+ }
+ elseif version==0x00010000 then
+ fontdata.maximumprofile={
+ version=version,
+ nofglyphs=nofglyphs,
+ points=readushort(f),
+ contours=readushort(f),
+ compositepoints=readushort(f),
+ compositecontours=readushort(f),
+ zones=readushort(f),
+ twilightpoints=readushort(f),
+ storage=readushort(f),
+ functiondefs=readushort(f),
+ instructiondefs=readushort(f),
+ stackelements=readushort(f),
+ sizeofinstructions=readushort(f),
+ componentelements=readushort(f),
+ componentdepth=readushort(f),
+ }
+ else
+ fontdata.maximumprofile={
+ version=version,
+ nofglyphs=0,
+ }
+ end
+ end
+end
+readers.hmtx=function(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs)
+ if tableoffset then
+ local horizontalheader=fontdata.horizontalheader
+ local nofmetrics=horizontalheader.nofmetrics
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs
+ local width=0
+ local leftsidebearing=0
+ for i=0,nofmetrics-1 do
+ local glyph=glyphs[i]
+ width=readshort(f)
+ leftsidebearing=readshort(f)
+ if width~=0 then
+ glyph.width=width
+ end
+ end
+ for i=nofmetrics,nofglyphs-1 do
+ local glyph=glyphs[i]
+ if width~=0 then
+ glyph.width=width
+ end
+ end
+ end
+end
+readers.vmtx=function(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs)
+ if tableoffset then
+ local verticalheader=fontdata.verticalheader
+ local nofmetrics=verticalheader.nofmetrics
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs
+ local vheight=0
+ local vdefault=verticalheader.ascender-verticalheader.descender
+ local topsidebearing=0
+ for i=0,nofmetrics-1 do
+ local glyph=glyphs[i]
+ vheight=readushort(f)
+ topsidebearing=readshort(f)
+ if vheight~=0 and vheight~=vdefault then
+ glyph.vheight=vheight
+ end
+ if topsidebearing~=0 then
+ glyph.tsb=topsidebearing
+ end
+ end
+ for i=nofmetrics,nofglyphs-1 do
+ local glyph=glyphs[i]
+ if vheight~=0 and vheight~=vdefault then
+ glyph.vheight=vheight
+ end
+ end
+ end
+end
+readers.vorg=function(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"vorg",specification.glyphs)
+end
+readers.post=function(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"post",true)
+ if tableoffset then
+ local version=readulong(f)
+ fontdata.postscript={
+ version=version,
+ italicangle=round(1000*readfixed(f))/1000,
+ underlineposition=readfword(f),
+ underlinethickness=readfword(f),
+ monospaced=readulong(f),
+ minmemtype42=readulong(f),
+ maxmemtype42=readulong(f),
+ minmemtype1=readulong(f),
+ maxmemtype1=readulong(f),
+ }
+ if not specification.glyphs then
+ elseif version==0x00010000 then
+ for index=0,#standardromanencoding do
+ glyphs[index].name=standardromanencoding[index]
+ end
+ elseif version==0x00020000 then
+ local glyphs=fontdata.glyphs
+ local nofglyphs=readushort(f)
+ local indices={}
+ local names={}
+ local maxnames=0
+ for i=0,nofglyphs-1 do
+ local nameindex=readushort(f)
+ if nameindex>=258 then
+ maxnames=maxnames+1
+ nameindex=nameindex-257
+ indices[nameindex]=i
+ else
+ glyphs[i].name=standardromanencoding[nameindex]
+ end
+ end
+ for i=1,maxnames do
+ local mapping=indices[i]
+ if not mapping then
+ report("quit post name fetching at %a of %a: %s",i,maxnames,"no index")
+ break
+ else
+ local length=readbyte(f)
+ if length>0 then
+ glyphs[mapping].name=readstring(f,length)
+ else
+ report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow")
+ break
+ end
+ end
+ end
+ end
+ else
+ fontdata.postscript={}
+ end
+end
+readers.cff=function(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cff",specification.glyphs)
+end
+local formatreaders={}
+local duplicatestoo=true
+local sequence={
+ { 3,1,4 },
+ { 3,10,12 },
+ { 0,3,4 },
+ { 0,3,12 },
+ { 0,1,4 },
+ { 0,1,12 },
+ { 0,0,6 },
+ { 3,0,6 },
+ { 3,0,4 },
+ { 0,5,14 },
+ { 0,4,12 },
+ { 3,10,13 },
+}
+local supported={}
+for i=1,#sequence do
+ local si=sequence[i]
+ local sp,se,sf=si[1],si[2],si[3]
+ local p=supported[sp]
+ if not p then
+ p={}
+ supported[sp]=p
+ end
+ local e=p[se]
+ if not e then
+ e={}
+ p[se]=e
+ end
+ e[sf]=true
+end
+formatreaders[4]=function(f,fontdata,offset)
+ setposition(f,offset+2)
+ local length=readushort(f)
+ local language=readushort(f)
+ local nofsegments=readushort(f)/2
+ skipshort(f,3)
+ local mapping=fontdata.mapping
+ local glyphs=fontdata.glyphs
+ local duplicates=fontdata.duplicates
+ local nofdone=0
+ local endchars=readcardinaltable(f,nofsegments,ushort)
+ local reserved=readushort(f)
+ local startchars=readcardinaltable(f,nofsegments,ushort)
+ local deltas=readcardinaltable(f,nofsegments,ushort)
+ local offsets=readcardinaltable(f,nofsegments,ushort)
+ local size=(length-2*2-5*2-4*2*nofsegments)/2
+ local indices=readcardinaltable(f,size-1,ushort)
+ for segment=1,nofsegments do
+ local startchar=startchars[segment]
+ local endchar=endchars[segment]
+ local offset=offsets[segment]
+ local delta=deltas[segment]
+ if startchar==0xFFFF and endchar==0xFFFF then
+ elseif startchar==0xFFFF and offset==0 then
+ elseif offset==0xFFFF then
+ elseif offset==0 then
+ if trace_cmap_details then
+ report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536)
+ end
+ for unicode=startchar,endchar do
+ local index=(unicode+delta)%65536
+ if index and index>0 then
+ local glyph=glyphs[index]
+ if glyph then
+ local gu=glyph.unicode
+ if not gu then
+ glyph.unicode=unicode
+ nofdone=nofdone+1
+ elseif gu~=unicode then
+ if duplicatestoo then
+ local d=duplicates[gu]
+ if d then
+ d[unicode]=true
+ else
+ duplicates[gu]={ [unicode]=true }
+ end
+ else
+ report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name)
+ end
+ end
+ if not mapping[index] then
+ mapping[index]=unicode
+ end
+ end
+ end
+ end
+ else
+ local shift=(segment-nofsegments+offset/2)-startchar
+ if trace_cmap_details then
+ report_cmap("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536)
+ end
+ for unicode=startchar,endchar do
+ local slot=shift+unicode
+ local index=indices[slot]
+ if index and index>0 then
+ index=(index+delta)%65536
+ local glyph=glyphs[index]
+ if glyph then
+ local gu=glyph.unicode
+ if not gu then
+ glyph.unicode=unicode
+ nofdone=nofdone+1
+ elseif gu~=unicode then
+ if duplicatestoo then
+ local d=duplicates[gu]
+ if d then
+ d[unicode]=true
+ else
+ duplicates[gu]={ [unicode]=true }
+ end
+ else
+ report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name)
+ end
+ end
+ if not mapping[index] then
+ mapping[index]=unicode
+ end
+ end
+ end
+ end
+ end
+ end
+ return nofdone
+end
+formatreaders[6]=function(f,fontdata,offset)
+ setposition(f,offset)
+ local format=readushort(f)
+ local length=readushort(f)
+ local language=readushort(f)
+ local mapping=fontdata.mapping
+ local glyphs=fontdata.glyphs
+ local duplicates=fontdata.duplicates
+ local start=readushort(f)
+ local count=readushort(f)
+ local stop=start+count-1
+ local nofdone=0
+ if trace_cmap_details then
+ report_cmap("format 6 from %C to %C",2,start,stop)
+ end
+ for unicode=start,stop do
+ local index=readushort(f)
+ if index>0 then
+ local glyph=glyphs[index]
+ if glyph then
+ local gu=glyph.unicode
+ if not gu then
+ glyph.unicode=unicode
+ nofdone=nofdone+1
+ elseif gu~=unicode then
+ end
+ if not mapping[index] then
+ mapping[index]=unicode
+ end
+ end
+ end
+ end
+ return nofdone
+end
+formatreaders[12]=function(f,fontdata,offset)
+ setposition(f,offset+2+2+4+4)
+ local mapping=fontdata.mapping
+ local glyphs=fontdata.glyphs
+ local duplicates=fontdata.duplicates
+ local nofgroups=readulong(f)
+ local nofdone=0
+ for i=1,nofgroups do
+ local first=readulong(f)
+ local last=readulong(f)
+ local index=readulong(f)
+ if trace_cmap_details then
+ report_cmap("format 12 from %C to %C starts at index %i",first,last,index)
+ end
+ for unicode=first,last do
+ local glyph=glyphs[index]
+ if glyph then
+ local gu=glyph.unicode
+ if not gu then
+ glyph.unicode=unicode
+ nofdone=nofdone+1
+ elseif gu~=unicode then
+ local d=duplicates[gu]
+ if d then
+ d[unicode]=true
+ else
+ duplicates[gu]={ [unicode]=true }
+ end
+ end
+ if not mapping[index] then
+ mapping[index]=unicode
+ end
+ end
+ index=index+1
+ end
+ end
+ return nofdone
+end
+formatreaders[13]=function(f,fontdata,offset)
+ setposition(f,offset+2+2+4+4)
+ local mapping=fontdata.mapping
+ local glyphs=fontdata.glyphs
+ local duplicates=fontdata.duplicates
+ local nofgroups=readulong(f)
+ local nofdone=0
+ for i=1,nofgroups do
+ local first=readulong(f)
+ local last=readulong(f)
+ local index=readulong(f)
+ if first<privateoffset then
+ if trace_cmap_details then
+ report_cmap("format 13 from %C to %C get index %i",first,last,index)
+ end
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=first
+ glyph.unicode=unicode
+ first=first+1
+ end
+ local list=duplicates[unicode]
+ mapping[index]=unicode
+ if not list then
+ list={}
+ duplicates[unicode]=list
+ end
+ if last>=privateoffset then
+ local limit=privateoffset-1
+ report("format 13 from %C to %C pruned to %C",first,last,limit)
+ last=limit
+ end
+ for unicode=first,last do
+ list[unicode]=true
+ end
+ nofdone=nofdone+last-first+1
+ else
+ report("format 13 from %C to %C ignored",first,last)
+ end
+ end
+ return nofdone
+end
+formatreaders[14]=function(f,fontdata,offset)
+ if offset and offset~=0 then
+ setposition(f,offset)
+ local format=readushort(f)
+ local length=readulong(f)
+ local nofrecords=readulong(f)
+ local records={}
+ local variants={}
+ local nofdone=0
+ fontdata.variants=variants
+ for i=1,nofrecords do
+ records[i]={
+ selector=readuint(f),
+ default=readulong(f),
+ other=readulong(f),
+ }
+ end
+ for i=1,nofrecords do
+ local record=records[i]
+ local selector=record.selector
+ local default=record.default
+ local other=record.other
+ local other=record.other
+ if other~=0 then
+ setposition(f,offset+other)
+ local mapping={}
+ local count=readulong(f)
+ for i=1,count do
+ mapping[readuint(f)]=readushort(f)
+ end
+ nofdone=nofdone+count
+ variants[selector]=mapping
+ end
+ end
+ return nofdone
+ else
+ return 0
+ end
+end
+local function checkcmap(f,fontdata,records,platform,encoding,format)
+ local pdata=records[platform]
+ if not pdata then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","no platform",platform,encoding,format)
+ end
+ return 0
+ end
+ local edata=pdata[encoding]
+ if not edata then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","no encoding",platform,encoding,format)
+ end
+ return 0
+ end
+ local fdata=edata[format]
+ if not fdata then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","no format",platform,encoding,format)
+ end
+ return 0
+ elseif type(fdata)~="number" then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","already done",platform,encoding,format)
+ end
+ return 0
+ end
+ edata[format]=true
+ local reader=formatreaders[format]
+ if not reader then
+ if trace_cmap_details then
+ report_cmap("skipped, %s, p=%i e=%i f=%i","unsupported format",platform,encoding,format)
+ end
+ return 0
+ end
+ local n=reader(f,fontdata,fdata) or 0
+ if trace_cmap_details or trace_cmap then
+ local p=platforms[platform]
+ local e=encodings[p]
+ report_cmap("checked, platform %i (%s), encoding %i (%s), format %i, new unicodes %i",
+ platform,p,encoding,e and e[encoding] or "?",format,n)
+ end
+ return n
+end
+function readers.cmap(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local noftables=readushort(f)
+ local records={}
+ local unicodecid=false
+ local variantcid=false
+ local variants={}
+ local duplicates=fontdata.duplicates or {}
+ fontdata.duplicates=duplicates
+ for i=1,noftables do
+ local platform=readushort(f)
+ local encoding=readushort(f)
+ local offset=readulong(f)
+ local record=records[platform]
+ if not record then
+ records[platform]={
+ [encoding]={
+ offsets={ offset },
+ formats={},
+ }
+ }
+ else
+ local subtables=record[encoding]
+ if not subtables then
+ record[encoding]={
+ offsets={ offset },
+ formats={},
+ }
+ else
+ local offsets=subtables.offsets
+ offsets[#offsets+1]=offset
+ end
+ end
+ end
+ if trace_cmap then
+ report("found cmaps:")
+ end
+ for platform,record in sortedhash(records) do
+ local p=platforms[platform]
+ local e=encodings[p]
+ local sp=supported[platform]
+ local ps=p or "?"
+ if trace_cmap then
+ if sp then
+ report(" platform %i: %s",platform,ps)
+ else
+ report(" platform %i: %s (unsupported)",platform,ps)
+ end
+ end
+ for encoding,subtables in sortedhash(record) do
+ local se=sp and sp[encoding]
+ local es=e and e[encoding] or "?"
+ if trace_cmap then
+ if se then
+ report(" encoding %i: %s",encoding,es)
+ else
+ report(" encoding %i: %s (unsupported)",encoding,es)
+ end
+ end
+ local offsets=subtables.offsets
+ local formats=subtables.formats
+ for i=1,#offsets do
+ local offset=tableoffset+offsets[i]
+ setposition(f,offset)
+ formats[readushort(f)]=offset
+ end
+ record[encoding]=formats
+ if trace_cmap then
+ local list=sortedkeys(formats)
+ for i=1,#list do
+ if not (se and se[list[i]]) then
+ list[i]=list[i].." (unsupported)"
+ end
+ end
+ report(" formats: % t",list)
+ end
+ end
+ end
+ local ok=false
+ for i=1,#sequence do
+ local si=sequence[i]
+ local sp,se,sf=si[1],si[2],si[3]
+ if checkcmap(f,fontdata,records,sp,se,sf)>0 then
+ ok=true
+ end
+ end
+ if not ok then
+ report("no useable unicode cmap found")
+ end
+ fontdata.cidmaps={
+ version=version,
+ noftables=noftables,
+ records=records,
+ }
+ else
+ fontdata.cidmaps={}
+ end
+end
+function readers.loca(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"loca",specification.glyphs)
+end
+function readers.glyf(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"glyf",specification.glyphs)
+end
+function readers.colr(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"colr",specification.glyphs)
+end
+function readers.cpal(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cpal",specification.glyphs)
+end
+function readers.svg(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"svg",specification.glyphs)
+end
+function readers.sbix(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"sbix",specification.glyphs)
+end
+function readers.cbdt(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cbdt",specification.glyphs)
+end
+function readers.cblc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"cblc",specification.glyphs)
+end
+function readers.ebdt(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"ebdt",specification.glyphs)
+end
+function readers.ebsc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"ebsc",specification.glyphs)
+end
+function readers.eblc(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"eblc",specification.glyphs)
+end
+function readers.kern(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns)
+ if tableoffset then
+ local version=readushort(f)
+ local noftables=readushort(f)
+ for i=1,noftables do
+ local version=readushort(f)
+ local length=readushort(f)
+ local coverage=readushort(f)
+ local format=rshift(coverage,8)
+ if format==0 then
+ local nofpairs=readushort(f)
+ local searchrange=readushort(f)
+ local entryselector=readushort(f)
+ local rangeshift=readushort(f)
+ local kerns={}
+ local glyphs=fontdata.glyphs
+ for i=1,nofpairs do
+ local left=readushort(f)
+ local right=readushort(f)
+ local kern=readfword(f)
+ local glyph=glyphs[left]
+ local kerns=glyph.kerns
+ if kerns then
+ kerns[right]=kern
+ else
+ glyph.kerns={ [right]=kern }
+ end
+ end
+ elseif format==2 then
+ report("todo: kern classes")
+ else
+ report("todo: kerns")
+ end
+ end
+ end
+end
+function readers.gdef(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"gdef",specification.details)
+end
+function readers.gsub(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"gsub",specification.details)
+end
+function readers.gpos(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"gpos",specification.details)
+end
+function readers.math(f,fontdata,specification)
+ reportskippedtable(f,fontdata,"math",specification.details)
+end
+local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames)
+ local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata
+ local names=fontdata.names
+ local info=nil
+ if names then
+ local metrics=fontdata.windowsmetrics or {}
+ local postscript=fontdata.postscript or {}
+ local fontheader=fontdata.fontheader or {}
+ local cffinfo=fontdata.cffinfo or {}
+ local verticalheader=fontdata.verticalheader or {}
+ local filename=fontdata.filename
+ local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight)
+ local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width )
+ local fontname=getname(fontdata,"postscriptname")
+ local fullname=getname(fontdata,"fullname")
+ local family=getname(fontdata,"family")
+ local subfamily=getname(fontdata,"subfamily")
+ local familyname=getname(fontdata,"typographicfamily")
+ local subfamilyname=getname(fontdata,"typographicsubfamily")
+ local compatiblename=getname(fontdata,"compatiblefullname")
+ if rawfamilynames then
+ else
+ if not familyname then familyname=family end
+ if not subfamilyname then subfamilyname=subfamily end
+ end
+ if platformnames then
+ platformnames=fontdata.platformnames
+ end
+ if instancenames then
+ local variabledata=fontdata.variabledata
+ if variabledata then
+ local instances=variabledata and variabledata.instances
+ if instances then
+ instancenames={}
+ for i=1,#instances do
+ instancenames[i]=lower(stripstring(instances[i].subfamily))
+ end
+ else
+ instancenames=nil
+ end
+ else
+ instancenames=nil
+ end
+ end
+ info={
+ subfontindex=fontdata.subfontindex or sub or 0,
+ version=getname(fontdata,"version"),
+ fontname=fontname,
+ fullname=fullname,
+ family=family,
+ subfamily=subfamily,
+ familyname=familyname,
+ subfamilyname=subfamilyname,
+ compatiblename=compatiblename,
+ weight=weight and lower(weight),
+ width=width and lower(width),
+ pfmweight=metrics.weightclass or 400,
+ pfmwidth=metrics.widthclass or 5,
+ panosewidth=metrics.panosewidth,
+ panoseweight=metrics.panoseweight,
+ italicangle=postscript.italicangle or 0,
+ units=fontheader.units or 0,
+ designsize=fontdata.designsize,
+ minsize=fontdata.minsize,
+ maxsize=fontdata.maxsize,
+ boundingbox=fontheader and { fontheader.xmin or 0,fontheader.ymin or 0,fontheader.xmax or 0,fontheader.ymax or 0 } or nil,
+ monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced",
+ averagewidth=metrics.averagewidth,
+ xheight=metrics.xheight,
+ capheight=metrics.capheight or fontdata.maxy,
+ ascender=metrics.typoascender,
+ descender=metrics.typodescender,
+ platformnames=platformnames or nil,
+ instancenames=instancenames or nil,
+ tableoffsets=fontdata.tableoffsets,
+ defaultvheight=(verticalheader.ascender or 0)-(verticalheader.descender or 0)
+ }
+ if metricstoo then
+ local keys={
+ "version",
+ "ascender","descender","linegap",
+ "maxadvancewidth","maxadvanceheight","maxextent",
+ "minbottomsidebearing","mintopsidebearing",
+ }
+ local h=fontdata.horizontalheader or {}
+ local v=fontdata.verticalheader or {}
+ if h then
+ local th={}
+ local tv={}
+ for i=1,#keys do
+ local key=keys[i]
+ th[key]=h[key] or 0
+ tv[key]=v[key] or 0
+ end
+ info.horizontalmetrics=th
+ info.verticalmetrics=tv
+ end
+ end
+ elseif n then
+ info={
+ filename=fontdata.filename,
+ comment="there is no info for subfont "..n,
+ }
+ else
+ info={
+ filename=fontdata.filename,
+ comment="there is no info",
+ }
+ end
+ return info
+end
+local function loadtables(f,specification,offset)
+ if offset then
+ setposition(f,offset)
+ end
+ local tables={}
+ local basename=file.basename(specification.filename)
+ local filesize=specification.filesize
+ local filetime=specification.filetime
+ local fontdata={
+ filename=basename,
+ filesize=filesize,
+ filetime=filetime,
+ version=readstring(f,4),
+ noftables=readushort(f),
+ searchrange=readushort(f),
+ entryselector=readushort(f),
+ rangeshift=readushort(f),
+ tables=tables,
+ foundtables=false,
+ }
+ for i=1,fontdata.noftables do
+ local tag=lower(stripstring(readstring(f,4)))
+ local checksum=readushort(f)*0x10000+readushort(f)
+ local offset=readulong(f)
+ local length=readulong(f)
+ if offset+length>filesize then
+ report("bad %a table in file %a",tag,basename)
+ end
+ tables[tag]={
+ checksum=checksum,
+ offset=offset,
+ length=length,
+ }
+ end
+ fontdata.foundtables=sortedkeys(tables)
+ if tables.cff or tables.cff2 then
+ fontdata.format="opentype"
+ else
+ fontdata.format="truetype"
+ end
+ return fontdata,tables
+end
+local function prepareglyps(fontdata)
+ local glyphs=setmetatableindex(function(t,k)
+ local v={
+ index=k,
+ }
+ t[k]=v
+ return v
+ end)
+ fontdata.glyphs=glyphs
+ fontdata.mapping={}
+end
+local function readtable(tag,f,fontdata,specification,...)
+ local reader=readers[tag]
+ if reader then
+ reader(f,fontdata,specification,...)
+ end
+end
+local variablefonts_supported=(context and true) or (logs and logs.application and true) or false
+local function readdata(f,offset,specification)
+ local fontdata,tables=loadtables(f,specification,offset)
+ if specification.glyphs then
+ prepareglyps(fontdata)
+ end
+ if not variablefonts_supported then
+ specification.instance=nil
+ specification.variable=nil
+ specification.factors=nil
+ end
+ fontdata.temporary={}
+ readtable("name",f,fontdata,specification)
+ local askedname=specification.askedname
+ if askedname then
+ local fullname=getname(fontdata,"fullname") or ""
+ local cleanname=gsub(askedname,"[^a-zA-Z0-9]","")
+ local foundname=gsub(fullname,"[^a-zA-Z0-9]","")
+ if lower(cleanname)~=lower(foundname) then
+ return
+ end
+ end
+ readtable("stat",f,fontdata,specification)
+ readtable("avar",f,fontdata,specification)
+ readtable("fvar",f,fontdata,specification)
+ if variablefonts_supported then
+ local variabledata=fontdata.variabledata
+ if variabledata then
+ local instances=variabledata.instances
+ local axis=variabledata.axis
+ if axis and (not instances or #instances==0) then
+ instances={}
+ variabledata.instances=instances
+ local function add(n,subfamily,value)
+ local values={}
+ for i=1,#axis do
+ local a=axis[i]
+ values[i]={
+ axis=a.tag,
+ value=i==n and value or a.default,
+ }
+ end
+ instances[#instances+1]={
+ subfamily=subfamily,
+ values=values,
+ }
+ end
+ for i=1,#axis do
+ local a=axis[i]
+ local tag=a.tag
+ add(i,"default"..tag,a.default)
+ add(i,"minimum"..tag,a.minimum)
+ add(i,"maximum"..tag,a.maximum)
+ end
+ end
+ end
+ if not specification.factors then
+ local instance=specification.instance
+ if type(instance)=="string" then
+ local factors=helpers.getfactors(fontdata,instance)
+ 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)
+ if factors then
+ specification.factors=factors
+ fontdata.factors=factors
+ end
+ else
+ end
+ end
+ end
+ readtable("os/2",f,fontdata,specification)
+ readtable("head",f,fontdata,specification)
+ readtable("maxp",f,fontdata,specification)
+ readtable("hhea",f,fontdata,specification)
+ readtable("vhea",f,fontdata,specification)
+ readtable("hmtx",f,fontdata,specification)
+ readtable("vmtx",f,fontdata,specification)
+ readtable("vorg",f,fontdata,specification)
+ readtable("post",f,fontdata,specification)
+ readtable("mvar",f,fontdata,specification)
+ readtable("hvar",f,fontdata,specification)
+ readtable("vvar",f,fontdata,specification)
+ readtable("gdef",f,fontdata,specification)
+ readtable("cff",f,fontdata,specification)
+ readtable("cff2",f,fontdata,specification)
+ readtable("cmap",f,fontdata,specification)
+ readtable("loca",f,fontdata,specification)
+ readtable("glyf",f,fontdata,specification)
+ readtable("colr",f,fontdata,specification)
+ readtable("cpal",f,fontdata,specification)
+ readtable("svg",f,fontdata,specification)
+ readtable("sbix",f,fontdata,specification)
+ readtable("cbdt",f,fontdata,specification)
+ readtable("cblc",f,fontdata,specification)
+ readtable("ebdt",f,fontdata,specification)
+ readtable("eblc",f,fontdata,specification)
+ readtable("kern",f,fontdata,specification)
+ readtable("gsub",f,fontdata,specification)
+ readtable("gpos",f,fontdata,specification)
+ readtable("math",f,fontdata,specification)
+ fontdata.locations=nil
+ fontdata.cidmaps=nil
+ fontdata.dictionaries=nil
+ if specification.tableoffsets then
+ fontdata.tableoffsets=tables
+ setmetatableindex(tables,{
+ version=fontdata.version,
+ noftables=fontdata.noftables,
+ searchrange=fontdata.searchrange,
+ entryselector=fontdata.entryselector,
+ rangeshift=fontdata.rangeshift,
+ })
+ end
+ return fontdata
+end
+local function loadfontdata(specification)
+ local filename=specification.filename
+ local fileattr=lfs.attributes(filename)
+ local filesize=fileattr and fileattr.size or 0
+ local filetime=fileattr and fileattr.modification or 0
+ local f=openfile(filename,true)
+ if not f then
+ report("unable to open %a",filename)
+ elseif filesize==0 then
+ report("empty file %a",filename)
+ closefile(f)
+ else
+ specification.filesize=filesize
+ specification.filetime=filetime
+ local version=readstring(f,4)
+ local fontdata=nil
+ if version=="OTTO" or version=="true" or version=="\0\1\0\0" then
+ fontdata=readdata(f,0,specification)
+ elseif version=="ttcf" then
+ local subfont=tonumber(specification.subfont)
+ local ttcversion=readulong(f)
+ local nofsubfonts=readulong(f)
+ local offsets=readcardinaltable(f,nofsubfonts,ulong)
+ if subfont then
+ if subfont>=1 and subfont<=nofsubfonts then
+ fontdata=readdata(f,offsets[subfont],specification)
+ else
+ report("no subfont %a in file %a",subfont,filename)
+ end
+ else
+ subfont=specification.subfont
+ if type(subfont)=="string" and subfont~="" then
+ specification.askedname=subfont
+ for i=1,nofsubfonts do
+ fontdata=readdata(f,offsets[i],specification)
+ if fontdata then
+ fontdata.subfontindex=i
+ report("subfont named %a has index %a",subfont,i)
+ break
+ end
+ end
+ if not fontdata then
+ report("no subfont named %a",subfont)
+ end
+ else
+ local subfonts={}
+ fontdata={
+ filename=filename,
+ filesize=filesize,
+ filetime=filetime,
+ version=version,
+ subfonts=subfonts,
+ ttcversion=ttcversion,
+ nofsubfonts=nofsubfonts,
+ }
+ for i=1,nofsubfonts do
+ subfonts[i]=readdata(f,offsets[i],specification)
+ end
+ end
+ end
+ else
+ report("unknown version %a in file %a",version,filename)
+ end
+ closefile(f)
+ return fontdata or {}
+ end
+end
+local function loadfont(specification,n,instance)
+ if type(specification)=="string" then
+ specification={
+ filename=specification,
+ info=true,
+ details=true,
+ glyphs=true,
+ shapes=true,
+ kerns=true,
+ variable=true,
+ globalkerns=true,
+ lookups=true,
+ subfont=n or true,
+ tounicode=false,
+ instance=instance
+ }
+ end
+ if specification.shapes or specification.lookups or specification.kerns then
+ specification.glyphs=true
+ end
+ if specification.glyphs then
+ specification.details=true
+ end
+ if specification.details then
+ specification.info=true
+ end
+ if specification.platformnames then
+ specification.platformnames=true
+ end
+ if specification.instance or instance then
+ specification.variable=true
+ specification.instance=specification.instance or instance
+ end
+ local function message(str)
+ report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback())
+ end
+ local ok,result=xpcall(loadfontdata,message,specification)
+ if ok then
+ return result
+ end
+end
+function readers.loadshapes(filename,n,instance,streams)
+ local fontdata=loadfont {
+ filename=filename,
+ shapes=true,
+ streams=streams,
+ variable=true,
+ subfont=n,
+ instance=instance,
+ }
+ if fontdata then
+ for k,v in next,fontdata.glyphs do
+ v.class=nil
+ v.index=nil
+ v.math=nil
+ end
+ local names=fontdata.names
+ if names then
+ for k,v in next,names do
+ names[k]=fullstrip(v.content)
+ end
+ end
+ end
+ return fontdata and {
+ filename=filename,
+ format=fontdata.format,
+ glyphs=fontdata.glyphs,
+ units=fontdata.fontheader.units,
+ cffinfo=fontdata.cffinfo,
+ fontheader=fontdata.fontheader,
+ horizontalheader=fontdata.horizontalheader,
+ verticalheader=fontdata.verticalheader,
+ maximumprofile=fontdata.maximumprofile,
+ names=fontdata.names,
+ postscript=fontdata.postscript,
+ } or {
+ filename=filename,
+ format="unknown",
+ glyphs={},
+ units=0,
+ }
+end
+function readers.loadfont(filename,n,instance)
+ local fontdata=loadfont {
+ filename=filename,
+ glyphs=true,
+ shapes=false,
+ lookups=true,
+ variable=true,
+ subfont=n,
+ instance=instance,
+ }
+ if fontdata then
+ return {
+ tableversion=tableversion,
+ creator="context mkiv",
+ size=fontdata.filesize,
+ time=fontdata.filetime,
+ glyphs=fontdata.glyphs,
+ descriptions=fontdata.descriptions,
+ format=fontdata.format,
+ goodies={},
+ metadata=getinfo(fontdata,n,false,false,true,true),
+ properties={
+ hasitalics=fontdata.hasitalics or false,
+ maxcolorclass=fontdata.maxcolorclass,
+ hascolor=fontdata.hascolor or false,
+ instance=fontdata.instance,
+ factors=fontdata.factors,
+ },
+ resources={
+ filename=filename,
+ private=privateoffset,
+ duplicates=fontdata.duplicates or {},
+ features=fontdata.features or {},
+ sublookups=fontdata.sublookups or {},
+ marks=fontdata.marks or {},
+ markclasses=fontdata.markclasses or {},
+ marksets=fontdata.marksets or {},
+ sequences=fontdata.sequences or {},
+ variants=fontdata.variants,
+ version=getname(fontdata,"version"),
+ cidinfo=fontdata.cidinfo,
+ mathconstants=fontdata.mathconstants,
+ colorpalettes=fontdata.colorpalettes,
+ svgshapes=fontdata.svgshapes,
+ pngshapes=fontdata.pngshapes,
+ variabledata=fontdata.variabledata,
+ foundtables=fontdata.foundtables,
+ },
+ }
+ end
+end
+function readers.getinfo(filename,specification)
+ local subfont=nil
+ local platformnames=false
+ local rawfamilynames=false
+ local instancenames=true
+ local tableoffsets=false
+ if type(specification)=="table" then
+ subfont=tonumber(specification.subfont)
+ platformnames=specification.platformnames
+ rawfamilynames=specification.rawfamilynames
+ tableoffsets=specification.tableoffsets
+ else
+ subfont=tonumber(specification)
+ end
+ local fontdata=loadfont {
+ filename=filename,
+ details=true,
+ platformnames=platformnames,
+ instancenames=true,
+ tableoffsets=tableoffsets,
+ }
+ if fontdata then
+ local subfonts=fontdata.subfonts
+ if not subfonts then
+ return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames)
+ elseif not subfont then
+ local info={}
+ for i=1,#subfonts do
+ info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames)
+ end
+ return info
+ elseif subfont>=1 and subfont<=#subfonts then
+ return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames)
+ else
+ return {
+ filename=filename,
+ comment="there is no subfont "..subfont.." in this file"
+ }
+ end
+ else
+ return {
+ filename=filename,
+ comment="the file cannot be opened for reading",
+ }
+ end
+end
+function readers.rehash(fontdata,hashmethod)
+ report("the %a helper is not yet implemented","rehash")
+end
+function readers.checkhash(fontdata)
+ report("the %a helper is not yet implemented","checkhash")
+end
+function readers.pack(fontdata,hashmethod)
+ report("the %a helper is not yet implemented","pack")
+end
+function readers.unpack(fontdata)
+ report("the %a helper is not yet implemented","unpack")
+end
+function readers.expand(fontdata)
+ report("the %a helper is not yet implemented","unpack")
+end
+function readers.compact(fontdata)
+ report("the %a helper is not yet implemented","compact")
+end
+local extenders={}
+function readers.registerextender(extender)
+ extenders[#extenders+1]=extender
+end
+function readers.extend(fontdata)
+ for i=1,#extenders do
+ local extender=extenders[i]
+ local name=extender.name or "unknown"
+ local action=extender.action
+ if action then
+ action(fontdata)
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-oti']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local lower=string.lower
+local fonts=fonts
+local constructors=fonts.constructors
+local otf=constructors.handlers.otf
+local otffeatures=constructors.features.otf
+local registerotffeature=otffeatures.register
+local otftables=otf.tables or {}
+otf.tables=otftables
+local allocate=utilities.storage.allocate
+registerotffeature {
+ name="features",
+ description="initialization of feature handler",
+ default=true,
+}
+local function setmode(tfmdata,value)
+ if value then
+ tfmdata.properties.mode=lower(value)
+ end
+end
+otf.modeinitializer=setmode
+local function setlanguage(tfmdata,value)
+ if value then
+ local cleanvalue=lower(value)
+ local languages=otftables and otftables.languages
+ local properties=tfmdata.properties
+ if not languages then
+ properties.language=cleanvalue
+ elseif languages[value] then
+ properties.language=cleanvalue
+ else
+ properties.language="dflt"
+ end
+ end
+end
+local function setscript(tfmdata,value)
+ if value then
+ local cleanvalue=lower(value)
+ local scripts=otftables and otftables.scripts
+ local properties=tfmdata.properties
+ if not scripts then
+ properties.script=cleanvalue
+ elseif scripts[value] then
+ properties.script=cleanvalue
+ else
+ properties.script="dflt"
+ end
+ end
+end
+registerotffeature {
+ name="mode",
+ description="mode",
+ initializers={
+ base=setmode,
+ node=setmode,
+ plug=setmode,
+ }
+}
+registerotffeature {
+ name="language",
+ description="language",
+ initializers={
+ base=setlanguage,
+ node=setlanguage,
+ plug=setlanguage,
+ }
+}
+registerotffeature {
+ name="script",
+ description="script",
+ initializers={
+ base=setscript,
+ node=setscript,
+ plug=setscript,
+ }
+}
+otftables.featuretypes=allocate {
+ gpos_single="position",
+ gpos_pair="position",
+ gpos_cursive="position",
+ gpos_mark2base="position",
+ gpos_mark2ligature="position",
+ gpos_mark2mark="position",
+ gpos_context="position",
+ gpos_contextchain="position",
+ gsub_single="substitution",
+ gsub_multiple="substitution",
+ gsub_alternate="substitution",
+ gsub_ligature="substitution",
+ gsub_context="substitution",
+ gsub_contextchain="substitution",
+ gsub_reversecontextchain="substitution",
+ gsub_reversesub="substitution",
+}
+function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts)
+ if featuretype=="position" then
+ local default=scripts.dflt
+ if default then
+ if autoscript=="position" or autoscript==true then
+ return default
+ else
+ report_otf("script feature %s not applied, enable default positioning")
+ end
+ else
+ end
+ elseif featuretype=="substitution" then
+ local default=scripts.dflt
+ if default then
+ if autoscript=="substitution" or autoscript==true then
+ return default
+ end
+ end
+ end
+end
+function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
+ if featuretype=="position" then
+ local default=languages.dflt
+ if default then
+ if autolanguage=="position" or autolanguage==true then
+ return default
+ else
+ report_otf("language feature %s not applied, enable default positioning")
+ end
+ else
+ end
+ elseif featuretype=="substitution" then
+ local default=languages.dflt
+ if default then
+ if autolanguage=="substitution" or autolanguage==true then
+ return default
+ end
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ["font-ott"]={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
+}
+local type,next,tonumber,tostring,rawget,rawset=type,next,tonumber,tostring,rawget,rawset
+local gsub,lower,format,match,gmatch,find=string.gsub,string.lower,string.format,string.match,string.gmatch,string.find
+local sequenced=table.sequenced
+local is_boolean=string.is_boolean
+local setmetatableindex=table.setmetatableindex
+local setmetatablenewindex=table.setmetatablenewindex
+local allocate=utilities.storage.allocate
+local fonts=fonts
+local otf=fonts.handlers.otf
+local otffeatures=otf.features
+local tables=otf.tables or {}
+otf.tables=tables
+local statistics=otf.statistics or {}
+otf.statistics=statistics
+local scripts=allocate {
+ ["adlm"]="adlam",
+ ["aghb"]="caucasian albanian",
+ ["ahom"]="ahom",
+ ["arab"]="arabic",
+ ["armi"]="imperial aramaic",
+ ["armn"]="armenian",
+ ["avst"]="avestan",
+ ["bali"]="balinese",
+ ["bamu"]="bamum",
+ ["bass"]="bassa vah",
+ ["batk"]="batak",
+ ["beng"]="bengali",
+ ["bhks"]="bhaiksuki",
+ ["bng2"]="bengali variant 2",
+ ["bopo"]="bopomofo",
+ ["brah"]="brahmi",
+ ["brai"]="braille",
+ ["bugi"]="buginese",
+ ["buhd"]="buhid",
+ ["byzm"]="byzantine music",
+ ["cakm"]="chakma",
+ ["cans"]="canadian syllabics",
+ ["cari"]="carian",
+ ["cham"]="cham",
+ ["cher"]="cherokee",
+ ["copt"]="coptic",
+ ["cprt"]="cypriot syllabary",
+ ["cyrl"]="cyrillic",
+ ["dev2"]="devanagari variant 2",
+ ["deva"]="devanagari",
+ ["dogr"]="dogra",
+ ["dsrt"]="deseret",
+ ["dupl"]="duployan",
+ ["egyp"]="egyptian heiroglyphs",
+ ["elba"]="elbasan",
+ ["ethi"]="ethiopic",
+ ["geor"]="georgian",
+ ["gjr2"]="gujarati variant 2",
+ ["glag"]="glagolitic",
+ ["gong"]="gunjala gondi",
+ ["gonm"]="masaram gondi",
+ ["goth"]="gothic",
+ ["gran"]="grantha",
+ ["grek"]="greek",
+ ["gujr"]="gujarati",
+ ["gur2"]="gurmukhi variant 2",
+ ["guru"]="gurmukhi",
+ ["hang"]="hangul",
+ ["hani"]="cjk ideographic",
+ ["hano"]="hanunoo",
+ ["hatr"]="hatran",
+ ["hebr"]="hebrew",
+ ["hluw"]="anatolian hieroglyphs",
+ ["hmng"]="pahawh hmong",
+ ["hung"]="old hungarian",
+ ["ital"]="old italic",
+ ["jamo"]="hangul jamo",
+ ["java"]="javanese",
+ ["kali"]="kayah li",
+ ["kana"]="hiragana and katakana",
+ ["khar"]="kharosthi",
+ ["khmr"]="khmer",
+ ["khoj"]="khojki",
+ ["knd2"]="kannada variant 2",
+ ["knda"]="kannada",
+ ["kthi"]="kaithi",
+ ["lana"]="tai tham",
+ ["lao" ]="lao",
+ ["latn"]="latin",
+ ["lepc"]="lepcha",
+ ["limb"]="limbu",
+ ["lina"]="linear a",
+ ["linb"]="linear b",
+ ["lisu"]="lisu",
+ ["lyci"]="lycian",
+ ["lydi"]="lydian",
+ ["mahj"]="mahajani",
+ ["maka"]="makasar",
+ ["mand"]="mandaic and mandaean",
+ ["mani"]="manichaean",
+ ["marc"]="marchen",
+ ["math"]="mathematical alphanumeric symbols",
+ ["medf"]="medefaidrin",
+ ["mend"]="mende kikakui",
+ ["merc"]="meroitic cursive",
+ ["mero"]="meroitic hieroglyphs",
+ ["mlm2"]="malayalam variant 2",
+ ["mlym"]="malayalam",
+ ["modi"]="modi",
+ ["mong"]="mongolian",
+ ["mroo"]="mro",
+ ["mtei"]="meitei Mayek",
+ ["mult"]="multani",
+ ["musc"]="musical symbols",
+ ["mym2"]="myanmar variant 2",
+ ["mymr"]="myanmar",
+ ["narb"]="old north arabian",
+ ["nbat"]="nabataean",
+ ["newa"]="newa",
+ ["nko" ]='n"ko',
+ ["nshu"]="nüshu",
+ ["ogam"]="ogham",
+ ["olck"]="ol chiki",
+ ["orkh"]="old turkic and orkhon runic",
+ ["ory2"]="odia variant 2",
+ ["orya"]="oriya",
+ ["osge"]="osage",
+ ["osma"]="osmanya",
+ ["palm"]="palmyrene",
+ ["pauc"]="pau cin hau",
+ ["perm"]="old permic",
+ ["phag"]="phags-pa",
+ ["phli"]="inscriptional pahlavi",
+ ["phlp"]="psalter pahlavi",
+ ["phnx"]="phoenician",
+ ["plrd"]="miao",
+ ["prti"]="inscriptional parthian",
+ ["rjng"]="rejang",
+ ["rohg"]="hanifi rohingya",
+ ["runr"]="runic",
+ ["samr"]="samaritan",
+ ["sarb"]="old south arabian",
+ ["saur"]="saurashtra",
+ ["sgnw"]="sign writing",
+ ["shaw"]="shavian",
+ ["shrd"]="sharada",
+ ["sidd"]="siddham",
+ ["sind"]="khudawadi",
+ ["sinh"]="sinhala",
+ ["sogd"]="sogdian",
+ ["sogo"]="old sogdian",
+ ["sora"]="sora sompeng",
+ ["soyo"]="soyombo",
+ ["sund"]="sundanese",
+ ["sylo"]="syloti nagri",
+ ["syrc"]="syriac",
+ ["tagb"]="tagbanwa",
+ ["takr"]="takri",
+ ["tale"]="tai le",
+ ["talu"]="tai lu",
+ ["taml"]="tamil",
+ ["tang"]="tangut",
+ ["tavt"]="tai viet",
+ ["tel2"]="telugu variant 2",
+ ["telu"]="telugu",
+ ["tfng"]="tifinagh",
+ ["tglg"]="tagalog",
+ ["thaa"]="thaana",
+ ["thai"]="thai",
+ ["tibt"]="tibetan",
+ ["tirh"]="tirhuta",
+ ["tml2"]="tamil variant 2",
+ ["ugar"]="ugaritic cuneiform",
+ ["vai" ]="vai",
+ ["wara"]="warang citi",
+ ["xpeo"]="old persian cuneiform",
+ ["xsux"]="sumero-akkadian cuneiform",
+ ["yi" ]="yi",
+ ["zanb"]="zanabazar square",
+}
+local languages=allocate {
+ ["aba" ]="abaza",
+ ["abk" ]="abkhazian",
+ ["ach" ]="acholi",
+ ["acr" ]="achi",
+ ["ady" ]="adyghe",
+ ["afk" ]="afrikaans",
+ ["afr" ]="afar",
+ ["agw" ]="agaw",
+ ["aio" ]="aiton",
+ ["aka" ]="akan",
+ ["als" ]="alsatian",
+ ["alt" ]="altai",
+ ["amh" ]="amharic",
+ ["ang" ]="anglo-saxon",
+ ["apph"]="phonetic transcription—americanist conventions",
+ ["ara" ]="arabic",
+ ["arg" ]="aragonese",
+ ["ari" ]="aari",
+ ["ark" ]="rakhine",
+ ["asm" ]="assamese",
+ ["ast" ]="asturian",
+ ["ath" ]="athapaskan",
+ ["avr" ]="avar",
+ ["awa" ]="awadhi",
+ ["aym" ]="aymara",
+ ["azb" ]="torki",
+ ["aze" ]="azerbaijani",
+ ["bad" ]="badaga",
+ ["bad0"]="banda",
+ ["bag" ]="baghelkhandi",
+ ["bal" ]="balkar",
+ ["ban" ]="balinese",
+ ["bar" ]="bavarian",
+ ["bau" ]="baulé",
+ ["bbc" ]="batak toba",
+ ["bbr" ]="berber",
+ ["bch" ]="bench",
+ ["bcr" ]="bible cree",
+ ["bdy" ]="bandjalang",
+ ["bel" ]="belarussian",
+ ["bem" ]="bemba",
+ ["ben" ]="bengali",
+ ["bgc" ]="haryanvi",
+ ["bgq" ]="bagri",
+ ["bgr" ]="bulgarian",
+ ["bhi" ]="bhili",
+ ["bho" ]="bhojpuri",
+ ["bik" ]="bikol",
+ ["bil" ]="bilen",
+ ["bis" ]="bislama",
+ ["bjj" ]="kanauji",
+ ["bkf" ]="blackfoot",
+ ["bli" ]="baluchi",
+ ["blk" ]="pa'o karen",
+ ["bln" ]="balante",
+ ["blt" ]="balti",
+ ["bmb" ]="bambara (bamanankan)",
+ ["bml" ]="bamileke",
+ ["bos" ]="bosnian",
+ ["bpy" ]="bishnupriya manipuri",
+ ["bre" ]="breton",
+ ["brh" ]="brahui",
+ ["bri" ]="braj bhasha",
+ ["brm" ]="burmese",
+ ["brx" ]="bodo",
+ ["bsh" ]="bashkir",
+ ["bsk" ]="burushaski",
+ ["bti" ]="beti",
+ ["bts" ]="batak simalungun",
+ ["bug" ]="bugis",
+ ["byv" ]="medumba",
+ ["cak" ]="kaqchikel",
+ ["cat" ]="catalan",
+ ["cbk" ]="zamboanga chavacano",
+ ["cchn"]="chinantec",
+ ["ceb" ]="cebuano",
+ ["cgg" ]="chiga",
+ ["cha" ]="chamorro",
+ ["che" ]="chechen",
+ ["chg" ]="chaha gurage",
+ ["chh" ]="chattisgarhi",
+ ["chi" ]="chichewa (chewa, nyanja)",
+ ["chk" ]="chukchi",
+ ["chk0"]="chuukese",
+ ["cho" ]="choctaw",
+ ["chp" ]="chipewyan",
+ ["chr" ]="cherokee",
+ ["chu" ]="chuvash",
+ ["chy" ]="cheyenne",
+ ["cja" ]="western cham",
+ ["cjm" ]="eastern cham",
+ ["cmr" ]="comorian",
+ ["cop" ]="coptic",
+ ["cor" ]="cornish",
+ ["cos" ]="corsican",
+ ["cpp" ]="creoles",
+ ["cre" ]="cree",
+ ["crr" ]="carrier",
+ ["crt" ]="crimean tatar",
+ ["csb" ]="kashubian",
+ ["csl" ]="church slavonic",
+ ["csy" ]="czech",
+ ["ctg" ]="chittagonian",
+ ["cuk" ]="san blas kuna",
+ ["dan" ]="danish",
+ ["dar" ]="dargwa",
+ ["dax" ]="dayi",
+ ["dcr" ]="woods cree",
+ ["deu" ]="german",
+ ["dgo" ]="dogri",
+ ["dgr" ]="dogri",
+ ["dhg" ]="dhangu",
+ ["dhv" ]="divehi (dhivehi, maldivian)",
+ ["diq" ]="dimli",
+ ["div" ]="divehi (dhivehi, maldivian)",
+ ["djr" ]="zarma",
+ ["djr0"]="djambarrpuyngu",
+ ["dng" ]="dangme",
+ ["dnj" ]="dan",
+ ["dnk" ]="dinka",
+ ["dri" ]="dari",
+ ["duj" ]="dhuwal",
+ ["dun" ]="dungan",
+ ["dzn" ]="dzongkha",
+ ["ebi" ]="ebira",
+ ["ecr" ]="eastern cree",
+ ["edo" ]="edo",
+ ["efi" ]="efik",
+ ["ell" ]="greek",
+ ["emk" ]="eastern maninkakan",
+ ["eng" ]="english",
+ ["erz" ]="erzya",
+ ["esp" ]="spanish",
+ ["esu" ]="central yupik",
+ ["eti" ]="estonian",
+ ["euq" ]="basque",
+ ["evk" ]="evenki",
+ ["evn" ]="even",
+ ["ewe" ]="ewe",
+ ["fan" ]="french antillean",
+ ["fan0"]=" fang",
+ ["far" ]="persian",
+ ["fat" ]="fanti",
+ ["fin" ]="finnish",
+ ["fji" ]="fijian",
+ ["fle" ]="dutch (flemish)",
+ ["fmp" ]="fe’fe’",
+ ["fne" ]="forest nenets",
+ ["fon" ]="fon",
+ ["fos" ]="faroese",
+ ["fra" ]="french",
+ ["frc" ]="cajun french",
+ ["fri" ]="frisian",
+ ["frl" ]="friulian",
+ ["frp" ]="arpitan",
+ ["fta" ]="futa",
+ ["ful" ]="fulah",
+ ["fuv" ]="nigerian fulfulde",
+ ["gad" ]="ga",
+ ["gae" ]="scottish gaelic (gaelic)",
+ ["gag" ]="gagauz",
+ ["gal" ]="galician",
+ ["gar" ]="garshuni",
+ ["gaw" ]="garhwali",
+ ["gez" ]="ge'ez",
+ ["gih" ]="githabul",
+ ["gil" ]="gilyak",
+ ["gil0"]="kiribati (gilbertese)",
+ ["gkp" ]="kpelle (guinea)",
+ ["glk" ]="gilaki",
+ ["gmz" ]="gumuz",
+ ["gnn" ]="gumatj",
+ ["gog" ]="gogo",
+ ["gon" ]="gondi",
+ ["grn" ]="greenlandic",
+ ["gro" ]="garo",
+ ["gua" ]="guarani",
+ ["guc" ]="wayuu",
+ ["guf" ]="gupapuyngu",
+ ["guj" ]="gujarati",
+ ["guz" ]="gusii",
+ ["hai" ]="haitian (haitian creole)",
+ ["hal" ]="halam",
+ ["har" ]="harauti",
+ ["hau" ]="hausa",
+ ["haw" ]="hawaiian",
+ ["hay" ]="haya",
+ ["haz" ]="hazaragi",
+ ["hbn" ]="hammer-banna",
+ ["her" ]="herero",
+ ["hil" ]="hiligaynon",
+ ["hin" ]="hindi",
+ ["hma" ]="high mari",
+ ["hmn" ]="hmong",
+ ["hmo" ]="hiri motu",
+ ["hnd" ]="hindko",
+ ["ho" ]="ho",
+ ["hri" ]="harari",
+ ["hrv" ]="croatian",
+ ["hun" ]="hungarian",
+ ["hye" ]="armenian",
+ ["hye0"]="armenian east",
+ ["iba" ]="iban",
+ ["ibb" ]="ibibio",
+ ["ibo" ]="igbo",
+ ["ido" ]="ido",
+ ["ijo" ]="ijo languages",
+ ["ile" ]="interlingue",
+ ["ilo" ]="ilokano",
+ ["ina" ]="interlingua",
+ ["ind" ]="indonesian",
+ ["ing" ]="ingush",
+ ["inu" ]="inuktitut",
+ ["ipk" ]="inupiat",
+ ["ipph"]="phonetic transcription—ipa conventions",
+ ["iri" ]="irish",
+ ["irt" ]="irish traditional",
+ ["isl" ]="icelandic",
+ ["ism" ]="inari sami",
+ ["ita" ]="italian",
+ ["iwr" ]="hebrew",
+ ["jam" ]="jamaican creole",
+ ["jan" ]="japanese",
+ ["jav" ]="javanese",
+ ["jbo" ]="lojban",
+ ["jct" ]="krymchak",
+ ["jii" ]="yiddish",
+ ["jud" ]="ladino",
+ ["jul" ]="jula",
+ ["kab" ]="kabardian",
+ ["kab0"]="kabyle",
+ ["kac" ]="kachchi",
+ ["kal" ]="kalenjin",
+ ["kan" ]="kannada",
+ ["kar" ]="karachay",
+ ["kat" ]="georgian",
+ ["kaz" ]="kazakh",
+ ["kde" ]="makonde",
+ ["kea" ]="kabuverdianu (crioulo)",
+ ["keb" ]="kebena",
+ ["kek" ]="kekchi",
+ ["kge" ]="khutsuri georgian",
+ ["kha" ]="khakass",
+ ["khk" ]="khanty-kazim",
+ ["khm" ]="khmer",
+ ["khs" ]="khanty-shurishkar",
+ ["kht" ]="khamti shan",
+ ["khv" ]="khanty-vakhi",
+ ["khw" ]="khowar",
+ ["kik" ]="kikuyu (gikuyu)",
+ ["kir" ]="kirghiz (kyrgyz)",
+ ["kis" ]="kisii",
+ ["kiu" ]="kirmanjki",
+ ["kjd" ]="southern kiwai",
+ ["kjp" ]="eastern pwo karen",
+ ["kjz" ]="bumthangkha",
+ ["kkn" ]="kokni",
+ ["klm" ]="kalmyk",
+ ["kmb" ]="kamba",
+ ["kmn" ]="kumaoni",
+ ["kmo" ]="komo",
+ ["kms" ]="komso",
+ ["kmz" ]="khorasani turkic",
+ ["knr" ]="kanuri",
+ ["kod" ]="kodagu",
+ ["koh" ]="korean old hangul",
+ ["kok" ]="konkani",
+ ["kom" ]="komi",
+ ["kon" ]="kikongo",
+ ["kon0"]="kongo",
+ ["kop" ]="komi-permyak",
+ ["kor" ]="korean",
+ ["kos" ]="kosraean",
+ ["koz" ]="komi-zyrian",
+ ["kpl" ]="kpelle",
+ ["kri" ]="krio",
+ ["krk" ]="karakalpak",
+ ["krl" ]="karelian",
+ ["krm" ]="karaim",
+ ["krn" ]="karen",
+ ["krt" ]="koorete",
+ ["ksh" ]="kashmiri",
+ ["ksh0"]="ripuarian",
+ ["ksi" ]="khasi",
+ ["ksm" ]="kildin sami",
+ ["ksw" ]="s’gaw karen",
+ ["kua" ]="kuanyama",
+ ["kui" ]="kui",
+ ["kul" ]="kulvi",
+ ["kum" ]="kumyk",
+ ["kur" ]="kurdish",
+ ["kuu" ]="kurukh",
+ ["kuy" ]="kuy",
+ ["kyk" ]="koryak",
+ ["kyu" ]="western kayah",
+ ["lad" ]="ladin",
+ ["lah" ]="lahuli",
+ ["lak" ]="lak",
+ ["lam" ]="lambani",
+ ["lao" ]="lao",
+ ["lat" ]="latin",
+ ["laz" ]="laz",
+ ["lcr" ]="l-cree",
+ ["ldk" ]="ladakhi",
+ ["lez" ]="lezgi",
+ ["lij" ]="ligurian",
+ ["lim" ]="limburgish",
+ ["lin" ]="lingala",
+ ["lis" ]="lisu",
+ ["ljp" ]="lampung",
+ ["lki" ]="laki",
+ ["lma" ]="low mari",
+ ["lmb" ]="limbu",
+ ["lmo" ]="lombard",
+ ["lmw" ]="lomwe",
+ ["lom" ]="loma",
+ ["lrc" ]="luri",
+ ["lsb" ]="lower sorbian",
+ ["lsm" ]="lule sami",
+ ["lth" ]="lithuanian",
+ ["ltz" ]="luxembourgish",
+ ["lua" ]="luba-lulua",
+ ["lub" ]="luba-katanga",
+ ["lug" ]="ganda",
+ ["luh" ]="luyia",
+ ["luo" ]="luo",
+ ["lvi" ]="latvian",
+ ["mad" ]="madura",
+ ["mag" ]="magahi",
+ ["mah" ]="marshallese",
+ ["maj" ]="majang",
+ ["mak" ]="makhuwa",
+ ["mal" ]="malayalam reformed",
+ ["mam" ]="mam",
+ ["man" ]="mansi",
+ ["map" ]="mapudungun",
+ ["mar" ]="marathi",
+ ["maw" ]="marwari",
+ ["mbn" ]="mbundu",
+ ["mbo" ]="mbo",
+ ["mch" ]="manchu",
+ ["mcr" ]="moose cree",
+ ["mde" ]="mende",
+ ["mdr" ]="mandar",
+ ["men" ]="me'en",
+ ["mer" ]="meru",
+ ["mfa" ]="pattani malay",
+ ["mfe" ]="morisyen",
+ ["min" ]="minangkabau",
+ ["miz" ]="mizo",
+ ["mkd" ]="macedonian",
+ ["mkr" ]="makasar",
+ ["mkw" ]="kituba",
+ ["mle" ]="male",
+ ["mlg" ]="malagasy",
+ ["mln" ]="malinke",
+ ["mlr" ]="malayalam reformed",
+ ["mly" ]="malay",
+ ["mnd" ]="mandinka",
+ ["mng" ]="mongolian",
+ ["mni" ]="manipuri",
+ ["mnk" ]="maninka",
+ ["mnx" ]="manx",
+ ["moh" ]="mohawk",
+ ["mok" ]="moksha",
+ ["mol" ]="moldavian",
+ ["mon" ]="mon",
+ ["mor" ]="moroccan",
+ ["mos" ]="mossi",
+ ["mri" ]="maori",
+ ["mth" ]="maithili",
+ ["mts" ]="maltese",
+ ["mun" ]="mundari",
+ ["mus" ]="muscogee",
+ ["mwl" ]="mirandese",
+ ["mww" ]="hmong daw",
+ ["myn" ]="mayan",
+ ["mzn" ]="mazanderani",
+ ["nag" ]="naga-assamese",
+ ["nah" ]="nahuatl",
+ ["nan" ]="nanai",
+ ["nap" ]="neapolitan",
+ ["nas" ]="naskapi",
+ ["nau" ]="nauruan",
+ ["nav" ]="navajo",
+ ["ncr" ]="n-cree",
+ ["ndb" ]="ndebele",
+ ["ndc" ]="ndau",
+ ["ndg" ]="ndonga",
+ ["nds" ]="low saxon",
+ ["nep" ]="nepali",
+ ["new" ]="newari",
+ ["nga" ]="ngbaka",
+ ["ngr" ]="nagari",
+ ["nhc" ]="norway house cree",
+ ["nis" ]="nisi",
+ ["niu" ]="niuean",
+ ["nkl" ]="nyankole",
+ ["nko" ]="n'ko",
+ ["nld" ]="dutch",
+ ["noe" ]="nimadi",
+ ["nog" ]="nogai",
+ ["nor" ]="norwegian",
+ ["nov" ]="novial",
+ ["nsm" ]="northern sami",
+ ["nso" ]="sotho, northern",
+ ["nta" ]="northern tai",
+ ["nto" ]="esperanto",
+ ["nym" ]="nyamwezi",
+ ["nyn" ]="norwegian nynorsk",
+ ["nza" ]="mbembe tigon",
+ ["oci" ]="occitan",
+ ["ocr" ]="oji-cree",
+ ["ojb" ]="ojibway",
+ ["ori" ]="odia",
+ ["oro" ]="oromo",
+ ["oss" ]="ossetian",
+ ["paa" ]="palestinian aramaic",
+ ["pag" ]="pangasinan",
+ ["pal" ]="pali",
+ ["pam" ]="pampangan",
+ ["pan" ]="punjabi",
+ ["pap" ]="palpa",
+ ["pap0"]="papiamentu",
+ ["pas" ]="pashto",
+ ["pau" ]="palauan",
+ ["pcc" ]="bouyei",
+ ["pcd" ]="picard",
+ ["pdc" ]="pennsylvania german",
+ ["pgr" ]="polytonic greek",
+ ["phk" ]="phake",
+ ["pih" ]="norfolk",
+ ["pil" ]="filipino",
+ ["plg" ]="palaung",
+ ["plk" ]="polish",
+ ["pms" ]="piemontese",
+ ["pnb" ]="western panjabi",
+ ["poh" ]="pocomchi",
+ ["pon" ]="pohnpeian",
+ ["pro" ]="provencal",
+ ["ptg" ]="portuguese",
+ ["pwo" ]="western pwo karen",
+ ["qin" ]="chin",
+ ["quc" ]="k’iche’",
+ ["quh" ]="quechua (bolivia)",
+ ["quz" ]="quechua",
+ ["qvi" ]="quechua (ecuador)",
+ ["qwh" ]="quechua (peru)",
+ ["raj" ]="rajasthani",
+ ["rar" ]="rarotongan",
+ ["rbu" ]="russian buriat",
+ ["rcr" ]="r-cree",
+ ["rej" ]="rejang",
+ ["ria" ]="riang",
+ ["rif" ]="tarifit",
+ ["rit" ]="ritarungo",
+ ["rkw" ]="arakwal",
+ ["rms" ]="romansh",
+ ["rmy" ]="vlax romani",
+ ["rom" ]="romanian",
+ ["roy" ]="romany",
+ ["rsy" ]="rusyn",
+ ["rtm" ]="rotuman",
+ ["rua" ]="kinyarwanda",
+ ["run" ]="rundi",
+ ["rup" ]="aromanian",
+ ["rus" ]="russian",
+ ["sad" ]="sadri",
+ ["san" ]="sanskrit",
+ ["sas" ]="sasak",
+ ["sat" ]="santali",
+ ["say" ]="sayisi",
+ ["scn" ]="sicilian",
+ ["sco" ]="scots",
+ ["scs" ]="north slavey",
+ ["sek" ]="sekota",
+ ["sel" ]="selkup",
+ ["sga" ]="old irish",
+ ["sgo" ]="sango",
+ ["sgs" ]="samogitian",
+ ["shi" ]="tachelhit",
+ ["shn" ]="shan",
+ ["sib" ]="sibe",
+ ["sid" ]="sidamo",
+ ["sig" ]="silte gurage",
+ ["sks" ]="skolt sami",
+ ["sky" ]="slovak",
+ ["sla" ]="slavey",
+ ["slv" ]="slovenian",
+ ["sml" ]="somali",
+ ["smo" ]="samoan",
+ ["sna" ]="sena",
+ ["sna0"]="shona",
+ ["snd" ]="sindhi",
+ ["snh" ]="sinhala (sinhalese)",
+ ["snk" ]="soninke",
+ ["sog" ]="sodo gurage",
+ ["sop" ]="songe",
+ ["sot" ]="sotho, southern",
+ ["sqi" ]="albanian",
+ ["srb" ]="serbian",
+ ["srd" ]="sardinian",
+ ["srk" ]="saraiki",
+ ["srr" ]="serer",
+ ["ssl" ]="south slavey",
+ ["ssm" ]="southern sami",
+ ["stq" ]="saterland frisian",
+ ["suk" ]="sukuma",
+ ["sun" ]="sundanese",
+ ["sur" ]="suri",
+ ["sva" ]="svan",
+ ["sve" ]="swedish",
+ ["swa" ]="swadaya aramaic",
+ ["swk" ]="swahili",
+ ["swz" ]="swati",
+ ["sxt" ]="sutu",
+ ["sxu" ]="upper saxon",
+ ["syl" ]="sylheti",
+ ["syr" ]="syriac",
+ ["syre"]="estrangela syriac",
+ ["syrj"]="western syriac",
+ ["syrn"]="eastern syriac",
+ ["szl" ]="silesian",
+ ["tab" ]="tabasaran",
+ ["taj" ]="tajiki",
+ ["tam" ]="tamil",
+ ["tat" ]="tatar",
+ ["tcr" ]="th-cree",
+ ["tdd" ]="dehong dai",
+ ["tel" ]="telugu",
+ ["tet" ]="tetum",
+ ["tgl" ]="tagalog",
+ ["tgn" ]="tongan",
+ ["tgr" ]="tigre",
+ ["tgy" ]="tigrinya",
+ ["tha" ]="thai",
+ ["tht" ]="tahitian",
+ ["tib" ]="tibetan",
+ ["tiv" ]="tiv",
+ ["tkm" ]="turkmen",
+ ["tmh" ]="tamashek",
+ ["tmn" ]="temne",
+ ["tna" ]="tswana",
+ ["tne" ]="tundra nenets",
+ ["tng" ]="tonga",
+ ["tod" ]="todo",
+ ["tod0"]="toma",
+ ["tpi" ]="tok pisin",
+ ["trk" ]="turkish",
+ ["tsg" ]="tsonga",
+ ["tsj" ]="tshangla",
+ ["tua" ]="turoyo aramaic",
+ ["tul" ]="tulu",
+ ["tum" ]="tulu",
+ ["tuv" ]="tuvin",
+ ["tvl" ]="tuvalu",
+ ["twi" ]="twi",
+ ["tyz" ]="tày",
+ ["tzm" ]="tamazight",
+ ["tzo" ]="tzotzil",
+ ["udm" ]="udmurt",
+ ["ukr" ]="ukrainian",
+ ["umb" ]="umbundu",
+ ["urd" ]="urdu",
+ ["usb" ]="upper sorbian",
+ ["uyg" ]="uyghur",
+ ["uzb" ]="uzbek",
+ ["vec" ]="venetian",
+ ["ven" ]="venda",
+ ["vit" ]="vietnamese",
+ ["vol" ]="volapük",
+ ["vro" ]="võro",
+ ["wa" ]="wa",
+ ["wag" ]="wagdi",
+ ["war" ]="waray-waray",
+ ["wcr" ]="west-cree",
+ ["wel" ]="welsh",
+ ["wlf" ]="wolof",
+ ["wln" ]="walloon",
+ ["wtm" ]="mewati",
+ ["xbd" ]="lü",
+ ["xhs" ]="xhosa",
+ ["xjb" ]="minjangbal",
+ ["xkf" ]="khengkha",
+ ["xog" ]="soga",
+ ["xpe" ]="kpelle (liberia)",
+ ["yak" ]="sakha",
+ ["yao" ]="yao",
+ ["yap" ]="yapese",
+ ["yba" ]="yoruba",
+ ["ycr" ]="y-cree",
+ ["yic" ]="yi classic",
+ ["yim" ]="yi modern",
+ ["zea" ]="zealandic",
+ ["zgh" ]="standard morrocan tamazigh",
+ ["zha" ]="zhuang",
+ ["zhh" ]="chinese, hong kong sar",
+ ["zhp" ]="chinese phonetic",
+ ["zhs" ]="chinese simplified",
+ ["zht" ]="chinese traditional",
+ ["znd" ]="zande",
+ ["zul" ]="zulu",
+ ["zza" ]="zazaki",
+}
+local features=allocate {
+ ["aalt"]="access all alternates",
+ ["abvf"]="above-base forms",
+ ["abvm"]="above-base mark positioning",
+ ["abvs"]="above-base substitutions",
+ ["afrc"]="alternative fractions",
+ ["akhn"]="akhands",
+ ["blwf"]="below-base forms",
+ ["blwm"]="below-base mark positioning",
+ ["blws"]="below-base substitutions",
+ ["c2pc"]="petite capitals from capitals",
+ ["c2sc"]="small capitals from capitals",
+ ["calt"]="contextual alternates",
+ ["case"]="case-sensitive forms",
+ ["ccmp"]="glyph composition/decomposition",
+ ["cfar"]="conjunct form after ro",
+ ["cjct"]="conjunct forms",
+ ["clig"]="contextual ligatures",
+ ["cpct"]="centered cjk punctuation",
+ ["cpsp"]="capital spacing",
+ ["cswh"]="contextual swash",
+ ["curs"]="cursive positioning",
+ ["dflt"]="default processing",
+ ["dist"]="distances",
+ ["dlig"]="discretionary ligatures",
+ ["dnom"]="denominators",
+ ["dtls"]="dotless forms",
+ ["expt"]="expert forms",
+ ["falt"]="final glyph alternates",
+ ["fin2"]="terminal forms #2",
+ ["fin3"]="terminal forms #3",
+ ["fina"]="terminal forms",
+ ["flac"]="flattened accents over capitals",
+ ["frac"]="fractions",
+ ["fwid"]="full width",
+ ["half"]="half forms",
+ ["haln"]="halant forms",
+ ["halt"]="alternate half width",
+ ["hist"]="historical forms",
+ ["hkna"]="horizontal kana alternates",
+ ["hlig"]="historical ligatures",
+ ["hngl"]="hangul",
+ ["hojo"]="hojo kanji forms",
+ ["hwid"]="half width",
+ ["init"]="initial forms",
+ ["isol"]="isolated forms",
+ ["ital"]="italics",
+ ["jalt"]="justification alternatives",
+ ["jp04"]="jis2004 forms",
+ ["jp78"]="jis78 forms",
+ ["jp83"]="jis83 forms",
+ ["jp90"]="jis90 forms",
+ ["kern"]="kerning",
+ ["lfbd"]="left bounds",
+ ["liga"]="standard ligatures",
+ ["ljmo"]="leading jamo forms",
+ ["lnum"]="lining figures",
+ ["locl"]="localized forms",
+ ["ltra"]="left-to-right alternates",
+ ["ltrm"]="left-to-right mirrored forms",
+ ["mark"]="mark positioning",
+ ["med2"]="medial forms #2",
+ ["medi"]="medial forms",
+ ["mgrk"]="mathematical greek",
+ ["mkmk"]="mark to mark positioning",
+ ["mset"]="mark positioning via substitution",
+ ["nalt"]="alternate annotation forms",
+ ["nlck"]="nlc kanji forms",
+ ["nukt"]="nukta forms",
+ ["numr"]="numerators",
+ ["onum"]="old style figures",
+ ["opbd"]="optical bounds",
+ ["ordn"]="ordinals",
+ ["ornm"]="ornaments",
+ ["palt"]="proportional alternate width",
+ ["pcap"]="petite capitals",
+ ["pkna"]="proportional kana",
+ ["pnum"]="proportional figures",
+ ["pref"]="pre-base forms",
+ ["pres"]="pre-base substitutions",
+ ["pstf"]="post-base forms",
+ ["psts"]="post-base substitutions",
+ ["pwid"]="proportional widths",
+ ["qwid"]="quarter widths",
+ ["rand"]="randomize",
+ ["rclt"]="required contextual alternates",
+ ["rkrf"]="rakar forms",
+ ["rlig"]="required ligatures",
+ ["rphf"]="reph form",
+ ["rtbd"]="right bounds",
+ ["rtla"]="right-to-left alternates",
+ ["rtlm"]="right to left mirrored forms",
+ ["rvrn"]="required variation alternates",
+ ["ruby"]="ruby notation forms",
+ ["salt"]="stylistic alternates",
+ ["sinf"]="scientific inferiors",
+ ["size"]="optical size",
+ ["smcp"]="small capitals",
+ ["smpl"]="simplified forms",
+ ["ssty"]="script style",
+ ["stch"]="stretching glyph decomposition",
+ ["subs"]="subscript",
+ ["sups"]="superscript",
+ ["swsh"]="swash",
+ ["titl"]="titling",
+ ["tjmo"]="trailing jamo forms",
+ ["tnam"]="traditional name forms",
+ ["tnum"]="tabular figures",
+ ["trad"]="traditional forms",
+ ["twid"]="third widths",
+ ["unic"]="unicase",
+ ["valt"]="alternate vertical metrics",
+ ["vatu"]="vattu variants",
+ ["vert"]="vertical writing",
+ ["vhal"]="alternate vertical half metrics",
+ ["vjmo"]="vowel jamo forms",
+ ["vkna"]="vertical kana alternates",
+ ["vkrn"]="vertical kerning",
+ ["vpal"]="proportional alternate vertical metrics",
+ ["vrtr"]="vertical alternates for rotation",
+ ["vrt2"]="vertical rotation",
+ ["zero"]="slashed zero",
+ ["trep"]="traditional tex replacements",
+ ["tlig"]="traditional tex ligatures",
+ ["ss.."]="stylistic set ..",
+ ["cv.."]="character variant ..",
+ ["js.."]="justification ..",
+ ["dv.."]="devanagari ..",
+ ["ml.."]="malayalam ..",
+}
+local baselines=allocate {
+ ["hang"]="hanging baseline",
+ ["icfb"]="ideographic character face bottom edge baseline",
+ ["icft"]="ideographic character face tope edige baseline",
+ ["ideo"]="ideographic em-box bottom edge baseline",
+ ["idtp"]="ideographic em-box top edge baseline",
+ ["math"]="mathematical centered baseline",
+ ["romn"]="roman baseline"
+}
+tables.scripts=scripts
+tables.languages=languages
+tables.features=features
+tables.baselines=baselines
+local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end)
+local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end)
+local report_checks=logs.reporter("fonts","checks")
+if otffeatures.features then
+ for k,v in next,otffeatures.features do
+ features[k]=v
+ end
+ otffeatures.features=features
+end
+local function swapped(h)
+ local r={}
+ for k,v in next,h do
+ r[gsub(v,"[^a-z0-9]","")]=k
+ end
+ return r
+end
+local verbosescripts=allocate(swapped(scripts ))
+local verboselanguages=allocate(swapped(languages))
+local verbosefeatures=allocate(swapped(features ))
+local verbosebaselines=allocate(swapped(baselines))
+local function resolve(t,k)
+ if k then
+ k=gsub(lower(k),"[^a-z0-9]","")
+ local v=rawget(t,k)
+ if v then
+ return v
+ end
+ end
+end
+setmetatableindex(verbosescripts,resolve)
+setmetatableindex(verboselanguages,resolve)
+setmetatableindex(verbosefeatures,resolve)
+setmetatableindex(verbosebaselines,resolve)
+setmetatableindex(scripts,function(t,k)
+ if k then
+ k=lower(k)
+ if k=="dflt" then
+ return k
+ end
+ local v=rawget(t,k)
+ if v then
+ return v
+ end
+ k=gsub(k," ","")
+ v=rawget(t,v)
+ if v then
+ return v
+ elseif acceptscripts then
+ report_checks("registering extra script %a",k)
+ rawset(t,k,k)
+ return k
+ end
+ end
+ return "dflt"
+end)
+setmetatableindex(languages,function(t,k)
+ if k then
+ k=lower(k)
+ if k=="dflt" then
+ return k
+ end
+ local v=rawget(t,k)
+ if v then
+ return v
+ end
+ k=gsub(k," ","")
+ v=rawget(t,v)
+ if v then
+ return v
+ elseif acceptlanguages then
+ report_checks("registering extra language %a",k)
+ rawset(t,k,k)
+ return k
+ end
+ end
+ return "dflt"
+end)
+if setmetatablenewindex then
+ setmetatablenewindex(languages,"ignore")
+ setmetatablenewindex(scripts,"ignore")
+ setmetatablenewindex(baselines,"ignore")
+end
+local function resolve(t,k)
+ if k then
+ k=lower(k)
+ local v=rawget(t,k)
+ if v then
+ return v
+ end
+ k=gsub(k," ","")
+ local v=rawget(t,k)
+ if v then
+ return v
+ end
+ local tag,dd=match(k,"(..)(%d+)")
+ if tag and dd then
+ local v=rawget(t,tag)
+ if v then
+ return v
+ else
+ local v=rawget(t,tag.."..")
+ if v then
+ return (gsub(v,"%.%.",tonumber(dd)))
+ end
+ end
+ end
+ end
+ return k
+end
+setmetatableindex(features,resolve)
+local function assign(t,k,v)
+ if k and v then
+ v=lower(v)
+ rawset(t,k,v)
+ end
+end
+if setmetatablenewindex then
+ setmetatablenewindex(features,assign)
+end
+local checkers={
+ rand=function(v)
+ return v==true and "random" or v
+ end
+}
+if not storage then
+ return
+end
+local usedfeatures=statistics.usedfeatures or {}
+statistics.usedfeatures=usedfeatures
+table.setmetatableindex(usedfeatures,function(t,k) if k then local v={} t[k]=v return v end end)
+storage.register("fonts/otf/usedfeatures",usedfeatures,"fonts.handlers.otf.statistics.usedfeatures" )
+local normalizedaxis=otf.readers.helpers.normalizedaxis or function(s) return s end
+function otffeatures.normalize(features,wrap)
+ if features then
+ local h={}
+ for key,value in next,features do
+ local k=lower(key)
+ if k=="language" then
+ local v=gsub(lower(value),"[^a-z0-9]","")
+ h.language=rawget(verboselanguages,v) or (languages[v] and v) or "dflt"
+ elseif k=="script" then
+ local v=gsub(lower(value),"[^a-z0-9]","")
+ h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt"
+ elseif k=="axis" then
+ h[k]=normalizedaxis(value)
+ if not callbacks.supported.glyph_stream_provider then
+ h.variableshapes=true
+ end
+ else
+ local uk=usedfeatures[key]
+ local uv=uk[value]
+ if uv then
+ else
+ uv=tonumber(value)
+ if uv then
+ elseif type(value)=="string" then
+ local b=is_boolean(value)
+ if type(b)=="nil" then
+ if wrap and find(value,",") then
+ uv="{"..lower(value).."}"
+ else
+ uv=lower(value)
+ end
+ else
+ uv=b
+ end
+ elseif type(value)=="table" then
+ uv=sequenced(t,",")
+ else
+ uv=value
+ end
+ if not rawget(features,k) then
+ k=rawget(verbosefeatures,k) or k
+ end
+ local c=checkers[k]
+ if c then
+ uv=c(uv) or vc
+ end
+ uk[value]=uv
+ end
+ h[k]=uv
+ end
+ end
+ return h
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-cff']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type,tonumber,rawget=next,type,tonumber,rawget
+local byte,char,gmatch=string.byte,string.char,string.gmatch
+local concat,remove,unpack=table.concat,table.remove,table.unpack
+local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max
+local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct
+local lpegmatch=lpeg.match
+local formatters=string.formatters
+local bytetable=string.bytetable
+local idiv=number.idiv
+local rshift,band,extract=bit32.rshift,bit32.band,bit32.extract
+local readers=fonts.handlers.otf.readers
+local streamreader=readers.streamreader
+local readstring=streamreader.readstring
+local readbyte=streamreader.readcardinal1
+local readushort=streamreader.readcardinal2
+local readuint=streamreader.readcardinal3
+local readulong=streamreader.readcardinal4
+local setposition=streamreader.setposition
+local getposition=streamreader.getposition
+local readbytetable=streamreader.readbytetable
+directives.register("fonts.streamreader",function()
+ streamreader=utilities.streams
+ readstring=streamreader.readstring
+ readbyte=streamreader.readcardinal1
+ readushort=streamreader.readcardinal2
+ readuint=streamreader.readcardinal3
+ readulong=streamreader.readcardinal4
+ setposition=streamreader.setposition
+ getposition=streamreader.getposition
+ readbytetable=streamreader.readbytetable
+end)
+local setmetatableindex=table.setmetatableindex
+local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end)
+local report=logs.reporter("otf reader","cff")
+local parsedictionaries
+local parsecharstring
+local parsecharstrings
+local resetcharstrings
+local parseprivates
+local startparsing
+local stopparsing
+local defaultstrings={ [0]=
+ ".notdef","space","exclam","quotedbl","numbersign","dollar","percent",
+ "ampersand","quoteright","parenleft","parenright","asterisk","plus",
+ "comma","hyphen","period","slash","zero","one","two","three","four",
+ "five","six","seven","eight","nine","colon","semicolon","less",
+ "equal","greater","question","at","A","B","C","D","E","F","G","H",
+ "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W",
+ "X","Y","Z","bracketleft","backslash","bracketright","asciicircum",
+ "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j",
+ "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y",
+ "z","braceleft","bar","braceright","asciitilde","exclamdown","cent",
+ "sterling","fraction","yen","florin","section","currency",
+ "quotesingle","quotedblleft","guillemotleft","guilsinglleft",
+ "guilsinglright","fi","fl","endash","dagger","daggerdbl",
+ "periodcentered","paragraph","bullet","quotesinglbase","quotedblbase",
+ "quotedblright","guillemotright","ellipsis","perthousand","questiondown",
+ "grave","acute","circumflex","tilde","macron","breve","dotaccent",
+ "dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash",
+ "AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae",
+ "dotlessi","lslash","oslash","oe","germandbls","onesuperior",
+ "logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn",
+ "onequarter","divide","brokenbar","degree","thorn","threequarters",
+ "twosuperior","registered","minus","eth","multiply","threesuperior",
+ "copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring",
+ "Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave",
+ "Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute",
+ "Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute",
+ "Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron",
+ "aacute","acircumflex","adieresis","agrave","aring","atilde",
+ "ccedilla","eacute","ecircumflex","edieresis","egrave","iacute",
+ "icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex",
+ "odieresis","ograve","otilde","scaron","uacute","ucircumflex",
+ "udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall",
+ "Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall",
+ "Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader",
+ "onedotenleader","zerooldstyle","oneoldstyle","twooldstyle",
+ "threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle",
+ "sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior",
+ "threequartersemdash","periodsuperior","questionsmall","asuperior",
+ "bsuperior","centsuperior","dsuperior","esuperior","isuperior",
+ "lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior",
+ "tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior",
+ "Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall",
+ "Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall",
+ "Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall",
+ "Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall",
+ "Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah",
+ "Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall",
+ "Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall",
+ "Dotaccentsmall","Macronsmall","figuredash","hypheninferior",
+ "Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth",
+ "threeeighths","fiveeighths","seveneighths","onethird","twothirds",
+ "zerosuperior","foursuperior","fivesuperior","sixsuperior",
+ "sevensuperior","eightsuperior","ninesuperior","zeroinferior",
+ "oneinferior","twoinferior","threeinferior","fourinferior",
+ "fiveinferior","sixinferior","seveninferior","eightinferior",
+ "nineinferior","centinferior","dollarinferior","periodinferior",
+ "commainferior","Agravesmall","Aacutesmall","Acircumflexsmall",
+ "Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall",
+ "Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall",
+ "Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall",
+ "Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall",
+ "Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall",
+ "Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall",
+ "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003",
+ "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold",
+}
+local cffreaders={
+ readbyte,
+ readushort,
+ readuint,
+ readulong,
+}
+local function readheader(f)
+ local offset=getposition(f)
+ local major=readbyte(f)
+ local header={
+ offset=offset,
+ major=major,
+ minor=readbyte(f),
+ size=readbyte(f),
+ }
+ if major==1 then
+ header.dsize=readbyte(f)
+ elseif major==2 then
+ header.dsize=readushort(f)
+ else
+ end
+ setposition(f,offset+header.size)
+ return header
+end
+local function readlengths(f,longcount)
+ local count=longcount and readulong(f) or readushort(f)
+ if count==0 then
+ return {}
+ end
+ local osize=readbyte(f)
+ local read=cffreaders[osize]
+ if not read then
+ report("bad offset size: %i",osize)
+ return {}
+ end
+ local lengths={}
+ local previous=read(f)
+ for i=1,count do
+ local offset=read(f)
+ local length=offset-previous
+ if length<0 then
+ report("bad offset: %i",length)
+ length=0
+ end
+ lengths[i]=length
+ previous=offset
+ end
+ return lengths
+end
+local function readfontnames(f)
+ local names=readlengths(f)
+ for i=1,#names do
+ names[i]=readstring(f,names[i])
+ end
+ return names
+end
+local function readtopdictionaries(f)
+ local dictionaries=readlengths(f)
+ for i=1,#dictionaries do
+ dictionaries[i]=readstring(f,dictionaries[i])
+ end
+ return dictionaries
+end
+local function readstrings(f)
+ local lengths=readlengths(f)
+ local strings=setmetatableindex({},defaultstrings)
+ local index=#defaultstrings
+ for i=1,#lengths do
+ index=index+1
+ strings[index]=readstring(f,lengths[i])
+ end
+ return strings
+end
+do
+ local stack={}
+ local top=0
+ local result={}
+ local strings={}
+ local p_single=P("\00")/function()
+ result.version=strings[stack[top]] or "unset"
+ top=0
+ end+P("\01")/function()
+ result.notice=strings[stack[top]] or "unset"
+ top=0
+ end+P("\02")/function()
+ result.fullname=strings[stack[top]] or "unset"
+ top=0
+ end+P("\03")/function()
+ result.familyname=strings[stack[top]] or "unset"
+ top=0
+ end+P("\04")/function()
+ result.weight=strings[stack[top]] or "unset"
+ top=0
+ end+P("\05")/function()
+ result.fontbbox={ unpack(stack,1,4) }
+ top=0
+ end+P("\06")/function()
+ result.bluevalues={ unpack(stack,1,top) }
+ top=0
+ end+P("\07")/function()
+ result.otherblues={ unpack(stack,1,top) }
+ top=0
+ end+P("\08")/function()
+ result.familyblues={ unpack(stack,1,top) }
+ top=0
+ end+P("\09")/function()
+ result.familyotherblues={ unpack(stack,1,top) }
+ top=0
+ end+P("\10")/function()
+ result.strhw=stack[top]
+ top=0
+ end+P("\11")/function()
+ result.strvw=stack[top]
+ top=0
+ end+P("\13")/function()
+ result.uniqueid=stack[top]
+ top=0
+ end+P("\14")/function()
+ result.xuid=concat(stack,"",1,top)
+ top=0
+ end+P("\15")/function()
+ result.charset=stack[top]
+ top=0
+ end+P("\16")/function()
+ result.encoding=stack[top]
+ top=0
+ end+P("\17")/function()
+ result.charstrings=stack[top]
+ top=0
+ end+P("\18")/function()
+ result.private={
+ size=stack[top-1],
+ offset=stack[top],
+ }
+ top=0
+ end+P("\19")/function()
+ result.subroutines=stack[top]
+ top=0
+ end+P("\20")/function()
+ result.defaultwidthx=stack[top]
+ top=0
+ end+P("\21")/function()
+ result.nominalwidthx=stack[top]
+ top=0
+ end
++P("\24")/function()
+ result.vstore=stack[top]
+ top=0
+ end+P("\25")/function()
+ result.maxstack=stack[top]
+ top=0
+ end
+ local p_double=P("\12")*(
+ P("\00")/function()
+ result.copyright=stack[top]
+ top=0
+ end+P("\01")/function()
+ result.monospaced=stack[top]==1 and true or false
+ top=0
+ end+P("\02")/function()
+ result.italicangle=stack[top]
+ top=0
+ end+P("\03")/function()
+ result.underlineposition=stack[top]
+ top=0
+ end+P("\04")/function()
+ result.underlinethickness=stack[top]
+ top=0
+ end+P("\05")/function()
+ result.painttype=stack[top]
+ top=0
+ end+P("\06")/function()
+ result.charstringtype=stack[top]
+ top=0
+ end+P("\07")/function()
+ result.fontmatrix={ unpack(stack,1,6) }
+ top=0
+ end+P("\08")/function()
+ result.strokewidth=stack[top]
+ top=0
+ end+P("\09")/function()
+ result.bluescale=stack[top]
+ top=0
+ end+P("\10")/function()
+ result.bluesnap=stack[top]
+ top=0
+ end+P("\11")/function()
+ result.bluefuzz=stack[top]
+ top=0
+ end+P("\12")/function()
+ result.stemsnaph={ unpack(stack,1,top) }
+ top=0
+ end+P("\13")/function()
+ result.stemsnapv={ unpack(stack,1,top) }
+ top=0
+ end+P("\20")/function()
+ result.syntheticbase=stack[top]
+ top=0
+ end+P("\21")/function()
+ result.postscript=strings[stack[top]] or "unset"
+ top=0
+ end+P("\22")/function()
+ result.basefontname=strings[stack[top]] or "unset"
+ top=0
+ end+P("\21")/function()
+ result.basefontblend=stack[top]
+ top=0
+ end+P("\30")/function()
+ result.cid.registry=strings[stack[top-2]] or "unset"
+ result.cid.ordering=strings[stack[top-1]] or "unset"
+ result.cid.supplement=stack[top]
+ top=0
+ end+P("\31")/function()
+ result.cid.fontversion=stack[top]
+ top=0
+ end+P("\32")/function()
+ result.cid.fontrevision=stack[top]
+ top=0
+ end+P("\33")/function()
+ result.cid.fonttype=stack[top]
+ top=0
+ end+P("\34")/function()
+ result.cid.count=stack[top]
+ top=0
+ end+P("\35")/function()
+ result.cid.uidbase=stack[top]
+ top=0
+ end+P("\36")/function()
+ result.cid.fdarray=stack[top]
+ top=0
+ end+P("\37")/function()
+ result.cid.fdselect=stack[top]
+ top=0
+ end+P("\38")/function()
+ result.cid.fontname=strings[stack[top]] or "unset"
+ top=0
+ end
+ )
+ local remap={
+ ["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0",
+ ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="1.",["\x1B"]="1E",["\x1C"]="1E-",["\x1D"]="1",["\x1E"]="1-",["\x1F"]="1",
+ ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="2.",["\x2B"]="2E",["\x2C"]="2E-",["\x2D"]="2",["\x2E"]="2-",["\x2F"]="2",
+ ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="3.",["\x3B"]="3E",["\x3C"]="3E-",["\x3D"]="3",["\x3E"]="3-",["\x3F"]="3",
+ ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="4.",["\x4B"]="4E",["\x4C"]="4E-",["\x4D"]="4",["\x4E"]="4-",["\x4F"]="4",
+ ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="5.",["\x5B"]="5E",["\x5C"]="5E-",["\x5D"]="5",["\x5E"]="5-",["\x5F"]="5",
+ ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="6.",["\x6B"]="6E",["\x6C"]="6E-",["\x6D"]="6",["\x6E"]="6-",["\x6F"]="6",
+ ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="7.",["\x7B"]="7E",["\x7C"]="7E-",["\x7D"]="7",["\x7E"]="7-",["\x7F"]="7",
+ ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="8.",["\x8B"]="8E",["\x8C"]="8E-",["\x8D"]="8",["\x8E"]="8-",["\x8F"]="8",
+ ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="9.",["\x9B"]="9E",["\x9C"]="9E-",["\x9D"]="9",["\x9E"]="9-",["\x9F"]="9",
+ ["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".",
+ ["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E",
+ ["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-",
+ ["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-",
+ }
+ local p_last=S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")+R("\xF0\xFF")
+ local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0*(P(1)/remap))/function(n)
+ top=top+1
+ stack[top]=tonumber(n) or 0
+ end
+ local p_byte=C(R("\32\246"))/function(b0)
+ top=top+1
+ stack[top]=byte(b0)-139
+ end
+ local p_positive=C(R("\247\250"))*C(1)/function(b0,b1)
+ top=top+1
+ stack[top]=(byte(b0)-247)*256+byte(b1)+108
+ end
+ local p_negative=C(R("\251\254"))*C(1)/function(b0,b1)
+ top=top+1
+ stack[top]=-(byte(b0)-251)*256-byte(b1)-108
+ end
+ local p_short=P("\28")*C(1)*C(1)/function(b1,b2)
+ top=top+1
+ local n=0x100*byte(b1)+byte(b2)
+ if n>=0x8000 then
+ stack[top]=n-0xFFFF-1
+ else
+ stack[top]=n
+ end
+ end
+ local p_long=P("\29")*C(1)*C(1)*C(1)*C(1)/function(b1,b2,b3,b4)
+ top=top+1
+ local n=0x1000000*byte(b1)+0x10000*byte(b2)+0x100*byte(b3)+byte(b4)
+ if n>=0x8000000 then
+ stack[top]=n-0xFFFFFFFF-1
+ else
+ stack[top]=n
+ end
+ end
+ local p_unsupported=P(1)/function(detail)
+ top=0
+ end
+ local p_dictionary=(
+ p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported
+ )^1
+ parsedictionaries=function(data,dictionaries,what)
+ stack={}
+ strings=data.strings
+ for i=1,#dictionaries do
+ top=0
+ result=what=="cff" and {
+ monospaced=false,
+ italicangle=0,
+ underlineposition=-100,
+ underlinethickness=50,
+ painttype=0,
+ charstringtype=2,
+ fontmatrix={ 0.001,0,0,0.001,0,0 },
+ fontbbox={ 0,0,0,0 },
+ strokewidth=0,
+ charset=0,
+ encoding=0,
+ cid={
+ fontversion=0,
+ fontrevision=0,
+ fonttype=0,
+ count=8720,
+ }
+ } or {
+ charstringtype=2,
+ charset=0,
+ vstore=0,
+ cid={
+ },
+ }
+ lpegmatch(p_dictionary,dictionaries[i])
+ dictionaries[i]=result
+ end
+ result={}
+ top=0
+ stack={}
+ end
+ parseprivates=function(data,dictionaries)
+ stack={}
+ strings=data.strings
+ for i=1,#dictionaries do
+ local private=dictionaries[i].private
+ if private and private.data then
+ top=0
+ result={
+ forcebold=false,
+ languagegroup=0,
+ expansionfactor=0.06,
+ initialrandomseed=0,
+ subroutines=0,
+ defaultwidthx=0,
+ nominalwidthx=0,
+ cid={
+ },
+ }
+ lpegmatch(p_dictionary,private.data)
+ private.data=result
+ end
+ end
+ result={}
+ top=0
+ stack={}
+ end
+ local x=0
+ local y=0
+ local width=false
+ local r=0
+ local stems=0
+ local globalbias=0
+ local localbias=0
+ local nominalwidth=0
+ local defaultwidth=0
+ local charset=false
+ local globals=false
+ local locals=false
+ local depth=1
+ local xmin=0
+ local xmax=0
+ local ymin=0
+ local ymax=0
+ local checked=false
+ local keepcurve=false
+ local version=2
+ local regions=false
+ local nofregions=0
+ local region=false
+ local factors=false
+ local axis=false
+ local vsindex=0
+ local function showstate(where)
+ report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top)
+ end
+ local function showvalue(where,value,showstack)
+ if showstack then
+ report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top)
+ else
+ report("%w%-10s : %s",depth*2,where,tostring(value))
+ end
+ end
+ local function xymoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
+ end
+ if checked then
+ if x>xmax then xmax=x elseif x<xmin then xmin=x end
+ if y>ymax then ymax=y elseif y<ymin then ymin=y end
+ else
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ end
+ end
+ local function xmoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif x>xmax then
+ xmax=x
+ elseif x<xmin then
+ xmin=x
+ end
+ end
+ local function ymoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif y>ymax then
+ ymax=y
+ elseif y<ymin then
+ ymin=y
+ end
+ end
+ local function moveto()
+ if trace_charstrings then
+ showstate("moveto")
+ end
+ top=0
+ xymoveto()
+ end
+ local function xylineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if checked then
+ if x>xmax then xmax=x elseif x<xmin then xmin=x end
+ if y>ymax then ymax=y elseif y<ymin then ymin=y end
+ else
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ end
+ end
+ local function xlineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif x>xmax then
+ xmax=x
+ elseif x<xmin then
+ xmin=x
+ end
+ end
+ local function ylineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif y>ymax then
+ ymax=y
+ elseif y<ymin then
+ ymin=y
+ end
+ end
+ local function xycurveto(x1,y1,x2,y2,x3,y3)
+ if trace_charstrings then
+ showstate("curveto")
+ end
+ if keepcurve then
+ r=r+1
+ result[r]={ x1,y1,x2,y2,x3,y3,"c" }
+ end
+ if checked then
+ if x1>xmax then xmax=x1 elseif x1<xmin then xmin=x1 end
+ if y1>ymax then ymax=y1 elseif y1<ymin then ymin=y1 end
+ else
+ xmin=x1
+ ymin=y1
+ xmax=x1
+ ymax=y1
+ checked=true
+ end
+ if x2>xmax then xmax=x2 elseif x2<xmin then xmin=x2 end
+ if y2>ymax then ymax=y2 elseif y2<ymin then ymin=y2 end
+ if x3>xmax then xmax=x3 elseif x3<xmin then xmin=x3 end
+ if y3>ymax then ymax=y3 elseif y3<ymin then ymin=y3 end
+ end
+ local function rmoveto()
+ if not width then
+ if top>2 then
+ width=stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
+ end
+ else
+ width=true
+ end
+ end
+ if trace_charstrings then
+ showstate("rmoveto")
+ end
+ x=x+stack[top-1]
+ y=y+stack[top]
+ top=0
+ xymoveto()
+ end
+ local function hmoveto()
+ if not width then
+ if top>1 then
+ width=stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
+ end
+ else
+ width=true
+ end
+ end
+ if trace_charstrings then
+ showstate("hmoveto")
+ end
+ x=x+stack[top]
+ top=0
+ xmoveto()
+ end
+ local function vmoveto()
+ if not width then
+ if top>1 then
+ width=stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
+ end
+ else
+ width=true
+ end
+ end
+ if trace_charstrings then
+ showstate("vmoveto")
+ end
+ y=y+stack[top]
+ top=0
+ ymoveto()
+ end
+ local function rlineto()
+ if trace_charstrings then
+ showstate("rlineto")
+ end
+ for i=1,top,2 do
+ x=x+stack[i]
+ y=y+stack[i+1]
+ xylineto()
+ end
+ top=0
+ end
+ local function hlineto()
+ if trace_charstrings then
+ showstate("hlineto")
+ end
+ if top==1 then
+ x=x+stack[1]
+ xlineto()
+ else
+ local swap=true
+ for i=1,top do
+ if swap then
+ x=x+stack[i]
+ xlineto()
+ swap=false
+ else
+ y=y+stack[i]
+ ylineto()
+ swap=true
+ end
+ end
+ end
+ top=0
+ end
+ local function vlineto()
+ if trace_charstrings then
+ showstate("vlineto")
+ end
+ if top==1 then
+ y=y+stack[1]
+ ylineto()
+ else
+ local swap=false
+ for i=1,top do
+ if swap then
+ x=x+stack[i]
+ xlineto()
+ swap=false
+ else
+ y=y+stack[i]
+ ylineto()
+ swap=true
+ end
+ end
+ end
+ top=0
+ end
+ local function rrcurveto()
+ if trace_charstrings then
+ showstate("rrcurveto")
+ end
+ for i=1,top,6 do
+ local ax=x+stack[i]
+ local ay=y+stack[i+1]
+ local bx=ax+stack[i+2]
+ local by=ay+stack[i+3]
+ x=bx+stack[i+4]
+ y=by+stack[i+5]
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ top=0
+ end
+ local function hhcurveto()
+ if trace_charstrings then
+ showstate("hhcurveto")
+ end
+ local s=1
+ if top%2~=0 then
+ y=y+stack[1]
+ s=2
+ end
+ for i=s,top,4 do
+ local ax=x+stack[i]
+ local ay=y
+ local bx=ax+stack[i+1]
+ local by=ay+stack[i+2]
+ x=bx+stack[i+3]
+ y=by
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ top=0
+ end
+ local function vvcurveto()
+ if trace_charstrings then
+ showstate("vvcurveto")
+ end
+ local s=1
+ local d=0
+ if top%2~=0 then
+ d=stack[1]
+ s=2
+ end
+ for i=s,top,4 do
+ local ax=x+d
+ local ay=y+stack[i]
+ local bx=ax+stack[i+1]
+ local by=ay+stack[i+2]
+ x=bx
+ y=by+stack[i+3]
+ xycurveto(ax,ay,bx,by,x,y)
+ d=0
+ end
+ top=0
+ end
+ local function xxcurveto(swap)
+ local last=top%4~=0 and stack[top]
+ if last then
+ top=top-1
+ end
+ for i=1,top,4 do
+ local ax,ay,bx,by
+ if swap then
+ ax=x+stack[i]
+ ay=y
+ bx=ax+stack[i+1]
+ by=ay+stack[i+2]
+ y=by+stack[i+3]
+ if last and i+3==top then
+ x=bx+last
+ else
+ x=bx
+ end
+ swap=false
+ else
+ ax=x
+ ay=y+stack[i]
+ bx=ax+stack[i+1]
+ by=ay+stack[i+2]
+ x=bx+stack[i+3]
+ if last and i+3==top then
+ y=by+last
+ else
+ y=by
+ end
+ swap=true
+ end
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ top=0
+ end
+ local function hvcurveto()
+ if trace_charstrings then
+ showstate("hvcurveto")
+ end
+ xxcurveto(true)
+ end
+ local function vhcurveto()
+ if trace_charstrings then
+ showstate("vhcurveto")
+ end
+ xxcurveto(false)
+ end
+ local function rcurveline()
+ if trace_charstrings then
+ showstate("rcurveline")
+ end
+ for i=1,top-2,6 do
+ local ax=x+stack[i]
+ local ay=y+stack[i+1]
+ local bx=ax+stack[i+2]
+ local by=ay+stack[i+3]
+ x=bx+stack[i+4]
+ y=by+stack[i+5]
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ x=x+stack[top-1]
+ y=y+stack[top]
+ xylineto()
+ top=0
+ end
+ local function rlinecurve()
+ if trace_charstrings then
+ showstate("rlinecurve")
+ end
+ if top>6 then
+ for i=1,top-6,2 do
+ x=x+stack[i]
+ y=y+stack[i+1]
+ xylineto()
+ end
+ end
+ local ax=x+stack[top-5]
+ local ay=y+stack[top-4]
+ local bx=ax+stack[top-3]
+ local by=ay+stack[top-2]
+ x=bx+stack[top-1]
+ y=by+stack[top]
+ xycurveto(ax,ay,bx,by,x,y)
+ top=0
+ end
+ local function flex()
+ if trace_charstrings then
+ showstate("flex")
+ end
+ local ax=x+stack[1]
+ local ay=y+stack[2]
+ local bx=ax+stack[3]
+ local by=ay+stack[4]
+ local cx=bx+stack[5]
+ local cy=by+stack[6]
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx=cx+stack[7]
+ local dy=cy+stack[8]
+ local ex=dx+stack[9]
+ local ey=dy+stack[10]
+ x=ex+stack[11]
+ y=ey+stack[12]
+ xycurveto(dx,dy,ex,ey,x,y)
+ top=0
+ end
+ local function hflex()
+ if trace_charstrings then
+ showstate("hflex")
+ end
+ local ax=x+stack[1]
+ local ay=y
+ local bx=ax+stack[2]
+ local by=ay+stack[3]
+ local cx=bx+stack[4]
+ local cy=by
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx=cx+stack[5]
+ local dy=by
+ local ex=dx+stack[6]
+ local ey=y
+ x=ex+stack[7]
+ xycurveto(dx,dy,ex,ey,x,y)
+ top=0
+ end
+ local function hflex1()
+ if trace_charstrings then
+ showstate("hflex1")
+ end
+ local ax=x+stack[1]
+ local ay=y+stack[2]
+ local bx=ax+stack[3]
+ local by=ay+stack[4]
+ local cx=bx+stack[5]
+ local cy=by
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx=cx+stack[6]
+ local dy=by
+ local ex=dx+stack[7]
+ local ey=dy+stack[8]
+ x=ex+stack[9]
+ xycurveto(dx,dy,ex,ey,x,y)
+ top=0
+ end
+ local function flex1()
+ if trace_charstrings then
+ showstate("flex1")
+ end
+ local ax=x+stack[1]
+ local ay=y+stack[2]
+ local bx=ax+stack[3]
+ local by=ay+stack[4]
+ local cx=bx+stack[5]
+ local cy=by+stack[6]
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx=cx+stack[7]
+ local dy=cy+stack[8]
+ local ex=dx+stack[9]
+ local ey=dy+stack[10]
+ if abs(ex-x)>abs(ey-y) then
+ x=ex+stack[11]
+ else
+ y=ey+stack[11]
+ end
+ xycurveto(dx,dy,ex,ey,x,y)
+ top=0
+ end
+ local function getstem()
+ if top==0 then
+ elseif top%2~=0 then
+ if width then
+ remove(stack,1)
+ else
+ width=remove(stack,1)
+ if trace_charstrings then
+ showvalue("width",width)
+ end
+ end
+ top=top-1
+ end
+ if trace_charstrings then
+ showstate("stem")
+ end
+ stems=stems+idiv(top,2)
+ top=0
+ end
+ local function getmask()
+ if top==0 then
+ elseif top%2~=0 then
+ if width then
+ remove(stack,1)
+ else
+ width=remove(stack,1)
+ if trace_charstrings then
+ showvalue("width",width)
+ end
+ end
+ top=top-1
+ end
+ if trace_charstrings then
+ showstate(operator==19 and "hintmark" or "cntrmask")
+ end
+ stems=stems+idiv(top,2)
+ top=0
+ if stems==0 then
+ elseif stems<=8 then
+ return 1
+ else
+ return idiv(stems+7,8)
+ end
+ end
+ local function unsupported(t)
+ if trace_charstrings then
+ showstate("unsupported "..t)
+ end
+ top=0
+ end
+ local function unsupportedsub(t)
+ if trace_charstrings then
+ showstate("unsupported sub "..t)
+ end
+ top=0
+ end
+ local function getstem3()
+ if trace_charstrings then
+ showstate("stem3")
+ end
+ top=0
+ end
+ local function divide()
+ if version==1 then
+ local d=stack[top]
+ top=top-1
+ stack[top]=stack[top]/d
+ end
+ end
+ local function closepath()
+ if version==1 then
+ if trace_charstrings then
+ showstate("closepath")
+ end
+ end
+ top=0
+ end
+ local function hsbw()
+ if version==1 then
+ if trace_charstrings then
+ showstate("hsbw")
+ end
+ width=stack[top]
+ end
+ top=0
+ end
+ local function seac()
+ if version==1 then
+ if trace_charstrings then
+ showstate("seac")
+ end
+ end
+ top=0
+ end
+ local function sbw()
+ if version==1 then
+ if trace_charstrings then
+ showstate("sbw")
+ end
+ width=stack[top-1]
+ end
+ top=0
+ end
+ local function callothersubr()
+ if version==1 then
+ if trace_charstrings then
+ showstate("callothersubr (unsupported)")
+ end
+ end
+ top=0
+ end
+ local function pop()
+ if version==1 then
+ if trace_charstrings then
+ showstate("pop (unsupported)")
+ end
+ top=top+1
+ stack[top]=0
+ else
+ top=0
+ end
+ end
+ local function setcurrentpoint()
+ if version==1 then
+ if trace_charstrings then
+ showstate("pop (unsupported)")
+ end
+ x=x+stack[top-1]
+ y=y+stack[top]
+ end
+ top=0
+ end
+ local reginit=false
+ local function updateregions(n)
+ if regions then
+ local current=regions[n] or regions[1]
+ nofregions=#current
+ if axis and n~=reginit then
+ factors={}
+ for i=1,nofregions do
+ local region=current[i]
+ local s=1
+ for j=1,#axis do
+ local f=axis[j]
+ local r=region[j]
+ local start=r.start
+ local peak=r.peak
+ local stop=r.stop
+ if start>peak or peak>stop then
+ elseif start<0 and stop>0 and peak~=0 then
+ elseif peak==0 then
+ elseif f<start or f>stop then
+ s=0
+ break
+ elseif f<peak then
+ s=s*(f-start)/(peak-start)
+ elseif f>peak then
+ s=s*(stop-f)/(stop-peak)
+ else
+ end
+ end
+ factors[i]=s
+ end
+ end
+ end
+ reginit=n
+ end
+ local function setvsindex()
+ local vsindex=stack[top]
+ if trace_charstrings then
+ showstate(formatters["vsindex %i"](vsindex))
+ end
+ updateregions(vsindex)
+ top=top-1
+ end
+ local function blend()
+ local n=stack[top]
+ top=top-1
+ if axis then
+ if trace_charstrings then
+ local t=top-nofregions*n
+ local m=t-n
+ for i=1,n do
+ local k=m+i
+ local d=m+n+(i-1)*nofregions
+ local old=stack[k]
+ local new=old
+ for r=1,nofregions do
+ new=new+stack[d+r]*factors[r]
+ end
+ stack[k]=new
+ showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new))
+ end
+ top=t
+ elseif n==1 then
+ top=top-nofregions
+ local v=stack[top]
+ for r=1,nofregions do
+ v=v+stack[top+r]*factors[r]
+ end
+ stack[top]=v
+ else
+ top=top-nofregions*n
+ local d=top
+ local k=top-n
+ for i=1,n do
+ k=k+1
+ local v=stack[k]
+ for r=1,nofregions do
+ v=v+stack[d+r]*factors[r]
+ end
+ stack[k]=v
+ d=d+nofregions
+ end
+ end
+ else
+ end
+ end
+ local actions={ [0]=unsupported,
+ getstem,
+ unsupported,
+ getstem,
+ vmoveto,
+ rlineto,
+ hlineto,
+ vlineto,
+ rrcurveto,
+ unsupported,
+ unsupported,
+ unsupported,
+ unsupported,
+ hsbw,
+ unsupported,
+ setvsindex,
+ blend,
+ unsupported,
+ getstem,
+ getmask,
+ getmask,
+ rmoveto,
+ hmoveto,
+ getstem,
+ rcurveline,
+ rlinecurve,
+ vvcurveto,
+ hhcurveto,
+ unsupported,
+ unsupported,
+ vhcurveto,
+ hvcurveto,
+ }
+ local subactions={
+ [000]=dotsection,
+ [001]=getstem3,
+ [002]=getstem3,
+ [006]=seac,
+ [007]=sbw,
+ [012]=divide,
+ [016]=callothersubr,
+ [017]=pop,
+ [033]=setcurrentpoint,
+ [034]=hflex,
+ [035]=flex,
+ [036]=hflex1,
+ [037]=flex1,
+ }
+ local chars=setmetatableindex(function (t,k)
+ local v=char(k)
+ t[k]=v
+ return v
+ end)
+ local c_endchar=chars[14]
+ local encode={}
+ setmetatableindex(encode,function(t,i)
+ for i=-2048,-1130 do
+ t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+ end
+ for i=-1131,-108 do
+ local v=0xFB00-i-108
+ t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF))
+ end
+ for i=-107,107 do
+ t[i]=chars[i+139]
+ end
+ for i=108,1131 do
+ local v=0xF700+i-108
+ t[i]=char(extract(v,8,8),extract(v,0,8))
+ end
+ for i=1132,2048 do
+ t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+ end
+ setmetatableindex(encode,function(t,k)
+ local r=round(k)
+ local v=rawget(t,r)
+ if v then
+ return v
+ end
+ local v1=floor(k)
+ local v2=floor((k-v1)*0x10000)
+ return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8))
+ end)
+ return t[i]
+ end)
+ readers.cffencoder=encode
+ local function p_setvsindex()
+ local vsindex=stack[top]
+ updateregions(vsindex)
+ top=top-1
+ end
+ local function p_blend()
+ local n=stack[top]
+ top=top-1
+ if not axis then
+ elseif n==1 then
+ top=top-nofregions
+ local v=stack[top]
+ for r=1,nofregions do
+ v=v+stack[top+r]*factors[r]
+ end
+ stack[top]=round(v)
+ else
+ top=top-nofregions*n
+ local d=top
+ local k=top-n
+ for i=1,n do
+ k=k+1
+ local v=stack[k]
+ for r=1,nofregions do
+ v=v+stack[d+r]*factors[r]
+ end
+ stack[k]=round(v)
+ d=d+nofregions
+ end
+ end
+ end
+ local function p_getstem()
+ local n=0
+ if top%2~=0 then
+ n=1
+ end
+ if top>n then
+ stems=stems+idiv(top-n,2)
+ end
+ end
+ local function p_getmask()
+ local n=0
+ if top%2~=0 then
+ n=1
+ end
+ if top>n then
+ stems=stems+idiv(top-n,2)
+ end
+ if stems==0 then
+ return 0
+ elseif stems<=8 then
+ return 1
+ else
+ return idiv(stems+7,8)
+ end
+ end
+ local process
+ local function call(scope,list,bias)
+ depth=depth+1
+ if top==0 then
+ showstate(formatters["unknown %s call %s"](scope,"?"))
+ top=0
+ else
+ local index=stack[top]+bias
+ top=top-1
+ if trace_charstrings then
+ showvalue(scope,index,true)
+ end
+ local tab=list[index]
+ if tab then
+ process(tab)
+ else
+ showstate(formatters["unknown %s call %s"](scope,index))
+ top=0
+ end
+ end
+ depth=depth-1
+ end
+ local justpass=false
+ process=function(tab)
+ local i=1
+ local n=#tab
+ while i<=n do
+ local t=tab[i]
+ if t>=32 then
+ top=top+1
+ if t<=246 then
+ stack[top]=t-139
+ i=i+1
+ elseif t<=250 then
+ stack[top]=t*256-63124+tab[i+1]
+ i=i+2
+ elseif t<=254 then
+ stack[top]=-t*256+64148-tab[i+1]
+ i=i+2
+ else
+ local n=0x100*tab[i+1]+tab[i+2]
+ if n>=0x8000 then
+ stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF
+ else
+ stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF
+ end
+ i=i+5
+ end
+ elseif t==28 then
+ top=top+1
+ local n=0x100*tab[i+1]+tab[i+2]
+ if n>=0x8000 then
+ stack[top]=n-0x10000
+ else
+ stack[top]=n
+ end
+ i=i+3
+ elseif t==11 then
+ if trace_charstrings then
+ showstate("return")
+ end
+ return
+ elseif t==10 then
+ call("local",locals,localbias)
+ i=i+1
+ elseif t==14 then
+ if width then
+ elseif top>0 then
+ width=stack[1]
+ if trace_charstrings then
+ showvalue("width",width)
+ end
+ else
+ width=true
+ end
+ if trace_charstrings then
+ showstate("endchar")
+ end
+ return
+ elseif t==29 then
+ call("global",globals,globalbias)
+ i=i+1
+ elseif t==12 then
+ i=i+1
+ local t=tab[i]
+ if justpass then
+ if t>=34 and t<=37 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ r=r+1;result[r]=chars[12]
+ r=r+1;result[r]=chars[t]
+ top=0
+ else
+ local a=subactions[t]
+ if a then
+ a(t)
+ else
+ top=0
+ end
+ end
+ else
+ local a=subactions[t]
+ if a then
+ a(t)
+ else
+ if trace_charstrings then
+ showvalue("<subaction>",t)
+ end
+ top=0
+ end
+ end
+ i=i+1
+ elseif justpass then
+ if t==15 then
+ p_setvsindex()
+ i=i+1
+ elseif t==16 then
+ local s=p_blend() or 0
+ i=i+s+1
+ elseif t==1 or t==3 or t==18 or operation==23 then
+ p_getstem()
+if true then
+ if top>0 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ top=0
+ end
+ r=r+1;result[r]=chars[t]
+else
+ top=0
+end
+ i=i+1
+ elseif t==19 or t==20 then
+ local s=p_getmask() or 0
+if true then
+ if top>0 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ top=0
+ end
+ r=r+1;result[r]=chars[t]
+ for j=1,s do
+ i=i+1
+ r=r+1;result[r]=chars[tab[i]]
+ end
+else
+ i=i+s
+ top=0
+end
+ i=i+1
+ elseif t==9 then
+ top=0
+ i=i+1
+ elseif t==13 then
+ local s=hsbw() or 0
+ i=i+s+1
+ else
+ if top>0 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ top=0
+ end
+ r=r+1;result[r]=chars[t]
+ i=i+1
+ end
+ else
+ local a=actions[t]
+ if a then
+ local s=a(t)
+ if s then
+ i=i+s+1
+ else
+ i=i+1
+ end
+ else
+ if trace_charstrings then
+ showvalue("<action>",t)
+ end
+ top=0
+ i=i+1
+ end
+ end
+ end
+ end
+ local function setbias(globals,locals,nobias)
+ if nobias then
+ return 0,0
+ else
+ local g=#globals
+ local l=#locals
+ return
+ ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1,
+ ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1
+ end
+ end
+ local function processshape(tab,index)
+ if not tab then
+ glyphs[index]={
+ boundingbox={ 0,0,0,0 },
+ width=0,
+ name=charset and charset[index] or nil,
+ }
+ return
+ end
+ tab=bytetable(tab)
+ x=0
+ y=0
+ width=false
+ r=0
+ top=0
+ stems=0
+ result={}
+ xmin=0
+ xmax=0
+ ymin=0
+ ymax=0
+ checked=false
+ if trace_charstrings then
+ report("glyph: %i",index)
+ report("data : % t",tab)
+ end
+ if regions then
+ updateregions(vsindex)
+ end
+ process(tab)
+ local boundingbox={
+ round(xmin),
+ round(ymin),
+ round(xmax),
+ round(ymax),
+ }
+ if width==true or width==false then
+ width=defaultwidth
+ else
+ width=nominalwidth+width
+ end
+ local glyph=glyphs[index]
+ if justpass then
+ r=r+1
+ result[r]=c_endchar
+ local stream=concat(result)
+ if glyph then
+ glyph.stream=stream
+ else
+ glyphs[index]={ stream=stream }
+ end
+ elseif glyph then
+ glyph.segments=keepcurve~=false and result or nil
+ glyph.boundingbox=boundingbox
+ if not glyph.width then
+ glyph.width=width
+ end
+ if charset and not glyph.name then
+ glyph.name=charset[index]
+ end
+ elseif keepcurve then
+ glyphs[index]={
+ segments=result,
+ boundingbox=boundingbox,
+ width=width,
+ name=charset and charset[index] or nil,
+ }
+ else
+ glyphs[index]={
+ boundingbox=boundingbox,
+ width=width,
+ name=charset and charset[index] or nil,
+ }
+ end
+ if trace_charstrings then
+ report("width : %s",tostring(width))
+ report("boundingbox: % t",boundingbox)
+ end
+ end
+ startparsing=function(fontdata,data,streams)
+ reginit=false
+ axis=false
+ regions=data.regions
+ justpass=streams==true
+ if regions then
+ regions={ regions }
+ axis=data.factors or false
+ end
+ end
+ stopparsing=function(fontdata,data)
+ stack={}
+ glyphs=false
+ result={}
+ top=0
+ locals=false
+ globals=false
+ strings=false
+ end
+ local function setwidths(private)
+ if not private then
+ return 0,0
+ end
+ local privatedata=private.data
+ if not privatedata then
+ return 0,0
+ end
+ return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0
+ end
+ parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams,nobias)
+ local dictionary=data.dictionaries[1]
+ local charstrings=dictionary.charstrings
+ keepcurve=doshapes
+ version=tversion
+ strings=data.strings
+ globals=data.routines or {}
+ locals=dictionary.subroutines or {}
+ charset=dictionary.charset
+ vsindex=dictionary.vsindex or 0
+ glyphs=glphs or {}
+ globalbias,localbias=setbias(globals,locals,nobias)
+ nominalwidth,defaultwidth=setwidths(dictionary.private)
+ if charstrings then
+ startparsing(fontdata,data,streams)
+ for index=1,#charstrings do
+ processshape(charstrings[index],index-1)
+ end
+ stopparsing(fontdata,data)
+ else
+ report("no charstrings")
+ end
+ return glyphs
+ end
+ parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams)
+ keepcurve=doshapes
+ version=tversion
+ strings=data.strings
+ globals=data.routines or {}
+ locals=dictionary.subroutines or {}
+ charset=false
+ vsindex=dictionary.vsindex or 0
+ glyphs=glphs or {}
+ justpass=streams==true
+ globalbias,localbias=setbias(globals,locals,nobias)
+ nominalwidth,defaultwidth=setwidths(dictionary.private)
+ processshape(tab,index-1)
+ end
+end
+local function readglobals(f,data)
+ local routines=readlengths(f)
+ for i=1,#routines do
+ routines[i]=readbytetable(f,routines[i])
+ end
+ data.routines=routines
+end
+local function readencodings(f,data)
+ data.encodings={}
+end
+local function readcharsets(f,data,dictionary)
+ local header=data.header
+ local strings=data.strings
+ local nofglyphs=data.nofglyphs
+ local charsetoffset=dictionary.charset
+ if charsetoffset and charsetoffset~=0 then
+ setposition(f,header.offset+charsetoffset)
+ local format=readbyte(f)
+ local charset={ [0]=".notdef" }
+ dictionary.charset=charset
+ if format==0 then
+ for i=1,nofglyphs do
+ charset[i]=strings[readushort(f)]
+ end
+ elseif format==1 or format==2 then
+ local readcount=format==1 and readbyte or readushort
+ local i=1
+ while i<=nofglyphs do
+ local sid=readushort(f)
+ local n=readcount(f)
+ for s=sid,sid+n do
+ charset[i]=strings[s]
+ i=i+1
+ if i>nofglyphs then
+ break
+ end
+ end
+ end
+ else
+ report("cff parser: unsupported charset format %a",format)
+ end
+ else
+ dictionary.nocharset=true
+ dictionary.charset=nil
+ end
+end
+local function readprivates(f,data)
+ local header=data.header
+ local dictionaries=data.dictionaries
+ local private=dictionaries[1].private
+ if private then
+ setposition(f,header.offset+private.offset)
+ private.data=readstring(f,private.size)
+ end
+end
+local function readlocals(f,data,dictionary)
+ local header=data.header
+ local private=dictionary.private
+ if private then
+ local subroutineoffset=private.data.subroutines
+ if subroutineoffset~=0 then
+ setposition(f,header.offset+private.offset+subroutineoffset)
+ local subroutines=readlengths(f)
+ for i=1,#subroutines do
+ subroutines[i]=readbytetable(f,subroutines[i])
+ end
+ dictionary.subroutines=subroutines
+ private.data.subroutines=nil
+ else
+ dictionary.subroutines={}
+ end
+ else
+ dictionary.subroutines={}
+ end
+end
+local function readcharstrings(f,data,what)
+ local header=data.header
+ local dictionaries=data.dictionaries
+ local dictionary=dictionaries[1]
+ local stringtype=dictionary.charstringtype
+ local offset=dictionary.charstrings
+ if type(offset)~="number" then
+ elseif stringtype==2 then
+ setposition(f,header.offset+offset)
+ local charstrings=readlengths(f,what=="cff2")
+ local nofglyphs=#charstrings
+ for i=1,nofglyphs do
+ charstrings[i]=readstring(f,charstrings[i])
+ end
+ data.nofglyphs=nofglyphs
+ dictionary.charstrings=charstrings
+ else
+ report("unsupported charstr type %i",stringtype)
+ data.nofglyphs=0
+ dictionary.charstrings={}
+ end
+end
+local function readcidprivates(f,data)
+ local header=data.header
+ local dictionaries=data.dictionaries[1].cid.dictionaries
+ for i=1,#dictionaries do
+ local dictionary=dictionaries[i]
+ local private=dictionary.private
+ if private then
+ setposition(f,header.offset+private.offset)
+ private.data=readstring(f,private.size)
+ end
+ end
+ parseprivates(data,dictionaries)
+end
+readers.parsecharstrings=parsecharstrings
+local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
+ local dictionaries=data.dictionaries
+ local dictionary=dictionaries[1]
+ readglobals(f,data)
+ readcharstrings(f,data,version)
+ if version=="cff2" then
+ dictionary.charset=nil
+ else
+ readencodings(f,data)
+ readcharsets(f,data,dictionary)
+ end
+ readprivates(f,data)
+ parseprivates(data,data.dictionaries)
+ readlocals(f,data,dictionary)
+ startparsing(fontdata,data,streams)
+ parsecharstrings(fontdata,data,glyphs,doshapes,version,streams)
+ stopparsing(fontdata,data)
+end
+local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
+ local header=data.header
+ local dictionaries=data.dictionaries
+ local dictionary=dictionaries[1]
+ local cid=dictionary.cid
+ local cidselect=cid and cid.fdselect
+ readglobals(f,data)
+ readcharstrings(f,data,version)
+ if version~="cff2" then
+ readencodings(f,data)
+ end
+ local charstrings=dictionary.charstrings
+ local fdindex={}
+ local nofglyphs=data.nofglyphs
+ local maxindex=-1
+ setposition(f,header.offset+cidselect)
+ local format=readbyte(f)
+ if format==1 then
+ for i=0,nofglyphs do
+ local index=readbyte(f)
+ fdindex[i]=index
+ if index>maxindex then
+ maxindex=index
+ end
+ end
+ elseif format==3 then
+ local nofranges=readushort(f)
+ local first=readushort(f)
+ local index=readbyte(f)
+ while true do
+ local last=readushort(f)
+ if index>maxindex then
+ maxindex=index
+ end
+ for i=first,last do
+ fdindex[i]=index
+ end
+ if last>=nofglyphs then
+ break
+ else
+ first=last+1
+ index=readbyte(f)
+ end
+ end
+ else
+ end
+ if maxindex>=0 then
+ local cidarray=cid.fdarray
+ if cidarray then
+ setposition(f,header.offset+cidarray)
+ local dictionaries=readlengths(f)
+ for i=1,#dictionaries do
+ dictionaries[i]=readstring(f,dictionaries[i])
+ end
+ parsedictionaries(data,dictionaries)
+ cid.dictionaries=dictionaries
+ readcidprivates(f,data)
+ for i=1,#dictionaries do
+ readlocals(f,data,dictionaries[i])
+ end
+ startparsing(fontdata,data,streams)
+ for i=1,#charstrings do
+ parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version,streams)
+ end
+ stopparsing(fontdata,data)
+ else
+ report("no cid array")
+ end
+ end
+end
+local gotodatatable=readers.helpers.gotodatatable
+local function cleanup(data,dictionaries)
+end
+function readers.cff(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs)
+ if tableoffset then
+ local header=readheader(f)
+ if header.major~=1 then
+ report("only version %s is supported for table %a",1,"cff")
+ return
+ end
+ local glyphs=fontdata.glyphs
+ local names=readfontnames(f)
+ local dictionaries=readtopdictionaries(f)
+ local strings=readstrings(f)
+ local data={
+ header=header,
+ names=names,
+ dictionaries=dictionaries,
+ strings=strings,
+ nofglyphs=fontdata.nofglyphs,
+ }
+ parsedictionaries(data,dictionaries,"cff")
+ local dic=dictionaries[1]
+ local cid=dic.cid
+ local cffinfo={
+ familyname=dic.familyname,
+ fullname=dic.fullname,
+ boundingbox=dic.boundingbox,
+ weight=dic.weight,
+ italicangle=dic.italicangle,
+ underlineposition=dic.underlineposition,
+ underlinethickness=dic.underlinethickness,
+ defaultwidth=dic.defaultwidthx,
+ nominalwidth=dic.nominalwidthx,
+ monospaced=dic.monospaced,
+ }
+ fontdata.cidinfo=cid and {
+ registry=cid.registry,
+ ordering=cid.ordering,
+ supplement=cid.supplement,
+ }
+ fontdata.cffinfo=cffinfo
+ local all=specification.shapes or specification.streams or false
+ if specification.glyphs or all then
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
+ else
+ readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
+ end
+ end
+ local private=dic.private
+ if private then
+ local data=private.data
+ if type(data)=="table" then
+ cffinfo.defaultwidth=data.defaultwidthx or cffinfo.defaultwidth
+ cffinfo.nominalwidth=data.nominalwidthx or cffinfo.nominalwidth
+ cffinfo.bluevalues=data.bluevalues
+ cffinfo.otherblues=data.otherblues
+ cffinfo.familyblues=data.familyblues
+ cffinfo.familyotherblues=data.familyotherblues
+ cffinfo.bluescale=data.bluescale
+ cffinfo.blueshift=data.blueshift
+ cffinfo.bluefuzz=data.bluefuzz
+ cffinfo.stdhw=data.stdhw
+ cffinfo.stdvw=data.stdvw
+ end
+ end
+ cleanup(data,dictionaries)
+ end
+end
+function readers.cff2(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"cff2",specification.glyphs)
+ if tableoffset then
+ local header=readheader(f)
+ if header.major~=2 then
+ report("only version %s is supported for table %a",2,"cff2")
+ return
+ end
+ local glyphs=fontdata.glyphs
+ local dictionaries={ readstring(f,header.dsize) }
+ local data={
+ header=header,
+ dictionaries=dictionaries,
+ nofglyphs=fontdata.nofglyphs,
+ }
+ parsedictionaries(data,dictionaries,"cff2")
+ 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 specification.streams or false
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
+ else
+ readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
+ end
+ cleanup(data,dictionaries)
+ end
+end
+function readers.cffcheck(filename)
+ local f=io.open(filename,"rb")
+ if f then
+ local fontdata={
+ glyphs={},
+ }
+ local header=readheader(f)
+ if header.major~=1 then
+ report("only version %s is supported for table %a",1,"cff")
+ return
+ end
+ local names=readfontnames(f)
+ local dictionaries=readtopdictionaries(f)
+ local strings=readstrings(f)
+ local glyphs={}
+ local data={
+ header=header,
+ names=names,
+ dictionaries=dictionaries,
+ strings=strings,
+ glyphs=glyphs,
+ nofglyphs=0,
+ }
+ parsedictionaries(data,dictionaries,"cff")
+ local cid=data.dictionaries[1].cid
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,false)
+ else
+ readnoselect(f,fontdata,data,glyphs,false)
+ end
+ return data
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-ttf']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type,unpack=next,type,unpack
+local band,rshift=bit32.band,bit32.rshift
+local sqrt,round=math.sqrt,math.round
+local char,rep=string.char,string.rep
+local concat=table.concat
+local idiv=number.idiv
+local setmetatableindex=table.setmetatableindex
+local report=logs.reporter("otf reader","ttf")
+local trace_deltas=false
+local readers=fonts.handlers.otf.readers
+local streamreader=readers.streamreader
+local setposition=streamreader.setposition
+local getposition=streamreader.getposition
+local skipbytes=streamreader.skip
+local readbyte=streamreader.readcardinal1
+local readushort=streamreader.readcardinal2
+local readulong=streamreader.readcardinal4
+local readchar=streamreader.readinteger1
+local readshort=streamreader.readinteger2
+local read2dot14=streamreader.read2dot14
+local readinteger=streamreader.readinteger1
+local readcardinaltable=streamreader.readcardinaltable
+local readintegertable=streamreader.readintegertable
+directives.register("fonts.streamreader",function()
+ streamreader=utilities.streams
+ setposition=streamreader.setposition
+ getposition=streamreader.getposition
+ skipbytes=streamreader.skip
+ readbyte=streamreader.readcardinal1
+ readushort=streamreader.readcardinal2
+ readulong=streamreader.readcardinal4
+ readchar=streamreader.readinteger1
+ readshort=streamreader.readinteger2
+ read2dot14=streamreader.read2dot14
+ readinteger=streamreader.readinteger1
+ readcardinaltable=streamreader.readcardinaltable
+ readintegertable=streamreader.readintegertable
+end)
+local short=2
+local ushort=2
+local ulong=4
+local helpers=readers.helpers
+local gotodatatable=helpers.gotodatatable
+local function mergecomposites(glyphs,shapes)
+ local function merge(index,shape,components)
+ local contours={}
+ local points={}
+ local nofcontours=0
+ local nofpoints=0
+ local offset=0
+ local deltas=shape.deltas
+ for i=1,#components do
+ local component=components[i]
+ local subindex=component.index
+ local subshape=shapes[subindex]
+ local subcontours=subshape.contours
+ local subpoints=subshape.points
+ if not subcontours then
+ local subcomponents=subshape.components
+ if subcomponents then
+ subcontours,subpoints=merge(subindex,subshape,subcomponents)
+ end
+ end
+ if subpoints then
+ local matrix=component.matrix
+ local xscale=matrix[1]
+ local xrotate=matrix[2]
+ local yrotate=matrix[3]
+ local yscale=matrix[4]
+ local xoffset=matrix[5]
+ local yoffset=matrix[6]
+ local count=#subpoints
+ if xscale==1 and yscale==1 and xrotate==0 and yrotate==0 then
+ for i=1,count do
+ local p=subpoints[i]
+ nofpoints=nofpoints+1
+ points[nofpoints]={
+ p[1]+xoffset,
+ p[2]+yoffset,
+ p[3]
+ }
+ end
+ else
+ for i=1,count do
+ local p=subpoints[i]
+ local x=p[1]
+ local y=p[2]
+ nofpoints=nofpoints+1
+ points[nofpoints]={
+ xscale*x+xrotate*y+xoffset,
+ yscale*y+yrotate*x+yoffset,
+ p[3]
+ }
+ end
+ end
+ local subcount=#subcontours
+ if subcount==1 then
+ nofcontours=nofcontours+1
+ contours[nofcontours]=offset+subcontours[1]
+ else
+ for i=1,#subcontours do
+ nofcontours=nofcontours+1
+ contours[nofcontours]=offset+subcontours[i]
+ end
+ end
+ offset=offset+count
+ else
+ report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex)
+ end
+ end
+ shape.points=points
+ shape.contours=contours
+ shape.components=nil
+ return contours,points
+ end
+ for index=0,#glyphs-1 do
+ local shape=shapes[index]
+ if shape then
+ local components=shape.components
+ if components then
+ merge(index,shape,components)
+ end
+ end
+ end
+end
+local function readnothing(f)
+ return {
+ type="nothing",
+ }
+end
+local function curveto(m_x,m_y,l_x,l_y,r_x,r_y)
+ return
+ l_x+2/3*(m_x-l_x),l_y+2/3*(m_y-l_y),
+ r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y),
+ r_x,r_y,"c"
+end
+local function applyaxis(glyph,shape,deltas,dowidth)
+ local points=shape.points
+ if points then
+ local nofpoints=#points
+ local h=nofpoints+2
+ local l=nofpoints+1
+ local dw=0
+ local dl=0
+ for i=1,#deltas do
+ local deltaset=deltas[i]
+ local xvalues=deltaset.xvalues
+ local yvalues=deltaset.yvalues
+ local dpoints=deltaset.points
+ local factor=deltaset.factor
+ if dpoints then
+ local nofdpoints=#dpoints
+ for i=1,nofdpoints do
+ local d=dpoints[i]
+ local p=points[d]
+ if p then
+ if xvalues then
+ local x=xvalues[i]
+ if x and x~=0 then
+ p[1]=p[1]+factor*x
+ end
+ end
+ if yvalues then
+ local y=yvalues[i]
+ if y and y~=0 then
+ p[2]=p[2]+factor*y
+ end
+ end
+ elseif dowidth then
+ if d==h then
+ local x=xvalues[i]
+ if x then
+ dw=dw+factor*x
+ end
+ elseif d==l then
+ local x=xvalues[i]
+ if x then
+ dl=dl+factor*x
+ end
+ end
+ end
+ end
+ else
+ for i=1,nofpoints do
+ local p=points[i]
+ if xvalues then
+ local x=xvalues[i]
+ if x and x~=0 then
+ p[1]=p[1]+factor*x
+ end
+ end
+ if yvalues then
+ local y=yvalues[i]
+ if y and y~=0 then
+ p[2]=p[2]+factor*y
+ end
+ end
+ end
+ if dowidth then
+ local x=xvalues[h]
+ if x then
+ dw=dw+factor*x
+ end
+ local x=xvalues[l]
+ if x then
+ dl=dl+factor*x
+ end
+ end
+ end
+ end
+ if dowidth then
+ local width=glyph.width or 0
+ glyph.width=width+dw-dl
+ end
+ else
+ report("no points for glyph %a",glyph.name)
+ end
+end
+local quadratic=false
+local function contours2outlines_normal(glyphs,shapes)
+ for index=0,#glyphs-1 do
+ local shape=shapes[index]
+ if shape then
+ local glyph=glyphs[index]
+ local contours=shape.contours
+ local points=shape.points
+ if contours then
+ local nofcontours=#contours
+ local segments={}
+ local nofsegments=0
+ glyph.segments=segments
+ if nofcontours>0 then
+ local px=0
+ local py=0
+ local first=1
+ for i=1,nofcontours do
+ local last=contours[i]
+ if last>=first then
+ local first_pt=points[first]
+ local first_on=first_pt[3]
+ if first==last then
+ first_pt[3]="m"
+ nofsegments=nofsegments+1
+ segments[nofsegments]=first_pt
+ else
+ local first_on=first_pt[3]
+ local last_pt=points[last]
+ local last_on=last_pt[3]
+ local start=1
+ local control_pt=false
+ if first_on then
+ start=2
+ else
+ if last_on then
+ first_pt=last_pt
+ else
+ first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false }
+ end
+ control_pt=first_pt
+ end
+ local x=first_pt[1]
+ local y=first_pt[2]
+ if not done then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ done=true
+ end
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x,y,"m" }
+ if not quadratic then
+ px=x
+ py=y
+ end
+ local previous_pt=first_pt
+ for i=first,last do
+ local current_pt=points[i]
+ local current_on=current_pt[3]
+ local previous_on=previous_pt[3]
+ if previous_on then
+ if current_on then
+ local x,y=current_pt[1],current_pt[2]
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x,y,"l" }
+ if not quadratic then
+ px,py=x,y
+ end
+ else
+ control_pt=current_pt
+ end
+ elseif current_on then
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ local x2=current_pt[1]
+ local y2=current_pt[2]
+ nofsegments=nofsegments+1
+ if quadratic then
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ control_pt=false
+ else
+ local x2=(previous_pt[1]+current_pt[1])/2
+ local y2=(previous_pt[2]+current_pt[2])/2
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ nofsegments=nofsegments+1
+ if quadratic then
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ control_pt=current_pt
+ end
+ previous_pt=current_pt
+ end
+ if first_pt==last_pt then
+ else
+ nofsegments=nofsegments+1
+ local x2=first_pt[1]
+ local y2=first_pt[2]
+ if not control_pt then
+ segments[nofsegments]={ x2,y2,"l" }
+ elseif quadratic then
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ else
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ end
+ end
+ end
+ first=last+1
+ end
+ end
+ end
+ end
+ end
+end
+local function contours2outlines_shaped(glyphs,shapes,keepcurve)
+ for index=0,#glyphs-1 do
+ local shape=shapes[index]
+ if shape then
+ local glyph=glyphs[index]
+ local contours=shape.contours
+ local points=shape.points
+ if contours then
+ local nofcontours=#contours
+ local segments=keepcurve and {} or nil
+ local nofsegments=0
+ if keepcurve then
+ glyph.segments=segments
+ end
+ if nofcontours>0 then
+ local xmin,ymin,xmax,ymax,done=0,0,0,0,false
+ local px,py=0,0
+ local first=1
+ for i=1,nofcontours do
+ local last=contours[i]
+ if last>=first then
+ local first_pt=points[first]
+ local first_on=first_pt[3]
+ if first==last then
+ if keepcurve then
+ first_pt[3]="m"
+ nofsegments=nofsegments+1
+ segments[nofsegments]=first_pt
+ end
+ else
+ local first_on=first_pt[3]
+ local last_pt=points[last]
+ local last_on=last_pt[3]
+ local start=1
+ local control_pt=false
+ if first_on then
+ start=2
+ else
+ if last_on then
+ first_pt=last_pt
+ else
+ first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false }
+ end
+ control_pt=first_pt
+ end
+ local x=first_pt[1]
+ local y=first_pt[2]
+ if not done then
+ xmin,ymin,xmax,ymax=x,y,x,y
+ done=true
+ else
+ if x<xmin then xmin=x elseif x>xmax then xmax=x end
+ if y<ymin then ymin=y elseif y>ymax then ymax=y end
+ end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x,y,"m" }
+ end
+ if not quadratic then
+ px=x
+ py=y
+ end
+ local previous_pt=first_pt
+ for i=first,last do
+ local current_pt=points[i]
+ local current_on=current_pt[3]
+ local previous_on=previous_pt[3]
+ if previous_on then
+ if current_on then
+ local x=current_pt[1]
+ local y=current_pt[2]
+ if x<xmin then xmin=x elseif x>xmax then xmax=x end
+ if y<ymin then ymin=y elseif y>ymax then ymax=y end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x,y,"l" }
+ end
+ if not quadratic then
+ px=x
+ py=y
+ end
+ else
+ control_pt=current_pt
+ end
+ elseif current_on then
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ local x2=current_pt[1]
+ local y2=current_pt[2]
+ if quadratic then
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ end
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
+ if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
+ if px<xmin then xmin=px elseif px>xmax then xmax=px end
+ if py<ymin then ymin=py elseif py>ymax then ymax=py end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ end
+ control_pt=false
+ else
+ local x2=(previous_pt[1]+current_pt[1])/2
+ local y2=(previous_pt[2]+current_pt[2])/2
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ if quadratic then
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ end
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
+ if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
+ if px<xmin then xmin=px elseif px>xmax then xmax=px end
+ if py<ymin then ymin=py elseif py>ymax then ymax=py end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ end
+ control_pt=current_pt
+ end
+ previous_pt=current_pt
+ end
+ if first_pt==last_pt then
+ elseif not control_pt then
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ first_pt[1],first_pt[2],"l" }
+ end
+ else
+ local x1=control_pt[1]
+ local y1=control_pt[2]
+ local x2=first_pt[1]
+ local y2=first_pt[2]
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if quadratic then
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ end
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
+ if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
+ if px<xmin then xmin=px elseif px>xmax then xmax=px end
+ if py<ymin then ymin=py elseif py>ymax then ymax=py end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ end
+ end
+ end
+ end
+ first=last+1
+ end
+ glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) }
+ end
+ end
+ end
+ end
+end
+local c_zero=char(0)
+local s_zero=char(0,0)
+local function toushort(n)
+ return char(band(rshift(n,8),0xFF),band(n,0xFF))
+end
+local function toshort(n)
+ if n<0 then
+ n=n+0x10000
+ end
+ return char(band(rshift(n,8),0xFF),band(n,0xFF))
+end
+local chars=setmetatableindex(function(t,k)
+ for i=0,255 do local v=char(i) t[i]=v end return t[k]
+end)
+local function repackpoints(glyphs,shapes)
+ local noboundingbox={ 0,0,0,0 }
+ local result={}
+ local xpoints={}
+ local ypoints={}
+ for index=0,#glyphs-1 do
+ local shape=shapes[index]
+ if shape then
+ local r=0
+ local glyph=glyphs[index]
+ local contours=shape.contours
+ local nofcontours=contours and #contours or 0
+ local boundingbox=glyph.boundingbox or noboundingbox
+ r=r+1 result[r]=toshort(nofcontours)
+ r=r+1 result[r]=toshort(boundingbox[1])
+ r=r+1 result[r]=toshort(boundingbox[2])
+ r=r+1 result[r]=toshort(boundingbox[3])
+ r=r+1 result[r]=toshort(boundingbox[4])
+ if nofcontours>0 then
+ for i=1,nofcontours do
+ r=r+1 result[r]=toshort(contours[i]-1)
+ end
+ r=r+1 result[r]=s_zero
+ local points=shape.points
+ local currentx=0
+ local currenty=0
+ local x=0
+ local y=0
+ local lastflag=nil
+ local nofflags=0
+ for i=1,#points do
+ local pt=points[i]
+ local px=pt[1]
+ local py=pt[2]
+ local fl=pt[3] and 0x01 or 0x00
+ if px==currentx then
+ fl=fl+0x10
+ else
+ local dx=round(px-currentx)
+ x=x+1
+ if dx<-255 or dx>255 then
+ xpoints[x]=toshort(dx)
+ elseif dx<0 then
+ fl=fl+0x02
+ xpoints[x]=chars[-dx]
+ elseif dx>0 then
+ fl=fl+0x12
+ xpoints[x]=chars[dx]
+ else
+ fl=fl+0x02
+ xpoints[x]=c_zero
+ end
+ end
+ if py==currenty then
+ fl=fl+0x20
+ else
+ local dy=round(py-currenty)
+ y=y+1
+ if dy<-255 or dy>255 then
+ ypoints[y]=toshort(dy)
+ elseif dy<0 then
+ fl=fl+0x04
+ ypoints[y]=chars[-dy]
+ elseif dy>0 then
+ fl=fl+0x24
+ ypoints[y]=chars[dy]
+ else
+ fl=fl+0x04
+ ypoints[y]=c_zero
+ end
+ end
+ currentx=px
+ currenty=py
+ if lastflag==fl then
+ if nofflags==255 then
+ lastflag=lastflag+0x08
+ r=r+1 result[r]=char(lastflag,nofflags-1)
+ nofflags=1
+ lastflag=fl
+ else
+ nofflags=nofflags+1
+ end
+ else
+ if nofflags==1 then
+ r=r+1 result[r]=chars[lastflag]
+ elseif nofflags==2 then
+ r=r+1 result[r]=char(lastflag,lastflag)
+ elseif nofflags>2 then
+ lastflag=lastflag+0x08
+ r=r+1 result[r]=char(lastflag,nofflags-1)
+ end
+ nofflags=1
+ lastflag=fl
+ end
+ end
+ if nofflags==1 then
+ r=r+1 result[r]=chars[lastflag]
+ elseif nofflags==2 then
+ r=r+1 result[r]=char(lastflag,lastflag)
+ elseif nofflags>2 then
+ lastflag=lastflag+0x08
+ r=r+1 result[r]=char(lastflag,nofflags-1)
+ end
+ r=r+1 result[r]=concat(xpoints,"",1,x)
+ r=r+1 result[r]=concat(ypoints,"",1,y)
+ end
+ local stream=concat(result,"",1,r)
+ local length=#stream
+ local padding=idiv(length+3,4)*4-length
+ if padding>0 then
+ if padding==1 then
+ padding="\0"
+ elseif padding==2 then
+ padding="\0\0"
+ else
+ padding="\0\0\0"
+ end
+ padding=stream..padding
+ end
+ glyph.stream=stream
+ end
+ end
+end
+local flags={}
+local function readglyph(f,nofcontours)
+ local points={}
+ local contours={}
+ for i=1,nofcontours do
+ contours[i]=readshort(f)+1
+ end
+ local nofpoints=contours[nofcontours]
+ local nofinstructions=readushort(f)
+ skipbytes(f,nofinstructions)
+ local i=1
+ while i<=nofpoints do
+ local flag=readbyte(f)
+ flags[i]=flag
+ if band(flag,0x08)~=0 then
+ local n=readbyte(f)
+ if n==1 then
+ i=i+1
+ flags[i]=flag
+ else
+ for j=1,n do
+ i=i+1
+ flags[i]=flag
+ end
+ end
+ end
+ i=i+1
+ end
+ local x=0
+ for i=1,nofpoints do
+ local flag=flags[i]
+ if band(flag,0x02)~=0 then
+ if band(flag,0x10)~=0 then
+ x=x+readbyte(f)
+ else
+ x=x-readbyte(f)
+ end
+ elseif band(flag,0x10)~=0 then
+ else
+ x=x+readshort(f)
+ end
+ points[i]={ x,0,band(flag,0x01)~=0 }
+ end
+ local y=0
+ for i=1,nofpoints do
+ local flag=flags[i]
+ if band(flag,0x04)~=0 then
+ if band(flag,0x20)~=0 then
+ y=y+readbyte(f)
+ else
+ y=y-readbyte(f)
+ end
+ elseif band(flag,0x20)~=0 then
+ else
+ y=y+readshort(f)
+ end
+ points[i][2]=y
+ end
+ return {
+ type="glyph",
+ points=points,
+ contours=contours,
+ nofpoints=nofpoints,
+ }
+end
+local function readcomposite(f)
+ local components={}
+ local nofcomponents=0
+ local instructions=false
+ while true do
+ local flags=readushort(f)
+ local index=readushort(f)
+ local f_xyarg=band(flags,0x0002)~=0
+ local f_offset=band(flags,0x0800)~=0
+ local xscale=1
+ local xrotate=0
+ local yrotate=0
+ local yscale=1
+ local xoffset=0
+ local yoffset=0
+ local base=false
+ local reference=false
+ if f_xyarg then
+ if band(flags,0x0001)~=0 then
+ xoffset=readshort(f)
+ yoffset=readshort(f)
+ else
+ xoffset=readchar(f)
+ yoffset=readchar(f)
+ end
+ else
+ if band(flags,0x0001)~=0 then
+ base=readshort(f)
+ reference=readshort(f)
+ else
+ base=readchar(f)
+ reference=readchar(f)
+ end
+ end
+ if band(flags,0x0008)~=0 then
+ xscale=read2dot14(f)
+ yscale=xscale
+ if f_xyarg and f_offset then
+ xoffset=xoffset*xscale
+ yoffset=yoffset*yscale
+ end
+ elseif band(flags,0x0040)~=0 then
+ xscale=read2dot14(f)
+ yscale=read2dot14(f)
+ if f_xyarg and f_offset then
+ xoffset=xoffset*xscale
+ yoffset=yoffset*yscale
+ end
+ elseif band(flags,0x0080)~=0 then
+ xscale=read2dot14(f)
+ xrotate=read2dot14(f)
+ yrotate=read2dot14(f)
+ yscale=read2dot14(f)
+ if f_xyarg and f_offset then
+ xoffset=xoffset*sqrt(xscale^2+xrotate^2)
+ yoffset=yoffset*sqrt(yrotate^2+yscale^2)
+ end
+ end
+ nofcomponents=nofcomponents+1
+ components[nofcomponents]={
+ index=index,
+ usemine=band(flags,0x0200)~=0,
+ round=band(flags,0x0006)~=0,
+ base=base,
+ reference=reference,
+ matrix={ xscale,xrotate,yrotate,yscale,xoffset,yoffset },
+ }
+ if band(flags,0x0100)~=0 then
+ instructions=true
+ end
+ if band(flags,0x0020)==0 then
+ break
+ end
+ end
+ return {
+ type="composite",
+ components=components,
+ }
+end
+function readers.loca(f,fontdata,specification)
+ if specification.glyphs then
+ local datatable=fontdata.tables.loca
+ if datatable then
+ local offset=fontdata.tables.glyf.offset
+ local format=fontdata.fontheader.indextolocformat
+ local profile=fontdata.maximumprofile
+ local nofglyphs=profile and profile.nofglyphs
+ local locations={}
+ setposition(f,datatable.offset)
+ if format==1 then
+ if not nofglyphs then
+ nofglyphs=idiv(datatable.length,4)-1
+ end
+ for i=0,nofglyphs do
+ locations[i]=offset+readulong(f)
+ end
+ fontdata.nofglyphs=nofglyphs
+ else
+ if not nofglyphs then
+ nofglyphs=idiv(datatable.length,2)-1
+ end
+ for i=0,nofglyphs do
+ locations[i]=offset+readushort(f)*2
+ end
+ end
+ fontdata.nofglyphs=nofglyphs
+ fontdata.locations=locations
+ end
+ end
+end
+function readers.glyf(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"glyf",specification.glyphs)
+ if tableoffset then
+ local locations=fontdata.locations
+ if locations then
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs
+ local filesize=fontdata.filesize
+ local nothing={ 0,0,0,0 }
+ local shapes={}
+ local loadshapes=specification.shapes or specification.instance or specification.streams
+ for index=0,nofglyphs-1 do
+ local location=locations[index]
+ local length=locations[index+1]-location
+ if location>=filesize then
+ report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1)
+ fontdata.nofglyphs=index-1
+ fontdata.badfont=true
+ break
+ elseif length>0 then
+ setposition(f,location)
+ local nofcontours=readshort(f)
+ glyphs[index].boundingbox={
+ readshort(f),
+ readshort(f),
+ readshort(f),
+ readshort(f),
+ }
+ if not loadshapes then
+ elseif nofcontours==0 then
+ shapes[index]=readnothing(f)
+ elseif nofcontours>0 then
+ shapes[index]=readglyph(f,nofcontours)
+ else
+ shapes[index]=readcomposite(f,nofcontours)
+ end
+ else
+ if loadshapes then
+ shapes[index]=readnothing(f)
+ end
+ glyphs[index].boundingbox=nothing
+ end
+ end
+ if loadshapes then
+ if readers.gvar then
+ readers.gvar(f,fontdata,specification,glyphs,shapes)
+ end
+ mergecomposites(glyphs,shapes)
+ if specification.instance then
+ if specification.streams then
+ repackpoints(glyphs,shapes)
+ else
+ contours2outlines_shaped(glyphs,shapes,specification.shapes)
+ end
+ elseif specification.shapes then
+ if specification.streams then
+ repackpoints(glyphs,shapes)
+ else
+ contours2outlines_normal(glyphs,shapes)
+ end
+ elseif specification.streams then
+ repackpoints(glyphs,shapes)
+ end
+ end
+ end
+ end
+end
+local function readtuplerecord(f,nofaxis)
+ local record={}
+ for i=1,nofaxis do
+ record[i]=read2dot14(f)
+ end
+ return record
+end
+local function readpoints(f)
+ local count=readbyte(f)
+ if count==0 then
+ return nil,0
+ else
+ if count<128 then
+ elseif band(count,0x80)~=0 then
+ count=band(count,0x7F)*256+readbyte(f)
+ else
+ end
+ local points={}
+ local p=0
+ local n=1
+ while p<count do
+ local control=readbyte(f)
+ local runreader=band(control,0x80)~=0 and readushort or readbyte
+ local runlength=band(control,0x7F)
+ for i=1,runlength+1 do
+ n=n+runreader(f)
+ p=p+1
+ points[p]=n
+ end
+ end
+ return points,p
+ end
+end
+local function readdeltas(f,nofpoints)
+ local deltas={}
+ local p=0
+ local z=0
+ while nofpoints>0 do
+ local control=readbyte(f)
+if not control then
+ break
+end
+ local allzero=band(control,0x80)~=0
+ local runlength=band(control,0x3F)+1
+ if allzero then
+ z=z+runlength
+ else
+ local runreader=band(control,0x40)~=0 and readshort or readinteger
+ if z>0 then
+ for i=1,z do
+ p=p+1
+ deltas[p]=0
+ end
+ z=0
+ end
+ for i=1,runlength do
+ p=p+1
+ deltas[p]=runreader(f)
+ end
+ end
+ nofpoints=nofpoints-runlength
+ end
+ if p>0 then
+ return deltas
+ else
+ end
+end
+local function readdeltas(f,nofpoints)
+ local deltas={}
+ local p=0
+ while nofpoints>0 do
+ local control=readbyte(f)
+ if control then
+ local allzero=band(control,0x80)~=0
+ local runlength=band(control,0x3F)+1
+ if allzero then
+ for i=1,runlength do
+ p=p+1
+ deltas[p]=0
+ end
+ else
+ local runreader=band(control,0x40)~=0 and readshort or readinteger
+ for i=1,runlength do
+ p=p+1
+ deltas[p]=runreader(f)
+ end
+ end
+ nofpoints=nofpoints-runlength
+ else
+ break
+ end
+ end
+ if p>0 then
+ return deltas
+ else
+ end
+end
+function readers.gvar(f,fontdata,specification,glyphdata,shapedata)
+ local instance=specification.instance
+ if not instance then
+ return
+ end
+ local factors=specification.factors
+ if not factors then
+ return
+ end
+ local tableoffset=gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes)
+ if tableoffset then
+ local version=readulong(f)
+ local nofaxis=readushort(f)
+ local noftuples=readushort(f)
+ local tupleoffset=tableoffset+readulong(f)
+ local nofglyphs=readushort(f)
+ local flags=readushort(f)
+ local dataoffset=tableoffset+readulong(f)
+ local data={}
+ local tuples={}
+ local glyphdata=fontdata.glyphs
+ local dowidth=not fontdata.variabledata.hvarwidths
+ if band(flags,0x0001)~=0 then
+ for i=1,nofglyphs+1 do
+ data[i]=dataoffset+readulong(f)
+ end
+ else
+ for i=1,nofglyphs+1 do
+ data[i]=dataoffset+2*readushort(f)
+ end
+ end
+ if noftuples>0 then
+ setposition(f,tupleoffset)
+ for i=1,noftuples do
+ tuples[i]=readtuplerecord(f,nofaxis)
+ end
+ end
+ local nextoffset=false
+ local startoffset=data[1]
+ for i=1,nofglyphs do
+ nextoffset=data[i+1]
+ local glyph=glyphdata[i-1]
+ local name=trace_deltas and glyph.name
+ if startoffset==nextoffset then
+ if name then
+ report("no deltas for glyph %a",name)
+ end
+ else
+ local shape=shapedata[i-1]
+ if not shape then
+ if name then
+ report("no shape for glyph %a",name)
+ end
+ else
+ lastoffset=startoffset
+ setposition(f,startoffset)
+ local flags=readushort(f)
+ local count=band(flags,0x0FFF)
+ local offset=startoffset+readushort(f)
+ local deltas={}
+ local allpoints=(shape.nofpoints or 0)
+ local shared=false
+ local nofshared=0
+ if band(flags,0x8000)~=0 then
+ local current=getposition(f)
+ setposition(f,offset)
+ shared,nofshared=readpoints(f)
+ offset=getposition(f)
+ setposition(f,current)
+ end
+ for j=1,count do
+ local size=readushort(f)
+ local flags=readushort(f)
+ local index=band(flags,0x0FFF)
+ local haspeak=band(flags,0x8000)~=0
+ local intermediate=band(flags,0x4000)~=0
+ local private=band(flags,0x2000)~=0
+ local peak=nil
+ local start=nil
+ local stop=nil
+ local xvalues=nil
+ local yvalues=nil
+ local points=shared
+ local nofpoints=nofshared
+ if haspeak then
+ peak=readtuplerecord(f,nofaxis)
+ else
+ if index+1>#tuples then
+ report("error, bad tuple index",index)
+ end
+ peak=tuples[index+1]
+ end
+ if intermediate then
+ start=readtuplerecord(f,nofaxis)
+ stop=readtuplerecord(f,nofaxis)
+ end
+ if size>0 then
+ local current=getposition(f)
+ setposition(f,offset)
+ if private then
+ points,nofpoints=readpoints(f)
+ end
+ if nofpoints==0 then
+ nofpoints=allpoints+4
+ end
+ if nofpoints>0 then
+ xvalues=readdeltas(f,nofpoints)
+ yvalues=readdeltas(f,nofpoints)
+ end
+ offset=offset+size
+ setposition(f,current)
+ end
+ if not xvalues and not yvalues then
+ points=nil
+ end
+ local s=1
+ for i=1,nofaxis do
+ local f=factors[i]
+ local peak=peak and peak [i] or 0
+ local start=start and start[i] or (peak<0 and peak or 0)
+ local stop=stop and stop [i] or (peak>0 and peak or 0)
+ if start>peak or peak>stop then
+ elseif start<0 and stop>0 and peak~=0 then
+ elseif peak==0 then
+ elseif f<start or f>stop then
+ s=0
+ break
+ elseif f<peak then
+ s=s*(f-start)/(peak-start)
+ elseif f>peak then
+ s=s*(stop-f)/(stop-peak)
+ else
+ end
+ end
+ if s==0 then
+ if name then
+ report("no deltas applied for glyph %a",name)
+ end
+ else
+ deltas[#deltas+1]={
+ factor=s,
+ points=points,
+ xvalues=xvalues,
+ yvalues=yvalues,
+ }
+ end
+ end
+ if shape.type=="glyph" then
+ applyaxis(glyph,shape,deltas,dowidth)
+ else
+ shape.deltas=deltas
+ end
+ end
+ end
+ startoffset=nextoffset
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-dsp']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type,tonumber=next,type,tonumber
+local band=bit32.band
+local extract=bit32.extract
+local bor=bit32.bor
+local lshift=bit32.lshift
+local rshift=bit32.rshift
+local gsub=string.gsub
+local lower=string.lower
+local sub=string.sub
+local strip=string.strip
+local tohash=table.tohash
+local concat=table.concat
+local copy=table.copy
+local reversed=table.reversed
+local sort=table.sort
+local insert=table.insert
+local round=math.round
+local settings_to_hash=utilities.parsers.settings_to_hash_colon_too
+local setmetatableindex=table.setmetatableindex
+local formatters=string.formatters
+local sortedkeys=table.sortedkeys
+local sortedhash=table.sortedhash
+local sequenced=table.sequenced
+local report=logs.reporter("otf reader")
+local readers=fonts.handlers.otf.readers
+local streamreader=readers.streamreader
+local setposition=streamreader.setposition
+local getposition=streamreader.getposition
+local readuinteger=streamreader.readcardinal1
+local readushort=streamreader.readcardinal2
+local readulong=streamreader.readcardinal4
+local readinteger=streamreader.readinteger1
+local readshort=streamreader.readinteger2
+local readstring=streamreader.readstring
+local readtag=streamreader.readtag
+local readbytes=streamreader.readbytes
+local readfixed=streamreader.readfixed4
+local read2dot14=streamreader.read2dot14
+local skipshort=streamreader.skipshort
+local skipbytes=streamreader.skip
+local readbytetable=streamreader.readbytetable
+local readbyte=streamreader.readbyte
+local readcardinaltable=streamreader.readcardinaltable
+local readintegertable=streamreader.readintegertable
+local readfword=readshort
+local short=2
+local ushort=2
+local ulong=4
+directives.register("fonts.streamreader",function()
+ streamreader=utilities.streams
+ setposition=streamreader.setposition
+ getposition=streamreader.getposition
+ readuinteger=streamreader.readcardinal1
+ readushort=streamreader.readcardinal2
+ readulong=streamreader.readcardinal4
+ readinteger=streamreader.readinteger1
+ readshort=streamreader.readinteger2
+ readstring=streamreader.readstring
+ readtag=streamreader.readtag
+ readbytes=streamreader.readbytes
+ readfixed=streamreader.readfixed4
+ read2dot14=streamreader.read2dot14
+ skipshort=streamreader.skipshort
+ skipbytes=streamreader.skip
+ readbytetable=streamreader.readbytetable
+ readbyte=streamreader.readbyte
+ readcardinaltable=streamreader.readcardinaltable
+ readintegertable=streamreader.readintegertable
+ readfword=readshort
+end)
+local gsubhandlers={}
+local gposhandlers={}
+readers.gsubhandlers=gsubhandlers
+readers.gposhandlers=gposhandlers
+local helpers=readers.helpers
+local gotodatatable=helpers.gotodatatable
+local setvariabledata=helpers.setvariabledata
+local lookupidoffset=-1
+local classes={
+ "base",
+ "ligature",
+ "mark",
+ "component",
+}
+local gsubtypes={
+ "single",
+ "multiple",
+ "alternate",
+ "ligature",
+ "context",
+ "chainedcontext",
+ "extension",
+ "reversechainedcontextsingle",
+}
+local gpostypes={
+ "single",
+ "pair",
+ "cursive",
+ "marktobase",
+ "marktoligature",
+ "marktomark",
+ "context",
+ "chainedcontext",
+ "extension",
+}
+local chaindirections={
+ context=0,
+ chainedcontext=1,
+ reversechainedcontextsingle=-1,
+}
+local function setmetrics(data,where,tag,d)
+ local w=data[where]
+ if w then
+ local v=w[tag]
+ if v then
+ w[tag]=v+d
+ end
+ end
+end
+local variabletags={
+ hasc=function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end,
+ hdsc=function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end,
+ hlgp=function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end,
+ hcla=function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end,
+ hcld=function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end,
+ vasc=function(data,d) setmetrics(data,"vhea not done","ascent",d) end,
+ vdsc=function(data,d) setmetrics(data,"vhea not done","descent",d) end,
+ vlgp=function(data,d) setmetrics(data,"vhea not done","linegap",d) end,
+ xhgt=function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end,
+ cpht=function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end,
+ sbxs=function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end,
+ sbys=function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end,
+ sbxo=function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end,
+ sbyo=function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end,
+ spxs=function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end,
+ spys=function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end,
+ spxo=function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end,
+ spyo=function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end,
+ strs=function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end,
+ stro=function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end,
+ unds=function(data,d) setmetrics(data,"postscript","underlineposition",d) end,
+ undo=function(data,d) setmetrics(data,"postscript","underlinethickness",d) end,
+}
+local read_cardinal={
+ streamreader.readcardinal1,
+ streamreader.readcardinal2,
+ streamreader.readcardinal3,
+ streamreader.readcardinal4,
+}
+local read_integer={
+ streamreader.readinteger1,
+ streamreader.readinteger2,
+ streamreader.readinteger3,
+ streamreader.readinteger4,
+}
+local lookupnames={
+ gsub={
+ single="gsub_single",
+ multiple="gsub_multiple",
+ alternate="gsub_alternate",
+ ligature="gsub_ligature",
+ context="gsub_context",
+ chainedcontext="gsub_contextchain",
+ reversechainedcontextsingle="gsub_reversecontextchain",
+ },
+ gpos={
+ single="gpos_single",
+ pair="gpos_pair",
+ cursive="gpos_cursive",
+ marktobase="gpos_mark2base",
+ marktoligature="gpos_mark2ligature",
+ marktomark="gpos_mark2mark",
+ context="gpos_context",
+ chainedcontext="gpos_contextchain",
+ }
+}
+local lookupflags=setmetatableindex(function(t,k)
+ local v={
+ band(k,0x0008)~=0 and true or false,
+ band(k,0x0004)~=0 and true or false,
+ band(k,0x0002)~=0 and true or false,
+ band(k,0x0001)~=0 and true or false,
+ }
+ t[k]=v
+ return v
+end)
+local function axistofactors(str)
+ local t=settings_to_hash(str)
+ for k,v in next,t do
+ t[k]=tonumber(v) or v
+ end
+ return t
+end
+local hash=table.setmetatableindex(function(t,k)
+ local v=sequenced(axistofactors(k),",")
+ t[k]=v
+ return v
+end)
+helpers.normalizedaxishash=hash
+local cleanname=fonts.names and fonts.names.cleanname or function(name)
+ return name and (gsub(lower(name),"[^%a%d]","")) or nil
+end
+helpers.cleanname=cleanname
+function helpers.normalizedaxis(str)
+ return hash[str] or str
+end
+local function getaxisscale(segments,minimum,default,maximum,user)
+ if not minimum or not default or not maximum then
+ return false
+ end
+ if user<minimum then
+ user=minimum
+ elseif user>maximum then
+ user=maximum
+ end
+ if user<default then
+ default=- (default-user)/(default-minimum)
+ elseif user>default then
+ default=(user-default)/(maximum-default)
+ else
+ default=0
+ end
+ if not segments then
+ return default
+ end
+ local e
+ for i=1,#segments do
+ local s=segments[i]
+ if type(s)~="number" then
+ report("using default axis scale")
+ return default
+ elseif s[1]>=default then
+ if s[2]==default then
+ return default
+ else
+ e=i
+ break
+ end
+ end
+ end
+ if e then
+ local b=segments[e-1]
+ local e=segments[e]
+ return b[2]+(e[2]-b[2])*(default-b[1])/(e[1]-b[1])
+ else
+ return false
+ end
+end
+local function getfactors(data,instancespec)
+ if instancespec==true then
+ elseif type(instancespec)~="string" or instancespec=="" then
+ return
+ end
+ local variabledata=data.variabledata
+ if not variabledata then
+ return
+ end
+ local instances=variabledata.instances
+ local axis=variabledata.axis
+ local segments=variabledata.segments
+ if instances and axis then
+ local values
+ if instancespec==true then
+ values={}
+ for i=1,#axis do
+ values[i]={
+ value=axis[i].default,
+ }
+ end
+ else
+ for i=1,#instances do
+ local instance=instances[i]
+ if cleanname(instance.subfamily)==instancespec then
+ values=instance.values
+ break
+ end
+ end
+ end
+ if values then
+ local factors={}
+ for i=1,#axis do
+ local a=axis[i]
+ factors[i]=getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value)
+ end
+ return factors
+ end
+ local values=axistofactors(hash[instancespec] or instancespec)
+ if values then
+ local factors={}
+ for i=1,#axis do
+ local a=axis[i]
+ local d=a.default
+ factors[i]=getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d)
+ end
+ return factors
+ end
+ end
+end
+local function getscales(regions,factors)
+ local scales={}
+ for i=1,#regions do
+ local region=regions[i]
+ local s=1
+ for j=1,#region do
+ local axis=region[j]
+ local f=factors[j]
+ local start=axis.start
+ local peak=axis.peak
+ local stop=axis.stop
+ if start>peak or peak>stop then
+ elseif start<0 and stop>0 and peak~=0 then
+ elseif peak==0 then
+ elseif f<start or f>stop then
+ s=0
+ break
+ elseif f<peak then
+ s=s*(f-start)/(peak-start)
+ elseif f>peak then
+ s=s*(stop-f)/(stop-peak)
+ else
+ end
+ end
+ scales[i]=s
+ end
+ return scales
+end
+helpers.getaxisscale=getaxisscale
+helpers.getfactors=getfactors
+helpers.getscales=getscales
+helpers.axistofactors=axistofactors
+local function readvariationdata(f,storeoffset,factors)
+ local position=getposition(f)
+ setposition(f,storeoffset)
+ local format=readushort(f)
+ local regionoffset=storeoffset+readulong(f)
+ local nofdeltadata=readushort(f)
+ local deltadata=readcardinaltable(f,nofdeltadata,ulong)
+ setposition(f,regionoffset)
+ local nofaxis=readushort(f)
+ local nofregions=readushort(f)
+ local regions={}
+ for i=1,nofregions do
+ local t={}
+ for i=1,nofaxis do
+ t[i]={
+ start=read2dot14(f),
+ peak=read2dot14(f),
+ stop=read2dot14(f),
+ }
+ end
+ regions[i]=t
+ end
+ if factors then
+ for i=1,nofdeltadata do
+ setposition(f,storeoffset+deltadata[i])
+ local nofdeltasets=readushort(f)
+ local nofshorts=readushort(f)
+ local nofregions=readushort(f)
+ local usedregions={}
+ local deltas={}
+ for i=1,nofregions do
+ usedregions[i]=regions[readushort(f)+1]
+ end
+ for i=1,nofdeltasets do
+ local t=readintegertable(f,nofshorts,short)
+ for i=nofshorts+1,nofregions do
+ t[i]=readinteger(f)
+ end
+ deltas[i]=t
+ end
+ deltadata[i]={
+ regions=usedregions,
+ deltas=deltas,
+ scales=factors and getscales(usedregions,factors) or nil,
+ }
+ end
+ end
+ setposition(f,position)
+ return regions,deltadata
+end
+helpers.readvariationdata=readvariationdata
+local function readcoverage(f,offset,simple)
+ setposition(f,offset)
+ local coverageformat=readushort(f)
+ if coverageformat==1 then
+ local nofcoverage=readushort(f)
+ if simple then
+ if nofcoverage==1 then
+ return { readushort(f) }
+ elseif nofcoverage==2 then
+ return { readushort(f),readushort(f) }
+ else
+ return readcardinaltable(f,nofcoverage,ushort)
+ end
+ elseif nofcoverage==1 then
+ return { [readushort(f)]=0 }
+ elseif nofcoverage==2 then
+ return { [readushort(f)]=0,[readushort(f)]=1 }
+ else
+ local coverage={}
+ for i=0,nofcoverage-1 do
+ coverage[readushort(f)]=i
+ end
+ return coverage
+ end
+ elseif coverageformat==2 then
+ local nofranges=readushort(f)
+ local coverage={}
+ local n=simple and 1 or 0
+ for i=1,nofranges do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local coverindex=readushort(f)
+ if simple then
+ for i=firstindex,lastindex do
+ coverage[n]=i
+ n=n+1
+ end
+ else
+ for i=firstindex,lastindex do
+ coverage[i]=n
+ n=n+1
+ end
+ end
+ end
+ return coverage
+ else
+ report("unknown coverage format %a ",coverageformat)
+ return {}
+ end
+end
+local function readclassdef(f,offset,preset)
+ setposition(f,offset)
+ local classdefformat=readushort(f)
+ local classdef={}
+ if type(preset)=="number" then
+ for k=0,preset-1 do
+ classdef[k]=1
+ end
+ end
+ if classdefformat==1 then
+ local index=readushort(f)
+ local nofclassdef=readushort(f)
+ for i=1,nofclassdef do
+ classdef[index]=readushort(f)+1
+ index=index+1
+ end
+ elseif classdefformat==2 then
+ local nofranges=readushort(f)
+ local n=0
+ for i=1,nofranges do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local class=readushort(f)+1
+ for i=firstindex,lastindex do
+ classdef[i]=class
+ end
+ end
+ else
+ report("unknown classdef format %a ",classdefformat)
+ end
+ if type(preset)=="table" then
+ for k in next,preset do
+ if not classdef[k] then
+ classdef[k]=1
+ end
+ end
+ end
+ return classdef
+end
+local function classtocoverage(defs)
+ if defs then
+ local list={}
+ for index,class in next,defs do
+ local c=list[class]
+ if c then
+ c[#c+1]=index
+ else
+ list[class]={ index }
+ end
+ end
+ return list
+ end
+end
+local skips={ [0]=0,
+ 1,
+ 1,
+ 2,
+ 1,
+ 2,
+ 2,
+ 3,
+ 2,
+ 2,
+ 3,
+ 2,
+ 3,
+ 3,
+ 4,
+}
+local function readvariation(f,offset)
+ local p=getposition(f)
+ setposition(f,offset)
+ local outer=readushort(f)
+ local inner=readushort(f)
+ local format=readushort(f)
+ setposition(f,p)
+ if format==0x8000 then
+ return outer,inner
+ end
+end
+local function readposition(f,format,mainoffset,getdelta)
+ if format==0 then
+ return false
+ end
+ if format==0x04 then
+ local h=readshort(f)
+ if h==0 then
+ return true
+ else
+ return { 0,0,h,0 }
+ end
+ end
+ if format==0x05 then
+ local x=readshort(f)
+ local h=readshort(f)
+ if x==0 and h==0 then
+ return true
+ else
+ return { x,0,h,0 }
+ end
+ end
+ if format==0x44 then
+ local h=readshort(f)
+ if getdelta then
+ local d=readshort(f)
+ if d>0 then
+ local outer,inner=readvariation(f,mainoffset+d)
+ if outer then
+ h=h+getdelta(outer,inner)
+ end
+ end
+ else
+ skipshort(f,1)
+ end
+ if h==0 then
+ return true
+ else
+ return { 0,0,h,0 }
+ end
+ end
+ local x=band(format,0x1)~=0 and readshort(f) or 0
+ local y=band(format,0x2)~=0 and readshort(f) or 0
+ local h=band(format,0x4)~=0 and readshort(f) or 0
+ local v=band(format,0x8)~=0 and readshort(f) or 0
+ if format>=0x10 then
+ local X=band(format,0x10)~=0 and skipshort(f) or 0
+ local Y=band(format,0x20)~=0 and skipshort(f) or 0
+ local H=band(format,0x40)~=0 and skipshort(f) or 0
+ local V=band(format,0x80)~=0 and skipshort(f) or 0
+ local s=skips[extract(format,4,4)]
+ if s>0 then
+ skipshort(f,s)
+ end
+ if getdelta then
+ if X>0 then
+ local outer,inner=readvariation(f,mainoffset+X)
+ if outer then
+ x=x+getdelta(outer,inner)
+ end
+ end
+ if Y>0 then
+ local outer,inner=readvariation(f,mainoffset+Y)
+ if outer then
+ y=y+getdelta(outer,inner)
+ end
+ end
+ if H>0 then
+ local outer,inner=readvariation(f,mainoffset+H)
+ if outer then
+ h=h+getdelta(outer,inner)
+ end
+ end
+ if V>0 then
+ local outer,inner=readvariation(f,mainoffset+V)
+ if outer then
+ v=v+getdelta(outer,inner)
+ end
+ end
+ end
+ return { x,y,h,v }
+ elseif x==0 and y==0 and h==0 and v==0 then
+ return true
+ else
+ return { x,y,h,v }
+ end
+end
+local function readanchor(f,offset,getdelta)
+ if not offset or offset==0 then
+ return nil
+ end
+ setposition(f,offset)
+ local format=readshort(f)
+ local x=readshort(f)
+ local y=readshort(f)
+ if format==3 then
+ if getdelta then
+ local X=readshort(f)
+ local Y=readshort(f)
+ if X>0 then
+ local outer,inner=readvariation(f,offset+X)
+ if outer then
+ x=x+getdelta(outer,inner)
+ end
+ end
+ if Y>0 then
+ local outer,inner=readvariation(f,offset+Y)
+ if outer then
+ y=y+getdelta(outer,inner)
+ end
+ end
+ else
+ skipshort(f,2)
+ end
+ return { x,y }
+ else
+ return { x,y }
+ end
+end
+local function readfirst(f,offset)
+ if offset then
+ setposition(f,offset)
+ end
+ return { readushort(f) }
+end
+function readarray(f,offset)
+ if offset then
+ setposition(f,offset)
+ end
+ local n=readushort(f)
+ if n==1 then
+ return { readushort(f) },1
+ elseif n>0 then
+ return readcardinaltable(f,n,ushort),n
+ end
+end
+local function readcoveragearray(f,offset,t,simple)
+ if not t then
+ return nil
+ end
+ local n=#t
+ if n==0 then
+ return nil
+ end
+ for i=1,n do
+ t[i]=readcoverage(f,offset+t[i],simple)
+ end
+ return t
+end
+local function covered(subset,all)
+ local used,u
+ for i=1,#subset do
+ local s=subset[i]
+ if all[s] then
+ if used then
+ u=u+1
+ used[u]=s
+ else
+ u=1
+ used={ s }
+ end
+ end
+ end
+ return used
+end
+local function readlookuparray(f,noflookups,nofcurrent)
+ local lookups={}
+ if noflookups>0 then
+ local length=0
+ for i=1,noflookups do
+ local index=readushort(f)+1
+ if index>length then
+ length=index
+ end
+ 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
+ lookups[index]=false
+ end
+ end
+ end
+ return lookups
+end
+local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local subclasssets=readarray(f)
+ local rules={}
+ if subclasssets then
+ coverage=readcoverage(f,tableoffset+coverage,true)
+ for i=1,#subclasssets do
+ local offset=subclasssets[i]
+ if offset>0 then
+ local firstcoverage=coverage[i]
+ local rulesoffset=tableoffset+offset
+ local subclassrules=readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset+subclassrules[rule])
+ local nofcurrent=readushort(f)
+ local noflookups=readushort(f)
+ local current={ { firstcoverage } }
+ for i=2,nofcurrent do
+ current[i]={ readushort(f) }
+ end
+ local lookups=readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1]={
+ current=current,
+ lookups=lookups
+ }
+ end
+ end
+ end
+ else
+ report("empty subclassset in %a subtype %i","unchainedcontext",subtype)
+ end
+ return {
+ format="glyphs",
+ rules=rules,
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local currentclassdef=readushort(f)
+ local subclasssets=readarray(f)
+ local rules={}
+ if subclasssets then
+ coverage=readcoverage(f,tableoffset+coverage)
+ currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage)
+ local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs)
+ for class=1,#subclasssets do
+ local offset=subclasssets[class]
+ if offset>0 then
+ local firstcoverage=currentclasses[class]
+ if firstcoverage then
+ firstcoverage=covered(firstcoverage,coverage)
+ if firstcoverage then
+ local rulesoffset=tableoffset+offset
+ local subclassrules=readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset+subclassrules[rule])
+ local nofcurrent=readushort(f)
+ local noflookups=readushort(f)
+ local current={ firstcoverage }
+ for i=2,nofcurrent do
+ current[i]=currentclasses[readushort(f)+1]
+ end
+ local lookups=readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1]={
+ current=current,
+ lookups=lookups
+ }
+ end
+ else
+ report("no coverage")
+ end
+ else
+ report("no coverage class")
+ end
+ end
+ end
+ else
+ report("empty subclassset in %a subtype %i","unchainedcontext",subtype)
+ end
+ return {
+ format="class",
+ rules=rules,
+ }
+ elseif subtype==3 then
+ local nofglyphs=readushort(f)
+ local noflookups=readushort(f)
+ local current=readcardinaltable(f,nofglyphs,ushort)
+ local lookups=readlookuparray(f,noflookups,#current)
+ current=readcoveragearray(f,tableoffset,current,true)
+ return {
+ format="coverage",
+ rules={
+ {
+ current=current,
+ lookups=lookups,
+ }
+ }
+ }
+ else
+ report("unsupported subtype %a in %a %s",subtype,"unchainedcontext",what)
+ end
+end
+local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local subclasssets=readarray(f)
+ local rules={}
+ if subclasssets then
+ coverage=readcoverage(f,tableoffset+coverage,true)
+ for i=1,#subclasssets do
+ local offset=subclasssets[i]
+ if offset>0 then
+ local firstcoverage=coverage[i]
+ local rulesoffset=tableoffset+offset
+ local subclassrules=readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset+subclassrules[rule])
+ local nofbefore=readushort(f)
+ local before
+ if nofbefore>0 then
+ before={}
+ for i=1,nofbefore do
+ before[i]={ readushort(f) }
+ end
+ end
+ local nofcurrent=readushort(f)
+ local current={ { firstcoverage } }
+ for i=2,nofcurrent do
+ current[i]={ readushort(f) }
+ end
+ local nofafter=readushort(f)
+ local after
+ if nofafter>0 then
+ after={}
+ for i=1,nofafter do
+ after[i]={ readushort(f) }
+ end
+ end
+ local noflookups=readushort(f)
+ local lookups=readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1]={
+ before=before,
+ current=current,
+ after=after,
+ lookups=lookups,
+ }
+ end
+ end
+ end
+ else
+ report("empty subclassset in %a subtype %i","chainedcontext",subtype)
+ end
+ return {
+ format="glyphs",
+ rules=rules,
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local beforeclassdef=readushort(f)
+ local currentclassdef=readushort(f)
+ local afterclassdef=readushort(f)
+ local subclasssets=readarray(f)
+ local rules={}
+ if subclasssets then
+ local coverage=readcoverage(f,tableoffset+coverage)
+ local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef,nofglyphs)
+ local currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage)
+ local afterclassdef=readclassdef(f,tableoffset+afterclassdef,nofglyphs)
+ local beforeclasses=classtocoverage(beforeclassdef,fontdata.glyphs)
+ local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs)
+ local afterclasses=classtocoverage(afterclassdef,fontdata.glyphs)
+ for class=1,#subclasssets do
+ local offset=subclasssets[class]
+ if offset>0 then
+ local firstcoverage=currentclasses[class]
+ if firstcoverage then
+ firstcoverage=covered(firstcoverage,coverage)
+ if firstcoverage then
+ local rulesoffset=tableoffset+offset
+ local subclassrules=readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset+subclassrules[rule])
+ local nofbefore=readushort(f)
+ local before
+ if nofbefore>0 then
+ before={}
+ for i=1,nofbefore do
+ before[i]=beforeclasses[readushort(f)+1]
+ end
+ end
+ local nofcurrent=readushort(f)
+ local current={ firstcoverage }
+ for i=2,nofcurrent do
+ current[i]=currentclasses[readushort(f)+1]
+ end
+ local nofafter=readushort(f)
+ local after
+ if nofafter>0 then
+ after={}
+ for i=1,nofafter do
+ after[i]=afterclasses[readushort(f)+1]
+ end
+ end
+ local noflookups=readushort(f)
+ local lookups=readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1]={
+ before=before,
+ current=current,
+ after=after,
+ lookups=lookups,
+ }
+ end
+ else
+ report("no coverage")
+ end
+ else
+ report("class is not covered")
+ end
+ end
+ end
+ else
+ report("empty subclassset in %a subtype %i","chainedcontext",subtype)
+ end
+ return {
+ format="class",
+ rules=rules,
+ }
+ elseif subtype==3 then
+ local before=readarray(f)
+ local current=readarray(f)
+ local after=readarray(f)
+ local noflookups=readushort(f)
+ local lookups=readlookuparray(f,noflookups,#current)
+ before=readcoveragearray(f,tableoffset,before,true)
+ current=readcoveragearray(f,tableoffset,current,true)
+ after=readcoveragearray(f,tableoffset,after,true)
+ return {
+ format="coverage",
+ rules={
+ {
+ before=before,
+ current=current,
+ after=after,
+ lookups=lookups,
+ }
+ }
+ }
+ else
+ report("unsupported subtype %a in %a %s",subtype,"chainedcontext",what)
+ end
+end
+local function extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,types,handlers,what)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local lookuptype=types[readushort(f)]
+ local faroffset=readulong(f)
+ local handler=handlers[lookuptype]
+ if handler then
+ return handler(f,fontdata,lookupid,tableoffset+faroffset,0,glyphs,nofglyphs),lookuptype
+ else
+ report("no handler for lookuptype %a subtype %a in %s %s",lookuptype,subtype,what,"extension")
+ end
+ else
+ report("unsupported subtype %a in %s %s",subtype,what,"extension")
+ end
+end
+function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local delta=readshort(f)
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index in next,coverage do
+ local newindex=(index+delta)%65536
+ if index>nofglyphs or newindex>nofglyphs then
+ report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs)
+ coverage[index]=nil
+ else
+ coverage[index]=newindex
+ end
+ end
+ return {
+ coverage=coverage
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local nofreplacements=readushort(f)
+ local replacements=readcardinaltable(f,nofreplacements,ushort)
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ newindex=newindex+1
+ if index>nofglyphs or newindex>nofglyphs then
+ report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs)
+ coverage[index]=nil
+ else
+ coverage[index]=replacements[newindex]
+ end
+ end
+ return {
+ coverage=coverage
+ }
+ else
+ report("unsupported subtype %a in %a substitution",subtype,"single")
+ end
+end
+local function sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local nofsequence=readushort(f)
+ local sequences=readcardinaltable(f,nofsequence,ushort)
+ for i=1,nofsequence do
+ setposition(f,tableoffset+sequences[i])
+ sequences[i]=readcardinaltable(f,readushort(f),ushort)
+ end
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ newindex=newindex+1
+ if index>nofglyphs or newindex>nofglyphs then
+ report("invalid index in %s format %i: %i -> %i (max %i)",what,subtype,index,newindex,nofglyphs)
+ coverage[index]=nil
+ else
+ coverage[index]=sequences[newindex]
+ end
+ end
+ return {
+ coverage=coverage
+ }
+ else
+ report("unsupported subtype %a in %a substitution",subtype,what)
+ end
+end
+function gsubhandlers.multiple(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"multiple")
+end
+function gsubhandlers.alternate(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"alternate")
+end
+function gsubhandlers.ligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local nofsets=readushort(f)
+ local ligatures=readcardinaltable(f,nofsets,ushort)
+ for i=1,nofsets do
+ local offset=lookupoffset+offset+ligatures[i]
+ setposition(f,offset)
+ local n=readushort(f)
+ if n==1 then
+ ligatures[i]={ offset+readushort(f) }
+ else
+ local l={}
+ for i=1,n do
+ l[i]=offset+readushort(f)
+ end
+ ligatures[i]=l
+ end
+ end
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ local hash={}
+ local ligatures=ligatures[newindex+1]
+ for i=1,#ligatures do
+ local offset=ligatures[i]
+ setposition(f,offset)
+ local lig=readushort(f)
+ local cnt=readushort(f)
+ local hsh=hash
+ for i=2,cnt do
+ local c=readushort(f)
+ local h=hsh[c]
+ if not h then
+ h={}
+ hsh[c]=h
+ end
+ hsh=h
+ end
+ hsh.ligature=lig
+ end
+ coverage[index]=hash
+ end
+ return {
+ coverage=coverage
+ }
+ else
+ report("unsupported subtype %a in %a substitution",subtype,"ligature")
+ end
+end
+function gsubhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"context"
+end
+function gsubhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"chainedcontext"
+end
+function gsubhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gsubtypes,gsubhandlers,"substitution")
+end
+function gsubhandlers.reversechainedcontextsingle(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local current=readfirst(f)
+ local before=readarray(f)
+ local after=readarray(f)
+ local replacements=readarray(f)
+ current=readcoveragearray(f,tableoffset,current,true)
+ before=readcoveragearray(f,tableoffset,before,true)
+ after=readcoveragearray(f,tableoffset,after,true)
+ return {
+ format="reversecoverage",
+ rules={
+ {
+ before=before,
+ current=current,
+ after=after,
+ replacements=replacements,
+ }
+ }
+ },"reversechainedcontextsingle"
+ else
+ report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle")
+ end
+end
+local function readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta)
+ local done={}
+ for i=1,#sets do
+ local offset=sets[i]
+ local reused=done[offset]
+ if not reused then
+ offset=tableoffset+offset
+ setposition(f,offset)
+ local n=readushort(f)
+ reused={}
+ for i=1,n do
+ reused[i]={
+ readushort(f),
+ readposition(f,format1,offset,getdelta),
+ readposition(f,format2,offset,getdelta),
+ }
+ end
+ done[offset]=reused
+ end
+ sets[i]=reused
+ end
+ return sets
+end
+local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,mainoffset,getdelta)
+ local classlist1={}
+ for i=1,nofclasses1 do
+ local classlist2={}
+ classlist1[i]=classlist2
+ for j=1,nofclasses2 do
+ local one=readposition(f,format1,mainoffset,getdelta)
+ local two=readposition(f,format2,mainoffset,getdelta)
+ if one or two then
+ classlist2[j]={ one,two }
+ else
+ classlist2[j]=false
+ end
+ end
+ end
+ return classlist1
+end
+function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ local getdelta=fontdata.temporary.getdelta
+ if subtype==1 then
+ local coverage=readushort(f)
+ local format=readushort(f)
+ local value=readposition(f,format,tableoffset,getdelta)
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ coverage[index]=value
+ end
+ return {
+ format="single",
+ coverage=coverage,
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local format=readushort(f)
+ local nofvalues=readushort(f)
+ local values={}
+ for i=1,nofvalues do
+ values[i]=readposition(f,format,tableoffset,getdelta)
+ end
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ coverage[index]=values[newindex+1]
+ end
+ return {
+ format="single",
+ coverage=coverage,
+ }
+ else
+ report("unsupported subtype %a in %a positioning",subtype,"single")
+ end
+end
+function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ local getdelta=fontdata.temporary.getdelta
+ if subtype==1 then
+ local coverage=readushort(f)
+ local format1=readushort(f)
+ local format2=readushort(f)
+ local sets=readarray(f)
+ sets=readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta)
+ coverage=readcoverage(f,tableoffset+coverage)
+ local shared={}
+ for index,newindex in next,coverage do
+ local set=sets[newindex+1]
+ local hash={}
+ for i=1,#set do
+ local value=set[i]
+ if value then
+ local other=value[1]
+ local share=shared[value]
+ if share==nil then
+ local first=value[2]
+ local second=value[3]
+ if first or second then
+ share={ first,second or nil }
+ else
+ share=false
+ end
+ shared[value]=share
+ end
+ hash[other]=share or nil
+ end
+ end
+ coverage[index]=hash
+ end
+ return {
+ shared=shared and true or nil,
+ format="pair",
+ coverage=coverage,
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local format1=readushort(f)
+ local format2=readushort(f)
+ local classdef1=readushort(f)
+ local classdef2=readushort(f)
+ local nofclasses1=readushort(f)
+ local nofclasses2=readushort(f)
+ local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta)
+ coverage=readcoverage(f,tableoffset+coverage)
+ classdef1=readclassdef(f,tableoffset+classdef1,coverage)
+ classdef2=readclassdef(f,tableoffset+classdef2,nofglyphs)
+ local usedcoverage={}
+ local shared={}
+ for g1,c1 in next,classdef1 do
+ if coverage[g1] then
+ local l1=classlist[c1]
+ if l1 then
+ local hash={}
+ for paired,class in next,classdef2 do
+ local offsets=l1[class]
+ if offsets then
+ local first=offsets[1]
+ local second=offsets[2]
+ if first or second then
+ local s1=shared[first]
+ if s1==nil then
+ s1={}
+ shared[first]=s1
+ end
+ local s2=s1[second]
+ if s2==nil then
+ s2={ first,second or nil }
+ s1[second]=s2
+ end
+ hash[paired]=s2
+ end
+ end
+ end
+ usedcoverage[g1]=hash
+ end
+ end
+ end
+ return {
+ shared=shared and true or nil,
+ format="pair",
+ coverage=usedcoverage,
+ }
+ elseif subtype==3 then
+ report("yet unsupported subtype %a in %a positioning",subtype,"pair")
+ else
+ report("unsupported subtype %a in %a positioning",subtype,"pair")
+ end
+end
+function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ local getdelta=fontdata.temporary.getdelta
+ if subtype==1 then
+ local coverage=tableoffset+readushort(f)
+ local nofrecords=readushort(f)
+ local records={}
+ for i=1,nofrecords do
+ local entry=readushort(f)
+ local exit=readushort(f)
+ records[i]={
+ entry~=0 and (tableoffset+entry) or false,
+ exit~=0 and (tableoffset+exit ) or nil,
+ }
+ end
+ local cc=(fontdata.temporary.cursivecount or 0)+1
+ fontdata.temporary.cursivecount=cc
+ cc="cc-"..cc
+ coverage=readcoverage(f,coverage)
+ for i=1,nofrecords do
+ local r=records[i]
+ records[i]={
+ cc,
+ readanchor(f,r[1],getdelta) or false,
+ readanchor(f,r[2],getdelta) or nil,
+ }
+ end
+ for index,newindex in next,coverage do
+ coverage[index]=records[newindex+1]
+ end
+ return {
+ coverage=coverage,
+ }
+ else
+ report("unsupported subtype %a in %a positioning",subtype,"cursive")
+ end
+end
+local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,ligature)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ local getdelta=fontdata.temporary.getdelta
+ if subtype==1 then
+ local markcoverage=tableoffset+readushort(f)
+ local basecoverage=tableoffset+readushort(f)
+ local nofclasses=readushort(f)
+ local markoffset=tableoffset+readushort(f)
+ local baseoffset=tableoffset+readushort(f)
+ local markcoverage=readcoverage(f,markcoverage)
+ local basecoverage=readcoverage(f,basecoverage,true)
+ setposition(f,markoffset)
+ local markclasses={}
+ local nofmarkclasses=readushort(f)
+ local lastanchor=fontdata.lastanchor or 0
+ local usedanchors={}
+ for i=1,nofmarkclasses do
+ local class=readushort(f)+1
+ local offset=readushort(f)
+ if offset==0 then
+ markclasses[i]=false
+ else
+ markclasses[i]={ class,markoffset+offset }
+ end
+ usedanchors[class]=true
+ end
+ for i=1,nofmarkclasses do
+ local mc=markclasses[i]
+ if mc then
+ mc[2]=readanchor(f,mc[2],getdelta)
+ end
+ end
+ setposition(f,baseoffset)
+ local nofbaserecords=readushort(f)
+ local baserecords={}
+ if ligature then
+ for i=1,nofbaserecords do
+ local offset=readushort(f)
+ if offset==0 then
+ baserecords[i]=false
+ else
+ baserecords[i]=baseoffset+offset
+ end
+ end
+ for i=1,nofbaserecords do
+ local recordoffset=baserecords[i]
+ if recordoffset then
+ setposition(f,recordoffset)
+ local nofcomponents=readushort(f)
+ local components={}
+ for i=1,nofcomponents do
+ local classes={}
+ for i=1,nofclasses do
+ local offset=readushort(f)
+ if offset~=0 then
+ classes[i]=recordoffset+offset
+ else
+ classes[i]=false
+ end
+ end
+ components[i]=classes
+ end
+ baserecords[i]=components
+ end
+ end
+ local baseclasses={}
+ for i=1,nofclasses do
+ baseclasses[i]={}
+ end
+ for i=1,nofbaserecords do
+ local components=baserecords[i]
+ if components then
+ local b=basecoverage[i]
+ for c=1,#components do
+ local classes=components[c]
+ if classes then
+ for i=1,nofclasses do
+ local anchor=readanchor(f,classes[i],getdelta)
+ local bclass=baseclasses[i]
+ local bentry=bclass[b]
+ if bentry then
+ bentry[c]=anchor
+ else
+ bclass[b]={ [c]=anchor }
+ end
+ end
+ end
+ end
+ end
+ end
+ for index,newindex in next,markcoverage do
+ markcoverage[index]=markclasses[newindex+1] or nil
+ end
+ return {
+ format="ligature",
+ baseclasses=baseclasses,
+ coverage=markcoverage,
+ }
+ else
+ for i=1,nofbaserecords do
+ local r={}
+ for j=1,nofclasses do
+ local offset=readushort(f)
+ if offset==0 then
+ r[j]=false
+ else
+ r[j]=baseoffset+offset
+ end
+ end
+ baserecords[i]=r
+ end
+ local baseclasses={}
+ for i=1,nofclasses do
+ baseclasses[i]={}
+ end
+ for i=1,nofbaserecords do
+ local r=baserecords[i]
+ local b=basecoverage[i]
+ for j=1,nofclasses do
+ baseclasses[j][b]=readanchor(f,r[j],getdelta)
+ end
+ end
+ for index,newindex in next,markcoverage do
+ markcoverage[index]=markclasses[newindex+1] or nil
+ end
+ return {
+ format="base",
+ baseclasses=baseclasses,
+ coverage=markcoverage,
+ }
+ end
+ else
+ report("unsupported subtype %a in",subtype)
+ end
+end
+function gposhandlers.marktobase(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+end
+function gposhandlers.marktoligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,true)
+end
+function gposhandlers.marktomark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+end
+function gposhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"context"
+end
+function gposhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"chainedcontext"
+end
+function gposhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gpostypes,gposhandlers,"positioning")
+end
+do
+ local plugins={}
+ function plugins.size(f,fontdata,tableoffset,feature)
+ if fontdata.designsize then
+ else
+ local function check(offset)
+ setposition(f,offset)
+ local designsize=readushort(f)
+ if designsize>0 then
+ local fontstyleid=readushort(f)
+ local guimenuid=readushort(f)
+ local minsize=readushort(f)
+ local maxsize=readushort(f)
+ if minsize==0 and maxsize==0 and fontstyleid==0 and guimenuid==0 then
+ minsize=designsize
+ maxsize=designsize
+ end
+ if designsize>=minsize and designsize<=maxsize then
+ return minsize,maxsize,designsize
+ end
+ end
+ end
+ local minsize,maxsize,designsize=check(tableoffset+feature.offset+feature.parameters)
+ if not designsize then
+ minsize,maxsize,designsize=check(tableoffset+feature.parameters)
+ if designsize then
+ report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?")
+ else
+ report("bad size feature in %a,",fontdata.filename or "?")
+ end
+ end
+ if designsize then
+ fontdata.minsize=minsize
+ fontdata.maxsize=maxsize
+ fontdata.designsize=designsize
+ end
+ end
+ end
+ local function reorderfeatures(fontdata,scripts,features)
+ local scriptlangs={}
+ local featurehash={}
+ local featureorder={}
+ for script,languages in next,scripts do
+ for language,record in next,languages do
+ local hash={}
+ local list=record.featureindices
+ for k=1,#list do
+ local index=list[k]
+ local feature=features[index]
+ local lookups=feature.lookups
+ local tag=feature.tag
+ if tag then
+ hash[tag]=true
+ end
+ if lookups then
+ for i=1,#lookups do
+ local lookup=lookups[i]
+ local o=featureorder[lookup]
+ if o then
+ local okay=true
+ for i=1,#o do
+ if o[i]==tag then
+ okay=false
+ break
+ end
+ end
+ if okay then
+ o[#o+1]=tag
+ end
+ else
+ featureorder[lookup]={ tag }
+ end
+ local f=featurehash[lookup]
+ if f then
+ local h=f[tag]
+ if h then
+ local s=h[script]
+ if s then
+ s[language]=true
+ else
+ h[script]={ [language]=true }
+ end
+ else
+ f[tag]={ [script]={ [language]=true } }
+ end
+ else
+ featurehash[lookup]={ [tag]={ [script]={ [language]=true } } }
+ end
+ local h=scriptlangs[tag]
+ if h then
+ local s=h[script]
+ if s then
+ s[language]=true
+ else
+ h[script]={ [language]=true }
+ end
+ else
+ scriptlangs[tag]={ [script]={ [language]=true } }
+ end
+ end
+ end
+ end
+ end
+ end
+ return scriptlangs,featurehash,featureorder
+ end
+ local function readscriplan(f,fontdata,scriptoffset)
+ setposition(f,scriptoffset)
+ local nofscripts=readushort(f)
+ local scripts={}
+ for i=1,nofscripts do
+ scripts[readtag(f)]=scriptoffset+readushort(f)
+ end
+ local languagesystems=setmetatableindex("table")
+ for script,offset in next,scripts do
+ setposition(f,offset)
+ local defaultoffset=readushort(f)
+ local noflanguages=readushort(f)
+ local languages={}
+ if defaultoffset>0 then
+ languages.dflt=languagesystems[offset+defaultoffset]
+ end
+ for i=1,noflanguages do
+ local language=readtag(f)
+ local offset=offset+readushort(f)
+ languages[language]=languagesystems[offset]
+ end
+ scripts[script]=languages
+ end
+ for offset,usedfeatures in next,languagesystems do
+ if offset>0 then
+ setposition(f,offset)
+ local featureindices={}
+ usedfeatures.featureindices=featureindices
+ usedfeatures.lookuporder=readushort(f)
+ usedfeatures.requiredindex=readushort(f)
+ local noffeatures=readushort(f)
+ for i=1,noffeatures do
+ featureindices[i]=readushort(f)+1
+ end
+ end
+ end
+ return scripts
+ end
+ local function readfeatures(f,fontdata,featureoffset)
+ setposition(f,featureoffset)
+ local features={}
+ local noffeatures=readushort(f)
+ for i=1,noffeatures do
+ features[i]={
+ tag=readtag(f),
+ offset=readushort(f)
+ }
+ end
+ for i=1,noffeatures do
+ local feature=features[i]
+ local offset=featureoffset+feature.offset
+ setposition(f,offset)
+ local parameters=readushort(f)
+ local noflookups=readushort(f)
+ if noflookups>0 then
+ local lookups=readcardinaltable(f,noflookups,ushort)
+ feature.lookups=lookups
+ for j=1,noflookups do
+ lookups[j]=lookups[j]+1
+ end
+ end
+ if parameters>0 then
+ feature.parameters=parameters
+ local plugin=plugins[feature.tag]
+ if plugin then
+ plugin(f,fontdata,featureoffset,feature)
+ end
+ end
+ end
+ return features
+ end
+ local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder)
+ setposition(f,lookupoffset)
+ local noflookups=readushort(f)
+ local lookups=readcardinaltable(f,noflookups,ushort)
+ for lookupid=1,noflookups do
+ local offset=lookups[lookupid]
+ setposition(f,lookupoffset+offset)
+ local subtables={}
+ local typebits=readushort(f)
+ local flagbits=readushort(f)
+ local lookuptype=lookuptypes[typebits]
+ local lookupflags=lookupflags[flagbits]
+ local nofsubtables=readushort(f)
+ for j=1,nofsubtables do
+ subtables[j]=offset+readushort(f)
+ end
+ local markclass=band(flagbits,0x0010)~=0
+ if markclass then
+ markclass=readushort(f)
+ end
+ local markset=rshift(flagbits,8)
+ if markset>0 then
+ markclass=markset
+ end
+ lookups[lookupid]={
+ type=lookuptype,
+ flags=lookupflags,
+ name=lookupid,
+ subtables=subtables,
+ markclass=markclass,
+ features=featurehash[lookupid],
+ order=featureorder[lookupid],
+ }
+ end
+ return lookups
+ end
+ local f_lookupname=formatters["%s_%s_%s"]
+ local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset)
+ local sequences=fontdata.sequences or {}
+ local sublookuplist=fontdata.sublookups or {}
+ fontdata.sequences=sequences
+ fontdata.sublookups=sublookuplist
+ local nofsublookups=#sublookuplist
+ local nofsequences=#sequences
+ local lastsublookup=nofsublookups
+ local lastsequence=nofsequences
+ local lookupnames=lookupnames[what]
+ local sublookuphash={}
+ local sublookupcheck={}
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs or #glyphs
+ local noflookups=#lookups
+ local lookupprefix=sub(what,2,2)
+ local usedlookups=false
+ for lookupid=1,noflookups do
+ local lookup=lookups[lookupid]
+ local lookuptype=lookup.type
+ local subtables=lookup.subtables
+ local features=lookup.features
+ local handler=lookuphandlers[lookuptype]
+ if handler then
+ local nofsubtables=#subtables
+ local order=lookup.order
+ local flags=lookup.flags
+ if flags[1] then flags[1]="mark" end
+ if flags[2] then flags[2]="ligature" end
+ if flags[3] then flags[3]="base" end
+ local markclass=lookup.markclass
+ if nofsubtables>0 then
+ local steps={}
+ local nofsteps=0
+ local oldtype=nil
+ for s=1,nofsubtables do
+ local step,lt=handler(f,fontdata,lookupid,lookupoffset,subtables[s],glyphs,nofglyphs)
+ if lt then
+ lookuptype=lt
+ if oldtype and lt~=oldtype then
+ report("messy %s lookup type %a and %a",what,lookuptype,oldtype)
+ end
+ oldtype=lookuptype
+ end
+ if not step then
+ report("unsupported %s lookup type %a",what,lookuptype)
+ else
+ nofsteps=nofsteps+1
+ steps[nofsteps]=step
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local before=rule.before
+ local current=rule.current
+ local after=rule.after
+ local replacements=rule.replacements
+ if before then
+ for i=1,#before do
+ before[i]=tohash(before[i])
+ end
+ rule.before=reversed(before)
+ end
+ if current then
+ if replacements then
+ local first=current[1]
+ local hash={}
+ local repl={}
+ for i=1,#first do
+ local c=first[i]
+ hash[c]=true
+ repl[c]=replacements[i]
+ end
+ rule.current={ hash }
+ rule.replacements=repl
+ else
+ for i=1,#current do
+ current[i]=tohash(current[i])
+ end
+ end
+ else
+ end
+ if after then
+ for i=1,#after do
+ after[i]=tohash(after[i])
+ end
+ end
+ if usedlookups then
+ local lookups=rule.lookups
+ if lookups then
+ for k,v in next,lookups do
+ if v then
+ for k,v in next,v do
+ usedlookups[v]=usedlookups[v]+1
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if nofsteps~=nofsubtables then
+ report("bogus subtables removed in %s lookup type %a",what,lookuptype)
+ end
+ lookuptype=lookupnames[lookuptype] or lookuptype
+ if features then
+ nofsequences=nofsequences+1
+ local l={
+ index=nofsequences,
+ name=f_lookupname(lookupprefix,"s",lookupid+lookupidoffset),
+ steps=steps,
+ nofsteps=nofsteps,
+ type=lookuptype,
+ markclass=markclass or nil,
+ flags=flags,
+ order=order,
+ features=features,
+ }
+ sequences[nofsequences]=l
+ lookup.done=l
+ else
+ nofsublookups=nofsublookups+1
+ local l={
+ index=nofsublookups,
+ name=f_lookupname(lookupprefix,"l",lookupid+lookupidoffset),
+ steps=steps,
+ nofsteps=nofsteps,
+ type=lookuptype,
+ markclass=markclass or nil,
+ flags=flags,
+ }
+ sublookuplist[nofsublookups]=l
+ sublookuphash[lookupid]=nofsublookups
+ sublookupcheck[lookupid]=0
+ lookup.done=l
+ end
+ else
+ report("no subtables for lookup %a",lookupid)
+ end
+ else
+ report("no handler for lookup %a with type %a",lookupid,lookuptype)
+ end
+ end
+ if usedlookups then
+ report("used %s lookups: % t",what,sortedkeys(usedlookups))
+ end
+ local reported={}
+ local function report_issue(i,what,sequence,kind)
+ local name=sequence.name
+ if not reported[name] then
+ report("rule %i in %s lookup %a has %s lookups",i,what,name,kind)
+ reported[name]=true
+ end
+ end
+ for i=lastsequence+1,nofsequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ for i=1,#steps do
+ local step=steps[i]
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local rlookups=rule.lookups
+ if not rlookups then
+ report_issue(i,what,sequence,"no")
+ elseif not next(rlookups) then
+ rule.lookups=nil
+ else
+ local length=#rlookups
+ for index=1,length do
+ 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
+ local l={
+ 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(l)
+ 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
+ sublookupcheck[lookupid]=sublookupcheck[lookupid]+1
+ end
+ if h then
+ noffound=noffound+1
+ found[noffound]=h
+ end
+ end
+ end
+ rlookups[index]=noffound>0 and found or false
+ else
+ rlookups[index]=false
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ for i,n in sortedhash(sublookupcheck) do
+ local l=lookups[i]
+ local t=l.type
+ if n==0 and t~="extension" then
+ local d=l.done
+ report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t)
+ end
+ end
+ end
+ local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
+ setposition(f,variationsoffset)
+ local version=readulong(f)
+ local nofrecords=readulong(f)
+ local records={}
+ for i=1,nofrecords do
+ records[i]={
+ conditions=readulong(f),
+ substitutions=readulong(f),
+ }
+ end
+ for i=1,nofrecords do
+ local record=records[i]
+ local offset=record.conditions
+ if offset==0 then
+ record.condition=nil
+ record.matchtype="always"
+ else
+ local offset=variationsoffset+offset
+ setposition(f,offset)
+ local nofconditions=readushort(f)
+ local conditions={}
+ for i=1,nofconditions do
+ conditions[i]=offset+readulong(f)
+ end
+ record.conditions=conditions
+ record.matchtype="condition"
+ end
+ end
+ for i=1,nofrecords do
+ local record=records[i]
+ if record.matchtype=="condition" then
+ local conditions=record.conditions
+ for i=1,#conditions do
+ setposition(f,conditions[i])
+ conditions[i]={
+ format=readushort(f),
+ axis=readushort(f),
+ minvalue=read2dot14(f),
+ maxvalue=read2dot14(f),
+ }
+ end
+ end
+ end
+ for i=1,nofrecords do
+ local record=records[i]
+ local offset=record.substitutions
+ if offset==0 then
+ record.substitutions={}
+ else
+ setposition(f,variationsoffset+offset)
+ local version=readulong(f)
+ local nofsubstitutions=readushort(f)
+ local substitutions={}
+ for i=1,nofsubstitutions do
+ substitutions[readushort(f)]=readulong(f)
+ end
+ for index,alternates in sortedhash(substitutions) do
+ if index==0 then
+ record.substitutions=false
+ else
+ local tableoffset=variationsoffset+offset+alternates
+ setposition(f,tableoffset)
+ local parameters=readulong(f)
+ local noflookups=readushort(f)
+ local lookups=readcardinaltable(f,noflookups,ushort)
+ record.substitutions=lookups
+ end
+ end
+ end
+ end
+ setvariabledata(fontdata,"features",records)
+ end
+ local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo)
+ local tableoffset=gotodatatable(f,fontdata,what,true)
+ if tableoffset then
+ local version=readulong(f)
+ local scriptoffset=tableoffset+readushort(f)
+ local featureoffset=tableoffset+readushort(f)
+ local lookupoffset=tableoffset+readushort(f)
+ local variationsoffset=version>0x00010000 and (tableoffset+readulong(f)) or 0
+ if not scriptoffset then
+ return
+ end
+ local scripts=readscriplan(f,fontdata,scriptoffset)
+ local features=readfeatures(f,fontdata,featureoffset)
+ local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features)
+ if fontdata.features then
+ fontdata.features[what]=scriptlangs
+ else
+ fontdata.features={ [what]=scriptlangs }
+ end
+ if not lookupstoo then
+ return
+ end
+ local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder)
+ if lookups then
+ resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset)
+ end
+ if variationsoffset>0 then
+ loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
+ end
+ end
+ end
+ local function checkkerns(f,fontdata,specification)
+ local datatable=fontdata.tables.kern
+ if not datatable then
+ return
+ end
+ local features=fontdata.features
+ local gposfeatures=features and features.gpos
+ local name
+ if not gposfeatures or not gposfeatures.kern then
+ name="kern"
+ elseif specification.globalkerns then
+ name="globalkern"
+ else
+ report("ignoring global kern table, using gpos kern feature")
+ return
+ end
+ setposition(f,datatable.offset)
+ local version=readushort(f)
+ local noftables=readushort(f)
+ if noftables>1 then
+ report("adding global kern table as gpos feature %a",name)
+ local kerns=setmetatableindex("table")
+ for i=1,noftables do
+ local version=readushort(f)
+ local length=readushort(f)
+ local coverage=readushort(f)
+ local format=rshift(coverage,8)
+ if format==0 then
+ local nofpairs=readushort(f)
+ local searchrange=readushort(f)
+ local entryselector=readushort(f)
+ local rangeshift=readushort(f)
+ for i=1,nofpairs do
+ kerns[readushort(f)][readushort(f)]=readfword(f)
+ end
+ elseif format==2 then
+ else
+ end
+ end
+ local feature={ dflt={ dflt=true } }
+ if not features then
+ fontdata.features={ gpos={ [name]=feature } }
+ elseif not gposfeatures then
+ fontdata.features.gpos={ [name]=feature }
+ else
+ gposfeatures[name]=feature
+ end
+ local sequences=fontdata.sequences
+ if not sequences then
+ sequences={}
+ fontdata.sequences=sequences
+ end
+ local nofsequences=#sequences+1
+ sequences[nofsequences]={
+ index=nofsequences,
+ name=name,
+ steps={
+ {
+ coverage=kerns,
+ format="kern",
+ },
+ },
+ nofsteps=1,
+ type="gpos_pair",
+ flags={ false,false,false,false },
+ order={ name },
+ features={ [name]=feature },
+ }
+ else
+ report("ignoring empty kern table of feature %a",name)
+ end
+ end
+ function readers.gsub(f,fontdata,specification)
+ if specification.details then
+ readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups)
+ end
+ end
+ function readers.gpos(f,fontdata,specification)
+ if specification.details then
+ readscripts(f,fontdata,"gpos",gpostypes,gposhandlers,specification.lookups)
+ if specification.lookups then
+ checkkerns(f,fontdata,specification)
+ end
+ end
+ end
+end
+function readers.gdef(f,fontdata,specification)
+ if not specification.glyphs then
+ return
+ end
+ local datatable=fontdata.tables.gdef
+ if datatable then
+ local tableoffset=datatable.offset
+ setposition(f,tableoffset)
+ local version=readulong(f)
+ local classoffset=readushort(f)
+ local attachmentoffset=readushort(f)
+ local ligaturecarets=readushort(f)
+ local markclassoffset=readushort(f)
+ local marksetsoffset=version>=0x00010002 and readushort(f) or 0
+ local varsetsoffset=version>=0x00010003 and readulong(f) or 0
+ local glyphs=fontdata.glyphs
+ local marks={}
+ local markclasses=setmetatableindex("table")
+ local marksets=setmetatableindex("table")
+ fontdata.marks=marks
+ fontdata.markclasses=markclasses
+ fontdata.marksets=marksets
+ if classoffset~=0 then
+ setposition(f,tableoffset+classoffset)
+ local classformat=readushort(f)
+ if classformat==1 then
+ local firstindex=readushort(f)
+ local lastindex=firstindex+readushort(f)-1
+ for index=firstindex,lastindex do
+ local class=classes[readushort(f)]
+ if class=="mark" then
+ marks[index]=true
+ end
+ glyphs[index].class=class
+ end
+ elseif classformat==2 then
+ local nofranges=readushort(f)
+ for i=1,nofranges do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local class=classes[readushort(f)]
+ if class then
+ for index=firstindex,lastindex do
+ glyphs[index].class=class
+ if class=="mark" then
+ marks[index]=true
+ end
+ end
+ end
+ end
+ end
+ end
+ if markclassoffset~=0 then
+ setposition(f,tableoffset+markclassoffset)
+ local classformat=readushort(f)
+ if classformat==1 then
+ local firstindex=readushort(f)
+ local lastindex=firstindex+readushort(f)-1
+ for index=firstindex,lastindex do
+ markclasses[readushort(f)][index]=true
+ end
+ elseif classformat==2 then
+ local nofranges=readushort(f)
+ for i=1,nofranges do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local class=markclasses[readushort(f)]
+ for index=firstindex,lastindex do
+ class[index]=true
+ end
+ end
+ end
+ end
+ if marksetsoffset~=0 then
+ marksetsoffset=tableoffset+marksetsoffset
+ setposition(f,marksetsoffset)
+ local format=readushort(f)
+ if format==1 then
+ local nofsets=readushort(f)
+ local sets=readcardinaltable(f,nofsets,ulong)
+ for i=1,nofsets do
+ local offset=sets[i]
+ if offset~=0 then
+ marksets[i]=readcoverage(f,marksetsoffset+offset)
+ end
+ end
+ end
+ end
+ local factors=specification.factors
+ if (specification.variable or factors) and varsetsoffset~=0 then
+ local regions,deltas=readvariationdata(f,tableoffset+varsetsoffset,factors)
+ if factors then
+ fontdata.temporary.getdelta=function(outer,inner)
+ local delta=deltas[outer+1]
+ if delta then
+ local d=delta.deltas[inner+1]
+ if d then
+ local scales=delta.scales
+ local dd=0
+ for i=1,#scales do
+ local di=d[i]
+ if di then
+ dd=dd+scales[i]*di
+ else
+ break
+ end
+ end
+ return round(dd)
+ end
+ end
+ return 0
+ end
+ end
+ end
+ end
+end
+local function readmathvalue(f)
+ local v=readshort(f)
+ skipshort(f,1)
+ return v
+end
+local function readmathconstants(f,fontdata,offset)
+ setposition(f,offset)
+ fontdata.mathconstants={
+ ScriptPercentScaleDown=readshort(f),
+ ScriptScriptPercentScaleDown=readshort(f),
+ DelimitedSubFormulaMinHeight=readushort(f),
+ DisplayOperatorMinHeight=readushort(f),
+ MathLeading=readmathvalue(f),
+ AxisHeight=readmathvalue(f),
+ AccentBaseHeight=readmathvalue(f),
+ FlattenedAccentBaseHeight=readmathvalue(f),
+ SubscriptShiftDown=readmathvalue(f),
+ SubscriptTopMax=readmathvalue(f),
+ SubscriptBaselineDropMin=readmathvalue(f),
+ SuperscriptShiftUp=readmathvalue(f),
+ SuperscriptShiftUpCramped=readmathvalue(f),
+ SuperscriptBottomMin=readmathvalue(f),
+ SuperscriptBaselineDropMax=readmathvalue(f),
+ SubSuperscriptGapMin=readmathvalue(f),
+ SuperscriptBottomMaxWithSubscript=readmathvalue(f),
+ SpaceAfterScript=readmathvalue(f),
+ UpperLimitGapMin=readmathvalue(f),
+ UpperLimitBaselineRiseMin=readmathvalue(f),
+ LowerLimitGapMin=readmathvalue(f),
+ LowerLimitBaselineDropMin=readmathvalue(f),
+ StackTopShiftUp=readmathvalue(f),
+ StackTopDisplayStyleShiftUp=readmathvalue(f),
+ StackBottomShiftDown=readmathvalue(f),
+ StackBottomDisplayStyleShiftDown=readmathvalue(f),
+ StackGapMin=readmathvalue(f),
+ StackDisplayStyleGapMin=readmathvalue(f),
+ StretchStackTopShiftUp=readmathvalue(f),
+ StretchStackBottomShiftDown=readmathvalue(f),
+ StretchStackGapAboveMin=readmathvalue(f),
+ StretchStackGapBelowMin=readmathvalue(f),
+ FractionNumeratorShiftUp=readmathvalue(f),
+ FractionNumeratorDisplayStyleShiftUp=readmathvalue(f),
+ FractionDenominatorShiftDown=readmathvalue(f),
+ FractionDenominatorDisplayStyleShiftDown=readmathvalue(f),
+ FractionNumeratorGapMin=readmathvalue(f),
+ FractionNumeratorDisplayStyleGapMin=readmathvalue(f),
+ FractionRuleThickness=readmathvalue(f),
+ FractionDenominatorGapMin=readmathvalue(f),
+ FractionDenominatorDisplayStyleGapMin=readmathvalue(f),
+ SkewedFractionHorizontalGap=readmathvalue(f),
+ SkewedFractionVerticalGap=readmathvalue(f),
+ OverbarVerticalGap=readmathvalue(f),
+ OverbarRuleThickness=readmathvalue(f),
+ OverbarExtraAscender=readmathvalue(f),
+ UnderbarVerticalGap=readmathvalue(f),
+ UnderbarRuleThickness=readmathvalue(f),
+ UnderbarExtraDescender=readmathvalue(f),
+ RadicalVerticalGap=readmathvalue(f),
+ RadicalDisplayStyleVerticalGap=readmathvalue(f),
+ RadicalRuleThickness=readmathvalue(f),
+ RadicalExtraAscender=readmathvalue(f),
+ RadicalKernBeforeDegree=readmathvalue(f),
+ RadicalKernAfterDegree=readmathvalue(f),
+ RadicalDegreeBottomRaisePercent=readshort(f),
+ }
+end
+local function readmathglyphinfo(f,fontdata,offset)
+ setposition(f,offset)
+ local italics=readushort(f)
+ local accents=readushort(f)
+ local extensions=readushort(f)
+ local kerns=readushort(f)
+ local glyphs=fontdata.glyphs
+ if italics~=0 then
+ setposition(f,offset+italics)
+ local coverage=readushort(f)
+ local nofglyphs=readushort(f)
+ coverage=readcoverage(f,offset+italics+coverage,true)
+ setposition(f,offset+italics+4)
+ for i=1,nofglyphs do
+ local italic=readmathvalue(f)
+ if italic~=0 then
+ local glyph=glyphs[coverage[i]]
+ local math=glyph.math
+ if not math then
+ glyph.math={ italic=italic }
+ else
+ math.italic=italic
+ end
+ end
+ end
+ fontdata.hasitalics=true
+ end
+ if accents~=0 then
+ setposition(f,offset+accents)
+ local coverage=readushort(f)
+ local nofglyphs=readushort(f)
+ coverage=readcoverage(f,offset+accents+coverage,true)
+ setposition(f,offset+accents+4)
+ for i=1,nofglyphs do
+ local accent=readmathvalue(f)
+ if accent~=0 then
+ local glyph=glyphs[coverage[i]]
+ local math=glyph.math
+ if not math then
+ glyph.math={ accent=accent }
+ else
+ math.accent=accent
+ end
+ end
+ end
+ end
+ if extensions~=0 then
+ setposition(f,offset+extensions)
+ end
+ if kerns~=0 then
+ local kernoffset=offset+kerns
+ setposition(f,kernoffset)
+ local coverage=readushort(f)
+ local nofglyphs=readushort(f)
+ if nofglyphs>0 then
+ local function get(offset)
+ setposition(f,kernoffset+offset)
+ local n=readushort(f)
+ if n==0 then
+ local k=readmathvalue(f)
+ if k==0 then
+ else
+ return { { kern=k } }
+ end
+ else
+ local l={}
+ for i=1,n do
+ l[i]={ height=readmathvalue(f) }
+ end
+ for i=1,n do
+ l[i].kern=readmathvalue(f)
+ end
+ l[n+1]={ kern=readmathvalue(f) }
+ return l
+ end
+ end
+ local kernsets={}
+ for i=1,nofglyphs do
+ local topright=readushort(f)
+ local topleft=readushort(f)
+ local bottomright=readushort(f)
+ local bottomleft=readushort(f)
+ kernsets[i]={
+ topright=topright~=0 and topright or nil,
+ topleft=topleft~=0 and topleft or nil,
+ bottomright=bottomright~=0 and bottomright or nil,
+ bottomleft=bottomleft~=0 and bottomleft or nil,
+ }
+ end
+ coverage=readcoverage(f,kernoffset+coverage,true)
+ for i=1,nofglyphs do
+ local kernset=kernsets[i]
+ if next(kernset) then
+ local k=kernset.topright if k then kernset.topright=get(k) end
+ local k=kernset.topleft if k then kernset.topleft=get(k) end
+ local k=kernset.bottomright if k then kernset.bottomright=get(k) end
+ local k=kernset.bottomleft if k then kernset.bottomleft=get(k) end
+ if next(kernset) then
+ local glyph=glyphs[coverage[i]]
+ local math=glyph.math
+ if math then
+ math.kerns=kernset
+ else
+ glyph.math={ kerns=kernset }
+ end
+ end
+ end
+ end
+ end
+ end
+end
+local function readmathvariants(f,fontdata,offset)
+ setposition(f,offset)
+ local glyphs=fontdata.glyphs
+ local minoverlap=readushort(f)
+ local vcoverage=readushort(f)
+ local hcoverage=readushort(f)
+ local vnofglyphs=readushort(f)
+ local hnofglyphs=readushort(f)
+ local vconstruction=readcardinaltable(f,vnofglyphs,ushort)
+ local hconstruction=readcardinaltable(f,hnofglyphs,ushort)
+ fontdata.mathconstants.MinConnectorOverlap=minoverlap
+ local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic)
+ if coverage~=0 and nofglyphs>0 then
+ local coverage=readcoverage(f,offset+coverage,true)
+ for i=1,nofglyphs do
+ local c=construction[i]
+ if c~=0 then
+ local index=coverage[i]
+ local glyph=glyphs[index]
+ local math=glyph.math
+ setposition(f,offset+c)
+ local assembly=readushort(f)
+ local nofvariants=readushort(f)
+ if nofvariants>0 then
+ local variants,v=nil,0
+ for i=1,nofvariants do
+ local variant=readushort(f)
+ if variant==index then
+ elseif variants then
+ v=v+1
+ variants[v]=variant
+ else
+ v=1
+ variants={ variant }
+ end
+ skipshort(f)
+ end
+ if not variants then
+ elseif not math then
+ math={ [kvariants]=variants }
+ glyph.math=math
+ else
+ math[kvariants]=variants
+ end
+ end
+ if assembly~=0 then
+ setposition(f,offset+c+assembly)
+ local italic=readmathvalue(f)
+ local nofparts=readushort(f)
+ local parts={}
+ for i=1,nofparts do
+ local p={
+ glyph=readushort(f),
+ start=readushort(f),
+ ["end"]=readushort(f),
+ advance=readushort(f),
+ }
+ local flags=readushort(f)
+ if band(flags,0x0001)~=0 then
+ p.extender=1
+ end
+ parts[i]=p
+ end
+ if not math then
+ math={
+ [kparts]=parts
+ }
+ glyph.math=math
+ else
+ math[kparts]=parts
+ end
+ if italic and italic~=0 then
+ math[kitalic]=italic
+ end
+ end
+ end
+ end
+ end
+ end
+ get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic")
+ get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic")
+end
+function readers.math(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"math",specification.glyphs)
+ if tableoffset then
+ local version=readulong(f)
+ local constants=readushort(f)
+ local glyphinfo=readushort(f)
+ local variants=readushort(f)
+ if constants==0 then
+ report("the math table of %a has no constants",fontdata.filename)
+ else
+ readmathconstants(f,fontdata,tableoffset+constants)
+ end
+ if glyphinfo~=0 then
+ readmathglyphinfo(f,fontdata,tableoffset+glyphinfo)
+ end
+ if variants~=0 then
+ readmathvariants(f,fontdata,tableoffset+variants)
+ end
+ end
+end
+function readers.colr(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"colr",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ if version~=0 then
+ report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename)
+ return
+ end
+ if not fontdata.tables.cpal then
+ report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal")
+ fontdata.colorpalettes={}
+ end
+ local glyphs=fontdata.glyphs
+ local nofglyphs=readushort(f)
+ local baseoffset=readulong(f)
+ local layeroffset=readulong(f)
+ local noflayers=readushort(f)
+ local layerrecords={}
+ local maxclass=0
+ setposition(f,tableoffset+layeroffset)
+ for i=1,noflayers do
+ local slot=readushort(f)
+ local class=readushort(f)
+ if class<0xFFFF then
+ class=class+1
+ if class>maxclass then
+ maxclass=class
+ end
+ end
+ layerrecords[i]={
+ slot=slot,
+ class=class,
+ }
+ end
+ fontdata.maxcolorclass=maxclass
+ setposition(f,tableoffset+baseoffset)
+ for i=0,nofglyphs-1 do
+ local glyphindex=readushort(f)
+ local firstlayer=readushort(f)
+ local noflayers=readushort(f)
+ local t={}
+ for i=1,noflayers do
+ t[i]=layerrecords[firstlayer+i]
+ end
+ glyphs[glyphindex].colors=t
+ end
+ end
+ fontdata.hascolor=true
+end
+function readers.cpal(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"cpal",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local nofpaletteentries=readushort(f)
+ local nofpalettes=readushort(f)
+ local nofcolorrecords=readushort(f)
+ local firstcoloroffset=readulong(f)
+ local colorrecords={}
+ local palettes=readcardinaltable(f,nofpalettes,ushort)
+ if version==1 then
+ local palettettypesoffset=readulong(f)
+ local palettelabelsoffset=readulong(f)
+ local paletteentryoffset=readulong(f)
+ end
+ setposition(f,tableoffset+firstcoloroffset)
+ for i=1,nofcolorrecords do
+ local b,g,r,a=readbytes(f,4)
+ colorrecords[i]={
+ r,g,b,a~=255 and a or nil,
+ }
+ end
+ for i=1,nofpalettes do
+ local p={}
+ local o=palettes[i]
+ for j=1,nofpaletteentries do
+ p[j]=colorrecords[o+j]
+ end
+ palettes[i]=p
+ end
+ fontdata.colorpalettes=palettes
+ end
+end
+function readers.svg(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local glyphs=fontdata.glyphs
+ local indexoffset=tableoffset+readulong(f)
+ local reserved=readulong(f)
+ setposition(f,indexoffset)
+ local nofentries=readushort(f)
+ local entries={}
+ for i=1,nofentries do
+ entries[i]={
+ first=readushort(f),
+ last=readushort(f),
+ offset=indexoffset+readulong(f),
+ length=readulong(f),
+ }
+ end
+ for i=1,nofentries do
+ local entry=entries[i]
+ setposition(f,entry.offset)
+ entries[i]={
+ first=entry.first,
+ last=entry.last,
+ data=readstring(f,entry.length)
+ }
+ end
+ fontdata.svgshapes=entries
+ end
+ fontdata.hascolor=true
+end
+function readers.sbix(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"sbix",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local flags=readushort(f)
+ local nofstrikes=readulong(f)
+ local strikes={}
+ local nofglyphs=fontdata.nofglyphs
+ for i=1,nofstrikes do
+ strikes[i]=readulong(f)
+ end
+ local shapes={}
+ local done=0
+ for i=1,nofstrikes do
+ local strikeoffset=strikes[i]+tableoffset
+ setposition(f,strikeoffset)
+ strikes[i]={
+ ppem=readushort(f),
+ ppi=readushort(f),
+ offset=strikeoffset
+ }
+ end
+ sort(strikes,function(a,b)
+ if b.ppem==a.ppem then
+ return b.ppi<a.ppi
+ else
+ return b.ppem<a.ppem
+ end
+ end)
+ local glyphs={}
+ for i=1,nofstrikes do
+ local strike=strikes[i]
+ local strikeppem=strike.ppem
+ local strikeppi=strike.ppi
+ local strikeoffset=strike.offset
+ setposition(f,strikeoffset)
+ for i=0,nofglyphs do
+ glyphs[i]=readulong(f)
+ end
+ local glyphoffset=glyphs[0]
+ for i=0,nofglyphs-1 do
+ local nextoffset=glyphs[i+1]
+ if not shapes[i] then
+ local datasize=nextoffset-glyphoffset
+ if datasize>0 then
+ setposition(f,strikeoffset+glyphoffset)
+ shapes[i]={
+ x=readshort(f),
+ y=readshort(f),
+ tag=readtag(f),
+ data=readstring(f,datasize-8),
+ ppem=strikeppem,
+ ppi=strikeppi,
+ }
+ done=done+1
+ if done==nofglyphs then
+ break
+ end
+ end
+ end
+ glyphoffset=nextoffset
+ end
+ end
+ fontdata.pngshapes=shapes
+ end
+end
+do
+ local function getmetrics(f)
+ return {
+ ascender=readinteger(f),
+ descender=readinteger(f),
+ widthmax=readuinteger(f),
+ caretslopedumerator=readinteger(f),
+ caretslopedenominator=readinteger(f),
+ caretoffset=readinteger(f),
+ minorigin=readinteger(f),
+ minadvance=readinteger(f),
+ maxbefore=readinteger(f),
+ minafter=readinteger(f),
+ pad1=readinteger(f),
+ pad2=readinteger(f),
+ }
+ end
+ local function getbigmetrics(f)
+ return {
+ height=readuinteger(f),
+ width=readuinteger(f),
+ horiBearingX=readinteger(f),
+ horiBearingY=readinteger(f),
+ horiAdvance=readuinteger(f),
+ vertBearingX=readinteger(f),
+ vertBearingY=readinteger(f),
+ vertAdvance=readuinteger(f),
+ }
+ end
+ local function getsmallmetrics(f)
+ return {
+ height=readuinteger(f),
+ width=readuinteger(f),
+ bearingX=readinteger(f),
+ bearingY=readinteger(f),
+ advance=readuinteger(f),
+ }
+ end
+ function readers.cblc(f,fontdata,specification)
+ local ctdttableoffset=gotodatatable(f,fontdata,"cbdt",specification.glyphs)
+ if not ctdttableoffset then
+ return
+ end
+ local cblctableoffset=gotodatatable(f,fontdata,"cblc",specification.glyphs)
+ if cblctableoffset then
+ local majorversion=readushort(f)
+ local minorversion=readushort(f)
+ local nofsizetables=readulong(f)
+ local sizetables={}
+ local shapes={}
+ local subtables={}
+ for i=1,nofsizetables do
+ sizetables[i]={
+ subtables=readulong(f),
+ indexsize=readulong(f),
+ nofsubtables=readulong(f),
+ colorref=readulong(f),
+ hormetrics=getmetrics(f),
+ vermetrics=getmetrics(f),
+ firstindex=readushort(f),
+ lastindex=readushort(f),
+ ppemx=readbyte(f),
+ ppemy=readbyte(f),
+ bitdepth=readbyte(f),
+ flags=readbyte(f),
+ }
+ end
+ sort(sizetables,function(a,b)
+ if b.ppemx==a.ppemx then
+ return b.bitdepth<a.bitdepth
+ else
+ return b.ppemx<a.ppemx
+ end
+ end)
+ for i=1,nofsizetables do
+ local s=sizetables[i]
+ local d=false
+ for j=s.firstindex,s.lastindex do
+ if not shapes[j] then
+ shapes[j]=i
+ d=true
+ end
+ end
+ if d then
+ s.used=true
+ end
+ end
+ for i=1,nofsizetables do
+ local s=sizetables[i]
+ if s.used then
+ local offset=s.subtables
+ setposition(f,cblctableoffset+offset)
+ for j=1,s.nofsubtables do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local tableoffset=readulong(f)+offset
+ for k=firstindex,lastindex do
+ if shapes[k]==i then
+ local s=subtables[tableoffset]
+ if not s then
+ s={
+ firstindex=firstindex,
+ lastindex=lastindex,
+ }
+ subtables[tableoffset]=s
+ end
+ shapes[k]=s
+ end
+ end
+ end
+ end
+ end
+ for offset,subtable in sortedhash(subtables) do
+ local tabletype=readushort(f)
+ subtable.format=readushort(f)
+ local baseoffset=readulong(f)+ctdttableoffset
+ local offsets={}
+ local metrics=nil
+ if tabletype==1 then
+ for i=subtable.firstindex,subtable.lastindex do
+ offsets[i]=readulong(f)+baseoffset
+ end
+ skipbytes(f,4)
+ elseif tabletype==2 then
+ local size=readulong(f)
+ local done=baseoffset
+ metrics=getbigmetrics(f)
+ for i=subtable.firstindex,subtable.lastindex do
+ offsets[i]=done
+ done=done+size
+ end
+ elseif tabletype==3 then
+ local n=subtable.lastindex-subtable.firstindex+2
+ for i=subtable.firstindex,subtable.lastindex do
+ offsets[i]=readushort(f)+baseoffset
+ end
+ if math.odd(n) then
+ skipbytes(f,4)
+ else
+ skipbytes(f,2)
+ end
+ elseif tabletype==4 then
+ for i=1,readulong(f) do
+ offsets[readushort(f)]=readushort(f)+baseoffset
+ end
+ elseif tabletype==5 then
+ local size=readulong(f)
+ local done=baseoffset
+ metrics=getbigmetrics(f)
+ local n=readulong(f)
+ for i=1,n do
+ offsets[readushort(f)]=done
+ done=done+size
+ end
+ if math.odd(n) then
+ skipbytes(f,2)
+ end
+ else
+ return
+ end
+ subtable.offsets=offsets
+ subtable.metrics=metrics
+ end
+ local default={ width=0,height=0 }
+ local glyphs=fontdata.glyphs
+ for index,subtable in sortedhash(shapes) do
+ if type(subtable)=="table" then
+ local data=nil
+ local metrics=default
+ local format=subtable.format
+ local offset=subtable.offsets[index]
+ setposition(f,offset)
+ if format==17 then
+ metrics=getsmallmetrics(f)
+ data=readstring(f,readulong(f))
+ elseif format==18 then
+ metrics=getbigmetrics(f)
+ data=readstring(f,readulong(f))
+ elseif format==19 then
+ metrics=subtable.metrics
+ data=readstring(f,readulong(f))
+ else
+ end
+ local x=metrics.width
+ local y=metrics.height
+ shapes[index]={
+ x=x,
+ y=y,
+ data=data,
+ }
+ local glyph=glyphs[index]
+ if not glyph.boundingbox then
+ local width=glyph.width
+ local height=width*y/x
+ glyph.boundingbox={ 0,0,width,height }
+ end
+ else
+ shapes[index]={
+ x=0,
+ y=0,
+ data="",
+ }
+ end
+ end
+ fontdata.pngshapes=shapes
+ end
+ end
+ function readers.cbdt(f,fontdata,specification)
+ end
+end
+function readers.stat(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"stat",true)
+ if tableoffset then
+ local extras=fontdata.extras
+ local version=readulong(f)
+ local axissize=readushort(f)
+ local nofaxis=readushort(f)
+ local axisoffset=readulong(f)
+ local nofvalues=readushort(f)
+ local valuesoffset=readulong(f)
+ local fallbackname=extras[readushort(f)]
+ local axis={}
+ local values={}
+ setposition(f,tableoffset+axisoffset)
+ for i=1,nofaxis do
+ local tag=readtag(f)
+ axis[i]={
+ tag=tag,
+ name=lower(extras[readushort(f)] or tag),
+ ordering=readushort(f),
+ variants={}
+ }
+ end
+ setposition(f,tableoffset+valuesoffset)
+ for i=1,nofvalues do
+ values[i]=readushort(f)
+ end
+ for i=1,nofvalues do
+ setposition(f,tableoffset+valuesoffset+values[i])
+ local format=readushort(f)
+ local index=readushort(f)+1
+ local flags=readushort(f)
+ local name=lower(extras[readushort(f)] or "no name")
+ local value=readfixed(f)
+ local variant
+ if format==1 then
+ variant={
+ flags=flags,
+ name=name,
+ value=value,
+ }
+ elseif format==2 then
+ variant={
+ flags=flags,
+ name=name,
+ value=value,
+ minimum=readfixed(f),
+ maximum=readfixed(f),
+ }
+ elseif format==3 then
+ variant={
+ flags=flags,
+ name=name,
+ value=value,
+ link=readfixed(f),
+ }
+ end
+ insert(axis[index].variants,variant)
+ end
+ sort(axis,function(a,b)
+ return a.ordering<b.ordering
+ end)
+ for i=1,#axis do
+ local a=axis[i]
+ sort(a.variants,function(a,b)
+ return a.name<b.name
+ end)
+ a.ordering=nil
+ end
+ setvariabledata(fontdata,"designaxis",axis)
+ setvariabledata(fontdata,"fallbackname",fallbackname)
+ end
+end
+function readers.avar(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"avar",true)
+ if tableoffset then
+ local function collect()
+ local nofvalues=readushort(f)
+ local values={}
+ local lastfrom=false
+ local lastto=false
+ for i=1,nofvalues do
+ local from=read2dot14(f)
+ local to=read2dot14(f)
+ if lastfrom and from<=lastfrom then
+ elseif lastto and to>=lastto then
+ else
+ values[#values+1]={ from,to }
+ lastfrom,lastto=from,to
+ end
+ end
+ nofvalues=#values
+ if nofvalues>2 then
+ local some=values[1]
+ if some[1]==-1 and some[2]==-1 then
+ some=values[nofvalues]
+ if some[1]==1 and some[2]==1 then
+ for i=2,nofvalues-1 do
+ some=values[i]
+ if some[1]==0 and some[2]==0 then
+ return values
+ end
+ end
+ end
+ end
+ end
+ return false
+ end
+ local version=readulong(f)
+ local reserved=readushort(f)
+ local nofaxis=readushort(f)
+ local segments={}
+ for i=1,nofaxis do
+ segments[i]=collect()
+ end
+ setvariabledata(fontdata,"segments",segments)
+ end
+end
+function readers.fvar(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"fvar",true)
+ if tableoffset then
+ local version=readulong(f)
+ local offsettoaxis=tableoffset+readushort(f)
+ local reserved=skipshort(f)
+ local nofaxis=readushort(f)
+ local sizeofaxis=readushort(f)
+ local nofinstances=readushort(f)
+ local sizeofinstances=readushort(f)
+ local extras=fontdata.extras
+ local axis={}
+ local instances={}
+ setposition(f,offsettoaxis)
+ for i=1,nofaxis do
+ axis[i]={
+ tag=readtag(f),
+ minimum=readfixed(f),
+ default=readfixed(f),
+ maximum=readfixed(f),
+ flags=readushort(f),
+ name=lower(extras[readushort(f)] or "bad name"),
+ }
+ local n=sizeofaxis-20
+ if n>0 then
+ skipbytes(f,n)
+ elseif n<0 then
+ end
+ end
+ local nofbytes=2+2+2+nofaxis*4
+ local readpsname=nofbytes<=sizeofinstances
+ local skippable=sizeofinstances-nofbytes
+ for i=1,nofinstances do
+ local subfamid=readushort(f)
+ local flags=readushort(f)
+ local values={}
+ for i=1,nofaxis do
+ values[i]={
+ axis=axis[i].tag,
+ value=readfixed(f),
+ }
+ end
+ local psnameid=readpsname and readushort(f) or 0xFFFF
+ if subfamid==2 or subfamid==17 then
+ elseif subfamid==0xFFFF then
+ subfamid=nil
+ elseif subfamid<=256 or subfamid>=32768 then
+ subfamid=nil
+ end
+ if psnameid==6 then
+ elseif psnameid==0xFFFF then
+ psnameid=nil
+ elseif psnameid<=256 or psnameid>=32768 then
+ psnameid=nil
+ end
+ instances[i]={
+ subfamily=extras[subfamid],
+ psname=psnameid and extras[psnameid] or nil,
+ values=values,
+ }
+ if skippable>0 then
+ skipbytes(f,skippable)
+ end
+ end
+ setvariabledata(fontdata,"axis",axis)
+ setvariabledata(fontdata,"instances",instances)
+ end
+end
+function readers.hvar(f,fontdata,specification)
+ local factors=specification.factors
+ if not factors then
+ return
+ end
+ local tableoffset=gotodatatable(f,fontdata,"hvar",specification.variable)
+ if not tableoffset then
+ return
+ end
+ local version=readulong(f)
+ local variationoffset=tableoffset+readulong(f)
+ local advanceoffset=tableoffset+readulong(f)
+ local lsboffset=tableoffset+readulong(f)
+ local rsboffset=tableoffset+readulong(f)
+ local regions={}
+ local variations={}
+ local innerindex={}
+ local outerindex={}
+ if variationoffset>0 then
+ regions,deltas=readvariationdata(f,variationoffset,factors)
+ end
+ if not regions then
+ return
+ end
+ if advanceoffset>0 then
+ setposition(f,advanceoffset)
+ local format=readushort(f)
+ local mapcount=readushort(f)
+ local entrysize=rshift(band(format,0x0030),4)+1
+ local nofinnerbits=band(format,0x000F)+1
+ local innermask=lshift(1,nofinnerbits)-1
+ local readcardinal=read_cardinal[entrysize]
+ for i=0,mapcount-1 do
+ local mapdata=readcardinal(f)
+ outerindex[i]=rshift(mapdata,nofinnerbits)
+ innerindex[i]=band(mapdata,innermask)
+ end
+ setvariabledata(fontdata,"hvarwidths",true)
+ local glyphs=fontdata.glyphs
+ for i=0,fontdata.nofglyphs-1 do
+ local glyph=glyphs[i]
+ local width=glyph.width
+ if width then
+ local outer=outerindex[i] or 0
+ local inner=innerindex[i] or i
+ if outer and inner then
+ local delta=deltas[outer+1]
+ if delta then
+ local d=delta.deltas[inner+1]
+ if d then
+ local scales=delta.scales
+ local deltaw=0
+ for i=1,#scales do
+ local di=d[i]
+ if di then
+ deltaw=deltaw+scales[i]*di
+ else
+ break
+ end
+ end
+ glyph.width=width+round(deltaw)
+ end
+ end
+ end
+ end
+ end
+ end
+end
+function readers.vvar(f,fontdata,specification)
+ if not specification.variable then
+ return
+ end
+end
+function readers.mvar(f,fontdata,specification)
+ local tableoffset=gotodatatable(f,fontdata,"mvar",specification.variable)
+ if tableoffset then
+ local version=readulong(f)
+ local reserved=skipshort(f,1)
+ local recordsize=readushort(f)
+ local nofrecords=readushort(f)
+ local offsettostore=tableoffset+readushort(f)
+ local dimensions={}
+ local factors=specification.factors
+ if factors then
+ local regions,deltas=readvariationdata(f,offsettostore,factors)
+ for i=1,nofrecords do
+ local tag=readtag(f)
+ local var=variabletags[tag]
+ if var then
+ local outer=readushort(f)
+ local inner=readushort(f)
+ local delta=deltas[outer+1]
+ if delta then
+ local d=delta.deltas[inner+1]
+ if d then
+ local scales=delta.scales
+ local dd=0
+ for i=1,#scales do
+ dd=dd+scales[i]*d[i]
+ end
+ var(fontdata,round(dd))
+ end
+ end
+ else
+ skipshort(f,2)
+ end
+ if recordsize>8 then
+ skipbytes(recordsize-8)
+ end
+ end
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-oup']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type=next,type
+local P,R,S=lpeg.P,lpeg.R,lpeg.S
+local lpegmatch=lpeg.match
+local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack
+local formatters=string.formatters
+local sortedkeys=table.sortedkeys
+local sortedhash=table.sortedhash
+local tohash=table.tohash
+local setmetatableindex=table.setmetatableindex
+local report_error=logs.reporter("otf reader","error")
+local report_markwidth=logs.reporter("otf reader","markwidth")
+local report_cleanup=logs.reporter("otf reader","cleanup")
+local report_optimizations=logs.reporter("otf reader","merges")
+local report_unicodes=logs.reporter("otf reader","unicodes")
+local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end)
+local trace_cleanup=false trackers.register("otf.cleanups",function(v) trace_cleanups=v end)
+local trace_optimizations=false trackers.register("otf.optimizations",function(v) trace_optimizations=v end)
+local trace_unicodes=false trackers.register("otf.unicodes",function(v) trace_unicodes=v end)
+local readers=fonts.handlers.otf.readers
+local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+local f_private=formatters["P%05X"]
+local f_unicode=formatters["U%05X"]
+local f_index=formatters["I%05X"]
+local f_character_y=formatters["%C"]
+local f_character_n=formatters["[ %C ]"]
+local check_duplicates=true
+local check_soft_hyphen=true
+directives.register("otf.checksofthyphen",function(v)
+ check_soft_hyphen=v
+end)
+local function replaced(list,index,replacement)
+ if type(list)=="number" then
+ return replacement
+ elseif type(replacement)=="table" then
+ local t={}
+ local n=index-1
+ for i=1,n do
+ t[i]=list[i]
+ end
+ for i=1,#replacement do
+ n=n+1
+ t[n]=replacement[i]
+ end
+ for i=index+1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ else
+ list[index]=replacement
+ return list
+ end
+end
+local function unifyresources(fontdata,indices)
+ local descriptions=fontdata.descriptions
+ local resources=fontdata.resources
+ if not descriptions or not resources then
+ return
+ end
+ local nofindices=#indices
+ local variants=fontdata.resources.variants
+ if variants then
+ for selector,unicodes in next,variants do
+ for unicode,index in next,unicodes do
+ unicodes[unicode]=indices[index]
+ end
+ end
+ end
+ local function remark(marks)
+ if marks then
+ local newmarks={}
+ for k,v in next,marks do
+ local u=indices[k]
+ if u then
+ newmarks[u]=v
+ elseif trace_optimizations then
+ report_optimizations("discarding mark %i",k)
+ end
+ end
+ return newmarks
+ end
+ end
+ local marks=resources.marks
+ if marks then
+ resources.marks=remark(marks)
+ end
+ local markclasses=resources.markclasses
+ if markclasses then
+ for class,marks in next,markclasses do
+ markclasses[class]=remark(marks)
+ end
+ end
+ local marksets=resources.marksets
+ if marksets then
+ for class,marks in next,marksets do
+ marksets[class]=remark(marks)
+ end
+ end
+ local done={}
+ local duplicates=check_duplicates and resources.duplicates
+ if duplicates and not next(duplicates) then
+ duplicates=false
+ end
+ local function recover(cover)
+ for i=1,#cover do
+ local c=cover[i]
+ if not done[c] then
+ local t={}
+ for k,v in next,c do
+ local ug=indices[k]
+ if ug then
+ t[ug]=v
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices)
+ end
+ end
+ cover[i]=t
+ done[c]=d
+ end
+ end
+ end
+ local function recursed(c,kind)
+ local t={}
+ for g,d in next,c do
+ if type(d)=="table" then
+ local ug=indices[g]
+ if ug then
+ t[ug]=recursed(d,kind)
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices)
+ end
+ else
+ t[g]=indices[d]
+ end
+ end
+ return t
+ end
+ local function unifythem(sequences)
+ if not sequences then
+ return
+ end
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local features=sequence.features
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gsub_single" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ local ud1=indices[d1]
+ if ud1 then
+ t1[ug1]=ud1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=ud1
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices)
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=indices[d1]
+ else
+ report_error("fuzzy case %i in unifying %s: %i",2,kind,g1)
+ end
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ local t2=done[d1]
+ if not t2 then
+ t2={}
+ for g2,d2 in next,d1 do
+ local ug2=indices[g2]
+ if ug2 then
+ t2[ug2]=d2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices)
+ end
+ end
+ done[d1]=t2
+ end
+ t1[ug1]=t2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gsub_ligature" then
+ local c=step.coverage
+ if c then
+ step.coverage=recursed(c,kind)
+ end
+ elseif kind=="gsub_alternate" or kind=="gsub_multiple" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ for i=1,#d1 do
+ local d1i=d1[i]
+ local d1u=indices[d1i]
+ if d1u then
+ d1[i]=d1u
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices)
+ end
+ end
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=copy(d1)
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ for i=1,#d1 do
+ local d1i=d1[i]
+ local d1u=indices[d1i]
+ if d1u then
+ d1[i]=d1u
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices)
+ end
+ end
+ t1[indices[g1]]=d1
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gpos_single" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=d1
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ local c=step.baseclasses
+ if c then
+ local t1=done[c]
+ if not t1 then
+ for g1,d1 in next,c do
+ local t2=done[d1]
+ if not t2 then
+ t2={}
+ for g2,d2 in next,d1 do
+ local ug2=indices[g2]
+ if ug2 then
+ t2[ug2]=d2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices)
+ end
+ end
+ done[d1]=t2
+ end
+ c[g1]=t2
+ end
+ done[c]=c
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=copy(d1)
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local before=rule.before if before then recover(before) end
+ local after=rule.after if after then recover(after) end
+ local current=rule.current if current then recover(current) end
+ local replacements=rule.replacements
+ if replacements then
+ if not done[replacements] then
+ local r={}
+ for k,v in next,replacements do
+ r[indices[k]]=indices[v]
+ end
+ rule.replacements=r
+ done[replacements]=r
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ unifythem(resources.sequences)
+ unifythem(resources.sublookups)
+end
+local function copyduplicates(fontdata)
+ if check_duplicates then
+ local descriptions=fontdata.descriptions
+ local resources=fontdata.resources
+ local duplicates=resources.duplicates
+ if check_soft_hyphen then
+ local ds=descriptions[0xAD]
+ if not ds or ds.width==0 then
+ if ds then
+ descriptions[0xAD]=nil
+ if trace_unicodes then
+ report_unicodes("patching soft hyphen")
+ end
+ else
+ if trace_unicodes then
+ report_unicodes("adding soft hyphen")
+ end
+ end
+ if not duplicates then
+ duplicates={}
+ resources.duplicates=duplicates
+ end
+ local dh=duplicates[0x2D]
+ if dh then
+ dh[#dh+1]={ [0xAD]=true }
+ else
+ duplicates[0x2D]={ [0xAD]=true }
+ end
+ end
+ end
+ if duplicates then
+ for u,d in next,duplicates do
+ local du=descriptions[u]
+ if du then
+ local t={ f_character_y(u),"@",f_index(du.index),"->" }
+ local n=0
+ local m=25
+ for u in next,d do
+ if descriptions[u] then
+ if n<m then
+ t[n+4]=f_character_n(u)
+ end
+ else
+ local c=copy(du)
+ c.unicode=u
+ descriptions[u]=c
+ if n<m then
+ t[n+4]=f_character_y(u)
+ end
+ end
+ n=n+1
+ end
+ if trace_unicodes then
+ if n<=m then
+ report_unicodes("%i : % t",n,t)
+ else
+ report_unicodes("%i : % t ...",n,t)
+ end
+ end
+ else
+ end
+ end
+ end
+ end
+end
+local ignore={
+ ["notdef"]=true,
+ [".notdef"]=true,
+ ["null"]=true,
+ [".null"]=true,
+ ["nonmarkingreturn"]=true,
+}
+local function checklookups(fontdata,missing,nofmissing)
+ local descriptions=fontdata.descriptions
+ local resources=fontdata.resources
+ if missing and nofmissing and nofmissing<=0 then
+ return
+ end
+ local singles={}
+ local alternates={}
+ local ligatures={}
+ if not missing then
+ missing={}
+ nofmissing=0
+ for u,d in next,descriptions do
+ if not d.unicode then
+ nofmissing=nofmissing+1
+ missing[u]=true
+ end
+ end
+ end
+ local function collectthem(sequences)
+ if not sequences then
+ return
+ end
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gsub_single" then
+ local c=step.coverage
+ if c then
+ singles[#singles+1]=c
+ end
+ elseif kind=="gsub_alternate" then
+ local c=step.coverage
+ if c then
+ alternates[#alternates+1]=c
+ end
+ elseif kind=="gsub_ligature" then
+ local c=step.coverage
+ if c then
+ ligatures[#ligatures+1]=c
+ end
+ end
+ end
+ end
+ end
+ end
+ collectthem(resources.sequences)
+ collectthem(resources.sublookups)
+ local loops=0
+ while true do
+ loops=loops+1
+ local old=nofmissing
+ for i=1,#singles do
+ local c=singles[i]
+ for g1,g2 in next,c do
+ if missing[g1] then
+ local u2=descriptions[g2].unicode
+ if u2 then
+ missing[g1]=false
+ descriptions[g1].unicode=u2
+ nofmissing=nofmissing-1
+ end
+ end
+ if missing[g2] then
+ local u1=descriptions[g1].unicode
+ if u1 then
+ missing[g2]=false
+ descriptions[g2].unicode=u1
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ end
+ for i=1,#alternates do
+ local c=alternates[i]
+ for g1,d1 in next,c do
+ if missing[g1] then
+ for i=1,#d1 do
+ local g2=d1[i]
+ local u2=descriptions[g2].unicode
+ if u2 then
+ missing[g1]=false
+ descriptions[g1].unicode=u2
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ if not missing[g1] then
+ for i=1,#d1 do
+ local g2=d1[i]
+ if missing[g2] then
+ local u1=descriptions[g1].unicode
+ if u1 then
+ missing[g2]=false
+ descriptions[g2].unicode=u1
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ end
+ end
+ end
+ if nofmissing<=0 then
+ if trace_unicodes then
+ report_unicodes("all missings done in %s loops",loops)
+ end
+ return
+ elseif old==nofmissing then
+ break
+ end
+ end
+ local t,n
+ local function recursed(c)
+ for g,d in next,c do
+ if g~="ligature" then
+ local u=descriptions[g].unicode
+ if u then
+ n=n+1
+ t[n]=u
+ recursed(d)
+ n=n-1
+ end
+ elseif missing[d] then
+ local l={}
+ local m=0
+ for i=1,n do
+ local u=t[i]
+ if type(u)=="table" then
+ for i=1,#u do
+ m=m+1
+ l[m]=u[i]
+ end
+ else
+ m=m+1
+ l[m]=u
+ end
+ end
+ missing[d]=false
+ descriptions[d].unicode=l
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ if nofmissing>0 then
+ t={}
+ n=0
+ local loops=0
+ while true do
+ loops=loops+1
+ local old=nofmissing
+ for i=1,#ligatures do
+ recursed(ligatures[i])
+ end
+ if nofmissing<=0 then
+ if trace_unicodes then
+ report_unicodes("all missings done in %s loops",loops)
+ end
+ return
+ elseif old==nofmissing then
+ break
+ end
+ end
+ t=nil
+ n=0
+ end
+ if trace_unicodes and nofmissing>0 then
+ local done={}
+ for i,r in next,missing do
+ if r then
+ local data=descriptions[i]
+ local name=data and data.name or f_index(i)
+ if not ignore[name] then
+ done[name]=true
+ end
+ end
+ end
+ if next(done) then
+ report_unicodes("not unicoded: % t",sortedkeys(done))
+ end
+ end
+end
+local function unifymissing(fontdata)
+ if not fonts.mappings then
+ require("font-map")
+ require("font-agl")
+ end
+ local unicodes={}
+ local resources=fontdata.resources
+ resources.unicodes=unicodes
+ for unicode,d in next,fontdata.descriptions do
+ if unicode<privateoffset then
+ local name=d.name
+ if name then
+ unicodes[name]=unicode
+ end
+ end
+ end
+ fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups)
+ resources.unicodes=nil
+end
+local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000
+local puafirst=0xE000
+local pualast=0xF8FF
+local function unifyglyphs(fontdata,usenames)
+ local private=fontdata.private or privateoffset
+ local glyphs=fontdata.glyphs
+ local indices={}
+ local descriptions={}
+ local names=usenames and {}
+ local resources=fontdata.resources
+ local zero=glyphs[0]
+ local zerocode=zero.unicode
+ if not zerocode then
+ zerocode=private
+ zero.unicode=zerocode
+ private=private+1
+ end
+ descriptions[zerocode]=zero
+ if names then
+ local name=glyphs[0].name or f_private(zerocode)
+ indices[0]=name
+ names[name]=zerocode
+ else
+ indices[0]=zerocode
+ end
+ if names then
+ for index=1,#glyphs do
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ private=private+1
+ elseif unicode>=firstprivate then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ private=private+1
+ elseif unicode>=puafirst and unicode<=pualast then
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ elseif descriptions[unicode] then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ private=private+1
+ else
+ local name=glyph.name or f_unicode(unicode)
+ indices[index]=name
+ names[name]=unicode
+ end
+ descriptions[unicode]=glyph
+ end
+ elseif trace_unicodes then
+ for index=1,#glyphs do
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=firstprivate then
+ local name=glyph.name
+ if name then
+ report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private)
+ else
+ report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private)
+ end
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=puafirst and unicode<=pualast then
+ local name=glyph.name
+ if name then
+ report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index)
+ else
+ report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index)
+ end
+ indices[index]=unicode
+ elseif descriptions[unicode] then
+ local name=glyph.name
+ if name then
+ report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index)
+ else
+ report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index)
+ end
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ else
+ indices[index]=unicode
+ end
+ descriptions[unicode]=glyph
+ end
+ else
+ for index=1,#glyphs do
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=firstprivate then
+ local name=glyph.name
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=puafirst and unicode<=pualast then
+ local name=glyph.name
+ indices[index]=unicode
+ elseif descriptions[unicode] then
+ local name=glyph.name
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ else
+ indices[index]=unicode
+ end
+ descriptions[unicode]=glyph
+ end
+ end
+ for index=1,#glyphs do
+ local math=glyphs[index].math
+ if math then
+ local list=math.vparts
+ if list then
+ for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
+ end
+ local list=math.hparts
+ if list then
+ for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
+ end
+ local list=math.vvariants
+ if list then
+ for i=1,#list do list[i]=indices[list[i]] end
+ end
+ local list=math.hvariants
+ if list then
+ for i=1,#list do list[i]=indices[list[i]] end
+ end
+ end
+ end
+ local colorpalettes=resources.colorpalettes
+ if colorpalettes then
+ for index=1,#glyphs do
+ local colors=glyphs[index].colors
+ if colors then
+ for i=1,#colors do
+ local c=colors[i]
+ c.slot=indices[c.slot]
+ end
+ end
+ end
+ end
+ fontdata.private=private
+ fontdata.glyphs=nil
+ fontdata.names=names
+ fontdata.descriptions=descriptions
+ fontdata.hashmethod=hashmethod
+ return indices,names
+end
+local p_crappyname do
+ local p_hex=R("af","AF","09")
+ local p_digit=R("09")
+ local p_done=S("._-")^0+P(-1)
+ local p_alpha=R("az","AZ")
+ local p_ALPHA=R("AZ")
+ p_crappyname=(
+ lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1
++lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1
++lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1
++p_digit*p_hex^3+p_alpha*p_digit^1
++P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1
+ )*p_done
+end
+local forcekeep=false
+directives.register("otf.keepnames",function(v)
+ report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
+ forcekeep=v
+end)
+local function stripredundant(fontdata)
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ local n=0
+ local c=0
+ if (not context and fonts.privateoffsets.keepnames) or forcekeep then
+ for unicode,d in next,descriptions do
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ else
+ for unicode,d in next,descriptions do
+ local name=d.name
+ if name and lpegmatch(p_crappyname,name) then
+ d.name=nil
+ n=n+1
+ end
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ end
+ if trace_cleanup then
+ if n>0 then
+ report_cleanup("%s bogus names removed (verbose unicode)",n)
+ end
+ if c>0 then
+ report_cleanup("%s base class tags removed (default is base)",c)
+ end
+ end
+ end
+end
+readers.stripredundant=stripredundant
+function readers.getcomponents(fontdata)
+ local resources=fontdata.resources
+ if resources then
+ local sequences=resources.sequences
+ if sequences then
+ local collected={}
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ if sequence.type=="gsub_ligature" then
+ local steps=sequence.steps
+ if steps then
+ local l={}
+ local function traverse(p,k,v)
+ if k=="ligature" then
+ collected[v]={ unpack(l) }
+ else
+ insert(l,k)
+ for k,vv in next,v do
+ traverse(p,k,vv)
+ end
+ remove(l)
+ end
+ end
+ for i=1,#steps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ traverse(k,k,v)
+ end
+ end
+ end
+ end
+ end
+ end
+ if next(collected) then
+ while true do
+ local done=false
+ for k,v in next,collected do
+ for i=1,#v do
+ local vi=v[i]
+ if vi==k then
+ collected[k]=nil
+ break
+ else
+ local c=collected[vi]
+ if c then
+ done=true
+ local t={}
+ local n=i-1
+ for j=1,n do
+ t[j]=v[j]
+ end
+ for j=1,#c do
+ n=n+1
+ t[n]=c[j]
+ end
+ for j=i+1,#v do
+ n=n+1
+ t[n]=v[j]
+ end
+ collected[k]=t
+ break
+ end
+ end
+ end
+ end
+ if not done then
+ break
+ end
+ end
+ return collected
+ end
+ end
+ end
+end
+readers.unifymissing=unifymissing
+function readers.rehash(fontdata,hashmethod)
+ if not (fontdata and fontdata.glyphs) then
+ return
+ end
+ if hashmethod=="indices" then
+ fontdata.hashmethod="indices"
+ elseif hashmethod=="names" then
+ fontdata.hashmethod="names"
+ local indices=unifyglyphs(fontdata,true)
+ unifyresources(fontdata,indices)
+ copyduplicates(fontdata)
+ unifymissing(fontdata)
+ else
+ fontdata.hashmethod="unicodes"
+ local indices=unifyglyphs(fontdata)
+ unifyresources(fontdata,indices)
+ copyduplicates(fontdata)
+ unifymissing(fontdata)
+ stripredundant(fontdata)
+ end
+end
+function readers.checkhash(fontdata)
+ local hashmethod=fontdata.hashmethod
+ if hashmethod=="unicodes" then
+ fontdata.names=nil
+ elseif hashmethod=="names" and fontdata.names then
+ unifyresources(fontdata,fontdata.names)
+ copyduplicates(fontdata)
+ fontdata.hashmethod="unicodes"
+ fontdata.names=nil
+ else
+ readers.rehash(fontdata,"unicodes")
+ end
+end
+function readers.addunicodetable(fontdata)
+ local resources=fontdata.resources
+ local unicodes=resources.unicodes
+ if not unicodes then
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ unicodes={}
+ resources.unicodes=unicodes
+ for u,d in next,descriptions do
+ local n=d.name
+ if n then
+ unicodes[n]=u
+ end
+ end
+ end
+ end
+end
+local concat,sort=table.concat,table.sort
+local next,type,tostring=next,type,tostring
+local criterium=1
+local threshold=0
+local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end)
+local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
+local report_otf=logs.reporter("fonts","otf loading")
+local function tabstr_normal(t)
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k..">"..tabstr_normal(v)
+ elseif v==true then
+ s[n]=k.."+"
+ elseif v then
+ s[n]=k.."="..v
+ else
+ s[n]=k.."-"
+ end
+ end
+ if n==0 then
+ return ""
+ elseif n==1 then
+ return s[1]
+ else
+ sort(s)
+ return concat(s,",")
+ end
+end
+local function tabstr_flat(t)
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ s[n]=k.."="..v
+ end
+ if n==0 then
+ return ""
+ elseif n==1 then
+ return s[1]
+ else
+ sort(s)
+ return concat(s,",")
+ end
+end
+local function tabstr_mixed(t)
+ local s={}
+ local n=#t
+ if n==0 then
+ return ""
+ elseif n==1 then
+ local k=t[1]
+ if k==true then
+ return "++"
+ elseif k==false then
+ return "--"
+ else
+ return tostring(k)
+ end
+ else
+ for i=1,n do
+ local k=t[i]
+ if k==true then
+ s[i]="++"
+ elseif k==false then
+ s[i]="--"
+ else
+ s[i]=k
+ end
+ end
+ return concat(s,",")
+ end
+end
+local function tabstr_boolean(t)
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ if v then
+ s[n]=k.."+"
+ else
+ s[n]=k.."-"
+ end
+ end
+ if n==0 then
+ return ""
+ elseif n==1 then
+ return s[1]
+ else
+ sort(s)
+ return concat(s,",")
+ end
+end
+function readers.pack(data)
+ if data then
+ local h,t,c={},{},{}
+ local hh,tt,cc={},{},{}
+ local nt,ntt=0,0
+ local function pack_normal(v)
+ local tag=tabstr_normal(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_normal_cc(v)
+ local tag=tabstr_normal(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ v[1]=0
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_flat(v)
+ local tag=tabstr_flat(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_indexed(v)
+ local tag=concat(v," ")
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_mixed(v)
+ local tag=tabstr_mixed(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_boolean(v)
+ local tag=tabstr_boolean(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_final(v)
+ if c[v]<=criterium then
+ return t[v]
+ else
+ local hv=hh[v]
+ if hv then
+ return hv
+ else
+ ntt=ntt+1
+ tt[ntt]=t[v]
+ hh[v]=ntt
+ cc[ntt]=c[v]
+ return ntt
+ end
+ end
+ end
+ local function pack_final_cc(v)
+ if c[v]<=criterium then
+ return t[v]
+ else
+ local hv=hh[v]
+ if hv then
+ return hv
+ else
+ ntt=ntt+1
+ tt[ntt]=t[v]
+ hh[v]=ntt
+ cc[ntt]=c[v]
+ return ntt
+ end
+ end
+ end
+ local function success(stage,pass)
+ if nt==0 then
+ if trace_loading or trace_packing then
+ report_otf("pack quality: nothing to pack")
+ end
+ return false
+ elseif nt>=threshold then
+ local one=0
+ local two=0
+ local rest=0
+ if pass==1 then
+ for k,v in next,c do
+ if v==1 then
+ one=one+1
+ elseif v==2 then
+ two=two+1
+ else
+ rest=rest+1
+ end
+ end
+ else
+ for k,v in next,cc do
+ if v>20 then
+ rest=rest+1
+ elseif v>10 then
+ two=two+1
+ else
+ one=one+1
+ end
+ end
+ data.tables=tt
+ end
+ if trace_loading or trace_packing then
+ report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)",
+ stage,pass,one+two+rest,one,two,rest,criterium)
+ end
+ return true
+ else
+ if trace_loading or trace_packing then
+ report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)",
+ stage,pass,nt,threshold)
+ end
+ return false
+ end
+ end
+ local function packers(pass)
+ if pass==1 then
+ return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc
+ else
+ return pack_final,pack_final,pack_final,pack_final,pack_final,pack_final_cc
+ end
+ end
+ local resources=data.resources
+ local sequences=resources.sequences
+ local sublookups=resources.sublookups
+ local features=resources.features
+ local palettes=resources.colorpalettes
+ local variable=resources.variabledata
+ local chardata=characters and characters.data
+ local descriptions=data.descriptions or data.glyphs
+ if not descriptions then
+ return
+ end
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 1, pass %s",pass)
+ end
+ local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
+ for unicode,description in next,descriptions do
+ local boundingbox=description.boundingbox
+ if boundingbox then
+ description.boundingbox=pack_indexed(boundingbox)
+ end
+ local math=description.math
+ if math then
+ local kerns=math.kerns
+ if kerns then
+ for tag,kern in next,kerns do
+ kerns[tag]=pack_normal(kern)
+ end
+ end
+ end
+ end
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local order=sequence.order
+ local features=sequence.features
+ local flags=sequence.flags
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format~="pair" then
+ for g1,d1 in next,c do
+ c[g1]=pack_normal(d1)
+ end
+ elseif step.shared then
+ local shared={}
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ if not shared[d2] then
+ local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end
+ local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end
+ shared[d2]=true
+ end
+ end
+ end
+ if pass==2 then
+ step.shared=nil
+ end
+ else
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end
+ local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end
+ end
+ end
+ end
+ end
+ elseif kind=="gpos_single" then
+ local c=step.coverage
+ if c then
+ if step.format=="single" then
+ for g1,d1 in next,c do
+ if d1 and d1~=true then
+ c[g1]=pack_indexed(d1)
+ end
+ end
+ else
+ step.coverage=pack_normal(c)
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local f=d1[2] if f then d1[2]=pack_indexed(f) end
+ local s=d1[3] if s then d1[3]=pack_indexed(s) end
+ end
+ end
+ elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ d1[g2]=pack_indexed(d2)
+ end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ d1[2]=pack_indexed(d1[2])
+ end
+ end
+ elseif kind=="gpos_mark2ligature" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ for g3,d3 in next,d2 do
+ d2[g3]=pack_indexed(d3)
+ end
+ end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ d1[2]=pack_indexed(d1[2])
+ end
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ 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.replacements if r then rule.replacements=pack_flat (r) end
+ end
+ end
+ end
+ end
+ if order then
+ sequence.order=pack_indexed(order)
+ end
+ if features then
+ for script,feature in next,features do
+ features[script]=pack_normal(feature)
+ end
+ end
+ if flags then
+ sequence.flags=pack_normal(flags)
+ end
+ end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+ if features then
+ for k,list in next,features do
+ for feature,spec in next,list do
+ list[feature]=pack_normal(spec)
+ end
+ end
+ end
+ if palettes then
+ for i=1,#palettes do
+ local p=palettes[i]
+ for j=1,#p do
+ p[j]=pack_indexed(p[j])
+ end
+ end
+ end
+ if variable then
+ local instances=variable.instances
+ if instances then
+ for i=1,#instances do
+ local v=instances[i].values
+ for j=1,#v do
+ v[j]=pack_normal(v[j])
+ end
+ end
+ end
+ local function packdeltas(main)
+ if main then
+ local deltas=main.deltas
+ if deltas then
+ for i=1,#deltas do
+ local di=deltas[i]
+ local d=di.deltas
+ for j=1,#d do
+ d[j]=pack_indexed(d[j])
+ end
+ di.regions=pack_indexed(di.regions)
+ end
+ end
+ local regions=main.regions
+ if regions then
+ for i=1,#regions do
+ local r=regions[i]
+ for j=1,#r do
+ r[j]=pack_normal(r[j])
+ end
+ end
+ end
+ end
+ end
+ packdeltas(variable.global)
+ packdeltas(variable.horizontal)
+ packdeltas(variable.vertical)
+ packdeltas(variable.metrics)
+ end
+ if not success(1,pass) then
+ return
+ end
+ end
+ if nt>0 then
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 2, pass %s",pass)
+ end
+ local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
+ for unicode,description in next,descriptions do
+ local math=description.math
+ if math then
+ local kerns=math.kerns
+ if kerns then
+ math.kerns=pack_normal(kerns)
+ end
+ end
+ end
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local features=sequence.features
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ d1[g2]=pack_normal(d2)
+ end
+ end
+ end
+ end
+ elseif kind=="gpos_mark2ligature" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ d1[g2]=pack_normal(d2)
+ end
+ end
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local r=rule.before if r then rule.before=pack_normal(r) end
+ local r=rule.after if r then rule.after=pack_normal(r) end
+ local r=rule.current if r then rule.current=pack_normal(r) end
+ end
+ end
+ end
+ end
+ if features then
+ sequence.features=pack_normal(features)
+ end
+ end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+ if variable then
+ local function unpackdeltas(main)
+ if main then
+ local regions=main.regions
+ if regions then
+ main.regions=pack_normal(regions)
+ end
+ end
+ end
+ unpackdeltas(variable.global)
+ unpackdeltas(variable.horizontal)
+ unpackdeltas(variable.vertical)
+ unpackdeltas(variable.metrics)
+ end
+ end
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 3, pass %s",pass)
+ end
+ local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local features=sequence.features
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ c[g1]=pack_normal(d1)
+ end
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ c[g1]=pack_normal_cc(d1)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+ end
+ end
+ end
+end
+local unpacked_mt={
+ __index=function(t,k)
+ t[k]=false
+ return k
+ end
+}
+function readers.unpack(data)
+ if data then
+ local tables=data.tables
+ if tables then
+ local resources=data.resources
+ local descriptions=data.descriptions or data.glyphs
+ local sequences=resources.sequences
+ local sublookups=resources.sublookups
+ local features=resources.features
+ local palettes=resources.colorpalettes
+ local variable=resources.variabledata
+ local unpacked={}
+ setmetatable(unpacked,unpacked_mt)
+ for unicode,description in next,descriptions do
+ local tv=tables[description.boundingbox]
+ if tv then
+ description.boundingbox=tv
+ end
+ local math=description.math
+ if math then
+ local kerns=math.kerns
+ if kerns then
+ local tm=tables[kerns]
+ if tm then
+ math.kerns=tm
+ kerns=unpacked[tm]
+ end
+ if kerns then
+ for k,kern in next,kerns do
+ local tv=tables[kern]
+ if tv then
+ kerns[k]=tv
+ end
+ end
+ end
+ end
+ end
+ end
+ local function unpackthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local order=sequence.order
+ local features=sequence.features
+ local flags=sequence.flags
+ local markclass=sequence.markclass
+ if features then
+ local tv=tables[features]
+ if tv then
+ sequence.features=tv
+ features=tv
+ end
+ for script,feature in next,features do
+ local tv=tables[feature]
+ if tv then
+ features[script]=tv
+ end
+ end
+ end
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ d1=tv
+ end
+ for g2,d2 in next,d1 do
+ local tv=tables[d2]
+ if tv then
+ d1[g2]=tv
+ d2=tv
+ end
+ local f=tables[d2[1]] if f then d2[1]=f end
+ local s=tables[d2[2]] if s then d2[2]=s end
+ end
+ end
+ else
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ end
+ end
+ end
+ end
+ elseif kind=="gpos_single" then
+ local c=step.coverage
+ if c then
+ if step.format=="single" then
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ end
+ end
+ else
+ local tv=tables[c]
+ if tv then
+ step.coverage=tv
+ end
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ d1=tv
+ c[g1]=d1
+ end
+ local f=tables[d1[2]] if f then d1[2]=f end
+ local s=tables[d1[3]] if s then d1[3]=s end
+ end
+ end
+ elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ local tv=tables[d2]
+ if tv then
+ d1[g2]=tv
+ end
+ end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local tv=tables[d1[2]]
+ if tv then
+ d1[2]=tv
+ end
+ end
+ end
+ elseif kind=="gpos_mark2ligature" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ local tv=tables[d2]
+ if tv then
+ d2=tv
+ d1[g2]=d2
+ end
+ for g3,d3 in next,d2 do
+ local tv=tables[d2[g3]]
+ if tv then
+ d2[g3]=tv
+ end
+ end
+ end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local tv=tables[d1[2]]
+ if tv then
+ d1[2]=tv
+ end
+ end
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local before=rule.before
+ if before then
+ local tv=tables[before]
+ if tv then
+ rule.before=tv
+ before=tv
+ end
+ for i=1,#before do
+ local tv=tables[before[i]]
+ if tv then
+ before[i]=tv
+ end
+ end
+ end
+ local after=rule.after
+ if after then
+ local tv=tables[after]
+ if tv then
+ rule.after=tv
+ after=tv
+ end
+ for i=1,#after do
+ local tv=tables[after[i]]
+ if tv then
+ after[i]=tv
+ end
+ end
+ end
+ local current=rule.current
+ if current then
+ local tv=tables[current]
+ if tv then
+ rule.current=tv
+ current=tv
+ end
+ for i=1,#current do
+ local tv=tables[current[i]]
+ if tv then
+ current[i]=tv
+ end
+ end
+ end
+ local replacements=rule.replacements
+ if replacements then
+ local tv=tables[replacements]
+ if tv then
+ rule.replacements=tv
+ end
+ end
+ end
+ end
+ end
+ end
+ if order then
+ local tv=tables[order]
+ if tv then
+ sequence.order=tv
+ end
+ end
+ if flags then
+ local tv=tables[flags]
+ if tv then
+ sequence.flags=tv
+ end
+ end
+ end
+ end
+ if sequences then
+ unpackthem(sequences)
+ end
+ if sublookups then
+ unpackthem(sublookups)
+ end
+ if features then
+ for k,list in next,features do
+ for feature,spec in next,list do
+ local tv=tables[spec]
+ if tv then
+ list[feature]=tv
+ end
+ end
+ end
+ end
+ if palettes then
+ for i=1,#palettes do
+ local p=palettes[i]
+ for j=1,#p do
+ local tv=tables[p[j]]
+ if tv then
+ p[j]=tv
+ end
+ end
+ end
+ end
+ if variable then
+ local instances=variable.instances
+ if instances then
+ for i=1,#instances do
+ local v=instances[i].values
+ for j=1,#v do
+ local tv=tables[v[j]]
+ if tv then
+ v[j]=tv
+ end
+ end
+ end
+ end
+ local function unpackdeltas(main)
+ if main then
+ local deltas=main.deltas
+ if deltas then
+ for i=1,#deltas do
+ local di=deltas[i]
+ local d=di.deltas
+ local r=di.regions
+ for j=1,#d do
+ local tv=tables[d[j]]
+ if tv then
+ d[j]=tv
+ end
+ end
+ local tv=di.regions
+ if tv then
+ di.regions=tv
+ end
+ end
+ end
+ local regions=main.regions
+ if regions then
+ local tv=tables[regions]
+ if tv then
+ main.regions=tv
+ regions=tv
+ end
+ for i=1,#regions do
+ local r=regions[i]
+ for j=1,#r do
+ local tv=tables[r[j]]
+ if tv then
+ r[j]=tv
+ end
+ end
+ end
+ end
+ end
+ end
+ unpackdeltas(variable.global)
+ unpackdeltas(variable.horizontal)
+ unpackdeltas(variable.vertical)
+ unpackdeltas(variable.metrics)
+ end
+ data.tables=nil
+ end
+ end
+end
+local mt={
+ __index=function(t,k)
+ if k=="height" then
+ local ht=t.boundingbox[4]
+ return ht<0 and 0 or ht
+ elseif k=="depth" then
+ local dp=-t.boundingbox[2]
+ return dp<0 and 0 or dp
+ elseif k=="width" then
+ return 0
+ elseif k=="name" then
+ return forcenotdef and ".notdef"
+ end
+ end
+}
+local function sameformat(sequence,steps,first,nofsteps,kind)
+ return true
+end
+local function mergesteps_1(lookup,strict)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if strict then
+ local f=first.format
+ for i=2,nofsteps do
+ if steps[i].format~=f then
+ if trace_optimizations then
+ report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
+ end
+ return 0
+ end
+ end
+ end
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ if not target[k] then
+ target[k]=v
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function mergesteps_2(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if strict then
+ local f=first.format
+ for i=2,nofsteps do
+ if steps[i].format~=f then
+ if trace_optimizations then
+ report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
+ end
+ return 0
+ end
+ end
+ end
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=target[k]
+ if tk then
+ for kk,vv in next,v do
+ if tk[kk]==nil then
+ tk[kk]=vv
+ end
+ end
+ else
+ target[k]=v
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function mergesteps_3(lookup,strict)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local coverage={}
+ for i=1,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=coverage[k]
+ if tk then
+ if trace_optimizations then
+ report_optimizations("quitting merge due to multiple checks")
+ end
+ return nofsteps
+ else
+ coverage[k]=v
+ end
+ end
+ end
+ end
+ local first=steps[1]
+ local baseclasses={}
+ for i=1,nofsteps do
+ local offset=i*10
+ local step=steps[i]
+ for k,v in sortedhash(step.baseclasses) do
+ baseclasses[offset+k]=v
+ end
+ for k,v in next,step.coverage do
+ v[1]=offset+v[1]
+ end
+ end
+ first.baseclasses=baseclasses
+ first.coverage=coverage
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function nested(old,new)
+ for k,v in next,old do
+ if k=="ligature" then
+ if not new.ligature then
+ new.ligature=v
+ end
+ else
+ local n=new[k]
+ if n then
+ nested(v,n)
+ else
+ new[k]=v
+ end
+ end
+ end
+end
+local function mergesteps_4(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=target[k]
+ if tk then
+ nested(v,tk)
+ else
+ target[k]=v
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function mergesteps_5(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ local hash=nil
+ for k,v in next,target do
+ hash=v[1]
+ break
+ end
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=target[k]
+ if tk then
+ if not tk[2] then
+ tk[2]=v[2]
+ end
+ if not tk[3] then
+ tk[3]=v[3]
+ end
+ else
+ target[k]=v
+ v[1]=hash
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
+end
+local function checkkerns(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local kerned=0
+ for i=1,nofsteps do
+ local step=steps[i]
+ if step.format=="pair" then
+ local coverage=step.coverage
+ local kerns=true
+ for g1,d1 in next,coverage do
+ if d1==true then
+ elseif not d1 then
+ elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then
+ kerns=false
+ break
+ end
+ end
+ if kerns then
+ if trace_optimizations then
+ report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
+ end
+ local c={}
+ for g1,d1 in next,coverage do
+ if d1 and d1~=true then
+ c[g1]=d1[3]
+ end
+ end
+ step.coverage=c
+ step.format="move"
+ kerned=kerned+1
+ end
+ end
+ end
+ return kerned
+end
+local function checkpairs(lookup)
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local kerned=0
+ local function onlykerns(step)
+ local coverage=step.coverage
+ for g1,d1 in next,coverage do
+ for g2,d2 in next,d1 do
+ if d2[2] then
+ return false
+ else
+ local v=d2[1]
+ if v==true then
+ elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then
+ return false
+ end
+ end
+ end
+ end
+ return coverage
+ end
+ for i=1,nofsteps do
+ local step=steps[i]
+ if step.format=="pair" then
+ local coverage=onlykerns(step)
+ if coverage then
+ if trace_optimizations then
+ report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
+ end
+ for g1,d1 in next,coverage do
+ local d={}
+ for g2,d2 in next,d1 do
+ local v=d2[1]
+ if v==true then
+ elseif v then
+ d[g2]=v[3]
+ end
+ end
+ coverage[g1]=d
+ end
+ step.format="move"
+ kerned=kerned+1
+ end
+ end
+ end
+ return kerned
+end
+local compact_pairs=true
+local compact_singles=true
+local merge_pairs=true
+local merge_singles=true
+local merge_substitutions=true
+local merge_alternates=true
+local merge_multiples=true
+local merge_ligatures=true
+local merge_cursives=true
+local merge_marks=true
+directives.register("otf.compact.pairs",function(v) compact_pairs=v end)
+directives.register("otf.compact.singles",function(v) compact_singles=v end)
+directives.register("otf.merge.pairs",function(v) merge_pairs=v end)
+directives.register("otf.merge.singles",function(v) merge_singles=v end)
+directives.register("otf.merge.substitutions",function(v) merge_substitutions=v end)
+directives.register("otf.merge.alternates",function(v) merge_alternates=v end)
+directives.register("otf.merge.multiples",function(v) merge_multiples=v end)
+directives.register("otf.merge.ligatures",function(v) merge_ligatures=v end)
+directives.register("otf.merge.cursives",function(v) merge_cursives=v end)
+directives.register("otf.merge.marks",function(v) merge_marks=v end)
+function readers.compact(data)
+ if not data or data.compacted then
+ return
+ else
+ data.compacted=true
+ end
+ local resources=data.resources
+ local merged=0
+ local kerned=0
+ local allsteps=0
+ local function compact(what)
+ local lookups=resources[what]
+ if lookups then
+ for i=1,#lookups do
+ local lookup=lookups[i]
+ local nofsteps=lookup.nofsteps
+ local kind=lookup.type
+ allsteps=allsteps+nofsteps
+ if nofsteps>1 then
+ local merg=merged
+ if kind=="gsub_single" then
+ if merge_substitutions then
+ merged=merged+mergesteps_1(lookup)
+ end
+ elseif kind=="gsub_alternate" then
+ if merge_alternates then
+ merged=merged+mergesteps_1(lookup)
+ end
+ elseif kind=="gsub_multiple" then
+ if merge_multiples then
+ merged=merged+mergesteps_1(lookup)
+ end
+ elseif kind=="gsub_ligature" then
+ if merge_ligatures then
+ merged=merged+mergesteps_4(lookup)
+ end
+ elseif kind=="gpos_single" then
+ if merge_singles then
+ merged=merged+mergesteps_1(lookup,true)
+ end
+ if compact_singles then
+ kerned=kerned+checkkerns(lookup)
+ end
+ elseif kind=="gpos_pair" then
+ if merge_pairs then
+ merged=merged+mergesteps_2(lookup)
+ end
+ if compact_pairs then
+ kerned=kerned+checkpairs(lookup)
+ end
+ elseif kind=="gpos_cursive" then
+ if merge_cursives then
+ merged=merged+mergesteps_5(lookup)
+ end
+ elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then
+ if merge_marks then
+ merged=merged+mergesteps_3(lookup)
+ end
+ end
+ if merg~=merged then
+ lookup.merged=true
+ end
+ elseif nofsteps==1 then
+ local kern=kerned
+ if kind=="gpos_single" then
+ if compact_singles then
+ kerned=kerned+checkkerns(lookup)
+ end
+ elseif kind=="gpos_pair" then
+ if compact_pairs then
+ kerned=kerned+checkpairs(lookup)
+ end
+ end
+ if kern~=kerned then
+ end
+ end
+ end
+ elseif trace_optimizations then
+ report_optimizations("no lookups in %a",what)
+ end
+ end
+ compact("sequences")
+ compact("sublookups")
+ if trace_optimizations then
+ if merged>0 then
+ report_optimizations("%i steps of %i removed due to merging",merged,allsteps)
+ end
+ if kerned>0 then
+ report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps)
+ end
+ end
+end
+local function mergesteps(t,k)
+ if k=="merged" then
+ local merged={}
+ for i=1,#t do
+ local step=t[i]
+ local coverage=step.coverage
+ for k in next,coverage do
+ local m=merged[k]
+ if m then
+ m[2]=i
+ else
+ merged[k]={ i,i }
+ end
+ end
+ end
+ t.merged=merged
+ return merged
+ end
+end
+local function checkmerge(sequence)
+ local steps=sequence.steps
+ if steps then
+ setmetatableindex(steps,mergesteps)
+ end
+end
+local function checkflags(sequence,resources)
+ if not sequence.skiphash then
+ local flags=sequence.flags
+ if flags then
+ local skipmark=flags[1]
+ local skipligature=flags[2]
+ local skipbase=flags[3]
+ local markclass=sequence.markclass
+ local skipsome=skipmark or skipligature or skipbase or markclass or false
+ if skipsome then
+ sequence.skiphash=setmetatableindex(function(t,k)
+ local c=resources.classes[k]
+ local v=c==skipmark
+ or (markclass and c=="mark" and not markclass[k])
+ or c==skipligature
+ or c==skipbase
+ or false
+ t[k]=v
+ return v
+ end)
+ else
+ sequence.skiphash=false
+ end
+ else
+ sequence.skiphash=false
+ end
+ end
+end
+local function checksteps(sequence)
+ local steps=sequence.steps
+ if steps then
+ for i=1,#steps do
+ steps[i].index=i
+ end
+ end
+end
+if fonts.helpers then
+ fonts.helpers.checkmerge=checkmerge
+ fonts.helpers.checkflags=checkflags
+ fonts.helpers.checksteps=checksteps
+end
+function readers.expand(data)
+ if not data or data.expanded then
+ return
+ else
+ data.expanded=true
+ end
+ local resources=data.resources
+ local sublookups=resources.sublookups
+ local sequences=resources.sequences
+ local markclasses=resources.markclasses
+ local descriptions=data.descriptions
+ if descriptions then
+ local defaultwidth=resources.defaultwidth or 0
+ local defaultheight=resources.defaultheight or 0
+ local defaultdepth=resources.defaultdepth or 0
+ local basename=trace_markwidth and file.basename(resources.filename)
+ for u,d in next,descriptions do
+ local bb=d.boundingbox
+ local wd=d.width
+ if not wd then
+ d.width=defaultwidth
+ elseif trace_markwidth and wd~=0 and d.class=="mark" then
+ report_markwidth("mark %a with width %b found in %a",d.name or "<noname>",wd,basename)
+ end
+ if bb then
+ local ht=bb[4]
+ local dp=-bb[2]
+ if ht==0 or ht<0 then
+ else
+ d.height=ht
+ end
+ if dp==0 or dp<0 then
+ else
+ d.depth=dp
+ end
+ end
+ end
+ end
+ local function expandlookups(sequences)
+ if sequences then
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ if steps then
+ local nofsteps=sequence.nofsteps
+ local kind=sequence.type
+ local markclass=sequence.markclass
+ if markclass then
+ if not markclasses then
+ report_warning("missing markclasses")
+ sequence.markclass=false
+ else
+ sequence.markclass=markclasses[markclass]
+ end
+ end
+ for i=1,nofsteps do
+ local step=steps[i]
+ local baseclasses=step.baseclasses
+ if baseclasses then
+ local coverage=step.coverage
+ for k,v in next,coverage do
+ v[1]=baseclasses[v[1]]
+ end
+ elseif kind=="gpos_cursive" then
+ local coverage=step.coverage
+ for k,v in next,coverage do
+ v[1]=coverage
+ end
+ end
+ local rules=step.rules
+ if rules then
+ local rulehash={ n=0 }
+ local rulesize=0
+ local coverage={}
+ local lookuptype=sequence.type
+ local nofrules=#rules
+ step.coverage=coverage
+ for currentrule=1,nofrules do
+ local rule=rules[currentrule]
+ local current=rule.current
+ local before=rule.before
+ local after=rule.after
+ local replacements=rule.replacements or false
+ local sequence={}
+ local nofsequences=0
+ if before then
+ for n=1,#before do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=before[n]
+ end
+ end
+ local start=nofsequences+1
+ for n=1,#current do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=current[n]
+ end
+ local stop=nofsequences
+ if after then
+ for n=1,#after do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=after[n]
+ end
+ end
+ local lookups=rule.lookups or false
+ local subtype=nil
+ if lookups then
+ 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
+ end
+ end
+ end
+ if sequence[1] then
+ sequence.n=#sequence
+ local ruledata={
+ currentrule,
+ lookuptype,
+ sequence,
+ start,
+ stop,
+ lookups,
+ replacements,
+ subtype,
+ }
+ rulesize=rulesize+1
+ rulehash[rulesize]=ruledata
+ rulehash.n=rulesize
+ if true then
+ for unic in next,sequence[start] do
+ local cu=coverage[unic]
+ if cu then
+ local n=#cu+1
+ cu[n]=ruledata
+ cu.n=n
+ else
+ coverage[unic]={ ruledata,n=1 }
+ end
+ end
+ else
+ for unic in next,sequence[start] do
+ local cu=coverage[unic]
+ if cu then
+ else
+ coverage[unic]=rulehash
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ checkmerge(sequence)
+ checkflags(sequence,resources)
+ checksteps(sequence)
+ end
+ end
+ end
+ end
+ expandlookups(sequences)
+ expandlookups(sublookups)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-otl']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
+}
+local lower=string.lower
+local type,next,tonumber,tostring,unpack=type,next,tonumber,tostring,unpack
+local abs=math.abs
+local derivetable=table.derive
+local formatters=string.formatters
+local setmetatableindex=table.setmetatableindex
+local allocate=utilities.storage.allocate
+local registertracker=trackers.register
+local registerdirective=directives.register
+local starttiming=statistics.starttiming
+local stoptiming=statistics.stoptiming
+local elapsedtime=statistics.elapsedtime
+local findbinfile=resolvers.findbinfile
+local trace_loading=false registertracker("otf.loading",function(v) trace_loading=v end)
+local trace_features=false registertracker("otf.features",function(v) trace_features=v end)
+local trace_defining=false registertracker("fonts.defining",function(v) trace_defining=v end)
+local report_otf=logs.reporter("fonts","otf loading")
+local fonts=fonts
+local otf=fonts.handlers.otf
+otf.version=3.109
+otf.cache=containers.define("fonts","otl",otf.version,true)
+otf.svgcache=containers.define("fonts","svg",otf.version,true)
+otf.pngcache=containers.define("fonts","png",otf.version,true)
+otf.pdfcache=containers.define("fonts","pdf",otf.version,true)
+otf.svgenabled=false
+otf.pngenabled=false
+local otfreaders=otf.readers
+local hashes=fonts.hashes
+local definers=fonts.definers
+local readers=fonts.readers
+local constructors=fonts.constructors
+local otffeatures=constructors.features.otf
+local registerotffeature=otffeatures.register
+local otfenhancers=constructors.enhancers.otf
+local registerotfenhancer=otfenhancers.register
+local forceload=false
+local cleanup=0
+local syncspace=true
+local forcenotdef=false
+local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes
+local wildcard="*"
+local default="dflt"
+local formats=fonts.formats
+formats.otf="opentype"
+formats.ttf="truetype"
+formats.ttc="truetype"
+registerdirective("fonts.otf.loader.cleanup",function(v) cleanup=tonumber(v) or (v and 1) or 0 end)
+registerdirective("fonts.otf.loader.force",function(v) forceload=v end)
+registerdirective("fonts.otf.loader.syncspace",function(v) syncspace=v end)
+registerdirective("fonts.otf.loader.forcenotdef",function(v) forcenotdef=v end)
+registerotfenhancer("check extra features",function() end)
+local checkmemory=utilities.lua and utilities.lua.checkmemory
+local threshold=100
+local tracememory=false
+registertracker("fonts.otf.loader.memory",function(v) tracememory=v end)
+if not checkmemory then
+ local collectgarbage=collectgarbage
+ checkmemory=function(previous,threshold)
+ local current=collectgarbage("count")
+ if previous then
+ local checked=(threshold or 64)*1024
+ if current-previous>checked then
+ collectgarbage("collect")
+ current=collectgarbage("count")
+ end
+ end
+ return current
+ end
+end
+function otf.load(filename,sub,instance)
+ local base=file.basename(file.removesuffix(filename))
+ local name=file.removesuffix(base)
+ local attr=lfs.attributes(filename)
+ local size=attr and attr.size or 0
+ local time=attr and attr.modification or 0
+ if sub=="" then
+ sub=false
+ end
+ local hash=name
+ if sub then
+ hash=hash.."-"..sub
+ end
+ if instance then
+ hash=hash.."-"..instance
+ end
+ hash=containers.cleanname(hash)
+ local data=containers.read(otf.cache,hash)
+ local reload=not data or data.size~=size or data.time~=time or data.tableversion~=otfreaders.tableversion
+ if forceload then
+ report_otf("forced reload of %a due to hard coded flag",filename)
+ reload=true
+ end
+ if reload then
+ report_otf("loading %a, hash %a",filename,hash)
+ starttiming(otfreaders,true)
+ data=otfreaders.loadfont(filename,sub or 1,instance)
+ if data then
+ local used=checkmemory()
+ local resources=data.resources
+ local svgshapes=resources.svgshapes
+ local pngshapes=resources.pngshapes
+ if cleanup==0 then
+ checkmemory(used,threshold,tracememory)
+ end
+ if svgshapes then
+ resources.svgshapes=nil
+ if otf.svgenabled then
+ local timestamp=os.date()
+ containers.write(otf.svgcache,hash,{
+ svgshapes=svgshapes,
+ timestamp=timestamp,
+ })
+ data.properties.svg={
+ hash=hash,
+ timestamp=timestamp,
+ }
+ end
+ if cleanup>1 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ end
+ if pngshapes then
+ resources.pngshapes=nil
+ if otf.pngenabled then
+ local timestamp=os.date()
+ containers.write(otf.pngcache,hash,{
+ pngshapes=pngshapes,
+ timestamp=timestamp,
+ })
+ data.properties.png={
+ hash=hash,
+ timestamp=timestamp,
+ }
+ end
+ if cleanup>1 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ end
+ otfreaders.compact(data)
+ if cleanup==0 then
+ checkmemory(used,threshold,tracememory)
+ end
+ otfreaders.rehash(data,"unicodes")
+ otfreaders.addunicodetable(data)
+ otfreaders.extend(data)
+ if cleanup==0 then
+ checkmemory(used,threshold,tracememory)
+ end
+ otfreaders.pack(data)
+ report_otf("loading done")
+ report_otf("saving %a in cache",filename)
+ data=containers.write(otf.cache,hash,data)
+ if cleanup>1 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ stoptiming(otfreaders)
+ if elapsedtime then
+ report_otf("loading, optimizing, packing and caching time %s",elapsedtime(otfreaders))
+ end
+ if cleanup>3 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ data=containers.read(otf.cache,hash)
+ if cleanup>2 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ else
+ stoptiming(otfreaders)
+ data=nil
+ report_otf("loading failed due to read error")
+ end
+ end
+ if data then
+ if trace_defining then
+ report_otf("loading from cache using hash %a",hash)
+ end
+ otfreaders.unpack(data)
+ otfreaders.expand(data)
+ otfreaders.addunicodetable(data)
+ otfenhancers.apply(data,filename,data)
+ if applyruntimefixes then
+ applyruntimefixes(filename,data)
+ end
+ data.metadata.math=data.resources.mathconstants
+ local classes=data.resources.classes
+ if not classes then
+ local descriptions=data.descriptions
+ classes=setmetatableindex(function(t,k)
+ local d=descriptions[k]
+ local v=(d and d.class or "base") or false
+ t[k]=v
+ return v
+ end)
+ data.resources.classes=classes
+ end
+ end
+ return data
+end
+function otf.setfeatures(tfmdata,features)
+ local okay=constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf)
+ if okay then
+ return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf)
+ else
+ return {}
+ end
+end
+local function copytotfm(data,cache_id)
+ if data then
+ local metadata=data.metadata
+ local properties=derivetable(data.properties)
+ local descriptions=derivetable(data.descriptions)
+ local goodies=derivetable(data.goodies)
+ local characters={}
+ local parameters={}
+ local mathparameters={}
+ local resources=data.resources
+ local unicodes=resources.unicodes
+ local spaceunits=500
+ local spacer="space"
+ local designsize=metadata.designsize or 100
+ local minsize=metadata.minsize or designsize
+ local maxsize=metadata.maxsize or designsize
+ local mathspecs=metadata.math
+ if designsize==0 then
+ designsize=100
+ minsize=100
+ maxsize=100
+ end
+ if mathspecs then
+ for name,value in next,mathspecs do
+ mathparameters[name]=value
+ end
+ end
+ for unicode in next,data.descriptions do
+ characters[unicode]={}
+ end
+ if mathspecs then
+ for unicode,character in next,characters do
+ local d=descriptions[unicode]
+ local m=d.math
+ if m then
+ local italic=m.italic
+ local vitalic=m.vitalic
+ local variants=m.hvariants
+ local parts=m.hparts
+ if variants then
+ local c=character
+ for i=1,#variants do
+ local un=variants[i]
+ c.next=un
+ c=characters[un]
+ end
+ c.horiz_variants=parts
+ elseif parts then
+ character.horiz_variants=parts
+ italic=m.hitalic
+ end
+ local variants=m.vvariants
+ local parts=m.vparts
+ if variants then
+ local c=character
+ for i=1,#variants do
+ local un=variants[i]
+ c.next=un
+ c=characters[un]
+ end
+ c.vert_variants=parts
+ elseif parts then
+ character.vert_variants=parts
+ end
+ if italic and italic~=0 then
+ character.italic=italic
+ end
+ if vitalic and vitalic~=0 then
+ character.vert_italic=vitalic
+ end
+ local accent=m.accent
+ if accent then
+ character.accent=accent
+ end
+ local kerns=m.kerns
+ if kerns then
+ character.mathkerns=kerns
+ end
+ end
+ end
+ end
+ local filename=constructors.checkedfilename(resources)
+ local fontname=metadata.fontname
+ local fullname=metadata.fullname or fontname
+ local psname=fontname or fullname
+ local subfont=metadata.subfontindex
+ local units=metadata.units or 1000
+ if units==0 then
+ units=1000
+ metadata.units=1000
+ report_otf("changing %a units to %a",0,units)
+ end
+ local monospaced=metadata.monospaced
+ local charwidth=metadata.averagewidth
+ local charxheight=metadata.xheight
+ local italicangle=metadata.italicangle
+ local hasitalics=metadata.hasitalics
+ properties.monospaced=monospaced
+ properties.hasitalics=hasitalics
+ parameters.italicangle=italicangle
+ parameters.charwidth=charwidth
+ parameters.charxheight=charxheight
+ local space=0x0020
+ local emdash=0x2014
+ if monospaced then
+ if descriptions[space] then
+ spaceunits,spacer=descriptions[space].width,"space"
+ end
+ if not spaceunits and descriptions[emdash] then
+ spaceunits,spacer=descriptions[emdash].width,"emdash"
+ end
+ if not spaceunits and charwidth then
+ spaceunits,spacer=charwidth,"charwidth"
+ end
+ else
+ if descriptions[space] then
+ spaceunits,spacer=descriptions[space].width,"space"
+ end
+ if not spaceunits and descriptions[emdash] then
+ spaceunits,spacer=descriptions[emdash].width/2,"emdash/2"
+ end
+ if not spaceunits and charwidth then
+ spaceunits,spacer=charwidth,"charwidth"
+ end
+ end
+ spaceunits=tonumber(spaceunits) or units/2
+ parameters.slant=0
+ parameters.space=spaceunits
+ parameters.space_stretch=1*units/2
+ parameters.space_shrink=1*units/3
+ parameters.x_height=2*units/5
+ parameters.quad=units
+ if spaceunits<2*units/5 then
+ end
+ if italicangle and italicangle~=0 then
+ parameters.italicangle=italicangle
+ parameters.italicfactor=math.cos(math.rad(90+italicangle))
+ parameters.slant=- math.tan(italicangle*math.pi/180)
+ end
+ if monospaced then
+ parameters.space_stretch=0
+ parameters.space_shrink=0
+ elseif syncspace then
+ parameters.space_stretch=spaceunits/2
+ parameters.space_shrink=spaceunits/3
+ end
+ parameters.extra_space=parameters.space_shrink
+ if charxheight then
+ parameters.x_height=charxheight
+ else
+ local x=0x0078
+ if x then
+ local x=descriptions[x]
+ if x then
+ parameters.x_height=x.height
+ end
+ end
+ end
+ parameters.designsize=(designsize/10)*65536
+ parameters.minsize=(minsize/10)*65536
+ parameters.maxsize=(maxsize/10)*65536
+ parameters.ascender=abs(metadata.ascender or 0)
+ parameters.descender=abs(metadata.descender or 0)
+ parameters.units=units
+ parameters.vheight=metadata.defaultvheight
+ properties.space=spacer
+ properties.encodingbytes=2
+ properties.format=data.format or formats.otf
+ properties.filename=filename
+ properties.fontname=fontname
+ properties.fullname=fullname
+ properties.psname=psname
+ properties.name=filename or fullname
+ properties.subfont=subfont
+ properties.private=properties.private or data.private or privateoffset
+ return {
+ characters=characters,
+ descriptions=descriptions,
+ parameters=parameters,
+ mathparameters=mathparameters,
+ resources=resources,
+ properties=properties,
+ goodies=goodies,
+ }
+ end
+end
+local converters={
+ woff={
+ cachename="webfonts",
+ action=otf.readers.woff2otf,
+ }
+}
+local function checkconversion(specification)
+ local filename=specification.filename
+ local converter=converters[lower(file.suffix(filename))]
+ if converter then
+ local base=file.basename(filename)
+ local name=file.removesuffix(base)
+ local attr=lfs.attributes(filename)
+ local size=attr and attr.size or 0
+ local time=attr and attr.modification or 0
+ if size>0 then
+ local cleanname=containers.cleanname(name)
+ local cachename=caches.setfirstwritablefile(cleanname,converter.cachename)
+ if not io.exists(cachename) or (time~=lfs.attributes(cachename).modification) then
+ report_otf("caching font %a in %a",filename,cachename)
+ converter.action(filename,cachename)
+ lfs.touch(cachename,time,time)
+ end
+ specification.filename=cachename
+ end
+ end
+end
+local function otftotfm(specification)
+ local cache_id=specification.hash
+ local tfmdata=containers.read(constructors.cache,cache_id)
+ if not tfmdata then
+ checkconversion(specification)
+ local name=specification.name
+ local sub=specification.sub
+ local subindex=specification.subindex
+ local filename=specification.filename
+ local features=specification.features.normal
+ local instance=specification.instance or (features and features.axis)
+ local rawdata=otf.load(filename,sub,instance)
+ if rawdata and next(rawdata) then
+ local descriptions=rawdata.descriptions
+ rawdata.lookuphash={}
+ tfmdata=copytotfm(rawdata,cache_id)
+ if tfmdata and next(tfmdata) then
+ local features=constructors.checkedfeatures("otf",features)
+ local shared=tfmdata.shared
+ if not shared then
+ shared={}
+ tfmdata.shared=shared
+ end
+ shared.rawdata=rawdata
+ shared.dynamics={}
+ tfmdata.changed={}
+ shared.features=features
+ shared.processes=otf.setfeatures(tfmdata,features)
+ end
+ end
+ containers.write(constructors.cache,cache_id,tfmdata)
+ end
+ return tfmdata
+end
+local function read_from_otf(specification)
+ local tfmdata=otftotfm(specification)
+ if tfmdata then
+ tfmdata.properties.name=specification.name
+ tfmdata.properties.sub=specification.sub
+ tfmdata=constructors.scale(tfmdata,specification)
+ local allfeatures=tfmdata.shared.features or specification.features.normal
+ constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf)
+ constructors.setname(tfmdata,specification)
+ fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification)
+ end
+ return tfmdata
+end
+local function checkmathsize(tfmdata,mathsize)
+ local mathdata=tfmdata.shared.rawdata.metadata.math
+ local mathsize=tonumber(mathsize)
+ if mathdata then
+ local parameters=tfmdata.parameters
+ parameters.scriptpercentage=mathdata.ScriptPercentScaleDown
+ parameters.scriptscriptpercentage=mathdata.ScriptScriptPercentScaleDown
+ parameters.mathsize=mathsize
+ end
+end
+registerotffeature {
+ name="mathsize",
+ description="apply mathsize specified in the font",
+ initializers={
+ base=checkmathsize,
+ node=checkmathsize,
+ }
+}
+function otf.collectlookups(rawdata,kind,script,language)
+ if not kind then
+ return
+ end
+ if not script then
+ script=default
+ end
+ if not language then
+ language=default
+ end
+ local lookupcache=rawdata.lookupcache
+ if not lookupcache then
+ lookupcache={}
+ rawdata.lookupcache=lookupcache
+ end
+ local kindlookup=lookupcache[kind]
+ if not kindlookup then
+ kindlookup={}
+ lookupcache[kind]=kindlookup
+ end
+ local scriptlookup=kindlookup[script]
+ if not scriptlookup then
+ scriptlookup={}
+ kindlookup[script]=scriptlookup
+ end
+ local languagelookup=scriptlookup[language]
+ if not languagelookup then
+ local sequences=rawdata.resources.sequences
+ local featuremap={}
+ local featurelist={}
+ if sequences then
+ for s=1,#sequences do
+ local sequence=sequences[s]
+ local features=sequence.features
+ if features then
+ features=features[kind]
+ if features then
+ features=features[script] or features[wildcard]
+ if features then
+ features=features[language] or features[wildcard]
+ if features then
+ if not featuremap[sequence] then
+ featuremap[sequence]=true
+ featurelist[#featurelist+1]=sequence
+ end
+ end
+ end
+ end
+ end
+ end
+ if #featurelist==0 then
+ featuremap,featurelist=false,false
+ end
+ else
+ featuremap,featurelist=false,false
+ end
+ languagelookup={ featuremap,featurelist }
+ scriptlookup[language]=languagelookup
+ end
+ return unpack(languagelookup)
+end
+local function getgsub(tfmdata,k,kind,value)
+ local shared=tfmdata.shared
+ local rawdata=shared and shared.rawdata
+ if rawdata then
+ local sequences=rawdata.resources.sequences
+ if sequences then
+ local properties=tfmdata.properties
+ local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language)
+ if validlookups then
+ for i=1,#lookuplist do
+ local lookup=lookuplist[i]
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ for i=1,nofsteps do
+ local coverage=steps[i].coverage
+ if coverage then
+ local found=coverage[k]
+ if found then
+ return found,lookup.type
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+otf.getgsub=getgsub
+function otf.getsubstitution(tfmdata,k,kind,value)
+ local found,kind=getgsub(tfmdata,k,kind,value)
+ if not found then
+ elseif kind=="gsub_single" then
+ return found
+ elseif kind=="gsub_alternate" then
+ local choice=tonumber(value) or 1
+ return found[choice] or found[1] or k
+ end
+ return k
+end
+otf.getalternate=otf.getsubstitution
+function otf.getmultiple(tfmdata,k,kind)
+ local found,kind=getgsub(tfmdata,k,kind)
+ if found and kind=="gsub_multiple" then
+ return found
+ end
+ return { k }
+end
+function otf.getkern(tfmdata,left,right,kind)
+ local kerns=getgsub(tfmdata,left,kind or "kern",true)
+ if kerns then
+ local found=kerns[right]
+ local kind=type(found)
+ if kind=="table" then
+ found=found[1][3]
+ elseif kind~="number" then
+ found=false
+ end
+ if found then
+ return found*tfmdata.parameters.factor
+ end
+ end
+ return 0
+end
+local function check_otf(forced,specification,suffix)
+ local name=specification.name
+ if forced then
+ name=specification.forcedname
+ end
+ local fullname=findbinfile(name,suffix) or ""
+ if fullname=="" then
+ fullname=fonts.names.getfilename(name,suffix) or ""
+ end
+ if fullname~="" and not fonts.names.ignoredfile(fullname) then
+ specification.filename=fullname
+ return read_from_otf(specification)
+ end
+end
+local function opentypereader(specification,suffix)
+ local forced=specification.forced or ""
+ if formats[forced] then
+ return check_otf(true,specification,forced)
+ else
+ return check_otf(false,specification,suffix)
+ end
+end
+readers.opentype=opentypereader
+function readers.otf(specification) return opentypereader(specification,"otf") end
+function readers.ttf(specification) return opentypereader(specification,"ttf") end
+function readers.ttc(specification) return opentypereader(specification,"ttf") end
+function readers.woff(specification)
+ checkconversion(specification)
+ opentypereader(specification,"")
+end
+function otf.scriptandlanguage(tfmdata,attr)
+ local properties=tfmdata.properties
+ return properties.script or "dflt",properties.language or "dflt"
+end
+local function justset(coverage,unicode,replacement)
+ coverage[unicode]=replacement
+end
+otf.coverup={
+ stepkey="steps",
+ actions={
+ chainsubstitution=justset,
+ chainposition=justset,
+ substitution=justset,
+ alternate=justset,
+ multiple=justset,
+ kern=justset,
+ pair=justset,
+ single=justset,
+ ligature=function(coverage,unicode,ligature)
+ local first=ligature[1]
+ local tree=coverage[first]
+ if not tree then
+ tree={}
+ coverage[first]=tree
+ end
+ for i=2,#ligature do
+ local l=ligature[i]
+ local t=tree[l]
+ if not t then
+ t={}
+ tree[l]=t
+ end
+ tree=t
+ end
+ tree.ligature=unicode
+ end,
+ },
+ register=function(coverage,featuretype,format)
+ return {
+ format=format,
+ coverage=coverage,
+ }
+ end
+}
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-oto']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local concat,unpack=table.concat,table.unpack
+local insert,remove=table.insert,table.remove
+local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip
+local type,next,tonumber,tostring,rawget=type,next,tonumber,tostring,rawget
+local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end)
+local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end)
+local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end)
+local trace_alternatives=false trackers.register("otf.alternatives",function(v) trace_alternatives=v end)
+local trace_ligatures=false trackers.register("otf.ligatures",function(v) trace_ligatures=v end)
+local trace_kerns=false trackers.register("otf.kerns",function(v) trace_kerns=v end)
+local trace_preparing=false trackers.register("otf.preparing",function(v) trace_preparing=v end)
+local report_prepare=logs.reporter("fonts","otf prepare")
+local fonts=fonts
+local otf=fonts.handlers.otf
+local otffeatures=otf.features
+local registerotffeature=otffeatures.register
+otf.defaultbasealternate="none"
+local getprivate=fonts.constructors.getprivate
+local wildcard="*"
+local default="dflt"
+local formatters=string.formatters
+local f_unicode=formatters["%U"]
+local f_uniname=formatters["%U (%s)"]
+local f_unilist=formatters["% t (% t)"]
+local function gref(descriptions,n)
+ if type(n)=="number" then
+ local name=descriptions[n].name
+ if name then
+ return f_uniname(n,name)
+ else
+ return f_unicode(n)
+ end
+ elseif n then
+ local num={}
+ local nam={}
+ local j=0
+ for i=1,#n do
+ local ni=n[i]
+ if tonumber(ni) then
+ j=j+1
+ local di=descriptions[ni]
+ num[j]=f_unicode(ni)
+ nam[j]=di and di.name or "-"
+ end
+ end
+ return f_unilist(num,nam)
+ else
+ return "<error in base mode tracing>"
+ end
+end
+local function cref(feature,sequence)
+ return formatters["feature %a, type %a, chain lookup %a"](feature,sequence.type,sequence.name)
+end
+local function report_substitution(feature,sequence,descriptions,unicode,substitution)
+ if unicode==substitution then
+ report_prepare("%s: base substitution %s maps onto itself",
+ cref(feature,sequence),
+ gref(descriptions,unicode))
+ else
+ report_prepare("%s: base substitution %s => %S",
+ cref(feature,sequence),
+ gref(descriptions,unicode),
+ gref(descriptions,substitution))
+ end
+end
+local function report_alternate(feature,sequence,descriptions,unicode,replacement,value,comment)
+ if unicode==replacement then
+ report_prepare("%s: base alternate %s maps onto itself",
+ cref(feature,sequence),
+ gref(descriptions,unicode))
+ else
+ report_prepare("%s: base alternate %s => %s (%S => %S)",
+ cref(feature,sequence),
+ gref(descriptions,unicode),
+ replacement and gref(descriptions,replacement),
+ value,
+ comment)
+ end
+end
+local function report_ligature(feature,sequence,descriptions,unicode,ligature)
+ report_prepare("%s: base ligature %s => %S",
+ cref(feature,sequence),
+ gref(descriptions,ligature),
+ gref(descriptions,unicode))
+end
+local function report_kern(feature,sequence,descriptions,unicode,otherunicode,value)
+ report_prepare("%s: base kern %s + %s => %S",
+ cref(feature,sequence),
+ gref(descriptions,unicode),
+ gref(descriptions,otherunicode),
+ value)
+end
+local basehash,basehashes,applied={},1,{}
+local function registerbasehash(tfmdata)
+ local properties=tfmdata.properties
+ local hash=concat(applied," ")
+ local base=basehash[hash]
+ if not base then
+ basehashes=basehashes+1
+ base=basehashes
+ basehash[hash]=base
+ end
+ properties.basehash=base
+ properties.fullname=(properties.fullname or properties.name).."-"..base
+ applied={}
+end
+local function registerbasefeature(feature,value)
+ applied[#applied+1]=feature.."="..tostring(value)
+end
+local function makefake(tfmdata,name,present)
+ local private=getprivate(tfmdata)
+ local character={ intermediate=true,ligatures={} }
+ resources.unicodes[name]=private
+ tfmdata.characters[private]=character
+ tfmdata.descriptions[private]={ name=name }
+ present[name]=private
+ return character
+end
+local function make_1(present,tree,name)
+ for k,v in next,tree do
+ if k=="ligature" then
+ present[name]=v
+ else
+ make_1(present,v,name.."_"..k)
+ end
+ end
+end
+local function make_2(present,tfmdata,characters,tree,name,preceding,unicode,done)
+ for k,v in next,tree do
+ if k=="ligature" then
+ local character=characters[preceding]
+ if not character then
+ if trace_baseinit then
+ report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding)
+ end
+ character=makefake(tfmdata,name,present)
+ end
+ local ligatures=character.ligatures
+ if ligatures then
+ ligatures[unicode]={ char=v }
+ else
+ character.ligatures={ [unicode]={ char=v } }
+ end
+ if done then
+ local d=done[name]
+ if not d then
+ done[name]={ "dummy",v }
+ else
+ d[#d+1]=v
+ end
+ end
+ else
+ local code=present[name] or unicode
+ local name=name.."_"..k
+ make_2(present,tfmdata,characters,v,name,code,k,done)
+ end
+ end
+end
+local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist)
+ local characters=tfmdata.characters
+ local descriptions=tfmdata.descriptions
+ local resources=tfmdata.resources
+ local changed=tfmdata.changed
+ local ligatures={}
+ local alternate=tonumber(value) or true and 1
+ local defaultalt=otf.defaultbasealternate
+ local trace_singles=trace_baseinit and trace_singles
+ local trace_alternatives=trace_baseinit and trace_alternatives
+ local trace_ligatures=trace_baseinit and trace_ligatures
+ if not changed then
+ changed={}
+ tfmdata.changed=changed
+ end
+ for i=1,#lookuplist do
+ local sequence=lookuplist[i]
+ local steps=sequence.steps
+ local kind=sequence.type
+ if kind=="gsub_single" then
+ for i=1,#steps do
+ for unicode,data in next,steps[i].coverage do
+ if unicode~=data then
+ changed[unicode]=data
+ end
+ if trace_singles then
+ report_substitution(feature,sequence,descriptions,unicode,data)
+ end
+ end
+ end
+ elseif kind=="gsub_alternate" then
+ for i=1,#steps do
+ for unicode,data in next,steps[i].coverage do
+ local replacement=data[alternate]
+ if replacement then
+ if unicode~=replacement then
+ changed[unicode]=replacement
+ end
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal")
+ end
+ elseif defaultalt=="first" then
+ replacement=data[1]
+ if unicode~=replacement then
+ changed[unicode]=replacement
+ end
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
+ end
+ elseif defaultalt=="last" then
+ replacement=data[#data]
+ if unicode~=replacement then
+ changed[unicode]=replacement
+ end
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
+ end
+ else
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,"unknown")
+ end
+ end
+ end
+ end
+ elseif kind=="gsub_ligature" then
+ for i=1,#steps do
+ for unicode,data in next,steps[i].coverage do
+ ligatures[#ligatures+1]={ unicode,data,"" }
+ if trace_ligatures then
+ report_ligature(feature,sequence,descriptions,unicode,data)
+ end
+ end
+ end
+ end
+ end
+ local nofligatures=#ligatures
+ if nofligatures>0 then
+ local characters=tfmdata.characters
+ local present={}
+ local done=trace_baseinit and trace_ligatures and {}
+ for i=1,nofligatures do
+ local ligature=ligatures[i]
+ local unicode=ligature[1]
+ local tree=ligature[2]
+ make_1(present,tree,"ctx_"..unicode)
+ end
+ for i=1,nofligatures do
+ local ligature=ligatures[i]
+ local unicode=ligature[1]
+ local tree=ligature[2]
+ local lookupname=ligature[3]
+ make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence)
+ end
+ end
+end
+local function preparepositionings(tfmdata,feature,value,validlookups,lookuplist)
+ local characters=tfmdata.characters
+ local descriptions=tfmdata.descriptions
+ local resources=tfmdata.resources
+ local properties=tfmdata.properties
+ local traceindeed=trace_baseinit and trace_kerns
+ for i=1,#lookuplist do
+ local sequence=lookuplist[i]
+ local steps=sequence.steps
+ local kind=sequence.type
+ local format=sequence.format
+ if kind=="gpos_pair" then
+ for i=1,#steps do
+ local step=steps[i]
+ local format=step.format
+ if format=="kern" or format=="move" then
+ for unicode,data in next,steps[i].coverage do
+ local character=characters[unicode]
+ local kerns=character.kerns
+ if not kerns then
+ kerns={}
+ character.kerns=kerns
+ end
+ if traceindeed then
+ for otherunicode,kern in next,data do
+ if not kerns[otherunicode] and kern~=0 then
+ kerns[otherunicode]=kern
+ report_kern(feature,sequence,descriptions,unicode,otherunicode,kern)
+ end
+ end
+ else
+ for otherunicode,kern in next,data do
+ if not kerns[otherunicode] and kern~=0 then
+ kerns[otherunicode]=kern
+ end
+ end
+ end
+ end
+ else
+ for unicode,data in next,steps[i].coverage do
+ local character=characters[unicode]
+ local kerns=character.kerns
+ for otherunicode,kern in next,data do
+ local other=kern[2]
+ if other==true or (not other and not (kerns and kerns[otherunicode])) then
+ local kern=kern[1]
+ if kern==true then
+ elseif kern[1]~=0 or kern[2]~=0 or kern[4]~=0 then
+ else
+ kern=kern[3]
+ if kern~=0 then
+ if kerns then
+ kerns[otherunicode]=kern
+ else
+ kerns={ [otherunicode]=kern }
+ character.kerns=kerns
+ end
+ if traceindeed then
+ report_kern(feature,sequence,descriptions,unicode,otherunicode,kern)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+local function initializehashes(tfmdata)
+end
+local function checkmathreplacements(tfmdata,fullname,fixitalics)
+ if tfmdata.mathparameters then
+ local characters=tfmdata.characters
+ local changed=tfmdata.changed
+ if next(changed) then
+ if trace_preparing or trace_baseinit then
+ report_prepare("checking math replacements for %a",fullname)
+ end
+ for unicode,replacement in next,changed do
+ local u=characters[unicode]
+ local r=characters[replacement]
+ if u and r then
+ local n=u.next
+ local v=u.vert_variants
+ local h=u.horiz_variants
+ if fixitalics then
+ local ui=u.italic
+ if ui and not r.italic then
+ if trace_preparing then
+ report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement)
+ end
+ r.italic=ui
+ end
+ end
+ if n and not r.next then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement)
+ end
+ r.next=n
+ end
+ if v and not r.vert_variants then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement)
+ end
+ r.vert_variants=v
+ end
+ if h and not r.horiz_variants then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement)
+ end
+ r.horiz_variants=h
+ end
+ else
+ if trace_preparing then
+ report_prepare("error replacing %C by %U",unicode,replacement)
+ end
+ end
+ end
+ end
+ end
+end
+local function featuresinitializer(tfmdata,value)
+ if true then
+ local starttime=trace_preparing and os.clock()
+ local features=tfmdata.shared.features
+ local fullname=tfmdata.properties.fullname or "?"
+ if features then
+ initializehashes(tfmdata)
+ local collectlookups=otf.collectlookups
+ local rawdata=tfmdata.shared.rawdata
+ local properties=tfmdata.properties
+ local script=properties.script
+ local language=properties.language
+ local rawresources=rawdata.resources
+ local rawfeatures=rawresources and rawresources.features
+ local basesubstitutions=rawfeatures and rawfeatures.gsub
+ local basepositionings=rawfeatures and rawfeatures.gpos
+ local substitutionsdone=false
+ local positioningsdone=false
+ if basesubstitutions or basepositionings then
+ local sequences=tfmdata.resources.sequences
+ for s=1,#sequences do
+ local sequence=sequences[s]
+ local sfeatures=sequence.features
+ if sfeatures then
+ local order=sequence.order
+ if order then
+ for i=1,#order do
+ local feature=order[i]
+ local value=features[feature]
+ if value then
+ local validlookups,lookuplist=collectlookups(rawdata,feature,script,language)
+ if not validlookups then
+ elseif basesubstitutions and basesubstitutions[feature] then
+ if trace_preparing then
+ report_prepare("filtering base %s feature %a for %a with value %a","sub",feature,fullname,value)
+ end
+ preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist)
+ registerbasefeature(feature,value)
+ substitutionsdone=true
+ elseif basepositionings and basepositionings[feature] then
+ if trace_preparing then
+ report_prepare("filtering base %a feature %a for %a with value %a","pos",feature,fullname,value)
+ end
+ preparepositionings(tfmdata,feature,value,validlookups,lookuplist)
+ registerbasefeature(feature,value)
+ positioningsdone=true
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if substitutionsdone then
+ checkmathreplacements(tfmdata,fullname,features.fixitalics)
+ end
+ registerbasehash(tfmdata)
+ end
+ if trace_preparing then
+ report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname)
+ end
+ end
+end
+registerotffeature {
+ name="features",
+ description="features",
+ default=true,
+ initializers={
+ base=featuresinitializer,
+ }
+}
+otf.basemodeinitializer=featuresinitializer
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-otj']={
+ version=1.001,
+ comment="companion to font-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
+}
+if not nodes.properties then return end
+local next,rawget,tonumber=next,rawget,tonumber
+local fastcopy=table.fastcopy
+local registertracker=trackers.register
+local registerdirective=directives.register
+local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end)
+local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end)
+local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end)
+local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end)
+local report_injections=logs.reporter("fonts","injections")
+local report_spaces=logs.reporter("fonts","spaces")
+local attributes,nodes,node=attributes,nodes,node
+fonts=fonts
+local hashes=fonts.hashes
+local fontdata=hashes.identifiers
+local fontmarks=hashes.marks
+nodes.injections=nodes.injections or {}
+local injections=nodes.injections
+local tracers=nodes.tracers
+local setcolor=tracers and tracers.colors.set
+local resetcolor=tracers and tracers.colors.reset
+local nodecodes=nodes.nodecodes
+local glyph_code=nodecodes.glyph
+local disc_code=nodecodes.disc
+local kern_code=nodecodes.kern
+local glue_code=nodecodes.glue
+local nuts=nodes.nuts
+local nodepool=nuts.pool
+local tonode=nuts.tonode
+local tonut=nuts.tonut
+local setfield=nuts.setfield
+local getnext=nuts.getnext
+local getprev=nuts.getprev
+local getid=nuts.getid
+local getfont=nuts.getfont
+local getchar=nuts.getchar
+local getoffsets=nuts.getoffsets
+local getboth=nuts.getboth
+local getdisc=nuts.getdisc
+local setdisc=nuts.setdisc
+local setoffsets=nuts.setoffsets
+local ischar=nuts.ischar
+local getkern=nuts.getkern
+local setkern=nuts.setkern
+local setlink=nuts.setlink
+local setwidth=nuts.setwidth
+local getwidth=nuts.getwidth
+local nextchar=nuts.traversers.char
+local nextglue=nuts.traversers.glue
+local insert_node_before=nuts.insert_before
+local insert_node_after=nuts.insert_after
+local properties=nodes.properties.data
+local fontkern=nuts.pool and nuts.pool.fontkern
+local italickern=nuts.pool and nuts.pool.italickern
+local useitalickerns=false
+directives.register("fonts.injections.useitalics",function(v)
+ if v then
+ report_injections("using italics for space kerns (tracing only)")
+ end
+ useitalickerns=v
+end)
+do if not fontkern then
+ local thekern=nuts.new("kern",0)
+ local setkern=nuts.setkern
+ local copy_node=nuts.copy_node
+ fontkern=function(k)
+ local n=copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
+end end
+do if not italickern then
+ local thekern=nuts.new("kern",3)
+ local setkern=nuts.setkern
+ local copy_node=nuts.copy_node
+ italickern=function(k)
+ local n=copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
+end end
+function injections.installnewkern() end
+local nofregisteredkerns=0
+local nofregisteredpositions=0
+local nofregisteredmarks=0
+local nofregisteredcursives=0
+local keepregisteredcounts=false
+function injections.keepcounts()
+ keepregisteredcounts=true
+end
+function injections.resetcounts()
+ nofregisteredkerns=0
+ nofregisteredpositions=0
+ nofregisteredmarks=0
+ nofregisteredcursives=0
+ keepregisteredcounts=false
+end
+function injections.reset(n)
+ local p=rawget(properties,n)
+ if p then
+ p.injections=false
+ else
+ properties[n]=false
+ end
+end
+function injections.copy(target,source)
+ local sp=rawget(properties,source)
+ if sp then
+ local tp=rawget(properties,target)
+ local si=sp.injections
+ if si then
+ si=fastcopy(si)
+ if tp then
+ tp.injections=si
+ else
+ properties[target]={
+ injections=si,
+ }
+ end
+ elseif tp then
+ tp.injections=false
+ else
+ properties[target]={ injections={} }
+ end
+ else
+ local tp=rawget(properties,target)
+ if tp then
+ tp.injections=false
+ else
+ properties[target]=false
+ end
+ end
+end
+function injections.setligaindex(n,index)
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections
+ if i then
+ i.ligaindex=index
+ else
+ p.injections={
+ ligaindex=index
+ }
+ end
+ else
+ properties[n]={
+ injections={
+ ligaindex=index
+ }
+ }
+ end
+end
+function injections.getligaindex(n,default)
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections
+ if i then
+ return i.ligaindex or default
+ end
+ end
+ return default
+end
+function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext,r2lflag)
+ local dx=factor*(exit[1]-entry[1])
+ local dy=-factor*(exit[2]-entry[2])
+ local ws=tfmstart.width
+ local wn=tfmnext.width
+ nofregisteredcursives=nofregisteredcursives+1
+ if rlmode<0 then
+ dx=-(dx+wn)
+ else
+ dx=dx-ws
+ end
+ if dx==0 then
+ dx=0
+ end
+ local p=rawget(properties,start)
+ if p then
+ local i=p.injections
+ if i then
+ i.cursiveanchor=true
+ else
+ p.injections={
+ cursiveanchor=true,
+ }
+ end
+ else
+ properties[start]={
+ injections={
+ cursiveanchor=true,
+ },
+ }
+ end
+ local p=rawget(properties,nxt)
+ if p then
+ local i=p.injections
+ if i then
+ i.cursivex=dx
+ i.cursivey=dy
+ else
+ p.injections={
+ cursivex=dx,
+ cursivey=dy,
+ }
+ end
+ else
+ properties[nxt]={
+ injections={
+ cursivex=dx,
+ cursivey=dy,
+ },
+ }
+ end
+ return dx,dy,nofregisteredcursives
+end
+function injections.setposition(kind,current,factor,rlmode,spec,injection)
+ local x=factor*(spec[1] or 0)
+ local y=factor*(spec[2] or 0)
+ local w=factor*(spec[3] or 0)
+ local h=factor*(spec[4] or 0)
+ if x~=0 or w~=0 or y~=0 or h~=0 then
+ local yoffset=y-h
+ local leftkern=x
+ local rightkern=w-x
+ if leftkern~=0 or rightkern~=0 or yoffset~=0 then
+ nofregisteredpositions=nofregisteredpositions+1
+ if rlmode and rlmode<0 then
+ leftkern,rightkern=rightkern,leftkern
+ end
+ if not injection then
+ injection="injections"
+ end
+ local p=rawget(properties,current)
+ if p then
+ local i=p[injection]
+ if i then
+ if leftkern~=0 then
+ i.leftkern=(i.leftkern or 0)+leftkern
+ end
+ if rightkern~=0 then
+ i.rightkern=(i.rightkern or 0)+rightkern
+ end
+ if yoffset~=0 then
+ i.yoffset=(i.yoffset or 0)+yoffset
+ end
+ elseif leftkern~=0 or rightkern~=0 then
+ p[injection]={
+ leftkern=leftkern,
+ rightkern=rightkern,
+ yoffset=yoffset,
+ }
+ else
+ p[injection]={
+ yoffset=yoffset,
+ }
+ end
+ elseif leftkern~=0 or rightkern~=0 then
+ properties[current]={
+ [injection]={
+ leftkern=leftkern,
+ rightkern=rightkern,
+ yoffset=yoffset,
+ },
+ }
+ else
+ properties[current]={
+ [injection]={
+ yoffset=yoffset,
+ },
+ }
+ end
+ return x,y,w,h,nofregisteredpositions
+ end
+ end
+ return x,y,w,h
+end
+function injections.setkern(current,factor,rlmode,x,injection)
+ local dx=factor*x
+ if dx~=0 then
+ nofregisteredkerns=nofregisteredkerns+1
+ local p=rawget(properties,current)
+ if not injection then
+ injection="injections"
+ end
+ if p then
+ local i=p[injection]
+ if i then
+ i.leftkern=dx+(i.leftkern or 0)
+ else
+ p[injection]={
+ leftkern=dx,
+ }
+ end
+ else
+ properties[current]={
+ [injection]={
+ leftkern=dx,
+ },
+ }
+ end
+ return dx,nofregisteredkerns
+ else
+ return 0,0
+ end
+end
+function injections.setmove(current,factor,rlmode,x,injection)
+ local dx=factor*x
+ if dx~=0 then
+ nofregisteredkerns=nofregisteredkerns+1
+ local p=rawget(properties,current)
+ if not injection then
+ injection="injections"
+ end
+ if rlmode and rlmode<0 then
+ if p then
+ local i=p[injection]
+ if i then
+ i.rightkern=dx+(i.rightkern or 0)
+ else
+ p[injection]={
+ rightkern=dx,
+ }
+ end
+ else
+ properties[current]={
+ [injection]={
+ rightkern=dx,
+ },
+ }
+ end
+ else
+ if p then
+ local i=p[injection]
+ if i then
+ i.leftkern=dx+(i.leftkern or 0)
+ else
+ p[injection]={
+ leftkern=dx,
+ }
+ end
+ else
+ properties[current]={
+ [injection]={
+ leftkern=dx,
+ },
+ }
+ end
+ end
+ return dx,nofregisteredkerns
+ else
+ return 0,0
+ end
+end
+function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark)
+ local dx=factor*(ba[1]-ma[1])
+ local dy=factor*(ba[2]-ma[2])
+ nofregisteredmarks=nofregisteredmarks+1
+ if rlmode>=0 then
+ dx=tfmbase.width-dx
+ end
+ local p=rawget(properties,start)
+ if p then
+ local i=p.injections
+ if i then
+ if i.markmark then
+ else
+ i.markx=dx
+ i.marky=dy
+ i.markdir=rlmode or 0
+ i.markbase=nofregisteredmarks
+ i.markbasenode=base
+ i.markmark=mkmk
+ i.checkmark=checkmark
+ end
+ else
+ p.injections={
+ markx=dx,
+ marky=dy,
+ markdir=rlmode or 0,
+ markbase=nofregisteredmarks,
+ markbasenode=base,
+ markmark=mkmk,
+ checkmark=checkmark,
+ }
+ end
+ else
+ properties[start]={
+ injections={
+ markx=dx,
+ marky=dy,
+ markdir=rlmode or 0,
+ markbase=nofregisteredmarks,
+ markbasenode=base,
+ markmark=mkmk,
+ checkmark=checkmark,
+ },
+ }
+ end
+ return dx,dy,nofregisteredmarks
+end
+local function dir(n)
+ return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset"
+end
+local function showchar(n,nested)
+ local char=getchar(n)
+ report_injections("%wfont %s, char %U, glyph %c",nested and 2 or 0,getfont(n),char,char)
+end
+local function show(n,what,nested,symbol)
+ if n then
+ local p=rawget(properties,n)
+ if p then
+ local i=p[what]
+ if i then
+ local leftkern=i.leftkern or 0
+ local rightkern=i.rightkern or 0
+ local yoffset=i.yoffset or 0
+ local markx=i.markx or 0
+ local marky=i.marky or 0
+ local markdir=i.markdir or 0
+ local markbase=i.markbase or 0
+ local cursivex=i.cursivex or 0
+ local cursivey=i.cursivey or 0
+ local ligaindex=i.ligaindex or 0
+ local cursbase=i.cursiveanchor
+ local margin=nested and 4 or 2
+ if rightkern~=0 or yoffset~=0 then
+ report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset)
+ elseif leftkern~=0 then
+ report_injections("%w%s kern: dx %p",margin,symbol,leftkern)
+ end
+ if markx~=0 or marky~=0 or markbase~=0 then
+ report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase~=0 and "yes" or "no")
+ end
+ if cursivex~=0 or cursivey~=0 then
+ if cursbase then
+ report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ else
+ report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ end
+ elseif cursbase then
+ report_injections("%w%s curs: base",margin,symbol)
+ end
+ if ligaindex~=0 then
+ report_injections("%w%s liga: index %i",margin,symbol,ligaindex)
+ end
+ end
+ end
+ end
+end
+local function showsub(n,what,where)
+ report_injections("begin subrun: %s",where)
+ for n in nextchar,n do
+ showchar(n,where)
+ show(n,what,where," ")
+ end
+ report_injections("end subrun")
+end
+local function trace(head,where)
+ report_injections()
+ report_injections("begin run %s: %s kerns, %s positions, %s marks and %s cursives registered",
+ where or "",nofregisteredkerns,nofregisteredpositions,nofregisteredmarks,nofregisteredcursives)
+ local n=head
+ while n do
+ local id=getid(n)
+ if id==glyph_code then
+ showchar(n)
+ show(n,"injections",false," ")
+ show(n,"preinjections",false,"<")
+ show(n,"postinjections",false,">")
+ show(n,"replaceinjections",false,"=")
+ show(n,"emptyinjections",false,"*")
+ elseif id==disc_code then
+ local pre,post,replace=getdisc(n)
+ if pre then
+ showsub(pre,"preinjections","pre")
+ end
+ if post then
+ showsub(post,"postinjections","post")
+ end
+ if replace then
+ showsub(replace,"replaceinjections","replace")
+ end
+ show(n,"emptyinjections",false,"*")
+ end
+ n=getnext(n)
+ end
+ report_injections("end run")
+end
+local function show_result(head)
+ local current=head
+ local skipping=false
+ while current do
+ local id=getid(current)
+ if id==glyph_code then
+ local w=getwidth(current)
+ local x,y=getoffsets(current)
+ report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y)
+ skipping=false
+ elseif id==kern_code then
+ report_injections("kern: %p",getkern(current))
+ skipping=false
+ elseif not skipping then
+ report_injections()
+ skipping=true
+ end
+ current=getnext(current)
+ end
+ report_injections()
+end
+local function inject_kerns_only(head,where)
+ if trace_injections then
+ trace(head,"kerns")
+ end
+ local current=head
+ local prev=nil
+ local next=nil
+ local prevdisc=nil
+ local pre=nil
+ local post=nil
+ local replace=nil
+ local pretail=nil
+ local posttail=nil
+ local replacetail=nil
+ while current do
+ local next=getnext(current)
+ local char,id=ischar(current)
+ if char then
+ local p=rawget(properties,current)
+ if p then
+ local i=p.injections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ head=insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if prevdisc then
+ local done=false
+ if post then
+ local i=p.postinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(posttail,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ if replace then
+ local i=p.replaceinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(replacetail,fontkern(leftkern))
+ done=true
+ end
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=fontkern(leftkern)
+ done=true
+ end
+ end
+ end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
+ end
+ end
+ end
+ prevdisc=nil
+ elseif char==false then
+ prevdisc=nil
+ elseif id==disc_code then
+ pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
+ local done=false
+ if pre then
+ for n in nextchar,pre do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.preinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ pre=insert_node_before(pre,n,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if post then
+ for n in nextchar,post do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.postinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ post=insert_node_before(post,n,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if replace then
+ for n in nextchar,replace do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.replaceinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=insert_node_before(replace,n,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if done then
+ setdisc(current,pre,post,replace)
+ end
+ prevdisc=current
+ else
+ prevdisc=nil
+ end
+ prev=current
+ current=next
+ end
+ if keepregisteredcounts then
+ keepregisteredcounts=false
+ else
+ nofregisteredkerns=0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
+end
+local function inject_positions_only(head,where)
+ if trace_injections then
+ trace(head,"positions")
+ end
+ local current=head
+ local prev=nil
+ local next=nil
+ local prevdisc=nil
+ local prevglyph=nil
+ local pre=nil
+ local post=nil
+ local replace=nil
+ local pretail=nil
+ local posttail=nil
+ local replacetail=nil
+ while current do
+ local next=getnext(current)
+ local char,id=ischar(current)
+ if char then
+ local p=rawget(properties,current)
+ if p then
+ local i=p.injections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(current,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ local rightkern=i.rightkern
+ if leftkern and leftkern~=0 then
+ if rightkern and leftkern==-rightkern then
+ setoffsets(current,leftkern,false)
+ rightkern=0
+ else
+ head=insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if rightkern and rightkern~=0 then
+ insert_node_after(head,current,fontkern(rightkern))
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ if next and getid(next)==disc_code then
+ if replace then
+ else
+ replace=fontkern(rightkern)
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if prevdisc then
+ local done=false
+ if post then
+ local i=p.postinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(posttail,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ if replace then
+ local i=p.replaceinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(replacetail,fontkern(leftkern))
+ done=true
+ end
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=fontkern(leftkern)
+ done=true
+ end
+ end
+ end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
+ end
+ end
+ end
+ prevdisc=nil
+ prevglyph=current
+ elseif char==false then
+ prevdisc=nil
+ prevglyph=current
+ elseif id==disc_code then
+ pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
+ local done=false
+ if pre then
+ for n in nextchar,pre do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.preinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ pre=insert_node_before(pre,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(pre,n,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if post then
+ for n in nextchar,post do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.postinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ post=insert_node_before(post,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(post,n,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if replace then
+ for n in nextchar,replace do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.replaceinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=insert_node_before(replace,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(replace,n,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if prevglyph then
+ if pre then
+ local p=rawget(properties,prevglyph)
+ if p then
+ local i=p.preinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ pre=insert_node_before(pre,pre,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ if replace then
+ local p=rawget(properties,prevglyph)
+ if p then
+ local i=p.replaceinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ replace=insert_node_before(replace,replace,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if done then
+ setdisc(current,pre,post,replace)
+ end
+ prevglyph=nil
+ prevdisc=current
+ else
+ prevglyph=nil
+ prevdisc=nil
+ end
+ prev=current
+ current=next
+ end
+ if keepregisteredcounts then
+ keepregisteredcounts=false
+ else
+ nofregisteredpositions=0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
+end
+local function showoffset(n,flag)
+ local x,y=getoffsets(n)
+ if x~=0 or y~=0 then
+ setcolor(n,"darkgray")
+ end
+end
+local function inject_everything(head,where)
+ if trace_injections then
+ trace(head,"everything")
+ end
+ local hascursives=nofregisteredcursives>0
+ local hasmarks=nofregisteredmarks>0
+ local current=head
+ local last=nil
+ local prev=nil
+ local next=nil
+ local prevdisc=nil
+ local prevglyph=nil
+ local pre=nil
+ local post=nil
+ local replace=nil
+ local pretail=nil
+ local posttail=nil
+ local replacetail=nil
+ local cursiveanchor=nil
+ local minc=0
+ local maxc=0
+ local glyphs={}
+ local marks={}
+ local nofmarks=0
+ local function processmark(p,n,pn)
+ local px,py=getoffsets(p)
+ local nx,ny=getoffsets(n)
+ local ox=0
+ local rightkern=nil
+ local pp=rawget(properties,p)
+ if pp then
+ pp=pp.injections
+ if pp then
+ rightkern=pp.rightkern
+ end
+ end
+ local markdir=pn.markdir
+ if rightkern then
+ ox=px-(pn.markx or 0)-rightkern
+ if markdir and markdir<0 then
+ if not pn.markmark then
+ ox=ox+(pn.leftkern or 0)
+ end
+ else
+ if false then
+ local leftkern=pp.leftkern
+ if leftkern then
+ ox=ox-leftkern
+ end
+ end
+ end
+ else
+ ox=px-(pn.markx or 0)
+ if markdir and markdir<0 then
+ if not pn.markmark then
+ local leftkern=pn.leftkern
+ if leftkern then
+ ox=ox+leftkern
+ end
+ end
+ end
+ if pn.checkmark then
+ local wn=getwidth(n)
+ if wn and wn~=0 then
+ wn=wn/2
+ if trace_injections then
+ report_injections("correcting non zero width mark %C",getchar(n))
+ end
+ insert_node_before(n,n,fontkern(-wn))
+ insert_node_after(n,n,fontkern(-wn))
+ end
+ end
+ end
+ local oy=ny+py+(pn.marky or 0)
+ if not pn.markmark then
+ local yoffset=pn.yoffset
+ if yoffset then
+ oy=oy+yoffset
+ end
+ end
+ setoffsets(n,ox,oy)
+ if trace_marks then
+ showoffset(n,true)
+ end
+ end
+ while current do
+ local next=getnext(current)
+ local char,id=ischar(current)
+ if char then
+ local p=rawget(properties,current)
+ if p then
+ local i=p.injections
+ if i then
+ local pm=i.markbasenode
+ if pm then
+ nofmarks=nofmarks+1
+ marks[nofmarks]=current
+ else
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(current,false,yoffset)
+ end
+ if hascursives then
+ local cursivex=i.cursivex
+ if cursivex then
+ if cursiveanchor then
+ if cursivex~=0 then
+ i.leftkern=(i.leftkern or 0)+cursivex
+ end
+ if maxc==0 then
+ minc=1
+ maxc=1
+ glyphs[1]=cursiveanchor
+ else
+ maxc=maxc+1
+ glyphs[maxc]=cursiveanchor
+ end
+ properties[cursiveanchor].cursivedy=i.cursivey
+ last=current
+ else
+ maxc=0
+ end
+ elseif maxc>0 then
+ local nx,ny=getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti=glyphs[i]
+ ny=ny+properties[ti].cursivedy
+ setoffsets(ti,false,ny)
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ maxc=0
+ cursiveanchor=nil
+ end
+ if i.cursiveanchor then
+ cursiveanchor=current
+ else
+ if maxc>0 then
+ local nx,ny=getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti=glyphs[i]
+ ny=ny+properties[ti].cursivedy
+ setoffsets(ti,false,ny)
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ maxc=0
+ end
+ cursiveanchor=nil
+ end
+ end
+ local leftkern=i.leftkern
+ local rightkern=i.rightkern
+ if leftkern and leftkern~=0 then
+ if rightkern and leftkern==-rightkern then
+ setoffsets(current,leftkern,false)
+ rightkern=0
+ else
+ head=insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if rightkern and rightkern~=0 then
+ insert_node_after(head,current,fontkern(rightkern))
+ end
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ if next and getid(next)==disc_code then
+ if replace then
+ else
+ replace=fontkern(rightkern)
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if prevdisc then
+ if p then
+ local done=false
+ if post then
+ local i=p.postinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(posttail,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ if replace then
+ local i=p.replaceinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(replacetail,fontkern(leftkern))
+ done=true
+ end
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=fontkern(leftkern)
+ done=true
+ end
+ end
+ end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
+ end
+ end
+ end
+ else
+ if hascursives and maxc>0 then
+ local nx,ny=getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti=glyphs[i]
+ ny=ny+properties[ti].cursivedy
+ local xi,yi=getoffsets(ti)
+ setoffsets(ti,xi,yi+ny)
+ end
+ maxc=0
+ cursiveanchor=nil
+ end
+ end
+ prevdisc=nil
+ prevglyph=current
+ elseif char==false then
+ prevdisc=nil
+ prevglyph=current
+ elseif id==disc_code then
+ pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
+ local done=false
+ if pre then
+ for n in nextchar,pre do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.preinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ pre=insert_node_before(pre,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(pre,n,fontkern(rightkern))
+ done=true
+ end
+ if hasmarks then
+ local pm=i.markbasenode
+ if pm then
+ processmark(pm,n,i)
+ end
+ end
+ end
+ end
+ end
+ end
+ if post then
+ for n in nextchar,post do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.postinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ post=insert_node_before(post,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(post,n,fontkern(rightkern))
+ done=true
+ end
+ if hasmarks then
+ local pm=i.markbasenode
+ if pm then
+ processmark(pm,n,i)
+ end
+ end
+ end
+ end
+ end
+ end
+ if replace then
+ for n in nextchar,replace do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.replaceinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=insert_node_before(replace,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(replace,n,fontkern(rightkern))
+ done=true
+ end
+ if hasmarks then
+ local pm=i.markbasenode
+ if pm then
+ processmark(pm,n,i)
+ end
+ end
+ end
+ end
+ end
+ end
+ if prevglyph then
+ if pre then
+ local p=rawget(properties,prevglyph)
+ if p then
+ local i=p.preinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ pre=insert_node_before(pre,pre,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ if replace then
+ local p=rawget(properties,prevglyph)
+ if p then
+ local i=p.replaceinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ replace=insert_node_before(replace,replace,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if done then
+ setdisc(current,pre,post,replace)
+ end
+ prevglyph=nil
+ prevdisc=current
+ else
+ prevglyph=nil
+ prevdisc=nil
+ end
+ prev=current
+ current=next
+ end
+ if hascursives and maxc>0 then
+ local nx,ny=getoffsets(last)
+ for i=maxc,minc,-1 do
+ local ti=glyphs[i]
+ ny=ny+properties[ti].cursivedy
+ setoffsets(ti,false,ny)
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ end
+ if nofmarks>0 then
+ for i=1,nofmarks do
+ local m=marks[i]
+ local p=rawget(properties,m)
+ local i=p.injections
+ local b=i.markbasenode
+ processmark(b,m,i)
+ end
+ elseif hasmarks then
+ end
+ if keepregisteredcounts then
+ keepregisteredcounts=false
+ else
+ nofregisteredkerns=0
+ nofregisteredpositions=0
+ nofregisteredmarks=0
+ nofregisteredcursives=0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
+end
+local triggers=false
+function nodes.injections.setspacekerns(font,sequence)
+ if triggers then
+ triggers[font]=sequence
+ else
+ triggers={ [font]=sequence }
+ end
+end
+local getthreshold
+if context then
+
+--removed
+
+else
+ injections.threshold=0
+ getthreshold=function(font)
+ local p=fontdata[font].parameters
+ local f=p.factor
+ local s=p.spacing
+ local t=injections.threshold*(s and s.width or p.space or 0)-2
+ return t>0 and t or 0,f
+ end
+end
+injections.getthreshold=getthreshold
+function injections.isspace(n,threshold,id)
+ if (id or getid(n))==glue_code then
+ local w=getwidth(n)
+ if threshold and w>threshold then
+ return 32
+ end
+ end
+end
+local getspaceboth=getboth
+function injections.installgetspaceboth(gb)
+ getspaceboth=gb or getboth
+end
+local function injectspaces(head)
+ if not triggers then
+ return head
+ end
+ local lastfont=nil
+ local spacekerns=nil
+ local leftkerns=nil
+ local rightkerns=nil
+ local factor=0
+ local threshold=0
+ local leftkern=false
+ local rightkern=false
+ local function updatefont(font,trig)
+ leftkerns=trig.left
+ rightkerns=trig.right
+ lastfont=font
+ threshold,
+ factor=getthreshold(font)
+ end
+ for n in nextglue,head do
+ local prev,next=getspaceboth(n)
+ local prevchar=prev and ischar(prev)
+ local nextchar=next and ischar(next)
+ if nextchar then
+ local font=getfont(next)
+ local trig=triggers[font]
+ if trig then
+ if lastfont~=font then
+ updatefont(font,trig)
+ end
+ if rightkerns then
+ rightkern=rightkerns[nextchar]
+ end
+ end
+ end
+ if prevchar then
+ local font=getfont(prev)
+ local trig=triggers[font]
+ if trig then
+ if lastfont~=font then
+ updatefont(font,trig)
+ end
+ if leftkerns then
+ leftkern=leftkerns[prevchar]
+ end
+ end
+ end
+ if leftkern then
+ local old=getwidth(n)
+ if old>threshold then
+ if rightkern then
+ if useitalickerns then
+ local lnew=leftkern*factor
+ local rnew=rightkern*factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar)
+ end
+ head=insert_node_before(head,n,italickern(lnew))
+ insert_node_after(head,n,italickern(rnew))
+ else
+ local new=old+(leftkern+rightkern)*factor
+ if trace_spaces then
+ report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar)
+ end
+ setwidth(n,new)
+ end
+ rightkern=false
+ else
+ if useitalickerns then
+ local new=leftkern*factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p]",prevchar,old,new)
+ end
+ insert_node_after(head,n,italickern(new))
+ else
+ local new=old+leftkern*factor
+ if trace_spaces then
+ report_spaces("%C [%p -> %p]",prevchar,old,new)
+ end
+ setwidth(n,new)
+ end
+ end
+ end
+ leftkern=false
+ elseif rightkern then
+ local old=getwidth(n)
+ if old>threshold then
+ if useitalickerns then
+ local new=rightkern*factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p]",nextchar,old,new)
+ end
+ insert_node_after(head,n,italickern(new))
+ else
+ local new=old+rightkern*factor
+ if trace_spaces then
+ report_spaces("[%p -> %p] %C",nextchar,old,new)
+ end
+ setwidth(n,new)
+ end
+ end
+ rightkern=false
+ end
+ end
+ triggers=false
+ return head
+end
+function injections.handler(head,where)
+ if triggers then
+ head=injectspaces(head)
+ end
+ if nofregisteredmarks>0 or nofregisteredcursives>0 then
+ if trace_injections then
+ report_injections("injection variant %a","everything")
+ end
+ return inject_everything(head,where)
+ elseif nofregisteredpositions>0 then
+ if trace_injections then
+ report_injections("injection variant %a","positions")
+ end
+ return inject_positions_only(head,where)
+ elseif nofregisteredkerns>0 then
+ if trace_injections then
+ report_injections("injection variant %a","kerns")
+ end
+ return inject_kerns_only(head,where)
+ else
+ return head
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-ota']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local type=type
+if not trackers then trackers={ register=function() end } end
+local fonts,nodes,node=fonts,nodes,node
+local allocate=utilities.storage.allocate
+local otf=fonts.handlers.otf
+local analyzers=fonts.analyzers
+local initializers=allocate()
+local methods=allocate()
+analyzers.initializers=initializers
+analyzers.methods=methods
+local a_state=attributes.private('state')
+local nuts=nodes.nuts
+local tonut=nuts.tonut
+local getnext=nuts.getnext
+local getprev=nuts.getprev
+local getprev=nuts.getprev
+local getprop=nuts.getprop
+local setprop=nuts.setprop
+local getsubtype=nuts.getsubtype
+local getchar=nuts.getchar
+local ischar=nuts.ischar
+local end_of_math=nuts.end_of_math
+local nodecodes=nodes.nodecodes
+local disc_code=nodecodes.disc
+local math_code=nodecodes.math
+local fontdata=fonts.hashes.identifiers
+local categories=characters and characters.categories or {}
+local chardata=characters and characters.data
+local otffeatures=fonts.constructors.features.otf
+local registerotffeature=otffeatures.register
+local s_init=1 local s_rphf=7
+local s_medi=2 local s_half=8
+local s_fina=3 local s_pref=9
+local s_isol=4 local s_blwf=10
+local s_mark=5 local s_pstf=11
+local s_rest=6
+local states=allocate {
+ init=s_init,
+ medi=s_medi,
+ med2=s_medi,
+ fina=s_fina,
+ fin2=s_fina,
+ fin3=s_fina,
+ isol=s_isol,
+ mark=s_mark,
+ rest=s_rest,
+ rphf=s_rphf,
+ half=s_half,
+ pref=s_pref,
+ blwf=s_blwf,
+ pstf=s_pstf,
+}
+local features=allocate {
+ init=s_init,
+ medi=s_medi,
+ med2=s_medi,
+ fina=s_fina,
+ fin2=s_fina,
+ fin3=s_fina,
+ isol=s_isol,
+ rphf=s_rphf,
+ half=s_half,
+ pref=s_pref,
+ blwf=s_blwf,
+ pstf=s_pstf,
+}
+analyzers.states=states
+analyzers.features=features
+analyzers.useunicodemarks=false
+function analyzers.setstate(head,font)
+ local useunicodemarks=analyzers.useunicodemarks
+ local tfmdata=fontdata[font]
+ local descriptions=tfmdata.descriptions
+ local first,last,current,n,done=nil,nil,head,0,false
+ current=tonut(current)
+ while current do
+ local char,id=ischar(current,font)
+ if char and not getprop(current,a_state) then
+ done=true
+ local d=descriptions[char]
+ if d then
+ if d.class=="mark" then
+ done=true
+ setprop(current,a_state,s_mark)
+ elseif useunicodemarks and categories[char]=="mn" then
+ done=true
+ setprop(current,a_state,s_mark)
+ elseif n==0 then
+ first,last,n=current,current,1
+ setprop(current,a_state,s_init)
+ else
+ last,n=current,n+1
+ setprop(current,a_state,s_medi)
+ end
+ else
+ if first and first==last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ first,last,n=nil,nil,0
+ end
+ elseif char==false then
+ if first and first==last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ first,last,n=nil,nil,0
+ if id==math_code then
+ current=end_of_math(current)
+ end
+ elseif id==disc_code then
+ setprop(current,a_state,s_medi)
+ last=current
+ else
+ if first and first==last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ first,last,n=nil,nil,0
+ if id==math_code then
+ current=end_of_math(current)
+ end
+ end
+ current=getnext(current)
+ end
+ if first and first==last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ return head,done
+end
+local function analyzeinitializer(tfmdata,value)
+ local script,language=otf.scriptandlanguage(tfmdata)
+ local action=initializers[script]
+ if not action then
+ elseif type(action)=="function" then
+ return action(tfmdata,value)
+ else
+ local action=action[language]
+ if action then
+ return action(tfmdata,value)
+ end
+ end
+end
+local function analyzeprocessor(head,font,attr)
+ local tfmdata=fontdata[font]
+ local script,language=otf.scriptandlanguage(tfmdata,attr)
+ local action=methods[script]
+ if not action then
+ elseif type(action)=="function" then
+ return action(head,font,attr)
+ else
+ action=action[language]
+ if action then
+ return action(head,font,attr)
+ end
+ end
+ return head,false
+end
+registerotffeature {
+ name="analyze",
+ description="analysis of character classes",
+ default=true,
+ initializers={
+ node=analyzeinitializer,
+ },
+ processors={
+ position=1,
+ node=analyzeprocessor,
+ }
+}
+methods.latn=analyzers.setstate
+local arab_warned={}
+local function warning(current,what)
+ local char=getchar(current)
+ if not arab_warned[char] then
+ log.report("analyze","arab: character %C has no %a class",char,what)
+ arab_warned[char]=true
+ end
+end
+local mappers=allocate {
+ l=s_init,
+ d=s_medi,
+ c=s_medi,
+ r=s_fina,
+ u=s_isol,
+}
+local classifiers=characters.classifiers
+if not classifiers then
+ local f_arabic,l_arabic=characters.blockrange("arabic")
+ local f_syriac,l_syriac=characters.blockrange("syriac")
+ local f_mandiac,l_mandiac=characters.blockrange("mandiac")
+ local f_nko,l_nko=characters.blockrange("nko")
+ local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda")
+ classifiers=table.setmetatableindex(function(t,k)
+ if type(k)=="number" then
+ local c=chardata[k]
+ local v=false
+ if c then
+ local arabic=c.arabic
+ if arabic then
+ v=mappers[arabic]
+ if not v then
+ log.report("analyze","error in mapping arabic %C",k)
+ v=false
+ end
+ elseif (k>=f_arabic and k<=l_arabic) or
+ (k>=f_syriac and k<=l_syriac) or
+ (k>=f_mandiac and k<=l_mandiac) or
+ (k>=f_nko and k<=l_nko) or
+ (k>=f_ext_a and k<=l_ext_a) then
+ if categories[k]=="mn" then
+ v=s_mark
+ else
+ v=s_rest
+ end
+ end
+ end
+ t[k]=v
+ return v
+ end
+ end)
+ characters.classifiers=classifiers
+end
+function methods.arab(head,font,attr)
+ local first,last,c_first,c_last
+ local current=head
+ local done=false
+ current=tonut(current)
+ while current do
+ local char,id=ischar(current,font)
+ if char and not getprop(current,a_state) then
+ done=true
+ local classifier=classifiers[char]
+ if not classifier then
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first,last=nil,nil
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first=nil
+ end
+ elseif classifier==s_mark then
+ setprop(current,a_state,s_mark)
+ elseif classifier==s_isol then
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first,last=nil,nil
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first=nil
+ end
+ setprop(current,a_state,s_isol)
+ elseif classifier==s_medi then
+ if first then
+ last=current
+ c_last=classifier
+ setprop(current,a_state,s_medi)
+ else
+ setprop(current,a_state,s_init)
+ first=current
+ c_first=classifier
+ end
+ elseif classifier==s_fina then
+ if last then
+ if getprop(last,a_state)~=s_init then
+ setprop(last,a_state,s_medi)
+ end
+ setprop(current,a_state,s_fina)
+ first,last=nil,nil
+ elseif first then
+ setprop(current,a_state,s_fina)
+ first=nil
+ else
+ setprop(current,a_state,s_isol)
+ end
+ else
+ setprop(current,a_state,s_rest)
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first,last=nil,nil
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first=nil
+ end
+ end
+ else
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first,last=nil,nil
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first=nil
+ end
+ if id==math_code then
+ current=end_of_math(current)
+ end
+ end
+ current=getnext(current)
+ end
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ end
+ return head,done
+end
+methods.syrc=methods.arab
+methods.mand=methods.arab
+methods.nko=methods.arab
+directives.register("otf.analyze.useunicodemarks",function(v)
+ analyzers.useunicodemarks=v
+end)
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-ots']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
+}
+local type,next,tonumber=type,next,tonumber
+local random=math.random
+local formatters=string.formatters
+local insert=table.insert
+local registertracker=trackers.register
+local logs=logs
+local trackers=trackers
+local nodes=nodes
+local attributes=attributes
+local fonts=fonts
+local otf=fonts.handlers.otf
+local tracers=nodes.tracers
+local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end)
+local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end)
+local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end)
+local trace_ligatures=false registertracker("otf.ligatures",function(v) trace_ligatures=v end)
+local trace_contexts=false registertracker("otf.contexts",function(v) trace_contexts=v end)
+local trace_marks=false registertracker("otf.marks",function(v) trace_marks=v end)
+local trace_kerns=false registertracker("otf.kerns",function(v) trace_kerns=v end)
+local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursive=v end)
+local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end)
+local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end)
+local trace_details=false registertracker("otf.details",function(v) trace_details=v end)
+local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end)
+local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end)
+local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end)
+local trace_chains=false registertracker("otf.chains",function(v) trace_chains=v end)
+local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end)
+local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end)
+local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end)
+local forcediscretionaries=false
+local forcepairadvance=false
+directives.register("otf.forcediscretionaries",function(v)
+ forcediscretionaries=v
+end)
+directives.register("otf.forcepairadvance",function(v)
+ forcepairadvance=v
+end)
+local report_direct=logs.reporter("fonts","otf direct")
+local report_subchain=logs.reporter("fonts","otf subchain")
+local report_chain=logs.reporter("fonts","otf chain")
+local report_process=logs.reporter("fonts","otf process")
+local report_warning=logs.reporter("fonts","otf warning")
+local report_run=logs.reporter("fonts","otf run")
+registertracker("otf.substitutions","otf.singles","otf.multiples","otf.alternatives","otf.ligatures")
+registertracker("otf.positions","otf.marks","otf.kerns","otf.cursive")
+registertracker("otf.actions","otf.substitutions","otf.positions")
+registertracker("otf.sample","otf.steps","otf.substitutions","otf.positions","otf.analyzing")
+registertracker("otf.sample.silent","otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing")
+local nuts=nodes.nuts
+local getfield=nuts.getfield
+local getnext=nuts.getnext
+local setnext=nuts.setnext
+local getprev=nuts.getprev
+local setprev=nuts.setprev
+local getboth=nuts.getboth
+local setboth=nuts.setboth
+local getid=nuts.getid
+local getprop=nuts.getprop
+local setprop=nuts.setprop
+local getsubtype=nuts.getsubtype
+local setsubtype=nuts.setsubtype
+local getchar=nuts.getchar
+local setchar=nuts.setchar
+local getdisc=nuts.getdisc
+local setdisc=nuts.setdisc
+local setlink=nuts.setlink
+local getcomponents=nuts.getcomponents
+local setcomponents=nuts.setcomponents
+local getwidth=nuts.getwidth
+local getattr=nuts.getattr
+local getglyphdata=nuts.getglyphdata
+local ischar=nuts.ischar
+local isglyph=nuts.isglyph
+local usesfont=nuts.uses_font
+local insert_node_after=nuts.insert_after
+local copy_node=nuts.copy
+local copy_node_list=nuts.copy_list
+local remove_node=nuts.remove
+local find_node_tail=nuts.tail
+local flush_node_list=nuts.flush_list
+local flush_node=nuts.flush_node
+local end_of_math=nuts.end_of_math
+local setmetatable=setmetatable
+local setmetatableindex=table.setmetatableindex
+local nextnode=nuts.traversers.node
+local nodecodes=nodes.nodecodes
+local glyphcodes=nodes.glyphcodes
+local disccodes=nodes.disccodes
+local glyph_code=nodecodes.glyph
+local glue_code=nodecodes.glue
+local disc_code=nodecodes.disc
+local math_code=nodecodes.math
+local dir_code=nodecodes.dir
+local localpar_code=nodecodes.localpar
+local discretionarydisc_code=disccodes.discretionary
+local ligatureglyph_code=glyphcodes.ligature
+local a_state=attributes.private('state')
+local a_noligature=attributes.private("noligature")
+local injections=nodes.injections
+local setmark=injections.setmark
+local setcursive=injections.setcursive
+local setkern=injections.setkern
+local setmove=injections.setmove
+local setposition=injections.setposition
+local resetinjection=injections.reset
+local copyinjection=injections.copy
+local setligaindex=injections.setligaindex
+local getligaindex=injections.getligaindex
+local fontdata=fonts.hashes.identifiers
+local fontfeatures=fonts.hashes.features
+local otffeatures=fonts.constructors.features.otf
+local registerotffeature=otffeatures.register
+local onetimemessage=fonts.loggers.onetimemessage or function() end
+local getrandom=utilities and utilities.randomizer and utilities.randomizer.get
+otf.defaultnodealternate="none"
+local tfmdata=false
+local characters=false
+local descriptions=false
+local marks=false
+local classes=false
+local currentfont=false
+local factor=0
+local threshold=0
+local checkmarks=false
+local discs=false
+local spaces=false
+local sweepnode=nil
+local sweephead={}
+local notmatchpre={}
+local notmatchpost={}
+local notmatchreplace={}
+local handlers={}
+local isspace=injections.isspace
+local getthreshold=injections.getthreshold
+local checkstep=(tracers and tracers.steppers.check) or function() end
+local registerstep=(tracers and tracers.steppers.register) or function() end
+local registermessage=(tracers and tracers.steppers.message) or function() end
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ if trace_steps=="silent" then
+ return
+ end
+ end
+ report_direct(...)
+end
+local function logwarning(...)
+ report_direct(...)
+end
+local gref do
+ local f_unicode=formatters["U+%X"]
+ local f_uniname=formatters["U+%X (%s)"]
+ local f_unilist=formatters["% t"]
+ gref=function(n)
+ if type(n)=="number" then
+ local description=descriptions[n]
+ local name=description and description.name
+ if name then
+ return f_uniname(n,name)
+ else
+ return f_unicode(n)
+ end
+ elseif n then
+ local t={}
+ for i=1,#n do
+ local ni=n[i]
+ if tonumber(ni) then
+ local di=descriptions[ni]
+ local nn=di and di.name
+ if nn then
+ t[#t+1]=f_uniname(ni,nn)
+ else
+ t[#t+1]=f_unicode(ni)
+ end
+ end
+ end
+ return f_unilist(t)
+ else
+ return "<error in node mode tracing>"
+ end
+ end
+end
+local function cref(dataset,sequence,index)
+ if not dataset then
+ return "no valid dataset"
+ end
+ local merged=sequence.merged and "merged " or ""
+ if index then
+ return formatters["feature %a, type %a, %schain lookup %a, index %a"](
+ dataset[4],sequence.type,merged,sequence.name,index)
+ else
+ return formatters["feature %a, type %a, %schain lookup %a"](
+ dataset[4],sequence.type,merged,sequence.name)
+ end
+end
+local function pref(dataset,sequence)
+ return formatters["feature %a, type %a, %slookup %a"](
+ dataset[4],sequence.type,sequence.merged and "merged " or "",sequence.name)
+end
+local function mref(rlmode)
+ if not rlmode or rlmode>=0 then
+ return "l2r"
+ else
+ return "r2l"
+ end
+end
+local function flattendisk(head,disc)
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
+ local prev,next=getboth(disc)
+ local ishead=head==disc
+ setdisc(disc)
+ flush_node(disc)
+ if pre then
+ flush_node_list(pre)
+ end
+ if post then
+ flush_node_list(post)
+ end
+ if ishead then
+ if replace then
+ if next then
+ setlink(replacetail,next)
+ end
+ return replace,replace
+ elseif next then
+ return next,next
+ else
+ end
+ else
+ if replace then
+ if next then
+ setlink(replacetail,next)
+ end
+ setlink(prev,replace)
+ return head,replace
+ else
+ setlink(prev,next)
+ return head,next
+ end
+ end
+end
+local function appenddisc(disc,list)
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
+ local posthead=list
+ local replacehead=copy_node_list(list)
+ if post then
+ setlink(posttail,posthead)
+ else
+ post=posthead
+ end
+ if replace then
+ setlink(replacetail,replacehead)
+ else
+ replace=replacehead
+ end
+ setdisc(disc,pre,post,replace)
+end
+local copy_no_components=nuts.copy_no_components
+local copy_only_glyphs=nuts.copy_only_glyphs
+local set_components=setcomponents
+local take_components=getcomponents
+local function count_components(start,marks)
+ local char=isglyph(start)
+ if char then
+ if getsubtype(start)==ligatureglyph_code then
+ local i=0
+ local components=getcomponents(start)
+ while components do
+ i=i+count_components(components,marks)
+ components=getnext(components)
+ end
+ return i
+ elseif not marks[char] then
+ return 1
+ end
+ end
+ return 0
+end
+local function markstoligature(head,start,stop,char)
+ if start==stop and getchar(start)==char then
+ return head,start
+ else
+ local prev=getprev(start)
+ local next=getnext(stop)
+ setprev(start)
+ setnext(stop)
+ local base=copy_no_components(start,copyinjection)
+ if head==start then
+ head=base
+ end
+ resetinjection(base)
+ setchar(base,char)
+ setsubtype(base,ligatureglyph_code)
+ set_components(base,start)
+ setlink(prev,base,next)
+ return head,base
+ end
+end
+local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks)
+ if getattr(start,a_noligature)==1 then
+ return head,start
+ end
+ if start==stop and getchar(start)==char then
+ resetinjection(start)
+ setchar(start,char)
+ return head,start
+ end
+ local prev=getprev(start)
+ local next=getnext(stop)
+ local comp=start
+ setprev(start)
+ setnext(stop)
+ local base=copy_no_components(start,copyinjection)
+ if start==head then
+ head=base
+ end
+ resetinjection(base)
+ setchar(base,char)
+ setsubtype(base,ligatureglyph_code)
+ set_components(base,comp)
+ setlink(prev,base,next)
+ if not discfound then
+ local deletemarks=not skiphash or hasmarks
+ local components=start
+ local baseindex=0
+ local componentindex=0
+ local head=base
+ local current=base
+ while start do
+ local char=getchar(start)
+ if not marks[char] then
+ baseindex=baseindex+componentindex
+ componentindex=count_components(start,marks)
+ elseif not deletemarks then
+ setligaindex(start,baseindex+getligaindex(start,componentindex))
+ if trace_marks then
+ logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ end
+ local n=copy_node(start)
+ copyinjection(n,start)
+ head,current=insert_node_after(head,current,n)
+ elseif trace_marks then
+ logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char))
+ end
+ start=getnext(start)
+ end
+ local start=getnext(current)
+ while start do
+ local char=ischar(start)
+ if char then
+ if marks[char] then
+ setligaindex(start,baseindex+getligaindex(start,componentindex))
+ if trace_marks then
+ logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ end
+ start=getnext(start)
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ else
+ local discprev,discnext=getboth(discfound)
+ if discprev and discnext then
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true)
+ if not replace then
+ local prev=getprev(base)
+ local comp=take_components(base)
+ local copied=copy_only_glyphs(comp)
+ if pre then
+ setlink(discprev,pre)
+ else
+ setnext(discprev)
+ end
+ pre=comp
+ if post then
+ setlink(posttail,discnext)
+ setprev(post)
+ else
+ post=discnext
+ setprev(discnext)
+ end
+ setlink(prev,discfound,next)
+ setboth(base)
+ set_components(base,copied)
+ replace=base
+ if forcediscretionaries then
+ setdisc(discfound,pre,post,replace,discretionarydisc_code)
+ else
+ setdisc(discfound,pre,post,replace)
+ end
+ base=prev
+ end
+ end
+ end
+ return head,base
+end
+local function multiple_glyphs(head,start,multiple,skiphash,what,stop)
+ local nofmultiples=#multiple
+ if nofmultiples>0 then
+ resetinjection(start)
+ setchar(start,multiple[1])
+ if nofmultiples>1 then
+ local sn=getnext(start)
+ for k=2,nofmultiples do
+ local n=copy_node(start)
+ resetinjection(n)
+ setchar(n,multiple[k])
+ insert_node_after(head,start,n)
+ start=n
+ end
+ if what==true then
+ elseif what>1 then
+ local m=multiple[nofmultiples]
+ for i=2,what do
+ local n=copy_node(start)
+ resetinjection(n)
+ setchar(n,m)
+ insert_node_after(head,start,n)
+ start=n
+ end
+ end
+ end
+ return head,start,true
+ else
+ if trace_multiples then
+ logprocess("no multiple for %s",gref(getchar(start)))
+ end
+ return head,start,false
+ end
+end
+local function get_alternative_glyph(start,alternatives,value)
+ local n=#alternatives
+ if n==1 then
+ return alternatives[1],trace_alternatives and "1 (only one present)"
+ elseif value=="random" then
+ local r=getrandom and getrandom("glyph",1,n) or random(1,n)
+ return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r)
+ elseif value=="first" then
+ return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1)
+ elseif value=="last" then
+ return alternatives[n],trace_alternatives and formatters["value %a, taking %a"](value,n)
+ end
+ value=value==true and 1 or tonumber(value)
+ if type(value)~="number" then
+ return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,1)
+ end
+ if value>n then
+ local defaultalt=otf.defaultnodealternate
+ if defaultalt=="first" then
+ return alternatives[n],trace_alternatives and formatters["invalid value %s, taking %a"](value,1)
+ elseif defaultalt=="last" then
+ return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,n)
+ else
+ return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range")
+ end
+ elseif value==0 then
+ return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change")
+ elseif value<1 then
+ return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1)
+ else
+ return alternatives[value],trace_alternatives and formatters["value %a, taking %a"](value,value)
+ end
+end
+function handlers.gsub_single(head,start,dataset,sequence,replacement)
+ if trace_singles then
+ logprocess("%s: replacing %s by single %s",pref(dataset,sequence),gref(getchar(start)),gref(replacement))
+ end
+ resetinjection(start)
+ setchar(start,replacement)
+ return head,start,true
+end
+function handlers.gsub_alternate(head,start,dataset,sequence,alternative)
+ local kind=dataset[4]
+ local what=dataset[1]
+ local value=what==true and tfmdata.shared.features[kind] or what
+ local choice,comment=get_alternative_glyph(start,alternative,value)
+ if choice then
+ if trace_alternatives then
+ logprocess("%s: replacing %s by alternative %a to %s, %s",pref(dataset,sequence),gref(getchar(start)),gref(choice),comment)
+ end
+ resetinjection(start)
+ setchar(start,choice)
+ else
+ if trace_alternatives then
+ logwarning("%s: no variant %a for %s, %s",pref(dataset,sequence),value,gref(getchar(start)),comment)
+ end
+ end
+ return head,start,true
+end
+function handlers.gsub_multiple(head,start,dataset,sequence,multiple,rlmode,skiphash)
+ if trace_multiples then
+ logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple))
+ end
+ return multiple_glyphs(head,start,multiple,skiphash,dataset[1])
+end
+function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skiphash)
+ local current=getnext(start)
+ if not current then
+ return head,start,false,nil
+ end
+ local stop=nil
+ local startchar=getchar(start)
+ if skiphash and skiphash[startchar] then
+ while current do
+ local char=ischar(current,currentfont)
+ if char then
+ local lg=ligature[char]
+ if lg then
+ stop=current
+ ligature=lg
+ current=getnext(current)
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if stop then
+ local lig=ligature.ligature
+ if lig then
+ if trace_ligatures then
+ local stopchar=getchar(stop)
+ head,start=markstoligature(head,start,stop,lig)
+ logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start)))
+ else
+ head,start=markstoligature(head,start,stop,lig)
+ end
+ return head,start,true,false
+ else
+ end
+ end
+ else
+ local discfound=false
+ local hasmarks=marks[startchar]
+ while current do
+ local char,id=ischar(current,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ current=getnext(current)
+ else
+ local lg=ligature[char]
+ if lg then
+ if marks[char] then
+ hasmarks=true
+ end
+ stop=current
+ ligature=lg
+ current=getnext(current)
+ else
+ break
+ end
+ end
+ elseif char==false then
+ break
+ elseif id==disc_code then
+ discfound=current
+ break
+ else
+ break
+ end
+ end
+ if discfound then
+ local pre,post,replace=getdisc(discfound)
+ local match
+ if replace then
+ local char=ischar(replace,currentfont)
+ if char and ligature[char] then
+ match=true
+ end
+ end
+ if not match and pre then
+ local char=ischar(pre,currentfont)
+ if char and ligature[char] then
+ match=true
+ end
+ end
+ if not match and not pre or not replace then
+ local n=getnext(discfound)
+ local char=ischar(n,currentfont)
+ if char and ligature[char] then
+ match=true
+ end
+ end
+ if match then
+ local ishead=head==start
+ local prev=getprev(start)
+ if stop then
+ setnext(stop)
+ local copy=copy_node_list(start)
+ local tail=stop
+ local liat=find_node_tail(copy)
+ if pre then
+ setlink(liat,pre)
+ end
+ if replace then
+ setlink(tail,replace)
+ end
+ pre=copy
+ replace=start
+ else
+ setnext(start)
+ local copy=copy_node(start)
+ if pre then
+ setlink(copy,pre)
+ end
+ if replace then
+ setlink(start,replace)
+ end
+ pre=copy
+ replace=start
+ end
+ setdisc(discfound,pre,post,replace)
+ if prev then
+ setlink(prev,discfound)
+ else
+ setprev(discfound)
+ head=discfound
+ end
+ start=discfound
+ return head,start,true,true
+ end
+ end
+ local lig=ligature.ligature
+ if lig then
+ if stop then
+ if trace_ligatures then
+ local stopchar=getchar(stop)
+ head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
+ logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig))
+ else
+ head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
+ end
+ else
+ resetinjection(start)
+ setchar(start,lig)
+ if trace_ligatures then
+ logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig))
+ end
+ end
+ return head,start,true,false
+ else
+ end
+ end
+ return head,start,false,false
+end
+function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
+ local startchar=getchar(start)
+ local format=step.format
+ if format=="single" or type(kerns)=="table" then
+ local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else
+ local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
+ end
+ end
+ return head,start,true
+end
+function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
+ local snext=getnext(start)
+ if not snext then
+ return head,start,false
+ else
+ local prev=start
+ while snext do
+ local nextchar=ischar(snext,currentfont)
+ if nextchar then
+ if skiphash and skiphash[nextchar] then
+ prev=snext
+ snext=getnext(snext)
+ else
+ local krn=kerns[nextchar]
+ if not krn then
+ break
+ end
+ local format=step.format
+ if format=="pair" then
+ local a=krn[1]
+ local b=krn[2]
+ if a==true then
+ elseif a then
+ local x,y,w,h=setposition(1,start,factor,rlmode,a,injection)
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ end
+ if b==true then
+ start=snext
+ elseif b then
+ local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection)
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ start=snext
+ elseif forcepairadvance then
+ start=snext
+ end
+ return head,start,true
+ elseif krn~=0 then
+ local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
+ if trace_kerns then
+ logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
+ end
+ return head,start,true
+ else
+ break
+ end
+ end
+ else
+ break
+ end
+ end
+ return head,start,false
+ end
+end
+function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash)
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local base=getprev(start)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base=getprev(base)
+ if base then
+ basechar=ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
+ end
+ return head,start,false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
+ end
+ return head,start,false
+ end
+ end
+ end
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)",
+ pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head,start,true
+ elseif trace_bugs then
+ logwarning("%s: mark %s is not anchored to %s",pref(dataset,sequence),gref(markchar),gref(basechar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
+ return head,start,false
+end
+function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlmode,skiphash)
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local base=getprev(start)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base=getprev(base)
+ if base then
+ basechar=ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
+ end
+ return head,start,false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
+ end
+ return head,start,false
+ end
+ end
+ end
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ if ma then
+ local index=getligaindex(start)
+ ba=ba[index]
+ if ba then
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, index %s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)",
+ pref(dataset,sequence),index,bound,gref(markchar),gref(basechar),index,dx,dy)
+ end
+ return head,start,true
+ else
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(dataset,sequence),gref(markchar),gref(basechar),index)
+ end
+ end
+ end
+ elseif trace_bugs then
+ onetimemessage(currentfont,basechar,"no base anchors",report_fonts)
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
+ return head,start,false
+end
+function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode,skiphash)
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local base=getprev(start)
+ local slc=getligaindex(start)
+ if slc then
+ while base do
+ local blc=getligaindex(base)
+ if blc and blc~=slc then
+ base=getprev(base)
+ else
+ break
+ end
+ end
+ end
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)",
+ pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head,start,true
+ end
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
+ return head,start,false
+end
+function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,skiphash,step)
+ local startchar=getchar(start)
+ if marks[startchar] then
+ if trace_cursive then
+ logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar))
+ end
+ else
+ local nxt=getnext(start)
+ while nxt do
+ local nextchar=ischar(nxt,currentfont)
+ if not nextchar then
+ break
+ elseif marks[nextchar] then
+ nxt=getnext(nxt)
+ else
+ local exit=exitanchors[3]
+ if exit then
+ local entry=exitanchors[1][nextchar]
+ if entry then
+ entry=entry[2]
+ if entry then
+ local r2lflag=sequence.flags[4]
+ local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag)
+ if trace_cursive then
+ logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode))
+ end
+ return head,start,true
+ end
+ end
+ end
+ break
+ end
+ end
+ end
+ return head,start,false
+end
+local chainprocs={}
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ if trace_steps=="silent" then
+ return
+ end
+ end
+ report_subchain(...)
+end
+local logwarning=report_subchain
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ if trace_steps=="silent" then
+ return
+ end
+ end
+ report_chain(...)
+end
+local logwarning=report_chain
+local function reversesub(head,start,stop,dataset,sequence,replacements,rlmode,skiphash)
+ local char=getchar(start)
+ local replacement=replacements[char]
+ if replacement then
+ if trace_singles then
+ logprocess("%s: single reverse replacement of %s by %s",cref(dataset,sequence),gref(char),gref(replacement))
+ end
+ resetinjection(start)
+ setchar(start,replacement)
+ return head,start,true
+ else
+ return head,start,false
+ end
+end
+chainprocs.reversesub=reversesub
+local function reportzerosteps(dataset,sequence)
+ logwarning("%s: no steps",cref(dataset,sequence))
+end
+local function reportmoresteps(dataset,sequence)
+ logwarning("%s: more than 1 step",cref(dataset,sequence))
+end
+local function getmapping(dataset,sequence,currentlookup)
+ local steps=currentlookup.steps
+ local nofsteps=currentlookup.nofsteps
+ if nofsteps==0 then
+ reportzerosteps(dataset,sequence)
+ currentlookup.mapping=false
+ return false
+ else
+ if nofsteps>1 then
+ reportmoresteps(dataset,sequence)
+ end
+ local mapping=steps[1].coverage
+ currentlookup.mapping=mapping
+ currentlookup.format=steps[1].format
+ return mapping
+ end
+end
+function chainprocs.gsub_remove(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ if trace_chains then
+ logprocess("%s: removing character %s",cref(dataset,sequence,chainindex),gref(getchar(start)))
+ end
+ head,start=remove_node(head,start,true)
+ return head,getprev(start),true
+end
+function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local current=start
+ while current do
+ local currentchar=ischar(current)
+ if currentchar then
+ local replacement=mapping[currentchar]
+ if not replacement or replacement=="" then
+ if trace_bugs then
+ logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar))
+ end
+ else
+ if trace_singles then
+ logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement))
+ end
+ resetinjection(current)
+ setchar(current,replacement)
+ end
+ return head,start,true
+ elseif currentchar==false then
+ break
+ elseif current==stop then
+ break
+ else
+ current=getnext(current)
+ end
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local kind=dataset[4]
+ local what=dataset[1]
+ local value=what==true and tfmdata.shared.features[kind] or what
+ local current=start
+ while current do
+ local currentchar=ischar(current)
+ if currentchar then
+ local alternatives=mapping[currentchar]
+ if alternatives then
+ local choice,comment=get_alternative_glyph(current,alternatives,value)
+ if choice then
+ if trace_alternatives then
+ logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(currentchar),choice,gref(choice),comment)
+ end
+ resetinjection(start)
+ setchar(start,choice)
+ else
+ if trace_alternatives then
+ logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(currentchar),comment)
+ end
+ end
+ end
+ return head,start,true
+ elseif currentchar==false then
+ break
+ elseif current==stop then
+ break
+ else
+ current=getnext(current)
+ end
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local replacement=mapping[startchar]
+ if not replacement or replacement=="" then
+ if trace_bugs then
+ logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar))
+ end
+ else
+ if trace_multiples then
+ logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement))
+ end
+ return multiple_glyphs(head,start,replacement,skiphash,dataset[1],stop)
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local ligatures=mapping[startchar]
+ if not ligatures then
+ if trace_bugs then
+ logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar))
+ end
+ else
+ local hasmarks=marks[startchar]
+ local current=getnext(start)
+ local discfound=false
+ local last=stop
+ local nofreplacements=1
+ while current do
+ local id=getid(current)
+ if id==disc_code then
+ if not discfound then
+ discfound=current
+ end
+ if current==stop then
+ break
+ else
+ current=getnext(current)
+ end
+ else
+ local schar=getchar(current)
+ if skiphash and skiphash[schar] then
+ current=getnext(current)
+ else
+ local lg=ligatures[schar]
+ if lg then
+ ligatures=lg
+ last=current
+ nofreplacements=nofreplacements+1
+ if marks[char] then
+ hasmarks=true
+ end
+ if current==stop then
+ break
+ else
+ current=getnext(current)
+ end
+ else
+ break
+ end
+ end
+ end
+ end
+ local ligature=ligatures.ligature
+ if ligature then
+ if chainindex then
+ stop=last
+ end
+ if trace_ligatures then
+ if start==stop then
+ logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature))
+ else
+ logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature))
+ end
+ end
+ head,start=toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks)
+ return head,start,true,nofreplacements,discfound
+ elseif trace_bugs then
+ if start==stop then
+ logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar))
+ else
+ logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)))
+ end
+ end
+ end
+ end
+ return head,start,false,0,false
+end
+function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local kerns=mapping[startchar]
+ if kerns then
+ local format=currentlookup.format
+ if format=="single" then
+ local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else
+ local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ end
+ end
+ return head,start,true
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local snext=getnext(start)
+ if snext then
+ local startchar=getchar(start)
+ local kerns=mapping[startchar]
+ if kerns then
+ local prev=start
+ while snext do
+ local nextchar=ischar(snext,currentfont)
+ if not nextchar then
+ break
+ end
+ if skiphash and skiphash[nextchar] then
+ prev=snext
+ snext=getnext(snext)
+ else
+ local krn=kerns[nextchar]
+ if not krn then
+ break
+ end
+ local format=currentlookup.format
+ if format=="pair" then
+ local a=krn[1]
+ local b=krn[2]
+ if a==true then
+ elseif a then
+ local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections")
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ if b==true then
+ start=snext
+ elseif b then
+ local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections")
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ start=snext
+ elseif forcepairadvance then
+ start=snext
+ end
+ return head,start,true
+ elseif krn~=0 then
+ local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn)
+ if trace_kerns then
+ logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
+ end
+ return head,start,true
+ else
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local markanchors=mapping[markchar]
+ if markanchors then
+ local base=getprev(start)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base=getprev(base)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
+ end
+ return head,start,false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
+ end
+ return head,start,false
+ end
+ end
+ end
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ if ma then
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)",
+ cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head,start,true
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar))
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local markanchors=mapping[markchar]
+ if markanchors then
+ local base=getprev(start)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base=getprev(base)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1)
+ end
+ return head,start,false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2)
+ end
+ return head,start,false
+ end
+ end
+ end
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ if ma then
+ local index=getligaindex(start)
+ ba=ba[index]
+ if ba then
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)",
+ cref(dataset,sequence),a or bound,gref(markchar),gref(basechar),index,dx,dy)
+ end
+ return head,start,true
+ end
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar))
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local markanchors=mapping[markchar]
+ if markanchors then
+ local base=getprev(start)
+ local slc=getligaindex(start)
+ if slc then
+ while base do
+ local blc=getligaindex(base)
+ if blc and blc~=slc then
+ base=getprev(base)
+ else
+ break
+ end
+ end
+ end
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ if ma then
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)",
+ cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head,start,true
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1)
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar))
+ end
+ end
+ return head,start,false
+end
+function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local exitanchors=mapping[startchar]
+ if exitanchors then
+ if marks[startchar] then
+ if trace_cursive then
+ logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar))
+ end
+ else
+ local nxt=getnext(start)
+ while nxt do
+ local nextchar=ischar(nxt,currentfont)
+ if not nextchar then
+ break
+ elseif marks[nextchar] then
+ nxt=getnext(nxt)
+ else
+ local exit=exitanchors[3]
+ if exit then
+ local entry=exitanchors[1][nextchar]
+ if entry then
+ entry=entry[2]
+ if entry then
+ local r2lflag=sequence.flags[4]
+ local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag)
+ if trace_cursive then
+ logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode))
+ end
+ return head,start,true
+ end
+ end
+ elseif trace_bugs then
+ onetimemessage(currentfont,startchar,"no entry anchors",report_fonts)
+ end
+ break
+ end
+ end
+ end
+ elseif trace_cursive and trace_details then
+ logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone)
+ end
+ end
+ return head,start,false
+end
+local function show_skip(dataset,sequence,char,ck,class)
+ logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2])
+end
+local userkern=nuts.pool and nuts.pool.newkern
+do if not userkern then
+ local thekern=nuts.new("kern",1)
+ local setkern=nuts.setkern
+ userkern=function(k)
+ local n=copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
+end end
+local function checked(head)
+ local current=head
+ while current do
+ if getid(current)==glue_code then
+ local kern=userkern(getwidth(current))
+ if head==current then
+ local next=getnext(current)
+ if next then
+ setlink(kern,next)
+ end
+ flush_node(current)
+ head=kern
+ current=next
+ else
+ local prev,next=getboth(current)
+ setlink(prev,kern,next)
+ flush_node(current)
+ current=next
+ end
+ else
+ current=getnext(current)
+ end
+ end
+ return head
+end
+local function setdiscchecked(d,pre,post,replace)
+ if pre then pre=checked(pre) end
+ if post then post=checked(post) end
+ if replace then replace=checked(replace) end
+ setdisc(d,pre,post,replace)
+end
+local noflags={ false,false,false,false }
+local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
+ local size=ck[5]-ck[4]+1
+ local chainlookups=ck[6]
+ local done=false
+ if chainlookups then
+ if size==1 then
+ local chainlookup=chainlookups[1]
+ 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,skiphash)
+ if ok then
+ done=true
+ end
+ else
+ logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind)
+ end
+ end
+ else
+ local i=1
+ local laststart=start
+ local nofchainlookups=#chainlookups
+ while start do
+ if skiphash then
+ while start do
+ local char=ischar(start,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ end
+ local chainlookup=chainlookups[i]
+ if chainlookup then
+ 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,skiphash,i)
+ if ok then
+ done=true
+ if n and n>1 and i+n>nofchainlookups then
+ i=size
+ break
+ end
+ end
+ else
+ logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
+ end
+ end
+ else
+ end
+ i=i+1
+ if i>size or not start then
+ break
+ elseif start then
+ laststart=start
+ start=getnext(start)
+ end
+ end
+ if not start then
+ start=laststart
+ end
+ end
+ else
+ local replacements=ck[7]
+ if replacements then
+ head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode,skiphash)
+ else
+ done=true
+ if trace_contexts then
+ logprocess("%s: skipping match",cref(dataset,sequence))
+ end
+ end
+ end
+ return head,start,done
+end
+local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
+ if not start then
+ return head,start,false
+ end
+ local startishead=start==head
+ local seq=ck[3]
+ local f=ck[4]
+ local l=ck[5]
+ local s=#seq
+ local done=false
+ local sweepnode=sweepnode
+ local sweeptype=sweeptype
+ local sweepoverflow=false
+ local keepdisc=not sweepnode
+ local lookaheaddisc=nil
+ local backtrackdisc=nil
+ local current=start
+ local last=start
+ local prev=getprev(start)
+ local hasglue=false
+ local i=f
+ while i<=l do
+ local id=getid(current)
+ if id==glyph_code then
+ i=i+1
+ last=current
+ current=getnext(current)
+ elseif id==glue_code then
+ i=i+1
+ last=current
+ current=getnext(current)
+ hasglue=true
+ elseif id==disc_code then
+ if keepdisc then
+ keepdisc=false
+ lookaheaddisc=current
+ local replace=getfield(current,"replace")
+ if not replace then
+ sweepoverflow=true
+ sweepnode=current
+ current=getnext(current)
+ else
+ while replace and i<=l do
+ if getid(replace)==glyph_code then
+ i=i+1
+ end
+ replace=getnext(replace)
+ end
+ current=getnext(replace)
+ end
+ last=current
+ else
+ head,current=flattendisk(head,current)
+ end
+ else
+ last=current
+ current=getnext(current)
+ end
+ if current then
+ elseif sweepoverflow then
+ break
+ elseif sweeptype=="post" or sweeptype=="replace" then
+ current=getnext(sweepnode)
+ if current then
+ sweeptype=nil
+ sweepoverflow=true
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if sweepoverflow then
+ local prev=current and getprev(current)
+ if not current or prev~=sweepnode then
+ local head=getnext(sweepnode)
+ local tail=nil
+ if prev then
+ tail=prev
+ setprev(current,sweepnode)
+ else
+ tail=find_node_tail(head)
+ end
+ setnext(sweepnode,current)
+ setprev(head)
+ setnext(tail)
+ appenddisc(sweepnode,head)
+ end
+ end
+ if l<s then
+ local i=l
+ local t=sweeptype=="post" or sweeptype=="replace"
+ while current and i<s do
+ local id=getid(current)
+ if id==glyph_code then
+ i=i+1
+ current=getnext(current)
+ elseif id==glue_code then
+ i=i+1
+ current=getnext(current)
+ hasglue=true
+ elseif id==disc_code then
+ if keepdisc then
+ keepdisc=false
+ if notmatchpre[current]~=notmatchreplace[current] then
+ lookaheaddisc=current
+ end
+ local replace=getfield(current,"replace")
+ while replace and i<s do
+ if getid(replace)==glyph_code then
+ i=i+1
+ end
+ replace=getnext(replace)
+ end
+ current=getnext(current)
+ elseif notmatchpre[current]~=notmatchreplace[current] then
+ head,current=flattendisk(head,current)
+ else
+ current=getnext(current)
+ end
+ else
+ current=getnext(current)
+ end
+ if not current and t then
+ current=getnext(sweepnode)
+ if current then
+ sweeptype=nil
+ end
+ end
+ end
+ end
+ if f>1 then
+ local current=prev
+ local i=f
+ local t=sweeptype=="pre" or sweeptype=="replace"
+ if not current and t and current==checkdisk then
+ current=getprev(sweepnode)
+ end
+ while current and i>1 do
+ local id=getid(current)
+ if id==glyph_code then
+ i=i-1
+ elseif id==glue_code then
+ i=i-1
+ hasglue=true
+ elseif id==disc_code then
+ if keepdisc then
+ keepdisc=false
+ if notmatchpost[current]~=notmatchreplace[current] then
+ backtrackdisc=current
+ end
+ local replace=getfield(current,"replace")
+ while replace and i>1 do
+ if getid(replace)==glyph_code then
+ i=i-1
+ end
+ replace=getnext(replace)
+ end
+ elseif notmatchpost[current]~=notmatchreplace[current] then
+ head,current=flattendisk(head,current)
+ end
+ end
+ current=getprev(current)
+ if t and current==checkdisk then
+ current=getprev(sweepnode)
+ end
+ end
+ end
+ local done=false
+ if lookaheaddisc then
+ local cf=start
+ local cl=getprev(lookaheaddisc)
+ local cprev=getprev(start)
+ local insertedmarks=0
+ while cprev do
+ local char=ischar(cf,currentfont)
+ if char and marks[char] then
+ insertedmarks=insertedmarks+1
+ cf=cprev
+ startishead=cf==head
+ cprev=getprev(cprev)
+ else
+ break
+ end
+ end
+ setlink(cprev,lookaheaddisc)
+ setprev(cf)
+ setnext(cl)
+ if startishead then
+ head=lookaheaddisc
+ end
+ local pre,post,replace=getdisc(lookaheaddisc)
+ local new=copy_node_list(cf)
+ local cnew=new
+ if pre then
+ setlink(find_node_tail(cf),pre)
+ end
+ if replace then
+ local tail=find_node_tail(new)
+ setlink(tail,replace)
+ end
+ for i=1,insertedmarks do
+ cnew=getnext(cnew)
+ end
+ cl=start
+ local clast=cnew
+ for i=f,l do
+ cl=getnext(cl)
+ clast=getnext(clast)
+ end
+ if not notmatchpre[lookaheaddisc] then
+ local ok=false
+ cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ if not notmatchreplace[lookaheaddisc] then
+ local ok=false
+ new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ if hasglue then
+ setdiscchecked(lookaheaddisc,cf,post,new)
+ else
+ setdisc(lookaheaddisc,cf,post,new)
+ end
+ start=getprev(lookaheaddisc)
+ sweephead[cf]=getnext(clast) or false
+ sweephead[new]=getnext(cl) or false
+ elseif backtrackdisc then
+ local cf=getnext(backtrackdisc)
+ local cl=start
+ local cnext=getnext(start)
+ local insertedmarks=0
+ while cnext do
+ local char=ischar(cnext,currentfont)
+ if char and marks[char] then
+ insertedmarks=insertedmarks+1
+ cl=cnext
+ cnext=getnext(cnext)
+ else
+ break
+ end
+ end
+ setlink(backtrackdisc,cnext)
+ setprev(cf)
+ setnext(cl)
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true)
+ local new=copy_node_list(cf)
+ local cnew=find_node_tail(new)
+ for i=1,insertedmarks do
+ cnew=getprev(cnew)
+ end
+ local clast=cnew
+ for i=f,l do
+ clast=getnext(clast)
+ end
+ if not notmatchpost[backtrackdisc] then
+ local ok=false
+ cf,start,ok=chainrun(cf,start,last,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ if not notmatchreplace[backtrackdisc] then
+ local ok=false
+ new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ if post then
+ setlink(posttail,cf)
+ else
+ post=cf
+ end
+ if replace then
+ setlink(replacetail,new)
+ else
+ replace=new
+ end
+ if hasglue then
+ setdiscchecked(backtrackdisc,pre,post,replace)
+ else
+ setdisc(backtrackdisc,pre,post,replace)
+ end
+ start=getprev(backtrackdisc)
+ sweephead[post]=getnext(clast) or false
+ sweephead[replace]=getnext(last) or false
+ else
+ local ok=false
+ head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ return head,start,done
+end
+local function chaintrac(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode)
+ local rule=ck[1]
+ local lookuptype=ck[8] or ck[2]
+ local nofseq=#ck[3]
+ local first=ck[4]
+ local last=ck[5]
+ local char=getchar(start)
+ logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping",
+ cref(dataset,sequence),rule,match and "matches" or "nomatch",
+ gref(char),first-1,last-first+1,nofseq-last,lookuptype,
+ discseen and "" or "no ",sweepnode and "" or "not ")
+end
+local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash)
+ local sweepnode=sweepnode
+ local sweeptype=sweeptype
+ local postreplace
+ local prereplace
+ local checkdisc
+ local discseen
+ if sweeptype then
+ if sweeptype=="replace" then
+ postreplace=true
+ prereplace=true
+ else
+ postreplace=sweeptype=="post"
+ prereplace=sweeptype=="pre"
+ end
+ checkdisc=getprev(head)
+ end
+ local currentfont=currentfont
+ local skipped
+ local startprev,
+ startnext=getboth(start)
+ local done
+ local nofcontexts=contexts.n
+ local startchar=nofcontext==1 or ischar(start,currentfont)
+ for k=1,nofcontexts do
+ local ck=contexts[k]
+ local seq=ck[3]
+ local f=ck[4]
+ if not startchar or not seq[f][startchar] then
+ goto next
+ end
+ local s=seq.n
+ local l=ck[5]
+ local current=start
+ local last=start
+ if l>f then
+ local discfound
+ local n=f+1
+ last=startnext
+ while n<=l do
+ if postreplace and not last then
+ last=getnext(sweepnode)
+ sweeptype=nil
+ end
+ if last then
+ local char,id=ischar(last,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped=true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ last=getnext(last)
+ elseif seq[n][char] then
+ if n<l then
+ last=getnext(last)
+ end
+ n=n+1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif char==false then
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif id==disc_code then
+ discseen=true
+ discfound=last
+ notmatchpre[last]=nil
+ notmatchpost[last]=true
+ notmatchreplace[last]=nil
+ local pre,post,replace=getdisc(last)
+ if pre then
+ local n=n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n=n+1
+ if n>l then
+ break
+ end
+ pre=getnext(pre)
+ else
+ notmatchpre[last]=true
+ break
+ end
+ end
+ else
+ notmatchpre[last]=true
+ end
+ if replace then
+ while replace do
+ if seq[n][getchar(replace)] then
+ n=n+1
+ if n>l then
+ break
+ end
+ replace=getnext(replace)
+ else
+ notmatchreplace[last]=true
+ if notmatchpre[last] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ if notmatchpre[last] then
+ goto next
+ end
+ end
+ last=getnext(last)
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+ end
+ if f>1 then
+ if startprev then
+ local prev=startprev
+ if prereplace and prev==checkdisc then
+ prev=getprev(sweepnode)
+ end
+ if prev then
+ local discfound
+ local n=f-1
+ while n>=1 do
+ if prev then
+ local char,id=ischar(prev,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped=true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ prev=getprev(prev)
+ elseif seq[n][char] then
+ if n>1 then
+ prev=getprev(prev)
+ end
+ n=n-1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpost[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif char==false then
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpost[discfound] then
+ goto next
+ end
+ else
+ goto next
+ end
+ break
+ elseif id==disc_code then
+ discseen=true
+ discfound=prev
+ notmatchpre[prev]=true
+ notmatchpost[prev]=nil
+ notmatchreplace[prev]=nil
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true)
+ if pre~=start and post~=start and replace~=start then
+ if post then
+ local n=n
+ while posttail do
+ if seq[n][getchar(posttail)] then
+ n=n-1
+ if posttail==post or n<1 then
+ break
+ else
+ posttail=getprev(posttail)
+ end
+ else
+ notmatchpost[prev]=true
+ break
+ end
+ end
+ if n>=1 then
+ notmatchpost[prev]=true
+ end
+ else
+ notmatchpost[prev]=true
+ end
+ if replace then
+ while replacetail do
+ if seq[n][getchar(replacetail)] then
+ n=n-1
+ if replacetail==replace or n<1 then
+ break
+ else
+ replacetail=getprev(replacetail)
+ end
+ else
+ notmatchreplace[prev]=true
+ if notmatchpost[prev] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ else
+ end
+ end
+ prev=getprev(prev)
+ elseif id==glue_code then
+ local sn=seq[n]
+ if (sn[32] and spaces[prev]) or sn[0xFFFC] then
+ n=n-1
+ prev=getprev(prev)
+ else
+ goto next
+ end
+ elseif seq[n][0xFFFC] then
+ n=n-1
+ prev=getprev(prev)
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+ if s>l then
+ local current=last and getnext(last)
+ if not current and postreplace then
+ current=getnext(sweepnode)
+ end
+ if current then
+ local discfound
+ local n=l+1
+ while n<=s do
+ if current then
+ local char,id=ischar(current,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped=true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ current=getnext(current)
+ elseif seq[n][char] then
+ if n<s then
+ current=getnext(current)
+ end
+ n=n+1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif char==false then
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif id==disc_code then
+ discseen=true
+ discfound=current
+ notmatchpre[current]=nil
+ notmatchpost[current]=true
+ notmatchreplace[current]=nil
+ local pre,post,replace=getdisc(current)
+ if pre then
+ local n=n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n=n+1
+ if n>s then
+ break
+ else
+ pre=getnext(pre)
+ end
+ else
+ notmatchpre[current]=true
+ break
+ end
+ end
+ if n<=s then
+ notmatchpre[current]=true
+ end
+ else
+ notmatchpre[current]=true
+ end
+ if replace then
+ while replace do
+ if seq[n][getchar(replace)] then
+ n=n+1
+ if n>s then
+ break
+ else
+ replace=getnext(replace)
+ end
+ else
+ notmatchreplace[current]=true
+ if notmatchpre[current] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ else
+ end
+ current=getnext(current)
+ elseif id==glue_code then
+ local sn=seq[n]
+ if (sn[32] and spaces[current]) or sn[0xFFFC] then
+ n=n+1
+ current=getnext(current)
+ else
+ goto next
+ end
+ elseif seq[n][0xFFFC] then
+ n=n+1
+ current=getnext(current)
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+ else
+ goto next
+ end
+ end
+ if trace_contexts then
+ chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode)
+ end
+ if discseen or sweepnode then
+ head,start,done=chaindisk(head,start,dataset,sequence,rlmode,skipped and skiphash,ck)
+ else
+ head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck)
+ end
+ if done then
+ break
+ end
+ ::next::
+ end
+ if discseen then
+ notmatchpre={}
+ notmatchpost={}
+ notmatchreplace={}
+ end
+ return head,start,done
+end
+handlers.gsub_context=handle_contextchain
+handlers.gsub_contextchain=handle_contextchain
+handlers.gsub_reversecontextchain=handle_contextchain
+handlers.gpos_contextchain=handle_contextchain
+handlers.gpos_context=handle_contextchain
+local function chained_contextchain(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash)
+ local steps=currentlookup.steps
+ local nofsteps=currentlookup.nofsteps
+ if nofsteps>1 then
+ reportmoresteps(dataset,sequence)
+ end
+ local l=steps[1].coverage[getchar(start)]
+ if l then
+ return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash)
+ else
+ return head,start,false
+ end
+end
+chainprocs.gsub_context=chained_contextchain
+chainprocs.gsub_contextchain=chained_contextchain
+chainprocs.gsub_reversecontextchain=chained_contextchain
+chainprocs.gpos_contextchain=chained_contextchain
+chainprocs.gpos_context=chained_contextchain
+local missing=setmetatableindex("table")
+local logwarning=report_process
+local resolved={}
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ if trace_steps=="silent" then
+ return
+ end
+ end
+ report_process(...)
+end
+local sequencelists=setmetatableindex(function(t,font)
+ local sequences=fontdata[font].resources.sequences
+ if not sequences or not next(sequences) then
+ sequences=false
+ end
+ t[font]=sequences
+ return sequences
+end)
+do
+ local autofeatures=fonts.analyzers.features
+ local featuretypes=otf.tables.featuretypes
+ local defaultscript=otf.features.checkeddefaultscript
+ local defaultlanguage=otf.features.checkeddefaultlanguage
+ local wildcard="*"
+ local default="dflt"
+ local function initialize(sequence,script,language,enabled,autoscript,autolanguage)
+ local features=sequence.features
+ if features then
+ local order=sequence.order
+ if order then
+ local featuretype=featuretypes[sequence.type or "unknown"]
+ for i=1,#order do
+ local kind=order[i]
+ local valid=enabled[kind]
+ if valid then
+ local scripts=features[kind]
+ local languages=scripts and (
+ scripts[script] or
+ scripts[wildcard] or
+ (autoscript and defaultscript(featuretype,autoscript,scripts))
+ )
+ local enabled=languages and (
+ languages[language] or
+ languages[wildcard] or
+ (autolanguage and defaultlanguage(featuretype,autolanguage,languages))
+ )
+ if enabled then
+ return { valid,autofeatures[kind] or false,sequence,kind }
+ end
+ end
+ end
+ else
+ end
+ end
+ return false
+ end
+ function otf.dataset(tfmdata,font)
+ local shared=tfmdata.shared
+ local properties=tfmdata.properties
+ local language=properties.language or "dflt"
+ local script=properties.script or "dflt"
+ local enabled=shared.features
+ local autoscript=enabled and enabled.autoscript
+ local autolanguage=enabled and enabled.autolanguage
+ local res=resolved[font]
+ if not res then
+ res={}
+ resolved[font]=res
+ end
+ local rs=res[script]
+ if not rs then
+ rs={}
+ res[script]=rs
+ end
+ local rl=rs[language]
+ if not rl then
+ rl={
+ }
+ rs[language]=rl
+ local sequences=tfmdata.resources.sequences
+ if sequences then
+ for s=1,#sequences do
+ local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage)
+ if v then
+ rl[#rl+1]=v
+ end
+ end
+ end
+ end
+ return rl
+ end
+end
+local function report_disc(what,n)
+ report_run("%s: %s > %s",what,n,languages.serializediscretionary(n))
+end
+local function kernrun(disc,k_run,font,attr,...)
+ if trace_kernruns then
+ report_disc("kern",disc)
+ end
+ local prev,next=getboth(disc)
+ local nextstart=next
+ local done=false
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
+ local prevmarks=prev
+ while prevmarks do
+ local char=ischar(prevmarks,font)
+ if char and marks[char] then
+ prevmarks=getprev(prevmarks)
+ else
+ break
+ end
+ end
+ if prev and not ischar(prev,font) then
+ prev=false
+ end
+ if next and not ischar(next,font) then
+ next=false
+ end
+ if pre then
+ if k_run(pre,"injections",nil,font,attr,...) then
+ done=true
+ end
+ if prev then
+ setlink(prev,pre)
+ if k_run(prevmarks,"preinjections",pre,font,attr,...) then
+ done=true
+ end
+ setprev(pre)
+ setlink(prev,disc)
+ end
+ end
+ if post then
+ if k_run(post,"injections",nil,font,attr,...) then
+ done=true
+ end
+ if next then
+ setlink(posttail,next)
+ if k_run(posttail,"postinjections",next,font,attr,...) then
+ done=true
+ end
+ setnext(posttail)
+ setlink(disc,next)
+ end
+ end
+ if replace then
+ if k_run(replace,"injections",nil,font,attr,...) then
+ done=true
+ end
+ if prev then
+ setlink(prev,replace)
+ if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then
+ done=true
+ end
+ setprev(replace)
+ setlink(prev,disc)
+ end
+ if next then
+ setlink(replacetail,next)
+ if k_run(replacetail,"replaceinjections",next,font,attr,...) then
+ done=true
+ end
+ setnext(replacetail)
+ setlink(disc,next)
+ end
+ elseif prev and next then
+ setlink(prev,next)
+ if k_run(prevmarks,"emptyinjections",next,font,attr,...) then
+ done=true
+ end
+ setlink(prev,disc,next)
+ end
+ if done and trace_testruns then
+ report_disc("done",disc)
+ end
+ return nextstart,done
+end
+local function comprun(disc,c_run,...)
+ if trace_compruns then
+ report_disc("comp",disc)
+ end
+ local pre,post,replace=getdisc(disc)
+ local renewed=false
+ if pre then
+ sweepnode=disc
+ sweeptype="pre"
+ local new,done=c_run(pre,...)
+ if done then
+ pre=new
+ renewed=true
+ end
+ end
+ if post then
+ sweepnode=disc
+ sweeptype="post"
+ local new,done=c_run(post,...)
+ if done then
+ post=new
+ renewed=true
+ end
+ end
+ if replace then
+ sweepnode=disc
+ sweeptype="replace"
+ local new,done=c_run(replace,...)
+ if done then
+ replace=new
+ renewed=true
+ end
+ end
+ sweepnode=nil
+ sweeptype=nil
+ if renewed then
+ if trace_testruns then
+ report_disc("done",disc)
+ end
+ setdisc(disc,pre,post,replace)
+ end
+ return getnext(disc),renewed
+end
+local function testrun(disc,t_run,c_run,...)
+ if trace_testruns then
+ report_disc("test",disc)
+ end
+ local prev,next=getboth(disc)
+ if not next then
+ return
+ end
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
+ local renewed=false
+ if (post or replace) then
+ if post then
+ setlink(posttail,next)
+ else
+ post=next
+ end
+ if replace then
+ setlink(replacetail,next)
+ else
+ replace=next
+ end
+ local d_post=t_run(post,next,...)
+ local d_replace=t_run(replace,next,...)
+ if d_post>0 or d_replace>0 then
+ local d=d_replace>d_post and d_replace or d_post
+ local head=getnext(disc)
+ local tail=head
+ for i=2,d do
+ local nx=getnext(tail)
+ local id=getid(nx)
+ if id==disc_code then
+ head,tail=flattendisk(head,nx)
+ elseif id==glyph_code then
+ tail=nx
+ else
+ break
+ end
+ end
+ next=getnext(tail)
+ setnext(tail)
+ setprev(head)
+ local new=copy_node_list(head)
+ if posttail then
+ setlink(posttail,head)
+ else
+ post=head
+ end
+ if replacetail then
+ setlink(replacetail,new)
+ else
+ replace=new
+ end
+ else
+ if posttail then
+ setnext(posttail)
+ else
+ post=nil
+ end
+ if replacetail then
+ setnext(replacetail)
+ else
+ replace=nil
+ end
+ end
+ setlink(disc,next)
+ end
+ if trace_testruns then
+ report_disc("more",disc)
+ end
+ if pre then
+ sweepnode=disc
+ sweeptype="pre"
+ local new,ok=c_run(pre,...)
+ if ok then
+ pre=new
+ renewed=true
+ end
+ end
+ if post then
+ sweepnode=disc
+ sweeptype="post"
+ local new,ok=c_run(post,...)
+ if ok then
+ post=new
+ renewed=true
+ end
+ end
+ if replace then
+ sweepnode=disc
+ sweeptype="replace"
+ local new,ok=c_run(replace,...)
+ if ok then
+ replace=new
+ renewed=true
+ end
+ end
+ sweepnode=nil
+ sweeptype=nil
+ if renewed then
+ setdisc(disc,pre,post,replace)
+ if trace_testruns then
+ report_disc("done",disc)
+ end
+ end
+ return getnext(disc),renewed
+end
+local nesting=0
+local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ local done=false
+ local sweep=sweephead[head]
+ if sweep then
+ start=sweep
+ sweephead[head]=false
+ else
+ start=head
+ end
+ while start do
+ local char,id=ischar(start,font)
+ if char then
+ local a
+ if attr then
+ a=getglyphdata(start)
+ end
+ if not a or (a==attr) then
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ done=true
+ end
+ end
+ if start then
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ elseif char==false then
+ return head,done
+ elseif sweep then
+ return head,done
+ else
+ start=getnext(start)
+ end
+ end
+ return head,done
+end
+local function t_run_single(start,stop,font,attr,lookupcache)
+ local lastd=nil
+ while start~=stop do
+ local char=ischar(start,font)
+ if char then
+ local a
+ if attr then
+ a=getglyphdata(start)
+ end
+ local startnext=getnext(start)
+ if not a or (a==attr) then
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local s=startnext
+ local ss=nil
+ local sstop=s==stop
+ if not s then
+ s=ss
+ ss=nil
+ end
+ while getid(s)==disc_code do
+ ss=getnext(s)
+ s=getfield(s,"replace")
+ if not s then
+ s=ss
+ ss=nil
+ end
+ end
+ local l=nil
+ local d=0
+ while s do
+ local char=ischar(s,font)
+ if char then
+ local lg=lookupmatch[char]
+ if lg then
+ if sstop then
+ d=1
+ elseif d>0 then
+ d=d+1
+ end
+ l=lg
+ s=getnext(s)
+ sstop=s==stop
+ if not s then
+ s=ss
+ ss=nil
+ end
+ while getid(s)==disc_code do
+ ss=getnext(s)
+ s=getfield(s,"replace")
+ if not s then
+ s=ss
+ ss=nil
+ end
+ end
+lookupmatch=lg
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if l and l.ligature then
+ lastd=d
+ end
+ else
+ end
+ else
+ end
+ if lastd then
+ return lastd
+ end
+ start=startnext
+ else
+ break
+ end
+ end
+ return 0
+end
+local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ local a
+ if attr then
+ a=getglyphdata(sub)
+ end
+ if not a or (a==attr) then
+ for n in nextnode,sub do
+ if n==last then
+ break
+ end
+ local char=ischar(n)
+ if char then
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection)
+ if ok then
+ return true
+ end
+ end
+ end
+ end
+ end
+end
+local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ local done=false
+ local sweep=sweephead[head]
+ if sweep then
+ start=sweep
+ sweephead[head]=false
+ else
+ start=head
+ end
+ while start do
+ local char=ischar(start,font)
+ if char then
+ local a
+ if attr then
+ a=getglyphdata(start)
+ end
+ if not a or (a==attr) then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ done=true
+ break
+ elseif not start then
+ break
+ end
+ end
+ end
+ if start then
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ elseif char==false then
+ return head,done
+ elseif sweep then
+ return head,done
+ else
+ start=getnext(start)
+ end
+ end
+ return head,done
+end
+local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
+ local lastd=nil
+ while start~=stop do
+ local char=ischar(start,font)
+ if char then
+ local a
+ if attr then
+ a=getglyphdata(start)
+ end
+ local startnext=getnext(start)
+ if not a or (a==attr) then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local s=startnext
+ local ss=nil
+ local sstop=s==stop
+ if not s then
+ s=ss
+ ss=nil
+ end
+ while getid(s)==disc_code do
+ ss=getnext(s)
+ s=getfield(s,"replace")
+ if not s then
+ s=ss
+ ss=nil
+ end
+ end
+ local l=nil
+ local d=0
+ while s do
+ local char=ischar(s)
+ if char then
+ local lg=lookupmatch[char]
+ if lg then
+ if sstop then
+ d=1
+ elseif d>0 then
+ d=d+1
+ end
+ l=lg
+ s=getnext(s)
+ sstop=s==stop
+ if not s then
+ s=ss
+ ss=nil
+ end
+ while getid(s)==disc_code do
+ ss=getnext(s)
+ s=getfield(s,"replace")
+ if not s then
+ s=ss
+ ss=nil
+ end
+ end
+lookupmatch=lg
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if l and l.ligature then
+ lastd=d
+ end
+ end
+ end
+ else
+ end
+ if lastd then
+ return lastd
+ end
+ start=startnext
+ else
+ break
+ end
+ end
+ return 0
+end
+local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ local a
+ if attr then
+ a=getglyphdata(sub)
+ end
+ if not a or (a==attr) then
+ for n in nextnode,sub do
+ if n==last then
+ break
+ end
+ local char=ischar(n)
+ if char then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection)
+ if ok then
+ return true
+ end
+ end
+ end
+ end
+ end
+ end
+end
+local txtdirstate,pardirstate do
+ local getdirection=nuts.getdirection
+ local lefttoright=0
+ local righttoleft=1
+ txtdirstate=function(start,stack,top,rlparmode)
+ local dir,pop=getdirection(start)
+ if pop then
+ if top==1 then
+ return 0,rlparmode
+ else
+ top=top-1
+ if stack[top]==righttoleft then
+ return top,-1
+ else
+ return top,1
+ end
+ end
+ elseif dir==lefttoright then
+ top=top+1
+ stack[top]=lefttoright
+ return top,1
+ elseif dir==righttoleft then
+ top=top+1
+ stack[top]=righttoleft
+ return top,-1
+ else
+ return top,rlparmode
+ end
+ end
+ pardirstate=function(start)
+ local dir=getdirection(start)
+ if dir==lefttoright then
+ return 1,1
+ elseif dir==righttoleft then
+ return -1,-1
+ elseif dir=="TLT" then
+ return 1,1
+ elseif dir=="TRT" then
+ return -1,-1
+ else
+ return 0,0
+ end
+ end
+end
+otf.helpers=otf.helpers or {}
+otf.helpers.txtdirstate=txtdirstate
+otf.helpers.pardirstate=pardirstate
+do
+ local fastdisc=true
+ local testdics=false
+ directives.register("otf.fastdisc",function(v) fastdisc=v end)
+ local otfdataset=nil
+ local getfastdisc={ __index=function(t,k)
+ local v=usesfont(k,currentfont)
+ t[k]=v
+ return v
+ end }
+ local getfastspace={ __index=function(t,k)
+ local v=isspace(k,threshold) or false
+ t[k]=v
+ return v
+ end }
+ function otf.featuresprocessor(head,font,attr,direction,n)
+ local sequences=sequencelists[font]
+ nesting=nesting+1
+ if nesting==1 then
+ currentfont=font
+ tfmdata=fontdata[font]
+ descriptions=tfmdata.descriptions
+ characters=tfmdata.characters
+ local resources=tfmdata.resources
+ marks=resources.marks
+ classes=resources.classes
+ threshold,
+ factor=getthreshold(font)
+ checkmarks=tfmdata.properties.checkmarks
+ if not otfdataset then
+ otfdataset=otf.dataset
+ end
+ discs=fastdisc and n and n>1 and setmetatable({},getfastdisc)
+ spaces=setmetatable({},getfastspace)
+ elseif currentfont~=font then
+ report_warning("nested call with a different font, level %s, quitting",nesting)
+ nesting=nesting-1
+ return head,false
+ end
+ if trace_steps then
+ checkstep(head)
+ end
+ local initialrl=0
+ if getid(head)==localpar_code and getsubtype(head)==0 then
+ initialrl=pardirstate(head)
+ elseif direction==1 or direction=="TRT" then
+ initialrl=-1
+ end
+ local datasets=otfdataset(tfmdata,font,attr)
+ local dirstack={ nil }
+ sweephead={}
+ for s=1,#datasets do
+ local dataset=datasets[s]
+ local attribute=dataset[2]
+ local sequence=dataset[3]
+ local rlparmode=initialrl
+ local topstack=0
+ local typ=sequence.type
+ local gpossing=typ=="gpos_single" or typ=="gpos_pair"
+ local forcetestrun=typ=="gsub_ligature"
+ local handler=handlers[typ]
+ local steps=sequence.steps
+ local nofsteps=sequence.nofsteps
+ local skiphash=sequence.skiphash
+ if not steps then
+ local h,ok=handler(head,dataset,sequence,initialrl,font,attr)
+ if h and h~=head then
+ head=h
+ end
+ elseif typ=="gsub_reversecontextchain" then
+ local start=find_node_tail(head)
+ local rlmode=0
+ local merged=steps.merged
+ while start do
+ local char=ischar(start,font)
+ if char then
+ local m=merged[char]
+ if m then
+ local a
+ if attr then
+ a=getglyphdata(start)
+ end
+ if not a or (a==attr) then
+ for i=m[1],m[2] do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ break
+ end
+ end
+ end
+ if start then
+ start=getprev(start)
+ end
+ else
+ start=getprev(start)
+ end
+ else
+ start=getprev(start)
+ end
+ else
+ start=getprev(start)
+ end
+ end
+ else
+ local start=head
+ local rlmode=initialrl
+ if nofsteps==1 then
+ local step=steps[1]
+ local lookupcache=step.coverage
+ while start do
+ local char,id=ischar(start,font)
+ if char then
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local a
+ if attr then
+ if getglyphdata(start)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ a=true
+ end
+ elseif not attribute or getprop(start,a_state)==attribute then
+ a=true
+ end
+ if a then
+ local ok,df
+ head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if df then
+ elseif start then
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ end
+ elseif char==false or id==glue_code then
+ start=getnext(start)
+ elseif id==disc_code then
+ if not discs or discs[start]==true then
+ local ok
+ if gpossing then
+ start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ elseif forcetestrun then
+ start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ else
+ start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ end
+ else
+ start=getnext(start)
+ end
+ elseif id==math_code then
+ start=getnext(end_of_math(start))
+ elseif id==dir_code then
+ topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
+ start=getnext(start)
+ else
+ start=getnext(start)
+ end
+ end
+ else
+ local merged=steps.merged
+ while start do
+ local char,id=ischar(start,font)
+ if char then
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
+ local m=merged[char]
+ if m then
+ local a
+ if attr then
+ if getglyphdata(start)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ a=true
+ end
+ elseif not attribute or getprop(start,a_state)==attribute then
+ a=true
+ end
+ if a then
+ local ok,df
+ for i=m[1],m[2] do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if df then
+ break
+ elseif ok then
+ break
+ elseif not start then
+ break
+ end
+ end
+ end
+ if df then
+ elseif start then
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ end
+ elseif char==false or id==glue_code then
+ start=getnext(start)
+ elseif id==disc_code then
+ if not discs or discs[start]==true then
+ local ok
+ if gpossing then
+ start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ elseif forcetestrun then
+ start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ else
+ start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ end
+ else
+ start=getnext(start)
+ end
+ elseif id==math_code then
+ start=getnext(end_of_math(start))
+ elseif id==dir_code then
+ topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
+ start=getnext(start)
+ else
+ start=getnext(start)
+ end
+ end
+ end
+ end
+ if trace_steps then
+ registerstep(head)
+ end
+ end
+ nesting=nesting-1
+ return head
+ end
+ function otf.datasetpositionprocessor(head,font,direction,dataset)
+ currentfont=font
+ tfmdata=fontdata[font]
+ descriptions=tfmdata.descriptions
+ characters=tfmdata.characters
+ local resources=tfmdata.resources
+ marks=resources.marks
+ classes=resources.classes
+ threshold,
+ factor=getthreshold(font)
+ checkmarks=tfmdata.properties.checkmarks
+ if type(dataset)=="number" then
+ dataset=otfdataset(tfmdata,font,0)[dataset]
+ end
+ local sequence=dataset[3]
+ local typ=sequence.type
+ local handler=handlers[typ]
+ local steps=sequence.steps
+ local nofsteps=sequence.nofsteps
+ local done=false
+ local dirstack={ nil }
+ local start=head
+ local initialrl=(direction==1 or direction=="TRT") and -1 or 0
+ local rlmode=initialrl
+ local rlparmode=initialrl
+ local topstack=0
+ local merged=steps.merged
+ local position=0
+ while start do
+ local char,id=ischar(start,font)
+ if char then
+ position=position+1
+ local m=merged[char]
+ if m then
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
+ for i=m[1],m[2] do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ break
+ elseif not start then
+ break
+ end
+ end
+ end
+ if start then
+ start=getnext(start)
+ end
+ end
+ else
+ start=getnext(start)
+ end
+ elseif char==false or id==glue_code then
+ start=getnext(start)
+ elseif id==math_code then
+ start=getnext(end_of_math(start))
+ elseif id==dir_code then
+ topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
+ start=getnext(start)
+ else
+ start=getnext(start)
+ end
+ end
+ return head
+ end
+end
+local plugins={}
+otf.plugins=plugins
+local report=logs.reporter("fonts")
+function otf.registerplugin(name,f)
+ if type(name)=="string" and type(f)=="function" then
+ plugins[name]={ name,f }
+ report()
+ report("plugin %a has been loaded, please be aware of possible side effects",name)
+ report()
+ if logs.pushtarget then
+ logs.pushtarget("log")
+ end
+ report("Plugins are not officially supported unless stated otherwise. This is because")
+ report("they bypass the regular font handling and therefore some features in ConTeXt")
+ report("(especially those related to fonts) might not work as expected or might not work")
+ report("at all. Some plugins are for testing and development only and might change")
+ report("whenever we feel the need for it.")
+ report()
+ if logs.poptarget then
+ logs.poptarget()
+ end
+ end
+end
+function otf.plugininitializer(tfmdata,value)
+ if type(value)=="string" then
+ tfmdata.shared.plugin=plugins[value]
+ end
+end
+function otf.pluginprocessor(head,font,attr,direction)
+ local s=fontdata[font].shared
+ local p=s and s.plugin
+ if p then
+ if trace_plugins then
+ report_process("applying plugin %a",p[1])
+ end
+ return p[2](head,font,attr,direction)
+ else
+ return head,false
+ end
+end
+function otf.featuresinitializer(tfmdata,value)
+end
+registerotffeature {
+ name="features",
+ description="features",
+ default=true,
+ initializers={
+ position=1,
+ node=otf.featuresinitializer,
+ plug=otf.plugininitializer,
+ },
+ processors={
+ node=otf.featuresprocessor,
+ plug=otf.pluginprocessor,
+ }
+}
+otf.handlers=handlers
+local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end
+local tag="kern"
+if fontfeatures then
+ function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr)
+ local features=fontfeatures[font]
+ local enabled=features and features.spacekern and features[tag]
+ if enabled then
+ setspacekerns(font,sequence)
+ end
+ return head,enabled
+ end
+else
+ function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr)
+ local shared=fontdata[font].shared
+ local features=shared and shared.features
+ local enabled=features and features.spacekern and features[tag]
+ if enabled then
+ setspacekerns(font,sequence)
+ end
+ return head,enabled
+ end
+end
+local function hasspacekerns(data)
+ local resources=data.resources
+ local sequences=resources.sequences
+ local validgpos=resources.features.gpos
+ if validgpos and sequences then
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ if steps and sequence.features[tag] then
+ local kind=sequence.type
+ if kind=="gpos_pair" or kind=="gpos_single" then
+ for i=1,#steps do
+ local step=steps[i]
+ local coverage=step.coverage
+ local rules=step.rules
+ if rules then
+ elseif not coverage then
+ elseif kind=="gpos_single" then
+ elseif kind=="gpos_pair" then
+ local format=step.format
+ if format=="move" or format=="kern" then
+ local kerns=coverage[32]
+ if kerns then
+ return true
+ end
+ for k,v in next,coverage do
+ if v[32] then
+ return true
+ end
+ end
+ elseif format=="pair" then
+ local kerns=coverage[32]
+ if kerns then
+ for k,v in next,kerns do
+ local one=v[1]
+ if one and one~=true then
+ return true
+ end
+ end
+ end
+ for k,v in next,coverage do
+ local kern=v[32]
+ if kern then
+ local one=kern[1]
+ if one and one~=true then
+ return true
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return false
+end
+otf.readers.registerextender {
+ name="spacekerns",
+ action=function(data)
+ data.properties.hasspacekerns=hasspacekerns(data)
+ end
+}
+local function spaceinitializer(tfmdata,value)
+ local resources=tfmdata.resources
+ local spacekerns=resources and resources.spacekerns
+ if value and spacekerns==nil then
+ local rawdata=tfmdata.shared and tfmdata.shared.rawdata
+ local properties=rawdata.properties
+ if properties and properties.hasspacekerns then
+ local sequences=resources.sequences
+ local validgpos=resources.features.gpos
+ if validgpos and sequences then
+ local left={}
+ local right={}
+ local last=0
+ local feat=nil
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ if steps then
+ local kern=sequence.features[tag]
+ if kern then
+ local kind=sequence.type
+ if kind=="gpos_pair" or kind=="gpos_single" then
+ if feat then
+ for script,languages in next,kern do
+ local f=feat[script]
+ if f then
+ for l in next,languages do
+ f[l]=true
+ end
+ else
+ feat[script]=languages
+ end
+ end
+ else
+ feat=kern
+ end
+ for i=1,#steps do
+ local step=steps[i]
+ local coverage=step.coverage
+ local rules=step.rules
+ if rules then
+ elseif not coverage then
+ elseif kind=="gpos_single" then
+ elseif kind=="gpos_pair" then
+ local format=step.format
+ if format=="move" or format=="kern" then
+ local kerns=coverage[32]
+ if kerns then
+ for k,v in next,kerns do
+ right[k]=v
+ end
+ end
+ for k,v in next,coverage do
+ local kern=v[32]
+ if kern then
+ left[k]=kern
+ end
+ end
+ elseif format=="pair" then
+ local kerns=coverage[32]
+ if kerns then
+ for k,v in next,kerns do
+ local one=v[1]
+ if one and one~=true then
+ right[k]=one[3]
+ end
+ end
+ end
+ for k,v in next,coverage do
+ local kern=v[32]
+ if kern then
+ local one=kern[1]
+ if one and one~=true then
+ left[k]=one[3]
+ end
+ end
+ end
+ end
+ end
+ end
+ last=i
+ end
+ else
+ end
+ end
+ end
+ left=next(left) and left or false
+ right=next(right) and right or false
+ if left or right then
+ spacekerns={
+ left=left,
+ right=right,
+ }
+ if last>0 then
+ local triggersequence={
+ features={ [tag]=feat or { dflt={ dflt=true,} } },
+ flags=noflags,
+ name="trigger_space_kerns",
+ order={ tag },
+ type="trigger_space_kerns",
+ left=left,
+ right=right,
+ }
+ insert(sequences,last,triggersequence)
+ end
+ end
+ end
+ end
+ resources.spacekerns=spacekerns
+ end
+ return spacekerns
+end
+registerotffeature {
+ name="spacekern",
+ description="space kern injection",
+ default=true,
+ initializers={
+ node=spaceinitializer,
+ },
+}
+local function markinitializer(tfmdata,value)
+ local properties=tfmdata.properties
+ properties.checkmarks=value
+end
+registerotffeature {
+ name="checkmarks",
+ description="check mark widths",
+ default=true,
+ initializers={
+ node=markinitializer,
+ },
+}
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-osd']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Kai Eigner, TAT Zetwerk / Hans Hagen, PRAGMA ADE",
+ copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local insert,imerge,copy,tohash=table.insert,table.imerge,table.copy,table.tohash
+local next,type=next,type
+local report=logs.reporter("otf","devanagari")
+fonts=fonts or {}
+fonts.analyzers=fonts.analyzers or {}
+fonts.analyzers.methods=fonts.analyzers.methods or { node={ otf={} } }
+local otf=fonts.handlers.otf
+local handlers=otf.handlers
+local methods=fonts.analyzers.methods
+local otffeatures=fonts.constructors.features.otf
+local registerotffeature=otffeatures.register
+local nuts=nodes.nuts
+local getnext=nuts.getnext
+local getprev=nuts.getprev
+local getboth=nuts.getboth
+local getid=nuts.getid
+local getchar=nuts.getchar
+local getfont=nuts.getfont
+local getsubtype=nuts.getsubtype
+local setlink=nuts.setlink
+local setnext=nuts.setnext
+local setprev=nuts.setprev
+local setchar=nuts.setchar
+local getprop=nuts.getprop
+local setprop=nuts.setprop
+local ischar=nuts.ischar
+local insert_node_after=nuts.insert_after
+local copy_node=nuts.copy
+local remove_node=nuts.remove
+local flush_list=nuts.flush_list
+local flush_node=nuts.flush_node
+local copyinjection=nodes.injections.copy
+local unsetvalue=attributes.unsetvalue
+local fontdata=fonts.hashes.identifiers
+local a_state=attributes.private('state')
+local a_syllabe=attributes.private('syllabe')
+local dotted_circle=0x25CC
+local c_nbsp=0x00A0
+local c_zwnj=0x200C
+local c_zwj=0x200D
+local states=fonts.analyzers.states
+local s_rphf=states.rphf
+local s_half=states.half
+local s_pref=states.pref
+local s_blwf=states.blwf
+local s_pstf=states.pstf
+local s_init=states.init
+local replace_all_nbsp=nil
+replace_all_nbsp=function(head)
+ replace_all_nbsp=typesetters and typesetters.characters and typesetters.characters.replacenbspaces or function(head)
+ return head
+ end
+ return replace_all_nbsp(head)
+end
+local processcharacters=nil
+if context then
+
+--removed
+
+else
+ function processcharacters(head,font)
+ local processors=fontdata[font].shared.processes
+ for i=1,#processors do
+ head=processors[i](head,font,0)
+ end
+ return head
+ end
+end
+local indicgroups=characters and characters.indicgroups
+if not indicgroups and characters then
+ local indic={
+ c={},
+ i={},
+ d={},
+ m={},
+ s={},
+ o={},
+ }
+ local indicmarks={
+ l={},
+ t={},
+ b={},
+ r={},
+ s={},
+ }
+ local indicclasses={
+ nukta={},
+ halant={},
+ ra={},
+ anudatta={},
+ }
+ local indicorders={
+ bp={},
+ ap={},
+ bs={},
+ as={},
+ bh={},
+ ah={},
+ bm={},
+ am={},
+ }
+ for k,v in next,characters.data do
+ local i=v.indic
+ if i then
+ indic[i][k]=true
+ i=v.indicmark
+ if i then
+ if i=="s" then
+ local s=v.specials
+ indicmarks[i][k]={ s[2],s[3] }
+ else
+ indicmarks[i][k]=true
+ end
+ end
+ i=v.indicclass
+ if i then
+ indicclasses[i][k]=true
+ end
+ i=v.indicorder
+ if i then
+ indicorders[i][k]=true
+ end
+ end
+ end
+ indicgroups={
+ consonant=indic.c,
+ independent_vowel=indic.i,
+ dependent_vowel=indic.d,
+ vowel_modifier=indic.m,
+ stress_tone_mark=indic.s,
+ pre_mark=indicmarks.l,
+ above_mark=indicmarks.t,
+ below_mark=indicmarks.b,
+ post_mark=indicmarks.r,
+ twopart_mark=indicmarks.s,
+ nukta=indicclasses.nukta,
+ halant=indicclasses.halant,
+ ra=indicclasses.ra,
+ anudatta=indicclasses.anudatta,
+ before_postscript=indicorders.bp,
+ after_postscript=indicorders.ap,
+ before_half=indicorders.bh,
+ after_half=indicorders.ah,
+ before_subscript=indicorders.bs,
+ after_subscript=indicorders.as,
+ before_main=indicorders.bm,
+ after_main=indicorders.am,
+ }
+ indic=nil
+ indicmarks=nil
+ indicclasses=nil
+ indicorders=nil
+ characters.indicgroups=indicgroups
+end
+local consonant=indicgroups.consonant
+local independent_vowel=indicgroups.independent_vowel
+local dependent_vowel=indicgroups.dependent_vowel
+local vowel_modifier=indicgroups.vowel_modifier
+local stress_tone_mark=indicgroups.stress_tone_mark
+local pre_mark=indicgroups.pre_mark
+local above_mark=indicgroups.above_mark
+local below_mark=indicgroups.below_mark
+local post_mark=indicgroups.post_mark
+local twopart_mark=indicgroups.twopart_mark
+local nukta=indicgroups.nukta
+local halant=indicgroups.halant
+local ra=indicgroups.ra
+local anudatta=indicgroups.anudatta
+local before_postscript=indicgroups.before_postscript
+local after_postscript=indicgroups.after_postscript
+local before_half=indicgroups.before_half
+local after_half=indicgroups.after_half
+local before_subscript=indicgroups.before_subscript
+local after_subscript=indicgroups.after_subscript
+local before_main=indicgroups.before_main
+local after_main=indicgroups.after_main
+local mark_four=table.merged (
+ pre_mark,
+ above_mark,
+ below_mark,
+ post_mark
+)
+local mark_above_below_post=table.merged (
+ above_mark,
+ below_mark,
+ post_mark
+)
+local zw_char={
+ [c_zwnj]=true,
+ [c_zwj ]=true,
+}
+local dflt_true={
+ dflt=true,
+}
+local two_defaults={}
+local one_defaults={}
+local false_flags={ false,false,false,false }
+local sequence_reorder_matras={
+ features={ dv01=two_defaults },
+ flags=false_flags,
+ name="dv01_reorder_matras",
+ order={ "dv01" },
+ type="devanagari_reorder_matras",
+ nofsteps=1,
+ steps={
+ {
+ coverage=pre_mark,
+ }
+ }
+}
+local sequence_reorder_reph={
+ features={ dv02=two_defaults },
+ flags=false_flags,
+ name="dv02_reorder_reph",
+ order={ "dv02" },
+ type="devanagari_reorder_reph",
+ nofsteps=1,
+ steps={
+ {
+ coverage={},
+ }
+ }
+}
+local sequence_reorder_pre_base_reordering_consonants={
+ features={ dv03=one_defaults },
+ flags=false_flags,
+ name="dv03_reorder_pre_base_reordering_consonants",
+ order={ "dv03" },
+ type="devanagari_reorder_pre_base_reordering_consonants",
+ nofsteps=1,
+ steps={
+ {
+ coverage={},
+ }
+ }
+}
+local sequence_remove_joiners={
+ features={ dv04=one_defaults },
+ flags=false_flags,
+ name="dv04_remove_joiners",
+ order={ "dv04" },
+ type="devanagari_remove_joiners",
+ nofsteps=1,
+ steps={
+ {
+ coverage=zw_char,
+ },
+ }
+}
+local basic_shaping_forms={
+ akhn=true,
+ blwf=true,
+ cjct=true,
+ half=true,
+ nukt=true,
+ pref=true,
+ pstf=true,
+ rkrf=true,
+ rphf=true,
+ vatu=true,
+ locl=true,
+}
+local valid={
+ abvs=true,
+ akhn=true,
+ blwf=true,
+ calt=true,
+ cjct=true,
+ half=true,
+ haln=true,
+ nukt=true,
+ pref=true,
+ pres=true,
+ pstf=true,
+ psts=true,
+ rkrf=true,
+ rphf=true,
+ vatu=true,
+ pres=true,
+ abvs=true,
+ blws=true,
+ psts=true,
+ haln=true,
+ calt=true,
+ locl=true,
+}
+local scripts={}
+local scripts_one={ "deva","mlym","beng","gujr","guru","knda","orya","taml","telu" }
+local scripts_two={ "dev2","mlm2","bng2","gjr2","gur2","knd2","ory2","tml2","tel2" }
+local nofscripts=#scripts_one
+for i=1,nofscripts do
+ local one=scripts_one[i]
+ local two=scripts_two[i]
+ scripts[one]=true
+ scripts[two]=true
+ two_defaults[two]=dflt_true
+ one_defaults[one]=dflt_true
+ one_defaults[two]=dflt_true
+end
+local function valid_one(s) for i=1,nofscripts do if s[scripts_one[i]] then return true end end end
+local function valid_two(s) for i=1,nofscripts do if s[scripts_two[i]] then return true end end end
+local function initializedevanagi(tfmdata)
+ local script,language=otf.scriptandlanguage(tfmdata,attr)
+ if scripts[script] then
+ local resources=tfmdata.resources
+ local devanagari=resources.devanagari
+ if not devanagari then
+ report("adding devanagari features to font")
+ local gsubfeatures=resources.features.gsub
+ local sequences=resources.sequences
+ local sharedfeatures=tfmdata.shared.features
+ gsubfeatures["dv01"]=two_defaults
+ gsubfeatures["dv02"]=two_defaults
+ gsubfeatures["dv03"]=one_defaults
+ gsubfeatures["dv04"]=one_defaults
+ local reorder_pre_base_reordering_consonants=copy(sequence_reorder_pre_base_reordering_consonants)
+ local reorder_reph=copy(sequence_reorder_reph)
+ local reorder_matras=copy(sequence_reorder_matras)
+ local remove_joiners=copy(sequence_remove_joiners)
+ local lastmatch=0
+ for s=1,#sequences do
+ local features=sequences[s].features
+ if features then
+ for k,v in next,features do
+ if k=="locl" then
+ local steps=sequences[s].steps
+ local nofsteps=sequences[s].nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ for k,v in next,pre_mark do
+ local locl=coverage[k]
+ if locl then
+ if #locl>0 then
+ for j=1,#locl do
+ local ck=locl[j]
+ local f=ck[4]
+ local chainlookups=ck[6]
+ if chainlookups then
+ local chainlookup=chainlookups[f]
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ local steps=chainstep.steps
+ local nofsteps=chainstep.nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ locl=coverage[k]
+ end
+ end
+ end
+ end
+ end
+ end
+ if locl then
+ reorder_matras.steps[1].coverage[locl]=true
+ end
+ end
+ end
+ end
+ end
+ end
+ if basic_shaping_forms[k] then
+ lastmatch=lastmatch+1
+ if s~=lastmatch then
+ table.insert(sequences,lastmatch,table.remove(sequences,s))
+ end
+ end
+ end
+ end
+ end
+ local insertindex=lastmatch+1
+ if tfmdata.properties.language then
+ dflt_true[tfmdata.properties.language]=true
+ end
+ insert(sequences,insertindex,reorder_pre_base_reordering_consonants)
+ insert(sequences,insertindex,reorder_reph)
+ insert(sequences,insertindex,reorder_matras)
+ insert(sequences,insertindex,remove_joiners)
+ local blwfcache={}
+ local vatucache={}
+ local pstfcache={}
+ local seqsubset={}
+ local rephstep={
+ coverage={}
+ }
+ local devanagari={
+ reph=false,
+ vattu=false,
+ blwfcache=blwfcache,
+ vatucache=vatucache,
+ pstfcache=pstfcache,
+ seqsubset=seqsubset,
+ reorderreph=rephstep,
+ }
+ reorder_reph.steps={ rephstep }
+ local pre_base_reordering_consonants={}
+ reorder_pre_base_reordering_consonants.steps[1].coverage=pre_base_reordering_consonants
+ resources.devanagari=devanagari
+ for s=1,#sequences do
+ local sequence=sequences[s]
+ local steps=sequence.steps
+ local nofsteps=sequence.nofsteps
+ local features=sequence.features
+ local has_rphf=features.rphf
+ local has_blwf=features.blwf
+ local has_vatu=features.vatu
+ local has_pstf=features.pstf
+ if has_rphf and has_rphf[script] then
+ devanagari.reph=true
+ elseif (has_blwf and has_blwf[script] ) or (has_vatu and has_vatu[script] ) then
+ devanagari.vattu=true
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ for k,v in next,coverage do
+ for h,w in next,halant do
+ if v[h] then
+ if not blwfcache[k] then
+ blwfcache[k]=v
+ end
+ end
+ if has_vatu and has_vatu[script] and not vatucache[k] then
+ vatucache[k]=v
+ end
+ end
+ end
+ end
+ end
+ elseif has_pstf and has_pstf[script] then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ for k,v in next,coverage do
+ if not pstfcache[k] then
+ pstfcache[k]=v
+ end
+ end
+ for k,v in next,ra do
+ local r=coverage[k]
+ if r then
+ local found=false
+ if #r>0 then
+ for j=1,#r do
+ local ck=r[j]
+ local f=ck[4]
+ local chainlookups=ck[6]
+ if chainlookups and chainlookups[f] then
+ local chainlookup=chainlookups[f]
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ local steps=chainstep.steps
+ local nofsteps=chainstep.nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ local h=coverage[k]
+ if h then
+ for k,v in next,h do
+ found=v and v.ligature
+ if found then
+ pre_base_reordering_consonants[found]=true
+ break
+ end
+ end
+ if found then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ else
+ for k,v in next,r do
+ found=v and v.ligature
+ if found then
+ pre_base_reordering_consonants[found]=true
+ break
+ end
+ end
+ end
+ if found then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ for kind,spec in next,features do
+ if valid[kind] and valid_two(spec)then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ local reph,rephbase=false,false
+ if kind=="rphf" then
+ for k,v in next,ra do
+ local r=coverage[k]
+ if r then
+ rephbase=k
+ local h=false
+ if #r>0 then
+ for j=1,#r do
+ local ck=r[j]
+ local f=ck[4]
+ local chainlookups=ck[6]
+ if chainlookups then
+ local chainlookup=chainlookups[f]
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ local steps=chainstep.steps
+ local nofsteps=chainstep.nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ local r=coverage[k]
+ if r then
+ for k,v in next,halant do
+ local h=r[k]
+ if h then
+ reph=h.ligature or false
+ break
+ end
+ end
+ if h then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ else
+ for k,v in next,halant do
+ local h=r[k]
+ if h then
+ reph=h.ligature or false
+ break
+ end
+ end
+ end
+ if reph then
+ break
+ end
+ end
+ end
+ end
+ seqsubset[#seqsubset+1]={ kind,coverage,reph,rephbase }
+ end
+ end
+ end
+ if kind=="pref" then
+ local steps=sequence.steps
+ local nofsteps=sequence.nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ for k,v in next,halant do
+ local h=coverage[k]
+ if h then
+ local found=false
+ if #h>0 then
+ for j=1,#h do
+ local ck=h[j]
+ local f=ck[4]
+ local chainlookups=ck[6]
+ if chainlookups then
+ local chainlookup=chainlookups[f]
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ local steps=chainstep.steps
+ local nofsteps=chainstep.nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ local h=coverage[k]
+ if h then
+ for k,v in next,h do
+ found=v and v.ligature
+ if found then
+ pre_base_reordering_consonants[found]=true
+ break
+ end
+ end
+ if found then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ else
+ for k,v in next,h do
+ found=v and v.ligature
+ if found then
+ pre_base_reordering_consonants[found]=true
+ break
+ end
+ end
+ end
+ if found then
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if two_defaults[script] then
+ sharedfeatures["dv01"]=true
+ sharedfeatures["dv02"]=true
+ sharedfeatures["dv03"]=true
+ sharedfeatures["dv04"]=true
+ elseif one_defaults[script] then
+ sharedfeatures["dv03"]=true
+ sharedfeatures["dv04"]=true
+ end
+ if script=="mlym" or script=="taml" then
+ devanagari.left_matra_before_base=true
+ end
+ end
+ end
+end
+registerotffeature {
+ name="devanagari",
+ description="inject additional features",
+ default=true,
+ initializers={
+ node=initializedevanagi,
+ },
+}
+local show_syntax_errors=false
+local function inject_syntax_error(head,current,char)
+ local signal=copy_node(current)
+ copyinjection(signal,current)
+ if pre_mark[char] then
+ setchar(signal,dotted_circle)
+ else
+ setchar(current,dotted_circle)
+ end
+ return insert_node_after(head,current,signal)
+end
+local function initialize_one(font,attr)
+ local tfmdata=fontdata[font]
+ local datasets=otf.dataset(tfmdata,font,attr)
+ local devanagaridata=datasets.devanagari
+ if not devanagaridata then
+ devanagaridata={
+ reph=false,
+ vattu=false,
+ blwfcache={},
+ vatucache={},
+ pstfcache={},
+ }
+ datasets.devanagari=devanagaridata
+ local resources=tfmdata.resources
+ local devanagari=resources.devanagari
+ for s=1,#datasets do
+ local dataset=datasets[s]
+ if dataset and dataset[1] then
+ local kind=dataset[4]
+ if kind=="rphf" then
+ devanagaridata.reph=true
+ elseif kind=="blwf" or kind=="vatu" then
+ devanagaridata.vattu=true
+ devanagaridata.blwfcache=devanagari.blwfcache
+ devanagaridata.vatucache=devanagari.vatucache
+ devanagaridata.pstfcache=devanagari.pstfcache
+ end
+ end
+ end
+ end
+ return devanagaridata.reph,devanagaridata.vattu,devanagaridata.blwfcache,devanagaridata.vatucache,devanagaridata.pstfcache
+end
+local function contextchain(contexts,n)
+ local char=getchar(n)
+ for k=1,#contexts do
+ local ck=contexts[k]
+ local seq=ck[3]
+ local f=ck[4]
+ local l=ck[5]
+ if (l-f)==1 and seq[f+1][char] then
+ local ok=true
+ local c=n
+ for i=l+1,#seq do
+ c=getnext(c)
+ if not c or not seq[i][ischar(c)] then
+ ok=false
+ break
+ end
+ end
+ if ok then
+ c=getprev(n)
+ for i=1,f-1 do
+ c=getprev(c)
+ if not c or not seq[f-i][ischar(c)] then
+ ok=false
+ end
+ end
+ end
+ if ok then
+ return true
+ end
+ end
+ end
+ return false
+end
+local function order_matras(c)
+ local cn=getnext(c)
+ local char=getchar(cn)
+ while dependent_vowel[char] do
+ local next=getnext(cn)
+ local cc=c
+ local cchar=getchar(cc)
+ while cc~=cn do
+ if (above_mark[char] and (below_mark[cchar] or post_mark[cchar])) or (below_mark[char] and (post_mark[cchar])) then
+ local prev,next=getboth(cn)
+ if next then
+ setprev(next,prev)
+ end
+ setnext(prev,next)
+ setnext(getprev(cc),cn)
+ setprev(cn,getprev(cc))
+ setnext(cn,cc)
+ setprev(cc,cn)
+ break
+ end
+ cc=getnext(cc)
+ cchar=getchar(cc)
+ end
+ cn=next
+ char=getchar(cn)
+ end
+end
+local function reorder_one(head,start,stop,font,attr,nbspaces)
+ local reph,vattu,blwfcache,vatucache,pstfcache=initialize_one(font,attr)
+ local devanagari=fontdata[font].resources.devanagari
+ local current=start
+ local n=getnext(start)
+ local base=nil
+ local firstcons=nil
+ local lastcons=nil
+ local basefound=false
+ if reph and ra[getchar(start)] and halant[getchar(n)] then
+ if n==stop then
+ return head,stop,nbspaces
+ end
+ if getchar(getnext(n))==c_zwj then
+ current=start
+ else
+ current=getnext(n)
+ setprop(start,a_state,s_rphf)
+ end
+ end
+ if getchar(current)==c_nbsp then
+ if current==stop then
+ stop=getprev(stop)
+ head=remove_node(head,current)
+ flush_node(current)
+ return head,stop,nbspaces
+ else
+ nbspaces=nbspaces+1
+ base=current
+ firstcons=current
+ lastcons=current
+ current=getnext(current)
+ if current~=stop then
+ local char=getchar(current)
+ if nukta[char] then
+ current=getnext(current)
+ char=getchar(current)
+ end
+ if char==c_zwj and current~=stop then
+ local next=getnext(current)
+ if next~=stop and halant[getchar(next)] then
+ current=next
+ next=getnext(current)
+ local tmp=next and getnext(next) or nil
+ local changestop=next==stop
+ local tempcurrent=copy_node(next)
+ copyinjection(tempcurrent,next)
+ local nextcurrent=copy_node(current)
+ copyinjection(nextcurrent,current)
+ setlink(tempcurrent,nextcurrent)
+ setprop(tempcurrent,a_state,s_blwf)
+ tempcurrent=processcharacters(tempcurrent,font)
+ setprop(tempcurrent,a_state,unsetvalue)
+ if getchar(next)==getchar(tempcurrent) then
+ flush_list(tempcurrent)
+ if show_syntax_errors then
+ head,current=inject_syntax_error(head,current,char)
+ end
+ else
+ setchar(current,getchar(tempcurrent))
+ local freenode=getnext(current)
+ setlink(current,tmp)
+ flush_node(freenode)
+ flush_list(tempcurrent)
+ if changestop then
+ stop=current
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ while not basefound do
+ local char=getchar(current)
+ if consonant[char] then
+ setprop(current,a_state,s_half)
+ if not firstcons then
+ firstcons=current
+ end
+ lastcons=current
+ if not base then
+ base=current
+ elseif blwfcache[char] then
+ setprop(current,a_state,s_blwf)
+ elseif pstfcache[char] then
+ setprop(current,a_state,s_pstf)
+ else
+ base=current
+ end
+ end
+ basefound=current==stop
+ current=getnext(current)
+ end
+ if base~=lastcons then
+ local np=base
+ local n=getnext(base)
+ local ch=getchar(n)
+ if nukta[ch] then
+ np=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ if halant[ch] then
+ if lastcons~=stop then
+ local ln=getnext(lastcons)
+ if nukta[getchar(ln)] then
+ lastcons=ln
+ end
+ end
+ local nn=getnext(n)
+ local ln=getnext(lastcons)
+ setlink(np,nn)
+ setnext(lastcons,n)
+ if ln then
+ setprev(ln,n)
+ end
+ setnext(n,ln)
+ setprev(n,lastcons)
+ if lastcons==stop then
+ stop=n
+ end
+ end
+ end
+ n=getnext(start)
+ if n~=stop and ra[getchar(start)] and halant[getchar(n)] and not zw_char[getchar(getnext(n))] then
+ local matra=base
+ if base~=stop then
+ local next=getnext(base)
+ if dependent_vowel[getchar(next)] then
+ matra=next
+ end
+ end
+ local sp=getprev(start)
+ local nn=getnext(n)
+ local mn=getnext(matra)
+ setlink(sp,nn)
+ setlink(matra,start)
+ setlink(n,mn)
+ if head==start then
+ head=nn
+ end
+ start=nn
+ if matra==stop then
+ stop=n
+ end
+ end
+ local current=start
+ while current~=stop do
+ local next=getnext(current)
+ if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then
+ setprop(current,a_state,unsetvalue)
+ end
+ current=next
+ end
+ if base~=stop and getprop(base,a_state) then
+ local next=getnext(base)
+ if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then
+ setprop(base,a_state,unsetvalue)
+ end
+ end
+ local current,allreordered,moved=start,false,{ [base]=true }
+ local a,b,p,bn=base,base,base,getnext(base)
+ if base~=stop and nukta[getchar(bn)] then
+ a,b,p=bn,bn,bn
+ end
+ while not allreordered do
+ local c=current
+ local n=getnext(current)
+ local l=nil
+ if c~=stop then
+ local ch=getchar(n)
+ if nukta[ch] then
+ c=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ if c~=stop then
+ if halant[ch] then
+ c=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ local tpm=twopart_mark[ch]
+ while tpm do
+ local extra=copy_node(n)
+ copyinjection(extra,n)
+ ch=tpm[1]
+ setchar(n,ch)
+ setchar(extra,tpm[2])
+ head=insert_node_after(head,current,extra)
+ tpm=twopart_mark[ch]
+ end
+ while c~=stop and dependent_vowel[ch] do
+ c=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ if c~=stop then
+ if vowel_modifier[ch] then
+ c=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ if c~=stop and stress_tone_mark[ch] then
+ c=n
+ n=getnext(n)
+ end
+ end
+ end
+ end
+ local bp=getprev(firstcons)
+ local cn=getnext(current)
+ local last=getnext(c)
+ while cn~=last do
+ if pre_mark[getchar(cn)] then
+ if devanagari.left_matra_before_base then
+ local prev,next=getboth(cn)
+ setlink(prev,next)
+ if cn==stop then
+ stop=getprev(cn)
+ end
+ if base==start then
+ if head==start then
+ head=cn
+ end
+ start=cn
+ end
+ setlink(getprev(base),cn)
+ setlink(cn,base)
+ cn=next
+ else
+ if bp then
+ setnext(bp,cn)
+ end
+ local prev,next=getboth(cn)
+ if next then
+ setprev(next,prev)
+ end
+ setnext(prev,next)
+ if cn==stop then
+ stop=prev
+ end
+ setprev(cn,bp)
+ setlink(cn,firstcons)
+ if firstcons==start then
+ if head==start then
+ head=cn
+ end
+ start=cn
+ end
+ cn=next
+ end
+ elseif current~=base and dependent_vowel[getchar(cn)] then
+ local prev,next=getboth(cn)
+ if next then
+ setprev(next,prev)
+ end
+ setnext(prev,next)
+ if cn==stop then
+ stop=prev
+ end
+ setlink(b,cn,getnext(b))
+ order_matras(cn)
+ cn=next
+ elseif current==base and dependent_vowel[getchar(cn)] then
+ local cnn=getnext(cn)
+ order_matras(cn)
+ cn=cnn
+ while cn~=last and dependent_vowel[getchar(cn)] do
+ cn=getnext(cn)
+ end
+ else
+ cn=getnext(cn)
+ end
+ end
+ allreordered=c==stop
+ current=getnext(c)
+ end
+ if reph or vattu then
+ local current,cns=start,nil
+ while current~=stop do
+ local c=current
+ local n=getnext(current)
+ if ra[getchar(current)] and halant[getchar(n)] then
+ c=n
+ n=getnext(n)
+ local b,bn=base,base
+ while bn~=stop do
+ local next=getnext(bn)
+ if dependent_vowel[getchar(next)] then
+ b=next
+ end
+ bn=next
+ end
+ if getprop(current,a_state)==s_rphf then
+ if b~=current then
+ if current==start then
+ if head==start then
+ head=n
+ end
+ start=n
+ end
+ if b==stop then
+ stop=c
+ end
+ local prev=getprev(current)
+ setlink(prev,n)
+ local next=getnext(b)
+ setlink(c,next)
+ setlink(b,current)
+ end
+ elseif cns and getnext(cns)~=current then
+ local cp=getprev(current)
+ local cnsn=getnext(cns)
+ setlink(cp,n)
+ setlink(cns,current)
+ setlink(c,cnsn)
+ if c==stop then
+ stop=cp
+ break
+ end
+ current=getprev(n)
+ end
+ else
+ local char=getchar(current)
+ if consonant[char] then
+ cns=current
+ local next=getnext(cns)
+ if halant[getchar(next)] then
+ cns=next
+ end
+ if not vatucache[char] then
+ next=getnext(cns)
+ while dependent_vowel[getchar(next)] do
+ cns=next
+ next=getnext(cns)
+ end
+ end
+ elseif char==c_nbsp then
+ nbspaces=nbspaces+1
+ cns=current
+ local next=getnext(cns)
+ if halant[getchar(next)] then
+ cns=next
+ end
+ if not vatucache[char] then
+ next=getnext(cns)
+ while dependent_vowel[getchar(next)] do
+ cns=next
+ next=getnext(cns)
+ end
+ end
+ end
+ end
+ current=getnext(current)
+ end
+ end
+ if getchar(base)==c_nbsp then
+ nbspaces=nbspaces-1
+ if base==stop then
+ stop=getprev(stop)
+ end
+ head=remove_node(head,base)
+ flush_node(base)
+ end
+ return head,stop,nbspaces
+end
+function handlers.devanagari_reorder_matras(head,start)
+ local current=start
+ local startfont=getfont(start)
+ local startattr=getprop(start,a_syllabe)
+ while current do
+ local char=ischar(current,startfont)
+ local next=getnext(current)
+ if char and getprop(current,a_syllabe)==startattr then
+ if halant[char] then
+ if next then
+ local char=ischar(next,startfont)
+ if char and zw_char[char] and getprop(next,a_syllabe)==startattr then
+ current=next
+ next=getnext(current)
+ end
+ end
+ local startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(start,next)
+ setlink(current,start)
+ start=startnext
+ break
+ end
+ else
+ break
+ end
+ current=next
+ end
+ return head,start,true
+end
+local rephbase={}
+function handlers.devanagari_reorder_reph(head,start)
+ local current=getnext(start)
+ local startnext=nil
+ local startprev=nil
+ local startfont=getfont(start)
+ local startattr=getprop(start,a_syllabe)
+ ::step_1::
+ local char=ischar(start,startfont)
+ local rephbase=rephbase[startfont][char]
+ if char and after_subscript[rephbase] then
+ goto step_5
+ end
+ ::step_2::
+ if char and not after_postscript[rephbase] then
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ if halant[char] then
+ local next=getnext(current)
+ if next then
+ local nextchar=ischar(next,startfont)
+ if nextchar and zw_char[nextchar] and getprop(next,a_syllabe)==startattr then
+ current=next
+ next=getnext(current)
+ end
+ end
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(start,next)
+ setlink(current,start)
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ break
+ end
+ current=getnext(current)
+ else
+ break
+ end
+ end
+ end
+ ::step_3::
+ if not startnext then
+ if char and after_main[rephbase] then
+ current=getnext(start)
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ if consonant[char] and not getprop(current,a_state)==s_pref then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(current,start)
+ setlink(start,getnext(current))
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ break
+ end
+ current=getnext(current)
+ else
+ break
+ end
+ end
+ end
+ end
+ ::step_4::
+ if not startnext then
+ if char and before_postscript[rephbase] then
+ current=getnext(start)
+ local c=nil
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ if getprop(current,a_state)==s_pstf then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(getprev(current),start)
+ setlink(start,current)
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ break
+ elseif not c and (vowel_modifier[char] or stress_tone_mark[char] ) then
+ c=current
+ end
+ current=getnext(current)
+ else
+ if c then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(getprev(c),start)
+ setlink(start,c)
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ end
+ break
+ end
+ end
+ end
+ end
+ ::step_5::
+ if not startnext then
+ current=getnext(start)
+ local c=nil
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ local state=getprop(current,a_state)
+ if before_subscript[rephbase] and (state==s_blwf or state==s_pstf) then
+ c=current
+ elseif after_subscript[rephbase] and (state==s_pstf) then
+ c=current
+ end
+ current=getnext(current)
+ else
+ break
+ end
+ end
+ if c then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(getprev(c),start)
+ setlink(start,c)
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ end
+ end
+ ::step_6::
+ if not startnext then
+ current=start
+ local next=getnext(current)
+ while next do
+ local nextchar=ischar(next,startfont)
+ if nextchar and getprop(next,a_syllabe)==startattr then
+ current=next
+ next=getnext(current)
+ else
+ break
+ end
+ end
+ if start~=current then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(start,getnext(current))
+ setlink(current,start)
+ start=startnext
+ end
+ end
+ return head,start,true
+end
+local reordered_pre_base_reordering_consonants={}
+function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start)
+ if reordered_pre_base_reordering_consonants[start] then
+ return head,start,true
+ end
+ local current=start
+ local startfont=getfont(start)
+ local startattr=getprop(start,a_syllabe)
+ while current do
+ local char=ischar(current,startfont)
+ local next=getnext(current)
+ if char and getprop(current,a_syllabe)==startattr then
+ if halant[char] then
+ if next then
+ local char=ischar(next,startfont)
+ if char and zw_char[char] and getprop(next,a_syllabe)==startattr then
+ current=next
+ next=getnext(current)
+ end
+ end
+ local startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(start,next)
+ setlink(current,start)
+ reordered_pre_base_reordering_consonants[start]=true
+ start=startnext
+ return head,start,true
+ end
+ else
+ break
+ end
+ current=next
+ end
+ local startattr=getprop(start,a_syllabe)
+ local current=getprev(start)
+ while current and getprop(current,a_syllabe)==startattr do
+ local char=ischar(current)
+ if (not dependent_vowel[char] and not getprop(current,a_state) or getprop(current,a_state)==s_init) then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ if current==head then
+ setlink(start,current)
+ head=start
+ else
+ setlink(getprev(current),start)
+ setlink(start,current)
+ end
+ reordered_pre_base_reordering_consonants[start]=true
+ start=startnext
+ break
+ end
+ current=getprev(current)
+ end
+ return head,start,true
+end
+function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replacement)
+ local stop=getnext(start)
+ local font=getfont(start)
+ local last=start
+ while stop do
+ local char=ischar(stop,font)
+ if char and (char==c_zwnj or char==c_zwj) then
+ last=stop
+ stop=getnext(stop)
+ else
+ break
+ end
+ end
+ local prev=getprev(start)
+ if stop then
+ setnext(last)
+ setlink(prev,stop)
+ elseif prev then
+ setnext(prev)
+ end
+ if head==start then
+ head=stop
+ end
+ flush_list(start)
+ return head,stop,true
+end
+local function initialize_two(font,attr)
+ local devanagari=fontdata[font].resources.devanagari
+ if devanagari then
+ return devanagari.seqsubset or {},devanagari.reorderreph or {}
+ else
+ return {},{}
+ end
+end
+local function reorder_two(head,start,stop,font,attr,nbspaces)
+ local seqsubset,reorderreph=initialize_two(font,attr)
+ local halfpos=nil
+ local basepos=nil
+ local subpos=nil
+ local postpos=nil
+ reorderreph.coverage={}
+ rephbase[font]={}
+ for i=1,#seqsubset do
+ local subset=seqsubset[i]
+ local kind=subset[1]
+ local lookupcache=subset[2]
+ if kind=="rphf" then
+ reorderreph.coverage[subset[3]]=true
+ rephbase[font][subset[3]]=subset[4]
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ if found[getchar(next)] or contextchain(found,next) then
+ local afternext=next~=stop and getnext(next)
+ if afternext and zw_char[getchar(afternext)] then
+ current=afternext
+ elseif current==start then
+ setprop(current,a_state,s_rphf)
+ current=next
+ else
+ current=next
+ end
+ end
+ end
+ end
+ current=getnext(current)
+ end
+ elseif kind=="pref" then
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ if found[getchar(next)] or contextchain(found,next) then
+ if (not getprop(current,a_state) and not getprop(next,a_state)) then
+ setprop(current,a_state,s_pref)
+ setprop(next,a_state,s_pref)
+ current=next
+ end
+ end
+ end
+ end
+ current=getnext(current)
+ end
+ elseif kind=="half" then
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ if found[getchar(next)] or contextchain(found,next) then
+ if next~=stop and getchar(getnext(next))==c_zwnj then
+ current=next
+ elseif (not getprop(current,a_state)) then
+ setprop(current,a_state,s_half)
+ if not halfpos then
+ halfpos=current
+ end
+ end
+ current=getnext(current)
+ end
+ end
+ end
+ current=getnext(current)
+ end
+ elseif kind=="blwf" or kind=="vatu" then
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ if found[getchar(next)] or contextchain(found,next) then
+ if (not getprop(current,a_state) and not getprop(next,a_state)) then
+ setprop(current,a_state,s_blwf)
+ setprop(next,a_state,s_blwf)
+ current=next
+ subpos=current
+ end
+ end
+ end
+ end
+ current=getnext(current)
+ end
+ elseif kind=="pstf" then
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ if found[getchar(next)] or contextchain(found,next) then
+ if (not getprop(current,a_state) and not getprop(next,a_state)) then
+ setprop(current,a_state,s_pstf)
+ setprop(next,a_state,s_pstf)
+ current=next
+ postpos=current
+ end
+ end
+ end
+ end
+ current=getnext(current)
+ end
+ end
+ end
+ local current,base,firstcons=start,nil,nil
+ if getprop(start,a_state)==s_rphf then
+ current=getnext(getnext(start))
+ end
+ if current~=getnext(stop) and getchar(current)==c_nbsp then
+ if current==stop then
+ stop=getprev(stop)
+ head=remove_node(head,current)
+ flush_node(current)
+ return head,stop,nbspaces
+ else
+ nbspaces=nbspaces+1
+ base=current
+ current=getnext(current)
+ if current~=stop then
+ local char=getchar(current)
+ if nukta[char] then
+ current=getnext(current)
+ char=getchar(current)
+ end
+ if char==c_zwj then
+ local next=getnext(current)
+ if current~=stop and next~=stop and halant[getchar(next)] then
+ current=next
+ next=getnext(current)
+ local tmp=getnext(next)
+ local changestop=next==stop
+ setnext(next)
+ setprop(current,a_state,s_pref)
+ current=processcharacters(current,font)
+ setprop(current,a_state,s_blwf)
+ current=processcharacters(current,font)
+ setprop(current,a_state,s_pstf)
+ current=processcharacters(current,font)
+ setprop(current,a_state,unsetvalue)
+ if halant[getchar(current)] then
+ setnext(getnext(current),tmp)
+ if show_syntax_errors then
+ head,current=inject_syntax_error(head,current,char)
+ end
+ else
+ setnext(current,tmp)
+ if changestop then
+ stop=current
+ end
+ end
+ end
+ end
+ end
+ end
+ else
+ local last=getnext(stop)
+ while current~=last do
+ local next=getnext(current)
+ if consonant[getchar(current)] then
+ if not (current~=stop and next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwj) then
+ if not firstcons then
+ firstcons=current
+ end
+ local a=getprop(current,a_state)
+ if not (a==s_blwf or a==s_pstf or (a~=s_rphf and a~=s_blwf and ra[getchar(current)])) then
+ base=current
+ end
+ end
+ end
+ current=next
+ end
+ if not base then
+ base=firstcons
+ end
+ end
+ if not base then
+ if getprop(start,a_state)==s_rphf then
+ setprop(start,a_state,unsetvalue)
+ end
+ return head,stop,nbspaces
+ else
+ if getprop(base,a_state) then
+ setprop(base,a_state,unsetvalue)
+ end
+ basepos=base
+ end
+ if not halfpos then
+ halfpos=base
+ end
+ if not subpos then
+ subpos=base
+ end
+ if not postpos then
+ postpos=subpos or base
+ end
+ local moved={}
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ local char=getchar(current)
+ local target=nil
+ local cn=getnext(current)
+ local tpm=twopart_mark[char]
+ while tpm do
+ local extra=copy_node(current)
+ copyinjection(extra,current)
+ char=tpm[1]
+ setchar(current,char)
+ setchar(extra,tpm[2])
+ head=insert_node_after(head,current,extra)
+ tpm=twopart_mark[char]
+ end
+ if not moved[current] and dependent_vowel[char] then
+ if pre_mark[char] then
+ moved[current]=true
+ local prev,next=getboth(current)
+ setlink(prev,next)
+ if current==stop then
+ stop=getprev(current)
+ end
+ local pos
+ if before_main[char] then
+ pos=basepos
+ else
+ pos=halfpos
+ end
+ local ppos=getprev(pos)
+ while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) do
+ if getprop(ppos,a_state)==s_pref then
+ pos=ppos
+ end
+ ppos=getprev(ppos)
+ end
+ local ppos=getprev(pos)
+ while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) and halant[ischar(ppos)] do
+ ppos=getprev(ppos)
+ if ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) and consonant[ischar(ppos)] then
+ pos=ppos
+ ppos=getprev(ppos)
+ else
+ break
+ end
+ end
+ if pos==start then
+ if head==start then
+ head=current
+ end
+ start=current
+ end
+ setlink(getprev(pos),current)
+ setlink(current,pos)
+ elseif above_mark[char] then
+ target=basepos
+ if subpos==basepos then
+ subpos=current
+ end
+ if postpos==basepos then
+ postpos=current
+ end
+ basepos=current
+ elseif below_mark[char] then
+ target=subpos
+ if postpos==subpos then
+ postpos=current
+ end
+ subpos=current
+ elseif post_mark[char] then
+ local n=getnext(postpos)
+ while n do
+ local v=ischar(n,font)
+ if nukta[v] or stress_tone_mark[v] or vowel_modifier[v] then
+ postpos=n
+ else
+ break
+ end
+ n=getnext(n)
+ end
+ target=postpos
+ postpos=current
+ end
+ if mark_above_below_post[char] then
+ local prev=getprev(current)
+ if prev~=target then
+ local next=getnext(current)
+ setlink(prev,next)
+ if current==stop then
+ stop=prev
+ end
+ setlink(current,getnext(target))
+ setlink(target,current)
+ end
+ end
+ end
+ current=cn
+ end
+ local current=getnext(start)
+ local last=getnext(stop)
+ while current~=last do
+ local char=getchar(current)
+ local cn=getnext(current)
+ if halant[char] and ra[ischar(cn)] and getprop(cn,a_state)~=s_rphf and getprop(cn,a_state)~=s_blwf then
+ if after_main[ischar(cn)] then
+ local prev=getprev(current)
+ local next=getnext(cn)
+ local bpn=getnext(basepos)
+ while bpn and dependent_vowel[ischar(bpn)] do
+ basepos=bpn
+ bpn=getnext(bpn)
+ end
+ if basepos~=prev then
+ setlink(prev,next)
+ setlink(cn,getnext(basepos))
+ setlink(basepos,current)
+ if cn==stop then
+ stop=prev
+ end
+ cn=next
+ end
+ end
+ end
+ current=cn
+ end
+ local current=start
+ local c=nil
+ while current~=stop do
+ local char=getchar(current)
+ if halant[char] or stress_tone_mark[char] then
+ if not c then
+ c=current
+ end
+ else
+ c=nil
+ end
+ local next=getnext(current)
+ if c and nukta[getchar(next)] then
+ if head==c then
+ head=next
+ end
+ if stop==next then
+ stop=current
+ end
+ setlink(getprev(c),next)
+ local nextnext=getnext(next)
+ setnext(current,nextnext)
+ local nextnextnext=getnext(nextnext)
+ if nextnextnext then
+ setprev(nextnextnext,current)
+ end
+ setlink(nextnext,c)
+ end
+ if stop==current then break end
+ current=getnext(current)
+ end
+ if getchar(base)==c_nbsp then
+ if base==stop then
+ stop=getprev(stop)
+ end
+ nbspaces=nbspaces-1
+ head=remove_node(head,base)
+ flush_node(base)
+ end
+ return head,stop,nbspaces
+end
+local separator={}
+imerge(separator,consonant)
+imerge(separator,independent_vowel)
+imerge(separator,dependent_vowel)
+imerge(separator,vowel_modifier)
+imerge(separator,stress_tone_mark)
+for k,v in next,nukta do separator[k]=true end
+for k,v in next,halant do separator[k]=true end
+local function analyze_next_chars_one(c,font,variant)
+ local n=getnext(c)
+ if not n then
+ return c
+ end
+ if variant==1 then
+ local v=ischar(n,font)
+ if v and nukta[v] then
+ n=getnext(n)
+ if n then
+ v=ischar(n,font)
+ end
+ end
+ if n and v then
+ local nn=getnext(n)
+ if nn then
+ local vv=ischar(nn,font)
+ if vv then
+ local nnn=getnext(nn)
+ if nnn then
+ local vvv=ischar(nnn,font)
+ if vvv then
+ if vv==c_zwj and consonant[vvv] then
+ c=nnn
+ elseif (vv==c_zwnj or vv==c_zwj) and halant[vvv] then
+ local nnnn=getnext(nnn)
+ if nnnn then
+ local vvvv=ischar(nnnn,font)
+ if vvvv and consonant[vvvv] then
+ c=nnnn
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ elseif variant==2 then
+ local v=ischar(n,font)
+ if v and nukta[v] then
+ c=n
+ end
+ n=getnext(c)
+ if n then
+ v=ischar(n,font)
+ if v then
+ local nn=getnext(n)
+ if nn then
+ local vv=ischar(nn,font)
+ if vv and zw_char[v] then
+ n=nn
+ v=vv
+ nn=getnext(nn)
+ vv=nn and ischar(nn,font)
+ end
+ if vv and halant[v] and consonant[vv] then
+ c=nn
+ end
+ end
+ end
+ end
+ end
+ local n=getnext(c)
+ if not n then
+ return c
+ end
+ local v=ischar(n,font)
+ if not v then
+ return c
+ end
+ local already_pre_mark
+ local already_above_mark
+ local already_below_mark
+ local already_post_mark
+ while dependent_vowel[v] do
+ local vowels=twopart_mark[v] or { v }
+ for k,v in next,vowels do
+ if pre_mark[v] and not already_pre_mark then
+ already_pre_mark=true
+ elseif above_mark[v] and not already_above_mark then
+ already_above_mark=true
+ elseif below_mark[v] and not already_below_mark then
+ already_below_mark=true
+ elseif post_mark[v] and not already_post_mark then
+ already_post_mark=true
+ else
+ return c
+ end
+ end
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if nukta[v] then
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if halant[v] then
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if vowel_modifier[v] then
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ return n
+ else
+ return c
+ end
+end
+local function analyze_next_chars_two(c,font)
+ local n=getnext(c)
+ if not n then
+ return c
+ end
+ local v=ischar(n,font)
+ if v and nukta[v] then
+ c=n
+ end
+ n=c
+ while true do
+ local nn=getnext(n)
+ if nn then
+ local vv=ischar(nn,font)
+ if vv then
+ if halant[vv] then
+ n=nn
+ local nnn=getnext(nn)
+ if nnn then
+ local vvv=ischar(nnn,font)
+ if vvv and zw_char[vvv] then
+ n=nnn
+ end
+ end
+ elseif vv==c_zwnj or vv==c_zwj then
+ local nnn=getnext(nn)
+ if nnn then
+ local vvv=ischar(nnn,font)
+ if vvv and halant[vvv] then
+ n=nnn
+ end
+ end
+ else
+ break
+ end
+ local nn=getnext(n)
+ if nn then
+ local vv=ischar(nn,font)
+ if vv and consonant[vv] then
+ n=nn
+ local nnn=getnext(nn)
+ if nnn then
+ local vvv=ischar(nnn,font)
+ if vvv and nukta[vvv] then
+ n=nnn
+ end
+ end
+ c=n
+ else
+ break
+ end
+ else
+ break
+ end
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if not c then
+ return
+ end
+ local n=getnext(c)
+ if not n then
+ return c
+ end
+ local v=ischar(n,font)
+ if not v then
+ return c
+ end
+ if anudatta[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if halant[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ if v==c_zwnj or v==c_zwj then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ else
+ local already_pre_mark
+ local already_above_mark
+ local already_below_mark
+ local already_post_mark
+ while dependent_vowel[v] do
+ local vowels=twopart_mark[v] or { v }
+ for k,v in next,vowels do
+ if pre_mark[v] and not already_pre_mark then
+ already_pre_mark=true
+ elseif above_mark[v] and not already_above_mark then
+ already_above_mark=true
+ elseif below_mark[v] and not already_below_mark then
+ already_below_mark=true
+ elseif post_mark[v] and not already_post_mark then
+ already_post_mark=true
+ else
+ return c
+ end
+ end
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if nukta[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if halant[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ end
+ if vowel_modifier[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ return n
+ else
+ return c
+ end
+end
+local function method_one(head,font,attr)
+ local current=head
+ local start=true
+ local done=false
+ local nbspaces=0
+ local syllabe=0
+ while current do
+ local char=ischar(current,font)
+ if char then
+ done=true
+ local syllablestart=current
+ local syllableend=nil
+ local c=current
+ local n=getnext(c)
+ local first=char
+ if n and ra[first] then
+ local second=ischar(n,font)
+ if second and halant[second] then
+ local n=getnext(n)
+ if n then
+ local third=ischar(n,font)
+ if third then
+ c=n
+ first=third
+ end
+ end
+ end
+ end
+ local standalone=first==c_nbsp
+ if standalone then
+ local prev=getprev(current)
+ if prev then
+ local prevchar=ischar(prev,font)
+ if not prevchar then
+ elseif not separator[prevchar] then
+ else
+ standalone=false
+ end
+ else
+ end
+ end
+ if standalone then
+ local syllableend=analyze_next_chars_one(c,font,2)
+ current=getnext(syllableend)
+ if syllablestart~=syllableend then
+ head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces)
+ current=getnext(current)
+ end
+ else
+ if consonant[char] then
+ local prevc=true
+ while prevc do
+ prevc=false
+ local n=getnext(current)
+ if not n then
+ break
+ end
+ local v=ischar(n,font)
+ if not v then
+ break
+ end
+ if nukta[v] then
+ n=getnext(n)
+ if not n then
+ break
+ end
+ v=ischar(n,font)
+ if not v then
+ break
+ end
+ end
+ if halant[v] then
+ n=getnext(n)
+ if not n then
+ break
+ end
+ v=ischar(n,font)
+ if not v then
+ break
+ end
+ if v==c_zwnj or v==c_zwj then
+ n=getnext(n)
+ if not n then
+ break
+ end
+ v=ischar(n,font)
+ if not v then
+ break
+ end
+ end
+ if consonant[v] then
+ prevc=true
+ current=n
+ end
+ end
+ end
+ local n=getnext(current)
+ if n then
+ local v=ischar(n,font)
+ if v and nukta[v] then
+ current=n
+ n=getnext(current)
+ end
+ end
+ syllableend=current
+ current=n
+ if current then
+ local v=ischar(current,font)
+ if not v then
+ elseif halant[v] then
+ local n=getnext(current)
+ if n then
+ local v=ischar(n,font)
+ if v and zw_char[v] then
+ syllableend=n
+ current=getnext(n)
+ else
+ syllableend=current
+ current=n
+ end
+ else
+ syllableend=current
+ current=n
+ end
+ else
+ if dependent_vowel[v] then
+ syllableend=current
+ current=getnext(current)
+ v=ischar(current,font)
+ end
+ if v and vowel_modifier[v] then
+ syllableend=current
+ current=getnext(current)
+ v=ischar(current,font)
+ end
+ if v and stress_tone_mark[v] then
+ syllableend=current
+ current=getnext(current)
+ end
+ end
+ end
+ if syllablestart~=syllableend then
+ if syllableend then
+ syllabe=syllabe+1
+ local c=syllablestart
+ local n=getnext(syllableend)
+ while c~=n do
+ setprop(c,a_syllabe,syllabe)
+ c=getnext(c)
+ end
+ end
+ head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces)
+ current=getnext(current)
+ end
+ elseif independent_vowel[char] then
+ syllableend=current
+ current=getnext(current)
+ if current then
+ local v=ischar(current,font)
+ if v then
+ if vowel_modifier[v] then
+ syllableend=current
+ current=getnext(current)
+ v=ischar(current,font)
+ end
+ if v and stress_tone_mark[v] then
+ syllableend=current
+ current=getnext(current)
+ end
+ end
+ end
+ else
+ if show_syntax_errors then
+ local mark=mark_four[char]
+ if mark then
+ head,current=inject_syntax_error(head,current,char)
+ end
+ end
+ current=getnext(current)
+ end
+ end
+ else
+ current=getnext(current)
+ end
+ start=false
+ end
+ if nbspaces>0 then
+ head=replace_all_nbsp(head)
+ end
+ current=head
+ local n=0
+ while current do
+ local char=ischar(current,font)
+ if char then
+ if n==0 and not getprop(current,a_state) then
+ setprop(current,a_state,s_init)
+ end
+ n=n+1
+ else
+ n=0
+ end
+ current=getnext(current)
+ end
+ return head,done
+end
+local function method_two(head,font,attr)
+ local current=head
+ local start=true
+ local done=false
+ local syllabe=0
+ local nbspaces=0
+ while current do
+ local syllablestart=nil
+ local syllableend=nil
+ local char=ischar(current,font)
+ if char then
+ done=true
+ syllablestart=current
+ local c=current
+ local n=getnext(current)
+ if n and ra[char] then
+ local nextchar=ischar(n,font)
+ if nextchar and halant[nextchar] then
+ local n=getnext(n)
+ if n then
+ local nextnextchar=ischar(n,font)
+ if nextnextchar then
+ c=n
+ char=nextnextchar
+ end
+ end
+ end
+ end
+ if independent_vowel[char] then
+ current=analyze_next_chars_one(c,font,1)
+ syllableend=current
+ else
+ local standalone=char==c_nbsp
+ if standalone then
+ nbspaces=nbspaces+1
+ local p=getprev(current)
+ if not p then
+ elseif ischar(p,font) then
+ elseif not separator[getchar(p)] then
+ else
+ standalone=false
+ end
+ end
+ if standalone then
+ current=analyze_next_chars_one(c,font,2)
+ syllableend=current
+ elseif consonant[getchar(current)] then
+ current=analyze_next_chars_two(current,font)
+ syllableend=current
+ end
+ end
+ end
+ if syllableend then
+ syllabe=syllabe+1
+ local c=syllablestart
+ local n=getnext(syllableend)
+ while c~=n do
+ setprop(c,a_syllabe,syllabe)
+ c=getnext(c)
+ end
+ end
+ if syllableend and syllablestart~=syllableend then
+ head,current,nbspaces=reorder_two(head,syllablestart,syllableend,font,attr,nbspaces)
+ end
+ if not syllableend and show_syntax_errors then
+ local char=ischar(current,font)
+ if char and not getprop(current,a_state) then
+ local mark=mark_four[char]
+ if mark then
+ head,current=inject_syntax_error(head,current,char)
+ end
+ end
+ end
+ start=false
+ current=getnext(current)
+ end
+ if nbspaces>0 then
+ head=replace_all_nbsp(head)
+ end
+ current=head
+ local n=0
+ while current do
+ local char=ischar(current,font)
+ if char then
+ if n==0 and not getprop(current,a_state) then
+ setprop(current,a_state,s_init)
+ end
+ n=n+1
+ else
+ n=0
+ end
+ current=getnext(current)
+ end
+ return head,done
+end
+for i=1,nofscripts do
+ methods[scripts_one[i]]=method_one
+ methods[scripts_two[i]]=method_two
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-ocl']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local tostring,tonumber,next=tostring,tonumber,next
+local round,max=math.round,math.round
+local sortedkeys,sortedhash=table.sortedkeys,table.sortedhash
+local setmetatableindex=table.setmetatableindex
+local formatters=string.formatters
+local tounicode=fonts.mappings.tounicode
+local helpers=fonts.helpers
+local charcommand=helpers.commands.char
+local rightcommand=helpers.commands.right
+local leftcommand=helpers.commands.left
+local downcommand=helpers.commands.down
+local otf=fonts.handlers.otf
+local f_color=formatters["%.3f %.3f %.3f rg"]
+local f_gray=formatters["%.3f g"]
+if context then
+
+--removed
+
+else
+ local tounicode=fonts.mappings.tounicode16
+ function otf.getactualtext(s)
+ return
+ "/Span << /ActualText <feff"..s.."> >> BDC",
+ "EMC"
+ end
+end
+local sharedpalettes={}
+local hash=setmetatableindex(function(t,k)
+ local v={ "pdf","direct",k }
+ t[k]=v
+ return v
+end)
+if context then
+
+--removed
+
+else
+ function otf.registerpalette(name,values)
+ sharedpalettes[name]=values
+ for i=1,#values do
+ local v=values[i]
+ if v then
+ 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
+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 start={ "pdf","mode","font" }
+local push={ "pdf","page","q" }
+local pop={ "pdf","page","Q" }
+local function initialize(tfmdata,kind,value)
+ if value then
+ local resources=tfmdata.resources
+ local palettes=resources.colorpalettes
+ if palettes then
+ local converted=resources.converted
+ if not converted then
+ converted=setmetatableindex(convert)
+ resources.converted=converted
+ end
+ local colorvalues=sharedpalettes[value]
+ local default=false
+ if colorvalues then
+ default=colorvalues[#colorvalues]
+ else
+ colorvalues=converted[palettes[tonumber(value) or 1] or palettes[1]] or {}
+ end
+ local classes=#colorvalues
+ if classes==0 then
+ return
+ end
+ local characters=tfmdata.characters
+ local descriptions=tfmdata.descriptions
+ local properties=tfmdata.properties
+ properties.virtualized=true
+ tfmdata.fonts={
+ { id=0 }
+ }
+ local getactualtext=otf.getactualtext
+ local b,e=getactualtext(tounicode(0xFFFD))
+ local actualb={ "pdf","page",b }
+ local actuale={ "pdf","page",e }
+ for unicode,character in next,characters do
+ local description=descriptions[unicode]
+ if description then
+ local colorlist=description.colors
+ if colorlist then
+ local u=description.unicode or characters[unicode].unicode
+ local w=character.width or 0
+ local s=#colorlist
+ local goback=w~=0 and leftcommand[w] or nil
+ local t={
+ start,
+ not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }
+ }
+ local n=2
+ local l=nil
+ local f=false
+ for i=1,s do
+ local entry=colorlist[i]
+ local v=colorvalues[entry.class] or default
+ if v and l~=v then
+ if f then
+ n=n+1 t[n]=pop
+ end
+ n=n+1 t[n]=push
+ f=true
+ n=n+1 t[n]=v
+ l=v
+ else
+ if f then
+ n=n+1 t[n]=pop
+ end
+ f=false
+ l=nil
+ end
+ n=n+1 t[n]=charcommand[entry.slot]
+ if s>1 and i<s and goback then
+ n=n+1 t[n]=goback
+ end
+ end
+ if f then
+ n=n+1 t[n]=pop
+ end
+ n=n+1 t[n]=actuale
+ character.commands=t
+ end
+ end
+ end
+ end
+ end
+end
+fonts.handlers.otf.features.register {
+ name="colr",
+ description="color glyphs",
+ manipulators={
+ base=initialize,
+ node=initialize,
+ }
+}
+do
+ local nofstreams=0
+ local f_name=formatters[ [[pdf-glyph-%05i]] ]
+ local f_used=context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ]
+ local hashed={}
+ local cache={}
+ local openpdf=pdfe.new
+ function otf.storepdfdata(pdf)
+ local done=hashed[pdf]
+ if not done then
+ nofstreams=nofstreams+1
+ local f=f_name(nofstreams)
+ local n=openpdf(pdf,#pdf,f)
+ done=f_used(n)
+ hashed[pdf]=done
+ end
+ return done
+ end
+end
+local function pdftovirtual(tfmdata,pdfshapes,kind)
+ if not tfmdata or not pdfshapes or not kind then
+ return
+ end
+ local characters=tfmdata.characters
+ local properties=tfmdata.properties
+ local parameters=tfmdata.parameters
+ local hfactor=parameters.hfactor
+ properties.virtualized=true
+ tfmdata.fonts={
+ { id=0 }
+ }
+ local getactualtext=otf.getactualtext
+ local storepdfdata=otf.storepdfdata
+ local b,e=getactualtext(tounicode(0xFFFD))
+ local actualb={ "pdf","page",b }
+ local actuale={ "pdf","page",e }
+ local vfimage=lpdf and lpdf.vfimage or function(wd,ht,dp,data,name)
+ local name=storepdfdata(data)
+ return { "image",{ filename=name,width=wd,height=ht,depth=dp } }
+ end
+ for unicode,character in sortedhash(characters) do
+ local index=character.index
+ if index then
+ local pdf=pdfshapes[index]
+ local typ=type(pdf)
+ local data=nil
+ local dx=nil
+ local dy=nil
+ if typ=="table" then
+ data=pdf.data
+ dx=pdf.dx or 0
+ dy=pdf.dy or 0
+ elseif typ=="string" then
+ data=pdf
+ dx=0
+ dy=0
+ end
+ if data then
+ local bt=unicode and getactualtext(unicode)
+ local wd=character.width or 0
+ local ht=character.height or 0
+ local dp=character.depth or 0
+ character.commands={
+ not unicode and actualb or { "pdf","page",(getactualtext(unicode)) },
+ downcommand[dp+dy*hfactor],
+ rightcommand[dx*hfactor],
+ vfimage(wd,ht,dp,data,name),
+ actuale,
+ }
+ character[kind]=true
+ end
+ end
+ end
+end
+local otfsvg=otf.svg or {}
+otf.svg=otfsvg
+otf.svgenabled=true
+do
+ local report_svg=logs.reporter("fonts","svg conversion")
+ local loaddata=io.loaddata
+ local savedata=io.savedata
+ local remove=os.remove
+ if context and xml.convert then
+ local xmlconvert=xml.convert
+ local xmlfirst=xml.first
+ function otfsvg.filterglyph(entry,index)
+ local svg=xmlconvert(entry.data)
+ local root=svg and xmlfirst(svg,"/svg[@id='glyph"..index.."']")
+ local data=root and tostring(root)
+ return data
+ end
+ else
+ function otfsvg.filterglyph(entry,index)
+ return entry.data
+ end
+ end
+ local runner=sandbox and sandbox.registerrunner {
+ name="otfsvg",
+ program="inkscape",
+ method="pipeto",
+ template="--shell > temp-otf-svg-shape.log",
+ reporter=report_svg,
+ }
+ if not runner then
+ runner=function()
+ return io.open("inkscape --shell > temp-otf-svg-shape.log","w")
+ end
+ end
+ function otfsvg.topdf(svgshapes)
+ local pdfshapes={}
+ local inkscape=runner()
+ if inkscape then
+ local nofshapes=#svgshapes
+ local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"]
+ local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"]
+ local f_convert=formatters["%s --export-pdf=%s\n"]
+ local filterglyph=otfsvg.filterglyph
+ local nofdone=0
+ report_svg("processing %i svg containers",nofshapes)
+ statistics.starttiming()
+ for i=1,nofshapes do
+ local entry=svgshapes[i]
+ for index=entry.first,entry.last do
+ local data=filterglyph(entry,index)
+ if data and data~="" then
+ local svgfile=f_svgfile(index)
+ local pdffile=f_pdffile(index)
+ savedata(svgfile,data)
+ inkscape:write(f_convert(svgfile,pdffile))
+ pdfshapes[index]=true
+ nofdone=nofdone+1
+ if nofdone%100==0 then
+ report_svg("%i shapes processed",nofdone)
+ end
+ end
+ end
+ end
+ inkscape:write("quit\n")
+ inkscape:close()
+ report_svg("processing %i pdf results",nofshapes)
+ for index in next,pdfshapes do
+ local svgfile=f_svgfile(index)
+ local pdffile=f_pdffile(index)
+ pdfshapes[index]=loaddata(pdffile)
+ remove(svgfile)
+ remove(pdffile)
+ end
+ statistics.stoptiming()
+ if statistics.elapsedseconds then
+ report_svg("svg conversion time %s",statistics.elapsedseconds() or "-")
+ end
+ end
+ return pdfshapes
+ end
+end
+local function initializesvg(tfmdata,kind,value)
+ if value and otf.svgenabled then
+ local svg=tfmdata.properties.svg
+ local hash=svg and svg.hash
+ local timestamp=svg and svg.timestamp
+ if not hash then
+ return
+ end
+ local pdffile=containers.read(otf.pdfcache,hash)
+ local pdfshapes=pdffile and pdffile.pdfshapes
+ if not pdfshapes or pdffile.timestamp~=timestamp then
+ local svgfile=containers.read(otf.svgcache,hash)
+ local svgshapes=svgfile and svgfile.svgshapes
+ pdfshapes=svgshapes and otfsvg.topdf(svgshapes) or {}
+ containers.write(otf.pdfcache,hash,{
+ pdfshapes=pdfshapes,
+ timestamp=timestamp,
+ })
+ end
+ pdftovirtual(tfmdata,pdfshapes,"svg")
+ end
+end
+fonts.handlers.otf.features.register {
+ name="svg",
+ description="svg glyphs",
+ manipulators={
+ base=initializesvg,
+ node=initializesvg,
+ }
+}
+local otfpng=otf.png or {}
+otf.png=otfpng
+otf.pngenabled=true
+do
+ local report_png=logs.reporter("fonts","png conversion")
+ local loaddata=io.loaddata
+ local savedata=io.savedata
+ local remove=os.remove
+ local runner=sandbox and sandbox.registerrunner {
+ name="otfpng",
+ program="gm",
+ template="convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log",
+ }
+ if not runner then
+ runner=function()
+ return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log")
+ end
+ end
+ function otfpng.topdf(pngshapes)
+ local pdfshapes={}
+ local pngfile="temp-otf-png-shape.png"
+ local pdffile="temp-otf-png-shape.pdf"
+ local nofdone=0
+ local indices=sortedkeys(pngshapes)
+ local nofindices=#indices
+ report_png("processing %i png containers",nofindices)
+ statistics.starttiming()
+ for i=1,nofindices do
+ local index=indices[i]
+ local entry=pngshapes[index]
+ local data=entry.data
+ local x=entry.x
+ local y=entry.y
+ savedata(pngfile,data)
+ runner()
+ pdfshapes[index]={
+ x=x~=0 and x or nil,
+ y=y~=0 and y or nil,
+ data=loaddata(pdffile),
+ }
+ nofdone=nofdone+1
+ if nofdone%100==0 then
+ report_png("%i shapes processed",nofdone)
+ end
+ end
+ report_png("processing %i pdf results",nofindices)
+ remove(pngfile)
+ remove(pdffile)
+ statistics.stoptiming()
+ if statistics.elapsedseconds then
+ report_png("png conversion time %s",statistics.elapsedseconds() or "-")
+ end
+ return pdfshapes
+ end
+end
+local function initializepng(tfmdata,kind,value)
+ if value and otf.pngenabled then
+ local png=tfmdata.properties.png
+ local hash=png and png.hash
+ local timestamp=png and png.timestamp
+ if not hash then
+ return
+ end
+ local pdffile=containers.read(otf.pdfcache,hash)
+ local pdfshapes=pdffile and pdffile.pdfshapes
+ if not pdfshapes or pdffile.timestamp~=timestamp then
+ local pngfile=containers.read(otf.pngcache,hash)
+ local pngshapes=pngfile and pngfile.pngshapes
+ pdfshapes=pngshapes and otfpng.topdf(pngshapes) or {}
+ containers.write(otf.pdfcache,hash,{
+ pdfshapes=pdfshapes,
+ timestamp=timestamp,
+ })
+ end
+ pdftovirtual(tfmdata,pdfshapes,"png")
+ end
+end
+fonts.handlers.otf.features.register {
+ name="sbix",
+ description="sbix glyphs",
+ manipulators={
+ base=initializepng,
+ node=initializepng,
+ }
+}
+fonts.handlers.otf.features.register {
+ name="cblc",
+ description="cblc glyphs",
+ manipulators={
+ base=initializepng,
+ node=initializepng,
+ }
+}
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-otc']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local insert,sortedkeys,sortedhash,tohash=table.insert,table.sortedkeys,table.sortedhash,table.tohash
+local type,next,tonumber=type,next,tonumber
+local lpegmatch=lpeg.match
+local utfbyte,utflen=utf.byte,utf.len
+local sortedhash=table.sortedhash
+local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
+local report_otf=logs.reporter("fonts","otf loading")
+local fonts=fonts
+local otf=fonts.handlers.otf
+local registerotffeature=otf.features.register
+local setmetatableindex=table.setmetatableindex
+local checkmerge=fonts.helpers.checkmerge
+local checkflags=fonts.helpers.checkflags
+local checksteps=fonts.helpers.checksteps
+local normalized={
+ substitution="substitution",
+ single="substitution",
+ ligature="ligature",
+ alternate="alternate",
+ multiple="multiple",
+ kern="kern",
+ pair="pair",
+ single="single",
+ chainsubstitution="chainsubstitution",
+ chainposition="chainposition",
+}
+local types={
+ substitution="gsub_single",
+ ligature="gsub_ligature",
+ alternate="gsub_alternate",
+ multiple="gsub_multiple",
+ kern="gpos_pair",
+ pair="gpos_pair",
+ single="gpos_single",
+ chainsubstitution="gsub_contextchain",
+ chainposition="gpos_contextchain",
+}
+local names={
+ gsub_single="gsub",
+ gsub_multiple="gsub",
+ gsub_alternate="gsub",
+ gsub_ligature="gsub",
+ gsub_context="gsub",
+ gsub_contextchain="gsub",
+ gsub_reversecontextchain="gsub",
+ gpos_single="gpos",
+ gpos_pair="gpos",
+ gpos_cursive="gpos",
+ gpos_mark2base="gpos",
+ gpos_mark2ligature="gpos",
+ gpos_mark2mark="gpos",
+ gpos_context="gpos",
+ gpos_contextchain="gpos",
+}
+setmetatableindex(types,function(t,k) t[k]=k return k end)
+local everywhere={ ["*"]={ ["*"]=true } }
+local noflags={ false,false,false,false }
+local function getrange(sequences,category)
+ local count=#sequences
+ local first=nil
+ local last=nil
+ for i=1,count do
+ local t=sequences[i].type
+ if t and names[t]==category then
+ if not first then
+ first=i
+ end
+ last=i
+ end
+ end
+ return first or 1,last or count
+end
+local function validspecification(specification,name)
+ local dataset=specification.dataset
+ if dataset then
+ elseif specification[1] then
+ dataset=specification
+ specification={ dataset=dataset }
+ else
+ dataset={ { data=specification.data } }
+ specification.data=nil
+ specification.dataset=dataset
+ end
+ local first=dataset[1]
+ if first then
+ first=first.data
+ end
+ if not first then
+ report_otf("invalid feature specification, no dataset")
+ return
+ end
+ if type(name)~="string" then
+ name=specification.name or first.name
+ end
+ if type(name)~="string" then
+ report_otf("invalid feature specification, no name")
+ return
+ end
+ local n=#dataset
+ if n>0 then
+ for i=1,n do
+ setmetatableindex(dataset[i],specification)
+ end
+ return specification,name
+ end
+end
+local function addfeature(data,feature,specifications)
+ if not specifications then
+ report_otf("missing specification")
+ return
+ end
+ local descriptions=data.descriptions
+ local resources=data.resources
+ local features=resources.features
+ local sequences=resources.sequences
+ if not features or not sequences then
+ report_otf("missing specification")
+ return
+ end
+ local alreadydone=resources.alreadydone
+ if not alreadydone then
+ alreadydone={}
+ resources.alreadydone=alreadydone
+ end
+ if alreadydone[specifications] then
+ return
+ else
+ alreadydone[specifications]=true
+ end
+ local fontfeatures=resources.features or everywhere
+ local unicodes=resources.unicodes
+ local splitter=lpeg.splitter(" ",unicodes)
+ local done=0
+ local skip=0
+ local aglunicodes=false
+ local specifications=validspecification(specifications,feature)
+ if not specifications then
+ return
+ end
+ local p=lpeg.P("P")*(lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)*lpeg.P(-1)
+ local function tounicode(code)
+ if not code then
+ return
+ end
+ if type(code)=="number" then
+ return code
+ end
+ local u=unicodes[code]
+ if u then
+ return u
+ end
+ if utflen(code)==1 then
+ u=utfbyte(code)
+ if u then
+ return u
+ end
+ end
+ local u=lpegmatch(p,code)
+ if u then
+ return u
+ end
+ if not aglunicodes then
+ aglunicodes=fonts.encodings.agl.unicodes
+ end
+ local u=aglunicodes[code]
+ if u then
+ return u
+ end
+ end
+ local coverup=otf.coverup
+ local coveractions=coverup.actions
+ local stepkey=coverup.stepkey
+ local register=coverup.register
+ local function prepare_substitution(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ else
+ if type(replacement)=="table" then
+ replacement=replacement[1]
+ end
+ replacement=tounicode(replacement)
+ if replacement and descriptions[replacement] then
+ cover(coverage,unicode,replacement)
+ done=done+1
+ else
+ skip=skip+1
+ end
+ end
+ end
+ return coverage
+ end
+ local function prepare_alternate(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ elseif type(replacement)=="table" then
+ local r={}
+ for i=1,#replacement do
+ local u=tounicode(replacement[i])
+ r[i]=(nocheck or descriptions[u]) and u or unicode
+ end
+ cover(coverage,unicode,r)
+ done=done+1
+ else
+ local u=tounicode(replacement)
+ if u then
+ cover(coverage,unicode,{ u })
+ done=done+1
+ else
+ skip=skip+1
+ end
+ end
+ end
+ return coverage
+ end
+ local function prepare_multiple(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ elseif type(replacement)=="table" then
+ local r={}
+ local n=0
+ for i=1,#replacement do
+ local u=tounicode(replacement[i])
+ if nocheck or descriptions[u] then
+ n=n+1
+ r[n]=u
+ end
+ end
+ if n>0 then
+ cover(coverage,unicode,r)
+ done=done+1
+ else
+ skip=skip+1
+ end
+ else
+ local u=tounicode(replacement)
+ if u then
+ cover(coverage,unicode,{ u })
+ done=done+1
+ else
+ skip=skip+1
+ end
+ end
+ end
+ return coverage
+ end
+ local function prepare_ligature(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,ligature in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ else
+ if type(ligature)=="string" then
+ ligature={ lpegmatch(splitter,ligature) }
+ end
+ local present=true
+ for i=1,#ligature do
+ local l=ligature[i]
+ local u=tounicode(l)
+ if nocheck or descriptions[u] then
+ ligature[i]=u
+ else
+ present=false
+ break
+ end
+ end
+ if present then
+ cover(coverage,unicode,ligature)
+ done=done+1
+ else
+ skip=skip+1
+ end
+ end
+ end
+ return coverage
+ end
+ local function resetspacekerns()
+ data.properties.hasspacekerns=true
+ data.resources .spacekerns=nil
+ end
+ local function prepare_kern(list,featuretype)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ local isspace=false
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if description and type(replacement)=="table" then
+ local r={}
+ for k,v in next,replacement do
+ local u=tounicode(k)
+ if u then
+ r[u]=v
+ if u==32 then
+ isspace=true
+ end
+ end
+ end
+ if next(r) then
+ cover(coverage,unicode,r)
+ done=done+1
+ if unicode==32 then
+ isspace=true
+ end
+ else
+ skip=skip+1
+ end
+ else
+ skip=skip+1
+ end
+ end
+ if isspace then
+ resetspacekerns()
+ end
+ return coverage
+ end
+ local function prepare_pair(list,featuretype)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ if cover then
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if description and type(replacement)=="table" then
+ local r={}
+ for k,v in next,replacement do
+ local u=tounicode(k)
+ if u then
+ r[u]=v
+ if u==32 then
+ isspace=true
+ end
+ end
+ end
+ if next(r) then
+ cover(coverage,unicode,r)
+ done=done+1
+ if unicode==32 then
+ isspace=true
+ end
+ else
+ skip=skip+1
+ end
+ else
+ skip=skip+1
+ end
+ end
+ if isspace then
+ resetspacekerns()
+ end
+ else
+ report_otf("unknown cover type %a",featuretype)
+ end
+ return coverage
+ end
+ local prepare_single=prepare_pair
+ local function prepare_chain(list,featuretype,sublookups)
+ local rules=list.rules
+ local coverage={}
+ if rules then
+ local rulehash={}
+ local rulesize=0
+ local lookuptype=types[featuretype]
+ for nofrules=1,#rules do
+ local rule=rules[nofrules]
+ local current=rule.current
+ local before=rule.before
+ local after=rule.after
+ local replacements=rule.replacements or false
+ local sequence={}
+ local nofsequences=0
+ if before then
+ for n=1,#before do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=before[n]
+ end
+ end
+ local start=nofsequences+1
+ for n=1,#current do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=current[n]
+ end
+ local stop=nofsequences
+ if after then
+ for n=1,#after do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=after[n]
+ end
+ end
+ local lookups=rule.lookups or false
+ local subtype=nil
+ if lookups and sublookups then
+ for k,v in sortedhash(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 }
+ if not subtype then
+ subtype=lookup.type
+ end
+ elseif v==0 then
+ lookups[k]={ { type="gsub_remove" } }
+ else
+ lookups[k]=false
+ end
+ else
+ lookups[k]=false
+ end
+ end
+ end
+ if nofsequences>0 then
+ local hashed={}
+ for i=1,nofsequences do
+ local t={}
+ local s=sequence[i]
+ for i=1,#s do
+ local u=tounicode(s[i])
+ if u then
+ t[u]=true
+ end
+ end
+ hashed[i]=t
+ end
+ sequence=hashed
+ rulesize=rulesize+1
+ rulehash[rulesize]={
+ nofrules,
+ lookuptype,
+ sequence,
+ start,
+ stop,
+ lookups,
+ replacements,
+ subtype,
+ }
+ for unic in sortedhash(sequence[start]) do
+ local cu=coverage[unic]
+ if not cu then
+ coverage[unic]=rulehash
+ end
+ end
+ sequence.n=nofsequences
+ end
+ end
+ rulehash.n=rulesize
+ end
+ return coverage
+ end
+ local dataset=specifications.dataset
+ local function report(name,category,position,first,last,sequences)
+ report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]",
+ name,category,position,first,last,1,#sequences)
+ end
+ local function inject(specification,sequences,sequence,first,last,category,name)
+ local position=specification.position or false
+ if not position then
+ position=specification.prepend
+ if position==true then
+ if trace_loading then
+ report(name,category,first,first,last,sequences)
+ end
+ insert(sequences,first,sequence)
+ return
+ end
+ end
+ if not position then
+ position=specification.append
+ if position==true then
+ if trace_loading then
+ report(name,category,last+1,first,last,sequences)
+ end
+ insert(sequences,last+1,sequence)
+ return
+ end
+ end
+ local kind=type(position)
+ if kind=="string" then
+ local index=false
+ for i=first,last do
+ local s=sequences[i]
+ local f=s.features
+ if f then
+ for k in sortedhash(f) do
+ if k==position then
+ index=i
+ break
+ end
+ end
+ if index then
+ break
+ end
+ end
+ end
+ if index then
+ position=index
+ else
+ position=last+1
+ end
+ elseif kind=="number" then
+ if position<0 then
+ position=last-position+1
+ end
+ if position>last then
+ position=last+1
+ elseif position<first then
+ position=first
+ end
+ else
+ position=last+1
+ end
+ if trace_loading then
+ report(name,category,position,first,last,sequences)
+ end
+ insert(sequences,position,sequence)
+ end
+ for s=1,#dataset do
+ local specification=dataset[s]
+ local valid=specification.valid
+ local feature=specification.name or feature
+ if not feature or feature=="" then
+ report_otf("no valid name given for extra feature")
+ elseif not valid or valid(data,specification,feature) then
+ local initialize=specification.initialize
+ if initialize then
+ specification.initialize=initialize(specification,data) and initialize or nil
+ end
+ local askedfeatures=specification.features or everywhere
+ local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
+ local featuretype=normalized[specification.type or "substitution"] or "substitution"
+ local featureflags=specification.flags or noflags
+ local nocheck=specification.nocheck
+ local futuresteps=specification.futuresteps
+ local featureorder=specification.order or { feature }
+ local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0
+ local nofsteps=0
+ local steps={}
+ local sublookups=specification.lookups
+ local category=nil
+ checkflags(specification,resources)
+ if sublookups then
+ local s={}
+ for i=1,#sublookups do
+ local specification=sublookups[i]
+ local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
+ local featuretype=normalized[specification.type or "substitution"] or "substitution"
+ local featureflags=specification.flags or noflags
+ local nofsteps=0
+ local steps={}
+ for i=1,#askedsteps do
+ local list=askedsteps[i]
+ local coverage=nil
+ local format=nil
+ if featuretype=="substitution" then
+ coverage=prepare_substitution(list,featuretype,nocheck)
+ elseif featuretype=="ligature" then
+ coverage=prepare_ligature(list,featuretype,nocheck)
+ elseif featuretype=="alternate" then
+ coverage=prepare_alternate(list,featuretype,nocheck)
+ elseif featuretype=="multiple" then
+ coverage=prepare_multiple(list,featuretype,nocheck)
+ elseif featuretype=="kern" or featuretype=="move" then
+ format=featuretype
+ coverage=prepare_kern(list,featuretype)
+ elseif featuretype=="pair" then
+ format="pair"
+ coverage=prepare_pair(list,featuretype)
+ elseif featuretype=="single" then
+ format="single"
+ coverage=prepare_single(list,featuretype)
+ end
+ if coverage and next(coverage) then
+ nofsteps=nofsteps+1
+ steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
+ end
+ end
+ checkmerge(specification)
+ checksteps(specification)
+ s[i]={
+ [stepkey]=steps,
+ nofsteps=nofsteps,
+ flags=featureflags,
+ type=types[featuretype],
+ }
+ end
+ sublookups=s
+ end
+ for i=1,#askedsteps do
+ local list=askedsteps[i]
+ local coverage=nil
+ local format=nil
+ if featuretype=="substitution" then
+ category="gsub"
+ coverage=prepare_substitution(list,featuretype,nocheck)
+ elseif featuretype=="ligature" then
+ category="gsub"
+ coverage=prepare_ligature(list,featuretype,nocheck)
+ elseif featuretype=="alternate" then
+ category="gsub"
+ coverage=prepare_alternate(list,featuretype,nocheck)
+ elseif featuretype=="multiple" then
+ category="gsub"
+ coverage=prepare_multiple(list,featuretype,nocheck)
+ elseif featuretype=="kern" or featuretype=="move" then
+ category="gpos"
+ format=featuretype
+ coverage=prepare_kern(list,featuretype)
+ elseif featuretype=="pair" then
+ category="gpos"
+ format="pair"
+ coverage=prepare_pair(list,featuretype)
+ elseif featuretype=="single" then
+ category="gpos"
+ format="single"
+ coverage=prepare_single(list,featuretype)
+ elseif featuretype=="chainsubstitution" then
+ category="gsub"
+ coverage=prepare_chain(list,featuretype,sublookups)
+ elseif featuretype=="chainposition" then
+ category="gpos"
+ coverage=prepare_chain(list,featuretype,sublookups)
+ else
+ report_otf("not registering feature %a, unknown category",feature)
+ return
+ end
+ if coverage and next(coverage) then
+ nofsteps=nofsteps+1
+ steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
+ end
+ end
+ if nofsteps>0 then
+ for k,v in next,askedfeatures do
+ if v[1] then
+ askedfeatures[k]=tohash(v)
+ end
+ end
+ if featureflags[1] then featureflags[1]="mark" end
+ if featureflags[2] then featureflags[2]="ligature" end
+ if featureflags[3] then featureflags[3]="base" end
+ local steptype=types[featuretype]
+ local sequence={
+ chain=featurechain,
+ features={ [feature]=askedfeatures },
+ flags=featureflags,
+ name=feature,
+ order=featureorder,
+ [stepkey]=steps,
+ nofsteps=nofsteps,
+ type=steptype,
+ }
+ checkflags(sequence,resources)
+ checkmerge(sequence)
+ checksteps(sequence)
+ local first,last=getrange(sequences,category)
+ inject(specification,sequences,sequence,first,last,category,feature)
+ local features=fontfeatures[category]
+ if not features then
+ features={}
+ fontfeatures[category]=features
+ end
+ local k=features[feature]
+ if not k then
+ k={}
+ features[feature]=k
+ end
+ for script,languages in next,askedfeatures do
+ local kk=k[script]
+ if not kk then
+ kk={}
+ k[script]=kk
+ end
+ for language,value in next,languages do
+ kk[language]=value
+ end
+ end
+ end
+ end
+ end
+ if trace_loading then
+ report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip)
+ end
+end
+otf.enhancers.addfeature=addfeature
+local extrafeatures={}
+local knownfeatures={}
+function otf.addfeature(name,specification)
+ if type(name)=="table" then
+ specification=name
+ end
+ if type(specification)~="table" then
+ report_otf("invalid feature specification, no valid table")
+ return
+ end
+ specification,name=validspecification(specification,name)
+ if name and specification then
+ local slot=knownfeatures[name]
+ if not slot then
+ slot=#extrafeatures+1
+ knownfeatures[name]=slot
+ elseif specification.overload==false then
+ slot=#extrafeatures+1
+ knownfeatures[name]=slot
+ else
+ end
+ specification.name=name
+ extrafeatures[slot]=specification
+ end
+end
+local function enhance(data,filename,raw)
+ for slot=1,#extrafeatures do
+ local specification=extrafeatures[slot]
+ addfeature(data,specification.name,specification)
+ end
+end
+otf.enhancers.enhance=enhance
+otf.enhancers.register("check extra features",enhance)
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-onr']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local fonts,logs,trackers,resolvers=fonts,logs,trackers,resolvers
+local next,type,tonumber,rawget,rawset=next,type,tonumber,rawget,rawset
+local match,lower,gsub,strip,find=string.match,string.lower,string.gsub,string.strip,string.find
+local char,byte,sub=string.char,string.byte,string.sub
+local abs=math.abs
+local bxor,rshift=bit32.bxor,bit32.rshift
+local P,S,R,V,Cmt,C,Ct,Cs,Carg,Cf,Cg,Cc=lpeg.P,lpeg.S,lpeg.R,lpeg.V,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg,lpeg.Cc
+local lpegmatch,patterns=lpeg.match,lpeg.patterns
+local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
+local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
+local report_afm=logs.reporter("fonts","afm loading")
+local report_pfb=logs.reporter("fonts","pfb loading")
+local handlers=fonts.handlers
+local afm=handlers.afm or {}
+handlers.afm=afm
+local readers=afm.readers or {}
+afm.readers=readers
+afm.version=1.513
+local get_indexes,get_shapes
+do
+ local decrypt
+ do
+ local r,c1,c2,n=0,0,0,0
+ local function step(c)
+ local cipher=byte(c)
+ local plain=bxor(cipher,rshift(r,8))
+ r=((cipher+r)*c1+c2)%65536
+ return char(plain)
+ end
+ decrypt=function(binary,initial,seed)
+ r,c1,c2,n=initial,52845,22719,seed
+ binary=gsub(binary,".",step)
+ return sub(binary,n+1)
+ end
+ end
+ local charstrings=P("/CharStrings")
+ local subroutines=P("/Subrs")
+ local encoding=P("/Encoding")
+ local dup=P("dup")
+ local put=P("put")
+ local array=P("array")
+ local name=P("/")*C((R("az","AZ","09")+S("-_."))^1)
+ local digits=R("09")^1
+ local cardinal=digits/tonumber
+ local spaces=P(" ")^1
+ local spacing=patterns.whitespace^0
+ local routines,vector,chars,n,m
+ local initialize=function(str,position,size)
+ n=0
+ m=size
+ return position+1
+ end
+ local setroutine=function(str,position,index,size,filename)
+ if routines[index] then
+ return false
+ end
+ local forward=position+size
+ local stream=decrypt(sub(str,position+1,forward),4330,4)
+ routines[index]={ byte(stream,1,#stream) }
+ n=n+1
+ if n>=m then
+ return #str
+ end
+ return forward+1
+ end
+ local setvector=function(str,position,name,size,filename)
+ local forward=position+tonumber(size)
+ if n>=m then
+ return #str
+ elseif forward<#str then
+ if n==0 and name~=".notdef" then
+ report_pfb("reserving .notdef at index 0 in %a",filename)
+ n=n+1
+ end
+ vector[n]=name
+ n=n+1
+ return forward
+ else
+ return #str
+ end
+ end
+ local setshapes=function(str,position,name,size,filename)
+ local forward=position+tonumber(size)
+ local stream=sub(str,position+1,forward)
+ if n>m then
+ return #str
+ elseif forward<#str then
+ if n==0 and name~=".notdef" then
+ report_pfb("reserving .notdef at index 0 in %a",filename)
+ n=n+1
+ end
+ vector[n]=name
+ n=n+1
+ chars [n]=decrypt(stream,4330,4)
+ return forward
+ else
+ return #str
+ end
+ end
+ local p_rd=spacing*(P("RD")+P("-|"))
+ local p_np=spacing*(P("NP")+P("|"))
+ local p_nd=spacing*(P("ND")+P("|"))
+ local p_filterroutines=
+ (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd*Carg(1),setroutine)*p_np+(1-p_nd))^1
+ local p_filtershapes=
+ (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd*Carg(1),setshapes)*p_nd+P(1))^1
+ local p_filternames=Ct (
+ (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*Carg(1),setvector)+P(1))^1
+ )
+ local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf(
+ Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1
+,rawset)
+ local key=spacing*P("/")*R("az","AZ")
+ local str=spacing*Cs { (P("(")/"")*((1-P("\\(")-P("\\)")-S("()"))+V(1))^0*(P(")")/"") }
+ local num=spacing*(R("09")+S("+-."))^1/tonumber
+ local arr=spacing*Ct (S("[{")*(num)^0*spacing*S("]}"))
+ local boo=spacing*(P("true")*Cc(true)+P("false")*Cc(false))
+ local nam=spacing*P("/")*Cs(R("az","AZ")^1)
+ local p_filtermetadata=(
+ P("/")*Carg(1)*((
+ C("version")*str+C("Copyright")*str+C("Notice")*str+C("FullName")*str+C("FamilyName")*str+C("Weight")*str+C("ItalicAngle")*num+C("isFixedPitch")*boo+C("UnderlinePosition")*num+C("UnderlineThickness")*num+C("FontName")*nam+C("FontMatrix")*arr+C("FontBBox")*arr
+ ) )/function(t,k,v) t[lower(k)]=v end+P(1)
+ )^0*Carg(1)
+ local function loadpfbvector(filename,shapestoo,streams)
+ local data=io.loaddata(resolvers.findfile(filename))
+ if not data then
+ report_pfb("no data in %a",filename)
+ return
+ end
+ if not (find(data,"!PS-AdobeFont-",1,true) or find(data,"%!FontType1",1,true)) then
+ report_pfb("no font in %a",filename)
+ return
+ end
+ local ascii,binary=match(data,"(.*)eexec%s+......(.*)")
+ if not binary then
+ report_pfb("no binary data in %a",filename)
+ return
+ end
+ binary=decrypt(binary,55665,4)
+ local names={}
+ local encoding=lpegmatch(p_filterencoding,ascii)
+ local metadata=lpegmatch(p_filtermetadata,ascii,1,{})
+ local glyphs={}
+ routines,vector,chars={},{},{}
+ if shapestoo or streams then
+ lpegmatch(p_filterroutines,binary,1,filename)
+ lpegmatch(p_filtershapes,binary,1,filename)
+ local data={
+ dictionaries={
+ {
+ charstrings=chars,
+ charset=vector,
+ subroutines=routines,
+ }
+ },
+ }
+ fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,"cff",streams,true)
+ else
+ lpegmatch(p_filternames,binary,1,filename)
+ end
+ names=vector
+ routines,vector,chars=nil,nil,nil
+ return names,encoding,glyphs,metadata
+ end
+ local pfb=handlers.pfb or {}
+ handlers.pfb=pfb
+ pfb.loadvector=loadpfbvector
+ get_indexes=function(data,pfbname)
+ local vector=loadpfbvector(pfbname)
+ if vector then
+ local characters=data.characters
+ if trace_loading then
+ report_afm("getting index data from %a",pfbname)
+ end
+ for index=0,#vector do
+ local name=vector[index]
+ local char=characters[name]
+ if char then
+ if trace_indexing then
+ report_afm("glyph %a has index %a",name,index)
+ end
+ char.index=index
+ else
+ if trace_indexing then
+ report_afm("glyph %a has index %a but no data",name,index)
+ end
+ end
+ end
+ end
+ end
+ get_shapes=function(pfbname)
+ local vector,encoding,glyphs=loadpfbvector(pfbname,true)
+ return glyphs
+ end
+end
+local spacer=patterns.spacer
+local whitespace=patterns.whitespace
+local lineend=patterns.newline
+local spacing=spacer^0
+local number=spacing*S("+-")^-1*(R("09")+S("."))^1/tonumber
+local name=spacing*C((1-whitespace)^1)
+local words=spacing*((1-lineend)^1/strip)
+local rest=(1-lineend)^0
+local fontdata=Carg(1)
+local semicolon=spacing*P(";")
+local plus=spacing*P("plus")*number
+local minus=spacing*P("minus")*number
+local function addkernpair(data,one,two,value)
+ local chr=data.characters[one]
+ if chr then
+ local kerns=chr.kerns
+ if kerns then
+ kerns[two]=tonumber(value)
+ else
+ chr.kerns={ [two]=tonumber(value) }
+ end
+ end
+end
+local p_kernpair=(fontdata*P("KPX")*name*name*number)/addkernpair
+local chr=false
+local ind=0
+local function start(data,version)
+ data.metadata.afmversion=version
+ ind=0
+ chr={}
+end
+local function stop()
+ ind=0
+ chr=false
+end
+local function setindex(i)
+ if i<0 then
+ ind=ind+1
+ else
+ ind=i
+ end
+ chr={
+ index=ind
+ }
+end
+local function setwidth(width)
+ chr.width=width
+end
+local function setname(data,name)
+ data.characters[name]=chr
+end
+local function setboundingbox(boundingbox)
+ chr.boundingbox=boundingbox
+end
+local function setligature(plus,becomes)
+ local ligatures=chr.ligatures
+ if ligatures then
+ ligatures[plus]=becomes
+ else
+ chr.ligatures={ [plus]=becomes }
+ end
+end
+local p_charmetric=((
+ P("C")*number/setindex+P("WX")*number/setwidth+P("N")*fontdata*name/setname+P("B")*Ct((number)^4)/setboundingbox+P("L")*(name)^2/setligature
+ )*semicolon )^1
+local p_charmetrics=P("StartCharMetrics")*number*(p_charmetric+(1-P("EndCharMetrics")))^0*P("EndCharMetrics")
+local p_kernpairs=P("StartKernPairs")*number*(p_kernpair+(1-P("EndKernPairs" )))^0*P("EndKernPairs" )
+local function set_1(data,key,a) data.metadata[lower(key)]=a end
+local function set_2(data,key,a,b) data.metadata[lower(key)]={ a,b } end
+local function set_3(data,key,a,b,c) data.metadata[lower(key)]={ a,b,c } end
+local p_parameters=P(false)+fontdata*((P("FontName")+P("FullName")+P("FamilyName"))/lower)*words/function(data,key,value)
+ data.metadata[key]=value
+ end+fontdata*((P("Weight")+P("Version"))/lower)*name/function(data,key,value)
+ data.metadata[key]=value
+ end+fontdata*P("IsFixedPitch")*name/function(data,pitch)
+ data.metadata.monospaced=toboolean(pitch,true)
+ end+fontdata*P("FontBBox")*Ct(number^4)/function(data,boundingbox)
+ data.metadata.boundingbox=boundingbox
+ end+fontdata*((P("CharWidth")+P("CapHeight")+P("XHeight")+P("Descender")+P("Ascender")+P("ItalicAngle"))/lower)*number/function(data,key,value)
+ data.metadata[key]=value
+ end+P("Comment")*spacing*(P(false)+(fontdata*C("DESIGNSIZE")*number*rest)/set_1
++(fontdata*C("TFM designsize")*number*rest)/set_1+(fontdata*C("DesignSize")*number*rest)/set_1+(fontdata*C("CODINGSCHEME")*words*rest)/set_1
++(fontdata*C("CHECKSUM")*number*words*rest)/set_1
++(fontdata*C("SPACE")*number*plus*minus*rest)/set_3
++(fontdata*C("QUAD")*number*rest)/set_1
++(fontdata*C("EXTRASPACE")*number*rest)/set_1
++(fontdata*C("NUM")*number*number*number*rest)/set_3
++(fontdata*C("DENOM")*number*number*rest)/set_2
++(fontdata*C("SUP")*number*number*number*rest)/set_3
++(fontdata*C("SUB")*number*number*rest)/set_2
++(fontdata*C("SUPDROP")*number*rest)/set_1
++(fontdata*C("SUBDROP")*number*rest)/set_1
++(fontdata*C("DELIM")*number*number*rest)/set_2
++(fontdata*C("AXISHEIGHT")*number*rest)/set_1
+ )
+local fullparser=(P("StartFontMetrics")*fontdata*name/start )*(p_charmetrics+p_kernpairs+p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop )
+local infoparser=(P("StartFontMetrics")*fontdata*name/start )*(p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop )
+local function read(filename,parser)
+ local afmblob=io.loaddata(filename)
+ if afmblob then
+ local data={
+ resources={
+ filename=resolvers.unresolve(filename),
+ version=afm.version,
+ creator="context mkiv",
+ },
+ properties={
+ hasitalics=false,
+ },
+ goodies={},
+ metadata={
+ filename=file.removesuffix(file.basename(filename))
+ },
+ characters={
+ },
+ descriptions={
+ },
+ }
+ if trace_loading then
+ report_afm("parsing afm file %a",filename)
+ end
+ lpegmatch(parser,afmblob,1,data)
+ return data
+ else
+ if trace_loading then
+ report_afm("no valid afm file %a",filename)
+ end
+ return nil
+ end
+end
+function readers.loadfont(afmname,pfbname)
+ local data=read(resolvers.findfile(afmname),fullparser)
+ if data then
+ if not pfbname or pfbname=="" then
+ pfbname=resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb"))
+ end
+ if pfbname and pfbname~="" then
+ data.resources.filename=resolvers.unresolve(pfbname)
+ get_indexes(data,pfbname)
+ return data
+ else
+ report_afm("no pfb file for %a",afmname)
+ end
+ end
+end
+function readers.loadshapes(filename)
+ local fullname=resolvers.findfile(filename) or ""
+ if fullname=="" then
+ return {
+ filename="not found: "..filename,
+ glyphs={}
+ }
+ else
+ return {
+ filename=fullname,
+ format="opentype",
+ glyphs=get_shapes(fullname) or {},
+ units=1000,
+ }
+ end
+end
+function readers.getinfo(filename)
+ local data=read(resolvers.findfile(filename),infoparser)
+ if data then
+ return data.metadata
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-one']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local fonts,logs,trackers,containers,resolvers=fonts,logs,trackers,containers,resolvers
+local next,type,tonumber,rawget=next,type,tonumber,rawget
+local match,gsub=string.match,string.gsub
+local abs=math.abs
+local P,S,R,Cmt,C,Ct,Cs,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg
+local lpegmatch,patterns=lpeg.match,lpeg.patterns
+local sortedhash=table.sortedhash
+local trace_features=false trackers.register("afm.features",function(v) trace_features=v end)
+local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
+local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local report_afm=logs.reporter("fonts","afm loading")
+local setmetatableindex=table.setmetatableindex
+local derivetable=table.derive
+local findbinfile=resolvers.findbinfile
+local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+local definers=fonts.definers
+local readers=fonts.readers
+local constructors=fonts.constructors
+local afm=constructors.handlers.afm
+local pfb=constructors.handlers.pfb
+local otf=fonts.handlers.otf
+local otfreaders=otf.readers
+local otfenhancers=otf.enhancers
+local afmfeatures=constructors.features.afm
+local registerafmfeature=afmfeatures.register
+local afmenhancers=constructors.enhancers.afm
+local registerafmenhancer=afmenhancers.register
+afm.version=1.513
+afm.cache=containers.define("fonts","one",afm.version,true)
+afm.autoprefixed=true
+afm.helpdata={}
+afm.syncspace=true
+local overloads=fonts.mappings.overloads
+local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes
+function afm.load(filename)
+ filename=resolvers.findfile(filename,'afm') or ""
+ if filename~="" and not fonts.names.ignoredfile(filename) then
+ local name=file.removesuffix(file.basename(filename))
+ local data=containers.read(afm.cache,name)
+ local attr=lfs.attributes(filename)
+ local size=attr and attr.size or 0
+ local time=attr and attr.modification or 0
+ local pfbfile=file.replacesuffix(name,"pfb")
+ local pfbname=resolvers.findfile(pfbfile,"pfb") or ""
+ if pfbname=="" then
+ pfbname=resolvers.findfile(file.basename(pfbfile),"pfb") or ""
+ end
+ local pfbsize=0
+ local pfbtime=0
+ if pfbname~="" then
+ local attr=lfs.attributes(pfbname)
+ pfbsize=attr.size or 0
+ pfbtime=attr.modification or 0
+ end
+ if not data or data.size~=size or data.time~=time or data.pfbsize~=pfbsize or data.pfbtime~=pfbtime then
+ report_afm("reading %a",filename)
+ data=afm.readers.loadfont(filename,pfbname)
+ if data then
+ afmenhancers.apply(data,filename)
+ fonts.mappings.addtounicode(data,filename)
+ otfreaders.stripredundant(data)
+ otfreaders.pack(data)
+ data.size=size
+ data.time=time
+ data.pfbsize=pfbsize
+ data.pfbtime=pfbtime
+ report_afm("saving %a in cache",name)
+ data=containers.write(afm.cache,name,data)
+ data=containers.read(afm.cache,name)
+ end
+ end
+ if data then
+ otfreaders.unpack(data)
+ otfreaders.expand(data)
+ otfreaders.addunicodetable(data)
+ otfenhancers.apply(data,filename,data)
+ if applyruntimefixes then
+ applyruntimefixes(filename,data)
+ end
+ end
+ return data
+ end
+end
+local uparser=fonts.mappings.makenameparser()
+local function enhance_unify_names(data,filename)
+ local unicodevector=fonts.encodings.agl.unicodes
+ local unicodes={}
+ local names={}
+ local private=data.private or privateoffset
+ local descriptions=data.descriptions
+ for name,blob in sortedhash(data.characters) do
+ local code=unicodevector[name]
+ if not code then
+ code=lpegmatch(uparser,name)
+ if type(code)~="number" then
+ code=private
+ private=private+1
+ report_afm("assigning private slot %U for unknown glyph name %a",code,name)
+ end
+ end
+ local index=blob.index
+ unicodes[name]=code
+ names[name]=index
+ blob.name=name
+ descriptions[code]={
+ boundingbox=blob.boundingbox,
+ width=blob.width,
+ kerns=blob.kerns,
+ index=index,
+ name=name,
+ }
+ end
+ for unicode,description in next,descriptions do
+ local kerns=description.kerns
+ if kerns then
+ local krn={}
+ for name,kern in next,kerns do
+ local unicode=unicodes[name]
+ if unicode then
+ krn[unicode]=kern
+ else
+ end
+ end
+ description.kerns=krn
+ end
+ end
+ data.characters=nil
+ data.private=private
+ local resources=data.resources
+ local filename=resources.filename or file.removesuffix(file.basename(filename))
+ resources.filename=resolvers.unresolve(filename)
+ resources.unicodes=unicodes
+ resources.marks={}
+end
+local everywhere={ ["*"]={ ["*"]=true } }
+local noflags={ false,false,false,false }
+local function enhance_normalize_features(data)
+ local ligatures=setmetatableindex("table")
+ local kerns=setmetatableindex("table")
+ local extrakerns=setmetatableindex("table")
+ for u,c in next,data.descriptions do
+ local l=c.ligatures
+ local k=c.kerns
+ local e=c.extrakerns
+ if l then
+ ligatures[u]=l
+ for u,v in next,l do
+ l[u]={ ligature=v }
+ end
+ c.ligatures=nil
+ end
+ if k then
+ kerns[u]=k
+ for u,v in next,k do
+ k[u]=v
+ end
+ c.kerns=nil
+ end
+ if e then
+ extrakerns[u]=e
+ for u,v in next,e do
+ e[u]=v
+ end
+ c.extrakerns=nil
+ end
+ end
+ local features={
+ gpos={},
+ gsub={},
+ }
+ local sequences={
+ }
+ if next(ligatures) then
+ features.gsub.liga=everywhere
+ data.properties.hasligatures=true
+ sequences[#sequences+1]={
+ features={
+ liga=everywhere,
+ },
+ flags=noflags,
+ name="s_s_0",
+ nofsteps=1,
+ order={ "liga" },
+ type="gsub_ligature",
+ steps={
+ {
+ coverage=ligatures,
+ },
+ },
+ }
+ end
+ if next(kerns) then
+ features.gpos.kern=everywhere
+ data.properties.haskerns=true
+ sequences[#sequences+1]={
+ features={
+ kern=everywhere,
+ },
+ flags=noflags,
+ name="p_s_0",
+ nofsteps=1,
+ order={ "kern" },
+ type="gpos_pair",
+ steps={
+ {
+ format="kern",
+ coverage=kerns,
+ },
+ },
+ }
+ end
+ if next(extrakerns) then
+ features.gpos.extrakerns=everywhere
+ data.properties.haskerns=true
+ sequences[#sequences+1]={
+ features={
+ extrakerns=everywhere,
+ },
+ flags=noflags,
+ name="p_s_1",
+ nofsteps=1,
+ order={ "extrakerns" },
+ type="gpos_pair",
+ steps={
+ {
+ format="kern",
+ coverage=extrakerns,
+ },
+ },
+ }
+ end
+ data.resources.features=features
+ data.resources.sequences=sequences
+end
+local function enhance_fix_names(data)
+ for k,v in next,data.descriptions do
+ local n=v.name
+ local r=overloads[n]
+ if r then
+ local name=r.name
+ if trace_indexing then
+ report_afm("renaming characters %a to %a",n,name)
+ end
+ v.name=name
+ v.unicode=r.unicode
+ end
+ end
+end
+local addthem=function(rawdata,ligatures)
+ if ligatures then
+ local descriptions=rawdata.descriptions
+ local resources=rawdata.resources
+ local unicodes=resources.unicodes
+ for ligname,ligdata in next,ligatures do
+ local one=descriptions[unicodes[ligname]]
+ if one then
+ for _,pair in next,ligdata do
+ local two=unicodes[pair[1]]
+ local three=unicodes[pair[2]]
+ if two and three then
+ local ol=one.ligatures
+ if ol then
+ if not ol[two] then
+ ol[two]=three
+ end
+ else
+ one.ligatures={ [two]=three }
+ end
+ end
+ end
+ end
+ end
+ end
+end
+local function enhance_add_ligatures(rawdata)
+ addthem(rawdata,afm.helpdata.ligatures)
+end
+local function enhance_add_extra_kerns(rawdata)
+ local descriptions=rawdata.descriptions
+ local resources=rawdata.resources
+ local unicodes=resources.unicodes
+ local function do_it_left(what)
+ if what then
+ for unicode,description in next,descriptions do
+ local kerns=description.kerns
+ if kerns then
+ local extrakerns
+ for complex,simple in next,what do
+ complex=unicodes[complex]
+ simple=unicodes[simple]
+ if complex and simple then
+ local ks=kerns[simple]
+ if ks and not kerns[complex] then
+ if extrakerns then
+ extrakerns[complex]=ks
+ else
+ extrakerns={ [complex]=ks }
+ end
+ end
+ end
+ end
+ if extrakerns then
+ description.extrakerns=extrakerns
+ end
+ end
+ end
+ end
+ end
+ local function do_it_copy(what)
+ if what then
+ for complex,simple in next,what do
+ complex=unicodes[complex]
+ simple=unicodes[simple]
+ if complex and simple then
+ local complexdescription=descriptions[complex]
+ if complexdescription then
+ local simpledescription=descriptions[complex]
+ if simpledescription then
+ local extrakerns
+ local kerns=simpledescription.kerns
+ if kerns then
+ for unicode,kern in next,kerns do
+ if extrakerns then
+ extrakerns[unicode]=kern
+ else
+ extrakerns={ [unicode]=kern }
+ end
+ end
+ end
+ local extrakerns=simpledescription.extrakerns
+ if extrakerns then
+ for unicode,kern in next,extrakerns do
+ if extrakerns then
+ extrakerns[unicode]=kern
+ else
+ extrakerns={ [unicode]=kern }
+ end
+ end
+ end
+ if extrakerns then
+ complexdescription.extrakerns=extrakerns
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ do_it_left(afm.helpdata.leftkerned)
+ do_it_left(afm.helpdata.bothkerned)
+ do_it_copy(afm.helpdata.bothkerned)
+ do_it_copy(afm.helpdata.rightkerned)
+end
+local function adddimensions(data)
+ if data then
+ for unicode,description in next,data.descriptions do
+ local bb=description.boundingbox
+ if bb then
+ local ht=bb[4]
+ local dp=-bb[2]
+ if ht==0 or ht<0 then
+ else
+ description.height=ht
+ end
+ if dp==0 or dp<0 then
+ else
+ description.depth=dp
+ end
+ end
+ end
+ end
+end
+local function copytotfm(data)
+ if data and data.descriptions then
+ local metadata=data.metadata
+ local resources=data.resources
+ local properties=derivetable(data.properties)
+ local descriptions=derivetable(data.descriptions)
+ local goodies=derivetable(data.goodies)
+ local characters={}
+ local parameters={}
+ local unicodes=resources.unicodes
+ for unicode,description in next,data.descriptions do
+ characters[unicode]={}
+ end
+ local filename=constructors.checkedfilename(resources)
+ local fontname=metadata.fontname or metadata.fullname
+ local fullname=metadata.fullname or metadata.fontname
+ local endash=0x2013
+ local emdash=0x2014
+ local space=0x0020
+ local spacer="space"
+ local spaceunits=500
+ local monospaced=metadata.monospaced
+ local charwidth=metadata.charwidth
+ local italicangle=metadata.italicangle
+ local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight
+ properties.monospaced=monospaced
+ parameters.italicangle=italicangle
+ parameters.charwidth=charwidth
+ parameters.charxheight=charxheight
+ local d_endash=descriptions[endash]
+ local d_emdash=descriptions[emdash]
+ local d_space=descriptions[space]
+ if not d_space or d_space==0 then
+ d_space=d_endash
+ end
+ if d_space then
+ spaceunits,spacer=d_space.width or 0,"space"
+ end
+ if properties.monospaced then
+ if spaceunits==0 and d_emdash then
+ spaceunits,spacer=d_emdash.width or 0,"emdash"
+ end
+ else
+ if spaceunits==0 and d_endash then
+ spaceunits,spacer=d_emdash.width or 0,"endash"
+ end
+ end
+ if spaceunits==0 and charwidth then
+ spaceunits,spacer=charwidth or 0,"charwidth"
+ end
+ if spaceunits==0 then
+ spaceunits=tonumber(spaceunits) or 500
+ end
+ if spaceunits==0 then
+ spaceunits=500
+ end
+ parameters.slant=0
+ parameters.space=spaceunits
+ parameters.space_stretch=500
+ parameters.space_shrink=333
+ parameters.x_height=400
+ parameters.quad=1000
+ if italicangle and italicangle~=0 then
+ parameters.italicangle=italicangle
+ parameters.italicfactor=math.cos(math.rad(90+italicangle))
+ parameters.slant=- math.tan(italicangle*math.pi/180)
+ end
+ if monospaced then
+ parameters.space_stretch=0
+ parameters.space_shrink=0
+ elseif afm.syncspace then
+ parameters.space_stretch=spaceunits/2
+ parameters.space_shrink=spaceunits/3
+ end
+ parameters.extra_space=parameters.space_shrink
+ if charxheight then
+ parameters.x_height=charxheight
+ else
+ local x=0x0078
+ if x then
+ local x=descriptions[x]
+ if x then
+ parameters.x_height=x.height
+ end
+ end
+ end
+ if metadata.sup then
+ local dummy={ 0,0,0 }
+ parameters[ 1]=metadata.designsize or 0
+ parameters[ 2]=metadata.checksum or 0
+ parameters[ 3],
+ parameters[ 4],
+ parameters[ 5]=unpack(metadata.space or dummy)
+ parameters[ 6]=metadata.quad or 0
+ parameters[ 7]=metadata.extraspace or 0
+ parameters[ 8],
+ parameters[ 9],
+ parameters[10]=unpack(metadata.num or dummy)
+ parameters[11],
+ parameters[12]=unpack(metadata.denom or dummy)
+ parameters[13],
+ parameters[14],
+ parameters[15]=unpack(metadata.sup or dummy)
+ parameters[16],
+ parameters[17]=unpack(metadata.sub or dummy)
+ parameters[18]=metadata.supdrop or 0
+ parameters[19]=metadata.subdrop or 0
+ parameters[20],
+ parameters[21]=unpack(metadata.delim or dummy)
+ parameters[22]=metadata.axisheight or 0
+ end
+ parameters.designsize=(metadata.designsize or 10)*65536
+ parameters.ascender=abs(metadata.ascender or 0)
+ parameters.descender=abs(metadata.descender or 0)
+ parameters.units=1000
+ properties.spacer=spacer
+ properties.encodingbytes=2
+ properties.format=fonts.formats[filename] or "type1"
+ properties.filename=filename
+ properties.fontname=fontname
+ properties.fullname=fullname
+ properties.psname=fullname
+ properties.name=filename or fullname or fontname
+ properties.private=properties.private or data.private or privateoffset
+ if next(characters) then
+ return {
+ characters=characters,
+ descriptions=descriptions,
+ parameters=parameters,
+ resources=resources,
+ properties=properties,
+ goodies=goodies,
+ }
+ end
+ end
+ return nil
+end
+function afm.setfeatures(tfmdata,features)
+ local okay=constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm)
+ if okay then
+ return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm)
+ else
+ return {}
+ end
+end
+local function addtables(data)
+ local resources=data.resources
+ local lookuptags=resources.lookuptags
+ local unicodes=resources.unicodes
+ if not lookuptags then
+ lookuptags={}
+ resources.lookuptags=lookuptags
+ end
+ setmetatableindex(lookuptags,function(t,k)
+ local v=type(k)=="number" and ("lookup "..k) or k
+ t[k]=v
+ return v
+ end)
+ if not unicodes then
+ unicodes={}
+ resources.unicodes=unicodes
+ setmetatableindex(unicodes,function(t,k)
+ setmetatableindex(unicodes,nil)
+ for u,d in next,data.descriptions do
+ local n=d.name
+ if n then
+ t[n]=u
+ end
+ end
+ return rawget(t,k)
+ end)
+ end
+ constructors.addcoreunicodes(unicodes)
+end
+local function afmtotfm(specification)
+ local afmname=specification.filename or specification.name
+ if specification.forced=="afm" or specification.format=="afm" then
+ if trace_loading then
+ report_afm("forcing afm format for %a",afmname)
+ end
+ else
+ local tfmname=findbinfile(afmname,"ofm") or ""
+ if tfmname~="" then
+ if trace_loading then
+ report_afm("fallback from afm to tfm for %a",afmname)
+ end
+ return
+ end
+ end
+ if afmname~="" then
+ local features=constructors.checkedfeatures("afm",specification.features.normal)
+ specification.features.normal=features
+ constructors.hashinstance(specification,true)
+ specification=definers.resolve(specification)
+ local cache_id=specification.hash
+ local tfmdata=containers.read(constructors.cache,cache_id)
+ if not tfmdata then
+ local rawdata=afm.load(afmname)
+ if rawdata and next(rawdata) then
+ addtables(rawdata)
+ adddimensions(rawdata)
+ tfmdata=copytotfm(rawdata)
+ if tfmdata and next(tfmdata) then
+ local shared=tfmdata.shared
+ if not shared then
+ shared={}
+ tfmdata.shared=shared
+ end
+ shared.rawdata=rawdata
+ shared.dynamics={}
+ tfmdata.changed={}
+ shared.features=features
+ shared.processes=afm.setfeatures(tfmdata,features)
+ end
+ elseif trace_loading then
+ report_afm("no (valid) afm file found with name %a",afmname)
+ end
+ tfmdata=containers.write(constructors.cache,cache_id,tfmdata)
+ end
+ return tfmdata
+ end
+end
+local function read_from_afm(specification)
+ local tfmdata=afmtotfm(specification)
+ if tfmdata then
+ tfmdata.properties.name=specification.name
+ tfmdata=constructors.scale(tfmdata,specification)
+ local allfeatures=tfmdata.shared.features or specification.features.normal
+ constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm)
+ fonts.loggers.register(tfmdata,'afm',specification)
+ end
+ return tfmdata
+end
+registerafmfeature {
+ name="mode",
+ description="mode",
+ initializers={
+ base=otf.modeinitializer,
+ node=otf.modeinitializer,
+ }
+}
+registerafmfeature {
+ name="features",
+ description="features",
+ default=true,
+ initializers={
+ node=otf.nodemodeinitializer,
+ base=otf.basemodeinitializer,
+ },
+ processors={
+ node=otf.featuresprocessor,
+ }
+}
+fonts.formats.afm="type1"
+fonts.formats.pfb="type1"
+local function check_afm(specification,fullname)
+ local foundname=findbinfile(fullname,'afm') or ""
+ if foundname=="" then
+ foundname=fonts.names.getfilename(fullname,"afm") or ""
+ end
+ if fullname and foundname=="" and afm.autoprefixed then
+ local encoding,shortname=match(fullname,"^(.-)%-(.*)$")
+ if encoding and shortname and fonts.encodings.known[encoding] then
+ shortname=findbinfile(shortname,'afm') or ""
+ if shortname~="" then
+ foundname=shortname
+ if trace_defining then
+ report_afm("stripping encoding prefix from filename %a",afmname)
+ end
+ end
+ end
+ end
+ if foundname~="" then
+ specification.filename=foundname
+ specification.format="afm"
+ return read_from_afm(specification)
+ end
+end
+function readers.afm(specification,method)
+ local fullname=specification.filename or ""
+ local tfmdata=nil
+ if fullname=="" then
+ local forced=specification.forced or ""
+ if forced~="" then
+ tfmdata=check_afm(specification,specification.name.."."..forced)
+ end
+ if not tfmdata then
+ local check_tfm=readers.check_tfm
+ method=(check_tfm and (method or definers.method or "afm or tfm")) or "afm"
+ if method=="tfm" then
+ tfmdata=check_tfm(specification,specification.name)
+ elseif method=="afm" then
+ tfmdata=check_afm(specification,specification.name)
+ elseif method=="tfm or afm" then
+ tfmdata=check_tfm(specification,specification.name) or check_afm(specification,specification.name)
+ else
+ tfmdata=check_afm(specification,specification.name) or check_tfm(specification,specification.name)
+ end
+ end
+ else
+ tfmdata=check_afm(specification,fullname)
+ end
+ return tfmdata
+end
+function readers.pfb(specification,method)
+ local original=specification.specification
+ if trace_defining then
+ report_afm("using afm reader for %a",original)
+ end
+ specification.forced="afm"
+ local function swap(name)
+ local value=specification[swap]
+ if value then
+ specification[swap]=gsub("%.pfb",".afm",1)
+ end
+ end
+ swap("filename")
+ swap("fullname")
+ swap("forcedname")
+ swap("specification")
+ return readers.afm(specification,method)
+end
+registerafmenhancer("unify names",enhance_unify_names)
+registerafmenhancer("add ligatures",enhance_add_ligatures)
+registerafmenhancer("add extra kerns",enhance_add_extra_kerns)
+registerafmenhancer("normalize features",enhance_normalize_features)
+registerafmenhancer("check extra features",otfenhancers.enhance)
+registerafmenhancer("fix names",enhance_fix_names)
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-afk']={
+ version=1.001,
+ comment="companion to font-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
+ dataonly=true,
+}
+local allocate=utilities.storage.allocate
+fonts.handlers.afm.helpdata={
+ ligatures=allocate {
+ ['f']={
+ { 'f','ff' },
+ { 'i','fi' },
+ { 'l','fl' },
+ },
+ ['ff']={
+ { 'i','ffi' }
+ },
+ ['fi']={
+ { 'i','fii' }
+ },
+ ['fl']={
+ { 'i','fli' }
+ },
+ ['s']={
+ { 't','st' }
+ },
+ ['i']={
+ { 'j','ij' }
+ },
+ },
+ texligatures=allocate {
+ ['quoteleft']={
+ { 'quoteleft','quotedblleft' }
+ },
+ ['quoteright']={
+ { 'quoteright','quotedblright' }
+ },
+ ['hyphen']={
+ { 'hyphen','endash' }
+ },
+ ['endash']={
+ { 'hyphen','emdash' }
+ }
+ },
+ leftkerned=allocate {
+ AEligature="A",aeligature="a",
+ OEligature="O",oeligature="o",
+ IJligature="I",ijligature="i",
+ AE="A",ae="a",
+ OE="O",oe="o",
+ IJ="I",ij="i",
+ Ssharp="S",ssharp="s",
+ },
+ rightkerned=allocate {
+ AEligature="E",aeligature="e",
+ OEligature="E",oeligature="e",
+ IJligature="J",ijligature="j",
+ AE="E",ae="e",
+ OE="E",oe="e",
+ IJ="J",ij="j",
+ Ssharp="S",ssharp="s",
+ },
+ bothkerned=allocate {
+ Acircumflex="A",acircumflex="a",
+ Ccircumflex="C",ccircumflex="c",
+ Ecircumflex="E",ecircumflex="e",
+ Gcircumflex="G",gcircumflex="g",
+ Hcircumflex="H",hcircumflex="h",
+ Icircumflex="I",icircumflex="i",
+ Jcircumflex="J",jcircumflex="j",
+ Ocircumflex="O",ocircumflex="o",
+ Scircumflex="S",scircumflex="s",
+ Ucircumflex="U",ucircumflex="u",
+ Wcircumflex="W",wcircumflex="w",
+ Ycircumflex="Y",ycircumflex="y",
+ Agrave="A",agrave="a",
+ Egrave="E",egrave="e",
+ Igrave="I",igrave="i",
+ Ograve="O",ograve="o",
+ Ugrave="U",ugrave="u",
+ Ygrave="Y",ygrave="y",
+ Atilde="A",atilde="a",
+ Itilde="I",itilde="i",
+ Otilde="O",otilde="o",
+ Utilde="U",utilde="u",
+ Ntilde="N",ntilde="n",
+ Adiaeresis="A",adiaeresis="a",Adieresis="A",adieresis="a",
+ Ediaeresis="E",ediaeresis="e",Edieresis="E",edieresis="e",
+ Idiaeresis="I",idiaeresis="i",Idieresis="I",idieresis="i",
+ Odiaeresis="O",odiaeresis="o",Odieresis="O",odieresis="o",
+ Udiaeresis="U",udiaeresis="u",Udieresis="U",udieresis="u",
+ Ydiaeresis="Y",ydiaeresis="y",Ydieresis="Y",ydieresis="y",
+ Aacute="A",aacute="a",
+ Cacute="C",cacute="c",
+ Eacute="E",eacute="e",
+ Iacute="I",iacute="i",
+ Lacute="L",lacute="l",
+ Nacute="N",nacute="n",
+ Oacute="O",oacute="o",
+ Racute="R",racute="r",
+ Sacute="S",sacute="s",
+ Uacute="U",uacute="u",
+ Yacute="Y",yacute="y",
+ Zacute="Z",zacute="z",
+ Dstroke="D",dstroke="d",
+ Hstroke="H",hstroke="h",
+ Tstroke="T",tstroke="t",
+ Cdotaccent="C",cdotaccent="c",
+ Edotaccent="E",edotaccent="e",
+ Gdotaccent="G",gdotaccent="g",
+ Idotaccent="I",idotaccent="i",
+ Zdotaccent="Z",zdotaccent="z",
+ Amacron="A",amacron="a",
+ Emacron="E",emacron="e",
+ Imacron="I",imacron="i",
+ Omacron="O",omacron="o",
+ Umacron="U",umacron="u",
+ Ccedilla="C",ccedilla="c",
+ Kcedilla="K",kcedilla="k",
+ Lcedilla="L",lcedilla="l",
+ Ncedilla="N",ncedilla="n",
+ Rcedilla="R",rcedilla="r",
+ Scedilla="S",scedilla="s",
+ Tcedilla="T",tcedilla="t",
+ Ohungarumlaut="O",ohungarumlaut="o",
+ Uhungarumlaut="U",uhungarumlaut="u",
+ Aogonek="A",aogonek="a",
+ Eogonek="E",eogonek="e",
+ Iogonek="I",iogonek="i",
+ Uogonek="U",uogonek="u",
+ Aring="A",aring="a",
+ Uring="U",uring="u",
+ Abreve="A",abreve="a",
+ Ebreve="E",ebreve="e",
+ Gbreve="G",gbreve="g",
+ Ibreve="I",ibreve="i",
+ Obreve="O",obreve="o",
+ Ubreve="U",ubreve="u",
+ Ccaron="C",ccaron="c",
+ Dcaron="D",dcaron="d",
+ Ecaron="E",ecaron="e",
+ Lcaron="L",lcaron="l",
+ Ncaron="N",ncaron="n",
+ Rcaron="R",rcaron="r",
+ Scaron="S",scaron="s",
+ Tcaron="T",tcaron="t",
+ Zcaron="Z",zcaron="z",
+ dotlessI="I",dotlessi="i",
+ dotlessJ="J",dotlessj="j",
+ AEligature="AE",aeligature="ae",AE="AE",ae="ae",
+ OEligature="OE",oeligature="oe",OE="OE",oe="oe",
+ IJligature="IJ",ijligature="ij",IJ="IJ",ij="ij",
+ Lstroke="L",lstroke="l",Lslash="L",lslash="l",
+ Ostroke="O",ostroke="o",Oslash="O",oslash="o",
+ Ssharp="SS",ssharp="ss",
+ Aumlaut="A",aumlaut="a",
+ Eumlaut="E",eumlaut="e",
+ Iumlaut="I",iumlaut="i",
+ Oumlaut="O",oumlaut="o",
+ Uumlaut="U",uumlaut="u",
+ }
+}
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['luatex-fonts-tfm']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type=next,type
+local match,format=string.match,string.format
+local concat,sortedhash=table.concat,table.sortedhash
+local idiv=number.idiv
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end)
+local report_defining=logs.reporter("fonts","defining")
+local report_tfm=logs.reporter("fonts","tfm loading")
+local findbinfile=resolvers.findbinfile
+local setmetatableindex=table.setmetatableindex
+local fonts=fonts
+local handlers=fonts.handlers
+local helpers=fonts.helpers
+local readers=fonts.readers
+local constructors=fonts.constructors
+local encodings=fonts.encodings
+local tfm=constructors.handlers.tfm
+tfm.version=1.000
+tfm.maxnestingdepth=5
+tfm.maxnestingsize=65536*1024
+local otf=fonts.handlers.otf
+local otfenhancers=otf.enhancers
+local tfmfeatures=constructors.features.tfm
+local registertfmfeature=tfmfeatures.register
+local tfmenhancers=constructors.enhancers.tfm
+local registertfmenhancer=tfmenhancers.register
+local charcommand=helpers.commands.char
+constructors.resolvevirtualtoo=false
+fonts.formats.tfm="type1"
+fonts.formats.ofm="type1"
+function tfm.setfeatures(tfmdata,features)
+ local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm)
+ if okay then
+ return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm)
+ else
+ return {}
+ end
+end
+local depth={}
+local loadtfm=font.read_tfm
+local loadvf=font.read_vf
+local function read_from_tfm(specification)
+ local filename=specification.filename
+ local size=specification.size
+ depth[filename]=(depth[filename] or 0)+1
+ if trace_defining then
+ report_defining("loading tfm file %a at size %s",filename,size)
+ end
+ local tfmdata=loadtfm(filename,size)
+ if tfmdata then
+ local features=specification.features and specification.features.normal or {}
+ local features=constructors.checkedfeatures("tfm",features)
+ specification.features.normal=features
+ local newtfmdata=(depth[filename]==1) and tfm.reencode(tfmdata,specification)
+ if newtfmdata then
+ tfmdata=newtfmdata
+ end
+ local resources=tfmdata.resources or {}
+ local properties=tfmdata.properties or {}
+ local parameters=tfmdata.parameters or {}
+ local shared=tfmdata.shared or {}
+ shared.features=features
+ shared.resources=resources
+ properties.name=tfmdata.name
+ properties.fontname=tfmdata.fontname
+ properties.psname=tfmdata.psname
+ properties.fullname=tfmdata.fullname
+ properties.filename=specification.filename
+ properties.format=tfmdata.format or fonts.formats.tfm
+ properties.usedbitmap=tfmdata.usedbitmap
+ tfmdata.properties=properties
+ tfmdata.resources=resources
+ tfmdata.parameters=parameters
+ tfmdata.shared=shared
+ shared.rawdata={ resources=resources }
+ shared.features=features
+ if newtfmdata then
+ if not resources.marks then
+ resources.marks={}
+ end
+ if not resources.sequences then
+ resources.sequences={}
+ end
+ if not resources.features then
+ resources.features={
+ gsub={},
+ gpos={},
+ }
+ end
+ if not tfmdata.changed then
+ tfmdata.changed={}
+ end
+ if not tfmdata.descriptions then
+ tfmdata.descriptions=tfmdata.characters
+ end
+ otf.readers.addunicodetable(tfmdata)
+ tfmenhancers.apply(tfmdata,filename)
+ constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm)
+ otf.readers.unifymissing(tfmdata)
+ fonts.mappings.addtounicode(tfmdata,filename)
+ tfmdata.tounicode=1
+ local tounicode=fonts.mappings.tounicode
+ for unicode,v in next,tfmdata.characters do
+ local u=v.unicode
+ if u then
+ v.tounicode=tounicode(u)
+ end
+ end
+ if tfmdata.usedbitmap then
+ tfm.addtounicode(tfmdata)
+ end
+ end
+ shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil
+ if size<0 then
+ size=idiv(65536*-size,100)
+ end
+ parameters.factor=1
+ parameters.units=1000
+ parameters.size=size
+ parameters.slant=parameters.slant or parameters[1] or 0
+ parameters.space=parameters.space or parameters[2] or 0
+ parameters.space_stretch=parameters.space_stretch or parameters[3] or 0
+ parameters.space_shrink=parameters.space_shrink or parameters[4] or 0
+ parameters.x_height=parameters.x_height or parameters[5] or 0
+ parameters.quad=parameters.quad or parameters[6] or 0
+ parameters.extra_space=parameters.extra_space or parameters[7] or 0
+ constructors.enhanceparameters(parameters)
+ properties.private=properties.private or tfmdata.private or privateoffset
+ if newtfmdata then
+ elseif constructors.resolvevirtualtoo then
+ fonts.loggers.register(tfmdata,file.suffix(filename),specification)
+ local vfname=findbinfile(specification.name,'ovf')
+ if vfname and vfname~="" then
+ local vfdata=loadvf(vfname,size)
+ if vfdata then
+ local chars=tfmdata.characters
+ for k,v in next,vfdata.characters do
+ chars[k].commands=v.commands
+ end
+ properties.virtualized=true
+ tfmdata.fonts=vfdata.fonts
+ tfmdata.type="virtual"
+ local fontlist=vfdata.fonts
+ local name=file.nameonly(filename)
+ for i=1,#fontlist do
+ local n=fontlist[i].name
+ local s=fontlist[i].size
+ local d=depth[filename]
+ s=constructors.scaled(s,vfdata.designsize)
+ if d>tfm.maxnestingdepth then
+ report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth)
+ fontlist[i]={ id=0 }
+ elseif (d>1) and (s>tfm.maxnestingsize) then
+ report_defining("virtual font %a exceeds size %s",n,s)
+ fontlist[i]={ id=0 }
+ else
+ local t,id=constructors.readanddefine(n,s)
+ fontlist[i]={ id=id }
+ end
+ end
+ end
+ end
+ end
+ properties.haskerns=true
+ properties.hasligatures=true
+ properties.hasitalics=true
+ resources.unicodes={}
+ resources.lookuptags={}
+ depth[filename]=depth[filename]-1
+ return tfmdata
+ else
+ depth[filename]=depth[filename]-1
+ end
+end
+local function check_tfm(specification,fullname)
+ local foundname=findbinfile(fullname,'tfm') or ""
+ if foundname=="" then
+ foundname=findbinfile(fullname,'ofm') or ""
+ end
+ if foundname=="" then
+ foundname=fonts.names.getfilename(fullname,"tfm") or ""
+ end
+ if foundname~="" then
+ specification.filename=foundname
+ specification.format="ofm"
+ return read_from_tfm(specification)
+ elseif trace_defining then
+ report_defining("loading tfm with name %a fails",specification.name)
+ end
+end
+readers.check_tfm=check_tfm
+function readers.tfm(specification)
+ local fullname=specification.filename or ""
+ if fullname=="" then
+ local forced=specification.forced or ""
+ if forced~="" then
+ fullname=specification.name.."."..forced
+ else
+ fullname=specification.name
+ end
+ end
+ return check_tfm(specification,fullname)
+end
+readers.ofm=readers.tfm
+do
+ local outfiles={}
+ local tfmcache=table.setmetatableindex(function(t,tfmdata)
+ local id=font.define(tfmdata)
+ t[tfmdata]=id
+ return id
+ end)
+ local encdone=table.setmetatableindex("table")
+ function tfm.reencode(tfmdata,specification)
+ local features=specification.features
+ if not features then
+ return
+ end
+ local features=features.normal
+ if not features then
+ return
+ end
+ local tfmfile=file.basename(tfmdata.name)
+ local encfile=features.reencode
+ local pfbfile=features.pfbfile
+ local bitmap=features.bitmap
+ if not encfile then
+ return
+ end
+ local pfbfile=outfiles[tfmfile]
+ if pfbfile==nil then
+ if bitmap then
+ pfbfile=false
+ elseif type(pfbfile)~="string" then
+ pfbfile=tfmfile
+ end
+ if type(pfbfile)=="string" then
+ pfbfile=file.addsuffix(pfbfile,"pfb")
+ report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile)
+ else
+ report_tfm("using bitmap shapes for %a",tfmfile)
+ pfbfile=false
+ end
+ outfiles[tfmfile]=pfbfile
+ end
+ local encoding=false
+ local vector=false
+ if type(pfbfile)=="string" then
+ local pfb=constructors.handlers.pfb
+ if pfb and pfb.loadvector then
+ local v,e=pfb.loadvector(pfbfile)
+ if v then
+ vector=v
+ end
+ if e then
+ encoding=e
+ end
+ end
+ end
+ if type(encfile)=="string" and encfile~="auto" then
+ encoding=fonts.encodings.load(file.addsuffix(encfile,"enc"))
+ if encoding then
+ encoding=encoding.vector
+ end
+ end
+ if not encoding then
+ report_tfm("bad encoding for %a, quitting",tfmfile)
+ return
+ end
+ local unicoding=fonts.encodings.agl and fonts.encodings.agl.unicodes
+ local virtualid=tfmcache[tfmdata]
+ local tfmdata=table.copy(tfmdata)
+ local characters={}
+ local originals=tfmdata.characters
+ local indices={}
+ local parentfont={ "font",1 }
+ local private=tfmdata.privateoffset or constructors.privateoffset
+ local reported=encdone[tfmfile][encfile]
+ local backmap=vector and table.swapped(vector)
+ local done={}
+ for index,name in sortedhash(encoding) do
+ local unicode=unicoding[name]
+ local original=originals[index]
+ if original then
+ if unicode then
+ original.unicode=unicode
+ else
+ unicode=private
+ private=private+1
+ if not reported then
+ report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode)
+ end
+ end
+ characters[unicode]=original
+ indices[index]=unicode
+ original.name=name
+ if backmap then
+ original.index=backmap[name]
+ else
+ original.commands={ parentfont,charcommand[index] }
+ original.oindex=index
+ end
+ done[name]=true
+ elseif not done[name] then
+ report_tfm("bad index %a in font %a with name %a",index,tfmfile,name)
+ end
+ end
+ encdone[tfmfile][encfile]=true
+ for k,v in next,characters do
+ local kerns=v.kerns
+ if kerns then
+ local t={}
+ for k,v in next,kerns do
+ local i=indices[k]
+ if i then
+ t[i]=v
+ end
+ end
+ v.kerns=next(t) and t or nil
+ end
+ local ligatures=v.ligatures
+ if ligatures then
+ local t={}
+ for k,v in next,ligatures do
+ local i=indices[k]
+ if i then
+ t[i]=v
+ v.char=indices[v.char]
+ end
+ end
+ v.ligatures=next(t) and t or nil
+ end
+ end
+ tfmdata.fonts={ { id=virtualid } }
+ tfmdata.characters=characters
+ tfmdata.fullname=tfmdata.fullname or tfmdata.name
+ tfmdata.psname=file.nameonly(pfbfile or tfmdata.name)
+ tfmdata.filename=pfbfile
+ tfmdata.encodingbytes=2
+ tfmdata.format="type1"
+ tfmdata.tounicode=1
+ tfmdata.embedding="subset"
+ tfmdata.usedbitmap=bitmap and virtualid
+ tfmdata.private=private
+ return tfmdata
+ end
+end
+do
+ local template=[[
+/CIDInit /ProcSet findresource begin
+ 12 dict begin
+ begincmap
+ /CIDSystemInfo << /Registry (TeX) /Ordering (bitmap-%s) /Supplement 0 >> def
+ /CMapName /TeX-bitmap-%s def
+ /CMapType 2 def
+ 1 begincodespacerange
+ <00> <FF>
+ endcodespacerange
+ %s beginbfchar
+%s
+ endbfchar
+ endcmap
+CMapName currentdict /CMap defineresource pop end
+end
+end
+]]
+ local flushstreamobject=lpdf and lpdf.flushstreamobject
+ local setfontattributes=lpdf and lpdf.setfontattributes
+ if not flushstreamobject then
+ flushstreamobject=function(data)
+ return pdf.obj { immediate=true,type="stream",string=data }
+ end
+ end
+ if not setfontattributes then
+ setfontattributes=function(id,data)
+ return pdf.setfontattributes(id,data)
+ end
+ end
+ function tfm.addtounicode(tfmdata)
+ local id=tfmdata.usedbitmap
+ local map={}
+ local char={}
+ for k,v in next,tfmdata.characters do
+ local index=v.oindex
+ local tounicode=v.tounicode
+ if index and tounicode then
+ map[index]=tounicode
+ end
+ end
+ for k,v in sortedhash(map) do
+ char[#char+1]=format("<%02X> <%s>",k,v)
+ end
+ char=concat(char,"\n")
+ local stream=format(template,id,id,#char,char)
+ local reference=flushstreamobject(stream,nil,true)
+ setfontattributes(id,format("/ToUnicode %i 0 R",reference))
+ end
+end
+do
+ local everywhere={ ["*"]={ ["*"]=true } }
+ local noflags={ false,false,false,false }
+ local function enhance_normalize_features(data)
+ local ligatures=setmetatableindex("table")
+ local kerns=setmetatableindex("table")
+ local characters=data.characters
+ for u,c in next,characters do
+ local l=c.ligatures
+ local k=c.kerns
+ if l then
+ ligatures[u]=l
+ for u,v in next,l do
+ l[u]={ ligature=v.char }
+ end
+ c.ligatures=nil
+ end
+ if k then
+ kerns[u]=k
+ for u,v in next,k do
+ k[u]=v
+ end
+ c.kerns=nil
+ end
+ end
+ for u,l in next,ligatures do
+ for k,v in next,l do
+ local vl=v.ligature
+ local dl=ligatures[vl]
+ if dl then
+ for kk,vv in next,dl do
+ v[kk]=vv
+ end
+ end
+ end
+ end
+ local features={
+ gpos={},
+ gsub={},
+ }
+ local sequences={
+ }
+ if next(ligatures) then
+ features.gsub.liga=everywhere
+ data.properties.hasligatures=true
+ sequences[#sequences+1]={
+ features={
+ liga=everywhere,
+ },
+ flags=noflags,
+ name="s_s_0",
+ nofsteps=1,
+ order={ "liga" },
+ type="gsub_ligature",
+ steps={
+ {
+ coverage=ligatures,
+ },
+ },
+ }
+ end
+ if next(kerns) then
+ features.gpos.kern=everywhere
+ data.properties.haskerns=true
+ sequences[#sequences+1]={
+ features={
+ kern=everywhere,
+ },
+ flags=noflags,
+ name="p_s_0",
+ nofsteps=1,
+ order={ "kern" },
+ type="gpos_pair",
+ steps={
+ {
+ format="kern",
+ coverage=kerns,
+ },
+ },
+ }
+ end
+ data.resources.features=features
+ data.resources.sequences=sequences
+ data.shared.resources=data.shared.resources or resources
+ end
+ registertfmenhancer("normalize features",enhance_normalize_features)
+ registertfmenhancer("check extra features",otfenhancers.enhance)
+end
+registertfmfeature {
+ name="mode",
+ description="mode",
+ initializers={
+ base=otf.modeinitializer,
+ node=otf.modeinitializer,
+ }
+}
+registertfmfeature {
+ name="features",
+ description="features",
+ default=true,
+ initializers={
+ base=otf.basemodeinitializer,
+ node=otf.nodemodeinitializer,
+ },
+ processors={
+ node=otf.featuresprocessor,
+ }
+}
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-lua']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local report_lua=logs.reporter("fonts","lua loading")
+local fonts=fonts
+local readers=fonts.readers
+fonts.formats.lua="lua"
+local function check_lua(specification,fullname)
+ local fullname=resolvers.findfile(fullname) or ""
+ if fullname~="" then
+ local loader=loadfile(fullname)
+ loader=loader and loader()
+ return loader and loader(specification)
+ end
+end
+readers.check_lua=check_lua
+function readers.lua(specification)
+ local original=specification.specification
+ if trace_defining then
+ report_lua("using lua reader for %a",original)
+ end
+ local fullname=specification.filename or ""
+ if fullname=="" then
+ local forced=specification.forced or ""
+ if forced~="" then
+ fullname=specification.name.."."..forced
+ else
+ fullname=specification.name
+ end
+ end
+ return check_lua(specification,fullname)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-def']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local lower,gsub=string.lower,string.gsub
+local tostring,next=tostring,next
+local lpegmatch=lpeg.match
+local suffixonly,removesuffix,basename=file.suffix,file.removesuffix,file.basename
+local formatters=string.formatters
+local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
+local allocate=utilities.storage.allocate
+local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end)
+local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end)
+trackers.register("fonts.loading","fonts.defining","otf.loading","afm.loading","tfm.loading")
+local report_defining=logs.reporter("fonts","defining")
+local fonts=fonts
+local fontdata=fonts.hashes.identifiers
+local readers=fonts.readers
+local definers=fonts.definers
+local specifiers=fonts.specifiers
+local constructors=fonts.constructors
+local fontgoodies=fonts.goodies
+readers.sequence=allocate { 'otf','ttf','afm','tfm','lua' }
+local variants=allocate()
+specifiers.variants=variants
+definers.methods=definers.methods or {}
+local internalized=allocate()
+local lastdefined=nil
+local loadedfonts=constructors.loadedfonts
+local designsizes=constructors.designsizes
+local resolvefile=fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end
+local function makespecification(specification,lookup,name,sub,method,detail,size)
+ size=size or 655360
+ if not lookup or lookup=="" then
+ lookup=definers.defaultlookup
+ end
+ if trace_defining then
+ report_defining("specification %a, lookup %a, name %a, sub %a, method %a, detail %a",
+ specification,lookup,name,sub,method,detail)
+ end
+ local t={
+ lookup=lookup,
+ specification=specification,
+ size=size,
+ name=name,
+ sub=sub,
+ method=method,
+ detail=detail,
+ resolved="",
+ forced="",
+ features={},
+ }
+ return t
+end
+definers.makespecification=makespecification
+if context then
+
+--removed
+
+end
+definers.resolvers=definers.resolvers or {}
+local resolvers=definers.resolvers
+function resolvers.file(specification)
+ local name=resolvefile(specification.name)
+ local suffix=lower(suffixonly(name))
+ if fonts.formats[suffix] then
+ specification.forced=suffix
+ specification.forcedname=name
+ specification.name=removesuffix(name)
+ else
+ specification.name=name
+ end
+end
+function resolvers.name(specification)
+ local resolve=fonts.names.resolve
+ if resolve then
+ local resolved,sub,subindex,instance=resolve(specification.name,specification.sub,specification)
+ if resolved then
+ specification.resolved=resolved
+ specification.sub=sub
+ specification.subindex=subindex
+ if instance then
+ specification.instance=instance
+ local features=specification.features
+ if not features then
+ features={}
+ specification.features=features
+ end
+ local normal=features.normal
+ if not normal then
+ normal={}
+ features.normal=normal
+ end
+ normal.instance=instance
+ end
+ local suffix=lower(suffixonly(resolved))
+ if fonts.formats[suffix] then
+ specification.forced=suffix
+ specification.forcedname=resolved
+ specification.name=removesuffix(resolved)
+ else
+ specification.name=resolved
+ end
+ end
+ else
+ resolvers.file(specification)
+ end
+end
+function resolvers.spec(specification)
+ local resolvespec=fonts.names.resolvespec
+ if resolvespec then
+ local resolved,sub,subindex=resolvespec(specification.name,specification.sub,specification)
+ if resolved then
+ specification.resolved=resolved
+ specification.sub=sub
+ specification.subindex=subindex
+ specification.forced=lower(suffixonly(resolved))
+ specification.forcedname=resolved
+ specification.name=removesuffix(resolved)
+ end
+ else
+ resolvers.name(specification)
+ end
+end
+function definers.resolve(specification)
+ if not specification.resolved or specification.resolved=="" then
+ local r=resolvers[specification.lookup]
+ if r then
+ r(specification)
+ end
+ end
+ if specification.forced=="" then
+ specification.forced=nil
+ specification.forcedname=nil
+ end
+ specification.hash=lower(specification.name..' @ '..constructors.hashfeatures(specification))
+ if specification.sub and specification.sub~="" then
+ specification.hash=specification.sub..' @ '..specification.hash
+ end
+ return specification
+end
+function definers.applypostprocessors(tfmdata)
+ local postprocessors=tfmdata.postprocessors
+ if postprocessors then
+ local properties=tfmdata.properties
+ for i=1,#postprocessors do
+ local extrahash=postprocessors[i](tfmdata)
+ if type(extrahash)=="string" and extrahash~="" then
+ extrahash=gsub(lower(extrahash),"[^a-z]","-")
+ properties.fullname=formatters["%s-%s"](properties.fullname,extrahash)
+ end
+ end
+ end
+ return tfmdata
+end
+local function checkembedding(tfmdata)
+ local properties=tfmdata.properties
+ local embedding
+ if directive_embedall then
+ embedding="full"
+ elseif properties and properties.filename and constructors.dontembed[properties.filename] then
+ embedding="no"
+ else
+ embedding="subset"
+ end
+ if properties then
+ properties.embedding=embedding
+ else
+ tfmdata.properties={ embedding=embedding }
+ end
+ tfmdata.embedding=embedding
+end
+local function checkfeatures(tfmdata)
+ local resources=tfmdata.resources
+ local shared=tfmdata.shared
+ if resources and shared then
+ local features=resources.features
+ local usedfeatures=shared.features
+ if features and usedfeatures then
+ local usedlanguage=usedfeatures.language or "dflt"
+ local usedscript=usedfeatures.script or "dflt"
+ local function check(what)
+ if what then
+ local foundlanguages={}
+ for feature,scripts in next,what do
+ if usedscript=="auto" or scripts["*"] then
+ elseif not scripts[usedscript] then
+ else
+ for script,languages in next,scripts do
+ if languages["*"] then
+ elseif context and not languages[usedlanguage] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,usedlanguage)
+ end
+ end
+ end
+ for script,languages in next,scripts do
+ for language in next,languages do
+ foundlanguages[language]=true
+ end
+ end
+ end
+ if false then
+ foundlanguages["*"]=nil
+ foundlanguages=sortedkeys(foundlanguages)
+ for feature,scripts in sortedhash(what) do
+ for script,languages in next,scripts do
+ if not languages["*"] then
+ for i=1,#foundlanguages do
+ local language=foundlanguages[i]
+ if context and not languages[language] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,language)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ check(features.gsub)
+ check(features.gpos)
+ end
+ end
+end
+function definers.loadfont(specification)
+ local hash=constructors.hashinstance(specification)
+ local tfmdata=loadedfonts[hash]
+ if not tfmdata then
+ local forced=specification.forced or ""
+ if forced~="" then
+ local reader=readers[lower(forced)]
+ tfmdata=reader and reader(specification)
+ if not tfmdata then
+ report_defining("forced type %a of %a not found",forced,specification.name)
+ end
+ else
+ local sequence=readers.sequence
+ for s=1,#sequence do
+ local reader=sequence[s]
+ if readers[reader] then
+ if trace_defining then
+ report_defining("trying (reader sequence driven) type %a for %a with file %a",reader,specification.name,specification.filename)
+ end
+ tfmdata=readers[reader](specification)
+ if tfmdata then
+ break
+ else
+ specification.filename=nil
+ end
+ end
+ end
+ end
+ if tfmdata then
+ tfmdata=definers.applypostprocessors(tfmdata)
+ checkembedding(tfmdata)
+ loadedfonts[hash]=tfmdata
+ designsizes[specification.hash]=tfmdata.parameters.designsize
+ checkfeatures(tfmdata)
+ end
+ end
+ if not tfmdata then
+ report_defining("font with asked name %a is not found using lookup %a",specification.name,specification.lookup)
+ end
+ return tfmdata
+end
+function constructors.readanddefine(name,size)
+ local specification=definers.analyze(name,size)
+ local method=specification.method
+ if method and variants[method] then
+ specification=variants[method](specification)
+ end
+ specification=definers.resolve(specification)
+ local hash=constructors.hashinstance(specification)
+ local id=definers.registered(hash)
+ if not id then
+ local tfmdata=definers.loadfont(specification)
+ if tfmdata then
+ tfmdata.properties.hash=hash
+ id=font.define(tfmdata)
+ definers.register(tfmdata,id)
+ else
+ id=0
+ end
+ end
+ return fontdata[id],id
+end
+function definers.current()
+ return lastdefined
+end
+function definers.registered(hash)
+ local id=internalized[hash]
+ return id,id and fontdata[id]
+end
+function definers.register(tfmdata,id)
+ if tfmdata and id then
+ local hash=tfmdata.properties.hash
+ if not hash then
+ report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?")
+ elseif not internalized[hash] then
+ internalized[hash]=id
+ if trace_defining then
+ report_defining("registering font, id %s, hash %a",id,hash)
+ end
+ fontdata[id]=tfmdata
+ end
+ end
+end
+function definers.read(specification,size,id)
+ statistics.starttiming(fonts)
+ if type(specification)=="string" then
+ specification=definers.analyze(specification,size)
+ end
+ local method=specification.method
+ if method and variants[method] then
+ specification=variants[method](specification)
+ end
+ specification=definers.resolve(specification)
+ local hash=constructors.hashinstance(specification)
+ local tfmdata=definers.registered(hash)
+ if tfmdata then
+ if trace_defining then
+ report_defining("already hashed: %s",hash)
+ end
+ else
+ tfmdata=definers.loadfont(specification)
+ if tfmdata then
+ if trace_defining then
+ report_defining("loaded and hashed: %s",hash)
+ end
+ tfmdata.properties.hash=hash
+ if id then
+ definers.register(tfmdata,id)
+ end
+ else
+ if trace_defining then
+ report_defining("not loaded and hashed: %s",hash)
+ end
+ end
+ end
+ lastdefined=tfmdata or id
+ if not tfmdata then
+ report_defining("unknown font %a, loading aborted",specification.name)
+ elseif trace_defining and type(tfmdata)=="table" then
+ local properties=tfmdata.properties or {}
+ local parameters=tfmdata.parameters or {}
+ report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a",
+ properties.format or "unknown",id or "-",properties.name,parameters.size,properties.encodingbytes,
+ properties.encodingname,properties.fullname,basename(properties.filename))
+ end
+ statistics.stoptiming(fonts)
+ return tfmdata
+end
+function font.getfont(id)
+ return fontdata[id]
+end
+callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)")
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['luatex-fonts-def']={
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+--removed
+
+end
+local fonts=fonts
+fonts.constructors.namemode="specification"
+function fonts.definers.getspecification(str)
+ return "",str,"",":",str
+end
+local list={}
+local function issome () list.lookup='name' end
+local function isfile () list.lookup='file' end
+local function isname () list.lookup='name' end
+local function thename(s) list.name=s end
+local function issub (v) list.sub=v end
+local function iscrap (s) list.crap=string.lower(s) end
+local function iskey (k,v) list[k]=v end
+local function istrue (s) list[s]=true end
+local function isfalse(s) list[s]=false end
+local P,S,R,C,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs
+local spaces=P(" ")^0
+local namespec=Cs((P("{")/"")*(1-S("}"))^0*(P("}")/"")+(1-S("/:("))^0)
+local crapspec=spaces*P("/")*(((1-P(":"))^0)/iscrap)*spaces
+local filename_1=P("file:")/isfile*(namespec/thename)
+local filename_2=P("[")*P(true)/isfile*(((1-P("]"))^0)/thename)*P("]")
+local fontname_1=P("name:")/isname*(namespec/thename)
+local fontname_2=P(true)/issome*(namespec/thename)
+local sometext=R("az","AZ","09")^1
+local somekey=R("az","AZ","09")^1
+local somevalue=(P("{")/"")*(1-P("}"))^0*(P("}")/"")+(1-S(";"))^1
+local truevalue=P("+")*spaces*(sometext/istrue)
+local falsevalue=P("-")*spaces*(sometext/isfalse)
+local keyvalue=(C(somekey)*spaces*P("=")*spaces*C(somevalue))/iskey
+local somevalue=sometext/istrue
+local subvalue=P("(")*(C(P(1-S("()"))^1)/issub)*P(")")
+local option=spaces*(keyvalue+falsevalue+truevalue+somevalue)*spaces
+local options=P(":")*spaces*(P(";")^0*option)^0
+local pattern=(filename_1+filename_2+fontname_1+fontname_2)*subvalue^0*crapspec^0*options^0
+function fonts.definers.analyze(str,size)
+ local specification=fonts.definers.makespecification(str,nil,nil,nil,":",nil,size)
+ list={}
+ lpeg.match(pattern,str)
+ list.crap=nil
+ if list.name then
+ specification.name=list.name
+ list.name=nil
+ end
+ if list.lookup then
+ specification.lookup=list.lookup
+ list.lookup=nil
+ end
+ if list.sub then
+ specification.sub=list.sub
+ list.sub=nil
+ end
+ specification.features.normal=fonts.handlers.otf.features.normalize(list)
+ list=nil
+ return specification
+end
+function fonts.definers.applypostprocessors(tfmdata)
+ local postprocessors=tfmdata.postprocessors
+ if postprocessors then
+ for i=1,#postprocessors do
+ local extrahash=postprocessors[i](tfmdata)
+ if type(extrahash)=="string" and extrahash~="" then
+ extrahash=string.gsub(lower(extrahash),"[^a-z]","-")
+ tfmdata.properties.fullname=format("%s-%s",tfmdata.properties.fullname,extrahash)
+ end
+ end
+ end
+ return tfmdata
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['luatex-fonts-ext']={
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+--removed
+
+end
+local byte=string.byte
+local fonts=fonts
+local handlers=fonts.handlers
+local otf=handlers.otf
+local afm=handlers.afm
+local registerotffeature=otf.features.register
+local registerafmfeature=afm.features.register
+function fonts.loggers.onetimemessage() end
+fonts.protrusions=fonts.protrusions or {}
+fonts.protrusions.setups=fonts.protrusions.setups or {}
+local setups=fonts.protrusions.setups
+setups['default']={
+ factor=1,
+ left=1,
+ right=1,
+ [0x002C]={ 0,1 },
+ [0x002E]={ 0,1 },
+ [0x003A]={ 0,1 },
+ [0x003B]={ 0,1 },
+ [0x002D]={ 0,1 },
+ [0x2013]={ 0,0.50 },
+ [0x2014]={ 0,0.33 },
+ [0x3001]={ 0,1 },
+ [0x3002]={ 0,1 },
+ [0x060C]={ 0,1 },
+ [0x061B]={ 0,1 },
+ [0x06D4]={ 0,1 },
+}
+local function initializeprotrusion(tfmdata,value)
+ if value then
+ local setup=setups[value]
+ if setup then
+ local factor,left,right=setup.factor or 1,setup.left or 1,setup.right or 1
+ local emwidth=tfmdata.parameters.quad
+ tfmdata.parameters.protrusion={
+ auto=true,
+ }
+ for i,chr in next,tfmdata.characters do
+ local v,pl,pr=setup[i],nil,nil
+ if v then
+ pl,pr=v[1],v[2]
+ end
+ if pl and pl~=0 then chr.left_protruding=left*pl*factor end
+ if pr and pr~=0 then chr.right_protruding=right*pr*factor end
+ end
+ end
+ end
+end
+local specification={
+ name="protrusion",
+ description="shift characters into the left and or right margin",
+ initializers={
+ base=initializeprotrusion,
+ node=initializeprotrusion,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+fonts.expansions=fonts.expansions or {}
+fonts.expansions.setups=fonts.expansions.setups or {}
+local setups=fonts.expansions.setups
+setups['default']={
+ stretch=2,
+ shrink=2,
+ step=.5,
+ factor=1,
+ [byte('A')]=0.5,[byte('B')]=0.7,[byte('C')]=0.7,[byte('D')]=0.5,[byte('E')]=0.7,
+ [byte('F')]=0.7,[byte('G')]=0.5,[byte('H')]=0.7,[byte('K')]=0.7,[byte('M')]=0.7,
+ [byte('N')]=0.7,[byte('O')]=0.5,[byte('P')]=0.7,[byte('Q')]=0.5,[byte('R')]=0.7,
+ [byte('S')]=0.7,[byte('U')]=0.7,[byte('W')]=0.7,[byte('Z')]=0.7,
+ [byte('a')]=0.7,[byte('b')]=0.7,[byte('c')]=0.7,[byte('d')]=0.7,[byte('e')]=0.7,
+ [byte('g')]=0.7,[byte('h')]=0.7,[byte('k')]=0.7,[byte('m')]=0.7,[byte('n')]=0.7,
+ [byte('o')]=0.7,[byte('p')]=0.7,[byte('q')]=0.7,[byte('s')]=0.7,[byte('u')]=0.7,
+ [byte('w')]=0.7,[byte('z')]=0.7,
+ [byte('2')]=0.7,[byte('3')]=0.7,[byte('6')]=0.7,[byte('8')]=0.7,[byte('9')]=0.7,
+}
+local function initializeexpansion(tfmdata,value)
+ if value then
+ local setup=setups[value]
+ if setup then
+ local factor=setup.factor or 1
+ tfmdata.parameters.expansion={
+ stretch=10*(setup.stretch or 0),
+ shrink=10*(setup.shrink or 0),
+ step=10*(setup.step or 0),
+ auto=true,
+ }
+ for i,chr in next,tfmdata.characters do
+ local v=setup[i]
+ if v and v~=0 then
+ chr.expansion_factor=v*factor
+ else
+ chr.expansion_factor=factor
+ end
+ end
+ end
+ end
+end
+local specification={
+ name="expansion",
+ description="apply hz optimization",
+ initializers={
+ base=initializeexpansion,
+ node=initializeexpansion,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+if not otf.features.normalize then
+ otf.features.normalize=function(t)
+ if t.rand then
+ t.rand="random"
+ end
+ return t
+ end
+end
+function fonts.helpers.nametoslot(name)
+ local t=type(name)
+ if t=="string" then
+ local tfmdata=fonts.hashes.identifiers[currentfont()]
+ local shared=tfmdata and tfmdata.shared
+ local fntdata=shared and shared.rawdata
+ return fntdata and fntdata.resources.unicodes[name]
+ elseif t=="number" then
+ return n
+ end
+end
+fonts.encodings=fonts.encodings or {}
+local reencodings={}
+fonts.encodings.reencodings=reencodings
+local function specialreencode(tfmdata,value)
+ local encoding=value and reencodings[value]
+ if encoding then
+ local temp={}
+ local char=tfmdata.characters
+ for k,v in next,encoding do
+ temp[k]=char[v]
+ end
+ for k,v in next,temp do
+ char[k]=temp[k]
+ end
+ return string.format("reencoded:%s",value)
+ end
+end
+local function initialize(tfmdata,value)
+ tfmdata.postprocessors=tfmdata.postprocessors or {}
+ table.insert(tfmdata.postprocessors,
+ function(tfmdata)
+ return specialreencode(tfmdata,value)
+ end
+ )
+end
+registerotffeature {
+ name="reencode",
+ description="reencode characters",
+ manipulators={
+ base=initialize,
+ node=initialize,
+ }
+}
+local function initialize(tfmdata,key,value)
+ if value then
+ tfmdata.mathparameters=nil
+ end
+end
+registerotffeature {
+ name="ignoremathconstants",
+ description="ignore math constants table",
+ initializers={
+ base=initialize,
+ node=initialize,
+ }
+}
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-imp-tex']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next=next
+local fonts=fonts
+local otf=fonts.handlers.otf
+local registerotffeature=otf.features.register
+local addotffeature=otf.addfeature
+local specification={
+ type="ligature",
+ order={ "tlig" },
+ prepend=true,
+ data={
+ [0x2013]={ 0x002D,0x002D },
+ [0x2014]={ 0x002D,0x002D,0x002D },
+ },
+}
+addotffeature("tlig",specification)
+registerotffeature {
+ name="tlig",
+ description="tex ligatures",
+}
+local specification={
+ type="substitution",
+ order={ "trep" },
+ prepend=true,
+ data={
+ [0x0027]=0x2019,
+ },
+}
+addotffeature("trep",specification)
+registerotffeature {
+ name="trep",
+ description="tex replacements",
+}
+local anum_arabic={
+ [0x0030]=0x0660,
+ [0x0031]=0x0661,
+ [0x0032]=0x0662,
+ [0x0033]=0x0663,
+ [0x0034]=0x0664,
+ [0x0035]=0x0665,
+ [0x0036]=0x0666,
+ [0x0037]=0x0667,
+ [0x0038]=0x0668,
+ [0x0039]=0x0669,
+}
+local anum_persian={
+ [0x0030]=0x06F0,
+ [0x0031]=0x06F1,
+ [0x0032]=0x06F2,
+ [0x0033]=0x06F3,
+ [0x0034]=0x06F4,
+ [0x0035]=0x06F5,
+ [0x0036]=0x06F6,
+ [0x0037]=0x06F7,
+ [0x0038]=0x06F8,
+ [0x0039]=0x06F9,
+}
+local function valid(data)
+ local features=data.resources.features
+ if features then
+ for k,v in next,features do
+ for k,v in next,v do
+ if v.arab then
+ return true
+ end
+ end
+ end
+ end
+end
+local specification={
+ {
+ type="substitution",
+ features={ arab={ urd=true,dflt=true } },
+ order={ "anum" },
+ data=anum_arabic,
+ valid=valid,
+ },
+ {
+ type="substitution",
+ features={ arab={ urd=true } },
+ order={ "anum" },
+ data=anum_persian,
+ valid=valid,
+ },
+}
+addotffeature("anum",specification)
+registerotffeature {
+ name="anum",
+ description="arabic digits",
+}
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-imp-ligatures']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local lpegmatch=lpeg.match
+local utfsplit=utf.split
+local settings_to_array=utilities.parsers.settings_to_array
+local fonts=fonts
+local otf=fonts.handlers.otf
+local registerotffeature=otf.features.register
+local addotffeature=otf.addfeature
+local lookups={}
+local protect={}
+local revert={}
+local zwjchar=0x200C
+local zwj={ zwjchar }
+addotffeature {
+ name="blockligatures",
+ type="chainsubstitution",
+ nocheck=true,
+ prepend=true,
+ future=true,
+ lookups={
+ {
+ type="multiple",
+ data=lookups,
+ },
+ },
+ data={
+ rules=protect,
+ }
+}
+addotffeature {
+ name="blockligatures",
+ type="chainsubstitution",
+ nocheck=true,
+ append=true,
+ overload=false,
+ lookups={
+ {
+ type="ligature",
+ data=lookups,
+ },
+ },
+ data={
+ rules=revert,
+ }
+}
+registerotffeature {
+ name='blockligatures',
+ description='block certain ligatures',
+}
+local splitter=lpeg.splitat(":")
+local function blockligatures(str)
+ local t=settings_to_array(str)
+ for i=1,#t do
+ local ti=t[i]
+ local before,current,after=lpegmatch(splitter,ti)
+ if current and after then
+ if before then
+ before=utfsplit(before)
+ for i=1,#before do
+ before[i]={ before[i] }
+ end
+ end
+ if current then
+ current=utfsplit(current)
+ end
+ if after then
+ after=utfsplit(after)
+ for i=1,#after do
+ after[i]={ after[i] }
+ end
+ end
+ else
+ before=nil
+ current=utfsplit(ti)
+ after=nil
+ end
+ if #current>1 then
+ local one=current[1]
+ local two=current[2]
+ lookups[one]={ one,zwjchar }
+ local one={ one }
+ local two={ two }
+ local new=#protect+1
+ protect[new]={
+ before=before,
+ current={ one,two },
+ after=after,
+ lookups={ 1 },
+ }
+ revert[new]={
+ current={ one,zwj },
+ after={ two },
+ lookups={ 1 },
+ }
+ end
+ end
+end
+otf.helpers.blockligatures=blockligatures
+if context then
+
+--removed
+
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-imp-italics']={
+ version=1.001,
+ comment="companion to font-ini.mkiv and hand-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next=next
+local fonts=fonts
+local handlers=fonts.handlers
+local registerotffeature=handlers.otf.features.register
+local registerafmfeature=handlers.afm.features.register
+local function initialize(tfmdata,key,value)
+ for unicode,character in next,tfmdata.characters do
+ local olditalic=character.italic
+ if olditalic and olditalic~=0 then
+ character.width=character.width+olditalic
+ character.italic=0
+ end
+ end
+end
+local specification={
+ name="italicwidths",
+ description="add italic to width",
+ manipulators={
+ base=initialize,
+ node=initialize,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+local function initialize(tfmdata,value)
+ if value then
+ local parameters=tfmdata.parameters
+ local italicangle=parameters.italicangle
+ if italicangle and italicangle~=0 then
+ local properties=tfmdata.properties
+ local factor=tonumber(value) or 1
+ properties.hasitalics=true
+ properties.autoitalicamount=factor*(parameters.uwidth or 40)/2
+ end
+ end
+end
+local specification={
+ name="itlc",
+ description="italic correction",
+ initializers={
+ base=initialize,
+ node=initialize,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+if context then
+
+--removed
+
+end
+if context then
+ local letter=characters.is_letter
+ local always=true
+ local function collapseitalics(tfmdata,key,value)
+ local threshold=value==true and 100 or tonumber(value)
+ if threshold and threshold>0 then
+ if threshold>100 then
+ threshold=100
+ end
+ for unicode,data in next,tfmdata.characters do
+ if always or letter[unicode] or letter[data.unicode] then
+ local italic=data.italic
+ if italic and italic~=0 then
+ local width=data.width
+ if width and width~=0 then
+ local delta=threshold*italic/100
+ data.width=width+delta
+ data.italic=italic-delta
+ end
+ end
+ end
+ end
+ end
+ end
+ local dimensions_specification={
+ name="collapseitalics",
+ description="collapse italics",
+ manipulators={
+ base=collapseitalics,
+ node=collapseitalics,
+ }
+ }
+ registerotffeature(dimensions_specification)
+ registerafmfeature(dimensions_specification)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['font-imp-effects']={
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+local next,type,tonumber=next,type,tonumber
+local is_boolean=string.is_boolean
+local fonts=fonts
+local handlers=fonts.handlers
+local registerotffeature=handlers.otf.features.register
+local registerafmfeature=handlers.afm.features.register
+local settings_to_hash=utilities.parsers.settings_to_hash_colon_too
+local helpers=fonts.helpers
+local prependcommands=helpers.prependcommands
+local charcommand=helpers.commands.char
+local leftcommand=helpers.commands.left
+local rightcommand=helpers.commands.right
+local upcommand=helpers.commands.up
+local downcommand=helpers.commands.down
+local dummycommand=helpers.commands.dummy
+local report_effect=logs.reporter("fonts","effect")
+local report_slant=logs.reporter("fonts","slant")
+local report_extend=logs.reporter("fonts","extend")
+local report_squeeze=logs.reporter("fonts","squeeze")
+local trace=false
+trackers.register("fonts.effect",function(v) trace=v end)
+trackers.register("fonts.slant",function(v) trace=v end)
+trackers.register("fonts.extend",function(v) trace=v end)
+trackers.register("fonts.squeeze",function(v) trace=v end)
+local function initializeslant(tfmdata,value)
+ value=tonumber(value)
+ if not value then
+ value=0
+ elseif value>1 then
+ value=1
+ elseif value<-1 then
+ value=-1
+ end
+ if trace then
+ report_slant("applying %0.3f",value)
+ end
+ tfmdata.parameters.slantfactor=value
+end
+local specification={
+ name="slant",
+ description="slant glyphs",
+ initializers={
+ base=initializeslant,
+ node=initializeslant,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+local function initializeextend(tfmdata,value)
+ value=tonumber(value)
+ if not value then
+ value=0
+ elseif value>10 then
+ value=10
+ elseif value<-10 then
+ value=-10
+ end
+ if trace then
+ report_extend("applying %0.3f",value)
+ end
+ tfmdata.parameters.extendfactor=value
+end
+local specification={
+ name="extend",
+ description="scale glyphs horizontally",
+ initializers={
+ base=initializeextend,
+ node=initializeextend,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+local function initializesqueeze(tfmdata,value)
+ value=tonumber(value)
+ if not value then
+ value=0
+ elseif value>10 then
+ value=10
+ elseif value<-10 then
+ value=-10
+ end
+ if trace then
+ report_squeeze("applying %0.3f",value)
+ end
+ tfmdata.parameters.squeezefactor=value
+end
+local specification={
+ name="squeeze",
+ description="scale glyphs vertically",
+ initializers={
+ base=initializesqueeze,
+ node=initializesqueeze,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+local effects={
+ inner=0,
+ normal=0,
+ outer=1,
+ outline=1,
+ both=2,
+ hidden=3,
+}
+local function initializeeffect(tfmdata,value)
+ local spec
+ if type(value)=="number" then
+ spec={ width=value }
+ else
+ spec=settings_to_hash(value)
+ end
+ local effect=spec.effect or "both"
+ local width=tonumber(spec.width) or 0
+ local mode=effects[effect]
+ if not mode then
+ report_effect("invalid effect %a",effect)
+ elseif width==0 and mode==0 then
+ report_effect("invalid width %a for effect %a",width,effect)
+ else
+ local parameters=tfmdata.parameters
+ local properties=tfmdata.properties
+ parameters.mode=mode
+ parameters.width=width*1000
+ if is_boolean(spec.auto)==true then
+ local squeeze=1-width/20
+ local average=(1-squeeze)*width*100
+ spec.squeeze=squeeze
+ spec.extend=1+width/2
+ spec.wdelta=average
+ spec.hdelta=average/2
+ spec.ddelta=average/2
+ spec.vshift=average/2
+ end
+ local factor=tonumber(spec.factor) or 0
+ local hfactor=tonumber(spec.hfactor) or factor
+ local vfactor=tonumber(spec.vfactor) or factor
+ local delta=tonumber(spec.delta) or 1
+ local wdelta=tonumber(spec.wdelta) or delta
+ local hdelta=tonumber(spec.hdelta) or delta
+ local ddelta=tonumber(spec.ddelta) or hdelta
+ local vshift=tonumber(spec.vshift) or 0
+ local slant=spec.slant
+ local extend=spec.extend
+ local squeeze=spec.squeeze
+ if slant then
+ initializeslant(tfmdata,slant)
+ end
+ if extend then
+ initializeextend(tfmdata,extend)
+ end
+ if squeeze then
+ initializesqueeze(tfmdata,squeeze)
+ end
+ properties.effect={
+ effect=effect,
+ width=width,
+ factor=factor,
+ hfactor=hfactor,
+ vfactor=vfactor,
+ wdelta=wdelta,
+ hdelta=hdelta,
+ ddelta=ddelta,
+ vshift=vshift,
+ slant=tfmdata.parameters.slantfactor,
+ extend=tfmdata.parameters.extendfactor,
+ squeeze=tfmdata.parameters.squeezefactor,
+ }
+ end
+end
+local rules={
+ "RadicalRuleThickness",
+ "OverbarRuleThickness",
+ "FractionRuleThickness",
+ "UnderbarRuleThickness",
+}
+local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
+ if delta~=0 then
+ for i=1,#rules do
+ local name=rules[i]
+ local value=mathparameters[name]
+ if value then
+ mathparameters[name]=(squeeze or 1)*(value+dx)
+ end
+ end
+ end
+end
+local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
+ local function wdpatch(char)
+ if wsnap~=0 then
+ char.width=char.width+wdelta/2
+ end
+ end
+ local function htpatch(char)
+ if hsnap~=0 then
+ local height=char.height
+ if height then
+ char.height=char.height+2*dy
+ end
+ end
+ end
+ local character=characters[0x221A]
+ if character and character.next then
+ local char=character
+ local next=character.next
+ wdpatch(char)
+ htpatch(char)
+ while next do
+ char=characters[next]
+ wdpatch(char)
+ htpatch(char)
+ next=char.next
+ end
+ if char then
+ local v=char.vert_variants
+ if v then
+ local top=v[#v]
+ if top then
+ local char=characters[top.glyph]
+ htpatch(char)
+ end
+ end
+ end
+ end
+end
+local function manipulateeffect(tfmdata)
+ local effect=tfmdata.properties.effect
+ if effect then
+ local characters=tfmdata.characters
+ local parameters=tfmdata.parameters
+ local mathparameters=tfmdata.mathparameters
+ local multiplier=effect.width*100
+ local factor=parameters.factor
+ local hfactor=parameters.hfactor
+ local vfactor=parameters.vfactor
+ local wdelta=effect.wdelta*hfactor*multiplier
+ local hdelta=effect.hdelta*vfactor*multiplier
+ local ddelta=effect.ddelta*vfactor*multiplier
+ local vshift=effect.vshift*vfactor*multiplier
+ local squeeze=effect.squeeze
+ local hshift=wdelta/2
+ local dx=multiplier*vfactor
+ local dy=vshift
+ local factor=(1+effect.factor)*factor
+ local hfactor=(1+effect.hfactor)*hfactor
+ local vfactor=(1+effect.vfactor)*vfactor
+ local vshift=vshift~=0 and upcommand[vshift] or false
+ for unicode,character in next,characters do
+ local oldwidth=character.width
+ local oldheight=character.height
+ local olddepth=character.depth
+ if oldwidth and oldwidth>0 then
+ character.width=oldwidth+wdelta
+ local commands=character.commands
+ local hshift=rightcommand[hshift]
+ if vshift then
+ if commands then
+ prependcommands (commands,
+ hshift,
+ vshift
+ )
+ else
+ character.commands={
+ hshift,
+ vshift,
+ charcommand[unicode]
+ }
+ end
+ else
+ if commands then
+ prependcommands (commands,
+ hshift
+ )
+ else
+ character.commands={
+ hshift,
+ charcommand[unicode]
+ }
+ end
+ end
+ end
+ if oldheight and oldheight>0 then
+ character.height=oldheight+hdelta
+ end
+ if olddepth and olddepth>0 then
+ character.depth=olddepth+ddelta
+ end
+ end
+ if mathparameters then
+ setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
+ setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
+ end
+ parameters.factor=factor
+ parameters.hfactor=hfactor
+ parameters.vfactor=vfactor
+ if trace then
+ report_effect("applying")
+ report_effect(" effect : %s",effect.effect)
+ report_effect(" width : %s => %s",effect.width,multiplier)
+ report_effect(" factor : %s => %s",effect.factor,factor )
+ report_effect(" hfactor : %s => %s",effect.hfactor,hfactor)
+ report_effect(" vfactor : %s => %s",effect.vfactor,vfactor)
+ report_effect(" wdelta : %s => %s",effect.wdelta,wdelta)
+ report_effect(" hdelta : %s => %s",effect.hdelta,hdelta)
+ report_effect(" ddelta : %s => %s",effect.ddelta,ddelta)
+ end
+ end
+end
+local specification={
+ name="effect",
+ description="apply effects to glyphs",
+ initializers={
+ base=initializeeffect,
+ node=initializeeffect,
+ },
+ manipulators={
+ base=manipulateeffect,
+ node=manipulateeffect,
+ },
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+local function initializeoutline(tfmdata,value)
+ value=tonumber(value)
+ if not value then
+ value=0
+ else
+ value=tonumber(value) or 0
+ end
+ local parameters=tfmdata.parameters
+ local properties=tfmdata.properties
+ parameters.mode=effects.outline
+ parameters.width=value*1000
+ properties.effect={
+ effect=effect,
+ width=width,
+ }
+end
+local specification={
+ name="outline",
+ description="outline glyphs",
+ initializers={
+ base=initializeoutline,
+ node=initializeoutline,
+ }
+}
+registerotffeature(specification)
+registerafmfeature(specification)
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+
+fonts.handlers.otf.addfeature {
+ ["dataset"]={
+ {
+ ["data"]={
+ ["À"]={ "A","̀" },
+ ["Ã"]={ "A","Ì" },
+ ["Â"]={ "A","̂" },
+ ["Ã"]={ "A","̃" },
+ ["Ä"]={ "A","̈" },
+ ["Ã…"]={ "A","ÌŠ" },
+ ["Ç"]={ "C","̧" },
+ ["È"]={ "E","̀" },
+ ["É"]={ "E","Ì" },
+ ["Ê"]={ "E","̂" },
+ ["Ë"]={ "E","̈" },
+ ["Ì"]={ "I","̀" },
+ ["Ã"]={ "I","Ì" },
+ ["ÃŽ"]={ "I","Ì‚" },
+ ["Ã"]={ "I","̈" },
+ ["Ñ"]={ "N","̃" },
+ ["Ã’"]={ "O","Ì€" },
+ ["Ó"]={ "O","Ì" },
+ ["Ô"]={ "O","̂" },
+ ["Õ"]={ "O","̃" },
+ ["Ö"]={ "O","̈" },
+ ["Ù"]={ "U","̀" },
+ ["Ú"]={ "U","Ì" },
+ ["Û"]={ "U","̂" },
+ ["Ü"]={ "U","̈" },
+ ["Ã"]={ "Y","Ì" },
+ ["à"]={ "a","̀" },
+ ["á"]={ "a","Ì" },
+ ["â"]={ "a","̂" },
+ ["ã"]={ "a","̃" },
+ ["ä"]={ "a","̈" },
+ ["Ã¥"]={ "a","ÌŠ" },
+ ["ç"]={ "c","̧" },
+ ["è"]={ "e","̀" },
+ ["é"]={ "e","Ì" },
+ ["ê"]={ "e","̂" },
+ ["ë"]={ "e","̈" },
+ ["ì"]={ "i","̀" },
+ ["í"]={ "i","Ì" },
+ ["î"]={ "i","̂" },
+ ["ï"]={ "i","̈" },
+ ["ñ"]={ "n","̃" },
+ ["ò"]={ "o","̀" },
+ ["ó"]={ "o","Ì" },
+ ["ô"]={ "o","̂" },
+ ["õ"]={ "o","̃" },
+ ["ö"]={ "o","̈" },
+ ["ù"]={ "u","̀" },
+ ["ú"]={ "u","Ì" },
+ ["û"]={ "u","̂" },
+ ["ü"]={ "u","̈" },
+ ["ý"]={ "y","Ì" },
+ ["ÿ"]={ "y","̈" },
+ ["Ä€"]={ "A","Ì„" },
+ ["Ä"]={ "a","Ì„" },
+ ["Ă"]={ "A","̆" },
+ ["ă"]={ "a","̆" },
+ ["Ą"]={ "A","̨" },
+ ["ą"]={ "a","̨" },
+ ["Ć"]={ "C","Ì" },
+ ["ć"]={ "c","Ì" },
+ ["Ĉ"]={ "C","̂" },
+ ["ĉ"]={ "c","̂" },
+ ["Ċ"]={ "C","̇" },
+ ["ċ"]={ "c","̇" },
+ ["Č"]={ "C","̌" },
+ ["Ä"]={ "c","ÌŒ" },
+ ["Ď"]={ "D","̌" },
+ ["Ä"]={ "d","ÌŒ" },
+ ["Ä’"]={ "E","Ì„" },
+ ["Ä“"]={ "e","Ì„" },
+ ["Ĕ"]={ "E","̆" },
+ ["ĕ"]={ "e","̆" },
+ ["Ė"]={ "E","̇" },
+ ["ė"]={ "e","̇" },
+ ["Ę"]={ "E","̨" },
+ ["ę"]={ "e","̨" },
+ ["Ě"]={ "E","̌" },
+ ["ě"]={ "e","̌" },
+ ["Ĝ"]={ "G","̂" },
+ ["Ä"]={ "g","Ì‚" },
+ ["Ğ"]={ "G","̆" },
+ ["ğ"]={ "g","̆" },
+ ["Ġ"]={ "G","̇" },
+ ["ġ"]={ "g","̇" },
+ ["Ģ"]={ "G","̧" },
+ ["ģ"]={ "g","̧" },
+ ["Ĥ"]={ "H","̂" },
+ ["Ä¥"]={ "h","Ì‚" },
+ ["Ĩ"]={ "I","̃" },
+ ["ĩ"]={ "i","̃" },
+ ["Ī"]={ "I","̄" },
+ ["Ä«"]={ "i","Ì„" },
+ ["Ĭ"]={ "I","̆" },
+ ["ĭ"]={ "i","̆" },
+ ["Į"]={ "I","̨" },
+ ["į"]={ "i","̨" },
+ ["İ"]={ "I","̇" },
+ ["Ä´"]={ "J","Ì‚" },
+ ["ĵ"]={ "j","̂" },
+ ["Ķ"]={ "K","̧" },
+ ["ķ"]={ "k","̧" },
+ ["Ĺ"]={ "L","Ì" },
+ ["ĺ"]={ "l","Ì" },
+ ["Ļ"]={ "L","̧" },
+ ["ļ"]={ "l","̧" },
+ ["Ľ"]={ "L","̌" },
+ ["ľ"]={ "l","̌" },
+ ["Ń"]={ "N","Ì" },
+ ["Å„"]={ "n","Ì" },
+ ["Ņ"]={ "N","̧" },
+ ["ņ"]={ "n","̧" },
+ ["Ň"]={ "N","̌" },
+ ["ň"]={ "n","̌" },
+ ["Ō"]={ "O","̄" },
+ ["Å"]={ "o","Ì„" },
+ ["Ŏ"]={ "O","̆" },
+ ["Å"]={ "o","̆" },
+ ["Å"]={ "O","Ì‹" },
+ ["Å‘"]={ "o","Ì‹" },
+ ["Å”"]={ "R","Ì" },
+ ["Å•"]={ "r","Ì" },
+ ["Ŗ"]={ "R","̧" },
+ ["ŗ"]={ "r","̧" },
+ ["Ř"]={ "R","̌" },
+ ["ř"]={ "r","̌" },
+ ["Åš"]={ "S","Ì" },
+ ["Å›"]={ "s","Ì" },
+ ["Ŝ"]={ "S","̂" },
+ ["Å"]={ "s","Ì‚" },
+ ["Ş"]={ "S","̧" },
+ ["ş"]={ "s","̧" },
+ ["Š"]={ "S","̌" },
+ ["š"]={ "s","̌" },
+ ["Ţ"]={ "T","̧" },
+ ["ţ"]={ "t","̧" },
+ ["Ť"]={ "T","̌" },
+ ["ť"]={ "t","̌" },
+ ["Ũ"]={ "U","̃" },
+ ["ũ"]={ "u","̃" },
+ ["Ū"]={ "U","̄" },
+ ["Å«"]={ "u","Ì„" },
+ ["Ŭ"]={ "U","̆" },
+ ["ŭ"]={ "u","̆" },
+ ["Å®"]={ "U","ÌŠ" },
+ ["ů"]={ "u","̊" },
+ ["Å°"]={ "U","Ì‹" },
+ ["ű"]={ "u","̋" },
+ ["Ų"]={ "U","̨" },
+ ["ų"]={ "u","̨" },
+ ["Å´"]={ "W","Ì‚" },
+ ["ŵ"]={ "w","̂" },
+ ["Ŷ"]={ "Y","̂" },
+ ["Å·"]={ "y","Ì‚" },
+ ["Ÿ"]={ "Y","̈" },
+ ["Ź"]={ "Z","Ì" },
+ ["ź"]={ "z","Ì" },
+ ["Ż"]={ "Z","̇" },
+ ["ż"]={ "z","̇" },
+ ["Ž"]={ "Z","̌" },
+ ["ž"]={ "z","̌" },
+ ["Æ "]={ "O","Ì›" },
+ ["Æ¡"]={ "o","Ì›" },
+ ["Ư"]={ "U","̛" },
+ ["Æ°"]={ "u","Ì›" },
+ ["Ç"]={ "A","ÌŒ" },
+ ["ǎ"]={ "a","̌" },
+ ["Ç"]={ "I","ÌŒ" },
+ ["Ç"]={ "i","ÌŒ" },
+ ["Ǒ"]={ "O","̌" },
+ ["ǒ"]={ "o","̌" },
+ ["Ǔ"]={ "U","̌" },
+ ["ǔ"]={ "u","̌" },
+ ["Ǖ"]={ "Ü","̄" },
+ ["ǖ"]={ "ü","̄" },
+ ["Ç—"]={ "Ãœ","Ì" },
+ ["ǘ"]={ "ü","Ì" },
+ ["Ǚ"]={ "Ü","̌" },
+ ["ǚ"]={ "ü","̌" },
+ ["Ǜ"]={ "Ü","̀" },
+ ["ǜ"]={ "ü","̀" },
+ ["Ǟ"]={ "Ä","̄" },
+ ["ǟ"]={ "ä","̄" },
+ ["Ǡ"]={ "Ȧ","̄" },
+ ["ǡ"]={ "ȧ","̄" },
+ ["Ǣ"]={ "Æ","̄" },
+ ["ǣ"]={ "æ","̄" },
+ ["Ǧ"]={ "G","̌" },
+ ["ǧ"]={ "g","̌" },
+ ["Ǩ"]={ "K","̌" },
+ ["ǩ"]={ "k","̌" },
+ ["Ǫ"]={ "O","̨" },
+ ["ǫ"]={ "o","̨" },
+ ["Ǭ"]={ "Ǫ","̄" },
+ ["Ç­"]={ "Ç«","Ì„" },
+ ["Ǯ"]={ "Ʒ","̌" },
+ ["ǯ"]={ "ʒ","̌" },
+ ["ǰ"]={ "j","̌" },
+ ["Ç´"]={ "G","Ì" },
+ ["ǵ"]={ "g","Ì" },
+ ["Ǹ"]={ "N","̀" },
+ ["ǹ"]={ "n","̀" },
+ ["Ǻ"]={ "Ã…","Ì" },
+ ["Ç»"]={ "Ã¥","Ì" },
+ ["Ǽ"]={ "Æ","Ì" },
+ ["ǽ"]={ "æ","Ì" },
+ ["Ǿ"]={ "Ø","Ì" },
+ ["Ç¿"]={ "ø","Ì" },
+ ["È€"]={ "A","Ì" },
+ ["È"]={ "a","Ì" },
+ ["È‚"]={ "A","Ì‘" },
+ ["ȃ"]={ "a","̑" },
+ ["È„"]={ "E","Ì" },
+ ["È…"]={ "e","Ì" },
+ ["Ȇ"]={ "E","̑" },
+ ["ȇ"]={ "e","̑" },
+ ["Ȉ"]={ "I","Ì" },
+ ["ȉ"]={ "i","Ì" },
+ ["ÈŠ"]={ "I","Ì‘" },
+ ["È‹"]={ "i","Ì‘" },
+ ["ÈŒ"]={ "O","Ì" },
+ ["È"]={ "o","Ì" },
+ ["ÈŽ"]={ "O","Ì‘" },
+ ["È"]={ "o","Ì‘" },
+ ["È"]={ "R","Ì" },
+ ["È‘"]={ "r","Ì" },
+ ["È’"]={ "R","Ì‘" },
+ ["È“"]={ "r","Ì‘" },
+ ["È”"]={ "U","Ì" },
+ ["È•"]={ "u","Ì" },
+ ["È–"]={ "U","Ì‘" },
+ ["È—"]={ "u","Ì‘" },
+ ["Ș"]={ "S","̦" },
+ ["ș"]={ "s","̦" },
+ ["Ț"]={ "T","̦" },
+ ["ț"]={ "t","̦" },
+ ["Ȟ"]={ "H","̌" },
+ ["ȟ"]={ "h","̌" },
+ ["Ȧ"]={ "A","̇" },
+ ["ȧ"]={ "a","̇" },
+ ["Ȩ"]={ "E","̧" },
+ ["ȩ"]={ "e","̧" },
+ ["Ȫ"]={ "Ö","̄" },
+ ["ȫ"]={ "ö","̄" },
+ ["Ȭ"]={ "Õ","̄" },
+ ["ȭ"]={ "õ","̄" },
+ ["Ȯ"]={ "O","̇" },
+ ["ȯ"]={ "o","̇" },
+ ["È°"]={ "È®","Ì„" },
+ ["ȱ"]={ "ȯ","̄" },
+ ["Ȳ"]={ "Y","̄" },
+ ["ȳ"]={ "y","̄" },
+ ["Í„"]={ "̈","Ì" },
+ ["Î…"]={ "¨","Ì" },
+ ["Ά"]={ "Α","Ì" },
+ ["Έ"]={ "Ε","Ì" },
+ ["Ή"]={ "Η","Ì" },
+ ["Ί"]={ "Ι","Ì" },
+ ["ÎŒ"]={ "Ο","Ì" },
+ ["ÎŽ"]={ "Î¥","Ì" },
+ ["Î"]={ "Ω","Ì" },
+ ["Î"]={ "ÏŠ","Ì" },
+ ["Ϊ"]={ "Ι","̈" },
+ ["Ϋ"]={ "Υ","̈" },
+ ["ά"]={ "α","Ì" },
+ ["έ"]={ "ε","Ì" },
+ ["ή"]={ "η","Ì" },
+ ["ί"]={ "ι","Ì" },
+ ["ΰ"]={ "Ï‹","Ì" },
+ ["ϊ"]={ "ι","̈" },
+ ["ϋ"]={ "υ","̈" },
+ ["ÏŒ"]={ "ο","Ì" },
+ ["Ï"]={ "Ï…","Ì" },
+ ["ÏŽ"]={ "ω","Ì" },
+ ["Ï“"]={ "Ï’","Ì" },
+ ["ϔ"]={ "ϒ","̈" },
+ ["Ѐ"]={ "Е","̀" },
+ ["Ð"]={ "Е","̈" },
+ ["Ѓ"]={ "Г","Ì" },
+ ["Ї"]={ "І","̈" },
+ ["ÐŒ"]={ "К","Ì" },
+ ["Ð"]={ "И","Ì€" },
+ ["Ў"]={ "У","̆" },
+ ["Й"]={ "И","̆" },
+ ["й"]={ "и","̆" },
+ ["Ñ"]={ "е","Ì€" },
+ ["ё"]={ "е","̈" },
+ ["Ñ“"]={ "г","Ì" },
+ ["ї"]={ "і","̈" },
+ ["Ñœ"]={ "к","Ì" },
+ ["Ñ"]={ "и","Ì€" },
+ ["ў"]={ "у","̆" },
+ ["Ѷ"]={ "Ñ´","Ì" },
+ ["Ñ·"]={ "ѵ","Ì" },
+ ["Ó"]={ "Ж","̆" },
+ ["ӂ"]={ "ж","̆" },
+ ["Ó"]={ "Ð","̆" },
+ ["ӑ"]={ "а","̆" },
+ ["Ó’"]={ "Ð","̈" },
+ ["ӓ"]={ "а","̈" },
+ ["Ӗ"]={ "Е","̆" },
+ ["ӗ"]={ "е","̆" },
+ ["Ӛ"]={ "Ә","̈" },
+ ["ӛ"]={ "ә","̈" },
+ ["Ӝ"]={ "Ж","̈" },
+ ["Ó"]={ "ж","̈" },
+ ["Ӟ"]={ "З","̈" },
+ ["ӟ"]={ "з","̈" },
+ ["Ӣ"]={ "И","̄" },
+ ["ӣ"]={ "и","̄" },
+ ["Ӥ"]={ "И","̈" },
+ ["ӥ"]={ "и","̈" },
+ ["Ӧ"]={ "О","̈" },
+ ["ӧ"]={ "о","̈" },
+ ["Ӫ"]={ "Ө","̈" },
+ ["ӫ"]={ "ө","̈" },
+ ["Ӭ"]={ "Э","̈" },
+ ["Ó­"]={ "Ñ","̈" },
+ ["Ӯ"]={ "У","̄" },
+ ["ӯ"]={ "у","̄" },
+ ["Ӱ"]={ "У","̈" },
+ ["ӱ"]={ "у","̈" },
+ ["Ӳ"]={ "У","̋" },
+ ["ӳ"]={ "у","̋" },
+ ["Ӵ"]={ "Ч","̈" },
+ ["ӵ"]={ "ч","̈" },
+ ["Ӹ"]={ "Ы","̈" },
+ ["ӹ"]={ "ы","̈" },
+ ["آ"]={ "ا","ٓ" },
+ ["أ"]={ "ا","ٔ" },
+ ["ؤ"]={ "و","ٔ" },
+ ["إ"]={ "ا","ٕ" },
+ ["ئ"]={ "ي","ٔ" },
+ ["Û€"]={ "Û•","Ù”" },
+ ["Û‚"]={ "Û","Ù”" },
+ ["Û“"]={ "Û’","Ù”" },
+ ["ऩ"]={ "न","़" },
+ ["ऱ"]={ "र","़" },
+ ["ऴ"]={ "ळ","़" },
+ ["क़"]={ "क","़" },
+ ["ख़"]={ "ख","़" },
+ ["ग़"]={ "ग","़" },
+ ["ज़"]={ "ज","़" },
+ ["ड़"]={ "ड","़" },
+ ["à¥"]={ "ढ","़" },
+ ["फ़"]={ "फ","़" },
+ ["य़"]={ "य","़" },
+ ["ো"]={ "ে","া" },
+ ["ৌ"]={ "ে","ৗ" },
+ ["ড়"]={ "ড","়" },
+ ["à§"]={ "ঢ","়" },
+ ["য়"]={ "য","়" },
+ ["ਲ਼"]={ "ਲ","਼" },
+ ["ਸ਼"]={ "ਸ","਼" },
+ ["ਖ਼"]={ "ਖ","਼" },
+ ["ਗ਼"]={ "ਗ","਼" },
+ ["ਜ਼"]={ "ਜ","਼" },
+ ["ਫ਼"]={ "ਫ","਼" },
+ ["à­ˆ"]={ "à­‡","à­–" },
+ ["ୋ"]={ "େ","ା" },
+ ["ୌ"]={ "େ","ୗ" },
+ ["ଡ଼"]={ "ଡ","଼" },
+ ["à­"]={ "ଢ","଼" },
+ ["ஔ"]={ "ஒ","ௗ" },
+ ["ொ"]={ "ெ","ா" },
+ ["ோ"]={ "ே","ா" },
+ ["ௌ"]={ "ெ","ௗ" },
+ ["ై"]={ "ె","ౖ" },
+ ["ೀ"]={ "ಿ","ೕ" },
+ ["ೇ"]={ "ೆ","ೕ" },
+ ["ೈ"]={ "ೆ","ೖ" },
+ ["ೊ"]={ "ೆ","ೂ" },
+ ["ೋ"]={ "ೊ","ೕ" },
+ ["ൊ"]={ "െ","ാ" },
+ ["ോ"]={ "േ","ാ" },
+ ["ൌ"]={ "െ","ൗ" },
+ ["à·š"]={ "à·™","à·Š" },
+ ["à·œ"]={ "à·™","à·" },
+ ["à·"]={ "à·œ","à·Š" },
+ ["à·ž"]={ "à·™","à·Ÿ" },
+ ["གྷ"]={ "ག","ྷ" },
+ ["à½"]={ "ཌ","ྷ" },
+ ["དྷ"]={ "ད","ྷ" },
+ ["བྷ"]={ "བ","ྷ" },
+ ["ཛྷ"]={ "ཛ","ྷ" },
+ ["ཀྵ"]={ "ཀ","ྵ" },
+ ["ཱི"]={ "ཱ","ི" },
+ ["ཱུ"]={ "ཱ","ུ" },
+ ["ྲྀ"]={ "ྲ","ྀ" },
+ ["ླྀ"]={ "ླ","ྀ" },
+ ["à¾"]={ "ཱ","ྀ" },
+ ["ྒྷ"]={ "ྒ","ྷ" },
+ ["à¾"]={ "ྜ","ྷ" },
+ ["ྡྷ"]={ "ྡ","ྷ" },
+ ["ྦྷ"]={ "ྦ","ྷ" },
+ ["ྫྷ"]={ "ྫ","ྷ" },
+ ["ྐྵ"]={ "à¾","ྵ" },
+ ["ဦ"]={ "ဥ","ီ" },
+ ["ᬆ"]={ "ᬅ","ᬵ" },
+ ["ᬈ"]={ "ᬇ","ᬵ" },
+ ["ᬊ"]={ "ᬉ","ᬵ" },
+ ["ᬌ"]={ "ᬋ","ᬵ" },
+ ["ᬎ"]={ "á¬","ᬵ" },
+ ["ᬒ"]={ "ᬑ","ᬵ" },
+ ["ᬻ"]={ "ᬺ","ᬵ" },
+ ["ᬽ"]={ "ᬼ","ᬵ" },
+ ["ᭀ"]={ "ᬾ","ᬵ" },
+ ["á­"]={ "ᬿ","ᬵ" },
+ ["ᭃ"]={ "ᭂ","ᬵ" },
+ ["Ḁ"]={ "A","̥" },
+ ["á¸"]={ "a","Ì¥" },
+ ["Ḃ"]={ "B","̇" },
+ ["ḃ"]={ "b","̇" },
+ ["Ḅ"]={ "B","̣" },
+ ["ḅ"]={ "b","̣" },
+ ["Ḇ"]={ "B","̱" },
+ ["ḇ"]={ "b","̱" },
+ ["Ḉ"]={ "Ç","Ì" },
+ ["ḉ"]={ "ç","Ì" },
+ ["Ḋ"]={ "D","̇" },
+ ["ḋ"]={ "d","̇" },
+ ["Ḍ"]={ "D","̣" },
+ ["á¸"]={ "d","Ì£" },
+ ["Ḏ"]={ "D","̱" },
+ ["á¸"]={ "d","̱" },
+ ["á¸"]={ "D","̧" },
+ ["ḑ"]={ "d","̧" },
+ ["Ḓ"]={ "D","̭" },
+ ["ḓ"]={ "d","̭" },
+ ["Ḕ"]={ "Ē","̀" },
+ ["ḕ"]={ "ē","̀" },
+ ["Ḗ"]={ "Ä’","Ì" },
+ ["ḗ"]={ "Ä“","Ì" },
+ ["Ḙ"]={ "E","̭" },
+ ["ḙ"]={ "e","̭" },
+ ["Ḛ"]={ "E","̰" },
+ ["ḛ"]={ "e","̰" },
+ ["Ḝ"]={ "Ȩ","̆" },
+ ["á¸"]={ "È©","̆" },
+ ["Ḟ"]={ "F","̇" },
+ ["ḟ"]={ "f","̇" },
+ ["Ḡ"]={ "G","̄" },
+ ["ḡ"]={ "g","̄" },
+ ["Ḣ"]={ "H","̇" },
+ ["ḣ"]={ "h","̇" },
+ ["Ḥ"]={ "H","̣" },
+ ["ḥ"]={ "h","̣" },
+ ["Ḧ"]={ "H","̈" },
+ ["ḧ"]={ "h","̈" },
+ ["Ḩ"]={ "H","̧" },
+ ["ḩ"]={ "h","̧" },
+ ["Ḫ"]={ "H","̮" },
+ ["ḫ"]={ "h","̮" },
+ ["Ḭ"]={ "I","̰" },
+ ["ḭ"]={ "i","̰" },
+ ["Ḯ"]={ "Ã","Ì" },
+ ["ḯ"]={ "ï","Ì" },
+ ["Ḱ"]={ "K","Ì" },
+ ["ḱ"]={ "k","Ì" },
+ ["Ḳ"]={ "K","̣" },
+ ["ḳ"]={ "k","̣" },
+ ["Ḵ"]={ "K","̱" },
+ ["ḵ"]={ "k","̱" },
+ ["Ḷ"]={ "L","̣" },
+ ["ḷ"]={ "l","̣" },
+ ["Ḹ"]={ "Ḷ","̄" },
+ ["ḹ"]={ "ḷ","̄" },
+ ["Ḻ"]={ "L","̱" },
+ ["ḻ"]={ "l","̱" },
+ ["Ḽ"]={ "L","̭" },
+ ["ḽ"]={ "l","̭" },
+ ["Ḿ"]={ "M","Ì" },
+ ["ḿ"]={ "m","Ì" },
+ ["Ṁ"]={ "M","̇" },
+ ["á¹"]={ "m","̇" },
+ ["Ṃ"]={ "M","̣" },
+ ["ṃ"]={ "m","̣" },
+ ["Ṅ"]={ "N","̇" },
+ ["ṅ"]={ "n","̇" },
+ ["Ṇ"]={ "N","̣" },
+ ["ṇ"]={ "n","̣" },
+ ["Ṉ"]={ "N","̱" },
+ ["ṉ"]={ "n","̱" },
+ ["Ṋ"]={ "N","̭" },
+ ["ṋ"]={ "n","̭" },
+ ["Ṍ"]={ "Õ","Ì" },
+ ["á¹"]={ "õ","Ì" },
+ ["Ṏ"]={ "Õ","̈" },
+ ["á¹"]={ "õ","̈" },
+ ["á¹"]={ "ÅŒ","Ì€" },
+ ["ṑ"]={ "Å","Ì€" },
+ ["á¹’"]={ "ÅŒ","Ì" },
+ ["ṓ"]={ "Å","Ì" },
+ ["á¹”"]={ "P","Ì" },
+ ["ṕ"]={ "p","Ì" },
+ ["Ṗ"]={ "P","̇" },
+ ["ṗ"]={ "p","̇" },
+ ["Ṙ"]={ "R","̇" },
+ ["ṙ"]={ "r","̇" },
+ ["Ṛ"]={ "R","̣" },
+ ["á¹›"]={ "r","Ì£" },
+ ["Ṝ"]={ "Ṛ","̄" },
+ ["á¹"]={ "á¹›","Ì„" },
+ ["Ṟ"]={ "R","̱" },
+ ["ṟ"]={ "r","̱" },
+ ["Ṡ"]={ "S","̇" },
+ ["ṡ"]={ "s","̇" },
+ ["á¹¢"]={ "S","Ì£" },
+ ["á¹£"]={ "s","Ì£" },
+ ["Ṥ"]={ "Ś","̇" },
+ ["ṥ"]={ "ś","̇" },
+ ["Ṧ"]={ "Š","̇" },
+ ["ṧ"]={ "š","̇" },
+ ["Ṩ"]={ "Ṣ","̇" },
+ ["ṩ"]={ "ṣ","̇" },
+ ["Ṫ"]={ "T","̇" },
+ ["ṫ"]={ "t","̇" },
+ ["Ṭ"]={ "T","̣" },
+ ["á¹­"]={ "t","Ì£" },
+ ["Ṯ"]={ "T","̱" },
+ ["ṯ"]={ "t","̱" },
+ ["á¹°"]={ "T","Ì­" },
+ ["á¹±"]={ "t","Ì­" },
+ ["Ṳ"]={ "U","̤" },
+ ["ṳ"]={ "u","̤" },
+ ["á¹´"]={ "U","Ì°" },
+ ["á¹µ"]={ "u","Ì°" },
+ ["Ṷ"]={ "U","̭" },
+ ["á¹·"]={ "u","Ì­" },
+ ["Ṹ"]={ "Ũ","Ì" },
+ ["á¹¹"]={ "Å©","Ì" },
+ ["Ṻ"]={ "Ū","̈" },
+ ["ṻ"]={ "ū","̈" },
+ ["Ṽ"]={ "V","̃" },
+ ["ṽ"]={ "v","̃" },
+ ["á¹¾"]={ "V","Ì£" },
+ ["ṿ"]={ "v","̣" },
+ ["Ẁ"]={ "W","̀" },
+ ["áº"]={ "w","Ì€" },
+ ["Ẃ"]={ "W","Ì" },
+ ["ẃ"]={ "w","Ì" },
+ ["Ẅ"]={ "W","̈" },
+ ["ẅ"]={ "w","̈" },
+ ["Ẇ"]={ "W","̇" },
+ ["ẇ"]={ "w","̇" },
+ ["Ẉ"]={ "W","̣" },
+ ["ẉ"]={ "w","̣" },
+ ["Ẋ"]={ "X","̇" },
+ ["ẋ"]={ "x","̇" },
+ ["Ẍ"]={ "X","̈" },
+ ["áº"]={ "x","̈" },
+ ["Ẏ"]={ "Y","̇" },
+ ["áº"]={ "y","̇" },
+ ["áº"]={ "Z","Ì‚" },
+ ["ẑ"]={ "z","̂" },
+ ["Ẓ"]={ "Z","̣" },
+ ["ẓ"]={ "z","̣" },
+ ["Ẕ"]={ "Z","̱" },
+ ["ẕ"]={ "z","̱" },
+ ["ẖ"]={ "h","̱" },
+ ["ẗ"]={ "t","̈" },
+ ["ẘ"]={ "w","̊" },
+ ["ẙ"]={ "y","̊" },
+ ["ẛ"]={ "ſ","̇" },
+ ["Ạ"]={ "A","̣" },
+ ["ạ"]={ "a","̣" },
+ ["Ả"]={ "A","̉" },
+ ["ả"]={ "a","̉" },
+ ["Ấ"]={ "Â","Ì" },
+ ["ấ"]={ "â","Ì" },
+ ["Ầ"]={ "Â","̀" },
+ ["ầ"]={ "â","̀" },
+ ["Ẩ"]={ "Â","̉" },
+ ["ẩ"]={ "â","̉" },
+ ["Ẫ"]={ "Â","̃" },
+ ["ẫ"]={ "â","̃" },
+ ["Ậ"]={ "Ạ","̂" },
+ ["ậ"]={ "ạ","̂" },
+ ["Ắ"]={ "Ä‚","Ì" },
+ ["ắ"]={ "ă","Ì" },
+ ["Ằ"]={ "Ă","̀" },
+ ["ằ"]={ "ă","̀" },
+ ["Ẳ"]={ "Ă","̉" },
+ ["ẳ"]={ "ă","̉" },
+ ["Ẵ"]={ "Ă","̃" },
+ ["ẵ"]={ "ă","̃" },
+ ["Ặ"]={ "Ạ","̆" },
+ ["ặ"]={ "ạ","̆" },
+ ["Ẹ"]={ "E","̣" },
+ ["ẹ"]={ "e","̣" },
+ ["Ẻ"]={ "E","̉" },
+ ["ẻ"]={ "e","̉" },
+ ["Ẽ"]={ "E","̃" },
+ ["ẽ"]={ "e","̃" },
+ ["Ế"]={ "Ê","Ì" },
+ ["ế"]={ "ê","Ì" },
+ ["Ề"]={ "Ê","̀" },
+ ["á»"]={ "ê","Ì€" },
+ ["Ể"]={ "Ê","̉" },
+ ["ể"]={ "ê","̉" },
+ ["Ễ"]={ "Ê","̃" },
+ ["ễ"]={ "ê","̃" },
+ ["Ệ"]={ "Ẹ","̂" },
+ ["ệ"]={ "ẹ","̂" },
+ ["Ỉ"]={ "I","̉" },
+ ["ỉ"]={ "i","̉" },
+ ["Ị"]={ "I","̣" },
+ ["ị"]={ "i","̣" },
+ ["Ọ"]={ "O","̣" },
+ ["á»"]={ "o","Ì£" },
+ ["Ỏ"]={ "O","̉" },
+ ["á»"]={ "o","̉" },
+ ["á»"]={ "Ô","Ì" },
+ ["ố"]={ "ô","Ì" },
+ ["Ồ"]={ "Ô","̀" },
+ ["ồ"]={ "ô","̀" },
+ ["Ổ"]={ "Ô","̉" },
+ ["ổ"]={ "ô","̉" },
+ ["Ỗ"]={ "Ô","̃" },
+ ["ỗ"]={ "ô","̃" },
+ ["Ộ"]={ "Ọ","̂" },
+ ["á»™"]={ "á»","Ì‚" },
+ ["Ớ"]={ "Æ ","Ì" },
+ ["á»›"]={ "Æ¡","Ì" },
+ ["Ờ"]={ "Ơ","̀" },
+ ["á»"]={ "Æ¡","Ì€" },
+ ["Ở"]={ "Ơ","̉" },
+ ["ở"]={ "ơ","̉" },
+ ["Ỡ"]={ "Ơ","̃" },
+ ["ỡ"]={ "ơ","̃" },
+ ["Ợ"]={ "Ơ","̣" },
+ ["ợ"]={ "ơ","̣" },
+ ["Ụ"]={ "U","̣" },
+ ["ụ"]={ "u","̣" },
+ ["Ủ"]={ "U","̉" },
+ ["ủ"]={ "u","̉" },
+ ["Ứ"]={ "Ư","Ì" },
+ ["ứ"]={ "Æ°","Ì" },
+ ["Ừ"]={ "Ư","̀" },
+ ["ừ"]={ "ư","̀" },
+ ["Ử"]={ "Ư","̉" },
+ ["ử"]={ "ư","̉" },
+ ["Ữ"]={ "Ư","̃" },
+ ["ữ"]={ "ư","̃" },
+ ["Ự"]={ "Ư","̣" },
+ ["á»±"]={ "Æ°","Ì£" },
+ ["Ỳ"]={ "Y","̀" },
+ ["ỳ"]={ "y","̀" },
+ ["á»´"]={ "Y","Ì£" },
+ ["ỵ"]={ "y","̣" },
+ ["Ỷ"]={ "Y","̉" },
+ ["ỷ"]={ "y","̉" },
+ ["Ỹ"]={ "Y","̃" },
+ ["ỹ"]={ "y","̃" },
+ ["ἀ"]={ "α","̓" },
+ ["á¼"]={ "α","Ì”" },
+ ["ἂ"]={ "ἀ","̀" },
+ ["ἃ"]={ "á¼","Ì€" },
+ ["ἄ"]={ "á¼€","Ì" },
+ ["á¼…"]={ "á¼","Ì" },
+ ["ἆ"]={ "ἀ","͂" },
+ ["ἇ"]={ "á¼","Í‚" },
+ ["Ἀ"]={ "Α","̓" },
+ ["Ἁ"]={ "Α","̔" },
+ ["Ἂ"]={ "Ἀ","̀" },
+ ["Ἃ"]={ "Ἁ","̀" },
+ ["Ἄ"]={ "Ἀ","Ì" },
+ ["á¼"]={ "Ἁ","Ì" },
+ ["Ἆ"]={ "Ἀ","͂" },
+ ["á¼"]={ "Ἁ","Í‚" },
+ ["á¼"]={ "ε","Ì“" },
+ ["ἑ"]={ "ε","̔" },
+ ["á¼’"]={ "á¼","Ì€" },
+ ["ἓ"]={ "ἑ","̀" },
+ ["á¼”"]={ "á¼","Ì" },
+ ["ἕ"]={ "ἑ","Ì" },
+ ["Ἐ"]={ "Ε","̓" },
+ ["Ἑ"]={ "Ε","̔" },
+ ["Ἒ"]={ "Ἐ","̀" },
+ ["á¼›"]={ "á¼™","Ì€" },
+ ["Ἔ"]={ "Ἐ","Ì" },
+ ["á¼"]={ "á¼™","Ì" },
+ ["ἠ"]={ "η","̓" },
+ ["ἡ"]={ "η","̔" },
+ ["á¼¢"]={ "á¼ ","Ì€" },
+ ["ἣ"]={ "ἡ","̀" },
+ ["ἤ"]={ "á¼ ","Ì" },
+ ["á¼¥"]={ "ἡ","Ì" },
+ ["ἦ"]={ "ἠ","͂" },
+ ["ἧ"]={ "ἡ","͂" },
+ ["Ἠ"]={ "Η","̓" },
+ ["Ἡ"]={ "Η","̔" },
+ ["Ἢ"]={ "Ἠ","̀" },
+ ["Ἣ"]={ "Ἡ","̀" },
+ ["Ἤ"]={ "Ἠ","Ì" },
+ ["á¼­"]={ "Ἡ","Ì" },
+ ["Ἦ"]={ "Ἠ","͂" },
+ ["Ἧ"]={ "Ἡ","͂" },
+ ["ἰ"]={ "ι","̓" },
+ ["ἱ"]={ "ι","̔" },
+ ["á¼²"]={ "á¼°","Ì€" },
+ ["á¼³"]={ "á¼±","Ì€" },
+ ["á¼´"]={ "á¼°","Ì" },
+ ["á¼µ"]={ "á¼±","Ì" },
+ ["ἶ"]={ "ἰ","͂" },
+ ["á¼·"]={ "á¼±","Í‚" },
+ ["Ἰ"]={ "Ι","̓" },
+ ["Ἱ"]={ "Ι","̔" },
+ ["Ἲ"]={ "Ἰ","̀" },
+ ["á¼»"]={ "á¼¹","Ì€" },
+ ["á¼¼"]={ "Ἰ","Ì" },
+ ["á¼½"]={ "á¼¹","Ì" },
+ ["Ἶ"]={ "Ἰ","͂" },
+ ["Ἷ"]={ "Ἱ","͂" },
+ ["ὀ"]={ "ο","̓" },
+ ["á½"]={ "ο","Ì”" },
+ ["ὂ"]={ "ὀ","̀" },
+ ["ὃ"]={ "á½","Ì€" },
+ ["ὄ"]={ "á½€","Ì" },
+ ["á½…"]={ "á½","Ì" },
+ ["Ὀ"]={ "Ο","̓" },
+ ["Ὁ"]={ "Ο","̔" },
+ ["Ὂ"]={ "Ὀ","̀" },
+ ["Ὃ"]={ "Ὁ","̀" },
+ ["Ὄ"]={ "Ὀ","Ì" },
+ ["á½"]={ "Ὁ","Ì" },
+ ["á½"]={ "Ï…","Ì“" },
+ ["ὑ"]={ "υ","̔" },
+ ["á½’"]={ "á½","Ì€" },
+ ["ὓ"]={ "ὑ","̀" },
+ ["á½”"]={ "á½","Ì" },
+ ["ὕ"]={ "ὑ","Ì" },
+ ["á½–"]={ "á½","Í‚" },
+ ["ὗ"]={ "ὑ","͂" },
+ ["á½™"]={ "Î¥","Ì”" },
+ ["á½›"]={ "á½™","Ì€" },
+ ["á½"]={ "á½™","Ì" },
+ ["Ὗ"]={ "Ὑ","͂" },
+ ["ὠ"]={ "ω","̓" },
+ ["ὡ"]={ "ω","̔" },
+ ["á½¢"]={ "á½ ","Ì€" },
+ ["ὣ"]={ "ὡ","̀" },
+ ["ὤ"]={ "á½ ","Ì" },
+ ["á½¥"]={ "ὡ","Ì" },
+ ["ὦ"]={ "ὠ","͂" },
+ ["ὧ"]={ "ὡ","͂" },
+ ["Ὠ"]={ "Ω","̓" },
+ ["Ὡ"]={ "Ω","̔" },
+ ["Ὢ"]={ "Ὠ","̀" },
+ ["Ὣ"]={ "Ὡ","̀" },
+ ["Ὤ"]={ "Ὠ","Ì" },
+ ["á½­"]={ "Ὡ","Ì" },
+ ["Ὦ"]={ "Ὠ","͂" },
+ ["Ὧ"]={ "Ὡ","͂" },
+ ["ὰ"]={ "α","̀" },
+ ["ὲ"]={ "ε","̀" },
+ ["ὴ"]={ "η","̀" },
+ ["ὶ"]={ "ι","̀" },
+ ["ὸ"]={ "ο","̀" },
+ ["ὺ"]={ "υ","̀" },
+ ["ὼ"]={ "ω","̀" },
+ ["á¾€"]={ "á¼€","Í…" },
+ ["á¾"]={ "á¼","Í…" },
+ ["ᾂ"]={ "ἂ","ͅ" },
+ ["ᾃ"]={ "ἃ","ͅ" },
+ ["ᾄ"]={ "ἄ","ͅ" },
+ ["á¾…"]={ "á¼…","Í…" },
+ ["ᾆ"]={ "ἆ","ͅ" },
+ ["ᾇ"]={ "ἇ","ͅ" },
+ ["ᾈ"]={ "Ἀ","ͅ" },
+ ["ᾉ"]={ "Ἁ","ͅ" },
+ ["ᾊ"]={ "Ἂ","ͅ" },
+ ["ᾋ"]={ "Ἃ","ͅ" },
+ ["ᾌ"]={ "Ἄ","ͅ" },
+ ["á¾"]={ "á¼","Í…" },
+ ["ᾎ"]={ "Ἆ","ͅ" },
+ ["á¾"]={ "á¼","Í…" },
+ ["á¾"]={ "á¼ ","Í…" },
+ ["ᾑ"]={ "ἡ","ͅ" },
+ ["á¾’"]={ "á¼¢","Í…" },
+ ["ᾓ"]={ "ἣ","ͅ" },
+ ["ᾔ"]={ "ἤ","ͅ" },
+ ["ᾕ"]={ "ἥ","ͅ" },
+ ["ᾖ"]={ "ἦ","ͅ" },
+ ["ᾗ"]={ "ἧ","ͅ" },
+ ["ᾘ"]={ "Ἠ","ͅ" },
+ ["ᾙ"]={ "Ἡ","ͅ" },
+ ["ᾚ"]={ "Ἢ","ͅ" },
+ ["ᾛ"]={ "Ἣ","ͅ" },
+ ["ᾜ"]={ "Ἤ","ͅ" },
+ ["á¾"]={ "á¼­","Í…" },
+ ["ᾞ"]={ "Ἦ","ͅ" },
+ ["ᾟ"]={ "Ἧ","ͅ" },
+ ["á¾ "]={ "á½ ","Í…" },
+ ["ᾡ"]={ "ὡ","ͅ" },
+ ["á¾¢"]={ "á½¢","Í…" },
+ ["á¾£"]={ "á½£","Í…" },
+ ["ᾤ"]={ "ὤ","ͅ" },
+ ["á¾¥"]={ "á½¥","Í…" },
+ ["ᾦ"]={ "ὦ","ͅ" },
+ ["ᾧ"]={ "ὧ","ͅ" },
+ ["ᾨ"]={ "Ὠ","ͅ" },
+ ["ᾩ"]={ "Ὡ","ͅ" },
+ ["ᾪ"]={ "Ὢ","ͅ" },
+ ["ᾫ"]={ "Ὣ","ͅ" },
+ ["ᾬ"]={ "Ὤ","ͅ" },
+ ["á¾­"]={ "á½­","Í…" },
+ ["á¾®"]={ "á½®","Í…" },
+ ["ᾯ"]={ "Ὧ","ͅ" },
+ ["ᾰ"]={ "α","̆" },
+ ["ᾱ"]={ "α","̄" },
+ ["á¾²"]={ "á½°","Í…" },
+ ["ᾳ"]={ "α","ͅ" },
+ ["ᾴ"]={ "ά","ͅ" },
+ ["ᾶ"]={ "α","͂" },
+ ["ᾷ"]={ "ᾶ","ͅ" },
+ ["Ᾰ"]={ "Α","̆" },
+ ["Ᾱ"]={ "Α","̄" },
+ ["Ὰ"]={ "Α","̀" },
+ ["ᾼ"]={ "Α","ͅ" },
+ ["á¿"]={ "¨","Í‚" },
+ ["á¿‚"]={ "á½´","Í…" },
+ ["ῃ"]={ "η","ͅ" },
+ ["ῄ"]={ "ή","ͅ" },
+ ["ῆ"]={ "η","͂" },
+ ["ῇ"]={ "ῆ","ͅ" },
+ ["Ὲ"]={ "Ε","̀" },
+ ["Ὴ"]={ "Η","̀" },
+ ["ῌ"]={ "Η","ͅ" },
+ ["á¿"]={ "᾿","Ì€" },
+ ["á¿Ž"]={ "᾿","Ì" },
+ ["á¿"]={ "᾿","Í‚" },
+ ["á¿"]={ "ι","̆" },
+ ["ῑ"]={ "ι","̄" },
+ ["á¿’"]={ "ÏŠ","Ì€" },
+ ["ῖ"]={ "ι","͂" },
+ ["á¿—"]={ "ÏŠ","Í‚" },
+ ["Ῐ"]={ "Ι","̆" },
+ ["Ῑ"]={ "Ι","̄" },
+ ["Ὶ"]={ "Ι","̀" },
+ ["á¿"]={ "῾","Ì€" },
+ ["á¿ž"]={ "῾","Ì" },
+ ["῟"]={ "῾","͂" },
+ ["ῠ"]={ "υ","̆" },
+ ["á¿¡"]={ "Ï…","Ì„" },
+ ["á¿¢"]={ "Ï‹","Ì€" },
+ ["ῤ"]={ "Ï","Ì“" },
+ ["á¿¥"]={ "Ï","Ì”" },
+ ["ῦ"]={ "υ","͂" },
+ ["ῧ"]={ "ϋ","͂" },
+ ["Ῠ"]={ "Υ","̆" },
+ ["á¿©"]={ "Î¥","Ì„" },
+ ["Ὺ"]={ "Υ","̀" },
+ ["Ῥ"]={ "Ρ","̔" },
+ ["῭"]={ "¨","̀" },
+ ["ῲ"]={ "ὼ","ͅ" },
+ ["ῳ"]={ "ω","ͅ" },
+ ["á¿´"]={ "ÏŽ","Í…" },
+ ["ῶ"]={ "ω","͂" },
+ ["ῷ"]={ "ῶ","ͅ" },
+ ["Ὸ"]={ "Ο","̀" },
+ ["Ὼ"]={ "Ω","̀" },
+ ["ῼ"]={ "Ω","ͅ" },
+ ["↚"]={ "â†","̸" },
+ ["↛"]={ "→","̸" },
+ ["↮"]={ "↔","̸" },
+ ["â‡"]={ "â‡","̸" },
+ ["⇎"]={ "⇔","̸" },
+ ["â‡"]={ "⇒","̸" },
+ ["∄"]={ "∃","̸" },
+ ["∉"]={ "∈","̸" },
+ ["∌"]={ "∋","̸" },
+ ["∤"]={ "∣","̸" },
+ ["∦"]={ "∥","̸" },
+ ["â‰"]={ "∼","̸" },
+ ["≄"]={ "≃","̸" },
+ ["≇"]={ "≅","̸" },
+ ["≉"]={ "≈","̸" },
+ ["≠"]={ "=","̸" },
+ ["≢"]={ "≡","̸" },
+ ["≭"]={ "â‰","̸" },
+ ["≮"]={ "<","̸" },
+ ["≯"]={ ">","̸" },
+ ["≰"]={ "≤","̸" },
+ ["≱"]={ "≥","̸" },
+ ["≴"]={ "≲","̸" },
+ ["≵"]={ "≳","̸" },
+ ["≸"]={ "≶","̸" },
+ ["≹"]={ "≷","̸" },
+ ["⊀"]={ "≺","̸" },
+ ["âŠ"]={ "≻","̸" },
+ ["⊄"]={ "⊂","̸" },
+ ["⊅"]={ "⊃","̸" },
+ ["⊈"]={ "⊆","̸" },
+ ["⊉"]={ "⊇","̸" },
+ ["⊬"]={ "⊢","̸" },
+ ["⊭"]={ "⊨","̸" },
+ ["⊮"]={ "⊩","̸" },
+ ["⊯"]={ "⊫","̸" },
+ ["⋠"]={ "≼","̸" },
+ ["⋡"]={ "≽","̸" },
+ ["⋢"]={ "⊑","̸" },
+ ["⋣"]={ "⊒","̸" },
+ ["⋪"]={ "⊲","̸" },
+ ["⋫"]={ "⊳","̸" },
+ ["⋬"]={ "⊴","̸" },
+ ["⋭"]={ "⊵","̸" },
+ ["â«œ"]={ "â«","̸" },
+ ["ãŒ"]={ "ã‹","ã‚™" },
+ ["ãŽ"]={ "ã","ã‚™" },
+ ["ã"]={ "ã","ã‚™" },
+ ["ã’"]={ "ã‘","ã‚™" },
+ ["ã”"]={ "ã“","ã‚™" },
+ ["ã–"]={ "ã•","ã‚™" },
+ ["ã˜"]={ "ã—","ã‚™" },
+ ["ãš"]={ "ã™","ã‚™" },
+ ["ãœ"]={ "ã›","ã‚™" },
+ ["ãž"]={ "ã","ã‚™" },
+ ["ã "]={ "ãŸ","ã‚™" },
+ ["ã¢"]={ "ã¡","ã‚™" },
+ ["ã¥"]={ "ã¤","ã‚™" },
+ ["ã§"]={ "ã¦","ã‚™" },
+ ["ã©"]={ "ã¨","ã‚™" },
+ ["ã°"]={ "ã¯","ã‚™" },
+ ["ã±"]={ "ã¯","ã‚š" },
+ ["ã³"]={ "ã²","ã‚™" },
+ ["ã´"]={ "ã²","ã‚š" },
+ ["ã¶"]={ "ãµ","ã‚™" },
+ ["ã·"]={ "ãµ","ã‚š" },
+ ["ã¹"]={ "ã¸","ã‚™" },
+ ["ãº"]={ "ã¸","ã‚š" },
+ ["ã¼"]={ "ã»","ã‚™" },
+ ["ã½"]={ "ã»","ã‚š" },
+ ["ã‚”"]={ "ã†","ã‚™" },
+ ["ã‚ž"]={ "ã‚","ã‚™" },
+ ["ガ"]={ "カ","゙" },
+ ["ã‚®"]={ "ã‚­","ã‚™" },
+ ["グ"]={ "ク","゙" },
+ ["ゲ"]={ "ケ","゙" },
+ ["ゴ"]={ "コ","゙" },
+ ["ザ"]={ "サ","゙" },
+ ["ジ"]={ "シ","゙" },
+ ["ズ"]={ "ス","゙" },
+ ["ゼ"]={ "セ","゙" },
+ ["ゾ"]={ "ソ","゙" },
+ ["ダ"]={ "タ","゙" },
+ ["ヂ"]={ "ãƒ","ã‚™" },
+ ["ヅ"]={ "ツ","゙" },
+ ["デ"]={ "テ","゙" },
+ ["ド"]={ "ト","゙" },
+ ["ãƒ"]={ "ãƒ","ã‚™" },
+ ["パ"]={ "ãƒ","ã‚š" },
+ ["ビ"]={ "ヒ","゙" },
+ ["ピ"]={ "ヒ","゚" },
+ ["ブ"]={ "フ","゙" },
+ ["プ"]={ "フ","゚" },
+ ["ベ"]={ "ヘ","゙" },
+ ["ペ"]={ "ヘ","゚" },
+ ["ボ"]={ "ホ","゙" },
+ ["ãƒ"]={ "ホ","ã‚š" },
+ ["ヴ"]={ "ウ","゙" },
+ ["ヷ"]={ "ワ","゙" },
+ ["ヸ"]={ "ヰ","゙" },
+ ["ヹ"]={ "ヱ","゙" },
+ ["ヺ"]={ "ヲ","゙" },
+ ["ヾ"]={ "ヽ","゙" },
+ ["ï¬"]={ "×™","Ö´" },
+ ["ײַ"]={ "ײ","ַ" },
+ ["שׁ"]={ "ש","×" },
+ ["שׂ"]={ "ש","ׂ" },
+ ["שּׁ"]={ "ï­‰","×" },
+ ["שּׂ"]={ "שּ","ׂ" },
+ ["אַ"]={ "×","Ö·" },
+ ["אָ"]={ "×","Ö¸" },
+ ["אּ"]={ "×","Ö¼" },
+ ["בּ"]={ "ב","ּ" },
+ ["גּ"]={ "ג","ּ" },
+ ["דּ"]={ "ד","ּ" },
+ ["הּ"]={ "ה","ּ" },
+ ["וּ"]={ "ו","ּ" },
+ ["זּ"]={ "ז","ּ" },
+ ["טּ"]={ "ט","ּ" },
+ ["יּ"]={ "י","ּ" },
+ ["ךּ"]={ "ך","ּ" },
+ ["כּ"]={ "כ","ּ" },
+ ["לּ"]={ "ל","ּ" },
+ ["מּ"]={ "מ","ּ" },
+ ["ï­€"]={ "× ","Ö¼" },
+ ["ï­"]={ "ס","Ö¼" },
+ ["ï­ƒ"]={ "×£","Ö¼" },
+ ["פּ"]={ "פ","ּ" },
+ ["צּ"]={ "צ","ּ" },
+ ["קּ"]={ "ק","ּ" },
+ ["רּ"]={ "ר","ּ" },
+ ["שּ"]={ "ש","ּ" },
+ ["תּ"]={ "ת","ּ" },
+ ["וֹ"]={ "ו","ֹ" },
+ ["בֿ"]={ "ב","ֿ" },
+ ["ï­"]={ "×›","Ö¿" },
+ ["פֿ"]={ "פ","ֿ" },
+ ["𑂚"]={ "𑂙","𑂺" },
+ ["𑂜"]={ "𑂛","𑂺" },
+ ["𑂫"]={ "𑂥","𑂺" },
+ ["𑄮"]={ "𑄱","𑄧" },
+ ["𑄯"]={ "𑄲","𑄧" },
+ ["ð‘‹"]={ "ð‘‡","𑌾" },
+ ["ð‘Œ"]={ "ð‘‡","ð‘—" },
+ ["ð‘’»"]={ "ð‘’¹","ð‘’º" },
+ ["ð‘’¼"]={ "ð‘’¹","ð‘’°" },
+ ["ð‘’¾"]={ "ð‘’¹","ð‘’½" },
+ ["ð‘–º"]={ "ð‘–¸","ð‘–¯" },
+ ["ð‘–»"]={ "ð‘–¹","ð‘–¯" },
+ ["ð…ž"]={ "ð…—","ð…¥" },
+ ["ð…Ÿ"]={ "ð…˜","ð…¥" },
+ ["ð… "]={ "ð…Ÿ","ð…®" },
+ ["ð…¡"]={ "ð…Ÿ","ð…¯" },
+ ["ð…¢"]={ "ð…Ÿ","ð…°" },
+ ["ð…£"]={ "ð…Ÿ","ð…±" },
+ ["ð…¤"]={ "ð…Ÿ","ð…²" },
+ ["ð†»"]={ "ð†¹","ð…¥" },
+ ["ð†¼"]={ "ð†º","ð…¥" },
+ ["ð†½"]={ "ð†»","ð…®" },
+ ["ð†¾"]={ "ð†¼","ð…®" },
+ ["ð†¿"]={ "ð†»","ð…¯" },
+ ["ð‡€"]={ "ð†¼","ð…¯" },
+ },
+ },
+ {
+ ["data"]={
+ ["À"]={ "A","̀" },
+ ["Ã"]={ "A","Ì" },
+ ["Â"]={ "A","̂" },
+ ["Ã"]={ "A","̃" },
+ ["Ä"]={ "A","̈" },
+ ["Ã…"]={ "A","ÌŠ" },
+ ["Ç"]={ "C","̧" },
+ ["È"]={ "E","̀" },
+ ["É"]={ "E","Ì" },
+ ["Ê"]={ "E","̂" },
+ ["Ë"]={ "E","̈" },
+ ["Ì"]={ "I","̀" },
+ ["Ã"]={ "I","Ì" },
+ ["ÃŽ"]={ "I","Ì‚" },
+ ["Ã"]={ "I","̈" },
+ ["Ñ"]={ "N","̃" },
+ ["Ã’"]={ "O","Ì€" },
+ ["Ó"]={ "O","Ì" },
+ ["Ô"]={ "O","̂" },
+ ["Õ"]={ "O","̃" },
+ ["Ö"]={ "O","̈" },
+ ["Ù"]={ "U","̀" },
+ ["Ú"]={ "U","Ì" },
+ ["Û"]={ "U","̂" },
+ ["Ü"]={ "U","̈" },
+ ["Ã"]={ "Y","Ì" },
+ ["à"]={ "a","̀" },
+ ["á"]={ "a","Ì" },
+ ["â"]={ "a","̂" },
+ ["ã"]={ "a","̃" },
+ ["ä"]={ "a","̈" },
+ ["Ã¥"]={ "a","ÌŠ" },
+ ["ç"]={ "c","̧" },
+ ["è"]={ "e","̀" },
+ ["é"]={ "e","Ì" },
+ ["ê"]={ "e","̂" },
+ ["ë"]={ "e","̈" },
+ ["ì"]={ "i","̀" },
+ ["í"]={ "i","Ì" },
+ ["î"]={ "i","̂" },
+ ["ï"]={ "i","̈" },
+ ["ñ"]={ "n","̃" },
+ ["ò"]={ "o","̀" },
+ ["ó"]={ "o","Ì" },
+ ["ô"]={ "o","̂" },
+ ["õ"]={ "o","̃" },
+ ["ö"]={ "o","̈" },
+ ["ù"]={ "u","̀" },
+ ["ú"]={ "u","Ì" },
+ ["û"]={ "u","̂" },
+ ["ü"]={ "u","̈" },
+ ["ý"]={ "y","Ì" },
+ ["ÿ"]={ "y","̈" },
+ ["Ä€"]={ "A","Ì„" },
+ ["Ä"]={ "a","Ì„" },
+ ["Ă"]={ "A","̆" },
+ ["ă"]={ "a","̆" },
+ ["Ą"]={ "A","̨" },
+ ["ą"]={ "a","̨" },
+ ["Ć"]={ "C","Ì" },
+ ["ć"]={ "c","Ì" },
+ ["Ĉ"]={ "C","̂" },
+ ["ĉ"]={ "c","̂" },
+ ["Ċ"]={ "C","̇" },
+ ["ċ"]={ "c","̇" },
+ ["Č"]={ "C","̌" },
+ ["Ä"]={ "c","ÌŒ" },
+ ["Ď"]={ "D","̌" },
+ ["Ä"]={ "d","ÌŒ" },
+ ["Ä’"]={ "E","Ì„" },
+ ["Ä“"]={ "e","Ì„" },
+ ["Ĕ"]={ "E","̆" },
+ ["ĕ"]={ "e","̆" },
+ ["Ė"]={ "E","̇" },
+ ["ė"]={ "e","̇" },
+ ["Ę"]={ "E","̨" },
+ ["ę"]={ "e","̨" },
+ ["Ě"]={ "E","̌" },
+ ["ě"]={ "e","̌" },
+ ["Ĝ"]={ "G","̂" },
+ ["Ä"]={ "g","Ì‚" },
+ ["Ğ"]={ "G","̆" },
+ ["ğ"]={ "g","̆" },
+ ["Ġ"]={ "G","̇" },
+ ["ġ"]={ "g","̇" },
+ ["Ģ"]={ "G","̧" },
+ ["ģ"]={ "g","̧" },
+ ["Ĥ"]={ "H","̂" },
+ ["Ä¥"]={ "h","Ì‚" },
+ ["Ĩ"]={ "I","̃" },
+ ["ĩ"]={ "i","̃" },
+ ["Ī"]={ "I","̄" },
+ ["Ä«"]={ "i","Ì„" },
+ ["Ĭ"]={ "I","̆" },
+ ["ĭ"]={ "i","̆" },
+ ["Į"]={ "I","̨" },
+ ["į"]={ "i","̨" },
+ ["İ"]={ "I","̇" },
+ ["Ä´"]={ "J","Ì‚" },
+ ["ĵ"]={ "j","̂" },
+ ["Ķ"]={ "K","̧" },
+ ["ķ"]={ "k","̧" },
+ ["Ĺ"]={ "L","Ì" },
+ ["ĺ"]={ "l","Ì" },
+ ["Ļ"]={ "L","̧" },
+ ["ļ"]={ "l","̧" },
+ ["Ľ"]={ "L","̌" },
+ ["ľ"]={ "l","̌" },
+ ["Ń"]={ "N","Ì" },
+ ["Å„"]={ "n","Ì" },
+ ["Ņ"]={ "N","̧" },
+ ["ņ"]={ "n","̧" },
+ ["Ň"]={ "N","̌" },
+ ["ň"]={ "n","̌" },
+ ["Ō"]={ "O","̄" },
+ ["Å"]={ "o","Ì„" },
+ ["Ŏ"]={ "O","̆" },
+ ["Å"]={ "o","̆" },
+ ["Å"]={ "O","Ì‹" },
+ ["Å‘"]={ "o","Ì‹" },
+ ["Å”"]={ "R","Ì" },
+ ["Å•"]={ "r","Ì" },
+ ["Ŗ"]={ "R","̧" },
+ ["ŗ"]={ "r","̧" },
+ ["Ř"]={ "R","̌" },
+ ["ř"]={ "r","̌" },
+ ["Åš"]={ "S","Ì" },
+ ["Å›"]={ "s","Ì" },
+ ["Ŝ"]={ "S","̂" },
+ ["Å"]={ "s","Ì‚" },
+ ["Ş"]={ "S","̧" },
+ ["ş"]={ "s","̧" },
+ ["Š"]={ "S","̌" },
+ ["š"]={ "s","̌" },
+ ["Ţ"]={ "T","̧" },
+ ["ţ"]={ "t","̧" },
+ ["Ť"]={ "T","̌" },
+ ["ť"]={ "t","̌" },
+ ["Ũ"]={ "U","̃" },
+ ["ũ"]={ "u","̃" },
+ ["Ū"]={ "U","̄" },
+ ["Å«"]={ "u","Ì„" },
+ ["Ŭ"]={ "U","̆" },
+ ["ŭ"]={ "u","̆" },
+ ["Å®"]={ "U","ÌŠ" },
+ ["ů"]={ "u","̊" },
+ ["Å°"]={ "U","Ì‹" },
+ ["ű"]={ "u","̋" },
+ ["Ų"]={ "U","̨" },
+ ["ų"]={ "u","̨" },
+ ["Å´"]={ "W","Ì‚" },
+ ["ŵ"]={ "w","̂" },
+ ["Ŷ"]={ "Y","̂" },
+ ["Å·"]={ "y","Ì‚" },
+ ["Ÿ"]={ "Y","̈" },
+ ["Ź"]={ "Z","Ì" },
+ ["ź"]={ "z","Ì" },
+ ["Ż"]={ "Z","̇" },
+ ["ż"]={ "z","̇" },
+ ["Ž"]={ "Z","̌" },
+ ["ž"]={ "z","̌" },
+ ["Æ "]={ "O","Ì›" },
+ ["Æ¡"]={ "o","Ì›" },
+ ["Ư"]={ "U","̛" },
+ ["Æ°"]={ "u","Ì›" },
+ ["Ç"]={ "A","ÌŒ" },
+ ["ǎ"]={ "a","̌" },
+ ["Ç"]={ "I","ÌŒ" },
+ ["Ç"]={ "i","ÌŒ" },
+ ["Ǒ"]={ "O","̌" },
+ ["ǒ"]={ "o","̌" },
+ ["Ǔ"]={ "U","̌" },
+ ["ǔ"]={ "u","̌" },
+ ["Ǖ"]={ "Ü","̄" },
+ ["ǖ"]={ "ü","̄" },
+ ["Ç—"]={ "Ãœ","Ì" },
+ ["ǘ"]={ "ü","Ì" },
+ ["Ǚ"]={ "Ü","̌" },
+ ["ǚ"]={ "ü","̌" },
+ ["Ǜ"]={ "Ü","̀" },
+ ["ǜ"]={ "ü","̀" },
+ ["Ǟ"]={ "Ä","̄" },
+ ["ǟ"]={ "ä","̄" },
+ ["Ǡ"]={ "Ȧ","̄" },
+ ["ǡ"]={ "ȧ","̄" },
+ ["Ǣ"]={ "Æ","̄" },
+ ["ǣ"]={ "æ","̄" },
+ ["Ǧ"]={ "G","̌" },
+ ["ǧ"]={ "g","̌" },
+ ["Ǩ"]={ "K","̌" },
+ ["ǩ"]={ "k","̌" },
+ ["Ǫ"]={ "O","̨" },
+ ["ǫ"]={ "o","̨" },
+ ["Ǭ"]={ "Ǫ","̄" },
+ ["Ç­"]={ "Ç«","Ì„" },
+ ["Ǯ"]={ "Ʒ","̌" },
+ ["ǯ"]={ "ʒ","̌" },
+ ["ǰ"]={ "j","̌" },
+ ["Ç´"]={ "G","Ì" },
+ ["ǵ"]={ "g","Ì" },
+ ["Ǹ"]={ "N","̀" },
+ ["ǹ"]={ "n","̀" },
+ ["Ǻ"]={ "Ã…","Ì" },
+ ["Ç»"]={ "Ã¥","Ì" },
+ ["Ǽ"]={ "Æ","Ì" },
+ ["ǽ"]={ "æ","Ì" },
+ ["Ǿ"]={ "Ø","Ì" },
+ ["Ç¿"]={ "ø","Ì" },
+ ["È€"]={ "A","Ì" },
+ ["È"]={ "a","Ì" },
+ ["È‚"]={ "A","Ì‘" },
+ ["ȃ"]={ "a","̑" },
+ ["È„"]={ "E","Ì" },
+ ["È…"]={ "e","Ì" },
+ ["Ȇ"]={ "E","̑" },
+ ["ȇ"]={ "e","̑" },
+ ["Ȉ"]={ "I","Ì" },
+ ["ȉ"]={ "i","Ì" },
+ ["ÈŠ"]={ "I","Ì‘" },
+ ["È‹"]={ "i","Ì‘" },
+ ["ÈŒ"]={ "O","Ì" },
+ ["È"]={ "o","Ì" },
+ ["ÈŽ"]={ "O","Ì‘" },
+ ["È"]={ "o","Ì‘" },
+ ["È"]={ "R","Ì" },
+ ["È‘"]={ "r","Ì" },
+ ["È’"]={ "R","Ì‘" },
+ ["È“"]={ "r","Ì‘" },
+ ["È”"]={ "U","Ì" },
+ ["È•"]={ "u","Ì" },
+ ["È–"]={ "U","Ì‘" },
+ ["È—"]={ "u","Ì‘" },
+ ["Ș"]={ "S","̦" },
+ ["ș"]={ "s","̦" },
+ ["Ț"]={ "T","̦" },
+ ["ț"]={ "t","̦" },
+ ["Ȟ"]={ "H","̌" },
+ ["ȟ"]={ "h","̌" },
+ ["Ȧ"]={ "A","̇" },
+ ["ȧ"]={ "a","̇" },
+ ["Ȩ"]={ "E","̧" },
+ ["ȩ"]={ "e","̧" },
+ ["Ȫ"]={ "Ö","̄" },
+ ["ȫ"]={ "ö","̄" },
+ ["Ȭ"]={ "Õ","̄" },
+ ["ȭ"]={ "õ","̄" },
+ ["Ȯ"]={ "O","̇" },
+ ["ȯ"]={ "o","̇" },
+ ["È°"]={ "È®","Ì„" },
+ ["ȱ"]={ "ȯ","̄" },
+ ["Ȳ"]={ "Y","̄" },
+ ["ȳ"]={ "y","̄" },
+ ["Í„"]={ "̈","Ì" },
+ ["Î…"]={ "¨","Ì" },
+ ["Ά"]={ "Α","Ì" },
+ ["Έ"]={ "Ε","Ì" },
+ ["Ή"]={ "Η","Ì" },
+ ["Ί"]={ "Ι","Ì" },
+ ["ÎŒ"]={ "Ο","Ì" },
+ ["ÎŽ"]={ "Î¥","Ì" },
+ ["Î"]={ "Ω","Ì" },
+ ["Î"]={ "ÏŠ","Ì" },
+ ["Ϊ"]={ "Ι","̈" },
+ ["Ϋ"]={ "Υ","̈" },
+ ["ά"]={ "α","Ì" },
+ ["έ"]={ "ε","Ì" },
+ ["ή"]={ "η","Ì" },
+ ["ί"]={ "ι","Ì" },
+ ["ΰ"]={ "Ï‹","Ì" },
+ ["ϊ"]={ "ι","̈" },
+ ["ϋ"]={ "υ","̈" },
+ ["ÏŒ"]={ "ο","Ì" },
+ ["Ï"]={ "Ï…","Ì" },
+ ["ÏŽ"]={ "ω","Ì" },
+ ["Ï“"]={ "Ï’","Ì" },
+ ["ϔ"]={ "ϒ","̈" },
+ ["Ѐ"]={ "Е","̀" },
+ ["Ð"]={ "Е","̈" },
+ ["Ѓ"]={ "Г","Ì" },
+ ["Ї"]={ "І","̈" },
+ ["ÐŒ"]={ "К","Ì" },
+ ["Ð"]={ "И","Ì€" },
+ ["Ў"]={ "У","̆" },
+ ["Й"]={ "И","̆" },
+ ["й"]={ "и","̆" },
+ ["Ñ"]={ "е","Ì€" },
+ ["ё"]={ "е","̈" },
+ ["Ñ“"]={ "г","Ì" },
+ ["ї"]={ "і","̈" },
+ ["Ñœ"]={ "к","Ì" },
+ ["Ñ"]={ "и","Ì€" },
+ ["ў"]={ "у","̆" },
+ ["Ѷ"]={ "Ñ´","Ì" },
+ ["Ñ·"]={ "ѵ","Ì" },
+ ["Ó"]={ "Ж","̆" },
+ ["ӂ"]={ "ж","̆" },
+ ["Ó"]={ "Ð","̆" },
+ ["ӑ"]={ "а","̆" },
+ ["Ó’"]={ "Ð","̈" },
+ ["ӓ"]={ "а","̈" },
+ ["Ӗ"]={ "Е","̆" },
+ ["ӗ"]={ "е","̆" },
+ ["Ӛ"]={ "Ә","̈" },
+ ["ӛ"]={ "ә","̈" },
+ ["Ӝ"]={ "Ж","̈" },
+ ["Ó"]={ "ж","̈" },
+ ["Ӟ"]={ "З","̈" },
+ ["ӟ"]={ "з","̈" },
+ ["Ӣ"]={ "И","̄" },
+ ["ӣ"]={ "и","̄" },
+ ["Ӥ"]={ "И","̈" },
+ ["ӥ"]={ "и","̈" },
+ ["Ӧ"]={ "О","̈" },
+ ["ӧ"]={ "о","̈" },
+ ["Ӫ"]={ "Ө","̈" },
+ ["ӫ"]={ "ө","̈" },
+ ["Ӭ"]={ "Э","̈" },
+ ["Ó­"]={ "Ñ","̈" },
+ ["Ӯ"]={ "У","̄" },
+ ["ӯ"]={ "у","̄" },
+ ["Ӱ"]={ "У","̈" },
+ ["ӱ"]={ "у","̈" },
+ ["Ӳ"]={ "У","̋" },
+ ["ӳ"]={ "у","̋" },
+ ["Ӵ"]={ "Ч","̈" },
+ ["ӵ"]={ "ч","̈" },
+ ["Ӹ"]={ "Ы","̈" },
+ ["ӹ"]={ "ы","̈" },
+ ["آ"]={ "ا","ٓ" },
+ ["أ"]={ "ا","ٔ" },
+ ["ؤ"]={ "و","ٔ" },
+ ["إ"]={ "ا","ٕ" },
+ ["ئ"]={ "ي","ٔ" },
+ ["Û€"]={ "Û•","Ù”" },
+ ["Û‚"]={ "Û","Ù”" },
+ ["Û“"]={ "Û’","Ù”" },
+ ["ऩ"]={ "न","़" },
+ ["ऱ"]={ "र","़" },
+ ["ऴ"]={ "ळ","़" },
+ ["क़"]={ "क","़" },
+ ["ख़"]={ "ख","़" },
+ ["ग़"]={ "ग","़" },
+ ["ज़"]={ "ज","़" },
+ ["ड़"]={ "ड","़" },
+ ["à¥"]={ "ढ","़" },
+ ["फ़"]={ "फ","़" },
+ ["य़"]={ "य","़" },
+ ["ো"]={ "ে","া" },
+ ["ৌ"]={ "ে","ৗ" },
+ ["ড়"]={ "ড","়" },
+ ["à§"]={ "ঢ","়" },
+ ["য়"]={ "য","়" },
+ ["ਲ਼"]={ "ਲ","਼" },
+ ["ਸ਼"]={ "ਸ","਼" },
+ ["ਖ਼"]={ "ਖ","਼" },
+ ["ਗ਼"]={ "ਗ","਼" },
+ ["ਜ਼"]={ "ਜ","਼" },
+ ["ਫ਼"]={ "ਫ","਼" },
+ ["à­ˆ"]={ "à­‡","à­–" },
+ ["ୋ"]={ "େ","ା" },
+ ["ୌ"]={ "େ","ୗ" },
+ ["ଡ଼"]={ "ଡ","଼" },
+ ["à­"]={ "ଢ","଼" },
+ ["ஔ"]={ "ஒ","ௗ" },
+ ["ொ"]={ "ெ","ா" },
+ ["ோ"]={ "ே","ா" },
+ ["ௌ"]={ "ெ","ௗ" },
+ ["ై"]={ "ె","ౖ" },
+ ["ೀ"]={ "ಿ","ೕ" },
+ ["ೇ"]={ "ೆ","ೕ" },
+ ["ೈ"]={ "ೆ","ೖ" },
+ ["ೊ"]={ "ೆ","ೂ" },
+ ["ೋ"]={ "ೊ","ೕ" },
+ ["ൊ"]={ "െ","ാ" },
+ ["ോ"]={ "േ","ാ" },
+ ["ൌ"]={ "െ","ൗ" },
+ ["à·š"]={ "à·™","à·Š" },
+ ["à·œ"]={ "à·™","à·" },
+ ["à·"]={ "à·œ","à·Š" },
+ ["à·ž"]={ "à·™","à·Ÿ" },
+ ["གྷ"]={ "ག","ྷ" },
+ ["à½"]={ "ཌ","ྷ" },
+ ["དྷ"]={ "ད","ྷ" },
+ ["བྷ"]={ "བ","ྷ" },
+ ["ཛྷ"]={ "ཛ","ྷ" },
+ ["ཀྵ"]={ "ཀ","ྵ" },
+ ["ཱི"]={ "ཱ","ི" },
+ ["ཱུ"]={ "ཱ","ུ" },
+ ["ྲྀ"]={ "ྲ","ྀ" },
+ ["ླྀ"]={ "ླ","ྀ" },
+ ["à¾"]={ "ཱ","ྀ" },
+ ["ྒྷ"]={ "ྒ","ྷ" },
+ ["à¾"]={ "ྜ","ྷ" },
+ ["ྡྷ"]={ "ྡ","ྷ" },
+ ["ྦྷ"]={ "ྦ","ྷ" },
+ ["ྫྷ"]={ "ྫ","ྷ" },
+ ["ྐྵ"]={ "à¾","ྵ" },
+ ["ဦ"]={ "ဥ","ီ" },
+ ["ᬆ"]={ "ᬅ","ᬵ" },
+ ["ᬈ"]={ "ᬇ","ᬵ" },
+ ["ᬊ"]={ "ᬉ","ᬵ" },
+ ["ᬌ"]={ "ᬋ","ᬵ" },
+ ["ᬎ"]={ "á¬","ᬵ" },
+ ["ᬒ"]={ "ᬑ","ᬵ" },
+ ["ᬻ"]={ "ᬺ","ᬵ" },
+ ["ᬽ"]={ "ᬼ","ᬵ" },
+ ["ᭀ"]={ "ᬾ","ᬵ" },
+ ["á­"]={ "ᬿ","ᬵ" },
+ ["ᭃ"]={ "ᭂ","ᬵ" },
+ ["Ḁ"]={ "A","̥" },
+ ["á¸"]={ "a","Ì¥" },
+ ["Ḃ"]={ "B","̇" },
+ ["ḃ"]={ "b","̇" },
+ ["Ḅ"]={ "B","̣" },
+ ["ḅ"]={ "b","̣" },
+ ["Ḇ"]={ "B","̱" },
+ ["ḇ"]={ "b","̱" },
+ ["Ḉ"]={ "Ç","Ì" },
+ ["ḉ"]={ "ç","Ì" },
+ ["Ḋ"]={ "D","̇" },
+ ["ḋ"]={ "d","̇" },
+ ["Ḍ"]={ "D","̣" },
+ ["á¸"]={ "d","Ì£" },
+ ["Ḏ"]={ "D","̱" },
+ ["á¸"]={ "d","̱" },
+ ["á¸"]={ "D","̧" },
+ ["ḑ"]={ "d","̧" },
+ ["Ḓ"]={ "D","̭" },
+ ["ḓ"]={ "d","̭" },
+ ["Ḕ"]={ "Ē","̀" },
+ ["ḕ"]={ "ē","̀" },
+ ["Ḗ"]={ "Ä’","Ì" },
+ ["ḗ"]={ "Ä“","Ì" },
+ ["Ḙ"]={ "E","̭" },
+ ["ḙ"]={ "e","̭" },
+ ["Ḛ"]={ "E","̰" },
+ ["ḛ"]={ "e","̰" },
+ ["Ḝ"]={ "Ȩ","̆" },
+ ["á¸"]={ "È©","̆" },
+ ["Ḟ"]={ "F","̇" },
+ ["ḟ"]={ "f","̇" },
+ ["Ḡ"]={ "G","̄" },
+ ["ḡ"]={ "g","̄" },
+ ["Ḣ"]={ "H","̇" },
+ ["ḣ"]={ "h","̇" },
+ ["Ḥ"]={ "H","̣" },
+ ["ḥ"]={ "h","̣" },
+ ["Ḧ"]={ "H","̈" },
+ ["ḧ"]={ "h","̈" },
+ ["Ḩ"]={ "H","̧" },
+ ["ḩ"]={ "h","̧" },
+ ["Ḫ"]={ "H","̮" },
+ ["ḫ"]={ "h","̮" },
+ ["Ḭ"]={ "I","̰" },
+ ["ḭ"]={ "i","̰" },
+ ["Ḯ"]={ "Ã","Ì" },
+ ["ḯ"]={ "ï","Ì" },
+ ["Ḱ"]={ "K","Ì" },
+ ["ḱ"]={ "k","Ì" },
+ ["Ḳ"]={ "K","̣" },
+ ["ḳ"]={ "k","̣" },
+ ["Ḵ"]={ "K","̱" },
+ ["ḵ"]={ "k","̱" },
+ ["Ḷ"]={ "L","̣" },
+ ["ḷ"]={ "l","̣" },
+ ["Ḹ"]={ "Ḷ","̄" },
+ ["ḹ"]={ "ḷ","̄" },
+ ["Ḻ"]={ "L","̱" },
+ ["ḻ"]={ "l","̱" },
+ ["Ḽ"]={ "L","̭" },
+ ["ḽ"]={ "l","̭" },
+ ["Ḿ"]={ "M","Ì" },
+ ["ḿ"]={ "m","Ì" },
+ ["Ṁ"]={ "M","̇" },
+ ["á¹"]={ "m","̇" },
+ ["Ṃ"]={ "M","̣" },
+ ["ṃ"]={ "m","̣" },
+ ["Ṅ"]={ "N","̇" },
+ ["ṅ"]={ "n","̇" },
+ ["Ṇ"]={ "N","̣" },
+ ["ṇ"]={ "n","̣" },
+ ["Ṉ"]={ "N","̱" },
+ ["ṉ"]={ "n","̱" },
+ ["Ṋ"]={ "N","̭" },
+ ["ṋ"]={ "n","̭" },
+ ["Ṍ"]={ "Õ","Ì" },
+ ["á¹"]={ "õ","Ì" },
+ ["Ṏ"]={ "Õ","̈" },
+ ["á¹"]={ "õ","̈" },
+ ["á¹"]={ "ÅŒ","Ì€" },
+ ["ṑ"]={ "Å","Ì€" },
+ ["á¹’"]={ "ÅŒ","Ì" },
+ ["ṓ"]={ "Å","Ì" },
+ ["á¹”"]={ "P","Ì" },
+ ["ṕ"]={ "p","Ì" },
+ ["Ṗ"]={ "P","̇" },
+ ["ṗ"]={ "p","̇" },
+ ["Ṙ"]={ "R","̇" },
+ ["ṙ"]={ "r","̇" },
+ ["Ṛ"]={ "R","̣" },
+ ["á¹›"]={ "r","Ì£" },
+ ["Ṝ"]={ "Ṛ","̄" },
+ ["á¹"]={ "á¹›","Ì„" },
+ ["Ṟ"]={ "R","̱" },
+ ["ṟ"]={ "r","̱" },
+ ["Ṡ"]={ "S","̇" },
+ ["ṡ"]={ "s","̇" },
+ ["á¹¢"]={ "S","Ì£" },
+ ["á¹£"]={ "s","Ì£" },
+ ["Ṥ"]={ "Ś","̇" },
+ ["ṥ"]={ "ś","̇" },
+ ["Ṧ"]={ "Š","̇" },
+ ["ṧ"]={ "š","̇" },
+ ["Ṩ"]={ "Ṣ","̇" },
+ ["ṩ"]={ "ṣ","̇" },
+ ["Ṫ"]={ "T","̇" },
+ ["ṫ"]={ "t","̇" },
+ ["Ṭ"]={ "T","̣" },
+ ["á¹­"]={ "t","Ì£" },
+ ["Ṯ"]={ "T","̱" },
+ ["ṯ"]={ "t","̱" },
+ ["á¹°"]={ "T","Ì­" },
+ ["á¹±"]={ "t","Ì­" },
+ ["Ṳ"]={ "U","̤" },
+ ["ṳ"]={ "u","̤" },
+ ["á¹´"]={ "U","Ì°" },
+ ["á¹µ"]={ "u","Ì°" },
+ ["Ṷ"]={ "U","̭" },
+ ["á¹·"]={ "u","Ì­" },
+ ["Ṹ"]={ "Ũ","Ì" },
+ ["á¹¹"]={ "Å©","Ì" },
+ ["Ṻ"]={ "Ū","̈" },
+ ["ṻ"]={ "ū","̈" },
+ ["Ṽ"]={ "V","̃" },
+ ["ṽ"]={ "v","̃" },
+ ["á¹¾"]={ "V","Ì£" },
+ ["ṿ"]={ "v","̣" },
+ ["Ẁ"]={ "W","̀" },
+ ["áº"]={ "w","Ì€" },
+ ["Ẃ"]={ "W","Ì" },
+ ["ẃ"]={ "w","Ì" },
+ ["Ẅ"]={ "W","̈" },
+ ["ẅ"]={ "w","̈" },
+ ["Ẇ"]={ "W","̇" },
+ ["ẇ"]={ "w","̇" },
+ ["Ẉ"]={ "W","̣" },
+ ["ẉ"]={ "w","̣" },
+ ["Ẋ"]={ "X","̇" },
+ ["ẋ"]={ "x","̇" },
+ ["Ẍ"]={ "X","̈" },
+ ["áº"]={ "x","̈" },
+ ["Ẏ"]={ "Y","̇" },
+ ["áº"]={ "y","̇" },
+ ["áº"]={ "Z","Ì‚" },
+ ["ẑ"]={ "z","̂" },
+ ["Ẓ"]={ "Z","̣" },
+ ["ẓ"]={ "z","̣" },
+ ["Ẕ"]={ "Z","̱" },
+ ["ẕ"]={ "z","̱" },
+ ["ẖ"]={ "h","̱" },
+ ["ẗ"]={ "t","̈" },
+ ["ẘ"]={ "w","̊" },
+ ["ẙ"]={ "y","̊" },
+ ["ẛ"]={ "ſ","̇" },
+ ["Ạ"]={ "A","̣" },
+ ["ạ"]={ "a","̣" },
+ ["Ả"]={ "A","̉" },
+ ["ả"]={ "a","̉" },
+ ["Ấ"]={ "Â","Ì" },
+ ["ấ"]={ "â","Ì" },
+ ["Ầ"]={ "Â","̀" },
+ ["ầ"]={ "â","̀" },
+ ["Ẩ"]={ "Â","̉" },
+ ["ẩ"]={ "â","̉" },
+ ["Ẫ"]={ "Â","̃" },
+ ["ẫ"]={ "â","̃" },
+ ["Ậ"]={ "Ạ","̂" },
+ ["ậ"]={ "ạ","̂" },
+ ["Ắ"]={ "Ä‚","Ì" },
+ ["ắ"]={ "ă","Ì" },
+ ["Ằ"]={ "Ă","̀" },
+ ["ằ"]={ "ă","̀" },
+ ["Ẳ"]={ "Ă","̉" },
+ ["ẳ"]={ "ă","̉" },
+ ["Ẵ"]={ "Ă","̃" },
+ ["ẵ"]={ "ă","̃" },
+ ["Ặ"]={ "Ạ","̆" },
+ ["ặ"]={ "ạ","̆" },
+ ["Ẹ"]={ "E","̣" },
+ ["ẹ"]={ "e","̣" },
+ ["Ẻ"]={ "E","̉" },
+ ["ẻ"]={ "e","̉" },
+ ["Ẽ"]={ "E","̃" },
+ ["ẽ"]={ "e","̃" },
+ ["Ế"]={ "Ê","Ì" },
+ ["ế"]={ "ê","Ì" },
+ ["Ề"]={ "Ê","̀" },
+ ["á»"]={ "ê","Ì€" },
+ ["Ể"]={ "Ê","̉" },
+ ["ể"]={ "ê","̉" },
+ ["Ễ"]={ "Ê","̃" },
+ ["ễ"]={ "ê","̃" },
+ ["Ệ"]={ "Ẹ","̂" },
+ ["ệ"]={ "ẹ","̂" },
+ ["Ỉ"]={ "I","̉" },
+ ["ỉ"]={ "i","̉" },
+ ["Ị"]={ "I","̣" },
+ ["ị"]={ "i","̣" },
+ ["Ọ"]={ "O","̣" },
+ ["á»"]={ "o","Ì£" },
+ ["Ỏ"]={ "O","̉" },
+ ["á»"]={ "o","̉" },
+ ["á»"]={ "Ô","Ì" },
+ ["ố"]={ "ô","Ì" },
+ ["Ồ"]={ "Ô","̀" },
+ ["ồ"]={ "ô","̀" },
+ ["Ổ"]={ "Ô","̉" },
+ ["ổ"]={ "ô","̉" },
+ ["Ỗ"]={ "Ô","̃" },
+ ["ỗ"]={ "ô","̃" },
+ ["Ộ"]={ "Ọ","̂" },
+ ["á»™"]={ "á»","Ì‚" },
+ ["Ớ"]={ "Æ ","Ì" },
+ ["á»›"]={ "Æ¡","Ì" },
+ ["Ờ"]={ "Ơ","̀" },
+ ["á»"]={ "Æ¡","Ì€" },
+ ["Ở"]={ "Ơ","̉" },
+ ["ở"]={ "ơ","̉" },
+ ["Ỡ"]={ "Ơ","̃" },
+ ["ỡ"]={ "ơ","̃" },
+ ["Ợ"]={ "Ơ","̣" },
+ ["ợ"]={ "ơ","̣" },
+ ["Ụ"]={ "U","̣" },
+ ["ụ"]={ "u","̣" },
+ ["Ủ"]={ "U","̉" },
+ ["ủ"]={ "u","̉" },
+ ["Ứ"]={ "Ư","Ì" },
+ ["ứ"]={ "Æ°","Ì" },
+ ["Ừ"]={ "Ư","̀" },
+ ["ừ"]={ "ư","̀" },
+ ["Ử"]={ "Ư","̉" },
+ ["ử"]={ "ư","̉" },
+ ["Ữ"]={ "Ư","̃" },
+ ["ữ"]={ "ư","̃" },
+ ["Ự"]={ "Ư","̣" },
+ ["á»±"]={ "Æ°","Ì£" },
+ ["Ỳ"]={ "Y","̀" },
+ ["ỳ"]={ "y","̀" },
+ ["á»´"]={ "Y","Ì£" },
+ ["ỵ"]={ "y","̣" },
+ ["Ỷ"]={ "Y","̉" },
+ ["ỷ"]={ "y","̉" },
+ ["Ỹ"]={ "Y","̃" },
+ ["ỹ"]={ "y","̃" },
+ ["ἀ"]={ "α","̓" },
+ ["á¼"]={ "α","Ì”" },
+ ["ἂ"]={ "ἀ","̀" },
+ ["ἃ"]={ "á¼","Ì€" },
+ ["ἄ"]={ "á¼€","Ì" },
+ ["á¼…"]={ "á¼","Ì" },
+ ["ἆ"]={ "ἀ","͂" },
+ ["ἇ"]={ "á¼","Í‚" },
+ ["Ἀ"]={ "Α","̓" },
+ ["Ἁ"]={ "Α","̔" },
+ ["Ἂ"]={ "Ἀ","̀" },
+ ["Ἃ"]={ "Ἁ","̀" },
+ ["Ἄ"]={ "Ἀ","Ì" },
+ ["á¼"]={ "Ἁ","Ì" },
+ ["Ἆ"]={ "Ἀ","͂" },
+ ["á¼"]={ "Ἁ","Í‚" },
+ ["á¼"]={ "ε","Ì“" },
+ ["ἑ"]={ "ε","̔" },
+ ["á¼’"]={ "á¼","Ì€" },
+ ["ἓ"]={ "ἑ","̀" },
+ ["á¼”"]={ "á¼","Ì" },
+ ["ἕ"]={ "ἑ","Ì" },
+ ["Ἐ"]={ "Ε","̓" },
+ ["Ἑ"]={ "Ε","̔" },
+ ["Ἒ"]={ "Ἐ","̀" },
+ ["á¼›"]={ "á¼™","Ì€" },
+ ["Ἔ"]={ "Ἐ","Ì" },
+ ["á¼"]={ "á¼™","Ì" },
+ ["ἠ"]={ "η","̓" },
+ ["ἡ"]={ "η","̔" },
+ ["á¼¢"]={ "á¼ ","Ì€" },
+ ["ἣ"]={ "ἡ","̀" },
+ ["ἤ"]={ "á¼ ","Ì" },
+ ["á¼¥"]={ "ἡ","Ì" },
+ ["ἦ"]={ "ἠ","͂" },
+ ["ἧ"]={ "ἡ","͂" },
+ ["Ἠ"]={ "Η","̓" },
+ ["Ἡ"]={ "Η","̔" },
+ ["Ἢ"]={ "Ἠ","̀" },
+ ["Ἣ"]={ "Ἡ","̀" },
+ ["Ἤ"]={ "Ἠ","Ì" },
+ ["á¼­"]={ "Ἡ","Ì" },
+ ["Ἦ"]={ "Ἠ","͂" },
+ ["Ἧ"]={ "Ἡ","͂" },
+ ["ἰ"]={ "ι","̓" },
+ ["ἱ"]={ "ι","̔" },
+ ["á¼²"]={ "á¼°","Ì€" },
+ ["á¼³"]={ "á¼±","Ì€" },
+ ["á¼´"]={ "á¼°","Ì" },
+ ["á¼µ"]={ "á¼±","Ì" },
+ ["ἶ"]={ "ἰ","͂" },
+ ["á¼·"]={ "á¼±","Í‚" },
+ ["Ἰ"]={ "Ι","̓" },
+ ["Ἱ"]={ "Ι","̔" },
+ ["Ἲ"]={ "Ἰ","̀" },
+ ["á¼»"]={ "á¼¹","Ì€" },
+ ["á¼¼"]={ "Ἰ","Ì" },
+ ["á¼½"]={ "á¼¹","Ì" },
+ ["Ἶ"]={ "Ἰ","͂" },
+ ["Ἷ"]={ "Ἱ","͂" },
+ ["ὀ"]={ "ο","̓" },
+ ["á½"]={ "ο","Ì”" },
+ ["ὂ"]={ "ὀ","̀" },
+ ["ὃ"]={ "á½","Ì€" },
+ ["ὄ"]={ "á½€","Ì" },
+ ["á½…"]={ "á½","Ì" },
+ ["Ὀ"]={ "Ο","̓" },
+ ["Ὁ"]={ "Ο","̔" },
+ ["Ὂ"]={ "Ὀ","̀" },
+ ["Ὃ"]={ "Ὁ","̀" },
+ ["Ὄ"]={ "Ὀ","Ì" },
+ ["á½"]={ "Ὁ","Ì" },
+ ["á½"]={ "Ï…","Ì“" },
+ ["ὑ"]={ "υ","̔" },
+ ["á½’"]={ "á½","Ì€" },
+ ["ὓ"]={ "ὑ","̀" },
+ ["á½”"]={ "á½","Ì" },
+ ["ὕ"]={ "ὑ","Ì" },
+ ["á½–"]={ "á½","Í‚" },
+ ["ὗ"]={ "ὑ","͂" },
+ ["á½™"]={ "Î¥","Ì”" },
+ ["á½›"]={ "á½™","Ì€" },
+ ["á½"]={ "á½™","Ì" },
+ ["Ὗ"]={ "Ὑ","͂" },
+ ["ὠ"]={ "ω","̓" },
+ ["ὡ"]={ "ω","̔" },
+ ["á½¢"]={ "á½ ","Ì€" },
+ ["ὣ"]={ "ὡ","̀" },
+ ["ὤ"]={ "á½ ","Ì" },
+ ["á½¥"]={ "ὡ","Ì" },
+ ["ὦ"]={ "ὠ","͂" },
+ ["ὧ"]={ "ὡ","͂" },
+ ["Ὠ"]={ "Ω","̓" },
+ ["Ὡ"]={ "Ω","̔" },
+ ["Ὢ"]={ "Ὠ","̀" },
+ ["Ὣ"]={ "Ὡ","̀" },
+ ["Ὤ"]={ "Ὠ","Ì" },
+ ["á½­"]={ "Ὡ","Ì" },
+ ["Ὦ"]={ "Ὠ","͂" },
+ ["Ὧ"]={ "Ὡ","͂" },
+ ["ὰ"]={ "α","̀" },
+ ["ὲ"]={ "ε","̀" },
+ ["ὴ"]={ "η","̀" },
+ ["ὶ"]={ "ι","̀" },
+ ["ὸ"]={ "ο","̀" },
+ ["ὺ"]={ "υ","̀" },
+ ["ὼ"]={ "ω","̀" },
+ ["á¾€"]={ "á¼€","Í…" },
+ ["á¾"]={ "á¼","Í…" },
+ ["ᾂ"]={ "ἂ","ͅ" },
+ ["ᾃ"]={ "ἃ","ͅ" },
+ ["ᾄ"]={ "ἄ","ͅ" },
+ ["á¾…"]={ "á¼…","Í…" },
+ ["ᾆ"]={ "ἆ","ͅ" },
+ ["ᾇ"]={ "ἇ","ͅ" },
+ ["ᾈ"]={ "Ἀ","ͅ" },
+ ["ᾉ"]={ "Ἁ","ͅ" },
+ ["ᾊ"]={ "Ἂ","ͅ" },
+ ["ᾋ"]={ "Ἃ","ͅ" },
+ ["ᾌ"]={ "Ἄ","ͅ" },
+ ["á¾"]={ "á¼","Í…" },
+ ["ᾎ"]={ "Ἆ","ͅ" },
+ ["á¾"]={ "á¼","Í…" },
+ ["á¾"]={ "á¼ ","Í…" },
+ ["ᾑ"]={ "ἡ","ͅ" },
+ ["á¾’"]={ "á¼¢","Í…" },
+ ["ᾓ"]={ "ἣ","ͅ" },
+ ["ᾔ"]={ "ἤ","ͅ" },
+ ["ᾕ"]={ "ἥ","ͅ" },
+ ["ᾖ"]={ "ἦ","ͅ" },
+ ["ᾗ"]={ "ἧ","ͅ" },
+ ["ᾘ"]={ "Ἠ","ͅ" },
+ ["ᾙ"]={ "Ἡ","ͅ" },
+ ["ᾚ"]={ "Ἢ","ͅ" },
+ ["ᾛ"]={ "Ἣ","ͅ" },
+ ["ᾜ"]={ "Ἤ","ͅ" },
+ ["á¾"]={ "á¼­","Í…" },
+ ["ᾞ"]={ "Ἦ","ͅ" },
+ ["ᾟ"]={ "Ἧ","ͅ" },
+ ["á¾ "]={ "á½ ","Í…" },
+ ["ᾡ"]={ "ὡ","ͅ" },
+ ["á¾¢"]={ "á½¢","Í…" },
+ ["á¾£"]={ "á½£","Í…" },
+ ["ᾤ"]={ "ὤ","ͅ" },
+ ["á¾¥"]={ "á½¥","Í…" },
+ ["ᾦ"]={ "ὦ","ͅ" },
+ ["ᾧ"]={ "ὧ","ͅ" },
+ ["ᾨ"]={ "Ὠ","ͅ" },
+ ["ᾩ"]={ "Ὡ","ͅ" },
+ ["ᾪ"]={ "Ὢ","ͅ" },
+ ["ᾫ"]={ "Ὣ","ͅ" },
+ ["ᾬ"]={ "Ὤ","ͅ" },
+ ["á¾­"]={ "á½­","Í…" },
+ ["á¾®"]={ "á½®","Í…" },
+ ["ᾯ"]={ "Ὧ","ͅ" },
+ ["ᾰ"]={ "α","̆" },
+ ["ᾱ"]={ "α","̄" },
+ ["á¾²"]={ "á½°","Í…" },
+ ["ᾳ"]={ "α","ͅ" },
+ ["ᾴ"]={ "ά","ͅ" },
+ ["ᾶ"]={ "α","͂" },
+ ["ᾷ"]={ "ᾶ","ͅ" },
+ ["Ᾰ"]={ "Α","̆" },
+ ["Ᾱ"]={ "Α","̄" },
+ ["Ὰ"]={ "Α","̀" },
+ ["ᾼ"]={ "Α","ͅ" },
+ ["á¿"]={ "¨","Í‚" },
+ ["á¿‚"]={ "á½´","Í…" },
+ ["ῃ"]={ "η","ͅ" },
+ ["ῄ"]={ "ή","ͅ" },
+ ["ῆ"]={ "η","͂" },
+ ["ῇ"]={ "ῆ","ͅ" },
+ ["Ὲ"]={ "Ε","̀" },
+ ["Ὴ"]={ "Η","̀" },
+ ["ῌ"]={ "Η","ͅ" },
+ ["á¿"]={ "᾿","Ì€" },
+ ["á¿Ž"]={ "᾿","Ì" },
+ ["á¿"]={ "᾿","Í‚" },
+ ["á¿"]={ "ι","̆" },
+ ["ῑ"]={ "ι","̄" },
+ ["á¿’"]={ "ÏŠ","Ì€" },
+ ["ῖ"]={ "ι","͂" },
+ ["á¿—"]={ "ÏŠ","Í‚" },
+ ["Ῐ"]={ "Ι","̆" },
+ ["Ῑ"]={ "Ι","̄" },
+ ["Ὶ"]={ "Ι","̀" },
+ ["á¿"]={ "῾","Ì€" },
+ ["á¿ž"]={ "῾","Ì" },
+ ["῟"]={ "῾","͂" },
+ ["ῠ"]={ "υ","̆" },
+ ["á¿¡"]={ "Ï…","Ì„" },
+ ["á¿¢"]={ "Ï‹","Ì€" },
+ ["ῤ"]={ "Ï","Ì“" },
+ ["á¿¥"]={ "Ï","Ì”" },
+ ["ῦ"]={ "υ","͂" },
+ ["ῧ"]={ "ϋ","͂" },
+ ["Ῠ"]={ "Υ","̆" },
+ ["á¿©"]={ "Î¥","Ì„" },
+ ["Ὺ"]={ "Υ","̀" },
+ ["Ῥ"]={ "Ρ","̔" },
+ ["῭"]={ "¨","̀" },
+ ["ῲ"]={ "ὼ","ͅ" },
+ ["ῳ"]={ "ω","ͅ" },
+ ["á¿´"]={ "ÏŽ","Í…" },
+ ["ῶ"]={ "ω","͂" },
+ ["ῷ"]={ "ῶ","ͅ" },
+ ["Ὸ"]={ "Ο","̀" },
+ ["Ὼ"]={ "Ω","̀" },
+ ["ῼ"]={ "Ω","ͅ" },
+ ["↚"]={ "â†","̸" },
+ ["↛"]={ "→","̸" },
+ ["↮"]={ "↔","̸" },
+ ["â‡"]={ "â‡","̸" },
+ ["⇎"]={ "⇔","̸" },
+ ["â‡"]={ "⇒","̸" },
+ ["∄"]={ "∃","̸" },
+ ["∉"]={ "∈","̸" },
+ ["∌"]={ "∋","̸" },
+ ["∤"]={ "∣","̸" },
+ ["∦"]={ "∥","̸" },
+ ["â‰"]={ "∼","̸" },
+ ["≄"]={ "≃","̸" },
+ ["≇"]={ "≅","̸" },
+ ["≉"]={ "≈","̸" },
+ ["≠"]={ "=","̸" },
+ ["≢"]={ "≡","̸" },
+ ["≭"]={ "â‰","̸" },
+ ["≮"]={ "<","̸" },
+ ["≯"]={ ">","̸" },
+ ["≰"]={ "≤","̸" },
+ ["≱"]={ "≥","̸" },
+ ["≴"]={ "≲","̸" },
+ ["≵"]={ "≳","̸" },
+ ["≸"]={ "≶","̸" },
+ ["≹"]={ "≷","̸" },
+ ["⊀"]={ "≺","̸" },
+ ["âŠ"]={ "≻","̸" },
+ ["⊄"]={ "⊂","̸" },
+ ["⊅"]={ "⊃","̸" },
+ ["⊈"]={ "⊆","̸" },
+ ["⊉"]={ "⊇","̸" },
+ ["⊬"]={ "⊢","̸" },
+ ["⊭"]={ "⊨","̸" },
+ ["⊮"]={ "⊩","̸" },
+ ["⊯"]={ "⊫","̸" },
+ ["⋠"]={ "≼","̸" },
+ ["⋡"]={ "≽","̸" },
+ ["⋢"]={ "⊑","̸" },
+ ["⋣"]={ "⊒","̸" },
+ ["⋪"]={ "⊲","̸" },
+ ["⋫"]={ "⊳","̸" },
+ ["⋬"]={ "⊴","̸" },
+ ["⋭"]={ "⊵","̸" },
+ ["â«œ"]={ "â«","̸" },
+ ["ãŒ"]={ "ã‹","ã‚™" },
+ ["ãŽ"]={ "ã","ã‚™" },
+ ["ã"]={ "ã","ã‚™" },
+ ["ã’"]={ "ã‘","ã‚™" },
+ ["ã”"]={ "ã“","ã‚™" },
+ ["ã–"]={ "ã•","ã‚™" },
+ ["ã˜"]={ "ã—","ã‚™" },
+ ["ãš"]={ "ã™","ã‚™" },
+ ["ãœ"]={ "ã›","ã‚™" },
+ ["ãž"]={ "ã","ã‚™" },
+ ["ã "]={ "ãŸ","ã‚™" },
+ ["ã¢"]={ "ã¡","ã‚™" },
+ ["ã¥"]={ "ã¤","ã‚™" },
+ ["ã§"]={ "ã¦","ã‚™" },
+ ["ã©"]={ "ã¨","ã‚™" },
+ ["ã°"]={ "ã¯","ã‚™" },
+ ["ã±"]={ "ã¯","ã‚š" },
+ ["ã³"]={ "ã²","ã‚™" },
+ ["ã´"]={ "ã²","ã‚š" },
+ ["ã¶"]={ "ãµ","ã‚™" },
+ ["ã·"]={ "ãµ","ã‚š" },
+ ["ã¹"]={ "ã¸","ã‚™" },
+ ["ãº"]={ "ã¸","ã‚š" },
+ ["ã¼"]={ "ã»","ã‚™" },
+ ["ã½"]={ "ã»","ã‚š" },
+ ["ã‚”"]={ "ã†","ã‚™" },
+ ["ã‚ž"]={ "ã‚","ã‚™" },
+ ["ガ"]={ "カ","゙" },
+ ["ã‚®"]={ "ã‚­","ã‚™" },
+ ["グ"]={ "ク","゙" },
+ ["ゲ"]={ "ケ","゙" },
+ ["ゴ"]={ "コ","゙" },
+ ["ザ"]={ "サ","゙" },
+ ["ジ"]={ "シ","゙" },
+ ["ズ"]={ "ス","゙" },
+ ["ゼ"]={ "セ","゙" },
+ ["ゾ"]={ "ソ","゙" },
+ ["ダ"]={ "タ","゙" },
+ ["ヂ"]={ "ãƒ","ã‚™" },
+ ["ヅ"]={ "ツ","゙" },
+ ["デ"]={ "テ","゙" },
+ ["ド"]={ "ト","゙" },
+ ["ãƒ"]={ "ãƒ","ã‚™" },
+ ["パ"]={ "ãƒ","ã‚š" },
+ ["ビ"]={ "ヒ","゙" },
+ ["ピ"]={ "ヒ","゚" },
+ ["ブ"]={ "フ","゙" },
+ ["プ"]={ "フ","゚" },
+ ["ベ"]={ "ヘ","゙" },
+ ["ペ"]={ "ヘ","゚" },
+ ["ボ"]={ "ホ","゙" },
+ ["ãƒ"]={ "ホ","ã‚š" },
+ ["ヴ"]={ "ウ","゙" },
+ ["ヷ"]={ "ワ","゙" },
+ ["ヸ"]={ "ヰ","゙" },
+ ["ヹ"]={ "ヱ","゙" },
+ ["ヺ"]={ "ヲ","゙" },
+ ["ヾ"]={ "ヽ","゙" },
+ ["ï¬"]={ "×™","Ö´" },
+ ["ײַ"]={ "ײ","ַ" },
+ ["שׁ"]={ "ש","×" },
+ ["שׂ"]={ "ש","ׂ" },
+ ["שּׁ"]={ "ï­‰","×" },
+ ["שּׂ"]={ "שּ","ׂ" },
+ ["אַ"]={ "×","Ö·" },
+ ["אָ"]={ "×","Ö¸" },
+ ["אּ"]={ "×","Ö¼" },
+ ["בּ"]={ "ב","ּ" },
+ ["גּ"]={ "ג","ּ" },
+ ["דּ"]={ "ד","ּ" },
+ ["הּ"]={ "ה","ּ" },
+ ["וּ"]={ "ו","ּ" },
+ ["זּ"]={ "ז","ּ" },
+ ["טּ"]={ "ט","ּ" },
+ ["יּ"]={ "י","ּ" },
+ ["ךּ"]={ "ך","ּ" },
+ ["כּ"]={ "כ","ּ" },
+ ["לּ"]={ "ל","ּ" },
+ ["מּ"]={ "מ","ּ" },
+ ["ï­€"]={ "× ","Ö¼" },
+ ["ï­"]={ "ס","Ö¼" },
+ ["ï­ƒ"]={ "×£","Ö¼" },
+ ["פּ"]={ "פ","ּ" },
+ ["צּ"]={ "צ","ּ" },
+ ["קּ"]={ "ק","ּ" },
+ ["רּ"]={ "ר","ּ" },
+ ["שּ"]={ "ש","ּ" },
+ ["תּ"]={ "ת","ּ" },
+ ["וֹ"]={ "ו","ֹ" },
+ ["בֿ"]={ "ב","ֿ" },
+ ["ï­"]={ "×›","Ö¿" },
+ ["פֿ"]={ "פ","ֿ" },
+ ["𑂚"]={ "𑂙","𑂺" },
+ ["𑂜"]={ "𑂛","𑂺" },
+ ["𑂫"]={ "𑂥","𑂺" },
+ ["𑄮"]={ "𑄱","𑄧" },
+ ["𑄯"]={ "𑄲","𑄧" },
+ ["ð‘‹"]={ "ð‘‡","𑌾" },
+ ["ð‘Œ"]={ "ð‘‡","ð‘—" },
+ ["ð‘’»"]={ "ð‘’¹","ð‘’º" },
+ ["ð‘’¼"]={ "ð‘’¹","ð‘’°" },
+ ["ð‘’¾"]={ "ð‘’¹","ð‘’½" },
+ ["ð‘–º"]={ "ð‘–¸","ð‘–¯" },
+ ["ð‘–»"]={ "ð‘–¹","ð‘–¯" },
+ ["ð…ž"]={ "ð…—","ð…¥" },
+ ["ð…Ÿ"]={ "ð…˜","ð…¥" },
+ ["ð… "]={ "ð…Ÿ","ð…®" },
+ ["ð…¡"]={ "ð…Ÿ","ð…¯" },
+ ["ð…¢"]={ "ð…Ÿ","ð…°" },
+ ["ð…£"]={ "ð…Ÿ","ð…±" },
+ ["ð…¤"]={ "ð…Ÿ","ð…²" },
+ ["ð†»"]={ "ð†¹","ð…¥" },
+ ["ð†¼"]={ "ð†º","ð…¥" },
+ ["ð†½"]={ "ð†»","ð…®" },
+ ["ð†¾"]={ "ð†¼","ð…®" },
+ ["ð†¿"]={ "ð†»","ð…¯" },
+ ["ð‡€"]={ "ð†¼","ð…¯" },
+ },
+ },
+ },
+ ["name"]="collapse",
+ ["prepend"]=true,
+ ["type"]="ligature",
+}
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules={} end modules ['luatex-fonts-gbn']={
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+if context then
+--removed
+
+end
+local next=next
+local fonts=fonts
+local nodes=nodes
+local nuts=nodes.nuts
+local traverse_id=nuts.traverse_id
+local flush_node=nuts.flush_node
+local glyph_code=nodes.nodecodes.glyph
+local disc_code=nodes.nodecodes.disc
+local tonode=nuts.tonode
+local tonut=nuts.tonut
+local getfont=nuts.getfont
+local getchar=nuts.getchar
+local getid=nuts.getid
+local getboth=nuts.getboth
+local getprev=nuts.getprev
+local getnext=nuts.getnext
+local getdisc=nuts.getdisc
+local setchar=nuts.setchar
+local setlink=nuts.setlink
+local setprev=nuts.setprev
+local n_ligaturing=node.ligaturing
+local n_kerning=node.kerning
+local d_ligaturing=nuts.ligaturing
+local d_kerning=nuts.kerning
+local basemodepass=true
+local function l_warning() logs.report("fonts","don't call 'node.ligaturing' directly") l_warning=nil end
+local function k_warning() logs.report("fonts","don't call 'node.kerning' directly") k_warning=nil end
+function node.ligaturing(...)
+ if basemodepass and l_warning then
+ l_warning()
+ end
+ return n_ligaturing(...)
+end
+function node.kerning(...)
+ if basemodepass and k_warning then
+ k_warning()
+ end
+ return n_kerning(...)
+end
+function nuts.ligaturing(...)
+ if basemodepass and l_warning then
+ l_warning()
+ end
+ return d_ligaturing(...)
+end
+function nuts.kerning(...)
+ if basemodepass and k_warning then
+ k_warning()
+ end
+ return d_kerning(...)
+end
+function nodes.handlers.setbasemodepass(v)
+ basemodepass=v
+end
+local function nodepass(head,groupcode,size,packtype,direction)
+ local fontdata=fonts.hashes.identifiers
+ if fontdata then
+ local usedfonts={}
+ local basefonts={}
+ local prevfont=nil
+ local basefont=nil
+ local variants=nil
+ local redundant=nil
+ local nofused=0
+ for n in traverse_id(glyph_code,head) do
+ local font=getfont(n)
+ if font~=prevfont then
+ if basefont then
+ basefont[2]=getprev(n)
+ end
+ prevfont=font
+ local used=usedfonts[font]
+ if not used then
+ local tfmdata=fontdata[font]
+ if tfmdata then
+ local shared=tfmdata.shared
+ if shared then
+ local processors=shared.processes
+ if processors and #processors>0 then
+ usedfonts[font]=processors
+ nofused=nofused+1
+ elseif basemodepass then
+ basefont={ n,nil }
+ basefonts[#basefonts+1]=basefont
+ end
+ end
+ local resources=tfmdata.resources
+ variants=resources and resources.variants
+ variants=variants and next(variants) and variants or false
+ end
+ else
+ local tfmdata=fontdata[prevfont]
+ if tfmdata then
+ local resources=tfmdata.resources
+ variants=resources and resources.variants
+ variants=variants and next(variants) and variants or false
+ end
+ end
+ end
+ if variants then
+ local char=getchar(n)
+ if (char>=0xFE00 and char<=0xFE0F) or (char>=0xE0100 and char<=0xE01EF) then
+ local hash=variants[char]
+ if hash then
+ local p=getprev(n)
+ if p and getid(p)==glyph_code then
+ local variant=hash[getchar(p)]
+ if variant then
+ setchar(p,variant)
+ end
+ end
+ end
+ if not redundant then
+ redundant={ n }
+ else
+ redundant[#redundant+1]=n
+ end
+ end
+ end
+ end
+ local nofbasefonts=#basefonts
+ if redundant then
+ for i=1,#redundant do
+ local r=redundant[i]
+ local p,n=getboth(r)
+ if r==head then
+ head=n
+ setprev(n)
+ else
+ setlink(p,n)
+ end
+ if nofbasefonts>0 then
+ for i=1,nofbasefonts do
+ local bi=basefonts[i]
+ if r==bi[1] then
+ bi[1]=n
+ end
+ if r==bi[2] then
+ bi[2]=n
+ end
+ end
+ end
+ flush_node(r)
+ end
+ end
+ for d in traverse_id(disc_code,head) do
+ local _,_,r=getdisc(d)
+ if r then
+ for n in traverse_id(glyph_code,r) do
+ local font=getfont(n)
+ if font~=prevfont then
+ prevfont=font
+ local used=usedfonts[font]
+ if not used then
+ local tfmdata=fontdata[font]
+ if tfmdata then
+ local shared=tfmdata.shared
+ if shared then
+ local processors=shared.processes
+ if processors and #processors>0 then
+ usedfonts[font]=processors
+ nofused=nofused+1
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if next(usedfonts) then
+ for font,processors in next,usedfonts do
+ for i=1,#processors do
+ head=processors[i](head,font,0,direction,nofused) or head
+ end
+ end
+ end
+ if basemodepass and nofbasefonts>0 then
+ for i=1,nofbasefonts do
+ local range=basefonts[i]
+ local start=range[1]
+ local stop=range[2]
+ if start then
+ local front=head==start
+ local prev,next
+ if stop then
+ next=getnext(stop)
+ start,stop=d_ligaturing(start,stop)
+ start,stop=d_kerning(start,stop)
+ else
+ prev=getprev(start)
+ start=d_ligaturing(start)
+ start=d_kerning(start)
+ end
+ if prev then
+ setlink(prev,start)
+ end
+ if next then
+ setlink(stop,next)
+ end
+ if front and head~=start then
+ head=start
+ end
+ end
+ end
+ end
+ end
+ return head
+end
+local function basepass(head)
+ if basemodepass then
+ head=d_ligaturing(head)
+ head=d_kerning(head)
+ end
+ return head
+end
+local protectpass=node.direct.protect_glyphs
+local injectpass=nodes.injections.handler
+function nodes.handlers.nodepass(head,...)
+ if head then
+ return tonode(nodepass(tonut(head),...))
+ end
+end
+function nodes.handlers.basepass(head)
+ if head then
+ return tonode(basepass(tonut(head)))
+ end
+end
+function nodes.handlers.injectpass(head)
+ if head then
+ return tonode(injectpass(tonut(head)))
+ end
+end
+function nodes.handlers.protectpass(head)
+ if head then
+ protectpass(tonut(head))
+ return head
+ end
+end
+function nodes.simple_font_handler(head,groupcode,size,packtype,direction)
+ if head then
+ head=tonut(head)
+ head=nodepass(head,groupcode,size,packtype,direction)
+ head=injectpass(head)
+ if not basemodepass then
+ head=basepass(head)
+ end
+ protectpass(head)
+ head=tonode(head)
+ end
+ return head
+end
+
+end -- closure
diff --git a/macros/luatex/generic/luaotfload/fontloader-util-fil.lua b/macros/luatex/generic/luaotfload/fontloader-util-fil.lua
new file mode 100644
index 0000000000..79af277437
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-util-fil.lua
@@ -0,0 +1,452 @@
+if not modules then modules = { } end modules ['util-fil'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local tonumber = tonumber
+local byte = string.byte
+local char = string.char
+
+-- Here are a few helpers (the starting point were old ones I used for parsing
+-- flac files). In Lua 5.3 we can probably do this better. Some code will move
+-- here.
+
+-- We could comment those that are in fio and sio.
+
+utilities = utilities or { }
+local files = { }
+utilities.files = files
+
+-- we could have a gc method that closes but files auto close anyway
+
+local zerobased = { }
+
+function files.open(filename,zb)
+ local f = io.open(filename,"rb")
+ if f then
+ zerobased[f] = zb or false
+ end
+ return f
+end
+
+function files.close(f)
+ zerobased[f] = nil
+ f:close()
+end
+
+function files.size(f)
+ local current = f:seek()
+ local size = f:seek("end")
+ f:seek("set",current)
+ return size
+end
+
+files.getsize = files.size
+
+function files.setposition(f,n)
+ if zerobased[f] then
+ f:seek("set",n)
+ else
+ f:seek("set",n - 1)
+ end
+end
+
+function files.getposition(f)
+ if zerobased[f] then
+ return f:seek()
+ else
+ return f:seek() + 1
+ end
+end
+
+function files.look(f,n,chars)
+ local p = f:seek()
+ local s = f:read(n)
+ f:seek("set",p)
+ if chars then
+ return s
+ else
+ return byte(s,1,#s)
+ end
+end
+
+function files.skip(f,n)
+ if n == 1 then
+ f:read(n)
+ else
+ f:seek("set",f:seek()+n)
+ end
+end
+
+function files.readbyte(f)
+ return byte(f:read(1))
+end
+
+function files.readbytes(f,n)
+ return byte(f:read(n),1,n)
+end
+
+function files.readbytetable(f,n)
+ -- return { byte(f:read(n),1,n) }
+ local s = f:read(n or 1)
+ return { byte(s,1,#s) } -- best use the real length
+end
+
+function files.readchar(f)
+ return f:read(1)
+end
+
+function files.readstring(f,n)
+ return f:read(n or 1)
+end
+
+function files.readinteger1(f) -- one byte
+ local n = byte(f:read(1))
+ if n >= 0x80 then
+ return n - 0x100
+ else
+ return n
+ end
+end
+
+files.readcardinal1 = files.readbyte -- one byte
+files.readcardinal = files.readcardinal1
+files.readinteger = files.readinteger1
+files.readsignedbyte = files.readinteger1
+
+function files.readcardinal2(f)
+ local a, b = byte(f:read(2),1,2)
+ return 0x100 * a + b
+end
+
+function files.readcardinal2le(f)
+ local b, a = byte(f:read(2),1,2)
+ return 0x100 * a + b
+end
+
+function files.readinteger2(f)
+ local a, b = byte(f:read(2),1,2)
+ if a >= 0x80 then
+ return 0x100 * a + b - 0x10000
+ else
+ return 0x100 * a + b
+ end
+end
+
+function files.readinteger2le(f)
+ local b, a = byte(f:read(2),1,2)
+ if a >= 0x80 then
+ return 0x100 * a + b - 0x10000
+ else
+ return 0x100 * a + b
+ end
+end
+
+function files.readcardinal3(f)
+ local a, b, c = byte(f:read(3),1,3)
+ return 0x10000 * a + 0x100 * b + c
+end
+
+function files.readcardinal3le(f)
+ local c, b, a = byte(f:read(3),1,3)
+ return 0x10000 * a + 0x100 * b + c
+end
+
+function files.readinteger3(f)
+ local a, b, c = byte(f:read(3),1,3)
+ if a >= 0x80 then
+ return 0x10000 * a + 0x100 * b + c - 0x1000000
+ else
+ return 0x10000 * a + 0x100 * b + c
+ end
+end
+
+function files.readinteger3le(f)
+ local c, b, a = byte(f:read(3),1,3)
+ if a >= 0x80 then
+ return 0x10000 * a + 0x100 * b + c - 0x1000000
+ else
+ return 0x10000 * a + 0x100 * b + c
+ end
+end
+
+function files.readcardinal4(f)
+ local a, b, c, d = byte(f:read(4),1,4)
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+end
+
+function files.readcardinal4le(f)
+ local d, c, b, a = byte(f:read(4),1,4)
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+end
+
+function files.readinteger4(f)
+ local a, b, c, d = byte(f:read(4),1,4)
+ if a >= 0x80 then
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000
+ else
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+ end
+end
+
+function files.readinteger4le(f)
+ local d, c, b, a = byte(f:read(4),1,4)
+ if a >= 0x80 then
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000
+ else
+ return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
+ end
+end
+
+function files.readfixed2(f)
+ local a, b = byte(f:read(2),1,2)
+ if a >= 0x80 then
+ tonumber((a - 0x100) .. "." .. b)
+ else
+ tonumber(( a ) .. "." .. b)
+ end
+end
+
+-- (real) (n>>16) + ((n&0xffff)/65536.0)) but no cast in lua (we could use unpack)
+
+function files.readfixed4(f)
+ local a, b, c, d = byte(f:read(4),1,4)
+ if a >= 0x80 then
+ tonumber((0x100 * a + b - 0x10000) .. "." .. (0x100 * c + d))
+ else
+ tonumber((0x100 * a + b ) .. "." .. (0x100 * c + d))
+ end
+end
+
+-- (real) ((n<<16)>>(16+14)) + ((n&0x3fff)/16384.0))
+
+if bit32 then
+
+ local extract = bit32.extract
+ local band = bit32.band
+
+ function files.read2dot14(f)
+ local a, b = byte(f:read(2),1,2)
+ if a >= 0x80 then
+ local n = -(0x100 * a + b)
+ return - (extract(n,14,2) + (band(n,0x3FFF) / 16384.0))
+ else
+ local n = 0x100 * a + b
+ return (extract(n,14,2) + (band(n,0x3FFF) / 16384.0))
+ end
+ end
+
+end
+
+function files.skipshort(f,n)
+ f:read(2*(n or 1))
+end
+
+function files.skiplong(f,n)
+ f:read(4*(n or 1))
+end
+
+-- writers (kind of slow)
+
+if bit32 then
+
+ local rshift = bit32.rshift
+
+ function files.writecardinal2(f,n)
+ local a = char(n % 256)
+ n = rshift(n,8)
+ local b = char(n % 256)
+ f:write(b,a)
+ end
+
+ function files.writecardinal4(f,n)
+ local a = char(n % 256)
+ n = rshift(n,8)
+ local b = char(n % 256)
+ n = rshift(n,8)
+ local c = char(n % 256)
+ n = rshift(n,8)
+ local d = char(n % 256)
+ f:write(d,c,b,a)
+ end
+
+ function files.writecardinal2le(f,n)
+ local a = char(n % 256)
+ n = rshift(n,8)
+ local b = char(n % 256)
+ f:write(a,b)
+ end
+
+ function files.writecardinal4le(f,n)
+ local a = char(n % 256)
+ n = rshift(n,8)
+ local b = char(n % 256)
+ n = rshift(n,8)
+ local c = char(n % 256)
+ n = rshift(n,8)
+ local d = char(n % 256)
+ f:write(a,b,c,d)
+ end
+
+else
+
+ local floor = math.floor
+
+ function files.writecardinal2(f,n)
+ local a = char(n % 256)
+ n = floor(n/256)
+ local b = char(n % 256)
+ f:write(b,a)
+ end
+
+ function files.writecardinal4(f,n)
+ local a = char(n % 256)
+ n = floor(n/256)
+ local b = char(n % 256)
+ n = floor(n/256)
+ local c = char(n % 256)
+ n = floor(n/256)
+ local d = char(n % 256)
+ f:write(d,c,b,a)
+ end
+
+ function files.writecardinal2le(f,n)
+ local a = char(n % 256)
+ n = floor(n/256)
+ local b = char(n % 256)
+ f:write(a,b)
+ end
+
+ function files.writecardinal4le(f,n)
+ local a = char(n % 256)
+ n = floor(n/256)
+ local b = char(n % 256)
+ n = floor(n/256)
+ local c = char(n % 256)
+ n = floor(n/256)
+ local d = char(n % 256)
+ f:write(a,b,c,d)
+ end
+
+end
+
+function files.writestring(f,s)
+ f:write(char(byte(s,1,#s)))
+end
+
+function files.writebyte(f,b)
+ f:write(char(b))
+end
+
+if fio and fio.readcardinal1 then
+
+ files.readcardinal1 = fio.readcardinal1
+ files.readcardinal2 = fio.readcardinal2
+ files.readcardinal3 = fio.readcardinal3
+ files.readcardinal4 = fio.readcardinal4
+
+ files.readcardinal1le = fio.readcardinal1le or files.readcardinal1le
+ files.readcardinal2le = fio.readcardinal2le or files.readcardinal2le
+ files.readcardinal3le = fio.readcardinal3le or files.readcardinal3le
+ files.readcardinal4le = fio.readcardinal4le or files.readcardinal4le
+
+ files.readinteger1 = fio.readinteger1
+ files.readinteger2 = fio.readinteger2
+ files.readinteger3 = fio.readinteger3
+ files.readinteger4 = fio.readinteger4
+
+ files.readinteger1le = fio.readinteger1le or files.readinteger1le
+ files.readinteger2le = fio.readinteger2le or files.readinteger2le
+ files.readinteger3le = fio.readinteger3le or files.readinteger3le
+ files.readinteger4le = fio.readinteger4le or files.readinteger4le
+
+ files.readfixed2 = fio.readfixed2
+ files.readfixed4 = fio.readfixed4
+ files.read2dot14 = fio.read2dot14
+ files.setposition = fio.setposition
+ files.getposition = fio.getposition
+
+ files.readbyte = files.readcardinal1
+ files.readsignedbyte = files.readinteger1
+ files.readcardinal = files.readcardinal1
+ files.readinteger = files.readinteger1
+
+ local skipposition = fio.skipposition
+ files.skipposition = skipposition
+
+ files.readbytes = fio.readbytes
+ files.readbytetable = fio.readbytetable
+
+ function files.skipshort(f,n)
+ skipposition(f,2*(n or 1))
+ end
+
+ function files.skiplong(f,n)
+ skipposition(f,4*(n or 1))
+ end
+
+end
+
+if fio and fio.writecardinal1 then
+
+ files.writecardinal1 = fio.writecardinal1
+ files.writecardinal2 = fio.writecardinal2
+ files.writecardinal3 = fio.writecardinal3
+ files.writecardinal4 = fio.writecardinal4
+
+ files.writecardinal1le = fio.writecardinal1le
+ files.writecardinal2le = fio.writecardinal2le
+ files.writecardinal3le = fio.writecardinal3le
+ files.writecardinal4le = fio.writecardinal4le
+
+ files.writeinteger1 = fio.writeinteger1 or fio.writecardinal1
+ files.writeinteger2 = fio.writeinteger2 or fio.writecardinal2
+ files.writeinteger3 = fio.writeinteger3 or fio.writecardinal3
+ files.writeinteger4 = fio.writeinteger4 or fio.writecardinal4
+
+ files.writeinteger1le = files.writeinteger1le or fio.writecardinal1le
+ files.writeinteger2le = files.writeinteger2le or fio.writecardinal2le
+ files.writeinteger3le = files.writeinteger3le or fio.writecardinal3le
+ files.writeinteger4le = files.writeinteger4le or fio.writecardinal4le
+
+end
+
+if fio and fio.readcardinaltable then
+
+ files.readcardinaltable = fio.readcardinaltable
+ files.readintegertable = fio.readintegertable
+
+else
+
+ local readcardinal1 = files.readcardinal1
+ local readcardinal2 = files.readcardinal2
+ local readcardinal3 = files.readcardinal3
+ local readcardinal4 = files.readcardinal4
+
+ function files.readcardinaltable(f,n,b)
+ local t = { }
+ if b == 1 then for i=1,n do t[i] = readcardinal1(f) end
+ elseif b == 2 then for i=1,n do t[i] = readcardinal2(f) end
+ elseif b == 3 then for i=1,n do t[i] = readcardinal3(f) end
+ elseif b == 4 then for i=1,n do t[i] = readcardinal4(f) end end
+ return t
+ end
+
+ local readinteger1 = files.readinteger1
+ local readinteger2 = files.readinteger2
+ local readinteger3 = files.readinteger3
+ local readinteger4 = files.readinteger4
+
+ function files.readintegertable(f,n,b)
+ local t = { }
+ if b == 1 then for i=1,n do t[i] = readinteger1(f) end
+ elseif b == 2 then for i=1,n do t[i] = readinteger2(f) end
+ elseif b == 3 then for i=1,n do t[i] = readinteger3(f) end
+ elseif b == 4 then for i=1,n do t[i] = readinteger4(f) end end
+ return t
+ end
+
+end
diff --git a/macros/luatex/generic/luaotfload/fontloader-util-str.lua b/macros/luatex/generic/luaotfload/fontloader-util-str.lua
new file mode 100644
index 0000000000..ad22302df0
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/fontloader-util-str.lua
@@ -0,0 +1,1461 @@
+if not modules then modules = { } end modules ['util-str'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+utilities = utilities or { }
+utilities.strings = utilities.strings or { }
+local strings = utilities.strings
+
+local format, gsub, rep, sub, find = string.format, string.gsub, string.rep, string.sub, string.find
+local load, dump = load, string.dump
+local tonumber, type, tostring, next, setmetatable = tonumber, type, tostring, next, setmetatable
+local unpack, concat = table.unpack, table.concat
+local P, V, C, S, R, Ct, Cs, Cp, Carg, Cc = lpeg.P, lpeg.V, lpeg.C, lpeg.S, lpeg.R, lpeg.Ct, lpeg.Cs, lpeg.Cp, lpeg.Carg, lpeg.Cc
+local patterns, lpegmatch = lpeg.patterns, lpeg.match
+local utfchar, utfbyte, utflen = utf.char, utf.byte, utf.len
+
+----- loadstripped = utilities.lua.loadstripped
+----- setmetatableindex = table.setmetatableindex
+
+local loadstripped = function(str,shortcuts)
+ if shortcuts then
+ return load(dump(load(str),true),nil,nil,shortcuts)
+ else
+ return load(dump(load(str),true))
+ end
+end
+
+-- todo: make a special namespace for the formatter
+
+if not number then number = { } end -- temp hack for luatex-fonts
+
+local stripzero = patterns.stripzero
+local stripzeros = patterns.stripzeros
+local newline = patterns.newline
+local endofstring = patterns.endofstring
+local anything = patterns.anything
+local whitespace = patterns.whitespace
+local space = patterns.space
+local spacer = patterns.spacer
+local spaceortab = patterns.spaceortab
+local digit = patterns.digit
+local sign = patterns.sign
+local period = patterns.period
+
+-- local function points(n)
+-- n = tonumber(n)
+-- return (not n or n == 0) and "0pt" or lpegmatch(stripzeros,format("%.5fpt",n/65536))
+-- end
+
+-- local function basepoints(n)
+-- n = tonumber(n)
+-- return (not n or n == 0) and "0bp" or lpegmatch(stripzeros,format("%.5fbp", n*(7200/7227)/65536))
+-- end
+
+local ptf = 1 / 65536
+local bpf = (7200/7227) / 65536
+
+local function points(n)
+ if n == 0 then
+ return "0pt"
+ end
+ n = tonumber(n)
+ if not n or n == 0 then
+ return "0pt"
+ end
+ n = n * ptf
+ if n % 1 == 0 then
+ return format("%ipt",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fpt",n)) -- plural as we need to keep the pt
+end
+
+local function basepoints(n)
+ if n == 0 then
+ return "0pt"
+ end
+ n = tonumber(n)
+ if not n or n == 0 then
+ return "0pt"
+ end
+ n = n * bpf
+ if n % 1 == 0 then
+ return format("%ibp",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fbp",n)) -- plural as we need to keep the pt
+end
+
+number.points = points
+number.basepoints = basepoints
+
+-- str = " \n \ntest \n test\ntest "
+-- print("["..string.gsub(string.collapsecrlf(str),"\n","+").."]")
+
+local rubish = spaceortab^0 * newline
+local anyrubish = spaceortab + newline
+local stripped = (spaceortab^1 / "") * newline
+local leading = rubish^0 / ""
+local trailing = (anyrubish^1 * endofstring) / ""
+local redundant = rubish^3 / "\n"
+
+local pattern = Cs(leading * (trailing + redundant + stripped + anything)^0)
+
+function strings.collapsecrlf(str)
+ return lpegmatch(pattern,str)
+end
+
+-- The following functions might end up in another namespace.
+
+local repeaters = { } -- watch how we also moved the -1 in depth-1 to the creator
+
+function strings.newrepeater(str,offset)
+ offset = offset or 0
+ local s = repeaters[str]
+ if not s then
+ s = { }
+ repeaters[str] = s
+ end
+ local t = s[offset]
+ if t then
+ return t
+ end
+ t = { }
+ setmetatable(t, { __index = function(t,k)
+ if not k then
+ return ""
+ end
+ local n = k + offset
+ local s = n > 0 and rep(str,n) or ""
+ t[k] = s
+ return s
+ end })
+ s[offset] = t
+ return t
+end
+
+-- local dashes = strings.newrepeater("--",-1)
+-- print(dashes[2],dashes[3],dashes[1])
+
+local extra, tab, start = 0, 0, 4, 0
+
+local nspaces = strings.newrepeater(" ")
+
+string.nspaces = nspaces
+
+local pattern =
+ Carg(1) / function(t)
+ extra, tab, start = 0, t or 7, 1
+ end
+ * Cs((
+ Cp() * patterns.tab / function(position)
+ local current = (position - start + 1) + extra
+ local spaces = tab-(current-1) % tab
+ if spaces > 0 then
+ extra = extra + spaces - 1
+ return nspaces[spaces] -- rep(" ",spaces)
+ else
+ return ""
+ end
+ end
+ + newline * Cp() / function(position)
+ extra, start = 0, position
+ end
+ + anything
+ )^1)
+
+function strings.tabtospace(str,tab)
+ -- no real gain in first checking if a \t is there
+ return lpegmatch(pattern,str,1,tab or 7)
+end
+
+function string.utfpadding(s,n)
+ if not n or n == 0 then
+ return ""
+ end
+ local l = utflen(s)
+ if n > 0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
+end
+
+-- local t = {
+-- "1234567123456712345671234567",
+-- "\tb\tc",
+-- "a\tb\tc",
+-- "aa\tbb\tcc",
+-- "aaa\tbbb\tccc",
+-- "aaaa\tbbbb\tcccc",
+-- "aaaaa\tbbbbb\tccccc",
+-- "aaaaaa\tbbbbbb\tcccccc\n aaaaaa\tbbbbbb\tcccccc",
+-- "one\n two\nxxx three\nxx four\nx five\nsix",
+-- }
+-- for k=1,#t do
+-- print(strings.tabtospace(t[k]))
+-- end
+
+-- todo: lpeg
+
+-- function strings.striplong(str) -- strips all leading spaces
+-- str = gsub(str,"^%s*","")
+-- str = gsub(str,"[\n\r]+ *","\n")
+-- return str
+-- end
+
+local optionalspace = spacer^0
+local nospace = optionalspace/""
+local endofline = nospace * newline
+
+local stripend = (whitespace^1 * endofstring)/""
+
+local normalline = (nospace * ((1-optionalspace*(newline+endofstring))^1) * nospace)
+
+local stripempty = endofline^1/""
+local normalempty = endofline^1
+local singleempty = endofline * (endofline^0/"")
+local doubleempty = endofline * endofline^-1 * (endofline^0/"")
+local stripstart = stripempty^0
+
+local intospace = whitespace^1/" "
+local noleading = whitespace^1/""
+local notrailing = noleading * endofstring
+
+local p_prune_normal = Cs ( stripstart * ( stripend + normalline + normalempty )^0 )
+local p_prune_collapse = Cs ( stripstart * ( stripend + normalline + doubleempty )^0 )
+local p_prune_noempty = Cs ( stripstart * ( stripend + normalline + singleempty )^0 )
+local p_prune_intospace = Cs ( noleading * ( notrailing + intospace + 1 )^0 )
+local p_retain_normal = Cs ( ( normalline + normalempty )^0 )
+local p_retain_collapse = Cs ( ( normalline + doubleempty )^0 )
+local p_retain_noempty = Cs ( ( normalline + singleempty )^0 )
+
+-- function striplines(str,prune,collapse,noempty)
+-- if prune then
+-- if noempty then
+-- return lpegmatch(p_prune_noempty,str) or str
+-- elseif collapse then
+-- return lpegmatch(p_prune_collapse,str) or str
+-- else
+-- return lpegmatch(p_prune_normal,str) or str
+-- end
+-- else
+-- if noempty then
+-- return lpegmatch(p_retain_noempty,str) or str
+-- elseif collapse then
+-- return lpegmatch(p_retain_collapse,str) or str
+-- else
+-- return lpegmatch(p_retain_normal,str) or str
+-- end
+-- end
+-- end
+
+local striplinepatterns = {
+ ["prune"] = p_prune_normal,
+ ["prune and collapse"] = p_prune_collapse, -- default
+ ["prune and no empty"] = p_prune_noempty,
+ ["prune and to space"] = p_prune_intospace,
+ ["retain"] = p_retain_normal,
+ ["retain and collapse"] = p_retain_collapse,
+ ["retain and no empty"] = p_retain_noempty,
+ ["collapse"] = patterns.collapser,
+}
+
+setmetatable(striplinepatterns,{ __index = function(t,k) return p_prune_collapse end })
+
+strings.striplinepatterns = striplinepatterns
+
+function strings.striplines(str,how)
+ return str and lpegmatch(striplinepatterns[how],str) or str
+end
+
+function strings.collapse(str) -- maybe also in strings
+ return str and lpegmatch(p_prune_intospace,str) or str
+end
+
+-- also see: string.collapsespaces
+
+strings.striplong = strings.striplines -- for old times sake
+
+-- local str = table.concat( {
+-- " ",
+-- " aap",
+-- " noot mies",
+-- " ",
+-- " ",
+-- " zus wim jet",
+-- "zus wim jet",
+-- " zus wim jet",
+-- " ",
+-- }, "\n")
+--
+-- local str = table.concat( {
+-- " aaaa",
+-- " bb",
+-- " cccccc",
+-- " ",
+-- }, "\n")
+--
+-- for k, v in table.sortedhash(utilities.strings.striplinepatterns) do
+-- logs.report("stripper","method: %s, result: [[%s]]",k,utilities.strings.striplines(str,k))
+-- end
+
+-- inspect(strings.striplong([[
+-- aaaa
+-- bb
+-- cccccc
+-- ]]))
+
+function strings.nice(str)
+ str = gsub(str,"[:%-+_]+"," ") -- maybe more
+ return str
+end
+
+-- Work in progress. Interesting is that compared to the built-in this is faster in
+-- luatex than in luajittex where we have a comparable speed. It only makes sense
+-- to use the formatter when a (somewhat) complex format is used a lot. Each formatter
+-- is a function so there is some overhead and not all formatted output is worth that
+-- overhead. Keep in mind that there is an extra function call involved. In principle
+-- we end up with a string concatination so one could inline such a sequence but often
+-- at the cost of less readabinity. So, it's a sort of (visual) compromise. Of course
+-- there is the benefit of more variants. (Concerning the speed: a simple format like
+-- %05fpt is better off with format than with a formatter, but as soon as you put
+-- something in front formatters become faster. Passing the pt as extra argument makes
+-- formatters behave better. Of course this is rather implementation dependent. Also,
+-- when a specific format is only used a few times the overhead in creating it is not
+-- compensated by speed.)
+--
+-- More info can be found in cld-mkiv.pdf so here I stick to a simple list.
+--
+-- integer %...i number
+-- integer %...d number
+-- unsigned %...u number -- not used
+-- character %...c number
+-- hexadecimal %...x number
+-- HEXADECIMAL %...X number
+-- octal %...o number
+-- string %...s string number
+-- float %...f number
+-- checked float %...F number
+-- exponential %...e number
+-- exponential %...E number
+-- stripped e %...j number
+-- stripped E %...J number
+-- autofloat %...g number
+-- autofloat %...G number
+-- utf character %...c number
+-- force tostring %...S any
+-- force tostring %Q any
+-- force tonumber %N number (strip leading zeros)
+-- signed number %I number
+-- rounded number %r number
+-- 0xhexadecimal %...h character number
+-- 0xHEXADECIMAL %...H character number
+-- U+hexadecimal %...u character number
+-- U+HEXADECIMAL %...U character number
+-- points %p number (scaled points)
+-- basepoints %b number (scaled points)
+-- table concat %...t table
+-- table concat %{.}t table
+-- serialize %...T sequenced (no nested tables)
+-- serialize %{.}T sequenced (no nested tables)
+-- boolean (logic) %l boolean
+-- BOOLEAN %L boolean
+-- whitespace %...w number
+-- whitespace %...W (fixed)
+-- automatic %...a 'whatever' (string, table, ...)
+-- automatic %...A "whatever" (string, table, ...)
+-- zap %...z skip
+-- stripped %...N %...N
+-- comma/period real %...m
+-- period/comma real %...M
+-- formatted float %...k n.m
+
+local n = 0
+
+-- we are somewhat sloppy in parsing prefixes as it's not that critical
+
+-- hard to avoid but we can collect them in a private namespace if needed
+
+-- inline the next two makes no sense as we only use this in logging
+
+local sequenced = table.sequenced
+
+function string.autodouble(s,sep)
+ if s == nil then
+ return '""'
+ end
+ local t = type(s)
+ if t == "number" then
+ return tostring(s) -- tostring not really needed
+ end
+ if t == "table" then
+ return ('"' .. sequenced(s,sep or ",") .. '"')
+ end
+ return ('"' .. tostring(s) .. '"')
+end
+
+function string.autosingle(s,sep)
+ if s == nil then
+ return "''"
+ end
+ local t = type(s)
+ if t == "number" then
+ return tostring(s) -- tostring not really needed
+ end
+ if t == "table" then
+ return ("'" .. sequenced(s,sep or ",") .. "'")
+ end
+ return ("'" .. tostring(s) .. "'")
+end
+
+local tracedchars = { [0] =
+ -- the regular bunch
+ "[null]", "[soh]", "[stx]", "[etx]", "[eot]", "[enq]", "[ack]", "[bel]",
+ "[bs]", "[ht]", "[lf]", "[vt]", "[ff]", "[cr]", "[so]", "[si]",
+ "[dle]", "[dc1]", "[dc2]", "[dc3]", "[dc4]", "[nak]", "[syn]", "[etb]",
+ "[can]", "[em]", "[sub]", "[esc]", "[fs]", "[gs]", "[rs]", "[us]",
+ -- plus space
+ "[space]", -- 0x20
+}
+
+string.tracedchars = tracedchars
+strings.tracers = tracedchars
+
+function string.tracedchar(b)
+ -- todo: table
+ if type(b) == "number" then
+ return tracedchars[b] or (utfchar(b) .. " (U+" .. format("%05X",b) .. ")")
+ else
+ local c = utfbyte(b)
+ return tracedchars[c] or (b .. " (U+" .. (c and format("%05X",c) or "?????") .. ")")
+ end
+end
+
+function number.signed(i)
+ if i > 0 then
+ return "+", i
+ else
+ return "-", -i
+ end
+end
+
+-- maybe to util-num
+
+local two = digit * digit
+local three = two * digit
+local prefix = (Carg(1) * three)^1
+
+local splitter = Cs (
+ (((1 - (three^1 * period))^1 + C(three)) * prefix + C((1-period)^1))
+ * (anything/"" * Carg(2)) * C(2)
+)
+
+local splitter3 = Cs (
+ three * prefix * endofstring +
+ two * prefix * endofstring +
+ digit * prefix * endofstring +
+ three +
+ two +
+ digit
+)
+
+patterns.formattednumber = splitter
+
+function number.formatted(n,sep1,sep2)
+ if sep1 == false then
+ if type(n) == "number" then
+ n = tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n) == "number" then
+ n = format("%0.2f",n)
+ end
+ if sep1 == true then
+ return lpegmatch(splitter,n,1,".",",")
+ elseif sep1 == "." then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
+ elseif sep1 == "," then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
+ else
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
+ end
+ end
+end
+
+-- print(number.formatted(1))
+-- print(number.formatted(12))
+-- print(number.formatted(123))
+-- print(number.formatted(1234))
+-- print(number.formatted(12345))
+-- print(number.formatted(123456))
+-- print(number.formatted(1234567))
+-- print(number.formatted(12345678))
+-- print(number.formatted(12345678,true))
+-- print(number.formatted(1,false))
+-- print(number.formatted(12,false))
+-- print(number.formatted(123,false))
+-- print(number.formatted(1234,false))
+-- print(number.formatted(12345,false))
+-- print(number.formatted(123456,false))
+-- print(number.formatted(1234567,false))
+-- print(number.formatted(12345678,false))
+-- print(number.formatted(1234.56,"!","?"))
+
+local p = Cs(
+ P("-")^0
+ * (P("0")^1/"")^0
+ * (1-period)^0
+ * (period * P("0")^1 * endofstring/"" + period^0)
+ * P(1-P("0")^1*endofstring)^0
+ )
+
+function number.compactfloat(n,fmt)
+ if n == 0 then
+ return "0"
+ elseif n == 1 then
+ return "1"
+ end
+ n = lpegmatch(p,format(fmt or "%0.3f",n))
+ if n == "." or n == "" or n == "-" then
+ return "0"
+ end
+ return n
+end
+
+local zero = P("0")^1 / ""
+local plus = P("+") / ""
+local minus = P("-")
+local separator = period
+local trailing = zero^1 * #S("eE")
+local exponent = (S("eE") * (plus + Cs((minus * zero^0 * endofstring)/"") + minus) * zero^0 * (endofstring * Cc("0") + anything^1))
+local pattern_a = Cs(minus^0 * digit^1 * (separator/"" * trailing + separator * (trailing + digit)^0) * exponent)
+local pattern_b = Cs((exponent + anything)^0)
+
+function number.sparseexponent(f,n)
+ if not n then
+ n = f
+ f = "%e"
+ end
+ local tn = type(n)
+ if tn == "string" then -- cast to number
+ local m = tonumber(n)
+ if m then
+ return lpegmatch((f == "%e" or f == "%E") and pattern_a or pattern_b,format(f,m))
+ end
+ elseif tn == "number" then
+ return lpegmatch((f == "%e" or f == "%E") and pattern_a or pattern_b,format(f,n))
+ end
+ return tostring(n)
+end
+
+local hf = { }
+local hs = { }
+
+setmetatable(hf, { __index = function(t,k)
+ local v = "%." .. k .. "f"
+ t[k] = v
+ return v
+end } )
+
+setmetatable(hs, { __index = function(t,k)
+ local v = "%" .. k .. "s"
+ t[k] = v
+ return v
+end } )
+
+function number.formattedfloat(n,b,a)
+ local s = format(hf[a],n)
+ local l = (b or 0) + (a or 0) + 1
+ if #s < l then
+ return format(hs[l],s)
+ else
+ return s
+ end
+end
+
+local template = [[
+%s
+%s
+return function(%s) return %s end
+]]
+
+-- this might move
+
+local pattern = Cs(Cc('"') * (
+ (1-S('"\\\n\r'))^1
+ + P('"') / '\\"'
+ + P('\\') / '\\\\'
+ + P('\n') / '\\n'
+ + P('\r') / '\\r'
+)^0 * Cc('"'))
+
+patterns.escapedquotes = pattern
+
+function string.escapedquotes(s)
+ return lpegmatch(pattern,s)
+end
+
+-- print(string.escapedquotes('1\\23\n"'))
+
+-- but for now here
+
+local preamble = ""
+
+local environment = {
+ global = global or _G,
+ lpeg = lpeg,
+ type = type,
+ tostring = tostring,
+ tonumber = tonumber,
+ format = string.format,
+ concat = table.concat,
+ signed = number.signed,
+ points = number.points,
+ basepoints = number.basepoints,
+ utfchar = utf.char,
+ utfbyte = utf.byte,
+ lpegmatch = lpeg.match,
+ nspaces = string.nspaces,
+ utfpadding = string.utfpadding,
+ tracedchar = string.tracedchar,
+ autosingle = string.autosingle,
+ autodouble = string.autodouble,
+ sequenced = table.sequenced,
+ formattednumber = number.formatted,
+ sparseexponent = number.sparseexponent,
+ formattedfloat = number.formattedfloat,
+ stripzero = patterns.stripzero,
+ stripzeros = patterns.stripzeros,
+ escapedquotes = string.escapedquotes,
+
+ FORMAT = string.f9,
+}
+
+-- -- --
+
+local arguments = { "a1" } -- faster than previously used (select(n,...))
+
+setmetatable(arguments, { __index =
+ function(t,k)
+ local v = t[k-1] .. ",a" .. k
+ t[k] = v
+ return v
+ end
+})
+
+local prefix_any = C((sign + space + period + digit)^0)
+local prefix_sub = (C((sign + digit)^0) + Cc(0))
+ * period
+ * (C((sign + digit)^0) + Cc(0))
+local prefix_tab = P("{") * C((1-P("}"))^0) * P("}") + C((1-R("az","AZ","09","%%"))^0)
+
+-- we've split all cases as then we can optimize them (let's omit the fuzzy u)
+
+-- todo: replace outer formats in next by ..
+
+local format_s = function(f)
+ n = n + 1
+ if f and f ~= "" then
+ return format("format('%%%ss',a%s)",f,n)
+ else -- best no tostring in order to stay compatible (.. does a selective tostring too)
+ return format("(a%s or '')",n) -- goodie: nil check
+ end
+end
+
+local format_S = function(f) -- can be optimized
+ n = n + 1
+ if f and f ~= "" then
+ return format("format('%%%ss',tostring(a%s))",f,n)
+ else
+ return format("tostring(a%s)",n)
+ end
+end
+
+local format_right = function(f)
+ n = n + 1
+ f = tonumber(f)
+ if not f or f == 0 then
+ return format("(a%s or '')",n)
+ elseif f > 0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
+end
+
+local format_left = function(f)
+ n = n + 1
+ f = tonumber(f)
+ if not f or f == 0 then
+ return format("(a%s or '')",n)
+ end
+ if f < 0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
+end
+
+local format_q = function()
+ n = n + 1
+ -- lua 5.3 has a different q than lua 5.2 (which does a tostring on numbers)
+ -- return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
+ return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+ -- return format("(a%s ~= nil and escapedquotes(tostring(a%s)) or '')",n,n)
+end
+
+local format_Q = function() -- fast escaping
+ n = n + 1
+-- return format("format('%%q',tostring(a%s))",n)
+ return format("escapedquotes(tostring(a%s))",n)
+end
+
+local format_i = function(f)
+ n = n + 1
+ if f and f ~= "" then
+ return format("format('%%%si',a%s)",f,n)
+ else
+ return format("format('%%i',a%s)",n) -- why not just tostring()
+ end
+end
+
+local format_d = format_i
+
+local format_I = function(f)
+ n = n + 1
+ return format("format('%%s%%%si',signed(a%s))",f,n)
+end
+
+local format_f = function(f)
+ n = n + 1
+ return format("format('%%%sf',a%s)",f,n)
+end
+
+-- The next one formats an integer as integer and very small values as zero. This is needed
+-- for pdf backend code.
+--
+-- 1.23 % 1 : 0.23
+-- - 1.23 % 1 : 0.77
+--
+-- We could probably use just %s with integers but who knows what Lua 5.3 will do? So let's
+-- for the moment use %i.
+
+local format_F = function(f) -- beware, no cast to number
+ n = n + 1
+ if not f or f == "" then
+ return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
+ else
+ return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
+ end
+end
+
+-- if string.f9 then
+-- format_F = function(f) -- beware, no cast to number
+-- n = n + 1
+-- if not f or f == "" then
+-- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or FORMAT(a%s))",n,n,n,n,n)
+-- else
+-- return format("((a%s %% 1 == 0) and format('%%i',a%s) or FORMAT(a%s,'%%%sf'))",n,n,n,f)
+-- end
+-- end
+-- end
+
+local format_k = function(b,a) -- slow
+ n = n + 1
+ return format("formattedfloat(a%s,%s,%s)",n,b or 0,a or 0)
+end
+
+local format_g = function(f)
+ n = n + 1
+ return format("format('%%%sg',a%s)",f,n)
+end
+
+local format_G = function(f)
+ n = n + 1
+ return format("format('%%%sG',a%s)",f,n)
+end
+
+local format_e = function(f)
+ n = n + 1
+ return format("format('%%%se',a%s)",f,n)
+end
+
+local format_E = function(f)
+ n = n + 1
+ return format("format('%%%sE',a%s)",f,n)
+end
+
+local format_j = function(f)
+ n = n + 1
+ return format("sparseexponent('%%%se',a%s)",f,n)
+end
+
+local format_J = function(f)
+ n = n + 1
+ return format("sparseexponent('%%%sE',a%s)",f,n)
+end
+
+local format_x = function(f)
+ n = n + 1
+ return format("format('%%%sx',a%s)",f,n)
+end
+
+local format_X = function(f)
+ n = n + 1
+ return format("format('%%%sX',a%s)",f,n)
+end
+
+local format_o = function(f)
+ n = n + 1
+ return format("format('%%%so',a%s)",f,n)
+end
+
+local format_c = function()
+ n = n + 1
+ return format("utfchar(a%s)",n)
+end
+
+local format_C = function()
+ n = n + 1
+ return format("tracedchar(a%s)",n)
+end
+
+local format_r = function(f)
+ n = n + 1
+ return format("format('%%%s.0f',a%s)",f,n)
+end
+
+local format_h = function(f)
+ n = n + 1
+ if f == "-" then
+ f = sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ end
+end
+
+local format_H = function(f)
+ n = n + 1
+ if f == "-" then
+ f = sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ end
+end
+
+local format_u = function(f)
+ n = n + 1
+ if f == "-" then
+ f = sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ else
+ return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ end
+end
+
+local format_U = function(f)
+ n = n + 1
+ if f == "-" then
+ f = sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ else
+ return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f == "" and "05" or f,n,n,n)
+ end
+end
+
+local format_p = function()
+ n = n + 1
+ return format("points(a%s)",n)
+end
+
+local format_b = function()
+ n = n + 1
+ return format("basepoints(a%s)",n)
+end
+
+local format_t = function(f)
+ n = n + 1
+ if f and f ~= "" then
+ return format("concat(a%s,%q)",n,f)
+ else
+ return format("concat(a%s)",n)
+ end
+end
+
+local format_T = function(f)
+ n = n + 1
+ if f and f ~= "" then
+ return format("sequenced(a%s,%q)",n,f)
+ else
+ return format("sequenced(a%s)",n)
+ end
+end
+
+local format_l = function()
+ n = n + 1
+ return format("(a%s and 'true' or 'false')",n)
+end
+
+local format_L = function()
+ n = n + 1
+ return format("(a%s and 'TRUE' or 'FALSE')",n)
+end
+
+local format_n = function() -- strips leading and trailing zeros and removes .0
+ n = n + 1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+end
+
+-- local format_N = function() -- strips leading and trailing zeros (also accepts string)
+-- n = n + 1
+-- return format("tostring(tonumber(a%s) or a%s)",n,n)
+-- end
+
+-- local format_N = function(f) -- strips leading and trailing zeros
+-- n = n + 1
+-- -- stripzero (singular) as we only have a number
+-- if not f or f == "" then
+-- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or ((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%.9f',a%s)))",n,n,n,n,n)
+-- else
+-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+-- end
+-- end
+
+-- local format_N = function(f) -- strips leading and trailing zeros
+-- n = n + 1
+-- -- stripzero (singular) as we only have a number
+-- if not f or f == "" then
+-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or ((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or lpegmatch(stripzero,format('%%.9f',a%s)))",n,n,n,n,n)
+-- else
+-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+-- end
+-- end
+
+local format_N = function(f) -- strips leading and trailing zeros
+ n = n + 1
+ -- stripzero (singular) as we only have a number
+ if not f or f == "" then
+ f = ".9"
+ end -- always a leading number !
+ return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+end
+
+local format_a = function(f)
+ n = n + 1
+ if f and f ~= "" then
+ return format("autosingle(a%s,%q)",n,f)
+ else
+ return format("autosingle(a%s)",n)
+ end
+end
+
+local format_A = function(f)
+ n = n + 1
+ if f and f ~= "" then
+ return format("autodouble(a%s,%q)",n,f)
+ else
+ return format("autodouble(a%s)",n)
+ end
+end
+
+local format_w = function(f) -- handy when doing depth related indent
+ n = n + 1
+ f = tonumber(f)
+ if f then -- not that useful
+ return format("nspaces[%s+a%s]",f,n) -- no real need for tonumber
+ else
+ return format("nspaces[a%s]",n) -- no real need for tonumber
+ end
+end
+
+local format_W = function(f) -- handy when doing depth related indent
+ return format("nspaces[%s]",tonumber(f) or 0)
+end
+
+local format_m = function(f)
+ n = n + 1
+ if not f or f == "" then
+ f = ","
+ end
+ if f == "0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,".")]],n,f)
+ end
+end
+
+local format_M = function(f)
+ n = n + 1
+ if not f or f == "" then
+ f = "."
+ end
+ if f == "0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,",")]],n,f)
+ end
+end
+
+--
+
+local format_z = function(f)
+ n = n + (tonumber(f) or 1)
+ return "''" -- okay, not that efficient to append '' but a special case anyway
+end
+
+--
+
+-- local strip
+--
+-- local format_Z = function(f)
+-- n = n + 1
+-- if not f or f == "" then
+-- f = ".9"
+-- end
+-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or (strip and lpegmatch(stripzero,format('%%%sf',a%s))) or format('%%%sf',a%s))",n,n,f,n,f,n)
+-- end
+--
+-- function strings.stripformatterzeros()
+-- strip = true
+-- end
+
+-- add(formatters,"texexp", [[texexp(...)]], "local texexp = metapost.texexp")
+--
+-- add(formatters,"foo:bar",[[foo(...)]], { foo = function(...) print(...) return "!" end })
+-- print(string.formatters["foo %3!foo:bar! bar"](1,2,3))
+
+
+local format_rest = function(s)
+ return format("%q",s) -- catches " and \n and such
+end
+
+-- local format_extension = function(extensions,f,name)
+-- local extension = extensions[name] or "tostring(%s)"
+-- local f = tonumber(f) or 1
+-- local w = find(extension,"%.%.%.")
+-- if f == 0 then
+-- if w then
+-- extension = gsub(extension,"%.%.%.","")
+-- end
+-- return extension
+-- elseif f == 1 then
+-- if w then
+-- extension = gsub(extension,"%.%.%.","%%s")
+-- end
+-- n = n + 1
+-- local a = "a" .. n
+-- return format(extension,a,a) -- maybe more times?
+-- elseif f < 0 then
+-- local a = "a" .. (n + f + 1)
+-- return format(extension,a,a)
+-- else
+-- if w then
+-- extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+-- end
+-- -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
+-- -- cache we don't save much and there are hardly any extensions anyway
+-- local t = { }
+-- for i=1,f do
+-- n = n + 1
+-- -- t[#t+1] = "a" .. n
+-- t[i] = "a" .. n
+-- end
+-- return format(extension,unpack(t))
+-- end
+-- end
+
+local format_extension = function(extensions,f,name)
+ local extension = extensions[name] or "tostring(%s)"
+ local f = tonumber(f) or 1
+ local w = find(extension,"%.%.%.")
+ if w then
+ -- we have a wildcard
+ if f == 0 then
+ extension = gsub(extension,"%.%.%.","")
+ return extension
+ elseif f == 1 then
+ extension = gsub(extension,"%.%.%.","%%s")
+ n = n + 1
+ local a = "a" .. n
+ return format(extension,a,a) -- maybe more times?
+ elseif f < 0 then
+ local a = "a" .. (n + f + 1)
+ return format(extension,a,a)
+ else
+ extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+ -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
+ -- cache we don't save much and there are hardly any extensions anyway
+ local t = { }
+ for i=1,f do
+ n = n + 1
+ -- t[#t+1] = "a" .. n
+ t[i] = "a" .. n
+ end
+ return format(extension,unpack(t))
+ end
+ else
+ extension = gsub(extension,"%%s",function()
+ n = n + 1
+ return "a" .. n
+ end)
+ return extension
+ end
+end
+
+-- aA b cC d eE f gG hH iI jJ lL mM N o p qQ r sS tT uU wW xX z
+
+-- extensions : %!tag!
+
+-- can be made faster but not called that often
+
+local builder = Cs { "start",
+ start = (
+ (
+ P("%") / ""
+ * (
+ V("!") -- new
+ + V("s") + V("q")
+ + V("i") + V("d")
+ + V("f") + V("F") + V("g") + V("G") + V("e") + V("E")
+ + V("x") + V("X") + V("o")
+ --
+ + V("c")
+ + V("C")
+ + V("S") -- new
+ + V("Q") -- new
+ + V("n") -- new
+ + V("N") -- new
+ + V("k") -- new
+ --
+ + V("r")
+ + V("h") + V("H") + V("u") + V("U")
+ + V("p") + V("b")
+ + V("t") + V("T")
+ + V("l") + V("L")
+ + V("I")
+ + V("w") -- new
+ + V("W") -- new
+ + V("a") -- new
+ + V("A") -- new
+ + V("j") + V("J") -- stripped e E
+ + V("m") + V("M") -- new (formatted number)
+ + V("z") -- new
+ --
+ + V(">") -- left padding
+ + V("<") -- right padding
+ --
+ -- + V("?") -- ignored, probably messed up %
+ )
+ + V("*")
+ )
+ * (endofstring + Carg(1))
+ )^0,
+ --
+ ["s"] = (prefix_any * P("s")) / format_s, -- %s => regular %s (string)
+ ["q"] = (prefix_any * P("q")) / format_q, -- %q => regular %q (quoted string)
+ ["i"] = (prefix_any * P("i")) / format_i, -- %i => regular %i (integer)
+ ["d"] = (prefix_any * P("d")) / format_d, -- %d => regular %d (integer)
+ ["f"] = (prefix_any * P("f")) / format_f, -- %f => regular %f (float)
+ ["F"] = (prefix_any * P("F")) / format_F, -- %F => regular %f (float) but 0/1 check
+ ["g"] = (prefix_any * P("g")) / format_g, -- %g => regular %g (float)
+ ["G"] = (prefix_any * P("G")) / format_G, -- %G => regular %G (float)
+ ["e"] = (prefix_any * P("e")) / format_e, -- %e => regular %e (float)
+ ["E"] = (prefix_any * P("E")) / format_E, -- %E => regular %E (float)
+ ["x"] = (prefix_any * P("x")) / format_x, -- %x => regular %x (hexadecimal)
+ ["X"] = (prefix_any * P("X")) / format_X, -- %X => regular %X (HEXADECIMAL)
+ ["o"] = (prefix_any * P("o")) / format_o, -- %o => regular %o (octal)
+ --
+ ["S"] = (prefix_any * P("S")) / format_S, -- %S => %s (tostring)
+ ["Q"] = (prefix_any * P("Q")) / format_Q, -- %Q => %q (tostring)
+ ["n"] = (prefix_any * P("n")) / format_n, -- %n => tonumber (strips leading and trailing zeros, as well as .0, expects number)
+ ["N"] = (prefix_any * P("N")) / format_N, -- %N => tonumber (strips leading and trailing zeros, also takes string)
+ ["k"] = (prefix_sub * P("k")) / format_k, -- %k => like f but with n.m
+ ["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular)
+ ["C"] = (prefix_any * P("C")) / format_C, -- %c => U+.... utf character
+ --
+ ["r"] = (prefix_any * P("r")) / format_r, -- %r => round
+ ["h"] = (prefix_any * P("h")) / format_h, -- %h => 0x0a1b2 (when - no 0x) was v
+ ["H"] = (prefix_any * P("H")) / format_H, -- %H => 0x0A1B2 (when - no 0x) was V
+ ["u"] = (prefix_any * P("u")) / format_u, -- %u => u+0a1b2 (when - no u+)
+ ["U"] = (prefix_any * P("U")) / format_U, -- %U => U+0A1B2 (when - no U+)
+ ["p"] = (prefix_any * P("p")) / format_p, -- %p => 12.345pt / maybe: P (and more units)
+ ["b"] = (prefix_any * P("b")) / format_b, -- %b => 12.342bp / maybe: B (and more units)
+ ["t"] = (prefix_tab * P("t")) / format_t, -- %t => concat
+ ["T"] = (prefix_tab * P("T")) / format_T, -- %t => sequenced
+ ["l"] = (prefix_any * P("l")) / format_l, -- %l => boolean
+ ["L"] = (prefix_any * P("L")) / format_L, -- %L => BOOLEAN
+ ["I"] = (prefix_any * P("I")) / format_I, -- %I => signed integer
+ --
+ ["w"] = (prefix_any * P("w")) / format_w, -- %w => n spaces (optional prefix is added)
+ ["W"] = (prefix_any * P("W")) / format_W, -- %W => mandate prefix, no specifier
+ --
+ ["j"] = (prefix_any * P("j")) / format_j, -- %j => %e (float) stripped exponent (irrational)
+ ["J"] = (prefix_any * P("J")) / format_J, -- %J => %E (float) stripped exponent (irrational)
+ --
+ ["m"] = (prefix_any * P("m")) / format_m, -- %m => xxx.xxx.xxx,xx (optional prefix instead of .)
+ ["M"] = (prefix_any * P("M")) / format_M, -- %M => xxx,xxx,xxx.xx (optional prefix instead of ,)
+ --
+ ["z"] = (prefix_any * P("z")) / format_z, -- %z => skip n arguments
+ -- ["Z"] = (prefix_any * P("Z")) / format_Z, -- %Z => optionally strip zeros
+ --
+ ["a"] = (prefix_any * P("a")) / format_a, -- %a => '...' (forces tostring)
+ ["A"] = (prefix_any * P("A")) / format_A, -- %A => "..." (forces tostring)
+ --
+ ["<"] = (prefix_any * P("<")) / format_left,
+ [">"] = (prefix_any * P(">")) / format_right,
+ --
+ ["*"] = Cs(((1-P("%"))^1 + P("%%")/"%%")^1) / format_rest, -- rest (including %%)
+ ["?"] = Cs(((1-P("%"))^1 )^1) / format_rest, -- rest (including %%)
+ --
+ ["!"] = Carg(2) * prefix_any * P("!") * C((1-P("!"))^1) * P("!") / format_extension,
+}
+
+-- We can be clever and only alias what is needed:
+
+local xx = setmetatable({ }, { __index = function(t,k) local v = format("%02x",k) t[k] = v return v end })
+local XX = setmetatable({ }, { __index = function(t,k) local v = format("%02X",k) t[k] = v return v end })
+
+local preset = {
+ ["%02x"] = function(n) return xx[n] end,
+ ["%02X"] = function(n) return XX[n] end,
+}
+
+local direct =
+ P("%") * (sign + space + period + digit)^0 * S("sqidfgGeExXo") * endofstring
+ / [[local format = string.format return function(str) return format("%0",str) end]]
+
+local function make(t,str)
+ local f = preset[str]
+ if f then
+ return f
+ end
+ local p = lpegmatch(direct,str)
+ if p then
+ -- print("builder 1 >",p)
+ f = loadstripped(p)()
+ else
+ n = 0 -- used in patterns
+ -- p = lpegmatch(builder,str,1,"..",t._extensions_) -- after this we know n
+ p = lpegmatch(builder,str,1,t._connector_,t._extensions_) -- after this we know n
+ if n > 0 then
+ p = format(template,preamble,t._preamble_,arguments[n],p)
+ -- print("builder 2 >",p)
+ f = loadstripped(p,t._environment_)() -- t._environment is not populated (was experiment)
+ else
+ f = function() return str end
+ end
+ end
+ -- if jit then jit.on(f,true) end
+ t[str] = f
+ return f
+end
+
+-- -- collect periodically
+--
+-- local threshold = 1000 -- max nof cached formats
+--
+-- local function make(t,str)
+-- local f = rawget(t,str)
+-- if f then
+-- return f
+-- end
+-- local parent = t._t_
+-- if parent._n_ > threshold then
+-- local m = { _t_ = parent }
+-- getmetatable(parent).__index = m
+-- setmetatable(m, { __index = make })
+-- else
+-- parent._n_ = parent._n_ + 1
+-- end
+-- local f
+-- local p = lpegmatch(direct,str)
+-- if p then
+-- f = loadstripped(p)()
+-- else
+-- n = 0
+-- p = lpegmatch(builder,str,1,"..",parent._extensions_) -- after this we know n
+-- if n > 0 then
+-- p = format(template,preamble,parent._preamble_,arguments[n],p)
+-- -- print("builder>",p)
+-- f = loadstripped(p)()
+-- else
+-- f = function() return str end
+-- end
+-- end
+-- t[str] = f
+-- return f
+-- end
+
+local function use(t,fmt,...)
+ return t[fmt](...)
+end
+
+strings.formatters = { }
+
+-- we cannot make these tables weak, unless we start using an indirect
+-- table (metatable) in which case we could better keep a count and
+-- clear that table when a threshold is reached
+
+-- _connector_ is an experiment
+
+function strings.formatters.new(noconcat)
+ local e = { } -- better make a copy as we can overload
+ for k, v in next, environment do
+ e[k] = v
+ end
+ local t = {
+ _type_ = "formatter",
+ _connector_ = noconcat and "," or "..",
+ _extensions_ = { },
+ _preamble_ = "",
+ _environment_ = e,
+ }
+ setmetatable(t, { __index = make, __call = use })
+ return t
+end
+
+local formatters = strings.formatters.new() -- the default instance
+
+string.formatters = formatters -- in the main string namespace
+string.formatter = function(str,...) return formatters[str](...) end -- sometimes nicer name
+
+local function add(t,name,template,preamble)
+ if type(t) == "table" and t._type_ == "formatter" then
+ t._extensions_[name] = template or "%s"
+ if type(preamble) == "string" then
+ t._preamble_ = preamble .. "\n" .. t._preamble_ -- so no overload !
+ elseif type(preamble) == "table" then
+ for k, v in next, preamble do
+ t._environment_[k] = v
+ end
+ end
+ end
+end
+
+strings.formatters.add = add
+
+-- registered in the default instance (should we fall back on this one?)
+
+patterns.xmlescape = Cs((P("<")/"&lt;" + P(">")/"&gt;" + P("&")/"&amp;" + P('"')/"&quot;" + anything)^0)
+patterns.texescape = Cs((C(S("#$%\\{}"))/"\\%1" + anything)^0)
+patterns.luaescape = Cs(((1-S('"\n'))^1 + P('"')/'\\"' + P('\n')/'\\n"')^0) -- maybe also \0
+patterns.luaquoted = Cs(Cc('"') * ((1-S('"\n'))^1 + P('"')/'\\"' + P('\n')/'\\n"')^0 * Cc('"'))
+
+-- escaping by lpeg is faster for strings without quotes, slower on a string with quotes, but
+-- faster again when other q-escapables are found (the ones we don't need to escape)
+
+add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape = patterns.xmlescape })
+add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape = patterns.texescape })
+add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape = patterns.luaescape })
+
+-- -- yes or no:
+--
+-- local function make(t,str)
+-- local f
+-- local p = lpegmatch(direct,str)
+-- if p then
+-- f = loadstripped(p)()
+-- else
+-- n = 0
+-- p = lpegmatch(builder,str,1,",") -- after this we know n
+-- if n > 0 then
+-- p = format(template,template_shortcuts,arguments[n],p)
+-- f = loadstripped(p)()
+-- else
+-- f = function() return str end
+-- end
+-- end
+-- t[str] = f
+-- return f
+-- end
+--
+-- local formatteds = string.formatteds or { }
+-- string.formatteds = formatteds
+--
+-- setmetatable(formatteds, { __index = make, __call = use })
+
+-- This is a somewhat silly one used in commandline reconstruction but the older
+-- method, using a combination of fine, gsub, quoted and unquoted was not that
+-- reliable.
+--
+-- '"foo"bar \"and " whatever"' => "foo\"bar \"and \" whatever"
+-- 'foo"bar \"and " whatever' => "foo\"bar \"and \" whatever"
+
+local dquote = patterns.dquote -- P('"')
+local equote = patterns.escaped + dquote / '\\"' + 1
+local cquote = Cc('"')
+
+local pattern =
+ Cs(dquote * (equote - P(-2))^0 * dquote) -- we keep the outer but escape unescaped ones
+ + Cs(cquote * (equote - space)^0 * space * equote^0 * cquote) -- we escape unescaped ones
+
+function string.optionalquoted(str)
+ return lpegmatch(pattern,str) or str
+end
+
+local pattern = Cs((newline / (os.newline or "\r") + 1)^0)
+
+function string.replacenewlines(str)
+ return lpegmatch(pattern,str)
+end
+
+--
+
+function strings.newcollector()
+ local result, r = { }, 0
+ return
+ function(fmt,str,...) -- write
+ r = r + 1
+ result[r] = str == nil and fmt or formatters[fmt](str,...)
+ end,
+ function(connector) -- flush
+ if result then
+ local str = concat(result,connector)
+ result, r = { }, 0
+ return str
+ end
+ end
+end
+
+--
+
+local f_16_16 = formatters["%0.5N"]
+
+function number.to16dot16(n)
+ return f_16_16(n/65536.0)
+end
+
+--
+
+if not string.explode then
+
+ local tsplitat = lpeg.tsplitat
+
+ local p_utf = patterns.utf8character
+ local p_check = C(p_utf) * (P("+") * Cc(true))^0
+ local p_split = Ct(C(p_utf)^0)
+ local p_space = Ct((C(1-P(" ")^1) + P(" ")^1)^0)
+
+ function string.explode(str,symbol)
+ if symbol == "" then
+ return lpegmatch(p_split,str)
+ elseif symbol then
+ local a, b = lpegmatch(p_check,symbol)
+ if b then
+ return lpegmatch(tsplitat(P(a)^1),str)
+ else
+ return lpegmatch(tsplitat(a),str)
+ end
+ else
+ return lpegmatch(p_space,str)
+ end
+ end
+
+end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
new file mode 100644
index 0000000000..3e3283b5ff
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
@@ -0,0 +1,851 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-auxiliary.lua
+-- DESCRIPTION: part of luaotfload
+-- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-auxiliary",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / auxiliary functions",
+ license = "GPL v2.0"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+
+luaotfload = luaotfload or { }
+local log = luaotfload.log
+local logreport = log.report
+local fonthashes = fonts.hashes
+local encodings = fonts.encodings
+local identifiers = fonthashes.identifiers
+local fontnames = fonts.names
+
+local fontid = font.id
+local texsprint = tex.sprint
+
+local dofile = dofile
+local getmetatable = getmetatable
+local setmetatable = setmetatable
+local utfcodepoint = utf8.codepoint
+local stringlower = string.lower
+local stringformat = string.format
+local stringgsub = string.gsub
+local stringbyte = string.byte
+local stringfind = string.find
+local tablecopy = table.copy
+
+local aux = { }
+local luaotfload_callbacks = { }
+
+-----------------------------------------------------------------------
+--- font patches
+-----------------------------------------------------------------------
+
+--- https://github.com/khaledhosny/luaotfload/issues/54
+
+local function rewrite_fontname(tfmdata, specification)
+ local format = tfmdata.format or tfmdata.properties.format
+ if stringfind (specification, " ") then
+ tfmdata.name = stringformat ("%q", specification)
+ else
+ --- other specs should parse just fine
+ tfmdata.name = specification
+ end
+end
+
+local rewriting = false
+
+function aux.start_rewrite_fontname()
+ if rewriting == false then
+ luatexbase.add_to_callback (
+ "luaotfload.patch_font",
+ rewrite_fontname,
+ "luaotfload.rewrite_fontname")
+ rewriting = true
+ logreport ("log", 1, "aux",
+ "start rewriting tfmdata.name field")
+ end
+end
+
+function aux.stop_rewrite_fontname()
+ if rewriting == true then
+ luatexbase.remove_from_callback
+ ("luaotfload.patch_font", "luaotfload.rewrite_fontname")
+ rewriting = false
+ logreport ("log", 1, "aux",
+ "stop rewriting tfmdata.name field")
+ end
+end
+
+
+--[[doc--
+This sets two dimensions apparently relied upon by the unicode-math
+package.
+--doc]]--
+
+local function set_sscale_dimens(fontdata)
+ local resources = fontdata.resources if not resources then return end
+ local mathconstants = resources.MathConstants if not mathconstants then return end
+ local parameters = fontdata.parameters if not parameters then return end
+ --- the default values below are complete crap
+ parameters [10] = mathconstants.ScriptPercentScaleDown or 70
+ parameters [11] = mathconstants.ScriptScriptPercentScaleDown or 50
+end
+
+luaotfload_callbacks [#luaotfload_callbacks + 1] = {
+ "patch_font", set_sscale_dimens, "set_sscale_dimens",
+}
+
+local default_units = 1000
+
+--- fontobj -> int
+local function lookup_units(fontdata)
+ local units = fontdata.units
+ if units and units > 0 then return units end
+ local shared = fontdata.shared if not shared then return default_units end
+ local rawdata = shared.rawdata if not rawdata then return default_units end
+ local metadata = rawdata.metadata if not metadata then return default_units end
+ local capheight = metadata.capheight if not capheight then return default_units end
+ local units = metadata.units or fontdata.units
+ if not units or units == 0 then
+ return default_units
+ end
+ return units
+end
+
+--[[doc--
+This callback corrects some values of the Cambria font.
+--doc]]--
+--- fontobj -> unit
+local function patch_cambria_domh(fontdata)
+ local mathconstants = fontdata.MathConstants
+ if mathconstants and fontdata.psname == "CambriaMath" then
+ --- my test Cambria has 2048
+ local units = fontdata.units or lookup_units(fontdata)
+ local sz = fontdata.parameters.size or fontdata.size
+ local mh = 2800 / units * sz
+ if mathconstants.DisplayOperatorMinHeight < mh then
+ mathconstants.DisplayOperatorMinHeight = mh
+ end
+ end
+end
+
+luaotfload_callbacks [#luaotfload_callbacks + 1] = {
+ "patch_font", patch_cambria_domh, "patch_cambria_domh",
+}
+
+
+--[[doc--
+
+ Add missing field to fonts that lack it. Addresses issue
+ https://github.com/lualatex/luaotfload/issues/253
+
+ This is considered a hack, especially since importing the
+ unicode-math package fixes the problem quite nicely.
+
+--doc]]--
+
+--- fontobj -> unit
+local function fixup_fontdata(data)
+ local t = type (data)
+ --- Some OT fonts like Libertine R lack the resources table, causing
+ --- the fontloader to nil-index.
+ if t == "table" then
+ if data and not data.resources then data.resources = { } end
+ end
+end
+
+luaotfload_callbacks [#luaotfload_callbacks + 1] = {
+ "patch_font_unsafe", fixup_fontdata, "fixup_fontdata",
+}
+
+
+--[[doc--
+
+Comment from fontspec:
+
+ “Here we patch fonts tfm table to emulate \XeTeX's \cs{fontdimen8},
+ which stores the caps-height of the font. (Cf.\ \cs{fontdimen5} which
+ stores the x-height.)
+
+ Falls back to measuring the glyph if the font doesn't contain the
+ necessary information.
+ This needs to be extended for fonts that don't contain an `X'.â€
+
+--doc]]--
+
+local capheight_reference_chars = { "X", "M", "Ж", "ξ", }
+local capheight_reference_codepoints do
+ capheight_reference_codepoints = { }
+ for i = 1, #capheight_reference_chars do
+ local chr = capheight_reference_chars [i]
+ capheight_reference_codepoints [i] = utfcodepoint (chr)
+ end
+end
+
+local function determine_capheight(fontdata)
+ local parameters = fontdata.parameters if not parameters then return false end
+ local characters = fontdata.characters if not characters then return false end
+ --- Pretty simplistic but it does return *some* value for most fonts;
+ --- we could also refine the approach to return some kind of average
+ --- of all capital letters or a user-provided subset.
+ for i = 1, #capheight_reference_codepoints do
+ local refcp = capheight_reference_codepoints [i]
+ local refchar = characters [refcp]
+ if refchar then
+ logreport ("both", 4, "aux",
+ "picked height of character ‘%s’ (U+%d) as \\fontdimen8 \z
+ candidate",
+ capheight_reference_chars [i], refcp)
+ return refchar.height
+ end
+ end
+ return false
+end
+
+local function query_ascender(fontdata)
+ local parameters = fontdata.parameters if not parameters then return false end
+ local ascender = parameters.ascender
+ if ascender then
+ return ascender --- pre-scaled
+ end
+
+ local shared = fontdata.shared if not shared then return false end
+ local rawdata = shared.rawdata if not rawdata then return false end
+ local metadata = rawdata.metadata if not metadata then return false end
+ ascender = metadata.ascender if not ascender then return false end
+ local size = parameters.size if not size then return false end
+ local units = lookup_units (fontdata)
+ if not units or units == 0 then return false end
+ return ascender * size / units --- scaled
+end
+
+local function query_capheight(fontdata)
+ local parameters = fontdata.parameters if not parameters then return false end
+ local shared = fontdata.shared if not shared then return false end
+ local rawdata = shared.rawdata if not rawdata then return false end
+ local metadata = rawdata.metadata if not metadata then return false end
+ local capheight = metadata.capheight if not capheight then return false end
+ local size = parameters.size if not size then return false end
+ local units = lookup_units (fontdata)
+ if not units or units == 0 then return false end
+ return capheight * size / units
+end
+
+local function query_fontdimen8(fontdata)
+ local parameters = fontdata.parameters if not parameters then return false end
+ local fontdimen8 = parameters [8]
+ if fontdimen8 then return fontdimen8 end
+ return false
+end
+
+local function caphtfmt(ref, ht)
+ if not ht then return "<none>" end
+ if not ref then return tostring (ht) end
+ return stringformat ("%s(δ=%s)", ht, ht - ref)
+end
+
+local function set_capheight(fontdata)
+ if not fontdata then
+ logreport ("both", 0, "aux",
+ "error: set_capheight() received garbage")
+ return
+ end
+ local capheight_dimen8 = query_fontdimen8 (fontdata)
+ local capheight_alleged = query_capheight (fontdata)
+ local capheight_ascender = query_ascender (fontdata)
+ local capheight_measured = determine_capheight (fontdata)
+ logreport ("term", 4, "aux",
+ "capht: param[8]=%s advertised=%s ascender=%s measured=%s",
+ tostring (capheight_dimen8),
+ caphtfmt (capheight_dimen8, capheight_alleged),
+ caphtfmt (capheight_dimen8, capheight_ascender),
+ caphtfmt (capheight_dimen8, capheight_measured))
+ if capheight_dimen8 then --- nothing to do
+ return
+ end
+
+ local capheight = capheight_alleged or capheight_ascender or capheight_measured
+ if capheight then
+ fontdata.parameters [8] = capheight
+ end
+end
+
+luaotfload_callbacks [#luaotfload_callbacks + 1] = {
+ "patch_font", set_capheight, "set_capheight",
+}
+
+-- Of course there are also fonts with no sensible x-height, so let's add a
+-- fallback there:
+local function set_xheight(tfmdata)
+ local parameters = tfmdata.parameters
+ if not parameters then return end
+ if not (parameters.x_height or parameters[5] or 0) == 0 then return end
+ if tfmdata.characters and tfmdata.characters[120] then
+ parameters.x_height = tfmdata.characters[120].height
+ else
+ parameters.x_height = (parameters.ascender or 0)/2
+ end
+end
+luaotfload_callbacks [#luaotfload_callbacks + 1] = {
+ "patch_font", set_xheight, "set_xheight",
+}
+-----------------------------------------------------------------------
+--- glyphs and characters
+-----------------------------------------------------------------------
+
+--- int -> int -> bool
+function aux.font_has_glyph(font_id, codepoint)
+ local fontdata = fonts.hashes.identifiers[font_id]
+ if fontdata then
+ if fontdata.characters[codepoint] ~= nil then return true end
+ end
+ return false
+end
+
+--- undocumented
+
+local function raw_slot_of_name(font_id, glyphname)
+ local fontdata = font.fonts[font_id]
+ if fontdata.type == "virtual" then --- get base font for glyph idx
+ local codepoint = encodings.agl.unicodes[glyphname]
+ local glyph = fontdata.characters[codepoint]
+ if fontdata.characters[codepoint] then
+ return codepoint
+ end
+ end
+ return false
+end
+
+--[[doc--
+
+ This one is approximately “name_to_slot†from the microtype package;
+ note that it is all about Adobe Glyph names and glyph slots in the
+ font. The names and values may diverge from actual Unicode.
+
+ http://www.adobe.com/devnet/opentype/archives/glyph.html
+
+ The “unsafe†switch triggers a fallback lookup in the raw fonts
+ table. As some of the information is stored as references, this may
+ have unpredictable side-effects.
+
+--doc]]--
+
+--- int -> string -> bool -> (int | false)
+function aux.slot_of_name(font_id, glyphname, unsafe)
+ if not font_id or type (font_id) ~= "number"
+ or not glyphname or type (glyphname) ~= "string"
+ then
+ logreport ("both", 0, "aux",
+ "invalid parameters to slot_of_name (%s, %s)",
+ tostring (font_id), tostring (glyphname))
+ return false
+ end
+
+ local tfmdata = identifiers [font_id]
+ if not tfmdata then return raw_slot_of_name (font_id, glyphname) end
+ local resources = tfmdata.resources if not resources then return false end
+ local unicodes = resources.unicodes if not unicodes then return false end
+
+ local unicode = unicodes [glyphname]
+ if unicode then
+ if type (unicode) == "number" then
+ return unicode
+ else
+ return unicode [1] --- for multiple components
+ end
+ end
+ return false
+end
+
+--[[doc--
+
+ Inverse of above; not authoritative as to my knowledge the official
+ inverse of the AGL is the AGLFN. Maybe this whole issue should be
+ dealt with in a separate package that loads char-def.lua and thereby
+ solves the problem for the next couple decades.
+
+ http://partners.adobe.com/public/developer/en/opentype/aglfn13.txt
+
+--doc]]--
+
+local indices
+
+--- int -> (string | false)
+function aux.name_of_slot(codepoint)
+ if not codepoint or type (codepoint) ~= "number" then
+ logreport ("both", 0, "aux",
+ "invalid parameters to name_of_slot (%s)",
+ tostring (codepoint))
+ return false
+ end
+
+ if not indices then --- this will load the glyph list
+ local unicodes = encodings.agl.unicodes
+ if not unicodes or not next (unicodes)then
+ logreport ("both", 0, "aux",
+ "name_of_slot: failed to load the AGL.")
+ end
+ indices = table.swapped (unicodes)
+ end
+
+ local glyphname = indices [codepoint]
+ if glyphname then
+ return glyphname
+ end
+ return false
+end
+
+-----------------------------------------------------------------------
+--- features / scripts / languages
+-----------------------------------------------------------------------
+--- lots of arrowcode ahead
+
+local function get_features(tfmdata)
+ local resources = tfmdata.resources if not resources then return false end
+ local features = resources.features if not features then return false end
+ return features
+end
+
+--[[doc--
+This function, modeled after “check_script()†from fontspec, returns
+true if in the given font, the script “asked_script†is accounted for in at
+least one feature.
+--doc]]--
+
+--- int -> string -> bool
+function aux.provides_script(font_id, asked_script)
+ if not font_id or type (font_id) ~= "number"
+ or not asked_script or type (asked_script) ~= "string"
+ then
+ logreport ("both", 0, "aux",
+ "invalid parameters to provides_script(%s, %s)",
+ tostring (font_id), tostring (asked_script))
+ return false
+ end
+ asked_script = stringlower(asked_script)
+ if font_id and font_id > 0 then
+ local tfmdata = identifiers[font_id]
+ if not tfmdata then return false end
+ local features = get_features (tfmdata)
+ if features == false then
+ logreport ("log", 1, "aux", "font no %d lacks a features table", font_id)
+ return false
+ end
+ for method, featuredata in next, features do
+ --- where method: "gpos" | "gsub"
+ for feature, data in next, featuredata do
+ if data[asked_script] then
+ logreport ("log", 1, "aux",
+ "font no %d (%s) defines feature %s for script %s",
+ font_id, fontname, feature, asked_script)
+ return true
+ end
+ end
+ end
+ logreport ("log", 0, "aux",
+ "font no %d (%s) defines no feature for script %s",
+ font_id, fontname, asked_script)
+ end
+ logreport ("log", 0, "aux", "no font with id %d", font_id)
+ return false
+end
+
+--[[doc--
+This function, modeled after “check_language()†from fontspec, returns
+true if in the given font, the language with tage “asked_language†is
+accounted for in the script with tag “asked_script†in at least one
+feature.
+--doc]]--
+
+--- int -> string -> string -> bool
+function aux.provides_language(font_id, asked_script, asked_language)
+ if not font_id or type (font_id) ~= "number"
+ or not asked_script or type (asked_script) ~= "string"
+ or not asked_language or type (asked_language) ~= "string"
+ then
+ logreport ("both", 0, "aux",
+ "invalid parameters to provides_language(%s, %s, %s)",
+ tostring (font_id),
+ tostring (asked_script),
+ tostring (asked_language))
+ return false
+ end
+ asked_script = stringlower(asked_script)
+ asked_language = stringlower(asked_language)
+ if font_id and font_id > 0 then
+ local tfmdata = identifiers[font_id]
+ if not tfmdata then return false end
+ local features = get_features (tfmdata)
+ if features == false then
+ logreport ("log", 1, "aux", "font no %d lacks a features table", font_id)
+ return false
+ end
+ for method, featuredata in next, features do
+ --- where method: "gpos" | "gsub"
+ for feature, data in next, featuredata do
+ local scriptdata = data[asked_script]
+ if scriptdata and scriptdata[asked_language] then
+ logreport ("log", 1, "aux",
+ "font no %d (%s) defines feature %s "
+ .. "for script %s with language %s",
+ font_id, fontname, feature,
+ asked_script, asked_language)
+ return true
+ end
+ end
+ end
+ logreport ("log", 0, "aux",
+ "font no %d (%s) defines no feature "
+ .. "for script %s with language %s",
+ font_id, fontname, asked_script, asked_language)
+ end
+ logreport ("log", 0, "aux", "no font with id %d", font_id)
+ return false
+end
+
+--[[doc--
+We strip the syntax elements from feature definitions (shouldn’t
+actually be there in the first place, but who cares ...)
+--doc]]--
+
+local lpeg = require"lpeg"
+local C, P, S = lpeg.C, lpeg.P, lpeg.S
+local lpegmatch = lpeg.match
+
+local sign = S"+-"
+local rhs = P"=" * P(1)^0 * P(-1)
+local strip_garbage = sign^-1 * C((1 - rhs)^1)
+
+--s = "+foo" --> foo
+--ss = "-bar" --> bar
+--sss = "baz" --> baz
+--t = "foo=bar" --> foo
+--tt = "+bar=baz" --> bar
+--ttt = "-baz=true" --> baz
+--
+--print(lpeg.match(strip_garbage, s))
+--print(lpeg.match(strip_garbage, ss))
+--print(lpeg.match(strip_garbage, sss))
+--print(lpeg.match(strip_garbage, t))
+--print(lpeg.match(strip_garbage, tt))
+--print(lpeg.match(strip_garbage, ttt))
+
+--[[doc--
+This function, modeled after “check_feature()†from fontspec, returns
+true if in the given font, the language with tag “asked_language†is
+accounted for in the script with tag “asked_script†in feature
+“asked_featureâ€.
+--doc]]--
+
+--- int -> string -> string -> string -> bool
+function aux.provides_feature(font_id, asked_script,
+ asked_language, asked_feature)
+ if not font_id or type (font_id) ~= "number"
+ or not asked_script or type (asked_script) ~= "string"
+ or not asked_language or type (asked_language) ~= "string"
+ or not asked_feature or type (asked_feature) ~= "string"
+ then
+ logreport ("both", 0, "aux",
+ "invalid parameters to provides_feature(%s, %s, %s, %s)",
+ tostring (font_id), tostring (asked_script),
+ tostring (asked_language), tostring (asked_feature))
+ return false
+ end
+ asked_script = stringlower(asked_script)
+ asked_language = stringlower(asked_language)
+ asked_feature = lpegmatch(strip_garbage, asked_feature)
+
+ if font_id > 0 then
+ local tfmdata = identifiers[font_id]
+ if not tfmdata then return false end
+ local features = get_features (tfmdata)
+ if features == false then
+ logreport ("log", 1, "aux", "font no %d lacks a features table", font_id)
+ return false
+ end
+ for method, featuredata in next, features do
+ --- where method: "gpos" | "gsub"
+ local feature = featuredata[asked_feature]
+ if feature then
+ local scriptdata = feature[asked_script]
+ if scriptdata and scriptdata[asked_language] then
+ logreport ("log", 1, "aux",
+ "font no %d (%s) defines feature %s "
+ .. "for script %s with language %s",
+ font_id, fontname, asked_feature,
+ asked_script, asked_language)
+ return true
+ end
+ end
+ end
+ logreport ("log", 0, "aux",
+ "font no %d (%s) does not define feature %s for script %s with language %s",
+ font_id, fontname, asked_feature, asked_script, asked_language)
+ end
+ logreport ("log", 0, "aux", "no font with id %d", font_id)
+ return false
+end
+
+-----------------------------------------------------------------------
+--- font dimensions
+-----------------------------------------------------------------------
+
+--- int -> string -> int
+local function get_math_dimension(font_id, dimenname)
+ if type(font_id) == "string" then
+ font_id = fontid(font_id) --- safeguard
+ end
+ local fontdata = identifiers[font_id]
+ local mathdata = fontdata.mathparameters
+ if mathdata then
+ return mathdata[dimenname] or 0
+ end
+ return 0
+end
+
+aux.get_math_dimension = get_math_dimension
+
+--- int -> string -> unit
+function aux.sprint_math_dimension(font_id, dimenname)
+ if type(font_id) == "string" then
+ font_id = fontid(font_id)
+ end
+ local dim = get_math_dimension(font_id, dimenname)
+ texsprint(luatexbase.catcodetables["latex-package"], dim, "sp")
+end
+
+-----------------------------------------------------------------------
+--- extra database functions
+-----------------------------------------------------------------------
+
+--[====[-- TODO -> port this to new db model
+
+--- local directories -------------------------------------------------
+
+--- migrated from luaotfload-database.lua
+--- https://github.com/lualatex/luaotfload/pull/61#issuecomment-17776975
+
+--- string -> (int * int)
+local scan_external_dir = function (dir)
+ local old_names, new_names = names.data()
+ if not old_names then
+ old_names = load_names()
+ end
+ new_names = tablecopy(old_names)
+ local n_scanned, n_new = scan_dir(dir, old_names, new_names)
+ --- FIXME
+ --- This doesn’t seem right. If a db update is triggered after this
+ --- point, then the added fonts will be saved along with it --
+ --- which is not as “temporarily†as it should be. (This should be
+ --- addressed during a refactoring of names_resolve().)
+ names.data = new_names
+ return n_scanned, n_new
+end
+
+aux.scan_external_dir = scan_external_dir
+
+--]====]--
+
+function aux.scan_external_dir()
+ print "ERROR: scan_external_dir() is not implemented"
+end
+
+--- db queries --------------------------------------------------------
+
+--- https://github.com/lualatex/luaotfload/issues/74
+--- string -> (string * int)
+local function resolve_fontname(name)
+ local foundname, subfont = luaotfload.resolvers.name {
+ name = name,
+ specification = "name:" .. name,
+ }
+ if foundname then
+ return foundname, subfont
+ end
+ return false, false
+end
+
+aux.resolve_fontname = resolve_fontname
+
+--- string list -> (string * int)
+function aux.resolve_fontlist(names)
+ for n = 1, #names do
+ local foundname, subfont = resolve_fontname(this)
+ if foundname then
+ return foundname, subfont
+ end
+ end
+ return false, false
+end
+
+--- index access ------------------------------------------------------
+
+--- Based on a discussion on the Luatex mailing list:
+--- http://tug.org/pipermail/luatex/2014-June/004881.html
+
+--[[doc--
+
+ aux.read_font_index -- Read the names index from the canonical
+ location and return its contents. This does not affect the behavior
+ of Luaotfload: The returned table is independent of what the font
+ resolvers use internally. Access is raw: each call to the function
+ will result in the entire table being re-read from disk.
+
+--doc]]--
+
+local load_names = fontnames.load
+local access_font_index = fontnames.access_font_index
+
+function aux.read_font_index()
+ return load_names (true) or { }
+end
+
+--[[doc--
+
+ aux.font_index -- Access Luaotfload’s internal database. If the
+ database hasn’t been loaded yet this will cause it to be loaded, with
+ all the possible side-effects like for instance creating the index
+ file if it doesn’t exist, reading all font files, &c.
+
+--doc]]--
+
+function aux.font_index() return access_font_index () end
+
+
+--- loaded fonts ------------------------------------------------------
+
+--- just a proof of concept
+
+--- fontobj -> string list -> (string list) list
+local function get_font_data (tfmdata, keys)
+ local acc = {}
+ for n = 1, #keys do
+ acc[n] = tfmdata[keys[n]] or false
+ end
+ return acc
+end
+
+--[[doc--
+
+ The next one operates on the fonts.hashes.identifiers table.
+ It returns a list containing tuples of font ids and the
+ contents of the fields specified in the first argument.
+ Font table entries that were created indirectly -- e.g. by
+ \letterspacefont or during font expansion -- will not be
+ listed.
+
+--doc]]--
+
+local default_keys = { "fullname" }
+
+--- string list -> (int * string list) list
+function aux.get_loaded_fonts (keys)
+ keys = keys or default_keys
+ local acc = {}
+ for id, tfmdata in pairs(identifiers) do
+ local data = get_font_data(tfmdata, keys)
+ acc[#acc+1] = { id, data }
+ end
+ return acc
+end
+
+--- Raw access to the font.* namespace is unsafe so no documentation on
+--- this one.
+function aux.get_raw_fonts ()
+ local res = { }
+ for i, v in font.each() do
+ if v.filename then
+ res[#res+1] = { i, v }
+ end
+ end
+ return res
+end
+
+-----------------------------------------------------------------------
+--- font parameters
+-----------------------------------------------------------------------
+--- analogy of font-hsh
+
+fonthashes.parameters = fonthashes.parameters or { }
+fonthashes.quads = fonthashes.quads or { }
+
+local parameters = fonthashes.parameters or { }
+local quads = fonthashes.quads or { }
+
+setmetatable(parameters, { __index = function (t, font_id)
+ local tfmdata = identifiers[font_id]
+ if not tfmdata then --- unsafe; avoid
+ tfmdata = font.fonts[font_id]
+ end
+ if tfmdata and type(tfmdata) == "table" then
+ local fontparameters = tfmdata.parameters
+ t[font_id] = fontparameters
+ return fontparameters
+ end
+ return nil
+end})
+
+--[[doc--
+
+ Note that the reason as to why we prefer functions over table indices
+ is that functions are much safer against unintended manipulation.
+ This justifies the overhead they cost.
+
+--doc]]--
+
+--- int -> (number | false)
+function aux.get_quad(font_id)
+ local quad = quads[font_id]
+ if quad then
+ return quad
+ end
+ local fontparameters = parameters[font_id]
+ if fontparameters then
+ local quad = fontparameters.quad or 0
+ quads[font_id] = quad
+ return quad
+ end
+ return false
+end
+
+-----------------------------------------------------------------------
+--- initialization
+-----------------------------------------------------------------------
+
+local function inject_callbacks (lst)
+ if not lst and next (lst) then return false end
+
+ local inject = function (def)
+ local cb, fn, id = unpack (def)
+ cb = tostring (cb)
+ id = tostring (id)
+ if not cb or not fn or not id or not type (fn) == "function" then
+ logreport ("both", 0, "aux", "Invalid callback requested (%q, %s, %q).",
+ cb, tostring (fn), id)
+ return false
+ end
+ cb = stringformat ("luaotfload.%s", cb)
+ id = stringformat ("luaotfload.aux.%s", id)
+ logreport ("log", 5, "aux", "Installing callback %q->%q.", cb, id)
+ luatexbase.add_to_callback (cb, fn, id)
+ return true
+ end
+
+ local ret = true
+ for i = 1, #lst do ret = inject (lst [i]) end
+ return ret
+end
+
+return function ()
+ luaotfload.aux = aux
+ return inject_callbacks (luaotfload_callbacks)
+end
+
+-- vim:tw=79:sw=2:ts=8:et
+
diff --git a/macros/luatex/generic/luaotfload/luaotfload-blacklist.cnf b/macros/luatex/generic/luaotfload/luaotfload-blacklist.cnf
new file mode 100644
index 0000000000..e82669b9f8
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-blacklist.cnf
@@ -0,0 +1,4 @@
+spltfgbd.ttf
+spltfgbi.ttf
+spltfgit.ttf
+spltfgrg.ttf
diff --git a/macros/luatex/generic/luaotfload/luaotfload-characters.lua b/macros/luatex/generic/luaotfload/luaotfload-characters.lua
new file mode 100644
index 0000000000..ded3b3eaf0
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-characters.lua
@@ -0,0 +1,203947 @@
+return {
+ [0x0]={
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x2,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x3,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x4,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x5,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x6,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x7,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x8,
+ },
+ {
+ category="cc",
+ direction="s",
+ linebreak="ba",
+ unicodeslot=0x9,
+ },
+ {
+ category="cc",
+ direction="b",
+ linebreak="lf",
+ unicodeslot=0xA,
+ },
+ {
+ category="cc",
+ direction="s",
+ linebreak="bk",
+ unicodeslot=0xB,
+ },
+ {
+ category="cc",
+ direction="ws",
+ linebreak="bk",
+ unicodeslot=0xC,
+ },
+ {
+ category="cc",
+ direction="b",
+ linebreak="cr",
+ unicodeslot=0xD,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xF,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x10,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x11,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x12,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x13,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x14,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x15,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x16,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x17,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x18,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x19,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1A,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1B,
+ },
+ {
+ category="cc",
+ direction="b",
+ linebreak="cm",
+ unicodeslot=0x1C,
+ },
+ {
+ category="cc",
+ direction="b",
+ linebreak="cm",
+ unicodeslot=0x1D,
+ },
+ {
+ category="cc",
+ direction="b",
+ linebreak="cm",
+ unicodeslot=0x1E,
+ },
+ {
+ category="cc",
+ direction="s",
+ linebreak="cm",
+ unicodeslot=0x1F,
+ },
+ {
+ category="zs",
+ direction="ws",
+ linebreak="sp",
+ unicodeslot=0x20,
+ },
+ {
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x21,
+ },
+ {
+ category="po",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x22,
+ },
+ {
+ category="po",
+ direction="et",
+ linebreak="al",
+ unicodeslot=0x23,
+ },
+ {
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x24,
+ },
+ {
+ category="po",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x25,
+ },
+ {
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26,
+ },
+ {
+ category="po",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x27,
+ },
+ {
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x29,
+ textclass="open",
+ unicodeslot=0x28,
+ },
+ {
+ category="pe",
+ direction="on",
+ linebreak="cp",
+ mirror=0x28,
+ textclass="close",
+ unicodeslot=0x29,
+ },
+ {
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A,
+ },
+ {
+ category="sm",
+ direction="es",
+ linebreak="pr",
+ unicodeslot=0x2B,
+ },
+ {
+ category="po",
+ direction="cs",
+ linebreak="is",
+ unicodeslot=0x2C,
+ },
+ {
+ category="pd",
+ direction="es",
+ linebreak="hy",
+ unicodeslot=0x2D,
+ },
+ {
+ category="po",
+ direction="cs",
+ linebreak="is",
+ unicodeslot=0x2E,
+ },
+ {
+ category="po",
+ direction="cs",
+ linebreak="sy",
+ unicodeslot=0x2F,
+ },
+ {
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x30,
+ },
+ {
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x31,
+ },
+ {
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x32,
+ },
+ {
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x33,
+ },
+ {
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x34,
+ },
+ {
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x35,
+ },
+ {
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x36,
+ },
+ {
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x37,
+ },
+ {
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x38,
+ },
+ {
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x39,
+ },
+ {
+ category="po",
+ direction="cs",
+ linebreak="is",
+ unicodeslot=0x3A,
+ },
+ {
+ category="po",
+ direction="on",
+ linebreak="is",
+ unicodeslot=0x3B,
+ },
+ {
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x3E,
+ textclass="open",
+ unicodeslot=0x3C,
+ },
+ {
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x3D,
+ },
+ {
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x3C,
+ textclass="close",
+ unicodeslot=0x3E,
+ },
+ {
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x3F,
+ },
+ {
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x40,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x41,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x42,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x43,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x44,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x45,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x46,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x47,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x48,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x49,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4A,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4B,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4C,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4E,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x50,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x51,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x52,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x53,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x54,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x55,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x56,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x57,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x58,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x59,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x5A,
+ },
+ {
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x5D,
+ textclass="open",
+ unicodeslot=0x5B,
+ },
+ {
+ category="po",
+ direction="on",
+ linebreak="pr",
+ unicodeslot=0x5C,
+ },
+ {
+ category="pe",
+ direction="on",
+ linebreak="cp",
+ mirror=0x5B,
+ textclass="close",
+ unicodeslot=0x5D,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x5E,
+ },
+ {
+ category="pc",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x5F,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x60,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x61,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x62,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x63,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x64,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x65,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x66,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x67,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x68,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x69,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x6A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x6B,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x6C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x6D,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x6E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x6F,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x70,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x71,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x72,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x73,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x74,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x75,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x76,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x77,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x78,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x79,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x7A,
+ },
+ {
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x7D,
+ textclass="open",
+ unicodeslot=0x7B,
+ },
+ {
+ category="sm",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x7C,
+ },
+ {
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x7B,
+ textclass="close",
+ unicodeslot=0x7D,
+ },
+ {
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x7E,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x7F,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x80,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x81,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x82,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x83,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x84,
+ },
+ {
+ category="cc",
+ direction="b",
+ linebreak="nl",
+ unicodeslot=0x85,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x86,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x87,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x88,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x89,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x8A,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x8B,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x8C,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x8D,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x8E,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x8F,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x90,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x91,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x92,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x93,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x94,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x95,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x96,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x97,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x98,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x99,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x9A,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x9B,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x9C,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x9D,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x9E,
+ },
+ {
+ category="cc",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x9F,
+ },
+ {
+ category="zs",
+ direction="cs",
+ linebreak="gl",
+ specials={ "nobreak", 0x20 },
+ unicodeslot=0xA0,
+ },
+ {
+ category="po",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0xA1,
+ },
+ {
+ category="sc",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0xA2,
+ },
+ {
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0xA3,
+ },
+ {
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0xA4,
+ },
+ {
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0xA5,
+ },
+ {
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA6,
+ },
+ {
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0xA7,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x20, 0x308 },
+ unicodeslot=0xA8,
+ },
+ {
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA9,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="ai",
+ specials={ "super", 0x61 },
+ unicodeslot=0xAA,
+ },
+ {
+ category="pi",
+ direction="on",
+ linebreak="qu",
+ mirror=0xBB,
+ textclass="open",
+ unicodeslot=0xAB,
+ },
+ {
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xAC,
+ },
+ {
+ category="cf",
+ direction="bn",
+ linebreak="ba",
+ unicodeslot=0xAD,
+ },
+ {
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xAE,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x20, 0x304 },
+ unicodeslot=0xAF,
+ },
+ {
+ category="so",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0xB0,
+ },
+ {
+ category="sm",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0xB1,
+ },
+ {
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "super", 0x32 },
+ unicodeslot=0xB2,
+ },
+ {
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "super", 0x33 },
+ unicodeslot=0xB3,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="bb",
+ specials={ "compat", 0x20, 0x301 },
+ unicodeslot=0xB4,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x3BC },
+ unicodeslot=0xB5,
+ },
+ {
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0xB6,
+ },
+ {
+ category="po",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0xB7,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x20, 0x327 },
+ unicodeslot=0xB8,
+ },
+ {
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "super", 0x31 },
+ unicodeslot=0xB9,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="ai",
+ specials={ "super", 0x6F },
+ unicodeslot=0xBA,
+ },
+ {
+ category="pf",
+ direction="on",
+ linebreak="qu",
+ mirror=0xAB,
+ textclass="close",
+ unicodeslot=0xBB,
+ },
+ {
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x31, 0x2044, 0x34 },
+ unicodeslot=0xBC,
+ },
+ {
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x31, 0x2044, 0x32 },
+ unicodeslot=0xBD,
+ },
+ {
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x33, 0x2044, 0x34 },
+ unicodeslot=0xBE,
+ },
+ {
+ category="po",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0xBF,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x300 },
+ unicodeslot=0xC0,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x301 },
+ unicodeslot=0xC1,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x302 },
+ unicodeslot=0xC2,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x303 },
+ unicodeslot=0xC3,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x308 },
+ unicodeslot=0xC4,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x30A },
+ unicodeslot=0xC5,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xC6,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x43, 0x327 },
+ unicodeslot=0xC7,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x300 },
+ unicodeslot=0xC8,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x301 },
+ unicodeslot=0xC9,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x302 },
+ unicodeslot=0xCA,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x308 },
+ unicodeslot=0xCB,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x300 },
+ unicodeslot=0xCC,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x301 },
+ unicodeslot=0xCD,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x302 },
+ unicodeslot=0xCE,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x308 },
+ unicodeslot=0xCF,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD0,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4E, 0x303 },
+ unicodeslot=0xD1,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x300 },
+ unicodeslot=0xD2,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x301 },
+ unicodeslot=0xD3,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x302 },
+ unicodeslot=0xD4,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x303 },
+ unicodeslot=0xD5,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x308 },
+ unicodeslot=0xD6,
+ },
+ {
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0xD7,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD8,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x300 },
+ unicodeslot=0xD9,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x301 },
+ unicodeslot=0xDA,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x302 },
+ unicodeslot=0xDB,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x308 },
+ unicodeslot=0xDC,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x59, 0x301 },
+ unicodeslot=0xDD,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDE,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDF,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x300 },
+ unicodeslot=0xE0,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x301 },
+ unicodeslot=0xE1,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x302 },
+ unicodeslot=0xE2,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x303 },
+ unicodeslot=0xE3,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x308 },
+ unicodeslot=0xE4,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x30A },
+ unicodeslot=0xE5,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xE6,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x63, 0x327 },
+ unicodeslot=0xE7,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x300 },
+ unicodeslot=0xE8,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x301 },
+ unicodeslot=0xE9,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x302 },
+ unicodeslot=0xEA,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x308 },
+ unicodeslot=0xEB,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x300 },
+ unicodeslot=0xEC,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x301 },
+ unicodeslot=0xED,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x302 },
+ unicodeslot=0xEE,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x308 },
+ unicodeslot=0xEF,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF0,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6E, 0x303 },
+ unicodeslot=0xF1,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x300 },
+ unicodeslot=0xF2,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x301 },
+ unicodeslot=0xF3,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x302 },
+ unicodeslot=0xF4,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x303 },
+ unicodeslot=0xF5,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x308 },
+ unicodeslot=0xF6,
+ },
+ {
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0xF7,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF8,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x300 },
+ unicodeslot=0xF9,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x301 },
+ unicodeslot=0xFA,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x302 },
+ unicodeslot=0xFB,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x308 },
+ unicodeslot=0xFC,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x79, 0x301 },
+ unicodeslot=0xFD,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFE,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x79, 0x308 },
+ unicodeslot=0xFF,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x304 },
+ unicodeslot=0x100,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x304 },
+ unicodeslot=0x101,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x306 },
+ unicodeslot=0x102,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x306 },
+ unicodeslot=0x103,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x328 },
+ unicodeslot=0x104,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x328 },
+ unicodeslot=0x105,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x43, 0x301 },
+ unicodeslot=0x106,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x63, 0x301 },
+ unicodeslot=0x107,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x43, 0x302 },
+ unicodeslot=0x108,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x63, 0x302 },
+ unicodeslot=0x109,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x43, 0x307 },
+ unicodeslot=0x10A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x63, 0x307 },
+ unicodeslot=0x10B,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x43, 0x30C },
+ unicodeslot=0x10C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x63, 0x30C },
+ unicodeslot=0x10D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x44, 0x30C },
+ unicodeslot=0x10E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x64, 0x30C },
+ unicodeslot=0x10F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x304 },
+ unicodeslot=0x112,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x304 },
+ unicodeslot=0x113,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x306 },
+ unicodeslot=0x114,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x306 },
+ unicodeslot=0x115,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x307 },
+ unicodeslot=0x116,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x307 },
+ unicodeslot=0x117,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x328 },
+ unicodeslot=0x118,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x328 },
+ unicodeslot=0x119,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x30C },
+ unicodeslot=0x11A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x30C },
+ unicodeslot=0x11B,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x47, 0x302 },
+ unicodeslot=0x11C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x67, 0x302 },
+ unicodeslot=0x11D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x47, 0x306 },
+ unicodeslot=0x11E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x67, 0x306 },
+ unicodeslot=0x11F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x47, 0x307 },
+ unicodeslot=0x120,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x67, 0x307 },
+ unicodeslot=0x121,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x47, 0x327 },
+ unicodeslot=0x122,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x67, 0x327 },
+ unicodeslot=0x123,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x48, 0x302 },
+ unicodeslot=0x124,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x68, 0x302 },
+ unicodeslot=0x125,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x303 },
+ unicodeslot=0x128,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x303 },
+ unicodeslot=0x129,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x304 },
+ unicodeslot=0x12A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x304 },
+ unicodeslot=0x12B,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x306 },
+ unicodeslot=0x12C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x306 },
+ unicodeslot=0x12D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x328 },
+ unicodeslot=0x12E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x328 },
+ unicodeslot=0x12F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x307 },
+ unicodeslot=0x130,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x49, 0x4A },
+ unicodeslot=0x132,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x69, 0x6A },
+ unicodeslot=0x133,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4A, 0x302 },
+ unicodeslot=0x134,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6A, 0x302 },
+ unicodeslot=0x135,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4B, 0x327 },
+ unicodeslot=0x136,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6B, 0x327 },
+ unicodeslot=0x137,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4C, 0x301 },
+ unicodeslot=0x139,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6C, 0x301 },
+ unicodeslot=0x13A,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4C, 0x327 },
+ unicodeslot=0x13B,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6C, 0x327 },
+ unicodeslot=0x13C,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4C, 0x30C },
+ unicodeslot=0x13D,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6C, 0x30C },
+ unicodeslot=0x13E,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x4C, 0xB7 },
+ unicodeslot=0x13F,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x6C, 0xB7 },
+ unicodeslot=0x140,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4E, 0x301 },
+ unicodeslot=0x143,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6E, 0x301 },
+ unicodeslot=0x144,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4E, 0x327 },
+ unicodeslot=0x145,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6E, 0x327 },
+ unicodeslot=0x146,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4E, 0x30C },
+ unicodeslot=0x147,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6E, 0x30C },
+ unicodeslot=0x148,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x2BC, 0x6E },
+ unicodeslot=0x149,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x304 },
+ unicodeslot=0x14C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x304 },
+ unicodeslot=0x14D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x306 },
+ unicodeslot=0x14E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x306 },
+ unicodeslot=0x14F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x30B },
+ unicodeslot=0x150,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x30B },
+ unicodeslot=0x151,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x52, 0x301 },
+ unicodeslot=0x154,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x72, 0x301 },
+ unicodeslot=0x155,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x52, 0x327 },
+ unicodeslot=0x156,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x72, 0x327 },
+ unicodeslot=0x157,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x52, 0x30C },
+ unicodeslot=0x158,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x72, 0x30C },
+ unicodeslot=0x159,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x53, 0x301 },
+ unicodeslot=0x15A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x73, 0x301 },
+ unicodeslot=0x15B,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x53, 0x302 },
+ unicodeslot=0x15C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x73, 0x302 },
+ unicodeslot=0x15D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x53, 0x327 },
+ unicodeslot=0x15E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x73, 0x327 },
+ unicodeslot=0x15F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x53, 0x30C },
+ unicodeslot=0x160,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x73, 0x30C },
+ unicodeslot=0x161,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x54, 0x327 },
+ unicodeslot=0x162,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x74, 0x327 },
+ unicodeslot=0x163,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x54, 0x30C },
+ unicodeslot=0x164,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x74, 0x30C },
+ unicodeslot=0x165,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x303 },
+ unicodeslot=0x168,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x303 },
+ unicodeslot=0x169,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x304 },
+ unicodeslot=0x16A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x304 },
+ unicodeslot=0x16B,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x306 },
+ unicodeslot=0x16C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x306 },
+ unicodeslot=0x16D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x30A },
+ unicodeslot=0x16E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x30A },
+ unicodeslot=0x16F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x30B },
+ unicodeslot=0x170,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x30B },
+ unicodeslot=0x171,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x328 },
+ unicodeslot=0x172,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x328 },
+ unicodeslot=0x173,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x57, 0x302 },
+ unicodeslot=0x174,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x77, 0x302 },
+ unicodeslot=0x175,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x59, 0x302 },
+ unicodeslot=0x176,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x79, 0x302 },
+ unicodeslot=0x177,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x59, 0x308 },
+ unicodeslot=0x178,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x5A, 0x301 },
+ unicodeslot=0x179,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x7A, 0x301 },
+ unicodeslot=0x17A,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x5A, 0x307 },
+ unicodeslot=0x17B,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x7A, 0x307 },
+ unicodeslot=0x17C,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x5A, 0x30C },
+ unicodeslot=0x17D,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x7A, 0x30C },
+ unicodeslot=0x17E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x73 },
+ unicodeslot=0x17F,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x180,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x181,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x187,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x191,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x192,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x193,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x194,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x195,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x196,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x197,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x198,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x199,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x19A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x19B,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x19C,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x19D,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x19E,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x19F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x31B },
+ unicodeslot=0x1A0,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x31B },
+ unicodeslot=0x1A1,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A2,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A3,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A4,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A5,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A6,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A7,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A8,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A9,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1AA,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1AB,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1AC,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1AD,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1AE,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x31B },
+ unicodeslot=0x1AF,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x31B },
+ unicodeslot=0x1B0,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B3,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B4,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B5,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B6,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B7,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BA,
+ },
+ {
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BB,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BF,
+ },
+ {
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0,
+ },
+ {
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1,
+ },
+ {
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C2,
+ },
+ {
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C3,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x44, 0x17D },
+ unicodeslot=0x1C4,
+ },
+ {
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x44, 0x17E },
+ unicodeslot=0x1C5,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x64, 0x17E },
+ unicodeslot=0x1C6,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x4C, 0x4A },
+ unicodeslot=0x1C7,
+ },
+ {
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x4C, 0x6A },
+ unicodeslot=0x1C8,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x6C, 0x6A },
+ unicodeslot=0x1C9,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x4E, 0x4A },
+ unicodeslot=0x1CA,
+ },
+ {
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x4E, 0x6A },
+ unicodeslot=0x1CB,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x6E, 0x6A },
+ unicodeslot=0x1CC,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x30C },
+ unicodeslot=0x1CD,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x30C },
+ unicodeslot=0x1CE,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x30C },
+ unicodeslot=0x1CF,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x30C },
+ unicodeslot=0x1D0,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x30C },
+ unicodeslot=0x1D1,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x30C },
+ unicodeslot=0x1D2,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x30C },
+ unicodeslot=0x1D3,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x30C },
+ unicodeslot=0x1D4,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xDC, 0x304 },
+ unicodeslot=0x1D5,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xFC, 0x304 },
+ unicodeslot=0x1D6,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xDC, 0x301 },
+ unicodeslot=0x1D7,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xFC, 0x301 },
+ unicodeslot=0x1D8,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xDC, 0x30C },
+ unicodeslot=0x1D9,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xFC, 0x30C },
+ unicodeslot=0x1DA,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xDC, 0x300 },
+ unicodeslot=0x1DB,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xFC, 0x300 },
+ unicodeslot=0x1DC,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DD,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xC4, 0x304 },
+ unicodeslot=0x1DE,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xE4, 0x304 },
+ unicodeslot=0x1DF,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x226, 0x304 },
+ unicodeslot=0x1E0,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x227, 0x304 },
+ unicodeslot=0x1E1,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xC6, 0x304 },
+ unicodeslot=0x1E2,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xE6, 0x304 },
+ unicodeslot=0x1E3,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E4,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E5,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x47, 0x30C },
+ unicodeslot=0x1E6,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x67, 0x30C },
+ unicodeslot=0x1E7,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4B, 0x30C },
+ unicodeslot=0x1E8,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6B, 0x30C },
+ unicodeslot=0x1E9,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x328 },
+ unicodeslot=0x1EA,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x328 },
+ unicodeslot=0x1EB,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1EA, 0x304 },
+ unicodeslot=0x1EC,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1EB, 0x304 },
+ unicodeslot=0x1ED,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B7, 0x30C },
+ unicodeslot=0x1EE,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x292, 0x30C },
+ unicodeslot=0x1EF,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6A, 0x30C },
+ unicodeslot=0x1F0,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x44, 0x5A },
+ unicodeslot=0x1F1,
+ },
+ {
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x44, 0x7A },
+ unicodeslot=0x1F2,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x64, 0x7A },
+ unicodeslot=0x1F3,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x47, 0x301 },
+ unicodeslot=0x1F4,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x67, 0x301 },
+ unicodeslot=0x1F5,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1F6,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1F7,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4E, 0x300 },
+ unicodeslot=0x1F8,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6E, 0x300 },
+ unicodeslot=0x1F9,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xC5, 0x301 },
+ unicodeslot=0x1FA,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xE5, 0x301 },
+ unicodeslot=0x1FB,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xC6, 0x301 },
+ unicodeslot=0x1FC,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xE6, 0x301 },
+ unicodeslot=0x1FD,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xD8, 0x301 },
+ unicodeslot=0x1FE,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF8, 0x301 },
+ unicodeslot=0x1FF,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x30F },
+ unicodeslot=0x200,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x30F },
+ unicodeslot=0x201,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x311 },
+ unicodeslot=0x202,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x311 },
+ unicodeslot=0x203,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x30F },
+ unicodeslot=0x204,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x30F },
+ unicodeslot=0x205,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x311 },
+ unicodeslot=0x206,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x311 },
+ unicodeslot=0x207,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x30F },
+ unicodeslot=0x208,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x30F },
+ unicodeslot=0x209,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x311 },
+ unicodeslot=0x20A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x311 },
+ unicodeslot=0x20B,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x30F },
+ unicodeslot=0x20C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x30F },
+ unicodeslot=0x20D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x311 },
+ unicodeslot=0x20E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x311 },
+ unicodeslot=0x20F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x52, 0x30F },
+ unicodeslot=0x210,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x72, 0x30F },
+ unicodeslot=0x211,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x52, 0x311 },
+ unicodeslot=0x212,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x72, 0x311 },
+ unicodeslot=0x213,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x30F },
+ unicodeslot=0x214,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x30F },
+ unicodeslot=0x215,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x311 },
+ unicodeslot=0x216,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x311 },
+ unicodeslot=0x217,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x53, 0x326 },
+ unicodeslot=0x218,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x73, 0x326 },
+ unicodeslot=0x219,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x54, 0x326 },
+ unicodeslot=0x21A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x74, 0x326 },
+ unicodeslot=0x21B,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x21C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x21D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x48, 0x30C },
+ unicodeslot=0x21E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x68, 0x30C },
+ unicodeslot=0x21F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x220,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x221,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x222,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x223,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x224,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x225,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x307 },
+ unicodeslot=0x226,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x307 },
+ unicodeslot=0x227,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x327 },
+ unicodeslot=0x228,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x327 },
+ unicodeslot=0x229,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xD6, 0x304 },
+ unicodeslot=0x22A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF6, 0x304 },
+ unicodeslot=0x22B,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xD5, 0x304 },
+ unicodeslot=0x22C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF5, 0x304 },
+ unicodeslot=0x22D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x307 },
+ unicodeslot=0x22E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x307 },
+ unicodeslot=0x22F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x22E, 0x304 },
+ unicodeslot=0x230,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x22F, 0x304 },
+ unicodeslot=0x231,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x59, 0x304 },
+ unicodeslot=0x232,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x79, 0x304 },
+ unicodeslot=0x233,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x237,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x238,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x239,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x23A,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x23B,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x23C,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x23D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x23E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x23F,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x240,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x241,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x242,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x243,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x244,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x245,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x246,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x247,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x248,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x249,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x24A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x24B,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x24C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x24D,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x24E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x24F,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x250,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x251,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x252,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x253,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x254,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x255,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x256,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x257,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x258,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x259,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x25A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x25B,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x25C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x25D,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x25E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x25F,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x260,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x261,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x262,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x263,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x264,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x265,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x266,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x267,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x268,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x269,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x26A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x26B,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x26C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x26D,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x26E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x26F,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x270,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x271,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x272,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x273,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x274,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x275,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x276,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x277,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x278,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x279,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x27A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x27B,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x27C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x27D,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x27E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x27F,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x290,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x291,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x292,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x293,
+ },
+ {
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x294,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x295,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x296,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x297,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x298,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x299,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x29A,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x29B,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x29C,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x29D,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x29E,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x29F,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2A0,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2A1,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2A2,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2A3,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2A4,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2A5,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2A6,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2A7,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2A8,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2A9,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2AA,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2AB,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2AC,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2AD,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2AE,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2AF,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x68 },
+ unicodeslot=0x2B0,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x266 },
+ unicodeslot=0x2B1,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x6A },
+ unicodeslot=0x2B2,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x72 },
+ unicodeslot=0x2B3,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x279 },
+ unicodeslot=0x2B4,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x27B },
+ unicodeslot=0x2B5,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x281 },
+ unicodeslot=0x2B6,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x77 },
+ unicodeslot=0x2B7,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x79 },
+ unicodeslot=0x2B8,
+ },
+ {
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B9,
+ },
+ {
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BA,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2BB,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2BC,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2BD,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2BE,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2BF,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C0,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C1,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2C2,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2C3,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2C4,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2C5,
+ },
+ {
+ category="lm",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x20, 0x302 },
+ unicodeslot=0x2C6,
+ },
+ {
+ category="lm",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x20, 0x30C },
+ unicodeslot=0x2C7,
+ },
+ {
+ category="lm",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x2C8,
+ },
+ {
+ category="lm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2C9,
+ },
+ {
+ category="lm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2CA,
+ },
+ {
+ category="lm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2CB,
+ },
+ {
+ category="lm",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x2CC,
+ },
+ {
+ category="lm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2CD,
+ },
+ {
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CE,
+ },
+ {
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CF,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x2D0,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D1,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2D2,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2D3,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2D4,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2D5,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2D6,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2D7,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x20, 0x306 },
+ unicodeslot=0x2D8,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x20, 0x307 },
+ unicodeslot=0x2D9,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x20, 0x30A },
+ unicodeslot=0x2DA,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x20, 0x328 },
+ unicodeslot=0x2DB,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x20, 0x303 },
+ unicodeslot=0x2DC,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x20, 0x30B },
+ unicodeslot=0x2DD,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2DE,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x2DF,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x263 },
+ unicodeslot=0x2E0,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x6C },
+ unicodeslot=0x2E1,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x73 },
+ unicodeslot=0x2E2,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x78 },
+ unicodeslot=0x2E3,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x295 },
+ unicodeslot=0x2E4,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E5,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E6,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E7,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E8,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E9,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2EA,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2EB,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2EC,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2ED,
+ },
+ {
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2EE,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2EF,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2F0,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2F1,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2F2,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2F3,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2F4,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2F5,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2F6,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2F7,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2F8,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2F9,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2FA,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2FB,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2FC,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2FD,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2FE,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2FF,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x300,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x301,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x302,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x303,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x304,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x305,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x306,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x307,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x308,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x309,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x30A,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x30B,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x30C,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x30D,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x30E,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x30F,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x310,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x311,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x312,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x313,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x314,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x315,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x316,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x317,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x318,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x319,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x31A,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x31B,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x31C,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x31D,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x31E,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x31F,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x320,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x321,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x322,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x323,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x324,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x325,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x326,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x327,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x328,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x329,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x32A,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x32B,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x32C,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x32D,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x32E,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x32F,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x330,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x331,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x332,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x333,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x334,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x335,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x336,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x337,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x338,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x339,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x33A,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x33B,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x33C,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x33D,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x33E,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x33F,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x300 },
+ unicodeslot=0x340,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x301 },
+ unicodeslot=0x341,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x342,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x313 },
+ unicodeslot=0x343,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x308, 0x301 },
+ unicodeslot=0x344,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x345,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x346,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x347,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x348,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x349,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x34A,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x34B,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x34C,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x34D,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x34E,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x34F,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x350,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x351,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x352,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x353,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x354,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x355,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x356,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x357,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x358,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x359,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x35A,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x35B,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x35C,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x35D,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x35E,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x35F,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x360,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x361,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x362,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x363,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x364,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x365,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x366,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x367,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x368,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x369,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x36A,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x36B,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x36C,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x36D,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x36E,
+ },
+ {
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x36F,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x370,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x371,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x372,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x373,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x2B9 },
+ unicodeslot=0x374,
+ },
+ {
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x375,
+ },
+ {
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x376,
+ },
+ {
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x377,
+ },
+ [0x37A]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x20, 0x345 },
+ unicodeslot=0x37A,
+ },
+ [0x37B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x37B,
+ },
+ [0x37C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x37C,
+ },
+ [0x37D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x37D,
+ },
+ [0x37E]={
+ category="po",
+ direction="on",
+ linebreak="is",
+ specials={ "char", 0x3B },
+ unicodeslot=0x37E,
+ },
+ [0x37F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x37F,
+ },
+ [0x384]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x20, 0x301 },
+ unicodeslot=0x384,
+ },
+ [0x385]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0xA8, 0x301 },
+ unicodeslot=0x385,
+ },
+ [0x386]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x391, 0x301 },
+ unicodeslot=0x386,
+ },
+ [0x387]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0xB7 },
+ unicodeslot=0x387,
+ },
+ [0x388]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x395, 0x301 },
+ unicodeslot=0x388,
+ },
+ [0x389]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x397, 0x301 },
+ unicodeslot=0x389,
+ },
+ [0x38A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x399, 0x301 },
+ unicodeslot=0x38A,
+ },
+ [0x38C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x39F, 0x301 },
+ unicodeslot=0x38C,
+ },
+ [0x38E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A5, 0x301 },
+ unicodeslot=0x38E,
+ },
+ [0x38F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A9, 0x301 },
+ unicodeslot=0x38F,
+ },
+ [0x390]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3CA, 0x301 },
+ unicodeslot=0x390,
+ },
+ [0x391]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x391,
+ },
+ [0x392]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x392,
+ },
+ [0x393]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x393,
+ },
+ [0x394]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x394,
+ },
+ [0x395]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x395,
+ },
+ [0x396]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x396,
+ },
+ [0x397]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x397,
+ },
+ [0x398]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x398,
+ },
+ [0x399]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x399,
+ },
+ [0x39A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x39A,
+ },
+ [0x39B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x39B,
+ },
+ [0x39C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x39C,
+ },
+ [0x39D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x39D,
+ },
+ [0x39E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x39E,
+ },
+ [0x39F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x39F,
+ },
+ [0x3A0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3A0,
+ },
+ [0x3A1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3A1,
+ },
+ [0x3A3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3A3,
+ },
+ [0x3A4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3A4,
+ },
+ [0x3A5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3A5,
+ },
+ [0x3A6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3A6,
+ },
+ [0x3A7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3A7,
+ },
+ [0x3A8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3A8,
+ },
+ [0x3A9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3A9,
+ },
+ [0x3AA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x399, 0x308 },
+ unicodeslot=0x3AA,
+ },
+ [0x3AB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A5, 0x308 },
+ unicodeslot=0x3AB,
+ },
+ [0x3AC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B1, 0x301 },
+ unicodeslot=0x3AC,
+ },
+ [0x3AD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B5, 0x301 },
+ unicodeslot=0x3AD,
+ },
+ [0x3AE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B7, 0x301 },
+ unicodeslot=0x3AE,
+ },
+ [0x3AF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B9, 0x301 },
+ unicodeslot=0x3AF,
+ },
+ [0x3B0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3CB, 0x301 },
+ unicodeslot=0x3B0,
+ },
+ [0x3B1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3B1,
+ },
+ [0x3B2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3B2,
+ },
+ [0x3B3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3B3,
+ },
+ [0x3B4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3B4,
+ },
+ [0x3B5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3B5,
+ },
+ [0x3B6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3B6,
+ },
+ [0x3B7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3B7,
+ },
+ [0x3B8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3B8,
+ },
+ [0x3B9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3B9,
+ },
+ [0x3BA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3BA,
+ },
+ [0x3BB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3BB,
+ },
+ [0x3BC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3BC,
+ },
+ [0x3BD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3BD,
+ },
+ [0x3BE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3BE,
+ },
+ [0x3BF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3BF,
+ },
+ [0x3C0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3C0,
+ },
+ [0x3C1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3C1,
+ },
+ [0x3C2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3C2,
+ },
+ [0x3C3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3C3,
+ },
+ [0x3C4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3C4,
+ },
+ [0x3C5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3C5,
+ },
+ [0x3C6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3C6,
+ },
+ [0x3C7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3C7,
+ },
+ [0x3C8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3C8,
+ },
+ [0x3C9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3C9,
+ },
+ [0x3CA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B9, 0x308 },
+ unicodeslot=0x3CA,
+ },
+ [0x3CB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C5, 0x308 },
+ unicodeslot=0x3CB,
+ },
+ [0x3CC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3BF, 0x301 },
+ unicodeslot=0x3CC,
+ },
+ [0x3CD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C5, 0x301 },
+ unicodeslot=0x3CD,
+ },
+ [0x3CE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C9, 0x301 },
+ unicodeslot=0x3CE,
+ },
+ [0x3CF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3CF,
+ },
+ [0x3D0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x3B2 },
+ unicodeslot=0x3D0,
+ },
+ [0x3D1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x3B8 },
+ unicodeslot=0x3D1,
+ },
+ [0x3D2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x3A5 },
+ unicodeslot=0x3D2,
+ },
+ [0x3D3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3D2, 0x301 },
+ unicodeslot=0x3D3,
+ },
+ [0x3D4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3D2, 0x308 },
+ unicodeslot=0x3D4,
+ },
+ [0x3D5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x3C6 },
+ unicodeslot=0x3D5,
+ },
+ [0x3D6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x3C0 },
+ unicodeslot=0x3D6,
+ },
+ [0x3D7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3D7,
+ },
+ [0x3D8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3D8,
+ },
+ [0x3D9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3D9,
+ },
+ [0x3DA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3DA,
+ },
+ [0x3DB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3DB,
+ },
+ [0x3DC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3DC,
+ },
+ [0x3DD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3DD,
+ },
+ [0x3DE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3DE,
+ },
+ [0x3DF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3DF,
+ },
+ [0x3E0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3E0,
+ },
+ [0x3E1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3E1,
+ },
+ [0x3E2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3E2,
+ },
+ [0x3E3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3E3,
+ },
+ [0x3E4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3E4,
+ },
+ [0x3E5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3E5,
+ },
+ [0x3E6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3E6,
+ },
+ [0x3E7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3E7,
+ },
+ [0x3E8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3E8,
+ },
+ [0x3E9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3E9,
+ },
+ [0x3EA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3EA,
+ },
+ [0x3EB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3EB,
+ },
+ [0x3EC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3EC,
+ },
+ [0x3ED]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3ED,
+ },
+ [0x3EE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3EE,
+ },
+ [0x3EF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3EF,
+ },
+ [0x3F0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x3BA },
+ unicodeslot=0x3F0,
+ },
+ [0x3F1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x3C1 },
+ unicodeslot=0x3F1,
+ },
+ [0x3F2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x3C2 },
+ unicodeslot=0x3F2,
+ },
+ [0x3F3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3F3,
+ },
+ [0x3F4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x398 },
+ unicodeslot=0x3F4,
+ },
+ [0x3F5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x3B5 },
+ unicodeslot=0x3F5,
+ },
+ [0x3F6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x3F6,
+ },
+ [0x3F7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3F7,
+ },
+ [0x3F8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3F8,
+ },
+ [0x3F9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x3A3 },
+ unicodeslot=0x3F9,
+ },
+ [0x3FA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3FA,
+ },
+ [0x3FB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3FB,
+ },
+ [0x3FC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3FC,
+ },
+ [0x3FD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3FD,
+ },
+ [0x3FE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3FE,
+ },
+ [0x3FF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x3FF,
+ },
+ [0x400]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x415, 0x300 },
+ unicodeslot=0x400,
+ },
+ [0x401]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x415, 0x308 },
+ unicodeslot=0x401,
+ },
+ [0x402]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x402,
+ },
+ [0x403]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x413, 0x301 },
+ unicodeslot=0x403,
+ },
+ [0x404]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x404,
+ },
+ [0x405]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x405,
+ },
+ [0x406]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x406,
+ },
+ [0x407]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x406, 0x308 },
+ unicodeslot=0x407,
+ },
+ [0x408]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x408,
+ },
+ [0x409]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x409,
+ },
+ [0x40A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x40A,
+ },
+ [0x40B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x40B,
+ },
+ [0x40C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41A, 0x301 },
+ unicodeslot=0x40C,
+ },
+ [0x40D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x418, 0x300 },
+ unicodeslot=0x40D,
+ },
+ [0x40E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x423, 0x306 },
+ unicodeslot=0x40E,
+ },
+ [0x40F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x40F,
+ },
+ [0x410]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x410,
+ },
+ [0x411]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x411,
+ },
+ [0x412]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x412,
+ },
+ [0x413]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x413,
+ },
+ [0x414]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x414,
+ },
+ [0x415]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x415,
+ },
+ [0x416]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x416,
+ },
+ [0x417]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x417,
+ },
+ [0x418]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x418,
+ },
+ [0x419]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x418, 0x306 },
+ unicodeslot=0x419,
+ },
+ [0x41A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x41A,
+ },
+ [0x41B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x41B,
+ },
+ [0x41C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x41C,
+ },
+ [0x41D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x41D,
+ },
+ [0x41E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x41E,
+ },
+ [0x41F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x41F,
+ },
+ [0x420]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x420,
+ },
+ [0x421]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x421,
+ },
+ [0x422]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x422,
+ },
+ [0x423]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x423,
+ },
+ [0x424]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x424,
+ },
+ [0x425]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x425,
+ },
+ [0x426]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x426,
+ },
+ [0x427]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x427,
+ },
+ [0x428]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x428,
+ },
+ [0x429]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x429,
+ },
+ [0x42A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x42A,
+ },
+ [0x42B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x42B,
+ },
+ [0x42C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x42C,
+ },
+ [0x42D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x42D,
+ },
+ [0x42E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x42E,
+ },
+ [0x42F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x42F,
+ },
+ [0x430]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x430,
+ },
+ [0x431]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x431,
+ },
+ [0x432]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x432,
+ },
+ [0x433]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x433,
+ },
+ [0x434]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x434,
+ },
+ [0x435]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x435,
+ },
+ [0x436]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x436,
+ },
+ [0x437]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x437,
+ },
+ [0x438]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x438,
+ },
+ [0x439]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x438, 0x306 },
+ unicodeslot=0x439,
+ },
+ [0x43A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x43A,
+ },
+ [0x43B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x43B,
+ },
+ [0x43C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x43C,
+ },
+ [0x43D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x43D,
+ },
+ [0x43E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x43E,
+ },
+ [0x43F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x43F,
+ },
+ [0x440]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x440,
+ },
+ [0x441]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x441,
+ },
+ [0x442]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x442,
+ },
+ [0x443]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x443,
+ },
+ [0x444]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x444,
+ },
+ [0x445]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x445,
+ },
+ [0x446]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x446,
+ },
+ [0x447]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x447,
+ },
+ [0x448]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x448,
+ },
+ [0x449]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x449,
+ },
+ [0x44A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x44A,
+ },
+ [0x44B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x44B,
+ },
+ [0x44C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x44C,
+ },
+ [0x44D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x44D,
+ },
+ [0x44E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x44E,
+ },
+ [0x44F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x44F,
+ },
+ [0x450]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x435, 0x300 },
+ unicodeslot=0x450,
+ },
+ [0x451]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x435, 0x308 },
+ unicodeslot=0x451,
+ },
+ [0x452]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x452,
+ },
+ [0x453]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x433, 0x301 },
+ unicodeslot=0x453,
+ },
+ [0x454]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x454,
+ },
+ [0x455]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x455,
+ },
+ [0x456]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x456,
+ },
+ [0x457]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x456, 0x308 },
+ unicodeslot=0x457,
+ },
+ [0x458]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x458,
+ },
+ [0x459]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x459,
+ },
+ [0x45A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x45A,
+ },
+ [0x45B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x45B,
+ },
+ [0x45C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x43A, 0x301 },
+ unicodeslot=0x45C,
+ },
+ [0x45D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x438, 0x300 },
+ unicodeslot=0x45D,
+ },
+ [0x45E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x443, 0x306 },
+ unicodeslot=0x45E,
+ },
+ [0x45F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x45F,
+ },
+ [0x460]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x460,
+ },
+ [0x461]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x461,
+ },
+ [0x462]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x462,
+ },
+ [0x463]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x463,
+ },
+ [0x464]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x464,
+ },
+ [0x465]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x465,
+ },
+ [0x466]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x466,
+ },
+ [0x467]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x467,
+ },
+ [0x468]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x468,
+ },
+ [0x469]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x469,
+ },
+ [0x46A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x46A,
+ },
+ [0x46B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x46B,
+ },
+ [0x46C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x46C,
+ },
+ [0x46D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x46D,
+ },
+ [0x46E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x46E,
+ },
+ [0x46F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x46F,
+ },
+ [0x470]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x470,
+ },
+ [0x471]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x471,
+ },
+ [0x472]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x472,
+ },
+ [0x473]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x473,
+ },
+ [0x474]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x474,
+ },
+ [0x475]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x475,
+ },
+ [0x476]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x474, 0x30F },
+ unicodeslot=0x476,
+ },
+ [0x477]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x475, 0x30F },
+ unicodeslot=0x477,
+ },
+ [0x478]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x478,
+ },
+ [0x479]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x479,
+ },
+ [0x47A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x47A,
+ },
+ [0x47B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x47B,
+ },
+ [0x47C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x47C,
+ },
+ [0x47D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x47D,
+ },
+ [0x47E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x47E,
+ },
+ [0x47F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x47F,
+ },
+ [0x480]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x480,
+ },
+ [0x481]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x481,
+ },
+ [0x482]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x482,
+ },
+ [0x483]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x483,
+ },
+ [0x484]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x484,
+ },
+ [0x485]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x485,
+ },
+ [0x486]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x486,
+ },
+ [0x487]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x487,
+ },
+ [0x488]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x488,
+ },
+ [0x489]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x489,
+ },
+ [0x48A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x48A,
+ },
+ [0x48B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x48B,
+ },
+ [0x48C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x48C,
+ },
+ [0x48D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x48D,
+ },
+ [0x48E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x48E,
+ },
+ [0x48F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x48F,
+ },
+ [0x490]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x490,
+ },
+ [0x491]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x491,
+ },
+ [0x492]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x492,
+ },
+ [0x493]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x493,
+ },
+ [0x494]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x494,
+ },
+ [0x495]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x495,
+ },
+ [0x496]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x496,
+ },
+ [0x497]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x497,
+ },
+ [0x498]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x498,
+ },
+ [0x499]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x499,
+ },
+ [0x49A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x49A,
+ },
+ [0x49B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x49B,
+ },
+ [0x49C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x49C,
+ },
+ [0x49D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x49D,
+ },
+ [0x49E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x49E,
+ },
+ [0x49F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x49F,
+ },
+ [0x4A0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4A0,
+ },
+ [0x4A1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4A1,
+ },
+ [0x4A2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4A2,
+ },
+ [0x4A3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4A3,
+ },
+ [0x4A4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4A4,
+ },
+ [0x4A5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4A5,
+ },
+ [0x4A6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4A6,
+ },
+ [0x4A7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4A7,
+ },
+ [0x4A8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4A8,
+ },
+ [0x4A9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4A9,
+ },
+ [0x4AA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4AA,
+ },
+ [0x4AB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4AB,
+ },
+ [0x4AC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4AC,
+ },
+ [0x4AD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4AD,
+ },
+ [0x4AE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4AE,
+ },
+ [0x4AF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4AF,
+ },
+ [0x4B0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4B0,
+ },
+ [0x4B1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4B1,
+ },
+ [0x4B2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4B2,
+ },
+ [0x4B3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4B3,
+ },
+ [0x4B4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4B4,
+ },
+ [0x4B5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4B5,
+ },
+ [0x4B6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4B6,
+ },
+ [0x4B7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4B7,
+ },
+ [0x4B8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4B8,
+ },
+ [0x4B9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4B9,
+ },
+ [0x4BA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4BA,
+ },
+ [0x4BB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4BB,
+ },
+ [0x4BC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4BC,
+ },
+ [0x4BD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4BD,
+ },
+ [0x4BE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4BE,
+ },
+ [0x4BF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4BF,
+ },
+ [0x4C0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4C0,
+ },
+ [0x4C1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x416, 0x306 },
+ unicodeslot=0x4C1,
+ },
+ [0x4C2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x436, 0x306 },
+ unicodeslot=0x4C2,
+ },
+ [0x4C3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4C3,
+ },
+ [0x4C4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4C4,
+ },
+ [0x4C5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4C5,
+ },
+ [0x4C6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4C6,
+ },
+ [0x4C7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4C7,
+ },
+ [0x4C8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4C8,
+ },
+ [0x4C9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4C9,
+ },
+ [0x4CA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4CA,
+ },
+ [0x4CB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4CB,
+ },
+ [0x4CC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4CC,
+ },
+ [0x4CD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4CD,
+ },
+ [0x4CE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4CE,
+ },
+ [0x4CF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4CF,
+ },
+ [0x4D0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x410, 0x306 },
+ unicodeslot=0x4D0,
+ },
+ [0x4D1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x430, 0x306 },
+ unicodeslot=0x4D1,
+ },
+ [0x4D2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x410, 0x308 },
+ unicodeslot=0x4D2,
+ },
+ [0x4D3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x430, 0x308 },
+ unicodeslot=0x4D3,
+ },
+ [0x4D4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4D4,
+ },
+ [0x4D5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4D5,
+ },
+ [0x4D6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x415, 0x306 },
+ unicodeslot=0x4D6,
+ },
+ [0x4D7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x435, 0x306 },
+ unicodeslot=0x4D7,
+ },
+ [0x4D8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4D8,
+ },
+ [0x4D9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4D9,
+ },
+ [0x4DA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4D8, 0x308 },
+ unicodeslot=0x4DA,
+ },
+ [0x4DB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4D9, 0x308 },
+ unicodeslot=0x4DB,
+ },
+ [0x4DC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x416, 0x308 },
+ unicodeslot=0x4DC,
+ },
+ [0x4DD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x436, 0x308 },
+ unicodeslot=0x4DD,
+ },
+ [0x4DE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x417, 0x308 },
+ unicodeslot=0x4DE,
+ },
+ [0x4DF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x437, 0x308 },
+ unicodeslot=0x4DF,
+ },
+ [0x4E0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4E0,
+ },
+ [0x4E1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4E1,
+ },
+ [0x4E2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x418, 0x304 },
+ unicodeslot=0x4E2,
+ },
+ [0x4E3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x438, 0x304 },
+ unicodeslot=0x4E3,
+ },
+ [0x4E4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x418, 0x308 },
+ unicodeslot=0x4E4,
+ },
+ [0x4E5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x438, 0x308 },
+ unicodeslot=0x4E5,
+ },
+ [0x4E6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41E, 0x308 },
+ unicodeslot=0x4E6,
+ },
+ [0x4E7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x43E, 0x308 },
+ unicodeslot=0x4E7,
+ },
+ [0x4E8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4E8,
+ },
+ [0x4E9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4E9,
+ },
+ [0x4EA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4E8, 0x308 },
+ unicodeslot=0x4EA,
+ },
+ [0x4EB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4E9, 0x308 },
+ unicodeslot=0x4EB,
+ },
+ [0x4EC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x42D, 0x308 },
+ unicodeslot=0x4EC,
+ },
+ [0x4ED]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x44D, 0x308 },
+ unicodeslot=0x4ED,
+ },
+ [0x4EE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x423, 0x304 },
+ unicodeslot=0x4EE,
+ },
+ [0x4EF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x443, 0x304 },
+ unicodeslot=0x4EF,
+ },
+ [0x4F0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x423, 0x308 },
+ unicodeslot=0x4F0,
+ },
+ [0x4F1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x443, 0x308 },
+ unicodeslot=0x4F1,
+ },
+ [0x4F2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x423, 0x30B },
+ unicodeslot=0x4F2,
+ },
+ [0x4F3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x443, 0x30B },
+ unicodeslot=0x4F3,
+ },
+ [0x4F4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x427, 0x308 },
+ unicodeslot=0x4F4,
+ },
+ [0x4F5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x447, 0x308 },
+ unicodeslot=0x4F5,
+ },
+ [0x4F6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4F6,
+ },
+ [0x4F7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4F7,
+ },
+ [0x4F8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x42B, 0x308 },
+ unicodeslot=0x4F8,
+ },
+ [0x4F9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x44B, 0x308 },
+ unicodeslot=0x4F9,
+ },
+ [0x4FA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4FA,
+ },
+ [0x4FB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4FB,
+ },
+ [0x4FC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4FC,
+ },
+ [0x4FD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4FD,
+ },
+ [0x4FE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4FE,
+ },
+ [0x4FF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x4FF,
+ },
+ [0x500]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x500,
+ },
+ [0x501]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x501,
+ },
+ [0x502]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x502,
+ },
+ [0x503]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x503,
+ },
+ [0x504]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x504,
+ },
+ [0x505]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x505,
+ },
+ [0x506]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x506,
+ },
+ [0x507]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x507,
+ },
+ [0x508]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x508,
+ },
+ [0x509]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x509,
+ },
+ [0x50A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x50A,
+ },
+ [0x50B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x50B,
+ },
+ [0x50C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x50C,
+ },
+ [0x50D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x50D,
+ },
+ [0x50E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x50E,
+ },
+ [0x50F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x50F,
+ },
+ [0x510]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x510,
+ },
+ [0x511]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x511,
+ },
+ [0x512]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x512,
+ },
+ [0x513]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x513,
+ },
+ [0x514]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x514,
+ },
+ [0x515]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x515,
+ },
+ [0x516]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x516,
+ },
+ [0x517]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x517,
+ },
+ [0x518]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x518,
+ },
+ [0x519]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x519,
+ },
+ [0x51A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x51A,
+ },
+ [0x51B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x51B,
+ },
+ [0x51C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x51C,
+ },
+ [0x51D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x51D,
+ },
+ [0x51E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x51E,
+ },
+ [0x51F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x51F,
+ },
+ [0x520]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x520,
+ },
+ [0x521]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x521,
+ },
+ [0x522]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x522,
+ },
+ [0x523]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x523,
+ },
+ [0x524]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x524,
+ },
+ [0x525]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x525,
+ },
+ [0x526]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x526,
+ },
+ [0x527]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x527,
+ },
+ [0x528]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x528,
+ },
+ [0x529]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x529,
+ },
+ [0x52A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x52A,
+ },
+ [0x52B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x52B,
+ },
+ [0x52C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x52C,
+ },
+ [0x52D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x52D,
+ },
+ [0x52E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x52E,
+ },
+ [0x52F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x52F,
+ },
+ [0x531]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x531,
+ },
+ [0x532]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x532,
+ },
+ [0x533]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x533,
+ },
+ [0x534]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x534,
+ },
+ [0x535]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x535,
+ },
+ [0x536]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x536,
+ },
+ [0x537]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x537,
+ },
+ [0x538]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x538,
+ },
+ [0x539]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x539,
+ },
+ [0x53A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x53A,
+ },
+ [0x53B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x53B,
+ },
+ [0x53C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x53C,
+ },
+ [0x53D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x53D,
+ },
+ [0x53E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x53E,
+ },
+ [0x53F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x53F,
+ },
+ [0x540]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x540,
+ },
+ [0x541]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x541,
+ },
+ [0x542]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x542,
+ },
+ [0x543]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x543,
+ },
+ [0x544]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x544,
+ },
+ [0x545]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x545,
+ },
+ [0x546]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x546,
+ },
+ [0x547]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x547,
+ },
+ [0x548]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x548,
+ },
+ [0x549]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x549,
+ },
+ [0x54A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x54A,
+ },
+ [0x54B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x54B,
+ },
+ [0x54C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x54C,
+ },
+ [0x54D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x54D,
+ },
+ [0x54E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x54E,
+ },
+ [0x54F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x54F,
+ },
+ [0x550]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x550,
+ },
+ [0x551]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x551,
+ },
+ [0x552]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x552,
+ },
+ [0x553]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x553,
+ },
+ [0x554]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x554,
+ },
+ [0x555]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x555,
+ },
+ [0x556]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x556,
+ },
+ [0x559]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x559,
+ },
+ [0x55A]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x55A,
+ },
+ [0x55B]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x55B,
+ },
+ [0x55C]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x55C,
+ },
+ [0x55D]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x55D,
+ },
+ [0x55E]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x55E,
+ },
+ [0x55F]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x55F,
+ },
+ [0x560]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x560,
+ },
+ [0x561]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x561,
+ },
+ [0x562]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x562,
+ },
+ [0x563]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x563,
+ },
+ [0x564]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x564,
+ },
+ [0x565]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x565,
+ },
+ [0x566]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x566,
+ },
+ [0x567]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x567,
+ },
+ [0x568]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x568,
+ },
+ [0x569]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x569,
+ },
+ [0x56A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x56A,
+ },
+ [0x56B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x56B,
+ },
+ [0x56C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x56C,
+ },
+ [0x56D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x56D,
+ },
+ [0x56E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x56E,
+ },
+ [0x56F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x56F,
+ },
+ [0x570]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x570,
+ },
+ [0x571]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x571,
+ },
+ [0x572]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x572,
+ },
+ [0x573]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x573,
+ },
+ [0x574]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x574,
+ },
+ [0x575]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x575,
+ },
+ [0x576]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x576,
+ },
+ [0x577]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x577,
+ },
+ [0x578]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x578,
+ },
+ [0x579]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x579,
+ },
+ [0x57A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x57A,
+ },
+ [0x57B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x57B,
+ },
+ [0x57C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x57C,
+ },
+ [0x57D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x57D,
+ },
+ [0x57E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x57E,
+ },
+ [0x57F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x57F,
+ },
+ [0x580]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x580,
+ },
+ [0x581]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x581,
+ },
+ [0x582]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x582,
+ },
+ [0x583]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x583,
+ },
+ [0x584]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x584,
+ },
+ [0x585]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x585,
+ },
+ [0x586]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x586,
+ },
+ [0x587]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x565, 0x582 },
+ unicodeslot=0x587,
+ },
+ [0x588]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x588,
+ },
+ [0x589]={
+ category="po",
+ direction="l",
+ linebreak="is",
+ unicodeslot=0x589,
+ },
+ [0x58A]={
+ category="pd",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x58A,
+ },
+ [0x58D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x58D,
+ },
+ [0x58E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x58E,
+ },
+ [0x58F]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x58F,
+ },
+ [0x591]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x591,
+ },
+ [0x592]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x592,
+ },
+ [0x593]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x593,
+ },
+ [0x594]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x594,
+ },
+ [0x595]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x595,
+ },
+ [0x596]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x596,
+ },
+ [0x597]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x597,
+ },
+ [0x598]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x598,
+ },
+ [0x599]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x599,
+ },
+ [0x59A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x59A,
+ },
+ [0x59B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x59B,
+ },
+ [0x59C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x59C,
+ },
+ [0x59D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x59D,
+ },
+ [0x59E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x59E,
+ },
+ [0x59F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x59F,
+ },
+ [0x5A0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5A0,
+ },
+ [0x5A1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5A1,
+ },
+ [0x5A2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5A2,
+ },
+ [0x5A3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5A3,
+ },
+ [0x5A4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5A4,
+ },
+ [0x5A5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5A5,
+ },
+ [0x5A6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5A6,
+ },
+ [0x5A7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5A7,
+ },
+ [0x5A8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5A8,
+ },
+ [0x5A9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5A9,
+ },
+ [0x5AA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5AA,
+ },
+ [0x5AB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5AB,
+ },
+ [0x5AC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5AC,
+ },
+ [0x5AD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5AD,
+ },
+ [0x5AE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5AE,
+ },
+ [0x5AF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5AF,
+ },
+ [0x5B0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5B0,
+ },
+ [0x5B1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5B1,
+ },
+ [0x5B2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5B2,
+ },
+ [0x5B3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5B3,
+ },
+ [0x5B4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5B4,
+ },
+ [0x5B5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5B5,
+ },
+ [0x5B6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5B6,
+ },
+ [0x5B7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5B7,
+ },
+ [0x5B8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5B8,
+ },
+ [0x5B9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5B9,
+ },
+ [0x5BA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5BA,
+ },
+ [0x5BB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5BB,
+ },
+ [0x5BC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5BC,
+ },
+ [0x5BD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5BD,
+ },
+ [0x5BE]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x5BE,
+ },
+ [0x5BF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5BF,
+ },
+ [0x5C0]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x5C0,
+ },
+ [0x5C1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5C1,
+ },
+ [0x5C2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5C2,
+ },
+ [0x5C3]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x5C3,
+ },
+ [0x5C4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5C4,
+ },
+ [0x5C5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5C5,
+ },
+ [0x5C6]={
+ category="po",
+ direction="r",
+ linebreak="ex",
+ unicodeslot=0x5C6,
+ },
+ [0x5C7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x5C7,
+ },
+ [0x5D0]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5D0,
+ },
+ [0x5D1]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5D1,
+ },
+ [0x5D2]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5D2,
+ },
+ [0x5D3]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5D3,
+ },
+ [0x5D4]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5D4,
+ },
+ [0x5D5]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5D5,
+ },
+ [0x5D6]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5D6,
+ },
+ [0x5D7]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5D7,
+ },
+ [0x5D8]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5D8,
+ },
+ [0x5D9]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5D9,
+ },
+ [0x5DA]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5DA,
+ },
+ [0x5DB]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5DB,
+ },
+ [0x5DC]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5DC,
+ },
+ [0x5DD]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5DD,
+ },
+ [0x5DE]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5DE,
+ },
+ [0x5DF]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5DF,
+ },
+ [0x5E0]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5E0,
+ },
+ [0x5E1]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5E1,
+ },
+ [0x5E2]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5E2,
+ },
+ [0x5E3]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5E3,
+ },
+ [0x5E4]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5E4,
+ },
+ [0x5E5]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5E5,
+ },
+ [0x5E6]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5E6,
+ },
+ [0x5E7]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5E7,
+ },
+ [0x5E8]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5E8,
+ },
+ [0x5E9]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5E9,
+ },
+ [0x5EA]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5EA,
+ },
+ [0x5EF]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5EF,
+ },
+ [0x5F0]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5F0,
+ },
+ [0x5F1]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5F1,
+ },
+ [0x5F2]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x5F2,
+ },
+ [0x5F3]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x5F3,
+ },
+ [0x5F4]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x5F4,
+ },
+ [0x600]={
+ category="cf",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x600,
+ },
+ [0x601]={
+ category="cf",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x601,
+ },
+ [0x602]={
+ category="cf",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x602,
+ },
+ [0x603]={
+ category="cf",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x603,
+ },
+ [0x604]={
+ category="cf",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x604,
+ },
+ [0x605]={
+ category="cf",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x605,
+ },
+ [0x606]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x606,
+ },
+ [0x607]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x607,
+ },
+ [0x608]={
+ category="sm",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x608,
+ },
+ [0x609]={
+ category="po",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x609,
+ },
+ [0x60A]={
+ category="po",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x60A,
+ },
+ [0x60B]={
+ category="sc",
+ direction="al",
+ linebreak="po",
+ unicodeslot=0x60B,
+ },
+ [0x60C]={
+ category="po",
+ direction="cs",
+ linebreak="is",
+ unicodeslot=0x60C,
+ },
+ [0x60D]={
+ category="po",
+ direction="al",
+ linebreak="is",
+ unicodeslot=0x60D,
+ },
+ [0x60E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x60E,
+ },
+ [0x60F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x60F,
+ },
+ [0x610]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x610,
+ },
+ [0x611]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x611,
+ },
+ [0x612]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x612,
+ },
+ [0x613]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x613,
+ },
+ [0x614]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x614,
+ },
+ [0x615]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x615,
+ },
+ [0x616]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x616,
+ },
+ [0x617]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x617,
+ },
+ [0x618]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x618,
+ },
+ [0x619]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x619,
+ },
+ [0x61A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x61A,
+ },
+ [0x61B]={
+ category="po",
+ direction="al",
+ linebreak="ex",
+ unicodeslot=0x61B,
+ },
+ [0x61C]={
+ category="cf",
+ direction="al",
+ linebreak="cm",
+ unicodeslot=0x61C,
+ },
+ [0x61E]={
+ category="po",
+ direction="al",
+ linebreak="ex",
+ unicodeslot=0x61E,
+ },
+ [0x61F]={
+ category="po",
+ direction="al",
+ linebreak="ex",
+ unicodeslot=0x61F,
+ },
+ [0x620]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x620,
+ },
+ [0x621]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x621,
+ },
+ [0x622]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "char", 0x627, 0x653 },
+ unicodeslot=0x622,
+ },
+ [0x623]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "char", 0x627, 0x654 },
+ unicodeslot=0x623,
+ },
+ [0x624]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "char", 0x648, 0x654 },
+ unicodeslot=0x624,
+ },
+ [0x625]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "char", 0x627, 0x655 },
+ unicodeslot=0x625,
+ },
+ [0x626]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "char", 0x64A, 0x654 },
+ unicodeslot=0x626,
+ },
+ [0x627]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x627,
+ },
+ [0x628]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x628,
+ },
+ [0x629]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x629,
+ },
+ [0x62A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x62A,
+ },
+ [0x62B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x62B,
+ },
+ [0x62C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x62C,
+ },
+ [0x62D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x62D,
+ },
+ [0x62E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x62E,
+ },
+ [0x62F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x62F,
+ },
+ [0x630]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x630,
+ },
+ [0x631]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x631,
+ },
+ [0x632]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x632,
+ },
+ [0x633]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x633,
+ },
+ [0x634]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x634,
+ },
+ [0x635]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x635,
+ },
+ [0x636]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x636,
+ },
+ [0x637]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x637,
+ },
+ [0x638]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x638,
+ },
+ [0x639]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x639,
+ },
+ [0x63A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x63A,
+ },
+ [0x63B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x63B,
+ },
+ [0x63C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x63C,
+ },
+ [0x63D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x63D,
+ },
+ [0x63E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x63E,
+ },
+ [0x63F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x63F,
+ },
+ [0x640]={
+ category="lm",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x640,
+ },
+ [0x641]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x641,
+ },
+ [0x642]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x642,
+ },
+ [0x643]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x643,
+ },
+ [0x644]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x644,
+ },
+ [0x645]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x645,
+ },
+ [0x646]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x646,
+ },
+ [0x647]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x647,
+ },
+ [0x648]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x648,
+ },
+ [0x649]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x649,
+ },
+ [0x64A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x64A,
+ },
+ [0x64B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x64B,
+ },
+ [0x64C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x64C,
+ },
+ [0x64D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x64D,
+ },
+ [0x64E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x64E,
+ },
+ [0x64F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x64F,
+ },
+ [0x650]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x650,
+ },
+ [0x651]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x651,
+ },
+ [0x652]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x652,
+ },
+ [0x653]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x653,
+ },
+ [0x654]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x654,
+ },
+ [0x655]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x655,
+ },
+ [0x656]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x656,
+ },
+ [0x657]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x657,
+ },
+ [0x658]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x658,
+ },
+ [0x659]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x659,
+ },
+ [0x65A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x65A,
+ },
+ [0x65B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x65B,
+ },
+ [0x65C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x65C,
+ },
+ [0x65D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x65D,
+ },
+ [0x65E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x65E,
+ },
+ [0x65F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x65F,
+ },
+ [0x660]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x660,
+ },
+ [0x661]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x661,
+ },
+ [0x662]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x662,
+ },
+ [0x663]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x663,
+ },
+ [0x664]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x664,
+ },
+ [0x665]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x665,
+ },
+ [0x666]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x666,
+ },
+ [0x667]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x667,
+ },
+ [0x668]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x668,
+ },
+ [0x669]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x669,
+ },
+ [0x66A]={
+ category="po",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x66A,
+ },
+ [0x66B]={
+ category="po",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x66B,
+ },
+ [0x66C]={
+ category="po",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x66C,
+ },
+ [0x66D]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x66D,
+ },
+ [0x66E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x66E,
+ },
+ [0x66F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x66F,
+ },
+ [0x670]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x670,
+ },
+ [0x671]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x671,
+ },
+ [0x672]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x672,
+ },
+ [0x673]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x673,
+ },
+ [0x674]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x674,
+ },
+ [0x675]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "compat", 0x627, 0x674 },
+ unicodeslot=0x675,
+ },
+ [0x676]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "compat", 0x648, 0x674 },
+ unicodeslot=0x676,
+ },
+ [0x677]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "compat", 0x6C7, 0x674 },
+ unicodeslot=0x677,
+ },
+ [0x678]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "compat", 0x64A, 0x674 },
+ unicodeslot=0x678,
+ },
+ [0x679]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x679,
+ },
+ [0x67A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x67A,
+ },
+ [0x67B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x67B,
+ },
+ [0x67C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x67C,
+ },
+ [0x67D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x67D,
+ },
+ [0x67E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x67E,
+ },
+ [0x67F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x67F,
+ },
+ [0x680]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x680,
+ },
+ [0x681]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x681,
+ },
+ [0x682]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x682,
+ },
+ [0x683]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x683,
+ },
+ [0x684]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x684,
+ },
+ [0x685]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x685,
+ },
+ [0x686]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x686,
+ },
+ [0x687]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x687,
+ },
+ [0x688]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x688,
+ },
+ [0x689]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x689,
+ },
+ [0x68A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x68A,
+ },
+ [0x68B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x68B,
+ },
+ [0x68C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x68C,
+ },
+ [0x68D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x68D,
+ },
+ [0x68E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x68E,
+ },
+ [0x68F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x68F,
+ },
+ [0x690]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x690,
+ },
+ [0x691]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x691,
+ },
+ [0x692]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x692,
+ },
+ [0x693]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x693,
+ },
+ [0x694]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x694,
+ },
+ [0x695]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x695,
+ },
+ [0x696]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x696,
+ },
+ [0x697]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x697,
+ },
+ [0x698]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x698,
+ },
+ [0x699]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x699,
+ },
+ [0x69A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x69A,
+ },
+ [0x69B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x69B,
+ },
+ [0x69C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x69C,
+ },
+ [0x69D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x69D,
+ },
+ [0x69E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x69E,
+ },
+ [0x69F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x69F,
+ },
+ [0x6A0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6A0,
+ },
+ [0x6A1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6A1,
+ },
+ [0x6A2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6A2,
+ },
+ [0x6A3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6A3,
+ },
+ [0x6A4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6A4,
+ },
+ [0x6A5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6A5,
+ },
+ [0x6A6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6A6,
+ },
+ [0x6A7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6A7,
+ },
+ [0x6A8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6A8,
+ },
+ [0x6A9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6A9,
+ },
+ [0x6AA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6AA,
+ },
+ [0x6AB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6AB,
+ },
+ [0x6AC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6AC,
+ },
+ [0x6AD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6AD,
+ },
+ [0x6AE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6AE,
+ },
+ [0x6AF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6AF,
+ },
+ [0x6B0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6B0,
+ },
+ [0x6B1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6B1,
+ },
+ [0x6B2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6B2,
+ },
+ [0x6B3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6B3,
+ },
+ [0x6B4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6B4,
+ },
+ [0x6B5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6B5,
+ },
+ [0x6B6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6B6,
+ },
+ [0x6B7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6B7,
+ },
+ [0x6B8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6B8,
+ },
+ [0x6B9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6B9,
+ },
+ [0x6BA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6BA,
+ },
+ [0x6BB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6BB,
+ },
+ [0x6BC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6BC,
+ },
+ [0x6BD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6BD,
+ },
+ [0x6BE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6BE,
+ },
+ [0x6BF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6BF,
+ },
+ [0x6C0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "char", 0x6D5, 0x654 },
+ unicodeslot=0x6C0,
+ },
+ [0x6C1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6C1,
+ },
+ [0x6C2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "char", 0x6C1, 0x654 },
+ unicodeslot=0x6C2,
+ },
+ [0x6C3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6C3,
+ },
+ [0x6C4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6C4,
+ },
+ [0x6C5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6C5,
+ },
+ [0x6C6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6C6,
+ },
+ [0x6C7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6C7,
+ },
+ [0x6C8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6C8,
+ },
+ [0x6C9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6C9,
+ },
+ [0x6CA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6CA,
+ },
+ [0x6CB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6CB,
+ },
+ [0x6CC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6CC,
+ },
+ [0x6CD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6CD,
+ },
+ [0x6CE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6CE,
+ },
+ [0x6CF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6CF,
+ },
+ [0x6D0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6D0,
+ },
+ [0x6D1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6D1,
+ },
+ [0x6D2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6D2,
+ },
+ [0x6D3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "char", 0x6D2, 0x654 },
+ unicodeslot=0x6D3,
+ },
+ [0x6D4]={
+ category="po",
+ direction="al",
+ linebreak="ex",
+ unicodeslot=0x6D4,
+ },
+ [0x6D5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6D5,
+ },
+ [0x6D6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6D6,
+ },
+ [0x6D7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6D7,
+ },
+ [0x6D8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6D8,
+ },
+ [0x6D9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6D9,
+ },
+ [0x6DA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6DA,
+ },
+ [0x6DB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6DB,
+ },
+ [0x6DC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6DC,
+ },
+ [0x6DD]={
+ category="cf",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x6DD,
+ },
+ [0x6DE]={
+ category="me",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x6DE,
+ },
+ [0x6DF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6DF,
+ },
+ [0x6E0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6E0,
+ },
+ [0x6E1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6E1,
+ },
+ [0x6E2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6E2,
+ },
+ [0x6E3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6E3,
+ },
+ [0x6E4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6E4,
+ },
+ [0x6E5]={
+ category="lm",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6E5,
+ },
+ [0x6E6]={
+ category="lm",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6E6,
+ },
+ [0x6E7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6E7,
+ },
+ [0x6E8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6E8,
+ },
+ [0x6E9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x6E9,
+ },
+ [0x6EA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6EA,
+ },
+ [0x6EB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6EB,
+ },
+ [0x6EC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6EC,
+ },
+ [0x6ED]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x6ED,
+ },
+ [0x6EE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6EE,
+ },
+ [0x6EF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6EF,
+ },
+ [0x6F0]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x6F0,
+ },
+ [0x6F1]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x6F1,
+ },
+ [0x6F2]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x6F2,
+ },
+ [0x6F3]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x6F3,
+ },
+ [0x6F4]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x6F4,
+ },
+ [0x6F5]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x6F5,
+ },
+ [0x6F6]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x6F6,
+ },
+ [0x6F7]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x6F7,
+ },
+ [0x6F8]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x6F8,
+ },
+ [0x6F9]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x6F9,
+ },
+ [0x6FA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6FA,
+ },
+ [0x6FB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6FB,
+ },
+ [0x6FC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6FC,
+ },
+ [0x6FD]={
+ category="so",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6FD,
+ },
+ [0x6FE]={
+ category="so",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6FE,
+ },
+ [0x6FF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x6FF,
+ },
+ [0x700]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x700,
+ },
+ [0x701]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x701,
+ },
+ [0x702]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x702,
+ },
+ [0x703]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x703,
+ },
+ [0x704]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x704,
+ },
+ [0x705]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x705,
+ },
+ [0x706]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x706,
+ },
+ [0x707]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x707,
+ },
+ [0x708]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x708,
+ },
+ [0x709]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x709,
+ },
+ [0x70A]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x70A,
+ },
+ [0x70B]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x70B,
+ },
+ [0x70C]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x70C,
+ },
+ [0x70D]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x70D,
+ },
+ [0x70F]={
+ category="cf",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x70F,
+ },
+ [0x710]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x710,
+ },
+ [0x711]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x711,
+ },
+ [0x712]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x712,
+ },
+ [0x713]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x713,
+ },
+ [0x714]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x714,
+ },
+ [0x715]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x715,
+ },
+ [0x716]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x716,
+ },
+ [0x717]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x717,
+ },
+ [0x718]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x718,
+ },
+ [0x719]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x719,
+ },
+ [0x71A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x71A,
+ },
+ [0x71B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x71B,
+ },
+ [0x71C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x71C,
+ },
+ [0x71D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x71D,
+ },
+ [0x71E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x71E,
+ },
+ [0x71F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x71F,
+ },
+ [0x720]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x720,
+ },
+ [0x721]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x721,
+ },
+ [0x722]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x722,
+ },
+ [0x723]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x723,
+ },
+ [0x724]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x724,
+ },
+ [0x725]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x725,
+ },
+ [0x726]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x726,
+ },
+ [0x727]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x727,
+ },
+ [0x728]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x728,
+ },
+ [0x729]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x729,
+ },
+ [0x72A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x72A,
+ },
+ [0x72B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x72B,
+ },
+ [0x72C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x72C,
+ },
+ [0x72D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x72D,
+ },
+ [0x72E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x72E,
+ },
+ [0x72F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x72F,
+ },
+ [0x730]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x730,
+ },
+ [0x731]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x731,
+ },
+ [0x732]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x732,
+ },
+ [0x733]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x733,
+ },
+ [0x734]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x734,
+ },
+ [0x735]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x735,
+ },
+ [0x736]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x736,
+ },
+ [0x737]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x737,
+ },
+ [0x738]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x738,
+ },
+ [0x739]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x739,
+ },
+ [0x73A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x73A,
+ },
+ [0x73B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x73B,
+ },
+ [0x73C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x73C,
+ },
+ [0x73D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x73D,
+ },
+ [0x73E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x73E,
+ },
+ [0x73F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x73F,
+ },
+ [0x740]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x740,
+ },
+ [0x741]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x741,
+ },
+ [0x742]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x742,
+ },
+ [0x743]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x743,
+ },
+ [0x744]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x744,
+ },
+ [0x745]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x745,
+ },
+ [0x746]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x746,
+ },
+ [0x747]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x747,
+ },
+ [0x748]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x748,
+ },
+ [0x749]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x749,
+ },
+ [0x74A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x74A,
+ },
+ [0x74D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x74D,
+ },
+ [0x74E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x74E,
+ },
+ [0x74F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x74F,
+ },
+ [0x750]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x750,
+ },
+ [0x751]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x751,
+ },
+ [0x752]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x752,
+ },
+ [0x753]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x753,
+ },
+ [0x754]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x754,
+ },
+ [0x755]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x755,
+ },
+ [0x756]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x756,
+ },
+ [0x757]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x757,
+ },
+ [0x758]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x758,
+ },
+ [0x759]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x759,
+ },
+ [0x75A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x75A,
+ },
+ [0x75B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x75B,
+ },
+ [0x75C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x75C,
+ },
+ [0x75D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x75D,
+ },
+ [0x75E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x75E,
+ },
+ [0x75F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x75F,
+ },
+ [0x760]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x760,
+ },
+ [0x761]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x761,
+ },
+ [0x762]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x762,
+ },
+ [0x763]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x763,
+ },
+ [0x764]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x764,
+ },
+ [0x765]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x765,
+ },
+ [0x766]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x766,
+ },
+ [0x767]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x767,
+ },
+ [0x768]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x768,
+ },
+ [0x769]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x769,
+ },
+ [0x76A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x76A,
+ },
+ [0x76B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x76B,
+ },
+ [0x76C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x76C,
+ },
+ [0x76D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x76D,
+ },
+ [0x76E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x76E,
+ },
+ [0x76F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x76F,
+ },
+ [0x770]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x770,
+ },
+ [0x771]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x771,
+ },
+ [0x772]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x772,
+ },
+ [0x773]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x773,
+ },
+ [0x774]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x774,
+ },
+ [0x775]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x775,
+ },
+ [0x776]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x776,
+ },
+ [0x777]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x777,
+ },
+ [0x778]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x778,
+ },
+ [0x779]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x779,
+ },
+ [0x77A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x77A,
+ },
+ [0x77B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x77B,
+ },
+ [0x77C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x77C,
+ },
+ [0x77D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x77D,
+ },
+ [0x77E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x77E,
+ },
+ [0x77F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x77F,
+ },
+ [0x780]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x780,
+ },
+ [0x781]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x781,
+ },
+ [0x782]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x782,
+ },
+ [0x783]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x783,
+ },
+ [0x784]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x784,
+ },
+ [0x785]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x785,
+ },
+ [0x786]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x786,
+ },
+ [0x787]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x787,
+ },
+ [0x788]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x788,
+ },
+ [0x789]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x789,
+ },
+ [0x78A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x78A,
+ },
+ [0x78B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x78B,
+ },
+ [0x78C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x78C,
+ },
+ [0x78D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x78D,
+ },
+ [0x78E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x78E,
+ },
+ [0x78F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x78F,
+ },
+ [0x790]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x790,
+ },
+ [0x791]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x791,
+ },
+ [0x792]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x792,
+ },
+ [0x793]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x793,
+ },
+ [0x794]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x794,
+ },
+ [0x795]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x795,
+ },
+ [0x796]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x796,
+ },
+ [0x797]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x797,
+ },
+ [0x798]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x798,
+ },
+ [0x799]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x799,
+ },
+ [0x79A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x79A,
+ },
+ [0x79B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x79B,
+ },
+ [0x79C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x79C,
+ },
+ [0x79D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x79D,
+ },
+ [0x79E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x79E,
+ },
+ [0x79F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x79F,
+ },
+ [0x7A0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x7A0,
+ },
+ [0x7A1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x7A1,
+ },
+ [0x7A2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x7A2,
+ },
+ [0x7A3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x7A3,
+ },
+ [0x7A4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x7A4,
+ },
+ [0x7A5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x7A5,
+ },
+ [0x7A6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7A6,
+ },
+ [0x7A7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7A7,
+ },
+ [0x7A8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7A8,
+ },
+ [0x7A9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7A9,
+ },
+ [0x7AA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7AA,
+ },
+ [0x7AB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7AB,
+ },
+ [0x7AC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7AC,
+ },
+ [0x7AD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7AD,
+ },
+ [0x7AE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7AE,
+ },
+ [0x7AF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7AF,
+ },
+ [0x7B0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7B0,
+ },
+ [0x7B1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x7B1,
+ },
+ [0x7C0]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x7C0,
+ },
+ [0x7C1]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x7C1,
+ },
+ [0x7C2]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x7C2,
+ },
+ [0x7C3]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x7C3,
+ },
+ [0x7C4]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x7C4,
+ },
+ [0x7C5]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x7C5,
+ },
+ [0x7C6]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x7C6,
+ },
+ [0x7C7]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x7C7,
+ },
+ [0x7C8]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x7C8,
+ },
+ [0x7C9]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x7C9,
+ },
+ [0x7CA]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7CA,
+ },
+ [0x7CB]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7CB,
+ },
+ [0x7CC]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7CC,
+ },
+ [0x7CD]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7CD,
+ },
+ [0x7CE]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7CE,
+ },
+ [0x7CF]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7CF,
+ },
+ [0x7D0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7D0,
+ },
+ [0x7D1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7D1,
+ },
+ [0x7D2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7D2,
+ },
+ [0x7D3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7D3,
+ },
+ [0x7D4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7D4,
+ },
+ [0x7D5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7D5,
+ },
+ [0x7D6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7D6,
+ },
+ [0x7D7]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7D7,
+ },
+ [0x7D8]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7D8,
+ },
+ [0x7D9]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7D9,
+ },
+ [0x7DA]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7DA,
+ },
+ [0x7DB]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7DB,
+ },
+ [0x7DC]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7DC,
+ },
+ [0x7DD]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7DD,
+ },
+ [0x7DE]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7DE,
+ },
+ [0x7DF]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7DF,
+ },
+ [0x7E0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7E0,
+ },
+ [0x7E1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7E1,
+ },
+ [0x7E2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7E2,
+ },
+ [0x7E3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7E3,
+ },
+ [0x7E4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7E4,
+ },
+ [0x7E5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7E5,
+ },
+ [0x7E6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7E6,
+ },
+ [0x7E7]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7E7,
+ },
+ [0x7E8]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7E8,
+ },
+ [0x7E9]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7E9,
+ },
+ [0x7EA]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7EA,
+ },
+ [0x7EB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7EB,
+ },
+ [0x7EC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7EC,
+ },
+ [0x7ED]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7ED,
+ },
+ [0x7EE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7EE,
+ },
+ [0x7EF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7EF,
+ },
+ [0x7F0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7F0,
+ },
+ [0x7F1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7F1,
+ },
+ [0x7F2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7F2,
+ },
+ [0x7F3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7F3,
+ },
+ [0x7F4]={
+ category="lm",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7F4,
+ },
+ [0x7F5]={
+ category="lm",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7F5,
+ },
+ [0x7F6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x7F6,
+ },
+ [0x7F7]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x7F7,
+ },
+ [0x7F8]={
+ category="po",
+ direction="on",
+ linebreak="is",
+ unicodeslot=0x7F8,
+ },
+ [0x7F9]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x7F9,
+ },
+ [0x7FA]={
+ category="lm",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x7FA,
+ },
+ [0x7FD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x7FD,
+ },
+ [0x7FE]={
+ category="sc",
+ direction="r",
+ linebreak="pr",
+ unicodeslot=0x7FE,
+ },
+ [0x7FF]={
+ category="sc",
+ direction="r",
+ linebreak="pr",
+ unicodeslot=0x7FF,
+ },
+ [0x800]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x800,
+ },
+ [0x801]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x801,
+ },
+ [0x802]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x802,
+ },
+ [0x803]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x803,
+ },
+ [0x804]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x804,
+ },
+ [0x805]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x805,
+ },
+ [0x806]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x806,
+ },
+ [0x807]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x807,
+ },
+ [0x808]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x808,
+ },
+ [0x809]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x809,
+ },
+ [0x80A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x80A,
+ },
+ [0x80B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x80B,
+ },
+ [0x80C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x80C,
+ },
+ [0x80D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x80D,
+ },
+ [0x80E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x80E,
+ },
+ [0x80F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x80F,
+ },
+ [0x810]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x810,
+ },
+ [0x811]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x811,
+ },
+ [0x812]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x812,
+ },
+ [0x813]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x813,
+ },
+ [0x814]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x814,
+ },
+ [0x815]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x815,
+ },
+ [0x816]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x816,
+ },
+ [0x817]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x817,
+ },
+ [0x818]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x818,
+ },
+ [0x819]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x819,
+ },
+ [0x81A]={
+ category="lm",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x81A,
+ },
+ [0x81B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x81B,
+ },
+ [0x81C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x81C,
+ },
+ [0x81D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x81D,
+ },
+ [0x81E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x81E,
+ },
+ [0x81F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x81F,
+ },
+ [0x820]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x820,
+ },
+ [0x821]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x821,
+ },
+ [0x822]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x822,
+ },
+ [0x823]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x823,
+ },
+ [0x824]={
+ category="lm",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x824,
+ },
+ [0x825]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x825,
+ },
+ [0x826]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x826,
+ },
+ [0x827]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x827,
+ },
+ [0x828]={
+ category="lm",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x828,
+ },
+ [0x829]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x829,
+ },
+ [0x82A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x82A,
+ },
+ [0x82B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x82B,
+ },
+ [0x82C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x82C,
+ },
+ [0x82D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x82D,
+ },
+ [0x830]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x830,
+ },
+ [0x831]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x831,
+ },
+ [0x832]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x832,
+ },
+ [0x833]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x833,
+ },
+ [0x834]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x834,
+ },
+ [0x835]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x835,
+ },
+ [0x836]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x836,
+ },
+ [0x837]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x837,
+ },
+ [0x838]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x838,
+ },
+ [0x839]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x839,
+ },
+ [0x83A]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x83A,
+ },
+ [0x83B]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x83B,
+ },
+ [0x83C]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x83C,
+ },
+ [0x83D]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x83D,
+ },
+ [0x83E]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x83E,
+ },
+ [0x840]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x840,
+ },
+ [0x841]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x841,
+ },
+ [0x842]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x842,
+ },
+ [0x843]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x843,
+ },
+ [0x844]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x844,
+ },
+ [0x845]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x845,
+ },
+ [0x846]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x846,
+ },
+ [0x847]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x847,
+ },
+ [0x848]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x848,
+ },
+ [0x849]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x849,
+ },
+ [0x84A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x84A,
+ },
+ [0x84B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x84B,
+ },
+ [0x84C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x84C,
+ },
+ [0x84D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x84D,
+ },
+ [0x84E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x84E,
+ },
+ [0x84F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x84F,
+ },
+ [0x850]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x850,
+ },
+ [0x851]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x851,
+ },
+ [0x852]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x852,
+ },
+ [0x853]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x853,
+ },
+ [0x854]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x854,
+ },
+ [0x855]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x855,
+ },
+ [0x856]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x856,
+ },
+ [0x857]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x857,
+ },
+ [0x858]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x858,
+ },
+ [0x859]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x859,
+ },
+ [0x85A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x85A,
+ },
+ [0x85B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x85B,
+ },
+ [0x85E]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x85E,
+ },
+ [0x860]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x860,
+ },
+ [0x861]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x861,
+ },
+ [0x862]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x862,
+ },
+ [0x863]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x863,
+ },
+ [0x864]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x864,
+ },
+ [0x865]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x865,
+ },
+ [0x866]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x866,
+ },
+ [0x867]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x867,
+ },
+ [0x868]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x868,
+ },
+ [0x869]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x869,
+ },
+ [0x86A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x86A,
+ },
+ [0x8A0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8A0,
+ },
+ [0x8A1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8A1,
+ },
+ [0x8A2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8A2,
+ },
+ [0x8A3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8A3,
+ },
+ [0x8A4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8A4,
+ },
+ [0x8A5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8A5,
+ },
+ [0x8A6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8A6,
+ },
+ [0x8A7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8A7,
+ },
+ [0x8A8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8A8,
+ },
+ [0x8A9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8A9,
+ },
+ [0x8AA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8AA,
+ },
+ [0x8AB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8AB,
+ },
+ [0x8AC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8AC,
+ },
+ [0x8AD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8AD,
+ },
+ [0x8AE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8AE,
+ },
+ [0x8AF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8AF,
+ },
+ [0x8B0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8B0,
+ },
+ [0x8B1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8B1,
+ },
+ [0x8B2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8B2,
+ },
+ [0x8B3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8B3,
+ },
+ [0x8B4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8B4,
+ },
+ [0x8B6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8B6,
+ },
+ [0x8B7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8B7,
+ },
+ [0x8B8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8B8,
+ },
+ [0x8B9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8B9,
+ },
+ [0x8BA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8BA,
+ },
+ [0x8BB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8BB,
+ },
+ [0x8BC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8BC,
+ },
+ [0x8BD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8BD,
+ },
+ [0x8D3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8D3,
+ },
+ [0x8D4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8D4,
+ },
+ [0x8D5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8D5,
+ },
+ [0x8D6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8D6,
+ },
+ [0x8D7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8D7,
+ },
+ [0x8D8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8D8,
+ },
+ [0x8D9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8D9,
+ },
+ [0x8DA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8DA,
+ },
+ [0x8DB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8DB,
+ },
+ [0x8DC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8DC,
+ },
+ [0x8DD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8DD,
+ },
+ [0x8DE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8DE,
+ },
+ [0x8DF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8DF,
+ },
+ [0x8E0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8E0,
+ },
+ [0x8E1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8E1,
+ },
+ [0x8E2]={
+ category="cf",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x8E2,
+ },
+ [0x8E3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8E3,
+ },
+ [0x8E4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8E4,
+ },
+ [0x8E5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8E5,
+ },
+ [0x8E6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8E6,
+ },
+ [0x8E7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8E7,
+ },
+ [0x8E8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8E8,
+ },
+ [0x8E9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8E9,
+ },
+ [0x8EA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8EA,
+ },
+ [0x8EB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8EB,
+ },
+ [0x8EC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8EC,
+ },
+ [0x8ED]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8ED,
+ },
+ [0x8EE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8EE,
+ },
+ [0x8EF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8EF,
+ },
+ [0x8F0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8F0,
+ },
+ [0x8F1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8F1,
+ },
+ [0x8F2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8F2,
+ },
+ [0x8F3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8F3,
+ },
+ [0x8F4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8F4,
+ },
+ [0x8F5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8F5,
+ },
+ [0x8F6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8F6,
+ },
+ [0x8F7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8F7,
+ },
+ [0x8F8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8F8,
+ },
+ [0x8F9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8F9,
+ },
+ [0x8FA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8FA,
+ },
+ [0x8FB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8FB,
+ },
+ [0x8FC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8FC,
+ },
+ [0x8FD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8FD,
+ },
+ [0x8FE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8FE,
+ },
+ [0x8FF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x8FF,
+ },
+ [0x900]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0x900,
+ },
+ [0x901]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0x901,
+ },
+ [0x902]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0x902,
+ },
+ [0x903]={
+ category="mc",
+ direction="l",
+ indic="m",
+ indicmark="r",
+ linebreak="cm",
+ unicodeslot=0x903,
+ },
+ [0x904]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x904,
+ },
+ [0x905]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x905,
+ },
+ [0x906]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x906,
+ },
+ [0x907]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x907,
+ },
+ [0x908]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x908,
+ },
+ [0x909]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x909,
+ },
+ [0x90A]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x90A,
+ },
+ [0x90B]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x90B,
+ },
+ [0x90C]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x90C,
+ },
+ [0x90D]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x90D,
+ },
+ [0x90E]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x90E,
+ },
+ [0x90F]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x90F,
+ },
+ [0x910]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x910,
+ },
+ [0x911]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x911,
+ },
+ [0x912]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x912,
+ },
+ [0x913]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x913,
+ },
+ [0x914]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x914,
+ },
+ [0x915]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x915,
+ },
+ [0x916]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x916,
+ },
+ [0x917]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x917,
+ },
+ [0x918]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x918,
+ },
+ [0x919]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x919,
+ },
+ [0x91A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x91A,
+ },
+ [0x91B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x91B,
+ },
+ [0x91C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x91C,
+ },
+ [0x91D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x91D,
+ },
+ [0x91E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x91E,
+ },
+ [0x91F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x91F,
+ },
+ [0x920]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x920,
+ },
+ [0x921]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x921,
+ },
+ [0x922]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x922,
+ },
+ [0x923]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x923,
+ },
+ [0x924]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x924,
+ },
+ [0x925]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x925,
+ },
+ [0x926]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x926,
+ },
+ [0x927]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x927,
+ },
+ [0x928]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x928,
+ },
+ [0x929]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x928, 0x93C },
+ unicodeslot=0x929,
+ },
+ [0x92A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x92A,
+ },
+ [0x92B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x92B,
+ },
+ [0x92C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x92C,
+ },
+ [0x92D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x92D,
+ },
+ [0x92E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x92E,
+ },
+ [0x92F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x92F,
+ },
+ [0x930]={
+ category="lo",
+ direction="l",
+ indic="c",
+ indicclass="ra",
+ indicorder="bp",
+ linebreak="al",
+ unicodeslot=0x930,
+ },
+ [0x931]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x930, 0x93C },
+ unicodeslot=0x931,
+ },
+ [0x932]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x932,
+ },
+ [0x933]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x933,
+ },
+ [0x934]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x933, 0x93C },
+ unicodeslot=0x934,
+ },
+ [0x935]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x935,
+ },
+ [0x936]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x936,
+ },
+ [0x937]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x937,
+ },
+ [0x938]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x938,
+ },
+ [0x939]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x939,
+ },
+ [0x93A]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0x93A,
+ },
+ [0x93B]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ linebreak="cm",
+ unicodeslot=0x93B,
+ },
+ [0x93C]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="nukta",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0x93C,
+ },
+ [0x93D]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x93D,
+ },
+ [0x93E]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x93E,
+ },
+ [0x93F]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bh",
+ linebreak="cm",
+ unicodeslot=0x93F,
+ },
+ [0x940]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x940,
+ },
+ [0x941]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x941,
+ },
+ [0x942]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x942,
+ },
+ [0x943]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x943,
+ },
+ [0x944]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x944,
+ },
+ [0x945]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x945,
+ },
+ [0x946]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x946,
+ },
+ [0x947]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x947,
+ },
+ [0x948]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x948,
+ },
+ [0x949]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x949,
+ },
+ [0x94A]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x94A,
+ },
+ [0x94B]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x94B,
+ },
+ [0x94C]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x94C,
+ },
+ [0x94D]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="halant",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0x94D,
+ },
+ [0x94E]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bh",
+ linebreak="cm",
+ unicodeslot=0x94E,
+ },
+ [0x94F]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ linebreak="cm",
+ unicodeslot=0x94F,
+ },
+ [0x950]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x950,
+ },
+ [0x951]={
+ category="mn",
+ direction="nsm",
+ indic="s",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0x951,
+ },
+ [0x952]={
+ category="mn",
+ direction="nsm",
+ indic="s",
+ indicclass="anudatta",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0x952,
+ },
+ [0x953]={
+ category="mn",
+ direction="nsm",
+ indic="s",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0x953,
+ },
+ [0x954]={
+ category="mn",
+ direction="nsm",
+ indic="s",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0x954,
+ },
+ [0x955]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0x955,
+ },
+ [0x956]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0x956,
+ },
+ [0x957]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0x957,
+ },
+ [0x958]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x915, 0x93C },
+ unicodeslot=0x958,
+ },
+ [0x959]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x916, 0x93C },
+ unicodeslot=0x959,
+ },
+ [0x95A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x917, 0x93C },
+ unicodeslot=0x95A,
+ },
+ [0x95B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x91C, 0x93C },
+ unicodeslot=0x95B,
+ },
+ [0x95C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x921, 0x93C },
+ unicodeslot=0x95C,
+ },
+ [0x95D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x922, 0x93C },
+ unicodeslot=0x95D,
+ },
+ [0x95E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x92B, 0x93C },
+ unicodeslot=0x95E,
+ },
+ [0x95F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x92F, 0x93C },
+ unicodeslot=0x95F,
+ },
+ [0x960]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x960,
+ },
+ [0x961]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x961,
+ },
+ [0x962]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x962,
+ },
+ [0x963]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x963,
+ },
+ [0x964]={
+ category="po",
+ direction="l",
+ indic="o",
+ linebreak="ba",
+ unicodeslot=0x964,
+ },
+ [0x965]={
+ category="po",
+ direction="l",
+ indic="o",
+ linebreak="ba",
+ unicodeslot=0x965,
+ },
+ [0x966]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x966,
+ },
+ [0x967]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x967,
+ },
+ [0x968]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x968,
+ },
+ [0x969]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x969,
+ },
+ [0x96A]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x96A,
+ },
+ [0x96B]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x96B,
+ },
+ [0x96C]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x96C,
+ },
+ [0x96D]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x96D,
+ },
+ [0x96E]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x96E,
+ },
+ [0x96F]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x96F,
+ },
+ [0x970]={
+ category="po",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x970,
+ },
+ [0x971]={
+ category="lm",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x971,
+ },
+ [0x972]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x972,
+ },
+ [0x973]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x973,
+ },
+ [0x974]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x974,
+ },
+ [0x975]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x975,
+ },
+ [0x976]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x976,
+ },
+ [0x977]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x977,
+ },
+ [0x978]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x978,
+ },
+ [0x979]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x979,
+ },
+ [0x97A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x97A,
+ },
+ [0x97B]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x97B,
+ },
+ [0x97C]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x97C,
+ },
+ [0x97D]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x97D,
+ },
+ [0x97E]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x97E,
+ },
+ [0x97F]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x97F,
+ },
+ [0x980]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x980,
+ },
+ [0x981]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0x981,
+ },
+ [0x982]={
+ category="mc",
+ direction="l",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0x982,
+ },
+ [0x983]={
+ category="mc",
+ direction="l",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0x983,
+ },
+ [0x985]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x985,
+ },
+ [0x986]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x986,
+ },
+ [0x987]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x987,
+ },
+ [0x988]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x988,
+ },
+ [0x989]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x989,
+ },
+ [0x98A]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x98A,
+ },
+ [0x98B]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x98B,
+ },
+ [0x98C]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x98C,
+ },
+ [0x98F]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x98F,
+ },
+ [0x990]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x990,
+ },
+ [0x993]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x993,
+ },
+ [0x994]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x994,
+ },
+ [0x995]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x995,
+ },
+ [0x996]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x996,
+ },
+ [0x997]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x997,
+ },
+ [0x998]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x998,
+ },
+ [0x999]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x999,
+ },
+ [0x99A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x99A,
+ },
+ [0x99B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x99B,
+ },
+ [0x99C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x99C,
+ },
+ [0x99D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x99D,
+ },
+ [0x99E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x99E,
+ },
+ [0x99F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x99F,
+ },
+ [0x9A0]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9A0,
+ },
+ [0x9A1]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9A1,
+ },
+ [0x9A2]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9A2,
+ },
+ [0x9A3]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9A3,
+ },
+ [0x9A4]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9A4,
+ },
+ [0x9A5]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9A5,
+ },
+ [0x9A6]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9A6,
+ },
+ [0x9A7]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9A7,
+ },
+ [0x9A8]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9A8,
+ },
+ [0x9AA]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9AA,
+ },
+ [0x9AB]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9AB,
+ },
+ [0x9AC]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9AC,
+ },
+ [0x9AD]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9AD,
+ },
+ [0x9AE]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9AE,
+ },
+ [0x9AF]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9AF,
+ },
+ [0x9B0]={
+ category="lo",
+ direction="l",
+ indic="c",
+ indicclass="ra",
+ indicorder="as",
+ linebreak="al",
+ unicodeslot=0x9B0,
+ },
+ [0x9B2]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9B2,
+ },
+ [0x9B6]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9B6,
+ },
+ [0x9B7]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9B7,
+ },
+ [0x9B8]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9B8,
+ },
+ [0x9B9]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9B9,
+ },
+ [0x9BC]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="nukta",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0x9BC,
+ },
+ [0x9BD]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x9BD,
+ },
+ [0x9BE]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0x9BE,
+ },
+ [0x9BF]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bh",
+ linebreak="cm",
+ unicodeslot=0x9BF,
+ },
+ [0x9C0]={
+ category="mc",
+ direction="l",
+ indic="o",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0x9C0,
+ },
+ [0x9C1]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x9C1,
+ },
+ [0x9C2]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x9C2,
+ },
+ [0x9C3]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x9C3,
+ },
+ [0x9C4]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x9C4,
+ },
+ [0x9C7]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bh",
+ linebreak="cm",
+ unicodeslot=0x9C7,
+ },
+ [0x9C8]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bh",
+ linebreak="cm",
+ unicodeslot=0x9C8,
+ },
+ [0x9CB]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0x9C7, 0x9BE },
+ unicodeslot=0x9CB,
+ },
+ [0x9CC]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0x9C7, 0x9D7 },
+ unicodeslot=0x9CC,
+ },
+ [0x9CD]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="halant",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0x9CD,
+ },
+ [0x9CE]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0x9CE,
+ },
+ [0x9D7]={
+ category="mc",
+ direction="l",
+ indic="o",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0x9D7,
+ },
+ [0x9DC]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x9A1, 0x9BC },
+ unicodeslot=0x9DC,
+ },
+ [0x9DD]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x9A2, 0x9BC },
+ unicodeslot=0x9DD,
+ },
+ [0x9DF]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0x9AF, 0x9BC },
+ unicodeslot=0x9DF,
+ },
+ [0x9E0]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x9E0,
+ },
+ [0x9E1]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0x9E1,
+ },
+ [0x9E2]={
+ category="mn",
+ direction="nsm",
+ indic="i",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x9E2,
+ },
+ [0x9E3]={
+ category="mn",
+ direction="nsm",
+ indic="i",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0x9E3,
+ },
+ [0x9E6]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x9E6,
+ },
+ [0x9E7]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x9E7,
+ },
+ [0x9E8]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x9E8,
+ },
+ [0x9E9]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x9E9,
+ },
+ [0x9EA]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x9EA,
+ },
+ [0x9EB]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x9EB,
+ },
+ [0x9EC]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x9EC,
+ },
+ [0x9ED]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x9ED,
+ },
+ [0x9EE]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x9EE,
+ },
+ [0x9EF]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x9EF,
+ },
+ [0x9F0]={
+ category="lo",
+ direction="l",
+ indic="o",
+ indicclass="ra",
+ indicorder="as",
+ linebreak="al",
+ unicodeslot=0x9F0,
+ },
+ [0x9F1]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x9F1,
+ },
+ [0x9F2]={
+ category="sc",
+ direction="et",
+ indic="o",
+ linebreak="po",
+ unicodeslot=0x9F2,
+ },
+ [0x9F3]={
+ category="sc",
+ direction="et",
+ indic="o",
+ linebreak="po",
+ unicodeslot=0x9F3,
+ },
+ [0x9F4]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x9F4,
+ },
+ [0x9F5]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x9F5,
+ },
+ [0x9F6]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x9F6,
+ },
+ [0x9F7]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x9F7,
+ },
+ [0x9F8]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x9F8,
+ },
+ [0x9F9]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="po",
+ unicodeslot=0x9F9,
+ },
+ [0x9FA]={
+ category="so",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x9FA,
+ },
+ [0x9FB]={
+ category="sc",
+ direction="et",
+ indic="o",
+ linebreak="pr",
+ unicodeslot=0x9FB,
+ },
+ [0x9FC]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x9FC,
+ },
+ [0x9FD]={
+ category="po",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x9FD,
+ },
+ [0x9FE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x9FE,
+ },
+ [0xA01]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xA01,
+ },
+ [0xA02]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xA02,
+ },
+ [0xA03]={
+ category="mc",
+ direction="l",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xA03,
+ },
+ [0xA05]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA05,
+ },
+ [0xA06]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA06,
+ },
+ [0xA07]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA07,
+ },
+ [0xA08]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA08,
+ },
+ [0xA09]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA09,
+ },
+ [0xA0A]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA0A,
+ },
+ [0xA0F]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA0F,
+ },
+ [0xA10]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA10,
+ },
+ [0xA13]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA13,
+ },
+ [0xA14]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA14,
+ },
+ [0xA15]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA15,
+ },
+ [0xA16]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA16,
+ },
+ [0xA17]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA17,
+ },
+ [0xA18]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA18,
+ },
+ [0xA19]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA19,
+ },
+ [0xA1A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA1A,
+ },
+ [0xA1B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA1B,
+ },
+ [0xA1C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA1C,
+ },
+ [0xA1D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA1D,
+ },
+ [0xA1E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA1E,
+ },
+ [0xA1F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA1F,
+ },
+ [0xA20]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA20,
+ },
+ [0xA21]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA21,
+ },
+ [0xA22]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA22,
+ },
+ [0xA23]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA23,
+ },
+ [0xA24]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA24,
+ },
+ [0xA25]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA25,
+ },
+ [0xA26]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA26,
+ },
+ [0xA27]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA27,
+ },
+ [0xA28]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA28,
+ },
+ [0xA2A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA2A,
+ },
+ [0xA2B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA2B,
+ },
+ [0xA2C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA2C,
+ },
+ [0xA2D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA2D,
+ },
+ [0xA2E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA2E,
+ },
+ [0xA2F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA2F,
+ },
+ [0xA30]={
+ category="lo",
+ direction="l",
+ indic="c",
+ indicclass="ra",
+ indicorder="bs",
+ linebreak="al",
+ unicodeslot=0xA30,
+ },
+ [0xA32]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA32,
+ },
+ [0xA33]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0xA32, 0xA3C },
+ unicodeslot=0xA33,
+ },
+ [0xA35]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA35,
+ },
+ [0xA36]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0xA38, 0xA3C },
+ unicodeslot=0xA36,
+ },
+ [0xA38]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA38,
+ },
+ [0xA39]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA39,
+ },
+ [0xA3C]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="nukta",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xA3C,
+ },
+ [0xA3E]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xA3E,
+ },
+ [0xA3F]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bh",
+ linebreak="cm",
+ unicodeslot=0xA3F,
+ },
+ [0xA40]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xA40,
+ },
+ [0xA41]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xA41,
+ },
+ [0xA42]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xA42,
+ },
+ [0xA47]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xA47,
+ },
+ [0xA48]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xA48,
+ },
+ [0xA4B]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xA4B,
+ },
+ [0xA4C]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xA4C,
+ },
+ [0xA4D]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="halant",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xA4D,
+ },
+ [0xA51]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xA51,
+ },
+ [0xA59]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0xA16, 0xA3C },
+ unicodeslot=0xA59,
+ },
+ [0xA5A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0xA17, 0xA3C },
+ unicodeslot=0xA5A,
+ },
+ [0xA5B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0xA1C, 0xA3C },
+ unicodeslot=0xA5B,
+ },
+ [0xA5C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA5C,
+ },
+ [0xA5E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0xA2B, 0xA3C },
+ unicodeslot=0xA5E,
+ },
+ [0xA66]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA66,
+ },
+ [0xA67]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA67,
+ },
+ [0xA68]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA68,
+ },
+ [0xA69]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA69,
+ },
+ [0xA6A]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA6A,
+ },
+ [0xA6B]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA6B,
+ },
+ [0xA6C]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA6C,
+ },
+ [0xA6D]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA6D,
+ },
+ [0xA6E]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA6E,
+ },
+ [0xA6F]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA6F,
+ },
+ [0xA70]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xA70,
+ },
+ [0xA71]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xA71,
+ },
+ [0xA72]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xA72,
+ },
+ [0xA73]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xA73,
+ },
+ [0xA74]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xA74,
+ },
+ [0xA75]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xA75,
+ },
+ [0xA76]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76,
+ },
+ [0xA81]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xA81,
+ },
+ [0xA82]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA82,
+ },
+ [0xA83]={
+ category="mc",
+ direction="l",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xA83,
+ },
+ [0xA85]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA85,
+ },
+ [0xA86]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA86,
+ },
+ [0xA87]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA87,
+ },
+ [0xA88]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA88,
+ },
+ [0xA89]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA89,
+ },
+ [0xA8A]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA8A,
+ },
+ [0xA8B]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA8B,
+ },
+ [0xA8C]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA8C,
+ },
+ [0xA8D]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA8D,
+ },
+ [0xA8F]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA8F,
+ },
+ [0xA90]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA90,
+ },
+ [0xA91]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA91,
+ },
+ [0xA93]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA93,
+ },
+ [0xA94]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xA94,
+ },
+ [0xA95]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA95,
+ },
+ [0xA96]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA96,
+ },
+ [0xA97]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA97,
+ },
+ [0xA98]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA98,
+ },
+ [0xA99]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA99,
+ },
+ [0xA9A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA9A,
+ },
+ [0xA9B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA9B,
+ },
+ [0xA9C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA9C,
+ },
+ [0xA9D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA9D,
+ },
+ [0xA9E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA9E,
+ },
+ [0xA9F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xA9F,
+ },
+ [0xAA0]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAA0,
+ },
+ [0xAA1]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAA1,
+ },
+ [0xAA2]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAA2,
+ },
+ [0xAA3]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAA3,
+ },
+ [0xAA4]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAA4,
+ },
+ [0xAA5]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAA5,
+ },
+ [0xAA6]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAA6,
+ },
+ [0xAA7]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAA7,
+ },
+ [0xAA8]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAA8,
+ },
+ [0xAAA]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAAA,
+ },
+ [0xAAB]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAAB,
+ },
+ [0xAAC]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAAC,
+ },
+ [0xAAD]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAAD,
+ },
+ [0xAAE]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAAE,
+ },
+ [0xAAF]={
+ category="lo",
+ direction="l",
+ indic="c",
+ indicorder="ap",
+ linebreak="al",
+ unicodeslot=0xAAF,
+ },
+ [0xAB0]={
+ category="lo",
+ direction="l",
+ indic="c",
+ indicclass="ra",
+ indicorder="bp",
+ linebreak="al",
+ unicodeslot=0xAB0,
+ },
+ [0xAB2]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAB2,
+ },
+ [0xAB3]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAB3,
+ },
+ [0xAB5]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAB5,
+ },
+ [0xAB6]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAB6,
+ },
+ [0xAB7]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAB7,
+ },
+ [0xAB8]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAB8,
+ },
+ [0xAB9]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xAB9,
+ },
+ [0xABC]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="nukta",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xABC,
+ },
+ [0xABD]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xABD,
+ },
+ [0xABE]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xABE,
+ },
+ [0xABF]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bh",
+ linebreak="cm",
+ unicodeslot=0xABF,
+ },
+ [0xAC0]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xAC0,
+ },
+ [0xAC1]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xAC1,
+ },
+ [0xAC2]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xAC2,
+ },
+ [0xAC3]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xAC3,
+ },
+ [0xAC4]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xAC4,
+ },
+ [0xAC5]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xAC5,
+ },
+ [0xAC7]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xAC7,
+ },
+ [0xAC8]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xAC8,
+ },
+ [0xAC9]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xAC9,
+ },
+ [0xACB]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xACB,
+ },
+ [0xACC]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xACC,
+ },
+ [0xACD]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="halant",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xACD,
+ },
+ [0xAD0]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xAD0,
+ },
+ [0xAE0]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xAE0,
+ },
+ [0xAE1]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xAE1,
+ },
+ [0xAE2]={
+ category="mn",
+ direction="nsm",
+ indic="i",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xAE2,
+ },
+ [0xAE3]={
+ category="mn",
+ direction="nsm",
+ indic="i",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xAE3,
+ },
+ [0xAE6]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xAE6,
+ },
+ [0xAE7]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xAE7,
+ },
+ [0xAE8]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xAE8,
+ },
+ [0xAE9]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xAE9,
+ },
+ [0xAEA]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xAEA,
+ },
+ [0xAEB]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xAEB,
+ },
+ [0xAEC]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xAEC,
+ },
+ [0xAED]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xAED,
+ },
+ [0xAEE]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xAEE,
+ },
+ [0xAEF]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xAEF,
+ },
+ [0xAF0]={
+ category="po",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xAF0,
+ },
+ [0xAF1]={
+ category="sc",
+ direction="et",
+ indic="o",
+ linebreak="pr",
+ unicodeslot=0xAF1,
+ },
+ [0xAF9]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xAF9,
+ },
+ [0xAFA]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xAFA,
+ },
+ [0xAFB]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xAFB,
+ },
+ [0xAFC]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xAFC,
+ },
+ [0xAFD]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xAFD,
+ },
+ [0xAFE]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xAFE,
+ },
+ [0xAFF]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xAFF,
+ },
+ [0xB01]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xB01,
+ },
+ [0xB02]={
+ category="mc",
+ direction="l",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xB02,
+ },
+ [0xB03]={
+ category="mc",
+ direction="l",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xB03,
+ },
+ [0xB05]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB05,
+ },
+ [0xB06]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB06,
+ },
+ [0xB07]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB07,
+ },
+ [0xB08]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB08,
+ },
+ [0xB09]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB09,
+ },
+ [0xB0A]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB0A,
+ },
+ [0xB0B]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB0B,
+ },
+ [0xB0C]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB0C,
+ },
+ [0xB0F]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB0F,
+ },
+ [0xB10]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB10,
+ },
+ [0xB13]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB13,
+ },
+ [0xB14]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB14,
+ },
+ [0xB15]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB15,
+ },
+ [0xB16]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB16,
+ },
+ [0xB17]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB17,
+ },
+ [0xB18]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB18,
+ },
+ [0xB19]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB19,
+ },
+ [0xB1A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB1A,
+ },
+ [0xB1B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB1B,
+ },
+ [0xB1C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB1C,
+ },
+ [0xB1D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB1D,
+ },
+ [0xB1E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB1E,
+ },
+ [0xB1F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB1F,
+ },
+ [0xB20]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB20,
+ },
+ [0xB21]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB21,
+ },
+ [0xB22]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB22,
+ },
+ [0xB23]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB23,
+ },
+ [0xB24]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB24,
+ },
+ [0xB25]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB25,
+ },
+ [0xB26]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB26,
+ },
+ [0xB27]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB27,
+ },
+ [0xB28]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB28,
+ },
+ [0xB2A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB2A,
+ },
+ [0xB2B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB2B,
+ },
+ [0xB2C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB2C,
+ },
+ [0xB2D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB2D,
+ },
+ [0xB2E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB2E,
+ },
+ [0xB2F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB2F,
+ },
+ [0xB30]={
+ category="lo",
+ direction="l",
+ indic="c",
+ indicclass="ra",
+ indicorder="am",
+ linebreak="al",
+ unicodeslot=0xB30,
+ },
+ [0xB32]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB32,
+ },
+ [0xB33]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB33,
+ },
+ [0xB35]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB35,
+ },
+ [0xB36]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB36,
+ },
+ [0xB37]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB37,
+ },
+ [0xB38]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB38,
+ },
+ [0xB39]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB39,
+ },
+ [0xB3C]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="nukta",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xB3C,
+ },
+ [0xB3D]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xB3D,
+ },
+ [0xB3E]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xB3E,
+ },
+ [0xB3F]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="am",
+ linebreak="cm",
+ unicodeslot=0xB3F,
+ },
+ [0xB40]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xB40,
+ },
+ [0xB41]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xB41,
+ },
+ [0xB42]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xB42,
+ },
+ [0xB43]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xB43,
+ },
+ [0xB44]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xB44,
+ },
+ [0xB47]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bh",
+ linebreak="cm",
+ unicodeslot=0xB47,
+ },
+ [0xB48]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xB47, 0xB56 },
+ unicodeslot=0xB48,
+ },
+ [0xB4B]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xB47, 0xB3E },
+ unicodeslot=0xB4B,
+ },
+ [0xB4C]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xB47, 0xB57 },
+ unicodeslot=0xB4C,
+ },
+ [0xB4D]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="halant",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xB4D,
+ },
+ [0xB56]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicorder="am",
+ linebreak="cm",
+ unicodeslot=0xB56,
+ },
+ [0xB57]={
+ category="mc",
+ direction="l",
+ indic="o",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xB57,
+ },
+ [0xB5C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0xB21, 0xB3C },
+ unicodeslot=0xB5C,
+ },
+ [0xB5D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ specials={ "char", 0xB22, 0xB3C },
+ unicodeslot=0xB5D,
+ },
+ [0xB5F]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xB5F,
+ },
+ [0xB60]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB60,
+ },
+ [0xB61]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB61,
+ },
+ [0xB62]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xB62,
+ },
+ [0xB63]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xB63,
+ },
+ [0xB66]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xB66,
+ },
+ [0xB67]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xB67,
+ },
+ [0xB68]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xB68,
+ },
+ [0xB69]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xB69,
+ },
+ [0xB6A]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xB6A,
+ },
+ [0xB6B]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xB6B,
+ },
+ [0xB6C]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xB6C,
+ },
+ [0xB6D]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xB6D,
+ },
+ [0xB6E]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xB6E,
+ },
+ [0xB6F]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xB6F,
+ },
+ [0xB70]={
+ category="so",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xB70,
+ },
+ [0xB71]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB71,
+ },
+ [0xB72]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xB72,
+ },
+ [0xB73]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xB73,
+ },
+ [0xB74]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xB74,
+ },
+ [0xB75]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xB75,
+ },
+ [0xB76]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xB76,
+ },
+ [0xB77]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xB77,
+ },
+ [0xB82]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xB82,
+ },
+ [0xB83]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xB83,
+ },
+ [0xB85]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB85,
+ },
+ [0xB86]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB86,
+ },
+ [0xB87]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB87,
+ },
+ [0xB88]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB88,
+ },
+ [0xB89]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB89,
+ },
+ [0xB8A]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB8A,
+ },
+ [0xB8E]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB8E,
+ },
+ [0xB8F]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB8F,
+ },
+ [0xB90]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB90,
+ },
+ [0xB92]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB92,
+ },
+ [0xB93]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xB93,
+ },
+ [0xB94]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ specials={ "char", 0xB92, 0xBD7 },
+ unicodeslot=0xB94,
+ },
+ [0xB95]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB95,
+ },
+ [0xB99]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB99,
+ },
+ [0xB9A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB9A,
+ },
+ [0xB9C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB9C,
+ },
+ [0xB9E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB9E,
+ },
+ [0xB9F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xB9F,
+ },
+ [0xBA3]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBA3,
+ },
+ [0xBA4]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBA4,
+ },
+ [0xBA8]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBA8,
+ },
+ [0xBA9]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBA9,
+ },
+ [0xBAA]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBAA,
+ },
+ [0xBAE]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBAE,
+ },
+ [0xBAF]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBAF,
+ },
+ [0xBB0]={
+ category="lo",
+ direction="l",
+ indic="c",
+ indicclass="ra",
+ indicorder="ap",
+ linebreak="al",
+ unicodeslot=0xBB0,
+ },
+ [0xBB1]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBB1,
+ },
+ [0xBB2]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBB2,
+ },
+ [0xBB3]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBB3,
+ },
+ [0xBB4]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBB4,
+ },
+ [0xBB5]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBB5,
+ },
+ [0xBB6]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBB6,
+ },
+ [0xBB7]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBB7,
+ },
+ [0xBB8]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBB8,
+ },
+ [0xBB9]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xBB9,
+ },
+ [0xBBE]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xBBE,
+ },
+ [0xBBF]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xBBF,
+ },
+ [0xBC0]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xBC0,
+ },
+ [0xBC1]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="b",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xBC1,
+ },
+ [0xBC2]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="b",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xBC2,
+ },
+ [0xBC6]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bm",
+ linebreak="cm",
+ unicodeslot=0xBC6,
+ },
+ [0xBC7]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bm",
+ linebreak="cm",
+ unicodeslot=0xBC7,
+ },
+ [0xBC8]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bm",
+ linebreak="cm",
+ unicodeslot=0xBC8,
+ },
+ [0xBCA]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xBC6, 0xBBE },
+ unicodeslot=0xBCA,
+ },
+ [0xBCB]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xBC7, 0xBBE },
+ unicodeslot=0xBCB,
+ },
+ [0xBCC]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xBC6, 0xBD7 },
+ unicodeslot=0xBCC,
+ },
+ [0xBCD]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="halant",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xBCD,
+ },
+ [0xBD0]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xBD0,
+ },
+ [0xBD7]={
+ category="mc",
+ direction="l",
+ indic="o",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xBD7,
+ },
+ [0xBE6]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xBE6,
+ },
+ [0xBE7]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xBE7,
+ },
+ [0xBE8]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xBE8,
+ },
+ [0xBE9]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xBE9,
+ },
+ [0xBEA]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xBEA,
+ },
+ [0xBEB]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xBEB,
+ },
+ [0xBEC]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xBEC,
+ },
+ [0xBED]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xBED,
+ },
+ [0xBEE]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xBEE,
+ },
+ [0xBEF]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xBEF,
+ },
+ [0xBF0]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xBF0,
+ },
+ [0xBF1]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xBF1,
+ },
+ [0xBF2]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xBF2,
+ },
+ [0xBF3]={
+ category="so",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xBF3,
+ },
+ [0xBF4]={
+ category="so",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xBF4,
+ },
+ [0xBF5]={
+ category="so",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xBF5,
+ },
+ [0xBF6]={
+ category="so",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xBF6,
+ },
+ [0xBF7]={
+ category="so",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xBF7,
+ },
+ [0xBF8]={
+ category="so",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xBF8,
+ },
+ [0xBF9]={
+ category="sc",
+ direction="et",
+ indic="o",
+ linebreak="pr",
+ unicodeslot=0xBF9,
+ },
+ [0xBFA]={
+ category="so",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xBFA,
+ },
+ [0xC00]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xC00,
+ },
+ [0xC01]={
+ category="mc",
+ direction="l",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xC01,
+ },
+ [0xC02]={
+ category="mc",
+ direction="l",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xC02,
+ },
+ [0xC03]={
+ category="mc",
+ direction="l",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xC03,
+ },
+ [0xC04]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xC04,
+ },
+ [0xC05]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC05,
+ },
+ [0xC06]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC06,
+ },
+ [0xC07]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC07,
+ },
+ [0xC08]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC08,
+ },
+ [0xC09]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC09,
+ },
+ [0xC0A]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC0A,
+ },
+ [0xC0B]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC0B,
+ },
+ [0xC0C]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC0C,
+ },
+ [0xC0E]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC0E,
+ },
+ [0xC0F]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC0F,
+ },
+ [0xC10]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC10,
+ },
+ [0xC12]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC12,
+ },
+ [0xC13]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC13,
+ },
+ [0xC14]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC14,
+ },
+ [0xC15]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC15,
+ },
+ [0xC16]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC16,
+ },
+ [0xC17]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC17,
+ },
+ [0xC18]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC18,
+ },
+ [0xC19]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC19,
+ },
+ [0xC1A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC1A,
+ },
+ [0xC1B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC1B,
+ },
+ [0xC1C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC1C,
+ },
+ [0xC1D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC1D,
+ },
+ [0xC1E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC1E,
+ },
+ [0xC1F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC1F,
+ },
+ [0xC20]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC20,
+ },
+ [0xC21]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC21,
+ },
+ [0xC22]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC22,
+ },
+ [0xC23]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC23,
+ },
+ [0xC24]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC24,
+ },
+ [0xC25]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC25,
+ },
+ [0xC26]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC26,
+ },
+ [0xC27]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC27,
+ },
+ [0xC28]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC28,
+ },
+ [0xC2A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC2A,
+ },
+ [0xC2B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC2B,
+ },
+ [0xC2C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC2C,
+ },
+ [0xC2D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC2D,
+ },
+ [0xC2E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC2E,
+ },
+ [0xC2F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC2F,
+ },
+ [0xC30]={
+ category="lo",
+ direction="l",
+ indic="c",
+ indicclass="ra",
+ indicorder="ap",
+ linebreak="al",
+ unicodeslot=0xC30,
+ },
+ [0xC31]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC31,
+ },
+ [0xC32]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC32,
+ },
+ [0xC33]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC33,
+ },
+ [0xC34]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC34,
+ },
+ [0xC35]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC35,
+ },
+ [0xC36]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC36,
+ },
+ [0xC37]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC37,
+ },
+ [0xC38]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC38,
+ },
+ [0xC39]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC39,
+ },
+ [0xC3D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC3D,
+ },
+ [0xC3E]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xC3E,
+ },
+ [0xC3F]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xC3F,
+ },
+ [0xC40]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xC40,
+ },
+ [0xC41]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xC41,
+ },
+ [0xC42]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xC42,
+ },
+ [0xC43]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xC43,
+ },
+ [0xC44]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xC44,
+ },
+ [0xC46]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xC46,
+ },
+ [0xC47]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xC47,
+ },
+ [0xC48]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xC46, 0xC56 },
+ unicodeslot=0xC48,
+ },
+ [0xC4A]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xC4A,
+ },
+ [0xC4B]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xC4B,
+ },
+ [0xC4C]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xC4C,
+ },
+ [0xC4D]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="halant",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xC4D,
+ },
+ [0xC55]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xC55,
+ },
+ [0xC56]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xC56,
+ },
+ [0xC58]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xC58,
+ },
+ [0xC59]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xC59,
+ },
+ [0xC5A]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xC5A,
+ },
+ [0xC60]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC60,
+ },
+ [0xC61]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC61,
+ },
+ [0xC62]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xC62,
+ },
+ [0xC63]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xC63,
+ },
+ [0xC66]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xC66,
+ },
+ [0xC67]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xC67,
+ },
+ [0xC68]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xC68,
+ },
+ [0xC69]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xC69,
+ },
+ [0xC6A]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xC6A,
+ },
+ [0xC6B]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xC6B,
+ },
+ [0xC6C]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xC6C,
+ },
+ [0xC6D]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xC6D,
+ },
+ [0xC6E]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xC6E,
+ },
+ [0xC6F]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xC6F,
+ },
+ [0xC77]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xC77,
+ },
+ [0xC78]={
+ category="no",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xC78,
+ },
+ [0xC79]={
+ category="no",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xC79,
+ },
+ [0xC7A]={
+ category="no",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xC7A,
+ },
+ [0xC7B]={
+ category="no",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xC7B,
+ },
+ [0xC7C]={
+ category="no",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xC7C,
+ },
+ [0xC7D]={
+ category="no",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xC7D,
+ },
+ [0xC7E]={
+ category="no",
+ direction="on",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xC7E,
+ },
+ [0xC7F]={
+ category="so",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xC7F,
+ },
+ [0xC80]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xC80,
+ },
+ [0xC81]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xC81,
+ },
+ [0xC82]={
+ category="mc",
+ direction="l",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xC82,
+ },
+ [0xC83]={
+ category="mc",
+ direction="l",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xC83,
+ },
+ [0xC84]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xC84,
+ },
+ [0xC85]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC85,
+ },
+ [0xC86]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC86,
+ },
+ [0xC87]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC87,
+ },
+ [0xC88]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC88,
+ },
+ [0xC89]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC89,
+ },
+ [0xC8A]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC8A,
+ },
+ [0xC8B]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC8B,
+ },
+ [0xC8C]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC8C,
+ },
+ [0xC8E]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC8E,
+ },
+ [0xC8F]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC8F,
+ },
+ [0xC90]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC90,
+ },
+ [0xC92]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC92,
+ },
+ [0xC93]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC93,
+ },
+ [0xC94]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xC94,
+ },
+ [0xC95]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC95,
+ },
+ [0xC96]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC96,
+ },
+ [0xC97]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC97,
+ },
+ [0xC98]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC98,
+ },
+ [0xC99]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC99,
+ },
+ [0xC9A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC9A,
+ },
+ [0xC9B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC9B,
+ },
+ [0xC9C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC9C,
+ },
+ [0xC9D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC9D,
+ },
+ [0xC9E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC9E,
+ },
+ [0xC9F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xC9F,
+ },
+ [0xCA0]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCA0,
+ },
+ [0xCA1]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCA1,
+ },
+ [0xCA2]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCA2,
+ },
+ [0xCA3]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCA3,
+ },
+ [0xCA4]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCA4,
+ },
+ [0xCA5]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCA5,
+ },
+ [0xCA6]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCA6,
+ },
+ [0xCA7]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCA7,
+ },
+ [0xCA8]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCA8,
+ },
+ [0xCAA]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCAA,
+ },
+ [0xCAB]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCAB,
+ },
+ [0xCAC]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCAC,
+ },
+ [0xCAD]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCAD,
+ },
+ [0xCAE]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCAE,
+ },
+ [0xCAF]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCAF,
+ },
+ [0xCB0]={
+ category="lo",
+ direction="l",
+ indic="c",
+ indicclass="ra",
+ indicorder="ap",
+ linebreak="al",
+ unicodeslot=0xCB0,
+ },
+ [0xCB1]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCB1,
+ },
+ [0xCB2]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCB2,
+ },
+ [0xCB3]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCB3,
+ },
+ [0xCB5]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCB5,
+ },
+ [0xCB6]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCB6,
+ },
+ [0xCB7]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCB7,
+ },
+ [0xCB8]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCB8,
+ },
+ [0xCB9]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCB9,
+ },
+ [0xCBC]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="nukta",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xCBC,
+ },
+ [0xCBD]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xCBD,
+ },
+ [0xCBE]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xCBE,
+ },
+ [0xCBF]={
+ category="mn",
+ direction="l",
+ indic="d",
+ indicmark="t",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xCBF,
+ },
+ [0xCC0]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xCBF, 0xCD5 },
+ unicodeslot=0xCC0,
+ },
+ [0xCC1]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xCC1,
+ },
+ [0xCC2]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xCC2,
+ },
+ [0xCC3]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xCC3,
+ },
+ [0xCC4]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xCC4,
+ },
+ [0xCC6]={
+ category="mn",
+ direction="l",
+ indic="d",
+ indicmark="t",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xCC6,
+ },
+ [0xCC7]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xCC6, 0xCD5 },
+ unicodeslot=0xCC7,
+ },
+ [0xCC8]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xCC6, 0xCD6 },
+ unicodeslot=0xCC8,
+ },
+ [0xCCA]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xCC6, 0xCC2 },
+ unicodeslot=0xCCA,
+ },
+ [0xCCB]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xCCA, 0xCD5 },
+ unicodeslot=0xCCB,
+ },
+ [0xCCC]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="r",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xCCC,
+ },
+ [0xCCD]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="halant",
+ linebreak="cm",
+ unicodeslot=0xCCD,
+ },
+ [0xCD5]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xCD5,
+ },
+ [0xCD6]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="b",
+ indicorder="as",
+ linebreak="cm",
+ unicodeslot=0xCD6,
+ },
+ [0xCDE]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xCDE,
+ },
+ [0xCE0]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xCE0,
+ },
+ [0xCE1]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xCE1,
+ },
+ [0xCE2]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xCE2,
+ },
+ [0xCE3]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ indicorder="bs",
+ linebreak="cm",
+ unicodeslot=0xCE3,
+ },
+ [0xCE6]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xCE6,
+ },
+ [0xCE7]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xCE7,
+ },
+ [0xCE8]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xCE8,
+ },
+ [0xCE9]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xCE9,
+ },
+ [0xCEA]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xCEA,
+ },
+ [0xCEB]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xCEB,
+ },
+ [0xCEC]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xCEC,
+ },
+ [0xCED]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xCED,
+ },
+ [0xCEE]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xCEE,
+ },
+ [0xCEF]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xCEF,
+ },
+ [0xCF1]={
+ category="so",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xCF1,
+ },
+ [0xCF2]={
+ category="so",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xCF2,
+ },
+ [0xD00]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xD00,
+ },
+ [0xD01]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xD01,
+ },
+ [0xD02]={
+ category="mc",
+ direction="l",
+ indic="m",
+ linebreak="cm",
+ unicodeslot=0xD02,
+ },
+ [0xD03]={
+ category="mc",
+ direction="l",
+ indic="m",
+ linebreak="cm",
+ unicodeslot=0xD03,
+ },
+ [0xD05]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD05,
+ },
+ [0xD06]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD06,
+ },
+ [0xD07]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD07,
+ },
+ [0xD08]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD08,
+ },
+ [0xD09]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD09,
+ },
+ [0xD0A]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD0A,
+ },
+ [0xD0B]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD0B,
+ },
+ [0xD0C]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD0C,
+ },
+ [0xD0E]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD0E,
+ },
+ [0xD0F]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD0F,
+ },
+ [0xD10]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD10,
+ },
+ [0xD12]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD12,
+ },
+ [0xD13]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD13,
+ },
+ [0xD14]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD14,
+ },
+ [0xD15]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD15,
+ },
+ [0xD16]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD16,
+ },
+ [0xD17]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD17,
+ },
+ [0xD18]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD18,
+ },
+ [0xD19]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD19,
+ },
+ [0xD1A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD1A,
+ },
+ [0xD1B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD1B,
+ },
+ [0xD1C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD1C,
+ },
+ [0xD1D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD1D,
+ },
+ [0xD1E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD1E,
+ },
+ [0xD1F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD1F,
+ },
+ [0xD20]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD20,
+ },
+ [0xD21]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD21,
+ },
+ [0xD22]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD22,
+ },
+ [0xD23]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD23,
+ },
+ [0xD24]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD24,
+ },
+ [0xD25]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD25,
+ },
+ [0xD26]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD26,
+ },
+ [0xD27]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD27,
+ },
+ [0xD28]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD28,
+ },
+ [0xD29]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD29,
+ },
+ [0xD2A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD2A,
+ },
+ [0xD2B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD2B,
+ },
+ [0xD2C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD2C,
+ },
+ [0xD2D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD2D,
+ },
+ [0xD2E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD2E,
+ },
+ [0xD2F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD2F,
+ },
+ [0xD30]={
+ category="lo",
+ direction="l",
+ indic="c",
+ indicclass="ra",
+ indicorder="am",
+ linebreak="al",
+ unicodeslot=0xD30,
+ },
+ [0xD31]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD31,
+ },
+ [0xD32]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD32,
+ },
+ [0xD33]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD33,
+ },
+ [0xD34]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD34,
+ },
+ [0xD35]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD35,
+ },
+ [0xD36]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD36,
+ },
+ [0xD37]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD37,
+ },
+ [0xD38]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD38,
+ },
+ [0xD39]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD39,
+ },
+ [0xD3A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="al",
+ unicodeslot=0xD3A,
+ },
+ [0xD3B]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xD3B,
+ },
+ [0xD3C]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ linebreak="cm",
+ unicodeslot=0xD3C,
+ },
+ [0xD3D]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD3D,
+ },
+ [0xD3E]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xD3E,
+ },
+ [0xD3F]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xD3F,
+ },
+ [0xD40]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xD40,
+ },
+ [0xD41]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xD41,
+ },
+ [0xD42]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xD42,
+ },
+ [0xD43]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xD43,
+ },
+ [0xD44]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="r",
+ linebreak="cm",
+ unicodeslot=0xD44,
+ },
+ [0xD46]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bm",
+ linebreak="cm",
+ unicodeslot=0xD46,
+ },
+ [0xD47]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bm",
+ linebreak="cm",
+ unicodeslot=0xD47,
+ },
+ [0xD48]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ indicorder="bm",
+ linebreak="cm",
+ unicodeslot=0xD48,
+ },
+ [0xD4A]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xD46, 0xD3E },
+ unicodeslot=0xD4A,
+ },
+ [0xD4B]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xD47, 0xD3E },
+ unicodeslot=0xD4B,
+ },
+ [0xD4C]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="s",
+ linebreak="cm",
+ specials={ "char", 0xD46, 0xD57 },
+ unicodeslot=0xD4C,
+ },
+ [0xD4D]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicclass="halant",
+ linebreak="cm",
+ unicodeslot=0xD4D,
+ },
+ [0xD4E]={
+ category="lo",
+ direction="l",
+ indic="o",
+ indicmark="t",
+ linebreak="al",
+ unicodeslot=0xD4E,
+ },
+ [0xD4F]={
+ category="so",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD4F,
+ },
+ [0xD54]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD54,
+ },
+ [0xD55]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD55,
+ },
+ [0xD56]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD56,
+ },
+ [0xD57]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ indicorder="ap",
+ linebreak="cm",
+ unicodeslot=0xD57,
+ },
+ [0xD58]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD58,
+ },
+ [0xD59]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD59,
+ },
+ [0xD5A]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD5A,
+ },
+ [0xD5B]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD5B,
+ },
+ [0xD5C]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD5C,
+ },
+ [0xD5D]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD5D,
+ },
+ [0xD5E]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD5E,
+ },
+ [0xD5F]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD5F,
+ },
+ [0xD60]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD60,
+ },
+ [0xD61]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="al",
+ unicodeslot=0xD61,
+ },
+ [0xD62]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xD62,
+ },
+ [0xD63]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="cm",
+ unicodeslot=0xD63,
+ },
+ [0xD66]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xD66,
+ },
+ [0xD67]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xD67,
+ },
+ [0xD68]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xD68,
+ },
+ [0xD69]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xD69,
+ },
+ [0xD6A]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xD6A,
+ },
+ [0xD6B]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xD6B,
+ },
+ [0xD6C]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xD6C,
+ },
+ [0xD6D]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xD6D,
+ },
+ [0xD6E]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xD6E,
+ },
+ [0xD6F]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xD6F,
+ },
+ [0xD70]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD70,
+ },
+ [0xD71]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD71,
+ },
+ [0xD72]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD72,
+ },
+ [0xD73]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD73,
+ },
+ [0xD74]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD74,
+ },
+ [0xD75]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD75,
+ },
+ [0xD76]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD76,
+ },
+ [0xD77]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD77,
+ },
+ [0xD78]={
+ category="no",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD78,
+ },
+ [0xD79]={
+ category="so",
+ direction="l",
+ indic="o",
+ linebreak="po",
+ unicodeslot=0xD79,
+ },
+ [0xD7A]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD7A,
+ },
+ [0xD7B]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD7B,
+ },
+ [0xD7C]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD7C,
+ },
+ [0xD7D]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD7D,
+ },
+ [0xD7E]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD7E,
+ },
+ [0xD7F]={
+ category="lo",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0xD7F,
+ },
+ [0xD82]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xD82,
+ },
+ [0xD83]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xD83,
+ },
+ [0xD85]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD85,
+ },
+ [0xD86]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD86,
+ },
+ [0xD87]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD87,
+ },
+ [0xD88]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD88,
+ },
+ [0xD89]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD89,
+ },
+ [0xD8A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD8A,
+ },
+ [0xD8B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD8B,
+ },
+ [0xD8C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD8C,
+ },
+ [0xD8D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD8D,
+ },
+ [0xD8E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD8E,
+ },
+ [0xD8F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD8F,
+ },
+ [0xD90]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD90,
+ },
+ [0xD91]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD91,
+ },
+ [0xD92]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD92,
+ },
+ [0xD93]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD93,
+ },
+ [0xD94]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD94,
+ },
+ [0xD95]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD95,
+ },
+ [0xD96]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD96,
+ },
+ [0xD9A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD9A,
+ },
+ [0xD9B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD9B,
+ },
+ [0xD9C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD9C,
+ },
+ [0xD9D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD9D,
+ },
+ [0xD9E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD9E,
+ },
+ [0xD9F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD9F,
+ },
+ [0xDA0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDA0,
+ },
+ [0xDA1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDA1,
+ },
+ [0xDA2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDA2,
+ },
+ [0xDA3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDA3,
+ },
+ [0xDA4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDA4,
+ },
+ [0xDA5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDA5,
+ },
+ [0xDA6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDA6,
+ },
+ [0xDA7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDA7,
+ },
+ [0xDA8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDA8,
+ },
+ [0xDA9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDA9,
+ },
+ [0xDAA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDAA,
+ },
+ [0xDAB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDAB,
+ },
+ [0xDAC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDAC,
+ },
+ [0xDAD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDAD,
+ },
+ [0xDAE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDAE,
+ },
+ [0xDAF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDAF,
+ },
+ [0xDB0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDB0,
+ },
+ [0xDB1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDB1,
+ },
+ [0xDB3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDB3,
+ },
+ [0xDB4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDB4,
+ },
+ [0xDB5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDB5,
+ },
+ [0xDB6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDB6,
+ },
+ [0xDB7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDB7,
+ },
+ [0xDB8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDB8,
+ },
+ [0xDB9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDB9,
+ },
+ [0xDBA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDBA,
+ },
+ [0xDBB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDBB,
+ },
+ [0xDBD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDBD,
+ },
+ [0xDC0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDC0,
+ },
+ [0xDC1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDC1,
+ },
+ [0xDC2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDC2,
+ },
+ [0xDC3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDC3,
+ },
+ [0xDC4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDC4,
+ },
+ [0xDC5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDC5,
+ },
+ [0xDC6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDC6,
+ },
+ [0xDCA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xDCA,
+ },
+ [0xDCF]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xDCF,
+ },
+ [0xDD0]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xDD0,
+ },
+ [0xDD1]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xDD1,
+ },
+ [0xDD2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xDD2,
+ },
+ [0xDD3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xDD3,
+ },
+ [0xDD4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xDD4,
+ },
+ [0xDD6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xDD6,
+ },
+ [0xDD8]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xDD8,
+ },
+ [0xDD9]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xDD9,
+ },
+ [0xDDA]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0xDD9, 0xDCA },
+ unicodeslot=0xDDA,
+ },
+ [0xDDB]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xDDB,
+ },
+ [0xDDC]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0xDD9, 0xDCF },
+ unicodeslot=0xDDC,
+ },
+ [0xDDD]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0xDDC, 0xDCA },
+ unicodeslot=0xDDD,
+ },
+ [0xDDE]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0xDD9, 0xDDF },
+ unicodeslot=0xDDE,
+ },
+ [0xDDF]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xDDF,
+ },
+ [0xDE6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xDE6,
+ },
+ [0xDE7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xDE7,
+ },
+ [0xDE8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xDE8,
+ },
+ [0xDE9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xDE9,
+ },
+ [0xDEA]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xDEA,
+ },
+ [0xDEB]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xDEB,
+ },
+ [0xDEC]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xDEC,
+ },
+ [0xDED]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xDED,
+ },
+ [0xDEE]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xDEE,
+ },
+ [0xDEF]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xDEF,
+ },
+ [0xDF2]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xDF2,
+ },
+ [0xDF3]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xDF3,
+ },
+ [0xDF4]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xDF4,
+ },
+ [0xE01]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE01,
+ },
+ [0xE02]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE02,
+ },
+ [0xE03]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE03,
+ },
+ [0xE04]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE04,
+ },
+ [0xE05]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE05,
+ },
+ [0xE06]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE06,
+ },
+ [0xE07]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE07,
+ },
+ [0xE08]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE08,
+ },
+ [0xE09]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE09,
+ },
+ [0xE0A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE0A,
+ },
+ [0xE0B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE0B,
+ },
+ [0xE0C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE0C,
+ },
+ [0xE0D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE0D,
+ },
+ [0xE0E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE0E,
+ },
+ [0xE0F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE0F,
+ },
+ [0xE10]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE10,
+ },
+ [0xE11]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE11,
+ },
+ [0xE12]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE12,
+ },
+ [0xE13]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE13,
+ },
+ [0xE14]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE14,
+ },
+ [0xE15]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE15,
+ },
+ [0xE16]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE16,
+ },
+ [0xE17]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE17,
+ },
+ [0xE18]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE18,
+ },
+ [0xE19]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE19,
+ },
+ [0xE1A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE1A,
+ },
+ [0xE1B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE1B,
+ },
+ [0xE1C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE1C,
+ },
+ [0xE1D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE1D,
+ },
+ [0xE1E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE1E,
+ },
+ [0xE1F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE1F,
+ },
+ [0xE20]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE20,
+ },
+ [0xE21]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE21,
+ },
+ [0xE22]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE22,
+ },
+ [0xE23]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE23,
+ },
+ [0xE24]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE24,
+ },
+ [0xE25]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE25,
+ },
+ [0xE26]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE26,
+ },
+ [0xE27]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE27,
+ },
+ [0xE28]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE28,
+ },
+ [0xE29]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE29,
+ },
+ [0xE2A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE2A,
+ },
+ [0xE2B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE2B,
+ },
+ [0xE2C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE2C,
+ },
+ [0xE2D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE2D,
+ },
+ [0xE2E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE2E,
+ },
+ [0xE2F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE2F,
+ },
+ [0xE30]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE30,
+ },
+ [0xE31]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE31,
+ },
+ [0xE32]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE32,
+ },
+ [0xE33]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ specials={ "compat", 0xE4D, 0xE32 },
+ unicodeslot=0xE33,
+ },
+ [0xE34]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE34,
+ },
+ [0xE35]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE35,
+ },
+ [0xE36]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE36,
+ },
+ [0xE37]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE37,
+ },
+ [0xE38]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE38,
+ },
+ [0xE39]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE39,
+ },
+ [0xE3A]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE3A,
+ },
+ [0xE3F]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0xE3F,
+ },
+ [0xE40]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE40,
+ },
+ [0xE41]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE41,
+ },
+ [0xE42]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE42,
+ },
+ [0xE43]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE43,
+ },
+ [0xE44]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE44,
+ },
+ [0xE45]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE45,
+ },
+ [0xE46]={
+ category="lm",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE46,
+ },
+ [0xE47]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE47,
+ },
+ [0xE48]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE48,
+ },
+ [0xE49]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE49,
+ },
+ [0xE4A]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE4A,
+ },
+ [0xE4B]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE4B,
+ },
+ [0xE4C]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE4C,
+ },
+ [0xE4D]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE4D,
+ },
+ [0xE4E]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xE4E,
+ },
+ [0xE4F]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xE4F,
+ },
+ [0xE50]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xE50,
+ },
+ [0xE51]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xE51,
+ },
+ [0xE52]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xE52,
+ },
+ [0xE53]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xE53,
+ },
+ [0xE54]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xE54,
+ },
+ [0xE55]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xE55,
+ },
+ [0xE56]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xE56,
+ },
+ [0xE57]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xE57,
+ },
+ [0xE58]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xE58,
+ },
+ [0xE59]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xE59,
+ },
+ [0xE5A]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xE5A,
+ },
+ [0xE5B]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xE5B,
+ },
+ [0xE81]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE81,
+ },
+ [0xE82]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE82,
+ },
+ [0xE84]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE84,
+ },
+ [0xE86]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE86,
+ },
+ [0xE87]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE87,
+ },
+ [0xE88]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE88,
+ },
+ [0xE89]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE89,
+ },
+ [0xE8A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE8A,
+ },
+ [0xE8C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE8C,
+ },
+ [0xE8D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE8D,
+ },
+ [0xE8E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE8E,
+ },
+ [0xE8F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE8F,
+ },
+ [0xE90]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE90,
+ },
+ [0xE91]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE91,
+ },
+ [0xE92]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE92,
+ },
+ [0xE93]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE93,
+ },
+ [0xE94]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE94,
+ },
+ [0xE95]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE95,
+ },
+ [0xE96]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE96,
+ },
+ [0xE97]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE97,
+ },
+ [0xE98]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE98,
+ },
+ [0xE99]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE99,
+ },
+ [0xE9A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE9A,
+ },
+ [0xE9B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE9B,
+ },
+ [0xE9C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE9C,
+ },
+ [0xE9D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE9D,
+ },
+ [0xE9E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE9E,
+ },
+ [0xE9F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xE9F,
+ },
+ [0xEA0]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEA0,
+ },
+ [0xEA1]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEA1,
+ },
+ [0xEA2]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEA2,
+ },
+ [0xEA3]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEA3,
+ },
+ [0xEA5]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEA5,
+ },
+ [0xEA7]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEA7,
+ },
+ [0xEA8]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEA8,
+ },
+ [0xEA9]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEA9,
+ },
+ [0xEAA]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEAA,
+ },
+ [0xEAB]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEAB,
+ },
+ [0xEAC]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEAC,
+ },
+ [0xEAD]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEAD,
+ },
+ [0xEAE]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEAE,
+ },
+ [0xEAF]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEAF,
+ },
+ [0xEB0]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEB0,
+ },
+ [0xEB1]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xEB1,
+ },
+ [0xEB2]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEB2,
+ },
+ [0xEB3]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ specials={ "compat", 0xECD, 0xEB2 },
+ unicodeslot=0xEB3,
+ },
+ [0xEB4]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xEB4,
+ },
+ [0xEB5]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xEB5,
+ },
+ [0xEB6]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xEB6,
+ },
+ [0xEB7]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xEB7,
+ },
+ [0xEB8]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xEB8,
+ },
+ [0xEB9]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xEB9,
+ },
+ [0xEBA]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xEBA,
+ },
+ [0xEBB]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xEBB,
+ },
+ [0xEBC]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xEBC,
+ },
+ [0xEBD]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEBD,
+ },
+ [0xEC0]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEC0,
+ },
+ [0xEC1]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEC1,
+ },
+ [0xEC2]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEC2,
+ },
+ [0xEC3]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEC3,
+ },
+ [0xEC4]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEC4,
+ },
+ [0xEC6]={
+ category="lm",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEC6,
+ },
+ [0xEC8]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xEC8,
+ },
+ [0xEC9]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xEC9,
+ },
+ [0xECA]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xECA,
+ },
+ [0xECB]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xECB,
+ },
+ [0xECC]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xECC,
+ },
+ [0xECD]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xECD,
+ },
+ [0xED0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xED0,
+ },
+ [0xED1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xED1,
+ },
+ [0xED2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xED2,
+ },
+ [0xED3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xED3,
+ },
+ [0xED4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xED4,
+ },
+ [0xED5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xED5,
+ },
+ [0xED6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xED6,
+ },
+ [0xED7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xED7,
+ },
+ [0xED8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xED8,
+ },
+ [0xED9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xED9,
+ },
+ [0xEDC]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ specials={ "compat", 0xEAB, 0xE99 },
+ unicodeslot=0xEDC,
+ },
+ [0xEDD]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ specials={ "compat", 0xEAB, 0xEA1 },
+ unicodeslot=0xEDD,
+ },
+ [0xEDE]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEDE,
+ },
+ [0xEDF]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xEDF,
+ },
+ [0xF00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF00,
+ },
+ [0xF01]={
+ category="so",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xF01,
+ },
+ [0xF02]={
+ category="so",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xF02,
+ },
+ [0xF03]={
+ category="so",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xF03,
+ },
+ [0xF04]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xF04,
+ },
+ [0xF05]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF05,
+ },
+ [0xF06]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xF06,
+ },
+ [0xF07]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xF07,
+ },
+ [0xF08]={
+ category="po",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0xF08,
+ },
+ [0xF09]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xF09,
+ },
+ [0xF0A]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xF0A,
+ },
+ [0xF0B]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xF0B,
+ },
+ [0xF0C]={
+ category="po",
+ direction="l",
+ linebreak="gl",
+ specials={ "nobreak", 0xF0B },
+ unicodeslot=0xF0C,
+ },
+ [0xF0D]={
+ category="po",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0xF0D,
+ },
+ [0xF0E]={
+ category="po",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0xF0E,
+ },
+ [0xF0F]={
+ category="po",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0xF0F,
+ },
+ [0xF10]={
+ category="po",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0xF10,
+ },
+ [0xF11]={
+ category="po",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0xF11,
+ },
+ [0xF12]={
+ category="po",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0xF12,
+ },
+ [0xF13]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF13,
+ },
+ [0xF14]={
+ category="so",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0xF14,
+ },
+ [0xF15]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF15,
+ },
+ [0xF16]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF16,
+ },
+ [0xF17]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF17,
+ },
+ [0xF18]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF18,
+ },
+ [0xF19]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF19,
+ },
+ [0xF1A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF1A,
+ },
+ [0xF1B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF1B,
+ },
+ [0xF1C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF1C,
+ },
+ [0xF1D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF1D,
+ },
+ [0xF1E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF1E,
+ },
+ [0xF1F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF1F,
+ },
+ [0xF20]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xF20,
+ },
+ [0xF21]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xF21,
+ },
+ [0xF22]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xF22,
+ },
+ [0xF23]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xF23,
+ },
+ [0xF24]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xF24,
+ },
+ [0xF25]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xF25,
+ },
+ [0xF26]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xF26,
+ },
+ [0xF27]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xF27,
+ },
+ [0xF28]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xF28,
+ },
+ [0xF29]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xF29,
+ },
+ [0xF2A]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF2A,
+ },
+ [0xF2B]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF2B,
+ },
+ [0xF2C]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF2C,
+ },
+ [0xF2D]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF2D,
+ },
+ [0xF2E]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF2E,
+ },
+ [0xF2F]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF2F,
+ },
+ [0xF30]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF30,
+ },
+ [0xF31]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF31,
+ },
+ [0xF32]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF32,
+ },
+ [0xF33]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF33,
+ },
+ [0xF34]={
+ category="so",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xF34,
+ },
+ [0xF35]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF35,
+ },
+ [0xF36]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF36,
+ },
+ [0xF37]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF37,
+ },
+ [0xF38]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF38,
+ },
+ [0xF39]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF39,
+ },
+ [0xF3A]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0xF3B,
+ unicodeslot=0xF3A,
+ },
+ [0xF3B]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0xF3A,
+ unicodeslot=0xF3B,
+ },
+ [0xF3C]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0xF3D,
+ unicodeslot=0xF3C,
+ },
+ [0xF3D]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0xF3C,
+ unicodeslot=0xF3D,
+ },
+ [0xF3E]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xF3E,
+ },
+ [0xF3F]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xF3F,
+ },
+ [0xF40]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF40,
+ },
+ [0xF41]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF41,
+ },
+ [0xF42]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF42,
+ },
+ [0xF43]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF42, 0xFB7 },
+ unicodeslot=0xF43,
+ },
+ [0xF44]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF44,
+ },
+ [0xF45]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF45,
+ },
+ [0xF46]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF46,
+ },
+ [0xF47]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF47,
+ },
+ [0xF49]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF49,
+ },
+ [0xF4A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF4A,
+ },
+ [0xF4B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF4B,
+ },
+ [0xF4C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF4C,
+ },
+ [0xF4D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF4C, 0xFB7 },
+ unicodeslot=0xF4D,
+ },
+ [0xF4E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF4E,
+ },
+ [0xF4F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF4F,
+ },
+ [0xF50]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF50,
+ },
+ [0xF51]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF51,
+ },
+ [0xF52]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF51, 0xFB7 },
+ unicodeslot=0xF52,
+ },
+ [0xF53]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF53,
+ },
+ [0xF54]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF54,
+ },
+ [0xF55]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF55,
+ },
+ [0xF56]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF56,
+ },
+ [0xF57]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF56, 0xFB7 },
+ unicodeslot=0xF57,
+ },
+ [0xF58]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF58,
+ },
+ [0xF59]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF59,
+ },
+ [0xF5A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF5A,
+ },
+ [0xF5B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF5B,
+ },
+ [0xF5C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF5B, 0xFB7 },
+ unicodeslot=0xF5C,
+ },
+ [0xF5D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF5D,
+ },
+ [0xF5E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF5E,
+ },
+ [0xF5F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF5F,
+ },
+ [0xF60]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF60,
+ },
+ [0xF61]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF61,
+ },
+ [0xF62]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF62,
+ },
+ [0xF63]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF63,
+ },
+ [0xF64]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF64,
+ },
+ [0xF65]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF65,
+ },
+ [0xF66]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF66,
+ },
+ [0xF67]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF67,
+ },
+ [0xF68]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF68,
+ },
+ [0xF69]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF40, 0xFB5 },
+ unicodeslot=0xF69,
+ },
+ [0xF6A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF6A,
+ },
+ [0xF6B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF6B,
+ },
+ [0xF6C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF6C,
+ },
+ [0xF71]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF71,
+ },
+ [0xF72]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF72,
+ },
+ [0xF73]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0xF71, 0xF72 },
+ unicodeslot=0xF73,
+ },
+ [0xF74]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF74,
+ },
+ [0xF75]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0xF71, 0xF74 },
+ unicodeslot=0xF75,
+ },
+ [0xF76]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0xFB2, 0xF80 },
+ unicodeslot=0xF76,
+ },
+ [0xF77]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "compat", 0xFB2, 0xF81 },
+ unicodeslot=0xF77,
+ },
+ [0xF78]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0xFB3, 0xF80 },
+ unicodeslot=0xF78,
+ },
+ [0xF79]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "compat", 0xFB3, 0xF81 },
+ unicodeslot=0xF79,
+ },
+ [0xF7A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF7A,
+ },
+ [0xF7B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF7B,
+ },
+ [0xF7C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF7C,
+ },
+ [0xF7D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF7D,
+ },
+ [0xF7E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF7E,
+ },
+ [0xF7F]={
+ category="mc",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xF7F,
+ },
+ [0xF80]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF80,
+ },
+ [0xF81]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0xF71, 0xF80 },
+ unicodeslot=0xF81,
+ },
+ [0xF82]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF82,
+ },
+ [0xF83]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF83,
+ },
+ [0xF84]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF84,
+ },
+ [0xF85]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xF85,
+ },
+ [0xF86]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF86,
+ },
+ [0xF87]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF87,
+ },
+ [0xF88]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF88,
+ },
+ [0xF89]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF89,
+ },
+ [0xF8A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF8A,
+ },
+ [0xF8B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF8B,
+ },
+ [0xF8C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xF8C,
+ },
+ [0xF8D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF8D,
+ },
+ [0xF8E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF8E,
+ },
+ [0xF8F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF8F,
+ },
+ [0xF90]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF90,
+ },
+ [0xF91]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF91,
+ },
+ [0xF92]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF92,
+ },
+ [0xF93]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0xF92, 0xFB7 },
+ unicodeslot=0xF93,
+ },
+ [0xF94]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF94,
+ },
+ [0xF95]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF95,
+ },
+ [0xF96]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF96,
+ },
+ [0xF97]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF97,
+ },
+ [0xF99]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF99,
+ },
+ [0xF9A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF9A,
+ },
+ [0xF9B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF9B,
+ },
+ [0xF9C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF9C,
+ },
+ [0xF9D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0xF9C, 0xFB7 },
+ unicodeslot=0xF9D,
+ },
+ [0xF9E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF9E,
+ },
+ [0xF9F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xF9F,
+ },
+ [0xFA0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFA0,
+ },
+ [0xFA1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFA1,
+ },
+ [0xFA2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0xFA1, 0xFB7 },
+ unicodeslot=0xFA2,
+ },
+ [0xFA3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFA3,
+ },
+ [0xFA4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFA4,
+ },
+ [0xFA5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFA5,
+ },
+ [0xFA6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFA6,
+ },
+ [0xFA7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0xFA6, 0xFB7 },
+ unicodeslot=0xFA7,
+ },
+ [0xFA8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFA8,
+ },
+ [0xFA9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFA9,
+ },
+ [0xFAA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFAA,
+ },
+ [0xFAB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFAB,
+ },
+ [0xFAC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0xFAB, 0xFB7 },
+ unicodeslot=0xFAC,
+ },
+ [0xFAD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFAD,
+ },
+ [0xFAE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFAE,
+ },
+ [0xFAF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFAF,
+ },
+ [0xFB0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFB0,
+ },
+ [0xFB1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFB1,
+ },
+ [0xFB2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFB2,
+ },
+ [0xFB3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFB3,
+ },
+ [0xFB4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFB4,
+ },
+ [0xFB5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFB5,
+ },
+ [0xFB6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFB6,
+ },
+ [0xFB7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFB7,
+ },
+ [0xFB8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFB8,
+ },
+ [0xFB9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0xF90, 0xFB5 },
+ unicodeslot=0xFB9,
+ },
+ [0xFBA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFBA,
+ },
+ [0xFBB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFBB,
+ },
+ [0xFBC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFBC,
+ },
+ [0xFBE]={
+ category="so",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xFBE,
+ },
+ [0xFBF]={
+ category="so",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xFBF,
+ },
+ [0xFC0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFC0,
+ },
+ [0xFC1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFC1,
+ },
+ [0xFC2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFC2,
+ },
+ [0xFC3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFC3,
+ },
+ [0xFC4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFC4,
+ },
+ [0xFC5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFC5,
+ },
+ [0xFC6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFC6,
+ },
+ [0xFC7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFC7,
+ },
+ [0xFC8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFC8,
+ },
+ [0xFC9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFC9,
+ },
+ [0xFCA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFCA,
+ },
+ [0xFCB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFCB,
+ },
+ [0xFCC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFCC,
+ },
+ [0xFCE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFCE,
+ },
+ [0xFCF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFCF,
+ },
+ [0xFD0]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xFD0,
+ },
+ [0xFD1]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xFD1,
+ },
+ [0xFD2]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xFD2,
+ },
+ [0xFD3]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xFD3,
+ },
+ [0xFD4]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFD4,
+ },
+ [0xFD5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFD5,
+ },
+ [0xFD6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFD6,
+ },
+ [0xFD7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFD7,
+ },
+ [0xFD8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xFD8,
+ },
+ [0xFD9]={
+ category="po",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0xFD9,
+ },
+ [0xFDA]={
+ category="po",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0xFDA,
+ },
+ [0x1000]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1000,
+ },
+ [0x1001]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1001,
+ },
+ [0x1002]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1002,
+ },
+ [0x1003]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1003,
+ },
+ [0x1004]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1004,
+ },
+ [0x1005]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1005,
+ },
+ [0x1006]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1006,
+ },
+ [0x1007]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1007,
+ },
+ [0x1008]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1008,
+ },
+ [0x1009]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1009,
+ },
+ [0x100A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x100A,
+ },
+ [0x100B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x100B,
+ },
+ [0x100C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x100C,
+ },
+ [0x100D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x100D,
+ },
+ [0x100E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x100E,
+ },
+ [0x100F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x100F,
+ },
+ [0x1010]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1010,
+ },
+ [0x1011]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1011,
+ },
+ [0x1012]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1012,
+ },
+ [0x1013]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1013,
+ },
+ [0x1014]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1014,
+ },
+ [0x1015]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1015,
+ },
+ [0x1016]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1016,
+ },
+ [0x1017]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1017,
+ },
+ [0x1018]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1018,
+ },
+ [0x1019]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1019,
+ },
+ [0x101A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x101A,
+ },
+ [0x101B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x101B,
+ },
+ [0x101C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x101C,
+ },
+ [0x101D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x101D,
+ },
+ [0x101E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x101E,
+ },
+ [0x101F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x101F,
+ },
+ [0x1020]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1020,
+ },
+ [0x1021]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x1021,
+ },
+ [0x1022]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x1022,
+ },
+ [0x1023]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x1023,
+ },
+ [0x1024]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x1024,
+ },
+ [0x1025]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x1025,
+ },
+ [0x1026]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ specials={ "char", 0x1025, 0x102E },
+ unicodeslot=0x1026,
+ },
+ [0x1027]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x1027,
+ },
+ [0x1028]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x1028,
+ },
+ [0x1029]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x1029,
+ },
+ [0x102A]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x102A,
+ },
+ [0x102B]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x102B,
+ },
+ [0x102C]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x102C,
+ },
+ [0x102D]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x102D,
+ },
+ [0x102E]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x102E,
+ },
+ [0x102F]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x102F,
+ },
+ [0x1030]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x1030,
+ },
+ [0x1031]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ linebreak="sa",
+ unicodeslot=0x1031,
+ },
+ [0x1032]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x1032,
+ },
+ [0x1033]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x1033,
+ },
+ [0x1034]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x1034,
+ },
+ [0x1035]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x1035,
+ },
+ [0x1036]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x1036,
+ },
+ [0x1037]={
+ category="mn",
+ direction="nsm",
+ indic="s",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x1037,
+ },
+ [0x1038]={
+ category="mc",
+ direction="l",
+ indic="m",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1038,
+ },
+ [0x1039]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x1039,
+ },
+ [0x103A]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x103A,
+ },
+ [0x103B]={
+ category="mc",
+ direction="l",
+ indic="c",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x103B,
+ },
+ [0x103C]={
+ category="mc",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x103C,
+ },
+ [0x103D]={
+ category="mn",
+ direction="nsm",
+ indic="c",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x103D,
+ },
+ [0x103E]={
+ category="mn",
+ direction="nsm",
+ indic="c",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x103E,
+ },
+ [0x103F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x103F,
+ },
+ [0x1040]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1040,
+ },
+ [0x1041]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1041,
+ },
+ [0x1042]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1042,
+ },
+ [0x1043]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1043,
+ },
+ [0x1044]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1044,
+ },
+ [0x1045]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1045,
+ },
+ [0x1046]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1046,
+ },
+ [0x1047]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1047,
+ },
+ [0x1048]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1048,
+ },
+ [0x1049]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1049,
+ },
+ [0x104A]={
+ category="po",
+ direction="l",
+ indic="o",
+ linebreak="ba",
+ unicodeslot=0x104A,
+ },
+ [0x104B]={
+ category="po",
+ direction="l",
+ indic="o",
+ linebreak="ba",
+ unicodeslot=0x104B,
+ },
+ [0x104C]={
+ category="po",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x104C,
+ },
+ [0x104D]={
+ category="po",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x104D,
+ },
+ [0x104E]={
+ category="po",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x104E,
+ },
+ [0x104F]={
+ category="po",
+ direction="l",
+ indic="o",
+ linebreak="al",
+ unicodeslot=0x104F,
+ },
+ [0x1050]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1050,
+ },
+ [0x1051]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1051,
+ },
+ [0x1052]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x1052,
+ },
+ [0x1053]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x1053,
+ },
+ [0x1054]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x1054,
+ },
+ [0x1055]={
+ category="lo",
+ direction="l",
+ indic="i",
+ linebreak="sa",
+ unicodeslot=0x1055,
+ },
+ [0x1056]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1056,
+ },
+ [0x1057]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1057,
+ },
+ [0x1058]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x1058,
+ },
+ [0x1059]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x1059,
+ },
+ [0x105A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x105A,
+ },
+ [0x105B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x105B,
+ },
+ [0x105C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x105C,
+ },
+ [0x105D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x105D,
+ },
+ [0x105E]={
+ category="mn",
+ direction="nsm",
+ indic="c",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x105E,
+ },
+ [0x105F]={
+ category="mn",
+ direction="nsm",
+ indic="c",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x105F,
+ },
+ [0x1060]={
+ category="mn",
+ direction="nsm",
+ indic="c",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x1060,
+ },
+ [0x1061]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1061,
+ },
+ [0x1062]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1062,
+ },
+ [0x1063]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1063,
+ },
+ [0x1064]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1064,
+ },
+ [0x1065]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1065,
+ },
+ [0x1066]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1066,
+ },
+ [0x1067]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1067,
+ },
+ [0x1068]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1068,
+ },
+ [0x1069]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1069,
+ },
+ [0x106A]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x106A,
+ },
+ [0x106B]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x106B,
+ },
+ [0x106C]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x106C,
+ },
+ [0x106D]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x106D,
+ },
+ [0x106E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x106E,
+ },
+ [0x106F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x106F,
+ },
+ [0x1070]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1070,
+ },
+ [0x1071]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x1071,
+ },
+ [0x1072]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x1072,
+ },
+ [0x1073]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x1073,
+ },
+ [0x1074]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x1074,
+ },
+ [0x1075]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1075,
+ },
+ [0x1076]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1076,
+ },
+ [0x1077]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1077,
+ },
+ [0x1078]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1078,
+ },
+ [0x1079]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1079,
+ },
+ [0x107A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x107A,
+ },
+ [0x107B]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x107B,
+ },
+ [0x107C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x107C,
+ },
+ [0x107D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x107D,
+ },
+ [0x107E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x107E,
+ },
+ [0x107F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x107F,
+ },
+ [0x1080]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1080,
+ },
+ [0x1081]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x1081,
+ },
+ [0x1082]={
+ category="mn",
+ direction="nsm",
+ indic="c",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x1082,
+ },
+ [0x1083]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1083,
+ },
+ [0x1084]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="l",
+ linebreak="sa",
+ unicodeslot=0x1084,
+ },
+ [0x1085]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x1085,
+ },
+ [0x1086]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x1086,
+ },
+ [0x1087]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1087,
+ },
+ [0x1088]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1088,
+ },
+ [0x1089]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x1089,
+ },
+ [0x108A]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x108A,
+ },
+ [0x108B]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x108B,
+ },
+ [0x108C]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x108C,
+ },
+ [0x108D]={
+ category="mn",
+ direction="nsm",
+ indic="s",
+ indicmark="b",
+ linebreak="sa",
+ unicodeslot=0x108D,
+ },
+ [0x108E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0x108E,
+ },
+ [0x108F]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x108F,
+ },
+ [0x1090]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1090,
+ },
+ [0x1091]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1091,
+ },
+ [0x1092]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1092,
+ },
+ [0x1093]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1093,
+ },
+ [0x1094]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1094,
+ },
+ [0x1095]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1095,
+ },
+ [0x1096]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1096,
+ },
+ [0x1097]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1097,
+ },
+ [0x1098]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1098,
+ },
+ [0x1099]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0x1099,
+ },
+ [0x109A]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x109A,
+ },
+ [0x109B]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x109B,
+ },
+ [0x109C]={
+ category="mc",
+ direction="l",
+ indic="d",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0x109C,
+ },
+ [0x109D]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0x109D,
+ },
+ [0x109E]={
+ category="so",
+ direction="l",
+ indic="o",
+ linebreak="sa",
+ unicodeslot=0x109E,
+ },
+ [0x109F]={
+ category="so",
+ direction="l",
+ indic="o",
+ linebreak="sa",
+ unicodeslot=0x109F,
+ },
+ [0x10A0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10A0,
+ },
+ [0x10A1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10A1,
+ },
+ [0x10A2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10A2,
+ },
+ [0x10A3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10A3,
+ },
+ [0x10A4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10A4,
+ },
+ [0x10A5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10A5,
+ },
+ [0x10A6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10A6,
+ },
+ [0x10A7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10A7,
+ },
+ [0x10A8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10A8,
+ },
+ [0x10A9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10A9,
+ },
+ [0x10AA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10AA,
+ },
+ [0x10AB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10AB,
+ },
+ [0x10AC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10AC,
+ },
+ [0x10AD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10AD,
+ },
+ [0x10AE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10AE,
+ },
+ [0x10AF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10AF,
+ },
+ [0x10B0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10B0,
+ },
+ [0x10B1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10B1,
+ },
+ [0x10B2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10B2,
+ },
+ [0x10B3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10B3,
+ },
+ [0x10B4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10B4,
+ },
+ [0x10B5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10B5,
+ },
+ [0x10B6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10B6,
+ },
+ [0x10B7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10B7,
+ },
+ [0x10B8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10B8,
+ },
+ [0x10B9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10B9,
+ },
+ [0x10BA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10BA,
+ },
+ [0x10BB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10BB,
+ },
+ [0x10BC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10BC,
+ },
+ [0x10BD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10BD,
+ },
+ [0x10BE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10BE,
+ },
+ [0x10BF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10BF,
+ },
+ [0x10C0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10C0,
+ },
+ [0x10C1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10C1,
+ },
+ [0x10C2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10C2,
+ },
+ [0x10C3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10C3,
+ },
+ [0x10C4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10C4,
+ },
+ [0x10C5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10C5,
+ },
+ [0x10C7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10C7,
+ },
+ [0x10CD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10CD,
+ },
+ [0x10D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D0,
+ },
+ [0x10D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D1,
+ },
+ [0x10D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D2,
+ },
+ [0x10D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D3,
+ },
+ [0x10D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D4,
+ },
+ [0x10D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D5,
+ },
+ [0x10D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D6,
+ },
+ [0x10D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D7,
+ },
+ [0x10D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D8,
+ },
+ [0x10D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D9,
+ },
+ [0x10DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10DA,
+ },
+ [0x10DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10DB,
+ },
+ [0x10DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10DC,
+ },
+ [0x10DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10DD,
+ },
+ [0x10DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10DE,
+ },
+ [0x10DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10DF,
+ },
+ [0x10E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E0,
+ },
+ [0x10E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E1,
+ },
+ [0x10E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E2,
+ },
+ [0x10E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E3,
+ },
+ [0x10E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E4,
+ },
+ [0x10E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E5,
+ },
+ [0x10E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E6,
+ },
+ [0x10E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E7,
+ },
+ [0x10E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E8,
+ },
+ [0x10E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E9,
+ },
+ [0x10EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10EA,
+ },
+ [0x10EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10EB,
+ },
+ [0x10EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10EC,
+ },
+ [0x10ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10ED,
+ },
+ [0x10EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10EE,
+ },
+ [0x10EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10EF,
+ },
+ [0x10F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F0,
+ },
+ [0x10F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F1,
+ },
+ [0x10F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F2,
+ },
+ [0x10F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F3,
+ },
+ [0x10F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F4,
+ },
+ [0x10F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F5,
+ },
+ [0x10F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F6,
+ },
+ [0x10F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F7,
+ },
+ [0x10F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F8,
+ },
+ [0x10F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F9,
+ },
+ [0x10FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10FA,
+ },
+ [0x10FB]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10FB,
+ },
+ [0x10FC]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x10DC },
+ unicodeslot=0x10FC,
+ },
+ [0x10FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10FD,
+ },
+ [0x10FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10FE,
+ },
+ [0x10FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10FF,
+ },
+ [0x1100]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1100,
+ },
+ [0x1101]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1101,
+ },
+ [0x1102]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1102,
+ },
+ [0x1103]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1103,
+ },
+ [0x1104]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1104,
+ },
+ [0x1105]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1105,
+ },
+ [0x1106]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1106,
+ },
+ [0x1107]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1107,
+ },
+ [0x1108]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1108,
+ },
+ [0x1109]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1109,
+ },
+ [0x110A]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x110A,
+ },
+ [0x110B]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x110B,
+ },
+ [0x110C]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x110C,
+ },
+ [0x110D]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x110D,
+ },
+ [0x110E]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x110E,
+ },
+ [0x110F]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x110F,
+ },
+ [0x1110]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1110,
+ },
+ [0x1111]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1111,
+ },
+ [0x1112]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1112,
+ },
+ [0x1113]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1113,
+ },
+ [0x1114]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1114,
+ },
+ [0x1115]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1115,
+ },
+ [0x1116]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1116,
+ },
+ [0x1117]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1117,
+ },
+ [0x1118]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1118,
+ },
+ [0x1119]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1119,
+ },
+ [0x111A]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x111A,
+ },
+ [0x111B]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x111B,
+ },
+ [0x111C]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x111C,
+ },
+ [0x111D]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x111D,
+ },
+ [0x111E]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x111E,
+ },
+ [0x111F]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x111F,
+ },
+ [0x1120]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1120,
+ },
+ [0x1121]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1121,
+ },
+ [0x1122]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1122,
+ },
+ [0x1123]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1123,
+ },
+ [0x1124]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1124,
+ },
+ [0x1125]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1125,
+ },
+ [0x1126]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1126,
+ },
+ [0x1127]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1127,
+ },
+ [0x1128]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1128,
+ },
+ [0x1129]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1129,
+ },
+ [0x112A]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x112A,
+ },
+ [0x112B]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x112B,
+ },
+ [0x112C]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x112C,
+ },
+ [0x112D]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x112D,
+ },
+ [0x112E]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x112E,
+ },
+ [0x112F]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x112F,
+ },
+ [0x1130]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1130,
+ },
+ [0x1131]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1131,
+ },
+ [0x1132]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1132,
+ },
+ [0x1133]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1133,
+ },
+ [0x1134]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1134,
+ },
+ [0x1135]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1135,
+ },
+ [0x1136]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1136,
+ },
+ [0x1137]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1137,
+ },
+ [0x1138]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1138,
+ },
+ [0x1139]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1139,
+ },
+ [0x113A]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x113A,
+ },
+ [0x113B]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x113B,
+ },
+ [0x113C]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x113C,
+ },
+ [0x113D]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x113D,
+ },
+ [0x113E]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x113E,
+ },
+ [0x113F]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x113F,
+ },
+ [0x1140]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1140,
+ },
+ [0x1141]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1141,
+ },
+ [0x1142]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1142,
+ },
+ [0x1143]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1143,
+ },
+ [0x1144]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1144,
+ },
+ [0x1145]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1145,
+ },
+ [0x1146]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1146,
+ },
+ [0x1147]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1147,
+ },
+ [0x1148]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1148,
+ },
+ [0x1149]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1149,
+ },
+ [0x114A]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x114A,
+ },
+ [0x114B]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x114B,
+ },
+ [0x114C]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x114C,
+ },
+ [0x114D]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x114D,
+ },
+ [0x114E]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x114E,
+ },
+ [0x114F]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x114F,
+ },
+ [0x1150]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1150,
+ },
+ [0x1151]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1151,
+ },
+ [0x1152]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1152,
+ },
+ [0x1153]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1153,
+ },
+ [0x1154]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1154,
+ },
+ [0x1155]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1155,
+ },
+ [0x1156]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1156,
+ },
+ [0x1157]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1157,
+ },
+ [0x1158]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1158,
+ },
+ [0x1159]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1159,
+ },
+ [0x115A]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x115A,
+ },
+ [0x115B]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x115B,
+ },
+ [0x115C]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x115C,
+ },
+ [0x115D]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x115D,
+ },
+ [0x115E]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x115E,
+ },
+ [0x115F]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x115F,
+ },
+ [0x1160]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1160,
+ },
+ [0x1161]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1161,
+ },
+ [0x1162]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1162,
+ },
+ [0x1163]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1163,
+ },
+ [0x1164]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1164,
+ },
+ [0x1165]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1165,
+ },
+ [0x1166]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1166,
+ },
+ [0x1167]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1167,
+ },
+ [0x1168]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1168,
+ },
+ [0x1169]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1169,
+ },
+ [0x116A]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x116A,
+ },
+ [0x116B]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x116B,
+ },
+ [0x116C]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x116C,
+ },
+ [0x116D]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x116D,
+ },
+ [0x116E]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x116E,
+ },
+ [0x116F]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x116F,
+ },
+ [0x1170]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1170,
+ },
+ [0x1171]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1171,
+ },
+ [0x1172]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1172,
+ },
+ [0x1173]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1173,
+ },
+ [0x1174]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1174,
+ },
+ [0x1175]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1175,
+ },
+ [0x1176]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1176,
+ },
+ [0x1177]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1177,
+ },
+ [0x1178]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1178,
+ },
+ [0x1179]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1179,
+ },
+ [0x117A]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x117A,
+ },
+ [0x117B]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x117B,
+ },
+ [0x117C]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x117C,
+ },
+ [0x117D]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x117D,
+ },
+ [0x117E]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x117E,
+ },
+ [0x117F]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x117F,
+ },
+ [0x1180]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1180,
+ },
+ [0x1181]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1181,
+ },
+ [0x1182]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1182,
+ },
+ [0x1183]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1183,
+ },
+ [0x1184]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1184,
+ },
+ [0x1185]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1185,
+ },
+ [0x1186]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1186,
+ },
+ [0x1187]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1187,
+ },
+ [0x1188]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1188,
+ },
+ [0x1189]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1189,
+ },
+ [0x118A]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x118A,
+ },
+ [0x118B]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x118B,
+ },
+ [0x118C]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x118C,
+ },
+ [0x118D]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x118D,
+ },
+ [0x118E]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x118E,
+ },
+ [0x118F]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x118F,
+ },
+ [0x1190]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1190,
+ },
+ [0x1191]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1191,
+ },
+ [0x1192]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1192,
+ },
+ [0x1193]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1193,
+ },
+ [0x1194]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1194,
+ },
+ [0x1195]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1195,
+ },
+ [0x1196]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1196,
+ },
+ [0x1197]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1197,
+ },
+ [0x1198]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1198,
+ },
+ [0x1199]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1199,
+ },
+ [0x119A]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x119A,
+ },
+ [0x119B]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x119B,
+ },
+ [0x119C]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x119C,
+ },
+ [0x119D]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x119D,
+ },
+ [0x119E]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x119E,
+ },
+ [0x119F]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x119F,
+ },
+ [0x11A0]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A0,
+ },
+ [0x11A1]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A1,
+ },
+ [0x11A2]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A2,
+ },
+ [0x11A3]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A3,
+ },
+ [0x11A4]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A4,
+ },
+ [0x11A5]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A5,
+ },
+ [0x11A6]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A6,
+ },
+ [0x11A7]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A7,
+ },
+ [0x11A8]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11A8,
+ },
+ [0x11A9]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11A9,
+ },
+ [0x11AA]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11AA,
+ },
+ [0x11AB]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11AB,
+ },
+ [0x11AC]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11AC,
+ },
+ [0x11AD]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11AD,
+ },
+ [0x11AE]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11AE,
+ },
+ [0x11AF]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11AF,
+ },
+ [0x11B0]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B0,
+ },
+ [0x11B1]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B1,
+ },
+ [0x11B2]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B2,
+ },
+ [0x11B3]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B3,
+ },
+ [0x11B4]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B4,
+ },
+ [0x11B5]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B5,
+ },
+ [0x11B6]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B6,
+ },
+ [0x11B7]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B7,
+ },
+ [0x11B8]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B8,
+ },
+ [0x11B9]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B9,
+ },
+ [0x11BA]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11BA,
+ },
+ [0x11BB]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11BB,
+ },
+ [0x11BC]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11BC,
+ },
+ [0x11BD]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11BD,
+ },
+ [0x11BE]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11BE,
+ },
+ [0x11BF]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11BF,
+ },
+ [0x11C0]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C0,
+ },
+ [0x11C1]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C1,
+ },
+ [0x11C2]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C2,
+ },
+ [0x11C3]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C3,
+ },
+ [0x11C4]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C4,
+ },
+ [0x11C5]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C5,
+ },
+ [0x11C6]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C6,
+ },
+ [0x11C7]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C7,
+ },
+ [0x11C8]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C8,
+ },
+ [0x11C9]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C9,
+ },
+ [0x11CA]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11CA,
+ },
+ [0x11CB]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11CB,
+ },
+ [0x11CC]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11CC,
+ },
+ [0x11CD]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11CD,
+ },
+ [0x11CE]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11CE,
+ },
+ [0x11CF]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11CF,
+ },
+ [0x11D0]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D0,
+ },
+ [0x11D1]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D1,
+ },
+ [0x11D2]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D2,
+ },
+ [0x11D3]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D3,
+ },
+ [0x11D4]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D4,
+ },
+ [0x11D5]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D5,
+ },
+ [0x11D6]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D6,
+ },
+ [0x11D7]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D7,
+ },
+ [0x11D8]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D8,
+ },
+ [0x11D9]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D9,
+ },
+ [0x11DA]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11DA,
+ },
+ [0x11DB]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11DB,
+ },
+ [0x11DC]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11DC,
+ },
+ [0x11DD]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11DD,
+ },
+ [0x11DE]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11DE,
+ },
+ [0x11DF]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11DF,
+ },
+ [0x11E0]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E0,
+ },
+ [0x11E1]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E1,
+ },
+ [0x11E2]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E2,
+ },
+ [0x11E3]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E3,
+ },
+ [0x11E4]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E4,
+ },
+ [0x11E5]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E5,
+ },
+ [0x11E6]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E6,
+ },
+ [0x11E7]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E7,
+ },
+ [0x11E8]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E8,
+ },
+ [0x11E9]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E9,
+ },
+ [0x11EA]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11EA,
+ },
+ [0x11EB]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11EB,
+ },
+ [0x11EC]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11EC,
+ },
+ [0x11ED]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11ED,
+ },
+ [0x11EE]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11EE,
+ },
+ [0x11EF]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11EF,
+ },
+ [0x11F0]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F0,
+ },
+ [0x11F1]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F1,
+ },
+ [0x11F2]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F2,
+ },
+ [0x11F3]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F3,
+ },
+ [0x11F4]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F4,
+ },
+ [0x11F5]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F5,
+ },
+ [0x11F6]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F6,
+ },
+ [0x11F7]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F7,
+ },
+ [0x11F8]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F8,
+ },
+ [0x11F9]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F9,
+ },
+ [0x11FA]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11FA,
+ },
+ [0x11FB]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11FB,
+ },
+ [0x11FC]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11FC,
+ },
+ [0x11FD]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11FD,
+ },
+ [0x11FE]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11FE,
+ },
+ [0x11FF]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11FF,
+ },
+ [0x1200]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200,
+ },
+ [0x1201]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201,
+ },
+ [0x1202]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202,
+ },
+ [0x1203]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203,
+ },
+ [0x1204]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204,
+ },
+ [0x1205]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205,
+ },
+ [0x1206]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206,
+ },
+ [0x1207]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207,
+ },
+ [0x1208]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208,
+ },
+ [0x1209]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209,
+ },
+ [0x120A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A,
+ },
+ [0x120B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B,
+ },
+ [0x120C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C,
+ },
+ [0x120D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D,
+ },
+ [0x120E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E,
+ },
+ [0x120F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F,
+ },
+ [0x1210]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210,
+ },
+ [0x1211]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211,
+ },
+ [0x1212]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212,
+ },
+ [0x1213]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213,
+ },
+ [0x1214]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214,
+ },
+ [0x1215]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215,
+ },
+ [0x1216]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216,
+ },
+ [0x1217]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217,
+ },
+ [0x1218]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218,
+ },
+ [0x1219]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219,
+ },
+ [0x121A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A,
+ },
+ [0x121B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B,
+ },
+ [0x121C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C,
+ },
+ [0x121D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D,
+ },
+ [0x121E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E,
+ },
+ [0x121F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F,
+ },
+ [0x1220]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220,
+ },
+ [0x1221]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221,
+ },
+ [0x1222]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222,
+ },
+ [0x1223]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223,
+ },
+ [0x1224]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224,
+ },
+ [0x1225]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225,
+ },
+ [0x1226]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226,
+ },
+ [0x1227]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227,
+ },
+ [0x1228]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228,
+ },
+ [0x1229]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229,
+ },
+ [0x122A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A,
+ },
+ [0x122B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B,
+ },
+ [0x122C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C,
+ },
+ [0x122D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D,
+ },
+ [0x122E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E,
+ },
+ [0x122F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F,
+ },
+ [0x1230]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230,
+ },
+ [0x1231]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231,
+ },
+ [0x1232]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232,
+ },
+ [0x1233]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233,
+ },
+ [0x1234]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234,
+ },
+ [0x1235]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235,
+ },
+ [0x1236]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236,
+ },
+ [0x1237]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1237,
+ },
+ [0x1238]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1238,
+ },
+ [0x1239]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1239,
+ },
+ [0x123A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x123A,
+ },
+ [0x123B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x123B,
+ },
+ [0x123C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x123C,
+ },
+ [0x123D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x123D,
+ },
+ [0x123E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x123E,
+ },
+ [0x123F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x123F,
+ },
+ [0x1240]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240,
+ },
+ [0x1241]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241,
+ },
+ [0x1242]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242,
+ },
+ [0x1243]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243,
+ },
+ [0x1244]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244,
+ },
+ [0x1245]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245,
+ },
+ [0x1246]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1246,
+ },
+ [0x1247]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1247,
+ },
+ [0x1248]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1248,
+ },
+ [0x124A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124A,
+ },
+ [0x124B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124B,
+ },
+ [0x124C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124C,
+ },
+ [0x124D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124D,
+ },
+ [0x1250]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1250,
+ },
+ [0x1251]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1251,
+ },
+ [0x1252]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1252,
+ },
+ [0x1253]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1253,
+ },
+ [0x1254]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1254,
+ },
+ [0x1255]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1255,
+ },
+ [0x1256]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1256,
+ },
+ [0x1258]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1258,
+ },
+ [0x125A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x125A,
+ },
+ [0x125B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x125B,
+ },
+ [0x125C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x125C,
+ },
+ [0x125D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x125D,
+ },
+ [0x1260]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1260,
+ },
+ [0x1261]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1261,
+ },
+ [0x1262]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1262,
+ },
+ [0x1263]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1263,
+ },
+ [0x1264]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1264,
+ },
+ [0x1265]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1265,
+ },
+ [0x1266]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1266,
+ },
+ [0x1267]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1267,
+ },
+ [0x1268]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1268,
+ },
+ [0x1269]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1269,
+ },
+ [0x126A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126A,
+ },
+ [0x126B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126B,
+ },
+ [0x126C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126C,
+ },
+ [0x126D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126D,
+ },
+ [0x126E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126E,
+ },
+ [0x126F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126F,
+ },
+ [0x1270]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1270,
+ },
+ [0x1271]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1271,
+ },
+ [0x1272]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1272,
+ },
+ [0x1273]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1273,
+ },
+ [0x1274]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1274,
+ },
+ [0x1275]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1275,
+ },
+ [0x1276]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1276,
+ },
+ [0x1277]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1277,
+ },
+ [0x1278]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1278,
+ },
+ [0x1279]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1279,
+ },
+ [0x127A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127A,
+ },
+ [0x127B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127B,
+ },
+ [0x127C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127C,
+ },
+ [0x127D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127D,
+ },
+ [0x127E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127E,
+ },
+ [0x127F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127F,
+ },
+ [0x1280]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1280,
+ },
+ [0x1281]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1281,
+ },
+ [0x1282]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1282,
+ },
+ [0x1283]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1283,
+ },
+ [0x1284]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1284,
+ },
+ [0x1285]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1285,
+ },
+ [0x1286]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1286,
+ },
+ [0x1287]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1287,
+ },
+ [0x1288]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1288,
+ },
+ [0x128A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x128A,
+ },
+ [0x128B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x128B,
+ },
+ [0x128C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x128C,
+ },
+ [0x128D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x128D,
+ },
+ [0x1290]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1290,
+ },
+ [0x1291]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1291,
+ },
+ [0x1292]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1292,
+ },
+ [0x1293]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1293,
+ },
+ [0x1294]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1294,
+ },
+ [0x1295]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1295,
+ },
+ [0x1296]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1296,
+ },
+ [0x1297]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1297,
+ },
+ [0x1298]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1298,
+ },
+ [0x1299]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1299,
+ },
+ [0x129A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x129A,
+ },
+ [0x129B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x129B,
+ },
+ [0x129C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x129C,
+ },
+ [0x129D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x129D,
+ },
+ [0x129E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x129E,
+ },
+ [0x129F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x129F,
+ },
+ [0x12A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A0,
+ },
+ [0x12A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A1,
+ },
+ [0x12A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A2,
+ },
+ [0x12A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A3,
+ },
+ [0x12A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A4,
+ },
+ [0x12A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A5,
+ },
+ [0x12A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A6,
+ },
+ [0x12A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A7,
+ },
+ [0x12A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A8,
+ },
+ [0x12A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A9,
+ },
+ [0x12AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12AA,
+ },
+ [0x12AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12AB,
+ },
+ [0x12AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12AC,
+ },
+ [0x12AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12AD,
+ },
+ [0x12AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12AE,
+ },
+ [0x12AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12AF,
+ },
+ [0x12B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B0,
+ },
+ [0x12B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B2,
+ },
+ [0x12B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B3,
+ },
+ [0x12B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B4,
+ },
+ [0x12B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B5,
+ },
+ [0x12B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B8,
+ },
+ [0x12B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B9,
+ },
+ [0x12BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12BA,
+ },
+ [0x12BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12BB,
+ },
+ [0x12BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12BC,
+ },
+ [0x12BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12BD,
+ },
+ [0x12BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12BE,
+ },
+ [0x12C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C0,
+ },
+ [0x12C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C2,
+ },
+ [0x12C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C3,
+ },
+ [0x12C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C4,
+ },
+ [0x12C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C5,
+ },
+ [0x12C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C8,
+ },
+ [0x12C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C9,
+ },
+ [0x12CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12CA,
+ },
+ [0x12CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12CB,
+ },
+ [0x12CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12CC,
+ },
+ [0x12CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12CD,
+ },
+ [0x12CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12CE,
+ },
+ [0x12CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12CF,
+ },
+ [0x12D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D0,
+ },
+ [0x12D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D1,
+ },
+ [0x12D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D2,
+ },
+ [0x12D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D3,
+ },
+ [0x12D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D4,
+ },
+ [0x12D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D5,
+ },
+ [0x12D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D6,
+ },
+ [0x12D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D8,
+ },
+ [0x12D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D9,
+ },
+ [0x12DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12DA,
+ },
+ [0x12DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12DB,
+ },
+ [0x12DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12DC,
+ },
+ [0x12DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12DD,
+ },
+ [0x12DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12DE,
+ },
+ [0x12DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12DF,
+ },
+ [0x12E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E0,
+ },
+ [0x12E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E1,
+ },
+ [0x12E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E2,
+ },
+ [0x12E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E3,
+ },
+ [0x12E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E4,
+ },
+ [0x12E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E5,
+ },
+ [0x12E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E6,
+ },
+ [0x12E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E7,
+ },
+ [0x12E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E8,
+ },
+ [0x12E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E9,
+ },
+ [0x12EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12EA,
+ },
+ [0x12EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12EB,
+ },
+ [0x12EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12EC,
+ },
+ [0x12ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12ED,
+ },
+ [0x12EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12EE,
+ },
+ [0x12EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12EF,
+ },
+ [0x12F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F0,
+ },
+ [0x12F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F1,
+ },
+ [0x12F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F2,
+ },
+ [0x12F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F3,
+ },
+ [0x12F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F4,
+ },
+ [0x12F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F5,
+ },
+ [0x12F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F6,
+ },
+ [0x12F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F7,
+ },
+ [0x12F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F8,
+ },
+ [0x12F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F9,
+ },
+ [0x12FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12FA,
+ },
+ [0x12FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12FB,
+ },
+ [0x12FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12FC,
+ },
+ [0x12FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12FD,
+ },
+ [0x12FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12FE,
+ },
+ [0x12FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12FF,
+ },
+ [0x1300]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300,
+ },
+ [0x1301]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301,
+ },
+ [0x1302]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302,
+ },
+ [0x1303]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303,
+ },
+ [0x1304]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304,
+ },
+ [0x1305]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305,
+ },
+ [0x1306]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306,
+ },
+ [0x1307]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307,
+ },
+ [0x1308]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308,
+ },
+ [0x1309]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309,
+ },
+ [0x130A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A,
+ },
+ [0x130B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B,
+ },
+ [0x130C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C,
+ },
+ [0x130D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D,
+ },
+ [0x130E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E,
+ },
+ [0x130F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F,
+ },
+ [0x1310]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310,
+ },
+ [0x1312]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312,
+ },
+ [0x1313]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313,
+ },
+ [0x1314]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314,
+ },
+ [0x1315]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315,
+ },
+ [0x1318]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318,
+ },
+ [0x1319]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319,
+ },
+ [0x131A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A,
+ },
+ [0x131B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B,
+ },
+ [0x131C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C,
+ },
+ [0x131D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D,
+ },
+ [0x131E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E,
+ },
+ [0x131F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F,
+ },
+ [0x1320]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320,
+ },
+ [0x1321]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321,
+ },
+ [0x1322]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322,
+ },
+ [0x1323]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323,
+ },
+ [0x1324]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324,
+ },
+ [0x1325]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1325,
+ },
+ [0x1326]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326,
+ },
+ [0x1327]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327,
+ },
+ [0x1328]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328,
+ },
+ [0x1329]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329,
+ },
+ [0x132A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A,
+ },
+ [0x132B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B,
+ },
+ [0x132C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C,
+ },
+ [0x132D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D,
+ },
+ [0x132E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E,
+ },
+ [0x132F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F,
+ },
+ [0x1330]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330,
+ },
+ [0x1331]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331,
+ },
+ [0x1332]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332,
+ },
+ [0x1333]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333,
+ },
+ [0x1334]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334,
+ },
+ [0x1335]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335,
+ },
+ [0x1336]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336,
+ },
+ [0x1337]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1337,
+ },
+ [0x1338]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338,
+ },
+ [0x1339]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339,
+ },
+ [0x133A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A,
+ },
+ [0x133B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B,
+ },
+ [0x133C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C,
+ },
+ [0x133D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D,
+ },
+ [0x133E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E,
+ },
+ [0x133F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F,
+ },
+ [0x1340]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340,
+ },
+ [0x1341]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341,
+ },
+ [0x1342]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1342,
+ },
+ [0x1343]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1343,
+ },
+ [0x1344]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1344,
+ },
+ [0x1345]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1345,
+ },
+ [0x1346]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1346,
+ },
+ [0x1347]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1347,
+ },
+ [0x1348]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1348,
+ },
+ [0x1349]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1349,
+ },
+ [0x134A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x134A,
+ },
+ [0x134B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x134B,
+ },
+ [0x134C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x134C,
+ },
+ [0x134D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x134D,
+ },
+ [0x134E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x134E,
+ },
+ [0x134F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x134F,
+ },
+ [0x1350]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1350,
+ },
+ [0x1351]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1351,
+ },
+ [0x1352]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1352,
+ },
+ [0x1353]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1353,
+ },
+ [0x1354]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1354,
+ },
+ [0x1355]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1355,
+ },
+ [0x1356]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1356,
+ },
+ [0x1357]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1357,
+ },
+ [0x1358]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1358,
+ },
+ [0x1359]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1359,
+ },
+ [0x135A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x135A,
+ },
+ [0x135D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x135D,
+ },
+ [0x135E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x135E,
+ },
+ [0x135F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x135F,
+ },
+ [0x1360]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1360,
+ },
+ [0x1361]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1361,
+ },
+ [0x1362]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1362,
+ },
+ [0x1363]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1363,
+ },
+ [0x1364]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1364,
+ },
+ [0x1365]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1365,
+ },
+ [0x1366]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1366,
+ },
+ [0x1367]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1367,
+ },
+ [0x1368]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1368,
+ },
+ [0x1369]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1369,
+ },
+ [0x136A]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x136A,
+ },
+ [0x136B]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x136B,
+ },
+ [0x136C]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x136C,
+ },
+ [0x136D]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x136D,
+ },
+ [0x136E]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x136E,
+ },
+ [0x136F]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x136F,
+ },
+ [0x1370]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1370,
+ },
+ [0x1371]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1371,
+ },
+ [0x1372]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1372,
+ },
+ [0x1373]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1373,
+ },
+ [0x1374]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1374,
+ },
+ [0x1375]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1375,
+ },
+ [0x1376]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1376,
+ },
+ [0x1377]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1377,
+ },
+ [0x1378]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1378,
+ },
+ [0x1379]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1379,
+ },
+ [0x137A]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x137A,
+ },
+ [0x137B]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x137B,
+ },
+ [0x137C]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x137C,
+ },
+ [0x1380]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1380,
+ },
+ [0x1381]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1381,
+ },
+ [0x1382]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1382,
+ },
+ [0x1383]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1383,
+ },
+ [0x1384]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1384,
+ },
+ [0x1385]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1385,
+ },
+ [0x1386]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1386,
+ },
+ [0x1387]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1387,
+ },
+ [0x1388]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1388,
+ },
+ [0x1389]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1389,
+ },
+ [0x138A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138A,
+ },
+ [0x138B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138B,
+ },
+ [0x138C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138C,
+ },
+ [0x138D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138D,
+ },
+ [0x138E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138E,
+ },
+ [0x138F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138F,
+ },
+ [0x1390]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1390,
+ },
+ [0x1391]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1391,
+ },
+ [0x1392]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1392,
+ },
+ [0x1393]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1393,
+ },
+ [0x1394]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1394,
+ },
+ [0x1395]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1395,
+ },
+ [0x1396]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1396,
+ },
+ [0x1397]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1397,
+ },
+ [0x1398]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1398,
+ },
+ [0x1399]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1399,
+ },
+ [0x13A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A0,
+ },
+ [0x13A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A1,
+ },
+ [0x13A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A2,
+ },
+ [0x13A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A3,
+ },
+ [0x13A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A4,
+ },
+ [0x13A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A5,
+ },
+ [0x13A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A6,
+ },
+ [0x13A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A7,
+ },
+ [0x13A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A8,
+ },
+ [0x13A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A9,
+ },
+ [0x13AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13AA,
+ },
+ [0x13AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13AB,
+ },
+ [0x13AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13AC,
+ },
+ [0x13AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13AD,
+ },
+ [0x13AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13AE,
+ },
+ [0x13AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13AF,
+ },
+ [0x13B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B0,
+ },
+ [0x13B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B1,
+ },
+ [0x13B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B2,
+ },
+ [0x13B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B3,
+ },
+ [0x13B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B4,
+ },
+ [0x13B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B5,
+ },
+ [0x13B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B6,
+ },
+ [0x13B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B7,
+ },
+ [0x13B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B8,
+ },
+ [0x13B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B9,
+ },
+ [0x13BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13BA,
+ },
+ [0x13BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13BB,
+ },
+ [0x13BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13BC,
+ },
+ [0x13BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13BD,
+ },
+ [0x13BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13BE,
+ },
+ [0x13BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13BF,
+ },
+ [0x13C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C0,
+ },
+ [0x13C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C1,
+ },
+ [0x13C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C2,
+ },
+ [0x13C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C3,
+ },
+ [0x13C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C4,
+ },
+ [0x13C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C5,
+ },
+ [0x13C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C6,
+ },
+ [0x13C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C7,
+ },
+ [0x13C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C8,
+ },
+ [0x13C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C9,
+ },
+ [0x13CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13CA,
+ },
+ [0x13CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13CB,
+ },
+ [0x13CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13CC,
+ },
+ [0x13CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13CD,
+ },
+ [0x13CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13CE,
+ },
+ [0x13CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13CF,
+ },
+ [0x13D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D0,
+ },
+ [0x13D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D1,
+ },
+ [0x13D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D2,
+ },
+ [0x13D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D3,
+ },
+ [0x13D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D4,
+ },
+ [0x13D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D5,
+ },
+ [0x13D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D6,
+ },
+ [0x13D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D7,
+ },
+ [0x13D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D8,
+ },
+ [0x13D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D9,
+ },
+ [0x13DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13DA,
+ },
+ [0x13DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13DB,
+ },
+ [0x13DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13DC,
+ },
+ [0x13DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13DD,
+ },
+ [0x13DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13DE,
+ },
+ [0x13DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13DF,
+ },
+ [0x13E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E0,
+ },
+ [0x13E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E1,
+ },
+ [0x13E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E2,
+ },
+ [0x13E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E3,
+ },
+ [0x13E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E4,
+ },
+ [0x13E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E5,
+ },
+ [0x13E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E6,
+ },
+ [0x13E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E7,
+ },
+ [0x13E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E8,
+ },
+ [0x13E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E9,
+ },
+ [0x13EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13EA,
+ },
+ [0x13EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13EB,
+ },
+ [0x13EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13EC,
+ },
+ [0x13ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13ED,
+ },
+ [0x13EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13EE,
+ },
+ [0x13EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13EF,
+ },
+ [0x13F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F0,
+ },
+ [0x13F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F1,
+ },
+ [0x13F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F2,
+ },
+ [0x13F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F3,
+ },
+ [0x13F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F4,
+ },
+ [0x13F5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F5,
+ },
+ [0x13F8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F8,
+ },
+ [0x13F9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F9,
+ },
+ [0x13FA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13FA,
+ },
+ [0x13FB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13FB,
+ },
+ [0x13FC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13FC,
+ },
+ [0x13FD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13FD,
+ },
+ [0x1400]={
+ category="pd",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x1400,
+ },
+ [0x1401]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1401,
+ },
+ [0x1402]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1402,
+ },
+ [0x1403]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1403,
+ },
+ [0x1404]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1404,
+ },
+ [0x1405]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1405,
+ },
+ [0x1406]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1406,
+ },
+ [0x1407]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1407,
+ },
+ [0x1408]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1408,
+ },
+ [0x1409]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1409,
+ },
+ [0x140A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x140A,
+ },
+ [0x140B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x140B,
+ },
+ [0x140C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x140C,
+ },
+ [0x140D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x140D,
+ },
+ [0x140E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x140E,
+ },
+ [0x140F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x140F,
+ },
+ [0x1410]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1410,
+ },
+ [0x1411]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1411,
+ },
+ [0x1412]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1412,
+ },
+ [0x1413]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1413,
+ },
+ [0x1414]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1414,
+ },
+ [0x1415]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1415,
+ },
+ [0x1416]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1416,
+ },
+ [0x1417]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1417,
+ },
+ [0x1418]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1418,
+ },
+ [0x1419]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1419,
+ },
+ [0x141A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141A,
+ },
+ [0x141B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141B,
+ },
+ [0x141C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141C,
+ },
+ [0x141D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141D,
+ },
+ [0x141E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141E,
+ },
+ [0x141F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141F,
+ },
+ [0x1420]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1420,
+ },
+ [0x1421]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1421,
+ },
+ [0x1422]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1422,
+ },
+ [0x1423]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1423,
+ },
+ [0x1424]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1424,
+ },
+ [0x1425]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1425,
+ },
+ [0x1426]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1426,
+ },
+ [0x1427]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1427,
+ },
+ [0x1428]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1428,
+ },
+ [0x1429]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1429,
+ },
+ [0x142A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142A,
+ },
+ [0x142B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142B,
+ },
+ [0x142C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142C,
+ },
+ [0x142D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142D,
+ },
+ [0x142E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142E,
+ },
+ [0x142F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142F,
+ },
+ [0x1430]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1430,
+ },
+ [0x1431]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1431,
+ },
+ [0x1432]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1432,
+ },
+ [0x1433]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1433,
+ },
+ [0x1434]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1434,
+ },
+ [0x1435]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1435,
+ },
+ [0x1436]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1436,
+ },
+ [0x1437]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1437,
+ },
+ [0x1438]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1438,
+ },
+ [0x1439]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1439,
+ },
+ [0x143A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x143A,
+ },
+ [0x143B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x143B,
+ },
+ [0x143C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x143C,
+ },
+ [0x143D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x143D,
+ },
+ [0x143E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x143E,
+ },
+ [0x143F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x143F,
+ },
+ [0x1440]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1440,
+ },
+ [0x1441]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1441,
+ },
+ [0x1442]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1442,
+ },
+ [0x1443]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1443,
+ },
+ [0x1444]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1444,
+ },
+ [0x1445]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1445,
+ },
+ [0x1446]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1446,
+ },
+ [0x1447]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1447,
+ },
+ [0x1448]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1448,
+ },
+ [0x1449]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1449,
+ },
+ [0x144A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144A,
+ },
+ [0x144B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144B,
+ },
+ [0x144C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144C,
+ },
+ [0x144D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144D,
+ },
+ [0x144E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144E,
+ },
+ [0x144F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144F,
+ },
+ [0x1450]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1450,
+ },
+ [0x1451]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1451,
+ },
+ [0x1452]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1452,
+ },
+ [0x1453]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1453,
+ },
+ [0x1454]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1454,
+ },
+ [0x1455]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1455,
+ },
+ [0x1456]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1456,
+ },
+ [0x1457]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1457,
+ },
+ [0x1458]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1458,
+ },
+ [0x1459]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1459,
+ },
+ [0x145A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145A,
+ },
+ [0x145B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145B,
+ },
+ [0x145C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145C,
+ },
+ [0x145D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145D,
+ },
+ [0x145E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145E,
+ },
+ [0x145F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145F,
+ },
+ [0x1460]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1460,
+ },
+ [0x1461]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1461,
+ },
+ [0x1462]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1462,
+ },
+ [0x1463]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1463,
+ },
+ [0x1464]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1464,
+ },
+ [0x1465]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1465,
+ },
+ [0x1466]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1466,
+ },
+ [0x1467]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1467,
+ },
+ [0x1468]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1468,
+ },
+ [0x1469]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1469,
+ },
+ [0x146A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x146A,
+ },
+ [0x146B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x146B,
+ },
+ [0x146C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x146C,
+ },
+ [0x146D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x146D,
+ },
+ [0x146E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x146E,
+ },
+ [0x146F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x146F,
+ },
+ [0x1470]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1470,
+ },
+ [0x1471]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1471,
+ },
+ [0x1472]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1472,
+ },
+ [0x1473]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1473,
+ },
+ [0x1474]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1474,
+ },
+ [0x1475]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1475,
+ },
+ [0x1476]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1476,
+ },
+ [0x1477]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1477,
+ },
+ [0x1478]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1478,
+ },
+ [0x1479]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1479,
+ },
+ [0x147A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x147A,
+ },
+ [0x147B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x147B,
+ },
+ [0x147C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x147C,
+ },
+ [0x147D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x147D,
+ },
+ [0x147E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x147E,
+ },
+ [0x147F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x147F,
+ },
+ [0x1480]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1480,
+ },
+ [0x1481]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1481,
+ },
+ [0x1482]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1482,
+ },
+ [0x1483]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1483,
+ },
+ [0x1484]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1484,
+ },
+ [0x1485]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1485,
+ },
+ [0x1486]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1486,
+ },
+ [0x1487]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1487,
+ },
+ [0x1488]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1488,
+ },
+ [0x1489]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1489,
+ },
+ [0x148A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x148A,
+ },
+ [0x148B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x148B,
+ },
+ [0x148C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x148C,
+ },
+ [0x148D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x148D,
+ },
+ [0x148E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x148E,
+ },
+ [0x148F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x148F,
+ },
+ [0x1490]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1490,
+ },
+ [0x1491]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1491,
+ },
+ [0x1492]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1492,
+ },
+ [0x1493]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1493,
+ },
+ [0x1494]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1494,
+ },
+ [0x1495]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1495,
+ },
+ [0x1496]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1496,
+ },
+ [0x1497]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1497,
+ },
+ [0x1498]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1498,
+ },
+ [0x1499]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1499,
+ },
+ [0x149A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x149A,
+ },
+ [0x149B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x149B,
+ },
+ [0x149C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x149C,
+ },
+ [0x149D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x149D,
+ },
+ [0x149E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x149E,
+ },
+ [0x149F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x149F,
+ },
+ [0x14A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A0,
+ },
+ [0x14A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A1,
+ },
+ [0x14A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A2,
+ },
+ [0x14A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A3,
+ },
+ [0x14A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A4,
+ },
+ [0x14A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A5,
+ },
+ [0x14A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A6,
+ },
+ [0x14A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A7,
+ },
+ [0x14A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A8,
+ },
+ [0x14A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A9,
+ },
+ [0x14AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14AA,
+ },
+ [0x14AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14AB,
+ },
+ [0x14AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14AC,
+ },
+ [0x14AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14AD,
+ },
+ [0x14AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14AE,
+ },
+ [0x14AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14AF,
+ },
+ [0x14B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B0,
+ },
+ [0x14B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B1,
+ },
+ [0x14B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B2,
+ },
+ [0x14B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B3,
+ },
+ [0x14B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B4,
+ },
+ [0x14B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B5,
+ },
+ [0x14B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B6,
+ },
+ [0x14B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B7,
+ },
+ [0x14B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B8,
+ },
+ [0x14B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B9,
+ },
+ [0x14BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14BA,
+ },
+ [0x14BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14BB,
+ },
+ [0x14BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14BC,
+ },
+ [0x14BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14BD,
+ },
+ [0x14BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14BE,
+ },
+ [0x14BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14BF,
+ },
+ [0x14C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C0,
+ },
+ [0x14C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C1,
+ },
+ [0x14C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C2,
+ },
+ [0x14C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C3,
+ },
+ [0x14C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C4,
+ },
+ [0x14C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C5,
+ },
+ [0x14C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C6,
+ },
+ [0x14C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C7,
+ },
+ [0x14C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C8,
+ },
+ [0x14C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C9,
+ },
+ [0x14CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14CA,
+ },
+ [0x14CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14CB,
+ },
+ [0x14CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14CC,
+ },
+ [0x14CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14CD,
+ },
+ [0x14CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14CE,
+ },
+ [0x14CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14CF,
+ },
+ [0x14D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D0,
+ },
+ [0x14D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D1,
+ },
+ [0x14D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D2,
+ },
+ [0x14D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D3,
+ },
+ [0x14D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D4,
+ },
+ [0x14D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D5,
+ },
+ [0x14D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D6,
+ },
+ [0x14D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D7,
+ },
+ [0x14D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D8,
+ },
+ [0x14D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D9,
+ },
+ [0x14DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14DA,
+ },
+ [0x14DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14DB,
+ },
+ [0x14DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14DC,
+ },
+ [0x14DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14DD,
+ },
+ [0x14DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14DE,
+ },
+ [0x14DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14DF,
+ },
+ [0x14E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E0,
+ },
+ [0x14E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E1,
+ },
+ [0x14E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E2,
+ },
+ [0x14E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E3,
+ },
+ [0x14E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E4,
+ },
+ [0x14E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E5,
+ },
+ [0x14E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E6,
+ },
+ [0x14E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E7,
+ },
+ [0x14E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E8,
+ },
+ [0x14E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E9,
+ },
+ [0x14EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14EA,
+ },
+ [0x14EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14EB,
+ },
+ [0x14EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14EC,
+ },
+ [0x14ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14ED,
+ },
+ [0x14EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14EE,
+ },
+ [0x14EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14EF,
+ },
+ [0x14F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F0,
+ },
+ [0x14F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F1,
+ },
+ [0x14F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F2,
+ },
+ [0x14F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F3,
+ },
+ [0x14F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F4,
+ },
+ [0x14F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F5,
+ },
+ [0x14F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F6,
+ },
+ [0x14F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F7,
+ },
+ [0x14F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F8,
+ },
+ [0x14F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F9,
+ },
+ [0x14FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14FA,
+ },
+ [0x14FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14FB,
+ },
+ [0x14FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14FC,
+ },
+ [0x14FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14FD,
+ },
+ [0x14FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14FE,
+ },
+ [0x14FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14FF,
+ },
+ [0x1500]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1500,
+ },
+ [0x1501]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1501,
+ },
+ [0x1502]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1502,
+ },
+ [0x1503]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1503,
+ },
+ [0x1504]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1504,
+ },
+ [0x1505]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1505,
+ },
+ [0x1506]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1506,
+ },
+ [0x1507]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1507,
+ },
+ [0x1508]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1508,
+ },
+ [0x1509]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1509,
+ },
+ [0x150A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x150A,
+ },
+ [0x150B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x150B,
+ },
+ [0x150C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x150C,
+ },
+ [0x150D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x150D,
+ },
+ [0x150E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x150E,
+ },
+ [0x150F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x150F,
+ },
+ [0x1510]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1510,
+ },
+ [0x1511]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1511,
+ },
+ [0x1512]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1512,
+ },
+ [0x1513]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1513,
+ },
+ [0x1514]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1514,
+ },
+ [0x1515]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1515,
+ },
+ [0x1516]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1516,
+ },
+ [0x1517]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1517,
+ },
+ [0x1518]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1518,
+ },
+ [0x1519]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1519,
+ },
+ [0x151A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x151A,
+ },
+ [0x151B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x151B,
+ },
+ [0x151C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x151C,
+ },
+ [0x151D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x151D,
+ },
+ [0x151E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x151E,
+ },
+ [0x151F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x151F,
+ },
+ [0x1520]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1520,
+ },
+ [0x1521]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1521,
+ },
+ [0x1522]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1522,
+ },
+ [0x1523]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1523,
+ },
+ [0x1524]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1524,
+ },
+ [0x1525]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1525,
+ },
+ [0x1526]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1526,
+ },
+ [0x1527]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1527,
+ },
+ [0x1528]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1528,
+ },
+ [0x1529]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1529,
+ },
+ [0x152A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152A,
+ },
+ [0x152B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152B,
+ },
+ [0x152C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152C,
+ },
+ [0x152D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152D,
+ },
+ [0x152E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152E,
+ },
+ [0x152F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152F,
+ },
+ [0x1530]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1530,
+ },
+ [0x1531]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1531,
+ },
+ [0x1532]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1532,
+ },
+ [0x1533]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1533,
+ },
+ [0x1534]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1534,
+ },
+ [0x1535]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1535,
+ },
+ [0x1536]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1536,
+ },
+ [0x1537]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1537,
+ },
+ [0x1538]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1538,
+ },
+ [0x1539]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1539,
+ },
+ [0x153A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153A,
+ },
+ [0x153B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153B,
+ },
+ [0x153C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153C,
+ },
+ [0x153D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153D,
+ },
+ [0x153E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153E,
+ },
+ [0x153F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153F,
+ },
+ [0x1540]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1540,
+ },
+ [0x1541]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1541,
+ },
+ [0x1542]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1542,
+ },
+ [0x1543]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1543,
+ },
+ [0x1544]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1544,
+ },
+ [0x1545]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1545,
+ },
+ [0x1546]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1546,
+ },
+ [0x1547]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1547,
+ },
+ [0x1548]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1548,
+ },
+ [0x1549]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1549,
+ },
+ [0x154A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x154A,
+ },
+ [0x154B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x154B,
+ },
+ [0x154C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x154C,
+ },
+ [0x154D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x154D,
+ },
+ [0x154E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x154E,
+ },
+ [0x154F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x154F,
+ },
+ [0x1550]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1550,
+ },
+ [0x1551]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1551,
+ },
+ [0x1552]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1552,
+ },
+ [0x1553]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1553,
+ },
+ [0x1554]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1554,
+ },
+ [0x1555]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1555,
+ },
+ [0x1556]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1556,
+ },
+ [0x1557]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1557,
+ },
+ [0x1558]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1558,
+ },
+ [0x1559]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1559,
+ },
+ [0x155A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x155A,
+ },
+ [0x155B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x155B,
+ },
+ [0x155C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x155C,
+ },
+ [0x155D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x155D,
+ },
+ [0x155E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x155E,
+ },
+ [0x155F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x155F,
+ },
+ [0x1560]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1560,
+ },
+ [0x1561]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1561,
+ },
+ [0x1562]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1562,
+ },
+ [0x1563]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1563,
+ },
+ [0x1564]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1564,
+ },
+ [0x1565]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1565,
+ },
+ [0x1566]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1566,
+ },
+ [0x1567]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1567,
+ },
+ [0x1568]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1568,
+ },
+ [0x1569]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1569,
+ },
+ [0x156A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x156A,
+ },
+ [0x156B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x156B,
+ },
+ [0x156C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x156C,
+ },
+ [0x156D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x156D,
+ },
+ [0x156E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x156E,
+ },
+ [0x156F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x156F,
+ },
+ [0x1570]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1570,
+ },
+ [0x1571]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1571,
+ },
+ [0x1572]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1572,
+ },
+ [0x1573]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1573,
+ },
+ [0x1574]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1574,
+ },
+ [0x1575]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1575,
+ },
+ [0x1576]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1576,
+ },
+ [0x1577]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1577,
+ },
+ [0x1578]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1578,
+ },
+ [0x1579]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1579,
+ },
+ [0x157A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x157A,
+ },
+ [0x157B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x157B,
+ },
+ [0x157C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x157C,
+ },
+ [0x157D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x157D,
+ },
+ [0x157E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x157E,
+ },
+ [0x157F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x157F,
+ },
+ [0x1580]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1580,
+ },
+ [0x1581]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1581,
+ },
+ [0x1582]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1582,
+ },
+ [0x1583]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1583,
+ },
+ [0x1584]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1584,
+ },
+ [0x1585]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1585,
+ },
+ [0x1586]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1586,
+ },
+ [0x1587]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1587,
+ },
+ [0x1588]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1588,
+ },
+ [0x1589]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1589,
+ },
+ [0x158A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x158A,
+ },
+ [0x158B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x158B,
+ },
+ [0x158C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x158C,
+ },
+ [0x158D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x158D,
+ },
+ [0x158E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x158E,
+ },
+ [0x158F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x158F,
+ },
+ [0x1590]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1590,
+ },
+ [0x1591]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1591,
+ },
+ [0x1592]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1592,
+ },
+ [0x1593]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1593,
+ },
+ [0x1594]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1594,
+ },
+ [0x1595]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1595,
+ },
+ [0x1596]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1596,
+ },
+ [0x1597]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1597,
+ },
+ [0x1598]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1598,
+ },
+ [0x1599]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1599,
+ },
+ [0x159A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x159A,
+ },
+ [0x159B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x159B,
+ },
+ [0x159C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x159C,
+ },
+ [0x159D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x159D,
+ },
+ [0x159E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x159E,
+ },
+ [0x159F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x159F,
+ },
+ [0x15A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A0,
+ },
+ [0x15A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A1,
+ },
+ [0x15A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A2,
+ },
+ [0x15A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A3,
+ },
+ [0x15A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A4,
+ },
+ [0x15A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A5,
+ },
+ [0x15A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A6,
+ },
+ [0x15A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A7,
+ },
+ [0x15A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A8,
+ },
+ [0x15A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A9,
+ },
+ [0x15AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15AA,
+ },
+ [0x15AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15AB,
+ },
+ [0x15AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15AC,
+ },
+ [0x15AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15AD,
+ },
+ [0x15AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15AE,
+ },
+ [0x15AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15AF,
+ },
+ [0x15B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B0,
+ },
+ [0x15B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B1,
+ },
+ [0x15B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B2,
+ },
+ [0x15B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B3,
+ },
+ [0x15B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B4,
+ },
+ [0x15B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B5,
+ },
+ [0x15B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B6,
+ },
+ [0x15B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B7,
+ },
+ [0x15B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B8,
+ },
+ [0x15B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B9,
+ },
+ [0x15BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15BA,
+ },
+ [0x15BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15BB,
+ },
+ [0x15BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15BC,
+ },
+ [0x15BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15BD,
+ },
+ [0x15BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15BE,
+ },
+ [0x15BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15BF,
+ },
+ [0x15C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C0,
+ },
+ [0x15C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C1,
+ },
+ [0x15C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C2,
+ },
+ [0x15C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C3,
+ },
+ [0x15C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C4,
+ },
+ [0x15C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C5,
+ },
+ [0x15C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C6,
+ },
+ [0x15C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C7,
+ },
+ [0x15C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C8,
+ },
+ [0x15C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C9,
+ },
+ [0x15CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15CA,
+ },
+ [0x15CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15CB,
+ },
+ [0x15CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15CC,
+ },
+ [0x15CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15CD,
+ },
+ [0x15CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15CE,
+ },
+ [0x15CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15CF,
+ },
+ [0x15D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D0,
+ },
+ [0x15D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D1,
+ },
+ [0x15D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D2,
+ },
+ [0x15D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D3,
+ },
+ [0x15D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D4,
+ },
+ [0x15D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D5,
+ },
+ [0x15D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D6,
+ },
+ [0x15D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D7,
+ },
+ [0x15D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D8,
+ },
+ [0x15D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D9,
+ },
+ [0x15DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15DA,
+ },
+ [0x15DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15DB,
+ },
+ [0x15DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15DC,
+ },
+ [0x15DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15DD,
+ },
+ [0x15DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15DE,
+ },
+ [0x15DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15DF,
+ },
+ [0x15E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E0,
+ },
+ [0x15E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E1,
+ },
+ [0x15E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E2,
+ },
+ [0x15E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E3,
+ },
+ [0x15E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E4,
+ },
+ [0x15E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E5,
+ },
+ [0x15E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E6,
+ },
+ [0x15E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E7,
+ },
+ [0x15E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E8,
+ },
+ [0x15E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E9,
+ },
+ [0x15EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15EA,
+ },
+ [0x15EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15EB,
+ },
+ [0x15EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15EC,
+ },
+ [0x15ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15ED,
+ },
+ [0x15EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15EE,
+ },
+ [0x15EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15EF,
+ },
+ [0x15F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F0,
+ },
+ [0x15F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F1,
+ },
+ [0x15F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F2,
+ },
+ [0x15F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F3,
+ },
+ [0x15F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F4,
+ },
+ [0x15F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F5,
+ },
+ [0x15F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F6,
+ },
+ [0x15F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F7,
+ },
+ [0x15F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F8,
+ },
+ [0x15F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F9,
+ },
+ [0x15FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15FA,
+ },
+ [0x15FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15FB,
+ },
+ [0x15FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15FC,
+ },
+ [0x15FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15FD,
+ },
+ [0x15FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15FE,
+ },
+ [0x15FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15FF,
+ },
+ [0x1600]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1600,
+ },
+ [0x1601]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1601,
+ },
+ [0x1602]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1602,
+ },
+ [0x1603]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1603,
+ },
+ [0x1604]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1604,
+ },
+ [0x1605]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1605,
+ },
+ [0x1606]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1606,
+ },
+ [0x1607]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1607,
+ },
+ [0x1608]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1608,
+ },
+ [0x1609]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1609,
+ },
+ [0x160A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x160A,
+ },
+ [0x160B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x160B,
+ },
+ [0x160C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x160C,
+ },
+ [0x160D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x160D,
+ },
+ [0x160E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x160E,
+ },
+ [0x160F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x160F,
+ },
+ [0x1610]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1610,
+ },
+ [0x1611]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1611,
+ },
+ [0x1612]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1612,
+ },
+ [0x1613]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1613,
+ },
+ [0x1614]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1614,
+ },
+ [0x1615]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1615,
+ },
+ [0x1616]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1616,
+ },
+ [0x1617]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1617,
+ },
+ [0x1618]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1618,
+ },
+ [0x1619]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1619,
+ },
+ [0x161A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x161A,
+ },
+ [0x161B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x161B,
+ },
+ [0x161C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x161C,
+ },
+ [0x161D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x161D,
+ },
+ [0x161E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x161E,
+ },
+ [0x161F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x161F,
+ },
+ [0x1620]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1620,
+ },
+ [0x1621]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1621,
+ },
+ [0x1622]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1622,
+ },
+ [0x1623]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1623,
+ },
+ [0x1624]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1624,
+ },
+ [0x1625]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1625,
+ },
+ [0x1626]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1626,
+ },
+ [0x1627]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1627,
+ },
+ [0x1628]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1628,
+ },
+ [0x1629]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1629,
+ },
+ [0x162A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x162A,
+ },
+ [0x162B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x162B,
+ },
+ [0x162C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x162C,
+ },
+ [0x162D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x162D,
+ },
+ [0x162E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x162E,
+ },
+ [0x162F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x162F,
+ },
+ [0x1630]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1630,
+ },
+ [0x1631]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1631,
+ },
+ [0x1632]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1632,
+ },
+ [0x1633]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1633,
+ },
+ [0x1634]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1634,
+ },
+ [0x1635]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1635,
+ },
+ [0x1636]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1636,
+ },
+ [0x1637]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1637,
+ },
+ [0x1638]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1638,
+ },
+ [0x1639]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1639,
+ },
+ [0x163A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x163A,
+ },
+ [0x163B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x163B,
+ },
+ [0x163C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x163C,
+ },
+ [0x163D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x163D,
+ },
+ [0x163E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x163E,
+ },
+ [0x163F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x163F,
+ },
+ [0x1640]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1640,
+ },
+ [0x1641]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1641,
+ },
+ [0x1642]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1642,
+ },
+ [0x1643]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1643,
+ },
+ [0x1644]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1644,
+ },
+ [0x1645]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1645,
+ },
+ [0x1646]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1646,
+ },
+ [0x1647]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1647,
+ },
+ [0x1648]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1648,
+ },
+ [0x1649]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1649,
+ },
+ [0x164A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x164A,
+ },
+ [0x164B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x164B,
+ },
+ [0x164C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x164C,
+ },
+ [0x164D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x164D,
+ },
+ [0x164E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x164E,
+ },
+ [0x164F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x164F,
+ },
+ [0x1650]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1650,
+ },
+ [0x1651]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1651,
+ },
+ [0x1652]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1652,
+ },
+ [0x1653]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1653,
+ },
+ [0x1654]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1654,
+ },
+ [0x1655]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1655,
+ },
+ [0x1656]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1656,
+ },
+ [0x1657]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1657,
+ },
+ [0x1658]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1658,
+ },
+ [0x1659]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1659,
+ },
+ [0x165A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x165A,
+ },
+ [0x165B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x165B,
+ },
+ [0x165C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x165C,
+ },
+ [0x165D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x165D,
+ },
+ [0x165E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x165E,
+ },
+ [0x165F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x165F,
+ },
+ [0x1660]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1660,
+ },
+ [0x1661]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1661,
+ },
+ [0x1662]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1662,
+ },
+ [0x1663]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1663,
+ },
+ [0x1664]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1664,
+ },
+ [0x1665]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1665,
+ },
+ [0x1666]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1666,
+ },
+ [0x1667]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1667,
+ },
+ [0x1668]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1668,
+ },
+ [0x1669]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1669,
+ },
+ [0x166A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166A,
+ },
+ [0x166B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166B,
+ },
+ [0x166C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166C,
+ },
+ [0x166D]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166D,
+ },
+ [0x166E]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166E,
+ },
+ [0x166F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166F,
+ },
+ [0x1670]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1670,
+ },
+ [0x1671]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1671,
+ },
+ [0x1672]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1672,
+ },
+ [0x1673]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1673,
+ },
+ [0x1674]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1674,
+ },
+ [0x1675]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1675,
+ },
+ [0x1676]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1676,
+ },
+ [0x1677]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1677,
+ },
+ [0x1678]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1678,
+ },
+ [0x1679]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1679,
+ },
+ [0x167A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167A,
+ },
+ [0x167B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167B,
+ },
+ [0x167C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167C,
+ },
+ [0x167D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167D,
+ },
+ [0x167E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167E,
+ },
+ [0x167F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167F,
+ },
+ [0x1680]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ unicodeslot=0x1680,
+ },
+ [0x1681]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681,
+ },
+ [0x1682]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682,
+ },
+ [0x1683]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683,
+ },
+ [0x1684]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684,
+ },
+ [0x1685]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685,
+ },
+ [0x1686]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686,
+ },
+ [0x1687]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687,
+ },
+ [0x1688]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688,
+ },
+ [0x1689]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689,
+ },
+ [0x168A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A,
+ },
+ [0x168B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B,
+ },
+ [0x168C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C,
+ },
+ [0x168D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D,
+ },
+ [0x168E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E,
+ },
+ [0x168F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F,
+ },
+ [0x1690]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690,
+ },
+ [0x1691]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691,
+ },
+ [0x1692]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692,
+ },
+ [0x1693]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693,
+ },
+ [0x1694]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694,
+ },
+ [0x1695]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695,
+ },
+ [0x1696]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696,
+ },
+ [0x1697]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697,
+ },
+ [0x1698]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698,
+ },
+ [0x1699]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699,
+ },
+ [0x169A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A,
+ },
+ [0x169B]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x169C,
+ unicodeslot=0x169B,
+ },
+ [0x169C]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x169B,
+ unicodeslot=0x169C,
+ },
+ [0x16A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0,
+ },
+ [0x16A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1,
+ },
+ [0x16A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2,
+ },
+ [0x16A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A3,
+ },
+ [0x16A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A4,
+ },
+ [0x16A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A5,
+ },
+ [0x16A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A6,
+ },
+ [0x16A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A7,
+ },
+ [0x16A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A8,
+ },
+ [0x16A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A9,
+ },
+ [0x16AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AA,
+ },
+ [0x16AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AB,
+ },
+ [0x16AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AC,
+ },
+ [0x16AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AD,
+ },
+ [0x16AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AE,
+ },
+ [0x16AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AF,
+ },
+ [0x16B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B0,
+ },
+ [0x16B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B1,
+ },
+ [0x16B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B2,
+ },
+ [0x16B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B3,
+ },
+ [0x16B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B4,
+ },
+ [0x16B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B5,
+ },
+ [0x16B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B6,
+ },
+ [0x16B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B7,
+ },
+ [0x16B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B8,
+ },
+ [0x16B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B9,
+ },
+ [0x16BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16BA,
+ },
+ [0x16BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16BB,
+ },
+ [0x16BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16BC,
+ },
+ [0x16BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16BD,
+ },
+ [0x16BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16BE,
+ },
+ [0x16BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16BF,
+ },
+ [0x16C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C0,
+ },
+ [0x16C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C1,
+ },
+ [0x16C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C2,
+ },
+ [0x16C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C3,
+ },
+ [0x16C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C4,
+ },
+ [0x16C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C5,
+ },
+ [0x16C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C6,
+ },
+ [0x16C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C7,
+ },
+ [0x16C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C8,
+ },
+ [0x16C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C9,
+ },
+ [0x16CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16CA,
+ },
+ [0x16CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16CB,
+ },
+ [0x16CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16CC,
+ },
+ [0x16CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16CD,
+ },
+ [0x16CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16CE,
+ },
+ [0x16CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16CF,
+ },
+ [0x16D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D0,
+ },
+ [0x16D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D1,
+ },
+ [0x16D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D2,
+ },
+ [0x16D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D3,
+ },
+ [0x16D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D4,
+ },
+ [0x16D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D5,
+ },
+ [0x16D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D6,
+ },
+ [0x16D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D7,
+ },
+ [0x16D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D8,
+ },
+ [0x16D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D9,
+ },
+ [0x16DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16DA,
+ },
+ [0x16DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16DB,
+ },
+ [0x16DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16DC,
+ },
+ [0x16DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16DD,
+ },
+ [0x16DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16DE,
+ },
+ [0x16DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16DF,
+ },
+ [0x16E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E0,
+ },
+ [0x16E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E1,
+ },
+ [0x16E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E2,
+ },
+ [0x16E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E3,
+ },
+ [0x16E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E4,
+ },
+ [0x16E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E5,
+ },
+ [0x16E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E6,
+ },
+ [0x16E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E7,
+ },
+ [0x16E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E8,
+ },
+ [0x16E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E9,
+ },
+ [0x16EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16EA,
+ },
+ [0x16EB]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16EB,
+ },
+ [0x16EC]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16EC,
+ },
+ [0x16ED]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16ED,
+ },
+ [0x16EE]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16EE,
+ },
+ [0x16EF]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16EF,
+ },
+ [0x16F0]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0,
+ },
+ [0x16F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1,
+ },
+ [0x16F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2,
+ },
+ [0x16F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3,
+ },
+ [0x16F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F4,
+ },
+ [0x16F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F5,
+ },
+ [0x16F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F6,
+ },
+ [0x16F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F7,
+ },
+ [0x16F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F8,
+ },
+ [0x1700]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1700,
+ },
+ [0x1701]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1701,
+ },
+ [0x1702]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1702,
+ },
+ [0x1703]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1703,
+ },
+ [0x1704]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1704,
+ },
+ [0x1705]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1705,
+ },
+ [0x1706]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1706,
+ },
+ [0x1707]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1707,
+ },
+ [0x1708]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1708,
+ },
+ [0x1709]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1709,
+ },
+ [0x170A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x170A,
+ },
+ [0x170B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x170B,
+ },
+ [0x170C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x170C,
+ },
+ [0x170E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x170E,
+ },
+ [0x170F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x170F,
+ },
+ [0x1710]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1710,
+ },
+ [0x1711]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1711,
+ },
+ [0x1712]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1712,
+ },
+ [0x1713]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1713,
+ },
+ [0x1714]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1714,
+ },
+ [0x1720]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1720,
+ },
+ [0x1721]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1721,
+ },
+ [0x1722]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1722,
+ },
+ [0x1723]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1723,
+ },
+ [0x1724]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1724,
+ },
+ [0x1725]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1725,
+ },
+ [0x1726]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1726,
+ },
+ [0x1727]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1727,
+ },
+ [0x1728]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1728,
+ },
+ [0x1729]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1729,
+ },
+ [0x172A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x172A,
+ },
+ [0x172B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x172B,
+ },
+ [0x172C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x172C,
+ },
+ [0x172D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x172D,
+ },
+ [0x172E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x172E,
+ },
+ [0x172F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x172F,
+ },
+ [0x1730]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1730,
+ },
+ [0x1731]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1731,
+ },
+ [0x1732]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1732,
+ },
+ [0x1733]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1733,
+ },
+ [0x1734]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1734,
+ },
+ [0x1735]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1735,
+ },
+ [0x1736]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1736,
+ },
+ [0x1740]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1740,
+ },
+ [0x1741]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1741,
+ },
+ [0x1742]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1742,
+ },
+ [0x1743]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1743,
+ },
+ [0x1744]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1744,
+ },
+ [0x1745]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1745,
+ },
+ [0x1746]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1746,
+ },
+ [0x1747]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1747,
+ },
+ [0x1748]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1748,
+ },
+ [0x1749]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1749,
+ },
+ [0x174A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x174A,
+ },
+ [0x174B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x174B,
+ },
+ [0x174C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x174C,
+ },
+ [0x174D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x174D,
+ },
+ [0x174E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x174E,
+ },
+ [0x174F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x174F,
+ },
+ [0x1750]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1750,
+ },
+ [0x1751]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1751,
+ },
+ [0x1752]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1752,
+ },
+ [0x1753]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1753,
+ },
+ [0x1760]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1760,
+ },
+ [0x1761]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1761,
+ },
+ [0x1762]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1762,
+ },
+ [0x1763]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1763,
+ },
+ [0x1764]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1764,
+ },
+ [0x1765]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1765,
+ },
+ [0x1766]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1766,
+ },
+ [0x1767]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1767,
+ },
+ [0x1768]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1768,
+ },
+ [0x1769]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1769,
+ },
+ [0x176A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x176A,
+ },
+ [0x176B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x176B,
+ },
+ [0x176C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x176C,
+ },
+ [0x176E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x176E,
+ },
+ [0x176F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x176F,
+ },
+ [0x1770]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1770,
+ },
+ [0x1772]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1772,
+ },
+ [0x1773]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1773,
+ },
+ [0x1780]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1780,
+ },
+ [0x1781]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1781,
+ },
+ [0x1782]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1782,
+ },
+ [0x1783]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1783,
+ },
+ [0x1784]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1784,
+ },
+ [0x1785]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1785,
+ },
+ [0x1786]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1786,
+ },
+ [0x1787]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1787,
+ },
+ [0x1788]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1788,
+ },
+ [0x1789]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1789,
+ },
+ [0x178A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x178A,
+ },
+ [0x178B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x178B,
+ },
+ [0x178C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x178C,
+ },
+ [0x178D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x178D,
+ },
+ [0x178E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x178E,
+ },
+ [0x178F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x178F,
+ },
+ [0x1790]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1790,
+ },
+ [0x1791]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1791,
+ },
+ [0x1792]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1792,
+ },
+ [0x1793]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1793,
+ },
+ [0x1794]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1794,
+ },
+ [0x1795]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1795,
+ },
+ [0x1796]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1796,
+ },
+ [0x1797]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1797,
+ },
+ [0x1798]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1798,
+ },
+ [0x1799]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1799,
+ },
+ [0x179A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x179A,
+ },
+ [0x179B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x179B,
+ },
+ [0x179C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x179C,
+ },
+ [0x179D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x179D,
+ },
+ [0x179E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x179E,
+ },
+ [0x179F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x179F,
+ },
+ [0x17A0]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A0,
+ },
+ [0x17A1]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A1,
+ },
+ [0x17A2]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A2,
+ },
+ [0x17A3]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A3,
+ },
+ [0x17A4]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A4,
+ },
+ [0x17A5]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A5,
+ },
+ [0x17A6]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A6,
+ },
+ [0x17A7]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A7,
+ },
+ [0x17A8]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A8,
+ },
+ [0x17A9]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A9,
+ },
+ [0x17AA]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17AA,
+ },
+ [0x17AB]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17AB,
+ },
+ [0x17AC]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17AC,
+ },
+ [0x17AD]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17AD,
+ },
+ [0x17AE]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17AE,
+ },
+ [0x17AF]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17AF,
+ },
+ [0x17B0]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17B0,
+ },
+ [0x17B1]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17B1,
+ },
+ [0x17B2]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17B2,
+ },
+ [0x17B3]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17B3,
+ },
+ [0x17B4]={
+ category="cf",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17B4,
+ },
+ [0x17B5]={
+ category="cf",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17B5,
+ },
+ [0x17B6]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17B6,
+ },
+ [0x17B7]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17B7,
+ },
+ [0x17B8]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17B8,
+ },
+ [0x17B9]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17B9,
+ },
+ [0x17BA]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17BA,
+ },
+ [0x17BB]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17BB,
+ },
+ [0x17BC]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17BC,
+ },
+ [0x17BD]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17BD,
+ },
+ [0x17BE]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17BE,
+ },
+ [0x17BF]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17BF,
+ },
+ [0x17C0]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C0,
+ },
+ [0x17C1]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C1,
+ },
+ [0x17C2]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C2,
+ },
+ [0x17C3]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C3,
+ },
+ [0x17C4]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C4,
+ },
+ [0x17C5]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C5,
+ },
+ [0x17C6]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17C6,
+ },
+ [0x17C7]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C7,
+ },
+ [0x17C8]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C8,
+ },
+ [0x17C9]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17C9,
+ },
+ [0x17CA]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17CA,
+ },
+ [0x17CB]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17CB,
+ },
+ [0x17CC]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17CC,
+ },
+ [0x17CD]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17CD,
+ },
+ [0x17CE]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17CE,
+ },
+ [0x17CF]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17CF,
+ },
+ [0x17D0]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17D0,
+ },
+ [0x17D1]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17D1,
+ },
+ [0x17D2]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17D2,
+ },
+ [0x17D3]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17D3,
+ },
+ [0x17D4]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x17D4,
+ },
+ [0x17D5]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x17D5,
+ },
+ [0x17D6]={
+ category="po",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x17D6,
+ },
+ [0x17D7]={
+ category="lm",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17D7,
+ },
+ [0x17D8]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x17D8,
+ },
+ [0x17D9]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x17D9,
+ },
+ [0x17DA]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x17DA,
+ },
+ [0x17DB]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x17DB,
+ },
+ [0x17DC]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17DC,
+ },
+ [0x17DD]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17DD,
+ },
+ [0x17E0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E0,
+ },
+ [0x17E1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E1,
+ },
+ [0x17E2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E2,
+ },
+ [0x17E3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E3,
+ },
+ [0x17E4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E4,
+ },
+ [0x17E5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E5,
+ },
+ [0x17E6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E6,
+ },
+ [0x17E7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E7,
+ },
+ [0x17E8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E8,
+ },
+ [0x17E9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E9,
+ },
+ [0x17F0]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F0,
+ },
+ [0x17F1]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F1,
+ },
+ [0x17F2]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F2,
+ },
+ [0x17F3]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F3,
+ },
+ [0x17F4]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F4,
+ },
+ [0x17F5]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F5,
+ },
+ [0x17F6]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F6,
+ },
+ [0x17F7]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F7,
+ },
+ [0x17F8]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F8,
+ },
+ [0x17F9]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F9,
+ },
+ [0x1800]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1800,
+ },
+ [0x1801]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1801,
+ },
+ [0x1802]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x1802,
+ },
+ [0x1803]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x1803,
+ },
+ [0x1804]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x1804,
+ },
+ [0x1805]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x1805,
+ },
+ [0x1806]={
+ category="pd",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x1806,
+ },
+ [0x1807]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1807,
+ },
+ [0x1808]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x1808,
+ },
+ [0x1809]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x1809,
+ },
+ [0x180A]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x180A,
+ },
+ [0x180B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x180B,
+ },
+ [0x180C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x180C,
+ },
+ [0x180D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x180D,
+ },
+ [0x180E]={
+ category="zs",
+ direction="bn",
+ linebreak="gl",
+ unicodeslot=0x180E,
+ },
+ [0x1810]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1810,
+ },
+ [0x1811]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1811,
+ },
+ [0x1812]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1812,
+ },
+ [0x1813]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1813,
+ },
+ [0x1814]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1814,
+ },
+ [0x1815]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1815,
+ },
+ [0x1816]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1816,
+ },
+ [0x1817]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1817,
+ },
+ [0x1818]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1818,
+ },
+ [0x1819]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1819,
+ },
+ [0x1820]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1820,
+ },
+ [0x1821]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1821,
+ },
+ [0x1822]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1822,
+ },
+ [0x1823]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1823,
+ },
+ [0x1824]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1824,
+ },
+ [0x1825]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1825,
+ },
+ [0x1826]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1826,
+ },
+ [0x1827]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1827,
+ },
+ [0x1828]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1828,
+ },
+ [0x1829]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1829,
+ },
+ [0x182A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182A,
+ },
+ [0x182B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182B,
+ },
+ [0x182C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182C,
+ },
+ [0x182D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182D,
+ },
+ [0x182E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182E,
+ },
+ [0x182F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182F,
+ },
+ [0x1830]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1830,
+ },
+ [0x1831]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1831,
+ },
+ [0x1832]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1832,
+ },
+ [0x1833]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1833,
+ },
+ [0x1834]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1834,
+ },
+ [0x1835]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1835,
+ },
+ [0x1836]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1836,
+ },
+ [0x1837]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1837,
+ },
+ [0x1838]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1838,
+ },
+ [0x1839]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1839,
+ },
+ [0x183A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183A,
+ },
+ [0x183B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183B,
+ },
+ [0x183C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183C,
+ },
+ [0x183D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183D,
+ },
+ [0x183E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183E,
+ },
+ [0x183F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183F,
+ },
+ [0x1840]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1840,
+ },
+ [0x1841]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1841,
+ },
+ [0x1842]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1842,
+ },
+ [0x1843]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1843,
+ },
+ [0x1844]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1844,
+ },
+ [0x1845]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1845,
+ },
+ [0x1846]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1846,
+ },
+ [0x1847]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1847,
+ },
+ [0x1848]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1848,
+ },
+ [0x1849]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1849,
+ },
+ [0x184A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184A,
+ },
+ [0x184B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184B,
+ },
+ [0x184C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184C,
+ },
+ [0x184D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184D,
+ },
+ [0x184E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184E,
+ },
+ [0x184F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184F,
+ },
+ [0x1850]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1850,
+ },
+ [0x1851]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1851,
+ },
+ [0x1852]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1852,
+ },
+ [0x1853]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1853,
+ },
+ [0x1854]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1854,
+ },
+ [0x1855]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1855,
+ },
+ [0x1856]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1856,
+ },
+ [0x1857]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1857,
+ },
+ [0x1858]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1858,
+ },
+ [0x1859]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1859,
+ },
+ [0x185A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185A,
+ },
+ [0x185B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185B,
+ },
+ [0x185C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185C,
+ },
+ [0x185D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185D,
+ },
+ [0x185E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185E,
+ },
+ [0x185F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185F,
+ },
+ [0x1860]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1860,
+ },
+ [0x1861]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1861,
+ },
+ [0x1862]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1862,
+ },
+ [0x1863]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1863,
+ },
+ [0x1864]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1864,
+ },
+ [0x1865]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1865,
+ },
+ [0x1866]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1866,
+ },
+ [0x1867]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1867,
+ },
+ [0x1868]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1868,
+ },
+ [0x1869]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1869,
+ },
+ [0x186A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186A,
+ },
+ [0x186B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186B,
+ },
+ [0x186C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186C,
+ },
+ [0x186D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186D,
+ },
+ [0x186E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186E,
+ },
+ [0x186F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186F,
+ },
+ [0x1870]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1870,
+ },
+ [0x1871]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1871,
+ },
+ [0x1872]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1872,
+ },
+ [0x1873]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1873,
+ },
+ [0x1874]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1874,
+ },
+ [0x1875]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1875,
+ },
+ [0x1876]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1876,
+ },
+ [0x1877]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1877,
+ },
+ [0x1878]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1878,
+ },
+ [0x1880]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1880,
+ },
+ [0x1881]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1881,
+ },
+ [0x1882]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1882,
+ },
+ [0x1883]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1883,
+ },
+ [0x1884]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1884,
+ },
+ [0x1885]={
+ category="lo",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1885,
+ },
+ [0x1886]={
+ category="lo",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1886,
+ },
+ [0x1887]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1887,
+ },
+ [0x1888]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1888,
+ },
+ [0x1889]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1889,
+ },
+ [0x188A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188A,
+ },
+ [0x188B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188B,
+ },
+ [0x188C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188C,
+ },
+ [0x188D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188D,
+ },
+ [0x188E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188E,
+ },
+ [0x188F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188F,
+ },
+ [0x1890]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1890,
+ },
+ [0x1891]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1891,
+ },
+ [0x1892]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1892,
+ },
+ [0x1893]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1893,
+ },
+ [0x1894]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1894,
+ },
+ [0x1895]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1895,
+ },
+ [0x1896]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1896,
+ },
+ [0x1897]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1897,
+ },
+ [0x1898]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1898,
+ },
+ [0x1899]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1899,
+ },
+ [0x189A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189A,
+ },
+ [0x189B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189B,
+ },
+ [0x189C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189C,
+ },
+ [0x189D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189D,
+ },
+ [0x189E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189E,
+ },
+ [0x189F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189F,
+ },
+ [0x18A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A0,
+ },
+ [0x18A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A1,
+ },
+ [0x18A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A2,
+ },
+ [0x18A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A3,
+ },
+ [0x18A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A4,
+ },
+ [0x18A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A5,
+ },
+ [0x18A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A6,
+ },
+ [0x18A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A7,
+ },
+ [0x18A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A8,
+ },
+ [0x18A9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x18A9,
+ },
+ [0x18AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18AA,
+ },
+ [0x18B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B0,
+ },
+ [0x18B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B1,
+ },
+ [0x18B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B2,
+ },
+ [0x18B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B3,
+ },
+ [0x18B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B4,
+ },
+ [0x18B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B5,
+ },
+ [0x18B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B6,
+ },
+ [0x18B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B7,
+ },
+ [0x18B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B8,
+ },
+ [0x18B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B9,
+ },
+ [0x18BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BA,
+ },
+ [0x18BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BB,
+ },
+ [0x18BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BC,
+ },
+ [0x18BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BD,
+ },
+ [0x18BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BE,
+ },
+ [0x18BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BF,
+ },
+ [0x18C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C0,
+ },
+ [0x18C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C1,
+ },
+ [0x18C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C2,
+ },
+ [0x18C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C3,
+ },
+ [0x18C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C4,
+ },
+ [0x18C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C5,
+ },
+ [0x18C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C6,
+ },
+ [0x18C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C7,
+ },
+ [0x18C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C8,
+ },
+ [0x18C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C9,
+ },
+ [0x18CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CA,
+ },
+ [0x18CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CB,
+ },
+ [0x18CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CC,
+ },
+ [0x18CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CD,
+ },
+ [0x18CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CE,
+ },
+ [0x18CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CF,
+ },
+ [0x18D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D0,
+ },
+ [0x18D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D1,
+ },
+ [0x18D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D2,
+ },
+ [0x18D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D3,
+ },
+ [0x18D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D4,
+ },
+ [0x18D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D5,
+ },
+ [0x18D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D6,
+ },
+ [0x18D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D7,
+ },
+ [0x18D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D8,
+ },
+ [0x18D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D9,
+ },
+ [0x18DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18DA,
+ },
+ [0x18DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18DB,
+ },
+ [0x18DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18DC,
+ },
+ [0x18DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18DD,
+ },
+ [0x18DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18DE,
+ },
+ [0x18DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18DF,
+ },
+ [0x18E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E0,
+ },
+ [0x18E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E1,
+ },
+ [0x18E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E2,
+ },
+ [0x18E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E3,
+ },
+ [0x18E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E4,
+ },
+ [0x18E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E5,
+ },
+ [0x18E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E6,
+ },
+ [0x18E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E7,
+ },
+ [0x18E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E8,
+ },
+ [0x18E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E9,
+ },
+ [0x18EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18EA,
+ },
+ [0x18EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18EB,
+ },
+ [0x18EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18EC,
+ },
+ [0x18ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18ED,
+ },
+ [0x18EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18EE,
+ },
+ [0x18EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18EF,
+ },
+ [0x18F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F0,
+ },
+ [0x18F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F1,
+ },
+ [0x18F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F2,
+ },
+ [0x18F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F3,
+ },
+ [0x18F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F4,
+ },
+ [0x18F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F5,
+ },
+ [0x1900]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1900,
+ },
+ [0x1901]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1901,
+ },
+ [0x1902]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1902,
+ },
+ [0x1903]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1903,
+ },
+ [0x1904]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1904,
+ },
+ [0x1905]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1905,
+ },
+ [0x1906]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1906,
+ },
+ [0x1907]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1907,
+ },
+ [0x1908]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1908,
+ },
+ [0x1909]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1909,
+ },
+ [0x190A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190A,
+ },
+ [0x190B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190B,
+ },
+ [0x190C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190C,
+ },
+ [0x190D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190D,
+ },
+ [0x190E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190E,
+ },
+ [0x190F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190F,
+ },
+ [0x1910]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1910,
+ },
+ [0x1911]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1911,
+ },
+ [0x1912]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1912,
+ },
+ [0x1913]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1913,
+ },
+ [0x1914]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1914,
+ },
+ [0x1915]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1915,
+ },
+ [0x1916]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1916,
+ },
+ [0x1917]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1917,
+ },
+ [0x1918]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1918,
+ },
+ [0x1919]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1919,
+ },
+ [0x191A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x191A,
+ },
+ [0x191B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x191B,
+ },
+ [0x191C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x191C,
+ },
+ [0x191D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x191D,
+ },
+ [0x191E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x191E,
+ },
+ [0x1920]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1920,
+ },
+ [0x1921]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1921,
+ },
+ [0x1922]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1922,
+ },
+ [0x1923]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1923,
+ },
+ [0x1924]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1924,
+ },
+ [0x1925]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1925,
+ },
+ [0x1926]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1926,
+ },
+ [0x1927]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1927,
+ },
+ [0x1928]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1928,
+ },
+ [0x1929]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1929,
+ },
+ [0x192A]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x192A,
+ },
+ [0x192B]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x192B,
+ },
+ [0x1930]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1930,
+ },
+ [0x1931]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1931,
+ },
+ [0x1932]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1932,
+ },
+ [0x1933]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1933,
+ },
+ [0x1934]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1934,
+ },
+ [0x1935]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1935,
+ },
+ [0x1936]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1936,
+ },
+ [0x1937]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1937,
+ },
+ [0x1938]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1938,
+ },
+ [0x1939]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1939,
+ },
+ [0x193A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x193A,
+ },
+ [0x193B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x193B,
+ },
+ [0x1940]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1940,
+ },
+ [0x1944]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x1944,
+ },
+ [0x1945]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x1945,
+ },
+ [0x1946]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1946,
+ },
+ [0x1947]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1947,
+ },
+ [0x1948]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1948,
+ },
+ [0x1949]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1949,
+ },
+ [0x194A]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x194A,
+ },
+ [0x194B]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x194B,
+ },
+ [0x194C]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x194C,
+ },
+ [0x194D]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x194D,
+ },
+ [0x194E]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x194E,
+ },
+ [0x194F]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x194F,
+ },
+ [0x1950]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1950,
+ },
+ [0x1951]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1951,
+ },
+ [0x1952]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1952,
+ },
+ [0x1953]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1953,
+ },
+ [0x1954]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1954,
+ },
+ [0x1955]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1955,
+ },
+ [0x1956]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1956,
+ },
+ [0x1957]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1957,
+ },
+ [0x1958]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1958,
+ },
+ [0x1959]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1959,
+ },
+ [0x195A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x195A,
+ },
+ [0x195B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x195B,
+ },
+ [0x195C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x195C,
+ },
+ [0x195D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x195D,
+ },
+ [0x195E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x195E,
+ },
+ [0x195F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x195F,
+ },
+ [0x1960]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1960,
+ },
+ [0x1961]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1961,
+ },
+ [0x1962]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1962,
+ },
+ [0x1963]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1963,
+ },
+ [0x1964]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1964,
+ },
+ [0x1965]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1965,
+ },
+ [0x1966]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1966,
+ },
+ [0x1967]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1967,
+ },
+ [0x1968]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1968,
+ },
+ [0x1969]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1969,
+ },
+ [0x196A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x196A,
+ },
+ [0x196B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x196B,
+ },
+ [0x196C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x196C,
+ },
+ [0x196D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x196D,
+ },
+ [0x1970]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1970,
+ },
+ [0x1971]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1971,
+ },
+ [0x1972]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1972,
+ },
+ [0x1973]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1973,
+ },
+ [0x1974]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1974,
+ },
+ [0x1980]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1980,
+ },
+ [0x1981]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1981,
+ },
+ [0x1982]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1982,
+ },
+ [0x1983]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1983,
+ },
+ [0x1984]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1984,
+ },
+ [0x1985]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1985,
+ },
+ [0x1986]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1986,
+ },
+ [0x1987]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1987,
+ },
+ [0x1988]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1988,
+ },
+ [0x1989]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1989,
+ },
+ [0x198A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x198A,
+ },
+ [0x198B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x198B,
+ },
+ [0x198C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x198C,
+ },
+ [0x198D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x198D,
+ },
+ [0x198E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x198E,
+ },
+ [0x198F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x198F,
+ },
+ [0x1990]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1990,
+ },
+ [0x1991]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1991,
+ },
+ [0x1992]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1992,
+ },
+ [0x1993]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1993,
+ },
+ [0x1994]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1994,
+ },
+ [0x1995]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1995,
+ },
+ [0x1996]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1996,
+ },
+ [0x1997]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1997,
+ },
+ [0x1998]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1998,
+ },
+ [0x1999]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1999,
+ },
+ [0x199A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x199A,
+ },
+ [0x199B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x199B,
+ },
+ [0x199C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x199C,
+ },
+ [0x199D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x199D,
+ },
+ [0x199E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x199E,
+ },
+ [0x199F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x199F,
+ },
+ [0x19A0]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A0,
+ },
+ [0x19A1]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A1,
+ },
+ [0x19A2]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A2,
+ },
+ [0x19A3]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A3,
+ },
+ [0x19A4]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A4,
+ },
+ [0x19A5]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A5,
+ },
+ [0x19A6]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A6,
+ },
+ [0x19A7]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A7,
+ },
+ [0x19A8]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A8,
+ },
+ [0x19A9]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A9,
+ },
+ [0x19AA]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19AA,
+ },
+ [0x19AB]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19AB,
+ },
+ [0x19B0]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B0,
+ },
+ [0x19B1]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B1,
+ },
+ [0x19B2]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B2,
+ },
+ [0x19B3]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B3,
+ },
+ [0x19B4]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B4,
+ },
+ [0x19B5]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B5,
+ },
+ [0x19B6]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B6,
+ },
+ [0x19B7]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B7,
+ },
+ [0x19B8]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B8,
+ },
+ [0x19B9]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B9,
+ },
+ [0x19BA]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19BA,
+ },
+ [0x19BB]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19BB,
+ },
+ [0x19BC]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19BC,
+ },
+ [0x19BD]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19BD,
+ },
+ [0x19BE]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19BE,
+ },
+ [0x19BF]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19BF,
+ },
+ [0x19C0]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C0,
+ },
+ [0x19C1]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C1,
+ },
+ [0x19C2]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C2,
+ },
+ [0x19C3]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C3,
+ },
+ [0x19C4]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C4,
+ },
+ [0x19C5]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C5,
+ },
+ [0x19C6]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C6,
+ },
+ [0x19C7]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C7,
+ },
+ [0x19C8]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C8,
+ },
+ [0x19C9]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C9,
+ },
+ [0x19D0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D0,
+ },
+ [0x19D1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D1,
+ },
+ [0x19D2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D2,
+ },
+ [0x19D3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D3,
+ },
+ [0x19D4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D4,
+ },
+ [0x19D5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D5,
+ },
+ [0x19D6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D6,
+ },
+ [0x19D7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D7,
+ },
+ [0x19D8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D8,
+ },
+ [0x19D9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D9,
+ },
+ [0x19DA]={
+ category="no",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19DA,
+ },
+ [0x19DE]={
+ category="po",
+ direction="on",
+ linebreak="sa",
+ unicodeslot=0x19DE,
+ },
+ [0x19DF]={
+ category="po",
+ direction="on",
+ linebreak="sa",
+ unicodeslot=0x19DF,
+ },
+ [0x19E0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E0,
+ },
+ [0x19E1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E1,
+ },
+ [0x19E2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E2,
+ },
+ [0x19E3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E3,
+ },
+ [0x19E4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E4,
+ },
+ [0x19E5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E5,
+ },
+ [0x19E6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E6,
+ },
+ [0x19E7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E7,
+ },
+ [0x19E8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E8,
+ },
+ [0x19E9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E9,
+ },
+ [0x19EA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19EA,
+ },
+ [0x19EB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19EB,
+ },
+ [0x19EC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19EC,
+ },
+ [0x19ED]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19ED,
+ },
+ [0x19EE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19EE,
+ },
+ [0x19EF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19EF,
+ },
+ [0x19F0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F0,
+ },
+ [0x19F1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F1,
+ },
+ [0x19F2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F2,
+ },
+ [0x19F3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F3,
+ },
+ [0x19F4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F4,
+ },
+ [0x19F5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F5,
+ },
+ [0x19F6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F6,
+ },
+ [0x19F7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F7,
+ },
+ [0x19F8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F8,
+ },
+ [0x19F9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F9,
+ },
+ [0x19FA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19FA,
+ },
+ [0x19FB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19FB,
+ },
+ [0x19FC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19FC,
+ },
+ [0x19FD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19FD,
+ },
+ [0x19FE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19FE,
+ },
+ [0x19FF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19FF,
+ },
+ [0x1A00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A00,
+ },
+ [0x1A01]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A01,
+ },
+ [0x1A02]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A02,
+ },
+ [0x1A03]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A03,
+ },
+ [0x1A04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A04,
+ },
+ [0x1A05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A05,
+ },
+ [0x1A06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A06,
+ },
+ [0x1A07]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A07,
+ },
+ [0x1A08]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A08,
+ },
+ [0x1A09]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A09,
+ },
+ [0x1A0A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A0A,
+ },
+ [0x1A0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A0B,
+ },
+ [0x1A0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A0C,
+ },
+ [0x1A0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A0D,
+ },
+ [0x1A0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A0E,
+ },
+ [0x1A0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A0F,
+ },
+ [0x1A10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A10,
+ },
+ [0x1A11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A11,
+ },
+ [0x1A12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A12,
+ },
+ [0x1A13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A13,
+ },
+ [0x1A14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A14,
+ },
+ [0x1A15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A15,
+ },
+ [0x1A16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A16,
+ },
+ [0x1A17]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1A17,
+ },
+ [0x1A18]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1A18,
+ },
+ [0x1A19]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1A19,
+ },
+ [0x1A1A]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1A1A,
+ },
+ [0x1A1B]={
+ category="mc",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1A1B,
+ },
+ [0x1A1E]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A1E,
+ },
+ [0x1A1F]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A1F,
+ },
+ [0x1A20]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A20,
+ },
+ [0x1A21]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A21,
+ },
+ [0x1A22]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A22,
+ },
+ [0x1A23]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A23,
+ },
+ [0x1A24]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A24,
+ },
+ [0x1A25]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A25,
+ },
+ [0x1A26]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A26,
+ },
+ [0x1A27]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A27,
+ },
+ [0x1A28]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A28,
+ },
+ [0x1A29]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A29,
+ },
+ [0x1A2A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A2A,
+ },
+ [0x1A2B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A2B,
+ },
+ [0x1A2C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A2C,
+ },
+ [0x1A2D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A2D,
+ },
+ [0x1A2E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A2E,
+ },
+ [0x1A2F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A2F,
+ },
+ [0x1A30]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A30,
+ },
+ [0x1A31]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A31,
+ },
+ [0x1A32]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A32,
+ },
+ [0x1A33]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A33,
+ },
+ [0x1A34]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A34,
+ },
+ [0x1A35]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A35,
+ },
+ [0x1A36]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A36,
+ },
+ [0x1A37]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A37,
+ },
+ [0x1A38]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A38,
+ },
+ [0x1A39]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A39,
+ },
+ [0x1A3A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A3A,
+ },
+ [0x1A3B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A3B,
+ },
+ [0x1A3C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A3C,
+ },
+ [0x1A3D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A3D,
+ },
+ [0x1A3E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A3E,
+ },
+ [0x1A3F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A3F,
+ },
+ [0x1A40]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A40,
+ },
+ [0x1A41]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A41,
+ },
+ [0x1A42]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A42,
+ },
+ [0x1A43]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A43,
+ },
+ [0x1A44]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A44,
+ },
+ [0x1A45]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A45,
+ },
+ [0x1A46]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A46,
+ },
+ [0x1A47]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A47,
+ },
+ [0x1A48]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A48,
+ },
+ [0x1A49]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A49,
+ },
+ [0x1A4A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A4A,
+ },
+ [0x1A4B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A4B,
+ },
+ [0x1A4C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A4C,
+ },
+ [0x1A4D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A4D,
+ },
+ [0x1A4E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A4E,
+ },
+ [0x1A4F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A4F,
+ },
+ [0x1A50]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A50,
+ },
+ [0x1A51]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A51,
+ },
+ [0x1A52]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A52,
+ },
+ [0x1A53]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A53,
+ },
+ [0x1A54]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A54,
+ },
+ [0x1A55]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A55,
+ },
+ [0x1A56]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A56,
+ },
+ [0x1A57]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A57,
+ },
+ [0x1A58]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A58,
+ },
+ [0x1A59]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A59,
+ },
+ [0x1A5A]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A5A,
+ },
+ [0x1A5B]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A5B,
+ },
+ [0x1A5C]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A5C,
+ },
+ [0x1A5D]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A5D,
+ },
+ [0x1A5E]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A5E,
+ },
+ [0x1A60]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A60,
+ },
+ [0x1A61]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A61,
+ },
+ [0x1A62]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A62,
+ },
+ [0x1A63]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A63,
+ },
+ [0x1A64]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A64,
+ },
+ [0x1A65]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A65,
+ },
+ [0x1A66]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A66,
+ },
+ [0x1A67]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A67,
+ },
+ [0x1A68]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A68,
+ },
+ [0x1A69]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A69,
+ },
+ [0x1A6A]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A6A,
+ },
+ [0x1A6B]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A6B,
+ },
+ [0x1A6C]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A6C,
+ },
+ [0x1A6D]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A6D,
+ },
+ [0x1A6E]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A6E,
+ },
+ [0x1A6F]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A6F,
+ },
+ [0x1A70]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A70,
+ },
+ [0x1A71]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A71,
+ },
+ [0x1A72]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A72,
+ },
+ [0x1A73]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A73,
+ },
+ [0x1A74]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A74,
+ },
+ [0x1A75]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A75,
+ },
+ [0x1A76]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A76,
+ },
+ [0x1A77]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A77,
+ },
+ [0x1A78]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A78,
+ },
+ [0x1A79]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A79,
+ },
+ [0x1A7A]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A7A,
+ },
+ [0x1A7B]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A7B,
+ },
+ [0x1A7C]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A7C,
+ },
+ [0x1A7F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1A7F,
+ },
+ [0x1A80]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A80,
+ },
+ [0x1A81]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A81,
+ },
+ [0x1A82]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A82,
+ },
+ [0x1A83]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A83,
+ },
+ [0x1A84]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A84,
+ },
+ [0x1A85]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A85,
+ },
+ [0x1A86]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A86,
+ },
+ [0x1A87]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A87,
+ },
+ [0x1A88]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A88,
+ },
+ [0x1A89]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A89,
+ },
+ [0x1A90]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A90,
+ },
+ [0x1A91]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A91,
+ },
+ [0x1A92]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A92,
+ },
+ [0x1A93]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A93,
+ },
+ [0x1A94]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A94,
+ },
+ [0x1A95]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A95,
+ },
+ [0x1A96]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A96,
+ },
+ [0x1A97]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A97,
+ },
+ [0x1A98]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A98,
+ },
+ [0x1A99]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A99,
+ },
+ [0x1AA0]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA0,
+ },
+ [0x1AA1]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA1,
+ },
+ [0x1AA2]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA2,
+ },
+ [0x1AA3]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA3,
+ },
+ [0x1AA4]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA4,
+ },
+ [0x1AA5]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA5,
+ },
+ [0x1AA6]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA6,
+ },
+ [0x1AA7]={
+ category="lm",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA7,
+ },
+ [0x1AA8]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA8,
+ },
+ [0x1AA9]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA9,
+ },
+ [0x1AAA]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AAA,
+ },
+ [0x1AAB]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AAB,
+ },
+ [0x1AAC]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AAC,
+ },
+ [0x1AAD]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AAD,
+ },
+ [0x1AB0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1AB0,
+ },
+ [0x1AB1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1AB1,
+ },
+ [0x1AB2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1AB2,
+ },
+ [0x1AB3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1AB3,
+ },
+ [0x1AB4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1AB4,
+ },
+ [0x1AB5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1AB5,
+ },
+ [0x1AB6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1AB6,
+ },
+ [0x1AB7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1AB7,
+ },
+ [0x1AB8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1AB8,
+ },
+ [0x1AB9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1AB9,
+ },
+ [0x1ABA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1ABA,
+ },
+ [0x1ABB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1ABB,
+ },
+ [0x1ABC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1ABC,
+ },
+ [0x1ABD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1ABD,
+ },
+ [0x1ABE]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1ABE,
+ },
+ [0x1B00]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B00,
+ },
+ [0x1B01]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B01,
+ },
+ [0x1B02]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B02,
+ },
+ [0x1B03]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B03,
+ },
+ [0x1B04]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1B04,
+ },
+ [0x1B05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B05,
+ },
+ [0x1B06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B05, 0x1B35 },
+ unicodeslot=0x1B06,
+ },
+ [0x1B07]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B07,
+ },
+ [0x1B08]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B07, 0x1B35 },
+ unicodeslot=0x1B08,
+ },
+ [0x1B09]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B09,
+ },
+ [0x1B0A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B09, 0x1B35 },
+ unicodeslot=0x1B0A,
+ },
+ [0x1B0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B0B,
+ },
+ [0x1B0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B0B, 0x1B35 },
+ unicodeslot=0x1B0C,
+ },
+ [0x1B0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B0D,
+ },
+ [0x1B0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B0D, 0x1B35 },
+ unicodeslot=0x1B0E,
+ },
+ [0x1B0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B0F,
+ },
+ [0x1B10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B10,
+ },
+ [0x1B11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B11,
+ },
+ [0x1B12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B11, 0x1B35 },
+ unicodeslot=0x1B12,
+ },
+ [0x1B13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B13,
+ },
+ [0x1B14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B14,
+ },
+ [0x1B15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B15,
+ },
+ [0x1B16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B16,
+ },
+ [0x1B17]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B17,
+ },
+ [0x1B18]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B18,
+ },
+ [0x1B19]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B19,
+ },
+ [0x1B1A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1A,
+ },
+ [0x1B1B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1B,
+ },
+ [0x1B1C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1C,
+ },
+ [0x1B1D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1D,
+ },
+ [0x1B1E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1E,
+ },
+ [0x1B1F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1F,
+ },
+ [0x1B20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B20,
+ },
+ [0x1B21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B21,
+ },
+ [0x1B22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B22,
+ },
+ [0x1B23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B23,
+ },
+ [0x1B24]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B24,
+ },
+ [0x1B25]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B25,
+ },
+ [0x1B26]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B26,
+ },
+ [0x1B27]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B27,
+ },
+ [0x1B28]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B28,
+ },
+ [0x1B29]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B29,
+ },
+ [0x1B2A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2A,
+ },
+ [0x1B2B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2B,
+ },
+ [0x1B2C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2C,
+ },
+ [0x1B2D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2D,
+ },
+ [0x1B2E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2E,
+ },
+ [0x1B2F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2F,
+ },
+ [0x1B30]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B30,
+ },
+ [0x1B31]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B31,
+ },
+ [0x1B32]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B32,
+ },
+ [0x1B33]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B33,
+ },
+ [0x1B34]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B34,
+ },
+ [0x1B35]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1B35,
+ },
+ [0x1B36]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B36,
+ },
+ [0x1B37]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B37,
+ },
+ [0x1B38]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B38,
+ },
+ [0x1B39]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B39,
+ },
+ [0x1B3A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B3A,
+ },
+ [0x1B3B]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x1B3A, 0x1B35 },
+ unicodeslot=0x1B3B,
+ },
+ [0x1B3C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B3C,
+ },
+ [0x1B3D]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x1B3C, 0x1B35 },
+ unicodeslot=0x1B3D,
+ },
+ [0x1B3E]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1B3E,
+ },
+ [0x1B3F]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1B3F,
+ },
+ [0x1B40]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x1B3E, 0x1B35 },
+ unicodeslot=0x1B40,
+ },
+ [0x1B41]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x1B3F, 0x1B35 },
+ unicodeslot=0x1B41,
+ },
+ [0x1B42]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B42,
+ },
+ [0x1B43]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x1B42, 0x1B35 },
+ unicodeslot=0x1B43,
+ },
+ [0x1B44]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1B44,
+ },
+ [0x1B45]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B45,
+ },
+ [0x1B46]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B46,
+ },
+ [0x1B47]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B47,
+ },
+ [0x1B48]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B48,
+ },
+ [0x1B49]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B49,
+ },
+ [0x1B4A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B4A,
+ },
+ [0x1B4B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B4B,
+ },
+ [0x1B50]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B50,
+ },
+ [0x1B51]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B51,
+ },
+ [0x1B52]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B52,
+ },
+ [0x1B53]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B53,
+ },
+ [0x1B54]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B54,
+ },
+ [0x1B55]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B55,
+ },
+ [0x1B56]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B56,
+ },
+ [0x1B57]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B57,
+ },
+ [0x1B58]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B58,
+ },
+ [0x1B59]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B59,
+ },
+ [0x1B5A]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1B5A,
+ },
+ [0x1B5B]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1B5B,
+ },
+ [0x1B5C]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B5C,
+ },
+ [0x1B5D]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1B5D,
+ },
+ [0x1B5E]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1B5E,
+ },
+ [0x1B5F]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1B5F,
+ },
+ [0x1B60]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1B60,
+ },
+ [0x1B61]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B61,
+ },
+ [0x1B62]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B62,
+ },
+ [0x1B63]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B63,
+ },
+ [0x1B64]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B64,
+ },
+ [0x1B65]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B65,
+ },
+ [0x1B66]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B66,
+ },
+ [0x1B67]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B67,
+ },
+ [0x1B68]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B68,
+ },
+ [0x1B69]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B69,
+ },
+ [0x1B6A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B6A,
+ },
+ [0x1B6B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B6B,
+ },
+ [0x1B6C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B6C,
+ },
+ [0x1B6D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B6D,
+ },
+ [0x1B6E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B6E,
+ },
+ [0x1B6F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B6F,
+ },
+ [0x1B70]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B70,
+ },
+ [0x1B71]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B71,
+ },
+ [0x1B72]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B72,
+ },
+ [0x1B73]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B73,
+ },
+ [0x1B74]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B74,
+ },
+ [0x1B75]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B75,
+ },
+ [0x1B76]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B76,
+ },
+ [0x1B77]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B77,
+ },
+ [0x1B78]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B78,
+ },
+ [0x1B79]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B79,
+ },
+ [0x1B7A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B7A,
+ },
+ [0x1B7B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B7B,
+ },
+ [0x1B7C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B7C,
+ },
+ [0x1B80]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B80,
+ },
+ [0x1B81]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B81,
+ },
+ [0x1B82]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1B82,
+ },
+ [0x1B83]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B83,
+ },
+ [0x1B84]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B84,
+ },
+ [0x1B85]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B85,
+ },
+ [0x1B86]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B86,
+ },
+ [0x1B87]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B87,
+ },
+ [0x1B88]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B88,
+ },
+ [0x1B89]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B89,
+ },
+ [0x1B8A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8A,
+ },
+ [0x1B8B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8B,
+ },
+ [0x1B8C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8C,
+ },
+ [0x1B8D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8D,
+ },
+ [0x1B8E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8E,
+ },
+ [0x1B8F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8F,
+ },
+ [0x1B90]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B90,
+ },
+ [0x1B91]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B91,
+ },
+ [0x1B92]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B92,
+ },
+ [0x1B93]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B93,
+ },
+ [0x1B94]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B94,
+ },
+ [0x1B95]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B95,
+ },
+ [0x1B96]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B96,
+ },
+ [0x1B97]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B97,
+ },
+ [0x1B98]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B98,
+ },
+ [0x1B99]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B99,
+ },
+ [0x1B9A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9A,
+ },
+ [0x1B9B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9B,
+ },
+ [0x1B9C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9C,
+ },
+ [0x1B9D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9D,
+ },
+ [0x1B9E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9E,
+ },
+ [0x1B9F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9F,
+ },
+ [0x1BA0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BA0,
+ },
+ [0x1BA1]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BA1,
+ },
+ [0x1BA2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BA2,
+ },
+ [0x1BA3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BA3,
+ },
+ [0x1BA4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BA4,
+ },
+ [0x1BA5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BA5,
+ },
+ [0x1BA6]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BA6,
+ },
+ [0x1BA7]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BA7,
+ },
+ [0x1BA8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BA8,
+ },
+ [0x1BA9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BA9,
+ },
+ [0x1BAA]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BAA,
+ },
+ [0x1BAB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BAB,
+ },
+ [0x1BAC]={
+ category="mc",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BAC,
+ },
+ [0x1BAD]={
+ category="mc",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BAD,
+ },
+ [0x1BAE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BAE,
+ },
+ [0x1BAF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BAF,
+ },
+ [0x1BB0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB0,
+ },
+ [0x1BB1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB1,
+ },
+ [0x1BB2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB2,
+ },
+ [0x1BB3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB3,
+ },
+ [0x1BB4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB4,
+ },
+ [0x1BB5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB5,
+ },
+ [0x1BB6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB6,
+ },
+ [0x1BB7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB7,
+ },
+ [0x1BB8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB8,
+ },
+ [0x1BB9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB9,
+ },
+ [0x1BBA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BBA,
+ },
+ [0x1BBB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BBB,
+ },
+ [0x1BBC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BBC,
+ },
+ [0x1BBD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BBD,
+ },
+ [0x1BBE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BBE,
+ },
+ [0x1BBF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BBF,
+ },
+ [0x1BC0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC0,
+ },
+ [0x1BC1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC1,
+ },
+ [0x1BC2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC2,
+ },
+ [0x1BC3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC3,
+ },
+ [0x1BC4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC4,
+ },
+ [0x1BC5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC5,
+ },
+ [0x1BC6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC6,
+ },
+ [0x1BC7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC7,
+ },
+ [0x1BC8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC8,
+ },
+ [0x1BC9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC9,
+ },
+ [0x1BCA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BCA,
+ },
+ [0x1BCB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BCB,
+ },
+ [0x1BCC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BCC,
+ },
+ [0x1BCD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BCD,
+ },
+ [0x1BCE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BCE,
+ },
+ [0x1BCF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BCF,
+ },
+ [0x1BD0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD0,
+ },
+ [0x1BD1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD1,
+ },
+ [0x1BD2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD2,
+ },
+ [0x1BD3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD3,
+ },
+ [0x1BD4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD4,
+ },
+ [0x1BD5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD5,
+ },
+ [0x1BD6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD6,
+ },
+ [0x1BD7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD7,
+ },
+ [0x1BD8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD8,
+ },
+ [0x1BD9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD9,
+ },
+ [0x1BDA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BDA,
+ },
+ [0x1BDB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BDB,
+ },
+ [0x1BDC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BDC,
+ },
+ [0x1BDD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BDD,
+ },
+ [0x1BDE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BDE,
+ },
+ [0x1BDF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BDF,
+ },
+ [0x1BE0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE0,
+ },
+ [0x1BE1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE1,
+ },
+ [0x1BE2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE2,
+ },
+ [0x1BE3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE3,
+ },
+ [0x1BE4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE4,
+ },
+ [0x1BE5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE5,
+ },
+ [0x1BE6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BE6,
+ },
+ [0x1BE7]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BE7,
+ },
+ [0x1BE8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BE8,
+ },
+ [0x1BE9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BE9,
+ },
+ [0x1BEA]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BEA,
+ },
+ [0x1BEB]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BEB,
+ },
+ [0x1BEC]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BEC,
+ },
+ [0x1BED]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BED,
+ },
+ [0x1BEE]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BEE,
+ },
+ [0x1BEF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BEF,
+ },
+ [0x1BF0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BF0,
+ },
+ [0x1BF1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BF1,
+ },
+ [0x1BF2]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BF2,
+ },
+ [0x1BF3]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BF3,
+ },
+ [0x1BFC]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BFC,
+ },
+ [0x1BFD]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BFD,
+ },
+ [0x1BFE]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BFE,
+ },
+ [0x1BFF]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BFF,
+ },
+ [0x1C00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C00,
+ },
+ [0x1C01]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C01,
+ },
+ [0x1C02]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C02,
+ },
+ [0x1C03]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C03,
+ },
+ [0x1C04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C04,
+ },
+ [0x1C05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C05,
+ },
+ [0x1C06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C06,
+ },
+ [0x1C07]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C07,
+ },
+ [0x1C08]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C08,
+ },
+ [0x1C09]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C09,
+ },
+ [0x1C0A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0A,
+ },
+ [0x1C0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0B,
+ },
+ [0x1C0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0C,
+ },
+ [0x1C0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0D,
+ },
+ [0x1C0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0E,
+ },
+ [0x1C0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0F,
+ },
+ [0x1C10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C10,
+ },
+ [0x1C11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C11,
+ },
+ [0x1C12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C12,
+ },
+ [0x1C13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C13,
+ },
+ [0x1C14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C14,
+ },
+ [0x1C15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C15,
+ },
+ [0x1C16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C16,
+ },
+ [0x1C17]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C17,
+ },
+ [0x1C18]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C18,
+ },
+ [0x1C19]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C19,
+ },
+ [0x1C1A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1A,
+ },
+ [0x1C1B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1B,
+ },
+ [0x1C1C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1C,
+ },
+ [0x1C1D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1D,
+ },
+ [0x1C1E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1E,
+ },
+ [0x1C1F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1F,
+ },
+ [0x1C20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C20,
+ },
+ [0x1C21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C21,
+ },
+ [0x1C22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C22,
+ },
+ [0x1C23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C23,
+ },
+ [0x1C24]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C24,
+ },
+ [0x1C25]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C25,
+ },
+ [0x1C26]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C26,
+ },
+ [0x1C27]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C27,
+ },
+ [0x1C28]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C28,
+ },
+ [0x1C29]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C29,
+ },
+ [0x1C2A]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C2A,
+ },
+ [0x1C2B]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C2B,
+ },
+ [0x1C2C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C2C,
+ },
+ [0x1C2D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C2D,
+ },
+ [0x1C2E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C2E,
+ },
+ [0x1C2F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C2F,
+ },
+ [0x1C30]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C30,
+ },
+ [0x1C31]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C31,
+ },
+ [0x1C32]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C32,
+ },
+ [0x1C33]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C33,
+ },
+ [0x1C34]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C34,
+ },
+ [0x1C35]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C35,
+ },
+ [0x1C36]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C36,
+ },
+ [0x1C37]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C37,
+ },
+ [0x1C3B]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C3B,
+ },
+ [0x1C3C]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C3C,
+ },
+ [0x1C3D]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C3D,
+ },
+ [0x1C3E]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C3E,
+ },
+ [0x1C3F]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C3F,
+ },
+ [0x1C40]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C40,
+ },
+ [0x1C41]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C41,
+ },
+ [0x1C42]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C42,
+ },
+ [0x1C43]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C43,
+ },
+ [0x1C44]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C44,
+ },
+ [0x1C45]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C45,
+ },
+ [0x1C46]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C46,
+ },
+ [0x1C47]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C47,
+ },
+ [0x1C48]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C48,
+ },
+ [0x1C49]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C49,
+ },
+ [0x1C4D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C4D,
+ },
+ [0x1C4E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C4E,
+ },
+ [0x1C4F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C4F,
+ },
+ [0x1C50]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C50,
+ },
+ [0x1C51]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C51,
+ },
+ [0x1C52]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C52,
+ },
+ [0x1C53]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C53,
+ },
+ [0x1C54]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C54,
+ },
+ [0x1C55]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C55,
+ },
+ [0x1C56]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C56,
+ },
+ [0x1C57]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C57,
+ },
+ [0x1C58]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C58,
+ },
+ [0x1C59]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C59,
+ },
+ [0x1C5A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C5A,
+ },
+ [0x1C5B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C5B,
+ },
+ [0x1C5C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C5C,
+ },
+ [0x1C5D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C5D,
+ },
+ [0x1C5E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C5E,
+ },
+ [0x1C5F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C5F,
+ },
+ [0x1C60]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C60,
+ },
+ [0x1C61]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C61,
+ },
+ [0x1C62]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C62,
+ },
+ [0x1C63]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C63,
+ },
+ [0x1C64]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C64,
+ },
+ [0x1C65]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C65,
+ },
+ [0x1C66]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C66,
+ },
+ [0x1C67]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C67,
+ },
+ [0x1C68]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C68,
+ },
+ [0x1C69]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C69,
+ },
+ [0x1C6A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C6A,
+ },
+ [0x1C6B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C6B,
+ },
+ [0x1C6C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C6C,
+ },
+ [0x1C6D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C6D,
+ },
+ [0x1C6E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C6E,
+ },
+ [0x1C6F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C6F,
+ },
+ [0x1C70]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C70,
+ },
+ [0x1C71]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C71,
+ },
+ [0x1C72]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C72,
+ },
+ [0x1C73]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C73,
+ },
+ [0x1C74]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C74,
+ },
+ [0x1C75]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C75,
+ },
+ [0x1C76]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C76,
+ },
+ [0x1C77]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C77,
+ },
+ [0x1C78]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C78,
+ },
+ [0x1C79]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C79,
+ },
+ [0x1C7A]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C7A,
+ },
+ [0x1C7B]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C7B,
+ },
+ [0x1C7C]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C7C,
+ },
+ [0x1C7D]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C7D,
+ },
+ [0x1C7E]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C7E,
+ },
+ [0x1C7F]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C7F,
+ },
+ [0x1C80]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C80,
+ },
+ [0x1C81]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C81,
+ },
+ [0x1C82]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C82,
+ },
+ [0x1C83]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C83,
+ },
+ [0x1C84]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C84,
+ },
+ [0x1C85]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C85,
+ },
+ [0x1C86]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C86,
+ },
+ [0x1C87]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C87,
+ },
+ [0x1C88]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C88,
+ },
+ [0x1C90]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C90,
+ },
+ [0x1C91]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C91,
+ },
+ [0x1C92]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C92,
+ },
+ [0x1C93]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C93,
+ },
+ [0x1C94]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C94,
+ },
+ [0x1C95]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C95,
+ },
+ [0x1C96]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C96,
+ },
+ [0x1C97]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C97,
+ },
+ [0x1C98]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C98,
+ },
+ [0x1C99]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C99,
+ },
+ [0x1C9A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C9A,
+ },
+ [0x1C9B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C9B,
+ },
+ [0x1C9C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C9C,
+ },
+ [0x1C9D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C9D,
+ },
+ [0x1C9E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C9E,
+ },
+ [0x1C9F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C9F,
+ },
+ [0x1CA0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CA0,
+ },
+ [0x1CA1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CA1,
+ },
+ [0x1CA2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CA2,
+ },
+ [0x1CA3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CA3,
+ },
+ [0x1CA4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CA4,
+ },
+ [0x1CA5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CA5,
+ },
+ [0x1CA6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CA6,
+ },
+ [0x1CA7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CA7,
+ },
+ [0x1CA8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CA8,
+ },
+ [0x1CA9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CA9,
+ },
+ [0x1CAA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CAA,
+ },
+ [0x1CAB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CAB,
+ },
+ [0x1CAC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CAC,
+ },
+ [0x1CAD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CAD,
+ },
+ [0x1CAE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CAE,
+ },
+ [0x1CAF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CAF,
+ },
+ [0x1CB0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CB0,
+ },
+ [0x1CB1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CB1,
+ },
+ [0x1CB2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CB2,
+ },
+ [0x1CB3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CB3,
+ },
+ [0x1CB4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CB4,
+ },
+ [0x1CB5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CB5,
+ },
+ [0x1CB6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CB6,
+ },
+ [0x1CB7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CB7,
+ },
+ [0x1CB8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CB8,
+ },
+ [0x1CB9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CB9,
+ },
+ [0x1CBA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CBA,
+ },
+ [0x1CBD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CBD,
+ },
+ [0x1CBE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CBE,
+ },
+ [0x1CBF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CBF,
+ },
+ [0x1CC0]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC0,
+ },
+ [0x1CC1]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC1,
+ },
+ [0x1CC2]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC2,
+ },
+ [0x1CC3]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC3,
+ },
+ [0x1CC4]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC4,
+ },
+ [0x1CC5]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC5,
+ },
+ [0x1CC6]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC6,
+ },
+ [0x1CC7]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC7,
+ },
+ [0x1CD0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD0,
+ },
+ [0x1CD1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD1,
+ },
+ [0x1CD2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD2,
+ },
+ [0x1CD3]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CD3,
+ },
+ [0x1CD4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD4,
+ },
+ [0x1CD5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD5,
+ },
+ [0x1CD6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD6,
+ },
+ [0x1CD7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD7,
+ },
+ [0x1CD8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD8,
+ },
+ [0x1CD9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD9,
+ },
+ [0x1CDA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CDA,
+ },
+ [0x1CDB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CDB,
+ },
+ [0x1CDC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CDC,
+ },
+ [0x1CDD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CDD,
+ },
+ [0x1CDE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CDE,
+ },
+ [0x1CDF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CDF,
+ },
+ [0x1CE0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE0,
+ },
+ [0x1CE1]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1CE1,
+ },
+ [0x1CE2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE2,
+ },
+ [0x1CE3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE3,
+ },
+ [0x1CE4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE4,
+ },
+ [0x1CE5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE5,
+ },
+ [0x1CE6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE6,
+ },
+ [0x1CE7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE7,
+ },
+ [0x1CE8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE8,
+ },
+ [0x1CE9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CE9,
+ },
+ [0x1CEA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CEA,
+ },
+ [0x1CEB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CEB,
+ },
+ [0x1CEC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CEC,
+ },
+ [0x1CED]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CED,
+ },
+ [0x1CEE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CEE,
+ },
+ [0x1CEF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CEF,
+ },
+ [0x1CF0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CF0,
+ },
+ [0x1CF1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CF1,
+ },
+ [0x1CF2]={
+ category="mc",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CF2,
+ },
+ [0x1CF3]={
+ category="mc",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CF3,
+ },
+ [0x1CF4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CF4,
+ },
+ [0x1CF5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CF5,
+ },
+ [0x1CF6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CF6,
+ },
+ [0x1CF7]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1CF7,
+ },
+ [0x1CF8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CF8,
+ },
+ [0x1CF9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CF9,
+ },
+ [0x1CFA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CFA,
+ },
+ [0x1D00]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00,
+ },
+ [0x1D01]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01,
+ },
+ [0x1D02]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02,
+ },
+ [0x1D03]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03,
+ },
+ [0x1D04]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04,
+ },
+ [0x1D05]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05,
+ },
+ [0x1D06]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06,
+ },
+ [0x1D07]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07,
+ },
+ [0x1D08]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08,
+ },
+ [0x1D09]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09,
+ },
+ [0x1D0A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A,
+ },
+ [0x1D0B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B,
+ },
+ [0x1D0C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C,
+ },
+ [0x1D0D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D,
+ },
+ [0x1D0E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E,
+ },
+ [0x1D0F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F,
+ },
+ [0x1D10]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10,
+ },
+ [0x1D11]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11,
+ },
+ [0x1D12]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12,
+ },
+ [0x1D13]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13,
+ },
+ [0x1D14]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14,
+ },
+ [0x1D15]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D15,
+ },
+ [0x1D16]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D16,
+ },
+ [0x1D17]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D17,
+ },
+ [0x1D18]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D18,
+ },
+ [0x1D19]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19,
+ },
+ [0x1D1A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A,
+ },
+ [0x1D1B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B,
+ },
+ [0x1D1C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C,
+ },
+ [0x1D1D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D,
+ },
+ [0x1D1E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1E,
+ },
+ [0x1D1F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1F,
+ },
+ [0x1D20]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D20,
+ },
+ [0x1D21]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D21,
+ },
+ [0x1D22]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D22,
+ },
+ [0x1D23]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D23,
+ },
+ [0x1D24]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D24,
+ },
+ [0x1D25]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D25,
+ },
+ [0x1D26]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D26,
+ },
+ [0x1D27]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D27,
+ },
+ [0x1D28]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D28,
+ },
+ [0x1D29]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D29,
+ },
+ [0x1D2A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2A,
+ },
+ [0x1D2B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2B,
+ },
+ [0x1D2C]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x41 },
+ unicodeslot=0x1D2C,
+ },
+ [0x1D2D]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0xC6 },
+ unicodeslot=0x1D2D,
+ },
+ [0x1D2E]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x42 },
+ unicodeslot=0x1D2E,
+ },
+ [0x1D2F]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2F,
+ },
+ [0x1D30]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x44 },
+ unicodeslot=0x1D30,
+ },
+ [0x1D31]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x45 },
+ unicodeslot=0x1D31,
+ },
+ [0x1D32]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x18E },
+ unicodeslot=0x1D32,
+ },
+ [0x1D33]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x47 },
+ unicodeslot=0x1D33,
+ },
+ [0x1D34]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x48 },
+ unicodeslot=0x1D34,
+ },
+ [0x1D35]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x49 },
+ unicodeslot=0x1D35,
+ },
+ [0x1D36]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x4A },
+ unicodeslot=0x1D36,
+ },
+ [0x1D37]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x4B },
+ unicodeslot=0x1D37,
+ },
+ [0x1D38]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x4C },
+ unicodeslot=0x1D38,
+ },
+ [0x1D39]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x4D },
+ unicodeslot=0x1D39,
+ },
+ [0x1D3A]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x4E },
+ unicodeslot=0x1D3A,
+ },
+ [0x1D3B]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D3B,
+ },
+ [0x1D3C]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x4F },
+ unicodeslot=0x1D3C,
+ },
+ [0x1D3D]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x222 },
+ unicodeslot=0x1D3D,
+ },
+ [0x1D3E]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x50 },
+ unicodeslot=0x1D3E,
+ },
+ [0x1D3F]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x52 },
+ unicodeslot=0x1D3F,
+ },
+ [0x1D40]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x54 },
+ unicodeslot=0x1D40,
+ },
+ [0x1D41]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x55 },
+ unicodeslot=0x1D41,
+ },
+ [0x1D42]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x57 },
+ unicodeslot=0x1D42,
+ },
+ [0x1D43]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x61 },
+ unicodeslot=0x1D43,
+ },
+ [0x1D44]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x250 },
+ unicodeslot=0x1D44,
+ },
+ [0x1D45]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x251 },
+ unicodeslot=0x1D45,
+ },
+ [0x1D46]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D02 },
+ unicodeslot=0x1D46,
+ },
+ [0x1D47]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x62 },
+ unicodeslot=0x1D47,
+ },
+ [0x1D48]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x64 },
+ unicodeslot=0x1D48,
+ },
+ [0x1D49]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x65 },
+ unicodeslot=0x1D49,
+ },
+ [0x1D4A]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x259 },
+ unicodeslot=0x1D4A,
+ },
+ [0x1D4B]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x25B },
+ unicodeslot=0x1D4B,
+ },
+ [0x1D4C]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x25C },
+ unicodeslot=0x1D4C,
+ },
+ [0x1D4D]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x67 },
+ unicodeslot=0x1D4D,
+ },
+ [0x1D4E]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D4E,
+ },
+ [0x1D4F]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x6B },
+ unicodeslot=0x1D4F,
+ },
+ [0x1D50]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x6D },
+ unicodeslot=0x1D50,
+ },
+ [0x1D51]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x14B },
+ unicodeslot=0x1D51,
+ },
+ [0x1D52]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x6F },
+ unicodeslot=0x1D52,
+ },
+ [0x1D53]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x254 },
+ unicodeslot=0x1D53,
+ },
+ [0x1D54]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D16 },
+ unicodeslot=0x1D54,
+ },
+ [0x1D55]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D17 },
+ unicodeslot=0x1D55,
+ },
+ [0x1D56]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x70 },
+ unicodeslot=0x1D56,
+ },
+ [0x1D57]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x74 },
+ unicodeslot=0x1D57,
+ },
+ [0x1D58]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x75 },
+ unicodeslot=0x1D58,
+ },
+ [0x1D59]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D1D },
+ unicodeslot=0x1D59,
+ },
+ [0x1D5A]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x26F },
+ unicodeslot=0x1D5A,
+ },
+ [0x1D5B]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x76 },
+ unicodeslot=0x1D5B,
+ },
+ [0x1D5C]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D25 },
+ unicodeslot=0x1D5C,
+ },
+ [0x1D5D]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x3B2 },
+ unicodeslot=0x1D5D,
+ },
+ [0x1D5E]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x3B3 },
+ unicodeslot=0x1D5E,
+ },
+ [0x1D5F]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x3B4 },
+ unicodeslot=0x1D5F,
+ },
+ [0x1D60]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x3C6 },
+ unicodeslot=0x1D60,
+ },
+ [0x1D61]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x3C7 },
+ unicodeslot=0x1D61,
+ },
+ [0x1D62]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x69 },
+ unicodeslot=0x1D62,
+ },
+ [0x1D63]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x72 },
+ unicodeslot=0x1D63,
+ },
+ [0x1D64]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x75 },
+ unicodeslot=0x1D64,
+ },
+ [0x1D65]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x76 },
+ unicodeslot=0x1D65,
+ },
+ [0x1D66]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x3B2 },
+ unicodeslot=0x1D66,
+ },
+ [0x1D67]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x3B3 },
+ unicodeslot=0x1D67,
+ },
+ [0x1D68]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x3C1 },
+ unicodeslot=0x1D68,
+ },
+ [0x1D69]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x3C6 },
+ unicodeslot=0x1D69,
+ },
+ [0x1D6A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x3C7 },
+ unicodeslot=0x1D6A,
+ },
+ [0x1D6B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D6B,
+ },
+ [0x1D6C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D6C,
+ },
+ [0x1D6D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D6D,
+ },
+ [0x1D6E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D6E,
+ },
+ [0x1D6F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D6F,
+ },
+ [0x1D70]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D70,
+ },
+ [0x1D71]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D71,
+ },
+ [0x1D72]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D72,
+ },
+ [0x1D73]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D73,
+ },
+ [0x1D74]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D74,
+ },
+ [0x1D75]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D75,
+ },
+ [0x1D76]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D76,
+ },
+ [0x1D77]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D77,
+ },
+ [0x1D78]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x43D },
+ unicodeslot=0x1D78,
+ },
+ [0x1D79]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D79,
+ },
+ [0x1D7A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D7A,
+ },
+ [0x1D7B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D7B,
+ },
+ [0x1D7C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D7C,
+ },
+ [0x1D7D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D7D,
+ },
+ [0x1D7E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D7E,
+ },
+ [0x1D7F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D7F,
+ },
+ [0x1D80]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D80,
+ },
+ [0x1D81]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D81,
+ },
+ [0x1D82]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D82,
+ },
+ [0x1D83]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D83,
+ },
+ [0x1D84]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D84,
+ },
+ [0x1D85]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D85,
+ },
+ [0x1D86]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D86,
+ },
+ [0x1D87]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D87,
+ },
+ [0x1D88]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D88,
+ },
+ [0x1D89]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D89,
+ },
+ [0x1D8A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8A,
+ },
+ [0x1D8B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8B,
+ },
+ [0x1D8C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8C,
+ },
+ [0x1D8D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8D,
+ },
+ [0x1D8E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8E,
+ },
+ [0x1D8F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8F,
+ },
+ [0x1D90]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D90,
+ },
+ [0x1D91]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D91,
+ },
+ [0x1D92]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D92,
+ },
+ [0x1D93]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D93,
+ },
+ [0x1D94]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D94,
+ },
+ [0x1D95]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D95,
+ },
+ [0x1D96]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D96,
+ },
+ [0x1D97]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D97,
+ },
+ [0x1D98]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D98,
+ },
+ [0x1D99]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D99,
+ },
+ [0x1D9A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9A,
+ },
+ [0x1D9B]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x252 },
+ unicodeslot=0x1D9B,
+ },
+ [0x1D9C]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x63 },
+ unicodeslot=0x1D9C,
+ },
+ [0x1D9D]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x255 },
+ unicodeslot=0x1D9D,
+ },
+ [0x1D9E]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0xF0 },
+ unicodeslot=0x1D9E,
+ },
+ [0x1D9F]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x25C },
+ unicodeslot=0x1D9F,
+ },
+ [0x1DA0]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x66 },
+ unicodeslot=0x1DA0,
+ },
+ [0x1DA1]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x25F },
+ unicodeslot=0x1DA1,
+ },
+ [0x1DA2]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x261 },
+ unicodeslot=0x1DA2,
+ },
+ [0x1DA3]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x265 },
+ unicodeslot=0x1DA3,
+ },
+ [0x1DA4]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x268 },
+ unicodeslot=0x1DA4,
+ },
+ [0x1DA5]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x269 },
+ unicodeslot=0x1DA5,
+ },
+ [0x1DA6]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x26A },
+ unicodeslot=0x1DA6,
+ },
+ [0x1DA7]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D7B },
+ unicodeslot=0x1DA7,
+ },
+ [0x1DA8]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x29D },
+ unicodeslot=0x1DA8,
+ },
+ [0x1DA9]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x26D },
+ unicodeslot=0x1DA9,
+ },
+ [0x1DAA]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D85 },
+ unicodeslot=0x1DAA,
+ },
+ [0x1DAB]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x29F },
+ unicodeslot=0x1DAB,
+ },
+ [0x1DAC]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x271 },
+ unicodeslot=0x1DAC,
+ },
+ [0x1DAD]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x270 },
+ unicodeslot=0x1DAD,
+ },
+ [0x1DAE]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x272 },
+ unicodeslot=0x1DAE,
+ },
+ [0x1DAF]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x273 },
+ unicodeslot=0x1DAF,
+ },
+ [0x1DB0]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x274 },
+ unicodeslot=0x1DB0,
+ },
+ [0x1DB1]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x275 },
+ unicodeslot=0x1DB1,
+ },
+ [0x1DB2]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x278 },
+ unicodeslot=0x1DB2,
+ },
+ [0x1DB3]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x282 },
+ unicodeslot=0x1DB3,
+ },
+ [0x1DB4]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x283 },
+ unicodeslot=0x1DB4,
+ },
+ [0x1DB5]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1AB },
+ unicodeslot=0x1DB5,
+ },
+ [0x1DB6]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x289 },
+ unicodeslot=0x1DB6,
+ },
+ [0x1DB7]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x28A },
+ unicodeslot=0x1DB7,
+ },
+ [0x1DB8]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D1C },
+ unicodeslot=0x1DB8,
+ },
+ [0x1DB9]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x28B },
+ unicodeslot=0x1DB9,
+ },
+ [0x1DBA]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x28C },
+ unicodeslot=0x1DBA,
+ },
+ [0x1DBB]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x7A },
+ unicodeslot=0x1DBB,
+ },
+ [0x1DBC]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x290 },
+ unicodeslot=0x1DBC,
+ },
+ [0x1DBD]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x291 },
+ unicodeslot=0x1DBD,
+ },
+ [0x1DBE]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x292 },
+ unicodeslot=0x1DBE,
+ },
+ [0x1DBF]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x3B8 },
+ unicodeslot=0x1DBF,
+ },
+ [0x1DC0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC0,
+ },
+ [0x1DC1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC1,
+ },
+ [0x1DC2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC2,
+ },
+ [0x1DC3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC3,
+ },
+ [0x1DC4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC4,
+ },
+ [0x1DC5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC5,
+ },
+ [0x1DC6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC6,
+ },
+ [0x1DC7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC7,
+ },
+ [0x1DC8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC8,
+ },
+ [0x1DC9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC9,
+ },
+ [0x1DCA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DCA,
+ },
+ [0x1DCB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DCB,
+ },
+ [0x1DCC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DCC,
+ },
+ [0x1DCD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DCD,
+ },
+ [0x1DCE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DCE,
+ },
+ [0x1DCF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DCF,
+ },
+ [0x1DD0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD0,
+ },
+ [0x1DD1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD1,
+ },
+ [0x1DD2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD2,
+ },
+ [0x1DD3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD3,
+ },
+ [0x1DD4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD4,
+ },
+ [0x1DD5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD5,
+ },
+ [0x1DD6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD6,
+ },
+ [0x1DD7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD7,
+ },
+ [0x1DD8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD8,
+ },
+ [0x1DD9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD9,
+ },
+ [0x1DDA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DDA,
+ },
+ [0x1DDB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DDB,
+ },
+ [0x1DDC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DDC,
+ },
+ [0x1DDD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DDD,
+ },
+ [0x1DDE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DDE,
+ },
+ [0x1DDF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DDF,
+ },
+ [0x1DE0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE0,
+ },
+ [0x1DE1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE1,
+ },
+ [0x1DE2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE2,
+ },
+ [0x1DE3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE3,
+ },
+ [0x1DE4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE4,
+ },
+ [0x1DE5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE5,
+ },
+ [0x1DE6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE6,
+ },
+ [0x1DE7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE7,
+ },
+ [0x1DE8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE8,
+ },
+ [0x1DE9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE9,
+ },
+ [0x1DEA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DEA,
+ },
+ [0x1DEB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DEB,
+ },
+ [0x1DEC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DEC,
+ },
+ [0x1DED]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DED,
+ },
+ [0x1DEE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DEE,
+ },
+ [0x1DEF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DEF,
+ },
+ [0x1DF0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DF0,
+ },
+ [0x1DF1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DF1,
+ },
+ [0x1DF2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DF2,
+ },
+ [0x1DF3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DF3,
+ },
+ [0x1DF4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DF4,
+ },
+ [0x1DF5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DF5,
+ },
+ [0x1DF6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DF6,
+ },
+ [0x1DF7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DF7,
+ },
+ [0x1DF8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DF8,
+ },
+ [0x1DF9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DF9,
+ },
+ [0x1DFB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DFB,
+ },
+ [0x1DFC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DFC,
+ },
+ [0x1DFD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DFD,
+ },
+ [0x1DFE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DFE,
+ },
+ [0x1DFF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DFF,
+ },
+ [0x1E00]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x325 },
+ unicodeslot=0x1E00,
+ },
+ [0x1E01]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x325 },
+ unicodeslot=0x1E01,
+ },
+ [0x1E02]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x42, 0x307 },
+ unicodeslot=0x1E02,
+ },
+ [0x1E03]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x62, 0x307 },
+ unicodeslot=0x1E03,
+ },
+ [0x1E04]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x42, 0x323 },
+ unicodeslot=0x1E04,
+ },
+ [0x1E05]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x62, 0x323 },
+ unicodeslot=0x1E05,
+ },
+ [0x1E06]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x42, 0x331 },
+ unicodeslot=0x1E06,
+ },
+ [0x1E07]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x62, 0x331 },
+ unicodeslot=0x1E07,
+ },
+ [0x1E08]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xC7, 0x301 },
+ unicodeslot=0x1E08,
+ },
+ [0x1E09]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xE7, 0x301 },
+ unicodeslot=0x1E09,
+ },
+ [0x1E0A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x44, 0x307 },
+ unicodeslot=0x1E0A,
+ },
+ [0x1E0B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x64, 0x307 },
+ unicodeslot=0x1E0B,
+ },
+ [0x1E0C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x44, 0x323 },
+ unicodeslot=0x1E0C,
+ },
+ [0x1E0D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x64, 0x323 },
+ unicodeslot=0x1E0D,
+ },
+ [0x1E0E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x44, 0x331 },
+ unicodeslot=0x1E0E,
+ },
+ [0x1E0F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x64, 0x331 },
+ unicodeslot=0x1E0F,
+ },
+ [0x1E10]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x44, 0x327 },
+ unicodeslot=0x1E10,
+ },
+ [0x1E11]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x64, 0x327 },
+ unicodeslot=0x1E11,
+ },
+ [0x1E12]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x44, 0x32D },
+ unicodeslot=0x1E12,
+ },
+ [0x1E13]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x64, 0x32D },
+ unicodeslot=0x1E13,
+ },
+ [0x1E14]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x112, 0x300 },
+ unicodeslot=0x1E14,
+ },
+ [0x1E15]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x113, 0x300 },
+ unicodeslot=0x1E15,
+ },
+ [0x1E16]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x112, 0x301 },
+ unicodeslot=0x1E16,
+ },
+ [0x1E17]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x113, 0x301 },
+ unicodeslot=0x1E17,
+ },
+ [0x1E18]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x32D },
+ unicodeslot=0x1E18,
+ },
+ [0x1E19]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x32D },
+ unicodeslot=0x1E19,
+ },
+ [0x1E1A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x330 },
+ unicodeslot=0x1E1A,
+ },
+ [0x1E1B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x330 },
+ unicodeslot=0x1E1B,
+ },
+ [0x1E1C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x228, 0x306 },
+ unicodeslot=0x1E1C,
+ },
+ [0x1E1D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x229, 0x306 },
+ unicodeslot=0x1E1D,
+ },
+ [0x1E1E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x46, 0x307 },
+ unicodeslot=0x1E1E,
+ },
+ [0x1E1F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x66, 0x307 },
+ unicodeslot=0x1E1F,
+ },
+ [0x1E20]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x47, 0x304 },
+ unicodeslot=0x1E20,
+ },
+ [0x1E21]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x67, 0x304 },
+ unicodeslot=0x1E21,
+ },
+ [0x1E22]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x48, 0x307 },
+ unicodeslot=0x1E22,
+ },
+ [0x1E23]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x68, 0x307 },
+ unicodeslot=0x1E23,
+ },
+ [0x1E24]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x48, 0x323 },
+ unicodeslot=0x1E24,
+ },
+ [0x1E25]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x68, 0x323 },
+ unicodeslot=0x1E25,
+ },
+ [0x1E26]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x48, 0x308 },
+ unicodeslot=0x1E26,
+ },
+ [0x1E27]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x68, 0x308 },
+ unicodeslot=0x1E27,
+ },
+ [0x1E28]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x48, 0x327 },
+ unicodeslot=0x1E28,
+ },
+ [0x1E29]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x68, 0x327 },
+ unicodeslot=0x1E29,
+ },
+ [0x1E2A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x48, 0x32E },
+ unicodeslot=0x1E2A,
+ },
+ [0x1E2B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x68, 0x32E },
+ unicodeslot=0x1E2B,
+ },
+ [0x1E2C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x330 },
+ unicodeslot=0x1E2C,
+ },
+ [0x1E2D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x330 },
+ unicodeslot=0x1E2D,
+ },
+ [0x1E2E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xCF, 0x301 },
+ unicodeslot=0x1E2E,
+ },
+ [0x1E2F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xEF, 0x301 },
+ unicodeslot=0x1E2F,
+ },
+ [0x1E30]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4B, 0x301 },
+ unicodeslot=0x1E30,
+ },
+ [0x1E31]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6B, 0x301 },
+ unicodeslot=0x1E31,
+ },
+ [0x1E32]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4B, 0x323 },
+ unicodeslot=0x1E32,
+ },
+ [0x1E33]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6B, 0x323 },
+ unicodeslot=0x1E33,
+ },
+ [0x1E34]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4B, 0x331 },
+ unicodeslot=0x1E34,
+ },
+ [0x1E35]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6B, 0x331 },
+ unicodeslot=0x1E35,
+ },
+ [0x1E36]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4C, 0x323 },
+ unicodeslot=0x1E36,
+ },
+ [0x1E37]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6C, 0x323 },
+ unicodeslot=0x1E37,
+ },
+ [0x1E38]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1E36, 0x304 },
+ unicodeslot=0x1E38,
+ },
+ [0x1E39]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1E37, 0x304 },
+ unicodeslot=0x1E39,
+ },
+ [0x1E3A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4C, 0x331 },
+ unicodeslot=0x1E3A,
+ },
+ [0x1E3B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6C, 0x331 },
+ unicodeslot=0x1E3B,
+ },
+ [0x1E3C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4C, 0x32D },
+ unicodeslot=0x1E3C,
+ },
+ [0x1E3D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6C, 0x32D },
+ unicodeslot=0x1E3D,
+ },
+ [0x1E3E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4D, 0x301 },
+ unicodeslot=0x1E3E,
+ },
+ [0x1E3F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6D, 0x301 },
+ unicodeslot=0x1E3F,
+ },
+ [0x1E40]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4D, 0x307 },
+ unicodeslot=0x1E40,
+ },
+ [0x1E41]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6D, 0x307 },
+ unicodeslot=0x1E41,
+ },
+ [0x1E42]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4D, 0x323 },
+ unicodeslot=0x1E42,
+ },
+ [0x1E43]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6D, 0x323 },
+ unicodeslot=0x1E43,
+ },
+ [0x1E44]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4E, 0x307 },
+ unicodeslot=0x1E44,
+ },
+ [0x1E45]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6E, 0x307 },
+ unicodeslot=0x1E45,
+ },
+ [0x1E46]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4E, 0x323 },
+ unicodeslot=0x1E46,
+ },
+ [0x1E47]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6E, 0x323 },
+ unicodeslot=0x1E47,
+ },
+ [0x1E48]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4E, 0x331 },
+ unicodeslot=0x1E48,
+ },
+ [0x1E49]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6E, 0x331 },
+ unicodeslot=0x1E49,
+ },
+ [0x1E4A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4E, 0x32D },
+ unicodeslot=0x1E4A,
+ },
+ [0x1E4B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6E, 0x32D },
+ unicodeslot=0x1E4B,
+ },
+ [0x1E4C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xD5, 0x301 },
+ unicodeslot=0x1E4C,
+ },
+ [0x1E4D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF5, 0x301 },
+ unicodeslot=0x1E4D,
+ },
+ [0x1E4E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xD5, 0x308 },
+ unicodeslot=0x1E4E,
+ },
+ [0x1E4F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF5, 0x308 },
+ unicodeslot=0x1E4F,
+ },
+ [0x1E50]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x14C, 0x300 },
+ unicodeslot=0x1E50,
+ },
+ [0x1E51]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x14D, 0x300 },
+ unicodeslot=0x1E51,
+ },
+ [0x1E52]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x14C, 0x301 },
+ unicodeslot=0x1E52,
+ },
+ [0x1E53]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x14D, 0x301 },
+ unicodeslot=0x1E53,
+ },
+ [0x1E54]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x50, 0x301 },
+ unicodeslot=0x1E54,
+ },
+ [0x1E55]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x70, 0x301 },
+ unicodeslot=0x1E55,
+ },
+ [0x1E56]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x50, 0x307 },
+ unicodeslot=0x1E56,
+ },
+ [0x1E57]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x70, 0x307 },
+ unicodeslot=0x1E57,
+ },
+ [0x1E58]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x52, 0x307 },
+ unicodeslot=0x1E58,
+ },
+ [0x1E59]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x72, 0x307 },
+ unicodeslot=0x1E59,
+ },
+ [0x1E5A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x52, 0x323 },
+ unicodeslot=0x1E5A,
+ },
+ [0x1E5B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x72, 0x323 },
+ unicodeslot=0x1E5B,
+ },
+ [0x1E5C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1E5A, 0x304 },
+ unicodeslot=0x1E5C,
+ },
+ [0x1E5D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1E5B, 0x304 },
+ unicodeslot=0x1E5D,
+ },
+ [0x1E5E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x52, 0x331 },
+ unicodeslot=0x1E5E,
+ },
+ [0x1E5F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x72, 0x331 },
+ unicodeslot=0x1E5F,
+ },
+ [0x1E60]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x53, 0x307 },
+ unicodeslot=0x1E60,
+ },
+ [0x1E61]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x73, 0x307 },
+ unicodeslot=0x1E61,
+ },
+ [0x1E62]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x53, 0x323 },
+ unicodeslot=0x1E62,
+ },
+ [0x1E63]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x73, 0x323 },
+ unicodeslot=0x1E63,
+ },
+ [0x1E64]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x15A, 0x307 },
+ unicodeslot=0x1E64,
+ },
+ [0x1E65]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x15B, 0x307 },
+ unicodeslot=0x1E65,
+ },
+ [0x1E66]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x160, 0x307 },
+ unicodeslot=0x1E66,
+ },
+ [0x1E67]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x161, 0x307 },
+ unicodeslot=0x1E67,
+ },
+ [0x1E68]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1E62, 0x307 },
+ unicodeslot=0x1E68,
+ },
+ [0x1E69]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1E63, 0x307 },
+ unicodeslot=0x1E69,
+ },
+ [0x1E6A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x54, 0x307 },
+ unicodeslot=0x1E6A,
+ },
+ [0x1E6B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x74, 0x307 },
+ unicodeslot=0x1E6B,
+ },
+ [0x1E6C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x54, 0x323 },
+ unicodeslot=0x1E6C,
+ },
+ [0x1E6D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x74, 0x323 },
+ unicodeslot=0x1E6D,
+ },
+ [0x1E6E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x54, 0x331 },
+ unicodeslot=0x1E6E,
+ },
+ [0x1E6F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x74, 0x331 },
+ unicodeslot=0x1E6F,
+ },
+ [0x1E70]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x54, 0x32D },
+ unicodeslot=0x1E70,
+ },
+ [0x1E71]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x74, 0x32D },
+ unicodeslot=0x1E71,
+ },
+ [0x1E72]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x324 },
+ unicodeslot=0x1E72,
+ },
+ [0x1E73]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x324 },
+ unicodeslot=0x1E73,
+ },
+ [0x1E74]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x330 },
+ unicodeslot=0x1E74,
+ },
+ [0x1E75]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x330 },
+ unicodeslot=0x1E75,
+ },
+ [0x1E76]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x32D },
+ unicodeslot=0x1E76,
+ },
+ [0x1E77]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x32D },
+ unicodeslot=0x1E77,
+ },
+ [0x1E78]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x168, 0x301 },
+ unicodeslot=0x1E78,
+ },
+ [0x1E79]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x169, 0x301 },
+ unicodeslot=0x1E79,
+ },
+ [0x1E7A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x16A, 0x308 },
+ unicodeslot=0x1E7A,
+ },
+ [0x1E7B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x16B, 0x308 },
+ unicodeslot=0x1E7B,
+ },
+ [0x1E7C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x56, 0x303 },
+ unicodeslot=0x1E7C,
+ },
+ [0x1E7D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x76, 0x303 },
+ unicodeslot=0x1E7D,
+ },
+ [0x1E7E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x56, 0x323 },
+ unicodeslot=0x1E7E,
+ },
+ [0x1E7F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x76, 0x323 },
+ unicodeslot=0x1E7F,
+ },
+ [0x1E80]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x57, 0x300 },
+ unicodeslot=0x1E80,
+ },
+ [0x1E81]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x77, 0x300 },
+ unicodeslot=0x1E81,
+ },
+ [0x1E82]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x57, 0x301 },
+ unicodeslot=0x1E82,
+ },
+ [0x1E83]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x77, 0x301 },
+ unicodeslot=0x1E83,
+ },
+ [0x1E84]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x57, 0x308 },
+ unicodeslot=0x1E84,
+ },
+ [0x1E85]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x77, 0x308 },
+ unicodeslot=0x1E85,
+ },
+ [0x1E86]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x57, 0x307 },
+ unicodeslot=0x1E86,
+ },
+ [0x1E87]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x77, 0x307 },
+ unicodeslot=0x1E87,
+ },
+ [0x1E88]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x57, 0x323 },
+ unicodeslot=0x1E88,
+ },
+ [0x1E89]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x77, 0x323 },
+ unicodeslot=0x1E89,
+ },
+ [0x1E8A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x58, 0x307 },
+ unicodeslot=0x1E8A,
+ },
+ [0x1E8B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x78, 0x307 },
+ unicodeslot=0x1E8B,
+ },
+ [0x1E8C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x58, 0x308 },
+ unicodeslot=0x1E8C,
+ },
+ [0x1E8D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x78, 0x308 },
+ unicodeslot=0x1E8D,
+ },
+ [0x1E8E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x59, 0x307 },
+ unicodeslot=0x1E8E,
+ },
+ [0x1E8F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x79, 0x307 },
+ unicodeslot=0x1E8F,
+ },
+ [0x1E90]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x5A, 0x302 },
+ unicodeslot=0x1E90,
+ },
+ [0x1E91]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x7A, 0x302 },
+ unicodeslot=0x1E91,
+ },
+ [0x1E92]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x5A, 0x323 },
+ unicodeslot=0x1E92,
+ },
+ [0x1E93]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x7A, 0x323 },
+ unicodeslot=0x1E93,
+ },
+ [0x1E94]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x5A, 0x331 },
+ unicodeslot=0x1E94,
+ },
+ [0x1E95]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x7A, 0x331 },
+ unicodeslot=0x1E95,
+ },
+ [0x1E96]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x68, 0x331 },
+ unicodeslot=0x1E96,
+ },
+ [0x1E97]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x74, 0x308 },
+ unicodeslot=0x1E97,
+ },
+ [0x1E98]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x77, 0x30A },
+ unicodeslot=0x1E98,
+ },
+ [0x1E99]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x79, 0x30A },
+ unicodeslot=0x1E99,
+ },
+ [0x1E9A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x61, 0x2BE },
+ unicodeslot=0x1E9A,
+ },
+ [0x1E9B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x17F, 0x307 },
+ unicodeslot=0x1E9B,
+ },
+ [0x1E9C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E9C,
+ },
+ [0x1E9D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E9D,
+ },
+ [0x1E9E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E9E,
+ },
+ [0x1E9F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E9F,
+ },
+ [0x1EA0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x323 },
+ unicodeslot=0x1EA0,
+ },
+ [0x1EA1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x323 },
+ unicodeslot=0x1EA1,
+ },
+ [0x1EA2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x41, 0x309 },
+ unicodeslot=0x1EA2,
+ },
+ [0x1EA3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x61, 0x309 },
+ unicodeslot=0x1EA3,
+ },
+ [0x1EA4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xC2, 0x301 },
+ unicodeslot=0x1EA4,
+ },
+ [0x1EA5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xE2, 0x301 },
+ unicodeslot=0x1EA5,
+ },
+ [0x1EA6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xC2, 0x300 },
+ unicodeslot=0x1EA6,
+ },
+ [0x1EA7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xE2, 0x300 },
+ unicodeslot=0x1EA7,
+ },
+ [0x1EA8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xC2, 0x309 },
+ unicodeslot=0x1EA8,
+ },
+ [0x1EA9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xE2, 0x309 },
+ unicodeslot=0x1EA9,
+ },
+ [0x1EAA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xC2, 0x303 },
+ unicodeslot=0x1EAA,
+ },
+ [0x1EAB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xE2, 0x303 },
+ unicodeslot=0x1EAB,
+ },
+ [0x1EAC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1EA0, 0x302 },
+ unicodeslot=0x1EAC,
+ },
+ [0x1EAD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1EA1, 0x302 },
+ unicodeslot=0x1EAD,
+ },
+ [0x1EAE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x102, 0x301 },
+ unicodeslot=0x1EAE,
+ },
+ [0x1EAF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x103, 0x301 },
+ unicodeslot=0x1EAF,
+ },
+ [0x1EB0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x102, 0x300 },
+ unicodeslot=0x1EB0,
+ },
+ [0x1EB1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x103, 0x300 },
+ unicodeslot=0x1EB1,
+ },
+ [0x1EB2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x102, 0x309 },
+ unicodeslot=0x1EB2,
+ },
+ [0x1EB3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x103, 0x309 },
+ unicodeslot=0x1EB3,
+ },
+ [0x1EB4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x102, 0x303 },
+ unicodeslot=0x1EB4,
+ },
+ [0x1EB5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x103, 0x303 },
+ unicodeslot=0x1EB5,
+ },
+ [0x1EB6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1EA0, 0x306 },
+ unicodeslot=0x1EB6,
+ },
+ [0x1EB7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1EA1, 0x306 },
+ unicodeslot=0x1EB7,
+ },
+ [0x1EB8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x323 },
+ unicodeslot=0x1EB8,
+ },
+ [0x1EB9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x323 },
+ unicodeslot=0x1EB9,
+ },
+ [0x1EBA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x309 },
+ unicodeslot=0x1EBA,
+ },
+ [0x1EBB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x309 },
+ unicodeslot=0x1EBB,
+ },
+ [0x1EBC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x45, 0x303 },
+ unicodeslot=0x1EBC,
+ },
+ [0x1EBD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x65, 0x303 },
+ unicodeslot=0x1EBD,
+ },
+ [0x1EBE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xCA, 0x301 },
+ unicodeslot=0x1EBE,
+ },
+ [0x1EBF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xEA, 0x301 },
+ unicodeslot=0x1EBF,
+ },
+ [0x1EC0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xCA, 0x300 },
+ unicodeslot=0x1EC0,
+ },
+ [0x1EC1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xEA, 0x300 },
+ unicodeslot=0x1EC1,
+ },
+ [0x1EC2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xCA, 0x309 },
+ unicodeslot=0x1EC2,
+ },
+ [0x1EC3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xEA, 0x309 },
+ unicodeslot=0x1EC3,
+ },
+ [0x1EC4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xCA, 0x303 },
+ unicodeslot=0x1EC4,
+ },
+ [0x1EC5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xEA, 0x303 },
+ unicodeslot=0x1EC5,
+ },
+ [0x1EC6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1EB8, 0x302 },
+ unicodeslot=0x1EC6,
+ },
+ [0x1EC7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1EB9, 0x302 },
+ unicodeslot=0x1EC7,
+ },
+ [0x1EC8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x309 },
+ unicodeslot=0x1EC8,
+ },
+ [0x1EC9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x309 },
+ unicodeslot=0x1EC9,
+ },
+ [0x1ECA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x49, 0x323 },
+ unicodeslot=0x1ECA,
+ },
+ [0x1ECB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x69, 0x323 },
+ unicodeslot=0x1ECB,
+ },
+ [0x1ECC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x323 },
+ unicodeslot=0x1ECC,
+ },
+ [0x1ECD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x323 },
+ unicodeslot=0x1ECD,
+ },
+ [0x1ECE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4F, 0x309 },
+ unicodeslot=0x1ECE,
+ },
+ [0x1ECF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x6F, 0x309 },
+ unicodeslot=0x1ECF,
+ },
+ [0x1ED0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xD4, 0x301 },
+ unicodeslot=0x1ED0,
+ },
+ [0x1ED1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF4, 0x301 },
+ unicodeslot=0x1ED1,
+ },
+ [0x1ED2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xD4, 0x300 },
+ unicodeslot=0x1ED2,
+ },
+ [0x1ED3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF4, 0x300 },
+ unicodeslot=0x1ED3,
+ },
+ [0x1ED4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xD4, 0x309 },
+ unicodeslot=0x1ED4,
+ },
+ [0x1ED5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF4, 0x309 },
+ unicodeslot=0x1ED5,
+ },
+ [0x1ED6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xD4, 0x303 },
+ unicodeslot=0x1ED6,
+ },
+ [0x1ED7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0xF4, 0x303 },
+ unicodeslot=0x1ED7,
+ },
+ [0x1ED8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1ECC, 0x302 },
+ unicodeslot=0x1ED8,
+ },
+ [0x1ED9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1ECD, 0x302 },
+ unicodeslot=0x1ED9,
+ },
+ [0x1EDA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1A0, 0x301 },
+ unicodeslot=0x1EDA,
+ },
+ [0x1EDB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1A1, 0x301 },
+ unicodeslot=0x1EDB,
+ },
+ [0x1EDC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1A0, 0x300 },
+ unicodeslot=0x1EDC,
+ },
+ [0x1EDD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1A1, 0x300 },
+ unicodeslot=0x1EDD,
+ },
+ [0x1EDE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1A0, 0x309 },
+ unicodeslot=0x1EDE,
+ },
+ [0x1EDF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1A1, 0x309 },
+ unicodeslot=0x1EDF,
+ },
+ [0x1EE0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1A0, 0x303 },
+ unicodeslot=0x1EE0,
+ },
+ [0x1EE1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1A1, 0x303 },
+ unicodeslot=0x1EE1,
+ },
+ [0x1EE2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1A0, 0x323 },
+ unicodeslot=0x1EE2,
+ },
+ [0x1EE3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1A1, 0x323 },
+ unicodeslot=0x1EE3,
+ },
+ [0x1EE4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x323 },
+ unicodeslot=0x1EE4,
+ },
+ [0x1EE5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x323 },
+ unicodeslot=0x1EE5,
+ },
+ [0x1EE6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x55, 0x309 },
+ unicodeslot=0x1EE6,
+ },
+ [0x1EE7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x75, 0x309 },
+ unicodeslot=0x1EE7,
+ },
+ [0x1EE8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1AF, 0x301 },
+ unicodeslot=0x1EE8,
+ },
+ [0x1EE9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B0, 0x301 },
+ unicodeslot=0x1EE9,
+ },
+ [0x1EEA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1AF, 0x300 },
+ unicodeslot=0x1EEA,
+ },
+ [0x1EEB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B0, 0x300 },
+ unicodeslot=0x1EEB,
+ },
+ [0x1EEC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1AF, 0x309 },
+ unicodeslot=0x1EEC,
+ },
+ [0x1EED]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B0, 0x309 },
+ unicodeslot=0x1EED,
+ },
+ [0x1EEE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1AF, 0x303 },
+ unicodeslot=0x1EEE,
+ },
+ [0x1EEF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B0, 0x303 },
+ unicodeslot=0x1EEF,
+ },
+ [0x1EF0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1AF, 0x323 },
+ unicodeslot=0x1EF0,
+ },
+ [0x1EF1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B0, 0x323 },
+ unicodeslot=0x1EF1,
+ },
+ [0x1EF2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x59, 0x300 },
+ unicodeslot=0x1EF2,
+ },
+ [0x1EF3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x79, 0x300 },
+ unicodeslot=0x1EF3,
+ },
+ [0x1EF4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x59, 0x323 },
+ unicodeslot=0x1EF4,
+ },
+ [0x1EF5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x79, 0x323 },
+ unicodeslot=0x1EF5,
+ },
+ [0x1EF6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x59, 0x309 },
+ unicodeslot=0x1EF6,
+ },
+ [0x1EF7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x79, 0x309 },
+ unicodeslot=0x1EF7,
+ },
+ [0x1EF8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x59, 0x303 },
+ unicodeslot=0x1EF8,
+ },
+ [0x1EF9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x79, 0x303 },
+ unicodeslot=0x1EF9,
+ },
+ [0x1EFA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1EFA,
+ },
+ [0x1EFB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1EFB,
+ },
+ [0x1EFC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1EFC,
+ },
+ [0x1EFD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1EFD,
+ },
+ [0x1EFE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1EFE,
+ },
+ [0x1EFF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1EFF,
+ },
+ [0x1F00]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B1, 0x313 },
+ unicodeslot=0x1F00,
+ },
+ [0x1F01]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B1, 0x314 },
+ unicodeslot=0x1F01,
+ },
+ [0x1F02]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F00, 0x300 },
+ unicodeslot=0x1F02,
+ },
+ [0x1F03]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F01, 0x300 },
+ unicodeslot=0x1F03,
+ },
+ [0x1F04]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F00, 0x301 },
+ unicodeslot=0x1F04,
+ },
+ [0x1F05]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F01, 0x301 },
+ unicodeslot=0x1F05,
+ },
+ [0x1F06]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F00, 0x342 },
+ unicodeslot=0x1F06,
+ },
+ [0x1F07]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F01, 0x342 },
+ unicodeslot=0x1F07,
+ },
+ [0x1F08]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x391, 0x313 },
+ unicodeslot=0x1F08,
+ },
+ [0x1F09]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x391, 0x314 },
+ unicodeslot=0x1F09,
+ },
+ [0x1F0A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F08, 0x300 },
+ unicodeslot=0x1F0A,
+ },
+ [0x1F0B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F09, 0x300 },
+ unicodeslot=0x1F0B,
+ },
+ [0x1F0C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F08, 0x301 },
+ unicodeslot=0x1F0C,
+ },
+ [0x1F0D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F09, 0x301 },
+ unicodeslot=0x1F0D,
+ },
+ [0x1F0E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F08, 0x342 },
+ unicodeslot=0x1F0E,
+ },
+ [0x1F0F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F09, 0x342 },
+ unicodeslot=0x1F0F,
+ },
+ [0x1F10]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B5, 0x313 },
+ unicodeslot=0x1F10,
+ },
+ [0x1F11]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B5, 0x314 },
+ unicodeslot=0x1F11,
+ },
+ [0x1F12]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F10, 0x300 },
+ unicodeslot=0x1F12,
+ },
+ [0x1F13]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F11, 0x300 },
+ unicodeslot=0x1F13,
+ },
+ [0x1F14]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F10, 0x301 },
+ unicodeslot=0x1F14,
+ },
+ [0x1F15]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F11, 0x301 },
+ unicodeslot=0x1F15,
+ },
+ [0x1F18]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x395, 0x313 },
+ unicodeslot=0x1F18,
+ },
+ [0x1F19]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x395, 0x314 },
+ unicodeslot=0x1F19,
+ },
+ [0x1F1A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F18, 0x300 },
+ unicodeslot=0x1F1A,
+ },
+ [0x1F1B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F19, 0x300 },
+ unicodeslot=0x1F1B,
+ },
+ [0x1F1C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F18, 0x301 },
+ unicodeslot=0x1F1C,
+ },
+ [0x1F1D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F19, 0x301 },
+ unicodeslot=0x1F1D,
+ },
+ [0x1F20]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B7, 0x313 },
+ unicodeslot=0x1F20,
+ },
+ [0x1F21]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B7, 0x314 },
+ unicodeslot=0x1F21,
+ },
+ [0x1F22]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F20, 0x300 },
+ unicodeslot=0x1F22,
+ },
+ [0x1F23]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F21, 0x300 },
+ unicodeslot=0x1F23,
+ },
+ [0x1F24]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F20, 0x301 },
+ unicodeslot=0x1F24,
+ },
+ [0x1F25]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F21, 0x301 },
+ unicodeslot=0x1F25,
+ },
+ [0x1F26]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F20, 0x342 },
+ unicodeslot=0x1F26,
+ },
+ [0x1F27]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F21, 0x342 },
+ unicodeslot=0x1F27,
+ },
+ [0x1F28]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x397, 0x313 },
+ unicodeslot=0x1F28,
+ },
+ [0x1F29]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x397, 0x314 },
+ unicodeslot=0x1F29,
+ },
+ [0x1F2A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F28, 0x300 },
+ unicodeslot=0x1F2A,
+ },
+ [0x1F2B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F29, 0x300 },
+ unicodeslot=0x1F2B,
+ },
+ [0x1F2C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F28, 0x301 },
+ unicodeslot=0x1F2C,
+ },
+ [0x1F2D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F29, 0x301 },
+ unicodeslot=0x1F2D,
+ },
+ [0x1F2E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F28, 0x342 },
+ unicodeslot=0x1F2E,
+ },
+ [0x1F2F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F29, 0x342 },
+ unicodeslot=0x1F2F,
+ },
+ [0x1F30]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B9, 0x313 },
+ unicodeslot=0x1F30,
+ },
+ [0x1F31]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B9, 0x314 },
+ unicodeslot=0x1F31,
+ },
+ [0x1F32]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F30, 0x300 },
+ unicodeslot=0x1F32,
+ },
+ [0x1F33]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F31, 0x300 },
+ unicodeslot=0x1F33,
+ },
+ [0x1F34]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F30, 0x301 },
+ unicodeslot=0x1F34,
+ },
+ [0x1F35]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F31, 0x301 },
+ unicodeslot=0x1F35,
+ },
+ [0x1F36]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F30, 0x342 },
+ unicodeslot=0x1F36,
+ },
+ [0x1F37]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F31, 0x342 },
+ unicodeslot=0x1F37,
+ },
+ [0x1F38]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x399, 0x313 },
+ unicodeslot=0x1F38,
+ },
+ [0x1F39]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x399, 0x314 },
+ unicodeslot=0x1F39,
+ },
+ [0x1F3A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F38, 0x300 },
+ unicodeslot=0x1F3A,
+ },
+ [0x1F3B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F39, 0x300 },
+ unicodeslot=0x1F3B,
+ },
+ [0x1F3C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F38, 0x301 },
+ unicodeslot=0x1F3C,
+ },
+ [0x1F3D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F39, 0x301 },
+ unicodeslot=0x1F3D,
+ },
+ [0x1F3E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F38, 0x342 },
+ unicodeslot=0x1F3E,
+ },
+ [0x1F3F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F39, 0x342 },
+ unicodeslot=0x1F3F,
+ },
+ [0x1F40]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3BF, 0x313 },
+ unicodeslot=0x1F40,
+ },
+ [0x1F41]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3BF, 0x314 },
+ unicodeslot=0x1F41,
+ },
+ [0x1F42]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F40, 0x300 },
+ unicodeslot=0x1F42,
+ },
+ [0x1F43]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F41, 0x300 },
+ unicodeslot=0x1F43,
+ },
+ [0x1F44]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F40, 0x301 },
+ unicodeslot=0x1F44,
+ },
+ [0x1F45]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F41, 0x301 },
+ unicodeslot=0x1F45,
+ },
+ [0x1F48]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x39F, 0x313 },
+ unicodeslot=0x1F48,
+ },
+ [0x1F49]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x39F, 0x314 },
+ unicodeslot=0x1F49,
+ },
+ [0x1F4A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F48, 0x300 },
+ unicodeslot=0x1F4A,
+ },
+ [0x1F4B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F49, 0x300 },
+ unicodeslot=0x1F4B,
+ },
+ [0x1F4C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F48, 0x301 },
+ unicodeslot=0x1F4C,
+ },
+ [0x1F4D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F49, 0x301 },
+ unicodeslot=0x1F4D,
+ },
+ [0x1F50]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C5, 0x313 },
+ unicodeslot=0x1F50,
+ },
+ [0x1F51]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C5, 0x314 },
+ unicodeslot=0x1F51,
+ },
+ [0x1F52]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F50, 0x300 },
+ unicodeslot=0x1F52,
+ },
+ [0x1F53]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F51, 0x300 },
+ unicodeslot=0x1F53,
+ },
+ [0x1F54]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F50, 0x301 },
+ unicodeslot=0x1F54,
+ },
+ [0x1F55]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F51, 0x301 },
+ unicodeslot=0x1F55,
+ },
+ [0x1F56]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F50, 0x342 },
+ unicodeslot=0x1F56,
+ },
+ [0x1F57]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F51, 0x342 },
+ unicodeslot=0x1F57,
+ },
+ [0x1F59]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A5, 0x314 },
+ unicodeslot=0x1F59,
+ },
+ [0x1F5B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F59, 0x300 },
+ unicodeslot=0x1F5B,
+ },
+ [0x1F5D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F59, 0x301 },
+ unicodeslot=0x1F5D,
+ },
+ [0x1F5F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F59, 0x342 },
+ unicodeslot=0x1F5F,
+ },
+ [0x1F60]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C9, 0x313 },
+ unicodeslot=0x1F60,
+ },
+ [0x1F61]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C9, 0x314 },
+ unicodeslot=0x1F61,
+ },
+ [0x1F62]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F60, 0x300 },
+ unicodeslot=0x1F62,
+ },
+ [0x1F63]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F61, 0x300 },
+ unicodeslot=0x1F63,
+ },
+ [0x1F64]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F60, 0x301 },
+ unicodeslot=0x1F64,
+ },
+ [0x1F65]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F61, 0x301 },
+ unicodeslot=0x1F65,
+ },
+ [0x1F66]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F60, 0x342 },
+ unicodeslot=0x1F66,
+ },
+ [0x1F67]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F61, 0x342 },
+ unicodeslot=0x1F67,
+ },
+ [0x1F68]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A9, 0x313 },
+ unicodeslot=0x1F68,
+ },
+ [0x1F69]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A9, 0x314 },
+ unicodeslot=0x1F69,
+ },
+ [0x1F6A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F68, 0x300 },
+ unicodeslot=0x1F6A,
+ },
+ [0x1F6B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F69, 0x300 },
+ unicodeslot=0x1F6B,
+ },
+ [0x1F6C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F68, 0x301 },
+ unicodeslot=0x1F6C,
+ },
+ [0x1F6D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F69, 0x301 },
+ unicodeslot=0x1F6D,
+ },
+ [0x1F6E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F68, 0x342 },
+ unicodeslot=0x1F6E,
+ },
+ [0x1F6F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F69, 0x342 },
+ unicodeslot=0x1F6F,
+ },
+ [0x1F70]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B1, 0x300 },
+ unicodeslot=0x1F70,
+ },
+ [0x1F71]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3AC },
+ unicodeslot=0x1F71,
+ },
+ [0x1F72]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B5, 0x300 },
+ unicodeslot=0x1F72,
+ },
+ [0x1F73]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3AD },
+ unicodeslot=0x1F73,
+ },
+ [0x1F74]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B7, 0x300 },
+ unicodeslot=0x1F74,
+ },
+ [0x1F75]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3AE },
+ unicodeslot=0x1F75,
+ },
+ [0x1F76]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B9, 0x300 },
+ unicodeslot=0x1F76,
+ },
+ [0x1F77]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3AF },
+ unicodeslot=0x1F77,
+ },
+ [0x1F78]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3BF, 0x300 },
+ unicodeslot=0x1F78,
+ },
+ [0x1F79]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3CC },
+ unicodeslot=0x1F79,
+ },
+ [0x1F7A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C5, 0x300 },
+ unicodeslot=0x1F7A,
+ },
+ [0x1F7B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3CD },
+ unicodeslot=0x1F7B,
+ },
+ [0x1F7C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C9, 0x300 },
+ unicodeslot=0x1F7C,
+ },
+ [0x1F7D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3CE },
+ unicodeslot=0x1F7D,
+ },
+ [0x1F80]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F00, 0x345 },
+ unicodeslot=0x1F80,
+ },
+ [0x1F81]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F01, 0x345 },
+ unicodeslot=0x1F81,
+ },
+ [0x1F82]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F02, 0x345 },
+ unicodeslot=0x1F82,
+ },
+ [0x1F83]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F03, 0x345 },
+ unicodeslot=0x1F83,
+ },
+ [0x1F84]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F04, 0x345 },
+ unicodeslot=0x1F84,
+ },
+ [0x1F85]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F05, 0x345 },
+ unicodeslot=0x1F85,
+ },
+ [0x1F86]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F06, 0x345 },
+ unicodeslot=0x1F86,
+ },
+ [0x1F87]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F07, 0x345 },
+ unicodeslot=0x1F87,
+ },
+ [0x1F88]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F08, 0x345 },
+ unicodeslot=0x1F88,
+ },
+ [0x1F89]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F09, 0x345 },
+ unicodeslot=0x1F89,
+ },
+ [0x1F8A]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F0A, 0x345 },
+ unicodeslot=0x1F8A,
+ },
+ [0x1F8B]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F0B, 0x345 },
+ unicodeslot=0x1F8B,
+ },
+ [0x1F8C]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F0C, 0x345 },
+ unicodeslot=0x1F8C,
+ },
+ [0x1F8D]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F0D, 0x345 },
+ unicodeslot=0x1F8D,
+ },
+ [0x1F8E]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F0E, 0x345 },
+ unicodeslot=0x1F8E,
+ },
+ [0x1F8F]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F0F, 0x345 },
+ unicodeslot=0x1F8F,
+ },
+ [0x1F90]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F20, 0x345 },
+ unicodeslot=0x1F90,
+ },
+ [0x1F91]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F21, 0x345 },
+ unicodeslot=0x1F91,
+ },
+ [0x1F92]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F22, 0x345 },
+ unicodeslot=0x1F92,
+ },
+ [0x1F93]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F23, 0x345 },
+ unicodeslot=0x1F93,
+ },
+ [0x1F94]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F24, 0x345 },
+ unicodeslot=0x1F94,
+ },
+ [0x1F95]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F25, 0x345 },
+ unicodeslot=0x1F95,
+ },
+ [0x1F96]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F26, 0x345 },
+ unicodeslot=0x1F96,
+ },
+ [0x1F97]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F27, 0x345 },
+ unicodeslot=0x1F97,
+ },
+ [0x1F98]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F28, 0x345 },
+ unicodeslot=0x1F98,
+ },
+ [0x1F99]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F29, 0x345 },
+ unicodeslot=0x1F99,
+ },
+ [0x1F9A]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F2A, 0x345 },
+ unicodeslot=0x1F9A,
+ },
+ [0x1F9B]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F2B, 0x345 },
+ unicodeslot=0x1F9B,
+ },
+ [0x1F9C]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F2C, 0x345 },
+ unicodeslot=0x1F9C,
+ },
+ [0x1F9D]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F2D, 0x345 },
+ unicodeslot=0x1F9D,
+ },
+ [0x1F9E]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F2E, 0x345 },
+ unicodeslot=0x1F9E,
+ },
+ [0x1F9F]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F2F, 0x345 },
+ unicodeslot=0x1F9F,
+ },
+ [0x1FA0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F60, 0x345 },
+ unicodeslot=0x1FA0,
+ },
+ [0x1FA1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F61, 0x345 },
+ unicodeslot=0x1FA1,
+ },
+ [0x1FA2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F62, 0x345 },
+ unicodeslot=0x1FA2,
+ },
+ [0x1FA3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F63, 0x345 },
+ unicodeslot=0x1FA3,
+ },
+ [0x1FA4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F64, 0x345 },
+ unicodeslot=0x1FA4,
+ },
+ [0x1FA5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F65, 0x345 },
+ unicodeslot=0x1FA5,
+ },
+ [0x1FA6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F66, 0x345 },
+ unicodeslot=0x1FA6,
+ },
+ [0x1FA7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F67, 0x345 },
+ unicodeslot=0x1FA7,
+ },
+ [0x1FA8]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F68, 0x345 },
+ unicodeslot=0x1FA8,
+ },
+ [0x1FA9]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F69, 0x345 },
+ unicodeslot=0x1FA9,
+ },
+ [0x1FAA]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F6A, 0x345 },
+ unicodeslot=0x1FAA,
+ },
+ [0x1FAB]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F6B, 0x345 },
+ unicodeslot=0x1FAB,
+ },
+ [0x1FAC]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F6C, 0x345 },
+ unicodeslot=0x1FAC,
+ },
+ [0x1FAD]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F6D, 0x345 },
+ unicodeslot=0x1FAD,
+ },
+ [0x1FAE]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F6E, 0x345 },
+ unicodeslot=0x1FAE,
+ },
+ [0x1FAF]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F6F, 0x345 },
+ unicodeslot=0x1FAF,
+ },
+ [0x1FB0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B1, 0x306 },
+ unicodeslot=0x1FB0,
+ },
+ [0x1FB1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B1, 0x304 },
+ unicodeslot=0x1FB1,
+ },
+ [0x1FB2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F70, 0x345 },
+ unicodeslot=0x1FB2,
+ },
+ [0x1FB3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B1, 0x345 },
+ unicodeslot=0x1FB3,
+ },
+ [0x1FB4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3AC, 0x345 },
+ unicodeslot=0x1FB4,
+ },
+ [0x1FB6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B1, 0x342 },
+ unicodeslot=0x1FB6,
+ },
+ [0x1FB7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1FB6, 0x345 },
+ unicodeslot=0x1FB7,
+ },
+ [0x1FB8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x391, 0x306 },
+ unicodeslot=0x1FB8,
+ },
+ [0x1FB9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x391, 0x304 },
+ unicodeslot=0x1FB9,
+ },
+ [0x1FBA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x391, 0x300 },
+ unicodeslot=0x1FBA,
+ },
+ [0x1FBB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x386 },
+ unicodeslot=0x1FBB,
+ },
+ [0x1FBC]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x391, 0x345 },
+ unicodeslot=0x1FBC,
+ },
+ [0x1FBD]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x20, 0x313 },
+ unicodeslot=0x1FBD,
+ },
+ [0x1FBE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B9 },
+ unicodeslot=0x1FBE,
+ },
+ [0x1FBF]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x20, 0x313 },
+ unicodeslot=0x1FBF,
+ },
+ [0x1FC0]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x20, 0x342 },
+ unicodeslot=0x1FC0,
+ },
+ [0x1FC1]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0xA8, 0x342 },
+ unicodeslot=0x1FC1,
+ },
+ [0x1FC2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F74, 0x345 },
+ unicodeslot=0x1FC2,
+ },
+ [0x1FC3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B7, 0x345 },
+ unicodeslot=0x1FC3,
+ },
+ [0x1FC4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3AE, 0x345 },
+ unicodeslot=0x1FC4,
+ },
+ [0x1FC6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B7, 0x342 },
+ unicodeslot=0x1FC6,
+ },
+ [0x1FC7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1FC6, 0x345 },
+ unicodeslot=0x1FC7,
+ },
+ [0x1FC8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x395, 0x300 },
+ unicodeslot=0x1FC8,
+ },
+ [0x1FC9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x388 },
+ unicodeslot=0x1FC9,
+ },
+ [0x1FCA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x397, 0x300 },
+ unicodeslot=0x1FCA,
+ },
+ [0x1FCB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x389 },
+ unicodeslot=0x1FCB,
+ },
+ [0x1FCC]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x397, 0x345 },
+ unicodeslot=0x1FCC,
+ },
+ [0x1FCD]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x1FBF, 0x300 },
+ unicodeslot=0x1FCD,
+ },
+ [0x1FCE]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x1FBF, 0x301 },
+ unicodeslot=0x1FCE,
+ },
+ [0x1FCF]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x1FBF, 0x342 },
+ unicodeslot=0x1FCF,
+ },
+ [0x1FD0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B9, 0x306 },
+ unicodeslot=0x1FD0,
+ },
+ [0x1FD1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B9, 0x304 },
+ unicodeslot=0x1FD1,
+ },
+ [0x1FD2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3CA, 0x300 },
+ unicodeslot=0x1FD2,
+ },
+ [0x1FD3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x390 },
+ unicodeslot=0x1FD3,
+ },
+ [0x1FD6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B9, 0x342 },
+ unicodeslot=0x1FD6,
+ },
+ [0x1FD7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3CA, 0x342 },
+ unicodeslot=0x1FD7,
+ },
+ [0x1FD8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x399, 0x306 },
+ unicodeslot=0x1FD8,
+ },
+ [0x1FD9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x399, 0x304 },
+ unicodeslot=0x1FD9,
+ },
+ [0x1FDA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x399, 0x300 },
+ unicodeslot=0x1FDA,
+ },
+ [0x1FDB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x38A },
+ unicodeslot=0x1FDB,
+ },
+ [0x1FDD]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x1FFE, 0x300 },
+ unicodeslot=0x1FDD,
+ },
+ [0x1FDE]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x1FFE, 0x301 },
+ unicodeslot=0x1FDE,
+ },
+ [0x1FDF]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x1FFE, 0x342 },
+ unicodeslot=0x1FDF,
+ },
+ [0x1FE0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C5, 0x306 },
+ unicodeslot=0x1FE0,
+ },
+ [0x1FE1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C5, 0x304 },
+ unicodeslot=0x1FE1,
+ },
+ [0x1FE2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3CB, 0x300 },
+ unicodeslot=0x1FE2,
+ },
+ [0x1FE3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3B0 },
+ unicodeslot=0x1FE3,
+ },
+ [0x1FE4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C1, 0x313 },
+ unicodeslot=0x1FE4,
+ },
+ [0x1FE5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C1, 0x314 },
+ unicodeslot=0x1FE5,
+ },
+ [0x1FE6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C5, 0x342 },
+ unicodeslot=0x1FE6,
+ },
+ [0x1FE7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3CB, 0x342 },
+ unicodeslot=0x1FE7,
+ },
+ [0x1FE8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A5, 0x306 },
+ unicodeslot=0x1FE8,
+ },
+ [0x1FE9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A5, 0x304 },
+ unicodeslot=0x1FE9,
+ },
+ [0x1FEA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A5, 0x300 },
+ unicodeslot=0x1FEA,
+ },
+ [0x1FEB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x38E },
+ unicodeslot=0x1FEB,
+ },
+ [0x1FEC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A1, 0x314 },
+ unicodeslot=0x1FEC,
+ },
+ [0x1FED]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0xA8, 0x300 },
+ unicodeslot=0x1FED,
+ },
+ [0x1FEE]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x385 },
+ unicodeslot=0x1FEE,
+ },
+ [0x1FEF]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x60 },
+ unicodeslot=0x1FEF,
+ },
+ [0x1FF2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1F7C, 0x345 },
+ unicodeslot=0x1FF2,
+ },
+ [0x1FF3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C9, 0x345 },
+ unicodeslot=0x1FF3,
+ },
+ [0x1FF4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3CE, 0x345 },
+ unicodeslot=0x1FF4,
+ },
+ [0x1FF6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3C9, 0x342 },
+ unicodeslot=0x1FF6,
+ },
+ [0x1FF7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1FF6, 0x345 },
+ unicodeslot=0x1FF7,
+ },
+ [0x1FF8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x39F, 0x300 },
+ unicodeslot=0x1FF8,
+ },
+ [0x1FF9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x38C },
+ unicodeslot=0x1FF9,
+ },
+ [0x1FFA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A9, 0x300 },
+ unicodeslot=0x1FFA,
+ },
+ [0x1FFB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x38F },
+ unicodeslot=0x1FFB,
+ },
+ [0x1FFC]={
+ category="lt",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A9, 0x345 },
+ unicodeslot=0x1FFC,
+ },
+ [0x1FFD]={
+ category="sk",
+ direction="on",
+ linebreak="bb",
+ specials={ "char", 0xB4 },
+ unicodeslot=0x1FFD,
+ },
+ [0x1FFE]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x20, 0x314 },
+ unicodeslot=0x1FFE,
+ },
+ [0x2000]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ specials={ "char", 0x2002 },
+ unicodeslot=0x2000,
+ },
+ [0x2001]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ specials={ "char", 0x2003 },
+ unicodeslot=0x2001,
+ },
+ [0x2002]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x20 },
+ unicodeslot=0x2002,
+ },
+ [0x2003]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x20 },
+ unicodeslot=0x2003,
+ },
+ [0x2004]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x20 },
+ unicodeslot=0x2004,
+ },
+ [0x2005]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x20 },
+ unicodeslot=0x2005,
+ },
+ [0x2006]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x20 },
+ unicodeslot=0x2006,
+ },
+ [0x2007]={
+ category="zs",
+ direction="ws",
+ linebreak="gl",
+ specials={ "nobreak", 0x20 },
+ unicodeslot=0x2007,
+ },
+ [0x2008]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x20 },
+ unicodeslot=0x2008,
+ },
+ [0x2009]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x20 },
+ unicodeslot=0x2009,
+ },
+ [0x200A]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x20 },
+ unicodeslot=0x200A,
+ },
+ [0x200B]={
+ category="cf",
+ direction="bn",
+ linebreak="zw",
+ unicodeslot=0x200B,
+ },
+ [0x200C]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x200C,
+ },
+ [0x200D]={
+ category="cf",
+ direction="bn",
+ linebreak="zwj",
+ unicodeslot=0x200D,
+ },
+ [0x200E]={
+ category="cf",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x200E,
+ },
+ [0x200F]={
+ category="cf",
+ direction="r",
+ linebreak="cm",
+ unicodeslot=0x200F,
+ },
+ [0x2010]={
+ category="pd",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2010,
+ },
+ [0x2011]={
+ category="pd",
+ direction="on",
+ linebreak="gl",
+ specials={ "nobreak", 0x2010 },
+ unicodeslot=0x2011,
+ },
+ [0x2012]={
+ category="pd",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2012,
+ },
+ [0x2013]={
+ category="pd",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2013,
+ },
+ [0x2014]={
+ category="pd",
+ direction="on",
+ linebreak="b2",
+ unicodeslot=0x2014,
+ },
+ [0x2015]={
+ category="pd",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2015,
+ },
+ [0x2016]={
+ category="po",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2016,
+ },
+ [0x2017]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x20, 0x333 },
+ unicodeslot=0x2017,
+ },
+ [0x2018]={
+ category="pi",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2018,
+ },
+ [0x2019]={
+ category="pf",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2019,
+ },
+ [0x201A]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0x201A,
+ },
+ [0x201B]={
+ category="pi",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x201B,
+ },
+ [0x201C]={
+ category="pi",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x201C,
+ },
+ [0x201D]={
+ category="pf",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x201D,
+ },
+ [0x201E]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0x201E,
+ },
+ [0x201F]={
+ category="pi",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x201F,
+ },
+ [0x2020]={
+ category="po",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2020,
+ },
+ [0x2021]={
+ category="po",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2021,
+ },
+ [0x2022]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2022,
+ },
+ [0x2023]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2023,
+ },
+ [0x2024]={
+ category="po",
+ direction="on",
+ linebreak="in",
+ specials={ "compat", 0x2E },
+ unicodeslot=0x2024,
+ },
+ [0x2025]={
+ category="po",
+ direction="on",
+ linebreak="in",
+ specials={ "compat", 0x2E, 0x2E },
+ unicodeslot=0x2025,
+ },
+ [0x2026]={
+ category="po",
+ direction="on",
+ linebreak="in",
+ specials={ "compat", 0x2E, 0x2E, 0x2E },
+ unicodeslot=0x2026,
+ },
+ [0x2027]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2027,
+ },
+ [0x2028]={
+ category="zl",
+ direction="ws",
+ linebreak="bk",
+ unicodeslot=0x2028,
+ },
+ [0x2029]={
+ category="zp",
+ direction="b",
+ linebreak="bk",
+ unicodeslot=0x2029,
+ },
+ [0x202A]={
+ category="cf",
+ direction="lre",
+ linebreak="cm",
+ unicodeslot=0x202A,
+ },
+ [0x202B]={
+ category="cf",
+ direction="rle",
+ linebreak="cm",
+ unicodeslot=0x202B,
+ },
+ [0x202C]={
+ category="cf",
+ direction="pdf",
+ linebreak="cm",
+ unicodeslot=0x202C,
+ },
+ [0x202D]={
+ category="cf",
+ direction="lro",
+ linebreak="cm",
+ unicodeslot=0x202D,
+ },
+ [0x202E]={
+ category="cf",
+ direction="rlo",
+ linebreak="cm",
+ unicodeslot=0x202E,
+ },
+ [0x202F]={
+ category="zs",
+ direction="cs",
+ linebreak="gl",
+ specials={ "nobreak", 0x20 },
+ unicodeslot=0x202F,
+ },
+ [0x2030]={
+ category="po",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x2030,
+ },
+ [0x2031]={
+ category="po",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x2031,
+ },
+ [0x2032]={
+ category="po",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x2032,
+ },
+ [0x2033]={
+ category="po",
+ direction="et",
+ linebreak="po",
+ specials={ "compat", 0x2032, 0x2032 },
+ unicodeslot=0x2033,
+ },
+ [0x2034]={
+ category="po",
+ direction="et",
+ linebreak="po",
+ specials={ "compat", 0x2032, 0x2032, 0x2032 },
+ unicodeslot=0x2034,
+ },
+ [0x2035]={
+ category="po",
+ direction="on",
+ linebreak="po",
+ unicodeslot=0x2035,
+ },
+ [0x2036]={
+ category="po",
+ direction="on",
+ linebreak="po",
+ specials={ "compat", 0x2035, 0x2035 },
+ unicodeslot=0x2036,
+ },
+ [0x2037]={
+ category="po",
+ direction="on",
+ linebreak="po",
+ specials={ "compat", 0x2035, 0x2035, 0x2035 },
+ unicodeslot=0x2037,
+ },
+ [0x2038]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2038,
+ },
+ [0x2039]={
+ category="pi",
+ direction="on",
+ linebreak="qu",
+ mirror=0x203A,
+ textclass="open",
+ unicodeslot=0x2039,
+ },
+ [0x203A]={
+ category="pf",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2039,
+ textclass="close",
+ unicodeslot=0x203A,
+ },
+ [0x203B]={
+ category="po",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x203B,
+ },
+ [0x203C]={
+ category="po",
+ direction="on",
+ linebreak="ns",
+ specials={ "compat", 0x21, 0x21 },
+ unicodeslot=0x203C,
+ },
+ [0x203D]={
+ category="po",
+ direction="on",
+ linebreak="ns",
+ unicodeslot=0x203D,
+ },
+ [0x203E]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x20, 0x305 },
+ unicodeslot=0x203E,
+ },
+ [0x203F]={
+ category="pc",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x203F,
+ },
+ [0x2040]={
+ category="pc",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2040,
+ },
+ [0x2041]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2041,
+ },
+ [0x2042]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2042,
+ },
+ [0x2043]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2043,
+ },
+ [0x2044]={
+ category="sm",
+ direction="cs",
+ linebreak="is",
+ unicodeslot=0x2044,
+ },
+ [0x2045]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2046,
+ unicodeslot=0x2045,
+ },
+ [0x2046]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2045,
+ unicodeslot=0x2046,
+ },
+ [0x2047]={
+ category="po",
+ direction="on",
+ linebreak="ns",
+ specials={ "compat", 0x3F, 0x3F },
+ unicodeslot=0x2047,
+ },
+ [0x2048]={
+ category="po",
+ direction="on",
+ linebreak="ns",
+ specials={ "compat", 0x3F, 0x21 },
+ unicodeslot=0x2048,
+ },
+ [0x2049]={
+ category="po",
+ direction="on",
+ linebreak="ns",
+ specials={ "compat", 0x21, 0x3F },
+ unicodeslot=0x2049,
+ },
+ [0x204A]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x204A,
+ },
+ [0x204B]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x204B,
+ },
+ [0x204C]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x204C,
+ },
+ [0x204D]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x204D,
+ },
+ [0x204E]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x204E,
+ },
+ [0x204F]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x204F,
+ },
+ [0x2050]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2050,
+ },
+ [0x2051]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2051,
+ },
+ [0x2052]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2052,
+ },
+ [0x2053]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2053,
+ },
+ [0x2054]={
+ category="pc",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2054,
+ },
+ [0x2055]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2055,
+ },
+ [0x2056]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2056,
+ },
+ [0x2057]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x2032, 0x2032, 0x2032, 0x2032 },
+ unicodeslot=0x2057,
+ },
+ [0x2058]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2058,
+ },
+ [0x2059]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2059,
+ },
+ [0x205A]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x205A,
+ },
+ [0x205B]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x205B,
+ },
+ [0x205C]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x205C,
+ },
+ [0x205D]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x205D,
+ },
+ [0x205E]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x205E,
+ },
+ [0x205F]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x20 },
+ unicodeslot=0x205F,
+ },
+ [0x2060]={
+ category="cf",
+ direction="bn",
+ linebreak="wj",
+ unicodeslot=0x2060,
+ },
+ [0x2061]={
+ category="cf",
+ direction="bn",
+ linebreak="al",
+ unicodeslot=0x2061,
+ },
+ [0x2062]={
+ category="cf",
+ direction="bn",
+ linebreak="al",
+ unicodeslot=0x2062,
+ },
+ [0x2063]={
+ category="cf",
+ direction="bn",
+ linebreak="al",
+ unicodeslot=0x2063,
+ },
+ [0x2064]={
+ category="cf",
+ direction="bn",
+ linebreak="al",
+ unicodeslot=0x2064,
+ },
+ [0x2066]={
+ category="cf",
+ direction="lri",
+ linebreak="cm",
+ unicodeslot=0x2066,
+ },
+ [0x2067]={
+ category="cf",
+ direction="rli",
+ linebreak="cm",
+ unicodeslot=0x2067,
+ },
+ [0x2068]={
+ category="cf",
+ direction="fsi",
+ linebreak="cm",
+ unicodeslot=0x2068,
+ },
+ [0x2069]={
+ category="cf",
+ direction="pdi",
+ linebreak="cm",
+ unicodeslot=0x2069,
+ },
+ [0x206A]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x206A,
+ },
+ [0x206B]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x206B,
+ },
+ [0x206C]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x206C,
+ },
+ [0x206D]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x206D,
+ },
+ [0x206E]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x206E,
+ },
+ [0x206F]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x206F,
+ },
+ [0x2070]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ specials={ "super", 0x30 },
+ unicodeslot=0x2070,
+ },
+ [0x2071]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x69 },
+ unicodeslot=0x2071,
+ },
+ [0x2074]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "super", 0x34 },
+ unicodeslot=0x2074,
+ },
+ [0x2075]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ specials={ "super", 0x35 },
+ unicodeslot=0x2075,
+ },
+ [0x2076]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ specials={ "super", 0x36 },
+ unicodeslot=0x2076,
+ },
+ [0x2077]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ specials={ "super", 0x37 },
+ unicodeslot=0x2077,
+ },
+ [0x2078]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ specials={ "super", 0x38 },
+ unicodeslot=0x2078,
+ },
+ [0x2079]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ specials={ "super", 0x39 },
+ unicodeslot=0x2079,
+ },
+ [0x207A]={
+ category="sm",
+ direction="es",
+ linebreak="al",
+ specials={ "super", 0x2B },
+ unicodeslot=0x207A,
+ },
+ [0x207B]={
+ category="sm",
+ direction="es",
+ linebreak="al",
+ specials={ "super", 0x2212 },
+ unicodeslot=0x207B,
+ },
+ [0x207C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "super", 0x3D },
+ unicodeslot=0x207C,
+ },
+ [0x207D]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x207E,
+ specials={ "super", 0x28 },
+ textclass="open",
+ unicodeslot=0x207D,
+ },
+ [0x207E]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x207D,
+ specials={ "super", 0x29 },
+ textclass="close",
+ unicodeslot=0x207E,
+ },
+ [0x207F]={
+ category="ll",
+ direction="l",
+ linebreak="ai",
+ specials={ "super", 0x6E },
+ unicodeslot=0x207F,
+ },
+ [0x2080]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ specials={ "sub", 0x30 },
+ unicodeslot=0x2080,
+ },
+ [0x2081]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "sub", 0x31 },
+ unicodeslot=0x2081,
+ },
+ [0x2082]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "sub", 0x32 },
+ unicodeslot=0x2082,
+ },
+ [0x2083]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "sub", 0x33 },
+ unicodeslot=0x2083,
+ },
+ [0x2084]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "sub", 0x34 },
+ unicodeslot=0x2084,
+ },
+ [0x2085]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ specials={ "sub", 0x35 },
+ unicodeslot=0x2085,
+ },
+ [0x2086]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ specials={ "sub", 0x36 },
+ unicodeslot=0x2086,
+ },
+ [0x2087]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ specials={ "sub", 0x37 },
+ unicodeslot=0x2087,
+ },
+ [0x2088]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ specials={ "sub", 0x38 },
+ unicodeslot=0x2088,
+ },
+ [0x2089]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ specials={ "sub", 0x39 },
+ unicodeslot=0x2089,
+ },
+ [0x208A]={
+ category="sm",
+ direction="es",
+ linebreak="al",
+ specials={ "sub", 0x2B },
+ unicodeslot=0x208A,
+ },
+ [0x208B]={
+ category="sm",
+ direction="es",
+ linebreak="al",
+ specials={ "sub", 0x2212 },
+ unicodeslot=0x208B,
+ },
+ [0x208C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "sub", 0x3D },
+ unicodeslot=0x208C,
+ },
+ [0x208D]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x208E,
+ specials={ "sub", 0x28 },
+ textclass="open",
+ unicodeslot=0x208D,
+ },
+ [0x208E]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x208D,
+ specials={ "sub", 0x29 },
+ textclass="close",
+ unicodeslot=0x208E,
+ },
+ [0x2090]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x61 },
+ unicodeslot=0x2090,
+ },
+ [0x2091]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x65 },
+ unicodeslot=0x2091,
+ },
+ [0x2092]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x6F },
+ unicodeslot=0x2092,
+ },
+ [0x2093]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x78 },
+ unicodeslot=0x2093,
+ },
+ [0x2094]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x259 },
+ unicodeslot=0x2094,
+ },
+ [0x2095]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x68 },
+ unicodeslot=0x2095,
+ },
+ [0x2096]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x6B },
+ unicodeslot=0x2096,
+ },
+ [0x2097]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x6C },
+ unicodeslot=0x2097,
+ },
+ [0x2098]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x6D },
+ unicodeslot=0x2098,
+ },
+ [0x2099]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x6E },
+ unicodeslot=0x2099,
+ },
+ [0x209A]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x70 },
+ unicodeslot=0x209A,
+ },
+ [0x209B]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x73 },
+ unicodeslot=0x209B,
+ },
+ [0x209C]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x74 },
+ unicodeslot=0x209C,
+ },
+ [0x20A0]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A0,
+ },
+ [0x20A1]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A1,
+ },
+ [0x20A2]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A2,
+ },
+ [0x20A3]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A3,
+ },
+ [0x20A4]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A4,
+ },
+ [0x20A5]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A5,
+ },
+ [0x20A6]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A6,
+ },
+ [0x20A7]={
+ category="sc",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x20A7,
+ },
+ [0x20A8]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ specials={ "compat", 0x52, 0x73 },
+ unicodeslot=0x20A8,
+ },
+ [0x20A9]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A9,
+ },
+ [0x20AA]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20AA,
+ },
+ [0x20AB]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20AB,
+ },
+ [0x20AC]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20AC,
+ },
+ [0x20AD]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20AD,
+ },
+ [0x20AE]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20AE,
+ },
+ [0x20AF]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20AF,
+ },
+ [0x20B0]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B0,
+ },
+ [0x20B1]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B1,
+ },
+ [0x20B2]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B2,
+ },
+ [0x20B3]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B3,
+ },
+ [0x20B4]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B4,
+ },
+ [0x20B5]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B5,
+ },
+ [0x20B6]={
+ category="sc",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x20B6,
+ },
+ [0x20B7]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B7,
+ },
+ [0x20B8]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B8,
+ },
+ [0x20B9]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B9,
+ },
+ [0x20BA]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20BA,
+ },
+ [0x20BB]={
+ category="sc",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x20BB,
+ },
+ [0x20BC]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20BC,
+ },
+ [0x20BD]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20BD,
+ },
+ [0x20BE]={
+ category="sc",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x20BE,
+ },
+ [0x20BF]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20BF,
+ },
+ [0x20D0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D0,
+ },
+ [0x20D1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D1,
+ },
+ [0x20D2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D2,
+ },
+ [0x20D3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D3,
+ },
+ [0x20D4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D4,
+ },
+ [0x20D5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D5,
+ },
+ [0x20D6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D6,
+ },
+ [0x20D7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D7,
+ },
+ [0x20D8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D8,
+ },
+ [0x20D9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D9,
+ },
+ [0x20DA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20DA,
+ },
+ [0x20DB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20DB,
+ },
+ [0x20DC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20DC,
+ },
+ [0x20DD]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20DD,
+ },
+ [0x20DE]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20DE,
+ },
+ [0x20DF]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20DF,
+ },
+ [0x20E0]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E0,
+ },
+ [0x20E1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E1,
+ },
+ [0x20E2]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E2,
+ },
+ [0x20E3]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E3,
+ },
+ [0x20E4]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E4,
+ },
+ [0x20E5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E5,
+ },
+ [0x20E6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E6,
+ },
+ [0x20E7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E7,
+ },
+ [0x20E8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E8,
+ },
+ [0x20E9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E9,
+ },
+ [0x20EA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20EA,
+ },
+ [0x20EB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20EB,
+ },
+ [0x20EC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20EC,
+ },
+ [0x20ED]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20ED,
+ },
+ [0x20EE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20EE,
+ },
+ [0x20EF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20EF,
+ },
+ [0x20F0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20F0,
+ },
+ [0x2100]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x61, 0x2F, 0x63 },
+ unicodeslot=0x2100,
+ },
+ [0x2101]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x61, 0x2F, 0x73 },
+ unicodeslot=0x2101,
+ },
+ [0x2102]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x2102,
+ },
+ [0x2103]={
+ category="so",
+ direction="on",
+ linebreak="po",
+ specials={ "compat", 0xB0, 0x43 },
+ unicodeslot=0x2103,
+ },
+ [0x2104]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2104,
+ },
+ [0x2105]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x63, 0x2F, 0x6F },
+ unicodeslot=0x2105,
+ },
+ [0x2106]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x63, 0x2F, 0x75 },
+ unicodeslot=0x2106,
+ },
+ [0x2107]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x190 },
+ unicodeslot=0x2107,
+ },
+ [0x2108]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2108,
+ },
+ [0x2109]={
+ category="so",
+ direction="on",
+ linebreak="po",
+ specials={ "compat", 0xB0, 0x46 },
+ unicodeslot=0x2109,
+ },
+ [0x210A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x210A,
+ },
+ [0x210B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x210B,
+ },
+ [0x210C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x210C,
+ },
+ [0x210D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x210D,
+ },
+ [0x210E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x210E,
+ },
+ [0x210F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x127 },
+ unicodeslot=0x210F,
+ },
+ [0x2110]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x2110,
+ },
+ [0x2111]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x2111,
+ },
+ [0x2112]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x2112,
+ },
+ [0x2113]={
+ category="ll",
+ direction="l",
+ linebreak="ai",
+ specials={ "font", 0x6C },
+ unicodeslot=0x2113,
+ },
+ [0x2114]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2114,
+ },
+ [0x2115]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x2115,
+ },
+ [0x2116]={
+ category="so",
+ direction="on",
+ linebreak="pr",
+ specials={ "compat", 0x4E, 0x6F },
+ unicodeslot=0x2116,
+ },
+ [0x2117]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2117,
+ },
+ [0x2118]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2118,
+ },
+ [0x2119]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x2119,
+ },
+ [0x211A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x211A,
+ },
+ [0x211B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x211B,
+ },
+ [0x211C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x211C,
+ },
+ [0x211D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x211D,
+ },
+ [0x211E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x211E,
+ },
+ [0x211F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x211F,
+ },
+ [0x2120]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ specials={ "super", 0x53, 0x4D },
+ unicodeslot=0x2120,
+ },
+ [0x2121]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x54, 0x45, 0x4C },
+ unicodeslot=0x2121,
+ },
+ [0x2122]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ specials={ "super", 0x54, 0x4D },
+ unicodeslot=0x2122,
+ },
+ [0x2123]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2123,
+ },
+ [0x2124]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x2124,
+ },
+ [0x2125]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2125,
+ },
+ [0x2126]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x3A9 },
+ unicodeslot=0x2126,
+ },
+ [0x2127]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2127,
+ },
+ [0x2128]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x2128,
+ },
+ [0x2129]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2129,
+ },
+ [0x212A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x4B },
+ unicodeslot=0x212A,
+ },
+ [0x212B]={
+ category="lu",
+ direction="l",
+ linebreak="ai",
+ specials={ "char", 0xC5 },
+ unicodeslot=0x212B,
+ },
+ [0x212C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x212C,
+ },
+ [0x212D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x212D,
+ },
+ [0x212E]={
+ category="so",
+ direction="et",
+ linebreak="al",
+ unicodeslot=0x212E,
+ },
+ [0x212F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x212F,
+ },
+ [0x2130]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x2130,
+ },
+ [0x2131]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x2131,
+ },
+ [0x2132]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2132,
+ },
+ [0x2133]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x2133,
+ },
+ [0x2134]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x2134,
+ },
+ [0x2135]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x5D0 },
+ unicodeslot=0x2135,
+ },
+ [0x2136]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x5D1 },
+ unicodeslot=0x2136,
+ },
+ [0x2137]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x5D2 },
+ unicodeslot=0x2137,
+ },
+ [0x2138]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x5D3 },
+ unicodeslot=0x2138,
+ },
+ [0x2139]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x2139,
+ },
+ [0x213A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x213A,
+ },
+ [0x213B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x46, 0x41, 0x58 },
+ unicodeslot=0x213B,
+ },
+ [0x213C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C0 },
+ unicodeslot=0x213C,
+ },
+ [0x213D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B3 },
+ unicodeslot=0x213D,
+ },
+ [0x213E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x393 },
+ unicodeslot=0x213E,
+ },
+ [0x213F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A0 },
+ unicodeslot=0x213F,
+ },
+ [0x2140]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "font", 0x2211 },
+ unicodeslot=0x2140,
+ },
+ [0x2141]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2141,
+ },
+ [0x2142]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2142,
+ },
+ [0x2143]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2143,
+ },
+ [0x2144]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2144,
+ },
+ [0x2145]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x2145,
+ },
+ [0x2146]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x2146,
+ },
+ [0x2147]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x2147,
+ },
+ [0x2148]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x2148,
+ },
+ [0x2149]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x2149,
+ },
+ [0x214A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x214A,
+ },
+ [0x214B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x214B,
+ },
+ [0x214C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x214C,
+ },
+ [0x214D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x214D,
+ },
+ [0x214E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x214E,
+ },
+ [0x214F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x214F,
+ },
+ [0x2150]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x31, 0x2044, 0x37 },
+ unicodeslot=0x2150,
+ },
+ [0x2151]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x31, 0x2044, 0x39 },
+ unicodeslot=0x2151,
+ },
+ [0x2152]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x31, 0x2044, 0x31, 0x30 },
+ unicodeslot=0x2152,
+ },
+ [0x2153]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x31, 0x2044, 0x33 },
+ unicodeslot=0x2153,
+ },
+ [0x2154]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x32, 0x2044, 0x33 },
+ unicodeslot=0x2154,
+ },
+ [0x2155]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x31, 0x2044, 0x35 },
+ unicodeslot=0x2155,
+ },
+ [0x2156]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x32, 0x2044, 0x35 },
+ unicodeslot=0x2156,
+ },
+ [0x2157]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x33, 0x2044, 0x35 },
+ unicodeslot=0x2157,
+ },
+ [0x2158]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x34, 0x2044, 0x35 },
+ unicodeslot=0x2158,
+ },
+ [0x2159]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x31, 0x2044, 0x36 },
+ unicodeslot=0x2159,
+ },
+ [0x215A]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x35, 0x2044, 0x36 },
+ unicodeslot=0x215A,
+ },
+ [0x215B]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x31, 0x2044, 0x38 },
+ unicodeslot=0x215B,
+ },
+ [0x215C]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x33, 0x2044, 0x38 },
+ unicodeslot=0x215C,
+ },
+ [0x215D]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x35, 0x2044, 0x38 },
+ unicodeslot=0x215D,
+ },
+ [0x215E]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x37, 0x2044, 0x38 },
+ unicodeslot=0x215E,
+ },
+ [0x215F]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x31, 0x2044 },
+ unicodeslot=0x215F,
+ },
+ [0x2160]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x49 },
+ unicodeslot=0x2160,
+ },
+ [0x2161]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x49, 0x49 },
+ unicodeslot=0x2161,
+ },
+ [0x2162]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x49, 0x49, 0x49 },
+ unicodeslot=0x2162,
+ },
+ [0x2163]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x49, 0x56 },
+ unicodeslot=0x2163,
+ },
+ [0x2164]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x56 },
+ unicodeslot=0x2164,
+ },
+ [0x2165]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x56, 0x49 },
+ unicodeslot=0x2165,
+ },
+ [0x2166]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x56, 0x49, 0x49 },
+ unicodeslot=0x2166,
+ },
+ [0x2167]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x56, 0x49, 0x49, 0x49 },
+ unicodeslot=0x2167,
+ },
+ [0x2168]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x49, 0x58 },
+ unicodeslot=0x2168,
+ },
+ [0x2169]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x58 },
+ unicodeslot=0x2169,
+ },
+ [0x216A]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x58, 0x49 },
+ unicodeslot=0x216A,
+ },
+ [0x216B]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x58, 0x49, 0x49 },
+ unicodeslot=0x216B,
+ },
+ [0x216C]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x4C },
+ unicodeslot=0x216C,
+ },
+ [0x216D]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x43 },
+ unicodeslot=0x216D,
+ },
+ [0x216E]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x44 },
+ unicodeslot=0x216E,
+ },
+ [0x216F]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x4D },
+ unicodeslot=0x216F,
+ },
+ [0x2170]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x69 },
+ unicodeslot=0x2170,
+ },
+ [0x2171]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x69, 0x69 },
+ unicodeslot=0x2171,
+ },
+ [0x2172]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x69, 0x69, 0x69 },
+ unicodeslot=0x2172,
+ },
+ [0x2173]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x69, 0x76 },
+ unicodeslot=0x2173,
+ },
+ [0x2174]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x76 },
+ unicodeslot=0x2174,
+ },
+ [0x2175]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x76, 0x69 },
+ unicodeslot=0x2175,
+ },
+ [0x2176]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x76, 0x69, 0x69 },
+ unicodeslot=0x2176,
+ },
+ [0x2177]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x76, 0x69, 0x69, 0x69 },
+ unicodeslot=0x2177,
+ },
+ [0x2178]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x69, 0x78 },
+ unicodeslot=0x2178,
+ },
+ [0x2179]={
+ category="nl",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x78 },
+ unicodeslot=0x2179,
+ },
+ [0x217A]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x78, 0x69 },
+ unicodeslot=0x217A,
+ },
+ [0x217B]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x78, 0x69, 0x69 },
+ unicodeslot=0x217B,
+ },
+ [0x217C]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x6C },
+ unicodeslot=0x217C,
+ },
+ [0x217D]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x63 },
+ unicodeslot=0x217D,
+ },
+ [0x217E]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x64 },
+ unicodeslot=0x217E,
+ },
+ [0x217F]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x6D },
+ unicodeslot=0x217F,
+ },
+ [0x2180]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2180,
+ },
+ [0x2181]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2181,
+ },
+ [0x2182]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2182,
+ },
+ [0x2183]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2183,
+ },
+ [0x2184]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2184,
+ },
+ [0x2185]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2185,
+ },
+ [0x2186]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2186,
+ },
+ [0x2187]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2187,
+ },
+ [0x2188]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2188,
+ },
+ [0x2189]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x30, 0x2044, 0x33 },
+ unicodeslot=0x2189,
+ },
+ [0x218A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x218A,
+ },
+ [0x218B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x218B,
+ },
+ [0x2190]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2190,
+ },
+ [0x2191]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2191,
+ },
+ [0x2192]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2192,
+ },
+ [0x2193]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2193,
+ },
+ [0x2194]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2194,
+ },
+ [0x2195]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2195,
+ },
+ [0x2196]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2196,
+ },
+ [0x2197]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2197,
+ },
+ [0x2198]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2198,
+ },
+ [0x2199]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2199,
+ },
+ [0x219A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x2190, 0x338 },
+ unicodeslot=0x219A,
+ },
+ [0x219B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x2192, 0x338 },
+ unicodeslot=0x219B,
+ },
+ [0x219C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x219C,
+ },
+ [0x219D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x219D,
+ },
+ [0x219E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x219E,
+ },
+ [0x219F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x219F,
+ },
+ [0x21A0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21A0,
+ },
+ [0x21A1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21A1,
+ },
+ [0x21A2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21A2,
+ },
+ [0x21A3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21A3,
+ },
+ [0x21A4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21A4,
+ },
+ [0x21A5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21A5,
+ },
+ [0x21A6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21A6,
+ },
+ [0x21A7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21A7,
+ },
+ [0x21A8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21A8,
+ },
+ [0x21A9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21A9,
+ },
+ [0x21AA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21AA,
+ },
+ [0x21AB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21AB,
+ },
+ [0x21AC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21AC,
+ },
+ [0x21AD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21AD,
+ },
+ [0x21AE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x2194, 0x338 },
+ unicodeslot=0x21AE,
+ },
+ [0x21AF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21AF,
+ },
+ [0x21B0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21B0,
+ },
+ [0x21B1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21B1,
+ },
+ [0x21B2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21B2,
+ },
+ [0x21B3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21B3,
+ },
+ [0x21B4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21B4,
+ },
+ [0x21B5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21B5,
+ },
+ [0x21B6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21B6,
+ },
+ [0x21B7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21B7,
+ },
+ [0x21B8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21B8,
+ },
+ [0x21B9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21B9,
+ },
+ [0x21BA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21BA,
+ },
+ [0x21BB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21BB,
+ },
+ [0x21BC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21BC,
+ },
+ [0x21BD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21BD,
+ },
+ [0x21BE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21BE,
+ },
+ [0x21BF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21BF,
+ },
+ [0x21C0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21C0,
+ },
+ [0x21C1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21C1,
+ },
+ [0x21C2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21C2,
+ },
+ [0x21C3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21C3,
+ },
+ [0x21C4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21C4,
+ },
+ [0x21C5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21C5,
+ },
+ [0x21C6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21C6,
+ },
+ [0x21C7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21C7,
+ },
+ [0x21C8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21C8,
+ },
+ [0x21C9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21C9,
+ },
+ [0x21CA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21CA,
+ },
+ [0x21CB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21CB,
+ },
+ [0x21CC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21CC,
+ },
+ [0x21CD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x21D0, 0x338 },
+ unicodeslot=0x21CD,
+ },
+ [0x21CE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x21D4, 0x338 },
+ unicodeslot=0x21CE,
+ },
+ [0x21CF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x21D2, 0x338 },
+ unicodeslot=0x21CF,
+ },
+ [0x21D0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21D0,
+ },
+ [0x21D1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21D1,
+ },
+ [0x21D2]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x21D2,
+ },
+ [0x21D3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21D3,
+ },
+ [0x21D4]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x21D4,
+ },
+ [0x21D5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21D5,
+ },
+ [0x21D6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21D6,
+ },
+ [0x21D7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21D7,
+ },
+ [0x21D8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21D8,
+ },
+ [0x21D9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21D9,
+ },
+ [0x21DA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21DA,
+ },
+ [0x21DB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21DB,
+ },
+ [0x21DC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21DC,
+ },
+ [0x21DD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21DD,
+ },
+ [0x21DE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21DE,
+ },
+ [0x21DF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21DF,
+ },
+ [0x21E0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21E0,
+ },
+ [0x21E1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21E1,
+ },
+ [0x21E2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21E2,
+ },
+ [0x21E3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21E3,
+ },
+ [0x21E4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21E4,
+ },
+ [0x21E5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21E5,
+ },
+ [0x21E6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21E6,
+ },
+ [0x21E7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21E7,
+ },
+ [0x21E8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21E8,
+ },
+ [0x21E9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21E9,
+ },
+ [0x21EA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21EA,
+ },
+ [0x21EB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21EB,
+ },
+ [0x21EC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21EC,
+ },
+ [0x21ED]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21ED,
+ },
+ [0x21EE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21EE,
+ },
+ [0x21EF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21EF,
+ },
+ [0x21F0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F0,
+ },
+ [0x21F1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F1,
+ },
+ [0x21F2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F2,
+ },
+ [0x21F3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F3,
+ },
+ [0x21F4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F4,
+ },
+ [0x21F5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F5,
+ },
+ [0x21F6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F6,
+ },
+ [0x21F7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F7,
+ },
+ [0x21F8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F8,
+ },
+ [0x21F9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F9,
+ },
+ [0x21FA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21FA,
+ },
+ [0x21FB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21FB,
+ },
+ [0x21FC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21FC,
+ },
+ [0x21FD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21FD,
+ },
+ [0x21FE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21FE,
+ },
+ [0x21FF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21FF,
+ },
+ [0x2200]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2200,
+ },
+ [0x2201]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2201,
+ },
+ [0x2202]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2202,
+ },
+ [0x2203]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2203,
+ },
+ [0x2204]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x2203, 0x338 },
+ unicodeslot=0x2204,
+ },
+ [0x2205]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2205,
+ },
+ [0x2206]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2206,
+ },
+ [0x2207]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2207,
+ },
+ [0x2208]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x220B,
+ unicodeslot=0x2208,
+ },
+ [0x2209]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x220C,
+ specials={ "char", 0x2208, 0x338 },
+ unicodeslot=0x2209,
+ },
+ [0x220A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x220D,
+ unicodeslot=0x220A,
+ },
+ [0x220B]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x2208,
+ unicodeslot=0x220B,
+ },
+ [0x220C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2209,
+ specials={ "char", 0x220B, 0x338 },
+ unicodeslot=0x220C,
+ },
+ [0x220D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x220A,
+ unicodeslot=0x220D,
+ },
+ [0x220E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x220E,
+ },
+ [0x220F]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x220F,
+ },
+ [0x2210]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2210,
+ },
+ [0x2211]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2211,
+ },
+ [0x2212]={
+ category="sm",
+ direction="es",
+ linebreak="pr",
+ unicodeslot=0x2212,
+ },
+ [0x2213]={
+ category="sm",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x2213,
+ },
+ [0x2214]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2214,
+ },
+ [0x2215]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x29F5,
+ unicodeslot=0x2215,
+ },
+ [0x2216]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2216,
+ },
+ [0x2217]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2217,
+ },
+ [0x2218]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2218,
+ },
+ [0x2219]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2219,
+ },
+ [0x221A]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x221A,
+ },
+ [0x221B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x221B,
+ },
+ [0x221C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x221C,
+ },
+ [0x221D]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x221D,
+ },
+ [0x221E]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x221E,
+ },
+ [0x221F]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x2BFE,
+ unicodeslot=0x221F,
+ },
+ [0x2220]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x29A3,
+ unicodeslot=0x2220,
+ },
+ [0x2221]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x299B,
+ unicodeslot=0x2221,
+ },
+ [0x2222]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29A0,
+ unicodeslot=0x2222,
+ },
+ [0x2223]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2223,
+ },
+ [0x2224]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AEE,
+ specials={ "char", 0x2223, 0x338 },
+ unicodeslot=0x2224,
+ },
+ [0x2225]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2225,
+ },
+ [0x2226]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x2225, 0x338 },
+ unicodeslot=0x2226,
+ },
+ [0x2227]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2227,
+ },
+ [0x2228]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2228,
+ },
+ [0x2229]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2229,
+ },
+ [0x222A]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x222A,
+ },
+ [0x222B]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x222B,
+ },
+ [0x222C]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x222B, 0x222B },
+ unicodeslot=0x222C,
+ },
+ [0x222D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x222B, 0x222B, 0x222B },
+ unicodeslot=0x222D,
+ },
+ [0x222E]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x222E,
+ },
+ [0x222F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x222E, 0x222E },
+ unicodeslot=0x222F,
+ },
+ [0x2230]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x222E, 0x222E, 0x222E },
+ unicodeslot=0x2230,
+ },
+ [0x2231]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2231,
+ },
+ [0x2232]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2232,
+ },
+ [0x2233]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2233,
+ },
+ [0x2234]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2234,
+ },
+ [0x2235]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2235,
+ },
+ [0x2236]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2236,
+ },
+ [0x2237]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2237,
+ },
+ [0x2238]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2238,
+ },
+ [0x2239]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2239,
+ },
+ [0x223A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x223A,
+ },
+ [0x223B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x223B,
+ },
+ [0x223C]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x223D,
+ unicodeslot=0x223C,
+ },
+ [0x223D]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x223C,
+ unicodeslot=0x223D,
+ },
+ [0x223E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x223E,
+ },
+ [0x223F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x223F,
+ },
+ [0x2240]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2240,
+ },
+ [0x2241]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x223C, 0x338 },
+ unicodeslot=0x2241,
+ },
+ [0x2242]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2242,
+ },
+ [0x2243]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22CD,
+ unicodeslot=0x2243,
+ },
+ [0x2244]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x2243, 0x338 },
+ unicodeslot=0x2244,
+ },
+ [0x2245]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x224C,
+ unicodeslot=0x2245,
+ },
+ [0x2246]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2246,
+ },
+ [0x2247]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x2245, 0x338 },
+ unicodeslot=0x2247,
+ },
+ [0x2248]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2248,
+ },
+ [0x2249]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x2248, 0x338 },
+ unicodeslot=0x2249,
+ },
+ [0x224A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x224A,
+ },
+ [0x224B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x224B,
+ },
+ [0x224C]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x2245,
+ unicodeslot=0x224C,
+ },
+ [0x224D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x224D,
+ },
+ [0x224E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x224E,
+ },
+ [0x224F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x224F,
+ },
+ [0x2250]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2250,
+ },
+ [0x2251]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2251,
+ },
+ [0x2252]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x2253,
+ unicodeslot=0x2252,
+ },
+ [0x2253]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2252,
+ unicodeslot=0x2253,
+ },
+ [0x2254]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2255,
+ unicodeslot=0x2254,
+ },
+ [0x2255]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2254,
+ unicodeslot=0x2255,
+ },
+ [0x2256]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2256,
+ },
+ [0x2257]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2257,
+ },
+ [0x2258]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2258,
+ },
+ [0x2259]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2259,
+ },
+ [0x225A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x225A,
+ },
+ [0x225B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x225B,
+ },
+ [0x225C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x225C,
+ },
+ [0x225D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x225D,
+ },
+ [0x225E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x225E,
+ },
+ [0x225F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x225F,
+ },
+ [0x2260]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ specials={ "char", 0x3D, 0x338 },
+ unicodeslot=0x2260,
+ },
+ [0x2261]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2261,
+ },
+ [0x2262]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x2261, 0x338 },
+ unicodeslot=0x2262,
+ },
+ [0x2263]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2263,
+ },
+ [0x2264]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x2265,
+ unicodeslot=0x2264,
+ },
+ [0x2265]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x2264,
+ unicodeslot=0x2265,
+ },
+ [0x2266]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x2267,
+ unicodeslot=0x2266,
+ },
+ [0x2267]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x2266,
+ unicodeslot=0x2267,
+ },
+ [0x2268]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2269,
+ unicodeslot=0x2268,
+ },
+ [0x2269]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2268,
+ unicodeslot=0x2269,
+ },
+ [0x226A]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x226B,
+ unicodeslot=0x226A,
+ },
+ [0x226B]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x226A,
+ unicodeslot=0x226B,
+ },
+ [0x226C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x226C,
+ },
+ [0x226D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x224D, 0x338 },
+ unicodeslot=0x226D,
+ },
+ [0x226E]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x226F,
+ specials={ "char", 0x3C, 0x338 },
+ unicodeslot=0x226E,
+ },
+ [0x226F]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x226E,
+ specials={ "char", 0x3E, 0x338 },
+ unicodeslot=0x226F,
+ },
+ [0x2270]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2271,
+ specials={ "char", 0x2264, 0x338 },
+ unicodeslot=0x2270,
+ },
+ [0x2271]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2270,
+ specials={ "char", 0x2265, 0x338 },
+ unicodeslot=0x2271,
+ },
+ [0x2272]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2273,
+ unicodeslot=0x2272,
+ },
+ [0x2273]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2272,
+ unicodeslot=0x2273,
+ },
+ [0x2274]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2275,
+ specials={ "char", 0x2272, 0x338 },
+ unicodeslot=0x2274,
+ },
+ [0x2275]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2274,
+ specials={ "char", 0x2273, 0x338 },
+ unicodeslot=0x2275,
+ },
+ [0x2276]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2277,
+ unicodeslot=0x2276,
+ },
+ [0x2277]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2276,
+ unicodeslot=0x2277,
+ },
+ [0x2278]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2279,
+ specials={ "char", 0x2276, 0x338 },
+ unicodeslot=0x2278,
+ },
+ [0x2279]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2278,
+ specials={ "char", 0x2277, 0x338 },
+ unicodeslot=0x2279,
+ },
+ [0x227A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x227B,
+ unicodeslot=0x227A,
+ },
+ [0x227B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x227A,
+ unicodeslot=0x227B,
+ },
+ [0x227C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x227D,
+ unicodeslot=0x227C,
+ },
+ [0x227D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x227C,
+ unicodeslot=0x227D,
+ },
+ [0x227E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x227F,
+ unicodeslot=0x227E,
+ },
+ [0x227F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x227E,
+ unicodeslot=0x227F,
+ },
+ [0x2280]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2281,
+ specials={ "char", 0x227A, 0x338 },
+ unicodeslot=0x2280,
+ },
+ [0x2281]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2280,
+ specials={ "char", 0x227B, 0x338 },
+ unicodeslot=0x2281,
+ },
+ [0x2282]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x2283,
+ unicodeslot=0x2282,
+ },
+ [0x2283]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x2282,
+ unicodeslot=0x2283,
+ },
+ [0x2284]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2285,
+ specials={ "char", 0x2282, 0x338 },
+ unicodeslot=0x2284,
+ },
+ [0x2285]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2284,
+ specials={ "char", 0x2283, 0x338 },
+ unicodeslot=0x2285,
+ },
+ [0x2286]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x2287,
+ unicodeslot=0x2286,
+ },
+ [0x2287]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ mirror=0x2286,
+ unicodeslot=0x2287,
+ },
+ [0x2288]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2289,
+ specials={ "char", 0x2286, 0x338 },
+ unicodeslot=0x2288,
+ },
+ [0x2289]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2288,
+ specials={ "char", 0x2287, 0x338 },
+ unicodeslot=0x2289,
+ },
+ [0x228A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x228B,
+ unicodeslot=0x228A,
+ },
+ [0x228B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x228A,
+ unicodeslot=0x228B,
+ },
+ [0x228C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x228C,
+ },
+ [0x228D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x228D,
+ },
+ [0x228E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x228E,
+ },
+ [0x228F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2290,
+ unicodeslot=0x228F,
+ },
+ [0x2290]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x228F,
+ unicodeslot=0x2290,
+ },
+ [0x2291]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2292,
+ unicodeslot=0x2291,
+ },
+ [0x2292]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2291,
+ unicodeslot=0x2292,
+ },
+ [0x2293]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2293,
+ },
+ [0x2294]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2294,
+ },
+ [0x2295]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2295,
+ },
+ [0x2296]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2296,
+ },
+ [0x2297]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2297,
+ },
+ [0x2298]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29B8,
+ unicodeslot=0x2298,
+ },
+ [0x2299]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2299,
+ },
+ [0x229A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x229A,
+ },
+ [0x229B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x229B,
+ },
+ [0x229C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x229C,
+ },
+ [0x229D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x229D,
+ },
+ [0x229E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x229E,
+ },
+ [0x229F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x229F,
+ },
+ [0x22A0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22A0,
+ },
+ [0x22A1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22A1,
+ },
+ [0x22A2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22A3,
+ unicodeslot=0x22A2,
+ },
+ [0x22A3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22A2,
+ unicodeslot=0x22A3,
+ },
+ [0x22A4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22A4,
+ },
+ [0x22A5]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x22A5,
+ },
+ [0x22A6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ADE,
+ unicodeslot=0x22A6,
+ },
+ [0x22A7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22A7,
+ },
+ [0x22A8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AE4,
+ unicodeslot=0x22A8,
+ },
+ [0x22A9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AE3,
+ unicodeslot=0x22A9,
+ },
+ [0x22AA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22AA,
+ },
+ [0x22AB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AE5,
+ unicodeslot=0x22AB,
+ },
+ [0x22AC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x22A2, 0x338 },
+ unicodeslot=0x22AC,
+ },
+ [0x22AD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x22A8, 0x338 },
+ unicodeslot=0x22AD,
+ },
+ [0x22AE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x22A9, 0x338 },
+ unicodeslot=0x22AE,
+ },
+ [0x22AF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x22AB, 0x338 },
+ unicodeslot=0x22AF,
+ },
+ [0x22B0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B1,
+ unicodeslot=0x22B0,
+ },
+ [0x22B1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B0,
+ unicodeslot=0x22B1,
+ },
+ [0x22B2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B3,
+ unicodeslot=0x22B2,
+ },
+ [0x22B3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B2,
+ unicodeslot=0x22B3,
+ },
+ [0x22B4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B5,
+ unicodeslot=0x22B4,
+ },
+ [0x22B5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B4,
+ unicodeslot=0x22B5,
+ },
+ [0x22B6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B7,
+ unicodeslot=0x22B6,
+ },
+ [0x22B7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B6,
+ unicodeslot=0x22B7,
+ },
+ [0x22B8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27DC,
+ unicodeslot=0x22B8,
+ },
+ [0x22B9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22B9,
+ },
+ [0x22BA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22BA,
+ },
+ [0x22BB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22BB,
+ },
+ [0x22BC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22BC,
+ },
+ [0x22BD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22BD,
+ },
+ [0x22BE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22BE,
+ },
+ [0x22BF]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x22BF,
+ },
+ [0x22C0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22C0,
+ },
+ [0x22C1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22C1,
+ },
+ [0x22C2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22C2,
+ },
+ [0x22C3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22C3,
+ },
+ [0x22C4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22C4,
+ },
+ [0x22C5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22C5,
+ },
+ [0x22C6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22C6,
+ },
+ [0x22C7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22C7,
+ },
+ [0x22C8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22C8,
+ },
+ [0x22C9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22CA,
+ unicodeslot=0x22C9,
+ },
+ [0x22CA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22C9,
+ unicodeslot=0x22CA,
+ },
+ [0x22CB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22CC,
+ unicodeslot=0x22CB,
+ },
+ [0x22CC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22CB,
+ unicodeslot=0x22CC,
+ },
+ [0x22CD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2243,
+ unicodeslot=0x22CD,
+ },
+ [0x22CE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22CE,
+ },
+ [0x22CF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22CF,
+ },
+ [0x22D0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22D1,
+ unicodeslot=0x22D0,
+ },
+ [0x22D1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22D0,
+ unicodeslot=0x22D1,
+ },
+ [0x22D2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22D2,
+ },
+ [0x22D3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22D3,
+ },
+ [0x22D4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22D4,
+ },
+ [0x22D5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22D5,
+ },
+ [0x22D6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22D7,
+ unicodeslot=0x22D6,
+ },
+ [0x22D7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22D6,
+ unicodeslot=0x22D7,
+ },
+ [0x22D8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22D9,
+ unicodeslot=0x22D8,
+ },
+ [0x22D9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22D8,
+ unicodeslot=0x22D9,
+ },
+ [0x22DA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22DB,
+ unicodeslot=0x22DA,
+ },
+ [0x22DB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22DA,
+ unicodeslot=0x22DB,
+ },
+ [0x22DC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22DD,
+ unicodeslot=0x22DC,
+ },
+ [0x22DD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22DC,
+ unicodeslot=0x22DD,
+ },
+ [0x22DE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22DF,
+ unicodeslot=0x22DE,
+ },
+ [0x22DF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22DE,
+ unicodeslot=0x22DF,
+ },
+ [0x22E0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22E1,
+ specials={ "char", 0x227C, 0x338 },
+ unicodeslot=0x22E0,
+ },
+ [0x22E1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22E0,
+ specials={ "char", 0x227D, 0x338 },
+ unicodeslot=0x22E1,
+ },
+ [0x22E2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22E3,
+ specials={ "char", 0x2291, 0x338 },
+ unicodeslot=0x22E2,
+ },
+ [0x22E3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22E2,
+ specials={ "char", 0x2292, 0x338 },
+ unicodeslot=0x22E3,
+ },
+ [0x22E4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22E5,
+ unicodeslot=0x22E4,
+ },
+ [0x22E5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22E4,
+ unicodeslot=0x22E5,
+ },
+ [0x22E6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22E7,
+ unicodeslot=0x22E6,
+ },
+ [0x22E7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22E6,
+ unicodeslot=0x22E7,
+ },
+ [0x22E8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22E9,
+ unicodeslot=0x22E8,
+ },
+ [0x22E9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22E8,
+ unicodeslot=0x22E9,
+ },
+ [0x22EA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22EB,
+ specials={ "char", 0x22B2, 0x338 },
+ unicodeslot=0x22EA,
+ },
+ [0x22EB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22EA,
+ specials={ "char", 0x22B3, 0x338 },
+ unicodeslot=0x22EB,
+ },
+ [0x22EC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22ED,
+ specials={ "char", 0x22B4, 0x338 },
+ unicodeslot=0x22EC,
+ },
+ [0x22ED]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22EC,
+ specials={ "char", 0x22B5, 0x338 },
+ unicodeslot=0x22ED,
+ },
+ [0x22EE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22EE,
+ },
+ [0x22EF]={
+ category="sm",
+ direction="on",
+ linebreak="in",
+ unicodeslot=0x22EF,
+ },
+ [0x22F0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22F1,
+ unicodeslot=0x22F0,
+ },
+ [0x22F1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22F0,
+ unicodeslot=0x22F1,
+ },
+ [0x22F2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22FA,
+ unicodeslot=0x22F2,
+ },
+ [0x22F3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22FB,
+ unicodeslot=0x22F3,
+ },
+ [0x22F4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22FC,
+ unicodeslot=0x22F4,
+ },
+ [0x22F5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22F5,
+ },
+ [0x22F6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22FD,
+ unicodeslot=0x22F6,
+ },
+ [0x22F7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22FE,
+ unicodeslot=0x22F7,
+ },
+ [0x22F8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22F8,
+ },
+ [0x22F9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22F9,
+ },
+ [0x22FA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22F2,
+ unicodeslot=0x22FA,
+ },
+ [0x22FB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22F3,
+ unicodeslot=0x22FB,
+ },
+ [0x22FC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22F4,
+ unicodeslot=0x22FC,
+ },
+ [0x22FD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22F6,
+ unicodeslot=0x22FD,
+ },
+ [0x22FE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22F7,
+ unicodeslot=0x22FE,
+ },
+ [0x22FF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22FF,
+ },
+ [0x2300]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2300,
+ },
+ [0x2301]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2301,
+ },
+ [0x2302]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2302,
+ },
+ [0x2303]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2303,
+ },
+ [0x2304]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2304,
+ },
+ [0x2305]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2305,
+ },
+ [0x2306]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2306,
+ },
+ [0x2307]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2307,
+ },
+ [0x2308]={
+ category="sm",
+ direction="on",
+ linebreak="op",
+ mirror=0x2309,
+ unicodeslot=0x2308,
+ },
+ [0x2309]={
+ category="sm",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2308,
+ unicodeslot=0x2309,
+ },
+ [0x230A]={
+ category="sm",
+ direction="on",
+ linebreak="op",
+ mirror=0x230B,
+ unicodeslot=0x230A,
+ },
+ [0x230B]={
+ category="sm",
+ direction="on",
+ linebreak="cl",
+ mirror=0x230A,
+ unicodeslot=0x230B,
+ },
+ [0x230C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x230C,
+ },
+ [0x230D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x230D,
+ },
+ [0x230E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x230E,
+ },
+ [0x230F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x230F,
+ },
+ [0x2310]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2310,
+ },
+ [0x2311]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2311,
+ },
+ [0x2312]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2312,
+ },
+ [0x2313]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2313,
+ },
+ [0x2314]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2314,
+ },
+ [0x2315]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2315,
+ },
+ [0x2316]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2316,
+ },
+ [0x2317]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2317,
+ },
+ [0x2318]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2318,
+ },
+ [0x2319]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2319,
+ },
+ [0x231A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x231A,
+ },
+ [0x231B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x231B,
+ },
+ [0x231C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x231C,
+ },
+ [0x231D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x231D,
+ },
+ [0x231E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x231E,
+ },
+ [0x231F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x231F,
+ },
+ [0x2320]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2320,
+ },
+ [0x2321]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2321,
+ },
+ [0x2322]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2322,
+ },
+ [0x2323]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2323,
+ },
+ [0x2324]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2324,
+ },
+ [0x2325]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2325,
+ },
+ [0x2326]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2326,
+ },
+ [0x2327]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2327,
+ },
+ [0x2328]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2328,
+ },
+ [0x2329]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x232A,
+ specials={ "char", 0x3008 },
+ unicodeslot=0x2329,
+ },
+ [0x232A]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2329,
+ specials={ "char", 0x3009 },
+ unicodeslot=0x232A,
+ },
+ [0x232B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x232B,
+ },
+ [0x232C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x232C,
+ },
+ [0x232D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x232D,
+ },
+ [0x232E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x232E,
+ },
+ [0x232F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x232F,
+ },
+ [0x2330]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2330,
+ },
+ [0x2331]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2331,
+ },
+ [0x2332]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2332,
+ },
+ [0x2333]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2333,
+ },
+ [0x2334]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2334,
+ },
+ [0x2335]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2335,
+ },
+ [0x2336]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2336,
+ },
+ [0x2337]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2337,
+ },
+ [0x2338]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2338,
+ },
+ [0x2339]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2339,
+ },
+ [0x233A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x233A,
+ },
+ [0x233B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x233B,
+ },
+ [0x233C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x233C,
+ },
+ [0x233D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x233D,
+ },
+ [0x233E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x233E,
+ },
+ [0x233F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x233F,
+ },
+ [0x2340]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2340,
+ },
+ [0x2341]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2341,
+ },
+ [0x2342]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2342,
+ },
+ [0x2343]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2343,
+ },
+ [0x2344]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2344,
+ },
+ [0x2345]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2345,
+ },
+ [0x2346]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2346,
+ },
+ [0x2347]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2347,
+ },
+ [0x2348]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2348,
+ },
+ [0x2349]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2349,
+ },
+ [0x234A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234A,
+ },
+ [0x234B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234B,
+ },
+ [0x234C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234C,
+ },
+ [0x234D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234D,
+ },
+ [0x234E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234E,
+ },
+ [0x234F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234F,
+ },
+ [0x2350]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2350,
+ },
+ [0x2351]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2351,
+ },
+ [0x2352]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2352,
+ },
+ [0x2353]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2353,
+ },
+ [0x2354]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2354,
+ },
+ [0x2355]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2355,
+ },
+ [0x2356]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2356,
+ },
+ [0x2357]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2357,
+ },
+ [0x2358]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2358,
+ },
+ [0x2359]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2359,
+ },
+ [0x235A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235A,
+ },
+ [0x235B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235B,
+ },
+ [0x235C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235C,
+ },
+ [0x235D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235D,
+ },
+ [0x235E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235E,
+ },
+ [0x235F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235F,
+ },
+ [0x2360]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2360,
+ },
+ [0x2361]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2361,
+ },
+ [0x2362]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2362,
+ },
+ [0x2363]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2363,
+ },
+ [0x2364]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2364,
+ },
+ [0x2365]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2365,
+ },
+ [0x2366]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2366,
+ },
+ [0x2367]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2367,
+ },
+ [0x2368]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2368,
+ },
+ [0x2369]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2369,
+ },
+ [0x236A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236A,
+ },
+ [0x236B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236B,
+ },
+ [0x236C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236C,
+ },
+ [0x236D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236D,
+ },
+ [0x236E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236E,
+ },
+ [0x236F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236F,
+ },
+ [0x2370]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2370,
+ },
+ [0x2371]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2371,
+ },
+ [0x2372]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2372,
+ },
+ [0x2373]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2373,
+ },
+ [0x2374]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2374,
+ },
+ [0x2375]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2375,
+ },
+ [0x2376]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2376,
+ },
+ [0x2377]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2377,
+ },
+ [0x2378]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2378,
+ },
+ [0x2379]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2379,
+ },
+ [0x237A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x237A,
+ },
+ [0x237B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x237B,
+ },
+ [0x237C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x237C,
+ },
+ [0x237D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x237D,
+ },
+ [0x237E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x237E,
+ },
+ [0x237F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x237F,
+ },
+ [0x2380]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2380,
+ },
+ [0x2381]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2381,
+ },
+ [0x2382]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2382,
+ },
+ [0x2383]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2383,
+ },
+ [0x2384]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2384,
+ },
+ [0x2385]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2385,
+ },
+ [0x2386]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2386,
+ },
+ [0x2387]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2387,
+ },
+ [0x2388]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2388,
+ },
+ [0x2389]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2389,
+ },
+ [0x238A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x238A,
+ },
+ [0x238B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x238B,
+ },
+ [0x238C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x238C,
+ },
+ [0x238D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x238D,
+ },
+ [0x238E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x238E,
+ },
+ [0x238F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x238F,
+ },
+ [0x2390]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2390,
+ },
+ [0x2391]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2391,
+ },
+ [0x2392]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2392,
+ },
+ [0x2393]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2393,
+ },
+ [0x2394]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2394,
+ },
+ [0x2395]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2395,
+ },
+ [0x2396]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2396,
+ },
+ [0x2397]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2397,
+ },
+ [0x2398]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2398,
+ },
+ [0x2399]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2399,
+ },
+ [0x239A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x239A,
+ },
+ [0x239B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x239B,
+ },
+ [0x239C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x239C,
+ },
+ [0x239D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x239D,
+ },
+ [0x239E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x239E,
+ },
+ [0x239F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x239F,
+ },
+ [0x23A0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A0,
+ },
+ [0x23A1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A1,
+ },
+ [0x23A2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A2,
+ },
+ [0x23A3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A3,
+ },
+ [0x23A4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A4,
+ },
+ [0x23A5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A5,
+ },
+ [0x23A6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A6,
+ },
+ [0x23A7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A7,
+ },
+ [0x23A8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A8,
+ },
+ [0x23A9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A9,
+ },
+ [0x23AA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23AA,
+ },
+ [0x23AB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23AB,
+ },
+ [0x23AC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23AC,
+ },
+ [0x23AD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23AD,
+ },
+ [0x23AE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23AE,
+ },
+ [0x23AF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23AF,
+ },
+ [0x23B0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B0,
+ },
+ [0x23B1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B1,
+ },
+ [0x23B2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B2,
+ },
+ [0x23B3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B3,
+ },
+ [0x23B4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B4,
+ },
+ [0x23B5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B5,
+ },
+ [0x23B6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B6,
+ },
+ [0x23B7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B7,
+ },
+ [0x23B8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B8,
+ },
+ [0x23B9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B9,
+ },
+ [0x23BA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23BA,
+ },
+ [0x23BB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23BB,
+ },
+ [0x23BC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23BC,
+ },
+ [0x23BD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23BD,
+ },
+ [0x23BE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23BE,
+ },
+ [0x23BF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23BF,
+ },
+ [0x23C0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C0,
+ },
+ [0x23C1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C1,
+ },
+ [0x23C2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C2,
+ },
+ [0x23C3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C3,
+ },
+ [0x23C4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C4,
+ },
+ [0x23C5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C5,
+ },
+ [0x23C6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C6,
+ },
+ [0x23C7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C7,
+ },
+ [0x23C8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C8,
+ },
+ [0x23C9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C9,
+ },
+ [0x23CA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23CA,
+ },
+ [0x23CB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23CB,
+ },
+ [0x23CC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23CC,
+ },
+ [0x23CD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23CD,
+ },
+ [0x23CE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23CE,
+ },
+ [0x23CF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23CF,
+ },
+ [0x23D0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D0,
+ },
+ [0x23D1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D1,
+ },
+ [0x23D2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D2,
+ },
+ [0x23D3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D3,
+ },
+ [0x23D4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D4,
+ },
+ [0x23D5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D5,
+ },
+ [0x23D6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D6,
+ },
+ [0x23D7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D7,
+ },
+ [0x23D8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D8,
+ },
+ [0x23D9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D9,
+ },
+ [0x23DA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23DA,
+ },
+ [0x23DB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23DB,
+ },
+ [0x23DC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23DC,
+ },
+ [0x23DD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23DD,
+ },
+ [0x23DE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23DE,
+ },
+ [0x23DF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23DF,
+ },
+ [0x23E0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E0,
+ },
+ [0x23E1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E1,
+ },
+ [0x23E2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E2,
+ },
+ [0x23E3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E3,
+ },
+ [0x23E4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E4,
+ },
+ [0x23E5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E5,
+ },
+ [0x23E6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E6,
+ },
+ [0x23E7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E7,
+ },
+ [0x23E8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E8,
+ },
+ [0x23E9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E9,
+ },
+ [0x23EA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23EA,
+ },
+ [0x23EB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23EB,
+ },
+ [0x23EC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23EC,
+ },
+ [0x23ED]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23ED,
+ },
+ [0x23EE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23EE,
+ },
+ [0x23EF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23EF,
+ },
+ [0x23F0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x23F0,
+ },
+ [0x23F1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x23F1,
+ },
+ [0x23F2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x23F2,
+ },
+ [0x23F3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x23F3,
+ },
+ [0x23F4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23F4,
+ },
+ [0x23F5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23F5,
+ },
+ [0x23F6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23F6,
+ },
+ [0x23F7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23F7,
+ },
+ [0x23F8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23F8,
+ },
+ [0x23F9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23F9,
+ },
+ [0x23FA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23FA,
+ },
+ [0x23FB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23FB,
+ },
+ [0x23FC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23FC,
+ },
+ [0x23FD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23FD,
+ },
+ [0x23FE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23FE,
+ },
+ [0x23FF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23FF,
+ },
+ [0x2400]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2400,
+ },
+ [0x2401]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2401,
+ },
+ [0x2402]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2402,
+ },
+ [0x2403]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2403,
+ },
+ [0x2404]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2404,
+ },
+ [0x2405]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2405,
+ },
+ [0x2406]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2406,
+ },
+ [0x2407]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2407,
+ },
+ [0x2408]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2408,
+ },
+ [0x2409]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2409,
+ },
+ [0x240A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x240A,
+ },
+ [0x240B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x240B,
+ },
+ [0x240C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x240C,
+ },
+ [0x240D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x240D,
+ },
+ [0x240E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x240E,
+ },
+ [0x240F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x240F,
+ },
+ [0x2410]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2410,
+ },
+ [0x2411]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2411,
+ },
+ [0x2412]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2412,
+ },
+ [0x2413]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2413,
+ },
+ [0x2414]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2414,
+ },
+ [0x2415]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2415,
+ },
+ [0x2416]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2416,
+ },
+ [0x2417]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2417,
+ },
+ [0x2418]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2418,
+ },
+ [0x2419]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2419,
+ },
+ [0x241A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x241A,
+ },
+ [0x241B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x241B,
+ },
+ [0x241C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x241C,
+ },
+ [0x241D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x241D,
+ },
+ [0x241E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x241E,
+ },
+ [0x241F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x241F,
+ },
+ [0x2420]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2420,
+ },
+ [0x2421]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2421,
+ },
+ [0x2422]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2422,
+ },
+ [0x2423]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2423,
+ },
+ [0x2424]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2424,
+ },
+ [0x2425]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2425,
+ },
+ [0x2426]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2426,
+ },
+ [0x2440]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2440,
+ },
+ [0x2441]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2441,
+ },
+ [0x2442]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2442,
+ },
+ [0x2443]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2443,
+ },
+ [0x2444]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2444,
+ },
+ [0x2445]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2445,
+ },
+ [0x2446]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2446,
+ },
+ [0x2447]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2447,
+ },
+ [0x2448]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2448,
+ },
+ [0x2449]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2449,
+ },
+ [0x244A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x244A,
+ },
+ [0x2460]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x31 },
+ unicodeslot=0x2460,
+ },
+ [0x2461]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x32 },
+ unicodeslot=0x2461,
+ },
+ [0x2462]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x33 },
+ unicodeslot=0x2462,
+ },
+ [0x2463]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x34 },
+ unicodeslot=0x2463,
+ },
+ [0x2464]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x35 },
+ unicodeslot=0x2464,
+ },
+ [0x2465]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x36 },
+ unicodeslot=0x2465,
+ },
+ [0x2466]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x37 },
+ unicodeslot=0x2466,
+ },
+ [0x2467]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x38 },
+ unicodeslot=0x2467,
+ },
+ [0x2468]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x39 },
+ unicodeslot=0x2468,
+ },
+ [0x2469]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x31, 0x30 },
+ unicodeslot=0x2469,
+ },
+ [0x246A]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x31, 0x31 },
+ unicodeslot=0x246A,
+ },
+ [0x246B]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x31, 0x32 },
+ unicodeslot=0x246B,
+ },
+ [0x246C]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x31, 0x33 },
+ unicodeslot=0x246C,
+ },
+ [0x246D]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x31, 0x34 },
+ unicodeslot=0x246D,
+ },
+ [0x246E]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x31, 0x35 },
+ unicodeslot=0x246E,
+ },
+ [0x246F]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x31, 0x36 },
+ unicodeslot=0x246F,
+ },
+ [0x2470]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x31, 0x37 },
+ unicodeslot=0x2470,
+ },
+ [0x2471]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x31, 0x38 },
+ unicodeslot=0x2471,
+ },
+ [0x2472]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x31, 0x39 },
+ unicodeslot=0x2472,
+ },
+ [0x2473]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x32, 0x30 },
+ unicodeslot=0x2473,
+ },
+ [0x2474]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x31, 0x29 },
+ unicodeslot=0x2474,
+ },
+ [0x2475]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x32, 0x29 },
+ unicodeslot=0x2475,
+ },
+ [0x2476]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x33, 0x29 },
+ unicodeslot=0x2476,
+ },
+ [0x2477]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x34, 0x29 },
+ unicodeslot=0x2477,
+ },
+ [0x2478]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x35, 0x29 },
+ unicodeslot=0x2478,
+ },
+ [0x2479]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x36, 0x29 },
+ unicodeslot=0x2479,
+ },
+ [0x247A]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x37, 0x29 },
+ unicodeslot=0x247A,
+ },
+ [0x247B]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x38, 0x29 },
+ unicodeslot=0x247B,
+ },
+ [0x247C]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x39, 0x29 },
+ unicodeslot=0x247C,
+ },
+ [0x247D]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x31, 0x30, 0x29 },
+ unicodeslot=0x247D,
+ },
+ [0x247E]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x31, 0x31, 0x29 },
+ unicodeslot=0x247E,
+ },
+ [0x247F]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x31, 0x32, 0x29 },
+ unicodeslot=0x247F,
+ },
+ [0x2480]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x31, 0x33, 0x29 },
+ unicodeslot=0x2480,
+ },
+ [0x2481]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x31, 0x34, 0x29 },
+ unicodeslot=0x2481,
+ },
+ [0x2482]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x31, 0x35, 0x29 },
+ unicodeslot=0x2482,
+ },
+ [0x2483]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x31, 0x36, 0x29 },
+ unicodeslot=0x2483,
+ },
+ [0x2484]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x31, 0x37, 0x29 },
+ unicodeslot=0x2484,
+ },
+ [0x2485]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x31, 0x38, 0x29 },
+ unicodeslot=0x2485,
+ },
+ [0x2486]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x31, 0x39, 0x29 },
+ unicodeslot=0x2486,
+ },
+ [0x2487]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x32, 0x30, 0x29 },
+ unicodeslot=0x2487,
+ },
+ [0x2488]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x31, 0x2E },
+ unicodeslot=0x2488,
+ },
+ [0x2489]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x32, 0x2E },
+ unicodeslot=0x2489,
+ },
+ [0x248A]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x33, 0x2E },
+ unicodeslot=0x248A,
+ },
+ [0x248B]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x34, 0x2E },
+ unicodeslot=0x248B,
+ },
+ [0x248C]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x35, 0x2E },
+ unicodeslot=0x248C,
+ },
+ [0x248D]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x36, 0x2E },
+ unicodeslot=0x248D,
+ },
+ [0x248E]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x37, 0x2E },
+ unicodeslot=0x248E,
+ },
+ [0x248F]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x38, 0x2E },
+ unicodeslot=0x248F,
+ },
+ [0x2490]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x39, 0x2E },
+ unicodeslot=0x2490,
+ },
+ [0x2491]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x31, 0x30, 0x2E },
+ unicodeslot=0x2491,
+ },
+ [0x2492]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x31, 0x31, 0x2E },
+ unicodeslot=0x2492,
+ },
+ [0x2493]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x31, 0x32, 0x2E },
+ unicodeslot=0x2493,
+ },
+ [0x2494]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x31, 0x33, 0x2E },
+ unicodeslot=0x2494,
+ },
+ [0x2495]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x31, 0x34, 0x2E },
+ unicodeslot=0x2495,
+ },
+ [0x2496]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x31, 0x35, 0x2E },
+ unicodeslot=0x2496,
+ },
+ [0x2497]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x31, 0x36, 0x2E },
+ unicodeslot=0x2497,
+ },
+ [0x2498]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x31, 0x37, 0x2E },
+ unicodeslot=0x2498,
+ },
+ [0x2499]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x31, 0x38, 0x2E },
+ unicodeslot=0x2499,
+ },
+ [0x249A]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x31, 0x39, 0x2E },
+ unicodeslot=0x249A,
+ },
+ [0x249B]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x32, 0x30, 0x2E },
+ unicodeslot=0x249B,
+ },
+ [0x249C]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x61, 0x29 },
+ unicodeslot=0x249C,
+ },
+ [0x249D]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x62, 0x29 },
+ unicodeslot=0x249D,
+ },
+ [0x249E]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x63, 0x29 },
+ unicodeslot=0x249E,
+ },
+ [0x249F]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x64, 0x29 },
+ unicodeslot=0x249F,
+ },
+ [0x24A0]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x65, 0x29 },
+ unicodeslot=0x24A0,
+ },
+ [0x24A1]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x66, 0x29 },
+ unicodeslot=0x24A1,
+ },
+ [0x24A2]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x67, 0x29 },
+ unicodeslot=0x24A2,
+ },
+ [0x24A3]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x68, 0x29 },
+ unicodeslot=0x24A3,
+ },
+ [0x24A4]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x69, 0x29 },
+ unicodeslot=0x24A4,
+ },
+ [0x24A5]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x6A, 0x29 },
+ unicodeslot=0x24A5,
+ },
+ [0x24A6]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x6B, 0x29 },
+ unicodeslot=0x24A6,
+ },
+ [0x24A7]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x6C, 0x29 },
+ unicodeslot=0x24A7,
+ },
+ [0x24A8]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x6D, 0x29 },
+ unicodeslot=0x24A8,
+ },
+ [0x24A9]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x6E, 0x29 },
+ unicodeslot=0x24A9,
+ },
+ [0x24AA]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x6F, 0x29 },
+ unicodeslot=0x24AA,
+ },
+ [0x24AB]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x70, 0x29 },
+ unicodeslot=0x24AB,
+ },
+ [0x24AC]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x71, 0x29 },
+ unicodeslot=0x24AC,
+ },
+ [0x24AD]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x72, 0x29 },
+ unicodeslot=0x24AD,
+ },
+ [0x24AE]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x73, 0x29 },
+ unicodeslot=0x24AE,
+ },
+ [0x24AF]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x74, 0x29 },
+ unicodeslot=0x24AF,
+ },
+ [0x24B0]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x75, 0x29 },
+ unicodeslot=0x24B0,
+ },
+ [0x24B1]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x76, 0x29 },
+ unicodeslot=0x24B1,
+ },
+ [0x24B2]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x77, 0x29 },
+ unicodeslot=0x24B2,
+ },
+ [0x24B3]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x78, 0x29 },
+ unicodeslot=0x24B3,
+ },
+ [0x24B4]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x79, 0x29 },
+ unicodeslot=0x24B4,
+ },
+ [0x24B5]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x7A, 0x29 },
+ unicodeslot=0x24B5,
+ },
+ [0x24B6]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x41 },
+ unicodeslot=0x24B6,
+ },
+ [0x24B7]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x42 },
+ unicodeslot=0x24B7,
+ },
+ [0x24B8]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x43 },
+ unicodeslot=0x24B8,
+ },
+ [0x24B9]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x44 },
+ unicodeslot=0x24B9,
+ },
+ [0x24BA]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x45 },
+ unicodeslot=0x24BA,
+ },
+ [0x24BB]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x46 },
+ unicodeslot=0x24BB,
+ },
+ [0x24BC]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x47 },
+ unicodeslot=0x24BC,
+ },
+ [0x24BD]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x48 },
+ unicodeslot=0x24BD,
+ },
+ [0x24BE]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x49 },
+ unicodeslot=0x24BE,
+ },
+ [0x24BF]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x4A },
+ unicodeslot=0x24BF,
+ },
+ [0x24C0]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x4B },
+ unicodeslot=0x24C0,
+ },
+ [0x24C1]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x4C },
+ unicodeslot=0x24C1,
+ },
+ [0x24C2]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x4D },
+ unicodeslot=0x24C2,
+ },
+ [0x24C3]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x4E },
+ unicodeslot=0x24C3,
+ },
+ [0x24C4]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x4F },
+ unicodeslot=0x24C4,
+ },
+ [0x24C5]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x50 },
+ unicodeslot=0x24C5,
+ },
+ [0x24C6]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x51 },
+ unicodeslot=0x24C6,
+ },
+ [0x24C7]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x52 },
+ unicodeslot=0x24C7,
+ },
+ [0x24C8]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x53 },
+ unicodeslot=0x24C8,
+ },
+ [0x24C9]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x54 },
+ unicodeslot=0x24C9,
+ },
+ [0x24CA]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x55 },
+ unicodeslot=0x24CA,
+ },
+ [0x24CB]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x56 },
+ unicodeslot=0x24CB,
+ },
+ [0x24CC]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x57 },
+ unicodeslot=0x24CC,
+ },
+ [0x24CD]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x58 },
+ unicodeslot=0x24CD,
+ },
+ [0x24CE]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x59 },
+ unicodeslot=0x24CE,
+ },
+ [0x24CF]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x5A },
+ unicodeslot=0x24CF,
+ },
+ [0x24D0]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x61 },
+ unicodeslot=0x24D0,
+ },
+ [0x24D1]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x62 },
+ unicodeslot=0x24D1,
+ },
+ [0x24D2]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x63 },
+ unicodeslot=0x24D2,
+ },
+ [0x24D3]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x64 },
+ unicodeslot=0x24D3,
+ },
+ [0x24D4]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x65 },
+ unicodeslot=0x24D4,
+ },
+ [0x24D5]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x66 },
+ unicodeslot=0x24D5,
+ },
+ [0x24D6]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x67 },
+ unicodeslot=0x24D6,
+ },
+ [0x24D7]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x68 },
+ unicodeslot=0x24D7,
+ },
+ [0x24D8]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x69 },
+ unicodeslot=0x24D8,
+ },
+ [0x24D9]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x6A },
+ unicodeslot=0x24D9,
+ },
+ [0x24DA]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x6B },
+ unicodeslot=0x24DA,
+ },
+ [0x24DB]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x6C },
+ unicodeslot=0x24DB,
+ },
+ [0x24DC]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x6D },
+ unicodeslot=0x24DC,
+ },
+ [0x24DD]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x6E },
+ unicodeslot=0x24DD,
+ },
+ [0x24DE]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x6F },
+ unicodeslot=0x24DE,
+ },
+ [0x24DF]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x70 },
+ unicodeslot=0x24DF,
+ },
+ [0x24E0]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x71 },
+ unicodeslot=0x24E0,
+ },
+ [0x24E1]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x72 },
+ unicodeslot=0x24E1,
+ },
+ [0x24E2]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x73 },
+ unicodeslot=0x24E2,
+ },
+ [0x24E3]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x74 },
+ unicodeslot=0x24E3,
+ },
+ [0x24E4]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x75 },
+ unicodeslot=0x24E4,
+ },
+ [0x24E5]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x76 },
+ unicodeslot=0x24E5,
+ },
+ [0x24E6]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x77 },
+ unicodeslot=0x24E6,
+ },
+ [0x24E7]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x78 },
+ unicodeslot=0x24E7,
+ },
+ [0x24E8]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x79 },
+ unicodeslot=0x24E8,
+ },
+ [0x24E9]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x7A },
+ unicodeslot=0x24E9,
+ },
+ [0x24EA]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x30 },
+ unicodeslot=0x24EA,
+ },
+ [0x24EB]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24EB,
+ },
+ [0x24EC]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24EC,
+ },
+ [0x24ED]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24ED,
+ },
+ [0x24EE]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24EE,
+ },
+ [0x24EF]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24EF,
+ },
+ [0x24F0]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F0,
+ },
+ [0x24F1]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F1,
+ },
+ [0x24F2]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F2,
+ },
+ [0x24F3]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F3,
+ },
+ [0x24F4]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F4,
+ },
+ [0x24F5]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F5,
+ },
+ [0x24F6]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F6,
+ },
+ [0x24F7]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F7,
+ },
+ [0x24F8]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F8,
+ },
+ [0x24F9]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F9,
+ },
+ [0x24FA]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24FA,
+ },
+ [0x24FB]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24FB,
+ },
+ [0x24FC]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24FC,
+ },
+ [0x24FD]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24FD,
+ },
+ [0x24FE]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24FE,
+ },
+ [0x24FF]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x24FF,
+ },
+ [0x2500]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2500,
+ },
+ [0x2501]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2501,
+ },
+ [0x2502]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2502,
+ },
+ [0x2503]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2503,
+ },
+ [0x2504]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2504,
+ },
+ [0x2505]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2505,
+ },
+ [0x2506]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2506,
+ },
+ [0x2507]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2507,
+ },
+ [0x2508]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2508,
+ },
+ [0x2509]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2509,
+ },
+ [0x250A]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x250A,
+ },
+ [0x250B]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x250B,
+ },
+ [0x250C]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x250C,
+ },
+ [0x250D]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x250D,
+ },
+ [0x250E]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x250E,
+ },
+ [0x250F]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x250F,
+ },
+ [0x2510]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2510,
+ },
+ [0x2511]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2511,
+ },
+ [0x2512]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2512,
+ },
+ [0x2513]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2513,
+ },
+ [0x2514]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2514,
+ },
+ [0x2515]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2515,
+ },
+ [0x2516]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2516,
+ },
+ [0x2517]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2517,
+ },
+ [0x2518]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2518,
+ },
+ [0x2519]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2519,
+ },
+ [0x251A]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x251A,
+ },
+ [0x251B]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x251B,
+ },
+ [0x251C]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x251C,
+ },
+ [0x251D]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x251D,
+ },
+ [0x251E]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x251E,
+ },
+ [0x251F]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x251F,
+ },
+ [0x2520]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2520,
+ },
+ [0x2521]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2521,
+ },
+ [0x2522]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2522,
+ },
+ [0x2523]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2523,
+ },
+ [0x2524]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2524,
+ },
+ [0x2525]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2525,
+ },
+ [0x2526]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2526,
+ },
+ [0x2527]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2527,
+ },
+ [0x2528]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2528,
+ },
+ [0x2529]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2529,
+ },
+ [0x252A]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x252A,
+ },
+ [0x252B]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x252B,
+ },
+ [0x252C]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x252C,
+ },
+ [0x252D]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x252D,
+ },
+ [0x252E]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x252E,
+ },
+ [0x252F]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x252F,
+ },
+ [0x2530]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2530,
+ },
+ [0x2531]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2531,
+ },
+ [0x2532]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2532,
+ },
+ [0x2533]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2533,
+ },
+ [0x2534]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2534,
+ },
+ [0x2535]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2535,
+ },
+ [0x2536]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2536,
+ },
+ [0x2537]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2537,
+ },
+ [0x2538]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2538,
+ },
+ [0x2539]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2539,
+ },
+ [0x253A]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x253A,
+ },
+ [0x253B]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x253B,
+ },
+ [0x253C]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x253C,
+ },
+ [0x253D]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x253D,
+ },
+ [0x253E]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x253E,
+ },
+ [0x253F]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x253F,
+ },
+ [0x2540]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2540,
+ },
+ [0x2541]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2541,
+ },
+ [0x2542]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2542,
+ },
+ [0x2543]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2543,
+ },
+ [0x2544]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2544,
+ },
+ [0x2545]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2545,
+ },
+ [0x2546]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2546,
+ },
+ [0x2547]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2547,
+ },
+ [0x2548]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2548,
+ },
+ [0x2549]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2549,
+ },
+ [0x254A]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x254A,
+ },
+ [0x254B]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x254B,
+ },
+ [0x254C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x254C,
+ },
+ [0x254D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x254D,
+ },
+ [0x254E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x254E,
+ },
+ [0x254F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x254F,
+ },
+ [0x2550]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2550,
+ },
+ [0x2551]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2551,
+ },
+ [0x2552]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2552,
+ },
+ [0x2553]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2553,
+ },
+ [0x2554]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2554,
+ },
+ [0x2555]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2555,
+ },
+ [0x2556]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2556,
+ },
+ [0x2557]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2557,
+ },
+ [0x2558]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2558,
+ },
+ [0x2559]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2559,
+ },
+ [0x255A]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x255A,
+ },
+ [0x255B]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x255B,
+ },
+ [0x255C]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x255C,
+ },
+ [0x255D]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x255D,
+ },
+ [0x255E]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x255E,
+ },
+ [0x255F]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x255F,
+ },
+ [0x2560]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2560,
+ },
+ [0x2561]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2561,
+ },
+ [0x2562]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2562,
+ },
+ [0x2563]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2563,
+ },
+ [0x2564]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2564,
+ },
+ [0x2565]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2565,
+ },
+ [0x2566]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2566,
+ },
+ [0x2567]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2567,
+ },
+ [0x2568]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2568,
+ },
+ [0x2569]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2569,
+ },
+ [0x256A]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x256A,
+ },
+ [0x256B]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x256B,
+ },
+ [0x256C]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x256C,
+ },
+ [0x256D]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x256D,
+ },
+ [0x256E]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x256E,
+ },
+ [0x256F]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x256F,
+ },
+ [0x2570]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2570,
+ },
+ [0x2571]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2571,
+ },
+ [0x2572]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2572,
+ },
+ [0x2573]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2573,
+ },
+ [0x2574]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2574,
+ },
+ [0x2575]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2575,
+ },
+ [0x2576]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2576,
+ },
+ [0x2577]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2577,
+ },
+ [0x2578]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2578,
+ },
+ [0x2579]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2579,
+ },
+ [0x257A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x257A,
+ },
+ [0x257B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x257B,
+ },
+ [0x257C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x257C,
+ },
+ [0x257D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x257D,
+ },
+ [0x257E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x257E,
+ },
+ [0x257F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x257F,
+ },
+ [0x2580]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2580,
+ },
+ [0x2581]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2581,
+ },
+ [0x2582]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2582,
+ },
+ [0x2583]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2583,
+ },
+ [0x2584]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2584,
+ },
+ [0x2585]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2585,
+ },
+ [0x2586]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2586,
+ },
+ [0x2587]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2587,
+ },
+ [0x2588]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2588,
+ },
+ [0x2589]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2589,
+ },
+ [0x258A]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x258A,
+ },
+ [0x258B]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x258B,
+ },
+ [0x258C]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x258C,
+ },
+ [0x258D]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x258D,
+ },
+ [0x258E]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x258E,
+ },
+ [0x258F]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x258F,
+ },
+ [0x2590]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2590,
+ },
+ [0x2591]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2591,
+ },
+ [0x2592]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2592,
+ },
+ [0x2593]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2593,
+ },
+ [0x2594]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2594,
+ },
+ [0x2595]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2595,
+ },
+ [0x2596]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2596,
+ },
+ [0x2597]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2597,
+ },
+ [0x2598]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2598,
+ },
+ [0x2599]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2599,
+ },
+ [0x259A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x259A,
+ },
+ [0x259B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x259B,
+ },
+ [0x259C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x259C,
+ },
+ [0x259D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x259D,
+ },
+ [0x259E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x259E,
+ },
+ [0x259F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x259F,
+ },
+ [0x25A0]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A0,
+ },
+ [0x25A1]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A1,
+ },
+ [0x25A2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25A2,
+ },
+ [0x25A3]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A3,
+ },
+ [0x25A4]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A4,
+ },
+ [0x25A5]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A5,
+ },
+ [0x25A6]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A6,
+ },
+ [0x25A7]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A7,
+ },
+ [0x25A8]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A8,
+ },
+ [0x25A9]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A9,
+ },
+ [0x25AA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25AA,
+ },
+ [0x25AB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25AB,
+ },
+ [0x25AC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25AC,
+ },
+ [0x25AD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25AD,
+ },
+ [0x25AE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25AE,
+ },
+ [0x25AF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25AF,
+ },
+ [0x25B0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25B0,
+ },
+ [0x25B1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25B1,
+ },
+ [0x25B2]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25B2,
+ },
+ [0x25B3]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25B3,
+ },
+ [0x25B4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25B4,
+ },
+ [0x25B5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25B5,
+ },
+ [0x25B6]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25B6,
+ },
+ [0x25B7]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25B7,
+ },
+ [0x25B8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25B8,
+ },
+ [0x25B9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25B9,
+ },
+ [0x25BA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25BA,
+ },
+ [0x25BB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25BB,
+ },
+ [0x25BC]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25BC,
+ },
+ [0x25BD]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25BD,
+ },
+ [0x25BE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25BE,
+ },
+ [0x25BF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25BF,
+ },
+ [0x25C0]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25C0,
+ },
+ [0x25C1]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25C1,
+ },
+ [0x25C2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25C2,
+ },
+ [0x25C3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25C3,
+ },
+ [0x25C4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25C4,
+ },
+ [0x25C5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25C5,
+ },
+ [0x25C6]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25C6,
+ },
+ [0x25C7]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25C7,
+ },
+ [0x25C8]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25C8,
+ },
+ [0x25C9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25C9,
+ },
+ [0x25CA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25CA,
+ },
+ [0x25CB]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25CB,
+ },
+ [0x25CC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25CC,
+ },
+ [0x25CD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25CD,
+ },
+ [0x25CE]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25CE,
+ },
+ [0x25CF]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25CF,
+ },
+ [0x25D0]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25D0,
+ },
+ [0x25D1]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25D1,
+ },
+ [0x25D2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D2,
+ },
+ [0x25D3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D3,
+ },
+ [0x25D4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D4,
+ },
+ [0x25D5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D5,
+ },
+ [0x25D6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D6,
+ },
+ [0x25D7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D7,
+ },
+ [0x25D8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D8,
+ },
+ [0x25D9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D9,
+ },
+ [0x25DA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25DA,
+ },
+ [0x25DB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25DB,
+ },
+ [0x25DC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25DC,
+ },
+ [0x25DD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25DD,
+ },
+ [0x25DE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25DE,
+ },
+ [0x25DF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25DF,
+ },
+ [0x25E0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25E0,
+ },
+ [0x25E1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25E1,
+ },
+ [0x25E2]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25E2,
+ },
+ [0x25E3]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25E3,
+ },
+ [0x25E4]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25E4,
+ },
+ [0x25E5]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25E5,
+ },
+ [0x25E6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25E6,
+ },
+ [0x25E7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25E7,
+ },
+ [0x25E8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25E8,
+ },
+ [0x25E9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25E9,
+ },
+ [0x25EA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25EA,
+ },
+ [0x25EB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25EB,
+ },
+ [0x25EC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25EC,
+ },
+ [0x25ED]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25ED,
+ },
+ [0x25EE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25EE,
+ },
+ [0x25EF]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25EF,
+ },
+ [0x25F0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F0,
+ },
+ [0x25F1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F1,
+ },
+ [0x25F2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F2,
+ },
+ [0x25F3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F3,
+ },
+ [0x25F4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F4,
+ },
+ [0x25F5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F5,
+ },
+ [0x25F6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F6,
+ },
+ [0x25F7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F7,
+ },
+ [0x25F8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F8,
+ },
+ [0x25F9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F9,
+ },
+ [0x25FA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25FA,
+ },
+ [0x25FB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25FB,
+ },
+ [0x25FC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25FC,
+ },
+ [0x25FD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25FD,
+ },
+ [0x25FE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25FE,
+ },
+ [0x25FF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25FF,
+ },
+ [0x2600]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2600,
+ },
+ [0x2601]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2601,
+ },
+ [0x2602]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2602,
+ },
+ [0x2603]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2603,
+ },
+ [0x2604]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2604,
+ },
+ [0x2605]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2605,
+ },
+ [0x2606]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2606,
+ },
+ [0x2607]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2607,
+ },
+ [0x2608]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2608,
+ },
+ [0x2609]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2609,
+ },
+ [0x260A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x260A,
+ },
+ [0x260B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x260B,
+ },
+ [0x260C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x260C,
+ },
+ [0x260D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x260D,
+ },
+ [0x260E]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x260E,
+ },
+ [0x260F]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x260F,
+ },
+ [0x2610]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2610,
+ },
+ [0x2611]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2611,
+ },
+ [0x2612]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2612,
+ },
+ [0x2613]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2613,
+ },
+ [0x2614]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2614,
+ },
+ [0x2615]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2615,
+ },
+ [0x2616]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2616,
+ },
+ [0x2617]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2617,
+ },
+ [0x2618]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2618,
+ },
+ [0x2619]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2619,
+ },
+ [0x261A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x261A,
+ },
+ [0x261B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x261B,
+ },
+ [0x261C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x261C,
+ },
+ [0x261D]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x261D,
+ },
+ [0x261E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x261E,
+ },
+ [0x261F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x261F,
+ },
+ [0x2620]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2620,
+ },
+ [0x2621]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2621,
+ },
+ [0x2622]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2622,
+ },
+ [0x2623]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2623,
+ },
+ [0x2624]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2624,
+ },
+ [0x2625]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2625,
+ },
+ [0x2626]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2626,
+ },
+ [0x2627]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2627,
+ },
+ [0x2628]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2628,
+ },
+ [0x2629]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2629,
+ },
+ [0x262A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x262A,
+ },
+ [0x262B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x262B,
+ },
+ [0x262C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x262C,
+ },
+ [0x262D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x262D,
+ },
+ [0x262E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x262E,
+ },
+ [0x262F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x262F,
+ },
+ [0x2630]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2630,
+ },
+ [0x2631]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2631,
+ },
+ [0x2632]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2632,
+ },
+ [0x2633]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2633,
+ },
+ [0x2634]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2634,
+ },
+ [0x2635]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2635,
+ },
+ [0x2636]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2636,
+ },
+ [0x2637]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2637,
+ },
+ [0x2638]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2638,
+ },
+ [0x2639]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2639,
+ },
+ [0x263A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x263A,
+ },
+ [0x263B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x263B,
+ },
+ [0x263C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x263C,
+ },
+ [0x263D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x263D,
+ },
+ [0x263E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x263E,
+ },
+ [0x263F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x263F,
+ },
+ [0x2640]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2640,
+ },
+ [0x2641]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2641,
+ },
+ [0x2642]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2642,
+ },
+ [0x2643]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2643,
+ },
+ [0x2644]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2644,
+ },
+ [0x2645]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2645,
+ },
+ [0x2646]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2646,
+ },
+ [0x2647]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2647,
+ },
+ [0x2648]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2648,
+ },
+ [0x2649]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2649,
+ },
+ [0x264A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x264A,
+ },
+ [0x264B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x264B,
+ },
+ [0x264C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x264C,
+ },
+ [0x264D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x264D,
+ },
+ [0x264E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x264E,
+ },
+ [0x264F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x264F,
+ },
+ [0x2650]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2650,
+ },
+ [0x2651]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2651,
+ },
+ [0x2652]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2652,
+ },
+ [0x2653]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2653,
+ },
+ [0x2654]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2654,
+ },
+ [0x2655]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2655,
+ },
+ [0x2656]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2656,
+ },
+ [0x2657]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2657,
+ },
+ [0x2658]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2658,
+ },
+ [0x2659]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2659,
+ },
+ [0x265A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x265A,
+ },
+ [0x265B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x265B,
+ },
+ [0x265C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x265C,
+ },
+ [0x265D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x265D,
+ },
+ [0x265E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x265E,
+ },
+ [0x265F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x265F,
+ },
+ [0x2660]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2660,
+ },
+ [0x2661]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2661,
+ },
+ [0x2662]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2662,
+ },
+ [0x2663]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2663,
+ },
+ [0x2664]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2664,
+ },
+ [0x2665]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2665,
+ },
+ [0x2666]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2666,
+ },
+ [0x2667]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2667,
+ },
+ [0x2668]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2668,
+ },
+ [0x2669]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2669,
+ },
+ [0x266A]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x266A,
+ },
+ [0x266B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x266B,
+ },
+ [0x266C]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x266C,
+ },
+ [0x266D]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x266D,
+ },
+ [0x266E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x266E,
+ },
+ [0x266F]={
+ category="sm",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x266F,
+ },
+ [0x2670]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2670,
+ },
+ [0x2671]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2671,
+ },
+ [0x2672]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2672,
+ },
+ [0x2673]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2673,
+ },
+ [0x2674]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2674,
+ },
+ [0x2675]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2675,
+ },
+ [0x2676]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2676,
+ },
+ [0x2677]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2677,
+ },
+ [0x2678]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2678,
+ },
+ [0x2679]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2679,
+ },
+ [0x267A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x267A,
+ },
+ [0x267B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x267B,
+ },
+ [0x267C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x267C,
+ },
+ [0x267D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x267D,
+ },
+ [0x267E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x267E,
+ },
+ [0x267F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x267F,
+ },
+ [0x2680]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2680,
+ },
+ [0x2681]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2681,
+ },
+ [0x2682]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2682,
+ },
+ [0x2683]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2683,
+ },
+ [0x2684]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2684,
+ },
+ [0x2685]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2685,
+ },
+ [0x2686]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2686,
+ },
+ [0x2687]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2687,
+ },
+ [0x2688]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2688,
+ },
+ [0x2689]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2689,
+ },
+ [0x268A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x268A,
+ },
+ [0x268B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x268B,
+ },
+ [0x268C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x268C,
+ },
+ [0x268D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x268D,
+ },
+ [0x268E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x268E,
+ },
+ [0x268F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x268F,
+ },
+ [0x2690]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2690,
+ },
+ [0x2691]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2691,
+ },
+ [0x2692]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2692,
+ },
+ [0x2693]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2693,
+ },
+ [0x2694]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2694,
+ },
+ [0x2695]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2695,
+ },
+ [0x2696]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2696,
+ },
+ [0x2697]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2697,
+ },
+ [0x2698]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2698,
+ },
+ [0x2699]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2699,
+ },
+ [0x269A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x269A,
+ },
+ [0x269B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x269B,
+ },
+ [0x269C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x269C,
+ },
+ [0x269D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x269D,
+ },
+ [0x269E]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x269E,
+ },
+ [0x269F]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x269F,
+ },
+ [0x26A0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A0,
+ },
+ [0x26A1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A1,
+ },
+ [0x26A2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A2,
+ },
+ [0x26A3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A3,
+ },
+ [0x26A4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A4,
+ },
+ [0x26A5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A5,
+ },
+ [0x26A6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A6,
+ },
+ [0x26A7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A7,
+ },
+ [0x26A8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A8,
+ },
+ [0x26A9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A9,
+ },
+ [0x26AA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26AA,
+ },
+ [0x26AB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26AB,
+ },
+ [0x26AC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x26AC,
+ },
+ [0x26AD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26AD,
+ },
+ [0x26AE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26AE,
+ },
+ [0x26AF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26AF,
+ },
+ [0x26B0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B0,
+ },
+ [0x26B1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B1,
+ },
+ [0x26B2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B2,
+ },
+ [0x26B3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B3,
+ },
+ [0x26B4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B4,
+ },
+ [0x26B5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B5,
+ },
+ [0x26B6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B6,
+ },
+ [0x26B7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B7,
+ },
+ [0x26B8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B8,
+ },
+ [0x26B9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B9,
+ },
+ [0x26BA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26BA,
+ },
+ [0x26BB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26BB,
+ },
+ [0x26BC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26BC,
+ },
+ [0x26BD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26BD,
+ },
+ [0x26BE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26BE,
+ },
+ [0x26BF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26BF,
+ },
+ [0x26C0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C0,
+ },
+ [0x26C1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C1,
+ },
+ [0x26C2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C2,
+ },
+ [0x26C3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C3,
+ },
+ [0x26C4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C4,
+ },
+ [0x26C5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C5,
+ },
+ [0x26C6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C6,
+ },
+ [0x26C7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C7,
+ },
+ [0x26C8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C8,
+ },
+ [0x26C9]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26C9,
+ },
+ [0x26CA]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26CA,
+ },
+ [0x26CB]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26CB,
+ },
+ [0x26CC]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26CC,
+ },
+ [0x26CD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26CD,
+ },
+ [0x26CE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26CE,
+ },
+ [0x26CF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26CF,
+ },
+ [0x26D0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26D0,
+ },
+ [0x26D1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26D1,
+ },
+ [0x26D2]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26D2,
+ },
+ [0x26D3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26D3,
+ },
+ [0x26D4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26D4,
+ },
+ [0x26D5]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26D5,
+ },
+ [0x26D6]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26D6,
+ },
+ [0x26D7]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26D7,
+ },
+ [0x26D8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26D8,
+ },
+ [0x26D9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26D9,
+ },
+ [0x26DA]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26DA,
+ },
+ [0x26DB]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26DB,
+ },
+ [0x26DC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26DC,
+ },
+ [0x26DD]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26DD,
+ },
+ [0x26DE]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26DE,
+ },
+ [0x26DF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26DF,
+ },
+ [0x26E0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26E0,
+ },
+ [0x26E1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26E1,
+ },
+ [0x26E2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26E2,
+ },
+ [0x26E3]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26E3,
+ },
+ [0x26E4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26E4,
+ },
+ [0x26E5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26E5,
+ },
+ [0x26E6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26E6,
+ },
+ [0x26E7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26E7,
+ },
+ [0x26E8]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26E8,
+ },
+ [0x26E9]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26E9,
+ },
+ [0x26EA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26EA,
+ },
+ [0x26EB]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26EB,
+ },
+ [0x26EC]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26EC,
+ },
+ [0x26ED]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26ED,
+ },
+ [0x26EE]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26EE,
+ },
+ [0x26EF]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26EF,
+ },
+ [0x26F0]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26F0,
+ },
+ [0x26F1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F1,
+ },
+ [0x26F2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F2,
+ },
+ [0x26F3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F3,
+ },
+ [0x26F4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F4,
+ },
+ [0x26F5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F5,
+ },
+ [0x26F6]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26F6,
+ },
+ [0x26F7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F7,
+ },
+ [0x26F8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F8,
+ },
+ [0x26F9]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x26F9,
+ },
+ [0x26FA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26FA,
+ },
+ [0x26FB]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26FB,
+ },
+ [0x26FC]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26FC,
+ },
+ [0x26FD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26FD,
+ },
+ [0x26FE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26FE,
+ },
+ [0x26FF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26FF,
+ },
+ [0x2700]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2700,
+ },
+ [0x2701]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2701,
+ },
+ [0x2702]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2702,
+ },
+ [0x2703]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2703,
+ },
+ [0x2704]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2704,
+ },
+ [0x2705]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2705,
+ },
+ [0x2706]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2706,
+ },
+ [0x2707]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2707,
+ },
+ [0x2708]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2708,
+ },
+ [0x2709]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2709,
+ },
+ [0x270A]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x270A,
+ },
+ [0x270B]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x270B,
+ },
+ [0x270C]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x270C,
+ },
+ [0x270D]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x270D,
+ },
+ [0x270E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x270E,
+ },
+ [0x270F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x270F,
+ },
+ [0x2710]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2710,
+ },
+ [0x2711]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2711,
+ },
+ [0x2712]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2712,
+ },
+ [0x2713]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2713,
+ },
+ [0x2714]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2714,
+ },
+ [0x2715]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2715,
+ },
+ [0x2716]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2716,
+ },
+ [0x2717]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2717,
+ },
+ [0x2718]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2718,
+ },
+ [0x2719]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2719,
+ },
+ [0x271A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x271A,
+ },
+ [0x271B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x271B,
+ },
+ [0x271C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x271C,
+ },
+ [0x271D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x271D,
+ },
+ [0x271E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x271E,
+ },
+ [0x271F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x271F,
+ },
+ [0x2720]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2720,
+ },
+ [0x2721]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2721,
+ },
+ [0x2722]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2722,
+ },
+ [0x2723]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2723,
+ },
+ [0x2724]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2724,
+ },
+ [0x2725]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2725,
+ },
+ [0x2726]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2726,
+ },
+ [0x2727]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2727,
+ },
+ [0x2728]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2728,
+ },
+ [0x2729]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2729,
+ },
+ [0x272A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x272A,
+ },
+ [0x272B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x272B,
+ },
+ [0x272C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x272C,
+ },
+ [0x272D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x272D,
+ },
+ [0x272E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x272E,
+ },
+ [0x272F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x272F,
+ },
+ [0x2730]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2730,
+ },
+ [0x2731]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2731,
+ },
+ [0x2732]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2732,
+ },
+ [0x2733]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2733,
+ },
+ [0x2734]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2734,
+ },
+ [0x2735]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2735,
+ },
+ [0x2736]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2736,
+ },
+ [0x2737]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2737,
+ },
+ [0x2738]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2738,
+ },
+ [0x2739]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2739,
+ },
+ [0x273A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x273A,
+ },
+ [0x273B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x273B,
+ },
+ [0x273C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x273C,
+ },
+ [0x273D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x273D,
+ },
+ [0x273E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x273E,
+ },
+ [0x273F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x273F,
+ },
+ [0x2740]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2740,
+ },
+ [0x2741]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2741,
+ },
+ [0x2742]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2742,
+ },
+ [0x2743]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2743,
+ },
+ [0x2744]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2744,
+ },
+ [0x2745]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2745,
+ },
+ [0x2746]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2746,
+ },
+ [0x2747]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2747,
+ },
+ [0x2748]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2748,
+ },
+ [0x2749]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2749,
+ },
+ [0x274A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x274A,
+ },
+ [0x274B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x274B,
+ },
+ [0x274C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x274C,
+ },
+ [0x274D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x274D,
+ },
+ [0x274E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x274E,
+ },
+ [0x274F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x274F,
+ },
+ [0x2750]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2750,
+ },
+ [0x2751]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2751,
+ },
+ [0x2752]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2752,
+ },
+ [0x2753]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2753,
+ },
+ [0x2754]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2754,
+ },
+ [0x2755]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2755,
+ },
+ [0x2756]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2756,
+ },
+ [0x2757]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2757,
+ },
+ [0x2758]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2758,
+ },
+ [0x2759]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2759,
+ },
+ [0x275A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x275A,
+ },
+ [0x275B]={
+ category="so",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x275B,
+ },
+ [0x275C]={
+ category="so",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x275C,
+ },
+ [0x275D]={
+ category="so",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x275D,
+ },
+ [0x275E]={
+ category="so",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x275E,
+ },
+ [0x275F]={
+ category="so",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x275F,
+ },
+ [0x2760]={
+ category="so",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2760,
+ },
+ [0x2761]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2761,
+ },
+ [0x2762]={
+ category="so",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x2762,
+ },
+ [0x2763]={
+ category="so",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x2763,
+ },
+ [0x2764]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2764,
+ },
+ [0x2765]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2765,
+ },
+ [0x2766]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2766,
+ },
+ [0x2767]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2767,
+ },
+ [0x2768]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2769,
+ unicodeslot=0x2768,
+ },
+ [0x2769]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2768,
+ unicodeslot=0x2769,
+ },
+ [0x276A]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x276B,
+ unicodeslot=0x276A,
+ },
+ [0x276B]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x276A,
+ unicodeslot=0x276B,
+ },
+ [0x276C]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x276D,
+ unicodeslot=0x276C,
+ },
+ [0x276D]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x276C,
+ unicodeslot=0x276D,
+ },
+ [0x276E]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x276F,
+ unicodeslot=0x276E,
+ },
+ [0x276F]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x276E,
+ unicodeslot=0x276F,
+ },
+ [0x2770]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2771,
+ unicodeslot=0x2770,
+ },
+ [0x2771]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2770,
+ unicodeslot=0x2771,
+ },
+ [0x2772]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2773,
+ unicodeslot=0x2772,
+ },
+ [0x2773]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2772,
+ unicodeslot=0x2773,
+ },
+ [0x2774]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2775,
+ unicodeslot=0x2774,
+ },
+ [0x2775]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2774,
+ unicodeslot=0x2775,
+ },
+ [0x2776]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2776,
+ },
+ [0x2777]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2777,
+ },
+ [0x2778]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2778,
+ },
+ [0x2779]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2779,
+ },
+ [0x277A]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x277A,
+ },
+ [0x277B]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x277B,
+ },
+ [0x277C]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x277C,
+ },
+ [0x277D]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x277D,
+ },
+ [0x277E]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x277E,
+ },
+ [0x277F]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x277F,
+ },
+ [0x2780]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2780,
+ },
+ [0x2781]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2781,
+ },
+ [0x2782]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2782,
+ },
+ [0x2783]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2783,
+ },
+ [0x2784]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2784,
+ },
+ [0x2785]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2785,
+ },
+ [0x2786]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2786,
+ },
+ [0x2787]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2787,
+ },
+ [0x2788]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2788,
+ },
+ [0x2789]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2789,
+ },
+ [0x278A]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x278A,
+ },
+ [0x278B]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x278B,
+ },
+ [0x278C]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x278C,
+ },
+ [0x278D]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x278D,
+ },
+ [0x278E]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x278E,
+ },
+ [0x278F]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x278F,
+ },
+ [0x2790]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2790,
+ },
+ [0x2791]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2791,
+ },
+ [0x2792]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2792,
+ },
+ [0x2793]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2793,
+ },
+ [0x2794]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2794,
+ },
+ [0x2795]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2795,
+ },
+ [0x2796]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2796,
+ },
+ [0x2797]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2797,
+ },
+ [0x2798]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2798,
+ },
+ [0x2799]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2799,
+ },
+ [0x279A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x279A,
+ },
+ [0x279B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x279B,
+ },
+ [0x279C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x279C,
+ },
+ [0x279D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x279D,
+ },
+ [0x279E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x279E,
+ },
+ [0x279F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x279F,
+ },
+ [0x27A0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A0,
+ },
+ [0x27A1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A1,
+ },
+ [0x27A2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A2,
+ },
+ [0x27A3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A3,
+ },
+ [0x27A4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A4,
+ },
+ [0x27A5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A5,
+ },
+ [0x27A6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A6,
+ },
+ [0x27A7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A7,
+ },
+ [0x27A8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A8,
+ },
+ [0x27A9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A9,
+ },
+ [0x27AA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27AA,
+ },
+ [0x27AB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27AB,
+ },
+ [0x27AC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27AC,
+ },
+ [0x27AD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27AD,
+ },
+ [0x27AE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27AE,
+ },
+ [0x27AF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27AF,
+ },
+ [0x27B0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B0,
+ },
+ [0x27B1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B1,
+ },
+ [0x27B2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B2,
+ },
+ [0x27B3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B3,
+ },
+ [0x27B4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B4,
+ },
+ [0x27B5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B5,
+ },
+ [0x27B6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B6,
+ },
+ [0x27B7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B7,
+ },
+ [0x27B8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B8,
+ },
+ [0x27B9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B9,
+ },
+ [0x27BA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27BA,
+ },
+ [0x27BB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27BB,
+ },
+ [0x27BC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27BC,
+ },
+ [0x27BD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27BD,
+ },
+ [0x27BE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27BE,
+ },
+ [0x27BF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27BF,
+ },
+ [0x27C0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27C0,
+ },
+ [0x27C1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27C1,
+ },
+ [0x27C2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27C2,
+ },
+ [0x27C3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27C4,
+ unicodeslot=0x27C3,
+ },
+ [0x27C4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27C3,
+ unicodeslot=0x27C4,
+ },
+ [0x27C5]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x27C6,
+ unicodeslot=0x27C5,
+ },
+ [0x27C6]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x27C5,
+ unicodeslot=0x27C6,
+ },
+ [0x27C7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27C7,
+ },
+ [0x27C8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27C9,
+ unicodeslot=0x27C8,
+ },
+ [0x27C9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27C8,
+ unicodeslot=0x27C9,
+ },
+ [0x27CA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27CA,
+ },
+ [0x27CB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27CD,
+ unicodeslot=0x27CB,
+ },
+ [0x27CC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27CC,
+ },
+ [0x27CD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27CB,
+ unicodeslot=0x27CD,
+ },
+ [0x27CE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27CE,
+ },
+ [0x27CF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27CF,
+ },
+ [0x27D0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D0,
+ },
+ [0x27D1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D1,
+ },
+ [0x27D2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D2,
+ },
+ [0x27D3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D3,
+ },
+ [0x27D4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D4,
+ },
+ [0x27D5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27D6,
+ unicodeslot=0x27D5,
+ },
+ [0x27D6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27D5,
+ unicodeslot=0x27D6,
+ },
+ [0x27D7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D7,
+ },
+ [0x27D8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D8,
+ },
+ [0x27D9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D9,
+ },
+ [0x27DA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27DA,
+ },
+ [0x27DB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27DB,
+ },
+ [0x27DC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B8,
+ unicodeslot=0x27DC,
+ },
+ [0x27DD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27DE,
+ unicodeslot=0x27DD,
+ },
+ [0x27DE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27DD,
+ unicodeslot=0x27DE,
+ },
+ [0x27DF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27DF,
+ },
+ [0x27E0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27E0,
+ },
+ [0x27E1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27E1,
+ },
+ [0x27E2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27E3,
+ unicodeslot=0x27E2,
+ },
+ [0x27E3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27E2,
+ unicodeslot=0x27E3,
+ },
+ [0x27E4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27E5,
+ unicodeslot=0x27E4,
+ },
+ [0x27E5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x27E4,
+ unicodeslot=0x27E5,
+ },
+ [0x27E6]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x27E7,
+ unicodeslot=0x27E6,
+ },
+ [0x27E7]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x27E6,
+ unicodeslot=0x27E7,
+ },
+ [0x27E8]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x27E9,
+ unicodeslot=0x27E8,
+ },
+ [0x27E9]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x27E8,
+ unicodeslot=0x27E9,
+ },
+ [0x27EA]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x27EB,
+ unicodeslot=0x27EA,
+ },
+ [0x27EB]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x27EA,
+ unicodeslot=0x27EB,
+ },
+ [0x27EC]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x27ED,
+ unicodeslot=0x27EC,
+ },
+ [0x27ED]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x27EC,
+ unicodeslot=0x27ED,
+ },
+ [0x27EE]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x27EF,
+ unicodeslot=0x27EE,
+ },
+ [0x27EF]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x27EE,
+ unicodeslot=0x27EF,
+ },
+ [0x27F0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27F0,
+ },
+ [0x27F1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27F1,
+ },
+ [0x27F2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27F2,
+ },
+ [0x27F3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27F3,
+ },
+ [0x27F4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27F4,
+ },
+ [0x27F5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27F5,
+ },
+ [0x27F6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27F6,
+ },
+ [0x27F7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27F7,
+ },
+ [0x27F8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27F8,
+ },
+ [0x27F9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27F9,
+ },
+ [0x27FA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27FA,
+ },
+ [0x27FB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27FB,
+ },
+ [0x27FC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27FC,
+ },
+ [0x27FD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27FD,
+ },
+ [0x27FE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27FE,
+ },
+ [0x27FF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27FF,
+ },
+ [0x2800]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2800,
+ },
+ [0x2801]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2801,
+ },
+ [0x2802]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2802,
+ },
+ [0x2803]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2803,
+ },
+ [0x2804]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2804,
+ },
+ [0x2805]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2805,
+ },
+ [0x2806]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2806,
+ },
+ [0x2807]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2807,
+ },
+ [0x2808]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2808,
+ },
+ [0x2809]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2809,
+ },
+ [0x280A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280A,
+ },
+ [0x280B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280B,
+ },
+ [0x280C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280C,
+ },
+ [0x280D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280D,
+ },
+ [0x280E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280E,
+ },
+ [0x280F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280F,
+ },
+ [0x2810]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2810,
+ },
+ [0x2811]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2811,
+ },
+ [0x2812]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2812,
+ },
+ [0x2813]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2813,
+ },
+ [0x2814]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2814,
+ },
+ [0x2815]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2815,
+ },
+ [0x2816]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2816,
+ },
+ [0x2817]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2817,
+ },
+ [0x2818]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2818,
+ },
+ [0x2819]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2819,
+ },
+ [0x281A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281A,
+ },
+ [0x281B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281B,
+ },
+ [0x281C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281C,
+ },
+ [0x281D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281D,
+ },
+ [0x281E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281E,
+ },
+ [0x281F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281F,
+ },
+ [0x2820]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2820,
+ },
+ [0x2821]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2821,
+ },
+ [0x2822]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2822,
+ },
+ [0x2823]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2823,
+ },
+ [0x2824]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2824,
+ },
+ [0x2825]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2825,
+ },
+ [0x2826]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2826,
+ },
+ [0x2827]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2827,
+ },
+ [0x2828]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2828,
+ },
+ [0x2829]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2829,
+ },
+ [0x282A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282A,
+ },
+ [0x282B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282B,
+ },
+ [0x282C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282C,
+ },
+ [0x282D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282D,
+ },
+ [0x282E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282E,
+ },
+ [0x282F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282F,
+ },
+ [0x2830]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2830,
+ },
+ [0x2831]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2831,
+ },
+ [0x2832]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2832,
+ },
+ [0x2833]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2833,
+ },
+ [0x2834]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2834,
+ },
+ [0x2835]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2835,
+ },
+ [0x2836]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2836,
+ },
+ [0x2837]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2837,
+ },
+ [0x2838]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2838,
+ },
+ [0x2839]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2839,
+ },
+ [0x283A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283A,
+ },
+ [0x283B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283B,
+ },
+ [0x283C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283C,
+ },
+ [0x283D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283D,
+ },
+ [0x283E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283E,
+ },
+ [0x283F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283F,
+ },
+ [0x2840]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2840,
+ },
+ [0x2841]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2841,
+ },
+ [0x2842]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2842,
+ },
+ [0x2843]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2843,
+ },
+ [0x2844]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2844,
+ },
+ [0x2845]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2845,
+ },
+ [0x2846]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2846,
+ },
+ [0x2847]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2847,
+ },
+ [0x2848]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2848,
+ },
+ [0x2849]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2849,
+ },
+ [0x284A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284A,
+ },
+ [0x284B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284B,
+ },
+ [0x284C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284C,
+ },
+ [0x284D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284D,
+ },
+ [0x284E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284E,
+ },
+ [0x284F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284F,
+ },
+ [0x2850]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2850,
+ },
+ [0x2851]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2851,
+ },
+ [0x2852]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2852,
+ },
+ [0x2853]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2853,
+ },
+ [0x2854]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2854,
+ },
+ [0x2855]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2855,
+ },
+ [0x2856]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2856,
+ },
+ [0x2857]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2857,
+ },
+ [0x2858]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2858,
+ },
+ [0x2859]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2859,
+ },
+ [0x285A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285A,
+ },
+ [0x285B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285B,
+ },
+ [0x285C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285C,
+ },
+ [0x285D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285D,
+ },
+ [0x285E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285E,
+ },
+ [0x285F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285F,
+ },
+ [0x2860]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2860,
+ },
+ [0x2861]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2861,
+ },
+ [0x2862]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2862,
+ },
+ [0x2863]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2863,
+ },
+ [0x2864]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2864,
+ },
+ [0x2865]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2865,
+ },
+ [0x2866]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2866,
+ },
+ [0x2867]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2867,
+ },
+ [0x2868]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2868,
+ },
+ [0x2869]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2869,
+ },
+ [0x286A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286A,
+ },
+ [0x286B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286B,
+ },
+ [0x286C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286C,
+ },
+ [0x286D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286D,
+ },
+ [0x286E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286E,
+ },
+ [0x286F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286F,
+ },
+ [0x2870]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2870,
+ },
+ [0x2871]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2871,
+ },
+ [0x2872]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2872,
+ },
+ [0x2873]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2873,
+ },
+ [0x2874]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2874,
+ },
+ [0x2875]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2875,
+ },
+ [0x2876]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2876,
+ },
+ [0x2877]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2877,
+ },
+ [0x2878]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2878,
+ },
+ [0x2879]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2879,
+ },
+ [0x287A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287A,
+ },
+ [0x287B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287B,
+ },
+ [0x287C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287C,
+ },
+ [0x287D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287D,
+ },
+ [0x287E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287E,
+ },
+ [0x287F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287F,
+ },
+ [0x2880]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2880,
+ },
+ [0x2881]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2881,
+ },
+ [0x2882]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2882,
+ },
+ [0x2883]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2883,
+ },
+ [0x2884]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2884,
+ },
+ [0x2885]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2885,
+ },
+ [0x2886]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2886,
+ },
+ [0x2887]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2887,
+ },
+ [0x2888]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2888,
+ },
+ [0x2889]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2889,
+ },
+ [0x288A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288A,
+ },
+ [0x288B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288B,
+ },
+ [0x288C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288C,
+ },
+ [0x288D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288D,
+ },
+ [0x288E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288E,
+ },
+ [0x288F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288F,
+ },
+ [0x2890]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2890,
+ },
+ [0x2891]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2891,
+ },
+ [0x2892]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2892,
+ },
+ [0x2893]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2893,
+ },
+ [0x2894]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2894,
+ },
+ [0x2895]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2895,
+ },
+ [0x2896]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2896,
+ },
+ [0x2897]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2897,
+ },
+ [0x2898]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2898,
+ },
+ [0x2899]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2899,
+ },
+ [0x289A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289A,
+ },
+ [0x289B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289B,
+ },
+ [0x289C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289C,
+ },
+ [0x289D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289D,
+ },
+ [0x289E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289E,
+ },
+ [0x289F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289F,
+ },
+ [0x28A0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A0,
+ },
+ [0x28A1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A1,
+ },
+ [0x28A2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A2,
+ },
+ [0x28A3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A3,
+ },
+ [0x28A4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A4,
+ },
+ [0x28A5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A5,
+ },
+ [0x28A6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A6,
+ },
+ [0x28A7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A7,
+ },
+ [0x28A8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A8,
+ },
+ [0x28A9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A9,
+ },
+ [0x28AA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28AA,
+ },
+ [0x28AB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28AB,
+ },
+ [0x28AC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28AC,
+ },
+ [0x28AD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28AD,
+ },
+ [0x28AE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28AE,
+ },
+ [0x28AF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28AF,
+ },
+ [0x28B0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B0,
+ },
+ [0x28B1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B1,
+ },
+ [0x28B2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B2,
+ },
+ [0x28B3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B3,
+ },
+ [0x28B4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B4,
+ },
+ [0x28B5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B5,
+ },
+ [0x28B6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B6,
+ },
+ [0x28B7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B7,
+ },
+ [0x28B8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B8,
+ },
+ [0x28B9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B9,
+ },
+ [0x28BA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28BA,
+ },
+ [0x28BB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28BB,
+ },
+ [0x28BC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28BC,
+ },
+ [0x28BD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28BD,
+ },
+ [0x28BE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28BE,
+ },
+ [0x28BF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28BF,
+ },
+ [0x28C0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C0,
+ },
+ [0x28C1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C1,
+ },
+ [0x28C2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C2,
+ },
+ [0x28C3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C3,
+ },
+ [0x28C4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C4,
+ },
+ [0x28C5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C5,
+ },
+ [0x28C6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C6,
+ },
+ [0x28C7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C7,
+ },
+ [0x28C8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C8,
+ },
+ [0x28C9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C9,
+ },
+ [0x28CA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28CA,
+ },
+ [0x28CB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28CB,
+ },
+ [0x28CC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28CC,
+ },
+ [0x28CD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28CD,
+ },
+ [0x28CE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28CE,
+ },
+ [0x28CF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28CF,
+ },
+ [0x28D0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D0,
+ },
+ [0x28D1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D1,
+ },
+ [0x28D2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D2,
+ },
+ [0x28D3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D3,
+ },
+ [0x28D4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D4,
+ },
+ [0x28D5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D5,
+ },
+ [0x28D6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D6,
+ },
+ [0x28D7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D7,
+ },
+ [0x28D8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D8,
+ },
+ [0x28D9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D9,
+ },
+ [0x28DA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28DA,
+ },
+ [0x28DB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28DB,
+ },
+ [0x28DC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28DC,
+ },
+ [0x28DD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28DD,
+ },
+ [0x28DE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28DE,
+ },
+ [0x28DF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28DF,
+ },
+ [0x28E0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E0,
+ },
+ [0x28E1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E1,
+ },
+ [0x28E2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E2,
+ },
+ [0x28E3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E3,
+ },
+ [0x28E4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E4,
+ },
+ [0x28E5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E5,
+ },
+ [0x28E6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E6,
+ },
+ [0x28E7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E7,
+ },
+ [0x28E8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E8,
+ },
+ [0x28E9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E9,
+ },
+ [0x28EA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28EA,
+ },
+ [0x28EB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28EB,
+ },
+ [0x28EC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28EC,
+ },
+ [0x28ED]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28ED,
+ },
+ [0x28EE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28EE,
+ },
+ [0x28EF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28EF,
+ },
+ [0x28F0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F0,
+ },
+ [0x28F1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F1,
+ },
+ [0x28F2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F2,
+ },
+ [0x28F3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F3,
+ },
+ [0x28F4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F4,
+ },
+ [0x28F5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F5,
+ },
+ [0x28F6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F6,
+ },
+ [0x28F7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F7,
+ },
+ [0x28F8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F8,
+ },
+ [0x28F9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F9,
+ },
+ [0x28FA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28FA,
+ },
+ [0x28FB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28FB,
+ },
+ [0x28FC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28FC,
+ },
+ [0x28FD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28FD,
+ },
+ [0x28FE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28FE,
+ },
+ [0x28FF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28FF,
+ },
+ [0x2900]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2900,
+ },
+ [0x2901]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2901,
+ },
+ [0x2902]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2902,
+ },
+ [0x2903]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2903,
+ },
+ [0x2904]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2904,
+ },
+ [0x2905]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2905,
+ },
+ [0x2906]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2906,
+ },
+ [0x2907]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2907,
+ },
+ [0x2908]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2908,
+ },
+ [0x2909]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2909,
+ },
+ [0x290A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x290A,
+ },
+ [0x290B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x290B,
+ },
+ [0x290C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x290C,
+ },
+ [0x290D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x290D,
+ },
+ [0x290E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x290E,
+ },
+ [0x290F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x290F,
+ },
+ [0x2910]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2910,
+ },
+ [0x2911]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2911,
+ },
+ [0x2912]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2912,
+ },
+ [0x2913]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2913,
+ },
+ [0x2914]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2914,
+ },
+ [0x2915]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2915,
+ },
+ [0x2916]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2916,
+ },
+ [0x2917]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2917,
+ },
+ [0x2918]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2918,
+ },
+ [0x2919]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2919,
+ },
+ [0x291A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x291A,
+ },
+ [0x291B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x291B,
+ },
+ [0x291C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x291C,
+ },
+ [0x291D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x291D,
+ },
+ [0x291E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x291E,
+ },
+ [0x291F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x291F,
+ },
+ [0x2920]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2920,
+ },
+ [0x2921]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2921,
+ },
+ [0x2922]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2922,
+ },
+ [0x2923]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2923,
+ },
+ [0x2924]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2924,
+ },
+ [0x2925]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2925,
+ },
+ [0x2926]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2926,
+ },
+ [0x2927]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2927,
+ },
+ [0x2928]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2928,
+ },
+ [0x2929]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2929,
+ },
+ [0x292A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x292A,
+ },
+ [0x292B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x292B,
+ },
+ [0x292C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x292C,
+ },
+ [0x292D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x292D,
+ },
+ [0x292E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x292E,
+ },
+ [0x292F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x292F,
+ },
+ [0x2930]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2930,
+ },
+ [0x2931]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2931,
+ },
+ [0x2932]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2932,
+ },
+ [0x2933]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2933,
+ },
+ [0x2934]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2934,
+ },
+ [0x2935]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2935,
+ },
+ [0x2936]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2936,
+ },
+ [0x2937]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2937,
+ },
+ [0x2938]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2938,
+ },
+ [0x2939]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2939,
+ },
+ [0x293A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x293A,
+ },
+ [0x293B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x293B,
+ },
+ [0x293C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x293C,
+ },
+ [0x293D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x293D,
+ },
+ [0x293E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x293E,
+ },
+ [0x293F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x293F,
+ },
+ [0x2940]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2940,
+ },
+ [0x2941]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2941,
+ },
+ [0x2942]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2942,
+ },
+ [0x2943]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2943,
+ },
+ [0x2944]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2944,
+ },
+ [0x2945]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2945,
+ },
+ [0x2946]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2946,
+ },
+ [0x2947]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2947,
+ },
+ [0x2948]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2948,
+ },
+ [0x2949]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2949,
+ },
+ [0x294A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x294A,
+ },
+ [0x294B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x294B,
+ },
+ [0x294C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x294C,
+ },
+ [0x294D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x294D,
+ },
+ [0x294E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x294E,
+ },
+ [0x294F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x294F,
+ },
+ [0x2950]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2950,
+ },
+ [0x2951]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2951,
+ },
+ [0x2952]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2952,
+ },
+ [0x2953]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2953,
+ },
+ [0x2954]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2954,
+ },
+ [0x2955]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2955,
+ },
+ [0x2956]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2956,
+ },
+ [0x2957]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2957,
+ },
+ [0x2958]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2958,
+ },
+ [0x2959]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2959,
+ },
+ [0x295A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x295A,
+ },
+ [0x295B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x295B,
+ },
+ [0x295C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x295C,
+ },
+ [0x295D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x295D,
+ },
+ [0x295E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x295E,
+ },
+ [0x295F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x295F,
+ },
+ [0x2960]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2960,
+ },
+ [0x2961]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2961,
+ },
+ [0x2962]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2962,
+ },
+ [0x2963]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2963,
+ },
+ [0x2964]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2964,
+ },
+ [0x2965]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2965,
+ },
+ [0x2966]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2966,
+ },
+ [0x2967]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2967,
+ },
+ [0x2968]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2968,
+ },
+ [0x2969]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2969,
+ },
+ [0x296A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x296A,
+ },
+ [0x296B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x296B,
+ },
+ [0x296C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x296C,
+ },
+ [0x296D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x296D,
+ },
+ [0x296E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x296E,
+ },
+ [0x296F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x296F,
+ },
+ [0x2970]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2970,
+ },
+ [0x2971]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2971,
+ },
+ [0x2972]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2972,
+ },
+ [0x2973]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2973,
+ },
+ [0x2974]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2974,
+ },
+ [0x2975]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2975,
+ },
+ [0x2976]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2976,
+ },
+ [0x2977]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2977,
+ },
+ [0x2978]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2978,
+ },
+ [0x2979]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2979,
+ },
+ [0x297A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x297A,
+ },
+ [0x297B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x297B,
+ },
+ [0x297C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x297C,
+ },
+ [0x297D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x297D,
+ },
+ [0x297E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x297E,
+ },
+ [0x297F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x297F,
+ },
+ [0x2980]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2980,
+ },
+ [0x2981]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2981,
+ },
+ [0x2982]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2982,
+ },
+ [0x2983]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2984,
+ unicodeslot=0x2983,
+ },
+ [0x2984]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2983,
+ unicodeslot=0x2984,
+ },
+ [0x2985]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2986,
+ unicodeslot=0x2985,
+ },
+ [0x2986]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2985,
+ unicodeslot=0x2986,
+ },
+ [0x2987]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2988,
+ unicodeslot=0x2987,
+ },
+ [0x2988]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2987,
+ unicodeslot=0x2988,
+ },
+ [0x2989]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x298A,
+ unicodeslot=0x2989,
+ },
+ [0x298A]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2989,
+ unicodeslot=0x298A,
+ },
+ [0x298B]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x298C,
+ unicodeslot=0x298B,
+ },
+ [0x298C]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x298B,
+ unicodeslot=0x298C,
+ },
+ [0x298D]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2990,
+ unicodeslot=0x298D,
+ },
+ [0x298E]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x298F,
+ unicodeslot=0x298E,
+ },
+ [0x298F]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x298E,
+ unicodeslot=0x298F,
+ },
+ [0x2990]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x298D,
+ unicodeslot=0x2990,
+ },
+ [0x2991]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2992,
+ unicodeslot=0x2991,
+ },
+ [0x2992]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2991,
+ unicodeslot=0x2992,
+ },
+ [0x2993]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2994,
+ unicodeslot=0x2993,
+ },
+ [0x2994]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2993,
+ unicodeslot=0x2994,
+ },
+ [0x2995]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2996,
+ unicodeslot=0x2995,
+ },
+ [0x2996]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2995,
+ unicodeslot=0x2996,
+ },
+ [0x2997]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2998,
+ textclass="open",
+ unicodeslot=0x2997,
+ },
+ [0x2998]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2997,
+ textclass="close",
+ unicodeslot=0x2998,
+ },
+ [0x2999]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2999,
+ },
+ [0x299A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x299A,
+ },
+ [0x299B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2221,
+ unicodeslot=0x299B,
+ },
+ [0x299C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x299C,
+ },
+ [0x299D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x299D,
+ },
+ [0x299E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x299E,
+ },
+ [0x299F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x299F,
+ },
+ [0x29A0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2222,
+ unicodeslot=0x29A0,
+ },
+ [0x29A1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A1,
+ },
+ [0x29A2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A2,
+ },
+ [0x29A3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2220,
+ unicodeslot=0x29A3,
+ },
+ [0x29A4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29A5,
+ unicodeslot=0x29A4,
+ },
+ [0x29A5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29A4,
+ unicodeslot=0x29A5,
+ },
+ [0x29A6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A6,
+ },
+ [0x29A7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A7,
+ },
+ [0x29A8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29A9,
+ unicodeslot=0x29A8,
+ },
+ [0x29A9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29A8,
+ unicodeslot=0x29A9,
+ },
+ [0x29AA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29AB,
+ unicodeslot=0x29AA,
+ },
+ [0x29AB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29AA,
+ unicodeslot=0x29AB,
+ },
+ [0x29AC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29AD,
+ unicodeslot=0x29AC,
+ },
+ [0x29AD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29AC,
+ unicodeslot=0x29AD,
+ },
+ [0x29AE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29AF,
+ unicodeslot=0x29AE,
+ },
+ [0x29AF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29AE,
+ unicodeslot=0x29AF,
+ },
+ [0x29B0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B0,
+ },
+ [0x29B1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B1,
+ },
+ [0x29B2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B2,
+ },
+ [0x29B3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B3,
+ },
+ [0x29B4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B4,
+ },
+ [0x29B5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B5,
+ },
+ [0x29B6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B6,
+ },
+ [0x29B7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B7,
+ },
+ [0x29B8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2298,
+ unicodeslot=0x29B8,
+ },
+ [0x29B9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B9,
+ },
+ [0x29BA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29BA,
+ },
+ [0x29BB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29BB,
+ },
+ [0x29BC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29BC,
+ },
+ [0x29BD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29BD,
+ },
+ [0x29BE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29BE,
+ },
+ [0x29BF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29BF,
+ },
+ [0x29C0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29C1,
+ unicodeslot=0x29C0,
+ },
+ [0x29C1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29C0,
+ unicodeslot=0x29C1,
+ },
+ [0x29C2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29C2,
+ },
+ [0x29C3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29C3,
+ },
+ [0x29C4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29C5,
+ unicodeslot=0x29C4,
+ },
+ [0x29C5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29C4,
+ unicodeslot=0x29C5,
+ },
+ [0x29C6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29C6,
+ },
+ [0x29C7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29C7,
+ },
+ [0x29C8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29C8,
+ },
+ [0x29C9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29C9,
+ },
+ [0x29CA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29CA,
+ },
+ [0x29CB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29CB,
+ },
+ [0x29CC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29CC,
+ },
+ [0x29CD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29CD,
+ },
+ [0x29CE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29CE,
+ },
+ [0x29CF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29D0,
+ unicodeslot=0x29CF,
+ },
+ [0x29D0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29CF,
+ unicodeslot=0x29D0,
+ },
+ [0x29D1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29D2,
+ unicodeslot=0x29D1,
+ },
+ [0x29D2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29D1,
+ unicodeslot=0x29D2,
+ },
+ [0x29D3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29D3,
+ },
+ [0x29D4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29D5,
+ unicodeslot=0x29D4,
+ },
+ [0x29D5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29D4,
+ unicodeslot=0x29D5,
+ },
+ [0x29D6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29D6,
+ },
+ [0x29D7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29D7,
+ },
+ [0x29D8]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x29D9,
+ unicodeslot=0x29D8,
+ },
+ [0x29D9]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x29D8,
+ unicodeslot=0x29D9,
+ },
+ [0x29DA]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x29DB,
+ unicodeslot=0x29DA,
+ },
+ [0x29DB]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x29DA,
+ unicodeslot=0x29DB,
+ },
+ [0x29DC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29DC,
+ },
+ [0x29DD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29DD,
+ },
+ [0x29DE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29DE,
+ },
+ [0x29DF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29DF,
+ },
+ [0x29E0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E0,
+ },
+ [0x29E1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E1,
+ },
+ [0x29E2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E2,
+ },
+ [0x29E3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E3,
+ },
+ [0x29E4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E4,
+ },
+ [0x29E5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E5,
+ },
+ [0x29E6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E6,
+ },
+ [0x29E7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E7,
+ },
+ [0x29E8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29E9,
+ unicodeslot=0x29E8,
+ },
+ [0x29E9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29E8,
+ unicodeslot=0x29E9,
+ },
+ [0x29EA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29EA,
+ },
+ [0x29EB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29EB,
+ },
+ [0x29EC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29EC,
+ },
+ [0x29ED]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29ED,
+ },
+ [0x29EE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29EE,
+ },
+ [0x29EF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29EF,
+ },
+ [0x29F0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F0,
+ },
+ [0x29F1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F1,
+ },
+ [0x29F2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F2,
+ },
+ [0x29F3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F3,
+ },
+ [0x29F4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F4,
+ },
+ [0x29F5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2215,
+ unicodeslot=0x29F5,
+ },
+ [0x29F6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F6,
+ },
+ [0x29F7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F7,
+ },
+ [0x29F8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29F9,
+ unicodeslot=0x29F8,
+ },
+ [0x29F9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x29F8,
+ unicodeslot=0x29F9,
+ },
+ [0x29FA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29FA,
+ },
+ [0x29FB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29FB,
+ },
+ [0x29FC]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x29FD,
+ unicodeslot=0x29FC,
+ },
+ [0x29FD]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x29FC,
+ unicodeslot=0x29FD,
+ },
+ [0x29FE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29FE,
+ },
+ [0x29FF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29FF,
+ },
+ [0x2A00]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A00,
+ },
+ [0x2A01]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A01,
+ },
+ [0x2A02]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A02,
+ },
+ [0x2A03]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A03,
+ },
+ [0x2A04]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A04,
+ },
+ [0x2A05]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A05,
+ },
+ [0x2A06]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A06,
+ },
+ [0x2A07]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A07,
+ },
+ [0x2A08]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A08,
+ },
+ [0x2A09]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A09,
+ },
+ [0x2A0A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A0A,
+ },
+ [0x2A0B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A0B,
+ },
+ [0x2A0C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x222B, 0x222B, 0x222B, 0x222B },
+ unicodeslot=0x2A0C,
+ },
+ [0x2A0D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A0D,
+ },
+ [0x2A0E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A0E,
+ },
+ [0x2A0F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A0F,
+ },
+ [0x2A10]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A10,
+ },
+ [0x2A11]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A11,
+ },
+ [0x2A12]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A12,
+ },
+ [0x2A13]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A13,
+ },
+ [0x2A14]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A14,
+ },
+ [0x2A15]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A15,
+ },
+ [0x2A16]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A16,
+ },
+ [0x2A17]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A17,
+ },
+ [0x2A18]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A18,
+ },
+ [0x2A19]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A19,
+ },
+ [0x2A1A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A1A,
+ },
+ [0x2A1B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A1B,
+ },
+ [0x2A1C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A1C,
+ },
+ [0x2A1D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A1D,
+ },
+ [0x2A1E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A1E,
+ },
+ [0x2A1F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A1F,
+ },
+ [0x2A20]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A20,
+ },
+ [0x2A21]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A21,
+ },
+ [0x2A22]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A22,
+ },
+ [0x2A23]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A23,
+ },
+ [0x2A24]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A24,
+ },
+ [0x2A25]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A25,
+ },
+ [0x2A26]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A26,
+ },
+ [0x2A27]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A27,
+ },
+ [0x2A28]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A28,
+ },
+ [0x2A29]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A29,
+ },
+ [0x2A2A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A2A,
+ },
+ [0x2A2B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A2C,
+ unicodeslot=0x2A2B,
+ },
+ [0x2A2C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A2B,
+ unicodeslot=0x2A2C,
+ },
+ [0x2A2D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A2E,
+ unicodeslot=0x2A2D,
+ },
+ [0x2A2E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A2D,
+ unicodeslot=0x2A2E,
+ },
+ [0x2A2F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A2F,
+ },
+ [0x2A30]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A30,
+ },
+ [0x2A31]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A31,
+ },
+ [0x2A32]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A32,
+ },
+ [0x2A33]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A33,
+ },
+ [0x2A34]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A35,
+ unicodeslot=0x2A34,
+ },
+ [0x2A35]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A34,
+ unicodeslot=0x2A35,
+ },
+ [0x2A36]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A36,
+ },
+ [0x2A37]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A37,
+ },
+ [0x2A38]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A38,
+ },
+ [0x2A39]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A39,
+ },
+ [0x2A3A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A3A,
+ },
+ [0x2A3B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A3B,
+ },
+ [0x2A3C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A3D,
+ unicodeslot=0x2A3C,
+ },
+ [0x2A3D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A3C,
+ unicodeslot=0x2A3D,
+ },
+ [0x2A3E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A3E,
+ },
+ [0x2A3F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A3F,
+ },
+ [0x2A40]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A40,
+ },
+ [0x2A41]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A41,
+ },
+ [0x2A42]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A42,
+ },
+ [0x2A43]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A43,
+ },
+ [0x2A44]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A44,
+ },
+ [0x2A45]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A45,
+ },
+ [0x2A46]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A46,
+ },
+ [0x2A47]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A47,
+ },
+ [0x2A48]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A48,
+ },
+ [0x2A49]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A49,
+ },
+ [0x2A4A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A4A,
+ },
+ [0x2A4B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A4B,
+ },
+ [0x2A4C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A4C,
+ },
+ [0x2A4D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A4D,
+ },
+ [0x2A4E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A4E,
+ },
+ [0x2A4F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A4F,
+ },
+ [0x2A50]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A50,
+ },
+ [0x2A51]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A51,
+ },
+ [0x2A52]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A52,
+ },
+ [0x2A53]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A53,
+ },
+ [0x2A54]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A54,
+ },
+ [0x2A55]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A55,
+ },
+ [0x2A56]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A56,
+ },
+ [0x2A57]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A57,
+ },
+ [0x2A58]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A58,
+ },
+ [0x2A59]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A59,
+ },
+ [0x2A5A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A5A,
+ },
+ [0x2A5B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A5B,
+ },
+ [0x2A5C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A5C,
+ },
+ [0x2A5D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A5D,
+ },
+ [0x2A5E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A5E,
+ },
+ [0x2A5F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A5F,
+ },
+ [0x2A60]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A60,
+ },
+ [0x2A61]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A61,
+ },
+ [0x2A62]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A62,
+ },
+ [0x2A63]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A63,
+ },
+ [0x2A64]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A65,
+ unicodeslot=0x2A64,
+ },
+ [0x2A65]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A64,
+ unicodeslot=0x2A65,
+ },
+ [0x2A66]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A66,
+ },
+ [0x2A67]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A67,
+ },
+ [0x2A68]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A68,
+ },
+ [0x2A69]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A69,
+ },
+ [0x2A6A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A6A,
+ },
+ [0x2A6B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A6B,
+ },
+ [0x2A6C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A6C,
+ },
+ [0x2A6D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A6D,
+ },
+ [0x2A6E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A6E,
+ },
+ [0x2A6F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A6F,
+ },
+ [0x2A70]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A70,
+ },
+ [0x2A71]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A71,
+ },
+ [0x2A72]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A72,
+ },
+ [0x2A73]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A73,
+ },
+ [0x2A74]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x3A, 0x3A, 0x3D },
+ unicodeslot=0x2A74,
+ },
+ [0x2A75]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x3D, 0x3D },
+ unicodeslot=0x2A75,
+ },
+ [0x2A76]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x3D, 0x3D, 0x3D },
+ unicodeslot=0x2A76,
+ },
+ [0x2A77]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A77,
+ },
+ [0x2A78]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A78,
+ },
+ [0x2A79]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A7A,
+ unicodeslot=0x2A79,
+ },
+ [0x2A7A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A79,
+ unicodeslot=0x2A7A,
+ },
+ [0x2A7B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A7C,
+ unicodeslot=0x2A7B,
+ },
+ [0x2A7C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A7B,
+ unicodeslot=0x2A7C,
+ },
+ [0x2A7D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A7E,
+ unicodeslot=0x2A7D,
+ },
+ [0x2A7E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A7D,
+ unicodeslot=0x2A7E,
+ },
+ [0x2A7F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A80,
+ unicodeslot=0x2A7F,
+ },
+ [0x2A80]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A7F,
+ unicodeslot=0x2A80,
+ },
+ [0x2A81]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A82,
+ unicodeslot=0x2A81,
+ },
+ [0x2A82]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A81,
+ unicodeslot=0x2A82,
+ },
+ [0x2A83]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A84,
+ unicodeslot=0x2A83,
+ },
+ [0x2A84]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A83,
+ unicodeslot=0x2A84,
+ },
+ [0x2A85]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A86,
+ unicodeslot=0x2A85,
+ },
+ [0x2A86]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A85,
+ unicodeslot=0x2A86,
+ },
+ [0x2A87]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A88,
+ unicodeslot=0x2A87,
+ },
+ [0x2A88]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A87,
+ unicodeslot=0x2A88,
+ },
+ [0x2A89]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A8A,
+ unicodeslot=0x2A89,
+ },
+ [0x2A8A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A89,
+ unicodeslot=0x2A8A,
+ },
+ [0x2A8B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A8C,
+ unicodeslot=0x2A8B,
+ },
+ [0x2A8C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A8B,
+ unicodeslot=0x2A8C,
+ },
+ [0x2A8D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A8E,
+ unicodeslot=0x2A8D,
+ },
+ [0x2A8E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A8D,
+ unicodeslot=0x2A8E,
+ },
+ [0x2A8F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A90,
+ unicodeslot=0x2A8F,
+ },
+ [0x2A90]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A8F,
+ unicodeslot=0x2A90,
+ },
+ [0x2A91]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A92,
+ unicodeslot=0x2A91,
+ },
+ [0x2A92]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A91,
+ unicodeslot=0x2A92,
+ },
+ [0x2A93]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A94,
+ unicodeslot=0x2A93,
+ },
+ [0x2A94]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A93,
+ unicodeslot=0x2A94,
+ },
+ [0x2A95]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A96,
+ unicodeslot=0x2A95,
+ },
+ [0x2A96]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A95,
+ unicodeslot=0x2A96,
+ },
+ [0x2A97]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A98,
+ unicodeslot=0x2A97,
+ },
+ [0x2A98]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A97,
+ unicodeslot=0x2A98,
+ },
+ [0x2A99]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A9A,
+ unicodeslot=0x2A99,
+ },
+ [0x2A9A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A99,
+ unicodeslot=0x2A9A,
+ },
+ [0x2A9B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A9C,
+ unicodeslot=0x2A9B,
+ },
+ [0x2A9C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A9B,
+ unicodeslot=0x2A9C,
+ },
+ [0x2A9D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A9E,
+ unicodeslot=0x2A9D,
+ },
+ [0x2A9E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A9D,
+ unicodeslot=0x2A9E,
+ },
+ [0x2A9F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA0,
+ unicodeslot=0x2A9F,
+ },
+ [0x2AA0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A9F,
+ unicodeslot=0x2AA0,
+ },
+ [0x2AA1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA2,
+ unicodeslot=0x2AA1,
+ },
+ [0x2AA2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA1,
+ unicodeslot=0x2AA2,
+ },
+ [0x2AA3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AA3,
+ },
+ [0x2AA4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AA4,
+ },
+ [0x2AA5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AA5,
+ },
+ [0x2AA6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA7,
+ unicodeslot=0x2AA6,
+ },
+ [0x2AA7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA6,
+ unicodeslot=0x2AA7,
+ },
+ [0x2AA8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA9,
+ unicodeslot=0x2AA8,
+ },
+ [0x2AA9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA8,
+ unicodeslot=0x2AA9,
+ },
+ [0x2AAA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AAB,
+ unicodeslot=0x2AAA,
+ },
+ [0x2AAB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AAA,
+ unicodeslot=0x2AAB,
+ },
+ [0x2AAC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AAD,
+ unicodeslot=0x2AAC,
+ },
+ [0x2AAD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AAC,
+ unicodeslot=0x2AAD,
+ },
+ [0x2AAE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AAE,
+ },
+ [0x2AAF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AB0,
+ unicodeslot=0x2AAF,
+ },
+ [0x2AB0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AAF,
+ unicodeslot=0x2AB0,
+ },
+ [0x2AB1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AB2,
+ unicodeslot=0x2AB1,
+ },
+ [0x2AB2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AB1,
+ unicodeslot=0x2AB2,
+ },
+ [0x2AB3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AB4,
+ unicodeslot=0x2AB3,
+ },
+ [0x2AB4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AB3,
+ unicodeslot=0x2AB4,
+ },
+ [0x2AB5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AB6,
+ unicodeslot=0x2AB5,
+ },
+ [0x2AB6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AB5,
+ unicodeslot=0x2AB6,
+ },
+ [0x2AB7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AB8,
+ unicodeslot=0x2AB7,
+ },
+ [0x2AB8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AB7,
+ unicodeslot=0x2AB8,
+ },
+ [0x2AB9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ABA,
+ unicodeslot=0x2AB9,
+ },
+ [0x2ABA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AB9,
+ unicodeslot=0x2ABA,
+ },
+ [0x2ABB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ABC,
+ unicodeslot=0x2ABB,
+ },
+ [0x2ABC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ABB,
+ unicodeslot=0x2ABC,
+ },
+ [0x2ABD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ABE,
+ unicodeslot=0x2ABD,
+ },
+ [0x2ABE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ABD,
+ unicodeslot=0x2ABE,
+ },
+ [0x2ABF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC0,
+ unicodeslot=0x2ABF,
+ },
+ [0x2AC0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ABF,
+ unicodeslot=0x2AC0,
+ },
+ [0x2AC1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC2,
+ unicodeslot=0x2AC1,
+ },
+ [0x2AC2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC1,
+ unicodeslot=0x2AC2,
+ },
+ [0x2AC3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC4,
+ unicodeslot=0x2AC3,
+ },
+ [0x2AC4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC3,
+ unicodeslot=0x2AC4,
+ },
+ [0x2AC5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC6,
+ unicodeslot=0x2AC5,
+ },
+ [0x2AC6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC5,
+ unicodeslot=0x2AC6,
+ },
+ [0x2AC7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC8,
+ unicodeslot=0x2AC7,
+ },
+ [0x2AC8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC7,
+ unicodeslot=0x2AC8,
+ },
+ [0x2AC9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ACA,
+ unicodeslot=0x2AC9,
+ },
+ [0x2ACA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC9,
+ unicodeslot=0x2ACA,
+ },
+ [0x2ACB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ACC,
+ unicodeslot=0x2ACB,
+ },
+ [0x2ACC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ACB,
+ unicodeslot=0x2ACC,
+ },
+ [0x2ACD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ACE,
+ unicodeslot=0x2ACD,
+ },
+ [0x2ACE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ACD,
+ unicodeslot=0x2ACE,
+ },
+ [0x2ACF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD0,
+ unicodeslot=0x2ACF,
+ },
+ [0x2AD0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ACF,
+ unicodeslot=0x2AD0,
+ },
+ [0x2AD1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD2,
+ unicodeslot=0x2AD1,
+ },
+ [0x2AD2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD1,
+ unicodeslot=0x2AD2,
+ },
+ [0x2AD3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD4,
+ unicodeslot=0x2AD3,
+ },
+ [0x2AD4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD3,
+ unicodeslot=0x2AD4,
+ },
+ [0x2AD5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD6,
+ unicodeslot=0x2AD5,
+ },
+ [0x2AD6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD5,
+ unicodeslot=0x2AD6,
+ },
+ [0x2AD7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AD7,
+ },
+ [0x2AD8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AD8,
+ },
+ [0x2AD9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AD9,
+ },
+ [0x2ADA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2ADA,
+ },
+ [0x2ADB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2ADB,
+ },
+ [0x2ADC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x2ADD, 0x338 },
+ unicodeslot=0x2ADC,
+ },
+ [0x2ADD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2ADD,
+ },
+ [0x2ADE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22A6,
+ unicodeslot=0x2ADE,
+ },
+ [0x2ADF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2ADF,
+ },
+ [0x2AE0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE0,
+ },
+ [0x2AE1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE1,
+ },
+ [0x2AE2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE2,
+ },
+ [0x2AE3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22A9,
+ unicodeslot=0x2AE3,
+ },
+ [0x2AE4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22A8,
+ unicodeslot=0x2AE4,
+ },
+ [0x2AE5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x22AB,
+ unicodeslot=0x2AE5,
+ },
+ [0x2AE6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE6,
+ },
+ [0x2AE7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE7,
+ },
+ [0x2AE8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE8,
+ },
+ [0x2AE9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE9,
+ },
+ [0x2AEA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AEA,
+ },
+ [0x2AEB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AEB,
+ },
+ [0x2AEC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AED,
+ unicodeslot=0x2AEC,
+ },
+ [0x2AED]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AEC,
+ unicodeslot=0x2AED,
+ },
+ [0x2AEE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2224,
+ unicodeslot=0x2AEE,
+ },
+ [0x2AEF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AEF,
+ },
+ [0x2AF0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF0,
+ },
+ [0x2AF1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF1,
+ },
+ [0x2AF2]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF2,
+ },
+ [0x2AF3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF3,
+ },
+ [0x2AF4]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF4,
+ },
+ [0x2AF5]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF5,
+ },
+ [0x2AF6]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF6,
+ },
+ [0x2AF7]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AF8,
+ unicodeslot=0x2AF7,
+ },
+ [0x2AF8]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AF7,
+ unicodeslot=0x2AF8,
+ },
+ [0x2AF9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AFA,
+ unicodeslot=0x2AF9,
+ },
+ [0x2AFA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AF9,
+ unicodeslot=0x2AFA,
+ },
+ [0x2AFB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AFB,
+ },
+ [0x2AFC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AFC,
+ },
+ [0x2AFD]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AFD,
+ },
+ [0x2AFE]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AFE,
+ },
+ [0x2AFF]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AFF,
+ },
+ [0x2B00]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B00,
+ },
+ [0x2B01]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B01,
+ },
+ [0x2B02]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B02,
+ },
+ [0x2B03]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B03,
+ },
+ [0x2B04]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B04,
+ },
+ [0x2B05]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B05,
+ },
+ [0x2B06]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B06,
+ },
+ [0x2B07]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B07,
+ },
+ [0x2B08]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B08,
+ },
+ [0x2B09]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B09,
+ },
+ [0x2B0A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B0A,
+ },
+ [0x2B0B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B0B,
+ },
+ [0x2B0C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B0C,
+ },
+ [0x2B0D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B0D,
+ },
+ [0x2B0E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B0E,
+ },
+ [0x2B0F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B0F,
+ },
+ [0x2B10]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B10,
+ },
+ [0x2B11]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B11,
+ },
+ [0x2B12]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B12,
+ },
+ [0x2B13]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B13,
+ },
+ [0x2B14]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B14,
+ },
+ [0x2B15]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B15,
+ },
+ [0x2B16]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B16,
+ },
+ [0x2B17]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B17,
+ },
+ [0x2B18]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B18,
+ },
+ [0x2B19]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B19,
+ },
+ [0x2B1A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B1A,
+ },
+ [0x2B1B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B1B,
+ },
+ [0x2B1C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B1C,
+ },
+ [0x2B1D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B1D,
+ },
+ [0x2B1E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B1E,
+ },
+ [0x2B1F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B1F,
+ },
+ [0x2B20]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B20,
+ },
+ [0x2B21]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B21,
+ },
+ [0x2B22]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B22,
+ },
+ [0x2B23]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B23,
+ },
+ [0x2B24]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B24,
+ },
+ [0x2B25]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B25,
+ },
+ [0x2B26]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B26,
+ },
+ [0x2B27]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B27,
+ },
+ [0x2B28]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B28,
+ },
+ [0x2B29]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B29,
+ },
+ [0x2B2A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B2A,
+ },
+ [0x2B2B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B2B,
+ },
+ [0x2B2C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B2C,
+ },
+ [0x2B2D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B2D,
+ },
+ [0x2B2E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B2E,
+ },
+ [0x2B2F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B2F,
+ },
+ [0x2B30]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B30,
+ },
+ [0x2B31]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B31,
+ },
+ [0x2B32]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B32,
+ },
+ [0x2B33]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B33,
+ },
+ [0x2B34]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B34,
+ },
+ [0x2B35]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B35,
+ },
+ [0x2B36]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B36,
+ },
+ [0x2B37]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B37,
+ },
+ [0x2B38]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B38,
+ },
+ [0x2B39]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B39,
+ },
+ [0x2B3A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B3A,
+ },
+ [0x2B3B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B3B,
+ },
+ [0x2B3C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B3C,
+ },
+ [0x2B3D]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B3D,
+ },
+ [0x2B3E]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B3E,
+ },
+ [0x2B3F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B3F,
+ },
+ [0x2B40]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B40,
+ },
+ [0x2B41]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B41,
+ },
+ [0x2B42]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B42,
+ },
+ [0x2B43]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B43,
+ },
+ [0x2B44]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B44,
+ },
+ [0x2B45]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B45,
+ },
+ [0x2B46]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B46,
+ },
+ [0x2B47]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B47,
+ },
+ [0x2B48]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B48,
+ },
+ [0x2B49]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B49,
+ },
+ [0x2B4A]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B4A,
+ },
+ [0x2B4B]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B4B,
+ },
+ [0x2B4C]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B4C,
+ },
+ [0x2B4D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B4D,
+ },
+ [0x2B4E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B4E,
+ },
+ [0x2B4F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B4F,
+ },
+ [0x2B50]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B50,
+ },
+ [0x2B51]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B51,
+ },
+ [0x2B52]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B52,
+ },
+ [0x2B53]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B53,
+ },
+ [0x2B54]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B54,
+ },
+ [0x2B55]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2B55,
+ },
+ [0x2B56]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2B56,
+ },
+ [0x2B57]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2B57,
+ },
+ [0x2B58]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2B58,
+ },
+ [0x2B59]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2B59,
+ },
+ [0x2B5A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B5A,
+ },
+ [0x2B5B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B5B,
+ },
+ [0x2B5C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B5C,
+ },
+ [0x2B5D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B5D,
+ },
+ [0x2B5E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B5E,
+ },
+ [0x2B5F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B5F,
+ },
+ [0x2B60]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B60,
+ },
+ [0x2B61]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B61,
+ },
+ [0x2B62]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B62,
+ },
+ [0x2B63]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B63,
+ },
+ [0x2B64]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B64,
+ },
+ [0x2B65]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B65,
+ },
+ [0x2B66]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B66,
+ },
+ [0x2B67]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B67,
+ },
+ [0x2B68]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B68,
+ },
+ [0x2B69]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B69,
+ },
+ [0x2B6A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B6A,
+ },
+ [0x2B6B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B6B,
+ },
+ [0x2B6C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B6C,
+ },
+ [0x2B6D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B6D,
+ },
+ [0x2B6E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B6E,
+ },
+ [0x2B6F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B6F,
+ },
+ [0x2B70]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B70,
+ },
+ [0x2B71]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B71,
+ },
+ [0x2B72]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B72,
+ },
+ [0x2B73]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B73,
+ },
+ [0x2B76]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B76,
+ },
+ [0x2B77]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B77,
+ },
+ [0x2B78]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B78,
+ },
+ [0x2B79]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B79,
+ },
+ [0x2B7A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B7A,
+ },
+ [0x2B7B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B7B,
+ },
+ [0x2B7C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B7C,
+ },
+ [0x2B7D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B7D,
+ },
+ [0x2B7E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B7E,
+ },
+ [0x2B7F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B7F,
+ },
+ [0x2B80]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B80,
+ },
+ [0x2B81]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B81,
+ },
+ [0x2B82]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B82,
+ },
+ [0x2B83]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B83,
+ },
+ [0x2B84]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B84,
+ },
+ [0x2B85]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B85,
+ },
+ [0x2B86]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B86,
+ },
+ [0x2B87]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B87,
+ },
+ [0x2B88]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B88,
+ },
+ [0x2B89]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B89,
+ },
+ [0x2B8A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B8A,
+ },
+ [0x2B8B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B8B,
+ },
+ [0x2B8C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B8C,
+ },
+ [0x2B8D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B8D,
+ },
+ [0x2B8E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B8E,
+ },
+ [0x2B8F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B8F,
+ },
+ [0x2B90]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B90,
+ },
+ [0x2B91]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B91,
+ },
+ [0x2B92]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B92,
+ },
+ [0x2B93]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B93,
+ },
+ [0x2B94]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B94,
+ },
+ [0x2B95]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B95,
+ },
+ [0x2B98]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B98,
+ },
+ [0x2B99]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B99,
+ },
+ [0x2B9A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B9A,
+ },
+ [0x2B9B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B9B,
+ },
+ [0x2B9C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B9C,
+ },
+ [0x2B9D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B9D,
+ },
+ [0x2B9E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B9E,
+ },
+ [0x2B9F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B9F,
+ },
+ [0x2BA0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BA0,
+ },
+ [0x2BA1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BA1,
+ },
+ [0x2BA2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BA2,
+ },
+ [0x2BA3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BA3,
+ },
+ [0x2BA4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BA4,
+ },
+ [0x2BA5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BA5,
+ },
+ [0x2BA6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BA6,
+ },
+ [0x2BA7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BA7,
+ },
+ [0x2BA8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BA8,
+ },
+ [0x2BA9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BA9,
+ },
+ [0x2BAA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BAA,
+ },
+ [0x2BAB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BAB,
+ },
+ [0x2BAC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BAC,
+ },
+ [0x2BAD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BAD,
+ },
+ [0x2BAE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BAE,
+ },
+ [0x2BAF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BAF,
+ },
+ [0x2BB0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BB0,
+ },
+ [0x2BB1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BB1,
+ },
+ [0x2BB2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BB2,
+ },
+ [0x2BB3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BB3,
+ },
+ [0x2BB4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BB4,
+ },
+ [0x2BB5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BB5,
+ },
+ [0x2BB6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BB6,
+ },
+ [0x2BB7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BB7,
+ },
+ [0x2BB8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BB8,
+ },
+ [0x2BB9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BB9,
+ },
+ [0x2BBA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BBA,
+ },
+ [0x2BBB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BBB,
+ },
+ [0x2BBC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BBC,
+ },
+ [0x2BBD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BBD,
+ },
+ [0x2BBE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BBE,
+ },
+ [0x2BBF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BBF,
+ },
+ [0x2BC0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BC0,
+ },
+ [0x2BC1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BC1,
+ },
+ [0x2BC2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BC2,
+ },
+ [0x2BC3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BC3,
+ },
+ [0x2BC4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BC4,
+ },
+ [0x2BC5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BC5,
+ },
+ [0x2BC6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BC6,
+ },
+ [0x2BC7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BC7,
+ },
+ [0x2BC8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BC8,
+ },
+ [0x2BC9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BC9,
+ },
+ [0x2BCA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BCA,
+ },
+ [0x2BCB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BCB,
+ },
+ [0x2BCC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BCC,
+ },
+ [0x2BCD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BCD,
+ },
+ [0x2BCE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BCE,
+ },
+ [0x2BCF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BCF,
+ },
+ [0x2BD0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BD0,
+ },
+ [0x2BD1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BD1,
+ },
+ [0x2BD2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BD2,
+ },
+ [0x2BD3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BD3,
+ },
+ [0x2BD4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BD4,
+ },
+ [0x2BD5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BD5,
+ },
+ [0x2BD6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BD6,
+ },
+ [0x2BD7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BD7,
+ },
+ [0x2BD8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BD8,
+ },
+ [0x2BD9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BD9,
+ },
+ [0x2BDA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BDA,
+ },
+ [0x2BDB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BDB,
+ },
+ [0x2BDC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BDC,
+ },
+ [0x2BDD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BDD,
+ },
+ [0x2BDE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BDE,
+ },
+ [0x2BDF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BDF,
+ },
+ [0x2BE0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BE0,
+ },
+ [0x2BE1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BE1,
+ },
+ [0x2BE2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BE2,
+ },
+ [0x2BE3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BE3,
+ },
+ [0x2BE4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BE4,
+ },
+ [0x2BE5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BE5,
+ },
+ [0x2BE6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BE6,
+ },
+ [0x2BE7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BE7,
+ },
+ [0x2BE8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BE8,
+ },
+ [0x2BE9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BE9,
+ },
+ [0x2BEA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BEA,
+ },
+ [0x2BEB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BEB,
+ },
+ [0x2BEC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BEC,
+ },
+ [0x2BED]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BED,
+ },
+ [0x2BEE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BEE,
+ },
+ [0x2BEF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BEF,
+ },
+ [0x2BF0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BF0,
+ },
+ [0x2BF1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BF1,
+ },
+ [0x2BF2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BF2,
+ },
+ [0x2BF3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BF3,
+ },
+ [0x2BF4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BF4,
+ },
+ [0x2BF5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BF5,
+ },
+ [0x2BF6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BF6,
+ },
+ [0x2BF7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BF7,
+ },
+ [0x2BF8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BF8,
+ },
+ [0x2BF9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BF9,
+ },
+ [0x2BFA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BFA,
+ },
+ [0x2BFB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BFB,
+ },
+ [0x2BFC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BFC,
+ },
+ [0x2BFD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BFD,
+ },
+ [0x2BFE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ mirror=0x221F,
+ unicodeslot=0x2BFE,
+ },
+ [0x2BFF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2BFF,
+ },
+ [0x2C00]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C00,
+ },
+ [0x2C01]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C01,
+ },
+ [0x2C02]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C02,
+ },
+ [0x2C03]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C03,
+ },
+ [0x2C04]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C04,
+ },
+ [0x2C05]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C05,
+ },
+ [0x2C06]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C06,
+ },
+ [0x2C07]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C07,
+ },
+ [0x2C08]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C08,
+ },
+ [0x2C09]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C09,
+ },
+ [0x2C0A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C0A,
+ },
+ [0x2C0B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C0B,
+ },
+ [0x2C0C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C0C,
+ },
+ [0x2C0D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C0D,
+ },
+ [0x2C0E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C0E,
+ },
+ [0x2C0F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C0F,
+ },
+ [0x2C10]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C10,
+ },
+ [0x2C11]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C11,
+ },
+ [0x2C12]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C12,
+ },
+ [0x2C13]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C13,
+ },
+ [0x2C14]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C14,
+ },
+ [0x2C15]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C15,
+ },
+ [0x2C16]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C16,
+ },
+ [0x2C17]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C17,
+ },
+ [0x2C18]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C18,
+ },
+ [0x2C19]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C19,
+ },
+ [0x2C1A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C1A,
+ },
+ [0x2C1B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C1B,
+ },
+ [0x2C1C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C1C,
+ },
+ [0x2C1D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C1D,
+ },
+ [0x2C1E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C1E,
+ },
+ [0x2C1F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C1F,
+ },
+ [0x2C20]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C20,
+ },
+ [0x2C21]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C21,
+ },
+ [0x2C22]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C22,
+ },
+ [0x2C23]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C23,
+ },
+ [0x2C24]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C24,
+ },
+ [0x2C25]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C25,
+ },
+ [0x2C26]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C26,
+ },
+ [0x2C27]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C27,
+ },
+ [0x2C28]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C28,
+ },
+ [0x2C29]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C29,
+ },
+ [0x2C2A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C2A,
+ },
+ [0x2C2B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C2B,
+ },
+ [0x2C2C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C2C,
+ },
+ [0x2C2D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C2D,
+ },
+ [0x2C2E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C2E,
+ },
+ [0x2C30]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C30,
+ },
+ [0x2C31]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C31,
+ },
+ [0x2C32]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C32,
+ },
+ [0x2C33]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C33,
+ },
+ [0x2C34]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C34,
+ },
+ [0x2C35]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C35,
+ },
+ [0x2C36]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C36,
+ },
+ [0x2C37]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C37,
+ },
+ [0x2C38]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C38,
+ },
+ [0x2C39]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C39,
+ },
+ [0x2C3A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C3A,
+ },
+ [0x2C3B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C3B,
+ },
+ [0x2C3C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C3C,
+ },
+ [0x2C3D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C3D,
+ },
+ [0x2C3E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C3E,
+ },
+ [0x2C3F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C3F,
+ },
+ [0x2C40]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C40,
+ },
+ [0x2C41]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C41,
+ },
+ [0x2C42]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C42,
+ },
+ [0x2C43]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C43,
+ },
+ [0x2C44]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C44,
+ },
+ [0x2C45]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C45,
+ },
+ [0x2C46]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C46,
+ },
+ [0x2C47]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C47,
+ },
+ [0x2C48]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C48,
+ },
+ [0x2C49]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C49,
+ },
+ [0x2C4A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C4A,
+ },
+ [0x2C4B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C4B,
+ },
+ [0x2C4C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C4C,
+ },
+ [0x2C4D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C4D,
+ },
+ [0x2C4E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C4E,
+ },
+ [0x2C4F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C4F,
+ },
+ [0x2C50]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C50,
+ },
+ [0x2C51]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C51,
+ },
+ [0x2C52]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C52,
+ },
+ [0x2C53]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C53,
+ },
+ [0x2C54]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C54,
+ },
+ [0x2C55]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C55,
+ },
+ [0x2C56]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C56,
+ },
+ [0x2C57]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C57,
+ },
+ [0x2C58]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C58,
+ },
+ [0x2C59]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C59,
+ },
+ [0x2C5A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C5A,
+ },
+ [0x2C5B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C5B,
+ },
+ [0x2C5C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C5C,
+ },
+ [0x2C5D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C5D,
+ },
+ [0x2C5E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C5E,
+ },
+ [0x2C60]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C60,
+ },
+ [0x2C61]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C61,
+ },
+ [0x2C62]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C62,
+ },
+ [0x2C63]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C63,
+ },
+ [0x2C64]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C64,
+ },
+ [0x2C65]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C65,
+ },
+ [0x2C66]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C66,
+ },
+ [0x2C67]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C67,
+ },
+ [0x2C68]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C68,
+ },
+ [0x2C69]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C69,
+ },
+ [0x2C6A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C6A,
+ },
+ [0x2C6B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C6B,
+ },
+ [0x2C6C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C6C,
+ },
+ [0x2C6D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C6D,
+ },
+ [0x2C6E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C6E,
+ },
+ [0x2C6F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C6F,
+ },
+ [0x2C70]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C70,
+ },
+ [0x2C71]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C71,
+ },
+ [0x2C72]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C72,
+ },
+ [0x2C73]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C73,
+ },
+ [0x2C74]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C74,
+ },
+ [0x2C75]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C75,
+ },
+ [0x2C76]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C76,
+ },
+ [0x2C77]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C77,
+ },
+ [0x2C78]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C78,
+ },
+ [0x2C79]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C79,
+ },
+ [0x2C7A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C7A,
+ },
+ [0x2C7B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C7B,
+ },
+ [0x2C7C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x6A },
+ unicodeslot=0x2C7C,
+ },
+ [0x2C7D]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x56 },
+ unicodeslot=0x2C7D,
+ },
+ [0x2C7E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C7E,
+ },
+ [0x2C7F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C7F,
+ },
+ [0x2C80]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C80,
+ },
+ [0x2C81]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C81,
+ },
+ [0x2C82]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C82,
+ },
+ [0x2C83]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C83,
+ },
+ [0x2C84]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C84,
+ },
+ [0x2C85]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C85,
+ },
+ [0x2C86]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C86,
+ },
+ [0x2C87]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C87,
+ },
+ [0x2C88]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C88,
+ },
+ [0x2C89]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C89,
+ },
+ [0x2C8A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C8A,
+ },
+ [0x2C8B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C8B,
+ },
+ [0x2C8C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C8C,
+ },
+ [0x2C8D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C8D,
+ },
+ [0x2C8E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C8E,
+ },
+ [0x2C8F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C8F,
+ },
+ [0x2C90]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C90,
+ },
+ [0x2C91]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C91,
+ },
+ [0x2C92]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C92,
+ },
+ [0x2C93]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C93,
+ },
+ [0x2C94]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C94,
+ },
+ [0x2C95]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C95,
+ },
+ [0x2C96]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C96,
+ },
+ [0x2C97]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C97,
+ },
+ [0x2C98]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C98,
+ },
+ [0x2C99]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C99,
+ },
+ [0x2C9A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C9A,
+ },
+ [0x2C9B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C9B,
+ },
+ [0x2C9C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C9C,
+ },
+ [0x2C9D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C9D,
+ },
+ [0x2C9E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C9E,
+ },
+ [0x2C9F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C9F,
+ },
+ [0x2CA0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CA0,
+ },
+ [0x2CA1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CA1,
+ },
+ [0x2CA2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CA2,
+ },
+ [0x2CA3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CA3,
+ },
+ [0x2CA4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CA4,
+ },
+ [0x2CA5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CA5,
+ },
+ [0x2CA6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CA6,
+ },
+ [0x2CA7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CA7,
+ },
+ [0x2CA8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CA8,
+ },
+ [0x2CA9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CA9,
+ },
+ [0x2CAA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CAA,
+ },
+ [0x2CAB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CAB,
+ },
+ [0x2CAC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CAC,
+ },
+ [0x2CAD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CAD,
+ },
+ [0x2CAE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CAE,
+ },
+ [0x2CAF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CAF,
+ },
+ [0x2CB0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CB0,
+ },
+ [0x2CB1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CB1,
+ },
+ [0x2CB2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CB2,
+ },
+ [0x2CB3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CB3,
+ },
+ [0x2CB4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CB4,
+ },
+ [0x2CB5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CB5,
+ },
+ [0x2CB6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CB6,
+ },
+ [0x2CB7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CB7,
+ },
+ [0x2CB8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CB8,
+ },
+ [0x2CB9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CB9,
+ },
+ [0x2CBA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CBA,
+ },
+ [0x2CBB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CBB,
+ },
+ [0x2CBC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CBC,
+ },
+ [0x2CBD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CBD,
+ },
+ [0x2CBE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CBE,
+ },
+ [0x2CBF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CBF,
+ },
+ [0x2CC0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CC0,
+ },
+ [0x2CC1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CC1,
+ },
+ [0x2CC2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CC2,
+ },
+ [0x2CC3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CC3,
+ },
+ [0x2CC4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CC4,
+ },
+ [0x2CC5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CC5,
+ },
+ [0x2CC6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CC6,
+ },
+ [0x2CC7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CC7,
+ },
+ [0x2CC8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CC8,
+ },
+ [0x2CC9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CC9,
+ },
+ [0x2CCA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CCA,
+ },
+ [0x2CCB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CCB,
+ },
+ [0x2CCC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CCC,
+ },
+ [0x2CCD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CCD,
+ },
+ [0x2CCE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CCE,
+ },
+ [0x2CCF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CCF,
+ },
+ [0x2CD0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CD0,
+ },
+ [0x2CD1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CD1,
+ },
+ [0x2CD2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CD2,
+ },
+ [0x2CD3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CD3,
+ },
+ [0x2CD4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CD4,
+ },
+ [0x2CD5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CD5,
+ },
+ [0x2CD6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CD6,
+ },
+ [0x2CD7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CD7,
+ },
+ [0x2CD8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CD8,
+ },
+ [0x2CD9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CD9,
+ },
+ [0x2CDA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CDA,
+ },
+ [0x2CDB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CDB,
+ },
+ [0x2CDC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CDC,
+ },
+ [0x2CDD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CDD,
+ },
+ [0x2CDE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CDE,
+ },
+ [0x2CDF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CDF,
+ },
+ [0x2CE0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CE0,
+ },
+ [0x2CE1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CE1,
+ },
+ [0x2CE2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CE2,
+ },
+ [0x2CE3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CE3,
+ },
+ [0x2CE4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CE4,
+ },
+ [0x2CE5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CE5,
+ },
+ [0x2CE6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CE6,
+ },
+ [0x2CE7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CE7,
+ },
+ [0x2CE8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CE8,
+ },
+ [0x2CE9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CE9,
+ },
+ [0x2CEA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CEA,
+ },
+ [0x2CEB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CEB,
+ },
+ [0x2CEC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CEC,
+ },
+ [0x2CED]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CED,
+ },
+ [0x2CEE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CEE,
+ },
+ [0x2CEF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2CEF,
+ },
+ [0x2CF0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2CF0,
+ },
+ [0x2CF1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2CF1,
+ },
+ [0x2CF2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CF2,
+ },
+ [0x2CF3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CF3,
+ },
+ [0x2CF9]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x2CF9,
+ },
+ [0x2CFA]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2CFA,
+ },
+ [0x2CFB]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2CFB,
+ },
+ [0x2CFC]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2CFC,
+ },
+ [0x2CFD]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CFD,
+ },
+ [0x2CFE]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x2CFE,
+ },
+ [0x2CFF]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2CFF,
+ },
+ [0x2D00]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D00,
+ },
+ [0x2D01]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D01,
+ },
+ [0x2D02]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D02,
+ },
+ [0x2D03]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D03,
+ },
+ [0x2D04]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D04,
+ },
+ [0x2D05]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D05,
+ },
+ [0x2D06]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D06,
+ },
+ [0x2D07]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D07,
+ },
+ [0x2D08]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D08,
+ },
+ [0x2D09]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D09,
+ },
+ [0x2D0A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D0A,
+ },
+ [0x2D0B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D0B,
+ },
+ [0x2D0C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D0C,
+ },
+ [0x2D0D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D0D,
+ },
+ [0x2D0E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D0E,
+ },
+ [0x2D0F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D0F,
+ },
+ [0x2D10]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D10,
+ },
+ [0x2D11]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D11,
+ },
+ [0x2D12]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D12,
+ },
+ [0x2D13]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D13,
+ },
+ [0x2D14]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D14,
+ },
+ [0x2D15]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D15,
+ },
+ [0x2D16]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D16,
+ },
+ [0x2D17]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D17,
+ },
+ [0x2D18]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D18,
+ },
+ [0x2D19]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D19,
+ },
+ [0x2D1A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D1A,
+ },
+ [0x2D1B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D1B,
+ },
+ [0x2D1C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D1C,
+ },
+ [0x2D1D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D1D,
+ },
+ [0x2D1E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D1E,
+ },
+ [0x2D1F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D1F,
+ },
+ [0x2D20]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D20,
+ },
+ [0x2D21]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D21,
+ },
+ [0x2D22]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D22,
+ },
+ [0x2D23]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D23,
+ },
+ [0x2D24]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D24,
+ },
+ [0x2D25]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D25,
+ },
+ [0x2D27]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D27,
+ },
+ [0x2D2D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D2D,
+ },
+ [0x2D30]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D30,
+ },
+ [0x2D31]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D31,
+ },
+ [0x2D32]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D32,
+ },
+ [0x2D33]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D33,
+ },
+ [0x2D34]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D34,
+ },
+ [0x2D35]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D35,
+ },
+ [0x2D36]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D36,
+ },
+ [0x2D37]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D37,
+ },
+ [0x2D38]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D38,
+ },
+ [0x2D39]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D39,
+ },
+ [0x2D3A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D3A,
+ },
+ [0x2D3B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D3B,
+ },
+ [0x2D3C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D3C,
+ },
+ [0x2D3D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D3D,
+ },
+ [0x2D3E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D3E,
+ },
+ [0x2D3F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D3F,
+ },
+ [0x2D40]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D40,
+ },
+ [0x2D41]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D41,
+ },
+ [0x2D42]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D42,
+ },
+ [0x2D43]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D43,
+ },
+ [0x2D44]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D44,
+ },
+ [0x2D45]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D45,
+ },
+ [0x2D46]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D46,
+ },
+ [0x2D47]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D47,
+ },
+ [0x2D48]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D48,
+ },
+ [0x2D49]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D49,
+ },
+ [0x2D4A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D4A,
+ },
+ [0x2D4B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D4B,
+ },
+ [0x2D4C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D4C,
+ },
+ [0x2D4D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D4D,
+ },
+ [0x2D4E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D4E,
+ },
+ [0x2D4F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D4F,
+ },
+ [0x2D50]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D50,
+ },
+ [0x2D51]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D51,
+ },
+ [0x2D52]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D52,
+ },
+ [0x2D53]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D53,
+ },
+ [0x2D54]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D54,
+ },
+ [0x2D55]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D55,
+ },
+ [0x2D56]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D56,
+ },
+ [0x2D57]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D57,
+ },
+ [0x2D58]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D58,
+ },
+ [0x2D59]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D59,
+ },
+ [0x2D5A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D5A,
+ },
+ [0x2D5B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D5B,
+ },
+ [0x2D5C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D5C,
+ },
+ [0x2D5D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D5D,
+ },
+ [0x2D5E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D5E,
+ },
+ [0x2D5F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D5F,
+ },
+ [0x2D60]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D60,
+ },
+ [0x2D61]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D61,
+ },
+ [0x2D62]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D62,
+ },
+ [0x2D63]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D63,
+ },
+ [0x2D64]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D64,
+ },
+ [0x2D65]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D65,
+ },
+ [0x2D66]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D66,
+ },
+ [0x2D67]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D67,
+ },
+ [0x2D6F]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x2D61 },
+ unicodeslot=0x2D6F,
+ },
+ [0x2D70]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x2D70,
+ },
+ [0x2D7F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2D7F,
+ },
+ [0x2D80]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D80,
+ },
+ [0x2D81]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D81,
+ },
+ [0x2D82]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D82,
+ },
+ [0x2D83]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D83,
+ },
+ [0x2D84]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D84,
+ },
+ [0x2D85]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D85,
+ },
+ [0x2D86]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D86,
+ },
+ [0x2D87]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D87,
+ },
+ [0x2D88]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D88,
+ },
+ [0x2D89]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D89,
+ },
+ [0x2D8A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D8A,
+ },
+ [0x2D8B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D8B,
+ },
+ [0x2D8C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D8C,
+ },
+ [0x2D8D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D8D,
+ },
+ [0x2D8E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D8E,
+ },
+ [0x2D8F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D8F,
+ },
+ [0x2D90]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D90,
+ },
+ [0x2D91]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D91,
+ },
+ [0x2D92]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D92,
+ },
+ [0x2D93]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D93,
+ },
+ [0x2D94]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D94,
+ },
+ [0x2D95]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D95,
+ },
+ [0x2D96]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D96,
+ },
+ [0x2DA0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA0,
+ },
+ [0x2DA1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA1,
+ },
+ [0x2DA2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA2,
+ },
+ [0x2DA3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA3,
+ },
+ [0x2DA4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA4,
+ },
+ [0x2DA5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA5,
+ },
+ [0x2DA6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA6,
+ },
+ [0x2DA8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA8,
+ },
+ [0x2DA9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA9,
+ },
+ [0x2DAA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DAA,
+ },
+ [0x2DAB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DAB,
+ },
+ [0x2DAC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DAC,
+ },
+ [0x2DAD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DAD,
+ },
+ [0x2DAE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DAE,
+ },
+ [0x2DB0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB0,
+ },
+ [0x2DB1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB1,
+ },
+ [0x2DB2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB2,
+ },
+ [0x2DB3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB3,
+ },
+ [0x2DB4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB4,
+ },
+ [0x2DB5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB5,
+ },
+ [0x2DB6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB6,
+ },
+ [0x2DB8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB8,
+ },
+ [0x2DB9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB9,
+ },
+ [0x2DBA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DBA,
+ },
+ [0x2DBB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DBB,
+ },
+ [0x2DBC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DBC,
+ },
+ [0x2DBD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DBD,
+ },
+ [0x2DBE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DBE,
+ },
+ [0x2DC0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC0,
+ },
+ [0x2DC1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC1,
+ },
+ [0x2DC2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC2,
+ },
+ [0x2DC3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC3,
+ },
+ [0x2DC4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC4,
+ },
+ [0x2DC5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC5,
+ },
+ [0x2DC6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC6,
+ },
+ [0x2DC8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC8,
+ },
+ [0x2DC9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC9,
+ },
+ [0x2DCA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DCA,
+ },
+ [0x2DCB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DCB,
+ },
+ [0x2DCC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DCC,
+ },
+ [0x2DCD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DCD,
+ },
+ [0x2DCE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DCE,
+ },
+ [0x2DD0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD0,
+ },
+ [0x2DD1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD1,
+ },
+ [0x2DD2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD2,
+ },
+ [0x2DD3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD3,
+ },
+ [0x2DD4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD4,
+ },
+ [0x2DD5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD5,
+ },
+ [0x2DD6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD6,
+ },
+ [0x2DD8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD8,
+ },
+ [0x2DD9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD9,
+ },
+ [0x2DDA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DDA,
+ },
+ [0x2DDB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DDB,
+ },
+ [0x2DDC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DDC,
+ },
+ [0x2DDD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DDD,
+ },
+ [0x2DDE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DDE,
+ },
+ [0x2DE0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE0,
+ },
+ [0x2DE1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE1,
+ },
+ [0x2DE2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE2,
+ },
+ [0x2DE3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE3,
+ },
+ [0x2DE4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE4,
+ },
+ [0x2DE5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE5,
+ },
+ [0x2DE6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE6,
+ },
+ [0x2DE7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE7,
+ },
+ [0x2DE8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE8,
+ },
+ [0x2DE9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE9,
+ },
+ [0x2DEA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DEA,
+ },
+ [0x2DEB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DEB,
+ },
+ [0x2DEC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DEC,
+ },
+ [0x2DED]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DED,
+ },
+ [0x2DEE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DEE,
+ },
+ [0x2DEF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DEF,
+ },
+ [0x2DF0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF0,
+ },
+ [0x2DF1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF1,
+ },
+ [0x2DF2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF2,
+ },
+ [0x2DF3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF3,
+ },
+ [0x2DF4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF4,
+ },
+ [0x2DF5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF5,
+ },
+ [0x2DF6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF6,
+ },
+ [0x2DF7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF7,
+ },
+ [0x2DF8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF8,
+ },
+ [0x2DF9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF9,
+ },
+ [0x2DFA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DFA,
+ },
+ [0x2DFB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DFB,
+ },
+ [0x2DFC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DFC,
+ },
+ [0x2DFD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DFD,
+ },
+ [0x2DFE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DFE,
+ },
+ [0x2DFF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DFF,
+ },
+ [0x2E00]={
+ category="po",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2E00,
+ },
+ [0x2E01]={
+ category="po",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2E01,
+ },
+ [0x2E02]={
+ category="pi",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E03,
+ unicodeslot=0x2E02,
+ },
+ [0x2E03]={
+ category="pf",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E02,
+ unicodeslot=0x2E03,
+ },
+ [0x2E04]={
+ category="pi",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E05,
+ unicodeslot=0x2E04,
+ },
+ [0x2E05]={
+ category="pf",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E04,
+ unicodeslot=0x2E05,
+ },
+ [0x2E06]={
+ category="po",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2E06,
+ },
+ [0x2E07]={
+ category="po",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2E07,
+ },
+ [0x2E08]={
+ category="po",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2E08,
+ },
+ [0x2E09]={
+ category="pi",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E0A,
+ unicodeslot=0x2E09,
+ },
+ [0x2E0A]={
+ category="pf",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E09,
+ unicodeslot=0x2E0A,
+ },
+ [0x2E0B]={
+ category="po",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2E0B,
+ },
+ [0x2E0C]={
+ category="pi",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E0D,
+ unicodeslot=0x2E0C,
+ },
+ [0x2E0D]={
+ category="pf",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E0C,
+ unicodeslot=0x2E0D,
+ },
+ [0x2E0E]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E0E,
+ },
+ [0x2E0F]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E0F,
+ },
+ [0x2E10]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E10,
+ },
+ [0x2E11]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E11,
+ },
+ [0x2E12]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E12,
+ },
+ [0x2E13]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E13,
+ },
+ [0x2E14]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E14,
+ },
+ [0x2E15]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E15,
+ },
+ [0x2E16]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E16,
+ },
+ [0x2E17]={
+ category="pd",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E17,
+ },
+ [0x2E18]={
+ category="po",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0x2E18,
+ },
+ [0x2E19]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E19,
+ },
+ [0x2E1A]={
+ category="pd",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E1A,
+ },
+ [0x2E1B]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E1B,
+ },
+ [0x2E1C]={
+ category="pi",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E1D,
+ unicodeslot=0x2E1C,
+ },
+ [0x2E1D]={
+ category="pf",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E1C,
+ unicodeslot=0x2E1D,
+ },
+ [0x2E1E]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E1E,
+ },
+ [0x2E1F]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E1F,
+ },
+ [0x2E20]={
+ category="pi",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E21,
+ unicodeslot=0x2E20,
+ },
+ [0x2E21]={
+ category="pf",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E20,
+ unicodeslot=0x2E21,
+ },
+ [0x2E22]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2E23,
+ unicodeslot=0x2E22,
+ },
+ [0x2E23]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2E22,
+ unicodeslot=0x2E23,
+ },
+ [0x2E24]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2E25,
+ unicodeslot=0x2E24,
+ },
+ [0x2E25]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2E24,
+ unicodeslot=0x2E25,
+ },
+ [0x2E26]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2E27,
+ unicodeslot=0x2E26,
+ },
+ [0x2E27]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2E26,
+ unicodeslot=0x2E27,
+ },
+ [0x2E28]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x2E29,
+ unicodeslot=0x2E28,
+ },
+ [0x2E29]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2E28,
+ unicodeslot=0x2E29,
+ },
+ [0x2E2A]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E2A,
+ },
+ [0x2E2B]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E2B,
+ },
+ [0x2E2C]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E2C,
+ },
+ [0x2E2D]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E2D,
+ },
+ [0x2E2E]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x2E2E,
+ },
+ [0x2E2F]={
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E2F,
+ },
+ [0x2E30]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E30,
+ },
+ [0x2E31]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E31,
+ },
+ [0x2E32]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E32,
+ },
+ [0x2E33]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E33,
+ },
+ [0x2E34]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E34,
+ },
+ [0x2E35]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E35,
+ },
+ [0x2E36]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E36,
+ },
+ [0x2E37]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E37,
+ },
+ [0x2E38]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E38,
+ },
+ [0x2E39]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E39,
+ },
+ [0x2E3A]={
+ category="pd",
+ direction="on",
+ linebreak="b2",
+ unicodeslot=0x2E3A,
+ },
+ [0x2E3B]={
+ category="pd",
+ direction="on",
+ linebreak="b2",
+ unicodeslot=0x2E3B,
+ },
+ [0x2E3C]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E3C,
+ },
+ [0x2E3D]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E3D,
+ },
+ [0x2E3E]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E3E,
+ },
+ [0x2E3F]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E3F,
+ },
+ [0x2E40]={
+ category="pd",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E40,
+ },
+ [0x2E41]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E41,
+ },
+ [0x2E42]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0x2E42,
+ },
+ [0x2E43]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E43,
+ },
+ [0x2E44]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E44,
+ },
+ [0x2E45]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E45,
+ },
+ [0x2E46]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E46,
+ },
+ [0x2E47]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E47,
+ },
+ [0x2E48]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E48,
+ },
+ [0x2E49]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E49,
+ },
+ [0x2E4A]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E4A,
+ },
+ [0x2E4B]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E4B,
+ },
+ [0x2E4C]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E4C,
+ },
+ [0x2E4D]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E4D,
+ },
+ [0x2E4E]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E4E,
+ },
+ [0x2E4F]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E4F,
+ },
+ [0x2E80]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E80,
+ },
+ [0x2E81]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E81,
+ },
+ [0x2E82]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E82,
+ },
+ [0x2E83]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E83,
+ },
+ [0x2E84]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E84,
+ },
+ [0x2E85]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E85,
+ },
+ [0x2E86]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E86,
+ },
+ [0x2E87]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E87,
+ },
+ [0x2E88]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E88,
+ },
+ [0x2E89]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E89,
+ },
+ [0x2E8A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E8A,
+ },
+ [0x2E8B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E8B,
+ },
+ [0x2E8C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E8C,
+ },
+ [0x2E8D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E8D,
+ },
+ [0x2E8E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E8E,
+ },
+ [0x2E8F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E8F,
+ },
+ [0x2E90]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E90,
+ },
+ [0x2E91]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E91,
+ },
+ [0x2E92]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E92,
+ },
+ [0x2E93]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E93,
+ },
+ [0x2E94]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E94,
+ },
+ [0x2E95]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E95,
+ },
+ [0x2E96]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E96,
+ },
+ [0x2E97]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E97,
+ },
+ [0x2E98]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E98,
+ },
+ [0x2E99]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E99,
+ },
+ [0x2E9B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E9B,
+ },
+ [0x2E9C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E9C,
+ },
+ [0x2E9D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E9D,
+ },
+ [0x2E9E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E9E,
+ },
+ [0x2E9F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6BCD },
+ unicodeslot=0x2E9F,
+ },
+ [0x2EA0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA0,
+ },
+ [0x2EA1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA1,
+ },
+ [0x2EA2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA2,
+ },
+ [0x2EA3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA3,
+ },
+ [0x2EA4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA4,
+ },
+ [0x2EA5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA5,
+ },
+ [0x2EA6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA6,
+ },
+ [0x2EA7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA7,
+ },
+ [0x2EA8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA8,
+ },
+ [0x2EA9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA9,
+ },
+ [0x2EAA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EAA,
+ },
+ [0x2EAB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EAB,
+ },
+ [0x2EAC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EAC,
+ },
+ [0x2EAD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EAD,
+ },
+ [0x2EAE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EAE,
+ },
+ [0x2EAF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EAF,
+ },
+ [0x2EB0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB0,
+ },
+ [0x2EB1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB1,
+ },
+ [0x2EB2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB2,
+ },
+ [0x2EB3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB3,
+ },
+ [0x2EB4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB4,
+ },
+ [0x2EB5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB5,
+ },
+ [0x2EB6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB6,
+ },
+ [0x2EB7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB7,
+ },
+ [0x2EB8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB8,
+ },
+ [0x2EB9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB9,
+ },
+ [0x2EBA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EBA,
+ },
+ [0x2EBB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EBB,
+ },
+ [0x2EBC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EBC,
+ },
+ [0x2EBD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EBD,
+ },
+ [0x2EBE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EBE,
+ },
+ [0x2EBF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EBF,
+ },
+ [0x2EC0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC0,
+ },
+ [0x2EC1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC1,
+ },
+ [0x2EC2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC2,
+ },
+ [0x2EC3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC3,
+ },
+ [0x2EC4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC4,
+ },
+ [0x2EC5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC5,
+ },
+ [0x2EC6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC6,
+ },
+ [0x2EC7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC7,
+ },
+ [0x2EC8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC8,
+ },
+ [0x2EC9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC9,
+ },
+ [0x2ECA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ECA,
+ },
+ [0x2ECB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ECB,
+ },
+ [0x2ECC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ECC,
+ },
+ [0x2ECD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ECD,
+ },
+ [0x2ECE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ECE,
+ },
+ [0x2ECF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ECF,
+ },
+ [0x2ED0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED0,
+ },
+ [0x2ED1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED1,
+ },
+ [0x2ED2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED2,
+ },
+ [0x2ED3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED3,
+ },
+ [0x2ED4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED4,
+ },
+ [0x2ED5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED5,
+ },
+ [0x2ED6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED6,
+ },
+ [0x2ED7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED7,
+ },
+ [0x2ED8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED8,
+ },
+ [0x2ED9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED9,
+ },
+ [0x2EDA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EDA,
+ },
+ [0x2EDB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EDB,
+ },
+ [0x2EDC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EDC,
+ },
+ [0x2EDD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EDD,
+ },
+ [0x2EDE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EDE,
+ },
+ [0x2EDF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EDF,
+ },
+ [0x2EE0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE0,
+ },
+ [0x2EE1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE1,
+ },
+ [0x2EE2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE2,
+ },
+ [0x2EE3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE3,
+ },
+ [0x2EE4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE4,
+ },
+ [0x2EE5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE5,
+ },
+ [0x2EE6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE6,
+ },
+ [0x2EE7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE7,
+ },
+ [0x2EE8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE8,
+ },
+ [0x2EE9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE9,
+ },
+ [0x2EEA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EEA,
+ },
+ [0x2EEB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EEB,
+ },
+ [0x2EEC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EEC,
+ },
+ [0x2EED]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EED,
+ },
+ [0x2EEE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EEE,
+ },
+ [0x2EEF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EEF,
+ },
+ [0x2EF0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EF0,
+ },
+ [0x2EF1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EF1,
+ },
+ [0x2EF2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EF2,
+ },
+ [0x2EF3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F9F },
+ unicodeslot=0x2EF3,
+ },
+ [0x2F00]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E00 },
+ unicodeslot=0x2F00,
+ },
+ [0x2F01]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E28 },
+ unicodeslot=0x2F01,
+ },
+ [0x2F02]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E36 },
+ unicodeslot=0x2F02,
+ },
+ [0x2F03]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E3F },
+ unicodeslot=0x2F03,
+ },
+ [0x2F04]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E59 },
+ unicodeslot=0x2F04,
+ },
+ [0x2F05]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E85 },
+ unicodeslot=0x2F05,
+ },
+ [0x2F06]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E8C },
+ unicodeslot=0x2F06,
+ },
+ [0x2F07]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4EA0 },
+ unicodeslot=0x2F07,
+ },
+ [0x2F08]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4EBA },
+ unicodeslot=0x2F08,
+ },
+ [0x2F09]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x513F },
+ unicodeslot=0x2F09,
+ },
+ [0x2F0A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5165 },
+ unicodeslot=0x2F0A,
+ },
+ [0x2F0B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x516B },
+ unicodeslot=0x2F0B,
+ },
+ [0x2F0C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5182 },
+ unicodeslot=0x2F0C,
+ },
+ [0x2F0D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5196 },
+ unicodeslot=0x2F0D,
+ },
+ [0x2F0E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x51AB },
+ unicodeslot=0x2F0E,
+ },
+ [0x2F0F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x51E0 },
+ unicodeslot=0x2F0F,
+ },
+ [0x2F10]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x51F5 },
+ unicodeslot=0x2F10,
+ },
+ [0x2F11]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5200 },
+ unicodeslot=0x2F11,
+ },
+ [0x2F12]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x529B },
+ unicodeslot=0x2F12,
+ },
+ [0x2F13]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x52F9 },
+ unicodeslot=0x2F13,
+ },
+ [0x2F14]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5315 },
+ unicodeslot=0x2F14,
+ },
+ [0x2F15]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x531A },
+ unicodeslot=0x2F15,
+ },
+ [0x2F16]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5338 },
+ unicodeslot=0x2F16,
+ },
+ [0x2F17]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5341 },
+ unicodeslot=0x2F17,
+ },
+ [0x2F18]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x535C },
+ unicodeslot=0x2F18,
+ },
+ [0x2F19]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5369 },
+ unicodeslot=0x2F19,
+ },
+ [0x2F1A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5382 },
+ unicodeslot=0x2F1A,
+ },
+ [0x2F1B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x53B6 },
+ unicodeslot=0x2F1B,
+ },
+ [0x2F1C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x53C8 },
+ unicodeslot=0x2F1C,
+ },
+ [0x2F1D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x53E3 },
+ unicodeslot=0x2F1D,
+ },
+ [0x2F1E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x56D7 },
+ unicodeslot=0x2F1E,
+ },
+ [0x2F1F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x571F },
+ unicodeslot=0x2F1F,
+ },
+ [0x2F20]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x58EB },
+ unicodeslot=0x2F20,
+ },
+ [0x2F21]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5902 },
+ unicodeslot=0x2F21,
+ },
+ [0x2F22]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x590A },
+ unicodeslot=0x2F22,
+ },
+ [0x2F23]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5915 },
+ unicodeslot=0x2F23,
+ },
+ [0x2F24]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5927 },
+ unicodeslot=0x2F24,
+ },
+ [0x2F25]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5973 },
+ unicodeslot=0x2F25,
+ },
+ [0x2F26]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5B50 },
+ unicodeslot=0x2F26,
+ },
+ [0x2F27]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5B80 },
+ unicodeslot=0x2F27,
+ },
+ [0x2F28]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5BF8 },
+ unicodeslot=0x2F28,
+ },
+ [0x2F29]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5C0F },
+ unicodeslot=0x2F29,
+ },
+ [0x2F2A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5C22 },
+ unicodeslot=0x2F2A,
+ },
+ [0x2F2B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5C38 },
+ unicodeslot=0x2F2B,
+ },
+ [0x2F2C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5C6E },
+ unicodeslot=0x2F2C,
+ },
+ [0x2F2D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5C71 },
+ unicodeslot=0x2F2D,
+ },
+ [0x2F2E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5DDB },
+ unicodeslot=0x2F2E,
+ },
+ [0x2F2F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5DE5 },
+ unicodeslot=0x2F2F,
+ },
+ [0x2F30]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5DF1 },
+ unicodeslot=0x2F30,
+ },
+ [0x2F31]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5DFE },
+ unicodeslot=0x2F31,
+ },
+ [0x2F32]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5E72 },
+ unicodeslot=0x2F32,
+ },
+ [0x2F33]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5E7A },
+ unicodeslot=0x2F33,
+ },
+ [0x2F34]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5E7F },
+ unicodeslot=0x2F34,
+ },
+ [0x2F35]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5EF4 },
+ unicodeslot=0x2F35,
+ },
+ [0x2F36]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5EFE },
+ unicodeslot=0x2F36,
+ },
+ [0x2F37]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F0B },
+ unicodeslot=0x2F37,
+ },
+ [0x2F38]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F13 },
+ unicodeslot=0x2F38,
+ },
+ [0x2F39]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F50 },
+ unicodeslot=0x2F39,
+ },
+ [0x2F3A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F61 },
+ unicodeslot=0x2F3A,
+ },
+ [0x2F3B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F73 },
+ unicodeslot=0x2F3B,
+ },
+ [0x2F3C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5FC3 },
+ unicodeslot=0x2F3C,
+ },
+ [0x2F3D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6208 },
+ unicodeslot=0x2F3D,
+ },
+ [0x2F3E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6236 },
+ unicodeslot=0x2F3E,
+ },
+ [0x2F3F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x624B },
+ unicodeslot=0x2F3F,
+ },
+ [0x2F40]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x652F },
+ unicodeslot=0x2F40,
+ },
+ [0x2F41]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6534 },
+ unicodeslot=0x2F41,
+ },
+ [0x2F42]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6587 },
+ unicodeslot=0x2F42,
+ },
+ [0x2F43]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6597 },
+ unicodeslot=0x2F43,
+ },
+ [0x2F44]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x65A4 },
+ unicodeslot=0x2F44,
+ },
+ [0x2F45]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x65B9 },
+ unicodeslot=0x2F45,
+ },
+ [0x2F46]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x65E0 },
+ unicodeslot=0x2F46,
+ },
+ [0x2F47]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x65E5 },
+ unicodeslot=0x2F47,
+ },
+ [0x2F48]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x66F0 },
+ unicodeslot=0x2F48,
+ },
+ [0x2F49]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6708 },
+ unicodeslot=0x2F49,
+ },
+ [0x2F4A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6728 },
+ unicodeslot=0x2F4A,
+ },
+ [0x2F4B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6B20 },
+ unicodeslot=0x2F4B,
+ },
+ [0x2F4C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6B62 },
+ unicodeslot=0x2F4C,
+ },
+ [0x2F4D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6B79 },
+ unicodeslot=0x2F4D,
+ },
+ [0x2F4E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6BB3 },
+ unicodeslot=0x2F4E,
+ },
+ [0x2F4F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6BCB },
+ unicodeslot=0x2F4F,
+ },
+ [0x2F50]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6BD4 },
+ unicodeslot=0x2F50,
+ },
+ [0x2F51]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6BDB },
+ unicodeslot=0x2F51,
+ },
+ [0x2F52]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6C0F },
+ unicodeslot=0x2F52,
+ },
+ [0x2F53]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6C14 },
+ unicodeslot=0x2F53,
+ },
+ [0x2F54]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6C34 },
+ unicodeslot=0x2F54,
+ },
+ [0x2F55]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x706B },
+ unicodeslot=0x2F55,
+ },
+ [0x2F56]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x722A },
+ unicodeslot=0x2F56,
+ },
+ [0x2F57]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7236 },
+ unicodeslot=0x2F57,
+ },
+ [0x2F58]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x723B },
+ unicodeslot=0x2F58,
+ },
+ [0x2F59]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x723F },
+ unicodeslot=0x2F59,
+ },
+ [0x2F5A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7247 },
+ unicodeslot=0x2F5A,
+ },
+ [0x2F5B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7259 },
+ unicodeslot=0x2F5B,
+ },
+ [0x2F5C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x725B },
+ unicodeslot=0x2F5C,
+ },
+ [0x2F5D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x72AC },
+ unicodeslot=0x2F5D,
+ },
+ [0x2F5E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7384 },
+ unicodeslot=0x2F5E,
+ },
+ [0x2F5F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7389 },
+ unicodeslot=0x2F5F,
+ },
+ [0x2F60]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x74DC },
+ unicodeslot=0x2F60,
+ },
+ [0x2F61]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x74E6 },
+ unicodeslot=0x2F61,
+ },
+ [0x2F62]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7518 },
+ unicodeslot=0x2F62,
+ },
+ [0x2F63]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x751F },
+ unicodeslot=0x2F63,
+ },
+ [0x2F64]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7528 },
+ unicodeslot=0x2F64,
+ },
+ [0x2F65]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7530 },
+ unicodeslot=0x2F65,
+ },
+ [0x2F66]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x758B },
+ unicodeslot=0x2F66,
+ },
+ [0x2F67]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7592 },
+ unicodeslot=0x2F67,
+ },
+ [0x2F68]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7676 },
+ unicodeslot=0x2F68,
+ },
+ [0x2F69]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x767D },
+ unicodeslot=0x2F69,
+ },
+ [0x2F6A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x76AE },
+ unicodeslot=0x2F6A,
+ },
+ [0x2F6B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x76BF },
+ unicodeslot=0x2F6B,
+ },
+ [0x2F6C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x76EE },
+ unicodeslot=0x2F6C,
+ },
+ [0x2F6D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x77DB },
+ unicodeslot=0x2F6D,
+ },
+ [0x2F6E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x77E2 },
+ unicodeslot=0x2F6E,
+ },
+ [0x2F6F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x77F3 },
+ unicodeslot=0x2F6F,
+ },
+ [0x2F70]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x793A },
+ unicodeslot=0x2F70,
+ },
+ [0x2F71]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x79B8 },
+ unicodeslot=0x2F71,
+ },
+ [0x2F72]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x79BE },
+ unicodeslot=0x2F72,
+ },
+ [0x2F73]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7A74 },
+ unicodeslot=0x2F73,
+ },
+ [0x2F74]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7ACB },
+ unicodeslot=0x2F74,
+ },
+ [0x2F75]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7AF9 },
+ unicodeslot=0x2F75,
+ },
+ [0x2F76]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7C73 },
+ unicodeslot=0x2F76,
+ },
+ [0x2F77]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7CF8 },
+ unicodeslot=0x2F77,
+ },
+ [0x2F78]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7F36 },
+ unicodeslot=0x2F78,
+ },
+ [0x2F79]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7F51 },
+ unicodeslot=0x2F79,
+ },
+ [0x2F7A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7F8A },
+ unicodeslot=0x2F7A,
+ },
+ [0x2F7B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7FBD },
+ unicodeslot=0x2F7B,
+ },
+ [0x2F7C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8001 },
+ unicodeslot=0x2F7C,
+ },
+ [0x2F7D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x800C },
+ unicodeslot=0x2F7D,
+ },
+ [0x2F7E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8012 },
+ unicodeslot=0x2F7E,
+ },
+ [0x2F7F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8033 },
+ unicodeslot=0x2F7F,
+ },
+ [0x2F80]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x807F },
+ unicodeslot=0x2F80,
+ },
+ [0x2F81]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8089 },
+ unicodeslot=0x2F81,
+ },
+ [0x2F82]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x81E3 },
+ unicodeslot=0x2F82,
+ },
+ [0x2F83]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x81EA },
+ unicodeslot=0x2F83,
+ },
+ [0x2F84]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x81F3 },
+ unicodeslot=0x2F84,
+ },
+ [0x2F85]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x81FC },
+ unicodeslot=0x2F85,
+ },
+ [0x2F86]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x820C },
+ unicodeslot=0x2F86,
+ },
+ [0x2F87]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x821B },
+ unicodeslot=0x2F87,
+ },
+ [0x2F88]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x821F },
+ unicodeslot=0x2F88,
+ },
+ [0x2F89]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x826E },
+ unicodeslot=0x2F89,
+ },
+ [0x2F8A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8272 },
+ unicodeslot=0x2F8A,
+ },
+ [0x2F8B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8278 },
+ unicodeslot=0x2F8B,
+ },
+ [0x2F8C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x864D },
+ unicodeslot=0x2F8C,
+ },
+ [0x2F8D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x866B },
+ unicodeslot=0x2F8D,
+ },
+ [0x2F8E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8840 },
+ unicodeslot=0x2F8E,
+ },
+ [0x2F8F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x884C },
+ unicodeslot=0x2F8F,
+ },
+ [0x2F90]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8863 },
+ unicodeslot=0x2F90,
+ },
+ [0x2F91]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x897E },
+ unicodeslot=0x2F91,
+ },
+ [0x2F92]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x898B },
+ unicodeslot=0x2F92,
+ },
+ [0x2F93]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x89D2 },
+ unicodeslot=0x2F93,
+ },
+ [0x2F94]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8A00 },
+ unicodeslot=0x2F94,
+ },
+ [0x2F95]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8C37 },
+ unicodeslot=0x2F95,
+ },
+ [0x2F96]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8C46 },
+ unicodeslot=0x2F96,
+ },
+ [0x2F97]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8C55 },
+ unicodeslot=0x2F97,
+ },
+ [0x2F98]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8C78 },
+ unicodeslot=0x2F98,
+ },
+ [0x2F99]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8C9D },
+ unicodeslot=0x2F99,
+ },
+ [0x2F9A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8D64 },
+ unicodeslot=0x2F9A,
+ },
+ [0x2F9B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8D70 },
+ unicodeslot=0x2F9B,
+ },
+ [0x2F9C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8DB3 },
+ unicodeslot=0x2F9C,
+ },
+ [0x2F9D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8EAB },
+ unicodeslot=0x2F9D,
+ },
+ [0x2F9E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8ECA },
+ unicodeslot=0x2F9E,
+ },
+ [0x2F9F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8F9B },
+ unicodeslot=0x2F9F,
+ },
+ [0x2FA0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8FB0 },
+ unicodeslot=0x2FA0,
+ },
+ [0x2FA1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8FB5 },
+ unicodeslot=0x2FA1,
+ },
+ [0x2FA2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9091 },
+ unicodeslot=0x2FA2,
+ },
+ [0x2FA3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9149 },
+ unicodeslot=0x2FA3,
+ },
+ [0x2FA4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x91C6 },
+ unicodeslot=0x2FA4,
+ },
+ [0x2FA5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x91CC },
+ unicodeslot=0x2FA5,
+ },
+ [0x2FA6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x91D1 },
+ unicodeslot=0x2FA6,
+ },
+ [0x2FA7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9577 },
+ unicodeslot=0x2FA7,
+ },
+ [0x2FA8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9580 },
+ unicodeslot=0x2FA8,
+ },
+ [0x2FA9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x961C },
+ unicodeslot=0x2FA9,
+ },
+ [0x2FAA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x96B6 },
+ unicodeslot=0x2FAA,
+ },
+ [0x2FAB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x96B9 },
+ unicodeslot=0x2FAB,
+ },
+ [0x2FAC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x96E8 },
+ unicodeslot=0x2FAC,
+ },
+ [0x2FAD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9751 },
+ unicodeslot=0x2FAD,
+ },
+ [0x2FAE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x975E },
+ unicodeslot=0x2FAE,
+ },
+ [0x2FAF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9762 },
+ unicodeslot=0x2FAF,
+ },
+ [0x2FB0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9769 },
+ unicodeslot=0x2FB0,
+ },
+ [0x2FB1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x97CB },
+ unicodeslot=0x2FB1,
+ },
+ [0x2FB2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x97ED },
+ unicodeslot=0x2FB2,
+ },
+ [0x2FB3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x97F3 },
+ unicodeslot=0x2FB3,
+ },
+ [0x2FB4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9801 },
+ unicodeslot=0x2FB4,
+ },
+ [0x2FB5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x98A8 },
+ unicodeslot=0x2FB5,
+ },
+ [0x2FB6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x98DB },
+ unicodeslot=0x2FB6,
+ },
+ [0x2FB7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x98DF },
+ unicodeslot=0x2FB7,
+ },
+ [0x2FB8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9996 },
+ unicodeslot=0x2FB8,
+ },
+ [0x2FB9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9999 },
+ unicodeslot=0x2FB9,
+ },
+ [0x2FBA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x99AC },
+ unicodeslot=0x2FBA,
+ },
+ [0x2FBB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9AA8 },
+ unicodeslot=0x2FBB,
+ },
+ [0x2FBC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9AD8 },
+ unicodeslot=0x2FBC,
+ },
+ [0x2FBD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9ADF },
+ unicodeslot=0x2FBD,
+ },
+ [0x2FBE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9B25 },
+ unicodeslot=0x2FBE,
+ },
+ [0x2FBF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9B2F },
+ unicodeslot=0x2FBF,
+ },
+ [0x2FC0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9B32 },
+ unicodeslot=0x2FC0,
+ },
+ [0x2FC1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9B3C },
+ unicodeslot=0x2FC1,
+ },
+ [0x2FC2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9B5A },
+ unicodeslot=0x2FC2,
+ },
+ [0x2FC3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9CE5 },
+ unicodeslot=0x2FC3,
+ },
+ [0x2FC4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9E75 },
+ unicodeslot=0x2FC4,
+ },
+ [0x2FC5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9E7F },
+ unicodeslot=0x2FC5,
+ },
+ [0x2FC6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9EA5 },
+ unicodeslot=0x2FC6,
+ },
+ [0x2FC7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9EBB },
+ unicodeslot=0x2FC7,
+ },
+ [0x2FC8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9EC3 },
+ unicodeslot=0x2FC8,
+ },
+ [0x2FC9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9ECD },
+ unicodeslot=0x2FC9,
+ },
+ [0x2FCA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9ED1 },
+ unicodeslot=0x2FCA,
+ },
+ [0x2FCB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9EF9 },
+ unicodeslot=0x2FCB,
+ },
+ [0x2FCC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9EFD },
+ unicodeslot=0x2FCC,
+ },
+ [0x2FCD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F0E },
+ unicodeslot=0x2FCD,
+ },
+ [0x2FCE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F13 },
+ unicodeslot=0x2FCE,
+ },
+ [0x2FCF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F20 },
+ unicodeslot=0x2FCF,
+ },
+ [0x2FD0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F3B },
+ unicodeslot=0x2FD0,
+ },
+ [0x2FD1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F4A },
+ unicodeslot=0x2FD1,
+ },
+ [0x2FD2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F52 },
+ unicodeslot=0x2FD2,
+ },
+ [0x2FD3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F8D },
+ unicodeslot=0x2FD3,
+ },
+ [0x2FD4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F9C },
+ unicodeslot=0x2FD4,
+ },
+ [0x2FD5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9FA0 },
+ unicodeslot=0x2FD5,
+ },
+ [0x2FF0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF0,
+ },
+ [0x2FF1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF1,
+ },
+ [0x2FF2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF2,
+ },
+ [0x2FF3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF3,
+ },
+ [0x2FF4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF4,
+ },
+ [0x2FF5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF5,
+ },
+ [0x2FF6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF6,
+ },
+ [0x2FF7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF7,
+ },
+ [0x2FF8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF8,
+ },
+ [0x2FF9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF9,
+ },
+ [0x2FFA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FFA,
+ },
+ [0x2FFB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FFB,
+ },
+ [0x3000]={
+ category="zs",
+ direction="ws",
+ linebreak="ba",
+ specials={ "wide", 0x20 },
+ unicodeslot=0x3000,
+ },
+ [0x3001]={
+ category="po",
+ direction="on",
+ linebreak="cl",
+ unicodeslot=0x3001,
+ },
+ [0x3002]={
+ category="po",
+ direction="on",
+ linebreak="cl",
+ unicodeslot=0x3002,
+ },
+ [0x3003]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3003,
+ },
+ [0x3004]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3004,
+ },
+ [0x3005]={
+ category="lm",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x3005,
+ },
+ [0x3006]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3006,
+ },
+ [0x3007]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3007,
+ },
+ [0x3008]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x3009,
+ unicodeslot=0x3008,
+ },
+ [0x3009]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x3008,
+ unicodeslot=0x3009,
+ },
+ [0x300A]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x300B,
+ unicodeslot=0x300A,
+ },
+ [0x300B]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x300A,
+ unicodeslot=0x300B,
+ },
+ [0x300C]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x300D,
+ unicodeslot=0x300C,
+ },
+ [0x300D]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x300C,
+ unicodeslot=0x300D,
+ },
+ [0x300E]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x300F,
+ unicodeslot=0x300E,
+ },
+ [0x300F]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x300E,
+ unicodeslot=0x300F,
+ },
+ [0x3010]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x3011,
+ unicodeslot=0x3010,
+ },
+ [0x3011]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x3010,
+ unicodeslot=0x3011,
+ },
+ [0x3012]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3012,
+ },
+ [0x3013]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3013,
+ },
+ [0x3014]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x3015,
+ unicodeslot=0x3014,
+ },
+ [0x3015]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x3014,
+ unicodeslot=0x3015,
+ },
+ [0x3016]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x3017,
+ unicodeslot=0x3016,
+ },
+ [0x3017]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x3016,
+ unicodeslot=0x3017,
+ },
+ [0x3018]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x3019,
+ unicodeslot=0x3018,
+ },
+ [0x3019]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x3018,
+ unicodeslot=0x3019,
+ },
+ [0x301A]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0x301B,
+ unicodeslot=0x301A,
+ },
+ [0x301B]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0x301A,
+ unicodeslot=0x301B,
+ },
+ [0x301C]={
+ category="pd",
+ direction="on",
+ linebreak="ns",
+ unicodeslot=0x301C,
+ },
+ [0x301D]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0x301D,
+ },
+ [0x301E]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ unicodeslot=0x301E,
+ },
+ [0x301F]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ unicodeslot=0x301F,
+ },
+ [0x3020]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3020,
+ },
+ [0x3021]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3021,
+ },
+ [0x3022]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3022,
+ },
+ [0x3023]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3023,
+ },
+ [0x3024]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3024,
+ },
+ [0x3025]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3025,
+ },
+ [0x3026]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3026,
+ },
+ [0x3027]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3027,
+ },
+ [0x3028]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3028,
+ },
+ [0x3029]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3029,
+ },
+ [0x302A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x302A,
+ },
+ [0x302B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x302B,
+ },
+ [0x302C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x302C,
+ },
+ [0x302D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x302D,
+ },
+ [0x302E]={
+ category="mn",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x302E,
+ },
+ [0x302F]={
+ category="mn",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x302F,
+ },
+ [0x3030]={
+ category="pd",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3030,
+ },
+ [0x3031]={
+ category="lm",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3031,
+ },
+ [0x3032]={
+ category="lm",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3032,
+ },
+ [0x3033]={
+ category="lm",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3033,
+ },
+ [0x3034]={
+ category="lm",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3034,
+ },
+ [0x3035]={
+ category="lm",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x3035,
+ },
+ [0x3036]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x3012 },
+ unicodeslot=0x3036,
+ },
+ [0x3037]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3037,
+ },
+ [0x3038]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x5341 },
+ unicodeslot=0x3038,
+ },
+ [0x3039]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x5344 },
+ unicodeslot=0x3039,
+ },
+ [0x303A]={
+ category="nl",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x5345 },
+ unicodeslot=0x303A,
+ },
+ [0x303B]={
+ category="lm",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x303B,
+ },
+ [0x303C]={
+ category="lo",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x303C,
+ },
+ [0x303D]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x303D,
+ },
+ [0x303E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x303E,
+ },
+ [0x303F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x303F,
+ },
+ [0x3041]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3041,
+ },
+ [0x3042]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3042,
+ },
+ [0x3043]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3043,
+ },
+ [0x3044]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3044,
+ },
+ [0x3045]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3045,
+ },
+ [0x3046]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3046,
+ },
+ [0x3047]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3047,
+ },
+ [0x3048]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3048,
+ },
+ [0x3049]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3049,
+ },
+ [0x304A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x304A,
+ },
+ [0x304B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x304B,
+ },
+ [0x304C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x304B, 0x3099 },
+ unicodeslot=0x304C,
+ },
+ [0x304D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x304D,
+ },
+ [0x304E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x304D, 0x3099 },
+ unicodeslot=0x304E,
+ },
+ [0x304F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x304F,
+ },
+ [0x3050]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x304F, 0x3099 },
+ unicodeslot=0x3050,
+ },
+ [0x3051]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3051,
+ },
+ [0x3052]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3051, 0x3099 },
+ unicodeslot=0x3052,
+ },
+ [0x3053]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3053,
+ },
+ [0x3054]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3053, 0x3099 },
+ unicodeslot=0x3054,
+ },
+ [0x3055]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3055,
+ },
+ [0x3056]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3055, 0x3099 },
+ unicodeslot=0x3056,
+ },
+ [0x3057]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3057,
+ },
+ [0x3058]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3057, 0x3099 },
+ unicodeslot=0x3058,
+ },
+ [0x3059]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3059,
+ },
+ [0x305A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3059, 0x3099 },
+ unicodeslot=0x305A,
+ },
+ [0x305B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x305B,
+ },
+ [0x305C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x305B, 0x3099 },
+ unicodeslot=0x305C,
+ },
+ [0x305D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x305D,
+ },
+ [0x305E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x305D, 0x3099 },
+ unicodeslot=0x305E,
+ },
+ [0x305F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x305F,
+ },
+ [0x3060]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x305F, 0x3099 },
+ unicodeslot=0x3060,
+ },
+ [0x3061]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3061,
+ },
+ [0x3062]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3061, 0x3099 },
+ unicodeslot=0x3062,
+ },
+ [0x3063]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3063,
+ },
+ [0x3064]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3064,
+ },
+ [0x3065]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3064, 0x3099 },
+ unicodeslot=0x3065,
+ },
+ [0x3066]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3066,
+ },
+ [0x3067]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3066, 0x3099 },
+ unicodeslot=0x3067,
+ },
+ [0x3068]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3068,
+ },
+ [0x3069]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3068, 0x3099 },
+ unicodeslot=0x3069,
+ },
+ [0x306A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x306A,
+ },
+ [0x306B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x306B,
+ },
+ [0x306C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x306C,
+ },
+ [0x306D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x306D,
+ },
+ [0x306E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x306E,
+ },
+ [0x306F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x306F,
+ },
+ [0x3070]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x306F, 0x3099 },
+ unicodeslot=0x3070,
+ },
+ [0x3071]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x306F, 0x309A },
+ unicodeslot=0x3071,
+ },
+ [0x3072]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3072,
+ },
+ [0x3073]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3072, 0x3099 },
+ unicodeslot=0x3073,
+ },
+ [0x3074]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3072, 0x309A },
+ unicodeslot=0x3074,
+ },
+ [0x3075]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3075,
+ },
+ [0x3076]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3075, 0x3099 },
+ unicodeslot=0x3076,
+ },
+ [0x3077]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3075, 0x309A },
+ unicodeslot=0x3077,
+ },
+ [0x3078]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3078,
+ },
+ [0x3079]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3078, 0x3099 },
+ unicodeslot=0x3079,
+ },
+ [0x307A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3078, 0x309A },
+ unicodeslot=0x307A,
+ },
+ [0x307B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x307B,
+ },
+ [0x307C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x307B, 0x3099 },
+ unicodeslot=0x307C,
+ },
+ [0x307D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x307B, 0x309A },
+ unicodeslot=0x307D,
+ },
+ [0x307E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x307E,
+ },
+ [0x307F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x307F,
+ },
+ [0x3080]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3080,
+ },
+ [0x3081]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3081,
+ },
+ [0x3082]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3082,
+ },
+ [0x3083]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3083,
+ },
+ [0x3084]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3084,
+ },
+ [0x3085]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3085,
+ },
+ [0x3086]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3086,
+ },
+ [0x3087]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3087,
+ },
+ [0x3088]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3088,
+ },
+ [0x3089]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3089,
+ },
+ [0x308A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x308A,
+ },
+ [0x308B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x308B,
+ },
+ [0x308C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x308C,
+ },
+ [0x308D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x308D,
+ },
+ [0x308E]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x308E,
+ },
+ [0x308F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x308F,
+ },
+ [0x3090]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3090,
+ },
+ [0x3091]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3091,
+ },
+ [0x3092]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3092,
+ },
+ [0x3093]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3093,
+ },
+ [0x3094]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3046, 0x3099 },
+ unicodeslot=0x3094,
+ },
+ [0x3095]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3095,
+ },
+ [0x3096]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3096,
+ },
+ [0x3099]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x3099,
+ },
+ [0x309A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x309A,
+ },
+ [0x309B]={
+ category="sk",
+ direction="on",
+ linebreak="ns",
+ specials={ "compat", 0x20, 0x3099 },
+ unicodeslot=0x309B,
+ },
+ [0x309C]={
+ category="sk",
+ direction="on",
+ linebreak="ns",
+ specials={ "compat", 0x20, 0x309A },
+ unicodeslot=0x309C,
+ },
+ [0x309D]={
+ category="lm",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x309D,
+ },
+ [0x309E]={
+ category="lm",
+ direction="l",
+ linebreak="ns",
+ specials={ "char", 0x309D, 0x3099 },
+ unicodeslot=0x309E,
+ },
+ [0x309F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "vertical", 0x3088, 0x308A },
+ unicodeslot=0x309F,
+ },
+ [0x30A0]={
+ category="pd",
+ direction="on",
+ linebreak="ns",
+ unicodeslot=0x30A0,
+ },
+ [0x30A1]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30A1,
+ },
+ [0x30A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30A2,
+ },
+ [0x30A3]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30A3,
+ },
+ [0x30A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30A4,
+ },
+ [0x30A5]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30A5,
+ },
+ [0x30A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30A6,
+ },
+ [0x30A7]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30A7,
+ },
+ [0x30A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30A8,
+ },
+ [0x30A9]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30A9,
+ },
+ [0x30AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30AA,
+ },
+ [0x30AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30AB,
+ },
+ [0x30AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30AB, 0x3099 },
+ unicodeslot=0x30AC,
+ },
+ [0x30AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30AD,
+ },
+ [0x30AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30AD, 0x3099 },
+ unicodeslot=0x30AE,
+ },
+ [0x30AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30AF,
+ },
+ [0x30B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30AF, 0x3099 },
+ unicodeslot=0x30B0,
+ },
+ [0x30B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30B1,
+ },
+ [0x30B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30B1, 0x3099 },
+ unicodeslot=0x30B2,
+ },
+ [0x30B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30B3,
+ },
+ [0x30B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30B3, 0x3099 },
+ unicodeslot=0x30B4,
+ },
+ [0x30B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30B5,
+ },
+ [0x30B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30B5, 0x3099 },
+ unicodeslot=0x30B6,
+ },
+ [0x30B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30B7,
+ },
+ [0x30B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30B7, 0x3099 },
+ unicodeslot=0x30B8,
+ },
+ [0x30B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30B9,
+ },
+ [0x30BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30B9, 0x3099 },
+ unicodeslot=0x30BA,
+ },
+ [0x30BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30BB,
+ },
+ [0x30BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30BB, 0x3099 },
+ unicodeslot=0x30BC,
+ },
+ [0x30BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30BD,
+ },
+ [0x30BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30BD, 0x3099 },
+ unicodeslot=0x30BE,
+ },
+ [0x30BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30BF,
+ },
+ [0x30C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30BF, 0x3099 },
+ unicodeslot=0x30C0,
+ },
+ [0x30C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30C1,
+ },
+ [0x30C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30C1, 0x3099 },
+ unicodeslot=0x30C2,
+ },
+ [0x30C3]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30C3,
+ },
+ [0x30C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30C4,
+ },
+ [0x30C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30C4, 0x3099 },
+ unicodeslot=0x30C5,
+ },
+ [0x30C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30C6,
+ },
+ [0x30C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30C6, 0x3099 },
+ unicodeslot=0x30C7,
+ },
+ [0x30C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30C8,
+ },
+ [0x30C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30C8, 0x3099 },
+ unicodeslot=0x30C9,
+ },
+ [0x30CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30CA,
+ },
+ [0x30CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30CB,
+ },
+ [0x30CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30CC,
+ },
+ [0x30CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30CD,
+ },
+ [0x30CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30CE,
+ },
+ [0x30CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30CF,
+ },
+ [0x30D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30CF, 0x3099 },
+ unicodeslot=0x30D0,
+ },
+ [0x30D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30CF, 0x309A },
+ unicodeslot=0x30D1,
+ },
+ [0x30D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30D2,
+ },
+ [0x30D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30D2, 0x3099 },
+ unicodeslot=0x30D3,
+ },
+ [0x30D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30D2, 0x309A },
+ unicodeslot=0x30D4,
+ },
+ [0x30D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30D5,
+ },
+ [0x30D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30D5, 0x3099 },
+ unicodeslot=0x30D6,
+ },
+ [0x30D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30D5, 0x309A },
+ unicodeslot=0x30D7,
+ },
+ [0x30D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30D8,
+ },
+ [0x30D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30D8, 0x3099 },
+ unicodeslot=0x30D9,
+ },
+ [0x30DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30D8, 0x309A },
+ unicodeslot=0x30DA,
+ },
+ [0x30DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30DB,
+ },
+ [0x30DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30DB, 0x3099 },
+ unicodeslot=0x30DC,
+ },
+ [0x30DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30DB, 0x309A },
+ unicodeslot=0x30DD,
+ },
+ [0x30DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30DE,
+ },
+ [0x30DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30DF,
+ },
+ [0x30E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E0,
+ },
+ [0x30E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E1,
+ },
+ [0x30E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E2,
+ },
+ [0x30E3]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30E3,
+ },
+ [0x30E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E4,
+ },
+ [0x30E5]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30E5,
+ },
+ [0x30E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E6,
+ },
+ [0x30E7]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30E7,
+ },
+ [0x30E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E8,
+ },
+ [0x30E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E9,
+ },
+ [0x30EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30EA,
+ },
+ [0x30EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30EB,
+ },
+ [0x30EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30EC,
+ },
+ [0x30ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30ED,
+ },
+ [0x30EE]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30EE,
+ },
+ [0x30EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30EF,
+ },
+ [0x30F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30F0,
+ },
+ [0x30F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30F1,
+ },
+ [0x30F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30F2,
+ },
+ [0x30F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30F3,
+ },
+ [0x30F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30A6, 0x3099 },
+ unicodeslot=0x30F4,
+ },
+ [0x30F5]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30F5,
+ },
+ [0x30F6]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30F6,
+ },
+ [0x30F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30EF, 0x3099 },
+ unicodeslot=0x30F7,
+ },
+ [0x30F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30F0, 0x3099 },
+ unicodeslot=0x30F8,
+ },
+ [0x30F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30F1, 0x3099 },
+ unicodeslot=0x30F9,
+ },
+ [0x30FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30F2, 0x3099 },
+ unicodeslot=0x30FA,
+ },
+ [0x30FB]={
+ category="po",
+ direction="on",
+ linebreak="ns",
+ unicodeslot=0x30FB,
+ },
+ [0x30FC]={
+ category="lm",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30FC,
+ },
+ [0x30FD]={
+ category="lm",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x30FD,
+ },
+ [0x30FE]={
+ category="lm",
+ direction="l",
+ linebreak="ns",
+ specials={ "char", 0x30FD, 0x3099 },
+ unicodeslot=0x30FE,
+ },
+ [0x30FF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "vertical", 0x30B3, 0x30C8 },
+ unicodeslot=0x30FF,
+ },
+ [0x3105]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3105,
+ },
+ [0x3106]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3106,
+ },
+ [0x3107]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3107,
+ },
+ [0x3108]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3108,
+ },
+ [0x3109]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3109,
+ },
+ [0x310A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x310A,
+ },
+ [0x310B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x310B,
+ },
+ [0x310C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x310C,
+ },
+ [0x310D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x310D,
+ },
+ [0x310E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x310E,
+ },
+ [0x310F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x310F,
+ },
+ [0x3110]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3110,
+ },
+ [0x3111]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3111,
+ },
+ [0x3112]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3112,
+ },
+ [0x3113]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3113,
+ },
+ [0x3114]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3114,
+ },
+ [0x3115]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3115,
+ },
+ [0x3116]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3116,
+ },
+ [0x3117]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3117,
+ },
+ [0x3118]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3118,
+ },
+ [0x3119]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3119,
+ },
+ [0x311A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x311A,
+ },
+ [0x311B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x311B,
+ },
+ [0x311C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x311C,
+ },
+ [0x311D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x311D,
+ },
+ [0x311E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x311E,
+ },
+ [0x311F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x311F,
+ },
+ [0x3120]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3120,
+ },
+ [0x3121]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3121,
+ },
+ [0x3122]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3122,
+ },
+ [0x3123]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3123,
+ },
+ [0x3124]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3124,
+ },
+ [0x3125]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3125,
+ },
+ [0x3126]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3126,
+ },
+ [0x3127]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3127,
+ },
+ [0x3128]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3128,
+ },
+ [0x3129]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3129,
+ },
+ [0x312A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x312A,
+ },
+ [0x312B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x312B,
+ },
+ [0x312C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x312C,
+ },
+ [0x312D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x312D,
+ },
+ [0x312E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x312E,
+ },
+ [0x312F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x312F,
+ },
+ [0x3131]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1100 },
+ unicodeslot=0x3131,
+ },
+ [0x3132]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1101 },
+ unicodeslot=0x3132,
+ },
+ [0x3133]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11AA },
+ unicodeslot=0x3133,
+ },
+ [0x3134]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1102 },
+ unicodeslot=0x3134,
+ },
+ [0x3135]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11AC },
+ unicodeslot=0x3135,
+ },
+ [0x3136]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11AD },
+ unicodeslot=0x3136,
+ },
+ [0x3137]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1103 },
+ unicodeslot=0x3137,
+ },
+ [0x3138]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1104 },
+ unicodeslot=0x3138,
+ },
+ [0x3139]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1105 },
+ unicodeslot=0x3139,
+ },
+ [0x313A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11B0 },
+ unicodeslot=0x313A,
+ },
+ [0x313B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11B1 },
+ unicodeslot=0x313B,
+ },
+ [0x313C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11B2 },
+ unicodeslot=0x313C,
+ },
+ [0x313D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11B3 },
+ unicodeslot=0x313D,
+ },
+ [0x313E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11B4 },
+ unicodeslot=0x313E,
+ },
+ [0x313F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11B5 },
+ unicodeslot=0x313F,
+ },
+ [0x3140]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x111A },
+ unicodeslot=0x3140,
+ },
+ [0x3141]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1106 },
+ unicodeslot=0x3141,
+ },
+ [0x3142]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1107 },
+ unicodeslot=0x3142,
+ },
+ [0x3143]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1108 },
+ unicodeslot=0x3143,
+ },
+ [0x3144]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1121 },
+ unicodeslot=0x3144,
+ },
+ [0x3145]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1109 },
+ unicodeslot=0x3145,
+ },
+ [0x3146]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x110A },
+ unicodeslot=0x3146,
+ },
+ [0x3147]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x110B },
+ unicodeslot=0x3147,
+ },
+ [0x3148]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x110C },
+ unicodeslot=0x3148,
+ },
+ [0x3149]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x110D },
+ unicodeslot=0x3149,
+ },
+ [0x314A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x110E },
+ unicodeslot=0x314A,
+ },
+ [0x314B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x110F },
+ unicodeslot=0x314B,
+ },
+ [0x314C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1110 },
+ unicodeslot=0x314C,
+ },
+ [0x314D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1111 },
+ unicodeslot=0x314D,
+ },
+ [0x314E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1112 },
+ unicodeslot=0x314E,
+ },
+ [0x314F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1161 },
+ unicodeslot=0x314F,
+ },
+ [0x3150]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1162 },
+ unicodeslot=0x3150,
+ },
+ [0x3151]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1163 },
+ unicodeslot=0x3151,
+ },
+ [0x3152]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1164 },
+ unicodeslot=0x3152,
+ },
+ [0x3153]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1165 },
+ unicodeslot=0x3153,
+ },
+ [0x3154]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1166 },
+ unicodeslot=0x3154,
+ },
+ [0x3155]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1167 },
+ unicodeslot=0x3155,
+ },
+ [0x3156]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1168 },
+ unicodeslot=0x3156,
+ },
+ [0x3157]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1169 },
+ unicodeslot=0x3157,
+ },
+ [0x3158]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x116A },
+ unicodeslot=0x3158,
+ },
+ [0x3159]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x116B },
+ unicodeslot=0x3159,
+ },
+ [0x315A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x116C },
+ unicodeslot=0x315A,
+ },
+ [0x315B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x116D },
+ unicodeslot=0x315B,
+ },
+ [0x315C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x116E },
+ unicodeslot=0x315C,
+ },
+ [0x315D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x116F },
+ unicodeslot=0x315D,
+ },
+ [0x315E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1170 },
+ unicodeslot=0x315E,
+ },
+ [0x315F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1171 },
+ unicodeslot=0x315F,
+ },
+ [0x3160]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1172 },
+ unicodeslot=0x3160,
+ },
+ [0x3161]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1173 },
+ unicodeslot=0x3161,
+ },
+ [0x3162]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1174 },
+ unicodeslot=0x3162,
+ },
+ [0x3163]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1175 },
+ unicodeslot=0x3163,
+ },
+ [0x3164]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1160 },
+ unicodeslot=0x3164,
+ },
+ [0x3165]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1114 },
+ unicodeslot=0x3165,
+ },
+ [0x3166]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1115 },
+ unicodeslot=0x3166,
+ },
+ [0x3167]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11C7 },
+ unicodeslot=0x3167,
+ },
+ [0x3168]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11C8 },
+ unicodeslot=0x3168,
+ },
+ [0x3169]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11CC },
+ unicodeslot=0x3169,
+ },
+ [0x316A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11CE },
+ unicodeslot=0x316A,
+ },
+ [0x316B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11D3 },
+ unicodeslot=0x316B,
+ },
+ [0x316C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11D7 },
+ unicodeslot=0x316C,
+ },
+ [0x316D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11D9 },
+ unicodeslot=0x316D,
+ },
+ [0x316E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x111C },
+ unicodeslot=0x316E,
+ },
+ [0x316F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11DD },
+ unicodeslot=0x316F,
+ },
+ [0x3170]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11DF },
+ unicodeslot=0x3170,
+ },
+ [0x3171]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x111D },
+ unicodeslot=0x3171,
+ },
+ [0x3172]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x111E },
+ unicodeslot=0x3172,
+ },
+ [0x3173]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1120 },
+ unicodeslot=0x3173,
+ },
+ [0x3174]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1122 },
+ unicodeslot=0x3174,
+ },
+ [0x3175]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1123 },
+ unicodeslot=0x3175,
+ },
+ [0x3176]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1127 },
+ unicodeslot=0x3176,
+ },
+ [0x3177]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1129 },
+ unicodeslot=0x3177,
+ },
+ [0x3178]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x112B },
+ unicodeslot=0x3178,
+ },
+ [0x3179]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x112C },
+ unicodeslot=0x3179,
+ },
+ [0x317A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x112D },
+ unicodeslot=0x317A,
+ },
+ [0x317B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x112E },
+ unicodeslot=0x317B,
+ },
+ [0x317C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x112F },
+ unicodeslot=0x317C,
+ },
+ [0x317D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1132 },
+ unicodeslot=0x317D,
+ },
+ [0x317E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1136 },
+ unicodeslot=0x317E,
+ },
+ [0x317F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1140 },
+ unicodeslot=0x317F,
+ },
+ [0x3180]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1147 },
+ unicodeslot=0x3180,
+ },
+ [0x3181]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x114C },
+ unicodeslot=0x3181,
+ },
+ [0x3182]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11F1 },
+ unicodeslot=0x3182,
+ },
+ [0x3183]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11F2 },
+ unicodeslot=0x3183,
+ },
+ [0x3184]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1157 },
+ unicodeslot=0x3184,
+ },
+ [0x3185]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1158 },
+ unicodeslot=0x3185,
+ },
+ [0x3186]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1159 },
+ unicodeslot=0x3186,
+ },
+ [0x3187]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1184 },
+ unicodeslot=0x3187,
+ },
+ [0x3188]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1185 },
+ unicodeslot=0x3188,
+ },
+ [0x3189]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1188 },
+ unicodeslot=0x3189,
+ },
+ [0x318A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1191 },
+ unicodeslot=0x318A,
+ },
+ [0x318B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1192 },
+ unicodeslot=0x318B,
+ },
+ [0x318C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1194 },
+ unicodeslot=0x318C,
+ },
+ [0x318D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x119E },
+ unicodeslot=0x318D,
+ },
+ [0x318E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11A1 },
+ unicodeslot=0x318E,
+ },
+ [0x3190]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3190,
+ },
+ [0x3191]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3191,
+ },
+ [0x3192]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E00 },
+ unicodeslot=0x3192,
+ },
+ [0x3193]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E8C },
+ unicodeslot=0x3193,
+ },
+ [0x3194]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E09 },
+ unicodeslot=0x3194,
+ },
+ [0x3195]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x56DB },
+ unicodeslot=0x3195,
+ },
+ [0x3196]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E0A },
+ unicodeslot=0x3196,
+ },
+ [0x3197]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E2D },
+ unicodeslot=0x3197,
+ },
+ [0x3198]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E0B },
+ unicodeslot=0x3198,
+ },
+ [0x3199]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x7532 },
+ unicodeslot=0x3199,
+ },
+ [0x319A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E59 },
+ unicodeslot=0x319A,
+ },
+ [0x319B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E19 },
+ unicodeslot=0x319B,
+ },
+ [0x319C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E01 },
+ unicodeslot=0x319C,
+ },
+ [0x319D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x5929 },
+ unicodeslot=0x319D,
+ },
+ [0x319E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x5730 },
+ unicodeslot=0x319E,
+ },
+ [0x319F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4EBA },
+ unicodeslot=0x319F,
+ },
+ [0x31A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A0,
+ },
+ [0x31A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A1,
+ },
+ [0x31A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A2,
+ },
+ [0x31A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A3,
+ },
+ [0x31A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A4,
+ },
+ [0x31A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A5,
+ },
+ [0x31A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A6,
+ },
+ [0x31A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A7,
+ },
+ [0x31A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A8,
+ },
+ [0x31A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A9,
+ },
+ [0x31AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31AA,
+ },
+ [0x31AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31AB,
+ },
+ [0x31AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31AC,
+ },
+ [0x31AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31AD,
+ },
+ [0x31AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31AE,
+ },
+ [0x31AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31AF,
+ },
+ [0x31B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B0,
+ },
+ [0x31B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B1,
+ },
+ [0x31B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B2,
+ },
+ [0x31B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B3,
+ },
+ [0x31B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B4,
+ },
+ [0x31B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B5,
+ },
+ [0x31B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B6,
+ },
+ [0x31B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B7,
+ },
+ [0x31B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B8,
+ },
+ [0x31B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B9,
+ },
+ [0x31BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31BA,
+ },
+ [0x31C0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C0,
+ },
+ [0x31C1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C1,
+ },
+ [0x31C2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C2,
+ },
+ [0x31C3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C3,
+ },
+ [0x31C4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C4,
+ },
+ [0x31C5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C5,
+ },
+ [0x31C6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C6,
+ },
+ [0x31C7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C7,
+ },
+ [0x31C8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C8,
+ },
+ [0x31C9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C9,
+ },
+ [0x31CA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31CA,
+ },
+ [0x31CB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31CB,
+ },
+ [0x31CC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31CC,
+ },
+ [0x31CD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31CD,
+ },
+ [0x31CE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31CE,
+ },
+ [0x31CF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31CF,
+ },
+ [0x31D0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D0,
+ },
+ [0x31D1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D1,
+ },
+ [0x31D2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D2,
+ },
+ [0x31D3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D3,
+ },
+ [0x31D4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D4,
+ },
+ [0x31D5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D5,
+ },
+ [0x31D6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D6,
+ },
+ [0x31D7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D7,
+ },
+ [0x31D8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D8,
+ },
+ [0x31D9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D9,
+ },
+ [0x31DA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31DA,
+ },
+ [0x31DB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31DB,
+ },
+ [0x31DC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31DC,
+ },
+ [0x31DD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31DD,
+ },
+ [0x31DE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31DE,
+ },
+ [0x31DF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31DF,
+ },
+ [0x31E0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31E0,
+ },
+ [0x31E1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31E1,
+ },
+ [0x31E2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31E2,
+ },
+ [0x31E3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31E3,
+ },
+ [0x31F0]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F0,
+ },
+ [0x31F1]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F1,
+ },
+ [0x31F2]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F2,
+ },
+ [0x31F3]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F3,
+ },
+ [0x31F4]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F4,
+ },
+ [0x31F5]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F5,
+ },
+ [0x31F6]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F6,
+ },
+ [0x31F7]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F7,
+ },
+ [0x31F8]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F8,
+ },
+ [0x31F9]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F9,
+ },
+ [0x31FA]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31FA,
+ },
+ [0x31FB]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31FB,
+ },
+ [0x31FC]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31FC,
+ },
+ [0x31FD]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31FD,
+ },
+ [0x31FE]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31FE,
+ },
+ [0x31FF]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31FF,
+ },
+ [0x3200]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1100, 0x29 },
+ unicodeslot=0x3200,
+ },
+ [0x3201]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1102, 0x29 },
+ unicodeslot=0x3201,
+ },
+ [0x3202]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1103, 0x29 },
+ unicodeslot=0x3202,
+ },
+ [0x3203]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1105, 0x29 },
+ unicodeslot=0x3203,
+ },
+ [0x3204]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1106, 0x29 },
+ unicodeslot=0x3204,
+ },
+ [0x3205]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1107, 0x29 },
+ unicodeslot=0x3205,
+ },
+ [0x3206]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1109, 0x29 },
+ unicodeslot=0x3206,
+ },
+ [0x3207]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x110B, 0x29 },
+ unicodeslot=0x3207,
+ },
+ [0x3208]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x110C, 0x29 },
+ unicodeslot=0x3208,
+ },
+ [0x3209]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x110E, 0x29 },
+ unicodeslot=0x3209,
+ },
+ [0x320A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x110F, 0x29 },
+ unicodeslot=0x320A,
+ },
+ [0x320B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1110, 0x29 },
+ unicodeslot=0x320B,
+ },
+ [0x320C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1111, 0x29 },
+ unicodeslot=0x320C,
+ },
+ [0x320D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1112, 0x29 },
+ unicodeslot=0x320D,
+ },
+ [0x320E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1100, 0x1161, 0x29 },
+ unicodeslot=0x320E,
+ },
+ [0x320F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1102, 0x1161, 0x29 },
+ unicodeslot=0x320F,
+ },
+ [0x3210]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1103, 0x1161, 0x29 },
+ unicodeslot=0x3210,
+ },
+ [0x3211]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1105, 0x1161, 0x29 },
+ unicodeslot=0x3211,
+ },
+ [0x3212]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1106, 0x1161, 0x29 },
+ unicodeslot=0x3212,
+ },
+ [0x3213]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1107, 0x1161, 0x29 },
+ unicodeslot=0x3213,
+ },
+ [0x3214]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1109, 0x1161, 0x29 },
+ unicodeslot=0x3214,
+ },
+ [0x3215]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x110B, 0x1161, 0x29 },
+ unicodeslot=0x3215,
+ },
+ [0x3216]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x110C, 0x1161, 0x29 },
+ unicodeslot=0x3216,
+ },
+ [0x3217]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x110E, 0x1161, 0x29 },
+ unicodeslot=0x3217,
+ },
+ [0x3218]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x110F, 0x1161, 0x29 },
+ unicodeslot=0x3218,
+ },
+ [0x3219]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1110, 0x1161, 0x29 },
+ unicodeslot=0x3219,
+ },
+ [0x321A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1111, 0x1161, 0x29 },
+ unicodeslot=0x321A,
+ },
+ [0x321B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x1112, 0x1161, 0x29 },
+ unicodeslot=0x321B,
+ },
+ [0x321C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x110C, 0x116E, 0x29 },
+ unicodeslot=0x321C,
+ },
+ [0x321D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x110B, 0x1169, 0x110C, 0x1165, 0x11AB, 0x29 },
+ unicodeslot=0x321D,
+ },
+ [0x321E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x110B, 0x1169, 0x1112, 0x116E, 0x29 },
+ unicodeslot=0x321E,
+ },
+ [0x3220]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x4E00, 0x29 },
+ unicodeslot=0x3220,
+ },
+ [0x3221]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x4E8C, 0x29 },
+ unicodeslot=0x3221,
+ },
+ [0x3222]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x4E09, 0x29 },
+ unicodeslot=0x3222,
+ },
+ [0x3223]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x56DB, 0x29 },
+ unicodeslot=0x3223,
+ },
+ [0x3224]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x4E94, 0x29 },
+ unicodeslot=0x3224,
+ },
+ [0x3225]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x516D, 0x29 },
+ unicodeslot=0x3225,
+ },
+ [0x3226]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x4E03, 0x29 },
+ unicodeslot=0x3226,
+ },
+ [0x3227]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x516B, 0x29 },
+ unicodeslot=0x3227,
+ },
+ [0x3228]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x4E5D, 0x29 },
+ unicodeslot=0x3228,
+ },
+ [0x3229]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x5341, 0x29 },
+ unicodeslot=0x3229,
+ },
+ [0x322A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x6708, 0x29 },
+ unicodeslot=0x322A,
+ },
+ [0x322B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x706B, 0x29 },
+ unicodeslot=0x322B,
+ },
+ [0x322C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x6C34, 0x29 },
+ unicodeslot=0x322C,
+ },
+ [0x322D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x6728, 0x29 },
+ unicodeslot=0x322D,
+ },
+ [0x322E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x91D1, 0x29 },
+ unicodeslot=0x322E,
+ },
+ [0x322F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x571F, 0x29 },
+ unicodeslot=0x322F,
+ },
+ [0x3230]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x65E5, 0x29 },
+ unicodeslot=0x3230,
+ },
+ [0x3231]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x682A, 0x29 },
+ unicodeslot=0x3231,
+ },
+ [0x3232]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x6709, 0x29 },
+ unicodeslot=0x3232,
+ },
+ [0x3233]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x793E, 0x29 },
+ unicodeslot=0x3233,
+ },
+ [0x3234]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x540D, 0x29 },
+ unicodeslot=0x3234,
+ },
+ [0x3235]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x7279, 0x29 },
+ unicodeslot=0x3235,
+ },
+ [0x3236]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x8CA1, 0x29 },
+ unicodeslot=0x3236,
+ },
+ [0x3237]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x795D, 0x29 },
+ unicodeslot=0x3237,
+ },
+ [0x3238]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x52B4, 0x29 },
+ unicodeslot=0x3238,
+ },
+ [0x3239]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x4EE3, 0x29 },
+ unicodeslot=0x3239,
+ },
+ [0x323A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x547C, 0x29 },
+ unicodeslot=0x323A,
+ },
+ [0x323B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x5B66, 0x29 },
+ unicodeslot=0x323B,
+ },
+ [0x323C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x76E3, 0x29 },
+ unicodeslot=0x323C,
+ },
+ [0x323D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x4F01, 0x29 },
+ unicodeslot=0x323D,
+ },
+ [0x323E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x8CC7, 0x29 },
+ unicodeslot=0x323E,
+ },
+ [0x323F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x5354, 0x29 },
+ unicodeslot=0x323F,
+ },
+ [0x3240]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x796D, 0x29 },
+ unicodeslot=0x3240,
+ },
+ [0x3241]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x4F11, 0x29 },
+ unicodeslot=0x3241,
+ },
+ [0x3242]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x81EA, 0x29 },
+ unicodeslot=0x3242,
+ },
+ [0x3243]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x28, 0x81F3, 0x29 },
+ unicodeslot=0x3243,
+ },
+ [0x3244]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x554F },
+ unicodeslot=0x3244,
+ },
+ [0x3245]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5E7C },
+ unicodeslot=0x3245,
+ },
+ [0x3246]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6587 },
+ unicodeslot=0x3246,
+ },
+ [0x3247]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x7B8F },
+ unicodeslot=0x3247,
+ },
+ [0x3248]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x3248,
+ },
+ [0x3249]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x3249,
+ },
+ [0x324A]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x324A,
+ },
+ [0x324B]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x324B,
+ },
+ [0x324C]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x324C,
+ },
+ [0x324D]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x324D,
+ },
+ [0x324E]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x324E,
+ },
+ [0x324F]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x324F,
+ },
+ [0x3250]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x50, 0x54, 0x45 },
+ unicodeslot=0x3250,
+ },
+ [0x3251]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x32, 0x31 },
+ unicodeslot=0x3251,
+ },
+ [0x3252]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x32, 0x32 },
+ unicodeslot=0x3252,
+ },
+ [0x3253]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x32, 0x33 },
+ unicodeslot=0x3253,
+ },
+ [0x3254]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x32, 0x34 },
+ unicodeslot=0x3254,
+ },
+ [0x3255]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x32, 0x35 },
+ unicodeslot=0x3255,
+ },
+ [0x3256]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x32, 0x36 },
+ unicodeslot=0x3256,
+ },
+ [0x3257]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x32, 0x37 },
+ unicodeslot=0x3257,
+ },
+ [0x3258]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x32, 0x38 },
+ unicodeslot=0x3258,
+ },
+ [0x3259]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x32, 0x39 },
+ unicodeslot=0x3259,
+ },
+ [0x325A]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x33, 0x30 },
+ unicodeslot=0x325A,
+ },
+ [0x325B]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x33, 0x31 },
+ unicodeslot=0x325B,
+ },
+ [0x325C]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x33, 0x32 },
+ unicodeslot=0x325C,
+ },
+ [0x325D]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x33, 0x33 },
+ unicodeslot=0x325D,
+ },
+ [0x325E]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x33, 0x34 },
+ unicodeslot=0x325E,
+ },
+ [0x325F]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x33, 0x35 },
+ unicodeslot=0x325F,
+ },
+ [0x3260]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1100 },
+ unicodeslot=0x3260,
+ },
+ [0x3261]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1102 },
+ unicodeslot=0x3261,
+ },
+ [0x3262]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1103 },
+ unicodeslot=0x3262,
+ },
+ [0x3263]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1105 },
+ unicodeslot=0x3263,
+ },
+ [0x3264]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1106 },
+ unicodeslot=0x3264,
+ },
+ [0x3265]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1107 },
+ unicodeslot=0x3265,
+ },
+ [0x3266]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1109 },
+ unicodeslot=0x3266,
+ },
+ [0x3267]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110B },
+ unicodeslot=0x3267,
+ },
+ [0x3268]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110C },
+ unicodeslot=0x3268,
+ },
+ [0x3269]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110E },
+ unicodeslot=0x3269,
+ },
+ [0x326A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110F },
+ unicodeslot=0x326A,
+ },
+ [0x326B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1110 },
+ unicodeslot=0x326B,
+ },
+ [0x326C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1111 },
+ unicodeslot=0x326C,
+ },
+ [0x326D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1112 },
+ unicodeslot=0x326D,
+ },
+ [0x326E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1100, 0x1161 },
+ unicodeslot=0x326E,
+ },
+ [0x326F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1102, 0x1161 },
+ unicodeslot=0x326F,
+ },
+ [0x3270]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1103, 0x1161 },
+ unicodeslot=0x3270,
+ },
+ [0x3271]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1105, 0x1161 },
+ unicodeslot=0x3271,
+ },
+ [0x3272]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1106, 0x1161 },
+ unicodeslot=0x3272,
+ },
+ [0x3273]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1107, 0x1161 },
+ unicodeslot=0x3273,
+ },
+ [0x3274]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1109, 0x1161 },
+ unicodeslot=0x3274,
+ },
+ [0x3275]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110B, 0x1161 },
+ unicodeslot=0x3275,
+ },
+ [0x3276]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110C, 0x1161 },
+ unicodeslot=0x3276,
+ },
+ [0x3277]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110E, 0x1161 },
+ unicodeslot=0x3277,
+ },
+ [0x3278]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110F, 0x1161 },
+ unicodeslot=0x3278,
+ },
+ [0x3279]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1110, 0x1161 },
+ unicodeslot=0x3279,
+ },
+ [0x327A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1111, 0x1161 },
+ unicodeslot=0x327A,
+ },
+ [0x327B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1112, 0x1161 },
+ unicodeslot=0x327B,
+ },
+ [0x327C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x110E, 0x1161, 0x11B7, 0x1100, 0x1169 },
+ unicodeslot=0x327C,
+ },
+ [0x327D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x110C, 0x116E, 0x110B, 0x1174 },
+ unicodeslot=0x327D,
+ },
+ [0x327E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x110B, 0x116E },
+ unicodeslot=0x327E,
+ },
+ [0x327F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x327F,
+ },
+ [0x3280]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E00 },
+ unicodeslot=0x3280,
+ },
+ [0x3281]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E8C },
+ unicodeslot=0x3281,
+ },
+ [0x3282]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E09 },
+ unicodeslot=0x3282,
+ },
+ [0x3283]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x56DB },
+ unicodeslot=0x3283,
+ },
+ [0x3284]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E94 },
+ unicodeslot=0x3284,
+ },
+ [0x3285]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x516D },
+ unicodeslot=0x3285,
+ },
+ [0x3286]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E03 },
+ unicodeslot=0x3286,
+ },
+ [0x3287]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x516B },
+ unicodeslot=0x3287,
+ },
+ [0x3288]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E5D },
+ unicodeslot=0x3288,
+ },
+ [0x3289]={
+ category="no",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5341 },
+ unicodeslot=0x3289,
+ },
+ [0x328A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6708 },
+ unicodeslot=0x328A,
+ },
+ [0x328B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x706B },
+ unicodeslot=0x328B,
+ },
+ [0x328C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6C34 },
+ unicodeslot=0x328C,
+ },
+ [0x328D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6728 },
+ unicodeslot=0x328D,
+ },
+ [0x328E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x91D1 },
+ unicodeslot=0x328E,
+ },
+ [0x328F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x571F },
+ unicodeslot=0x328F,
+ },
+ [0x3290]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x65E5 },
+ unicodeslot=0x3290,
+ },
+ [0x3291]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x682A },
+ unicodeslot=0x3291,
+ },
+ [0x3292]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6709 },
+ unicodeslot=0x3292,
+ },
+ [0x3293]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x793E },
+ unicodeslot=0x3293,
+ },
+ [0x3294]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x540D },
+ unicodeslot=0x3294,
+ },
+ [0x3295]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x7279 },
+ unicodeslot=0x3295,
+ },
+ [0x3296]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x8CA1 },
+ unicodeslot=0x3296,
+ },
+ [0x3297]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x795D },
+ unicodeslot=0x3297,
+ },
+ [0x3298]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x52B4 },
+ unicodeslot=0x3298,
+ },
+ [0x3299]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x79D8 },
+ unicodeslot=0x3299,
+ },
+ [0x329A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x7537 },
+ unicodeslot=0x329A,
+ },
+ [0x329B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5973 },
+ unicodeslot=0x329B,
+ },
+ [0x329C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x9069 },
+ unicodeslot=0x329C,
+ },
+ [0x329D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x512A },
+ unicodeslot=0x329D,
+ },
+ [0x329E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5370 },
+ unicodeslot=0x329E,
+ },
+ [0x329F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6CE8 },
+ unicodeslot=0x329F,
+ },
+ [0x32A0]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x9805 },
+ unicodeslot=0x32A0,
+ },
+ [0x32A1]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4F11 },
+ unicodeslot=0x32A1,
+ },
+ [0x32A2]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5199 },
+ unicodeslot=0x32A2,
+ },
+ [0x32A3]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6B63 },
+ unicodeslot=0x32A3,
+ },
+ [0x32A4]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E0A },
+ unicodeslot=0x32A4,
+ },
+ [0x32A5]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E2D },
+ unicodeslot=0x32A5,
+ },
+ [0x32A6]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E0B },
+ unicodeslot=0x32A6,
+ },
+ [0x32A7]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5DE6 },
+ unicodeslot=0x32A7,
+ },
+ [0x32A8]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x53F3 },
+ unicodeslot=0x32A8,
+ },
+ [0x32A9]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x533B },
+ unicodeslot=0x32A9,
+ },
+ [0x32AA]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5B97 },
+ unicodeslot=0x32AA,
+ },
+ [0x32AB]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5B66 },
+ unicodeslot=0x32AB,
+ },
+ [0x32AC]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x76E3 },
+ unicodeslot=0x32AC,
+ },
+ [0x32AD]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4F01 },
+ unicodeslot=0x32AD,
+ },
+ [0x32AE]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x8CC7 },
+ unicodeslot=0x32AE,
+ },
+ [0x32AF]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5354 },
+ unicodeslot=0x32AF,
+ },
+ [0x32B0]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x591C },
+ unicodeslot=0x32B0,
+ },
+ [0x32B1]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x33, 0x36 },
+ unicodeslot=0x32B1,
+ },
+ [0x32B2]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x33, 0x37 },
+ unicodeslot=0x32B2,
+ },
+ [0x32B3]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x33, 0x38 },
+ unicodeslot=0x32B3,
+ },
+ [0x32B4]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x33, 0x39 },
+ unicodeslot=0x32B4,
+ },
+ [0x32B5]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x34, 0x30 },
+ unicodeslot=0x32B5,
+ },
+ [0x32B6]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x34, 0x31 },
+ unicodeslot=0x32B6,
+ },
+ [0x32B7]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x34, 0x32 },
+ unicodeslot=0x32B7,
+ },
+ [0x32B8]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x34, 0x33 },
+ unicodeslot=0x32B8,
+ },
+ [0x32B9]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x34, 0x34 },
+ unicodeslot=0x32B9,
+ },
+ [0x32BA]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x34, 0x35 },
+ unicodeslot=0x32BA,
+ },
+ [0x32BB]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x34, 0x36 },
+ unicodeslot=0x32BB,
+ },
+ [0x32BC]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x34, 0x37 },
+ unicodeslot=0x32BC,
+ },
+ [0x32BD]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x34, 0x38 },
+ unicodeslot=0x32BD,
+ },
+ [0x32BE]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x34, 0x39 },
+ unicodeslot=0x32BE,
+ },
+ [0x32BF]={
+ category="no",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x35, 0x30 },
+ unicodeslot=0x32BF,
+ },
+ [0x32C0]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x6708 },
+ unicodeslot=0x32C0,
+ },
+ [0x32C1]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x6708 },
+ unicodeslot=0x32C1,
+ },
+ [0x32C2]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x33, 0x6708 },
+ unicodeslot=0x32C2,
+ },
+ [0x32C3]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x34, 0x6708 },
+ unicodeslot=0x32C3,
+ },
+ [0x32C4]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x35, 0x6708 },
+ unicodeslot=0x32C4,
+ },
+ [0x32C5]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x36, 0x6708 },
+ unicodeslot=0x32C5,
+ },
+ [0x32C6]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x37, 0x6708 },
+ unicodeslot=0x32C6,
+ },
+ [0x32C7]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x38, 0x6708 },
+ unicodeslot=0x32C7,
+ },
+ [0x32C8]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x39, 0x6708 },
+ unicodeslot=0x32C8,
+ },
+ [0x32C9]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x30, 0x6708 },
+ unicodeslot=0x32C9,
+ },
+ [0x32CA]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x31, 0x6708 },
+ unicodeslot=0x32CA,
+ },
+ [0x32CB]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x32, 0x6708 },
+ unicodeslot=0x32CB,
+ },
+ [0x32CC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x48, 0x67 },
+ unicodeslot=0x32CC,
+ },
+ [0x32CD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x65, 0x72, 0x67 },
+ unicodeslot=0x32CD,
+ },
+ [0x32CE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x65, 0x56 },
+ unicodeslot=0x32CE,
+ },
+ [0x32CF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x4C, 0x54, 0x44 },
+ unicodeslot=0x32CF,
+ },
+ [0x32D0]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30A2 },
+ unicodeslot=0x32D0,
+ },
+ [0x32D1]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30A4 },
+ unicodeslot=0x32D1,
+ },
+ [0x32D2]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30A6 },
+ unicodeslot=0x32D2,
+ },
+ [0x32D3]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30A8 },
+ unicodeslot=0x32D3,
+ },
+ [0x32D4]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30AA },
+ unicodeslot=0x32D4,
+ },
+ [0x32D5]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30AB },
+ unicodeslot=0x32D5,
+ },
+ [0x32D6]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30AD },
+ unicodeslot=0x32D6,
+ },
+ [0x32D7]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30AF },
+ unicodeslot=0x32D7,
+ },
+ [0x32D8]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30B1 },
+ unicodeslot=0x32D8,
+ },
+ [0x32D9]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30B3 },
+ unicodeslot=0x32D9,
+ },
+ [0x32DA]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30B5 },
+ unicodeslot=0x32DA,
+ },
+ [0x32DB]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30B7 },
+ unicodeslot=0x32DB,
+ },
+ [0x32DC]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30B9 },
+ unicodeslot=0x32DC,
+ },
+ [0x32DD]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30BB },
+ unicodeslot=0x32DD,
+ },
+ [0x32DE]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30BD },
+ unicodeslot=0x32DE,
+ },
+ [0x32DF]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30BF },
+ unicodeslot=0x32DF,
+ },
+ [0x32E0]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30C1 },
+ unicodeslot=0x32E0,
+ },
+ [0x32E1]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30C4 },
+ unicodeslot=0x32E1,
+ },
+ [0x32E2]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30C6 },
+ unicodeslot=0x32E2,
+ },
+ [0x32E3]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30C8 },
+ unicodeslot=0x32E3,
+ },
+ [0x32E4]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30CA },
+ unicodeslot=0x32E4,
+ },
+ [0x32E5]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30CB },
+ unicodeslot=0x32E5,
+ },
+ [0x32E6]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30CC },
+ unicodeslot=0x32E6,
+ },
+ [0x32E7]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30CD },
+ unicodeslot=0x32E7,
+ },
+ [0x32E8]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30CE },
+ unicodeslot=0x32E8,
+ },
+ [0x32E9]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30CF },
+ unicodeslot=0x32E9,
+ },
+ [0x32EA]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30D2 },
+ unicodeslot=0x32EA,
+ },
+ [0x32EB]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30D5 },
+ unicodeslot=0x32EB,
+ },
+ [0x32EC]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30D8 },
+ unicodeslot=0x32EC,
+ },
+ [0x32ED]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30DB },
+ unicodeslot=0x32ED,
+ },
+ [0x32EE]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30DE },
+ unicodeslot=0x32EE,
+ },
+ [0x32EF]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30DF },
+ unicodeslot=0x32EF,
+ },
+ [0x32F0]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E0 },
+ unicodeslot=0x32F0,
+ },
+ [0x32F1]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E1 },
+ unicodeslot=0x32F1,
+ },
+ [0x32F2]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E2 },
+ unicodeslot=0x32F2,
+ },
+ [0x32F3]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E4 },
+ unicodeslot=0x32F3,
+ },
+ [0x32F4]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E6 },
+ unicodeslot=0x32F4,
+ },
+ [0x32F5]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E8 },
+ unicodeslot=0x32F5,
+ },
+ [0x32F6]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E9 },
+ unicodeslot=0x32F6,
+ },
+ [0x32F7]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30EA },
+ unicodeslot=0x32F7,
+ },
+ [0x32F8]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30EB },
+ unicodeslot=0x32F8,
+ },
+ [0x32F9]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30EC },
+ unicodeslot=0x32F9,
+ },
+ [0x32FA]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30ED },
+ unicodeslot=0x32FA,
+ },
+ [0x32FB]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30EF },
+ unicodeslot=0x32FB,
+ },
+ [0x32FC]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30F0 },
+ unicodeslot=0x32FC,
+ },
+ [0x32FD]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30F1 },
+ unicodeslot=0x32FD,
+ },
+ [0x32FE]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30F2 },
+ unicodeslot=0x32FE,
+ },
+ [0x32FF]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4EE4, 0x548C },
+ unicodeslot=0x32FF,
+ },
+ [0x3300]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A2, 0x30D1, 0x30FC, 0x30C8 },
+ unicodeslot=0x3300,
+ },
+ [0x3301]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A2, 0x30EB, 0x30D5, 0x30A1 },
+ unicodeslot=0x3301,
+ },
+ [0x3302]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A2, 0x30F3, 0x30DA, 0x30A2 },
+ unicodeslot=0x3302,
+ },
+ [0x3303]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A2, 0x30FC, 0x30EB },
+ unicodeslot=0x3303,
+ },
+ [0x3304]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A4, 0x30CB, 0x30F3, 0x30B0 },
+ unicodeslot=0x3304,
+ },
+ [0x3305]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A4, 0x30F3, 0x30C1 },
+ unicodeslot=0x3305,
+ },
+ [0x3306]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A6, 0x30A9, 0x30F3 },
+ unicodeslot=0x3306,
+ },
+ [0x3307]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A8, 0x30B9, 0x30AF, 0x30FC, 0x30C9 },
+ unicodeslot=0x3307,
+ },
+ [0x3308]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A8, 0x30FC, 0x30AB, 0x30FC },
+ unicodeslot=0x3308,
+ },
+ [0x3309]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AA, 0x30F3, 0x30B9 },
+ unicodeslot=0x3309,
+ },
+ [0x330A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AA, 0x30FC, 0x30E0 },
+ unicodeslot=0x330A,
+ },
+ [0x330B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AB, 0x30A4, 0x30EA },
+ unicodeslot=0x330B,
+ },
+ [0x330C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AB, 0x30E9, 0x30C3, 0x30C8 },
+ unicodeslot=0x330C,
+ },
+ [0x330D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AB, 0x30ED, 0x30EA, 0x30FC },
+ unicodeslot=0x330D,
+ },
+ [0x330E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AC, 0x30ED, 0x30F3 },
+ unicodeslot=0x330E,
+ },
+ [0x330F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AC, 0x30F3, 0x30DE },
+ unicodeslot=0x330F,
+ },
+ [0x3310]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AE, 0x30AC },
+ unicodeslot=0x3310,
+ },
+ [0x3311]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AE, 0x30CB, 0x30FC },
+ unicodeslot=0x3311,
+ },
+ [0x3312]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AD, 0x30E5, 0x30EA, 0x30FC },
+ unicodeslot=0x3312,
+ },
+ [0x3313]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AE, 0x30EB, 0x30C0, 0x30FC },
+ unicodeslot=0x3313,
+ },
+ [0x3314]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AD, 0x30ED },
+ unicodeslot=0x3314,
+ },
+ [0x3315]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AD, 0x30ED, 0x30B0, 0x30E9, 0x30E0 },
+ unicodeslot=0x3315,
+ },
+ [0x3316]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AD, 0x30ED, 0x30E1, 0x30FC, 0x30C8, 0x30EB },
+ unicodeslot=0x3316,
+ },
+ [0x3317]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AD, 0x30ED, 0x30EF, 0x30C3, 0x30C8 },
+ unicodeslot=0x3317,
+ },
+ [0x3318]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B0, 0x30E9, 0x30E0 },
+ unicodeslot=0x3318,
+ },
+ [0x3319]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B0, 0x30E9, 0x30E0, 0x30C8, 0x30F3 },
+ unicodeslot=0x3319,
+ },
+ [0x331A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AF, 0x30EB, 0x30BC, 0x30A4, 0x30ED },
+ unicodeslot=0x331A,
+ },
+ [0x331B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AF, 0x30ED, 0x30FC, 0x30CD },
+ unicodeslot=0x331B,
+ },
+ [0x331C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B1, 0x30FC, 0x30B9 },
+ unicodeslot=0x331C,
+ },
+ [0x331D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B3, 0x30EB, 0x30CA },
+ unicodeslot=0x331D,
+ },
+ [0x331E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B3, 0x30FC, 0x30DD },
+ unicodeslot=0x331E,
+ },
+ [0x331F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B5, 0x30A4, 0x30AF, 0x30EB },
+ unicodeslot=0x331F,
+ },
+ [0x3320]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B5, 0x30F3, 0x30C1, 0x30FC, 0x30E0 },
+ unicodeslot=0x3320,
+ },
+ [0x3321]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B7, 0x30EA, 0x30F3, 0x30B0 },
+ unicodeslot=0x3321,
+ },
+ [0x3322]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30BB, 0x30F3, 0x30C1 },
+ unicodeslot=0x3322,
+ },
+ [0x3323]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30BB, 0x30F3, 0x30C8 },
+ unicodeslot=0x3323,
+ },
+ [0x3324]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30C0, 0x30FC, 0x30B9 },
+ unicodeslot=0x3324,
+ },
+ [0x3325]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30C7, 0x30B7 },
+ unicodeslot=0x3325,
+ },
+ [0x3326]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30C9, 0x30EB },
+ unicodeslot=0x3326,
+ },
+ [0x3327]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30C8, 0x30F3 },
+ unicodeslot=0x3327,
+ },
+ [0x3328]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30CA, 0x30CE },
+ unicodeslot=0x3328,
+ },
+ [0x3329]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30CE, 0x30C3, 0x30C8 },
+ unicodeslot=0x3329,
+ },
+ [0x332A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30CF, 0x30A4, 0x30C4 },
+ unicodeslot=0x332A,
+ },
+ [0x332B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D1, 0x30FC, 0x30BB, 0x30F3, 0x30C8 },
+ unicodeslot=0x332B,
+ },
+ [0x332C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D1, 0x30FC, 0x30C4 },
+ unicodeslot=0x332C,
+ },
+ [0x332D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D0, 0x30FC, 0x30EC, 0x30EB },
+ unicodeslot=0x332D,
+ },
+ [0x332E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D4, 0x30A2, 0x30B9, 0x30C8, 0x30EB },
+ unicodeslot=0x332E,
+ },
+ [0x332F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D4, 0x30AF, 0x30EB },
+ unicodeslot=0x332F,
+ },
+ [0x3330]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D4, 0x30B3 },
+ unicodeslot=0x3330,
+ },
+ [0x3331]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D3, 0x30EB },
+ unicodeslot=0x3331,
+ },
+ [0x3332]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D5, 0x30A1, 0x30E9, 0x30C3, 0x30C9 },
+ unicodeslot=0x3332,
+ },
+ [0x3333]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D5, 0x30A3, 0x30FC, 0x30C8 },
+ unicodeslot=0x3333,
+ },
+ [0x3334]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D6, 0x30C3, 0x30B7, 0x30A7, 0x30EB },
+ unicodeslot=0x3334,
+ },
+ [0x3335]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D5, 0x30E9, 0x30F3 },
+ unicodeslot=0x3335,
+ },
+ [0x3336]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D8, 0x30AF, 0x30BF, 0x30FC, 0x30EB },
+ unicodeslot=0x3336,
+ },
+ [0x3337]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DA, 0x30BD },
+ unicodeslot=0x3337,
+ },
+ [0x3338]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DA, 0x30CB, 0x30D2 },
+ unicodeslot=0x3338,
+ },
+ [0x3339]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D8, 0x30EB, 0x30C4 },
+ unicodeslot=0x3339,
+ },
+ [0x333A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DA, 0x30F3, 0x30B9 },
+ unicodeslot=0x333A,
+ },
+ [0x333B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DA, 0x30FC, 0x30B8 },
+ unicodeslot=0x333B,
+ },
+ [0x333C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D9, 0x30FC, 0x30BF },
+ unicodeslot=0x333C,
+ },
+ [0x333D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DD, 0x30A4, 0x30F3, 0x30C8 },
+ unicodeslot=0x333D,
+ },
+ [0x333E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DC, 0x30EB, 0x30C8 },
+ unicodeslot=0x333E,
+ },
+ [0x333F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DB, 0x30F3 },
+ unicodeslot=0x333F,
+ },
+ [0x3340]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DD, 0x30F3, 0x30C9 },
+ unicodeslot=0x3340,
+ },
+ [0x3341]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DB, 0x30FC, 0x30EB },
+ unicodeslot=0x3341,
+ },
+ [0x3342]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DB, 0x30FC, 0x30F3 },
+ unicodeslot=0x3342,
+ },
+ [0x3343]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DE, 0x30A4, 0x30AF, 0x30ED },
+ unicodeslot=0x3343,
+ },
+ [0x3344]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DE, 0x30A4, 0x30EB },
+ unicodeslot=0x3344,
+ },
+ [0x3345]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DE, 0x30C3, 0x30CF },
+ unicodeslot=0x3345,
+ },
+ [0x3346]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DE, 0x30EB, 0x30AF },
+ unicodeslot=0x3346,
+ },
+ [0x3347]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DE, 0x30F3, 0x30B7, 0x30E7, 0x30F3 },
+ unicodeslot=0x3347,
+ },
+ [0x3348]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DF, 0x30AF, 0x30ED, 0x30F3 },
+ unicodeslot=0x3348,
+ },
+ [0x3349]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DF, 0x30EA },
+ unicodeslot=0x3349,
+ },
+ [0x334A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DF, 0x30EA, 0x30D0, 0x30FC, 0x30EB },
+ unicodeslot=0x334A,
+ },
+ [0x334B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30E1, 0x30AC },
+ unicodeslot=0x334B,
+ },
+ [0x334C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30E1, 0x30AC, 0x30C8, 0x30F3 },
+ unicodeslot=0x334C,
+ },
+ [0x334D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30E1, 0x30FC, 0x30C8, 0x30EB },
+ unicodeslot=0x334D,
+ },
+ [0x334E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30E4, 0x30FC, 0x30C9 },
+ unicodeslot=0x334E,
+ },
+ [0x334F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30E4, 0x30FC, 0x30EB },
+ unicodeslot=0x334F,
+ },
+ [0x3350]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30E6, 0x30A2, 0x30F3 },
+ unicodeslot=0x3350,
+ },
+ [0x3351]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EA, 0x30C3, 0x30C8, 0x30EB },
+ unicodeslot=0x3351,
+ },
+ [0x3352]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EA, 0x30E9 },
+ unicodeslot=0x3352,
+ },
+ [0x3353]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EB, 0x30D4, 0x30FC },
+ unicodeslot=0x3353,
+ },
+ [0x3354]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EB, 0x30FC, 0x30D6, 0x30EB },
+ unicodeslot=0x3354,
+ },
+ [0x3355]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EC, 0x30E0 },
+ unicodeslot=0x3355,
+ },
+ [0x3356]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EC, 0x30F3, 0x30C8, 0x30B2, 0x30F3 },
+ unicodeslot=0x3356,
+ },
+ [0x3357]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EF, 0x30C3, 0x30C8 },
+ unicodeslot=0x3357,
+ },
+ [0x3358]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x30, 0x70B9 },
+ unicodeslot=0x3358,
+ },
+ [0x3359]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x70B9 },
+ unicodeslot=0x3359,
+ },
+ [0x335A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x70B9 },
+ unicodeslot=0x335A,
+ },
+ [0x335B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x33, 0x70B9 },
+ unicodeslot=0x335B,
+ },
+ [0x335C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x34, 0x70B9 },
+ unicodeslot=0x335C,
+ },
+ [0x335D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x35, 0x70B9 },
+ unicodeslot=0x335D,
+ },
+ [0x335E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x36, 0x70B9 },
+ unicodeslot=0x335E,
+ },
+ [0x335F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x37, 0x70B9 },
+ unicodeslot=0x335F,
+ },
+ [0x3360]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x38, 0x70B9 },
+ unicodeslot=0x3360,
+ },
+ [0x3361]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x39, 0x70B9 },
+ unicodeslot=0x3361,
+ },
+ [0x3362]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x30, 0x70B9 },
+ unicodeslot=0x3362,
+ },
+ [0x3363]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x31, 0x70B9 },
+ unicodeslot=0x3363,
+ },
+ [0x3364]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x32, 0x70B9 },
+ unicodeslot=0x3364,
+ },
+ [0x3365]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x33, 0x70B9 },
+ unicodeslot=0x3365,
+ },
+ [0x3366]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x34, 0x70B9 },
+ unicodeslot=0x3366,
+ },
+ [0x3367]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x35, 0x70B9 },
+ unicodeslot=0x3367,
+ },
+ [0x3368]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x36, 0x70B9 },
+ unicodeslot=0x3368,
+ },
+ [0x3369]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x37, 0x70B9 },
+ unicodeslot=0x3369,
+ },
+ [0x336A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x38, 0x70B9 },
+ unicodeslot=0x336A,
+ },
+ [0x336B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x39, 0x70B9 },
+ unicodeslot=0x336B,
+ },
+ [0x336C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x30, 0x70B9 },
+ unicodeslot=0x336C,
+ },
+ [0x336D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x31, 0x70B9 },
+ unicodeslot=0x336D,
+ },
+ [0x336E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x32, 0x70B9 },
+ unicodeslot=0x336E,
+ },
+ [0x336F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x33, 0x70B9 },
+ unicodeslot=0x336F,
+ },
+ [0x3370]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x34, 0x70B9 },
+ unicodeslot=0x3370,
+ },
+ [0x3371]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x68, 0x50, 0x61 },
+ unicodeslot=0x3371,
+ },
+ [0x3372]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x64, 0x61 },
+ unicodeslot=0x3372,
+ },
+ [0x3373]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x41, 0x55 },
+ unicodeslot=0x3373,
+ },
+ [0x3374]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x62, 0x61, 0x72 },
+ unicodeslot=0x3374,
+ },
+ [0x3375]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6F, 0x56 },
+ unicodeslot=0x3375,
+ },
+ [0x3376]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x70, 0x63 },
+ unicodeslot=0x3376,
+ },
+ [0x3377]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x64, 0x6D },
+ unicodeslot=0x3377,
+ },
+ [0x3378]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x64, 0x6D, 0xB2 },
+ unicodeslot=0x3378,
+ },
+ [0x3379]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x64, 0x6D, 0xB3 },
+ unicodeslot=0x3379,
+ },
+ [0x337A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x49, 0x55 },
+ unicodeslot=0x337A,
+ },
+ [0x337B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5E73, 0x6210 },
+ unicodeslot=0x337B,
+ },
+ [0x337C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x662D, 0x548C },
+ unicodeslot=0x337C,
+ },
+ [0x337D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5927, 0x6B63 },
+ unicodeslot=0x337D,
+ },
+ [0x337E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x660E, 0x6CBB },
+ unicodeslot=0x337E,
+ },
+ [0x337F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x682A, 0x5F0F, 0x4F1A, 0x793E },
+ unicodeslot=0x337F,
+ },
+ [0x3380]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x70, 0x41 },
+ unicodeslot=0x3380,
+ },
+ [0x3381]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6E, 0x41 },
+ unicodeslot=0x3381,
+ },
+ [0x3382]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x3BC, 0x41 },
+ unicodeslot=0x3382,
+ },
+ [0x3383]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x41 },
+ unicodeslot=0x3383,
+ },
+ [0x3384]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x41 },
+ unicodeslot=0x3384,
+ },
+ [0x3385]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4B, 0x42 },
+ unicodeslot=0x3385,
+ },
+ [0x3386]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4D, 0x42 },
+ unicodeslot=0x3386,
+ },
+ [0x3387]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x47, 0x42 },
+ unicodeslot=0x3387,
+ },
+ [0x3388]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x63, 0x61, 0x6C },
+ unicodeslot=0x3388,
+ },
+ [0x3389]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x63, 0x61, 0x6C },
+ unicodeslot=0x3389,
+ },
+ [0x338A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x70, 0x46 },
+ unicodeslot=0x338A,
+ },
+ [0x338B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6E, 0x46 },
+ unicodeslot=0x338B,
+ },
+ [0x338C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x3BC, 0x46 },
+ unicodeslot=0x338C,
+ },
+ [0x338D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x3BC, 0x67 },
+ unicodeslot=0x338D,
+ },
+ [0x338E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x67 },
+ unicodeslot=0x338E,
+ },
+ [0x338F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x67 },
+ unicodeslot=0x338F,
+ },
+ [0x3390]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x48, 0x7A },
+ unicodeslot=0x3390,
+ },
+ [0x3391]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x48, 0x7A },
+ unicodeslot=0x3391,
+ },
+ [0x3392]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4D, 0x48, 0x7A },
+ unicodeslot=0x3392,
+ },
+ [0x3393]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x47, 0x48, 0x7A },
+ unicodeslot=0x3393,
+ },
+ [0x3394]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x54, 0x48, 0x7A },
+ unicodeslot=0x3394,
+ },
+ [0x3395]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x3BC, 0x2113 },
+ unicodeslot=0x3395,
+ },
+ [0x3396]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x2113 },
+ unicodeslot=0x3396,
+ },
+ [0x3397]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x64, 0x2113 },
+ unicodeslot=0x3397,
+ },
+ [0x3398]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x2113 },
+ unicodeslot=0x3398,
+ },
+ [0x3399]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x66, 0x6D },
+ unicodeslot=0x3399,
+ },
+ [0x339A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6E, 0x6D },
+ unicodeslot=0x339A,
+ },
+ [0x339B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x3BC, 0x6D },
+ unicodeslot=0x339B,
+ },
+ [0x339C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x6D },
+ unicodeslot=0x339C,
+ },
+ [0x339D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x63, 0x6D },
+ unicodeslot=0x339D,
+ },
+ [0x339E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x6D },
+ unicodeslot=0x339E,
+ },
+ [0x339F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x6D, 0xB2 },
+ unicodeslot=0x339F,
+ },
+ [0x33A0]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x63, 0x6D, 0xB2 },
+ unicodeslot=0x33A0,
+ },
+ [0x33A1]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0xB2 },
+ unicodeslot=0x33A1,
+ },
+ [0x33A2]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x6D, 0xB2 },
+ unicodeslot=0x33A2,
+ },
+ [0x33A3]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x6D, 0xB3 },
+ unicodeslot=0x33A3,
+ },
+ [0x33A4]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x63, 0x6D, 0xB3 },
+ unicodeslot=0x33A4,
+ },
+ [0x33A5]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0xB3 },
+ unicodeslot=0x33A5,
+ },
+ [0x33A6]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x6D, 0xB3 },
+ unicodeslot=0x33A6,
+ },
+ [0x33A7]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x2215, 0x73 },
+ unicodeslot=0x33A7,
+ },
+ [0x33A8]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x2215, 0x73, 0xB2 },
+ unicodeslot=0x33A8,
+ },
+ [0x33A9]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x50, 0x61 },
+ unicodeslot=0x33A9,
+ },
+ [0x33AA]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x50, 0x61 },
+ unicodeslot=0x33AA,
+ },
+ [0x33AB]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4D, 0x50, 0x61 },
+ unicodeslot=0x33AB,
+ },
+ [0x33AC]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x47, 0x50, 0x61 },
+ unicodeslot=0x33AC,
+ },
+ [0x33AD]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x72, 0x61, 0x64 },
+ unicodeslot=0x33AD,
+ },
+ [0x33AE]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x72, 0x61, 0x64, 0x2215, 0x73 },
+ unicodeslot=0x33AE,
+ },
+ [0x33AF]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x72, 0x61, 0x64, 0x2215, 0x73, 0xB2 },
+ unicodeslot=0x33AF,
+ },
+ [0x33B0]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x70, 0x73 },
+ unicodeslot=0x33B0,
+ },
+ [0x33B1]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6E, 0x73 },
+ unicodeslot=0x33B1,
+ },
+ [0x33B2]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x3BC, 0x73 },
+ unicodeslot=0x33B2,
+ },
+ [0x33B3]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x73 },
+ unicodeslot=0x33B3,
+ },
+ [0x33B4]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x70, 0x56 },
+ unicodeslot=0x33B4,
+ },
+ [0x33B5]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6E, 0x56 },
+ unicodeslot=0x33B5,
+ },
+ [0x33B6]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x3BC, 0x56 },
+ unicodeslot=0x33B6,
+ },
+ [0x33B7]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x56 },
+ unicodeslot=0x33B7,
+ },
+ [0x33B8]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x56 },
+ unicodeslot=0x33B8,
+ },
+ [0x33B9]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4D, 0x56 },
+ unicodeslot=0x33B9,
+ },
+ [0x33BA]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x70, 0x57 },
+ unicodeslot=0x33BA,
+ },
+ [0x33BB]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6E, 0x57 },
+ unicodeslot=0x33BB,
+ },
+ [0x33BC]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x3BC, 0x57 },
+ unicodeslot=0x33BC,
+ },
+ [0x33BD]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x57 },
+ unicodeslot=0x33BD,
+ },
+ [0x33BE]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x57 },
+ unicodeslot=0x33BE,
+ },
+ [0x33BF]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4D, 0x57 },
+ unicodeslot=0x33BF,
+ },
+ [0x33C0]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x3A9 },
+ unicodeslot=0x33C0,
+ },
+ [0x33C1]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4D, 0x3A9 },
+ unicodeslot=0x33C1,
+ },
+ [0x33C2]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x61, 0x2E, 0x6D, 0x2E },
+ unicodeslot=0x33C2,
+ },
+ [0x33C3]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x42, 0x71 },
+ unicodeslot=0x33C3,
+ },
+ [0x33C4]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x63, 0x63 },
+ unicodeslot=0x33C4,
+ },
+ [0x33C5]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x63, 0x64 },
+ unicodeslot=0x33C5,
+ },
+ [0x33C6]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x43, 0x2215, 0x6B, 0x67 },
+ unicodeslot=0x33C6,
+ },
+ [0x33C7]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x43, 0x6F, 0x2E },
+ unicodeslot=0x33C7,
+ },
+ [0x33C8]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x64, 0x42 },
+ unicodeslot=0x33C8,
+ },
+ [0x33C9]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x47, 0x79 },
+ unicodeslot=0x33C9,
+ },
+ [0x33CA]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x68, 0x61 },
+ unicodeslot=0x33CA,
+ },
+ [0x33CB]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x48, 0x50 },
+ unicodeslot=0x33CB,
+ },
+ [0x33CC]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x69, 0x6E },
+ unicodeslot=0x33CC,
+ },
+ [0x33CD]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4B, 0x4B },
+ unicodeslot=0x33CD,
+ },
+ [0x33CE]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4B, 0x4D },
+ unicodeslot=0x33CE,
+ },
+ [0x33CF]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6B, 0x74 },
+ unicodeslot=0x33CF,
+ },
+ [0x33D0]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6C, 0x6D },
+ unicodeslot=0x33D0,
+ },
+ [0x33D1]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6C, 0x6E },
+ unicodeslot=0x33D1,
+ },
+ [0x33D2]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6C, 0x6F, 0x67 },
+ unicodeslot=0x33D2,
+ },
+ [0x33D3]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6C, 0x78 },
+ unicodeslot=0x33D3,
+ },
+ [0x33D4]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x62 },
+ unicodeslot=0x33D4,
+ },
+ [0x33D5]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x69, 0x6C },
+ unicodeslot=0x33D5,
+ },
+ [0x33D6]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6D, 0x6F, 0x6C },
+ unicodeslot=0x33D6,
+ },
+ [0x33D7]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x50, 0x48 },
+ unicodeslot=0x33D7,
+ },
+ [0x33D8]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x70, 0x2E, 0x6D, 0x2E },
+ unicodeslot=0x33D8,
+ },
+ [0x33D9]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x50, 0x50, 0x4D },
+ unicodeslot=0x33D9,
+ },
+ [0x33DA]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x50, 0x52 },
+ unicodeslot=0x33DA,
+ },
+ [0x33DB]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x73, 0x72 },
+ unicodeslot=0x33DB,
+ },
+ [0x33DC]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x53, 0x76 },
+ unicodeslot=0x33DC,
+ },
+ [0x33DD]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x57, 0x62 },
+ unicodeslot=0x33DD,
+ },
+ [0x33DE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x56, 0x2215, 0x6D },
+ unicodeslot=0x33DE,
+ },
+ [0x33DF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x41, 0x2215, 0x6D },
+ unicodeslot=0x33DF,
+ },
+ [0x33E0]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x65E5 },
+ unicodeslot=0x33E0,
+ },
+ [0x33E1]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x65E5 },
+ unicodeslot=0x33E1,
+ },
+ [0x33E2]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x33, 0x65E5 },
+ unicodeslot=0x33E2,
+ },
+ [0x33E3]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x34, 0x65E5 },
+ unicodeslot=0x33E3,
+ },
+ [0x33E4]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x35, 0x65E5 },
+ unicodeslot=0x33E4,
+ },
+ [0x33E5]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x36, 0x65E5 },
+ unicodeslot=0x33E5,
+ },
+ [0x33E6]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x37, 0x65E5 },
+ unicodeslot=0x33E6,
+ },
+ [0x33E7]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x38, 0x65E5 },
+ unicodeslot=0x33E7,
+ },
+ [0x33E8]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x39, 0x65E5 },
+ unicodeslot=0x33E8,
+ },
+ [0x33E9]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x30, 0x65E5 },
+ unicodeslot=0x33E9,
+ },
+ [0x33EA]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x31, 0x65E5 },
+ unicodeslot=0x33EA,
+ },
+ [0x33EB]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x32, 0x65E5 },
+ unicodeslot=0x33EB,
+ },
+ [0x33EC]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x33, 0x65E5 },
+ unicodeslot=0x33EC,
+ },
+ [0x33ED]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x34, 0x65E5 },
+ unicodeslot=0x33ED,
+ },
+ [0x33EE]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x35, 0x65E5 },
+ unicodeslot=0x33EE,
+ },
+ [0x33EF]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x36, 0x65E5 },
+ unicodeslot=0x33EF,
+ },
+ [0x33F0]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x37, 0x65E5 },
+ unicodeslot=0x33F0,
+ },
+ [0x33F1]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x38, 0x65E5 },
+ unicodeslot=0x33F1,
+ },
+ [0x33F2]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x31, 0x39, 0x65E5 },
+ unicodeslot=0x33F2,
+ },
+ [0x33F3]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x30, 0x65E5 },
+ unicodeslot=0x33F3,
+ },
+ [0x33F4]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x31, 0x65E5 },
+ unicodeslot=0x33F4,
+ },
+ [0x33F5]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x32, 0x65E5 },
+ unicodeslot=0x33F5,
+ },
+ [0x33F6]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x33, 0x65E5 },
+ unicodeslot=0x33F6,
+ },
+ [0x33F7]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x34, 0x65E5 },
+ unicodeslot=0x33F7,
+ },
+ [0x33F8]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x35, 0x65E5 },
+ unicodeslot=0x33F8,
+ },
+ [0x33F9]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x36, 0x65E5 },
+ unicodeslot=0x33F9,
+ },
+ [0x33FA]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x37, 0x65E5 },
+ unicodeslot=0x33FA,
+ },
+ [0x33FB]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x38, 0x65E5 },
+ unicodeslot=0x33FB,
+ },
+ [0x33FC]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x32, 0x39, 0x65E5 },
+ unicodeslot=0x33FC,
+ },
+ [0x33FD]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x33, 0x30, 0x65E5 },
+ unicodeslot=0x33FD,
+ },
+ [0x33FE]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x33, 0x31, 0x65E5 },
+ unicodeslot=0x33FE,
+ },
+ [0x33FF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x67, 0x61, 0x6C },
+ unicodeslot=0x33FF,
+ },
+ [0x4DC0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC0,
+ },
+ [0x4DC1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC1,
+ },
+ [0x4DC2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC2,
+ },
+ [0x4DC3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC3,
+ },
+ [0x4DC4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC4,
+ },
+ [0x4DC5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC5,
+ },
+ [0x4DC6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC6,
+ },
+ [0x4DC7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC7,
+ },
+ [0x4DC8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC8,
+ },
+ [0x4DC9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC9,
+ },
+ [0x4DCA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DCA,
+ },
+ [0x4DCB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DCB,
+ },
+ [0x4DCC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DCC,
+ },
+ [0x4DCD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DCD,
+ },
+ [0x4DCE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DCE,
+ },
+ [0x4DCF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DCF,
+ },
+ [0x4DD0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD0,
+ },
+ [0x4DD1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD1,
+ },
+ [0x4DD2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD2,
+ },
+ [0x4DD3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD3,
+ },
+ [0x4DD4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD4,
+ },
+ [0x4DD5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD5,
+ },
+ [0x4DD6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD6,
+ },
+ [0x4DD7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD7,
+ },
+ [0x4DD8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD8,
+ },
+ [0x4DD9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD9,
+ },
+ [0x4DDA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DDA,
+ },
+ [0x4DDB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DDB,
+ },
+ [0x4DDC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DDC,
+ },
+ [0x4DDD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DDD,
+ },
+ [0x4DDE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DDE,
+ },
+ [0x4DDF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DDF,
+ },
+ [0x4DE0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE0,
+ },
+ [0x4DE1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE1,
+ },
+ [0x4DE2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE2,
+ },
+ [0x4DE3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE3,
+ },
+ [0x4DE4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE4,
+ },
+ [0x4DE5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE5,
+ },
+ [0x4DE6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE6,
+ },
+ [0x4DE7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE7,
+ },
+ [0x4DE8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE8,
+ },
+ [0x4DE9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE9,
+ },
+ [0x4DEA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DEA,
+ },
+ [0x4DEB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DEB,
+ },
+ [0x4DEC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DEC,
+ },
+ [0x4DED]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DED,
+ },
+ [0x4DEE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DEE,
+ },
+ [0x4DEF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DEF,
+ },
+ [0x4DF0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF0,
+ },
+ [0x4DF1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF1,
+ },
+ [0x4DF2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF2,
+ },
+ [0x4DF3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF3,
+ },
+ [0x4DF4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF4,
+ },
+ [0x4DF5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF5,
+ },
+ [0x4DF6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF6,
+ },
+ [0x4DF7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF7,
+ },
+ [0x4DF8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF8,
+ },
+ [0x4DF9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF9,
+ },
+ [0x4DFA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DFA,
+ },
+ [0x4DFB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DFB,
+ },
+ [0x4DFC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DFC,
+ },
+ [0x4DFD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DFD,
+ },
+ [0x4DFE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DFE,
+ },
+ [0x4DFF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DFF,
+ },
+ [0xA000]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA000,
+ },
+ [0xA001]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA001,
+ },
+ [0xA002]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA002,
+ },
+ [0xA003]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA003,
+ },
+ [0xA004]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA004,
+ },
+ [0xA005]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA005,
+ },
+ [0xA006]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA006,
+ },
+ [0xA007]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA007,
+ },
+ [0xA008]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA008,
+ },
+ [0xA009]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA009,
+ },
+ [0xA00A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA00A,
+ },
+ [0xA00B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA00B,
+ },
+ [0xA00C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA00C,
+ },
+ [0xA00D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA00D,
+ },
+ [0xA00E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA00E,
+ },
+ [0xA00F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA00F,
+ },
+ [0xA010]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA010,
+ },
+ [0xA011]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA011,
+ },
+ [0xA012]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA012,
+ },
+ [0xA013]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA013,
+ },
+ [0xA014]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA014,
+ },
+ [0xA015]={
+ category="lm",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0xA015,
+ },
+ [0xA016]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA016,
+ },
+ [0xA017]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA017,
+ },
+ [0xA018]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA018,
+ },
+ [0xA019]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA019,
+ },
+ [0xA01A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA01A,
+ },
+ [0xA01B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA01B,
+ },
+ [0xA01C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA01C,
+ },
+ [0xA01D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA01D,
+ },
+ [0xA01E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA01E,
+ },
+ [0xA01F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA01F,
+ },
+ [0xA020]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA020,
+ },
+ [0xA021]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA021,
+ },
+ [0xA022]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA022,
+ },
+ [0xA023]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA023,
+ },
+ [0xA024]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA024,
+ },
+ [0xA025]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA025,
+ },
+ [0xA026]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA026,
+ },
+ [0xA027]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA027,
+ },
+ [0xA028]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA028,
+ },
+ [0xA029]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA029,
+ },
+ [0xA02A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA02A,
+ },
+ [0xA02B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA02B,
+ },
+ [0xA02C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA02C,
+ },
+ [0xA02D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA02D,
+ },
+ [0xA02E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA02E,
+ },
+ [0xA02F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA02F,
+ },
+ [0xA030]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA030,
+ },
+ [0xA031]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA031,
+ },
+ [0xA032]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA032,
+ },
+ [0xA033]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA033,
+ },
+ [0xA034]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA034,
+ },
+ [0xA035]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA035,
+ },
+ [0xA036]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA036,
+ },
+ [0xA037]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA037,
+ },
+ [0xA038]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA038,
+ },
+ [0xA039]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA039,
+ },
+ [0xA03A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA03A,
+ },
+ [0xA03B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA03B,
+ },
+ [0xA03C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA03C,
+ },
+ [0xA03D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA03D,
+ },
+ [0xA03E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA03E,
+ },
+ [0xA03F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA03F,
+ },
+ [0xA040]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA040,
+ },
+ [0xA041]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA041,
+ },
+ [0xA042]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA042,
+ },
+ [0xA043]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA043,
+ },
+ [0xA044]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA044,
+ },
+ [0xA045]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA045,
+ },
+ [0xA046]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA046,
+ },
+ [0xA047]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA047,
+ },
+ [0xA048]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA048,
+ },
+ [0xA049]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA049,
+ },
+ [0xA04A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA04A,
+ },
+ [0xA04B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA04B,
+ },
+ [0xA04C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA04C,
+ },
+ [0xA04D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA04D,
+ },
+ [0xA04E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA04E,
+ },
+ [0xA04F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA04F,
+ },
+ [0xA050]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA050,
+ },
+ [0xA051]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA051,
+ },
+ [0xA052]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA052,
+ },
+ [0xA053]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA053,
+ },
+ [0xA054]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA054,
+ },
+ [0xA055]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA055,
+ },
+ [0xA056]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA056,
+ },
+ [0xA057]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA057,
+ },
+ [0xA058]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA058,
+ },
+ [0xA059]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA059,
+ },
+ [0xA05A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA05A,
+ },
+ [0xA05B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA05B,
+ },
+ [0xA05C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA05C,
+ },
+ [0xA05D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA05D,
+ },
+ [0xA05E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA05E,
+ },
+ [0xA05F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA05F,
+ },
+ [0xA060]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA060,
+ },
+ [0xA061]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA061,
+ },
+ [0xA062]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA062,
+ },
+ [0xA063]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA063,
+ },
+ [0xA064]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA064,
+ },
+ [0xA065]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA065,
+ },
+ [0xA066]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA066,
+ },
+ [0xA067]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA067,
+ },
+ [0xA068]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA068,
+ },
+ [0xA069]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA069,
+ },
+ [0xA06A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA06A,
+ },
+ [0xA06B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA06B,
+ },
+ [0xA06C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA06C,
+ },
+ [0xA06D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA06D,
+ },
+ [0xA06E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA06E,
+ },
+ [0xA06F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA06F,
+ },
+ [0xA070]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA070,
+ },
+ [0xA071]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA071,
+ },
+ [0xA072]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA072,
+ },
+ [0xA073]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA073,
+ },
+ [0xA074]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA074,
+ },
+ [0xA075]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA075,
+ },
+ [0xA076]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA076,
+ },
+ [0xA077]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA077,
+ },
+ [0xA078]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA078,
+ },
+ [0xA079]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA079,
+ },
+ [0xA07A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA07A,
+ },
+ [0xA07B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA07B,
+ },
+ [0xA07C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA07C,
+ },
+ [0xA07D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA07D,
+ },
+ [0xA07E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA07E,
+ },
+ [0xA07F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA07F,
+ },
+ [0xA080]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA080,
+ },
+ [0xA081]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA081,
+ },
+ [0xA082]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA082,
+ },
+ [0xA083]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA083,
+ },
+ [0xA084]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA084,
+ },
+ [0xA085]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA085,
+ },
+ [0xA086]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA086,
+ },
+ [0xA087]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA087,
+ },
+ [0xA088]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA088,
+ },
+ [0xA089]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA089,
+ },
+ [0xA08A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA08A,
+ },
+ [0xA08B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA08B,
+ },
+ [0xA08C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA08C,
+ },
+ [0xA08D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA08D,
+ },
+ [0xA08E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA08E,
+ },
+ [0xA08F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA08F,
+ },
+ [0xA090]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA090,
+ },
+ [0xA091]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA091,
+ },
+ [0xA092]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA092,
+ },
+ [0xA093]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA093,
+ },
+ [0xA094]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA094,
+ },
+ [0xA095]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA095,
+ },
+ [0xA096]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA096,
+ },
+ [0xA097]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA097,
+ },
+ [0xA098]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA098,
+ },
+ [0xA099]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA099,
+ },
+ [0xA09A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA09A,
+ },
+ [0xA09B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA09B,
+ },
+ [0xA09C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA09C,
+ },
+ [0xA09D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA09D,
+ },
+ [0xA09E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA09E,
+ },
+ [0xA09F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA09F,
+ },
+ [0xA0A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A0,
+ },
+ [0xA0A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A1,
+ },
+ [0xA0A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A2,
+ },
+ [0xA0A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A3,
+ },
+ [0xA0A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A4,
+ },
+ [0xA0A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A5,
+ },
+ [0xA0A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A6,
+ },
+ [0xA0A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A7,
+ },
+ [0xA0A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A8,
+ },
+ [0xA0A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A9,
+ },
+ [0xA0AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0AA,
+ },
+ [0xA0AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0AB,
+ },
+ [0xA0AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0AC,
+ },
+ [0xA0AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0AD,
+ },
+ [0xA0AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0AE,
+ },
+ [0xA0AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0AF,
+ },
+ [0xA0B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B0,
+ },
+ [0xA0B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B1,
+ },
+ [0xA0B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B2,
+ },
+ [0xA0B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B3,
+ },
+ [0xA0B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B4,
+ },
+ [0xA0B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B5,
+ },
+ [0xA0B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B6,
+ },
+ [0xA0B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B7,
+ },
+ [0xA0B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B8,
+ },
+ [0xA0B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B9,
+ },
+ [0xA0BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0BA,
+ },
+ [0xA0BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0BB,
+ },
+ [0xA0BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0BC,
+ },
+ [0xA0BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0BD,
+ },
+ [0xA0BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0BE,
+ },
+ [0xA0BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0BF,
+ },
+ [0xA0C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C0,
+ },
+ [0xA0C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C1,
+ },
+ [0xA0C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C2,
+ },
+ [0xA0C3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C3,
+ },
+ [0xA0C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C4,
+ },
+ [0xA0C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C5,
+ },
+ [0xA0C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C6,
+ },
+ [0xA0C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C7,
+ },
+ [0xA0C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C8,
+ },
+ [0xA0C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C9,
+ },
+ [0xA0CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0CA,
+ },
+ [0xA0CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0CB,
+ },
+ [0xA0CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0CC,
+ },
+ [0xA0CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0CD,
+ },
+ [0xA0CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0CE,
+ },
+ [0xA0CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0CF,
+ },
+ [0xA0D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D0,
+ },
+ [0xA0D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D1,
+ },
+ [0xA0D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D2,
+ },
+ [0xA0D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D3,
+ },
+ [0xA0D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D4,
+ },
+ [0xA0D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D5,
+ },
+ [0xA0D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D6,
+ },
+ [0xA0D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D7,
+ },
+ [0xA0D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D8,
+ },
+ [0xA0D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D9,
+ },
+ [0xA0DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0DA,
+ },
+ [0xA0DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0DB,
+ },
+ [0xA0DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0DC,
+ },
+ [0xA0DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0DD,
+ },
+ [0xA0DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0DE,
+ },
+ [0xA0DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0DF,
+ },
+ [0xA0E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E0,
+ },
+ [0xA0E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E1,
+ },
+ [0xA0E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E2,
+ },
+ [0xA0E3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E3,
+ },
+ [0xA0E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E4,
+ },
+ [0xA0E5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E5,
+ },
+ [0xA0E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E6,
+ },
+ [0xA0E7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E7,
+ },
+ [0xA0E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E8,
+ },
+ [0xA0E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E9,
+ },
+ [0xA0EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0EA,
+ },
+ [0xA0EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0EB,
+ },
+ [0xA0EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0EC,
+ },
+ [0xA0ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0ED,
+ },
+ [0xA0EE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0EE,
+ },
+ [0xA0EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0EF,
+ },
+ [0xA0F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F0,
+ },
+ [0xA0F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F1,
+ },
+ [0xA0F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F2,
+ },
+ [0xA0F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F3,
+ },
+ [0xA0F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F4,
+ },
+ [0xA0F5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F5,
+ },
+ [0xA0F6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F6,
+ },
+ [0xA0F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F7,
+ },
+ [0xA0F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F8,
+ },
+ [0xA0F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F9,
+ },
+ [0xA0FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0FA,
+ },
+ [0xA0FB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0FB,
+ },
+ [0xA0FC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0FC,
+ },
+ [0xA0FD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0FD,
+ },
+ [0xA0FE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0FE,
+ },
+ [0xA0FF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0FF,
+ },
+ [0xA100]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA100,
+ },
+ [0xA101]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA101,
+ },
+ [0xA102]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA102,
+ },
+ [0xA103]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA103,
+ },
+ [0xA104]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA104,
+ },
+ [0xA105]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA105,
+ },
+ [0xA106]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA106,
+ },
+ [0xA107]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA107,
+ },
+ [0xA108]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA108,
+ },
+ [0xA109]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA109,
+ },
+ [0xA10A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA10A,
+ },
+ [0xA10B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA10B,
+ },
+ [0xA10C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA10C,
+ },
+ [0xA10D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA10D,
+ },
+ [0xA10E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA10E,
+ },
+ [0xA10F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA10F,
+ },
+ [0xA110]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA110,
+ },
+ [0xA111]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA111,
+ },
+ [0xA112]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA112,
+ },
+ [0xA113]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA113,
+ },
+ [0xA114]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA114,
+ },
+ [0xA115]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA115,
+ },
+ [0xA116]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA116,
+ },
+ [0xA117]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA117,
+ },
+ [0xA118]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA118,
+ },
+ [0xA119]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA119,
+ },
+ [0xA11A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA11A,
+ },
+ [0xA11B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA11B,
+ },
+ [0xA11C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA11C,
+ },
+ [0xA11D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA11D,
+ },
+ [0xA11E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA11E,
+ },
+ [0xA11F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA11F,
+ },
+ [0xA120]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA120,
+ },
+ [0xA121]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA121,
+ },
+ [0xA122]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA122,
+ },
+ [0xA123]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA123,
+ },
+ [0xA124]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA124,
+ },
+ [0xA125]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA125,
+ },
+ [0xA126]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA126,
+ },
+ [0xA127]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA127,
+ },
+ [0xA128]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA128,
+ },
+ [0xA129]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA129,
+ },
+ [0xA12A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA12A,
+ },
+ [0xA12B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA12B,
+ },
+ [0xA12C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA12C,
+ },
+ [0xA12D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA12D,
+ },
+ [0xA12E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA12E,
+ },
+ [0xA12F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA12F,
+ },
+ [0xA130]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA130,
+ },
+ [0xA131]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA131,
+ },
+ [0xA132]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA132,
+ },
+ [0xA133]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA133,
+ },
+ [0xA134]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA134,
+ },
+ [0xA135]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA135,
+ },
+ [0xA136]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA136,
+ },
+ [0xA137]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA137,
+ },
+ [0xA138]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA138,
+ },
+ [0xA139]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA139,
+ },
+ [0xA13A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA13A,
+ },
+ [0xA13B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA13B,
+ },
+ [0xA13C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA13C,
+ },
+ [0xA13D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA13D,
+ },
+ [0xA13E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA13E,
+ },
+ [0xA13F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA13F,
+ },
+ [0xA140]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA140,
+ },
+ [0xA141]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA141,
+ },
+ [0xA142]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA142,
+ },
+ [0xA143]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA143,
+ },
+ [0xA144]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA144,
+ },
+ [0xA145]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA145,
+ },
+ [0xA146]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA146,
+ },
+ [0xA147]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA147,
+ },
+ [0xA148]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA148,
+ },
+ [0xA149]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA149,
+ },
+ [0xA14A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA14A,
+ },
+ [0xA14B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA14B,
+ },
+ [0xA14C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA14C,
+ },
+ [0xA14D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA14D,
+ },
+ [0xA14E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA14E,
+ },
+ [0xA14F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA14F,
+ },
+ [0xA150]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA150,
+ },
+ [0xA151]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA151,
+ },
+ [0xA152]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA152,
+ },
+ [0xA153]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA153,
+ },
+ [0xA154]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA154,
+ },
+ [0xA155]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA155,
+ },
+ [0xA156]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA156,
+ },
+ [0xA157]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA157,
+ },
+ [0xA158]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA158,
+ },
+ [0xA159]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA159,
+ },
+ [0xA15A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA15A,
+ },
+ [0xA15B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA15B,
+ },
+ [0xA15C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA15C,
+ },
+ [0xA15D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA15D,
+ },
+ [0xA15E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA15E,
+ },
+ [0xA15F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA15F,
+ },
+ [0xA160]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA160,
+ },
+ [0xA161]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA161,
+ },
+ [0xA162]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA162,
+ },
+ [0xA163]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA163,
+ },
+ [0xA164]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA164,
+ },
+ [0xA165]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA165,
+ },
+ [0xA166]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA166,
+ },
+ [0xA167]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA167,
+ },
+ [0xA168]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA168,
+ },
+ [0xA169]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA169,
+ },
+ [0xA16A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA16A,
+ },
+ [0xA16B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA16B,
+ },
+ [0xA16C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA16C,
+ },
+ [0xA16D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA16D,
+ },
+ [0xA16E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA16E,
+ },
+ [0xA16F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA16F,
+ },
+ [0xA170]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA170,
+ },
+ [0xA171]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA171,
+ },
+ [0xA172]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA172,
+ },
+ [0xA173]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA173,
+ },
+ [0xA174]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA174,
+ },
+ [0xA175]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA175,
+ },
+ [0xA176]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA176,
+ },
+ [0xA177]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA177,
+ },
+ [0xA178]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA178,
+ },
+ [0xA179]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA179,
+ },
+ [0xA17A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA17A,
+ },
+ [0xA17B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA17B,
+ },
+ [0xA17C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA17C,
+ },
+ [0xA17D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA17D,
+ },
+ [0xA17E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA17E,
+ },
+ [0xA17F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA17F,
+ },
+ [0xA180]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA180,
+ },
+ [0xA181]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA181,
+ },
+ [0xA182]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA182,
+ },
+ [0xA183]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA183,
+ },
+ [0xA184]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA184,
+ },
+ [0xA185]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA185,
+ },
+ [0xA186]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA186,
+ },
+ [0xA187]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA187,
+ },
+ [0xA188]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA188,
+ },
+ [0xA189]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA189,
+ },
+ [0xA18A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA18A,
+ },
+ [0xA18B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA18B,
+ },
+ [0xA18C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA18C,
+ },
+ [0xA18D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA18D,
+ },
+ [0xA18E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA18E,
+ },
+ [0xA18F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA18F,
+ },
+ [0xA190]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA190,
+ },
+ [0xA191]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA191,
+ },
+ [0xA192]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA192,
+ },
+ [0xA193]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA193,
+ },
+ [0xA194]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA194,
+ },
+ [0xA195]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA195,
+ },
+ [0xA196]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA196,
+ },
+ [0xA197]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA197,
+ },
+ [0xA198]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA198,
+ },
+ [0xA199]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA199,
+ },
+ [0xA19A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA19A,
+ },
+ [0xA19B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA19B,
+ },
+ [0xA19C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA19C,
+ },
+ [0xA19D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA19D,
+ },
+ [0xA19E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA19E,
+ },
+ [0xA19F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA19F,
+ },
+ [0xA1A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A0,
+ },
+ [0xA1A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A1,
+ },
+ [0xA1A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A2,
+ },
+ [0xA1A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A3,
+ },
+ [0xA1A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A4,
+ },
+ [0xA1A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A5,
+ },
+ [0xA1A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A6,
+ },
+ [0xA1A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A7,
+ },
+ [0xA1A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A8,
+ },
+ [0xA1A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A9,
+ },
+ [0xA1AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1AA,
+ },
+ [0xA1AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1AB,
+ },
+ [0xA1AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1AC,
+ },
+ [0xA1AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1AD,
+ },
+ [0xA1AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1AE,
+ },
+ [0xA1AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1AF,
+ },
+ [0xA1B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B0,
+ },
+ [0xA1B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B1,
+ },
+ [0xA1B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B2,
+ },
+ [0xA1B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B3,
+ },
+ [0xA1B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B4,
+ },
+ [0xA1B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B5,
+ },
+ [0xA1B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B6,
+ },
+ [0xA1B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B7,
+ },
+ [0xA1B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B8,
+ },
+ [0xA1B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B9,
+ },
+ [0xA1BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1BA,
+ },
+ [0xA1BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1BB,
+ },
+ [0xA1BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1BC,
+ },
+ [0xA1BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1BD,
+ },
+ [0xA1BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1BE,
+ },
+ [0xA1BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1BF,
+ },
+ [0xA1C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C0,
+ },
+ [0xA1C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C1,
+ },
+ [0xA1C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C2,
+ },
+ [0xA1C3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C3,
+ },
+ [0xA1C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C4,
+ },
+ [0xA1C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C5,
+ },
+ [0xA1C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C6,
+ },
+ [0xA1C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C7,
+ },
+ [0xA1C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C8,
+ },
+ [0xA1C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C9,
+ },
+ [0xA1CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1CA,
+ },
+ [0xA1CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1CB,
+ },
+ [0xA1CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1CC,
+ },
+ [0xA1CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1CD,
+ },
+ [0xA1CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1CE,
+ },
+ [0xA1CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1CF,
+ },
+ [0xA1D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D0,
+ },
+ [0xA1D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D1,
+ },
+ [0xA1D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D2,
+ },
+ [0xA1D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D3,
+ },
+ [0xA1D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D4,
+ },
+ [0xA1D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D5,
+ },
+ [0xA1D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D6,
+ },
+ [0xA1D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D7,
+ },
+ [0xA1D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D8,
+ },
+ [0xA1D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D9,
+ },
+ [0xA1DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1DA,
+ },
+ [0xA1DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1DB,
+ },
+ [0xA1DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1DC,
+ },
+ [0xA1DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1DD,
+ },
+ [0xA1DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1DE,
+ },
+ [0xA1DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1DF,
+ },
+ [0xA1E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E0,
+ },
+ [0xA1E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E1,
+ },
+ [0xA1E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E2,
+ },
+ [0xA1E3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E3,
+ },
+ [0xA1E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E4,
+ },
+ [0xA1E5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E5,
+ },
+ [0xA1E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E6,
+ },
+ [0xA1E7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E7,
+ },
+ [0xA1E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E8,
+ },
+ [0xA1E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E9,
+ },
+ [0xA1EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1EA,
+ },
+ [0xA1EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1EB,
+ },
+ [0xA1EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1EC,
+ },
+ [0xA1ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1ED,
+ },
+ [0xA1EE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1EE,
+ },
+ [0xA1EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1EF,
+ },
+ [0xA1F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F0,
+ },
+ [0xA1F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F1,
+ },
+ [0xA1F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F2,
+ },
+ [0xA1F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F3,
+ },
+ [0xA1F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F4,
+ },
+ [0xA1F5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F5,
+ },
+ [0xA1F6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F6,
+ },
+ [0xA1F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F7,
+ },
+ [0xA1F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F8,
+ },
+ [0xA1F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F9,
+ },
+ [0xA1FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1FA,
+ },
+ [0xA1FB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1FB,
+ },
+ [0xA1FC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1FC,
+ },
+ [0xA1FD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1FD,
+ },
+ [0xA1FE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1FE,
+ },
+ [0xA1FF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1FF,
+ },
+ [0xA200]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA200,
+ },
+ [0xA201]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA201,
+ },
+ [0xA202]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA202,
+ },
+ [0xA203]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA203,
+ },
+ [0xA204]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA204,
+ },
+ [0xA205]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA205,
+ },
+ [0xA206]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA206,
+ },
+ [0xA207]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA207,
+ },
+ [0xA208]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA208,
+ },
+ [0xA209]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA209,
+ },
+ [0xA20A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA20A,
+ },
+ [0xA20B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA20B,
+ },
+ [0xA20C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA20C,
+ },
+ [0xA20D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA20D,
+ },
+ [0xA20E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA20E,
+ },
+ [0xA20F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA20F,
+ },
+ [0xA210]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA210,
+ },
+ [0xA211]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA211,
+ },
+ [0xA212]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA212,
+ },
+ [0xA213]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA213,
+ },
+ [0xA214]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA214,
+ },
+ [0xA215]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA215,
+ },
+ [0xA216]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA216,
+ },
+ [0xA217]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA217,
+ },
+ [0xA218]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA218,
+ },
+ [0xA219]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA219,
+ },
+ [0xA21A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA21A,
+ },
+ [0xA21B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA21B,
+ },
+ [0xA21C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA21C,
+ },
+ [0xA21D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA21D,
+ },
+ [0xA21E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA21E,
+ },
+ [0xA21F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA21F,
+ },
+ [0xA220]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA220,
+ },
+ [0xA221]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA221,
+ },
+ [0xA222]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA222,
+ },
+ [0xA223]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA223,
+ },
+ [0xA224]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA224,
+ },
+ [0xA225]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA225,
+ },
+ [0xA226]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA226,
+ },
+ [0xA227]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA227,
+ },
+ [0xA228]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA228,
+ },
+ [0xA229]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA229,
+ },
+ [0xA22A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA22A,
+ },
+ [0xA22B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA22B,
+ },
+ [0xA22C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA22C,
+ },
+ [0xA22D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA22D,
+ },
+ [0xA22E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA22E,
+ },
+ [0xA22F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA22F,
+ },
+ [0xA230]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA230,
+ },
+ [0xA231]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA231,
+ },
+ [0xA232]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA232,
+ },
+ [0xA233]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA233,
+ },
+ [0xA234]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA234,
+ },
+ [0xA235]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA235,
+ },
+ [0xA236]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA236,
+ },
+ [0xA237]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA237,
+ },
+ [0xA238]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA238,
+ },
+ [0xA239]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA239,
+ },
+ [0xA23A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA23A,
+ },
+ [0xA23B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA23B,
+ },
+ [0xA23C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA23C,
+ },
+ [0xA23D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA23D,
+ },
+ [0xA23E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA23E,
+ },
+ [0xA23F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA23F,
+ },
+ [0xA240]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA240,
+ },
+ [0xA241]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA241,
+ },
+ [0xA242]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA242,
+ },
+ [0xA243]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA243,
+ },
+ [0xA244]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA244,
+ },
+ [0xA245]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA245,
+ },
+ [0xA246]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA246,
+ },
+ [0xA247]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA247,
+ },
+ [0xA248]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA248,
+ },
+ [0xA249]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA249,
+ },
+ [0xA24A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA24A,
+ },
+ [0xA24B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA24B,
+ },
+ [0xA24C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA24C,
+ },
+ [0xA24D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA24D,
+ },
+ [0xA24E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA24E,
+ },
+ [0xA24F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA24F,
+ },
+ [0xA250]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA250,
+ },
+ [0xA251]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA251,
+ },
+ [0xA252]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA252,
+ },
+ [0xA253]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA253,
+ },
+ [0xA254]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA254,
+ },
+ [0xA255]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA255,
+ },
+ [0xA256]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA256,
+ },
+ [0xA257]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA257,
+ },
+ [0xA258]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA258,
+ },
+ [0xA259]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA259,
+ },
+ [0xA25A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA25A,
+ },
+ [0xA25B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA25B,
+ },
+ [0xA25C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA25C,
+ },
+ [0xA25D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA25D,
+ },
+ [0xA25E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA25E,
+ },
+ [0xA25F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA25F,
+ },
+ [0xA260]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA260,
+ },
+ [0xA261]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA261,
+ },
+ [0xA262]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA262,
+ },
+ [0xA263]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA263,
+ },
+ [0xA264]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA264,
+ },
+ [0xA265]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA265,
+ },
+ [0xA266]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA266,
+ },
+ [0xA267]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA267,
+ },
+ [0xA268]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA268,
+ },
+ [0xA269]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA269,
+ },
+ [0xA26A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA26A,
+ },
+ [0xA26B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA26B,
+ },
+ [0xA26C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA26C,
+ },
+ [0xA26D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA26D,
+ },
+ [0xA26E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA26E,
+ },
+ [0xA26F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA26F,
+ },
+ [0xA270]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA270,
+ },
+ [0xA271]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA271,
+ },
+ [0xA272]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA272,
+ },
+ [0xA273]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA273,
+ },
+ [0xA274]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA274,
+ },
+ [0xA275]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA275,
+ },
+ [0xA276]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA276,
+ },
+ [0xA277]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA277,
+ },
+ [0xA278]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA278,
+ },
+ [0xA279]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA279,
+ },
+ [0xA27A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA27A,
+ },
+ [0xA27B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA27B,
+ },
+ [0xA27C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA27C,
+ },
+ [0xA27D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA27D,
+ },
+ [0xA27E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA27E,
+ },
+ [0xA27F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA27F,
+ },
+ [0xA280]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA280,
+ },
+ [0xA281]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA281,
+ },
+ [0xA282]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA282,
+ },
+ [0xA283]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA283,
+ },
+ [0xA284]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA284,
+ },
+ [0xA285]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA285,
+ },
+ [0xA286]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA286,
+ },
+ [0xA287]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA287,
+ },
+ [0xA288]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA288,
+ },
+ [0xA289]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA289,
+ },
+ [0xA28A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA28A,
+ },
+ [0xA28B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA28B,
+ },
+ [0xA28C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA28C,
+ },
+ [0xA28D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA28D,
+ },
+ [0xA28E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA28E,
+ },
+ [0xA28F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA28F,
+ },
+ [0xA290]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA290,
+ },
+ [0xA291]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA291,
+ },
+ [0xA292]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA292,
+ },
+ [0xA293]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA293,
+ },
+ [0xA294]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA294,
+ },
+ [0xA295]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA295,
+ },
+ [0xA296]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA296,
+ },
+ [0xA297]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA297,
+ },
+ [0xA298]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA298,
+ },
+ [0xA299]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA299,
+ },
+ [0xA29A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA29A,
+ },
+ [0xA29B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA29B,
+ },
+ [0xA29C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA29C,
+ },
+ [0xA29D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA29D,
+ },
+ [0xA29E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA29E,
+ },
+ [0xA29F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA29F,
+ },
+ [0xA2A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A0,
+ },
+ [0xA2A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A1,
+ },
+ [0xA2A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A2,
+ },
+ [0xA2A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A3,
+ },
+ [0xA2A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A4,
+ },
+ [0xA2A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A5,
+ },
+ [0xA2A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A6,
+ },
+ [0xA2A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A7,
+ },
+ [0xA2A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A8,
+ },
+ [0xA2A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A9,
+ },
+ [0xA2AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2AA,
+ },
+ [0xA2AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2AB,
+ },
+ [0xA2AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2AC,
+ },
+ [0xA2AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2AD,
+ },
+ [0xA2AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2AE,
+ },
+ [0xA2AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2AF,
+ },
+ [0xA2B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B0,
+ },
+ [0xA2B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B1,
+ },
+ [0xA2B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B2,
+ },
+ [0xA2B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B3,
+ },
+ [0xA2B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B4,
+ },
+ [0xA2B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B5,
+ },
+ [0xA2B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B6,
+ },
+ [0xA2B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B7,
+ },
+ [0xA2B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B8,
+ },
+ [0xA2B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B9,
+ },
+ [0xA2BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2BA,
+ },
+ [0xA2BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2BB,
+ },
+ [0xA2BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2BC,
+ },
+ [0xA2BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2BD,
+ },
+ [0xA2BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2BE,
+ },
+ [0xA2BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2BF,
+ },
+ [0xA2C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C0,
+ },
+ [0xA2C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C1,
+ },
+ [0xA2C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C2,
+ },
+ [0xA2C3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C3,
+ },
+ [0xA2C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C4,
+ },
+ [0xA2C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C5,
+ },
+ [0xA2C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C6,
+ },
+ [0xA2C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C7,
+ },
+ [0xA2C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C8,
+ },
+ [0xA2C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C9,
+ },
+ [0xA2CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2CA,
+ },
+ [0xA2CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2CB,
+ },
+ [0xA2CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2CC,
+ },
+ [0xA2CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2CD,
+ },
+ [0xA2CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2CE,
+ },
+ [0xA2CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2CF,
+ },
+ [0xA2D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D0,
+ },
+ [0xA2D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D1,
+ },
+ [0xA2D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D2,
+ },
+ [0xA2D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D3,
+ },
+ [0xA2D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D4,
+ },
+ [0xA2D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D5,
+ },
+ [0xA2D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D6,
+ },
+ [0xA2D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D7,
+ },
+ [0xA2D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D8,
+ },
+ [0xA2D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D9,
+ },
+ [0xA2DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2DA,
+ },
+ [0xA2DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2DB,
+ },
+ [0xA2DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2DC,
+ },
+ [0xA2DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2DD,
+ },
+ [0xA2DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2DE,
+ },
+ [0xA2DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2DF,
+ },
+ [0xA2E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E0,
+ },
+ [0xA2E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E1,
+ },
+ [0xA2E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E2,
+ },
+ [0xA2E3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E3,
+ },
+ [0xA2E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E4,
+ },
+ [0xA2E5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E5,
+ },
+ [0xA2E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E6,
+ },
+ [0xA2E7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E7,
+ },
+ [0xA2E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E8,
+ },
+ [0xA2E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E9,
+ },
+ [0xA2EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2EA,
+ },
+ [0xA2EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2EB,
+ },
+ [0xA2EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2EC,
+ },
+ [0xA2ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2ED,
+ },
+ [0xA2EE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2EE,
+ },
+ [0xA2EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2EF,
+ },
+ [0xA2F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F0,
+ },
+ [0xA2F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F1,
+ },
+ [0xA2F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F2,
+ },
+ [0xA2F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F3,
+ },
+ [0xA2F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F4,
+ },
+ [0xA2F5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F5,
+ },
+ [0xA2F6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F6,
+ },
+ [0xA2F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F7,
+ },
+ [0xA2F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F8,
+ },
+ [0xA2F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F9,
+ },
+ [0xA2FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2FA,
+ },
+ [0xA2FB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2FB,
+ },
+ [0xA2FC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2FC,
+ },
+ [0xA2FD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2FD,
+ },
+ [0xA2FE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2FE,
+ },
+ [0xA2FF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2FF,
+ },
+ [0xA300]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA300,
+ },
+ [0xA301]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA301,
+ },
+ [0xA302]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA302,
+ },
+ [0xA303]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA303,
+ },
+ [0xA304]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA304,
+ },
+ [0xA305]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA305,
+ },
+ [0xA306]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA306,
+ },
+ [0xA307]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA307,
+ },
+ [0xA308]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA308,
+ },
+ [0xA309]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA309,
+ },
+ [0xA30A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA30A,
+ },
+ [0xA30B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA30B,
+ },
+ [0xA30C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA30C,
+ },
+ [0xA30D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA30D,
+ },
+ [0xA30E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA30E,
+ },
+ [0xA30F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA30F,
+ },
+ [0xA310]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA310,
+ },
+ [0xA311]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA311,
+ },
+ [0xA312]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA312,
+ },
+ [0xA313]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA313,
+ },
+ [0xA314]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA314,
+ },
+ [0xA315]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA315,
+ },
+ [0xA316]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA316,
+ },
+ [0xA317]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA317,
+ },
+ [0xA318]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA318,
+ },
+ [0xA319]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA319,
+ },
+ [0xA31A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA31A,
+ },
+ [0xA31B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA31B,
+ },
+ [0xA31C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA31C,
+ },
+ [0xA31D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA31D,
+ },
+ [0xA31E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA31E,
+ },
+ [0xA31F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA31F,
+ },
+ [0xA320]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA320,
+ },
+ [0xA321]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA321,
+ },
+ [0xA322]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA322,
+ },
+ [0xA323]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA323,
+ },
+ [0xA324]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA324,
+ },
+ [0xA325]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA325,
+ },
+ [0xA326]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA326,
+ },
+ [0xA327]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA327,
+ },
+ [0xA328]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA328,
+ },
+ [0xA329]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA329,
+ },
+ [0xA32A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA32A,
+ },
+ [0xA32B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA32B,
+ },
+ [0xA32C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA32C,
+ },
+ [0xA32D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA32D,
+ },
+ [0xA32E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA32E,
+ },
+ [0xA32F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA32F,
+ },
+ [0xA330]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA330,
+ },
+ [0xA331]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA331,
+ },
+ [0xA332]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA332,
+ },
+ [0xA333]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA333,
+ },
+ [0xA334]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA334,
+ },
+ [0xA335]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA335,
+ },
+ [0xA336]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA336,
+ },
+ [0xA337]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA337,
+ },
+ [0xA338]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA338,
+ },
+ [0xA339]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA339,
+ },
+ [0xA33A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA33A,
+ },
+ [0xA33B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA33B,
+ },
+ [0xA33C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA33C,
+ },
+ [0xA33D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA33D,
+ },
+ [0xA33E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA33E,
+ },
+ [0xA33F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA33F,
+ },
+ [0xA340]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA340,
+ },
+ [0xA341]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA341,
+ },
+ [0xA342]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA342,
+ },
+ [0xA343]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA343,
+ },
+ [0xA344]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA344,
+ },
+ [0xA345]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA345,
+ },
+ [0xA346]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA346,
+ },
+ [0xA347]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA347,
+ },
+ [0xA348]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA348,
+ },
+ [0xA349]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA349,
+ },
+ [0xA34A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA34A,
+ },
+ [0xA34B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA34B,
+ },
+ [0xA34C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA34C,
+ },
+ [0xA34D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA34D,
+ },
+ [0xA34E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA34E,
+ },
+ [0xA34F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA34F,
+ },
+ [0xA350]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA350,
+ },
+ [0xA351]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA351,
+ },
+ [0xA352]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA352,
+ },
+ [0xA353]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA353,
+ },
+ [0xA354]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA354,
+ },
+ [0xA355]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA355,
+ },
+ [0xA356]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA356,
+ },
+ [0xA357]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA357,
+ },
+ [0xA358]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA358,
+ },
+ [0xA359]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA359,
+ },
+ [0xA35A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA35A,
+ },
+ [0xA35B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA35B,
+ },
+ [0xA35C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA35C,
+ },
+ [0xA35D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA35D,
+ },
+ [0xA35E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA35E,
+ },
+ [0xA35F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA35F,
+ },
+ [0xA360]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA360,
+ },
+ [0xA361]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA361,
+ },
+ [0xA362]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA362,
+ },
+ [0xA363]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA363,
+ },
+ [0xA364]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA364,
+ },
+ [0xA365]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA365,
+ },
+ [0xA366]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA366,
+ },
+ [0xA367]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA367,
+ },
+ [0xA368]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA368,
+ },
+ [0xA369]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA369,
+ },
+ [0xA36A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA36A,
+ },
+ [0xA36B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA36B,
+ },
+ [0xA36C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA36C,
+ },
+ [0xA36D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA36D,
+ },
+ [0xA36E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA36E,
+ },
+ [0xA36F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA36F,
+ },
+ [0xA370]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA370,
+ },
+ [0xA371]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA371,
+ },
+ [0xA372]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA372,
+ },
+ [0xA373]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA373,
+ },
+ [0xA374]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA374,
+ },
+ [0xA375]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA375,
+ },
+ [0xA376]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA376,
+ },
+ [0xA377]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA377,
+ },
+ [0xA378]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA378,
+ },
+ [0xA379]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA379,
+ },
+ [0xA37A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA37A,
+ },
+ [0xA37B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA37B,
+ },
+ [0xA37C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA37C,
+ },
+ [0xA37D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA37D,
+ },
+ [0xA37E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA37E,
+ },
+ [0xA37F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA37F,
+ },
+ [0xA380]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA380,
+ },
+ [0xA381]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA381,
+ },
+ [0xA382]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA382,
+ },
+ [0xA383]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA383,
+ },
+ [0xA384]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA384,
+ },
+ [0xA385]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA385,
+ },
+ [0xA386]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA386,
+ },
+ [0xA387]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA387,
+ },
+ [0xA388]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA388,
+ },
+ [0xA389]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA389,
+ },
+ [0xA38A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA38A,
+ },
+ [0xA38B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA38B,
+ },
+ [0xA38C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA38C,
+ },
+ [0xA38D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA38D,
+ },
+ [0xA38E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA38E,
+ },
+ [0xA38F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA38F,
+ },
+ [0xA390]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA390,
+ },
+ [0xA391]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA391,
+ },
+ [0xA392]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA392,
+ },
+ [0xA393]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA393,
+ },
+ [0xA394]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA394,
+ },
+ [0xA395]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA395,
+ },
+ [0xA396]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA396,
+ },
+ [0xA397]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA397,
+ },
+ [0xA398]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA398,
+ },
+ [0xA399]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA399,
+ },
+ [0xA39A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA39A,
+ },
+ [0xA39B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA39B,
+ },
+ [0xA39C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA39C,
+ },
+ [0xA39D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA39D,
+ },
+ [0xA39E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA39E,
+ },
+ [0xA39F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA39F,
+ },
+ [0xA3A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A0,
+ },
+ [0xA3A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A1,
+ },
+ [0xA3A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A2,
+ },
+ [0xA3A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A3,
+ },
+ [0xA3A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A4,
+ },
+ [0xA3A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A5,
+ },
+ [0xA3A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A6,
+ },
+ [0xA3A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A7,
+ },
+ [0xA3A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A8,
+ },
+ [0xA3A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A9,
+ },
+ [0xA3AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3AA,
+ },
+ [0xA3AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3AB,
+ },
+ [0xA3AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3AC,
+ },
+ [0xA3AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3AD,
+ },
+ [0xA3AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3AE,
+ },
+ [0xA3AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3AF,
+ },
+ [0xA3B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B0,
+ },
+ [0xA3B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B1,
+ },
+ [0xA3B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B2,
+ },
+ [0xA3B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B3,
+ },
+ [0xA3B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B4,
+ },
+ [0xA3B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B5,
+ },
+ [0xA3B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B6,
+ },
+ [0xA3B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B7,
+ },
+ [0xA3B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B8,
+ },
+ [0xA3B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B9,
+ },
+ [0xA3BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3BA,
+ },
+ [0xA3BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3BB,
+ },
+ [0xA3BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3BC,
+ },
+ [0xA3BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3BD,
+ },
+ [0xA3BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3BE,
+ },
+ [0xA3BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3BF,
+ },
+ [0xA3C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C0,
+ },
+ [0xA3C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C1,
+ },
+ [0xA3C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C2,
+ },
+ [0xA3C3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C3,
+ },
+ [0xA3C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C4,
+ },
+ [0xA3C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C5,
+ },
+ [0xA3C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C6,
+ },
+ [0xA3C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C7,
+ },
+ [0xA3C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C8,
+ },
+ [0xA3C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C9,
+ },
+ [0xA3CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3CA,
+ },
+ [0xA3CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3CB,
+ },
+ [0xA3CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3CC,
+ },
+ [0xA3CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3CD,
+ },
+ [0xA3CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3CE,
+ },
+ [0xA3CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3CF,
+ },
+ [0xA3D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D0,
+ },
+ [0xA3D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D1,
+ },
+ [0xA3D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D2,
+ },
+ [0xA3D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D3,
+ },
+ [0xA3D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D4,
+ },
+ [0xA3D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D5,
+ },
+ [0xA3D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D6,
+ },
+ [0xA3D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D7,
+ },
+ [0xA3D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D8,
+ },
+ [0xA3D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D9,
+ },
+ [0xA3DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3DA,
+ },
+ [0xA3DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3DB,
+ },
+ [0xA3DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3DC,
+ },
+ [0xA3DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3DD,
+ },
+ [0xA3DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3DE,
+ },
+ [0xA3DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3DF,
+ },
+ [0xA3E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E0,
+ },
+ [0xA3E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E1,
+ },
+ [0xA3E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E2,
+ },
+ [0xA3E3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E3,
+ },
+ [0xA3E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E4,
+ },
+ [0xA3E5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E5,
+ },
+ [0xA3E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E6,
+ },
+ [0xA3E7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E7,
+ },
+ [0xA3E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E8,
+ },
+ [0xA3E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E9,
+ },
+ [0xA3EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3EA,
+ },
+ [0xA3EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3EB,
+ },
+ [0xA3EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3EC,
+ },
+ [0xA3ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3ED,
+ },
+ [0xA3EE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3EE,
+ },
+ [0xA3EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3EF,
+ },
+ [0xA3F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F0,
+ },
+ [0xA3F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F1,
+ },
+ [0xA3F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F2,
+ },
+ [0xA3F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F3,
+ },
+ [0xA3F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F4,
+ },
+ [0xA3F5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F5,
+ },
+ [0xA3F6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F6,
+ },
+ [0xA3F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F7,
+ },
+ [0xA3F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F8,
+ },
+ [0xA3F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F9,
+ },
+ [0xA3FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3FA,
+ },
+ [0xA3FB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3FB,
+ },
+ [0xA3FC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3FC,
+ },
+ [0xA3FD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3FD,
+ },
+ [0xA3FE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3FE,
+ },
+ [0xA3FF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3FF,
+ },
+ [0xA400]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA400,
+ },
+ [0xA401]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA401,
+ },
+ [0xA402]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA402,
+ },
+ [0xA403]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA403,
+ },
+ [0xA404]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA404,
+ },
+ [0xA405]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA405,
+ },
+ [0xA406]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA406,
+ },
+ [0xA407]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA407,
+ },
+ [0xA408]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA408,
+ },
+ [0xA409]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA409,
+ },
+ [0xA40A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA40A,
+ },
+ [0xA40B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA40B,
+ },
+ [0xA40C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA40C,
+ },
+ [0xA40D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA40D,
+ },
+ [0xA40E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA40E,
+ },
+ [0xA40F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA40F,
+ },
+ [0xA410]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA410,
+ },
+ [0xA411]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA411,
+ },
+ [0xA412]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA412,
+ },
+ [0xA413]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA413,
+ },
+ [0xA414]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA414,
+ },
+ [0xA415]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA415,
+ },
+ [0xA416]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA416,
+ },
+ [0xA417]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA417,
+ },
+ [0xA418]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA418,
+ },
+ [0xA419]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA419,
+ },
+ [0xA41A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA41A,
+ },
+ [0xA41B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA41B,
+ },
+ [0xA41C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA41C,
+ },
+ [0xA41D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA41D,
+ },
+ [0xA41E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA41E,
+ },
+ [0xA41F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA41F,
+ },
+ [0xA420]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA420,
+ },
+ [0xA421]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA421,
+ },
+ [0xA422]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA422,
+ },
+ [0xA423]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA423,
+ },
+ [0xA424]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA424,
+ },
+ [0xA425]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA425,
+ },
+ [0xA426]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA426,
+ },
+ [0xA427]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA427,
+ },
+ [0xA428]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA428,
+ },
+ [0xA429]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA429,
+ },
+ [0xA42A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA42A,
+ },
+ [0xA42B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA42B,
+ },
+ [0xA42C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA42C,
+ },
+ [0xA42D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA42D,
+ },
+ [0xA42E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA42E,
+ },
+ [0xA42F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA42F,
+ },
+ [0xA430]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA430,
+ },
+ [0xA431]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA431,
+ },
+ [0xA432]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA432,
+ },
+ [0xA433]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA433,
+ },
+ [0xA434]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA434,
+ },
+ [0xA435]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA435,
+ },
+ [0xA436]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA436,
+ },
+ [0xA437]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA437,
+ },
+ [0xA438]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA438,
+ },
+ [0xA439]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA439,
+ },
+ [0xA43A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA43A,
+ },
+ [0xA43B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA43B,
+ },
+ [0xA43C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA43C,
+ },
+ [0xA43D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA43D,
+ },
+ [0xA43E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA43E,
+ },
+ [0xA43F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA43F,
+ },
+ [0xA440]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA440,
+ },
+ [0xA441]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA441,
+ },
+ [0xA442]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA442,
+ },
+ [0xA443]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA443,
+ },
+ [0xA444]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA444,
+ },
+ [0xA445]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA445,
+ },
+ [0xA446]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA446,
+ },
+ [0xA447]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA447,
+ },
+ [0xA448]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA448,
+ },
+ [0xA449]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA449,
+ },
+ [0xA44A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA44A,
+ },
+ [0xA44B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA44B,
+ },
+ [0xA44C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA44C,
+ },
+ [0xA44D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA44D,
+ },
+ [0xA44E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA44E,
+ },
+ [0xA44F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA44F,
+ },
+ [0xA450]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA450,
+ },
+ [0xA451]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA451,
+ },
+ [0xA452]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA452,
+ },
+ [0xA453]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA453,
+ },
+ [0xA454]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA454,
+ },
+ [0xA455]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA455,
+ },
+ [0xA456]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA456,
+ },
+ [0xA457]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA457,
+ },
+ [0xA458]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA458,
+ },
+ [0xA459]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA459,
+ },
+ [0xA45A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA45A,
+ },
+ [0xA45B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA45B,
+ },
+ [0xA45C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA45C,
+ },
+ [0xA45D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA45D,
+ },
+ [0xA45E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA45E,
+ },
+ [0xA45F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA45F,
+ },
+ [0xA460]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA460,
+ },
+ [0xA461]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA461,
+ },
+ [0xA462]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA462,
+ },
+ [0xA463]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA463,
+ },
+ [0xA464]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA464,
+ },
+ [0xA465]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA465,
+ },
+ [0xA466]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA466,
+ },
+ [0xA467]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA467,
+ },
+ [0xA468]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA468,
+ },
+ [0xA469]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA469,
+ },
+ [0xA46A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA46A,
+ },
+ [0xA46B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA46B,
+ },
+ [0xA46C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA46C,
+ },
+ [0xA46D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA46D,
+ },
+ [0xA46E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA46E,
+ },
+ [0xA46F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA46F,
+ },
+ [0xA470]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA470,
+ },
+ [0xA471]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA471,
+ },
+ [0xA472]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA472,
+ },
+ [0xA473]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA473,
+ },
+ [0xA474]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA474,
+ },
+ [0xA475]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA475,
+ },
+ [0xA476]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA476,
+ },
+ [0xA477]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA477,
+ },
+ [0xA478]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA478,
+ },
+ [0xA479]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA479,
+ },
+ [0xA47A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA47A,
+ },
+ [0xA47B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA47B,
+ },
+ [0xA47C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA47C,
+ },
+ [0xA47D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA47D,
+ },
+ [0xA47E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA47E,
+ },
+ [0xA47F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA47F,
+ },
+ [0xA480]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA480,
+ },
+ [0xA481]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA481,
+ },
+ [0xA482]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA482,
+ },
+ [0xA483]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA483,
+ },
+ [0xA484]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA484,
+ },
+ [0xA485]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA485,
+ },
+ [0xA486]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA486,
+ },
+ [0xA487]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA487,
+ },
+ [0xA488]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA488,
+ },
+ [0xA489]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA489,
+ },
+ [0xA48A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA48A,
+ },
+ [0xA48B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA48B,
+ },
+ [0xA48C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA48C,
+ },
+ [0xA490]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA490,
+ },
+ [0xA491]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA491,
+ },
+ [0xA492]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA492,
+ },
+ [0xA493]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA493,
+ },
+ [0xA494]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA494,
+ },
+ [0xA495]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA495,
+ },
+ [0xA496]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA496,
+ },
+ [0xA497]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA497,
+ },
+ [0xA498]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA498,
+ },
+ [0xA499]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA499,
+ },
+ [0xA49A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA49A,
+ },
+ [0xA49B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA49B,
+ },
+ [0xA49C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA49C,
+ },
+ [0xA49D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA49D,
+ },
+ [0xA49E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA49E,
+ },
+ [0xA49F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA49F,
+ },
+ [0xA4A0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A0,
+ },
+ [0xA4A1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A1,
+ },
+ [0xA4A2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A2,
+ },
+ [0xA4A3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A3,
+ },
+ [0xA4A4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A4,
+ },
+ [0xA4A5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A5,
+ },
+ [0xA4A6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A6,
+ },
+ [0xA4A7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A7,
+ },
+ [0xA4A8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A8,
+ },
+ [0xA4A9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A9,
+ },
+ [0xA4AA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4AA,
+ },
+ [0xA4AB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4AB,
+ },
+ [0xA4AC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4AC,
+ },
+ [0xA4AD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4AD,
+ },
+ [0xA4AE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4AE,
+ },
+ [0xA4AF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4AF,
+ },
+ [0xA4B0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B0,
+ },
+ [0xA4B1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B1,
+ },
+ [0xA4B2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B2,
+ },
+ [0xA4B3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B3,
+ },
+ [0xA4B4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B4,
+ },
+ [0xA4B5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B5,
+ },
+ [0xA4B6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B6,
+ },
+ [0xA4B7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B7,
+ },
+ [0xA4B8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B8,
+ },
+ [0xA4B9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B9,
+ },
+ [0xA4BA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4BA,
+ },
+ [0xA4BB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4BB,
+ },
+ [0xA4BC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4BC,
+ },
+ [0xA4BD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4BD,
+ },
+ [0xA4BE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4BE,
+ },
+ [0xA4BF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4BF,
+ },
+ [0xA4C0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C0,
+ },
+ [0xA4C1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C1,
+ },
+ [0xA4C2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C2,
+ },
+ [0xA4C3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C3,
+ },
+ [0xA4C4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C4,
+ },
+ [0xA4C5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C5,
+ },
+ [0xA4C6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C6,
+ },
+ [0xA4D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D0,
+ },
+ [0xA4D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D1,
+ },
+ [0xA4D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D2,
+ },
+ [0xA4D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D3,
+ },
+ [0xA4D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D4,
+ },
+ [0xA4D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D5,
+ },
+ [0xA4D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D6,
+ },
+ [0xA4D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D7,
+ },
+ [0xA4D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D8,
+ },
+ [0xA4D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D9,
+ },
+ [0xA4DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4DA,
+ },
+ [0xA4DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4DB,
+ },
+ [0xA4DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4DC,
+ },
+ [0xA4DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4DD,
+ },
+ [0xA4DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4DE,
+ },
+ [0xA4DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4DF,
+ },
+ [0xA4E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E0,
+ },
+ [0xA4E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E1,
+ },
+ [0xA4E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E2,
+ },
+ [0xA4E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E3,
+ },
+ [0xA4E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E4,
+ },
+ [0xA4E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E5,
+ },
+ [0xA4E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E6,
+ },
+ [0xA4E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E7,
+ },
+ [0xA4E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E8,
+ },
+ [0xA4E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E9,
+ },
+ [0xA4EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4EA,
+ },
+ [0xA4EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4EB,
+ },
+ [0xA4EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4EC,
+ },
+ [0xA4ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4ED,
+ },
+ [0xA4EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4EE,
+ },
+ [0xA4EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4EF,
+ },
+ [0xA4F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F0,
+ },
+ [0xA4F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F1,
+ },
+ [0xA4F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F2,
+ },
+ [0xA4F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F3,
+ },
+ [0xA4F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F4,
+ },
+ [0xA4F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F5,
+ },
+ [0xA4F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F6,
+ },
+ [0xA4F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F7,
+ },
+ [0xA4F8]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F8,
+ },
+ [0xA4F9]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F9,
+ },
+ [0xA4FA]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4FA,
+ },
+ [0xA4FB]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4FB,
+ },
+ [0xA4FC]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4FC,
+ },
+ [0xA4FD]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4FD,
+ },
+ [0xA4FE]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA4FE,
+ },
+ [0xA4FF]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA4FF,
+ },
+ [0xA500]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA500,
+ },
+ [0xA501]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA501,
+ },
+ [0xA502]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA502,
+ },
+ [0xA503]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA503,
+ },
+ [0xA504]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA504,
+ },
+ [0xA505]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA505,
+ },
+ [0xA506]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA506,
+ },
+ [0xA507]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA507,
+ },
+ [0xA508]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA508,
+ },
+ [0xA509]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA509,
+ },
+ [0xA50A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA50A,
+ },
+ [0xA50B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA50B,
+ },
+ [0xA50C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA50C,
+ },
+ [0xA50D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA50D,
+ },
+ [0xA50E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA50E,
+ },
+ [0xA50F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA50F,
+ },
+ [0xA510]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA510,
+ },
+ [0xA511]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA511,
+ },
+ [0xA512]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA512,
+ },
+ [0xA513]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA513,
+ },
+ [0xA514]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA514,
+ },
+ [0xA515]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA515,
+ },
+ [0xA516]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA516,
+ },
+ [0xA517]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA517,
+ },
+ [0xA518]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA518,
+ },
+ [0xA519]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA519,
+ },
+ [0xA51A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA51A,
+ },
+ [0xA51B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA51B,
+ },
+ [0xA51C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA51C,
+ },
+ [0xA51D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA51D,
+ },
+ [0xA51E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA51E,
+ },
+ [0xA51F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA51F,
+ },
+ [0xA520]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA520,
+ },
+ [0xA521]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA521,
+ },
+ [0xA522]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA522,
+ },
+ [0xA523]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA523,
+ },
+ [0xA524]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA524,
+ },
+ [0xA525]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA525,
+ },
+ [0xA526]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA526,
+ },
+ [0xA527]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA527,
+ },
+ [0xA528]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA528,
+ },
+ [0xA529]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA529,
+ },
+ [0xA52A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA52A,
+ },
+ [0xA52B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA52B,
+ },
+ [0xA52C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA52C,
+ },
+ [0xA52D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA52D,
+ },
+ [0xA52E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA52E,
+ },
+ [0xA52F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA52F,
+ },
+ [0xA530]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA530,
+ },
+ [0xA531]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA531,
+ },
+ [0xA532]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA532,
+ },
+ [0xA533]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA533,
+ },
+ [0xA534]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA534,
+ },
+ [0xA535]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA535,
+ },
+ [0xA536]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA536,
+ },
+ [0xA537]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA537,
+ },
+ [0xA538]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA538,
+ },
+ [0xA539]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA539,
+ },
+ [0xA53A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA53A,
+ },
+ [0xA53B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA53B,
+ },
+ [0xA53C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA53C,
+ },
+ [0xA53D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA53D,
+ },
+ [0xA53E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA53E,
+ },
+ [0xA53F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA53F,
+ },
+ [0xA540]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA540,
+ },
+ [0xA541]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA541,
+ },
+ [0xA542]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA542,
+ },
+ [0xA543]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA543,
+ },
+ [0xA544]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA544,
+ },
+ [0xA545]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA545,
+ },
+ [0xA546]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA546,
+ },
+ [0xA547]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA547,
+ },
+ [0xA548]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA548,
+ },
+ [0xA549]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA549,
+ },
+ [0xA54A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA54A,
+ },
+ [0xA54B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA54B,
+ },
+ [0xA54C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA54C,
+ },
+ [0xA54D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA54D,
+ },
+ [0xA54E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA54E,
+ },
+ [0xA54F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA54F,
+ },
+ [0xA550]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA550,
+ },
+ [0xA551]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA551,
+ },
+ [0xA552]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA552,
+ },
+ [0xA553]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA553,
+ },
+ [0xA554]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA554,
+ },
+ [0xA555]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA555,
+ },
+ [0xA556]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA556,
+ },
+ [0xA557]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA557,
+ },
+ [0xA558]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA558,
+ },
+ [0xA559]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA559,
+ },
+ [0xA55A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA55A,
+ },
+ [0xA55B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA55B,
+ },
+ [0xA55C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA55C,
+ },
+ [0xA55D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA55D,
+ },
+ [0xA55E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA55E,
+ },
+ [0xA55F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA55F,
+ },
+ [0xA560]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA560,
+ },
+ [0xA561]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA561,
+ },
+ [0xA562]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA562,
+ },
+ [0xA563]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA563,
+ },
+ [0xA564]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA564,
+ },
+ [0xA565]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA565,
+ },
+ [0xA566]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA566,
+ },
+ [0xA567]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA567,
+ },
+ [0xA568]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA568,
+ },
+ [0xA569]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA569,
+ },
+ [0xA56A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA56A,
+ },
+ [0xA56B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA56B,
+ },
+ [0xA56C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA56C,
+ },
+ [0xA56D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA56D,
+ },
+ [0xA56E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA56E,
+ },
+ [0xA56F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA56F,
+ },
+ [0xA570]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA570,
+ },
+ [0xA571]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA571,
+ },
+ [0xA572]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA572,
+ },
+ [0xA573]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA573,
+ },
+ [0xA574]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA574,
+ },
+ [0xA575]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA575,
+ },
+ [0xA576]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA576,
+ },
+ [0xA577]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA577,
+ },
+ [0xA578]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA578,
+ },
+ [0xA579]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA579,
+ },
+ [0xA57A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA57A,
+ },
+ [0xA57B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA57B,
+ },
+ [0xA57C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA57C,
+ },
+ [0xA57D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA57D,
+ },
+ [0xA57E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA57E,
+ },
+ [0xA57F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA57F,
+ },
+ [0xA580]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA580,
+ },
+ [0xA581]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA581,
+ },
+ [0xA582]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA582,
+ },
+ [0xA583]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA583,
+ },
+ [0xA584]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA584,
+ },
+ [0xA585]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA585,
+ },
+ [0xA586]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA586,
+ },
+ [0xA587]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA587,
+ },
+ [0xA588]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA588,
+ },
+ [0xA589]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA589,
+ },
+ [0xA58A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA58A,
+ },
+ [0xA58B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA58B,
+ },
+ [0xA58C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA58C,
+ },
+ [0xA58D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA58D,
+ },
+ [0xA58E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA58E,
+ },
+ [0xA58F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA58F,
+ },
+ [0xA590]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA590,
+ },
+ [0xA591]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA591,
+ },
+ [0xA592]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA592,
+ },
+ [0xA593]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA593,
+ },
+ [0xA594]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA594,
+ },
+ [0xA595]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA595,
+ },
+ [0xA596]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA596,
+ },
+ [0xA597]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA597,
+ },
+ [0xA598]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA598,
+ },
+ [0xA599]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA599,
+ },
+ [0xA59A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA59A,
+ },
+ [0xA59B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA59B,
+ },
+ [0xA59C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA59C,
+ },
+ [0xA59D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA59D,
+ },
+ [0xA59E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA59E,
+ },
+ [0xA59F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA59F,
+ },
+ [0xA5A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A0,
+ },
+ [0xA5A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A1,
+ },
+ [0xA5A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A2,
+ },
+ [0xA5A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A3,
+ },
+ [0xA5A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A4,
+ },
+ [0xA5A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A5,
+ },
+ [0xA5A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A6,
+ },
+ [0xA5A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A7,
+ },
+ [0xA5A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A8,
+ },
+ [0xA5A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A9,
+ },
+ [0xA5AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5AA,
+ },
+ [0xA5AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5AB,
+ },
+ [0xA5AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5AC,
+ },
+ [0xA5AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5AD,
+ },
+ [0xA5AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5AE,
+ },
+ [0xA5AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5AF,
+ },
+ [0xA5B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B0,
+ },
+ [0xA5B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B1,
+ },
+ [0xA5B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B2,
+ },
+ [0xA5B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B3,
+ },
+ [0xA5B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B4,
+ },
+ [0xA5B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B5,
+ },
+ [0xA5B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B6,
+ },
+ [0xA5B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B7,
+ },
+ [0xA5B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B8,
+ },
+ [0xA5B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B9,
+ },
+ [0xA5BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5BA,
+ },
+ [0xA5BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5BB,
+ },
+ [0xA5BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5BC,
+ },
+ [0xA5BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5BD,
+ },
+ [0xA5BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5BE,
+ },
+ [0xA5BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5BF,
+ },
+ [0xA5C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C0,
+ },
+ [0xA5C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C1,
+ },
+ [0xA5C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C2,
+ },
+ [0xA5C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C3,
+ },
+ [0xA5C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C4,
+ },
+ [0xA5C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C5,
+ },
+ [0xA5C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C6,
+ },
+ [0xA5C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C7,
+ },
+ [0xA5C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C8,
+ },
+ [0xA5C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C9,
+ },
+ [0xA5CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5CA,
+ },
+ [0xA5CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5CB,
+ },
+ [0xA5CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5CC,
+ },
+ [0xA5CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5CD,
+ },
+ [0xA5CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5CE,
+ },
+ [0xA5CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5CF,
+ },
+ [0xA5D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D0,
+ },
+ [0xA5D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D1,
+ },
+ [0xA5D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D2,
+ },
+ [0xA5D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D3,
+ },
+ [0xA5D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D4,
+ },
+ [0xA5D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D5,
+ },
+ [0xA5D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D6,
+ },
+ [0xA5D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D7,
+ },
+ [0xA5D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D8,
+ },
+ [0xA5D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D9,
+ },
+ [0xA5DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5DA,
+ },
+ [0xA5DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5DB,
+ },
+ [0xA5DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5DC,
+ },
+ [0xA5DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5DD,
+ },
+ [0xA5DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5DE,
+ },
+ [0xA5DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5DF,
+ },
+ [0xA5E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E0,
+ },
+ [0xA5E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E1,
+ },
+ [0xA5E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E2,
+ },
+ [0xA5E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E3,
+ },
+ [0xA5E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E4,
+ },
+ [0xA5E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E5,
+ },
+ [0xA5E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E6,
+ },
+ [0xA5E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E7,
+ },
+ [0xA5E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E8,
+ },
+ [0xA5E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E9,
+ },
+ [0xA5EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5EA,
+ },
+ [0xA5EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5EB,
+ },
+ [0xA5EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5EC,
+ },
+ [0xA5ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5ED,
+ },
+ [0xA5EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5EE,
+ },
+ [0xA5EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5EF,
+ },
+ [0xA5F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F0,
+ },
+ [0xA5F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F1,
+ },
+ [0xA5F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F2,
+ },
+ [0xA5F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F3,
+ },
+ [0xA5F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F4,
+ },
+ [0xA5F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F5,
+ },
+ [0xA5F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F6,
+ },
+ [0xA5F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F7,
+ },
+ [0xA5F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F8,
+ },
+ [0xA5F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F9,
+ },
+ [0xA5FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5FA,
+ },
+ [0xA5FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5FB,
+ },
+ [0xA5FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5FC,
+ },
+ [0xA5FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5FD,
+ },
+ [0xA5FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5FE,
+ },
+ [0xA5FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5FF,
+ },
+ [0xA600]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA600,
+ },
+ [0xA601]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA601,
+ },
+ [0xA602]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA602,
+ },
+ [0xA603]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA603,
+ },
+ [0xA604]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA604,
+ },
+ [0xA605]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA605,
+ },
+ [0xA606]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA606,
+ },
+ [0xA607]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA607,
+ },
+ [0xA608]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA608,
+ },
+ [0xA609]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA609,
+ },
+ [0xA60A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA60A,
+ },
+ [0xA60B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA60B,
+ },
+ [0xA60C]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA60C,
+ },
+ [0xA60D]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0xA60D,
+ },
+ [0xA60E]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0xA60E,
+ },
+ [0xA60F]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0xA60F,
+ },
+ [0xA610]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA610,
+ },
+ [0xA611]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA611,
+ },
+ [0xA612]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA612,
+ },
+ [0xA613]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA613,
+ },
+ [0xA614]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA614,
+ },
+ [0xA615]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA615,
+ },
+ [0xA616]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA616,
+ },
+ [0xA617]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA617,
+ },
+ [0xA618]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA618,
+ },
+ [0xA619]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA619,
+ },
+ [0xA61A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA61A,
+ },
+ [0xA61B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA61B,
+ },
+ [0xA61C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA61C,
+ },
+ [0xA61D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA61D,
+ },
+ [0xA61E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA61E,
+ },
+ [0xA61F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA61F,
+ },
+ [0xA620]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA620,
+ },
+ [0xA621]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA621,
+ },
+ [0xA622]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA622,
+ },
+ [0xA623]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA623,
+ },
+ [0xA624]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA624,
+ },
+ [0xA625]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA625,
+ },
+ [0xA626]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA626,
+ },
+ [0xA627]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA627,
+ },
+ [0xA628]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA628,
+ },
+ [0xA629]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA629,
+ },
+ [0xA62A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA62A,
+ },
+ [0xA62B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA62B,
+ },
+ [0xA640]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA640,
+ },
+ [0xA641]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA641,
+ },
+ [0xA642]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA642,
+ },
+ [0xA643]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA643,
+ },
+ [0xA644]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA644,
+ },
+ [0xA645]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA645,
+ },
+ [0xA646]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA646,
+ },
+ [0xA647]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA647,
+ },
+ [0xA648]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA648,
+ },
+ [0xA649]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA649,
+ },
+ [0xA64A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA64A,
+ },
+ [0xA64B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA64B,
+ },
+ [0xA64C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA64C,
+ },
+ [0xA64D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA64D,
+ },
+ [0xA64E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA64E,
+ },
+ [0xA64F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA64F,
+ },
+ [0xA650]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA650,
+ },
+ [0xA651]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA651,
+ },
+ [0xA652]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA652,
+ },
+ [0xA653]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA653,
+ },
+ [0xA654]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA654,
+ },
+ [0xA655]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA655,
+ },
+ [0xA656]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA656,
+ },
+ [0xA657]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA657,
+ },
+ [0xA658]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA658,
+ },
+ [0xA659]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA659,
+ },
+ [0xA65A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA65A,
+ },
+ [0xA65B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA65B,
+ },
+ [0xA65C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA65C,
+ },
+ [0xA65D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA65D,
+ },
+ [0xA65E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA65E,
+ },
+ [0xA65F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA65F,
+ },
+ [0xA660]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA660,
+ },
+ [0xA661]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA661,
+ },
+ [0xA662]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA662,
+ },
+ [0xA663]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA663,
+ },
+ [0xA664]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA664,
+ },
+ [0xA665]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA665,
+ },
+ [0xA666]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA666,
+ },
+ [0xA667]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA667,
+ },
+ [0xA668]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA668,
+ },
+ [0xA669]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA669,
+ },
+ [0xA66A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA66A,
+ },
+ [0xA66B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA66B,
+ },
+ [0xA66C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA66C,
+ },
+ [0xA66D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA66D,
+ },
+ [0xA66E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA66E,
+ },
+ [0xA66F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA66F,
+ },
+ [0xA670]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA670,
+ },
+ [0xA671]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA671,
+ },
+ [0xA672]={
+ category="me",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA672,
+ },
+ [0xA673]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA673,
+ },
+ [0xA674]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA674,
+ },
+ [0xA675]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA675,
+ },
+ [0xA676]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA676,
+ },
+ [0xA677]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA677,
+ },
+ [0xA678]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA678,
+ },
+ [0xA679]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA679,
+ },
+ [0xA67A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA67A,
+ },
+ [0xA67B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA67B,
+ },
+ [0xA67C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA67C,
+ },
+ [0xA67D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA67D,
+ },
+ [0xA67E]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA67E,
+ },
+ [0xA67F]={
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA67F,
+ },
+ [0xA680]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA680,
+ },
+ [0xA681]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA681,
+ },
+ [0xA682]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA682,
+ },
+ [0xA683]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA683,
+ },
+ [0xA684]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA684,
+ },
+ [0xA685]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA685,
+ },
+ [0xA686]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA686,
+ },
+ [0xA687]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA687,
+ },
+ [0xA688]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA688,
+ },
+ [0xA689]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA689,
+ },
+ [0xA68A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA68A,
+ },
+ [0xA68B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA68B,
+ },
+ [0xA68C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA68C,
+ },
+ [0xA68D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA68D,
+ },
+ [0xA68E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA68E,
+ },
+ [0xA68F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA68F,
+ },
+ [0xA690]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA690,
+ },
+ [0xA691]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA691,
+ },
+ [0xA692]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA692,
+ },
+ [0xA693]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA693,
+ },
+ [0xA694]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA694,
+ },
+ [0xA695]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA695,
+ },
+ [0xA696]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA696,
+ },
+ [0xA697]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA697,
+ },
+ [0xA698]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA698,
+ },
+ [0xA699]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA699,
+ },
+ [0xA69A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA69A,
+ },
+ [0xA69B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA69B,
+ },
+ [0xA69C]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x44A },
+ unicodeslot=0xA69C,
+ },
+ [0xA69D]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x44C },
+ unicodeslot=0xA69D,
+ },
+ [0xA69E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA69E,
+ },
+ [0xA69F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA69F,
+ },
+ [0xA6A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A0,
+ },
+ [0xA6A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A1,
+ },
+ [0xA6A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A2,
+ },
+ [0xA6A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A3,
+ },
+ [0xA6A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A4,
+ },
+ [0xA6A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A5,
+ },
+ [0xA6A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A6,
+ },
+ [0xA6A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A7,
+ },
+ [0xA6A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A8,
+ },
+ [0xA6A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A9,
+ },
+ [0xA6AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6AA,
+ },
+ [0xA6AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6AB,
+ },
+ [0xA6AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6AC,
+ },
+ [0xA6AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6AD,
+ },
+ [0xA6AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6AE,
+ },
+ [0xA6AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6AF,
+ },
+ [0xA6B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B0,
+ },
+ [0xA6B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B1,
+ },
+ [0xA6B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B2,
+ },
+ [0xA6B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B3,
+ },
+ [0xA6B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B4,
+ },
+ [0xA6B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B5,
+ },
+ [0xA6B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B6,
+ },
+ [0xA6B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B7,
+ },
+ [0xA6B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B8,
+ },
+ [0xA6B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B9,
+ },
+ [0xA6BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6BA,
+ },
+ [0xA6BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6BB,
+ },
+ [0xA6BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6BC,
+ },
+ [0xA6BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6BD,
+ },
+ [0xA6BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6BE,
+ },
+ [0xA6BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6BF,
+ },
+ [0xA6C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C0,
+ },
+ [0xA6C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C1,
+ },
+ [0xA6C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C2,
+ },
+ [0xA6C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C3,
+ },
+ [0xA6C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C4,
+ },
+ [0xA6C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C5,
+ },
+ [0xA6C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C6,
+ },
+ [0xA6C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C7,
+ },
+ [0xA6C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C8,
+ },
+ [0xA6C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C9,
+ },
+ [0xA6CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6CA,
+ },
+ [0xA6CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6CB,
+ },
+ [0xA6CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6CC,
+ },
+ [0xA6CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6CD,
+ },
+ [0xA6CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6CE,
+ },
+ [0xA6CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6CF,
+ },
+ [0xA6D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D0,
+ },
+ [0xA6D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D1,
+ },
+ [0xA6D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D2,
+ },
+ [0xA6D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D3,
+ },
+ [0xA6D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D4,
+ },
+ [0xA6D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D5,
+ },
+ [0xA6D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D6,
+ },
+ [0xA6D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D7,
+ },
+ [0xA6D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D8,
+ },
+ [0xA6D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D9,
+ },
+ [0xA6DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6DA,
+ },
+ [0xA6DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6DB,
+ },
+ [0xA6DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6DC,
+ },
+ [0xA6DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6DD,
+ },
+ [0xA6DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6DE,
+ },
+ [0xA6DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6DF,
+ },
+ [0xA6E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E0,
+ },
+ [0xA6E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E1,
+ },
+ [0xA6E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E2,
+ },
+ [0xA6E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E3,
+ },
+ [0xA6E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E4,
+ },
+ [0xA6E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E5,
+ },
+ [0xA6E6]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E6,
+ },
+ [0xA6E7]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E7,
+ },
+ [0xA6E8]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E8,
+ },
+ [0xA6E9]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E9,
+ },
+ [0xA6EA]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6EA,
+ },
+ [0xA6EB]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6EB,
+ },
+ [0xA6EC]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6EC,
+ },
+ [0xA6ED]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6ED,
+ },
+ [0xA6EE]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6EE,
+ },
+ [0xA6EF]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6EF,
+ },
+ [0xA6F0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA6F0,
+ },
+ [0xA6F1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA6F1,
+ },
+ [0xA6F2]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6F2,
+ },
+ [0xA6F3]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA6F3,
+ },
+ [0xA6F4]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA6F4,
+ },
+ [0xA6F5]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA6F5,
+ },
+ [0xA6F6]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA6F6,
+ },
+ [0xA6F7]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA6F7,
+ },
+ [0xA700]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA700,
+ },
+ [0xA701]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA701,
+ },
+ [0xA702]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA702,
+ },
+ [0xA703]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA703,
+ },
+ [0xA704]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA704,
+ },
+ [0xA705]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA705,
+ },
+ [0xA706]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA706,
+ },
+ [0xA707]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA707,
+ },
+ [0xA708]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA708,
+ },
+ [0xA709]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA709,
+ },
+ [0xA70A]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA70A,
+ },
+ [0xA70B]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA70B,
+ },
+ [0xA70C]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA70C,
+ },
+ [0xA70D]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA70D,
+ },
+ [0xA70E]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA70E,
+ },
+ [0xA70F]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA70F,
+ },
+ [0xA710]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA710,
+ },
+ [0xA711]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA711,
+ },
+ [0xA712]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA712,
+ },
+ [0xA713]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA713,
+ },
+ [0xA714]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA714,
+ },
+ [0xA715]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA715,
+ },
+ [0xA716]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA716,
+ },
+ [0xA717]={
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA717,
+ },
+ [0xA718]={
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA718,
+ },
+ [0xA719]={
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA719,
+ },
+ [0xA71A]={
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA71A,
+ },
+ [0xA71B]={
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA71B,
+ },
+ [0xA71C]={
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA71C,
+ },
+ [0xA71D]={
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA71D,
+ },
+ [0xA71E]={
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA71E,
+ },
+ [0xA71F]={
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA71F,
+ },
+ [0xA720]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA720,
+ },
+ [0xA721]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA721,
+ },
+ [0xA722]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA722,
+ },
+ [0xA723]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA723,
+ },
+ [0xA724]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA724,
+ },
+ [0xA725]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA725,
+ },
+ [0xA726]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA726,
+ },
+ [0xA727]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA727,
+ },
+ [0xA728]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA728,
+ },
+ [0xA729]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA729,
+ },
+ [0xA72A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA72A,
+ },
+ [0xA72B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA72B,
+ },
+ [0xA72C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA72C,
+ },
+ [0xA72D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA72D,
+ },
+ [0xA72E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA72E,
+ },
+ [0xA72F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA72F,
+ },
+ [0xA730]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA730,
+ },
+ [0xA731]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA731,
+ },
+ [0xA732]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA732,
+ },
+ [0xA733]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA733,
+ },
+ [0xA734]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA734,
+ },
+ [0xA735]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA735,
+ },
+ [0xA736]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA736,
+ },
+ [0xA737]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA737,
+ },
+ [0xA738]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA738,
+ },
+ [0xA739]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA739,
+ },
+ [0xA73A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA73A,
+ },
+ [0xA73B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA73B,
+ },
+ [0xA73C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA73C,
+ },
+ [0xA73D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA73D,
+ },
+ [0xA73E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA73E,
+ },
+ [0xA73F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA73F,
+ },
+ [0xA740]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA740,
+ },
+ [0xA741]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA741,
+ },
+ [0xA742]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA742,
+ },
+ [0xA743]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA743,
+ },
+ [0xA744]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA744,
+ },
+ [0xA745]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA745,
+ },
+ [0xA746]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA746,
+ },
+ [0xA747]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA747,
+ },
+ [0xA748]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA748,
+ },
+ [0xA749]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA749,
+ },
+ [0xA74A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA74A,
+ },
+ [0xA74B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA74B,
+ },
+ [0xA74C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA74C,
+ },
+ [0xA74D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA74D,
+ },
+ [0xA74E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA74E,
+ },
+ [0xA74F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA74F,
+ },
+ [0xA750]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA750,
+ },
+ [0xA751]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA751,
+ },
+ [0xA752]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA752,
+ },
+ [0xA753]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA753,
+ },
+ [0xA754]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA754,
+ },
+ [0xA755]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA755,
+ },
+ [0xA756]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA756,
+ },
+ [0xA757]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA757,
+ },
+ [0xA758]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA758,
+ },
+ [0xA759]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA759,
+ },
+ [0xA75A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA75A,
+ },
+ [0xA75B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA75B,
+ },
+ [0xA75C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA75C,
+ },
+ [0xA75D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA75D,
+ },
+ [0xA75E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA75E,
+ },
+ [0xA75F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA75F,
+ },
+ [0xA760]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA760,
+ },
+ [0xA761]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA761,
+ },
+ [0xA762]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA762,
+ },
+ [0xA763]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA763,
+ },
+ [0xA764]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA764,
+ },
+ [0xA765]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA765,
+ },
+ [0xA766]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA766,
+ },
+ [0xA767]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA767,
+ },
+ [0xA768]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA768,
+ },
+ [0xA769]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA769,
+ },
+ [0xA76A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76A,
+ },
+ [0xA76B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76B,
+ },
+ [0xA76C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76C,
+ },
+ [0xA76D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76D,
+ },
+ [0xA76E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76E,
+ },
+ [0xA76F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76F,
+ },
+ [0xA770]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0xA76F },
+ unicodeslot=0xA770,
+ },
+ [0xA771]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA771,
+ },
+ [0xA772]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA772,
+ },
+ [0xA773]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA773,
+ },
+ [0xA774]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA774,
+ },
+ [0xA775]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA775,
+ },
+ [0xA776]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA776,
+ },
+ [0xA777]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA777,
+ },
+ [0xA778]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA778,
+ },
+ [0xA779]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA779,
+ },
+ [0xA77A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA77A,
+ },
+ [0xA77B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA77B,
+ },
+ [0xA77C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA77C,
+ },
+ [0xA77D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA77D,
+ },
+ [0xA77E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA77E,
+ },
+ [0xA77F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA77F,
+ },
+ [0xA780]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA780,
+ },
+ [0xA781]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA781,
+ },
+ [0xA782]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA782,
+ },
+ [0xA783]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA783,
+ },
+ [0xA784]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA784,
+ },
+ [0xA785]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA785,
+ },
+ [0xA786]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA786,
+ },
+ [0xA787]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA787,
+ },
+ [0xA788]={
+ category="lm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA788,
+ },
+ [0xA789]={
+ category="sk",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA789,
+ },
+ [0xA78A]={
+ category="sk",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA78A,
+ },
+ [0xA78B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA78B,
+ },
+ [0xA78C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA78C,
+ },
+ [0xA78D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA78D,
+ },
+ [0xA78E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA78E,
+ },
+ [0xA78F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA78F,
+ },
+ [0xA790]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA790,
+ },
+ [0xA791]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA791,
+ },
+ [0xA792]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA792,
+ },
+ [0xA793]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA793,
+ },
+ [0xA794]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA794,
+ },
+ [0xA795]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA795,
+ },
+ [0xA796]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA796,
+ },
+ [0xA797]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA797,
+ },
+ [0xA798]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA798,
+ },
+ [0xA799]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA799,
+ },
+ [0xA79A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA79A,
+ },
+ [0xA79B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA79B,
+ },
+ [0xA79C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA79C,
+ },
+ [0xA79D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA79D,
+ },
+ [0xA79E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA79E,
+ },
+ [0xA79F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA79F,
+ },
+ [0xA7A0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A0,
+ },
+ [0xA7A1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A1,
+ },
+ [0xA7A2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A2,
+ },
+ [0xA7A3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A3,
+ },
+ [0xA7A4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A4,
+ },
+ [0xA7A5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A5,
+ },
+ [0xA7A6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A6,
+ },
+ [0xA7A7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A7,
+ },
+ [0xA7A8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A8,
+ },
+ [0xA7A9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A9,
+ },
+ [0xA7AA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7AA,
+ },
+ [0xA7AB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7AB,
+ },
+ [0xA7AC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7AC,
+ },
+ [0xA7AD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7AD,
+ },
+ [0xA7AE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7AE,
+ },
+ [0xA7AF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7AF,
+ },
+ [0xA7B0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7B0,
+ },
+ [0xA7B1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7B1,
+ },
+ [0xA7B2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7B2,
+ },
+ [0xA7B3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7B3,
+ },
+ [0xA7B4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7B4,
+ },
+ [0xA7B5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7B5,
+ },
+ [0xA7B6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7B6,
+ },
+ [0xA7B7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7B7,
+ },
+ [0xA7B8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7B8,
+ },
+ [0xA7B9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7B9,
+ },
+ [0xA7BA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7BA,
+ },
+ [0xA7BB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7BB,
+ },
+ [0xA7BC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7BC,
+ },
+ [0xA7BD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7BD,
+ },
+ [0xA7BE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7BE,
+ },
+ [0xA7BF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7BF,
+ },
+ [0xA7C2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7C2,
+ },
+ [0xA7C3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7C3,
+ },
+ [0xA7C4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7C4,
+ },
+ [0xA7C5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7C5,
+ },
+ [0xA7C6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7C6,
+ },
+ [0xA7F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7F7,
+ },
+ [0xA7F8]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x126 },
+ unicodeslot=0xA7F8,
+ },
+ [0xA7F9]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x153 },
+ unicodeslot=0xA7F9,
+ },
+ [0xA7FA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7FA,
+ },
+ [0xA7FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7FB,
+ },
+ [0xA7FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7FC,
+ },
+ [0xA7FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7FD,
+ },
+ [0xA7FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7FE,
+ },
+ [0xA7FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7FF,
+ },
+ [0xA800]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA800,
+ },
+ [0xA801]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA801,
+ },
+ [0xA802]={
+ category="mc",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA802,
+ },
+ [0xA803]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA803,
+ },
+ [0xA804]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA804,
+ },
+ [0xA805]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA805,
+ },
+ [0xA806]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA806,
+ },
+ [0xA807]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA807,
+ },
+ [0xA808]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA808,
+ },
+ [0xA809]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA809,
+ },
+ [0xA80A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA80A,
+ },
+ [0xA80B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA80B,
+ },
+ [0xA80C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA80C,
+ },
+ [0xA80D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA80D,
+ },
+ [0xA80E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA80E,
+ },
+ [0xA80F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA80F,
+ },
+ [0xA810]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA810,
+ },
+ [0xA811]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA811,
+ },
+ [0xA812]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA812,
+ },
+ [0xA813]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA813,
+ },
+ [0xA814]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA814,
+ },
+ [0xA815]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA815,
+ },
+ [0xA816]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA816,
+ },
+ [0xA817]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA817,
+ },
+ [0xA818]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA818,
+ },
+ [0xA819]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA819,
+ },
+ [0xA81A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA81A,
+ },
+ [0xA81B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA81B,
+ },
+ [0xA81C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA81C,
+ },
+ [0xA81D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA81D,
+ },
+ [0xA81E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA81E,
+ },
+ [0xA81F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA81F,
+ },
+ [0xA820]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA820,
+ },
+ [0xA821]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA821,
+ },
+ [0xA822]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA822,
+ },
+ [0xA823]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA823,
+ },
+ [0xA824]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA824,
+ },
+ [0xA825]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA825,
+ },
+ [0xA826]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA826,
+ },
+ [0xA827]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA827,
+ },
+ [0xA828]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA828,
+ },
+ [0xA829]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA829,
+ },
+ [0xA82A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA82A,
+ },
+ [0xA82B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA82B,
+ },
+ [0xA830]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA830,
+ },
+ [0xA831]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA831,
+ },
+ [0xA832]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA832,
+ },
+ [0xA833]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA833,
+ },
+ [0xA834]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA834,
+ },
+ [0xA835]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA835,
+ },
+ [0xA836]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA836,
+ },
+ [0xA837]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA837,
+ },
+ [0xA838]={
+ category="sc",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0xA838,
+ },
+ [0xA839]={
+ category="so",
+ direction="et",
+ linebreak="al",
+ unicodeslot=0xA839,
+ },
+ [0xA840]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA840,
+ },
+ [0xA841]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA841,
+ },
+ [0xA842]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA842,
+ },
+ [0xA843]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA843,
+ },
+ [0xA844]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA844,
+ },
+ [0xA845]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA845,
+ },
+ [0xA846]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA846,
+ },
+ [0xA847]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA847,
+ },
+ [0xA848]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA848,
+ },
+ [0xA849]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA849,
+ },
+ [0xA84A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA84A,
+ },
+ [0xA84B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA84B,
+ },
+ [0xA84C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA84C,
+ },
+ [0xA84D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA84D,
+ },
+ [0xA84E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA84E,
+ },
+ [0xA84F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA84F,
+ },
+ [0xA850]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA850,
+ },
+ [0xA851]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA851,
+ },
+ [0xA852]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA852,
+ },
+ [0xA853]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA853,
+ },
+ [0xA854]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA854,
+ },
+ [0xA855]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA855,
+ },
+ [0xA856]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA856,
+ },
+ [0xA857]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA857,
+ },
+ [0xA858]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA858,
+ },
+ [0xA859]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA859,
+ },
+ [0xA85A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA85A,
+ },
+ [0xA85B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA85B,
+ },
+ [0xA85C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA85C,
+ },
+ [0xA85D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA85D,
+ },
+ [0xA85E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA85E,
+ },
+ [0xA85F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA85F,
+ },
+ [0xA860]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA860,
+ },
+ [0xA861]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA861,
+ },
+ [0xA862]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA862,
+ },
+ [0xA863]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA863,
+ },
+ [0xA864]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA864,
+ },
+ [0xA865]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA865,
+ },
+ [0xA866]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA866,
+ },
+ [0xA867]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA867,
+ },
+ [0xA868]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA868,
+ },
+ [0xA869]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA869,
+ },
+ [0xA86A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA86A,
+ },
+ [0xA86B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA86B,
+ },
+ [0xA86C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA86C,
+ },
+ [0xA86D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA86D,
+ },
+ [0xA86E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA86E,
+ },
+ [0xA86F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA86F,
+ },
+ [0xA870]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA870,
+ },
+ [0xA871]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA871,
+ },
+ [0xA872]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA872,
+ },
+ [0xA873]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA873,
+ },
+ [0xA874]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0xA874,
+ },
+ [0xA875]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0xA875,
+ },
+ [0xA876]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0xA876,
+ },
+ [0xA877]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0xA877,
+ },
+ [0xA880]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA880,
+ },
+ [0xA881]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA881,
+ },
+ [0xA882]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA882,
+ },
+ [0xA883]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA883,
+ },
+ [0xA884]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA884,
+ },
+ [0xA885]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA885,
+ },
+ [0xA886]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA886,
+ },
+ [0xA887]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA887,
+ },
+ [0xA888]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA888,
+ },
+ [0xA889]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA889,
+ },
+ [0xA88A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA88A,
+ },
+ [0xA88B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA88B,
+ },
+ [0xA88C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA88C,
+ },
+ [0xA88D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA88D,
+ },
+ [0xA88E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA88E,
+ },
+ [0xA88F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA88F,
+ },
+ [0xA890]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA890,
+ },
+ [0xA891]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA891,
+ },
+ [0xA892]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA892,
+ },
+ [0xA893]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA893,
+ },
+ [0xA894]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA894,
+ },
+ [0xA895]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA895,
+ },
+ [0xA896]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA896,
+ },
+ [0xA897]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA897,
+ },
+ [0xA898]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA898,
+ },
+ [0xA899]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA899,
+ },
+ [0xA89A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA89A,
+ },
+ [0xA89B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA89B,
+ },
+ [0xA89C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA89C,
+ },
+ [0xA89D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA89D,
+ },
+ [0xA89E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA89E,
+ },
+ [0xA89F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA89F,
+ },
+ [0xA8A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A0,
+ },
+ [0xA8A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A1,
+ },
+ [0xA8A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A2,
+ },
+ [0xA8A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A3,
+ },
+ [0xA8A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A4,
+ },
+ [0xA8A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A5,
+ },
+ [0xA8A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A6,
+ },
+ [0xA8A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A7,
+ },
+ [0xA8A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A8,
+ },
+ [0xA8A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A9,
+ },
+ [0xA8AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8AA,
+ },
+ [0xA8AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8AB,
+ },
+ [0xA8AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8AC,
+ },
+ [0xA8AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8AD,
+ },
+ [0xA8AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8AE,
+ },
+ [0xA8AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8AF,
+ },
+ [0xA8B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8B0,
+ },
+ [0xA8B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8B1,
+ },
+ [0xA8B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8B2,
+ },
+ [0xA8B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8B3,
+ },
+ [0xA8B4]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8B4,
+ },
+ [0xA8B5]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8B5,
+ },
+ [0xA8B6]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8B6,
+ },
+ [0xA8B7]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8B7,
+ },
+ [0xA8B8]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8B8,
+ },
+ [0xA8B9]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8B9,
+ },
+ [0xA8BA]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8BA,
+ },
+ [0xA8BB]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8BB,
+ },
+ [0xA8BC]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8BC,
+ },
+ [0xA8BD]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8BD,
+ },
+ [0xA8BE]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8BE,
+ },
+ [0xA8BF]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8BF,
+ },
+ [0xA8C0]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8C0,
+ },
+ [0xA8C1]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8C1,
+ },
+ [0xA8C2]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8C2,
+ },
+ [0xA8C3]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8C3,
+ },
+ [0xA8C4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8C4,
+ },
+ [0xA8C5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8C5,
+ },
+ [0xA8CE]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA8CE,
+ },
+ [0xA8CF]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA8CF,
+ },
+ [0xA8D0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D0,
+ },
+ [0xA8D1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D1,
+ },
+ [0xA8D2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D2,
+ },
+ [0xA8D3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D3,
+ },
+ [0xA8D4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D4,
+ },
+ [0xA8D5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D5,
+ },
+ [0xA8D6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D6,
+ },
+ [0xA8D7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D7,
+ },
+ [0xA8D8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D8,
+ },
+ [0xA8D9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D9,
+ },
+ [0xA8E0]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8E0,
+ },
+ [0xA8E1]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8E1,
+ },
+ [0xA8E2]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8E2,
+ },
+ [0xA8E3]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8E3,
+ },
+ [0xA8E4]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8E4,
+ },
+ [0xA8E5]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8E5,
+ },
+ [0xA8E6]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8E6,
+ },
+ [0xA8E7]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8E7,
+ },
+ [0xA8E8]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8E8,
+ },
+ [0xA8E9]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8E9,
+ },
+ [0xA8EA]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8EA,
+ },
+ [0xA8EB]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8EB,
+ },
+ [0xA8EC]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8EC,
+ },
+ [0xA8ED]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8ED,
+ },
+ [0xA8EE]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8EE,
+ },
+ [0xA8EF]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8EF,
+ },
+ [0xA8F0]={
+ category="mn",
+ direction="nsm",
+ indic="o",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8F0,
+ },
+ [0xA8F1]={
+ category="mn",
+ direction="nsm",
+ indic="m",
+ indicmark="t",
+ linebreak="cm",
+ unicodeslot=0xA8F1,
+ },
+ [0xA8F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F2,
+ },
+ [0xA8F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F3,
+ },
+ [0xA8F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F4,
+ },
+ [0xA8F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F5,
+ },
+ [0xA8F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F6,
+ },
+ [0xA8F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F7,
+ },
+ [0xA8F8]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F8,
+ },
+ [0xA8F9]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F9,
+ },
+ [0xA8FA]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8FA,
+ },
+ [0xA8FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8FB,
+ },
+ [0xA8FC]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0xA8FC,
+ },
+ [0xA8FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8FD,
+ },
+ [0xA8FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8FE,
+ },
+ [0xA8FF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8FF,
+ },
+ [0xA900]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA900,
+ },
+ [0xA901]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA901,
+ },
+ [0xA902]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA902,
+ },
+ [0xA903]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA903,
+ },
+ [0xA904]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA904,
+ },
+ [0xA905]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA905,
+ },
+ [0xA906]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA906,
+ },
+ [0xA907]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA907,
+ },
+ [0xA908]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA908,
+ },
+ [0xA909]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA909,
+ },
+ [0xA90A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA90A,
+ },
+ [0xA90B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA90B,
+ },
+ [0xA90C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA90C,
+ },
+ [0xA90D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA90D,
+ },
+ [0xA90E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA90E,
+ },
+ [0xA90F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA90F,
+ },
+ [0xA910]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA910,
+ },
+ [0xA911]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA911,
+ },
+ [0xA912]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA912,
+ },
+ [0xA913]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA913,
+ },
+ [0xA914]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA914,
+ },
+ [0xA915]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA915,
+ },
+ [0xA916]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA916,
+ },
+ [0xA917]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA917,
+ },
+ [0xA918]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA918,
+ },
+ [0xA919]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA919,
+ },
+ [0xA91A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA91A,
+ },
+ [0xA91B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA91B,
+ },
+ [0xA91C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA91C,
+ },
+ [0xA91D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA91D,
+ },
+ [0xA91E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA91E,
+ },
+ [0xA91F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA91F,
+ },
+ [0xA920]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA920,
+ },
+ [0xA921]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA921,
+ },
+ [0xA922]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA922,
+ },
+ [0xA923]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA923,
+ },
+ [0xA924]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA924,
+ },
+ [0xA925]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA925,
+ },
+ [0xA926]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA926,
+ },
+ [0xA927]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA927,
+ },
+ [0xA928]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA928,
+ },
+ [0xA929]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA929,
+ },
+ [0xA92A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA92A,
+ },
+ [0xA92B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA92B,
+ },
+ [0xA92C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA92C,
+ },
+ [0xA92D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA92D,
+ },
+ [0xA92E]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA92E,
+ },
+ [0xA92F]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA92F,
+ },
+ [0xA930]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA930,
+ },
+ [0xA931]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA931,
+ },
+ [0xA932]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA932,
+ },
+ [0xA933]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA933,
+ },
+ [0xA934]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA934,
+ },
+ [0xA935]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA935,
+ },
+ [0xA936]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA936,
+ },
+ [0xA937]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA937,
+ },
+ [0xA938]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA938,
+ },
+ [0xA939]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA939,
+ },
+ [0xA93A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA93A,
+ },
+ [0xA93B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA93B,
+ },
+ [0xA93C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA93C,
+ },
+ [0xA93D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA93D,
+ },
+ [0xA93E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA93E,
+ },
+ [0xA93F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA93F,
+ },
+ [0xA940]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA940,
+ },
+ [0xA941]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA941,
+ },
+ [0xA942]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA942,
+ },
+ [0xA943]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA943,
+ },
+ [0xA944]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA944,
+ },
+ [0xA945]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA945,
+ },
+ [0xA946]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA946,
+ },
+ [0xA947]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA947,
+ },
+ [0xA948]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA948,
+ },
+ [0xA949]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA949,
+ },
+ [0xA94A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA94A,
+ },
+ [0xA94B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA94B,
+ },
+ [0xA94C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA94C,
+ },
+ [0xA94D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA94D,
+ },
+ [0xA94E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA94E,
+ },
+ [0xA94F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA94F,
+ },
+ [0xA950]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA950,
+ },
+ [0xA951]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA951,
+ },
+ [0xA952]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA952,
+ },
+ [0xA953]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA953,
+ },
+ [0xA95F]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA95F,
+ },
+ [0xA960]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA960,
+ },
+ [0xA961]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA961,
+ },
+ [0xA962]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA962,
+ },
+ [0xA963]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA963,
+ },
+ [0xA964]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA964,
+ },
+ [0xA965]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA965,
+ },
+ [0xA966]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA966,
+ },
+ [0xA967]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA967,
+ },
+ [0xA968]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA968,
+ },
+ [0xA969]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA969,
+ },
+ [0xA96A]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA96A,
+ },
+ [0xA96B]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA96B,
+ },
+ [0xA96C]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA96C,
+ },
+ [0xA96D]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA96D,
+ },
+ [0xA96E]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA96E,
+ },
+ [0xA96F]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA96F,
+ },
+ [0xA970]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA970,
+ },
+ [0xA971]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA971,
+ },
+ [0xA972]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA972,
+ },
+ [0xA973]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA973,
+ },
+ [0xA974]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA974,
+ },
+ [0xA975]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA975,
+ },
+ [0xA976]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA976,
+ },
+ [0xA977]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA977,
+ },
+ [0xA978]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA978,
+ },
+ [0xA979]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA979,
+ },
+ [0xA97A]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA97A,
+ },
+ [0xA97B]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA97B,
+ },
+ [0xA97C]={
+ category="lo",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA97C,
+ },
+ [0xA980]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA980,
+ },
+ [0xA981]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA981,
+ },
+ [0xA982]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA982,
+ },
+ [0xA983]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA983,
+ },
+ [0xA984]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA984,
+ },
+ [0xA985]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA985,
+ },
+ [0xA986]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA986,
+ },
+ [0xA987]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA987,
+ },
+ [0xA988]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA988,
+ },
+ [0xA989]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA989,
+ },
+ [0xA98A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA98A,
+ },
+ [0xA98B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA98B,
+ },
+ [0xA98C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA98C,
+ },
+ [0xA98D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA98D,
+ },
+ [0xA98E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA98E,
+ },
+ [0xA98F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA98F,
+ },
+ [0xA990]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA990,
+ },
+ [0xA991]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA991,
+ },
+ [0xA992]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA992,
+ },
+ [0xA993]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA993,
+ },
+ [0xA994]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA994,
+ },
+ [0xA995]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA995,
+ },
+ [0xA996]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA996,
+ },
+ [0xA997]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA997,
+ },
+ [0xA998]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA998,
+ },
+ [0xA999]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA999,
+ },
+ [0xA99A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA99A,
+ },
+ [0xA99B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA99B,
+ },
+ [0xA99C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA99C,
+ },
+ [0xA99D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA99D,
+ },
+ [0xA99E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA99E,
+ },
+ [0xA99F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA99F,
+ },
+ [0xA9A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A0,
+ },
+ [0xA9A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A1,
+ },
+ [0xA9A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A2,
+ },
+ [0xA9A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A3,
+ },
+ [0xA9A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A4,
+ },
+ [0xA9A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A5,
+ },
+ [0xA9A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A6,
+ },
+ [0xA9A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A7,
+ },
+ [0xA9A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A8,
+ },
+ [0xA9A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A9,
+ },
+ [0xA9AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9AA,
+ },
+ [0xA9AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9AB,
+ },
+ [0xA9AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9AC,
+ },
+ [0xA9AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9AD,
+ },
+ [0xA9AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9AE,
+ },
+ [0xA9AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9AF,
+ },
+ [0xA9B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9B0,
+ },
+ [0xA9B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9B1,
+ },
+ [0xA9B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9B2,
+ },
+ [0xA9B3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9B3,
+ },
+ [0xA9B4]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9B4,
+ },
+ [0xA9B5]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9B5,
+ },
+ [0xA9B6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9B6,
+ },
+ [0xA9B7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9B7,
+ },
+ [0xA9B8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9B8,
+ },
+ [0xA9B9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9B9,
+ },
+ [0xA9BA]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9BA,
+ },
+ [0xA9BB]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9BB,
+ },
+ [0xA9BC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9BC,
+ },
+ [0xA9BD]={
+ category="mc",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9BD,
+ },
+ [0xA9BE]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9BE,
+ },
+ [0xA9BF]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9BF,
+ },
+ [0xA9C0]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9C0,
+ },
+ [0xA9C1]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9C1,
+ },
+ [0xA9C2]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9C2,
+ },
+ [0xA9C3]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9C3,
+ },
+ [0xA9C4]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9C4,
+ },
+ [0xA9C5]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9C5,
+ },
+ [0xA9C6]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9C6,
+ },
+ [0xA9C7]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA9C7,
+ },
+ [0xA9C8]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA9C8,
+ },
+ [0xA9C9]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA9C9,
+ },
+ [0xA9CA]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9CA,
+ },
+ [0xA9CB]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9CB,
+ },
+ [0xA9CC]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9CC,
+ },
+ [0xA9CD]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9CD,
+ },
+ [0xA9CF]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9CF,
+ },
+ [0xA9D0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D0,
+ },
+ [0xA9D1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D1,
+ },
+ [0xA9D2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D2,
+ },
+ [0xA9D3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D3,
+ },
+ [0xA9D4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D4,
+ },
+ [0xA9D5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D5,
+ },
+ [0xA9D6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D6,
+ },
+ [0xA9D7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D7,
+ },
+ [0xA9D8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D8,
+ },
+ [0xA9D9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D9,
+ },
+ [0xA9DE]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9DE,
+ },
+ [0xA9DF]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9DF,
+ },
+ [0xA9E0]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9E0,
+ },
+ [0xA9E1]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9E1,
+ },
+ [0xA9E2]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9E2,
+ },
+ [0xA9E3]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9E3,
+ },
+ [0xA9E4]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9E4,
+ },
+ [0xA9E5]={
+ category="mn",
+ direction="nsm",
+ indic="d",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0xA9E5,
+ },
+ [0xA9E6]={
+ category="lm",
+ direction="l",
+ indic="o",
+ linebreak="sa",
+ unicodeslot=0xA9E6,
+ },
+ [0xA9E7]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9E7,
+ },
+ [0xA9E8]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9E8,
+ },
+ [0xA9E9]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9E9,
+ },
+ [0xA9EA]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9EA,
+ },
+ [0xA9EB]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9EB,
+ },
+ [0xA9EC]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9EC,
+ },
+ [0xA9ED]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9ED,
+ },
+ [0xA9EE]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9EE,
+ },
+ [0xA9EF]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9EF,
+ },
+ [0xA9F0]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA9F0,
+ },
+ [0xA9F1]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA9F1,
+ },
+ [0xA9F2]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA9F2,
+ },
+ [0xA9F3]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA9F3,
+ },
+ [0xA9F4]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA9F4,
+ },
+ [0xA9F5]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA9F5,
+ },
+ [0xA9F6]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA9F6,
+ },
+ [0xA9F7]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA9F7,
+ },
+ [0xA9F8]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA9F8,
+ },
+ [0xA9F9]={
+ category="nd",
+ direction="l",
+ indic="o",
+ linebreak="nu",
+ unicodeslot=0xA9F9,
+ },
+ [0xA9FA]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9FA,
+ },
+ [0xA9FB]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9FB,
+ },
+ [0xA9FC]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9FC,
+ },
+ [0xA9FD]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9FD,
+ },
+ [0xA9FE]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xA9FE,
+ },
+ [0xAA00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA00,
+ },
+ [0xAA01]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA01,
+ },
+ [0xAA02]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA02,
+ },
+ [0xAA03]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA03,
+ },
+ [0xAA04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA04,
+ },
+ [0xAA05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA05,
+ },
+ [0xAA06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA06,
+ },
+ [0xAA07]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA07,
+ },
+ [0xAA08]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA08,
+ },
+ [0xAA09]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA09,
+ },
+ [0xAA0A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA0A,
+ },
+ [0xAA0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA0B,
+ },
+ [0xAA0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA0C,
+ },
+ [0xAA0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA0D,
+ },
+ [0xAA0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA0E,
+ },
+ [0xAA0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA0F,
+ },
+ [0xAA10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA10,
+ },
+ [0xAA11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA11,
+ },
+ [0xAA12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA12,
+ },
+ [0xAA13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA13,
+ },
+ [0xAA14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA14,
+ },
+ [0xAA15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA15,
+ },
+ [0xAA16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA16,
+ },
+ [0xAA17]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA17,
+ },
+ [0xAA18]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA18,
+ },
+ [0xAA19]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA19,
+ },
+ [0xAA1A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA1A,
+ },
+ [0xAA1B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA1B,
+ },
+ [0xAA1C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA1C,
+ },
+ [0xAA1D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA1D,
+ },
+ [0xAA1E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA1E,
+ },
+ [0xAA1F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA1F,
+ },
+ [0xAA20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA20,
+ },
+ [0xAA21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA21,
+ },
+ [0xAA22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA22,
+ },
+ [0xAA23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA23,
+ },
+ [0xAA24]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA24,
+ },
+ [0xAA25]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA25,
+ },
+ [0xAA26]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA26,
+ },
+ [0xAA27]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA27,
+ },
+ [0xAA28]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA28,
+ },
+ [0xAA29]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA29,
+ },
+ [0xAA2A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA2A,
+ },
+ [0xAA2B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA2B,
+ },
+ [0xAA2C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA2C,
+ },
+ [0xAA2D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA2D,
+ },
+ [0xAA2E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA2E,
+ },
+ [0xAA2F]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAA2F,
+ },
+ [0xAA30]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAA30,
+ },
+ [0xAA31]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA31,
+ },
+ [0xAA32]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA32,
+ },
+ [0xAA33]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAA33,
+ },
+ [0xAA34]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAA34,
+ },
+ [0xAA35]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA35,
+ },
+ [0xAA36]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA36,
+ },
+ [0xAA40]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA40,
+ },
+ [0xAA41]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA41,
+ },
+ [0xAA42]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA42,
+ },
+ [0xAA43]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA43,
+ },
+ [0xAA44]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA44,
+ },
+ [0xAA45]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA45,
+ },
+ [0xAA46]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA46,
+ },
+ [0xAA47]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA47,
+ },
+ [0xAA48]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA48,
+ },
+ [0xAA49]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA49,
+ },
+ [0xAA4A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA4A,
+ },
+ [0xAA4B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA4B,
+ },
+ [0xAA4C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA4C,
+ },
+ [0xAA4D]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAA4D,
+ },
+ [0xAA50]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA50,
+ },
+ [0xAA51]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA51,
+ },
+ [0xAA52]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA52,
+ },
+ [0xAA53]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA53,
+ },
+ [0xAA54]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA54,
+ },
+ [0xAA55]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA55,
+ },
+ [0xAA56]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA56,
+ },
+ [0xAA57]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA57,
+ },
+ [0xAA58]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA58,
+ },
+ [0xAA59]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA59,
+ },
+ [0xAA5C]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA5C,
+ },
+ [0xAA5D]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xAA5D,
+ },
+ [0xAA5E]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xAA5E,
+ },
+ [0xAA5F]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xAA5F,
+ },
+ [0xAA60]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA60,
+ },
+ [0xAA61]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA61,
+ },
+ [0xAA62]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA62,
+ },
+ [0xAA63]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA63,
+ },
+ [0xAA64]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA64,
+ },
+ [0xAA65]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA65,
+ },
+ [0xAA66]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA66,
+ },
+ [0xAA67]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA67,
+ },
+ [0xAA68]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA68,
+ },
+ [0xAA69]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA69,
+ },
+ [0xAA6A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA6A,
+ },
+ [0xAA6B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA6B,
+ },
+ [0xAA6C]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA6C,
+ },
+ [0xAA6D]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA6D,
+ },
+ [0xAA6E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA6E,
+ },
+ [0xAA6F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA6F,
+ },
+ [0xAA70]={
+ category="lm",
+ direction="l",
+ indic="o",
+ linebreak="sa",
+ unicodeslot=0xAA70,
+ },
+ [0xAA71]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA71,
+ },
+ [0xAA72]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA72,
+ },
+ [0xAA73]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA73,
+ },
+ [0xAA74]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA74,
+ },
+ [0xAA75]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA75,
+ },
+ [0xAA76]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA76,
+ },
+ [0xAA77]={
+ category="so",
+ direction="l",
+ indic="o",
+ linebreak="sa",
+ unicodeslot=0xAA77,
+ },
+ [0xAA78]={
+ category="so",
+ direction="l",
+ indic="o",
+ linebreak="sa",
+ unicodeslot=0xAA78,
+ },
+ [0xAA79]={
+ category="so",
+ direction="l",
+ indic="o",
+ linebreak="sa",
+ unicodeslot=0xAA79,
+ },
+ [0xAA7A]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA7A,
+ },
+ [0xAA7B]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0xAA7B,
+ },
+ [0xAA7C]={
+ category="mn",
+ direction="nsm",
+ indic="s",
+ indicmark="t",
+ linebreak="sa",
+ unicodeslot=0xAA7C,
+ },
+ [0xAA7D]={
+ category="mc",
+ direction="l",
+ indic="s",
+ indicmark="r",
+ linebreak="sa",
+ unicodeslot=0xAA7D,
+ },
+ [0xAA7E]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA7E,
+ },
+ [0xAA7F]={
+ category="lo",
+ direction="l",
+ indic="c",
+ linebreak="sa",
+ unicodeslot=0xAA7F,
+ },
+ [0xAA80]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA80,
+ },
+ [0xAA81]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA81,
+ },
+ [0xAA82]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA82,
+ },
+ [0xAA83]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA83,
+ },
+ [0xAA84]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA84,
+ },
+ [0xAA85]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA85,
+ },
+ [0xAA86]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA86,
+ },
+ [0xAA87]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA87,
+ },
+ [0xAA88]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA88,
+ },
+ [0xAA89]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA89,
+ },
+ [0xAA8A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA8A,
+ },
+ [0xAA8B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA8B,
+ },
+ [0xAA8C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA8C,
+ },
+ [0xAA8D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA8D,
+ },
+ [0xAA8E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA8E,
+ },
+ [0xAA8F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA8F,
+ },
+ [0xAA90]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA90,
+ },
+ [0xAA91]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA91,
+ },
+ [0xAA92]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA92,
+ },
+ [0xAA93]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA93,
+ },
+ [0xAA94]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA94,
+ },
+ [0xAA95]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA95,
+ },
+ [0xAA96]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA96,
+ },
+ [0xAA97]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA97,
+ },
+ [0xAA98]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA98,
+ },
+ [0xAA99]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA99,
+ },
+ [0xAA9A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA9A,
+ },
+ [0xAA9B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA9B,
+ },
+ [0xAA9C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA9C,
+ },
+ [0xAA9D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA9D,
+ },
+ [0xAA9E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA9E,
+ },
+ [0xAA9F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA9F,
+ },
+ [0xAAA0]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA0,
+ },
+ [0xAAA1]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA1,
+ },
+ [0xAAA2]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA2,
+ },
+ [0xAAA3]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA3,
+ },
+ [0xAAA4]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA4,
+ },
+ [0xAAA5]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA5,
+ },
+ [0xAAA6]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA6,
+ },
+ [0xAAA7]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA7,
+ },
+ [0xAAA8]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA8,
+ },
+ [0xAAA9]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA9,
+ },
+ [0xAAAA]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAAA,
+ },
+ [0xAAAB]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAAB,
+ },
+ [0xAAAC]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAAC,
+ },
+ [0xAAAD]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAAD,
+ },
+ [0xAAAE]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAAE,
+ },
+ [0xAAAF]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAAF,
+ },
+ [0xAAB0]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAB0,
+ },
+ [0xAAB1]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAB1,
+ },
+ [0xAAB2]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAB2,
+ },
+ [0xAAB3]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAB3,
+ },
+ [0xAAB4]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAB4,
+ },
+ [0xAAB5]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAB5,
+ },
+ [0xAAB6]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAB6,
+ },
+ [0xAAB7]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAB7,
+ },
+ [0xAAB8]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAB8,
+ },
+ [0xAAB9]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAB9,
+ },
+ [0xAABA]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAABA,
+ },
+ [0xAABB]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAABB,
+ },
+ [0xAABC]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAABC,
+ },
+ [0xAABD]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAABD,
+ },
+ [0xAABE]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAABE,
+ },
+ [0xAABF]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAABF,
+ },
+ [0xAAC0]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAC0,
+ },
+ [0xAAC1]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAC1,
+ },
+ [0xAAC2]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAC2,
+ },
+ [0xAADB]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAADB,
+ },
+ [0xAADC]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAADC,
+ },
+ [0xAADD]={
+ category="lm",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAADD,
+ },
+ [0xAADE]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAADE,
+ },
+ [0xAADF]={
+ category="po",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAADF,
+ },
+ [0xAAE0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE0,
+ },
+ [0xAAE1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE1,
+ },
+ [0xAAE2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE2,
+ },
+ [0xAAE3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE3,
+ },
+ [0xAAE4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE4,
+ },
+ [0xAAE5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE5,
+ },
+ [0xAAE6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE6,
+ },
+ [0xAAE7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE7,
+ },
+ [0xAAE8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE8,
+ },
+ [0xAAE9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE9,
+ },
+ [0xAAEA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAEA,
+ },
+ [0xAAEB]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAAEB,
+ },
+ [0xAAEC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAAEC,
+ },
+ [0xAAED]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAAED,
+ },
+ [0xAAEE]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAAEE,
+ },
+ [0xAAEF]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAAEF,
+ },
+ [0xAAF0]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xAAF0,
+ },
+ [0xAAF1]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xAAF1,
+ },
+ [0xAAF2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAF2,
+ },
+ [0xAAF3]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAF3,
+ },
+ [0xAAF4]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAF4,
+ },
+ [0xAAF5]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAAF5,
+ },
+ [0xAAF6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAAF6,
+ },
+ [0xAB01]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB01,
+ },
+ [0xAB02]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB02,
+ },
+ [0xAB03]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB03,
+ },
+ [0xAB04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB04,
+ },
+ [0xAB05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB05,
+ },
+ [0xAB06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB06,
+ },
+ [0xAB09]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB09,
+ },
+ [0xAB0A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB0A,
+ },
+ [0xAB0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB0B,
+ },
+ [0xAB0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB0C,
+ },
+ [0xAB0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB0D,
+ },
+ [0xAB0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB0E,
+ },
+ [0xAB11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB11,
+ },
+ [0xAB12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB12,
+ },
+ [0xAB13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB13,
+ },
+ [0xAB14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB14,
+ },
+ [0xAB15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB15,
+ },
+ [0xAB16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB16,
+ },
+ [0xAB20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB20,
+ },
+ [0xAB21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB21,
+ },
+ [0xAB22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB22,
+ },
+ [0xAB23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB23,
+ },
+ [0xAB24]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB24,
+ },
+ [0xAB25]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB25,
+ },
+ [0xAB26]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB26,
+ },
+ [0xAB28]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB28,
+ },
+ [0xAB29]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB29,
+ },
+ [0xAB2A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB2A,
+ },
+ [0xAB2B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB2B,
+ },
+ [0xAB2C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB2C,
+ },
+ [0xAB2D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB2D,
+ },
+ [0xAB2E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB2E,
+ },
+ [0xAB30]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB30,
+ },
+ [0xAB31]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB31,
+ },
+ [0xAB32]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB32,
+ },
+ [0xAB33]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB33,
+ },
+ [0xAB34]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB34,
+ },
+ [0xAB35]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB35,
+ },
+ [0xAB36]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB36,
+ },
+ [0xAB37]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB37,
+ },
+ [0xAB38]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB38,
+ },
+ [0xAB39]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB39,
+ },
+ [0xAB3A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB3A,
+ },
+ [0xAB3B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB3B,
+ },
+ [0xAB3C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB3C,
+ },
+ [0xAB3D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB3D,
+ },
+ [0xAB3E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB3E,
+ },
+ [0xAB3F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB3F,
+ },
+ [0xAB40]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB40,
+ },
+ [0xAB41]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB41,
+ },
+ [0xAB42]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB42,
+ },
+ [0xAB43]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB43,
+ },
+ [0xAB44]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB44,
+ },
+ [0xAB45]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB45,
+ },
+ [0xAB46]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB46,
+ },
+ [0xAB47]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB47,
+ },
+ [0xAB48]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB48,
+ },
+ [0xAB49]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB49,
+ },
+ [0xAB4A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB4A,
+ },
+ [0xAB4B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB4B,
+ },
+ [0xAB4C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB4C,
+ },
+ [0xAB4D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB4D,
+ },
+ [0xAB4E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB4E,
+ },
+ [0xAB4F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB4F,
+ },
+ [0xAB50]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB50,
+ },
+ [0xAB51]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB51,
+ },
+ [0xAB52]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB52,
+ },
+ [0xAB53]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB53,
+ },
+ [0xAB54]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB54,
+ },
+ [0xAB55]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB55,
+ },
+ [0xAB56]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB56,
+ },
+ [0xAB57]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB57,
+ },
+ [0xAB58]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB58,
+ },
+ [0xAB59]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB59,
+ },
+ [0xAB5A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB5A,
+ },
+ [0xAB5B]={
+ category="sk",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB5B,
+ },
+ [0xAB5C]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0xA727 },
+ unicodeslot=0xAB5C,
+ },
+ [0xAB5D]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0xAB37 },
+ unicodeslot=0xAB5D,
+ },
+ [0xAB5E]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x26B },
+ unicodeslot=0xAB5E,
+ },
+ [0xAB5F]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0xAB52 },
+ unicodeslot=0xAB5F,
+ },
+ [0xAB60]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB60,
+ },
+ [0xAB61]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB61,
+ },
+ [0xAB62]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB62,
+ },
+ [0xAB63]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB63,
+ },
+ [0xAB64]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB64,
+ },
+ [0xAB65]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB65,
+ },
+ [0xAB66]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB66,
+ },
+ [0xAB67]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB67,
+ },
+ [0xAB70]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB70,
+ },
+ [0xAB71]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB71,
+ },
+ [0xAB72]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB72,
+ },
+ [0xAB73]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB73,
+ },
+ [0xAB74]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB74,
+ },
+ [0xAB75]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB75,
+ },
+ [0xAB76]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB76,
+ },
+ [0xAB77]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB77,
+ },
+ [0xAB78]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB78,
+ },
+ [0xAB79]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB79,
+ },
+ [0xAB7A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB7A,
+ },
+ [0xAB7B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB7B,
+ },
+ [0xAB7C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB7C,
+ },
+ [0xAB7D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB7D,
+ },
+ [0xAB7E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB7E,
+ },
+ [0xAB7F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB7F,
+ },
+ [0xAB80]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB80,
+ },
+ [0xAB81]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB81,
+ },
+ [0xAB82]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB82,
+ },
+ [0xAB83]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB83,
+ },
+ [0xAB84]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB84,
+ },
+ [0xAB85]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB85,
+ },
+ [0xAB86]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB86,
+ },
+ [0xAB87]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB87,
+ },
+ [0xAB88]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB88,
+ },
+ [0xAB89]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB89,
+ },
+ [0xAB8A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB8A,
+ },
+ [0xAB8B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB8B,
+ },
+ [0xAB8C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB8C,
+ },
+ [0xAB8D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB8D,
+ },
+ [0xAB8E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB8E,
+ },
+ [0xAB8F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB8F,
+ },
+ [0xAB90]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB90,
+ },
+ [0xAB91]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB91,
+ },
+ [0xAB92]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB92,
+ },
+ [0xAB93]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB93,
+ },
+ [0xAB94]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB94,
+ },
+ [0xAB95]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB95,
+ },
+ [0xAB96]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB96,
+ },
+ [0xAB97]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB97,
+ },
+ [0xAB98]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB98,
+ },
+ [0xAB99]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB99,
+ },
+ [0xAB9A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB9A,
+ },
+ [0xAB9B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB9B,
+ },
+ [0xAB9C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB9C,
+ },
+ [0xAB9D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB9D,
+ },
+ [0xAB9E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB9E,
+ },
+ [0xAB9F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB9F,
+ },
+ [0xABA0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABA0,
+ },
+ [0xABA1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABA1,
+ },
+ [0xABA2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABA2,
+ },
+ [0xABA3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABA3,
+ },
+ [0xABA4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABA4,
+ },
+ [0xABA5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABA5,
+ },
+ [0xABA6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABA6,
+ },
+ [0xABA7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABA7,
+ },
+ [0xABA8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABA8,
+ },
+ [0xABA9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABA9,
+ },
+ [0xABAA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABAA,
+ },
+ [0xABAB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABAB,
+ },
+ [0xABAC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABAC,
+ },
+ [0xABAD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABAD,
+ },
+ [0xABAE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABAE,
+ },
+ [0xABAF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABAF,
+ },
+ [0xABB0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABB0,
+ },
+ [0xABB1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABB1,
+ },
+ [0xABB2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABB2,
+ },
+ [0xABB3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABB3,
+ },
+ [0xABB4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABB4,
+ },
+ [0xABB5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABB5,
+ },
+ [0xABB6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABB6,
+ },
+ [0xABB7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABB7,
+ },
+ [0xABB8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABB8,
+ },
+ [0xABB9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABB9,
+ },
+ [0xABBA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABBA,
+ },
+ [0xABBB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABBB,
+ },
+ [0xABBC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABBC,
+ },
+ [0xABBD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABBD,
+ },
+ [0xABBE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABBE,
+ },
+ [0xABBF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABBF,
+ },
+ [0xABC0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC0,
+ },
+ [0xABC1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC1,
+ },
+ [0xABC2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC2,
+ },
+ [0xABC3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC3,
+ },
+ [0xABC4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC4,
+ },
+ [0xABC5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC5,
+ },
+ [0xABC6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC6,
+ },
+ [0xABC7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC7,
+ },
+ [0xABC8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC8,
+ },
+ [0xABC9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC9,
+ },
+ [0xABCA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABCA,
+ },
+ [0xABCB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABCB,
+ },
+ [0xABCC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABCC,
+ },
+ [0xABCD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABCD,
+ },
+ [0xABCE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABCE,
+ },
+ [0xABCF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABCF,
+ },
+ [0xABD0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD0,
+ },
+ [0xABD1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD1,
+ },
+ [0xABD2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD2,
+ },
+ [0xABD3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD3,
+ },
+ [0xABD4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD4,
+ },
+ [0xABD5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD5,
+ },
+ [0xABD6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD6,
+ },
+ [0xABD7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD7,
+ },
+ [0xABD8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD8,
+ },
+ [0xABD9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD9,
+ },
+ [0xABDA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABDA,
+ },
+ [0xABDB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABDB,
+ },
+ [0xABDC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABDC,
+ },
+ [0xABDD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABDD,
+ },
+ [0xABDE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABDE,
+ },
+ [0xABDF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABDF,
+ },
+ [0xABE0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABE0,
+ },
+ [0xABE1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABE1,
+ },
+ [0xABE2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABE2,
+ },
+ [0xABE3]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABE3,
+ },
+ [0xABE4]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABE4,
+ },
+ [0xABE5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xABE5,
+ },
+ [0xABE6]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABE6,
+ },
+ [0xABE7]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABE7,
+ },
+ [0xABE8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xABE8,
+ },
+ [0xABE9]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABE9,
+ },
+ [0xABEA]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABEA,
+ },
+ [0xABEB]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xABEB,
+ },
+ [0xABEC]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABEC,
+ },
+ [0xABED]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xABED,
+ },
+ [0xABF0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF0,
+ },
+ [0xABF1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF1,
+ },
+ [0xABF2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF2,
+ },
+ [0xABF3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF3,
+ },
+ [0xABF4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF4,
+ },
+ [0xABF5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF5,
+ },
+ [0xABF6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF6,
+ },
+ [0xABF7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF7,
+ },
+ [0xABF8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF8,
+ },
+ [0xABF9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF9,
+ },
+ [0xD7B0]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B0,
+ },
+ [0xD7B1]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B1,
+ },
+ [0xD7B2]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B2,
+ },
+ [0xD7B3]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B3,
+ },
+ [0xD7B4]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B4,
+ },
+ [0xD7B5]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B5,
+ },
+ [0xD7B6]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B6,
+ },
+ [0xD7B7]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B7,
+ },
+ [0xD7B8]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B8,
+ },
+ [0xD7B9]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B9,
+ },
+ [0xD7BA]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7BA,
+ },
+ [0xD7BB]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7BB,
+ },
+ [0xD7BC]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7BC,
+ },
+ [0xD7BD]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7BD,
+ },
+ [0xD7BE]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7BE,
+ },
+ [0xD7BF]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7BF,
+ },
+ [0xD7C0]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C0,
+ },
+ [0xD7C1]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C1,
+ },
+ [0xD7C2]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C2,
+ },
+ [0xD7C3]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C3,
+ },
+ [0xD7C4]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C4,
+ },
+ [0xD7C5]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C5,
+ },
+ [0xD7C6]={
+ category="lo",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C6,
+ },
+ [0xD7CB]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7CB,
+ },
+ [0xD7CC]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7CC,
+ },
+ [0xD7CD]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7CD,
+ },
+ [0xD7CE]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7CE,
+ },
+ [0xD7CF]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7CF,
+ },
+ [0xD7D0]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D0,
+ },
+ [0xD7D1]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D1,
+ },
+ [0xD7D2]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D2,
+ },
+ [0xD7D3]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D3,
+ },
+ [0xD7D4]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D4,
+ },
+ [0xD7D5]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D5,
+ },
+ [0xD7D6]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D6,
+ },
+ [0xD7D7]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D7,
+ },
+ [0xD7D8]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D8,
+ },
+ [0xD7D9]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D9,
+ },
+ [0xD7DA]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7DA,
+ },
+ [0xD7DB]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7DB,
+ },
+ [0xD7DC]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7DC,
+ },
+ [0xD7DD]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7DD,
+ },
+ [0xD7DE]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7DE,
+ },
+ [0xD7DF]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7DF,
+ },
+ [0xD7E0]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E0,
+ },
+ [0xD7E1]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E1,
+ },
+ [0xD7E2]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E2,
+ },
+ [0xD7E3]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E3,
+ },
+ [0xD7E4]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E4,
+ },
+ [0xD7E5]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E5,
+ },
+ [0xD7E6]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E6,
+ },
+ [0xD7E7]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E7,
+ },
+ [0xD7E8]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E8,
+ },
+ [0xD7E9]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E9,
+ },
+ [0xD7EA]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7EA,
+ },
+ [0xD7EB]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7EB,
+ },
+ [0xD7EC]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7EC,
+ },
+ [0xD7ED]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7ED,
+ },
+ [0xD7EE]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7EE,
+ },
+ [0xD7EF]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7EF,
+ },
+ [0xD7F0]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F0,
+ },
+ [0xD7F1]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F1,
+ },
+ [0xD7F2]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F2,
+ },
+ [0xD7F3]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F3,
+ },
+ [0xD7F4]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F4,
+ },
+ [0xD7F5]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F5,
+ },
+ [0xD7F6]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F6,
+ },
+ [0xD7F7]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F7,
+ },
+ [0xD7F8]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F8,
+ },
+ [0xD7F9]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F9,
+ },
+ [0xD7FA]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7FA,
+ },
+ [0xD7FB]={
+ category="lo",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7FB,
+ },
+ [0xD800]={
+ category="cs",
+ direction="l",
+ linebreak="sg",
+ unicodeslot=0xD800,
+ },
+ [0xDB7F]={
+ category="cs",
+ direction="l",
+ linebreak="sg",
+ unicodeslot=0xDB7F,
+ },
+ [0xDB80]={
+ category="cs",
+ direction="l",
+ linebreak="sg",
+ unicodeslot=0xDB80,
+ },
+ [0xDBFF]={
+ category="cs",
+ direction="l",
+ linebreak="sg",
+ unicodeslot=0xDBFF,
+ },
+ [0xDC00]={
+ category="cs",
+ direction="l",
+ linebreak="sg",
+ unicodeslot=0xDC00,
+ },
+ [0xDFFF]={
+ category="cs",
+ direction="l",
+ linebreak="sg",
+ unicodeslot=0xDFFF,
+ },
+ [0xE000]={
+ category="co",
+ direction="l",
+ unicodeslot=0xE000,
+ },
+ [0xF8FF]={
+ category="co",
+ direction="l",
+ unicodeslot=0xF8FF,
+ },
+ [0xF900]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8C48 },
+ unicodeslot=0xF900,
+ },
+ [0xF901]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x66F4 },
+ unicodeslot=0xF901,
+ },
+ [0xF902]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8ECA },
+ unicodeslot=0xF902,
+ },
+ [0xF903]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8CC8 },
+ unicodeslot=0xF903,
+ },
+ [0xF904]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6ED1 },
+ unicodeslot=0xF904,
+ },
+ [0xF905]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E32 },
+ unicodeslot=0xF905,
+ },
+ [0xF906]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x53E5 },
+ unicodeslot=0xF906,
+ },
+ [0xF907]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F9C },
+ unicodeslot=0xF907,
+ },
+ [0xF908]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F9C },
+ unicodeslot=0xF908,
+ },
+ [0xF909]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5951 },
+ unicodeslot=0xF909,
+ },
+ [0xF90A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x91D1 },
+ unicodeslot=0xF90A,
+ },
+ [0xF90B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5587 },
+ unicodeslot=0xF90B,
+ },
+ [0xF90C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5948 },
+ unicodeslot=0xF90C,
+ },
+ [0xF90D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61F6 },
+ unicodeslot=0xF90D,
+ },
+ [0xF90E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7669 },
+ unicodeslot=0xF90E,
+ },
+ [0xF90F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F85 },
+ unicodeslot=0xF90F,
+ },
+ [0xF910]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x863F },
+ unicodeslot=0xF910,
+ },
+ [0xF911]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x87BA },
+ unicodeslot=0xF911,
+ },
+ [0xF912]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88F8 },
+ unicodeslot=0xF912,
+ },
+ [0xF913]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x908F },
+ unicodeslot=0xF913,
+ },
+ [0xF914]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6A02 },
+ unicodeslot=0xF914,
+ },
+ [0xF915]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D1B },
+ unicodeslot=0xF915,
+ },
+ [0xF916]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x70D9 },
+ unicodeslot=0xF916,
+ },
+ [0xF917]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x73DE },
+ unicodeslot=0xF917,
+ },
+ [0xF918]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x843D },
+ unicodeslot=0xF918,
+ },
+ [0xF919]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x916A },
+ unicodeslot=0xF919,
+ },
+ [0xF91A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x99F1 },
+ unicodeslot=0xF91A,
+ },
+ [0xF91B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E82 },
+ unicodeslot=0xF91B,
+ },
+ [0xF91C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5375 },
+ unicodeslot=0xF91C,
+ },
+ [0xF91D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B04 },
+ unicodeslot=0xF91D,
+ },
+ [0xF91E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x721B },
+ unicodeslot=0xF91E,
+ },
+ [0xF91F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x862D },
+ unicodeslot=0xF91F,
+ },
+ [0xF920]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9E1E },
+ unicodeslot=0xF920,
+ },
+ [0xF921]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5D50 },
+ unicodeslot=0xF921,
+ },
+ [0xF922]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6FEB },
+ unicodeslot=0xF922,
+ },
+ [0xF923]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x85CD },
+ unicodeslot=0xF923,
+ },
+ [0xF924]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8964 },
+ unicodeslot=0xF924,
+ },
+ [0xF925]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62C9 },
+ unicodeslot=0xF925,
+ },
+ [0xF926]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x81D8 },
+ unicodeslot=0xF926,
+ },
+ [0xF927]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x881F },
+ unicodeslot=0xF927,
+ },
+ [0xF928]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5ECA },
+ unicodeslot=0xF928,
+ },
+ [0xF929]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6717 },
+ unicodeslot=0xF929,
+ },
+ [0xF92A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D6A },
+ unicodeslot=0xF92A,
+ },
+ [0xF92B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x72FC },
+ unicodeslot=0xF92B,
+ },
+ [0xF92C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x90CE },
+ unicodeslot=0xF92C,
+ },
+ [0xF92D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4F86 },
+ unicodeslot=0xF92D,
+ },
+ [0xF92E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51B7 },
+ unicodeslot=0xF92E,
+ },
+ [0xF92F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52DE },
+ unicodeslot=0xF92F,
+ },
+ [0xF930]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x64C4 },
+ unicodeslot=0xF930,
+ },
+ [0xF931]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6AD3 },
+ unicodeslot=0xF931,
+ },
+ [0xF932]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7210 },
+ unicodeslot=0xF932,
+ },
+ [0xF933]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x76E7 },
+ unicodeslot=0xF933,
+ },
+ [0xF934]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8001 },
+ unicodeslot=0xF934,
+ },
+ [0xF935]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8606 },
+ unicodeslot=0xF935,
+ },
+ [0xF936]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x865C },
+ unicodeslot=0xF936,
+ },
+ [0xF937]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8DEF },
+ unicodeslot=0xF937,
+ },
+ [0xF938]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9732 },
+ unicodeslot=0xF938,
+ },
+ [0xF939]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9B6F },
+ unicodeslot=0xF939,
+ },
+ [0xF93A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9DFA },
+ unicodeslot=0xF93A,
+ },
+ [0xF93B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x788C },
+ unicodeslot=0xF93B,
+ },
+ [0xF93C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x797F },
+ unicodeslot=0xF93C,
+ },
+ [0xF93D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7DA0 },
+ unicodeslot=0xF93D,
+ },
+ [0xF93E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83C9 },
+ unicodeslot=0xF93E,
+ },
+ [0xF93F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9304 },
+ unicodeslot=0xF93F,
+ },
+ [0xF940]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9E7F },
+ unicodeslot=0xF940,
+ },
+ [0xF941]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AD6 },
+ unicodeslot=0xF941,
+ },
+ [0xF942]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58DF },
+ unicodeslot=0xF942,
+ },
+ [0xF943]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F04 },
+ unicodeslot=0xF943,
+ },
+ [0xF944]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7C60 },
+ unicodeslot=0xF944,
+ },
+ [0xF945]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x807E },
+ unicodeslot=0xF945,
+ },
+ [0xF946]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7262 },
+ unicodeslot=0xF946,
+ },
+ [0xF947]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x78CA },
+ unicodeslot=0xF947,
+ },
+ [0xF948]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8CC2 },
+ unicodeslot=0xF948,
+ },
+ [0xF949]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96F7 },
+ unicodeslot=0xF949,
+ },
+ [0xF94A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58D8 },
+ unicodeslot=0xF94A,
+ },
+ [0xF94B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C62 },
+ unicodeslot=0xF94B,
+ },
+ [0xF94C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6A13 },
+ unicodeslot=0xF94C,
+ },
+ [0xF94D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6DDA },
+ unicodeslot=0xF94D,
+ },
+ [0xF94E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6F0F },
+ unicodeslot=0xF94E,
+ },
+ [0xF94F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7D2F },
+ unicodeslot=0xF94F,
+ },
+ [0xF950]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7E37 },
+ unicodeslot=0xF950,
+ },
+ [0xF951]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x964B },
+ unicodeslot=0xF951,
+ },
+ [0xF952]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52D2 },
+ unicodeslot=0xF952,
+ },
+ [0xF953]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x808B },
+ unicodeslot=0xF953,
+ },
+ [0xF954]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51DC },
+ unicodeslot=0xF954,
+ },
+ [0xF955]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51CC },
+ unicodeslot=0xF955,
+ },
+ [0xF956]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7A1C },
+ unicodeslot=0xF956,
+ },
+ [0xF957]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7DBE },
+ unicodeslot=0xF957,
+ },
+ [0xF958]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83F1 },
+ unicodeslot=0xF958,
+ },
+ [0xF959]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9675 },
+ unicodeslot=0xF959,
+ },
+ [0xF95A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B80 },
+ unicodeslot=0xF95A,
+ },
+ [0xF95B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62CF },
+ unicodeslot=0xF95B,
+ },
+ [0xF95C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6A02 },
+ unicodeslot=0xF95C,
+ },
+ [0xF95D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AFE },
+ unicodeslot=0xF95D,
+ },
+ [0xF95E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E39 },
+ unicodeslot=0xF95E,
+ },
+ [0xF95F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BE7 },
+ unicodeslot=0xF95F,
+ },
+ [0xF960]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6012 },
+ unicodeslot=0xF960,
+ },
+ [0xF961]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7387 },
+ unicodeslot=0xF961,
+ },
+ [0xF962]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7570 },
+ unicodeslot=0xF962,
+ },
+ [0xF963]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5317 },
+ unicodeslot=0xF963,
+ },
+ [0xF964]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x78FB },
+ unicodeslot=0xF964,
+ },
+ [0xF965]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4FBF },
+ unicodeslot=0xF965,
+ },
+ [0xF966]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5FA9 },
+ unicodeslot=0xF966,
+ },
+ [0xF967]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E0D },
+ unicodeslot=0xF967,
+ },
+ [0xF968]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6CCC },
+ unicodeslot=0xF968,
+ },
+ [0xF969]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6578 },
+ unicodeslot=0xF969,
+ },
+ [0xF96A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7D22 },
+ unicodeslot=0xF96A,
+ },
+ [0xF96B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x53C3 },
+ unicodeslot=0xF96B,
+ },
+ [0xF96C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x585E },
+ unicodeslot=0xF96C,
+ },
+ [0xF96D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7701 },
+ unicodeslot=0xF96D,
+ },
+ [0xF96E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8449 },
+ unicodeslot=0xF96E,
+ },
+ [0xF96F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AAA },
+ unicodeslot=0xF96F,
+ },
+ [0xF970]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6BBA },
+ unicodeslot=0xF970,
+ },
+ [0xF971]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8FB0 },
+ unicodeslot=0xF971,
+ },
+ [0xF972]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6C88 },
+ unicodeslot=0xF972,
+ },
+ [0xF973]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62FE },
+ unicodeslot=0xF973,
+ },
+ [0xF974]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x82E5 },
+ unicodeslot=0xF974,
+ },
+ [0xF975]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x63A0 },
+ unicodeslot=0xF975,
+ },
+ [0xF976]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7565 },
+ unicodeslot=0xF976,
+ },
+ [0xF977]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4EAE },
+ unicodeslot=0xF977,
+ },
+ [0xF978]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5169 },
+ unicodeslot=0xF978,
+ },
+ [0xF979]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51C9 },
+ unicodeslot=0xF979,
+ },
+ [0xF97A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6881 },
+ unicodeslot=0xF97A,
+ },
+ [0xF97B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7CE7 },
+ unicodeslot=0xF97B,
+ },
+ [0xF97C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x826F },
+ unicodeslot=0xF97C,
+ },
+ [0xF97D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AD2 },
+ unicodeslot=0xF97D,
+ },
+ [0xF97E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x91CF },
+ unicodeslot=0xF97E,
+ },
+ [0xF97F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52F5 },
+ unicodeslot=0xF97F,
+ },
+ [0xF980]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5442 },
+ unicodeslot=0xF980,
+ },
+ [0xF981]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5973 },
+ unicodeslot=0xF981,
+ },
+ [0xF982]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EEC },
+ unicodeslot=0xF982,
+ },
+ [0xF983]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x65C5 },
+ unicodeslot=0xF983,
+ },
+ [0xF984]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6FFE },
+ unicodeslot=0xF984,
+ },
+ [0xF985]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x792A },
+ unicodeslot=0xF985,
+ },
+ [0xF986]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x95AD },
+ unicodeslot=0xF986,
+ },
+ [0xF987]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9A6A },
+ unicodeslot=0xF987,
+ },
+ [0xF988]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9E97 },
+ unicodeslot=0xF988,
+ },
+ [0xF989]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9ECE },
+ unicodeslot=0xF989,
+ },
+ [0xF98A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x529B },
+ unicodeslot=0xF98A,
+ },
+ [0xF98B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x66C6 },
+ unicodeslot=0xF98B,
+ },
+ [0xF98C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B77 },
+ unicodeslot=0xF98C,
+ },
+ [0xF98D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F62 },
+ unicodeslot=0xF98D,
+ },
+ [0xF98E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5E74 },
+ unicodeslot=0xF98E,
+ },
+ [0xF98F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6190 },
+ unicodeslot=0xF98F,
+ },
+ [0xF990]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6200 },
+ unicodeslot=0xF990,
+ },
+ [0xF991]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x649A },
+ unicodeslot=0xF991,
+ },
+ [0xF992]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6F23 },
+ unicodeslot=0xF992,
+ },
+ [0xF993]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7149 },
+ unicodeslot=0xF993,
+ },
+ [0xF994]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7489 },
+ unicodeslot=0xF994,
+ },
+ [0xF995]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x79CA },
+ unicodeslot=0xF995,
+ },
+ [0xF996]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7DF4 },
+ unicodeslot=0xF996,
+ },
+ [0xF997]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x806F },
+ unicodeslot=0xF997,
+ },
+ [0xF998]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F26 },
+ unicodeslot=0xF998,
+ },
+ [0xF999]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x84EE },
+ unicodeslot=0xF999,
+ },
+ [0xF99A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9023 },
+ unicodeslot=0xF99A,
+ },
+ [0xF99B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x934A },
+ unicodeslot=0xF99B,
+ },
+ [0xF99C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5217 },
+ unicodeslot=0xF99C,
+ },
+ [0xF99D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52A3 },
+ unicodeslot=0xF99D,
+ },
+ [0xF99E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x54BD },
+ unicodeslot=0xF99E,
+ },
+ [0xF99F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x70C8 },
+ unicodeslot=0xF99F,
+ },
+ [0xF9A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88C2 },
+ unicodeslot=0xF9A0,
+ },
+ [0xF9A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AAA },
+ unicodeslot=0xF9A1,
+ },
+ [0xF9A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EC9 },
+ unicodeslot=0xF9A2,
+ },
+ [0xF9A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5FF5 },
+ unicodeslot=0xF9A3,
+ },
+ [0xF9A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x637B },
+ unicodeslot=0xF9A4,
+ },
+ [0xF9A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6BAE },
+ unicodeslot=0xF9A5,
+ },
+ [0xF9A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7C3E },
+ unicodeslot=0xF9A6,
+ },
+ [0xF9A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7375 },
+ unicodeslot=0xF9A7,
+ },
+ [0xF9A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4EE4 },
+ unicodeslot=0xF9A8,
+ },
+ [0xF9A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x56F9 },
+ unicodeslot=0xF9A9,
+ },
+ [0xF9AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BE7 },
+ unicodeslot=0xF9AA,
+ },
+ [0xF9AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5DBA },
+ unicodeslot=0xF9AB,
+ },
+ [0xF9AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x601C },
+ unicodeslot=0xF9AC,
+ },
+ [0xF9AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x73B2 },
+ unicodeslot=0xF9AD,
+ },
+ [0xF9AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7469 },
+ unicodeslot=0xF9AE,
+ },
+ [0xF9AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F9A },
+ unicodeslot=0xF9AF,
+ },
+ [0xF9B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8046 },
+ unicodeslot=0xF9B0,
+ },
+ [0xF9B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9234 },
+ unicodeslot=0xF9B1,
+ },
+ [0xF9B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96F6 },
+ unicodeslot=0xF9B2,
+ },
+ [0xF9B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9748 },
+ unicodeslot=0xF9B3,
+ },
+ [0xF9B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9818 },
+ unicodeslot=0xF9B4,
+ },
+ [0xF9B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4F8B },
+ unicodeslot=0xF9B5,
+ },
+ [0xF9B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x79AE },
+ unicodeslot=0xF9B6,
+ },
+ [0xF9B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x91B4 },
+ unicodeslot=0xF9B7,
+ },
+ [0xF9B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96B8 },
+ unicodeslot=0xF9B8,
+ },
+ [0xF9B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x60E1 },
+ unicodeslot=0xF9B9,
+ },
+ [0xF9BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E86 },
+ unicodeslot=0xF9BA,
+ },
+ [0xF9BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x50DA },
+ unicodeslot=0xF9BB,
+ },
+ [0xF9BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BEE },
+ unicodeslot=0xF9BC,
+ },
+ [0xF9BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C3F },
+ unicodeslot=0xF9BD,
+ },
+ [0xF9BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6599 },
+ unicodeslot=0xF9BE,
+ },
+ [0xF9BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6A02 },
+ unicodeslot=0xF9BF,
+ },
+ [0xF9C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x71CE },
+ unicodeslot=0xF9C0,
+ },
+ [0xF9C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7642 },
+ unicodeslot=0xF9C1,
+ },
+ [0xF9C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x84FC },
+ unicodeslot=0xF9C2,
+ },
+ [0xF9C3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x907C },
+ unicodeslot=0xF9C3,
+ },
+ [0xF9C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F8D },
+ unicodeslot=0xF9C4,
+ },
+ [0xF9C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6688 },
+ unicodeslot=0xF9C5,
+ },
+ [0xF9C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x962E },
+ unicodeslot=0xF9C6,
+ },
+ [0xF9C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5289 },
+ unicodeslot=0xF9C7,
+ },
+ [0xF9C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x677B },
+ unicodeslot=0xF9C8,
+ },
+ [0xF9C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x67F3 },
+ unicodeslot=0xF9C9,
+ },
+ [0xF9CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D41 },
+ unicodeslot=0xF9CA,
+ },
+ [0xF9CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6E9C },
+ unicodeslot=0xF9CB,
+ },
+ [0xF9CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7409 },
+ unicodeslot=0xF9CC,
+ },
+ [0xF9CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7559 },
+ unicodeslot=0xF9CD,
+ },
+ [0xF9CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x786B },
+ unicodeslot=0xF9CE,
+ },
+ [0xF9CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7D10 },
+ unicodeslot=0xF9CF,
+ },
+ [0xF9D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x985E },
+ unicodeslot=0xF9D0,
+ },
+ [0xF9D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x516D },
+ unicodeslot=0xF9D1,
+ },
+ [0xF9D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x622E },
+ unicodeslot=0xF9D2,
+ },
+ [0xF9D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9678 },
+ unicodeslot=0xF9D3,
+ },
+ [0xF9D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x502B },
+ unicodeslot=0xF9D4,
+ },
+ [0xF9D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5D19 },
+ unicodeslot=0xF9D5,
+ },
+ [0xF9D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6DEA },
+ unicodeslot=0xF9D6,
+ },
+ [0xF9D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F2A },
+ unicodeslot=0xF9D7,
+ },
+ [0xF9D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F8B },
+ unicodeslot=0xF9D8,
+ },
+ [0xF9D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6144 },
+ unicodeslot=0xF9D9,
+ },
+ [0xF9DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6817 },
+ unicodeslot=0xF9DA,
+ },
+ [0xF9DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7387 },
+ unicodeslot=0xF9DB,
+ },
+ [0xF9DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9686 },
+ unicodeslot=0xF9DC,
+ },
+ [0xF9DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5229 },
+ unicodeslot=0xF9DD,
+ },
+ [0xF9DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x540F },
+ unicodeslot=0xF9DE,
+ },
+ [0xF9DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C65 },
+ unicodeslot=0xF9DF,
+ },
+ [0xF9E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6613 },
+ unicodeslot=0xF9E0,
+ },
+ [0xF9E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x674E },
+ unicodeslot=0xF9E1,
+ },
+ [0xF9E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x68A8 },
+ unicodeslot=0xF9E2,
+ },
+ [0xF9E3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6CE5 },
+ unicodeslot=0xF9E3,
+ },
+ [0xF9E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7406 },
+ unicodeslot=0xF9E4,
+ },
+ [0xF9E5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x75E2 },
+ unicodeslot=0xF9E5,
+ },
+ [0xF9E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F79 },
+ unicodeslot=0xF9E6,
+ },
+ [0xF9E7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88CF },
+ unicodeslot=0xF9E7,
+ },
+ [0xF9E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88E1 },
+ unicodeslot=0xF9E8,
+ },
+ [0xF9E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x91CC },
+ unicodeslot=0xF9E9,
+ },
+ [0xF9EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96E2 },
+ unicodeslot=0xF9EA,
+ },
+ [0xF9EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x533F },
+ unicodeslot=0xF9EB,
+ },
+ [0xF9EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6EBA },
+ unicodeslot=0xF9EC,
+ },
+ [0xF9ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x541D },
+ unicodeslot=0xF9ED,
+ },
+ [0xF9EE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x71D0 },
+ unicodeslot=0xF9EE,
+ },
+ [0xF9EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7498 },
+ unicodeslot=0xF9EF,
+ },
+ [0xF9F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x85FA },
+ unicodeslot=0xF9F0,
+ },
+ [0xF9F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96A3 },
+ unicodeslot=0xF9F1,
+ },
+ [0xF9F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9C57 },
+ unicodeslot=0xF9F2,
+ },
+ [0xF9F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9E9F },
+ unicodeslot=0xF9F3,
+ },
+ [0xF9F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6797 },
+ unicodeslot=0xF9F4,
+ },
+ [0xF9F5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6DCB },
+ unicodeslot=0xF9F5,
+ },
+ [0xF9F6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x81E8 },
+ unicodeslot=0xF9F6,
+ },
+ [0xF9F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7ACB },
+ unicodeslot=0xF9F7,
+ },
+ [0xF9F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7B20 },
+ unicodeslot=0xF9F8,
+ },
+ [0xF9F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7C92 },
+ unicodeslot=0xF9F9,
+ },
+ [0xF9FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x72C0 },
+ unicodeslot=0xF9FA,
+ },
+ [0xF9FB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7099 },
+ unicodeslot=0xF9FB,
+ },
+ [0xF9FC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B58 },
+ unicodeslot=0xF9FC,
+ },
+ [0xF9FD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4EC0 },
+ unicodeslot=0xF9FD,
+ },
+ [0xF9FE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8336 },
+ unicodeslot=0xF9FE,
+ },
+ [0xF9FF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x523A },
+ unicodeslot=0xF9FF,
+ },
+ [0xFA00]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5207 },
+ unicodeslot=0xFA00,
+ },
+ [0xFA01]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EA6 },
+ unicodeslot=0xFA01,
+ },
+ [0xFA02]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62D3 },
+ unicodeslot=0xFA02,
+ },
+ [0xFA03]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7CD6 },
+ unicodeslot=0xFA03,
+ },
+ [0xFA04]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5B85 },
+ unicodeslot=0xFA04,
+ },
+ [0xFA05]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D1E },
+ unicodeslot=0xFA05,
+ },
+ [0xFA06]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x66B4 },
+ unicodeslot=0xFA06,
+ },
+ [0xFA07]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F3B },
+ unicodeslot=0xFA07,
+ },
+ [0xFA08]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x884C },
+ unicodeslot=0xFA08,
+ },
+ [0xFA09]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x964D },
+ unicodeslot=0xFA09,
+ },
+ [0xFA0A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x898B },
+ unicodeslot=0xFA0A,
+ },
+ [0xFA0B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5ED3 },
+ unicodeslot=0xFA0B,
+ },
+ [0xFA0C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5140 },
+ unicodeslot=0xFA0C,
+ },
+ [0xFA0D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x55C0 },
+ unicodeslot=0xFA0D,
+ },
+ [0xFA0E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA0E,
+ },
+ [0xFA0F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA0F,
+ },
+ [0xFA10]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x585A },
+ unicodeslot=0xFA10,
+ },
+ [0xFA11]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA11,
+ },
+ [0xFA12]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6674 },
+ unicodeslot=0xFA12,
+ },
+ [0xFA13]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA13,
+ },
+ [0xFA14]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA14,
+ },
+ [0xFA15]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51DE },
+ unicodeslot=0xFA15,
+ },
+ [0xFA16]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x732A },
+ unicodeslot=0xFA16,
+ },
+ [0xFA17]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x76CA },
+ unicodeslot=0xFA17,
+ },
+ [0xFA18]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x793C },
+ unicodeslot=0xFA18,
+ },
+ [0xFA19]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x795E },
+ unicodeslot=0xFA19,
+ },
+ [0xFA1A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7965 },
+ unicodeslot=0xFA1A,
+ },
+ [0xFA1B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x798F },
+ unicodeslot=0xFA1B,
+ },
+ [0xFA1C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9756 },
+ unicodeslot=0xFA1C,
+ },
+ [0xFA1D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7CBE },
+ unicodeslot=0xFA1D,
+ },
+ [0xFA1E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7FBD },
+ unicodeslot=0xFA1E,
+ },
+ [0xFA1F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA1F,
+ },
+ [0xFA20]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8612 },
+ unicodeslot=0xFA20,
+ },
+ [0xFA21]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA21,
+ },
+ [0xFA22]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AF8 },
+ unicodeslot=0xFA22,
+ },
+ [0xFA23]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA23,
+ },
+ [0xFA24]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA24,
+ },
+ [0xFA25]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9038 },
+ unicodeslot=0xFA25,
+ },
+ [0xFA26]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x90FD },
+ unicodeslot=0xFA26,
+ },
+ [0xFA27]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA27,
+ },
+ [0xFA28]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA28,
+ },
+ [0xFA29]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA29,
+ },
+ [0xFA2A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x98EF },
+ unicodeslot=0xFA2A,
+ },
+ [0xFA2B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x98FC },
+ unicodeslot=0xFA2B,
+ },
+ [0xFA2C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9928 },
+ unicodeslot=0xFA2C,
+ },
+ [0xFA2D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9DB4 },
+ unicodeslot=0xFA2D,
+ },
+ [0xFA2E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x90DE },
+ unicodeslot=0xFA2E,
+ },
+ [0xFA2F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96B7 },
+ unicodeslot=0xFA2F,
+ },
+ [0xFA30]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4FAE },
+ unicodeslot=0xFA30,
+ },
+ [0xFA31]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x50E7 },
+ unicodeslot=0xFA31,
+ },
+ [0xFA32]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x514D },
+ unicodeslot=0xFA32,
+ },
+ [0xFA33]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52C9 },
+ unicodeslot=0xFA33,
+ },
+ [0xFA34]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52E4 },
+ unicodeslot=0xFA34,
+ },
+ [0xFA35]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5351 },
+ unicodeslot=0xFA35,
+ },
+ [0xFA36]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x559D },
+ unicodeslot=0xFA36,
+ },
+ [0xFA37]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5606 },
+ unicodeslot=0xFA37,
+ },
+ [0xFA38]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5668 },
+ unicodeslot=0xFA38,
+ },
+ [0xFA39]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5840 },
+ unicodeslot=0xFA39,
+ },
+ [0xFA3A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58A8 },
+ unicodeslot=0xFA3A,
+ },
+ [0xFA3B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C64 },
+ unicodeslot=0xFA3B,
+ },
+ [0xFA3C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C6E },
+ unicodeslot=0xFA3C,
+ },
+ [0xFA3D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6094 },
+ unicodeslot=0xFA3D,
+ },
+ [0xFA3E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6168 },
+ unicodeslot=0xFA3E,
+ },
+ [0xFA3F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x618E },
+ unicodeslot=0xFA3F,
+ },
+ [0xFA40]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61F2 },
+ unicodeslot=0xFA40,
+ },
+ [0xFA41]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x654F },
+ unicodeslot=0xFA41,
+ },
+ [0xFA42]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x65E2 },
+ unicodeslot=0xFA42,
+ },
+ [0xFA43]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6691 },
+ unicodeslot=0xFA43,
+ },
+ [0xFA44]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6885 },
+ unicodeslot=0xFA44,
+ },
+ [0xFA45]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D77 },
+ unicodeslot=0xFA45,
+ },
+ [0xFA46]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6E1A },
+ unicodeslot=0xFA46,
+ },
+ [0xFA47]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6F22 },
+ unicodeslot=0xFA47,
+ },
+ [0xFA48]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x716E },
+ unicodeslot=0xFA48,
+ },
+ [0xFA49]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x722B },
+ unicodeslot=0xFA49,
+ },
+ [0xFA4A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7422 },
+ unicodeslot=0xFA4A,
+ },
+ [0xFA4B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7891 },
+ unicodeslot=0xFA4B,
+ },
+ [0xFA4C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x793E },
+ unicodeslot=0xFA4C,
+ },
+ [0xFA4D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7949 },
+ unicodeslot=0xFA4D,
+ },
+ [0xFA4E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7948 },
+ unicodeslot=0xFA4E,
+ },
+ [0xFA4F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7950 },
+ unicodeslot=0xFA4F,
+ },
+ [0xFA50]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7956 },
+ unicodeslot=0xFA50,
+ },
+ [0xFA51]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x795D },
+ unicodeslot=0xFA51,
+ },
+ [0xFA52]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x798D },
+ unicodeslot=0xFA52,
+ },
+ [0xFA53]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x798E },
+ unicodeslot=0xFA53,
+ },
+ [0xFA54]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7A40 },
+ unicodeslot=0xFA54,
+ },
+ [0xFA55]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7A81 },
+ unicodeslot=0xFA55,
+ },
+ [0xFA56]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7BC0 },
+ unicodeslot=0xFA56,
+ },
+ [0xFA57]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7DF4 },
+ unicodeslot=0xFA57,
+ },
+ [0xFA58]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7E09 },
+ unicodeslot=0xFA58,
+ },
+ [0xFA59]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7E41 },
+ unicodeslot=0xFA59,
+ },
+ [0xFA5A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F72 },
+ unicodeslot=0xFA5A,
+ },
+ [0xFA5B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8005 },
+ unicodeslot=0xFA5B,
+ },
+ [0xFA5C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x81ED },
+ unicodeslot=0xFA5C,
+ },
+ [0xFA5D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8279 },
+ unicodeslot=0xFA5D,
+ },
+ [0xFA5E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8279 },
+ unicodeslot=0xFA5E,
+ },
+ [0xFA5F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8457 },
+ unicodeslot=0xFA5F,
+ },
+ [0xFA60]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8910 },
+ unicodeslot=0xFA60,
+ },
+ [0xFA61]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8996 },
+ unicodeslot=0xFA61,
+ },
+ [0xFA62]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B01 },
+ unicodeslot=0xFA62,
+ },
+ [0xFA63]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B39 },
+ unicodeslot=0xFA63,
+ },
+ [0xFA64]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8CD3 },
+ unicodeslot=0xFA64,
+ },
+ [0xFA65]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8D08 },
+ unicodeslot=0xFA65,
+ },
+ [0xFA66]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8FB6 },
+ unicodeslot=0xFA66,
+ },
+ [0xFA67]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9038 },
+ unicodeslot=0xFA67,
+ },
+ [0xFA68]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96E3 },
+ unicodeslot=0xFA68,
+ },
+ [0xFA69]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x97FF },
+ unicodeslot=0xFA69,
+ },
+ [0xFA6A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x983B },
+ unicodeslot=0xFA6A,
+ },
+ [0xFA6B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6075 },
+ unicodeslot=0xFA6B,
+ },
+ [0xFA6C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x242EE },
+ unicodeslot=0xFA6C,
+ },
+ [0xFA6D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8218 },
+ unicodeslot=0xFA6D,
+ },
+ [0xFA70]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E26 },
+ unicodeslot=0xFA70,
+ },
+ [0xFA71]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51B5 },
+ unicodeslot=0xFA71,
+ },
+ [0xFA72]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5168 },
+ unicodeslot=0xFA72,
+ },
+ [0xFA73]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4F80 },
+ unicodeslot=0xFA73,
+ },
+ [0xFA74]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5145 },
+ unicodeslot=0xFA74,
+ },
+ [0xFA75]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5180 },
+ unicodeslot=0xFA75,
+ },
+ [0xFA76]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52C7 },
+ unicodeslot=0xFA76,
+ },
+ [0xFA77]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52FA },
+ unicodeslot=0xFA77,
+ },
+ [0xFA78]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x559D },
+ unicodeslot=0xFA78,
+ },
+ [0xFA79]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5555 },
+ unicodeslot=0xFA79,
+ },
+ [0xFA7A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5599 },
+ unicodeslot=0xFA7A,
+ },
+ [0xFA7B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x55E2 },
+ unicodeslot=0xFA7B,
+ },
+ [0xFA7C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x585A },
+ unicodeslot=0xFA7C,
+ },
+ [0xFA7D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58B3 },
+ unicodeslot=0xFA7D,
+ },
+ [0xFA7E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5944 },
+ unicodeslot=0xFA7E,
+ },
+ [0xFA7F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5954 },
+ unicodeslot=0xFA7F,
+ },
+ [0xFA80]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5A62 },
+ unicodeslot=0xFA80,
+ },
+ [0xFA81]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5B28 },
+ unicodeslot=0xFA81,
+ },
+ [0xFA82]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5ED2 },
+ unicodeslot=0xFA82,
+ },
+ [0xFA83]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5ED9 },
+ unicodeslot=0xFA83,
+ },
+ [0xFA84]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F69 },
+ unicodeslot=0xFA84,
+ },
+ [0xFA85]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5FAD },
+ unicodeslot=0xFA85,
+ },
+ [0xFA86]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x60D8 },
+ unicodeslot=0xFA86,
+ },
+ [0xFA87]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x614E },
+ unicodeslot=0xFA87,
+ },
+ [0xFA88]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6108 },
+ unicodeslot=0xFA88,
+ },
+ [0xFA89]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x618E },
+ unicodeslot=0xFA89,
+ },
+ [0xFA8A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6160 },
+ unicodeslot=0xFA8A,
+ },
+ [0xFA8B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61F2 },
+ unicodeslot=0xFA8B,
+ },
+ [0xFA8C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6234 },
+ unicodeslot=0xFA8C,
+ },
+ [0xFA8D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x63C4 },
+ unicodeslot=0xFA8D,
+ },
+ [0xFA8E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x641C },
+ unicodeslot=0xFA8E,
+ },
+ [0xFA8F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6452 },
+ unicodeslot=0xFA8F,
+ },
+ [0xFA90]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6556 },
+ unicodeslot=0xFA90,
+ },
+ [0xFA91]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6674 },
+ unicodeslot=0xFA91,
+ },
+ [0xFA92]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6717 },
+ unicodeslot=0xFA92,
+ },
+ [0xFA93]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x671B },
+ unicodeslot=0xFA93,
+ },
+ [0xFA94]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6756 },
+ unicodeslot=0xFA94,
+ },
+ [0xFA95]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B79 },
+ unicodeslot=0xFA95,
+ },
+ [0xFA96]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6BBA },
+ unicodeslot=0xFA96,
+ },
+ [0xFA97]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D41 },
+ unicodeslot=0xFA97,
+ },
+ [0xFA98]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6EDB },
+ unicodeslot=0xFA98,
+ },
+ [0xFA99]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6ECB },
+ unicodeslot=0xFA99,
+ },
+ [0xFA9A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6F22 },
+ unicodeslot=0xFA9A,
+ },
+ [0xFA9B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x701E },
+ unicodeslot=0xFA9B,
+ },
+ [0xFA9C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x716E },
+ unicodeslot=0xFA9C,
+ },
+ [0xFA9D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x77A7 },
+ unicodeslot=0xFA9D,
+ },
+ [0xFA9E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7235 },
+ unicodeslot=0xFA9E,
+ },
+ [0xFA9F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x72AF },
+ unicodeslot=0xFA9F,
+ },
+ [0xFAA0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x732A },
+ unicodeslot=0xFAA0,
+ },
+ [0xFAA1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7471 },
+ unicodeslot=0xFAA1,
+ },
+ [0xFAA2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7506 },
+ unicodeslot=0xFAA2,
+ },
+ [0xFAA3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x753B },
+ unicodeslot=0xFAA3,
+ },
+ [0xFAA4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x761D },
+ unicodeslot=0xFAA4,
+ },
+ [0xFAA5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x761F },
+ unicodeslot=0xFAA5,
+ },
+ [0xFAA6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x76CA },
+ unicodeslot=0xFAA6,
+ },
+ [0xFAA7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x76DB },
+ unicodeslot=0xFAA7,
+ },
+ [0xFAA8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x76F4 },
+ unicodeslot=0xFAA8,
+ },
+ [0xFAA9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x774A },
+ unicodeslot=0xFAA9,
+ },
+ [0xFAAA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7740 },
+ unicodeslot=0xFAAA,
+ },
+ [0xFAAB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x78CC },
+ unicodeslot=0xFAAB,
+ },
+ [0xFAAC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7AB1 },
+ unicodeslot=0xFAAC,
+ },
+ [0xFAAD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7BC0 },
+ unicodeslot=0xFAAD,
+ },
+ [0xFAAE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7C7B },
+ unicodeslot=0xFAAE,
+ },
+ [0xFAAF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7D5B },
+ unicodeslot=0xFAAF,
+ },
+ [0xFAB0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7DF4 },
+ unicodeslot=0xFAB0,
+ },
+ [0xFAB1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F3E },
+ unicodeslot=0xFAB1,
+ },
+ [0xFAB2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8005 },
+ unicodeslot=0xFAB2,
+ },
+ [0xFAB3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8352 },
+ unicodeslot=0xFAB3,
+ },
+ [0xFAB4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83EF },
+ unicodeslot=0xFAB4,
+ },
+ [0xFAB5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8779 },
+ unicodeslot=0xFAB5,
+ },
+ [0xFAB6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8941 },
+ unicodeslot=0xFAB6,
+ },
+ [0xFAB7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8986 },
+ unicodeslot=0xFAB7,
+ },
+ [0xFAB8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8996 },
+ unicodeslot=0xFAB8,
+ },
+ [0xFAB9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8ABF },
+ unicodeslot=0xFAB9,
+ },
+ [0xFABA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AF8 },
+ unicodeslot=0xFABA,
+ },
+ [0xFABB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8ACB },
+ unicodeslot=0xFABB,
+ },
+ [0xFABC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B01 },
+ unicodeslot=0xFABC,
+ },
+ [0xFABD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AFE },
+ unicodeslot=0xFABD,
+ },
+ [0xFABE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AED },
+ unicodeslot=0xFABE,
+ },
+ [0xFABF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B39 },
+ unicodeslot=0xFABF,
+ },
+ [0xFAC0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B8A },
+ unicodeslot=0xFAC0,
+ },
+ [0xFAC1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8D08 },
+ unicodeslot=0xFAC1,
+ },
+ [0xFAC2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F38 },
+ unicodeslot=0xFAC2,
+ },
+ [0xFAC3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9072 },
+ unicodeslot=0xFAC3,
+ },
+ [0xFAC4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9199 },
+ unicodeslot=0xFAC4,
+ },
+ [0xFAC5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9276 },
+ unicodeslot=0xFAC5,
+ },
+ [0xFAC6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x967C },
+ unicodeslot=0xFAC6,
+ },
+ [0xFAC7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96E3 },
+ unicodeslot=0xFAC7,
+ },
+ [0xFAC8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9756 },
+ unicodeslot=0xFAC8,
+ },
+ [0xFAC9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x97DB },
+ unicodeslot=0xFAC9,
+ },
+ [0xFACA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x97FF },
+ unicodeslot=0xFACA,
+ },
+ [0xFACB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x980B },
+ unicodeslot=0xFACB,
+ },
+ [0xFACC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x983B },
+ unicodeslot=0xFACC,
+ },
+ [0xFACD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9B12 },
+ unicodeslot=0xFACD,
+ },
+ [0xFACE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F9C },
+ unicodeslot=0xFACE,
+ },
+ [0xFACF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2284A },
+ unicodeslot=0xFACF,
+ },
+ [0xFAD0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x22844 },
+ unicodeslot=0xFAD0,
+ },
+ [0xFAD1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x233D5 },
+ unicodeslot=0xFAD1,
+ },
+ [0xFAD2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3B9D },
+ unicodeslot=0xFAD2,
+ },
+ [0xFAD3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4018 },
+ unicodeslot=0xFAD3,
+ },
+ [0xFAD4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4039 },
+ unicodeslot=0xFAD4,
+ },
+ [0xFAD5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25249 },
+ unicodeslot=0xFAD5,
+ },
+ [0xFAD6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25CD0 },
+ unicodeslot=0xFAD6,
+ },
+ [0xFAD7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x27ED3 },
+ unicodeslot=0xFAD7,
+ },
+ [0xFAD8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F43 },
+ unicodeslot=0xFAD8,
+ },
+ [0xFAD9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F8E },
+ unicodeslot=0xFAD9,
+ },
+ [0xFB00]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x66, 0x66 },
+ unicodeslot=0xFB00,
+ },
+ [0xFB01]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x66, 0x69 },
+ unicodeslot=0xFB01,
+ },
+ [0xFB02]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x66, 0x6C },
+ unicodeslot=0xFB02,
+ },
+ [0xFB03]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x66, 0x66, 0x69 },
+ unicodeslot=0xFB03,
+ },
+ [0xFB04]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x66, 0x66, 0x6C },
+ unicodeslot=0xFB04,
+ },
+ [0xFB05]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x17F, 0x74 },
+ unicodeslot=0xFB05,
+ },
+ [0xFB06]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x73, 0x74 },
+ unicodeslot=0xFB06,
+ },
+ [0xFB13]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x574, 0x576 },
+ unicodeslot=0xFB13,
+ },
+ [0xFB14]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x574, 0x565 },
+ unicodeslot=0xFB14,
+ },
+ [0xFB15]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x574, 0x56B },
+ unicodeslot=0xFB15,
+ },
+ [0xFB16]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x57E, 0x576 },
+ unicodeslot=0xFB16,
+ },
+ [0xFB17]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x574, 0x56D },
+ unicodeslot=0xFB17,
+ },
+ [0xFB1D]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D9, 0x5B4 },
+ unicodeslot=0xFB1D,
+ },
+ [0xFB1E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFB1E,
+ },
+ [0xFB1F]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5F2, 0x5B7 },
+ unicodeslot=0xFB1F,
+ },
+ [0xFB20]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x5E2 },
+ unicodeslot=0xFB20,
+ },
+ [0xFB21]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x5D0 },
+ unicodeslot=0xFB21,
+ },
+ [0xFB22]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x5D3 },
+ unicodeslot=0xFB22,
+ },
+ [0xFB23]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x5D4 },
+ unicodeslot=0xFB23,
+ },
+ [0xFB24]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x5DB },
+ unicodeslot=0xFB24,
+ },
+ [0xFB25]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x5DC },
+ unicodeslot=0xFB25,
+ },
+ [0xFB26]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x5DD },
+ unicodeslot=0xFB26,
+ },
+ [0xFB27]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x5E8 },
+ unicodeslot=0xFB27,
+ },
+ [0xFB28]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x5EA },
+ unicodeslot=0xFB28,
+ },
+ [0xFB29]={
+ category="sm",
+ direction="es",
+ linebreak="al",
+ specials={ "font", 0x2B },
+ unicodeslot=0xFB29,
+ },
+ [0xFB2A]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5E9, 0x5C1 },
+ unicodeslot=0xFB2A,
+ },
+ [0xFB2B]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5E9, 0x5C2 },
+ unicodeslot=0xFB2B,
+ },
+ [0xFB2C]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0xFB49, 0x5C1 },
+ unicodeslot=0xFB2C,
+ },
+ [0xFB2D]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0xFB49, 0x5C2 },
+ unicodeslot=0xFB2D,
+ },
+ [0xFB2E]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D0, 0x5B7 },
+ unicodeslot=0xFB2E,
+ },
+ [0xFB2F]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D0, 0x5B8 },
+ unicodeslot=0xFB2F,
+ },
+ [0xFB30]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D0, 0x5BC },
+ unicodeslot=0xFB30,
+ },
+ [0xFB31]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D1, 0x5BC },
+ unicodeslot=0xFB31,
+ },
+ [0xFB32]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D2, 0x5BC },
+ unicodeslot=0xFB32,
+ },
+ [0xFB33]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D3, 0x5BC },
+ unicodeslot=0xFB33,
+ },
+ [0xFB34]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D4, 0x5BC },
+ unicodeslot=0xFB34,
+ },
+ [0xFB35]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D5, 0x5BC },
+ unicodeslot=0xFB35,
+ },
+ [0xFB36]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D6, 0x5BC },
+ unicodeslot=0xFB36,
+ },
+ [0xFB38]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D8, 0x5BC },
+ unicodeslot=0xFB38,
+ },
+ [0xFB39]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D9, 0x5BC },
+ unicodeslot=0xFB39,
+ },
+ [0xFB3A]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5DA, 0x5BC },
+ unicodeslot=0xFB3A,
+ },
+ [0xFB3B]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5DB, 0x5BC },
+ unicodeslot=0xFB3B,
+ },
+ [0xFB3C]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5DC, 0x5BC },
+ unicodeslot=0xFB3C,
+ },
+ [0xFB3E]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5DE, 0x5BC },
+ unicodeslot=0xFB3E,
+ },
+ [0xFB40]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5E0, 0x5BC },
+ unicodeslot=0xFB40,
+ },
+ [0xFB41]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5E1, 0x5BC },
+ unicodeslot=0xFB41,
+ },
+ [0xFB43]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5E3, 0x5BC },
+ unicodeslot=0xFB43,
+ },
+ [0xFB44]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5E4, 0x5BC },
+ unicodeslot=0xFB44,
+ },
+ [0xFB46]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5E6, 0x5BC },
+ unicodeslot=0xFB46,
+ },
+ [0xFB47]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5E7, 0x5BC },
+ unicodeslot=0xFB47,
+ },
+ [0xFB48]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5E8, 0x5BC },
+ unicodeslot=0xFB48,
+ },
+ [0xFB49]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5E9, 0x5BC },
+ unicodeslot=0xFB49,
+ },
+ [0xFB4A]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5EA, 0x5BC },
+ unicodeslot=0xFB4A,
+ },
+ [0xFB4B]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D5, 0x5B9 },
+ unicodeslot=0xFB4B,
+ },
+ [0xFB4C]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5D1, 0x5BF },
+ unicodeslot=0xFB4C,
+ },
+ [0xFB4D]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5DB, 0x5BF },
+ unicodeslot=0xFB4D,
+ },
+ [0xFB4E]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x5E4, 0x5BF },
+ unicodeslot=0xFB4E,
+ },
+ [0xFB4F]={
+ category="lo",
+ direction="r",
+ linebreak="hl",
+ specials={ "compat", 0x5D0, 0x5DC },
+ unicodeslot=0xFB4F,
+ },
+ [0xFB50]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x671 },
+ unicodeslot=0xFB50,
+ },
+ [0xFB51]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x671 },
+ unicodeslot=0xFB51,
+ },
+ [0xFB52]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x67B },
+ unicodeslot=0xFB52,
+ },
+ [0xFB53]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x67B },
+ unicodeslot=0xFB53,
+ },
+ [0xFB54]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x67B },
+ unicodeslot=0xFB54,
+ },
+ [0xFB55]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x67B },
+ unicodeslot=0xFB55,
+ },
+ [0xFB56]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x67E },
+ unicodeslot=0xFB56,
+ },
+ [0xFB57]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x67E },
+ unicodeslot=0xFB57,
+ },
+ [0xFB58]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x67E },
+ unicodeslot=0xFB58,
+ },
+ [0xFB59]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x67E },
+ unicodeslot=0xFB59,
+ },
+ [0xFB5A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x680 },
+ unicodeslot=0xFB5A,
+ },
+ [0xFB5B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x680 },
+ unicodeslot=0xFB5B,
+ },
+ [0xFB5C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x680 },
+ unicodeslot=0xFB5C,
+ },
+ [0xFB5D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x680 },
+ unicodeslot=0xFB5D,
+ },
+ [0xFB5E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x67A },
+ unicodeslot=0xFB5E,
+ },
+ [0xFB5F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x67A },
+ unicodeslot=0xFB5F,
+ },
+ [0xFB60]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x67A },
+ unicodeslot=0xFB60,
+ },
+ [0xFB61]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x67A },
+ unicodeslot=0xFB61,
+ },
+ [0xFB62]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x67F },
+ unicodeslot=0xFB62,
+ },
+ [0xFB63]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x67F },
+ unicodeslot=0xFB63,
+ },
+ [0xFB64]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x67F },
+ unicodeslot=0xFB64,
+ },
+ [0xFB65]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x67F },
+ unicodeslot=0xFB65,
+ },
+ [0xFB66]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x679 },
+ unicodeslot=0xFB66,
+ },
+ [0xFB67]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x679 },
+ unicodeslot=0xFB67,
+ },
+ [0xFB68]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x679 },
+ unicodeslot=0xFB68,
+ },
+ [0xFB69]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x679 },
+ unicodeslot=0xFB69,
+ },
+ [0xFB6A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6A4 },
+ unicodeslot=0xFB6A,
+ },
+ [0xFB6B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6A4 },
+ unicodeslot=0xFB6B,
+ },
+ [0xFB6C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x6A4 },
+ unicodeslot=0xFB6C,
+ },
+ [0xFB6D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x6A4 },
+ unicodeslot=0xFB6D,
+ },
+ [0xFB6E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6A6 },
+ unicodeslot=0xFB6E,
+ },
+ [0xFB6F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6A6 },
+ unicodeslot=0xFB6F,
+ },
+ [0xFB70]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x6A6 },
+ unicodeslot=0xFB70,
+ },
+ [0xFB71]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x6A6 },
+ unicodeslot=0xFB71,
+ },
+ [0xFB72]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x684 },
+ unicodeslot=0xFB72,
+ },
+ [0xFB73]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x684 },
+ unicodeslot=0xFB73,
+ },
+ [0xFB74]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x684 },
+ unicodeslot=0xFB74,
+ },
+ [0xFB75]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x684 },
+ unicodeslot=0xFB75,
+ },
+ [0xFB76]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x683 },
+ unicodeslot=0xFB76,
+ },
+ [0xFB77]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x683 },
+ unicodeslot=0xFB77,
+ },
+ [0xFB78]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x683 },
+ unicodeslot=0xFB78,
+ },
+ [0xFB79]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x683 },
+ unicodeslot=0xFB79,
+ },
+ [0xFB7A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x686 },
+ unicodeslot=0xFB7A,
+ },
+ [0xFB7B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x686 },
+ unicodeslot=0xFB7B,
+ },
+ [0xFB7C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x686 },
+ unicodeslot=0xFB7C,
+ },
+ [0xFB7D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x686 },
+ unicodeslot=0xFB7D,
+ },
+ [0xFB7E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x687 },
+ unicodeslot=0xFB7E,
+ },
+ [0xFB7F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x687 },
+ unicodeslot=0xFB7F,
+ },
+ [0xFB80]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x687 },
+ unicodeslot=0xFB80,
+ },
+ [0xFB81]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x687 },
+ unicodeslot=0xFB81,
+ },
+ [0xFB82]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x68D },
+ unicodeslot=0xFB82,
+ },
+ [0xFB83]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x68D },
+ unicodeslot=0xFB83,
+ },
+ [0xFB84]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x68C },
+ unicodeslot=0xFB84,
+ },
+ [0xFB85]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x68C },
+ unicodeslot=0xFB85,
+ },
+ [0xFB86]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x68E },
+ unicodeslot=0xFB86,
+ },
+ [0xFB87]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x68E },
+ unicodeslot=0xFB87,
+ },
+ [0xFB88]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x688 },
+ unicodeslot=0xFB88,
+ },
+ [0xFB89]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x688 },
+ unicodeslot=0xFB89,
+ },
+ [0xFB8A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x698 },
+ unicodeslot=0xFB8A,
+ },
+ [0xFB8B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x698 },
+ unicodeslot=0xFB8B,
+ },
+ [0xFB8C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x691 },
+ unicodeslot=0xFB8C,
+ },
+ [0xFB8D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x691 },
+ unicodeslot=0xFB8D,
+ },
+ [0xFB8E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6A9 },
+ unicodeslot=0xFB8E,
+ },
+ [0xFB8F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6A9 },
+ unicodeslot=0xFB8F,
+ },
+ [0xFB90]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x6A9 },
+ unicodeslot=0xFB90,
+ },
+ [0xFB91]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x6A9 },
+ unicodeslot=0xFB91,
+ },
+ [0xFB92]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6AF },
+ unicodeslot=0xFB92,
+ },
+ [0xFB93]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6AF },
+ unicodeslot=0xFB93,
+ },
+ [0xFB94]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x6AF },
+ unicodeslot=0xFB94,
+ },
+ [0xFB95]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x6AF },
+ unicodeslot=0xFB95,
+ },
+ [0xFB96]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6B3 },
+ unicodeslot=0xFB96,
+ },
+ [0xFB97]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6B3 },
+ unicodeslot=0xFB97,
+ },
+ [0xFB98]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x6B3 },
+ unicodeslot=0xFB98,
+ },
+ [0xFB99]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x6B3 },
+ unicodeslot=0xFB99,
+ },
+ [0xFB9A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6B1 },
+ unicodeslot=0xFB9A,
+ },
+ [0xFB9B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6B1 },
+ unicodeslot=0xFB9B,
+ },
+ [0xFB9C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x6B1 },
+ unicodeslot=0xFB9C,
+ },
+ [0xFB9D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x6B1 },
+ unicodeslot=0xFB9D,
+ },
+ [0xFB9E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6BA },
+ unicodeslot=0xFB9E,
+ },
+ [0xFB9F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6BA },
+ unicodeslot=0xFB9F,
+ },
+ [0xFBA0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6BB },
+ unicodeslot=0xFBA0,
+ },
+ [0xFBA1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6BB },
+ unicodeslot=0xFBA1,
+ },
+ [0xFBA2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x6BB },
+ unicodeslot=0xFBA2,
+ },
+ [0xFBA3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x6BB },
+ unicodeslot=0xFBA3,
+ },
+ [0xFBA4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6C0 },
+ unicodeslot=0xFBA4,
+ },
+ [0xFBA5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6C0 },
+ unicodeslot=0xFBA5,
+ },
+ [0xFBA6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6C1 },
+ unicodeslot=0xFBA6,
+ },
+ [0xFBA7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6C1 },
+ unicodeslot=0xFBA7,
+ },
+ [0xFBA8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x6C1 },
+ unicodeslot=0xFBA8,
+ },
+ [0xFBA9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x6C1 },
+ unicodeslot=0xFBA9,
+ },
+ [0xFBAA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6BE },
+ unicodeslot=0xFBAA,
+ },
+ [0xFBAB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6BE },
+ unicodeslot=0xFBAB,
+ },
+ [0xFBAC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x6BE },
+ unicodeslot=0xFBAC,
+ },
+ [0xFBAD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x6BE },
+ unicodeslot=0xFBAD,
+ },
+ [0xFBAE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6D2 },
+ unicodeslot=0xFBAE,
+ },
+ [0xFBAF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6D2 },
+ unicodeslot=0xFBAF,
+ },
+ [0xFBB0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6D3 },
+ unicodeslot=0xFBB0,
+ },
+ [0xFBB1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6D3 },
+ unicodeslot=0xFBB1,
+ },
+ [0xFBB2]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB2,
+ },
+ [0xFBB3]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB3,
+ },
+ [0xFBB4]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB4,
+ },
+ [0xFBB5]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB5,
+ },
+ [0xFBB6]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB6,
+ },
+ [0xFBB7]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB7,
+ },
+ [0xFBB8]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB8,
+ },
+ [0xFBB9]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB9,
+ },
+ [0xFBBA]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBBA,
+ },
+ [0xFBBB]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBBB,
+ },
+ [0xFBBC]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBBC,
+ },
+ [0xFBBD]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBBD,
+ },
+ [0xFBBE]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBBE,
+ },
+ [0xFBBF]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBBF,
+ },
+ [0xFBC0]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBC0,
+ },
+ [0xFBC1]={
+ category="sk",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBC1,
+ },
+ [0xFBD3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6AD },
+ unicodeslot=0xFBD3,
+ },
+ [0xFBD4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6AD },
+ unicodeslot=0xFBD4,
+ },
+ [0xFBD5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x6AD },
+ unicodeslot=0xFBD5,
+ },
+ [0xFBD6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x6AD },
+ unicodeslot=0xFBD6,
+ },
+ [0xFBD7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6C7 },
+ unicodeslot=0xFBD7,
+ },
+ [0xFBD8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6C7 },
+ unicodeslot=0xFBD8,
+ },
+ [0xFBD9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6C6 },
+ unicodeslot=0xFBD9,
+ },
+ [0xFBDA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6C6 },
+ unicodeslot=0xFBDA,
+ },
+ [0xFBDB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6C8 },
+ unicodeslot=0xFBDB,
+ },
+ [0xFBDC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6C8 },
+ unicodeslot=0xFBDC,
+ },
+ [0xFBDD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x677 },
+ unicodeslot=0xFBDD,
+ },
+ [0xFBDE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6CB },
+ unicodeslot=0xFBDE,
+ },
+ [0xFBDF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6CB },
+ unicodeslot=0xFBDF,
+ },
+ [0xFBE0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6C5 },
+ unicodeslot=0xFBE0,
+ },
+ [0xFBE1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6C5 },
+ unicodeslot=0xFBE1,
+ },
+ [0xFBE2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6C9 },
+ unicodeslot=0xFBE2,
+ },
+ [0xFBE3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6C9 },
+ unicodeslot=0xFBE3,
+ },
+ [0xFBE4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6D0 },
+ unicodeslot=0xFBE4,
+ },
+ [0xFBE5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6D0 },
+ unicodeslot=0xFBE5,
+ },
+ [0xFBE6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x6D0 },
+ unicodeslot=0xFBE6,
+ },
+ [0xFBE7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x6D0 },
+ unicodeslot=0xFBE7,
+ },
+ [0xFBE8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x649 },
+ unicodeslot=0xFBE8,
+ },
+ [0xFBE9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x649 },
+ unicodeslot=0xFBE9,
+ },
+ [0xFBEA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x627 },
+ unicodeslot=0xFBEA,
+ },
+ [0xFBEB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x627 },
+ unicodeslot=0xFBEB,
+ },
+ [0xFBEC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x6D5 },
+ unicodeslot=0xFBEC,
+ },
+ [0xFBED]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x6D5 },
+ unicodeslot=0xFBED,
+ },
+ [0xFBEE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x648 },
+ unicodeslot=0xFBEE,
+ },
+ [0xFBEF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x648 },
+ unicodeslot=0xFBEF,
+ },
+ [0xFBF0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x6C7 },
+ unicodeslot=0xFBF0,
+ },
+ [0xFBF1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x6C7 },
+ unicodeslot=0xFBF1,
+ },
+ [0xFBF2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x6C6 },
+ unicodeslot=0xFBF2,
+ },
+ [0xFBF3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x6C6 },
+ unicodeslot=0xFBF3,
+ },
+ [0xFBF4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x6C8 },
+ unicodeslot=0xFBF4,
+ },
+ [0xFBF5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x6C8 },
+ unicodeslot=0xFBF5,
+ },
+ [0xFBF6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x6D0 },
+ unicodeslot=0xFBF6,
+ },
+ [0xFBF7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x6D0 },
+ unicodeslot=0xFBF7,
+ },
+ [0xFBF8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x626, 0x6D0 },
+ unicodeslot=0xFBF8,
+ },
+ [0xFBF9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x649 },
+ unicodeslot=0xFBF9,
+ },
+ [0xFBFA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x649 },
+ unicodeslot=0xFBFA,
+ },
+ [0xFBFB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x626, 0x649 },
+ unicodeslot=0xFBFB,
+ },
+ [0xFBFC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x6CC },
+ unicodeslot=0xFBFC,
+ },
+ [0xFBFD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x6CC },
+ unicodeslot=0xFBFD,
+ },
+ [0xFBFE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x6CC },
+ unicodeslot=0xFBFE,
+ },
+ [0xFBFF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x6CC },
+ unicodeslot=0xFBFF,
+ },
+ [0xFC00]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x62C },
+ unicodeslot=0xFC00,
+ },
+ [0xFC01]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x62D },
+ unicodeslot=0xFC01,
+ },
+ [0xFC02]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x645 },
+ unicodeslot=0xFC02,
+ },
+ [0xFC03]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x649 },
+ unicodeslot=0xFC03,
+ },
+ [0xFC04]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626, 0x64A },
+ unicodeslot=0xFC04,
+ },
+ [0xFC05]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x628, 0x62C },
+ unicodeslot=0xFC05,
+ },
+ [0xFC06]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x628, 0x62D },
+ unicodeslot=0xFC06,
+ },
+ [0xFC07]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x628, 0x62E },
+ unicodeslot=0xFC07,
+ },
+ [0xFC08]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x628, 0x645 },
+ unicodeslot=0xFC08,
+ },
+ [0xFC09]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x628, 0x649 },
+ unicodeslot=0xFC09,
+ },
+ [0xFC0A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x628, 0x64A },
+ unicodeslot=0xFC0A,
+ },
+ [0xFC0B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62A, 0x62C },
+ unicodeslot=0xFC0B,
+ },
+ [0xFC0C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62A, 0x62D },
+ unicodeslot=0xFC0C,
+ },
+ [0xFC0D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62A, 0x62E },
+ unicodeslot=0xFC0D,
+ },
+ [0xFC0E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62A, 0x645 },
+ unicodeslot=0xFC0E,
+ },
+ [0xFC0F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62A, 0x649 },
+ unicodeslot=0xFC0F,
+ },
+ [0xFC10]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62A, 0x64A },
+ unicodeslot=0xFC10,
+ },
+ [0xFC11]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62B, 0x62C },
+ unicodeslot=0xFC11,
+ },
+ [0xFC12]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62B, 0x645 },
+ unicodeslot=0xFC12,
+ },
+ [0xFC13]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62B, 0x649 },
+ unicodeslot=0xFC13,
+ },
+ [0xFC14]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62B, 0x64A },
+ unicodeslot=0xFC14,
+ },
+ [0xFC15]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62C, 0x62D },
+ unicodeslot=0xFC15,
+ },
+ [0xFC16]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62C, 0x645 },
+ unicodeslot=0xFC16,
+ },
+ [0xFC17]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62D, 0x62C },
+ unicodeslot=0xFC17,
+ },
+ [0xFC18]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62D, 0x645 },
+ unicodeslot=0xFC18,
+ },
+ [0xFC19]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62E, 0x62C },
+ unicodeslot=0xFC19,
+ },
+ [0xFC1A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62E, 0x62D },
+ unicodeslot=0xFC1A,
+ },
+ [0xFC1B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62E, 0x645 },
+ unicodeslot=0xFC1B,
+ },
+ [0xFC1C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x633, 0x62C },
+ unicodeslot=0xFC1C,
+ },
+ [0xFC1D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x633, 0x62D },
+ unicodeslot=0xFC1D,
+ },
+ [0xFC1E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x633, 0x62E },
+ unicodeslot=0xFC1E,
+ },
+ [0xFC1F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x633, 0x645 },
+ unicodeslot=0xFC1F,
+ },
+ [0xFC20]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x635, 0x62D },
+ unicodeslot=0xFC20,
+ },
+ [0xFC21]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x635, 0x645 },
+ unicodeslot=0xFC21,
+ },
+ [0xFC22]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x636, 0x62C },
+ unicodeslot=0xFC22,
+ },
+ [0xFC23]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x636, 0x62D },
+ unicodeslot=0xFC23,
+ },
+ [0xFC24]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x636, 0x62E },
+ unicodeslot=0xFC24,
+ },
+ [0xFC25]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x636, 0x645 },
+ unicodeslot=0xFC25,
+ },
+ [0xFC26]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x637, 0x62D },
+ unicodeslot=0xFC26,
+ },
+ [0xFC27]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x637, 0x645 },
+ unicodeslot=0xFC27,
+ },
+ [0xFC28]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x638, 0x645 },
+ unicodeslot=0xFC28,
+ },
+ [0xFC29]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x639, 0x62C },
+ unicodeslot=0xFC29,
+ },
+ [0xFC2A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x639, 0x645 },
+ unicodeslot=0xFC2A,
+ },
+ [0xFC2B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x63A, 0x62C },
+ unicodeslot=0xFC2B,
+ },
+ [0xFC2C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x63A, 0x645 },
+ unicodeslot=0xFC2C,
+ },
+ [0xFC2D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x641, 0x62C },
+ unicodeslot=0xFC2D,
+ },
+ [0xFC2E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x641, 0x62D },
+ unicodeslot=0xFC2E,
+ },
+ [0xFC2F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x641, 0x62E },
+ unicodeslot=0xFC2F,
+ },
+ [0xFC30]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x641, 0x645 },
+ unicodeslot=0xFC30,
+ },
+ [0xFC31]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x641, 0x649 },
+ unicodeslot=0xFC31,
+ },
+ [0xFC32]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x641, 0x64A },
+ unicodeslot=0xFC32,
+ },
+ [0xFC33]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x642, 0x62D },
+ unicodeslot=0xFC33,
+ },
+ [0xFC34]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x642, 0x645 },
+ unicodeslot=0xFC34,
+ },
+ [0xFC35]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x642, 0x649 },
+ unicodeslot=0xFC35,
+ },
+ [0xFC36]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x642, 0x64A },
+ unicodeslot=0xFC36,
+ },
+ [0xFC37]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x643, 0x627 },
+ unicodeslot=0xFC37,
+ },
+ [0xFC38]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x643, 0x62C },
+ unicodeslot=0xFC38,
+ },
+ [0xFC39]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x643, 0x62D },
+ unicodeslot=0xFC39,
+ },
+ [0xFC3A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x643, 0x62E },
+ unicodeslot=0xFC3A,
+ },
+ [0xFC3B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x643, 0x644 },
+ unicodeslot=0xFC3B,
+ },
+ [0xFC3C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x643, 0x645 },
+ unicodeslot=0xFC3C,
+ },
+ [0xFC3D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x643, 0x649 },
+ unicodeslot=0xFC3D,
+ },
+ [0xFC3E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x643, 0x64A },
+ unicodeslot=0xFC3E,
+ },
+ [0xFC3F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x644, 0x62C },
+ unicodeslot=0xFC3F,
+ },
+ [0xFC40]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x644, 0x62D },
+ unicodeslot=0xFC40,
+ },
+ [0xFC41]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x644, 0x62E },
+ unicodeslot=0xFC41,
+ },
+ [0xFC42]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x644, 0x645 },
+ unicodeslot=0xFC42,
+ },
+ [0xFC43]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x644, 0x649 },
+ unicodeslot=0xFC43,
+ },
+ [0xFC44]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x644, 0x64A },
+ unicodeslot=0xFC44,
+ },
+ [0xFC45]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x645, 0x62C },
+ unicodeslot=0xFC45,
+ },
+ [0xFC46]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x645, 0x62D },
+ unicodeslot=0xFC46,
+ },
+ [0xFC47]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x645, 0x62E },
+ unicodeslot=0xFC47,
+ },
+ [0xFC48]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x645, 0x645 },
+ unicodeslot=0xFC48,
+ },
+ [0xFC49]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x645, 0x649 },
+ unicodeslot=0xFC49,
+ },
+ [0xFC4A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x645, 0x64A },
+ unicodeslot=0xFC4A,
+ },
+ [0xFC4B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x646, 0x62C },
+ unicodeslot=0xFC4B,
+ },
+ [0xFC4C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x646, 0x62D },
+ unicodeslot=0xFC4C,
+ },
+ [0xFC4D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x646, 0x62E },
+ unicodeslot=0xFC4D,
+ },
+ [0xFC4E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x646, 0x645 },
+ unicodeslot=0xFC4E,
+ },
+ [0xFC4F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x646, 0x649 },
+ unicodeslot=0xFC4F,
+ },
+ [0xFC50]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x646, 0x64A },
+ unicodeslot=0xFC50,
+ },
+ [0xFC51]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x647, 0x62C },
+ unicodeslot=0xFC51,
+ },
+ [0xFC52]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x647, 0x645 },
+ unicodeslot=0xFC52,
+ },
+ [0xFC53]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x647, 0x649 },
+ unicodeslot=0xFC53,
+ },
+ [0xFC54]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x647, 0x64A },
+ unicodeslot=0xFC54,
+ },
+ [0xFC55]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x64A, 0x62C },
+ unicodeslot=0xFC55,
+ },
+ [0xFC56]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x64A, 0x62D },
+ unicodeslot=0xFC56,
+ },
+ [0xFC57]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x64A, 0x62E },
+ unicodeslot=0xFC57,
+ },
+ [0xFC58]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x64A, 0x645 },
+ unicodeslot=0xFC58,
+ },
+ [0xFC59]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x64A, 0x649 },
+ unicodeslot=0xFC59,
+ },
+ [0xFC5A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x64A, 0x64A },
+ unicodeslot=0xFC5A,
+ },
+ [0xFC5B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x630, 0x670 },
+ unicodeslot=0xFC5B,
+ },
+ [0xFC5C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x631, 0x670 },
+ unicodeslot=0xFC5C,
+ },
+ [0xFC5D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x649, 0x670 },
+ unicodeslot=0xFC5D,
+ },
+ [0xFC5E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x64C, 0x651 },
+ unicodeslot=0xFC5E,
+ },
+ [0xFC5F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x64D, 0x651 },
+ unicodeslot=0xFC5F,
+ },
+ [0xFC60]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x64E, 0x651 },
+ unicodeslot=0xFC60,
+ },
+ [0xFC61]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x64F, 0x651 },
+ unicodeslot=0xFC61,
+ },
+ [0xFC62]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x650, 0x651 },
+ unicodeslot=0xFC62,
+ },
+ [0xFC63]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x651, 0x670 },
+ unicodeslot=0xFC63,
+ },
+ [0xFC64]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x631 },
+ unicodeslot=0xFC64,
+ },
+ [0xFC65]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x632 },
+ unicodeslot=0xFC65,
+ },
+ [0xFC66]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x645 },
+ unicodeslot=0xFC66,
+ },
+ [0xFC67]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x646 },
+ unicodeslot=0xFC67,
+ },
+ [0xFC68]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x649 },
+ unicodeslot=0xFC68,
+ },
+ [0xFC69]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626, 0x64A },
+ unicodeslot=0xFC69,
+ },
+ [0xFC6A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x628, 0x631 },
+ unicodeslot=0xFC6A,
+ },
+ [0xFC6B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x628, 0x632 },
+ unicodeslot=0xFC6B,
+ },
+ [0xFC6C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x628, 0x645 },
+ unicodeslot=0xFC6C,
+ },
+ [0xFC6D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x628, 0x646 },
+ unicodeslot=0xFC6D,
+ },
+ [0xFC6E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x628, 0x649 },
+ unicodeslot=0xFC6E,
+ },
+ [0xFC6F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x628, 0x64A },
+ unicodeslot=0xFC6F,
+ },
+ [0xFC70]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x631 },
+ unicodeslot=0xFC70,
+ },
+ [0xFC71]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x632 },
+ unicodeslot=0xFC71,
+ },
+ [0xFC72]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x645 },
+ unicodeslot=0xFC72,
+ },
+ [0xFC73]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x646 },
+ unicodeslot=0xFC73,
+ },
+ [0xFC74]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x649 },
+ unicodeslot=0xFC74,
+ },
+ [0xFC75]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x64A },
+ unicodeslot=0xFC75,
+ },
+ [0xFC76]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62B, 0x631 },
+ unicodeslot=0xFC76,
+ },
+ [0xFC77]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62B, 0x632 },
+ unicodeslot=0xFC77,
+ },
+ [0xFC78]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62B, 0x645 },
+ unicodeslot=0xFC78,
+ },
+ [0xFC79]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62B, 0x646 },
+ unicodeslot=0xFC79,
+ },
+ [0xFC7A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62B, 0x649 },
+ unicodeslot=0xFC7A,
+ },
+ [0xFC7B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62B, 0x64A },
+ unicodeslot=0xFC7B,
+ },
+ [0xFC7C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x641, 0x649 },
+ unicodeslot=0xFC7C,
+ },
+ [0xFC7D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x641, 0x64A },
+ unicodeslot=0xFC7D,
+ },
+ [0xFC7E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x642, 0x649 },
+ unicodeslot=0xFC7E,
+ },
+ [0xFC7F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x642, 0x64A },
+ unicodeslot=0xFC7F,
+ },
+ [0xFC80]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x643, 0x627 },
+ unicodeslot=0xFC80,
+ },
+ [0xFC81]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x643, 0x644 },
+ unicodeslot=0xFC81,
+ },
+ [0xFC82]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x643, 0x645 },
+ unicodeslot=0xFC82,
+ },
+ [0xFC83]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x643, 0x649 },
+ unicodeslot=0xFC83,
+ },
+ [0xFC84]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x643, 0x64A },
+ unicodeslot=0xFC84,
+ },
+ [0xFC85]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x645 },
+ unicodeslot=0xFC85,
+ },
+ [0xFC86]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x649 },
+ unicodeslot=0xFC86,
+ },
+ [0xFC87]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x64A },
+ unicodeslot=0xFC87,
+ },
+ [0xFC88]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x645, 0x627 },
+ unicodeslot=0xFC88,
+ },
+ [0xFC89]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x645, 0x645 },
+ unicodeslot=0xFC89,
+ },
+ [0xFC8A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x631 },
+ unicodeslot=0xFC8A,
+ },
+ [0xFC8B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x632 },
+ unicodeslot=0xFC8B,
+ },
+ [0xFC8C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x645 },
+ unicodeslot=0xFC8C,
+ },
+ [0xFC8D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x646 },
+ unicodeslot=0xFC8D,
+ },
+ [0xFC8E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x649 },
+ unicodeslot=0xFC8E,
+ },
+ [0xFC8F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x64A },
+ unicodeslot=0xFC8F,
+ },
+ [0xFC90]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x649, 0x670 },
+ unicodeslot=0xFC90,
+ },
+ [0xFC91]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x64A, 0x631 },
+ unicodeslot=0xFC91,
+ },
+ [0xFC92]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x64A, 0x632 },
+ unicodeslot=0xFC92,
+ },
+ [0xFC93]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x64A, 0x645 },
+ unicodeslot=0xFC93,
+ },
+ [0xFC94]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x64A, 0x646 },
+ unicodeslot=0xFC94,
+ },
+ [0xFC95]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x64A, 0x649 },
+ unicodeslot=0xFC95,
+ },
+ [0xFC96]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x64A, 0x64A },
+ unicodeslot=0xFC96,
+ },
+ [0xFC97]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x626, 0x62C },
+ unicodeslot=0xFC97,
+ },
+ [0xFC98]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x626, 0x62D },
+ unicodeslot=0xFC98,
+ },
+ [0xFC99]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x626, 0x62E },
+ unicodeslot=0xFC99,
+ },
+ [0xFC9A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x626, 0x645 },
+ unicodeslot=0xFC9A,
+ },
+ [0xFC9B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x626, 0x647 },
+ unicodeslot=0xFC9B,
+ },
+ [0xFC9C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x628, 0x62C },
+ unicodeslot=0xFC9C,
+ },
+ [0xFC9D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x628, 0x62D },
+ unicodeslot=0xFC9D,
+ },
+ [0xFC9E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x628, 0x62E },
+ unicodeslot=0xFC9E,
+ },
+ [0xFC9F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x628, 0x645 },
+ unicodeslot=0xFC9F,
+ },
+ [0xFCA0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x628, 0x647 },
+ unicodeslot=0xFCA0,
+ },
+ [0xFCA1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A, 0x62C },
+ unicodeslot=0xFCA1,
+ },
+ [0xFCA2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A, 0x62D },
+ unicodeslot=0xFCA2,
+ },
+ [0xFCA3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A, 0x62E },
+ unicodeslot=0xFCA3,
+ },
+ [0xFCA4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A, 0x645 },
+ unicodeslot=0xFCA4,
+ },
+ [0xFCA5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A, 0x647 },
+ unicodeslot=0xFCA5,
+ },
+ [0xFCA6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62B, 0x645 },
+ unicodeslot=0xFCA6,
+ },
+ [0xFCA7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62C, 0x62D },
+ unicodeslot=0xFCA7,
+ },
+ [0xFCA8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62C, 0x645 },
+ unicodeslot=0xFCA8,
+ },
+ [0xFCA9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62D, 0x62C },
+ unicodeslot=0xFCA9,
+ },
+ [0xFCAA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62D, 0x645 },
+ unicodeslot=0xFCAA,
+ },
+ [0xFCAB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62E, 0x62C },
+ unicodeslot=0xFCAB,
+ },
+ [0xFCAC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62E, 0x645 },
+ unicodeslot=0xFCAC,
+ },
+ [0xFCAD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x633, 0x62C },
+ unicodeslot=0xFCAD,
+ },
+ [0xFCAE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x633, 0x62D },
+ unicodeslot=0xFCAE,
+ },
+ [0xFCAF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x633, 0x62E },
+ unicodeslot=0xFCAF,
+ },
+ [0xFCB0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x633, 0x645 },
+ unicodeslot=0xFCB0,
+ },
+ [0xFCB1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x635, 0x62D },
+ unicodeslot=0xFCB1,
+ },
+ [0xFCB2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x635, 0x62E },
+ unicodeslot=0xFCB2,
+ },
+ [0xFCB3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x635, 0x645 },
+ unicodeslot=0xFCB3,
+ },
+ [0xFCB4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x636, 0x62C },
+ unicodeslot=0xFCB4,
+ },
+ [0xFCB5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x636, 0x62D },
+ unicodeslot=0xFCB5,
+ },
+ [0xFCB6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x636, 0x62E },
+ unicodeslot=0xFCB6,
+ },
+ [0xFCB7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x636, 0x645 },
+ unicodeslot=0xFCB7,
+ },
+ [0xFCB8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x637, 0x62D },
+ unicodeslot=0xFCB8,
+ },
+ [0xFCB9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x638, 0x645 },
+ unicodeslot=0xFCB9,
+ },
+ [0xFCBA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x639, 0x62C },
+ unicodeslot=0xFCBA,
+ },
+ [0xFCBB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x639, 0x645 },
+ unicodeslot=0xFCBB,
+ },
+ [0xFCBC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x63A, 0x62C },
+ unicodeslot=0xFCBC,
+ },
+ [0xFCBD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x63A, 0x645 },
+ unicodeslot=0xFCBD,
+ },
+ [0xFCBE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x641, 0x62C },
+ unicodeslot=0xFCBE,
+ },
+ [0xFCBF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x641, 0x62D },
+ unicodeslot=0xFCBF,
+ },
+ [0xFCC0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x641, 0x62E },
+ unicodeslot=0xFCC0,
+ },
+ [0xFCC1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x641, 0x645 },
+ unicodeslot=0xFCC1,
+ },
+ [0xFCC2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x642, 0x62D },
+ unicodeslot=0xFCC2,
+ },
+ [0xFCC3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x642, 0x645 },
+ unicodeslot=0xFCC3,
+ },
+ [0xFCC4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x643, 0x62C },
+ unicodeslot=0xFCC4,
+ },
+ [0xFCC5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x643, 0x62D },
+ unicodeslot=0xFCC5,
+ },
+ [0xFCC6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x643, 0x62E },
+ unicodeslot=0xFCC6,
+ },
+ [0xFCC7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x643, 0x644 },
+ unicodeslot=0xFCC7,
+ },
+ [0xFCC8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x643, 0x645 },
+ unicodeslot=0xFCC8,
+ },
+ [0xFCC9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x644, 0x62C },
+ unicodeslot=0xFCC9,
+ },
+ [0xFCCA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x644, 0x62D },
+ unicodeslot=0xFCCA,
+ },
+ [0xFCCB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x644, 0x62E },
+ unicodeslot=0xFCCB,
+ },
+ [0xFCCC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x644, 0x645 },
+ unicodeslot=0xFCCC,
+ },
+ [0xFCCD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x644, 0x647 },
+ unicodeslot=0xFCCD,
+ },
+ [0xFCCE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x645, 0x62C },
+ unicodeslot=0xFCCE,
+ },
+ [0xFCCF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x645, 0x62D },
+ unicodeslot=0xFCCF,
+ },
+ [0xFCD0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x645, 0x62E },
+ unicodeslot=0xFCD0,
+ },
+ [0xFCD1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x645, 0x645 },
+ unicodeslot=0xFCD1,
+ },
+ [0xFCD2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x646, 0x62C },
+ unicodeslot=0xFCD2,
+ },
+ [0xFCD3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x646, 0x62D },
+ unicodeslot=0xFCD3,
+ },
+ [0xFCD4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x646, 0x62E },
+ unicodeslot=0xFCD4,
+ },
+ [0xFCD5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x646, 0x645 },
+ unicodeslot=0xFCD5,
+ },
+ [0xFCD6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x646, 0x647 },
+ unicodeslot=0xFCD6,
+ },
+ [0xFCD7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x647, 0x62C },
+ unicodeslot=0xFCD7,
+ },
+ [0xFCD8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x647, 0x645 },
+ unicodeslot=0xFCD8,
+ },
+ [0xFCD9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x647, 0x670 },
+ unicodeslot=0xFCD9,
+ },
+ [0xFCDA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x64A, 0x62C },
+ unicodeslot=0xFCDA,
+ },
+ [0xFCDB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x64A, 0x62D },
+ unicodeslot=0xFCDB,
+ },
+ [0xFCDC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x64A, 0x62E },
+ unicodeslot=0xFCDC,
+ },
+ [0xFCDD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x64A, 0x645 },
+ unicodeslot=0xFCDD,
+ },
+ [0xFCDE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x64A, 0x647 },
+ unicodeslot=0xFCDE,
+ },
+ [0xFCDF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x626, 0x645 },
+ unicodeslot=0xFCDF,
+ },
+ [0xFCE0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x626, 0x647 },
+ unicodeslot=0xFCE0,
+ },
+ [0xFCE1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x628, 0x645 },
+ unicodeslot=0xFCE1,
+ },
+ [0xFCE2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x628, 0x647 },
+ unicodeslot=0xFCE2,
+ },
+ [0xFCE3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x62A, 0x645 },
+ unicodeslot=0xFCE3,
+ },
+ [0xFCE4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x62A, 0x647 },
+ unicodeslot=0xFCE4,
+ },
+ [0xFCE5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x62B, 0x645 },
+ unicodeslot=0xFCE5,
+ },
+ [0xFCE6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x62B, 0x647 },
+ unicodeslot=0xFCE6,
+ },
+ [0xFCE7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x633, 0x645 },
+ unicodeslot=0xFCE7,
+ },
+ [0xFCE8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x633, 0x647 },
+ unicodeslot=0xFCE8,
+ },
+ [0xFCE9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x634, 0x645 },
+ unicodeslot=0xFCE9,
+ },
+ [0xFCEA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x634, 0x647 },
+ unicodeslot=0xFCEA,
+ },
+ [0xFCEB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x643, 0x644 },
+ unicodeslot=0xFCEB,
+ },
+ [0xFCEC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x643, 0x645 },
+ unicodeslot=0xFCEC,
+ },
+ [0xFCED]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x644, 0x645 },
+ unicodeslot=0xFCED,
+ },
+ [0xFCEE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x646, 0x645 },
+ unicodeslot=0xFCEE,
+ },
+ [0xFCEF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x646, 0x647 },
+ unicodeslot=0xFCEF,
+ },
+ [0xFCF0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x64A, 0x645 },
+ unicodeslot=0xFCF0,
+ },
+ [0xFCF1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x64A, 0x647 },
+ unicodeslot=0xFCF1,
+ },
+ [0xFCF2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x640, 0x64E, 0x651 },
+ unicodeslot=0xFCF2,
+ },
+ [0xFCF3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x640, 0x64F, 0x651 },
+ unicodeslot=0xFCF3,
+ },
+ [0xFCF4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x640, 0x650, 0x651 },
+ unicodeslot=0xFCF4,
+ },
+ [0xFCF5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x637, 0x649 },
+ unicodeslot=0xFCF5,
+ },
+ [0xFCF6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x637, 0x64A },
+ unicodeslot=0xFCF6,
+ },
+ [0xFCF7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x639, 0x649 },
+ unicodeslot=0xFCF7,
+ },
+ [0xFCF8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x639, 0x64A },
+ unicodeslot=0xFCF8,
+ },
+ [0xFCF9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x63A, 0x649 },
+ unicodeslot=0xFCF9,
+ },
+ [0xFCFA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x63A, 0x64A },
+ unicodeslot=0xFCFA,
+ },
+ [0xFCFB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x633, 0x649 },
+ unicodeslot=0xFCFB,
+ },
+ [0xFCFC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x633, 0x64A },
+ unicodeslot=0xFCFC,
+ },
+ [0xFCFD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x634, 0x649 },
+ unicodeslot=0xFCFD,
+ },
+ [0xFCFE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x634, 0x64A },
+ unicodeslot=0xFCFE,
+ },
+ [0xFCFF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62D, 0x649 },
+ unicodeslot=0xFCFF,
+ },
+ [0xFD00]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62D, 0x64A },
+ unicodeslot=0xFD00,
+ },
+ [0xFD01]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62C, 0x649 },
+ unicodeslot=0xFD01,
+ },
+ [0xFD02]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62C, 0x64A },
+ unicodeslot=0xFD02,
+ },
+ [0xFD03]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62E, 0x649 },
+ unicodeslot=0xFD03,
+ },
+ [0xFD04]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62E, 0x64A },
+ unicodeslot=0xFD04,
+ },
+ [0xFD05]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x635, 0x649 },
+ unicodeslot=0xFD05,
+ },
+ [0xFD06]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x635, 0x64A },
+ unicodeslot=0xFD06,
+ },
+ [0xFD07]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x636, 0x649 },
+ unicodeslot=0xFD07,
+ },
+ [0xFD08]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x636, 0x64A },
+ unicodeslot=0xFD08,
+ },
+ [0xFD09]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x634, 0x62C },
+ unicodeslot=0xFD09,
+ },
+ [0xFD0A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x634, 0x62D },
+ unicodeslot=0xFD0A,
+ },
+ [0xFD0B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x634, 0x62E },
+ unicodeslot=0xFD0B,
+ },
+ [0xFD0C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x634, 0x645 },
+ unicodeslot=0xFD0C,
+ },
+ [0xFD0D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x634, 0x631 },
+ unicodeslot=0xFD0D,
+ },
+ [0xFD0E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x633, 0x631 },
+ unicodeslot=0xFD0E,
+ },
+ [0xFD0F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x635, 0x631 },
+ unicodeslot=0xFD0F,
+ },
+ [0xFD10]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x636, 0x631 },
+ unicodeslot=0xFD10,
+ },
+ [0xFD11]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x637, 0x649 },
+ unicodeslot=0xFD11,
+ },
+ [0xFD12]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x637, 0x64A },
+ unicodeslot=0xFD12,
+ },
+ [0xFD13]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x639, 0x649 },
+ unicodeslot=0xFD13,
+ },
+ [0xFD14]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x639, 0x64A },
+ unicodeslot=0xFD14,
+ },
+ [0xFD15]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x63A, 0x649 },
+ unicodeslot=0xFD15,
+ },
+ [0xFD16]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x63A, 0x64A },
+ unicodeslot=0xFD16,
+ },
+ [0xFD17]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x633, 0x649 },
+ unicodeslot=0xFD17,
+ },
+ [0xFD18]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x633, 0x64A },
+ unicodeslot=0xFD18,
+ },
+ [0xFD19]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634, 0x649 },
+ unicodeslot=0xFD19,
+ },
+ [0xFD1A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634, 0x64A },
+ unicodeslot=0xFD1A,
+ },
+ [0xFD1B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62D, 0x649 },
+ unicodeslot=0xFD1B,
+ },
+ [0xFD1C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62D, 0x64A },
+ unicodeslot=0xFD1C,
+ },
+ [0xFD1D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62C, 0x649 },
+ unicodeslot=0xFD1D,
+ },
+ [0xFD1E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62C, 0x64A },
+ unicodeslot=0xFD1E,
+ },
+ [0xFD1F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62E, 0x649 },
+ unicodeslot=0xFD1F,
+ },
+ [0xFD20]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62E, 0x64A },
+ unicodeslot=0xFD20,
+ },
+ [0xFD21]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x635, 0x649 },
+ unicodeslot=0xFD21,
+ },
+ [0xFD22]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x635, 0x64A },
+ unicodeslot=0xFD22,
+ },
+ [0xFD23]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x636, 0x649 },
+ unicodeslot=0xFD23,
+ },
+ [0xFD24]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x636, 0x64A },
+ unicodeslot=0xFD24,
+ },
+ [0xFD25]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634, 0x62C },
+ unicodeslot=0xFD25,
+ },
+ [0xFD26]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634, 0x62D },
+ unicodeslot=0xFD26,
+ },
+ [0xFD27]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634, 0x62E },
+ unicodeslot=0xFD27,
+ },
+ [0xFD28]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634, 0x645 },
+ unicodeslot=0xFD28,
+ },
+ [0xFD29]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634, 0x631 },
+ unicodeslot=0xFD29,
+ },
+ [0xFD2A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x633, 0x631 },
+ unicodeslot=0xFD2A,
+ },
+ [0xFD2B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x635, 0x631 },
+ unicodeslot=0xFD2B,
+ },
+ [0xFD2C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x636, 0x631 },
+ unicodeslot=0xFD2C,
+ },
+ [0xFD2D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x634, 0x62C },
+ unicodeslot=0xFD2D,
+ },
+ [0xFD2E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x634, 0x62D },
+ unicodeslot=0xFD2E,
+ },
+ [0xFD2F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x634, 0x62E },
+ unicodeslot=0xFD2F,
+ },
+ [0xFD30]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x634, 0x645 },
+ unicodeslot=0xFD30,
+ },
+ [0xFD31]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x633, 0x647 },
+ unicodeslot=0xFD31,
+ },
+ [0xFD32]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x634, 0x647 },
+ unicodeslot=0xFD32,
+ },
+ [0xFD33]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x637, 0x645 },
+ unicodeslot=0xFD33,
+ },
+ [0xFD34]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x633, 0x62C },
+ unicodeslot=0xFD34,
+ },
+ [0xFD35]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x633, 0x62D },
+ unicodeslot=0xFD35,
+ },
+ [0xFD36]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x633, 0x62E },
+ unicodeslot=0xFD36,
+ },
+ [0xFD37]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x634, 0x62C },
+ unicodeslot=0xFD37,
+ },
+ [0xFD38]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x634, 0x62D },
+ unicodeslot=0xFD38,
+ },
+ [0xFD39]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x634, 0x62E },
+ unicodeslot=0xFD39,
+ },
+ [0xFD3A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x637, 0x645 },
+ unicodeslot=0xFD3A,
+ },
+ [0xFD3B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x638, 0x645 },
+ unicodeslot=0xFD3B,
+ },
+ [0xFD3C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x627, 0x64B },
+ unicodeslot=0xFD3C,
+ },
+ [0xFD3D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x627, 0x64B },
+ unicodeslot=0xFD3D,
+ },
+ [0xFD3E]={
+ category="ps",
+ direction="on",
+ linebreak="cl",
+ unicodeslot=0xFD3E,
+ },
+ [0xFD3F]={
+ category="pe",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0xFD3F,
+ },
+ [0xFD50]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A, 0x62C, 0x645 },
+ unicodeslot=0xFD50,
+ },
+ [0xFD51]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x62D, 0x62C },
+ unicodeslot=0xFD51,
+ },
+ [0xFD52]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A, 0x62D, 0x62C },
+ unicodeslot=0xFD52,
+ },
+ [0xFD53]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A, 0x62D, 0x645 },
+ unicodeslot=0xFD53,
+ },
+ [0xFD54]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A, 0x62E, 0x645 },
+ unicodeslot=0xFD54,
+ },
+ [0xFD55]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A, 0x645, 0x62C },
+ unicodeslot=0xFD55,
+ },
+ [0xFD56]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A, 0x645, 0x62D },
+ unicodeslot=0xFD56,
+ },
+ [0xFD57]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A, 0x645, 0x62E },
+ unicodeslot=0xFD57,
+ },
+ [0xFD58]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62C, 0x645, 0x62D },
+ unicodeslot=0xFD58,
+ },
+ [0xFD59]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62C, 0x645, 0x62D },
+ unicodeslot=0xFD59,
+ },
+ [0xFD5A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62D, 0x645, 0x64A },
+ unicodeslot=0xFD5A,
+ },
+ [0xFD5B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62D, 0x645, 0x649 },
+ unicodeslot=0xFD5B,
+ },
+ [0xFD5C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x633, 0x62D, 0x62C },
+ unicodeslot=0xFD5C,
+ },
+ [0xFD5D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x633, 0x62C, 0x62D },
+ unicodeslot=0xFD5D,
+ },
+ [0xFD5E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x633, 0x62C, 0x649 },
+ unicodeslot=0xFD5E,
+ },
+ [0xFD5F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x633, 0x645, 0x62D },
+ unicodeslot=0xFD5F,
+ },
+ [0xFD60]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x633, 0x645, 0x62D },
+ unicodeslot=0xFD60,
+ },
+ [0xFD61]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x633, 0x645, 0x62C },
+ unicodeslot=0xFD61,
+ },
+ [0xFD62]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x633, 0x645, 0x645 },
+ unicodeslot=0xFD62,
+ },
+ [0xFD63]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x633, 0x645, 0x645 },
+ unicodeslot=0xFD63,
+ },
+ [0xFD64]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x635, 0x62D, 0x62D },
+ unicodeslot=0xFD64,
+ },
+ [0xFD65]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x635, 0x62D, 0x62D },
+ unicodeslot=0xFD65,
+ },
+ [0xFD66]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x635, 0x645, 0x645 },
+ unicodeslot=0xFD66,
+ },
+ [0xFD67]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634, 0x62D, 0x645 },
+ unicodeslot=0xFD67,
+ },
+ [0xFD68]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x634, 0x62D, 0x645 },
+ unicodeslot=0xFD68,
+ },
+ [0xFD69]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634, 0x62C, 0x64A },
+ unicodeslot=0xFD69,
+ },
+ [0xFD6A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634, 0x645, 0x62E },
+ unicodeslot=0xFD6A,
+ },
+ [0xFD6B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x634, 0x645, 0x62E },
+ unicodeslot=0xFD6B,
+ },
+ [0xFD6C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634, 0x645, 0x645 },
+ unicodeslot=0xFD6C,
+ },
+ [0xFD6D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x634, 0x645, 0x645 },
+ unicodeslot=0xFD6D,
+ },
+ [0xFD6E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x636, 0x62D, 0x649 },
+ unicodeslot=0xFD6E,
+ },
+ [0xFD6F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x636, 0x62E, 0x645 },
+ unicodeslot=0xFD6F,
+ },
+ [0xFD70]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x636, 0x62E, 0x645 },
+ unicodeslot=0xFD70,
+ },
+ [0xFD71]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x637, 0x645, 0x62D },
+ unicodeslot=0xFD71,
+ },
+ [0xFD72]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x637, 0x645, 0x62D },
+ unicodeslot=0xFD72,
+ },
+ [0xFD73]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x637, 0x645, 0x645 },
+ unicodeslot=0xFD73,
+ },
+ [0xFD74]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x637, 0x645, 0x64A },
+ unicodeslot=0xFD74,
+ },
+ [0xFD75]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x639, 0x62C, 0x645 },
+ unicodeslot=0xFD75,
+ },
+ [0xFD76]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x639, 0x645, 0x645 },
+ unicodeslot=0xFD76,
+ },
+ [0xFD77]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x639, 0x645, 0x645 },
+ unicodeslot=0xFD77,
+ },
+ [0xFD78]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x639, 0x645, 0x649 },
+ unicodeslot=0xFD78,
+ },
+ [0xFD79]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x63A, 0x645, 0x645 },
+ unicodeslot=0xFD79,
+ },
+ [0xFD7A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x63A, 0x645, 0x64A },
+ unicodeslot=0xFD7A,
+ },
+ [0xFD7B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x63A, 0x645, 0x649 },
+ unicodeslot=0xFD7B,
+ },
+ [0xFD7C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x641, 0x62E, 0x645 },
+ unicodeslot=0xFD7C,
+ },
+ [0xFD7D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x641, 0x62E, 0x645 },
+ unicodeslot=0xFD7D,
+ },
+ [0xFD7E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x642, 0x645, 0x62D },
+ unicodeslot=0xFD7E,
+ },
+ [0xFD7F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x642, 0x645, 0x645 },
+ unicodeslot=0xFD7F,
+ },
+ [0xFD80]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x62D, 0x645 },
+ unicodeslot=0xFD80,
+ },
+ [0xFD81]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x62D, 0x64A },
+ unicodeslot=0xFD81,
+ },
+ [0xFD82]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x62D, 0x649 },
+ unicodeslot=0xFD82,
+ },
+ [0xFD83]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x644, 0x62C, 0x62C },
+ unicodeslot=0xFD83,
+ },
+ [0xFD84]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x62C, 0x62C },
+ unicodeslot=0xFD84,
+ },
+ [0xFD85]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x62E, 0x645 },
+ unicodeslot=0xFD85,
+ },
+ [0xFD86]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x644, 0x62E, 0x645 },
+ unicodeslot=0xFD86,
+ },
+ [0xFD87]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x645, 0x62D },
+ unicodeslot=0xFD87,
+ },
+ [0xFD88]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x644, 0x645, 0x62D },
+ unicodeslot=0xFD88,
+ },
+ [0xFD89]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x645, 0x62D, 0x62C },
+ unicodeslot=0xFD89,
+ },
+ [0xFD8A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x645, 0x62D, 0x645 },
+ unicodeslot=0xFD8A,
+ },
+ [0xFD8B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x645, 0x62D, 0x64A },
+ unicodeslot=0xFD8B,
+ },
+ [0xFD8C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x645, 0x62C, 0x62D },
+ unicodeslot=0xFD8C,
+ },
+ [0xFD8D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x645, 0x62C, 0x645 },
+ unicodeslot=0xFD8D,
+ },
+ [0xFD8E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x645, 0x62E, 0x62C },
+ unicodeslot=0xFD8E,
+ },
+ [0xFD8F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x645, 0x62E, 0x645 },
+ unicodeslot=0xFD8F,
+ },
+ [0xFD92]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x645, 0x62C, 0x62E },
+ unicodeslot=0xFD92,
+ },
+ [0xFD93]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x647, 0x645, 0x62C },
+ unicodeslot=0xFD93,
+ },
+ [0xFD94]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x647, 0x645, 0x645 },
+ unicodeslot=0xFD94,
+ },
+ [0xFD95]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x646, 0x62D, 0x645 },
+ unicodeslot=0xFD95,
+ },
+ [0xFD96]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x62D, 0x649 },
+ unicodeslot=0xFD96,
+ },
+ [0xFD97]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x62C, 0x645 },
+ unicodeslot=0xFD97,
+ },
+ [0xFD98]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x646, 0x62C, 0x645 },
+ unicodeslot=0xFD98,
+ },
+ [0xFD99]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x62C, 0x649 },
+ unicodeslot=0xFD99,
+ },
+ [0xFD9A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x645, 0x64A },
+ unicodeslot=0xFD9A,
+ },
+ [0xFD9B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x645, 0x649 },
+ unicodeslot=0xFD9B,
+ },
+ [0xFD9C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x64A, 0x645, 0x645 },
+ unicodeslot=0xFD9C,
+ },
+ [0xFD9D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x64A, 0x645, 0x645 },
+ unicodeslot=0xFD9D,
+ },
+ [0xFD9E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x628, 0x62E, 0x64A },
+ unicodeslot=0xFD9E,
+ },
+ [0xFD9F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x62C, 0x64A },
+ unicodeslot=0xFD9F,
+ },
+ [0xFDA0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x62C, 0x649 },
+ unicodeslot=0xFDA0,
+ },
+ [0xFDA1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x62E, 0x64A },
+ unicodeslot=0xFDA1,
+ },
+ [0xFDA2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x62E, 0x649 },
+ unicodeslot=0xFDA2,
+ },
+ [0xFDA3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x645, 0x64A },
+ unicodeslot=0xFDA3,
+ },
+ [0xFDA4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A, 0x645, 0x649 },
+ unicodeslot=0xFDA4,
+ },
+ [0xFDA5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62C, 0x645, 0x64A },
+ unicodeslot=0xFDA5,
+ },
+ [0xFDA6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62C, 0x62D, 0x649 },
+ unicodeslot=0xFDA6,
+ },
+ [0xFDA7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62C, 0x645, 0x649 },
+ unicodeslot=0xFDA7,
+ },
+ [0xFDA8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x633, 0x62E, 0x649 },
+ unicodeslot=0xFDA8,
+ },
+ [0xFDA9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x635, 0x62D, 0x64A },
+ unicodeslot=0xFDA9,
+ },
+ [0xFDAA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634, 0x62D, 0x64A },
+ unicodeslot=0xFDAA,
+ },
+ [0xFDAB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x636, 0x62D, 0x64A },
+ unicodeslot=0xFDAB,
+ },
+ [0xFDAC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x62C, 0x64A },
+ unicodeslot=0xFDAC,
+ },
+ [0xFDAD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x645, 0x64A },
+ unicodeslot=0xFDAD,
+ },
+ [0xFDAE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x64A, 0x62D, 0x64A },
+ unicodeslot=0xFDAE,
+ },
+ [0xFDAF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x64A, 0x62C, 0x64A },
+ unicodeslot=0xFDAF,
+ },
+ [0xFDB0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x64A, 0x645, 0x64A },
+ unicodeslot=0xFDB0,
+ },
+ [0xFDB1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x645, 0x645, 0x64A },
+ unicodeslot=0xFDB1,
+ },
+ [0xFDB2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x642, 0x645, 0x64A },
+ unicodeslot=0xFDB2,
+ },
+ [0xFDB3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x62D, 0x64A },
+ unicodeslot=0xFDB3,
+ },
+ [0xFDB4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x642, 0x645, 0x62D },
+ unicodeslot=0xFDB4,
+ },
+ [0xFDB5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x644, 0x62D, 0x645 },
+ unicodeslot=0xFDB5,
+ },
+ [0xFDB6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x639, 0x645, 0x64A },
+ unicodeslot=0xFDB6,
+ },
+ [0xFDB7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x643, 0x645, 0x64A },
+ unicodeslot=0xFDB7,
+ },
+ [0xFDB8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x646, 0x62C, 0x62D },
+ unicodeslot=0xFDB8,
+ },
+ [0xFDB9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x645, 0x62E, 0x64A },
+ unicodeslot=0xFDB9,
+ },
+ [0xFDBA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x644, 0x62C, 0x645 },
+ unicodeslot=0xFDBA,
+ },
+ [0xFDBB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x643, 0x645, 0x645 },
+ unicodeslot=0xFDBB,
+ },
+ [0xFDBC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x62C, 0x645 },
+ unicodeslot=0xFDBC,
+ },
+ [0xFDBD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x62C, 0x62D },
+ unicodeslot=0xFDBD,
+ },
+ [0xFDBE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62C, 0x62D, 0x64A },
+ unicodeslot=0xFDBE,
+ },
+ [0xFDBF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62D, 0x62C, 0x64A },
+ unicodeslot=0xFDBF,
+ },
+ [0xFDC0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x645, 0x62C, 0x64A },
+ unicodeslot=0xFDC0,
+ },
+ [0xFDC1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x641, 0x645, 0x64A },
+ unicodeslot=0xFDC1,
+ },
+ [0xFDC2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x628, 0x62D, 0x64A },
+ unicodeslot=0xFDC2,
+ },
+ [0xFDC3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x643, 0x645, 0x645 },
+ unicodeslot=0xFDC3,
+ },
+ [0xFDC4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x639, 0x62C, 0x645 },
+ unicodeslot=0xFDC4,
+ },
+ [0xFDC5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x635, 0x645, 0x645 },
+ unicodeslot=0xFDC5,
+ },
+ [0xFDC6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x633, 0x62E, 0x64A },
+ unicodeslot=0xFDC6,
+ },
+ [0xFDC7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646, 0x62C, 0x64A },
+ unicodeslot=0xFDC7,
+ },
+ [0xFDF0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x635, 0x644, 0x6D2 },
+ unicodeslot=0xFDF0,
+ },
+ [0xFDF1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x642, 0x644, 0x6D2 },
+ unicodeslot=0xFDF1,
+ },
+ [0xFDF2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x627, 0x644, 0x644, 0x647 },
+ unicodeslot=0xFDF2,
+ },
+ [0xFDF3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x627, 0x643, 0x628, 0x631 },
+ unicodeslot=0xFDF3,
+ },
+ [0xFDF4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x645, 0x62D, 0x645, 0x62F },
+ unicodeslot=0xFDF4,
+ },
+ [0xFDF5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x635, 0x644, 0x639, 0x645 },
+ unicodeslot=0xFDF5,
+ },
+ [0xFDF6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x631, 0x633, 0x648, 0x644 },
+ unicodeslot=0xFDF6,
+ },
+ [0xFDF7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x639, 0x644, 0x64A, 0x647 },
+ unicodeslot=0xFDF7,
+ },
+ [0xFDF8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x648, 0x633, 0x644, 0x645 },
+ unicodeslot=0xFDF8,
+ },
+ [0xFDF9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x635, 0x644, 0x649 },
+ unicodeslot=0xFDF9,
+ },
+ [0xFDFA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x635, 0x644, 0x649, 0x20, 0x627, 0x644, 0x644, 0x647, 0x20, 0x639, 0x644, 0x64A, 0x647, 0x20, 0x648, 0x633, 0x644, 0x645 },
+ unicodeslot=0xFDFA,
+ },
+ [0xFDFB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62C, 0x644, 0x20, 0x62C, 0x644, 0x627, 0x644, 0x647 },
+ unicodeslot=0xFDFB,
+ },
+ [0xFDFC]={
+ category="sc",
+ direction="al",
+ linebreak="po",
+ specials={ "isolated", 0x631, 0x6CC, 0x627, 0x644 },
+ unicodeslot=0xFDFC,
+ },
+ [0xFDFD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xFDFD,
+ },
+ [0xFE00]={
+ unicodeslot=0xFE00,
+ },
+ [0xFE10]={
+ category="po",
+ direction="on",
+ linebreak="is",
+ specials={ "vertical", 0x2C },
+ unicodeslot=0xFE10,
+ },
+ [0xFE11]={
+ category="po",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x3001 },
+ unicodeslot=0xFE11,
+ },
+ [0xFE12]={
+ category="po",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x3002 },
+ unicodeslot=0xFE12,
+ },
+ [0xFE13]={
+ category="po",
+ direction="on",
+ linebreak="is",
+ specials={ "vertical", 0x3A },
+ unicodeslot=0xFE13,
+ },
+ [0xFE14]={
+ category="po",
+ direction="on",
+ linebreak="is",
+ specials={ "vertical", 0x3B },
+ unicodeslot=0xFE14,
+ },
+ [0xFE15]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ specials={ "vertical", 0x21 },
+ unicodeslot=0xFE15,
+ },
+ [0xFE16]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ specials={ "vertical", 0x3F },
+ unicodeslot=0xFE16,
+ },
+ [0xFE17]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x3016 },
+ unicodeslot=0xFE17,
+ },
+ [0xFE18]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x3017 },
+ unicodeslot=0xFE18,
+ },
+ [0xFE19]={
+ category="po",
+ direction="on",
+ linebreak="in",
+ specials={ "vertical", 0x2026 },
+ unicodeslot=0xFE19,
+ },
+ [0xFE20]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE20,
+ },
+ [0xFE21]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE21,
+ },
+ [0xFE22]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE22,
+ },
+ [0xFE23]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE23,
+ },
+ [0xFE24]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE24,
+ },
+ [0xFE25]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE25,
+ },
+ [0xFE26]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE26,
+ },
+ [0xFE27]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE27,
+ },
+ [0xFE28]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE28,
+ },
+ [0xFE29]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE29,
+ },
+ [0xFE2A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE2A,
+ },
+ [0xFE2B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE2B,
+ },
+ [0xFE2C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE2C,
+ },
+ [0xFE2D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE2D,
+ },
+ [0xFE2E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE2E,
+ },
+ [0xFE2F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE2F,
+ },
+ [0xFE30]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "vertical", 0x2025 },
+ unicodeslot=0xFE30,
+ },
+ [0xFE31]={
+ category="pd",
+ direction="on",
+ linebreak="id",
+ specials={ "vertical", 0x2014 },
+ unicodeslot=0xFE31,
+ },
+ [0xFE32]={
+ category="pd",
+ direction="on",
+ linebreak="id",
+ specials={ "vertical", 0x2013 },
+ unicodeslot=0xFE32,
+ },
+ [0xFE33]={
+ category="pc",
+ direction="on",
+ linebreak="id",
+ specials={ "vertical", 0x5F },
+ unicodeslot=0xFE33,
+ },
+ [0xFE34]={
+ category="pc",
+ direction="on",
+ linebreak="id",
+ specials={ "vertical", 0x5F },
+ unicodeslot=0xFE34,
+ },
+ [0xFE35]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x28 },
+ unicodeslot=0xFE35,
+ },
+ [0xFE36]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x29 },
+ unicodeslot=0xFE36,
+ },
+ [0xFE37]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x7B },
+ unicodeslot=0xFE37,
+ },
+ [0xFE38]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x7D },
+ unicodeslot=0xFE38,
+ },
+ [0xFE39]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x3014 },
+ unicodeslot=0xFE39,
+ },
+ [0xFE3A]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x3015 },
+ unicodeslot=0xFE3A,
+ },
+ [0xFE3B]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x3010 },
+ unicodeslot=0xFE3B,
+ },
+ [0xFE3C]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x3011 },
+ unicodeslot=0xFE3C,
+ },
+ [0xFE3D]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x300A },
+ unicodeslot=0xFE3D,
+ },
+ [0xFE3E]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x300B },
+ unicodeslot=0xFE3E,
+ },
+ [0xFE3F]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x3008 },
+ unicodeslot=0xFE3F,
+ },
+ [0xFE40]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x3009 },
+ unicodeslot=0xFE40,
+ },
+ [0xFE41]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x300C },
+ unicodeslot=0xFE41,
+ },
+ [0xFE42]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x300D },
+ unicodeslot=0xFE42,
+ },
+ [0xFE43]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x300E },
+ unicodeslot=0xFE43,
+ },
+ [0xFE44]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x300F },
+ unicodeslot=0xFE44,
+ },
+ [0xFE45]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xFE45,
+ },
+ [0xFE46]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xFE46,
+ },
+ [0xFE47]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x5B },
+ unicodeslot=0xFE47,
+ },
+ [0xFE48]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x5D },
+ unicodeslot=0xFE48,
+ },
+ [0xFE49]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x203E },
+ unicodeslot=0xFE49,
+ },
+ [0xFE4A]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x203E },
+ unicodeslot=0xFE4A,
+ },
+ [0xFE4B]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x203E },
+ unicodeslot=0xFE4B,
+ },
+ [0xFE4C]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x203E },
+ unicodeslot=0xFE4C,
+ },
+ [0xFE4D]={
+ category="pc",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F },
+ unicodeslot=0xFE4D,
+ },
+ [0xFE4E]={
+ category="pc",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F },
+ unicodeslot=0xFE4E,
+ },
+ [0xFE4F]={
+ category="pc",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F },
+ unicodeslot=0xFE4F,
+ },
+ [0xFE50]={
+ category="po",
+ direction="cs",
+ linebreak="cl",
+ specials={ "small", 0x2C },
+ unicodeslot=0xFE50,
+ },
+ [0xFE51]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x3001 },
+ unicodeslot=0xFE51,
+ },
+ [0xFE52]={
+ category="po",
+ direction="cs",
+ linebreak="cl",
+ specials={ "small", 0x2E },
+ unicodeslot=0xFE52,
+ },
+ [0xFE54]={
+ category="po",
+ direction="on",
+ linebreak="ns",
+ specials={ "small", 0x3B },
+ unicodeslot=0xFE54,
+ },
+ [0xFE55]={
+ category="po",
+ direction="cs",
+ linebreak="ns",
+ specials={ "small", 0x3A },
+ unicodeslot=0xFE55,
+ },
+ [0xFE56]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ specials={ "small", 0x3F },
+ unicodeslot=0xFE56,
+ },
+ [0xFE57]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ specials={ "small", 0x21 },
+ unicodeslot=0xFE57,
+ },
+ [0xFE58]={
+ category="pd",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x2014 },
+ unicodeslot=0xFE58,
+ },
+ [0xFE59]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0xFE5A,
+ specials={ "small", 0x28 },
+ textclass="open",
+ unicodeslot=0xFE59,
+ },
+ [0xFE5A]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFE59,
+ specials={ "small", 0x29 },
+ textclass="close",
+ unicodeslot=0xFE5A,
+ },
+ [0xFE5B]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0xFE5C,
+ specials={ "small", 0x7B },
+ textclass="open",
+ unicodeslot=0xFE5B,
+ },
+ [0xFE5C]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFE5B,
+ specials={ "small", 0x7D },
+ textclass="close",
+ unicodeslot=0xFE5C,
+ },
+ [0xFE5D]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0xFE5E,
+ specials={ "small", 0x3014 },
+ textclass="open",
+ unicodeslot=0xFE5D,
+ },
+ [0xFE5E]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFE5D,
+ specials={ "small", 0x3015 },
+ textclass="close",
+ unicodeslot=0xFE5E,
+ },
+ [0xFE5F]={
+ category="po",
+ direction="et",
+ linebreak="id",
+ specials={ "small", 0x23 },
+ unicodeslot=0xFE5F,
+ },
+ [0xFE60]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x26 },
+ unicodeslot=0xFE60,
+ },
+ [0xFE61]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x2A },
+ unicodeslot=0xFE61,
+ },
+ [0xFE62]={
+ category="sm",
+ direction="es",
+ linebreak="id",
+ specials={ "small", 0x2B },
+ unicodeslot=0xFE62,
+ },
+ [0xFE63]={
+ category="pd",
+ direction="es",
+ linebreak="id",
+ specials={ "small", 0x2D },
+ unicodeslot=0xFE63,
+ },
+ [0xFE64]={
+ category="sm",
+ direction="on",
+ linebreak="id",
+ mirror=0xFE65,
+ specials={ "small", 0x3C },
+ textclass="open",
+ unicodeslot=0xFE64,
+ },
+ [0xFE65]={
+ category="sm",
+ direction="on",
+ linebreak="id",
+ mirror=0xFE64,
+ specials={ "small", 0x3E },
+ textclass="close",
+ unicodeslot=0xFE65,
+ },
+ [0xFE66]={
+ category="sm",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x3D },
+ unicodeslot=0xFE66,
+ },
+ [0xFE68]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x5C },
+ unicodeslot=0xFE68,
+ },
+ [0xFE69]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ specials={ "small", 0x24 },
+ unicodeslot=0xFE69,
+ },
+ [0xFE6A]={
+ category="po",
+ direction="et",
+ linebreak="po",
+ specials={ "small", 0x25 },
+ unicodeslot=0xFE6A,
+ },
+ [0xFE6B]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x40 },
+ unicodeslot=0xFE6B,
+ },
+ [0xFE70]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x64B },
+ unicodeslot=0xFE70,
+ },
+ [0xFE71]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x640, 0x64B },
+ unicodeslot=0xFE71,
+ },
+ [0xFE72]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x64C },
+ unicodeslot=0xFE72,
+ },
+ [0xFE73]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFE73,
+ },
+ [0xFE74]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x64D },
+ unicodeslot=0xFE74,
+ },
+ [0xFE76]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x64E },
+ unicodeslot=0xFE76,
+ },
+ [0xFE77]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x640, 0x64E },
+ unicodeslot=0xFE77,
+ },
+ [0xFE78]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x64F },
+ unicodeslot=0xFE78,
+ },
+ [0xFE79]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x640, 0x64F },
+ unicodeslot=0xFE79,
+ },
+ [0xFE7A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x650 },
+ unicodeslot=0xFE7A,
+ },
+ [0xFE7B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x640, 0x650 },
+ unicodeslot=0xFE7B,
+ },
+ [0xFE7C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x651 },
+ unicodeslot=0xFE7C,
+ },
+ [0xFE7D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x640, 0x651 },
+ unicodeslot=0xFE7D,
+ },
+ [0xFE7E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x20, 0x652 },
+ unicodeslot=0xFE7E,
+ },
+ [0xFE7F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x640, 0x652 },
+ unicodeslot=0xFE7F,
+ },
+ [0xFE80]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x621 },
+ unicodeslot=0xFE80,
+ },
+ [0xFE81]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x622 },
+ unicodeslot=0xFE81,
+ },
+ [0xFE82]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x622 },
+ unicodeslot=0xFE82,
+ },
+ [0xFE83]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x623 },
+ unicodeslot=0xFE83,
+ },
+ [0xFE84]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x623 },
+ unicodeslot=0xFE84,
+ },
+ [0xFE85]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x624 },
+ unicodeslot=0xFE85,
+ },
+ [0xFE86]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x624 },
+ unicodeslot=0xFE86,
+ },
+ [0xFE87]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x625 },
+ unicodeslot=0xFE87,
+ },
+ [0xFE88]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x625 },
+ unicodeslot=0xFE88,
+ },
+ [0xFE89]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x626 },
+ unicodeslot=0xFE89,
+ },
+ [0xFE8A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x626 },
+ unicodeslot=0xFE8A,
+ },
+ [0xFE8B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x626 },
+ unicodeslot=0xFE8B,
+ },
+ [0xFE8C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x626 },
+ unicodeslot=0xFE8C,
+ },
+ [0xFE8D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x627 },
+ unicodeslot=0xFE8D,
+ },
+ [0xFE8E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x627 },
+ unicodeslot=0xFE8E,
+ },
+ [0xFE8F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x628 },
+ unicodeslot=0xFE8F,
+ },
+ [0xFE90]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x628 },
+ unicodeslot=0xFE90,
+ },
+ [0xFE91]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x628 },
+ unicodeslot=0xFE91,
+ },
+ [0xFE92]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x628 },
+ unicodeslot=0xFE92,
+ },
+ [0xFE93]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x629 },
+ unicodeslot=0xFE93,
+ },
+ [0xFE94]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x629 },
+ unicodeslot=0xFE94,
+ },
+ [0xFE95]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62A },
+ unicodeslot=0xFE95,
+ },
+ [0xFE96]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62A },
+ unicodeslot=0xFE96,
+ },
+ [0xFE97]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62A },
+ unicodeslot=0xFE97,
+ },
+ [0xFE98]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x62A },
+ unicodeslot=0xFE98,
+ },
+ [0xFE99]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62B },
+ unicodeslot=0xFE99,
+ },
+ [0xFE9A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62B },
+ unicodeslot=0xFE9A,
+ },
+ [0xFE9B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62B },
+ unicodeslot=0xFE9B,
+ },
+ [0xFE9C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x62B },
+ unicodeslot=0xFE9C,
+ },
+ [0xFE9D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62C },
+ unicodeslot=0xFE9D,
+ },
+ [0xFE9E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62C },
+ unicodeslot=0xFE9E,
+ },
+ [0xFE9F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62C },
+ unicodeslot=0xFE9F,
+ },
+ [0xFEA0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x62C },
+ unicodeslot=0xFEA0,
+ },
+ [0xFEA1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62D },
+ unicodeslot=0xFEA1,
+ },
+ [0xFEA2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62D },
+ unicodeslot=0xFEA2,
+ },
+ [0xFEA3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62D },
+ unicodeslot=0xFEA3,
+ },
+ [0xFEA4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x62D },
+ unicodeslot=0xFEA4,
+ },
+ [0xFEA5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62E },
+ unicodeslot=0xFEA5,
+ },
+ [0xFEA6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62E },
+ unicodeslot=0xFEA6,
+ },
+ [0xFEA7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x62E },
+ unicodeslot=0xFEA7,
+ },
+ [0xFEA8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x62E },
+ unicodeslot=0xFEA8,
+ },
+ [0xFEA9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x62F },
+ unicodeslot=0xFEA9,
+ },
+ [0xFEAA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x62F },
+ unicodeslot=0xFEAA,
+ },
+ [0xFEAB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x630 },
+ unicodeslot=0xFEAB,
+ },
+ [0xFEAC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x630 },
+ unicodeslot=0xFEAC,
+ },
+ [0xFEAD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x631 },
+ unicodeslot=0xFEAD,
+ },
+ [0xFEAE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x631 },
+ unicodeslot=0xFEAE,
+ },
+ [0xFEAF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x632 },
+ unicodeslot=0xFEAF,
+ },
+ [0xFEB0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x632 },
+ unicodeslot=0xFEB0,
+ },
+ [0xFEB1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x633 },
+ unicodeslot=0xFEB1,
+ },
+ [0xFEB2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x633 },
+ unicodeslot=0xFEB2,
+ },
+ [0xFEB3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x633 },
+ unicodeslot=0xFEB3,
+ },
+ [0xFEB4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x633 },
+ unicodeslot=0xFEB4,
+ },
+ [0xFEB5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x634 },
+ unicodeslot=0xFEB5,
+ },
+ [0xFEB6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x634 },
+ unicodeslot=0xFEB6,
+ },
+ [0xFEB7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x634 },
+ unicodeslot=0xFEB7,
+ },
+ [0xFEB8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x634 },
+ unicodeslot=0xFEB8,
+ },
+ [0xFEB9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x635 },
+ unicodeslot=0xFEB9,
+ },
+ [0xFEBA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x635 },
+ unicodeslot=0xFEBA,
+ },
+ [0xFEBB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x635 },
+ unicodeslot=0xFEBB,
+ },
+ [0xFEBC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x635 },
+ unicodeslot=0xFEBC,
+ },
+ [0xFEBD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x636 },
+ unicodeslot=0xFEBD,
+ },
+ [0xFEBE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x636 },
+ unicodeslot=0xFEBE,
+ },
+ [0xFEBF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x636 },
+ unicodeslot=0xFEBF,
+ },
+ [0xFEC0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x636 },
+ unicodeslot=0xFEC0,
+ },
+ [0xFEC1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x637 },
+ unicodeslot=0xFEC1,
+ },
+ [0xFEC2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x637 },
+ unicodeslot=0xFEC2,
+ },
+ [0xFEC3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x637 },
+ unicodeslot=0xFEC3,
+ },
+ [0xFEC4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x637 },
+ unicodeslot=0xFEC4,
+ },
+ [0xFEC5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x638 },
+ unicodeslot=0xFEC5,
+ },
+ [0xFEC6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x638 },
+ unicodeslot=0xFEC6,
+ },
+ [0xFEC7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x638 },
+ unicodeslot=0xFEC7,
+ },
+ [0xFEC8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x638 },
+ unicodeslot=0xFEC8,
+ },
+ [0xFEC9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x639 },
+ unicodeslot=0xFEC9,
+ },
+ [0xFECA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x639 },
+ unicodeslot=0xFECA,
+ },
+ [0xFECB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x639 },
+ unicodeslot=0xFECB,
+ },
+ [0xFECC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x639 },
+ unicodeslot=0xFECC,
+ },
+ [0xFECD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x63A },
+ unicodeslot=0xFECD,
+ },
+ [0xFECE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x63A },
+ unicodeslot=0xFECE,
+ },
+ [0xFECF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x63A },
+ unicodeslot=0xFECF,
+ },
+ [0xFED0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x63A },
+ unicodeslot=0xFED0,
+ },
+ [0xFED1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x641 },
+ unicodeslot=0xFED1,
+ },
+ [0xFED2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x641 },
+ unicodeslot=0xFED2,
+ },
+ [0xFED3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x641 },
+ unicodeslot=0xFED3,
+ },
+ [0xFED4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x641 },
+ unicodeslot=0xFED4,
+ },
+ [0xFED5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x642 },
+ unicodeslot=0xFED5,
+ },
+ [0xFED6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x642 },
+ unicodeslot=0xFED6,
+ },
+ [0xFED7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x642 },
+ unicodeslot=0xFED7,
+ },
+ [0xFED8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x642 },
+ unicodeslot=0xFED8,
+ },
+ [0xFED9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x643 },
+ unicodeslot=0xFED9,
+ },
+ [0xFEDA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x643 },
+ unicodeslot=0xFEDA,
+ },
+ [0xFEDB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x643 },
+ unicodeslot=0xFEDB,
+ },
+ [0xFEDC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x643 },
+ unicodeslot=0xFEDC,
+ },
+ [0xFEDD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x644 },
+ unicodeslot=0xFEDD,
+ },
+ [0xFEDE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644 },
+ unicodeslot=0xFEDE,
+ },
+ [0xFEDF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x644 },
+ unicodeslot=0xFEDF,
+ },
+ [0xFEE0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x644 },
+ unicodeslot=0xFEE0,
+ },
+ [0xFEE1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x645 },
+ unicodeslot=0xFEE1,
+ },
+ [0xFEE2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x645 },
+ unicodeslot=0xFEE2,
+ },
+ [0xFEE3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x645 },
+ unicodeslot=0xFEE3,
+ },
+ [0xFEE4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x645 },
+ unicodeslot=0xFEE4,
+ },
+ [0xFEE5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x646 },
+ unicodeslot=0xFEE5,
+ },
+ [0xFEE6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x646 },
+ unicodeslot=0xFEE6,
+ },
+ [0xFEE7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x646 },
+ unicodeslot=0xFEE7,
+ },
+ [0xFEE8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x646 },
+ unicodeslot=0xFEE8,
+ },
+ [0xFEE9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x647 },
+ unicodeslot=0xFEE9,
+ },
+ [0xFEEA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x647 },
+ unicodeslot=0xFEEA,
+ },
+ [0xFEEB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x647 },
+ unicodeslot=0xFEEB,
+ },
+ [0xFEEC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x647 },
+ unicodeslot=0xFEEC,
+ },
+ [0xFEED]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x648 },
+ unicodeslot=0xFEED,
+ },
+ [0xFEEE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x648 },
+ unicodeslot=0xFEEE,
+ },
+ [0xFEEF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x649 },
+ unicodeslot=0xFEEF,
+ },
+ [0xFEF0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x649 },
+ unicodeslot=0xFEF0,
+ },
+ [0xFEF1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x64A },
+ unicodeslot=0xFEF1,
+ },
+ [0xFEF2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x64A },
+ unicodeslot=0xFEF2,
+ },
+ [0xFEF3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x64A },
+ unicodeslot=0xFEF3,
+ },
+ [0xFEF4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x64A },
+ unicodeslot=0xFEF4,
+ },
+ [0xFEF5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x644, 0x622 },
+ unicodeslot=0xFEF5,
+ },
+ [0xFEF6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x622 },
+ unicodeslot=0xFEF6,
+ },
+ [0xFEF7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x644, 0x623 },
+ unicodeslot=0xFEF7,
+ },
+ [0xFEF8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x623 },
+ unicodeslot=0xFEF8,
+ },
+ [0xFEF9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x644, 0x625 },
+ unicodeslot=0xFEF9,
+ },
+ [0xFEFA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x625 },
+ unicodeslot=0xFEFA,
+ },
+ [0xFEFB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x644, 0x627 },
+ unicodeslot=0xFEFB,
+ },
+ [0xFEFC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x644, 0x627 },
+ unicodeslot=0xFEFC,
+ },
+ [0xFEFF]={
+ category="cf",
+ direction="bn",
+ linebreak="wj",
+ unicodeslot=0xFEFF,
+ },
+ [0xFF01]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ specials={ "wide", 0x21 },
+ unicodeslot=0xFF01,
+ },
+ [0xFF02]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x22 },
+ unicodeslot=0xFF02,
+ },
+ [0xFF03]={
+ category="po",
+ direction="et",
+ linebreak="id",
+ specials={ "wide", 0x23 },
+ unicodeslot=0xFF03,
+ },
+ [0xFF04]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ specials={ "wide", 0x24 },
+ unicodeslot=0xFF04,
+ },
+ [0xFF05]={
+ category="po",
+ direction="et",
+ linebreak="po",
+ specials={ "wide", 0x25 },
+ unicodeslot=0xFF05,
+ },
+ [0xFF06]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x26 },
+ unicodeslot=0xFF06,
+ },
+ [0xFF07]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x27 },
+ unicodeslot=0xFF07,
+ },
+ [0xFF08]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0xFF09,
+ specials={ "wide", 0x28 },
+ textclass="open",
+ unicodeslot=0xFF08,
+ },
+ [0xFF09]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFF08,
+ specials={ "wide", 0x29 },
+ textclass="close",
+ unicodeslot=0xFF09,
+ },
+ [0xFF0A]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x2A },
+ unicodeslot=0xFF0A,
+ },
+ [0xFF0B]={
+ category="sm",
+ direction="es",
+ linebreak="id",
+ specials={ "wide", 0x2B },
+ unicodeslot=0xFF0B,
+ },
+ [0xFF0C]={
+ category="po",
+ direction="cs",
+ linebreak="cl",
+ specials={ "wide", 0x2C },
+ unicodeslot=0xFF0C,
+ },
+ [0xFF0D]={
+ category="pd",
+ direction="es",
+ linebreak="id",
+ specials={ "wide", 0x2D },
+ unicodeslot=0xFF0D,
+ },
+ [0xFF0E]={
+ category="po",
+ direction="cs",
+ linebreak="cl",
+ specials={ "wide", 0x2E },
+ unicodeslot=0xFF0E,
+ },
+ [0xFF0F]={
+ category="po",
+ direction="cs",
+ linebreak="id",
+ specials={ "wide", 0x2F },
+ unicodeslot=0xFF0F,
+ },
+ [0xFF10]={
+ category="nd",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x30 },
+ unicodeslot=0xFF10,
+ },
+ [0xFF11]={
+ category="nd",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x31 },
+ unicodeslot=0xFF11,
+ },
+ [0xFF12]={
+ category="nd",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x32 },
+ unicodeslot=0xFF12,
+ },
+ [0xFF13]={
+ category="nd",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x33 },
+ unicodeslot=0xFF13,
+ },
+ [0xFF14]={
+ category="nd",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x34 },
+ unicodeslot=0xFF14,
+ },
+ [0xFF15]={
+ category="nd",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x35 },
+ unicodeslot=0xFF15,
+ },
+ [0xFF16]={
+ category="nd",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x36 },
+ unicodeslot=0xFF16,
+ },
+ [0xFF17]={
+ category="nd",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x37 },
+ unicodeslot=0xFF17,
+ },
+ [0xFF18]={
+ category="nd",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x38 },
+ unicodeslot=0xFF18,
+ },
+ [0xFF19]={
+ category="nd",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x39 },
+ unicodeslot=0xFF19,
+ },
+ [0xFF1A]={
+ category="po",
+ direction="cs",
+ linebreak="ns",
+ specials={ "wide", 0x3A },
+ unicodeslot=0xFF1A,
+ },
+ [0xFF1B]={
+ category="po",
+ direction="on",
+ linebreak="ns",
+ specials={ "wide", 0x3B },
+ unicodeslot=0xFF1B,
+ },
+ [0xFF1C]={
+ category="sm",
+ direction="on",
+ linebreak="id",
+ mirror=0xFF1E,
+ specials={ "wide", 0x3C },
+ textclass="open",
+ unicodeslot=0xFF1C,
+ },
+ [0xFF1D]={
+ category="sm",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x3D },
+ unicodeslot=0xFF1D,
+ },
+ [0xFF1E]={
+ category="sm",
+ direction="on",
+ linebreak="id",
+ mirror=0xFF1C,
+ specials={ "wide", 0x3E },
+ textclass="close",
+ unicodeslot=0xFF1E,
+ },
+ [0xFF1F]={
+ category="po",
+ direction="on",
+ linebreak="ex",
+ specials={ "wide", 0x3F },
+ unicodeslot=0xFF1F,
+ },
+ [0xFF20]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x40 },
+ unicodeslot=0xFF20,
+ },
+ [0xFF21]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x41 },
+ unicodeslot=0xFF21,
+ },
+ [0xFF22]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x42 },
+ unicodeslot=0xFF22,
+ },
+ [0xFF23]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x43 },
+ unicodeslot=0xFF23,
+ },
+ [0xFF24]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x44 },
+ unicodeslot=0xFF24,
+ },
+ [0xFF25]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x45 },
+ unicodeslot=0xFF25,
+ },
+ [0xFF26]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x46 },
+ unicodeslot=0xFF26,
+ },
+ [0xFF27]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x47 },
+ unicodeslot=0xFF27,
+ },
+ [0xFF28]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x48 },
+ unicodeslot=0xFF28,
+ },
+ [0xFF29]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x49 },
+ unicodeslot=0xFF29,
+ },
+ [0xFF2A]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x4A },
+ unicodeslot=0xFF2A,
+ },
+ [0xFF2B]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x4B },
+ unicodeslot=0xFF2B,
+ },
+ [0xFF2C]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x4C },
+ unicodeslot=0xFF2C,
+ },
+ [0xFF2D]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x4D },
+ unicodeslot=0xFF2D,
+ },
+ [0xFF2E]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x4E },
+ unicodeslot=0xFF2E,
+ },
+ [0xFF2F]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x4F },
+ unicodeslot=0xFF2F,
+ },
+ [0xFF30]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x50 },
+ unicodeslot=0xFF30,
+ },
+ [0xFF31]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x51 },
+ unicodeslot=0xFF31,
+ },
+ [0xFF32]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x52 },
+ unicodeslot=0xFF32,
+ },
+ [0xFF33]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x53 },
+ unicodeslot=0xFF33,
+ },
+ [0xFF34]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x54 },
+ unicodeslot=0xFF34,
+ },
+ [0xFF35]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x55 },
+ unicodeslot=0xFF35,
+ },
+ [0xFF36]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x56 },
+ unicodeslot=0xFF36,
+ },
+ [0xFF37]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x57 },
+ unicodeslot=0xFF37,
+ },
+ [0xFF38]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x58 },
+ unicodeslot=0xFF38,
+ },
+ [0xFF39]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x59 },
+ unicodeslot=0xFF39,
+ },
+ [0xFF3A]={
+ category="lu",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x5A },
+ unicodeslot=0xFF3A,
+ },
+ [0xFF3B]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0xFF3D,
+ specials={ "wide", 0x5B },
+ textclass="open",
+ unicodeslot=0xFF3B,
+ },
+ [0xFF3C]={
+ category="po",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x5C },
+ unicodeslot=0xFF3C,
+ },
+ [0xFF3D]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFF3B,
+ specials={ "wide", 0x5D },
+ textclass="close",
+ unicodeslot=0xFF3D,
+ },
+ [0xFF3E]={
+ category="sk",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x5E },
+ unicodeslot=0xFF3E,
+ },
+ [0xFF3F]={
+ category="pc",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x5F },
+ unicodeslot=0xFF3F,
+ },
+ [0xFF40]={
+ category="sk",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x60 },
+ unicodeslot=0xFF40,
+ },
+ [0xFF41]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x61 },
+ unicodeslot=0xFF41,
+ },
+ [0xFF42]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x62 },
+ unicodeslot=0xFF42,
+ },
+ [0xFF43]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x63 },
+ unicodeslot=0xFF43,
+ },
+ [0xFF44]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x64 },
+ unicodeslot=0xFF44,
+ },
+ [0xFF45]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x65 },
+ unicodeslot=0xFF45,
+ },
+ [0xFF46]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x66 },
+ unicodeslot=0xFF46,
+ },
+ [0xFF47]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x67 },
+ unicodeslot=0xFF47,
+ },
+ [0xFF48]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x68 },
+ unicodeslot=0xFF48,
+ },
+ [0xFF49]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x69 },
+ unicodeslot=0xFF49,
+ },
+ [0xFF4A]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x6A },
+ unicodeslot=0xFF4A,
+ },
+ [0xFF4B]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x6B },
+ unicodeslot=0xFF4B,
+ },
+ [0xFF4C]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x6C },
+ unicodeslot=0xFF4C,
+ },
+ [0xFF4D]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x6D },
+ unicodeslot=0xFF4D,
+ },
+ [0xFF4E]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x6E },
+ unicodeslot=0xFF4E,
+ },
+ [0xFF4F]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x6F },
+ unicodeslot=0xFF4F,
+ },
+ [0xFF50]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x70 },
+ unicodeslot=0xFF50,
+ },
+ [0xFF51]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x71 },
+ unicodeslot=0xFF51,
+ },
+ [0xFF52]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x72 },
+ unicodeslot=0xFF52,
+ },
+ [0xFF53]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x73 },
+ unicodeslot=0xFF53,
+ },
+ [0xFF54]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x74 },
+ unicodeslot=0xFF54,
+ },
+ [0xFF55]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x75 },
+ unicodeslot=0xFF55,
+ },
+ [0xFF56]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x76 },
+ unicodeslot=0xFF56,
+ },
+ [0xFF57]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x77 },
+ unicodeslot=0xFF57,
+ },
+ [0xFF58]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x78 },
+ unicodeslot=0xFF58,
+ },
+ [0xFF59]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x79 },
+ unicodeslot=0xFF59,
+ },
+ [0xFF5A]={
+ category="ll",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x7A },
+ unicodeslot=0xFF5A,
+ },
+ [0xFF5B]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0xFF5D,
+ specials={ "wide", 0x7B },
+ textclass="open",
+ unicodeslot=0xFF5B,
+ },
+ [0xFF5C]={
+ category="sm",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x7C },
+ unicodeslot=0xFF5C,
+ },
+ [0xFF5D]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFF5B,
+ specials={ "wide", 0x7D },
+ textclass="close",
+ unicodeslot=0xFF5D,
+ },
+ [0xFF5E]={
+ category="sm",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x7E },
+ unicodeslot=0xFF5E,
+ },
+ [0xFF5F]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0xFF60,
+ specials={ "wide", 0x2985 },
+ textclass="open",
+ unicodeslot=0xFF5F,
+ },
+ [0xFF60]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFF5F,
+ specials={ "wide", 0x2986 },
+ textclass="close",
+ unicodeslot=0xFF60,
+ },
+ [0xFF61]={
+ category="po",
+ direction="on",
+ linebreak="cl",
+ specials={ "narrow", 0x3002 },
+ unicodeslot=0xFF61,
+ },
+ [0xFF62]={
+ category="ps",
+ direction="on",
+ linebreak="op",
+ mirror=0xFF63,
+ specials={ "narrow", 0x300C },
+ textclass="open",
+ unicodeslot=0xFF62,
+ },
+ [0xFF63]={
+ category="pe",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFF62,
+ specials={ "narrow", 0x300D },
+ textclass="close",
+ unicodeslot=0xFF63,
+ },
+ [0xFF64]={
+ category="po",
+ direction="on",
+ linebreak="cl",
+ specials={ "narrow", 0x3001 },
+ unicodeslot=0xFF64,
+ },
+ [0xFF65]={
+ category="po",
+ direction="on",
+ linebreak="ns",
+ specials={ "narrow", 0x30FB },
+ unicodeslot=0xFF65,
+ },
+ [0xFF66]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30F2 },
+ unicodeslot=0xFF66,
+ },
+ [0xFF67]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30A1 },
+ unicodeslot=0xFF67,
+ },
+ [0xFF68]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30A3 },
+ unicodeslot=0xFF68,
+ },
+ [0xFF69]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30A5 },
+ unicodeslot=0xFF69,
+ },
+ [0xFF6A]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30A7 },
+ unicodeslot=0xFF6A,
+ },
+ [0xFF6B]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30A9 },
+ unicodeslot=0xFF6B,
+ },
+ [0xFF6C]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30E3 },
+ unicodeslot=0xFF6C,
+ },
+ [0xFF6D]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30E5 },
+ unicodeslot=0xFF6D,
+ },
+ [0xFF6E]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30E7 },
+ unicodeslot=0xFF6E,
+ },
+ [0xFF6F]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30C3 },
+ unicodeslot=0xFF6F,
+ },
+ [0xFF70]={
+ category="lm",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30FC },
+ unicodeslot=0xFF70,
+ },
+ [0xFF71]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30A2 },
+ unicodeslot=0xFF71,
+ },
+ [0xFF72]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30A4 },
+ unicodeslot=0xFF72,
+ },
+ [0xFF73]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30A6 },
+ unicodeslot=0xFF73,
+ },
+ [0xFF74]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30A8 },
+ unicodeslot=0xFF74,
+ },
+ [0xFF75]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30AA },
+ unicodeslot=0xFF75,
+ },
+ [0xFF76]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30AB },
+ unicodeslot=0xFF76,
+ },
+ [0xFF77]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30AD },
+ unicodeslot=0xFF77,
+ },
+ [0xFF78]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30AF },
+ unicodeslot=0xFF78,
+ },
+ [0xFF79]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30B1 },
+ unicodeslot=0xFF79,
+ },
+ [0xFF7A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30B3 },
+ unicodeslot=0xFF7A,
+ },
+ [0xFF7B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30B5 },
+ unicodeslot=0xFF7B,
+ },
+ [0xFF7C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30B7 },
+ unicodeslot=0xFF7C,
+ },
+ [0xFF7D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30B9 },
+ unicodeslot=0xFF7D,
+ },
+ [0xFF7E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30BB },
+ unicodeslot=0xFF7E,
+ },
+ [0xFF7F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30BD },
+ unicodeslot=0xFF7F,
+ },
+ [0xFF80]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30BF },
+ unicodeslot=0xFF80,
+ },
+ [0xFF81]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30C1 },
+ unicodeslot=0xFF81,
+ },
+ [0xFF82]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30C4 },
+ unicodeslot=0xFF82,
+ },
+ [0xFF83]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30C6 },
+ unicodeslot=0xFF83,
+ },
+ [0xFF84]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30C8 },
+ unicodeslot=0xFF84,
+ },
+ [0xFF85]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30CA },
+ unicodeslot=0xFF85,
+ },
+ [0xFF86]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30CB },
+ unicodeslot=0xFF86,
+ },
+ [0xFF87]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30CC },
+ unicodeslot=0xFF87,
+ },
+ [0xFF88]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30CD },
+ unicodeslot=0xFF88,
+ },
+ [0xFF89]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30CE },
+ unicodeslot=0xFF89,
+ },
+ [0xFF8A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30CF },
+ unicodeslot=0xFF8A,
+ },
+ [0xFF8B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30D2 },
+ unicodeslot=0xFF8B,
+ },
+ [0xFF8C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30D5 },
+ unicodeslot=0xFF8C,
+ },
+ [0xFF8D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30D8 },
+ unicodeslot=0xFF8D,
+ },
+ [0xFF8E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30DB },
+ unicodeslot=0xFF8E,
+ },
+ [0xFF8F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30DE },
+ unicodeslot=0xFF8F,
+ },
+ [0xFF90]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30DF },
+ unicodeslot=0xFF90,
+ },
+ [0xFF91]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30E0 },
+ unicodeslot=0xFF91,
+ },
+ [0xFF92]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30E1 },
+ unicodeslot=0xFF92,
+ },
+ [0xFF93]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30E2 },
+ unicodeslot=0xFF93,
+ },
+ [0xFF94]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30E4 },
+ unicodeslot=0xFF94,
+ },
+ [0xFF95]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30E6 },
+ unicodeslot=0xFF95,
+ },
+ [0xFF96]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30E8 },
+ unicodeslot=0xFF96,
+ },
+ [0xFF97]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30E9 },
+ unicodeslot=0xFF97,
+ },
+ [0xFF98]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30EA },
+ unicodeslot=0xFF98,
+ },
+ [0xFF99]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30EB },
+ unicodeslot=0xFF99,
+ },
+ [0xFF9A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30EC },
+ unicodeslot=0xFF9A,
+ },
+ [0xFF9B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30ED },
+ unicodeslot=0xFF9B,
+ },
+ [0xFF9C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30EF },
+ unicodeslot=0xFF9C,
+ },
+ [0xFF9D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x30F3 },
+ unicodeslot=0xFF9D,
+ },
+ [0xFF9E]={
+ category="lm",
+ direction="l",
+ linebreak="ns",
+ specials={ "narrow", 0x3099 },
+ unicodeslot=0xFF9E,
+ },
+ [0xFF9F]={
+ category="lm",
+ direction="l",
+ linebreak="ns",
+ specials={ "narrow", 0x309A },
+ unicodeslot=0xFF9F,
+ },
+ [0xFFA0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3164 },
+ unicodeslot=0xFFA0,
+ },
+ [0xFFA1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3131 },
+ unicodeslot=0xFFA1,
+ },
+ [0xFFA2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3132 },
+ unicodeslot=0xFFA2,
+ },
+ [0xFFA3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3133 },
+ unicodeslot=0xFFA3,
+ },
+ [0xFFA4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3134 },
+ unicodeslot=0xFFA4,
+ },
+ [0xFFA5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3135 },
+ unicodeslot=0xFFA5,
+ },
+ [0xFFA6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3136 },
+ unicodeslot=0xFFA6,
+ },
+ [0xFFA7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3137 },
+ unicodeslot=0xFFA7,
+ },
+ [0xFFA8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3138 },
+ unicodeslot=0xFFA8,
+ },
+ [0xFFA9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3139 },
+ unicodeslot=0xFFA9,
+ },
+ [0xFFAA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x313A },
+ unicodeslot=0xFFAA,
+ },
+ [0xFFAB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x313B },
+ unicodeslot=0xFFAB,
+ },
+ [0xFFAC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x313C },
+ unicodeslot=0xFFAC,
+ },
+ [0xFFAD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x313D },
+ unicodeslot=0xFFAD,
+ },
+ [0xFFAE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x313E },
+ unicodeslot=0xFFAE,
+ },
+ [0xFFAF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x313F },
+ unicodeslot=0xFFAF,
+ },
+ [0xFFB0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3140 },
+ unicodeslot=0xFFB0,
+ },
+ [0xFFB1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3141 },
+ unicodeslot=0xFFB1,
+ },
+ [0xFFB2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3142 },
+ unicodeslot=0xFFB2,
+ },
+ [0xFFB3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3143 },
+ unicodeslot=0xFFB3,
+ },
+ [0xFFB4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3144 },
+ unicodeslot=0xFFB4,
+ },
+ [0xFFB5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3145 },
+ unicodeslot=0xFFB5,
+ },
+ [0xFFB6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3146 },
+ unicodeslot=0xFFB6,
+ },
+ [0xFFB7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3147 },
+ unicodeslot=0xFFB7,
+ },
+ [0xFFB8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3148 },
+ unicodeslot=0xFFB8,
+ },
+ [0xFFB9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3149 },
+ unicodeslot=0xFFB9,
+ },
+ [0xFFBA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x314A },
+ unicodeslot=0xFFBA,
+ },
+ [0xFFBB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x314B },
+ unicodeslot=0xFFBB,
+ },
+ [0xFFBC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x314C },
+ unicodeslot=0xFFBC,
+ },
+ [0xFFBD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x314D },
+ unicodeslot=0xFFBD,
+ },
+ [0xFFBE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x314E },
+ unicodeslot=0xFFBE,
+ },
+ [0xFFC2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x314F },
+ unicodeslot=0xFFC2,
+ },
+ [0xFFC3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3150 },
+ unicodeslot=0xFFC3,
+ },
+ [0xFFC4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3151 },
+ unicodeslot=0xFFC4,
+ },
+ [0xFFC5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3152 },
+ unicodeslot=0xFFC5,
+ },
+ [0xFFC6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3153 },
+ unicodeslot=0xFFC6,
+ },
+ [0xFFC7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3154 },
+ unicodeslot=0xFFC7,
+ },
+ [0xFFCA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3155 },
+ unicodeslot=0xFFCA,
+ },
+ [0xFFCB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3156 },
+ unicodeslot=0xFFCB,
+ },
+ [0xFFCC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3157 },
+ unicodeslot=0xFFCC,
+ },
+ [0xFFCD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3158 },
+ unicodeslot=0xFFCD,
+ },
+ [0xFFCE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3159 },
+ unicodeslot=0xFFCE,
+ },
+ [0xFFCF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x315A },
+ unicodeslot=0xFFCF,
+ },
+ [0xFFD2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x315B },
+ unicodeslot=0xFFD2,
+ },
+ [0xFFD3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x315C },
+ unicodeslot=0xFFD3,
+ },
+ [0xFFD4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x315D },
+ unicodeslot=0xFFD4,
+ },
+ [0xFFD5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x315E },
+ unicodeslot=0xFFD5,
+ },
+ [0xFFD6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x315F },
+ unicodeslot=0xFFD6,
+ },
+ [0xFFD7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3160 },
+ unicodeslot=0xFFD7,
+ },
+ [0xFFDA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3161 },
+ unicodeslot=0xFFDA,
+ },
+ [0xFFDB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3162 },
+ unicodeslot=0xFFDB,
+ },
+ [0xFFDC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "narrow", 0x3163 },
+ unicodeslot=0xFFDC,
+ },
+ [0xFFE0]={
+ category="sc",
+ direction="et",
+ linebreak="po",
+ specials={ "wide", 0xA2 },
+ unicodeslot=0xFFE0,
+ },
+ [0xFFE1]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ specials={ "wide", 0xA3 },
+ unicodeslot=0xFFE1,
+ },
+ [0xFFE2]={
+ category="sm",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0xAC },
+ unicodeslot=0xFFE2,
+ },
+ [0xFFE3]={
+ category="sk",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0xAF },
+ unicodeslot=0xFFE3,
+ },
+ [0xFFE4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0xA6 },
+ unicodeslot=0xFFE4,
+ },
+ [0xFFE5]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ specials={ "wide", 0xA5 },
+ unicodeslot=0xFFE5,
+ },
+ [0xFFE6]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ specials={ "wide", 0x20A9 },
+ unicodeslot=0xFFE6,
+ },
+ [0xFFE8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x2502 },
+ unicodeslot=0xFFE8,
+ },
+ [0xFFE9]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x2190 },
+ unicodeslot=0xFFE9,
+ },
+ [0xFFEA]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x2191 },
+ unicodeslot=0xFFEA,
+ },
+ [0xFFEB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x2192 },
+ unicodeslot=0xFFEB,
+ },
+ [0xFFEC]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x2193 },
+ unicodeslot=0xFFEC,
+ },
+ [0xFFED]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x25A0 },
+ unicodeslot=0xFFED,
+ },
+ [0xFFEE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x25CB },
+ unicodeslot=0xFFEE,
+ },
+ [0xFFF9]={
+ category="cf",
+ direction="on",
+ linebreak="cm",
+ unicodeslot=0xFFF9,
+ },
+ [0xFFFA]={
+ category="cf",
+ direction="on",
+ linebreak="cm",
+ unicodeslot=0xFFFA,
+ },
+ [0xFFFB]={
+ category="cf",
+ direction="on",
+ linebreak="cm",
+ unicodeslot=0xFFFB,
+ },
+ [0xFFFC]={
+ category="so",
+ direction="on",
+ linebreak="cb",
+ unicodeslot=0xFFFC,
+ },
+ [0xFFFD]={
+ category="so",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0xFFFD,
+ },
+ [0x10000]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10000,
+ },
+ [0x10001]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10001,
+ },
+ [0x10002]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10002,
+ },
+ [0x10003]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10003,
+ },
+ [0x10004]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10004,
+ },
+ [0x10005]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10005,
+ },
+ [0x10006]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10006,
+ },
+ [0x10007]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10007,
+ },
+ [0x10008]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10008,
+ },
+ [0x10009]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10009,
+ },
+ [0x1000A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1000A,
+ },
+ [0x1000B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1000B,
+ },
+ [0x1000D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1000D,
+ },
+ [0x1000E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1000E,
+ },
+ [0x1000F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1000F,
+ },
+ [0x10010]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10010,
+ },
+ [0x10011]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10011,
+ },
+ [0x10012]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10012,
+ },
+ [0x10013]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10013,
+ },
+ [0x10014]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10014,
+ },
+ [0x10015]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10015,
+ },
+ [0x10016]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10016,
+ },
+ [0x10017]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10017,
+ },
+ [0x10018]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10018,
+ },
+ [0x10019]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10019,
+ },
+ [0x1001A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1001A,
+ },
+ [0x1001B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1001B,
+ },
+ [0x1001C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1001C,
+ },
+ [0x1001D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1001D,
+ },
+ [0x1001E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1001E,
+ },
+ [0x1001F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1001F,
+ },
+ [0x10020]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10020,
+ },
+ [0x10021]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10021,
+ },
+ [0x10022]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10022,
+ },
+ [0x10023]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10023,
+ },
+ [0x10024]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10024,
+ },
+ [0x10025]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10025,
+ },
+ [0x10026]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10026,
+ },
+ [0x10028]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10028,
+ },
+ [0x10029]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10029,
+ },
+ [0x1002A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1002A,
+ },
+ [0x1002B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1002B,
+ },
+ [0x1002C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1002C,
+ },
+ [0x1002D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1002D,
+ },
+ [0x1002E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1002E,
+ },
+ [0x1002F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1002F,
+ },
+ [0x10030]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10030,
+ },
+ [0x10031]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10031,
+ },
+ [0x10032]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10032,
+ },
+ [0x10033]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10033,
+ },
+ [0x10034]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10034,
+ },
+ [0x10035]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10035,
+ },
+ [0x10036]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10036,
+ },
+ [0x10037]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10037,
+ },
+ [0x10038]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10038,
+ },
+ [0x10039]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10039,
+ },
+ [0x1003A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1003A,
+ },
+ [0x1003C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1003C,
+ },
+ [0x1003D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1003D,
+ },
+ [0x1003F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1003F,
+ },
+ [0x10040]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10040,
+ },
+ [0x10041]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10041,
+ },
+ [0x10042]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10042,
+ },
+ [0x10043]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10043,
+ },
+ [0x10044]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10044,
+ },
+ [0x10045]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10045,
+ },
+ [0x10046]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10046,
+ },
+ [0x10047]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10047,
+ },
+ [0x10048]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10048,
+ },
+ [0x10049]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10049,
+ },
+ [0x1004A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1004A,
+ },
+ [0x1004B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1004B,
+ },
+ [0x1004C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1004C,
+ },
+ [0x1004D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1004D,
+ },
+ [0x10050]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10050,
+ },
+ [0x10051]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10051,
+ },
+ [0x10052]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10052,
+ },
+ [0x10053]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10053,
+ },
+ [0x10054]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10054,
+ },
+ [0x10055]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10055,
+ },
+ [0x10056]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10056,
+ },
+ [0x10057]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10057,
+ },
+ [0x10058]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10058,
+ },
+ [0x10059]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10059,
+ },
+ [0x1005A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1005A,
+ },
+ [0x1005B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1005B,
+ },
+ [0x1005C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1005C,
+ },
+ [0x1005D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1005D,
+ },
+ [0x10080]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10080,
+ },
+ [0x10081]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10081,
+ },
+ [0x10082]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10082,
+ },
+ [0x10083]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10083,
+ },
+ [0x10084]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10084,
+ },
+ [0x10085]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10085,
+ },
+ [0x10086]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10086,
+ },
+ [0x10087]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10087,
+ },
+ [0x10088]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10088,
+ },
+ [0x10089]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10089,
+ },
+ [0x1008A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1008A,
+ },
+ [0x1008B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1008B,
+ },
+ [0x1008C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1008C,
+ },
+ [0x1008D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1008D,
+ },
+ [0x1008E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1008E,
+ },
+ [0x1008F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1008F,
+ },
+ [0x10090]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10090,
+ },
+ [0x10091]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10091,
+ },
+ [0x10092]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10092,
+ },
+ [0x10093]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10093,
+ },
+ [0x10094]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10094,
+ },
+ [0x10095]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10095,
+ },
+ [0x10096]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10096,
+ },
+ [0x10097]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10097,
+ },
+ [0x10098]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10098,
+ },
+ [0x10099]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10099,
+ },
+ [0x1009A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1009A,
+ },
+ [0x1009B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1009B,
+ },
+ [0x1009C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1009C,
+ },
+ [0x1009D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1009D,
+ },
+ [0x1009E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1009E,
+ },
+ [0x1009F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1009F,
+ },
+ [0x100A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A0,
+ },
+ [0x100A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A1,
+ },
+ [0x100A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A2,
+ },
+ [0x100A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A3,
+ },
+ [0x100A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A4,
+ },
+ [0x100A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A5,
+ },
+ [0x100A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A6,
+ },
+ [0x100A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A7,
+ },
+ [0x100A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A8,
+ },
+ [0x100A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A9,
+ },
+ [0x100AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100AA,
+ },
+ [0x100AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100AB,
+ },
+ [0x100AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100AC,
+ },
+ [0x100AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100AD,
+ },
+ [0x100AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100AE,
+ },
+ [0x100AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100AF,
+ },
+ [0x100B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B0,
+ },
+ [0x100B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B1,
+ },
+ [0x100B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B2,
+ },
+ [0x100B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B3,
+ },
+ [0x100B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B4,
+ },
+ [0x100B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B5,
+ },
+ [0x100B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B6,
+ },
+ [0x100B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B7,
+ },
+ [0x100B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B8,
+ },
+ [0x100B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B9,
+ },
+ [0x100BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100BA,
+ },
+ [0x100BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100BB,
+ },
+ [0x100BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100BC,
+ },
+ [0x100BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100BD,
+ },
+ [0x100BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100BE,
+ },
+ [0x100BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100BF,
+ },
+ [0x100C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C0,
+ },
+ [0x100C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C1,
+ },
+ [0x100C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C2,
+ },
+ [0x100C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C3,
+ },
+ [0x100C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C4,
+ },
+ [0x100C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C5,
+ },
+ [0x100C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C6,
+ },
+ [0x100C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C7,
+ },
+ [0x100C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C8,
+ },
+ [0x100C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C9,
+ },
+ [0x100CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100CA,
+ },
+ [0x100CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100CB,
+ },
+ [0x100CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100CC,
+ },
+ [0x100CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100CD,
+ },
+ [0x100CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100CE,
+ },
+ [0x100CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100CF,
+ },
+ [0x100D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D0,
+ },
+ [0x100D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D1,
+ },
+ [0x100D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D2,
+ },
+ [0x100D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D3,
+ },
+ [0x100D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D4,
+ },
+ [0x100D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D5,
+ },
+ [0x100D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D6,
+ },
+ [0x100D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D7,
+ },
+ [0x100D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D8,
+ },
+ [0x100D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D9,
+ },
+ [0x100DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100DA,
+ },
+ [0x100DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100DB,
+ },
+ [0x100DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100DC,
+ },
+ [0x100DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100DD,
+ },
+ [0x100DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100DE,
+ },
+ [0x100DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100DF,
+ },
+ [0x100E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E0,
+ },
+ [0x100E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E1,
+ },
+ [0x100E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E2,
+ },
+ [0x100E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E3,
+ },
+ [0x100E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E4,
+ },
+ [0x100E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E5,
+ },
+ [0x100E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E6,
+ },
+ [0x100E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E7,
+ },
+ [0x100E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E8,
+ },
+ [0x100E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E9,
+ },
+ [0x100EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100EA,
+ },
+ [0x100EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100EB,
+ },
+ [0x100EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100EC,
+ },
+ [0x100ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100ED,
+ },
+ [0x100EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100EE,
+ },
+ [0x100EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100EF,
+ },
+ [0x100F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F0,
+ },
+ [0x100F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F1,
+ },
+ [0x100F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F2,
+ },
+ [0x100F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F3,
+ },
+ [0x100F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F4,
+ },
+ [0x100F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F5,
+ },
+ [0x100F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F6,
+ },
+ [0x100F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F7,
+ },
+ [0x100F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F8,
+ },
+ [0x100F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F9,
+ },
+ [0x100FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100FA,
+ },
+ [0x10100]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x10100,
+ },
+ [0x10101]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10101,
+ },
+ [0x10102]={
+ category="so",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x10102,
+ },
+ [0x10107]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10107,
+ },
+ [0x10108]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10108,
+ },
+ [0x10109]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10109,
+ },
+ [0x1010A]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1010A,
+ },
+ [0x1010B]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1010B,
+ },
+ [0x1010C]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1010C,
+ },
+ [0x1010D]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1010D,
+ },
+ [0x1010E]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1010E,
+ },
+ [0x1010F]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1010F,
+ },
+ [0x10110]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10110,
+ },
+ [0x10111]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10111,
+ },
+ [0x10112]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10112,
+ },
+ [0x10113]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10113,
+ },
+ [0x10114]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10114,
+ },
+ [0x10115]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10115,
+ },
+ [0x10116]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10116,
+ },
+ [0x10117]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10117,
+ },
+ [0x10118]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10118,
+ },
+ [0x10119]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10119,
+ },
+ [0x1011A]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1011A,
+ },
+ [0x1011B]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1011B,
+ },
+ [0x1011C]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1011C,
+ },
+ [0x1011D]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1011D,
+ },
+ [0x1011E]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1011E,
+ },
+ [0x1011F]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1011F,
+ },
+ [0x10120]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10120,
+ },
+ [0x10121]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10121,
+ },
+ [0x10122]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10122,
+ },
+ [0x10123]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10123,
+ },
+ [0x10124]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10124,
+ },
+ [0x10125]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10125,
+ },
+ [0x10126]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10126,
+ },
+ [0x10127]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10127,
+ },
+ [0x10128]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10128,
+ },
+ [0x10129]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10129,
+ },
+ [0x1012A]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1012A,
+ },
+ [0x1012B]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1012B,
+ },
+ [0x1012C]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1012C,
+ },
+ [0x1012D]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1012D,
+ },
+ [0x1012E]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1012E,
+ },
+ [0x1012F]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1012F,
+ },
+ [0x10130]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10130,
+ },
+ [0x10131]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10131,
+ },
+ [0x10132]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10132,
+ },
+ [0x10133]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10133,
+ },
+ [0x10137]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10137,
+ },
+ [0x10138]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10138,
+ },
+ [0x10139]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10139,
+ },
+ [0x1013A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1013A,
+ },
+ [0x1013B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1013B,
+ },
+ [0x1013C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1013C,
+ },
+ [0x1013D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1013D,
+ },
+ [0x1013E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1013E,
+ },
+ [0x1013F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1013F,
+ },
+ [0x10140]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10140,
+ },
+ [0x10141]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10141,
+ },
+ [0x10142]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10142,
+ },
+ [0x10143]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10143,
+ },
+ [0x10144]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10144,
+ },
+ [0x10145]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10145,
+ },
+ [0x10146]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10146,
+ },
+ [0x10147]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10147,
+ },
+ [0x10148]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10148,
+ },
+ [0x10149]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10149,
+ },
+ [0x1014A]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1014A,
+ },
+ [0x1014B]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1014B,
+ },
+ [0x1014C]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1014C,
+ },
+ [0x1014D]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1014D,
+ },
+ [0x1014E]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1014E,
+ },
+ [0x1014F]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1014F,
+ },
+ [0x10150]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10150,
+ },
+ [0x10151]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10151,
+ },
+ [0x10152]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10152,
+ },
+ [0x10153]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10153,
+ },
+ [0x10154]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10154,
+ },
+ [0x10155]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10155,
+ },
+ [0x10156]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10156,
+ },
+ [0x10157]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10157,
+ },
+ [0x10158]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10158,
+ },
+ [0x10159]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10159,
+ },
+ [0x1015A]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1015A,
+ },
+ [0x1015B]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1015B,
+ },
+ [0x1015C]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1015C,
+ },
+ [0x1015D]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1015D,
+ },
+ [0x1015E]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1015E,
+ },
+ [0x1015F]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1015F,
+ },
+ [0x10160]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10160,
+ },
+ [0x10161]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10161,
+ },
+ [0x10162]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10162,
+ },
+ [0x10163]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10163,
+ },
+ [0x10164]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10164,
+ },
+ [0x10165]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10165,
+ },
+ [0x10166]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10166,
+ },
+ [0x10167]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10167,
+ },
+ [0x10168]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10168,
+ },
+ [0x10169]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10169,
+ },
+ [0x1016A]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1016A,
+ },
+ [0x1016B]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1016B,
+ },
+ [0x1016C]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1016C,
+ },
+ [0x1016D]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1016D,
+ },
+ [0x1016E]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1016E,
+ },
+ [0x1016F]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1016F,
+ },
+ [0x10170]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10170,
+ },
+ [0x10171]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10171,
+ },
+ [0x10172]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10172,
+ },
+ [0x10173]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10173,
+ },
+ [0x10174]={
+ category="nl",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10174,
+ },
+ [0x10175]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10175,
+ },
+ [0x10176]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10176,
+ },
+ [0x10177]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10177,
+ },
+ [0x10178]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10178,
+ },
+ [0x10179]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10179,
+ },
+ [0x1017A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1017A,
+ },
+ [0x1017B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1017B,
+ },
+ [0x1017C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1017C,
+ },
+ [0x1017D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1017D,
+ },
+ [0x1017E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1017E,
+ },
+ [0x1017F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1017F,
+ },
+ [0x10180]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10180,
+ },
+ [0x10181]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10181,
+ },
+ [0x10182]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10182,
+ },
+ [0x10183]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10183,
+ },
+ [0x10184]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10184,
+ },
+ [0x10185]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10185,
+ },
+ [0x10186]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10186,
+ },
+ [0x10187]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10187,
+ },
+ [0x10188]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10188,
+ },
+ [0x10189]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10189,
+ },
+ [0x1018A]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1018A,
+ },
+ [0x1018B]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1018B,
+ },
+ [0x1018C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1018C,
+ },
+ [0x1018D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1018D,
+ },
+ [0x1018E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1018E,
+ },
+ [0x10190]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10190,
+ },
+ [0x10191]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10191,
+ },
+ [0x10192]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10192,
+ },
+ [0x10193]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10193,
+ },
+ [0x10194]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10194,
+ },
+ [0x10195]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10195,
+ },
+ [0x10196]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10196,
+ },
+ [0x10197]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10197,
+ },
+ [0x10198]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10198,
+ },
+ [0x10199]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10199,
+ },
+ [0x1019A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1019A,
+ },
+ [0x1019B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1019B,
+ },
+ [0x101A0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x101A0,
+ },
+ [0x101D0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D0,
+ },
+ [0x101D1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D1,
+ },
+ [0x101D2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D2,
+ },
+ [0x101D3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D3,
+ },
+ [0x101D4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D4,
+ },
+ [0x101D5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D5,
+ },
+ [0x101D6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D6,
+ },
+ [0x101D7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D7,
+ },
+ [0x101D8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D8,
+ },
+ [0x101D9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D9,
+ },
+ [0x101DA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101DA,
+ },
+ [0x101DB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101DB,
+ },
+ [0x101DC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101DC,
+ },
+ [0x101DD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101DD,
+ },
+ [0x101DE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101DE,
+ },
+ [0x101DF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101DF,
+ },
+ [0x101E0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E0,
+ },
+ [0x101E1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E1,
+ },
+ [0x101E2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E2,
+ },
+ [0x101E3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E3,
+ },
+ [0x101E4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E4,
+ },
+ [0x101E5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E5,
+ },
+ [0x101E6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E6,
+ },
+ [0x101E7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E7,
+ },
+ [0x101E8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E8,
+ },
+ [0x101E9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E9,
+ },
+ [0x101EA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101EA,
+ },
+ [0x101EB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101EB,
+ },
+ [0x101EC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101EC,
+ },
+ [0x101ED]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101ED,
+ },
+ [0x101EE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101EE,
+ },
+ [0x101EF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101EF,
+ },
+ [0x101F0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F0,
+ },
+ [0x101F1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F1,
+ },
+ [0x101F2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F2,
+ },
+ [0x101F3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F3,
+ },
+ [0x101F4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F4,
+ },
+ [0x101F5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F5,
+ },
+ [0x101F6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F6,
+ },
+ [0x101F7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F7,
+ },
+ [0x101F8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F8,
+ },
+ [0x101F9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F9,
+ },
+ [0x101FA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101FA,
+ },
+ [0x101FB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101FB,
+ },
+ [0x101FC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101FC,
+ },
+ [0x101FD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x101FD,
+ },
+ [0x10280]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10280,
+ },
+ [0x10281]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10281,
+ },
+ [0x10282]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10282,
+ },
+ [0x10283]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10283,
+ },
+ [0x10284]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10284,
+ },
+ [0x10285]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10285,
+ },
+ [0x10286]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10286,
+ },
+ [0x10287]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10287,
+ },
+ [0x10288]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10288,
+ },
+ [0x10289]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10289,
+ },
+ [0x1028A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1028A,
+ },
+ [0x1028B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1028B,
+ },
+ [0x1028C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1028C,
+ },
+ [0x1028D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1028D,
+ },
+ [0x1028E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1028E,
+ },
+ [0x1028F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1028F,
+ },
+ [0x10290]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10290,
+ },
+ [0x10291]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10291,
+ },
+ [0x10292]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10292,
+ },
+ [0x10293]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10293,
+ },
+ [0x10294]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10294,
+ },
+ [0x10295]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10295,
+ },
+ [0x10296]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10296,
+ },
+ [0x10297]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10297,
+ },
+ [0x10298]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10298,
+ },
+ [0x10299]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10299,
+ },
+ [0x1029A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1029A,
+ },
+ [0x1029B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1029B,
+ },
+ [0x1029C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1029C,
+ },
+ [0x102A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A0,
+ },
+ [0x102A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A1,
+ },
+ [0x102A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A2,
+ },
+ [0x102A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A3,
+ },
+ [0x102A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A4,
+ },
+ [0x102A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A5,
+ },
+ [0x102A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A6,
+ },
+ [0x102A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A7,
+ },
+ [0x102A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A8,
+ },
+ [0x102A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A9,
+ },
+ [0x102AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102AA,
+ },
+ [0x102AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102AB,
+ },
+ [0x102AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102AC,
+ },
+ [0x102AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102AD,
+ },
+ [0x102AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102AE,
+ },
+ [0x102AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102AF,
+ },
+ [0x102B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B0,
+ },
+ [0x102B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B1,
+ },
+ [0x102B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B2,
+ },
+ [0x102B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B3,
+ },
+ [0x102B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B4,
+ },
+ [0x102B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B5,
+ },
+ [0x102B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B6,
+ },
+ [0x102B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B7,
+ },
+ [0x102B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B8,
+ },
+ [0x102B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B9,
+ },
+ [0x102BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102BA,
+ },
+ [0x102BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102BB,
+ },
+ [0x102BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102BC,
+ },
+ [0x102BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102BD,
+ },
+ [0x102BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102BE,
+ },
+ [0x102BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102BF,
+ },
+ [0x102C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C0,
+ },
+ [0x102C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C1,
+ },
+ [0x102C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C2,
+ },
+ [0x102C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C3,
+ },
+ [0x102C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C4,
+ },
+ [0x102C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C5,
+ },
+ [0x102C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C6,
+ },
+ [0x102C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C7,
+ },
+ [0x102C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C8,
+ },
+ [0x102C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C9,
+ },
+ [0x102CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102CA,
+ },
+ [0x102CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102CB,
+ },
+ [0x102CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102CC,
+ },
+ [0x102CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102CD,
+ },
+ [0x102CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102CE,
+ },
+ [0x102CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102CF,
+ },
+ [0x102D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102D0,
+ },
+ [0x102E0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x102E0,
+ },
+ [0x102E1]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102E1,
+ },
+ [0x102E2]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102E2,
+ },
+ [0x102E3]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102E3,
+ },
+ [0x102E4]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102E4,
+ },
+ [0x102E5]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102E5,
+ },
+ [0x102E6]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102E6,
+ },
+ [0x102E7]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102E7,
+ },
+ [0x102E8]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102E8,
+ },
+ [0x102E9]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102E9,
+ },
+ [0x102EA]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102EA,
+ },
+ [0x102EB]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102EB,
+ },
+ [0x102EC]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102EC,
+ },
+ [0x102ED]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102ED,
+ },
+ [0x102EE]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102EE,
+ },
+ [0x102EF]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102EF,
+ },
+ [0x102F0]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102F0,
+ },
+ [0x102F1]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102F1,
+ },
+ [0x102F2]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102F2,
+ },
+ [0x102F3]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102F3,
+ },
+ [0x102F4]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102F4,
+ },
+ [0x102F5]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102F5,
+ },
+ [0x102F6]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102F6,
+ },
+ [0x102F7]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102F7,
+ },
+ [0x102F8]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102F8,
+ },
+ [0x102F9]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102F9,
+ },
+ [0x102FA]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102FA,
+ },
+ [0x102FB]={
+ category="no",
+ direction="en",
+ linebreak="al",
+ unicodeslot=0x102FB,
+ },
+ [0x10300]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10300,
+ },
+ [0x10301]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10301,
+ },
+ [0x10302]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10302,
+ },
+ [0x10303]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10303,
+ },
+ [0x10304]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10304,
+ },
+ [0x10305]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10305,
+ },
+ [0x10306]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10306,
+ },
+ [0x10307]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10307,
+ },
+ [0x10308]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10308,
+ },
+ [0x10309]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10309,
+ },
+ [0x1030A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1030A,
+ },
+ [0x1030B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1030B,
+ },
+ [0x1030C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1030C,
+ },
+ [0x1030D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1030D,
+ },
+ [0x1030E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1030E,
+ },
+ [0x1030F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1030F,
+ },
+ [0x10310]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10310,
+ },
+ [0x10311]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10311,
+ },
+ [0x10312]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10312,
+ },
+ [0x10313]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10313,
+ },
+ [0x10314]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10314,
+ },
+ [0x10315]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10315,
+ },
+ [0x10316]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10316,
+ },
+ [0x10317]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10317,
+ },
+ [0x10318]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10318,
+ },
+ [0x10319]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10319,
+ },
+ [0x1031A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1031A,
+ },
+ [0x1031B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1031B,
+ },
+ [0x1031C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1031C,
+ },
+ [0x1031D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1031D,
+ },
+ [0x1031E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1031E,
+ },
+ [0x1031F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1031F,
+ },
+ [0x10320]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10320,
+ },
+ [0x10321]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10321,
+ },
+ [0x10322]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10322,
+ },
+ [0x10323]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10323,
+ },
+ [0x1032D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1032D,
+ },
+ [0x1032E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1032E,
+ },
+ [0x1032F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1032F,
+ },
+ [0x10330]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10330,
+ },
+ [0x10331]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10331,
+ },
+ [0x10332]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10332,
+ },
+ [0x10333]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10333,
+ },
+ [0x10334]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10334,
+ },
+ [0x10335]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10335,
+ },
+ [0x10336]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10336,
+ },
+ [0x10337]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10337,
+ },
+ [0x10338]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10338,
+ },
+ [0x10339]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10339,
+ },
+ [0x1033A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1033A,
+ },
+ [0x1033B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1033B,
+ },
+ [0x1033C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1033C,
+ },
+ [0x1033D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1033D,
+ },
+ [0x1033E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1033E,
+ },
+ [0x1033F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1033F,
+ },
+ [0x10340]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10340,
+ },
+ [0x10341]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10341,
+ },
+ [0x10342]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10342,
+ },
+ [0x10343]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10343,
+ },
+ [0x10344]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10344,
+ },
+ [0x10345]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10345,
+ },
+ [0x10346]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10346,
+ },
+ [0x10347]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10347,
+ },
+ [0x10348]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10348,
+ },
+ [0x10349]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10349,
+ },
+ [0x1034A]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1034A,
+ },
+ [0x10350]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10350,
+ },
+ [0x10351]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10351,
+ },
+ [0x10352]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10352,
+ },
+ [0x10353]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10353,
+ },
+ [0x10354]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10354,
+ },
+ [0x10355]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10355,
+ },
+ [0x10356]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10356,
+ },
+ [0x10357]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10357,
+ },
+ [0x10358]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10358,
+ },
+ [0x10359]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10359,
+ },
+ [0x1035A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1035A,
+ },
+ [0x1035B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1035B,
+ },
+ [0x1035C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1035C,
+ },
+ [0x1035D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1035D,
+ },
+ [0x1035E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1035E,
+ },
+ [0x1035F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1035F,
+ },
+ [0x10360]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10360,
+ },
+ [0x10361]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10361,
+ },
+ [0x10362]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10362,
+ },
+ [0x10363]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10363,
+ },
+ [0x10364]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10364,
+ },
+ [0x10365]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10365,
+ },
+ [0x10366]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10366,
+ },
+ [0x10367]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10367,
+ },
+ [0x10368]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10368,
+ },
+ [0x10369]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10369,
+ },
+ [0x1036A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1036A,
+ },
+ [0x1036B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1036B,
+ },
+ [0x1036C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1036C,
+ },
+ [0x1036D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1036D,
+ },
+ [0x1036E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1036E,
+ },
+ [0x1036F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1036F,
+ },
+ [0x10370]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10370,
+ },
+ [0x10371]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10371,
+ },
+ [0x10372]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10372,
+ },
+ [0x10373]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10373,
+ },
+ [0x10374]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10374,
+ },
+ [0x10375]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10375,
+ },
+ [0x10376]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10376,
+ },
+ [0x10377]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10377,
+ },
+ [0x10378]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10378,
+ },
+ [0x10379]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10379,
+ },
+ [0x1037A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1037A,
+ },
+ [0x10380]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10380,
+ },
+ [0x10381]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10381,
+ },
+ [0x10382]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10382,
+ },
+ [0x10383]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10383,
+ },
+ [0x10384]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10384,
+ },
+ [0x10385]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10385,
+ },
+ [0x10386]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10386,
+ },
+ [0x10387]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10387,
+ },
+ [0x10388]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10388,
+ },
+ [0x10389]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10389,
+ },
+ [0x1038A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1038A,
+ },
+ [0x1038B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1038B,
+ },
+ [0x1038C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1038C,
+ },
+ [0x1038D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1038D,
+ },
+ [0x1038E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1038E,
+ },
+ [0x1038F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1038F,
+ },
+ [0x10390]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10390,
+ },
+ [0x10391]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10391,
+ },
+ [0x10392]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10392,
+ },
+ [0x10393]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10393,
+ },
+ [0x10394]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10394,
+ },
+ [0x10395]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10395,
+ },
+ [0x10396]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10396,
+ },
+ [0x10397]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10397,
+ },
+ [0x10398]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10398,
+ },
+ [0x10399]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10399,
+ },
+ [0x1039A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1039A,
+ },
+ [0x1039B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1039B,
+ },
+ [0x1039C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1039C,
+ },
+ [0x1039D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1039D,
+ },
+ [0x1039F]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1039F,
+ },
+ [0x103A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A0,
+ },
+ [0x103A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A1,
+ },
+ [0x103A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A2,
+ },
+ [0x103A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A3,
+ },
+ [0x103A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A4,
+ },
+ [0x103A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A5,
+ },
+ [0x103A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A6,
+ },
+ [0x103A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A7,
+ },
+ [0x103A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A8,
+ },
+ [0x103A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A9,
+ },
+ [0x103AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103AA,
+ },
+ [0x103AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103AB,
+ },
+ [0x103AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103AC,
+ },
+ [0x103AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103AD,
+ },
+ [0x103AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103AE,
+ },
+ [0x103AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103AF,
+ },
+ [0x103B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B0,
+ },
+ [0x103B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B1,
+ },
+ [0x103B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B2,
+ },
+ [0x103B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B3,
+ },
+ [0x103B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B4,
+ },
+ [0x103B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B5,
+ },
+ [0x103B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B6,
+ },
+ [0x103B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B7,
+ },
+ [0x103B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B8,
+ },
+ [0x103B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B9,
+ },
+ [0x103BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103BA,
+ },
+ [0x103BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103BB,
+ },
+ [0x103BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103BC,
+ },
+ [0x103BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103BD,
+ },
+ [0x103BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103BE,
+ },
+ [0x103BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103BF,
+ },
+ [0x103C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103C0,
+ },
+ [0x103C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103C1,
+ },
+ [0x103C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103C2,
+ },
+ [0x103C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103C3,
+ },
+ [0x103C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103C8,
+ },
+ [0x103C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103C9,
+ },
+ [0x103CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103CA,
+ },
+ [0x103CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103CB,
+ },
+ [0x103CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103CC,
+ },
+ [0x103CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103CD,
+ },
+ [0x103CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103CE,
+ },
+ [0x103CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103CF,
+ },
+ [0x103D0]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x103D0,
+ },
+ [0x103D1]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103D1,
+ },
+ [0x103D2]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103D2,
+ },
+ [0x103D3]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103D3,
+ },
+ [0x103D4]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103D4,
+ },
+ [0x103D5]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103D5,
+ },
+ [0x10400]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10400,
+ },
+ [0x10401]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10401,
+ },
+ [0x10402]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10402,
+ },
+ [0x10403]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10403,
+ },
+ [0x10404]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10404,
+ },
+ [0x10405]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10405,
+ },
+ [0x10406]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10406,
+ },
+ [0x10407]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10407,
+ },
+ [0x10408]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10408,
+ },
+ [0x10409]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10409,
+ },
+ [0x1040A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1040A,
+ },
+ [0x1040B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1040B,
+ },
+ [0x1040C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1040C,
+ },
+ [0x1040D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1040D,
+ },
+ [0x1040E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1040E,
+ },
+ [0x1040F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1040F,
+ },
+ [0x10410]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10410,
+ },
+ [0x10411]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10411,
+ },
+ [0x10412]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10412,
+ },
+ [0x10413]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10413,
+ },
+ [0x10414]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10414,
+ },
+ [0x10415]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10415,
+ },
+ [0x10416]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10416,
+ },
+ [0x10417]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10417,
+ },
+ [0x10418]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10418,
+ },
+ [0x10419]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10419,
+ },
+ [0x1041A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1041A,
+ },
+ [0x1041B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1041B,
+ },
+ [0x1041C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1041C,
+ },
+ [0x1041D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1041D,
+ },
+ [0x1041E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1041E,
+ },
+ [0x1041F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1041F,
+ },
+ [0x10420]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10420,
+ },
+ [0x10421]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10421,
+ },
+ [0x10422]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10422,
+ },
+ [0x10423]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10423,
+ },
+ [0x10424]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10424,
+ },
+ [0x10425]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10425,
+ },
+ [0x10426]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10426,
+ },
+ [0x10427]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10427,
+ },
+ [0x10428]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10428,
+ },
+ [0x10429]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10429,
+ },
+ [0x1042A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1042A,
+ },
+ [0x1042B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1042B,
+ },
+ [0x1042C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1042C,
+ },
+ [0x1042D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1042D,
+ },
+ [0x1042E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1042E,
+ },
+ [0x1042F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1042F,
+ },
+ [0x10430]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10430,
+ },
+ [0x10431]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10431,
+ },
+ [0x10432]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10432,
+ },
+ [0x10433]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10433,
+ },
+ [0x10434]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10434,
+ },
+ [0x10435]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10435,
+ },
+ [0x10436]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10436,
+ },
+ [0x10437]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10437,
+ },
+ [0x10438]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10438,
+ },
+ [0x10439]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10439,
+ },
+ [0x1043A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1043A,
+ },
+ [0x1043B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1043B,
+ },
+ [0x1043C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1043C,
+ },
+ [0x1043D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1043D,
+ },
+ [0x1043E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1043E,
+ },
+ [0x1043F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1043F,
+ },
+ [0x10440]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10440,
+ },
+ [0x10441]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10441,
+ },
+ [0x10442]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10442,
+ },
+ [0x10443]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10443,
+ },
+ [0x10444]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10444,
+ },
+ [0x10445]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10445,
+ },
+ [0x10446]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10446,
+ },
+ [0x10447]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10447,
+ },
+ [0x10448]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10448,
+ },
+ [0x10449]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10449,
+ },
+ [0x1044A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1044A,
+ },
+ [0x1044B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1044B,
+ },
+ [0x1044C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1044C,
+ },
+ [0x1044D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1044D,
+ },
+ [0x1044E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1044E,
+ },
+ [0x1044F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1044F,
+ },
+ [0x10450]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10450,
+ },
+ [0x10451]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10451,
+ },
+ [0x10452]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10452,
+ },
+ [0x10453]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10453,
+ },
+ [0x10454]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10454,
+ },
+ [0x10455]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10455,
+ },
+ [0x10456]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10456,
+ },
+ [0x10457]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10457,
+ },
+ [0x10458]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10458,
+ },
+ [0x10459]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10459,
+ },
+ [0x1045A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1045A,
+ },
+ [0x1045B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1045B,
+ },
+ [0x1045C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1045C,
+ },
+ [0x1045D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1045D,
+ },
+ [0x1045E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1045E,
+ },
+ [0x1045F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1045F,
+ },
+ [0x10460]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10460,
+ },
+ [0x10461]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10461,
+ },
+ [0x10462]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10462,
+ },
+ [0x10463]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10463,
+ },
+ [0x10464]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10464,
+ },
+ [0x10465]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10465,
+ },
+ [0x10466]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10466,
+ },
+ [0x10467]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10467,
+ },
+ [0x10468]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10468,
+ },
+ [0x10469]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10469,
+ },
+ [0x1046A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1046A,
+ },
+ [0x1046B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1046B,
+ },
+ [0x1046C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1046C,
+ },
+ [0x1046D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1046D,
+ },
+ [0x1046E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1046E,
+ },
+ [0x1046F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1046F,
+ },
+ [0x10470]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10470,
+ },
+ [0x10471]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10471,
+ },
+ [0x10472]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10472,
+ },
+ [0x10473]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10473,
+ },
+ [0x10474]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10474,
+ },
+ [0x10475]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10475,
+ },
+ [0x10476]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10476,
+ },
+ [0x10477]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10477,
+ },
+ [0x10478]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10478,
+ },
+ [0x10479]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10479,
+ },
+ [0x1047A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1047A,
+ },
+ [0x1047B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1047B,
+ },
+ [0x1047C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1047C,
+ },
+ [0x1047D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1047D,
+ },
+ [0x1047E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1047E,
+ },
+ [0x1047F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1047F,
+ },
+ [0x10480]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10480,
+ },
+ [0x10481]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10481,
+ },
+ [0x10482]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10482,
+ },
+ [0x10483]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10483,
+ },
+ [0x10484]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10484,
+ },
+ [0x10485]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10485,
+ },
+ [0x10486]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10486,
+ },
+ [0x10487]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10487,
+ },
+ [0x10488]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10488,
+ },
+ [0x10489]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10489,
+ },
+ [0x1048A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1048A,
+ },
+ [0x1048B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1048B,
+ },
+ [0x1048C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1048C,
+ },
+ [0x1048D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1048D,
+ },
+ [0x1048E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1048E,
+ },
+ [0x1048F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1048F,
+ },
+ [0x10490]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10490,
+ },
+ [0x10491]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10491,
+ },
+ [0x10492]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10492,
+ },
+ [0x10493]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10493,
+ },
+ [0x10494]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10494,
+ },
+ [0x10495]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10495,
+ },
+ [0x10496]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10496,
+ },
+ [0x10497]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10497,
+ },
+ [0x10498]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10498,
+ },
+ [0x10499]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10499,
+ },
+ [0x1049A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1049A,
+ },
+ [0x1049B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1049B,
+ },
+ [0x1049C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1049C,
+ },
+ [0x1049D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1049D,
+ },
+ [0x104A0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A0,
+ },
+ [0x104A1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A1,
+ },
+ [0x104A2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A2,
+ },
+ [0x104A3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A3,
+ },
+ [0x104A4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A4,
+ },
+ [0x104A5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A5,
+ },
+ [0x104A6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A6,
+ },
+ [0x104A7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A7,
+ },
+ [0x104A8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A8,
+ },
+ [0x104A9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A9,
+ },
+ [0x104B0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104B0,
+ },
+ [0x104B1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104B1,
+ },
+ [0x104B2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104B2,
+ },
+ [0x104B3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104B3,
+ },
+ [0x104B4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104B4,
+ },
+ [0x104B5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104B5,
+ },
+ [0x104B6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104B6,
+ },
+ [0x104B7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104B7,
+ },
+ [0x104B8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104B8,
+ },
+ [0x104B9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104B9,
+ },
+ [0x104BA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104BA,
+ },
+ [0x104BB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104BB,
+ },
+ [0x104BC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104BC,
+ },
+ [0x104BD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104BD,
+ },
+ [0x104BE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104BE,
+ },
+ [0x104BF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104BF,
+ },
+ [0x104C0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104C0,
+ },
+ [0x104C1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104C1,
+ },
+ [0x104C2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104C2,
+ },
+ [0x104C3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104C3,
+ },
+ [0x104C4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104C4,
+ },
+ [0x104C5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104C5,
+ },
+ [0x104C6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104C6,
+ },
+ [0x104C7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104C7,
+ },
+ [0x104C8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104C8,
+ },
+ [0x104C9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104C9,
+ },
+ [0x104CA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104CA,
+ },
+ [0x104CB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104CB,
+ },
+ [0x104CC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104CC,
+ },
+ [0x104CD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104CD,
+ },
+ [0x104CE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104CE,
+ },
+ [0x104CF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104CF,
+ },
+ [0x104D0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104D0,
+ },
+ [0x104D1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104D1,
+ },
+ [0x104D2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104D2,
+ },
+ [0x104D3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104D3,
+ },
+ [0x104D8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104D8,
+ },
+ [0x104D9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104D9,
+ },
+ [0x104DA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104DA,
+ },
+ [0x104DB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104DB,
+ },
+ [0x104DC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104DC,
+ },
+ [0x104DD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104DD,
+ },
+ [0x104DE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104DE,
+ },
+ [0x104DF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104DF,
+ },
+ [0x104E0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104E0,
+ },
+ [0x104E1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104E1,
+ },
+ [0x104E2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104E2,
+ },
+ [0x104E3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104E3,
+ },
+ [0x104E4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104E4,
+ },
+ [0x104E5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104E5,
+ },
+ [0x104E6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104E6,
+ },
+ [0x104E7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104E7,
+ },
+ [0x104E8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104E8,
+ },
+ [0x104E9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104E9,
+ },
+ [0x104EA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104EA,
+ },
+ [0x104EB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104EB,
+ },
+ [0x104EC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104EC,
+ },
+ [0x104ED]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104ED,
+ },
+ [0x104EE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104EE,
+ },
+ [0x104EF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104EF,
+ },
+ [0x104F0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104F0,
+ },
+ [0x104F1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104F1,
+ },
+ [0x104F2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104F2,
+ },
+ [0x104F3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104F3,
+ },
+ [0x104F4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104F4,
+ },
+ [0x104F5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104F5,
+ },
+ [0x104F6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104F6,
+ },
+ [0x104F7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104F7,
+ },
+ [0x104F8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104F8,
+ },
+ [0x104F9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104F9,
+ },
+ [0x104FA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104FA,
+ },
+ [0x104FB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104FB,
+ },
+ [0x10500]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10500,
+ },
+ [0x10501]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10501,
+ },
+ [0x10502]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10502,
+ },
+ [0x10503]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10503,
+ },
+ [0x10504]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10504,
+ },
+ [0x10505]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10505,
+ },
+ [0x10506]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10506,
+ },
+ [0x10507]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10507,
+ },
+ [0x10508]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10508,
+ },
+ [0x10509]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10509,
+ },
+ [0x1050A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1050A,
+ },
+ [0x1050B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1050B,
+ },
+ [0x1050C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1050C,
+ },
+ [0x1050D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1050D,
+ },
+ [0x1050E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1050E,
+ },
+ [0x1050F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1050F,
+ },
+ [0x10510]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10510,
+ },
+ [0x10511]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10511,
+ },
+ [0x10512]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10512,
+ },
+ [0x10513]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10513,
+ },
+ [0x10514]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10514,
+ },
+ [0x10515]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10515,
+ },
+ [0x10516]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10516,
+ },
+ [0x10517]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10517,
+ },
+ [0x10518]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10518,
+ },
+ [0x10519]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10519,
+ },
+ [0x1051A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1051A,
+ },
+ [0x1051B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1051B,
+ },
+ [0x1051C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1051C,
+ },
+ [0x1051D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1051D,
+ },
+ [0x1051E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1051E,
+ },
+ [0x1051F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1051F,
+ },
+ [0x10520]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10520,
+ },
+ [0x10521]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10521,
+ },
+ [0x10522]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10522,
+ },
+ [0x10523]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10523,
+ },
+ [0x10524]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10524,
+ },
+ [0x10525]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10525,
+ },
+ [0x10526]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10526,
+ },
+ [0x10527]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10527,
+ },
+ [0x10530]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10530,
+ },
+ [0x10531]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10531,
+ },
+ [0x10532]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10532,
+ },
+ [0x10533]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10533,
+ },
+ [0x10534]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10534,
+ },
+ [0x10535]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10535,
+ },
+ [0x10536]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10536,
+ },
+ [0x10537]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10537,
+ },
+ [0x10538]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10538,
+ },
+ [0x10539]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10539,
+ },
+ [0x1053A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1053A,
+ },
+ [0x1053B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1053B,
+ },
+ [0x1053C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1053C,
+ },
+ [0x1053D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1053D,
+ },
+ [0x1053E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1053E,
+ },
+ [0x1053F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1053F,
+ },
+ [0x10540]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10540,
+ },
+ [0x10541]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10541,
+ },
+ [0x10542]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10542,
+ },
+ [0x10543]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10543,
+ },
+ [0x10544]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10544,
+ },
+ [0x10545]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10545,
+ },
+ [0x10546]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10546,
+ },
+ [0x10547]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10547,
+ },
+ [0x10548]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10548,
+ },
+ [0x10549]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10549,
+ },
+ [0x1054A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1054A,
+ },
+ [0x1054B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1054B,
+ },
+ [0x1054C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1054C,
+ },
+ [0x1054D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1054D,
+ },
+ [0x1054E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1054E,
+ },
+ [0x1054F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1054F,
+ },
+ [0x10550]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10550,
+ },
+ [0x10551]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10551,
+ },
+ [0x10552]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10552,
+ },
+ [0x10553]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10553,
+ },
+ [0x10554]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10554,
+ },
+ [0x10555]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10555,
+ },
+ [0x10556]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10556,
+ },
+ [0x10557]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10557,
+ },
+ [0x10558]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10558,
+ },
+ [0x10559]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10559,
+ },
+ [0x1055A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1055A,
+ },
+ [0x1055B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1055B,
+ },
+ [0x1055C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1055C,
+ },
+ [0x1055D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1055D,
+ },
+ [0x1055E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1055E,
+ },
+ [0x1055F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1055F,
+ },
+ [0x10560]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10560,
+ },
+ [0x10561]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10561,
+ },
+ [0x10562]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10562,
+ },
+ [0x10563]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10563,
+ },
+ [0x1056F]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1056F,
+ },
+ [0x10600]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10600,
+ },
+ [0x10601]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10601,
+ },
+ [0x10602]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10602,
+ },
+ [0x10603]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10603,
+ },
+ [0x10604]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10604,
+ },
+ [0x10605]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10605,
+ },
+ [0x10606]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10606,
+ },
+ [0x10607]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10607,
+ },
+ [0x10608]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10608,
+ },
+ [0x10609]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10609,
+ },
+ [0x1060A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1060A,
+ },
+ [0x1060B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1060B,
+ },
+ [0x1060C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1060C,
+ },
+ [0x1060D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1060D,
+ },
+ [0x1060E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1060E,
+ },
+ [0x1060F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1060F,
+ },
+ [0x10610]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10610,
+ },
+ [0x10611]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10611,
+ },
+ [0x10612]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10612,
+ },
+ [0x10613]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10613,
+ },
+ [0x10614]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10614,
+ },
+ [0x10615]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10615,
+ },
+ [0x10616]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10616,
+ },
+ [0x10617]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10617,
+ },
+ [0x10618]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10618,
+ },
+ [0x10619]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10619,
+ },
+ [0x1061A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1061A,
+ },
+ [0x1061B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1061B,
+ },
+ [0x1061C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1061C,
+ },
+ [0x1061D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1061D,
+ },
+ [0x1061E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1061E,
+ },
+ [0x1061F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1061F,
+ },
+ [0x10620]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10620,
+ },
+ [0x10621]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10621,
+ },
+ [0x10622]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10622,
+ },
+ [0x10623]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10623,
+ },
+ [0x10624]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10624,
+ },
+ [0x10625]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10625,
+ },
+ [0x10626]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10626,
+ },
+ [0x10627]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10627,
+ },
+ [0x10628]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10628,
+ },
+ [0x10629]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10629,
+ },
+ [0x1062A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1062A,
+ },
+ [0x1062B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1062B,
+ },
+ [0x1062C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1062C,
+ },
+ [0x1062D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1062D,
+ },
+ [0x1062E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1062E,
+ },
+ [0x1062F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1062F,
+ },
+ [0x10630]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10630,
+ },
+ [0x10631]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10631,
+ },
+ [0x10632]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10632,
+ },
+ [0x10633]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10633,
+ },
+ [0x10634]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10634,
+ },
+ [0x10635]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10635,
+ },
+ [0x10636]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10636,
+ },
+ [0x10637]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10637,
+ },
+ [0x10638]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10638,
+ },
+ [0x10639]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10639,
+ },
+ [0x1063A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1063A,
+ },
+ [0x1063B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1063B,
+ },
+ [0x1063C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1063C,
+ },
+ [0x1063D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1063D,
+ },
+ [0x1063E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1063E,
+ },
+ [0x1063F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1063F,
+ },
+ [0x10640]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10640,
+ },
+ [0x10641]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10641,
+ },
+ [0x10642]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10642,
+ },
+ [0x10643]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10643,
+ },
+ [0x10644]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10644,
+ },
+ [0x10645]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10645,
+ },
+ [0x10646]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10646,
+ },
+ [0x10647]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10647,
+ },
+ [0x10648]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10648,
+ },
+ [0x10649]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10649,
+ },
+ [0x1064A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1064A,
+ },
+ [0x1064B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1064B,
+ },
+ [0x1064C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1064C,
+ },
+ [0x1064D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1064D,
+ },
+ [0x1064E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1064E,
+ },
+ [0x1064F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1064F,
+ },
+ [0x10650]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10650,
+ },
+ [0x10651]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10651,
+ },
+ [0x10652]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10652,
+ },
+ [0x10653]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10653,
+ },
+ [0x10654]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10654,
+ },
+ [0x10655]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10655,
+ },
+ [0x10656]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10656,
+ },
+ [0x10657]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10657,
+ },
+ [0x10658]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10658,
+ },
+ [0x10659]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10659,
+ },
+ [0x1065A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1065A,
+ },
+ [0x1065B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1065B,
+ },
+ [0x1065C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1065C,
+ },
+ [0x1065D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1065D,
+ },
+ [0x1065E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1065E,
+ },
+ [0x1065F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1065F,
+ },
+ [0x10660]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10660,
+ },
+ [0x10661]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10661,
+ },
+ [0x10662]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10662,
+ },
+ [0x10663]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10663,
+ },
+ [0x10664]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10664,
+ },
+ [0x10665]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10665,
+ },
+ [0x10666]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10666,
+ },
+ [0x10667]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10667,
+ },
+ [0x10668]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10668,
+ },
+ [0x10669]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10669,
+ },
+ [0x1066A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1066A,
+ },
+ [0x1066B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1066B,
+ },
+ [0x1066C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1066C,
+ },
+ [0x1066D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1066D,
+ },
+ [0x1066E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1066E,
+ },
+ [0x1066F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1066F,
+ },
+ [0x10670]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10670,
+ },
+ [0x10671]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10671,
+ },
+ [0x10672]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10672,
+ },
+ [0x10673]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10673,
+ },
+ [0x10674]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10674,
+ },
+ [0x10675]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10675,
+ },
+ [0x10676]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10676,
+ },
+ [0x10677]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10677,
+ },
+ [0x10678]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10678,
+ },
+ [0x10679]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10679,
+ },
+ [0x1067A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1067A,
+ },
+ [0x1067B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1067B,
+ },
+ [0x1067C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1067C,
+ },
+ [0x1067D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1067D,
+ },
+ [0x1067E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1067E,
+ },
+ [0x1067F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1067F,
+ },
+ [0x10680]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10680,
+ },
+ [0x10681]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10681,
+ },
+ [0x10682]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10682,
+ },
+ [0x10683]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10683,
+ },
+ [0x10684]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10684,
+ },
+ [0x10685]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10685,
+ },
+ [0x10686]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10686,
+ },
+ [0x10687]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10687,
+ },
+ [0x10688]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10688,
+ },
+ [0x10689]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10689,
+ },
+ [0x1068A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1068A,
+ },
+ [0x1068B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1068B,
+ },
+ [0x1068C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1068C,
+ },
+ [0x1068D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1068D,
+ },
+ [0x1068E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1068E,
+ },
+ [0x1068F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1068F,
+ },
+ [0x10690]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10690,
+ },
+ [0x10691]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10691,
+ },
+ [0x10692]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10692,
+ },
+ [0x10693]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10693,
+ },
+ [0x10694]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10694,
+ },
+ [0x10695]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10695,
+ },
+ [0x10696]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10696,
+ },
+ [0x10697]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10697,
+ },
+ [0x10698]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10698,
+ },
+ [0x10699]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10699,
+ },
+ [0x1069A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1069A,
+ },
+ [0x1069B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1069B,
+ },
+ [0x1069C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1069C,
+ },
+ [0x1069D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1069D,
+ },
+ [0x1069E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1069E,
+ },
+ [0x1069F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1069F,
+ },
+ [0x106A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106A0,
+ },
+ [0x106A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106A1,
+ },
+ [0x106A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106A2,
+ },
+ [0x106A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106A3,
+ },
+ [0x106A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106A4,
+ },
+ [0x106A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106A5,
+ },
+ [0x106A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106A6,
+ },
+ [0x106A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106A7,
+ },
+ [0x106A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106A8,
+ },
+ [0x106A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106A9,
+ },
+ [0x106AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106AA,
+ },
+ [0x106AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106AB,
+ },
+ [0x106AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106AC,
+ },
+ [0x106AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106AD,
+ },
+ [0x106AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106AE,
+ },
+ [0x106AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106AF,
+ },
+ [0x106B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106B0,
+ },
+ [0x106B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106B1,
+ },
+ [0x106B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106B2,
+ },
+ [0x106B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106B3,
+ },
+ [0x106B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106B4,
+ },
+ [0x106B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106B5,
+ },
+ [0x106B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106B6,
+ },
+ [0x106B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106B7,
+ },
+ [0x106B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106B8,
+ },
+ [0x106B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106B9,
+ },
+ [0x106BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106BA,
+ },
+ [0x106BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106BB,
+ },
+ [0x106BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106BC,
+ },
+ [0x106BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106BD,
+ },
+ [0x106BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106BE,
+ },
+ [0x106BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106BF,
+ },
+ [0x106C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106C0,
+ },
+ [0x106C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106C1,
+ },
+ [0x106C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106C2,
+ },
+ [0x106C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106C3,
+ },
+ [0x106C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106C4,
+ },
+ [0x106C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106C5,
+ },
+ [0x106C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106C6,
+ },
+ [0x106C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106C7,
+ },
+ [0x106C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106C8,
+ },
+ [0x106C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106C9,
+ },
+ [0x106CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106CA,
+ },
+ [0x106CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106CB,
+ },
+ [0x106CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106CC,
+ },
+ [0x106CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106CD,
+ },
+ [0x106CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106CE,
+ },
+ [0x106CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106CF,
+ },
+ [0x106D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106D0,
+ },
+ [0x106D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106D1,
+ },
+ [0x106D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106D2,
+ },
+ [0x106D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106D3,
+ },
+ [0x106D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106D4,
+ },
+ [0x106D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106D5,
+ },
+ [0x106D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106D6,
+ },
+ [0x106D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106D7,
+ },
+ [0x106D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106D8,
+ },
+ [0x106D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106D9,
+ },
+ [0x106DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106DA,
+ },
+ [0x106DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106DB,
+ },
+ [0x106DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106DC,
+ },
+ [0x106DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106DD,
+ },
+ [0x106DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106DE,
+ },
+ [0x106DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106DF,
+ },
+ [0x106E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106E0,
+ },
+ [0x106E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106E1,
+ },
+ [0x106E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106E2,
+ },
+ [0x106E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106E3,
+ },
+ [0x106E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106E4,
+ },
+ [0x106E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106E5,
+ },
+ [0x106E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106E6,
+ },
+ [0x106E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106E7,
+ },
+ [0x106E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106E8,
+ },
+ [0x106E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106E9,
+ },
+ [0x106EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106EA,
+ },
+ [0x106EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106EB,
+ },
+ [0x106EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106EC,
+ },
+ [0x106ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106ED,
+ },
+ [0x106EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106EE,
+ },
+ [0x106EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106EF,
+ },
+ [0x106F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106F0,
+ },
+ [0x106F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106F1,
+ },
+ [0x106F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106F2,
+ },
+ [0x106F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106F3,
+ },
+ [0x106F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106F4,
+ },
+ [0x106F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106F5,
+ },
+ [0x106F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106F6,
+ },
+ [0x106F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106F7,
+ },
+ [0x106F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106F8,
+ },
+ [0x106F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106F9,
+ },
+ [0x106FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106FA,
+ },
+ [0x106FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106FB,
+ },
+ [0x106FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106FC,
+ },
+ [0x106FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106FD,
+ },
+ [0x106FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106FE,
+ },
+ [0x106FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x106FF,
+ },
+ [0x10700]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10700,
+ },
+ [0x10701]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10701,
+ },
+ [0x10702]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10702,
+ },
+ [0x10703]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10703,
+ },
+ [0x10704]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10704,
+ },
+ [0x10705]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10705,
+ },
+ [0x10706]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10706,
+ },
+ [0x10707]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10707,
+ },
+ [0x10708]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10708,
+ },
+ [0x10709]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10709,
+ },
+ [0x1070A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1070A,
+ },
+ [0x1070B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1070B,
+ },
+ [0x1070C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1070C,
+ },
+ [0x1070D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1070D,
+ },
+ [0x1070E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1070E,
+ },
+ [0x1070F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1070F,
+ },
+ [0x10710]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10710,
+ },
+ [0x10711]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10711,
+ },
+ [0x10712]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10712,
+ },
+ [0x10713]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10713,
+ },
+ [0x10714]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10714,
+ },
+ [0x10715]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10715,
+ },
+ [0x10716]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10716,
+ },
+ [0x10717]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10717,
+ },
+ [0x10718]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10718,
+ },
+ [0x10719]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10719,
+ },
+ [0x1071A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1071A,
+ },
+ [0x1071B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1071B,
+ },
+ [0x1071C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1071C,
+ },
+ [0x1071D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1071D,
+ },
+ [0x1071E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1071E,
+ },
+ [0x1071F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1071F,
+ },
+ [0x10720]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10720,
+ },
+ [0x10721]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10721,
+ },
+ [0x10722]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10722,
+ },
+ [0x10723]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10723,
+ },
+ [0x10724]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10724,
+ },
+ [0x10725]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10725,
+ },
+ [0x10726]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10726,
+ },
+ [0x10727]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10727,
+ },
+ [0x10728]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10728,
+ },
+ [0x10729]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10729,
+ },
+ [0x1072A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1072A,
+ },
+ [0x1072B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1072B,
+ },
+ [0x1072C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1072C,
+ },
+ [0x1072D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1072D,
+ },
+ [0x1072E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1072E,
+ },
+ [0x1072F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1072F,
+ },
+ [0x10730]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10730,
+ },
+ [0x10731]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10731,
+ },
+ [0x10732]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10732,
+ },
+ [0x10733]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10733,
+ },
+ [0x10734]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10734,
+ },
+ [0x10735]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10735,
+ },
+ [0x10736]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10736,
+ },
+ [0x10740]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10740,
+ },
+ [0x10741]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10741,
+ },
+ [0x10742]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10742,
+ },
+ [0x10743]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10743,
+ },
+ [0x10744]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10744,
+ },
+ [0x10745]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10745,
+ },
+ [0x10746]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10746,
+ },
+ [0x10747]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10747,
+ },
+ [0x10748]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10748,
+ },
+ [0x10749]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10749,
+ },
+ [0x1074A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1074A,
+ },
+ [0x1074B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1074B,
+ },
+ [0x1074C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1074C,
+ },
+ [0x1074D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1074D,
+ },
+ [0x1074E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1074E,
+ },
+ [0x1074F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1074F,
+ },
+ [0x10750]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10750,
+ },
+ [0x10751]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10751,
+ },
+ [0x10752]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10752,
+ },
+ [0x10753]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10753,
+ },
+ [0x10754]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10754,
+ },
+ [0x10755]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10755,
+ },
+ [0x10760]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10760,
+ },
+ [0x10761]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10761,
+ },
+ [0x10762]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10762,
+ },
+ [0x10763]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10763,
+ },
+ [0x10764]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10764,
+ },
+ [0x10765]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10765,
+ },
+ [0x10766]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10766,
+ },
+ [0x10767]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10767,
+ },
+ [0x10800]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10800,
+ },
+ [0x10801]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10801,
+ },
+ [0x10802]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10802,
+ },
+ [0x10803]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10803,
+ },
+ [0x10804]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10804,
+ },
+ [0x10805]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10805,
+ },
+ [0x10808]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10808,
+ },
+ [0x1080A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1080A,
+ },
+ [0x1080B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1080B,
+ },
+ [0x1080C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1080C,
+ },
+ [0x1080D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1080D,
+ },
+ [0x1080E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1080E,
+ },
+ [0x1080F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1080F,
+ },
+ [0x10810]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10810,
+ },
+ [0x10811]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10811,
+ },
+ [0x10812]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10812,
+ },
+ [0x10813]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10813,
+ },
+ [0x10814]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10814,
+ },
+ [0x10815]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10815,
+ },
+ [0x10816]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10816,
+ },
+ [0x10817]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10817,
+ },
+ [0x10818]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10818,
+ },
+ [0x10819]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10819,
+ },
+ [0x1081A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1081A,
+ },
+ [0x1081B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1081B,
+ },
+ [0x1081C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1081C,
+ },
+ [0x1081D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1081D,
+ },
+ [0x1081E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1081E,
+ },
+ [0x1081F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1081F,
+ },
+ [0x10820]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10820,
+ },
+ [0x10821]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10821,
+ },
+ [0x10822]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10822,
+ },
+ [0x10823]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10823,
+ },
+ [0x10824]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10824,
+ },
+ [0x10825]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10825,
+ },
+ [0x10826]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10826,
+ },
+ [0x10827]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10827,
+ },
+ [0x10828]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10828,
+ },
+ [0x10829]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10829,
+ },
+ [0x1082A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1082A,
+ },
+ [0x1082B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1082B,
+ },
+ [0x1082C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1082C,
+ },
+ [0x1082D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1082D,
+ },
+ [0x1082E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1082E,
+ },
+ [0x1082F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1082F,
+ },
+ [0x10830]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10830,
+ },
+ [0x10831]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10831,
+ },
+ [0x10832]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10832,
+ },
+ [0x10833]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10833,
+ },
+ [0x10834]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10834,
+ },
+ [0x10835]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10835,
+ },
+ [0x10837]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10837,
+ },
+ [0x10838]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10838,
+ },
+ [0x1083C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1083C,
+ },
+ [0x1083F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1083F,
+ },
+ [0x10840]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10840,
+ },
+ [0x10841]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10841,
+ },
+ [0x10842]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10842,
+ },
+ [0x10843]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10843,
+ },
+ [0x10844]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10844,
+ },
+ [0x10845]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10845,
+ },
+ [0x10846]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10846,
+ },
+ [0x10847]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10847,
+ },
+ [0x10848]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10848,
+ },
+ [0x10849]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10849,
+ },
+ [0x1084A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1084A,
+ },
+ [0x1084B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1084B,
+ },
+ [0x1084C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1084C,
+ },
+ [0x1084D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1084D,
+ },
+ [0x1084E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1084E,
+ },
+ [0x1084F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1084F,
+ },
+ [0x10850]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10850,
+ },
+ [0x10851]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10851,
+ },
+ [0x10852]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10852,
+ },
+ [0x10853]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10853,
+ },
+ [0x10854]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10854,
+ },
+ [0x10855]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10855,
+ },
+ [0x10857]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10857,
+ },
+ [0x10858]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10858,
+ },
+ [0x10859]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10859,
+ },
+ [0x1085A]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1085A,
+ },
+ [0x1085B]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1085B,
+ },
+ [0x1085C]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1085C,
+ },
+ [0x1085D]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1085D,
+ },
+ [0x1085E]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1085E,
+ },
+ [0x1085F]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1085F,
+ },
+ [0x10860]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10860,
+ },
+ [0x10861]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10861,
+ },
+ [0x10862]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10862,
+ },
+ [0x10863]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10863,
+ },
+ [0x10864]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10864,
+ },
+ [0x10865]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10865,
+ },
+ [0x10866]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10866,
+ },
+ [0x10867]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10867,
+ },
+ [0x10868]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10868,
+ },
+ [0x10869]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10869,
+ },
+ [0x1086A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1086A,
+ },
+ [0x1086B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1086B,
+ },
+ [0x1086C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1086C,
+ },
+ [0x1086D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1086D,
+ },
+ [0x1086E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1086E,
+ },
+ [0x1086F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1086F,
+ },
+ [0x10870]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10870,
+ },
+ [0x10871]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10871,
+ },
+ [0x10872]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10872,
+ },
+ [0x10873]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10873,
+ },
+ [0x10874]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10874,
+ },
+ [0x10875]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10875,
+ },
+ [0x10876]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10876,
+ },
+ [0x10877]={
+ category="so",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10877,
+ },
+ [0x10878]={
+ category="so",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10878,
+ },
+ [0x10879]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10879,
+ },
+ [0x1087A]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1087A,
+ },
+ [0x1087B]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1087B,
+ },
+ [0x1087C]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1087C,
+ },
+ [0x1087D]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1087D,
+ },
+ [0x1087E]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1087E,
+ },
+ [0x1087F]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1087F,
+ },
+ [0x10880]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10880,
+ },
+ [0x10881]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10881,
+ },
+ [0x10882]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10882,
+ },
+ [0x10883]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10883,
+ },
+ [0x10884]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10884,
+ },
+ [0x10885]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10885,
+ },
+ [0x10886]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10886,
+ },
+ [0x10887]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10887,
+ },
+ [0x10888]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10888,
+ },
+ [0x10889]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10889,
+ },
+ [0x1088A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1088A,
+ },
+ [0x1088B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1088B,
+ },
+ [0x1088C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1088C,
+ },
+ [0x1088D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1088D,
+ },
+ [0x1088E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1088E,
+ },
+ [0x1088F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1088F,
+ },
+ [0x10890]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10890,
+ },
+ [0x10891]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10891,
+ },
+ [0x10892]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10892,
+ },
+ [0x10893]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10893,
+ },
+ [0x10894]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10894,
+ },
+ [0x10895]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10895,
+ },
+ [0x10896]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10896,
+ },
+ [0x10897]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10897,
+ },
+ [0x10898]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10898,
+ },
+ [0x10899]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10899,
+ },
+ [0x1089A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1089A,
+ },
+ [0x1089B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1089B,
+ },
+ [0x1089C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1089C,
+ },
+ [0x1089D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1089D,
+ },
+ [0x1089E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1089E,
+ },
+ [0x108A7]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108A7,
+ },
+ [0x108A8]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108A8,
+ },
+ [0x108A9]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108A9,
+ },
+ [0x108AA]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108AA,
+ },
+ [0x108AB]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108AB,
+ },
+ [0x108AC]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108AC,
+ },
+ [0x108AD]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108AD,
+ },
+ [0x108AE]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108AE,
+ },
+ [0x108AF]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108AF,
+ },
+ [0x108E0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108E0,
+ },
+ [0x108E1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108E1,
+ },
+ [0x108E2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108E2,
+ },
+ [0x108E3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108E3,
+ },
+ [0x108E4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108E4,
+ },
+ [0x108E5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108E5,
+ },
+ [0x108E6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108E6,
+ },
+ [0x108E7]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108E7,
+ },
+ [0x108E8]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108E8,
+ },
+ [0x108E9]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108E9,
+ },
+ [0x108EA]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108EA,
+ },
+ [0x108EB]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108EB,
+ },
+ [0x108EC]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108EC,
+ },
+ [0x108ED]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108ED,
+ },
+ [0x108EE]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108EE,
+ },
+ [0x108EF]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108EF,
+ },
+ [0x108F0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108F0,
+ },
+ [0x108F1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108F1,
+ },
+ [0x108F2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108F2,
+ },
+ [0x108F4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108F4,
+ },
+ [0x108F5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108F5,
+ },
+ [0x108FB]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108FB,
+ },
+ [0x108FC]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108FC,
+ },
+ [0x108FD]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108FD,
+ },
+ [0x108FE]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108FE,
+ },
+ [0x108FF]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x108FF,
+ },
+ [0x10900]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10900,
+ },
+ [0x10901]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10901,
+ },
+ [0x10902]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10902,
+ },
+ [0x10903]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10903,
+ },
+ [0x10904]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10904,
+ },
+ [0x10905]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10905,
+ },
+ [0x10906]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10906,
+ },
+ [0x10907]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10907,
+ },
+ [0x10908]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10908,
+ },
+ [0x10909]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10909,
+ },
+ [0x1090A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1090A,
+ },
+ [0x1090B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1090B,
+ },
+ [0x1090C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1090C,
+ },
+ [0x1090D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1090D,
+ },
+ [0x1090E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1090E,
+ },
+ [0x1090F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1090F,
+ },
+ [0x10910]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10910,
+ },
+ [0x10911]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10911,
+ },
+ [0x10912]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10912,
+ },
+ [0x10913]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10913,
+ },
+ [0x10914]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10914,
+ },
+ [0x10915]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10915,
+ },
+ [0x10916]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10916,
+ },
+ [0x10917]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10917,
+ },
+ [0x10918]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10918,
+ },
+ [0x10919]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10919,
+ },
+ [0x1091A]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1091A,
+ },
+ [0x1091B]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1091B,
+ },
+ [0x1091F]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x1091F,
+ },
+ [0x10920]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10920,
+ },
+ [0x10921]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10921,
+ },
+ [0x10922]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10922,
+ },
+ [0x10923]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10923,
+ },
+ [0x10924]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10924,
+ },
+ [0x10925]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10925,
+ },
+ [0x10926]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10926,
+ },
+ [0x10927]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10927,
+ },
+ [0x10928]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10928,
+ },
+ [0x10929]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10929,
+ },
+ [0x1092A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1092A,
+ },
+ [0x1092B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1092B,
+ },
+ [0x1092C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1092C,
+ },
+ [0x1092D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1092D,
+ },
+ [0x1092E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1092E,
+ },
+ [0x1092F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1092F,
+ },
+ [0x10930]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10930,
+ },
+ [0x10931]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10931,
+ },
+ [0x10932]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10932,
+ },
+ [0x10933]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10933,
+ },
+ [0x10934]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10934,
+ },
+ [0x10935]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10935,
+ },
+ [0x10936]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10936,
+ },
+ [0x10937]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10937,
+ },
+ [0x10938]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10938,
+ },
+ [0x10939]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10939,
+ },
+ [0x1093F]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1093F,
+ },
+ [0x10980]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10980,
+ },
+ [0x10981]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10981,
+ },
+ [0x10982]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10982,
+ },
+ [0x10983]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10983,
+ },
+ [0x10984]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10984,
+ },
+ [0x10985]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10985,
+ },
+ [0x10986]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10986,
+ },
+ [0x10987]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10987,
+ },
+ [0x10988]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10988,
+ },
+ [0x10989]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10989,
+ },
+ [0x1098A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1098A,
+ },
+ [0x1098B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1098B,
+ },
+ [0x1098C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1098C,
+ },
+ [0x1098D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1098D,
+ },
+ [0x1098E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1098E,
+ },
+ [0x1098F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1098F,
+ },
+ [0x10990]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10990,
+ },
+ [0x10991]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10991,
+ },
+ [0x10992]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10992,
+ },
+ [0x10993]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10993,
+ },
+ [0x10994]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10994,
+ },
+ [0x10995]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10995,
+ },
+ [0x10996]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10996,
+ },
+ [0x10997]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10997,
+ },
+ [0x10998]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10998,
+ },
+ [0x10999]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10999,
+ },
+ [0x1099A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1099A,
+ },
+ [0x1099B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1099B,
+ },
+ [0x1099C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1099C,
+ },
+ [0x1099D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1099D,
+ },
+ [0x1099E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1099E,
+ },
+ [0x1099F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1099F,
+ },
+ [0x109A0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A0,
+ },
+ [0x109A1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A1,
+ },
+ [0x109A2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A2,
+ },
+ [0x109A3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A3,
+ },
+ [0x109A4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A4,
+ },
+ [0x109A5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A5,
+ },
+ [0x109A6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A6,
+ },
+ [0x109A7]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A7,
+ },
+ [0x109A8]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A8,
+ },
+ [0x109A9]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A9,
+ },
+ [0x109AA]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109AA,
+ },
+ [0x109AB]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109AB,
+ },
+ [0x109AC]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109AC,
+ },
+ [0x109AD]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109AD,
+ },
+ [0x109AE]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109AE,
+ },
+ [0x109AF]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109AF,
+ },
+ [0x109B0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B0,
+ },
+ [0x109B1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B1,
+ },
+ [0x109B2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B2,
+ },
+ [0x109B3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B3,
+ },
+ [0x109B4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B4,
+ },
+ [0x109B5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B5,
+ },
+ [0x109B6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B6,
+ },
+ [0x109B7]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B7,
+ },
+ [0x109BC]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109BC,
+ },
+ [0x109BD]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109BD,
+ },
+ [0x109BE]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109BE,
+ },
+ [0x109BF]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109BF,
+ },
+ [0x109C0]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109C0,
+ },
+ [0x109C1]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109C1,
+ },
+ [0x109C2]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109C2,
+ },
+ [0x109C3]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109C3,
+ },
+ [0x109C4]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109C4,
+ },
+ [0x109C5]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109C5,
+ },
+ [0x109C6]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109C6,
+ },
+ [0x109C7]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109C7,
+ },
+ [0x109C8]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109C8,
+ },
+ [0x109C9]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109C9,
+ },
+ [0x109CA]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109CA,
+ },
+ [0x109CB]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109CB,
+ },
+ [0x109CC]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109CC,
+ },
+ [0x109CD]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109CD,
+ },
+ [0x109CE]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109CE,
+ },
+ [0x109CF]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109CF,
+ },
+ [0x109D2]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109D2,
+ },
+ [0x109D3]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109D3,
+ },
+ [0x109D4]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109D4,
+ },
+ [0x109D5]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109D5,
+ },
+ [0x109D6]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109D6,
+ },
+ [0x109D7]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109D7,
+ },
+ [0x109D8]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109D8,
+ },
+ [0x109D9]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109D9,
+ },
+ [0x109DA]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109DA,
+ },
+ [0x109DB]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109DB,
+ },
+ [0x109DC]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109DC,
+ },
+ [0x109DD]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109DD,
+ },
+ [0x109DE]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109DE,
+ },
+ [0x109DF]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109DF,
+ },
+ [0x109E0]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109E0,
+ },
+ [0x109E1]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109E1,
+ },
+ [0x109E2]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109E2,
+ },
+ [0x109E3]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109E3,
+ },
+ [0x109E4]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109E4,
+ },
+ [0x109E5]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109E5,
+ },
+ [0x109E6]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109E6,
+ },
+ [0x109E7]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109E7,
+ },
+ [0x109E8]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109E8,
+ },
+ [0x109E9]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109E9,
+ },
+ [0x109EA]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109EA,
+ },
+ [0x109EB]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109EB,
+ },
+ [0x109EC]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109EC,
+ },
+ [0x109ED]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109ED,
+ },
+ [0x109EE]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109EE,
+ },
+ [0x109EF]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109EF,
+ },
+ [0x109F0]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109F0,
+ },
+ [0x109F1]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109F1,
+ },
+ [0x109F2]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109F2,
+ },
+ [0x109F3]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109F3,
+ },
+ [0x109F4]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109F4,
+ },
+ [0x109F5]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109F5,
+ },
+ [0x109F6]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109F6,
+ },
+ [0x109F7]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109F7,
+ },
+ [0x109F8]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109F8,
+ },
+ [0x109F9]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109F9,
+ },
+ [0x109FA]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109FA,
+ },
+ [0x109FB]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109FB,
+ },
+ [0x109FC]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109FC,
+ },
+ [0x109FD]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109FD,
+ },
+ [0x109FE]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109FE,
+ },
+ [0x109FF]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109FF,
+ },
+ [0x10A00]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A00,
+ },
+ [0x10A01]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A01,
+ },
+ [0x10A02]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A02,
+ },
+ [0x10A03]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A03,
+ },
+ [0x10A05]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A05,
+ },
+ [0x10A06]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A06,
+ },
+ [0x10A0C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A0C,
+ },
+ [0x10A0D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A0D,
+ },
+ [0x10A0E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A0E,
+ },
+ [0x10A0F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A0F,
+ },
+ [0x10A10]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A10,
+ },
+ [0x10A11]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A11,
+ },
+ [0x10A12]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A12,
+ },
+ [0x10A13]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A13,
+ },
+ [0x10A15]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A15,
+ },
+ [0x10A16]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A16,
+ },
+ [0x10A17]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A17,
+ },
+ [0x10A19]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A19,
+ },
+ [0x10A1A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A1A,
+ },
+ [0x10A1B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A1B,
+ },
+ [0x10A1C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A1C,
+ },
+ [0x10A1D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A1D,
+ },
+ [0x10A1E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A1E,
+ },
+ [0x10A1F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A1F,
+ },
+ [0x10A20]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A20,
+ },
+ [0x10A21]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A21,
+ },
+ [0x10A22]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A22,
+ },
+ [0x10A23]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A23,
+ },
+ [0x10A24]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A24,
+ },
+ [0x10A25]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A25,
+ },
+ [0x10A26]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A26,
+ },
+ [0x10A27]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A27,
+ },
+ [0x10A28]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A28,
+ },
+ [0x10A29]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A29,
+ },
+ [0x10A2A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A2A,
+ },
+ [0x10A2B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A2B,
+ },
+ [0x10A2C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A2C,
+ },
+ [0x10A2D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A2D,
+ },
+ [0x10A2E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A2E,
+ },
+ [0x10A2F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A2F,
+ },
+ [0x10A30]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A30,
+ },
+ [0x10A31]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A31,
+ },
+ [0x10A32]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A32,
+ },
+ [0x10A33]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A33,
+ },
+ [0x10A34]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A34,
+ },
+ [0x10A35]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A35,
+ },
+ [0x10A38]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A38,
+ },
+ [0x10A39]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A39,
+ },
+ [0x10A3A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A3A,
+ },
+ [0x10A3F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A3F,
+ },
+ [0x10A40]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A40,
+ },
+ [0x10A41]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A41,
+ },
+ [0x10A42]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A42,
+ },
+ [0x10A43]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A43,
+ },
+ [0x10A44]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A44,
+ },
+ [0x10A45]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A45,
+ },
+ [0x10A46]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A46,
+ },
+ [0x10A47]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A47,
+ },
+ [0x10A48]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A48,
+ },
+ [0x10A50]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A50,
+ },
+ [0x10A51]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A51,
+ },
+ [0x10A52]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A52,
+ },
+ [0x10A53]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A53,
+ },
+ [0x10A54]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A54,
+ },
+ [0x10A55]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A55,
+ },
+ [0x10A56]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A56,
+ },
+ [0x10A57]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A57,
+ },
+ [0x10A58]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A58,
+ },
+ [0x10A60]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A60,
+ },
+ [0x10A61]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A61,
+ },
+ [0x10A62]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A62,
+ },
+ [0x10A63]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A63,
+ },
+ [0x10A64]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A64,
+ },
+ [0x10A65]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A65,
+ },
+ [0x10A66]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A66,
+ },
+ [0x10A67]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A67,
+ },
+ [0x10A68]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A68,
+ },
+ [0x10A69]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A69,
+ },
+ [0x10A6A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A6A,
+ },
+ [0x10A6B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A6B,
+ },
+ [0x10A6C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A6C,
+ },
+ [0x10A6D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A6D,
+ },
+ [0x10A6E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A6E,
+ },
+ [0x10A6F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A6F,
+ },
+ [0x10A70]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A70,
+ },
+ [0x10A71]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A71,
+ },
+ [0x10A72]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A72,
+ },
+ [0x10A73]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A73,
+ },
+ [0x10A74]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A74,
+ },
+ [0x10A75]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A75,
+ },
+ [0x10A76]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A76,
+ },
+ [0x10A77]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A77,
+ },
+ [0x10A78]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A78,
+ },
+ [0x10A79]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A79,
+ },
+ [0x10A7A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A7A,
+ },
+ [0x10A7B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A7B,
+ },
+ [0x10A7C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A7C,
+ },
+ [0x10A7D]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A7D,
+ },
+ [0x10A7E]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A7E,
+ },
+ [0x10A7F]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A7F,
+ },
+ [0x10A80]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A80,
+ },
+ [0x10A81]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A81,
+ },
+ [0x10A82]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A82,
+ },
+ [0x10A83]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A83,
+ },
+ [0x10A84]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A84,
+ },
+ [0x10A85]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A85,
+ },
+ [0x10A86]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A86,
+ },
+ [0x10A87]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A87,
+ },
+ [0x10A88]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A88,
+ },
+ [0x10A89]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A89,
+ },
+ [0x10A8A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A8A,
+ },
+ [0x10A8B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A8B,
+ },
+ [0x10A8C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A8C,
+ },
+ [0x10A8D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A8D,
+ },
+ [0x10A8E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A8E,
+ },
+ [0x10A8F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A8F,
+ },
+ [0x10A90]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A90,
+ },
+ [0x10A91]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A91,
+ },
+ [0x10A92]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A92,
+ },
+ [0x10A93]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A93,
+ },
+ [0x10A94]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A94,
+ },
+ [0x10A95]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A95,
+ },
+ [0x10A96]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A96,
+ },
+ [0x10A97]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A97,
+ },
+ [0x10A98]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A98,
+ },
+ [0x10A99]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A99,
+ },
+ [0x10A9A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A9A,
+ },
+ [0x10A9B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A9B,
+ },
+ [0x10A9C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A9C,
+ },
+ [0x10A9D]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A9D,
+ },
+ [0x10A9E]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A9E,
+ },
+ [0x10A9F]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A9F,
+ },
+ [0x10AC0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AC0,
+ },
+ [0x10AC1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AC1,
+ },
+ [0x10AC2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AC2,
+ },
+ [0x10AC3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AC3,
+ },
+ [0x10AC4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AC4,
+ },
+ [0x10AC5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AC5,
+ },
+ [0x10AC6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AC6,
+ },
+ [0x10AC7]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AC7,
+ },
+ [0x10AC8]={
+ category="so",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AC8,
+ },
+ [0x10AC9]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AC9,
+ },
+ [0x10ACA]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10ACA,
+ },
+ [0x10ACB]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10ACB,
+ },
+ [0x10ACC]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10ACC,
+ },
+ [0x10ACD]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10ACD,
+ },
+ [0x10ACE]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10ACE,
+ },
+ [0x10ACF]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10ACF,
+ },
+ [0x10AD0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AD0,
+ },
+ [0x10AD1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AD1,
+ },
+ [0x10AD2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AD2,
+ },
+ [0x10AD3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AD3,
+ },
+ [0x10AD4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AD4,
+ },
+ [0x10AD5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AD5,
+ },
+ [0x10AD6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AD6,
+ },
+ [0x10AD7]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AD7,
+ },
+ [0x10AD8]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AD8,
+ },
+ [0x10AD9]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AD9,
+ },
+ [0x10ADA]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10ADA,
+ },
+ [0x10ADB]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10ADB,
+ },
+ [0x10ADC]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10ADC,
+ },
+ [0x10ADD]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10ADD,
+ },
+ [0x10ADE]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10ADE,
+ },
+ [0x10ADF]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10ADF,
+ },
+ [0x10AE0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AE0,
+ },
+ [0x10AE1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AE1,
+ },
+ [0x10AE2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AE2,
+ },
+ [0x10AE3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AE3,
+ },
+ [0x10AE4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AE4,
+ },
+ [0x10AE5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10AE5,
+ },
+ [0x10AE6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10AE6,
+ },
+ [0x10AEB]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AEB,
+ },
+ [0x10AEC]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AEC,
+ },
+ [0x10AED]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AED,
+ },
+ [0x10AEE]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AEE,
+ },
+ [0x10AEF]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10AEF,
+ },
+ [0x10AF0]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10AF0,
+ },
+ [0x10AF1]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10AF1,
+ },
+ [0x10AF2]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10AF2,
+ },
+ [0x10AF3]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10AF3,
+ },
+ [0x10AF4]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10AF4,
+ },
+ [0x10AF5]={
+ category="po",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10AF5,
+ },
+ [0x10AF6]={
+ category="po",
+ direction="r",
+ linebreak="in",
+ unicodeslot=0x10AF6,
+ },
+ [0x10B00]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B00,
+ },
+ [0x10B01]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B01,
+ },
+ [0x10B02]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B02,
+ },
+ [0x10B03]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B03,
+ },
+ [0x10B04]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B04,
+ },
+ [0x10B05]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B05,
+ },
+ [0x10B06]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B06,
+ },
+ [0x10B07]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B07,
+ },
+ [0x10B08]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B08,
+ },
+ [0x10B09]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B09,
+ },
+ [0x10B0A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B0A,
+ },
+ [0x10B0B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B0B,
+ },
+ [0x10B0C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B0C,
+ },
+ [0x10B0D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B0D,
+ },
+ [0x10B0E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B0E,
+ },
+ [0x10B0F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B0F,
+ },
+ [0x10B10]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B10,
+ },
+ [0x10B11]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B11,
+ },
+ [0x10B12]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B12,
+ },
+ [0x10B13]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B13,
+ },
+ [0x10B14]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B14,
+ },
+ [0x10B15]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B15,
+ },
+ [0x10B16]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B16,
+ },
+ [0x10B17]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B17,
+ },
+ [0x10B18]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B18,
+ },
+ [0x10B19]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B19,
+ },
+ [0x10B1A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B1A,
+ },
+ [0x10B1B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B1B,
+ },
+ [0x10B1C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B1C,
+ },
+ [0x10B1D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B1D,
+ },
+ [0x10B1E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B1E,
+ },
+ [0x10B1F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B1F,
+ },
+ [0x10B20]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B20,
+ },
+ [0x10B21]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B21,
+ },
+ [0x10B22]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B22,
+ },
+ [0x10B23]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B23,
+ },
+ [0x10B24]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B24,
+ },
+ [0x10B25]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B25,
+ },
+ [0x10B26]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B26,
+ },
+ [0x10B27]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B27,
+ },
+ [0x10B28]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B28,
+ },
+ [0x10B29]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B29,
+ },
+ [0x10B2A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B2A,
+ },
+ [0x10B2B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B2B,
+ },
+ [0x10B2C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B2C,
+ },
+ [0x10B2D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B2D,
+ },
+ [0x10B2E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B2E,
+ },
+ [0x10B2F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B2F,
+ },
+ [0x10B30]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B30,
+ },
+ [0x10B31]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B31,
+ },
+ [0x10B32]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B32,
+ },
+ [0x10B33]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B33,
+ },
+ [0x10B34]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B34,
+ },
+ [0x10B35]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B35,
+ },
+ [0x10B39]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B39,
+ },
+ [0x10B3A]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B3A,
+ },
+ [0x10B3B]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B3B,
+ },
+ [0x10B3C]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B3C,
+ },
+ [0x10B3D]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B3D,
+ },
+ [0x10B3E]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B3E,
+ },
+ [0x10B3F]={
+ category="po",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B3F,
+ },
+ [0x10B40]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B40,
+ },
+ [0x10B41]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B41,
+ },
+ [0x10B42]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B42,
+ },
+ [0x10B43]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B43,
+ },
+ [0x10B44]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B44,
+ },
+ [0x10B45]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B45,
+ },
+ [0x10B46]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B46,
+ },
+ [0x10B47]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B47,
+ },
+ [0x10B48]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B48,
+ },
+ [0x10B49]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B49,
+ },
+ [0x10B4A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B4A,
+ },
+ [0x10B4B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B4B,
+ },
+ [0x10B4C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B4C,
+ },
+ [0x10B4D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B4D,
+ },
+ [0x10B4E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B4E,
+ },
+ [0x10B4F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B4F,
+ },
+ [0x10B50]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B50,
+ },
+ [0x10B51]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B51,
+ },
+ [0x10B52]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B52,
+ },
+ [0x10B53]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B53,
+ },
+ [0x10B54]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B54,
+ },
+ [0x10B55]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B55,
+ },
+ [0x10B58]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B58,
+ },
+ [0x10B59]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B59,
+ },
+ [0x10B5A]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B5A,
+ },
+ [0x10B5B]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B5B,
+ },
+ [0x10B5C]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B5C,
+ },
+ [0x10B5D]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B5D,
+ },
+ [0x10B5E]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B5E,
+ },
+ [0x10B5F]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B5F,
+ },
+ [0x10B60]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B60,
+ },
+ [0x10B61]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B61,
+ },
+ [0x10B62]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B62,
+ },
+ [0x10B63]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B63,
+ },
+ [0x10B64]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B64,
+ },
+ [0x10B65]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B65,
+ },
+ [0x10B66]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B66,
+ },
+ [0x10B67]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B67,
+ },
+ [0x10B68]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B68,
+ },
+ [0x10B69]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B69,
+ },
+ [0x10B6A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B6A,
+ },
+ [0x10B6B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B6B,
+ },
+ [0x10B6C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B6C,
+ },
+ [0x10B6D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B6D,
+ },
+ [0x10B6E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B6E,
+ },
+ [0x10B6F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B6F,
+ },
+ [0x10B70]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B70,
+ },
+ [0x10B71]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B71,
+ },
+ [0x10B72]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B72,
+ },
+ [0x10B78]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B78,
+ },
+ [0x10B79]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B79,
+ },
+ [0x10B7A]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B7A,
+ },
+ [0x10B7B]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B7B,
+ },
+ [0x10B7C]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B7C,
+ },
+ [0x10B7D]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B7D,
+ },
+ [0x10B7E]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B7E,
+ },
+ [0x10B7F]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B7F,
+ },
+ [0x10B80]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B80,
+ },
+ [0x10B81]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B81,
+ },
+ [0x10B82]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B82,
+ },
+ [0x10B83]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B83,
+ },
+ [0x10B84]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B84,
+ },
+ [0x10B85]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B85,
+ },
+ [0x10B86]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B86,
+ },
+ [0x10B87]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B87,
+ },
+ [0x10B88]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B88,
+ },
+ [0x10B89]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B89,
+ },
+ [0x10B8A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B8A,
+ },
+ [0x10B8B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B8B,
+ },
+ [0x10B8C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B8C,
+ },
+ [0x10B8D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B8D,
+ },
+ [0x10B8E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B8E,
+ },
+ [0x10B8F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B8F,
+ },
+ [0x10B90]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B90,
+ },
+ [0x10B91]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B91,
+ },
+ [0x10B99]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B99,
+ },
+ [0x10B9A]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B9A,
+ },
+ [0x10B9B]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B9B,
+ },
+ [0x10B9C]={
+ category="po",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B9C,
+ },
+ [0x10BA9]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10BA9,
+ },
+ [0x10BAA]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10BAA,
+ },
+ [0x10BAB]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10BAB,
+ },
+ [0x10BAC]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10BAC,
+ },
+ [0x10BAD]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10BAD,
+ },
+ [0x10BAE]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10BAE,
+ },
+ [0x10BAF]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10BAF,
+ },
+ [0x10C00]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C00,
+ },
+ [0x10C01]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C01,
+ },
+ [0x10C02]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C02,
+ },
+ [0x10C03]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C03,
+ },
+ [0x10C04]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C04,
+ },
+ [0x10C05]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C05,
+ },
+ [0x10C06]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C06,
+ },
+ [0x10C07]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C07,
+ },
+ [0x10C08]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C08,
+ },
+ [0x10C09]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C09,
+ },
+ [0x10C0A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C0A,
+ },
+ [0x10C0B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C0B,
+ },
+ [0x10C0C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C0C,
+ },
+ [0x10C0D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C0D,
+ },
+ [0x10C0E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C0E,
+ },
+ [0x10C0F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C0F,
+ },
+ [0x10C10]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C10,
+ },
+ [0x10C11]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C11,
+ },
+ [0x10C12]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C12,
+ },
+ [0x10C13]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C13,
+ },
+ [0x10C14]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C14,
+ },
+ [0x10C15]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C15,
+ },
+ [0x10C16]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C16,
+ },
+ [0x10C17]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C17,
+ },
+ [0x10C18]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C18,
+ },
+ [0x10C19]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C19,
+ },
+ [0x10C1A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C1A,
+ },
+ [0x10C1B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C1B,
+ },
+ [0x10C1C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C1C,
+ },
+ [0x10C1D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C1D,
+ },
+ [0x10C1E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C1E,
+ },
+ [0x10C1F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C1F,
+ },
+ [0x10C20]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C20,
+ },
+ [0x10C21]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C21,
+ },
+ [0x10C22]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C22,
+ },
+ [0x10C23]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C23,
+ },
+ [0x10C24]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C24,
+ },
+ [0x10C25]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C25,
+ },
+ [0x10C26]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C26,
+ },
+ [0x10C27]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C27,
+ },
+ [0x10C28]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C28,
+ },
+ [0x10C29]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C29,
+ },
+ [0x10C2A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C2A,
+ },
+ [0x10C2B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C2B,
+ },
+ [0x10C2C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C2C,
+ },
+ [0x10C2D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C2D,
+ },
+ [0x10C2E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C2E,
+ },
+ [0x10C2F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C2F,
+ },
+ [0x10C30]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C30,
+ },
+ [0x10C31]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C31,
+ },
+ [0x10C32]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C32,
+ },
+ [0x10C33]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C33,
+ },
+ [0x10C34]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C34,
+ },
+ [0x10C35]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C35,
+ },
+ [0x10C36]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C36,
+ },
+ [0x10C37]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C37,
+ },
+ [0x10C38]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C38,
+ },
+ [0x10C39]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C39,
+ },
+ [0x10C3A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C3A,
+ },
+ [0x10C3B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C3B,
+ },
+ [0x10C3C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C3C,
+ },
+ [0x10C3D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C3D,
+ },
+ [0x10C3E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C3E,
+ },
+ [0x10C3F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C3F,
+ },
+ [0x10C40]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C40,
+ },
+ [0x10C41]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C41,
+ },
+ [0x10C42]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C42,
+ },
+ [0x10C43]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C43,
+ },
+ [0x10C44]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C44,
+ },
+ [0x10C45]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C45,
+ },
+ [0x10C46]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C46,
+ },
+ [0x10C47]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C47,
+ },
+ [0x10C48]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C48,
+ },
+ [0x10C80]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C80,
+ },
+ [0x10C81]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C81,
+ },
+ [0x10C82]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C82,
+ },
+ [0x10C83]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C83,
+ },
+ [0x10C84]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C84,
+ },
+ [0x10C85]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C85,
+ },
+ [0x10C86]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C86,
+ },
+ [0x10C87]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C87,
+ },
+ [0x10C88]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C88,
+ },
+ [0x10C89]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C89,
+ },
+ [0x10C8A]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C8A,
+ },
+ [0x10C8B]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C8B,
+ },
+ [0x10C8C]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C8C,
+ },
+ [0x10C8D]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C8D,
+ },
+ [0x10C8E]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C8E,
+ },
+ [0x10C8F]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C8F,
+ },
+ [0x10C90]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C90,
+ },
+ [0x10C91]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C91,
+ },
+ [0x10C92]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C92,
+ },
+ [0x10C93]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C93,
+ },
+ [0x10C94]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C94,
+ },
+ [0x10C95]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C95,
+ },
+ [0x10C96]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C96,
+ },
+ [0x10C97]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C97,
+ },
+ [0x10C98]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C98,
+ },
+ [0x10C99]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C99,
+ },
+ [0x10C9A]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C9A,
+ },
+ [0x10C9B]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C9B,
+ },
+ [0x10C9C]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C9C,
+ },
+ [0x10C9D]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C9D,
+ },
+ [0x10C9E]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C9E,
+ },
+ [0x10C9F]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C9F,
+ },
+ [0x10CA0]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CA0,
+ },
+ [0x10CA1]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CA1,
+ },
+ [0x10CA2]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CA2,
+ },
+ [0x10CA3]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CA3,
+ },
+ [0x10CA4]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CA4,
+ },
+ [0x10CA5]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CA5,
+ },
+ [0x10CA6]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CA6,
+ },
+ [0x10CA7]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CA7,
+ },
+ [0x10CA8]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CA8,
+ },
+ [0x10CA9]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CA9,
+ },
+ [0x10CAA]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CAA,
+ },
+ [0x10CAB]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CAB,
+ },
+ [0x10CAC]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CAC,
+ },
+ [0x10CAD]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CAD,
+ },
+ [0x10CAE]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CAE,
+ },
+ [0x10CAF]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CAF,
+ },
+ [0x10CB0]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CB0,
+ },
+ [0x10CB1]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CB1,
+ },
+ [0x10CB2]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CB2,
+ },
+ [0x10CC0]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CC0,
+ },
+ [0x10CC1]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CC1,
+ },
+ [0x10CC2]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CC2,
+ },
+ [0x10CC3]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CC3,
+ },
+ [0x10CC4]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CC4,
+ },
+ [0x10CC5]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CC5,
+ },
+ [0x10CC6]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CC6,
+ },
+ [0x10CC7]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CC7,
+ },
+ [0x10CC8]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CC8,
+ },
+ [0x10CC9]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CC9,
+ },
+ [0x10CCA]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CCA,
+ },
+ [0x10CCB]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CCB,
+ },
+ [0x10CCC]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CCC,
+ },
+ [0x10CCD]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CCD,
+ },
+ [0x10CCE]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CCE,
+ },
+ [0x10CCF]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CCF,
+ },
+ [0x10CD0]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CD0,
+ },
+ [0x10CD1]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CD1,
+ },
+ [0x10CD2]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CD2,
+ },
+ [0x10CD3]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CD3,
+ },
+ [0x10CD4]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CD4,
+ },
+ [0x10CD5]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CD5,
+ },
+ [0x10CD6]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CD6,
+ },
+ [0x10CD7]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CD7,
+ },
+ [0x10CD8]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CD8,
+ },
+ [0x10CD9]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CD9,
+ },
+ [0x10CDA]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CDA,
+ },
+ [0x10CDB]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CDB,
+ },
+ [0x10CDC]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CDC,
+ },
+ [0x10CDD]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CDD,
+ },
+ [0x10CDE]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CDE,
+ },
+ [0x10CDF]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CDF,
+ },
+ [0x10CE0]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CE0,
+ },
+ [0x10CE1]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CE1,
+ },
+ [0x10CE2]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CE2,
+ },
+ [0x10CE3]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CE3,
+ },
+ [0x10CE4]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CE4,
+ },
+ [0x10CE5]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CE5,
+ },
+ [0x10CE6]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CE6,
+ },
+ [0x10CE7]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CE7,
+ },
+ [0x10CE8]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CE8,
+ },
+ [0x10CE9]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CE9,
+ },
+ [0x10CEA]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CEA,
+ },
+ [0x10CEB]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CEB,
+ },
+ [0x10CEC]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CEC,
+ },
+ [0x10CED]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CED,
+ },
+ [0x10CEE]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CEE,
+ },
+ [0x10CEF]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CEF,
+ },
+ [0x10CF0]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CF0,
+ },
+ [0x10CF1]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CF1,
+ },
+ [0x10CF2]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CF2,
+ },
+ [0x10CFA]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CFA,
+ },
+ [0x10CFB]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CFB,
+ },
+ [0x10CFC]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CFC,
+ },
+ [0x10CFD]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CFD,
+ },
+ [0x10CFE]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CFE,
+ },
+ [0x10CFF]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10CFF,
+ },
+ [0x10D00]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D00,
+ },
+ [0x10D01]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D01,
+ },
+ [0x10D02]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D02,
+ },
+ [0x10D03]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D03,
+ },
+ [0x10D04]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D04,
+ },
+ [0x10D05]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D05,
+ },
+ [0x10D06]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D06,
+ },
+ [0x10D07]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D07,
+ },
+ [0x10D08]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D08,
+ },
+ [0x10D09]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D09,
+ },
+ [0x10D0A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D0A,
+ },
+ [0x10D0B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D0B,
+ },
+ [0x10D0C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D0C,
+ },
+ [0x10D0D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D0D,
+ },
+ [0x10D0E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D0E,
+ },
+ [0x10D0F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D0F,
+ },
+ [0x10D10]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D10,
+ },
+ [0x10D11]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D11,
+ },
+ [0x10D12]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D12,
+ },
+ [0x10D13]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D13,
+ },
+ [0x10D14]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D14,
+ },
+ [0x10D15]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D15,
+ },
+ [0x10D16]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D16,
+ },
+ [0x10D17]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D17,
+ },
+ [0x10D18]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D18,
+ },
+ [0x10D19]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D19,
+ },
+ [0x10D1A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D1A,
+ },
+ [0x10D1B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D1B,
+ },
+ [0x10D1C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D1C,
+ },
+ [0x10D1D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D1D,
+ },
+ [0x10D1E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D1E,
+ },
+ [0x10D1F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D1F,
+ },
+ [0x10D20]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D20,
+ },
+ [0x10D21]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D21,
+ },
+ [0x10D22]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D22,
+ },
+ [0x10D23]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10D23,
+ },
+ [0x10D24]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10D24,
+ },
+ [0x10D25]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10D25,
+ },
+ [0x10D26]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10D26,
+ },
+ [0x10D27]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10D27,
+ },
+ [0x10D30]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x10D30,
+ },
+ [0x10D31]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x10D31,
+ },
+ [0x10D32]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x10D32,
+ },
+ [0x10D33]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x10D33,
+ },
+ [0x10D34]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x10D34,
+ },
+ [0x10D35]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x10D35,
+ },
+ [0x10D36]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x10D36,
+ },
+ [0x10D37]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x10D37,
+ },
+ [0x10D38]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x10D38,
+ },
+ [0x10D39]={
+ category="nd",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x10D39,
+ },
+ [0x10E60]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E60,
+ },
+ [0x10E61]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E61,
+ },
+ [0x10E62]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E62,
+ },
+ [0x10E63]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E63,
+ },
+ [0x10E64]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E64,
+ },
+ [0x10E65]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E65,
+ },
+ [0x10E66]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E66,
+ },
+ [0x10E67]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E67,
+ },
+ [0x10E68]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E68,
+ },
+ [0x10E69]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E69,
+ },
+ [0x10E6A]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E6A,
+ },
+ [0x10E6B]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E6B,
+ },
+ [0x10E6C]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E6C,
+ },
+ [0x10E6D]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E6D,
+ },
+ [0x10E6E]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E6E,
+ },
+ [0x10E6F]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E6F,
+ },
+ [0x10E70]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E70,
+ },
+ [0x10E71]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E71,
+ },
+ [0x10E72]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E72,
+ },
+ [0x10E73]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E73,
+ },
+ [0x10E74]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E74,
+ },
+ [0x10E75]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E75,
+ },
+ [0x10E76]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E76,
+ },
+ [0x10E77]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E77,
+ },
+ [0x10E78]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E78,
+ },
+ [0x10E79]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E79,
+ },
+ [0x10E7A]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E7A,
+ },
+ [0x10E7B]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E7B,
+ },
+ [0x10E7C]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E7C,
+ },
+ [0x10E7D]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E7D,
+ },
+ [0x10E7E]={
+ category="no",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E7E,
+ },
+ [0x10F00]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F00,
+ },
+ [0x10F01]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F01,
+ },
+ [0x10F02]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F02,
+ },
+ [0x10F03]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F03,
+ },
+ [0x10F04]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F04,
+ },
+ [0x10F05]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F05,
+ },
+ [0x10F06]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F06,
+ },
+ [0x10F07]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F07,
+ },
+ [0x10F08]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F08,
+ },
+ [0x10F09]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F09,
+ },
+ [0x10F0A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F0A,
+ },
+ [0x10F0B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F0B,
+ },
+ [0x10F0C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F0C,
+ },
+ [0x10F0D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F0D,
+ },
+ [0x10F0E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F0E,
+ },
+ [0x10F0F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F0F,
+ },
+ [0x10F10]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F10,
+ },
+ [0x10F11]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F11,
+ },
+ [0x10F12]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F12,
+ },
+ [0x10F13]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F13,
+ },
+ [0x10F14]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F14,
+ },
+ [0x10F15]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F15,
+ },
+ [0x10F16]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F16,
+ },
+ [0x10F17]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F17,
+ },
+ [0x10F18]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F18,
+ },
+ [0x10F19]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F19,
+ },
+ [0x10F1A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F1A,
+ },
+ [0x10F1B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F1B,
+ },
+ [0x10F1C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F1C,
+ },
+ [0x10F1D]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F1D,
+ },
+ [0x10F1E]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F1E,
+ },
+ [0x10F1F]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F1F,
+ },
+ [0x10F20]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F20,
+ },
+ [0x10F21]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F21,
+ },
+ [0x10F22]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F22,
+ },
+ [0x10F23]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F23,
+ },
+ [0x10F24]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F24,
+ },
+ [0x10F25]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F25,
+ },
+ [0x10F26]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F26,
+ },
+ [0x10F27]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10F27,
+ },
+ [0x10F30]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F30,
+ },
+ [0x10F31]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F31,
+ },
+ [0x10F32]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F32,
+ },
+ [0x10F33]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F33,
+ },
+ [0x10F34]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F34,
+ },
+ [0x10F35]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F35,
+ },
+ [0x10F36]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F36,
+ },
+ [0x10F37]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F37,
+ },
+ [0x10F38]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F38,
+ },
+ [0x10F39]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F39,
+ },
+ [0x10F3A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F3A,
+ },
+ [0x10F3B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F3B,
+ },
+ [0x10F3C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F3C,
+ },
+ [0x10F3D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F3D,
+ },
+ [0x10F3E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F3E,
+ },
+ [0x10F3F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F3F,
+ },
+ [0x10F40]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F40,
+ },
+ [0x10F41]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F41,
+ },
+ [0x10F42]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F42,
+ },
+ [0x10F43]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F43,
+ },
+ [0x10F44]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F44,
+ },
+ [0x10F45]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F45,
+ },
+ [0x10F46]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10F46,
+ },
+ [0x10F47]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10F47,
+ },
+ [0x10F48]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10F48,
+ },
+ [0x10F49]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10F49,
+ },
+ [0x10F4A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10F4A,
+ },
+ [0x10F4B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10F4B,
+ },
+ [0x10F4C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10F4C,
+ },
+ [0x10F4D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10F4D,
+ },
+ [0x10F4E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10F4E,
+ },
+ [0x10F4F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10F4F,
+ },
+ [0x10F50]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10F50,
+ },
+ [0x10F51]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F51,
+ },
+ [0x10F52]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F52,
+ },
+ [0x10F53]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F53,
+ },
+ [0x10F54]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F54,
+ },
+ [0x10F55]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F55,
+ },
+ [0x10F56]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F56,
+ },
+ [0x10F57]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F57,
+ },
+ [0x10F58]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F58,
+ },
+ [0x10F59]={
+ category="po",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x10F59,
+ },
+ [0x10FE0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FE0,
+ },
+ [0x10FE1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FE1,
+ },
+ [0x10FE2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FE2,
+ },
+ [0x10FE3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FE3,
+ },
+ [0x10FE4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FE4,
+ },
+ [0x10FE5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FE5,
+ },
+ [0x10FE6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FE6,
+ },
+ [0x10FE7]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FE7,
+ },
+ [0x10FE8]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FE8,
+ },
+ [0x10FE9]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FE9,
+ },
+ [0x10FEA]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FEA,
+ },
+ [0x10FEB]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FEB,
+ },
+ [0x10FEC]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FEC,
+ },
+ [0x10FED]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FED,
+ },
+ [0x10FEE]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FEE,
+ },
+ [0x10FEF]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FEF,
+ },
+ [0x10FF0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FF0,
+ },
+ [0x10FF1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FF1,
+ },
+ [0x10FF2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FF2,
+ },
+ [0x10FF3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FF3,
+ },
+ [0x10FF4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FF4,
+ },
+ [0x10FF5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FF5,
+ },
+ [0x10FF6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FF6,
+ },
+ [0x11000]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11000,
+ },
+ [0x11001]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11001,
+ },
+ [0x11002]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11002,
+ },
+ [0x11003]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11003,
+ },
+ [0x11004]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11004,
+ },
+ [0x11005]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11005,
+ },
+ [0x11006]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11006,
+ },
+ [0x11007]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11007,
+ },
+ [0x11008]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11008,
+ },
+ [0x11009]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11009,
+ },
+ [0x1100A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1100A,
+ },
+ [0x1100B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1100B,
+ },
+ [0x1100C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1100C,
+ },
+ [0x1100D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1100D,
+ },
+ [0x1100E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1100E,
+ },
+ [0x1100F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1100F,
+ },
+ [0x11010]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11010,
+ },
+ [0x11011]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11011,
+ },
+ [0x11012]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11012,
+ },
+ [0x11013]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11013,
+ },
+ [0x11014]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11014,
+ },
+ [0x11015]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11015,
+ },
+ [0x11016]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11016,
+ },
+ [0x11017]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11017,
+ },
+ [0x11018]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11018,
+ },
+ [0x11019]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11019,
+ },
+ [0x1101A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1101A,
+ },
+ [0x1101B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1101B,
+ },
+ [0x1101C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1101C,
+ },
+ [0x1101D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1101D,
+ },
+ [0x1101E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1101E,
+ },
+ [0x1101F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1101F,
+ },
+ [0x11020]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11020,
+ },
+ [0x11021]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11021,
+ },
+ [0x11022]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11022,
+ },
+ [0x11023]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11023,
+ },
+ [0x11024]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11024,
+ },
+ [0x11025]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11025,
+ },
+ [0x11026]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11026,
+ },
+ [0x11027]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11027,
+ },
+ [0x11028]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11028,
+ },
+ [0x11029]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11029,
+ },
+ [0x1102A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1102A,
+ },
+ [0x1102B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1102B,
+ },
+ [0x1102C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1102C,
+ },
+ [0x1102D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1102D,
+ },
+ [0x1102E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1102E,
+ },
+ [0x1102F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1102F,
+ },
+ [0x11030]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11030,
+ },
+ [0x11031]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11031,
+ },
+ [0x11032]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11032,
+ },
+ [0x11033]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11033,
+ },
+ [0x11034]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11034,
+ },
+ [0x11035]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11035,
+ },
+ [0x11036]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11036,
+ },
+ [0x11037]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11037,
+ },
+ [0x11038]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11038,
+ },
+ [0x11039]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11039,
+ },
+ [0x1103A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1103A,
+ },
+ [0x1103B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1103B,
+ },
+ [0x1103C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1103C,
+ },
+ [0x1103D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1103D,
+ },
+ [0x1103E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1103E,
+ },
+ [0x1103F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1103F,
+ },
+ [0x11040]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11040,
+ },
+ [0x11041]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11041,
+ },
+ [0x11042]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11042,
+ },
+ [0x11043]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11043,
+ },
+ [0x11044]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11044,
+ },
+ [0x11045]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11045,
+ },
+ [0x11046]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11046,
+ },
+ [0x11047]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11047,
+ },
+ [0x11048]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11048,
+ },
+ [0x11049]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11049,
+ },
+ [0x1104A]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1104A,
+ },
+ [0x1104B]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1104B,
+ },
+ [0x1104C]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1104C,
+ },
+ [0x1104D]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1104D,
+ },
+ [0x11052]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11052,
+ },
+ [0x11053]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11053,
+ },
+ [0x11054]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11054,
+ },
+ [0x11055]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11055,
+ },
+ [0x11056]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11056,
+ },
+ [0x11057]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11057,
+ },
+ [0x11058]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11058,
+ },
+ [0x11059]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11059,
+ },
+ [0x1105A]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1105A,
+ },
+ [0x1105B]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1105B,
+ },
+ [0x1105C]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1105C,
+ },
+ [0x1105D]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1105D,
+ },
+ [0x1105E]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1105E,
+ },
+ [0x1105F]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1105F,
+ },
+ [0x11060]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11060,
+ },
+ [0x11061]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11061,
+ },
+ [0x11062]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11062,
+ },
+ [0x11063]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11063,
+ },
+ [0x11064]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11064,
+ },
+ [0x11065]={
+ category="no",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11065,
+ },
+ [0x11066]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11066,
+ },
+ [0x11067]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11067,
+ },
+ [0x11068]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11068,
+ },
+ [0x11069]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11069,
+ },
+ [0x1106A]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1106A,
+ },
+ [0x1106B]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1106B,
+ },
+ [0x1106C]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1106C,
+ },
+ [0x1106D]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1106D,
+ },
+ [0x1106E]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1106E,
+ },
+ [0x1106F]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1106F,
+ },
+ [0x1107F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1107F,
+ },
+ [0x11080]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11080,
+ },
+ [0x11081]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11081,
+ },
+ [0x11082]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11082,
+ },
+ [0x11083]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11083,
+ },
+ [0x11084]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11084,
+ },
+ [0x11085]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11085,
+ },
+ [0x11086]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11086,
+ },
+ [0x11087]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11087,
+ },
+ [0x11088]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11088,
+ },
+ [0x11089]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11089,
+ },
+ [0x1108A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1108A,
+ },
+ [0x1108B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1108B,
+ },
+ [0x1108C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1108C,
+ },
+ [0x1108D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1108D,
+ },
+ [0x1108E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1108E,
+ },
+ [0x1108F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1108F,
+ },
+ [0x11090]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11090,
+ },
+ [0x11091]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11091,
+ },
+ [0x11092]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11092,
+ },
+ [0x11093]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11093,
+ },
+ [0x11094]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11094,
+ },
+ [0x11095]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11095,
+ },
+ [0x11096]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11096,
+ },
+ [0x11097]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11097,
+ },
+ [0x11098]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11098,
+ },
+ [0x11099]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11099,
+ },
+ [0x1109A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x11099, 0x110BA },
+ unicodeslot=0x1109A,
+ },
+ [0x1109B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1109B,
+ },
+ [0x1109C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1109B, 0x110BA },
+ unicodeslot=0x1109C,
+ },
+ [0x1109D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1109D,
+ },
+ [0x1109E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1109E,
+ },
+ [0x1109F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1109F,
+ },
+ [0x110A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A0,
+ },
+ [0x110A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A1,
+ },
+ [0x110A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A2,
+ },
+ [0x110A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A3,
+ },
+ [0x110A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A4,
+ },
+ [0x110A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A5,
+ },
+ [0x110A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A6,
+ },
+ [0x110A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A7,
+ },
+ [0x110A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A8,
+ },
+ [0x110A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A9,
+ },
+ [0x110AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110AA,
+ },
+ [0x110AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x110A5, 0x110BA },
+ unicodeslot=0x110AB,
+ },
+ [0x110AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110AC,
+ },
+ [0x110AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110AD,
+ },
+ [0x110AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110AE,
+ },
+ [0x110AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110AF,
+ },
+ [0x110B0]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x110B0,
+ },
+ [0x110B1]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x110B1,
+ },
+ [0x110B2]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x110B2,
+ },
+ [0x110B3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x110B3,
+ },
+ [0x110B4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x110B4,
+ },
+ [0x110B5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x110B5,
+ },
+ [0x110B6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x110B6,
+ },
+ [0x110B7]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x110B7,
+ },
+ [0x110B8]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x110B8,
+ },
+ [0x110B9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x110B9,
+ },
+ [0x110BA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x110BA,
+ },
+ [0x110BB]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110BB,
+ },
+ [0x110BC]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110BC,
+ },
+ [0x110BD]={
+ category="cf",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110BD,
+ },
+ [0x110BE]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x110BE,
+ },
+ [0x110BF]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x110BF,
+ },
+ [0x110C0]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x110C0,
+ },
+ [0x110C1]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x110C1,
+ },
+ [0x110CD]={
+ category="cf",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110CD,
+ },
+ [0x110D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D0,
+ },
+ [0x110D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D1,
+ },
+ [0x110D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D2,
+ },
+ [0x110D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D3,
+ },
+ [0x110D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D4,
+ },
+ [0x110D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D5,
+ },
+ [0x110D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D6,
+ },
+ [0x110D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D7,
+ },
+ [0x110D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D8,
+ },
+ [0x110D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D9,
+ },
+ [0x110DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110DA,
+ },
+ [0x110DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110DB,
+ },
+ [0x110DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110DC,
+ },
+ [0x110DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110DD,
+ },
+ [0x110DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110DE,
+ },
+ [0x110DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110DF,
+ },
+ [0x110E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E0,
+ },
+ [0x110E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E1,
+ },
+ [0x110E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E2,
+ },
+ [0x110E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E3,
+ },
+ [0x110E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E4,
+ },
+ [0x110E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E5,
+ },
+ [0x110E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E6,
+ },
+ [0x110E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E7,
+ },
+ [0x110E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E8,
+ },
+ [0x110F0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F0,
+ },
+ [0x110F1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F1,
+ },
+ [0x110F2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F2,
+ },
+ [0x110F3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F3,
+ },
+ [0x110F4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F4,
+ },
+ [0x110F5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F5,
+ },
+ [0x110F6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F6,
+ },
+ [0x110F7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F7,
+ },
+ [0x110F8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F8,
+ },
+ [0x110F9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F9,
+ },
+ [0x11100]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11100,
+ },
+ [0x11101]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11101,
+ },
+ [0x11102]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11102,
+ },
+ [0x11103]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11103,
+ },
+ [0x11104]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11104,
+ },
+ [0x11105]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11105,
+ },
+ [0x11106]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11106,
+ },
+ [0x11107]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11107,
+ },
+ [0x11108]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11108,
+ },
+ [0x11109]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11109,
+ },
+ [0x1110A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1110A,
+ },
+ [0x1110B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1110B,
+ },
+ [0x1110C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1110C,
+ },
+ [0x1110D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1110D,
+ },
+ [0x1110E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1110E,
+ },
+ [0x1110F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1110F,
+ },
+ [0x11110]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11110,
+ },
+ [0x11111]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11111,
+ },
+ [0x11112]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11112,
+ },
+ [0x11113]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11113,
+ },
+ [0x11114]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11114,
+ },
+ [0x11115]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11115,
+ },
+ [0x11116]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11116,
+ },
+ [0x11117]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11117,
+ },
+ [0x11118]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11118,
+ },
+ [0x11119]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11119,
+ },
+ [0x1111A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1111A,
+ },
+ [0x1111B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1111B,
+ },
+ [0x1111C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1111C,
+ },
+ [0x1111D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1111D,
+ },
+ [0x1111E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1111E,
+ },
+ [0x1111F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1111F,
+ },
+ [0x11120]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11120,
+ },
+ [0x11121]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11121,
+ },
+ [0x11122]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11122,
+ },
+ [0x11123]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11123,
+ },
+ [0x11124]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11124,
+ },
+ [0x11125]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11125,
+ },
+ [0x11126]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11126,
+ },
+ [0x11127]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11127,
+ },
+ [0x11128]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11128,
+ },
+ [0x11129]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11129,
+ },
+ [0x1112A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1112A,
+ },
+ [0x1112B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1112B,
+ },
+ [0x1112C]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1112C,
+ },
+ [0x1112D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1112D,
+ },
+ [0x1112E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x11131, 0x11127 },
+ unicodeslot=0x1112E,
+ },
+ [0x1112F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x11132, 0x11127 },
+ unicodeslot=0x1112F,
+ },
+ [0x11130]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11130,
+ },
+ [0x11131]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11131,
+ },
+ [0x11132]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11132,
+ },
+ [0x11133]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11133,
+ },
+ [0x11134]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11134,
+ },
+ [0x11136]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11136,
+ },
+ [0x11137]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11137,
+ },
+ [0x11138]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11138,
+ },
+ [0x11139]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11139,
+ },
+ [0x1113A]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1113A,
+ },
+ [0x1113B]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1113B,
+ },
+ [0x1113C]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1113C,
+ },
+ [0x1113D]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1113D,
+ },
+ [0x1113E]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1113E,
+ },
+ [0x1113F]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1113F,
+ },
+ [0x11140]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11140,
+ },
+ [0x11141]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11141,
+ },
+ [0x11142]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11142,
+ },
+ [0x11143]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11143,
+ },
+ [0x11144]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11144,
+ },
+ [0x11145]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11145,
+ },
+ [0x11146]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11146,
+ },
+ [0x11150]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11150,
+ },
+ [0x11151]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11151,
+ },
+ [0x11152]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11152,
+ },
+ [0x11153]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11153,
+ },
+ [0x11154]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11154,
+ },
+ [0x11155]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11155,
+ },
+ [0x11156]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11156,
+ },
+ [0x11157]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11157,
+ },
+ [0x11158]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11158,
+ },
+ [0x11159]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11159,
+ },
+ [0x1115A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1115A,
+ },
+ [0x1115B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1115B,
+ },
+ [0x1115C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1115C,
+ },
+ [0x1115D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1115D,
+ },
+ [0x1115E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1115E,
+ },
+ [0x1115F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1115F,
+ },
+ [0x11160]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11160,
+ },
+ [0x11161]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11161,
+ },
+ [0x11162]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11162,
+ },
+ [0x11163]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11163,
+ },
+ [0x11164]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11164,
+ },
+ [0x11165]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11165,
+ },
+ [0x11166]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11166,
+ },
+ [0x11167]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11167,
+ },
+ [0x11168]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11168,
+ },
+ [0x11169]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11169,
+ },
+ [0x1116A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1116A,
+ },
+ [0x1116B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1116B,
+ },
+ [0x1116C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1116C,
+ },
+ [0x1116D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1116D,
+ },
+ [0x1116E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1116E,
+ },
+ [0x1116F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1116F,
+ },
+ [0x11170]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11170,
+ },
+ [0x11171]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11171,
+ },
+ [0x11172]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11172,
+ },
+ [0x11173]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11173,
+ },
+ [0x11174]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11174,
+ },
+ [0x11175]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x11175,
+ },
+ [0x11176]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11176,
+ },
+ [0x11180]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11180,
+ },
+ [0x11181]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11181,
+ },
+ [0x11182]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11182,
+ },
+ [0x11183]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11183,
+ },
+ [0x11184]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11184,
+ },
+ [0x11185]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11185,
+ },
+ [0x11186]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11186,
+ },
+ [0x11187]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11187,
+ },
+ [0x11188]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11188,
+ },
+ [0x11189]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11189,
+ },
+ [0x1118A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1118A,
+ },
+ [0x1118B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1118B,
+ },
+ [0x1118C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1118C,
+ },
+ [0x1118D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1118D,
+ },
+ [0x1118E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1118E,
+ },
+ [0x1118F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1118F,
+ },
+ [0x11190]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11190,
+ },
+ [0x11191]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11191,
+ },
+ [0x11192]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11192,
+ },
+ [0x11193]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11193,
+ },
+ [0x11194]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11194,
+ },
+ [0x11195]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11195,
+ },
+ [0x11196]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11196,
+ },
+ [0x11197]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11197,
+ },
+ [0x11198]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11198,
+ },
+ [0x11199]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11199,
+ },
+ [0x1119A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1119A,
+ },
+ [0x1119B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1119B,
+ },
+ [0x1119C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1119C,
+ },
+ [0x1119D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1119D,
+ },
+ [0x1119E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1119E,
+ },
+ [0x1119F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1119F,
+ },
+ [0x111A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A0,
+ },
+ [0x111A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A1,
+ },
+ [0x111A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A2,
+ },
+ [0x111A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A3,
+ },
+ [0x111A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A4,
+ },
+ [0x111A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A5,
+ },
+ [0x111A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A6,
+ },
+ [0x111A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A7,
+ },
+ [0x111A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A8,
+ },
+ [0x111A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A9,
+ },
+ [0x111AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111AA,
+ },
+ [0x111AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111AB,
+ },
+ [0x111AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111AC,
+ },
+ [0x111AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111AD,
+ },
+ [0x111AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111AE,
+ },
+ [0x111AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111AF,
+ },
+ [0x111B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111B0,
+ },
+ [0x111B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111B1,
+ },
+ [0x111B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111B2,
+ },
+ [0x111B3]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x111B3,
+ },
+ [0x111B4]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x111B4,
+ },
+ [0x111B5]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x111B5,
+ },
+ [0x111B6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111B6,
+ },
+ [0x111B7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111B7,
+ },
+ [0x111B8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111B8,
+ },
+ [0x111B9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111B9,
+ },
+ [0x111BA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111BA,
+ },
+ [0x111BB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111BB,
+ },
+ [0x111BC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111BC,
+ },
+ [0x111BD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111BD,
+ },
+ [0x111BE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111BE,
+ },
+ [0x111BF]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x111BF,
+ },
+ [0x111C0]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x111C0,
+ },
+ [0x111C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111C1,
+ },
+ [0x111C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111C2,
+ },
+ [0x111C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111C3,
+ },
+ [0x111C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111C4,
+ },
+ [0x111C5]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x111C5,
+ },
+ [0x111C6]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x111C6,
+ },
+ [0x111C7]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111C7,
+ },
+ [0x111C8]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x111C8,
+ },
+ [0x111C9]={
+ category="po",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111C9,
+ },
+ [0x111CA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111CA,
+ },
+ [0x111CB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111CB,
+ },
+ [0x111CC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111CC,
+ },
+ [0x111CD]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111CD,
+ },
+ [0x111D0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D0,
+ },
+ [0x111D1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D1,
+ },
+ [0x111D2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D2,
+ },
+ [0x111D3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D3,
+ },
+ [0x111D4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D4,
+ },
+ [0x111D5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D5,
+ },
+ [0x111D6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D6,
+ },
+ [0x111D7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D7,
+ },
+ [0x111D8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D8,
+ },
+ [0x111D9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D9,
+ },
+ [0x111DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111DA,
+ },
+ [0x111DB]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x111DB,
+ },
+ [0x111DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111DC,
+ },
+ [0x111DD]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x111DD,
+ },
+ [0x111DE]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x111DE,
+ },
+ [0x111DF]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x111DF,
+ },
+ [0x111E1]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111E1,
+ },
+ [0x111E2]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111E2,
+ },
+ [0x111E3]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111E3,
+ },
+ [0x111E4]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111E4,
+ },
+ [0x111E5]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111E5,
+ },
+ [0x111E6]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111E6,
+ },
+ [0x111E7]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111E7,
+ },
+ [0x111E8]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111E8,
+ },
+ [0x111E9]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111E9,
+ },
+ [0x111EA]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111EA,
+ },
+ [0x111EB]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111EB,
+ },
+ [0x111EC]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111EC,
+ },
+ [0x111ED]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111ED,
+ },
+ [0x111EE]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111EE,
+ },
+ [0x111EF]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111EF,
+ },
+ [0x111F0]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111F0,
+ },
+ [0x111F1]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111F1,
+ },
+ [0x111F2]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111F2,
+ },
+ [0x111F3]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111F3,
+ },
+ [0x111F4]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111F4,
+ },
+ [0x11200]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11200,
+ },
+ [0x11201]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11201,
+ },
+ [0x11202]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11202,
+ },
+ [0x11203]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11203,
+ },
+ [0x11204]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11204,
+ },
+ [0x11205]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11205,
+ },
+ [0x11206]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11206,
+ },
+ [0x11207]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11207,
+ },
+ [0x11208]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11208,
+ },
+ [0x11209]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11209,
+ },
+ [0x1120A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1120A,
+ },
+ [0x1120B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1120B,
+ },
+ [0x1120C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1120C,
+ },
+ [0x1120D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1120D,
+ },
+ [0x1120E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1120E,
+ },
+ [0x1120F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1120F,
+ },
+ [0x11210]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11210,
+ },
+ [0x11211]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11211,
+ },
+ [0x11213]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11213,
+ },
+ [0x11214]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11214,
+ },
+ [0x11215]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11215,
+ },
+ [0x11216]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11216,
+ },
+ [0x11217]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11217,
+ },
+ [0x11218]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11218,
+ },
+ [0x11219]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11219,
+ },
+ [0x1121A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1121A,
+ },
+ [0x1121B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1121B,
+ },
+ [0x1121C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1121C,
+ },
+ [0x1121D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1121D,
+ },
+ [0x1121E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1121E,
+ },
+ [0x1121F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1121F,
+ },
+ [0x11220]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11220,
+ },
+ [0x11221]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11221,
+ },
+ [0x11222]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11222,
+ },
+ [0x11223]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11223,
+ },
+ [0x11224]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11224,
+ },
+ [0x11225]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11225,
+ },
+ [0x11226]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11226,
+ },
+ [0x11227]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11227,
+ },
+ [0x11228]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11228,
+ },
+ [0x11229]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11229,
+ },
+ [0x1122A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1122A,
+ },
+ [0x1122B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1122B,
+ },
+ [0x1122C]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1122C,
+ },
+ [0x1122D]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1122D,
+ },
+ [0x1122E]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1122E,
+ },
+ [0x1122F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1122F,
+ },
+ [0x11230]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11230,
+ },
+ [0x11231]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11231,
+ },
+ [0x11232]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11232,
+ },
+ [0x11233]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11233,
+ },
+ [0x11234]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11234,
+ },
+ [0x11235]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11235,
+ },
+ [0x11236]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11236,
+ },
+ [0x11237]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11237,
+ },
+ [0x11238]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11238,
+ },
+ [0x11239]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11239,
+ },
+ [0x1123A]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1123A,
+ },
+ [0x1123B]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1123B,
+ },
+ [0x1123C]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1123C,
+ },
+ [0x1123D]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1123D,
+ },
+ [0x1123E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1123E,
+ },
+ [0x11280]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11280,
+ },
+ [0x11281]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11281,
+ },
+ [0x11282]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11282,
+ },
+ [0x11283]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11283,
+ },
+ [0x11284]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11284,
+ },
+ [0x11285]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11285,
+ },
+ [0x11286]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11286,
+ },
+ [0x11288]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11288,
+ },
+ [0x1128A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1128A,
+ },
+ [0x1128B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1128B,
+ },
+ [0x1128C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1128C,
+ },
+ [0x1128D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1128D,
+ },
+ [0x1128F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1128F,
+ },
+ [0x11290]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11290,
+ },
+ [0x11291]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11291,
+ },
+ [0x11292]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11292,
+ },
+ [0x11293]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11293,
+ },
+ [0x11294]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11294,
+ },
+ [0x11295]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11295,
+ },
+ [0x11296]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11296,
+ },
+ [0x11297]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11297,
+ },
+ [0x11298]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11298,
+ },
+ [0x11299]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11299,
+ },
+ [0x1129A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1129A,
+ },
+ [0x1129B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1129B,
+ },
+ [0x1129C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1129C,
+ },
+ [0x1129D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1129D,
+ },
+ [0x1129F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1129F,
+ },
+ [0x112A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112A0,
+ },
+ [0x112A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112A1,
+ },
+ [0x112A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112A2,
+ },
+ [0x112A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112A3,
+ },
+ [0x112A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112A4,
+ },
+ [0x112A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112A5,
+ },
+ [0x112A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112A6,
+ },
+ [0x112A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112A7,
+ },
+ [0x112A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112A8,
+ },
+ [0x112A9]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x112A9,
+ },
+ [0x112B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112B0,
+ },
+ [0x112B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112B1,
+ },
+ [0x112B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112B2,
+ },
+ [0x112B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112B3,
+ },
+ [0x112B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112B4,
+ },
+ [0x112B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112B5,
+ },
+ [0x112B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112B6,
+ },
+ [0x112B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112B7,
+ },
+ [0x112B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112B8,
+ },
+ [0x112B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112B9,
+ },
+ [0x112BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112BA,
+ },
+ [0x112BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112BB,
+ },
+ [0x112BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112BC,
+ },
+ [0x112BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112BD,
+ },
+ [0x112BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112BE,
+ },
+ [0x112BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112BF,
+ },
+ [0x112C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112C0,
+ },
+ [0x112C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112C1,
+ },
+ [0x112C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112C2,
+ },
+ [0x112C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112C3,
+ },
+ [0x112C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112C4,
+ },
+ [0x112C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112C5,
+ },
+ [0x112C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112C6,
+ },
+ [0x112C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112C7,
+ },
+ [0x112C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112C8,
+ },
+ [0x112C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112C9,
+ },
+ [0x112CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112CA,
+ },
+ [0x112CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112CB,
+ },
+ [0x112CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112CC,
+ },
+ [0x112CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112CD,
+ },
+ [0x112CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112CE,
+ },
+ [0x112CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112CF,
+ },
+ [0x112D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112D0,
+ },
+ [0x112D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112D1,
+ },
+ [0x112D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112D2,
+ },
+ [0x112D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112D3,
+ },
+ [0x112D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112D4,
+ },
+ [0x112D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112D5,
+ },
+ [0x112D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112D6,
+ },
+ [0x112D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112D7,
+ },
+ [0x112D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112D8,
+ },
+ [0x112D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112D9,
+ },
+ [0x112DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112DA,
+ },
+ [0x112DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112DB,
+ },
+ [0x112DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112DC,
+ },
+ [0x112DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112DD,
+ },
+ [0x112DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x112DE,
+ },
+ [0x112DF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x112DF,
+ },
+ [0x112E0]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x112E0,
+ },
+ [0x112E1]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x112E1,
+ },
+ [0x112E2]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x112E2,
+ },
+ [0x112E3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x112E3,
+ },
+ [0x112E4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x112E4,
+ },
+ [0x112E5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x112E5,
+ },
+ [0x112E6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x112E6,
+ },
+ [0x112E7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x112E7,
+ },
+ [0x112E8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x112E8,
+ },
+ [0x112E9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x112E9,
+ },
+ [0x112EA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x112EA,
+ },
+ [0x112F0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x112F0,
+ },
+ [0x112F1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x112F1,
+ },
+ [0x112F2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x112F2,
+ },
+ [0x112F3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x112F3,
+ },
+ [0x112F4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x112F4,
+ },
+ [0x112F5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x112F5,
+ },
+ [0x112F6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x112F6,
+ },
+ [0x112F7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x112F7,
+ },
+ [0x112F8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x112F8,
+ },
+ [0x112F9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x112F9,
+ },
+ [0x11300]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11300,
+ },
+ [0x11301]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11301,
+ },
+ [0x11302]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11302,
+ },
+ [0x11303]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11303,
+ },
+ [0x11305]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11305,
+ },
+ [0x11306]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11306,
+ },
+ [0x11307]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11307,
+ },
+ [0x11308]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11308,
+ },
+ [0x11309]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11309,
+ },
+ [0x1130A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1130A,
+ },
+ [0x1130B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1130B,
+ },
+ [0x1130C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1130C,
+ },
+ [0x1130F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1130F,
+ },
+ [0x11310]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11310,
+ },
+ [0x11313]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11313,
+ },
+ [0x11314]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11314,
+ },
+ [0x11315]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11315,
+ },
+ [0x11316]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11316,
+ },
+ [0x11317]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11317,
+ },
+ [0x11318]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11318,
+ },
+ [0x11319]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11319,
+ },
+ [0x1131A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1131A,
+ },
+ [0x1131B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1131B,
+ },
+ [0x1131C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1131C,
+ },
+ [0x1131D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1131D,
+ },
+ [0x1131E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1131E,
+ },
+ [0x1131F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1131F,
+ },
+ [0x11320]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11320,
+ },
+ [0x11321]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11321,
+ },
+ [0x11322]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11322,
+ },
+ [0x11323]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11323,
+ },
+ [0x11324]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11324,
+ },
+ [0x11325]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11325,
+ },
+ [0x11326]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11326,
+ },
+ [0x11327]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11327,
+ },
+ [0x11328]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11328,
+ },
+ [0x1132A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1132A,
+ },
+ [0x1132B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1132B,
+ },
+ [0x1132C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1132C,
+ },
+ [0x1132D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1132D,
+ },
+ [0x1132E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1132E,
+ },
+ [0x1132F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1132F,
+ },
+ [0x11330]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11330,
+ },
+ [0x11332]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11332,
+ },
+ [0x11333]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11333,
+ },
+ [0x11335]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11335,
+ },
+ [0x11336]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11336,
+ },
+ [0x11337]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11337,
+ },
+ [0x11338]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11338,
+ },
+ [0x11339]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11339,
+ },
+ [0x1133B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1133B,
+ },
+ [0x1133C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1133C,
+ },
+ [0x1133D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1133D,
+ },
+ [0x1133E]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1133E,
+ },
+ [0x1133F]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1133F,
+ },
+ [0x11340]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11340,
+ },
+ [0x11341]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11341,
+ },
+ [0x11342]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11342,
+ },
+ [0x11343]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11343,
+ },
+ [0x11344]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11344,
+ },
+ [0x11347]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11347,
+ },
+ [0x11348]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11348,
+ },
+ [0x1134B]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x11347, 0x1133E },
+ unicodeslot=0x1134B,
+ },
+ [0x1134C]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x11347, 0x11357 },
+ unicodeslot=0x1134C,
+ },
+ [0x1134D]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1134D,
+ },
+ [0x11350]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11350,
+ },
+ [0x11357]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11357,
+ },
+ [0x1135D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1135D,
+ },
+ [0x1135E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1135E,
+ },
+ [0x1135F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1135F,
+ },
+ [0x11360]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11360,
+ },
+ [0x11361]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11361,
+ },
+ [0x11362]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11362,
+ },
+ [0x11363]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11363,
+ },
+ [0x11366]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11366,
+ },
+ [0x11367]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11367,
+ },
+ [0x11368]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11368,
+ },
+ [0x11369]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11369,
+ },
+ [0x1136A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1136A,
+ },
+ [0x1136B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1136B,
+ },
+ [0x1136C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1136C,
+ },
+ [0x11370]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11370,
+ },
+ [0x11371]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11371,
+ },
+ [0x11372]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11372,
+ },
+ [0x11373]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11373,
+ },
+ [0x11374]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11374,
+ },
+ [0x11400]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11400,
+ },
+ [0x11401]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11401,
+ },
+ [0x11402]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11402,
+ },
+ [0x11403]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11403,
+ },
+ [0x11404]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11404,
+ },
+ [0x11405]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11405,
+ },
+ [0x11406]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11406,
+ },
+ [0x11407]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11407,
+ },
+ [0x11408]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11408,
+ },
+ [0x11409]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11409,
+ },
+ [0x1140A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1140A,
+ },
+ [0x1140B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1140B,
+ },
+ [0x1140C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1140C,
+ },
+ [0x1140D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1140D,
+ },
+ [0x1140E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1140E,
+ },
+ [0x1140F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1140F,
+ },
+ [0x11410]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11410,
+ },
+ [0x11411]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11411,
+ },
+ [0x11412]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11412,
+ },
+ [0x11413]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11413,
+ },
+ [0x11414]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11414,
+ },
+ [0x11415]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11415,
+ },
+ [0x11416]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11416,
+ },
+ [0x11417]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11417,
+ },
+ [0x11418]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11418,
+ },
+ [0x11419]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11419,
+ },
+ [0x1141A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1141A,
+ },
+ [0x1141B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1141B,
+ },
+ [0x1141C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1141C,
+ },
+ [0x1141D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1141D,
+ },
+ [0x1141E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1141E,
+ },
+ [0x1141F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1141F,
+ },
+ [0x11420]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11420,
+ },
+ [0x11421]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11421,
+ },
+ [0x11422]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11422,
+ },
+ [0x11423]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11423,
+ },
+ [0x11424]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11424,
+ },
+ [0x11425]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11425,
+ },
+ [0x11426]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11426,
+ },
+ [0x11427]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11427,
+ },
+ [0x11428]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11428,
+ },
+ [0x11429]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11429,
+ },
+ [0x1142A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1142A,
+ },
+ [0x1142B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1142B,
+ },
+ [0x1142C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1142C,
+ },
+ [0x1142D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1142D,
+ },
+ [0x1142E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1142E,
+ },
+ [0x1142F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1142F,
+ },
+ [0x11430]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11430,
+ },
+ [0x11431]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11431,
+ },
+ [0x11432]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11432,
+ },
+ [0x11433]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11433,
+ },
+ [0x11434]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11434,
+ },
+ [0x11435]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11435,
+ },
+ [0x11436]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11436,
+ },
+ [0x11437]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11437,
+ },
+ [0x11438]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11438,
+ },
+ [0x11439]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11439,
+ },
+ [0x1143A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1143A,
+ },
+ [0x1143B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1143B,
+ },
+ [0x1143C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1143C,
+ },
+ [0x1143D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1143D,
+ },
+ [0x1143E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1143E,
+ },
+ [0x1143F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1143F,
+ },
+ [0x11440]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11440,
+ },
+ [0x11441]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11441,
+ },
+ [0x11442]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11442,
+ },
+ [0x11443]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11443,
+ },
+ [0x11444]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11444,
+ },
+ [0x11445]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11445,
+ },
+ [0x11446]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11446,
+ },
+ [0x11447]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11447,
+ },
+ [0x11448]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11448,
+ },
+ [0x11449]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11449,
+ },
+ [0x1144A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1144A,
+ },
+ [0x1144B]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1144B,
+ },
+ [0x1144C]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1144C,
+ },
+ [0x1144D]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1144D,
+ },
+ [0x1144E]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1144E,
+ },
+ [0x1144F]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1144F,
+ },
+ [0x11450]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11450,
+ },
+ [0x11451]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11451,
+ },
+ [0x11452]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11452,
+ },
+ [0x11453]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11453,
+ },
+ [0x11454]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11454,
+ },
+ [0x11455]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11455,
+ },
+ [0x11456]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11456,
+ },
+ [0x11457]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11457,
+ },
+ [0x11458]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11458,
+ },
+ [0x11459]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11459,
+ },
+ [0x1145B]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1145B,
+ },
+ [0x1145D]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1145D,
+ },
+ [0x1145E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1145E,
+ },
+ [0x1145F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1145F,
+ },
+ [0x11480]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11480,
+ },
+ [0x11481]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11481,
+ },
+ [0x11482]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11482,
+ },
+ [0x11483]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11483,
+ },
+ [0x11484]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11484,
+ },
+ [0x11485]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11485,
+ },
+ [0x11486]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11486,
+ },
+ [0x11487]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11487,
+ },
+ [0x11488]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11488,
+ },
+ [0x11489]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11489,
+ },
+ [0x1148A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1148A,
+ },
+ [0x1148B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1148B,
+ },
+ [0x1148C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1148C,
+ },
+ [0x1148D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1148D,
+ },
+ [0x1148E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1148E,
+ },
+ [0x1148F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1148F,
+ },
+ [0x11490]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11490,
+ },
+ [0x11491]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11491,
+ },
+ [0x11492]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11492,
+ },
+ [0x11493]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11493,
+ },
+ [0x11494]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11494,
+ },
+ [0x11495]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11495,
+ },
+ [0x11496]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11496,
+ },
+ [0x11497]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11497,
+ },
+ [0x11498]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11498,
+ },
+ [0x11499]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11499,
+ },
+ [0x1149A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1149A,
+ },
+ [0x1149B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1149B,
+ },
+ [0x1149C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1149C,
+ },
+ [0x1149D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1149D,
+ },
+ [0x1149E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1149E,
+ },
+ [0x1149F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1149F,
+ },
+ [0x114A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114A0,
+ },
+ [0x114A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114A1,
+ },
+ [0x114A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114A2,
+ },
+ [0x114A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114A3,
+ },
+ [0x114A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114A4,
+ },
+ [0x114A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114A5,
+ },
+ [0x114A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114A6,
+ },
+ [0x114A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114A7,
+ },
+ [0x114A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114A8,
+ },
+ [0x114A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114A9,
+ },
+ [0x114AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114AA,
+ },
+ [0x114AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114AB,
+ },
+ [0x114AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114AC,
+ },
+ [0x114AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114AD,
+ },
+ [0x114AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114AE,
+ },
+ [0x114AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114AF,
+ },
+ [0x114B0]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x114B0,
+ },
+ [0x114B1]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x114B1,
+ },
+ [0x114B2]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x114B2,
+ },
+ [0x114B3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x114B3,
+ },
+ [0x114B4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x114B4,
+ },
+ [0x114B5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x114B5,
+ },
+ [0x114B6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x114B6,
+ },
+ [0x114B7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x114B7,
+ },
+ [0x114B8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x114B8,
+ },
+ [0x114B9]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x114B9,
+ },
+ [0x114BA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x114BA,
+ },
+ [0x114BB]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x114B9, 0x114BA },
+ unicodeslot=0x114BB,
+ },
+ [0x114BC]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x114B9, 0x114B0 },
+ unicodeslot=0x114BC,
+ },
+ [0x114BD]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x114BD,
+ },
+ [0x114BE]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x114B9, 0x114BD },
+ unicodeslot=0x114BE,
+ },
+ [0x114BF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x114BF,
+ },
+ [0x114C0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x114C0,
+ },
+ [0x114C1]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x114C1,
+ },
+ [0x114C2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x114C2,
+ },
+ [0x114C3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x114C3,
+ },
+ [0x114C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114C4,
+ },
+ [0x114C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114C5,
+ },
+ [0x114C6]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114C6,
+ },
+ [0x114C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x114C7,
+ },
+ [0x114D0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x114D0,
+ },
+ [0x114D1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x114D1,
+ },
+ [0x114D2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x114D2,
+ },
+ [0x114D3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x114D3,
+ },
+ [0x114D4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x114D4,
+ },
+ [0x114D5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x114D5,
+ },
+ [0x114D6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x114D6,
+ },
+ [0x114D7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x114D7,
+ },
+ [0x114D8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x114D8,
+ },
+ [0x114D9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x114D9,
+ },
+ [0x11580]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11580,
+ },
+ [0x11581]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11581,
+ },
+ [0x11582]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11582,
+ },
+ [0x11583]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11583,
+ },
+ [0x11584]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11584,
+ },
+ [0x11585]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11585,
+ },
+ [0x11586]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11586,
+ },
+ [0x11587]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11587,
+ },
+ [0x11588]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11588,
+ },
+ [0x11589]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11589,
+ },
+ [0x1158A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1158A,
+ },
+ [0x1158B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1158B,
+ },
+ [0x1158C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1158C,
+ },
+ [0x1158D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1158D,
+ },
+ [0x1158E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1158E,
+ },
+ [0x1158F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1158F,
+ },
+ [0x11590]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11590,
+ },
+ [0x11591]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11591,
+ },
+ [0x11592]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11592,
+ },
+ [0x11593]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11593,
+ },
+ [0x11594]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11594,
+ },
+ [0x11595]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11595,
+ },
+ [0x11596]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11596,
+ },
+ [0x11597]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11597,
+ },
+ [0x11598]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11598,
+ },
+ [0x11599]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11599,
+ },
+ [0x1159A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1159A,
+ },
+ [0x1159B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1159B,
+ },
+ [0x1159C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1159C,
+ },
+ [0x1159D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1159D,
+ },
+ [0x1159E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1159E,
+ },
+ [0x1159F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1159F,
+ },
+ [0x115A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115A0,
+ },
+ [0x115A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115A1,
+ },
+ [0x115A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115A2,
+ },
+ [0x115A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115A3,
+ },
+ [0x115A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115A4,
+ },
+ [0x115A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115A5,
+ },
+ [0x115A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115A6,
+ },
+ [0x115A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115A7,
+ },
+ [0x115A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115A8,
+ },
+ [0x115A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115A9,
+ },
+ [0x115AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115AA,
+ },
+ [0x115AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115AB,
+ },
+ [0x115AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115AC,
+ },
+ [0x115AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115AD,
+ },
+ [0x115AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115AE,
+ },
+ [0x115AF]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x115AF,
+ },
+ [0x115B0]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x115B0,
+ },
+ [0x115B1]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x115B1,
+ },
+ [0x115B2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x115B2,
+ },
+ [0x115B3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x115B3,
+ },
+ [0x115B4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x115B4,
+ },
+ [0x115B5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x115B5,
+ },
+ [0x115B8]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x115B8,
+ },
+ [0x115B9]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x115B9,
+ },
+ [0x115BA]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x115B8, 0x115AF },
+ unicodeslot=0x115BA,
+ },
+ [0x115BB]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x115B9, 0x115AF },
+ unicodeslot=0x115BB,
+ },
+ [0x115BC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x115BC,
+ },
+ [0x115BD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x115BD,
+ },
+ [0x115BE]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x115BE,
+ },
+ [0x115BF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x115BF,
+ },
+ [0x115C0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x115C0,
+ },
+ [0x115C1]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x115C1,
+ },
+ [0x115C2]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115C2,
+ },
+ [0x115C3]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115C3,
+ },
+ [0x115C4]={
+ category="po",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0x115C4,
+ },
+ [0x115C5]={
+ category="po",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0x115C5,
+ },
+ [0x115C6]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115C6,
+ },
+ [0x115C7]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115C7,
+ },
+ [0x115C8]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115C8,
+ },
+ [0x115C9]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115C9,
+ },
+ [0x115CA]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115CA,
+ },
+ [0x115CB]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115CB,
+ },
+ [0x115CC]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115CC,
+ },
+ [0x115CD]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115CD,
+ },
+ [0x115CE]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115CE,
+ },
+ [0x115CF]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115CF,
+ },
+ [0x115D0]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115D0,
+ },
+ [0x115D1]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115D1,
+ },
+ [0x115D2]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115D2,
+ },
+ [0x115D3]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115D3,
+ },
+ [0x115D4]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115D4,
+ },
+ [0x115D5]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115D5,
+ },
+ [0x115D6]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115D6,
+ },
+ [0x115D7]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x115D7,
+ },
+ [0x115D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115D8,
+ },
+ [0x115D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115D9,
+ },
+ [0x115DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115DA,
+ },
+ [0x115DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x115DB,
+ },
+ [0x115DC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x115DC,
+ },
+ [0x115DD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x115DD,
+ },
+ [0x11600]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11600,
+ },
+ [0x11601]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11601,
+ },
+ [0x11602]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11602,
+ },
+ [0x11603]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11603,
+ },
+ [0x11604]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11604,
+ },
+ [0x11605]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11605,
+ },
+ [0x11606]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11606,
+ },
+ [0x11607]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11607,
+ },
+ [0x11608]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11608,
+ },
+ [0x11609]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11609,
+ },
+ [0x1160A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1160A,
+ },
+ [0x1160B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1160B,
+ },
+ [0x1160C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1160C,
+ },
+ [0x1160D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1160D,
+ },
+ [0x1160E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1160E,
+ },
+ [0x1160F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1160F,
+ },
+ [0x11610]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11610,
+ },
+ [0x11611]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11611,
+ },
+ [0x11612]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11612,
+ },
+ [0x11613]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11613,
+ },
+ [0x11614]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11614,
+ },
+ [0x11615]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11615,
+ },
+ [0x11616]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11616,
+ },
+ [0x11617]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11617,
+ },
+ [0x11618]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11618,
+ },
+ [0x11619]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11619,
+ },
+ [0x1161A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1161A,
+ },
+ [0x1161B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1161B,
+ },
+ [0x1161C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1161C,
+ },
+ [0x1161D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1161D,
+ },
+ [0x1161E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1161E,
+ },
+ [0x1161F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1161F,
+ },
+ [0x11620]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11620,
+ },
+ [0x11621]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11621,
+ },
+ [0x11622]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11622,
+ },
+ [0x11623]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11623,
+ },
+ [0x11624]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11624,
+ },
+ [0x11625]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11625,
+ },
+ [0x11626]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11626,
+ },
+ [0x11627]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11627,
+ },
+ [0x11628]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11628,
+ },
+ [0x11629]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11629,
+ },
+ [0x1162A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1162A,
+ },
+ [0x1162B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1162B,
+ },
+ [0x1162C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1162C,
+ },
+ [0x1162D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1162D,
+ },
+ [0x1162E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1162E,
+ },
+ [0x1162F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1162F,
+ },
+ [0x11630]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11630,
+ },
+ [0x11631]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11631,
+ },
+ [0x11632]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11632,
+ },
+ [0x11633]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11633,
+ },
+ [0x11634]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11634,
+ },
+ [0x11635]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11635,
+ },
+ [0x11636]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11636,
+ },
+ [0x11637]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11637,
+ },
+ [0x11638]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11638,
+ },
+ [0x11639]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11639,
+ },
+ [0x1163A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1163A,
+ },
+ [0x1163B]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1163B,
+ },
+ [0x1163C]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1163C,
+ },
+ [0x1163D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1163D,
+ },
+ [0x1163E]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1163E,
+ },
+ [0x1163F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1163F,
+ },
+ [0x11640]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11640,
+ },
+ [0x11641]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11641,
+ },
+ [0x11642]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11642,
+ },
+ [0x11643]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11643,
+ },
+ [0x11644]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11644,
+ },
+ [0x11650]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11650,
+ },
+ [0x11651]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11651,
+ },
+ [0x11652]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11652,
+ },
+ [0x11653]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11653,
+ },
+ [0x11654]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11654,
+ },
+ [0x11655]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11655,
+ },
+ [0x11656]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11656,
+ },
+ [0x11657]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11657,
+ },
+ [0x11658]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11658,
+ },
+ [0x11659]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11659,
+ },
+ [0x11660]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x11660,
+ },
+ [0x11661]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x11661,
+ },
+ [0x11662]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x11662,
+ },
+ [0x11663]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x11663,
+ },
+ [0x11664]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x11664,
+ },
+ [0x11665]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x11665,
+ },
+ [0x11666]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x11666,
+ },
+ [0x11667]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x11667,
+ },
+ [0x11668]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x11668,
+ },
+ [0x11669]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x11669,
+ },
+ [0x1166A]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x1166A,
+ },
+ [0x1166B]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x1166B,
+ },
+ [0x1166C]={
+ category="po",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x1166C,
+ },
+ [0x11680]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11680,
+ },
+ [0x11681]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11681,
+ },
+ [0x11682]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11682,
+ },
+ [0x11683]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11683,
+ },
+ [0x11684]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11684,
+ },
+ [0x11685]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11685,
+ },
+ [0x11686]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11686,
+ },
+ [0x11687]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11687,
+ },
+ [0x11688]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11688,
+ },
+ [0x11689]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11689,
+ },
+ [0x1168A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1168A,
+ },
+ [0x1168B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1168B,
+ },
+ [0x1168C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1168C,
+ },
+ [0x1168D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1168D,
+ },
+ [0x1168E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1168E,
+ },
+ [0x1168F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1168F,
+ },
+ [0x11690]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11690,
+ },
+ [0x11691]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11691,
+ },
+ [0x11692]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11692,
+ },
+ [0x11693]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11693,
+ },
+ [0x11694]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11694,
+ },
+ [0x11695]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11695,
+ },
+ [0x11696]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11696,
+ },
+ [0x11697]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11697,
+ },
+ [0x11698]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11698,
+ },
+ [0x11699]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11699,
+ },
+ [0x1169A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1169A,
+ },
+ [0x1169B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1169B,
+ },
+ [0x1169C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1169C,
+ },
+ [0x1169D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1169D,
+ },
+ [0x1169E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1169E,
+ },
+ [0x1169F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1169F,
+ },
+ [0x116A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A0,
+ },
+ [0x116A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A1,
+ },
+ [0x116A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A2,
+ },
+ [0x116A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A3,
+ },
+ [0x116A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A4,
+ },
+ [0x116A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A5,
+ },
+ [0x116A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A6,
+ },
+ [0x116A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A7,
+ },
+ [0x116A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A8,
+ },
+ [0x116A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A9,
+ },
+ [0x116AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116AA,
+ },
+ [0x116AB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116AB,
+ },
+ [0x116AC]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x116AC,
+ },
+ [0x116AD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116AD,
+ },
+ [0x116AE]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x116AE,
+ },
+ [0x116AF]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x116AF,
+ },
+ [0x116B0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B0,
+ },
+ [0x116B1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B1,
+ },
+ [0x116B2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B2,
+ },
+ [0x116B3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B3,
+ },
+ [0x116B4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B4,
+ },
+ [0x116B5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B5,
+ },
+ [0x116B6]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x116B6,
+ },
+ [0x116B7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B7,
+ },
+ [0x116B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116B8,
+ },
+ [0x116C0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C0,
+ },
+ [0x116C1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C1,
+ },
+ [0x116C2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C2,
+ },
+ [0x116C3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C3,
+ },
+ [0x116C4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C4,
+ },
+ [0x116C5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C5,
+ },
+ [0x116C6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C6,
+ },
+ [0x116C7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C7,
+ },
+ [0x116C8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C8,
+ },
+ [0x116C9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C9,
+ },
+ [0x11700]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11700,
+ },
+ [0x11701]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11701,
+ },
+ [0x11702]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11702,
+ },
+ [0x11703]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11703,
+ },
+ [0x11704]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11704,
+ },
+ [0x11705]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11705,
+ },
+ [0x11706]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11706,
+ },
+ [0x11707]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11707,
+ },
+ [0x11708]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11708,
+ },
+ [0x11709]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11709,
+ },
+ [0x1170A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1170A,
+ },
+ [0x1170B]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1170B,
+ },
+ [0x1170C]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1170C,
+ },
+ [0x1170D]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1170D,
+ },
+ [0x1170E]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1170E,
+ },
+ [0x1170F]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1170F,
+ },
+ [0x11710]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11710,
+ },
+ [0x11711]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11711,
+ },
+ [0x11712]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11712,
+ },
+ [0x11713]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11713,
+ },
+ [0x11714]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11714,
+ },
+ [0x11715]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11715,
+ },
+ [0x11716]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11716,
+ },
+ [0x11717]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11717,
+ },
+ [0x11718]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11718,
+ },
+ [0x11719]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11719,
+ },
+ [0x1171A]={
+ category="lo",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1171A,
+ },
+ [0x1171D]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1171D,
+ },
+ [0x1171E]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1171E,
+ },
+ [0x1171F]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1171F,
+ },
+ [0x11720]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11720,
+ },
+ [0x11721]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11721,
+ },
+ [0x11722]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x11722,
+ },
+ [0x11723]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x11723,
+ },
+ [0x11724]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x11724,
+ },
+ [0x11725]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x11725,
+ },
+ [0x11726]={
+ category="mc",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x11726,
+ },
+ [0x11727]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x11727,
+ },
+ [0x11728]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x11728,
+ },
+ [0x11729]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x11729,
+ },
+ [0x1172A]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1172A,
+ },
+ [0x1172B]={
+ category="mn",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1172B,
+ },
+ [0x11730]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11730,
+ },
+ [0x11731]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11731,
+ },
+ [0x11732]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11732,
+ },
+ [0x11733]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11733,
+ },
+ [0x11734]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11734,
+ },
+ [0x11735]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11735,
+ },
+ [0x11736]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11736,
+ },
+ [0x11737]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11737,
+ },
+ [0x11738]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11738,
+ },
+ [0x11739]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11739,
+ },
+ [0x1173A]={
+ category="no",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1173A,
+ },
+ [0x1173B]={
+ category="no",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1173B,
+ },
+ [0x1173C]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1173C,
+ },
+ [0x1173D]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1173D,
+ },
+ [0x1173E]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1173E,
+ },
+ [0x1173F]={
+ category="so",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1173F,
+ },
+ [0x11800]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11800,
+ },
+ [0x11801]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11801,
+ },
+ [0x11802]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11802,
+ },
+ [0x11803]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11803,
+ },
+ [0x11804]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11804,
+ },
+ [0x11805]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11805,
+ },
+ [0x11806]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11806,
+ },
+ [0x11807]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11807,
+ },
+ [0x11808]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11808,
+ },
+ [0x11809]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11809,
+ },
+ [0x1180A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1180A,
+ },
+ [0x1180B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1180B,
+ },
+ [0x1180C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1180C,
+ },
+ [0x1180D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1180D,
+ },
+ [0x1180E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1180E,
+ },
+ [0x1180F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1180F,
+ },
+ [0x11810]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11810,
+ },
+ [0x11811]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11811,
+ },
+ [0x11812]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11812,
+ },
+ [0x11813]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11813,
+ },
+ [0x11814]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11814,
+ },
+ [0x11815]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11815,
+ },
+ [0x11816]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11816,
+ },
+ [0x11817]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11817,
+ },
+ [0x11818]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11818,
+ },
+ [0x11819]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11819,
+ },
+ [0x1181A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1181A,
+ },
+ [0x1181B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1181B,
+ },
+ [0x1181C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1181C,
+ },
+ [0x1181D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1181D,
+ },
+ [0x1181E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1181E,
+ },
+ [0x1181F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1181F,
+ },
+ [0x11820]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11820,
+ },
+ [0x11821]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11821,
+ },
+ [0x11822]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11822,
+ },
+ [0x11823]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11823,
+ },
+ [0x11824]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11824,
+ },
+ [0x11825]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11825,
+ },
+ [0x11826]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11826,
+ },
+ [0x11827]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11827,
+ },
+ [0x11828]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11828,
+ },
+ [0x11829]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11829,
+ },
+ [0x1182A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1182A,
+ },
+ [0x1182B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1182B,
+ },
+ [0x1182C]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1182C,
+ },
+ [0x1182D]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1182D,
+ },
+ [0x1182E]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1182E,
+ },
+ [0x1182F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1182F,
+ },
+ [0x11830]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11830,
+ },
+ [0x11831]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11831,
+ },
+ [0x11832]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11832,
+ },
+ [0x11833]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11833,
+ },
+ [0x11834]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11834,
+ },
+ [0x11835]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11835,
+ },
+ [0x11836]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11836,
+ },
+ [0x11837]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11837,
+ },
+ [0x11838]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11838,
+ },
+ [0x11839]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11839,
+ },
+ [0x1183A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1183A,
+ },
+ [0x1183B]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1183B,
+ },
+ [0x118A0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118A0,
+ },
+ [0x118A1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118A1,
+ },
+ [0x118A2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118A2,
+ },
+ [0x118A3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118A3,
+ },
+ [0x118A4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118A4,
+ },
+ [0x118A5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118A5,
+ },
+ [0x118A6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118A6,
+ },
+ [0x118A7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118A7,
+ },
+ [0x118A8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118A8,
+ },
+ [0x118A9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118A9,
+ },
+ [0x118AA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118AA,
+ },
+ [0x118AB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118AB,
+ },
+ [0x118AC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118AC,
+ },
+ [0x118AD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118AD,
+ },
+ [0x118AE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118AE,
+ },
+ [0x118AF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118AF,
+ },
+ [0x118B0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118B0,
+ },
+ [0x118B1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118B1,
+ },
+ [0x118B2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118B2,
+ },
+ [0x118B3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118B3,
+ },
+ [0x118B4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118B4,
+ },
+ [0x118B5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118B5,
+ },
+ [0x118B6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118B6,
+ },
+ [0x118B7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118B7,
+ },
+ [0x118B8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118B8,
+ },
+ [0x118B9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118B9,
+ },
+ [0x118BA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118BA,
+ },
+ [0x118BB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118BB,
+ },
+ [0x118BC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118BC,
+ },
+ [0x118BD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118BD,
+ },
+ [0x118BE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118BE,
+ },
+ [0x118BF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118BF,
+ },
+ [0x118C0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118C0,
+ },
+ [0x118C1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118C1,
+ },
+ [0x118C2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118C2,
+ },
+ [0x118C3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118C3,
+ },
+ [0x118C4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118C4,
+ },
+ [0x118C5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118C5,
+ },
+ [0x118C6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118C6,
+ },
+ [0x118C7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118C7,
+ },
+ [0x118C8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118C8,
+ },
+ [0x118C9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118C9,
+ },
+ [0x118CA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118CA,
+ },
+ [0x118CB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118CB,
+ },
+ [0x118CC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118CC,
+ },
+ [0x118CD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118CD,
+ },
+ [0x118CE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118CE,
+ },
+ [0x118CF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118CF,
+ },
+ [0x118D0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118D0,
+ },
+ [0x118D1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118D1,
+ },
+ [0x118D2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118D2,
+ },
+ [0x118D3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118D3,
+ },
+ [0x118D4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118D4,
+ },
+ [0x118D5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118D5,
+ },
+ [0x118D6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118D6,
+ },
+ [0x118D7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118D7,
+ },
+ [0x118D8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118D8,
+ },
+ [0x118D9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118D9,
+ },
+ [0x118DA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118DA,
+ },
+ [0x118DB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118DB,
+ },
+ [0x118DC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118DC,
+ },
+ [0x118DD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118DD,
+ },
+ [0x118DE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118DE,
+ },
+ [0x118DF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118DF,
+ },
+ [0x118E0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x118E0,
+ },
+ [0x118E1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x118E1,
+ },
+ [0x118E2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x118E2,
+ },
+ [0x118E3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x118E3,
+ },
+ [0x118E4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x118E4,
+ },
+ [0x118E5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x118E5,
+ },
+ [0x118E6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x118E6,
+ },
+ [0x118E7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x118E7,
+ },
+ [0x118E8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x118E8,
+ },
+ [0x118E9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x118E9,
+ },
+ [0x118EA]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118EA,
+ },
+ [0x118EB]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118EB,
+ },
+ [0x118EC]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118EC,
+ },
+ [0x118ED]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118ED,
+ },
+ [0x118EE]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118EE,
+ },
+ [0x118EF]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118EF,
+ },
+ [0x118F0]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118F0,
+ },
+ [0x118F1]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118F1,
+ },
+ [0x118F2]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118F2,
+ },
+ [0x118FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x118FF,
+ },
+ [0x119A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119A0,
+ },
+ [0x119A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119A1,
+ },
+ [0x119A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119A2,
+ },
+ [0x119A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119A3,
+ },
+ [0x119A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119A4,
+ },
+ [0x119A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119A5,
+ },
+ [0x119A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119A6,
+ },
+ [0x119A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119A7,
+ },
+ [0x119AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119AA,
+ },
+ [0x119AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119AB,
+ },
+ [0x119AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119AC,
+ },
+ [0x119AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119AD,
+ },
+ [0x119AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119AE,
+ },
+ [0x119AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119AF,
+ },
+ [0x119B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119B0,
+ },
+ [0x119B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119B1,
+ },
+ [0x119B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119B2,
+ },
+ [0x119B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119B3,
+ },
+ [0x119B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119B4,
+ },
+ [0x119B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119B5,
+ },
+ [0x119B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119B6,
+ },
+ [0x119B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119B7,
+ },
+ [0x119B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119B8,
+ },
+ [0x119B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119B9,
+ },
+ [0x119BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119BA,
+ },
+ [0x119BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119BB,
+ },
+ [0x119BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119BC,
+ },
+ [0x119BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119BD,
+ },
+ [0x119BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119BE,
+ },
+ [0x119BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119BF,
+ },
+ [0x119C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119C0,
+ },
+ [0x119C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119C1,
+ },
+ [0x119C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119C2,
+ },
+ [0x119C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119C3,
+ },
+ [0x119C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119C4,
+ },
+ [0x119C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119C5,
+ },
+ [0x119C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119C6,
+ },
+ [0x119C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119C7,
+ },
+ [0x119C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119C8,
+ },
+ [0x119C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119C9,
+ },
+ [0x119CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119CA,
+ },
+ [0x119CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119CB,
+ },
+ [0x119CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119CC,
+ },
+ [0x119CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119CD,
+ },
+ [0x119CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119CE,
+ },
+ [0x119CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119CF,
+ },
+ [0x119D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119D0,
+ },
+ [0x119D1]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x119D1,
+ },
+ [0x119D2]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x119D2,
+ },
+ [0x119D3]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x119D3,
+ },
+ [0x119D4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x119D4,
+ },
+ [0x119D5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x119D5,
+ },
+ [0x119D6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x119D6,
+ },
+ [0x119D7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x119D7,
+ },
+ [0x119DA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x119DA,
+ },
+ [0x119DB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x119DB,
+ },
+ [0x119DC]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x119DC,
+ },
+ [0x119DD]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x119DD,
+ },
+ [0x119DE]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x119DE,
+ },
+ [0x119DF]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x119DF,
+ },
+ [0x119E0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x119E0,
+ },
+ [0x119E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119E1,
+ },
+ [0x119E2]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x119E2,
+ },
+ [0x119E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x119E3,
+ },
+ [0x119E4]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x119E4,
+ },
+ [0x11A00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A00,
+ },
+ [0x11A01]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A01,
+ },
+ [0x11A02]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A02,
+ },
+ [0x11A03]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A03,
+ },
+ [0x11A04]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A04,
+ },
+ [0x11A05]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A05,
+ },
+ [0x11A06]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A06,
+ },
+ [0x11A07]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11A07,
+ },
+ [0x11A08]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11A08,
+ },
+ [0x11A09]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A09,
+ },
+ [0x11A0A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A0A,
+ },
+ [0x11A0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A0B,
+ },
+ [0x11A0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A0C,
+ },
+ [0x11A0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A0D,
+ },
+ [0x11A0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A0E,
+ },
+ [0x11A0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A0F,
+ },
+ [0x11A10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A10,
+ },
+ [0x11A11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A11,
+ },
+ [0x11A12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A12,
+ },
+ [0x11A13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A13,
+ },
+ [0x11A14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A14,
+ },
+ [0x11A15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A15,
+ },
+ [0x11A16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A16,
+ },
+ [0x11A17]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A17,
+ },
+ [0x11A18]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A18,
+ },
+ [0x11A19]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A19,
+ },
+ [0x11A1A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A1A,
+ },
+ [0x11A1B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A1B,
+ },
+ [0x11A1C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A1C,
+ },
+ [0x11A1D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A1D,
+ },
+ [0x11A1E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A1E,
+ },
+ [0x11A1F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A1F,
+ },
+ [0x11A20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A20,
+ },
+ [0x11A21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A21,
+ },
+ [0x11A22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A22,
+ },
+ [0x11A23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A23,
+ },
+ [0x11A24]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A24,
+ },
+ [0x11A25]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A25,
+ },
+ [0x11A26]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A26,
+ },
+ [0x11A27]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A27,
+ },
+ [0x11A28]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A28,
+ },
+ [0x11A29]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A29,
+ },
+ [0x11A2A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A2A,
+ },
+ [0x11A2B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A2B,
+ },
+ [0x11A2C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A2C,
+ },
+ [0x11A2D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A2D,
+ },
+ [0x11A2E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A2E,
+ },
+ [0x11A2F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A2F,
+ },
+ [0x11A30]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A30,
+ },
+ [0x11A31]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A31,
+ },
+ [0x11A32]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A32,
+ },
+ [0x11A33]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A33,
+ },
+ [0x11A34]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A34,
+ },
+ [0x11A35]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A35,
+ },
+ [0x11A36]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A36,
+ },
+ [0x11A37]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A37,
+ },
+ [0x11A38]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A38,
+ },
+ [0x11A39]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11A39,
+ },
+ [0x11A3A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A3A,
+ },
+ [0x11A3B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A3B,
+ },
+ [0x11A3C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A3C,
+ },
+ [0x11A3D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A3D,
+ },
+ [0x11A3E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A3E,
+ },
+ [0x11A3F]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x11A3F,
+ },
+ [0x11A40]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A40,
+ },
+ [0x11A41]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11A41,
+ },
+ [0x11A42]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11A42,
+ },
+ [0x11A43]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11A43,
+ },
+ [0x11A44]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11A44,
+ },
+ [0x11A45]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x11A45,
+ },
+ [0x11A46]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A46,
+ },
+ [0x11A47]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A47,
+ },
+ [0x11A50]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A50,
+ },
+ [0x11A51]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A51,
+ },
+ [0x11A52]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A52,
+ },
+ [0x11A53]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A53,
+ },
+ [0x11A54]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A54,
+ },
+ [0x11A55]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A55,
+ },
+ [0x11A56]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A56,
+ },
+ [0x11A57]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11A57,
+ },
+ [0x11A58]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11A58,
+ },
+ [0x11A59]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A59,
+ },
+ [0x11A5A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A5A,
+ },
+ [0x11A5B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A5B,
+ },
+ [0x11A5C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A5C,
+ },
+ [0x11A5D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A5D,
+ },
+ [0x11A5E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A5E,
+ },
+ [0x11A5F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A5F,
+ },
+ [0x11A60]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A60,
+ },
+ [0x11A61]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A61,
+ },
+ [0x11A62]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A62,
+ },
+ [0x11A63]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A63,
+ },
+ [0x11A64]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A64,
+ },
+ [0x11A65]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A65,
+ },
+ [0x11A66]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A66,
+ },
+ [0x11A67]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A67,
+ },
+ [0x11A68]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A68,
+ },
+ [0x11A69]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A69,
+ },
+ [0x11A6A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A6A,
+ },
+ [0x11A6B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A6B,
+ },
+ [0x11A6C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A6C,
+ },
+ [0x11A6D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A6D,
+ },
+ [0x11A6E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A6E,
+ },
+ [0x11A6F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A6F,
+ },
+ [0x11A70]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A70,
+ },
+ [0x11A71]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A71,
+ },
+ [0x11A72]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A72,
+ },
+ [0x11A73]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A73,
+ },
+ [0x11A74]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A74,
+ },
+ [0x11A75]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A75,
+ },
+ [0x11A76]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A76,
+ },
+ [0x11A77]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A77,
+ },
+ [0x11A78]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A78,
+ },
+ [0x11A79]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A79,
+ },
+ [0x11A7A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A7A,
+ },
+ [0x11A7B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A7B,
+ },
+ [0x11A7C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A7C,
+ },
+ [0x11A7D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A7D,
+ },
+ [0x11A7E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A7E,
+ },
+ [0x11A7F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A7F,
+ },
+ [0x11A80]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A80,
+ },
+ [0x11A81]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A81,
+ },
+ [0x11A82]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A82,
+ },
+ [0x11A83]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A83,
+ },
+ [0x11A84]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A84,
+ },
+ [0x11A85]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A85,
+ },
+ [0x11A86]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A86,
+ },
+ [0x11A87]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A87,
+ },
+ [0x11A88]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A88,
+ },
+ [0x11A89]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A89,
+ },
+ [0x11A8A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A8A,
+ },
+ [0x11A8B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A8B,
+ },
+ [0x11A8C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A8C,
+ },
+ [0x11A8D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A8D,
+ },
+ [0x11A8E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A8E,
+ },
+ [0x11A8F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A8F,
+ },
+ [0x11A90]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A90,
+ },
+ [0x11A91]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A91,
+ },
+ [0x11A92]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A92,
+ },
+ [0x11A93]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A93,
+ },
+ [0x11A94]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A94,
+ },
+ [0x11A95]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A95,
+ },
+ [0x11A96]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A96,
+ },
+ [0x11A97]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11A97,
+ },
+ [0x11A98]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A98,
+ },
+ [0x11A99]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11A99,
+ },
+ [0x11A9A]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11A9A,
+ },
+ [0x11A9B]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11A9B,
+ },
+ [0x11A9C]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11A9C,
+ },
+ [0x11A9D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11A9D,
+ },
+ [0x11A9E]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x11A9E,
+ },
+ [0x11A9F]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x11A9F,
+ },
+ [0x11AA0]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x11AA0,
+ },
+ [0x11AA1]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11AA1,
+ },
+ [0x11AA2]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11AA2,
+ },
+ [0x11AC0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AC0,
+ },
+ [0x11AC1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AC1,
+ },
+ [0x11AC2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AC2,
+ },
+ [0x11AC3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AC3,
+ },
+ [0x11AC4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AC4,
+ },
+ [0x11AC5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AC5,
+ },
+ [0x11AC6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AC6,
+ },
+ [0x11AC7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AC7,
+ },
+ [0x11AC8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AC8,
+ },
+ [0x11AC9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AC9,
+ },
+ [0x11ACA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11ACA,
+ },
+ [0x11ACB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11ACB,
+ },
+ [0x11ACC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11ACC,
+ },
+ [0x11ACD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11ACD,
+ },
+ [0x11ACE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11ACE,
+ },
+ [0x11ACF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11ACF,
+ },
+ [0x11AD0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AD0,
+ },
+ [0x11AD1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AD1,
+ },
+ [0x11AD2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AD2,
+ },
+ [0x11AD3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AD3,
+ },
+ [0x11AD4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AD4,
+ },
+ [0x11AD5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AD5,
+ },
+ [0x11AD6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AD6,
+ },
+ [0x11AD7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AD7,
+ },
+ [0x11AD8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AD8,
+ },
+ [0x11AD9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AD9,
+ },
+ [0x11ADA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11ADA,
+ },
+ [0x11ADB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11ADB,
+ },
+ [0x11ADC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11ADC,
+ },
+ [0x11ADD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11ADD,
+ },
+ [0x11ADE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11ADE,
+ },
+ [0x11ADF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11ADF,
+ },
+ [0x11AE0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AE0,
+ },
+ [0x11AE1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AE1,
+ },
+ [0x11AE2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AE2,
+ },
+ [0x11AE3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AE3,
+ },
+ [0x11AE4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AE4,
+ },
+ [0x11AE5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AE5,
+ },
+ [0x11AE6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AE6,
+ },
+ [0x11AE7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AE7,
+ },
+ [0x11AE8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AE8,
+ },
+ [0x11AE9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AE9,
+ },
+ [0x11AEA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AEA,
+ },
+ [0x11AEB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AEB,
+ },
+ [0x11AEC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AEC,
+ },
+ [0x11AED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AED,
+ },
+ [0x11AEE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AEE,
+ },
+ [0x11AEF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AEF,
+ },
+ [0x11AF0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AF0,
+ },
+ [0x11AF1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AF1,
+ },
+ [0x11AF2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AF2,
+ },
+ [0x11AF3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AF3,
+ },
+ [0x11AF4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AF4,
+ },
+ [0x11AF5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AF5,
+ },
+ [0x11AF6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AF6,
+ },
+ [0x11AF7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AF7,
+ },
+ [0x11AF8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11AF8,
+ },
+ [0x11C00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C00,
+ },
+ [0x11C01]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C01,
+ },
+ [0x11C02]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C02,
+ },
+ [0x11C03]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C03,
+ },
+ [0x11C04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C04,
+ },
+ [0x11C05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C05,
+ },
+ [0x11C06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C06,
+ },
+ [0x11C07]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C07,
+ },
+ [0x11C08]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C08,
+ },
+ [0x11C0A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C0A,
+ },
+ [0x11C0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C0B,
+ },
+ [0x11C0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C0C,
+ },
+ [0x11C0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C0D,
+ },
+ [0x11C0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C0E,
+ },
+ [0x11C0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C0F,
+ },
+ [0x11C10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C10,
+ },
+ [0x11C11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C11,
+ },
+ [0x11C12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C12,
+ },
+ [0x11C13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C13,
+ },
+ [0x11C14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C14,
+ },
+ [0x11C15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C15,
+ },
+ [0x11C16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C16,
+ },
+ [0x11C17]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C17,
+ },
+ [0x11C18]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C18,
+ },
+ [0x11C19]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C19,
+ },
+ [0x11C1A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C1A,
+ },
+ [0x11C1B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C1B,
+ },
+ [0x11C1C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C1C,
+ },
+ [0x11C1D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C1D,
+ },
+ [0x11C1E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C1E,
+ },
+ [0x11C1F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C1F,
+ },
+ [0x11C20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C20,
+ },
+ [0x11C21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C21,
+ },
+ [0x11C22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C22,
+ },
+ [0x11C23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C23,
+ },
+ [0x11C24]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C24,
+ },
+ [0x11C25]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C25,
+ },
+ [0x11C26]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C26,
+ },
+ [0x11C27]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C27,
+ },
+ [0x11C28]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C28,
+ },
+ [0x11C29]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C29,
+ },
+ [0x11C2A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C2A,
+ },
+ [0x11C2B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C2B,
+ },
+ [0x11C2C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C2C,
+ },
+ [0x11C2D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C2D,
+ },
+ [0x11C2E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C2E,
+ },
+ [0x11C2F]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11C2F,
+ },
+ [0x11C30]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C30,
+ },
+ [0x11C31]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C31,
+ },
+ [0x11C32]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C32,
+ },
+ [0x11C33]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C33,
+ },
+ [0x11C34]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C34,
+ },
+ [0x11C35]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C35,
+ },
+ [0x11C36]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C36,
+ },
+ [0x11C38]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C38,
+ },
+ [0x11C39]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C39,
+ },
+ [0x11C3A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C3A,
+ },
+ [0x11C3B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C3B,
+ },
+ [0x11C3C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C3C,
+ },
+ [0x11C3D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C3D,
+ },
+ [0x11C3E]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11C3E,
+ },
+ [0x11C3F]={
+ category="mn",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11C3F,
+ },
+ [0x11C40]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C40,
+ },
+ [0x11C41]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11C41,
+ },
+ [0x11C42]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11C42,
+ },
+ [0x11C43]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11C43,
+ },
+ [0x11C44]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11C44,
+ },
+ [0x11C45]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11C45,
+ },
+ [0x11C50]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11C50,
+ },
+ [0x11C51]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11C51,
+ },
+ [0x11C52]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11C52,
+ },
+ [0x11C53]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11C53,
+ },
+ [0x11C54]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11C54,
+ },
+ [0x11C55]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11C55,
+ },
+ [0x11C56]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11C56,
+ },
+ [0x11C57]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11C57,
+ },
+ [0x11C58]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11C58,
+ },
+ [0x11C59]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11C59,
+ },
+ [0x11C5A]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C5A,
+ },
+ [0x11C5B]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C5B,
+ },
+ [0x11C5C]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C5C,
+ },
+ [0x11C5D]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C5D,
+ },
+ [0x11C5E]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C5E,
+ },
+ [0x11C5F]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C5F,
+ },
+ [0x11C60]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C60,
+ },
+ [0x11C61]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C61,
+ },
+ [0x11C62]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C62,
+ },
+ [0x11C63]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C63,
+ },
+ [0x11C64]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C64,
+ },
+ [0x11C65]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C65,
+ },
+ [0x11C66]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C66,
+ },
+ [0x11C67]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C67,
+ },
+ [0x11C68]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C68,
+ },
+ [0x11C69]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C69,
+ },
+ [0x11C6A]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C6A,
+ },
+ [0x11C6B]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C6B,
+ },
+ [0x11C6C]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C6C,
+ },
+ [0x11C70]={
+ category="po",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x11C70,
+ },
+ [0x11C71]={
+ category="po",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0x11C71,
+ },
+ [0x11C72]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C72,
+ },
+ [0x11C73]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C73,
+ },
+ [0x11C74]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C74,
+ },
+ [0x11C75]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C75,
+ },
+ [0x11C76]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C76,
+ },
+ [0x11C77]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C77,
+ },
+ [0x11C78]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C78,
+ },
+ [0x11C79]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C79,
+ },
+ [0x11C7A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C7A,
+ },
+ [0x11C7B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C7B,
+ },
+ [0x11C7C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C7C,
+ },
+ [0x11C7D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C7D,
+ },
+ [0x11C7E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C7E,
+ },
+ [0x11C7F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C7F,
+ },
+ [0x11C80]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C80,
+ },
+ [0x11C81]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C81,
+ },
+ [0x11C82]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C82,
+ },
+ [0x11C83]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C83,
+ },
+ [0x11C84]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C84,
+ },
+ [0x11C85]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C85,
+ },
+ [0x11C86]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C86,
+ },
+ [0x11C87]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C87,
+ },
+ [0x11C88]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C88,
+ },
+ [0x11C89]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C89,
+ },
+ [0x11C8A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C8A,
+ },
+ [0x11C8B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C8B,
+ },
+ [0x11C8C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C8C,
+ },
+ [0x11C8D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C8D,
+ },
+ [0x11C8E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C8E,
+ },
+ [0x11C8F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11C8F,
+ },
+ [0x11C92]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C92,
+ },
+ [0x11C93]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C93,
+ },
+ [0x11C94]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C94,
+ },
+ [0x11C95]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C95,
+ },
+ [0x11C96]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C96,
+ },
+ [0x11C97]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C97,
+ },
+ [0x11C98]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C98,
+ },
+ [0x11C99]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C99,
+ },
+ [0x11C9A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C9A,
+ },
+ [0x11C9B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C9B,
+ },
+ [0x11C9C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C9C,
+ },
+ [0x11C9D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C9D,
+ },
+ [0x11C9E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C9E,
+ },
+ [0x11C9F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11C9F,
+ },
+ [0x11CA0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CA0,
+ },
+ [0x11CA1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CA1,
+ },
+ [0x11CA2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CA2,
+ },
+ [0x11CA3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CA3,
+ },
+ [0x11CA4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CA4,
+ },
+ [0x11CA5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CA5,
+ },
+ [0x11CA6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CA6,
+ },
+ [0x11CA7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CA7,
+ },
+ [0x11CA9]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11CA9,
+ },
+ [0x11CAA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CAA,
+ },
+ [0x11CAB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CAB,
+ },
+ [0x11CAC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CAC,
+ },
+ [0x11CAD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CAD,
+ },
+ [0x11CAE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CAE,
+ },
+ [0x11CAF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CAF,
+ },
+ [0x11CB0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CB0,
+ },
+ [0x11CB1]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11CB1,
+ },
+ [0x11CB2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CB2,
+ },
+ [0x11CB3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CB3,
+ },
+ [0x11CB4]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11CB4,
+ },
+ [0x11CB5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CB5,
+ },
+ [0x11CB6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11CB6,
+ },
+ [0x11D00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D00,
+ },
+ [0x11D01]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D01,
+ },
+ [0x11D02]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D02,
+ },
+ [0x11D03]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D03,
+ },
+ [0x11D04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D04,
+ },
+ [0x11D05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D05,
+ },
+ [0x11D06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D06,
+ },
+ [0x11D08]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D08,
+ },
+ [0x11D09]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D09,
+ },
+ [0x11D0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D0B,
+ },
+ [0x11D0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D0C,
+ },
+ [0x11D0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D0D,
+ },
+ [0x11D0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D0E,
+ },
+ [0x11D0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D0F,
+ },
+ [0x11D10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D10,
+ },
+ [0x11D11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D11,
+ },
+ [0x11D12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D12,
+ },
+ [0x11D13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D13,
+ },
+ [0x11D14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D14,
+ },
+ [0x11D15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D15,
+ },
+ [0x11D16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D16,
+ },
+ [0x11D17]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D17,
+ },
+ [0x11D18]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D18,
+ },
+ [0x11D19]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D19,
+ },
+ [0x11D1A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D1A,
+ },
+ [0x11D1B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D1B,
+ },
+ [0x11D1C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D1C,
+ },
+ [0x11D1D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D1D,
+ },
+ [0x11D1E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D1E,
+ },
+ [0x11D1F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D1F,
+ },
+ [0x11D20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D20,
+ },
+ [0x11D21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D21,
+ },
+ [0x11D22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D22,
+ },
+ [0x11D23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D23,
+ },
+ [0x11D24]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D24,
+ },
+ [0x11D25]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D25,
+ },
+ [0x11D26]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D26,
+ },
+ [0x11D27]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D27,
+ },
+ [0x11D28]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D28,
+ },
+ [0x11D29]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D29,
+ },
+ [0x11D2A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D2A,
+ },
+ [0x11D2B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D2B,
+ },
+ [0x11D2C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D2C,
+ },
+ [0x11D2D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D2D,
+ },
+ [0x11D2E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D2E,
+ },
+ [0x11D2F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D2F,
+ },
+ [0x11D30]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D30,
+ },
+ [0x11D31]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D31,
+ },
+ [0x11D32]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D32,
+ },
+ [0x11D33]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D33,
+ },
+ [0x11D34]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D34,
+ },
+ [0x11D35]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D35,
+ },
+ [0x11D36]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D36,
+ },
+ [0x11D3A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D3A,
+ },
+ [0x11D3C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D3C,
+ },
+ [0x11D3D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D3D,
+ },
+ [0x11D3F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D3F,
+ },
+ [0x11D40]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D40,
+ },
+ [0x11D41]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D41,
+ },
+ [0x11D42]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D42,
+ },
+ [0x11D43]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D43,
+ },
+ [0x11D44]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D44,
+ },
+ [0x11D45]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D45,
+ },
+ [0x11D46]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D46,
+ },
+ [0x11D47]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D47,
+ },
+ [0x11D50]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11D50,
+ },
+ [0x11D51]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11D51,
+ },
+ [0x11D52]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11D52,
+ },
+ [0x11D53]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11D53,
+ },
+ [0x11D54]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11D54,
+ },
+ [0x11D55]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11D55,
+ },
+ [0x11D56]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11D56,
+ },
+ [0x11D57]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11D57,
+ },
+ [0x11D58]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11D58,
+ },
+ [0x11D59]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11D59,
+ },
+ [0x11D60]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D60,
+ },
+ [0x11D61]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D61,
+ },
+ [0x11D62]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D62,
+ },
+ [0x11D63]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D63,
+ },
+ [0x11D64]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D64,
+ },
+ [0x11D65]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D65,
+ },
+ [0x11D67]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D67,
+ },
+ [0x11D68]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D68,
+ },
+ [0x11D6A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D6A,
+ },
+ [0x11D6B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D6B,
+ },
+ [0x11D6C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D6C,
+ },
+ [0x11D6D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D6D,
+ },
+ [0x11D6E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D6E,
+ },
+ [0x11D6F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D6F,
+ },
+ [0x11D70]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D70,
+ },
+ [0x11D71]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D71,
+ },
+ [0x11D72]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D72,
+ },
+ [0x11D73]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D73,
+ },
+ [0x11D74]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D74,
+ },
+ [0x11D75]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D75,
+ },
+ [0x11D76]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D76,
+ },
+ [0x11D77]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D77,
+ },
+ [0x11D78]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D78,
+ },
+ [0x11D79]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D79,
+ },
+ [0x11D7A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D7A,
+ },
+ [0x11D7B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D7B,
+ },
+ [0x11D7C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D7C,
+ },
+ [0x11D7D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D7D,
+ },
+ [0x11D7E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D7E,
+ },
+ [0x11D7F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D7F,
+ },
+ [0x11D80]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D80,
+ },
+ [0x11D81]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D81,
+ },
+ [0x11D82]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D82,
+ },
+ [0x11D83]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D83,
+ },
+ [0x11D84]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D84,
+ },
+ [0x11D85]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D85,
+ },
+ [0x11D86]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D86,
+ },
+ [0x11D87]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D87,
+ },
+ [0x11D88]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D88,
+ },
+ [0x11D89]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D89,
+ },
+ [0x11D8A]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11D8A,
+ },
+ [0x11D8B]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11D8B,
+ },
+ [0x11D8C]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11D8C,
+ },
+ [0x11D8D]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11D8D,
+ },
+ [0x11D8E]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11D8E,
+ },
+ [0x11D90]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D90,
+ },
+ [0x11D91]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D91,
+ },
+ [0x11D93]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11D93,
+ },
+ [0x11D94]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11D94,
+ },
+ [0x11D95]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D95,
+ },
+ [0x11D96]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11D96,
+ },
+ [0x11D97]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11D97,
+ },
+ [0x11D98]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11D98,
+ },
+ [0x11DA0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11DA0,
+ },
+ [0x11DA1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11DA1,
+ },
+ [0x11DA2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11DA2,
+ },
+ [0x11DA3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11DA3,
+ },
+ [0x11DA4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11DA4,
+ },
+ [0x11DA5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11DA5,
+ },
+ [0x11DA6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11DA6,
+ },
+ [0x11DA7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11DA7,
+ },
+ [0x11DA8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11DA8,
+ },
+ [0x11DA9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11DA9,
+ },
+ [0x11EE0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EE0,
+ },
+ [0x11EE1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EE1,
+ },
+ [0x11EE2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EE2,
+ },
+ [0x11EE3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EE3,
+ },
+ [0x11EE4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EE4,
+ },
+ [0x11EE5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EE5,
+ },
+ [0x11EE6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EE6,
+ },
+ [0x11EE7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EE7,
+ },
+ [0x11EE8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EE8,
+ },
+ [0x11EE9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EE9,
+ },
+ [0x11EEA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EEA,
+ },
+ [0x11EEB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EEB,
+ },
+ [0x11EEC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EEC,
+ },
+ [0x11EED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EED,
+ },
+ [0x11EEE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EEE,
+ },
+ [0x11EEF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EEF,
+ },
+ [0x11EF0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EF0,
+ },
+ [0x11EF1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EF1,
+ },
+ [0x11EF2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EF2,
+ },
+ [0x11EF3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11EF3,
+ },
+ [0x11EF4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11EF4,
+ },
+ [0x11EF5]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11EF5,
+ },
+ [0x11EF6]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11EF6,
+ },
+ [0x11EF7]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EF7,
+ },
+ [0x11EF8]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11EF8,
+ },
+ [0x11FC0]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FC0,
+ },
+ [0x11FC1]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FC1,
+ },
+ [0x11FC2]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FC2,
+ },
+ [0x11FC3]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FC3,
+ },
+ [0x11FC4]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FC4,
+ },
+ [0x11FC5]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FC5,
+ },
+ [0x11FC6]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FC6,
+ },
+ [0x11FC7]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FC7,
+ },
+ [0x11FC8]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FC8,
+ },
+ [0x11FC9]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FC9,
+ },
+ [0x11FCA]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FCA,
+ },
+ [0x11FCB]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FCB,
+ },
+ [0x11FCC]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FCC,
+ },
+ [0x11FCD]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FCD,
+ },
+ [0x11FCE]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FCE,
+ },
+ [0x11FCF]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FCF,
+ },
+ [0x11FD0]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FD0,
+ },
+ [0x11FD1]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FD1,
+ },
+ [0x11FD2]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FD2,
+ },
+ [0x11FD3]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FD3,
+ },
+ [0x11FD4]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FD4,
+ },
+ [0x11FD5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FD5,
+ },
+ [0x11FD6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FD6,
+ },
+ [0x11FD7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FD7,
+ },
+ [0x11FD8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FD8,
+ },
+ [0x11FD9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FD9,
+ },
+ [0x11FDA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FDA,
+ },
+ [0x11FDB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FDB,
+ },
+ [0x11FDC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FDC,
+ },
+ [0x11FDD]={
+ category="sc",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x11FDD,
+ },
+ [0x11FDE]={
+ category="sc",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x11FDE,
+ },
+ [0x11FDF]={
+ category="sc",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x11FDF,
+ },
+ [0x11FE0]={
+ category="sc",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x11FE0,
+ },
+ [0x11FE1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FE1,
+ },
+ [0x11FE2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FE2,
+ },
+ [0x11FE3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FE3,
+ },
+ [0x11FE4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FE4,
+ },
+ [0x11FE5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FE5,
+ },
+ [0x11FE6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FE6,
+ },
+ [0x11FE7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FE7,
+ },
+ [0x11FE8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FE8,
+ },
+ [0x11FE9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FE9,
+ },
+ [0x11FEA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FEA,
+ },
+ [0x11FEB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FEB,
+ },
+ [0x11FEC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FEC,
+ },
+ [0x11FED]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FED,
+ },
+ [0x11FEE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FEE,
+ },
+ [0x11FEF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FEF,
+ },
+ [0x11FF0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FF0,
+ },
+ [0x11FF1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11FF1,
+ },
+ [0x11FFF]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11FFF,
+ },
+ [0x12000]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12000,
+ },
+ [0x12001]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12001,
+ },
+ [0x12002]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12002,
+ },
+ [0x12003]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12003,
+ },
+ [0x12004]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12004,
+ },
+ [0x12005]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12005,
+ },
+ [0x12006]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12006,
+ },
+ [0x12007]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12007,
+ },
+ [0x12008]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12008,
+ },
+ [0x12009]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12009,
+ },
+ [0x1200A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200A,
+ },
+ [0x1200B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200B,
+ },
+ [0x1200C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200C,
+ },
+ [0x1200D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200D,
+ },
+ [0x1200E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200E,
+ },
+ [0x1200F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200F,
+ },
+ [0x12010]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12010,
+ },
+ [0x12011]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12011,
+ },
+ [0x12012]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12012,
+ },
+ [0x12013]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12013,
+ },
+ [0x12014]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12014,
+ },
+ [0x12015]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12015,
+ },
+ [0x12016]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12016,
+ },
+ [0x12017]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12017,
+ },
+ [0x12018]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12018,
+ },
+ [0x12019]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12019,
+ },
+ [0x1201A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201A,
+ },
+ [0x1201B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201B,
+ },
+ [0x1201C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201C,
+ },
+ [0x1201D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201D,
+ },
+ [0x1201E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201E,
+ },
+ [0x1201F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201F,
+ },
+ [0x12020]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12020,
+ },
+ [0x12021]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12021,
+ },
+ [0x12022]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12022,
+ },
+ [0x12023]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12023,
+ },
+ [0x12024]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12024,
+ },
+ [0x12025]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12025,
+ },
+ [0x12026]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12026,
+ },
+ [0x12027]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12027,
+ },
+ [0x12028]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12028,
+ },
+ [0x12029]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12029,
+ },
+ [0x1202A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202A,
+ },
+ [0x1202B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202B,
+ },
+ [0x1202C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202C,
+ },
+ [0x1202D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202D,
+ },
+ [0x1202E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202E,
+ },
+ [0x1202F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202F,
+ },
+ [0x12030]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12030,
+ },
+ [0x12031]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12031,
+ },
+ [0x12032]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12032,
+ },
+ [0x12033]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12033,
+ },
+ [0x12034]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12034,
+ },
+ [0x12035]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12035,
+ },
+ [0x12036]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12036,
+ },
+ [0x12037]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12037,
+ },
+ [0x12038]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12038,
+ },
+ [0x12039]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12039,
+ },
+ [0x1203A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203A,
+ },
+ [0x1203B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203B,
+ },
+ [0x1203C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203C,
+ },
+ [0x1203D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203D,
+ },
+ [0x1203E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203E,
+ },
+ [0x1203F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203F,
+ },
+ [0x12040]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12040,
+ },
+ [0x12041]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12041,
+ },
+ [0x12042]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12042,
+ },
+ [0x12043]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12043,
+ },
+ [0x12044]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12044,
+ },
+ [0x12045]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12045,
+ },
+ [0x12046]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12046,
+ },
+ [0x12047]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12047,
+ },
+ [0x12048]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12048,
+ },
+ [0x12049]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12049,
+ },
+ [0x1204A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204A,
+ },
+ [0x1204B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204B,
+ },
+ [0x1204C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204C,
+ },
+ [0x1204D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204D,
+ },
+ [0x1204E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204E,
+ },
+ [0x1204F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204F,
+ },
+ [0x12050]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12050,
+ },
+ [0x12051]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12051,
+ },
+ [0x12052]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12052,
+ },
+ [0x12053]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12053,
+ },
+ [0x12054]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12054,
+ },
+ [0x12055]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12055,
+ },
+ [0x12056]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12056,
+ },
+ [0x12057]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12057,
+ },
+ [0x12058]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12058,
+ },
+ [0x12059]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12059,
+ },
+ [0x1205A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205A,
+ },
+ [0x1205B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205B,
+ },
+ [0x1205C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205C,
+ },
+ [0x1205D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205D,
+ },
+ [0x1205E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205E,
+ },
+ [0x1205F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205F,
+ },
+ [0x12060]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12060,
+ },
+ [0x12061]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12061,
+ },
+ [0x12062]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12062,
+ },
+ [0x12063]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12063,
+ },
+ [0x12064]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12064,
+ },
+ [0x12065]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12065,
+ },
+ [0x12066]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12066,
+ },
+ [0x12067]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12067,
+ },
+ [0x12068]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12068,
+ },
+ [0x12069]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12069,
+ },
+ [0x1206A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206A,
+ },
+ [0x1206B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206B,
+ },
+ [0x1206C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206C,
+ },
+ [0x1206D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206D,
+ },
+ [0x1206E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206E,
+ },
+ [0x1206F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206F,
+ },
+ [0x12070]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12070,
+ },
+ [0x12071]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12071,
+ },
+ [0x12072]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12072,
+ },
+ [0x12073]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12073,
+ },
+ [0x12074]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12074,
+ },
+ [0x12075]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12075,
+ },
+ [0x12076]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12076,
+ },
+ [0x12077]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12077,
+ },
+ [0x12078]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12078,
+ },
+ [0x12079]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12079,
+ },
+ [0x1207A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207A,
+ },
+ [0x1207B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207B,
+ },
+ [0x1207C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207C,
+ },
+ [0x1207D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207D,
+ },
+ [0x1207E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207E,
+ },
+ [0x1207F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207F,
+ },
+ [0x12080]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12080,
+ },
+ [0x12081]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12081,
+ },
+ [0x12082]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12082,
+ },
+ [0x12083]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12083,
+ },
+ [0x12084]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12084,
+ },
+ [0x12085]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12085,
+ },
+ [0x12086]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12086,
+ },
+ [0x12087]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12087,
+ },
+ [0x12088]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12088,
+ },
+ [0x12089]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12089,
+ },
+ [0x1208A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208A,
+ },
+ [0x1208B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208B,
+ },
+ [0x1208C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208C,
+ },
+ [0x1208D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208D,
+ },
+ [0x1208E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208E,
+ },
+ [0x1208F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208F,
+ },
+ [0x12090]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12090,
+ },
+ [0x12091]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12091,
+ },
+ [0x12092]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12092,
+ },
+ [0x12093]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12093,
+ },
+ [0x12094]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12094,
+ },
+ [0x12095]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12095,
+ },
+ [0x12096]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12096,
+ },
+ [0x12097]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12097,
+ },
+ [0x12098]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12098,
+ },
+ [0x12099]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12099,
+ },
+ [0x1209A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209A,
+ },
+ [0x1209B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209B,
+ },
+ [0x1209C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209C,
+ },
+ [0x1209D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209D,
+ },
+ [0x1209E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209E,
+ },
+ [0x1209F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209F,
+ },
+ [0x120A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A0,
+ },
+ [0x120A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A1,
+ },
+ [0x120A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A2,
+ },
+ [0x120A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A3,
+ },
+ [0x120A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A4,
+ },
+ [0x120A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A5,
+ },
+ [0x120A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A6,
+ },
+ [0x120A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A7,
+ },
+ [0x120A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A8,
+ },
+ [0x120A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A9,
+ },
+ [0x120AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120AA,
+ },
+ [0x120AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120AB,
+ },
+ [0x120AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120AC,
+ },
+ [0x120AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120AD,
+ },
+ [0x120AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120AE,
+ },
+ [0x120AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120AF,
+ },
+ [0x120B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B0,
+ },
+ [0x120B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B1,
+ },
+ [0x120B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B2,
+ },
+ [0x120B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B3,
+ },
+ [0x120B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B4,
+ },
+ [0x120B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B5,
+ },
+ [0x120B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B6,
+ },
+ [0x120B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B7,
+ },
+ [0x120B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B8,
+ },
+ [0x120B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B9,
+ },
+ [0x120BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120BA,
+ },
+ [0x120BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120BB,
+ },
+ [0x120BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120BC,
+ },
+ [0x120BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120BD,
+ },
+ [0x120BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120BE,
+ },
+ [0x120BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120BF,
+ },
+ [0x120C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C0,
+ },
+ [0x120C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C1,
+ },
+ [0x120C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C2,
+ },
+ [0x120C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C3,
+ },
+ [0x120C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C4,
+ },
+ [0x120C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C5,
+ },
+ [0x120C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C6,
+ },
+ [0x120C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C7,
+ },
+ [0x120C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C8,
+ },
+ [0x120C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C9,
+ },
+ [0x120CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120CA,
+ },
+ [0x120CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120CB,
+ },
+ [0x120CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120CC,
+ },
+ [0x120CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120CD,
+ },
+ [0x120CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120CE,
+ },
+ [0x120CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120CF,
+ },
+ [0x120D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D0,
+ },
+ [0x120D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D1,
+ },
+ [0x120D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D2,
+ },
+ [0x120D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D3,
+ },
+ [0x120D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D4,
+ },
+ [0x120D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D5,
+ },
+ [0x120D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D6,
+ },
+ [0x120D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D7,
+ },
+ [0x120D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D8,
+ },
+ [0x120D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D9,
+ },
+ [0x120DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120DA,
+ },
+ [0x120DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120DB,
+ },
+ [0x120DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120DC,
+ },
+ [0x120DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120DD,
+ },
+ [0x120DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120DE,
+ },
+ [0x120DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120DF,
+ },
+ [0x120E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E0,
+ },
+ [0x120E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E1,
+ },
+ [0x120E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E2,
+ },
+ [0x120E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E3,
+ },
+ [0x120E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E4,
+ },
+ [0x120E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E5,
+ },
+ [0x120E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E6,
+ },
+ [0x120E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E7,
+ },
+ [0x120E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E8,
+ },
+ [0x120E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E9,
+ },
+ [0x120EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120EA,
+ },
+ [0x120EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120EB,
+ },
+ [0x120EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120EC,
+ },
+ [0x120ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120ED,
+ },
+ [0x120EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120EE,
+ },
+ [0x120EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120EF,
+ },
+ [0x120F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F0,
+ },
+ [0x120F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F1,
+ },
+ [0x120F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F2,
+ },
+ [0x120F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F3,
+ },
+ [0x120F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F4,
+ },
+ [0x120F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F5,
+ },
+ [0x120F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F6,
+ },
+ [0x120F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F7,
+ },
+ [0x120F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F8,
+ },
+ [0x120F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F9,
+ },
+ [0x120FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120FA,
+ },
+ [0x120FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120FB,
+ },
+ [0x120FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120FC,
+ },
+ [0x120FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120FD,
+ },
+ [0x120FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120FE,
+ },
+ [0x120FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120FF,
+ },
+ [0x12100]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12100,
+ },
+ [0x12101]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12101,
+ },
+ [0x12102]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12102,
+ },
+ [0x12103]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12103,
+ },
+ [0x12104]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12104,
+ },
+ [0x12105]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12105,
+ },
+ [0x12106]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12106,
+ },
+ [0x12107]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12107,
+ },
+ [0x12108]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12108,
+ },
+ [0x12109]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12109,
+ },
+ [0x1210A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210A,
+ },
+ [0x1210B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210B,
+ },
+ [0x1210C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210C,
+ },
+ [0x1210D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210D,
+ },
+ [0x1210E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210E,
+ },
+ [0x1210F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210F,
+ },
+ [0x12110]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12110,
+ },
+ [0x12111]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12111,
+ },
+ [0x12112]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12112,
+ },
+ [0x12113]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12113,
+ },
+ [0x12114]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12114,
+ },
+ [0x12115]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12115,
+ },
+ [0x12116]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12116,
+ },
+ [0x12117]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12117,
+ },
+ [0x12118]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12118,
+ },
+ [0x12119]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12119,
+ },
+ [0x1211A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211A,
+ },
+ [0x1211B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211B,
+ },
+ [0x1211C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211C,
+ },
+ [0x1211D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211D,
+ },
+ [0x1211E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211E,
+ },
+ [0x1211F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211F,
+ },
+ [0x12120]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12120,
+ },
+ [0x12121]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12121,
+ },
+ [0x12122]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12122,
+ },
+ [0x12123]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12123,
+ },
+ [0x12124]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12124,
+ },
+ [0x12125]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12125,
+ },
+ [0x12126]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12126,
+ },
+ [0x12127]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12127,
+ },
+ [0x12128]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12128,
+ },
+ [0x12129]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12129,
+ },
+ [0x1212A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212A,
+ },
+ [0x1212B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212B,
+ },
+ [0x1212C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212C,
+ },
+ [0x1212D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212D,
+ },
+ [0x1212E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212E,
+ },
+ [0x1212F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212F,
+ },
+ [0x12130]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12130,
+ },
+ [0x12131]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12131,
+ },
+ [0x12132]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12132,
+ },
+ [0x12133]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12133,
+ },
+ [0x12134]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12134,
+ },
+ [0x12135]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12135,
+ },
+ [0x12136]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12136,
+ },
+ [0x12137]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12137,
+ },
+ [0x12138]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12138,
+ },
+ [0x12139]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12139,
+ },
+ [0x1213A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213A,
+ },
+ [0x1213B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213B,
+ },
+ [0x1213C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213C,
+ },
+ [0x1213D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213D,
+ },
+ [0x1213E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213E,
+ },
+ [0x1213F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213F,
+ },
+ [0x12140]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12140,
+ },
+ [0x12141]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12141,
+ },
+ [0x12142]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12142,
+ },
+ [0x12143]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12143,
+ },
+ [0x12144]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12144,
+ },
+ [0x12145]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12145,
+ },
+ [0x12146]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12146,
+ },
+ [0x12147]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12147,
+ },
+ [0x12148]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12148,
+ },
+ [0x12149]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12149,
+ },
+ [0x1214A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214A,
+ },
+ [0x1214B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214B,
+ },
+ [0x1214C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214C,
+ },
+ [0x1214D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214D,
+ },
+ [0x1214E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214E,
+ },
+ [0x1214F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214F,
+ },
+ [0x12150]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12150,
+ },
+ [0x12151]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12151,
+ },
+ [0x12152]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12152,
+ },
+ [0x12153]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12153,
+ },
+ [0x12154]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12154,
+ },
+ [0x12155]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12155,
+ },
+ [0x12156]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12156,
+ },
+ [0x12157]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12157,
+ },
+ [0x12158]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12158,
+ },
+ [0x12159]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12159,
+ },
+ [0x1215A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215A,
+ },
+ [0x1215B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215B,
+ },
+ [0x1215C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215C,
+ },
+ [0x1215D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215D,
+ },
+ [0x1215E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215E,
+ },
+ [0x1215F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215F,
+ },
+ [0x12160]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12160,
+ },
+ [0x12161]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12161,
+ },
+ [0x12162]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12162,
+ },
+ [0x12163]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12163,
+ },
+ [0x12164]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12164,
+ },
+ [0x12165]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12165,
+ },
+ [0x12166]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12166,
+ },
+ [0x12167]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12167,
+ },
+ [0x12168]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12168,
+ },
+ [0x12169]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12169,
+ },
+ [0x1216A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216A,
+ },
+ [0x1216B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216B,
+ },
+ [0x1216C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216C,
+ },
+ [0x1216D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216D,
+ },
+ [0x1216E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216E,
+ },
+ [0x1216F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216F,
+ },
+ [0x12170]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12170,
+ },
+ [0x12171]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12171,
+ },
+ [0x12172]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12172,
+ },
+ [0x12173]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12173,
+ },
+ [0x12174]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12174,
+ },
+ [0x12175]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12175,
+ },
+ [0x12176]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12176,
+ },
+ [0x12177]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12177,
+ },
+ [0x12178]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12178,
+ },
+ [0x12179]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12179,
+ },
+ [0x1217A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217A,
+ },
+ [0x1217B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217B,
+ },
+ [0x1217C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217C,
+ },
+ [0x1217D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217D,
+ },
+ [0x1217E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217E,
+ },
+ [0x1217F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217F,
+ },
+ [0x12180]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12180,
+ },
+ [0x12181]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12181,
+ },
+ [0x12182]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12182,
+ },
+ [0x12183]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12183,
+ },
+ [0x12184]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12184,
+ },
+ [0x12185]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12185,
+ },
+ [0x12186]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12186,
+ },
+ [0x12187]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12187,
+ },
+ [0x12188]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12188,
+ },
+ [0x12189]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12189,
+ },
+ [0x1218A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218A,
+ },
+ [0x1218B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218B,
+ },
+ [0x1218C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218C,
+ },
+ [0x1218D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218D,
+ },
+ [0x1218E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218E,
+ },
+ [0x1218F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218F,
+ },
+ [0x12190]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12190,
+ },
+ [0x12191]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12191,
+ },
+ [0x12192]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12192,
+ },
+ [0x12193]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12193,
+ },
+ [0x12194]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12194,
+ },
+ [0x12195]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12195,
+ },
+ [0x12196]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12196,
+ },
+ [0x12197]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12197,
+ },
+ [0x12198]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12198,
+ },
+ [0x12199]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12199,
+ },
+ [0x1219A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219A,
+ },
+ [0x1219B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219B,
+ },
+ [0x1219C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219C,
+ },
+ [0x1219D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219D,
+ },
+ [0x1219E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219E,
+ },
+ [0x1219F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219F,
+ },
+ [0x121A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A0,
+ },
+ [0x121A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A1,
+ },
+ [0x121A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A2,
+ },
+ [0x121A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A3,
+ },
+ [0x121A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A4,
+ },
+ [0x121A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A5,
+ },
+ [0x121A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A6,
+ },
+ [0x121A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A7,
+ },
+ [0x121A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A8,
+ },
+ [0x121A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A9,
+ },
+ [0x121AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121AA,
+ },
+ [0x121AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121AB,
+ },
+ [0x121AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121AC,
+ },
+ [0x121AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121AD,
+ },
+ [0x121AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121AE,
+ },
+ [0x121AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121AF,
+ },
+ [0x121B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B0,
+ },
+ [0x121B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B1,
+ },
+ [0x121B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B2,
+ },
+ [0x121B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B3,
+ },
+ [0x121B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B4,
+ },
+ [0x121B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B5,
+ },
+ [0x121B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B6,
+ },
+ [0x121B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B7,
+ },
+ [0x121B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B8,
+ },
+ [0x121B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B9,
+ },
+ [0x121BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121BA,
+ },
+ [0x121BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121BB,
+ },
+ [0x121BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121BC,
+ },
+ [0x121BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121BD,
+ },
+ [0x121BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121BE,
+ },
+ [0x121BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121BF,
+ },
+ [0x121C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C0,
+ },
+ [0x121C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C1,
+ },
+ [0x121C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C2,
+ },
+ [0x121C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C3,
+ },
+ [0x121C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C4,
+ },
+ [0x121C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C5,
+ },
+ [0x121C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C6,
+ },
+ [0x121C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C7,
+ },
+ [0x121C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C8,
+ },
+ [0x121C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C9,
+ },
+ [0x121CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121CA,
+ },
+ [0x121CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121CB,
+ },
+ [0x121CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121CC,
+ },
+ [0x121CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121CD,
+ },
+ [0x121CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121CE,
+ },
+ [0x121CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121CF,
+ },
+ [0x121D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D0,
+ },
+ [0x121D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D1,
+ },
+ [0x121D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D2,
+ },
+ [0x121D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D3,
+ },
+ [0x121D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D4,
+ },
+ [0x121D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D5,
+ },
+ [0x121D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D6,
+ },
+ [0x121D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D7,
+ },
+ [0x121D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D8,
+ },
+ [0x121D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D9,
+ },
+ [0x121DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121DA,
+ },
+ [0x121DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121DB,
+ },
+ [0x121DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121DC,
+ },
+ [0x121DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121DD,
+ },
+ [0x121DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121DE,
+ },
+ [0x121DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121DF,
+ },
+ [0x121E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E0,
+ },
+ [0x121E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E1,
+ },
+ [0x121E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E2,
+ },
+ [0x121E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E3,
+ },
+ [0x121E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E4,
+ },
+ [0x121E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E5,
+ },
+ [0x121E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E6,
+ },
+ [0x121E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E7,
+ },
+ [0x121E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E8,
+ },
+ [0x121E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E9,
+ },
+ [0x121EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121EA,
+ },
+ [0x121EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121EB,
+ },
+ [0x121EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121EC,
+ },
+ [0x121ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121ED,
+ },
+ [0x121EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121EE,
+ },
+ [0x121EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121EF,
+ },
+ [0x121F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F0,
+ },
+ [0x121F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F1,
+ },
+ [0x121F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F2,
+ },
+ [0x121F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F3,
+ },
+ [0x121F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F4,
+ },
+ [0x121F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F5,
+ },
+ [0x121F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F6,
+ },
+ [0x121F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F7,
+ },
+ [0x121F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F8,
+ },
+ [0x121F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F9,
+ },
+ [0x121FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121FA,
+ },
+ [0x121FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121FB,
+ },
+ [0x121FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121FC,
+ },
+ [0x121FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121FD,
+ },
+ [0x121FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121FE,
+ },
+ [0x121FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121FF,
+ },
+ [0x12200]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12200,
+ },
+ [0x12201]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12201,
+ },
+ [0x12202]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12202,
+ },
+ [0x12203]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12203,
+ },
+ [0x12204]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12204,
+ },
+ [0x12205]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12205,
+ },
+ [0x12206]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12206,
+ },
+ [0x12207]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12207,
+ },
+ [0x12208]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12208,
+ },
+ [0x12209]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12209,
+ },
+ [0x1220A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220A,
+ },
+ [0x1220B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220B,
+ },
+ [0x1220C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220C,
+ },
+ [0x1220D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220D,
+ },
+ [0x1220E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220E,
+ },
+ [0x1220F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220F,
+ },
+ [0x12210]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12210,
+ },
+ [0x12211]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12211,
+ },
+ [0x12212]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12212,
+ },
+ [0x12213]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12213,
+ },
+ [0x12214]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12214,
+ },
+ [0x12215]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12215,
+ },
+ [0x12216]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12216,
+ },
+ [0x12217]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12217,
+ },
+ [0x12218]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12218,
+ },
+ [0x12219]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12219,
+ },
+ [0x1221A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221A,
+ },
+ [0x1221B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221B,
+ },
+ [0x1221C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221C,
+ },
+ [0x1221D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221D,
+ },
+ [0x1221E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221E,
+ },
+ [0x1221F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221F,
+ },
+ [0x12220]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12220,
+ },
+ [0x12221]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12221,
+ },
+ [0x12222]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12222,
+ },
+ [0x12223]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12223,
+ },
+ [0x12224]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12224,
+ },
+ [0x12225]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12225,
+ },
+ [0x12226]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12226,
+ },
+ [0x12227]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12227,
+ },
+ [0x12228]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12228,
+ },
+ [0x12229]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12229,
+ },
+ [0x1222A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222A,
+ },
+ [0x1222B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222B,
+ },
+ [0x1222C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222C,
+ },
+ [0x1222D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222D,
+ },
+ [0x1222E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222E,
+ },
+ [0x1222F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222F,
+ },
+ [0x12230]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12230,
+ },
+ [0x12231]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12231,
+ },
+ [0x12232]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12232,
+ },
+ [0x12233]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12233,
+ },
+ [0x12234]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12234,
+ },
+ [0x12235]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12235,
+ },
+ [0x12236]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12236,
+ },
+ [0x12237]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12237,
+ },
+ [0x12238]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12238,
+ },
+ [0x12239]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12239,
+ },
+ [0x1223A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223A,
+ },
+ [0x1223B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223B,
+ },
+ [0x1223C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223C,
+ },
+ [0x1223D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223D,
+ },
+ [0x1223E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223E,
+ },
+ [0x1223F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223F,
+ },
+ [0x12240]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12240,
+ },
+ [0x12241]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12241,
+ },
+ [0x12242]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12242,
+ },
+ [0x12243]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12243,
+ },
+ [0x12244]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12244,
+ },
+ [0x12245]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12245,
+ },
+ [0x12246]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12246,
+ },
+ [0x12247]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12247,
+ },
+ [0x12248]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12248,
+ },
+ [0x12249]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12249,
+ },
+ [0x1224A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224A,
+ },
+ [0x1224B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224B,
+ },
+ [0x1224C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224C,
+ },
+ [0x1224D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224D,
+ },
+ [0x1224E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224E,
+ },
+ [0x1224F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224F,
+ },
+ [0x12250]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12250,
+ },
+ [0x12251]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12251,
+ },
+ [0x12252]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12252,
+ },
+ [0x12253]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12253,
+ },
+ [0x12254]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12254,
+ },
+ [0x12255]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12255,
+ },
+ [0x12256]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12256,
+ },
+ [0x12257]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12257,
+ },
+ [0x12258]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12258,
+ },
+ [0x12259]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12259,
+ },
+ [0x1225A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225A,
+ },
+ [0x1225B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225B,
+ },
+ [0x1225C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225C,
+ },
+ [0x1225D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225D,
+ },
+ [0x1225E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225E,
+ },
+ [0x1225F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225F,
+ },
+ [0x12260]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12260,
+ },
+ [0x12261]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12261,
+ },
+ [0x12262]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12262,
+ },
+ [0x12263]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12263,
+ },
+ [0x12264]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12264,
+ },
+ [0x12265]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12265,
+ },
+ [0x12266]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12266,
+ },
+ [0x12267]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12267,
+ },
+ [0x12268]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12268,
+ },
+ [0x12269]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12269,
+ },
+ [0x1226A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226A,
+ },
+ [0x1226B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226B,
+ },
+ [0x1226C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226C,
+ },
+ [0x1226D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226D,
+ },
+ [0x1226E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226E,
+ },
+ [0x1226F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226F,
+ },
+ [0x12270]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12270,
+ },
+ [0x12271]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12271,
+ },
+ [0x12272]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12272,
+ },
+ [0x12273]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12273,
+ },
+ [0x12274]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12274,
+ },
+ [0x12275]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12275,
+ },
+ [0x12276]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12276,
+ },
+ [0x12277]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12277,
+ },
+ [0x12278]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12278,
+ },
+ [0x12279]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12279,
+ },
+ [0x1227A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227A,
+ },
+ [0x1227B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227B,
+ },
+ [0x1227C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227C,
+ },
+ [0x1227D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227D,
+ },
+ [0x1227E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227E,
+ },
+ [0x1227F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227F,
+ },
+ [0x12280]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12280,
+ },
+ [0x12281]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12281,
+ },
+ [0x12282]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12282,
+ },
+ [0x12283]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12283,
+ },
+ [0x12284]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12284,
+ },
+ [0x12285]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12285,
+ },
+ [0x12286]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12286,
+ },
+ [0x12287]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12287,
+ },
+ [0x12288]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12288,
+ },
+ [0x12289]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12289,
+ },
+ [0x1228A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228A,
+ },
+ [0x1228B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228B,
+ },
+ [0x1228C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228C,
+ },
+ [0x1228D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228D,
+ },
+ [0x1228E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228E,
+ },
+ [0x1228F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228F,
+ },
+ [0x12290]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12290,
+ },
+ [0x12291]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12291,
+ },
+ [0x12292]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12292,
+ },
+ [0x12293]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12293,
+ },
+ [0x12294]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12294,
+ },
+ [0x12295]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12295,
+ },
+ [0x12296]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12296,
+ },
+ [0x12297]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12297,
+ },
+ [0x12298]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12298,
+ },
+ [0x12299]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12299,
+ },
+ [0x1229A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229A,
+ },
+ [0x1229B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229B,
+ },
+ [0x1229C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229C,
+ },
+ [0x1229D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229D,
+ },
+ [0x1229E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229E,
+ },
+ [0x1229F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229F,
+ },
+ [0x122A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A0,
+ },
+ [0x122A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A1,
+ },
+ [0x122A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A2,
+ },
+ [0x122A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A3,
+ },
+ [0x122A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A4,
+ },
+ [0x122A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A5,
+ },
+ [0x122A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A6,
+ },
+ [0x122A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A7,
+ },
+ [0x122A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A8,
+ },
+ [0x122A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A9,
+ },
+ [0x122AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122AA,
+ },
+ [0x122AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122AB,
+ },
+ [0x122AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122AC,
+ },
+ [0x122AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122AD,
+ },
+ [0x122AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122AE,
+ },
+ [0x122AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122AF,
+ },
+ [0x122B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B0,
+ },
+ [0x122B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B1,
+ },
+ [0x122B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B2,
+ },
+ [0x122B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B3,
+ },
+ [0x122B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B4,
+ },
+ [0x122B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B5,
+ },
+ [0x122B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B6,
+ },
+ [0x122B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B7,
+ },
+ [0x122B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B8,
+ },
+ [0x122B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B9,
+ },
+ [0x122BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122BA,
+ },
+ [0x122BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122BB,
+ },
+ [0x122BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122BC,
+ },
+ [0x122BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122BD,
+ },
+ [0x122BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122BE,
+ },
+ [0x122BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122BF,
+ },
+ [0x122C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C0,
+ },
+ [0x122C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C1,
+ },
+ [0x122C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C2,
+ },
+ [0x122C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C3,
+ },
+ [0x122C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C4,
+ },
+ [0x122C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C5,
+ },
+ [0x122C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C6,
+ },
+ [0x122C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C7,
+ },
+ [0x122C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C8,
+ },
+ [0x122C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C9,
+ },
+ [0x122CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122CA,
+ },
+ [0x122CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122CB,
+ },
+ [0x122CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122CC,
+ },
+ [0x122CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122CD,
+ },
+ [0x122CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122CE,
+ },
+ [0x122CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122CF,
+ },
+ [0x122D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D0,
+ },
+ [0x122D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D1,
+ },
+ [0x122D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D2,
+ },
+ [0x122D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D3,
+ },
+ [0x122D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D4,
+ },
+ [0x122D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D5,
+ },
+ [0x122D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D6,
+ },
+ [0x122D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D7,
+ },
+ [0x122D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D8,
+ },
+ [0x122D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D9,
+ },
+ [0x122DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122DA,
+ },
+ [0x122DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122DB,
+ },
+ [0x122DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122DC,
+ },
+ [0x122DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122DD,
+ },
+ [0x122DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122DE,
+ },
+ [0x122DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122DF,
+ },
+ [0x122E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E0,
+ },
+ [0x122E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E1,
+ },
+ [0x122E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E2,
+ },
+ [0x122E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E3,
+ },
+ [0x122E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E4,
+ },
+ [0x122E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E5,
+ },
+ [0x122E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E6,
+ },
+ [0x122E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E7,
+ },
+ [0x122E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E8,
+ },
+ [0x122E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E9,
+ },
+ [0x122EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122EA,
+ },
+ [0x122EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122EB,
+ },
+ [0x122EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122EC,
+ },
+ [0x122ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122ED,
+ },
+ [0x122EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122EE,
+ },
+ [0x122EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122EF,
+ },
+ [0x122F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F0,
+ },
+ [0x122F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F1,
+ },
+ [0x122F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F2,
+ },
+ [0x122F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F3,
+ },
+ [0x122F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F4,
+ },
+ [0x122F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F5,
+ },
+ [0x122F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F6,
+ },
+ [0x122F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F7,
+ },
+ [0x122F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F8,
+ },
+ [0x122F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F9,
+ },
+ [0x122FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122FA,
+ },
+ [0x122FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122FB,
+ },
+ [0x122FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122FC,
+ },
+ [0x122FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122FD,
+ },
+ [0x122FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122FE,
+ },
+ [0x122FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122FF,
+ },
+ [0x12300]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12300,
+ },
+ [0x12301]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12301,
+ },
+ [0x12302]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12302,
+ },
+ [0x12303]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12303,
+ },
+ [0x12304]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12304,
+ },
+ [0x12305]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12305,
+ },
+ [0x12306]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12306,
+ },
+ [0x12307]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12307,
+ },
+ [0x12308]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12308,
+ },
+ [0x12309]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12309,
+ },
+ [0x1230A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230A,
+ },
+ [0x1230B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230B,
+ },
+ [0x1230C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230C,
+ },
+ [0x1230D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230D,
+ },
+ [0x1230E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230E,
+ },
+ [0x1230F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230F,
+ },
+ [0x12310]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12310,
+ },
+ [0x12311]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12311,
+ },
+ [0x12312]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12312,
+ },
+ [0x12313]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12313,
+ },
+ [0x12314]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12314,
+ },
+ [0x12315]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12315,
+ },
+ [0x12316]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12316,
+ },
+ [0x12317]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12317,
+ },
+ [0x12318]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12318,
+ },
+ [0x12319]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12319,
+ },
+ [0x1231A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231A,
+ },
+ [0x1231B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231B,
+ },
+ [0x1231C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231C,
+ },
+ [0x1231D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231D,
+ },
+ [0x1231E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231E,
+ },
+ [0x1231F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231F,
+ },
+ [0x12320]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12320,
+ },
+ [0x12321]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12321,
+ },
+ [0x12322]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12322,
+ },
+ [0x12323]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12323,
+ },
+ [0x12324]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12324,
+ },
+ [0x12325]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12325,
+ },
+ [0x12326]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12326,
+ },
+ [0x12327]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12327,
+ },
+ [0x12328]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12328,
+ },
+ [0x12329]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12329,
+ },
+ [0x1232A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232A,
+ },
+ [0x1232B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232B,
+ },
+ [0x1232C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232C,
+ },
+ [0x1232D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232D,
+ },
+ [0x1232E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232E,
+ },
+ [0x1232F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232F,
+ },
+ [0x12330]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12330,
+ },
+ [0x12331]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12331,
+ },
+ [0x12332]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12332,
+ },
+ [0x12333]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12333,
+ },
+ [0x12334]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12334,
+ },
+ [0x12335]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12335,
+ },
+ [0x12336]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12336,
+ },
+ [0x12337]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12337,
+ },
+ [0x12338]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12338,
+ },
+ [0x12339]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12339,
+ },
+ [0x1233A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233A,
+ },
+ [0x1233B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233B,
+ },
+ [0x1233C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233C,
+ },
+ [0x1233D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233D,
+ },
+ [0x1233E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233E,
+ },
+ [0x1233F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233F,
+ },
+ [0x12340]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12340,
+ },
+ [0x12341]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12341,
+ },
+ [0x12342]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12342,
+ },
+ [0x12343]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12343,
+ },
+ [0x12344]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12344,
+ },
+ [0x12345]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12345,
+ },
+ [0x12346]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12346,
+ },
+ [0x12347]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12347,
+ },
+ [0x12348]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12348,
+ },
+ [0x12349]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12349,
+ },
+ [0x1234A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234A,
+ },
+ [0x1234B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234B,
+ },
+ [0x1234C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234C,
+ },
+ [0x1234D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234D,
+ },
+ [0x1234E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234E,
+ },
+ [0x1234F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234F,
+ },
+ [0x12350]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12350,
+ },
+ [0x12351]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12351,
+ },
+ [0x12352]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12352,
+ },
+ [0x12353]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12353,
+ },
+ [0x12354]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12354,
+ },
+ [0x12355]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12355,
+ },
+ [0x12356]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12356,
+ },
+ [0x12357]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12357,
+ },
+ [0x12358]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12358,
+ },
+ [0x12359]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12359,
+ },
+ [0x1235A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235A,
+ },
+ [0x1235B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235B,
+ },
+ [0x1235C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235C,
+ },
+ [0x1235D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235D,
+ },
+ [0x1235E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235E,
+ },
+ [0x1235F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235F,
+ },
+ [0x12360]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12360,
+ },
+ [0x12361]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12361,
+ },
+ [0x12362]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12362,
+ },
+ [0x12363]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12363,
+ },
+ [0x12364]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12364,
+ },
+ [0x12365]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12365,
+ },
+ [0x12366]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12366,
+ },
+ [0x12367]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12367,
+ },
+ [0x12368]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12368,
+ },
+ [0x12369]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12369,
+ },
+ [0x1236A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236A,
+ },
+ [0x1236B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236B,
+ },
+ [0x1236C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236C,
+ },
+ [0x1236D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236D,
+ },
+ [0x1236E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236E,
+ },
+ [0x1236F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236F,
+ },
+ [0x12370]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12370,
+ },
+ [0x12371]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12371,
+ },
+ [0x12372]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12372,
+ },
+ [0x12373]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12373,
+ },
+ [0x12374]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12374,
+ },
+ [0x12375]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12375,
+ },
+ [0x12376]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12376,
+ },
+ [0x12377]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12377,
+ },
+ [0x12378]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12378,
+ },
+ [0x12379]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12379,
+ },
+ [0x1237A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1237A,
+ },
+ [0x1237B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1237B,
+ },
+ [0x1237C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1237C,
+ },
+ [0x1237D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1237D,
+ },
+ [0x1237E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1237E,
+ },
+ [0x1237F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1237F,
+ },
+ [0x12380]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12380,
+ },
+ [0x12381]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12381,
+ },
+ [0x12382]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12382,
+ },
+ [0x12383]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12383,
+ },
+ [0x12384]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12384,
+ },
+ [0x12385]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12385,
+ },
+ [0x12386]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12386,
+ },
+ [0x12387]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12387,
+ },
+ [0x12388]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12388,
+ },
+ [0x12389]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12389,
+ },
+ [0x1238A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1238A,
+ },
+ [0x1238B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1238B,
+ },
+ [0x1238C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1238C,
+ },
+ [0x1238D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1238D,
+ },
+ [0x1238E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1238E,
+ },
+ [0x1238F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1238F,
+ },
+ [0x12390]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12390,
+ },
+ [0x12391]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12391,
+ },
+ [0x12392]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12392,
+ },
+ [0x12393]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12393,
+ },
+ [0x12394]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12394,
+ },
+ [0x12395]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12395,
+ },
+ [0x12396]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12396,
+ },
+ [0x12397]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12397,
+ },
+ [0x12398]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12398,
+ },
+ [0x12399]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12399,
+ },
+ [0x12400]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12400,
+ },
+ [0x12401]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12401,
+ },
+ [0x12402]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12402,
+ },
+ [0x12403]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12403,
+ },
+ [0x12404]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12404,
+ },
+ [0x12405]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12405,
+ },
+ [0x12406]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12406,
+ },
+ [0x12407]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12407,
+ },
+ [0x12408]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12408,
+ },
+ [0x12409]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12409,
+ },
+ [0x1240A]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240A,
+ },
+ [0x1240B]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240B,
+ },
+ [0x1240C]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240C,
+ },
+ [0x1240D]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240D,
+ },
+ [0x1240E]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240E,
+ },
+ [0x1240F]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240F,
+ },
+ [0x12410]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12410,
+ },
+ [0x12411]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12411,
+ },
+ [0x12412]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12412,
+ },
+ [0x12413]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12413,
+ },
+ [0x12414]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12414,
+ },
+ [0x12415]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12415,
+ },
+ [0x12416]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12416,
+ },
+ [0x12417]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12417,
+ },
+ [0x12418]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12418,
+ },
+ [0x12419]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12419,
+ },
+ [0x1241A]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241A,
+ },
+ [0x1241B]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241B,
+ },
+ [0x1241C]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241C,
+ },
+ [0x1241D]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241D,
+ },
+ [0x1241E]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241E,
+ },
+ [0x1241F]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241F,
+ },
+ [0x12420]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12420,
+ },
+ [0x12421]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12421,
+ },
+ [0x12422]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12422,
+ },
+ [0x12423]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12423,
+ },
+ [0x12424]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12424,
+ },
+ [0x12425]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12425,
+ },
+ [0x12426]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12426,
+ },
+ [0x12427]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12427,
+ },
+ [0x12428]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12428,
+ },
+ [0x12429]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12429,
+ },
+ [0x1242A]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242A,
+ },
+ [0x1242B]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242B,
+ },
+ [0x1242C]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242C,
+ },
+ [0x1242D]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242D,
+ },
+ [0x1242E]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242E,
+ },
+ [0x1242F]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242F,
+ },
+ [0x12430]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12430,
+ },
+ [0x12431]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12431,
+ },
+ [0x12432]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12432,
+ },
+ [0x12433]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12433,
+ },
+ [0x12434]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12434,
+ },
+ [0x12435]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12435,
+ },
+ [0x12436]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12436,
+ },
+ [0x12437]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12437,
+ },
+ [0x12438]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12438,
+ },
+ [0x12439]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12439,
+ },
+ [0x1243A]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243A,
+ },
+ [0x1243B]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243B,
+ },
+ [0x1243C]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243C,
+ },
+ [0x1243D]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243D,
+ },
+ [0x1243E]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243E,
+ },
+ [0x1243F]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243F,
+ },
+ [0x12440]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12440,
+ },
+ [0x12441]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12441,
+ },
+ [0x12442]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12442,
+ },
+ [0x12443]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12443,
+ },
+ [0x12444]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12444,
+ },
+ [0x12445]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12445,
+ },
+ [0x12446]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12446,
+ },
+ [0x12447]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12447,
+ },
+ [0x12448]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12448,
+ },
+ [0x12449]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12449,
+ },
+ [0x1244A]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244A,
+ },
+ [0x1244B]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244B,
+ },
+ [0x1244C]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244C,
+ },
+ [0x1244D]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244D,
+ },
+ [0x1244E]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244E,
+ },
+ [0x1244F]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244F,
+ },
+ [0x12450]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12450,
+ },
+ [0x12451]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12451,
+ },
+ [0x12452]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12452,
+ },
+ [0x12453]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12453,
+ },
+ [0x12454]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12454,
+ },
+ [0x12455]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12455,
+ },
+ [0x12456]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12456,
+ },
+ [0x12457]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12457,
+ },
+ [0x12458]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12458,
+ },
+ [0x12459]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12459,
+ },
+ [0x1245A]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245A,
+ },
+ [0x1245B]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245B,
+ },
+ [0x1245C]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245C,
+ },
+ [0x1245D]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245D,
+ },
+ [0x1245E]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245E,
+ },
+ [0x1245F]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245F,
+ },
+ [0x12460]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12460,
+ },
+ [0x12461]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12461,
+ },
+ [0x12462]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12462,
+ },
+ [0x12463]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12463,
+ },
+ [0x12464]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12464,
+ },
+ [0x12465]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12465,
+ },
+ [0x12466]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12466,
+ },
+ [0x12467]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12467,
+ },
+ [0x12468]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12468,
+ },
+ [0x12469]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12469,
+ },
+ [0x1246A]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1246A,
+ },
+ [0x1246B]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1246B,
+ },
+ [0x1246C]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1246C,
+ },
+ [0x1246D]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1246D,
+ },
+ [0x1246E]={
+ category="nl",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1246E,
+ },
+ [0x12470]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x12470,
+ },
+ [0x12471]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x12471,
+ },
+ [0x12472]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x12472,
+ },
+ [0x12473]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x12473,
+ },
+ [0x12474]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x12474,
+ },
+ [0x12480]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12480,
+ },
+ [0x12481]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12481,
+ },
+ [0x12482]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12482,
+ },
+ [0x12483]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12483,
+ },
+ [0x12484]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12484,
+ },
+ [0x12485]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12485,
+ },
+ [0x12486]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12486,
+ },
+ [0x12487]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12487,
+ },
+ [0x12488]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12488,
+ },
+ [0x12489]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12489,
+ },
+ [0x1248A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1248A,
+ },
+ [0x1248B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1248B,
+ },
+ [0x1248C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1248C,
+ },
+ [0x1248D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1248D,
+ },
+ [0x1248E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1248E,
+ },
+ [0x1248F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1248F,
+ },
+ [0x12490]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12490,
+ },
+ [0x12491]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12491,
+ },
+ [0x12492]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12492,
+ },
+ [0x12493]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12493,
+ },
+ [0x12494]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12494,
+ },
+ [0x12495]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12495,
+ },
+ [0x12496]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12496,
+ },
+ [0x12497]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12497,
+ },
+ [0x12498]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12498,
+ },
+ [0x12499]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12499,
+ },
+ [0x1249A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1249A,
+ },
+ [0x1249B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1249B,
+ },
+ [0x1249C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1249C,
+ },
+ [0x1249D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1249D,
+ },
+ [0x1249E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1249E,
+ },
+ [0x1249F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1249F,
+ },
+ [0x124A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124A0,
+ },
+ [0x124A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124A1,
+ },
+ [0x124A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124A2,
+ },
+ [0x124A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124A3,
+ },
+ [0x124A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124A4,
+ },
+ [0x124A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124A5,
+ },
+ [0x124A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124A6,
+ },
+ [0x124A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124A7,
+ },
+ [0x124A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124A8,
+ },
+ [0x124A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124A9,
+ },
+ [0x124AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124AA,
+ },
+ [0x124AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124AB,
+ },
+ [0x124AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124AC,
+ },
+ [0x124AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124AD,
+ },
+ [0x124AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124AE,
+ },
+ [0x124AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124AF,
+ },
+ [0x124B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124B0,
+ },
+ [0x124B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124B1,
+ },
+ [0x124B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124B2,
+ },
+ [0x124B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124B3,
+ },
+ [0x124B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124B4,
+ },
+ [0x124B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124B5,
+ },
+ [0x124B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124B6,
+ },
+ [0x124B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124B7,
+ },
+ [0x124B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124B8,
+ },
+ [0x124B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124B9,
+ },
+ [0x124BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124BA,
+ },
+ [0x124BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124BB,
+ },
+ [0x124BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124BC,
+ },
+ [0x124BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124BD,
+ },
+ [0x124BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124BE,
+ },
+ [0x124BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124BF,
+ },
+ [0x124C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124C0,
+ },
+ [0x124C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124C1,
+ },
+ [0x124C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124C2,
+ },
+ [0x124C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124C3,
+ },
+ [0x124C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124C4,
+ },
+ [0x124C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124C5,
+ },
+ [0x124C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124C6,
+ },
+ [0x124C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124C7,
+ },
+ [0x124C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124C8,
+ },
+ [0x124C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124C9,
+ },
+ [0x124CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124CA,
+ },
+ [0x124CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124CB,
+ },
+ [0x124CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124CC,
+ },
+ [0x124CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124CD,
+ },
+ [0x124CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124CE,
+ },
+ [0x124CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124CF,
+ },
+ [0x124D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124D0,
+ },
+ [0x124D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124D1,
+ },
+ [0x124D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124D2,
+ },
+ [0x124D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124D3,
+ },
+ [0x124D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124D4,
+ },
+ [0x124D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124D5,
+ },
+ [0x124D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124D6,
+ },
+ [0x124D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124D7,
+ },
+ [0x124D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124D8,
+ },
+ [0x124D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124D9,
+ },
+ [0x124DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124DA,
+ },
+ [0x124DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124DB,
+ },
+ [0x124DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124DC,
+ },
+ [0x124DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124DD,
+ },
+ [0x124DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124DE,
+ },
+ [0x124DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124DF,
+ },
+ [0x124E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124E0,
+ },
+ [0x124E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124E1,
+ },
+ [0x124E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124E2,
+ },
+ [0x124E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124E3,
+ },
+ [0x124E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124E4,
+ },
+ [0x124E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124E5,
+ },
+ [0x124E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124E6,
+ },
+ [0x124E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124E7,
+ },
+ [0x124E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124E8,
+ },
+ [0x124E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124E9,
+ },
+ [0x124EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124EA,
+ },
+ [0x124EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124EB,
+ },
+ [0x124EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124EC,
+ },
+ [0x124ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124ED,
+ },
+ [0x124EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124EE,
+ },
+ [0x124EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124EF,
+ },
+ [0x124F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124F0,
+ },
+ [0x124F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124F1,
+ },
+ [0x124F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124F2,
+ },
+ [0x124F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124F3,
+ },
+ [0x124F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124F4,
+ },
+ [0x124F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124F5,
+ },
+ [0x124F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124F6,
+ },
+ [0x124F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124F7,
+ },
+ [0x124F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124F8,
+ },
+ [0x124F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124F9,
+ },
+ [0x124FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124FA,
+ },
+ [0x124FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124FB,
+ },
+ [0x124FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124FC,
+ },
+ [0x124FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124FD,
+ },
+ [0x124FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124FE,
+ },
+ [0x124FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124FF,
+ },
+ [0x12500]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12500,
+ },
+ [0x12501]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12501,
+ },
+ [0x12502]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12502,
+ },
+ [0x12503]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12503,
+ },
+ [0x12504]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12504,
+ },
+ [0x12505]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12505,
+ },
+ [0x12506]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12506,
+ },
+ [0x12507]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12507,
+ },
+ [0x12508]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12508,
+ },
+ [0x12509]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12509,
+ },
+ [0x1250A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1250A,
+ },
+ [0x1250B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1250B,
+ },
+ [0x1250C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1250C,
+ },
+ [0x1250D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1250D,
+ },
+ [0x1250E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1250E,
+ },
+ [0x1250F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1250F,
+ },
+ [0x12510]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12510,
+ },
+ [0x12511]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12511,
+ },
+ [0x12512]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12512,
+ },
+ [0x12513]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12513,
+ },
+ [0x12514]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12514,
+ },
+ [0x12515]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12515,
+ },
+ [0x12516]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12516,
+ },
+ [0x12517]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12517,
+ },
+ [0x12518]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12518,
+ },
+ [0x12519]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12519,
+ },
+ [0x1251A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1251A,
+ },
+ [0x1251B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1251B,
+ },
+ [0x1251C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1251C,
+ },
+ [0x1251D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1251D,
+ },
+ [0x1251E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1251E,
+ },
+ [0x1251F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1251F,
+ },
+ [0x12520]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12520,
+ },
+ [0x12521]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12521,
+ },
+ [0x12522]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12522,
+ },
+ [0x12523]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12523,
+ },
+ [0x12524]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12524,
+ },
+ [0x12525]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12525,
+ },
+ [0x12526]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12526,
+ },
+ [0x12527]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12527,
+ },
+ [0x12528]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12528,
+ },
+ [0x12529]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12529,
+ },
+ [0x1252A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1252A,
+ },
+ [0x1252B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1252B,
+ },
+ [0x1252C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1252C,
+ },
+ [0x1252D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1252D,
+ },
+ [0x1252E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1252E,
+ },
+ [0x1252F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1252F,
+ },
+ [0x12530]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12530,
+ },
+ [0x12531]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12531,
+ },
+ [0x12532]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12532,
+ },
+ [0x12533]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12533,
+ },
+ [0x12534]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12534,
+ },
+ [0x12535]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12535,
+ },
+ [0x12536]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12536,
+ },
+ [0x12537]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12537,
+ },
+ [0x12538]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12538,
+ },
+ [0x12539]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12539,
+ },
+ [0x1253A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1253A,
+ },
+ [0x1253B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1253B,
+ },
+ [0x1253C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1253C,
+ },
+ [0x1253D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1253D,
+ },
+ [0x1253E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1253E,
+ },
+ [0x1253F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1253F,
+ },
+ [0x12540]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12540,
+ },
+ [0x12541]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12541,
+ },
+ [0x12542]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12542,
+ },
+ [0x12543]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12543,
+ },
+ [0x13000]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13000,
+ },
+ [0x13001]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13001,
+ },
+ [0x13002]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13002,
+ },
+ [0x13003]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13003,
+ },
+ [0x13004]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13004,
+ },
+ [0x13005]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13005,
+ },
+ [0x13006]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13006,
+ },
+ [0x13007]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13007,
+ },
+ [0x13008]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13008,
+ },
+ [0x13009]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13009,
+ },
+ [0x1300A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300A,
+ },
+ [0x1300B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300B,
+ },
+ [0x1300C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300C,
+ },
+ [0x1300D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300D,
+ },
+ [0x1300E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300E,
+ },
+ [0x1300F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300F,
+ },
+ [0x13010]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13010,
+ },
+ [0x13011]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13011,
+ },
+ [0x13012]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13012,
+ },
+ [0x13013]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13013,
+ },
+ [0x13014]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13014,
+ },
+ [0x13015]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13015,
+ },
+ [0x13016]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13016,
+ },
+ [0x13017]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13017,
+ },
+ [0x13018]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13018,
+ },
+ [0x13019]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13019,
+ },
+ [0x1301A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301A,
+ },
+ [0x1301B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301B,
+ },
+ [0x1301C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301C,
+ },
+ [0x1301D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301D,
+ },
+ [0x1301E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301E,
+ },
+ [0x1301F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301F,
+ },
+ [0x13020]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13020,
+ },
+ [0x13021]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13021,
+ },
+ [0x13022]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13022,
+ },
+ [0x13023]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13023,
+ },
+ [0x13024]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13024,
+ },
+ [0x13025]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13025,
+ },
+ [0x13026]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13026,
+ },
+ [0x13027]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13027,
+ },
+ [0x13028]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13028,
+ },
+ [0x13029]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13029,
+ },
+ [0x1302A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302A,
+ },
+ [0x1302B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302B,
+ },
+ [0x1302C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302C,
+ },
+ [0x1302D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302D,
+ },
+ [0x1302E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302E,
+ },
+ [0x1302F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302F,
+ },
+ [0x13030]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13030,
+ },
+ [0x13031]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13031,
+ },
+ [0x13032]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13032,
+ },
+ [0x13033]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13033,
+ },
+ [0x13034]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13034,
+ },
+ [0x13035]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13035,
+ },
+ [0x13036]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13036,
+ },
+ [0x13037]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13037,
+ },
+ [0x13038]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13038,
+ },
+ [0x13039]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13039,
+ },
+ [0x1303A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303A,
+ },
+ [0x1303B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303B,
+ },
+ [0x1303C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303C,
+ },
+ [0x1303D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303D,
+ },
+ [0x1303E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303E,
+ },
+ [0x1303F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303F,
+ },
+ [0x13040]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13040,
+ },
+ [0x13041]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13041,
+ },
+ [0x13042]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13042,
+ },
+ [0x13043]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13043,
+ },
+ [0x13044]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13044,
+ },
+ [0x13045]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13045,
+ },
+ [0x13046]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13046,
+ },
+ [0x13047]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13047,
+ },
+ [0x13048]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13048,
+ },
+ [0x13049]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13049,
+ },
+ [0x1304A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304A,
+ },
+ [0x1304B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304B,
+ },
+ [0x1304C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304C,
+ },
+ [0x1304D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304D,
+ },
+ [0x1304E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304E,
+ },
+ [0x1304F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304F,
+ },
+ [0x13050]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13050,
+ },
+ [0x13051]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13051,
+ },
+ [0x13052]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13052,
+ },
+ [0x13053]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13053,
+ },
+ [0x13054]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13054,
+ },
+ [0x13055]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13055,
+ },
+ [0x13056]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13056,
+ },
+ [0x13057]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13057,
+ },
+ [0x13058]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13058,
+ },
+ [0x13059]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13059,
+ },
+ [0x1305A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305A,
+ },
+ [0x1305B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305B,
+ },
+ [0x1305C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305C,
+ },
+ [0x1305D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305D,
+ },
+ [0x1305E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305E,
+ },
+ [0x1305F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305F,
+ },
+ [0x13060]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13060,
+ },
+ [0x13061]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13061,
+ },
+ [0x13062]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13062,
+ },
+ [0x13063]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13063,
+ },
+ [0x13064]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13064,
+ },
+ [0x13065]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13065,
+ },
+ [0x13066]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13066,
+ },
+ [0x13067]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13067,
+ },
+ [0x13068]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13068,
+ },
+ [0x13069]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13069,
+ },
+ [0x1306A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306A,
+ },
+ [0x1306B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306B,
+ },
+ [0x1306C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306C,
+ },
+ [0x1306D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306D,
+ },
+ [0x1306E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306E,
+ },
+ [0x1306F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306F,
+ },
+ [0x13070]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13070,
+ },
+ [0x13071]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13071,
+ },
+ [0x13072]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13072,
+ },
+ [0x13073]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13073,
+ },
+ [0x13074]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13074,
+ },
+ [0x13075]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13075,
+ },
+ [0x13076]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13076,
+ },
+ [0x13077]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13077,
+ },
+ [0x13078]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13078,
+ },
+ [0x13079]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13079,
+ },
+ [0x1307A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307A,
+ },
+ [0x1307B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307B,
+ },
+ [0x1307C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307C,
+ },
+ [0x1307D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307D,
+ },
+ [0x1307E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307E,
+ },
+ [0x1307F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307F,
+ },
+ [0x13080]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13080,
+ },
+ [0x13081]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13081,
+ },
+ [0x13082]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13082,
+ },
+ [0x13083]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13083,
+ },
+ [0x13084]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13084,
+ },
+ [0x13085]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13085,
+ },
+ [0x13086]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13086,
+ },
+ [0x13087]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13087,
+ },
+ [0x13088]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13088,
+ },
+ [0x13089]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13089,
+ },
+ [0x1308A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308A,
+ },
+ [0x1308B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308B,
+ },
+ [0x1308C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308C,
+ },
+ [0x1308D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308D,
+ },
+ [0x1308E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308E,
+ },
+ [0x1308F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308F,
+ },
+ [0x13090]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13090,
+ },
+ [0x13091]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13091,
+ },
+ [0x13092]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13092,
+ },
+ [0x13093]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13093,
+ },
+ [0x13094]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13094,
+ },
+ [0x13095]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13095,
+ },
+ [0x13096]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13096,
+ },
+ [0x13097]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13097,
+ },
+ [0x13098]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13098,
+ },
+ [0x13099]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13099,
+ },
+ [0x1309A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309A,
+ },
+ [0x1309B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309B,
+ },
+ [0x1309C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309C,
+ },
+ [0x1309D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309D,
+ },
+ [0x1309E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309E,
+ },
+ [0x1309F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309F,
+ },
+ [0x130A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A0,
+ },
+ [0x130A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A1,
+ },
+ [0x130A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A2,
+ },
+ [0x130A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A3,
+ },
+ [0x130A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A4,
+ },
+ [0x130A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A5,
+ },
+ [0x130A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A6,
+ },
+ [0x130A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A7,
+ },
+ [0x130A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A8,
+ },
+ [0x130A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A9,
+ },
+ [0x130AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130AA,
+ },
+ [0x130AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130AB,
+ },
+ [0x130AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130AC,
+ },
+ [0x130AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130AD,
+ },
+ [0x130AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130AE,
+ },
+ [0x130AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130AF,
+ },
+ [0x130B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B0,
+ },
+ [0x130B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B1,
+ },
+ [0x130B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B2,
+ },
+ [0x130B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B3,
+ },
+ [0x130B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B4,
+ },
+ [0x130B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B5,
+ },
+ [0x130B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B6,
+ },
+ [0x130B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B7,
+ },
+ [0x130B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B8,
+ },
+ [0x130B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B9,
+ },
+ [0x130BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130BA,
+ },
+ [0x130BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130BB,
+ },
+ [0x130BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130BC,
+ },
+ [0x130BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130BD,
+ },
+ [0x130BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130BE,
+ },
+ [0x130BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130BF,
+ },
+ [0x130C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C0,
+ },
+ [0x130C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C1,
+ },
+ [0x130C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C2,
+ },
+ [0x130C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C3,
+ },
+ [0x130C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C4,
+ },
+ [0x130C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C5,
+ },
+ [0x130C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C6,
+ },
+ [0x130C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C7,
+ },
+ [0x130C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C8,
+ },
+ [0x130C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C9,
+ },
+ [0x130CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130CA,
+ },
+ [0x130CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130CB,
+ },
+ [0x130CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130CC,
+ },
+ [0x130CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130CD,
+ },
+ [0x130CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130CE,
+ },
+ [0x130CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130CF,
+ },
+ [0x130D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D0,
+ },
+ [0x130D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D1,
+ },
+ [0x130D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D2,
+ },
+ [0x130D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D3,
+ },
+ [0x130D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D4,
+ },
+ [0x130D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D5,
+ },
+ [0x130D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D6,
+ },
+ [0x130D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D7,
+ },
+ [0x130D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D8,
+ },
+ [0x130D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D9,
+ },
+ [0x130DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130DA,
+ },
+ [0x130DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130DB,
+ },
+ [0x130DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130DC,
+ },
+ [0x130DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130DD,
+ },
+ [0x130DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130DE,
+ },
+ [0x130DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130DF,
+ },
+ [0x130E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E0,
+ },
+ [0x130E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E1,
+ },
+ [0x130E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E2,
+ },
+ [0x130E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E3,
+ },
+ [0x130E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E4,
+ },
+ [0x130E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E5,
+ },
+ [0x130E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E6,
+ },
+ [0x130E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E7,
+ },
+ [0x130E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E8,
+ },
+ [0x130E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E9,
+ },
+ [0x130EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130EA,
+ },
+ [0x130EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130EB,
+ },
+ [0x130EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130EC,
+ },
+ [0x130ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130ED,
+ },
+ [0x130EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130EE,
+ },
+ [0x130EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130EF,
+ },
+ [0x130F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F0,
+ },
+ [0x130F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F1,
+ },
+ [0x130F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F2,
+ },
+ [0x130F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F3,
+ },
+ [0x130F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F4,
+ },
+ [0x130F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F5,
+ },
+ [0x130F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F6,
+ },
+ [0x130F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F7,
+ },
+ [0x130F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F8,
+ },
+ [0x130F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F9,
+ },
+ [0x130FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130FA,
+ },
+ [0x130FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130FB,
+ },
+ [0x130FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130FC,
+ },
+ [0x130FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130FD,
+ },
+ [0x130FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130FE,
+ },
+ [0x130FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130FF,
+ },
+ [0x13100]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13100,
+ },
+ [0x13101]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13101,
+ },
+ [0x13102]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13102,
+ },
+ [0x13103]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13103,
+ },
+ [0x13104]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13104,
+ },
+ [0x13105]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13105,
+ },
+ [0x13106]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13106,
+ },
+ [0x13107]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13107,
+ },
+ [0x13108]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13108,
+ },
+ [0x13109]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13109,
+ },
+ [0x1310A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310A,
+ },
+ [0x1310B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310B,
+ },
+ [0x1310C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310C,
+ },
+ [0x1310D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310D,
+ },
+ [0x1310E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310E,
+ },
+ [0x1310F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310F,
+ },
+ [0x13110]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13110,
+ },
+ [0x13111]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13111,
+ },
+ [0x13112]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13112,
+ },
+ [0x13113]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13113,
+ },
+ [0x13114]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13114,
+ },
+ [0x13115]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13115,
+ },
+ [0x13116]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13116,
+ },
+ [0x13117]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13117,
+ },
+ [0x13118]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13118,
+ },
+ [0x13119]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13119,
+ },
+ [0x1311A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1311A,
+ },
+ [0x1311B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1311B,
+ },
+ [0x1311C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1311C,
+ },
+ [0x1311D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1311D,
+ },
+ [0x1311E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1311E,
+ },
+ [0x1311F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1311F,
+ },
+ [0x13120]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13120,
+ },
+ [0x13121]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13121,
+ },
+ [0x13122]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13122,
+ },
+ [0x13123]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13123,
+ },
+ [0x13124]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13124,
+ },
+ [0x13125]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13125,
+ },
+ [0x13126]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13126,
+ },
+ [0x13127]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13127,
+ },
+ [0x13128]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13128,
+ },
+ [0x13129]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13129,
+ },
+ [0x1312A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312A,
+ },
+ [0x1312B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312B,
+ },
+ [0x1312C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312C,
+ },
+ [0x1312D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312D,
+ },
+ [0x1312E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312E,
+ },
+ [0x1312F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312F,
+ },
+ [0x13130]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13130,
+ },
+ [0x13131]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13131,
+ },
+ [0x13132]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13132,
+ },
+ [0x13133]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13133,
+ },
+ [0x13134]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13134,
+ },
+ [0x13135]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13135,
+ },
+ [0x13136]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13136,
+ },
+ [0x13137]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13137,
+ },
+ [0x13138]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13138,
+ },
+ [0x13139]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13139,
+ },
+ [0x1313A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313A,
+ },
+ [0x1313B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313B,
+ },
+ [0x1313C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313C,
+ },
+ [0x1313D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313D,
+ },
+ [0x1313E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313E,
+ },
+ [0x1313F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313F,
+ },
+ [0x13140]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13140,
+ },
+ [0x13141]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13141,
+ },
+ [0x13142]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13142,
+ },
+ [0x13143]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13143,
+ },
+ [0x13144]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13144,
+ },
+ [0x13145]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13145,
+ },
+ [0x13146]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13146,
+ },
+ [0x13147]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13147,
+ },
+ [0x13148]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13148,
+ },
+ [0x13149]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13149,
+ },
+ [0x1314A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314A,
+ },
+ [0x1314B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314B,
+ },
+ [0x1314C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314C,
+ },
+ [0x1314D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314D,
+ },
+ [0x1314E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314E,
+ },
+ [0x1314F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314F,
+ },
+ [0x13150]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13150,
+ },
+ [0x13151]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13151,
+ },
+ [0x13152]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13152,
+ },
+ [0x13153]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13153,
+ },
+ [0x13154]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13154,
+ },
+ [0x13155]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13155,
+ },
+ [0x13156]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13156,
+ },
+ [0x13157]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13157,
+ },
+ [0x13158]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13158,
+ },
+ [0x13159]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13159,
+ },
+ [0x1315A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315A,
+ },
+ [0x1315B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315B,
+ },
+ [0x1315C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315C,
+ },
+ [0x1315D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315D,
+ },
+ [0x1315E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315E,
+ },
+ [0x1315F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315F,
+ },
+ [0x13160]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13160,
+ },
+ [0x13161]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13161,
+ },
+ [0x13162]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13162,
+ },
+ [0x13163]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13163,
+ },
+ [0x13164]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13164,
+ },
+ [0x13165]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13165,
+ },
+ [0x13166]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13166,
+ },
+ [0x13167]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13167,
+ },
+ [0x13168]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13168,
+ },
+ [0x13169]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13169,
+ },
+ [0x1316A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1316A,
+ },
+ [0x1316B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1316B,
+ },
+ [0x1316C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1316C,
+ },
+ [0x1316D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1316D,
+ },
+ [0x1316E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1316E,
+ },
+ [0x1316F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1316F,
+ },
+ [0x13170]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13170,
+ },
+ [0x13171]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13171,
+ },
+ [0x13172]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13172,
+ },
+ [0x13173]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13173,
+ },
+ [0x13174]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13174,
+ },
+ [0x13175]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13175,
+ },
+ [0x13176]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13176,
+ },
+ [0x13177]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13177,
+ },
+ [0x13178]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13178,
+ },
+ [0x13179]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13179,
+ },
+ [0x1317A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1317A,
+ },
+ [0x1317B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1317B,
+ },
+ [0x1317C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1317C,
+ },
+ [0x1317D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1317D,
+ },
+ [0x1317E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1317E,
+ },
+ [0x1317F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1317F,
+ },
+ [0x13180]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13180,
+ },
+ [0x13181]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13181,
+ },
+ [0x13182]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13182,
+ },
+ [0x13183]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13183,
+ },
+ [0x13184]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13184,
+ },
+ [0x13185]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13185,
+ },
+ [0x13186]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13186,
+ },
+ [0x13187]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13187,
+ },
+ [0x13188]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13188,
+ },
+ [0x13189]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13189,
+ },
+ [0x1318A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318A,
+ },
+ [0x1318B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318B,
+ },
+ [0x1318C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318C,
+ },
+ [0x1318D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318D,
+ },
+ [0x1318E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318E,
+ },
+ [0x1318F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318F,
+ },
+ [0x13190]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13190,
+ },
+ [0x13191]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13191,
+ },
+ [0x13192]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13192,
+ },
+ [0x13193]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13193,
+ },
+ [0x13194]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13194,
+ },
+ [0x13195]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13195,
+ },
+ [0x13196]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13196,
+ },
+ [0x13197]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13197,
+ },
+ [0x13198]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13198,
+ },
+ [0x13199]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13199,
+ },
+ [0x1319A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319A,
+ },
+ [0x1319B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319B,
+ },
+ [0x1319C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319C,
+ },
+ [0x1319D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319D,
+ },
+ [0x1319E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319E,
+ },
+ [0x1319F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319F,
+ },
+ [0x131A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A0,
+ },
+ [0x131A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A1,
+ },
+ [0x131A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A2,
+ },
+ [0x131A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A3,
+ },
+ [0x131A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A4,
+ },
+ [0x131A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A5,
+ },
+ [0x131A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A6,
+ },
+ [0x131A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A7,
+ },
+ [0x131A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A8,
+ },
+ [0x131A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A9,
+ },
+ [0x131AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131AA,
+ },
+ [0x131AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131AB,
+ },
+ [0x131AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131AC,
+ },
+ [0x131AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131AD,
+ },
+ [0x131AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131AE,
+ },
+ [0x131AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131AF,
+ },
+ [0x131B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B0,
+ },
+ [0x131B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B1,
+ },
+ [0x131B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B2,
+ },
+ [0x131B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B3,
+ },
+ [0x131B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B4,
+ },
+ [0x131B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B5,
+ },
+ [0x131B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B6,
+ },
+ [0x131B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B7,
+ },
+ [0x131B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B8,
+ },
+ [0x131B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B9,
+ },
+ [0x131BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131BA,
+ },
+ [0x131BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131BB,
+ },
+ [0x131BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131BC,
+ },
+ [0x131BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131BD,
+ },
+ [0x131BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131BE,
+ },
+ [0x131BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131BF,
+ },
+ [0x131C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C0,
+ },
+ [0x131C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C1,
+ },
+ [0x131C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C2,
+ },
+ [0x131C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C3,
+ },
+ [0x131C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C4,
+ },
+ [0x131C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C5,
+ },
+ [0x131C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C6,
+ },
+ [0x131C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C7,
+ },
+ [0x131C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C8,
+ },
+ [0x131C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C9,
+ },
+ [0x131CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131CA,
+ },
+ [0x131CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131CB,
+ },
+ [0x131CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131CC,
+ },
+ [0x131CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131CD,
+ },
+ [0x131CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131CE,
+ },
+ [0x131CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131CF,
+ },
+ [0x131D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D0,
+ },
+ [0x131D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D1,
+ },
+ [0x131D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D2,
+ },
+ [0x131D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D3,
+ },
+ [0x131D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D4,
+ },
+ [0x131D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D5,
+ },
+ [0x131D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D6,
+ },
+ [0x131D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D7,
+ },
+ [0x131D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D8,
+ },
+ [0x131D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D9,
+ },
+ [0x131DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131DA,
+ },
+ [0x131DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131DB,
+ },
+ [0x131DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131DC,
+ },
+ [0x131DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131DD,
+ },
+ [0x131DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131DE,
+ },
+ [0x131DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131DF,
+ },
+ [0x131E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E0,
+ },
+ [0x131E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E1,
+ },
+ [0x131E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E2,
+ },
+ [0x131E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E3,
+ },
+ [0x131E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E4,
+ },
+ [0x131E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E5,
+ },
+ [0x131E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E6,
+ },
+ [0x131E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E7,
+ },
+ [0x131E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E8,
+ },
+ [0x131E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E9,
+ },
+ [0x131EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131EA,
+ },
+ [0x131EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131EB,
+ },
+ [0x131EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131EC,
+ },
+ [0x131ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131ED,
+ },
+ [0x131EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131EE,
+ },
+ [0x131EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131EF,
+ },
+ [0x131F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F0,
+ },
+ [0x131F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F1,
+ },
+ [0x131F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F2,
+ },
+ [0x131F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F3,
+ },
+ [0x131F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F4,
+ },
+ [0x131F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F5,
+ },
+ [0x131F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F6,
+ },
+ [0x131F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F7,
+ },
+ [0x131F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F8,
+ },
+ [0x131F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F9,
+ },
+ [0x131FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131FA,
+ },
+ [0x131FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131FB,
+ },
+ [0x131FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131FC,
+ },
+ [0x131FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131FD,
+ },
+ [0x131FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131FE,
+ },
+ [0x131FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131FF,
+ },
+ [0x13200]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13200,
+ },
+ [0x13201]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13201,
+ },
+ [0x13202]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13202,
+ },
+ [0x13203]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13203,
+ },
+ [0x13204]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13204,
+ },
+ [0x13205]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13205,
+ },
+ [0x13206]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13206,
+ },
+ [0x13207]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13207,
+ },
+ [0x13208]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13208,
+ },
+ [0x13209]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13209,
+ },
+ [0x1320A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320A,
+ },
+ [0x1320B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320B,
+ },
+ [0x1320C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320C,
+ },
+ [0x1320D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320D,
+ },
+ [0x1320E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320E,
+ },
+ [0x1320F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320F,
+ },
+ [0x13210]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13210,
+ },
+ [0x13211]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13211,
+ },
+ [0x13212]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13212,
+ },
+ [0x13213]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13213,
+ },
+ [0x13214]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13214,
+ },
+ [0x13215]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13215,
+ },
+ [0x13216]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13216,
+ },
+ [0x13217]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13217,
+ },
+ [0x13218]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13218,
+ },
+ [0x13219]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13219,
+ },
+ [0x1321A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321A,
+ },
+ [0x1321B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321B,
+ },
+ [0x1321C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321C,
+ },
+ [0x1321D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321D,
+ },
+ [0x1321E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321E,
+ },
+ [0x1321F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321F,
+ },
+ [0x13220]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13220,
+ },
+ [0x13221]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13221,
+ },
+ [0x13222]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13222,
+ },
+ [0x13223]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13223,
+ },
+ [0x13224]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13224,
+ },
+ [0x13225]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13225,
+ },
+ [0x13226]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13226,
+ },
+ [0x13227]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13227,
+ },
+ [0x13228]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13228,
+ },
+ [0x13229]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13229,
+ },
+ [0x1322A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322A,
+ },
+ [0x1322B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322B,
+ },
+ [0x1322C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322C,
+ },
+ [0x1322D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322D,
+ },
+ [0x1322E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322E,
+ },
+ [0x1322F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322F,
+ },
+ [0x13230]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13230,
+ },
+ [0x13231]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13231,
+ },
+ [0x13232]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13232,
+ },
+ [0x13233]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13233,
+ },
+ [0x13234]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13234,
+ },
+ [0x13235]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13235,
+ },
+ [0x13236]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13236,
+ },
+ [0x13237]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13237,
+ },
+ [0x13238]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13238,
+ },
+ [0x13239]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13239,
+ },
+ [0x1323A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323A,
+ },
+ [0x1323B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323B,
+ },
+ [0x1323C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323C,
+ },
+ [0x1323D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323D,
+ },
+ [0x1323E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323E,
+ },
+ [0x1323F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323F,
+ },
+ [0x13240]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13240,
+ },
+ [0x13241]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13241,
+ },
+ [0x13242]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13242,
+ },
+ [0x13243]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13243,
+ },
+ [0x13244]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13244,
+ },
+ [0x13245]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13245,
+ },
+ [0x13246]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13246,
+ },
+ [0x13247]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13247,
+ },
+ [0x13248]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13248,
+ },
+ [0x13249]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13249,
+ },
+ [0x1324A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324A,
+ },
+ [0x1324B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324B,
+ },
+ [0x1324C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324C,
+ },
+ [0x1324D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324D,
+ },
+ [0x1324E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324E,
+ },
+ [0x1324F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324F,
+ },
+ [0x13250]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13250,
+ },
+ [0x13251]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13251,
+ },
+ [0x13252]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13252,
+ },
+ [0x13253]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13253,
+ },
+ [0x13254]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13254,
+ },
+ [0x13255]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13255,
+ },
+ [0x13256]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13256,
+ },
+ [0x13257]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13257,
+ },
+ [0x13258]={
+ category="lo",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x13258,
+ },
+ [0x13259]={
+ category="lo",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x13259,
+ },
+ [0x1325A]={
+ category="lo",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x1325A,
+ },
+ [0x1325B]={
+ category="lo",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x1325B,
+ },
+ [0x1325C]={
+ category="lo",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x1325C,
+ },
+ [0x1325D]={
+ category="lo",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x1325D,
+ },
+ [0x1325E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1325E,
+ },
+ [0x1325F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1325F,
+ },
+ [0x13260]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13260,
+ },
+ [0x13261]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13261,
+ },
+ [0x13262]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13262,
+ },
+ [0x13263]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13263,
+ },
+ [0x13264]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13264,
+ },
+ [0x13265]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13265,
+ },
+ [0x13266]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13266,
+ },
+ [0x13267]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13267,
+ },
+ [0x13268]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13268,
+ },
+ [0x13269]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13269,
+ },
+ [0x1326A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326A,
+ },
+ [0x1326B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326B,
+ },
+ [0x1326C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326C,
+ },
+ [0x1326D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326D,
+ },
+ [0x1326E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326E,
+ },
+ [0x1326F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326F,
+ },
+ [0x13270]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13270,
+ },
+ [0x13271]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13271,
+ },
+ [0x13272]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13272,
+ },
+ [0x13273]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13273,
+ },
+ [0x13274]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13274,
+ },
+ [0x13275]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13275,
+ },
+ [0x13276]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13276,
+ },
+ [0x13277]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13277,
+ },
+ [0x13278]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13278,
+ },
+ [0x13279]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13279,
+ },
+ [0x1327A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327A,
+ },
+ [0x1327B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327B,
+ },
+ [0x1327C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327C,
+ },
+ [0x1327D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327D,
+ },
+ [0x1327E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327E,
+ },
+ [0x1327F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327F,
+ },
+ [0x13280]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13280,
+ },
+ [0x13281]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13281,
+ },
+ [0x13282]={
+ category="lo",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x13282,
+ },
+ [0x13283]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13283,
+ },
+ [0x13284]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13284,
+ },
+ [0x13285]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13285,
+ },
+ [0x13286]={
+ category="lo",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x13286,
+ },
+ [0x13287]={
+ category="lo",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x13287,
+ },
+ [0x13288]={
+ category="lo",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x13288,
+ },
+ [0x13289]={
+ category="lo",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x13289,
+ },
+ [0x1328A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328A,
+ },
+ [0x1328B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328B,
+ },
+ [0x1328C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328C,
+ },
+ [0x1328D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328D,
+ },
+ [0x1328E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328E,
+ },
+ [0x1328F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328F,
+ },
+ [0x13290]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13290,
+ },
+ [0x13291]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13291,
+ },
+ [0x13292]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13292,
+ },
+ [0x13293]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13293,
+ },
+ [0x13294]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13294,
+ },
+ [0x13295]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13295,
+ },
+ [0x13296]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13296,
+ },
+ [0x13297]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13297,
+ },
+ [0x13298]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13298,
+ },
+ [0x13299]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13299,
+ },
+ [0x1329A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329A,
+ },
+ [0x1329B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329B,
+ },
+ [0x1329C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329C,
+ },
+ [0x1329D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329D,
+ },
+ [0x1329E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329E,
+ },
+ [0x1329F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329F,
+ },
+ [0x132A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A0,
+ },
+ [0x132A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A1,
+ },
+ [0x132A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A2,
+ },
+ [0x132A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A3,
+ },
+ [0x132A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A4,
+ },
+ [0x132A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A5,
+ },
+ [0x132A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A6,
+ },
+ [0x132A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A7,
+ },
+ [0x132A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A8,
+ },
+ [0x132A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A9,
+ },
+ [0x132AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132AA,
+ },
+ [0x132AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132AB,
+ },
+ [0x132AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132AC,
+ },
+ [0x132AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132AD,
+ },
+ [0x132AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132AE,
+ },
+ [0x132AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132AF,
+ },
+ [0x132B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B0,
+ },
+ [0x132B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B1,
+ },
+ [0x132B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B2,
+ },
+ [0x132B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B3,
+ },
+ [0x132B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B4,
+ },
+ [0x132B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B5,
+ },
+ [0x132B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B6,
+ },
+ [0x132B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B7,
+ },
+ [0x132B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B8,
+ },
+ [0x132B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B9,
+ },
+ [0x132BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132BA,
+ },
+ [0x132BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132BB,
+ },
+ [0x132BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132BC,
+ },
+ [0x132BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132BD,
+ },
+ [0x132BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132BE,
+ },
+ [0x132BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132BF,
+ },
+ [0x132C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C0,
+ },
+ [0x132C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C1,
+ },
+ [0x132C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C2,
+ },
+ [0x132C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C3,
+ },
+ [0x132C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C4,
+ },
+ [0x132C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C5,
+ },
+ [0x132C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C6,
+ },
+ [0x132C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C7,
+ },
+ [0x132C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C8,
+ },
+ [0x132C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C9,
+ },
+ [0x132CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132CA,
+ },
+ [0x132CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132CB,
+ },
+ [0x132CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132CC,
+ },
+ [0x132CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132CD,
+ },
+ [0x132CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132CE,
+ },
+ [0x132CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132CF,
+ },
+ [0x132D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D0,
+ },
+ [0x132D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D1,
+ },
+ [0x132D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D2,
+ },
+ [0x132D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D3,
+ },
+ [0x132D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D4,
+ },
+ [0x132D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D5,
+ },
+ [0x132D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D6,
+ },
+ [0x132D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D7,
+ },
+ [0x132D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D8,
+ },
+ [0x132D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D9,
+ },
+ [0x132DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132DA,
+ },
+ [0x132DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132DB,
+ },
+ [0x132DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132DC,
+ },
+ [0x132DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132DD,
+ },
+ [0x132DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132DE,
+ },
+ [0x132DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132DF,
+ },
+ [0x132E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E0,
+ },
+ [0x132E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E1,
+ },
+ [0x132E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E2,
+ },
+ [0x132E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E3,
+ },
+ [0x132E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E4,
+ },
+ [0x132E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E5,
+ },
+ [0x132E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E6,
+ },
+ [0x132E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E7,
+ },
+ [0x132E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E8,
+ },
+ [0x132E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E9,
+ },
+ [0x132EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132EA,
+ },
+ [0x132EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132EB,
+ },
+ [0x132EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132EC,
+ },
+ [0x132ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132ED,
+ },
+ [0x132EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132EE,
+ },
+ [0x132EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132EF,
+ },
+ [0x132F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F0,
+ },
+ [0x132F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F1,
+ },
+ [0x132F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F2,
+ },
+ [0x132F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F3,
+ },
+ [0x132F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F4,
+ },
+ [0x132F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F5,
+ },
+ [0x132F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F6,
+ },
+ [0x132F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F7,
+ },
+ [0x132F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F8,
+ },
+ [0x132F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F9,
+ },
+ [0x132FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132FA,
+ },
+ [0x132FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132FB,
+ },
+ [0x132FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132FC,
+ },
+ [0x132FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132FD,
+ },
+ [0x132FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132FE,
+ },
+ [0x132FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132FF,
+ },
+ [0x13300]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13300,
+ },
+ [0x13301]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13301,
+ },
+ [0x13302]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13302,
+ },
+ [0x13303]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13303,
+ },
+ [0x13304]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13304,
+ },
+ [0x13305]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13305,
+ },
+ [0x13306]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13306,
+ },
+ [0x13307]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13307,
+ },
+ [0x13308]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13308,
+ },
+ [0x13309]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13309,
+ },
+ [0x1330A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330A,
+ },
+ [0x1330B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330B,
+ },
+ [0x1330C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330C,
+ },
+ [0x1330D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330D,
+ },
+ [0x1330E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330E,
+ },
+ [0x1330F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330F,
+ },
+ [0x13310]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13310,
+ },
+ [0x13311]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13311,
+ },
+ [0x13312]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13312,
+ },
+ [0x13313]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13313,
+ },
+ [0x13314]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13314,
+ },
+ [0x13315]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13315,
+ },
+ [0x13316]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13316,
+ },
+ [0x13317]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13317,
+ },
+ [0x13318]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13318,
+ },
+ [0x13319]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13319,
+ },
+ [0x1331A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331A,
+ },
+ [0x1331B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331B,
+ },
+ [0x1331C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331C,
+ },
+ [0x1331D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331D,
+ },
+ [0x1331E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331E,
+ },
+ [0x1331F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331F,
+ },
+ [0x13320]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13320,
+ },
+ [0x13321]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13321,
+ },
+ [0x13322]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13322,
+ },
+ [0x13323]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13323,
+ },
+ [0x13324]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13324,
+ },
+ [0x13325]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13325,
+ },
+ [0x13326]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13326,
+ },
+ [0x13327]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13327,
+ },
+ [0x13328]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13328,
+ },
+ [0x13329]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13329,
+ },
+ [0x1332A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332A,
+ },
+ [0x1332B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332B,
+ },
+ [0x1332C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332C,
+ },
+ [0x1332D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332D,
+ },
+ [0x1332E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332E,
+ },
+ [0x1332F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332F,
+ },
+ [0x13330]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13330,
+ },
+ [0x13331]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13331,
+ },
+ [0x13332]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13332,
+ },
+ [0x13333]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13333,
+ },
+ [0x13334]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13334,
+ },
+ [0x13335]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13335,
+ },
+ [0x13336]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13336,
+ },
+ [0x13337]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13337,
+ },
+ [0x13338]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13338,
+ },
+ [0x13339]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13339,
+ },
+ [0x1333A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333A,
+ },
+ [0x1333B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333B,
+ },
+ [0x1333C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333C,
+ },
+ [0x1333D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333D,
+ },
+ [0x1333E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333E,
+ },
+ [0x1333F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333F,
+ },
+ [0x13340]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13340,
+ },
+ [0x13341]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13341,
+ },
+ [0x13342]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13342,
+ },
+ [0x13343]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13343,
+ },
+ [0x13344]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13344,
+ },
+ [0x13345]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13345,
+ },
+ [0x13346]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13346,
+ },
+ [0x13347]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13347,
+ },
+ [0x13348]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13348,
+ },
+ [0x13349]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13349,
+ },
+ [0x1334A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334A,
+ },
+ [0x1334B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334B,
+ },
+ [0x1334C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334C,
+ },
+ [0x1334D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334D,
+ },
+ [0x1334E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334E,
+ },
+ [0x1334F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334F,
+ },
+ [0x13350]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13350,
+ },
+ [0x13351]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13351,
+ },
+ [0x13352]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13352,
+ },
+ [0x13353]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13353,
+ },
+ [0x13354]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13354,
+ },
+ [0x13355]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13355,
+ },
+ [0x13356]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13356,
+ },
+ [0x13357]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13357,
+ },
+ [0x13358]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13358,
+ },
+ [0x13359]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13359,
+ },
+ [0x1335A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335A,
+ },
+ [0x1335B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335B,
+ },
+ [0x1335C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335C,
+ },
+ [0x1335D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335D,
+ },
+ [0x1335E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335E,
+ },
+ [0x1335F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335F,
+ },
+ [0x13360]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13360,
+ },
+ [0x13361]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13361,
+ },
+ [0x13362]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13362,
+ },
+ [0x13363]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13363,
+ },
+ [0x13364]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13364,
+ },
+ [0x13365]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13365,
+ },
+ [0x13366]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13366,
+ },
+ [0x13367]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13367,
+ },
+ [0x13368]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13368,
+ },
+ [0x13369]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13369,
+ },
+ [0x1336A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336A,
+ },
+ [0x1336B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336B,
+ },
+ [0x1336C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336C,
+ },
+ [0x1336D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336D,
+ },
+ [0x1336E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336E,
+ },
+ [0x1336F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336F,
+ },
+ [0x13370]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13370,
+ },
+ [0x13371]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13371,
+ },
+ [0x13372]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13372,
+ },
+ [0x13373]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13373,
+ },
+ [0x13374]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13374,
+ },
+ [0x13375]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13375,
+ },
+ [0x13376]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13376,
+ },
+ [0x13377]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13377,
+ },
+ [0x13378]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13378,
+ },
+ [0x13379]={
+ category="lo",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x13379,
+ },
+ [0x1337A]={
+ category="lo",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x1337A,
+ },
+ [0x1337B]={
+ category="lo",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x1337B,
+ },
+ [0x1337C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1337C,
+ },
+ [0x1337D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1337D,
+ },
+ [0x1337E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1337E,
+ },
+ [0x1337F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1337F,
+ },
+ [0x13380]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13380,
+ },
+ [0x13381]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13381,
+ },
+ [0x13382]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13382,
+ },
+ [0x13383]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13383,
+ },
+ [0x13384]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13384,
+ },
+ [0x13385]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13385,
+ },
+ [0x13386]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13386,
+ },
+ [0x13387]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13387,
+ },
+ [0x13388]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13388,
+ },
+ [0x13389]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13389,
+ },
+ [0x1338A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338A,
+ },
+ [0x1338B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338B,
+ },
+ [0x1338C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338C,
+ },
+ [0x1338D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338D,
+ },
+ [0x1338E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338E,
+ },
+ [0x1338F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338F,
+ },
+ [0x13390]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13390,
+ },
+ [0x13391]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13391,
+ },
+ [0x13392]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13392,
+ },
+ [0x13393]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13393,
+ },
+ [0x13394]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13394,
+ },
+ [0x13395]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13395,
+ },
+ [0x13396]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13396,
+ },
+ [0x13397]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13397,
+ },
+ [0x13398]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13398,
+ },
+ [0x13399]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13399,
+ },
+ [0x1339A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339A,
+ },
+ [0x1339B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339B,
+ },
+ [0x1339C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339C,
+ },
+ [0x1339D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339D,
+ },
+ [0x1339E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339E,
+ },
+ [0x1339F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339F,
+ },
+ [0x133A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A0,
+ },
+ [0x133A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A1,
+ },
+ [0x133A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A2,
+ },
+ [0x133A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A3,
+ },
+ [0x133A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A4,
+ },
+ [0x133A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A5,
+ },
+ [0x133A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A6,
+ },
+ [0x133A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A7,
+ },
+ [0x133A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A8,
+ },
+ [0x133A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A9,
+ },
+ [0x133AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133AA,
+ },
+ [0x133AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133AB,
+ },
+ [0x133AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133AC,
+ },
+ [0x133AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133AD,
+ },
+ [0x133AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133AE,
+ },
+ [0x133AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133AF,
+ },
+ [0x133B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B0,
+ },
+ [0x133B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B1,
+ },
+ [0x133B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B2,
+ },
+ [0x133B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B3,
+ },
+ [0x133B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B4,
+ },
+ [0x133B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B5,
+ },
+ [0x133B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B6,
+ },
+ [0x133B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B7,
+ },
+ [0x133B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B8,
+ },
+ [0x133B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B9,
+ },
+ [0x133BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133BA,
+ },
+ [0x133BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133BB,
+ },
+ [0x133BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133BC,
+ },
+ [0x133BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133BD,
+ },
+ [0x133BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133BE,
+ },
+ [0x133BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133BF,
+ },
+ [0x133C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C0,
+ },
+ [0x133C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C1,
+ },
+ [0x133C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C2,
+ },
+ [0x133C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C3,
+ },
+ [0x133C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C4,
+ },
+ [0x133C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C5,
+ },
+ [0x133C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C6,
+ },
+ [0x133C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C7,
+ },
+ [0x133C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C8,
+ },
+ [0x133C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C9,
+ },
+ [0x133CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133CA,
+ },
+ [0x133CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133CB,
+ },
+ [0x133CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133CC,
+ },
+ [0x133CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133CD,
+ },
+ [0x133CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133CE,
+ },
+ [0x133CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133CF,
+ },
+ [0x133D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D0,
+ },
+ [0x133D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D1,
+ },
+ [0x133D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D2,
+ },
+ [0x133D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D3,
+ },
+ [0x133D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D4,
+ },
+ [0x133D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D5,
+ },
+ [0x133D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D6,
+ },
+ [0x133D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D7,
+ },
+ [0x133D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D8,
+ },
+ [0x133D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D9,
+ },
+ [0x133DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133DA,
+ },
+ [0x133DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133DB,
+ },
+ [0x133DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133DC,
+ },
+ [0x133DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133DD,
+ },
+ [0x133DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133DE,
+ },
+ [0x133DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133DF,
+ },
+ [0x133E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E0,
+ },
+ [0x133E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E1,
+ },
+ [0x133E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E2,
+ },
+ [0x133E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E3,
+ },
+ [0x133E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E4,
+ },
+ [0x133E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E5,
+ },
+ [0x133E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E6,
+ },
+ [0x133E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E7,
+ },
+ [0x133E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E8,
+ },
+ [0x133E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E9,
+ },
+ [0x133EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133EA,
+ },
+ [0x133EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133EB,
+ },
+ [0x133EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133EC,
+ },
+ [0x133ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133ED,
+ },
+ [0x133EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133EE,
+ },
+ [0x133EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133EF,
+ },
+ [0x133F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F0,
+ },
+ [0x133F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F1,
+ },
+ [0x133F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F2,
+ },
+ [0x133F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F3,
+ },
+ [0x133F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F4,
+ },
+ [0x133F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F5,
+ },
+ [0x133F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F6,
+ },
+ [0x133F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F7,
+ },
+ [0x133F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F8,
+ },
+ [0x133F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F9,
+ },
+ [0x133FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133FA,
+ },
+ [0x133FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133FB,
+ },
+ [0x133FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133FC,
+ },
+ [0x133FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133FD,
+ },
+ [0x133FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133FE,
+ },
+ [0x133FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133FF,
+ },
+ [0x13400]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13400,
+ },
+ [0x13401]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13401,
+ },
+ [0x13402]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13402,
+ },
+ [0x13403]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13403,
+ },
+ [0x13404]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13404,
+ },
+ [0x13405]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13405,
+ },
+ [0x13406]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13406,
+ },
+ [0x13407]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13407,
+ },
+ [0x13408]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13408,
+ },
+ [0x13409]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13409,
+ },
+ [0x1340A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340A,
+ },
+ [0x1340B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340B,
+ },
+ [0x1340C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340C,
+ },
+ [0x1340D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340D,
+ },
+ [0x1340E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340E,
+ },
+ [0x1340F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340F,
+ },
+ [0x13410]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13410,
+ },
+ [0x13411]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13411,
+ },
+ [0x13412]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13412,
+ },
+ [0x13413]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13413,
+ },
+ [0x13414]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13414,
+ },
+ [0x13415]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13415,
+ },
+ [0x13416]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13416,
+ },
+ [0x13417]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13417,
+ },
+ [0x13418]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13418,
+ },
+ [0x13419]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13419,
+ },
+ [0x1341A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341A,
+ },
+ [0x1341B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341B,
+ },
+ [0x1341C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341C,
+ },
+ [0x1341D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341D,
+ },
+ [0x1341E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341E,
+ },
+ [0x1341F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341F,
+ },
+ [0x13420]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13420,
+ },
+ [0x13421]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13421,
+ },
+ [0x13422]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13422,
+ },
+ [0x13423]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13423,
+ },
+ [0x13424]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13424,
+ },
+ [0x13425]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13425,
+ },
+ [0x13426]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13426,
+ },
+ [0x13427]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13427,
+ },
+ [0x13428]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13428,
+ },
+ [0x13429]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13429,
+ },
+ [0x1342A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1342A,
+ },
+ [0x1342B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1342B,
+ },
+ [0x1342C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1342C,
+ },
+ [0x1342D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1342D,
+ },
+ [0x1342E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1342E,
+ },
+ [0x13430]={
+ category="cf",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0x13430,
+ },
+ [0x13431]={
+ category="cf",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0x13431,
+ },
+ [0x13432]={
+ category="cf",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0x13432,
+ },
+ [0x13433]={
+ category="cf",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0x13433,
+ },
+ [0x13434]={
+ category="cf",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0x13434,
+ },
+ [0x13435]={
+ category="cf",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0x13435,
+ },
+ [0x13436]={
+ category="cf",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0x13436,
+ },
+ [0x13437]={
+ category="cf",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x13437,
+ },
+ [0x13438]={
+ category="cf",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x13438,
+ },
+ [0x14400]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14400,
+ },
+ [0x14401]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14401,
+ },
+ [0x14402]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14402,
+ },
+ [0x14403]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14403,
+ },
+ [0x14404]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14404,
+ },
+ [0x14405]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14405,
+ },
+ [0x14406]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14406,
+ },
+ [0x14407]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14407,
+ },
+ [0x14408]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14408,
+ },
+ [0x14409]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14409,
+ },
+ [0x1440A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1440A,
+ },
+ [0x1440B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1440B,
+ },
+ [0x1440C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1440C,
+ },
+ [0x1440D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1440D,
+ },
+ [0x1440E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1440E,
+ },
+ [0x1440F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1440F,
+ },
+ [0x14410]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14410,
+ },
+ [0x14411]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14411,
+ },
+ [0x14412]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14412,
+ },
+ [0x14413]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14413,
+ },
+ [0x14414]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14414,
+ },
+ [0x14415]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14415,
+ },
+ [0x14416]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14416,
+ },
+ [0x14417]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14417,
+ },
+ [0x14418]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14418,
+ },
+ [0x14419]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14419,
+ },
+ [0x1441A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1441A,
+ },
+ [0x1441B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1441B,
+ },
+ [0x1441C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1441C,
+ },
+ [0x1441D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1441D,
+ },
+ [0x1441E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1441E,
+ },
+ [0x1441F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1441F,
+ },
+ [0x14420]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14420,
+ },
+ [0x14421]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14421,
+ },
+ [0x14422]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14422,
+ },
+ [0x14423]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14423,
+ },
+ [0x14424]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14424,
+ },
+ [0x14425]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14425,
+ },
+ [0x14426]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14426,
+ },
+ [0x14427]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14427,
+ },
+ [0x14428]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14428,
+ },
+ [0x14429]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14429,
+ },
+ [0x1442A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1442A,
+ },
+ [0x1442B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1442B,
+ },
+ [0x1442C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1442C,
+ },
+ [0x1442D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1442D,
+ },
+ [0x1442E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1442E,
+ },
+ [0x1442F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1442F,
+ },
+ [0x14430]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14430,
+ },
+ [0x14431]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14431,
+ },
+ [0x14432]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14432,
+ },
+ [0x14433]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14433,
+ },
+ [0x14434]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14434,
+ },
+ [0x14435]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14435,
+ },
+ [0x14436]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14436,
+ },
+ [0x14437]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14437,
+ },
+ [0x14438]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14438,
+ },
+ [0x14439]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14439,
+ },
+ [0x1443A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1443A,
+ },
+ [0x1443B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1443B,
+ },
+ [0x1443C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1443C,
+ },
+ [0x1443D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1443D,
+ },
+ [0x1443E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1443E,
+ },
+ [0x1443F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1443F,
+ },
+ [0x14440]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14440,
+ },
+ [0x14441]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14441,
+ },
+ [0x14442]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14442,
+ },
+ [0x14443]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14443,
+ },
+ [0x14444]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14444,
+ },
+ [0x14445]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14445,
+ },
+ [0x14446]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14446,
+ },
+ [0x14447]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14447,
+ },
+ [0x14448]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14448,
+ },
+ [0x14449]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14449,
+ },
+ [0x1444A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1444A,
+ },
+ [0x1444B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1444B,
+ },
+ [0x1444C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1444C,
+ },
+ [0x1444D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1444D,
+ },
+ [0x1444E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1444E,
+ },
+ [0x1444F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1444F,
+ },
+ [0x14450]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14450,
+ },
+ [0x14451]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14451,
+ },
+ [0x14452]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14452,
+ },
+ [0x14453]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14453,
+ },
+ [0x14454]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14454,
+ },
+ [0x14455]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14455,
+ },
+ [0x14456]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14456,
+ },
+ [0x14457]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14457,
+ },
+ [0x14458]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14458,
+ },
+ [0x14459]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14459,
+ },
+ [0x1445A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1445A,
+ },
+ [0x1445B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1445B,
+ },
+ [0x1445C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1445C,
+ },
+ [0x1445D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1445D,
+ },
+ [0x1445E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1445E,
+ },
+ [0x1445F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1445F,
+ },
+ [0x14460]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14460,
+ },
+ [0x14461]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14461,
+ },
+ [0x14462]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14462,
+ },
+ [0x14463]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14463,
+ },
+ [0x14464]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14464,
+ },
+ [0x14465]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14465,
+ },
+ [0x14466]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14466,
+ },
+ [0x14467]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14467,
+ },
+ [0x14468]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14468,
+ },
+ [0x14469]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14469,
+ },
+ [0x1446A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1446A,
+ },
+ [0x1446B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1446B,
+ },
+ [0x1446C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1446C,
+ },
+ [0x1446D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1446D,
+ },
+ [0x1446E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1446E,
+ },
+ [0x1446F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1446F,
+ },
+ [0x14470]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14470,
+ },
+ [0x14471]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14471,
+ },
+ [0x14472]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14472,
+ },
+ [0x14473]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14473,
+ },
+ [0x14474]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14474,
+ },
+ [0x14475]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14475,
+ },
+ [0x14476]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14476,
+ },
+ [0x14477]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14477,
+ },
+ [0x14478]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14478,
+ },
+ [0x14479]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14479,
+ },
+ [0x1447A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1447A,
+ },
+ [0x1447B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1447B,
+ },
+ [0x1447C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1447C,
+ },
+ [0x1447D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1447D,
+ },
+ [0x1447E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1447E,
+ },
+ [0x1447F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1447F,
+ },
+ [0x14480]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14480,
+ },
+ [0x14481]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14481,
+ },
+ [0x14482]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14482,
+ },
+ [0x14483]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14483,
+ },
+ [0x14484]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14484,
+ },
+ [0x14485]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14485,
+ },
+ [0x14486]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14486,
+ },
+ [0x14487]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14487,
+ },
+ [0x14488]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14488,
+ },
+ [0x14489]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14489,
+ },
+ [0x1448A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1448A,
+ },
+ [0x1448B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1448B,
+ },
+ [0x1448C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1448C,
+ },
+ [0x1448D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1448D,
+ },
+ [0x1448E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1448E,
+ },
+ [0x1448F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1448F,
+ },
+ [0x14490]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14490,
+ },
+ [0x14491]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14491,
+ },
+ [0x14492]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14492,
+ },
+ [0x14493]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14493,
+ },
+ [0x14494]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14494,
+ },
+ [0x14495]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14495,
+ },
+ [0x14496]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14496,
+ },
+ [0x14497]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14497,
+ },
+ [0x14498]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14498,
+ },
+ [0x14499]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14499,
+ },
+ [0x1449A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1449A,
+ },
+ [0x1449B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1449B,
+ },
+ [0x1449C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1449C,
+ },
+ [0x1449D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1449D,
+ },
+ [0x1449E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1449E,
+ },
+ [0x1449F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1449F,
+ },
+ [0x144A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144A0,
+ },
+ [0x144A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144A1,
+ },
+ [0x144A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144A2,
+ },
+ [0x144A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144A3,
+ },
+ [0x144A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144A4,
+ },
+ [0x144A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144A5,
+ },
+ [0x144A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144A6,
+ },
+ [0x144A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144A7,
+ },
+ [0x144A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144A8,
+ },
+ [0x144A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144A9,
+ },
+ [0x144AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144AA,
+ },
+ [0x144AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144AB,
+ },
+ [0x144AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144AC,
+ },
+ [0x144AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144AD,
+ },
+ [0x144AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144AE,
+ },
+ [0x144AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144AF,
+ },
+ [0x144B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144B0,
+ },
+ [0x144B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144B1,
+ },
+ [0x144B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144B2,
+ },
+ [0x144B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144B3,
+ },
+ [0x144B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144B4,
+ },
+ [0x144B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144B5,
+ },
+ [0x144B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144B6,
+ },
+ [0x144B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144B7,
+ },
+ [0x144B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144B8,
+ },
+ [0x144B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144B9,
+ },
+ [0x144BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144BA,
+ },
+ [0x144BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144BB,
+ },
+ [0x144BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144BC,
+ },
+ [0x144BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144BD,
+ },
+ [0x144BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144BE,
+ },
+ [0x144BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144BF,
+ },
+ [0x144C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144C0,
+ },
+ [0x144C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144C1,
+ },
+ [0x144C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144C2,
+ },
+ [0x144C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144C3,
+ },
+ [0x144C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144C4,
+ },
+ [0x144C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144C5,
+ },
+ [0x144C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144C6,
+ },
+ [0x144C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144C7,
+ },
+ [0x144C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144C8,
+ },
+ [0x144C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144C9,
+ },
+ [0x144CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144CA,
+ },
+ [0x144CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144CB,
+ },
+ [0x144CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144CC,
+ },
+ [0x144CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144CD,
+ },
+ [0x144CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144CE,
+ },
+ [0x144CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144CF,
+ },
+ [0x144D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144D0,
+ },
+ [0x144D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144D1,
+ },
+ [0x144D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144D2,
+ },
+ [0x144D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144D3,
+ },
+ [0x144D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144D4,
+ },
+ [0x144D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144D5,
+ },
+ [0x144D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144D6,
+ },
+ [0x144D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144D7,
+ },
+ [0x144D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144D8,
+ },
+ [0x144D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144D9,
+ },
+ [0x144DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144DA,
+ },
+ [0x144DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144DB,
+ },
+ [0x144DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144DC,
+ },
+ [0x144DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144DD,
+ },
+ [0x144DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144DE,
+ },
+ [0x144DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144DF,
+ },
+ [0x144E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144E0,
+ },
+ [0x144E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144E1,
+ },
+ [0x144E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144E2,
+ },
+ [0x144E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144E3,
+ },
+ [0x144E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144E4,
+ },
+ [0x144E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144E5,
+ },
+ [0x144E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144E6,
+ },
+ [0x144E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144E7,
+ },
+ [0x144E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144E8,
+ },
+ [0x144E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144E9,
+ },
+ [0x144EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144EA,
+ },
+ [0x144EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144EB,
+ },
+ [0x144EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144EC,
+ },
+ [0x144ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144ED,
+ },
+ [0x144EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144EE,
+ },
+ [0x144EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144EF,
+ },
+ [0x144F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144F0,
+ },
+ [0x144F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144F1,
+ },
+ [0x144F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144F2,
+ },
+ [0x144F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144F3,
+ },
+ [0x144F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144F4,
+ },
+ [0x144F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144F5,
+ },
+ [0x144F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144F6,
+ },
+ [0x144F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144F7,
+ },
+ [0x144F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144F8,
+ },
+ [0x144F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144F9,
+ },
+ [0x144FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144FA,
+ },
+ [0x144FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144FB,
+ },
+ [0x144FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144FC,
+ },
+ [0x144FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144FD,
+ },
+ [0x144FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144FE,
+ },
+ [0x144FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144FF,
+ },
+ [0x14500]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14500,
+ },
+ [0x14501]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14501,
+ },
+ [0x14502]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14502,
+ },
+ [0x14503]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14503,
+ },
+ [0x14504]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14504,
+ },
+ [0x14505]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14505,
+ },
+ [0x14506]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14506,
+ },
+ [0x14507]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14507,
+ },
+ [0x14508]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14508,
+ },
+ [0x14509]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14509,
+ },
+ [0x1450A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1450A,
+ },
+ [0x1450B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1450B,
+ },
+ [0x1450C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1450C,
+ },
+ [0x1450D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1450D,
+ },
+ [0x1450E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1450E,
+ },
+ [0x1450F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1450F,
+ },
+ [0x14510]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14510,
+ },
+ [0x14511]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14511,
+ },
+ [0x14512]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14512,
+ },
+ [0x14513]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14513,
+ },
+ [0x14514]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14514,
+ },
+ [0x14515]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14515,
+ },
+ [0x14516]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14516,
+ },
+ [0x14517]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14517,
+ },
+ [0x14518]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14518,
+ },
+ [0x14519]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14519,
+ },
+ [0x1451A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1451A,
+ },
+ [0x1451B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1451B,
+ },
+ [0x1451C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1451C,
+ },
+ [0x1451D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1451D,
+ },
+ [0x1451E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1451E,
+ },
+ [0x1451F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1451F,
+ },
+ [0x14520]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14520,
+ },
+ [0x14521]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14521,
+ },
+ [0x14522]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14522,
+ },
+ [0x14523]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14523,
+ },
+ [0x14524]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14524,
+ },
+ [0x14525]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14525,
+ },
+ [0x14526]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14526,
+ },
+ [0x14527]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14527,
+ },
+ [0x14528]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14528,
+ },
+ [0x14529]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14529,
+ },
+ [0x1452A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1452A,
+ },
+ [0x1452B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1452B,
+ },
+ [0x1452C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1452C,
+ },
+ [0x1452D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1452D,
+ },
+ [0x1452E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1452E,
+ },
+ [0x1452F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1452F,
+ },
+ [0x14530]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14530,
+ },
+ [0x14531]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14531,
+ },
+ [0x14532]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14532,
+ },
+ [0x14533]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14533,
+ },
+ [0x14534]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14534,
+ },
+ [0x14535]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14535,
+ },
+ [0x14536]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14536,
+ },
+ [0x14537]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14537,
+ },
+ [0x14538]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14538,
+ },
+ [0x14539]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14539,
+ },
+ [0x1453A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1453A,
+ },
+ [0x1453B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1453B,
+ },
+ [0x1453C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1453C,
+ },
+ [0x1453D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1453D,
+ },
+ [0x1453E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1453E,
+ },
+ [0x1453F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1453F,
+ },
+ [0x14540]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14540,
+ },
+ [0x14541]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14541,
+ },
+ [0x14542]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14542,
+ },
+ [0x14543]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14543,
+ },
+ [0x14544]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14544,
+ },
+ [0x14545]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14545,
+ },
+ [0x14546]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14546,
+ },
+ [0x14547]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14547,
+ },
+ [0x14548]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14548,
+ },
+ [0x14549]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14549,
+ },
+ [0x1454A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1454A,
+ },
+ [0x1454B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1454B,
+ },
+ [0x1454C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1454C,
+ },
+ [0x1454D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1454D,
+ },
+ [0x1454E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1454E,
+ },
+ [0x1454F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1454F,
+ },
+ [0x14550]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14550,
+ },
+ [0x14551]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14551,
+ },
+ [0x14552]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14552,
+ },
+ [0x14553]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14553,
+ },
+ [0x14554]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14554,
+ },
+ [0x14555]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14555,
+ },
+ [0x14556]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14556,
+ },
+ [0x14557]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14557,
+ },
+ [0x14558]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14558,
+ },
+ [0x14559]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14559,
+ },
+ [0x1455A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1455A,
+ },
+ [0x1455B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1455B,
+ },
+ [0x1455C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1455C,
+ },
+ [0x1455D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1455D,
+ },
+ [0x1455E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1455E,
+ },
+ [0x1455F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1455F,
+ },
+ [0x14560]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14560,
+ },
+ [0x14561]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14561,
+ },
+ [0x14562]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14562,
+ },
+ [0x14563]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14563,
+ },
+ [0x14564]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14564,
+ },
+ [0x14565]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14565,
+ },
+ [0x14566]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14566,
+ },
+ [0x14567]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14567,
+ },
+ [0x14568]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14568,
+ },
+ [0x14569]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14569,
+ },
+ [0x1456A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1456A,
+ },
+ [0x1456B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1456B,
+ },
+ [0x1456C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1456C,
+ },
+ [0x1456D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1456D,
+ },
+ [0x1456E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1456E,
+ },
+ [0x1456F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1456F,
+ },
+ [0x14570]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14570,
+ },
+ [0x14571]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14571,
+ },
+ [0x14572]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14572,
+ },
+ [0x14573]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14573,
+ },
+ [0x14574]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14574,
+ },
+ [0x14575]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14575,
+ },
+ [0x14576]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14576,
+ },
+ [0x14577]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14577,
+ },
+ [0x14578]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14578,
+ },
+ [0x14579]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14579,
+ },
+ [0x1457A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1457A,
+ },
+ [0x1457B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1457B,
+ },
+ [0x1457C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1457C,
+ },
+ [0x1457D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1457D,
+ },
+ [0x1457E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1457E,
+ },
+ [0x1457F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1457F,
+ },
+ [0x14580]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14580,
+ },
+ [0x14581]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14581,
+ },
+ [0x14582]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14582,
+ },
+ [0x14583]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14583,
+ },
+ [0x14584]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14584,
+ },
+ [0x14585]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14585,
+ },
+ [0x14586]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14586,
+ },
+ [0x14587]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14587,
+ },
+ [0x14588]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14588,
+ },
+ [0x14589]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14589,
+ },
+ [0x1458A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1458A,
+ },
+ [0x1458B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1458B,
+ },
+ [0x1458C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1458C,
+ },
+ [0x1458D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1458D,
+ },
+ [0x1458E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1458E,
+ },
+ [0x1458F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1458F,
+ },
+ [0x14590]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14590,
+ },
+ [0x14591]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14591,
+ },
+ [0x14592]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14592,
+ },
+ [0x14593]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14593,
+ },
+ [0x14594]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14594,
+ },
+ [0x14595]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14595,
+ },
+ [0x14596]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14596,
+ },
+ [0x14597]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14597,
+ },
+ [0x14598]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14598,
+ },
+ [0x14599]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14599,
+ },
+ [0x1459A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1459A,
+ },
+ [0x1459B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1459B,
+ },
+ [0x1459C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1459C,
+ },
+ [0x1459D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1459D,
+ },
+ [0x1459E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1459E,
+ },
+ [0x1459F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1459F,
+ },
+ [0x145A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145A0,
+ },
+ [0x145A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145A1,
+ },
+ [0x145A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145A2,
+ },
+ [0x145A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145A3,
+ },
+ [0x145A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145A4,
+ },
+ [0x145A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145A5,
+ },
+ [0x145A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145A6,
+ },
+ [0x145A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145A7,
+ },
+ [0x145A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145A8,
+ },
+ [0x145A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145A9,
+ },
+ [0x145AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145AA,
+ },
+ [0x145AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145AB,
+ },
+ [0x145AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145AC,
+ },
+ [0x145AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145AD,
+ },
+ [0x145AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145AE,
+ },
+ [0x145AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145AF,
+ },
+ [0x145B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145B0,
+ },
+ [0x145B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145B1,
+ },
+ [0x145B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145B2,
+ },
+ [0x145B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145B3,
+ },
+ [0x145B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145B4,
+ },
+ [0x145B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145B5,
+ },
+ [0x145B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145B6,
+ },
+ [0x145B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145B7,
+ },
+ [0x145B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145B8,
+ },
+ [0x145B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145B9,
+ },
+ [0x145BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145BA,
+ },
+ [0x145BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145BB,
+ },
+ [0x145BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145BC,
+ },
+ [0x145BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145BD,
+ },
+ [0x145BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145BE,
+ },
+ [0x145BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145BF,
+ },
+ [0x145C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145C0,
+ },
+ [0x145C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145C1,
+ },
+ [0x145C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145C2,
+ },
+ [0x145C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145C3,
+ },
+ [0x145C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145C4,
+ },
+ [0x145C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145C5,
+ },
+ [0x145C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145C6,
+ },
+ [0x145C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145C7,
+ },
+ [0x145C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145C8,
+ },
+ [0x145C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145C9,
+ },
+ [0x145CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145CA,
+ },
+ [0x145CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145CB,
+ },
+ [0x145CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145CC,
+ },
+ [0x145CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145CD,
+ },
+ [0x145CE]={
+ category="lo",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x145CE,
+ },
+ [0x145CF]={
+ category="lo",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x145CF,
+ },
+ [0x145D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145D0,
+ },
+ [0x145D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145D1,
+ },
+ [0x145D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145D2,
+ },
+ [0x145D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145D3,
+ },
+ [0x145D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145D4,
+ },
+ [0x145D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145D5,
+ },
+ [0x145D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145D6,
+ },
+ [0x145D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145D7,
+ },
+ [0x145D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145D8,
+ },
+ [0x145D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145D9,
+ },
+ [0x145DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145DA,
+ },
+ [0x145DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145DB,
+ },
+ [0x145DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145DC,
+ },
+ [0x145DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145DD,
+ },
+ [0x145DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145DE,
+ },
+ [0x145DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145DF,
+ },
+ [0x145E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145E0,
+ },
+ [0x145E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145E1,
+ },
+ [0x145E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145E2,
+ },
+ [0x145E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145E3,
+ },
+ [0x145E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145E4,
+ },
+ [0x145E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145E5,
+ },
+ [0x145E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145E6,
+ },
+ [0x145E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145E7,
+ },
+ [0x145E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145E8,
+ },
+ [0x145E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145E9,
+ },
+ [0x145EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145EA,
+ },
+ [0x145EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145EB,
+ },
+ [0x145EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145EC,
+ },
+ [0x145ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145ED,
+ },
+ [0x145EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145EE,
+ },
+ [0x145EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145EF,
+ },
+ [0x145F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145F0,
+ },
+ [0x145F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145F1,
+ },
+ [0x145F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145F2,
+ },
+ [0x145F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145F3,
+ },
+ [0x145F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145F4,
+ },
+ [0x145F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145F5,
+ },
+ [0x145F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145F6,
+ },
+ [0x145F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145F7,
+ },
+ [0x145F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145F8,
+ },
+ [0x145F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145F9,
+ },
+ [0x145FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145FA,
+ },
+ [0x145FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145FB,
+ },
+ [0x145FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145FC,
+ },
+ [0x145FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145FD,
+ },
+ [0x145FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145FE,
+ },
+ [0x145FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145FF,
+ },
+ [0x14600]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14600,
+ },
+ [0x14601]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14601,
+ },
+ [0x14602]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14602,
+ },
+ [0x14603]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14603,
+ },
+ [0x14604]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14604,
+ },
+ [0x14605]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14605,
+ },
+ [0x14606]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14606,
+ },
+ [0x14607]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14607,
+ },
+ [0x14608]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14608,
+ },
+ [0x14609]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14609,
+ },
+ [0x1460A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1460A,
+ },
+ [0x1460B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1460B,
+ },
+ [0x1460C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1460C,
+ },
+ [0x1460D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1460D,
+ },
+ [0x1460E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1460E,
+ },
+ [0x1460F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1460F,
+ },
+ [0x14610]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14610,
+ },
+ [0x14611]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14611,
+ },
+ [0x14612]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14612,
+ },
+ [0x14613]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14613,
+ },
+ [0x14614]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14614,
+ },
+ [0x14615]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14615,
+ },
+ [0x14616]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14616,
+ },
+ [0x14617]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14617,
+ },
+ [0x14618]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14618,
+ },
+ [0x14619]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14619,
+ },
+ [0x1461A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1461A,
+ },
+ [0x1461B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1461B,
+ },
+ [0x1461C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1461C,
+ },
+ [0x1461D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1461D,
+ },
+ [0x1461E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1461E,
+ },
+ [0x1461F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1461F,
+ },
+ [0x14620]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14620,
+ },
+ [0x14621]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14621,
+ },
+ [0x14622]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14622,
+ },
+ [0x14623]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14623,
+ },
+ [0x14624]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14624,
+ },
+ [0x14625]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14625,
+ },
+ [0x14626]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14626,
+ },
+ [0x14627]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14627,
+ },
+ [0x14628]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14628,
+ },
+ [0x14629]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14629,
+ },
+ [0x1462A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1462A,
+ },
+ [0x1462B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1462B,
+ },
+ [0x1462C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1462C,
+ },
+ [0x1462D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1462D,
+ },
+ [0x1462E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1462E,
+ },
+ [0x1462F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1462F,
+ },
+ [0x14630]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14630,
+ },
+ [0x14631]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14631,
+ },
+ [0x14632]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14632,
+ },
+ [0x14633]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14633,
+ },
+ [0x14634]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14634,
+ },
+ [0x14635]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14635,
+ },
+ [0x14636]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14636,
+ },
+ [0x14637]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14637,
+ },
+ [0x14638]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14638,
+ },
+ [0x14639]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14639,
+ },
+ [0x1463A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1463A,
+ },
+ [0x1463B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1463B,
+ },
+ [0x1463C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1463C,
+ },
+ [0x1463D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1463D,
+ },
+ [0x1463E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1463E,
+ },
+ [0x1463F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1463F,
+ },
+ [0x14640]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14640,
+ },
+ [0x14641]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14641,
+ },
+ [0x14642]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14642,
+ },
+ [0x14643]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14643,
+ },
+ [0x14644]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14644,
+ },
+ [0x14645]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14645,
+ },
+ [0x14646]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14646,
+ },
+ [0x16800]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16800,
+ },
+ [0x16801]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16801,
+ },
+ [0x16802]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16802,
+ },
+ [0x16803]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16803,
+ },
+ [0x16804]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16804,
+ },
+ [0x16805]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16805,
+ },
+ [0x16806]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16806,
+ },
+ [0x16807]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16807,
+ },
+ [0x16808]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16808,
+ },
+ [0x16809]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16809,
+ },
+ [0x1680A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1680A,
+ },
+ [0x1680B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1680B,
+ },
+ [0x1680C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1680C,
+ },
+ [0x1680D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1680D,
+ },
+ [0x1680E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1680E,
+ },
+ [0x1680F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1680F,
+ },
+ [0x16810]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16810,
+ },
+ [0x16811]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16811,
+ },
+ [0x16812]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16812,
+ },
+ [0x16813]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16813,
+ },
+ [0x16814]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16814,
+ },
+ [0x16815]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16815,
+ },
+ [0x16816]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16816,
+ },
+ [0x16817]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16817,
+ },
+ [0x16818]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16818,
+ },
+ [0x16819]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16819,
+ },
+ [0x1681A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681A,
+ },
+ [0x1681B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681B,
+ },
+ [0x1681C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681C,
+ },
+ [0x1681D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681D,
+ },
+ [0x1681E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681E,
+ },
+ [0x1681F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681F,
+ },
+ [0x16820]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16820,
+ },
+ [0x16821]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16821,
+ },
+ [0x16822]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16822,
+ },
+ [0x16823]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16823,
+ },
+ [0x16824]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16824,
+ },
+ [0x16825]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16825,
+ },
+ [0x16826]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16826,
+ },
+ [0x16827]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16827,
+ },
+ [0x16828]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16828,
+ },
+ [0x16829]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16829,
+ },
+ [0x1682A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682A,
+ },
+ [0x1682B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682B,
+ },
+ [0x1682C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682C,
+ },
+ [0x1682D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682D,
+ },
+ [0x1682E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682E,
+ },
+ [0x1682F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682F,
+ },
+ [0x16830]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16830,
+ },
+ [0x16831]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16831,
+ },
+ [0x16832]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16832,
+ },
+ [0x16833]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16833,
+ },
+ [0x16834]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16834,
+ },
+ [0x16835]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16835,
+ },
+ [0x16836]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16836,
+ },
+ [0x16837]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16837,
+ },
+ [0x16838]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16838,
+ },
+ [0x16839]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16839,
+ },
+ [0x1683A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683A,
+ },
+ [0x1683B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683B,
+ },
+ [0x1683C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683C,
+ },
+ [0x1683D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683D,
+ },
+ [0x1683E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683E,
+ },
+ [0x1683F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683F,
+ },
+ [0x16840]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16840,
+ },
+ [0x16841]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16841,
+ },
+ [0x16842]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16842,
+ },
+ [0x16843]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16843,
+ },
+ [0x16844]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16844,
+ },
+ [0x16845]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16845,
+ },
+ [0x16846]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16846,
+ },
+ [0x16847]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16847,
+ },
+ [0x16848]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16848,
+ },
+ [0x16849]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16849,
+ },
+ [0x1684A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684A,
+ },
+ [0x1684B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684B,
+ },
+ [0x1684C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684C,
+ },
+ [0x1684D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684D,
+ },
+ [0x1684E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684E,
+ },
+ [0x1684F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684F,
+ },
+ [0x16850]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16850,
+ },
+ [0x16851]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16851,
+ },
+ [0x16852]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16852,
+ },
+ [0x16853]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16853,
+ },
+ [0x16854]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16854,
+ },
+ [0x16855]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16855,
+ },
+ [0x16856]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16856,
+ },
+ [0x16857]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16857,
+ },
+ [0x16858]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16858,
+ },
+ [0x16859]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16859,
+ },
+ [0x1685A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685A,
+ },
+ [0x1685B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685B,
+ },
+ [0x1685C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685C,
+ },
+ [0x1685D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685D,
+ },
+ [0x1685E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685E,
+ },
+ [0x1685F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685F,
+ },
+ [0x16860]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16860,
+ },
+ [0x16861]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16861,
+ },
+ [0x16862]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16862,
+ },
+ [0x16863]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16863,
+ },
+ [0x16864]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16864,
+ },
+ [0x16865]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16865,
+ },
+ [0x16866]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16866,
+ },
+ [0x16867]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16867,
+ },
+ [0x16868]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16868,
+ },
+ [0x16869]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16869,
+ },
+ [0x1686A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686A,
+ },
+ [0x1686B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686B,
+ },
+ [0x1686C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686C,
+ },
+ [0x1686D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686D,
+ },
+ [0x1686E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686E,
+ },
+ [0x1686F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686F,
+ },
+ [0x16870]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16870,
+ },
+ [0x16871]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16871,
+ },
+ [0x16872]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16872,
+ },
+ [0x16873]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16873,
+ },
+ [0x16874]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16874,
+ },
+ [0x16875]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16875,
+ },
+ [0x16876]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16876,
+ },
+ [0x16877]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16877,
+ },
+ [0x16878]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16878,
+ },
+ [0x16879]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16879,
+ },
+ [0x1687A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687A,
+ },
+ [0x1687B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687B,
+ },
+ [0x1687C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687C,
+ },
+ [0x1687D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687D,
+ },
+ [0x1687E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687E,
+ },
+ [0x1687F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687F,
+ },
+ [0x16880]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16880,
+ },
+ [0x16881]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16881,
+ },
+ [0x16882]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16882,
+ },
+ [0x16883]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16883,
+ },
+ [0x16884]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16884,
+ },
+ [0x16885]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16885,
+ },
+ [0x16886]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16886,
+ },
+ [0x16887]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16887,
+ },
+ [0x16888]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16888,
+ },
+ [0x16889]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16889,
+ },
+ [0x1688A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688A,
+ },
+ [0x1688B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688B,
+ },
+ [0x1688C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688C,
+ },
+ [0x1688D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688D,
+ },
+ [0x1688E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688E,
+ },
+ [0x1688F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688F,
+ },
+ [0x16890]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16890,
+ },
+ [0x16891]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16891,
+ },
+ [0x16892]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16892,
+ },
+ [0x16893]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16893,
+ },
+ [0x16894]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16894,
+ },
+ [0x16895]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16895,
+ },
+ [0x16896]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16896,
+ },
+ [0x16897]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16897,
+ },
+ [0x16898]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16898,
+ },
+ [0x16899]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16899,
+ },
+ [0x1689A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689A,
+ },
+ [0x1689B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689B,
+ },
+ [0x1689C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689C,
+ },
+ [0x1689D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689D,
+ },
+ [0x1689E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689E,
+ },
+ [0x1689F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689F,
+ },
+ [0x168A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A0,
+ },
+ [0x168A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A1,
+ },
+ [0x168A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A2,
+ },
+ [0x168A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A3,
+ },
+ [0x168A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A4,
+ },
+ [0x168A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A5,
+ },
+ [0x168A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A6,
+ },
+ [0x168A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A7,
+ },
+ [0x168A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A8,
+ },
+ [0x168A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A9,
+ },
+ [0x168AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168AA,
+ },
+ [0x168AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168AB,
+ },
+ [0x168AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168AC,
+ },
+ [0x168AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168AD,
+ },
+ [0x168AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168AE,
+ },
+ [0x168AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168AF,
+ },
+ [0x168B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B0,
+ },
+ [0x168B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B1,
+ },
+ [0x168B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B2,
+ },
+ [0x168B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B3,
+ },
+ [0x168B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B4,
+ },
+ [0x168B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B5,
+ },
+ [0x168B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B6,
+ },
+ [0x168B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B7,
+ },
+ [0x168B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B8,
+ },
+ [0x168B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B9,
+ },
+ [0x168BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168BA,
+ },
+ [0x168BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168BB,
+ },
+ [0x168BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168BC,
+ },
+ [0x168BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168BD,
+ },
+ [0x168BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168BE,
+ },
+ [0x168BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168BF,
+ },
+ [0x168C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C0,
+ },
+ [0x168C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C1,
+ },
+ [0x168C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C2,
+ },
+ [0x168C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C3,
+ },
+ [0x168C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C4,
+ },
+ [0x168C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C5,
+ },
+ [0x168C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C6,
+ },
+ [0x168C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C7,
+ },
+ [0x168C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C8,
+ },
+ [0x168C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C9,
+ },
+ [0x168CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168CA,
+ },
+ [0x168CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168CB,
+ },
+ [0x168CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168CC,
+ },
+ [0x168CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168CD,
+ },
+ [0x168CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168CE,
+ },
+ [0x168CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168CF,
+ },
+ [0x168D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D0,
+ },
+ [0x168D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D1,
+ },
+ [0x168D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D2,
+ },
+ [0x168D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D3,
+ },
+ [0x168D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D4,
+ },
+ [0x168D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D5,
+ },
+ [0x168D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D6,
+ },
+ [0x168D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D7,
+ },
+ [0x168D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D8,
+ },
+ [0x168D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D9,
+ },
+ [0x168DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168DA,
+ },
+ [0x168DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168DB,
+ },
+ [0x168DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168DC,
+ },
+ [0x168DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168DD,
+ },
+ [0x168DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168DE,
+ },
+ [0x168DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168DF,
+ },
+ [0x168E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E0,
+ },
+ [0x168E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E1,
+ },
+ [0x168E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E2,
+ },
+ [0x168E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E3,
+ },
+ [0x168E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E4,
+ },
+ [0x168E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E5,
+ },
+ [0x168E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E6,
+ },
+ [0x168E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E7,
+ },
+ [0x168E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E8,
+ },
+ [0x168E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E9,
+ },
+ [0x168EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168EA,
+ },
+ [0x168EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168EB,
+ },
+ [0x168EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168EC,
+ },
+ [0x168ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168ED,
+ },
+ [0x168EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168EE,
+ },
+ [0x168EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168EF,
+ },
+ [0x168F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F0,
+ },
+ [0x168F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F1,
+ },
+ [0x168F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F2,
+ },
+ [0x168F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F3,
+ },
+ [0x168F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F4,
+ },
+ [0x168F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F5,
+ },
+ [0x168F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F6,
+ },
+ [0x168F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F7,
+ },
+ [0x168F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F8,
+ },
+ [0x168F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F9,
+ },
+ [0x168FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168FA,
+ },
+ [0x168FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168FB,
+ },
+ [0x168FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168FC,
+ },
+ [0x168FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168FD,
+ },
+ [0x168FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168FE,
+ },
+ [0x168FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168FF,
+ },
+ [0x16900]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16900,
+ },
+ [0x16901]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16901,
+ },
+ [0x16902]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16902,
+ },
+ [0x16903]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16903,
+ },
+ [0x16904]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16904,
+ },
+ [0x16905]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16905,
+ },
+ [0x16906]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16906,
+ },
+ [0x16907]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16907,
+ },
+ [0x16908]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16908,
+ },
+ [0x16909]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16909,
+ },
+ [0x1690A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690A,
+ },
+ [0x1690B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690B,
+ },
+ [0x1690C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690C,
+ },
+ [0x1690D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690D,
+ },
+ [0x1690E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690E,
+ },
+ [0x1690F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690F,
+ },
+ [0x16910]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16910,
+ },
+ [0x16911]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16911,
+ },
+ [0x16912]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16912,
+ },
+ [0x16913]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16913,
+ },
+ [0x16914]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16914,
+ },
+ [0x16915]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16915,
+ },
+ [0x16916]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16916,
+ },
+ [0x16917]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16917,
+ },
+ [0x16918]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16918,
+ },
+ [0x16919]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16919,
+ },
+ [0x1691A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691A,
+ },
+ [0x1691B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691B,
+ },
+ [0x1691C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691C,
+ },
+ [0x1691D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691D,
+ },
+ [0x1691E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691E,
+ },
+ [0x1691F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691F,
+ },
+ [0x16920]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16920,
+ },
+ [0x16921]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16921,
+ },
+ [0x16922]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16922,
+ },
+ [0x16923]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16923,
+ },
+ [0x16924]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16924,
+ },
+ [0x16925]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16925,
+ },
+ [0x16926]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16926,
+ },
+ [0x16927]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16927,
+ },
+ [0x16928]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16928,
+ },
+ [0x16929]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16929,
+ },
+ [0x1692A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692A,
+ },
+ [0x1692B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692B,
+ },
+ [0x1692C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692C,
+ },
+ [0x1692D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692D,
+ },
+ [0x1692E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692E,
+ },
+ [0x1692F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692F,
+ },
+ [0x16930]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16930,
+ },
+ [0x16931]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16931,
+ },
+ [0x16932]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16932,
+ },
+ [0x16933]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16933,
+ },
+ [0x16934]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16934,
+ },
+ [0x16935]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16935,
+ },
+ [0x16936]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16936,
+ },
+ [0x16937]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16937,
+ },
+ [0x16938]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16938,
+ },
+ [0x16939]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16939,
+ },
+ [0x1693A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693A,
+ },
+ [0x1693B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693B,
+ },
+ [0x1693C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693C,
+ },
+ [0x1693D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693D,
+ },
+ [0x1693E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693E,
+ },
+ [0x1693F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693F,
+ },
+ [0x16940]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16940,
+ },
+ [0x16941]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16941,
+ },
+ [0x16942]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16942,
+ },
+ [0x16943]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16943,
+ },
+ [0x16944]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16944,
+ },
+ [0x16945]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16945,
+ },
+ [0x16946]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16946,
+ },
+ [0x16947]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16947,
+ },
+ [0x16948]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16948,
+ },
+ [0x16949]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16949,
+ },
+ [0x1694A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694A,
+ },
+ [0x1694B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694B,
+ },
+ [0x1694C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694C,
+ },
+ [0x1694D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694D,
+ },
+ [0x1694E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694E,
+ },
+ [0x1694F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694F,
+ },
+ [0x16950]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16950,
+ },
+ [0x16951]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16951,
+ },
+ [0x16952]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16952,
+ },
+ [0x16953]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16953,
+ },
+ [0x16954]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16954,
+ },
+ [0x16955]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16955,
+ },
+ [0x16956]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16956,
+ },
+ [0x16957]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16957,
+ },
+ [0x16958]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16958,
+ },
+ [0x16959]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16959,
+ },
+ [0x1695A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695A,
+ },
+ [0x1695B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695B,
+ },
+ [0x1695C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695C,
+ },
+ [0x1695D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695D,
+ },
+ [0x1695E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695E,
+ },
+ [0x1695F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695F,
+ },
+ [0x16960]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16960,
+ },
+ [0x16961]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16961,
+ },
+ [0x16962]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16962,
+ },
+ [0x16963]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16963,
+ },
+ [0x16964]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16964,
+ },
+ [0x16965]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16965,
+ },
+ [0x16966]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16966,
+ },
+ [0x16967]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16967,
+ },
+ [0x16968]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16968,
+ },
+ [0x16969]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16969,
+ },
+ [0x1696A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696A,
+ },
+ [0x1696B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696B,
+ },
+ [0x1696C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696C,
+ },
+ [0x1696D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696D,
+ },
+ [0x1696E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696E,
+ },
+ [0x1696F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696F,
+ },
+ [0x16970]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16970,
+ },
+ [0x16971]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16971,
+ },
+ [0x16972]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16972,
+ },
+ [0x16973]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16973,
+ },
+ [0x16974]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16974,
+ },
+ [0x16975]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16975,
+ },
+ [0x16976]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16976,
+ },
+ [0x16977]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16977,
+ },
+ [0x16978]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16978,
+ },
+ [0x16979]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16979,
+ },
+ [0x1697A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697A,
+ },
+ [0x1697B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697B,
+ },
+ [0x1697C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697C,
+ },
+ [0x1697D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697D,
+ },
+ [0x1697E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697E,
+ },
+ [0x1697F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697F,
+ },
+ [0x16980]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16980,
+ },
+ [0x16981]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16981,
+ },
+ [0x16982]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16982,
+ },
+ [0x16983]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16983,
+ },
+ [0x16984]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16984,
+ },
+ [0x16985]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16985,
+ },
+ [0x16986]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16986,
+ },
+ [0x16987]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16987,
+ },
+ [0x16988]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16988,
+ },
+ [0x16989]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16989,
+ },
+ [0x1698A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698A,
+ },
+ [0x1698B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698B,
+ },
+ [0x1698C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698C,
+ },
+ [0x1698D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698D,
+ },
+ [0x1698E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698E,
+ },
+ [0x1698F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698F,
+ },
+ [0x16990]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16990,
+ },
+ [0x16991]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16991,
+ },
+ [0x16992]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16992,
+ },
+ [0x16993]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16993,
+ },
+ [0x16994]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16994,
+ },
+ [0x16995]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16995,
+ },
+ [0x16996]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16996,
+ },
+ [0x16997]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16997,
+ },
+ [0x16998]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16998,
+ },
+ [0x16999]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16999,
+ },
+ [0x1699A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699A,
+ },
+ [0x1699B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699B,
+ },
+ [0x1699C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699C,
+ },
+ [0x1699D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699D,
+ },
+ [0x1699E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699E,
+ },
+ [0x1699F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699F,
+ },
+ [0x169A0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A0,
+ },
+ [0x169A1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A1,
+ },
+ [0x169A2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A2,
+ },
+ [0x169A3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A3,
+ },
+ [0x169A4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A4,
+ },
+ [0x169A5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A5,
+ },
+ [0x169A6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A6,
+ },
+ [0x169A7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A7,
+ },
+ [0x169A8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A8,
+ },
+ [0x169A9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A9,
+ },
+ [0x169AA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169AA,
+ },
+ [0x169AB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169AB,
+ },
+ [0x169AC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169AC,
+ },
+ [0x169AD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169AD,
+ },
+ [0x169AE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169AE,
+ },
+ [0x169AF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169AF,
+ },
+ [0x169B0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B0,
+ },
+ [0x169B1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B1,
+ },
+ [0x169B2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B2,
+ },
+ [0x169B3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B3,
+ },
+ [0x169B4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B4,
+ },
+ [0x169B5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B5,
+ },
+ [0x169B6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B6,
+ },
+ [0x169B7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B7,
+ },
+ [0x169B8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B8,
+ },
+ [0x169B9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B9,
+ },
+ [0x169BA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169BA,
+ },
+ [0x169BB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169BB,
+ },
+ [0x169BC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169BC,
+ },
+ [0x169BD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169BD,
+ },
+ [0x169BE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169BE,
+ },
+ [0x169BF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169BF,
+ },
+ [0x169C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C0,
+ },
+ [0x169C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C1,
+ },
+ [0x169C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C2,
+ },
+ [0x169C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C3,
+ },
+ [0x169C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C4,
+ },
+ [0x169C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C5,
+ },
+ [0x169C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C6,
+ },
+ [0x169C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C7,
+ },
+ [0x169C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C8,
+ },
+ [0x169C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C9,
+ },
+ [0x169CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169CA,
+ },
+ [0x169CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169CB,
+ },
+ [0x169CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169CC,
+ },
+ [0x169CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169CD,
+ },
+ [0x169CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169CE,
+ },
+ [0x169CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169CF,
+ },
+ [0x169D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D0,
+ },
+ [0x169D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D1,
+ },
+ [0x169D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D2,
+ },
+ [0x169D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D3,
+ },
+ [0x169D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D4,
+ },
+ [0x169D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D5,
+ },
+ [0x169D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D6,
+ },
+ [0x169D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D7,
+ },
+ [0x169D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D8,
+ },
+ [0x169D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D9,
+ },
+ [0x169DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169DA,
+ },
+ [0x169DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169DB,
+ },
+ [0x169DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169DC,
+ },
+ [0x169DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169DD,
+ },
+ [0x169DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169DE,
+ },
+ [0x169DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169DF,
+ },
+ [0x169E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E0,
+ },
+ [0x169E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E1,
+ },
+ [0x169E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E2,
+ },
+ [0x169E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E3,
+ },
+ [0x169E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E4,
+ },
+ [0x169E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E5,
+ },
+ [0x169E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E6,
+ },
+ [0x169E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E7,
+ },
+ [0x169E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E8,
+ },
+ [0x169E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E9,
+ },
+ [0x169EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169EA,
+ },
+ [0x169EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169EB,
+ },
+ [0x169EC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169EC,
+ },
+ [0x169ED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169ED,
+ },
+ [0x169EE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169EE,
+ },
+ [0x169EF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169EF,
+ },
+ [0x169F0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F0,
+ },
+ [0x169F1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F1,
+ },
+ [0x169F2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F2,
+ },
+ [0x169F3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F3,
+ },
+ [0x169F4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F4,
+ },
+ [0x169F5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F5,
+ },
+ [0x169F6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F6,
+ },
+ [0x169F7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F7,
+ },
+ [0x169F8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F8,
+ },
+ [0x169F9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F9,
+ },
+ [0x169FA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169FA,
+ },
+ [0x169FB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169FB,
+ },
+ [0x169FC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169FC,
+ },
+ [0x169FD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169FD,
+ },
+ [0x169FE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169FE,
+ },
+ [0x169FF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169FF,
+ },
+ [0x16A00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A00,
+ },
+ [0x16A01]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A01,
+ },
+ [0x16A02]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A02,
+ },
+ [0x16A03]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A03,
+ },
+ [0x16A04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A04,
+ },
+ [0x16A05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A05,
+ },
+ [0x16A06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A06,
+ },
+ [0x16A07]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A07,
+ },
+ [0x16A08]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A08,
+ },
+ [0x16A09]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A09,
+ },
+ [0x16A0A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0A,
+ },
+ [0x16A0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0B,
+ },
+ [0x16A0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0C,
+ },
+ [0x16A0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0D,
+ },
+ [0x16A0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0E,
+ },
+ [0x16A0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0F,
+ },
+ [0x16A10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A10,
+ },
+ [0x16A11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A11,
+ },
+ [0x16A12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A12,
+ },
+ [0x16A13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A13,
+ },
+ [0x16A14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A14,
+ },
+ [0x16A15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A15,
+ },
+ [0x16A16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A16,
+ },
+ [0x16A17]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A17,
+ },
+ [0x16A18]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A18,
+ },
+ [0x16A19]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A19,
+ },
+ [0x16A1A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1A,
+ },
+ [0x16A1B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1B,
+ },
+ [0x16A1C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1C,
+ },
+ [0x16A1D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1D,
+ },
+ [0x16A1E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1E,
+ },
+ [0x16A1F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1F,
+ },
+ [0x16A20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A20,
+ },
+ [0x16A21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A21,
+ },
+ [0x16A22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A22,
+ },
+ [0x16A23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A23,
+ },
+ [0x16A24]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A24,
+ },
+ [0x16A25]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A25,
+ },
+ [0x16A26]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A26,
+ },
+ [0x16A27]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A27,
+ },
+ [0x16A28]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A28,
+ },
+ [0x16A29]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A29,
+ },
+ [0x16A2A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2A,
+ },
+ [0x16A2B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2B,
+ },
+ [0x16A2C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2C,
+ },
+ [0x16A2D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2D,
+ },
+ [0x16A2E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2E,
+ },
+ [0x16A2F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2F,
+ },
+ [0x16A30]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A30,
+ },
+ [0x16A31]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A31,
+ },
+ [0x16A32]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A32,
+ },
+ [0x16A33]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A33,
+ },
+ [0x16A34]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A34,
+ },
+ [0x16A35]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A35,
+ },
+ [0x16A36]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A36,
+ },
+ [0x16A37]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A37,
+ },
+ [0x16A38]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A38,
+ },
+ [0x16A40]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A40,
+ },
+ [0x16A41]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A41,
+ },
+ [0x16A42]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A42,
+ },
+ [0x16A43]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A43,
+ },
+ [0x16A44]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A44,
+ },
+ [0x16A45]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A45,
+ },
+ [0x16A46]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A46,
+ },
+ [0x16A47]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A47,
+ },
+ [0x16A48]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A48,
+ },
+ [0x16A49]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A49,
+ },
+ [0x16A4A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A4A,
+ },
+ [0x16A4B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A4B,
+ },
+ [0x16A4C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A4C,
+ },
+ [0x16A4D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A4D,
+ },
+ [0x16A4E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A4E,
+ },
+ [0x16A4F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A4F,
+ },
+ [0x16A50]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A50,
+ },
+ [0x16A51]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A51,
+ },
+ [0x16A52]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A52,
+ },
+ [0x16A53]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A53,
+ },
+ [0x16A54]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A54,
+ },
+ [0x16A55]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A55,
+ },
+ [0x16A56]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A56,
+ },
+ [0x16A57]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A57,
+ },
+ [0x16A58]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A58,
+ },
+ [0x16A59]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A59,
+ },
+ [0x16A5A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A5A,
+ },
+ [0x16A5B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A5B,
+ },
+ [0x16A5C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A5C,
+ },
+ [0x16A5D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A5D,
+ },
+ [0x16A5E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A5E,
+ },
+ [0x16A60]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16A60,
+ },
+ [0x16A61]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16A61,
+ },
+ [0x16A62]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16A62,
+ },
+ [0x16A63]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16A63,
+ },
+ [0x16A64]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16A64,
+ },
+ [0x16A65]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16A65,
+ },
+ [0x16A66]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16A66,
+ },
+ [0x16A67]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16A67,
+ },
+ [0x16A68]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16A68,
+ },
+ [0x16A69]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16A69,
+ },
+ [0x16A6E]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16A6E,
+ },
+ [0x16A6F]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16A6F,
+ },
+ [0x16AD0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AD0,
+ },
+ [0x16AD1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AD1,
+ },
+ [0x16AD2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AD2,
+ },
+ [0x16AD3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AD3,
+ },
+ [0x16AD4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AD4,
+ },
+ [0x16AD5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AD5,
+ },
+ [0x16AD6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AD6,
+ },
+ [0x16AD7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AD7,
+ },
+ [0x16AD8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AD8,
+ },
+ [0x16AD9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AD9,
+ },
+ [0x16ADA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16ADA,
+ },
+ [0x16ADB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16ADB,
+ },
+ [0x16ADC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16ADC,
+ },
+ [0x16ADD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16ADD,
+ },
+ [0x16ADE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16ADE,
+ },
+ [0x16ADF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16ADF,
+ },
+ [0x16AE0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AE0,
+ },
+ [0x16AE1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AE1,
+ },
+ [0x16AE2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AE2,
+ },
+ [0x16AE3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AE3,
+ },
+ [0x16AE4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AE4,
+ },
+ [0x16AE5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AE5,
+ },
+ [0x16AE6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AE6,
+ },
+ [0x16AE7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AE7,
+ },
+ [0x16AE8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AE8,
+ },
+ [0x16AE9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AE9,
+ },
+ [0x16AEA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AEA,
+ },
+ [0x16AEB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AEB,
+ },
+ [0x16AEC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AEC,
+ },
+ [0x16AED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AED,
+ },
+ [0x16AF0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16AF0,
+ },
+ [0x16AF1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16AF1,
+ },
+ [0x16AF2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16AF2,
+ },
+ [0x16AF3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16AF3,
+ },
+ [0x16AF4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16AF4,
+ },
+ [0x16AF5]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16AF5,
+ },
+ [0x16B00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B00,
+ },
+ [0x16B01]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B01,
+ },
+ [0x16B02]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B02,
+ },
+ [0x16B03]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B03,
+ },
+ [0x16B04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B04,
+ },
+ [0x16B05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B05,
+ },
+ [0x16B06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B06,
+ },
+ [0x16B07]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B07,
+ },
+ [0x16B08]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B08,
+ },
+ [0x16B09]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B09,
+ },
+ [0x16B0A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B0A,
+ },
+ [0x16B0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B0B,
+ },
+ [0x16B0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B0C,
+ },
+ [0x16B0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B0D,
+ },
+ [0x16B0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B0E,
+ },
+ [0x16B0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B0F,
+ },
+ [0x16B10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B10,
+ },
+ [0x16B11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B11,
+ },
+ [0x16B12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B12,
+ },
+ [0x16B13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B13,
+ },
+ [0x16B14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B14,
+ },
+ [0x16B15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B15,
+ },
+ [0x16B16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B16,
+ },
+ [0x16B17]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B17,
+ },
+ [0x16B18]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B18,
+ },
+ [0x16B19]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B19,
+ },
+ [0x16B1A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B1A,
+ },
+ [0x16B1B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B1B,
+ },
+ [0x16B1C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B1C,
+ },
+ [0x16B1D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B1D,
+ },
+ [0x16B1E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B1E,
+ },
+ [0x16B1F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B1F,
+ },
+ [0x16B20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B20,
+ },
+ [0x16B21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B21,
+ },
+ [0x16B22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B22,
+ },
+ [0x16B23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B23,
+ },
+ [0x16B24]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B24,
+ },
+ [0x16B25]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B25,
+ },
+ [0x16B26]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B26,
+ },
+ [0x16B27]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B27,
+ },
+ [0x16B28]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B28,
+ },
+ [0x16B29]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B29,
+ },
+ [0x16B2A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B2A,
+ },
+ [0x16B2B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B2B,
+ },
+ [0x16B2C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B2C,
+ },
+ [0x16B2D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B2D,
+ },
+ [0x16B2E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B2E,
+ },
+ [0x16B2F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B2F,
+ },
+ [0x16B30]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16B30,
+ },
+ [0x16B31]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16B31,
+ },
+ [0x16B32]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16B32,
+ },
+ [0x16B33]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16B33,
+ },
+ [0x16B34]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16B34,
+ },
+ [0x16B35]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16B35,
+ },
+ [0x16B36]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16B36,
+ },
+ [0x16B37]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16B37,
+ },
+ [0x16B38]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16B38,
+ },
+ [0x16B39]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16B39,
+ },
+ [0x16B3A]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B3A,
+ },
+ [0x16B3B]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B3B,
+ },
+ [0x16B3C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B3C,
+ },
+ [0x16B3D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B3D,
+ },
+ [0x16B3E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B3E,
+ },
+ [0x16B3F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B3F,
+ },
+ [0x16B40]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B40,
+ },
+ [0x16B41]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B41,
+ },
+ [0x16B42]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B42,
+ },
+ [0x16B43]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B43,
+ },
+ [0x16B44]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16B44,
+ },
+ [0x16B45]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B45,
+ },
+ [0x16B50]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16B50,
+ },
+ [0x16B51]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16B51,
+ },
+ [0x16B52]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16B52,
+ },
+ [0x16B53]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16B53,
+ },
+ [0x16B54]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16B54,
+ },
+ [0x16B55]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16B55,
+ },
+ [0x16B56]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16B56,
+ },
+ [0x16B57]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16B57,
+ },
+ [0x16B58]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16B58,
+ },
+ [0x16B59]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x16B59,
+ },
+ [0x16B5B]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B5B,
+ },
+ [0x16B5C]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B5C,
+ },
+ [0x16B5D]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B5D,
+ },
+ [0x16B5E]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B5E,
+ },
+ [0x16B5F]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B5F,
+ },
+ [0x16B60]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B60,
+ },
+ [0x16B61]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B61,
+ },
+ [0x16B63]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B63,
+ },
+ [0x16B64]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B64,
+ },
+ [0x16B65]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B65,
+ },
+ [0x16B66]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B66,
+ },
+ [0x16B67]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B67,
+ },
+ [0x16B68]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B68,
+ },
+ [0x16B69]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B69,
+ },
+ [0x16B6A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B6A,
+ },
+ [0x16B6B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B6B,
+ },
+ [0x16B6C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B6C,
+ },
+ [0x16B6D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B6D,
+ },
+ [0x16B6E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B6E,
+ },
+ [0x16B6F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B6F,
+ },
+ [0x16B70]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B70,
+ },
+ [0x16B71]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B71,
+ },
+ [0x16B72]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B72,
+ },
+ [0x16B73]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B73,
+ },
+ [0x16B74]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B74,
+ },
+ [0x16B75]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B75,
+ },
+ [0x16B76]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B76,
+ },
+ [0x16B77]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B77,
+ },
+ [0x16B7D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B7D,
+ },
+ [0x16B7E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B7E,
+ },
+ [0x16B7F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B7F,
+ },
+ [0x16B80]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B80,
+ },
+ [0x16B81]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B81,
+ },
+ [0x16B82]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B82,
+ },
+ [0x16B83]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B83,
+ },
+ [0x16B84]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B84,
+ },
+ [0x16B85]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B85,
+ },
+ [0x16B86]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B86,
+ },
+ [0x16B87]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B87,
+ },
+ [0x16B88]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B88,
+ },
+ [0x16B89]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B89,
+ },
+ [0x16B8A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B8A,
+ },
+ [0x16B8B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B8B,
+ },
+ [0x16B8C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B8C,
+ },
+ [0x16B8D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B8D,
+ },
+ [0x16B8E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B8E,
+ },
+ [0x16B8F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B8F,
+ },
+ [0x16E40]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E40,
+ },
+ [0x16E41]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E41,
+ },
+ [0x16E42]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E42,
+ },
+ [0x16E43]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E43,
+ },
+ [0x16E44]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E44,
+ },
+ [0x16E45]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E45,
+ },
+ [0x16E46]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E46,
+ },
+ [0x16E47]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E47,
+ },
+ [0x16E48]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E48,
+ },
+ [0x16E49]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E49,
+ },
+ [0x16E4A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E4A,
+ },
+ [0x16E4B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E4B,
+ },
+ [0x16E4C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E4C,
+ },
+ [0x16E4D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E4D,
+ },
+ [0x16E4E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E4E,
+ },
+ [0x16E4F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E4F,
+ },
+ [0x16E50]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E50,
+ },
+ [0x16E51]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E51,
+ },
+ [0x16E52]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E52,
+ },
+ [0x16E53]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E53,
+ },
+ [0x16E54]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E54,
+ },
+ [0x16E55]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E55,
+ },
+ [0x16E56]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E56,
+ },
+ [0x16E57]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E57,
+ },
+ [0x16E58]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E58,
+ },
+ [0x16E59]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E59,
+ },
+ [0x16E5A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E5A,
+ },
+ [0x16E5B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E5B,
+ },
+ [0x16E5C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E5C,
+ },
+ [0x16E5D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E5D,
+ },
+ [0x16E5E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E5E,
+ },
+ [0x16E5F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E5F,
+ },
+ [0x16E60]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E60,
+ },
+ [0x16E61]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E61,
+ },
+ [0x16E62]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E62,
+ },
+ [0x16E63]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E63,
+ },
+ [0x16E64]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E64,
+ },
+ [0x16E65]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E65,
+ },
+ [0x16E66]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E66,
+ },
+ [0x16E67]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E67,
+ },
+ [0x16E68]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E68,
+ },
+ [0x16E69]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E69,
+ },
+ [0x16E6A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E6A,
+ },
+ [0x16E6B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E6B,
+ },
+ [0x16E6C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E6C,
+ },
+ [0x16E6D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E6D,
+ },
+ [0x16E6E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E6E,
+ },
+ [0x16E6F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E6F,
+ },
+ [0x16E70]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E70,
+ },
+ [0x16E71]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E71,
+ },
+ [0x16E72]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E72,
+ },
+ [0x16E73]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E73,
+ },
+ [0x16E74]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E74,
+ },
+ [0x16E75]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E75,
+ },
+ [0x16E76]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E76,
+ },
+ [0x16E77]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E77,
+ },
+ [0x16E78]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E78,
+ },
+ [0x16E79]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E79,
+ },
+ [0x16E7A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E7A,
+ },
+ [0x16E7B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E7B,
+ },
+ [0x16E7C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E7C,
+ },
+ [0x16E7D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E7D,
+ },
+ [0x16E7E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E7E,
+ },
+ [0x16E7F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E7F,
+ },
+ [0x16E80]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E80,
+ },
+ [0x16E81]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E81,
+ },
+ [0x16E82]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E82,
+ },
+ [0x16E83]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E83,
+ },
+ [0x16E84]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E84,
+ },
+ [0x16E85]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E85,
+ },
+ [0x16E86]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E86,
+ },
+ [0x16E87]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E87,
+ },
+ [0x16E88]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E88,
+ },
+ [0x16E89]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E89,
+ },
+ [0x16E8A]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E8A,
+ },
+ [0x16E8B]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E8B,
+ },
+ [0x16E8C]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E8C,
+ },
+ [0x16E8D]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E8D,
+ },
+ [0x16E8E]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E8E,
+ },
+ [0x16E8F]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E8F,
+ },
+ [0x16E90]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E90,
+ },
+ [0x16E91]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E91,
+ },
+ [0x16E92]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E92,
+ },
+ [0x16E93]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E93,
+ },
+ [0x16E94]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E94,
+ },
+ [0x16E95]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E95,
+ },
+ [0x16E96]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E96,
+ },
+ [0x16E97]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16E97,
+ },
+ [0x16E98]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16E98,
+ },
+ [0x16E99]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E99,
+ },
+ [0x16E9A]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E9A,
+ },
+ [0x16F00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F00,
+ },
+ [0x16F01]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F01,
+ },
+ [0x16F02]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F02,
+ },
+ [0x16F03]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F03,
+ },
+ [0x16F04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F04,
+ },
+ [0x16F05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F05,
+ },
+ [0x16F06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F06,
+ },
+ [0x16F07]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F07,
+ },
+ [0x16F08]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F08,
+ },
+ [0x16F09]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F09,
+ },
+ [0x16F0A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0A,
+ },
+ [0x16F0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0B,
+ },
+ [0x16F0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0C,
+ },
+ [0x16F0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0D,
+ },
+ [0x16F0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0E,
+ },
+ [0x16F0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0F,
+ },
+ [0x16F10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F10,
+ },
+ [0x16F11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F11,
+ },
+ [0x16F12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F12,
+ },
+ [0x16F13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F13,
+ },
+ [0x16F14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F14,
+ },
+ [0x16F15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F15,
+ },
+ [0x16F16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F16,
+ },
+ [0x16F17]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F17,
+ },
+ [0x16F18]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F18,
+ },
+ [0x16F19]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F19,
+ },
+ [0x16F1A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1A,
+ },
+ [0x16F1B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1B,
+ },
+ [0x16F1C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1C,
+ },
+ [0x16F1D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1D,
+ },
+ [0x16F1E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1E,
+ },
+ [0x16F1F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1F,
+ },
+ [0x16F20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F20,
+ },
+ [0x16F21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F21,
+ },
+ [0x16F22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F22,
+ },
+ [0x16F23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F23,
+ },
+ [0x16F24]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F24,
+ },
+ [0x16F25]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F25,
+ },
+ [0x16F26]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F26,
+ },
+ [0x16F27]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F27,
+ },
+ [0x16F28]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F28,
+ },
+ [0x16F29]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F29,
+ },
+ [0x16F2A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2A,
+ },
+ [0x16F2B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2B,
+ },
+ [0x16F2C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2C,
+ },
+ [0x16F2D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2D,
+ },
+ [0x16F2E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2E,
+ },
+ [0x16F2F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2F,
+ },
+ [0x16F30]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F30,
+ },
+ [0x16F31]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F31,
+ },
+ [0x16F32]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F32,
+ },
+ [0x16F33]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F33,
+ },
+ [0x16F34]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F34,
+ },
+ [0x16F35]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F35,
+ },
+ [0x16F36]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F36,
+ },
+ [0x16F37]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F37,
+ },
+ [0x16F38]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F38,
+ },
+ [0x16F39]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F39,
+ },
+ [0x16F3A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3A,
+ },
+ [0x16F3B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3B,
+ },
+ [0x16F3C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3C,
+ },
+ [0x16F3D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3D,
+ },
+ [0x16F3E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3E,
+ },
+ [0x16F3F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3F,
+ },
+ [0x16F40]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F40,
+ },
+ [0x16F41]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F41,
+ },
+ [0x16F42]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F42,
+ },
+ [0x16F43]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F43,
+ },
+ [0x16F44]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F44,
+ },
+ [0x16F45]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F45,
+ },
+ [0x16F46]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F46,
+ },
+ [0x16F47]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F47,
+ },
+ [0x16F48]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F48,
+ },
+ [0x16F49]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F49,
+ },
+ [0x16F4A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F4A,
+ },
+ [0x16F4F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16F4F,
+ },
+ [0x16F50]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F50,
+ },
+ [0x16F51]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F51,
+ },
+ [0x16F52]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F52,
+ },
+ [0x16F53]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F53,
+ },
+ [0x16F54]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F54,
+ },
+ [0x16F55]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F55,
+ },
+ [0x16F56]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F56,
+ },
+ [0x16F57]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F57,
+ },
+ [0x16F58]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F58,
+ },
+ [0x16F59]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F59,
+ },
+ [0x16F5A]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F5A,
+ },
+ [0x16F5B]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F5B,
+ },
+ [0x16F5C]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F5C,
+ },
+ [0x16F5D]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F5D,
+ },
+ [0x16F5E]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F5E,
+ },
+ [0x16F5F]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F5F,
+ },
+ [0x16F60]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F60,
+ },
+ [0x16F61]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F61,
+ },
+ [0x16F62]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F62,
+ },
+ [0x16F63]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F63,
+ },
+ [0x16F64]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F64,
+ },
+ [0x16F65]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F65,
+ },
+ [0x16F66]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F66,
+ },
+ [0x16F67]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F67,
+ },
+ [0x16F68]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F68,
+ },
+ [0x16F69]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F69,
+ },
+ [0x16F6A]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F6A,
+ },
+ [0x16F6B]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F6B,
+ },
+ [0x16F6C]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F6C,
+ },
+ [0x16F6D]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F6D,
+ },
+ [0x16F6E]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F6E,
+ },
+ [0x16F6F]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F6F,
+ },
+ [0x16F70]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F70,
+ },
+ [0x16F71]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F71,
+ },
+ [0x16F72]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F72,
+ },
+ [0x16F73]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F73,
+ },
+ [0x16F74]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F74,
+ },
+ [0x16F75]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F75,
+ },
+ [0x16F76]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F76,
+ },
+ [0x16F77]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F77,
+ },
+ [0x16F78]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F78,
+ },
+ [0x16F79]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F79,
+ },
+ [0x16F7A]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F7A,
+ },
+ [0x16F7B]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F7B,
+ },
+ [0x16F7C]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F7C,
+ },
+ [0x16F7D]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F7D,
+ },
+ [0x16F7E]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F7E,
+ },
+ [0x16F7F]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F7F,
+ },
+ [0x16F80]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F80,
+ },
+ [0x16F81]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F81,
+ },
+ [0x16F82]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F82,
+ },
+ [0x16F83]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F83,
+ },
+ [0x16F84]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F84,
+ },
+ [0x16F85]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F85,
+ },
+ [0x16F86]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F86,
+ },
+ [0x16F87]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F87,
+ },
+ [0x16F8F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16F8F,
+ },
+ [0x16F90]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16F90,
+ },
+ [0x16F91]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16F91,
+ },
+ [0x16F92]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16F92,
+ },
+ [0x16F93]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F93,
+ },
+ [0x16F94]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F94,
+ },
+ [0x16F95]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F95,
+ },
+ [0x16F96]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F96,
+ },
+ [0x16F97]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F97,
+ },
+ [0x16F98]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F98,
+ },
+ [0x16F99]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F99,
+ },
+ [0x16F9A]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F9A,
+ },
+ [0x16F9B]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F9B,
+ },
+ [0x16F9C]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F9C,
+ },
+ [0x16F9D]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F9D,
+ },
+ [0x16F9E]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F9E,
+ },
+ [0x16F9F]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F9F,
+ },
+ [0x16FE0]={
+ category="lm",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x16FE0,
+ },
+ [0x16FE1]={
+ category="lm",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x16FE1,
+ },
+ [0x16FE2]={
+ category="po",
+ direction="on",
+ linebreak="ns",
+ unicodeslot=0x16FE2,
+ },
+ [0x16FE3]={
+ category="lm",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x16FE3,
+ },
+ [0x18800]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18800,
+ },
+ [0x18801]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18801,
+ },
+ [0x18802]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18802,
+ },
+ [0x18803]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18803,
+ },
+ [0x18804]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18804,
+ },
+ [0x18805]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18805,
+ },
+ [0x18806]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18806,
+ },
+ [0x18807]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18807,
+ },
+ [0x18808]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18808,
+ },
+ [0x18809]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18809,
+ },
+ [0x1880A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1880A,
+ },
+ [0x1880B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1880B,
+ },
+ [0x1880C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1880C,
+ },
+ [0x1880D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1880D,
+ },
+ [0x1880E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1880E,
+ },
+ [0x1880F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1880F,
+ },
+ [0x18810]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18810,
+ },
+ [0x18811]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18811,
+ },
+ [0x18812]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18812,
+ },
+ [0x18813]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18813,
+ },
+ [0x18814]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18814,
+ },
+ [0x18815]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18815,
+ },
+ [0x18816]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18816,
+ },
+ [0x18817]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18817,
+ },
+ [0x18818]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18818,
+ },
+ [0x18819]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18819,
+ },
+ [0x1881A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1881A,
+ },
+ [0x1881B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1881B,
+ },
+ [0x1881C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1881C,
+ },
+ [0x1881D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1881D,
+ },
+ [0x1881E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1881E,
+ },
+ [0x1881F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1881F,
+ },
+ [0x18820]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18820,
+ },
+ [0x18821]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18821,
+ },
+ [0x18822]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18822,
+ },
+ [0x18823]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18823,
+ },
+ [0x18824]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18824,
+ },
+ [0x18825]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18825,
+ },
+ [0x18826]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18826,
+ },
+ [0x18827]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18827,
+ },
+ [0x18828]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18828,
+ },
+ [0x18829]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18829,
+ },
+ [0x1882A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1882A,
+ },
+ [0x1882B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1882B,
+ },
+ [0x1882C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1882C,
+ },
+ [0x1882D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1882D,
+ },
+ [0x1882E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1882E,
+ },
+ [0x1882F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1882F,
+ },
+ [0x18830]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18830,
+ },
+ [0x18831]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18831,
+ },
+ [0x18832]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18832,
+ },
+ [0x18833]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18833,
+ },
+ [0x18834]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18834,
+ },
+ [0x18835]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18835,
+ },
+ [0x18836]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18836,
+ },
+ [0x18837]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18837,
+ },
+ [0x18838]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18838,
+ },
+ [0x18839]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18839,
+ },
+ [0x1883A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1883A,
+ },
+ [0x1883B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1883B,
+ },
+ [0x1883C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1883C,
+ },
+ [0x1883D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1883D,
+ },
+ [0x1883E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1883E,
+ },
+ [0x1883F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1883F,
+ },
+ [0x18840]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18840,
+ },
+ [0x18841]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18841,
+ },
+ [0x18842]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18842,
+ },
+ [0x18843]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18843,
+ },
+ [0x18844]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18844,
+ },
+ [0x18845]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18845,
+ },
+ [0x18846]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18846,
+ },
+ [0x18847]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18847,
+ },
+ [0x18848]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18848,
+ },
+ [0x18849]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18849,
+ },
+ [0x1884A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1884A,
+ },
+ [0x1884B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1884B,
+ },
+ [0x1884C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1884C,
+ },
+ [0x1884D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1884D,
+ },
+ [0x1884E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1884E,
+ },
+ [0x1884F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1884F,
+ },
+ [0x18850]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18850,
+ },
+ [0x18851]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18851,
+ },
+ [0x18852]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18852,
+ },
+ [0x18853]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18853,
+ },
+ [0x18854]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18854,
+ },
+ [0x18855]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18855,
+ },
+ [0x18856]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18856,
+ },
+ [0x18857]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18857,
+ },
+ [0x18858]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18858,
+ },
+ [0x18859]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18859,
+ },
+ [0x1885A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1885A,
+ },
+ [0x1885B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1885B,
+ },
+ [0x1885C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1885C,
+ },
+ [0x1885D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1885D,
+ },
+ [0x1885E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1885E,
+ },
+ [0x1885F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1885F,
+ },
+ [0x18860]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18860,
+ },
+ [0x18861]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18861,
+ },
+ [0x18862]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18862,
+ },
+ [0x18863]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18863,
+ },
+ [0x18864]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18864,
+ },
+ [0x18865]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18865,
+ },
+ [0x18866]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18866,
+ },
+ [0x18867]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18867,
+ },
+ [0x18868]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18868,
+ },
+ [0x18869]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18869,
+ },
+ [0x1886A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1886A,
+ },
+ [0x1886B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1886B,
+ },
+ [0x1886C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1886C,
+ },
+ [0x1886D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1886D,
+ },
+ [0x1886E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1886E,
+ },
+ [0x1886F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1886F,
+ },
+ [0x18870]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18870,
+ },
+ [0x18871]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18871,
+ },
+ [0x18872]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18872,
+ },
+ [0x18873]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18873,
+ },
+ [0x18874]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18874,
+ },
+ [0x18875]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18875,
+ },
+ [0x18876]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18876,
+ },
+ [0x18877]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18877,
+ },
+ [0x18878]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18878,
+ },
+ [0x18879]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18879,
+ },
+ [0x1887A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1887A,
+ },
+ [0x1887B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1887B,
+ },
+ [0x1887C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1887C,
+ },
+ [0x1887D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1887D,
+ },
+ [0x1887E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1887E,
+ },
+ [0x1887F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1887F,
+ },
+ [0x18880]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18880,
+ },
+ [0x18881]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18881,
+ },
+ [0x18882]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18882,
+ },
+ [0x18883]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18883,
+ },
+ [0x18884]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18884,
+ },
+ [0x18885]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18885,
+ },
+ [0x18886]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18886,
+ },
+ [0x18887]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18887,
+ },
+ [0x18888]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18888,
+ },
+ [0x18889]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18889,
+ },
+ [0x1888A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1888A,
+ },
+ [0x1888B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1888B,
+ },
+ [0x1888C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1888C,
+ },
+ [0x1888D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1888D,
+ },
+ [0x1888E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1888E,
+ },
+ [0x1888F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1888F,
+ },
+ [0x18890]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18890,
+ },
+ [0x18891]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18891,
+ },
+ [0x18892]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18892,
+ },
+ [0x18893]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18893,
+ },
+ [0x18894]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18894,
+ },
+ [0x18895]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18895,
+ },
+ [0x18896]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18896,
+ },
+ [0x18897]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18897,
+ },
+ [0x18898]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18898,
+ },
+ [0x18899]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18899,
+ },
+ [0x1889A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1889A,
+ },
+ [0x1889B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1889B,
+ },
+ [0x1889C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1889C,
+ },
+ [0x1889D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1889D,
+ },
+ [0x1889E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1889E,
+ },
+ [0x1889F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1889F,
+ },
+ [0x188A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188A0,
+ },
+ [0x188A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188A1,
+ },
+ [0x188A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188A2,
+ },
+ [0x188A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188A3,
+ },
+ [0x188A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188A4,
+ },
+ [0x188A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188A5,
+ },
+ [0x188A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188A6,
+ },
+ [0x188A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188A7,
+ },
+ [0x188A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188A8,
+ },
+ [0x188A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188A9,
+ },
+ [0x188AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188AA,
+ },
+ [0x188AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188AB,
+ },
+ [0x188AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188AC,
+ },
+ [0x188AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188AD,
+ },
+ [0x188AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188AE,
+ },
+ [0x188AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188AF,
+ },
+ [0x188B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188B0,
+ },
+ [0x188B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188B1,
+ },
+ [0x188B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188B2,
+ },
+ [0x188B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188B3,
+ },
+ [0x188B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188B4,
+ },
+ [0x188B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188B5,
+ },
+ [0x188B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188B6,
+ },
+ [0x188B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188B7,
+ },
+ [0x188B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188B8,
+ },
+ [0x188B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188B9,
+ },
+ [0x188BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188BA,
+ },
+ [0x188BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188BB,
+ },
+ [0x188BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188BC,
+ },
+ [0x188BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188BD,
+ },
+ [0x188BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188BE,
+ },
+ [0x188BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188BF,
+ },
+ [0x188C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188C0,
+ },
+ [0x188C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188C1,
+ },
+ [0x188C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188C2,
+ },
+ [0x188C3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188C3,
+ },
+ [0x188C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188C4,
+ },
+ [0x188C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188C5,
+ },
+ [0x188C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188C6,
+ },
+ [0x188C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188C7,
+ },
+ [0x188C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188C8,
+ },
+ [0x188C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188C9,
+ },
+ [0x188CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188CA,
+ },
+ [0x188CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188CB,
+ },
+ [0x188CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188CC,
+ },
+ [0x188CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188CD,
+ },
+ [0x188CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188CE,
+ },
+ [0x188CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188CF,
+ },
+ [0x188D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188D0,
+ },
+ [0x188D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188D1,
+ },
+ [0x188D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188D2,
+ },
+ [0x188D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188D3,
+ },
+ [0x188D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188D4,
+ },
+ [0x188D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188D5,
+ },
+ [0x188D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188D6,
+ },
+ [0x188D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188D7,
+ },
+ [0x188D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188D8,
+ },
+ [0x188D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188D9,
+ },
+ [0x188DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188DA,
+ },
+ [0x188DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188DB,
+ },
+ [0x188DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188DC,
+ },
+ [0x188DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188DD,
+ },
+ [0x188DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188DE,
+ },
+ [0x188DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188DF,
+ },
+ [0x188E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188E0,
+ },
+ [0x188E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188E1,
+ },
+ [0x188E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188E2,
+ },
+ [0x188E3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188E3,
+ },
+ [0x188E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188E4,
+ },
+ [0x188E5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188E5,
+ },
+ [0x188E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188E6,
+ },
+ [0x188E7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188E7,
+ },
+ [0x188E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188E8,
+ },
+ [0x188E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188E9,
+ },
+ [0x188EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188EA,
+ },
+ [0x188EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188EB,
+ },
+ [0x188EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188EC,
+ },
+ [0x188ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188ED,
+ },
+ [0x188EE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188EE,
+ },
+ [0x188EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188EF,
+ },
+ [0x188F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188F0,
+ },
+ [0x188F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188F1,
+ },
+ [0x188F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188F2,
+ },
+ [0x188F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188F3,
+ },
+ [0x188F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188F4,
+ },
+ [0x188F5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188F5,
+ },
+ [0x188F6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188F6,
+ },
+ [0x188F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188F7,
+ },
+ [0x188F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188F8,
+ },
+ [0x188F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188F9,
+ },
+ [0x188FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188FA,
+ },
+ [0x188FB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188FB,
+ },
+ [0x188FC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188FC,
+ },
+ [0x188FD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188FD,
+ },
+ [0x188FE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188FE,
+ },
+ [0x188FF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x188FF,
+ },
+ [0x18900]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18900,
+ },
+ [0x18901]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18901,
+ },
+ [0x18902]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18902,
+ },
+ [0x18903]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18903,
+ },
+ [0x18904]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18904,
+ },
+ [0x18905]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18905,
+ },
+ [0x18906]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18906,
+ },
+ [0x18907]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18907,
+ },
+ [0x18908]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18908,
+ },
+ [0x18909]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18909,
+ },
+ [0x1890A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1890A,
+ },
+ [0x1890B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1890B,
+ },
+ [0x1890C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1890C,
+ },
+ [0x1890D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1890D,
+ },
+ [0x1890E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1890E,
+ },
+ [0x1890F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1890F,
+ },
+ [0x18910]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18910,
+ },
+ [0x18911]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18911,
+ },
+ [0x18912]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18912,
+ },
+ [0x18913]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18913,
+ },
+ [0x18914]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18914,
+ },
+ [0x18915]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18915,
+ },
+ [0x18916]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18916,
+ },
+ [0x18917]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18917,
+ },
+ [0x18918]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18918,
+ },
+ [0x18919]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18919,
+ },
+ [0x1891A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1891A,
+ },
+ [0x1891B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1891B,
+ },
+ [0x1891C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1891C,
+ },
+ [0x1891D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1891D,
+ },
+ [0x1891E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1891E,
+ },
+ [0x1891F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1891F,
+ },
+ [0x18920]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18920,
+ },
+ [0x18921]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18921,
+ },
+ [0x18922]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18922,
+ },
+ [0x18923]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18923,
+ },
+ [0x18924]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18924,
+ },
+ [0x18925]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18925,
+ },
+ [0x18926]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18926,
+ },
+ [0x18927]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18927,
+ },
+ [0x18928]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18928,
+ },
+ [0x18929]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18929,
+ },
+ [0x1892A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1892A,
+ },
+ [0x1892B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1892B,
+ },
+ [0x1892C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1892C,
+ },
+ [0x1892D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1892D,
+ },
+ [0x1892E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1892E,
+ },
+ [0x1892F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1892F,
+ },
+ [0x18930]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18930,
+ },
+ [0x18931]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18931,
+ },
+ [0x18932]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18932,
+ },
+ [0x18933]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18933,
+ },
+ [0x18934]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18934,
+ },
+ [0x18935]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18935,
+ },
+ [0x18936]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18936,
+ },
+ [0x18937]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18937,
+ },
+ [0x18938]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18938,
+ },
+ [0x18939]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18939,
+ },
+ [0x1893A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1893A,
+ },
+ [0x1893B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1893B,
+ },
+ [0x1893C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1893C,
+ },
+ [0x1893D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1893D,
+ },
+ [0x1893E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1893E,
+ },
+ [0x1893F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1893F,
+ },
+ [0x18940]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18940,
+ },
+ [0x18941]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18941,
+ },
+ [0x18942]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18942,
+ },
+ [0x18943]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18943,
+ },
+ [0x18944]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18944,
+ },
+ [0x18945]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18945,
+ },
+ [0x18946]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18946,
+ },
+ [0x18947]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18947,
+ },
+ [0x18948]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18948,
+ },
+ [0x18949]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18949,
+ },
+ [0x1894A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1894A,
+ },
+ [0x1894B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1894B,
+ },
+ [0x1894C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1894C,
+ },
+ [0x1894D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1894D,
+ },
+ [0x1894E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1894E,
+ },
+ [0x1894F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1894F,
+ },
+ [0x18950]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18950,
+ },
+ [0x18951]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18951,
+ },
+ [0x18952]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18952,
+ },
+ [0x18953]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18953,
+ },
+ [0x18954]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18954,
+ },
+ [0x18955]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18955,
+ },
+ [0x18956]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18956,
+ },
+ [0x18957]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18957,
+ },
+ [0x18958]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18958,
+ },
+ [0x18959]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18959,
+ },
+ [0x1895A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1895A,
+ },
+ [0x1895B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1895B,
+ },
+ [0x1895C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1895C,
+ },
+ [0x1895D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1895D,
+ },
+ [0x1895E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1895E,
+ },
+ [0x1895F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1895F,
+ },
+ [0x18960]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18960,
+ },
+ [0x18961]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18961,
+ },
+ [0x18962]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18962,
+ },
+ [0x18963]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18963,
+ },
+ [0x18964]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18964,
+ },
+ [0x18965]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18965,
+ },
+ [0x18966]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18966,
+ },
+ [0x18967]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18967,
+ },
+ [0x18968]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18968,
+ },
+ [0x18969]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18969,
+ },
+ [0x1896A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1896A,
+ },
+ [0x1896B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1896B,
+ },
+ [0x1896C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1896C,
+ },
+ [0x1896D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1896D,
+ },
+ [0x1896E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1896E,
+ },
+ [0x1896F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1896F,
+ },
+ [0x18970]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18970,
+ },
+ [0x18971]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18971,
+ },
+ [0x18972]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18972,
+ },
+ [0x18973]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18973,
+ },
+ [0x18974]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18974,
+ },
+ [0x18975]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18975,
+ },
+ [0x18976]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18976,
+ },
+ [0x18977]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18977,
+ },
+ [0x18978]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18978,
+ },
+ [0x18979]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18979,
+ },
+ [0x1897A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1897A,
+ },
+ [0x1897B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1897B,
+ },
+ [0x1897C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1897C,
+ },
+ [0x1897D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1897D,
+ },
+ [0x1897E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1897E,
+ },
+ [0x1897F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1897F,
+ },
+ [0x18980]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18980,
+ },
+ [0x18981]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18981,
+ },
+ [0x18982]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18982,
+ },
+ [0x18983]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18983,
+ },
+ [0x18984]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18984,
+ },
+ [0x18985]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18985,
+ },
+ [0x18986]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18986,
+ },
+ [0x18987]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18987,
+ },
+ [0x18988]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18988,
+ },
+ [0x18989]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18989,
+ },
+ [0x1898A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1898A,
+ },
+ [0x1898B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1898B,
+ },
+ [0x1898C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1898C,
+ },
+ [0x1898D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1898D,
+ },
+ [0x1898E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1898E,
+ },
+ [0x1898F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1898F,
+ },
+ [0x18990]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18990,
+ },
+ [0x18991]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18991,
+ },
+ [0x18992]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18992,
+ },
+ [0x18993]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18993,
+ },
+ [0x18994]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18994,
+ },
+ [0x18995]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18995,
+ },
+ [0x18996]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18996,
+ },
+ [0x18997]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18997,
+ },
+ [0x18998]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18998,
+ },
+ [0x18999]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18999,
+ },
+ [0x1899A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1899A,
+ },
+ [0x1899B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1899B,
+ },
+ [0x1899C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1899C,
+ },
+ [0x1899D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1899D,
+ },
+ [0x1899E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1899E,
+ },
+ [0x1899F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1899F,
+ },
+ [0x189A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189A0,
+ },
+ [0x189A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189A1,
+ },
+ [0x189A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189A2,
+ },
+ [0x189A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189A3,
+ },
+ [0x189A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189A4,
+ },
+ [0x189A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189A5,
+ },
+ [0x189A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189A6,
+ },
+ [0x189A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189A7,
+ },
+ [0x189A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189A8,
+ },
+ [0x189A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189A9,
+ },
+ [0x189AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189AA,
+ },
+ [0x189AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189AB,
+ },
+ [0x189AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189AC,
+ },
+ [0x189AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189AD,
+ },
+ [0x189AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189AE,
+ },
+ [0x189AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189AF,
+ },
+ [0x189B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189B0,
+ },
+ [0x189B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189B1,
+ },
+ [0x189B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189B2,
+ },
+ [0x189B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189B3,
+ },
+ [0x189B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189B4,
+ },
+ [0x189B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189B5,
+ },
+ [0x189B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189B6,
+ },
+ [0x189B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189B7,
+ },
+ [0x189B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189B8,
+ },
+ [0x189B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189B9,
+ },
+ [0x189BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189BA,
+ },
+ [0x189BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189BB,
+ },
+ [0x189BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189BC,
+ },
+ [0x189BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189BD,
+ },
+ [0x189BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189BE,
+ },
+ [0x189BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189BF,
+ },
+ [0x189C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189C0,
+ },
+ [0x189C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189C1,
+ },
+ [0x189C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189C2,
+ },
+ [0x189C3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189C3,
+ },
+ [0x189C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189C4,
+ },
+ [0x189C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189C5,
+ },
+ [0x189C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189C6,
+ },
+ [0x189C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189C7,
+ },
+ [0x189C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189C8,
+ },
+ [0x189C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189C9,
+ },
+ [0x189CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189CA,
+ },
+ [0x189CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189CB,
+ },
+ [0x189CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189CC,
+ },
+ [0x189CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189CD,
+ },
+ [0x189CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189CE,
+ },
+ [0x189CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189CF,
+ },
+ [0x189D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189D0,
+ },
+ [0x189D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189D1,
+ },
+ [0x189D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189D2,
+ },
+ [0x189D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189D3,
+ },
+ [0x189D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189D4,
+ },
+ [0x189D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189D5,
+ },
+ [0x189D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189D6,
+ },
+ [0x189D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189D7,
+ },
+ [0x189D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189D8,
+ },
+ [0x189D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189D9,
+ },
+ [0x189DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189DA,
+ },
+ [0x189DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189DB,
+ },
+ [0x189DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189DC,
+ },
+ [0x189DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189DD,
+ },
+ [0x189DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189DE,
+ },
+ [0x189DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189DF,
+ },
+ [0x189E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189E0,
+ },
+ [0x189E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189E1,
+ },
+ [0x189E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189E2,
+ },
+ [0x189E3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189E3,
+ },
+ [0x189E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189E4,
+ },
+ [0x189E5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189E5,
+ },
+ [0x189E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189E6,
+ },
+ [0x189E7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189E7,
+ },
+ [0x189E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189E8,
+ },
+ [0x189E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189E9,
+ },
+ [0x189EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189EA,
+ },
+ [0x189EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189EB,
+ },
+ [0x189EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189EC,
+ },
+ [0x189ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189ED,
+ },
+ [0x189EE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189EE,
+ },
+ [0x189EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189EF,
+ },
+ [0x189F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189F0,
+ },
+ [0x189F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189F1,
+ },
+ [0x189F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189F2,
+ },
+ [0x189F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189F3,
+ },
+ [0x189F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189F4,
+ },
+ [0x189F5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189F5,
+ },
+ [0x189F6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189F6,
+ },
+ [0x189F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189F7,
+ },
+ [0x189F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189F8,
+ },
+ [0x189F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189F9,
+ },
+ [0x189FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189FA,
+ },
+ [0x189FB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189FB,
+ },
+ [0x189FC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189FC,
+ },
+ [0x189FD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189FD,
+ },
+ [0x189FE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189FE,
+ },
+ [0x189FF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x189FF,
+ },
+ [0x18A00]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A00,
+ },
+ [0x18A01]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A01,
+ },
+ [0x18A02]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A02,
+ },
+ [0x18A03]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A03,
+ },
+ [0x18A04]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A04,
+ },
+ [0x18A05]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A05,
+ },
+ [0x18A06]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A06,
+ },
+ [0x18A07]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A07,
+ },
+ [0x18A08]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A08,
+ },
+ [0x18A09]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A09,
+ },
+ [0x18A0A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A0A,
+ },
+ [0x18A0B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A0B,
+ },
+ [0x18A0C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A0C,
+ },
+ [0x18A0D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A0D,
+ },
+ [0x18A0E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A0E,
+ },
+ [0x18A0F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A0F,
+ },
+ [0x18A10]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A10,
+ },
+ [0x18A11]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A11,
+ },
+ [0x18A12]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A12,
+ },
+ [0x18A13]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A13,
+ },
+ [0x18A14]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A14,
+ },
+ [0x18A15]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A15,
+ },
+ [0x18A16]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A16,
+ },
+ [0x18A17]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A17,
+ },
+ [0x18A18]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A18,
+ },
+ [0x18A19]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A19,
+ },
+ [0x18A1A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A1A,
+ },
+ [0x18A1B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A1B,
+ },
+ [0x18A1C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A1C,
+ },
+ [0x18A1D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A1D,
+ },
+ [0x18A1E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A1E,
+ },
+ [0x18A1F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A1F,
+ },
+ [0x18A20]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A20,
+ },
+ [0x18A21]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A21,
+ },
+ [0x18A22]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A22,
+ },
+ [0x18A23]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A23,
+ },
+ [0x18A24]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A24,
+ },
+ [0x18A25]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A25,
+ },
+ [0x18A26]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A26,
+ },
+ [0x18A27]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A27,
+ },
+ [0x18A28]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A28,
+ },
+ [0x18A29]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A29,
+ },
+ [0x18A2A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A2A,
+ },
+ [0x18A2B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A2B,
+ },
+ [0x18A2C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A2C,
+ },
+ [0x18A2D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A2D,
+ },
+ [0x18A2E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A2E,
+ },
+ [0x18A2F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A2F,
+ },
+ [0x18A30]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A30,
+ },
+ [0x18A31]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A31,
+ },
+ [0x18A32]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A32,
+ },
+ [0x18A33]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A33,
+ },
+ [0x18A34]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A34,
+ },
+ [0x18A35]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A35,
+ },
+ [0x18A36]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A36,
+ },
+ [0x18A37]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A37,
+ },
+ [0x18A38]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A38,
+ },
+ [0x18A39]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A39,
+ },
+ [0x18A3A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A3A,
+ },
+ [0x18A3B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A3B,
+ },
+ [0x18A3C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A3C,
+ },
+ [0x18A3D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A3D,
+ },
+ [0x18A3E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A3E,
+ },
+ [0x18A3F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A3F,
+ },
+ [0x18A40]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A40,
+ },
+ [0x18A41]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A41,
+ },
+ [0x18A42]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A42,
+ },
+ [0x18A43]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A43,
+ },
+ [0x18A44]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A44,
+ },
+ [0x18A45]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A45,
+ },
+ [0x18A46]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A46,
+ },
+ [0x18A47]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A47,
+ },
+ [0x18A48]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A48,
+ },
+ [0x18A49]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A49,
+ },
+ [0x18A4A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A4A,
+ },
+ [0x18A4B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A4B,
+ },
+ [0x18A4C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A4C,
+ },
+ [0x18A4D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A4D,
+ },
+ [0x18A4E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A4E,
+ },
+ [0x18A4F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A4F,
+ },
+ [0x18A50]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A50,
+ },
+ [0x18A51]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A51,
+ },
+ [0x18A52]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A52,
+ },
+ [0x18A53]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A53,
+ },
+ [0x18A54]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A54,
+ },
+ [0x18A55]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A55,
+ },
+ [0x18A56]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A56,
+ },
+ [0x18A57]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A57,
+ },
+ [0x18A58]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A58,
+ },
+ [0x18A59]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A59,
+ },
+ [0x18A5A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A5A,
+ },
+ [0x18A5B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A5B,
+ },
+ [0x18A5C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A5C,
+ },
+ [0x18A5D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A5D,
+ },
+ [0x18A5E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A5E,
+ },
+ [0x18A5F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A5F,
+ },
+ [0x18A60]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A60,
+ },
+ [0x18A61]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A61,
+ },
+ [0x18A62]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A62,
+ },
+ [0x18A63]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A63,
+ },
+ [0x18A64]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A64,
+ },
+ [0x18A65]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A65,
+ },
+ [0x18A66]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A66,
+ },
+ [0x18A67]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A67,
+ },
+ [0x18A68]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A68,
+ },
+ [0x18A69]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A69,
+ },
+ [0x18A6A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A6A,
+ },
+ [0x18A6B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A6B,
+ },
+ [0x18A6C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A6C,
+ },
+ [0x18A6D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A6D,
+ },
+ [0x18A6E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A6E,
+ },
+ [0x18A6F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A6F,
+ },
+ [0x18A70]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A70,
+ },
+ [0x18A71]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A71,
+ },
+ [0x18A72]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A72,
+ },
+ [0x18A73]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A73,
+ },
+ [0x18A74]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A74,
+ },
+ [0x18A75]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A75,
+ },
+ [0x18A76]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A76,
+ },
+ [0x18A77]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A77,
+ },
+ [0x18A78]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A78,
+ },
+ [0x18A79]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A79,
+ },
+ [0x18A7A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A7A,
+ },
+ [0x18A7B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A7B,
+ },
+ [0x18A7C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A7C,
+ },
+ [0x18A7D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A7D,
+ },
+ [0x18A7E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A7E,
+ },
+ [0x18A7F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A7F,
+ },
+ [0x18A80]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A80,
+ },
+ [0x18A81]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A81,
+ },
+ [0x18A82]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A82,
+ },
+ [0x18A83]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A83,
+ },
+ [0x18A84]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A84,
+ },
+ [0x18A85]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A85,
+ },
+ [0x18A86]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A86,
+ },
+ [0x18A87]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A87,
+ },
+ [0x18A88]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A88,
+ },
+ [0x18A89]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A89,
+ },
+ [0x18A8A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A8A,
+ },
+ [0x18A8B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A8B,
+ },
+ [0x18A8C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A8C,
+ },
+ [0x18A8D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A8D,
+ },
+ [0x18A8E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A8E,
+ },
+ [0x18A8F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A8F,
+ },
+ [0x18A90]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A90,
+ },
+ [0x18A91]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A91,
+ },
+ [0x18A92]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A92,
+ },
+ [0x18A93]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A93,
+ },
+ [0x18A94]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A94,
+ },
+ [0x18A95]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A95,
+ },
+ [0x18A96]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A96,
+ },
+ [0x18A97]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A97,
+ },
+ [0x18A98]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A98,
+ },
+ [0x18A99]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A99,
+ },
+ [0x18A9A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A9A,
+ },
+ [0x18A9B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A9B,
+ },
+ [0x18A9C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A9C,
+ },
+ [0x18A9D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A9D,
+ },
+ [0x18A9E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A9E,
+ },
+ [0x18A9F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18A9F,
+ },
+ [0x18AA0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AA0,
+ },
+ [0x18AA1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AA1,
+ },
+ [0x18AA2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AA2,
+ },
+ [0x18AA3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AA3,
+ },
+ [0x18AA4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AA4,
+ },
+ [0x18AA5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AA5,
+ },
+ [0x18AA6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AA6,
+ },
+ [0x18AA7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AA7,
+ },
+ [0x18AA8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AA8,
+ },
+ [0x18AA9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AA9,
+ },
+ [0x18AAA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AAA,
+ },
+ [0x18AAB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AAB,
+ },
+ [0x18AAC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AAC,
+ },
+ [0x18AAD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AAD,
+ },
+ [0x18AAE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AAE,
+ },
+ [0x18AAF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AAF,
+ },
+ [0x18AB0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AB0,
+ },
+ [0x18AB1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AB1,
+ },
+ [0x18AB2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AB2,
+ },
+ [0x18AB3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AB3,
+ },
+ [0x18AB4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AB4,
+ },
+ [0x18AB5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AB5,
+ },
+ [0x18AB6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AB6,
+ },
+ [0x18AB7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AB7,
+ },
+ [0x18AB8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AB8,
+ },
+ [0x18AB9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AB9,
+ },
+ [0x18ABA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ABA,
+ },
+ [0x18ABB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ABB,
+ },
+ [0x18ABC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ABC,
+ },
+ [0x18ABD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ABD,
+ },
+ [0x18ABE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ABE,
+ },
+ [0x18ABF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ABF,
+ },
+ [0x18AC0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AC0,
+ },
+ [0x18AC1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AC1,
+ },
+ [0x18AC2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AC2,
+ },
+ [0x18AC3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AC3,
+ },
+ [0x18AC4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AC4,
+ },
+ [0x18AC5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AC5,
+ },
+ [0x18AC6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AC6,
+ },
+ [0x18AC7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AC7,
+ },
+ [0x18AC8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AC8,
+ },
+ [0x18AC9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AC9,
+ },
+ [0x18ACA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ACA,
+ },
+ [0x18ACB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ACB,
+ },
+ [0x18ACC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ACC,
+ },
+ [0x18ACD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ACD,
+ },
+ [0x18ACE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ACE,
+ },
+ [0x18ACF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ACF,
+ },
+ [0x18AD0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AD0,
+ },
+ [0x18AD1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AD1,
+ },
+ [0x18AD2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AD2,
+ },
+ [0x18AD3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AD3,
+ },
+ [0x18AD4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AD4,
+ },
+ [0x18AD5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AD5,
+ },
+ [0x18AD6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AD6,
+ },
+ [0x18AD7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AD7,
+ },
+ [0x18AD8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AD8,
+ },
+ [0x18AD9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AD9,
+ },
+ [0x18ADA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ADA,
+ },
+ [0x18ADB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ADB,
+ },
+ [0x18ADC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ADC,
+ },
+ [0x18ADD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ADD,
+ },
+ [0x18ADE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ADE,
+ },
+ [0x18ADF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18ADF,
+ },
+ [0x18AE0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AE0,
+ },
+ [0x18AE1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AE1,
+ },
+ [0x18AE2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AE2,
+ },
+ [0x18AE3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AE3,
+ },
+ [0x18AE4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AE4,
+ },
+ [0x18AE5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AE5,
+ },
+ [0x18AE6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AE6,
+ },
+ [0x18AE7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AE7,
+ },
+ [0x18AE8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AE8,
+ },
+ [0x18AE9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AE9,
+ },
+ [0x18AEA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AEA,
+ },
+ [0x18AEB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AEB,
+ },
+ [0x18AEC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AEC,
+ },
+ [0x18AED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AED,
+ },
+ [0x18AEE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AEE,
+ },
+ [0x18AEF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AEF,
+ },
+ [0x18AF0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AF0,
+ },
+ [0x18AF1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AF1,
+ },
+ [0x18AF2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AF2,
+ },
+ [0x1B000]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B000,
+ },
+ [0x1B001]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B001,
+ },
+ [0x1B002]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B002,
+ },
+ [0x1B003]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B003,
+ },
+ [0x1B004]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B004,
+ },
+ [0x1B005]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B005,
+ },
+ [0x1B006]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B006,
+ },
+ [0x1B007]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B007,
+ },
+ [0x1B008]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B008,
+ },
+ [0x1B009]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B009,
+ },
+ [0x1B00A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B00A,
+ },
+ [0x1B00B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B00B,
+ },
+ [0x1B00C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B00C,
+ },
+ [0x1B00D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B00D,
+ },
+ [0x1B00E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B00E,
+ },
+ [0x1B00F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B00F,
+ },
+ [0x1B010]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B010,
+ },
+ [0x1B011]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B011,
+ },
+ [0x1B012]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B012,
+ },
+ [0x1B013]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B013,
+ },
+ [0x1B014]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B014,
+ },
+ [0x1B015]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B015,
+ },
+ [0x1B016]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B016,
+ },
+ [0x1B017]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B017,
+ },
+ [0x1B018]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B018,
+ },
+ [0x1B019]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B019,
+ },
+ [0x1B01A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B01A,
+ },
+ [0x1B01B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B01B,
+ },
+ [0x1B01C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B01C,
+ },
+ [0x1B01D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B01D,
+ },
+ [0x1B01E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B01E,
+ },
+ [0x1B01F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B01F,
+ },
+ [0x1B020]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B020,
+ },
+ [0x1B021]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B021,
+ },
+ [0x1B022]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B022,
+ },
+ [0x1B023]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B023,
+ },
+ [0x1B024]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B024,
+ },
+ [0x1B025]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B025,
+ },
+ [0x1B026]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B026,
+ },
+ [0x1B027]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B027,
+ },
+ [0x1B028]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B028,
+ },
+ [0x1B029]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B029,
+ },
+ [0x1B02A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B02A,
+ },
+ [0x1B02B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B02B,
+ },
+ [0x1B02C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B02C,
+ },
+ [0x1B02D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B02D,
+ },
+ [0x1B02E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B02E,
+ },
+ [0x1B02F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B02F,
+ },
+ [0x1B030]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B030,
+ },
+ [0x1B031]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B031,
+ },
+ [0x1B032]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B032,
+ },
+ [0x1B033]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B033,
+ },
+ [0x1B034]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B034,
+ },
+ [0x1B035]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B035,
+ },
+ [0x1B036]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B036,
+ },
+ [0x1B037]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B037,
+ },
+ [0x1B038]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B038,
+ },
+ [0x1B039]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B039,
+ },
+ [0x1B03A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B03A,
+ },
+ [0x1B03B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B03B,
+ },
+ [0x1B03C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B03C,
+ },
+ [0x1B03D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B03D,
+ },
+ [0x1B03E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B03E,
+ },
+ [0x1B03F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B03F,
+ },
+ [0x1B040]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B040,
+ },
+ [0x1B041]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B041,
+ },
+ [0x1B042]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B042,
+ },
+ [0x1B043]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B043,
+ },
+ [0x1B044]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B044,
+ },
+ [0x1B045]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B045,
+ },
+ [0x1B046]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B046,
+ },
+ [0x1B047]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B047,
+ },
+ [0x1B048]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B048,
+ },
+ [0x1B049]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B049,
+ },
+ [0x1B04A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B04A,
+ },
+ [0x1B04B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B04B,
+ },
+ [0x1B04C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B04C,
+ },
+ [0x1B04D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B04D,
+ },
+ [0x1B04E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B04E,
+ },
+ [0x1B04F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B04F,
+ },
+ [0x1B050]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B050,
+ },
+ [0x1B051]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B051,
+ },
+ [0x1B052]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B052,
+ },
+ [0x1B053]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B053,
+ },
+ [0x1B054]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B054,
+ },
+ [0x1B055]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B055,
+ },
+ [0x1B056]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B056,
+ },
+ [0x1B057]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B057,
+ },
+ [0x1B058]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B058,
+ },
+ [0x1B059]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B059,
+ },
+ [0x1B05A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B05A,
+ },
+ [0x1B05B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B05B,
+ },
+ [0x1B05C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B05C,
+ },
+ [0x1B05D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B05D,
+ },
+ [0x1B05E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B05E,
+ },
+ [0x1B05F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B05F,
+ },
+ [0x1B060]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B060,
+ },
+ [0x1B061]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B061,
+ },
+ [0x1B062]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B062,
+ },
+ [0x1B063]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B063,
+ },
+ [0x1B064]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B064,
+ },
+ [0x1B065]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B065,
+ },
+ [0x1B066]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B066,
+ },
+ [0x1B067]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B067,
+ },
+ [0x1B068]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B068,
+ },
+ [0x1B069]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B069,
+ },
+ [0x1B06A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B06A,
+ },
+ [0x1B06B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B06B,
+ },
+ [0x1B06C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B06C,
+ },
+ [0x1B06D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B06D,
+ },
+ [0x1B06E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B06E,
+ },
+ [0x1B06F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B06F,
+ },
+ [0x1B070]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B070,
+ },
+ [0x1B071]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B071,
+ },
+ [0x1B072]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B072,
+ },
+ [0x1B073]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B073,
+ },
+ [0x1B074]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B074,
+ },
+ [0x1B075]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B075,
+ },
+ [0x1B076]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B076,
+ },
+ [0x1B077]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B077,
+ },
+ [0x1B078]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B078,
+ },
+ [0x1B079]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B079,
+ },
+ [0x1B07A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B07A,
+ },
+ [0x1B07B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B07B,
+ },
+ [0x1B07C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B07C,
+ },
+ [0x1B07D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B07D,
+ },
+ [0x1B07E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B07E,
+ },
+ [0x1B07F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B07F,
+ },
+ [0x1B080]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B080,
+ },
+ [0x1B081]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B081,
+ },
+ [0x1B082]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B082,
+ },
+ [0x1B083]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B083,
+ },
+ [0x1B084]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B084,
+ },
+ [0x1B085]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B085,
+ },
+ [0x1B086]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B086,
+ },
+ [0x1B087]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B087,
+ },
+ [0x1B088]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B088,
+ },
+ [0x1B089]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B089,
+ },
+ [0x1B08A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B08A,
+ },
+ [0x1B08B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B08B,
+ },
+ [0x1B08C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B08C,
+ },
+ [0x1B08D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B08D,
+ },
+ [0x1B08E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B08E,
+ },
+ [0x1B08F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B08F,
+ },
+ [0x1B090]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B090,
+ },
+ [0x1B091]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B091,
+ },
+ [0x1B092]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B092,
+ },
+ [0x1B093]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B093,
+ },
+ [0x1B094]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B094,
+ },
+ [0x1B095]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B095,
+ },
+ [0x1B096]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B096,
+ },
+ [0x1B097]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B097,
+ },
+ [0x1B098]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B098,
+ },
+ [0x1B099]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B099,
+ },
+ [0x1B09A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B09A,
+ },
+ [0x1B09B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B09B,
+ },
+ [0x1B09C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B09C,
+ },
+ [0x1B09D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B09D,
+ },
+ [0x1B09E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B09E,
+ },
+ [0x1B09F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B09F,
+ },
+ [0x1B0A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0A0,
+ },
+ [0x1B0A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0A1,
+ },
+ [0x1B0A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0A2,
+ },
+ [0x1B0A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0A3,
+ },
+ [0x1B0A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0A4,
+ },
+ [0x1B0A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0A5,
+ },
+ [0x1B0A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0A6,
+ },
+ [0x1B0A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0A7,
+ },
+ [0x1B0A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0A8,
+ },
+ [0x1B0A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0A9,
+ },
+ [0x1B0AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0AA,
+ },
+ [0x1B0AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0AB,
+ },
+ [0x1B0AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0AC,
+ },
+ [0x1B0AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0AD,
+ },
+ [0x1B0AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0AE,
+ },
+ [0x1B0AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0AF,
+ },
+ [0x1B0B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0B0,
+ },
+ [0x1B0B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0B1,
+ },
+ [0x1B0B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0B2,
+ },
+ [0x1B0B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0B3,
+ },
+ [0x1B0B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0B4,
+ },
+ [0x1B0B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0B5,
+ },
+ [0x1B0B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0B6,
+ },
+ [0x1B0B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0B7,
+ },
+ [0x1B0B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0B8,
+ },
+ [0x1B0B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0B9,
+ },
+ [0x1B0BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0BA,
+ },
+ [0x1B0BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0BB,
+ },
+ [0x1B0BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0BC,
+ },
+ [0x1B0BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0BD,
+ },
+ [0x1B0BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0BE,
+ },
+ [0x1B0BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0BF,
+ },
+ [0x1B0C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0C0,
+ },
+ [0x1B0C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0C1,
+ },
+ [0x1B0C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0C2,
+ },
+ [0x1B0C3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0C3,
+ },
+ [0x1B0C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0C4,
+ },
+ [0x1B0C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0C5,
+ },
+ [0x1B0C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0C6,
+ },
+ [0x1B0C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0C7,
+ },
+ [0x1B0C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0C8,
+ },
+ [0x1B0C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0C9,
+ },
+ [0x1B0CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0CA,
+ },
+ [0x1B0CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0CB,
+ },
+ [0x1B0CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0CC,
+ },
+ [0x1B0CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0CD,
+ },
+ [0x1B0CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0CE,
+ },
+ [0x1B0CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0CF,
+ },
+ [0x1B0D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0D0,
+ },
+ [0x1B0D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0D1,
+ },
+ [0x1B0D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0D2,
+ },
+ [0x1B0D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0D3,
+ },
+ [0x1B0D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0D4,
+ },
+ [0x1B0D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0D5,
+ },
+ [0x1B0D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0D6,
+ },
+ [0x1B0D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0D7,
+ },
+ [0x1B0D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0D8,
+ },
+ [0x1B0D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0D9,
+ },
+ [0x1B0DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0DA,
+ },
+ [0x1B0DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0DB,
+ },
+ [0x1B0DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0DC,
+ },
+ [0x1B0DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0DD,
+ },
+ [0x1B0DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0DE,
+ },
+ [0x1B0DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0DF,
+ },
+ [0x1B0E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0E0,
+ },
+ [0x1B0E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0E1,
+ },
+ [0x1B0E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0E2,
+ },
+ [0x1B0E3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0E3,
+ },
+ [0x1B0E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0E4,
+ },
+ [0x1B0E5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0E5,
+ },
+ [0x1B0E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0E6,
+ },
+ [0x1B0E7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0E7,
+ },
+ [0x1B0E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0E8,
+ },
+ [0x1B0E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0E9,
+ },
+ [0x1B0EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0EA,
+ },
+ [0x1B0EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0EB,
+ },
+ [0x1B0EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0EC,
+ },
+ [0x1B0ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0ED,
+ },
+ [0x1B0EE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0EE,
+ },
+ [0x1B0EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0EF,
+ },
+ [0x1B0F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0F0,
+ },
+ [0x1B0F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0F1,
+ },
+ [0x1B0F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0F2,
+ },
+ [0x1B0F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0F3,
+ },
+ [0x1B0F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0F4,
+ },
+ [0x1B0F5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0F5,
+ },
+ [0x1B0F6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0F6,
+ },
+ [0x1B0F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0F7,
+ },
+ [0x1B0F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0F8,
+ },
+ [0x1B0F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0F9,
+ },
+ [0x1B0FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0FA,
+ },
+ [0x1B0FB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0FB,
+ },
+ [0x1B0FC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0FC,
+ },
+ [0x1B0FD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0FD,
+ },
+ [0x1B0FE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0FE,
+ },
+ [0x1B0FF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B0FF,
+ },
+ [0x1B100]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B100,
+ },
+ [0x1B101]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B101,
+ },
+ [0x1B102]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B102,
+ },
+ [0x1B103]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B103,
+ },
+ [0x1B104]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B104,
+ },
+ [0x1B105]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B105,
+ },
+ [0x1B106]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B106,
+ },
+ [0x1B107]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B107,
+ },
+ [0x1B108]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B108,
+ },
+ [0x1B109]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B109,
+ },
+ [0x1B10A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B10A,
+ },
+ [0x1B10B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B10B,
+ },
+ [0x1B10C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B10C,
+ },
+ [0x1B10D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B10D,
+ },
+ [0x1B10E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B10E,
+ },
+ [0x1B10F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B10F,
+ },
+ [0x1B110]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B110,
+ },
+ [0x1B111]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B111,
+ },
+ [0x1B112]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B112,
+ },
+ [0x1B113]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B113,
+ },
+ [0x1B114]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B114,
+ },
+ [0x1B115]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B115,
+ },
+ [0x1B116]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B116,
+ },
+ [0x1B117]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B117,
+ },
+ [0x1B118]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B118,
+ },
+ [0x1B119]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B119,
+ },
+ [0x1B11A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B11A,
+ },
+ [0x1B11B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B11B,
+ },
+ [0x1B11C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B11C,
+ },
+ [0x1B11D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B11D,
+ },
+ [0x1B11E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B11E,
+ },
+ [0x1B150]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x1B150,
+ },
+ [0x1B151]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x1B151,
+ },
+ [0x1B152]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x1B152,
+ },
+ [0x1B164]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x1B164,
+ },
+ [0x1B165]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x1B165,
+ },
+ [0x1B166]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x1B166,
+ },
+ [0x1B167]={
+ category="lo",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x1B167,
+ },
+ [0x1B170]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B170,
+ },
+ [0x1B171]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B171,
+ },
+ [0x1B172]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B172,
+ },
+ [0x1B173]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B173,
+ },
+ [0x1B174]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B174,
+ },
+ [0x1B175]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B175,
+ },
+ [0x1B176]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B176,
+ },
+ [0x1B177]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B177,
+ },
+ [0x1B178]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B178,
+ },
+ [0x1B179]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B179,
+ },
+ [0x1B17A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B17A,
+ },
+ [0x1B17B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B17B,
+ },
+ [0x1B17C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B17C,
+ },
+ [0x1B17D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B17D,
+ },
+ [0x1B17E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B17E,
+ },
+ [0x1B17F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B17F,
+ },
+ [0x1B180]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B180,
+ },
+ [0x1B181]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B181,
+ },
+ [0x1B182]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B182,
+ },
+ [0x1B183]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B183,
+ },
+ [0x1B184]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B184,
+ },
+ [0x1B185]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B185,
+ },
+ [0x1B186]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B186,
+ },
+ [0x1B187]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B187,
+ },
+ [0x1B188]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B188,
+ },
+ [0x1B189]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B189,
+ },
+ [0x1B18A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B18A,
+ },
+ [0x1B18B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B18B,
+ },
+ [0x1B18C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B18C,
+ },
+ [0x1B18D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B18D,
+ },
+ [0x1B18E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B18E,
+ },
+ [0x1B18F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B18F,
+ },
+ [0x1B190]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B190,
+ },
+ [0x1B191]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B191,
+ },
+ [0x1B192]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B192,
+ },
+ [0x1B193]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B193,
+ },
+ [0x1B194]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B194,
+ },
+ [0x1B195]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B195,
+ },
+ [0x1B196]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B196,
+ },
+ [0x1B197]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B197,
+ },
+ [0x1B198]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B198,
+ },
+ [0x1B199]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B199,
+ },
+ [0x1B19A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B19A,
+ },
+ [0x1B19B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B19B,
+ },
+ [0x1B19C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B19C,
+ },
+ [0x1B19D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B19D,
+ },
+ [0x1B19E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B19E,
+ },
+ [0x1B19F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B19F,
+ },
+ [0x1B1A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1A0,
+ },
+ [0x1B1A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1A1,
+ },
+ [0x1B1A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1A2,
+ },
+ [0x1B1A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1A3,
+ },
+ [0x1B1A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1A4,
+ },
+ [0x1B1A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1A5,
+ },
+ [0x1B1A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1A6,
+ },
+ [0x1B1A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1A7,
+ },
+ [0x1B1A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1A8,
+ },
+ [0x1B1A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1A9,
+ },
+ [0x1B1AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1AA,
+ },
+ [0x1B1AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1AB,
+ },
+ [0x1B1AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1AC,
+ },
+ [0x1B1AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1AD,
+ },
+ [0x1B1AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1AE,
+ },
+ [0x1B1AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1AF,
+ },
+ [0x1B1B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1B0,
+ },
+ [0x1B1B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1B1,
+ },
+ [0x1B1B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1B2,
+ },
+ [0x1B1B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1B3,
+ },
+ [0x1B1B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1B4,
+ },
+ [0x1B1B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1B5,
+ },
+ [0x1B1B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1B6,
+ },
+ [0x1B1B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1B7,
+ },
+ [0x1B1B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1B8,
+ },
+ [0x1B1B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1B9,
+ },
+ [0x1B1BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1BA,
+ },
+ [0x1B1BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1BB,
+ },
+ [0x1B1BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1BC,
+ },
+ [0x1B1BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1BD,
+ },
+ [0x1B1BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1BE,
+ },
+ [0x1B1BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1BF,
+ },
+ [0x1B1C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1C0,
+ },
+ [0x1B1C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1C1,
+ },
+ [0x1B1C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1C2,
+ },
+ [0x1B1C3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1C3,
+ },
+ [0x1B1C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1C4,
+ },
+ [0x1B1C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1C5,
+ },
+ [0x1B1C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1C6,
+ },
+ [0x1B1C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1C7,
+ },
+ [0x1B1C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1C8,
+ },
+ [0x1B1C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1C9,
+ },
+ [0x1B1CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1CA,
+ },
+ [0x1B1CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1CB,
+ },
+ [0x1B1CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1CC,
+ },
+ [0x1B1CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1CD,
+ },
+ [0x1B1CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1CE,
+ },
+ [0x1B1CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1CF,
+ },
+ [0x1B1D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1D0,
+ },
+ [0x1B1D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1D1,
+ },
+ [0x1B1D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1D2,
+ },
+ [0x1B1D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1D3,
+ },
+ [0x1B1D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1D4,
+ },
+ [0x1B1D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1D5,
+ },
+ [0x1B1D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1D6,
+ },
+ [0x1B1D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1D7,
+ },
+ [0x1B1D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1D8,
+ },
+ [0x1B1D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1D9,
+ },
+ [0x1B1DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1DA,
+ },
+ [0x1B1DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1DB,
+ },
+ [0x1B1DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1DC,
+ },
+ [0x1B1DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1DD,
+ },
+ [0x1B1DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1DE,
+ },
+ [0x1B1DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1DF,
+ },
+ [0x1B1E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1E0,
+ },
+ [0x1B1E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1E1,
+ },
+ [0x1B1E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1E2,
+ },
+ [0x1B1E3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1E3,
+ },
+ [0x1B1E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1E4,
+ },
+ [0x1B1E5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1E5,
+ },
+ [0x1B1E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1E6,
+ },
+ [0x1B1E7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1E7,
+ },
+ [0x1B1E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1E8,
+ },
+ [0x1B1E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1E9,
+ },
+ [0x1B1EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1EA,
+ },
+ [0x1B1EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1EB,
+ },
+ [0x1B1EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1EC,
+ },
+ [0x1B1ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1ED,
+ },
+ [0x1B1EE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1EE,
+ },
+ [0x1B1EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1EF,
+ },
+ [0x1B1F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1F0,
+ },
+ [0x1B1F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1F1,
+ },
+ [0x1B1F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1F2,
+ },
+ [0x1B1F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1F3,
+ },
+ [0x1B1F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1F4,
+ },
+ [0x1B1F5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1F5,
+ },
+ [0x1B1F6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1F6,
+ },
+ [0x1B1F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1F7,
+ },
+ [0x1B1F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1F8,
+ },
+ [0x1B1F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1F9,
+ },
+ [0x1B1FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1FA,
+ },
+ [0x1B1FB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1FB,
+ },
+ [0x1B1FC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1FC,
+ },
+ [0x1B1FD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1FD,
+ },
+ [0x1B1FE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1FE,
+ },
+ [0x1B1FF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B1FF,
+ },
+ [0x1B200]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B200,
+ },
+ [0x1B201]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B201,
+ },
+ [0x1B202]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B202,
+ },
+ [0x1B203]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B203,
+ },
+ [0x1B204]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B204,
+ },
+ [0x1B205]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B205,
+ },
+ [0x1B206]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B206,
+ },
+ [0x1B207]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B207,
+ },
+ [0x1B208]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B208,
+ },
+ [0x1B209]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B209,
+ },
+ [0x1B20A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B20A,
+ },
+ [0x1B20B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B20B,
+ },
+ [0x1B20C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B20C,
+ },
+ [0x1B20D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B20D,
+ },
+ [0x1B20E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B20E,
+ },
+ [0x1B20F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B20F,
+ },
+ [0x1B210]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B210,
+ },
+ [0x1B211]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B211,
+ },
+ [0x1B212]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B212,
+ },
+ [0x1B213]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B213,
+ },
+ [0x1B214]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B214,
+ },
+ [0x1B215]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B215,
+ },
+ [0x1B216]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B216,
+ },
+ [0x1B217]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B217,
+ },
+ [0x1B218]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B218,
+ },
+ [0x1B219]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B219,
+ },
+ [0x1B21A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B21A,
+ },
+ [0x1B21B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B21B,
+ },
+ [0x1B21C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B21C,
+ },
+ [0x1B21D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B21D,
+ },
+ [0x1B21E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B21E,
+ },
+ [0x1B21F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B21F,
+ },
+ [0x1B220]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B220,
+ },
+ [0x1B221]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B221,
+ },
+ [0x1B222]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B222,
+ },
+ [0x1B223]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B223,
+ },
+ [0x1B224]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B224,
+ },
+ [0x1B225]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B225,
+ },
+ [0x1B226]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B226,
+ },
+ [0x1B227]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B227,
+ },
+ [0x1B228]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B228,
+ },
+ [0x1B229]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B229,
+ },
+ [0x1B22A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B22A,
+ },
+ [0x1B22B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B22B,
+ },
+ [0x1B22C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B22C,
+ },
+ [0x1B22D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B22D,
+ },
+ [0x1B22E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B22E,
+ },
+ [0x1B22F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B22F,
+ },
+ [0x1B230]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B230,
+ },
+ [0x1B231]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B231,
+ },
+ [0x1B232]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B232,
+ },
+ [0x1B233]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B233,
+ },
+ [0x1B234]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B234,
+ },
+ [0x1B235]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B235,
+ },
+ [0x1B236]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B236,
+ },
+ [0x1B237]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B237,
+ },
+ [0x1B238]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B238,
+ },
+ [0x1B239]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B239,
+ },
+ [0x1B23A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B23A,
+ },
+ [0x1B23B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B23B,
+ },
+ [0x1B23C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B23C,
+ },
+ [0x1B23D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B23D,
+ },
+ [0x1B23E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B23E,
+ },
+ [0x1B23F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B23F,
+ },
+ [0x1B240]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B240,
+ },
+ [0x1B241]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B241,
+ },
+ [0x1B242]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B242,
+ },
+ [0x1B243]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B243,
+ },
+ [0x1B244]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B244,
+ },
+ [0x1B245]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B245,
+ },
+ [0x1B246]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B246,
+ },
+ [0x1B247]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B247,
+ },
+ [0x1B248]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B248,
+ },
+ [0x1B249]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B249,
+ },
+ [0x1B24A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B24A,
+ },
+ [0x1B24B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B24B,
+ },
+ [0x1B24C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B24C,
+ },
+ [0x1B24D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B24D,
+ },
+ [0x1B24E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B24E,
+ },
+ [0x1B24F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B24F,
+ },
+ [0x1B250]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B250,
+ },
+ [0x1B251]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B251,
+ },
+ [0x1B252]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B252,
+ },
+ [0x1B253]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B253,
+ },
+ [0x1B254]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B254,
+ },
+ [0x1B255]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B255,
+ },
+ [0x1B256]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B256,
+ },
+ [0x1B257]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B257,
+ },
+ [0x1B258]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B258,
+ },
+ [0x1B259]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B259,
+ },
+ [0x1B25A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B25A,
+ },
+ [0x1B25B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B25B,
+ },
+ [0x1B25C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B25C,
+ },
+ [0x1B25D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B25D,
+ },
+ [0x1B25E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B25E,
+ },
+ [0x1B25F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B25F,
+ },
+ [0x1B260]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B260,
+ },
+ [0x1B261]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B261,
+ },
+ [0x1B262]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B262,
+ },
+ [0x1B263]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B263,
+ },
+ [0x1B264]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B264,
+ },
+ [0x1B265]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B265,
+ },
+ [0x1B266]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B266,
+ },
+ [0x1B267]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B267,
+ },
+ [0x1B268]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B268,
+ },
+ [0x1B269]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B269,
+ },
+ [0x1B26A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B26A,
+ },
+ [0x1B26B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B26B,
+ },
+ [0x1B26C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B26C,
+ },
+ [0x1B26D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B26D,
+ },
+ [0x1B26E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B26E,
+ },
+ [0x1B26F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B26F,
+ },
+ [0x1B270]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B270,
+ },
+ [0x1B271]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B271,
+ },
+ [0x1B272]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B272,
+ },
+ [0x1B273]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B273,
+ },
+ [0x1B274]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B274,
+ },
+ [0x1B275]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B275,
+ },
+ [0x1B276]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B276,
+ },
+ [0x1B277]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B277,
+ },
+ [0x1B278]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B278,
+ },
+ [0x1B279]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B279,
+ },
+ [0x1B27A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B27A,
+ },
+ [0x1B27B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B27B,
+ },
+ [0x1B27C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B27C,
+ },
+ [0x1B27D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B27D,
+ },
+ [0x1B27E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B27E,
+ },
+ [0x1B27F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B27F,
+ },
+ [0x1B280]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B280,
+ },
+ [0x1B281]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B281,
+ },
+ [0x1B282]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B282,
+ },
+ [0x1B283]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B283,
+ },
+ [0x1B284]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B284,
+ },
+ [0x1B285]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B285,
+ },
+ [0x1B286]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B286,
+ },
+ [0x1B287]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B287,
+ },
+ [0x1B288]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B288,
+ },
+ [0x1B289]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B289,
+ },
+ [0x1B28A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B28A,
+ },
+ [0x1B28B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B28B,
+ },
+ [0x1B28C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B28C,
+ },
+ [0x1B28D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B28D,
+ },
+ [0x1B28E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B28E,
+ },
+ [0x1B28F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B28F,
+ },
+ [0x1B290]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B290,
+ },
+ [0x1B291]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B291,
+ },
+ [0x1B292]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B292,
+ },
+ [0x1B293]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B293,
+ },
+ [0x1B294]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B294,
+ },
+ [0x1B295]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B295,
+ },
+ [0x1B296]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B296,
+ },
+ [0x1B297]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B297,
+ },
+ [0x1B298]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B298,
+ },
+ [0x1B299]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B299,
+ },
+ [0x1B29A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B29A,
+ },
+ [0x1B29B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B29B,
+ },
+ [0x1B29C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B29C,
+ },
+ [0x1B29D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B29D,
+ },
+ [0x1B29E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B29E,
+ },
+ [0x1B29F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B29F,
+ },
+ [0x1B2A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2A0,
+ },
+ [0x1B2A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2A1,
+ },
+ [0x1B2A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2A2,
+ },
+ [0x1B2A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2A3,
+ },
+ [0x1B2A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2A4,
+ },
+ [0x1B2A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2A5,
+ },
+ [0x1B2A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2A6,
+ },
+ [0x1B2A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2A7,
+ },
+ [0x1B2A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2A8,
+ },
+ [0x1B2A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2A9,
+ },
+ [0x1B2AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2AA,
+ },
+ [0x1B2AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2AB,
+ },
+ [0x1B2AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2AC,
+ },
+ [0x1B2AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2AD,
+ },
+ [0x1B2AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2AE,
+ },
+ [0x1B2AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2AF,
+ },
+ [0x1B2B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2B0,
+ },
+ [0x1B2B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2B1,
+ },
+ [0x1B2B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2B2,
+ },
+ [0x1B2B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2B3,
+ },
+ [0x1B2B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2B4,
+ },
+ [0x1B2B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2B5,
+ },
+ [0x1B2B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2B6,
+ },
+ [0x1B2B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2B7,
+ },
+ [0x1B2B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2B8,
+ },
+ [0x1B2B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2B9,
+ },
+ [0x1B2BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2BA,
+ },
+ [0x1B2BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2BB,
+ },
+ [0x1B2BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2BC,
+ },
+ [0x1B2BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2BD,
+ },
+ [0x1B2BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2BE,
+ },
+ [0x1B2BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2BF,
+ },
+ [0x1B2C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2C0,
+ },
+ [0x1B2C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2C1,
+ },
+ [0x1B2C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2C2,
+ },
+ [0x1B2C3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2C3,
+ },
+ [0x1B2C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2C4,
+ },
+ [0x1B2C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2C5,
+ },
+ [0x1B2C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2C6,
+ },
+ [0x1B2C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2C7,
+ },
+ [0x1B2C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2C8,
+ },
+ [0x1B2C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2C9,
+ },
+ [0x1B2CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2CA,
+ },
+ [0x1B2CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2CB,
+ },
+ [0x1B2CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2CC,
+ },
+ [0x1B2CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2CD,
+ },
+ [0x1B2CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2CE,
+ },
+ [0x1B2CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2CF,
+ },
+ [0x1B2D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2D0,
+ },
+ [0x1B2D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2D1,
+ },
+ [0x1B2D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2D2,
+ },
+ [0x1B2D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2D3,
+ },
+ [0x1B2D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2D4,
+ },
+ [0x1B2D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2D5,
+ },
+ [0x1B2D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2D6,
+ },
+ [0x1B2D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2D7,
+ },
+ [0x1B2D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2D8,
+ },
+ [0x1B2D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2D9,
+ },
+ [0x1B2DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2DA,
+ },
+ [0x1B2DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2DB,
+ },
+ [0x1B2DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2DC,
+ },
+ [0x1B2DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2DD,
+ },
+ [0x1B2DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2DE,
+ },
+ [0x1B2DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2DF,
+ },
+ [0x1B2E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2E0,
+ },
+ [0x1B2E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2E1,
+ },
+ [0x1B2E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2E2,
+ },
+ [0x1B2E3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2E3,
+ },
+ [0x1B2E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2E4,
+ },
+ [0x1B2E5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2E5,
+ },
+ [0x1B2E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2E6,
+ },
+ [0x1B2E7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2E7,
+ },
+ [0x1B2E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2E8,
+ },
+ [0x1B2E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2E9,
+ },
+ [0x1B2EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2EA,
+ },
+ [0x1B2EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2EB,
+ },
+ [0x1B2EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2EC,
+ },
+ [0x1B2ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2ED,
+ },
+ [0x1B2EE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2EE,
+ },
+ [0x1B2EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2EF,
+ },
+ [0x1B2F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2F0,
+ },
+ [0x1B2F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2F1,
+ },
+ [0x1B2F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2F2,
+ },
+ [0x1B2F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2F3,
+ },
+ [0x1B2F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2F4,
+ },
+ [0x1B2F5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2F5,
+ },
+ [0x1B2F6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2F6,
+ },
+ [0x1B2F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2F7,
+ },
+ [0x1B2F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2F8,
+ },
+ [0x1B2F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2F9,
+ },
+ [0x1B2FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2FA,
+ },
+ [0x1B2FB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B2FB,
+ },
+ [0x1BC00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC00,
+ },
+ [0x1BC01]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC01,
+ },
+ [0x1BC02]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC02,
+ },
+ [0x1BC03]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC03,
+ },
+ [0x1BC04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC04,
+ },
+ [0x1BC05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC05,
+ },
+ [0x1BC06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC06,
+ },
+ [0x1BC07]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC07,
+ },
+ [0x1BC08]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC08,
+ },
+ [0x1BC09]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC09,
+ },
+ [0x1BC0A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC0A,
+ },
+ [0x1BC0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC0B,
+ },
+ [0x1BC0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC0C,
+ },
+ [0x1BC0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC0D,
+ },
+ [0x1BC0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC0E,
+ },
+ [0x1BC0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC0F,
+ },
+ [0x1BC10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC10,
+ },
+ [0x1BC11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC11,
+ },
+ [0x1BC12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC12,
+ },
+ [0x1BC13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC13,
+ },
+ [0x1BC14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC14,
+ },
+ [0x1BC15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC15,
+ },
+ [0x1BC16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC16,
+ },
+ [0x1BC17]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC17,
+ },
+ [0x1BC18]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC18,
+ },
+ [0x1BC19]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC19,
+ },
+ [0x1BC1A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC1A,
+ },
+ [0x1BC1B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC1B,
+ },
+ [0x1BC1C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC1C,
+ },
+ [0x1BC1D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC1D,
+ },
+ [0x1BC1E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC1E,
+ },
+ [0x1BC1F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC1F,
+ },
+ [0x1BC20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC20,
+ },
+ [0x1BC21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC21,
+ },
+ [0x1BC22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC22,
+ },
+ [0x1BC23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC23,
+ },
+ [0x1BC24]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC24,
+ },
+ [0x1BC25]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC25,
+ },
+ [0x1BC26]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC26,
+ },
+ [0x1BC27]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC27,
+ },
+ [0x1BC28]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC28,
+ },
+ [0x1BC29]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC29,
+ },
+ [0x1BC2A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC2A,
+ },
+ [0x1BC2B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC2B,
+ },
+ [0x1BC2C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC2C,
+ },
+ [0x1BC2D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC2D,
+ },
+ [0x1BC2E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC2E,
+ },
+ [0x1BC2F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC2F,
+ },
+ [0x1BC30]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC30,
+ },
+ [0x1BC31]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC31,
+ },
+ [0x1BC32]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC32,
+ },
+ [0x1BC33]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC33,
+ },
+ [0x1BC34]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC34,
+ },
+ [0x1BC35]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC35,
+ },
+ [0x1BC36]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC36,
+ },
+ [0x1BC37]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC37,
+ },
+ [0x1BC38]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC38,
+ },
+ [0x1BC39]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC39,
+ },
+ [0x1BC3A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC3A,
+ },
+ [0x1BC3B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC3B,
+ },
+ [0x1BC3C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC3C,
+ },
+ [0x1BC3D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC3D,
+ },
+ [0x1BC3E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC3E,
+ },
+ [0x1BC3F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC3F,
+ },
+ [0x1BC40]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC40,
+ },
+ [0x1BC41]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC41,
+ },
+ [0x1BC42]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC42,
+ },
+ [0x1BC43]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC43,
+ },
+ [0x1BC44]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC44,
+ },
+ [0x1BC45]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC45,
+ },
+ [0x1BC46]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC46,
+ },
+ [0x1BC47]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC47,
+ },
+ [0x1BC48]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC48,
+ },
+ [0x1BC49]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC49,
+ },
+ [0x1BC4A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC4A,
+ },
+ [0x1BC4B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC4B,
+ },
+ [0x1BC4C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC4C,
+ },
+ [0x1BC4D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC4D,
+ },
+ [0x1BC4E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC4E,
+ },
+ [0x1BC4F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC4F,
+ },
+ [0x1BC50]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC50,
+ },
+ [0x1BC51]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC51,
+ },
+ [0x1BC52]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC52,
+ },
+ [0x1BC53]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC53,
+ },
+ [0x1BC54]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC54,
+ },
+ [0x1BC55]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC55,
+ },
+ [0x1BC56]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC56,
+ },
+ [0x1BC57]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC57,
+ },
+ [0x1BC58]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC58,
+ },
+ [0x1BC59]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC59,
+ },
+ [0x1BC5A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC5A,
+ },
+ [0x1BC5B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC5B,
+ },
+ [0x1BC5C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC5C,
+ },
+ [0x1BC5D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC5D,
+ },
+ [0x1BC5E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC5E,
+ },
+ [0x1BC5F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC5F,
+ },
+ [0x1BC60]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC60,
+ },
+ [0x1BC61]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC61,
+ },
+ [0x1BC62]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC62,
+ },
+ [0x1BC63]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC63,
+ },
+ [0x1BC64]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC64,
+ },
+ [0x1BC65]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC65,
+ },
+ [0x1BC66]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC66,
+ },
+ [0x1BC67]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC67,
+ },
+ [0x1BC68]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC68,
+ },
+ [0x1BC69]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC69,
+ },
+ [0x1BC6A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC6A,
+ },
+ [0x1BC70]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC70,
+ },
+ [0x1BC71]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC71,
+ },
+ [0x1BC72]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC72,
+ },
+ [0x1BC73]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC73,
+ },
+ [0x1BC74]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC74,
+ },
+ [0x1BC75]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC75,
+ },
+ [0x1BC76]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC76,
+ },
+ [0x1BC77]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC77,
+ },
+ [0x1BC78]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC78,
+ },
+ [0x1BC79]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC79,
+ },
+ [0x1BC7A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC7A,
+ },
+ [0x1BC7B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC7B,
+ },
+ [0x1BC7C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC7C,
+ },
+ [0x1BC80]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC80,
+ },
+ [0x1BC81]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC81,
+ },
+ [0x1BC82]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC82,
+ },
+ [0x1BC83]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC83,
+ },
+ [0x1BC84]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC84,
+ },
+ [0x1BC85]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC85,
+ },
+ [0x1BC86]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC86,
+ },
+ [0x1BC87]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC87,
+ },
+ [0x1BC88]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC88,
+ },
+ [0x1BC90]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC90,
+ },
+ [0x1BC91]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC91,
+ },
+ [0x1BC92]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC92,
+ },
+ [0x1BC93]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC93,
+ },
+ [0x1BC94]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC94,
+ },
+ [0x1BC95]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC95,
+ },
+ [0x1BC96]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC96,
+ },
+ [0x1BC97]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC97,
+ },
+ [0x1BC98]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC98,
+ },
+ [0x1BC99]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC99,
+ },
+ [0x1BC9C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC9C,
+ },
+ [0x1BC9D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BC9D,
+ },
+ [0x1BC9E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BC9E,
+ },
+ [0x1BC9F]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1BC9F,
+ },
+ [0x1BCA0]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1BCA0,
+ },
+ [0x1BCA1]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1BCA1,
+ },
+ [0x1BCA2]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1BCA2,
+ },
+ [0x1BCA3]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1BCA3,
+ },
+ [0x1D000]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D000,
+ },
+ [0x1D001]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D001,
+ },
+ [0x1D002]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D002,
+ },
+ [0x1D003]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D003,
+ },
+ [0x1D004]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D004,
+ },
+ [0x1D005]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D005,
+ },
+ [0x1D006]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D006,
+ },
+ [0x1D007]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D007,
+ },
+ [0x1D008]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D008,
+ },
+ [0x1D009]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D009,
+ },
+ [0x1D00A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00A,
+ },
+ [0x1D00B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00B,
+ },
+ [0x1D00C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00C,
+ },
+ [0x1D00D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00D,
+ },
+ [0x1D00E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00E,
+ },
+ [0x1D00F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00F,
+ },
+ [0x1D010]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D010,
+ },
+ [0x1D011]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D011,
+ },
+ [0x1D012]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D012,
+ },
+ [0x1D013]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D013,
+ },
+ [0x1D014]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D014,
+ },
+ [0x1D015]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D015,
+ },
+ [0x1D016]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D016,
+ },
+ [0x1D017]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D017,
+ },
+ [0x1D018]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D018,
+ },
+ [0x1D019]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D019,
+ },
+ [0x1D01A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01A,
+ },
+ [0x1D01B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01B,
+ },
+ [0x1D01C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01C,
+ },
+ [0x1D01D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01D,
+ },
+ [0x1D01E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01E,
+ },
+ [0x1D01F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01F,
+ },
+ [0x1D020]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D020,
+ },
+ [0x1D021]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D021,
+ },
+ [0x1D022]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D022,
+ },
+ [0x1D023]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D023,
+ },
+ [0x1D024]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D024,
+ },
+ [0x1D025]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D025,
+ },
+ [0x1D026]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D026,
+ },
+ [0x1D027]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D027,
+ },
+ [0x1D028]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D028,
+ },
+ [0x1D029]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D029,
+ },
+ [0x1D02A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02A,
+ },
+ [0x1D02B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02B,
+ },
+ [0x1D02C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02C,
+ },
+ [0x1D02D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02D,
+ },
+ [0x1D02E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02E,
+ },
+ [0x1D02F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02F,
+ },
+ [0x1D030]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D030,
+ },
+ [0x1D031]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D031,
+ },
+ [0x1D032]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D032,
+ },
+ [0x1D033]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D033,
+ },
+ [0x1D034]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D034,
+ },
+ [0x1D035]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D035,
+ },
+ [0x1D036]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D036,
+ },
+ [0x1D037]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D037,
+ },
+ [0x1D038]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D038,
+ },
+ [0x1D039]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D039,
+ },
+ [0x1D03A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03A,
+ },
+ [0x1D03B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03B,
+ },
+ [0x1D03C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03C,
+ },
+ [0x1D03D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03D,
+ },
+ [0x1D03E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03E,
+ },
+ [0x1D03F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03F,
+ },
+ [0x1D040]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D040,
+ },
+ [0x1D041]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D041,
+ },
+ [0x1D042]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D042,
+ },
+ [0x1D043]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D043,
+ },
+ [0x1D044]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D044,
+ },
+ [0x1D045]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D045,
+ },
+ [0x1D046]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D046,
+ },
+ [0x1D047]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D047,
+ },
+ [0x1D048]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D048,
+ },
+ [0x1D049]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D049,
+ },
+ [0x1D04A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04A,
+ },
+ [0x1D04B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04B,
+ },
+ [0x1D04C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04C,
+ },
+ [0x1D04D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04D,
+ },
+ [0x1D04E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04E,
+ },
+ [0x1D04F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04F,
+ },
+ [0x1D050]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D050,
+ },
+ [0x1D051]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D051,
+ },
+ [0x1D052]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D052,
+ },
+ [0x1D053]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D053,
+ },
+ [0x1D054]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D054,
+ },
+ [0x1D055]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D055,
+ },
+ [0x1D056]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D056,
+ },
+ [0x1D057]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D057,
+ },
+ [0x1D058]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D058,
+ },
+ [0x1D059]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D059,
+ },
+ [0x1D05A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05A,
+ },
+ [0x1D05B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05B,
+ },
+ [0x1D05C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05C,
+ },
+ [0x1D05D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05D,
+ },
+ [0x1D05E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05E,
+ },
+ [0x1D05F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05F,
+ },
+ [0x1D060]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D060,
+ },
+ [0x1D061]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D061,
+ },
+ [0x1D062]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D062,
+ },
+ [0x1D063]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D063,
+ },
+ [0x1D064]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D064,
+ },
+ [0x1D065]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D065,
+ },
+ [0x1D066]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D066,
+ },
+ [0x1D067]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D067,
+ },
+ [0x1D068]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D068,
+ },
+ [0x1D069]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D069,
+ },
+ [0x1D06A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06A,
+ },
+ [0x1D06B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06B,
+ },
+ [0x1D06C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06C,
+ },
+ [0x1D06D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06D,
+ },
+ [0x1D06E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06E,
+ },
+ [0x1D06F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06F,
+ },
+ [0x1D070]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D070,
+ },
+ [0x1D071]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D071,
+ },
+ [0x1D072]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D072,
+ },
+ [0x1D073]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D073,
+ },
+ [0x1D074]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D074,
+ },
+ [0x1D075]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D075,
+ },
+ [0x1D076]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D076,
+ },
+ [0x1D077]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D077,
+ },
+ [0x1D078]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D078,
+ },
+ [0x1D079]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D079,
+ },
+ [0x1D07A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07A,
+ },
+ [0x1D07B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07B,
+ },
+ [0x1D07C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07C,
+ },
+ [0x1D07D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07D,
+ },
+ [0x1D07E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07E,
+ },
+ [0x1D07F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07F,
+ },
+ [0x1D080]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D080,
+ },
+ [0x1D081]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D081,
+ },
+ [0x1D082]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D082,
+ },
+ [0x1D083]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D083,
+ },
+ [0x1D084]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D084,
+ },
+ [0x1D085]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D085,
+ },
+ [0x1D086]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D086,
+ },
+ [0x1D087]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D087,
+ },
+ [0x1D088]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D088,
+ },
+ [0x1D089]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D089,
+ },
+ [0x1D08A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08A,
+ },
+ [0x1D08B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08B,
+ },
+ [0x1D08C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08C,
+ },
+ [0x1D08D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08D,
+ },
+ [0x1D08E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08E,
+ },
+ [0x1D08F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08F,
+ },
+ [0x1D090]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D090,
+ },
+ [0x1D091]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D091,
+ },
+ [0x1D092]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D092,
+ },
+ [0x1D093]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D093,
+ },
+ [0x1D094]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D094,
+ },
+ [0x1D095]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D095,
+ },
+ [0x1D096]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D096,
+ },
+ [0x1D097]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D097,
+ },
+ [0x1D098]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D098,
+ },
+ [0x1D099]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D099,
+ },
+ [0x1D09A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09A,
+ },
+ [0x1D09B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09B,
+ },
+ [0x1D09C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09C,
+ },
+ [0x1D09D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09D,
+ },
+ [0x1D09E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09E,
+ },
+ [0x1D09F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09F,
+ },
+ [0x1D0A0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A0,
+ },
+ [0x1D0A1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A1,
+ },
+ [0x1D0A2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A2,
+ },
+ [0x1D0A3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A3,
+ },
+ [0x1D0A4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A4,
+ },
+ [0x1D0A5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A5,
+ },
+ [0x1D0A6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A6,
+ },
+ [0x1D0A7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A7,
+ },
+ [0x1D0A8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A8,
+ },
+ [0x1D0A9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A9,
+ },
+ [0x1D0AA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0AA,
+ },
+ [0x1D0AB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0AB,
+ },
+ [0x1D0AC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0AC,
+ },
+ [0x1D0AD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0AD,
+ },
+ [0x1D0AE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0AE,
+ },
+ [0x1D0AF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0AF,
+ },
+ [0x1D0B0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B0,
+ },
+ [0x1D0B1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B1,
+ },
+ [0x1D0B2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B2,
+ },
+ [0x1D0B3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B3,
+ },
+ [0x1D0B4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B4,
+ },
+ [0x1D0B5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B5,
+ },
+ [0x1D0B6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B6,
+ },
+ [0x1D0B7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B7,
+ },
+ [0x1D0B8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B8,
+ },
+ [0x1D0B9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B9,
+ },
+ [0x1D0BA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0BA,
+ },
+ [0x1D0BB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0BB,
+ },
+ [0x1D0BC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0BC,
+ },
+ [0x1D0BD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0BD,
+ },
+ [0x1D0BE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0BE,
+ },
+ [0x1D0BF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0BF,
+ },
+ [0x1D0C0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C0,
+ },
+ [0x1D0C1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C1,
+ },
+ [0x1D0C2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C2,
+ },
+ [0x1D0C3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C3,
+ },
+ [0x1D0C4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C4,
+ },
+ [0x1D0C5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C5,
+ },
+ [0x1D0C6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C6,
+ },
+ [0x1D0C7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C7,
+ },
+ [0x1D0C8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C8,
+ },
+ [0x1D0C9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C9,
+ },
+ [0x1D0CA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0CA,
+ },
+ [0x1D0CB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0CB,
+ },
+ [0x1D0CC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0CC,
+ },
+ [0x1D0CD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0CD,
+ },
+ [0x1D0CE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0CE,
+ },
+ [0x1D0CF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0CF,
+ },
+ [0x1D0D0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D0,
+ },
+ [0x1D0D1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D1,
+ },
+ [0x1D0D2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D2,
+ },
+ [0x1D0D3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D3,
+ },
+ [0x1D0D4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D4,
+ },
+ [0x1D0D5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D5,
+ },
+ [0x1D0D6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D6,
+ },
+ [0x1D0D7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D7,
+ },
+ [0x1D0D8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D8,
+ },
+ [0x1D0D9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D9,
+ },
+ [0x1D0DA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0DA,
+ },
+ [0x1D0DB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0DB,
+ },
+ [0x1D0DC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0DC,
+ },
+ [0x1D0DD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0DD,
+ },
+ [0x1D0DE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0DE,
+ },
+ [0x1D0DF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0DF,
+ },
+ [0x1D0E0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E0,
+ },
+ [0x1D0E1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E1,
+ },
+ [0x1D0E2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E2,
+ },
+ [0x1D0E3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E3,
+ },
+ [0x1D0E4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E4,
+ },
+ [0x1D0E5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E5,
+ },
+ [0x1D0E6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E6,
+ },
+ [0x1D0E7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E7,
+ },
+ [0x1D0E8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E8,
+ },
+ [0x1D0E9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E9,
+ },
+ [0x1D0EA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0EA,
+ },
+ [0x1D0EB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0EB,
+ },
+ [0x1D0EC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0EC,
+ },
+ [0x1D0ED]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0ED,
+ },
+ [0x1D0EE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0EE,
+ },
+ [0x1D0EF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0EF,
+ },
+ [0x1D0F0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F0,
+ },
+ [0x1D0F1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F1,
+ },
+ [0x1D0F2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F2,
+ },
+ [0x1D0F3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F3,
+ },
+ [0x1D0F4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F4,
+ },
+ [0x1D0F5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F5,
+ },
+ [0x1D100]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D100,
+ },
+ [0x1D101]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D101,
+ },
+ [0x1D102]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D102,
+ },
+ [0x1D103]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D103,
+ },
+ [0x1D104]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D104,
+ },
+ [0x1D105]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D105,
+ },
+ [0x1D106]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D106,
+ },
+ [0x1D107]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D107,
+ },
+ [0x1D108]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D108,
+ },
+ [0x1D109]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D109,
+ },
+ [0x1D10A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10A,
+ },
+ [0x1D10B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10B,
+ },
+ [0x1D10C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10C,
+ },
+ [0x1D10D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10D,
+ },
+ [0x1D10E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10E,
+ },
+ [0x1D10F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10F,
+ },
+ [0x1D110]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D110,
+ },
+ [0x1D111]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D111,
+ },
+ [0x1D112]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D112,
+ },
+ [0x1D113]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D113,
+ },
+ [0x1D114]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D114,
+ },
+ [0x1D115]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D115,
+ },
+ [0x1D116]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D116,
+ },
+ [0x1D117]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D117,
+ },
+ [0x1D118]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D118,
+ },
+ [0x1D119]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D119,
+ },
+ [0x1D11A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11A,
+ },
+ [0x1D11B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11B,
+ },
+ [0x1D11C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11C,
+ },
+ [0x1D11D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11D,
+ },
+ [0x1D11E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11E,
+ },
+ [0x1D11F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11F,
+ },
+ [0x1D120]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D120,
+ },
+ [0x1D121]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D121,
+ },
+ [0x1D122]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D122,
+ },
+ [0x1D123]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D123,
+ },
+ [0x1D124]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D124,
+ },
+ [0x1D125]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D125,
+ },
+ [0x1D126]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D126,
+ },
+ [0x1D129]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D129,
+ },
+ [0x1D12A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12A,
+ },
+ [0x1D12B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12B,
+ },
+ [0x1D12C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12C,
+ },
+ [0x1D12D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12D,
+ },
+ [0x1D12E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12E,
+ },
+ [0x1D12F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12F,
+ },
+ [0x1D130]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D130,
+ },
+ [0x1D131]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D131,
+ },
+ [0x1D132]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D132,
+ },
+ [0x1D133]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D133,
+ },
+ [0x1D134]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D134,
+ },
+ [0x1D135]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D135,
+ },
+ [0x1D136]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D136,
+ },
+ [0x1D137]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D137,
+ },
+ [0x1D138]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D138,
+ },
+ [0x1D139]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D139,
+ },
+ [0x1D13A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13A,
+ },
+ [0x1D13B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13B,
+ },
+ [0x1D13C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13C,
+ },
+ [0x1D13D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13D,
+ },
+ [0x1D13E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13E,
+ },
+ [0x1D13F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13F,
+ },
+ [0x1D140]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D140,
+ },
+ [0x1D141]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D141,
+ },
+ [0x1D142]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D142,
+ },
+ [0x1D143]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D143,
+ },
+ [0x1D144]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D144,
+ },
+ [0x1D145]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D145,
+ },
+ [0x1D146]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D146,
+ },
+ [0x1D147]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D147,
+ },
+ [0x1D148]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D148,
+ },
+ [0x1D149]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D149,
+ },
+ [0x1D14A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14A,
+ },
+ [0x1D14B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14B,
+ },
+ [0x1D14C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14C,
+ },
+ [0x1D14D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14D,
+ },
+ [0x1D14E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14E,
+ },
+ [0x1D14F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14F,
+ },
+ [0x1D150]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D150,
+ },
+ [0x1D151]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D151,
+ },
+ [0x1D152]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D152,
+ },
+ [0x1D153]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D153,
+ },
+ [0x1D154]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D154,
+ },
+ [0x1D155]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D155,
+ },
+ [0x1D156]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D156,
+ },
+ [0x1D157]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D157,
+ },
+ [0x1D158]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D158,
+ },
+ [0x1D159]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D159,
+ },
+ [0x1D15A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D15A,
+ },
+ [0x1D15B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D15B,
+ },
+ [0x1D15C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D15C,
+ },
+ [0x1D15D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D15D,
+ },
+ [0x1D15E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D157, 0x1D165 },
+ unicodeslot=0x1D15E,
+ },
+ [0x1D15F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D158, 0x1D165 },
+ unicodeslot=0x1D15F,
+ },
+ [0x1D160]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D15F, 0x1D16E },
+ unicodeslot=0x1D160,
+ },
+ [0x1D161]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D15F, 0x1D16F },
+ unicodeslot=0x1D161,
+ },
+ [0x1D162]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D15F, 0x1D170 },
+ unicodeslot=0x1D162,
+ },
+ [0x1D163]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D15F, 0x1D171 },
+ unicodeslot=0x1D163,
+ },
+ [0x1D164]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D15F, 0x1D172 },
+ unicodeslot=0x1D164,
+ },
+ [0x1D165]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D165,
+ },
+ [0x1D166]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D166,
+ },
+ [0x1D167]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D167,
+ },
+ [0x1D168]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D168,
+ },
+ [0x1D169]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D169,
+ },
+ [0x1D16A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D16A,
+ },
+ [0x1D16B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D16B,
+ },
+ [0x1D16C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D16C,
+ },
+ [0x1D16D]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D16D,
+ },
+ [0x1D16E]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D16E,
+ },
+ [0x1D16F]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D16F,
+ },
+ [0x1D170]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D170,
+ },
+ [0x1D171]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D171,
+ },
+ [0x1D172]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D172,
+ },
+ [0x1D173]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D173,
+ },
+ [0x1D174]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D174,
+ },
+ [0x1D175]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D175,
+ },
+ [0x1D176]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D176,
+ },
+ [0x1D177]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D177,
+ },
+ [0x1D178]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D178,
+ },
+ [0x1D179]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D179,
+ },
+ [0x1D17A]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D17A,
+ },
+ [0x1D17B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D17B,
+ },
+ [0x1D17C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D17C,
+ },
+ [0x1D17D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D17D,
+ },
+ [0x1D17E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D17E,
+ },
+ [0x1D17F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D17F,
+ },
+ [0x1D180]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D180,
+ },
+ [0x1D181]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D181,
+ },
+ [0x1D182]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D182,
+ },
+ [0x1D183]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D183,
+ },
+ [0x1D184]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D184,
+ },
+ [0x1D185]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D185,
+ },
+ [0x1D186]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D186,
+ },
+ [0x1D187]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D187,
+ },
+ [0x1D188]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D188,
+ },
+ [0x1D189]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D189,
+ },
+ [0x1D18A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D18A,
+ },
+ [0x1D18B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D18B,
+ },
+ [0x1D18C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D18C,
+ },
+ [0x1D18D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D18D,
+ },
+ [0x1D18E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D18E,
+ },
+ [0x1D18F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D18F,
+ },
+ [0x1D190]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D190,
+ },
+ [0x1D191]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D191,
+ },
+ [0x1D192]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D192,
+ },
+ [0x1D193]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D193,
+ },
+ [0x1D194]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D194,
+ },
+ [0x1D195]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D195,
+ },
+ [0x1D196]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D196,
+ },
+ [0x1D197]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D197,
+ },
+ [0x1D198]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D198,
+ },
+ [0x1D199]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D199,
+ },
+ [0x1D19A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19A,
+ },
+ [0x1D19B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19B,
+ },
+ [0x1D19C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19C,
+ },
+ [0x1D19D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19D,
+ },
+ [0x1D19E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19E,
+ },
+ [0x1D19F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19F,
+ },
+ [0x1D1A0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A0,
+ },
+ [0x1D1A1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A1,
+ },
+ [0x1D1A2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A2,
+ },
+ [0x1D1A3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A3,
+ },
+ [0x1D1A4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A4,
+ },
+ [0x1D1A5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A5,
+ },
+ [0x1D1A6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A6,
+ },
+ [0x1D1A7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A7,
+ },
+ [0x1D1A8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A8,
+ },
+ [0x1D1A9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A9,
+ },
+ [0x1D1AA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D1AA,
+ },
+ [0x1D1AB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D1AB,
+ },
+ [0x1D1AC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D1AC,
+ },
+ [0x1D1AD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D1AD,
+ },
+ [0x1D1AE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1AE,
+ },
+ [0x1D1AF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1AF,
+ },
+ [0x1D1B0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B0,
+ },
+ [0x1D1B1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B1,
+ },
+ [0x1D1B2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B2,
+ },
+ [0x1D1B3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B3,
+ },
+ [0x1D1B4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B4,
+ },
+ [0x1D1B5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B5,
+ },
+ [0x1D1B6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B6,
+ },
+ [0x1D1B7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B7,
+ },
+ [0x1D1B8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B8,
+ },
+ [0x1D1B9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B9,
+ },
+ [0x1D1BA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1BA,
+ },
+ [0x1D1BB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D1B9, 0x1D165 },
+ unicodeslot=0x1D1BB,
+ },
+ [0x1D1BC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D1BA, 0x1D165 },
+ unicodeslot=0x1D1BC,
+ },
+ [0x1D1BD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D1BB, 0x1D16E },
+ unicodeslot=0x1D1BD,
+ },
+ [0x1D1BE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D1BC, 0x1D16E },
+ unicodeslot=0x1D1BE,
+ },
+ [0x1D1BF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D1BB, 0x1D16F },
+ unicodeslot=0x1D1BF,
+ },
+ [0x1D1C0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D1BC, 0x1D16F },
+ unicodeslot=0x1D1C0,
+ },
+ [0x1D1C1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C1,
+ },
+ [0x1D1C2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C2,
+ },
+ [0x1D1C3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C3,
+ },
+ [0x1D1C4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C4,
+ },
+ [0x1D1C5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C5,
+ },
+ [0x1D1C6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C6,
+ },
+ [0x1D1C7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C7,
+ },
+ [0x1D1C8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C8,
+ },
+ [0x1D1C9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C9,
+ },
+ [0x1D1CA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1CA,
+ },
+ [0x1D1CB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1CB,
+ },
+ [0x1D1CC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1CC,
+ },
+ [0x1D1CD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1CD,
+ },
+ [0x1D1CE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1CE,
+ },
+ [0x1D1CF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1CF,
+ },
+ [0x1D1D0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D0,
+ },
+ [0x1D1D1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D1,
+ },
+ [0x1D1D2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D2,
+ },
+ [0x1D1D3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D3,
+ },
+ [0x1D1D4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D4,
+ },
+ [0x1D1D5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D5,
+ },
+ [0x1D1D6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D6,
+ },
+ [0x1D1D7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D7,
+ },
+ [0x1D1D8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D8,
+ },
+ [0x1D1D9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D9,
+ },
+ [0x1D1DA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1DA,
+ },
+ [0x1D1DB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1DB,
+ },
+ [0x1D1DC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1DC,
+ },
+ [0x1D1DD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1DD,
+ },
+ [0x1D1DE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1DE,
+ },
+ [0x1D1DF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1DF,
+ },
+ [0x1D1E0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1E0,
+ },
+ [0x1D1E1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1E1,
+ },
+ [0x1D1E2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1E2,
+ },
+ [0x1D1E3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1E3,
+ },
+ [0x1D1E4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1E4,
+ },
+ [0x1D1E5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1E5,
+ },
+ [0x1D1E6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1E6,
+ },
+ [0x1D1E7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1E7,
+ },
+ [0x1D1E8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1E8,
+ },
+ [0x1D200]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D200,
+ },
+ [0x1D201]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D201,
+ },
+ [0x1D202]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D202,
+ },
+ [0x1D203]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D203,
+ },
+ [0x1D204]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D204,
+ },
+ [0x1D205]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D205,
+ },
+ [0x1D206]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D206,
+ },
+ [0x1D207]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D207,
+ },
+ [0x1D208]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D208,
+ },
+ [0x1D209]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D209,
+ },
+ [0x1D20A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D20A,
+ },
+ [0x1D20B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D20B,
+ },
+ [0x1D20C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D20C,
+ },
+ [0x1D20D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D20D,
+ },
+ [0x1D20E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D20E,
+ },
+ [0x1D20F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D20F,
+ },
+ [0x1D210]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D210,
+ },
+ [0x1D211]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D211,
+ },
+ [0x1D212]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D212,
+ },
+ [0x1D213]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D213,
+ },
+ [0x1D214]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D214,
+ },
+ [0x1D215]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D215,
+ },
+ [0x1D216]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D216,
+ },
+ [0x1D217]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D217,
+ },
+ [0x1D218]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D218,
+ },
+ [0x1D219]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D219,
+ },
+ [0x1D21A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D21A,
+ },
+ [0x1D21B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D21B,
+ },
+ [0x1D21C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D21C,
+ },
+ [0x1D21D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D21D,
+ },
+ [0x1D21E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D21E,
+ },
+ [0x1D21F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D21F,
+ },
+ [0x1D220]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D220,
+ },
+ [0x1D221]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D221,
+ },
+ [0x1D222]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D222,
+ },
+ [0x1D223]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D223,
+ },
+ [0x1D224]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D224,
+ },
+ [0x1D225]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D225,
+ },
+ [0x1D226]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D226,
+ },
+ [0x1D227]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D227,
+ },
+ [0x1D228]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D228,
+ },
+ [0x1D229]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D229,
+ },
+ [0x1D22A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D22A,
+ },
+ [0x1D22B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D22B,
+ },
+ [0x1D22C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D22C,
+ },
+ [0x1D22D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D22D,
+ },
+ [0x1D22E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D22E,
+ },
+ [0x1D22F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D22F,
+ },
+ [0x1D230]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D230,
+ },
+ [0x1D231]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D231,
+ },
+ [0x1D232]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D232,
+ },
+ [0x1D233]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D233,
+ },
+ [0x1D234]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D234,
+ },
+ [0x1D235]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D235,
+ },
+ [0x1D236]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D236,
+ },
+ [0x1D237]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D237,
+ },
+ [0x1D238]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D238,
+ },
+ [0x1D239]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D239,
+ },
+ [0x1D23A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D23A,
+ },
+ [0x1D23B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D23B,
+ },
+ [0x1D23C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D23C,
+ },
+ [0x1D23D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D23D,
+ },
+ [0x1D23E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D23E,
+ },
+ [0x1D23F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D23F,
+ },
+ [0x1D240]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D240,
+ },
+ [0x1D241]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D241,
+ },
+ [0x1D242]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D242,
+ },
+ [0x1D243]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D243,
+ },
+ [0x1D244]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D244,
+ },
+ [0x1D245]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D245,
+ },
+ [0x1D2E0]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2E0,
+ },
+ [0x1D2E1]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2E1,
+ },
+ [0x1D2E2]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2E2,
+ },
+ [0x1D2E3]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2E3,
+ },
+ [0x1D2E4]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2E4,
+ },
+ [0x1D2E5]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2E5,
+ },
+ [0x1D2E6]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2E6,
+ },
+ [0x1D2E7]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2E7,
+ },
+ [0x1D2E8]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2E8,
+ },
+ [0x1D2E9]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2E9,
+ },
+ [0x1D2EA]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2EA,
+ },
+ [0x1D2EB]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2EB,
+ },
+ [0x1D2EC]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2EC,
+ },
+ [0x1D2ED]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2ED,
+ },
+ [0x1D2EE]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2EE,
+ },
+ [0x1D2EF]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2EF,
+ },
+ [0x1D2F0]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2F0,
+ },
+ [0x1D2F1]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2F1,
+ },
+ [0x1D2F2]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2F2,
+ },
+ [0x1D2F3]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2F3,
+ },
+ [0x1D300]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D300,
+ },
+ [0x1D301]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D301,
+ },
+ [0x1D302]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D302,
+ },
+ [0x1D303]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D303,
+ },
+ [0x1D304]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D304,
+ },
+ [0x1D305]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D305,
+ },
+ [0x1D306]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D306,
+ },
+ [0x1D307]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D307,
+ },
+ [0x1D308]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D308,
+ },
+ [0x1D309]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D309,
+ },
+ [0x1D30A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D30A,
+ },
+ [0x1D30B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D30B,
+ },
+ [0x1D30C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D30C,
+ },
+ [0x1D30D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D30D,
+ },
+ [0x1D30E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D30E,
+ },
+ [0x1D30F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D30F,
+ },
+ [0x1D310]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D310,
+ },
+ [0x1D311]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D311,
+ },
+ [0x1D312]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D312,
+ },
+ [0x1D313]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D313,
+ },
+ [0x1D314]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D314,
+ },
+ [0x1D315]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D315,
+ },
+ [0x1D316]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D316,
+ },
+ [0x1D317]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D317,
+ },
+ [0x1D318]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D318,
+ },
+ [0x1D319]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D319,
+ },
+ [0x1D31A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D31A,
+ },
+ [0x1D31B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D31B,
+ },
+ [0x1D31C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D31C,
+ },
+ [0x1D31D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D31D,
+ },
+ [0x1D31E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D31E,
+ },
+ [0x1D31F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D31F,
+ },
+ [0x1D320]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D320,
+ },
+ [0x1D321]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D321,
+ },
+ [0x1D322]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D322,
+ },
+ [0x1D323]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D323,
+ },
+ [0x1D324]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D324,
+ },
+ [0x1D325]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D325,
+ },
+ [0x1D326]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D326,
+ },
+ [0x1D327]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D327,
+ },
+ [0x1D328]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D328,
+ },
+ [0x1D329]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D329,
+ },
+ [0x1D32A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D32A,
+ },
+ [0x1D32B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D32B,
+ },
+ [0x1D32C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D32C,
+ },
+ [0x1D32D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D32D,
+ },
+ [0x1D32E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D32E,
+ },
+ [0x1D32F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D32F,
+ },
+ [0x1D330]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D330,
+ },
+ [0x1D331]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D331,
+ },
+ [0x1D332]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D332,
+ },
+ [0x1D333]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D333,
+ },
+ [0x1D334]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D334,
+ },
+ [0x1D335]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D335,
+ },
+ [0x1D336]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D336,
+ },
+ [0x1D337]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D337,
+ },
+ [0x1D338]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D338,
+ },
+ [0x1D339]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D339,
+ },
+ [0x1D33A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D33A,
+ },
+ [0x1D33B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D33B,
+ },
+ [0x1D33C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D33C,
+ },
+ [0x1D33D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D33D,
+ },
+ [0x1D33E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D33E,
+ },
+ [0x1D33F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D33F,
+ },
+ [0x1D340]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D340,
+ },
+ [0x1D341]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D341,
+ },
+ [0x1D342]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D342,
+ },
+ [0x1D343]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D343,
+ },
+ [0x1D344]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D344,
+ },
+ [0x1D345]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D345,
+ },
+ [0x1D346]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D346,
+ },
+ [0x1D347]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D347,
+ },
+ [0x1D348]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D348,
+ },
+ [0x1D349]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D349,
+ },
+ [0x1D34A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D34A,
+ },
+ [0x1D34B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D34B,
+ },
+ [0x1D34C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D34C,
+ },
+ [0x1D34D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D34D,
+ },
+ [0x1D34E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D34E,
+ },
+ [0x1D34F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D34F,
+ },
+ [0x1D350]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D350,
+ },
+ [0x1D351]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D351,
+ },
+ [0x1D352]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D352,
+ },
+ [0x1D353]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D353,
+ },
+ [0x1D354]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D354,
+ },
+ [0x1D355]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D355,
+ },
+ [0x1D356]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D356,
+ },
+ [0x1D360]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D360,
+ },
+ [0x1D361]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D361,
+ },
+ [0x1D362]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D362,
+ },
+ [0x1D363]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D363,
+ },
+ [0x1D364]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D364,
+ },
+ [0x1D365]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D365,
+ },
+ [0x1D366]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D366,
+ },
+ [0x1D367]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D367,
+ },
+ [0x1D368]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D368,
+ },
+ [0x1D369]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D369,
+ },
+ [0x1D36A]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D36A,
+ },
+ [0x1D36B]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D36B,
+ },
+ [0x1D36C]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D36C,
+ },
+ [0x1D36D]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D36D,
+ },
+ [0x1D36E]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D36E,
+ },
+ [0x1D36F]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D36F,
+ },
+ [0x1D370]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D370,
+ },
+ [0x1D371]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D371,
+ },
+ [0x1D372]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D372,
+ },
+ [0x1D373]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D373,
+ },
+ [0x1D374]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D374,
+ },
+ [0x1D375]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D375,
+ },
+ [0x1D376]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D376,
+ },
+ [0x1D377]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D377,
+ },
+ [0x1D378]={
+ category="no",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D378,
+ },
+ [0x1D400]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D400,
+ },
+ [0x1D401]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x1D401,
+ },
+ [0x1D402]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x1D402,
+ },
+ [0x1D403]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D403,
+ },
+ [0x1D404]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x1D404,
+ },
+ [0x1D405]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x1D405,
+ },
+ [0x1D406]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D406,
+ },
+ [0x1D407]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x1D407,
+ },
+ [0x1D408]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x1D408,
+ },
+ [0x1D409]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D409,
+ },
+ [0x1D40A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D40A,
+ },
+ [0x1D40B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x1D40B,
+ },
+ [0x1D40C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x1D40C,
+ },
+ [0x1D40D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x1D40D,
+ },
+ [0x1D40E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D40E,
+ },
+ [0x1D40F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x1D40F,
+ },
+ [0x1D410]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x1D410,
+ },
+ [0x1D411]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x1D411,
+ },
+ [0x1D412]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D412,
+ },
+ [0x1D413]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D413,
+ },
+ [0x1D414]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D414,
+ },
+ [0x1D415]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D415,
+ },
+ [0x1D416]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D416,
+ },
+ [0x1D417]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D417,
+ },
+ [0x1D418]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D418,
+ },
+ [0x1D419]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x1D419,
+ },
+ [0x1D41A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D41A,
+ },
+ [0x1D41B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D41B,
+ },
+ [0x1D41C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D41C,
+ },
+ [0x1D41D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D41D,
+ },
+ [0x1D41E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x1D41E,
+ },
+ [0x1D41F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D41F,
+ },
+ [0x1D420]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x1D420,
+ },
+ [0x1D421]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x1D421,
+ },
+ [0x1D422]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D422,
+ },
+ [0x1D423]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D423,
+ },
+ [0x1D424]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D424,
+ },
+ [0x1D425]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D425,
+ },
+ [0x1D426]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D426,
+ },
+ [0x1D427]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D427,
+ },
+ [0x1D428]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x1D428,
+ },
+ [0x1D429]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D429,
+ },
+ [0x1D42A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D42A,
+ },
+ [0x1D42B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D42B,
+ },
+ [0x1D42C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D42C,
+ },
+ [0x1D42D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D42D,
+ },
+ [0x1D42E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D42E,
+ },
+ [0x1D42F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D42F,
+ },
+ [0x1D430]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D430,
+ },
+ [0x1D431]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D431,
+ },
+ [0x1D432]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D432,
+ },
+ [0x1D433]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D433,
+ },
+ [0x1D434]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D434,
+ },
+ [0x1D435]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x1D435,
+ },
+ [0x1D436]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x1D436,
+ },
+ [0x1D437]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D437,
+ },
+ [0x1D438]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x1D438,
+ },
+ [0x1D439]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x1D439,
+ },
+ [0x1D43A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D43A,
+ },
+ [0x1D43B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x1D43B,
+ },
+ [0x1D43C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x1D43C,
+ },
+ [0x1D43D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D43D,
+ },
+ [0x1D43E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D43E,
+ },
+ [0x1D43F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x1D43F,
+ },
+ [0x1D440]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x1D440,
+ },
+ [0x1D441]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x1D441,
+ },
+ [0x1D442]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D442,
+ },
+ [0x1D443]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x1D443,
+ },
+ [0x1D444]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x1D444,
+ },
+ [0x1D445]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x1D445,
+ },
+ [0x1D446]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D446,
+ },
+ [0x1D447]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D447,
+ },
+ [0x1D448]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D448,
+ },
+ [0x1D449]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D449,
+ },
+ [0x1D44A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D44A,
+ },
+ [0x1D44B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D44B,
+ },
+ [0x1D44C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D44C,
+ },
+ [0x1D44D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x1D44D,
+ },
+ [0x1D44E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D44E,
+ },
+ [0x1D44F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D44F,
+ },
+ [0x1D450]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D450,
+ },
+ [0x1D451]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D451,
+ },
+ [0x1D452]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x1D452,
+ },
+ [0x1D453]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D453,
+ },
+ [0x1D454]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x1D454,
+ },
+ [0x1D456]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D456,
+ },
+ [0x1D457]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D457,
+ },
+ [0x1D458]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D458,
+ },
+ [0x1D459]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D459,
+ },
+ [0x1D45A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D45A,
+ },
+ [0x1D45B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D45B,
+ },
+ [0x1D45C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x1D45C,
+ },
+ [0x1D45D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D45D,
+ },
+ [0x1D45E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D45E,
+ },
+ [0x1D45F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D45F,
+ },
+ [0x1D460]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D460,
+ },
+ [0x1D461]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D461,
+ },
+ [0x1D462]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D462,
+ },
+ [0x1D463]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D463,
+ },
+ [0x1D464]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D464,
+ },
+ [0x1D465]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D465,
+ },
+ [0x1D466]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D466,
+ },
+ [0x1D467]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D467,
+ },
+ [0x1D468]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D468,
+ },
+ [0x1D469]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x1D469,
+ },
+ [0x1D46A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x1D46A,
+ },
+ [0x1D46B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D46B,
+ },
+ [0x1D46C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x1D46C,
+ },
+ [0x1D46D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x1D46D,
+ },
+ [0x1D46E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D46E,
+ },
+ [0x1D46F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x1D46F,
+ },
+ [0x1D470]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x1D470,
+ },
+ [0x1D471]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D471,
+ },
+ [0x1D472]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D472,
+ },
+ [0x1D473]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x1D473,
+ },
+ [0x1D474]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x1D474,
+ },
+ [0x1D475]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x1D475,
+ },
+ [0x1D476]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D476,
+ },
+ [0x1D477]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x1D477,
+ },
+ [0x1D478]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x1D478,
+ },
+ [0x1D479]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x1D479,
+ },
+ [0x1D47A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D47A,
+ },
+ [0x1D47B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D47B,
+ },
+ [0x1D47C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D47C,
+ },
+ [0x1D47D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D47D,
+ },
+ [0x1D47E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D47E,
+ },
+ [0x1D47F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D47F,
+ },
+ [0x1D480]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D480,
+ },
+ [0x1D481]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x1D481,
+ },
+ [0x1D482]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D482,
+ },
+ [0x1D483]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D483,
+ },
+ [0x1D484]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D484,
+ },
+ [0x1D485]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D485,
+ },
+ [0x1D486]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x1D486,
+ },
+ [0x1D487]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D487,
+ },
+ [0x1D488]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x1D488,
+ },
+ [0x1D489]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x1D489,
+ },
+ [0x1D48A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D48A,
+ },
+ [0x1D48B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D48B,
+ },
+ [0x1D48C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D48C,
+ },
+ [0x1D48D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D48D,
+ },
+ [0x1D48E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D48E,
+ },
+ [0x1D48F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D48F,
+ },
+ [0x1D490]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x1D490,
+ },
+ [0x1D491]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D491,
+ },
+ [0x1D492]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D492,
+ },
+ [0x1D493]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D493,
+ },
+ [0x1D494]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D494,
+ },
+ [0x1D495]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D495,
+ },
+ [0x1D496]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D496,
+ },
+ [0x1D497]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D497,
+ },
+ [0x1D498]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D498,
+ },
+ [0x1D499]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D499,
+ },
+ [0x1D49A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D49A,
+ },
+ [0x1D49B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D49B,
+ },
+ [0x1D49C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D49C,
+ },
+ [0x1D49E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x1D49E,
+ },
+ [0x1D49F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D49F,
+ },
+ [0x1D4A2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D4A2,
+ },
+ [0x1D4A5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D4A5,
+ },
+ [0x1D4A6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D4A6,
+ },
+ [0x1D4A9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x1D4A9,
+ },
+ [0x1D4AA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D4AA,
+ },
+ [0x1D4AB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x1D4AB,
+ },
+ [0x1D4AC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x1D4AC,
+ },
+ [0x1D4AE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D4AE,
+ },
+ [0x1D4AF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D4AF,
+ },
+ [0x1D4B0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D4B0,
+ },
+ [0x1D4B1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D4B1,
+ },
+ [0x1D4B2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D4B2,
+ },
+ [0x1D4B3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D4B3,
+ },
+ [0x1D4B4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D4B4,
+ },
+ [0x1D4B5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x1D4B5,
+ },
+ [0x1D4B6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D4B6,
+ },
+ [0x1D4B7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D4B7,
+ },
+ [0x1D4B8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D4B8,
+ },
+ [0x1D4B9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D4B9,
+ },
+ [0x1D4BB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D4BB,
+ },
+ [0x1D4BD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x1D4BD,
+ },
+ [0x1D4BE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D4BE,
+ },
+ [0x1D4BF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D4BF,
+ },
+ [0x1D4C0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D4C0,
+ },
+ [0x1D4C1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D4C1,
+ },
+ [0x1D4C2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D4C2,
+ },
+ [0x1D4C3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D4C3,
+ },
+ [0x1D4C5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D4C5,
+ },
+ [0x1D4C6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D4C6,
+ },
+ [0x1D4C7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D4C7,
+ },
+ [0x1D4C8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D4C8,
+ },
+ [0x1D4C9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D4C9,
+ },
+ [0x1D4CA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D4CA,
+ },
+ [0x1D4CB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D4CB,
+ },
+ [0x1D4CC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D4CC,
+ },
+ [0x1D4CD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D4CD,
+ },
+ [0x1D4CE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D4CE,
+ },
+ [0x1D4CF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D4CF,
+ },
+ [0x1D4D0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D4D0,
+ },
+ [0x1D4D1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x1D4D1,
+ },
+ [0x1D4D2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x1D4D2,
+ },
+ [0x1D4D3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D4D3,
+ },
+ [0x1D4D4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x1D4D4,
+ },
+ [0x1D4D5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x1D4D5,
+ },
+ [0x1D4D6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D4D6,
+ },
+ [0x1D4D7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x1D4D7,
+ },
+ [0x1D4D8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x1D4D8,
+ },
+ [0x1D4D9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D4D9,
+ },
+ [0x1D4DA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D4DA,
+ },
+ [0x1D4DB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x1D4DB,
+ },
+ [0x1D4DC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x1D4DC,
+ },
+ [0x1D4DD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x1D4DD,
+ },
+ [0x1D4DE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D4DE,
+ },
+ [0x1D4DF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x1D4DF,
+ },
+ [0x1D4E0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x1D4E0,
+ },
+ [0x1D4E1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x1D4E1,
+ },
+ [0x1D4E2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D4E2,
+ },
+ [0x1D4E3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D4E3,
+ },
+ [0x1D4E4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D4E4,
+ },
+ [0x1D4E5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D4E5,
+ },
+ [0x1D4E6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D4E6,
+ },
+ [0x1D4E7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D4E7,
+ },
+ [0x1D4E8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D4E8,
+ },
+ [0x1D4E9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x1D4E9,
+ },
+ [0x1D4EA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D4EA,
+ },
+ [0x1D4EB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D4EB,
+ },
+ [0x1D4EC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D4EC,
+ },
+ [0x1D4ED]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D4ED,
+ },
+ [0x1D4EE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x1D4EE,
+ },
+ [0x1D4EF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D4EF,
+ },
+ [0x1D4F0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x1D4F0,
+ },
+ [0x1D4F1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x1D4F1,
+ },
+ [0x1D4F2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D4F2,
+ },
+ [0x1D4F3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D4F3,
+ },
+ [0x1D4F4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D4F4,
+ },
+ [0x1D4F5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D4F5,
+ },
+ [0x1D4F6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D4F6,
+ },
+ [0x1D4F7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D4F7,
+ },
+ [0x1D4F8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x1D4F8,
+ },
+ [0x1D4F9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D4F9,
+ },
+ [0x1D4FA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D4FA,
+ },
+ [0x1D4FB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D4FB,
+ },
+ [0x1D4FC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D4FC,
+ },
+ [0x1D4FD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D4FD,
+ },
+ [0x1D4FE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D4FE,
+ },
+ [0x1D4FF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D4FF,
+ },
+ [0x1D500]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D500,
+ },
+ [0x1D501]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D501,
+ },
+ [0x1D502]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D502,
+ },
+ [0x1D503]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D503,
+ },
+ [0x1D504]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D504,
+ },
+ [0x1D505]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x1D505,
+ },
+ [0x1D507]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D507,
+ },
+ [0x1D508]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x1D508,
+ },
+ [0x1D509]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x1D509,
+ },
+ [0x1D50A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D50A,
+ },
+ [0x1D50D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D50D,
+ },
+ [0x1D50E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D50E,
+ },
+ [0x1D50F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x1D50F,
+ },
+ [0x1D510]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x1D510,
+ },
+ [0x1D511]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x1D511,
+ },
+ [0x1D512]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D512,
+ },
+ [0x1D513]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x1D513,
+ },
+ [0x1D514]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x1D514,
+ },
+ [0x1D516]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D516,
+ },
+ [0x1D517]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D517,
+ },
+ [0x1D518]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D518,
+ },
+ [0x1D519]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D519,
+ },
+ [0x1D51A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D51A,
+ },
+ [0x1D51B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D51B,
+ },
+ [0x1D51C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D51C,
+ },
+ [0x1D51E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D51E,
+ },
+ [0x1D51F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D51F,
+ },
+ [0x1D520]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D520,
+ },
+ [0x1D521]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D521,
+ },
+ [0x1D522]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x1D522,
+ },
+ [0x1D523]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D523,
+ },
+ [0x1D524]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x1D524,
+ },
+ [0x1D525]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x1D525,
+ },
+ [0x1D526]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D526,
+ },
+ [0x1D527]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D527,
+ },
+ [0x1D528]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D528,
+ },
+ [0x1D529]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D529,
+ },
+ [0x1D52A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D52A,
+ },
+ [0x1D52B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D52B,
+ },
+ [0x1D52C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x1D52C,
+ },
+ [0x1D52D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D52D,
+ },
+ [0x1D52E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D52E,
+ },
+ [0x1D52F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D52F,
+ },
+ [0x1D530]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D530,
+ },
+ [0x1D531]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D531,
+ },
+ [0x1D532]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D532,
+ },
+ [0x1D533]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D533,
+ },
+ [0x1D534]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D534,
+ },
+ [0x1D535]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D535,
+ },
+ [0x1D536]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D536,
+ },
+ [0x1D537]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D537,
+ },
+ [0x1D538]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D538,
+ },
+ [0x1D539]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x1D539,
+ },
+ [0x1D53B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D53B,
+ },
+ [0x1D53C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x1D53C,
+ },
+ [0x1D53D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x1D53D,
+ },
+ [0x1D53E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D53E,
+ },
+ [0x1D540]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x1D540,
+ },
+ [0x1D541]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D541,
+ },
+ [0x1D542]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D542,
+ },
+ [0x1D543]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x1D543,
+ },
+ [0x1D544]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x1D544,
+ },
+ [0x1D546]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D546,
+ },
+ [0x1D54A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D54A,
+ },
+ [0x1D54B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D54B,
+ },
+ [0x1D54C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D54C,
+ },
+ [0x1D54D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D54D,
+ },
+ [0x1D54E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D54E,
+ },
+ [0x1D54F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D54F,
+ },
+ [0x1D550]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D550,
+ },
+ [0x1D552]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D552,
+ },
+ [0x1D553]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D553,
+ },
+ [0x1D554]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D554,
+ },
+ [0x1D555]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D555,
+ },
+ [0x1D556]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x1D556,
+ },
+ [0x1D557]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D557,
+ },
+ [0x1D558]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x1D558,
+ },
+ [0x1D559]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x1D559,
+ },
+ [0x1D55A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D55A,
+ },
+ [0x1D55B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D55B,
+ },
+ [0x1D55C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D55C,
+ },
+ [0x1D55D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D55D,
+ },
+ [0x1D55E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D55E,
+ },
+ [0x1D55F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D55F,
+ },
+ [0x1D560]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x1D560,
+ },
+ [0x1D561]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D561,
+ },
+ [0x1D562]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D562,
+ },
+ [0x1D563]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D563,
+ },
+ [0x1D564]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D564,
+ },
+ [0x1D565]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D565,
+ },
+ [0x1D566]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D566,
+ },
+ [0x1D567]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D567,
+ },
+ [0x1D568]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D568,
+ },
+ [0x1D569]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D569,
+ },
+ [0x1D56A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D56A,
+ },
+ [0x1D56B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D56B,
+ },
+ [0x1D56C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D56C,
+ },
+ [0x1D56D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x1D56D,
+ },
+ [0x1D56E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x1D56E,
+ },
+ [0x1D56F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D56F,
+ },
+ [0x1D570]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x1D570,
+ },
+ [0x1D571]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x1D571,
+ },
+ [0x1D572]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D572,
+ },
+ [0x1D573]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x1D573,
+ },
+ [0x1D574]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x1D574,
+ },
+ [0x1D575]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D575,
+ },
+ [0x1D576]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D576,
+ },
+ [0x1D577]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x1D577,
+ },
+ [0x1D578]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x1D578,
+ },
+ [0x1D579]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x1D579,
+ },
+ [0x1D57A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D57A,
+ },
+ [0x1D57B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x1D57B,
+ },
+ [0x1D57C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x1D57C,
+ },
+ [0x1D57D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x1D57D,
+ },
+ [0x1D57E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D57E,
+ },
+ [0x1D57F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D57F,
+ },
+ [0x1D580]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D580,
+ },
+ [0x1D581]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D581,
+ },
+ [0x1D582]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D582,
+ },
+ [0x1D583]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D583,
+ },
+ [0x1D584]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D584,
+ },
+ [0x1D585]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x1D585,
+ },
+ [0x1D586]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D586,
+ },
+ [0x1D587]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D587,
+ },
+ [0x1D588]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D588,
+ },
+ [0x1D589]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D589,
+ },
+ [0x1D58A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x1D58A,
+ },
+ [0x1D58B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D58B,
+ },
+ [0x1D58C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x1D58C,
+ },
+ [0x1D58D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x1D58D,
+ },
+ [0x1D58E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D58E,
+ },
+ [0x1D58F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D58F,
+ },
+ [0x1D590]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D590,
+ },
+ [0x1D591]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D591,
+ },
+ [0x1D592]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D592,
+ },
+ [0x1D593]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D593,
+ },
+ [0x1D594]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x1D594,
+ },
+ [0x1D595]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D595,
+ },
+ [0x1D596]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D596,
+ },
+ [0x1D597]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D597,
+ },
+ [0x1D598]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D598,
+ },
+ [0x1D599]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D599,
+ },
+ [0x1D59A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D59A,
+ },
+ [0x1D59B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D59B,
+ },
+ [0x1D59C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D59C,
+ },
+ [0x1D59D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D59D,
+ },
+ [0x1D59E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D59E,
+ },
+ [0x1D59F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D59F,
+ },
+ [0x1D5A0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D5A0,
+ },
+ [0x1D5A1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x1D5A1,
+ },
+ [0x1D5A2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x1D5A2,
+ },
+ [0x1D5A3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D5A3,
+ },
+ [0x1D5A4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x1D5A4,
+ },
+ [0x1D5A5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x1D5A5,
+ },
+ [0x1D5A6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D5A6,
+ },
+ [0x1D5A7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x1D5A7,
+ },
+ [0x1D5A8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x1D5A8,
+ },
+ [0x1D5A9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D5A9,
+ },
+ [0x1D5AA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D5AA,
+ },
+ [0x1D5AB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x1D5AB,
+ },
+ [0x1D5AC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x1D5AC,
+ },
+ [0x1D5AD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x1D5AD,
+ },
+ [0x1D5AE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D5AE,
+ },
+ [0x1D5AF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x1D5AF,
+ },
+ [0x1D5B0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x1D5B0,
+ },
+ [0x1D5B1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x1D5B1,
+ },
+ [0x1D5B2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D5B2,
+ },
+ [0x1D5B3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D5B3,
+ },
+ [0x1D5B4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D5B4,
+ },
+ [0x1D5B5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D5B5,
+ },
+ [0x1D5B6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D5B6,
+ },
+ [0x1D5B7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D5B7,
+ },
+ [0x1D5B8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D5B8,
+ },
+ [0x1D5B9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x1D5B9,
+ },
+ [0x1D5BA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D5BA,
+ },
+ [0x1D5BB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D5BB,
+ },
+ [0x1D5BC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D5BC,
+ },
+ [0x1D5BD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D5BD,
+ },
+ [0x1D5BE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x1D5BE,
+ },
+ [0x1D5BF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D5BF,
+ },
+ [0x1D5C0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x1D5C0,
+ },
+ [0x1D5C1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x1D5C1,
+ },
+ [0x1D5C2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D5C2,
+ },
+ [0x1D5C3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D5C3,
+ },
+ [0x1D5C4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D5C4,
+ },
+ [0x1D5C5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D5C5,
+ },
+ [0x1D5C6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D5C6,
+ },
+ [0x1D5C7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D5C7,
+ },
+ [0x1D5C8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x1D5C8,
+ },
+ [0x1D5C9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D5C9,
+ },
+ [0x1D5CA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D5CA,
+ },
+ [0x1D5CB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D5CB,
+ },
+ [0x1D5CC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D5CC,
+ },
+ [0x1D5CD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D5CD,
+ },
+ [0x1D5CE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D5CE,
+ },
+ [0x1D5CF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D5CF,
+ },
+ [0x1D5D0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D5D0,
+ },
+ [0x1D5D1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D5D1,
+ },
+ [0x1D5D2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D5D2,
+ },
+ [0x1D5D3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D5D3,
+ },
+ [0x1D5D4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D5D4,
+ },
+ [0x1D5D5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x1D5D5,
+ },
+ [0x1D5D6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x1D5D6,
+ },
+ [0x1D5D7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D5D7,
+ },
+ [0x1D5D8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x1D5D8,
+ },
+ [0x1D5D9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x1D5D9,
+ },
+ [0x1D5DA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D5DA,
+ },
+ [0x1D5DB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x1D5DB,
+ },
+ [0x1D5DC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x1D5DC,
+ },
+ [0x1D5DD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D5DD,
+ },
+ [0x1D5DE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D5DE,
+ },
+ [0x1D5DF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x1D5DF,
+ },
+ [0x1D5E0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x1D5E0,
+ },
+ [0x1D5E1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x1D5E1,
+ },
+ [0x1D5E2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D5E2,
+ },
+ [0x1D5E3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x1D5E3,
+ },
+ [0x1D5E4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x1D5E4,
+ },
+ [0x1D5E5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x1D5E5,
+ },
+ [0x1D5E6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D5E6,
+ },
+ [0x1D5E7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D5E7,
+ },
+ [0x1D5E8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D5E8,
+ },
+ [0x1D5E9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D5E9,
+ },
+ [0x1D5EA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D5EA,
+ },
+ [0x1D5EB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D5EB,
+ },
+ [0x1D5EC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D5EC,
+ },
+ [0x1D5ED]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x1D5ED,
+ },
+ [0x1D5EE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D5EE,
+ },
+ [0x1D5EF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D5EF,
+ },
+ [0x1D5F0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D5F0,
+ },
+ [0x1D5F1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D5F1,
+ },
+ [0x1D5F2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x1D5F2,
+ },
+ [0x1D5F3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D5F3,
+ },
+ [0x1D5F4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x1D5F4,
+ },
+ [0x1D5F5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x1D5F5,
+ },
+ [0x1D5F6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D5F6,
+ },
+ [0x1D5F7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D5F7,
+ },
+ [0x1D5F8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D5F8,
+ },
+ [0x1D5F9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D5F9,
+ },
+ [0x1D5FA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D5FA,
+ },
+ [0x1D5FB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D5FB,
+ },
+ [0x1D5FC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x1D5FC,
+ },
+ [0x1D5FD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D5FD,
+ },
+ [0x1D5FE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D5FE,
+ },
+ [0x1D5FF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D5FF,
+ },
+ [0x1D600]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D600,
+ },
+ [0x1D601]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D601,
+ },
+ [0x1D602]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D602,
+ },
+ [0x1D603]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D603,
+ },
+ [0x1D604]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D604,
+ },
+ [0x1D605]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D605,
+ },
+ [0x1D606]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D606,
+ },
+ [0x1D607]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D607,
+ },
+ [0x1D608]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D608,
+ },
+ [0x1D609]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x1D609,
+ },
+ [0x1D60A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x1D60A,
+ },
+ [0x1D60B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D60B,
+ },
+ [0x1D60C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x1D60C,
+ },
+ [0x1D60D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x1D60D,
+ },
+ [0x1D60E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D60E,
+ },
+ [0x1D60F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x1D60F,
+ },
+ [0x1D610]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x1D610,
+ },
+ [0x1D611]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D611,
+ },
+ [0x1D612]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D612,
+ },
+ [0x1D613]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x1D613,
+ },
+ [0x1D614]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x1D614,
+ },
+ [0x1D615]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x1D615,
+ },
+ [0x1D616]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D616,
+ },
+ [0x1D617]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x1D617,
+ },
+ [0x1D618]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x1D618,
+ },
+ [0x1D619]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x1D619,
+ },
+ [0x1D61A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D61A,
+ },
+ [0x1D61B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D61B,
+ },
+ [0x1D61C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D61C,
+ },
+ [0x1D61D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D61D,
+ },
+ [0x1D61E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D61E,
+ },
+ [0x1D61F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D61F,
+ },
+ [0x1D620]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D620,
+ },
+ [0x1D621]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x1D621,
+ },
+ [0x1D622]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D622,
+ },
+ [0x1D623]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D623,
+ },
+ [0x1D624]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D624,
+ },
+ [0x1D625]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D625,
+ },
+ [0x1D626]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x1D626,
+ },
+ [0x1D627]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D627,
+ },
+ [0x1D628]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x1D628,
+ },
+ [0x1D629]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x1D629,
+ },
+ [0x1D62A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D62A,
+ },
+ [0x1D62B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D62B,
+ },
+ [0x1D62C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D62C,
+ },
+ [0x1D62D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D62D,
+ },
+ [0x1D62E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D62E,
+ },
+ [0x1D62F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D62F,
+ },
+ [0x1D630]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x1D630,
+ },
+ [0x1D631]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D631,
+ },
+ [0x1D632]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D632,
+ },
+ [0x1D633]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D633,
+ },
+ [0x1D634]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D634,
+ },
+ [0x1D635]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D635,
+ },
+ [0x1D636]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D636,
+ },
+ [0x1D637]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D637,
+ },
+ [0x1D638]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D638,
+ },
+ [0x1D639]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D639,
+ },
+ [0x1D63A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D63A,
+ },
+ [0x1D63B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D63B,
+ },
+ [0x1D63C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D63C,
+ },
+ [0x1D63D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x1D63D,
+ },
+ [0x1D63E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x1D63E,
+ },
+ [0x1D63F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D63F,
+ },
+ [0x1D640]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x1D640,
+ },
+ [0x1D641]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x1D641,
+ },
+ [0x1D642]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D642,
+ },
+ [0x1D643]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x1D643,
+ },
+ [0x1D644]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x1D644,
+ },
+ [0x1D645]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D645,
+ },
+ [0x1D646]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D646,
+ },
+ [0x1D647]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x1D647,
+ },
+ [0x1D648]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x1D648,
+ },
+ [0x1D649]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x1D649,
+ },
+ [0x1D64A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D64A,
+ },
+ [0x1D64B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x1D64B,
+ },
+ [0x1D64C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x1D64C,
+ },
+ [0x1D64D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x1D64D,
+ },
+ [0x1D64E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D64E,
+ },
+ [0x1D64F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D64F,
+ },
+ [0x1D650]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D650,
+ },
+ [0x1D651]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D651,
+ },
+ [0x1D652]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D652,
+ },
+ [0x1D653]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D653,
+ },
+ [0x1D654]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D654,
+ },
+ [0x1D655]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x1D655,
+ },
+ [0x1D656]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D656,
+ },
+ [0x1D657]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D657,
+ },
+ [0x1D658]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D658,
+ },
+ [0x1D659]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D659,
+ },
+ [0x1D65A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x1D65A,
+ },
+ [0x1D65B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D65B,
+ },
+ [0x1D65C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x1D65C,
+ },
+ [0x1D65D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x1D65D,
+ },
+ [0x1D65E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D65E,
+ },
+ [0x1D65F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D65F,
+ },
+ [0x1D660]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D660,
+ },
+ [0x1D661]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D661,
+ },
+ [0x1D662]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D662,
+ },
+ [0x1D663]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D663,
+ },
+ [0x1D664]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x1D664,
+ },
+ [0x1D665]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D665,
+ },
+ [0x1D666]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D666,
+ },
+ [0x1D667]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D667,
+ },
+ [0x1D668]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D668,
+ },
+ [0x1D669]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D669,
+ },
+ [0x1D66A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D66A,
+ },
+ [0x1D66B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D66B,
+ },
+ [0x1D66C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D66C,
+ },
+ [0x1D66D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D66D,
+ },
+ [0x1D66E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D66E,
+ },
+ [0x1D66F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D66F,
+ },
+ [0x1D670]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x41 },
+ unicodeslot=0x1D670,
+ },
+ [0x1D671]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x42 },
+ unicodeslot=0x1D671,
+ },
+ [0x1D672]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x43 },
+ unicodeslot=0x1D672,
+ },
+ [0x1D673]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x44 },
+ unicodeslot=0x1D673,
+ },
+ [0x1D674]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x45 },
+ unicodeslot=0x1D674,
+ },
+ [0x1D675]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x46 },
+ unicodeslot=0x1D675,
+ },
+ [0x1D676]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x47 },
+ unicodeslot=0x1D676,
+ },
+ [0x1D677]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x48 },
+ unicodeslot=0x1D677,
+ },
+ [0x1D678]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x49 },
+ unicodeslot=0x1D678,
+ },
+ [0x1D679]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4A },
+ unicodeslot=0x1D679,
+ },
+ [0x1D67A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4B },
+ unicodeslot=0x1D67A,
+ },
+ [0x1D67B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4C },
+ unicodeslot=0x1D67B,
+ },
+ [0x1D67C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4D },
+ unicodeslot=0x1D67C,
+ },
+ [0x1D67D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4E },
+ unicodeslot=0x1D67D,
+ },
+ [0x1D67E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x4F },
+ unicodeslot=0x1D67E,
+ },
+ [0x1D67F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x50 },
+ unicodeslot=0x1D67F,
+ },
+ [0x1D680]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x51 },
+ unicodeslot=0x1D680,
+ },
+ [0x1D681]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x52 },
+ unicodeslot=0x1D681,
+ },
+ [0x1D682]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x53 },
+ unicodeslot=0x1D682,
+ },
+ [0x1D683]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x54 },
+ unicodeslot=0x1D683,
+ },
+ [0x1D684]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x55 },
+ unicodeslot=0x1D684,
+ },
+ [0x1D685]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x56 },
+ unicodeslot=0x1D685,
+ },
+ [0x1D686]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x57 },
+ unicodeslot=0x1D686,
+ },
+ [0x1D687]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x58 },
+ unicodeslot=0x1D687,
+ },
+ [0x1D688]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x59 },
+ unicodeslot=0x1D688,
+ },
+ [0x1D689]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x5A },
+ unicodeslot=0x1D689,
+ },
+ [0x1D68A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x61 },
+ unicodeslot=0x1D68A,
+ },
+ [0x1D68B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x62 },
+ unicodeslot=0x1D68B,
+ },
+ [0x1D68C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x63 },
+ unicodeslot=0x1D68C,
+ },
+ [0x1D68D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x64 },
+ unicodeslot=0x1D68D,
+ },
+ [0x1D68E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x65 },
+ unicodeslot=0x1D68E,
+ },
+ [0x1D68F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x66 },
+ unicodeslot=0x1D68F,
+ },
+ [0x1D690]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x67 },
+ unicodeslot=0x1D690,
+ },
+ [0x1D691]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x68 },
+ unicodeslot=0x1D691,
+ },
+ [0x1D692]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x69 },
+ unicodeslot=0x1D692,
+ },
+ [0x1D693]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6A },
+ unicodeslot=0x1D693,
+ },
+ [0x1D694]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6B },
+ unicodeslot=0x1D694,
+ },
+ [0x1D695]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6C },
+ unicodeslot=0x1D695,
+ },
+ [0x1D696]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6D },
+ unicodeslot=0x1D696,
+ },
+ [0x1D697]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6E },
+ unicodeslot=0x1D697,
+ },
+ [0x1D698]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x6F },
+ unicodeslot=0x1D698,
+ },
+ [0x1D699]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x70 },
+ unicodeslot=0x1D699,
+ },
+ [0x1D69A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x71 },
+ unicodeslot=0x1D69A,
+ },
+ [0x1D69B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x72 },
+ unicodeslot=0x1D69B,
+ },
+ [0x1D69C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x73 },
+ unicodeslot=0x1D69C,
+ },
+ [0x1D69D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x74 },
+ unicodeslot=0x1D69D,
+ },
+ [0x1D69E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x75 },
+ unicodeslot=0x1D69E,
+ },
+ [0x1D69F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x76 },
+ unicodeslot=0x1D69F,
+ },
+ [0x1D6A0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x77 },
+ unicodeslot=0x1D6A0,
+ },
+ [0x1D6A1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x78 },
+ unicodeslot=0x1D6A1,
+ },
+ [0x1D6A2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x79 },
+ unicodeslot=0x1D6A2,
+ },
+ [0x1D6A3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x7A },
+ unicodeslot=0x1D6A3,
+ },
+ [0x1D6A4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x131 },
+ unicodeslot=0x1D6A4,
+ },
+ [0x1D6A5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x237 },
+ unicodeslot=0x1D6A5,
+ },
+ [0x1D6A8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x391 },
+ unicodeslot=0x1D6A8,
+ },
+ [0x1D6A9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x392 },
+ unicodeslot=0x1D6A9,
+ },
+ [0x1D6AA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x393 },
+ unicodeslot=0x1D6AA,
+ },
+ [0x1D6AB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x394 },
+ unicodeslot=0x1D6AB,
+ },
+ [0x1D6AC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x395 },
+ unicodeslot=0x1D6AC,
+ },
+ [0x1D6AD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x396 },
+ unicodeslot=0x1D6AD,
+ },
+ [0x1D6AE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x397 },
+ unicodeslot=0x1D6AE,
+ },
+ [0x1D6AF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x398 },
+ unicodeslot=0x1D6AF,
+ },
+ [0x1D6B0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x399 },
+ unicodeslot=0x1D6B0,
+ },
+ [0x1D6B1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39A },
+ unicodeslot=0x1D6B1,
+ },
+ [0x1D6B2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39B },
+ unicodeslot=0x1D6B2,
+ },
+ [0x1D6B3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39C },
+ unicodeslot=0x1D6B3,
+ },
+ [0x1D6B4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39D },
+ unicodeslot=0x1D6B4,
+ },
+ [0x1D6B5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39E },
+ unicodeslot=0x1D6B5,
+ },
+ [0x1D6B6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39F },
+ unicodeslot=0x1D6B6,
+ },
+ [0x1D6B7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A0 },
+ unicodeslot=0x1D6B7,
+ },
+ [0x1D6B8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A1 },
+ unicodeslot=0x1D6B8,
+ },
+ [0x1D6B9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F4 },
+ unicodeslot=0x1D6B9,
+ },
+ [0x1D6BA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A3 },
+ unicodeslot=0x1D6BA,
+ },
+ [0x1D6BB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A4 },
+ unicodeslot=0x1D6BB,
+ },
+ [0x1D6BC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A5 },
+ unicodeslot=0x1D6BC,
+ },
+ [0x1D6BD]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A6 },
+ unicodeslot=0x1D6BD,
+ },
+ [0x1D6BE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A7 },
+ unicodeslot=0x1D6BE,
+ },
+ [0x1D6BF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A8 },
+ unicodeslot=0x1D6BF,
+ },
+ [0x1D6C0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A9 },
+ unicodeslot=0x1D6C0,
+ },
+ [0x1D6C1]={
+ category="sm",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x2207 },
+ unicodeslot=0x1D6C1,
+ },
+ [0x1D6C2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B1 },
+ unicodeslot=0x1D6C2,
+ },
+ [0x1D6C3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B2 },
+ unicodeslot=0x1D6C3,
+ },
+ [0x1D6C4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B3 },
+ unicodeslot=0x1D6C4,
+ },
+ [0x1D6C5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B4 },
+ unicodeslot=0x1D6C5,
+ },
+ [0x1D6C6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B5 },
+ unicodeslot=0x1D6C6,
+ },
+ [0x1D6C7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B6 },
+ unicodeslot=0x1D6C7,
+ },
+ [0x1D6C8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B7 },
+ unicodeslot=0x1D6C8,
+ },
+ [0x1D6C9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B8 },
+ unicodeslot=0x1D6C9,
+ },
+ [0x1D6CA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B9 },
+ unicodeslot=0x1D6CA,
+ },
+ [0x1D6CB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BA },
+ unicodeslot=0x1D6CB,
+ },
+ [0x1D6CC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BB },
+ unicodeslot=0x1D6CC,
+ },
+ [0x1D6CD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BC },
+ unicodeslot=0x1D6CD,
+ },
+ [0x1D6CE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BD },
+ unicodeslot=0x1D6CE,
+ },
+ [0x1D6CF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BE },
+ unicodeslot=0x1D6CF,
+ },
+ [0x1D6D0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BF },
+ unicodeslot=0x1D6D0,
+ },
+ [0x1D6D1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C0 },
+ unicodeslot=0x1D6D1,
+ },
+ [0x1D6D2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C1 },
+ unicodeslot=0x1D6D2,
+ },
+ [0x1D6D3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C2 },
+ unicodeslot=0x1D6D3,
+ },
+ [0x1D6D4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C3 },
+ unicodeslot=0x1D6D4,
+ },
+ [0x1D6D5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C4 },
+ unicodeslot=0x1D6D5,
+ },
+ [0x1D6D6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C5 },
+ unicodeslot=0x1D6D6,
+ },
+ [0x1D6D7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C6 },
+ unicodeslot=0x1D6D7,
+ },
+ [0x1D6D8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C7 },
+ unicodeslot=0x1D6D8,
+ },
+ [0x1D6D9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C8 },
+ unicodeslot=0x1D6D9,
+ },
+ [0x1D6DA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C9 },
+ unicodeslot=0x1D6DA,
+ },
+ [0x1D6DB]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "font", 0x2202 },
+ unicodeslot=0x1D6DB,
+ },
+ [0x1D6DC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F5 },
+ unicodeslot=0x1D6DC,
+ },
+ [0x1D6DD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D1 },
+ unicodeslot=0x1D6DD,
+ },
+ [0x1D6DE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F0 },
+ unicodeslot=0x1D6DE,
+ },
+ [0x1D6DF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D5 },
+ unicodeslot=0x1D6DF,
+ },
+ [0x1D6E0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F1 },
+ unicodeslot=0x1D6E0,
+ },
+ [0x1D6E1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D6 },
+ unicodeslot=0x1D6E1,
+ },
+ [0x1D6E2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x391 },
+ unicodeslot=0x1D6E2,
+ },
+ [0x1D6E3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x392 },
+ unicodeslot=0x1D6E3,
+ },
+ [0x1D6E4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x393 },
+ unicodeslot=0x1D6E4,
+ },
+ [0x1D6E5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x394 },
+ unicodeslot=0x1D6E5,
+ },
+ [0x1D6E6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x395 },
+ unicodeslot=0x1D6E6,
+ },
+ [0x1D6E7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x396 },
+ unicodeslot=0x1D6E7,
+ },
+ [0x1D6E8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x397 },
+ unicodeslot=0x1D6E8,
+ },
+ [0x1D6E9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x398 },
+ unicodeslot=0x1D6E9,
+ },
+ [0x1D6EA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x399 },
+ unicodeslot=0x1D6EA,
+ },
+ [0x1D6EB]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39A },
+ unicodeslot=0x1D6EB,
+ },
+ [0x1D6EC]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39B },
+ unicodeslot=0x1D6EC,
+ },
+ [0x1D6ED]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39C },
+ unicodeslot=0x1D6ED,
+ },
+ [0x1D6EE]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39D },
+ unicodeslot=0x1D6EE,
+ },
+ [0x1D6EF]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39E },
+ unicodeslot=0x1D6EF,
+ },
+ [0x1D6F0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39F },
+ unicodeslot=0x1D6F0,
+ },
+ [0x1D6F1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A0 },
+ unicodeslot=0x1D6F1,
+ },
+ [0x1D6F2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A1 },
+ unicodeslot=0x1D6F2,
+ },
+ [0x1D6F3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F4 },
+ unicodeslot=0x1D6F3,
+ },
+ [0x1D6F4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A3 },
+ unicodeslot=0x1D6F4,
+ },
+ [0x1D6F5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A4 },
+ unicodeslot=0x1D6F5,
+ },
+ [0x1D6F6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A5 },
+ unicodeslot=0x1D6F6,
+ },
+ [0x1D6F7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A6 },
+ unicodeslot=0x1D6F7,
+ },
+ [0x1D6F8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A7 },
+ unicodeslot=0x1D6F8,
+ },
+ [0x1D6F9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A8 },
+ unicodeslot=0x1D6F9,
+ },
+ [0x1D6FA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A9 },
+ unicodeslot=0x1D6FA,
+ },
+ [0x1D6FB]={
+ category="sm",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x2207 },
+ unicodeslot=0x1D6FB,
+ },
+ [0x1D6FC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B1 },
+ unicodeslot=0x1D6FC,
+ },
+ [0x1D6FD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B2 },
+ unicodeslot=0x1D6FD,
+ },
+ [0x1D6FE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B3 },
+ unicodeslot=0x1D6FE,
+ },
+ [0x1D6FF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B4 },
+ unicodeslot=0x1D6FF,
+ },
+ [0x1D700]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B5 },
+ unicodeslot=0x1D700,
+ },
+ [0x1D701]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B6 },
+ unicodeslot=0x1D701,
+ },
+ [0x1D702]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B7 },
+ unicodeslot=0x1D702,
+ },
+ [0x1D703]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B8 },
+ unicodeslot=0x1D703,
+ },
+ [0x1D704]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B9 },
+ unicodeslot=0x1D704,
+ },
+ [0x1D705]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BA },
+ unicodeslot=0x1D705,
+ },
+ [0x1D706]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BB },
+ unicodeslot=0x1D706,
+ },
+ [0x1D707]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BC },
+ unicodeslot=0x1D707,
+ },
+ [0x1D708]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BD },
+ unicodeslot=0x1D708,
+ },
+ [0x1D709]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BE },
+ unicodeslot=0x1D709,
+ },
+ [0x1D70A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BF },
+ unicodeslot=0x1D70A,
+ },
+ [0x1D70B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C0 },
+ unicodeslot=0x1D70B,
+ },
+ [0x1D70C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C1 },
+ unicodeslot=0x1D70C,
+ },
+ [0x1D70D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C2 },
+ unicodeslot=0x1D70D,
+ },
+ [0x1D70E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C3 },
+ unicodeslot=0x1D70E,
+ },
+ [0x1D70F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C4 },
+ unicodeslot=0x1D70F,
+ },
+ [0x1D710]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C5 },
+ unicodeslot=0x1D710,
+ },
+ [0x1D711]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C6 },
+ unicodeslot=0x1D711,
+ },
+ [0x1D712]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C7 },
+ unicodeslot=0x1D712,
+ },
+ [0x1D713]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C8 },
+ unicodeslot=0x1D713,
+ },
+ [0x1D714]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C9 },
+ unicodeslot=0x1D714,
+ },
+ [0x1D715]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "font", 0x2202 },
+ unicodeslot=0x1D715,
+ },
+ [0x1D716]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F5 },
+ unicodeslot=0x1D716,
+ },
+ [0x1D717]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D1 },
+ unicodeslot=0x1D717,
+ },
+ [0x1D718]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F0 },
+ unicodeslot=0x1D718,
+ },
+ [0x1D719]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D5 },
+ unicodeslot=0x1D719,
+ },
+ [0x1D71A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F1 },
+ unicodeslot=0x1D71A,
+ },
+ [0x1D71B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D6 },
+ unicodeslot=0x1D71B,
+ },
+ [0x1D71C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x391 },
+ unicodeslot=0x1D71C,
+ },
+ [0x1D71D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x392 },
+ unicodeslot=0x1D71D,
+ },
+ [0x1D71E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x393 },
+ unicodeslot=0x1D71E,
+ },
+ [0x1D71F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x394 },
+ unicodeslot=0x1D71F,
+ },
+ [0x1D720]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x395 },
+ unicodeslot=0x1D720,
+ },
+ [0x1D721]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x396 },
+ unicodeslot=0x1D721,
+ },
+ [0x1D722]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x397 },
+ unicodeslot=0x1D722,
+ },
+ [0x1D723]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x398 },
+ unicodeslot=0x1D723,
+ },
+ [0x1D724]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x399 },
+ unicodeslot=0x1D724,
+ },
+ [0x1D725]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39A },
+ unicodeslot=0x1D725,
+ },
+ [0x1D726]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39B },
+ unicodeslot=0x1D726,
+ },
+ [0x1D727]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39C },
+ unicodeslot=0x1D727,
+ },
+ [0x1D728]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39D },
+ unicodeslot=0x1D728,
+ },
+ [0x1D729]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39E },
+ unicodeslot=0x1D729,
+ },
+ [0x1D72A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39F },
+ unicodeslot=0x1D72A,
+ },
+ [0x1D72B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A0 },
+ unicodeslot=0x1D72B,
+ },
+ [0x1D72C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A1 },
+ unicodeslot=0x1D72C,
+ },
+ [0x1D72D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F4 },
+ unicodeslot=0x1D72D,
+ },
+ [0x1D72E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A3 },
+ unicodeslot=0x1D72E,
+ },
+ [0x1D72F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A4 },
+ unicodeslot=0x1D72F,
+ },
+ [0x1D730]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A5 },
+ unicodeslot=0x1D730,
+ },
+ [0x1D731]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A6 },
+ unicodeslot=0x1D731,
+ },
+ [0x1D732]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A7 },
+ unicodeslot=0x1D732,
+ },
+ [0x1D733]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A8 },
+ unicodeslot=0x1D733,
+ },
+ [0x1D734]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A9 },
+ unicodeslot=0x1D734,
+ },
+ [0x1D735]={
+ category="sm",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x2207 },
+ unicodeslot=0x1D735,
+ },
+ [0x1D736]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B1 },
+ unicodeslot=0x1D736,
+ },
+ [0x1D737]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B2 },
+ unicodeslot=0x1D737,
+ },
+ [0x1D738]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B3 },
+ unicodeslot=0x1D738,
+ },
+ [0x1D739]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B4 },
+ unicodeslot=0x1D739,
+ },
+ [0x1D73A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B5 },
+ unicodeslot=0x1D73A,
+ },
+ [0x1D73B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B6 },
+ unicodeslot=0x1D73B,
+ },
+ [0x1D73C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B7 },
+ unicodeslot=0x1D73C,
+ },
+ [0x1D73D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B8 },
+ unicodeslot=0x1D73D,
+ },
+ [0x1D73E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B9 },
+ unicodeslot=0x1D73E,
+ },
+ [0x1D73F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BA },
+ unicodeslot=0x1D73F,
+ },
+ [0x1D740]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BB },
+ unicodeslot=0x1D740,
+ },
+ [0x1D741]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BC },
+ unicodeslot=0x1D741,
+ },
+ [0x1D742]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BD },
+ unicodeslot=0x1D742,
+ },
+ [0x1D743]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BE },
+ unicodeslot=0x1D743,
+ },
+ [0x1D744]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BF },
+ unicodeslot=0x1D744,
+ },
+ [0x1D745]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C0 },
+ unicodeslot=0x1D745,
+ },
+ [0x1D746]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C1 },
+ unicodeslot=0x1D746,
+ },
+ [0x1D747]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C2 },
+ unicodeslot=0x1D747,
+ },
+ [0x1D748]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C3 },
+ unicodeslot=0x1D748,
+ },
+ [0x1D749]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C4 },
+ unicodeslot=0x1D749,
+ },
+ [0x1D74A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C5 },
+ unicodeslot=0x1D74A,
+ },
+ [0x1D74B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C6 },
+ unicodeslot=0x1D74B,
+ },
+ [0x1D74C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C7 },
+ unicodeslot=0x1D74C,
+ },
+ [0x1D74D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C8 },
+ unicodeslot=0x1D74D,
+ },
+ [0x1D74E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C9 },
+ unicodeslot=0x1D74E,
+ },
+ [0x1D74F]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "font", 0x2202 },
+ unicodeslot=0x1D74F,
+ },
+ [0x1D750]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F5 },
+ unicodeslot=0x1D750,
+ },
+ [0x1D751]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D1 },
+ unicodeslot=0x1D751,
+ },
+ [0x1D752]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F0 },
+ unicodeslot=0x1D752,
+ },
+ [0x1D753]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D5 },
+ unicodeslot=0x1D753,
+ },
+ [0x1D754]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F1 },
+ unicodeslot=0x1D754,
+ },
+ [0x1D755]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D6 },
+ unicodeslot=0x1D755,
+ },
+ [0x1D756]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x391 },
+ unicodeslot=0x1D756,
+ },
+ [0x1D757]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x392 },
+ unicodeslot=0x1D757,
+ },
+ [0x1D758]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x393 },
+ unicodeslot=0x1D758,
+ },
+ [0x1D759]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x394 },
+ unicodeslot=0x1D759,
+ },
+ [0x1D75A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x395 },
+ unicodeslot=0x1D75A,
+ },
+ [0x1D75B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x396 },
+ unicodeslot=0x1D75B,
+ },
+ [0x1D75C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x397 },
+ unicodeslot=0x1D75C,
+ },
+ [0x1D75D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x398 },
+ unicodeslot=0x1D75D,
+ },
+ [0x1D75E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x399 },
+ unicodeslot=0x1D75E,
+ },
+ [0x1D75F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39A },
+ unicodeslot=0x1D75F,
+ },
+ [0x1D760]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39B },
+ unicodeslot=0x1D760,
+ },
+ [0x1D761]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39C },
+ unicodeslot=0x1D761,
+ },
+ [0x1D762]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39D },
+ unicodeslot=0x1D762,
+ },
+ [0x1D763]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39E },
+ unicodeslot=0x1D763,
+ },
+ [0x1D764]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39F },
+ unicodeslot=0x1D764,
+ },
+ [0x1D765]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A0 },
+ unicodeslot=0x1D765,
+ },
+ [0x1D766]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A1 },
+ unicodeslot=0x1D766,
+ },
+ [0x1D767]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F4 },
+ unicodeslot=0x1D767,
+ },
+ [0x1D768]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A3 },
+ unicodeslot=0x1D768,
+ },
+ [0x1D769]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A4 },
+ unicodeslot=0x1D769,
+ },
+ [0x1D76A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A5 },
+ unicodeslot=0x1D76A,
+ },
+ [0x1D76B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A6 },
+ unicodeslot=0x1D76B,
+ },
+ [0x1D76C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A7 },
+ unicodeslot=0x1D76C,
+ },
+ [0x1D76D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A8 },
+ unicodeslot=0x1D76D,
+ },
+ [0x1D76E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A9 },
+ unicodeslot=0x1D76E,
+ },
+ [0x1D76F]={
+ category="sm",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x2207 },
+ unicodeslot=0x1D76F,
+ },
+ [0x1D770]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B1 },
+ unicodeslot=0x1D770,
+ },
+ [0x1D771]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B2 },
+ unicodeslot=0x1D771,
+ },
+ [0x1D772]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B3 },
+ unicodeslot=0x1D772,
+ },
+ [0x1D773]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B4 },
+ unicodeslot=0x1D773,
+ },
+ [0x1D774]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B5 },
+ unicodeslot=0x1D774,
+ },
+ [0x1D775]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B6 },
+ unicodeslot=0x1D775,
+ },
+ [0x1D776]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B7 },
+ unicodeslot=0x1D776,
+ },
+ [0x1D777]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B8 },
+ unicodeslot=0x1D777,
+ },
+ [0x1D778]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B9 },
+ unicodeslot=0x1D778,
+ },
+ [0x1D779]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BA },
+ unicodeslot=0x1D779,
+ },
+ [0x1D77A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BB },
+ unicodeslot=0x1D77A,
+ },
+ [0x1D77B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BC },
+ unicodeslot=0x1D77B,
+ },
+ [0x1D77C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BD },
+ unicodeslot=0x1D77C,
+ },
+ [0x1D77D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BE },
+ unicodeslot=0x1D77D,
+ },
+ [0x1D77E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BF },
+ unicodeslot=0x1D77E,
+ },
+ [0x1D77F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C0 },
+ unicodeslot=0x1D77F,
+ },
+ [0x1D780]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C1 },
+ unicodeslot=0x1D780,
+ },
+ [0x1D781]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C2 },
+ unicodeslot=0x1D781,
+ },
+ [0x1D782]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C3 },
+ unicodeslot=0x1D782,
+ },
+ [0x1D783]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C4 },
+ unicodeslot=0x1D783,
+ },
+ [0x1D784]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C5 },
+ unicodeslot=0x1D784,
+ },
+ [0x1D785]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C6 },
+ unicodeslot=0x1D785,
+ },
+ [0x1D786]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C7 },
+ unicodeslot=0x1D786,
+ },
+ [0x1D787]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C8 },
+ unicodeslot=0x1D787,
+ },
+ [0x1D788]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C9 },
+ unicodeslot=0x1D788,
+ },
+ [0x1D789]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "font", 0x2202 },
+ unicodeslot=0x1D789,
+ },
+ [0x1D78A]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F5 },
+ unicodeslot=0x1D78A,
+ },
+ [0x1D78B]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D1 },
+ unicodeslot=0x1D78B,
+ },
+ [0x1D78C]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F0 },
+ unicodeslot=0x1D78C,
+ },
+ [0x1D78D]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D5 },
+ unicodeslot=0x1D78D,
+ },
+ [0x1D78E]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F1 },
+ unicodeslot=0x1D78E,
+ },
+ [0x1D78F]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D6 },
+ unicodeslot=0x1D78F,
+ },
+ [0x1D790]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x391 },
+ unicodeslot=0x1D790,
+ },
+ [0x1D791]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x392 },
+ unicodeslot=0x1D791,
+ },
+ [0x1D792]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x393 },
+ unicodeslot=0x1D792,
+ },
+ [0x1D793]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x394 },
+ unicodeslot=0x1D793,
+ },
+ [0x1D794]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x395 },
+ unicodeslot=0x1D794,
+ },
+ [0x1D795]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x396 },
+ unicodeslot=0x1D795,
+ },
+ [0x1D796]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x397 },
+ unicodeslot=0x1D796,
+ },
+ [0x1D797]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x398 },
+ unicodeslot=0x1D797,
+ },
+ [0x1D798]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x399 },
+ unicodeslot=0x1D798,
+ },
+ [0x1D799]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39A },
+ unicodeslot=0x1D799,
+ },
+ [0x1D79A]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39B },
+ unicodeslot=0x1D79A,
+ },
+ [0x1D79B]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39C },
+ unicodeslot=0x1D79B,
+ },
+ [0x1D79C]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39D },
+ unicodeslot=0x1D79C,
+ },
+ [0x1D79D]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39E },
+ unicodeslot=0x1D79D,
+ },
+ [0x1D79E]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x39F },
+ unicodeslot=0x1D79E,
+ },
+ [0x1D79F]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A0 },
+ unicodeslot=0x1D79F,
+ },
+ [0x1D7A0]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A1 },
+ unicodeslot=0x1D7A0,
+ },
+ [0x1D7A1]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F4 },
+ unicodeslot=0x1D7A1,
+ },
+ [0x1D7A2]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A3 },
+ unicodeslot=0x1D7A2,
+ },
+ [0x1D7A3]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A4 },
+ unicodeslot=0x1D7A3,
+ },
+ [0x1D7A4]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A5 },
+ unicodeslot=0x1D7A4,
+ },
+ [0x1D7A5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A6 },
+ unicodeslot=0x1D7A5,
+ },
+ [0x1D7A6]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A7 },
+ unicodeslot=0x1D7A6,
+ },
+ [0x1D7A7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A8 },
+ unicodeslot=0x1D7A7,
+ },
+ [0x1D7A8]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3A9 },
+ unicodeslot=0x1D7A8,
+ },
+ [0x1D7A9]={
+ category="sm",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x2207 },
+ unicodeslot=0x1D7A9,
+ },
+ [0x1D7AA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B1 },
+ unicodeslot=0x1D7AA,
+ },
+ [0x1D7AB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B2 },
+ unicodeslot=0x1D7AB,
+ },
+ [0x1D7AC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B3 },
+ unicodeslot=0x1D7AC,
+ },
+ [0x1D7AD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B4 },
+ unicodeslot=0x1D7AD,
+ },
+ [0x1D7AE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B5 },
+ unicodeslot=0x1D7AE,
+ },
+ [0x1D7AF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B6 },
+ unicodeslot=0x1D7AF,
+ },
+ [0x1D7B0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B7 },
+ unicodeslot=0x1D7B0,
+ },
+ [0x1D7B1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B8 },
+ unicodeslot=0x1D7B1,
+ },
+ [0x1D7B2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3B9 },
+ unicodeslot=0x1D7B2,
+ },
+ [0x1D7B3]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BA },
+ unicodeslot=0x1D7B3,
+ },
+ [0x1D7B4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BB },
+ unicodeslot=0x1D7B4,
+ },
+ [0x1D7B5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BC },
+ unicodeslot=0x1D7B5,
+ },
+ [0x1D7B6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BD },
+ unicodeslot=0x1D7B6,
+ },
+ [0x1D7B7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BE },
+ unicodeslot=0x1D7B7,
+ },
+ [0x1D7B8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3BF },
+ unicodeslot=0x1D7B8,
+ },
+ [0x1D7B9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C0 },
+ unicodeslot=0x1D7B9,
+ },
+ [0x1D7BA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C1 },
+ unicodeslot=0x1D7BA,
+ },
+ [0x1D7BB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C2 },
+ unicodeslot=0x1D7BB,
+ },
+ [0x1D7BC]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C3 },
+ unicodeslot=0x1D7BC,
+ },
+ [0x1D7BD]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C4 },
+ unicodeslot=0x1D7BD,
+ },
+ [0x1D7BE]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C5 },
+ unicodeslot=0x1D7BE,
+ },
+ [0x1D7BF]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C6 },
+ unicodeslot=0x1D7BF,
+ },
+ [0x1D7C0]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C7 },
+ unicodeslot=0x1D7C0,
+ },
+ [0x1D7C1]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C8 },
+ unicodeslot=0x1D7C1,
+ },
+ [0x1D7C2]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3C9 },
+ unicodeslot=0x1D7C2,
+ },
+ [0x1D7C3]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ specials={ "font", 0x2202 },
+ unicodeslot=0x1D7C3,
+ },
+ [0x1D7C4]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F5 },
+ unicodeslot=0x1D7C4,
+ },
+ [0x1D7C5]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D1 },
+ unicodeslot=0x1D7C5,
+ },
+ [0x1D7C6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F0 },
+ unicodeslot=0x1D7C6,
+ },
+ [0x1D7C7]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D5 },
+ unicodeslot=0x1D7C7,
+ },
+ [0x1D7C8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3F1 },
+ unicodeslot=0x1D7C8,
+ },
+ [0x1D7C9]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3D6 },
+ unicodeslot=0x1D7C9,
+ },
+ [0x1D7CA]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3DC },
+ unicodeslot=0x1D7CA,
+ },
+ [0x1D7CB]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x3DD },
+ unicodeslot=0x1D7CB,
+ },
+ [0x1D7CE]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x30 },
+ unicodeslot=0x1D7CE,
+ },
+ [0x1D7CF]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x31 },
+ unicodeslot=0x1D7CF,
+ },
+ [0x1D7D0]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x32 },
+ unicodeslot=0x1D7D0,
+ },
+ [0x1D7D1]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x33 },
+ unicodeslot=0x1D7D1,
+ },
+ [0x1D7D2]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x34 },
+ unicodeslot=0x1D7D2,
+ },
+ [0x1D7D3]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x35 },
+ unicodeslot=0x1D7D3,
+ },
+ [0x1D7D4]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x36 },
+ unicodeslot=0x1D7D4,
+ },
+ [0x1D7D5]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x37 },
+ unicodeslot=0x1D7D5,
+ },
+ [0x1D7D6]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x38 },
+ unicodeslot=0x1D7D6,
+ },
+ [0x1D7D7]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x39 },
+ unicodeslot=0x1D7D7,
+ },
+ [0x1D7D8]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x30 },
+ unicodeslot=0x1D7D8,
+ },
+ [0x1D7D9]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x31 },
+ unicodeslot=0x1D7D9,
+ },
+ [0x1D7DA]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x32 },
+ unicodeslot=0x1D7DA,
+ },
+ [0x1D7DB]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x33 },
+ unicodeslot=0x1D7DB,
+ },
+ [0x1D7DC]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x34 },
+ unicodeslot=0x1D7DC,
+ },
+ [0x1D7DD]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x35 },
+ unicodeslot=0x1D7DD,
+ },
+ [0x1D7DE]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x36 },
+ unicodeslot=0x1D7DE,
+ },
+ [0x1D7DF]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x37 },
+ unicodeslot=0x1D7DF,
+ },
+ [0x1D7E0]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x38 },
+ unicodeslot=0x1D7E0,
+ },
+ [0x1D7E1]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x39 },
+ unicodeslot=0x1D7E1,
+ },
+ [0x1D7E2]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x30 },
+ unicodeslot=0x1D7E2,
+ },
+ [0x1D7E3]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x31 },
+ unicodeslot=0x1D7E3,
+ },
+ [0x1D7E4]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x32 },
+ unicodeslot=0x1D7E4,
+ },
+ [0x1D7E5]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x33 },
+ unicodeslot=0x1D7E5,
+ },
+ [0x1D7E6]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x34 },
+ unicodeslot=0x1D7E6,
+ },
+ [0x1D7E7]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x35 },
+ unicodeslot=0x1D7E7,
+ },
+ [0x1D7E8]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x36 },
+ unicodeslot=0x1D7E8,
+ },
+ [0x1D7E9]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x37 },
+ unicodeslot=0x1D7E9,
+ },
+ [0x1D7EA]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x38 },
+ unicodeslot=0x1D7EA,
+ },
+ [0x1D7EB]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x39 },
+ unicodeslot=0x1D7EB,
+ },
+ [0x1D7EC]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x30 },
+ unicodeslot=0x1D7EC,
+ },
+ [0x1D7ED]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x31 },
+ unicodeslot=0x1D7ED,
+ },
+ [0x1D7EE]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x32 },
+ unicodeslot=0x1D7EE,
+ },
+ [0x1D7EF]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x33 },
+ unicodeslot=0x1D7EF,
+ },
+ [0x1D7F0]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x34 },
+ unicodeslot=0x1D7F0,
+ },
+ [0x1D7F1]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x35 },
+ unicodeslot=0x1D7F1,
+ },
+ [0x1D7F2]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x36 },
+ unicodeslot=0x1D7F2,
+ },
+ [0x1D7F3]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x37 },
+ unicodeslot=0x1D7F3,
+ },
+ [0x1D7F4]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x38 },
+ unicodeslot=0x1D7F4,
+ },
+ [0x1D7F5]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x39 },
+ unicodeslot=0x1D7F5,
+ },
+ [0x1D7F6]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x30 },
+ unicodeslot=0x1D7F6,
+ },
+ [0x1D7F7]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x31 },
+ unicodeslot=0x1D7F7,
+ },
+ [0x1D7F8]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x32 },
+ unicodeslot=0x1D7F8,
+ },
+ [0x1D7F9]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x33 },
+ unicodeslot=0x1D7F9,
+ },
+ [0x1D7FA]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x34 },
+ unicodeslot=0x1D7FA,
+ },
+ [0x1D7FB]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x35 },
+ unicodeslot=0x1D7FB,
+ },
+ [0x1D7FC]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x36 },
+ unicodeslot=0x1D7FC,
+ },
+ [0x1D7FD]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x37 },
+ unicodeslot=0x1D7FD,
+ },
+ [0x1D7FE]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x38 },
+ unicodeslot=0x1D7FE,
+ },
+ [0x1D7FF]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x39 },
+ unicodeslot=0x1D7FF,
+ },
+ [0x1D800]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D800,
+ },
+ [0x1D801]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D801,
+ },
+ [0x1D802]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D802,
+ },
+ [0x1D803]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D803,
+ },
+ [0x1D804]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D804,
+ },
+ [0x1D805]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D805,
+ },
+ [0x1D806]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D806,
+ },
+ [0x1D807]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D807,
+ },
+ [0x1D808]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D808,
+ },
+ [0x1D809]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D809,
+ },
+ [0x1D80A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D80A,
+ },
+ [0x1D80B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D80B,
+ },
+ [0x1D80C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D80C,
+ },
+ [0x1D80D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D80D,
+ },
+ [0x1D80E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D80E,
+ },
+ [0x1D80F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D80F,
+ },
+ [0x1D810]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D810,
+ },
+ [0x1D811]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D811,
+ },
+ [0x1D812]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D812,
+ },
+ [0x1D813]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D813,
+ },
+ [0x1D814]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D814,
+ },
+ [0x1D815]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D815,
+ },
+ [0x1D816]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D816,
+ },
+ [0x1D817]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D817,
+ },
+ [0x1D818]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D818,
+ },
+ [0x1D819]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D819,
+ },
+ [0x1D81A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D81A,
+ },
+ [0x1D81B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D81B,
+ },
+ [0x1D81C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D81C,
+ },
+ [0x1D81D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D81D,
+ },
+ [0x1D81E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D81E,
+ },
+ [0x1D81F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D81F,
+ },
+ [0x1D820]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D820,
+ },
+ [0x1D821]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D821,
+ },
+ [0x1D822]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D822,
+ },
+ [0x1D823]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D823,
+ },
+ [0x1D824]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D824,
+ },
+ [0x1D825]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D825,
+ },
+ [0x1D826]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D826,
+ },
+ [0x1D827]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D827,
+ },
+ [0x1D828]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D828,
+ },
+ [0x1D829]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D829,
+ },
+ [0x1D82A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D82A,
+ },
+ [0x1D82B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D82B,
+ },
+ [0x1D82C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D82C,
+ },
+ [0x1D82D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D82D,
+ },
+ [0x1D82E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D82E,
+ },
+ [0x1D82F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D82F,
+ },
+ [0x1D830]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D830,
+ },
+ [0x1D831]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D831,
+ },
+ [0x1D832]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D832,
+ },
+ [0x1D833]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D833,
+ },
+ [0x1D834]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D834,
+ },
+ [0x1D835]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D835,
+ },
+ [0x1D836]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D836,
+ },
+ [0x1D837]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D837,
+ },
+ [0x1D838]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D838,
+ },
+ [0x1D839]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D839,
+ },
+ [0x1D83A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D83A,
+ },
+ [0x1D83B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D83B,
+ },
+ [0x1D83C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D83C,
+ },
+ [0x1D83D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D83D,
+ },
+ [0x1D83E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D83E,
+ },
+ [0x1D83F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D83F,
+ },
+ [0x1D840]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D840,
+ },
+ [0x1D841]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D841,
+ },
+ [0x1D842]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D842,
+ },
+ [0x1D843]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D843,
+ },
+ [0x1D844]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D844,
+ },
+ [0x1D845]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D845,
+ },
+ [0x1D846]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D846,
+ },
+ [0x1D847]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D847,
+ },
+ [0x1D848]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D848,
+ },
+ [0x1D849]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D849,
+ },
+ [0x1D84A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D84A,
+ },
+ [0x1D84B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D84B,
+ },
+ [0x1D84C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D84C,
+ },
+ [0x1D84D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D84D,
+ },
+ [0x1D84E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D84E,
+ },
+ [0x1D84F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D84F,
+ },
+ [0x1D850]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D850,
+ },
+ [0x1D851]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D851,
+ },
+ [0x1D852]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D852,
+ },
+ [0x1D853]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D853,
+ },
+ [0x1D854]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D854,
+ },
+ [0x1D855]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D855,
+ },
+ [0x1D856]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D856,
+ },
+ [0x1D857]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D857,
+ },
+ [0x1D858]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D858,
+ },
+ [0x1D859]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D859,
+ },
+ [0x1D85A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D85A,
+ },
+ [0x1D85B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D85B,
+ },
+ [0x1D85C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D85C,
+ },
+ [0x1D85D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D85D,
+ },
+ [0x1D85E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D85E,
+ },
+ [0x1D85F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D85F,
+ },
+ [0x1D860]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D860,
+ },
+ [0x1D861]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D861,
+ },
+ [0x1D862]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D862,
+ },
+ [0x1D863]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D863,
+ },
+ [0x1D864]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D864,
+ },
+ [0x1D865]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D865,
+ },
+ [0x1D866]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D866,
+ },
+ [0x1D867]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D867,
+ },
+ [0x1D868]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D868,
+ },
+ [0x1D869]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D869,
+ },
+ [0x1D86A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D86A,
+ },
+ [0x1D86B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D86B,
+ },
+ [0x1D86C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D86C,
+ },
+ [0x1D86D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D86D,
+ },
+ [0x1D86E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D86E,
+ },
+ [0x1D86F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D86F,
+ },
+ [0x1D870]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D870,
+ },
+ [0x1D871]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D871,
+ },
+ [0x1D872]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D872,
+ },
+ [0x1D873]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D873,
+ },
+ [0x1D874]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D874,
+ },
+ [0x1D875]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D875,
+ },
+ [0x1D876]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D876,
+ },
+ [0x1D877]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D877,
+ },
+ [0x1D878]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D878,
+ },
+ [0x1D879]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D879,
+ },
+ [0x1D87A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D87A,
+ },
+ [0x1D87B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D87B,
+ },
+ [0x1D87C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D87C,
+ },
+ [0x1D87D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D87D,
+ },
+ [0x1D87E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D87E,
+ },
+ [0x1D87F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D87F,
+ },
+ [0x1D880]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D880,
+ },
+ [0x1D881]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D881,
+ },
+ [0x1D882]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D882,
+ },
+ [0x1D883]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D883,
+ },
+ [0x1D884]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D884,
+ },
+ [0x1D885]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D885,
+ },
+ [0x1D886]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D886,
+ },
+ [0x1D887]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D887,
+ },
+ [0x1D888]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D888,
+ },
+ [0x1D889]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D889,
+ },
+ [0x1D88A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D88A,
+ },
+ [0x1D88B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D88B,
+ },
+ [0x1D88C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D88C,
+ },
+ [0x1D88D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D88D,
+ },
+ [0x1D88E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D88E,
+ },
+ [0x1D88F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D88F,
+ },
+ [0x1D890]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D890,
+ },
+ [0x1D891]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D891,
+ },
+ [0x1D892]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D892,
+ },
+ [0x1D893]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D893,
+ },
+ [0x1D894]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D894,
+ },
+ [0x1D895]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D895,
+ },
+ [0x1D896]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D896,
+ },
+ [0x1D897]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D897,
+ },
+ [0x1D898]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D898,
+ },
+ [0x1D899]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D899,
+ },
+ [0x1D89A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D89A,
+ },
+ [0x1D89B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D89B,
+ },
+ [0x1D89C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D89C,
+ },
+ [0x1D89D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D89D,
+ },
+ [0x1D89E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D89E,
+ },
+ [0x1D89F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D89F,
+ },
+ [0x1D8A0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8A0,
+ },
+ [0x1D8A1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8A1,
+ },
+ [0x1D8A2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8A2,
+ },
+ [0x1D8A3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8A3,
+ },
+ [0x1D8A4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8A4,
+ },
+ [0x1D8A5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8A5,
+ },
+ [0x1D8A6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8A6,
+ },
+ [0x1D8A7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8A7,
+ },
+ [0x1D8A8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8A8,
+ },
+ [0x1D8A9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8A9,
+ },
+ [0x1D8AA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8AA,
+ },
+ [0x1D8AB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8AB,
+ },
+ [0x1D8AC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8AC,
+ },
+ [0x1D8AD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8AD,
+ },
+ [0x1D8AE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8AE,
+ },
+ [0x1D8AF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8AF,
+ },
+ [0x1D8B0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8B0,
+ },
+ [0x1D8B1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8B1,
+ },
+ [0x1D8B2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8B2,
+ },
+ [0x1D8B3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8B3,
+ },
+ [0x1D8B4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8B4,
+ },
+ [0x1D8B5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8B5,
+ },
+ [0x1D8B6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8B6,
+ },
+ [0x1D8B7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8B7,
+ },
+ [0x1D8B8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8B8,
+ },
+ [0x1D8B9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8B9,
+ },
+ [0x1D8BA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8BA,
+ },
+ [0x1D8BB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8BB,
+ },
+ [0x1D8BC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8BC,
+ },
+ [0x1D8BD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8BD,
+ },
+ [0x1D8BE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8BE,
+ },
+ [0x1D8BF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8BF,
+ },
+ [0x1D8C0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8C0,
+ },
+ [0x1D8C1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8C1,
+ },
+ [0x1D8C2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8C2,
+ },
+ [0x1D8C3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8C3,
+ },
+ [0x1D8C4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8C4,
+ },
+ [0x1D8C5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8C5,
+ },
+ [0x1D8C6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8C6,
+ },
+ [0x1D8C7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8C7,
+ },
+ [0x1D8C8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8C8,
+ },
+ [0x1D8C9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8C9,
+ },
+ [0x1D8CA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8CA,
+ },
+ [0x1D8CB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8CB,
+ },
+ [0x1D8CC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8CC,
+ },
+ [0x1D8CD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8CD,
+ },
+ [0x1D8CE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8CE,
+ },
+ [0x1D8CF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8CF,
+ },
+ [0x1D8D0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8D0,
+ },
+ [0x1D8D1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8D1,
+ },
+ [0x1D8D2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8D2,
+ },
+ [0x1D8D3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8D3,
+ },
+ [0x1D8D4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8D4,
+ },
+ [0x1D8D5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8D5,
+ },
+ [0x1D8D6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8D6,
+ },
+ [0x1D8D7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8D7,
+ },
+ [0x1D8D8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8D8,
+ },
+ [0x1D8D9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8D9,
+ },
+ [0x1D8DA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8DA,
+ },
+ [0x1D8DB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8DB,
+ },
+ [0x1D8DC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8DC,
+ },
+ [0x1D8DD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8DD,
+ },
+ [0x1D8DE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8DE,
+ },
+ [0x1D8DF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8DF,
+ },
+ [0x1D8E0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8E0,
+ },
+ [0x1D8E1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8E1,
+ },
+ [0x1D8E2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8E2,
+ },
+ [0x1D8E3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8E3,
+ },
+ [0x1D8E4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8E4,
+ },
+ [0x1D8E5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8E5,
+ },
+ [0x1D8E6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8E6,
+ },
+ [0x1D8E7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8E7,
+ },
+ [0x1D8E8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8E8,
+ },
+ [0x1D8E9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8E9,
+ },
+ [0x1D8EA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8EA,
+ },
+ [0x1D8EB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8EB,
+ },
+ [0x1D8EC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8EC,
+ },
+ [0x1D8ED]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8ED,
+ },
+ [0x1D8EE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8EE,
+ },
+ [0x1D8EF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8EF,
+ },
+ [0x1D8F0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8F0,
+ },
+ [0x1D8F1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8F1,
+ },
+ [0x1D8F2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8F2,
+ },
+ [0x1D8F3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8F3,
+ },
+ [0x1D8F4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8F4,
+ },
+ [0x1D8F5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8F5,
+ },
+ [0x1D8F6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8F6,
+ },
+ [0x1D8F7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8F7,
+ },
+ [0x1D8F8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8F8,
+ },
+ [0x1D8F9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8F9,
+ },
+ [0x1D8FA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8FA,
+ },
+ [0x1D8FB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8FB,
+ },
+ [0x1D8FC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8FC,
+ },
+ [0x1D8FD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8FD,
+ },
+ [0x1D8FE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8FE,
+ },
+ [0x1D8FF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D8FF,
+ },
+ [0x1D900]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D900,
+ },
+ [0x1D901]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D901,
+ },
+ [0x1D902]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D902,
+ },
+ [0x1D903]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D903,
+ },
+ [0x1D904]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D904,
+ },
+ [0x1D905]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D905,
+ },
+ [0x1D906]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D906,
+ },
+ [0x1D907]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D907,
+ },
+ [0x1D908]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D908,
+ },
+ [0x1D909]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D909,
+ },
+ [0x1D90A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D90A,
+ },
+ [0x1D90B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D90B,
+ },
+ [0x1D90C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D90C,
+ },
+ [0x1D90D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D90D,
+ },
+ [0x1D90E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D90E,
+ },
+ [0x1D90F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D90F,
+ },
+ [0x1D910]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D910,
+ },
+ [0x1D911]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D911,
+ },
+ [0x1D912]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D912,
+ },
+ [0x1D913]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D913,
+ },
+ [0x1D914]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D914,
+ },
+ [0x1D915]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D915,
+ },
+ [0x1D916]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D916,
+ },
+ [0x1D917]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D917,
+ },
+ [0x1D918]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D918,
+ },
+ [0x1D919]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D919,
+ },
+ [0x1D91A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D91A,
+ },
+ [0x1D91B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D91B,
+ },
+ [0x1D91C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D91C,
+ },
+ [0x1D91D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D91D,
+ },
+ [0x1D91E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D91E,
+ },
+ [0x1D91F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D91F,
+ },
+ [0x1D920]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D920,
+ },
+ [0x1D921]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D921,
+ },
+ [0x1D922]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D922,
+ },
+ [0x1D923]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D923,
+ },
+ [0x1D924]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D924,
+ },
+ [0x1D925]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D925,
+ },
+ [0x1D926]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D926,
+ },
+ [0x1D927]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D927,
+ },
+ [0x1D928]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D928,
+ },
+ [0x1D929]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D929,
+ },
+ [0x1D92A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D92A,
+ },
+ [0x1D92B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D92B,
+ },
+ [0x1D92C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D92C,
+ },
+ [0x1D92D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D92D,
+ },
+ [0x1D92E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D92E,
+ },
+ [0x1D92F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D92F,
+ },
+ [0x1D930]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D930,
+ },
+ [0x1D931]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D931,
+ },
+ [0x1D932]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D932,
+ },
+ [0x1D933]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D933,
+ },
+ [0x1D934]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D934,
+ },
+ [0x1D935]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D935,
+ },
+ [0x1D936]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D936,
+ },
+ [0x1D937]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D937,
+ },
+ [0x1D938]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D938,
+ },
+ [0x1D939]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D939,
+ },
+ [0x1D93A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D93A,
+ },
+ [0x1D93B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D93B,
+ },
+ [0x1D93C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D93C,
+ },
+ [0x1D93D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D93D,
+ },
+ [0x1D93E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D93E,
+ },
+ [0x1D93F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D93F,
+ },
+ [0x1D940]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D940,
+ },
+ [0x1D941]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D941,
+ },
+ [0x1D942]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D942,
+ },
+ [0x1D943]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D943,
+ },
+ [0x1D944]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D944,
+ },
+ [0x1D945]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D945,
+ },
+ [0x1D946]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D946,
+ },
+ [0x1D947]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D947,
+ },
+ [0x1D948]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D948,
+ },
+ [0x1D949]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D949,
+ },
+ [0x1D94A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D94A,
+ },
+ [0x1D94B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D94B,
+ },
+ [0x1D94C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D94C,
+ },
+ [0x1D94D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D94D,
+ },
+ [0x1D94E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D94E,
+ },
+ [0x1D94F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D94F,
+ },
+ [0x1D950]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D950,
+ },
+ [0x1D951]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D951,
+ },
+ [0x1D952]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D952,
+ },
+ [0x1D953]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D953,
+ },
+ [0x1D954]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D954,
+ },
+ [0x1D955]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D955,
+ },
+ [0x1D956]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D956,
+ },
+ [0x1D957]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D957,
+ },
+ [0x1D958]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D958,
+ },
+ [0x1D959]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D959,
+ },
+ [0x1D95A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D95A,
+ },
+ [0x1D95B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D95B,
+ },
+ [0x1D95C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D95C,
+ },
+ [0x1D95D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D95D,
+ },
+ [0x1D95E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D95E,
+ },
+ [0x1D95F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D95F,
+ },
+ [0x1D960]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D960,
+ },
+ [0x1D961]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D961,
+ },
+ [0x1D962]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D962,
+ },
+ [0x1D963]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D963,
+ },
+ [0x1D964]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D964,
+ },
+ [0x1D965]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D965,
+ },
+ [0x1D966]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D966,
+ },
+ [0x1D967]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D967,
+ },
+ [0x1D968]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D968,
+ },
+ [0x1D969]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D969,
+ },
+ [0x1D96A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D96A,
+ },
+ [0x1D96B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D96B,
+ },
+ [0x1D96C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D96C,
+ },
+ [0x1D96D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D96D,
+ },
+ [0x1D96E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D96E,
+ },
+ [0x1D96F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D96F,
+ },
+ [0x1D970]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D970,
+ },
+ [0x1D971]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D971,
+ },
+ [0x1D972]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D972,
+ },
+ [0x1D973]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D973,
+ },
+ [0x1D974]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D974,
+ },
+ [0x1D975]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D975,
+ },
+ [0x1D976]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D976,
+ },
+ [0x1D977]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D977,
+ },
+ [0x1D978]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D978,
+ },
+ [0x1D979]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D979,
+ },
+ [0x1D97A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D97A,
+ },
+ [0x1D97B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D97B,
+ },
+ [0x1D97C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D97C,
+ },
+ [0x1D97D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D97D,
+ },
+ [0x1D97E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D97E,
+ },
+ [0x1D97F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D97F,
+ },
+ [0x1D980]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D980,
+ },
+ [0x1D981]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D981,
+ },
+ [0x1D982]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D982,
+ },
+ [0x1D983]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D983,
+ },
+ [0x1D984]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D984,
+ },
+ [0x1D985]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D985,
+ },
+ [0x1D986]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D986,
+ },
+ [0x1D987]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D987,
+ },
+ [0x1D988]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D988,
+ },
+ [0x1D989]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D989,
+ },
+ [0x1D98A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D98A,
+ },
+ [0x1D98B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D98B,
+ },
+ [0x1D98C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D98C,
+ },
+ [0x1D98D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D98D,
+ },
+ [0x1D98E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D98E,
+ },
+ [0x1D98F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D98F,
+ },
+ [0x1D990]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D990,
+ },
+ [0x1D991]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D991,
+ },
+ [0x1D992]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D992,
+ },
+ [0x1D993]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D993,
+ },
+ [0x1D994]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D994,
+ },
+ [0x1D995]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D995,
+ },
+ [0x1D996]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D996,
+ },
+ [0x1D997]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D997,
+ },
+ [0x1D998]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D998,
+ },
+ [0x1D999]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D999,
+ },
+ [0x1D99A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D99A,
+ },
+ [0x1D99B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D99B,
+ },
+ [0x1D99C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D99C,
+ },
+ [0x1D99D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D99D,
+ },
+ [0x1D99E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D99E,
+ },
+ [0x1D99F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D99F,
+ },
+ [0x1D9A0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9A0,
+ },
+ [0x1D9A1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9A1,
+ },
+ [0x1D9A2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9A2,
+ },
+ [0x1D9A3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9A3,
+ },
+ [0x1D9A4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9A4,
+ },
+ [0x1D9A5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9A5,
+ },
+ [0x1D9A6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9A6,
+ },
+ [0x1D9A7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9A7,
+ },
+ [0x1D9A8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9A8,
+ },
+ [0x1D9A9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9A9,
+ },
+ [0x1D9AA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9AA,
+ },
+ [0x1D9AB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9AB,
+ },
+ [0x1D9AC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9AC,
+ },
+ [0x1D9AD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9AD,
+ },
+ [0x1D9AE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9AE,
+ },
+ [0x1D9AF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9AF,
+ },
+ [0x1D9B0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9B0,
+ },
+ [0x1D9B1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9B1,
+ },
+ [0x1D9B2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9B2,
+ },
+ [0x1D9B3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9B3,
+ },
+ [0x1D9B4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9B4,
+ },
+ [0x1D9B5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9B5,
+ },
+ [0x1D9B6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9B6,
+ },
+ [0x1D9B7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9B7,
+ },
+ [0x1D9B8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9B8,
+ },
+ [0x1D9B9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9B9,
+ },
+ [0x1D9BA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9BA,
+ },
+ [0x1D9BB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9BB,
+ },
+ [0x1D9BC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9BC,
+ },
+ [0x1D9BD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9BD,
+ },
+ [0x1D9BE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9BE,
+ },
+ [0x1D9BF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9BF,
+ },
+ [0x1D9C0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9C0,
+ },
+ [0x1D9C1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9C1,
+ },
+ [0x1D9C2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9C2,
+ },
+ [0x1D9C3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9C3,
+ },
+ [0x1D9C4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9C4,
+ },
+ [0x1D9C5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9C5,
+ },
+ [0x1D9C6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9C6,
+ },
+ [0x1D9C7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9C7,
+ },
+ [0x1D9C8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9C8,
+ },
+ [0x1D9C9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9C9,
+ },
+ [0x1D9CA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9CA,
+ },
+ [0x1D9CB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9CB,
+ },
+ [0x1D9CC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9CC,
+ },
+ [0x1D9CD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9CD,
+ },
+ [0x1D9CE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9CE,
+ },
+ [0x1D9CF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9CF,
+ },
+ [0x1D9D0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9D0,
+ },
+ [0x1D9D1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9D1,
+ },
+ [0x1D9D2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9D2,
+ },
+ [0x1D9D3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9D3,
+ },
+ [0x1D9D4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9D4,
+ },
+ [0x1D9D5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9D5,
+ },
+ [0x1D9D6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9D6,
+ },
+ [0x1D9D7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9D7,
+ },
+ [0x1D9D8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9D8,
+ },
+ [0x1D9D9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9D9,
+ },
+ [0x1D9DA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9DA,
+ },
+ [0x1D9DB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9DB,
+ },
+ [0x1D9DC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9DC,
+ },
+ [0x1D9DD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9DD,
+ },
+ [0x1D9DE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9DE,
+ },
+ [0x1D9DF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9DF,
+ },
+ [0x1D9E0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9E0,
+ },
+ [0x1D9E1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9E1,
+ },
+ [0x1D9E2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9E2,
+ },
+ [0x1D9E3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9E3,
+ },
+ [0x1D9E4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9E4,
+ },
+ [0x1D9E5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9E5,
+ },
+ [0x1D9E6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9E6,
+ },
+ [0x1D9E7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9E7,
+ },
+ [0x1D9E8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9E8,
+ },
+ [0x1D9E9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9E9,
+ },
+ [0x1D9EA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9EA,
+ },
+ [0x1D9EB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9EB,
+ },
+ [0x1D9EC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9EC,
+ },
+ [0x1D9ED]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9ED,
+ },
+ [0x1D9EE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9EE,
+ },
+ [0x1D9EF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9EF,
+ },
+ [0x1D9F0]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9F0,
+ },
+ [0x1D9F1]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9F1,
+ },
+ [0x1D9F2]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9F2,
+ },
+ [0x1D9F3]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9F3,
+ },
+ [0x1D9F4]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9F4,
+ },
+ [0x1D9F5]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9F5,
+ },
+ [0x1D9F6]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9F6,
+ },
+ [0x1D9F7]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9F7,
+ },
+ [0x1D9F8]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9F8,
+ },
+ [0x1D9F9]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9F9,
+ },
+ [0x1D9FA]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9FA,
+ },
+ [0x1D9FB]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9FB,
+ },
+ [0x1D9FC]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9FC,
+ },
+ [0x1D9FD]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9FD,
+ },
+ [0x1D9FE]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9FE,
+ },
+ [0x1D9FF]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D9FF,
+ },
+ [0x1DA00]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA00,
+ },
+ [0x1DA01]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA01,
+ },
+ [0x1DA02]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA02,
+ },
+ [0x1DA03]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA03,
+ },
+ [0x1DA04]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA04,
+ },
+ [0x1DA05]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA05,
+ },
+ [0x1DA06]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA06,
+ },
+ [0x1DA07]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA07,
+ },
+ [0x1DA08]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA08,
+ },
+ [0x1DA09]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA09,
+ },
+ [0x1DA0A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA0A,
+ },
+ [0x1DA0B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA0B,
+ },
+ [0x1DA0C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA0C,
+ },
+ [0x1DA0D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA0D,
+ },
+ [0x1DA0E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA0E,
+ },
+ [0x1DA0F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA0F,
+ },
+ [0x1DA10]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA10,
+ },
+ [0x1DA11]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA11,
+ },
+ [0x1DA12]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA12,
+ },
+ [0x1DA13]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA13,
+ },
+ [0x1DA14]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA14,
+ },
+ [0x1DA15]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA15,
+ },
+ [0x1DA16]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA16,
+ },
+ [0x1DA17]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA17,
+ },
+ [0x1DA18]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA18,
+ },
+ [0x1DA19]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA19,
+ },
+ [0x1DA1A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA1A,
+ },
+ [0x1DA1B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA1B,
+ },
+ [0x1DA1C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA1C,
+ },
+ [0x1DA1D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA1D,
+ },
+ [0x1DA1E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA1E,
+ },
+ [0x1DA1F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA1F,
+ },
+ [0x1DA20]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA20,
+ },
+ [0x1DA21]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA21,
+ },
+ [0x1DA22]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA22,
+ },
+ [0x1DA23]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA23,
+ },
+ [0x1DA24]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA24,
+ },
+ [0x1DA25]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA25,
+ },
+ [0x1DA26]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA26,
+ },
+ [0x1DA27]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA27,
+ },
+ [0x1DA28]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA28,
+ },
+ [0x1DA29]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA29,
+ },
+ [0x1DA2A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA2A,
+ },
+ [0x1DA2B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA2B,
+ },
+ [0x1DA2C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA2C,
+ },
+ [0x1DA2D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA2D,
+ },
+ [0x1DA2E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA2E,
+ },
+ [0x1DA2F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA2F,
+ },
+ [0x1DA30]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA30,
+ },
+ [0x1DA31]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA31,
+ },
+ [0x1DA32]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA32,
+ },
+ [0x1DA33]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA33,
+ },
+ [0x1DA34]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA34,
+ },
+ [0x1DA35]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA35,
+ },
+ [0x1DA36]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA36,
+ },
+ [0x1DA37]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA37,
+ },
+ [0x1DA38]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA38,
+ },
+ [0x1DA39]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA39,
+ },
+ [0x1DA3A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA3A,
+ },
+ [0x1DA3B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA3B,
+ },
+ [0x1DA3C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA3C,
+ },
+ [0x1DA3D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA3D,
+ },
+ [0x1DA3E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA3E,
+ },
+ [0x1DA3F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA3F,
+ },
+ [0x1DA40]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA40,
+ },
+ [0x1DA41]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA41,
+ },
+ [0x1DA42]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA42,
+ },
+ [0x1DA43]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA43,
+ },
+ [0x1DA44]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA44,
+ },
+ [0x1DA45]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA45,
+ },
+ [0x1DA46]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA46,
+ },
+ [0x1DA47]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA47,
+ },
+ [0x1DA48]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA48,
+ },
+ [0x1DA49]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA49,
+ },
+ [0x1DA4A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA4A,
+ },
+ [0x1DA4B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA4B,
+ },
+ [0x1DA4C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA4C,
+ },
+ [0x1DA4D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA4D,
+ },
+ [0x1DA4E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA4E,
+ },
+ [0x1DA4F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA4F,
+ },
+ [0x1DA50]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA50,
+ },
+ [0x1DA51]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA51,
+ },
+ [0x1DA52]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA52,
+ },
+ [0x1DA53]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA53,
+ },
+ [0x1DA54]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA54,
+ },
+ [0x1DA55]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA55,
+ },
+ [0x1DA56]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA56,
+ },
+ [0x1DA57]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA57,
+ },
+ [0x1DA58]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA58,
+ },
+ [0x1DA59]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA59,
+ },
+ [0x1DA5A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA5A,
+ },
+ [0x1DA5B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA5B,
+ },
+ [0x1DA5C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA5C,
+ },
+ [0x1DA5D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA5D,
+ },
+ [0x1DA5E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA5E,
+ },
+ [0x1DA5F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA5F,
+ },
+ [0x1DA60]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA60,
+ },
+ [0x1DA61]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA61,
+ },
+ [0x1DA62]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA62,
+ },
+ [0x1DA63]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA63,
+ },
+ [0x1DA64]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA64,
+ },
+ [0x1DA65]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA65,
+ },
+ [0x1DA66]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA66,
+ },
+ [0x1DA67]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA67,
+ },
+ [0x1DA68]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA68,
+ },
+ [0x1DA69]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA69,
+ },
+ [0x1DA6A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA6A,
+ },
+ [0x1DA6B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA6B,
+ },
+ [0x1DA6C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA6C,
+ },
+ [0x1DA6D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA6D,
+ },
+ [0x1DA6E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA6E,
+ },
+ [0x1DA6F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA6F,
+ },
+ [0x1DA70]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA70,
+ },
+ [0x1DA71]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA71,
+ },
+ [0x1DA72]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA72,
+ },
+ [0x1DA73]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA73,
+ },
+ [0x1DA74]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA74,
+ },
+ [0x1DA75]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA75,
+ },
+ [0x1DA76]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA76,
+ },
+ [0x1DA77]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA77,
+ },
+ [0x1DA78]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA78,
+ },
+ [0x1DA79]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA79,
+ },
+ [0x1DA7A]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA7A,
+ },
+ [0x1DA7B]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA7B,
+ },
+ [0x1DA7C]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA7C,
+ },
+ [0x1DA7D]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA7D,
+ },
+ [0x1DA7E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA7E,
+ },
+ [0x1DA7F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA7F,
+ },
+ [0x1DA80]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA80,
+ },
+ [0x1DA81]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA81,
+ },
+ [0x1DA82]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA82,
+ },
+ [0x1DA83]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA83,
+ },
+ [0x1DA84]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA84,
+ },
+ [0x1DA85]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA85,
+ },
+ [0x1DA86]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA86,
+ },
+ [0x1DA87]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1DA87,
+ },
+ [0x1DA88]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1DA88,
+ },
+ [0x1DA89]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1DA89,
+ },
+ [0x1DA8A]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1DA8A,
+ },
+ [0x1DA8B]={
+ category="po",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1DA8B,
+ },
+ [0x1DA9B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA9B,
+ },
+ [0x1DA9C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA9C,
+ },
+ [0x1DA9D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA9D,
+ },
+ [0x1DA9E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA9E,
+ },
+ [0x1DA9F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DA9F,
+ },
+ [0x1DAA1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAA1,
+ },
+ [0x1DAA2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAA2,
+ },
+ [0x1DAA3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAA3,
+ },
+ [0x1DAA4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAA4,
+ },
+ [0x1DAA5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAA5,
+ },
+ [0x1DAA6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAA6,
+ },
+ [0x1DAA7]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAA7,
+ },
+ [0x1DAA8]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAA8,
+ },
+ [0x1DAA9]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAA9,
+ },
+ [0x1DAAA]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAAA,
+ },
+ [0x1DAAB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAAB,
+ },
+ [0x1DAAC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAAC,
+ },
+ [0x1DAAD]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAAD,
+ },
+ [0x1DAAE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAAE,
+ },
+ [0x1DAAF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DAAF,
+ },
+ [0x1E000]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E000,
+ },
+ [0x1E001]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E001,
+ },
+ [0x1E002]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E002,
+ },
+ [0x1E003]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E003,
+ },
+ [0x1E004]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E004,
+ },
+ [0x1E005]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E005,
+ },
+ [0x1E006]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E006,
+ },
+ [0x1E008]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E008,
+ },
+ [0x1E009]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E009,
+ },
+ [0x1E00A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E00A,
+ },
+ [0x1E00B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E00B,
+ },
+ [0x1E00C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E00C,
+ },
+ [0x1E00D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E00D,
+ },
+ [0x1E00E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E00E,
+ },
+ [0x1E00F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E00F,
+ },
+ [0x1E010]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E010,
+ },
+ [0x1E011]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E011,
+ },
+ [0x1E012]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E012,
+ },
+ [0x1E013]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E013,
+ },
+ [0x1E014]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E014,
+ },
+ [0x1E015]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E015,
+ },
+ [0x1E016]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E016,
+ },
+ [0x1E017]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E017,
+ },
+ [0x1E018]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E018,
+ },
+ [0x1E01B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E01B,
+ },
+ [0x1E01C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E01C,
+ },
+ [0x1E01D]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E01D,
+ },
+ [0x1E01E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E01E,
+ },
+ [0x1E01F]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E01F,
+ },
+ [0x1E020]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E020,
+ },
+ [0x1E021]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E021,
+ },
+ [0x1E023]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E023,
+ },
+ [0x1E024]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E024,
+ },
+ [0x1E026]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E026,
+ },
+ [0x1E027]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E027,
+ },
+ [0x1E028]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E028,
+ },
+ [0x1E029]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E029,
+ },
+ [0x1E02A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E02A,
+ },
+ [0x1E100]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E100,
+ },
+ [0x1E101]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E101,
+ },
+ [0x1E102]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E102,
+ },
+ [0x1E103]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E103,
+ },
+ [0x1E104]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E104,
+ },
+ [0x1E105]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E105,
+ },
+ [0x1E106]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E106,
+ },
+ [0x1E107]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E107,
+ },
+ [0x1E108]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E108,
+ },
+ [0x1E109]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E109,
+ },
+ [0x1E10A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E10A,
+ },
+ [0x1E10B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E10B,
+ },
+ [0x1E10C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E10C,
+ },
+ [0x1E10D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E10D,
+ },
+ [0x1E10E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E10E,
+ },
+ [0x1E10F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E10F,
+ },
+ [0x1E110]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E110,
+ },
+ [0x1E111]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E111,
+ },
+ [0x1E112]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E112,
+ },
+ [0x1E113]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E113,
+ },
+ [0x1E114]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E114,
+ },
+ [0x1E115]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E115,
+ },
+ [0x1E116]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E116,
+ },
+ [0x1E117]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E117,
+ },
+ [0x1E118]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E118,
+ },
+ [0x1E119]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E119,
+ },
+ [0x1E11A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E11A,
+ },
+ [0x1E11B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E11B,
+ },
+ [0x1E11C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E11C,
+ },
+ [0x1E11D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E11D,
+ },
+ [0x1E11E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E11E,
+ },
+ [0x1E11F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E11F,
+ },
+ [0x1E120]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E120,
+ },
+ [0x1E121]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E121,
+ },
+ [0x1E122]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E122,
+ },
+ [0x1E123]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E123,
+ },
+ [0x1E124]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E124,
+ },
+ [0x1E125]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E125,
+ },
+ [0x1E126]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E126,
+ },
+ [0x1E127]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E127,
+ },
+ [0x1E128]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E128,
+ },
+ [0x1E129]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E129,
+ },
+ [0x1E12A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E12A,
+ },
+ [0x1E12B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E12B,
+ },
+ [0x1E12C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E12C,
+ },
+ [0x1E130]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E130,
+ },
+ [0x1E131]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E131,
+ },
+ [0x1E132]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E132,
+ },
+ [0x1E133]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E133,
+ },
+ [0x1E134]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E134,
+ },
+ [0x1E135]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E135,
+ },
+ [0x1E136]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E136,
+ },
+ [0x1E137]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E137,
+ },
+ [0x1E138]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E138,
+ },
+ [0x1E139]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E139,
+ },
+ [0x1E13A]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E13A,
+ },
+ [0x1E13B]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E13B,
+ },
+ [0x1E13C]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E13C,
+ },
+ [0x1E13D]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E13D,
+ },
+ [0x1E140]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E140,
+ },
+ [0x1E141]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E141,
+ },
+ [0x1E142]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E142,
+ },
+ [0x1E143]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E143,
+ },
+ [0x1E144]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E144,
+ },
+ [0x1E145]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E145,
+ },
+ [0x1E146]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E146,
+ },
+ [0x1E147]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E147,
+ },
+ [0x1E148]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E148,
+ },
+ [0x1E149]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E149,
+ },
+ [0x1E14E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E14E,
+ },
+ [0x1E14F]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E14F,
+ },
+ [0x1E2C0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2C0,
+ },
+ [0x1E2C1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2C1,
+ },
+ [0x1E2C2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2C2,
+ },
+ [0x1E2C3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2C3,
+ },
+ [0x1E2C4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2C4,
+ },
+ [0x1E2C5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2C5,
+ },
+ [0x1E2C6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2C6,
+ },
+ [0x1E2C7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2C7,
+ },
+ [0x1E2C8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2C8,
+ },
+ [0x1E2C9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2C9,
+ },
+ [0x1E2CA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2CA,
+ },
+ [0x1E2CB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2CB,
+ },
+ [0x1E2CC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2CC,
+ },
+ [0x1E2CD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2CD,
+ },
+ [0x1E2CE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2CE,
+ },
+ [0x1E2CF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2CF,
+ },
+ [0x1E2D0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2D0,
+ },
+ [0x1E2D1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2D1,
+ },
+ [0x1E2D2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2D2,
+ },
+ [0x1E2D3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2D3,
+ },
+ [0x1E2D4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2D4,
+ },
+ [0x1E2D5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2D5,
+ },
+ [0x1E2D6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2D6,
+ },
+ [0x1E2D7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2D7,
+ },
+ [0x1E2D8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2D8,
+ },
+ [0x1E2D9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2D9,
+ },
+ [0x1E2DA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2DA,
+ },
+ [0x1E2DB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2DB,
+ },
+ [0x1E2DC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2DC,
+ },
+ [0x1E2DD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2DD,
+ },
+ [0x1E2DE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2DE,
+ },
+ [0x1E2DF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2DF,
+ },
+ [0x1E2E0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2E0,
+ },
+ [0x1E2E1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2E1,
+ },
+ [0x1E2E2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2E2,
+ },
+ [0x1E2E3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2E3,
+ },
+ [0x1E2E4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2E4,
+ },
+ [0x1E2E5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2E5,
+ },
+ [0x1E2E6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2E6,
+ },
+ [0x1E2E7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2E7,
+ },
+ [0x1E2E8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2E8,
+ },
+ [0x1E2E9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2E9,
+ },
+ [0x1E2EA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2EA,
+ },
+ [0x1E2EB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E2EB,
+ },
+ [0x1E2EC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E2EC,
+ },
+ [0x1E2ED]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E2ED,
+ },
+ [0x1E2EE]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E2EE,
+ },
+ [0x1E2EF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E2EF,
+ },
+ [0x1E2F0]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E2F0,
+ },
+ [0x1E2F1]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E2F1,
+ },
+ [0x1E2F2]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E2F2,
+ },
+ [0x1E2F3]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E2F3,
+ },
+ [0x1E2F4]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E2F4,
+ },
+ [0x1E2F5]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E2F5,
+ },
+ [0x1E2F6]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E2F6,
+ },
+ [0x1E2F7]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E2F7,
+ },
+ [0x1E2F8]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E2F8,
+ },
+ [0x1E2F9]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1E2F9,
+ },
+ [0x1E2FF]={
+ category="sc",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x1E2FF,
+ },
+ [0x1E800]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E800,
+ },
+ [0x1E801]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E801,
+ },
+ [0x1E802]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E802,
+ },
+ [0x1E803]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E803,
+ },
+ [0x1E804]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E804,
+ },
+ [0x1E805]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E805,
+ },
+ [0x1E806]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E806,
+ },
+ [0x1E807]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E807,
+ },
+ [0x1E808]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E808,
+ },
+ [0x1E809]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E809,
+ },
+ [0x1E80A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E80A,
+ },
+ [0x1E80B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E80B,
+ },
+ [0x1E80C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E80C,
+ },
+ [0x1E80D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E80D,
+ },
+ [0x1E80E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E80E,
+ },
+ [0x1E80F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E80F,
+ },
+ [0x1E810]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E810,
+ },
+ [0x1E811]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E811,
+ },
+ [0x1E812]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E812,
+ },
+ [0x1E813]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E813,
+ },
+ [0x1E814]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E814,
+ },
+ [0x1E815]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E815,
+ },
+ [0x1E816]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E816,
+ },
+ [0x1E817]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E817,
+ },
+ [0x1E818]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E818,
+ },
+ [0x1E819]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E819,
+ },
+ [0x1E81A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E81A,
+ },
+ [0x1E81B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E81B,
+ },
+ [0x1E81C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E81C,
+ },
+ [0x1E81D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E81D,
+ },
+ [0x1E81E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E81E,
+ },
+ [0x1E81F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E81F,
+ },
+ [0x1E820]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E820,
+ },
+ [0x1E821]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E821,
+ },
+ [0x1E822]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E822,
+ },
+ [0x1E823]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E823,
+ },
+ [0x1E824]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E824,
+ },
+ [0x1E825]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E825,
+ },
+ [0x1E826]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E826,
+ },
+ [0x1E827]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E827,
+ },
+ [0x1E828]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E828,
+ },
+ [0x1E829]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E829,
+ },
+ [0x1E82A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E82A,
+ },
+ [0x1E82B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E82B,
+ },
+ [0x1E82C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E82C,
+ },
+ [0x1E82D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E82D,
+ },
+ [0x1E82E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E82E,
+ },
+ [0x1E82F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E82F,
+ },
+ [0x1E830]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E830,
+ },
+ [0x1E831]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E831,
+ },
+ [0x1E832]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E832,
+ },
+ [0x1E833]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E833,
+ },
+ [0x1E834]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E834,
+ },
+ [0x1E835]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E835,
+ },
+ [0x1E836]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E836,
+ },
+ [0x1E837]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E837,
+ },
+ [0x1E838]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E838,
+ },
+ [0x1E839]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E839,
+ },
+ [0x1E83A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E83A,
+ },
+ [0x1E83B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E83B,
+ },
+ [0x1E83C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E83C,
+ },
+ [0x1E83D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E83D,
+ },
+ [0x1E83E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E83E,
+ },
+ [0x1E83F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E83F,
+ },
+ [0x1E840]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E840,
+ },
+ [0x1E841]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E841,
+ },
+ [0x1E842]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E842,
+ },
+ [0x1E843]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E843,
+ },
+ [0x1E844]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E844,
+ },
+ [0x1E845]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E845,
+ },
+ [0x1E846]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E846,
+ },
+ [0x1E847]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E847,
+ },
+ [0x1E848]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E848,
+ },
+ [0x1E849]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E849,
+ },
+ [0x1E84A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E84A,
+ },
+ [0x1E84B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E84B,
+ },
+ [0x1E84C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E84C,
+ },
+ [0x1E84D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E84D,
+ },
+ [0x1E84E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E84E,
+ },
+ [0x1E84F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E84F,
+ },
+ [0x1E850]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E850,
+ },
+ [0x1E851]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E851,
+ },
+ [0x1E852]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E852,
+ },
+ [0x1E853]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E853,
+ },
+ [0x1E854]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E854,
+ },
+ [0x1E855]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E855,
+ },
+ [0x1E856]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E856,
+ },
+ [0x1E857]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E857,
+ },
+ [0x1E858]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E858,
+ },
+ [0x1E859]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E859,
+ },
+ [0x1E85A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E85A,
+ },
+ [0x1E85B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E85B,
+ },
+ [0x1E85C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E85C,
+ },
+ [0x1E85D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E85D,
+ },
+ [0x1E85E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E85E,
+ },
+ [0x1E85F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E85F,
+ },
+ [0x1E860]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E860,
+ },
+ [0x1E861]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E861,
+ },
+ [0x1E862]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E862,
+ },
+ [0x1E863]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E863,
+ },
+ [0x1E864]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E864,
+ },
+ [0x1E865]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E865,
+ },
+ [0x1E866]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E866,
+ },
+ [0x1E867]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E867,
+ },
+ [0x1E868]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E868,
+ },
+ [0x1E869]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E869,
+ },
+ [0x1E86A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E86A,
+ },
+ [0x1E86B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E86B,
+ },
+ [0x1E86C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E86C,
+ },
+ [0x1E86D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E86D,
+ },
+ [0x1E86E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E86E,
+ },
+ [0x1E86F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E86F,
+ },
+ [0x1E870]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E870,
+ },
+ [0x1E871]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E871,
+ },
+ [0x1E872]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E872,
+ },
+ [0x1E873]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E873,
+ },
+ [0x1E874]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E874,
+ },
+ [0x1E875]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E875,
+ },
+ [0x1E876]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E876,
+ },
+ [0x1E877]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E877,
+ },
+ [0x1E878]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E878,
+ },
+ [0x1E879]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E879,
+ },
+ [0x1E87A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E87A,
+ },
+ [0x1E87B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E87B,
+ },
+ [0x1E87C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E87C,
+ },
+ [0x1E87D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E87D,
+ },
+ [0x1E87E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E87E,
+ },
+ [0x1E87F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E87F,
+ },
+ [0x1E880]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E880,
+ },
+ [0x1E881]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E881,
+ },
+ [0x1E882]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E882,
+ },
+ [0x1E883]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E883,
+ },
+ [0x1E884]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E884,
+ },
+ [0x1E885]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E885,
+ },
+ [0x1E886]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E886,
+ },
+ [0x1E887]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E887,
+ },
+ [0x1E888]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E888,
+ },
+ [0x1E889]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E889,
+ },
+ [0x1E88A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E88A,
+ },
+ [0x1E88B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E88B,
+ },
+ [0x1E88C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E88C,
+ },
+ [0x1E88D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E88D,
+ },
+ [0x1E88E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E88E,
+ },
+ [0x1E88F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E88F,
+ },
+ [0x1E890]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E890,
+ },
+ [0x1E891]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E891,
+ },
+ [0x1E892]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E892,
+ },
+ [0x1E893]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E893,
+ },
+ [0x1E894]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E894,
+ },
+ [0x1E895]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E895,
+ },
+ [0x1E896]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E896,
+ },
+ [0x1E897]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E897,
+ },
+ [0x1E898]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E898,
+ },
+ [0x1E899]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E899,
+ },
+ [0x1E89A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E89A,
+ },
+ [0x1E89B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E89B,
+ },
+ [0x1E89C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E89C,
+ },
+ [0x1E89D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E89D,
+ },
+ [0x1E89E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E89E,
+ },
+ [0x1E89F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E89F,
+ },
+ [0x1E8A0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8A0,
+ },
+ [0x1E8A1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8A1,
+ },
+ [0x1E8A2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8A2,
+ },
+ [0x1E8A3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8A3,
+ },
+ [0x1E8A4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8A4,
+ },
+ [0x1E8A5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8A5,
+ },
+ [0x1E8A6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8A6,
+ },
+ [0x1E8A7]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8A7,
+ },
+ [0x1E8A8]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8A8,
+ },
+ [0x1E8A9]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8A9,
+ },
+ [0x1E8AA]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8AA,
+ },
+ [0x1E8AB]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8AB,
+ },
+ [0x1E8AC]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8AC,
+ },
+ [0x1E8AD]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8AD,
+ },
+ [0x1E8AE]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8AE,
+ },
+ [0x1E8AF]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8AF,
+ },
+ [0x1E8B0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8B0,
+ },
+ [0x1E8B1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8B1,
+ },
+ [0x1E8B2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8B2,
+ },
+ [0x1E8B3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8B3,
+ },
+ [0x1E8B4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8B4,
+ },
+ [0x1E8B5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8B5,
+ },
+ [0x1E8B6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8B6,
+ },
+ [0x1E8B7]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8B7,
+ },
+ [0x1E8B8]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8B8,
+ },
+ [0x1E8B9]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8B9,
+ },
+ [0x1E8BA]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8BA,
+ },
+ [0x1E8BB]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8BB,
+ },
+ [0x1E8BC]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8BC,
+ },
+ [0x1E8BD]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8BD,
+ },
+ [0x1E8BE]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8BE,
+ },
+ [0x1E8BF]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8BF,
+ },
+ [0x1E8C0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8C0,
+ },
+ [0x1E8C1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8C1,
+ },
+ [0x1E8C2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8C2,
+ },
+ [0x1E8C3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8C3,
+ },
+ [0x1E8C4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8C4,
+ },
+ [0x1E8C7]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8C7,
+ },
+ [0x1E8C8]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8C8,
+ },
+ [0x1E8C9]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8C9,
+ },
+ [0x1E8CA]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8CA,
+ },
+ [0x1E8CB]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8CB,
+ },
+ [0x1E8CC]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8CC,
+ },
+ [0x1E8CD]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8CD,
+ },
+ [0x1E8CE]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8CE,
+ },
+ [0x1E8CF]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E8CF,
+ },
+ [0x1E8D0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E8D0,
+ },
+ [0x1E8D1]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E8D1,
+ },
+ [0x1E8D2]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E8D2,
+ },
+ [0x1E8D3]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E8D3,
+ },
+ [0x1E8D4]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E8D4,
+ },
+ [0x1E8D5]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E8D5,
+ },
+ [0x1E8D6]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E8D6,
+ },
+ [0x1E900]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E900,
+ },
+ [0x1E901]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E901,
+ },
+ [0x1E902]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E902,
+ },
+ [0x1E903]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E903,
+ },
+ [0x1E904]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E904,
+ },
+ [0x1E905]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E905,
+ },
+ [0x1E906]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E906,
+ },
+ [0x1E907]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E907,
+ },
+ [0x1E908]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E908,
+ },
+ [0x1E909]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E909,
+ },
+ [0x1E90A]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E90A,
+ },
+ [0x1E90B]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E90B,
+ },
+ [0x1E90C]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E90C,
+ },
+ [0x1E90D]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E90D,
+ },
+ [0x1E90E]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E90E,
+ },
+ [0x1E90F]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E90F,
+ },
+ [0x1E910]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E910,
+ },
+ [0x1E911]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E911,
+ },
+ [0x1E912]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E912,
+ },
+ [0x1E913]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E913,
+ },
+ [0x1E914]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E914,
+ },
+ [0x1E915]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E915,
+ },
+ [0x1E916]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E916,
+ },
+ [0x1E917]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E917,
+ },
+ [0x1E918]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E918,
+ },
+ [0x1E919]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E919,
+ },
+ [0x1E91A]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E91A,
+ },
+ [0x1E91B]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E91B,
+ },
+ [0x1E91C]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E91C,
+ },
+ [0x1E91D]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E91D,
+ },
+ [0x1E91E]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E91E,
+ },
+ [0x1E91F]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E91F,
+ },
+ [0x1E920]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E920,
+ },
+ [0x1E921]={
+ category="lu",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E921,
+ },
+ [0x1E922]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E922,
+ },
+ [0x1E923]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E923,
+ },
+ [0x1E924]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E924,
+ },
+ [0x1E925]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E925,
+ },
+ [0x1E926]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E926,
+ },
+ [0x1E927]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E927,
+ },
+ [0x1E928]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E928,
+ },
+ [0x1E929]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E929,
+ },
+ [0x1E92A]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E92A,
+ },
+ [0x1E92B]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E92B,
+ },
+ [0x1E92C]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E92C,
+ },
+ [0x1E92D]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E92D,
+ },
+ [0x1E92E]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E92E,
+ },
+ [0x1E92F]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E92F,
+ },
+ [0x1E930]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E930,
+ },
+ [0x1E931]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E931,
+ },
+ [0x1E932]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E932,
+ },
+ [0x1E933]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E933,
+ },
+ [0x1E934]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E934,
+ },
+ [0x1E935]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E935,
+ },
+ [0x1E936]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E936,
+ },
+ [0x1E937]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E937,
+ },
+ [0x1E938]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E938,
+ },
+ [0x1E939]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E939,
+ },
+ [0x1E93A]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E93A,
+ },
+ [0x1E93B]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E93B,
+ },
+ [0x1E93C]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E93C,
+ },
+ [0x1E93D]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E93D,
+ },
+ [0x1E93E]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E93E,
+ },
+ [0x1E93F]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E93F,
+ },
+ [0x1E940]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E940,
+ },
+ [0x1E941]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E941,
+ },
+ [0x1E942]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E942,
+ },
+ [0x1E943]={
+ category="ll",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E943,
+ },
+ [0x1E944]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E944,
+ },
+ [0x1E945]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E945,
+ },
+ [0x1E946]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E946,
+ },
+ [0x1E947]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E947,
+ },
+ [0x1E948]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E948,
+ },
+ [0x1E949]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E949,
+ },
+ [0x1E94A]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1E94A,
+ },
+ [0x1E94B]={
+ category="lm",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1E94B,
+ },
+ [0x1E950]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x1E950,
+ },
+ [0x1E951]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x1E951,
+ },
+ [0x1E952]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x1E952,
+ },
+ [0x1E953]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x1E953,
+ },
+ [0x1E954]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x1E954,
+ },
+ [0x1E955]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x1E955,
+ },
+ [0x1E956]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x1E956,
+ },
+ [0x1E957]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x1E957,
+ },
+ [0x1E958]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x1E958,
+ },
+ [0x1E959]={
+ category="nd",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x1E959,
+ },
+ [0x1E95E]={
+ category="po",
+ direction="r",
+ linebreak="op",
+ unicodeslot=0x1E95E,
+ },
+ [0x1E95F]={
+ category="po",
+ direction="r",
+ linebreak="op",
+ unicodeslot=0x1E95F,
+ },
+ [0x1EC71]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC71,
+ },
+ [0x1EC72]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC72,
+ },
+ [0x1EC73]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC73,
+ },
+ [0x1EC74]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC74,
+ },
+ [0x1EC75]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC75,
+ },
+ [0x1EC76]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC76,
+ },
+ [0x1EC77]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC77,
+ },
+ [0x1EC78]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC78,
+ },
+ [0x1EC79]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC79,
+ },
+ [0x1EC7A]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC7A,
+ },
+ [0x1EC7B]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC7B,
+ },
+ [0x1EC7C]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC7C,
+ },
+ [0x1EC7D]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC7D,
+ },
+ [0x1EC7E]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC7E,
+ },
+ [0x1EC7F]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC7F,
+ },
+ [0x1EC80]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC80,
+ },
+ [0x1EC81]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC81,
+ },
+ [0x1EC82]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC82,
+ },
+ [0x1EC83]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC83,
+ },
+ [0x1EC84]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC84,
+ },
+ [0x1EC85]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC85,
+ },
+ [0x1EC86]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC86,
+ },
+ [0x1EC87]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC87,
+ },
+ [0x1EC88]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC88,
+ },
+ [0x1EC89]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC89,
+ },
+ [0x1EC8A]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC8A,
+ },
+ [0x1EC8B]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC8B,
+ },
+ [0x1EC8C]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC8C,
+ },
+ [0x1EC8D]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC8D,
+ },
+ [0x1EC8E]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC8E,
+ },
+ [0x1EC8F]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC8F,
+ },
+ [0x1EC90]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC90,
+ },
+ [0x1EC91]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC91,
+ },
+ [0x1EC92]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC92,
+ },
+ [0x1EC93]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC93,
+ },
+ [0x1EC94]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC94,
+ },
+ [0x1EC95]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC95,
+ },
+ [0x1EC96]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC96,
+ },
+ [0x1EC97]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC97,
+ },
+ [0x1EC98]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC98,
+ },
+ [0x1EC99]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC99,
+ },
+ [0x1EC9A]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC9A,
+ },
+ [0x1EC9B]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC9B,
+ },
+ [0x1EC9C]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC9C,
+ },
+ [0x1EC9D]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC9D,
+ },
+ [0x1EC9E]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC9E,
+ },
+ [0x1EC9F]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1EC9F,
+ },
+ [0x1ECA0]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECA0,
+ },
+ [0x1ECA1]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECA1,
+ },
+ [0x1ECA2]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECA2,
+ },
+ [0x1ECA3]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECA3,
+ },
+ [0x1ECA4]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECA4,
+ },
+ [0x1ECA5]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECA5,
+ },
+ [0x1ECA6]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECA6,
+ },
+ [0x1ECA7]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECA7,
+ },
+ [0x1ECA8]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECA8,
+ },
+ [0x1ECA9]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECA9,
+ },
+ [0x1ECAA]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECAA,
+ },
+ [0x1ECAB]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECAB,
+ },
+ [0x1ECAC]={
+ category="so",
+ direction="al",
+ linebreak="po",
+ unicodeslot=0x1ECAC,
+ },
+ [0x1ECAD]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECAD,
+ },
+ [0x1ECAE]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECAE,
+ },
+ [0x1ECAF]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECAF,
+ },
+ [0x1ECB0]={
+ category="sc",
+ direction="al",
+ linebreak="po",
+ unicodeslot=0x1ECB0,
+ },
+ [0x1ECB1]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECB1,
+ },
+ [0x1ECB2]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECB2,
+ },
+ [0x1ECB3]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECB3,
+ },
+ [0x1ECB4]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ECB4,
+ },
+ [0x1ED01]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED01,
+ },
+ [0x1ED02]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED02,
+ },
+ [0x1ED03]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED03,
+ },
+ [0x1ED04]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED04,
+ },
+ [0x1ED05]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED05,
+ },
+ [0x1ED06]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED06,
+ },
+ [0x1ED07]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED07,
+ },
+ [0x1ED08]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED08,
+ },
+ [0x1ED09]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED09,
+ },
+ [0x1ED0A]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED0A,
+ },
+ [0x1ED0B]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED0B,
+ },
+ [0x1ED0C]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED0C,
+ },
+ [0x1ED0D]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED0D,
+ },
+ [0x1ED0E]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED0E,
+ },
+ [0x1ED0F]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED0F,
+ },
+ [0x1ED10]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED10,
+ },
+ [0x1ED11]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED11,
+ },
+ [0x1ED12]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED12,
+ },
+ [0x1ED13]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED13,
+ },
+ [0x1ED14]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED14,
+ },
+ [0x1ED15]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED15,
+ },
+ [0x1ED16]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED16,
+ },
+ [0x1ED17]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED17,
+ },
+ [0x1ED18]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED18,
+ },
+ [0x1ED19]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED19,
+ },
+ [0x1ED1A]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED1A,
+ },
+ [0x1ED1B]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED1B,
+ },
+ [0x1ED1C]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED1C,
+ },
+ [0x1ED1D]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED1D,
+ },
+ [0x1ED1E]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED1E,
+ },
+ [0x1ED1F]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED1F,
+ },
+ [0x1ED20]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED20,
+ },
+ [0x1ED21]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED21,
+ },
+ [0x1ED22]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED22,
+ },
+ [0x1ED23]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED23,
+ },
+ [0x1ED24]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED24,
+ },
+ [0x1ED25]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED25,
+ },
+ [0x1ED26]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED26,
+ },
+ [0x1ED27]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED27,
+ },
+ [0x1ED28]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED28,
+ },
+ [0x1ED29]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED29,
+ },
+ [0x1ED2A]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED2A,
+ },
+ [0x1ED2B]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED2B,
+ },
+ [0x1ED2C]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED2C,
+ },
+ [0x1ED2D]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED2D,
+ },
+ [0x1ED2E]={
+ category="so",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED2E,
+ },
+ [0x1ED2F]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED2F,
+ },
+ [0x1ED30]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED30,
+ },
+ [0x1ED31]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED31,
+ },
+ [0x1ED32]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED32,
+ },
+ [0x1ED33]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED33,
+ },
+ [0x1ED34]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED34,
+ },
+ [0x1ED35]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED35,
+ },
+ [0x1ED36]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED36,
+ },
+ [0x1ED37]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED37,
+ },
+ [0x1ED38]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED38,
+ },
+ [0x1ED39]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED39,
+ },
+ [0x1ED3A]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED3A,
+ },
+ [0x1ED3B]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED3B,
+ },
+ [0x1ED3C]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED3C,
+ },
+ [0x1ED3D]={
+ category="no",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x1ED3D,
+ },
+ [0x1EE00]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x627 },
+ unicodeslot=0x1EE00,
+ },
+ [0x1EE01]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x628 },
+ unicodeslot=0x1EE01,
+ },
+ [0x1EE02]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62C },
+ unicodeslot=0x1EE02,
+ },
+ [0x1EE03]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62F },
+ unicodeslot=0x1EE03,
+ },
+ [0x1EE05]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x648 },
+ unicodeslot=0x1EE05,
+ },
+ [0x1EE06]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x632 },
+ unicodeslot=0x1EE06,
+ },
+ [0x1EE07]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62D },
+ unicodeslot=0x1EE07,
+ },
+ [0x1EE08]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x637 },
+ unicodeslot=0x1EE08,
+ },
+ [0x1EE09]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x64A },
+ unicodeslot=0x1EE09,
+ },
+ [0x1EE0A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x643 },
+ unicodeslot=0x1EE0A,
+ },
+ [0x1EE0B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x644 },
+ unicodeslot=0x1EE0B,
+ },
+ [0x1EE0C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x645 },
+ unicodeslot=0x1EE0C,
+ },
+ [0x1EE0D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x646 },
+ unicodeslot=0x1EE0D,
+ },
+ [0x1EE0E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x633 },
+ unicodeslot=0x1EE0E,
+ },
+ [0x1EE0F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x639 },
+ unicodeslot=0x1EE0F,
+ },
+ [0x1EE10]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x641 },
+ unicodeslot=0x1EE10,
+ },
+ [0x1EE11]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x635 },
+ unicodeslot=0x1EE11,
+ },
+ [0x1EE12]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x642 },
+ unicodeslot=0x1EE12,
+ },
+ [0x1EE13]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x631 },
+ unicodeslot=0x1EE13,
+ },
+ [0x1EE14]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x634 },
+ unicodeslot=0x1EE14,
+ },
+ [0x1EE15]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62A },
+ unicodeslot=0x1EE15,
+ },
+ [0x1EE16]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62B },
+ unicodeslot=0x1EE16,
+ },
+ [0x1EE17]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62E },
+ unicodeslot=0x1EE17,
+ },
+ [0x1EE18]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x630 },
+ unicodeslot=0x1EE18,
+ },
+ [0x1EE19]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x636 },
+ unicodeslot=0x1EE19,
+ },
+ [0x1EE1A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x638 },
+ unicodeslot=0x1EE1A,
+ },
+ [0x1EE1B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x63A },
+ unicodeslot=0x1EE1B,
+ },
+ [0x1EE1C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x66E },
+ unicodeslot=0x1EE1C,
+ },
+ [0x1EE1D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x6BA },
+ unicodeslot=0x1EE1D,
+ },
+ [0x1EE1E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x6A1 },
+ unicodeslot=0x1EE1E,
+ },
+ [0x1EE1F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x66F },
+ unicodeslot=0x1EE1F,
+ },
+ [0x1EE21]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x628 },
+ unicodeslot=0x1EE21,
+ },
+ [0x1EE22]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62C },
+ unicodeslot=0x1EE22,
+ },
+ [0x1EE24]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x647 },
+ unicodeslot=0x1EE24,
+ },
+ [0x1EE27]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62D },
+ unicodeslot=0x1EE27,
+ },
+ [0x1EE29]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x64A },
+ unicodeslot=0x1EE29,
+ },
+ [0x1EE2A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x643 },
+ unicodeslot=0x1EE2A,
+ },
+ [0x1EE2B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x644 },
+ unicodeslot=0x1EE2B,
+ },
+ [0x1EE2C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x645 },
+ unicodeslot=0x1EE2C,
+ },
+ [0x1EE2D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x646 },
+ unicodeslot=0x1EE2D,
+ },
+ [0x1EE2E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x633 },
+ unicodeslot=0x1EE2E,
+ },
+ [0x1EE2F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x639 },
+ unicodeslot=0x1EE2F,
+ },
+ [0x1EE30]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x641 },
+ unicodeslot=0x1EE30,
+ },
+ [0x1EE31]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x635 },
+ unicodeslot=0x1EE31,
+ },
+ [0x1EE32]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x642 },
+ unicodeslot=0x1EE32,
+ },
+ [0x1EE34]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x634 },
+ unicodeslot=0x1EE34,
+ },
+ [0x1EE35]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62A },
+ unicodeslot=0x1EE35,
+ },
+ [0x1EE36]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62B },
+ unicodeslot=0x1EE36,
+ },
+ [0x1EE37]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62E },
+ unicodeslot=0x1EE37,
+ },
+ [0x1EE39]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x636 },
+ unicodeslot=0x1EE39,
+ },
+ [0x1EE3B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x63A },
+ unicodeslot=0x1EE3B,
+ },
+ [0x1EE42]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62C },
+ unicodeslot=0x1EE42,
+ },
+ [0x1EE47]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62D },
+ unicodeslot=0x1EE47,
+ },
+ [0x1EE49]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x64A },
+ unicodeslot=0x1EE49,
+ },
+ [0x1EE4B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x644 },
+ unicodeslot=0x1EE4B,
+ },
+ [0x1EE4D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x646 },
+ unicodeslot=0x1EE4D,
+ },
+ [0x1EE4E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x633 },
+ unicodeslot=0x1EE4E,
+ },
+ [0x1EE4F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x639 },
+ unicodeslot=0x1EE4F,
+ },
+ [0x1EE51]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x635 },
+ unicodeslot=0x1EE51,
+ },
+ [0x1EE52]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x642 },
+ unicodeslot=0x1EE52,
+ },
+ [0x1EE54]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x634 },
+ unicodeslot=0x1EE54,
+ },
+ [0x1EE57]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62E },
+ unicodeslot=0x1EE57,
+ },
+ [0x1EE59]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x636 },
+ unicodeslot=0x1EE59,
+ },
+ [0x1EE5B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x63A },
+ unicodeslot=0x1EE5B,
+ },
+ [0x1EE5D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x6BA },
+ unicodeslot=0x1EE5D,
+ },
+ [0x1EE5F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x66F },
+ unicodeslot=0x1EE5F,
+ },
+ [0x1EE61]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x628 },
+ unicodeslot=0x1EE61,
+ },
+ [0x1EE62]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62C },
+ unicodeslot=0x1EE62,
+ },
+ [0x1EE64]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x647 },
+ unicodeslot=0x1EE64,
+ },
+ [0x1EE67]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62D },
+ unicodeslot=0x1EE67,
+ },
+ [0x1EE68]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x637 },
+ unicodeslot=0x1EE68,
+ },
+ [0x1EE69]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x64A },
+ unicodeslot=0x1EE69,
+ },
+ [0x1EE6A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x643 },
+ unicodeslot=0x1EE6A,
+ },
+ [0x1EE6C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x645 },
+ unicodeslot=0x1EE6C,
+ },
+ [0x1EE6D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x646 },
+ unicodeslot=0x1EE6D,
+ },
+ [0x1EE6E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x633 },
+ unicodeslot=0x1EE6E,
+ },
+ [0x1EE6F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x639 },
+ unicodeslot=0x1EE6F,
+ },
+ [0x1EE70]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x641 },
+ unicodeslot=0x1EE70,
+ },
+ [0x1EE71]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x635 },
+ unicodeslot=0x1EE71,
+ },
+ [0x1EE72]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x642 },
+ unicodeslot=0x1EE72,
+ },
+ [0x1EE74]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x634 },
+ unicodeslot=0x1EE74,
+ },
+ [0x1EE75]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62A },
+ unicodeslot=0x1EE75,
+ },
+ [0x1EE76]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62B },
+ unicodeslot=0x1EE76,
+ },
+ [0x1EE77]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62E },
+ unicodeslot=0x1EE77,
+ },
+ [0x1EE79]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x636 },
+ unicodeslot=0x1EE79,
+ },
+ [0x1EE7A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x638 },
+ unicodeslot=0x1EE7A,
+ },
+ [0x1EE7B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x63A },
+ unicodeslot=0x1EE7B,
+ },
+ [0x1EE7C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x66E },
+ unicodeslot=0x1EE7C,
+ },
+ [0x1EE7E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x6A1 },
+ unicodeslot=0x1EE7E,
+ },
+ [0x1EE80]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x627 },
+ unicodeslot=0x1EE80,
+ },
+ [0x1EE81]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x628 },
+ unicodeslot=0x1EE81,
+ },
+ [0x1EE82]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62C },
+ unicodeslot=0x1EE82,
+ },
+ [0x1EE83]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62F },
+ unicodeslot=0x1EE83,
+ },
+ [0x1EE84]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x647 },
+ unicodeslot=0x1EE84,
+ },
+ [0x1EE85]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x648 },
+ unicodeslot=0x1EE85,
+ },
+ [0x1EE86]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x632 },
+ unicodeslot=0x1EE86,
+ },
+ [0x1EE87]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62D },
+ unicodeslot=0x1EE87,
+ },
+ [0x1EE88]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x637 },
+ unicodeslot=0x1EE88,
+ },
+ [0x1EE89]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x64A },
+ unicodeslot=0x1EE89,
+ },
+ [0x1EE8B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x644 },
+ unicodeslot=0x1EE8B,
+ },
+ [0x1EE8C]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x645 },
+ unicodeslot=0x1EE8C,
+ },
+ [0x1EE8D]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x646 },
+ unicodeslot=0x1EE8D,
+ },
+ [0x1EE8E]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x633 },
+ unicodeslot=0x1EE8E,
+ },
+ [0x1EE8F]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x639 },
+ unicodeslot=0x1EE8F,
+ },
+ [0x1EE90]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x641 },
+ unicodeslot=0x1EE90,
+ },
+ [0x1EE91]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x635 },
+ unicodeslot=0x1EE91,
+ },
+ [0x1EE92]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x642 },
+ unicodeslot=0x1EE92,
+ },
+ [0x1EE93]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x631 },
+ unicodeslot=0x1EE93,
+ },
+ [0x1EE94]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x634 },
+ unicodeslot=0x1EE94,
+ },
+ [0x1EE95]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62A },
+ unicodeslot=0x1EE95,
+ },
+ [0x1EE96]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62B },
+ unicodeslot=0x1EE96,
+ },
+ [0x1EE97]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62E },
+ unicodeslot=0x1EE97,
+ },
+ [0x1EE98]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x630 },
+ unicodeslot=0x1EE98,
+ },
+ [0x1EE99]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x636 },
+ unicodeslot=0x1EE99,
+ },
+ [0x1EE9A]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x638 },
+ unicodeslot=0x1EE9A,
+ },
+ [0x1EE9B]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x63A },
+ unicodeslot=0x1EE9B,
+ },
+ [0x1EEA1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x628 },
+ unicodeslot=0x1EEA1,
+ },
+ [0x1EEA2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62C },
+ unicodeslot=0x1EEA2,
+ },
+ [0x1EEA3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62F },
+ unicodeslot=0x1EEA3,
+ },
+ [0x1EEA5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x648 },
+ unicodeslot=0x1EEA5,
+ },
+ [0x1EEA6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x632 },
+ unicodeslot=0x1EEA6,
+ },
+ [0x1EEA7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62D },
+ unicodeslot=0x1EEA7,
+ },
+ [0x1EEA8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x637 },
+ unicodeslot=0x1EEA8,
+ },
+ [0x1EEA9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x64A },
+ unicodeslot=0x1EEA9,
+ },
+ [0x1EEAB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x644 },
+ unicodeslot=0x1EEAB,
+ },
+ [0x1EEAC]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x645 },
+ unicodeslot=0x1EEAC,
+ },
+ [0x1EEAD]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x646 },
+ unicodeslot=0x1EEAD,
+ },
+ [0x1EEAE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x633 },
+ unicodeslot=0x1EEAE,
+ },
+ [0x1EEAF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x639 },
+ unicodeslot=0x1EEAF,
+ },
+ [0x1EEB0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x641 },
+ unicodeslot=0x1EEB0,
+ },
+ [0x1EEB1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x635 },
+ unicodeslot=0x1EEB1,
+ },
+ [0x1EEB2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x642 },
+ unicodeslot=0x1EEB2,
+ },
+ [0x1EEB3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x631 },
+ unicodeslot=0x1EEB3,
+ },
+ [0x1EEB4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x634 },
+ unicodeslot=0x1EEB4,
+ },
+ [0x1EEB5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62A },
+ unicodeslot=0x1EEB5,
+ },
+ [0x1EEB6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62B },
+ unicodeslot=0x1EEB6,
+ },
+ [0x1EEB7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x62E },
+ unicodeslot=0x1EEB7,
+ },
+ [0x1EEB8]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x630 },
+ unicodeslot=0x1EEB8,
+ },
+ [0x1EEB9]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x636 },
+ unicodeslot=0x1EEB9,
+ },
+ [0x1EEBA]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x638 },
+ unicodeslot=0x1EEBA,
+ },
+ [0x1EEBB]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x63A },
+ unicodeslot=0x1EEBB,
+ },
+ [0x1EEF0]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1EEF0,
+ },
+ [0x1EEF1]={
+ category="sm",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1EEF1,
+ },
+ [0x1F000]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F000,
+ },
+ [0x1F001]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F001,
+ },
+ [0x1F002]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F002,
+ },
+ [0x1F003]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F003,
+ },
+ [0x1F004]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F004,
+ },
+ [0x1F005]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F005,
+ },
+ [0x1F006]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F006,
+ },
+ [0x1F007]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F007,
+ },
+ [0x1F008]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F008,
+ },
+ [0x1F009]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F009,
+ },
+ [0x1F00A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F00A,
+ },
+ [0x1F00B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F00B,
+ },
+ [0x1F00C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F00C,
+ },
+ [0x1F00D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F00D,
+ },
+ [0x1F00E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F00E,
+ },
+ [0x1F00F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F00F,
+ },
+ [0x1F010]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F010,
+ },
+ [0x1F011]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F011,
+ },
+ [0x1F012]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F012,
+ },
+ [0x1F013]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F013,
+ },
+ [0x1F014]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F014,
+ },
+ [0x1F015]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F015,
+ },
+ [0x1F016]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F016,
+ },
+ [0x1F017]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F017,
+ },
+ [0x1F018]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F018,
+ },
+ [0x1F019]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F019,
+ },
+ [0x1F01A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F01A,
+ },
+ [0x1F01B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F01B,
+ },
+ [0x1F01C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F01C,
+ },
+ [0x1F01D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F01D,
+ },
+ [0x1F01E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F01E,
+ },
+ [0x1F01F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F01F,
+ },
+ [0x1F020]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F020,
+ },
+ [0x1F021]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F021,
+ },
+ [0x1F022]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F022,
+ },
+ [0x1F023]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F023,
+ },
+ [0x1F024]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F024,
+ },
+ [0x1F025]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F025,
+ },
+ [0x1F026]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F026,
+ },
+ [0x1F027]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F027,
+ },
+ [0x1F028]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F028,
+ },
+ [0x1F029]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F029,
+ },
+ [0x1F02A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F02A,
+ },
+ [0x1F02B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F02B,
+ },
+ [0x1F030]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F030,
+ },
+ [0x1F031]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F031,
+ },
+ [0x1F032]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F032,
+ },
+ [0x1F033]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F033,
+ },
+ [0x1F034]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F034,
+ },
+ [0x1F035]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F035,
+ },
+ [0x1F036]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F036,
+ },
+ [0x1F037]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F037,
+ },
+ [0x1F038]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F038,
+ },
+ [0x1F039]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F039,
+ },
+ [0x1F03A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F03A,
+ },
+ [0x1F03B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F03B,
+ },
+ [0x1F03C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F03C,
+ },
+ [0x1F03D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F03D,
+ },
+ [0x1F03E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F03E,
+ },
+ [0x1F03F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F03F,
+ },
+ [0x1F040]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F040,
+ },
+ [0x1F041]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F041,
+ },
+ [0x1F042]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F042,
+ },
+ [0x1F043]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F043,
+ },
+ [0x1F044]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F044,
+ },
+ [0x1F045]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F045,
+ },
+ [0x1F046]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F046,
+ },
+ [0x1F047]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F047,
+ },
+ [0x1F048]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F048,
+ },
+ [0x1F049]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F049,
+ },
+ [0x1F04A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F04A,
+ },
+ [0x1F04B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F04B,
+ },
+ [0x1F04C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F04C,
+ },
+ [0x1F04D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F04D,
+ },
+ [0x1F04E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F04E,
+ },
+ [0x1F04F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F04F,
+ },
+ [0x1F050]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F050,
+ },
+ [0x1F051]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F051,
+ },
+ [0x1F052]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F052,
+ },
+ [0x1F053]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F053,
+ },
+ [0x1F054]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F054,
+ },
+ [0x1F055]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F055,
+ },
+ [0x1F056]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F056,
+ },
+ [0x1F057]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F057,
+ },
+ [0x1F058]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F058,
+ },
+ [0x1F059]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F059,
+ },
+ [0x1F05A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F05A,
+ },
+ [0x1F05B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F05B,
+ },
+ [0x1F05C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F05C,
+ },
+ [0x1F05D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F05D,
+ },
+ [0x1F05E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F05E,
+ },
+ [0x1F05F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F05F,
+ },
+ [0x1F060]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F060,
+ },
+ [0x1F061]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F061,
+ },
+ [0x1F062]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F062,
+ },
+ [0x1F063]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F063,
+ },
+ [0x1F064]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F064,
+ },
+ [0x1F065]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F065,
+ },
+ [0x1F066]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F066,
+ },
+ [0x1F067]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F067,
+ },
+ [0x1F068]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F068,
+ },
+ [0x1F069]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F069,
+ },
+ [0x1F06A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F06A,
+ },
+ [0x1F06B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F06B,
+ },
+ [0x1F06C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F06C,
+ },
+ [0x1F06D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F06D,
+ },
+ [0x1F06E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F06E,
+ },
+ [0x1F06F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F06F,
+ },
+ [0x1F070]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F070,
+ },
+ [0x1F071]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F071,
+ },
+ [0x1F072]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F072,
+ },
+ [0x1F073]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F073,
+ },
+ [0x1F074]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F074,
+ },
+ [0x1F075]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F075,
+ },
+ [0x1F076]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F076,
+ },
+ [0x1F077]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F077,
+ },
+ [0x1F078]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F078,
+ },
+ [0x1F079]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F079,
+ },
+ [0x1F07A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F07A,
+ },
+ [0x1F07B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F07B,
+ },
+ [0x1F07C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F07C,
+ },
+ [0x1F07D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F07D,
+ },
+ [0x1F07E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F07E,
+ },
+ [0x1F07F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F07F,
+ },
+ [0x1F080]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F080,
+ },
+ [0x1F081]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F081,
+ },
+ [0x1F082]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F082,
+ },
+ [0x1F083]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F083,
+ },
+ [0x1F084]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F084,
+ },
+ [0x1F085]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F085,
+ },
+ [0x1F086]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F086,
+ },
+ [0x1F087]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F087,
+ },
+ [0x1F088]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F088,
+ },
+ [0x1F089]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F089,
+ },
+ [0x1F08A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F08A,
+ },
+ [0x1F08B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F08B,
+ },
+ [0x1F08C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F08C,
+ },
+ [0x1F08D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F08D,
+ },
+ [0x1F08E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F08E,
+ },
+ [0x1F08F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F08F,
+ },
+ [0x1F090]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F090,
+ },
+ [0x1F091]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F091,
+ },
+ [0x1F092]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F092,
+ },
+ [0x1F093]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F093,
+ },
+ [0x1F0A0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A0,
+ },
+ [0x1F0A1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A1,
+ },
+ [0x1F0A2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A2,
+ },
+ [0x1F0A3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A3,
+ },
+ [0x1F0A4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A4,
+ },
+ [0x1F0A5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A5,
+ },
+ [0x1F0A6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A6,
+ },
+ [0x1F0A7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A7,
+ },
+ [0x1F0A8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A8,
+ },
+ [0x1F0A9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A9,
+ },
+ [0x1F0AA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0AA,
+ },
+ [0x1F0AB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0AB,
+ },
+ [0x1F0AC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0AC,
+ },
+ [0x1F0AD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0AD,
+ },
+ [0x1F0AE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0AE,
+ },
+ [0x1F0B1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B1,
+ },
+ [0x1F0B2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B2,
+ },
+ [0x1F0B3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B3,
+ },
+ [0x1F0B4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B4,
+ },
+ [0x1F0B5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B5,
+ },
+ [0x1F0B6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B6,
+ },
+ [0x1F0B7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B7,
+ },
+ [0x1F0B8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B8,
+ },
+ [0x1F0B9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B9,
+ },
+ [0x1F0BA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0BA,
+ },
+ [0x1F0BB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0BB,
+ },
+ [0x1F0BC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0BC,
+ },
+ [0x1F0BD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0BD,
+ },
+ [0x1F0BE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0BE,
+ },
+ [0x1F0BF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0BF,
+ },
+ [0x1F0C1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C1,
+ },
+ [0x1F0C2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C2,
+ },
+ [0x1F0C3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C3,
+ },
+ [0x1F0C4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C4,
+ },
+ [0x1F0C5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C5,
+ },
+ [0x1F0C6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C6,
+ },
+ [0x1F0C7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C7,
+ },
+ [0x1F0C8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C8,
+ },
+ [0x1F0C9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C9,
+ },
+ [0x1F0CA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0CA,
+ },
+ [0x1F0CB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0CB,
+ },
+ [0x1F0CC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0CC,
+ },
+ [0x1F0CD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0CD,
+ },
+ [0x1F0CE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0CE,
+ },
+ [0x1F0CF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0CF,
+ },
+ [0x1F0D1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D1,
+ },
+ [0x1F0D2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D2,
+ },
+ [0x1F0D3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D3,
+ },
+ [0x1F0D4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D4,
+ },
+ [0x1F0D5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D5,
+ },
+ [0x1F0D6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D6,
+ },
+ [0x1F0D7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D7,
+ },
+ [0x1F0D8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D8,
+ },
+ [0x1F0D9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D9,
+ },
+ [0x1F0DA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0DA,
+ },
+ [0x1F0DB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0DB,
+ },
+ [0x1F0DC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0DC,
+ },
+ [0x1F0DD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0DD,
+ },
+ [0x1F0DE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0DE,
+ },
+ [0x1F0DF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0DF,
+ },
+ [0x1F0E0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0E0,
+ },
+ [0x1F0E1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0E1,
+ },
+ [0x1F0E2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0E2,
+ },
+ [0x1F0E3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0E3,
+ },
+ [0x1F0E4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0E4,
+ },
+ [0x1F0E5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0E5,
+ },
+ [0x1F0E6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0E6,
+ },
+ [0x1F0E7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0E7,
+ },
+ [0x1F0E8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0E8,
+ },
+ [0x1F0E9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0E9,
+ },
+ [0x1F0EA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0EA,
+ },
+ [0x1F0EB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0EB,
+ },
+ [0x1F0EC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0EC,
+ },
+ [0x1F0ED]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0ED,
+ },
+ [0x1F0EE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0EE,
+ },
+ [0x1F0EF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0EF,
+ },
+ [0x1F0F0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0F0,
+ },
+ [0x1F0F1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0F1,
+ },
+ [0x1F0F2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0F2,
+ },
+ [0x1F0F3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0F3,
+ },
+ [0x1F0F4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0F4,
+ },
+ [0x1F0F5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0F5,
+ },
+ [0x1F100]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x30, 0x2E },
+ unicodeslot=0x1F100,
+ },
+ [0x1F101]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x30, 0x2C },
+ unicodeslot=0x1F101,
+ },
+ [0x1F102]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x31, 0x2C },
+ unicodeslot=0x1F102,
+ },
+ [0x1F103]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x32, 0x2C },
+ unicodeslot=0x1F103,
+ },
+ [0x1F104]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x33, 0x2C },
+ unicodeslot=0x1F104,
+ },
+ [0x1F105]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x34, 0x2C },
+ unicodeslot=0x1F105,
+ },
+ [0x1F106]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x35, 0x2C },
+ unicodeslot=0x1F106,
+ },
+ [0x1F107]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x36, 0x2C },
+ unicodeslot=0x1F107,
+ },
+ [0x1F108]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x37, 0x2C },
+ unicodeslot=0x1F108,
+ },
+ [0x1F109]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x38, 0x2C },
+ unicodeslot=0x1F109,
+ },
+ [0x1F10A]={
+ category="no",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x39, 0x2C },
+ unicodeslot=0x1F10A,
+ },
+ [0x1F10B]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x1F10B,
+ },
+ [0x1F10C]={
+ category="no",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x1F10C,
+ },
+ [0x1F110]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x41, 0x29 },
+ unicodeslot=0x1F110,
+ },
+ [0x1F111]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x42, 0x29 },
+ unicodeslot=0x1F111,
+ },
+ [0x1F112]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x43, 0x29 },
+ unicodeslot=0x1F112,
+ },
+ [0x1F113]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x44, 0x29 },
+ unicodeslot=0x1F113,
+ },
+ [0x1F114]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x45, 0x29 },
+ unicodeslot=0x1F114,
+ },
+ [0x1F115]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x46, 0x29 },
+ unicodeslot=0x1F115,
+ },
+ [0x1F116]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x47, 0x29 },
+ unicodeslot=0x1F116,
+ },
+ [0x1F117]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x48, 0x29 },
+ unicodeslot=0x1F117,
+ },
+ [0x1F118]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x49, 0x29 },
+ unicodeslot=0x1F118,
+ },
+ [0x1F119]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x4A, 0x29 },
+ unicodeslot=0x1F119,
+ },
+ [0x1F11A]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x4B, 0x29 },
+ unicodeslot=0x1F11A,
+ },
+ [0x1F11B]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x4C, 0x29 },
+ unicodeslot=0x1F11B,
+ },
+ [0x1F11C]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x4D, 0x29 },
+ unicodeslot=0x1F11C,
+ },
+ [0x1F11D]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x4E, 0x29 },
+ unicodeslot=0x1F11D,
+ },
+ [0x1F11E]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x4F, 0x29 },
+ unicodeslot=0x1F11E,
+ },
+ [0x1F11F]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x50, 0x29 },
+ unicodeslot=0x1F11F,
+ },
+ [0x1F120]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x51, 0x29 },
+ unicodeslot=0x1F120,
+ },
+ [0x1F121]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x52, 0x29 },
+ unicodeslot=0x1F121,
+ },
+ [0x1F122]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x53, 0x29 },
+ unicodeslot=0x1F122,
+ },
+ [0x1F123]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x54, 0x29 },
+ unicodeslot=0x1F123,
+ },
+ [0x1F124]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x55, 0x29 },
+ unicodeslot=0x1F124,
+ },
+ [0x1F125]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x56, 0x29 },
+ unicodeslot=0x1F125,
+ },
+ [0x1F126]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x57, 0x29 },
+ unicodeslot=0x1F126,
+ },
+ [0x1F127]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x58, 0x29 },
+ unicodeslot=0x1F127,
+ },
+ [0x1F128]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x59, 0x29 },
+ unicodeslot=0x1F128,
+ },
+ [0x1F129]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x28, 0x5A, 0x29 },
+ unicodeslot=0x1F129,
+ },
+ [0x1F12A]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x3014, 0x53, 0x3015 },
+ unicodeslot=0x1F12A,
+ },
+ [0x1F12B]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x43 },
+ unicodeslot=0x1F12B,
+ },
+ [0x1F12C]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x52 },
+ unicodeslot=0x1F12C,
+ },
+ [0x1F12D]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x43, 0x44 },
+ unicodeslot=0x1F12D,
+ },
+ [0x1F12E]={
+ category="so",
+ direction="l",
+ linebreak="al",
+ specials={ "circle", 0x57, 0x5A },
+ unicodeslot=0x1F12E,
+ },
+ [0x1F12F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F12F,
+ },
+ [0x1F130]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x41 },
+ unicodeslot=0x1F130,
+ },
+ [0x1F131]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x42 },
+ unicodeslot=0x1F131,
+ },
+ [0x1F132]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x43 },
+ unicodeslot=0x1F132,
+ },
+ [0x1F133]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x44 },
+ unicodeslot=0x1F133,
+ },
+ [0x1F134]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x45 },
+ unicodeslot=0x1F134,
+ },
+ [0x1F135]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x46 },
+ unicodeslot=0x1F135,
+ },
+ [0x1F136]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x47 },
+ unicodeslot=0x1F136,
+ },
+ [0x1F137]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x48 },
+ unicodeslot=0x1F137,
+ },
+ [0x1F138]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x49 },
+ unicodeslot=0x1F138,
+ },
+ [0x1F139]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x4A },
+ unicodeslot=0x1F139,
+ },
+ [0x1F13A]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x4B },
+ unicodeslot=0x1F13A,
+ },
+ [0x1F13B]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x4C },
+ unicodeslot=0x1F13B,
+ },
+ [0x1F13C]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x4D },
+ unicodeslot=0x1F13C,
+ },
+ [0x1F13D]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x4E },
+ unicodeslot=0x1F13D,
+ },
+ [0x1F13E]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x4F },
+ unicodeslot=0x1F13E,
+ },
+ [0x1F13F]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x50 },
+ unicodeslot=0x1F13F,
+ },
+ [0x1F140]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x51 },
+ unicodeslot=0x1F140,
+ },
+ [0x1F141]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x52 },
+ unicodeslot=0x1F141,
+ },
+ [0x1F142]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x53 },
+ unicodeslot=0x1F142,
+ },
+ [0x1F143]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x54 },
+ unicodeslot=0x1F143,
+ },
+ [0x1F144]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x55 },
+ unicodeslot=0x1F144,
+ },
+ [0x1F145]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x56 },
+ unicodeslot=0x1F145,
+ },
+ [0x1F146]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x57 },
+ unicodeslot=0x1F146,
+ },
+ [0x1F147]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x58 },
+ unicodeslot=0x1F147,
+ },
+ [0x1F148]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x59 },
+ unicodeslot=0x1F148,
+ },
+ [0x1F149]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x5A },
+ unicodeslot=0x1F149,
+ },
+ [0x1F14A]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x48, 0x56 },
+ unicodeslot=0x1F14A,
+ },
+ [0x1F14B]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x4D, 0x56 },
+ unicodeslot=0x1F14B,
+ },
+ [0x1F14C]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x53, 0x44 },
+ unicodeslot=0x1F14C,
+ },
+ [0x1F14D]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x53, 0x53 },
+ unicodeslot=0x1F14D,
+ },
+ [0x1F14E]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x50, 0x50, 0x56 },
+ unicodeslot=0x1F14E,
+ },
+ [0x1F14F]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x57, 0x43 },
+ unicodeslot=0x1F14F,
+ },
+ [0x1F150]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F150,
+ },
+ [0x1F151]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F151,
+ },
+ [0x1F152]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F152,
+ },
+ [0x1F153]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F153,
+ },
+ [0x1F154]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F154,
+ },
+ [0x1F155]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F155,
+ },
+ [0x1F156]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F156,
+ },
+ [0x1F157]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F157,
+ },
+ [0x1F158]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F158,
+ },
+ [0x1F159]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F159,
+ },
+ [0x1F15A]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F15A,
+ },
+ [0x1F15B]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F15B,
+ },
+ [0x1F15C]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F15C,
+ },
+ [0x1F15D]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F15D,
+ },
+ [0x1F15E]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F15E,
+ },
+ [0x1F15F]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F15F,
+ },
+ [0x1F160]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F160,
+ },
+ [0x1F161]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F161,
+ },
+ [0x1F162]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F162,
+ },
+ [0x1F163]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F163,
+ },
+ [0x1F164]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F164,
+ },
+ [0x1F165]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F165,
+ },
+ [0x1F166]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F166,
+ },
+ [0x1F167]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F167,
+ },
+ [0x1F168]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F168,
+ },
+ [0x1F169]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F169,
+ },
+ [0x1F16A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ specials={ "super", 0x4D, 0x43 },
+ unicodeslot=0x1F16A,
+ },
+ [0x1F16B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ specials={ "super", 0x4D, 0x44 },
+ unicodeslot=0x1F16B,
+ },
+ [0x1F16C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ specials={ "super", 0x4D, 0x52 },
+ unicodeslot=0x1F16C,
+ },
+ [0x1F170]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F170,
+ },
+ [0x1F171]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F171,
+ },
+ [0x1F172]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F172,
+ },
+ [0x1F173]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F173,
+ },
+ [0x1F174]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F174,
+ },
+ [0x1F175]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F175,
+ },
+ [0x1F176]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F176,
+ },
+ [0x1F177]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F177,
+ },
+ [0x1F178]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F178,
+ },
+ [0x1F179]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F179,
+ },
+ [0x1F17A]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F17A,
+ },
+ [0x1F17B]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F17B,
+ },
+ [0x1F17C]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F17C,
+ },
+ [0x1F17D]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F17D,
+ },
+ [0x1F17E]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F17E,
+ },
+ [0x1F17F]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F17F,
+ },
+ [0x1F180]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F180,
+ },
+ [0x1F181]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F181,
+ },
+ [0x1F182]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F182,
+ },
+ [0x1F183]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F183,
+ },
+ [0x1F184]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F184,
+ },
+ [0x1F185]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F185,
+ },
+ [0x1F186]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F186,
+ },
+ [0x1F187]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F187,
+ },
+ [0x1F188]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F188,
+ },
+ [0x1F189]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F189,
+ },
+ [0x1F18A]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F18A,
+ },
+ [0x1F18B]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F18B,
+ },
+ [0x1F18C]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F18C,
+ },
+ [0x1F18D]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F18D,
+ },
+ [0x1F18E]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F18E,
+ },
+ [0x1F18F]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F18F,
+ },
+ [0x1F190]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x44, 0x4A },
+ unicodeslot=0x1F190,
+ },
+ [0x1F191]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F191,
+ },
+ [0x1F192]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F192,
+ },
+ [0x1F193]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F193,
+ },
+ [0x1F194]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F194,
+ },
+ [0x1F195]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F195,
+ },
+ [0x1F196]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F196,
+ },
+ [0x1F197]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F197,
+ },
+ [0x1F198]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F198,
+ },
+ [0x1F199]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F199,
+ },
+ [0x1F19A]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F19A,
+ },
+ [0x1F19B]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F19B,
+ },
+ [0x1F19C]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F19C,
+ },
+ [0x1F19D]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F19D,
+ },
+ [0x1F19E]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F19E,
+ },
+ [0x1F19F]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F19F,
+ },
+ [0x1F1A0]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1A0,
+ },
+ [0x1F1A1]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1A1,
+ },
+ [0x1F1A2]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1A2,
+ },
+ [0x1F1A3]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1A3,
+ },
+ [0x1F1A4]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1A4,
+ },
+ [0x1F1A5]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1A5,
+ },
+ [0x1F1A6]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1A6,
+ },
+ [0x1F1A7]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1A7,
+ },
+ [0x1F1A8]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1A8,
+ },
+ [0x1F1A9]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1A9,
+ },
+ [0x1F1AA]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1AA,
+ },
+ [0x1F1AB]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1AB,
+ },
+ [0x1F1AC]={
+ category="so",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F1AC,
+ },
+ [0x1F1E6]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1E6,
+ },
+ [0x1F1E7]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1E7,
+ },
+ [0x1F1E8]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1E8,
+ },
+ [0x1F1E9]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1E9,
+ },
+ [0x1F1EA]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1EA,
+ },
+ [0x1F1EB]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1EB,
+ },
+ [0x1F1EC]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1EC,
+ },
+ [0x1F1ED]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1ED,
+ },
+ [0x1F1EE]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1EE,
+ },
+ [0x1F1EF]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1EF,
+ },
+ [0x1F1F0]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F0,
+ },
+ [0x1F1F1]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F1,
+ },
+ [0x1F1F2]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F2,
+ },
+ [0x1F1F3]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F3,
+ },
+ [0x1F1F4]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F4,
+ },
+ [0x1F1F5]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F5,
+ },
+ [0x1F1F6]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F6,
+ },
+ [0x1F1F7]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F7,
+ },
+ [0x1F1F8]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F8,
+ },
+ [0x1F1F9]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F9,
+ },
+ [0x1F1FA]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1FA,
+ },
+ [0x1F1FB]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1FB,
+ },
+ [0x1F1FC]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1FC,
+ },
+ [0x1F1FD]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1FD,
+ },
+ [0x1F1FE]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1FE,
+ },
+ [0x1F1FF]={
+ category="so",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1FF,
+ },
+ [0x1F200]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x307B, 0x304B },
+ unicodeslot=0x1F200,
+ },
+ [0x1F201]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B3, 0x30B3 },
+ unicodeslot=0x1F201,
+ },
+ [0x1F202]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B5 },
+ unicodeslot=0x1F202,
+ },
+ [0x1F210]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x624B },
+ unicodeslot=0x1F210,
+ },
+ [0x1F211]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5B57 },
+ unicodeslot=0x1F211,
+ },
+ [0x1F212]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x53CC },
+ unicodeslot=0x1F212,
+ },
+ [0x1F213]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30C7 },
+ unicodeslot=0x1F213,
+ },
+ [0x1F214]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4E8C },
+ unicodeslot=0x1F214,
+ },
+ [0x1F215]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x591A },
+ unicodeslot=0x1F215,
+ },
+ [0x1F216]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x89E3 },
+ unicodeslot=0x1F216,
+ },
+ [0x1F217]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5929 },
+ unicodeslot=0x1F217,
+ },
+ [0x1F218]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4EA4 },
+ unicodeslot=0x1F218,
+ },
+ [0x1F219]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6620 },
+ unicodeslot=0x1F219,
+ },
+ [0x1F21A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x7121 },
+ unicodeslot=0x1F21A,
+ },
+ [0x1F21B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6599 },
+ unicodeslot=0x1F21B,
+ },
+ [0x1F21C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x524D },
+ unicodeslot=0x1F21C,
+ },
+ [0x1F21D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5F8C },
+ unicodeslot=0x1F21D,
+ },
+ [0x1F21E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x518D },
+ unicodeslot=0x1F21E,
+ },
+ [0x1F21F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x65B0 },
+ unicodeslot=0x1F21F,
+ },
+ [0x1F220]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x521D },
+ unicodeslot=0x1F220,
+ },
+ [0x1F221]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x7D42 },
+ unicodeslot=0x1F221,
+ },
+ [0x1F222]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x751F },
+ unicodeslot=0x1F222,
+ },
+ [0x1F223]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x8CA9 },
+ unicodeslot=0x1F223,
+ },
+ [0x1F224]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x58F0 },
+ unicodeslot=0x1F224,
+ },
+ [0x1F225]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5439 },
+ unicodeslot=0x1F225,
+ },
+ [0x1F226]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6F14 },
+ unicodeslot=0x1F226,
+ },
+ [0x1F227]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6295 },
+ unicodeslot=0x1F227,
+ },
+ [0x1F228]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6355 },
+ unicodeslot=0x1F228,
+ },
+ [0x1F229]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4E00 },
+ unicodeslot=0x1F229,
+ },
+ [0x1F22A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4E09 },
+ unicodeslot=0x1F22A,
+ },
+ [0x1F22B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x904A },
+ unicodeslot=0x1F22B,
+ },
+ [0x1F22C]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5DE6 },
+ unicodeslot=0x1F22C,
+ },
+ [0x1F22D]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4E2D },
+ unicodeslot=0x1F22D,
+ },
+ [0x1F22E]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x53F3 },
+ unicodeslot=0x1F22E,
+ },
+ [0x1F22F]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6307 },
+ unicodeslot=0x1F22F,
+ },
+ [0x1F230]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x8D70 },
+ unicodeslot=0x1F230,
+ },
+ [0x1F231]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6253 },
+ unicodeslot=0x1F231,
+ },
+ [0x1F232]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x7981 },
+ unicodeslot=0x1F232,
+ },
+ [0x1F233]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x7A7A },
+ unicodeslot=0x1F233,
+ },
+ [0x1F234]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5408 },
+ unicodeslot=0x1F234,
+ },
+ [0x1F235]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6E80 },
+ unicodeslot=0x1F235,
+ },
+ [0x1F236]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6709 },
+ unicodeslot=0x1F236,
+ },
+ [0x1F237]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6708 },
+ unicodeslot=0x1F237,
+ },
+ [0x1F238]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x7533 },
+ unicodeslot=0x1F238,
+ },
+ [0x1F239]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5272 },
+ unicodeslot=0x1F239,
+ },
+ [0x1F23A]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x55B6 },
+ unicodeslot=0x1F23A,
+ },
+ [0x1F23B]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x914D },
+ unicodeslot=0x1F23B,
+ },
+ [0x1F240]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x672C, 0x3015 },
+ unicodeslot=0x1F240,
+ },
+ [0x1F241]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x4E09, 0x3015 },
+ unicodeslot=0x1F241,
+ },
+ [0x1F242]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x4E8C, 0x3015 },
+ unicodeslot=0x1F242,
+ },
+ [0x1F243]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x5B89, 0x3015 },
+ unicodeslot=0x1F243,
+ },
+ [0x1F244]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x70B9, 0x3015 },
+ unicodeslot=0x1F244,
+ },
+ [0x1F245]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x6253, 0x3015 },
+ unicodeslot=0x1F245,
+ },
+ [0x1F246]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x76D7, 0x3015 },
+ unicodeslot=0x1F246,
+ },
+ [0x1F247]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x52DD, 0x3015 },
+ unicodeslot=0x1F247,
+ },
+ [0x1F248]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x6557, 0x3015 },
+ unicodeslot=0x1F248,
+ },
+ [0x1F250]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5F97 },
+ unicodeslot=0x1F250,
+ },
+ [0x1F251]={
+ category="so",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x53EF },
+ unicodeslot=0x1F251,
+ },
+ [0x1F260]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F260,
+ },
+ [0x1F261]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F261,
+ },
+ [0x1F262]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F262,
+ },
+ [0x1F263]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F263,
+ },
+ [0x1F264]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F264,
+ },
+ [0x1F265]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F265,
+ },
+ [0x1F300]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F300,
+ },
+ [0x1F301]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F301,
+ },
+ [0x1F302]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F302,
+ },
+ [0x1F303]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F303,
+ },
+ [0x1F304]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F304,
+ },
+ [0x1F305]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F305,
+ },
+ [0x1F306]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F306,
+ },
+ [0x1F307]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F307,
+ },
+ [0x1F308]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F308,
+ },
+ [0x1F309]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F309,
+ },
+ [0x1F30A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F30A,
+ },
+ [0x1F30B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F30B,
+ },
+ [0x1F30C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F30C,
+ },
+ [0x1F30D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F30D,
+ },
+ [0x1F30E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F30E,
+ },
+ [0x1F30F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F30F,
+ },
+ [0x1F310]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F310,
+ },
+ [0x1F311]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F311,
+ },
+ [0x1F312]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F312,
+ },
+ [0x1F313]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F313,
+ },
+ [0x1F314]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F314,
+ },
+ [0x1F315]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F315,
+ },
+ [0x1F316]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F316,
+ },
+ [0x1F317]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F317,
+ },
+ [0x1F318]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F318,
+ },
+ [0x1F319]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F319,
+ },
+ [0x1F31A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F31A,
+ },
+ [0x1F31B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F31B,
+ },
+ [0x1F31C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F31C,
+ },
+ [0x1F31D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F31D,
+ },
+ [0x1F31E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F31E,
+ },
+ [0x1F31F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F31F,
+ },
+ [0x1F320]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F320,
+ },
+ [0x1F321]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F321,
+ },
+ [0x1F322]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F322,
+ },
+ [0x1F323]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F323,
+ },
+ [0x1F324]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F324,
+ },
+ [0x1F325]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F325,
+ },
+ [0x1F326]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F326,
+ },
+ [0x1F327]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F327,
+ },
+ [0x1F328]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F328,
+ },
+ [0x1F329]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F329,
+ },
+ [0x1F32A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F32A,
+ },
+ [0x1F32B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F32B,
+ },
+ [0x1F32C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F32C,
+ },
+ [0x1F32D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F32D,
+ },
+ [0x1F32E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F32E,
+ },
+ [0x1F32F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F32F,
+ },
+ [0x1F330]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F330,
+ },
+ [0x1F331]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F331,
+ },
+ [0x1F332]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F332,
+ },
+ [0x1F333]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F333,
+ },
+ [0x1F334]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F334,
+ },
+ [0x1F335]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F335,
+ },
+ [0x1F336]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F336,
+ },
+ [0x1F337]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F337,
+ },
+ [0x1F338]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F338,
+ },
+ [0x1F339]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F339,
+ },
+ [0x1F33A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F33A,
+ },
+ [0x1F33B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F33B,
+ },
+ [0x1F33C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F33C,
+ },
+ [0x1F33D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F33D,
+ },
+ [0x1F33E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F33E,
+ },
+ [0x1F33F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F33F,
+ },
+ [0x1F340]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F340,
+ },
+ [0x1F341]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F341,
+ },
+ [0x1F342]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F342,
+ },
+ [0x1F343]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F343,
+ },
+ [0x1F344]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F344,
+ },
+ [0x1F345]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F345,
+ },
+ [0x1F346]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F346,
+ },
+ [0x1F347]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F347,
+ },
+ [0x1F348]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F348,
+ },
+ [0x1F349]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F349,
+ },
+ [0x1F34A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F34A,
+ },
+ [0x1F34B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F34B,
+ },
+ [0x1F34C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F34C,
+ },
+ [0x1F34D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F34D,
+ },
+ [0x1F34E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F34E,
+ },
+ [0x1F34F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F34F,
+ },
+ [0x1F350]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F350,
+ },
+ [0x1F351]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F351,
+ },
+ [0x1F352]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F352,
+ },
+ [0x1F353]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F353,
+ },
+ [0x1F354]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F354,
+ },
+ [0x1F355]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F355,
+ },
+ [0x1F356]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F356,
+ },
+ [0x1F357]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F357,
+ },
+ [0x1F358]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F358,
+ },
+ [0x1F359]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F359,
+ },
+ [0x1F35A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F35A,
+ },
+ [0x1F35B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F35B,
+ },
+ [0x1F35C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F35C,
+ },
+ [0x1F35D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F35D,
+ },
+ [0x1F35E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F35E,
+ },
+ [0x1F35F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F35F,
+ },
+ [0x1F360]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F360,
+ },
+ [0x1F361]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F361,
+ },
+ [0x1F362]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F362,
+ },
+ [0x1F363]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F363,
+ },
+ [0x1F364]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F364,
+ },
+ [0x1F365]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F365,
+ },
+ [0x1F366]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F366,
+ },
+ [0x1F367]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F367,
+ },
+ [0x1F368]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F368,
+ },
+ [0x1F369]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F369,
+ },
+ [0x1F36A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F36A,
+ },
+ [0x1F36B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F36B,
+ },
+ [0x1F36C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F36C,
+ },
+ [0x1F36D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F36D,
+ },
+ [0x1F36E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F36E,
+ },
+ [0x1F36F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F36F,
+ },
+ [0x1F370]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F370,
+ },
+ [0x1F371]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F371,
+ },
+ [0x1F372]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F372,
+ },
+ [0x1F373]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F373,
+ },
+ [0x1F374]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F374,
+ },
+ [0x1F375]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F375,
+ },
+ [0x1F376]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F376,
+ },
+ [0x1F377]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F377,
+ },
+ [0x1F378]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F378,
+ },
+ [0x1F379]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F379,
+ },
+ [0x1F37A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F37A,
+ },
+ [0x1F37B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F37B,
+ },
+ [0x1F37C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F37C,
+ },
+ [0x1F37D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F37D,
+ },
+ [0x1F37E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F37E,
+ },
+ [0x1F37F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F37F,
+ },
+ [0x1F380]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F380,
+ },
+ [0x1F381]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F381,
+ },
+ [0x1F382]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F382,
+ },
+ [0x1F383]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F383,
+ },
+ [0x1F384]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F384,
+ },
+ [0x1F385]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F385,
+ },
+ [0x1F386]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F386,
+ },
+ [0x1F387]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F387,
+ },
+ [0x1F388]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F388,
+ },
+ [0x1F389]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F389,
+ },
+ [0x1F38A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F38A,
+ },
+ [0x1F38B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F38B,
+ },
+ [0x1F38C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F38C,
+ },
+ [0x1F38D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F38D,
+ },
+ [0x1F38E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F38E,
+ },
+ [0x1F38F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F38F,
+ },
+ [0x1F390]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F390,
+ },
+ [0x1F391]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F391,
+ },
+ [0x1F392]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F392,
+ },
+ [0x1F393]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F393,
+ },
+ [0x1F394]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F394,
+ },
+ [0x1F395]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F395,
+ },
+ [0x1F396]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F396,
+ },
+ [0x1F397]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F397,
+ },
+ [0x1F398]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F398,
+ },
+ [0x1F399]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F399,
+ },
+ [0x1F39A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F39A,
+ },
+ [0x1F39B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F39B,
+ },
+ [0x1F39C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F39C,
+ },
+ [0x1F39D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F39D,
+ },
+ [0x1F39E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F39E,
+ },
+ [0x1F39F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F39F,
+ },
+ [0x1F3A0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A0,
+ },
+ [0x1F3A1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A1,
+ },
+ [0x1F3A2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A2,
+ },
+ [0x1F3A3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A3,
+ },
+ [0x1F3A4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A4,
+ },
+ [0x1F3A5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A5,
+ },
+ [0x1F3A6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A6,
+ },
+ [0x1F3A7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A7,
+ },
+ [0x1F3A8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A8,
+ },
+ [0x1F3A9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A9,
+ },
+ [0x1F3AA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3AA,
+ },
+ [0x1F3AB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3AB,
+ },
+ [0x1F3AC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3AC,
+ },
+ [0x1F3AD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3AD,
+ },
+ [0x1F3AE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3AE,
+ },
+ [0x1F3AF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3AF,
+ },
+ [0x1F3B0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B0,
+ },
+ [0x1F3B1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B1,
+ },
+ [0x1F3B2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B2,
+ },
+ [0x1F3B3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B3,
+ },
+ [0x1F3B4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B4,
+ },
+ [0x1F3B5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F3B5,
+ },
+ [0x1F3B6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F3B6,
+ },
+ [0x1F3B7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B7,
+ },
+ [0x1F3B8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B8,
+ },
+ [0x1F3B9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B9,
+ },
+ [0x1F3BA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3BA,
+ },
+ [0x1F3BB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3BB,
+ },
+ [0x1F3BC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F3BC,
+ },
+ [0x1F3BD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3BD,
+ },
+ [0x1F3BE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3BE,
+ },
+ [0x1F3BF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3BF,
+ },
+ [0x1F3C0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C0,
+ },
+ [0x1F3C1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C1,
+ },
+ [0x1F3C2]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F3C2,
+ },
+ [0x1F3C3]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F3C3,
+ },
+ [0x1F3C4]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F3C4,
+ },
+ [0x1F3C5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C5,
+ },
+ [0x1F3C6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C6,
+ },
+ [0x1F3C7]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F3C7,
+ },
+ [0x1F3C8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C8,
+ },
+ [0x1F3C9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C9,
+ },
+ [0x1F3CA]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F3CA,
+ },
+ [0x1F3CB]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F3CB,
+ },
+ [0x1F3CC]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F3CC,
+ },
+ [0x1F3CD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3CD,
+ },
+ [0x1F3CE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3CE,
+ },
+ [0x1F3CF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3CF,
+ },
+ [0x1F3D0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3D0,
+ },
+ [0x1F3D1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3D1,
+ },
+ [0x1F3D2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3D2,
+ },
+ [0x1F3D3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3D3,
+ },
+ [0x1F3D4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3D4,
+ },
+ [0x1F3D5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3D5,
+ },
+ [0x1F3D6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3D6,
+ },
+ [0x1F3D7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3D7,
+ },
+ [0x1F3D8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3D8,
+ },
+ [0x1F3D9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3D9,
+ },
+ [0x1F3DA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3DA,
+ },
+ [0x1F3DB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3DB,
+ },
+ [0x1F3DC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3DC,
+ },
+ [0x1F3DD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3DD,
+ },
+ [0x1F3DE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3DE,
+ },
+ [0x1F3DF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3DF,
+ },
+ [0x1F3E0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E0,
+ },
+ [0x1F3E1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E1,
+ },
+ [0x1F3E2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E2,
+ },
+ [0x1F3E3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E3,
+ },
+ [0x1F3E4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E4,
+ },
+ [0x1F3E5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E5,
+ },
+ [0x1F3E6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E6,
+ },
+ [0x1F3E7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E7,
+ },
+ [0x1F3E8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E8,
+ },
+ [0x1F3E9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E9,
+ },
+ [0x1F3EA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3EA,
+ },
+ [0x1F3EB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3EB,
+ },
+ [0x1F3EC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3EC,
+ },
+ [0x1F3ED]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3ED,
+ },
+ [0x1F3EE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3EE,
+ },
+ [0x1F3EF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3EF,
+ },
+ [0x1F3F0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3F0,
+ },
+ [0x1F3F1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3F1,
+ },
+ [0x1F3F2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3F2,
+ },
+ [0x1F3F3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3F3,
+ },
+ [0x1F3F4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3F4,
+ },
+ [0x1F3F5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3F5,
+ },
+ [0x1F3F6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3F6,
+ },
+ [0x1F3F7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3F7,
+ },
+ [0x1F3F8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3F8,
+ },
+ [0x1F3F9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3F9,
+ },
+ [0x1F3FA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3FA,
+ },
+ [0x1F3FB]={
+ category="sk",
+ direction="on",
+ linebreak="em",
+ unicodeslot=0x1F3FB,
+ },
+ [0x1F3FC]={
+ category="sk",
+ direction="on",
+ linebreak="em",
+ unicodeslot=0x1F3FC,
+ },
+ [0x1F3FD]={
+ category="sk",
+ direction="on",
+ linebreak="em",
+ unicodeslot=0x1F3FD,
+ },
+ [0x1F3FE]={
+ category="sk",
+ direction="on",
+ linebreak="em",
+ unicodeslot=0x1F3FE,
+ },
+ [0x1F3FF]={
+ category="sk",
+ direction="on",
+ linebreak="em",
+ unicodeslot=0x1F3FF,
+ },
+ [0x1F400]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F400,
+ },
+ [0x1F401]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F401,
+ },
+ [0x1F402]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F402,
+ },
+ [0x1F403]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F403,
+ },
+ [0x1F404]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F404,
+ },
+ [0x1F405]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F405,
+ },
+ [0x1F406]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F406,
+ },
+ [0x1F407]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F407,
+ },
+ [0x1F408]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F408,
+ },
+ [0x1F409]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F409,
+ },
+ [0x1F40A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F40A,
+ },
+ [0x1F40B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F40B,
+ },
+ [0x1F40C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F40C,
+ },
+ [0x1F40D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F40D,
+ },
+ [0x1F40E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F40E,
+ },
+ [0x1F40F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F40F,
+ },
+ [0x1F410]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F410,
+ },
+ [0x1F411]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F411,
+ },
+ [0x1F412]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F412,
+ },
+ [0x1F413]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F413,
+ },
+ [0x1F414]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F414,
+ },
+ [0x1F415]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F415,
+ },
+ [0x1F416]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F416,
+ },
+ [0x1F417]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F417,
+ },
+ [0x1F418]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F418,
+ },
+ [0x1F419]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F419,
+ },
+ [0x1F41A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F41A,
+ },
+ [0x1F41B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F41B,
+ },
+ [0x1F41C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F41C,
+ },
+ [0x1F41D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F41D,
+ },
+ [0x1F41E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F41E,
+ },
+ [0x1F41F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F41F,
+ },
+ [0x1F420]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F420,
+ },
+ [0x1F421]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F421,
+ },
+ [0x1F422]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F422,
+ },
+ [0x1F423]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F423,
+ },
+ [0x1F424]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F424,
+ },
+ [0x1F425]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F425,
+ },
+ [0x1F426]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F426,
+ },
+ [0x1F427]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F427,
+ },
+ [0x1F428]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F428,
+ },
+ [0x1F429]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F429,
+ },
+ [0x1F42A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F42A,
+ },
+ [0x1F42B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F42B,
+ },
+ [0x1F42C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F42C,
+ },
+ [0x1F42D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F42D,
+ },
+ [0x1F42E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F42E,
+ },
+ [0x1F42F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F42F,
+ },
+ [0x1F430]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F430,
+ },
+ [0x1F431]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F431,
+ },
+ [0x1F432]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F432,
+ },
+ [0x1F433]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F433,
+ },
+ [0x1F434]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F434,
+ },
+ [0x1F435]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F435,
+ },
+ [0x1F436]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F436,
+ },
+ [0x1F437]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F437,
+ },
+ [0x1F438]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F438,
+ },
+ [0x1F439]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F439,
+ },
+ [0x1F43A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F43A,
+ },
+ [0x1F43B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F43B,
+ },
+ [0x1F43C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F43C,
+ },
+ [0x1F43D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F43D,
+ },
+ [0x1F43E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F43E,
+ },
+ [0x1F43F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F43F,
+ },
+ [0x1F440]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F440,
+ },
+ [0x1F441]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F441,
+ },
+ [0x1F442]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F442,
+ },
+ [0x1F443]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F443,
+ },
+ [0x1F444]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F444,
+ },
+ [0x1F445]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F445,
+ },
+ [0x1F446]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F446,
+ },
+ [0x1F447]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F447,
+ },
+ [0x1F448]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F448,
+ },
+ [0x1F449]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F449,
+ },
+ [0x1F44A]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F44A,
+ },
+ [0x1F44B]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F44B,
+ },
+ [0x1F44C]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F44C,
+ },
+ [0x1F44D]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F44D,
+ },
+ [0x1F44E]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F44E,
+ },
+ [0x1F44F]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F44F,
+ },
+ [0x1F450]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F450,
+ },
+ [0x1F451]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F451,
+ },
+ [0x1F452]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F452,
+ },
+ [0x1F453]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F453,
+ },
+ [0x1F454]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F454,
+ },
+ [0x1F455]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F455,
+ },
+ [0x1F456]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F456,
+ },
+ [0x1F457]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F457,
+ },
+ [0x1F458]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F458,
+ },
+ [0x1F459]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F459,
+ },
+ [0x1F45A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F45A,
+ },
+ [0x1F45B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F45B,
+ },
+ [0x1F45C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F45C,
+ },
+ [0x1F45D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F45D,
+ },
+ [0x1F45E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F45E,
+ },
+ [0x1F45F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F45F,
+ },
+ [0x1F460]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F460,
+ },
+ [0x1F461]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F461,
+ },
+ [0x1F462]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F462,
+ },
+ [0x1F463]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F463,
+ },
+ [0x1F464]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F464,
+ },
+ [0x1F465]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F465,
+ },
+ [0x1F466]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F466,
+ },
+ [0x1F467]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F467,
+ },
+ [0x1F468]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F468,
+ },
+ [0x1F469]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F469,
+ },
+ [0x1F46A]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F46A,
+ },
+ [0x1F46B]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F46B,
+ },
+ [0x1F46C]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F46C,
+ },
+ [0x1F46D]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F46D,
+ },
+ [0x1F46E]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F46E,
+ },
+ [0x1F46F]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F46F,
+ },
+ [0x1F470]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F470,
+ },
+ [0x1F471]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F471,
+ },
+ [0x1F472]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F472,
+ },
+ [0x1F473]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F473,
+ },
+ [0x1F474]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F474,
+ },
+ [0x1F475]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F475,
+ },
+ [0x1F476]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F476,
+ },
+ [0x1F477]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F477,
+ },
+ [0x1F478]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F478,
+ },
+ [0x1F479]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F479,
+ },
+ [0x1F47A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F47A,
+ },
+ [0x1F47B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F47B,
+ },
+ [0x1F47C]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F47C,
+ },
+ [0x1F47D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F47D,
+ },
+ [0x1F47E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F47E,
+ },
+ [0x1F47F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F47F,
+ },
+ [0x1F480]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F480,
+ },
+ [0x1F481]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F481,
+ },
+ [0x1F482]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F482,
+ },
+ [0x1F483]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F483,
+ },
+ [0x1F484]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F484,
+ },
+ [0x1F485]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F485,
+ },
+ [0x1F486]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F486,
+ },
+ [0x1F487]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F487,
+ },
+ [0x1F488]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F488,
+ },
+ [0x1F489]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F489,
+ },
+ [0x1F48A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F48A,
+ },
+ [0x1F48B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F48B,
+ },
+ [0x1F48C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F48C,
+ },
+ [0x1F48D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F48D,
+ },
+ [0x1F48E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F48E,
+ },
+ [0x1F48F]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F48F,
+ },
+ [0x1F490]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F490,
+ },
+ [0x1F491]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F491,
+ },
+ [0x1F492]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F492,
+ },
+ [0x1F493]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F493,
+ },
+ [0x1F494]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F494,
+ },
+ [0x1F495]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F495,
+ },
+ [0x1F496]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F496,
+ },
+ [0x1F497]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F497,
+ },
+ [0x1F498]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F498,
+ },
+ [0x1F499]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F499,
+ },
+ [0x1F49A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F49A,
+ },
+ [0x1F49B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F49B,
+ },
+ [0x1F49C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F49C,
+ },
+ [0x1F49D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F49D,
+ },
+ [0x1F49E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F49E,
+ },
+ [0x1F49F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F49F,
+ },
+ [0x1F4A0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F4A0,
+ },
+ [0x1F4A1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A1,
+ },
+ [0x1F4A2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F4A2,
+ },
+ [0x1F4A3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A3,
+ },
+ [0x1F4A4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F4A4,
+ },
+ [0x1F4A5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A5,
+ },
+ [0x1F4A6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A6,
+ },
+ [0x1F4A7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A7,
+ },
+ [0x1F4A8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A8,
+ },
+ [0x1F4A9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A9,
+ },
+ [0x1F4AA]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F4AA,
+ },
+ [0x1F4AB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4AB,
+ },
+ [0x1F4AC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4AC,
+ },
+ [0x1F4AD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4AD,
+ },
+ [0x1F4AE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4AE,
+ },
+ [0x1F4AF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F4AF,
+ },
+ [0x1F4B0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B0,
+ },
+ [0x1F4B1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F4B1,
+ },
+ [0x1F4B2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F4B2,
+ },
+ [0x1F4B3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B3,
+ },
+ [0x1F4B4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B4,
+ },
+ [0x1F4B5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B5,
+ },
+ [0x1F4B6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B6,
+ },
+ [0x1F4B7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B7,
+ },
+ [0x1F4B8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B8,
+ },
+ [0x1F4B9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B9,
+ },
+ [0x1F4BA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4BA,
+ },
+ [0x1F4BB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4BB,
+ },
+ [0x1F4BC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4BC,
+ },
+ [0x1F4BD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4BD,
+ },
+ [0x1F4BE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4BE,
+ },
+ [0x1F4BF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4BF,
+ },
+ [0x1F4C0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C0,
+ },
+ [0x1F4C1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C1,
+ },
+ [0x1F4C2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C2,
+ },
+ [0x1F4C3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C3,
+ },
+ [0x1F4C4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C4,
+ },
+ [0x1F4C5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C5,
+ },
+ [0x1F4C6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C6,
+ },
+ [0x1F4C7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C7,
+ },
+ [0x1F4C8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C8,
+ },
+ [0x1F4C9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C9,
+ },
+ [0x1F4CA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4CA,
+ },
+ [0x1F4CB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4CB,
+ },
+ [0x1F4CC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4CC,
+ },
+ [0x1F4CD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4CD,
+ },
+ [0x1F4CE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4CE,
+ },
+ [0x1F4CF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4CF,
+ },
+ [0x1F4D0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D0,
+ },
+ [0x1F4D1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D1,
+ },
+ [0x1F4D2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D2,
+ },
+ [0x1F4D3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D3,
+ },
+ [0x1F4D4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D4,
+ },
+ [0x1F4D5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D5,
+ },
+ [0x1F4D6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D6,
+ },
+ [0x1F4D7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D7,
+ },
+ [0x1F4D8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D8,
+ },
+ [0x1F4D9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D9,
+ },
+ [0x1F4DA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4DA,
+ },
+ [0x1F4DB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4DB,
+ },
+ [0x1F4DC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4DC,
+ },
+ [0x1F4DD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4DD,
+ },
+ [0x1F4DE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4DE,
+ },
+ [0x1F4DF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4DF,
+ },
+ [0x1F4E0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E0,
+ },
+ [0x1F4E1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E1,
+ },
+ [0x1F4E2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E2,
+ },
+ [0x1F4E3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E3,
+ },
+ [0x1F4E4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E4,
+ },
+ [0x1F4E5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E5,
+ },
+ [0x1F4E6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E6,
+ },
+ [0x1F4E7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E7,
+ },
+ [0x1F4E8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E8,
+ },
+ [0x1F4E9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E9,
+ },
+ [0x1F4EA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4EA,
+ },
+ [0x1F4EB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4EB,
+ },
+ [0x1F4EC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4EC,
+ },
+ [0x1F4ED]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4ED,
+ },
+ [0x1F4EE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4EE,
+ },
+ [0x1F4EF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4EF,
+ },
+ [0x1F4F0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F0,
+ },
+ [0x1F4F1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F1,
+ },
+ [0x1F4F2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F2,
+ },
+ [0x1F4F3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F3,
+ },
+ [0x1F4F4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F4,
+ },
+ [0x1F4F5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F5,
+ },
+ [0x1F4F6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F6,
+ },
+ [0x1F4F7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F7,
+ },
+ [0x1F4F8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F8,
+ },
+ [0x1F4F9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F9,
+ },
+ [0x1F4FA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4FA,
+ },
+ [0x1F4FB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4FB,
+ },
+ [0x1F4FC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4FC,
+ },
+ [0x1F4FD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4FD,
+ },
+ [0x1F4FE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4FE,
+ },
+ [0x1F4FF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4FF,
+ },
+ [0x1F500]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F500,
+ },
+ [0x1F501]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F501,
+ },
+ [0x1F502]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F502,
+ },
+ [0x1F503]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F503,
+ },
+ [0x1F504]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F504,
+ },
+ [0x1F505]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F505,
+ },
+ [0x1F506]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F506,
+ },
+ [0x1F507]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F507,
+ },
+ [0x1F508]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F508,
+ },
+ [0x1F509]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F509,
+ },
+ [0x1F50A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F50A,
+ },
+ [0x1F50B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F50B,
+ },
+ [0x1F50C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F50C,
+ },
+ [0x1F50D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F50D,
+ },
+ [0x1F50E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F50E,
+ },
+ [0x1F50F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F50F,
+ },
+ [0x1F510]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F510,
+ },
+ [0x1F511]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F511,
+ },
+ [0x1F512]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F512,
+ },
+ [0x1F513]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F513,
+ },
+ [0x1F514]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F514,
+ },
+ [0x1F515]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F515,
+ },
+ [0x1F516]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F516,
+ },
+ [0x1F517]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F517,
+ },
+ [0x1F518]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F518,
+ },
+ [0x1F519]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F519,
+ },
+ [0x1F51A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F51A,
+ },
+ [0x1F51B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F51B,
+ },
+ [0x1F51C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F51C,
+ },
+ [0x1F51D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F51D,
+ },
+ [0x1F51E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F51E,
+ },
+ [0x1F51F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F51F,
+ },
+ [0x1F520]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F520,
+ },
+ [0x1F521]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F521,
+ },
+ [0x1F522]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F522,
+ },
+ [0x1F523]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F523,
+ },
+ [0x1F524]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F524,
+ },
+ [0x1F525]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F525,
+ },
+ [0x1F526]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F526,
+ },
+ [0x1F527]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F527,
+ },
+ [0x1F528]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F528,
+ },
+ [0x1F529]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F529,
+ },
+ [0x1F52A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F52A,
+ },
+ [0x1F52B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F52B,
+ },
+ [0x1F52C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F52C,
+ },
+ [0x1F52D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F52D,
+ },
+ [0x1F52E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F52E,
+ },
+ [0x1F52F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F52F,
+ },
+ [0x1F530]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F530,
+ },
+ [0x1F531]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F531,
+ },
+ [0x1F532]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F532,
+ },
+ [0x1F533]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F533,
+ },
+ [0x1F534]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F534,
+ },
+ [0x1F535]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F535,
+ },
+ [0x1F536]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F536,
+ },
+ [0x1F537]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F537,
+ },
+ [0x1F538]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F538,
+ },
+ [0x1F539]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F539,
+ },
+ [0x1F53A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F53A,
+ },
+ [0x1F53B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F53B,
+ },
+ [0x1F53C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F53C,
+ },
+ [0x1F53D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F53D,
+ },
+ [0x1F53E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F53E,
+ },
+ [0x1F53F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F53F,
+ },
+ [0x1F540]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F540,
+ },
+ [0x1F541]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F541,
+ },
+ [0x1F542]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F542,
+ },
+ [0x1F543]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F543,
+ },
+ [0x1F544]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F544,
+ },
+ [0x1F545]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F545,
+ },
+ [0x1F546]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F546,
+ },
+ [0x1F547]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F547,
+ },
+ [0x1F548]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F548,
+ },
+ [0x1F549]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F549,
+ },
+ [0x1F54A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F54A,
+ },
+ [0x1F54B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F54B,
+ },
+ [0x1F54C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F54C,
+ },
+ [0x1F54D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F54D,
+ },
+ [0x1F54E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F54E,
+ },
+ [0x1F54F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F54F,
+ },
+ [0x1F550]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F550,
+ },
+ [0x1F551]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F551,
+ },
+ [0x1F552]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F552,
+ },
+ [0x1F553]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F553,
+ },
+ [0x1F554]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F554,
+ },
+ [0x1F555]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F555,
+ },
+ [0x1F556]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F556,
+ },
+ [0x1F557]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F557,
+ },
+ [0x1F558]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F558,
+ },
+ [0x1F559]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F559,
+ },
+ [0x1F55A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F55A,
+ },
+ [0x1F55B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F55B,
+ },
+ [0x1F55C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F55C,
+ },
+ [0x1F55D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F55D,
+ },
+ [0x1F55E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F55E,
+ },
+ [0x1F55F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F55F,
+ },
+ [0x1F560]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F560,
+ },
+ [0x1F561]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F561,
+ },
+ [0x1F562]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F562,
+ },
+ [0x1F563]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F563,
+ },
+ [0x1F564]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F564,
+ },
+ [0x1F565]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F565,
+ },
+ [0x1F566]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F566,
+ },
+ [0x1F567]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F567,
+ },
+ [0x1F568]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F568,
+ },
+ [0x1F569]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F569,
+ },
+ [0x1F56A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F56A,
+ },
+ [0x1F56B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F56B,
+ },
+ [0x1F56C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F56C,
+ },
+ [0x1F56D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F56D,
+ },
+ [0x1F56E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F56E,
+ },
+ [0x1F56F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F56F,
+ },
+ [0x1F570]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F570,
+ },
+ [0x1F571]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F571,
+ },
+ [0x1F572]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F572,
+ },
+ [0x1F573]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F573,
+ },
+ [0x1F574]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F574,
+ },
+ [0x1F575]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F575,
+ },
+ [0x1F576]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F576,
+ },
+ [0x1F577]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F577,
+ },
+ [0x1F578]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F578,
+ },
+ [0x1F579]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F579,
+ },
+ [0x1F57A]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F57A,
+ },
+ [0x1F57B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F57B,
+ },
+ [0x1F57C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F57C,
+ },
+ [0x1F57D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F57D,
+ },
+ [0x1F57E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F57E,
+ },
+ [0x1F57F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F57F,
+ },
+ [0x1F580]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F580,
+ },
+ [0x1F581]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F581,
+ },
+ [0x1F582]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F582,
+ },
+ [0x1F583]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F583,
+ },
+ [0x1F584]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F584,
+ },
+ [0x1F585]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F585,
+ },
+ [0x1F586]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F586,
+ },
+ [0x1F587]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F587,
+ },
+ [0x1F588]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F588,
+ },
+ [0x1F589]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F589,
+ },
+ [0x1F58A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F58A,
+ },
+ [0x1F58B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F58B,
+ },
+ [0x1F58C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F58C,
+ },
+ [0x1F58D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F58D,
+ },
+ [0x1F58E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F58E,
+ },
+ [0x1F58F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F58F,
+ },
+ [0x1F590]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F590,
+ },
+ [0x1F591]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F591,
+ },
+ [0x1F592]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F592,
+ },
+ [0x1F593]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F593,
+ },
+ [0x1F594]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F594,
+ },
+ [0x1F595]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F595,
+ },
+ [0x1F596]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F596,
+ },
+ [0x1F597]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F597,
+ },
+ [0x1F598]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F598,
+ },
+ [0x1F599]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F599,
+ },
+ [0x1F59A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F59A,
+ },
+ [0x1F59B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F59B,
+ },
+ [0x1F59C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F59C,
+ },
+ [0x1F59D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F59D,
+ },
+ [0x1F59E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F59E,
+ },
+ [0x1F59F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F59F,
+ },
+ [0x1F5A0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5A0,
+ },
+ [0x1F5A1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5A1,
+ },
+ [0x1F5A2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5A2,
+ },
+ [0x1F5A3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5A3,
+ },
+ [0x1F5A4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5A4,
+ },
+ [0x1F5A5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5A5,
+ },
+ [0x1F5A6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5A6,
+ },
+ [0x1F5A7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5A7,
+ },
+ [0x1F5A8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5A8,
+ },
+ [0x1F5A9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5A9,
+ },
+ [0x1F5AA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5AA,
+ },
+ [0x1F5AB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5AB,
+ },
+ [0x1F5AC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5AC,
+ },
+ [0x1F5AD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5AD,
+ },
+ [0x1F5AE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5AE,
+ },
+ [0x1F5AF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5AF,
+ },
+ [0x1F5B0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5B0,
+ },
+ [0x1F5B1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5B1,
+ },
+ [0x1F5B2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5B2,
+ },
+ [0x1F5B3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5B3,
+ },
+ [0x1F5B4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5B4,
+ },
+ [0x1F5B5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5B5,
+ },
+ [0x1F5B6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5B6,
+ },
+ [0x1F5B7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5B7,
+ },
+ [0x1F5B8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5B8,
+ },
+ [0x1F5B9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5B9,
+ },
+ [0x1F5BA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5BA,
+ },
+ [0x1F5BB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5BB,
+ },
+ [0x1F5BC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5BC,
+ },
+ [0x1F5BD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5BD,
+ },
+ [0x1F5BE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5BE,
+ },
+ [0x1F5BF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5BF,
+ },
+ [0x1F5C0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5C0,
+ },
+ [0x1F5C1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5C1,
+ },
+ [0x1F5C2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5C2,
+ },
+ [0x1F5C3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5C3,
+ },
+ [0x1F5C4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5C4,
+ },
+ [0x1F5C5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5C5,
+ },
+ [0x1F5C6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5C6,
+ },
+ [0x1F5C7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5C7,
+ },
+ [0x1F5C8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5C8,
+ },
+ [0x1F5C9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5C9,
+ },
+ [0x1F5CA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5CA,
+ },
+ [0x1F5CB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5CB,
+ },
+ [0x1F5CC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5CC,
+ },
+ [0x1F5CD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5CD,
+ },
+ [0x1F5CE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5CE,
+ },
+ [0x1F5CF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5CF,
+ },
+ [0x1F5D0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5D0,
+ },
+ [0x1F5D1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5D1,
+ },
+ [0x1F5D2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5D2,
+ },
+ [0x1F5D3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5D3,
+ },
+ [0x1F5D4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5D4,
+ },
+ [0x1F5D5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5D5,
+ },
+ [0x1F5D6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5D6,
+ },
+ [0x1F5D7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5D7,
+ },
+ [0x1F5D8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5D8,
+ },
+ [0x1F5D9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5D9,
+ },
+ [0x1F5DA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5DA,
+ },
+ [0x1F5DB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5DB,
+ },
+ [0x1F5DC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5DC,
+ },
+ [0x1F5DD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5DD,
+ },
+ [0x1F5DE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5DE,
+ },
+ [0x1F5DF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5DF,
+ },
+ [0x1F5E0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5E0,
+ },
+ [0x1F5E1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5E1,
+ },
+ [0x1F5E2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5E2,
+ },
+ [0x1F5E3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5E3,
+ },
+ [0x1F5E4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5E4,
+ },
+ [0x1F5E5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5E5,
+ },
+ [0x1F5E6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5E6,
+ },
+ [0x1F5E7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5E7,
+ },
+ [0x1F5E8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5E8,
+ },
+ [0x1F5E9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5E9,
+ },
+ [0x1F5EA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5EA,
+ },
+ [0x1F5EB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5EB,
+ },
+ [0x1F5EC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5EC,
+ },
+ [0x1F5ED]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5ED,
+ },
+ [0x1F5EE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5EE,
+ },
+ [0x1F5EF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5EF,
+ },
+ [0x1F5F0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5F0,
+ },
+ [0x1F5F1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5F1,
+ },
+ [0x1F5F2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5F2,
+ },
+ [0x1F5F3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5F3,
+ },
+ [0x1F5F4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5F4,
+ },
+ [0x1F5F5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5F5,
+ },
+ [0x1F5F6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5F6,
+ },
+ [0x1F5F7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5F7,
+ },
+ [0x1F5F8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5F8,
+ },
+ [0x1F5F9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F5F9,
+ },
+ [0x1F5FA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5FA,
+ },
+ [0x1F5FB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5FB,
+ },
+ [0x1F5FC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5FC,
+ },
+ [0x1F5FD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5FD,
+ },
+ [0x1F5FE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5FE,
+ },
+ [0x1F5FF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5FF,
+ },
+ [0x1F600]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F600,
+ },
+ [0x1F601]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F601,
+ },
+ [0x1F602]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F602,
+ },
+ [0x1F603]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F603,
+ },
+ [0x1F604]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F604,
+ },
+ [0x1F605]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F605,
+ },
+ [0x1F606]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F606,
+ },
+ [0x1F607]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F607,
+ },
+ [0x1F608]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F608,
+ },
+ [0x1F609]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F609,
+ },
+ [0x1F60A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F60A,
+ },
+ [0x1F60B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F60B,
+ },
+ [0x1F60C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F60C,
+ },
+ [0x1F60D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F60D,
+ },
+ [0x1F60E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F60E,
+ },
+ [0x1F60F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F60F,
+ },
+ [0x1F610]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F610,
+ },
+ [0x1F611]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F611,
+ },
+ [0x1F612]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F612,
+ },
+ [0x1F613]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F613,
+ },
+ [0x1F614]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F614,
+ },
+ [0x1F615]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F615,
+ },
+ [0x1F616]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F616,
+ },
+ [0x1F617]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F617,
+ },
+ [0x1F618]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F618,
+ },
+ [0x1F619]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F619,
+ },
+ [0x1F61A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F61A,
+ },
+ [0x1F61B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F61B,
+ },
+ [0x1F61C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F61C,
+ },
+ [0x1F61D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F61D,
+ },
+ [0x1F61E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F61E,
+ },
+ [0x1F61F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F61F,
+ },
+ [0x1F620]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F620,
+ },
+ [0x1F621]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F621,
+ },
+ [0x1F622]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F622,
+ },
+ [0x1F623]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F623,
+ },
+ [0x1F624]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F624,
+ },
+ [0x1F625]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F625,
+ },
+ [0x1F626]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F626,
+ },
+ [0x1F627]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F627,
+ },
+ [0x1F628]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F628,
+ },
+ [0x1F629]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F629,
+ },
+ [0x1F62A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F62A,
+ },
+ [0x1F62B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F62B,
+ },
+ [0x1F62C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F62C,
+ },
+ [0x1F62D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F62D,
+ },
+ [0x1F62E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F62E,
+ },
+ [0x1F62F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F62F,
+ },
+ [0x1F630]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F630,
+ },
+ [0x1F631]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F631,
+ },
+ [0x1F632]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F632,
+ },
+ [0x1F633]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F633,
+ },
+ [0x1F634]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F634,
+ },
+ [0x1F635]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F635,
+ },
+ [0x1F636]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F636,
+ },
+ [0x1F637]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F637,
+ },
+ [0x1F638]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F638,
+ },
+ [0x1F639]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F639,
+ },
+ [0x1F63A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F63A,
+ },
+ [0x1F63B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F63B,
+ },
+ [0x1F63C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F63C,
+ },
+ [0x1F63D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F63D,
+ },
+ [0x1F63E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F63E,
+ },
+ [0x1F63F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F63F,
+ },
+ [0x1F640]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F640,
+ },
+ [0x1F641]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F641,
+ },
+ [0x1F642]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F642,
+ },
+ [0x1F643]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F643,
+ },
+ [0x1F644]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F644,
+ },
+ [0x1F645]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F645,
+ },
+ [0x1F646]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F646,
+ },
+ [0x1F647]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F647,
+ },
+ [0x1F648]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F648,
+ },
+ [0x1F649]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F649,
+ },
+ [0x1F64A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F64A,
+ },
+ [0x1F64B]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F64B,
+ },
+ [0x1F64C]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F64C,
+ },
+ [0x1F64D]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F64D,
+ },
+ [0x1F64E]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F64E,
+ },
+ [0x1F64F]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F64F,
+ },
+ [0x1F650]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F650,
+ },
+ [0x1F651]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F651,
+ },
+ [0x1F652]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F652,
+ },
+ [0x1F653]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F653,
+ },
+ [0x1F654]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F654,
+ },
+ [0x1F655]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F655,
+ },
+ [0x1F656]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F656,
+ },
+ [0x1F657]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F657,
+ },
+ [0x1F658]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F658,
+ },
+ [0x1F659]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F659,
+ },
+ [0x1F65A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F65A,
+ },
+ [0x1F65B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F65B,
+ },
+ [0x1F65C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F65C,
+ },
+ [0x1F65D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F65D,
+ },
+ [0x1F65E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F65E,
+ },
+ [0x1F65F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F65F,
+ },
+ [0x1F660]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F660,
+ },
+ [0x1F661]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F661,
+ },
+ [0x1F662]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F662,
+ },
+ [0x1F663]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F663,
+ },
+ [0x1F664]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F664,
+ },
+ [0x1F665]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F665,
+ },
+ [0x1F666]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F666,
+ },
+ [0x1F667]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F667,
+ },
+ [0x1F668]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F668,
+ },
+ [0x1F669]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F669,
+ },
+ [0x1F66A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F66A,
+ },
+ [0x1F66B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F66B,
+ },
+ [0x1F66C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F66C,
+ },
+ [0x1F66D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F66D,
+ },
+ [0x1F66E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F66E,
+ },
+ [0x1F66F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F66F,
+ },
+ [0x1F670]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F670,
+ },
+ [0x1F671]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F671,
+ },
+ [0x1F672]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F672,
+ },
+ [0x1F673]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F673,
+ },
+ [0x1F674]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F674,
+ },
+ [0x1F675]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F675,
+ },
+ [0x1F676]={
+ category="so",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x1F676,
+ },
+ [0x1F677]={
+ category="so",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x1F677,
+ },
+ [0x1F678]={
+ category="so",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x1F678,
+ },
+ [0x1F679]={
+ category="so",
+ direction="on",
+ linebreak="ns",
+ unicodeslot=0x1F679,
+ },
+ [0x1F67A]={
+ category="so",
+ direction="on",
+ linebreak="ns",
+ unicodeslot=0x1F67A,
+ },
+ [0x1F67B]={
+ category="so",
+ direction="on",
+ linebreak="ns",
+ unicodeslot=0x1F67B,
+ },
+ [0x1F67C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F67C,
+ },
+ [0x1F67D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F67D,
+ },
+ [0x1F67E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F67E,
+ },
+ [0x1F67F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F67F,
+ },
+ [0x1F680]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F680,
+ },
+ [0x1F681]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F681,
+ },
+ [0x1F682]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F682,
+ },
+ [0x1F683]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F683,
+ },
+ [0x1F684]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F684,
+ },
+ [0x1F685]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F685,
+ },
+ [0x1F686]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F686,
+ },
+ [0x1F687]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F687,
+ },
+ [0x1F688]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F688,
+ },
+ [0x1F689]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F689,
+ },
+ [0x1F68A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F68A,
+ },
+ [0x1F68B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F68B,
+ },
+ [0x1F68C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F68C,
+ },
+ [0x1F68D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F68D,
+ },
+ [0x1F68E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F68E,
+ },
+ [0x1F68F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F68F,
+ },
+ [0x1F690]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F690,
+ },
+ [0x1F691]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F691,
+ },
+ [0x1F692]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F692,
+ },
+ [0x1F693]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F693,
+ },
+ [0x1F694]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F694,
+ },
+ [0x1F695]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F695,
+ },
+ [0x1F696]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F696,
+ },
+ [0x1F697]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F697,
+ },
+ [0x1F698]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F698,
+ },
+ [0x1F699]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F699,
+ },
+ [0x1F69A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F69A,
+ },
+ [0x1F69B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F69B,
+ },
+ [0x1F69C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F69C,
+ },
+ [0x1F69D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F69D,
+ },
+ [0x1F69E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F69E,
+ },
+ [0x1F69F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F69F,
+ },
+ [0x1F6A0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A0,
+ },
+ [0x1F6A1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A1,
+ },
+ [0x1F6A2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A2,
+ },
+ [0x1F6A3]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F6A3,
+ },
+ [0x1F6A4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A4,
+ },
+ [0x1F6A5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A5,
+ },
+ [0x1F6A6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A6,
+ },
+ [0x1F6A7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A7,
+ },
+ [0x1F6A8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A8,
+ },
+ [0x1F6A9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A9,
+ },
+ [0x1F6AA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6AA,
+ },
+ [0x1F6AB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6AB,
+ },
+ [0x1F6AC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6AC,
+ },
+ [0x1F6AD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6AD,
+ },
+ [0x1F6AE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6AE,
+ },
+ [0x1F6AF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6AF,
+ },
+ [0x1F6B0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B0,
+ },
+ [0x1F6B1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B1,
+ },
+ [0x1F6B2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B2,
+ },
+ [0x1F6B3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B3,
+ },
+ [0x1F6B4]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F6B4,
+ },
+ [0x1F6B5]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F6B5,
+ },
+ [0x1F6B6]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F6B6,
+ },
+ [0x1F6B7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B7,
+ },
+ [0x1F6B8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B8,
+ },
+ [0x1F6B9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B9,
+ },
+ [0x1F6BA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6BA,
+ },
+ [0x1F6BB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6BB,
+ },
+ [0x1F6BC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6BC,
+ },
+ [0x1F6BD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6BD,
+ },
+ [0x1F6BE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6BE,
+ },
+ [0x1F6BF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6BF,
+ },
+ [0x1F6C0]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F6C0,
+ },
+ [0x1F6C1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C1,
+ },
+ [0x1F6C2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C2,
+ },
+ [0x1F6C3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C3,
+ },
+ [0x1F6C4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C4,
+ },
+ [0x1F6C5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C5,
+ },
+ [0x1F6C6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C6,
+ },
+ [0x1F6C7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C7,
+ },
+ [0x1F6C8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C8,
+ },
+ [0x1F6C9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C9,
+ },
+ [0x1F6CA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6CA,
+ },
+ [0x1F6CB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6CB,
+ },
+ [0x1F6CC]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F6CC,
+ },
+ [0x1F6CD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6CD,
+ },
+ [0x1F6CE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6CE,
+ },
+ [0x1F6CF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6CF,
+ },
+ [0x1F6D0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6D0,
+ },
+ [0x1F6D1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6D1,
+ },
+ [0x1F6D2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6D2,
+ },
+ [0x1F6D3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6D3,
+ },
+ [0x1F6D4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6D4,
+ },
+ [0x1F6D5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6D5,
+ },
+ [0x1F6E0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6E0,
+ },
+ [0x1F6E1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6E1,
+ },
+ [0x1F6E2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6E2,
+ },
+ [0x1F6E3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6E3,
+ },
+ [0x1F6E4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6E4,
+ },
+ [0x1F6E5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6E5,
+ },
+ [0x1F6E6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6E6,
+ },
+ [0x1F6E7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6E7,
+ },
+ [0x1F6E8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6E8,
+ },
+ [0x1F6E9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6E9,
+ },
+ [0x1F6EA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6EA,
+ },
+ [0x1F6EB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6EB,
+ },
+ [0x1F6EC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6EC,
+ },
+ [0x1F6F0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6F0,
+ },
+ [0x1F6F1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6F1,
+ },
+ [0x1F6F2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6F2,
+ },
+ [0x1F6F3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6F3,
+ },
+ [0x1F6F4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6F4,
+ },
+ [0x1F6F5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6F5,
+ },
+ [0x1F6F6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6F6,
+ },
+ [0x1F6F7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6F7,
+ },
+ [0x1F6F8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6F8,
+ },
+ [0x1F6F9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6F9,
+ },
+ [0x1F6FA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6FA,
+ },
+ [0x1F700]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F700,
+ },
+ [0x1F701]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F701,
+ },
+ [0x1F702]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F702,
+ },
+ [0x1F703]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F703,
+ },
+ [0x1F704]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F704,
+ },
+ [0x1F705]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F705,
+ },
+ [0x1F706]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F706,
+ },
+ [0x1F707]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F707,
+ },
+ [0x1F708]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F708,
+ },
+ [0x1F709]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F709,
+ },
+ [0x1F70A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F70A,
+ },
+ [0x1F70B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F70B,
+ },
+ [0x1F70C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F70C,
+ },
+ [0x1F70D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F70D,
+ },
+ [0x1F70E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F70E,
+ },
+ [0x1F70F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F70F,
+ },
+ [0x1F710]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F710,
+ },
+ [0x1F711]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F711,
+ },
+ [0x1F712]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F712,
+ },
+ [0x1F713]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F713,
+ },
+ [0x1F714]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F714,
+ },
+ [0x1F715]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F715,
+ },
+ [0x1F716]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F716,
+ },
+ [0x1F717]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F717,
+ },
+ [0x1F718]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F718,
+ },
+ [0x1F719]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F719,
+ },
+ [0x1F71A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F71A,
+ },
+ [0x1F71B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F71B,
+ },
+ [0x1F71C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F71C,
+ },
+ [0x1F71D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F71D,
+ },
+ [0x1F71E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F71E,
+ },
+ [0x1F71F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F71F,
+ },
+ [0x1F720]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F720,
+ },
+ [0x1F721]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F721,
+ },
+ [0x1F722]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F722,
+ },
+ [0x1F723]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F723,
+ },
+ [0x1F724]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F724,
+ },
+ [0x1F725]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F725,
+ },
+ [0x1F726]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F726,
+ },
+ [0x1F727]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F727,
+ },
+ [0x1F728]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F728,
+ },
+ [0x1F729]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F729,
+ },
+ [0x1F72A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F72A,
+ },
+ [0x1F72B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F72B,
+ },
+ [0x1F72C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F72C,
+ },
+ [0x1F72D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F72D,
+ },
+ [0x1F72E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F72E,
+ },
+ [0x1F72F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F72F,
+ },
+ [0x1F730]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F730,
+ },
+ [0x1F731]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F731,
+ },
+ [0x1F732]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F732,
+ },
+ [0x1F733]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F733,
+ },
+ [0x1F734]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F734,
+ },
+ [0x1F735]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F735,
+ },
+ [0x1F736]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F736,
+ },
+ [0x1F737]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F737,
+ },
+ [0x1F738]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F738,
+ },
+ [0x1F739]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F739,
+ },
+ [0x1F73A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F73A,
+ },
+ [0x1F73B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F73B,
+ },
+ [0x1F73C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F73C,
+ },
+ [0x1F73D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F73D,
+ },
+ [0x1F73E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F73E,
+ },
+ [0x1F73F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F73F,
+ },
+ [0x1F740]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F740,
+ },
+ [0x1F741]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F741,
+ },
+ [0x1F742]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F742,
+ },
+ [0x1F743]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F743,
+ },
+ [0x1F744]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F744,
+ },
+ [0x1F745]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F745,
+ },
+ [0x1F746]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F746,
+ },
+ [0x1F747]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F747,
+ },
+ [0x1F748]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F748,
+ },
+ [0x1F749]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F749,
+ },
+ [0x1F74A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F74A,
+ },
+ [0x1F74B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F74B,
+ },
+ [0x1F74C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F74C,
+ },
+ [0x1F74D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F74D,
+ },
+ [0x1F74E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F74E,
+ },
+ [0x1F74F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F74F,
+ },
+ [0x1F750]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F750,
+ },
+ [0x1F751]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F751,
+ },
+ [0x1F752]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F752,
+ },
+ [0x1F753]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F753,
+ },
+ [0x1F754]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F754,
+ },
+ [0x1F755]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F755,
+ },
+ [0x1F756]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F756,
+ },
+ [0x1F757]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F757,
+ },
+ [0x1F758]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F758,
+ },
+ [0x1F759]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F759,
+ },
+ [0x1F75A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F75A,
+ },
+ [0x1F75B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F75B,
+ },
+ [0x1F75C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F75C,
+ },
+ [0x1F75D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F75D,
+ },
+ [0x1F75E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F75E,
+ },
+ [0x1F75F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F75F,
+ },
+ [0x1F760]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F760,
+ },
+ [0x1F761]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F761,
+ },
+ [0x1F762]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F762,
+ },
+ [0x1F763]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F763,
+ },
+ [0x1F764]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F764,
+ },
+ [0x1F765]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F765,
+ },
+ [0x1F766]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F766,
+ },
+ [0x1F767]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F767,
+ },
+ [0x1F768]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F768,
+ },
+ [0x1F769]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F769,
+ },
+ [0x1F76A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F76A,
+ },
+ [0x1F76B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F76B,
+ },
+ [0x1F76C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F76C,
+ },
+ [0x1F76D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F76D,
+ },
+ [0x1F76E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F76E,
+ },
+ [0x1F76F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F76F,
+ },
+ [0x1F770]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F770,
+ },
+ [0x1F771]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F771,
+ },
+ [0x1F772]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F772,
+ },
+ [0x1F773]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F773,
+ },
+ [0x1F780]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F780,
+ },
+ [0x1F781]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F781,
+ },
+ [0x1F782]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F782,
+ },
+ [0x1F783]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F783,
+ },
+ [0x1F784]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F784,
+ },
+ [0x1F785]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F785,
+ },
+ [0x1F786]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F786,
+ },
+ [0x1F787]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F787,
+ },
+ [0x1F788]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F788,
+ },
+ [0x1F789]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F789,
+ },
+ [0x1F78A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F78A,
+ },
+ [0x1F78B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F78B,
+ },
+ [0x1F78C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F78C,
+ },
+ [0x1F78D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F78D,
+ },
+ [0x1F78E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F78E,
+ },
+ [0x1F78F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F78F,
+ },
+ [0x1F790]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F790,
+ },
+ [0x1F791]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F791,
+ },
+ [0x1F792]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F792,
+ },
+ [0x1F793]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F793,
+ },
+ [0x1F794]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F794,
+ },
+ [0x1F795]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F795,
+ },
+ [0x1F796]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F796,
+ },
+ [0x1F797]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F797,
+ },
+ [0x1F798]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F798,
+ },
+ [0x1F799]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F799,
+ },
+ [0x1F79A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F79A,
+ },
+ [0x1F79B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F79B,
+ },
+ [0x1F79C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F79C,
+ },
+ [0x1F79D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F79D,
+ },
+ [0x1F79E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F79E,
+ },
+ [0x1F79F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F79F,
+ },
+ [0x1F7A0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7A0,
+ },
+ [0x1F7A1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7A1,
+ },
+ [0x1F7A2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7A2,
+ },
+ [0x1F7A3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7A3,
+ },
+ [0x1F7A4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7A4,
+ },
+ [0x1F7A5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7A5,
+ },
+ [0x1F7A6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7A6,
+ },
+ [0x1F7A7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7A7,
+ },
+ [0x1F7A8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7A8,
+ },
+ [0x1F7A9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7A9,
+ },
+ [0x1F7AA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7AA,
+ },
+ [0x1F7AB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7AB,
+ },
+ [0x1F7AC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7AC,
+ },
+ [0x1F7AD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7AD,
+ },
+ [0x1F7AE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7AE,
+ },
+ [0x1F7AF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7AF,
+ },
+ [0x1F7B0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7B0,
+ },
+ [0x1F7B1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7B1,
+ },
+ [0x1F7B2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7B2,
+ },
+ [0x1F7B3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7B3,
+ },
+ [0x1F7B4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7B4,
+ },
+ [0x1F7B5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7B5,
+ },
+ [0x1F7B6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7B6,
+ },
+ [0x1F7B7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7B7,
+ },
+ [0x1F7B8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7B8,
+ },
+ [0x1F7B9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7B9,
+ },
+ [0x1F7BA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7BA,
+ },
+ [0x1F7BB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7BB,
+ },
+ [0x1F7BC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7BC,
+ },
+ [0x1F7BD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7BD,
+ },
+ [0x1F7BE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7BE,
+ },
+ [0x1F7BF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7BF,
+ },
+ [0x1F7C0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7C0,
+ },
+ [0x1F7C1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7C1,
+ },
+ [0x1F7C2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7C2,
+ },
+ [0x1F7C3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7C3,
+ },
+ [0x1F7C4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7C4,
+ },
+ [0x1F7C5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7C5,
+ },
+ [0x1F7C6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7C6,
+ },
+ [0x1F7C7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7C7,
+ },
+ [0x1F7C8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7C8,
+ },
+ [0x1F7C9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7C9,
+ },
+ [0x1F7CA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7CA,
+ },
+ [0x1F7CB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7CB,
+ },
+ [0x1F7CC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7CC,
+ },
+ [0x1F7CD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7CD,
+ },
+ [0x1F7CE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7CE,
+ },
+ [0x1F7CF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7CF,
+ },
+ [0x1F7D0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7D0,
+ },
+ [0x1F7D1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7D1,
+ },
+ [0x1F7D2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7D2,
+ },
+ [0x1F7D3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7D3,
+ },
+ [0x1F7D4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F7D4,
+ },
+ [0x1F7D5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7D5,
+ },
+ [0x1F7D6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7D6,
+ },
+ [0x1F7D7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7D7,
+ },
+ [0x1F7D8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7D8,
+ },
+ [0x1F7E0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7E0,
+ },
+ [0x1F7E1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7E1,
+ },
+ [0x1F7E2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7E2,
+ },
+ [0x1F7E3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7E3,
+ },
+ [0x1F7E4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7E4,
+ },
+ [0x1F7E5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7E5,
+ },
+ [0x1F7E6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7E6,
+ },
+ [0x1F7E7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7E7,
+ },
+ [0x1F7E8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7E8,
+ },
+ [0x1F7E9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7E9,
+ },
+ [0x1F7EA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7EA,
+ },
+ [0x1F7EB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F7EB,
+ },
+ [0x1F800]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F800,
+ },
+ [0x1F801]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F801,
+ },
+ [0x1F802]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F802,
+ },
+ [0x1F803]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F803,
+ },
+ [0x1F804]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F804,
+ },
+ [0x1F805]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F805,
+ },
+ [0x1F806]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F806,
+ },
+ [0x1F807]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F807,
+ },
+ [0x1F808]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F808,
+ },
+ [0x1F809]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F809,
+ },
+ [0x1F80A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F80A,
+ },
+ [0x1F80B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F80B,
+ },
+ [0x1F810]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F810,
+ },
+ [0x1F811]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F811,
+ },
+ [0x1F812]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F812,
+ },
+ [0x1F813]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F813,
+ },
+ [0x1F814]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F814,
+ },
+ [0x1F815]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F815,
+ },
+ [0x1F816]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F816,
+ },
+ [0x1F817]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F817,
+ },
+ [0x1F818]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F818,
+ },
+ [0x1F819]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F819,
+ },
+ [0x1F81A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F81A,
+ },
+ [0x1F81B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F81B,
+ },
+ [0x1F81C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F81C,
+ },
+ [0x1F81D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F81D,
+ },
+ [0x1F81E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F81E,
+ },
+ [0x1F81F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F81F,
+ },
+ [0x1F820]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F820,
+ },
+ [0x1F821]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F821,
+ },
+ [0x1F822]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F822,
+ },
+ [0x1F823]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F823,
+ },
+ [0x1F824]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F824,
+ },
+ [0x1F825]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F825,
+ },
+ [0x1F826]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F826,
+ },
+ [0x1F827]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F827,
+ },
+ [0x1F828]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F828,
+ },
+ [0x1F829]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F829,
+ },
+ [0x1F82A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F82A,
+ },
+ [0x1F82B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F82B,
+ },
+ [0x1F82C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F82C,
+ },
+ [0x1F82D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F82D,
+ },
+ [0x1F82E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F82E,
+ },
+ [0x1F82F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F82F,
+ },
+ [0x1F830]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F830,
+ },
+ [0x1F831]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F831,
+ },
+ [0x1F832]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F832,
+ },
+ [0x1F833]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F833,
+ },
+ [0x1F834]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F834,
+ },
+ [0x1F835]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F835,
+ },
+ [0x1F836]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F836,
+ },
+ [0x1F837]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F837,
+ },
+ [0x1F838]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F838,
+ },
+ [0x1F839]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F839,
+ },
+ [0x1F83A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F83A,
+ },
+ [0x1F83B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F83B,
+ },
+ [0x1F83C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F83C,
+ },
+ [0x1F83D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F83D,
+ },
+ [0x1F83E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F83E,
+ },
+ [0x1F83F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F83F,
+ },
+ [0x1F840]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F840,
+ },
+ [0x1F841]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F841,
+ },
+ [0x1F842]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F842,
+ },
+ [0x1F843]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F843,
+ },
+ [0x1F844]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F844,
+ },
+ [0x1F845]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F845,
+ },
+ [0x1F846]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F846,
+ },
+ [0x1F847]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F847,
+ },
+ [0x1F850]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F850,
+ },
+ [0x1F851]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F851,
+ },
+ [0x1F852]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F852,
+ },
+ [0x1F853]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F853,
+ },
+ [0x1F854]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F854,
+ },
+ [0x1F855]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F855,
+ },
+ [0x1F856]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F856,
+ },
+ [0x1F857]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F857,
+ },
+ [0x1F858]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F858,
+ },
+ [0x1F859]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F859,
+ },
+ [0x1F860]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F860,
+ },
+ [0x1F861]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F861,
+ },
+ [0x1F862]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F862,
+ },
+ [0x1F863]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F863,
+ },
+ [0x1F864]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F864,
+ },
+ [0x1F865]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F865,
+ },
+ [0x1F866]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F866,
+ },
+ [0x1F867]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F867,
+ },
+ [0x1F868]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F868,
+ },
+ [0x1F869]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F869,
+ },
+ [0x1F86A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F86A,
+ },
+ [0x1F86B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F86B,
+ },
+ [0x1F86C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F86C,
+ },
+ [0x1F86D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F86D,
+ },
+ [0x1F86E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F86E,
+ },
+ [0x1F86F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F86F,
+ },
+ [0x1F870]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F870,
+ },
+ [0x1F871]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F871,
+ },
+ [0x1F872]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F872,
+ },
+ [0x1F873]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F873,
+ },
+ [0x1F874]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F874,
+ },
+ [0x1F875]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F875,
+ },
+ [0x1F876]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F876,
+ },
+ [0x1F877]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F877,
+ },
+ [0x1F878]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F878,
+ },
+ [0x1F879]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F879,
+ },
+ [0x1F87A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F87A,
+ },
+ [0x1F87B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F87B,
+ },
+ [0x1F87C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F87C,
+ },
+ [0x1F87D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F87D,
+ },
+ [0x1F87E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F87E,
+ },
+ [0x1F87F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F87F,
+ },
+ [0x1F880]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F880,
+ },
+ [0x1F881]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F881,
+ },
+ [0x1F882]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F882,
+ },
+ [0x1F883]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F883,
+ },
+ [0x1F884]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F884,
+ },
+ [0x1F885]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F885,
+ },
+ [0x1F886]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F886,
+ },
+ [0x1F887]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F887,
+ },
+ [0x1F890]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F890,
+ },
+ [0x1F891]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F891,
+ },
+ [0x1F892]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F892,
+ },
+ [0x1F893]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F893,
+ },
+ [0x1F894]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F894,
+ },
+ [0x1F895]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F895,
+ },
+ [0x1F896]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F896,
+ },
+ [0x1F897]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F897,
+ },
+ [0x1F898]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F898,
+ },
+ [0x1F899]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F899,
+ },
+ [0x1F89A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F89A,
+ },
+ [0x1F89B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F89B,
+ },
+ [0x1F89C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F89C,
+ },
+ [0x1F89D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F89D,
+ },
+ [0x1F89E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F89E,
+ },
+ [0x1F89F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F89F,
+ },
+ [0x1F8A0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8A0,
+ },
+ [0x1F8A1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8A1,
+ },
+ [0x1F8A2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8A2,
+ },
+ [0x1F8A3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8A3,
+ },
+ [0x1F8A4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8A4,
+ },
+ [0x1F8A5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8A5,
+ },
+ [0x1F8A6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8A6,
+ },
+ [0x1F8A7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8A7,
+ },
+ [0x1F8A8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8A8,
+ },
+ [0x1F8A9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8A9,
+ },
+ [0x1F8AA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8AA,
+ },
+ [0x1F8AB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8AB,
+ },
+ [0x1F8AC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8AC,
+ },
+ [0x1F8AD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F8AD,
+ },
+ [0x1F900]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F900,
+ },
+ [0x1F901]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F901,
+ },
+ [0x1F902]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F902,
+ },
+ [0x1F903]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F903,
+ },
+ [0x1F904]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F904,
+ },
+ [0x1F905]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F905,
+ },
+ [0x1F906]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F906,
+ },
+ [0x1F907]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F907,
+ },
+ [0x1F908]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F908,
+ },
+ [0x1F909]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F909,
+ },
+ [0x1F90A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F90A,
+ },
+ [0x1F90B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F90B,
+ },
+ [0x1F90D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F90D,
+ },
+ [0x1F90E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F90E,
+ },
+ [0x1F90F]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F90F,
+ },
+ [0x1F910]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F910,
+ },
+ [0x1F911]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F911,
+ },
+ [0x1F912]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F912,
+ },
+ [0x1F913]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F913,
+ },
+ [0x1F914]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F914,
+ },
+ [0x1F915]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F915,
+ },
+ [0x1F916]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F916,
+ },
+ [0x1F917]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F917,
+ },
+ [0x1F918]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F918,
+ },
+ [0x1F919]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F919,
+ },
+ [0x1F91A]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F91A,
+ },
+ [0x1F91B]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F91B,
+ },
+ [0x1F91C]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F91C,
+ },
+ [0x1F91D]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F91D,
+ },
+ [0x1F91E]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F91E,
+ },
+ [0x1F91F]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F91F,
+ },
+ [0x1F920]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F920,
+ },
+ [0x1F921]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F921,
+ },
+ [0x1F922]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F922,
+ },
+ [0x1F923]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F923,
+ },
+ [0x1F924]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F924,
+ },
+ [0x1F925]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F925,
+ },
+ [0x1F926]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F926,
+ },
+ [0x1F927]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F927,
+ },
+ [0x1F928]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F928,
+ },
+ [0x1F929]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F929,
+ },
+ [0x1F92A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F92A,
+ },
+ [0x1F92B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F92B,
+ },
+ [0x1F92C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F92C,
+ },
+ [0x1F92D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F92D,
+ },
+ [0x1F92E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F92E,
+ },
+ [0x1F92F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F92F,
+ },
+ [0x1F930]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F930,
+ },
+ [0x1F931]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F931,
+ },
+ [0x1F932]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F932,
+ },
+ [0x1F933]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F933,
+ },
+ [0x1F934]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F934,
+ },
+ [0x1F935]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F935,
+ },
+ [0x1F936]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F936,
+ },
+ [0x1F937]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F937,
+ },
+ [0x1F938]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F938,
+ },
+ [0x1F939]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F939,
+ },
+ [0x1F93A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F93A,
+ },
+ [0x1F93B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F93B,
+ },
+ [0x1F93C]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F93C,
+ },
+ [0x1F93D]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F93D,
+ },
+ [0x1F93E]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F93E,
+ },
+ [0x1F93F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F93F,
+ },
+ [0x1F940]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F940,
+ },
+ [0x1F941]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F941,
+ },
+ [0x1F942]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F942,
+ },
+ [0x1F943]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F943,
+ },
+ [0x1F944]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F944,
+ },
+ [0x1F945]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F945,
+ },
+ [0x1F946]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F946,
+ },
+ [0x1F947]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F947,
+ },
+ [0x1F948]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F948,
+ },
+ [0x1F949]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F949,
+ },
+ [0x1F94A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F94A,
+ },
+ [0x1F94B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F94B,
+ },
+ [0x1F94C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F94C,
+ },
+ [0x1F94D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F94D,
+ },
+ [0x1F94E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F94E,
+ },
+ [0x1F94F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F94F,
+ },
+ [0x1F950]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F950,
+ },
+ [0x1F951]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F951,
+ },
+ [0x1F952]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F952,
+ },
+ [0x1F953]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F953,
+ },
+ [0x1F954]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F954,
+ },
+ [0x1F955]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F955,
+ },
+ [0x1F956]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F956,
+ },
+ [0x1F957]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F957,
+ },
+ [0x1F958]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F958,
+ },
+ [0x1F959]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F959,
+ },
+ [0x1F95A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F95A,
+ },
+ [0x1F95B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F95B,
+ },
+ [0x1F95C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F95C,
+ },
+ [0x1F95D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F95D,
+ },
+ [0x1F95E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F95E,
+ },
+ [0x1F95F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F95F,
+ },
+ [0x1F960]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F960,
+ },
+ [0x1F961]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F961,
+ },
+ [0x1F962]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F962,
+ },
+ [0x1F963]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F963,
+ },
+ [0x1F964]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F964,
+ },
+ [0x1F965]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F965,
+ },
+ [0x1F966]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F966,
+ },
+ [0x1F967]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F967,
+ },
+ [0x1F968]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F968,
+ },
+ [0x1F969]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F969,
+ },
+ [0x1F96A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F96A,
+ },
+ [0x1F96B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F96B,
+ },
+ [0x1F96C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F96C,
+ },
+ [0x1F96D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F96D,
+ },
+ [0x1F96E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F96E,
+ },
+ [0x1F96F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F96F,
+ },
+ [0x1F970]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F970,
+ },
+ [0x1F971]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F971,
+ },
+ [0x1F973]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F973,
+ },
+ [0x1F974]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F974,
+ },
+ [0x1F975]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F975,
+ },
+ [0x1F976]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F976,
+ },
+ [0x1F97A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F97A,
+ },
+ [0x1F97B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F97B,
+ },
+ [0x1F97C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F97C,
+ },
+ [0x1F97D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F97D,
+ },
+ [0x1F97E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F97E,
+ },
+ [0x1F97F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F97F,
+ },
+ [0x1F980]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F980,
+ },
+ [0x1F981]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F981,
+ },
+ [0x1F982]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F982,
+ },
+ [0x1F983]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F983,
+ },
+ [0x1F984]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F984,
+ },
+ [0x1F985]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F985,
+ },
+ [0x1F986]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F986,
+ },
+ [0x1F987]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F987,
+ },
+ [0x1F988]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F988,
+ },
+ [0x1F989]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F989,
+ },
+ [0x1F98A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F98A,
+ },
+ [0x1F98B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F98B,
+ },
+ [0x1F98C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F98C,
+ },
+ [0x1F98D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F98D,
+ },
+ [0x1F98E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F98E,
+ },
+ [0x1F98F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F98F,
+ },
+ [0x1F990]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F990,
+ },
+ [0x1F991]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F991,
+ },
+ [0x1F992]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F992,
+ },
+ [0x1F993]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F993,
+ },
+ [0x1F994]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F994,
+ },
+ [0x1F995]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F995,
+ },
+ [0x1F996]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F996,
+ },
+ [0x1F997]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F997,
+ },
+ [0x1F998]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F998,
+ },
+ [0x1F999]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F999,
+ },
+ [0x1F99A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F99A,
+ },
+ [0x1F99B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F99B,
+ },
+ [0x1F99C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F99C,
+ },
+ [0x1F99D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F99D,
+ },
+ [0x1F99E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F99E,
+ },
+ [0x1F99F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F99F,
+ },
+ [0x1F9A0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9A0,
+ },
+ [0x1F9A1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9A1,
+ },
+ [0x1F9A2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9A2,
+ },
+ [0x1F9A5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9A5,
+ },
+ [0x1F9A6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9A6,
+ },
+ [0x1F9A7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9A7,
+ },
+ [0x1F9A8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9A8,
+ },
+ [0x1F9A9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9A9,
+ },
+ [0x1F9AA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9AA,
+ },
+ [0x1F9AE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9AE,
+ },
+ [0x1F9AF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9AF,
+ },
+ [0x1F9B0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9B0,
+ },
+ [0x1F9B1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9B1,
+ },
+ [0x1F9B2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9B2,
+ },
+ [0x1F9B3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9B3,
+ },
+ [0x1F9B4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9B4,
+ },
+ [0x1F9B5]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9B5,
+ },
+ [0x1F9B6]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9B6,
+ },
+ [0x1F9B7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9B7,
+ },
+ [0x1F9B8]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9B8,
+ },
+ [0x1F9B9]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9B9,
+ },
+ [0x1F9BA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9BA,
+ },
+ [0x1F9BB]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9BB,
+ },
+ [0x1F9BC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9BC,
+ },
+ [0x1F9BD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9BD,
+ },
+ [0x1F9BE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9BE,
+ },
+ [0x1F9BF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9BF,
+ },
+ [0x1F9C0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9C0,
+ },
+ [0x1F9C1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9C1,
+ },
+ [0x1F9C2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9C2,
+ },
+ [0x1F9C3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9C3,
+ },
+ [0x1F9C4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9C4,
+ },
+ [0x1F9C5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9C5,
+ },
+ [0x1F9C6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9C6,
+ },
+ [0x1F9C7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9C7,
+ },
+ [0x1F9C8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9C8,
+ },
+ [0x1F9C9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9C9,
+ },
+ [0x1F9CA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9CA,
+ },
+ [0x1F9CD]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9CD,
+ },
+ [0x1F9CE]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9CE,
+ },
+ [0x1F9CF]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9CF,
+ },
+ [0x1F9D0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9D0,
+ },
+ [0x1F9D1]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9D1,
+ },
+ [0x1F9D2]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9D2,
+ },
+ [0x1F9D3]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9D3,
+ },
+ [0x1F9D4]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9D4,
+ },
+ [0x1F9D5]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9D5,
+ },
+ [0x1F9D6]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9D6,
+ },
+ [0x1F9D7]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9D7,
+ },
+ [0x1F9D8]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9D8,
+ },
+ [0x1F9D9]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9D9,
+ },
+ [0x1F9DA]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9DA,
+ },
+ [0x1F9DB]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9DB,
+ },
+ [0x1F9DC]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9DC,
+ },
+ [0x1F9DD]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F9DD,
+ },
+ [0x1F9DE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9DE,
+ },
+ [0x1F9DF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9DF,
+ },
+ [0x1F9E0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9E0,
+ },
+ [0x1F9E1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9E1,
+ },
+ [0x1F9E2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9E2,
+ },
+ [0x1F9E3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9E3,
+ },
+ [0x1F9E4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9E4,
+ },
+ [0x1F9E5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9E5,
+ },
+ [0x1F9E6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9E6,
+ },
+ [0x1F9E7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9E7,
+ },
+ [0x1F9E8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9E8,
+ },
+ [0x1F9E9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9E9,
+ },
+ [0x1F9EA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9EA,
+ },
+ [0x1F9EB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9EB,
+ },
+ [0x1F9EC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9EC,
+ },
+ [0x1F9ED]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9ED,
+ },
+ [0x1F9EE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9EE,
+ },
+ [0x1F9EF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9EF,
+ },
+ [0x1F9F0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9F0,
+ },
+ [0x1F9F1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9F1,
+ },
+ [0x1F9F2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9F2,
+ },
+ [0x1F9F3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9F3,
+ },
+ [0x1F9F4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9F4,
+ },
+ [0x1F9F5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9F5,
+ },
+ [0x1F9F6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9F6,
+ },
+ [0x1F9F7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9F7,
+ },
+ [0x1F9F8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9F8,
+ },
+ [0x1F9F9]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9F9,
+ },
+ [0x1F9FA]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9FA,
+ },
+ [0x1F9FB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9FB,
+ },
+ [0x1F9FC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9FC,
+ },
+ [0x1F9FD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9FD,
+ },
+ [0x1F9FE]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9FE,
+ },
+ [0x1F9FF]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9FF,
+ },
+ [0x1FA00]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA00,
+ },
+ [0x1FA01]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA01,
+ },
+ [0x1FA02]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA02,
+ },
+ [0x1FA03]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA03,
+ },
+ [0x1FA04]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA04,
+ },
+ [0x1FA05]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA05,
+ },
+ [0x1FA06]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA06,
+ },
+ [0x1FA07]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA07,
+ },
+ [0x1FA08]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA08,
+ },
+ [0x1FA09]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA09,
+ },
+ [0x1FA0A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA0A,
+ },
+ [0x1FA0B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA0B,
+ },
+ [0x1FA0C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA0C,
+ },
+ [0x1FA0D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA0D,
+ },
+ [0x1FA0E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA0E,
+ },
+ [0x1FA0F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA0F,
+ },
+ [0x1FA10]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA10,
+ },
+ [0x1FA11]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA11,
+ },
+ [0x1FA12]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA12,
+ },
+ [0x1FA13]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA13,
+ },
+ [0x1FA14]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA14,
+ },
+ [0x1FA15]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA15,
+ },
+ [0x1FA16]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA16,
+ },
+ [0x1FA17]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA17,
+ },
+ [0x1FA18]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA18,
+ },
+ [0x1FA19]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA19,
+ },
+ [0x1FA1A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA1A,
+ },
+ [0x1FA1B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA1B,
+ },
+ [0x1FA1C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA1C,
+ },
+ [0x1FA1D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA1D,
+ },
+ [0x1FA1E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA1E,
+ },
+ [0x1FA1F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA1F,
+ },
+ [0x1FA20]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA20,
+ },
+ [0x1FA21]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA21,
+ },
+ [0x1FA22]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA22,
+ },
+ [0x1FA23]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA23,
+ },
+ [0x1FA24]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA24,
+ },
+ [0x1FA25]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA25,
+ },
+ [0x1FA26]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA26,
+ },
+ [0x1FA27]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA27,
+ },
+ [0x1FA28]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA28,
+ },
+ [0x1FA29]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA29,
+ },
+ [0x1FA2A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA2A,
+ },
+ [0x1FA2B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA2B,
+ },
+ [0x1FA2C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA2C,
+ },
+ [0x1FA2D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA2D,
+ },
+ [0x1FA2E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA2E,
+ },
+ [0x1FA2F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA2F,
+ },
+ [0x1FA30]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA30,
+ },
+ [0x1FA31]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA31,
+ },
+ [0x1FA32]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA32,
+ },
+ [0x1FA33]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA33,
+ },
+ [0x1FA34]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA34,
+ },
+ [0x1FA35]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA35,
+ },
+ [0x1FA36]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA36,
+ },
+ [0x1FA37]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA37,
+ },
+ [0x1FA38]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA38,
+ },
+ [0x1FA39]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA39,
+ },
+ [0x1FA3A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA3A,
+ },
+ [0x1FA3B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA3B,
+ },
+ [0x1FA3C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA3C,
+ },
+ [0x1FA3D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA3D,
+ },
+ [0x1FA3E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA3E,
+ },
+ [0x1FA3F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA3F,
+ },
+ [0x1FA40]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA40,
+ },
+ [0x1FA41]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA41,
+ },
+ [0x1FA42]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA42,
+ },
+ [0x1FA43]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA43,
+ },
+ [0x1FA44]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA44,
+ },
+ [0x1FA45]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA45,
+ },
+ [0x1FA46]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA46,
+ },
+ [0x1FA47]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA47,
+ },
+ [0x1FA48]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA48,
+ },
+ [0x1FA49]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA49,
+ },
+ [0x1FA4A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA4A,
+ },
+ [0x1FA4B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA4B,
+ },
+ [0x1FA4C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA4C,
+ },
+ [0x1FA4D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA4D,
+ },
+ [0x1FA4E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA4E,
+ },
+ [0x1FA4F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA4F,
+ },
+ [0x1FA50]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA50,
+ },
+ [0x1FA51]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA51,
+ },
+ [0x1FA52]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA52,
+ },
+ [0x1FA53]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FA53,
+ },
+ [0x1FA60]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA60,
+ },
+ [0x1FA61]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA61,
+ },
+ [0x1FA62]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA62,
+ },
+ [0x1FA63]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA63,
+ },
+ [0x1FA64]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA64,
+ },
+ [0x1FA65]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA65,
+ },
+ [0x1FA66]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA66,
+ },
+ [0x1FA67]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA67,
+ },
+ [0x1FA68]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA68,
+ },
+ [0x1FA69]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA69,
+ },
+ [0x1FA6A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA6A,
+ },
+ [0x1FA6B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA6B,
+ },
+ [0x1FA6C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA6C,
+ },
+ [0x1FA6D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA6D,
+ },
+ [0x1FA70]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA70,
+ },
+ [0x1FA71]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA71,
+ },
+ [0x1FA72]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA72,
+ },
+ [0x1FA73]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA73,
+ },
+ [0x1FA78]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA78,
+ },
+ [0x1FA79]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA79,
+ },
+ [0x1FA7A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA7A,
+ },
+ [0x1FA80]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA80,
+ },
+ [0x1FA81]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA81,
+ },
+ [0x1FA82]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA82,
+ },
+ [0x1FA90]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA90,
+ },
+ [0x1FA91]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA91,
+ },
+ [0x1FA92]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA92,
+ },
+ [0x1FA93]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA93,
+ },
+ [0x1FA94]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA94,
+ },
+ [0x1FA95]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA95,
+ },
+ [0x2F800]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E3D },
+ unicodeslot=0x2F800,
+ },
+ [0x2F801]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E38 },
+ unicodeslot=0x2F801,
+ },
+ [0x2F802]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E41 },
+ unicodeslot=0x2F802,
+ },
+ [0x2F803]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x20122 },
+ unicodeslot=0x2F803,
+ },
+ [0x2F804]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4F60 },
+ unicodeslot=0x2F804,
+ },
+ [0x2F805]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4FAE },
+ unicodeslot=0x2F805,
+ },
+ [0x2F806]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4FBB },
+ unicodeslot=0x2F806,
+ },
+ [0x2F807]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5002 },
+ unicodeslot=0x2F807,
+ },
+ [0x2F808]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x507A },
+ unicodeslot=0x2F808,
+ },
+ [0x2F809]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5099 },
+ unicodeslot=0x2F809,
+ },
+ [0x2F80A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x50E7 },
+ unicodeslot=0x2F80A,
+ },
+ [0x2F80B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x50CF },
+ unicodeslot=0x2F80B,
+ },
+ [0x2F80C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x349E },
+ unicodeslot=0x2F80C,
+ },
+ [0x2F80D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2063A },
+ unicodeslot=0x2F80D,
+ },
+ [0x2F80E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x514D },
+ unicodeslot=0x2F80E,
+ },
+ [0x2F80F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5154 },
+ unicodeslot=0x2F80F,
+ },
+ [0x2F810]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5164 },
+ unicodeslot=0x2F810,
+ },
+ [0x2F811]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5177 },
+ unicodeslot=0x2F811,
+ },
+ [0x2F812]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2051C },
+ unicodeslot=0x2F812,
+ },
+ [0x2F813]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x34B9 },
+ unicodeslot=0x2F813,
+ },
+ [0x2F814]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5167 },
+ unicodeslot=0x2F814,
+ },
+ [0x2F815]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x518D },
+ unicodeslot=0x2F815,
+ },
+ [0x2F816]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2054B },
+ unicodeslot=0x2F816,
+ },
+ [0x2F817]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5197 },
+ unicodeslot=0x2F817,
+ },
+ [0x2F818]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51A4 },
+ unicodeslot=0x2F818,
+ },
+ [0x2F819]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4ECC },
+ unicodeslot=0x2F819,
+ },
+ [0x2F81A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51AC },
+ unicodeslot=0x2F81A,
+ },
+ [0x2F81B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51B5 },
+ unicodeslot=0x2F81B,
+ },
+ [0x2F81C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x291DF },
+ unicodeslot=0x2F81C,
+ },
+ [0x2F81D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51F5 },
+ unicodeslot=0x2F81D,
+ },
+ [0x2F81E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5203 },
+ unicodeslot=0x2F81E,
+ },
+ [0x2F81F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x34DF },
+ unicodeslot=0x2F81F,
+ },
+ [0x2F820]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x523B },
+ unicodeslot=0x2F820,
+ },
+ [0x2F821]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5246 },
+ unicodeslot=0x2F821,
+ },
+ [0x2F822]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5272 },
+ unicodeslot=0x2F822,
+ },
+ [0x2F823]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5277 },
+ unicodeslot=0x2F823,
+ },
+ [0x2F824]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3515 },
+ unicodeslot=0x2F824,
+ },
+ [0x2F825]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52C7 },
+ unicodeslot=0x2F825,
+ },
+ [0x2F826]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52C9 },
+ unicodeslot=0x2F826,
+ },
+ [0x2F827]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52E4 },
+ unicodeslot=0x2F827,
+ },
+ [0x2F828]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52FA },
+ unicodeslot=0x2F828,
+ },
+ [0x2F829]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5305 },
+ unicodeslot=0x2F829,
+ },
+ [0x2F82A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5306 },
+ unicodeslot=0x2F82A,
+ },
+ [0x2F82B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5317 },
+ unicodeslot=0x2F82B,
+ },
+ [0x2F82C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5349 },
+ unicodeslot=0x2F82C,
+ },
+ [0x2F82D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5351 },
+ unicodeslot=0x2F82D,
+ },
+ [0x2F82E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x535A },
+ unicodeslot=0x2F82E,
+ },
+ [0x2F82F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5373 },
+ unicodeslot=0x2F82F,
+ },
+ [0x2F830]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x537D },
+ unicodeslot=0x2F830,
+ },
+ [0x2F831]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x537F },
+ unicodeslot=0x2F831,
+ },
+ [0x2F832]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x537F },
+ unicodeslot=0x2F832,
+ },
+ [0x2F833]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x537F },
+ unicodeslot=0x2F833,
+ },
+ [0x2F834]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x20A2C },
+ unicodeslot=0x2F834,
+ },
+ [0x2F835]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7070 },
+ unicodeslot=0x2F835,
+ },
+ [0x2F836]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x53CA },
+ unicodeslot=0x2F836,
+ },
+ [0x2F837]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x53DF },
+ unicodeslot=0x2F837,
+ },
+ [0x2F838]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x20B63 },
+ unicodeslot=0x2F838,
+ },
+ [0x2F839]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x53EB },
+ unicodeslot=0x2F839,
+ },
+ [0x2F83A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x53F1 },
+ unicodeslot=0x2F83A,
+ },
+ [0x2F83B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5406 },
+ unicodeslot=0x2F83B,
+ },
+ [0x2F83C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x549E },
+ unicodeslot=0x2F83C,
+ },
+ [0x2F83D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5438 },
+ unicodeslot=0x2F83D,
+ },
+ [0x2F83E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5448 },
+ unicodeslot=0x2F83E,
+ },
+ [0x2F83F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5468 },
+ unicodeslot=0x2F83F,
+ },
+ [0x2F840]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x54A2 },
+ unicodeslot=0x2F840,
+ },
+ [0x2F841]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x54F6 },
+ unicodeslot=0x2F841,
+ },
+ [0x2F842]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5510 },
+ unicodeslot=0x2F842,
+ },
+ [0x2F843]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5553 },
+ unicodeslot=0x2F843,
+ },
+ [0x2F844]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5563 },
+ unicodeslot=0x2F844,
+ },
+ [0x2F845]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5584 },
+ unicodeslot=0x2F845,
+ },
+ [0x2F846]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5584 },
+ unicodeslot=0x2F846,
+ },
+ [0x2F847]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5599 },
+ unicodeslot=0x2F847,
+ },
+ [0x2F848]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x55AB },
+ unicodeslot=0x2F848,
+ },
+ [0x2F849]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x55B3 },
+ unicodeslot=0x2F849,
+ },
+ [0x2F84A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x55C2 },
+ unicodeslot=0x2F84A,
+ },
+ [0x2F84B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5716 },
+ unicodeslot=0x2F84B,
+ },
+ [0x2F84C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5606 },
+ unicodeslot=0x2F84C,
+ },
+ [0x2F84D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5717 },
+ unicodeslot=0x2F84D,
+ },
+ [0x2F84E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5651 },
+ unicodeslot=0x2F84E,
+ },
+ [0x2F84F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5674 },
+ unicodeslot=0x2F84F,
+ },
+ [0x2F850]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5207 },
+ unicodeslot=0x2F850,
+ },
+ [0x2F851]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58EE },
+ unicodeslot=0x2F851,
+ },
+ [0x2F852]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x57CE },
+ unicodeslot=0x2F852,
+ },
+ [0x2F853]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x57F4 },
+ unicodeslot=0x2F853,
+ },
+ [0x2F854]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x580D },
+ unicodeslot=0x2F854,
+ },
+ [0x2F855]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x578B },
+ unicodeslot=0x2F855,
+ },
+ [0x2F856]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5832 },
+ unicodeslot=0x2F856,
+ },
+ [0x2F857]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5831 },
+ unicodeslot=0x2F857,
+ },
+ [0x2F858]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58AC },
+ unicodeslot=0x2F858,
+ },
+ [0x2F859]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x214E4 },
+ unicodeslot=0x2F859,
+ },
+ [0x2F85A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58F2 },
+ unicodeslot=0x2F85A,
+ },
+ [0x2F85B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58F7 },
+ unicodeslot=0x2F85B,
+ },
+ [0x2F85C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5906 },
+ unicodeslot=0x2F85C,
+ },
+ [0x2F85D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x591A },
+ unicodeslot=0x2F85D,
+ },
+ [0x2F85E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5922 },
+ unicodeslot=0x2F85E,
+ },
+ [0x2F85F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5962 },
+ unicodeslot=0x2F85F,
+ },
+ [0x2F860]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x216A8 },
+ unicodeslot=0x2F860,
+ },
+ [0x2F861]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x216EA },
+ unicodeslot=0x2F861,
+ },
+ [0x2F862]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x59EC },
+ unicodeslot=0x2F862,
+ },
+ [0x2F863]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5A1B },
+ unicodeslot=0x2F863,
+ },
+ [0x2F864]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5A27 },
+ unicodeslot=0x2F864,
+ },
+ [0x2F865]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x59D8 },
+ unicodeslot=0x2F865,
+ },
+ [0x2F866]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5A66 },
+ unicodeslot=0x2F866,
+ },
+ [0x2F867]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x36EE },
+ unicodeslot=0x2F867,
+ },
+ [0x2F868]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x36FC },
+ unicodeslot=0x2F868,
+ },
+ [0x2F869]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5B08 },
+ unicodeslot=0x2F869,
+ },
+ [0x2F86A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5B3E },
+ unicodeslot=0x2F86A,
+ },
+ [0x2F86B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5B3E },
+ unicodeslot=0x2F86B,
+ },
+ [0x2F86C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x219C8 },
+ unicodeslot=0x2F86C,
+ },
+ [0x2F86D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BC3 },
+ unicodeslot=0x2F86D,
+ },
+ [0x2F86E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BD8 },
+ unicodeslot=0x2F86E,
+ },
+ [0x2F86F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BE7 },
+ unicodeslot=0x2F86F,
+ },
+ [0x2F870]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BF3 },
+ unicodeslot=0x2F870,
+ },
+ [0x2F871]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x21B18 },
+ unicodeslot=0x2F871,
+ },
+ [0x2F872]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BFF },
+ unicodeslot=0x2F872,
+ },
+ [0x2F873]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C06 },
+ unicodeslot=0x2F873,
+ },
+ [0x2F874]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F53 },
+ unicodeslot=0x2F874,
+ },
+ [0x2F875]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C22 },
+ unicodeslot=0x2F875,
+ },
+ [0x2F876]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3781 },
+ unicodeslot=0x2F876,
+ },
+ [0x2F877]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C60 },
+ unicodeslot=0x2F877,
+ },
+ [0x2F878]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C6E },
+ unicodeslot=0x2F878,
+ },
+ [0x2F879]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5CC0 },
+ unicodeslot=0x2F879,
+ },
+ [0x2F87A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C8D },
+ unicodeslot=0x2F87A,
+ },
+ [0x2F87B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x21DE4 },
+ unicodeslot=0x2F87B,
+ },
+ [0x2F87C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5D43 },
+ unicodeslot=0x2F87C,
+ },
+ [0x2F87D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x21DE6 },
+ unicodeslot=0x2F87D,
+ },
+ [0x2F87E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5D6E },
+ unicodeslot=0x2F87E,
+ },
+ [0x2F87F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5D6B },
+ unicodeslot=0x2F87F,
+ },
+ [0x2F880]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5D7C },
+ unicodeslot=0x2F880,
+ },
+ [0x2F881]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5DE1 },
+ unicodeslot=0x2F881,
+ },
+ [0x2F882]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5DE2 },
+ unicodeslot=0x2F882,
+ },
+ [0x2F883]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x382F },
+ unicodeslot=0x2F883,
+ },
+ [0x2F884]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5DFD },
+ unicodeslot=0x2F884,
+ },
+ [0x2F885]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5E28 },
+ unicodeslot=0x2F885,
+ },
+ [0x2F886]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5E3D },
+ unicodeslot=0x2F886,
+ },
+ [0x2F887]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5E69 },
+ unicodeslot=0x2F887,
+ },
+ [0x2F888]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3862 },
+ unicodeslot=0x2F888,
+ },
+ [0x2F889]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x22183 },
+ unicodeslot=0x2F889,
+ },
+ [0x2F88A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x387C },
+ unicodeslot=0x2F88A,
+ },
+ [0x2F88B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EB0 },
+ unicodeslot=0x2F88B,
+ },
+ [0x2F88C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EB3 },
+ unicodeslot=0x2F88C,
+ },
+ [0x2F88D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EB6 },
+ unicodeslot=0x2F88D,
+ },
+ [0x2F88E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5ECA },
+ unicodeslot=0x2F88E,
+ },
+ [0x2F88F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2A392 },
+ unicodeslot=0x2F88F,
+ },
+ [0x2F890]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EFE },
+ unicodeslot=0x2F890,
+ },
+ [0x2F891]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x22331 },
+ unicodeslot=0x2F891,
+ },
+ [0x2F892]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x22331 },
+ unicodeslot=0x2F892,
+ },
+ [0x2F893]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8201 },
+ unicodeslot=0x2F893,
+ },
+ [0x2F894]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F22 },
+ unicodeslot=0x2F894,
+ },
+ [0x2F895]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F22 },
+ unicodeslot=0x2F895,
+ },
+ [0x2F896]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x38C7 },
+ unicodeslot=0x2F896,
+ },
+ [0x2F897]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x232B8 },
+ unicodeslot=0x2F897,
+ },
+ [0x2F898]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x261DA },
+ unicodeslot=0x2F898,
+ },
+ [0x2F899]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F62 },
+ unicodeslot=0x2F899,
+ },
+ [0x2F89A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F6B },
+ unicodeslot=0x2F89A,
+ },
+ [0x2F89B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x38E3 },
+ unicodeslot=0x2F89B,
+ },
+ [0x2F89C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F9A },
+ unicodeslot=0x2F89C,
+ },
+ [0x2F89D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5FCD },
+ unicodeslot=0x2F89D,
+ },
+ [0x2F89E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5FD7 },
+ unicodeslot=0x2F89E,
+ },
+ [0x2F89F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5FF9 },
+ unicodeslot=0x2F89F,
+ },
+ [0x2F8A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6081 },
+ unicodeslot=0x2F8A0,
+ },
+ [0x2F8A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x393A },
+ unicodeslot=0x2F8A1,
+ },
+ [0x2F8A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x391C },
+ unicodeslot=0x2F8A2,
+ },
+ [0x2F8A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6094 },
+ unicodeslot=0x2F8A3,
+ },
+ [0x2F8A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x226D4 },
+ unicodeslot=0x2F8A4,
+ },
+ [0x2F8A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x60C7 },
+ unicodeslot=0x2F8A5,
+ },
+ [0x2F8A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6148 },
+ unicodeslot=0x2F8A6,
+ },
+ [0x2F8A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x614C },
+ unicodeslot=0x2F8A7,
+ },
+ [0x2F8A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x614E },
+ unicodeslot=0x2F8A8,
+ },
+ [0x2F8A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x614C },
+ unicodeslot=0x2F8A9,
+ },
+ [0x2F8AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x617A },
+ unicodeslot=0x2F8AA,
+ },
+ [0x2F8AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x618E },
+ unicodeslot=0x2F8AB,
+ },
+ [0x2F8AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61B2 },
+ unicodeslot=0x2F8AC,
+ },
+ [0x2F8AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61A4 },
+ unicodeslot=0x2F8AD,
+ },
+ [0x2F8AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61AF },
+ unicodeslot=0x2F8AE,
+ },
+ [0x2F8AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61DE },
+ unicodeslot=0x2F8AF,
+ },
+ [0x2F8B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61F2 },
+ unicodeslot=0x2F8B0,
+ },
+ [0x2F8B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61F6 },
+ unicodeslot=0x2F8B1,
+ },
+ [0x2F8B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6210 },
+ unicodeslot=0x2F8B2,
+ },
+ [0x2F8B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x621B },
+ unicodeslot=0x2F8B3,
+ },
+ [0x2F8B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x625D },
+ unicodeslot=0x2F8B4,
+ },
+ [0x2F8B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62B1 },
+ unicodeslot=0x2F8B5,
+ },
+ [0x2F8B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62D4 },
+ unicodeslot=0x2F8B6,
+ },
+ [0x2F8B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6350 },
+ unicodeslot=0x2F8B7,
+ },
+ [0x2F8B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x22B0C },
+ unicodeslot=0x2F8B8,
+ },
+ [0x2F8B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x633D },
+ unicodeslot=0x2F8B9,
+ },
+ [0x2F8BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62FC },
+ unicodeslot=0x2F8BA,
+ },
+ [0x2F8BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6368 },
+ unicodeslot=0x2F8BB,
+ },
+ [0x2F8BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6383 },
+ unicodeslot=0x2F8BC,
+ },
+ [0x2F8BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x63E4 },
+ unicodeslot=0x2F8BD,
+ },
+ [0x2F8BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x22BF1 },
+ unicodeslot=0x2F8BE,
+ },
+ [0x2F8BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6422 },
+ unicodeslot=0x2F8BF,
+ },
+ [0x2F8C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x63C5 },
+ unicodeslot=0x2F8C0,
+ },
+ [0x2F8C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x63A9 },
+ unicodeslot=0x2F8C1,
+ },
+ [0x2F8C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3A2E },
+ unicodeslot=0x2F8C2,
+ },
+ [0x2F8C3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6469 },
+ unicodeslot=0x2F8C3,
+ },
+ [0x2F8C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x647E },
+ unicodeslot=0x2F8C4,
+ },
+ [0x2F8C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x649D },
+ unicodeslot=0x2F8C5,
+ },
+ [0x2F8C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6477 },
+ unicodeslot=0x2F8C6,
+ },
+ [0x2F8C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3A6C },
+ unicodeslot=0x2F8C7,
+ },
+ [0x2F8C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x654F },
+ unicodeslot=0x2F8C8,
+ },
+ [0x2F8C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x656C },
+ unicodeslot=0x2F8C9,
+ },
+ [0x2F8CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2300A },
+ unicodeslot=0x2F8CA,
+ },
+ [0x2F8CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x65E3 },
+ unicodeslot=0x2F8CB,
+ },
+ [0x2F8CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x66F8 },
+ unicodeslot=0x2F8CC,
+ },
+ [0x2F8CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6649 },
+ unicodeslot=0x2F8CD,
+ },
+ [0x2F8CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3B19 },
+ unicodeslot=0x2F8CE,
+ },
+ [0x2F8CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6691 },
+ unicodeslot=0x2F8CF,
+ },
+ [0x2F8D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3B08 },
+ unicodeslot=0x2F8D0,
+ },
+ [0x2F8D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3AE4 },
+ unicodeslot=0x2F8D1,
+ },
+ [0x2F8D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5192 },
+ unicodeslot=0x2F8D2,
+ },
+ [0x2F8D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5195 },
+ unicodeslot=0x2F8D3,
+ },
+ [0x2F8D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6700 },
+ unicodeslot=0x2F8D4,
+ },
+ [0x2F8D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x669C },
+ unicodeslot=0x2F8D5,
+ },
+ [0x2F8D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x80AD },
+ unicodeslot=0x2F8D6,
+ },
+ [0x2F8D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x43D9 },
+ unicodeslot=0x2F8D7,
+ },
+ [0x2F8D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6717 },
+ unicodeslot=0x2F8D8,
+ },
+ [0x2F8D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x671B },
+ unicodeslot=0x2F8D9,
+ },
+ [0x2F8DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6721 },
+ unicodeslot=0x2F8DA,
+ },
+ [0x2F8DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x675E },
+ unicodeslot=0x2F8DB,
+ },
+ [0x2F8DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6753 },
+ unicodeslot=0x2F8DC,
+ },
+ [0x2F8DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x233C3 },
+ unicodeslot=0x2F8DD,
+ },
+ [0x2F8DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3B49 },
+ unicodeslot=0x2F8DE,
+ },
+ [0x2F8DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x67FA },
+ unicodeslot=0x2F8DF,
+ },
+ [0x2F8E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6785 },
+ unicodeslot=0x2F8E0,
+ },
+ [0x2F8E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6852 },
+ unicodeslot=0x2F8E1,
+ },
+ [0x2F8E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6885 },
+ unicodeslot=0x2F8E2,
+ },
+ [0x2F8E3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2346D },
+ unicodeslot=0x2F8E3,
+ },
+ [0x2F8E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x688E },
+ unicodeslot=0x2F8E4,
+ },
+ [0x2F8E5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x681F },
+ unicodeslot=0x2F8E5,
+ },
+ [0x2F8E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6914 },
+ unicodeslot=0x2F8E6,
+ },
+ [0x2F8E7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3B9D },
+ unicodeslot=0x2F8E7,
+ },
+ [0x2F8E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6942 },
+ unicodeslot=0x2F8E8,
+ },
+ [0x2F8E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x69A3 },
+ unicodeslot=0x2F8E9,
+ },
+ [0x2F8EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x69EA },
+ unicodeslot=0x2F8EA,
+ },
+ [0x2F8EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6AA8 },
+ unicodeslot=0x2F8EB,
+ },
+ [0x2F8EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x236A3 },
+ unicodeslot=0x2F8EC,
+ },
+ [0x2F8ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6ADB },
+ unicodeslot=0x2F8ED,
+ },
+ [0x2F8EE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3C18 },
+ unicodeslot=0x2F8EE,
+ },
+ [0x2F8EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B21 },
+ unicodeslot=0x2F8EF,
+ },
+ [0x2F8F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x238A7 },
+ unicodeslot=0x2F8F0,
+ },
+ [0x2F8F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B54 },
+ unicodeslot=0x2F8F1,
+ },
+ [0x2F8F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3C4E },
+ unicodeslot=0x2F8F2,
+ },
+ [0x2F8F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B72 },
+ unicodeslot=0x2F8F3,
+ },
+ [0x2F8F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B9F },
+ unicodeslot=0x2F8F4,
+ },
+ [0x2F8F5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6BBA },
+ unicodeslot=0x2F8F5,
+ },
+ [0x2F8F6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6BBB },
+ unicodeslot=0x2F8F6,
+ },
+ [0x2F8F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23A8D },
+ unicodeslot=0x2F8F7,
+ },
+ [0x2F8F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x21D0B },
+ unicodeslot=0x2F8F8,
+ },
+ [0x2F8F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23AFA },
+ unicodeslot=0x2F8F9,
+ },
+ [0x2F8FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6C4E },
+ unicodeslot=0x2F8FA,
+ },
+ [0x2F8FB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23CBC },
+ unicodeslot=0x2F8FB,
+ },
+ [0x2F8FC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6CBF },
+ unicodeslot=0x2F8FC,
+ },
+ [0x2F8FD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6CCD },
+ unicodeslot=0x2F8FD,
+ },
+ [0x2F8FE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6C67 },
+ unicodeslot=0x2F8FE,
+ },
+ [0x2F8FF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D16 },
+ unicodeslot=0x2F8FF,
+ },
+ [0x2F900]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D3E },
+ unicodeslot=0x2F900,
+ },
+ [0x2F901]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D77 },
+ unicodeslot=0x2F901,
+ },
+ [0x2F902]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D41 },
+ unicodeslot=0x2F902,
+ },
+ [0x2F903]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D69 },
+ unicodeslot=0x2F903,
+ },
+ [0x2F904]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D78 },
+ unicodeslot=0x2F904,
+ },
+ [0x2F905]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D85 },
+ unicodeslot=0x2F905,
+ },
+ [0x2F906]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23D1E },
+ unicodeslot=0x2F906,
+ },
+ [0x2F907]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D34 },
+ unicodeslot=0x2F907,
+ },
+ [0x2F908]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6E2F },
+ unicodeslot=0x2F908,
+ },
+ [0x2F909]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6E6E },
+ unicodeslot=0x2F909,
+ },
+ [0x2F90A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3D33 },
+ unicodeslot=0x2F90A,
+ },
+ [0x2F90B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6ECB },
+ unicodeslot=0x2F90B,
+ },
+ [0x2F90C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6EC7 },
+ unicodeslot=0x2F90C,
+ },
+ [0x2F90D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23ED1 },
+ unicodeslot=0x2F90D,
+ },
+ [0x2F90E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6DF9 },
+ unicodeslot=0x2F90E,
+ },
+ [0x2F90F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6F6E },
+ unicodeslot=0x2F90F,
+ },
+ [0x2F910]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23F5E },
+ unicodeslot=0x2F910,
+ },
+ [0x2F911]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23F8E },
+ unicodeslot=0x2F911,
+ },
+ [0x2F912]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6FC6 },
+ unicodeslot=0x2F912,
+ },
+ [0x2F913]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7039 },
+ unicodeslot=0x2F913,
+ },
+ [0x2F914]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x701E },
+ unicodeslot=0x2F914,
+ },
+ [0x2F915]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x701B },
+ unicodeslot=0x2F915,
+ },
+ [0x2F916]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3D96 },
+ unicodeslot=0x2F916,
+ },
+ [0x2F917]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x704A },
+ unicodeslot=0x2F917,
+ },
+ [0x2F918]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x707D },
+ unicodeslot=0x2F918,
+ },
+ [0x2F919]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7077 },
+ unicodeslot=0x2F919,
+ },
+ [0x2F91A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x70AD },
+ unicodeslot=0x2F91A,
+ },
+ [0x2F91B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x20525 },
+ unicodeslot=0x2F91B,
+ },
+ [0x2F91C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7145 },
+ unicodeslot=0x2F91C,
+ },
+ [0x2F91D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24263 },
+ unicodeslot=0x2F91D,
+ },
+ [0x2F91E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x719C },
+ unicodeslot=0x2F91E,
+ },
+ [0x2F91F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x243AB },
+ unicodeslot=0x2F91F,
+ },
+ [0x2F920]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7228 },
+ unicodeslot=0x2F920,
+ },
+ [0x2F921]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7235 },
+ unicodeslot=0x2F921,
+ },
+ [0x2F922]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7250 },
+ unicodeslot=0x2F922,
+ },
+ [0x2F923]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24608 },
+ unicodeslot=0x2F923,
+ },
+ [0x2F924]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7280 },
+ unicodeslot=0x2F924,
+ },
+ [0x2F925]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7295 },
+ unicodeslot=0x2F925,
+ },
+ [0x2F926]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24735 },
+ unicodeslot=0x2F926,
+ },
+ [0x2F927]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24814 },
+ unicodeslot=0x2F927,
+ },
+ [0x2F928]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x737A },
+ unicodeslot=0x2F928,
+ },
+ [0x2F929]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x738B },
+ unicodeslot=0x2F929,
+ },
+ [0x2F92A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3EAC },
+ unicodeslot=0x2F92A,
+ },
+ [0x2F92B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x73A5 },
+ unicodeslot=0x2F92B,
+ },
+ [0x2F92C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3EB8 },
+ unicodeslot=0x2F92C,
+ },
+ [0x2F92D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3EB8 },
+ unicodeslot=0x2F92D,
+ },
+ [0x2F92E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7447 },
+ unicodeslot=0x2F92E,
+ },
+ [0x2F92F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x745C },
+ unicodeslot=0x2F92F,
+ },
+ [0x2F930]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7471 },
+ unicodeslot=0x2F930,
+ },
+ [0x2F931]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7485 },
+ unicodeslot=0x2F931,
+ },
+ [0x2F932]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x74CA },
+ unicodeslot=0x2F932,
+ },
+ [0x2F933]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3F1B },
+ unicodeslot=0x2F933,
+ },
+ [0x2F934]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7524 },
+ unicodeslot=0x2F934,
+ },
+ [0x2F935]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24C36 },
+ unicodeslot=0x2F935,
+ },
+ [0x2F936]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x753E },
+ unicodeslot=0x2F936,
+ },
+ [0x2F937]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24C92 },
+ unicodeslot=0x2F937,
+ },
+ [0x2F938]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7570 },
+ unicodeslot=0x2F938,
+ },
+ [0x2F939]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2219F },
+ unicodeslot=0x2F939,
+ },
+ [0x2F93A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7610 },
+ unicodeslot=0x2F93A,
+ },
+ [0x2F93B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24FA1 },
+ unicodeslot=0x2F93B,
+ },
+ [0x2F93C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24FB8 },
+ unicodeslot=0x2F93C,
+ },
+ [0x2F93D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25044 },
+ unicodeslot=0x2F93D,
+ },
+ [0x2F93E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3FFC },
+ unicodeslot=0x2F93E,
+ },
+ [0x2F93F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4008 },
+ unicodeslot=0x2F93F,
+ },
+ [0x2F940]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x76F4 },
+ unicodeslot=0x2F940,
+ },
+ [0x2F941]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x250F3 },
+ unicodeslot=0x2F941,
+ },
+ [0x2F942]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x250F2 },
+ unicodeslot=0x2F942,
+ },
+ [0x2F943]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25119 },
+ unicodeslot=0x2F943,
+ },
+ [0x2F944]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25133 },
+ unicodeslot=0x2F944,
+ },
+ [0x2F945]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x771E },
+ unicodeslot=0x2F945,
+ },
+ [0x2F946]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x771F },
+ unicodeslot=0x2F946,
+ },
+ [0x2F947]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x771F },
+ unicodeslot=0x2F947,
+ },
+ [0x2F948]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x774A },
+ unicodeslot=0x2F948,
+ },
+ [0x2F949]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4039 },
+ unicodeslot=0x2F949,
+ },
+ [0x2F94A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x778B },
+ unicodeslot=0x2F94A,
+ },
+ [0x2F94B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4046 },
+ unicodeslot=0x2F94B,
+ },
+ [0x2F94C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4096 },
+ unicodeslot=0x2F94C,
+ },
+ [0x2F94D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2541D },
+ unicodeslot=0x2F94D,
+ },
+ [0x2F94E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x784E },
+ unicodeslot=0x2F94E,
+ },
+ [0x2F94F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x788C },
+ unicodeslot=0x2F94F,
+ },
+ [0x2F950]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x78CC },
+ unicodeslot=0x2F950,
+ },
+ [0x2F951]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x40E3 },
+ unicodeslot=0x2F951,
+ },
+ [0x2F952]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25626 },
+ unicodeslot=0x2F952,
+ },
+ [0x2F953]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7956 },
+ unicodeslot=0x2F953,
+ },
+ [0x2F954]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2569A },
+ unicodeslot=0x2F954,
+ },
+ [0x2F955]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x256C5 },
+ unicodeslot=0x2F955,
+ },
+ [0x2F956]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x798F },
+ unicodeslot=0x2F956,
+ },
+ [0x2F957]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x79EB },
+ unicodeslot=0x2F957,
+ },
+ [0x2F958]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x412F },
+ unicodeslot=0x2F958,
+ },
+ [0x2F959]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7A40 },
+ unicodeslot=0x2F959,
+ },
+ [0x2F95A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7A4A },
+ unicodeslot=0x2F95A,
+ },
+ [0x2F95B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7A4F },
+ unicodeslot=0x2F95B,
+ },
+ [0x2F95C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2597C },
+ unicodeslot=0x2F95C,
+ },
+ [0x2F95D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25AA7 },
+ unicodeslot=0x2F95D,
+ },
+ [0x2F95E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25AA7 },
+ unicodeslot=0x2F95E,
+ },
+ [0x2F95F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7AEE },
+ unicodeslot=0x2F95F,
+ },
+ [0x2F960]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4202 },
+ unicodeslot=0x2F960,
+ },
+ [0x2F961]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25BAB },
+ unicodeslot=0x2F961,
+ },
+ [0x2F962]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7BC6 },
+ unicodeslot=0x2F962,
+ },
+ [0x2F963]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7BC9 },
+ unicodeslot=0x2F963,
+ },
+ [0x2F964]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4227 },
+ unicodeslot=0x2F964,
+ },
+ [0x2F965]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25C80 },
+ unicodeslot=0x2F965,
+ },
+ [0x2F966]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7CD2 },
+ unicodeslot=0x2F966,
+ },
+ [0x2F967]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x42A0 },
+ unicodeslot=0x2F967,
+ },
+ [0x2F968]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7CE8 },
+ unicodeslot=0x2F968,
+ },
+ [0x2F969]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7CE3 },
+ unicodeslot=0x2F969,
+ },
+ [0x2F96A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7D00 },
+ unicodeslot=0x2F96A,
+ },
+ [0x2F96B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25F86 },
+ unicodeslot=0x2F96B,
+ },
+ [0x2F96C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7D63 },
+ unicodeslot=0x2F96C,
+ },
+ [0x2F96D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4301 },
+ unicodeslot=0x2F96D,
+ },
+ [0x2F96E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7DC7 },
+ unicodeslot=0x2F96E,
+ },
+ [0x2F96F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7E02 },
+ unicodeslot=0x2F96F,
+ },
+ [0x2F970]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7E45 },
+ unicodeslot=0x2F970,
+ },
+ [0x2F971]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4334 },
+ unicodeslot=0x2F971,
+ },
+ [0x2F972]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26228 },
+ unicodeslot=0x2F972,
+ },
+ [0x2F973]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26247 },
+ unicodeslot=0x2F973,
+ },
+ [0x2F974]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4359 },
+ unicodeslot=0x2F974,
+ },
+ [0x2F975]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x262D9 },
+ unicodeslot=0x2F975,
+ },
+ [0x2F976]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F7A },
+ unicodeslot=0x2F976,
+ },
+ [0x2F977]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2633E },
+ unicodeslot=0x2F977,
+ },
+ [0x2F978]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F95 },
+ unicodeslot=0x2F978,
+ },
+ [0x2F979]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7FFA },
+ unicodeslot=0x2F979,
+ },
+ [0x2F97A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8005 },
+ unicodeslot=0x2F97A,
+ },
+ [0x2F97B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x264DA },
+ unicodeslot=0x2F97B,
+ },
+ [0x2F97C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26523 },
+ unicodeslot=0x2F97C,
+ },
+ [0x2F97D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8060 },
+ unicodeslot=0x2F97D,
+ },
+ [0x2F97E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x265A8 },
+ unicodeslot=0x2F97E,
+ },
+ [0x2F97F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8070 },
+ unicodeslot=0x2F97F,
+ },
+ [0x2F980]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2335F },
+ unicodeslot=0x2F980,
+ },
+ [0x2F981]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x43D5 },
+ unicodeslot=0x2F981,
+ },
+ [0x2F982]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x80B2 },
+ unicodeslot=0x2F982,
+ },
+ [0x2F983]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8103 },
+ unicodeslot=0x2F983,
+ },
+ [0x2F984]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x440B },
+ unicodeslot=0x2F984,
+ },
+ [0x2F985]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x813E },
+ unicodeslot=0x2F985,
+ },
+ [0x2F986]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5AB5 },
+ unicodeslot=0x2F986,
+ },
+ [0x2F987]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x267A7 },
+ unicodeslot=0x2F987,
+ },
+ [0x2F988]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x267B5 },
+ unicodeslot=0x2F988,
+ },
+ [0x2F989]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23393 },
+ unicodeslot=0x2F989,
+ },
+ [0x2F98A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2339C },
+ unicodeslot=0x2F98A,
+ },
+ [0x2F98B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8201 },
+ unicodeslot=0x2F98B,
+ },
+ [0x2F98C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8204 },
+ unicodeslot=0x2F98C,
+ },
+ [0x2F98D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F9E },
+ unicodeslot=0x2F98D,
+ },
+ [0x2F98E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x446B },
+ unicodeslot=0x2F98E,
+ },
+ [0x2F98F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8291 },
+ unicodeslot=0x2F98F,
+ },
+ [0x2F990]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x828B },
+ unicodeslot=0x2F990,
+ },
+ [0x2F991]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x829D },
+ unicodeslot=0x2F991,
+ },
+ [0x2F992]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52B3 },
+ unicodeslot=0x2F992,
+ },
+ [0x2F993]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x82B1 },
+ unicodeslot=0x2F993,
+ },
+ [0x2F994]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x82B3 },
+ unicodeslot=0x2F994,
+ },
+ [0x2F995]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x82BD },
+ unicodeslot=0x2F995,
+ },
+ [0x2F996]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x82E6 },
+ unicodeslot=0x2F996,
+ },
+ [0x2F997]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26B3C },
+ unicodeslot=0x2F997,
+ },
+ [0x2F998]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x82E5 },
+ unicodeslot=0x2F998,
+ },
+ [0x2F999]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x831D },
+ unicodeslot=0x2F999,
+ },
+ [0x2F99A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8363 },
+ unicodeslot=0x2F99A,
+ },
+ [0x2F99B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83AD },
+ unicodeslot=0x2F99B,
+ },
+ [0x2F99C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8323 },
+ unicodeslot=0x2F99C,
+ },
+ [0x2F99D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83BD },
+ unicodeslot=0x2F99D,
+ },
+ [0x2F99E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83E7 },
+ unicodeslot=0x2F99E,
+ },
+ [0x2F99F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8457 },
+ unicodeslot=0x2F99F,
+ },
+ [0x2F9A0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8353 },
+ unicodeslot=0x2F9A0,
+ },
+ [0x2F9A1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83CA },
+ unicodeslot=0x2F9A1,
+ },
+ [0x2F9A2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83CC },
+ unicodeslot=0x2F9A2,
+ },
+ [0x2F9A3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83DC },
+ unicodeslot=0x2F9A3,
+ },
+ [0x2F9A4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26C36 },
+ unicodeslot=0x2F9A4,
+ },
+ [0x2F9A5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26D6B },
+ unicodeslot=0x2F9A5,
+ },
+ [0x2F9A6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26CD5 },
+ unicodeslot=0x2F9A6,
+ },
+ [0x2F9A7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x452B },
+ unicodeslot=0x2F9A7,
+ },
+ [0x2F9A8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x84F1 },
+ unicodeslot=0x2F9A8,
+ },
+ [0x2F9A9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x84F3 },
+ unicodeslot=0x2F9A9,
+ },
+ [0x2F9AA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8516 },
+ unicodeslot=0x2F9AA,
+ },
+ [0x2F9AB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x273CA },
+ unicodeslot=0x2F9AB,
+ },
+ [0x2F9AC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8564 },
+ unicodeslot=0x2F9AC,
+ },
+ [0x2F9AD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26F2C },
+ unicodeslot=0x2F9AD,
+ },
+ [0x2F9AE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x455D },
+ unicodeslot=0x2F9AE,
+ },
+ [0x2F9AF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4561 },
+ unicodeslot=0x2F9AF,
+ },
+ [0x2F9B0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26FB1 },
+ unicodeslot=0x2F9B0,
+ },
+ [0x2F9B1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x270D2 },
+ unicodeslot=0x2F9B1,
+ },
+ [0x2F9B2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x456B },
+ unicodeslot=0x2F9B2,
+ },
+ [0x2F9B3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8650 },
+ unicodeslot=0x2F9B3,
+ },
+ [0x2F9B4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x865C },
+ unicodeslot=0x2F9B4,
+ },
+ [0x2F9B5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8667 },
+ unicodeslot=0x2F9B5,
+ },
+ [0x2F9B6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8669 },
+ unicodeslot=0x2F9B6,
+ },
+ [0x2F9B7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x86A9 },
+ unicodeslot=0x2F9B7,
+ },
+ [0x2F9B8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8688 },
+ unicodeslot=0x2F9B8,
+ },
+ [0x2F9B9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x870E },
+ unicodeslot=0x2F9B9,
+ },
+ [0x2F9BA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x86E2 },
+ unicodeslot=0x2F9BA,
+ },
+ [0x2F9BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8779 },
+ unicodeslot=0x2F9BB,
+ },
+ [0x2F9BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8728 },
+ unicodeslot=0x2F9BC,
+ },
+ [0x2F9BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x876B },
+ unicodeslot=0x2F9BD,
+ },
+ [0x2F9BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8786 },
+ unicodeslot=0x2F9BE,
+ },
+ [0x2F9BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x45D7 },
+ unicodeslot=0x2F9BF,
+ },
+ [0x2F9C0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x87E1 },
+ unicodeslot=0x2F9C0,
+ },
+ [0x2F9C1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8801 },
+ unicodeslot=0x2F9C1,
+ },
+ [0x2F9C2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x45F9 },
+ unicodeslot=0x2F9C2,
+ },
+ [0x2F9C3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8860 },
+ unicodeslot=0x2F9C3,
+ },
+ [0x2F9C4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8863 },
+ unicodeslot=0x2F9C4,
+ },
+ [0x2F9C5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x27667 },
+ unicodeslot=0x2F9C5,
+ },
+ [0x2F9C6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88D7 },
+ unicodeslot=0x2F9C6,
+ },
+ [0x2F9C7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88DE },
+ unicodeslot=0x2F9C7,
+ },
+ [0x2F9C8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4635 },
+ unicodeslot=0x2F9C8,
+ },
+ [0x2F9C9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88FA },
+ unicodeslot=0x2F9C9,
+ },
+ [0x2F9CA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x34BB },
+ unicodeslot=0x2F9CA,
+ },
+ [0x2F9CB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x278AE },
+ unicodeslot=0x2F9CB,
+ },
+ [0x2F9CC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x27966 },
+ unicodeslot=0x2F9CC,
+ },
+ [0x2F9CD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x46BE },
+ unicodeslot=0x2F9CD,
+ },
+ [0x2F9CE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x46C7 },
+ unicodeslot=0x2F9CE,
+ },
+ [0x2F9CF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AA0 },
+ unicodeslot=0x2F9CF,
+ },
+ [0x2F9D0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AED },
+ unicodeslot=0x2F9D0,
+ },
+ [0x2F9D1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B8A },
+ unicodeslot=0x2F9D1,
+ },
+ [0x2F9D2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8C55 },
+ unicodeslot=0x2F9D2,
+ },
+ [0x2F9D3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x27CA8 },
+ unicodeslot=0x2F9D3,
+ },
+ [0x2F9D4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8CAB },
+ unicodeslot=0x2F9D4,
+ },
+ [0x2F9D5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8CC1 },
+ unicodeslot=0x2F9D5,
+ },
+ [0x2F9D6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8D1B },
+ unicodeslot=0x2F9D6,
+ },
+ [0x2F9D7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8D77 },
+ unicodeslot=0x2F9D7,
+ },
+ [0x2F9D8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x27F2F },
+ unicodeslot=0x2F9D8,
+ },
+ [0x2F9D9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x20804 },
+ unicodeslot=0x2F9D9,
+ },
+ [0x2F9DA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8DCB },
+ unicodeslot=0x2F9DA,
+ },
+ [0x2F9DB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8DBC },
+ unicodeslot=0x2F9DB,
+ },
+ [0x2F9DC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8DF0 },
+ unicodeslot=0x2F9DC,
+ },
+ [0x2F9DD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x208DE },
+ unicodeslot=0x2F9DD,
+ },
+ [0x2F9DE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8ED4 },
+ unicodeslot=0x2F9DE,
+ },
+ [0x2F9DF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F38 },
+ unicodeslot=0x2F9DF,
+ },
+ [0x2F9E0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x285D2 },
+ unicodeslot=0x2F9E0,
+ },
+ [0x2F9E1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x285ED },
+ unicodeslot=0x2F9E1,
+ },
+ [0x2F9E2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9094 },
+ unicodeslot=0x2F9E2,
+ },
+ [0x2F9E3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x90F1 },
+ unicodeslot=0x2F9E3,
+ },
+ [0x2F9E4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9111 },
+ unicodeslot=0x2F9E4,
+ },
+ [0x2F9E5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2872E },
+ unicodeslot=0x2F9E5,
+ },
+ [0x2F9E6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x911B },
+ unicodeslot=0x2F9E6,
+ },
+ [0x2F9E7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9238 },
+ unicodeslot=0x2F9E7,
+ },
+ [0x2F9E8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x92D7 },
+ unicodeslot=0x2F9E8,
+ },
+ [0x2F9E9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x92D8 },
+ unicodeslot=0x2F9E9,
+ },
+ [0x2F9EA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x927C },
+ unicodeslot=0x2F9EA,
+ },
+ [0x2F9EB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x93F9 },
+ unicodeslot=0x2F9EB,
+ },
+ [0x2F9EC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9415 },
+ unicodeslot=0x2F9EC,
+ },
+ [0x2F9ED]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x28BFA },
+ unicodeslot=0x2F9ED,
+ },
+ [0x2F9EE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x958B },
+ unicodeslot=0x2F9EE,
+ },
+ [0x2F9EF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4995 },
+ unicodeslot=0x2F9EF,
+ },
+ [0x2F9F0]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x95B7 },
+ unicodeslot=0x2F9F0,
+ },
+ [0x2F9F1]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x28D77 },
+ unicodeslot=0x2F9F1,
+ },
+ [0x2F9F2]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x49E6 },
+ unicodeslot=0x2F9F2,
+ },
+ [0x2F9F3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96C3 },
+ unicodeslot=0x2F9F3,
+ },
+ [0x2F9F4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5DB2 },
+ unicodeslot=0x2F9F4,
+ },
+ [0x2F9F5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9723 },
+ unicodeslot=0x2F9F5,
+ },
+ [0x2F9F6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x29145 },
+ unicodeslot=0x2F9F6,
+ },
+ [0x2F9F7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2921A },
+ unicodeslot=0x2F9F7,
+ },
+ [0x2F9F8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4A6E },
+ unicodeslot=0x2F9F8,
+ },
+ [0x2F9F9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4A76 },
+ unicodeslot=0x2F9F9,
+ },
+ [0x2F9FA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x97E0 },
+ unicodeslot=0x2F9FA,
+ },
+ [0x2F9FB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2940A },
+ unicodeslot=0x2F9FB,
+ },
+ [0x2F9FC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4AB2 },
+ unicodeslot=0x2F9FC,
+ },
+ [0x2F9FD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x29496 },
+ unicodeslot=0x2F9FD,
+ },
+ [0x2F9FE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x980B },
+ unicodeslot=0x2F9FE,
+ },
+ [0x2F9FF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x980B },
+ unicodeslot=0x2F9FF,
+ },
+ [0x2FA00]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9829 },
+ unicodeslot=0x2FA00,
+ },
+ [0x2FA01]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x295B6 },
+ unicodeslot=0x2FA01,
+ },
+ [0x2FA02]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x98E2 },
+ unicodeslot=0x2FA02,
+ },
+ [0x2FA03]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4B33 },
+ unicodeslot=0x2FA03,
+ },
+ [0x2FA04]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9929 },
+ unicodeslot=0x2FA04,
+ },
+ [0x2FA05]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x99A7 },
+ unicodeslot=0x2FA05,
+ },
+ [0x2FA06]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x99C2 },
+ unicodeslot=0x2FA06,
+ },
+ [0x2FA07]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x99FE },
+ unicodeslot=0x2FA07,
+ },
+ [0x2FA08]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4BCE },
+ unicodeslot=0x2FA08,
+ },
+ [0x2FA09]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x29B30 },
+ unicodeslot=0x2FA09,
+ },
+ [0x2FA0A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9B12 },
+ unicodeslot=0x2FA0A,
+ },
+ [0x2FA0B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9C40 },
+ unicodeslot=0x2FA0B,
+ },
+ [0x2FA0C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9CFD },
+ unicodeslot=0x2FA0C,
+ },
+ [0x2FA0D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4CCE },
+ unicodeslot=0x2FA0D,
+ },
+ [0x2FA0E]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4CED },
+ unicodeslot=0x2FA0E,
+ },
+ [0x2FA0F]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9D67 },
+ unicodeslot=0x2FA0F,
+ },
+ [0x2FA10]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2A0CE },
+ unicodeslot=0x2FA10,
+ },
+ [0x2FA11]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4CF8 },
+ unicodeslot=0x2FA11,
+ },
+ [0x2FA12]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2A105 },
+ unicodeslot=0x2FA12,
+ },
+ [0x2FA13]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2A20E },
+ unicodeslot=0x2FA13,
+ },
+ [0x2FA14]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2A291 },
+ unicodeslot=0x2FA14,
+ },
+ [0x2FA15]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9EBB },
+ unicodeslot=0x2FA15,
+ },
+ [0x2FA16]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4D56 },
+ unicodeslot=0x2FA16,
+ },
+ [0x2FA17]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9EF9 },
+ unicodeslot=0x2FA17,
+ },
+ [0x2FA18]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9EFE },
+ unicodeslot=0x2FA18,
+ },
+ [0x2FA19]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F05 },
+ unicodeslot=0x2FA19,
+ },
+ [0x2FA1A]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F0F },
+ unicodeslot=0x2FA1A,
+ },
+ [0x2FA1B]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F16 },
+ unicodeslot=0x2FA1B,
+ },
+ [0x2FA1C]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F3B },
+ unicodeslot=0x2FA1C,
+ },
+ [0x2FA1D]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2A600 },
+ unicodeslot=0x2FA1D,
+ },
+ [0xE0001]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0001,
+ },
+ [0xE0020]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0020,
+ },
+ [0xE0021]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0021,
+ },
+ [0xE0022]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0022,
+ },
+ [0xE0023]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0023,
+ },
+ [0xE0024]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0024,
+ },
+ [0xE0025]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0025,
+ },
+ [0xE0026]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0026,
+ },
+ [0xE0027]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0027,
+ },
+ [0xE0028]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0028,
+ },
+ [0xE0029]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0029,
+ },
+ [0xE002A]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE002A,
+ },
+ [0xE002B]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE002B,
+ },
+ [0xE002C]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE002C,
+ },
+ [0xE002D]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE002D,
+ },
+ [0xE002E]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE002E,
+ },
+ [0xE002F]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE002F,
+ },
+ [0xE0030]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0030,
+ },
+ [0xE0031]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0031,
+ },
+ [0xE0032]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0032,
+ },
+ [0xE0033]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0033,
+ },
+ [0xE0034]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0034,
+ },
+ [0xE0035]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0035,
+ },
+ [0xE0036]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0036,
+ },
+ [0xE0037]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0037,
+ },
+ [0xE0038]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0038,
+ },
+ [0xE0039]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0039,
+ },
+ [0xE003A]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE003A,
+ },
+ [0xE003B]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE003B,
+ },
+ [0xE003C]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE003C,
+ },
+ [0xE003D]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE003D,
+ },
+ [0xE003E]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE003E,
+ },
+ [0xE003F]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE003F,
+ },
+ [0xE0040]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0040,
+ },
+ [0xE0041]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0041,
+ },
+ [0xE0042]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0042,
+ },
+ [0xE0043]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0043,
+ },
+ [0xE0044]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0044,
+ },
+ [0xE0045]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0045,
+ },
+ [0xE0046]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0046,
+ },
+ [0xE0047]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0047,
+ },
+ [0xE0048]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0048,
+ },
+ [0xE0049]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0049,
+ },
+ [0xE004A]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE004A,
+ },
+ [0xE004B]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE004B,
+ },
+ [0xE004C]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE004C,
+ },
+ [0xE004D]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE004D,
+ },
+ [0xE004E]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE004E,
+ },
+ [0xE004F]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE004F,
+ },
+ [0xE0050]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0050,
+ },
+ [0xE0051]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0051,
+ },
+ [0xE0052]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0052,
+ },
+ [0xE0053]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0053,
+ },
+ [0xE0054]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0054,
+ },
+ [0xE0055]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0055,
+ },
+ [0xE0056]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0056,
+ },
+ [0xE0057]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0057,
+ },
+ [0xE0058]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0058,
+ },
+ [0xE0059]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0059,
+ },
+ [0xE005A]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE005A,
+ },
+ [0xE005B]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE005B,
+ },
+ [0xE005C]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE005C,
+ },
+ [0xE005D]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE005D,
+ },
+ [0xE005E]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE005E,
+ },
+ [0xE005F]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE005F,
+ },
+ [0xE0060]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0060,
+ },
+ [0xE0061]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0061,
+ },
+ [0xE0062]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0062,
+ },
+ [0xE0063]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0063,
+ },
+ [0xE0064]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0064,
+ },
+ [0xE0065]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0065,
+ },
+ [0xE0066]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0066,
+ },
+ [0xE0067]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0067,
+ },
+ [0xE0068]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0068,
+ },
+ [0xE0069]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0069,
+ },
+ [0xE006A]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE006A,
+ },
+ [0xE006B]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE006B,
+ },
+ [0xE006C]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE006C,
+ },
+ [0xE006D]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE006D,
+ },
+ [0xE006E]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE006E,
+ },
+ [0xE006F]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE006F,
+ },
+ [0xE0070]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0070,
+ },
+ [0xE0071]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0071,
+ },
+ [0xE0072]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0072,
+ },
+ [0xE0073]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0073,
+ },
+ [0xE0074]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0074,
+ },
+ [0xE0075]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0075,
+ },
+ [0xE0076]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0076,
+ },
+ [0xE0077]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0077,
+ },
+ [0xE0078]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0078,
+ },
+ [0xE0079]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0079,
+ },
+ [0xE007A]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE007A,
+ },
+ [0xE007B]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE007B,
+ },
+ [0xE007C]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE007C,
+ },
+ [0xE007D]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE007D,
+ },
+ [0xE007E]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE007E,
+ },
+ [0xE007F]={
+ category="cf",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE007F,
+ },
+ [0xE0100]={
+ unicodeslot=0xE0100,
+ },
+ characters={},
+ classifiers={
+ [0x600]=0x4,
+ [0x601]=0x4,
+ [0x602]=0x4,
+ [0x603]=0x4,
+ [0x604]=0x4,
+ [0x605]=0x4,
+ [0x606]=0x6,
+ [0x607]=0x6,
+ [0x608]=0x4,
+ [0x609]=0x6,
+ [0x60A]=0x6,
+ [0x60B]=0x4,
+ [0x60C]=0x6,
+ [0x60D]=0x6,
+ [0x60E]=0x6,
+ [0x60F]=0x6,
+ [0x610]=0x5,
+ [0x611]=0x5,
+ [0x612]=0x5,
+ [0x613]=0x5,
+ [0x614]=0x5,
+ [0x615]=0x5,
+ [0x616]=0x5,
+ [0x617]=0x5,
+ [0x618]=0x5,
+ [0x619]=0x5,
+ [0x61A]=0x5,
+ [0x61B]=0x6,
+ [0x61C]=0x6,
+ [0x61E]=0x6,
+ [0x61F]=0x6,
+ [0x620]=0x2,
+ [0x621]=0x4,
+ [0x622]=0x3,
+ [0x623]=0x3,
+ [0x624]=0x3,
+ [0x625]=0x3,
+ [0x626]=0x2,
+ [0x627]=0x3,
+ [0x628]=0x2,
+ [0x629]=0x3,
+ [0x62A]=0x2,
+ [0x62B]=0x2,
+ [0x62C]=0x2,
+ [0x62D]=0x2,
+ [0x62E]=0x2,
+ [0x62F]=0x3,
+ [0x630]=0x3,
+ [0x631]=0x3,
+ [0x632]=0x3,
+ [0x633]=0x2,
+ [0x634]=0x2,
+ [0x635]=0x2,
+ [0x636]=0x2,
+ [0x637]=0x2,
+ [0x638]=0x2,
+ [0x639]=0x2,
+ [0x63A]=0x2,
+ [0x63B]=0x2,
+ [0x63C]=0x2,
+ [0x63D]=0x2,
+ [0x63E]=0x2,
+ [0x63F]=0x2,
+ [0x640]=0x2,
+ [0x641]=0x2,
+ [0x642]=0x2,
+ [0x643]=0x2,
+ [0x644]=0x2,
+ [0x645]=0x2,
+ [0x646]=0x2,
+ [0x647]=0x2,
+ [0x648]=0x3,
+ [0x649]=0x2,
+ [0x64A]=0x2,
+ [0x64B]=0x5,
+ [0x64C]=0x5,
+ [0x64D]=0x5,
+ [0x64E]=0x5,
+ [0x64F]=0x5,
+ [0x650]=0x5,
+ [0x651]=0x5,
+ [0x652]=0x5,
+ [0x653]=0x5,
+ [0x654]=0x5,
+ [0x655]=0x5,
+ [0x656]=0x5,
+ [0x657]=0x5,
+ [0x658]=0x5,
+ [0x659]=0x5,
+ [0x65A]=0x5,
+ [0x65B]=0x5,
+ [0x65C]=0x5,
+ [0x65D]=0x5,
+ [0x65E]=0x5,
+ [0x65F]=0x5,
+ [0x660]=0x6,
+ [0x661]=0x6,
+ [0x662]=0x6,
+ [0x663]=0x6,
+ [0x664]=0x6,
+ [0x665]=0x6,
+ [0x666]=0x6,
+ [0x667]=0x6,
+ [0x668]=0x6,
+ [0x669]=0x6,
+ [0x66A]=0x6,
+ [0x66B]=0x6,
+ [0x66C]=0x6,
+ [0x66D]=0x6,
+ [0x66E]=0x2,
+ [0x66F]=0x2,
+ [0x670]=0x5,
+ [0x671]=0x3,
+ [0x672]=0x3,
+ [0x673]=0x3,
+ [0x674]=0x4,
+ [0x675]=0x3,
+ [0x676]=0x3,
+ [0x677]=0x3,
+ [0x678]=0x2,
+ [0x679]=0x2,
+ [0x67A]=0x2,
+ [0x67B]=0x2,
+ [0x67C]=0x2,
+ [0x67D]=0x2,
+ [0x67E]=0x2,
+ [0x67F]=0x2,
+ [0x680]=0x2,
+ [0x681]=0x2,
+ [0x682]=0x2,
+ [0x683]=0x2,
+ [0x684]=0x2,
+ [0x685]=0x2,
+ [0x686]=0x2,
+ [0x687]=0x2,
+ [0x688]=0x3,
+ [0x689]=0x3,
+ [0x68A]=0x3,
+ [0x68B]=0x3,
+ [0x68C]=0x3,
+ [0x68D]=0x3,
+ [0x68E]=0x3,
+ [0x68F]=0x3,
+ [0x690]=0x3,
+ [0x691]=0x3,
+ [0x692]=0x3,
+ [0x693]=0x3,
+ [0x694]=0x3,
+ [0x695]=0x3,
+ [0x696]=0x3,
+ [0x697]=0x3,
+ [0x698]=0x3,
+ [0x699]=0x3,
+ [0x69A]=0x2,
+ [0x69B]=0x2,
+ [0x69C]=0x2,
+ [0x69D]=0x2,
+ [0x69E]=0x2,
+ [0x69F]=0x2,
+ [0x6A0]=0x2,
+ [0x6A1]=0x2,
+ [0x6A2]=0x2,
+ [0x6A3]=0x2,
+ [0x6A4]=0x2,
+ [0x6A5]=0x2,
+ [0x6A6]=0x2,
+ [0x6A7]=0x2,
+ [0x6A8]=0x2,
+ [0x6A9]=0x2,
+ [0x6AA]=0x2,
+ [0x6AB]=0x2,
+ [0x6AC]=0x2,
+ [0x6AD]=0x2,
+ [0x6AE]=0x2,
+ [0x6AF]=0x2,
+ [0x6B0]=0x2,
+ [0x6B1]=0x2,
+ [0x6B2]=0x2,
+ [0x6B3]=0x2,
+ [0x6B4]=0x2,
+ [0x6B5]=0x2,
+ [0x6B6]=0x2,
+ [0x6B7]=0x2,
+ [0x6B8]=0x2,
+ [0x6B9]=0x2,
+ [0x6BA]=0x2,
+ [0x6BB]=0x2,
+ [0x6BC]=0x2,
+ [0x6BD]=0x2,
+ [0x6BE]=0x2,
+ [0x6BF]=0x2,
+ [0x6C0]=0x3,
+ [0x6C1]=0x2,
+ [0x6C2]=0x2,
+ [0x6C3]=0x3,
+ [0x6C4]=0x3,
+ [0x6C5]=0x3,
+ [0x6C6]=0x3,
+ [0x6C7]=0x3,
+ [0x6C8]=0x3,
+ [0x6C9]=0x3,
+ [0x6CA]=0x3,
+ [0x6CB]=0x3,
+ [0x6CC]=0x2,
+ [0x6CD]=0x3,
+ [0x6CE]=0x2,
+ [0x6CF]=0x3,
+ [0x6D0]=0x2,
+ [0x6D1]=0x2,
+ [0x6D2]=0x3,
+ [0x6D3]=0x3,
+ [0x6D4]=0x6,
+ [0x6D5]=0x3,
+ [0x6D6]=0x5,
+ [0x6D7]=0x5,
+ [0x6D8]=0x5,
+ [0x6D9]=0x5,
+ [0x6DA]=0x5,
+ [0x6DB]=0x5,
+ [0x6DC]=0x5,
+ [0x6DD]=0x4,
+ [0x6DE]=0x6,
+ [0x6DF]=0x5,
+ [0x6E0]=0x5,
+ [0x6E1]=0x5,
+ [0x6E2]=0x5,
+ [0x6E3]=0x5,
+ [0x6E4]=0x5,
+ [0x6E5]=0x6,
+ [0x6E6]=0x6,
+ [0x6E7]=0x5,
+ [0x6E8]=0x5,
+ [0x6E9]=0x6,
+ [0x6EA]=0x5,
+ [0x6EB]=0x5,
+ [0x6EC]=0x5,
+ [0x6ED]=0x5,
+ [0x6EE]=0x3,
+ [0x6EF]=0x3,
+ [0x6F0]=0x6,
+ [0x6F1]=0x6,
+ [0x6F2]=0x6,
+ [0x6F3]=0x6,
+ [0x6F4]=0x6,
+ [0x6F5]=0x6,
+ [0x6F6]=0x6,
+ [0x6F7]=0x6,
+ [0x6F8]=0x6,
+ [0x6F9]=0x6,
+ [0x6FA]=0x2,
+ [0x6FB]=0x2,
+ [0x6FC]=0x2,
+ [0x6FD]=0x6,
+ [0x6FE]=0x6,
+ [0x6FF]=0x2,
+ [0x700]=0x6,
+ [0x701]=0x6,
+ [0x702]=0x6,
+ [0x703]=0x6,
+ [0x704]=0x6,
+ [0x705]=0x6,
+ [0x706]=0x6,
+ [0x707]=0x6,
+ [0x708]=0x6,
+ [0x709]=0x6,
+ [0x70A]=0x6,
+ [0x70B]=0x6,
+ [0x70C]=0x6,
+ [0x70D]=0x6,
+ [0x710]=0x3,
+ [0x711]=0x5,
+ [0x712]=0x2,
+ [0x713]=0x2,
+ [0x714]=0x2,
+ [0x715]=0x3,
+ [0x716]=0x3,
+ [0x717]=0x3,
+ [0x718]=0x3,
+ [0x719]=0x3,
+ [0x71A]=0x2,
+ [0x71B]=0x2,
+ [0x71C]=0x2,
+ [0x71D]=0x2,
+ [0x71E]=0x3,
+ [0x71F]=0x2,
+ [0x720]=0x2,
+ [0x721]=0x2,
+ [0x722]=0x2,
+ [0x723]=0x2,
+ [0x724]=0x2,
+ [0x725]=0x2,
+ [0x726]=0x2,
+ [0x727]=0x2,
+ [0x728]=0x3,
+ [0x729]=0x2,
+ [0x72A]=0x3,
+ [0x72B]=0x2,
+ [0x72C]=0x3,
+ [0x72D]=0x2,
+ [0x72E]=0x2,
+ [0x72F]=0x3,
+ [0x730]=0x5,
+ [0x731]=0x5,
+ [0x732]=0x5,
+ [0x733]=0x5,
+ [0x734]=0x5,
+ [0x735]=0x5,
+ [0x736]=0x5,
+ [0x737]=0x5,
+ [0x738]=0x5,
+ [0x739]=0x5,
+ [0x73A]=0x5,
+ [0x73B]=0x5,
+ [0x73C]=0x5,
+ [0x73D]=0x5,
+ [0x73E]=0x5,
+ [0x73F]=0x5,
+ [0x740]=0x5,
+ [0x741]=0x5,
+ [0x742]=0x5,
+ [0x743]=0x5,
+ [0x744]=0x5,
+ [0x745]=0x5,
+ [0x746]=0x5,
+ [0x747]=0x5,
+ [0x748]=0x5,
+ [0x749]=0x5,
+ [0x74A]=0x5,
+ [0x74D]=0x3,
+ [0x74E]=0x2,
+ [0x74F]=0x2,
+ [0x750]=0x2,
+ [0x751]=0x2,
+ [0x752]=0x2,
+ [0x753]=0x2,
+ [0x754]=0x2,
+ [0x755]=0x2,
+ [0x756]=0x2,
+ [0x757]=0x2,
+ [0x758]=0x2,
+ [0x759]=0x3,
+ [0x75A]=0x3,
+ [0x75B]=0x3,
+ [0x75C]=0x2,
+ [0x75D]=0x2,
+ [0x75E]=0x2,
+ [0x75F]=0x2,
+ [0x760]=0x2,
+ [0x761]=0x2,
+ [0x762]=0x2,
+ [0x763]=0x2,
+ [0x764]=0x2,
+ [0x765]=0x2,
+ [0x766]=0x2,
+ [0x767]=0x2,
+ [0x768]=0x2,
+ [0x769]=0x2,
+ [0x76A]=0x2,
+ [0x76B]=0x3,
+ [0x76C]=0x3,
+ [0x76D]=0x2,
+ [0x76E]=0x2,
+ [0x76F]=0x2,
+ [0x770]=0x2,
+ [0x771]=0x3,
+ [0x772]=0x2,
+ [0x773]=0x3,
+ [0x774]=0x3,
+ [0x775]=0x2,
+ [0x776]=0x2,
+ [0x777]=0x2,
+ [0x778]=0x3,
+ [0x779]=0x3,
+ [0x77A]=0x2,
+ [0x77B]=0x2,
+ [0x77C]=0x2,
+ [0x77D]=0x2,
+ [0x77E]=0x2,
+ [0x77F]=0x2,
+ [0x7C0]=0x6,
+ [0x7C1]=0x6,
+ [0x7C2]=0x6,
+ [0x7C3]=0x6,
+ [0x7C4]=0x6,
+ [0x7C5]=0x6,
+ [0x7C6]=0x6,
+ [0x7C7]=0x6,
+ [0x7C8]=0x6,
+ [0x7C9]=0x6,
+ [0x7CA]=0x2,
+ [0x7CB]=0x2,
+ [0x7CC]=0x2,
+ [0x7CD]=0x2,
+ [0x7CE]=0x2,
+ [0x7CF]=0x2,
+ [0x7D0]=0x2,
+ [0x7D1]=0x2,
+ [0x7D2]=0x2,
+ [0x7D3]=0x2,
+ [0x7D4]=0x2,
+ [0x7D5]=0x2,
+ [0x7D6]=0x2,
+ [0x7D7]=0x2,
+ [0x7D8]=0x2,
+ [0x7D9]=0x2,
+ [0x7DA]=0x2,
+ [0x7DB]=0x2,
+ [0x7DC]=0x2,
+ [0x7DD]=0x2,
+ [0x7DE]=0x2,
+ [0x7DF]=0x2,
+ [0x7E0]=0x2,
+ [0x7E1]=0x2,
+ [0x7E2]=0x2,
+ [0x7E3]=0x2,
+ [0x7E4]=0x2,
+ [0x7E5]=0x2,
+ [0x7E6]=0x2,
+ [0x7E7]=0x2,
+ [0x7E8]=0x2,
+ [0x7E9]=0x2,
+ [0x7EA]=0x2,
+ [0x7EB]=0x5,
+ [0x7EC]=0x5,
+ [0x7ED]=0x5,
+ [0x7EE]=0x5,
+ [0x7EF]=0x5,
+ [0x7F0]=0x5,
+ [0x7F1]=0x5,
+ [0x7F2]=0x5,
+ [0x7F3]=0x5,
+ [0x7F4]=0x6,
+ [0x7F5]=0x6,
+ [0x7F6]=0x6,
+ [0x7F7]=0x6,
+ [0x7F8]=0x6,
+ [0x7F9]=0x6,
+ [0x7FA]=0x2,
+ [0x7FD]=0x5,
+ [0x7FE]=0x6,
+ [0x7FF]=0x6,
+ [0x840]=0x3,
+ [0x841]=0x2,
+ [0x842]=0x2,
+ [0x843]=0x2,
+ [0x844]=0x2,
+ [0x845]=0x2,
+ [0x846]=0x3,
+ [0x847]=0x3,
+ [0x848]=0x2,
+ [0x849]=0x3,
+ [0x84A]=0x2,
+ [0x84B]=0x2,
+ [0x84C]=0x2,
+ [0x84D]=0x2,
+ [0x84E]=0x2,
+ [0x84F]=0x2,
+ [0x850]=0x2,
+ [0x851]=0x2,
+ [0x852]=0x2,
+ [0x853]=0x2,
+ [0x854]=0x3,
+ [0x855]=0x2,
+ [0x856]=0x4,
+ [0x857]=0x4,
+ [0x858]=0x4,
+ [0x860]=0x2,
+ [0x861]=0x4,
+ [0x862]=0x2,
+ [0x863]=0x2,
+ [0x864]=0x2,
+ [0x865]=0x2,
+ [0x866]=0x4,
+ [0x867]=0x3,
+ [0x868]=0x2,
+ [0x869]=0x3,
+ [0x86A]=0x3,
+ [0x8A0]=0x2,
+ [0x8A1]=0x2,
+ [0x8A2]=0x2,
+ [0x8A3]=0x2,
+ [0x8A4]=0x2,
+ [0x8A5]=0x2,
+ [0x8A6]=0x2,
+ [0x8A7]=0x2,
+ [0x8A8]=0x2,
+ [0x8A9]=0x2,
+ [0x8AA]=0x3,
+ [0x8AB]=0x3,
+ [0x8AC]=0x3,
+ [0x8AD]=0x4,
+ [0x8AE]=0x3,
+ [0x8AF]=0x2,
+ [0x8B0]=0x2,
+ [0x8B1]=0x3,
+ [0x8B2]=0x3,
+ [0x8B3]=0x2,
+ [0x8B4]=0x2,
+ [0x8B6]=0x2,
+ [0x8B7]=0x2,
+ [0x8B8]=0x2,
+ [0x8B9]=0x3,
+ [0x8BA]=0x2,
+ [0x8BB]=0x2,
+ [0x8BC]=0x2,
+ [0x8BD]=0x2,
+ [0x8E2]=0x4,
+ [0x1806]=0x4,
+ [0x1807]=0x2,
+ [0x180A]=0x2,
+ [0x180E]=0x4,
+ [0x1820]=0x2,
+ [0x1821]=0x2,
+ [0x1822]=0x2,
+ [0x1823]=0x2,
+ [0x1824]=0x2,
+ [0x1825]=0x2,
+ [0x1826]=0x2,
+ [0x1827]=0x2,
+ [0x1828]=0x2,
+ [0x1829]=0x2,
+ [0x182A]=0x2,
+ [0x182B]=0x2,
+ [0x182C]=0x2,
+ [0x182D]=0x2,
+ [0x182E]=0x2,
+ [0x182F]=0x2,
+ [0x1830]=0x2,
+ [0x1831]=0x2,
+ [0x1832]=0x2,
+ [0x1833]=0x2,
+ [0x1834]=0x2,
+ [0x1835]=0x2,
+ [0x1836]=0x2,
+ [0x1837]=0x2,
+ [0x1838]=0x2,
+ [0x1839]=0x2,
+ [0x183A]=0x2,
+ [0x183B]=0x2,
+ [0x183C]=0x2,
+ [0x183D]=0x2,
+ [0x183E]=0x2,
+ [0x183F]=0x2,
+ [0x1840]=0x2,
+ [0x1841]=0x2,
+ [0x1842]=0x2,
+ [0x1843]=0x2,
+ [0x1844]=0x2,
+ [0x1845]=0x2,
+ [0x1846]=0x2,
+ [0x1847]=0x2,
+ [0x1848]=0x2,
+ [0x1849]=0x2,
+ [0x184A]=0x2,
+ [0x184B]=0x2,
+ [0x184C]=0x2,
+ [0x184D]=0x2,
+ [0x184E]=0x2,
+ [0x184F]=0x2,
+ [0x1850]=0x2,
+ [0x1851]=0x2,
+ [0x1852]=0x2,
+ [0x1853]=0x2,
+ [0x1854]=0x2,
+ [0x1855]=0x2,
+ [0x1856]=0x2,
+ [0x1857]=0x2,
+ [0x1858]=0x2,
+ [0x1859]=0x2,
+ [0x185A]=0x2,
+ [0x185B]=0x2,
+ [0x185C]=0x2,
+ [0x185D]=0x2,
+ [0x185E]=0x2,
+ [0x185F]=0x2,
+ [0x1860]=0x2,
+ [0x1861]=0x2,
+ [0x1862]=0x2,
+ [0x1863]=0x2,
+ [0x1864]=0x2,
+ [0x1865]=0x2,
+ [0x1866]=0x2,
+ [0x1867]=0x2,
+ [0x1868]=0x2,
+ [0x1869]=0x2,
+ [0x186A]=0x2,
+ [0x186B]=0x2,
+ [0x186C]=0x2,
+ [0x186D]=0x2,
+ [0x186E]=0x2,
+ [0x186F]=0x2,
+ [0x1870]=0x2,
+ [0x1871]=0x2,
+ [0x1872]=0x2,
+ [0x1873]=0x2,
+ [0x1874]=0x2,
+ [0x1875]=0x2,
+ [0x1876]=0x2,
+ [0x1877]=0x2,
+ [0x1878]=0x2,
+ [0x1880]=0x4,
+ [0x1881]=0x4,
+ [0x1882]=0x4,
+ [0x1883]=0x4,
+ [0x1884]=0x4,
+ [0x1887]=0x2,
+ [0x1888]=0x2,
+ [0x1889]=0x2,
+ [0x188A]=0x2,
+ [0x188B]=0x2,
+ [0x188C]=0x2,
+ [0x188D]=0x2,
+ [0x188E]=0x2,
+ [0x188F]=0x2,
+ [0x1890]=0x2,
+ [0x1891]=0x2,
+ [0x1892]=0x2,
+ [0x1893]=0x2,
+ [0x1894]=0x2,
+ [0x1895]=0x2,
+ [0x1896]=0x2,
+ [0x1897]=0x2,
+ [0x1898]=0x2,
+ [0x1899]=0x2,
+ [0x189A]=0x2,
+ [0x189B]=0x2,
+ [0x189C]=0x2,
+ [0x189D]=0x2,
+ [0x189E]=0x2,
+ [0x189F]=0x2,
+ [0x18A0]=0x2,
+ [0x18A1]=0x2,
+ [0x18A2]=0x2,
+ [0x18A3]=0x2,
+ [0x18A4]=0x2,
+ [0x18A5]=0x2,
+ [0x18A6]=0x2,
+ [0x18A7]=0x2,
+ [0x18A8]=0x2,
+ [0x18AA]=0x2,
+ [0x200C]=0x4,
+ [0x200D]=0x2,
+ [0x202F]=0x4,
+ [0x2066]=0x4,
+ [0x2067]=0x4,
+ [0x2068]=0x4,
+ [0x2069]=0x4,
+ [0xA840]=0x2,
+ [0xA841]=0x2,
+ [0xA842]=0x2,
+ [0xA843]=0x2,
+ [0xA844]=0x2,
+ [0xA845]=0x2,
+ [0xA846]=0x2,
+ [0xA847]=0x2,
+ [0xA848]=0x2,
+ [0xA849]=0x2,
+ [0xA84A]=0x2,
+ [0xA84B]=0x2,
+ [0xA84C]=0x2,
+ [0xA84D]=0x2,
+ [0xA84E]=0x2,
+ [0xA84F]=0x2,
+ [0xA850]=0x2,
+ [0xA851]=0x2,
+ [0xA852]=0x2,
+ [0xA853]=0x2,
+ [0xA854]=0x2,
+ [0xA855]=0x2,
+ [0xA856]=0x2,
+ [0xA857]=0x2,
+ [0xA858]=0x2,
+ [0xA859]=0x2,
+ [0xA85A]=0x2,
+ [0xA85B]=0x2,
+ [0xA85C]=0x2,
+ [0xA85D]=0x2,
+ [0xA85E]=0x2,
+ [0xA85F]=0x2,
+ [0xA860]=0x2,
+ [0xA861]=0x2,
+ [0xA862]=0x2,
+ [0xA863]=0x2,
+ [0xA864]=0x2,
+ [0xA865]=0x2,
+ [0xA866]=0x2,
+ [0xA867]=0x2,
+ [0xA868]=0x2,
+ [0xA869]=0x2,
+ [0xA86A]=0x2,
+ [0xA86B]=0x2,
+ [0xA86C]=0x2,
+ [0xA86D]=0x2,
+ [0xA86E]=0x2,
+ [0xA86F]=0x2,
+ [0xA870]=0x2,
+ [0xA871]=0x2,
+ [0xA872]=0x1,
+ [0xA873]=0x4,
+ [0x10AC0]=0x2,
+ [0x10AC1]=0x2,
+ [0x10AC2]=0x2,
+ [0x10AC3]=0x2,
+ [0x10AC4]=0x2,
+ [0x10AC5]=0x3,
+ [0x10AC6]=0x4,
+ [0x10AC7]=0x3,
+ [0x10AC8]=0x4,
+ [0x10AC9]=0x3,
+ [0x10ACA]=0x3,
+ [0x10ACB]=0x4,
+ [0x10ACC]=0x4,
+ [0x10ACD]=0x1,
+ [0x10ACE]=0x3,
+ [0x10ACF]=0x3,
+ [0x10AD0]=0x3,
+ [0x10AD1]=0x3,
+ [0x10AD2]=0x3,
+ [0x10AD3]=0x2,
+ [0x10AD4]=0x2,
+ [0x10AD5]=0x2,
+ [0x10AD6]=0x2,
+ [0x10AD7]=0x1,
+ [0x10AD8]=0x2,
+ [0x10AD9]=0x2,
+ [0x10ADA]=0x2,
+ [0x10ADB]=0x2,
+ [0x10ADC]=0x2,
+ [0x10ADD]=0x3,
+ [0x10ADE]=0x2,
+ [0x10ADF]=0x2,
+ [0x10AE0]=0x2,
+ [0x10AE1]=0x3,
+ [0x10AE2]=0x4,
+ [0x10AE3]=0x4,
+ [0x10AE4]=0x3,
+ [0x10AEB]=0x2,
+ [0x10AEC]=0x2,
+ [0x10AED]=0x2,
+ [0x10AEE]=0x2,
+ [0x10AEF]=0x3,
+ [0x10B80]=0x2,
+ [0x10B81]=0x3,
+ [0x10B82]=0x2,
+ [0x10B83]=0x3,
+ [0x10B84]=0x3,
+ [0x10B85]=0x3,
+ [0x10B86]=0x2,
+ [0x10B87]=0x2,
+ [0x10B88]=0x2,
+ [0x10B89]=0x3,
+ [0x10B8A]=0x2,
+ [0x10B8B]=0x2,
+ [0x10B8C]=0x3,
+ [0x10B8D]=0x2,
+ [0x10B8E]=0x3,
+ [0x10B8F]=0x3,
+ [0x10B90]=0x2,
+ [0x10B91]=0x3,
+ [0x10BA9]=0x3,
+ [0x10BAA]=0x3,
+ [0x10BAB]=0x3,
+ [0x10BAC]=0x3,
+ [0x10BAD]=0x2,
+ [0x10BAE]=0x2,
+ [0x10BAF]=0x4,
+ [0x10D00]=0x1,
+ [0x10D01]=0x2,
+ [0x10D02]=0x2,
+ [0x10D03]=0x2,
+ [0x10D04]=0x2,
+ [0x10D05]=0x2,
+ [0x10D06]=0x2,
+ [0x10D07]=0x2,
+ [0x10D08]=0x2,
+ [0x10D09]=0x2,
+ [0x10D0A]=0x2,
+ [0x10D0B]=0x2,
+ [0x10D0C]=0x2,
+ [0x10D0D]=0x2,
+ [0x10D0E]=0x2,
+ [0x10D0F]=0x2,
+ [0x10D10]=0x2,
+ [0x10D11]=0x2,
+ [0x10D12]=0x2,
+ [0x10D13]=0x2,
+ [0x10D14]=0x2,
+ [0x10D15]=0x2,
+ [0x10D16]=0x2,
+ [0x10D17]=0x2,
+ [0x10D18]=0x2,
+ [0x10D19]=0x2,
+ [0x10D1A]=0x2,
+ [0x10D1B]=0x2,
+ [0x10D1C]=0x2,
+ [0x10D1D]=0x2,
+ [0x10D1E]=0x2,
+ [0x10D1F]=0x2,
+ [0x10D20]=0x2,
+ [0x10D21]=0x2,
+ [0x10D22]=0x3,
+ [0x10D23]=0x2,
+ [0x10F30]=0x2,
+ [0x10F31]=0x2,
+ [0x10F32]=0x2,
+ [0x10F33]=0x3,
+ [0x10F34]=0x2,
+ [0x10F35]=0x2,
+ [0x10F36]=0x2,
+ [0x10F37]=0x2,
+ [0x10F38]=0x2,
+ [0x10F39]=0x2,
+ [0x10F3A]=0x2,
+ [0x10F3B]=0x2,
+ [0x10F3C]=0x2,
+ [0x10F3D]=0x2,
+ [0x10F3E]=0x2,
+ [0x10F3F]=0x2,
+ [0x10F40]=0x2,
+ [0x10F41]=0x2,
+ [0x10F42]=0x2,
+ [0x10F43]=0x2,
+ [0x10F44]=0x2,
+ [0x10F45]=0x4,
+ [0x10F51]=0x2,
+ [0x10F52]=0x2,
+ [0x10F53]=0x2,
+ [0x10F54]=0x3,
+ [0x110BD]=0x4,
+ [0x110CD]=0x4,
+ [0x1E900]=0x2,
+ [0x1E901]=0x2,
+ [0x1E902]=0x2,
+ [0x1E903]=0x2,
+ [0x1E904]=0x2,
+ [0x1E905]=0x2,
+ [0x1E906]=0x2,
+ [0x1E907]=0x2,
+ [0x1E908]=0x2,
+ [0x1E909]=0x2,
+ [0x1E90A]=0x2,
+ [0x1E90B]=0x2,
+ [0x1E90C]=0x2,
+ [0x1E90D]=0x2,
+ [0x1E90E]=0x2,
+ [0x1E90F]=0x2,
+ [0x1E910]=0x2,
+ [0x1E911]=0x2,
+ [0x1E912]=0x2,
+ [0x1E913]=0x2,
+ [0x1E914]=0x2,
+ [0x1E915]=0x2,
+ [0x1E916]=0x2,
+ [0x1E917]=0x2,
+ [0x1E918]=0x2,
+ [0x1E919]=0x2,
+ [0x1E91A]=0x2,
+ [0x1E91B]=0x2,
+ [0x1E91C]=0x2,
+ [0x1E91D]=0x2,
+ [0x1E91E]=0x2,
+ [0x1E91F]=0x2,
+ [0x1E920]=0x2,
+ [0x1E921]=0x2,
+ [0x1E922]=0x2,
+ [0x1E923]=0x2,
+ [0x1E924]=0x2,
+ [0x1E925]=0x2,
+ [0x1E926]=0x2,
+ [0x1E927]=0x2,
+ [0x1E928]=0x2,
+ [0x1E929]=0x2,
+ [0x1E92A]=0x2,
+ [0x1E92B]=0x2,
+ [0x1E92C]=0x2,
+ [0x1E92D]=0x2,
+ [0x1E92E]=0x2,
+ [0x1E92F]=0x2,
+ [0x1E930]=0x2,
+ [0x1E931]=0x2,
+ [0x1E932]=0x2,
+ [0x1E933]=0x2,
+ [0x1E934]=0x2,
+ [0x1E935]=0x2,
+ [0x1E936]=0x2,
+ [0x1E937]=0x2,
+ [0x1E938]=0x2,
+ [0x1E939]=0x2,
+ [0x1E93A]=0x2,
+ [0x1E93B]=0x2,
+ [0x1E93C]=0x2,
+ [0x1E93D]=0x2,
+ [0x1E93E]=0x2,
+ [0x1E93F]=0x2,
+ [0x1E940]=0x2,
+ [0x1E941]=0x2,
+ [0x1E942]=0x2,
+ [0x1E943]=0x2,
+ },
+} \ No newline at end of file
diff --git a/macros/luatex/generic/luaotfload/luaotfload-colors.lua b/macros/luatex/generic/luaotfload/luaotfload-colors.lua
new file mode 100644
index 0000000000..d9dabd1c6c
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-colors.lua
@@ -0,0 +1,414 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-colors.lua
+-- DESCRIPTION: part of luaotfload / font colors
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-colors",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / color",
+ license = "GPL v2.0",
+ author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle",
+ copyright = "Luaotfload Development Team"
+ }
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+
+--[[doc--
+
+buggy coloring with the pre_output_filter when expansion is enabled
+ · tfmdata for different expansion values is split over different objects
+ · in ``initializeexpansion()``, chr.expansion_factor is set, and only
+ those characters that have it are affected
+ · in constructors.scale: chr.expansion_factor = ve*1000 if commented out
+ makes the bug vanish
+
+explanation: http://tug.org/pipermail/luatex/2013-May/004305.html
+
+--doc]]--
+
+local logreport = luaotfload and luaotfload.log.report or print
+
+local nodedirect = node.direct
+local newnode = nodedirect.new
+local insert_node_before = nodedirect.insert_before
+local insert_node_after = nodedirect.insert_after
+local todirect = nodedirect.todirect
+local tonode = nodedirect.tonode
+local setfield = nodedirect.setfield
+local getid = nodedirect.getid
+local getfont = nodedirect.getfont
+local getlist = nodedirect.getlist
+local getsubtype = nodedirect.getsubtype
+local getnext = nodedirect.getnext
+local nodetail = nodedirect.tail
+local getattribute = nodedirect.has_attribute
+local setattribute = nodedirect.set_attribute
+
+local stringformat = string.format
+local identifiers = fonts.hashes.identifiers
+
+local add_color_callback --[[ this used to be a global‽ ]]
+
+--[[doc--
+This converts a single octet into a decimal with three digits of
+precision. The optional second argument limits precision to a single
+digit.
+--doc]]--
+
+--- string -> bool? -> string
+local hex_to_dec = function (hex,one) --- one isn’t actually used anywhere ...
+ if one then
+ return stringformat("%.1g", tonumber(hex, 16)/255)
+ else
+ return stringformat("%.3g", tonumber(hex, 16)/255)
+ end
+end
+
+--[[doc--
+Color string validator / parser.
+--doc]]--
+
+local lpeg = require"lpeg"
+local lpegmatch = lpeg.match
+local C, Cg, Ct, P, R, S = lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S
+
+local digit16 = R("09", "af", "AF")
+local opaque = S("fF") * S("fF")
+local octet = C(digit16 * digit16)
+
+local p_rgb = octet * octet * octet
+local p_rgba = p_rgb * (octet - opaque)
+local valid_digits = C(p_rgba + p_rgb) -- matches eight or six hex digits
+
+local p_Crgb = Cg(octet/hex_to_dec, "red") --- for captures
+ * Cg(octet/hex_to_dec, "green")
+ * Cg(octet/hex_to_dec, "blue")
+local p_Crgba = p_Crgb * Cg(octet/hex_to_dec, "alpha")
+local extract_color = Ct(p_Crgba + p_Crgb)
+
+--- string -> (string | nil)
+local sanitize_color_expression = function (digits)
+ digits = tostring(digits)
+ local sanitized = lpegmatch(valid_digits, digits)
+ if not sanitized then
+ logreport("both", 0, "color",
+ "%q is not a valid rgb[a] color expression",
+ digits)
+ return nil
+ end
+ return sanitized
+end
+
+--- something is carried around in ``res``
+--- for later use by color_handler() --- but what?
+
+local res = nil
+
+--- float -> unit
+local function pageresources(alpha)
+ res = res or {}
+ res[alpha] = true
+end
+
+--- we store results of below color handler as tuples of
+--- push/pop strings
+local color_cache = { } --- (string, (string * string)) hash_t
+
+--- string -> (string * string)
+local hex_to_rgba = function (digits)
+ if not digits then
+ return
+ end
+
+ --- this is called like a thousand times, so some
+ --- memoizing is in order.
+ local cached = color_cache[digits]
+ if not cached then
+ local push, pop
+ local rgb = lpegmatch(extract_color, digits)
+ if rgb.alpha then
+ pageresources(rgb.alpha)
+ push = stringformat(
+ "/TransGs%g gs %s %s %s rg",
+ rgb.alpha,
+ rgb.red,
+ rgb.green,
+ rgb.blue)
+ pop = "0 g /TransGs1 gs"
+ else
+ push = stringformat(
+ "%s %s %s rg",
+ rgb.red,
+ rgb.green,
+ rgb.blue)
+ pop = "0 g"
+ end
+ color_cache[digits] = { push, pop }
+ return push, pop
+ end
+
+ return cached[1], cached[2]
+end
+
+--- Luatex internal types
+
+local nodetype = node.id
+local glyph_t = nodetype("glyph")
+local hlist_t = nodetype("hlist")
+local vlist_t = nodetype("vlist")
+local whatsit_t = nodetype("whatsit")
+local disc_t = nodetype("disc")
+local pdfliteral_t = node.subtype("pdf_literal")
+local colorstack_t = node.subtype("pdf_colorstack")
+local mlist_to_hlist = node.mlist_to_hlist
+
+local color_callback
+local color_attr = luatexbase.new_attribute("luaotfload_color_attribute")
+
+-- (node * node * string * bool * (bool | nil)) -> (node * node * (string | nil))
+local color_whatsit
+color_whatsit = function (head, curr, color, push, tail)
+ local pushdata = hex_to_rgba(color)
+ local colornode = newnode(whatsit_t, colorstack_t)
+ setfield(colornode, "stack", 0)
+ setfield(colornode, "command", push and 1 or 2) -- 1: push, 2: pop
+ setfield(colornode, "data", push and pushdata or nil)
+ if tail then
+ head, curr = insert_node_after (head, curr, colornode)
+ else
+ head = insert_node_before(head, curr, colornode)
+ end
+ if not push and color:len() > 6 then
+ local colornode = newnode(whatsit_t, pdfliteral_t)
+ setfield(colornode, "mode", 2)
+ setfield(colornode, "data", "/TransGs1 gs")
+ if tail then
+ head, curr = insert_node_after (head, curr, colornode)
+ else
+ head = insert_node_before(head, curr, colornode)
+ end
+ end
+ color = push and color or nil
+ return head, curr, color
+end
+
+-- number -> string | nil
+local get_font_color = function (font_id)
+ local tfmdata = identifiers[font_id]
+ local font_color = tfmdata and tfmdata.properties and tfmdata.properties.color
+ return font_color
+end
+
+--[[doc--
+While the second argument and second returned value are apparently
+always nil when the function is called, they temporarily take string
+values during the node list traversal.
+--doc]]--
+
+--- (node * (string | nil)) -> (node * (string | nil))
+local node_colorize
+node_colorize = function (head, toplevel, current_color)
+ local n = head
+ while n do
+ local n_id = getid(n)
+
+ if n_id == hlist_t or n_id == vlist_t then
+ local n_list = getlist(n)
+ if getattribute(n_list, color_attr) then
+ if current_color then
+ head, n, current_color = color_whatsit(head, n, current_color, false)
+ end
+ else
+ n_list, current_color = node_colorize(n_list, false, current_color)
+ if current_color and getsubtype(n) == 1 then -- created by linebreak
+ n_list, _, current_color = color_whatsit(n_list, nodetail(n_list), current_color, false, true)
+ end
+ setfield(n, "head", n_list)
+ end
+
+ elseif n_id == glyph_t then
+ --- colorization is restricted to those fonts
+ --- that received the “color†property upon
+ --- loading (see ``setcolor()`` above)
+ local font_color = get_font_color(getfont(n))
+ if font_color ~= current_color then
+ if current_color then
+ head, n, current_color = color_whatsit(head, n, current_color, false)
+ end
+ if font_color then
+ head, n, current_color = color_whatsit(head, n, font_color, true)
+ end
+ end
+
+ if current_color and color_callback == "pre_linebreak_filter" then
+ local nn = getnext(n)
+ while nn and getid(nn) == glyph_t do
+ local font_color = get_font_color(getfont(nn))
+ if font_color == current_color then
+ n = nn
+ else
+ break
+ end
+ nn = getnext(nn)
+ end
+ if getid(nn) == disc_t then
+ head, n, current_color = color_whatsit(head, nn, current_color, false, true)
+ else
+ head, n, current_color = color_whatsit(head, n, current_color, false, true)
+ end
+ end
+
+ elseif n_id == whatsit_t then
+ if current_color then
+ head, n, current_color = color_whatsit(head, n, current_color, false)
+ end
+
+ end
+
+ n = getnext(n)
+ end
+
+ if toplevel and current_color then
+ head, _, current_color = color_whatsit(head, nodetail(head), current_color, false, true)
+ end
+
+ setattribute(head, color_attr, 1)
+ return head, current_color
+end
+
+local getpageres = pdf.getpageresources or function() return pdf.pageresources end
+local setpageres = pdf.setpageresources or function(s) pdf.pageresources = s end
+local catat11 = luatexbase.registernumber("catcodetable@atletter")
+local gettoks, scantoks = tex.gettoks, tex.scantoks
+local pgf = { bye = "pgfutil@everybye", extgs = "\\pgf@sys@addpdfresource@extgs@plain" }
+
+--- node -> node
+local color_handler = function (head)
+ head = todirect(head)
+ head = node_colorize(head, true)
+ head = tonode(head)
+
+ -- now append our page resources
+ if res then
+ res["1"] = true
+ if scantoks and pgf.bye and not pgf.loaded then
+ pgf.loaded = token.create(pgf.bye).cmdname == "assign_toks"
+ pgf.bye = pgf.loaded and pgf.bye
+ end
+ local tpr = pgf.loaded and gettoks(pgf.bye) or getpageres() or ""
+
+ local t = ""
+ for k in pairs(res) do
+ local str = stringformat("/TransGs%s<</ca %s>>", k, k) -- don't touch stroking elements
+ if not tpr:find(str) then
+ t = t .. str
+ end
+ end
+ if t ~= "" then
+ if pgf.loaded then
+ scantoks("global", pgf.bye, catat11, stringformat("%s{%s}%s", pgf.extgs, t, tpr))
+ else
+ local tpr, n = tpr:gsub("/ExtGState<<", "%1"..t)
+ if n == 0 then
+ tpr = stringformat("%s/ExtGState<<%s>>", tpr, t)
+ end
+ setpageres(tpr)
+ end
+ end
+ res = nil -- reset res
+ end
+ return head
+end
+
+local color_callback_name = "luaotfload.color_handler"
+local color_callback_activated = 0
+local add_to_callback = luatexbase.add_to_callback
+
+--- unit -> bool
+local mlist_to_hlist_initial = function ()
+ local cdesc = luatexbase.callback_descriptions "mlist_to_hlist"
+ return cdesc and cdesc[1] == color_callback_name
+end
+
+--- unit -> unit
+add_color_callback = function ( )
+ color_callback = config.luaotfload.run.color_callback
+ if not color_callback then
+ color_callback = "post_linebreak_filter"
+ end
+
+ if color_callback_activated == 0 then
+ add_to_callback(color_callback,
+ color_handler,
+ color_callback_name)
+ add_to_callback("hpack_filter",
+ function (head, groupcode)
+ if groupcode == "hbox" or
+ groupcode == "adjusted_hbox" or
+ groupcode == "align_set" then
+ head = color_handler(head)
+ end
+ return head
+ end,
+ color_callback_name)
+ add_to_callback("mlist_to_hlist",
+ function (head, display_type, need_penalties)
+ if mlist_to_hlist_initial () then
+ head = mlist_to_hlist(head, display_type, need_penalties)
+ end
+ if display_type == "text" then
+ return head
+ end
+ return color_handler(head)
+ end,
+ color_callback_name)
+ color_callback_activated = 1
+ end
+end
+
+--[[doc--
+``setcolor`` modifies tfmdata.properties.color in place
+--doc]]--
+
+--- fontobj -> string -> unit
+---
+--- (where “string†is a rgb value as three octet
+--- hexadecimal, with an optional fourth transparency
+--- value)
+---
+local setcolor = function (tfmdata, value)
+ local sanitized = sanitize_color_expression(value)
+ local properties = tfmdata.properties
+
+ if sanitized then
+ properties.color = sanitized
+ add_color_callback()
+ end
+end
+
+return function ()
+ logreport = luaotfload.log.report
+ if not fonts then
+ logreport ("log", 0, "color",
+ "OTF mechanisms missing -- did you forget to \z
+ load a font loader?")
+ return false
+ end
+ fonts.handlers.otf.features.register {
+ name = "color",
+ description = "color",
+ initializers = {
+ base = setcolor,
+ node = setcolor,
+ }
+ }
+ return true
+end
+
+-- vim:tw=71:sw=4:ts=4:expandtab
+
diff --git a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
new file mode 100644
index 0000000000..7ea1cd2882
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
new file mode 100644
index 0000000000..12fc63e0d5
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
@@ -0,0 +1,1034 @@
+-------------------------------------------------------------------------------
+-- FILE: luaotfload-configuration.lua
+-- DESCRIPTION: part of luaotfload / luaotfload-tool / config file reader
+-- AUTHOR: Philipp Gesang, <phg@phi-gamma.net>
+-- AUTHOR: Dohyun Kim <nomosnomos@gmail.com>
+-------------------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-configuration",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / config file reader",
+ license = "GPL v2.0"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+------------------------------
+
+local status_file = "luaotfload-status"
+local luaotfloadstatus = require (status_file)
+
+local string = string
+local stringfind = string.find
+local stringformat = string.format
+local stringstrip = string.strip
+local stringsub = string.sub
+
+local tableappend = table.append
+local tableconcat = table.concat
+local tablecopy = table.copy
+local table = table
+local tabletohash = table.tohash
+
+local math = math
+local mathfloor = math.floor
+
+local io = io
+local ioloaddata = io.loaddata
+local iopopen = io.popen
+local iowrite = io.write
+
+local os = os
+local osdate = os.date
+local osgetenv = os.getenv
+
+local lpeg = require "lpeg"
+local lpegmatch = lpeg.match
+local commasplitter = lpeg.splitat ","
+local equalssplitter = lpeg.splitat "="
+
+local kpseexpand_path = kpse.expand_path
+
+local lfs = lfs
+local lfsisfile = lfs.isfile
+local lfsisdir = lfs.isdir
+
+local file = file
+local filejoin = file.join
+local filereplacesuffix = file.replacesuffix
+
+local logreport = print -- overloaded later
+local getwritablepath = caches.getwritablepath
+
+
+local config_parser -- set later during init
+local stripslashes -- set later during init
+
+-------------------------------------------------------------------------------
+--- SETTINGS
+-------------------------------------------------------------------------------
+
+local path_t = 0
+local kpse_t = 1
+
+local val_home = kpseexpand_path "~"
+local val_xdg_config_home = kpseexpand_path "$XDG_CONFIG_HOME"
+
+if val_xdg_config_home == "" then val_xdg_config_home = "~/.config" end
+
+local config_paths = {
+ --- needs adapting for those other OS
+ { path_t, "./luaotfload.conf" },
+ { path_t, "./luaotfloadrc" },
+ { path_t, filejoin (val_xdg_config_home, "luaotfload/luaotfload.conf") },
+ { path_t, filejoin (val_xdg_config_home, "luaotfload/luaotfloadrc") },
+ { path_t, filejoin (val_home, ".luaotfloadrc") },
+ { kpse_t, "luaotfloadrc" },
+ { kpse_t, "luaotfload.conf" },
+}
+
+local valid_formats = tabletohash {
+ "otf", "ttc", "ttf", "afm", "pfb"
+}
+
+local default_anon_sequence = {
+ "tex", "path", "name"
+}
+
+local valid_resolvers = tabletohash {
+ "tex", "path", "name", "file", "my"
+}
+
+local feature_presets = {
+ arab = tabletohash {
+ "ccmp", "locl", "isol", "fina", "fin2",
+ "fin3", "medi", "med2", "init", "rlig",
+ "calt", "liga", "cswh", "mset", "curs",
+ "kern", "mark", "mkmk",
+ },
+ deva = tabletohash {
+ "ccmp", "locl", "init", "nukt", "akhn",
+ "rphf", "blwf", "half", "pstf", "vatu",
+ "pres", "blws", "abvs", "psts", "haln",
+ "calt", "blwm", "abvm", "dist", "kern",
+ "mark", "mkmk",
+ },
+ khmr = tabletohash {
+ "ccmp", "locl", "pref", "blwf", "abvf",
+ "pstf", "pres", "blws", "abvs", "psts",
+ "clig", "calt", "blwm", "abvm", "dist",
+ "kern", "mark", "mkmk",
+ },
+ thai = tabletohash {
+ "ccmp", "locl", "liga", "kern", "mark",
+ "mkmk",
+ },
+}
+
+--[[doc--
+
+ We allow loading of arbitrary fontloaders. Nevertheless we maintain a
+ list of the “official†ones shipped with Luaotfload so we can emit a
+ different log message.
+
+--doc]]--
+
+local default_fontloader = function ()
+ return luaotfloadstatus and luaotfloadstatus.notes.loader or "reference"
+end
+
+local registered_loaders = {
+ default = default_fontloader (),
+ reference = "reference",
+ unpackaged = "unpackaged",
+ context = "context",
+}
+
+local pick_fontloader = function (s)
+ local ldr = registered_loaders[s]
+ if ldr ~= nil and type (ldr) == "string" then
+ logreport ("log", 2, "conf", "Using predefined fontloader \"%s\".", ldr)
+ return ldr
+ end
+ local idx = stringfind (s, ":")
+ if idx and idx > 2 then
+ if stringsub (s, 1, idx - 1) == "context" then
+ local pth = stringsub (s, idx + 1)
+ pth = stringstrip (pth)
+ logreport ("log", 2, "conf", "Context base path specified at \"%s\".", pth)
+ if lfsisdir (pth) then
+ logreport ("log", 5, "conf", "Context base path exists at \"%s\".", pth)
+ return pth
+ end
+ pth = kpseexpand_path (pth)
+ if lfsisdir (pth) then
+ logreport ("log", 5, "conf", "Context base path exists at \"%s\".", pth)
+ return pth
+ end
+ logreport ("both", 0, "conf", "Context base path not found at \"%s\".", pth)
+ end
+ end
+ return nil
+end
+
+--[[doc--
+
+ The ``post_linebreak_filter`` has been made the default callback for
+ hooking the colorizer into. This helps with the linebreaking whose
+ inserted hyphens would remain unaffected by the coloring otherwise.
+
+ http://tex.stackexchange.com/q/238539/14066
+
+--doc]]--
+
+local permissible_color_callbacks = {
+ default = "post_linebreak_filter",
+ pre_linebreak_filter = "pre_linebreak_filter",
+ post_linebreak_filter = "post_linebreak_filter",
+ pre_output_filter = "pre_output_filter",
+}
+
+
+-------------------------------------------------------------------------------
+--- DEFAULTS
+-------------------------------------------------------------------------------
+
+local default_config = {
+ db = {
+ formats = "otf,ttf,ttc",
+ scan_local = false,
+ skip_read = false,
+ strip = true,
+ update_live = true,
+ compress = true,
+ max_fonts = 2^51,
+ designsize_dimen= "bp",
+ },
+ run = {
+ anon_sequence = default_anon_sequence,
+ resolver = "cached",
+ definer = "patch",
+ log_level = 0,
+ color_callback = "post_linebreak_filter",
+ fontloader = default_fontloader (),
+ },
+ misc = {
+ bisect = false,
+ version = luaotfload.version,
+ statistics = false,
+ termwidth = nil,
+ },
+ paths = {
+ names_dir = "names",
+ cache_dir = "fonts",
+ index_file = "luaotfload-names.lua",
+ lookups_file = "luaotfload-lookup-cache.lua",
+ lookup_path_lua = nil,
+ lookup_path_luc = nil,
+ index_path_lua = nil,
+ index_path_luc = nil,
+ },
+ default_features = {
+ global = { mode = "node" },
+ dflt = tabletohash {
+ "ccmp", "locl", "rlig", "liga", "clig",
+ "kern", "mark", "mkmk", 'itlc',
+ },
+
+ arab = feature_presets.arab,
+ syrc = feature_presets.arab,
+ mong = feature_presets.arab,
+ nko = feature_presets.arab,
+
+ deva = feature_presets.deva,
+ beng = feature_presets.deva,
+ guru = feature_presets.deva,
+ gujr = feature_presets.deva,
+ orya = feature_presets.deva,
+ taml = feature_presets.deva,
+ telu = feature_presets.deva,
+ knda = feature_presets.deva,
+ mlym = feature_presets.deva,
+ sinh = feature_presets.deva,
+
+ khmr = feature_presets.khmr,
+ tibt = feature_presets.khmr,
+ thai = feature_presets.thai,
+ lao = feature_presets.thai,
+
+ hang = tabletohash { "ccmp", "ljmo", "vjmo", "tjmo", },
+ },
+}
+
+-------------------------------------------------------------------------------
+--- RECONFIGURATION TASKS
+-------------------------------------------------------------------------------
+
+--[[doc--
+
+ Procedures to be executed in order to put the new configuration into effect.
+
+--doc]]--
+
+local reconf_tasks = nil
+
+local min_terminal_width = 40
+
+--- The “termwidth†value is only considered when printing
+--- short status messages, e.g. when building the database
+--- online.
+local check_termwidth = function ()
+ if config.luaotfload.misc.termwidth == nil then
+ local tw = 79
+ if not ( os.type == "windows" --- Assume broken terminal.
+ or osgetenv "TERM" == "dumb")
+ then
+ local p = iopopen "tput cols"
+ if p then
+ result = tonumber (p:read "*all")
+ p:close ()
+ if result then
+ tw = result
+ else
+ logreport ("log", 2, "db", "tput returned non-number.")
+ end
+ else
+ logreport ("log", 2, "db", "Shell escape disabled or tput executable missing.")
+ logreport ("log", 2, "db", "Assuming 79 cols terminal width.")
+ end
+ end
+ config.luaotfload.misc.termwidth = tw
+ end
+ return true
+end
+
+local set_font_filter = function ()
+ local names = fonts.names
+ if names and names.set_font_filter then
+ local formats = config.luaotfload.db.formats
+ if not formats or formats == "" then
+ formats = default_config.db.formats
+ end
+ names.set_font_filter (formats)
+ end
+ return true
+end
+
+local set_size_dimension = function ()
+ local names = fonts.names
+ if names and names.set_size_dimension then
+ local dim = config.luaotfload.db.designsize_dimen
+ if not dim or dim == "" then
+ dim = default_config.db.designsize_dimen
+ end
+ names.set_size_dimension (dim)
+ end
+ return true
+end
+
+local set_name_resolver = function ()
+ local names = fonts.names
+ if names and names.resolve_cached then
+ --- replace the resolver from luatex-fonts
+ if config.luaotfload.db.resolver == "cached" then
+ logreport ("both", 2, "cache", "Caching of name: lookups active.")
+ names.resolvespec = fonts.names.lookup_font_name_cached
+ else
+ names.resolvespec = fonts.names.lookup_font_name
+ end
+ end
+ return true
+end
+
+local set_loglevel = function ()
+ if luaotfload then
+ luaotfload.log.set_loglevel (config.luaotfload.run.log_level)
+ return true
+ end
+ return false
+end
+
+local build_cache_paths = function ()
+ local paths = config.luaotfload.paths
+ local prefix = getwritablepath (paths.names_dir, "")
+
+ if not prefix then
+ luaotfload.error ("Impossible to find a suitable writeable cache...")
+ return false
+ end
+
+ prefix = lpegmatch (stripslashes, prefix)
+ logreport ("log", 0, "conf", "Root cache directory is %s.", prefix)
+
+ local index_file = filejoin (prefix, paths.index_file)
+ local lookups_file = filejoin (prefix, paths.lookups_file)
+
+ paths.prefix = prefix
+ paths.index_path_lua = filereplacesuffix (index_file, "lua")
+ paths.index_path_luc = filereplacesuffix (index_file, "luc")
+ paths.lookup_path_lua = filereplacesuffix (lookups_file, "lua")
+ paths.lookup_path_luc = filereplacesuffix (lookups_file, "luc")
+ return true
+end
+
+
+local set_default_features = function ()
+ local default_features = config.luaotfload.default_features
+ luaotfload.features = luaotfload.features or {
+ global = { },
+ defaults = { },
+ }
+ current_features = luaotfload.features
+ for var, val in next, default_features do
+ if var == "global" then
+ current_features.global = val
+ else
+ current_features.defaults[var] = val
+ end
+ end
+ return true
+end
+
+reconf_tasks = {
+ { "Set the log level" , set_loglevel },
+ { "Build cache paths" , build_cache_paths },
+ { "Check terminal dimensions" , check_termwidth },
+ { "Set the font filter" , set_font_filter },
+ { "Set design size dimension" , set_size_dimension },
+ { "Install font name resolver", set_name_resolver },
+ { "Set default features" , set_default_features },
+}
+
+-------------------------------------------------------------------------------
+--- OPTION SPECIFICATION
+-------------------------------------------------------------------------------
+
+local string_t = "string"
+local table_t = "table"
+local number_t = "number"
+local boolean_t = "boolean"
+local function_t = "function"
+
+local tointeger = function (n)
+ n = tonumber (n)
+ if n then
+ return mathfloor (n + 0.5)
+ end
+end
+
+local toarray = function (s)
+ local fields = { lpegmatch (commasplitter, s) }
+ local ret = { }
+ for i = 1, #fields do
+ local field = stringstrip (fields[i])
+ if field and field ~= "" then
+ ret[#ret + 1] = field
+ end
+ end
+ return ret
+end
+
+local tohash = function (s)
+ local result = { }
+ local fields = toarray (s)
+ for _, field in next, fields do
+ local var, val
+ if stringfind (field, "=") then
+ local tmp
+ var, tmp = lpegmatch (equalssplitter, field)
+ if tmp == "true" or tmp == "yes" then val = true else val = tmp end
+ else
+ var, val = field, true
+ end
+ result[var] = val
+ end
+ return result
+end
+
+local option_spec = {
+ db = {
+ formats = {
+ in_t = string_t,
+ out_t = string_t,
+ transform = function (f)
+ local fields = toarray (f)
+
+ --- check validity
+ if not fields then
+ logreport ("both", 0, "conf",
+ "Expected list of identifiers, got %q.", f)
+ return nil
+ end
+
+ --- strip dupes
+ local known = { }
+ local result = { }
+ for i = 1, #fields do
+ local field = fields[i]
+ if known[field] ~= true then
+ --- yet unknown, tag as seen
+ known[field] = true
+ --- include in output if valid
+ if valid_formats[field] == true then
+ result[#result + 1] = field
+ else
+ logreport ("both", 4, "conf",
+ "Invalid font format identifier %q, ignoring.",
+ field)
+ end
+ end
+ end
+ if #result == 0 then
+ --- force defaults
+ return nil
+ end
+ return tableconcat (result, ",")
+ end
+ },
+ scan_local = { in_t = boolean_t, },
+ skip_read = { in_t = boolean_t, },
+ strip = { in_t = boolean_t, },
+ update_live = { in_t = boolean_t, },
+ compress = { in_t = boolean_t, },
+ max_fonts = {
+ in_t = number_t,
+ out_t = number_t, --- TODO int_t from 5.3.x on
+ transform = tointeger,
+ },
+ designsize_dimen = {
+ in_t = string_t,
+ out_t = string_t,
+ },
+ },
+ run = {
+ anon_sequence = {
+ in_t = string_t,
+ out_t = table_t,
+ transform = function (s)
+ if s ~= "default" then
+ local bits = { lpegmatch (commasplitter, s) }
+ if next (bits) then
+ local seq = { }
+ local done = { }
+ for i = 1, #bits do
+ local bit = bits [i]
+ if valid_resolvers [bit] then
+ if not done [bit] then
+ done [bit] = true
+ seq [#seq + 1] = bit
+ else
+ logreport ("both", 0, "conf",
+ "ignoring duplicate resolver %s at position %d \z
+ in lookup sequence",
+ bit, i)
+ end
+ else
+ logreport ("both", 0, "conf",
+ "lookup sequence contains invalid item %s \z
+ at position %d.",
+ bit, i)
+ end
+ end
+ if next (seq) then
+ logreport ("both", 2, "conf",
+ "overriding anon lookup sequence %s.",
+ tableconcat (seq, ","))
+ return seq
+ end
+ end
+ end
+ return default_anon_sequence
+ end
+ },
+ live = { in_t = boolean_t, }, --- false for the tool, true for TeX run
+ resolver = {
+ in_t = string_t,
+ out_t = string_t,
+ transform = function (r) return r == "normal" and r or "cached" end,
+ },
+ definer = {
+ in_t = string_t,
+ out_t = string_t,
+ transform = function (d)
+ if d == "generic" or d == "patch"
+ or d == "info_generic" or d == "info_patch"
+ then
+ return d
+ end
+ return "patch"
+ end,
+ },
+ fontloader = {
+ in_t = string_t,
+ out_t = string_t,
+ transform = function (id)
+ local ldr = pick_fontloader (id)
+ if ldr ~= nil then
+ return ldr
+ end
+ logreport ("log", 0, "conf",
+ "Requested fontloader \"%s\" not defined, "
+ .. "use at your own risk.",
+ id)
+ return id
+ end,
+ },
+ log_level = {
+ in_t = number_t,
+ out_t = number_t, --- TODO int_t from 5.3.x on
+ transform = tointeger,
+ },
+ color_callback = {
+ in_t = string_t,
+ out_t = string_t,
+ transform = function (cb_spec)
+ --- These are the two that make sense.
+ local cb = permissible_color_callbacks[cb_spec]
+ if cb then
+ logreport ("log", 3, "conf",
+ "Using callback \"%s\" for font colorization.",
+ cb)
+ return cb
+ end
+ logreport ("log", 0, "conf",
+ "Requested callback identifier \"%s\" invalid, "
+ .. "falling back to default.",
+ cb_spec)
+ return permissible_color_callbacks.default
+ end,
+ },
+ },
+ misc = {
+ bisect = { in_t = boolean_t, }, --- doesn’t make sense in a config file
+ version = { in_t = string_t, },
+ statistics = { in_t = boolean_t, },
+ termwidth = {
+ in_t = number_t,
+ out_t = number_t,
+ transform = function (w)
+ w = tointeger (w)
+ if w < min_terminal_width then
+ return min_terminal_width
+ end
+ return w
+ end,
+ },
+ },
+ paths = {
+ names_dir = { in_t = string_t, },
+ cache_dir = { in_t = string_t, },
+ index_file = { in_t = string_t, },
+ lookups_file = { in_t = string_t, },
+ lookup_path_lua = { in_t = string_t, },
+ lookup_path_luc = { in_t = string_t, },
+ index_path_lua = { in_t = string_t, },
+ index_path_luc = { in_t = string_t, },
+ },
+ default_features = {
+ __default = { in_t = string_t, out_t = table_t, transform = tohash, },
+ },
+}
+
+-------------------------------------------------------------------------------
+--- FORMATTERS
+-------------------------------------------------------------------------------
+
+local commented = function (str)
+ return ";" .. str
+end
+
+local underscore_replacer = lpeg.replacer ("_", "-", true)
+
+local dashed = function (var)
+ --- INI spec dictates that dashes are valid in variable names, not
+ --- underscores.
+ return underscore_replacer (var) or var
+end
+
+local indent = " "
+local format_string = function (var, val)
+ return stringformat (indent .. "%s = %s", var, val)
+end
+
+local format_integer = function (var, val)
+ return stringformat (indent .. "%s = %d", var, val)
+end
+
+local format_boolean = function (var, val)
+ return stringformat (indent .. "%s = %s", var, val == true and "true" or "false")
+end
+
+local format_keyval = function (var, val)
+ local list = { }
+ local keys = table.sortedkeys (val)
+ for i = 1, #keys do
+ local key = keys[i]
+ local subval = val[key]
+ if subval == true then
+ list[#list + 1] = stringformat ("%s", key)
+ else
+ list[#list + 1] = stringformat ("%s=%s", key, val[key])
+ end
+ end
+ if next (list) then
+ return stringformat (indent .. "%s = %s",
+ var,
+ tableconcat (list, ","))
+ end
+end
+
+local format_list = function (var, val)
+ local elts = { }
+ for i = 1, #val do elts [i] = val [i] end
+ if next (elts) then
+ return stringformat (indent .. "%s = %s",
+ var, tableconcat (elts, ","))
+ end
+end
+
+local format_section = function (title)
+ return stringformat ("[%s]", dashed (title))
+end
+
+local conf_header = [==[
+;;-----------------------------------------------------------------------------
+;; Luaotfload Configuration
+;;-----------------------------------------------------------------------------
+;;
+;; This file was generated by luaotfload-tool
+;; on %s. Configuration variables
+;; are documented in the manual to luaotfload.conf(5).
+;;
+;;-----------------------------------------------------------------------------
+
+]==]
+
+local conf_footer = [==[
+
+;; vim:filetype=dosini:expandtab:shiftwidth=2
+]==]
+
+--- Each dumpable variable (the ones mentioned in the man page) receives a
+--- formatter that will be used in dumping the variable. Each value receives a
+--- “commented†flag that indicates whether or not the line should be printed
+--- as a comment.
+
+local formatters = {
+ db = {
+ compress = { false, format_boolean },
+ designsize_dimen = { false, format_string },
+ formats = { false, format_string },
+ max_fonts = { false, format_integer },
+ scan_local = { false, format_boolean },
+ skip_read = { false, format_boolean },
+ strip = { false, format_boolean },
+ update_live = { false, format_boolean },
+ },
+ default_features = {
+ __default = { true, format_keyval },
+ },
+ misc = {
+ bisect = { false, format_boolean },
+ statistics = { false, format_boolean },
+ termwidth = { true , format_integer },
+ version = { true , format_string },
+ },
+ paths = {
+ cache_dir = { false, format_string },
+ names_dir = { false, format_string },
+ index_file = { false, format_string },
+ lookups_file = { false, format_string },
+ },
+ run = {
+ anon_sequence = { false, format_list },
+ color_callback = { false, format_string },
+ definer = { false, format_string },
+ fontloader = { false, format_string },
+ log_level = { false, format_integer },
+ resolver = { false, format_string },
+ },
+}
+
+-------------------------------------------------------------------------------
+--- MAIN FUNCTIONALITY
+-------------------------------------------------------------------------------
+
+--[[doc--
+
+ tilde_expand -- Rudimentary tilde expansion; covers just the “substitute ‘~’
+ by the current users’s $HOME†part.
+
+--doc]]--
+
+local tilde_expand = function (p)
+ if #p > 2 then
+ if stringsub (p, 1, 2) == "~/" then
+ local homedir = osgetenv "HOME"
+ if homedir and lfsisdir (homedir) then
+ p = filejoin (homedir, stringsub (p, 3))
+ end
+ end
+ end
+ return p
+end
+
+local resolve_config_path = function ()
+ for i = 1, #config_paths do
+ local t, p = unpack (config_paths[i])
+ local fullname
+ if t == kpse_t then
+ fullname = kpse.find_file (p)
+ logreport ("both", 6, "conf", "kpse lookup: %s -> %s.", p, fullname)
+ elseif t == path_t then
+ local expanded = tilde_expand (p)
+ if lfsisfile (expanded) then
+ fullname = expanded
+ end
+ logreport ("both", 6, "conf", "path lookup: %s -> %s.", p, fullname)
+ end
+ if fullname then
+ logreport ("both", 3, "conf", "Reading configuration file at %q.", fullname)
+ return fullname
+ end
+ end
+ logreport ("both", 2, "conf", "No configuration file found.")
+ return false
+end
+
+local add_config_paths = function (t)
+ if not next (t) then
+ return
+ end
+ local result = { }
+ for i = 1, #t do
+ local path = t[i]
+ result[#result + 1] = { path_t, path }
+ end
+ config_paths = tableappend (result, config_paths)
+end
+
+local process_options = function (opts)
+ local new = { }
+ for i = 1, #opts do
+ local section = opts[i]
+ local title = section.section.title
+ local vars = section.variables
+
+ if not title then --- trigger warning: arrow code ahead
+ logreport ("both", 2, "conf", "Section %d lacks a title; skipping.", i)
+ elseif not vars then
+ logreport ("both", 2, "conf", "Section %d (%s) lacks a variable section; skipping.", i, title)
+ else
+ local spec = option_spec[title]
+ if not spec then
+ logreport ("both", 2, "conf", "Section %d (%s) unknown; skipping.", i, title)
+ else
+ local newsection = new[title]
+ if not newsection then
+ newsection = { }
+ new[title] = newsection
+ end
+
+ for var, val in next, vars do
+ local vspec = spec[var] or spec.__default
+ local t_val = type (val)
+ if not vspec then
+ logreport ("both", 2, "conf",
+ "Section %d (%s): invalid configuration variable %q (%q); ignoring.",
+ i, title,
+ var, tostring (val))
+ elseif t_val ~= vspec.in_t then
+ logreport ("both", 2, "conf",
+ "Section %d (%s): type mismatch of input value %q (%q, %s != %s); ignoring.",
+ i, title,
+ var, tostring (val), t_val, vspec.in_t)
+ else --- type matches
+ local transform = vspec.transform
+ if transform then
+ local dval
+ local t_transform = type (transform)
+ if t_transform == function_t then
+ dval = transform (val)
+ elseif t_transform == table_t then
+ dval = transform[val]
+ end
+ if dval then
+ local out_t = vspec.out_t
+ if out_t then
+ local t_dval = type (dval)
+ if t_dval == out_t then
+ newsection[var] = dval
+ else
+ logreport ("both", 2, "conf",
+ "Section %d (%s): type mismatch of derived value of %q (%q, %s != %s); ignoring.",
+ i, title,
+ var, tostring (dval), t_dval, out_t)
+ end
+ else
+ newsection[var] = dval
+ end
+ else
+ logreport ("both", 2, "conf",
+ "Section %d (%s): value of %q could not be derived via %s from input %q; ignoring.",
+ i, title, var, t_transform, tostring (val))
+ end
+ else --- insert as is
+ newsection[var] = val
+ end
+ end
+ end
+ end
+ end
+ end
+ return new
+end
+
+local apply
+apply = function (old, new)
+ if not new then
+ if not old then
+ return false
+ end
+ return tablecopy (old)
+ elseif not old then
+ return tablecopy (new)
+ end
+ local result = tablecopy (old)
+ for name, section in next, new do
+ local t_section = type (section)
+ if t_section ~= table_t then
+ logreport ("both", 1, "conf",
+ "Error applying configuration: entry %s is %s, expected table.",
+ section, t_section)
+ --- ignore
+ else
+ local currentsection = result[name]
+ for var, val in next, section do
+ currentsection[var] = val
+ end
+ end
+ end
+ result.status = luaotfloadstatus
+ return result
+end
+
+local reconfigure = function ()
+ for i = 1, #reconf_tasks do
+ local name, task = unpack (reconf_tasks[i])
+ logreport ("both", 3, "conf", "Launch post-configuration task %q.", name)
+ if not task () then
+ logreport ("both", 0, "conf", "Post-configuration task %q failed.", name)
+ return false
+ end
+ end
+ return true
+end
+
+local read = function (extra)
+ if extra then
+ add_config_paths (extra)
+ end
+
+ local readme = resolve_config_path ()
+ if readme == false then
+ logreport ("both", 2, "conf", "No configuration file.")
+ return false
+ end
+
+ local raw = ioloaddata (readme)
+ if not raw then
+ logreport ("both", 2, "conf", "Error reading the configuration file %q.", readme)
+ return false
+ end
+
+ local parsed = lpegmatch (config_parser, raw)
+ if not parsed then
+ logreport ("both", 2, "conf", "Error parsing configuration file %q.", readme)
+ return false
+ end
+
+ local ret, msg = process_options (parsed)
+ if not ret then
+ logreport ("both", 2, "conf", "File %q is not a valid configuration file.", readme)
+ logreport ("both", 2, "conf", "Error: %s", msg)
+ return false
+ end
+ return ret
+end
+
+local apply_defaults = function ()
+ local defaults = default_config
+ local vars = read ()
+ --- Side-effects galore ...
+ config.luaotfload = apply (defaults, vars)
+ return reconfigure ()
+end
+
+local dump = function ()
+ local sections = table.sortedkeys (config.luaotfload)
+ local confdata = { }
+ for i = 1, #sections do
+ local section = sections[i]
+ local vars = config.luaotfload[section]
+ local varnames = table.sortedkeys (vars)
+ local sformats = formatters[section]
+ if sformats then
+ confdata[#confdata + 1] = format_section (section)
+ for j = 1, #varnames do
+ local var = varnames[j]
+ local val = vars[var]
+ local comment, sformat = unpack (sformats[var] or { })
+ if not sformat then
+ comment, sformat = unpack (sformats.__default or { })
+ end
+
+ if sformat then
+ local dashedvar = dashed (var)
+ if comment then
+ confdata[#confdata + 1] = commented (sformat (dashedvar, val))
+ else
+ confdata[#confdata + 1] = sformat (dashedvar, val)
+ end
+ end
+
+ end
+ confdata[#confdata + 1] = ""
+ end
+ end
+ if next(confdata) then
+ iowrite (stringformat (conf_header,
+ osdate ("%Y-%m-d %H:%M:%S", os.time ())))
+ iowrite (tableconcat (confdata, "\n"))
+ iowrite (conf_footer)
+ end
+end
+
+-------------------------------------------------------------------------------
+--- EXPORTS
+-------------------------------------------------------------------------------
+
+return function ()
+ config.luaotfload = { }
+ logreport = luaotfload.log.report
+ local parsers = luaotfload.parsers
+ config_parser = parsers.config
+ stripslashes = parsers.stripslashes
+
+ luaotfload.default_config = default_config
+ config.actions = {
+ read = read,
+ apply = apply,
+ apply_defaults = apply_defaults,
+ reconfigure = reconfigure,
+ dump = dump,
+ }
+ if not apply_defaults () then
+ logreport ("log", 0, "load",
+ "Configuration unsuccessful: error loading default settings.")
+ end
+ return true
+end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-database.lua b/macros/luatex/generic/luaotfload/luaotfload-database.lua
new file mode 100644
index 0000000000..a932456b6a
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-database.lua
@@ -0,0 +1,3764 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-database.lua
+-- DESCRIPTION: part of luaotfload / luaotfload-tool / font database
+-----------------------------------------------------------------------
+do -- block to avoid to many local variables error
+ local ProvidesLuaModule = {
+ name = "luaotfload-database",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / database",
+ license = "GPL v2.0",
+ author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
+ copyright = "Luaotfload Development Team",
+ }
+
+ if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+ end
+end
+
+--[[doc--
+
+ With version 2.7 we killed of the Fontforge libraries in favor of
+ the Lua implementation of the OT format reader. There were many
+ reasons to do this on top of the fact that FF won’t be around at
+ version 1.0 anymore: In addition to maintainability, memory safety
+ and general code hygiene, the new reader shows an amazing
+ performance: Scanning of the 3200 font files on my system takes
+ around 23 s now, as opposed to 74 s with the Fontforge libs. Memory
+ usage has improved drastically as well, as illustrated by these
+ profiles:
+
+ GB
+ 1.324^ #
+ | #
+ | ::#
+ | : #::
+ | @: #:
+ | @: #:
+ | @@@: #:
+ | @@@ @: #:
+ | @@ @ @ @: #:
+ | @ @@:@ @ @: #: :
+ | @@ : @ :@ @ @: #: :
+ | @@: ::@@ :@@ ::@ :@ @ @: #: : :::
+ | @@ : :: @@ :@ : @ :@ @ @: #: : :: :
+ | @@ : ::: @@ :@ ::: @ :@ @ @: #: :: :: :
+ | @@@@ :: :::: @@ :@ : : @ :@ @ @: #: :: :::: ::
+ | :@ @@ :: :::: @@ :@ : :: : @ :@ @ @: #: :: :: :: ::
+ | @:@ @@ :: ::::: @@ :@ : :::: : @ :@ @ @: #: :::: :::: :: ::
+ | @@:@ @@ :: ::::::: @@ :@ : : :: : @ :@ @ @: #: ::: @: :: :: ::@
+ | @@@:@ @@ :: :: ::::: @@ :@ ::: :: : @ :@ @ @: #: ::: @: :: :: ::@
+ | @@@@@:@ @@ ::::::: ::::: @@ :@ ::: :: : @ :@ @ @: #: ::: ::@: :: :: ::@
+ 0 +----------------------------------------------------------------------->GB
+ 0 16.29
+
+ This is the memory usage during a complete database rebuild with
+ the Fontforge libraries. The same action using the new
+ ``getinfo()`` method gives a different picture:
+
+ MB
+ 43.37^ #
+ | @ @ @#
+ | @@ @ @ @# :
+ | @@@ : @: @ @ @# :
+ | @ @@@ : : @: @ @: :@# :
+ | @ @ @@@ : : @: @ @: :@# :
+ | @ : : :@ @@@:::: @::@ @: :@#:: :
+ | :: : @ : @ : :::@ @ :@@@:::::@::@ @:::@#::::
+ | : @ : :: : :@:: :@: :::::@ @ :@@@:::::@::@:@:::@#::::
+ | :: :@ : @ ::@:@:::@:: :@: :::::@: :@ :@@@:::::@::@:@:::@#::::
+ | :: :@::: :@ ::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::::@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | ::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ 0 +----------------------------------------------------------------------->GB
+ 0 3.231
+
+ FF peaks at around 1.4 GB after 12.5 GB worth of allocations,
+ whereas the Lua implementation arrives at around 45 MB after 3.2 GB
+ total:
+
+ impl time(B) total(B) useful-heap(B) extra-heap(B)
+ fontforge 12,496,407,184 1,421,150,144 1,327,888,638 93,261,506
+ lua 3,263,698,960 45,478,640 37,231,892 8,246,748
+
+ Much of the inefficiency of Fontforge is a direct consequence of
+ having to parse the entire font to extract what essentially boils
+ down to a couple hundred bytes of metadata per font. Since some
+ information like design sizes (oh, Adobe!) is stuffed away in
+ Opentype tables, the vastly more efficient approach of
+ fontloader.info() proves insufficient for indexing. Thus, we ended
+ up using fontloader.open() which causes even the character tables
+ to be parsed, which incidentally are responsible for most of the
+ allocations during that peak of 1.4 GB measured above, along with
+ the encodings:
+
+ 20.67% (293,781,048B) 0x6A8F72: SplineCharCreate (splineutil.c:3878)
+ 09.82% (139,570,318B) 0x618ACD: _FontViewBaseCreate (fontviewbase.c:84)
+ 08.77% (124,634,384B) 0x6A8FB3: SplineCharCreate (splineutil.c:3885)
+ 04.53% (64,436,904B) in 80 places, all below massif's threshold (1.00%)
+ 02.68% (38,071,520B) 0x64E14E: addKernPair (parsettfatt.c:493)
+ 01.04% (14,735,320B) 0x64DE7D: addPairPos (parsettfatt.c:452)
+ 39.26% (557,942,484B) 0x64A4E0: PsuedoEncodeUnencoded (parsettf.c:5706)
+
+ What gives? For 2.7 we expect a rougher transition than a year back
+ due to the complete revamp of the OT loading code. Breakage of
+ fragile aspects like font and style names has been anticipated and
+ addressed prior to the 2016 pretest release. In contrast to the
+ earlier approach of letting FF do a complete dump and then harvest
+ identifiers from the output we now have to coordinate with upstream
+ as to which fields are actually needed in order to provide a
+ similarly acceptable name → file lookup. On the bright side, these
+ things are a lot simpler to fix than the rather tedious work of
+ having users update their Luatex binary =)
+
+--doc]]--
+
+local lpeg = require "lpeg"
+local P, lpegmatch = lpeg.P, lpeg.match
+
+local log = luaotfload.log
+local logreport = log and log.report or print -- overriden later on
+local report_status = log.names_status
+local report_status_start = log.names_status_start
+local report_status_stop = log.names_status_stop
+
+
+--- Luatex builtins
+local load = load
+local next = next
+local require = require
+local tonumber = tonumber
+local unpack = table.unpack
+
+local fonts = fonts or { }
+local fontshandlers = fonts.handlers or { }
+local otfhandler = fonts.handlers.otf or { }
+fonts.handlers = fontshandlers
+
+local gzipload = gzip.load
+local gzipsave = gzip.save
+local iolines = io.lines
+local ioopen = io.open
+local iopopen = io.popen
+local kpseexpand_path = kpse.expand_path
+local kpsefind_file = kpse.find_file
+local kpselookup = kpse.lookup
+local kpsereadable_file = kpse.readable_file
+local lfsattributes = lfs.attributes
+local lfschdir = lfs.chdir
+local lfscurrentdir = lfs.currentdir
+local lfsdir = lfs.dir
+local mathabs = math.abs
+local mathmin = math.min
+local osgetenv = os.getenv
+local osgettimeofday = os.gettimeofday
+local osremove = os.remove
+local stringfind = string.find
+local stringformat = string.format
+local stringgmatch = string.gmatch
+local stringgsub = string.gsub
+local stringlower = string.lower
+local stringsub = string.sub
+local stringupper = string.upper
+local tableconcat = table.concat
+local tablesort = table.sort
+local utf8len = utf8.len
+local utf8offset = utf8.offset
+
+--- these come from Lualibs/Context
+local filebasename = file.basename
+local filecollapsepath = file.collapsepath or file.collapse_path
+local filedirname = file.dirname
+local fileextname = file.extname
+local fileiswritable = file.iswritable
+local filejoin = file.join
+local filenameonly = file.nameonly
+local filereplacesuffix = file.replacesuffix
+local filesplitpath = file.splitpath or file.split_path
+local filesuffix = file.suffix
+local getwritablepath = caches.getwritablepath
+local lfsisdir = lfs.isdir
+local lfsisfile = lfs.isfile
+local lfsmkdirs = lfs.mkdirs
+local lpegsplitat = lpeg.splitat
+local stringis_empty = string.is_empty
+local stringsplit = string.split
+local stringstrip = string.strip
+local tableappend = table.append
+local tablecontains = table.contains
+local tablecopy = table.copy
+local tablefastcopy = table.fastcopy
+local tabletofile = table.tofile
+local tabletohash = table.tohash
+local tableserialize = table.serialize
+local names = fonts and fonts.names or { }
+
+--- some of our own
+local unicode = require'luaotfload-unicode'
+local casefold = unicode.casefold
+local alphnum_only = unicode.alphnum_only
+
+local name_index = nil --> upvalue for names.data
+local lookup_cache = nil --> for names.lookups
+
+--- string -> (string * string)
+local make_luanames = function (path)
+ return filereplacesuffix(path, "lua"),
+ filereplacesuffix(path, "luc")
+end
+
+local format_precedence = {
+ "otf", "ttc", "ttf", "afm", "pfb"
+}
+
+local location_precedence = {
+ "local", "system", "texmf",
+}
+
+local set_location_precedence = function (precedence)
+ location_precedence = precedence
+end
+
+--[[doc--
+
+ Auxiliary functions
+
+--doc]]--
+
+--- fontnames contain all kinds of garbage; as a precaution we
+--- lowercase and strip them of non alphanumerical characters
+
+--- string -> string
+
+local invalidchars = "[^%a%d]"
+
+local sanitize_fontname = function (str)
+ if str ~= nil then
+ if utf8len(str) then
+ str = alphnum_only(casefold(str, true))
+ else
+ str = stringgsub(stringlower(str), invalidchars, "")
+ end
+ return str
+ end
+ return nil
+end
+
+local sanitize_fontnames = function (rawnames)
+ local result = { }
+ for category, namedata in next, rawnames do
+
+ if type (namedata) == "string" then
+ if utf8len(namedata) then
+ result [category] = alphnum_only(casefold(namedata, true))
+ else
+ result [category] = stringgsub(stringlower(namedata), invalidchars, "")
+ end
+ else
+ local target = { }
+ for field, name in next, namedata do
+ if utf8len(name) then
+ target [field] = alphnum_only(casefold(name, true))
+ else
+ target [field] = stringgsub(stringlower(name), invalidchars, "")
+ end
+ end
+ result [category] = target
+ end
+ end
+ return result
+end
+
+local find_files_indeed
+find_files_indeed = function (acc, dirs, filter)
+ if not next (dirs) then --- done
+ return acc
+ end
+
+ local pwd = lfscurrentdir ()
+ local dir = dirs[#dirs]
+ dirs[#dirs] = nil
+
+ if lfschdir (dir) then
+ lfschdir (pwd)
+
+ local newfiles = { }
+ for ent in lfsdir (dir) do
+ if ent ~= "." and ent ~= ".." then
+ local fullpath = dir .. "/" .. ent
+ if filter (fullpath) == true then
+ if lfsisdir (fullpath) then
+ dirs[#dirs+1] = fullpath
+ elseif lfsisfile (fullpath) then
+ newfiles[#newfiles+1] = fullpath
+ end
+ end
+ end
+ end
+ return find_files_indeed (tableappend (acc, newfiles),
+ dirs, filter)
+ end
+ --- could not cd into, so we skip it
+ return find_files_indeed (acc, dirs, filter)
+end
+
+local dummyfilter = function () return true end
+
+--- the optional filter function receives the full path of a file
+--- system entity. a filter applies if the first argument it returns is
+--- true.
+
+--- string -> function? -> string list
+local find_files = function (root, filter)
+ if lfsisdir (root) then
+ return find_files_indeed ({}, { root }, filter or dummyfilter)
+ end
+end
+
+
+--[[doc--
+This is a sketch of the luaotfload db:
+
+ type dbobj = {
+ families : familytable;
+ files : filemap;
+ status : filestatus;
+ mappings : fontentry list;
+ meta : metadata;
+ }
+ and familytable = {
+ local : (format, familyentry) hash; // specified with include dir
+ texmf : (format, familyentry) hash;
+ system : (format, familyentry) hash;
+ }
+ and familyentry = {
+ r : sizes; // regular
+ i : sizes; // italic
+ b : sizes; // bold
+ bi : sizes; // bold italic
+ }
+ and sizes = {
+ default : int; // points into mappings or names
+ optical : (int, int) list; // design size -> index entry
+ }
+ and metadata = {
+ created : string // creation time
+ formats : string list; // { "otf", "ttf", "ttc" }
+ local : bool; (* set if local fonts were added to the db *)
+ modified : string // modification time
+ statistics : TODO; // created when built with "--stats"
+ version : float; // index version
+ }
+ and filemap = { // created by generate_filedata()
+ base : {
+ local : (string, int) hash; // basename -> idx
+ system : (string, int) hash;
+ texmf : (string, int) hash;
+ };
+ bare : {
+ local : (string, (string, int) hash) hash; // location -> (barename -> idx)
+ system : (string, (string, int) hash) hash;
+ texmf : (string, (string, int) hash) hash;
+ };
+ full : (int, string) hash; // idx -> full path
+ }
+ and fontentry = { // finalized by collect_families()
+ basename : string; // file name without path "foo.otf"
+ conflicts : { barename : int; basename : int }; // filename conflict with font at index; happens with subfonts
+ familyname : string; // sanitized name of the font family the font belongs to, usually from the names table
+ fontname : string; // sanitized name of the font
+ format : string; // "otf" | "ttf" | "afm" (* | "pfb" *)
+ fullname : string; // sanitized full name of the font including style modifiers
+ fullpath : string; // path to font in filesystem
+ index : int; // index in the mappings table
+ italicangle : float; // italic angle; non-zero with oblique faces
+ location : string; // "texmf" | "system" | "local"
+ plainname : string; // unsanitized font name
+ typographicsubfamily : string; // sanitized preferred subfamily (names table 14)
+ psname : string; // PostScript name
+ size : (false | float * float * float); // if available, size info from the size table converted from decipoints
+ subfamily : string; // sanitized subfamily (names table 2)
+ subfont : (int | bool); // integer if font is part of a TrueType collection ("ttc")
+ version : string; // font version string
+ weight : int; // usWeightClass
+ }
+ and filestatus = (string, // fullname
+ { index : int list; // pointer into mappings
+ timestamp : int; }) dict
+
+beware that this is a reconstruction and may be incomplete or out of
+date. Last update: 2014-04-06, describing version 2.51.
+
+mtx-fonts has in names.tma:
+
+ type names = {
+ cache_uuid : uuid;
+ cache_version : float;
+ datastate : uuid list;
+ fallbacks : (filetype, (basename, int) hash) hash;
+ families : (basename, int list) hash;
+ files : (filename, fullname) hash;
+ indices : (fullname, int) hash;
+ mappings : (filetype, (basename, int) hash) hash;
+ names : ? (empty hash) ?;
+ rejected : (basename, int) hash;
+ specifications: fontentry list;
+ }
+ and fontentry = {
+ designsize : int;
+ familyname : string;
+ filename : string;
+ fontname : string;
+ format : string;
+ fullname : string;
+ maxsize : int;
+ minsize : int;
+ modification : int;
+ rawname : string;
+ style : string;
+ subfamily : string;
+ variant : string;
+ weight : string;
+ width : string;
+ }
+
+--doc]]--
+
+--- string list -> string option -> dbobj
+
+local initialize_namedata = function (formats, created)
+ local now = os.date "%Y-%m-%d %H:%M:%S" --- i. e. "%F %T" on POSIX systems
+ return {
+ status = { }, -- was: status; map abspath -> mapping
+ mappings = { }, -- TODO: check if still necessary after rewrite
+ files = { }, -- created later
+ meta = {
+ created = created or now,
+ formats = formats,
+ ["local"] = false,
+ modified = now,
+ statistics = { },
+ version = names.version,
+ },
+ }
+end
+
+--- When loading a lua file we try its binary complement first, which
+--- is assumed to be located at an identical path, carrying the suffix
+--- .luc.
+
+--- string -> (string * table)
+local load_lua_file = function (path)
+ local foundname = filereplacesuffix (path, "luc")
+ local code = nil
+
+ local fh = ioopen (foundname, "rb") -- try bin first
+ if fh then
+ local chunk = fh:read"*all"
+ fh:close()
+ code = load (chunk, "b")
+ end
+
+ if not code then --- fall back to text file
+ foundname = filereplacesuffix (path, "lua")
+ fh = ioopen(foundname, "rb")
+ if fh then
+ local chunk = fh:read"*all"
+ fh:close()
+ code = load (chunk, "t")
+ end
+ end
+
+ if not code then --- probe gzipped file
+ foundname = filereplacesuffix (path, "lua.gz")
+ local chunk = gzipload (foundname)
+ if chunk then
+ code = load (chunk, "t")
+ end
+ end
+
+ if not code then return nil, nil end
+ return foundname, code ()
+end
+
+--- define locals in scope
+local access_font_index
+local find_closest
+local flush_lookup_cache
+local generate_filedata
+local get_font_filter
+local group_modifiers
+local load_names
+local lookup_font_name
+local getmetadata
+local order_design_sizes
+local ot_fullinfo
+local read_blacklist
+local reload_db
+local lookup_fullpath
+local save_lookups
+local save_names
+local set_font_filter
+local t1_fullinfo
+local update_names
+
+--- state of the database
+local fonts_reloaded = false
+
+--- limit output when approximate font matching (luaotfload-tool -F)
+local fuzzy_limit = 1 --- display closest only
+
+--- bool? -> -> bool? -> dbobj option
+load_names = function (dry_run, no_rebuild)
+ local starttime = osgettimeofday ()
+ local foundname, data = load_lua_file (config.luaotfload.paths.index_path_lua)
+
+ if data then
+ logreport ("log", 0, "db",
+ "Font names database loaded from %s", foundname)
+ logreport ("term", 3, "db",
+ "Font names database loaded from %s", foundname)
+ logreport ("info", 3, "db", "Loading took %0.f ms.",
+ 1000 * (osgettimeofday () - starttime))
+
+ local db_version, names_version
+ if data.meta then
+ db_version = data.meta.version
+ else
+ --- Compatibility branch; the version info used to be
+ --- stored in the table root which is why updating from
+ --- an earlier index version broke.
+ db_version = data.version or -42 --- invalid
+ end
+ names_version = names.version
+ if db_version ~= names_version then
+ if math.tointeger(db_version) then
+ logreport ("both", 0, "db",
+ [[Version mismatch; expected %d, got %d.]],
+ names_version, db_version)
+ else
+ logreport ("both", 0, "db",
+ [[Version mismatch; expected %d, got invalid data.]],
+ names_version, db_version)
+ end
+ if not fonts_reloaded then
+ logreport ("both", 0, "db", [[Force rebuild.]])
+ data = update_names (initialize_namedata (get_font_filter ()),
+ true, false)
+ if not data then
+ logreport ("both", 0, "db",
+ "Database creation unsuccessful.")
+ end
+ end
+ end
+ else
+ if no_rebuild == true then
+ logreport ("both", 2, "db",
+ [[Database does not exist, skipping rebuild though.]])
+ return false
+ end
+ logreport ("both", 0, "db",
+ [[Font names database not found, generating new one.]])
+ logreport ("both", 0, "db",
+ [[This can take several minutes; please be patient.]])
+ data = update_names (initialize_namedata (get_font_filter ()),
+ nil, dry_run)
+ if not data then
+ logreport ("both", 0, "db", "Database creation unsuccessful.")
+ end
+ end
+ return data
+end
+
+--[[doc--
+
+ access_font_index -- Provide a reference of the index table. Will
+ cause the index to be loaded if not present.
+
+--doc]]--
+
+access_font_index = function ()
+ if not name_index then name_index = load_names () end
+ return name_index
+end
+
+getmetadata = function ()
+ if not name_index then
+ name_index = load_names (false, true)
+ if name_index then return tablefastcopy (name_index.meta) end
+ end
+ return false
+end
+
+--- unit -> unit
+local load_lookups
+load_lookups = function ( )
+ local foundname, data = load_lua_file(config.luaotfload.paths.lookup_path_lua)
+ if data then
+ logreport ("log", 0, "cache", "Lookup cache loaded from %s.", foundname)
+ logreport ("term", 3, "cache",
+ "Lookup cache loaded from %s.", foundname)
+ else
+ logreport ("both", 1, "cache",
+ "No lookup cache, creating empty.")
+ data = { }
+ end
+ lookup_cache = data
+end
+
+local regular_synonym = {
+ book = true,
+ normal = true,
+ plain = true,
+ regular = true,
+ roman = true,
+}
+
+local style_synonym = {
+ oblique = 'i',
+ slanted = 'i',
+ italic = 'i',
+ boldoblique = 'bi',
+ boldslanted = 'bi',
+ bolditalic = 'bi',
+ bold = 'b',
+}
+
+-- MK Determine if casefold search is requested
+local casefold_search =
+ not ({['0'] = true, ['f'] = true, [''] = true})
+ [(kpse.var_value'texmf_casefold_search' or '1'):sub(1,1)]
+-- /MK
+
+local lookup_filename = function (filename)
+ if not name_index then name_index = load_names () end
+ local files = name_index.files
+ local basedata = files.base
+ local baredata = files.bare
+ for i = 1, #location_precedence do
+ local location = location_precedence [i]
+ local basenames = basedata [location]
+ local barenames = baredata [location]
+ local idx
+ if basenames ~= nil then
+ -- MK Added fallback
+ idx = basenames [filename]
+ or casefold_search and basenames [stringlower(filename)]
+ -- /MK
+ if idx then
+ goto done
+ end
+ end
+ if barenames ~= nil then
+ for j = 1, #format_precedence do
+ local format = format_precedence [j]
+ local filemap = barenames [format]
+ if filemap then
+ -- MK Added fallback
+ idx = barenames [format] [filename]
+ or casefold_search and barenames [format] [stringlower(filename)]
+ -- /MK
+ if idx then
+ break
+ end
+ end
+ end
+ end
+::done::
+ if idx then
+ return files.full [idx]
+ end
+ end
+end
+
+--[[doc--
+
+ lookup_font_file -- The ``file:`` are ultimately delegated here.
+ The lookups are kind of a blunt instrument since they try locating
+ the file using every conceivable method, which is quite
+ inefficient. Nevertheless, resolving files that way is rarely the
+ bottleneck.
+
+--doc]]--
+
+--- string -> string * string * bool
+local lookup_font_file
+
+-- MK Added mini scope to avoid variable limit
+do
+local type1_metrics = { "tfm", "ofm", }
+-- /MK
+
+lookup_font_file = function (filename)
+ local found = lookup_filename (filename)
+
+ if not found then
+ local type = file.suffix(filename)
+ if type ~= "" then
+ found = resolvers.findfile(filename, type)
+ end
+ end
+
+ if found then
+ return found, nil, true
+ end
+
+ for i=1, #type1_metrics do
+ local format = type1_metrics[i]
+ if resolvers.findfile(filename, format) then
+ return file.addsuffix(filename, format), format, true
+ end
+ end
+
+ if not fonts_reloaded and config.luaotfload.db.update_live == true then
+ return reload_db (stringformat ("File not found: %s.", filename),
+ lookup_font_file,
+ filename)
+ end
+ return filename, nil, false
+end
+-- MK
+end
+-- /MK
+
+--[[doc--
+
+ get_font_file -- Look up the file of an entry in the mappings
+ table. If the index is valid, pass on the name and subfont index
+ after verifing the existence of the resolved file. This
+ verification differs depending the index entry’s ``location``
+ field:
+
+ * ``texmf`` fonts are verified using the (slow) function
+ ``kpse.lookup()``;
+ * other locations are tested by resolving the full path and
+ checking for the presence of a file there.
+
+--doc]]--
+
+--- int -> bool * (string * int) option
+local get_font_file = function (index)
+ local entry = name_index.mappings [index]
+ if not entry then
+ return false
+ end
+ local basename = entry.basename
+ if entry.location == "texmf" then
+ local fullname = resolvers.findfile(basename, entry.format)
+ if fullname then
+ return true, fullname, entry.subfont
+ end
+ else --- system, local
+ local fullname = name_index.files.full [index]
+ if lfsisfile (fullname) then
+ return true, fullname, entry.subfont
+ end
+ end
+ return false
+end
+
+--[[doc--
+We need to verify if the result of a cached lookup actually exists in
+the texmf or filesystem. Again, due to the schizoprenic nature of the
+font managment we have to check both the system path and the texmf.
+--doc]]--
+
+local verify_font_file = function (basename)
+ local path = lookup_fullpath (basename)
+ if path and lfsisfile(path) then
+ return true
+ end
+ if resolvers.findfile(basename) then
+ return true
+ end
+ return false
+end
+
+--[[doc--
+Lookups can be quite costly, more so the less specific they are.
+Even if we find a matching font eventually, the next time the
+user compiles Eir document E will have to stand through the delay
+again.
+Thus, some caching of results -- even between runs -- is in order.
+We’ll just store successful name: lookups in a separate cache file.
+
+type lookup_cache = (string, (string * num)) dict
+
+The spec is expected to be modified in place (ugh), so we’ll have to
+catalogue what fields actually influence its behavior.
+
+Idk what the “spec†resolver is for.
+
+ lookup inspects modifies
+ ---------- ----------------- ---------------------------
+ file: name forced, name
+ name:[*] name, style, sub, resolved, sub, name, forced
+ optsize, size
+ spec: name, sub resolved, sub, name, forced
+
+[*] name: contains both the name resolver from luatex-fonts and
+ lookup_font_name () below
+
+From my reading of font-def.lua, what a resolver does is
+basically rewrite the “name†field of the specification record
+with the resolution.
+Also, the fields “resolvedâ€, “subâ€, “force†etc. influence the outcome.
+
+--doc]]--
+
+local concat_char = "#"
+local hash_fields = {
+ --- order is important
+ "specification", "style", "sub", "optsize", "size",
+}
+local n_hash_fields = #hash_fields
+
+--- spec -> string
+local hash_request = function (specification)
+ local key = { } --- segments of the hash
+ for i=1, n_hash_fields do
+ local field = specification[hash_fields[i]]
+ if field then
+ key[#key+1] = field
+ end
+ end
+ return tableconcat(key, concat_char)
+end
+
+--- 'a -> 'a -> table -> (string * int|boolean * boolean)
+local lookup_font_name_cached
+lookup_font_name_cached = function (specification)
+ if not lookup_cache then load_lookups () end
+ local request = hash_request(specification)
+ logreport ("both", 4, "cache", "Looking for %q in cache ...",
+ request)
+
+ local found = lookup_cache [request]
+
+ --- case 1) cache positive ----------------------------------------
+ if found then --- replay fields from cache hit
+ logreport ("info", 4, "cache", "Found!")
+ local basename = found[1]
+ --- check the presence of the file in case it’s been removed
+ local success = verify_font_file (basename)
+ if success == true then
+ return basename, found[2], true
+ end
+ logreport ("both", 4, "cache",
+ "Cached file not found; resolving again.")
+ else
+ logreport ("both", 4, "cache", "Not cached; resolving.")
+ end
+
+ --- case 2) cache negative ----------------------------------------
+ --- first we resolve normally ...
+ local filename, subfont = lookup_font_name (specification)
+ if not filename then
+ return nil, nil
+ end
+ --- ... then we add the fields to the cache ... ...
+ local entry = { filename, subfont }
+ logreport ("both", 4, "cache", "New entry: %s.", request)
+ lookup_cache [request] = entry
+
+ --- obviously, the updated cache needs to be stored.
+ --- TODO this should trigger a save only once the
+ --- document is compiled (finish_pdffile callback?)
+ logreport ("both", 5, "cache", "Saving updated cache.")
+ local success = save_lookups ()
+ if not success then --- sad, but not critical
+ logreport ("both", 0, "cache", "Error writing cache.")
+ end
+ return filename, subfont
+end
+
+--- this used to be inlined; with the lookup cache we don’t
+--- have to be parsimonious wrt function calls anymore
+--- “found†is the match accumulator
+local add_to_match = function (found, size, face)
+
+ local continue = true
+
+ local optsize = face.size
+
+ if optsize and next (optsize) then
+ local dsnsize, maxsize, minsize
+ dsnsize = optsize[1]
+ maxsize = optsize[2]
+ minsize = optsize[3]
+
+ if size ~= nil
+ and (dsnsize == size or (size > minsize and size <= maxsize))
+ then
+ found[1] = face
+ continue = false ---> break
+ else
+ found[#found+1] = face
+ end
+ else
+ found[1] = face
+ continue = false ---> break
+ end
+
+ return found, continue
+end
+
+local choose_closest = function (distances)
+ local closest = 2^51
+ local match
+ for i = 1, #distances do
+ local d, index = unpack (distances [i])
+ if d < closest then
+ closest = d
+ match = index
+ end
+ end
+ return match
+end
+
+--[[doc--
+
+ choose_size -- Pick a font face of appropriate size (in sp) from
+ the list of family members with matching style. There are three
+ categories:
+
+ 1. exact matches: if there is a face whose design size equals
+ the asked size, it is returned immediately and no further
+ candidates are inspected.
+
+ 2. range matches: of all faces in whose design range the
+ requested size falls the one whose center the requested
+ size is closest to is returned.
+
+ 3. out-of-range matches: of all other faces (i. e. whose range
+ is above or below the asked size) the one is chosen whose
+ boundary (upper or lower) is closest to the requested size.
+
+ 4. default matches: if no design size or a design size of zero
+ is requested, the face with the default size is returned.
+
+--doc]]--
+
+--- int * int * int * int list -> int -> int
+local function choose_size (sizes, askedsize)
+ local mappings = name_index.mappings
+ local exact
+ local inrange = { } --- distance * index list
+ local norange = { } --- distance * index list
+ local fontname, subfont
+ if askedsize ~= 0 then
+ --- firstly, look for an exactly matching design size or
+ --- matching range
+ for i = 1, #sizes do
+ local dsnsize, high, low, index = unpack (sizes [i])
+ if dsnsize == askedsize then
+ --- exact match, this is what we were looking for
+ return index
+ elseif askedsize <= low then
+ --- below range, add to the norange table
+ local d = low - askedsize
+ norange [#norange + 1] = { d, index }
+ elseif askedsize > high then
+ --- beyond range, add to the norange table
+ local d = askedsize - high
+ norange [#norange + 1] = { d, index }
+ else
+ --- range match
+ local d = 0
+
+ -- should always be true. Just in case there's some
+ -- weried fonts out there
+ if dsnsize > low and dsnsize < high then
+ d = dsnsize - askedsize
+ else
+ d = ((low + high) / 2) - askedsize
+ end
+ if d < 0 then
+ d = -d
+ end
+
+ inrange [#inrange + 1] = { d, index }
+ end
+ end
+ end
+::skip::
+ if #inrange > 0 then
+ return choose_closest (inrange)
+ elseif #norange > 0 then
+ return choose_closest (norange)
+ elseif sizes.default then
+ return sizes.default
+ elseif askedsize == 0 then
+ return choose_size(sizes, 655360) -- If there is no default size and no size specified, just guess
+ end
+end
+
+--[[doc--
+
+ lookup_familyname -- Query the families table for an entry
+ matching the specification.
+ The parameters “name†and “style†are pre-sanitized.
+
+--doc]]--
+--- spec -> string -> string -> int -> string * int * bool
+local lookup_familyname = function (specification, name, style, askedsize)
+ local families = name_index.families
+ local mappings = name_index.mappings
+ local candidates = nil
+ local fallback = true
+ --- arrow code alert
+ for i = 1, #location_precedence do
+ local location = location_precedence [i]
+ local locgroup = families [location]
+ for j = 1, #format_precedence do
+ local format = format_precedence [j]
+ local fmtgroup = locgroup [format]
+ if fmtgroup then
+ local familygroup = fmtgroup [name]
+ if familygroup then
+ local stylegroup = familygroup [style]
+ if stylegroup then --- suitable match
+ candidates = stylegroup
+ fallback = false
+ goto done
+ elseif not candidates then
+ candidates = familygroup.r
+ end
+ end
+ end
+ end
+ end
+ if not candidates then
+ return nil, nil
+ end
+::done::
+ index = choose_size (candidates, askedsize)
+ local success, resolved, subfont = get_font_file (index)
+ if not success then
+ return nil, nil
+ end
+ logreport ("info", 2, "db", "Match found: %s(%d).",
+ resolved, subfont or 0)
+ return resolved, subfont, fallback
+end
+
+local lookup_fontname = function (specification, name)
+ local mappings = name_index.mappings
+ local fallback = nil
+ local lastresort = nil
+ for i = 1, #mappings do
+ local face = mappings [i]
+ local typographicsubfamily = face.typographicsubfamily
+ local subfamily = face.subfamily
+ if face.fontname == name
+ or face.fullname == name
+ or face.psname == name
+ then
+ return face.fullpath, face.subfont
+ end
+ end
+ return nil, nil
+end
+
+local design_size_dimension --- scale asked size if not using bp
+local set_size_dimension --- called from config
+do
+
+ --- cf. TeXbook p. 57; the index stores sizes pre-scaled from bp to
+ --- sp. This allows requesting sizes we got from the TeX end
+ --- without further conversion. For the other options *pt* and *dd*
+ --- we scale the requested size as though the value in the font was
+ --- specified in the requested unit.
+
+ --- From @zhouyan:
+
+ --- Let P be the asked size in pt, and Aᵤ = CᵤP, where u is the
+ --- designed unit, pt, bp, or dd, and
+ ---
+ --- Cpt = 1, Cbp = 7200/7227, Cdd = 1157/1238.
+ ---
+ --- That is, Aᵤ is the asked size in the desired unit. Let D be the
+ --- de-sign size (assumed to be in the unit of bp) as reported by
+ --- the font (divided by 10; in all the following we ignore the
+ --- factor 2^16 ).
+ ---
+ --- For simplicity, consider only the case of exact match to the
+ --- design size. That is, we would like to have Aᵤ = D. Let A′ᵤ = αᵤP
+ --- and D′ = βD be the scaled values used in comparisons. For the
+ --- comparison to work correctly, we need,
+ ---
+ --- Aᵤ = D ⟺ A′ᵤ = D′ ,
+ ---
+ --- and thus αᵤ = βCᵤ. The fix in PR 400 is the case of β = 1. The
+ --- fix for review is β = 7227/7200, and the value of αᵤ is thus
+ --- correct for pt, bp, but not for dd.
+
+ local dimens = {
+ bp = false,
+ pt = 7227 / 7200,
+ dd = (7227 / 7200) * (1157 / 1238),
+ }
+
+ design_size_dimension = dimens.bp
+
+ set_size_dimension = function (dim)
+ local conv = dimens [dim]
+ if conv ~= nil then
+ logreport ("both", 4, "db",
+ "Interpreting design sizes as %q, factor %.6f.",
+ dim, conv or 1)
+ design_size_dimension = conv
+ return
+ end
+ logreport ("both", 0, "db",
+ "Invalid dimension %q requested for design sizes; \z
+ ignoring.")
+ end
+end
+
+
+--[[doc--
+
+ lookup_font_name -- Perform a name: lookup. This first queries the
+ font families table and, if there is no match for the spec, the
+ font names table.
+ The return value is a pair consisting of the file name and the
+ subfont index if appropriate..
+
+ the request specification has the fields:
+
+ · features: table
+ · normal: set of { ccmp clig itlc kern liga locl mark mkmk rlig }
+ · ???
+ · forced: string
+ · lookup: "name"
+ · method: string
+ · name: string
+ · resolved: string
+ · size: int
+ · specification: string (== <lookup> ":" <name>)
+ · sub: string
+
+ The “size†field deserves special attention: if its value is
+ negative, then it actually specifies a scalefactor of the
+ design size of the requested font. This happens e.g. if a font is
+ requested without an explicit “at sizeâ€. If the font is part of a
+ larger collection with different design sizes, this complicates
+ matters a bit: Normally, the resolver prefers fonts that have a
+ design size as close as possible to the requested size. If no
+ size specified, then the design size is implied. But which design
+ size should that be? Xetex appears to pick the “normal†(unmarked)
+ size: with Adobe fonts this would be the one that is neither
+ “caption†nor “subhead†nor “display†&c ... For fonts by Adobe this
+ seems to be the one that does not receive a “typographicsubfamilyâ€
+ field. (IOW Adobe uses the “typographicsubfamily†field to encode
+ the design size in more or less human readable format.) However,
+ this is not true of LM and EB Garamond. As this matters only where
+ there are multiple design sizes to a given font/style combination,
+ we put a workaround in place that chooses that unmarked version.
+
+ The first return value of “lookup_font_name†is the file name of the
+ requested font (string). It can be passed to the fullname resolver
+ get_font_file().
+ The second value is either “false†or an integer indicating the
+ subfont index in a TTC.
+
+--doc]]--
+
+--- table -> string * (int | bool)
+lookup_font_name = function (specification)
+ if not name_index then name_index = load_names () end
+ local name = sanitize_fontname (specification.name)
+ local style = sanitize_fontname (specification.style) or "r"
+ local askedsize = specification.optsize
+
+ if askedsize then
+ askedsize = tonumber (askedsize) * 65536
+ else
+ askedsize = specification.size
+ if not askedsize or askedsize < 0 then
+ askedsize = 0
+ end
+ end
+
+ if design_size_dimension ~= false then
+ askedsize = design_size_dimension * askedsize
+ end
+
+ local resolved, subfont, fallback = lookup_familyname (specification,
+ name,
+ style,
+ askedsize)
+ if not resolved or fallback then
+ local new_resolved, new_subfont = lookup_fontname (specification,
+ name,
+ style)
+ if new_resolved then
+ resolved, subfont = new_resolved, new_subfont
+ end
+ end
+
+ if not resolved then
+ if not fonts_reloaded and config.luaotfload.db.update_live == true then
+ return reload_db (stringformat ("Font %s not found.",
+ specification.name or "<?>"),
+ lookup_font_name,
+ specification)
+ end
+ end
+ return resolved, subfont
+end
+
+lookup_fullpath = function (fontname, ext) --- getfilename()
+ if not name_index then name_index = load_names () end
+ local files = name_index.files
+ local basedata = files.base
+ local baredata = files.bare
+ for i = 1, #location_precedence do
+ local location = location_precedence [i]
+ local basenames = basedata [location]
+ local idx
+ if basenames ~= nil then
+ -- MK Added fallback
+ idx = basenames [fontname]
+ or casefold_search and basenames [stringlower(fontname)]
+ -- /MK
+ end
+ if ext then
+ local barenames = baredata [location] [ext]
+ if not idx and barenames ~= nil then
+ -- MK Added fallback
+ idx = barenames [fontname]
+ or casefold_search and barenames [stringlower(fontname)]
+ -- /MK
+ end
+ end
+ if idx then
+ return files.full [idx]
+ end
+ end
+ return ""
+end
+
+--- when reload is triggered we update the database
+--- and then re-run the caller with the arg list
+
+--- string -> ('a -> 'a) -> 'a list -> 'a
+reload_db = function (why, caller, ...)
+ local namedata = name_index
+ local formats = tableconcat (namedata.meta.formats, ",")
+
+ logreport ("both", 0, "db",
+ "Reload initiated (formats: %s); reason: %q.",
+ formats, why)
+
+ set_font_filter (formats)
+ namedata = update_names (namedata, false, false)
+
+ if namedata then
+ fonts_reloaded = true
+ name_index = namedata
+ return caller (...)
+ end
+
+ logreport ("both", 0, "db", "Database update unsuccessful.")
+end
+
+--- string -> string -> int
+local iterative_levenshtein = function (s1, s2)
+
+ local costs = { }
+ local len1, len2 = #s1, #s2
+
+ for i = 0, len1 do
+ local last = i
+ for j = 0, len2 do
+ if i == 0 then
+ costs[j] = j
+ else
+ if j > 0 then
+ local current = costs[j-1]
+ if stringsub(s1, i, i) ~= stringsub(s2, j, j) then
+ current = mathmin(current, last, costs[j]) + 1
+ end
+ costs[j-1] = last
+ last = current
+ end
+ end
+ end
+ if i > 0 then costs[len2] = last end
+ end
+
+ return costs[len2]--- lower right has the distance
+end
+
+--- string list -> string list
+local delete_dupes = function (lst)
+ local n0 = #lst
+ if n0 == 0 then return lst end
+ tablesort (lst)
+ local ret = { }
+ local last
+ for i = 1, n0 do
+ local cur = lst[i]
+ if cur ~= last then
+ last = cur
+ ret[#ret + 1] = cur
+ end
+ end
+ logreport (false, 8, "query",
+ "Removed %d duplicate names.", n0 - #ret)
+ return ret
+end
+
+--- string -> int -> bool
+find_closest = function (name, limit)
+ local name = sanitize_fontname (name)
+ limit = limit or fuzzy_limit
+
+ if not name_index then name_index = load_names () end
+ if not name_index or type (name_index) ~= "table" then
+ if not fonts_reloaded then
+ return reload_db("Font index missing.", find_closest, name)
+ end
+ return false
+ end
+
+ local by_distance = { } --- (int, string list) dict
+ local distances = { } --- int list
+ local cached = { } --- (string, int) dict
+ local mappings = name_index.mappings
+ local n_fonts = #mappings
+
+ for n = 1, n_fonts do
+ local current = mappings[n]
+ --[[
+ This is simplistic but surpisingly fast.
+ Matching is performed against the “fullname†field
+ of a db record in preprocessed form. We then store the
+ raw “fullname†at its edit distance.
+ We should probably do some weighting over all the
+ font name categories as well as whatever agrep
+ does.
+ --]]
+ local fullname = current.plainname
+ local sfullname = current.fullname
+ local dist = cached[sfullname]--- maybe already calculated
+
+ if not dist then
+ dist = iterative_levenshtein(name, sfullname)
+ cached[sfullname] = dist
+ end
+ local namelst = by_distance[dist]
+ if not namelst then --- first entry
+ namelst = { fullname }
+ distances[#distances+1] = dist
+ else --- append
+ namelst[#namelst+1] = fullname
+ end
+
+ by_distance[dist] = namelst
+ end
+
+ --- print the matches according to their distance
+ local n_distances = #distances
+ if n_distances > 0 then --- got some data
+ tablesort(distances)
+ limit = mathmin(n_distances, limit)
+ logreport (false, 1, "query",
+ "Displaying %d distance levels.", limit)
+
+ for i = 1, limit do
+ local dist = distances[i]
+ local namelst = delete_dupes (by_distance[dist])
+ logreport (false, 0, "query",
+ "Distance from \"%s\": %s\n "
+ .. tableconcat (namelst, "\n "),
+ name, dist)
+ end
+
+ return true
+ end
+ return false
+end --- find_closest()
+
+--- string -> uint -> bool * (string | rawdata)
+local read_font_file = function (filename, subfont)
+ local fontdata = otfhandler.readers.getinfo (filename,
+ { subfont = subfont
+ , platformnames = true
+ , rawfamilynames = true
+ })
+ local msg = fontdata.comment
+ if msg then
+ return false, msg
+ end
+ return true, fontdata
+end
+
+local load_font_file = function (filename, subfont)
+ local err, ret = read_font_file (filename, subfont)
+ if err == false then
+ logreport ("both", 1, "db", "ERROR: failed to open %q: %q.",
+ tostring (filename), tostring (ret))
+ return
+ end
+ return ret
+end
+
+--- Design sizes in the fonts are specified in decipoints. For the
+--- index these values are prescaled to sp which is what we’re dealing
+--- with at the TeX end.
+
+local get_size_info do --- too many upvalues :/
+ --- rawdata -> (int * int * int | bool)
+
+ local sp = 2^16 -- pt
+ local bp = 7227 / 7200 -- pt
+
+ get_size_info = function (rawinfo)
+ local design_size = rawinfo.design_size
+ local design_range_top = rawinfo.design_range_top
+ local design_range_bottom = rawinfo.design_range_bottom
+
+ local fallback_size = design_size ~= 0 and design_size
+ or design_range_bottom ~= 0 and design_range_bottom
+ or design_range_top ~= 0 and design_range_top
+
+ if fallback_size then
+ design_size = ((design_size or fallback_size) * sp) / 10
+ design_range_top = ((design_range_top or fallback_size) * sp) / 10
+ design_range_bottom = ((design_range_bottom or fallback_size) * sp) / 10
+
+ design_size = design_size * bp
+ design_range_top = design_range_top * bp
+ design_range_bottom = design_range_bottom * bp
+
+ return {
+ design_size, design_range_top, design_range_bottom,
+ }
+ end
+
+ return false
+ end
+end ---[local get_size_info]
+
+--[[doc--
+ map_enlish_names -- Names-table for Lua fontloader objects. This
+ may vanish eventually once we ditch Fontforge completely. Only
+ subset of entries of that table are actually relevant so we’ll
+ stick to that part.
+--doc]]--
+
+local get_english_names = function (metadata)
+ local namesource
+ local platformnames = metadata.platformnames
+ --[[--
+ Hans added the “platformnames†option for us to access parts of
+ the original name table. The names are unreliable and
+ completely disorganized, sure, but the Windows variant of the
+ field often contains the superior information. Case in point:
+
+ ["platformnames"]={
+ ["macintosh"]={
+ ["compatiblefullname"]="Garamond Premr Pro Smbd It",
+ ["family"]="Garamond Premier Pro",
+ ["fullname"]="Garamond Premier Pro Semibold Italic",
+ ["postscriptname"]="GaramondPremrPro-SmbdIt",
+ ["subfamily"]="Semibold Italic",
+ },
+ ["windows"]={
+ ["family"]="Garamond Premr Pro Smbd",
+ ["fullname"]="GaramondPremrPro-SmbdIt",
+ ["postscriptname"]="GaramondPremrPro-SmbdIt",
+ ["subfamily"]="Italic",
+ ["typographicfamily"]="Garamond Premier Pro",
+ ["typographicsubfamily"]="Semibold Italic",
+ },
+ },
+
+ The essential bit is contained as “typographicfamily†(which we
+ call for historical reasons the “preferred familyâ€) and the
+ “subfamilyâ€. Only Why this is the case, only Adobe knows for
+ certain.
+ --]]--
+ if platformnames then
+ if platformnames.windows and platformnames.macintosh then
+ return table.merge(platformnames.macintosh, platformnames.windows)
+ end
+ namesource = platformnames.windows or platformnames.macintosh
+ end
+ return namesource or metadata
+end
+
+--[[--
+ In case of broken PS names we set some dummies.
+
+ For this reason we copy what is necessary whilst keeping the table
+ structure the same as in the tfmdata.
+--]]--
+local get_raw_info = function (metadata, basename)
+ local fontname = metadata.fontname
+ local fullname = metadata.fullname
+
+ if not fontname or not fullname then
+ --- Broken names table, e.g. avkv.ttf with UTF-16 strings;
+ --- we put some dummies in place like the fontloader
+ --- (font-otf.lua) does.
+ logreport ("both", 3, "db",
+ "Invalid names table of font %s, using dummies. \z
+ Reported: fontname=%q, fullname=%q.",
+ tostring (basename), tostring (fontname),
+ tostring (fullname))
+ fontname = "bad-fontname-" .. basename
+ fullname = "bad-fullname-" .. basename
+ end
+
+ return {
+ familyname = metadata.familyname,
+ fontname = fontname,
+ fullname = fullname,
+ italicangle = metadata.italicangle,
+ names = metadata.names,
+ units_per_em = metadata.units_per_em,
+ version = metadata.version,
+ design_size = metadata.design_size or metadata.designsize,
+ design_range_top = metadata.design_range_top or metadata.maxsize,
+ design_range_bottom = metadata.design_range_bottom or metadata.minsize,
+ }
+end
+
+local organize_namedata = function (rawinfo,
+ nametable,
+ basename,
+ info)
+ local default_name = nametable.compatiblefullname
+ or nametable.fullname
+ or nametable.postscriptname
+ or rawinfo.fullname
+ or rawinfo.fontname
+ or info.fullname
+ or info.fontname
+ local default_family = nametable.typographicfamily
+ or nametable.family
+ or rawinfo.familyname
+ or info.familyname
+-- local default_modifier = nametable.typographicsubfamily
+-- or nametable.subfamily
+ local fontnames = {
+ --- see
+ --- https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html
+ --- http://www.microsoft.com/typography/OTSPEC/name.htm#NameIDs
+ english = {
+ --- where a “compatiblefullname†field is given, the value
+ --- of “fullname†is either identical or differs by
+ --- separating the style with a hyphen and omitting spaces.
+ --- (According to the spec, “compatiblefullname†is
+ --- “Macintosh onlyâ€.) Of the three “fullname†fields, this
+ --- one appears to be the one with the entire name given in
+ --- a legible, non-abbreviated fashion, for most fonts at
+ --- any rate. However, in some fonts (e.g. CMU) all three
+ --- fields are identical.
+ fullname = --[[ 18 ]] nametable.compatiblefullname
+ or --[[ 4 ]] nametable.fullname
+ or default_name,
+ --- we keep both the “preferred family†and the “familyâ€
+ --- values around since both are valid but can turn out
+ --- quite differently, e.g. with Latin Modern:
+ --- typographicfamily: “Latin Modern Sansâ€,
+ --- family: “LM Sans 10â€
+ family = --[[ 1 ]] nametable.family or default_family,
+ subfamily = --[[ 2 ]] nametable.subfamily or rawinfo.subfamilyname,
+ psname = --[[ 6 ]] nametable.postscriptname,
+ typographicfamily = --[[ 16 ]] nametable.typographicfamily,
+ typographicsubfamily = --[[ 17 ]] nametable.typographicsubfamily,
+ },
+
+ metadata = {
+ fullname = rawinfo.fullname,
+ fontname = rawinfo.fontname,
+ familyname = rawinfo.familyname,
+ },
+
+ info = {
+ fullname = info.fullname,
+ familyname = info.familyname,
+ fontname = info.fontname,
+ },
+ }
+
+ return {
+ sanitized = sanitize_fontnames (fontnames),
+ fontname = rawinfo.fontname,
+ fullname = rawinfo.fullname,
+ familyname = rawinfo.familyname,
+ }
+end
+
+
+local dashsplitter = lpegsplitat "-"
+
+local split_fontname = function (fontname)
+ --- sometimes the style hides in the latter part of the
+ --- fontname, separated by a dash, e.g. “Iwona-Regularâ€,
+ --- “GFSSolomos-Regularâ€
+ local splitted = { lpegmatch (dashsplitter, fontname) }
+ if next (splitted) then
+ return sanitize_fontname (splitted [#splitted])
+ end
+end
+
+local organize_styledata = function (metadata, rawinfo, info)
+ local pfminfo = metadata.pfminfo
+ local names = rawinfo.names
+ return {
+ --- see http://www.microsoft.com/typography/OTSPEC/features_pt.htm#size
+ size = get_size_info (rawinfo),
+ pfmweight = pfminfo and pfminfo.weight or metadata.pfmweight or 400,
+ weight = rawinfo.weight or metadata.weight or "unspecified",
+ split = split_fontname (rawinfo.fontname),
+ width = pfminfo and pfminfo.width or metadata.pfmwidth,
+ italicangle = metadata.italicangle,
+ --- this is for querying, see www.ntg.nl/maps/40/07.pdf for details
+ units_per_em = metadata.units_per_em or metadata.units,
+ version = metadata.version,
+ }
+end
+
+--[[doc--
+The data inside an Opentype font file can be quite heterogeneous.
+Thus in order to get the relevant information, parts of the original
+table as returned by the font file reader need to be relocated.
+--doc]]--
+
+--- string -> int -> bool -> string -> fontentry
+
+ot_fullinfo = function (filename,
+ subfont,
+ location,
+ basename,
+ format,
+ info)
+
+ local metadata = load_font_file (filename, subfont)
+ if not metadata then
+ return nil
+ end
+
+ local rawinfo = get_raw_info (metadata, basename)
+ local nametable = get_english_names (metadata)
+ local namedata = organize_namedata (rawinfo,
+ nametable,
+ basename,
+ info)
+ local style = organize_styledata (metadata,
+ rawinfo,
+ info)
+ local res = {
+ file = { base = basename,
+ full = filename,
+ subfont = subfont,
+ location = location or "system" },
+ format = format,
+ names = namedata,
+ style = style,
+ version = rawinfo.version,
+ }
+ return res
+end
+
+--[[doc--
+
+ Type1 font inspector. In comparison with OTF, PFB’s contain a good
+ deal less name fields which makes it tricky in some parts to find a
+ meaningful representation for the database.
+
+ Good read: http://www.adobe.com/devnet/font/pdfs/5004.AFM_Spec.pdf
+
+--doc]]--
+
+--- string -> int -> bool -> string -> fontentry
+
+t1_fullinfo = function (filename, _subfont, location, basename, format)
+ local sanitized
+ local metadata = load_font_file (filename)
+ local fontname = metadata.fontname
+ local fullname = metadata.fullname
+ local familyname = metadata.familyname
+ local italicangle = metadata.italicangle
+ local style = ""
+ local weight
+
+ sanitized = sanitize_fontnames ({
+ fontname = fontname,
+ psname = fullname,
+ familyname = familyname,
+ weight = metadata.weight, --- string identifier
+ typographicsubfamily = style,
+ })
+
+ weight = sanitized.weight
+
+ if weight == "bold" then
+ style = weight
+ end
+
+ if italicangle ~= 0 then
+ style = style .. "italic"
+ end
+
+ return {
+ basename = basename,
+ fullpath = filename,
+ subfont = false,
+ location = location or "system",
+ format = format,
+ fullname = sanitized.fullname,
+ fontname = sanitized.fontname,
+ familyname = sanitized.familyname,
+ plainname = fullname,
+ psname = sanitized.fontname,
+ version = metadata.version,
+ size = false,
+ typographicsubfamily = style ~= "" and style or weight,
+ weight = metadata.pfminfo and pfminfo.weight or 400,
+ italicangle = italicangle,
+ }
+end
+
+local loaders = {
+ otf = ot_fullinfo,
+ ttc = ot_fullinfo,
+ ttf = ot_fullinfo,
+ afm = t1_fullinfo,
+ pfb = t1_fullinfo,
+}
+
+--- not side-effect free!
+
+local compare_timestamps = function (fullname,
+ currentstatus,
+ currententrystatus,
+ currentmappings,
+ targetstatus,
+ targetentrystatus,
+ targetmappings)
+
+ local currenttimestamp = currententrystatus
+ and currententrystatus.timestamp
+ local targettimestamp = lfsattributes (fullname, "modification")
+
+ if targetentrystatus ~= nil
+ and targetentrystatus.timestamp == targettimestamp then
+ logreport ("log", 3, "db", "Font %q already read.", fullname)
+ return false
+ end
+
+ targetentrystatus.timestamp = targettimestamp
+ targetentrystatus.index = targetentrystatus.index or { }
+
+ if currenttimestamp == targettimestamp
+ and not targetentrystatus.index [1]
+ then
+ --- copy old namedata into new
+
+ for _, currentindex in next, currententrystatus.index do
+
+ local targetindex = #targetentrystatus.index
+ local fullinfo = currentmappings [currentindex]
+ local location = #targetmappings + 1
+
+ targetmappings [location] = fullinfo
+ targetentrystatus.index [targetindex + 1] = location
+ end
+
+ logreport ("log", 3, "db", "Font %q already indexed.", fullname)
+
+ return false
+ end
+
+ return true
+end
+
+local insert_fullinfo = function (fullname,
+ basename,
+ n_font,
+ loader,
+ format,
+ location,
+ targetmappings,
+ targetentrystatus,
+ info)
+
+ local fullinfo = loader (fullname, n_font,
+ location, basename,
+ format, info)
+
+ if not fullinfo then
+ return false
+ end
+
+ local index = targetentrystatus.index [n_font]
+
+ if not index then
+ index = #targetmappings + 1
+ end
+
+ targetmappings [index] = fullinfo
+ targetentrystatus.index [n_font] = index
+
+ return true
+end
+
+
+
+--- we return true if the font is new or re-indexed
+--- string -> dbobj -> dbobj -> bool
+
+local read_font_names = function (fullname,
+ currentnames,
+ targetnames,
+ location)
+
+ local targetmappings = targetnames.mappings
+ local targetstatus = targetnames.status --- by full path
+ local targetentrystatus = targetstatus [fullname]
+
+ if targetentrystatus == nil then
+ targetentrystatus = { }
+ targetstatus [fullname] = targetentrystatus
+ end
+
+ local currentmappings = currentnames.mappings
+ local currentstatus = currentnames.status
+ local currententrystatus = currentstatus [fullname]
+
+ local basename = filebasename (fullname)
+ local barename = filenameonly (fullname)
+ local entryname = fullname
+
+ if location == "texmf" then
+ entryname = basename
+ end
+
+ --- 1) skip if blacklisted
+
+ if names.blacklist[fullname] or names.blacklist[basename] then
+ logreport ("log", 2, "db",
+ "Ignoring blacklisted font %q.", fullname)
+ return false
+ end
+
+ --- 2) skip if known with same timestamp
+
+ if not compare_timestamps (fullname,
+ currentstatus,
+ currententrystatus,
+ currentmappings,
+ targetstatus,
+ targetentrystatus,
+ targetmappings)
+ then
+ return false
+ end
+
+ --- 3) new font; choose a loader, abort if unknown
+
+ local format = stringlower (filesuffix (basename))
+ local loader = loaders [format] --- ot_fullinfo, t1_fullinfo
+
+ if not loader then
+ logreport ("both", 0, "db",
+ "Unknown format: %q, skipping.", format)
+ return false
+ end
+
+ --- 4) get basic info, abort if fontloader can’t read it
+
+ local err, info = read_font_file (fullname)
+
+ if err == false then
+ logreport ("log", 1, "db",
+ "Failed to read basic information from %q: %q",
+ basename, tostring (info))
+ return false
+ end
+
+
+ --- 5) check for subfonts and process each of them
+
+ if type (info) == "table" and #info >= 1 then --- ttc
+
+ local success = false --- true if at least one subfont got read
+
+ for n_font = 1, #info do
+ if insert_fullinfo (fullname, basename, n_font,
+ loader, format, location,
+ targetmappings, targetentrystatus,
+ info)
+ then
+ success = true
+ end
+ end
+
+ return success
+ end
+
+ return insert_fullinfo (fullname, basename, false,
+ loader, format, location,
+ targetmappings, targetentrystatus,
+ info)
+end
+
+local path_normalize
+do
+ --- os.type and os.name are constants so we
+ --- choose a normalization function in advance
+ --- instead of testing with every call
+ local os_type, os_name = os.type, os.name
+ local filecollapsepath = filecollapsepath
+ local lfsreadlink = lfs.readlink
+
+ --- windows and dos
+ if os_type == "windows" or os_type == "msdos" then
+ --- ms platfom specific stuff
+ path_normalize = function (path)
+ path = stringgsub(path, '\\', '/')
+ path = stringlower(path)
+ path = filecollapsepath(path)
+ return path
+ end
+--[[doc--
+ The special treatment for cygwin was removed with a patch submitted
+ by Ken Brown.
+ Reference: http://cygwin.com/ml/cygwin/2013-05/msg00006.html
+--doc]]--
+
+ else -- posix
+ path_normalize = function (path)
+ local dest = lfsreadlink(path)
+ if dest then
+ if kpsereadable_file(dest) then
+ path = dest
+ elseif kpsereadable_file(filejoin(filedirname(path), dest)) then
+ path = filejoin(file.dirname(path), dest)
+ else
+ -- broken symlink?
+ end
+ end
+ path = filecollapsepath(path)
+ return path
+ end
+ end
+end
+
+local blacklist = { }
+local p_blacklist --- prefixes of dirs
+
+--- string list -> string list
+local collapse_prefixes = function (lst)
+ --- avoid redundancies in blacklist
+ if #lst < 2 then
+ return lst
+ end
+
+ tablesort(lst)
+ local cur = lst[1]
+ local result = { cur }
+ for i=2, #lst do
+ local elm = lst[i]
+ if stringsub(elm, 1, #cur) ~= cur then
+ --- different prefix
+ cur = elm
+ result[#result+1] = cur
+ end
+ end
+ return result
+end
+
+--- string list -> string list -> (string, bool) hash_t
+local create_blacklist = function (blacklist, whitelist)
+ local result = { }
+ local dirs = { }
+
+ logreport ("info", 2, "db", "Blacklisting %d files and directories.",
+ #blacklist)
+ for i=1, #blacklist do
+ local entry = blacklist[i]
+ if lfsisdir(entry) then
+ dirs[#dirs+1] = entry
+ else
+ result[blacklist[i]] = true
+ end
+ end
+
+ logreport ("info", 2, "db", "Whitelisting %d files.", #whitelist)
+ for i=1, #whitelist do
+ result[whitelist[i]] = nil
+ end
+
+ dirs = collapse_prefixes(dirs)
+
+ --- build the disjunction of the blacklisted directories
+ for i=1, #dirs do
+ local p_dir = P(dirs[i])
+ if p_blacklist then
+ p_blacklist = p_blacklist + p_dir
+ else
+ p_blacklist = p_dir
+ end
+ end
+
+ if p_blacklist == nil then
+ --- always return false
+ p_blacklist = lpeg.Cc(false)
+ end
+
+ return result
+end
+
+--- unit -> unit
+read_blacklist = function ()
+ local files = {
+ kpselookup ("luaotfload-blacklist.cnf",
+ {all=true, format="tex"})
+ }
+ local blacklist = { }
+ local whitelist = { }
+
+ if files and type(files) == "table" then
+ for _, path in next, files do
+ for line in iolines (path) do
+ line = stringstrip(line) -- to get rid of lines like " % foo"
+ local first_chr = stringsub(line, 1, 1)
+ if first_chr == "%" or stringis_empty(line) then
+ -- comment or empty line
+ elseif first_chr == "-" then
+ logreport ("both", 3, "db",
+ "Whitelisted file %q via %q.",
+ line, path)
+ whitelist[#whitelist+1] = stringsub(line, 2, -1)
+ else
+ local cmt = stringfind(line, "%%")
+ if cmt then
+ line = stringsub(line, 1, cmt - 1)
+ end
+ line = stringstrip(line)
+ logreport ("both", 3, "db",
+ "Blacklisted file %q via %q.",
+ line, path)
+ blacklist[#blacklist+1] = line
+ end
+ end
+ end
+ end
+ names.blacklist = create_blacklist(blacklist, whitelist)
+end
+
+local p_font_filter
+
+do
+ local extension_pattern = function (list)
+ if type (list) ~= "table" or #list == 0 then return P(-1) end
+ local pat
+ for i=#list, 1, -1 do
+ local e = list[i]
+ if not pat then
+ pat = P(e)
+ else
+ pat = pat + P(e)
+ end
+ end
+ pat = pat * P(-1)
+ return (1 - pat)^1 * pat
+ end
+
+ --- small helper to adjust the font filter pattern (--formats
+ --- option)
+
+ local current_formats = { }
+
+ set_font_filter = function (formats)
+
+ if not formats or type (formats) ~= "string" then
+ return
+ end
+
+ if splitcomma == nil then
+ splitcomma = luaotfload.parsers and luaotfload.parsers.splitcomma
+ end
+ if stringsub (formats, 1, 1) == "+" then -- add
+ formats = lpegmatch (splitcomma, stringsub (formats, 2))
+ if formats then
+ current_formats = tableappend (current_formats, formats)
+ end
+ elseif stringsub (formats, 1, 1) == "-" then -- add
+ formats = lpegmatch (splitcomma, stringsub (formats, 2))
+ if formats then
+ local newformats = { }
+ for i = 1, #current_formats do
+ local fmt = current_formats[i]
+ local include = true
+ for j = 1, #formats do
+ if current_formats[i] == formats[j] then
+ include = false
+ goto skip
+ end
+ end
+ newformats[#newformats+1] = fmt
+ ::skip::
+ end
+ current_formats = newformats
+ end
+ else -- set
+ formats = lpegmatch (splitcomma, formats)
+ if formats then
+ current_formats = formats
+ end
+ end
+
+ p_font_filter = extension_pattern (current_formats)
+ end
+
+ get_font_filter = function (formats)
+ return tablefastcopy (current_formats)
+ end
+end
+
+local locate_matching_pfb = function (afmfile, dir)
+ local pfbname = filereplacesuffix (afmfile, "pfb")
+ local pfbpath = dir .. "/" .. pfbname
+ if lfsisfile (pfbpath) then
+ return pfbpath
+ end
+ --- Check for match in texmf too
+ return kpsefind_file (pfbname, "type1 fonts")
+end
+
+local process_dir_tree
+process_dir_tree = function (acc, dirs, done)
+ if not next (dirs) then --- done
+ return acc
+ end
+
+ local pwd = lfscurrentdir ()
+ local dir = dirs[#dirs]
+ dirs[#dirs] = nil
+
+ if not lfschdir (dir) then
+ --- Cannot cd; skip.
+ return process_dir_tree (acc, dirs, done)
+ end
+
+ dir = lfscurrentdir () --- resolve symlinks
+ lfschdir (pwd)
+ if tablecontains (done, dir) then
+ --- Already traversed. Note that it’d be unsafe to rely on the
+ --- hash part above due to Lua only processing up to 32 bytes
+ --- of string data. The lookup shouldn’t impact performance too
+ --- much but we could check the performance of alternative data
+ --- structures at some point.
+ return process_dir_tree (acc, dirs, done)
+ end
+
+ local newfiles = { }
+ local blacklist = names.blacklist
+ for ent in lfsdir (dir) do
+ --- filter right away
+ if ent ~= "." and ent ~= ".." and not blacklist[ent] then
+ local fullpath = dir .. "/" .. ent
+ if lfsisdir (fullpath)
+ and not lpegmatch (p_blacklist, fullpath)
+ then
+ dirs[#dirs+1] = fullpath
+ elseif lfsisfile (fullpath) then
+ ent = stringlower (ent)
+ if lpegmatch (p_font_filter, ent) then
+ if filesuffix (ent) == "afm" then
+ local pfbpath = locate_matching_pfb (ent, dir)
+ if pfbpath then
+ newfiles[#newfiles+1] = pfbpath
+ end
+ end
+ newfiles[#newfiles+1] = fullpath
+ end
+ end
+ end
+ end
+ done [#done + 1] = dir
+ return process_dir_tree (tableappend (acc, newfiles), dirs, done)
+end
+
+local process_dir = function (dir)
+ local pwd = lfscurrentdir ()
+ if lfschdir (dir) then
+ dir = lfscurrentdir () --- resolve symlinks
+ lfschdir (pwd)
+
+ local files = { }
+ local blacklist = names.blacklist
+ for ent in lfsdir (dir) do
+ if ent ~= "." and ent ~= ".." and not blacklist[ent] then
+ local fullpath = dir .. "/" .. ent
+ if lfsisfile (fullpath) then
+ ent = stringlower (ent)
+ if lpegmatch (p_font_filter, ent)
+ then
+ if filesuffix (ent) == "afm" then
+ local pfbpath = locate_matching_pfb (ent, dir)
+ if pfbpath then
+ files[#files+1] = pfbpath
+ end
+ else
+ files[#files+1] = fullpath
+ end
+ end
+ end
+ end
+ end
+ return files
+ end
+ return { }
+end
+
+--- string -> bool -> string list
+local find_font_files = function (root, recurse)
+ if lfsisdir (root) then
+ if recurse == true then
+ return process_dir_tree ({}, { root }, {})
+ else --- kpathsea already delivered the necessary subdirs
+ return process_dir (root)
+ end
+ end
+end
+
+--- truncate_string -- Cut the first part of a string to fit it
+--- into a given terminal width. The parameter “restrict†(int)
+--- indicates the number of characters already consumed on the
+--- line.
+local truncate_string = function (str, restrict)
+ local tw = config.luaotfload.misc.termwidth
+ local wd = tw - restrict
+ local len = utf8len (str)
+ if wd - len < 0 then
+ --- combined length exceeds terminal,
+ str = ".." .. stringsub(str, utf8offset(str, - wd + 2))
+ end
+ return str
+end
+
+
+--[[doc--
+
+ collect_font_filenames_dir -- Traverse the directory root at
+ ``dirname`` looking for font files. Returns a list of {*filename*;
+ *location*} pairs.
+
+--doc]]--
+
+--- string -> string -> string * string list
+local collect_font_filenames_dir = function (dirname, location)
+ if lpegmatch (p_blacklist, dirname) then
+ logreport ("both", 4, "db",
+ "Skipping blacklisted directory %s.", dirname)
+ --- ignore
+ return { }
+ end
+ local found = find_font_files (dirname, location ~= "texmf" and location ~= "local")
+ if not found then
+ logreport ("both", 4, "db",
+ "No such directory: %q; skipping.", dirname)
+ return { }
+ end
+
+ local nfound = #found
+ local files = { }
+
+ logreport ("both", 4, "db",
+ "%d font files detected in %s.",
+ nfound, dirname)
+ for j = 1, nfound do
+ local fullname = found[j]
+ files[#files + 1] = { path_normalize (fullname), location }
+ end
+ return files
+end
+
+--- string list -> string list
+local filter_out_pwd = function (dirs)
+ local result = { }
+ if stripslashes == nil then
+ stripslashes = luaotfload.parsers and luaotfload.parsers.stripslashes
+ end
+ local pwd = path_normalize (lpegmatch (stripslashes,
+ lfscurrentdir ()))
+ for i = 1, #dirs do
+ --- better safe than sorry
+ local dir = path_normalize (lpegmatch (stripslashes, dirs[i]))
+ if dir == "." or dir == pwd then
+ logreport ("both", 3, "db",
+ "Path “%s†matches $PWD (“%sâ€), skipping.",
+ dir, pwd)
+ else
+ result[#result+1] = dir
+ end
+ end
+ return result
+end
+
+local path_separator = os.type == "windows" and ";" or ":"
+
+--[[doc--
+
+ collect_font_filenames_texmf -- Scan texmf tree for font files
+ relying on the kpathsea variables $OPENTYPEFONTS and $TTFONTS of
+ texmf.cnf.
+ The current working directory comes as “.†(texlive) or absolute
+ path (miktex) and will always be filtered out.
+
+ Returns a list of { *filename*; *location* } pairs.
+
+--doc]]--
+
+--- unit -> string * string list
+local collect_font_filenames_texmf = function ()
+
+ local osfontdir = kpseexpand_path "$OSFONTDIR"
+
+ if stringis_empty (osfontdir) then
+ logreport ("both", 1, "db", "Scanning TEXMF for fonts...")
+ else
+ logreport ("both", 1, "db", "Scanning TEXMF and $OSFONTDIR for fonts...")
+ if log.get_loglevel () > 3 then
+ local osdirs = filesplitpath (osfontdir)
+ logreport ("both", 0, "db", "$OSFONTDIR has %d entries:", #osdirs)
+ for i = 1, #osdirs do
+ logreport ("both", 0, "db", "[%d] %s", i, osdirs[i])
+ end
+ end
+ end
+
+ fontdirs = kpseexpand_path "$OPENTYPEFONTS"
+ fontdirs = fontdirs .. path_separator .. kpseexpand_path "$TTFONTS"
+ fontdirs = fontdirs .. path_separator .. kpseexpand_path "$T1FONTS"
+ fontdirs = fontdirs .. path_separator .. kpseexpand_path "$AFMFONTS"
+
+ if stringis_empty (fontdirs) then
+ return { }
+ end
+
+ local tasks = filter_out_pwd (filesplitpath (fontdirs))
+ logreport ("both", 3, "db",
+ "Initiating scan of %d directories.", #tasks)
+
+ local files = { }
+ for _, dir in next, tasks do
+ files = tableappend (files, collect_font_filenames_dir (dir, "texmf"))
+ end
+ logreport ("both", 3, "db", "Collected %d files.", #files)
+ return files
+end
+
+--- unit -> string list
+local function get_os_dirs ()
+ if os.name == 'macosx' then
+ return {
+ filejoin(kpseexpand_path('~'), "Library/Fonts"),
+ "/Library/Fonts",
+ "/System/Library/Fonts",
+ "/Network/Library/Fonts",
+ }
+ elseif os.type == "windows" or os.type == "msdos" then
+ local windir = osgetenv("WINDIR")
+ return { filejoin(windir, 'Fonts') }
+ else
+ local fonts_conves = { --- plural, much?
+ "/usr/local/etc/fonts/fonts.conf",
+ "/etc/fonts/fonts.conf",
+ }
+ if not luaotfload.parsers then
+ logreport ("log", 0, "db", "Fatal: no fonts.conf parser.")
+ end
+ local os_dirs = luaotfload.parsers.read_fonts_conf(fonts_conves, find_files)
+ return os_dirs
+ end
+ return {}
+end
+
+--[[doc--
+
+ count_removed -- Count paths that do not exist in the file system.
+
+--doc]]--
+
+--- string list -> size_t
+local count_removed = function (files)
+ if not files or not files.full then
+ logreport ("log", 4, "db", "Empty file store; no data to work with.")
+ return 0
+ end
+ local old = files.full
+ logreport ("log", 4, "db", "Checking removed files.")
+ local nrem = 0
+ local nold = #old
+ for i = 1, nold do
+ local f = old[i]
+ if not kpsereadable_file (f) then
+ logreport ("log", 2, "db",
+ "File %s does not exist in file system.")
+ nrem = nrem + 1
+ end
+ end
+ return nrem
+end
+
+--[[doc--
+
+ retrieve_namedata -- Scan the list of collected fonts and populate
+ the list of namedata.
+
+ · dirname : name of the directory to scan
+ · currentnames : current font db object
+ · targetnames : font db object to fill
+ · dry_run : don’t touch anything
+
+ Returns the number of fonts that were actually added to the index.
+
+--doc]]--
+
+--- string * string list -> dbobj -> dbobj -> bool? -> int * int
+local retrieve_namedata = function (files, currentnames, targetnames, dry_run)
+
+ local nfiles = #files
+ local nnew = 0
+
+ logreport ("info", 1, "db", "Scanning %d collected font files ...", nfiles)
+
+ local bylocation = { texmf = { 0, 0 }
+ , ["local"] = { 0, 0 }
+ , system = { 0, 0 }
+ }
+ report_status_start (2, 4)
+ for i = 1, nfiles do
+ local fullname, location = unpack (files[i])
+ local count = bylocation[location]
+ count[1] = count[1] + 1
+ if dry_run == true then
+ local truncated = truncate_string (fullname, 43)
+ logreport ("log", 2, "db", "Would have been loading %s.", fullname)
+ report_status ("term", "db", "Would have been loading %s", truncated)
+ --- skip the read_font_names part
+ else
+ local truncated = truncate_string (fullname, 32)
+ logreport ("log", 2, "db", "Loading font %s.", fullname)
+ report_status ("term", "db", "Loading font %s", truncated)
+ local new = read_font_names (fullname, currentnames,
+ targetnames, location)
+ if new == true then
+ nnew = nnew + 1
+ count[2] = count[2] + 1
+ end
+ end
+ end
+ report_status_stop ("term", "db", "Scanned %d files, %d new.", nfiles, nnew)
+ for location, count in next, bylocation do
+ logreport ("term", 4, "db", " * %s: %d files, %d new",
+ location, count[1], count[2])
+ end
+ return nnew
+end
+
+--- unit -> string * string list
+local collect_font_filenames_system = function ()
+
+ local n_scanned, n_new = 0, 0
+ logreport ("info", 1, "db", "Scanning system fonts...")
+ logreport ("info", 2, "db",
+ "Searching in static system directories...")
+
+ local files = { }
+ for _, dir in next, get_os_dirs () do
+ tableappend (files, collect_font_filenames_dir (dir, "system"))
+ end
+ logreport ("term", 3, "db", "Collected %d files.", #files)
+ return files
+end
+
+--- unit -> bool
+flush_lookup_cache = function ()
+ lookup_cache = { }
+ collectgarbage "collect"
+ return true
+end
+
+--[[doc--
+
+ collect_font_filenames_local -- Scan $PWD (during a TeX run)
+ for font files.
+
+ Side effect: This sets the “local†flag in the subtable “meta†to
+ prevent the merged table from being saved to disk.
+
+ TODO the local tree could be cached in $PWD.
+
+--doc]]--
+
+--- unit -> string * string list
+local collect_font_filenames_local = function ()
+ local pwd = lfscurrentdir ()
+ logreport ("both", 1, "db", "Scanning for fonts in $PWD (%q) ...", pwd)
+
+ local files = collect_font_filenames_dir (pwd, "local")
+ local nfiles = #files
+ if nfiles > 0 then
+ targetnames.meta["local"] = true --- prevent saving to disk
+ logreport ("term", 1, "db", "Found %d files.", pwd)
+ else
+ logreport ("term", 1, "db",
+ "Couldn’t find a thing here. What a waste.", pwd)
+ end
+ logreport ("term", 3, "db", "Collected %d files.", #files)
+ return files
+end
+
+--- fontentry list -> filemap
+generate_filedata = function (mappings)
+
+ logreport ("both", 2, "db", "Creating filename map.")
+
+ local nmappings = #mappings
+
+ local files = {
+ bare = {
+ ["local"] = { },
+ system = { }, --- mapped to mapping format -> index in full
+ texmf = { }, --- mapped to mapping format -> “trueâ€
+ },
+ base = {
+ ["local"] = { },
+ system = { }, --- mapped to index in “fullâ€
+ texmf = { }, --- set; all values are “trueâ€
+ },
+ full = { }, --- non-texmf
+ }
+
+ local base = files.base
+ local bare = files.bare
+ local full = files.full
+
+ local conflicts = {
+ basenames = 0,
+ barenames = 0,
+ }
+
+ for index = 1, nmappings do
+ local entry = mappings [index]
+ local filedata = entry.file
+ local format
+ local location
+ local fullpath
+ local basename
+ local barename
+ local subfont
+
+ if filedata then --- new entry
+ format = entry.format --- otf, afm, ...
+ location = filedata.location --- texmf, system, ...
+ fullpath = filedata.full
+ basename = filedata.base
+ barename = filenameonly (fullpath)
+ subfont = filedata.subfont
+ else
+ format = entry.format --- otf, afm, ...
+ location = entry.location --- texmf, system, ...
+ fullpath = entry.fullpath
+ basename = entry.basename
+ barename = filenameonly (fullpath)
+ subfont = entry.subfont
+ end
+
+ entry.index = index
+
+ --- 1) add to basename table
+
+ local inbase = base [location] --- no format since the suffix is known
+
+ -- MK Added lowercase versions for case-insensitive fallback
+ if inbase then
+ local present = inbase [basename]
+ if present then
+ logreport ("both", 4, "db",
+ "Conflicting basename: %q already indexed \z
+ in category %s, ignoring.",
+ barename, location)
+ conflicts.basenames = conflicts.basenames + 1
+
+ --- track conflicts per font
+ local conflictdata = entry.conflicts
+
+ if not conflictdata then
+ entry.conflicts = { basename = present }
+ else -- some conflicts already detected
+ conflictdata.basename = present
+ end
+
+ else
+ local lowerbasename = stringlower (basename)
+ if basename ~= lowerbasename then
+ present = inbase [lowerbasename]
+ if present then
+ logreport ("both", 4, "db",
+ "Conflicting basename: %q already indexed \z
+ as %s.",
+ barename, mappings[present].basename)
+ conflicts.basenames = conflicts.basenames + 1
+
+ --- track conflicts per font
+ local conflictdata = entry.conflicts
+
+ if not conflictdata then
+ entry.conflicts = { basename = present }
+ else -- some conflicts already detected
+ conflictdata.basename = present
+ end
+
+ else
+ inbase [lowerbasename] = index
+ end
+ end
+ inbase [basename] = index
+ end
+ else
+ inbase = { basename = index }
+ base [location] = inbase
+ local lowerbasename = stringlower (basename)
+ if basename ~= lowerbasename then
+ inbase [lowerbasename] = index
+ end
+ end
+
+ --- 2) add to barename table
+
+ local inbare = bare [location] [format]
+
+ if inbare then
+ local present = inbare [barename]
+ if present then
+ logreport ("both", 4, "db",
+ "Conflicting barename: %q already indexed \z
+ in category %s/%s, ignoring.",
+ barename, location, format)
+ conflicts.barenames = conflicts.barenames + 1
+
+ --- track conflicts per font
+ local conflictdata = entry.conflicts
+
+ if not conflictdata then
+ entry.conflicts = { barename = present }
+ else -- some conflicts already detected
+ conflictdata.barename = present
+ end
+ else
+ local lowerbarename = stringlower (barename)
+ if barename ~= lowerbarename then
+ present = inbare [lowerbarename]
+ if present then
+ logreport ("both", 4, "db",
+ "Conflicting barename: %q already indexed \z
+ as %s.",
+ barename, mappings[present].basename)
+ conflicts.barenames = conflicts.barenames + 1
+
+ --- track conflicts per font
+ local conflictdata = entry.conflicts
+
+ if not conflictdata then
+ entry.conflicts = { barename = present }
+ else -- some conflicts already detected
+ conflictdata.barename = present
+ end
+ else
+ inbare [lowerbarename] = index
+ end
+ end
+ inbare [barename] = index
+ end
+ else
+ inbare = { [barename] = index }
+ bare [location] [format] = inbare
+ local lowerbarename = stringlower (barename)
+ if barename ~= lowerbarename then
+ inbare [lowerbarename] = index
+ end
+ end
+ -- /MK
+
+ --- 3) add to fullpath map
+
+ full [index] = fullpath
+ end --- mapping traversal
+
+ return files
+end
+
+local bold_spectrum_low = 501 --- 500 is medium, 900 heavy/black
+local normal_weight = 400
+local bold_weight = 700
+local normal_width = 5
+
+local pick_style
+local pick_fallback_style
+local check_regular
+
+do
+ pick_style = function (typographicsubfamily, subfamily)
+ return style_synonym [typographicsubfamily or subfamily or ""]
+ end
+
+ pick_fallback_style = function (italicangle, pfmweight, width)
+ --[[--
+ More aggressive, but only to determine bold faces.
+ Note: Before you make this test more inclusive, ensure
+ no fonts are matched in the bold synonym spectrum over
+ a literally “bold[italic]†one. In the past, heuristics
+ been tried but ultimately caused unwanted modifiers
+ polluting the lookup table. What doesn’t work is, e. g.
+ treating weights > 500 as bold or allowing synonyms like
+ “heavyâ€, “blackâ€.
+ --]]--
+ if width == normal_width then
+ if pfmweight == bold_weight then
+ --- bold spectrum matches
+ if italicangle == 0 then
+ return "b"
+ end
+ return "bi"
+ elseif pfmweight == normal_weight then
+ if italicangle ~= 0 then
+ return "i"
+ end
+ end
+ return tostring(pfmweight) .. (italicangle == 0 and "" or "i")
+ end
+ return false
+ end
+
+ --- we use only exact matches here since there are constructs
+ --- like “regularitalic†(Cabin, Bodoni Old Fashion)
+
+ check_regular = function (typographicsubfamily,
+ subfamily,
+ italicangle,
+ weight,
+ width,
+ pfmweight)
+ local plausible_weight = false
+ --[[--
+ This filters out undesirable candidates that specify their
+ typographicsubfamily or subfamily as “regular†but are actually of
+ “semibold†or other weight—another drawback of the
+ oversimplifying classification into only three styles (r, i,
+ b, bi).
+ --]]--
+ if italicangle == 0 then
+ if pfmweight == 400 then
+ --[[--
+ Some fonts like Dejavu advertise an undistinguished
+ regular and a “condensed†version with the same
+ weight whilst also providing the style info in the
+ typographic subfamily instead of the subfamily (i. e.
+ the converse of what Adobe’s doing). The only way to
+ weed out the undesired pseudo-regular shape is to
+ peek at its advertised width (4 vs. 5).
+ --]]--
+ if width then
+ plausible_weight = width == normal_width
+ else
+ plausible_weight = true
+ end
+ elseif weight and regular_synonym [weight] then
+ plausible_weight = true
+ end
+ end
+
+ if plausible_weight then
+ if subfamily then
+ if regular_synonym [subfamily] then return "r" end
+ elseif typographicsubfamily then
+ if regular_synonym [typographicsubfamily] then return "r" end
+ end
+ end
+ return false
+ end
+end
+
+local pull_values = function (entry)
+ local file = entry.file
+ local names = entry.names
+ local style = entry.style
+ local sanitized = names.sanitized
+ local english = sanitized.english
+ local info = sanitized.info
+ local metadata = sanitized.metadata
+
+ --- pull file info ...
+ entry.basename = file.base
+ entry.fullpath = file.full
+ entry.location = file.location
+ entry.subfont = file.subfont
+
+ --- pull name info ...
+ entry.psname = english.psname
+ entry.fontname = info.fontname or metadata.fontname
+ entry.fullname = english.fullname or info.fullname
+ entry.typographicsubfamily = english.typographicsubfamily
+ entry.familyname = metadata.familyname or english.typographicfamily or english.family
+ entry.plainname = names.fullname
+ entry.subfamily = english.subfamily
+
+ --- pull style info ...
+ entry.italicangle = style.italicangle
+ entry.size = style.size
+ entry.weight = style.weight
+ entry.width = style.width
+ entry.pfmweight = style.pfmweight
+
+ if config.luaotfload.db.strip == true then
+ entry.file = nil
+ entry.names = nil
+ entry.style = nil
+ end
+end
+
+local add_family = function (name, subtable, modifier, entry)
+ if not name then --- probably borked font
+ return
+ end
+ local familytable = subtable [name]
+ if not familytable then
+ familytable = { }
+ subtable [name] = familytable
+ end
+
+ familytable [#familytable + 1] = {
+ index = entry.index,
+ modifier = modifier,
+ }
+end
+
+local add_lastresort_regular = function (name, subtable, entry)
+ if not name then --- probably borked font
+ return
+ end
+ local familytable = subtable [name]
+ if not familytable then
+ familytable = { }
+ subtable [name] = familytable
+ end
+ familytable.fallback = entry.index
+end
+
+local get_subtable = function (families, entry)
+ local location = entry.location
+ local format = entry.format
+ local subtable = families [location] [format]
+ if not subtable then
+ subtable = { }
+ families [location] [format] = subtable
+ end
+ return subtable
+end
+
+local collect_families = function (mappings)
+
+ logreport ("info", 2, "db", "Analyzing families.")
+
+ local families = {
+ ["local"] = { },
+ system = { },
+ texmf = { },
+ }
+
+ for i = 1, #mappings do
+
+ local entry = mappings [i]
+
+ if entry.file then
+ pull_values (entry)
+ end
+
+ local subtable = get_subtable (families, entry)
+ local familyname = entry.familyname
+ local typographicsubfamily = entry.typographicsubfamily
+ local subfamily = entry.subfamily
+ local weight = entry.weight
+ local width = entry.width
+ local pfmweight = entry.pfmweight
+ local italicangle = entry.italicangle
+ local modifier = pick_style (typographicsubfamily, subfamily)
+
+ if not modifier then --- regular, exact only
+ modifier = check_regular (typographicsubfamily,
+ subfamily,
+ italicangle,
+ weight,
+ width,
+ pfmweight)
+ end
+
+ if not modifier then
+ modifier = pick_fallback_style (italicangle, pfmweight, width)
+ end
+
+ if modifier then
+ add_family (familyname, subtable, modifier, entry)
+ end
+ if modifier ~= 'r' and regular_synonym[typographicsubfamily or subfamily or ''] then
+ add_lastresort_regular (familyname, subtable, entry)
+ end
+ end
+
+ collectgarbage "collect"
+ return families
+end
+
+--[[doc--
+
+ group_modifiers -- For not-quite-bold faces, determine whether
+ they can fill in for a missing bold face slot in a matching family.
+
+ Some families like Lucida do not contain real bold / bold italic
+ members. Instead, they have semibold variants at weight 600 which
+ we must add in a separate pass.
+
+--doc]]--
+
+local style_categories = { "r", "b", "i", "bi" }
+local bold_categories = { "b", "bi" }
+
+group_modifiers = function (mappings, families)
+ logreport ("info", 2, "db", "Analyzing shapes, weights, and styles.")
+ for location, location_data in next, families do
+ for format, format_data in next, location_data do
+ for familyname, collected in next, format_data do
+ local styledata = { } --- will replace the “collected†table
+ local lastresort_regular = collected.fallback
+ collected.fallback = nil
+ --- First, fill in the ordinary style data that
+ --- fits neatly into the four relevant modifier
+ --- categories.
+ for _, modifier in next, style_categories do
+ local entries
+ for key, info in next, collected do
+ if info.modifier == modifier then
+ if not entries then
+ entries = { }
+ end
+ local index = info.index
+ local entry = mappings [index]
+ local size = entry.size
+ if size then
+ entries [#entries + 1] = {
+ size [1],
+ size [2],
+ size [3],
+ index,
+ }
+ else
+ entries.default = index
+ end
+ collected [key] = nil
+ end
+ styledata [modifier] = entries
+ end
+ end
+ if not styledata.r and lastresort_regular then
+ styledata.r = {default = lastresort_regular}
+ end
+
+ --- At this point the family set may still lack
+ --- entries for bold or bold italic. We will fill
+ --- those in using the modifier with the numeric
+ --- weight that is closest to bold (700).
+ if next (collected) then --- there are uncategorized entries
+ for _, modifier in next, bold_categories do
+ if not styledata [modifier] then
+ local closest
+ local minimum = 2^51
+ for key, info in next, collected do
+ local info_modifier = tonumber (info.modifier) and "b" or "bi"
+ if modifier == info_modifier then
+ local index = info.index
+ local entry = mappings [index]
+ local weight = entry.pfmweight
+ local diff = weight < 700 and 700 - weight or weight - 700
+ if weight > 500 and diff < minimum then
+ minimum = diff
+ closest = weight
+ end
+ end
+ end
+ if closest then
+ --- We know there is a substitute face for the modifier.
+ --- Now we scan the list again to extract the size data
+ --- in case the shape is available at multiple sizes.
+ local entries = { }
+ for key, info in next, collected do
+ local info_modifier = tonumber (info.modifier) and "b" or "bi"
+ if modifier == info_modifier then
+ local index = info.index
+ local entry = mappings [index]
+ local size = entry.size
+ if entry.pfmweight == closest then
+ if size then
+ entries [#entries + 1] = {
+ size [1],
+ size [2],
+ size [3],
+ index,
+ }
+ else
+ entries.default = index
+ end
+ end
+ end
+ end
+ styledata [modifier] = entries
+ end
+ end
+ end
+ end
+ format_data [familyname] = styledata
+ end
+ end
+ end
+ return families
+end
+
+local cmp_sizes = function (a, b)
+ return a [1] < b [1]
+end
+
+order_design_sizes = function (families)
+
+ logreport ("info", 2, "db", "Ordering design sizes.")
+
+ for location, data in next, families do
+ for format, data in next, data do
+ for familyname, data in next, data do
+ for style, data in next, data do
+ tablesort (data, cmp_sizes)
+ end
+ end
+ end
+ end
+
+ return families
+end
+
+--[[doc--
+
+ collect_font_filenames -- Scan the three search path categories for
+ font files. This constitutes the first pass of the update mode.
+
+--doc]]--
+
+--- unit -> string * string list
+local collect_font_filenames = function ()
+
+ logreport ("info", 4, "db", "Scanning the filesystem for font files.")
+
+ local filenames = { }
+ local bisect = config.luaotfload.misc.bisect
+ local max_fonts = config.luaotfload.db.max_fonts --- XXX revisit for lua 5.3 wrt integers
+
+ tableappend (filenames, collect_font_filenames_texmf ())
+ tableappend (filenames, collect_font_filenames_system ())
+ if config.luaotfload.db.scan_local == true then
+ tableappend (filenames, collect_font_filenames_local ())
+ end
+ --- Now drop everything above max_fonts.
+ if max_fonts < #filenames then
+ filenames = { unpack (filenames, 1, max_fonts) }
+ end
+ --- And choose the requested slice if in bisect mode.
+ if bisect then
+ return { unpack (filenames, bisect[1], bisect[2]) }
+ end
+ return filenames
+end
+
+--[[doc--
+
+ nth_font_file -- Return the filename of the nth font.
+
+--doc]]--
+
+--- int -> string
+local nth_font_filename = function (n)
+ logreport ("info", 4, "db", "Picking font file no. %d.", n)
+ if not p_blacklist then
+ read_blacklist ()
+ end
+ local filenames = collect_font_filenames ()
+ return filenames[n] and filenames[n][1] or "<error>"
+end
+
+--[[doc--
+
+ font_slice -- Return the fonts in the range from lo to hi.
+
+--doc]]--
+
+local font_slice = function (lo, hi)
+ logreport ("info", 4, "db", "Retrieving font files nos. %d--%d.", lo, hi)
+ if not p_blacklist then
+ read_blacklist ()
+ end
+ local filenames = collect_font_filenames ()
+ local result = { }
+ for i = lo, hi do
+ result[#result + 1] = filenames[i][1]
+ end
+ return result
+end
+
+--[[doc
+
+ count_font_files -- Return the number of files found by
+ collect_font_filenames. This function is exported primarily
+ for use with luaotfload-tool.lua in bisect mode.
+
+--doc]]--
+
+--- unit -> int
+local count_font_files = function ()
+ logreport ("info", 4, "db", "Counting font files.")
+ if not p_blacklist then
+ read_blacklist ()
+ end
+ return #collect_font_filenames ()
+end
+
+--- dbobj -> stats
+
+local collect_statistics = function (mappings)
+ local sum_dsnsize, n_dsnsize = 0, 0
+
+ local fullname, family, families = { }, { }, { }
+ local subfamily, typographicsubfamily = { }, { }
+
+ local addtohash = function (hash, item)
+ if item then
+ local times = hash [item]
+ if times then
+ hash [item] = times + 1
+ else
+ hash [item] = 1
+ end
+ end
+ end
+
+ local appendtohash = function (hash, key, value)
+ if key and value then
+ local entry = hash [key]
+ if entry then
+ entry [#entry + 1] = value
+ else
+ hash [key] = { value }
+ end
+ end
+ end
+
+ local addtoset = function (hash, key, value)
+ if key and value then
+ local set = hash [key]
+ if set then
+ set [value] = true
+ else
+ hash [key] = { [value] = true }
+ end
+ end
+ end
+
+ local setsize = function (set)
+ local n = 0
+ for _, _ in next, set do
+ n = n + 1
+ end
+ return n
+ end
+
+ local hashsum = function (hash)
+ local n = 0
+ for _, m in next, hash do
+ n = n + m
+ end
+ return n
+ end
+
+ for _, entry in next, mappings do
+ local style = entry.style
+ local names = entry.names.sanitized
+ local englishnames = names.english
+
+ addtohash (fullname, englishnames.fullname)
+ addtohash (family, englishnames.family)
+ addtohash (subfamily, englishnames.subfamily)
+ addtohash (typographicsubfamily, englishnames.typographicsubfamily)
+
+ addtoset (families, englishnames.family, englishnames.fullname)
+
+ local sizeinfo = entry.style.size
+ if sizeinfo then
+ sum_dsnsize = sum_dsnsize + sizeinfo [1]
+ n_dsnsize = n_dsnsize + 1
+ end
+ end
+
+ --inspect (families)
+
+ local n_fullname = setsize (fullname)
+ local n_family = setsize (family)
+
+ if log.get_loglevel () > 1 then
+ local pprint_top = function (hash, n, set)
+
+ local freqs = { }
+ local items = { }
+
+ for item, value in next, hash do
+ if set then
+ freq = setsize (value)
+ else
+ freq = value
+ end
+ local ifreq = items [freq]
+ if ifreq then
+ ifreq [#ifreq + 1] = item
+ else
+ items [freq] = { item }
+ freqs [#freqs + 1] = freq
+ end
+ end
+
+ tablesort (freqs)
+
+ local from = #freqs
+ local to = from - (n - 1)
+ if to < 1 then
+ to = 1
+ end
+
+ for i = from, to, -1 do
+ local freq = freqs [i]
+ local itemlist = items [freq]
+
+ if type (itemlist) == "table" then
+ itemlist = tableconcat (itemlist, ", ")
+ end
+
+ logreport ("both", 0, "db",
+ " · %4d × %s.",
+ freq, itemlist)
+ end
+ end
+
+ logreport ("both", 0, "", "~~~~ font index statistics ~~~~")
+ logreport ("both", 0, "db",
+ " · Collected %d fonts (%d names) in %d families.",
+ #mappings, n_fullname, n_family)
+ pprint_top (families, 4, true)
+
+ logreport ("both", 0, "db",
+ " · %d different “subfamily†kinds.",
+ setsize (subfamily))
+ pprint_top (subfamily, 4)
+
+ logreport ("both", 0, "db",
+ " · %d different “typographicsubfamily†kinds.",
+ setsize (typographicsubfamily))
+ pprint_top (typographicsubfamily, 4)
+
+ end
+
+ local mean_dsnsize = 0
+ if n_dsnsize > 0 then
+ mean_dsnsize = sum_dsnsize / n_dsnsize
+ end
+
+ return {
+ mean_dsnsize = mean_dsnsize,
+ names = {
+ fullname = n_fullname,
+ families = n_family,
+ },
+-- style = {
+-- subfamily = subfamily,
+-- typographicsubfamily = typographicsubfamily,
+-- },
+ }
+end
+
+--- force: dictate rebuild from scratch
+--- dry_dun: don’t write to the db, just scan dirs
+
+--- dbobj? -> bool? -> bool? -> dbobj
+update_names = function (currentnames, force, dry_run)
+ local targetnames
+ local n_new = 0
+ local n_rem = 0
+
+ local conf = config.luaotfload
+ if conf.run.live ~= false and conf.db.update_live == false then
+ logreport ("info", 2, "db", "Skipping database update.")
+ --- skip all db updates
+ return currentnames or name_index
+ end
+
+ local starttime = osgettimeofday ()
+
+ --[[
+ The main function, scans everything
+ - “targetnames†is the final table to return
+ - force is whether we rebuild it from scratch or not
+ ]]
+ logreport ("both", 1, "db",
+ "Updating the font names database"
+ .. (force and " forcefully." or "."))
+
+ if config.luaotfload.db.skip_read == true then
+ --- the difference to a “dry run†is that we don’t search
+ --- for font files entirely. we also ignore the “forceâ€
+ --- parameter since it concerns only the font files.
+ logreport ("info", 2, "db",
+ "Ignoring font files, reusing old data.")
+ currentnames = load_names (false)
+ targetnames = currentnames
+ else
+ if force then
+ currentnames = initialize_namedata (get_font_filter ())
+ else
+ if not currentnames or not next (currentnames) then
+ currentnames = load_names (dry_run)
+ end
+ if currentnames.meta.version ~= names.version then
+ logreport ("both", 1, "db",
+ "No font names database or old \z
+ one found; generating new one.")
+ currentnames = initialize_namedata (get_font_filter ())
+ end
+ end
+
+ targetnames = initialize_namedata (get_font_filter (),
+ currentnames.meta and currentnames.meta.created)
+
+ read_blacklist ()
+
+ --- pass 1: Collect the names of all fonts we are going to process.
+ local font_filenames = collect_font_filenames ()
+
+ --- pass 2: read font files (normal case) or reuse information
+ --- present in index
+
+ n_rem = count_removed (currentnames.files)
+
+ n_new = retrieve_namedata (font_filenames,
+ currentnames,
+ targetnames,
+ dry_run)
+
+ logreport ("info", 3, "db",
+ "Found %d font files; %d new, %d stale entries.",
+ #font_filenames, n_new, n_rem)
+ end
+
+ --- pass 3 (optional): collect some stats about the raw font info
+ if config.luaotfload.misc.statistics == true then
+ targetnames.meta.statistics = collect_statistics
+ (targetnames.mappings)
+ end
+
+ --- we always generate the file lookup tables because
+ --- non-texmf entries are redirected there and the mapping
+ --- needs to be 100% consistent
+
+ --- pass 4: build filename table
+ targetnames.files = generate_filedata (targetnames.mappings)
+
+ --- pass 5: build family lookup table
+ targetnames.families = collect_families (targetnames.mappings)
+
+ --- pass 6: arrange style and size info
+ targetnames.families = group_modifiers (targetnames.mappings,
+ targetnames.families)
+
+ --- pass 7: order design size tables
+ targetnames.families = order_design_sizes (targetnames.families)
+
+ logreport ("info", 3, "db",
+ "Rebuilt in %0.f ms.",
+ 1000 * (osgettimeofday () - starttime))
+ name_index = targetnames
+
+ if dry_run ~= true then
+
+ if n_new + n_rem == 0 then
+ logreport ("info", 2, "db",
+ "No new or removed fonts, skip saving to disk.")
+ else
+ local success, reason = save_names ()
+ if not success then
+ logreport ("both", 0, "db",
+ "Failed to save database to disk: %s",
+ reason)
+ end
+ end
+
+ if flush_lookup_cache () and save_lookups () then
+ logreport ("both", 2, "cache", "Lookup cache emptied.")
+ return targetnames
+ end
+ end
+ return targetnames
+end
+
+--- unit -> bool
+save_lookups = function ( )
+ local paths = config.luaotfload.paths
+ local luaname, lucname = paths.lookup_path_lua, paths.lookup_path_luc
+ if fileiswritable (luaname) and fileiswritable (lucname) then
+ tabletofile (luaname, lookup_cache, true)
+ osremove (lucname)
+ caches.compile (lookup_cache, luaname, lucname)
+ --- double check ...
+ if lfsisfile (luaname) and lfsisfile (lucname) then
+ logreport ("both", 3, "cache", "Lookup cache saved.")
+ return true
+ end
+ logreport ("info", 0, "cache", "Could not compile lookup cache.")
+ return false
+ end
+ logreport ("info", 0, "cache", "Lookup cache file not writable.")
+ if not fileiswritable (luaname) then
+ logreport ("info", 0, "cache", "Failed to write %s.", luaname)
+ end
+ if not fileiswritable (lucname) then
+ logreport ("info", 0, "cache", "Failed to write %s.", lucname)
+ end
+ return false
+end
+
+--- save_names() is usually called without the argument
+--- dbobj? -> bool * string option
+save_names = function (currentnames)
+ if not currentnames then
+ currentnames = name_index
+ end
+ if not currentnames or type (currentnames) ~= "table" then
+ return false, "invalid names table"
+ elseif currentnames.meta and currentnames.meta["local"] then
+ return false, "table contains local entries"
+ end
+ local paths = config.luaotfload.paths
+ local luaname, lucname = paths.index_path_lua, paths.index_path_luc
+ if fileiswritable (luaname) and fileiswritable (lucname) then
+ osremove (lucname)
+ local gzname = luaname .. ".gz"
+ if config.luaotfload.db.compress then
+ local serialized = tableserialize (currentnames, true)
+ gzipsave (gzname, serialized)
+ caches.compile (currentnames, "", lucname)
+ else
+ tabletofile (luaname, currentnames, true)
+ caches.compile (currentnames, luaname, lucname)
+ end
+ logreport ("info", 2, "db", "Font index saved at ...")
+ local success = false
+ if lfsisfile (luaname) then
+ logreport ("info", 2, "db", "Text: " .. luaname)
+ success = true
+ end
+ if lfsisfile (gzname) then
+ logreport ("info", 2, "db", "Gzip: " .. gzname)
+ success = true
+ end
+ if lfsisfile (lucname) then
+ logreport ("info", 2, "db", "Byte: " .. lucname)
+ success = true
+ end
+ if success then
+ return true
+ else
+ logreport ("info", 0, "db", "Could not compile font index.")
+ return false
+ end
+ end
+ logreport ("info", 0, "db", "Index file not writable")
+ if not fileiswritable (luaname) then
+ logreport ("info", 0, "db", "Failed to write %s.", luaname)
+ end
+ if not fileiswritable (lucname) then
+ logreport ("info", 0, "db", "Failed to write %s.", lucname)
+ end
+ return false
+end
+
+--[[doc--
+
+ Below set of functions is modeled after mtx-cache.
+
+--doc]]--
+
+--- string -> string -> string list -> string list -> string list -> unit
+local print_cache = function (category, path, luanames, lucnames, rest)
+ local report_indeed = function (...)
+ logreport ("info", 0, "cache", ...)
+ end
+ report_indeed("Luaotfload cache: %s", category)
+ report_indeed("location: %s", path)
+ report_indeed("[raw] %4i", #luanames)
+ report_indeed("[compiled] %4i", #lucnames)
+ report_indeed("[other] %4i", #rest)
+ report_indeed("[total] %4i", #luanames + #lucnames + #rest)
+end
+
+--- string -> string -> string list -> bool -> bool
+local purge_from_cache = function (category, path, list, all)
+ logreport ("info", 1, "cache", "Luaotfload cache: %s %s",
+ (all and "erase" or "purge"), category)
+ logreport ("info", 1, "cache", "location: %s", path)
+ local n = 0
+ for i=1,#list do
+ local filename = list[i]
+ if stringfind(filename,"luatex%-cache") then -- safeguard
+ if all then
+ logreport ("info", 5, "cache", "Removing %s.", filename)
+ osremove(filename)
+ n = n + 1
+ else
+ local suffix = filesuffix(filename)
+ if suffix == "lua" then
+ local checkname = file.replacesuffix(
+ filename, "lua", "luc")
+ if lfsisfile(checkname) then
+ logreport ("info", 5, "cache", "Removing %s.", filename)
+ osremove(filename)
+ n = n + 1
+ end
+ end
+ end
+ end
+ end
+ logreport ("info", 1, "cache", "Removed lua files : %i", n)
+ return true
+end
+
+--- string -> string list -> int -> string list -> string list -> string list ->
+--- (string list * string list * string list * string list)
+local collect_cache collect_cache = function (path, all, n, luanames,
+ lucnames, rest)
+ if not all then
+ local all = find_files (path)
+
+ local luanames, lucnames, rest = { }, { }, { }
+ return collect_cache(nil, all, 1, luanames, lucnames, rest)
+ end
+
+ local filename = all[n]
+ if filename then
+ local suffix = filesuffix(filename)
+ if suffix == "lua" then
+ luanames[#luanames+1] = filename
+ elseif suffix == "luc" then
+ lucnames[#lucnames+1] = filename
+ else
+ rest[#rest+1] = filename
+ end
+ return collect_cache(nil, all, n+1, luanames, lucnames, rest)
+ end
+ return luanames, lucnames, rest, all
+end
+
+local getwritablecachepath = function ( )
+ --- fonts.handlers.otf doesn’t exist outside a Luatex run,
+ --- so we have to improvise
+ local writable = getwritablepath (config.luaotfload.paths.cache_dir, "")
+ if writable then
+ return writable
+ end
+end
+
+local getreadablecachepaths = function ( )
+ local readables = caches.getreadablepaths
+ (config.luaotfload.paths.cache_dir)
+ local result = { }
+ if readables then
+ for i=1, #readables do
+ local readable = readables[i]
+ if lfsisdir (readable) then
+ result[#result+1] = readable
+ end
+ end
+ end
+ return result
+end
+
+--- unit -> unit
+local purge_cache = function ( )
+ local writable_path = getwritablecachepath ()
+ local luanames, lucnames, rest = collect_cache(writable_path)
+ if log.get_loglevel() > 1 then
+ print_cache("writable path", writable_path, luanames, lucnames, rest)
+ end
+ local success = purge_from_cache("writable path", writable_path, luanames, false)
+ return success
+end
+
+--- unit -> unit
+local erase_cache = function ( )
+ local writable_path = getwritablecachepath ()
+ local luanames, lucnames, rest, all = collect_cache(writable_path)
+ if log.get_loglevel() > 1 then
+ print_cache("writable path", writable_path, luanames, lucnames, rest)
+ end
+ local success = purge_from_cache("writable path", writable_path, all, true)
+ return success
+end
+
+local separator = function ( )
+ logreport ("info", 0, string.rep("-", 67))
+end
+
+--- unit -> unit
+local show_cache = function ( )
+ local readable_paths = getreadablecachepaths ()
+ local writable_path = getwritablecachepath ()
+ local luanames, lucnames, rest = collect_cache(writable_path)
+
+ separator ()
+ print_cache ("writable path", writable_path,
+ luanames, lucnames, rest)
+ texio.write_nl""
+ for i=1,#readable_paths do
+ local readable_path = readable_paths[i]
+ if readable_path ~= writable_path then
+ local luanames, lucnames = collect_cache (readable_path)
+ print_cache ("readable path",
+ readable_path, luanames, lucnames, rest)
+ end
+ end
+ separator()
+ return true
+end
+
+-----------------------------------------------------------------------
+--- API assumptions of the fontloader
+-----------------------------------------------------------------------
+--- PHG: we need to investigate these, maybe they’re useful as early
+--- hooks
+
+local ignoredfile = function () return false end
+
+local reportmissingbase = function ()
+ logreport ("info", 0, "db", --> bug‽
+ "Font name database not found but expected by fontloader.")
+ fonts.names.reportmissingbase = nil
+end
+
+local reportmissingname = function ()
+ logreport ("info", 0, "db", --> bug‽
+ "Fontloader attempted to lookup name before Luaotfload \z
+ was initialized.")
+ fonts.names.reportmissingname = nil
+end
+
+local getfilename = function (a1, a2)
+ logreport ("info", 6, "db", --> bug‽
+ "Fontloader looked up font file (%s, %s) before Luaotfload \z
+ was initialized.", tostring(a1), tostring(a2))
+ return lookup_fullpath (a1, a2)
+end
+
+local resolve = function (name, subfont)
+ logreport ("info", 6, "db", --> bug‽
+ "Fontloader attempted to resolve name (%s, %s) before \z
+ Luaotfload was initialized.", tostring(name), tostring(subfont))
+ return lookup_font_name { name = name, sub = subfont }
+end
+
+local api = {
+ ignoredfile = ignoredfile,
+ reportmissingbase = reportmissingbase,
+ reportmissingname = reportmissingname,
+ getfilename = getfilename,
+ resolve = resolve,
+}
+
+-----------------------------------------------------------------------
+--- export functionality to the namespace “fonts.namesâ€
+-----------------------------------------------------------------------
+
+local export = {
+ set_font_filter = set_font_filter,
+ set_size_dimension = set_size_dimension,
+ flush_lookup_cache = flush_lookup_cache,
+ save_lookups = save_lookups,
+ load = load_names,
+ access_font_index = access_font_index,
+ data = function () return name_index end,
+ save = save_names,
+ update = update_names,
+ lookup_font_file = lookup_font_file,
+ lookup_font_name = lookup_font_name,
+ lookup_font_name_cached = lookup_font_name_cached,
+ getfilename = lookup_fullpath,
+ lookup_fullpath = lookup_fullpath,
+ read_blacklist = read_blacklist,
+ sanitize_fontname = sanitize_fontname,
+ getmetadata = getmetadata,
+ set_location_precedence = set_location_precedence,
+ count_font_files = count_font_files,
+ nth_font_filename = nth_font_filename,
+ font_slice = font_slice,
+ --- font cache
+ purge_cache = purge_cache,
+ erase_cache = erase_cache,
+ show_cache = show_cache,
+ find_closest = find_closest,
+}
+
+return function ()
+ --- the font loader namespace is “fontsâ€, same as in Context
+ --- we need to put some fallbacks into place for when running
+ --- as a script
+ if not fonts then return false end
+ logreport = luaotfload.log.report
+ local fonts = fonts
+ fonts.names = fonts.names or names
+ fonts.formats = fonts.formats or { }
+ fonts.definers = fonts.definers or { resolvers = { } }
+
+ names.blacklist = blacklist
+ -- MK Changed to rebuild with case insensitive fallback.
+ -- Negative version to indicate generation by modified code.
+ names.version = -1 --- decrease monotonically
+ -- /MK
+ names.data = nil --- contains the loaded database
+ names.lookups = nil --- contains the lookup cache
+
+ for sym, ref in next, export do names[sym] = ref end
+ for sym, ref in next, api do names[sym] = names[sym] or ref end
+ return true
+end
+
+-- vim:tw=71:sw=4:ts=4:expandtab
diff --git a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
new file mode 100644
index 0000000000..8ef443aedc
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
@@ -0,0 +1,698 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-diagnostics.lua
+-- DESCRIPTION: part of luaotfload-tool / functionality accessible by the --diagnose option
+-- REQUIREMENTS: luaotfload-tool.lua
+-- AUTHOR: Philipp Gesang <phg@phi-gamma.net>
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-diagnostics",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload-tool submodule / diagnostics",
+ license = "GPL v2.0"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+
+local names = fonts.names
+
+local kpse = require "kpse"
+local kpseexpand_path = kpse.expand_path
+local kpseexpand_var = kpse.expand_var
+local kpsefind_file = kpse.find_file
+
+local lfs = require "lfs"
+local lfsattributes = lfs.attributes
+local lfsisfile = lfs.isfile
+local lfsreadlink = lfs.readlink
+
+local md5 = require "md5"
+local md5sumhexa = md5.sumhexa
+
+local ioopen = io.open
+
+local osgetenv = os.getenv
+local osname = os.name
+local osremove = os.remove
+local ostype = os.type
+local stringformat = string.format
+local stringlower = string.lower
+local stringsub = string.sub
+
+local fileisreadable = file.isreadable
+local fileiswritable = file.iswritable
+local filesplitpath = file.splitpath
+local filesuffix = file.suffix
+local ioloaddata = io.loaddata
+local lua_of_json = utilities.json.tolua
+local tableconcat = table.concat
+local tablesortedkeys = table.sortedkeys
+local tabletohash = table.tohash
+
+local lpeg = require "lpeg"
+local C, Cg, Ct = lpeg.C, lpeg.Cg, lpeg.Ct
+local lpegmatch = lpeg.match
+
+local report = luaotfload.log.report
+local out = function (...)
+ report (false, 0, "diagnose", ...)
+end
+
+local parsers = luaotfload.parsers
+local stripslashes = parsers.stripslashes
+local splitcomma = parsers.splitcomma
+
+local check_index = function (errcnt)
+
+ out "================= font names =================="
+ local namedata = names.data()
+
+ if not namedata then
+ namedata = names.load ()
+ end
+
+ local mappings = namedata.mappings
+
+ if not namedata and namedata.formats and namedata.version then
+ out "Database corrupt."
+ return errcnt + 1
+ end
+
+ out ("Database version: %.3f.", namedata.meta.version)
+ out ("Font formats indexed: %s.",
+ tableconcat (namedata.meta.formats, ", "))
+ out ("%d font files indexed.", #mappings)
+
+ local by_format = { }
+ for i = 1, #mappings do
+ local record = mappings[i]
+ local format = stringlower (filesuffix (record.filename))
+ local count = by_format[format]
+ if count then
+ by_format[format] = count + 1
+ else
+ by_format[format] = 1
+ end
+ end
+
+ local formats = tablesortedkeys (by_format)
+ for i = 1, #formats do
+ local format = formats[i]
+ out ("%20s: %5d", format, by_format[format])
+ end
+ return errcnt
+end
+
+local verify_files = function (errcnt)
+ out "================ verify files ================="
+ local status = config.luaotfload.status
+ local hashes = status.hashes
+ local notes = status.notes
+ if not hashes or #hashes == 0 then
+ out ("FAILED: cannot read checksums from %s.", status_file)
+ return 1/0
+ elseif not notes then
+ out ("FAILED: cannot read commit metadata from %s.",
+ status_file)
+ return 1/0
+ end
+
+ out ("Luaotfload revision %s.", notes.revision)
+ out ("Committed by %s.", notes.committer)
+ out ("Timestamp %s.", notes.timestamp)
+
+ local nhashes = #hashes
+ out ("Testing %d files for integrity.", nhashes)
+ for i = 1, nhashes do
+ local fname, canonicalsum = unpack (hashes[i])
+ local location = kpsefind_file (fname)
+ or kpsefind_file (fname, "texmfscripts")
+ if not location then
+ errcnt = errcnt + 1
+ out ("FAILED: file %s missing.", fname)
+ else
+ out ("File: %s.", location)
+ local raw = ioloaddata (location)
+ if not raw then
+ errcnt = errcnt + 1
+ out ("FAILED: file %d not readable.", fname)
+ else
+ local sum = md5sumhexa (raw)
+ if sum ~= canonicalsum then
+ errcnt = errcnt + 1
+ out ("FAILED: checksum mismatch for file %s.",
+ fname)
+ out ("Expected %s.", canonicalsum)
+ out ("Got %s.", sum)
+ else
+ out ("Ok, %s passed.", fname)
+ end
+ end
+ end
+ end
+ return errcnt
+end
+
+local get_tentative_attributes = function (file)
+ if not lfsisfile (file) then
+ local chan = ioopen (file, "w")
+ if chan then
+ chan:close ()
+ local attributes = lfsattributes (file)
+ os.remove (file)
+ return attributes
+ end
+ end
+end
+
+local p_permissions = Ct(Cg(Ct(C(1) * C(1) * C(1)), "u")
+ * Cg(Ct(C(1) * C(1) * C(1)), "g")
+ * Cg(Ct(C(1) * C(1) * C(1)), "o"))
+
+local analyze_permissions = function (raw)
+ return lpegmatch (p_permissions, raw)
+end
+
+local get_permissions = function (t, location)
+ if stringsub (location, #location) == "/" then
+ --- strip trailing slashes (lfs idiosyncrasy on Win)
+ location = lpegmatch (stripslashes, location)
+ end
+ local attributes = lfsattributes (location)
+ if not attributes then
+ print""
+ print("attr", location, attributes)
+ os.exit()
+ end
+
+ if not attributes and t == "f" then
+ attributes = get_tentative_attributes (location)
+ if not attributes then
+ return false
+ end
+ end
+
+ local permissions
+
+ if fileisreadable (location) then
+ --- link handling appears to be unnecessary because
+ --- lfs.attributes() will return the information on
+ --- the link target.
+ if mode == "link" then --follow and repeat
+ location = lfsreadlink (location)
+ attributes = lfsattributes (location)
+ end
+ end
+
+ permissions = analyze_permissions (attributes.permissions)
+
+ return {
+ location = location,
+ mode = attributes.mode,
+ owner = attributes.uid, --- useless on windows
+ permissions = permissions,
+ attributes = attributes,
+ }
+end
+
+local check_conformance = function (spec, permissions, errcnt)
+ local uid = permissions.attributes.uid
+ local gid = permissions.attributes.gid
+ local raw = permissions.attributes.permissions
+
+ out ("Owner: %d, group %d, permissions %s.", uid, gid, raw)
+ if ostype == "unix" then
+ if uid == 0 or gid == 0 then
+ out "Owned by the superuser, permission conflict likely."
+ errcnt = errcnt + 1
+ end
+ end
+
+ local user = permissions.permissions.u
+ if spec.r == true then
+ if user[1] == "r" then
+ out "Readable: ok."
+ else
+ out "Not readable: permissions need fixing."
+ errcnt = errcnt + 1
+ end
+ end
+
+ if spec.w == true then
+ if user[2] == "w"
+ or fileiswritable (permissions.location) then
+ out "Writable: ok."
+ else
+ out "Not writable: permissions need fixing."
+ errcnt = errcnt + 1
+ end
+ end
+
+ return errcnt
+end
+
+local init_desired_permissions = function ()
+ local paths = config.luaotfload.paths
+ return {
+ { "d", {"r","w"}, function () return caches.getwritablepath ("", "") end },
+ { "d", {"r","w"}, paths.prefix },
+ { "f", {"r","w"}, paths.index_path_lua .. ".gz" },
+ { "f", {"r","w"}, paths.index_path_luc },
+ { "f", {"r","w"}, paths.lookup_path_lua },
+ { "f", {"r","w"}, paths.lookup_path_luc },
+ }
+end
+
+local check_permissions = function (errcnt)
+ out [[=============== file permissions ==============]]
+ local desired_permissions = init_desired_permissions ()
+ for i = 1, #desired_permissions do
+ local t, spec, path = unpack (desired_permissions[i])
+ if type (path) == "function" then
+ path = path ()
+ end
+
+ spec = tabletohash (spec)
+
+ out ("Checking permissions of %s.", path)
+
+ local permissions = get_permissions (t, path)
+ if permissions then
+ --inspect (permissions)
+ errcnt = check_conformance (spec, permissions, errcnt)
+ else
+ errcnt = errcnt + 1
+ end
+ end
+ return errcnt
+end
+
+local check_upstream
+
+if kpsefind_file ("https.lua", "lua") == nil then
+ check_upstream = function (errcnt)
+ out [[============= upstream repository =============
+ WARNING: Cannot retrieve repository data.
+ Github API access requires the luasec library.
+ Grab it from <https://github.com/brunoos/luasec>
+ and retry.]]
+ return errcnt
+ end
+else
+--- github api stuff begin
+ local https = require "ssl.https"
+
+ local gh_api_root = [[https://api.github.com]]
+ local release_url = [[https://github.com/lualatex/luaotfload/releases]]
+ local luaotfload_repo = [[lualatex/luaotfload]]
+ local user_agent = [[lualatex/luaotfload integrity check]]
+ local shortbytes = 8
+
+ local gh_shortrevision = function (rev)
+ return stringsub (rev, 1, shortbytes)
+ end
+
+ local gh_encode_parameters = function (parameters)
+ local acc = {}
+ for field, value in next, parameters do
+ --- unsafe, non-urlencoded coz it’s all ascii chars
+ acc[#acc+1] = field .. "=" .. value
+ end
+ return "?" .. tableconcat (acc, "&")
+ end
+
+ local gh_make_url = function (components, parameters)
+ local url = tableconcat ({ gh_api_root,
+ unpack (components) },
+ "/")
+ if parameters then
+ url = url .. gh_encode_parameters (parameters)
+ end
+ return url
+ end
+
+ local alright = [[HTTP/1.1 200 OK]]
+
+ local gh_api_request = function (...)
+ local args = {...}
+ local nargs = #args
+ local final = args[nargs]
+ local request = {
+ url = "",
+ headers = { ["user-agent"] = user_agent },
+ }
+ if type (final) == "table" then
+ args[nargs] = nil
+ request = gh_make_url (args, final)
+ else
+ request = gh_make_url (args)
+ end
+
+ out ("Requesting <%s>.", request)
+ local response, code, headers, status = https.request (request)
+ if status ~= alright then
+ out "Request failed!"
+ return false
+ end
+ return response
+ end
+
+ local gh_api_checklimit = function (headers)
+ local rawlimit = gh_api_request "rate_limit"
+ local limitdata = lua_of_json (rawlimit)
+ if not limitdata and limitdata.rate then
+ out "Cannot parse API rate limit."
+ return false
+ end
+ limitdata = limitdata.rate
+
+ local limit = tonumber (limitdata.limit)
+ local left = tonumber (limitdata.remaining)
+ local reset = tonumber (limitdata.reset)
+
+ out ("%d of %d Github API requests left.", left, limit)
+ if left == 0 then
+ out ("Cannot make any more API requests.")
+ if ostype == "unix" then
+ out ("Try again later at %s.", osdate ("%F %T", reset))
+ else --- windows doesn’t C99
+ out ("Try again later at %s.",
+ osdate ("%Y-%m-d %H:%M:%S", reset))
+ end
+ end
+ return true
+ end
+
+ local gh_tags = function ()
+ out "Fetching tags from repository, please stand by."
+ local rawtags = gh_api_request ("repos",
+ luaotfload_repo,
+ "tags")
+ local taglist = lua_of_json (rawtags)
+ if not taglist or #taglist == 0 then
+ out "Cannot parse response."
+ return false
+ end
+
+ local ntags = #taglist
+ out ("Repository contains %d tags.", ntags)
+ local _idx, latest = next (taglist)
+ out ("The most recent release is %s (revision %s).",
+ latest.name,
+ gh_shortrevision (latest.commit.sha))
+ return latest
+ end
+
+ local gh_compare = function (head, base)
+ if base == nil then
+ base = "HEAD"
+ end
+ out ("Fetching comparison between %s and %s, \z
+ please stand by.",
+ gh_shortrevision (head),
+ gh_shortrevision (base))
+ local comparison = base .. "..." .. head
+ local rawstatus = gh_api_request ("repos",
+ luaotfload_repo,
+ "compare",
+ comparison)
+ local status = lua_of_json (rawstatus)
+ if not status then
+ out "Cannot parse response for status request."
+ return false
+ end
+ return status
+ end
+
+ local gh_news = function (since)
+ local compared = gh_compare (since)
+ if not compared then
+ return false
+ end
+ local behind_by = compared.behind_by
+ local ahead_by = compared.ahead_by
+ local status = compared.status
+ out ("Comparison state: %s.", status)
+ if behind_by > 0 then
+ out ("Your Luaotfload is %d \z
+ revisions behind upstream.",
+ behind_by)
+ return behind_by
+ elseif status == "ahead" then
+ out "Since you are obviously from the future \z
+ I assume you already know the repository state."
+ else
+ out "Everything up to date. \z
+ Luaotfload is in sync with upstream."
+ end
+ return false
+ end
+
+ local gh_catchup = function (current, latest)
+ local compared = gh_compare (latest, current)
+ local ahead_by = tonumber (compared.ahead_by)
+ if ahead_by > 0 then
+ local permalink_url = compared.permalink_url
+ out ("Your Luaotfload is %d revisions \z
+ behind the most recent release.",
+ ahead_by)
+ out ("To view the commit log, visit <%s>.",
+ permalink_url)
+ out ("You can grab an up to date tarball at <%s>.",
+ release_url)
+ return true
+ else
+ out "There weren't any new releases in the meantime."
+ out "Luaotfload is up to date."
+ end
+ return false
+ end
+
+ check_upstream = function (current)
+ out "============= upstream repository ============="
+ local _succ = gh_api_checklimit ()
+ local behind = gh_news (current)
+ if behind then
+ local latest = gh_tags ()
+ local _behind = gh_catchup (current,
+ latest.commit.sha,
+ latest.name)
+ end
+ end
+
+ --- trivium: diff since the first revision as pushed by Élie
+ --- in 2009
+ --- local firstrevision = "c3ccb3ee07e0a67171c24960966ae974e0dd8e98"
+ --- check_upstream (firstrevision)
+end
+--- github api stuff end
+
+local print_envvar = function (var)
+ local val = osgetenv (var)
+ if val then
+ out ("%20s: %q", stringformat ("$%s", var), val)
+ return val
+ else
+ out ("%20s: <unset>", stringformat ("$%s", var))
+ end
+end
+
+local print_path = function (var)
+ local val = osgetenv (var)
+ if val then
+ local paths = filesplitpath (val)
+ if paths then
+ local npaths = #paths
+ if npaths == 1 then
+ out ("%20s: %q", stringformat ("$%s", var), val)
+ elseif npaths > 1 then
+ out ("%20s: <%d items>", stringformat ("$%s", var), npaths)
+ for i = 1, npaths do
+ out (" +: %q", paths[i])
+ end
+ else
+ out ("%20s: <empty>")
+ end
+ end
+ else
+ out ("%20s: <unset>", stringformat ("$%s", var))
+ end
+end
+
+local print_kpsevar = function (var)
+ var = "$" .. var
+ local val = kpseexpand_var (var)
+ if val and val ~= var then
+ out ("%20s: %q", var, val)
+ return val
+ else
+ out ("%20s: <empty or unset>", var)
+ end
+end
+
+local print_kpsepath = function (var)
+ var = "$" .. var
+ local val = kpseexpand_path (var)
+ if val and val ~= "" then
+ local paths = filesplitpath (val)
+ if paths then
+ local npaths = #paths
+ if npaths == 1 then
+ out ("%20s: %q", var, paths[1])
+ elseif npaths > 1 then
+ out ("%20s: <%d items>", var, npaths)
+ for i = 1, npaths do
+ out (" +: %q", paths[i])
+ end
+ else
+ out ("%20s: <empty>")
+ end
+ end
+ else
+ out ("%20s: <empty or unset>", var)
+ end
+end
+
+--- this test first if a variable is set and then expands the
+--- paths; this is necessitated by the fact that expand-path will
+--- return the empty string both if the variable is unset and if
+--- the directory does not exist
+
+local print_kpsepathvar = function (var)
+ local vvar = "$" .. var
+ local val = kpseexpand_var (vvar)
+ if val and val ~= vvar then
+ out ("%20s: %q", vvar, val)
+ print_kpsepath (var)
+ else
+ out ("%20s: <empty or unset>", var)
+ end
+end
+
+local check_environment = function (errcnt)
+ out "============ environment settings ============="
+ out ("system: %s/%s", ostype, osname)
+ if ostype == "unix" and io.popen then
+ local chan = io.popen ("uname -a", "r")
+ if chan then
+ out ("info: %s", chan:read "*all")
+ chan:close ()
+ end
+ end
+
+ out "1) *shell environment*"
+ print_envvar "SHELL"
+ print_path "PATH"
+ print_path "OSFONTDIR"
+ print_envvar "USER"
+ if ostype == "windows" then
+ print_envvar "WINDIR"
+ print_envvar "CD"
+ print_path "TEMP"
+ elseif ostype == "unix" then
+ print_envvar "HOME"
+ print_envvar "PWD"
+ print_path "TMPDIR"
+ end
+
+ out "2) *kpathsea*"
+ print_kpsepathvar "OPENTYPEFONTS"
+ print_kpsepathvar "TTFONTS"
+
+ print_kpsepathvar "TEXMFCACHE"
+ print_kpsepathvar "TEXMFVAR"
+
+ --- the expansion of these can be quite large; as they aren’t
+ --- usually essential to luaotfload, we won’t dump every single
+ --- path
+ print_kpsevar "LUAINPUTS"
+ print_kpsevar "CLUAINPUTS"
+
+ return errcnt
+end
+
+local anamneses = {
+ "environment",
+ "files",
+ "index",
+ "repository",
+ "permissions"
+}
+
+local diagnose = function (job)
+ local errcnt = 0
+ local asked = job.asked_diagnostics
+ if asked == "all" or asked == "thorough" then
+ asked = tabletohash (anamneses, true)
+ else
+ asked = lpegmatch (splitcomma, asked)
+ asked = tabletohash (asked, true)
+ end
+
+ if asked.index == true then
+ errcnt = check_index (errcnt)
+ asked.index = nil
+ end
+
+ if asked.environment == true then
+ errcnt = check_environment (errcnt)
+ asked.environment = nil
+ end
+
+ if asked.files == true then
+ errcnt = verify_files (errcnt)
+ asked.files = nil
+ end
+
+ if asked.permissions == true then
+ errcnt = check_permissions (errcnt)
+ asked.permissions = nil
+ end
+
+ if asked.repository == true then
+ local status = config.luaotfload.status
+ check_upstream (status.notes.revision)
+ asked.repository = nil
+ end
+
+ local rest = next (asked)
+ if rest ~= nil then --> something unknown
+ out ("Unknown diagnostic %q.", rest)
+ end
+ if errcnt == 0 then --> success
+ out ("Everything appears to be in order, \z
+ you may sleep well.")
+ return true, false
+ end
+ out ( [[===============================================
+ WARNING
+ ===============================================
+
+ The diagnostic detected %d errors.
+
+ This version of luaotfload may have been
+ tampered with. Modified versions of the
+ luaotfload source are unsupported. Read the log
+ carefully and get a clean version from CTAN or
+ github:
+
+ × http://www.ctan.org/pkg/luaotfload
+ × https://github.com/lualatex/luaotfload/releases
+
+ If you are uncertain as to how to proceed, then
+ ask on the lualatex mailing list:
+
+ http://www.tug.org/mailman/listinfo/lualatex-dev
+
+ ===============================================
+]], errcnt)
+ return true, false
+end
+
+return diagnose
+
+-- vim:tw=71:sw=4:ts=4:expandtab
diff --git a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
new file mode 100644
index 0000000000..5229c009f7
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
@@ -0,0 +1,42 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-embolden.lua
+-- DESCRIPTION: part of luaotfload / embolden
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-embolden",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / color",
+ license = "GPL v2.0",
+ author = "Marcel Krüger"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+local otffeatures = fonts.constructors.newfeatures "otf"
+
+local function setembolden(tfmdata, factor)
+ tfmdata.embolden = factor
+end
+
+local function enableembolden(tfmdata)
+ tfmdata.mode, tfmdata.width = 2, tfmdata.size*tfmdata.unscaled.embolden/6578.176
+end
+
+otffeatures.register {
+ name = "embolden",
+ description = "embolden",
+ initializers = {
+ base = setembolden,
+ node = setembolden,
+ },
+ manipulators = {
+ base = enableembolden,
+ node = enableembolden,
+ }
+}
+
+--- vim:sw=2:ts=2:expandtab:tw=71
diff --git a/macros/luatex/generic/luaotfload/luaotfload-features.lua b/macros/luatex/generic/luaotfload/luaotfload-features.lua
new file mode 100644
index 0000000000..1d41cfd192
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-features.lua
@@ -0,0 +1,596 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-features.lua
+-- DESCRIPTION: part of luaotfload / font features
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-features",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / features",
+ license = "GPL v2.0",
+ author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+
+local type = type
+local next = next
+local tonumber = tonumber
+
+local lpeg = require "lpeg"
+local lpegmatch = lpeg.match
+local P = lpeg.P
+local R = lpeg.R
+local C = lpeg.C
+
+local table = table
+local tabletohash = table.tohash
+local tablesort = table.sort
+
+--- this appears to be based in part on luatex-fonts-def.lua
+
+local fonts = fonts
+local definers = fonts.definers
+local handlers = fonts.handlers
+local fontidentifiers = fonts.hashes and fonts.hashes.identifiers
+local otf = handlers.otf
+
+local config = config or { luaotfload = { run = { } } }
+
+local as_script = true
+local normalize = function () end
+
+if config.luaotfload.run.live ~= false then
+ normalize = otf.features.normalize
+ as_script = false
+end
+
+--[[HH (font-xtx) --
+ tricky: we sort of bypass the parser and directly feed all into
+ the sub parser
+--HH]]--
+
+function definers.getspecification(str)
+ return "", str, "", ":", str
+end
+
+local log = luaotfload.log
+local report = log.report
+
+local stringgsub = string.gsub
+local stringformat = string.format
+local stringis_empty = string.is_empty
+
+local cmp_by_idx = function (a, b) return a.idx < b.idx end
+
+local defined_combos = 0
+
+local handle_combination = function (combo, spec)
+ defined_combos = defined_combos + 1
+ if not combo [1] then
+ report ("both", 0, "features",
+ "combo %d: Empty font combination requested.",
+ defined_combos)
+ return false
+ end
+
+ if not fontidentifiers then
+ fontidentifiers = fonts.hashes and fonts.hashes.identifiers
+ end
+
+ local chain = { }
+ local fontids = { }
+ local n = #combo
+
+ tablesort (combo, cmp_by_idx)
+
+ --- pass 1: skim combo and resolve fonts
+ report ("both", 2, "features", "combo %d: combining %d fonts.",
+ defined_combos, n)
+ for i = 1, n do
+ local cur = combo [i]
+ local id = cur.id
+ local idx = cur.idx
+ local fnt = fontidentifiers [id]
+ if fnt then
+ local chars = cur.chars
+ if chars == true then
+ report ("both", 2, "features",
+ " *> %.2d: fallback font %d at rank %d.",
+ i, id, idx)
+ else
+ report ("both", 2, "features",
+ " *> %.2d: include font %d at rank %d (%d items).",
+ i, id, idx, (chars and #chars or 0))
+ end
+ chain [#chain + 1] = { fnt, chars, idx = idx }
+ fontids [#fontids + 1] = { id = id }
+ else
+ report ("both", 0, "features",
+ " *> %.2d: font %d at rank %d unknown, skipping.",
+ n, id, idx)
+ --- TODO might instead attempt to define the font at this point
+ --- but that’d require some modifications to the syntax
+ end
+ end
+
+ local nc = #chain
+ if nc == 0 then
+ report ("both", 0, "features",
+ " *> no valid font (of %d) in combination.", n)
+ return false
+ end
+
+ local basefnt = chain [1] [1]
+ if nc == 1 then
+ report ("both", 0, "features",
+ " *> combination boils down to a single font (%s) \z
+ of %d initially specified; not pursuing this any \z
+ further.", basefnt.fullname, n)
+ return basefnt
+ end
+
+ local basechar = basefnt.characters
+ local baseprop = basefnt.properties
+ baseprop.name = spec.name
+ baseprop.virtualized = true
+ basefnt.fonts = fontids
+
+ for i = 2, nc do
+ local cur = chain [i]
+ local fnt = cur [1]
+ local def = cur [2]
+ local src = fnt.characters
+ local cnt = 0
+
+ local pickchr = function (uc, unavailable)
+ local chr = src [uc]
+ if unavailable == true and basechar [uc] then
+ --- fallback mode: already known
+ return
+ end
+ if chr then
+ chr.commands = { { "slot", i, uc } }
+ basechar [uc] = chr
+ cnt = cnt + 1
+ end
+ end
+
+ if def == true then --> fallback; grab all currently unavailable
+ for uc, _chr in next, src do pickchr (uc, true) end
+ else --> grab only defined range
+ for j = 1, #def do
+ local this = def [j]
+ if type (this) == "number" then
+ report ("both", 2, "features",
+ " *> [%d][%d]: import codepoint U+%.4X",
+ i, j, this)
+ pickchr (this)
+ elseif type (this) == "table" then
+ local lo, hi = unpack (this)
+ report ("both", 2, "features",
+ " *> [%d][%d]: import codepoint range U+%.4X--U+%.4X",
+ i, j, lo, hi)
+ for uc = lo, hi do pickchr (uc) end
+ else
+ report ("both", 0, "features",
+ " *> item no. %d of combination definition \z
+ %d not processable.", j, i)
+ end
+ end
+ end
+ report ("both", 2, "features",
+ " *> font %d / %d: imported %d glyphs into combo.",
+ i, nc, cnt)
+ end
+ spec.lookup = "combo"
+ spec.file = basefnt.filename
+ spec.name = stringformat ("luaotfload<%d>", defined_combos)
+ spec.features = { normal = { spec.specification } }
+ spec.forced = "evl"
+ spec.eval = function () return basefnt end
+ return spec
+end
+
+---[[ begin excerpt from font-ott.lua ]]
+
+local swapped = function (h)
+ local r = { }
+ for k, v in next, h do
+ r[stringgsub(v,"[^a-z0-9]","")] = k -- is already lower
+ end
+ return r
+end
+
+local tables = otf.tables
+local scripts = tables.scripts
+local languages = tables.languages
+local verbosescripts = swapped(scripts )
+local verboselanguages = swapped(languages)
+
+---[[ end excerpt from font-ott.lua ]]
+
+--[[doc--
+
+ As discussed, we will issue a warning because of incomplete support
+ when one of the scripts below is requested.
+
+ Reference: https://github.com/lualatex/luaotfload/issues/31
+
+--doc]]--
+
+local support_incomplete = tabletohash({
+ -- "deva",
+ "beng", "guru", "gujr",
+ "orya", "taml", "telu", "knda",
+ "mlym", "sinh",
+}, true)
+
+--[[doc--
+
+ Which features are active by default depends on the script
+ requested.
+
+--doc]]--
+
+--- (string, string) dict -> (string, string) dict
+local apply_default_features = function (speclist)
+ local default_features = luaotfload.features
+
+ speclist = speclist or { }
+ speclist[""] = nil --- invalid options stub
+
+ --- handle language tag
+ local language = speclist.language
+ if language then --- already lowercase at this point
+ language = stringgsub(language, "[^a-z0-9]", "")
+ language = rawget(verboselanguages, language) -- srsly, rawget?
+ or (languages[language] and language)
+ or "dflt"
+ else
+ language = "dflt"
+ end
+ speclist.language = language
+
+ --- handle script tag
+ local script = speclist.script
+ if script then
+ script = stringgsub(script, "[^a-z0-9]","")
+ script = rawget(verbosescripts, script)
+ or (scripts[script] and script)
+ or "dflt"
+ if support_incomplete[script] then
+ report("log", 0, "features",
+ "Support for the requested script: "
+ .. "%q may be incomplete.", script)
+ end
+ else
+ script = "dflt"
+ end
+ speclist.script = script
+
+ report("log", 2, "features",
+ "Auto-selecting default features for script: %s.",
+ script)
+
+ local requested = default_features.defaults[script]
+ if not requested then
+ report("log", 2, "features",
+ "No default features for script %q, falling back to \"dflt\".",
+ script)
+ requested = default_features.defaults.dflt
+ end
+
+ for feat, state in next, requested do
+ if speclist[feat] == nil then speclist[feat] = state end
+ end
+
+ for feat, state in next, default_features.global do
+ --- This is primarily intended for setting node
+ --- mode unless “base†is requested, as stated
+ --- in the manual.
+ if speclist[feat] == nil then speclist[feat] = state end
+ end
+ return speclist
+end
+
+local import_values = {
+ --- That’s what the 1.x parser did, not quite as graciously,
+ --- with an array of branch expressions.
+ -- "style", "optsize",--> from slashed notation; handled otherwise
+ { "lookup", false },
+ { "sub", false },
+}
+
+local supported = {
+ b = "b",
+ i = "i",
+ bi = "bi",
+ aat = false,
+ icu = false,
+ gr = false,
+}
+
+--- (string | (string * string) | bool) list -> (string * number)
+local handle_slashed = function (modifiers)
+ local style, optsize
+ for i=1, #modifiers do
+ local mod = modifiers[i]
+ if type(mod) == "table" and mod[1] == "optsize" then --> optical size
+ optsize = tonumber(mod[2])
+ elseif mod == false then
+ --- ignore
+ report("log", 0, "features", "unsupported font option: %s", v)
+ elseif supported[mod] then
+ style = supported[mod]
+ elseif not stringis_empty(mod) then
+ style = stringgsub(mod, "[^%a%d]", "")
+ end
+ end
+ return style, optsize
+end
+
+local extract_subfont
+do
+ local eof = P(-1)
+ local digit = R"09"
+ --- Theoretically a valid subfont address can be up to ten
+ --- digits long.
+ local sub_expr = P"(" * C(digit^1) * P")" * eof
+ local full_path = C(P(1 - sub_expr)^1)
+ extract_subfont = full_path * sub_expr
+end
+
+--- spec -> spec
+local handle_request = function (specification)
+ local request = lpegmatch(luaotfload.parsers.font_request,
+ specification.specification)
+----inspect(request)
+ if not request then
+ --- happens when called with an absolute path
+ --- in an anonymous lookup;
+ --- we try to behave as friendly as possible
+ --- just go with it ...
+ report("log", 1, "features", "invalid request %q of type anon",
+ specification.specification)
+ report("log", 1, "features",
+ "use square bracket syntax or consult the documentation.")
+ --- The result of \fontname must be re-feedable into \font
+ --- which is expected by the Latex font mechanism. Now this
+ --- is complicated with TTC fonts that need to pass the
+ --- number of the requested subfont along with the file name.
+ --- Thus we test whether the request is a bare path only or
+ --- ends in a subfont expression (decimal digits inside
+ --- parentheses).
+ --- https://github.com/lualatex/luaotfload/issues/57
+ local fullpath, sub = lpegmatch(extract_subfont,
+ specification.specification)
+ if fullpath and sub then
+ specification.sub = tonumber(sub)
+ specification.name = fullpath
+ else
+ specification.name = specification.specification
+ end
+ specification.lookup = "path"
+ return specification
+ end
+
+ local lookup, name = request.lookup, request.name
+ if lookup == "combo" then
+ return handle_combination (name, specification)
+ end
+
+ local features = specification.features
+ if not features then
+ features = { }
+ specification.features = features
+ end
+
+ features.raw = request.features or {}
+ request.features = {}
+ for k, v in pairs(features.raw) do
+ if type(v) == 'string' then
+ v = string.lower(v)
+ v = ({['true'] = true, ['false'] = false})[v] or v
+ end
+ request.features[k] = v
+ end
+ request.features = apply_default_features(request.features)
+
+ if name then
+ specification.name = name
+ specification.lookup = lookup or specification.lookup
+ end
+
+ if request.modifiers then
+ local style, optsize = handle_slashed(request.modifiers)
+ specification.style, specification.optsize = style, optsize
+ end
+
+ for n=1, #import_values do
+ local feat = import_values[n][1]
+ local keep = import_values[n][2]
+ local newvalue = request.features[feat]
+ if newvalue then
+ specification[feat] = request.features[feat]
+ if not keep then
+ request.features[feat] = nil
+ end
+ end
+ end
+
+ --- The next line sets the “rand†feature to “randomâ€; I haven’t
+ --- investigated it any further (luatex-fonts-ext), so it will
+ --- just stay here.
+ features.normal = normalize (request.features)
+ local subfont = tonumber (request.sub)
+ if subfont and subfont >= 0 then
+ specification.sub = subfont + 1
+ else
+ specification.sub = false
+ end
+
+ if request.features and request.features.mode
+ and fonts.readers[request.features.mode] then
+ specification.forced = request.features.mode
+ end
+
+ return specification
+end
+
+fonts.names.handle_request = handle_request
+
+
+if as_script == true then --- skip the remainder of the file
+ report ("log", 5, "features",
+ "Exiting early from luaotfload-features.lua.")
+ return
+end
+
+-- MK: Added
+function fonts.definers.analyze (spec_string, size)
+ return handle_request {
+ size = size,
+ specification = spec_string,
+ }
+end
+-- /MK
+
+-- We assume that the other otf stuff is loaded already; though there’s
+-- another check below during the initialization phase.
+
+
+local tlig_specification = {
+ {
+ type = "substitution",
+ features = everywhere,
+ data = {
+ --- quotedblright:
+ --- " (QUOTATION MARK) → †(RIGHT DOUBLE QUOTATION MARK)
+ [0x0022] = 0x201D,
+
+ --- quoteleft:
+ --- ' (APOSTROPHE) → ’ (RIGHT SINGLE QUOTATION MARK)
+ [0x0027] = 0x2019,
+
+ --- quoteright:
+ --- ` (GRAVE ACCENT) → ‘ (LEFT SINGLE QUOTATION MARK)
+ [0x0060] = 0x2018,
+ },
+ flags = noflags,
+ order = { "tlig" },
+ prepend = true,
+ },
+ {
+ type = "ligature",
+ features = everywhere,
+ data = {
+
+ --- endash:
+ --- [--] (HYPHEN-MINUS, HYPHEN-MINUS) → – (EN DASH)
+ [0x2013] = {0x002D, 0x002D},
+
+ --- emdash:
+ --- [---] (HYPHEN-MINUS, HYPHEN-MINUS, HYPHEN-MINUS) → — (EM DASH)
+ [0x2014] = {0x002D, 0x002D, 0x002D},
+
+ --- quotedblleft:
+ --- [''] (GRAVE ACCENT, GRAVE ACCENT) → “ (LEFT DOUBLE QUOTATION MARK)
+ [0x201C] = {0x0060, 0x0060},
+
+ --- quotedblright:
+ --- [``] (APOSTROPHE, APOSTROPHE) → †(RIGHT DOUBLE QUOTATION MARK)
+ [0x201D] = {0x0027, 0x0027},
+
+ --- exclamdown:
+ --- [!'] (EXCLAMATION MARK, GRAVE ACCENT) → ¡ (INVERTED EXCLAMATION MARK)
+ [0x00A1] = {0x0021, 0x0060},
+
+ --- questiondown:
+ --- [?'] (QUESTION MARK, GRAVE ACCENT) → ¡ (INVERTED EXCLAMATION MARK)
+ [0x00BF] = {0x003F, 0x0060},
+
+ --- next three originate in T1 encoding (Xetex applies them too)
+ --- quotedblbase:
+ --- [,,] (COMMA, COMMA) → ¡ (DOUBLE LOW-9 QUOTATION MARK)
+ [0x201E] = {0x002C, 0x002C},
+
+ --- LEFT-POINTING DOUBLE ANGLE QUOTATION MARK:
+ --- [,,] (LESS-THAN SIGN, LESS-THAN SIGN) → ¡ (LEFT-POINTING ANGLE QUOTATION MARK)
+ [0x00AB] = {0x003C, 0x003C},
+
+ --- RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK:
+ --- [,,] (GREATER-THAN SIGN, GREATER-THAN SIGN) → ¡ (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK)
+ [0x00BB] = {0x003E, 0x003E},
+ },
+ flags = noflags,
+ order = { "tlig" },
+ prepend = true,
+ },
+}
+
+local rot13_specification = {
+ type = "substitution",
+ features = everywhere,
+ data = {
+ [65] = 78, [ 97] = 110, [78] = 65, [110] = 97,
+ [66] = 79, [ 98] = 111, [79] = 66, [111] = 98,
+ [67] = 80, [ 99] = 112, [80] = 67, [112] = 99,
+ [68] = 81, [100] = 113, [81] = 68, [113] = 100,
+ [69] = 82, [101] = 114, [82] = 69, [114] = 101,
+ [70] = 83, [102] = 115, [83] = 70, [115] = 102,
+ [71] = 84, [103] = 116, [84] = 71, [116] = 103,
+ [72] = 85, [104] = 117, [85] = 72, [117] = 104,
+ [73] = 86, [105] = 118, [86] = 73, [118] = 105,
+ [74] = 87, [106] = 119, [87] = 74, [119] = 106,
+ [75] = 88, [107] = 120, [88] = 75, [120] = 107,
+ [76] = 89, [108] = 121, [89] = 76, [121] = 108,
+ [77] = 90, [109] = 122, [90] = 77, [122] = 109,
+ },
+ flags = noflags,
+ order = { "rot13" },
+ prepend = true,
+}
+
+local interrolig_specification = {
+ { type = "ligature", data = { [0x203d] = {0x21, 0x3f}, [0x2e18] = {0xa1, 0xbf}, }, },
+ { type = "ligature", data = { [0x203d] = {0x3f, 0x21}, [0x2e18] = {0xbf, 0xa1}, }, },
+}
+
+local autofeatures = {
+ --- always present with Luaotfload; anum for Arabic and Persian is
+ --- predefined in font-otc.
+ { "tlig" , tlig_specification , "tex ligatures and substitutions" },
+ { "rot13", rot13_specification, "rot13" },
+ { "!!??", interrolig_specification, "interrobang substitutions" },
+}
+
+local add_auto_features = function ()
+ local nfeats = #autofeatures
+ logreport ("both", 5, "features",
+ "auto-installing %d feature definitions", nfeats)
+ for i = 1, nfeats do
+ local name, spec, desc = unpack (autofeatures [i])
+ spec.description = desc
+ otf.addfeature (name, spec)
+ end
+end
+
+return function ()
+ logreport = luaotfload.log.report
+
+ if not fonts and fonts.handlers then
+ logreport ("log", 0, "features",
+ "OTF mechanisms missing -- did you forget to \z
+ load a font loader?")
+ return false
+ end
+ add_auto_features ()
+ return true
+end
+-- vim:tw=79:sw=4:ts=4:expandtab
diff --git a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
new file mode 100644
index 0000000000..612822440f
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
@@ -0,0 +1,430 @@
+-------------------------------------------------------------------------------
+-- FILE: luaotfload-filelist.lua
+-- DESCRIPTION: part of luaotfload / list of files
+-- AUTHOR: Ulrike Fischer, <fischer@troubleshooting-tex.de>
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-filelist",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / filelist",
+ license = "GPL v2.0"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+
+
+--[[doc--
+
+luaotfload has tables with files list in many places: In the import scripts,
+in the init file, in the documentation. This makes maintenance difficult.
+This here is a try to get everything in one place. As the order how files are
+loaded during the merge matters the table is an array. Lists with other
+sorting should be created with functions. Ditto for subtables.
+
+Some redundancy can not be avoided for now if one want to avoid to have to change all sort of functions.
+
+## locations
+files can reside in up to three location (with perhaps different names)
+- context ctxdir
+- git gitdir
+- texmf texdir
+
+files don't need to exist in all locations but the direction of the flow is
+always from context over git to texmf:
+ context-> git -> texmf
+so the "stations" of a file and its source can be deduced by the dirs recorded in the entries
+
+
+## "kind"
+the first four entries are from the original mkimport code and are important for the imports.
+the others are new.
+
+ · *essential*: Files required at runtime.
+ · *merged*: Files merged into the fontloader package.
+ · *ignored*: Lua files not merged, but part of the format.
+ · *tex*: TeX code, i.e. format and examples.
+ · *lualibs*: Files imported, but also provided by the Lualibs package.
+ · *library*: native luaotfload-files of type library
+ · *core*: native core luaotfload files
+ · *generated*: generated luaotfload files
+ · *scripts*: scripts (mk-...)
+ · *docu*: documentation (should perhaps be more refined
+
+## names
+
+The "real" name of a file in a location can be build
+
+- in the context location: ctxpref + name + ext
+- in the git location: (gitpref or "fontloader-") + (ours or name ) + ext
+- in the tex location: (gitpref or "fontloader-") + (texname or ours or name ) + ext
+
+## fields
+ mkstatus: used to ignore some files in mkstatus
+
+
+## files which use the file names
+
+### mkimport
+
+ mkimports needs an
+ --> "import" table with two subtables:
+ --> fontloader, with the files to get from generic, cond: ctxtype = "ctxgene"
+ --> context, with the files to get from context, cond: ctxtype = "ctxbase"
+ entries are subtables with {name=, ours=, kind= }
+
+and a
+ --> "package" table with
+ --> optional (probably unused)
+ --> required = files of type kind_merged
+ entries are the values of name
+
+### mkstatus
+
+this script has been already changed to use luaotfload-filelist.lua
+
+### luaotfload-init.lua
+
+luaotfload-init.lua needs a table
+--> context_modules
+with the (ordered) entries
+
+{false, "name"} -- kind_lualibs
+{ctxdir,"ctxprefix+name"} -- kind_essential or kind_merged
+
+The same list should be used in local init_main = function ()
+but only without the prefix.
+it is unclear how fonts_syn should be handled!!!!
+
+### filegraph.tex
+has been already adapted
+
+### luaotfload-latex.tex/luaotfload-main.tex
+has been already adapted
+
+### build.lua
+???
+
+--doc]]--
+
+
+local kind_essential = 0
+local kind_merged = 1
+local kind_tex = 2
+local kind_ignored = 3
+local kind_lualibs = 4
+local kind_library = 5
+local kind_core = 6
+local kind_generated = 7
+local kind_script = 8
+local kind_docu = 9
+
+local kind_name = {
+ [0] = "essential",
+ [1] = "merged" ,
+ [2] = "tex" ,
+ [3] = "ignored" ,
+ [4] = "lualibs" ,
+ [5] = "library" ,
+ [6] = "core",
+ [7] = "generated",
+ [8] = "script",
+ [9] = "docu"
+}
+
+
+local ctxdirbas = "tex/context/base/mkiv/"
+local ctxdirgen = "tex/generic/context/luatex/"
+
+local gitdirimp = "src/fontloader/misc/" -- imp=imported
+local gitdirsrc = "src/"
+local gitdiress = "src/fontloader/runtime/"
+local gitdirgen = "src/fontloader/auto/"
+local gitdirdoc = "doc/"
+local gitdirscr = "scripts/"
+local gitdirmain = "./"
+
+-- these here a not really pathes
+local texdirtex = "tex"
+local texdirscr = "scripts"
+local texdirdoc = "doc"
+local texdirman = "man"
+
+luaotfload = luaotfload or {}
+luaotfload.filelist = luaotfload.filelist or {}
+
+luaotfload.filelist.data =
+ {
+ -- at first the source files from context
+ { name = "l-lua" , ours = "l-lua" , ext = ".lua", kind = kind_lualibs , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "l-lpeg" , ours = "l-lpeg" , ext = ".lua", kind = kind_lualibs , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "l-function" , ours = "l-function" , ext = ".lua", kind = kind_lualibs , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "l-string" , ours = "l-string" , ext = ".lua", kind = kind_lualibs , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "l-table" , ours = "l-table" , ext = ".lua", kind = kind_lualibs , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "l-io" , ours = "l-io" , ext = ".lua", kind = kind_lualibs , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "l-file" , ours = "l-file" , ext = ".lua", kind = kind_lualibs , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "l-boolean" , ours = "l-boolean" , ext = ".lua", kind = kind_lualibs , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "l-math" , ours = "l-math" , ext = ".lua", kind = kind_lualibs , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "l-unicode" , ours = "l-unicode" , ext = ".lua", kind = kind_lualibs , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+
+ { name = "util-str" , ours = "util-str" , ext = ".lua", kind = kind_lualibs , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "util-fil" , ours = "util-fil" , ext = ".lua", kind = kind_lualibs , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+
+ { name = "basics-gen" , ours = nil , ext = ".lua", kind = kind_essential , gitdir=gitdiress, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+-- files merged in the fontloader. One file is ignored
+ { name = "data-con" , ours = "data-con" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "basics-nod" , ours = nil , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+ { name = "basics-chr" , ours = nil , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+ { name = "font-ini" , ours = "font-ini" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "fonts-mis" , ours = nil , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+ { name = "font-con" , ours = "font-con" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "fonts-enc" , ours = nil , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+ { name = "font-cid" , ours = "font-cid" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-map" , ours = "font-map" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "fonts-syn" , ours = nil , ext = ".lua", kind = kind_ignored , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+ { name = "font-vfc" , ours = "font-vfc" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-otr" , ours = "font-otr" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-oti" , ours = "font-oti" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-ott" , ours = "font-ott" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-cff" , ours = "font-cff" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-ttf" , ours = "font-ttf" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-dsp" , ours = "font-dsp" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-oup" , ours = "font-oup" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-otl" , ours = "font-otl" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-oto" , ours = "font-oto" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-otj" , ours = "font-otj" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-ota" , ours = "font-ota" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-ots" , ours = "font-ots" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-osd" , ours = "font-osd" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-ocl" , ours = "font-ocl" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-otc" , ours = "font-otc" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-onr" , ours = "font-onr" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-one" , ours = "font-one" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-afk" , ours = "font-afk" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "fonts-tfm" , ours = nil , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+ { name = "font-lua" , ours = "font-lua" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-def" , ours = "font-def" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "fonts-def" , ours = nil , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+ { name = "fonts-ext" , ours = nil , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+ { name = "font-imp-tex" , ours = "font-imp-tex" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-imp-ligatures", ours = "font-imp-ligatures", ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-imp-italics" , ours = "font-imp-italics" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "font-imp-effects" , ours = "font-imp-effects" , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirbas, ctxtype = "ctxbase" },
+ { name = "fonts-lig" , ours = nil , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+ { name = "fonts-gbn" , ours = nil , ext = ".lua", kind = kind_merged , gitdir=gitdirimp, texdir = texdirtex , ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+-- end of files merged
+
+ { name = "fonts-merged" , ours = "reference" , ext = ".lua", kind = kind_essential , gitdir=gitdiress, texdir = texdirtex , ctxdir= ctxdirgen ,ctxtype = "ctxgene" , ctxpref = "luatex-" },
+
+
+
+-- this two files are useful as reference for the load order but should not be installed
+ { name = "fonts" , ours = "load-order-reference", ext = ".lua", kind = kind_ignored , gitdir=gitdirimp, ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+ { name = "fonts" , ours = "load-order-reference", ext = ".tex", kind = kind_tex , gitdir=gitdirimp, ctxdir= ctxdirgen, ctxtype = "ctxgene" , ctxpref = "luatex-" },
+
+-- the default fontloader. How to code the name??
+ { name = "YYYY-MM-DD" , ext = ".lua", kind = kind_generated , gitdir = gitdirgen, texdir = texdirtex,mkstatus="auto" },
+
+-- the luaotfload files
+ { name = "luaotfload" ,kind = kind_core, ext =".sty", gitdir=gitdirsrc, texdir=texdirtex, gitpref="",},
+ { name = "main" ,kind = kind_core, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "init" ,kind = kind_core, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "log" ,kind = kind_core, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "diagnostics" ,kind = kind_core, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+
+ { name = "tool" ,kind = kind_core, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "blacklist" ,kind = kind_core, ext =".cnf", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+
+ { name = "filelist" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "auxiliary" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "colors" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "configuration" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "database" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "features" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "letterspace" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "embolden" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "notdef" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "loaders" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "parsers" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "resolvers" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "unicode" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+
+ { name = "characters" ,kind = kind_generated, ext =".lua", gitdir=gitdirgen, texdir=texdirtex, gitpref = "luaotfload-", script="mkcharacter" },
+ { name = "glyphlist" ,kind = kind_generated, ext =".lua", gitdir=gitdirgen, texdir=texdirtex, gitpref = "luaotfload-", script="mkglyphlist" },
+ { name = "status" ,kind = kind_generated, ext =".lua", gitdir=gitdirgen, texdir=texdirtex, gitpref = "luaotfload-", script="mkstatus",mkstatus="ignore" },
+
+
+
+-- scripts
+ { name = "mkimport" ,kind = kind_script, gitdir = gitdirscr, gitpref = "", ext=""},
+ { name = "mkglyphlist" ,kind = kind_script, gitdir = gitdirscr, gitpref = "", ext=""},
+ { name = "mkcharacters" ,kind = kind_script, gitdir = gitdirscr, gitpref = "", ext=""},
+ { name = "mkstatus" ,kind = kind_script, gitdir = gitdirscr, gitpref = "", ext=""},
+ { name = "mktests" ,kind = kind_script, gitdir = gitdirscr, gitpref = "", ext=""},
+
+-- documentation (source dirs need perhaps coding ...) but don't overdo for now
+
+ { name = "latex" , kind= kind_docu, ext = ".tex", gitpref = "luaotfload-", gitdir = gitdirdoc, texdir= texdirdoc, typeset = true },
+ { name = "main" , kind= kind_docu, ext = ".tex", gitpref = "luaotfload-", gitdir = gitdirdoc, texdir= texdirdoc, typeset = false },
+ { name = "conf" , kind= kind_docu, ext = ".tex", gitpref = "luaotfload-", gitdir = gitdirdoc, texdir= texdirdoc, typeset = true , generated = true},
+ { name = "tool" , kind= kind_docu, ext = ".tex", gitpref = "luaotfload-", gitdir = gitdirdoc, texdir= texdirdoc, typeset = true , generated = true},
+ { name = "filegraph" , kind= kind_docu, ext = ".tex", gitpref ="", gitdir = gitdirdoc, texdir= texdirdoc, typeset = true , generated = true},
+ { name = "conf" , kind= kind_docu, ext = ".rst", gitpref = "luaotfload.", gitdir = gitdirdoc, texdir= texdirdoc },
+ { name = "conf" , kind= kind_docu, ext = ".5" , gitpref = "luaotfload.", gitdir = gitdirdoc, texdir= texdirman},
+ { name = "tool" , kind= kind_docu, ext = ".rst", gitpref = "luaotfload-", gitdir = gitdirdoc, texdir= texdirdoc},
+ { name = "tool" , kind= kind_docu, ext = ".1" , gitpref = "luaotfload-", gitdir = gitdirdoc, texdir= texdirman },
+ { name = "README" , kind= kind_docu, texname = "README", gitpref="", ext = ".md" , gitdir = gitdirdoc, texdir= texdirdoc},
+ { name = "COPYING" , kind= kind_docu, ext = "" , gitpref="", gitdir = gitdirmain, texdir= texdirdoc},
+ { name = "NEWS" , kind= kind_docu, ext = "" , gitpref="", gitdir = gitdirmain , texdir= texdirdoc},
+ { name = "README" , kind= kind_docu, gitpref="", ext = ".md" , gitdir = gitdirmain}, -- github readme
+
+}
+
+
+
+-- functions
+-- list of kind:
+--local kind_essential = 0
+--local kind_merged = 1
+--local kind_tex = 2
+--local kind_ignored = 3
+--local kind_lualibs = 4
+--local kind_library = 5
+--local kind_core = 6
+--local kind_generated = 7
+--local kind_script = 8
+--local kind_docu = 9
+
+
+-- some selections
+-- due to the history and setup of the other files, there are not always simple "kind" selections.
+-- ctx base files are splitted in two sets:
+-- 1. font & node
+function luaotfload.filelist.selectctxfontentries ( filetable )
+ local result = {}
+ for i,v in ipairs (filetable) do
+ if v.ctxtype == "ctxbase" and v.kind==1 then
+ table.insert(result,v)
+ end
+ end
+ return result
+end
+
+-- 2. lualibs libraries
+function luaotfload.filelist.selectctxlibsentries ( filetable )
+ local result = {}
+ for i,v in ipairs (filetable) do
+ if v.ctxtype == "ctxbase" and v.kind==4 then
+ table.insert(result,v)
+ end
+ end
+ return result
+end
+
+-- ctx generic files
+-- 1. ignored files are not in the list ...
+function luaotfload.filelist.selectctxgeneusedentries ( filetable )
+ local result = {}
+ for i,v in ipairs (filetable) do
+ if v.ctxtype == "ctxgene" and v.kind==1 then
+ table.insert(result,v)
+ end
+ end
+ return result
+end
+
+-- 2. ignored files are in the list
+function luaotfload.filelist.selectctxgeneentries ( filetable )
+ local result = {}
+ for i,v in ipairs (filetable) do
+ if v.ctxtype == "ctxgene" and (v.kind==1 or v.kind== 3) then
+ table.insert(result,v)
+ end
+ end
+ return result
+end
+
+-- luaotfload-files (lol) are splitted in essential (0), core (6), lib (5) and gene (7) and scr (scripts):
+-- luaoftload libraries
+
+function luaotfload.filelist.selectlolessentries (filetable)
+ local result = {}
+ for i,v in ipairs (filetable) do
+ if v.kind == 0 then
+ table.insert (result,v)
+ end
+ end
+ return result
+end
+
+
+function luaotfload.filelist.selectlollibentries (filetable)
+ local result = {}
+ for i,v in ipairs (filetable) do
+ if v.kind == 5 then
+ table.insert (result,v)
+ end
+ end
+ return result
+end
+
+-- luaoftload core
+
+function luaotfload.filelist.selectlolcoreentries (filetable)
+ local result = {}
+ for i,v in ipairs (filetable) do
+ if v.kind == 6 then
+ table.insert (result,v)
+ end
+ end
+ return result
+end
+
+-- core and lib lua-files
+
+function luaotfload.filelist.selectlolsrcluaentries (filetable)
+ local result = {}
+ for i,v in ipairs (filetable) do
+ if (v.kind == 5 or v.kind==6) and v.ext==".lua" then
+ table.insert (result,v)
+ end
+ end
+ return result
+end
+
+
+
+-- luaoftload generated
+
+function luaotfload.filelist.selectlolgeneentries (filetable)
+ local result = {}
+ for i,v in ipairs (filetable) do
+ if v.kind == 7 then
+ table.insert (result,v)
+ end
+ end
+ return result
+end
+
+
+
+-- scripts
+function luaotfload.filelist.selectlolscrentries ( filetable )
+ local result = {}
+ for i,v in ipairs (filetable) do
+ if v.kind==8 then
+ table.insert(result,v)
+ end
+ end
+ return result
+end
+
+
+
+
+
+
diff --git a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
new file mode 100644
index 0000000000..43c927b3d3
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
@@ -0,0 +1,4313 @@
+local ProvidesLuaModule = {
+ name = "luaotfload-glyphlist",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / autogenerated glyphlist",
+ copyright = "derived from https://raw.githubusercontent.com/adobe-type-tools/agl-aglfn/master/glyphlist.txt",
+ original = "Adobe Glyph List, version 2.0, September 20, 2002",
+ dataonly = true
+}
+
+if context then
+ logs.report("fatal error","this module is not for context")
+ os.exit(-1)
+end
+
+--[[doc--
+Everything below has been autogenerated. Run mkglyphlist to rebuild
+luaotfload-glyphlist.lua.
+--doc]]--
+
+return {
+ ["A"]=65,
+ ["AE"]=198,
+ ["AEacute"]=508,
+ ["AEmacron"]=482,
+ ["AEsmall"]=63462,
+ ["Aacute"]=193,
+ ["Aacutesmall"]=63457,
+ ["Abreve"]=258,
+ ["Abreveacute"]=7854,
+ ["Abrevecyrillic"]=1232,
+ ["Abrevedotbelow"]=7862,
+ ["Abrevegrave"]=7856,
+ ["Abrevehookabove"]=7858,
+ ["Abrevetilde"]=7860,
+ ["Acaron"]=461,
+ ["Acircle"]=9398,
+ ["Acircumflex"]=194,
+ ["Acircumflexacute"]=7844,
+ ["Acircumflexdotbelow"]=7852,
+ ["Acircumflexgrave"]=7846,
+ ["Acircumflexhookabove"]=7848,
+ ["Acircumflexsmall"]=63458,
+ ["Acircumflextilde"]=7850,
+ ["Acute"]=63177,
+ ["Acutesmall"]=63412,
+ ["Acyrillic"]=1040,
+ ["Adblgrave"]=512,
+ ["Adieresis"]=196,
+ ["Adieresiscyrillic"]=1234,
+ ["Adieresismacron"]=478,
+ ["Adieresissmall"]=63460,
+ ["Adotbelow"]=7840,
+ ["Adotmacron"]=480,
+ ["Agrave"]=192,
+ ["Agravesmall"]=63456,
+ ["Ahookabove"]=7842,
+ ["Aiecyrillic"]=1236,
+ ["Ainvertedbreve"]=514,
+ ["Alpha"]=913,
+ ["Alphatonos"]=902,
+ ["Amacron"]=256,
+ ["Amonospace"]=65313,
+ ["Aogonek"]=260,
+ ["Aring"]=197,
+ ["Aringacute"]=506,
+ ["Aringbelow"]=7680,
+ ["Aringsmall"]=63461,
+ ["Asmall"]=63329,
+ ["Atilde"]=195,
+ ["Atildesmall"]=63459,
+ ["Aybarmenian"]=1329,
+ ["B"]=66,
+ ["Bcircle"]=9399,
+ ["Bdotaccent"]=7682,
+ ["Bdotbelow"]=7684,
+ ["Becyrillic"]=1041,
+ ["Benarmenian"]=1330,
+ ["Beta"]=914,
+ ["Bhook"]=385,
+ ["Blinebelow"]=7686,
+ ["Bmonospace"]=65314,
+ ["Brevesmall"]=63220,
+ ["Bsmall"]=63330,
+ ["Btopbar"]=386,
+ ["C"]=67,
+ ["Caarmenian"]=1342,
+ ["Cacute"]=262,
+ ["Caron"]=63178,
+ ["Caronsmall"]=63221,
+ ["Ccaron"]=268,
+ ["Ccedilla"]=199,
+ ["Ccedillaacute"]=7688,
+ ["Ccedillasmall"]=63463,
+ ["Ccircle"]=9400,
+ ["Ccircumflex"]=264,
+ ["Cdot"]=266,
+ ["Cdotaccent"]=266,
+ ["Cedillasmall"]=63416,
+ ["Chaarmenian"]=1353,
+ ["Cheabkhasiancyrillic"]=1212,
+ ["Checyrillic"]=1063,
+ ["Chedescenderabkhasiancyrillic"]=1214,
+ ["Chedescendercyrillic"]=1206,
+ ["Chedieresiscyrillic"]=1268,
+ ["Cheharmenian"]=1347,
+ ["Chekhakassiancyrillic"]=1227,
+ ["Cheverticalstrokecyrillic"]=1208,
+ ["Chi"]=935,
+ ["Chook"]=391,
+ ["Circumflexsmall"]=63222,
+ ["Cmonospace"]=65315,
+ ["Coarmenian"]=1361,
+ ["Csmall"]=63331,
+ ["D"]=68,
+ ["DZ"]=497,
+ ["DZcaron"]=452,
+ ["Daarmenian"]=1332,
+ ["Dafrican"]=393,
+ ["Dcaron"]=270,
+ ["Dcedilla"]=7696,
+ ["Dcircle"]=9401,
+ ["Dcircumflexbelow"]=7698,
+ ["Dcroat"]=272,
+ ["Ddotaccent"]=7690,
+ ["Ddotbelow"]=7692,
+ ["Decyrillic"]=1044,
+ ["Deicoptic"]=1006,
+ ["Delta"]=8710,
+ ["Deltagreek"]=916,
+ ["Dhook"]=394,
+ ["Dieresis"]=63179,
+ ["DieresisAcute"]=63180,
+ ["DieresisGrave"]=63181,
+ ["Dieresissmall"]=63400,
+ ["Digammagreek"]=988,
+ ["Djecyrillic"]=1026,
+ ["Dlinebelow"]=7694,
+ ["Dmonospace"]=65316,
+ ["Dotaccentsmall"]=63223,
+ ["Dslash"]=272,
+ ["Dsmall"]=63332,
+ ["Dtopbar"]=395,
+ ["Dz"]=498,
+ ["Dzcaron"]=453,
+ ["Dzeabkhasiancyrillic"]=1248,
+ ["Dzecyrillic"]=1029,
+ ["Dzhecyrillic"]=1039,
+ ["E"]=69,
+ ["Eacute"]=201,
+ ["Eacutesmall"]=63465,
+ ["Ebreve"]=276,
+ ["Ecaron"]=282,
+ ["Ecedillabreve"]=7708,
+ ["Echarmenian"]=1333,
+ ["Ecircle"]=9402,
+ ["Ecircumflex"]=202,
+ ["Ecircumflexacute"]=7870,
+ ["Ecircumflexbelow"]=7704,
+ ["Ecircumflexdotbelow"]=7878,
+ ["Ecircumflexgrave"]=7872,
+ ["Ecircumflexhookabove"]=7874,
+ ["Ecircumflexsmall"]=63466,
+ ["Ecircumflextilde"]=7876,
+ ["Ecyrillic"]=1028,
+ ["Edblgrave"]=516,
+ ["Edieresis"]=203,
+ ["Edieresissmall"]=63467,
+ ["Edot"]=278,
+ ["Edotaccent"]=278,
+ ["Edotbelow"]=7864,
+ ["Efcyrillic"]=1060,
+ ["Egrave"]=200,
+ ["Egravesmall"]=63464,
+ ["Eharmenian"]=1335,
+ ["Ehookabove"]=7866,
+ ["Eightroman"]=8551,
+ ["Einvertedbreve"]=518,
+ ["Eiotifiedcyrillic"]=1124,
+ ["Elcyrillic"]=1051,
+ ["Elevenroman"]=8554,
+ ["Emacron"]=274,
+ ["Emacronacute"]=7702,
+ ["Emacrongrave"]=7700,
+ ["Emcyrillic"]=1052,
+ ["Emonospace"]=65317,
+ ["Encyrillic"]=1053,
+ ["Endescendercyrillic"]=1186,
+ ["Eng"]=330,
+ ["Enghecyrillic"]=1188,
+ ["Enhookcyrillic"]=1223,
+ ["Eogonek"]=280,
+ ["Eopen"]=400,
+ ["Epsilon"]=917,
+ ["Epsilontonos"]=904,
+ ["Ercyrillic"]=1056,
+ ["Ereversed"]=398,
+ ["Ereversedcyrillic"]=1069,
+ ["Escyrillic"]=1057,
+ ["Esdescendercyrillic"]=1194,
+ ["Esh"]=425,
+ ["Esmall"]=63333,
+ ["Eta"]=919,
+ ["Etarmenian"]=1336,
+ ["Etatonos"]=905,
+ ["Eth"]=208,
+ ["Ethsmall"]=63472,
+ ["Etilde"]=7868,
+ ["Etildebelow"]=7706,
+ ["Euro"]=8364,
+ ["Ezh"]=439,
+ ["Ezhcaron"]=494,
+ ["Ezhreversed"]=440,
+ ["F"]=70,
+ ["Fcircle"]=9403,
+ ["Fdotaccent"]=7710,
+ ["Feharmenian"]=1366,
+ ["Feicoptic"]=996,
+ ["Fhook"]=401,
+ ["Fitacyrillic"]=1138,
+ ["Fiveroman"]=8548,
+ ["Fmonospace"]=65318,
+ ["Fourroman"]=8547,
+ ["Fsmall"]=63334,
+ ["G"]=71,
+ ["GBsquare"]=13191,
+ ["Gacute"]=500,
+ ["Gamma"]=915,
+ ["Gammaafrican"]=404,
+ ["Gangiacoptic"]=1002,
+ ["Gbreve"]=286,
+ ["Gcaron"]=486,
+ ["Gcedilla"]=290,
+ ["Gcircle"]=9404,
+ ["Gcircumflex"]=284,
+ ["Gcommaaccent"]=290,
+ ["Gdot"]=288,
+ ["Gdotaccent"]=288,
+ ["Gecyrillic"]=1043,
+ ["Ghadarmenian"]=1346,
+ ["Ghemiddlehookcyrillic"]=1172,
+ ["Ghestrokecyrillic"]=1170,
+ ["Gheupturncyrillic"]=1168,
+ ["Ghook"]=403,
+ ["Gimarmenian"]=1331,
+ ["Gjecyrillic"]=1027,
+ ["Gmacron"]=7712,
+ ["Gmonospace"]=65319,
+ ["Grave"]=63182,
+ ["Gravesmall"]=63328,
+ ["Gsmall"]=63335,
+ ["Gsmallhook"]=667,
+ ["Gstroke"]=484,
+ ["H"]=72,
+ ["H18533"]=9679,
+ ["H18543"]=9642,
+ ["H18551"]=9643,
+ ["H22073"]=9633,
+ ["HPsquare"]=13259,
+ ["Haabkhasiancyrillic"]=1192,
+ ["Hadescendercyrillic"]=1202,
+ ["Hardsigncyrillic"]=1066,
+ ["Hbar"]=294,
+ ["Hbrevebelow"]=7722,
+ ["Hcedilla"]=7720,
+ ["Hcircle"]=9405,
+ ["Hcircumflex"]=292,
+ ["Hdieresis"]=7718,
+ ["Hdotaccent"]=7714,
+ ["Hdotbelow"]=7716,
+ ["Hmonospace"]=65320,
+ ["Hoarmenian"]=1344,
+ ["Horicoptic"]=1000,
+ ["Hsmall"]=63336,
+ ["Hungarumlaut"]=63183,
+ ["Hungarumlautsmall"]=63224,
+ ["Hzsquare"]=13200,
+ ["I"]=73,
+ ["IAcyrillic"]=1071,
+ ["IJ"]=306,
+ ["IUcyrillic"]=1070,
+ ["Iacute"]=205,
+ ["Iacutesmall"]=63469,
+ ["Ibreve"]=300,
+ ["Icaron"]=463,
+ ["Icircle"]=9406,
+ ["Icircumflex"]=206,
+ ["Icircumflexsmall"]=63470,
+ ["Icyrillic"]=1030,
+ ["Idblgrave"]=520,
+ ["Idieresis"]=207,
+ ["Idieresisacute"]=7726,
+ ["Idieresiscyrillic"]=1252,
+ ["Idieresissmall"]=63471,
+ ["Idot"]=304,
+ ["Idotaccent"]=304,
+ ["Idotbelow"]=7882,
+ ["Iebrevecyrillic"]=1238,
+ ["Iecyrillic"]=1045,
+ ["Ifraktur"]=8465,
+ ["Igrave"]=204,
+ ["Igravesmall"]=63468,
+ ["Ihookabove"]=7880,
+ ["Iicyrillic"]=1048,
+ ["Iinvertedbreve"]=522,
+ ["Iishortcyrillic"]=1049,
+ ["Imacron"]=298,
+ ["Imacroncyrillic"]=1250,
+ ["Imonospace"]=65321,
+ ["Iniarmenian"]=1339,
+ ["Iocyrillic"]=1025,
+ ["Iogonek"]=302,
+ ["Iota"]=921,
+ ["Iotaafrican"]=406,
+ ["Iotadieresis"]=938,
+ ["Iotatonos"]=906,
+ ["Ismall"]=63337,
+ ["Istroke"]=407,
+ ["Itilde"]=296,
+ ["Itildebelow"]=7724,
+ ["Izhitsacyrillic"]=1140,
+ ["Izhitsadblgravecyrillic"]=1142,
+ ["J"]=74,
+ ["Jaarmenian"]=1345,
+ ["Jcircle"]=9407,
+ ["Jcircumflex"]=308,
+ ["Jecyrillic"]=1032,
+ ["Jheharmenian"]=1355,
+ ["Jmonospace"]=65322,
+ ["Jsmall"]=63338,
+ ["K"]=75,
+ ["KBsquare"]=13189,
+ ["KKsquare"]=13261,
+ ["Kabashkircyrillic"]=1184,
+ ["Kacute"]=7728,
+ ["Kacyrillic"]=1050,
+ ["Kadescendercyrillic"]=1178,
+ ["Kahookcyrillic"]=1219,
+ ["Kappa"]=922,
+ ["Kastrokecyrillic"]=1182,
+ ["Kaverticalstrokecyrillic"]=1180,
+ ["Kcaron"]=488,
+ ["Kcedilla"]=310,
+ ["Kcircle"]=9408,
+ ["Kcommaaccent"]=310,
+ ["Kdotbelow"]=7730,
+ ["Keharmenian"]=1364,
+ ["Kenarmenian"]=1343,
+ ["Khacyrillic"]=1061,
+ ["Kheicoptic"]=998,
+ ["Khook"]=408,
+ ["Kjecyrillic"]=1036,
+ ["Klinebelow"]=7732,
+ ["Kmonospace"]=65323,
+ ["Koppacyrillic"]=1152,
+ ["Koppagreek"]=990,
+ ["Ksicyrillic"]=1134,
+ ["Ksmall"]=63339,
+ ["L"]=76,
+ ["LJ"]=455,
+ ["LL"]=63167,
+ ["Lacute"]=313,
+ ["Lambda"]=923,
+ ["Lcaron"]=317,
+ ["Lcedilla"]=315,
+ ["Lcircle"]=9409,
+ ["Lcircumflexbelow"]=7740,
+ ["Lcommaaccent"]=315,
+ ["Ldot"]=319,
+ ["Ldotaccent"]=319,
+ ["Ldotbelow"]=7734,
+ ["Ldotbelowmacron"]=7736,
+ ["Liwnarmenian"]=1340,
+ ["Lj"]=456,
+ ["Ljecyrillic"]=1033,
+ ["Llinebelow"]=7738,
+ ["Lmonospace"]=65324,
+ ["Lslash"]=321,
+ ["Lslashsmall"]=63225,
+ ["Lsmall"]=63340,
+ ["M"]=77,
+ ["MBsquare"]=13190,
+ ["Macron"]=63184,
+ ["Macronsmall"]=63407,
+ ["Macute"]=7742,
+ ["Mcircle"]=9410,
+ ["Mdotaccent"]=7744,
+ ["Mdotbelow"]=7746,
+ ["Menarmenian"]=1348,
+ ["Mmonospace"]=65325,
+ ["Msmall"]=63341,
+ ["Mturned"]=412,
+ ["Mu"]=924,
+ ["N"]=78,
+ ["NJ"]=458,
+ ["Nacute"]=323,
+ ["Ncaron"]=327,
+ ["Ncedilla"]=325,
+ ["Ncircle"]=9411,
+ ["Ncircumflexbelow"]=7754,
+ ["Ncommaaccent"]=325,
+ ["Ndotaccent"]=7748,
+ ["Ndotbelow"]=7750,
+ ["Nhookleft"]=413,
+ ["Nineroman"]=8552,
+ ["Nj"]=459,
+ ["Njecyrillic"]=1034,
+ ["Nlinebelow"]=7752,
+ ["Nmonospace"]=65326,
+ ["Nowarmenian"]=1350,
+ ["Nsmall"]=63342,
+ ["Ntilde"]=209,
+ ["Ntildesmall"]=63473,
+ ["Nu"]=925,
+ ["O"]=79,
+ ["OE"]=338,
+ ["OEsmall"]=63226,
+ ["Oacute"]=211,
+ ["Oacutesmall"]=63475,
+ ["Obarredcyrillic"]=1256,
+ ["Obarreddieresiscyrillic"]=1258,
+ ["Obreve"]=334,
+ ["Ocaron"]=465,
+ ["Ocenteredtilde"]=415,
+ ["Ocircle"]=9412,
+ ["Ocircumflex"]=212,
+ ["Ocircumflexacute"]=7888,
+ ["Ocircumflexdotbelow"]=7896,
+ ["Ocircumflexgrave"]=7890,
+ ["Ocircumflexhookabove"]=7892,
+ ["Ocircumflexsmall"]=63476,
+ ["Ocircumflextilde"]=7894,
+ ["Ocyrillic"]=1054,
+ ["Odblacute"]=336,
+ ["Odblgrave"]=524,
+ ["Odieresis"]=214,
+ ["Odieresiscyrillic"]=1254,
+ ["Odieresissmall"]=63478,
+ ["Odotbelow"]=7884,
+ ["Ogoneksmall"]=63227,
+ ["Ograve"]=210,
+ ["Ogravesmall"]=63474,
+ ["Oharmenian"]=1365,
+ ["Ohm"]=8486,
+ ["Ohookabove"]=7886,
+ ["Ohorn"]=416,
+ ["Ohornacute"]=7898,
+ ["Ohorndotbelow"]=7906,
+ ["Ohorngrave"]=7900,
+ ["Ohornhookabove"]=7902,
+ ["Ohorntilde"]=7904,
+ ["Ohungarumlaut"]=336,
+ ["Oi"]=418,
+ ["Oinvertedbreve"]=526,
+ ["Omacron"]=332,
+ ["Omacronacute"]=7762,
+ ["Omacrongrave"]=7760,
+ ["Omega"]=8486,
+ ["Omegacyrillic"]=1120,
+ ["Omegagreek"]=937,
+ ["Omegaroundcyrillic"]=1146,
+ ["Omegatitlocyrillic"]=1148,
+ ["Omegatonos"]=911,
+ ["Omicron"]=927,
+ ["Omicrontonos"]=908,
+ ["Omonospace"]=65327,
+ ["Oneroman"]=8544,
+ ["Oogonek"]=490,
+ ["Oogonekmacron"]=492,
+ ["Oopen"]=390,
+ ["Oslash"]=216,
+ ["Oslashacute"]=510,
+ ["Oslashsmall"]=63480,
+ ["Osmall"]=63343,
+ ["Ostrokeacute"]=510,
+ ["Otcyrillic"]=1150,
+ ["Otilde"]=213,
+ ["Otildeacute"]=7756,
+ ["Otildedieresis"]=7758,
+ ["Otildesmall"]=63477,
+ ["P"]=80,
+ ["Pacute"]=7764,
+ ["Pcircle"]=9413,
+ ["Pdotaccent"]=7766,
+ ["Pecyrillic"]=1055,
+ ["Peharmenian"]=1354,
+ ["Pemiddlehookcyrillic"]=1190,
+ ["Phi"]=934,
+ ["Phook"]=420,
+ ["Pi"]=928,
+ ["Piwrarmenian"]=1363,
+ ["Pmonospace"]=65328,
+ ["Psi"]=936,
+ ["Psicyrillic"]=1136,
+ ["Psmall"]=63344,
+ ["Q"]=81,
+ ["Qcircle"]=9414,
+ ["Qmonospace"]=65329,
+ ["Qsmall"]=63345,
+ ["R"]=82,
+ ["Raarmenian"]=1356,
+ ["Racute"]=340,
+ ["Rcaron"]=344,
+ ["Rcedilla"]=342,
+ ["Rcircle"]=9415,
+ ["Rcommaaccent"]=342,
+ ["Rdblgrave"]=528,
+ ["Rdotaccent"]=7768,
+ ["Rdotbelow"]=7770,
+ ["Rdotbelowmacron"]=7772,
+ ["Reharmenian"]=1360,
+ ["Rfraktur"]=8476,
+ ["Rho"]=929,
+ ["Ringsmall"]=63228,
+ ["Rinvertedbreve"]=530,
+ ["Rlinebelow"]=7774,
+ ["Rmonospace"]=65330,
+ ["Rsmall"]=63346,
+ ["Rsmallinverted"]=641,
+ ["Rsmallinvertedsuperior"]=694,
+ ["S"]=83,
+ ["SF010000"]=9484,
+ ["SF020000"]=9492,
+ ["SF030000"]=9488,
+ ["SF040000"]=9496,
+ ["SF050000"]=9532,
+ ["SF060000"]=9516,
+ ["SF070000"]=9524,
+ ["SF080000"]=9500,
+ ["SF090000"]=9508,
+ ["SF10000"]=9484,
+ ["SF100000"]=9472,
+ ["SF110000"]=9474,
+ ["SF190000"]=9569,
+ ["SF20000"]=9492,
+ ["SF200000"]=9570,
+ ["SF210000"]=9558,
+ ["SF220000"]=9557,
+ ["SF230000"]=9571,
+ ["SF240000"]=9553,
+ ["SF250000"]=9559,
+ ["SF260000"]=9565,
+ ["SF270000"]=9564,
+ ["SF280000"]=9563,
+ ["SF30000"]=9488,
+ ["SF360000"]=9566,
+ ["SF370000"]=9567,
+ ["SF380000"]=9562,
+ ["SF390000"]=9556,
+ ["SF40000"]=9496,
+ ["SF400000"]=9577,
+ ["SF410000"]=9574,
+ ["SF420000"]=9568,
+ ["SF430000"]=9552,
+ ["SF440000"]=9580,
+ ["SF450000"]=9575,
+ ["SF460000"]=9576,
+ ["SF470000"]=9572,
+ ["SF480000"]=9573,
+ ["SF490000"]=9561,
+ ["SF50000"]=9532,
+ ["SF500000"]=9560,
+ ["SF510000"]=9554,
+ ["SF520000"]=9555,
+ ["SF530000"]=9579,
+ ["SF540000"]=9578,
+ ["SF60000"]=9516,
+ ["SF70000"]=9524,
+ ["SF80000"]=9500,
+ ["SF90000"]=9508,
+ ["Sacute"]=346,
+ ["Sacutedotaccent"]=7780,
+ ["Sampigreek"]=992,
+ ["Scaron"]=352,
+ ["Scarondotaccent"]=7782,
+ ["Scaronsmall"]=63229,
+ ["Scedilla"]=350,
+ ["Schwa"]=399,
+ ["Schwacyrillic"]=1240,
+ ["Schwadieresiscyrillic"]=1242,
+ ["Scircle"]=9416,
+ ["Scircumflex"]=348,
+ ["Scommaaccent"]=536,
+ ["Sdotaccent"]=7776,
+ ["Sdotbelow"]=7778,
+ ["Sdotbelowdotaccent"]=7784,
+ ["Seharmenian"]=1357,
+ ["Sevenroman"]=8550,
+ ["Shaarmenian"]=1351,
+ ["Shacyrillic"]=1064,
+ ["Shchacyrillic"]=1065,
+ ["Sheicoptic"]=994,
+ ["Shhacyrillic"]=1210,
+ ["Shimacoptic"]=1004,
+ ["Sigma"]=931,
+ ["Sixroman"]=8549,
+ ["Smonospace"]=65331,
+ ["Softsigncyrillic"]=1068,
+ ["Ssmall"]=63347,
+ ["Stigmagreek"]=986,
+ ["T"]=84,
+ ["Tau"]=932,
+ ["Tbar"]=358,
+ ["Tcaron"]=356,
+ ["Tcedilla"]=354,
+ ["Tcircle"]=9417,
+ ["Tcircumflexbelow"]=7792,
+ ["Tcommaaccent"]=354,
+ ["Tdotaccent"]=7786,
+ ["Tdotbelow"]=7788,
+ ["Tecyrillic"]=1058,
+ ["Tedescendercyrillic"]=1196,
+ ["Tenroman"]=8553,
+ ["Tetsecyrillic"]=1204,
+ ["Theta"]=920,
+ ["Thook"]=428,
+ ["Thorn"]=222,
+ ["Thornsmall"]=63486,
+ ["Threeroman"]=8546,
+ ["Tildesmall"]=63230,
+ ["Tiwnarmenian"]=1359,
+ ["Tlinebelow"]=7790,
+ ["Tmonospace"]=65332,
+ ["Toarmenian"]=1337,
+ ["Tonefive"]=444,
+ ["Tonesix"]=388,
+ ["Tonetwo"]=423,
+ ["Tretroflexhook"]=430,
+ ["Tsecyrillic"]=1062,
+ ["Tshecyrillic"]=1035,
+ ["Tsmall"]=63348,
+ ["Twelveroman"]=8555,
+ ["Tworoman"]=8545,
+ ["U"]=85,
+ ["Uacute"]=218,
+ ["Uacutesmall"]=63482,
+ ["Ubreve"]=364,
+ ["Ucaron"]=467,
+ ["Ucircle"]=9418,
+ ["Ucircumflex"]=219,
+ ["Ucircumflexbelow"]=7798,
+ ["Ucircumflexsmall"]=63483,
+ ["Ucyrillic"]=1059,
+ ["Udblacute"]=368,
+ ["Udblgrave"]=532,
+ ["Udieresis"]=220,
+ ["Udieresisacute"]=471,
+ ["Udieresisbelow"]=7794,
+ ["Udieresiscaron"]=473,
+ ["Udieresiscyrillic"]=1264,
+ ["Udieresisgrave"]=475,
+ ["Udieresismacron"]=469,
+ ["Udieresissmall"]=63484,
+ ["Udotbelow"]=7908,
+ ["Ugrave"]=217,
+ ["Ugravesmall"]=63481,
+ ["Uhookabove"]=7910,
+ ["Uhorn"]=431,
+ ["Uhornacute"]=7912,
+ ["Uhorndotbelow"]=7920,
+ ["Uhorngrave"]=7914,
+ ["Uhornhookabove"]=7916,
+ ["Uhorntilde"]=7918,
+ ["Uhungarumlaut"]=368,
+ ["Uhungarumlautcyrillic"]=1266,
+ ["Uinvertedbreve"]=534,
+ ["Ukcyrillic"]=1144,
+ ["Umacron"]=362,
+ ["Umacroncyrillic"]=1262,
+ ["Umacrondieresis"]=7802,
+ ["Umonospace"]=65333,
+ ["Uogonek"]=370,
+ ["Upsilon"]=933,
+ ["Upsilon1"]=978,
+ ["Upsilonacutehooksymbolgreek"]=979,
+ ["Upsilonafrican"]=433,
+ ["Upsilondieresis"]=939,
+ ["Upsilondieresishooksymbolgreek"]=980,
+ ["Upsilonhooksymbol"]=978,
+ ["Upsilontonos"]=910,
+ ["Uring"]=366,
+ ["Ushortcyrillic"]=1038,
+ ["Usmall"]=63349,
+ ["Ustraightcyrillic"]=1198,
+ ["Ustraightstrokecyrillic"]=1200,
+ ["Utilde"]=360,
+ ["Utildeacute"]=7800,
+ ["Utildebelow"]=7796,
+ ["V"]=86,
+ ["Vcircle"]=9419,
+ ["Vdotbelow"]=7806,
+ ["Vecyrillic"]=1042,
+ ["Vewarmenian"]=1358,
+ ["Vhook"]=434,
+ ["Vmonospace"]=65334,
+ ["Voarmenian"]=1352,
+ ["Vsmall"]=63350,
+ ["Vtilde"]=7804,
+ ["W"]=87,
+ ["Wacute"]=7810,
+ ["Wcircle"]=9420,
+ ["Wcircumflex"]=372,
+ ["Wdieresis"]=7812,
+ ["Wdotaccent"]=7814,
+ ["Wdotbelow"]=7816,
+ ["Wgrave"]=7808,
+ ["Wmonospace"]=65335,
+ ["Wsmall"]=63351,
+ ["X"]=88,
+ ["Xcircle"]=9421,
+ ["Xdieresis"]=7820,
+ ["Xdotaccent"]=7818,
+ ["Xeharmenian"]=1341,
+ ["Xi"]=926,
+ ["Xmonospace"]=65336,
+ ["Xsmall"]=63352,
+ ["Y"]=89,
+ ["Yacute"]=221,
+ ["Yacutesmall"]=63485,
+ ["Yatcyrillic"]=1122,
+ ["Ycircle"]=9422,
+ ["Ycircumflex"]=374,
+ ["Ydieresis"]=376,
+ ["Ydieresissmall"]=63487,
+ ["Ydotaccent"]=7822,
+ ["Ydotbelow"]=7924,
+ ["Yericyrillic"]=1067,
+ ["Yerudieresiscyrillic"]=1272,
+ ["Ygrave"]=7922,
+ ["Yhook"]=435,
+ ["Yhookabove"]=7926,
+ ["Yiarmenian"]=1349,
+ ["Yicyrillic"]=1031,
+ ["Yiwnarmenian"]=1362,
+ ["Ymonospace"]=65337,
+ ["Ysmall"]=63353,
+ ["Ytilde"]=7928,
+ ["Yusbigcyrillic"]=1130,
+ ["Yusbigiotifiedcyrillic"]=1132,
+ ["Yuslittlecyrillic"]=1126,
+ ["Yuslittleiotifiedcyrillic"]=1128,
+ ["Z"]=90,
+ ["Zaarmenian"]=1334,
+ ["Zacute"]=377,
+ ["Zcaron"]=381,
+ ["Zcaronsmall"]=63231,
+ ["Zcircle"]=9423,
+ ["Zcircumflex"]=7824,
+ ["Zdot"]=379,
+ ["Zdotaccent"]=379,
+ ["Zdotbelow"]=7826,
+ ["Zecyrillic"]=1047,
+ ["Zedescendercyrillic"]=1176,
+ ["Zedieresiscyrillic"]=1246,
+ ["Zeta"]=918,
+ ["Zhearmenian"]=1338,
+ ["Zhebrevecyrillic"]=1217,
+ ["Zhecyrillic"]=1046,
+ ["Zhedescendercyrillic"]=1174,
+ ["Zhedieresiscyrillic"]=1244,
+ ["Zlinebelow"]=7828,
+ ["Zmonospace"]=65338,
+ ["Zsmall"]=63354,
+ ["Zstroke"]=437,
+ ["a"]=97,
+ ["aabengali"]=2438,
+ ["aacute"]=225,
+ ["aadeva"]=2310,
+ ["aagujarati"]=2694,
+ ["aagurmukhi"]=2566,
+ ["aamatragurmukhi"]=2622,
+ ["aarusquare"]=13059,
+ ["aavowelsignbengali"]=2494,
+ ["aavowelsigndeva"]=2366,
+ ["aavowelsigngujarati"]=2750,
+ ["abbreviationmarkarmenian"]=1375,
+ ["abbreviationsigndeva"]=2416,
+ ["abengali"]=2437,
+ ["abopomofo"]=12570,
+ ["abreve"]=259,
+ ["abreveacute"]=7855,
+ ["abrevecyrillic"]=1233,
+ ["abrevedotbelow"]=7863,
+ ["abrevegrave"]=7857,
+ ["abrevehookabove"]=7859,
+ ["abrevetilde"]=7861,
+ ["acaron"]=462,
+ ["acircle"]=9424,
+ ["acircumflex"]=226,
+ ["acircumflexacute"]=7845,
+ ["acircumflexdotbelow"]=7853,
+ ["acircumflexgrave"]=7847,
+ ["acircumflexhookabove"]=7849,
+ ["acircumflextilde"]=7851,
+ ["acute"]=180,
+ ["acutebelowcmb"]=791,
+ ["acutecmb"]=769,
+ ["acutecomb"]=769,
+ ["acutedeva"]=2388,
+ ["acutelowmod"]=719,
+ ["acutetonecmb"]=833,
+ ["acyrillic"]=1072,
+ ["adblgrave"]=513,
+ ["addakgurmukhi"]=2673,
+ ["adeva"]=2309,
+ ["adieresis"]=228,
+ ["adieresiscyrillic"]=1235,
+ ["adieresismacron"]=479,
+ ["adotbelow"]=7841,
+ ["adotmacron"]=481,
+ ["ae"]=230,
+ ["aeacute"]=509,
+ ["aekorean"]=12624,
+ ["aemacron"]=483,
+ ["afii00208"]=8213,
+ ["afii08941"]=8356,
+ ["afii10017"]=1040,
+ ["afii10018"]=1041,
+ ["afii10019"]=1042,
+ ["afii10020"]=1043,
+ ["afii10021"]=1044,
+ ["afii10022"]=1045,
+ ["afii10023"]=1025,
+ ["afii10024"]=1046,
+ ["afii10025"]=1047,
+ ["afii10026"]=1048,
+ ["afii10027"]=1049,
+ ["afii10028"]=1050,
+ ["afii10029"]=1051,
+ ["afii10030"]=1052,
+ ["afii10031"]=1053,
+ ["afii10032"]=1054,
+ ["afii10033"]=1055,
+ ["afii10034"]=1056,
+ ["afii10035"]=1057,
+ ["afii10036"]=1058,
+ ["afii10037"]=1059,
+ ["afii10038"]=1060,
+ ["afii10039"]=1061,
+ ["afii10040"]=1062,
+ ["afii10041"]=1063,
+ ["afii10042"]=1064,
+ ["afii10043"]=1065,
+ ["afii10044"]=1066,
+ ["afii10045"]=1067,
+ ["afii10046"]=1068,
+ ["afii10047"]=1069,
+ ["afii10048"]=1070,
+ ["afii10049"]=1071,
+ ["afii10050"]=1168,
+ ["afii10051"]=1026,
+ ["afii10052"]=1027,
+ ["afii10053"]=1028,
+ ["afii10054"]=1029,
+ ["afii10055"]=1030,
+ ["afii10056"]=1031,
+ ["afii10057"]=1032,
+ ["afii10058"]=1033,
+ ["afii10059"]=1034,
+ ["afii10060"]=1035,
+ ["afii10061"]=1036,
+ ["afii10062"]=1038,
+ ["afii10063"]=63172,
+ ["afii10064"]=63173,
+ ["afii10065"]=1072,
+ ["afii10066"]=1073,
+ ["afii10067"]=1074,
+ ["afii10068"]=1075,
+ ["afii10069"]=1076,
+ ["afii10070"]=1077,
+ ["afii10071"]=1105,
+ ["afii10072"]=1078,
+ ["afii10073"]=1079,
+ ["afii10074"]=1080,
+ ["afii10075"]=1081,
+ ["afii10076"]=1082,
+ ["afii10077"]=1083,
+ ["afii10078"]=1084,
+ ["afii10079"]=1085,
+ ["afii10080"]=1086,
+ ["afii10081"]=1087,
+ ["afii10082"]=1088,
+ ["afii10083"]=1089,
+ ["afii10084"]=1090,
+ ["afii10085"]=1091,
+ ["afii10086"]=1092,
+ ["afii10087"]=1093,
+ ["afii10088"]=1094,
+ ["afii10089"]=1095,
+ ["afii10090"]=1096,
+ ["afii10091"]=1097,
+ ["afii10092"]=1098,
+ ["afii10093"]=1099,
+ ["afii10094"]=1100,
+ ["afii10095"]=1101,
+ ["afii10096"]=1102,
+ ["afii10097"]=1103,
+ ["afii10098"]=1169,
+ ["afii10099"]=1106,
+ ["afii10100"]=1107,
+ ["afii10101"]=1108,
+ ["afii10102"]=1109,
+ ["afii10103"]=1110,
+ ["afii10104"]=1111,
+ ["afii10105"]=1112,
+ ["afii10106"]=1113,
+ ["afii10107"]=1114,
+ ["afii10108"]=1115,
+ ["afii10109"]=1116,
+ ["afii10110"]=1118,
+ ["afii10145"]=1039,
+ ["afii10146"]=1122,
+ ["afii10147"]=1138,
+ ["afii10148"]=1140,
+ ["afii10192"]=63174,
+ ["afii10193"]=1119,
+ ["afii10194"]=1123,
+ ["afii10195"]=1139,
+ ["afii10196"]=1141,
+ ["afii10831"]=63175,
+ ["afii10832"]=63176,
+ ["afii10846"]=1241,
+ ["afii208"]=8213,
+ ["afii299"]=8206,
+ ["afii300"]=8207,
+ ["afii301"]=8205,
+ ["afii57381"]=1642,
+ ["afii57388"]=1548,
+ ["afii57392"]=1632,
+ ["afii57393"]=1633,
+ ["afii57394"]=1634,
+ ["afii57395"]=1635,
+ ["afii57396"]=1636,
+ ["afii57397"]=1637,
+ ["afii57398"]=1638,
+ ["afii57399"]=1639,
+ ["afii57400"]=1640,
+ ["afii57401"]=1641,
+ ["afii57403"]=1563,
+ ["afii57407"]=1567,
+ ["afii57409"]=1569,
+ ["afii57410"]=1570,
+ ["afii57411"]=1571,
+ ["afii57412"]=1572,
+ ["afii57413"]=1573,
+ ["afii57414"]=1574,
+ ["afii57415"]=1575,
+ ["afii57416"]=1576,
+ ["afii57417"]=1577,
+ ["afii57418"]=1578,
+ ["afii57419"]=1579,
+ ["afii57420"]=1580,
+ ["afii57421"]=1581,
+ ["afii57422"]=1582,
+ ["afii57423"]=1583,
+ ["afii57424"]=1584,
+ ["afii57425"]=1585,
+ ["afii57426"]=1586,
+ ["afii57427"]=1587,
+ ["afii57428"]=1588,
+ ["afii57429"]=1589,
+ ["afii57430"]=1590,
+ ["afii57431"]=1591,
+ ["afii57432"]=1592,
+ ["afii57433"]=1593,
+ ["afii57434"]=1594,
+ ["afii57440"]=1600,
+ ["afii57441"]=1601,
+ ["afii57442"]=1602,
+ ["afii57443"]=1603,
+ ["afii57444"]=1604,
+ ["afii57445"]=1605,
+ ["afii57446"]=1606,
+ ["afii57448"]=1608,
+ ["afii57449"]=1609,
+ ["afii57450"]=1610,
+ ["afii57451"]=1611,
+ ["afii57452"]=1612,
+ ["afii57453"]=1613,
+ ["afii57454"]=1614,
+ ["afii57455"]=1615,
+ ["afii57456"]=1616,
+ ["afii57457"]=1617,
+ ["afii57458"]=1618,
+ ["afii57470"]=1607,
+ ["afii57505"]=1700,
+ ["afii57506"]=1662,
+ ["afii57507"]=1670,
+ ["afii57508"]=1688,
+ ["afii57509"]=1711,
+ ["afii57511"]=1657,
+ ["afii57512"]=1672,
+ ["afii57513"]=1681,
+ ["afii57514"]=1722,
+ ["afii57519"]=1746,
+ ["afii57534"]=1749,
+ ["afii57636"]=8362,
+ ["afii57645"]=1470,
+ ["afii57658"]=1475,
+ ["afii57664"]=1488,
+ ["afii57665"]=1489,
+ ["afii57666"]=1490,
+ ["afii57667"]=1491,
+ ["afii57668"]=1492,
+ ["afii57669"]=1493,
+ ["afii57670"]=1494,
+ ["afii57671"]=1495,
+ ["afii57672"]=1496,
+ ["afii57673"]=1497,
+ ["afii57674"]=1498,
+ ["afii57675"]=1499,
+ ["afii57676"]=1500,
+ ["afii57677"]=1501,
+ ["afii57678"]=1502,
+ ["afii57679"]=1503,
+ ["afii57680"]=1504,
+ ["afii57681"]=1505,
+ ["afii57682"]=1506,
+ ["afii57683"]=1507,
+ ["afii57684"]=1508,
+ ["afii57685"]=1509,
+ ["afii57686"]=1510,
+ ["afii57687"]=1511,
+ ["afii57688"]=1512,
+ ["afii57689"]=1513,
+ ["afii57690"]=1514,
+ ["afii57694"]=64298,
+ ["afii57695"]=64299,
+ ["afii57700"]=64331,
+ ["afii57705"]=64287,
+ ["afii57716"]=1520,
+ ["afii57717"]=1521,
+ ["afii57718"]=1522,
+ ["afii57723"]=64309,
+ ["afii57793"]=1460,
+ ["afii57794"]=1461,
+ ["afii57795"]=1462,
+ ["afii57796"]=1467,
+ ["afii57797"]=1464,
+ ["afii57798"]=1463,
+ ["afii57799"]=1456,
+ ["afii57800"]=1458,
+ ["afii57801"]=1457,
+ ["afii57802"]=1459,
+ ["afii57803"]=1474,
+ ["afii57804"]=1473,
+ ["afii57806"]=1465,
+ ["afii57807"]=1468,
+ ["afii57839"]=1469,
+ ["afii57841"]=1471,
+ ["afii57842"]=1472,
+ ["afii57929"]=700,
+ ["afii61248"]=8453,
+ ["afii61289"]=8467,
+ ["afii61352"]=8470,
+ ["afii61573"]=8236,
+ ["afii61574"]=8237,
+ ["afii61575"]=8238,
+ ["afii61664"]=8204,
+ ["afii63167"]=1645,
+ ["afii64937"]=701,
+ ["agrave"]=224,
+ ["agujarati"]=2693,
+ ["agurmukhi"]=2565,
+ ["ahiragana"]=12354,
+ ["ahookabove"]=7843,
+ ["aibengali"]=2448,
+ ["aibopomofo"]=12574,
+ ["aideva"]=2320,
+ ["aiecyrillic"]=1237,
+ ["aigujarati"]=2704,
+ ["aigurmukhi"]=2576,
+ ["aimatragurmukhi"]=2632,
+ ["ainarabic"]=1593,
+ ["ainfinalarabic"]=65226,
+ ["aininitialarabic"]=65227,
+ ["ainmedialarabic"]=65228,
+ ["ainvertedbreve"]=515,
+ ["aivowelsignbengali"]=2504,
+ ["aivowelsigndeva"]=2376,
+ ["aivowelsigngujarati"]=2760,
+ ["akatakana"]=12450,
+ ["akatakanahalfwidth"]=65393,
+ ["akorean"]=12623,
+ ["alef"]=1488,
+ ["alefarabic"]=1575,
+ ["alefdageshhebrew"]=64304,
+ ["aleffinalarabic"]=65166,
+ ["alefhamzaabovearabic"]=1571,
+ ["alefhamzaabovefinalarabic"]=65156,
+ ["alefhamzabelowarabic"]=1573,
+ ["alefhamzabelowfinalarabic"]=65160,
+ ["alefhebrew"]=1488,
+ ["aleflamedhebrew"]=64335,
+ ["alefmaddaabovearabic"]=1570,
+ ["alefmaddaabovefinalarabic"]=65154,
+ ["alefmaksuraarabic"]=1609,
+ ["alefmaksurafinalarabic"]=65264,
+ ["alefmaksurainitialarabic"]=65267,
+ ["alefmaksuramedialarabic"]=65268,
+ ["alefpatahhebrew"]=64302,
+ ["alefqamatshebrew"]=64303,
+ ["aleph"]=8501,
+ ["allequal"]=8780,
+ ["alpha"]=945,
+ ["alphatonos"]=940,
+ ["amacron"]=257,
+ ["amonospace"]=65345,
+ ["ampersand"]=38,
+ ["ampersandmonospace"]=65286,
+ ["ampersandsmall"]=63270,
+ ["amsquare"]=13250,
+ ["anbopomofo"]=12578,
+ ["angbopomofo"]=12580,
+ ["angkhankhuthai"]=3674,
+ ["angle"]=8736,
+ ["anglebracketleft"]=12296,
+ ["anglebracketleftvertical"]=65087,
+ ["anglebracketright"]=12297,
+ ["anglebracketrightvertical"]=65088,
+ ["angleleft"]=9001,
+ ["angleright"]=9002,
+ ["angstrom"]=8491,
+ ["anoteleia"]=903,
+ ["anudattadeva"]=2386,
+ ["anusvarabengali"]=2434,
+ ["anusvaradeva"]=2306,
+ ["anusvaragujarati"]=2690,
+ ["aogonek"]=261,
+ ["apaatosquare"]=13056,
+ ["aparen"]=9372,
+ ["apostrophearmenian"]=1370,
+ ["apostrophemod"]=700,
+ ["apple"]=63743,
+ ["approaches"]=8784,
+ ["approxequal"]=8776,
+ ["approxequalorimage"]=8786,
+ ["approximatelyequal"]=8773,
+ ["araeaekorean"]=12686,
+ ["araeakorean"]=12685,
+ ["arc"]=8978,
+ ["arighthalfring"]=7834,
+ ["aring"]=229,
+ ["aringacute"]=507,
+ ["aringbelow"]=7681,
+ ["arrowboth"]=8596,
+ ["arrowdashdown"]=8675,
+ ["arrowdashleft"]=8672,
+ ["arrowdashright"]=8674,
+ ["arrowdashup"]=8673,
+ ["arrowdblboth"]=8660,
+ ["arrowdbldown"]=8659,
+ ["arrowdblleft"]=8656,
+ ["arrowdblright"]=8658,
+ ["arrowdblup"]=8657,
+ ["arrowdown"]=8595,
+ ["arrowdownleft"]=8601,
+ ["arrowdownright"]=8600,
+ ["arrowdownwhite"]=8681,
+ ["arrowheaddownmod"]=709,
+ ["arrowheadleftmod"]=706,
+ ["arrowheadrightmod"]=707,
+ ["arrowheadupmod"]=708,
+ ["arrowhorizex"]=63719,
+ ["arrowleft"]=8592,
+ ["arrowleftdbl"]=8656,
+ ["arrowleftdblstroke"]=8653,
+ ["arrowleftoverright"]=8646,
+ ["arrowleftwhite"]=8678,
+ ["arrowright"]=8594,
+ ["arrowrightdblstroke"]=8655,
+ ["arrowrightheavy"]=10142,
+ ["arrowrightoverleft"]=8644,
+ ["arrowrightwhite"]=8680,
+ ["arrowtableft"]=8676,
+ ["arrowtabright"]=8677,
+ ["arrowup"]=8593,
+ ["arrowupdn"]=8597,
+ ["arrowupdnbse"]=8616,
+ ["arrowupdownbase"]=8616,
+ ["arrowupleft"]=8598,
+ ["arrowupleftofdown"]=8645,
+ ["arrowupright"]=8599,
+ ["arrowupwhite"]=8679,
+ ["arrowvertex"]=63718,
+ ["asciicircum"]=94,
+ ["asciicircummonospace"]=65342,
+ ["asciitilde"]=126,
+ ["asciitildemonospace"]=65374,
+ ["ascript"]=593,
+ ["ascriptturned"]=594,
+ ["asmallhiragana"]=12353,
+ ["asmallkatakana"]=12449,
+ ["asmallkatakanahalfwidth"]=65383,
+ ["asterisk"]=42,
+ ["asteriskaltonearabic"]=1645,
+ ["asteriskarabic"]=1645,
+ ["asteriskmath"]=8727,
+ ["asteriskmonospace"]=65290,
+ ["asterisksmall"]=65121,
+ ["asterism"]=8258,
+ ["asuperior"]=63209,
+ ["asymptoticallyequal"]=8771,
+ ["at"]=64,
+ ["atilde"]=227,
+ ["atmonospace"]=65312,
+ ["atsmall"]=65131,
+ ["aturned"]=592,
+ ["aubengali"]=2452,
+ ["aubopomofo"]=12576,
+ ["audeva"]=2324,
+ ["augujarati"]=2708,
+ ["augurmukhi"]=2580,
+ ["aulengthmarkbengali"]=2519,
+ ["aumatragurmukhi"]=2636,
+ ["auvowelsignbengali"]=2508,
+ ["auvowelsigndeva"]=2380,
+ ["auvowelsigngujarati"]=2764,
+ ["avagrahadeva"]=2365,
+ ["aybarmenian"]=1377,
+ ["ayin"]=1506,
+ ["ayinaltonehebrew"]=64288,
+ ["ayinhebrew"]=1506,
+ ["b"]=98,
+ ["babengali"]=2476,
+ ["backslash"]=92,
+ ["backslashmonospace"]=65340,
+ ["badeva"]=2348,
+ ["bagujarati"]=2732,
+ ["bagurmukhi"]=2604,
+ ["bahiragana"]=12400,
+ ["bahtthai"]=3647,
+ ["bakatakana"]=12496,
+ ["bar"]=124,
+ ["barmonospace"]=65372,
+ ["bbopomofo"]=12549,
+ ["bcircle"]=9425,
+ ["bdotaccent"]=7683,
+ ["bdotbelow"]=7685,
+ ["beamedsixteenthnotes"]=9836,
+ ["because"]=8757,
+ ["becyrillic"]=1073,
+ ["beharabic"]=1576,
+ ["behfinalarabic"]=65168,
+ ["behinitialarabic"]=65169,
+ ["behiragana"]=12409,
+ ["behmedialarabic"]=65170,
+ ["behmeeminitialarabic"]=64671,
+ ["behmeemisolatedarabic"]=64520,
+ ["behnoonfinalarabic"]=64621,
+ ["bekatakana"]=12505,
+ ["benarmenian"]=1378,
+ ["bet"]=1489,
+ ["beta"]=946,
+ ["betasymbolgreek"]=976,
+ ["betdagesh"]=64305,
+ ["betdageshhebrew"]=64305,
+ ["bethebrew"]=1489,
+ ["betrafehebrew"]=64332,
+ ["bhabengali"]=2477,
+ ["bhadeva"]=2349,
+ ["bhagujarati"]=2733,
+ ["bhagurmukhi"]=2605,
+ ["bhook"]=595,
+ ["bihiragana"]=12403,
+ ["bikatakana"]=12499,
+ ["bilabialclick"]=664,
+ ["bindigurmukhi"]=2562,
+ ["birusquare"]=13105,
+ ["blackcircle"]=9679,
+ ["blackdiamond"]=9670,
+ ["blackdownpointingtriangle"]=9660,
+ ["blackleftpointingpointer"]=9668,
+ ["blackleftpointingtriangle"]=9664,
+ ["blacklenticularbracketleft"]=12304,
+ ["blacklenticularbracketleftvertical"]=65083,
+ ["blacklenticularbracketright"]=12305,
+ ["blacklenticularbracketrightvertical"]=65084,
+ ["blacklowerlefttriangle"]=9699,
+ ["blacklowerrighttriangle"]=9698,
+ ["blackrectangle"]=9644,
+ ["blackrightpointingpointer"]=9658,
+ ["blackrightpointingtriangle"]=9654,
+ ["blacksmallsquare"]=9642,
+ ["blacksmilingface"]=9787,
+ ["blacksquare"]=9632,
+ ["blackstar"]=9733,
+ ["blackupperlefttriangle"]=9700,
+ ["blackupperrighttriangle"]=9701,
+ ["blackuppointingsmalltriangle"]=9652,
+ ["blackuppointingtriangle"]=9650,
+ ["blank"]=9251,
+ ["blinebelow"]=7687,
+ ["block"]=9608,
+ ["bmonospace"]=65346,
+ ["bobaimaithai"]=3610,
+ ["bohiragana"]=12412,
+ ["bokatakana"]=12508,
+ ["bparen"]=9373,
+ ["bqsquare"]=13251,
+ ["braceex"]=63732,
+ ["braceleft"]=123,
+ ["braceleftbt"]=63731,
+ ["braceleftmid"]=63730,
+ ["braceleftmonospace"]=65371,
+ ["braceleftsmall"]=65115,
+ ["bracelefttp"]=63729,
+ ["braceleftvertical"]=65079,
+ ["braceright"]=125,
+ ["bracerightbt"]=63742,
+ ["bracerightmid"]=63741,
+ ["bracerightmonospace"]=65373,
+ ["bracerightsmall"]=65116,
+ ["bracerighttp"]=63740,
+ ["bracerightvertical"]=65080,
+ ["bracketleft"]=91,
+ ["bracketleftbt"]=63728,
+ ["bracketleftex"]=63727,
+ ["bracketleftmonospace"]=65339,
+ ["bracketlefttp"]=63726,
+ ["bracketright"]=93,
+ ["bracketrightbt"]=63739,
+ ["bracketrightex"]=63738,
+ ["bracketrightmonospace"]=65341,
+ ["bracketrighttp"]=63737,
+ ["breve"]=728,
+ ["brevebelowcmb"]=814,
+ ["brevecmb"]=774,
+ ["breveinvertedbelowcmb"]=815,
+ ["breveinvertedcmb"]=785,
+ ["breveinverteddoublecmb"]=865,
+ ["bridgebelowcmb"]=810,
+ ["bridgeinvertedbelowcmb"]=826,
+ ["brokenbar"]=166,
+ ["bstroke"]=384,
+ ["bsuperior"]=63210,
+ ["btopbar"]=387,
+ ["buhiragana"]=12406,
+ ["bukatakana"]=12502,
+ ["bullet"]=8226,
+ ["bulletinverse"]=9688,
+ ["bulletoperator"]=8729,
+ ["bullseye"]=9678,
+ ["c"]=99,
+ ["caarmenian"]=1390,
+ ["cabengali"]=2458,
+ ["cacute"]=263,
+ ["cadeva"]=2330,
+ ["cagujarati"]=2714,
+ ["cagurmukhi"]=2586,
+ ["calsquare"]=13192,
+ ["candrabindubengali"]=2433,
+ ["candrabinducmb"]=784,
+ ["candrabindudeva"]=2305,
+ ["candrabindugujarati"]=2689,
+ ["capslock"]=8682,
+ ["careof"]=8453,
+ ["caron"]=711,
+ ["caronbelowcmb"]=812,
+ ["caroncmb"]=780,
+ ["carriagereturn"]=8629,
+ ["cbopomofo"]=12568,
+ ["ccaron"]=269,
+ ["ccedilla"]=231,
+ ["ccedillaacute"]=7689,
+ ["ccircle"]=9426,
+ ["ccircumflex"]=265,
+ ["ccurl"]=597,
+ ["cdot"]=267,
+ ["cdotaccent"]=267,
+ ["cdsquare"]=13253,
+ ["cedilla"]=184,
+ ["cedillacmb"]=807,
+ ["cent"]=162,
+ ["centigrade"]=8451,
+ ["centinferior"]=63199,
+ ["centmonospace"]=65504,
+ ["centoldstyle"]=63394,
+ ["centsuperior"]=63200,
+ ["chaarmenian"]=1401,
+ ["chabengali"]=2459,
+ ["chadeva"]=2331,
+ ["chagujarati"]=2715,
+ ["chagurmukhi"]=2587,
+ ["chbopomofo"]=12564,
+ ["cheabkhasiancyrillic"]=1213,
+ ["checkmark"]=10003,
+ ["checyrillic"]=1095,
+ ["chedescenderabkhasiancyrillic"]=1215,
+ ["chedescendercyrillic"]=1207,
+ ["chedieresiscyrillic"]=1269,
+ ["cheharmenian"]=1395,
+ ["chekhakassiancyrillic"]=1228,
+ ["cheverticalstrokecyrillic"]=1209,
+ ["chi"]=967,
+ ["chieuchacirclekorean"]=12919,
+ ["chieuchaparenkorean"]=12823,
+ ["chieuchcirclekorean"]=12905,
+ ["chieuchkorean"]=12618,
+ ["chieuchparenkorean"]=12809,
+ ["chochangthai"]=3594,
+ ["chochanthai"]=3592,
+ ["chochingthai"]=3593,
+ ["chochoethai"]=3596,
+ ["chook"]=392,
+ ["cieucacirclekorean"]=12918,
+ ["cieucaparenkorean"]=12822,
+ ["cieuccirclekorean"]=12904,
+ ["cieuckorean"]=12616,
+ ["cieucparenkorean"]=12808,
+ ["cieucuparenkorean"]=12828,
+ ["circle"]=9675,
+ ["circlemultiply"]=8855,
+ ["circleot"]=8857,
+ ["circleplus"]=8853,
+ ["circlepostalmark"]=12342,
+ ["circlewithlefthalfblack"]=9680,
+ ["circlewithrighthalfblack"]=9681,
+ ["circumflex"]=710,
+ ["circumflexbelowcmb"]=813,
+ ["circumflexcmb"]=770,
+ ["clear"]=8999,
+ ["clickalveolar"]=450,
+ ["clickdental"]=448,
+ ["clicklateral"]=449,
+ ["clickretroflex"]=451,
+ ["club"]=9827,
+ ["clubsuitblack"]=9827,
+ ["clubsuitwhite"]=9831,
+ ["cmcubedsquare"]=13220,
+ ["cmonospace"]=65347,
+ ["cmsquaredsquare"]=13216,
+ ["coarmenian"]=1409,
+ ["colon"]=58,
+ ["colonmonetary"]=8353,
+ ["colonmonospace"]=65306,
+ ["colonsign"]=8353,
+ ["colonsmall"]=65109,
+ ["colontriangularhalfmod"]=721,
+ ["colontriangularmod"]=720,
+ ["comma"]=44,
+ ["commaabovecmb"]=787,
+ ["commaaboverightcmb"]=789,
+ ["commaaccent"]=63171,
+ ["commaarabic"]=1548,
+ ["commaarmenian"]=1373,
+ ["commainferior"]=63201,
+ ["commamonospace"]=65292,
+ ["commareversedabovecmb"]=788,
+ ["commareversedmod"]=701,
+ ["commasmall"]=65104,
+ ["commasuperior"]=63202,
+ ["commaturnedabovecmb"]=786,
+ ["commaturnedmod"]=699,
+ ["compass"]=9788,
+ ["congruent"]=8773,
+ ["contourintegral"]=8750,
+ ["control"]=8963,
+ ["controlACK"]=6,
+ ["controlBEL"]=7,
+ ["controlBS"]=8,
+ ["controlCAN"]=24,
+ ["controlCR"]=13,
+ ["controlDC1"]=17,
+ ["controlDC2"]=18,
+ ["controlDC3"]=19,
+ ["controlDC4"]=20,
+ ["controlDEL"]=127,
+ ["controlDLE"]=16,
+ ["controlEM"]=25,
+ ["controlENQ"]=5,
+ ["controlEOT"]=4,
+ ["controlESC"]=27,
+ ["controlETB"]=23,
+ ["controlETX"]=3,
+ ["controlFF"]=12,
+ ["controlFS"]=28,
+ ["controlGS"]=29,
+ ["controlHT"]=9,
+ ["controlLF"]=10,
+ ["controlNAK"]=21,
+ ["controlRS"]=30,
+ ["controlSI"]=15,
+ ["controlSO"]=14,
+ ["controlSOT"]=2,
+ ["controlSTX"]=1,
+ ["controlSUB"]=26,
+ ["controlSYN"]=22,
+ ["controlUS"]=31,
+ ["controlVT"]=11,
+ ["copyright"]=169,
+ ["copyrightsans"]=63721,
+ ["copyrightserif"]=63193,
+ ["cornerbracketleft"]=12300,
+ ["cornerbracketlefthalfwidth"]=65378,
+ ["cornerbracketleftvertical"]=65089,
+ ["cornerbracketright"]=12301,
+ ["cornerbracketrighthalfwidth"]=65379,
+ ["cornerbracketrightvertical"]=65090,
+ ["corporationsquare"]=13183,
+ ["cosquare"]=13255,
+ ["coverkgsquare"]=13254,
+ ["cparen"]=9374,
+ ["cruzeiro"]=8354,
+ ["cstretched"]=663,
+ ["curlyand"]=8911,
+ ["curlyor"]=8910,
+ ["currency"]=164,
+ ["cyrBreve"]=63185,
+ ["cyrFlex"]=63186,
+ ["cyrbreve"]=63188,
+ ["cyrflex"]=63189,
+ ["d"]=100,
+ ["daarmenian"]=1380,
+ ["dabengali"]=2470,
+ ["dadarabic"]=1590,
+ ["dadeva"]=2342,
+ ["dadfinalarabic"]=65214,
+ ["dadinitialarabic"]=65215,
+ ["dadmedialarabic"]=65216,
+ ["dagesh"]=1468,
+ ["dageshhebrew"]=1468,
+ ["dagger"]=8224,
+ ["daggerdbl"]=8225,
+ ["dagujarati"]=2726,
+ ["dagurmukhi"]=2598,
+ ["dahiragana"]=12384,
+ ["dakatakana"]=12480,
+ ["dalarabic"]=1583,
+ ["dalet"]=1491,
+ ["daletdagesh"]=64307,
+ ["daletdageshhebrew"]=64307,
+ ["dalethatafpatah"]=1491,
+ ["dalethatafpatahhebrew"]=1491,
+ ["dalethatafsegol"]=1491,
+ ["dalethatafsegolhebrew"]=1491,
+ ["dalethebrew"]=1491,
+ ["dalethiriq"]=1491,
+ ["dalethiriqhebrew"]=1491,
+ ["daletholam"]=1491,
+ ["daletholamhebrew"]=1491,
+ ["daletpatah"]=1491,
+ ["daletpatahhebrew"]=1491,
+ ["daletqamats"]=1491,
+ ["daletqamatshebrew"]=1491,
+ ["daletqubuts"]=1491,
+ ["daletqubutshebrew"]=1491,
+ ["daletsegol"]=1491,
+ ["daletsegolhebrew"]=1491,
+ ["daletsheva"]=1491,
+ ["daletshevahebrew"]=1491,
+ ["dalettsere"]=1491,
+ ["dalettserehebrew"]=1491,
+ ["dalfinalarabic"]=65194,
+ ["dammaarabic"]=1615,
+ ["dammalowarabic"]=1615,
+ ["dammatanaltonearabic"]=1612,
+ ["dammatanarabic"]=1612,
+ ["danda"]=2404,
+ ["dargahebrew"]=1447,
+ ["dargalefthebrew"]=1447,
+ ["dasiapneumatacyrilliccmb"]=1157,
+ ["dblGrave"]=63187,
+ ["dblanglebracketleft"]=12298,
+ ["dblanglebracketleftvertical"]=65085,
+ ["dblanglebracketright"]=12299,
+ ["dblanglebracketrightvertical"]=65086,
+ ["dblarchinvertedbelowcmb"]=811,
+ ["dblarrowleft"]=8660,
+ ["dblarrowright"]=8658,
+ ["dbldanda"]=2405,
+ ["dblgrave"]=63190,
+ ["dblgravecmb"]=783,
+ ["dblintegral"]=8748,
+ ["dbllowline"]=8215,
+ ["dbllowlinecmb"]=819,
+ ["dbloverlinecmb"]=831,
+ ["dblprimemod"]=698,
+ ["dblverticalbar"]=8214,
+ ["dblverticallineabovecmb"]=782,
+ ["dbopomofo"]=12553,
+ ["dbsquare"]=13256,
+ ["dcaron"]=271,
+ ["dcedilla"]=7697,
+ ["dcircle"]=9427,
+ ["dcircumflexbelow"]=7699,
+ ["dcroat"]=273,
+ ["ddabengali"]=2465,
+ ["ddadeva"]=2337,
+ ["ddagujarati"]=2721,
+ ["ddagurmukhi"]=2593,
+ ["ddalarabic"]=1672,
+ ["ddalfinalarabic"]=64393,
+ ["dddhadeva"]=2396,
+ ["ddhabengali"]=2466,
+ ["ddhadeva"]=2338,
+ ["ddhagujarati"]=2722,
+ ["ddhagurmukhi"]=2594,
+ ["ddotaccent"]=7691,
+ ["ddotbelow"]=7693,
+ ["decimalseparatorarabic"]=1643,
+ ["decimalseparatorpersian"]=1643,
+ ["decyrillic"]=1076,
+ ["degree"]=176,
+ ["dehihebrew"]=1453,
+ ["dehiragana"]=12391,
+ ["deicoptic"]=1007,
+ ["dekatakana"]=12487,
+ ["deleteleft"]=9003,
+ ["deleteright"]=8998,
+ ["delta"]=948,
+ ["deltaturned"]=397,
+ ["denominatorminusonenumeratorbengali"]=2552,
+ ["dezh"]=676,
+ ["dhabengali"]=2471,
+ ["dhadeva"]=2343,
+ ["dhagujarati"]=2727,
+ ["dhagurmukhi"]=2599,
+ ["dhook"]=599,
+ ["dialytikatonos"]=901,
+ ["dialytikatonoscmb"]=836,
+ ["diamond"]=9830,
+ ["diamondsuitwhite"]=9826,
+ ["dieresis"]=168,
+ ["dieresisacute"]=63191,
+ ["dieresisbelowcmb"]=804,
+ ["dieresiscmb"]=776,
+ ["dieresisgrave"]=63192,
+ ["dieresistonos"]=901,
+ ["dihiragana"]=12386,
+ ["dikatakana"]=12482,
+ ["dittomark"]=12291,
+ ["divide"]=247,
+ ["divides"]=8739,
+ ["divisionslash"]=8725,
+ ["djecyrillic"]=1106,
+ ["dkshade"]=9619,
+ ["dlinebelow"]=7695,
+ ["dlsquare"]=13207,
+ ["dmacron"]=273,
+ ["dmonospace"]=65348,
+ ["dnblock"]=9604,
+ ["dochadathai"]=3598,
+ ["dodekthai"]=3604,
+ ["dohiragana"]=12393,
+ ["dokatakana"]=12489,
+ ["dollar"]=36,
+ ["dollarinferior"]=63203,
+ ["dollarmonospace"]=65284,
+ ["dollaroldstyle"]=63268,
+ ["dollarsmall"]=65129,
+ ["dollarsuperior"]=63204,
+ ["dong"]=8363,
+ ["dorusquare"]=13094,
+ ["dotaccent"]=729,
+ ["dotaccentcmb"]=775,
+ ["dotbelowcmb"]=803,
+ ["dotbelowcomb"]=803,
+ ["dotkatakana"]=12539,
+ ["dotlessi"]=305,
+ ["dotlessj"]=63166,
+ ["dotlessjstrokehook"]=644,
+ ["dotmath"]=8901,
+ ["dottedcircle"]=9676,
+ ["doubleyodpatah"]=64287,
+ ["doubleyodpatahhebrew"]=64287,
+ ["downtackbelowcmb"]=798,
+ ["downtackmod"]=725,
+ ["dparen"]=9375,
+ ["dsuperior"]=63211,
+ ["dtail"]=598,
+ ["dtopbar"]=396,
+ ["duhiragana"]=12389,
+ ["dukatakana"]=12485,
+ ["dz"]=499,
+ ["dzaltone"]=675,
+ ["dzcaron"]=454,
+ ["dzcurl"]=677,
+ ["dzeabkhasiancyrillic"]=1249,
+ ["dzecyrillic"]=1109,
+ ["dzhecyrillic"]=1119,
+ ["e"]=101,
+ ["eacute"]=233,
+ ["earth"]=9793,
+ ["ebengali"]=2447,
+ ["ebopomofo"]=12572,
+ ["ebreve"]=277,
+ ["ecandradeva"]=2317,
+ ["ecandragujarati"]=2701,
+ ["ecandravowelsigndeva"]=2373,
+ ["ecandravowelsigngujarati"]=2757,
+ ["ecaron"]=283,
+ ["ecedillabreve"]=7709,
+ ["echarmenian"]=1381,
+ ["echyiwnarmenian"]=1415,
+ ["ecircle"]=9428,
+ ["ecircumflex"]=234,
+ ["ecircumflexacute"]=7871,
+ ["ecircumflexbelow"]=7705,
+ ["ecircumflexdotbelow"]=7879,
+ ["ecircumflexgrave"]=7873,
+ ["ecircumflexhookabove"]=7875,
+ ["ecircumflextilde"]=7877,
+ ["ecyrillic"]=1108,
+ ["edblgrave"]=517,
+ ["edeva"]=2319,
+ ["edieresis"]=235,
+ ["edot"]=279,
+ ["edotaccent"]=279,
+ ["edotbelow"]=7865,
+ ["eegurmukhi"]=2575,
+ ["eematragurmukhi"]=2631,
+ ["efcyrillic"]=1092,
+ ["egrave"]=232,
+ ["egujarati"]=2703,
+ ["eharmenian"]=1383,
+ ["ehbopomofo"]=12573,
+ ["ehiragana"]=12360,
+ ["ehookabove"]=7867,
+ ["eibopomofo"]=12575,
+ ["eight"]=56,
+ ["eightarabic"]=1640,
+ ["eightbengali"]=2542,
+ ["eightcircle"]=9319,
+ ["eightcircleinversesansserif"]=10129,
+ ["eightdeva"]=2414,
+ ["eighteencircle"]=9329,
+ ["eighteenparen"]=9349,
+ ["eighteenperiod"]=9369,
+ ["eightgujarati"]=2798,
+ ["eightgurmukhi"]=2670,
+ ["eighthackarabic"]=1640,
+ ["eighthangzhou"]=12328,
+ ["eighthnotebeamed"]=9835,
+ ["eightideographicparen"]=12839,
+ ["eightinferior"]=8328,
+ ["eightmonospace"]=65304,
+ ["eightoldstyle"]=63288,
+ ["eightparen"]=9339,
+ ["eightperiod"]=9359,
+ ["eightpersian"]=1784,
+ ["eightroman"]=8567,
+ ["eightsuperior"]=8312,
+ ["eightthai"]=3672,
+ ["einvertedbreve"]=519,
+ ["eiotifiedcyrillic"]=1125,
+ ["ekatakana"]=12456,
+ ["ekatakanahalfwidth"]=65396,
+ ["ekonkargurmukhi"]=2676,
+ ["ekorean"]=12628,
+ ["elcyrillic"]=1083,
+ ["element"]=8712,
+ ["elevencircle"]=9322,
+ ["elevenparen"]=9342,
+ ["elevenperiod"]=9362,
+ ["elevenroman"]=8570,
+ ["ellipsis"]=8230,
+ ["ellipsisvertical"]=8942,
+ ["emacron"]=275,
+ ["emacronacute"]=7703,
+ ["emacrongrave"]=7701,
+ ["emcyrillic"]=1084,
+ ["emdash"]=8212,
+ ["emdashvertical"]=65073,
+ ["emonospace"]=65349,
+ ["emphasismarkarmenian"]=1371,
+ ["emptyset"]=8709,
+ ["enbopomofo"]=12579,
+ ["encyrillic"]=1085,
+ ["endash"]=8211,
+ ["endashvertical"]=65074,
+ ["endescendercyrillic"]=1187,
+ ["eng"]=331,
+ ["engbopomofo"]=12581,
+ ["enghecyrillic"]=1189,
+ ["enhookcyrillic"]=1224,
+ ["enspace"]=8194,
+ ["eogonek"]=281,
+ ["eokorean"]=12627,
+ ["eopen"]=603,
+ ["eopenclosed"]=666,
+ ["eopenreversed"]=604,
+ ["eopenreversedclosed"]=606,
+ ["eopenreversedhook"]=605,
+ ["eparen"]=9376,
+ ["epsilon"]=949,
+ ["epsilontonos"]=941,
+ ["equal"]=61,
+ ["equalmonospace"]=65309,
+ ["equalsmall"]=65126,
+ ["equalsuperior"]=8316,
+ ["equivalence"]=8801,
+ ["erbopomofo"]=12582,
+ ["ercyrillic"]=1088,
+ ["ereversed"]=600,
+ ["ereversedcyrillic"]=1101,
+ ["escyrillic"]=1089,
+ ["esdescendercyrillic"]=1195,
+ ["esh"]=643,
+ ["eshcurl"]=646,
+ ["eshortdeva"]=2318,
+ ["eshortvowelsigndeva"]=2374,
+ ["eshreversedloop"]=426,
+ ["eshsquatreversed"]=645,
+ ["esmallhiragana"]=12359,
+ ["esmallkatakana"]=12455,
+ ["esmallkatakanahalfwidth"]=65386,
+ ["estimated"]=8494,
+ ["esuperior"]=63212,
+ ["eta"]=951,
+ ["etarmenian"]=1384,
+ ["etatonos"]=942,
+ ["eth"]=240,
+ ["etilde"]=7869,
+ ["etildebelow"]=7707,
+ ["etnahtafoukhhebrew"]=1425,
+ ["etnahtafoukhlefthebrew"]=1425,
+ ["etnahtahebrew"]=1425,
+ ["etnahtalefthebrew"]=1425,
+ ["eturned"]=477,
+ ["eukorean"]=12641,
+ ["euro"]=8364,
+ ["evowelsignbengali"]=2503,
+ ["evowelsigndeva"]=2375,
+ ["evowelsigngujarati"]=2759,
+ ["exclam"]=33,
+ ["exclamarmenian"]=1372,
+ ["exclamdbl"]=8252,
+ ["exclamdown"]=161,
+ ["exclamdownsmall"]=63393,
+ ["exclammonospace"]=65281,
+ ["exclamsmall"]=63265,
+ ["existential"]=8707,
+ ["ezh"]=658,
+ ["ezhcaron"]=495,
+ ["ezhcurl"]=659,
+ ["ezhreversed"]=441,
+ ["ezhtail"]=442,
+ ["f"]=102,
+ ["fadeva"]=2398,
+ ["fagurmukhi"]=2654,
+ ["fahrenheit"]=8457,
+ ["fathaarabic"]=1614,
+ ["fathalowarabic"]=1614,
+ ["fathatanarabic"]=1611,
+ ["fbopomofo"]=12552,
+ ["fcircle"]=9429,
+ ["fdotaccent"]=7711,
+ ["feharabic"]=1601,
+ ["feharmenian"]=1414,
+ ["fehfinalarabic"]=65234,
+ ["fehinitialarabic"]=65235,
+ ["fehmedialarabic"]=65236,
+ ["feicoptic"]=997,
+ ["female"]=9792,
+ ["ff"]=64256,
+ ["ffi"]=64259,
+ ["ffl"]=64260,
+ ["fi"]=64257,
+ ["fifteencircle"]=9326,
+ ["fifteenparen"]=9346,
+ ["fifteenperiod"]=9366,
+ ["figuredash"]=8210,
+ ["filledbox"]=9632,
+ ["filledrect"]=9644,
+ ["finalkaf"]=1498,
+ ["finalkafdagesh"]=64314,
+ ["finalkafdageshhebrew"]=64314,
+ ["finalkafhebrew"]=1498,
+ ["finalkafqamats"]=1498,
+ ["finalkafqamatshebrew"]=1498,
+ ["finalkafsheva"]=1498,
+ ["finalkafshevahebrew"]=1498,
+ ["finalmem"]=1501,
+ ["finalmemhebrew"]=1501,
+ ["finalnun"]=1503,
+ ["finalnunhebrew"]=1503,
+ ["finalpe"]=1507,
+ ["finalpehebrew"]=1507,
+ ["finaltsadi"]=1509,
+ ["finaltsadihebrew"]=1509,
+ ["firsttonechinese"]=713,
+ ["fisheye"]=9673,
+ ["fitacyrillic"]=1139,
+ ["five"]=53,
+ ["fivearabic"]=1637,
+ ["fivebengali"]=2539,
+ ["fivecircle"]=9316,
+ ["fivecircleinversesansserif"]=10126,
+ ["fivedeva"]=2411,
+ ["fiveeighths"]=8541,
+ ["fivegujarati"]=2795,
+ ["fivegurmukhi"]=2667,
+ ["fivehackarabic"]=1637,
+ ["fivehangzhou"]=12325,
+ ["fiveideographicparen"]=12836,
+ ["fiveinferior"]=8325,
+ ["fivemonospace"]=65301,
+ ["fiveoldstyle"]=63285,
+ ["fiveparen"]=9336,
+ ["fiveperiod"]=9356,
+ ["fivepersian"]=1781,
+ ["fiveroman"]=8564,
+ ["fivesuperior"]=8309,
+ ["fivethai"]=3669,
+ ["fl"]=64258,
+ ["florin"]=402,
+ ["fmonospace"]=65350,
+ ["fmsquare"]=13209,
+ ["fofanthai"]=3615,
+ ["fofathai"]=3613,
+ ["fongmanthai"]=3663,
+ ["forall"]=8704,
+ ["four"]=52,
+ ["fourarabic"]=1636,
+ ["fourbengali"]=2538,
+ ["fourcircle"]=9315,
+ ["fourcircleinversesansserif"]=10125,
+ ["fourdeva"]=2410,
+ ["fourgujarati"]=2794,
+ ["fourgurmukhi"]=2666,
+ ["fourhackarabic"]=1636,
+ ["fourhangzhou"]=12324,
+ ["fourideographicparen"]=12835,
+ ["fourinferior"]=8324,
+ ["fourmonospace"]=65300,
+ ["fournumeratorbengali"]=2551,
+ ["fouroldstyle"]=63284,
+ ["fourparen"]=9335,
+ ["fourperiod"]=9355,
+ ["fourpersian"]=1780,
+ ["fourroman"]=8563,
+ ["foursuperior"]=8308,
+ ["fourteencircle"]=9325,
+ ["fourteenparen"]=9345,
+ ["fourteenperiod"]=9365,
+ ["fourthai"]=3668,
+ ["fourthtonechinese"]=715,
+ ["fparen"]=9377,
+ ["fraction"]=8260,
+ ["franc"]=8355,
+ ["g"]=103,
+ ["gabengali"]=2455,
+ ["gacute"]=501,
+ ["gadeva"]=2327,
+ ["gafarabic"]=1711,
+ ["gaffinalarabic"]=64403,
+ ["gafinitialarabic"]=64404,
+ ["gafmedialarabic"]=64405,
+ ["gagujarati"]=2711,
+ ["gagurmukhi"]=2583,
+ ["gahiragana"]=12364,
+ ["gakatakana"]=12460,
+ ["gamma"]=947,
+ ["gammalatinsmall"]=611,
+ ["gammasuperior"]=736,
+ ["gangiacoptic"]=1003,
+ ["gbopomofo"]=12557,
+ ["gbreve"]=287,
+ ["gcaron"]=487,
+ ["gcedilla"]=291,
+ ["gcircle"]=9430,
+ ["gcircumflex"]=285,
+ ["gcommaaccent"]=291,
+ ["gdot"]=289,
+ ["gdotaccent"]=289,
+ ["gecyrillic"]=1075,
+ ["gehiragana"]=12370,
+ ["gekatakana"]=12466,
+ ["geometricallyequal"]=8785,
+ ["gereshaccenthebrew"]=1436,
+ ["gereshhebrew"]=1523,
+ ["gereshmuqdamhebrew"]=1437,
+ ["germandbls"]=223,
+ ["gershayimaccenthebrew"]=1438,
+ ["gershayimhebrew"]=1524,
+ ["getamark"]=12307,
+ ["ghabengali"]=2456,
+ ["ghadarmenian"]=1394,
+ ["ghadeva"]=2328,
+ ["ghagujarati"]=2712,
+ ["ghagurmukhi"]=2584,
+ ["ghainarabic"]=1594,
+ ["ghainfinalarabic"]=65230,
+ ["ghaininitialarabic"]=65231,
+ ["ghainmedialarabic"]=65232,
+ ["ghemiddlehookcyrillic"]=1173,
+ ["ghestrokecyrillic"]=1171,
+ ["gheupturncyrillic"]=1169,
+ ["ghhadeva"]=2394,
+ ["ghhagurmukhi"]=2650,
+ ["ghook"]=608,
+ ["ghzsquare"]=13203,
+ ["gihiragana"]=12366,
+ ["gikatakana"]=12462,
+ ["gimarmenian"]=1379,
+ ["gimel"]=1490,
+ ["gimeldagesh"]=64306,
+ ["gimeldageshhebrew"]=64306,
+ ["gimelhebrew"]=1490,
+ ["gjecyrillic"]=1107,
+ ["glottalinvertedstroke"]=446,
+ ["glottalstop"]=660,
+ ["glottalstopinverted"]=662,
+ ["glottalstopmod"]=704,
+ ["glottalstopreversed"]=661,
+ ["glottalstopreversedmod"]=705,
+ ["glottalstopreversedsuperior"]=740,
+ ["glottalstopstroke"]=673,
+ ["glottalstopstrokereversed"]=674,
+ ["gmacron"]=7713,
+ ["gmonospace"]=65351,
+ ["gohiragana"]=12372,
+ ["gokatakana"]=12468,
+ ["gparen"]=9378,
+ ["gpasquare"]=13228,
+ ["gradient"]=8711,
+ ["grave"]=96,
+ ["gravebelowcmb"]=790,
+ ["gravecmb"]=768,
+ ["gravecomb"]=768,
+ ["gravedeva"]=2387,
+ ["gravelowmod"]=718,
+ ["gravemonospace"]=65344,
+ ["gravetonecmb"]=832,
+ ["greater"]=62,
+ ["greaterequal"]=8805,
+ ["greaterequalorless"]=8923,
+ ["greatermonospace"]=65310,
+ ["greaterorequivalent"]=8819,
+ ["greaterorless"]=8823,
+ ["greateroverequal"]=8807,
+ ["greatersmall"]=65125,
+ ["gscript"]=609,
+ ["gstroke"]=485,
+ ["guhiragana"]=12368,
+ ["guillemotleft"]=171,
+ ["guillemotright"]=187,
+ ["guilsinglleft"]=8249,
+ ["guilsinglright"]=8250,
+ ["gukatakana"]=12464,
+ ["guramusquare"]=13080,
+ ["gysquare"]=13257,
+ ["h"]=104,
+ ["haabkhasiancyrillic"]=1193,
+ ["haaltonearabic"]=1729,
+ ["habengali"]=2489,
+ ["hadescendercyrillic"]=1203,
+ ["hadeva"]=2361,
+ ["hagujarati"]=2745,
+ ["hagurmukhi"]=2617,
+ ["haharabic"]=1581,
+ ["hahfinalarabic"]=65186,
+ ["hahinitialarabic"]=65187,
+ ["hahiragana"]=12399,
+ ["hahmedialarabic"]=65188,
+ ["haitusquare"]=13098,
+ ["hakatakana"]=12495,
+ ["hakatakanahalfwidth"]=65418,
+ ["halantgurmukhi"]=2637,
+ ["hamzaarabic"]=1569,
+ ["hamzadammaarabic"]=1569,
+ ["hamzadammatanarabic"]=1569,
+ ["hamzafathaarabic"]=1569,
+ ["hamzafathatanarabic"]=1569,
+ ["hamzalowarabic"]=1569,
+ ["hamzalowkasraarabic"]=1569,
+ ["hamzalowkasratanarabic"]=1569,
+ ["hamzasukunarabic"]=1569,
+ ["hangulfiller"]=12644,
+ ["hardsigncyrillic"]=1098,
+ ["harpoonleftbarbup"]=8636,
+ ["harpoonrightbarbup"]=8640,
+ ["hasquare"]=13258,
+ ["hatafpatah"]=1458,
+ ["hatafpatah16"]=1458,
+ ["hatafpatah23"]=1458,
+ ["hatafpatah2f"]=1458,
+ ["hatafpatahhebrew"]=1458,
+ ["hatafpatahnarrowhebrew"]=1458,
+ ["hatafpatahquarterhebrew"]=1458,
+ ["hatafpatahwidehebrew"]=1458,
+ ["hatafqamats"]=1459,
+ ["hatafqamats1b"]=1459,
+ ["hatafqamats28"]=1459,
+ ["hatafqamats34"]=1459,
+ ["hatafqamatshebrew"]=1459,
+ ["hatafqamatsnarrowhebrew"]=1459,
+ ["hatafqamatsquarterhebrew"]=1459,
+ ["hatafqamatswidehebrew"]=1459,
+ ["hatafsegol"]=1457,
+ ["hatafsegol17"]=1457,
+ ["hatafsegol24"]=1457,
+ ["hatafsegol30"]=1457,
+ ["hatafsegolhebrew"]=1457,
+ ["hatafsegolnarrowhebrew"]=1457,
+ ["hatafsegolquarterhebrew"]=1457,
+ ["hatafsegolwidehebrew"]=1457,
+ ["hbar"]=295,
+ ["hbopomofo"]=12559,
+ ["hbrevebelow"]=7723,
+ ["hcedilla"]=7721,
+ ["hcircle"]=9431,
+ ["hcircumflex"]=293,
+ ["hdieresis"]=7719,
+ ["hdotaccent"]=7715,
+ ["hdotbelow"]=7717,
+ ["he"]=1492,
+ ["heart"]=9829,
+ ["heartsuitblack"]=9829,
+ ["heartsuitwhite"]=9825,
+ ["hedagesh"]=64308,
+ ["hedageshhebrew"]=64308,
+ ["hehaltonearabic"]=1729,
+ ["heharabic"]=1607,
+ ["hehebrew"]=1492,
+ ["hehfinalaltonearabic"]=64423,
+ ["hehfinalalttwoarabic"]=65258,
+ ["hehfinalarabic"]=65258,
+ ["hehhamzaabovefinalarabic"]=64421,
+ ["hehhamzaaboveisolatedarabic"]=64420,
+ ["hehinitialaltonearabic"]=64424,
+ ["hehinitialarabic"]=65259,
+ ["hehiragana"]=12408,
+ ["hehmedialaltonearabic"]=64425,
+ ["hehmedialarabic"]=65260,
+ ["heiseierasquare"]=13179,
+ ["hekatakana"]=12504,
+ ["hekatakanahalfwidth"]=65421,
+ ["hekutaarusquare"]=13110,
+ ["henghook"]=615,
+ ["herutusquare"]=13113,
+ ["het"]=1495,
+ ["hethebrew"]=1495,
+ ["hhook"]=614,
+ ["hhooksuperior"]=689,
+ ["hieuhacirclekorean"]=12923,
+ ["hieuhaparenkorean"]=12827,
+ ["hieuhcirclekorean"]=12909,
+ ["hieuhkorean"]=12622,
+ ["hieuhparenkorean"]=12813,
+ ["hihiragana"]=12402,
+ ["hikatakana"]=12498,
+ ["hikatakanahalfwidth"]=65419,
+ ["hiriq"]=1460,
+ ["hiriq14"]=1460,
+ ["hiriq21"]=1460,
+ ["hiriq2d"]=1460,
+ ["hiriqhebrew"]=1460,
+ ["hiriqnarrowhebrew"]=1460,
+ ["hiriqquarterhebrew"]=1460,
+ ["hiriqwidehebrew"]=1460,
+ ["hlinebelow"]=7830,
+ ["hmonospace"]=65352,
+ ["hoarmenian"]=1392,
+ ["hohipthai"]=3627,
+ ["hohiragana"]=12411,
+ ["hokatakana"]=12507,
+ ["hokatakanahalfwidth"]=65422,
+ ["holam"]=1465,
+ ["holam19"]=1465,
+ ["holam26"]=1465,
+ ["holam32"]=1465,
+ ["holamhebrew"]=1465,
+ ["holamnarrowhebrew"]=1465,
+ ["holamquarterhebrew"]=1465,
+ ["holamwidehebrew"]=1465,
+ ["honokhukthai"]=3630,
+ ["hookabovecomb"]=777,
+ ["hookcmb"]=777,
+ ["hookpalatalizedbelowcmb"]=801,
+ ["hookretroflexbelowcmb"]=802,
+ ["hoonsquare"]=13122,
+ ["horicoptic"]=1001,
+ ["horizontalbar"]=8213,
+ ["horncmb"]=795,
+ ["hotsprings"]=9832,
+ ["house"]=8962,
+ ["hparen"]=9379,
+ ["hsuperior"]=688,
+ ["hturned"]=613,
+ ["huhiragana"]=12405,
+ ["huiitosquare"]=13107,
+ ["hukatakana"]=12501,
+ ["hukatakanahalfwidth"]=65420,
+ ["hungarumlaut"]=733,
+ ["hungarumlautcmb"]=779,
+ ["hv"]=405,
+ ["hyphen"]=45,
+ ["hypheninferior"]=63205,
+ ["hyphenmonospace"]=65293,
+ ["hyphensmall"]=65123,
+ ["hyphensuperior"]=63206,
+ ["hyphentwo"]=8208,
+ ["i"]=105,
+ ["iacute"]=237,
+ ["iacyrillic"]=1103,
+ ["ibengali"]=2439,
+ ["ibopomofo"]=12583,
+ ["ibreve"]=301,
+ ["icaron"]=464,
+ ["icircle"]=9432,
+ ["icircumflex"]=238,
+ ["icyrillic"]=1110,
+ ["idblgrave"]=521,
+ ["ideographearthcircle"]=12943,
+ ["ideographfirecircle"]=12939,
+ ["ideographicallianceparen"]=12863,
+ ["ideographiccallparen"]=12858,
+ ["ideographiccentrecircle"]=12965,
+ ["ideographicclose"]=12294,
+ ["ideographiccomma"]=12289,
+ ["ideographiccommaleft"]=65380,
+ ["ideographiccongratulationparen"]=12855,
+ ["ideographiccorrectcircle"]=12963,
+ ["ideographicearthparen"]=12847,
+ ["ideographicenterpriseparen"]=12861,
+ ["ideographicexcellentcircle"]=12957,
+ ["ideographicfestivalparen"]=12864,
+ ["ideographicfinancialcircle"]=12950,
+ ["ideographicfinancialparen"]=12854,
+ ["ideographicfireparen"]=12843,
+ ["ideographichaveparen"]=12850,
+ ["ideographichighcircle"]=12964,
+ ["ideographiciterationmark"]=12293,
+ ["ideographiclaborcircle"]=12952,
+ ["ideographiclaborparen"]=12856,
+ ["ideographicleftcircle"]=12967,
+ ["ideographiclowcircle"]=12966,
+ ["ideographicmedicinecircle"]=12969,
+ ["ideographicmetalparen"]=12846,
+ ["ideographicmoonparen"]=12842,
+ ["ideographicnameparen"]=12852,
+ ["ideographicperiod"]=12290,
+ ["ideographicprintcircle"]=12958,
+ ["ideographicreachparen"]=12867,
+ ["ideographicrepresentparen"]=12857,
+ ["ideographicresourceparen"]=12862,
+ ["ideographicrightcircle"]=12968,
+ ["ideographicsecretcircle"]=12953,
+ ["ideographicselfparen"]=12866,
+ ["ideographicsocietyparen"]=12851,
+ ["ideographicspace"]=12288,
+ ["ideographicspecialparen"]=12853,
+ ["ideographicstockparen"]=12849,
+ ["ideographicstudyparen"]=12859,
+ ["ideographicsunparen"]=12848,
+ ["ideographicsuperviseparen"]=12860,
+ ["ideographicwaterparen"]=12844,
+ ["ideographicwoodparen"]=12845,
+ ["ideographiczero"]=12295,
+ ["ideographmetalcircle"]=12942,
+ ["ideographmooncircle"]=12938,
+ ["ideographnamecircle"]=12948,
+ ["ideographsuncircle"]=12944,
+ ["ideographwatercircle"]=12940,
+ ["ideographwoodcircle"]=12941,
+ ["ideva"]=2311,
+ ["idieresis"]=239,
+ ["idieresisacute"]=7727,
+ ["idieresiscyrillic"]=1253,
+ ["idotbelow"]=7883,
+ ["iebrevecyrillic"]=1239,
+ ["iecyrillic"]=1077,
+ ["ieungacirclekorean"]=12917,
+ ["ieungaparenkorean"]=12821,
+ ["ieungcirclekorean"]=12903,
+ ["ieungkorean"]=12615,
+ ["ieungparenkorean"]=12807,
+ ["igrave"]=236,
+ ["igujarati"]=2695,
+ ["igurmukhi"]=2567,
+ ["ihiragana"]=12356,
+ ["ihookabove"]=7881,
+ ["iibengali"]=2440,
+ ["iicyrillic"]=1080,
+ ["iideva"]=2312,
+ ["iigujarati"]=2696,
+ ["iigurmukhi"]=2568,
+ ["iimatragurmukhi"]=2624,
+ ["iinvertedbreve"]=523,
+ ["iishortcyrillic"]=1081,
+ ["iivowelsignbengali"]=2496,
+ ["iivowelsigndeva"]=2368,
+ ["iivowelsigngujarati"]=2752,
+ ["ij"]=307,
+ ["ikatakana"]=12452,
+ ["ikatakanahalfwidth"]=65394,
+ ["ikorean"]=12643,
+ ["ilde"]=732,
+ ["iluyhebrew"]=1452,
+ ["imacron"]=299,
+ ["imacroncyrillic"]=1251,
+ ["imageorapproximatelyequal"]=8787,
+ ["imatragurmukhi"]=2623,
+ ["imonospace"]=65353,
+ ["increment"]=8710,
+ ["infinity"]=8734,
+ ["iniarmenian"]=1387,
+ ["integral"]=8747,
+ ["integralbottom"]=8993,
+ ["integralbt"]=8993,
+ ["integralex"]=63733,
+ ["integraltop"]=8992,
+ ["integraltp"]=8992,
+ ["intersection"]=8745,
+ ["intisquare"]=13061,
+ ["invbullet"]=9688,
+ ["invcircle"]=9689,
+ ["invsmileface"]=9787,
+ ["iocyrillic"]=1105,
+ ["iogonek"]=303,
+ ["iota"]=953,
+ ["iotadieresis"]=970,
+ ["iotadieresistonos"]=912,
+ ["iotalatin"]=617,
+ ["iotatonos"]=943,
+ ["iparen"]=9380,
+ ["irigurmukhi"]=2674,
+ ["ismallhiragana"]=12355,
+ ["ismallkatakana"]=12451,
+ ["ismallkatakanahalfwidth"]=65384,
+ ["issharbengali"]=2554,
+ ["istroke"]=616,
+ ["isuperior"]=63213,
+ ["iterationhiragana"]=12445,
+ ["iterationkatakana"]=12541,
+ ["itilde"]=297,
+ ["itildebelow"]=7725,
+ ["iubopomofo"]=12585,
+ ["iucyrillic"]=1102,
+ ["ivowelsignbengali"]=2495,
+ ["ivowelsigndeva"]=2367,
+ ["ivowelsigngujarati"]=2751,
+ ["izhitsacyrillic"]=1141,
+ ["izhitsadblgravecyrillic"]=1143,
+ ["j"]=106,
+ ["jaarmenian"]=1393,
+ ["jabengali"]=2460,
+ ["jadeva"]=2332,
+ ["jagujarati"]=2716,
+ ["jagurmukhi"]=2588,
+ ["jbopomofo"]=12560,
+ ["jcaron"]=496,
+ ["jcircle"]=9433,
+ ["jcircumflex"]=309,
+ ["jcrossedtail"]=669,
+ ["jdotlessstroke"]=607,
+ ["jecyrillic"]=1112,
+ ["jeemarabic"]=1580,
+ ["jeemfinalarabic"]=65182,
+ ["jeeminitialarabic"]=65183,
+ ["jeemmedialarabic"]=65184,
+ ["jeharabic"]=1688,
+ ["jehfinalarabic"]=64395,
+ ["jhabengali"]=2461,
+ ["jhadeva"]=2333,
+ ["jhagujarati"]=2717,
+ ["jhagurmukhi"]=2589,
+ ["jheharmenian"]=1403,
+ ["jis"]=12292,
+ ["jmonospace"]=65354,
+ ["jparen"]=9381,
+ ["jsuperior"]=690,
+ ["k"]=107,
+ ["kabashkircyrillic"]=1185,
+ ["kabengali"]=2453,
+ ["kacute"]=7729,
+ ["kacyrillic"]=1082,
+ ["kadescendercyrillic"]=1179,
+ ["kadeva"]=2325,
+ ["kaf"]=1499,
+ ["kafarabic"]=1603,
+ ["kafdagesh"]=64315,
+ ["kafdageshhebrew"]=64315,
+ ["kaffinalarabic"]=65242,
+ ["kafhebrew"]=1499,
+ ["kafinitialarabic"]=65243,
+ ["kafmedialarabic"]=65244,
+ ["kafrafehebrew"]=64333,
+ ["kagujarati"]=2709,
+ ["kagurmukhi"]=2581,
+ ["kahiragana"]=12363,
+ ["kahookcyrillic"]=1220,
+ ["kakatakana"]=12459,
+ ["kakatakanahalfwidth"]=65398,
+ ["kappa"]=954,
+ ["kappasymbolgreek"]=1008,
+ ["kapyeounmieumkorean"]=12657,
+ ["kapyeounphieuphkorean"]=12676,
+ ["kapyeounpieupkorean"]=12664,
+ ["kapyeounssangpieupkorean"]=12665,
+ ["karoriisquare"]=13069,
+ ["kashidaautoarabic"]=1600,
+ ["kashidaautonosidebearingarabic"]=1600,
+ ["kasmallkatakana"]=12533,
+ ["kasquare"]=13188,
+ ["kasraarabic"]=1616,
+ ["kasratanarabic"]=1613,
+ ["kastrokecyrillic"]=1183,
+ ["katahiraprolongmarkhalfwidth"]=65392,
+ ["kaverticalstrokecyrillic"]=1181,
+ ["kbopomofo"]=12558,
+ ["kcalsquare"]=13193,
+ ["kcaron"]=489,
+ ["kcedilla"]=311,
+ ["kcircle"]=9434,
+ ["kcommaaccent"]=311,
+ ["kdotbelow"]=7731,
+ ["keharmenian"]=1412,
+ ["kehiragana"]=12369,
+ ["kekatakana"]=12465,
+ ["kekatakanahalfwidth"]=65401,
+ ["kenarmenian"]=1391,
+ ["kesmallkatakana"]=12534,
+ ["kgreenlandic"]=312,
+ ["khabengali"]=2454,
+ ["khacyrillic"]=1093,
+ ["khadeva"]=2326,
+ ["khagujarati"]=2710,
+ ["khagurmukhi"]=2582,
+ ["khaharabic"]=1582,
+ ["khahfinalarabic"]=65190,
+ ["khahinitialarabic"]=65191,
+ ["khahmedialarabic"]=65192,
+ ["kheicoptic"]=999,
+ ["khhadeva"]=2393,
+ ["khhagurmukhi"]=2649,
+ ["khieukhacirclekorean"]=12920,
+ ["khieukhaparenkorean"]=12824,
+ ["khieukhcirclekorean"]=12906,
+ ["khieukhkorean"]=12619,
+ ["khieukhparenkorean"]=12810,
+ ["khokhaithai"]=3586,
+ ["khokhonthai"]=3589,
+ ["khokhuatthai"]=3587,
+ ["khokhwaithai"]=3588,
+ ["khomutthai"]=3675,
+ ["khook"]=409,
+ ["khorakhangthai"]=3590,
+ ["khzsquare"]=13201,
+ ["kihiragana"]=12365,
+ ["kikatakana"]=12461,
+ ["kikatakanahalfwidth"]=65399,
+ ["kiroguramusquare"]=13077,
+ ["kiromeetorusquare"]=13078,
+ ["kirosquare"]=13076,
+ ["kiyeokacirclekorean"]=12910,
+ ["kiyeokaparenkorean"]=12814,
+ ["kiyeokcirclekorean"]=12896,
+ ["kiyeokkorean"]=12593,
+ ["kiyeokparenkorean"]=12800,
+ ["kiyeoksioskorean"]=12595,
+ ["kjecyrillic"]=1116,
+ ["klinebelow"]=7733,
+ ["klsquare"]=13208,
+ ["kmcubedsquare"]=13222,
+ ["kmonospace"]=65355,
+ ["kmsquaredsquare"]=13218,
+ ["kohiragana"]=12371,
+ ["kohmsquare"]=13248,
+ ["kokaithai"]=3585,
+ ["kokatakana"]=12467,
+ ["kokatakanahalfwidth"]=65402,
+ ["kooposquare"]=13086,
+ ["koppacyrillic"]=1153,
+ ["koreanstandardsymbol"]=12927,
+ ["koroniscmb"]=835,
+ ["kparen"]=9382,
+ ["kpasquare"]=13226,
+ ["ksicyrillic"]=1135,
+ ["ktsquare"]=13263,
+ ["kturned"]=670,
+ ["kuhiragana"]=12367,
+ ["kukatakana"]=12463,
+ ["kukatakanahalfwidth"]=65400,
+ ["kvsquare"]=13240,
+ ["kwsquare"]=13246,
+ ["l"]=108,
+ ["labengali"]=2482,
+ ["lacute"]=314,
+ ["ladeva"]=2354,
+ ["lagujarati"]=2738,
+ ["lagurmukhi"]=2610,
+ ["lakkhangyaothai"]=3653,
+ ["lamaleffinalarabic"]=65276,
+ ["lamalefhamzaabovefinalarabic"]=65272,
+ ["lamalefhamzaaboveisolatedarabic"]=65271,
+ ["lamalefhamzabelowfinalarabic"]=65274,
+ ["lamalefhamzabelowisolatedarabic"]=65273,
+ ["lamalefisolatedarabic"]=65275,
+ ["lamalefmaddaabovefinalarabic"]=65270,
+ ["lamalefmaddaaboveisolatedarabic"]=65269,
+ ["lamarabic"]=1604,
+ ["lambda"]=955,
+ ["lambdastroke"]=411,
+ ["lamed"]=1500,
+ ["lameddagesh"]=64316,
+ ["lameddageshhebrew"]=64316,
+ ["lamedhebrew"]=1500,
+ ["lamedholam"]=1500,
+ ["lamedholamdagesh"]=1500,
+ ["lamedholamdageshhebrew"]=1500,
+ ["lamedholamhebrew"]=1500,
+ ["lamfinalarabic"]=65246,
+ ["lamhahinitialarabic"]=64714,
+ ["laminitialarabic"]=65247,
+ ["lamjeeminitialarabic"]=64713,
+ ["lamkhahinitialarabic"]=64715,
+ ["lamlamhehisolatedarabic"]=65010,
+ ["lammedialarabic"]=65248,
+ ["lammeemhahinitialarabic"]=64904,
+ ["lammeeminitialarabic"]=64716,
+ ["lammeemjeeminitialarabic"]=65247,
+ ["lammeemkhahinitialarabic"]=65247,
+ ["largecircle"]=9711,
+ ["lbar"]=410,
+ ["lbelt"]=620,
+ ["lbopomofo"]=12556,
+ ["lcaron"]=318,
+ ["lcedilla"]=316,
+ ["lcircle"]=9435,
+ ["lcircumflexbelow"]=7741,
+ ["lcommaaccent"]=316,
+ ["ldot"]=320,
+ ["ldotaccent"]=320,
+ ["ldotbelow"]=7735,
+ ["ldotbelowmacron"]=7737,
+ ["leftangleabovecmb"]=794,
+ ["lefttackbelowcmb"]=792,
+ ["less"]=60,
+ ["lessequal"]=8804,
+ ["lessequalorgreater"]=8922,
+ ["lessmonospace"]=65308,
+ ["lessorequivalent"]=8818,
+ ["lessorgreater"]=8822,
+ ["lessoverequal"]=8806,
+ ["lesssmall"]=65124,
+ ["lezh"]=622,
+ ["lfblock"]=9612,
+ ["lhookretroflex"]=621,
+ ["lira"]=8356,
+ ["liwnarmenian"]=1388,
+ ["lj"]=457,
+ ["ljecyrillic"]=1113,
+ ["ll"]=63168,
+ ["lladeva"]=2355,
+ ["llagujarati"]=2739,
+ ["llinebelow"]=7739,
+ ["llladeva"]=2356,
+ ["llvocalicbengali"]=2529,
+ ["llvocalicdeva"]=2401,
+ ["llvocalicvowelsignbengali"]=2531,
+ ["llvocalicvowelsigndeva"]=2403,
+ ["lmiddletilde"]=619,
+ ["lmonospace"]=65356,
+ ["lmsquare"]=13264,
+ ["lochulathai"]=3628,
+ ["logicaland"]=8743,
+ ["logicalnot"]=172,
+ ["logicalnotreversed"]=8976,
+ ["logicalor"]=8744,
+ ["lolingthai"]=3621,
+ ["longs"]=383,
+ ["lowlinecenterline"]=65102,
+ ["lowlinecmb"]=818,
+ ["lowlinedashed"]=65101,
+ ["lozenge"]=9674,
+ ["lparen"]=9383,
+ ["lslash"]=322,
+ ["lsquare"]=8467,
+ ["lsuperior"]=63214,
+ ["ltshade"]=9617,
+ ["luthai"]=3622,
+ ["lvocalicbengali"]=2444,
+ ["lvocalicdeva"]=2316,
+ ["lvocalicvowelsignbengali"]=2530,
+ ["lvocalicvowelsigndeva"]=2402,
+ ["lxsquare"]=13267,
+ ["m"]=109,
+ ["mabengali"]=2478,
+ ["macron"]=175,
+ ["macronbelowcmb"]=817,
+ ["macroncmb"]=772,
+ ["macronlowmod"]=717,
+ ["macronmonospace"]=65507,
+ ["macute"]=7743,
+ ["madeva"]=2350,
+ ["magujarati"]=2734,
+ ["magurmukhi"]=2606,
+ ["mahapakhhebrew"]=1444,
+ ["mahapakhlefthebrew"]=1444,
+ ["mahiragana"]=12414,
+ ["maichattawalowleftthai"]=63637,
+ ["maichattawalowrightthai"]=63636,
+ ["maichattawathai"]=3659,
+ ["maichattawaupperleftthai"]=63635,
+ ["maieklowleftthai"]=63628,
+ ["maieklowrightthai"]=63627,
+ ["maiekthai"]=3656,
+ ["maiekupperleftthai"]=63626,
+ ["maihanakatleftthai"]=63620,
+ ["maihanakatthai"]=3633,
+ ["maitaikhuleftthai"]=63625,
+ ["maitaikhuthai"]=3655,
+ ["maitholowleftthai"]=63631,
+ ["maitholowrightthai"]=63630,
+ ["maithothai"]=3657,
+ ["maithoupperleftthai"]=63629,
+ ["maitrilowleftthai"]=63634,
+ ["maitrilowrightthai"]=63633,
+ ["maitrithai"]=3658,
+ ["maitriupperleftthai"]=63632,
+ ["maiyamokthai"]=3654,
+ ["makatakana"]=12510,
+ ["makatakanahalfwidth"]=65423,
+ ["male"]=9794,
+ ["mansyonsquare"]=13127,
+ ["maqafhebrew"]=1470,
+ ["mars"]=9794,
+ ["masoracirclehebrew"]=1455,
+ ["masquare"]=13187,
+ ["mbopomofo"]=12551,
+ ["mbsquare"]=13268,
+ ["mcircle"]=9436,
+ ["mcubedsquare"]=13221,
+ ["mdotaccent"]=7745,
+ ["mdotbelow"]=7747,
+ ["meemarabic"]=1605,
+ ["meemfinalarabic"]=65250,
+ ["meeminitialarabic"]=65251,
+ ["meemmedialarabic"]=65252,
+ ["meemmeeminitialarabic"]=64721,
+ ["meemmeemisolatedarabic"]=64584,
+ ["meetorusquare"]=13133,
+ ["mehiragana"]=12417,
+ ["meizierasquare"]=13182,
+ ["mekatakana"]=12513,
+ ["mekatakanahalfwidth"]=65426,
+ ["mem"]=1502,
+ ["memdagesh"]=64318,
+ ["memdageshhebrew"]=64318,
+ ["memhebrew"]=1502,
+ ["menarmenian"]=1396,
+ ["merkhahebrew"]=1445,
+ ["merkhakefulahebrew"]=1446,
+ ["merkhakefulalefthebrew"]=1446,
+ ["merkhalefthebrew"]=1445,
+ ["mhook"]=625,
+ ["mhzsquare"]=13202,
+ ["middledotkatakanahalfwidth"]=65381,
+ ["middot"]=183,
+ ["mieumacirclekorean"]=12914,
+ ["mieumaparenkorean"]=12818,
+ ["mieumcirclekorean"]=12900,
+ ["mieumkorean"]=12609,
+ ["mieumpansioskorean"]=12656,
+ ["mieumparenkorean"]=12804,
+ ["mieumpieupkorean"]=12654,
+ ["mieumsioskorean"]=12655,
+ ["mihiragana"]=12415,
+ ["mikatakana"]=12511,
+ ["mikatakanahalfwidth"]=65424,
+ ["minus"]=8722,
+ ["minusbelowcmb"]=800,
+ ["minuscircle"]=8854,
+ ["minusmod"]=727,
+ ["minusplus"]=8723,
+ ["minute"]=8242,
+ ["miribaarusquare"]=13130,
+ ["mirisquare"]=13129,
+ ["mlonglegturned"]=624,
+ ["mlsquare"]=13206,
+ ["mmcubedsquare"]=13219,
+ ["mmonospace"]=65357,
+ ["mmsquaredsquare"]=13215,
+ ["mohiragana"]=12418,
+ ["mohmsquare"]=13249,
+ ["mokatakana"]=12514,
+ ["mokatakanahalfwidth"]=65427,
+ ["molsquare"]=13270,
+ ["momathai"]=3617,
+ ["moverssquare"]=13223,
+ ["moverssquaredsquare"]=13224,
+ ["mparen"]=9384,
+ ["mpasquare"]=13227,
+ ["mssquare"]=13235,
+ ["msuperior"]=63215,
+ ["mturned"]=623,
+ ["mu"]=181,
+ ["mu1"]=181,
+ ["muasquare"]=13186,
+ ["muchgreater"]=8811,
+ ["muchless"]=8810,
+ ["mufsquare"]=13196,
+ ["mugreek"]=956,
+ ["mugsquare"]=13197,
+ ["muhiragana"]=12416,
+ ["mukatakana"]=12512,
+ ["mukatakanahalfwidth"]=65425,
+ ["mulsquare"]=13205,
+ ["multiply"]=215,
+ ["mumsquare"]=13211,
+ ["munahhebrew"]=1443,
+ ["munahlefthebrew"]=1443,
+ ["musicalnote"]=9834,
+ ["musicalnotedbl"]=9835,
+ ["musicflatsign"]=9837,
+ ["musicsharpsign"]=9839,
+ ["mussquare"]=13234,
+ ["muvsquare"]=13238,
+ ["muwsquare"]=13244,
+ ["mvmegasquare"]=13241,
+ ["mvsquare"]=13239,
+ ["mwmegasquare"]=13247,
+ ["mwsquare"]=13245,
+ ["n"]=110,
+ ["nabengali"]=2472,
+ ["nabla"]=8711,
+ ["nacute"]=324,
+ ["nadeva"]=2344,
+ ["nagujarati"]=2728,
+ ["nagurmukhi"]=2600,
+ ["nahiragana"]=12394,
+ ["nakatakana"]=12490,
+ ["nakatakanahalfwidth"]=65413,
+ ["napostrophe"]=329,
+ ["nasquare"]=13185,
+ ["nbopomofo"]=12555,
+ ["nbspace"]=160,
+ ["ncaron"]=328,
+ ["ncedilla"]=326,
+ ["ncircle"]=9437,
+ ["ncircumflexbelow"]=7755,
+ ["ncommaaccent"]=326,
+ ["ndotaccent"]=7749,
+ ["ndotbelow"]=7751,
+ ["nehiragana"]=12397,
+ ["nekatakana"]=12493,
+ ["nekatakanahalfwidth"]=65416,
+ ["newsheqelsign"]=8362,
+ ["nfsquare"]=13195,
+ ["ngabengali"]=2457,
+ ["ngadeva"]=2329,
+ ["ngagujarati"]=2713,
+ ["ngagurmukhi"]=2585,
+ ["ngonguthai"]=3591,
+ ["nhiragana"]=12435,
+ ["nhookleft"]=626,
+ ["nhookretroflex"]=627,
+ ["nieunacirclekorean"]=12911,
+ ["nieunaparenkorean"]=12815,
+ ["nieuncieuckorean"]=12597,
+ ["nieuncirclekorean"]=12897,
+ ["nieunhieuhkorean"]=12598,
+ ["nieunkorean"]=12596,
+ ["nieunpansioskorean"]=12648,
+ ["nieunparenkorean"]=12801,
+ ["nieunsioskorean"]=12647,
+ ["nieuntikeutkorean"]=12646,
+ ["nihiragana"]=12395,
+ ["nikatakana"]=12491,
+ ["nikatakanahalfwidth"]=65414,
+ ["nikhahitleftthai"]=63641,
+ ["nikhahitthai"]=3661,
+ ["nine"]=57,
+ ["ninearabic"]=1641,
+ ["ninebengali"]=2543,
+ ["ninecircle"]=9320,
+ ["ninecircleinversesansserif"]=10130,
+ ["ninedeva"]=2415,
+ ["ninegujarati"]=2799,
+ ["ninegurmukhi"]=2671,
+ ["ninehackarabic"]=1641,
+ ["ninehangzhou"]=12329,
+ ["nineideographicparen"]=12840,
+ ["nineinferior"]=8329,
+ ["ninemonospace"]=65305,
+ ["nineoldstyle"]=63289,
+ ["nineparen"]=9340,
+ ["nineperiod"]=9360,
+ ["ninepersian"]=1785,
+ ["nineroman"]=8568,
+ ["ninesuperior"]=8313,
+ ["nineteencircle"]=9330,
+ ["nineteenparen"]=9350,
+ ["nineteenperiod"]=9370,
+ ["ninethai"]=3673,
+ ["nj"]=460,
+ ["njecyrillic"]=1114,
+ ["nkatakana"]=12531,
+ ["nkatakanahalfwidth"]=65437,
+ ["nlegrightlong"]=414,
+ ["nlinebelow"]=7753,
+ ["nmonospace"]=65358,
+ ["nmsquare"]=13210,
+ ["nnabengali"]=2467,
+ ["nnadeva"]=2339,
+ ["nnagujarati"]=2723,
+ ["nnagurmukhi"]=2595,
+ ["nnnadeva"]=2345,
+ ["nohiragana"]=12398,
+ ["nokatakana"]=12494,
+ ["nokatakanahalfwidth"]=65417,
+ ["nonbreakingspace"]=160,
+ ["nonenthai"]=3603,
+ ["nonuthai"]=3609,
+ ["noonarabic"]=1606,
+ ["noonfinalarabic"]=65254,
+ ["noonghunnaarabic"]=1722,
+ ["noonghunnafinalarabic"]=64415,
+ ["noonhehinitialarabic"]=65255,
+ ["nooninitialarabic"]=65255,
+ ["noonjeeminitialarabic"]=64722,
+ ["noonjeemisolatedarabic"]=64587,
+ ["noonmedialarabic"]=65256,
+ ["noonmeeminitialarabic"]=64725,
+ ["noonmeemisolatedarabic"]=64590,
+ ["noonnoonfinalarabic"]=64653,
+ ["notcontains"]=8716,
+ ["notelement"]=8713,
+ ["notelementof"]=8713,
+ ["notequal"]=8800,
+ ["notgreater"]=8815,
+ ["notgreaternorequal"]=8817,
+ ["notgreaternorless"]=8825,
+ ["notidentical"]=8802,
+ ["notless"]=8814,
+ ["notlessnorequal"]=8816,
+ ["notparallel"]=8742,
+ ["notprecedes"]=8832,
+ ["notsubset"]=8836,
+ ["notsucceeds"]=8833,
+ ["notsuperset"]=8837,
+ ["nowarmenian"]=1398,
+ ["nparen"]=9385,
+ ["nssquare"]=13233,
+ ["nsuperior"]=8319,
+ ["ntilde"]=241,
+ ["nu"]=957,
+ ["nuhiragana"]=12396,
+ ["nukatakana"]=12492,
+ ["nukatakanahalfwidth"]=65415,
+ ["nuktabengali"]=2492,
+ ["nuktadeva"]=2364,
+ ["nuktagujarati"]=2748,
+ ["nuktagurmukhi"]=2620,
+ ["numbersign"]=35,
+ ["numbersignmonospace"]=65283,
+ ["numbersignsmall"]=65119,
+ ["numeralsigngreek"]=884,
+ ["numeralsignlowergreek"]=885,
+ ["numero"]=8470,
+ ["nun"]=1504,
+ ["nundagesh"]=64320,
+ ["nundageshhebrew"]=64320,
+ ["nunhebrew"]=1504,
+ ["nvsquare"]=13237,
+ ["nwsquare"]=13243,
+ ["nyabengali"]=2462,
+ ["nyadeva"]=2334,
+ ["nyagujarati"]=2718,
+ ["nyagurmukhi"]=2590,
+ ["o"]=111,
+ ["oacute"]=243,
+ ["oangthai"]=3629,
+ ["obarred"]=629,
+ ["obarredcyrillic"]=1257,
+ ["obarreddieresiscyrillic"]=1259,
+ ["obengali"]=2451,
+ ["obopomofo"]=12571,
+ ["obreve"]=335,
+ ["ocandradeva"]=2321,
+ ["ocandragujarati"]=2705,
+ ["ocandravowelsigndeva"]=2377,
+ ["ocandravowelsigngujarati"]=2761,
+ ["ocaron"]=466,
+ ["ocircle"]=9438,
+ ["ocircumflex"]=244,
+ ["ocircumflexacute"]=7889,
+ ["ocircumflexdotbelow"]=7897,
+ ["ocircumflexgrave"]=7891,
+ ["ocircumflexhookabove"]=7893,
+ ["ocircumflextilde"]=7895,
+ ["ocyrillic"]=1086,
+ ["odblacute"]=337,
+ ["odblgrave"]=525,
+ ["odeva"]=2323,
+ ["odieresis"]=246,
+ ["odieresiscyrillic"]=1255,
+ ["odotbelow"]=7885,
+ ["oe"]=339,
+ ["oekorean"]=12634,
+ ["ogonek"]=731,
+ ["ogonekcmb"]=808,
+ ["ograve"]=242,
+ ["ogujarati"]=2707,
+ ["oharmenian"]=1413,
+ ["ohiragana"]=12362,
+ ["ohookabove"]=7887,
+ ["ohorn"]=417,
+ ["ohornacute"]=7899,
+ ["ohorndotbelow"]=7907,
+ ["ohorngrave"]=7901,
+ ["ohornhookabove"]=7903,
+ ["ohorntilde"]=7905,
+ ["ohungarumlaut"]=337,
+ ["oi"]=419,
+ ["oinvertedbreve"]=527,
+ ["okatakana"]=12458,
+ ["okatakanahalfwidth"]=65397,
+ ["okorean"]=12631,
+ ["olehebrew"]=1451,
+ ["omacron"]=333,
+ ["omacronacute"]=7763,
+ ["omacrongrave"]=7761,
+ ["omdeva"]=2384,
+ ["omega"]=969,
+ ["omega1"]=982,
+ ["omegacyrillic"]=1121,
+ ["omegalatinclosed"]=631,
+ ["omegaroundcyrillic"]=1147,
+ ["omegatitlocyrillic"]=1149,
+ ["omegatonos"]=974,
+ ["omgujarati"]=2768,
+ ["omicron"]=959,
+ ["omicrontonos"]=972,
+ ["omonospace"]=65359,
+ ["one"]=49,
+ ["onearabic"]=1633,
+ ["onebengali"]=2535,
+ ["onecircle"]=9312,
+ ["onecircleinversesansserif"]=10122,
+ ["onedeva"]=2407,
+ ["onedotenleader"]=8228,
+ ["oneeighth"]=8539,
+ ["onefitted"]=63196,
+ ["onegujarati"]=2791,
+ ["onegurmukhi"]=2663,
+ ["onehackarabic"]=1633,
+ ["onehalf"]=189,
+ ["onehangzhou"]=12321,
+ ["oneideographicparen"]=12832,
+ ["oneinferior"]=8321,
+ ["onemonospace"]=65297,
+ ["onenumeratorbengali"]=2548,
+ ["oneoldstyle"]=63281,
+ ["oneparen"]=9332,
+ ["oneperiod"]=9352,
+ ["onepersian"]=1777,
+ ["onequarter"]=188,
+ ["oneroman"]=8560,
+ ["onesuperior"]=185,
+ ["onethai"]=3665,
+ ["onethird"]=8531,
+ ["oogonek"]=491,
+ ["oogonekmacron"]=493,
+ ["oogurmukhi"]=2579,
+ ["oomatragurmukhi"]=2635,
+ ["oopen"]=596,
+ ["oparen"]=9386,
+ ["openbullet"]=9702,
+ ["option"]=8997,
+ ["ordfeminine"]=170,
+ ["ordmasculine"]=186,
+ ["orthogonal"]=8735,
+ ["oshortdeva"]=2322,
+ ["oshortvowelsigndeva"]=2378,
+ ["oslash"]=248,
+ ["oslashacute"]=511,
+ ["osmallhiragana"]=12361,
+ ["osmallkatakana"]=12457,
+ ["osmallkatakanahalfwidth"]=65387,
+ ["ostrokeacute"]=511,
+ ["osuperior"]=63216,
+ ["otcyrillic"]=1151,
+ ["otilde"]=245,
+ ["otildeacute"]=7757,
+ ["otildedieresis"]=7759,
+ ["oubopomofo"]=12577,
+ ["overline"]=8254,
+ ["overlinecenterline"]=65098,
+ ["overlinecmb"]=773,
+ ["overlinedashed"]=65097,
+ ["overlinedblwavy"]=65100,
+ ["overlinewavy"]=65099,
+ ["overscore"]=175,
+ ["ovowelsignbengali"]=2507,
+ ["ovowelsigndeva"]=2379,
+ ["ovowelsigngujarati"]=2763,
+ ["p"]=112,
+ ["paampssquare"]=13184,
+ ["paasentosquare"]=13099,
+ ["pabengali"]=2474,
+ ["pacute"]=7765,
+ ["padeva"]=2346,
+ ["pagedown"]=8671,
+ ["pageup"]=8670,
+ ["pagujarati"]=2730,
+ ["pagurmukhi"]=2602,
+ ["pahiragana"]=12401,
+ ["paiyannoithai"]=3631,
+ ["pakatakana"]=12497,
+ ["palatalizationcyrilliccmb"]=1156,
+ ["palochkacyrillic"]=1216,
+ ["pansioskorean"]=12671,
+ ["paragraph"]=182,
+ ["parallel"]=8741,
+ ["parenleft"]=40,
+ ["parenleftaltonearabic"]=64830,
+ ["parenleftbt"]=63725,
+ ["parenleftex"]=63724,
+ ["parenleftinferior"]=8333,
+ ["parenleftmonospace"]=65288,
+ ["parenleftsmall"]=65113,
+ ["parenleftsuperior"]=8317,
+ ["parenlefttp"]=63723,
+ ["parenleftvertical"]=65077,
+ ["parenright"]=41,
+ ["parenrightaltonearabic"]=64831,
+ ["parenrightbt"]=63736,
+ ["parenrightex"]=63735,
+ ["parenrightinferior"]=8334,
+ ["parenrightmonospace"]=65289,
+ ["parenrightsmall"]=65114,
+ ["parenrightsuperior"]=8318,
+ ["parenrighttp"]=63734,
+ ["parenrightvertical"]=65078,
+ ["partialdiff"]=8706,
+ ["paseqhebrew"]=1472,
+ ["pashtahebrew"]=1433,
+ ["pasquare"]=13225,
+ ["patah"]=1463,
+ ["patah11"]=1463,
+ ["patah1d"]=1463,
+ ["patah2a"]=1463,
+ ["patahhebrew"]=1463,
+ ["patahnarrowhebrew"]=1463,
+ ["patahquarterhebrew"]=1463,
+ ["patahwidehebrew"]=1463,
+ ["pazerhebrew"]=1441,
+ ["pbopomofo"]=12550,
+ ["pcircle"]=9439,
+ ["pdotaccent"]=7767,
+ ["pe"]=1508,
+ ["pecyrillic"]=1087,
+ ["pedagesh"]=64324,
+ ["pedageshhebrew"]=64324,
+ ["peezisquare"]=13115,
+ ["pefinaldageshhebrew"]=64323,
+ ["peharabic"]=1662,
+ ["peharmenian"]=1402,
+ ["pehebrew"]=1508,
+ ["pehfinalarabic"]=64343,
+ ["pehinitialarabic"]=64344,
+ ["pehiragana"]=12410,
+ ["pehmedialarabic"]=64345,
+ ["pekatakana"]=12506,
+ ["pemiddlehookcyrillic"]=1191,
+ ["perafehebrew"]=64334,
+ ["percent"]=37,
+ ["percentarabic"]=1642,
+ ["percentmonospace"]=65285,
+ ["percentsmall"]=65130,
+ ["period"]=46,
+ ["periodarmenian"]=1417,
+ ["periodcentered"]=183,
+ ["periodhalfwidth"]=65377,
+ ["periodinferior"]=63207,
+ ["periodmonospace"]=65294,
+ ["periodsmall"]=65106,
+ ["periodsuperior"]=63208,
+ ["perispomenigreekcmb"]=834,
+ ["perpendicular"]=8869,
+ ["perthousand"]=8240,
+ ["peseta"]=8359,
+ ["pfsquare"]=13194,
+ ["phabengali"]=2475,
+ ["phadeva"]=2347,
+ ["phagujarati"]=2731,
+ ["phagurmukhi"]=2603,
+ ["phi"]=966,
+ ["phi1"]=981,
+ ["phieuphacirclekorean"]=12922,
+ ["phieuphaparenkorean"]=12826,
+ ["phieuphcirclekorean"]=12908,
+ ["phieuphkorean"]=12621,
+ ["phieuphparenkorean"]=12812,
+ ["philatin"]=632,
+ ["phinthuthai"]=3642,
+ ["phisymbolgreek"]=981,
+ ["phook"]=421,
+ ["phophanthai"]=3614,
+ ["phophungthai"]=3612,
+ ["phosamphaothai"]=3616,
+ ["pi"]=960,
+ ["pieupacirclekorean"]=12915,
+ ["pieupaparenkorean"]=12819,
+ ["pieupcieuckorean"]=12662,
+ ["pieupcirclekorean"]=12901,
+ ["pieupkiyeokkorean"]=12658,
+ ["pieupkorean"]=12610,
+ ["pieupparenkorean"]=12805,
+ ["pieupsioskiyeokkorean"]=12660,
+ ["pieupsioskorean"]=12612,
+ ["pieupsiostikeutkorean"]=12661,
+ ["pieupthieuthkorean"]=12663,
+ ["pieuptikeutkorean"]=12659,
+ ["pihiragana"]=12404,
+ ["pikatakana"]=12500,
+ ["pisymbolgreek"]=982,
+ ["piwrarmenian"]=1411,
+ ["plus"]=43,
+ ["plusbelowcmb"]=799,
+ ["pluscircle"]=8853,
+ ["plusminus"]=177,
+ ["plusmod"]=726,
+ ["plusmonospace"]=65291,
+ ["plussmall"]=65122,
+ ["plussuperior"]=8314,
+ ["pmonospace"]=65360,
+ ["pmsquare"]=13272,
+ ["pohiragana"]=12413,
+ ["pointingindexdownwhite"]=9759,
+ ["pointingindexleftwhite"]=9756,
+ ["pointingindexrightwhite"]=9758,
+ ["pointingindexupwhite"]=9757,
+ ["pokatakana"]=12509,
+ ["poplathai"]=3611,
+ ["postalmark"]=12306,
+ ["postalmarkface"]=12320,
+ ["pparen"]=9387,
+ ["precedes"]=8826,
+ ["prescription"]=8478,
+ ["primemod"]=697,
+ ["primereversed"]=8245,
+ ["product"]=8719,
+ ["projective"]=8965,
+ ["prolongedkana"]=12540,
+ ["propellor"]=8984,
+ ["propersubset"]=8834,
+ ["propersuperset"]=8835,
+ ["proportion"]=8759,
+ ["proportional"]=8733,
+ ["psi"]=968,
+ ["psicyrillic"]=1137,
+ ["psilipneumatacyrilliccmb"]=1158,
+ ["pssquare"]=13232,
+ ["puhiragana"]=12407,
+ ["pukatakana"]=12503,
+ ["pvsquare"]=13236,
+ ["pwsquare"]=13242,
+ ["q"]=113,
+ ["qadeva"]=2392,
+ ["qadmahebrew"]=1448,
+ ["qafarabic"]=1602,
+ ["qaffinalarabic"]=65238,
+ ["qafinitialarabic"]=65239,
+ ["qafmedialarabic"]=65240,
+ ["qamats"]=1464,
+ ["qamats10"]=1464,
+ ["qamats1a"]=1464,
+ ["qamats1c"]=1464,
+ ["qamats27"]=1464,
+ ["qamats29"]=1464,
+ ["qamats33"]=1464,
+ ["qamatsde"]=1464,
+ ["qamatshebrew"]=1464,
+ ["qamatsnarrowhebrew"]=1464,
+ ["qamatsqatanhebrew"]=1464,
+ ["qamatsqatannarrowhebrew"]=1464,
+ ["qamatsqatanquarterhebrew"]=1464,
+ ["qamatsqatanwidehebrew"]=1464,
+ ["qamatsquarterhebrew"]=1464,
+ ["qamatswidehebrew"]=1464,
+ ["qarneyparahebrew"]=1439,
+ ["qbopomofo"]=12561,
+ ["qcircle"]=9440,
+ ["qhook"]=672,
+ ["qmonospace"]=65361,
+ ["qof"]=1511,
+ ["qofdagesh"]=64327,
+ ["qofdageshhebrew"]=64327,
+ ["qofhatafpatah"]=1511,
+ ["qofhatafpatahhebrew"]=1511,
+ ["qofhatafsegol"]=1511,
+ ["qofhatafsegolhebrew"]=1511,
+ ["qofhebrew"]=1511,
+ ["qofhiriq"]=1511,
+ ["qofhiriqhebrew"]=1511,
+ ["qofholam"]=1511,
+ ["qofholamhebrew"]=1511,
+ ["qofpatah"]=1511,
+ ["qofpatahhebrew"]=1511,
+ ["qofqamats"]=1511,
+ ["qofqamatshebrew"]=1511,
+ ["qofqubuts"]=1511,
+ ["qofqubutshebrew"]=1511,
+ ["qofsegol"]=1511,
+ ["qofsegolhebrew"]=1511,
+ ["qofsheva"]=1511,
+ ["qofshevahebrew"]=1511,
+ ["qoftsere"]=1511,
+ ["qoftserehebrew"]=1511,
+ ["qparen"]=9388,
+ ["quarternote"]=9833,
+ ["qubuts"]=1467,
+ ["qubuts18"]=1467,
+ ["qubuts25"]=1467,
+ ["qubuts31"]=1467,
+ ["qubutshebrew"]=1467,
+ ["qubutsnarrowhebrew"]=1467,
+ ["qubutsquarterhebrew"]=1467,
+ ["qubutswidehebrew"]=1467,
+ ["question"]=63,
+ ["questionarabic"]=1567,
+ ["questionarmenian"]=1374,
+ ["questiondown"]=191,
+ ["questiondownsmall"]=63423,
+ ["questiongreek"]=894,
+ ["questionmonospace"]=65311,
+ ["questionsmall"]=63295,
+ ["quotedbl"]=34,
+ ["quotedblbase"]=8222,
+ ["quotedblleft"]=8220,
+ ["quotedblmonospace"]=65282,
+ ["quotedblprime"]=12318,
+ ["quotedblprimereversed"]=12317,
+ ["quotedblright"]=8221,
+ ["quoteleft"]=8216,
+ ["quoteleftreversed"]=8219,
+ ["quotereversed"]=8219,
+ ["quoteright"]=8217,
+ ["quoterightn"]=329,
+ ["quotesinglbase"]=8218,
+ ["quotesingle"]=39,
+ ["quotesinglemonospace"]=65287,
+ ["r"]=114,
+ ["raarmenian"]=1404,
+ ["rabengali"]=2480,
+ ["racute"]=341,
+ ["radeva"]=2352,
+ ["radical"]=8730,
+ ["radicalex"]=63717,
+ ["radoverssquare"]=13230,
+ ["radoverssquaredsquare"]=13231,
+ ["radsquare"]=13229,
+ ["rafe"]=1471,
+ ["rafehebrew"]=1471,
+ ["ragujarati"]=2736,
+ ["ragurmukhi"]=2608,
+ ["rahiragana"]=12425,
+ ["rakatakana"]=12521,
+ ["rakatakanahalfwidth"]=65431,
+ ["ralowerdiagonalbengali"]=2545,
+ ["ramiddlediagonalbengali"]=2544,
+ ["ramshorn"]=612,
+ ["ratio"]=8758,
+ ["rbopomofo"]=12566,
+ ["rcaron"]=345,
+ ["rcedilla"]=343,
+ ["rcircle"]=9441,
+ ["rcommaaccent"]=343,
+ ["rdblgrave"]=529,
+ ["rdotaccent"]=7769,
+ ["rdotbelow"]=7771,
+ ["rdotbelowmacron"]=7773,
+ ["referencemark"]=8251,
+ ["reflexsubset"]=8838,
+ ["reflexsuperset"]=8839,
+ ["registered"]=174,
+ ["registersans"]=63720,
+ ["registerserif"]=63194,
+ ["reharabic"]=1585,
+ ["reharmenian"]=1408,
+ ["rehfinalarabic"]=65198,
+ ["rehiragana"]=12428,
+ ["rehyehaleflamarabic"]=1585,
+ ["rekatakana"]=12524,
+ ["rekatakanahalfwidth"]=65434,
+ ["resh"]=1512,
+ ["reshdageshhebrew"]=64328,
+ ["reshhatafpatah"]=1512,
+ ["reshhatafpatahhebrew"]=1512,
+ ["reshhatafsegol"]=1512,
+ ["reshhatafsegolhebrew"]=1512,
+ ["reshhebrew"]=1512,
+ ["reshhiriq"]=1512,
+ ["reshhiriqhebrew"]=1512,
+ ["reshholam"]=1512,
+ ["reshholamhebrew"]=1512,
+ ["reshpatah"]=1512,
+ ["reshpatahhebrew"]=1512,
+ ["reshqamats"]=1512,
+ ["reshqamatshebrew"]=1512,
+ ["reshqubuts"]=1512,
+ ["reshqubutshebrew"]=1512,
+ ["reshsegol"]=1512,
+ ["reshsegolhebrew"]=1512,
+ ["reshsheva"]=1512,
+ ["reshshevahebrew"]=1512,
+ ["reshtsere"]=1512,
+ ["reshtserehebrew"]=1512,
+ ["reversedtilde"]=8765,
+ ["reviahebrew"]=1431,
+ ["reviamugrashhebrew"]=1431,
+ ["revlogicalnot"]=8976,
+ ["rfishhook"]=638,
+ ["rfishhookreversed"]=639,
+ ["rhabengali"]=2525,
+ ["rhadeva"]=2397,
+ ["rho"]=961,
+ ["rhook"]=637,
+ ["rhookturned"]=635,
+ ["rhookturnedsuperior"]=693,
+ ["rhosymbolgreek"]=1009,
+ ["rhotichookmod"]=734,
+ ["rieulacirclekorean"]=12913,
+ ["rieulaparenkorean"]=12817,
+ ["rieulcirclekorean"]=12899,
+ ["rieulhieuhkorean"]=12608,
+ ["rieulkiyeokkorean"]=12602,
+ ["rieulkiyeoksioskorean"]=12649,
+ ["rieulkorean"]=12601,
+ ["rieulmieumkorean"]=12603,
+ ["rieulpansioskorean"]=12652,
+ ["rieulparenkorean"]=12803,
+ ["rieulphieuphkorean"]=12607,
+ ["rieulpieupkorean"]=12604,
+ ["rieulpieupsioskorean"]=12651,
+ ["rieulsioskorean"]=12605,
+ ["rieulthieuthkorean"]=12606,
+ ["rieultikeutkorean"]=12650,
+ ["rieulyeorinhieuhkorean"]=12653,
+ ["rightangle"]=8735,
+ ["righttackbelowcmb"]=793,
+ ["righttriangle"]=8895,
+ ["rihiragana"]=12426,
+ ["rikatakana"]=12522,
+ ["rikatakanahalfwidth"]=65432,
+ ["ring"]=730,
+ ["ringbelowcmb"]=805,
+ ["ringcmb"]=778,
+ ["ringhalfleft"]=703,
+ ["ringhalfleftarmenian"]=1369,
+ ["ringhalfleftbelowcmb"]=796,
+ ["ringhalfleftcentered"]=723,
+ ["ringhalfright"]=702,
+ ["ringhalfrightbelowcmb"]=825,
+ ["ringhalfrightcentered"]=722,
+ ["rinvertedbreve"]=531,
+ ["rittorusquare"]=13137,
+ ["rlinebelow"]=7775,
+ ["rlongleg"]=636,
+ ["rlonglegturned"]=634,
+ ["rmonospace"]=65362,
+ ["rohiragana"]=12429,
+ ["rokatakana"]=12525,
+ ["rokatakanahalfwidth"]=65435,
+ ["roruathai"]=3619,
+ ["rparen"]=9389,
+ ["rrabengali"]=2524,
+ ["rradeva"]=2353,
+ ["rragurmukhi"]=2652,
+ ["rreharabic"]=1681,
+ ["rrehfinalarabic"]=64397,
+ ["rrvocalicbengali"]=2528,
+ ["rrvocalicdeva"]=2400,
+ ["rrvocalicgujarati"]=2784,
+ ["rrvocalicvowelsignbengali"]=2500,
+ ["rrvocalicvowelsigndeva"]=2372,
+ ["rrvocalicvowelsigngujarati"]=2756,
+ ["rsuperior"]=63217,
+ ["rtblock"]=9616,
+ ["rturned"]=633,
+ ["rturnedsuperior"]=692,
+ ["ruhiragana"]=12427,
+ ["rukatakana"]=12523,
+ ["rukatakanahalfwidth"]=65433,
+ ["rupeemarkbengali"]=2546,
+ ["rupeesignbengali"]=2547,
+ ["rupiah"]=63197,
+ ["ruthai"]=3620,
+ ["rvocalicbengali"]=2443,
+ ["rvocalicdeva"]=2315,
+ ["rvocalicgujarati"]=2699,
+ ["rvocalicvowelsignbengali"]=2499,
+ ["rvocalicvowelsigndeva"]=2371,
+ ["rvocalicvowelsigngujarati"]=2755,
+ ["s"]=115,
+ ["sabengali"]=2488,
+ ["sacute"]=347,
+ ["sacutedotaccent"]=7781,
+ ["sadarabic"]=1589,
+ ["sadeva"]=2360,
+ ["sadfinalarabic"]=65210,
+ ["sadinitialarabic"]=65211,
+ ["sadmedialarabic"]=65212,
+ ["sagujarati"]=2744,
+ ["sagurmukhi"]=2616,
+ ["sahiragana"]=12373,
+ ["sakatakana"]=12469,
+ ["sakatakanahalfwidth"]=65403,
+ ["sallallahoualayhewasallamarabic"]=65018,
+ ["samekh"]=1505,
+ ["samekhdagesh"]=64321,
+ ["samekhdageshhebrew"]=64321,
+ ["samekhhebrew"]=1505,
+ ["saraaathai"]=3634,
+ ["saraaethai"]=3649,
+ ["saraaimaimalaithai"]=3652,
+ ["saraaimaimuanthai"]=3651,
+ ["saraamthai"]=3635,
+ ["saraathai"]=3632,
+ ["saraethai"]=3648,
+ ["saraiileftthai"]=63622,
+ ["saraiithai"]=3637,
+ ["saraileftthai"]=63621,
+ ["saraithai"]=3636,
+ ["saraothai"]=3650,
+ ["saraueeleftthai"]=63624,
+ ["saraueethai"]=3639,
+ ["saraueleftthai"]=63623,
+ ["sarauethai"]=3638,
+ ["sarauthai"]=3640,
+ ["sarauuthai"]=3641,
+ ["sbopomofo"]=12569,
+ ["scaron"]=353,
+ ["scarondotaccent"]=7783,
+ ["scedilla"]=351,
+ ["schwa"]=601,
+ ["schwacyrillic"]=1241,
+ ["schwadieresiscyrillic"]=1243,
+ ["schwahook"]=602,
+ ["scircle"]=9442,
+ ["scircumflex"]=349,
+ ["scommaaccent"]=537,
+ ["sdotaccent"]=7777,
+ ["sdotbelow"]=7779,
+ ["sdotbelowdotaccent"]=7785,
+ ["seagullbelowcmb"]=828,
+ ["second"]=8243,
+ ["secondtonechinese"]=714,
+ ["section"]=167,
+ ["seenarabic"]=1587,
+ ["seenfinalarabic"]=65202,
+ ["seeninitialarabic"]=65203,
+ ["seenmedialarabic"]=65204,
+ ["segol"]=1462,
+ ["segol13"]=1462,
+ ["segol1f"]=1462,
+ ["segol2c"]=1462,
+ ["segolhebrew"]=1462,
+ ["segolnarrowhebrew"]=1462,
+ ["segolquarterhebrew"]=1462,
+ ["segoltahebrew"]=1426,
+ ["segolwidehebrew"]=1462,
+ ["seharmenian"]=1405,
+ ["sehiragana"]=12379,
+ ["sekatakana"]=12475,
+ ["sekatakanahalfwidth"]=65406,
+ ["semicolon"]=59,
+ ["semicolonarabic"]=1563,
+ ["semicolonmonospace"]=65307,
+ ["semicolonsmall"]=65108,
+ ["semivoicedmarkkana"]=12444,
+ ["semivoicedmarkkanahalfwidth"]=65439,
+ ["sentisquare"]=13090,
+ ["sentosquare"]=13091,
+ ["seven"]=55,
+ ["sevenarabic"]=1639,
+ ["sevenbengali"]=2541,
+ ["sevencircle"]=9318,
+ ["sevencircleinversesansserif"]=10128,
+ ["sevendeva"]=2413,
+ ["seveneighths"]=8542,
+ ["sevengujarati"]=2797,
+ ["sevengurmukhi"]=2669,
+ ["sevenhackarabic"]=1639,
+ ["sevenhangzhou"]=12327,
+ ["sevenideographicparen"]=12838,
+ ["seveninferior"]=8327,
+ ["sevenmonospace"]=65303,
+ ["sevenoldstyle"]=63287,
+ ["sevenparen"]=9338,
+ ["sevenperiod"]=9358,
+ ["sevenpersian"]=1783,
+ ["sevenroman"]=8566,
+ ["sevensuperior"]=8311,
+ ["seventeencircle"]=9328,
+ ["seventeenparen"]=9348,
+ ["seventeenperiod"]=9368,
+ ["seventhai"]=3671,
+ ["sfthyphen"]=173,
+ ["shaarmenian"]=1399,
+ ["shabengali"]=2486,
+ ["shacyrillic"]=1096,
+ ["shaddaarabic"]=1617,
+ ["shaddadammaarabic"]=64609,
+ ["shaddadammatanarabic"]=64606,
+ ["shaddafathaarabic"]=64608,
+ ["shaddafathatanarabic"]=1617,
+ ["shaddakasraarabic"]=64610,
+ ["shaddakasratanarabic"]=64607,
+ ["shade"]=9618,
+ ["shadedark"]=9619,
+ ["shadelight"]=9617,
+ ["shademedium"]=9618,
+ ["shadeva"]=2358,
+ ["shagujarati"]=2742,
+ ["shagurmukhi"]=2614,
+ ["shalshelethebrew"]=1427,
+ ["shbopomofo"]=12565,
+ ["shchacyrillic"]=1097,
+ ["sheenarabic"]=1588,
+ ["sheenfinalarabic"]=65206,
+ ["sheeninitialarabic"]=65207,
+ ["sheenmedialarabic"]=65208,
+ ["sheicoptic"]=995,
+ ["sheqel"]=8362,
+ ["sheqelhebrew"]=8362,
+ ["sheva"]=1456,
+ ["sheva115"]=1456,
+ ["sheva15"]=1456,
+ ["sheva22"]=1456,
+ ["sheva2e"]=1456,
+ ["shevahebrew"]=1456,
+ ["shevanarrowhebrew"]=1456,
+ ["shevaquarterhebrew"]=1456,
+ ["shevawidehebrew"]=1456,
+ ["shhacyrillic"]=1211,
+ ["shimacoptic"]=1005,
+ ["shin"]=1513,
+ ["shindagesh"]=64329,
+ ["shindageshhebrew"]=64329,
+ ["shindageshshindot"]=64300,
+ ["shindageshshindothebrew"]=64300,
+ ["shindageshsindot"]=64301,
+ ["shindageshsindothebrew"]=64301,
+ ["shindothebrew"]=1473,
+ ["shinhebrew"]=1513,
+ ["shinshindot"]=64298,
+ ["shinshindothebrew"]=64298,
+ ["shinsindot"]=64299,
+ ["shinsindothebrew"]=64299,
+ ["shook"]=642,
+ ["sigma"]=963,
+ ["sigma1"]=962,
+ ["sigmafinal"]=962,
+ ["sigmalunatesymbolgreek"]=1010,
+ ["sihiragana"]=12375,
+ ["sikatakana"]=12471,
+ ["sikatakanahalfwidth"]=65404,
+ ["siluqhebrew"]=1469,
+ ["siluqlefthebrew"]=1469,
+ ["similar"]=8764,
+ ["sindothebrew"]=1474,
+ ["siosacirclekorean"]=12916,
+ ["siosaparenkorean"]=12820,
+ ["sioscieuckorean"]=12670,
+ ["sioscirclekorean"]=12902,
+ ["sioskiyeokkorean"]=12666,
+ ["sioskorean"]=12613,
+ ["siosnieunkorean"]=12667,
+ ["siosparenkorean"]=12806,
+ ["siospieupkorean"]=12669,
+ ["siostikeutkorean"]=12668,
+ ["six"]=54,
+ ["sixarabic"]=1638,
+ ["sixbengali"]=2540,
+ ["sixcircle"]=9317,
+ ["sixcircleinversesansserif"]=10127,
+ ["sixdeva"]=2412,
+ ["sixgujarati"]=2796,
+ ["sixgurmukhi"]=2668,
+ ["sixhackarabic"]=1638,
+ ["sixhangzhou"]=12326,
+ ["sixideographicparen"]=12837,
+ ["sixinferior"]=8326,
+ ["sixmonospace"]=65302,
+ ["sixoldstyle"]=63286,
+ ["sixparen"]=9337,
+ ["sixperiod"]=9357,
+ ["sixpersian"]=1782,
+ ["sixroman"]=8565,
+ ["sixsuperior"]=8310,
+ ["sixteencircle"]=9327,
+ ["sixteencurrencydenominatorbengali"]=2553,
+ ["sixteenparen"]=9347,
+ ["sixteenperiod"]=9367,
+ ["sixthai"]=3670,
+ ["slash"]=47,
+ ["slashmonospace"]=65295,
+ ["slong"]=383,
+ ["slongdotaccent"]=7835,
+ ["smileface"]=9786,
+ ["smonospace"]=65363,
+ ["sofpasuqhebrew"]=1475,
+ ["softhyphen"]=173,
+ ["softsigncyrillic"]=1100,
+ ["sohiragana"]=12381,
+ ["sokatakana"]=12477,
+ ["sokatakanahalfwidth"]=65407,
+ ["soliduslongoverlaycmb"]=824,
+ ["solidusshortoverlaycmb"]=823,
+ ["sorusithai"]=3625,
+ ["sosalathai"]=3624,
+ ["sosothai"]=3595,
+ ["sosuathai"]=3626,
+ ["space"]=32,
+ ["spacehackarabic"]=32,
+ ["spade"]=9824,
+ ["spadesuitblack"]=9824,
+ ["spadesuitwhite"]=9828,
+ ["sparen"]=9390,
+ ["squarebelowcmb"]=827,
+ ["squarecc"]=13252,
+ ["squarecm"]=13213,
+ ["squarediagonalcrosshatchfill"]=9641,
+ ["squarehorizontalfill"]=9636,
+ ["squarekg"]=13199,
+ ["squarekm"]=13214,
+ ["squarekmcapital"]=13262,
+ ["squareln"]=13265,
+ ["squarelog"]=13266,
+ ["squaremg"]=13198,
+ ["squaremil"]=13269,
+ ["squaremm"]=13212,
+ ["squaremsquared"]=13217,
+ ["squareorthogonalcrosshatchfill"]=9638,
+ ["squareupperlefttolowerrightfill"]=9639,
+ ["squareupperrighttolowerleftfill"]=9640,
+ ["squareverticalfill"]=9637,
+ ["squarewhitewithsmallblack"]=9635,
+ ["srsquare"]=13275,
+ ["ssabengali"]=2487,
+ ["ssadeva"]=2359,
+ ["ssagujarati"]=2743,
+ ["ssangcieuckorean"]=12617,
+ ["ssanghieuhkorean"]=12677,
+ ["ssangieungkorean"]=12672,
+ ["ssangkiyeokkorean"]=12594,
+ ["ssangnieunkorean"]=12645,
+ ["ssangpieupkorean"]=12611,
+ ["ssangsioskorean"]=12614,
+ ["ssangtikeutkorean"]=12600,
+ ["ssuperior"]=63218,
+ ["sterling"]=163,
+ ["sterlingmonospace"]=65505,
+ ["strokelongoverlaycmb"]=822,
+ ["strokeshortoverlaycmb"]=821,
+ ["subset"]=8834,
+ ["subsetnotequal"]=8842,
+ ["subsetorequal"]=8838,
+ ["succeeds"]=8827,
+ ["suchthat"]=8715,
+ ["suhiragana"]=12377,
+ ["sukatakana"]=12473,
+ ["sukatakanahalfwidth"]=65405,
+ ["sukunarabic"]=1618,
+ ["summation"]=8721,
+ ["sun"]=9788,
+ ["superset"]=8835,
+ ["supersetnotequal"]=8843,
+ ["supersetorequal"]=8839,
+ ["svsquare"]=13276,
+ ["syouwaerasquare"]=13180,
+ ["t"]=116,
+ ["tabengali"]=2468,
+ ["tackdown"]=8868,
+ ["tackleft"]=8867,
+ ["tadeva"]=2340,
+ ["tagujarati"]=2724,
+ ["tagurmukhi"]=2596,
+ ["taharabic"]=1591,
+ ["tahfinalarabic"]=65218,
+ ["tahinitialarabic"]=65219,
+ ["tahiragana"]=12383,
+ ["tahmedialarabic"]=65220,
+ ["taisyouerasquare"]=13181,
+ ["takatakana"]=12479,
+ ["takatakanahalfwidth"]=65408,
+ ["tatweelarabic"]=1600,
+ ["tau"]=964,
+ ["tav"]=1514,
+ ["tavdages"]=64330,
+ ["tavdagesh"]=64330,
+ ["tavdageshhebrew"]=64330,
+ ["tavhebrew"]=1514,
+ ["tbar"]=359,
+ ["tbopomofo"]=12554,
+ ["tcaron"]=357,
+ ["tccurl"]=680,
+ ["tcedilla"]=355,
+ ["tcheharabic"]=1670,
+ ["tchehfinalarabic"]=64379,
+ ["tchehinitialarabic"]=64380,
+ ["tchehmedialarabic"]=64381,
+ ["tchehmeeminitialarabic"]=64380,
+ ["tcircle"]=9443,
+ ["tcircumflexbelow"]=7793,
+ ["tcommaaccent"]=355,
+ ["tdieresis"]=7831,
+ ["tdotaccent"]=7787,
+ ["tdotbelow"]=7789,
+ ["tecyrillic"]=1090,
+ ["tedescendercyrillic"]=1197,
+ ["teharabic"]=1578,
+ ["tehfinalarabic"]=65174,
+ ["tehhahinitialarabic"]=64674,
+ ["tehhahisolatedarabic"]=64524,
+ ["tehinitialarabic"]=65175,
+ ["tehiragana"]=12390,
+ ["tehjeeminitialarabic"]=64673,
+ ["tehjeemisolatedarabic"]=64523,
+ ["tehmarbutaarabic"]=1577,
+ ["tehmarbutafinalarabic"]=65172,
+ ["tehmedialarabic"]=65176,
+ ["tehmeeminitialarabic"]=64676,
+ ["tehmeemisolatedarabic"]=64526,
+ ["tehnoonfinalarabic"]=64627,
+ ["tekatakana"]=12486,
+ ["tekatakanahalfwidth"]=65411,
+ ["telephone"]=8481,
+ ["telephoneblack"]=9742,
+ ["telishagedolahebrew"]=1440,
+ ["telishaqetanahebrew"]=1449,
+ ["tencircle"]=9321,
+ ["tenideographicparen"]=12841,
+ ["tenparen"]=9341,
+ ["tenperiod"]=9361,
+ ["tenroman"]=8569,
+ ["tesh"]=679,
+ ["tet"]=1496,
+ ["tetdagesh"]=64312,
+ ["tetdageshhebrew"]=64312,
+ ["tethebrew"]=1496,
+ ["tetsecyrillic"]=1205,
+ ["tevirhebrew"]=1435,
+ ["tevirlefthebrew"]=1435,
+ ["thabengali"]=2469,
+ ["thadeva"]=2341,
+ ["thagujarati"]=2725,
+ ["thagurmukhi"]=2597,
+ ["thalarabic"]=1584,
+ ["thalfinalarabic"]=65196,
+ ["thanthakhatlowleftthai"]=63640,
+ ["thanthakhatlowrightthai"]=63639,
+ ["thanthakhatthai"]=3660,
+ ["thanthakhatupperleftthai"]=63638,
+ ["theharabic"]=1579,
+ ["thehfinalarabic"]=65178,
+ ["thehinitialarabic"]=65179,
+ ["thehmedialarabic"]=65180,
+ ["thereexists"]=8707,
+ ["therefore"]=8756,
+ ["theta"]=952,
+ ["theta1"]=977,
+ ["thetasymbolgreek"]=977,
+ ["thieuthacirclekorean"]=12921,
+ ["thieuthaparenkorean"]=12825,
+ ["thieuthcirclekorean"]=12907,
+ ["thieuthkorean"]=12620,
+ ["thieuthparenkorean"]=12811,
+ ["thirteencircle"]=9324,
+ ["thirteenparen"]=9344,
+ ["thirteenperiod"]=9364,
+ ["thonangmonthothai"]=3601,
+ ["thook"]=429,
+ ["thophuthaothai"]=3602,
+ ["thorn"]=254,
+ ["thothahanthai"]=3607,
+ ["thothanthai"]=3600,
+ ["thothongthai"]=3608,
+ ["thothungthai"]=3606,
+ ["thousandcyrillic"]=1154,
+ ["thousandsseparatorarabic"]=1644,
+ ["thousandsseparatorpersian"]=1644,
+ ["three"]=51,
+ ["threearabic"]=1635,
+ ["threebengali"]=2537,
+ ["threecircle"]=9314,
+ ["threecircleinversesansserif"]=10124,
+ ["threedeva"]=2409,
+ ["threeeighths"]=8540,
+ ["threegujarati"]=2793,
+ ["threegurmukhi"]=2665,
+ ["threehackarabic"]=1635,
+ ["threehangzhou"]=12323,
+ ["threeideographicparen"]=12834,
+ ["threeinferior"]=8323,
+ ["threemonospace"]=65299,
+ ["threenumeratorbengali"]=2550,
+ ["threeoldstyle"]=63283,
+ ["threeparen"]=9334,
+ ["threeperiod"]=9354,
+ ["threepersian"]=1779,
+ ["threequarters"]=190,
+ ["threequartersemdash"]=63198,
+ ["threeroman"]=8562,
+ ["threesuperior"]=179,
+ ["threethai"]=3667,
+ ["thzsquare"]=13204,
+ ["tihiragana"]=12385,
+ ["tikatakana"]=12481,
+ ["tikatakanahalfwidth"]=65409,
+ ["tikeutacirclekorean"]=12912,
+ ["tikeutaparenkorean"]=12816,
+ ["tikeutcirclekorean"]=12898,
+ ["tikeutkorean"]=12599,
+ ["tikeutparenkorean"]=12802,
+ ["tilde"]=732,
+ ["tildebelowcmb"]=816,
+ ["tildecmb"]=771,
+ ["tildecomb"]=771,
+ ["tildedoublecmb"]=864,
+ ["tildeoperator"]=8764,
+ ["tildeoverlaycmb"]=820,
+ ["tildeverticalcmb"]=830,
+ ["timescircle"]=8855,
+ ["tipehahebrew"]=1430,
+ ["tipehalefthebrew"]=1430,
+ ["tippigurmukhi"]=2672,
+ ["titlocyrilliccmb"]=1155,
+ ["tiwnarmenian"]=1407,
+ ["tlinebelow"]=7791,
+ ["tmonospace"]=65364,
+ ["toarmenian"]=1385,
+ ["tohiragana"]=12392,
+ ["tokatakana"]=12488,
+ ["tokatakanahalfwidth"]=65412,
+ ["tonebarextrahighmod"]=741,
+ ["tonebarextralowmod"]=745,
+ ["tonebarhighmod"]=742,
+ ["tonebarlowmod"]=744,
+ ["tonebarmidmod"]=743,
+ ["tonefive"]=445,
+ ["tonesix"]=389,
+ ["tonetwo"]=424,
+ ["tonos"]=900,
+ ["tonsquare"]=13095,
+ ["topatakthai"]=3599,
+ ["tortoiseshellbracketleft"]=12308,
+ ["tortoiseshellbracketleftsmall"]=65117,
+ ["tortoiseshellbracketleftvertical"]=65081,
+ ["tortoiseshellbracketright"]=12309,
+ ["tortoiseshellbracketrightsmall"]=65118,
+ ["tortoiseshellbracketrightvertical"]=65082,
+ ["totaothai"]=3605,
+ ["tpalatalhook"]=427,
+ ["tparen"]=9391,
+ ["trademark"]=8482,
+ ["trademarksans"]=63722,
+ ["trademarkserif"]=63195,
+ ["tretroflexhook"]=648,
+ ["triagdn"]=9660,
+ ["triaglf"]=9668,
+ ["triagrt"]=9658,
+ ["triagup"]=9650,
+ ["ts"]=678,
+ ["tsadi"]=1510,
+ ["tsadidagesh"]=64326,
+ ["tsadidageshhebrew"]=64326,
+ ["tsadihebrew"]=1510,
+ ["tsecyrillic"]=1094,
+ ["tsere"]=1461,
+ ["tsere12"]=1461,
+ ["tsere1e"]=1461,
+ ["tsere2b"]=1461,
+ ["tserehebrew"]=1461,
+ ["tserenarrowhebrew"]=1461,
+ ["tserequarterhebrew"]=1461,
+ ["tserewidehebrew"]=1461,
+ ["tshecyrillic"]=1115,
+ ["tsuperior"]=63219,
+ ["ttabengali"]=2463,
+ ["ttadeva"]=2335,
+ ["ttagujarati"]=2719,
+ ["ttagurmukhi"]=2591,
+ ["tteharabic"]=1657,
+ ["ttehfinalarabic"]=64359,
+ ["ttehinitialarabic"]=64360,
+ ["ttehmedialarabic"]=64361,
+ ["tthabengali"]=2464,
+ ["tthadeva"]=2336,
+ ["tthagujarati"]=2720,
+ ["tthagurmukhi"]=2592,
+ ["tturned"]=647,
+ ["tuhiragana"]=12388,
+ ["tukatakana"]=12484,
+ ["tukatakanahalfwidth"]=65410,
+ ["tusmallhiragana"]=12387,
+ ["tusmallkatakana"]=12483,
+ ["tusmallkatakanahalfwidth"]=65391,
+ ["twelvecircle"]=9323,
+ ["twelveparen"]=9343,
+ ["twelveperiod"]=9363,
+ ["twelveroman"]=8571,
+ ["twentycircle"]=9331,
+ ["twentyhangzhou"]=21316,
+ ["twentyparen"]=9351,
+ ["twentyperiod"]=9371,
+ ["two"]=50,
+ ["twoarabic"]=1634,
+ ["twobengali"]=2536,
+ ["twocircle"]=9313,
+ ["twocircleinversesansserif"]=10123,
+ ["twodeva"]=2408,
+ ["twodotenleader"]=8229,
+ ["twodotleader"]=8229,
+ ["twodotleadervertical"]=65072,
+ ["twogujarati"]=2792,
+ ["twogurmukhi"]=2664,
+ ["twohackarabic"]=1634,
+ ["twohangzhou"]=12322,
+ ["twoideographicparen"]=12833,
+ ["twoinferior"]=8322,
+ ["twomonospace"]=65298,
+ ["twonumeratorbengali"]=2549,
+ ["twooldstyle"]=63282,
+ ["twoparen"]=9333,
+ ["twoperiod"]=9353,
+ ["twopersian"]=1778,
+ ["tworoman"]=8561,
+ ["twostroke"]=443,
+ ["twosuperior"]=178,
+ ["twothai"]=3666,
+ ["twothirds"]=8532,
+ ["u"]=117,
+ ["uacute"]=250,
+ ["ubar"]=649,
+ ["ubengali"]=2441,
+ ["ubopomofo"]=12584,
+ ["ubreve"]=365,
+ ["ucaron"]=468,
+ ["ucircle"]=9444,
+ ["ucircumflex"]=251,
+ ["ucircumflexbelow"]=7799,
+ ["ucyrillic"]=1091,
+ ["udattadeva"]=2385,
+ ["udblacute"]=369,
+ ["udblgrave"]=533,
+ ["udeva"]=2313,
+ ["udieresis"]=252,
+ ["udieresisacute"]=472,
+ ["udieresisbelow"]=7795,
+ ["udieresiscaron"]=474,
+ ["udieresiscyrillic"]=1265,
+ ["udieresisgrave"]=476,
+ ["udieresismacron"]=470,
+ ["udotbelow"]=7909,
+ ["ugrave"]=249,
+ ["ugujarati"]=2697,
+ ["ugurmukhi"]=2569,
+ ["uhiragana"]=12358,
+ ["uhookabove"]=7911,
+ ["uhorn"]=432,
+ ["uhornacute"]=7913,
+ ["uhorndotbelow"]=7921,
+ ["uhorngrave"]=7915,
+ ["uhornhookabove"]=7917,
+ ["uhorntilde"]=7919,
+ ["uhungarumlaut"]=369,
+ ["uhungarumlautcyrillic"]=1267,
+ ["uinvertedbreve"]=535,
+ ["ukatakana"]=12454,
+ ["ukatakanahalfwidth"]=65395,
+ ["ukcyrillic"]=1145,
+ ["ukorean"]=12636,
+ ["umacron"]=363,
+ ["umacroncyrillic"]=1263,
+ ["umacrondieresis"]=7803,
+ ["umatragurmukhi"]=2625,
+ ["umonospace"]=65365,
+ ["underscore"]=95,
+ ["underscoredbl"]=8215,
+ ["underscoremonospace"]=65343,
+ ["underscorevertical"]=65075,
+ ["underscorewavy"]=65103,
+ ["union"]=8746,
+ ["universal"]=8704,
+ ["uogonek"]=371,
+ ["uparen"]=9392,
+ ["upblock"]=9600,
+ ["upperdothebrew"]=1476,
+ ["upsilon"]=965,
+ ["upsilondieresis"]=971,
+ ["upsilondieresistonos"]=944,
+ ["upsilonlatin"]=650,
+ ["upsilontonos"]=973,
+ ["uptackbelowcmb"]=797,
+ ["uptackmod"]=724,
+ ["uragurmukhi"]=2675,
+ ["uring"]=367,
+ ["ushortcyrillic"]=1118,
+ ["usmallhiragana"]=12357,
+ ["usmallkatakana"]=12453,
+ ["usmallkatakanahalfwidth"]=65385,
+ ["ustraightcyrillic"]=1199,
+ ["ustraightstrokecyrillic"]=1201,
+ ["utilde"]=361,
+ ["utildeacute"]=7801,
+ ["utildebelow"]=7797,
+ ["uubengali"]=2442,
+ ["uudeva"]=2314,
+ ["uugujarati"]=2698,
+ ["uugurmukhi"]=2570,
+ ["uumatragurmukhi"]=2626,
+ ["uuvowelsignbengali"]=2498,
+ ["uuvowelsigndeva"]=2370,
+ ["uuvowelsigngujarati"]=2754,
+ ["uvowelsignbengali"]=2497,
+ ["uvowelsigndeva"]=2369,
+ ["uvowelsigngujarati"]=2753,
+ ["v"]=118,
+ ["vadeva"]=2357,
+ ["vagujarati"]=2741,
+ ["vagurmukhi"]=2613,
+ ["vakatakana"]=12535,
+ ["vav"]=1493,
+ ["vavdagesh"]=64309,
+ ["vavdagesh65"]=64309,
+ ["vavdageshhebrew"]=64309,
+ ["vavhebrew"]=1493,
+ ["vavholam"]=64331,
+ ["vavholamhebrew"]=64331,
+ ["vavvavhebrew"]=1520,
+ ["vavyodhebrew"]=1521,
+ ["vcircle"]=9445,
+ ["vdotbelow"]=7807,
+ ["vecyrillic"]=1074,
+ ["veharabic"]=1700,
+ ["vehfinalarabic"]=64363,
+ ["vehinitialarabic"]=64364,
+ ["vehmedialarabic"]=64365,
+ ["vekatakana"]=12537,
+ ["venus"]=9792,
+ ["verticalbar"]=124,
+ ["verticallineabovecmb"]=781,
+ ["verticallinebelowcmb"]=809,
+ ["verticallinelowmod"]=716,
+ ["verticallinemod"]=712,
+ ["vewarmenian"]=1406,
+ ["vhook"]=651,
+ ["vikatakana"]=12536,
+ ["viramabengali"]=2509,
+ ["viramadeva"]=2381,
+ ["viramagujarati"]=2765,
+ ["visargabengali"]=2435,
+ ["visargadeva"]=2307,
+ ["visargagujarati"]=2691,
+ ["vmonospace"]=65366,
+ ["voarmenian"]=1400,
+ ["voicediterationhiragana"]=12446,
+ ["voicediterationkatakana"]=12542,
+ ["voicedmarkkana"]=12443,
+ ["voicedmarkkanahalfwidth"]=65438,
+ ["vokatakana"]=12538,
+ ["vparen"]=9393,
+ ["vtilde"]=7805,
+ ["vturned"]=652,
+ ["vuhiragana"]=12436,
+ ["vukatakana"]=12532,
+ ["w"]=119,
+ ["wacute"]=7811,
+ ["waekorean"]=12633,
+ ["wahiragana"]=12431,
+ ["wakatakana"]=12527,
+ ["wakatakanahalfwidth"]=65436,
+ ["wakorean"]=12632,
+ ["wasmallhiragana"]=12430,
+ ["wasmallkatakana"]=12526,
+ ["wattosquare"]=13143,
+ ["wavedash"]=12316,
+ ["wavyunderscorevertical"]=65076,
+ ["wawarabic"]=1608,
+ ["wawfinalarabic"]=65262,
+ ["wawhamzaabovearabic"]=1572,
+ ["wawhamzaabovefinalarabic"]=65158,
+ ["wbsquare"]=13277,
+ ["wcircle"]=9446,
+ ["wcircumflex"]=373,
+ ["wdieresis"]=7813,
+ ["wdotaccent"]=7815,
+ ["wdotbelow"]=7817,
+ ["wehiragana"]=12433,
+ ["weierstrass"]=8472,
+ ["wekatakana"]=12529,
+ ["wekorean"]=12638,
+ ["weokorean"]=12637,
+ ["wgrave"]=7809,
+ ["whitebullet"]=9702,
+ ["whitecircle"]=9675,
+ ["whitecircleinverse"]=9689,
+ ["whitecornerbracketleft"]=12302,
+ ["whitecornerbracketleftvertical"]=65091,
+ ["whitecornerbracketright"]=12303,
+ ["whitecornerbracketrightvertical"]=65092,
+ ["whitediamond"]=9671,
+ ["whitediamondcontainingblacksmalldiamond"]=9672,
+ ["whitedownpointingsmalltriangle"]=9663,
+ ["whitedownpointingtriangle"]=9661,
+ ["whiteleftpointingsmalltriangle"]=9667,
+ ["whiteleftpointingtriangle"]=9665,
+ ["whitelenticularbracketleft"]=12310,
+ ["whitelenticularbracketright"]=12311,
+ ["whiterightpointingsmalltriangle"]=9657,
+ ["whiterightpointingtriangle"]=9655,
+ ["whitesmallsquare"]=9643,
+ ["whitesmilingface"]=9786,
+ ["whitesquare"]=9633,
+ ["whitestar"]=9734,
+ ["whitetelephone"]=9743,
+ ["whitetortoiseshellbracketleft"]=12312,
+ ["whitetortoiseshellbracketright"]=12313,
+ ["whiteuppointingsmalltriangle"]=9653,
+ ["whiteuppointingtriangle"]=9651,
+ ["wihiragana"]=12432,
+ ["wikatakana"]=12528,
+ ["wikorean"]=12639,
+ ["wmonospace"]=65367,
+ ["wohiragana"]=12434,
+ ["wokatakana"]=12530,
+ ["wokatakanahalfwidth"]=65382,
+ ["won"]=8361,
+ ["wonmonospace"]=65510,
+ ["wowaenthai"]=3623,
+ ["wparen"]=9394,
+ ["wring"]=7832,
+ ["wsuperior"]=695,
+ ["wturned"]=653,
+ ["wynn"]=447,
+ ["x"]=120,
+ ["xabovecmb"]=829,
+ ["xbopomofo"]=12562,
+ ["xcircle"]=9447,
+ ["xdieresis"]=7821,
+ ["xdotaccent"]=7819,
+ ["xeharmenian"]=1389,
+ ["xi"]=958,
+ ["xmonospace"]=65368,
+ ["xparen"]=9395,
+ ["xsuperior"]=739,
+ ["y"]=121,
+ ["yaadosquare"]=13134,
+ ["yabengali"]=2479,
+ ["yacute"]=253,
+ ["yadeva"]=2351,
+ ["yaekorean"]=12626,
+ ["yagujarati"]=2735,
+ ["yagurmukhi"]=2607,
+ ["yahiragana"]=12420,
+ ["yakatakana"]=12516,
+ ["yakatakanahalfwidth"]=65428,
+ ["yakorean"]=12625,
+ ["yamakkanthai"]=3662,
+ ["yasmallhiragana"]=12419,
+ ["yasmallkatakana"]=12515,
+ ["yasmallkatakanahalfwidth"]=65388,
+ ["yatcyrillic"]=1123,
+ ["ycircle"]=9448,
+ ["ycircumflex"]=375,
+ ["ydieresis"]=255,
+ ["ydotaccent"]=7823,
+ ["ydotbelow"]=7925,
+ ["yeharabic"]=1610,
+ ["yehbarreearabic"]=1746,
+ ["yehbarreefinalarabic"]=64431,
+ ["yehfinalarabic"]=65266,
+ ["yehhamzaabovearabic"]=1574,
+ ["yehhamzaabovefinalarabic"]=65162,
+ ["yehhamzaaboveinitialarabic"]=65163,
+ ["yehhamzaabovemedialarabic"]=65164,
+ ["yehinitialarabic"]=65267,
+ ["yehmedialarabic"]=65268,
+ ["yehmeeminitialarabic"]=64733,
+ ["yehmeemisolatedarabic"]=64600,
+ ["yehnoonfinalarabic"]=64660,
+ ["yehthreedotsbelowarabic"]=1745,
+ ["yekorean"]=12630,
+ ["yen"]=165,
+ ["yenmonospace"]=65509,
+ ["yeokorean"]=12629,
+ ["yeorinhieuhkorean"]=12678,
+ ["yerahbenyomohebrew"]=1450,
+ ["yerahbenyomolefthebrew"]=1450,
+ ["yericyrillic"]=1099,
+ ["yerudieresiscyrillic"]=1273,
+ ["yesieungkorean"]=12673,
+ ["yesieungpansioskorean"]=12675,
+ ["yesieungsioskorean"]=12674,
+ ["yetivhebrew"]=1434,
+ ["ygrave"]=7923,
+ ["yhook"]=436,
+ ["yhookabove"]=7927,
+ ["yiarmenian"]=1397,
+ ["yicyrillic"]=1111,
+ ["yikorean"]=12642,
+ ["yinyang"]=9775,
+ ["yiwnarmenian"]=1410,
+ ["ymonospace"]=65369,
+ ["yod"]=1497,
+ ["yoddagesh"]=64313,
+ ["yoddageshhebrew"]=64313,
+ ["yodhebrew"]=1497,
+ ["yodyodhebrew"]=1522,
+ ["yodyodpatahhebrew"]=64287,
+ ["yohiragana"]=12424,
+ ["yoikorean"]=12681,
+ ["yokatakana"]=12520,
+ ["yokatakanahalfwidth"]=65430,
+ ["yokorean"]=12635,
+ ["yosmallhiragana"]=12423,
+ ["yosmallkatakana"]=12519,
+ ["yosmallkatakanahalfwidth"]=65390,
+ ["yotgreek"]=1011,
+ ["yoyaekorean"]=12680,
+ ["yoyakorean"]=12679,
+ ["yoyakthai"]=3618,
+ ["yoyingthai"]=3597,
+ ["yparen"]=9396,
+ ["ypogegrammeni"]=890,
+ ["ypogegrammenigreekcmb"]=837,
+ ["yr"]=422,
+ ["yring"]=7833,
+ ["ysuperior"]=696,
+ ["ytilde"]=7929,
+ ["yturned"]=654,
+ ["yuhiragana"]=12422,
+ ["yuikorean"]=12684,
+ ["yukatakana"]=12518,
+ ["yukatakanahalfwidth"]=65429,
+ ["yukorean"]=12640,
+ ["yusbigcyrillic"]=1131,
+ ["yusbigiotifiedcyrillic"]=1133,
+ ["yuslittlecyrillic"]=1127,
+ ["yuslittleiotifiedcyrillic"]=1129,
+ ["yusmallhiragana"]=12421,
+ ["yusmallkatakana"]=12517,
+ ["yusmallkatakanahalfwidth"]=65389,
+ ["yuyekorean"]=12683,
+ ["yuyeokorean"]=12682,
+ ["yyabengali"]=2527,
+ ["yyadeva"]=2399,
+ ["z"]=122,
+ ["zaarmenian"]=1382,
+ ["zacute"]=378,
+ ["zadeva"]=2395,
+ ["zagurmukhi"]=2651,
+ ["zaharabic"]=1592,
+ ["zahfinalarabic"]=65222,
+ ["zahinitialarabic"]=65223,
+ ["zahiragana"]=12374,
+ ["zahmedialarabic"]=65224,
+ ["zainarabic"]=1586,
+ ["zainfinalarabic"]=65200,
+ ["zakatakana"]=12470,
+ ["zaqefgadolhebrew"]=1429,
+ ["zaqefqatanhebrew"]=1428,
+ ["zarqahebrew"]=1432,
+ ["zayin"]=1494,
+ ["zayindagesh"]=64310,
+ ["zayindageshhebrew"]=64310,
+ ["zayinhebrew"]=1494,
+ ["zbopomofo"]=12567,
+ ["zcaron"]=382,
+ ["zcircle"]=9449,
+ ["zcircumflex"]=7825,
+ ["zcurl"]=657,
+ ["zdot"]=380,
+ ["zdotaccent"]=380,
+ ["zdotbelow"]=7827,
+ ["zecyrillic"]=1079,
+ ["zedescendercyrillic"]=1177,
+ ["zedieresiscyrillic"]=1247,
+ ["zehiragana"]=12380,
+ ["zekatakana"]=12476,
+ ["zero"]=48,
+ ["zeroarabic"]=1632,
+ ["zerobengali"]=2534,
+ ["zerodeva"]=2406,
+ ["zerogujarati"]=2790,
+ ["zerogurmukhi"]=2662,
+ ["zerohackarabic"]=1632,
+ ["zeroinferior"]=8320,
+ ["zeromonospace"]=65296,
+ ["zerooldstyle"]=63280,
+ ["zeropersian"]=1776,
+ ["zerosuperior"]=8304,
+ ["zerothai"]=3664,
+ ["zerowidthjoiner"]=65279,
+ ["zerowidthnonjoiner"]=8204,
+ ["zerowidthspace"]=8203,
+ ["zeta"]=950,
+ ["zhbopomofo"]=12563,
+ ["zhearmenian"]=1386,
+ ["zhebrevecyrillic"]=1218,
+ ["zhecyrillic"]=1078,
+ ["zhedescendercyrillic"]=1175,
+ ["zhedieresiscyrillic"]=1245,
+ ["zihiragana"]=12376,
+ ["zikatakana"]=12472,
+ ["zinorhebrew"]=1454,
+ ["zlinebelow"]=7829,
+ ["zmonospace"]=65370,
+ ["zohiragana"]=12382,
+ ["zokatakana"]=12478,
+ ["zparen"]=9397,
+ ["zretroflexhook"]=656,
+ ["zstroke"]=438,
+ ["zuhiragana"]=12378,
+ ["zukatakana"]=12474,
+}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-init.lua b/macros/luatex/generic/luaotfload/luaotfload-init.lua
new file mode 100644
index 0000000000..9c932892f4
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-init.lua
@@ -0,0 +1,781 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-init.lua
+-- DESCRIPTION: part of luaotfload / font loader initialization
+-- REQUIREMENTS: luatex v.0.80 or later; packages lualibs
+-- AUTHOR: Philipp Gesang (Phg), <phg@phi-gamma.net>, Marcel Krüger
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-init",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / initialization",
+ license = "GPL v2.0"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+-----------------------------------------------------------------------
+
+
+local setmetatable = setmetatable
+local kpsefind_file = kpse.find_file
+local lfsisdir = lfs.isdir
+
+--[[doc--
+
+ Initialization phases:
+
+ - Load Lualibs from package
+ - Set up the logger routines
+ - Load Fontloader
+ - as package specified in configuration
+ - from Context install
+ - (optional: from raw unpackaged files distributed with
+ Luaotfload)
+
+ The initialization of the Lualibs may be made configurable in the
+ future as well allowing to load both the files and the merged package
+ depending on a configuration setting. However, this would require
+ separating out the configuration parser into a self-contained
+ package, which might be problematic due to its current dependency on
+ the Lualibs itself.
+
+--doc]]--
+
+local log --- filled in after loading the log module
+local logreport --- filled in after loading the log module
+
+--[[doc--
+
+ \subsection{Preparing the Font Loader}
+ We treat the fontloader as a semi-black box so behavior is
+ consistent between formats.
+ We load the fontloader code directly in the same fashion as the
+ Plain format \identifier{luatex-fonts} that is part of Context.
+ How this is executed depends on the presence on the
+ \emphasis{merged font loader code}.
+ In \identifier{luaotfload} this is contained in the file
+ \fileent{luaotfload-merged.lua}.
+ If this file cannot be found, the original libraries from \CONTEXT
+ of which the merged code was composed are loaded instead.
+ Since these files are not shipped with Luaotfload, an installation
+ of Context is required.
+ (Since we pull the fontloader directly from the Context minimals,
+ the necessary Context version is likely to be more recent than that
+ of other TeX distributions like Texlive.)
+ The imported font loader will call \luafunction{callback.register}
+ once while reading \fileent{font-def.lua}.
+ This is unavoidable unless we modify the imported files, but
+ harmless if we make it call a dummy instead.
+ However, this problem might vanish if we decide to do the merging
+ ourselves, like the \identifier{lualibs} package does.
+ With this step we would obtain the freedom to load our own
+ overrides in the process right where they are needed, at the cost
+ of losing encapsulation.
+ The decision on how to progress is currently on indefinite hold.
+
+--doc]]--
+
+local init_early = function ()
+
+ local store = { }
+ config = config or { } --- global
+ config.luaotfload = config.luaotfload or { }
+ config.lualibs = config.lualibs or { }
+ config.lualibs.verbose = false
+ config.lualibs.prefer_merged = true
+ config.lualibs.load_extended = true
+ fonts = fonts or { }
+
+ require "lualibs"
+
+ if not lualibs then error "this module requires Luaotfload" end
+ if not luaotfload then error "this module requires Luaotfload" end
+
+ --[[doc--
+
+ The logger needs to be in place prior to loading the fontloader due
+ to order of initialization being crucial for the logger functions
+ that are swapped.
+
+ --doc]]--
+
+ luaotfload.loaders.luaotfload "log"
+ log = luaotfload.log
+ logreport = log.report
+ log.set_loglevel (default_log_level)
+
+ logreport ("log", 4, "init", "Concealing callback.register().")
+ store.trapped_register = callback.register
+
+ callback.register = function (id)
+ logreport ("log", 4, "init",
+ "Dummy callback.register() invoked on %s.",
+ id)
+ end
+
+ --[[doc--
+
+ By default, the fontloader requires a number of \emphasis{private
+ attributes} for internal use.
+ These must be kept consistent with the attribute handling methods
+ as provided by \identifier{luatexbase}.
+ Our strategy is to override the function that allocates new
+ attributes before we initialize the font loader, making it a
+ wrapper around \luafunction{luatexbase.new_attribute}.\footnote{%
+ Many thanks, again, to Hans Hagen for making this part
+ configurable!
+ }
+ The attribute identifiers are prefixed “\fileent{luaotfload@}†to
+ avoid name clashes.
+
+ --doc]]--
+
+ local new_attribute = luatexbase.new_attribute
+ local the_attributes = luatexbase.attributes
+
+ attributes = attributes or { } --- this writes a global, sorry
+
+ attributes.private = function (name)
+ local attr = "luaotfload@" .. name --- used to be: “otfl@â€
+ local number = the_attributes[attr]
+ if not number then number = new_attribute(attr) end
+ return number
+ end
+
+ luaotfload.loaders.fontloader "basics-gen"
+
+ return store
+end --- [init_early]
+
+--[[doc--
+
+ These next lines replicate the behavior of
+ \fileent{luatex-fonts.lua}.
+
+--doc]]--
+
+local push_namespaces = function ()
+ logreport ("log", 4, "init", "push namespace for font loader")
+ local normalglobal = { }
+ for k, v in next, _G do
+ normalglobal[k] = v
+ end
+ return normalglobal
+end
+
+local pop_namespaces = function (normalglobal,
+ isolate,
+ context_environment)
+ if normalglobal then
+ local _G = _G
+ local mode = "non-destructive"
+ if isolate then mode = "destructive" end
+ logreport ("log", 4, "init", "pop namespace from font loader -- " .. mode)
+ for k, v in next, _G do
+ if not normalglobal[k] then
+ context_environment[k] = v
+ if isolate then
+ _G[k] = nil
+ end
+ end
+ end
+ for k, v in next, normalglobal do
+ _G[k] = v
+ end
+ -- just to be sure:
+ setmetatable(context_environment, _G)
+ else
+ logreport ("both", 0, "init",
+ "irrecoverable error during pop_namespace: no globals to restore")
+ os.exit ()
+ end
+end
+
+--- below paths are relative to the texmf-context
+local ltx = "tex/generic/context/luatex"
+local ctx = { "tex/context/base/mkiv", "tex/context/base" }
+
+local context_modules = {
+
+ --- Since 2.6 those are directly provided by the Lualibs package.
+ { false, "l-lua" },
+ { false, "l-lpeg" },
+ { false, "l-function" },
+ { false, "l-string" },
+ { false, "l-table" },
+ { false, "l-io" },
+ { false, "l-file" },
+ { false, "l-boolean" },
+ { false, "l-math" },
+ { false, "l-unicode" }, -- NEW UF 19.09.2018
+ { false, "util-str" },
+ { false, "util-fil" },
+
+ --- These constitute the fontloader proper.
+ { ltx, "luatex-basics-gen" },
+ { ctx, "data-con" },
+ { ltx, "luatex-basics-nod" },
+ { ltx, "luatex-basics-chr" }, -- NEW UF 14.12.2018
+ { ctx, "font-ini" },
+ { ltx, "luatex-fonts-mis" }, -- NEW UF 19.09.2018
+ { ctx, "font-con" },
+ { ltx, "luatex-fonts-enc" },
+ { ctx, "font-cid" },
+ { ctx, "font-map" },
+-- { ltx, "luatex-fonts-syn" }, -- ignore??
+ { ctx, "font-vfc" }, -- NEW UF 19.09.2018
+ { ctx, "font-oti" },
+ { ctx, "font-otr" },
+ { ctx, "font-ott" },
+ { ctx, "font-cff" },
+ { ctx, "font-ttf" },
+ { ctx, "font-dsp" },
+ { ctx, "font-oup" },
+ { ctx, "font-otl" },
+ { ctx, "font-oto" },
+ { ctx, "font-otj" },
+ { ctx, "font-ota" },
+ { ctx, "font-ots" },
+ { ctx, "font-osd" },
+ { ctx, "font-ocl" },
+ { ctx, "font-otc" },
+ { ctx, "font-onr" },
+ { ctx, "font-one" },
+ { ctx, "font-afk" },
+ { ctx, "luatex-fonts-tfm" },
+ { ctx, "font-lua" },
+ { ctx, "font-def" },
+ { ltx, "luatex-fonts-def" },
+ { ltx, "luatex-fonts-ext" },
+ { ctx, "font-imp-tex" },
+ { ctx, "font-imp-ligatures"},
+ { ctx, "font-imp-italics" },
+ { ctx, "font-imp-effects" },
+ { ltx, "luatex-fonts-lig" },
+ { ltx, "luatex-fonts-gbn" },
+
+
+} --[[context_modules]]
+
+local load_context_modules = function (pth)
+
+ local load_module = luaotfload.loaders.context
+ local ignore_module = luaotfload.loaders.ignore
+
+ logreport ("both", 2, "init",
+ "Loading fontloader components from context.")
+ local n = #context_modules
+ for i = 1, n do
+ local sub, spec = unpack (context_modules [i])
+ if sub == false then
+ ignore_module (spec)
+ else
+ local tsub = type (sub)
+ if not pth then
+ load_module (spec)
+ elseif tsub == "string" then
+ load_module (spec, file.join (pth, sub))
+ elseif tsub == "table" then
+ local pfx
+ local nsub = #sub
+ for j = 1, nsub do
+ local full = file.join (pth, sub [j])
+ if lfsisdir (full) then --- pick the first real one
+ pfx = full
+ break
+ end
+ end
+ if pfx then
+ load_module (spec, pfx)
+ else
+ logreport ("both", 0, "init",
+ "None of the %d search paths for module %q exist; \z
+ falling back to default path.",
+ nsub, tostring (spec))
+ load_module (spec) --- maybe we’ll get by after all?
+ end
+ else
+ logreport ("both", 0, "init",
+ "Internal error, please report. \z
+ This is not your fault.")
+ os.exit (-1)
+ end
+ end
+ end
+
+end
+
+local init_adapt = function ()
+
+ local context_environment = { }
+ local our_environment = push_namespaces ()
+
+ --[[doc--
+
+ The font loader requires that the attribute with index zero be
+ zero. We happily oblige.
+ (Cf. \fileent{luatex-fonts-nod.lua}.)
+
+ --doc]]--
+
+ tex.attribute[0] = 0
+
+ return our_environment, context_environment
+
+end --- [init_adapt]
+
+--[[doc--
+
+ In Context, characters.data is where the data from char-def.lua
+ resides. The file is huge (>4.4 MB as of 2016) and only a stripped
+ down version is part of the isolated font loader. Nevertheless, we
+ include an excerpt generated by the mkcharacters script that contains
+ a subset of the fields of each character defined and some extra
+ metadata.
+
+ Currently, these are (compare the mkcharacters script!)
+
+ · "direction"
+ · "mirror"
+ · "category"
+ · "textclass"
+
+ The directional information is required for packages like Simurgh [0]
+ to work correctly. In an early stage [1] it was necessary to load
+ further files from Context directly, including the full blown version
+ of char-def. Since we have no use for most of the so imported
+ functionality, the required parts have been isolated and are now
+ instated along with luaotfload-characters.lua. We can extend the set
+ of imported features easily should it not be enough.
+
+ [0] https://github.com/persian-tex/simurgh
+ [1] http://tex.stackexchange.com/a/132301/14066
+
+--doc]]--
+
+--[[--14.12.2018disable characters
+--characters = characters or { } --- should be created in basics-gen
+--characters.data = nil
+--local chardef = "luaotfload-characters"
+--
+--do
+-- local setmetatableindex = function (t, f)
+-- local mt = getmetatable (t)
+-- if mt then
+-- mt.__index = f
+-- else
+-- setmetatable (t, { __index = f })
+-- end
+-- end
+--
+-- --- there are some special tables for each field that provide access
+-- --- to fields of the character table by means of a metatable
+--
+-- local mkcharspecial = function (characters, tablename, field)
+--
+-- local chardata = characters.data
+--
+-- if chardata then
+-- local newspecial = { }
+-- characters [tablename] = newspecial --> e.g. “characters.data.mirrorsâ€
+--
+-- local idx = function (t, char)
+-- local c = chardata [char]
+-- if c then
+-- local m = c [field] --> e.g. “mirrorâ€
+-- if m then
+-- t [char] = m
+-- return m
+-- end
+-- end
+-- newspecial [char] = false
+-- return char
+-- end
+--
+-- setmetatableindex (newspecial, idx)
+-- end
+--
+-- end
+--
+-- local mkcategories = function (characters) -- different from the others
+--
+-- local chardata = characters.data
+-- local categories = characters.categories or { }
+-- characters.categories = categories
+--
+-- setmetatable (categories, { __index = function (t, char)
+-- if char then
+-- local c = chardata [char]
+-- c = c.category or char
+-- t [char] = c
+-- return c
+-- end
+-- end})
+--
+-- end
+--
+-- local load_failed = false
+-- local chardata --> characters.data; loaded on demand
+--
+-- local load_chardef = function ()
+--
+-- logreport ("both", 1, "aux", "Loading character metadata from %s.", chardef)
+-- chardata = dofile (kpse.find_file (chardef, "lua"))
+--
+-- if chardata == nil then
+-- logreport ("both", 0, "aux",
+-- "Could not load %s; continuing with empty character table.",
+-- chardef)
+-- chardata = { }
+-- load_failed = true
+-- end
+--
+-- characters = { } --- nuke metatable
+-- characters.data = chardata
+-- characters.classifiers = chardata.classifiers
+-- chardata.classifiers = nil
+--
+-- --- institute some of the functionality from char-ini.lua
+--
+-- mkcharspecial (characters, "mirrors", "mirror")
+-- mkcharspecial (characters, "directions", "direction")
+-- mkcharspecial (characters, "textclasses", "textclass")
+-- mkcategories (characters)
+--
+-- end
+--
+-- local charindex = function (t, k)
+-- if chardata == nil and load_failed ~= true then
+-- load_chardef ()
+-- end
+--
+-- return rawget (characters, k)
+-- end
+--
+-- setmetatableindex (characters, charindex)
+--
+--end
+--]] --14.12.2018disable characters
+
+local init_main = function ()
+
+ local load_fontloader_module = luaotfload.loaders.fontloader
+ local ignore_module = luaotfload.loaders.ignore
+
+ --[[doc--
+
+ Now that things are sorted out we can finally load the
+ fontloader.
+
+ --doc]]--
+
+ local fontloader = config.luaotfload and config.luaotfload.run.fontloader
+ or "reference"
+ fontloader = tostring (fontloader)
+
+ if fontloader == "reference" then
+ logreport ("log", 0, "init", "Using reference fontloader.")
+ load_fontloader_module (luaotfload.fontloader_package)
+
+ elseif fontloader == "default" then
+ --- Same as above but loader name not correctly replaced by the file name
+ --- of our fontloader package. Perhaps something’s wrong with the status
+ --- file which contains the datestamped filename? In any case, it can’t
+ --- hurt reporting it as a bug.
+ logreport ("both", 0, "init", "Fontloader substitution failed, got “defaultâ€.")
+ logreport ("log", 4, "init", "Falling back to reference fontloader.")
+ load_fontloader_module (luaotfload.fontloader_package)
+
+ elseif fontloader == "unpackaged" then
+ logreport ("log", 0, "init",
+ "Loading fontloader components individually.")
+ --- The loading sequence is known to change, so this might have to be
+ --- updated with future updates. Do not modify it though unless there is
+ --- a change to the upstream package!
+
+ --- Since 2.6 those are directly provided by the Lualibs package.
+ ignore_module "l-lua"
+ ignore_module "l-lpeg"
+ ignore_module "l-function"
+ ignore_module "l-string"
+ ignore_module "l-table"
+ ignore_module "l-io"
+ ignore_module "l-file"
+ ignore_module "l-boolean"
+ ignore_module "l-math"
+ ignore_module "util-str"
+ ignore_module "util-fil"
+ ignore_module "luatex-basics-gen"
+
+ load_fontloader_module "data-con"
+ load_fontloader_module "basics-nod"
+ load_fontloader_module "basics-chr"
+ load_fontloader_module "font-ini"
+ load_fontloader_module "fonts-mis"
+ load_fontloader_module "font-con"
+ load_fontloader_module "fonts-enc"
+ load_fontloader_module "font-cid"
+ load_fontloader_module "font-map"
+-- load_fontloader_module "fonts-syn" -- ignore?
+ load_fontloader_module "font-vfc"
+ load_fontloader_module "font-otr"
+ load_fontloader_module "font-oti"
+ load_fontloader_module "font-ott"
+ load_fontloader_module "font-cff"
+ load_fontloader_module "font-ttf"
+ load_fontloader_module "font-dsp"
+ load_fontloader_module "font-oup"
+ load_fontloader_module "font-otl"
+ load_fontloader_module "font-oto"
+ load_fontloader_module "font-otj"
+ load_fontloader_module "font-ota"
+ load_fontloader_module "font-ots"
+ load_fontloader_module "font-osd"
+ load_fontloader_module "font-ocl"
+ load_fontloader_module "font-otc"
+ load_fontloader_module "font-onr"
+ load_fontloader_module "font-one"
+ load_fontloader_module "font-afk"
+ load_fontloader_module "fonts-tfm"
+ load_fontloader_module "font-lua"
+ load_fontloader_module "font-def"
+ load_fontloader_module "fonts-def"
+ load_fontloader_module "fonts-ext"
+ load_fontloader_module "font-imp-tex"
+ load_fontloader_module "font-imp-ligatures"
+ load_fontloader_module "font-imp-italics"
+ load_fontloader_module "font-imp-effects"
+ load_fontloader_module "fonts-lig"
+ load_fontloader_module "fonts-gbn"
+
+ elseif fontloader == "context" then
+ logreport ("log", 0, "init",
+ "Loading Context modules in lookup path.")
+ load_context_modules ()
+
+ elseif lfsisdir (fontloader) then
+ logreport ("log", 0, "init",
+ "Loading Context files under prefix “%sâ€.",
+ fontloader)
+ load_context_modules (fontloader)
+
+ elseif lfs.isfile (fontloader) then
+ logreport ("log", 0, "init",
+ "Loading fontloader from absolute path “%sâ€.",
+ fontloader)
+ local _void = require (fontloader)
+
+ elseif kpsefind_file (fontloader) then
+ local path = kpsefind_file (fontloader)
+ logreport ("log", 0, "init",
+ "Loading fontloader “%s†from kpse-resolved path “%sâ€.",
+ fontloader, path)
+ local _void = require (path)
+
+ elseif kpsefind_file (("fontloader-%s.lua"):format(fontloader)) then
+ logreport ("log", 0, "init",
+ "Using predefined fontloader “%sâ€.",
+ fontloader)
+ load_fontloader_module (fontloader)
+
+ else
+ logreport ("both", 0, "init",
+ "No match for requested fontloader “%sâ€.",
+ fontloader)
+ fontloader = luaotfload.fontloader_package
+ logreport ("both", 0, "init",
+ "Defaulting to predefined fontloader “%sâ€.",
+ fontloader)
+ load_fontloader_module (fontloader)
+ end
+
+ ---load_fontloader_module "font-odv.lua" --- <= Devanagari support from Context
+
+ logreport ("log", 0, "init",
+ "Context OpenType loader version “%sâ€",
+ fonts.handlers.otf.version)
+end --- [init_main]
+
+local init_cleanup = function (store)
+ --- reinstate all the stuff we had to move out of the way to
+ --- accomodate the loader
+
+ --[[doc--
+
+ Here we adjust the globals created during font loader
+ initialization. If the second argument to
+ \luafunction{pop_namespaces()} is \verb|true| this will restore the
+ state of \luafunction{_G}, eliminating every global generated since
+ the last call to \luafunction{push_namespaces()}. At the moment we
+ see no reason to do this, and since the font loader is considered
+ an essential part of \identifier{luatex} as well as a very well
+ organized piece of code, we happily concede it the right to add to
+ \luafunction{_G} if needed.
+
+ --doc]]--
+
+ pop_namespaces (store.our_environment,
+ false,
+ store.context_environment)
+
+ --[[doc--
+
+ \subsection{Callbacks}
+ After the fontloader is ready we can restore the callback trap
+ from \identifier{luatexbase}.
+
+ --doc]]--
+
+ logreport ("log", 4, "init",
+ "Restoring original callback.register().")
+ callback.register = store.trapped_register
+end --- [init_cleanup]
+
+local init_post_install_callbacks = function ()
+ --[[doc--
+
+ we do our own callback handling with the means provided by
+ luatexbase.
+ note: \luafunction{pre_linebreak_filter} and
+ \luafunction{hpack_filter} are coupled in \context in the
+ concept of \emphasis{node processor}.
+
+ --doc]]--
+
+ -- MK Pass current text direction to simple_font_handler
+ local handler = nodes.simple_font_handler
+ local callback = function(head, groupcode, _, _, direction)
+ return handler(head, groupcode, nil, nil, direction or tex.get'textdir')
+ end
+ luatexbase.add_to_callback("pre_linebreak_filter",
+ callback,
+ "luaotfload.node_processor",
+ 1)
+ luatexbase.add_to_callback("hpack_filter",
+ callback,
+ "luaotfload.node_processor",
+ 1)
+ -- /MK
+end
+
+local init_post_load_agl = function ()
+
+ --[[doc--
+
+ Adobe Glyph List.
+ -----------------------------------------------------------------
+
+ Context provides a somewhat different font-age.lua from an
+ unclear origin. Unfortunately, the file name it reads from is
+ hard-coded in font-enc.lua, so we have to replace the entire
+ table.
+
+ This shouldn’t cause any complications. Due to its implementation
+ the glyph list will be loaded upon loading a OTF or TTF for the
+ first time during a TeX run. (If one sticks to TFM/OFM then it is
+ never read at all.) For this reason we can install a metatable
+ that looks up the file of our choosing and only falls back to the
+ Context one in case it cannot be found.
+
+ --doc]]--
+
+ local encodings = fonts.encodings
+
+ if not encodings then
+ --- Might happen during refactoring; we continue graciously but in
+ --- a somewhat defect state.
+ logreport ("log", 0, "init",
+ "preconditions unmet, skipping the Adobe Glyph List; "
+ .. "this is a Luaotfload bug.")
+ return
+ end
+
+ if next (fonts.encodings.agl) then
+ --- unnecessary because the file shouldn’t be loaded at this time
+ --- but we’re just making sure
+ fonts.encodings.agl = nil
+ collectgarbage"collect"
+ end
+
+ local agl_init = { } --- start out empty, fill on demand
+ encodings.agl = agl_init --- ugh, replaced again later
+
+ setmetatable (agl_init, { __index = function (t, k)
+
+ if k ~= "unicodes" then
+ return nil
+ end
+
+ local glyphlist = kpsefind_file "luaotfload-glyphlist.lua"
+ if glyphlist then
+ logreport ("log", 1, "init", "loading the Adobe glyph list")
+ else
+ glyphlist = kpsefind_file "font-age.lua"
+ logreport ("both", 0, "init",
+ "loading the extended glyph list from ConTeXt")
+ end
+
+ if not glyphlist then
+ logreport ("both", 4, "init",
+ "Adobe glyph list not found, please check your installation.")
+ return nil
+ end
+ logreport ("both", 4, "init",
+ "found Adobe glyph list file at ``%s``, using that.",
+ glyphlist)
+
+ local unicodes = dofile(glyphlist)
+ encodings.agl = { unicodes = unicodes }
+ return unicodes
+ end })
+
+end
+
+--- (unit -> unit) list
+local init_post_actions = {
+ init_post_install_callbacks,
+ init_post_load_agl,
+}
+
+--- unit -> size_t
+local init_post = function ()
+ --- hook for actions that need to take place after the fontloader is
+ --- installed
+
+ local n = #init_post_actions
+ for i = 1, n do
+ local action = init_post_actions[i]
+ local taction = type (action)
+ if not action or taction ~= "function" then
+ logreport ("both", 1, "init",
+ "post hook WARNING: action %d not a function but %s/%s; ignoring.",
+ i, action, taction)
+ else
+ --- call closure
+ action ()
+ end
+ end
+
+ return n
+end --- [init_post]
+
+return {
+ early = init_early,
+ main = function (store)
+ local starttime = os.gettimeofday ()
+ store.our_environment, store.context_environment = init_adapt ()
+ init_main ()
+ init_cleanup (store)
+ logreport ("both", 1, "init",
+ "fontloader loaded in %0.3f seconds",
+ os.gettimeofday() - starttime)
+ local n = init_post ()
+ logreport ("both", 5, "init", "post hook terminated, %d actions performed", n)
+ return true
+ end
+}
+
+-- vim:tw=79:sw=2:ts=2:expandtab
diff --git a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
new file mode 100644
index 0000000000..43bfb25a2b
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/luaotfload-latex.tex b/macros/luatex/generic/luaotfload/luaotfload-latex.tex
new file mode 100644
index 0000000000..8a68efd035
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-latex.tex
@@ -0,0 +1,530 @@
+% !Mode:: "TeX:EN:UTF-8:Main"
+\suppresslongerror1%% sigh ...
+%% Copyright (C) 2009-2018
+%%
+%% by Elie Roux <elie.roux@telecom-bretagne.eu>
+%% and Khaled Hosny <khaledhosny@eglug.org>
+%% and Philipp Gesang <phg@phi-gamma.net>
+%%
+%% This file is part of Luaotfload.
+%%
+%% Home: https://github.com/lualatex/luaotfload
+%% Support: <lualatex-dev@tug.org>.
+%%
+%% Luaotfload is under the GPL v2.0 (exactly) license.
+%%
+%% ----------------------------------------------------------------------------
+%%
+%% Luaotfload is free software; you can redistribute it and/or
+%% modify it under the terms of the GNU General Public License
+%% as published by the Free Software Foundation; version 2
+%% of the License.
+%%
+%% Luaotfload is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%% GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with Luaotfload; if not, see <http://www.gnu.org/licenses/>.
+%%
+%% ----------------------------------------------------------------------------
+%%
+
+\documentclass{ltxdoc}
+
+\makeatletter
+
+\usepackage {metalogo,multicol,fancyvrb,xspace}
+\usepackage [x11names] {xcolor}
+
+\def \primarycolor {DodgerBlue4} %%-> rgb 16 78 139 | #104e8b
+\def \secondarycolor {Goldenrod4} %%-> rgb 139 105 200 | #8b6914
+
+\usepackage[
+ bookmarks=true,
+ colorlinks=true,
+ linkcolor=\primarycolor,
+ urlcolor=\secondarycolor,
+ citecolor=\primarycolor,
+ unicode,
+ pdftitle={The Luaotfload package},
+ pdfsubject={OpenType layout system for Plain TeX and LaTeX},
+ pdfauthor={Elie Roux \& Khaled Hosny \& Philipp Gesang \& Ulrike Fischer},
+ pdfkeywords={luatex, lualatex, unicode, opentype}
+]{hyperref}
+
+\usepackage {fontspec}
+\usepackage {unicode-math}
+
+\setmainfont[
+% Numbers = OldStyle, %% buggy with font cache
+ Ligatures = TeX,
+ BoldFont = {Linux Libertine O Bold},
+ ItalicFont = {Linux Libertine O Italic},
+ SlantedFont = {Linux Libertine O Italic},
+]{Linux Libertine O}
+\setmonofont[Ligatures=TeX,Scale=MatchLowercase]{InconsolataN-Regular.otf}
+%setsansfont[Ligatures=TeX]{Linux Biolinum O}
+\setsansfont[Ligatures=TeX,Scale=MatchLowercase]{IwonaMedium-Regular.otf}
+%setmathfont{XITS Math}
+
+\usepackage{hologo}
+
+\newcommand\TEX {\TeX\xspace}
+\newcommand\LUA {Lua\xspace}
+\newcommand\PDFTEX {pdf\TeX\xspace}
+\newcommand\LUATEX {Lua\TeX\xspace}
+\newcommand\XETEX {\XeTeX\xspace}
+\newcommand\LATEX {\LaTeX\xspace}
+\newcommand\LUALATEX {Lua\LaTeX\xspace}
+\newcommand\CONTEXT {Con\TeX t\xspace}
+\newcommand\OpenType {\identifier{Open\kern-.25ex Type}\xspace}
+
+%% \groupedcommand, with some omissions taken from syst-aux.mkiv
+\let \handlegroupnormalbefore \relax
+\let \handlegroupnormalafter \relax
+
+\protected \def \handlegroupnormal #1#2{%
+ \bgroup % 1
+ \def \handlegroupbefore {#1}%
+ \def \handlegroupafter {#2}%
+ \afterassignment \handlegroupnormalbefore
+ \let \next =
+}
+
+\def \handlegroupnormalbefore {%
+ \bgroup % 2
+ \handlegroupbefore
+ \bgroup % 3
+ \aftergroup \handlegroupnormalafter%
+}
+
+\def \handlegroupnormalafter {%
+ \handlegroupafter
+ \egroup % 3
+ \egroup % 2
+}
+
+\let \groupedcommand \handlegroupnormal %% only the two arg version
+
+\def \definehighlight [#1][#2]{%
+ \ifcsname #1\endcsname\else
+ \expandafter\def\csname #1\endcsname{%
+ \leavevmode
+ \groupedcommand {#2}\empty%
+ }
+ \fi%
+}
+
+%% old, simplistic definition: obsolete now that we have
+%% \groupedcommand
+%\def\definehighlight[#1][#2]%
+ %{\ifcsname #1\endcsname\else
+ %\expandafter\def\csname #1\endcsname%
+ %{\bgroup#2\csname #1_indeed\endcsname}
+ %\expandafter\def\csname #1_indeed\endcsname##1%
+ %{##1\egroup}%
+ %\fi}
+
+\def\restoreunderscore{\catcode`\_=12\relax}
+
+\definehighlight [fileent][\ttfamily\restoreunderscore] %% files, dirs
+\definehighlight [texmacro][\sffamily\itshape\textbackslash] %% cs
+\definehighlight [luaident][\sffamily\itshape\restoreunderscore] %% lua identifiers
+\definehighlight [identifier][\sffamily] %% names
+\definehighlight [abbrev][\rmfamily\scshape] %% acronyms
+\definehighlight [emphasis][\rmfamily\slshape] %% level 1 emph
+
+\definehighlight [Largefont][\Large] %% font size
+\definehighlight [smallcaps][\sc] %% font feature
+\definehighlight [nonproportional][\tt] %% font switch
+
+\newcommand*\email[1]{\href{mailto:#1}{#1}}
+
+\renewcommand\partname{Part}%% gets rid of the stupid “file†heading
+
+\usepackage{syntax}%% bnf for font request syntax
+
+\usepackage{titlesec}
+
+\def\movecountertomargin#1{\llap{\rmfamily\upshape#1\hskip2em}}
+\def\zeropoint{0pt}
+\titleformat \part
+ {\normalsize\rmfamily\bfseries}
+ {\movecountertomargin\thepart} \zeropoint {}
+\titleformat \section
+ {\normalsize\rmfamily\scshape}
+ {\movecountertomargin\thesection} \zeropoint {}
+\titleformat \subsection
+ {\small\rmfamily\itshape}
+ {\movecountertomargin\thesubsection} \zeropoint {}
+\titleformat \subsubsection
+ {\normalsize\rmfamily\upshape}
+ {\movecountertomargin\thesubsubsection} \zeropoint {}
+
+\usepackage{tocloft}
+\renewcommand \cftpartfont {\rmfamily\upshape}
+\renewcommand \cftsecfont {\rmfamily\upshape}
+\renewcommand \cftsubsecfont {\rmfamily\upshape}
+\setlength \cftbeforepartskip {1ex}
+\setlength \cftbeforesecskip {1ex}
+
+\VerbatimFootnotes
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% structurals
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def \definestructural #1{%
+ \expandafter \let \csname end#1\endcsname \relax
+
+ \expandafter \def \csname begin#1\endcsname {%
+ \@ifnextchar[{\csname begin#1indeed\endcsname}
+ {\csname begin#1indeed\endcsname[]}%
+ }
+
+ \expandafter \def \csname begin#1indeed\endcsname [##1]##2{%
+ \edef \first {##1}%
+ \ifx \first \empty
+ \csname #1\endcsname [##2]{##2}%
+ \else
+ \csname #1\endcsname [\first]{##2}%
+ \fi
+ }
+}
+
+\definestructural {section}
+\definestructural {subsection}
+\definestructural {subsubsection}
+
+\def \fakesection #1{\section*{#1}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% inline verbatim
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Context offers both \type{…} and \type<<…>>, but not an unbalanced
+%% one that we could map directly onto Latex’s \verb|…|.
+\usepackage{pdfpages}
+\usepackage {listings}
+\usepackage {luatexbase}
+\lstset {
+ basicstyle=\ttfamily,
+}
+
+%\let \inlinecode \lstinline
+\protected \def \inlinecode {\lstinline}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% codelistings; this sucks hard since we lack access to buffers
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newcount \othercatcode \othercatcode 12
+\newcount \activecatcode \othercatcode 13
+
+\newcatcodetable \vrbcatcodes
+\setcatcodetable \vrbcatcodes {%
+ \catcodetable \CatcodeTableIniTeX
+ \catcode 9 \othercatcode %% \tabasciicode
+ \catcode 13 \othercatcode %% \endoflineasciicode
+ \catcode 12 \othercatcode %% \formfeedasciicode
+ \catcode 26 \othercatcode %% \endoffileasciicode
+ \catcode 32 \othercatcode %% \spaceasciicode
+}
+
+\directlua {
+ document = document or { }
+ document.vrbcatcodesidx = tonumber (\the \vrbcatcodes)
+}
+
+\newcatcodetable \literalcatcodes
+\setcatcodetable \literalcatcodes {%
+ \catcodetable \CatcodeTableString
+ \catcode 32 \activecatcode %% \spaceasciicode
+}
+
+\def \listingsurroundskip {\vskip \baselineskip}
+
+\def \beginlisting {%
+ \noindent
+ \begingroup
+ \catcodetable \vrbcatcodes
+ \beginlistingindeed%
+}
+
+\directlua {
+ local texsprint = tex.sprint
+ local stringis_empty = string.is_empty
+ local stringsub = string.sub
+ local stringgsub = string.gsub
+ %local backslash = unicode.utf8.char (0x200c)
+ local backslash = unicode.utf8.char (0x5c)
+ local escaped = [[\string\string\string\]]
+ document.printlines = function (buffer)
+ local lines = string.explode (buffer, "\noexpand\n")
+ print ""
+ for i, line in next, lines do
+ local line = stringgsub (line, backslash, escaped)
+ if stringis_empty (line) then
+ print (i, "listing: <empty line />")
+ texsprint [[\string\listingpar]]
+ else
+ local line = [[\string\beginlistingline]]
+ .. line
+ .. [[\string\endlistingline]]
+ .. [[\string\listingpar]]
+ print (i, "listing: «" .. line .. "»")
+ texsprint (document.vrbcatcodesidx, line)
+ end
+ end
+ end
+}
+
+\def \listingpar {\endgraf}
+
+\let \endlistingline \relax
+\let \endlisting \relax
+
+\protected \def \beginlistingline{%
+ \leavevmode
+ \begingroup
+ \beginlistinglineindeed%
+}
+
+\def \beginlistinglineindeed #1\endlistingline{%
+ \endgroup
+ \hbox{%
+ \addfontfeature {RawFeature=-tlig;-liga}%% So one can’t just turn them all off at once using the ``Ligatures`` key?
+ \obeyspaces
+ #1}%
+}
+
+\def \beginlistingindeed#1\endlisting{%
+ \endgroup
+ \begingroup
+ \endgraf
+ \listingsurroundskip
+ \ttfamily
+ \small
+ \parindent = 0em
+ \leftskip = 2em
+ \hangindent = 2em
+ \directlua{document.printlines ([==[\detokenize {#1}]==])}%
+ \listingsurroundskip
+ \endgroup
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% enumerations and lists
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def \definelist [#1]#2{% name, itemcode
+ \expandafter \def \csname begin#1\endcsname {%
+ \begin {itemize}
+ \let \normalitem = \item
+ \def \altitem ####1{%
+ \def \first {####1}%
+ #2
+ }
+ \let \beginnormalitem \item
+ \let \endnormalitem \relax
+ \let \beginaltitem \altitem
+ \let \endaltitem \relax
+ }
+
+ \expandafter \def \csname end#1\endcsname {%
+ \end {itemize}
+ }
+}
+
+\definelist [descriptions]{\normalitem {\textbf \first}\hfill\break}
+\definelist [definitions]{\normalitem {\fileent {\first}}}
+\definelist [filelist]{\normalitem {\fileent {\first}}\space--\hskip 1em}
+\definelist [functionlist]{\normalitem {\luaident {\first}}\hfill\break}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% columns
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def \begindoublecolumns {\begin {multicols} {2}}
+\def \enddoublecolumns {\end {multicols}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% alignment
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def \begincentered {\begin {center}}
+\def \endcentered {\end {center}}
+
+\def \beginnarrower {\begin {quote}}
+\def \endnarrower {\end {quote}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% special elements
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\let \beginfrontmatter \relax
+\let \endfrontmatter \relax
+
+\def \beginabstractcontent {\begin {abstract}}
+\def \endabstractcontent {\end {abstract}}
+
+\let \setdocumenttitle \title
+\let \setdocumentdate \date
+\let \setdocumentauthor \author
+\let \typesetdocumenttitle \maketitle
+
+\AtBeginDocument {%% seriously?
+ \let \typesetcontent \tableofcontents%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% floats
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% syntax definition
+\def \beginsyntaxfloat #1#2{%% #1:label #2:caption
+ \begin {figure} [b]
+ \edef \syntaxlabel {#1}%
+ \def \syntaxcaption {#2}%
+ \setlength\grammarparsep{0pt plus 2pt minus 2pt}%
+ \setlength\grammarindent{5cm}%
+ \begingroup
+ \small
+ \begin {grammar}
+}
+
+\def \endsyntaxfloat {%
+ \end {grammar}
+ \endgroup
+ \caption \syntaxcaption
+ \label \syntaxlabel
+ \end {figure}
+}
+
+%% figures, e.g. the file graph
+\def \figurefloat #1#2#3{%% #1:label #2:caption #3:file
+ \begin {figure} [b]
+ \caption {#2}%
+ \includegraphics[width=\textwidth]{#3}%
+ \label {#1}
+ \end {figure}
+}
+
+%% tables
+\def \tablefloat #1#2{%% #1:label #2:caption
+ \begin {table} [t]
+ \hrule
+ \caption {#2}%
+ \label {#1}
+ \hrule
+ \end {table}
+}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% hyperlinks
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\protected \def \hyperlink{%
+ \@ifnextchar[{\hyperlinkindeed}%
+ {\hyperlinkindeed[]}%
+}
+
+\def \hyperlinkindeed [#1]#2{%
+ \def \first {#1}%
+ \ifx \first \empty
+ \url {#2}%
+ \else
+ \href {#2}{#1}%
+ \fi%
+}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% tables
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Our tables aren’t anything special so we stick with “tabular†on the
+%% Latex end.
+%%
+%% This is going to be largely incompatible with Context since format
+%% specifications work quite differently (even between different
+%% Context table variants).
+
+\def \begintabulate [#1]#2\endtabulate{%
+ \begingroup
+ \let \beginrow = \relax %% -> \NC in Context
+ \let \newcell = & %% -> \NC
+ \let \endrow = \cr %% -> \NC \NR
+ \begin {tabular}{#1}%
+ #2
+ \end {tabular}
+ \endgroup
+}
+
+\let \endtabulate \relax
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% escaped characters
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\let \charpercent \textpercent
+\let \charbackslash \textbackslash
+\let \chartilde \textasciitilde
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% main
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\makeatother
+
+\newif \ifcontextmkiv \contextmkivfalse
+
+\usepackage{luacode}
+
+% a few lua functions to grab the file lists.
+\begin{luacode}
+require("luaotfload-filelist.lua")
+
+function printctxlibslist ()
+ t= luaotfload.filelist.selectctxlibsentries (luaotfload.filelist.data)
+ for i,v in ipairs (t) do
+ tex.sprint("\\beginaltitem {"..v.name.. v.ext.."}\\endaltitem")
+ end
+end
+
+function printctxallgenericlist ()
+ t= luaotfload.filelist.selectctxgeneentries (luaotfload.filelist.data)
+ for i,v in ipairs (t) do
+ tex.sprint("\\beginaltitem {"..v.ctxpref..v.name..v.ext.."}\\endaltitem")
+ end
+end
+
+function printctxfontlist ()
+ t= luaotfload.filelist.selectctxfontentries (luaotfload.filelist.data)
+ for i,v in ipairs (t) do
+ tex.sprint("\\beginaltitem {"..v.name..v.ext.."}\\endaltitem")
+ end
+end
+\end{luacode}
+
+
+\begin {document}
+ \input {luaotfload-main.tex}
+\clearpage
+\includepdf[fitpaper,pagecommand={\label{file-graph}}]{filegraph}
+\clearpage
+
+\includepdf[pages=1,pagecommand={\phantomsection\addcontentsline{toc}{section}{Appendix: Manual of luaotfload.conf}{\thepage}{}}]{luaotfload-conf.pdf}
+\includepdf[pages=2-]{luaotfload-conf.pdf}
+
+\clearpage
+
+\includepdf[pages=1,pagecommand={\phantomsection\addcontentsline{toc}{section}{Appendix: Manual of luaotfload-tool}{\thepage}{}
+}]{luaotfload-tool.pdf}
+\includepdf[pages=2-]{luaotfload-tool.pdf}
+
+\end {document}
+
+
diff --git a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
new file mode 100644
index 0000000000..1acf67df8b
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
@@ -0,0 +1,578 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-letterspace.lua
+-- DESCRIPTION: part of luaotfload / letterspacing
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-letterspace",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / color",
+ license = "GPL v2.0",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL; adapted by Philipp Gesang, Ulrike Fischer, Marcel Krüger"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+--- This code diverged quite a bit from its origin in Context. Please
+--- do *not* report bugs on the Context list.
+
+local logreport = luaotfload.log.report
+
+local getmetatable = getmetatable
+local setmetatable = setmetatable
+local tonumber = tonumber
+local unpack = table.unpack
+
+local next = next
+local node, fonts = node, fonts
+
+local nodedirect = node.direct
+
+local getfield = nodedirect.getfield
+local setfield = nodedirect.setfield
+
+local getfont = nodedirect.getfont
+local getid = nodedirect.getid
+
+local getnext = nodedirect.getnext
+local setnext = nodedirect.setnext
+
+local getprev = nodedirect.getprev
+local setprev = nodedirect.setprev
+
+local getboth = nodedirect.getboth
+
+local setlink = nodedirect.setlink
+
+local getdisc = nodedirect.getdisc
+local setdisc = nodedirect.setdisc
+
+local getsubtype = nodedirect.getsubtype
+local setsubtype = nodedirect.setsubtype
+
+local getchar = nodedirect.getchar
+local setchar = nodedirect.setchar
+
+local getkern = nodedirect.getkern
+local setkern = nodedirect.setkern
+
+local getglue = nodedirect.getglue
+local setglue = nodedirect.setglue
+
+local find_node_tail = nodedirect.tail
+local todirect = nodedirect.todirect
+local tonode = nodedirect.tonode
+
+local insert_node_before = nodedirect.insert_before
+local free_node = nodedirect.free
+local copy_node = nodedirect.copy
+local new_node = nodedirect.new
+
+local glyph_code = node.id"glyph"
+local kern_code = node.id"kern"
+local disc_code = node.id"disc"
+local glue_code = node.id"glue"
+local whatsit_code = node.id"whatsit"
+
+local fonthashes = fonts.hashes
+local identifiers = fonthashes.identifiers
+local chardata = fonthashes.characters
+local otffeatures = fonts.constructors.newfeatures "otf"
+
+local function getprevreal(n)
+ repeat
+ n = getprev(n)
+ until not n or getid(n) ~= whatsit_code
+ return n
+end
+local function getnextreal(n)
+ repeat
+ n = getnext(n)
+ until not n or getid(n) ~= whatsit_code
+ return n
+end
+
+--[[doc--
+
+ Since the letterspacing method was derived initially from Context’s
+ typo-krn.lua we keep the sub-namespace “letterspace†inside the
+ “luaotfload†table.
+
+--doc]]--
+
+luaotfload.letterspace = luaotfload.letterspace or { }
+local letterspace = luaotfload.letterspace
+
+local lectured = false
+letterspace.keepligature = true
+letterspace.keeptogether = false
+letterspace.keepwordspacing = false
+
+---=================================================================---
+--- preliminary definitions
+---=================================================================---
+-- We set up a layer emulating some Context internals that are needed
+-- for the letterspacing callback.
+-----------------------------------------------------------------------
+--- node-ini
+-----------------------------------------------------------------------
+
+local kerning_code = 0
+local userkern_code = 1
+local userskip_code = 0
+local spaceskip_code = 13
+local xspaceskip_code = 14
+
+if not chardata then
+ chardata = { }
+ table.setmetatableindex(chardata, function(t, k)
+ if k == true then
+ return chardata[currentfont()]
+ else
+ local tfmdata = font.getfont(k) or font.fonts[k]
+ if tfmdata then
+ local characters = tfmdata.characters
+ t[k] = characters
+ return characters
+ end
+ end
+ end)
+ fonthashes.characters = chardata
+end
+
+---=================================================================---
+--- character kerning functionality
+---=================================================================---
+
+-- UF changed 2017-07-14
+local kern_injector = function (fillup, kern)
+ if fillup then
+ local g = new_node(glue_code)
+ setglue(g, 0, kern, 0, 1, 0)
+ return g
+ end
+ local g = new_node(kern_code)
+ setkern(g,kern)
+ return g
+end
+-- /UF
+
+local kernable_skip = function (n)
+ local st = getsubtype (n)
+ return st == userskip_code
+ or st == spaceskip_code
+ or st == xspaceskip_code
+end
+
+--[[doc--
+
+ Caveat lector.
+ This is an adaptation of the Context character kerning mechanism
+ that emulates XeTeX-style fontwise letterspacing. Note that in its
+ present state it is far inferior to the original, which is
+ attribute-based and ignores font-boundaries. Nevertheless, due to
+ popular demand the following callback has been added.
+
+--doc]]--
+
+local kernamounts = table.setmetatableindex(function (t, f) --- fontid -> {kern, fill}
+ local tfmdata = font.getfont(f) or font.fonts[f]
+ if tfmdata then
+ local fontproperties = tfmdata.properties
+ local fontparameters = tfmdata.parameters
+ if fontproperties and fontparameters then
+ local r
+ if fontproperties.kerncharacters == "max" then
+ r = {fontparameters.quad/4, true}
+ elseif fontproperties.kerncharacters then
+ r = {fontproperties.kerncharacters * fontparameters.quad, false}
+ else
+ r = {}
+ end
+ t[f] = r
+ return r
+ end
+ end
+ return {}
+end)
+
+local kerncharacters
+kerncharacters = function (head)
+ local start = head
+ local lastfont = nil
+ local keeptogether = letterspace.keeptogether --- function
+ local keepligature = letterspace.keepligature
+-- if not lectured and keepligature ~= true then
+-- logreport ("both", 0, "letterspace",
+-- "Breaking ligatures through letterspacing is deprecated and "
+-- .. "will be removed soon. Please disable unwanted ligatures through "
+-- .. "font features instead and reset luaotfload.letterspace.keepligature "
+-- .. "to true to maintain compatibility with future versions of luaotfload.")
+-- lectured = true
+-- end
+ if type(keepligature) ~= "function" then
+ local savedligature = keepligature
+ keepligature = function() return savedligature end
+ end
+ local keepwordspacing = letterspace.keepwordspacing
+ if type(keepwordspacing) ~= "function" then
+ local savedwordspacing = keepwordspacing
+ keepwordspacing = function() return savedwordspacing end
+ end
+
+ local kernamounts = kernamounts
+ local firstkern = true
+
+ while start do
+ local id = getid(start)
+ if id == glyph_code then
+ --- 1) look up kern factor (slow, but cached rudimentarily)
+ local fontid = getfont(start)
+ local krn, fillup = unpack(kernamounts[fontid])
+ if not krn or krn == 0 then
+ firstkern = true
+ goto nextnode
+ elseif firstkern then
+ firstkern = false
+ if (id ~= disc_code) and (not getfield(start, "components")) then
+ --- not a ligature, skip node
+ goto nextnode
+ end
+ end
+
+ lastfont = fontid
+
+ --- 2) resolve ligatures
+ local c = getfield(start, "components")
+
+ if c then
+ if keepligature(start) then
+ -- keep 'm
+ c = nil
+ else
+ while c do
+ local s = start
+ local p, n = getboth (s)
+ if p then
+ setlink (p, c)
+ else
+ head = c
+ end
+ if n then
+ local tail = find_node_tail(c)
+ setlink (tail, n)
+ end
+ start = c
+ setfield(s, "components", nil)
+ free_node(s) --> double free with multipart components
+ c = getfield (start, "components")
+ end
+ end
+ end -- kern ligature
+
+ --- 3) apply the extra kerning
+ local prev = getprevreal(start)
+ if prev then
+ local pid = getid(prev)
+
+ if not pid then
+ -- nothing
+
+ elseif pid == glue_code and kernable_skip(prev)
+ and not keepwordspacing(prev, lastfont) then
+ local wd, stretch, shrink = getglue(prev)
+ if wd > 0 then
+ local newwd = wd + krn
+ local stretched = (stretch * newwd) / wd
+ local shrunk = (shrink * newwd) / wd
+ if fillup then
+ setglue(prev, newwd, 2 * stretched, 2 * shrunk, 1, 0)
+ else
+ setglue(prev, newwd, stretched, shrunk, 0, 0)
+ end
+ end
+
+ elseif pid == kern_code then
+ local prev_subtype = getsubtype(prev)
+ if prev_subtype == kerning_code --- context does this by means of an
+ or prev_subtype == userkern_code --- attribute; we may need a test
+ then
+
+ local pprev = getprevreal(prev)
+ local pprev_id = getid(pprev)
+
+ if keeptogether
+ and pprev_id == glyph_code
+ and keeptogether(pprev, start)
+ then
+ -- keep
+ else
+ setsubtype (prev, userkern_code)
+ local prev_kern = getkern(prev)
+ prev_kern = prev_kern + krn
+ setkern (prev, prev_kern)
+ end
+ end
+
+ elseif pid == glyph_code then
+ if getfont(prev) == lastfont then
+ local prevchar = getchar(prev)
+ local lastchar = getchar(start)
+ if keeptogether and keeptogether(prev, start) then
+ -- keep 'm
+ elseif identifiers[lastfont] then
+ local lastfontchars = chardata[lastfont]
+ if lastfontchars then
+ local prevchardata = lastfontchars[prevchar]
+ if not prevchardata then
+ --- font doesn’t contain the glyph
+ else
+ local kern = 0
+ local kerns = prevchardata.kerns
+ if kerns then kern = kerns[lastchar] or kern end
+ krn = kern + krn -- here
+ insert_node_before(head,start,kern_injector(fillup,krn))
+ end
+ end
+ end
+ else
+ insert_node_before(head,start,kern_injector(fillup,krn))
+ end
+
+ elseif pid == disc_code then
+ local disc = prev -- disc
+ local pre, post, replace = getdisc (disc)
+ local prv = getprevreal(disc)
+ local nxt = getnextreal(disc)
+
+ if pre and prv then -- must pair with start.prev
+ -- this one happens in most cases
+ local before = copy_node(prv)
+ setprev(pre, before)
+ setnext(before, pre)
+ setprev(before, nil)
+ pre = kerncharacters (before)
+ pre = getnext(pre)
+ setprev(pre, nil)
+ setfield(disc, "pre", pre)
+ free_node(before)
+ end
+
+ if post and nxt then -- must pair with start
+ local after = copy_node(nxt)
+ local tail = find_node_tail(post)
+ setnext(tail, after)
+ setprev(after, tail)
+ post = kerncharacters (post)
+ setnext(getprev(after), nil)
+ setfield(disc, "post", post)
+ free_node(after)
+ end
+
+ if replace and prv and nxt then -- must pair with start and start.prev
+ local before = copy_node(prv)
+ local after = copy_node(nxt)
+ local tail = find_node_tail(replace)
+ setprev(replace, before)
+ setnext(before, replace)
+ setprev(before, nil)
+ setnext(tail, after)
+ setprev(after, tail)
+ setnext(after, nil)
+ replace = kerncharacters (before)
+ replace = getnext(replace)
+ setprev(replace, nil)
+ setnext(getprev(after), nil)
+ setfield(disc, "replace", replace)
+ free_node(after)
+ free_node(before)
+
+ elseif identifiers[lastfont] then
+ if prv
+ and getid(prv) == glyph_code
+ and getfont(prv) == lastfont
+ then
+ local kern = 0
+ local prevchar = getchar(prv)
+ local lastchar = getchar(start)
+ local lastfontchars = chardata[lastfont]
+ if lastfontchars then
+ local prevchardata = lastfontchars[prevchar]
+ if not prevchardata then
+ --- font doesn’t contain the glyph
+ else
+ local kerns = prevchardata.kerns
+ if kerns then kern = kerns[lastchar] or kern end
+ end
+ end
+ krn = kern + krn -- here
+ end
+ setfield(disc, "replace", kern_injector(false, krn))
+ end --[[if replace and prv and nxt]]
+ end --[[if not pid]]
+ end --[[if prev]]
+ end --[[if id == glyph_code]]
+
+ ::nextnode::
+ if start then
+ start = getnext(start)
+ end
+ end
+ return head
+end
+
+---=================================================================---
+--- integration
+---=================================================================---
+
+--- · callback: kerncharacters
+--- · enabler: enablefontkerning
+
+--- callback wrappers
+
+--- (node_t -> node_t) -> string -> string list -> bool
+local registered_as = { } --- procname -> callbacks
+local add_processor = function (processor, name, ...)
+ local callbacks = { ... }
+ for i=1, #callbacks do
+ luatexbase.add_to_callback(callbacks[i], processor, name)
+ end
+ registered_as[name] = callbacks --- for removal
+ return true
+end
+
+--- string -> bool
+local remove_processor = function (name)
+ local callbacks = registered_as[name]
+ if callbacks then
+ for i=1, #callbacks do
+ luatexbase.remove_from_callback(callbacks[i], name)
+ end
+ return true
+ end
+ return false --> unregistered
+end
+
+--- When font kerning is requested, usually by defining a font with the
+--- ``letterspace`` parameter, we inject a wrapper for the
+--- ``kerncharacters()`` node processor in the relevant callbacks. This
+--- wrapper initially converts the received head node into its “directâ€
+--- counterpart. Likewise, the callback result is converted back to an
+--- ordinary node prior to returning. Internally, ``kerncharacters()``
+--- performs all node operations on direct nodes.
+
+--- unit -> bool
+local enablefontkerning = function ( )
+
+ local handler = function (hd)
+ local direct_hd = todirect (hd)
+ logreport ("term", 5, "letterspace",
+ "kerncharacters() invoked with node.direct interface \z
+ (``%s`` -> ``%s``)", tostring (hd), tostring (direct_hd))
+ local direct_hd = kerncharacters (direct_hd)
+ if not direct_hd then --- bad
+ logreport ("both", 0, "letterspace",
+ "kerncharacters() failed to return a valid new head")
+ end
+ return tonode (direct_hd)
+ end
+
+ return add_processor( handler
+ , "luaotfload.letterspace"
+ , "pre_linebreak_filter"
+ , "hpack_filter")
+end
+
+--[[doc--
+
+ Fontwise kerning is enabled via the “kernfactor†option at font
+ definition time. Unlike the Context implementation which relies on
+ Luatex attributes, it uses a font property for passing along the
+ letterspacing factor of a node.
+
+ The callback is activated the first time a letterspaced font is
+ requested and stays active until the end of the run. Since the font
+ is a property of individual glyphs, every glyph in the entire
+ document must be checked for the kern property. This is quite
+ inefficient compared to Context’s attribute based approach, but Xetex
+ compatibility reduces our options significantly.
+
+--doc]]--
+
+
+local fontkerning_enabled = false --- callback state
+
+--- fontobj -> float -> unit
+local initializefontkerning = function (tfmdata, factor)
+ if factor ~= "max" then
+ factor = tonumber (factor) or 0
+ end
+ if factor == "max" or factor ~= 0 then
+ local fontproperties = tfmdata.properties
+ if fontproperties then
+ --- hopefully this field stays unused otherwise
+ fontproperties.kerncharacters = factor
+ end
+ if not fontkerning_enabled then
+ fontkerning_enabled = enablefontkerning ()
+ end
+ end
+end
+
+--- like the font colorization, fontwise kerning is hooked into the
+--- feature mechanism
+
+otffeatures.register {
+ name = "kernfactor",
+ description = "kernfactor",
+ initializers = {
+ base = initializefontkerning,
+ node = initializefontkerning,
+ }
+}
+
+--[[doc--
+
+ The “letterspace†feature is essentially identical with the above
+ “kernfactor†method, but scales the factor to percentages to match
+ Xetex’s behavior. (See the Xetex reference, page 5, section 1.2.2.)
+
+ Since Xetex doesn’t appear to have a (documented) “max†keyword, we
+ assume all input values are numeric.
+
+--doc]]--
+
+local initializecompatfontkerning = function (tfmdata, percentage)
+ local factor = tonumber (percentage)
+ if not factor then
+ logreport ("both", 0, "letterspace",
+ "Invalid argument to letterspace: %s (type %q), " ..
+ "was expecting percentage as Lua number instead.",
+ percentage, type (percentage))
+ return
+ end
+ return initializefontkerning (tfmdata, factor * 0.01)
+end
+
+otffeatures.register {
+ name = "letterspace",
+ description = "letterspace",
+ initializers = {
+ base = initializecompatfontkerning,
+ node = initializecompatfontkerning,
+ }
+}
+
+--[[example--
+
+See https://bitbucket.org/phg/lua-la-tex-tests/src/tip/pln-letterspace-8-compare.tex
+for an example.
+
+--example]]--
+
+--- vim:sw=2:ts=2:expandtab:tw=71
+
diff --git a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
new file mode 100644
index 0000000000..39ffd243f7
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
@@ -0,0 +1,240 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-loaders.lua
+-- DESCRIPTION: Luaotfload callback handling
+-- REQUIREMENTS: luatex v.0.80 or later; package lualibs
+-- AUTHOR: Philipp Gesang <phg@phi-gamma.net>
+-- AUTHOR: Hans Hagen, Khaled Hosny, Elie Roux, David Carlisle
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-loaders",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / callback handling",
+ license = "GPL v2.0"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+-----------------------------------------------------------------------
+
+
+
+if not lualibs then error "this module requires Luaotfload" end
+if not luaotfload then error "this module requires Luaotfload" end
+
+local logreport = luaotfload.log and luaotfload.log.report or print
+
+local lua_reader = function (specification)
+ local fullname = specification.filename or ""
+ if fullname == "" then
+ local forced = specification.forced or ""
+ if forced ~= "" then
+ fullname = specification.name .. "." .. forced
+ else
+ fullname = specification.name
+ end
+ end
+ local fullname = resolvers.findfile (fullname) or ""
+ if fullname ~= "" then
+ local loader = loadfile (fullname)
+ loader = loader and loader ()
+ return loader and loader (specification)
+ end
+end
+
+local eval_reader = function (specification)
+ local eval = specification.eval
+ if not eval or type (eval) ~= "function" then return nil end
+ logreport ("both", 0, "loaders",
+ "eval: found tfmdata for “%sâ€, injecting.",
+ specification.name)
+ return eval ()
+end
+
+local unsupported_reader = function (format)
+ return function (specification)
+ logreport ("both", 4, "loaders",
+ "font format “%s†unsupported; cannot load %s.",
+ format, tostring (specification.name))
+ end
+end
+
+local type1_reader = fonts.readers.afm
+local tfm_reader = fonts.readers.tfm
+
+local install_formats = function ()
+ local fonts = fonts
+ if not fonts then return false end
+
+ local readers = fonts.readers
+ local sequence = readers.sequence
+ local seqset = table.tohash (sequence)
+ local formats = fonts.formats
+ if not readers or not formats then return false end
+
+ local aux = function (which, reader)
+ if not which or type (which) ~= "string"
+ or not reader or type (reader) ~= "function" then
+ logreport ("both", 2, "loaders", "Error installing reader for “%sâ€.", which)
+ return false
+ end
+ formats [which] = "type1"
+ readers [which] = reader
+ if not seqset [which] then
+ logreport ("both", 3, "loaders",
+ "Extending reader sequence for “%sâ€.", which)
+ sequence [#sequence + 1] = which
+ seqset [which] = true
+ end
+ return true
+ end
+
+ return aux ("evl", eval_reader)
+ and aux ("lua", lua_reader)
+ and aux ("pfa", unsupported_reader "pfa")
+ and aux ("afm", type1_reader)
+ and aux ("pfb", type1_reader)
+ and aux ("tfm", tfm_reader)
+ and aux ("ofm", tfm_reader)
+ and aux ("dfont", unsupported_reader "dfont")
+end
+
+local not_found_msg = function (specification, size, id)
+ logreport ("both", 0, "loaders", "")
+ logreport ("both", 0, "loaders",
+ "--------------------------------------------------------")
+ logreport ("both", 0, "loaders", "")
+ logreport ("both", 0, "loaders", "Font definition failed for:")
+ logreport ("both", 0, "loaders", "")
+ logreport ("both", 0, "loaders", " > id : %d", id)
+ logreport ("both", 0, "loaders", " > specification : %q", specification)
+ if size > 0 then
+ logreport ("both", 0, "loaders", " > size : %.2f pt", size / 2^16)
+ end
+ logreport ("both", 0, "loaders", "")
+ logreport ("both", 0, "loaders",
+ "--------------------------------------------------------")
+end
+--[[doc--
+
+ \subsection{\CONTEXT override}
+ \label{define-font}
+ We provide a simplified version of the original font definition
+ callback.
+
+--doc]]--
+
+
+local definers --- (string, spec -> size -> id -> tmfdata) hash_t
+do
+ local read = fonts.definers.read
+
+ local patch = function (specification, size, id)
+ local fontdata = read (specification, size, id)
+----if not fontdata then not_found_msg (specification, size, id) end
+ if type (fontdata) == "table" and fontdata.encodingbytes == 2 then
+ --- We need to test for `encodingbytes` to avoid passing
+ --- tfm fonts to `patch_font`. These fonts are fragile
+ --- because they use traditional TeX font handling.
+ luatexbase.call_callback ("luaotfload.patch_font", fontdata, specification, id)
+ else
+ luatexbase.call_callback ("luaotfload.patch_font_unsafe", fontdata, specification, id)
+ end
+ return fontdata
+ end
+
+ local mk_info = function (name)
+ local definer = name == "patch" and patch or read
+ return function (specification, size, id)
+ logreport ("both", 0, "loaders", "defining font no. %d", id)
+ logreport ("both", 0, "loaders", " > active font definer: %q", name)
+ logreport ("both", 0, "loaders", " > spec %q", specification)
+ logreport ("both", 0, "loaders", " > at size %.2f pt", size / 2^16)
+ local result = definer (specification, size, id)
+ if not result then return not_found_msg (specification, size, id) end
+ if type (result) == "number" then
+ logreport ("both", 0, "loaders", " > font definition yielded id %d", result)
+ return result
+ end
+ logreport ("both", 0, "loaders", " > font definition successful")
+ logreport ("both", 0, "loaders", " > name %q", result.name or "<nil>")
+ logreport ("both", 0, "loaders", " > fontname %q", result.fontname or "<nil>")
+ logreport ("both", 0, "loaders", " > fullname %q", result.fullname or "<nil>")
+ logreport ("both", 0, "loaders", " > type %s", result.type or "<nil>")
+ local spec = result.specification
+ if spec then
+ logreport ("both", 0, "loaders", " > file %q", spec.filename or "<nil>")
+ logreport ("both", 0, "loaders", " > subfont %s", spec.sub or "<nil>")
+ end
+ return result
+ end
+ end
+
+ definers = {
+ patch = patch,
+ generic = read,
+ info_patch = mk_info "patch",
+ info_generic = mk_info "generic",
+ }
+end
+
+--[[doc--
+
+ We create callbacks for patching fonts on the fly, to be used by
+ other packages. In addition to the regular \identifier{patch_font}
+ callback there is an unsafe variant \identifier{patch_font_unsafe}
+ that will be invoked even if the target font lacks certain essential
+ tfmdata tables.
+
+ The callbacks initially contain the empty function that we are going
+ to override below.
+
+--doc]]--
+
+local purge_define_font = function ()
+ local cdesc = luatexbase.callback_descriptions "define_font"
+ --- define_font is an “exclusive†callback, meaning that there can
+ --- only ever be one entry. Everything beyond that would indicate
+ --- that something is broken.
+ local _, d = next (cdesc)
+ if d then
+ local i, d2 = next (cdesc, 1)
+ if d2 then --> issue warning
+ logreport ("both", 0, "loaders",
+ "Callback table for define_font contains multiple entries: \z
+ { [%d] = “%s†} -- seems fishy.", i, d2)
+ end
+ logreport ("log", 0, "loaders",
+ "Entry ``%s`` present in define_font callback; overriding.", d)
+ luatexbase.remove_from_callback ("define_font", d)
+ end
+end
+
+local install_callbacks = function ()
+ local create_callback = luatexbase.create_callback
+ local dummy_function = function () end
+ create_callback ("luaotfload.patch_font", "simple", dummy_function)
+ create_callback ("luaotfload.patch_font_unsafe", "simple", dummy_function)
+ purge_define_font ()
+ local definer = config.luaotfload.run.definer
+ luatexbase.add_to_callback ("define_font",
+ definers[definer or "patch"],
+ "luaotfload.define_font",
+ 1)
+ return true
+end
+
+return function ()
+ if not install_formats () then
+ logreport ("log", 0, "loaders", "Error initializing OFM/PF{A,B} loaders.")
+ return false
+ end
+ if not install_callbacks () then
+ logreport ("log", 0, "loaders", "Error installing font loader callbacks.")
+ return false
+ end
+ return true
+end
+-- vim:tw=79:sw=2:ts=2:expandtab
diff --git a/macros/luatex/generic/luaotfload/luaotfload-log.lua b/macros/luatex/generic/luaotfload/luaotfload-log.lua
new file mode 100644
index 0000000000..17938ffd3d
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-log.lua
@@ -0,0 +1,394 @@
+-------------------------------------------------------------------------------
+-- FILE: luaotfload-log.lua
+-- DESCRIPTION: part of luaotfload / logging
+-------------------------------------------------------------------------------
+
+
+local ProvidesLuaModule = {
+ name = "luaotfload-log",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / logging",
+ license = "GPL v2.0",
+ author = "Khaled Hosny, Elie Roux, Philipp Gesang",
+ copyright = "Luaotfload Development Team",
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+
+--[[doc--
+The logging system is slow in general, as we always have the function
+call overhead even if we aren’t going to output anything. On the other
+hand, the more efficient approach followed by Context isn’t an option
+because we lack a user interface to toggle per-subsystem tracing.
+--doc]]--
+
+local module_name = "luaotfload" --- prefix for messages
+local debug = debug
+
+luaotfload = luaotfload or { }
+luaotfload.log = luaotfload.log or { }
+local log = luaotfload.log
+
+local ioopen = io.open
+local iowrite = io.write
+local lfsisdir = lfs.isdir
+local lfsisfile = lfs.isfile
+local osdate = os.date
+local ostime = os.time
+local osuuid = os.uuid
+local select = select
+local stringformat = string.format
+local stringsub = string.sub
+local tableconcat = table.concat
+local texiowrite_nl = texio.write_nl
+local texiowrite = texio.write
+local type = type
+
+local dummyfunction = function () end
+
+local texjob = false
+if tex and (tex.jobname or tex.formatname) then
+ --- TeX
+ texjob = true
+end
+
+local loglevel = 0 --- default
+local logout = "log"
+
+--- int -> bool
+local set_loglevel = function (n)
+ if type(n) == "number" then
+ loglevel = n
+ end
+ return true
+end
+log.set_loglevel = set_loglevel
+
+--- unit -> int
+local get_loglevel = function ( )
+ return loglevel
+end
+log.get_loglevel = get_loglevel
+
+local writeln --- pointer to terminal/log writer
+local statusln --- terminal writer that reuses the current line
+local first_status = true --- indicate the begin of a status region
+
+local log_msg = [[
+logging output redirected to %s
+to monitor the progress run "tail -f %s" in another terminal
+]]
+
+local tmppath = os.getenv "TMPDIR" or "/tmp"
+
+local choose_logfile = function ( )
+ if lfsisdir (tmppath) then
+ local fname
+ repeat --- ensure that file of that name doesn’t exist
+ fname = tmppath .. "/luaotfload-log-" .. osuuid()
+ until not lfsisfile (fname)
+ iowrite (stringformat (log_msg, fname, fname))
+ return ioopen (fname, "w")
+ end
+ --- missing /tmp
+ return false
+end
+
+local set_logout = function (s, finalizers)
+ if s == "stdout" then
+ logout = "redirect"
+ elseif s == "file" then --- inject custom logger
+ logout = "redirect"
+ local chan = choose_logfile ()
+ chan:write (stringformat ("logging initiated at %s",
+ osdate ("%Y-%m-%d %H:%M:%S", --- i. e. osdate "%F %T"
+ ostime ())))
+ local writefile = function (...)
+ if select ("#", ...) == 2 then
+ chan:write (select (2, ...))
+ else
+ chan:write (select (1, ...))
+ end
+ end
+ local writefile_nl= function (...)
+ chan:write "\n"
+ if select ("#", ...) == 2 then
+ chan:write (select (2, ...))
+ else
+ chan:write (select (1, ...))
+ end
+ end
+
+ local writeln_orig = writeln
+
+ texiowrite = writefile
+ texiowrite_nl = writefile_nl
+ writeln = writefile_nl
+ statusln = dummyfunction
+
+ finalizers[#finalizers+1] = function ()
+ chan:write (stringformat ("\nlogging finished at %s\n",
+ osdate ("%Y-%m-%d %H:%M:%S", --- i. e. osdate "%F %T"
+ ostime ())))
+ chan:close ()
+ texiowrite = texio.write
+ texiowrite_nl = texio.write_nl
+ writeln = writeln_orig
+ end
+ --else --- remains “logâ€
+ end
+ return finalizers
+end
+
+log.set_logout = set_logout
+
+local format_error_handler
+if debug then
+ local debugtraceback = debug.traceback
+ format_error_handler = function (err)
+ print ""
+ print (stringformat ("luaotfload error: %q", err))
+ print (stringformat ("Lua interpreter %s", debugtraceback ()))
+ print ""
+ end
+else
+ format_error_handler = function (err)
+ print ""
+ print (stringformat ("luaotfload error: %q", err))
+ print "Lua debug module not available; please enable for a backtrace"
+ print ""
+ end
+end
+
+local basic_logger = function (category, fmt, ...)
+ local res = { module_name, "|", category or "UNKNOWN", ":" }
+ if fmt then
+ local ok, val = xpcall (stringformat, format_error_handler, fmt, ...)
+ if ok then
+ res [#res + 1] = val
+ else
+ res [#res + 1] = stringformat ("ERROR: %q", val)
+ end
+ end
+ texiowrite_nl (logout, tableconcat(res, " "))
+end
+
+--- with faux db update with maximum verbosity:
+---
+--- --------- --------
+--- buffering time (s)
+--- --------- --------
+--- full 4.12
+--- line 4.20
+--- none 4.39
+--- --------- --------
+---
+
+io.stdout:setvbuf "no"
+io.stderr:setvbuf "no"
+
+local kill_line = "\r\x1b[K"
+
+if texjob == true then
+ --- We imitate the texio.* functions so the output is consistent.
+ writeln = function (str)
+ iowrite "\n"
+ iowrite(str)
+ end
+ statusln = function (str)
+ if first_status == false then
+ iowrite (kill_line)
+ else
+ iowrite "\n"
+ end
+ iowrite (str)
+ end
+else
+ writeln = function (str)
+ iowrite(str)
+ iowrite "\n"
+ end
+ statusln = function (str)
+ if first_status == false then
+ iowrite (kill_line)
+ end
+ iowrite (str)
+ end
+end
+
+stdout = function (writer, category, ...)
+ local res = { module_name, "|", category, ":" }
+ local nargs = select("#", ...)
+ if nargs == 0 then
+ --writeln tableconcat(res, " ")
+ --return
+ elseif nargs == 1 then
+ res[#res+1] = select(1, ...) -- around 30% faster than unpack()
+ else
+ res[#res+1] = stringformat(...)
+ end
+ writer (tableconcat(res, " "))
+end
+
+--- at default (zero), we aim to be quiet
+local level_ids = { common = 1, loading = 2, search = 3 }
+
+--[[doc--
+
+ The report() logger is used more or less all over luaotfload.
+ Its requirements are twofold:
+
+ 1) Provide two logging channels, the terminal and the log file;
+ 2) Allow for control over verbosity levels.
+
+ The first part is addressed by specifying the log *mode* as the
+ first argument that can be either “logâ€, meaning the log file, or
+ “bothâ€: log file and stdout. Anything else is taken as referring to
+ stdout only.
+
+ Verbosity levels, though not as fine-grained as e.g. Context’s
+ system of tracers, allow keeping the logging spam caused by
+ different subsystems manageable. By default, luaotfload will not
+ emit anything if things are running smoothly on level zero. Only
+ warning messages are relayed, while the other messages are skipped
+ over. (This is a little sub-optimal performance-wise since the
+ function calls to the logger are executed regardless.) The log
+ level during a Luatex run can be adjusted by setting the “loglevelâ€
+ field in config.luaotfload, or by calling log.set_loglevel() as
+ defined above.
+
+--doc]]--
+
+local report = function (mode, lvl, ...)
+ if type(lvl) == "string" then
+ lvl = level_ids[lvl]
+ end
+ if not lvl then lvl = 0 end
+
+ if loglevel >= lvl then
+ if mode == "log" then
+ basic_logger (...)
+ elseif mode == "both" and logout ~= "redirect" then
+ basic_logger (...)
+ stdout (writeln, ...)
+ else
+ stdout (writeln, ...)
+ end
+ end
+end
+
+log.report = report
+
+--[[doc--
+
+ status_logger -- Overwrites the most recently printed line of the
+ terminal. Its purpose is to provide feedback without spamming
+ stdout with irrelevant messages, i.e. when building the database.
+
+ Status logging must be initialized by calling status_start() and
+ properly reset via status_stop().
+
+ The arguments low and high indicate the loglevel threshold at which
+ linewise and full logging is triggered, respectively. E.g.
+
+ names_status (1, 4, "term", "Hello, world!")
+
+ will print nothing if the loglevel is less than one, reuse the
+ current line if the loglevel ranges from one to three inclusively,
+ and output the message on a separate line otherwise.
+
+--doc]]--
+
+local status_logger = function (mode, ...)
+ if mode == "log" then
+ basic_logger (...)
+ else
+ if mode == "both" and logout ~= "redirect" then
+ basic_logger (...)
+ stdout (statusln, ...)
+ else
+ stdout (statusln, ...)
+ end
+ first_status = false
+ end
+end
+
+--[[doc--
+
+ status_start -- Initialize status logging. This installs the status
+ logger if the loglevel is in the specified range, and the normal
+ logger otherwise. It also resets the first line state which
+ causing the next line printed using the status logger to not kill
+ the current line.
+
+--doc]]--
+
+local status_writer
+local status_low = 99
+local status_high = 99
+
+local status_start = function (low, high)
+ first_status = true
+ status_low = low
+ status_high = high
+
+ if os.type == "windows" --- Assume broken terminal.
+ or os.getenv "TERM" == "dumb"
+ then
+ status_writer = function (mode, ...)
+ report (mode, high, ...)
+ end
+ return
+ end
+
+ if low <= loglevel and loglevel < high then
+ status_writer = status_logger
+ else
+ status_writer = function (mode, ...)
+ report (mode, high, ...)
+ end
+ end
+end
+
+--[[doc--
+
+ status_stop -- Finalize a status region by outputting a newline and
+ printing a message.
+
+--doc]]--
+
+local status_stop = function (...)
+ if first_status == false then
+ status_writer(...)
+ if texjob == false then
+ writeln ""
+ end
+ end
+end
+
+log.names_status = function (...) status_writer (...) end
+log.names_status_start = status_start
+log.names_status_stop = status_stop
+
+--[[doc--
+
+ The fontloader comes with the Context logging mechanisms
+ inaccessible. Instead, it provides dumb fallbacks based
+ on the functions in texio.write*() that can be overridden
+ by providing a function texio.reporter().
+
+ The fontloader output can be quite verbose, so we disable
+ it entirely by default.
+
+--doc]]--
+
+local texioreporter = function (message)
+ report ("log", 2, message)
+end
+
+texio.reporter = texioreporter
+--- vim:shiftwidth=4:expandtab:ft=lua
diff --git a/macros/luatex/generic/luaotfload/luaotfload-main.lua b/macros/luatex/generic/luaotfload/luaotfload-main.lua
new file mode 100644
index 0000000000..6c4b920181
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-main.lua
@@ -0,0 +1,313 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-main.lua
+-- DESCRIPTION: OpenType layout system / luaotfload entry point
+-- REQUIREMENTS: luatex v.0.95.0 or later; package lualibs
+-- AUTHOR: Élie Roux, Khaled Hosny, Philipp Gesang, Ulrike Fischer, Marcel Krüger
+-----------------------------------------------------------------------
+
+local authors = "\z
+ Hans Hagen,\z
+ Khaled Hosny,\z
+ Elie Roux,\z
+ Will Robertson,\z
+ Philipp Gesang,\z
+ Dohyun Kim,\z
+ Reuben Thomas,\z
+ David Carlisle,\
+ Ulrike Fischer,\z
+ Marcel Krüger\z
+"
+-- version number is used below!
+local ProvidesLuaModule = {
+ name = "luaotfload-main",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload entry point",
+ author = authors,
+ copyright = authors,
+ license = "GPL v2.0"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+local osgettimeofday = os.gettimeofday
+config = config or { }
+luaotfload = luaotfload or { }
+local luaotfload = luaotfload
+luaotfload.log = luaotfload.log or { }
+luaotfload.version = ProvidesLuaModule.version
+luaotfload.loaders = { }
+luaotfload.min_luatex_version = { 0, 95, 0 }
+luaotfload.fontloader_package = "reference" --- default: from current Context
+
+if not tex or not tex.luatexversion then
+ error "this program must be run in TeX mode" --- or call tex.initialize() =)
+else
+ --- version check
+ local major = tex.luatexversion / 100
+ local minor = tex.luatexversion % 100
+ local revision = tex.luatexrevision --[[ : string ]]
+ local revno = tonumber (revision)
+ local minimum = luaotfload.min_luatex_version
+ local actual = { major, minor, revno or 0 }
+ if actual [1] < minimum [1]
+ or actual == minimum and actual [2] < minimum [2]
+ or actual == minimum and actual [2] == minimum [2] and actual [3] < minimum [3]
+ then
+ texio.write_nl ("term and log",
+ string.format ("\tFATAL ERROR\n\z
+ \tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z
+ \tPlease update your TeX distribution!\n\n",
+ (unpack or table.unpack) (minimum)))
+ error "version check failed"
+ end
+end
+
+if status.safer_option ~= 0 then
+ texio.write_nl("term and log","luaotfload can't run with option --safer. Aborting")
+ error("safer_option used")
+end
+
+
+
+
+--[[doc--
+
+ This file initializes the system and loads the font loader. To
+ minimize potential conflicts between other packages and the code
+ imported from \CONTEXT, several precautions are in order. Some of
+ the functionality that the font loader expects to be present, like
+ raw access to callbacks, are assumed to have been disabled by
+ \identifier{luatexbase} when this file is processed. In some cases
+ it is possible to trick it by putting dummies into place and
+ restoring the behavior from \identifier{luatexbase} after
+ initilization. Other cases such as attribute allocation require
+ that we hook the functionality from \identifier{luatexbase} into
+ locations where they normally wouldn’t be.
+
+ Anyways we can import the code base without modifications, which is
+ due mostly to the extra effort by Hans Hagen to make \LUATEX-Fonts
+ self-contained and encapsulate it, and especially due to his
+ willingness to incorporate our suggestions.
+
+--doc]]--
+
+local luatexbase = luatexbase
+local require = require
+local type = type
+
+
+--[[doc--
+
+ \subsection{Module loading}
+ We load the files imported from \CONTEXT with function derived this way. It
+ automatically prepends a prefix to its argument, so we can refer to the
+ files with their actual \CONTEXT name.
+
+--doc]]--
+
+local make_loader_name = function (prefix, name)
+ local msg = luaotfload.log and luaotfload.log.report
+ or function (stream, lvl, cat, ...)
+ if lvl > 1 then --[[not pressing]] return end
+ texio.write_nl ("log",
+ string.format ("luaotfload | %s : ",
+ tostring (cat)))
+ texio.write (string.format (...))
+ end
+ if not name then
+ msg ("both", 0, "load",
+ "Fatal error: make_loader_name (“%sâ€, “%sâ€).",
+ tostring (prefix), tostring (name))
+ return "dummy-name"
+ end
+ name = tostring (name)
+ if prefix == false then
+ msg ("log", 9, "load",
+ "No prefix requested, passing module name “%s†unmodified.",
+ name)
+ return tostring (name) .. ".lua"
+ end
+ prefix = tostring (prefix)
+ msg ("log", 9, "load",
+ "Composing module name from constituents %s, %s.",
+ prefix, name)
+ return prefix .. "-" .. name .. ".lua"
+end
+
+local timing_info = {
+ t_load = { },
+ t_init = { },
+}
+
+local make_loader = function (prefix)
+ return function (name)
+ local t_0 = osgettimeofday ()
+ local modname = make_loader_name (prefix, name)
+ --- We don’t want the stack info from inside, so just pcall().
+ local ok, data = pcall (require, modname)
+ local t_end = osgettimeofday ()
+ timing_info.t_load [name] = t_end - t_0
+ if not ok then
+ io.write "\n"
+ local msg = luaotfload.log and luaotfload.log.report or print
+ msg ("both", 0, "load", "FATAL ERROR")
+ msg ("both", 0, "load", " × Failed to load module %q.",
+ tostring (modname))
+ local lines = string.split (data, "\n\t")
+ if not lines then
+ msg ("both", 0, "load", " × Error message: %q", data)
+ else
+ msg ("both", 0, "load", " × Error message:")
+ for i = 1, #lines do
+ msg ("both", 0, "load", " × %q.", lines [i])
+ end
+ end
+ io.write "\n\n"
+ local debug = debug
+ if debug then
+ io.write (debug.traceback())
+ io.write "\n\n"
+ end
+ os.exit(-1)
+ end
+ return data
+ end
+end
+
+--[[doc--
+ Certain files are kept around that aren’t loaded because they are part of
+ the imported fontloader. In order to keep the initialization structure
+ intact we also provide a no-op version of the module loader that can be
+ called in the expected places.
+--doc]]--
+
+local dummy_loader = function (name)
+ luaotfload.log.report ("log", 3, "load",
+ "Skipping module “%s†on purpose.",
+ name)
+end
+
+local context_loader = function (name, path)
+ luaotfload.log.report ("log", 3, "load",
+ "Loading module “%s†from Context.",
+ name)
+ local t_0 = osgettimeofday ()
+ local modname = make_loader_name (false, name)
+ local modpath = modname
+ if path then
+ if lfs.isdir (path) then
+ luaotfload.log.report ("log", 3, "load",
+ "Prepending path “%sâ€.",
+ path)
+ modpath = file.join (path, modname)
+ else
+ luaotfload.log.report ("both", 0, "load",
+ "Non-existant path “%s†specified, ignoring.",
+ path)
+ end
+ end
+ local ret = require (modpath)
+ local t_end = osgettimeofday ()
+ timing_info.t_load [name] = t_end - t_0
+
+ if ret ~= true then
+ --- require () returns “true†upon success unless the loaded file
+ --- yields a non-zero exit code. This isn’t per se indicating that
+ --- something isn’t right, but against HH’s coding practices. We’ll
+ --- silently ignore this ever happening on lower log levels.
+ luaotfload.log.report ("log", 4, "load",
+ "Module “%s†returned “%sâ€.", ret)
+ end
+ return ret
+end
+
+local install_loaders = function ()
+ local loaders = { }
+ local loadmodule = make_loader "luaotfload"
+ loaders.luaotfload = loadmodule
+ loaders.fontloader = make_loader "fontloader"
+ loaders.context = context_loader
+ loaders.ignore = dummy_loader
+----loaders.plaintex = make_loader "luatex" --=> for Luatex-Plain
+
+ loaders.initialize = function (name)
+ local tmp = loadmodule (name)
+ local logreport = luaotfload.log.report
+ local init = type(tmp) == "table" and tmp.init or tmp
+ if init and type (init) == "function" then
+ local t_0 = osgettimeofday ()
+ if not init () then
+ logreport ("log", 0, "load",
+ "Failed to load module “%sâ€.", name)
+ return
+ end
+ local t_end = osgettimeofday ()
+ local d_t = t_end - t_0
+ logreport ("log", 4, "load",
+ "Module “%s†loaded in %d ms.",
+ name, d_t)
+ timing_info.t_init [name] = d_t
+ end
+ end
+
+ return loaders
+end
+
+local luaotfload_initialized = false --- prevent multiple invocations
+
+luaotfload.main = function ()
+
+ if luaotfload_initialized then
+ logreport ("log", 0, "load",
+ "Luaotfload initialization requested but is already \z
+ loaded, ignoring.")
+ return
+ end
+ luaotfload_initialized = true
+
+ luaotfload.loaders = install_loaders ()
+ local loaders = luaotfload.loaders
+ local loadmodule = loaders.luaotfload
+ local initialize = loaders.initialize
+
+ local starttime = osgettimeofday ()
+ local init = loadmodule "init" --- fontloader initialization
+ local store = init.early () --- injects the log module too
+ local logreport = luaotfload.log.report
+
+ initialize "parsers" --- fonts.conf and syntax
+ initialize "configuration" --- configuration options
+
+ if not init.main (store) then
+ logreport ("log", 0, "load", "Main fontloader initialization failed.")
+ end
+
+ initialize "loaders" --- Font loading; callbacks
+ initialize "database" --- Font management.
+ initialize "colors" --- Per-font colors.
+
+ local init_resolvers = loadmodule "resolvers" --- Font lookup
+ init_resolvers ()
+
+ if not config.actions.reconfigure () then
+ logreport ("log", 0, "load", "Post-configuration hooks failed.")
+ end
+
+ initialize "features" --- font request and feature handling
+ loadmodule "letterspace" --- extra character kerning
+ loadmodule "embolden" --- fake bold
+ loadmodule "notdef" --- missing glyph handling
+ initialize "auxiliary" --- additional high-level functionality
+
+ luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec
+
+ logreport ("both", 0, "main",
+ "initialization completed in %0.3f seconds\n",
+ osgettimeofday() - starttime)
+----inspect (timing_info)
+end
+
+-- vim:tw=79:sw=4:ts=4:et
diff --git a/macros/luatex/generic/luaotfload/luaotfload-main.tex b/macros/luatex/generic/luaotfload/luaotfload-main.tex
new file mode 100644
index 0000000000..424b4e0fa8
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-main.tex
@@ -0,0 +1,2035 @@
+%% Copyright (C) 2009-2018
+%%
+%% by Elie Roux <elie.roux@telecom-bretagne.eu>
+%% and Khaled Hosny <khaledhosny@eglug.org>
+%% and Philipp Gesang <phg@phi-gamma.net>
+%%
+%% This file is part of Luaotfload.
+%%
+%% Home: https://github.com/lualatex/luaotfload
+%% Support: <lualatex-dev@tug.org>.
+%%
+%% Luaotfload is under the GPL v2.0 (exactly) license.
+%%
+%% ----------------------------------------------------------------------------
+%%
+%% Luaotfload is free software; you can redistribute it and/or
+%% modify it under the terms of the GNU General Public License
+%% as published by the Free Software Foundation; version 2
+%% of the License.
+%%
+%% Luaotfload is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%% GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with Luaotfload; if not, see <http://www.gnu.org/licenses/>.
+%%
+%% ----------------------------------------------------------------------------
+%%
+
+\beginfrontmatter
+
+ \setdocumenttitle {The \identifier{luaotfload} package}
+ \setdocumentdate {2019-08-11 v2.991}
+ \setdocumentauthor {Elie Roux · Khaled Hosny · Philipp Gesang · Ulrike Fischer\\
+ Home: \hyperlink {https://github.com/lualatex/luaotfload}\\
+ New Home: \hyperlink {https://github.com/u-fischer/luaotfload}\\
+ Support: \email {lualatex-dev@tug.org}}
+
+ \typesetdocumenttitle
+
+ \beginabstractcontent
+ This package is an adaptation of the \CONTEXT font loading system.
+ It allows for loading \OpenType fonts with an extended syntax and adds
+ support for a variety of font features.
+
+ After discussion of the font loading API, this manual gives an
+ overview of the core components of \identifier{Luaotfload}: The
+ packaged font loader code, the names database, configuration, and
+ helper functions on the \LUA\ end.
+ \endabstractcontent
+
+\endfrontmatter
+
+\pdfbookmark[1]{\contentsname}{table}
+\typesetcontent
+\beginsection {New in version 2.99 (by Ulrike Fischer)}
+\begin{itemize}
+\item Code cleanup.
+\item The fontloader has been synched with the context files from 2019-08-11.
+\end{itemize}
+\endsection
+\beginsection {New in version 2.98 (by Ulrike Fischer)}
+\begin{itemize}
+\item The\marginpar{\mbox{}\hfill \textbf{breaking change!}} handling of missing chars has been changed. In This version a missing char will insert the \inlinecode{/.notdef} char of the fonts (this is sometimes a space, sometimes a rectangle with a cross) and no longer simply ignore the glyph. This behaviour can be reverted by using \inlinecode{notdef=false} as font feature.
+\item The font feature \inlinecode{embolden} can now be used to fake a bold font.
+\item The fontloader has been synched with the context files from 2019-07-04.
+\end{itemize}
+\endsection
+\beginsection {New in version 2.97 (by Ulrike Fischer)}
+\begin{itemize}
+\item the new generic fontloader improves the handling of large fonts (but some fonts still need a 64bit luatex version to create the font files).
+\item A number of small bug (also in luaotfload-tool) have been corrected, see the NEWS file for details.
+
+\end{itemize}
+\endsection
+
+\beginsection {New in version 2.96 (by Ulrike Fischer)}
+\begin{itemize}
+\item In\marginpar{\mbox{}\hfill \textbf{Incompatible change!}}
+version 2.95 letterspacing was broken due to a change in the fontloader (issue 38). This has been repaired. At the same time a number of oddities and bugs in the letterspacing has been corrected. This can change existing documents. See page~\pageref{p:letterspace} for more information.
+
+\item A problem with the detection of bold fonts has been corrected (issue 41, pull request 42).
+
+\end{itemize}
+\endsection
+
+
+
+\beginsection {New in version 2.95 (by Ulrike Fischer)}
+\begin{itemize}
+\item
+This version imports from context the generic fontloader in the version of 2019-01-28. Contrary to the last announcement, it still works with luatex 1.07. So updates will continue.
+
+\item The handling of the lucida-fonts had been improved (issue 33).
+
+\item tex-files are no longer misused as font fallbacks (issue 35).
+
+\item The resolver code has be refactorated (pull request 36).
+
+\end{itemize}
+\endsection
+\beginsection {New in version 2.94 (by Ulrike Fischer)}
+\begin{itemize}
+\item
+This version imports from context the generic fontloader in the version of 2018-12-19. It is the last version that works with luatex 1.07 and texlive 2018. As context has moved to luatex 1.09 newer versions of the fontloader needs now this luatex version too. This means that until the texlive 2018 freeze there will be probably no update of luaotfload.
+
+\item This version changes the handling of the \inlinecode{mode} key. It no longer accepts only the values \inlinecode{base} and \inlinecode{node}, but can be used to load a font with an alternative font loader/renderer.
+
+
+\end{itemize}
+\endsection
+
+\beginsection {New in version 2.93 (by Ulrike Fischer)}
+Mainly internal clean up of the version info to allow automatic versioning.
+\endsection
+
+\beginsection {New in version 2.92 (by Ulrike Fischer)}
+
+\begin{itemize}
+
+ \item Better devanagari support (issue \#9).
+ \item \identifier{Luaotfload} doesn't work when luatex is used with the option \inlinecode{--safer}. So it now aborts cleanly when the option is detected -- but you still can get errors from fontspec later! (issue \#12).
+ \item The syntax \inlinecode{file:} for legacy font works again (issue \#11).
+ \item The fontloader has been synched with the newest context version from october, 18.
+\end{itemize}
+\endsection
+\beginsection {New in version 2.91 (by Ulrike Fischer)}
+
+This version mostly correct two bugs found in the previous fontloader: Glyphvariants weren't copied and pasted correctly. Glyphs encoded in the PUA couldn't be accessed anymore.
+
+\endsection
+
+
+\beginsection {New in version 2.9 (by Ulrike Fischer)}
+
+On the one side there is not very much new in this version: The native components of \identifier{Luaotfload} are nearly unchanged. A few bugs have been corrected, the various files lists which loads the components of the font loader have been cleaned up.
+
+On the other side there is a lot new:
+
+\begindescriptions
+
+ \beginaltitem {Fontloader} The fontloader files imported from \CONTEXT\ have been updated to the current version.
+ This was necessary to make \identifier{Luaotfload} compatible with the coming \LUATEX 1.08/1.09. Compared to the previous version from february 2017 quite a number of things have changed. Most importantly the handling of arabic fonts has greatly improved. But this also means that changes in the output are possible.
+ \endaltitem
+
+ \beginaltitem {Lualibs} The update of the fontloader files also required an update of the \identifier{Lualibs} package. This \identifier{Luaotfload} version needs version 2.6 of \identifier{Lualibs}.
+ \endaltitem
+
+ \beginaltitem {Maintenance} As the current maintainer wasn't available and it was urgent to get a \identifier{Luaotfload} compatible with \LUATEX 1.08/1.09 maintenance has been transfered to Ulrike Fischer and Marcel Krüger. The package is currently maintained and developed at \hyperlink{https://github.com/u-fischer/luaotfload}. Issues should be reported there.
+ \endaltitem
+
+ \beginaltitem {Documentation}
+ The core of documentation is nearly unchanged. I added this introduction. I recreated with the help of @marmot the graphic on \pageref{file-graph}. I updated the file lists. I imported as appendix pdf versions of the two man files which are part of the \identifier{Luaotfload} documentation.
+ \endaltitem
+
+\enddescriptions
+
+\endsection
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Introduction}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Font management and installation has always been painful with \TEX. A
+lot of files are needed for one font (\abbrev{tfm}, \abbrev{pfb},
+\abbrev{map}, \abbrev{fd}, \abbrev{vf}), and due to the 8-Bit encoding
+each font is limited to 256 characters.
+
+But the font world has evolved since the original \TEX, and new
+typographic systems have appeared, most notably the so called
+\emphasis{smart font} technologies like \OpenType fonts (\abbrev{otf}).
+
+These fonts can contain many more characters than \TEX fonts, as well
+as additional functionality like ligatures, old-style numbers, small
+capitals, etc., and support more complex writing systems like Arabic
+and Indic\footnote{%
+ Unfortunately, \identifier{luaotfload} doesn‘t support many Indic
+ scripts right now.
+ Assistance in implementing the prerequisites is greatly
+ appreciated.
+}
+scripts.
+
+\OpenType fonts are widely deployed and available for all modern
+operating systems.
+
+As of 2013 they have become the de facto standard for advanced text
+layout.
+
+However, until recently the only way to use them directly in the \TEX
+world was with the \XETEX engine.
+
+Unlike \XETEX, \LUATEX has no built-in support for \OpenType or
+technologies other than the original \TEX fonts.
+
+Instead, it provides hooks for executing \LUA code during the \TEX run
+that allow implementing extensions for loading fonts and manipulating
+how input text is processed without modifying the underlying engine.
+
+This is where \identifier{luaotfload} comes into play:
+Based on code from \CONTEXT, it extends \LUATEX with functionality necessary
+for handling \OpenType fonts.
+
+Additionally, it provides means for accessing fonts known to the operating
+system conveniently by indexing the metadata.
+
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Thanks}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\identifier{Luaotfload} is part of \LUALATEX, the community-driven
+project to provide a foundation for using the \LATEX format with the
+full capabilites of the \LUATEX engine.
+%
+As such, the distinction between end users, contributors, and project
+maintainers is intentionally kept less strict, lest we unduly
+personalize the common effort.
+
+Nevertheless, the current maintainers would like to express their
+gratitude to Khaled Hosny, Akira Kakuto, Hironori Kitagawa and Dohyun
+Kim.
+%
+Their contributions -- be it patches, advice, or systematic
+testing -- made the switch from version 1.x to 2.2 possible.
+%
+Also, Hans Hagen, the author of the font loader, made porting the
+code to \LATEX a breeze due to the extra effort he invested into
+isolating it from the rest of \CONTEXT, not to mention his assistance
+in the task and willingness to respond to our suggestions.
+
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Loading Fonts}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\identifier{luaotfload} supports an extended font request syntax:
+
+\beginnarrower
+ \nonproportional{\string\font\string\foo\space= \string{}%
+ \meta{prefix}\nonproportional{:}%
+ \meta{font name}\nonproportional{:}%
+ \meta{font features}\nonproportional{\string}}%
+ \meta{\TEX font features}
+\endnarrower
+
+\noindent
+The curly brackets are optional and escape the spaces in the enclosed
+font name.
+%
+Alternatively, double quotes serve the same purpose.
+%
+A selection of individual parts of the syntax are discussed below;
+for a more formal description see figure \ref{font-syntax}.
+
+\beginsyntaxfloat
+ {font-syntax}
+ {Font request syntax.
+ Braces or double quotes around the
+ \emphasis{specification} rule will
+ preserve whitespace in file names.
+ In addition to the font style modifiers
+ (\emphasis{slash-notation}) given above, there
+ are others that are recognized but will be silently
+ ignored: \nonproportional{aat},
+ \nonproportional{icu}, and
+ \nonproportional{gr}.
+ The special terminals are:
+ \smallcaps {feature\textunderscore id} for a valid font
+ feature name and
+ \smallcaps {feature\textunderscore value} for the corresponding
+ value.
+ \smallcaps {tfmname} is the name of a \abbrev{tfm} file.
+ \smallcaps {digit} again refers to bytes 48--57, and
+ \smallcaps {all\textunderscore characters} to all byte values.
+ \smallcaps {csname} and \smallcaps {dimension} are the \TEX concepts.}
+%
+ <definition> ::= `\\font', {\sc csname}, `=', <font request>, [ <size> ] ;
+
+ <size> ::= `at', {\sc dimension} ;
+
+ <font request> ::= `"', <unquoted font request> `"'
+ \alt `{', <unquoted font request> `}'
+ \alt <unquoted font request> ;
+
+ <unquoted font request> ::= <specification>, [`:', <feature list> ]
+ \alt <path lookup>, [ [`:'], <feature list> ] ;
+
+ <specification> ::= <prefixed spec>, [ <subfont no> ], \{ <modifier> \}
+ \alt <anon lookup>, \{ <modifier> \} ;
+
+ <prefixed spec> ::= `combo:', <combo list>
+ \alt `file:', <file lookup>
+ \alt `name:', <name lookup> ;
+
+ <combo list> ::= <combo def 1>, \{ `;', <combo def> \} ;
+
+ <combo def 1> ::= <combo id>, `->', <combo id> ;
+
+ <combo def> ::= <combo id>, `->', <combo id chars> ;
+
+ <combo id> ::= (`(', \{ {\sc digit} \}, `)' | \{ {\sc digit} \} ) ;
+
+ <combo id chars> ::= (`(', \{ {\sc digit} \}, `,', <combo chars>, `)'
+ \alt \{ {\sc digit} \} ) ;
+
+ <combo chars> ::= `fallback'
+ \alt \{ <combo range>, \{ `*', <combo range> \} \} ;
+
+ <combo range> ::= <combo num>, [ `-', <combo num> ] ;
+
+ <combo num> ::= `0x', \{ {\sc hexdigit} \}
+ \alt `U+', \{ {\sc digit} \}
+ \alt \{ {\sc digit} \} ;
+
+ <file lookup> ::= \{ <name character> \} ;
+
+ <name lookup> ::= \{ <name character> \} ;
+
+ <anon lookup> ::= {\sc tfmname} | <name lookup> ;
+
+ <path lookup> ::= `[', \{ <path content> \}, `]', [ <subfont no> ] ;
+
+ <path content> ::= <path balanced>
+ \alt `\\', {\sc all_characters}
+ \alt {\sc all_characters} - `]'
+
+ <path balanced> ::= `[', [ <path content> ], `]'
+
+ <modifier> ::= `/', (`I' | `B' | `BI' | `IB' | `S=', \{ {\sc digit} \} ) ;
+
+ <subfont no> ::= `(', \{ {\sc digit} \}, `)' ;
+
+ <feature list> ::= <feature expr>, \{ `;', <feature expr> \} ;
+
+ <feature expr> ::= {\sc feature_id}, `=', {\sc feature_value}
+ \alt <feature switch>, {\sc feature_id} ;
+
+ <feature switch> ::= `+' | `-' ;
+
+ <name character> ::= {\sc all_characters} - ( `(' | `/' | `:' ) ;
+\endsyntaxfloat
+
+%% Below guarded space gets borked in index; why‽
+\beginsubsection{Prefix -- the \texorpdfstring{\identifier{luaotfload}}{luaotfload}{ }Way}
+
+In \identifier{luaotfload}, the canonical syntax for font requests
+requires a \emphasis{prefix}:
+%
+\beginnarrower
+ \nonproportional{\string\font\string\fontname\space= }%
+ \meta{prefix}%
+ \nonproportional{:}%
+ \meta{fontname}%
+ \dots
+\endnarrower
+%
+where \meta{prefix} is either \inlinecode{file:} or \inlinecode {name:}.\footnote{%
+ \identifier{Luaotfload} also knows two further prefixes, \inlinecode {kpse:}
+ and \inlinecode {my:}.
+ %
+ A \inlinecode {kpse} lookup is restricted to files that can be found by
+ \identifier{kpathsea} and will not attempt to locate system fonts.
+ %
+ This behavior can be of value when an extra degree of encapsulation is
+ needed, for instance when supplying a customized tex distribution.
+
+ The \inlinecode {my} lookup takes this a step further: it lets you define
+ a custom resolver function and hook it into the \luaident{resolve_font}
+ callback.
+ %
+ This ensures full control over how a file is located.
+ %
+ For a working example see the
+ \hyperlink [test in the luaotfload
+ repo]{https://github.com/u-fischer/luaotfload/blob/master/testfiles/my-resolver.lvt}.
+}
+%
+It determines whether the font loader should interpret the request as
+a \emphasis{file name} or
+ \emphasis{font name}, respectively,
+which again influences how it will attempt to locate the font.
+%
+Examples for font names are
+ “Latin Modern Italicâ€,
+ “GFS Bodoni Rgâ€, and
+ “PT Serif Captionâ€
+-- they are the human readable identifiers
+usually listed in drop-down menus and the like.\footnote{%
+ Font names may appear like a great choice at first because they
+ offer seemingly more intuitive identifiers in comparison to arguably
+ cryptic file names:
+ %
+ “PT Sans Bold†is a lot more descriptive than \fileent{PTS75F.ttf}.
+ On the other hand, font names are quite arbitrary and there is no
+ universal method to determine their meaning.
+ %
+ While \identifier{luaotfload} provides fairly sophisticated heuristic
+ to figure out a matching font style, weight, and optical size, it
+ cannot be relied upon to work satisfactorily for all font files.
+ %
+ For an in-depth analysis of the situation and how broken font names
+ are, please refer to
+ \hyperlink [this post]{http://www.ntg.nl/pipermail/ntg-context/2013/073889.html}
+ by Hans Hagen, the author of the font loader.
+ %
+ If in doubt, use filenames.
+ %
+ \fileent{luaotfload-tool} can perform the matching for you with the
+ option \inlinecode {--find=<name>}, and you can use the file name it returns
+ in your font definition.
+}
+%
+In order for fonts installed both in system locations and in your
+\fileent{texmf} to be accessible by font name, \identifier{luaotfload} must
+first collect the metadata included in the files.
+%
+Please refer to section~\ref{sec:fontdb} below for instructions on how to
+create the database.
+
+File names are whatever your file system allows them to be, except
+that that they may not contain the characters
+ \inlinecode {(},
+ \inlinecode {:}, and
+ \inlinecode {/}.
+%
+As is obvious from the last exception, the \inlinecode {file:} lookup will
+not process paths to the font location -- only those
+files found when generating the database are addressable this way.
+%
+Continue below in the \XETEX section if you need to load your fonts
+by path.
+%
+The file names corresponding to the example font names above are
+ \fileent{lmroman12-italic.otf},
+ \fileent{GFSBodoni.otf}, and
+ \fileent{PTZ56F.ttf}.
+
+\endsubsection
+
+\beginsubsection {Bracketed Lookups}
+\label{sec:bracket}
+Bracketed lookups allow for arbitrary character content to be used in a
+definition.
+%
+A simple bracketed request looks follows the scheme
+
+\beginnarrower
+ \nonproportional{\string\font\string\fontname\space = [}%
+ \meta{/path/to/file}%
+ \nonproportional{]}
+\endnarrower
+
+\noindent
+Inside the square brackets, every character except for a closing bracket is
+permitted, allowing for arbitrary paths to a font file -- including Windows
+style paths with UNC or drive letter prepended -- to be specified.
+%
+The \identifier{Luaotfload} syntax differs from \XETEX in that the subfont
+selector goes \emphasis{after} the closing bracket:
+
+\beginnarrower
+ \nonproportional{\string\font\string\fontname\space = [}%
+ \meta{/path/to/file}%
+ \nonproportional{]}
+ \nonproportional{(}n\nonproportional{)}
+\endnarrower
+
+Naturally, path-less file names are equally valid and processed the
+same way as an ordinary \inlinecode {file:} lookup.
+
+\beginsubsection {Compatibility}
+
+In addition to the regular prefixed requests, \identifier{luaotfload}
+accepts loading fonts the \XETEX way.
+%
+There are again two modes: bracketed and unbracketed.
+For the bracketed variety, see above, \ref{sec:bracket}.
+
+Unbracketed (or, for lack of a better word: \emphasis{anonymous})
+font requests resemble the conventional \TEX syntax.
+
+\beginnarrower
+ \nonproportional{\string\font\string\fontname\space= }%
+ \meta{font name}
+ \dots
+\endnarrower
+\endsubsection
+
+However, they have a broader spectrum of possible interpretations:
+before anything else, \identifier{luaotfload} attempts to load a
+traditional \TEX Font Metric (\abbrev{tfm} or \abbrev{ofm}).
+%
+If this fails, it performs a \inlinecode {path:} lookup, which itself will
+fall back to a \inlinecode {file:} lookup.
+%
+Lastly, if none of the above succeeded, attempt to resolve the request as a
+\inlinecode {name:} lookup by searching the font index for \meta{font name}.
+%
+The behavior of this “anonymous†lookup is configurable, see the configuation
+manpage for details.
+
+Furthermore, \identifier{luaotfload} supports the slashed (shorthand)
+font style notation from \XETEX.
+
+\beginnarrower
+ \nonproportional{\string\font\string\fontname\space= }%
+ \meta{font name}%
+ \nonproportional{/}%
+ \meta{modifier}
+ \dots
+\endnarrower
+
+\noindent
+Currently, four style modifiers are supported:
+ \inlinecode {I} for italic shape,
+ \inlinecode {B} for bold weight,
+ \inlinecode {BI} or \inlinecode {IB} for the combination of both.
+%
+Other “slashed†modifiers are too specific to the \XETEX engine and
+have no meaning in \LUATEX.
+
+\endsubsection
+
+\beginsubsection{Examples}
+
+\beginsubsubsection{Loading by File Name}
+
+For example, conventional \TeX\ font can be loaded with a
+\inlinecode {file:} request like so:
+
+\beginlisting
+ \font \lmromanten = {file:ec-lmr10} at 10pt
+\endlisting
+
+The \OpenType version of Janusz Nowacki’s font \emphasis{Antykwa
+Półtawskiego}\footnote{%
+ \hyperlink {http://jmn.pl/antykwa-poltawskiego/}, also available in
+ in \TEX Live.
+}
+in its condensed variant can be loaded as follows:
+
+\beginlisting
+ \font \apcregular = file:antpoltltcond-regular.otf at 42pt
+\endlisting
+
+The next example shows how to load the \emphasis{Porson} font digitized by
+the Greek Font Society using \XETEX-style syntax and an absolute path from a
+non-standard directory:
+
+\beginlisting
+ \font \gfsporson = "[/tmp/GFSPorson.otf]" at 12pt
+\endlisting
+
+\identifier{TrueType} collection files (the extension is usually
+\inlinecode{.ttc}) contain more than a single font. In order to refer to these
+subfonts, the respective index may be added in parentheses after the file
+name.\footnote{%
+ Incidentally, this syntactical detail also prevents one from loading files
+ that end in balanced parentheses.
+}
+
+\beginlisting
+ \font \cambriamain = "file:cambria.ttc(0)" at 10pt
+ \font \cambriamath = "file:cambria.ttc(1)" at 10pt
+\endlisting
+
+and likewise, requesting subfont inside a TTC container by path:
+
+\beginlisting
+ \font \asanamain = "[/home/typesetter/.fonts/math/asana.ttc](0):mode=node;+tlig" at 10pt
+ \font \asanamath = "[/home/typesetter/.fonts/math/asana.ttc](1):mode=base" at 10pt
+\endlisting
+
+\endsubsubsection
+
+\beginsubsubsection{Loading by Font Name}
+
+The \inlinecode {name:} lookup does not depend on cryptic filenames:
+
+\beginlisting
+ \font \pagellaregular = {name:TeX Gyre Pagella} at 9pt
+\endlisting
+
+A bit more specific but essentially the same lookup would be:
+
+\beginlisting
+ \font \pagellaregular = {name:TeX Gyre Pagella Regular} at 9pt
+\endlisting
+
+\noindent
+Which fits nicely with the whole set:
+
+\beginlisting
+ \font\pagellaregular = {name:TeX Gyre Pagella Regular} at 9pt
+ \font\pagellaitalic = {name:TeX Gyre Pagella Italic} at 9pt
+ \font\pagellabold = {name:TeX Gyre Pagella Bold} at 9pt
+ \font\pagellabolditalic = {name:TeX Gyre Pagella Bolditalic} at 9pt
+
+ {\pagellaregular foo bar baz\endgraf}
+ {\pagellaitalic foo bar baz\endgraf}
+ {\pagellabold foo bar baz\endgraf}
+ {\pagellabolditalic foo bar baz\endgraf}
+
+ ...
+\endlisting
+
+\endsubsubsection
+
+\beginsubsubsection{Modifiers}
+
+If the entire \emphasis{Iwona} family\footnote{%
+ \hyperlink {http://jmn.pl/kurier-i-iwona/},
+ also in \TEX Live.
+}
+is installed in some location accessible by \identifier{luaotfload},
+the regular shape can be loaded as follows:
+
+\beginlisting
+ \font \iwona = Iwona at 20pt
+\endlisting
+
+\noindent
+To load the most common of the other styles, the slash notation can
+be employed as shorthand:
+
+\beginlisting
+ \font \iwonaitalic = Iwona/I at 20pt
+ \font \iwonabold = Iwona/B at 20pt
+ \font \iwonabolditalic = Iwona/BI at 20pt
+\endlisting
+
+\noindent
+which is equivalent to these full names:
+
+\beginlisting
+ \font \iwonaitalic = "Iwona Italic" at 20pt
+ \font \iwonabold = "Iwona Bold" at 20pt
+ \font \iwonabolditalic = "Iwona BoldItalic" at 20pt
+\endlisting
+
+\endsubsubsection
+\endsubsection
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Font features}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\emphasis{Font features} are the second to last component in the
+general scheme for font requests:
+
+\beginnarrower
+ \nonproportional{\string\font\string\foo\space= "}%
+ \meta{prefix}%
+ \nonproportional{:}%
+ \meta{font name}%
+ \nonproportional{:}%
+ \meta{font features}%
+ \meta{\TEX font features}%
+ \nonproportional{"}
+\endnarrower
+
+\noindent
+If style modifiers are present (\XETEX style), they must precede
+\meta{font features}.
+
+The element \meta{font features} is a semicolon-separated list of feature
+tags\footnote{%
+ Cf. \hyperlink {http://www.microsoft.com/typography/otspec/featurelist.htm}.
+}
+and font options.
+%
+Prepending a font feature with a \inlinecode{+} (plus sign) enables it,
+whereas a \inlinecode{-} (minus) disables it. For instance, the request
+
+\beginlisting
+ \font \test = LatinModernRoman:+clig;-kern
+\endlisting
+
+\noindent activates contextual ligatures (\inlinecode{clig}) and
+disables kerning (\inlinecode{kern}).
+%
+Alternatively the options \inlinecode{true} or \inlinecode{false} can
+be passed to the feature in a key/value expression.
+%
+The following request has the same meaning as the last one:
+
+\beginlisting
+ \font \test = LatinModernRoman:clig=true;kern=false
+\endlisting
+
+\noindent
+Furthermore, this second syntax is required should a font feature
+accept other options besides a true/false switch.
+%
+For example, \emphasis{stylistic alternates} (\inlinecode{salt}) are
+variants of given glyphs.
+%
+They can be selected either explicitly by supplying the variant
+index (starting from one), or randomly by setting the value to,
+obviously, \inlinecode{random}.
+
+%% TODO verify that this actually works with a font that supports
+%% the salt/random feature!\fi
+\beginlisting
+ \font \librmsaltfirst = LatinModernRoman:salt=1
+\endlisting
+
+\beginsubsection {Basic font features}\label{sec:mode}
+
+\begindescriptions
+
+ \beginaltitem {mode}
+ Until version 2.94
+ \identifier{luaotfload} had two \OpenType processing
+ \emphasis{modes}:
+ \identifier{base} and \identifier{node}.
+
+ \identifier{base} mode works by mapping \OpenType
+ features to traditional \TEX ligature and kerning mechanisms.
+ %
+ Supporting only non-contextual substitutions and kerning
+ pairs, it is the slightly faster, albeit somewhat limited, variant.
+ %
+ \identifier{node} mode works by processing \TeX’s internal
+ node list directly at the \LUA end and supports
+ a wider range of \OpenType features.
+ %
+ The downside is that the intricate operations required for
+ \identifier{node} mode may slow down typesetting especially
+ with complex fonts and it does not work in math mode.
+
+ By default \identifier{luaotfload} is in \identifier{node}
+ mode, and \identifier{base} mode has to be requested where needed,
+ e.~g. for math fonts.
+
+ Since version 2.94 it is possible to call other font renderers with the mode key. A simple example with a plain reader can be found at \hyperlink{https://github.com/u-fischer/luaotfload/pull/26\#issuecomment-437716326}.
+ A more useful example needs the new experimental harftex engine (windows binaries can be found at w32tex.org), and the harf renderer (\hyperlink{https://github.com/khaledhosny/harf}). With both it is possible to render a font using the harfbuzz library (used also by xetex).
+
+
+ \endaltitem
+
+ \beginaltitem {script} \label{script-tag}
+ An \OpenType script tag;\footnote{%
+ See \hyperlink {http://www.microsoft.com/typography/otspec/scripttags.htm}
+ for a list of valid values.
+ %
+ For scripts derived from the Latin alphabet the value
+ \inlinecode{latn} is good choice.
+ }
+ the default value is \inlinecode{dflt}.
+ %
+ Some fonts, including very popular ones by foundries like Adobe,
+ do not assign features to the \inlinecode{dflt} script, in
+ which case the script needs to be set explicitly.
+ \endaltitem
+
+ \beginaltitem {language}
+ An \OpenType language system identifier,\footnote{%
+ Cf. \hyperlink {http://www.microsoft.com/typography/otspec/languagetags.htm}.
+ }
+ defaulting to \inlinecode{dflt}.
+ \endaltitem
+
+ \beginaltitem {color}
+ A font color, defined as a triplet of two-digit hexadecimal
+ \abbrev{rgb} values, with an optional fourth value for
+ transparency
+ (where \inlinecode{00} is completely transparent and
+ \inlinecode{FF} is opaque).
+
+ For example, in order to set text in semitransparent red:
+
+ \beginlisting
+ \font \test = "Latin Modern Roman:color=FF0000BB"
+ \endlisting
+ \endaltitem
+
+
+ \beginaltitem {embolden}
+ A factor, defined as a decimal number.
+
+ For example
+
+ \beginlisting
+ \font\test = "Latin Modern Roman:mode=node;embolden=2;"
+ \endlisting
+
+ {\font\test= "Latin Modern Roman:mode=node;"\test Dies is not bold.
+ \font\test= "Latin Modern Roman:mode=node;embolden=2;" \test Dies is a faked bold font.}
+
+ \endaltitem
+
+ \beginaltitem {kernfactor \& letterspace}\label{p:letterspace}
+ Define a font with letterspacing (tracking) enabled.
+ %
+ In \identifier{luaotfload}, letterspacing is implemented by
+ inserting additional kerning between glyphs.
+
+ This approach is derived from and still quite similar to the
+ \emphasis{character kerning} (\texmacro{setcharacterkerning} /
+ \texmacro{definecharacterkerning} \& al.) functionality of
+ Context, see the file \fileent{typo-krn.lua} there.
+ %
+ The main difference is that \identifier{luaotfload} does not
+ use \LUATEX attributes to assign letterspacing to regions,
+ but defines virtual letterspaced versions of a font.
+
+ The option \identifier{kernfactor} accepts a numeric value that
+ determines the letterspacing factor to be applied to the font
+ size.
+ %
+ E.~g. a kern factor of $0.42$ applied to a $10$ pt font
+ results in $4.2$ pt of additional kerning applied to each
+ pair of glyphs.
+ %
+
+ Spaces\marginpar{\mbox{}\hfill NEW in v2.96!} between words are now stretched too. This is consistent with the \XETEX behaviour (and the amount of stretching should be similar). This
+ naturally changes the output of a document. In case you want the old behaviour back use
+ \beginlisting
+ \directlua{luaotfload.letterspace.keepwordspacing = true}
+ \endlisting
+
+ The difference between both options is obvious:
+
+ \begingroup
+ \fontspec{IwonaMedium-Regular.otf}[LetterSpace=60]
+ New: hello world
+
+ \directlua{luaotfload.letterspace.keepwordspacing = true}
+
+ Old: hello world
+
+ \directlua{luaotfload.letterspace.keepwordspacing = false}
+ \endgroup
+
+
+ Ligatures\marginpar{\mbox{}\hfill NEW in v2.96!} are no longer split into their component glyphs.
+ This change too make the \identifier{luaotfload} more compatible with \XETEX. It also makes it much easier to activate or deactivate ligature sets in letterspaced fonts.
+ If you want to split ligatures, you should deactivate as you would do it with a not-letterspaced font, e.g. with the fontspec \identifier{Ligatures} option, or the low-level \identifier{-liga} and similar.
+
+
+ {\font \test = "file:Iwona-Regular.otf:mode=base;+liga;+tlig;letterspace=12.5"
+ \test With standard ligatures: fi -- ff\par
+
+ \font \test = "file:Iwona-Regular.otf:mode=base;-liga;+tlig;letterspace=12.5"
+ \test Only with tlig: fi -- ff \par
+
+ \font \test = "file:Iwona-Regular.otf:mode=base;-liga;letterspace=12.5"
+ \test No ligatures: fi -- ff \par
+ }
+
+ For compatibility with \XETEX an alternative
+ \identifier{letterspace} option is supplied that interprets the
+ supplied value as a \emphasis{percentage} of the font size but
+ is otherwise identical to \identifier{kernfactor}.
+ %
+ Consequently, both definitions in below snippet yield the same
+ letterspacing width:
+
+ \beginlisting
+ \font \iwonakernedA = "file:Iwona-Regular.otf:kernfactor=0.125"
+ \font \iwonakernedB = "file:Iwona-Regular.otf:letterspace=12.5"
+ \endlisting
+
+ The \identifier{microtype} package uses a special implementation of letterspacing, and the commands \inlinecode{\lsstyle} and \inlinecode{\textls} are not affected by these changes.
+
+ Setting the ligatures with the font options is the recommended way, to activate or deactivate them. In case of special requirements
+ specific pairs of letters and ligatures may be exempt from
+ letterspacing by defining the \LUA functions
+ \luaident{keeptogether} and \luaident{keepligature},
+ respectively, inside the namespace \inlinecode {luaotfload.letterspace}.
+ %
+ Both functions are called whenever the letterspacing callback
+ encounters an appropriate node or set of nodes.
+ %
+ If they return a true-ish value, no extra kern is inserted at
+ the current position.
+ %
+ \luaident{keeptogether} receives a pair of consecutive
+ glyph nodes in order of their appearance in the node list.
+ %
+ \luaident{keepligature} receives a single node which can be
+ analyzed into components.
+ %
+ (For details refer to the \emphasis{glyph nodes} section in the
+ \LUATEX reference manual.)
+ %
+ The implementation of both functions is left entirely to the
+ user.
+ \endaltitem
+
+\iffalse
+ \startbuffer [printvectors]
+ \directlua{inspect(fonts.protrusions.setups.default)
+ inspect(fonts.expansions.setups.default)}
+ \stopbuffer
+\fi
+
+ \beginaltitem {protrusion \& expansion}
+ These keys control microtypographic features of the font,
+ namely \emphasis{character protrusion} and \emphasis{font
+ expansion}.
+ %
+ Their arguments are names of \LUA tables that contain
+ values for the respective features.\footnote{%
+ For examples of the table layout please refer to the
+ section of the file \fileent{luaotfload-fonts-ext.lua} where the
+ default values are defined.
+ %
+ Alternatively and with loss of information, you can dump
+ those tables into your terminal by issuing
+ \unless \iffalse
+ \beginlisting
+ \directlua{inspect(fonts.protrusions.setups.default)
+ inspect(fonts.expansions.setups.default)}
+ \endlisting
+ \else
+ \typebuffer [printvectors]
+ \fi
+ at some point after loading \fileent{luaotfload.sty}.
+ }
+ %
+ For both, only the set \identifier{default} is predefined.
+
+ For example, to define a font with the default
+ protrusion vector applied\footnote{%
+ You also need to set
+ \inlinecode {pdfprotrudechars=2} and
+ \inlinecode {pdfadjustspacing=2}
+ to activate protrusion and expansion, respectively.
+ See the
+ \hyperlink [\PDFTEX manual]{http://mirrors.ctan.org/systems/pdftex/manual/pdftex-a.pdf}%
+ for details.
+ }:
+
+ \beginlisting
+ \font \test = LatinModernRoman:protrusion=default
+ \endlisting
+ \endaltitem
+\enddescriptions
+
+\endsubsection
+
+\beginsubsection {Non-standard font features}
+\identifier{luaotfload} adds a number of features that are not defined
+in the original \OpenType specification, most of them
+aiming at emulating the behavior familiar from other \TEX engines.
+%
+Currently (2014) there are three of them:
+
+\begindescriptions
+
+ \beginaltitem {anum}
+ Substitutes the glyphs in the \abbrev{ascii} number range
+ with their counterparts from eastern Arabic or Persian,
+ depending on the value of \identifier{language}.
+ \endaltitem
+
+ \beginaltitem {tlig}
+ Applies legacy \TEX ligatures\footnote{%
+ These contain the feature set \inlinecode {trep} of earlier
+ versions of \identifier{luaotfload}.
+
+ Note to \XETEX users: this is the equivalent of the
+ assignment \inlinecode {mapping=text-tex} using \XETEX's input
+ remapping feature.
+ }:
+
+ \unless \iffalse
+ %% Using braced arg syntax with inline code appears to be
+ %% impossible within Latex tables -- just ignore the weird
+ %% exclamation points below.
+ \begintabulate [rlrl]
+ \beginrow `` \newcell {\inlinecode !``! } \newcell '' \newcell {\inlinecode !''!} \endrow
+ \beginrow ` \newcell {\inlinecode !`! } \newcell ' \newcell {\inlinecode !'! } \endrow
+ \beginrow " \newcell {\inlinecode !"! } \newcell -- \newcell {\inlinecode !--!} \endrow
+ \beginrow --- \newcell {\inlinecode !---!} \newcell !` \newcell {\inlinecode ?!`?} \endrow
+ \beginrow ?` \newcell {\inlinecode !?`! } \newcell \newcell \endrow
+ \endtabulate
+ \else
+ %% XXX find a way to wrap these in the tabulate environment
+ \startframed [frame=off,width=broad,align=middle]
+ \startframed [frame=off,width=\dimexpr(\textwidth/2)]
+ \startxtable [align=middle]
+ \startxrow \startxcell `` \stopxcell \startxcell \inlinecode {``} \stopxcell \startxcell '' \stopxcell \startxcell \inlinecode {''} \stopxcell \stopxrow
+ \startxrow \startxcell ` \stopxcell \startxcell \inlinecode {`} \stopxcell \startxcell ' \stopxcell \startxcell \inlinecode {'} \stopxcell \stopxrow
+ \startxrow \startxcell " \stopxcell \startxcell \inlinecode {"} \stopxcell \startxcell -- \stopxcell \startxcell \inlinecode {--} \stopxcell \stopxrow
+ \startxrow \startxcell --- \stopxcell \startxcell \inlinecode {---} \stopxcell \startxcell !` \stopxcell \startxcell \inlinecode {!`} \stopxcell \stopxrow
+ \startxrow \startxcell ?` \stopxcell \startxcell \inlinecode {?`} \stopxcell \startxcell \stopxcell \startxcell \stopxcell \stopxrow
+ \stopxtable
+ \stopframed
+ \stopframed
+ \fi
+ \endaltitem
+
+ \beginaltitem {itlc}
+ Computes italic correction values (active by default).
+ \endaltitem
+
+\enddescriptions
+
+\endsubsection
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Combining fonts}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Version 2.7 and later support combining characters from multiple fonts into a
+single virtualized one. This requires that the affected fonts be loaded in
+advance as well as a special \emphasis{request syntax}. Furthermore, this
+allows to define \emphasis{fallback fonts} to supplement fonts that may lack
+certain required glyphs.
+
+Combinations are created by defining a font using the \luaident{combo:} prefix.
+
+\beginsubsection {Fallbacks}
+
+For example, the \identifier{Latin Modern} family of fonts does, as indicated
+in the name, not provide Cyrillic glyphs. If Latin script dominates in the copy
+with interspersed Cyrillic, a fallback can be created from a similiar looking
+font like \identifier{Computer Modern Unicode}, taking advantage of the fact
+that it too derives from Knuth’s original \identifier{Computer Modern} series:
+
+\beginlisting
+ \input luaotfload.sty
+ \font \lm = file:lmroman10-regular.otf:mode=base
+ \font \cmu = file:cmunrm.otf:mode=base
+ \font \lmu = "combo: 1->\fontid\lm; 2->\fontid\cmu,fallback"
+ \lmu Eh bien, mon prince. Gênes et Lueques ne sont plus que des
+ apanages, des помеÑÑ‚ÑŒÑ, de la famille Buonaparte.
+ \bye
+\endlisting
+
+As simple as this may look on the first glance, this approach is entirely
+inappropriate if more than a couple letters are required from a different font.
+Because the combination pulls nothing except the glyph data, all of the
+important other information that constitute a proper font -- kerning, styles,
+features, and suchlike -- will be missing.
+
+\endsubsection %% Fallbacks
+
+\beginsubsection {Combinations}
+
+Generalizing the idea of a \emphasis{fallback font}, it is also possible to
+pick definite sets of glyphs from multiple fonts. On a bad day, for instance,
+it may be the sanest choice to start out with \identifier{EB Garamond} italics,
+typeset all decimal digits in the bold italics of \identifier{GNU Freefont},
+and tone down the punctuation with extra thin glyphs from \identifier{Source
+Sans}:
+
+\beginlisting
+ \def \feats {-tlig;-liga;mode=base;-kern}
+ \def \fileone {EBGaramond12-Italic.otf}
+ \def \filetwo {FreeMonoBoldOblique.otf}
+ \def \filethree {SourceSansPro-ExtraLight.otf}
+
+ \input luaotfload.sty
+
+ \font \one = file:\fileone :\feats
+ \font \two = file:\filetwo :\feats
+ \font \three = file:\filethree:\feats
+
+ \font \onetwothree = "combo: 1 -> \fontid\one;
+ 2 -> \fontid\two, 0x30-0x39;
+ 3 -> \fontid\three, 0x21*0x3f; "
+
+ {\onetwothree \TeX—0123456789—?!}
+ \bye
+\endlisting
+
+\noindent Despite the atrocious result, the example demonstrates well the
+syntax that is used to specify ranges and fonts. Fonts are being referred to by
+their internal index which can be obtained by passing the font command into the
+\texmacro{fontid} macro, e. g. \inlinecode{\fontid\one}, after a font has been
+defined. The first component of the combination is the base font which will be
+extended by the others. It is specified by the index alone.
+
+All further fonts require either the literal \inlinecode{fallback} or a list of
+codepoint definitions to be appended after a comma. The elements of this list
+again denote either single codepoints like \inlinecode{0x21} (referring to the
+exclamation point character) or ranges of codepoints (\inlinecode{0x30-0x39}).
+Elements are separated by the \identifier{ASCII} asterisk character
+(\inlinecode{*}). The characters referenced in the list will be imported from
+the respective font, if available.
+
+\endsubsection %% Combinations
+
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Font names database}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\label{sec:fontdb}
+
+As mentioned above, \identifier{luaotfload} keeps track of which
+fonts are available to \LUATEX by means of a \emphasis{database}.
+%
+This allows referring to fonts not only by explicit filenames but
+also by the proper names contained in the metadata which is often
+more accessible to humans.\footnote{%
+ The tool \hyperlink[\fileent{otfinfo}]{http://www.lcdf.org/type/}
+ (comes with \TEX Live), when invoked on a font file with the
+ \inlinecode {-i} option, lists the variety of name fields defined for
+ it.
+}
+
+When \identifier{luaotfload} is asked to load a font by a font name,
+it will check if the database exists and load it, or else generate a
+fresh one.
+%
+Should it then fail to locate the font, an update to the database is
+performed in case the font has been added to the system only
+recently.
+%
+As soon as the database is updated, the resolver will try
+and look up the font again, all without user intervention.
+%
+The goal is for \identifier{luaotfload} to act in the background and
+behave as unobtrusively as possible, while providing a convenient
+interface to the fonts installed on the system.
+
+Generating the database for the first time may take a while since it
+inspects every font file on your computer.
+%
+This is particularly noticeable if it occurs during a typesetting run.
+In any case, subsequent updates to the database will be quite fast.
+
+\beginsubsection[luaotfload-tool]
+ {\fileent{luaotfload-tool}}
+
+It can still be desirable at times to do some of these steps
+manually, and without having to compile a document.
+%
+To this end, \identifier{luaotfload} comes with the utility
+\fileent{luaotfload-tool} that offers an interface to the database
+functionality.
+%
+Being a \LUA script, there are two ways to run it:
+either make it executable (\inlinecode {chmod +x} on unixoid systems) or
+pass it as an argument to \fileent{texlua}.\footnote{%
+ Tests by the maintainer show only marginal performance gain by
+ running with Luigi Scarso’s
+ \hyperlink [\identifier{Luajit\kern-.25ex\TEX}]{https://foundry.supelec.fr/projects/luajittex/},
+ which is probably due to the fact that most of the time is spent
+ on file system operations.
+
+ \emphasis{Note}:
+ On \abbrev{MS} \identifier{Windows} systems, the script can be run
+ either by calling the wrapper application
+ \fileent{luaotfload-tool.exe} or as
+ \inlinecode {texlua.exe luaotfload-tool.lua}.
+}
+%
+Invoked with the argument \inlinecode {--update} it will perform a database
+update, scanning for fonts not indexed.
+
+\beginlisting
+ luaotfload-tool --update
+\endlisting
+
+Adding the \inlinecode {--force} switch will initiate a complete
+rebuild of the database.
+
+\beginlisting
+ luaotfload-tool --update --force
+\endlisting
+
+\endsubsection
+
+\beginsubsection{Search Paths}
+
+\identifier{luaotfload} scans those directories where fonts are
+expected to be located on a given system.
+%
+On a Linux machine it follows the paths listed in the
+\identifier{Fontconfig} configuration files;
+consult \inlinecode {man 5 fonts.conf} for further information.
+%
+On \identifier{Windows} systems, the standard location is
+\inlinecode {Windows\\Fonts},
+%
+while \identifier{Mac OS~X} requires a multitude of paths to
+be examined.
+%
+The complete list is is given in table \ref{table-searchpaths}.
+Other paths can be specified by setting the environment variable
+\inlinecode {OSFONTDIR}.
+%
+If it is non-empty, then search will be extended to the included
+directories.
+
+\tablefloat {table-searchpaths}
+ {List of paths searched for each supported operating system.}
+ {%
+ \unless \iffalse
+ \begincentered
+ \begintabulate [lp{.5\textwidth}]
+ \beginrow
+ Windows \newcell \inlinecode !\% WINDIR\%\\ Fonts!
+ \endrow
+ \beginrow
+ Linux \newcell \fileent{/usr/local/etc/fonts/fonts.conf} and\hfill\break
+ \fileent{/etc/fonts/fonts.conf}
+ \endrow
+ \beginrow
+ Mac \newcell \fileent{\textasciitilde/Library/Fonts},\break
+ \fileent{/Library/Fonts},\break
+ \fileent{/System/Library/Fonts}, and\hfill\break
+ \fileent{/Network/Library/Fonts}
+ \endrow
+ \endtabulate
+ \endcentered
+ \else
+ \setuplocalinterlinespace [14pt]
+ \starttabulate [|l|p(.5\textwidth)|]
+ \NC Windows \NC \inlinecode {\% WINDIR\%\\ Fonts} \NC \NR
+ \NC Linux \NC \fileent{/usr/local/etc/fonts/fonts.conf} and\crlf
+ \fileent{/etc/fonts/fonts.conf} \NC \NR
+ \NC
+ Mac \NC \fileent{\textasciitilde/Library/Fonts},\crlf
+ \fileent{/Library/Fonts},\break
+ \fileent{/System/Library/Fonts}, and\crlf
+ \fileent{/Network/Library/Fonts} \NC \NR
+ \stoptabulate
+ \fi%
+ }
+
+\endsubsection
+
+\beginsubsection{Querying from Outside}
+
+\fileent{luaotfload-tool} also provides rudimentary means of
+accessing the information collected in the font database.
+%
+If the option \inlinecode {--find=}\emphasis{name} is given, the script will
+try and search the fonts indexed by \identifier{luaotfload} for a
+matching name.
+%
+For instance, the invocation
+
+\beginlisting
+ luaotfload-tool --find="Iwona Regular"
+\endlisting
+
+\noindent
+will verify if “Iwona Regular†is found in the database and can be
+readily requested in a document.
+
+If you are unsure about the actual font name, then add the
+\inlinecode {-F} (or \inlinecode {--fuzzy}) switch to the command line to enable
+approximate matching.
+%
+Suppose you cannot precisely remember if the variant of
+\identifier{Iwona} you are looking for was “Bright†or “Lightâ€.
+The query
+
+\beginlisting
+ luaotfload-tool -F --find="Iwona Bright"
+\endlisting
+
+\noindent
+will tell you that indeed the latter name is correct.
+
+Basic information about fonts in the database can be displayed
+using the \inlinecode {-i} option (\inlinecode {--info}).
+%
+\beginlisting
+ luaotfload-tool -i --find="Iwona Light Italic"
+\endlisting
+%
+\noindent
+The meaning of the printed values is described in section 4.4 of the
+\LUATEX reference manual.\footnote{%
+ In \TEX Live: \fileent{texmf-dist/doc/luatex/base/luatexref-t.pdf}.
+}
+
+For a much more detailed report about a given font try the
+\inlinecode {-I} option instead (\inlinecode {--inspect}).
+\beginlisting
+ luaotfload-tool -I --find="Iwona Light Italic"
+\endlisting
+
+\inlinecode {luaotfload-tool --help} will list the available command line
+switches, including some not discussed in detail here.
+%
+For a full documentation of \identifier{luaotfload-tool} and its
+capabilities refer to the manpage
+(\inlinecode {man 1 luaotfload-tool}).\footnote{%
+ Or see \inlinecode {luaotfload-tool.rst} in the source directory.
+}
+
+\endsubsection
+
+\beginsubsection {Blacklisting Fonts}
+\label{font-blacklist}
+
+Some fonts are problematic in general, or just in \LUATEX.
+%
+If you find that compiling your document takes far too long or eats
+away all your system’s memory, you can track down the culprit by
+running \inlinecode {luaotfload-tool -v} to increase verbosity.
+%
+Take a note of the \emphasis{filename} of the font that database
+creation fails with and append it to the file
+\fileent{luaotfload-blacklist.cnf}.
+
+A blacklist file is a list of font filenames, one per line.
+Specifying the full path to where the file is located is optional, the
+plain filename should suffice.
+%
+File extensions (\fileent{.otf}, \fileent{.ttf}, etc.) may be omitted.
+%
+Anything after a percent (\inlinecode {\%}) character until the end of the line
+is ignored, so use this to add comments.
+%
+Place this file to some location where the \identifier{kpse}
+library can find it, e.~g.
+\fileent{texmf-local/tex/luatex/luaotfload} if you are running
+\identifier{\TEX Live},\footnote{%
+ You may have to run \inlinecode {mktexlsr} if you created a new file in
+ your \fileent{texmf} tree.
+}
+or just leave it in the working directory of your document.
+%
+\identifier{luaotfload} reads all files named
+\fileent{luaotfload-blacklist.cnf} it finds, so the fonts in
+\fileent{./luaotfload-blacklist.cnf} extend the global blacklist.
+
+Furthermore, a filename prepended with a dash character (\inlinecode{-}) is
+removed from the blacklist, causing it to be temporarily whitelisted
+without modifying the global file.
+%
+An example with explicit paths:
+
+\beginlisting
+% example otf-blacklist.cnf
+/Library/Fonts/GillSans.ttc % Luaotfload ignores this font.
+-/Library/Fonts/Optima.ttc % This one is usable again, even if
+ % blacklisted somewhere else.
+\endlisting
+
+\endsubsection
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {The Fontloader}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\beginsubsection {Overview}
+
+To a large extent, \identifier{luaotfload} relies on code originally
+written by Hans Hagen for the
+\hyperlink[\identifier{\CONTEXT}]{http://wiki.contextgarden.net}
+format.
+%
+It integrates the font loader, written entirely in \LUA, as distributed
+in the \identifier{\LUATEX-Fonts} package.
+%
+The original \LUA source files have been combined using the \CONTEXT
+packaging library into a single, self-contained blob. In
+this form the font loader depends only on the \identifier{lualibs}
+package and requires only minor adaptions to integrate into
+\identifier{luaotfload}.
+
+The guiding principle is to let \CONTEXT/\LUATEX-Fonts take care of the
+implementation, and update the imported code as frequently as
+necessary.
+%
+As maintainers, we aim at importing files from upstream essentially
+\emphasis{unmodified}, except for renaming them to prevent name
+clashes.
+%
+This job has been greatly alleviated since the advent of
+\LUATEX-Fonts, prior to which the individual dependencies had to be
+manually spotted and extracted from the \CONTEXT source code in a
+complicated and error-prone fashion.
+
+\endsubsection
+
+\beginsubsection {Contents and Dependencies}
+
+Below is a commented list of the files distributed with
+\identifier{luaotfload} in one way or the other.
+%
+See see the figure on page \pageref{file-graph} for a
+graphical representation of the dependencies.
+%
+\label{package}%
+Through the script \fileent{mkimport} a \CONTEXT library
+is invoked to create the \identifier{luaotfload} fontloader as a merged
+(amalgamated) source file.\footnote{%
+ In \CONTEXT, this facility can be accessed by means of a
+ \hyperlink[script]{https://bitbucket.org/phg/context-mirror/src/beta/scripts/context/lua/mtx-package.lua?at=beta}
+ which is integrated into \fileent{mtxrun} as a subcommand.
+ Run \inlinecode {mtxrun --script package --help} to display further
+ information.
+ For the actual merging code see the file
+ \fileent{util-mrg.lua} that is part of \CONTEXT.
+}
+%
+This file constitutes the “default fontloader†and is part of the
+\identifier{luaotfload} package as \fileent{fontloader-YY-MM-DD.lua},
+where the uppercase letters are placeholders for the build date.
+%
+A companion to it, \fileent{luatex-basics-gen.lua} (renamed to \fileent{fontloader-basics-gen.lua} in \identifier{luaotfload})
+must be loaded beforehand to set up parts of the environment required by the \CONTEXT
+libraries.
+%
+During a \TEX\ run, the fontloader initialization and injection happens
+in the module \fileent{luaotfload-init.lua}.
+%
+Additionally, the “reference fontloader†as imported from \LUATEX-Fonts
+is provided as the file \fileent{fontloader-reference.lua}.
+%
+This file is self-contained in that it packages all the auxiliary \LUA
+libraries too, as Luaotfload did up to the 2.5 series; since that job
+has been offloaded to the \identifier{Lualibs} package, loading this
+fontloader introduces a certain code duplication.
+
+A number of \emphasis{\LUA utility libraries} are not part of the
+\identifier{luaotfload} fontloader, contrary to its equivalent in
+\LUATEX-Fonts. These are already provided by the \identifier{lualibs}
+and have thus been omitted from the merge.\footnote{%
+ Faithful listeners will remember the pre-2.6 era when the fontloader
+ used to be integrated as-is which caused all kinds of code
+ duplication with the pervasive \identifier{lualibs} package.
+ This conceptual glitch has since been amended by tightening the
+ coupling with the excellent \CONTEXT\ toolchain.
+}
+
+\begindoublecolumns
+ \begindefinitions
+ \directlua{ printctxlibslist ()}
+ \enddefinitions
+\enddoublecolumns
+
+The reference fontloader is home to several \LUA files that can be
+grouped twofold as below:
+
+\begindefinitions
+ \beginnormalitem
+ The \emphasis{font loader} itself.
+ These files have been written for \LUATEX-Fonts and they are
+ distributed along with \identifier{luaotfload} so as to resemble
+ the state of the code when it was imported. Their purpose is either
+ to give a slightly aged version of a file if upstream considers
+ latest developments for not yet ready for use outside Context; or,
+ to install placeholders or minimalist versions of APIs relied upon
+ but usually provided by parts of Context not included in the
+ fontloader.
+ \begindoublecolumns
+ \begindefinitions
+ \directlua{printctxallgenericlist ()}
+ \enddefinitions
+ \enddoublecolumns
+ \endnormalitem
+
+ \beginnormalitem
+ Code related to \emphasis{font handling and node processing}, taken
+ directly from \CONTEXT.
+ \begindoublecolumns
+ \begindefinitions
+ \directlua{printctxfontlist ()}
+ \enddefinitions
+ \enddoublecolumns
+ \endnormalitem
+\enddefinitions
+
+As an alternative to the merged file, \identifier {Luaotfload} may load
+individual unpackaged \LUA libraries that come with the source, or even
+use the files from Context directly.
+%
+Thus if you prefer running bleeding edge code from the \CONTEXT beta,
+choose the \inlinecode {context} fontloader via the configuration file
+(see sections \ref{sec:conf} and \ref{sec:pkg} below).
+
+Also, the merged file at some point loads the Adobe Glyph List from a
+\LUA table that is contained in \fileent{luaotfload-glyphlist.lua},
+which is automatically generated by the script
+\fileent{mkglyphlist}.\footnote{%
+ See \fileent{luaotfload-font-enc.lua}.
+ The hard-coded file name is why we have to replace the procedure
+ that loads the file in \fileent{luaotfload-init.lua}.
+}
+%
+There is a make target \identifier{glyphs} that will create a fresh
+glyph list so we don’t need to import it from \CONTEXT any longer.
+
+In addition to these, \identifier{luaotfload} requires a number of
+files not contained in the merge. Some of these have no equivalent in
+\LUATEX-Fonts or \CONTEXT, some were taken unmodified from the latter.
+
+
+\beginfilelist
+ \beginaltitem {luaotfload-features.lua}
+ font feature handling; incorporates some of the code from
+ \fileent{font-otc} from \CONTEXT;
+ \endaltitem
+ \beginaltitem {luaotfload-configuration.lua}
+ handling of \fileent{luaotfload.conf(5)}.
+ \endaltitem
+ \beginaltitem {luaotfload-log.lua}
+ overrides the \CONTEXT logging functionality.
+ \endaltitem
+ \beginaltitem {luaotfload-loaders.lua}
+ registers readers in the fontloader for various kinds of
+ font formats
+ \endaltitem
+ \beginaltitem {luaotfload-parsers.lua}
+ various \abbrev{lpeg}-based parsers.
+ \endaltitem
+ \beginaltitem {luaotfload-database.lua}
+ font names database.
+ \endaltitem
+ \beginaltitem {luaotfload-resolvers.lua}
+ file name resolvers.
+ \endaltitem
+ \beginaltitem {luaotfload-colors.lua}
+ color handling.
+ \endaltitem
+ \beginaltitem {luaotfload-auxiliary.lua}
+ access to internal functionality for package authors (proposals
+ for additions welcome).
+ \endaltitem
+ \beginaltitem {luaotfload-letterspace.lua}
+ font-based letterspacing.
+ \endaltitem
+ \beginaltitem {luaotfload-filelist.lua}
+ data about the files in the package.
+ \endaltitem
+\endfilelist
+
+%\figurefloat
+% {file-graph}
+% {Schematic of the files in \identifier{Luaotfload}}
+% {filegraph.pdf}
+
+\endsubsection
+
+\beginsubsection {Packaging}
+
+\label{sec:pkg}%
+The fontloader code is integrated as an isolated component that can be
+switched out on demand.
+%
+To specify the fontloader you wish to use, the configuration file
+(described in section \ref{sec:conf}) provides the option
+\inlinecode{fontloader}.
+%
+Its value can be one of the identifiers \inlinecode{default} or
+\inlinecode{reference} (see above, section \ref{package}) or the name
+of a file somewhere in the search path of \LUATEX.
+%
+This will make \identifier {Luaotfload} locate the \CONTEXT source by
+means of \identifier{kpathsea} lookups and use those instead of the
+merged package.
+%
+The parameter may be extended with a path to the \CONTEXT
+\fileent{texmf}, separated with a colon:
+
+\beginlisting
+[run]
+ fontloader = context:~/context/tex/texmf-context
+\endlisting
+
+\noindent This setting allows accessing an installation -- e. g. the
+standalone distribution or a source repository -- outside the current
+\TEX distribution.
+
+Like the \identifier{Lualibs} package, the fontloader is deployed as a
+\emphasis{merged package} containing a series of \LUA files joined
+together in their expected order and stripped of non-significant parts.
+%
+The \fileent{mkimport} utility assists in pulling the files from a
+\CONTEXT tree and packaging them for use with \identifier{Luaotfload}.%
+%
+The state of the files currently in \identifier{Luaotfload}’s
+repository can be queried:
+\beginlisting
+./scripts/mkimport news
+\endlisting
+%
+The subcommand for importing takes the prefix of the desired \CONTEXT
+\identifier{texmf} as an optional argument:
+\beginlisting
+./scripts/mkimport import ~/context/tex/texmf-context
+\endlisting
+%
+Whereas the command for packaging requires a path to the
+\emphasis{package description file} and the output name to be passed.
+\beginlisting
+./scripts/mkimport package fontloader-custom.lua
+\endlisting
+
+From the toplevel makefile, the targets \inlinecode{import} and
+\inlinecode{package} provide easy access to the commands as invoked during
+the \identifier{Luaotfload} build process.\footnote{%
+ \emphasis{Hint for those interested in the packaging process}: issue
+ \inlinecode{make show} for a list of available build routines.
+}
+These will call \inlinecode{mkimport} script with the correct
+parameters to generate a datestamped package.
+%
+Whether files have been updated in the upstream distribution can be
+queried by \inlinecode{./scripts/mkimport news}.
+%
+This will compare the imported files with their counterparts in the
+\CONTEXT distribution and report changes.
+
+\endsubsection
+
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Configuration Files}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\beginnarrower
+ \emphasis{Caution}: For the authoritative documentation, consult the
+ manpage for \fileent{luaotfload.conf(5)}.
+\endnarrower
+
+\label{sec:conf}
+The runtime behavior of \identifier{Luaotfload} can be customized by
+means of a configuration file.
+% location
+At startup, it attempts to locate a file called \fileent
+{luaotfload.conf} or \fileent {luaotfloadrc} at a number of candidate
+locations:
+
+\begincentered
+ \begindefinitions
+ \beginnormalitem \fileent{./luaotfload.conf} \endnormalitem
+ \beginnormalitem \fileent{./luaotfloadrc} \endnormalitem
+ \beginnormalitem \fileent{\$XDG_CONFIG_HOME/luaotfload/luaotfload.conf} \endnormalitem
+ \beginnormalitem \fileent{\$XDG_CONFIG_HOME/luaotfload/luaotfload.rc} \endnormalitem
+ \beginnormalitem \fileent{~/.luaotfloadrc} \endnormalitem
+ \enddefinitions
+\endcentered
+
+\beginnarrower
+ \emphasis{Caution}: The configuration potentially modifies the final
+ document. A project-local file belongs under version control along
+ with the rest of the document. This is to ensure that everybody who
+ builds the project also receives the same customizations as the
+ author.
+\endnarrower
+
+% syntax
+The syntax is fairly close to the format used by
+\fileent{git-config(1)} which in turn was derived from the popular
+\identifier{.INI} format: Lines of key-value pairs are grouped under
+different configuration “sectionsâ€.\footnote{%
+ The configuration parser in \fileent {luoatfload-parsers.lua} might
+ be employed by other packages for similar purposes.
+}
+% example settings
+An example for customization via \fileent {luaotfload.conf} might look
+as below:
+
+\beginlisting
+; Example luaotfload.conf containing a rudimentary configuration
+[db]
+ update-live = false
+[run]
+ color-callback = pre_linebreak_filter
+ definer = info_patch
+ log-level = 5
+[default-features]
+ global = mode=base
+\endlisting
+
+This specifies that for the given project, \identifier{Luaotfload}
+shall not attempt to automatically scan for fonts if it can’t resolve a
+request. The font-based colorization will happen during \LUATEX’s
+pre-linebreak filter. The fontloader will output verbose information
+about the fonts at definition time along with globally increased
+verbosity. Lastly, the fontloader defaults to the less expensive
+\luaident{base} mode like it does in \CONTEXT.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Auxiliary Functions}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+With release version 2.2, \identifier{Luaotfload} received
+additional functions for package authors to call from outside
+(see the file \fileent{luaotfload-auxiliary.lua} for details).
+%
+The purpose of this addition twofold.
+%
+Firstly, \identifier{luaotfload} failed to provide a stable interface
+to internals in the past which resulted in an unmanageable situation
+of different packages abusing the raw access to font objects by means
+of the \luaident{patch_font} callback.
+%
+When the structure of the font object changed due to an update, all
+of these imploded and several packages had to be fixed while
+simultaneously providing fallbacks for earlier versions.
+%
+Now the patching is done on the \identifier{luaotfload} side and can
+be adapted with future modifications to font objects without touching
+the packages that depend on it.
+%
+Second, some the capabilities of the font loader and the names
+database are not immediately relevant in \identifier{luaotfload}
+itself but might nevertheless be of great value to package authors or
+end users.
+
+Note that the current interface is not yet set in stone and the
+development team is open to suggestions for improvements or
+additions.
+
+\beginsubsection {Callback Functions}
+
+The \luaident{patch_font} callback is inserted in the wrapper
+\identifier{luaotfload} provides for the font definition callback.
+%
+At this place it allows manipulating the font object immediately after
+the font loader is done creating it.
+%
+For a short demonstration of its usefulness, here is a snippet that
+writes an entire font object to the file \fileent{fontdump.lua}:
+
+\beginlisting
+ \input luaotfload.sty
+ \directlua{
+ local dumpfile = "fontdump.lua"
+ local dump_font = function (tfmdata)
+ local data = table.serialize(tfmdata)
+ io.savedata(dumpfile, data)
+ end
+
+ luatexbase.add_to_callback(
+ "luaotfload.patch_font",
+ dump_font,
+ "my_private_callbacks.dump_font"
+ )
+ }
+ \font \dumpme = name:Iwona
+ \bye
+\endlisting
+
+\emphasis{Beware}: this creates a Lua file of around 150,000 lines of
+code, taking up 3~\abbrev{mb} of disk space.
+%
+By inspecting the output you can get a first impression of how a font
+is structured in \LUATEX’s memory, what elements it is composed of,
+and in what ways it can be rearranged.
+
+\beginsubsubsection {Compatibility with Earlier Versions}
+
+As has been touched on in the preface to this section, the structure
+of the object as returned by the fontloader underwent rather drastic
+changes during different stages of its development, and not all
+packages that made use of font patching have kept up with every one
+of it.
+%
+To ensure compatibility with these as well as older versions of
+some packages, \identifier{luaotfload} sets up copies of or references
+to data in the font table where it used to be located.
+%
+For instance, important parameters like the requested point size, the
+units factor, and the font name have again been made accessible from
+the toplevel of the table even though they were migrated to different
+subtables in the meantime.
+
+\endsubsubsection
+
+\beginsubsubsection{Patches}
+
+These are mostly concerned with establishing compatibility with \XETEX.
+
+\beginfunctionlist
+
+ \beginaltitem {set_sscale_dimens}
+ Calculate \texmacro{fontdimen}s 10 and 11 to emulate \XETEX.
+ \endaltitem
+
+ \beginaltitem {set_capheight}
+ Calculates \texmacro{fontdimen} 8 like \XETEX.
+ \endaltitem
+
+ \beginaltitem {patch_cambria_domh}
+ Correct some values of the font \emphasis{Cambria Math}.
+ \endaltitem
+
+\endfunctionlist
+
+\endsubsection
+
+\beginsubsection {Package Author’s Interface}
+
+As \LUATEX release 1.0 is nearing, the demand for a reliable interface
+for package authors increases.
+
+\endsubsubsection
+
+\beginsubsubsection{Font Properties}
+
+Below functions mostly concern querying the different components of a
+font like for instance the glyphs it contains, or what font features
+are defined for which scripts.
+
+\beginfunctionlist
+
+ \beginaltitem {aux.font_has_glyph (id : int, index : int)}
+ Predicate that returns true if the font \luaident{id}
+ has glyph \luaident{index}.
+ \endaltitem
+
+ \beginaltitem {aux.slot_of_name(name : string)}
+ Translates an Adobe Glyph name to the corresponding glyph
+ slot.
+ \endaltitem
+
+ \beginaltitem {aux.name_of_slot(slot : int)}
+ The inverse of \luaident{slot_of_name}; note that this
+ might be incomplete as multiple glyph names may map to the
+ same codepoint, only one of which is returned by
+ \luaident{name_of_slot}.
+ \endaltitem
+
+ \beginaltitem {aux.provides_script(id : int, script : string)}
+ Test if a font supports \luaident{script}.
+ \endaltitem
+
+ \beginaltitem {aux.provides_language(id : int, script : string, language : string)}
+ Test if a font defines \luaident{language} for a given
+ \luaident{script}.
+ \endaltitem
+
+ \beginaltitem {aux.provides_feature(id : int, script : string,
+ language : string, feature : string)}
+ Test if a font defines \luaident{feature} for
+ \luaident{language} for a given \luaident{script}.
+ \endaltitem
+
+ \beginaltitem {aux.get_math_dimension(id : int, dimension : string)}
+ Get the dimension \luaident{dimension} of font \luaident{id}.
+ \endaltitem
+
+ \beginaltitem {aux.sprint_math_dimension(id : int, dimension : string)}
+ Same as \luaident{get_math_dimension()}, but output the value
+ in scaled points at the \TEX end.
+ \endaltitem
+
+\endfunctionlist
+
+\endsubsubsection
+
+\beginsubsubsection{Database}
+
+%% not implemented, may come back later
+\beginfunctionlist
+% \beginaltitem {aux.scan_external_dir(dir : string)}
+% Include fonts in directory \luaident{dir} in font lookups without
+% adding them to the database.
+%
+ \beginaltitem {aux.read_font_index (void)}
+ Read the index file from the appropriate location (usually
+ the bytecode file \fileent{luaotfload-names.luc} somewhere
+ in the \fileent{texmf-var} tree) and return the result as a
+ table. The file is processed with each call so it is up to
+ the user to store the result for later access.
+ \endaltitem
+
+ \beginaltitem {aux.font_index (void)}
+ Return a reference of the font names table used internally
+ by \identifier{luaotfload}. The index will be read if it
+ has not been loaded up to this point. Also a font scan that
+ overwrites the current index file might be triggered. Since
+ the return value points to the actual index, any
+ modifications to the table might influence runtime behavior
+ of \identifier{luaotfload}.
+ \endaltitem
+
+\endfunctionlist
+
+\endsubsubsection
+
+\endsubsection
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Troubleshooting}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\beginsubsection {Database Generation}
+
+If you encounter problems with some fonts, please first update to the
+latest version of this package before reporting a bug, as
+\identifier{luaotfload} is under active development and still a moving
+target.
+%
+The development takes place on \identifier{github} at
+\hyperlink {https://github.com/lualatex/luaotfload} where there is an issue
+tracker for submitting bug reports, feature requests and the likes.
+
+Bug reports are more likely to be addressed if they contain the output
+of
+
+\beginlisting
+ luaotfload-tool --diagnose=environment,files,permissions
+\endlisting
+
+\noindent Consult the man page for a description of these options.
+
+Errors during database generation can be traced by increasing the
+verbosity level and redirecting log output to \fileent{stdout}:
+
+\beginlisting
+ luaotfload-tool -fuvvv --log=stdout
+\endlisting
+
+\noindent or to a file in \fileent{/tmp}:
+
+\beginlisting
+ luaotfload-tool -fuvvv --log=file
+\endlisting
+
+\noindent In the latter case, invoke the \inlinecode {tail(1)} utility on the
+file for live monitoring of the progress.
+
+If database generation fails, the font last printed to the terminal or
+log file is likely to be the culprit.
+%
+Please specify it when reporting a bug, and blacklist it for the time
+being (see above, page \pageref{font-blacklist}).
+
+\endsubsection
+
+\beginsubsection {Font Features}
+
+A common problem is the lack of features for some
+\OpenType fonts even when specified.
+%
+This can be related to the fact that some fonts do not provide features
+for the \inlinecode {dflt} script (see above on page \pageref{script-tag}),
+which is the default one in this package.
+%
+If this happens, assigning a noth script when the font is defined should
+fix it.
+%
+For example with \inlinecode {latn}:
+
+\beginlisting
+ \font \test = file:MyFont.otf:script=latn;+liga;
+\endlisting
+
+You can get a list of features that a font defines for scripts and
+languages by querying it in \fileent{luaotfload-tool}:
+
+\beginlisting
+ luaotfload-tool --find="Iwona" --inspect
+\endlisting
+
+\endsubsection
+
+\beginsubsection {\LUATEX Programming}
+
+Another strategy that helps avoiding problems is to not access raw
+\LUATEX internals directly.
+%
+Some of them, even though they are dangerous to access, have not been
+overridden or disabled.
+%
+Thus, whenever possible prefer the functions in the \luaident{aux}
+namespace over direct manipulation of font objects. For example, raw
+access to the \luaident{font.fonts} table like:
+
+\beginlisting
+ local somefont = font.fonts[2]
+\endlisting
+
+\noindent can render already defined fonts unusable.
+%
+Instead, the function \luaident{font.getfont()} should be used
+because it has been replaced by a safe variant.
+
+However, \luaident{font.getfont()} only covers fonts handled by the
+font loader, e.~g. \identifier{OpenType} and \identifier{TrueType}
+fonts, but not \abbrev{tfm} or \abbrev{ofm}.
+%
+Should you absolutely require access to all fonts known to \LUATEX,
+including the virtual and autogenerated ones, then you need to query
+both \luaident{font.getfont()} and \luaident{font.fonts}.
+%
+In this case, best define you own accessor:
+
+\beginlisting
+ local unsafe_getfont = function (id)
+ local tfmdata = font.getfont (id)
+ if not tfmdata then
+ tfmdata = font.fonts[id]
+ end
+ return tfmdata
+ end
+
+ --- use like getfont()
+ local somefont = unsafe_getfont (2)
+\endlisting
+
+\endsubsection
+\endsection
+
+\beginsection {License}
+
+\identifier {luaotfload} is licensed under the terms of the
+\hyperlink [GNU General Public License version 2.0]%
+ {https://www.gnu.org/licenses/old-licenses/gpl-2.0.html}.
+Following the underlying fontloader code \identifier {luaotfload}
+recognizes only that exact version as its license.
+The „any later version†clause of the original license text as
+copyrighted by the \hyperlink [Free Software Foundation]{http://www.fsf.org/}
+\emphasis {does not apply} to either \identifier {luaotfload} or the
+code imported from \CONTEXT.
+
+The complete text of the license is given as a separate file \fileent
+{COPYING} in the toplevel directory of the
+\hyperlink [\fileent {Luaotfload} Git repository]{https://github.com/lualatex/luaotfload/blob/master/COPYING}.\\
+Distributions probably package it as \fileent
+{doc/luatex/luaotfload/COPYING} in the relevant \fileent {texmf} tree.
+
+\endsection
+
+\endinput
+
+% vim:ft=tex:tw=79:et:sw=2
diff --git a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
new file mode 100644
index 0000000000..196ea928bb
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
@@ -0,0 +1,105 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-notdef.lua
+-- DESCRIPTION: part of luaotfload / notdef
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-notdef",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / color",
+ license = "GPL v2.0",
+ author = "Marcel Krüger"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+local nodenew = node.direct.new
+local getfont = font.getfont
+local setfont = node.direct.setfont
+local getwhd = node.direct.getwhd
+local insert_after = node.direct.insert_after
+local traverse_char = node.direct.traverse_char
+local protect_glyph = node.direct.protect_glyph
+local otffeatures = fonts.constructors.newfeatures "otf"
+
+local function setnotdef(tfmdata, factor)
+ local desc = tfmdata.shared.rawdata.descriptions
+ -- So we have to find the .notdef glyph. We only know that it has GID
+ -- 0, but we need it's Unicode mapping. Normally it isn't mapped in
+ -- the font, so we auto-assigned the first private slot:
+ local guess = desc[0xF0000]
+ if guess and guess.index == 0 then
+ tfmdata.notdefcode = 0xF0000
+ return
+ end
+ print')'
+ -- If this didn't happen, it might be mapped to one of the
+ -- replacement characters:
+ for code = 0xFFFC,0xFFFF do
+ guess = desc[code]
+ if guess and guess.index == 0 then
+ tfmdata.notdefcode = code
+ return
+ end
+ end
+ print')))'
+ -- Oh no, we couldn't find it. Maybe we can find it by name?
+ local code = tfmdata.resources.unicodes[".notdef"]
+ -- Better safe than sorry
+ guess = code and desc[code]
+ if guess and guess.index == 0 then
+ tfmdata.notdefcode = code
+ return
+ end
+ print'))))'
+ -- So the font didn't do the obvious things and then it lied to us.
+ -- At this point we should think about sending an automated complain
+ -- to the font author, but we probably can't trust the contact
+ -- information either.
+ -- We will fall back to brute force now:
+ for code, char in pairs(desc) do
+ if char.index == 0 then
+ tfmdata.notdefcode = code
+ return
+ end
+ end
+ -- If we ever reach this point, something odd happened. Either there
+ -- are no glyphs at all (then LuaTeX will complain anyway, so let's
+ -- ignore that case) or someone tried to use this with a legacy font.
+ -- In that case there most likely isn't a `.notdef` glyph anyway and
+ -- inserting glyph 0 would insert a random character, so `notdefcode`
+ -- better stays `nil`.
+end
+
+local glyph_id = node.id'glyph'
+local function donotdef(head, font, _, _, _)
+ local tfmdata = getfont(font)
+ local notdef, chars = tfmdata.unscaled.notdefcode, tfmdata.characters
+ if not notdef then return end
+ for cur, cid, fid in traverse_char(head) do if fid == font then
+ local w, h, d = getwhd(cur)
+ if w == 0 and h == 0 and d == 0 and not chars[cid] then
+ local notdefnode = nodenew(glyph_id, 256)
+ setfont(notdefnode, font, notdef)
+ insert_after(cur, cur, notdefnode)
+ protect_glyph(cur)
+ end
+ end end
+end
+
+otffeatures.register {
+ name = "notdef",
+ description = "Add notdef glyphs",
+ default = 1,
+ initializers = {
+ node = setnotdef,
+ },
+ processors = {
+ node = donotdef,
+ }
+}
+
+--- vim:sw=2:ts=2:expandtab:tw=71
diff --git a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
new file mode 100644
index 0000000000..5a7ccd576f
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
@@ -0,0 +1,799 @@
+-------------------------------------------------------------------------------
+-- FILE: luaotfload-parsers.lua
+-- DESCRIPTION: various lpeg-based parsers used in Luaotfload
+-- REQUIREMENTS: Luaotfload
+-- AUTHOR: Philipp Gesang (Phg), <phg@phi-gamma.net>, Marcel Krüger
+-------------------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-parsers",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / filelist",
+ license = "GPL v2.0"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+
+local traversal_maxdepth = 42 --- prevent stack overflows
+
+local rawset = rawset
+
+local lpeg = require "lpeg"
+local patterns = lpeg.patterns
+local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V
+local lpegmatch = lpeg.match
+local C, Cc, Cf = lpeg.C, lpeg.Cc, lpeg.Cf
+local Cg, Cmt, Cs, Ct = lpeg.Cg, lpeg.Cmt, lpeg.Cs, lpeg.Ct
+
+local kpse = kpse
+local kpseexpand_path = kpse.expand_path
+local kpsereadable_file = kpse.readable_file
+
+local file = file
+local filejoin = file.join
+local filedirname = file.dirname
+
+local io = io
+local ioopen = io.open
+
+local logreport = print
+
+local string = string
+local stringsub = string.sub
+local stringfind = string.find
+local stringlower = string.lower
+
+local mathceil = math.ceil
+
+local lfs = lfs
+local lfsisfile = lfs.isfile
+local lfsisdir = lfs.isdir
+
+-------------------------------------------------------------------------------
+--- COMMON PATTERNS
+-------------------------------------------------------------------------------
+
+local asterisk = P"*"
+local dot = P"."
+local colon = P":"
+local semicolon = P";"
+local comma = P","
+local noncomma = 1 - comma
+local slash = P"/"
+local backslash = P"\\"
+local equals = P"="
+local dash = P"-"
+local gartenzaun = P"#"
+local lbrk, rbrk = P"[", P"]"
+local brackets = lbrk + rbrk
+local squote = P"'"
+local dquote = P"\""
+
+local newline = P"\n"
+local returnchar = P"\r"
+local spacing = S" \t\v"
+local linebreak = S"\n\r"
+local whitespace = spacing + linebreak
+local ws = spacing^0
+local xmlws = whitespace^1
+local eol = P"\n\r" + P"\r\n" + linebreak
+
+local digit = R"09"
+local alpha = R("az", "AZ")
+local anum = alpha + digit
+local decimal = digit^1 * (dot * digit^0)^-1
+local hexdigit = R("09", "af", "AF")
+local hex = P"0x" * hexdigit^1
+
+-------------------------------------------------------------------------------
+--- FONTCONFIG
+-------------------------------------------------------------------------------
+
+--[[doc--
+
+ For fonts installed on the operating system, there are several
+ options to make Luaotfload index them:
+
+ - If OSFONTDIR is set (which is the case under windows by default
+ but not on the other OSs), it scans it at the same time as the
+ texmf tree, in the function scan_texmf_fonts().
+
+ - Otherwise
+ - under Windows and Mac OSX, we take a look at some hardcoded
+ directories,
+ - under Unix, it reads /etc/fonts/fonts.conf and processes the
+ directories specified there.
+
+ This means that if you have fonts in fancy directories, you need to
+ set them in OSFONTDIR.
+
+ Beware: OSFONTDIR is a kpathsea variable, so fonts found in these
+ paths, though technically system fonts, are registered in the
+ category “texmfâ€, not “systemâ€. This may have consequences for the
+ lookup order when a font file (or a font with the same name
+ information) is located in both the system and the texmf tree.
+
+--doc]]--
+
+local tag_name = C(alpha^1)
+local comment = P"<!--" * (1 - P"--")^0 * P"-->"
+
+---> header specifica
+local xml_declaration = P"<?xml" * (1 - P"?>")^0 * P"?>"
+local xml_doctype = P"<!DOCTYPE" * xmlws
+ * "fontconfig" * (1 - P">")^0 * P">"
+local header = xml_declaration^-1
+ * (xml_doctype + comment + xmlws)^0
+
+---> enforce root node
+local root_start = P"<" * xmlws^-1 * P"fontconfig" * xmlws^-1 * P">"
+local root_stop = P"</" * xmlws^-1 * P"fontconfig" * xmlws^-1 * P">"
+
+local dquote, squote = P[["]], P"'"
+local xml_namestartchar = S":_" + alpha --- ascii only, funk the rest
+local xml_namechar = S":._" + alpha + digit
+local xml_name = xmlws^-1
+ * C(xml_namestartchar * xml_namechar^0)
+local xml_attvalue = dquote * C((1 - S[[%&"]])^1) * dquote * xmlws^-1
+ + squote * C((1 - S[[%&']])^1) * squote * xmlws^-1
+local xml_attr = Cg(xml_name * P"=" * xml_attvalue)
+local xml_attr_list = Cf(Ct"" * xml_attr^1, rawset)
+
+--[[doc--
+ scan_node creates a parser for a given xml tag.
+--doc]]--
+--- string -> bool -> lpeg_t
+local scan_node = function (tag)
+ --- Node attributes go into a table with the index “attributesâ€
+ --- (relevant for “prefix="xdg"†and the likes).
+ local p_tag = P(tag)
+ local with_attributes = P"<" * p_tag
+ * Cg(xml_attr_list, "attributes")^-1
+ * xmlws^-1
+ * P">"
+ local plain = P"<" * p_tag * xmlws^-1 * P">"
+ local node_start = plain + with_attributes
+ local node_stop = P"</" * p_tag * xmlws^-1 * P">"
+ --- there is no nesting, the earth is flat ...
+ local node = node_start
+ * Cc(tag) * C(comment + (1 - node_stop)^1)
+ * node_stop
+ return Ct(node) -- returns {string, string [, attributes = { key = val }] }
+end
+
+--[[doc--
+ At the moment, the interesting tags are “dir†for
+ directory declarations, and “include†for including
+ further configuration files.
+
+ spec: http://freedesktop.org/software/fontconfig/fontconfig-user.html
+--doc]]--
+local include_node = scan_node"include"
+local dir_node = scan_node"dir"
+
+local element = dir_node
+ + include_node
+ + comment --> ignore
+ + P(1-root_stop) --> skip byte
+
+local root = root_start * Ct(element^0) * root_stop
+local p_cheapxml = header * root
+
+--lpeg.print(p_cheapxml) ---> 757 rules with v0.10
+
+--[[doc--
+ fonts_conf_scanner() handles configuration files.
+ It is called on an abolute path to a config file (e.g.
+ /home/luser/.config/fontconfig/fonts.conf) and returns a list
+ of the nodes it managed to extract from the file.
+--doc]]--
+--- string -> path list
+local fonts_conf_scanner = function (path)
+ logreport("both", 5, "db", "Read fontconfig file %s.", path)
+ local fh = ioopen(path, "r")
+ if not fh then
+ logreport("both", 3, "db", "Cannot open fontconfig file %s.", path)
+ return
+ end
+ local raw = fh:read"*all"
+ fh:close()
+ logreport("both", 7, "db",
+ "Reading fontconfig file %s completed (%d bytes).",
+ path, #raw)
+
+ logreport("both", 5, "db", "Scan fontconfig file %s.", path)
+ local confdata = lpegmatch(p_cheapxml, raw)
+ if not confdata then
+ logreport("both", 3, "db", "Cannot scan fontconfig file %s.", path)
+ return
+ end
+ logreport("both", 7, "db", "Scan of fontconfig file %s completed.", path)
+ return confdata
+end
+
+local p_conf = P".conf" * P(-1)
+local p_filter = (1 - p_conf)^1 * p_conf
+
+local conf_filter = function (path)
+ if lpegmatch (p_filter, path) then
+ return true
+ end
+ return false
+end
+
+--[[doc--
+
+ read_fonts_conf_indeed() -- Scan paths included from fontconfig
+ configuration files recursively. Called with eight arguments.
+ The first five are
+
+ · the current recursion depth
+ · the path to the file
+ · the expanded $HOME
+ · the expanded $XDG_CONFIG_HOME
+ · the expanded $XDG_DATA_HOME
+
+ determining the path to be checked. Another three arguments are
+ tables that represent the state of the current job as lists of
+ strings; these are always returned. Finally a reference to the
+ find_files function is passed.
+
+--doc]]--
+
+--- size_t -> string -> string -> string -> string
+--- -> string list -> string list -> string list
+--- -> (string -> fun option -> string list)
+--- -> tab * tab * tab
+local read_fonts_conf_indeed
+-- MK Made basedir an explicit parameter to fix relative paths
+read_fonts_conf_indeed = function (depth,
+ start,
+ home,
+ xdg_config_home,
+ xdg_data_home,
+ acc,
+ done,
+ dirs_done,
+ find_files,
+ basedir)
+
+ logreport ("both", 4, "db",
+ "Fontconfig scanner processing path %s.",
+ start)
+ if depth >= traversal_maxdepth then
+ --- prevent overflow of Lua call stack
+ logreport ("both", 0, "db",
+ "Fontconfig scanner hit recursion limit (%d); "
+ .. "aborting directory traversal.",
+ traversal_maxdepth)
+ return acc, done, dirs_done
+ end
+
+ local paths = fonts_conf_scanner(start)
+ if not paths then --- nothing to do
+ return acc, done, dirs_done
+ end
+
+ for i=1, #paths do
+ local pathobj = paths[i]
+ local kind, path = pathobj[1], pathobj[2]
+ local attributes = pathobj.attributes
+
+ if kind == "dir" then
+ if attributes and attributes.prefix == "xdg" then
+ path = filejoin(xdg_data_home, path)
+ end
+ if stringsub(path, 1, 1) == "~" then
+ path = filejoin(home, stringsub(path, 2))
+ end
+ --- We exclude paths with texmf in them, as they should be
+ --- found anyway; also duplicates are ignored by checking
+ --- if they are elements of dirs_done.
+ ---
+ --- FIXME does this mean we cannot access paths from
+ --- distributions (e.g. Context minimals) installed
+ --- separately?
+ if not (stringfind(path, "texmf") or dirs_done[path]) then
+ logreport ("log", 5, "db",
+ "New fontconfig path at %s.",
+ path)
+ acc[#acc+1] = path
+ dirs_done[path] = true
+ end
+
+ elseif kind == "include" then
+ if attributes and attributes.prefix == "xdg" then
+ path = filejoin(xdg_config_home, path)
+ end
+ --- here the path can be four things: a directory or a file,
+ --- an absolute or relative path.
+ if stringsub(path, 1, 1) == "~" then
+ path = filejoin(home, stringsub(path, 2))
+ elseif --- if the path is relative, we make it absolute
+ not ( lfsisfile(path) or lfsisdir(path) )
+ then
+ path = filejoin(basedir, path)
+ end
+ if lfsisfile(path)
+ and kpsereadable_file(path)
+ then
+ if done[path] then
+ logreport("log", 3, "db",
+ "Skipping file at %s, already included.", path)
+ else
+ done[path] = true
+ acc = read_fonts_conf_indeed(depth + 1,
+ path,
+ home,
+ xdg_config_home,
+ xdg_data_home,
+ acc,
+ done,
+ dirs_done,
+ find_files,
+ basedir)
+ end
+ elseif lfsisdir(path) then --- arrow code ahead
+ if done[path] then
+ logreport ("log", 3, "db",
+ "Skipping directory at %s, already included.", path)
+ else
+ done[path] = true
+ local config_files = find_files (path, conf_filter)
+ for _, filename in next, config_files do
+ if done[filename] then
+ logreport ("log", 3, "db",
+ "Skipping file at %s, already included.", filename)
+ else
+ done[filename] = true
+ acc = read_fonts_conf_indeed(depth + 1,
+ filename,
+ home,
+ xdg_config_home,
+ xdg_data_home,
+ acc,
+ done,
+ dirs_done,
+ find_files,
+ basedir)
+ end
+ end
+ end
+ end --- match “kindâ€
+ end --- iterate paths
+ end
+
+ --inspect(acc)
+ --inspect(done)
+ return acc, done, dirs_done
+end --- read_fonts_conf_indeed()
+-- /MK
+
+--[[doc--
+ read_fonts_conf() sets up an accumulator and two sets
+ for tracking what’s been done.
+
+ Also, the environment variables HOME, XDG_DATA_HOME and
+ XDG_CONFIG_HOME -- which are constants anyways -- are expanded
+ so we don’t have to repeat that over and over again as with the
+ old parser. Now they’re just passed on to every call of
+ read_fonts_conf_indeed().
+--doc]]--
+
+--- list -> (string -> function option -> string list) -> list
+
+local read_fonts_conf = function (path_list, find_files)
+ local home = kpseexpand_path"~" --- could be os.getenv"HOME"
+ local xdg_config_home = kpseexpand_path"$XDG_CONFIG_HOME"
+ if xdg_config_home == "" then xdg_config_home = filejoin(home, ".config") end
+ local xdg_data_home = kpseexpand_path"$XDG_DATA_HOME"
+ if xdg_data_home == "" then xdg_data_home = filejoin(home, ".local/share") end
+ local acc = { } ---> list: paths collected
+ local done = { } ---> set: files inspected
+ local dirs_done = { } ---> set: dirs in list
+ for i=1, #path_list do --- we keep the state between files
+ -- MK Pass the base directory
+ acc, done, dirs_done = read_fonts_conf_indeed(0,
+ path_list[i],
+ home,
+ xdg_config_home,
+ xdg_data_home,
+ acc,
+ done,
+ dirs_done,
+ find_files,
+ filedirname(path_list[i]))
+ -- /MK
+ end
+ return acc
+end
+
+-------------------------------------------------------------------------------
+--- MISC PARSERS
+-------------------------------------------------------------------------------
+
+
+local trailingslashes = slash^1 * P(-1)
+local stripslashes = C((1 - trailingslashes)^0)
+
+local splitcomma = Ct((C(noncomma^1) + comma)^1)
+
+
+
+-------------------------------------------------------------------------------
+--- FONT REQUEST
+-------------------------------------------------------------------------------
+
+
+--[[doc------------------------------------------------------------------------
+
+ The luaotfload font request syntax (see manual)
+ has a canonical form:
+
+ \font<csname>=<prefix>:<identifier>:<features>
+
+ where
+ <csname> is the control sequence that activates the font
+ <prefix> is either “file†or “nameâ€, determining the lookup
+ <identifer> is either a file name (no path) or a font
+ name, depending on the lookup
+ <features> is a list of switches or options, separated by
+ semicolons or commas; a switch is of the form “+†foo
+ or “-†foo, options are of the form lhs “=†rhs
+
+ however, to ensure backward compatibility we also have
+ support for Xetex-style requests.
+
+ for the Xetex emulation see:
+ · The XeTeX Reference Guide by Will Robertson, 2011
+ · The XeTeX Companion by Michel Goosens, 2010
+ · About XeTeX by Jonathan Kew, 2005
+
+
+ caueat emptor.
+
+ the request is parsed into one of **four** different lookup
+ categories: the regular ones, file and name, as well as the
+ Xetex compatibility ones, path and anon. (maybe a better choice
+ of identifier would be “ambigâ€.)
+
+ according to my reconstruction, the correct chaining of the
+ lookups for each category is as follows:
+
+ | File -> ( db/filename lookup )
+
+ | Name -> ( db/name lookup,
+ db/filename lookup )
+
+ | Path -> ( db/filename lookup,
+ fullpath lookup )
+
+ | Anon -> ( kpse.find_file(), // <- for tfm, ofm
+ db/name lookup,
+ db/filename lookup,
+ fullpath lookup )
+
+ caching of successful lookups is essential. we now as of v2.2
+ have a lookup cache that is stored in a separate file. it
+ pertains only to name: lookups, and is described in more detail
+ in luaotfload-database.lua.
+
+-------------------------------------------------------------------------------
+
+ One further incompatibility between Xetex and Luatex-Fonts consists
+ in their option list syntax: apparently, Xetex requires key-value
+ options to be prefixed by a "+" (ascii “plusâ€) character. We
+ silently accept this as well, dropping the first byte if it is a
+ plus or minus character.
+
+ Reference: https://github.com/lualatex/luaotfload/issues/79#issuecomment-18104483
+
+--doc]]------------------------------------------------------------------------
+
+
+--[[doc--
+
+ Xetex style indexing begins at zero which we just increment before
+ passing it along to the font loader. Ymmv.
+
+--doc]]--
+
+local handle_xetex_option = function (val)
+ return tostring(1 + tonumber(val))
+end
+
+--[[doc--
+
+ Dirty test if a file: request is actually a path: lookup; don’t
+ ask! Note this fails on Windows-style absolute paths. These will
+ *really* have to use the correct request.
+
+--doc]]--
+
+local check_garbage = function (_,i, garbage)
+ if stringfind(garbage, "/") then
+ logreport("log", 0, "load", --- ffs use path!
+ "warning: path in file: lookups is deprecated; ")
+ logreport("log", 0, "load", "use bracket syntax instead!")
+ logreport("log", 0, "load",
+ "position: %d; full match: %q",
+ i, garbage)
+ return true
+ end
+ return false
+end
+
+local featuresep = comma + semicolon
+
+--- modifiers ---------------------------------------------------------
+--[[doc--
+ The slash notation: called “modifiers†(Kew) or “font optionsâ€
+ (Robertson, Goosens)
+ we only support the shorthands for italic / bold / bold italic
+ shapes, as well as setting optical size, the rest is ignored.
+--doc]]--
+local style_modifier = (P"BI" + P"IB" + P"bi" + P"ib" + S"biBI")
+ / stringlower
+local size_modifier = S"Ss" * P"=" --- optical size
+ * Cc"optsize" * C(decimal)
+local other_modifier = P"AAT" + P"aat" --- apple stuff; unsupported
+ + P"ICU" + P"icu" --- not applicable
+ + P"GR" + P"gr" --- sil stuff; unsupported
+local garbage_modifier = ((1 - colon - slash)^0 * Cc(false))
+local modifier = slash * (other_modifier --> ignore
+ + Cs(style_modifier) --> collect
+ + Ct(size_modifier) --> collect
+ + garbage_modifier) --> warn
+local modifier_list = Cg(Ct(modifier^0), "modifiers")
+
+--- combining ---------------------------------------------------------
+---
+--- \font \three = combo: 1->42; 2->99,0xdeadbeef; 3->(1,U+2a-U+1337*42)
+--- v +~ v +~ +~~~~~~~~~ v v +~~~ +~~~~~ +~
+--- | | | | | | | | | |
+--- | | | | | | | | | |
+--- idx : ---+--÷---+--÷--÷-----------+ | +----+ |
+--- | | | | | |
+--- id : ------+------+--÷---------------+ +-----------+
+--- | |
+--- chars : ----------------+-----------------+
+---
+local comborowsep = ws * semicolon * ws
+local combomapsep = ws * P"->" * ws
+local combodefsep = ws * comma * ws
+local comborangesep = ws * asterisk * ws
+
+local combohex = hex / tonumber
+local combouint = digit^1 / tonumber
+local tonumber16 = function (s) return tonumber (s, 16) end
+local combouni = P"U+" * (digit^1 / tonumber16)
+local combonum = combohex + combouni + combouint
+local comborange = Ct(combonum * dash * combonum) + combonum
+local combochars = comborange * (comborangesep * comborange)^0
+local parenthesized = function (p) return P"(" * ws * p * ws * P")" end
+
+local comboidxpat = Cg(combouint, "idx")
+local comboidpat = Cg(combouint, "id" )
+local combocharspat = Cg(P"fallback" * Cc(true) + Ct(combochars^1), "chars")
+local comboidcharspat = comboidpat * combodefsep * combocharspat
+
+local comboidx = parenthesized (comboidxpat ) + comboidxpat
+local comboid = parenthesized (comboidpat ) + comboidpat
+local comboidchars = parenthesized (comboidcharspat) + comboidcharspat
+
+local combodef1 = Ct(comboidx * combomapsep * comboid) --> no chars
+local combodef = Ct(comboidx * combomapsep * comboidchars)
+local combolist = Ct(combodef1 * (comborowsep * combodef)^1)
+
+--- subfonts ----------------------------------------------------------
+--- This rule is present in the original parser. It sets the “subâ€
+--- field of the specification which allows addressing a specific
+--- font inside a TTC container. Neither in Luatex-Fonts nor in
+--- Luaotfload is this documented, so we might as well silently drop
+--- it. However, as backward compatibility is one of our prime goals we
+--- just insert it here and leave it undocumented until someone cares
+--- to ask. (Note: afair subfonts are numbered, but this rule matches a
+--- string; I won’t mess with it though until someone reports a
+--- problem.)
+--- local subvalue = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim
+--- Note to self: subfonts apparently start at index 0. Tested with
+--- Cambria.ttc that includes “Cambria Math†at 0 and “Cambria†at 1.
+--- Other values cause luatex to segfault.
+local subfont = P"(" * Cg((1 - S"()")^1, "sub") * P")"
+
+--- lookups -----------------------------------------------------------
+local fontname = C((1-S":(/")^1) --- like luatex-fonts
+local unsupported = Cmt((1-S":(")^1, check_garbage)
+local combo = Cg(P"combo", "lookup") * colon * ws
+ * Cg(combolist, "name")
+--- initially we intended file: to emulate the behavior of
+--- luatex-fonts, i.e. no paths allowed. after all, we do have XeTeX
+--- emulation with the path lookup and it interferes with db lookups.
+--- turns out fontspec and other widely used packages rely on file:
+--- with paths already, so we’ll add a less strict rule here. anyways,
+--- we’ll emit a warning.
+local prefixed = P"file:" * ws * Cg(Cc"path", "lookup")
+ * Cg(unsupported, "name")
+ + Cg(P"name" + "file" + "kpse" + "my", "lookup")
+ * colon * ws * Cg(fontname, "name")
+local unprefixed = Cg(Cc"anon", "lookup") * Cg(fontname, "name")
+--- Bracketed “path†lookups: These may contain any character except
+--- for unbalanced brackets. A backslash escapes any following
+--- character. Everything inside the outermost brackets is treated as
+--- part of the filename or path to look up. Subfonts may be specified
+--- in parens *after* the closing bracket. Note that this differs from
+--- Xetex whose syntax expects the subfont passed inside the brackets,
+--- separated by a colon.
+local path_escape = backslash / "" * patterns.utf8char
+local path_content = path_escape + (1 - brackets)
+local path_balanced = { (path_content + V(2))^1
+ , lbrk * V(1)^-1 * rbrk }
+local path_lookup = Cg(Cc"path", "lookup")
+ * lbrk * Cg(Cs(path_balanced), "name") * rbrk
+ * subfont^-1
+
+--- features ----------------------------------------------------------
+local balanced_braces = P{((1 - S'{}') + '{' * V(1) * '}')^0}
+local field_char = '{' * balanced_braces * '}' + (1 - S'={}' - featuresep)
+local field = '{' * C(balanced_braces) * '}' + C(field_char^1)
+--- assignments are “lhs=rhsâ€
+--- or “+lhs=rhs†(Xetex-style)
+--- switches are “+key†| “-keyâ€
+local normal_option = field * ws * equals * ws * field
+local xetex_option = P"+" * ws * ( field * ws * equals * ws
+ * (digit^1/handle_xetex_option)
+ + normal_option)
+local assignment = xetex_option
+ + normal_option
+local switch = P"-" * ws * field * Cc(false)
+ + P"+"^-1 * ws * field * Cc(true)
+local feature_expr = ws * Cg(assignment + switch) * ws
+local option = feature_expr
+local feature_list = Cf(Ct""
+ * option
+ * (featuresep * option^-1)^0
+ , rawset)
+ * featuresep^-1
+--- top-level rules ---------------------------------------------------
+--- \font\foo=<specification>:<features>
+local features = Cg(feature_list, "features")
+local specification = (prefixed + unprefixed)
+ * subfont^-1
+ * modifier_list
+local font_request = Ct(path_lookup * (colon^-1 * features)^-1
+ + combo --> TODO: feature list needed?
+ + specification * (colon * features)^-1)
+
+-- lpeg.print(font_request)
+--- v2.5 parser: 1065 rules
+--- v1.2 parser: 230 rules
+
+-------------------------------------------------------------------------------
+--- INI FILES
+-------------------------------------------------------------------------------
+
+--[[doc--
+
+ Luaotfload uses the pervasive flavor of the INI files that allows '#' in
+ addition to ';' to indicate comment lines (see git-config(1) for a
+ description of the syntax we’re targeting).
+
+--doc]]--
+
+local truth_ids = {
+ ["true"] = true,
+ ["1"] = true,
+ yes = true,
+ on = true,
+ ["false"] = false,
+ ["2"] = false,
+ no = false,
+ off = false,
+}
+
+local maybe_cast = function (var)
+ local bool = truth_ids[var]
+ if bool ~= nil then
+ return bool
+ end
+ return tonumber (var) or var
+end
+
+local escape = function (chr, repl)
+ return (backslash * P(chr) / (repl or chr))
+end
+
+local valid_escapes = escape "\""
+ + escape "\\"
+ + escape ("n", "\n")
+ + escape ("t", "\t")
+ + escape ("b", "\b")
+local comment_char = semicolon + gartenzaun
+local comment_line = ws * comment_char * (1 - eol)^0 * eol
+local blank_line = ws * eol
+local skip_line = comment_line + blank_line
+local ini_id_char = alpha + (dash / "_")
+local ini_id = Cs(alpha * ini_id_char^0) / stringlower
+local ini_value_char = (valid_escapes + (1 - linebreak - backslash - comment_char))
+local ini_value = (Cs (ini_value_char^0) / string.strip)
+ * (comment_char * (1 - eol)^0)^-1
+local ini_string_char = (valid_escapes + (1 - linebreak - dquote - backslash))
+local ini_string = dquote
+ * Cs (ini_string_char^0)
+ * dquote
+
+local ini_heading_title = Ct (Cg (ini_id, "title")
+ * (ws * Cg (ini_string / stringlower, "subtitle"))^-1)
+local ini_heading = lbrk * ws
+ * Cg (ini_heading_title, "section")
+ * ws * rbrk * ws * eol
+
+local ini_variable_full = Cg (ws
+ * ini_id
+ * ws
+ * equals
+ * ws
+ * (ini_string + (ini_value / maybe_cast))
+ * ws
+ * eol)
+local ini_variable_true = Cg (ws * ini_id * ws * eol * Cc (true))
+local ini_variable = ini_variable_full
+ + ini_variable_true
+ + skip_line
+local ini_variables = Cg (Cf (Ct "" * ini_variable^0, rawset), "variables")
+
+local ini_section = Ct (ini_heading * ini_variables)
+local ini_sections = skip_line^0 * ini_section^0
+local parse_config = Ct (ini_sections)
+
+--[=[doc--
+
+ The INI parser converts an input of the form
+
+ [==[
+ [foo]
+ bar = baz
+ xyzzy = no
+ buzz
+
+ [lavernica "brutalitops"]
+ # It’s a locomotive that runs on us.
+ laan-ev = zip zop zooey ; jib-jab
+ Crouton = "Fibrosis \"\\ # "
+
+ ]==]
+
+ to a Lua table of the form
+
+ { { section = { title = "foo" },
+ variables = { bar = "baz",
+ xyzzy = false,
+ buzz = true } },
+ { section = { title = "boing",
+ subtitle = "brutalitops" },
+ variables = { ["laan-ev"] = "zip zop zooey",
+ crouton = "Fibrosis \"\\ # " } } }
+
+--doc]=]--
+
+return function ()
+ logreport = luaotfload.log.report
+ luaotfload.parsers = {
+ --- parameters
+ traversal_maxdepth = traversal_maxdepth,
+ --- main parsers
+ read_fonts_conf = read_fonts_conf,
+ font_request = font_request,
+ config = parse_config,
+ --- common patterns
+ stripslashes = stripslashes,
+ splitcomma = splitcomma,
+ }
+ return true
+end
+
+-- vim:ft=lua:tw=71:et:sw=2:sts=4:ts=8
diff --git a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
new file mode 100644
index 0000000000..839155a979
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
@@ -0,0 +1,303 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-resolvers.lua
+-- USAGE: ./luaotfload-resolvers.lua
+-- DESCRIPTION: Resolvers for hooking into the fontloader
+-- REQUIREMENTS: Luaotfload and a decent bit of courage
+-- AUTHOR: Philipp Gesang (Phg), <phg@phi-gamma.net>
+-----------------------------------------------------------------------
+--
+--- The bare fontloader uses a set of simplistic file name resolvers
+--- that must be overloaded by the user (i. e. us).
+
+local ProvidesLuaModule = {
+ name = "luaotfload-resolvers",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / resolvers",
+ license = "GPL v2.0"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+
+if not lualibs then error "this module requires Luaotfload" end
+if not luaotfload then error "this module requires Luaotfload" end
+
+--[[doc--
+
+ Relying on the \verb|name:| resolver for everything has been the
+ source of permanent trouble with the database.
+ With the introduction of the new syntax parser we now have enough
+ granularity to distinguish between the \XETEX emulation layer and
+ the genuine \verb|name:| and \verb|file:| lookups of \LUATEX-Fonts.
+ Another benefit is that we can now easily plug in or replace new
+ lookup behaviors if necessary.
+ The name resolver remains untouched, but it calls
+ \luafunction{fonts.names.resolve()} internally anyways (see
+ \fileent{luaotfload-database.lua}).
+
+--doc]]--
+
+local next = next
+local tableconcat = table.concat
+local kpsefind_file = kpse.find_file
+local lfsisfile = lfs.isfile
+local stringlower = string.lower
+local stringformat = string.format
+local filesuffix = file.suffix
+local fileremovesuffix = file.removesuffix
+local luatexbase = luatexbase
+local logreport = luaotfload.log.report
+
+--[[doc--
+
+ \identifier{luaotfload} promises easy access to system fonts.
+ Without additional precautions, this cannot be achieved by
+ \identifier{kpathsea} alone, because it searches only the
+ \fileent{texmf} directories by default.
+ Although it is possible for \identifier{kpathsea} to include extra
+ paths by adding them to the \verb|OSFONTDIR| environment variable,
+ this is still short of the goal »\emphasis{it just works!}«.
+ When building the font database \identifier{luaotfload} scans
+ system font directories anyways, so we already have all the
+ information for looking sytem fonts.
+ With the release version 2.2 the file names are indexed in the
+ database as well and we are ready to resolve \verb|file:| lookups
+ this way.
+ Thus we no longer need to call the \identifier{kpathsea} library in
+ most cases when looking up font files, only when generating the
+ database, and when verifying the existence of a file in the
+ \fileent{texmf} tree.
+
+--doc]]--
+
+local function resolve_file (specification)
+ local name, _format, success = fonts.names.lookup_font_file (specification.name)
+ if success then return name end
+ logreport ("log", 1, "resolve", "file lookup of %q unsuccessful", name)
+end
+
+--[[doc--
+
+ Prior to version 2.2, \identifier{luaotfload} did not distinguish
+ \verb|file:| and \verb|path:| lookups, causing complications with
+ the resolver.
+ Now we test if the requested name is an absolute path in the file
+ system, otherwise we fall back to the \verb|file:| lookup.
+
+--doc]]--
+
+local function resolve_path (specification)
+ local name = specification.name
+ if lfsisfile (name) then return name end
+ logreport ("log", 1, "resolve",
+ "path lookup of %q unsuccessful, falling back to file:",
+ name)
+ return resolve_file (specification)
+end
+
+--[[doc--
+
+ The \verb|name:| resolver.
+
+--doc]]--
+
+--- fonts.names.resolvers.name -- Customized version of the
+--- generic name resolver.
+
+local function resolve_name (specification)
+ local resolver = fonts.names.lookup_font_name_cached
+ if config.luaotfload.run.resolver == "normal" then
+ resolver = fonts.names.lookup_font_name
+ end
+ local resolved, subfont = resolver (specification)
+ if resolved then
+ logreport ("log", 1, "resolve", "name lookup %q -> \"%s%s\"",
+ specification.name, resolved,
+ subfont and stringformat ("(%d)", subfont) or "")
+ return resolved, tonumber(subfont)
+ end
+ return resolve_file (specification)
+end
+
+--[[doc--
+
+ We classify as \verb|anon:| those requests that have neither a
+ prefix nor brackets. According to Khaled\footnote{%
+ % XXX dead link‽
+ \url{https://github.com/phi-gamma/luaotfload/issues/4#issuecomment-17090553}.
+ }
+ they are the \XETEX equivalent of a \verb|name:| request, so we
+ will be treating them as such or, at least, in a similar fashion.
+
+ Not distinguishing between “anon†and “name†requests has a serious
+ drawback: The syntax is overloaded for requesting fonts in
+ \identifier{Type1} (\abbrev{tfm}, \abbrev{ofm}) format.
+ These are essentially \verb|file:| lookups and must be caught
+ before the \verb|name:| resolver kicks in, lest they cause the
+ database to update.
+ Even if we were to require the \verb|file:| prefix for all
+ \identifier{Type1} requests, tests have shown that certain fonts
+ still include further fonts (e.~g. \fileent{omlgcb.ofm} will ask
+ for \fileent{omsecob.tfm}) \emphasis{using the old syntax}.
+ For this reason, we introduce an extra check with an early return.
+
+--doc]]--
+
+local tex_formats = { "tfm", "ofm" }
+
+local resolve_tex_format = function (specification)
+ local name = specification.name
+ for i=1, #tex_formats do
+ local format = tex_formats [i]
+ local resolved = resolvers.findfile(name, format)
+ if resolved then
+ return resolved, format
+ end
+ end
+end
+
+local resolve_path_if_exists = function (specification)
+ local spec = specification.specification
+ local exists = lfsisfile (spec)
+ if exists then
+ --- If this path is taken a file matching the specification
+ --- literally was found. In this situation, Luaotfload is
+ --- expected to load that file directly, even though we provide
+ --- explicit “file†and “path†lookups to address exactly this
+ --- situation.
+ logreport ("log", 1, "resolve",
+ "file %q exists, performing path lookup", spec)
+ return spec
+ end
+end
+
+--[[doc--
+ Custom file resolvers via callback.
+--doc]]--
+
+local resolve_my = function (specification)
+ return luatexbase.call_callback ("luaotfload.resolve_font", specification)
+end
+
+local resolve_methods = {
+ tex = resolve_tex_format,
+ path = resolve_path_if_exists,
+ name = resolve_name,
+ file = resolve_file,
+ my = resolve_my,
+}
+
+local resolve_sequence = function (seq, specification)
+ for i = 1, #seq do
+ local id = seq [i]
+ local mth = resolve_methods [id]
+ if not mth then
+ logreport ("both", 0, "resolve",
+ "step %d: invalid lookup method %q", i, id)
+ else
+ logreport ("both", 3, "resolve", "step %d: apply method %q (%s)", i, id, mth)
+ local result, t = mth (specification)
+ if result then
+ logreport ("both", 3, "resolve",
+ "%d: method %q resolved %q -> %s.",
+ i, id, specification.specification, result)
+ return result, t
+ end
+ end
+ end
+ logreport ("both", 0, "resolve",
+ "sequence of %d lookups yielded nothing appropriate.", #seq)
+end
+
+local default_anon_sequence = {
+ "tex", "path", "name",
+}
+
+local function resolve_anon (specification)
+ return resolve_sequence (config.luaotfload.run.anon_sequence, specification)
+end
+
+--[[doc--
+
+ {\bfseries EXPERIMENTAL}:
+ \identifier{kpse}-only resolver, for those who can do without
+ system fonts.
+
+--doc]]--
+
+local function resolve_kpse (specification)
+ local name = specification.name
+ local suffix = stringlower (filesuffix (name))
+ if suffix and fonts.formats[suffix] then
+ local resolved = resolvers.findfile(name, suffix)
+ if resolved then return resolved end
+ end
+ for t, format in next, fonts.formats do --- brute force
+ local resolved = kpsefind_file (name, format)
+ if resolved then return resolved, t end
+ end
+end
+
+local function wrap_resolver(resolver)
+ return function (specification)
+ local filename, sub, forced = resolver(specification)
+ if type(sub) ~= "number" then
+ forced = sub
+ sub = nil
+ end
+ if filename then
+ specification.resolved = filename
+ specification.filename = filename
+ specification.name = filename
+ specification.sub = sub or specification.sub
+ specification.forced = specification.forced or forced
+ if not specification.forced then
+ local suffix = stringlower (filesuffix (filename))
+ if suffix and fonts.formats[suffix] then
+ specification.forced = suffix
+ end
+ end
+ if specification.forced then
+ specification.forcedname = filename
+ end
+ return true
+ end
+ return false
+ end
+end
+
+local resolvers = table.merge(luaotfload.resolvers, {
+ path = resolve_path,
+ name = resolve_name,
+ anon = resolve_anon,
+ file = resolve_file,
+ kpse = resolve_kpse,
+ my = resolve_my,
+})
+luaotfload.resolvers = resolvers
+
+return function()
+ if luatexbase and luatexbase.create_callback then
+ luatexbase.create_callback ("luaotfload.resolve_font",
+ "exclusive", function () end)
+ end
+ logreport ("log", 5, "resolvers", "installing font resolvers", name)
+ local request_resolvers = fonts.definers.resolvers
+ for k, _ in pairs(resolvers) do
+ request_resolvers[k] = nil
+ end
+ setmetatable(request_resolvers, {__index = function(t, n)
+ if not resolvers[n] then return end
+ local wrapped = wrap_resolver(resolvers[n])
+ t[n] = wrapped
+ return wrapped
+ end})
+ fonts.formats.ofm = "type1"
+ fonts.encodings = fonts.encodings or { }
+ fonts.encodings.known = fonts.encodings.known or { }
+ return true
+end
+--- vim:ft=lua:ts=8:sw=4:et:tw=79
diff --git a/macros/luatex/generic/luaotfload/luaotfload-status.lua b/macros/luatex/generic/luaotfload/luaotfload-status.lua
new file mode 100644
index 0000000000..bd7b328979
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-status.lua
@@ -0,0 +1,90 @@
+return {
+ ["hashes"]={
+ { "fontloader-2019-08-11.lua", "9ad89bd01fccf2f98b8777ad42851c58" },
+ { "fontloader-util-fil.lua", "4bb3e4dc72e308d8ed67cd7a80027fa7" },
+ { "fontloader-util-str.lua", "3c829af0b336703e62cb5a1cb7a6e503" },
+ { "fontloader-l-unicode.lua", "d46cc6cf18fb3f368ef1e404dc9fcb5c" },
+ { "fontloader-l-math.lua", "a373be3ed2db0d5f98588fa81abca48f" },
+ { "fontloader-l-boolean.lua", "18ed6c4b2c40dd87224ea33229548d20" },
+ { "fontloader-l-file.lua", "3d6ea476061292a0da98c3f65cdabe46" },
+ { "fontloader-l-io.lua", "42608ad95eb2822fdc370d1c11f08fb5" },
+ { "fontloader-l-table.lua", "63b13279139d2f94d29238b0d6242330" },
+ { "fontloader-l-string.lua", "e1347bef0eeeff9f098df83b30b32df9" },
+ { "fontloader-l-function.lua", "f771cc91839ebcdfc094083434fbe00f" },
+ { "fontloader-l-lpeg.lua", "a5364ddabb490408da9276ea7f7a7ba1" },
+ { "fontloader-l-lua.lua", "9e5e9d4f3b8f9e337f28aa2322192b94" },
+ { "fontloader-fonts-gbn.lua", "d25472d54c4841db43a745764a63533e" },
+ { "fontloader-fonts-lig.lua", "b9dbe77ce747d4c35bb2a20ffbe5aa51" },
+ { "fontloader-fonts-ext.lua", "01015ab3758cdc2af29394e6d502a91a" },
+ { "fontloader-fonts-def.lua", "5ad79120ebc5e60f4d322fb3ee13bffe" },
+ { "fontloader-fonts-tfm.lua", "3bbba3214fd0b8c6f35ad85592fc2917" },
+ { "fontloader-fonts-enc.lua", "3e71a54297e8f85a1ac438bb0f20dd79" },
+ { "fontloader-fonts-mis.lua", "bc9eb43c27f63ce9d0fff67e104fe1c6" },
+ { "fontloader-basics-chr.lua", "58b7ef0c486e06090b362971b9f85e27" },
+ { "fontloader-basics-nod.lua", "65064d03c2650a1761ee13ebd9e1400a" },
+ { "fontloader-font-imp-effects.lua", "73a660359a0ec71e44cc2b7225a715ac" },
+ { "fontloader-font-imp-italics.lua", "fe1ca80fb5ea4a2f8d2d5c484e7ba913" },
+ { "fontloader-font-imp-ligatures.lua", "043daa4fcccf2560868da359d71d3a4a" },
+ { "fontloader-font-imp-tex.lua", "77c374b0ef00c2fb12188ec42beb4257" },
+ { "fontloader-font-def.lua", "f66c365dae4499f982d8bf16e5d37de3" },
+ { "fontloader-font-lua.lua", "55b281fb98f7bd848fc19928f376f647" },
+ { "fontloader-font-afk.lua", "54d554530e75c57c56ee76234724e26d" },
+ { "fontloader-font-one.lua", "987c5c5ed3754ad2feab80985067d59e" },
+ { "fontloader-font-onr.lua", "d4d2449b4084e6afb1837ae5835082cc" },
+ { "fontloader-font-otc.lua", "95a4ff28ba4afb55a978a4aecfd688bf" },
+ { "fontloader-font-ocl.lua", "b720867fb19a23f0b50377efd2a3c54a" },
+ { "fontloader-font-osd.lua", "79eb2fc4a71364fd73c8b996a109f5df" },
+ { "fontloader-font-ots.lua", "d5504847a278385cd0d20ecf1b3d59cc" },
+ { "fontloader-font-ota.lua", "d6dfb94563d6a52675e274b2e673e4a6" },
+ { "fontloader-font-otj.lua", "66c7a910d95d4a52b81061de776898e1" },
+ { "fontloader-font-oto.lua", "52804afd96f4be005f513a012b874668" },
+ { "fontloader-font-otl.lua", "940f9c5ad84f4968a8488f4da2d15e2d" },
+ { "fontloader-font-oup.lua", "669e479e716999edc626a1f045bd76fa" },
+ { "fontloader-font-dsp.lua", "b5bf2f1c198e027a0d4ededcdf3947b4" },
+ { "fontloader-font-ttf.lua", "44e61cef50dab9b1aaf48130f9367c34" },
+ { "fontloader-font-cff.lua", "98d5a660ea803b65cb883c009ecf3c0b" },
+ { "fontloader-font-ott.lua", "aba6d8335a5f38a5a62d3631492f3392" },
+ { "fontloader-font-oti.lua", "dbae7722baae24d917a17176553825cf" },
+ { "fontloader-font-otr.lua", "b1c03925c949027c86f781785fa7a208" },
+ { "fontloader-font-vfc.lua", "94937140f2c909e9c831ba021f1ab303" },
+ { "fontloader-font-map.lua", "f486746e90fe972de4b73e208ac7cbb2" },
+ { "fontloader-font-cid.lua", "4d87988efa86020a14708ee03c23415f" },
+ { "fontloader-font-con.lua", "ca733211a0555d9a93b1e2f7ebc937d3" },
+ { "fontloader-font-ini.lua", "4299a02110bbd7c0d27e131235c5319d" },
+ { "fontloader-data-con.lua", "7ce546725b1550f655c78ac9d69419ca" },
+ { "fontloader-reference.lua", "759787e7ee75437382c0a2c4f8fe3b81" },
+ { "fontloader-basics-gen.lua", "b21e91bbd534f77e368f0ec13f865aed" },
+ { "mktests", "c7cff7025962922944376acc1ffa9c47" },
+ { "mkstatus", "d84c8b2ae4c2335c5dbd9fba4846f0e9" },
+ { "mkcharacters", "92c24bb582fc84c0365634f29eb89863" },
+ { "mkglyphlist", "557836886d4f0e6d656eac3ded4456a2" },
+ { "mkimport", "60e0b11a1a68719033e86a3e0f4d5e86" },
+ { "luaotfload-glyphlist.lua", "8a1cbf89f48a8ebe05a13345352a3435" },
+ { "luaotfload-characters.lua", "593ce9dccf6ddc4f7d4be0514f581102" },
+ { "luaotfload-unicode.lua", "aac378708c062d4de18132ae7600526f" },
+ { "luaotfload-resolvers.lua", "7e777d41afc10c928cd26dccfed6ba09" },
+ { "luaotfload-parsers.lua", "c69570b5f57d26abff8304f3a8eade58" },
+ { "luaotfload-loaders.lua", "920578f2f66758755c20fbf3539b3542" },
+ { "luaotfload-notdef.lua", "a4a40c92368510dcd81f6e95124bb2d3" },
+ { "luaotfload-embolden.lua", "4b6a0240b0f696d63cf2b343603fc742" },
+ { "luaotfload-letterspace.lua", "29453f635acb72ef76ec19942ce0449b" },
+ { "luaotfload-features.lua", "1c837c95c485d54204157fd3840e177e" },
+ { "luaotfload-database.lua", "3a3d0cbb02b0c9ff53b0dab969c7a879" },
+ { "luaotfload-configuration.lua", "37ffbef314b79ca2ae9bfaf4e4552207" },
+ { "luaotfload-colors.lua", "9b1ffa13d20cc4d1f2016e8d5b0939f1" },
+ { "luaotfload-auxiliary.lua", "99ff2ebee659717c2d1f9999e3ab4448" },
+ { "luaotfload-filelist.lua", "9de0e08f4b15acd7c56602ef362967e1" },
+ { "luaotfload-tool.lua", "4a1be51390301a48480681e66d9be64f" },
+ { "luaotfload-diagnostics.lua", "8c50e2459731ca15a511e4bd0b0d7685" },
+ { "luaotfload-log.lua", "981ccf90bb3a970b056dbfa87046b36d" },
+ { "luaotfload-init.lua", "acfe693817999d5c09272f3b33fe1aad" },
+ { "luaotfload-main.lua", "80b07ab0301a7b8fb5d03acec1b5c5dc" },
+ },
+ ["notes"]={
+ ["committer"]="Ulrike Fischer <fischer@troubleshooting-tex.de>",
+ ["description"]="v2.991/2019-08-11",
+ ["loader"]="fontloader-2019-08-11.lua",
+ ["revision"]="a86a6798c324c745af7b04f33fa188298d749a2a",
+ ["timestamp"]="2019-08-19 19:38:30 +0200",
+ },
+} \ No newline at end of file
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.1 b/macros/luatex/generic/luaotfload/luaotfload-tool.1
new file mode 100644
index 0000000000..81b5c22d6d
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.1
@@ -0,0 +1,442 @@
+.\" Man page generated from reStructuredText.
+.
+.TH LUAOTFLOAD-TOOL 1 "2019-08-11" "2.991" "text processing"
+.SH NAME
+luaotfload-tool \- generate and query the Luaotfload font names database
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.SH SYNOPSIS
+.sp
+\fBluaotfload\-tool\fP [ \-bcDfFiIlLnpqRSuvVhw ]
+.INDENT 0.0
+.TP
+.B \fBluaotfload\-tool\fP \-\-update [ \-\-force ] [ \-\-quiet ] [ \-\-verbose ]
+[ \-\-prefer\-texmf ] [ \-\-dry\-run ]
+[ \-\-formats=[+|\-]EXTENSIONS ]
+[ \-\-no\-compress ] [ \-\-no\-strip ]
+[ \-\-local ] [ \-\-max\-fonts=N ]
+.TP
+.B \fBluaotfload\-tool\fP \-\-find=FONTNAME [ \-\-fuzzy ] [ \-\-info ] [ \-\-inspect ]
+[ \-\-no\-reload ]
+.UNINDENT
+.sp
+\fBluaotfload\-tool\fP \-\-flush\-lookups
+.sp
+\fBluaotfload\-tool\fP \-\-cache=DIRECTIVE
+.sp
+\fBluaotfload\-tool\fP \-\-list=CRITERION[:VALUE] [ \-\-fields=F1,F2,...,Fn ]
+.sp
+\fBluaotfload\-tool\fP \-\-bisect=DIRECTIVE
+.sp
+\fBluaotfload\-tool\fP \-\-help
+.sp
+\fBluaotfload\-tool\fP \-\-version
+.sp
+\fBluaotfload\-tool\fP \-\-show\-blacklist
+.sp
+\fBluaotfload\-tool\fP \-\-diagnose=CHECK
+.sp
+\fBluaotfload\-tool\fP \-\-conf=FILE \-\-dumpconf
+.SH DESCRIPTION
+.sp
+luaotfload\-tool accesses the font names database that is required by
+the \fILuaotfload\fP package. There are two general modes: \fBupdate\fP and
+\fBquery\fP\&.
+.INDENT 0.0
+.IP \(bu 2
+\fBupdate\fP: update the database or rebuild it entirely;
+.IP \(bu 2
+\fBquery\fP: resolve a font name or display close matches.
+.UNINDENT
+.SH OPTIONS
+.SS update mode
+.INDENT 0.0
+.TP
+.B \-\-update\fP,\fB \-u
+Update the database; indexes new fonts.
+.TP
+.B \-\-force\fP,\fB \-f
+Force rebuilding of the database; re\-indexes
+all fonts.
+.TP
+.B \-\-local\fP,\fB \-L
+Include font files in \fB$PWD\fP\&. This option
+will cause large parts of the database to be
+rebuilt. Thus it is quite inefficient.
+Additionally, if local font files are found,
+the database is prevented from being saved
+to disk, so the local fonts need to be parsed
+with every invocation of \fBluaotfload\-tool\fP\&.
+.TP
+.B \-\-no\-reload\fP,\fB \-n
+Suppress auto\-updates to the database (e.g.
+when \fB\-\-find\fP is passed an unknown name).
+.TP
+.B \-\-no\-compress\fP,\fB \-c
+Do not filter the plain text version of the
+font index through gzip. Useful for debugging
+if your editor is built without zlib.
+.TP
+.B \-\-prefer\-texmf\fP,\fB \-p
+Organize the file name database in a way so
+that it prefer fonts in the \fITEXMF\fP tree over
+system fonts if they are installed in both.
+.TP
+.BI \-\-formats\fB= EXTENSIONS
+Extensions of the font files to index.
+Where \fIEXTENSIONS\fP is a comma\-separated list of
+supported file extensions (otf, ttf, ttc).
+If the list is prefixed
+with a \fB+\fP sign, the given list is added to
+the currently active one; \fB\-\fP subtracts.
+Default: \fIotf,ttf,ttc\fP\&.
+Examples:
+.INDENT 7.0
+.IP 1. 3
+\fB\-\-formats=\-ttc,ttf\fP would skip
+TrueType fonts and font collections;
+.IP 2. 3
+\fB\-\-formats=otf\fP would scan only OpenType
+files;
+.IP 3. 3
+\fB\-\-formats=+afm\fP includes binary
+Postscript files accompanied by an AFM file.
+.UNINDENT
+.UNINDENT
+.SS query mode
+.INDENT 0.0
+.TP
+.BI \-\-find\fB= NAME
+Resolve a font name; this looks up <name> in
+the database and prints the file name it is
+mapped to.
+\fB\-\-find\fP also understands request syntax,
+i.e. \fB\-\-find=file:foo.otf\fP checks whether
+\fBfoo.otf\fP is indexed.
+.TP
+.B \-\-fuzzy\fP,\fB \-F
+Show approximate matches to the file name if
+the lookup was unsuccessful (requires
+\fB\-\-find\fP).
+.TP
+.B \-\-info\fP,\fB \-i
+Display basic information to a resolved font
+file (requires \fB\-\-find\fP).
+.TP
+.B \-\-inspect\fP,\fB \-I
+Display detailed information by loading the
+font and analyzing the font table; very slow!
+For the meaning of the returned fields see
+the LuaTeX documentation.
+(requires \fB\-\-find\fP).
+.TP
+.BI \-\-list\fB= CRITERION
+Show entries, where \fICRITERION\fP is one of the
+following:
+.INDENT 7.0
+.IP 1. 3
+the character \fB*\fP, selecting all entries;
+.IP 2. 3
+a field of a database entry, for instance
+\fIversion\fP or \fIformat*\fP, according to which
+the output will be sorted.
+Information in an unstripped database (see
+the option \fB\-\-no\-strip\fP above) is nested:
+Subfields of a record can be addressed using
+the \fB\->\fP separator, e. g.
+\fBfile\->location\fP, \fBstyle\->units_per_em\fP,
+or
+\fBnames\->sanitized\->english\->prefmodifiers\fP\&.
+NB: shell syntax requires that arguments
+containing \fB\->\fP be properly quoted!
+.IP 3. 3
+an expression of the form \fBfield:value\fP to
+limit the output to entries whose \fBfield\fP
+matches \fBvalue\fP\&.
+.UNINDENT
+.sp
+For example, in order to output file names and
+corresponding versions, sorted by the font
+format:
+.INDENT 7.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+\&./luaotfload\-tool.lua \-\-list="format" \-\-fields="file\->base,version"
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+This prints:
+.INDENT 7.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+otf latinmodern\-math.otf Version 1.958
+otf lmromancaps10\-oblique.otf 2.004
+otf lmmono8\-regular.otf 2.004
+otf lmmonoproplt10\-bold.otf 2.004
+otf lmsans10\-oblique.otf 2.004
+otf lmromanslant8\-regular.otf 2.004
+otf lmroman12\-italic.otf 2.004
+otf lmsansdemicond10\-oblique.otf 2.004
+\&...
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.TP
+.BI \-\-fields\fB= FIELDS
+Comma\-separated list of fields that should be
+printed.
+Information in an unstripped database (see the
+option \fB\-\-no\-strip\fP above) is nested:
+Subfields of a record can be addressed using
+the \fB\->\fP separator, e. g.
+\fBfile\->location\fP, \fBstyle\->units_per_em\fP,
+or \fBnames\->sanitized\->english\->subfamily\fP\&.
+The default is plainname,version*.
+(Only meaningful with \fB\-\-list\fP\&.)
+.UNINDENT
+.SS font and lookup caches
+.INDENT 0.0
+.TP
+.B \-\-flush\-lookups
+Clear font name lookup cache (experimental).
+.TP
+.BI \-\-cache\fB= DIRECTIVE
+Cache control, where \fIDIRECTIVE\fP is one of the
+following:
+.INDENT 7.0
+.IP 1. 3
+\fBpurge\fP \-> delete Lua files from cache;
+.IP 2. 3
+\fBerase\fP \-> delete Lua and Luc files from
+cache;
+.IP 3. 3
+\fBshow\fP \-> print stats.
+.UNINDENT
+.UNINDENT
+.SS debugging methods
+.INDENT 0.0
+.TP
+.B \-\-show\-blacklist\fP,\fB \-b
+Show blacklisted files (not directories).
+.TP
+.B \-\-dry\-run\fP,\fB \-D
+Don’t load fonts when updating the database;
+scan directories only.
+(For debugging file system related issues.)
+.TP
+.B \-\-no\-strip
+Do not strip redundant information after
+building the database. Warning: this will
+inflate the index to about two to three times
+the normal size.
+.TP
+.BI \-\-max\-fonts\fB= N
+Process at most \fIN\fP font files, including fonts
+already indexed in the count.
+.TP
+.BI \-\-bisect\fB= DIRECTIVE
+Bisection of the font database.
+This mode is intended as assistance in
+debugging the Luatex engine, especially when
+tracking memleaks or buggy fonts.
+.sp
+\fIDIRECTIVE\fP can be one of the following:
+.INDENT 7.0
+.IP 1. 3
+\fBrun\fP \-> Make \fBluaotfload\-tool\fP respect
+the bisection progress when running.
+Combined with \fB\-\-update\fP and possibly
+\fB\-\-force\fP this will only process the files
+from the start up until the pivot and ignore
+the rest.
+.IP 2. 3
+\fBstart\fP \-> Start bisection: create a
+bisection state file and initialize the low,
+high, and pivot indices.
+.IP 3. 3
+\fBstop\fP \-> Terminate the current bisection
+session by deleting the state file.
+.IP 4. 3
+\fBgood\fP | \fBbad\fP \-> Mark the section
+processed last as “good†or “badâ€,
+respectively. The next bisection step will
+continue with the bad section.
+.IP 5. 3
+\fBstatus\fP \-> Print status information about
+the current bisection session. Hint: Use
+with higher verbosity settings for more
+output.
+.UNINDENT
+.sp
+A bisection session is initiated by issuing the
+\fBstart\fP directive. This sets the pivot to the
+middle of the list of available font files.
+Now run \fIluaotfload\-tool\fP with the \fB\-\-update\fP
+flag set as well as \fB\-\-bisect=run\fP: only the
+fonts up to the pivot will be considered. If
+that task exhibited the issue you are tracking,
+then tell Luaotfload using \fB\-\-bisect=bad\fP\&.
+The next step of \fB\-\-bisect=run\fP will continue
+bisection with the part of the files below the
+pivot.
+Likewise, issue \fB\-\-bisect=good\fP in order to
+continue with the fonts above the pivot,
+assuming the tested part of the list did not
+trigger the bug.
+.sp
+Once the culprit font is tracked down, \fBgood\fP
+or \fBbad\fP will have no effect anymore. \fBrun\fP
+will always end up processing the single font
+file that was left.
+Use \fB\-\-bisect=stop\fP to clear the bisection
+state.
+.UNINDENT
+.SS miscellaneous
+.INDENT 0.0
+.TP
+.BI \-\-verbose\fB= N\fP,\fB \ \-v
+Set verbosity level to \fIn\fP or the number of
+repetitions of \fB\-v\fP\&.
+.TP
+.B \-\-quiet
+No verbose output (log level set to zero).
+.TP
+.BI \-\-log\fB= CHANNEL
+Redirect log output (for database
+troubleshooting), where \fICHANNEL\fP can be
+.INDENT 7.0
+.IP 1. 3
+\fBstdout\fP \-> all output will be
+dumped to the terminal (default); or
+.IP 2. 3
+\fBfile\fP \-> write to a file to the temporary
+directory (the name will be chosen
+automatically.
+.UNINDENT
+.TP
+.B \-\-version\fP,\fB \-V
+Show version numbers of components as well as
+some basic information and exit.
+.TP
+.B \-\-help\fP,\fB \-h
+Show help message and exit.
+.TP
+.BI \-\-diagnose\fB= CHECK
+Run the diagnostic procedure \fICHECK\fP\&. Available
+procedures are:
+.INDENT 7.0
+.IP 1. 3
+\fBfiles\fP \-> check \fILuaotfload\fP files for
+modifications;
+.IP 2. 3
+\fBpermissions\fP \-> check permissions of
+cache directories and files;
+.IP 3. 3
+.INDENT 3.0
+.TP
+.B \fBenvironment\fP \-> print relevant
+environment and kpse variables;
+.UNINDENT
+.IP 4. 3
+\fBrepository\fP \-> check the git repository
+for new releases,
+.IP 5. 3
+\fBindex\fP \-> check database, display
+information about it.
+.UNINDENT
+.sp
+Procedures can be chained by concatenating with
+commas, e.g. \fB\-\-diagnose=files,permissions\fP\&.
+Specify \fBthorough\fP to run all checks.
+.TP
+.BI \-\-conf\fB= FILE
+Read the configuration from \fIFILE\fP\&. See
+\fBluaotfload.conf\fP(%) for documentation
+concerning the format and available options.
+.TP
+.B \-\-dumpconf
+Print the currently active configuration; the
+output can be saved to a file and used for
+bootstrapping a custom configuration files.
+.UNINDENT
+.SH FILES
+.sp
+The font name database is usually located in the directory
+\fBtexmf\-var/luatex\-cache/generic/names/\fP (\fB$TEXMFCACHE\fP as set in
+\fBtexmf.cnf\fP) of your \fITeX Live\fP distribution as a zlib\-compressed
+file \fBluaotfload\-names.lua.gz\fP\&.
+The experimental lookup cache will be created as
+\fBluaotfload\-lookup\-cache.lua\fP in the same directory.
+These Lua tables are not used directly by Luaotfload, though.
+Instead, they are compiled to Lua bytecode which is written to
+corresponding files with the extension \fB\&.luc\fP in the same directory.
+When modifying the files by hand keep in mind that only if the bytecode
+files are missing will Luaotfload use the plain version instead.
+Both kinds of files are safe to delete, at the cost of regenerating
+them with the next run of \fILuaTeX\fP\&.
+.SH SEE ALSO
+.sp
+\fBluaotfload.conf\fP(5), \fBluatex\fP(1), \fBlua\fP(1)
+.INDENT 0.0
+.IP \(bu 2
+\fBtexdoc luaotfload\fP to display the manual for the \fILuaotfload\fP
+package
+.IP \(bu 2
+Luaotfload development \fI\%https://github.com/lualatex/luaotfload\fP
+.IP \(bu 2
+LuaLaTeX mailing list \fI\%http://tug.org/pipermail/lualatex\-dev/\fP
+.IP \(bu 2
+LuaTeX \fI\%http://luatex.org/\fP
+.IP \(bu 2
+ConTeXt \fI\%http://wiki.contextgarden.net\fP
+.IP \(bu 2
+Luaotfload on CTAN \fI\%http://ctan.org/pkg/luaotfload\fP
+.UNINDENT
+.SH BUGS
+.sp
+Tons, probably.
+.SH AUTHORS
+.sp
+\fILuaotfload\fP was developed by the LuaLaTeX dev team
+(\fI\%https://github.com/lualatex/\fP). It is currently maintained by Ulrike Fischer
+and Marcel Krüger at \fI\%https://github.com/u\-fischer/luaotfload\fP
+The fontloader code is provided by Hans Hagen of Pragma ADE, Hasselt
+NL (\fI\%http://pragma\-ade.com/\fP).
+.sp
+This manual page was written by Philipp Gesang <\fI\%phg@phi\-gamma.net\fP>.
+.SH COPYRIGHT
+GPL v2.0
+.\" Generated by docutils manpage writer.
+.
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.lua b/macros/luatex/generic/luaotfload/luaotfload-tool.lua
new file mode 100755
index 0000000000..e7e144c6c7
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.lua
@@ -0,0 +1,1661 @@
+#!/usr/bin/env texlua
+-----------------------------------------------------------------------
+-- FILE: luaotfload-tool.lua
+-- DESCRIPTION: database functionality
+-- REQUIREMENTS: matching luaotfload
+-- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang
+-- LICENSE: GPL v2.0
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-tool",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload-tool / database functionality",
+ license = "GPL v2.0"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+
+luaotfload = luaotfload or { }
+local version = ProvidesLuaModule.version
+luaotfload.version = ProvidesLuaModule.version
+luaotfload.min_luatex_version = { 0, 95, 0 }
+luaotfload.self = "luaotfload-tool"
+
+--[[doc--
+
+luaotfload-tool(1)
+
+This file was originally written (as \fileent{mkluatexfontdb.lua}) by
+Elie Roux and Khaled Hosny and, as a derived work of ConTeXt, is
+provided under the terms of the GPL v2.0 license as printed in full
+text in the manual (luaotfload.pdf).
+
+ \url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html}.
+
+This file is a wrapper for the luaotfload font names module
+(luaotfload-database.lua). It is part of the luaotfload bundle, please
+see the luaotfload documentation for more info. Report bugs to
+
+ \url{https://github.com/lualatex/luaotfload/issues}.
+
+--doc]]--
+
+kpse.set_program_name "luatex"
+
+local iowrite = io.write
+local kpsefind_file = kpse.find_file
+local mathfloor = math.floor
+local next = next
+local osdate = os.date
+local ostype = os.type
+local stringexplode = string.explode
+local stringformat = string.format
+local stringlower = string.lower
+local stringrep = string.rep
+local tableconcat = table.concat
+local texiowrite_nl = texio.write_nl
+local texiowrite = texio.write
+local tonumber = tonumber
+local type = type
+
+do
+ local runtime = _G.jit and { "jit" , jit.version }
+ or { "stock", _VERSION }
+ local stats = status and status.list ()
+ local minimum = luaotfload.min_luatex_version
+ local actual = { 0, 0, 0 }
+ if stats then
+ local major = stats.luatex_version // 100
+ local minor = stats.luatex_version % 100
+ local revision = stats.luatex_revision --[[ : string ]]
+ local revno = tonumber (revision)
+ actual = { major, minor, revno or 0 }
+ end
+
+ if actual [1] < minimum [1]
+ or actual == minimum and actual [2] < minimum [2]
+ or actual == minimum and actual [2] == minimum [2] and actual [3] < minimum [3]
+ then
+ texio.write_nl ("term and log",
+ string.format ("\tFATAL ERROR\n\z
+ \tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z
+ \tPlease update your TeX distribution!\n\n",
+ (unpack or table.unpack) (minimum)))
+ error "version check failed"
+ end
+ luaotfload.runtime = runtime
+ luaotfload.luatex_version = actual
+end
+
+local C, Ct, P, S = lpeg.C, lpeg.Ct, lpeg.P, lpeg.S
+local lpegmatch = lpeg.match
+
+string.quoted = string.quoted or function (str)
+ return string.format("%q",str)
+end
+
+--[[doc--
+
+ XXX:
+ Creating the config table will be moved to the common
+ initialization when the times comes.
+
+--doc]]--
+
+config = config or { }
+local config = config
+config.luaotfload = config.luaotfload or { }
+
+config.lualibs = config.lualibs or { }
+config.lualibs.verbose = false
+config.lualibs.prefer_merged = true
+config.lualibs.load_extended = true
+
+require "lualibs"
+
+local iosavedata = io.savedata
+local lfsisdir = lfs.isdir
+local lfsisfile = lfs.isfile
+local stringsplit = string.split
+local tablekeys = table.keys
+local tableserialize = table.serialize
+local tablesortedkeys = table.sortedkeys
+local tabletohash = table.tohash
+
+--[[doc--
+\fileent{luatex-basics-gen.lua} calls functions from the
+\luafunction{texio.*} library; too much for our taste.
+We intercept them with dummies.
+
+Also, it sets up dummies in place of the tables created by the Context
+libraries. Since we have loaded the lualibs already this would cause
+collateral damage for some libraries whose namespace would be
+overridden. We employ our usual backup-restore strategy to work around
+this. (Postponing the loading of the lualibs code is not an option
+because the functionality is needed by basics-gen itself.)
+--doc]]--
+
+local dummy_function = function ( ) end
+local backup = {
+ write = texio.write,
+ write_nl = texio.write_nl,
+ utilities = utilities,
+}
+
+texio.write, texio.write_nl = dummy_function, dummy_function
+require "fontloader-basics-gen.lua"
+texio.write, texio.write_nl = backup.write, backup.write_nl
+utilities = backup.utilities
+
+pdf = pdf or { } --- for fonts-tfm
+
+require "fontloader-data-con"
+require "fontloader-font-ini"
+require "fontloader-font-con"
+require "fontloader-fonts-enc"
+require "fontloader-font-cid"
+require "fontloader-font-map"
+require "fontloader-font-oti"
+require "fontloader-font-otr"
+require "fontloader-font-ott"
+require "fontloader-font-cff"
+require "fontloader-font-ttf"
+require "fontloader-font-dsp"
+require "fontloader-font-oup"
+require "fontloader-font-onr"
+require "fontloader-font-def"
+
+fonts = fonts or { }
+local fontsnames = fonts.names or { }
+fonts.names = fontsnames
+
+local require_init = { }
+
+local loadmodule = function (name)
+ local v = require ("luaotfload-" .. name)
+ if v then
+ local mod = { }
+ local tv = type (v)
+ if tv == "table" then
+ mod.name = name
+ mod.init = v.init
+ require_init [#require_init + 1] = mod
+ elseif tv == "function" then
+ mod.name = name
+ mod.init = v
+ require_init [#require_init + 1] = mod
+ end
+ end
+end
+
+require "alt_getopt"
+
+loadmodule "log" --- this populates the luaotfload.log.* namespace
+loadmodule "parsers" --- fonts.conf, configuration, and request syntax
+loadmodule "configuration" --- configuration file handling
+loadmodule "database"
+loadmodule "resolvers" --- Font lookup
+
+local logreport
+
+local init_modules = function ()
+ --- NB we don’t command the logger at this point.
+ local todo = #require_init
+ local ret = true
+ for i = 1, todo do
+ local mod = require_init[i]
+ local name = mod.name
+ local init = mod.init
+ if type (init) ~= "function" then
+ error ("luaotfload broken; module "
+ .. name .. " missing initializers!")
+ end
+ local v = mod.init ()
+ if v == true then
+ --- evaluated well
+ elseif type (v) == "table" then
+ luaotfload[name] = v
+ else
+ error ("luaotfload broken; initialization of module "
+ .. name .. " returned " .. tostring (v) .. ".")
+ return false
+ end
+ end
+ logreport = luaotfload.log.report
+ return ret
+end
+
+
+local help_messages = {
+ ["luaotfload-tool"] = [[
+
+Usage: %s [OPTIONS...]
+
+ Luaotfload font management and diagnostic utility.
+ This program is part of the Luaotfload package.
+
+ Valid options are:
+
+-------------------------------------------------------------------------------
+ VERBOSITY AND DIAGNOSTICS
+
+ -q --quiet don't output anything
+ -v --verbose=LEVEL be more verbose (print the searched directories)
+ -v, -vv .. -vvvvvvvvv set loglevel in unary
+ --log=stdout redirect log output to stdout
+
+ -V --version print version and exit
+ -h --help print this message
+ --diagnose=CHECK run a self test procedure; one of "files",
+ "environment", "index", "permissions", or
+ "repository"
+
+-------------------------------------------------------------------------------
+ DATABASE
+
+ -u --update update the database
+ -n --no-reload suppress db update
+ --no-strip keep redundant information in db
+ -f --force force re-indexing all fonts
+ -L --local scan font files in $PWD
+ -c --no-compress do not gzip index file (text version only)
+ -l --flush-lookups empty lookup cache of font requests
+ -D --dry-run skip loading of fonts, just scan
+ --formats=[+|-]EXTENSIONS set, add, or subtract file formats
+ -p --prefer-texmf prefer fonts in the TEXMF over system fonts
+ --max-fonts=N process at most N font files
+
+ --find="font name" query the database for a font name
+ -F --fuzzy look for approximate matches if --find fails
+ --limit=n limit display of fuzzy matches to <n>
+ (default: n = 1)
+
+ -i --info display basic font metadata
+ -I --inspect display detailed font metadata
+
+ --list=<criterion> output list of entries by field <criterion>
+ --list=<criterion>:<value> restrict to entries with <criterion>=<value>
+ --fields=<f1>,<f2>,…,<fn> which fields <f> to print with --list
+ -b --show-blacklist show blacklisted files
+
+ --bisect=<directive> control database bisection: valid
+ directives are "start", "stop", "run", "status",
+ "good", "bad"
+
+The font database will be saved to
+ %s
+ %s
+
+-------------------------------------------------------------------------------
+ FONT CACHE
+
+ --cache=<directive> operate on font cache, where <directive> is
+ "show", "purge", or "erase"
+
+The font cache will be written to
+ %s
+
+]],
+ mkluatexfontdb = [[
+FATAL ERROR
+As of Luaotfload v2.5, legacy behavior is not supported anymore. Please
+update your scripts and/or habits! Kthxbye.
+]],
+ short = [[
+Usage: luaotfload-tool [--help] [--version] [--verbose=<lvl>]
+ [--update] [--force] [--prefer-texmf] [--local]
+ [--dry-run] [--formats=<extension list>]
+ [--find=<font name>] [--fuzzy] [--info] [--inspect]
+ [--list=<criterion>] [--fields=<field list>]
+ [--cache=<directive>] [--flush-lookups]
+ [--show-blacklist] [--diagnose=<procedure>]
+ [--no-compress] [--no-strip] [--local]
+ [--max-fonts=<n>] [--bisect=<directive>]
+
+Enter 'luaotfload-tool --help' for a larger list of options.
+]]
+}
+
+local help_msg = function (version)
+ local template = help_messages[version]
+ local paths = config.luaotfload.paths
+ local names_plain = paths.index_path_lua
+ local names_gzip = names_plain .. ".gz"
+ local names_bin = paths.index_path_luc
+
+ iowrite(stringformat(template,
+ luaotfload.self,
+ names_gzip,
+ names_bin,
+ caches.getwritablepath (config.luaotfload.paths.cache_dir, "")))
+end
+
+local about = [[
+%s:
+ Luaotfload font management and diagnostic utility.
+ License: GNU GPL v2.0.
+ Report problems to <https://github.com/lualatex/luaotfload/issues>
+]]
+
+local version_msg = function ( )
+ local out = function (...) texiowrite_nl (stringformat (...)) end
+ local uname = os.uname ()
+ local meta = fonts.names.getmetadata ()
+
+ local runtime = luaotfload.runtime
+ local actual = luaotfload.luatex_version
+ local status = config.luaotfload.status
+ local notes = status and status.notes or { }
+
+ out (about, luaotfload.self)
+ out ("%s version: %q", luaotfload.self, version)
+ if notes.description then
+ out ("Luaotfload: %q", notes.description)
+ end
+ out ("Revision: %q", notes.revision)
+ out ("Lua interpreter: %s; version %q", runtime[1], runtime[2])
+--[[out ("Luatex SVN revision: %d", info.luatex_svn)]] --> SVN r5624
+ out ("Luatex version: %d.%d", actual [1], actual [2])
+ out ("Platform: type=%s name=%s", os.type, os.name)
+
+ local uname_vars = tablesortedkeys (uname)
+ for i = 1, #uname_vars do
+ local var = uname_vars[i]
+ out (" + %8s: %s", var, uname[var])
+ end
+ if meta == false then
+ out("No database metadata available.")
+ else
+ out ("Index: version=%q created=%q modified=%q",
+ meta.version or "too old",
+ meta.created or "ages ago",
+ meta.modified or "ages ago")
+ end
+ out ""
+end
+
+
+--- makeshift formatting
+
+local head_adornchars = {
+ [1] = "*", [2] = "=", [3] = "~", [4] = "-", [5] = "·",
+}
+
+local textwidth = 80
+local wd_leftcolumn = mathfloor(textwidth * .25)
+local key_fmt = stringformat([[%%%ds]], wd_leftcolumn)
+local val_fmt = [[%s]]
+local fieldseparator = ":"
+local info_fmt = key_fmt .. fieldseparator .. " " .. val_fmt
+
+local currentdepth = 0
+local counterstack = { } -- counters per level
+local counterformat = "%d"
+
+local format_counter = function (stack)
+ local acc = { }
+ for lvl=1, #stack do
+ acc[#acc+1] = stringformat(counterformat, stack[lvl])
+ end
+ return tableconcat(acc, ".")
+end
+
+local print_heading = function (title, level)
+ if not title then return end
+ local structuredata
+ if currentdepth == level then -- top is current
+ counterstack[#counterstack] = counterstack[#counterstack] + 1
+ elseif currentdepth < level then -- push new
+ counterstack[#counterstack+1] = 1
+ else -- pop
+ local diff = currentdepth - level
+ while diff > 0 do
+ counterstack[#counterstack] = nil
+ diff = diff - 1
+ end
+ counterstack[#counterstack] = counterstack[#counterstack] + 1
+ end
+ currentdepth = level
+
+ texiowrite_nl ""
+ if not level or level > #head_adornchars then
+ level = #head_adornchars
+ end
+ local adornchar = head_adornchars[level]
+
+ local counter = format_counter(counterstack)
+
+ local s = adornchar .. adornchar .. " "
+ .. counter .. " "
+ .. title .. " "
+ texiowrite_nl (s .. stringrep(adornchar, textwidth-utf.len(s)))
+end
+
+local baseindent = " "
+
+--[[doc--
+
+ show_info_items -- Together with show_info_table prints the table returned by
+ readers.getinfo(), recursing into nested tables if appropriate (as necessitated
+ by Luatex versions 0.78+ which include the pfminfo table in the result.
+
+--doc]]--
+
+local show_info_table show_info_table = function (t, depth)
+ depth = depth or 0
+ local indent = stringrep (baseindent, depth)
+ local keys = tablesortedkeys (t)
+ for n = 1, #keys do
+ local key = keys [n]
+ local val = t [key]
+ if type (val) == "table" then
+ texiowrite_nl (indent .. stringformat (info_fmt, key, "<table>"))
+ show_info_table (val, depth + 1)
+ else
+ texiowrite_nl (indent .. stringformat (info_fmt, key, val))
+ end
+ end
+end
+
+local show_info_items = function (fontinfo)
+ print_heading (fontinfo.fullname, 1)
+ texiowrite_nl ""
+ show_info_table (fontinfo)
+ texiowrite_nl ""
+end
+
+local p_spacechar = S" \n\r\t\v"
+local p_wordchar = (1 - p_spacechar)
+local p_whitespace = p_spacechar^1
+local p_word = C(p_wordchar^1)
+local p_words = Ct(p_word * (p_whitespace * p_word)^0)
+
+--- string -> int -> string list
+local reflow = function (text, width)
+ local words
+ local t_text = type (text)
+ if t_text == "string" then
+ words = lpegmatch(p_words, text)
+ if #words < 2 then
+ return { text }
+ end
+ elseif t_text == "table" then
+ words = text
+ if #text < 2 then
+ return text
+ end
+ end
+
+ local space = " "
+ local utflen = utf.len
+ local reflowed = { }
+
+ local first = words[1]
+ local linelen = #first
+ local line = { first }
+
+ for i=2, #words do
+ local word = words[i]
+ local lword = utflen(word)
+ linelen = linelen + lword + 1
+ if linelen > width then
+ reflowed[#reflowed+1] = tableconcat(line)
+ linelen = #word
+ line = { word }
+ else
+ line[#line+1] = space
+ line[#line+1] = word
+ end
+ end
+ reflowed[#reflowed+1] = tableconcat(line)
+ return reflowed
+end
+
+--- string -> 'a -> string list
+local print_field = function (key, val)
+ val = tostring(val)
+ local lhs = stringformat(key_fmt, key) .. fieldseparator .. " "
+ local wd_lhs = #lhs
+ local lines = reflow(val, textwidth - wd_lhs)
+
+ texiowrite_nl(lhs)
+ texiowrite(lines[1])
+ if #lines > 1 then
+ local indent = stringrep(" ", wd_lhs)
+ for i=2, #lines do
+ texiowrite_nl(indent)
+ texiowrite (lines[i])
+ end
+ end
+end
+
+--- see luafflib.c
+local general_fields = {
+ --- second: l -> literal | n -> length | d -> date
+ { "fullname", "l", "font name" },
+ { "version", "l", "font version" },
+ { "width", "l", "width" },
+ { "averagewidth", "l", "average width" },
+ { "panosewidth", "l", "panose width" },
+ { "weight", "l", "weight indicator" },
+ { "pfmweight", "l", "numerical weight" },
+ { "panoseweight", "l", "panose weight" },
+ { "designsize", "l", "design size" },
+ { "minsize", "l", "design size min" },
+ { "maxsize", "l", "design size max" },
+ { "units", "l", "units per em" },
+ { "ascender", "l", "ascender height" },
+ { "descender", "l", "descender height" },
+ { "capheight", "l", "capital height" },
+}
+
+local display_general = function (fullinfo)
+ texiowrite_nl ""
+ print_heading("General Information", 2)
+ texiowrite_nl ""
+ for i=1, #general_fields do
+ local field = general_fields[i]
+ local key, mode, desc = unpack(field)
+ local val
+ if mode == "l" then
+ val = fullinfo[key]
+ elseif mode == "S" then --- style names table
+ local data = fullinfo[key]
+ if type (data) == "table" then
+ if #data > 0 then
+ for n = 1, #data do
+ local nth = data[n]
+ if nth.lang == 1033 then
+ val = nth.name
+ goto found
+ end
+ end
+ val = next (data).name
+ else
+ val = ""
+ end
+ ::found::
+ else
+ val = data
+ end
+ elseif mode == "n" then
+ local v = fullinfo[key]
+ if v then
+ val = #fullinfo[key]
+ end
+ elseif mode == "d" then
+ if ostype == "unix" then
+ val = osdate("%F %T", fullinfo[key])
+ else
+ --- the MS compiler doesn’t support C99, so
+ --- strftime is missing some functionality;
+ --- see loslib.c for details.
+ val = osdate("%Y-%m-d %H:%M:%S", fullinfo[key])
+ end
+ end
+ if not val then
+ val = "<none>"
+ end
+ print_field(desc, val)
+ end
+end
+
+local print_features = function (features)
+ for tag, data in next, features do
+ print_heading(tag, 4)
+ for script, languages in next, data do
+ local field = stringformat(key_fmt, script).. fieldseparator .. " "
+ local wd_field = #field
+ local lines = reflow(tablekeys(languages), textwidth - wd_field)
+ local indent = stringrep(" ", wd_field)
+ texiowrite_nl(field)
+ texiowrite(lines[1])
+ if #lines > 1 then
+ for i=1, #lines do
+ texiowrite_nl(indent .. lines[i])
+ end
+ end
+ end
+ end
+end
+
+local display_feature_set = function (set)
+ print_features(set)
+end
+
+local display_features_type = function (id, feat)
+ if feat and next (feat) then
+ print_heading(id, 3)
+ display_feature_set(feat)
+ return true
+ end
+ return false
+end
+
+local display_features = function (features)
+ texiowrite_nl ""
+ print_heading("Features", 2)
+
+ local status = 0
+ if not display_features_type ("GSUB Features", features.gsub) then
+ status = status + 1
+ end
+ if not display_features_type ("GPOS Features", features.gpos) then
+ status = status + 2
+ end
+ if status == 3 then
+ texiowrite_nl("font defines neither gsub nor gpos features")
+ elseif status == 2 then
+ texiowrite_nl("font defines no gpos feature")
+ elseif status == 1 then
+ texiowrite_nl("font defines no gsub feature")
+ end
+end
+
+local show_full_info = function (path, subfont)
+ local rawinfo, warn = fonts.handlers.otf.readers.loadfont (path, subfont)
+ if not rawinfo then
+ texiowrite_nl(stringformat([[cannot open font %s]], path))
+ return
+ end
+ display_general(rawinfo.metadata)
+ display_features(rawinfo.resources.features)
+end
+
+local subfont_by_name
+subfont_by_name = function (lst, askedname, n)
+ if not n then
+ return subfont_by_name (lst, askedname, 1)
+ end
+
+ local font = lst[n]
+ if font then
+ if fonts.names.sanitize_fontname (font.fullname) == askedname then
+ return font
+ end
+ return subfont_by_name (lst, askedname, n + 1)
+ end
+ return false
+end
+
+--[[doc--
+The font info knows two levels of detail:
+
+ a) basic information returned by readers.getinfo(); and
+ b) detailed information that is a subset of the font table
+ returned by readers.loadfont().
+--doc]]--
+
+local show_font_info = function (basename, askedname, detail, subfont)
+ local filenames = fonts.names.data().files
+ local index = filenames.base[basename]
+ local fullname = filenames.full[index]
+ askedname = fonts.names.sanitize_fontname (askedname)
+ if not fullname then -- texmf
+ fullname = resolvers.findfile(basename)
+ end
+ if fullname then
+ local shortinfo = fonts.handlers.otf.readers.getinfo (fullname, {
+ subfont = subfont,
+ platformnames = true,
+ rawfamilynames = true,
+ })
+ local nfonts = #shortinfo
+ if nfonts > 0 then -- true type collection
+ local subfont
+ if askedname then
+ logreport (true, 1, "resolve",
+ [[%s is part of the font collection %s]],
+ askedname, basename)
+ subfont = subfont_by_name(shortinfo, askedname)
+ end
+ if subfont then
+ show_info_items(subfont)
+ if detail == true then
+ show_full_info(fullname, subfont)
+ end
+ else -- list all subfonts
+ logreport (true, 1, "resolve",
+ [[%s is a font collection]], basename)
+ for subfont = 1, nfonts do
+ logreport (true, 1, "resolve",
+ [[Showing info for font no. %d]],
+ subfont)
+ show_info_items(shortinfo[subfont])
+ if detail == true then
+ show_full_info(fullname, subfont)
+ end
+ end
+ end
+ else
+ show_info_items(shortinfo)
+ if detail == true then
+ show_full_info(fullname, subfont)
+ end
+ end
+ else
+ logreport (true, 1, "resolve", "Font %s not found", filename)
+ end
+end
+
+--[[--
+Running the scripts triggers one or more actions that have to be
+executed in the correct order. To avoid duplication we track them in a
+set.
+--]]--
+
+local action_sequence = {
+ "config" , "loglevel" , "help" , "version" ,
+ "dumpconf" , "diagnose" , "blacklist" , "cache" ,
+ "flush" , "bisect" , "generate" , "list" ,
+ "query" ,
+}
+
+local action_pending = tabletohash(action_sequence, false)
+
+action_pending.config = true --- always read the configuration
+action_pending.loglevel = true --- always set the loglevel
+action_pending.generate = false --- this is the default action
+
+local actions = { } --- (jobspec -> (bool * bool)) list
+
+actions.loglevel = function (job)
+ local lvl = job.log_level
+ if lvl then
+ luaotfload.log.set_loglevel(lvl)
+ logreport ("info", 3, "util", "Setting the log level to %d.", lvl)
+ logreport ("log", 2, "util", "Lua=%q", _VERSION)
+ end
+ return true, true
+end
+
+actions.config = function (job)
+ local defaults = luaotfload.default_config
+ local vars = config.actions.read (job.extra_config)
+ config.luaotfload = config.actions.apply (defaults, vars)
+ config.luaotfload = config.actions.apply (config.luaotfload, job.config)
+
+ --inspect(config.luaotfload)
+ --os.exit()
+ if not config.actions.reconfigure () then
+ return false, false
+ end
+ return true, true
+end
+
+actions.version = function (job)
+ version_msg()
+ return true, false
+end
+
+actions.dumpconf = function (job)
+ config.actions.dump ()
+ return true, false
+end
+
+actions.help = function (job)
+ help_msg (job.help_version or "luaotfload-tool")
+ return true, false
+end
+
+actions.blacklist = function (job)
+ fonts.names.read_blacklist()
+ local n = 0
+ for n, entry in next, tablesortedkeys(fonts.names.blacklist) do
+ iowrite (stringformat("(%d %s)\n", n, entry))
+ end
+ return true, false
+end
+
+actions.generate = function (job)
+ local _ = fonts.names.update ({ }, job.force_reload, job.dry_run)
+ local namedata = fonts.names.data ()
+ if namedata then
+ logreport ("info", 2, "db",
+ "Fonts in the database: %i",
+ #namedata.mappings)
+ return true, true
+ end
+ return false, false
+end
+
+-------------------------------------------------------------------------------
+--- bisect mode
+-------------------------------------------------------------------------------
+
+local bisect_status_path = caches.getwritablepath ("bisect", "")
+local bisect_status_file = bisect_status_path .."/" .. "luaotfload-bisect-status.lua"
+local bisect_status_fmt = [[
+--[==[-------------------------------------------------------------------------
+ This file is generated by Luaotfload. It can be safely deleted.
+ Creation date: %s.
+-------------------------------------------------------------------------]==]--
+
+%s
+
+--- vim:ft=lua:ts=8:et:sw=2
+]]
+
+--[[doc--
+
+ write_bisect_status -- Write the history of the current bisection to disk.
+
+--doc]]--
+
+--- state list -> bool
+local write_bisect_status = function (data)
+ local payload = tableserialize (data, true)
+ local status = stringformat (bisect_status_fmt,
+ osdate ("%Y-%m-d %H:%M:%S", os.time ()),
+ payload)
+ if status and iosavedata (bisect_status_file, status) then
+ logreport ("info", 4, "bisect",
+ "Bisection state written to %s.",
+ bisect_status_file)
+ return true
+ end
+ logreport ("info", 0, "bisect",
+ "Failed to write bisection state to %s.",
+ bisect_status_file)
+ return false
+end
+
+--[[doc--
+
+ read_bisect_status -- Read the bisect log from disk.
+
+--doc]]--
+
+--- unit -> state list
+local read_bisect_status = function ()
+ logreport ("info", 4, "bisect",
+ "Testing for status file: %q.",
+ bisect_status_file)
+ if not lfsisfile (bisect_status_file) then
+ logreport ("info", 2, "bisect",
+ "No such file: %q.", bisect_status_file)
+ logreport ("info", 0, "bisect",
+ "Not in bisect mode.")
+ return false
+ end
+ logreport ("info", 4, "bisect",
+ "Reading status file: %q.", bisect_status_file)
+ local success, status = pcall (dofile, bisect_status_file)
+ if not success then
+ logreport ("info", 0, "bisect",
+ "Could not read status file.")
+ return false
+ end
+ return status
+end
+
+--[[doc--
+
+ bisect_start -- Begin a bisect session. Determines the number of
+ fonts and sets the initial high, low, and pivot values.
+
+--doc]]--
+
+local bisect_start = function ()
+ if lfsisfile (bisect_status_file) then
+ logreport ("info", 0, "bisect",
+ "Bisect session in progress.",
+ bisect_status_file)
+ logreport ("info", 0, "bisect",
+ "Use --bisect=stop to erase it before starting over.")
+ return false, false
+ end
+ logreport ("info", 2, "bisect",
+ "Starting bisection of font database %q.",
+ bisect_status_file)
+ local n = fonts.names.count_font_files ()
+ local pivot = mathfloor (n / 2)
+ local data = { { 1, n, pivot } }
+ logreport ("info", 0, "bisect",
+ "Initializing pivot to %d.", pivot)
+ if write_bisect_status (data) then
+ return true, false
+ end
+ return false, false
+end
+
+--[[doc--
+
+ bisect_stop -- Terminate bisection session by removing all state info.
+
+--doc]]--
+
+local bisect_stop = function ()
+ logreport ("info", 3, "bisect",
+ "Erasing bisection state at %s.",
+ bisect_status_file)
+ if lfsisfile (bisect_status_file) then
+ local success, msg = os.remove (bisect_status_file)
+ if not success then
+ logreport ("info", 2, "bisect",
+ "Failed to erase file %s (%s).",
+ bisect_status_file, msg)
+ end
+ end
+ if lfsisdir (bisect_status_path) then
+ local success, msg = os.remove (bisect_status_path)
+ if not success then
+ logreport ("info", 2, "bisect",
+ "Failed to erase directory %s (%s).",
+ bisect_status_path, msg)
+ end
+ end
+ if lfsisfile (bisect_status_file) then
+ return false, false
+ end
+ return true, false
+end
+
+--[[doc--
+
+ bisect_terminate -- Wrap up a bisect session by printing the
+ offending font and removing the state file.
+
+--doc]]--
+
+local bisect_terminate = function (nsteps, culprit)
+ logreport ("info", 1, "bisect",
+ "Bisection completed after %d steps.", nsteps)
+ logreport ("info", 0, "bisect",
+ "Bad file: %s.", fonts.names.nth_font_filename (culprit))
+ logreport ("info", 0, "bisect",
+ "Run with --bisect=stop to finish bisection.")
+ return true, false
+end
+
+--[[doc--
+
+ list_remainder -- Show remaining fonts in bisect slice.
+
+--doc]]--
+
+local list_remainder = function (lo, hi)
+ local fonts = fonts.names.font_slice (lo, hi)
+ logreport ("info", 0, "bisect", "%d fonts left.", hi - lo + 1)
+ for i = 1, #fonts do
+ logreport ("info", 1, "bisect", " · %2d: %s", lo, fonts[i])
+ lo = lo + 1
+ end
+end
+
+--[[doc--
+
+ bisect_set -- Prepare the next bisection step by setting high, low,
+ and pivot to new values.
+
+ The “run†directive always picks the segment below the pivot so we
+ can rely on the “outcome parameter†to be referring to that.
+
+--doc]]--
+
+local bisect_set = function (outcome)
+ local status = read_bisect_status ()
+ if not status then
+ return false, false
+ end
+
+ local nsteps = #status
+ local previous = status[nsteps]
+ if previous == true then
+ --- Bisection already completed; we exit early through
+ --- bisect_terminate() to avoid further writes to the
+ --- state files that mess up step counting.
+ nsteps = nsteps - 1
+ return bisect_terminate (nsteps, status[nsteps][1])
+ end
+
+ local lo, hi, pivot = unpack (previous)
+
+ logreport ("info", 3, "bisect",
+ "Previous step %d: lo=%d, hi=%d, pivot=%d.",
+ nsteps, lo, hi, pivot)
+
+ if outcome == "bad" then
+ hi = pivot
+ if lo >= hi then --- complete
+ status[nsteps + 1] = { lo, lo, lo }
+ status[nsteps + 2] = true
+ write_bisect_status (status)
+ return bisect_terminate (nsteps, lo)
+ end
+ pivot = mathfloor ((lo + hi) / 2)
+ logreport ("info", 0, "bisect",
+ "Continuing with the lower segment: lo=%d, hi=%d, pivot=%d.",
+ lo, hi, pivot)
+ elseif outcome == "good" then
+ lo = pivot + 1
+ if lo >= hi then --- complete
+ status[nsteps + 1] = { lo, lo, lo }
+ write_bisect_status (status)
+ status[nsteps + 2] = true
+ return bisect_terminate (nsteps, lo)
+ end
+ pivot = mathfloor ((lo + hi) / 2)
+ logreport ("info", 0, "bisect",
+ "Continuing with the upper segment: lo=%d, hi=%d, pivot=%d.",
+ lo, hi, pivot)
+ else -- can’t happen
+ logreport ("info", 0, "bisect",
+ "What the hell?", lo, hi, pivot)
+ return false, false
+ end
+
+ status[nsteps + 1] = { lo, hi, pivot }
+ write_bisect_status (status)
+ if hi - lo <= 10 then
+ list_remainder (lo, hi)
+ end
+ return true, false
+end
+
+--[[doc--
+
+ bisect_status -- Output information about the current bisect session.
+
+--doc]]--
+
+local bisect_status = function ()
+ local status = read_bisect_status ()
+ if not status then
+ return false, false
+ end
+ local nsteps = #status
+ if nsteps > 1 then
+ for i = nsteps - 1, 1, -1 do
+ local step = status[i]
+ logreport ("info", 2, "bisect", "Step %d: lo=%d, hi=%d, pivot=%d.",
+ i, unpack (step))
+ end
+ end
+ local current = status[nsteps]
+ logreport ("info", 0, "bisect", "Step %d: lo=%d, hi=%d, pivot=%d.",
+ nsteps, unpack (current))
+ return true, false
+end
+
+--[[doc--
+
+ bisect_run -- Run Luaotfload utilizing the current bisection state.
+ This should be combined with the --update mode, possibly with the
+ --force option.
+
+ Luaotfload always tests the segment below the pivot first.
+
+--doc]]--
+
+local bisect_run = function ()
+ local status = read_bisect_status ()
+ if not status then
+ return false, false
+ end
+ local nsteps = #status
+ local currentstep = nsteps + 1
+ local current = status[nsteps]
+ if current == true then -- final step
+ current = status[nsteps - 1]
+ end
+ local lo, hi, pivot = unpack (current)
+ logreport ("info", 3, "bisect", "Previous step %d: lo=%d, hi=%d, pivot=%d.",
+ nsteps, lo, hi, pivot)
+ logreport ("info", 1, "bisect", "Step %d: Testing fonts from %d to %d.",
+ currentstep, lo, pivot)
+ config.luaotfload.misc.bisect = { lo, pivot }
+ return true, true
+end
+
+local bisect_modes = {
+ start = bisect_start,
+ good = function () return bisect_set "good" end,
+ bad = function () return bisect_set "bad" end,
+ stop = bisect_stop,
+ status = bisect_status,
+ run = bisect_run,
+}
+
+actions.bisect = function (job)
+ local mode = job.bisect
+ local runner = bisect_modes[mode]
+ if not runner then
+ logreport ("info", 0, "bisect", "Unknown directive %q.", mode)
+ return false, false
+ end
+ return runner (job)
+end
+
+actions.flush = function (job)
+ local success = fonts.names.flush_lookup_cache()
+ if success then
+ local success = fonts.names.save_lookups()
+ if success then
+ logreport ("info", 2, "cache", "Lookup cache emptied")
+ return true, true
+ end
+ end
+ return false, false
+end
+
+local cache_directives = function ()
+ --- These exist only after initialization.
+ return {
+ ["purge"] = fonts.names.purge_cache,
+ ["erase"] = fonts.names.erase_cache,
+ ["show"] = fonts.names.show_cache,
+ }
+end
+
+actions.cache = function (job)
+ local directive = cache_directives()[job.cache]
+ if not directive or type(directive) ~= "function" then
+ logreport ("info", 2, "cache",
+ "Invalid font cache directive %s.", job.cache)
+ return false, false
+ end
+ if directive() then
+ return true, true
+ end
+ return false, false
+end
+
+actions.query = function (job)
+
+ require "luaotfload-features"
+
+ local query = job.query
+
+ local tmpspec = {
+ name = query,
+ lookup = "name",
+ specification = query,
+ optsize = 0,
+ features = { },
+ }
+
+ tmpspec = fonts.names.handle_request (tmpspec)
+
+ if not tmpspec.size then
+ tmpspec.size = 655360 --- assume 10pt
+ end
+
+ local foundname, subfont, success, needle
+
+ if tmpspec.lookup == "name" then
+ if fonts.definers.resolvers.name (tmpspec) then
+ needle = tmpspec.resolved
+ end
+ elseif tmpspec.lookup == "anon" then
+ if fonts.definers.resolvers.anon (tmpspec) then
+ needle = tmpspec.resolved or tmpspec.name
+ end
+ elseif tmpspec.lookup == "file" then
+ needle = tmpspec.name
+ end
+ subfont = tmpspec.sub
+
+ if needle then
+ foundname, _, success = fonts.names.lookup_font_file (tmpspec.name)
+ end
+
+ if success then
+ logreport (false, 0, "resolve", "Font %q found!", query)
+ if subfont then
+ logreport (false, 0, "resolve",
+ "Resolved file name %q, subfont nr. %q",
+ foundname, subfont)
+ else
+ logreport (false, 0, "resolve",
+ "Resolved file name %q", foundname)
+ end
+ if job.show_info then
+ logreport (false, 3, "resolve", "Dump extra info.")
+ show_font_info (foundname, query, job.full_info, subfont)
+ iowrite "\n"
+ end
+ else
+ logreport (false, 0, "resolve", "Cannot find %q in index.", query)
+ if job.fuzzy == true then
+ logreport (false, 0, "resolve",
+ "Looking for close matches, this may take a while ...")
+ local _success = fonts.names.find_closest(query, job.fuzzy_limit)
+ else
+ logreport (false, 0, "resolve",
+ "Hint: use the --fuzzy option to display suggestions.",
+ query)
+ end
+ end
+ return true, true
+end
+
+--- --list=<criterion>
+--- --list=<criterion>:<value>
+---
+--- --list=<criterion> --fields=<f1>,<f2>,<f3>,...<fn>
+
+local get_fields get_fields = function (entry, fields, acc, n)
+ if not acc then
+ return get_fields (entry, fields, { }, 1)
+ end
+
+ local field = fields [n]
+ if field then
+ local chain = stringsplit (field, "->")
+ local tmp = entry
+ for i = 1, #chain - 1 do
+ tmp = tmp [chain [i]]
+ if not tmp then
+ --- invalid field
+ break
+ end
+ end
+ if tmp then
+ local value = tmp [chain [#chain]]
+ acc[#acc+1] = value or false
+ else
+ acc[#acc+1] = false
+ end
+ return get_fields (entry, fields, acc, n+1)
+ end
+ return acc
+end
+
+local separator = "\t" --- could be “,†for csv
+
+local format_fields format_fields = function (fields, acc, n)
+ if not acc then
+ return format_fields(fields, { }, 1)
+ end
+
+ local field = fields[n]
+ if field ~= nil then
+ if field == false then
+ acc[#acc+1] = "<none>"
+ else
+ acc[#acc+1] = tostring(field)
+ end
+ return format_fields(fields, acc, n+1)
+ end
+ return tableconcat(acc, separator)
+end
+
+local set_primary_field
+set_primary_field = function (fields, addme, acc, n)
+ if not acc then
+ return set_primary_field(fields, addme, { addme }, 1)
+ end
+
+ local field = fields[n]
+ if field then
+ if field ~= addme then
+ acc[#acc+1] = field
+ end
+ return set_primary_field(fields, addme, acc, n+1)
+ end
+ return acc
+end
+
+actions.list = function (job)
+ local criterion = job.criterion
+ local asked_fields = job.asked_fields
+ local name_index = fonts.names.data ()
+
+ if asked_fields then
+ local splitcomma = luaotfload.parsers.splitcomma
+ asked_fields = lpegmatch(splitcomma, asked_fields)
+ end
+
+ if not asked_fields then
+ --- some defaults
+ asked_fields = { "plainname", "version", }
+ end
+
+ if not name_index then
+ name_index = fonts.names.load()
+ end
+
+ local mappings = name_index.mappings
+ local nmappings = #mappings
+
+ if criterion == "*" then
+ logreport (false, 1, "list", "All %d entries", nmappings)
+ for i=1, nmappings do
+ local entry = mappings[i]
+ local fields = get_fields(entry, asked_fields)
+ --- we could collect these instead ...
+ local formatted = format_fields(fields)
+ texiowrite_nl(formatted)
+ end
+
+ else
+ criterion = stringexplode(criterion, ":") --> { field, value }
+ local asked_value = criterion[2]
+ criterion = criterion[1]
+ asked_fields = set_primary_field(asked_fields, criterion)
+
+ logreport (false, 1, "list", "By %s", criterion)
+
+ --- firstly, build a list of fonts to operate on
+ local targets = { }
+ if asked_value then --- only those whose value matches
+ logreport (false, 2, "list", "Restricting to value %s", asked_value)
+ for i=1, nmappings do
+ local entry = mappings[i]
+ if entry[criterion]
+ and tostring(entry[criterion]) == asked_value
+ then
+ targets[#targets+1] = entry
+ end
+ end
+
+ else --- whichever have the field, sorted
+ local categories, by_category = { }, { }
+ for i=1, nmappings do
+ local entry = mappings[i]
+ local tmp = entry
+ local chain = stringsplit (criterion, "->")
+ for i = 1, #chain - 1 do
+ tmp = tmp [chain [i]]
+ if not tmp then
+ break
+ end
+ end
+ local value = tmp and tmp [chain [#chain]] or "<none>"
+ if value then
+ --value = tostring(value)
+ local entries = by_category[value]
+ if not entries then
+ entries = { entry }
+ categories[#categories+1] = value
+ else
+ entries[#entries+1] = entry
+ end
+ by_category[value] = entries
+ end
+ end
+ table.sort(categories)
+
+ for i=1, #categories do
+ local entries = by_category[categories[i]]
+ for j=1, #entries do
+ targets[#targets+1] = entries[j]
+ end
+ end
+ end
+ local ntargets = #targets
+ logreport (false, 2, "list", "%d entries", ntargets)
+
+ --- now, output the collection
+ for i=1, ntargets do
+ local entry = targets[i]
+ local fields = get_fields(entry, asked_fields)
+ local formatted = format_fields(fields)
+ texiowrite_nl(formatted)
+ end
+ end
+
+ texiowrite_nl ""
+
+ return true, true
+end
+
+actions.diagnose = function (job)
+ --- diagnostics are loaded on demand
+ local diagnose = require "luaotfload-diagnostics.lua"
+ return diagnose (job)
+end
+
+--- stuff to be carried out prior to exit
+
+local finalizers = { }
+
+--- returns false if at least one of the actions failed, mainly
+--- for closing io channels
+local finalize = function ()
+ local success = true
+ for _, fun in next, finalizers do
+ if type (fun) == "function" then
+ if fun () == false then success = false end
+ end
+ end
+ return success
+end
+
+--[[--
+Command-line processing.
+luaotfload-tool relies on the script alt_getopt to process argv and
+analyzes its output.
+
+TODO with extended lualibs we have the functionality from the
+environment.* namespace that could eliminate the dependency on
+alt_getopt.
+--]]--
+
+local process_cmdline = function ( ) -- unit -> jobspec
+ local result = { -- jobspec
+ force_reload = nil,
+ full_info = false,
+ criterion = "",
+ query = "",
+ log_level = nil,
+ bisect = nil,
+ config = { db = { }, misc = { }, run = { live = false }, paths = { } },
+ }
+
+ local long_options = {
+ ["bisect"] = 1,
+ cache = 1,
+ conf = 1,
+ diagnose = 1,
+ dumpconf = 0,
+ ["dry-run"] = "D",
+ ["flush-lookups"] = "l",
+ fields = 1,
+ find = 1,
+ force = "f",
+ formats = 1,
+ fuzzy = "F",
+ help = "h",
+ info = "i",
+ inspect = "I",
+ limit = 1,
+ list = 1,
+ ["local"] = "L",
+ log = 1,
+ ["max-fonts"] = 1,
+ ["no-compress"] = "c",
+ ["no-reload"] = "n",
+ ["no-strip"] = 0,
+ ["skip-read"] = "R",
+ ["prefer-texmf"] = "p",
+ ["print-conf"] = 0,
+ quiet = "q",
+ ["show-blacklist"] = "b",
+ stats = "S",
+ update = "u",
+ verbose = 1,
+ version = "V",
+ }
+
+ local short_options = "bcDfFiIlLnpqRSuvVh"
+
+ local options, _, optarg =
+ alt_getopt.get_ordered_opts (arg, short_options, long_options)
+
+ local nopts = #options
+ for n=1, nopts do
+ local v = options[n]
+ if v == "q" then
+ result.log_level = 0
+ elseif v == "u" then
+ action_pending["generate"] = true
+ elseif v == "v" then
+ local lvl = result.log_level
+ if not lvl or lvl < 1 then
+ lvl = 1
+ else
+ lvl = lvl + 1
+ end
+ result.log_level = lvl
+ elseif v == "V" then
+ action_pending["version"] = true
+ elseif v == "h" then
+ action_pending["help"] = true
+ elseif v == "f" then
+ result.update = true
+ result.force_reload = 1
+ elseif v == "verbose" then
+ local lvl = optarg[n]
+ if lvl then
+ lvl = tonumber(lvl)
+ result.log_level = lvl
+ end
+ elseif v == "log" then
+ local str = optarg[n]
+ if str then
+ finalizers = luaotfload.log.set_logout(str, finalizers)
+ end
+ elseif v == "find" then
+ action_pending["query"] = true
+ result.query = optarg[n]
+ elseif v == "F" then
+ result.fuzzy = true
+ elseif v == "limit" then
+ local lim = optarg[n]
+ if lim then
+ result.fuzzy_limit = tonumber(lim)
+ end
+ elseif v == "i" then
+ result.show_info = true
+ elseif v == "I" then
+ result.show_info = true
+ result.full_info = true
+ elseif v == "l" then
+ action_pending["flush"] = true
+ elseif v == "L" then
+ action_pending["generate"] = true
+ result.config.db.scan_local = true
+ elseif v == "list" then
+ action_pending["list"] = true
+ result.criterion = optarg[n]
+ elseif v == "fields" then
+ result.asked_fields = optarg[n]
+ elseif v == "cache" then
+ action_pending["cache"] = true
+ result.cache = optarg[n]
+ elseif v == "D" then
+ result.dry_run = true
+ elseif v == "p" then
+ fonts.names.set_location_precedence {
+ "local", "texmf", "system"
+ }
+ elseif v == "b" then
+ action_pending["blacklist"] = true
+ elseif v == "diagnose" then
+ action_pending["diagnose"] = true
+ result.asked_diagnostics = optarg[n]
+ elseif v == "formats" then
+ result.config.db.formats = optarg[n]
+ --names.set_font_filter (optarg[n])
+ elseif v == "n" then
+ result.config.db.update_live = false
+ elseif v == "S" then
+ result.config.misc.statistics = true
+ elseif v == "R" then
+ --- dev only, undocumented
+ result.config.db.skip_read = true
+ elseif v == "c" then
+ result.config.db.compress = false
+ elseif v == "no-strip" then
+ result.config.db.strip = false
+ elseif v == "max-fonts" then
+ local n = optarg[n]
+ if n then
+ n = tonumber(n)
+ if n and n > 0 then
+ result.config.db.max_fonts = n
+ end
+ end
+ elseif v == "bisect" then
+ result.bisect = optarg[n]
+ action_pending.bisect = true
+ elseif v == "conf" then
+ local confname = optarg[n]
+ if confname then
+ local extra = stringexplode (optarg[n], ",+")
+ if extra then
+ local extra_config = result.extra_config
+ if extra_config then
+ table.append (extra_config, extra)
+ else
+ result.extra_config = extra
+ end
+ end
+ end
+ elseif v == "dumpconf" then
+ action_pending["dumpconf"] = true
+ elseif v == "print-conf" then
+ result.print_config = true
+ end
+ end
+
+ if nopts == 0 then
+ action_pending["help"] = true
+ result.help_version = "short"
+ end
+ return result
+end
+
+local main = function ( ) -- unit -> int
+ if init_modules () == false then return -42 end
+
+ local retval = 0
+ local job = process_cmdline()
+
+-- inspect(action_pending)
+-- inspect(job)
+
+ for i=1, #action_sequence do
+ local actionname = action_sequence[i]
+ local exit = false
+ if action_pending[actionname] then
+ logreport ("log", 3, "util", "Preparing for task", "%s", actionname)
+
+ local action = actions[actionname]
+ local success, continue = action(job)
+
+ if not success then
+ logreport (false, 0, "util",
+ "Failed to execute task.", "%s", actionname)
+ retval = -1
+ exit = true
+ elseif not continue then
+ logreport (false, 3, "util",
+ "Task completed, exiting.", "%s", actionname)
+ exit = true
+ else
+ logreport (false, 3, "util",
+ "Task completed successfully.", "%s", actionname)
+ end
+ end
+ if exit then break end
+ end
+
+ if finalize () == false then
+ retval = -1
+ end
+
+ --texiowrite_nl""
+ return retval
+end
+
+return main()
+
+-- vim:tw=71:sw=4:ts=4:expandtab
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
new file mode 100644
index 0000000000..e278f8bbc5
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.rst b/macros/luatex/generic/luaotfload/luaotfload-tool.rst
new file mode 100644
index 0000000000..e091cbb1d1
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.rst
@@ -0,0 +1,328 @@
+=======================================================================
+ luaotfload-tool
+=======================================================================
+
+-----------------------------------------------------------------------
+ generate and query the Luaotfload font names database
+-----------------------------------------------------------------------
+
+:Date: 2019-08-11
+:Copyright: GPL v2.0
+:Version: 2.991
+:Manual section: 1
+:Manual group: text processing
+
+SYNOPSIS
+=======================================================================
+
+**luaotfload-tool** [ -bcDfFiIlLnpqRSuvVhw ]
+
+**luaotfload-tool** --update [ --force ] [ --quiet ] [ --verbose ]
+ [ --prefer-texmf ] [ --dry-run ]
+ [ --formats=[+|-]EXTENSIONS ]
+ [ --no-compress ] [ --no-strip ]
+ [ --local ] [ --max-fonts=N ]
+
+**luaotfload-tool** --find=FONTNAME [ --fuzzy ] [ --info ] [ --inspect ]
+ [ --no-reload ]
+
+**luaotfload-tool** --flush-lookups
+
+**luaotfload-tool** --cache=DIRECTIVE
+
+**luaotfload-tool** --list=CRITERION[:VALUE] [ --fields=F1,F2,...,Fn ]
+
+**luaotfload-tool** --bisect=DIRECTIVE
+
+**luaotfload-tool** --help
+
+**luaotfload-tool** --version
+
+**luaotfload-tool** --show-blacklist
+
+**luaotfload-tool** --diagnose=CHECK
+
+**luaotfload-tool** --conf=FILE --dumpconf
+
+DESCRIPTION
+=======================================================================
+
+luaotfload-tool accesses the font names database that is required by
+the *Luaotfload* package. There are two general modes: **update** and
+**query**.
+
++ **update**: update the database or rebuild it entirely;
++ **query**: resolve a font name or display close matches.
+
+OPTIONS
+=======================================================================
+
+update mode
+-----------------------------------------------------------------------
+--update, -u Update the database; indexes new fonts.
+--force, -f Force rebuilding of the database; re-indexes
+ all fonts.
+--local, -L Include font files in ``$PWD``. This option
+ will cause large parts of the database to be
+ rebuilt. Thus it is quite inefficient.
+ Additionally, if local font files are found,
+ the database is prevented from being saved
+ to disk, so the local fonts need to be parsed
+ with every invocation of ``luaotfload-tool``.
+--no-reload, -n Suppress auto-updates to the database (e.g.
+ when ``--find`` is passed an unknown name).
+--no-compress, -c Do not filter the plain text version of the
+ font index through gzip. Useful for debugging
+ if your editor is built without zlib.
+
+--prefer-texmf, -p Organize the file name database in a way so
+ that it prefer fonts in the *TEXMF* tree over
+ system fonts if they are installed in both.
+--formats=EXTENSIONS Extensions of the font files to index.
+ Where *EXTENSIONS* is a comma-separated list of
+ supported file extensions (otf, ttf, ttc).
+ If the list is prefixed
+ with a ``+`` sign, the given list is added to
+ the currently active one; ``-`` subtracts.
+ Default: *otf,ttf,ttc*.
+ Examples:
+
+ 1) ``--formats=-ttc,ttf`` would skip
+ TrueType fonts and font collections;
+ 2) ``--formats=otf`` would scan only OpenType
+ files;
+ 3) ``--formats=+afm`` includes binary
+ Postscript files accompanied by an AFM file.
+
+query mode
+-----------------------------------------------------------------------
+--find=NAME Resolve a font name; this looks up <name> in
+ the database and prints the file name it is
+ mapped to.
+ ``--find`` also understands request syntax,
+ i.e. ``--find=file:foo.otf`` checks whether
+ ``foo.otf`` is indexed.
+--fuzzy, -F Show approximate matches to the file name if
+ the lookup was unsuccessful (requires
+ ``--find``).
+
+--info, -i Display basic information to a resolved font
+ file (requires ``--find``).
+--inspect, -I Display detailed information by loading the
+ font and analyzing the font table; very slow!
+ For the meaning of the returned fields see
+ the LuaTeX documentation.
+ (requires ``--find``).
+
+--list=CRITERION Show entries, where *CRITERION* is one of the
+ following:
+
+ 1) the character ``*``, selecting all entries;
+ 2) a field of a database entry, for instance
+ *version* or *format**, according to which
+ the output will be sorted.
+ Information in an unstripped database (see
+ the option ``--no-strip`` above) is nested:
+ Subfields of a record can be addressed using
+ the ``->`` separator, e. g.
+ ``file->location``, ``style->units_per_em``,
+ or
+ ``names->sanitized->english->prefmodifiers``.
+ NB: shell syntax requires that arguments
+ containing ``->`` be properly quoted!
+ 3) an expression of the form ``field:value`` to
+ limit the output to entries whose ``field``
+ matches ``value``.
+
+ For example, in order to output file names and
+ corresponding versions, sorted by the font
+ format::
+
+ ./luaotfload-tool.lua --list="format" --fields="file->base,version"
+
+ This prints::
+
+ otf latinmodern-math.otf Version 1.958
+ otf lmromancaps10-oblique.otf 2.004
+ otf lmmono8-regular.otf 2.004
+ otf lmmonoproplt10-bold.otf 2.004
+ otf lmsans10-oblique.otf 2.004
+ otf lmromanslant8-regular.otf 2.004
+ otf lmroman12-italic.otf 2.004
+ otf lmsansdemicond10-oblique.otf 2.004
+ ...
+
+--fields=FIELDS Comma-separated list of fields that should be
+ printed.
+ Information in an unstripped database (see the
+ option ``--no-strip`` above) is nested:
+ Subfields of a record can be addressed using
+ the ``->`` separator, e. g.
+ ``file->location``, ``style->units_per_em``,
+ or ``names->sanitized->english->subfamily``.
+ The default is plainname,version*.
+ (Only meaningful with ``--list``.)
+
+font and lookup caches
+-----------------------------------------------------------------------
+--flush-lookups Clear font name lookup cache (experimental).
+
+--cache=DIRECTIVE Cache control, where *DIRECTIVE* is one of the
+ following:
+
+ 1) ``purge`` -> delete Lua files from cache;
+ 2) ``erase`` -> delete Lua and Luc files from
+ cache;
+ 3) ``show`` -> print stats.
+
+debugging methods
+-----------------------------------------------------------------------
+--show-blacklist, -b Show blacklisted files (not directories).
+--dry-run, -D Don’t load fonts when updating the database;
+ scan directories only.
+ (For debugging file system related issues.)
+--no-strip Do not strip redundant information after
+ building the database. Warning: this will
+ inflate the index to about two to three times
+ the normal size.
+--max-fonts=N Process at most *N* font files, including fonts
+ already indexed in the count.
+--bisect=DIRECTIVE Bisection of the font database.
+ This mode is intended as assistance in
+ debugging the Luatex engine, especially when
+ tracking memleaks or buggy fonts.
+
+ *DIRECTIVE* can be one of the following:
+
+ 1) ``run`` -> Make ``luaotfload-tool`` respect
+ the bisection progress when running.
+ Combined with ``--update`` and possibly
+ ``--force`` this will only process the files
+ from the start up until the pivot and ignore
+ the rest.
+ 2) ``start`` -> Start bisection: create a
+ bisection state file and initialize the low,
+ high, and pivot indices.
+ 3) ``stop`` -> Terminate the current bisection
+ session by deleting the state file.
+ 4) ``good`` | ``bad`` -> Mark the section
+ processed last as “good†or “badâ€,
+ respectively. The next bisection step will
+ continue with the bad section.
+ 5) ``status`` -> Print status information about
+ the current bisection session. Hint: Use
+ with higher verbosity settings for more
+ output.
+
+ A bisection session is initiated by issuing the
+ ``start`` directive. This sets the pivot to the
+ middle of the list of available font files.
+ Now run *luaotfload-tool* with the ``--update``
+ flag set as well as ``--bisect=run``: only the
+ fonts up to the pivot will be considered. If
+ that task exhibited the issue you are tracking,
+ then tell Luaotfload using ``--bisect=bad``.
+ The next step of ``--bisect=run`` will continue
+ bisection with the part of the files below the
+ pivot.
+ Likewise, issue ``--bisect=good`` in order to
+ continue with the fonts above the pivot,
+ assuming the tested part of the list did not
+ trigger the bug.
+
+ Once the culprit font is tracked down, ``good``
+ or ``bad`` will have no effect anymore. ``run``
+ will always end up processing the single font
+ file that was left.
+ Use ``--bisect=stop`` to clear the bisection
+ state.
+
+miscellaneous
+-----------------------------------------------------------------------
+--verbose=N, -v Set verbosity level to *n* or the number of
+ repetitions of ``-v``.
+--quiet No verbose output (log level set to zero).
+--log=CHANNEL Redirect log output (for database
+ troubleshooting), where *CHANNEL* can be
+
+ 1) ``stdout`` -> all output will be
+ dumped to the terminal (default); or
+ 2) ``file`` -> write to a file to the temporary
+ directory (the name will be chosen
+ automatically.
+
+--version, -V Show version numbers of components as well as
+ some basic information and exit.
+--help, -h Show help message and exit.
+
+--diagnose=CHECK Run the diagnostic procedure *CHECK*. Available
+ procedures are:
+
+ 1) ``files`` -> check *Luaotfload* files for
+ modifications;
+ 2) ``permissions`` -> check permissions of
+ cache directories and files;
+ 3) ``environment`` -> print relevant
+ environment and kpse variables;
+ 4) ``repository`` -> check the git repository
+ for new releases,
+ 5) ``index`` -> check database, display
+ information about it.
+
+ Procedures can be chained by concatenating with
+ commas, e.g. ``--diagnose=files,permissions``.
+ Specify ``thorough`` to run all checks.
+
+--conf=FILE Read the configuration from *FILE*. See
+ **luaotfload.conf**\(%) for documentation
+ concerning the format and available options.
+--dumpconf Print the currently active configuration; the
+ output can be saved to a file and used for
+ bootstrapping a custom configuration files.
+
+FILES
+=======================================================================
+
+The font name database is usually located in the directory
+``texmf-var/luatex-cache/generic/names/`` (``$TEXMFCACHE`` as set in
+``texmf.cnf``) of your *TeX Live* distribution as a zlib-compressed
+file ``luaotfload-names.lua.gz``.
+The experimental lookup cache will be created as
+``luaotfload-lookup-cache.lua`` in the same directory.
+These Lua tables are not used directly by Luaotfload, though.
+Instead, they are compiled to Lua bytecode which is written to
+corresponding files with the extension ``.luc`` in the same directory.
+When modifying the files by hand keep in mind that only if the bytecode
+files are missing will Luaotfload use the plain version instead.
+Both kinds of files are safe to delete, at the cost of regenerating
+them with the next run of *LuaTeX*.
+
+SEE ALSO
+=======================================================================
+
+**luaotfload.conf**\(5), **luatex**\(1), **lua**\(1)
+
+* ``texdoc luaotfload`` to display the manual for the *Luaotfload*
+ package
+* Luaotfload development `<https://github.com/lualatex/luaotfload>`_
+* LuaLaTeX mailing list `<http://tug.org/pipermail/lualatex-dev/>`_
+* LuaTeX `<http://luatex.org/>`_
+* ConTeXt `<http://wiki.contextgarden.net>`_
+* Luaotfload on CTAN `<http://ctan.org/pkg/luaotfload>`_
+
+BUGS
+=======================================================================
+
+Tons, probably.
+
+AUTHORS
+=======================================================================
+
+*Luaotfload* was developed by the LuaLaTeX dev team
+(`<https://github.com/lualatex/>`__). It is currently maintained by Ulrike Fischer
+and Marcel Krüger at `<https://github.com/u-fischer/luaotfload>`__
+The fontloader code is provided by Hans Hagen of Pragma ADE, Hasselt
+NL (`<http://pragma-ade.com/>`__).
+
+This manual page was written by Philipp Gesang <phg@phi-gamma.net>.
+
diff --git a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
new file mode 100644
index 0000000000..928bfcec96
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
@@ -0,0 +1,109 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-unicode.lua
+-- DESCRIPTION: part of luaotfload / unicode
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-unicode",
+ version = "2.991", --TAGVERSION
+ date = "2019-08-11", --TAGDATE
+ description = "luaotfload submodule / Unicode helpers",
+ license = "CC0 1.0 Universal",
+ author = "Marcel Krüger"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+local utf8codes = utf8.codes
+local utf8char = utf8.char
+local sub = string.sub
+local unpack = table.unpack
+local concat = table.concat
+local move = table.move
+
+local codepoint = lpeg.S'0123456789ABCDEF'^4/function(c)return tonumber(c, 16)end
+local empty = {}
+local result = {}
+
+local casefold do
+ local nl = ('#' * (1-lpeg.P'\n')^0)^-1 * '\n'
+ local entry = codepoint * "; " * lpeg.C(1) * ";" * lpeg.Ct((' ' * codepoint)^1) * "; " * nl
+ local file = lpeg.Cf(
+ lpeg.Ct(
+ lpeg.Cg(lpeg.Ct"", "C")
+ * lpeg.Cg(lpeg.Ct"", "F")
+ * lpeg.Cg(lpeg.Ct"", "S")
+ * lpeg.Cg(lpeg.Ct"", "T"))
+ * nl^0 * lpeg.Cg(entry)^0 * nl^0 * -1
+ , function(t, base, class, mapping)
+ rawset(rawget(t, class), base, mapping)
+ return t
+ end)
+
+ local f = io.open(kpse.find_file"CaseFolding.txt")
+ local data = file:match(f:read'*a')
+ f:close()
+ function casefold(s, full, special)
+ local first = special and data.T or empty
+ local second = data.C
+ local third = full and data.F or data.S
+ local result = result
+ for i = #result, 1, -1 do result[i] = nil end
+ local i = 1
+ for _, c in utf8codes(s) do
+ local datum = first[c] or second[c] or third[c]
+ if datum then
+ local l = #datum
+ move(datum, 1, l, i, result)
+ i = i + l
+ else
+ result[i] = c
+ i = i + 1
+ end
+ end
+ return utf8char(unpack(result))
+ end
+end
+
+local alphnum_only do
+ local niceentry = lpeg.Cg(codepoint * ';' * (1-lpeg.P';')^0 * ';' * lpeg.S'LN' * lpeg.Cc(true))
+ local entry = niceentry^0 * (1-lpeg.P'\n')^0 * lpeg.P'\n'
+ local file = lpeg.Cf(
+ lpeg.Ct''
+ * entry^0
+ , rawset)
+
+ local f = io.open(kpse.find_file"UnicodeData.txt")
+ local data = file:match(f:read'*a')
+ f:close()
+ function alphnum_only(s)
+ local result = result
+ for i = #result, 1, -1 do result[i] = nil end
+ local nice = nil
+ for p, c in utf8codes(s) do
+ if data[c]
+ or (c >= 0x3400 and c<= 0x3DB5)
+ or (c >= 0x4E00 and c<= 0x9FEF)
+ or (c >= 0xAC00 and c<= 0xD7A3)
+ then
+ if not nice then nice = p end
+ else
+ if nice then
+ result[#result + 1] = sub(s, nice, p-1)
+ nice = nil
+ end
+ end
+ end
+ if nice then
+ result[#result + 1] = sub(s, nice, #s)
+ end
+ return concat(result)
+ end
+end
+
+return {
+ casefold = casefold,
+ alphnum_only = alphnum_only,
+}
diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.5 b/macros/luatex/generic/luaotfload/luaotfload.conf.5
new file mode 100644
index 0000000000..7fc9e48574
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload.conf.5
@@ -0,0 +1,632 @@
+.\" Man page generated from reStructuredText.
+.
+.TH LUAOTFLOAD.CONF 5 "2019-08-11" "2.991" "text processing"
+.SH NAME
+luaotfload.conf \- Luaotfload configuration file
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.SH SYNOPSIS
+.INDENT 0.0
+.IP \(bu 2
+\fB\&./luaotfload{.conf,rc}\fP
+.IP \(bu 2
+\fBXDG_CONFIG_HOME/luaotfload/luaotfload{.conf,rc}\fP
+.IP \(bu 2
+\fB~/.luaotfloadrc\fP
+.UNINDENT
+.SH DESCRIPTION
+.sp
+The file \fBluaotfload.conf\fP contains configuration options for
+\fILuaotfload\fP, a font loading and font management component for LuaTeX.
+.SH EXAMPLE
+.sp
+A small Luaotfload configuration file with few customizations could
+look as follows:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+[db]
+ formats = afm,ttf
+ compress = false
+
+[misc]
+ termwidth = 60
+
+[run]
+ log\-level = 6
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+This will make Luaotfload ignore all font files except for PostScript
+binary fonts with a matching AFM file, and Truetype fonts. Also, an
+uncompressed index file will be dumped which is going to be much larger
+than the default gzip’ed index. The terminal width
+is truncated to 60 characters which influences the verbose output
+during indexing. Finally, the verbosity is increased greatly: each font
+file being processed will be printed to the stdout on a separate line,
+along with lots of other information.
+.sp
+To observe the difference in behavior, save above snippet to
+\fB\&./luaotfload.conf\fP and update the font index:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+luaotfload\-tool \-\-update \-\-force
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+The current configuration can be written to disk using
+\fBluaotfload\-tool\fP:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+luaotfload\-tool \-\-dumpconf > luaotfload.conf
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+The result can itself be used as a configuration file.
+.SH SYNTAX
+.sp
+The configuration file syntax follows the common INI format. For a more
+detailed description please refer to the section “CONFIGURATION FILEâ€
+of \fBgit\-config\fP(1). A brief list of rules is given below:
+.INDENT 0.0
+.INDENT 3.5
+.INDENT 0.0
+.IP \(bu 2
+Blank lines and lines starting with a semicolon (\fB;\fP) are ignored.
+.IP \(bu 2
+A configuration file is partitioned into sections that are declared
+by specifying the section title in brackets on a separate line:
+.INDENT 2.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+[some\-section]
+\&... section content ...
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.IP \(bu 2
+Sections consist of one or more variable assignments of the form
+\fBvariable\-name = value\fP E. g.:
+.INDENT 2.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+[foo]
+ bar = baz
+ quux = xyzzy
+ ...
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.IP \(bu 2
+Section and variable names may contain only uppercase and lowercase
+letters as well as dashes (\fB\-\fP).
+.UNINDENT
+.UNINDENT
+.UNINDENT
+.SH VARIABLES
+.sp
+Variables in belong into a configuration section and their values must
+be of a certain type. Some of them have further constraints. For
+example, the “color callback†must be a string of one of the values
+\fBpost_linebreak_filter\fP, \fBpre_linebreak_filter\fP, or
+\fBpre_output_filter\fP, defined in the section \fIrun\fP of the
+configuration file.
+.sp
+Currently, the configuration is organized into four sections:
+.INDENT 0.0
+.TP
+.B db
+Options relating to the font index.
+.TP
+.B misc
+Options without a clearly defined category.
+.TP
+.B paths
+Path and file name settings.
+.TP
+.B run
+Options controlling runtime behavior of Luaotfload.
+.UNINDENT
+.sp
+The list of valid variables, the sections they are part of and their
+type is given below. Types represent Lua types that the values must be
+convertible to; they are abbreviated as follows: \fBs\fP for the \fIstring\fP
+type, \fBn\fP for \fInumber\fP, \fBb\fP for \fIboolean\fP\&. A value of \fBnil\fP means
+the variable is unset.
+.SS Section \fBdb\fP
+.TS
+center;
+|l|l|l|.
+_
+T{
+variable
+T} T{
+type
+T} T{
+default
+T}
+_
+T{
+compress
+T} T{
+b
+T} T{
+\fBtrue\fP
+T}
+_
+T{
+designsize\-dimen
+T} T{
+b
+T} T{
+\fBbp\fP
+T}
+_
+T{
+formats
+T} T{
+s
+T} T{
+\fB"otf,ttf,ttc"\fP
+T}
+_
+T{
+max\-fonts
+T} T{
+n
+T} T{
+\fB2^51\fP
+T}
+_
+T{
+scan\-local
+T} T{
+b
+T} T{
+\fBfalse\fP
+T}
+_
+T{
+skip\-read
+T} T{
+b
+T} T{
+\fBfalse\fP
+T}
+_
+T{
+strip
+T} T{
+b
+T} T{
+\fBtrue\fP
+T}
+_
+T{
+update\-live
+T} T{
+b
+T} T{
+\fBtrue\fP
+T}
+_
+.TE
+.sp
+The flag \fBcompress\fP determines whether the font index (usually
+\fBluaotfload\-names.lua[.gz]\fP will be stored in compressed forms.
+If unset it is equivalent of passing \fB\-\-no\-compress\fP to
+\fBluaotfload\-tool\fP\&. Since the file is only created for convenience
+and has no effect on the runtime behavior of Luaotfload, the flag
+should remain set. Most editors come with zlib support anyways.
+.sp
+The setting \fBdesignsize\-dimen\fP applies when looking up fonts from
+families with design sizes. In Opentype, these are specified as
+“decipoints†where one decipoint equals ten DTP style “big pointsâ€.
+When indexing fonts these values are converted to \fBsp\fP\&. In order to
+treat the values as though they were specified in TeX points or Didot
+points, set \fBdesignsize\-dimen\fP to \fBpt\fP or \fBdd\fP\&.
+.sp
+The list of \fBformats\fP must be a comma separated sequence of strings
+containing one or more of these elements:
+.INDENT 0.0
+.IP \(bu 2
+\fBotf\fP (OpenType format),
+.IP \(bu 2
+\fBttf\fP and \fBttc\fP (TrueType format),
+.IP \(bu 2
+\fBafm\fP (Adobe Font Metrics),
+.UNINDENT
+.sp
+It corresponds loosely to the \fB\-\-formats\fP option to
+\fBluaotfload\-tool\fP\&. Invalid or duplicate members are ignored; if the
+list does not contain any useful identifiers, the default list
+\fB"otf,ttf,ttc"\fP will be used.
+.sp
+The variable \fBmax\-fonts\fP determines after processing how many font
+files the font scanner will terminate the search. This is useful for
+debugging issues with the font index and has the same effect as the
+option \fB\-\-max\-fonts\fP to \fBluaotfload\-tools\fP\&.
+.sp
+The \fBscan\-local\fP flag, if set, will incorporate the current working
+directory as a font search location. NB: This will potentially slow
+down document processing because a font index with local fonts will not
+be saved to disk, so these fonts will have to be re\-indexed whenever
+the document is built.
+.sp
+The \fBskip\-read\fP flag is only useful for debugging: It makes
+Luaotfload skip reading fonts. The font information for rebuilding the
+index is taken from the presently existing one.
+.sp
+Unsetting the \fBstrip\fP flag prevents Luaotfload from removing data
+from the index that is only useful when processing font files. NB: this
+can increase the size of the index files significantly and has no
+effect on the runtime behavior.
+.sp
+If \fBupdate\-live\fP is set, Luaotfload will reload the database if it
+cannot find a requested font. Those who prefer to update manually using
+\fBluaotfload\-tool\fP should unset this flag. This option does not affect
+rebuilds due to version mismatch.
+.SS Section \fBdefault\-features\fP
+.sp
+By default Luaotfload enables \fBnode\fP mode and picks the default font
+features that are prescribed in the OpenType standard. This behavior
+may be overridden in the \fBdefault\-features\fP section. Global defaults
+that will be applied for all scripts can be set via the \fBglobal\fP
+option, others by the script they are to be applied to. For example,
+a setting of
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+[default\-features]
+ global = mode=base,color=0000FF
+ dflt = smcp,onum
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+would force \fIbase\fP mode, tint all fonts blue and activate small
+capitals and text figures globally. Features are specified as a comma
+separated list of variables or variable\-value pairs. Variables without
+an explicit value are set to \fBtrue\fP\&.
+.SS Section \fBmisc\fP
+.TS
+center;
+|l|l|l|.
+_
+T{
+variable
+T} T{
+type
+T} T{
+default
+T}
+_
+T{
+statistics
+T} T{
+b
+T} T{
+\fBfalse\fP
+T}
+_
+T{
+termwidth
+T} T{
+n
+T} T{
+\fBnil\fP
+T}
+_
+T{
+version
+T} T{
+s
+T} T{
+<Luaotfload version>
+T}
+_
+.TE
+.sp
+With \fBstatistics\fP enabled, extra statistics will be collected during
+index creation and appended to the index file. It may then be queried
+at the Lua end or inspected by reading the file itself.
+.sp
+The value of \fBtermwidth\fP, if set, overrides the value retrieved by
+querying the properties of the terminal in which Luatex runs. This is
+useful if the engine runs with \fBshell_escape\fP disabled and the actual
+terminal dimensions cannot be retrieved.
+.sp
+The value of \fBversion\fP is derived from the version string hard\-coded
+in the Luaotfload source. Override at your own risk.
+.SS Section \fBpaths\fP
+.TS
+center;
+|l|l|l|.
+_
+T{
+variable
+T} T{
+type
+T} T{
+default
+T}
+_
+T{
+cache\-dir
+T} T{
+s
+T} T{
+\fB"fonts"\fP
+T}
+_
+T{
+names\-dir
+T} T{
+s
+T} T{
+\fB"names"\fP
+T}
+_
+T{
+index\-file
+T} T{
+s
+T} T{
+\fB"luaotfload\-names.lua"\fP
+T}
+_
+T{
+lookups\-file
+T} T{
+s
+T} T{
+\fB"luaotfload\-lookup\-cache.lua"\fP
+T}
+_
+.TE
+.sp
+The paths \fBcache\-dir\fP and \fBnames\-dir\fP determine the subdirectory
+inside the Luaotfload subtree of the \fBluatex\-cache\fP directory where
+the font cache and the font index will be stored, respectively.
+.sp
+Inside the index directory, the names of the index file and the font
+lookup cache will be derived from the respective values of
+\fBindex\-file\fP and \fBlookups\-file\fP\&. This is the filename base for the
+bytecode compiled version as well as \-\- for the index \-\- the gzipped
+version.
+.SS Section \fBrun\fP
+.TS
+center;
+|l|l|l|.
+_
+T{
+variable
+T} T{
+type
+T} T{
+default
+T}
+_
+T{
+anon\-sequence
+T} T{
+s
+T} T{
+\fB"tex,path,name"\fP
+T}
+_
+T{
+color\-callback
+T} T{
+s
+T} T{
+\fB"post_linebreak_filter"\fP
+T}
+_
+T{
+definer
+T} T{
+s
+T} T{
+\fB"patch"\fP
+T}
+_
+T{
+log\-level
+T} T{
+n
+T} T{
+\fB0\fP
+T}
+_
+T{
+resolver
+T} T{
+s
+T} T{
+\fB"cached"\fP
+T}
+_
+T{
+fontloader
+T} T{
+s
+T} T{
+\fB"default"\fP
+T}
+_
+.TE
+.sp
+Unqualified font lookups are treated with the flexible “anonymousâ€
+mechanism. This involves a chain of lookups applied successively until
+the first one yields a match. By default, the lookup will first search
+for TFM fonts using the Kpathsea library. If this wasn’t successful, an
+attempt is made at interpreting the request as an absolute path (like
+the \fB[/path/to/font/foo.ttf]\fP syntax) or a file name
+(\fBfile:foo.ttf\fP). Finally, the request is interpreted as a font name
+and retrieved from the index (\fBname:Foo Regular\fP). This behavior can
+be configured by specifying a list as the value to \fBanon\-sequence\fP\&.
+Available items are \fBtex\fP, \fBpath\fP, \fBname\fP \-\- representing the
+lookups described above, respectively \-\-, and \fBfile\fP for searching a
+filename but not an absolute path. Also, \fBmy\fP lookups are valid
+values but they should only be used from within TeX documents, because
+there is no means of customizing a \fBmy\fP lookups on the command line.
+.sp
+The \fBcolor\-callback\fP option determines the stage at which fonts that
+defined with a \fBcolor=xxyyzz\fP feature will be colorized. By default
+this happens in a \fBpost_linebreak_filter\fP but alternatively the
+\fBpre_linebreak_filter\fP or \fBpre_output_filter\fP may be chosen, which
+is faster but might produce inconsistent output. The
+\fBpre_output_filter\fP used to be the default in the 1.x series of
+Luaotfload, whilst later versions up to and including 2.5 hooked into
+the \fBpre_linebreak_filter\fP which naturally didn’t affect any glyphs
+inserting during hyphenation. Both are kept around as options to
+restore the previous behavior if necessary.
+.sp
+The \fBdefiner\fP allows for switching the \fBdefine_font\fP callback.
+Apart from the default \fBpatch\fP one may also choose the \fBgeneric\fP
+one that comes with the vanilla fontloader. Beware that this might
+break tools like Fontspec that rely on the \fBpatch_font\fP callback
+provided by Luaotfload to perform important corrections on font data.
+.sp
+The fontloader backend can be selected by setting the value of
+\fBfontloader\fP\&. The most important choices are \fBdefault\fP, which will
+load the dedicated Luaotfload fontloader, and \fBreference\fP, the
+upstream package as shipped with Luaotfload. Other than those, a file
+name accessible via kpathsea can be specified.
+.sp
+Alternatively, the individual files that constitute the fontloader can
+be loaded directly. While less efficient, this greatly aids debugging
+since error messages will reference the actual line numbers of the
+source files and explanatory comments are not stripped. Currently,
+three distinct loading strategies are available: \fBunpackaged\fP will
+load the batch that is part of Luaotfload. These contain the identical
+source code that the reference fontloader has been compiled from.
+Another option, \fBcontext\fP will attempt to load the same files by
+their names in the Context format from the search path. Consequently
+this option allows to use the version of Context that comes with the
+TeX distribution. Distros tend to prefer the stable version (“currentâ€
+in Context jargon) of those files so certain bugs encountered in the
+more bleeding edge Luaotfload can be avoided this way. A third option
+is to use \fBcontext\fP with a colon to specify a directory prefix where
+the \fITEXMF\fP is located that the files should be loaded from, e. g.
+\fBcontext:~/context/tex/texmf\-context\fP\&. This can be used when
+referencing another distribution like the Context minimals that is
+installed under a different path not indexed by kpathsea.
+.sp
+The value of \fBlog\-level\fP sets the default verbosity of messages
+printed by Luaotfload. Only messages defined with a verbosity of less
+than or equal to the supplied value will be output on the terminal.
+At a log level of five Luaotfload can be very noisy. Also, printing too
+many messages will slow down the interpreter due to line buffering
+being disabled (see \fBsetbuf\fP(3)).
+.sp
+The \fBresolver\fP setting allows choosing the font name resolution
+function: With the default value \fBcached\fP Luaotfload saves the result
+of a successful font name request to a cache file to speed up
+subsequent lookups. The alternative, \fBnormal\fP circumvents the cache
+and resolves every request individually. (Since to the restructuring of
+the font name index in Luaotfload 2.4 the performance difference
+between the cached and uncached lookups should be marginal.)
+.SH FILES
+.sp
+Luaotfload only processes the first configuration file it encounters at
+one of the search locations. The file name may be either
+\fBluaotfload.conf\fP or \fBluaotfloadrc\fP, except for the dotfile in the
+user’s home directory which is expected at \fB~/.luaotfloadrc\fP\&.
+.sp
+Configuration files are located following a series of steps. The search
+terminates as soon as a suitable file is encountered. The sequence of
+locations that Luaotfload looks at is
+.INDENT 0.0
+.IP i. 5
+The current working directory of the LuaTeX process.
+.IP ii. 5
+The subdirectory \fBluaotfload/\fP inside the XDG configuration
+tree, e. g. \fB/home/oenothea/config/luaotfload/\fP\&.
+.IP iii. 5
+The dotfile.
+.IP iv. 5
+The \fITEXMF\fP (using kpathsea).
+.UNINDENT
+.SH SEE ALSO
+.sp
+\fBluaotfload\-tool\fP(1), \fBluatex\fP(1), \fBlua\fP(1)
+.INDENT 0.0
+.IP \(bu 2
+\fBtexdoc luaotfload\fP to display the PDF manual for the \fILuaotfload\fP
+package
+.IP \(bu 2
+Luaotfload development \fI\%https://github.com/u\-fischer/luaotfload\fP
+.IP \(bu 2
+LuaLaTeX mailing list \fI\%http://tug.org/pipermail/lualatex\-dev/\fP
+.IP \(bu 2
+LuaTeX \fI\%http://luatex.org/\fP
+.IP \(bu 2
+Luaotfload on CTAN \fI\%http://ctan.org/pkg/luaotfload\fP
+.UNINDENT
+.SH REFERENCES
+.INDENT 0.0
+.IP \(bu 2
+The XDG base specification
+\fI\%http://standards.freedesktop.org/basedir\-spec/basedir\-spec\-latest.html\fP\&.
+.UNINDENT
+.SH AUTHORS
+.sp
+\fILuaotfload\fP was developed by the LuaLaTeX dev team
+(\fI\%https://github.com/lualatex/\fP). It is currently maintained by Ulrike Fischer
+and Marcel Krüger at \fI\%https://github.com/u\-fischer/luaotfload\fP
+.sp
+This manual page was written by Philipp Gesang <\fI\%phg@phi\-gamma.net\fP>.
+.SH COPYRIGHT
+GPL v2.0
+.\" Generated by docutils manpage writer.
+.
diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.example b/macros/luatex/generic/luaotfload/luaotfload.conf.example
new file mode 100644
index 0000000000..b0323afe51
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload.conf.example
@@ -0,0 +1,30 @@
+;; Example configuration file for Luaotfload. This file contains the
+;; defaults only, see luaotfload.conf(5) for more information.
+
+[db]
+ compress = true
+ formats = otf, ttf, ttc
+ max-fonts = 2.2517998136852e15
+ scan-local = false
+ skip-read = false
+ strip = true
+ update-live = true
+
+[misc]
+ statistics = false
+ termwidth = nil
+
+[paths]
+ cache-dir = fonts
+ names-dir = names
+ index-file = luaotfload-names.lua
+ lookups-file = luaotfload-lookup-cache.lua
+
+[run]
+ color-callback = pre_linebreak_filter
+ definer = patch
+ log-level = 0
+ resolver = cached
+
+;; vim:ft=dosini:et:sw=4:ts=8
+
diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.rst b/macros/luatex/generic/luaotfload/luaotfload.conf.rst
new file mode 100644
index 0000000000..754dff9f6a
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload.conf.rst
@@ -0,0 +1,409 @@
+=======================================================================
+ luaotfload.conf
+=======================================================================
+
+-----------------------------------------------------------------------
+ Luaotfload configuration file
+-----------------------------------------------------------------------
+
+:Date: 2019-08-11
+:Copyright: GPL v2.0
+:Version: 2.991
+:Manual section: 5
+:Manual group: text processing
+
+SYNOPSIS
+=======================================================================
+
+- **./luaotfload{.conf,rc}**
+- **XDG_CONFIG_HOME/luaotfload/luaotfload{.conf,rc}**
+- **~/.luaotfloadrc**
+
+DESCRIPTION
+=======================================================================
+
+The file ``luaotfload.conf`` contains configuration options for
+*Luaotfload*, a font loading and font management component for LuaTeX.
+
+
+EXAMPLE
+=======================================================================
+
+A small Luaotfload configuration file with few customizations could
+look as follows: ::
+
+ [db]
+ formats = afm,ttf
+ compress = false
+
+ [misc]
+ termwidth = 60
+
+ [run]
+ log-level = 6
+
+This will make Luaotfload ignore all font files except for PostScript
+binary fonts with a matching AFM file, and Truetype fonts. Also, an
+uncompressed index file will be dumped which is going to be much larger
+than the default gzip’ed index. The terminal width
+is truncated to 60 characters which influences the verbose output
+during indexing. Finally, the verbosity is increased greatly: each font
+file being processed will be printed to the stdout on a separate line,
+along with lots of other information.
+
+To observe the difference in behavior, save above snippet to
+``./luaotfload.conf`` and update the font index: ::
+
+ luaotfload-tool --update --force
+
+The current configuration can be written to disk using
+**luaotfload-tool**: ::
+
+ luaotfload-tool --dumpconf > luaotfload.conf
+
+The result can itself be used as a configuration file.
+
+
+SYNTAX
+=======================================================================
+
+The configuration file syntax follows the common INI format. For a more
+detailed description please refer to the section “CONFIGURATION FILEâ€
+of **git-config**\(1). A brief list of rules is given below:
+
+ * Blank lines and lines starting with a semicolon (``;``) are ignored.
+
+ * A configuration file is partitioned into sections that are declared
+ by specifying the section title in brackets on a separate line: ::
+
+ [some-section]
+ ... section content ...
+
+ * Sections consist of one or more variable assignments of the form
+ ``variable-name = value`` E. g.::
+
+ [foo]
+ bar = baz
+ quux = xyzzy
+ ...
+
+ * Section and variable names may contain only uppercase and lowercase
+ letters as well as dashes (``-``).
+
+
+VARIABLES
+=======================================================================
+
+Variables in belong into a configuration section and their values must
+be of a certain type. Some of them have further constraints. For
+example, the “color callback†must be a string of one of the values
+``post_linebreak_filter``, ``pre_linebreak_filter``, or
+``pre_output_filter``, defined in the section *run* of the
+configuration file.
+
+Currently, the configuration is organized into four sections:
+
+db
+ Options relating to the font index.
+
+misc
+ Options without a clearly defined category.
+
+paths
+ Path and file name settings.
+
+run
+ Options controlling runtime behavior of Luaotfload.
+
+The list of valid variables, the sections they are part of and their
+type is given below. Types represent Lua types that the values must be
+convertible to; they are abbreviated as follows: ``s`` for the *string*
+type, ``n`` for *number*, ``b`` for *boolean*. A value of ``nil`` means
+the variable is unset.
+
+
+Section ``db``
+-----------------------------------------------------------------------
+
++--------------------+--------+---------------------------+
+| variable | type | default |
++--------------------+--------+---------------------------+
+| compress | b | ``true`` |
++--------------------+--------+---------------------------+
+| designsize-dimen | b | ``bp`` |
++--------------------+--------+---------------------------+
+| formats | s | ``"otf,ttf,ttc"`` |
++--------------------+--------+---------------------------+
+| max-fonts | n | ``2^51`` |
++--------------------+--------+---------------------------+
+| scan-local | b | ``false`` |
++--------------------+--------+---------------------------+
+| skip-read | b | ``false`` |
++--------------------+--------+---------------------------+
+| strip | b | ``true`` |
++--------------------+--------+---------------------------+
+| update-live | b | ``true`` |
++--------------------+--------+---------------------------+
+
+The flag ``compress`` determines whether the font index (usually
+``luaotfload-names.lua[.gz]`` will be stored in compressed forms.
+If unset it is equivalent of passing ``--no-compress`` to
+**luaotfload-tool**. Since the file is only created for convenience
+and has no effect on the runtime behavior of Luaotfload, the flag
+should remain set. Most editors come with zlib support anyways.
+
+The setting ``designsize-dimen`` applies when looking up fonts from
+families with design sizes. In Opentype, these are specified as
+“decipoints†where one decipoint equals ten DTP style “big pointsâ€.
+When indexing fonts these values are converted to ``sp``. In order to
+treat the values as though they were specified in TeX points or Didot
+points, set ``designsize-dimen`` to ``pt`` or ``dd``.
+
+The list of ``formats`` must be a comma separated sequence of strings
+containing one or more of these elements:
+
+* ``otf`` (OpenType format),
+* ``ttf`` and ``ttc`` (TrueType format),
+* ``afm`` (Adobe Font Metrics),
+
+It corresponds loosely to the ``--formats`` option to
+**luaotfload-tool**. Invalid or duplicate members are ignored; if the
+list does not contain any useful identifiers, the default list
+``"otf,ttf,ttc"`` will be used.
+
+The variable ``max-fonts`` determines after processing how many font
+files the font scanner will terminate the search. This is useful for
+debugging issues with the font index and has the same effect as the
+option ``--max-fonts`` to **luaotfload-tools**.
+
+The ``scan-local`` flag, if set, will incorporate the current working
+directory as a font search location. NB: This will potentially slow
+down document processing because a font index with local fonts will not
+be saved to disk, so these fonts will have to be re-indexed whenever
+the document is built.
+
+The ``skip-read`` flag is only useful for debugging: It makes
+Luaotfload skip reading fonts. The font information for rebuilding the
+index is taken from the presently existing one.
+
+Unsetting the ``strip`` flag prevents Luaotfload from removing data
+from the index that is only useful when processing font files. NB: this
+can increase the size of the index files significantly and has no
+effect on the runtime behavior.
+
+If ``update-live`` is set, Luaotfload will reload the database if it
+cannot find a requested font. Those who prefer to update manually using
+**luaotfload-tool** should unset this flag. This option does not affect
+rebuilds due to version mismatch.
+
+Section ``default-features``
+-----------------------------------------------------------------------
+
+By default Luaotfload enables ``node`` mode and picks the default font
+features that are prescribed in the OpenType standard. This behavior
+may be overridden in the ``default-features`` section. Global defaults
+that will be applied for all scripts can be set via the ``global``
+option, others by the script they are to be applied to. For example,
+a setting of ::
+
+ [default-features]
+ global = mode=base,color=0000FF
+ dflt = smcp,onum
+
+would force *base* mode, tint all fonts blue and activate small
+capitals and text figures globally. Features are specified as a comma
+separated list of variables or variable-value pairs. Variables without
+an explicit value are set to ``true``.
+
+
+Section ``misc``
+-----------------------------------------------------------------------
+
++---------------+--------+-------------------------+
+| variable | type | default |
++---------------+--------+-------------------------+
+| statistics | b | ``false`` |
++---------------+--------+-------------------------+
+| termwidth | n | ``nil`` |
++---------------+--------+-------------------------+
+| version | s | <Luaotfload version> |
++---------------+--------+-------------------------+
+
+With ``statistics`` enabled, extra statistics will be collected during
+index creation and appended to the index file. It may then be queried
+at the Lua end or inspected by reading the file itself.
+
+The value of ``termwidth``, if set, overrides the value retrieved by
+querying the properties of the terminal in which Luatex runs. This is
+useful if the engine runs with ``shell_escape`` disabled and the actual
+terminal dimensions cannot be retrieved.
+
+The value of ``version`` is derived from the version string hard-coded
+in the Luaotfload source. Override at your own risk.
+
+
+Section ``paths``
+-----------------------------------------------------------------------
+
++------------------+--------+------------------------------------+
+| variable | type | default |
++------------------+--------+------------------------------------+
+| cache-dir | s | ``"fonts"`` |
++------------------+--------+------------------------------------+
+| names-dir | s | ``"names"`` |
++------------------+--------+------------------------------------+
+| index-file | s | ``"luaotfload-names.lua"`` |
++------------------+--------+------------------------------------+
+| lookups-file | s | ``"luaotfload-lookup-cache.lua"`` |
++------------------+--------+------------------------------------+
+
+The paths ``cache-dir`` and ``names-dir`` determine the subdirectory
+inside the Luaotfload subtree of the ``luatex-cache`` directory where
+the font cache and the font index will be stored, respectively.
+
+Inside the index directory, the names of the index file and the font
+lookup cache will be derived from the respective values of
+``index-file`` and ``lookups-file``. This is the filename base for the
+bytecode compiled version as well as -- for the index -- the gzipped
+version.
+
+
+Section ``run``
+-----------------------------------------------------------------------
+
++------------------+--------+------------------------------+
+| variable | type | default |
++------------------+--------+------------------------------+
+| anon-sequence | s | ``"tex,path,name"`` |
++------------------+--------+------------------------------+
+| color-callback | s | ``"post_linebreak_filter"`` |
++------------------+--------+------------------------------+
+| definer | s | ``"patch"`` |
++------------------+--------+------------------------------+
+| log-level | n | ``0`` |
++------------------+--------+------------------------------+
+| resolver | s | ``"cached"`` |
++------------------+--------+------------------------------+
+| fontloader | s | ``"default"`` |
++------------------+--------+------------------------------+
+
+Unqualified font lookups are treated with the flexible “anonymousâ€
+mechanism. This involves a chain of lookups applied successively until
+the first one yields a match. By default, the lookup will first search
+for TFM fonts using the Kpathsea library. If this wasn’t successful, an
+attempt is made at interpreting the request as an absolute path (like
+the ``[/path/to/font/foo.ttf]`` syntax) or a file name
+(``file:foo.ttf``). Finally, the request is interpreted as a font name
+and retrieved from the index (``name:Foo Regular``). This behavior can
+be configured by specifying a list as the value to ``anon-sequence``.
+Available items are ``tex``, ``path``, ``name`` -- representing the
+lookups described above, respectively --, and ``file`` for searching a
+filename but not an absolute path. Also, ``my`` lookups are valid
+values but they should only be used from within TeX documents, because
+there is no means of customizing a ``my`` lookups on the command line.
+
+The ``color-callback`` option determines the stage at which fonts that
+defined with a ``color=xxyyzz`` feature will be colorized. By default
+this happens in a ``post_linebreak_filter`` but alternatively the
+``pre_linebreak_filter`` or ``pre_output_filter`` may be chosen, which
+is faster but might produce inconsistent output. The
+``pre_output_filter`` used to be the default in the 1.x series of
+Luaotfload, whilst later versions up to and including 2.5 hooked into
+the ``pre_linebreak_filter`` which naturally didn’t affect any glyphs
+inserting during hyphenation. Both are kept around as options to
+restore the previous behavior if necessary.
+
+The ``definer`` allows for switching the ``define_font`` callback.
+Apart from the default ``patch`` one may also choose the ``generic``
+one that comes with the vanilla fontloader. Beware that this might
+break tools like Fontspec that rely on the ``patch_font`` callback
+provided by Luaotfload to perform important corrections on font data.
+
+The fontloader backend can be selected by setting the value of
+``fontloader``. The most important choices are ``default``, which will
+load the dedicated Luaotfload fontloader, and ``reference``, the
+upstream package as shipped with Luaotfload. Other than those, a file
+name accessible via kpathsea can be specified.
+
+Alternatively, the individual files that constitute the fontloader can
+be loaded directly. While less efficient, this greatly aids debugging
+since error messages will reference the actual line numbers of the
+source files and explanatory comments are not stripped. Currently,
+three distinct loading strategies are available: ``unpackaged`` will
+load the batch that is part of Luaotfload. These contain the identical
+source code that the reference fontloader has been compiled from.
+Another option, ``context`` will attempt to load the same files by
+their names in the Context format from the search path. Consequently
+this option allows to use the version of Context that comes with the
+TeX distribution. Distros tend to prefer the stable version (“currentâ€
+in Context jargon) of those files so certain bugs encountered in the
+more bleeding edge Luaotfload can be avoided this way. A third option
+is to use ``context`` with a colon to specify a directory prefix where
+the *TEXMF* is located that the files should be loaded from, e. g.
+``context:~/context/tex/texmf-context``. This can be used when
+referencing another distribution like the Context minimals that is
+installed under a different path not indexed by kpathsea.
+
+The value of ``log-level`` sets the default verbosity of messages
+printed by Luaotfload. Only messages defined with a verbosity of less
+than or equal to the supplied value will be output on the terminal.
+At a log level of five Luaotfload can be very noisy. Also, printing too
+many messages will slow down the interpreter due to line buffering
+being disabled (see **setbuf**\(3)).
+
+The ``resolver`` setting allows choosing the font name resolution
+function: With the default value ``cached`` Luaotfload saves the result
+of a successful font name request to a cache file to speed up
+subsequent lookups. The alternative, ``normal`` circumvents the cache
+and resolves every request individually. (Since to the restructuring of
+the font name index in Luaotfload 2.4 the performance difference
+between the cached and uncached lookups should be marginal.)
+
+
+FILES
+=======================================================================
+
+Luaotfload only processes the first configuration file it encounters at
+one of the search locations. The file name may be either
+``luaotfload.conf`` or ``luaotfloadrc``, except for the dotfile in the
+user’s home directory which is expected at ``~/.luaotfloadrc``.
+
+Configuration files are located following a series of steps. The search
+terminates as soon as a suitable file is encountered. The sequence of
+locations that Luaotfload looks at is
+
+i. The current working directory of the LuaTeX process.
+ii. The subdirectory ``luaotfload/`` inside the XDG configuration
+ tree, e. g. ``/home/oenothea/config/luaotfload/``.
+iii. The dotfile.
+iv. The *TEXMF* (using kpathsea).
+
+
+SEE ALSO
+=======================================================================
+
+**luaotfload-tool**\(1), **luatex**\(1), **lua**\(1)
+
+* ``texdoc luaotfload`` to display the PDF manual for the *Luaotfload*
+ package
+* Luaotfload development `<https://github.com/u-fischer/luaotfload>`_
+* LuaLaTeX mailing list `<http://tug.org/pipermail/lualatex-dev/>`_
+* LuaTeX `<http://luatex.org/>`_
+* Luaotfload on CTAN `<http://ctan.org/pkg/luaotfload>`_
+
+
+REFERENCES
+=======================================================================
+
+* The XDG base specification
+ `<http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_.
+
+AUTHORS
+=======================================================================
+
+*Luaotfload* was developed by the LuaLaTeX dev team
+(`<https://github.com/lualatex/>`_). It is currently maintained by Ulrike Fischer
+and Marcel Krüger at `<https://github.com/u-fischer/luaotfload>`_
+
+This manual page was written by Philipp Gesang <phg@phi-gamma.net>.
+
diff --git a/macros/luatex/generic/luaotfload/luaotfload.sty b/macros/luatex/generic/luaotfload/luaotfload.sty
new file mode 100644
index 0000000000..69f2a4151f
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload.sty
@@ -0,0 +1,53 @@
+%% Copyright (C) 2009-2018
+%%
+%% by Elie Roux <elie.roux@telecom-bretagne.eu>
+%% and Khaled Hosny <khaledhosny@eglug.org>
+%% and Philipp Gesang <phg@phi-gamma.net>
+%% and Dohyun Kim <nomosnomos@gmail.com>
+%% and David Carlisle <d.p.carlisle@gmail.com>
+%%
+%% This file is part of Luaotfload.
+%%
+%% Home: https://github.com/lualatex/luaotfload
+%%Current home: https://github.com/u-fischer/luaotfload
+%% Support: <lualatex-dev@tug.org>.
+%%
+%% Luaotfload is under the GPL v2.0 (exactly) license.
+%%
+%% ----------------------------------------------------------------------------
+%%
+%% Luaotfload is free software; you can redistribute it and/or
+%% modify it under the terms of the GNU General Public License
+%% as published by the Free Software Foundation; version 2
+%% of the License.
+%%
+%% Luaotfload is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%% GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with Luaotfload; if not, see <http://www.gnu.org/licenses/>.
+%%
+%% ----------------------------------------------------------------------------
+%%
+%% Classical Plain+\LATEX package initialization.
+%%
+\csname ifluaotfloadloaded\endcsname
+\let\ifluaotfloadloaded\endinput
+\ifx\newluafunction\undefined
+ \input ltluatex
+\fi
+\ifdefined\ProvidesPackage
+ \ProvidesPackage{luaotfload}%
+ [2019/08/11 v2.991 OpenType layout system]
+\fi
+\directlua{
+ if xpcall(function ()%
+ require('luaotfload-main')%
+ end,texio.write_nl) then %
+ local _void = luaotfload.main ()%
+ else %
+ texio.write_nl('Error in luaotfload - loading aborted')%
+ end %
+}
diff --git a/macros/luatex/generic/luapackageloader/README.md b/macros/luatex/generic/luapackageloader/README.md
new file mode 100644
index 0000000000..0326a4110d
--- /dev/null
+++ b/macros/luatex/generic/luapackageloader/README.md
@@ -0,0 +1,22 @@
+# luapackageloader
+CTAN package to allow LuaTeX to load packages from the default `package.path` and `package.cpath` locations. This could be useful
+to load external Lua modules, including modules installed via [LuaRocks](https://luarocks.org).
+
+## Usage
+See the [PDF documentation](luapackageloader.pdf) for details.
+
+Here is a quick TeX example:
+
+```tex
+\input luapackageloader
+
+% Now we proceed to load a LuaRocks package
+\directlua{
+ local spt = require("serpent")
+}
+```
+
+## License
+Distributable under the LaTeX Project Public License, version 1.3c or higher (your choice). The latest version of this license is at: http://www.latex-project.org/lppl.txt
+
+This work is "maintained" (as per LPPL maintenance status) by Deepak Jois.
diff --git a/macros/luatex/generic/luapackageloader/luapackageloader.lua b/macros/luatex/generic/luapackageloader/luapackageloader.lua
new file mode 100644
index 0000000000..7ebd5b63e3
--- /dev/null
+++ b/macros/luatex/generic/luapackageloader/luapackageloader.lua
@@ -0,0 +1,71 @@
+-- Author: Deepak Jois
+-- License: http://www.latex-project.org/lppl.txt
+-- Date: 2017/05/26
+-- Version: 0.1
+local luapackageloader = {}
+
+-- Cache the current kpse based searchers
+local kpse_lua_searcher = package.searchers[2]
+local kpse_clua_searcher = package.searchers[3]
+
+-- Emulates the default package.searchers[2] searcher.
+local function lua_searcher(name)
+ local file, err = package.searchpath(name,package.path)
+ if err then
+ return string.format("[lua searcher]: module not found: '%s'%s", name, err)
+ else
+ return loadfile(file)
+ end
+end
+
+-- Emulates the default package.searchers[3] searcher.
+local function clua_searcher(name)
+ local file, err = package.searchpath(name, package.cpath)
+ if err then
+ return string.format("[lua C searcher]: module not found: '%s'%s", name,err)
+ else
+ local symbol = name:gsub("%.","_")
+ return package.loadlib(file, "luaopen_"..symbol)
+ end
+end
+
+local function combine_searchers(searcher1, searcher2)
+ return function(name)
+ local loader1 = searcher1(name)
+ if type(loader1) == "string" then -- Not found using searcher1. Try searcher2.
+ local loader2 = searcher2(name)
+ if type(loader2) == "string" then -- Not found using searcher2. Return error.
+ return string.format("%s\n\t%s", loader1, loader2)
+ end
+ return loader2
+ end
+ return loader1
+ end
+end
+
+--- Use package.path and package.cpath to find Lua modules,
+-- in case kpse searching fails.
+--
+-- Package searching logic is overridden by default in LuaTeX to use kpse.
+-- Calling this function reverts the searchers to use package.path and
+-- package.cpath, if the kpse based searcher is not able to locate
+-- a module.
+--
+-- Package Loading References:
+-- 1. http://www.lua.org/manual/5.2/manual.html#pdf-package.searchers
+-- 2. LuaTeX Manual, Section 3.2, Lua behavior
+function luapackageloader.add_lua_searchers()
+ package.searchers[2] = combine_searchers(kpse_lua_searcher, lua_searcher)
+ package.searchers[3] = combine_searchers(kpse_clua_searcher, clua_searcher)
+end
+
+--- Restore the kpse package searchers that are used by default in LuaTeX.
+--
+-- Call this to restore the default LuaTeX behavior for searching packages,
+-- if you had earlier overridden it using `luapackageloader.add_lua_searchers()`.
+function luapackageloader.restore_kpse_searchers()
+ package.searchers[2] = kpse_lua_searcher
+ package.searchers[3] = kpse_clua_searcher
+end
+
+return luapackageloader
diff --git a/macros/luatex/generic/luapackageloader/luapackageloader.pdf b/macros/luatex/generic/luapackageloader/luapackageloader.pdf
new file mode 100644
index 0000000000..056a1d5967
--- /dev/null
+++ b/macros/luatex/generic/luapackageloader/luapackageloader.pdf
Binary files differ
diff --git a/macros/luatex/generic/luapackageloader/luapackageloader.sty b/macros/luatex/generic/luapackageloader/luapackageloader.sty
new file mode 100644
index 0000000000..7a6219e1c6
--- /dev/null
+++ b/macros/luatex/generic/luapackageloader/luapackageloader.sty
@@ -0,0 +1,35 @@
+% Author: Deepak Jois
+% License: http://www.latex-project.org/lppl.txt
+% Date: 2017/05/26
+% Version: 0.1
+\def\luapackageloaderpkgdate{2017/05/26}
+\def\luapackageloaderversion{0.1}
+
+\expandafter\ifx\csname ProvidesPackage\endcsname\relax
+ \input ifluatex.sty\relax
+\else
+ \NeedsTeXFormat{LaTeX2e}
+ \ProvidesPackage{}[\luapackageloaderpkgdate\space v\luapackageloaderversion\space Lua package searchers for LuaTeX]
+ \RequirePackage{ifluatex}
+\fi
+
+\def\luapackageloader@dothings{%
+ \directlua{
+ luapackageloader = require("luapackageloader")
+ luapackageloader.add_lua_searchers()
+ }%
+}
+
+\expandafter\ifx\csname ProvidesPackage\endcsname\relax
+ \ifluatex
+ \luapackageloader@dothings
+ \else
+ \message{Warning: luapackageloader only works with LuaTeX (plain and LaTeX format)}
+ \fi
+\else
+ \ifluatex
+ \luapackageloader@dothings
+ \else
+ \PackageWarning{luapackageloader}{You are using this package without LuaTeX. This is not supported.}
+ \fi
+\fi
diff --git a/macros/luatex/generic/luapackageloader/luapackageloader.tex b/macros/luatex/generic/luapackageloader/luapackageloader.tex
new file mode 100644
index 0000000000..4e2a9885ec
--- /dev/null
+++ b/macros/luatex/generic/luapackageloader/luapackageloader.tex
@@ -0,0 +1,116 @@
+\documentclass[a4paper]{article}
+
+%% Language and font encodings
+\usepackage[english]{babel}
+\usepackage[utf8x]{inputenc}
+\usepackage[T1]{fontenc}
+
+%% Sets page size and margins
+\usepackage[a4paper,top=3cm,bottom=2cm,left=3cm,right=3cm,marginparwidth=1.75cm]{geometry}
+
+%% Useful packages
+\usepackage[colorlinks=true,
+ linkcolor = blue,
+ urlcolor = blue,
+ citecolor = blue,
+ anchorcolor = blue]{hyperref}
+\usepackage{xcolor}
+\usepackage{minted}
+\usepackage{csquotes}
+
+\definecolor{LG}{HTML}{F9F9F9}
+
+%% Informations
+\title{\textsf{luapackageloader} package}
+\author{Deepak Jois \\ \href{deepak.jois@gmail.com}{deepak.jois@gmail.com}}
+
+\begin{document}
+\maketitle
+
+\section*{Introduction}
+LuaTeX modifies the package loading behavior for Lua package, as mentioned in
+Section 3.2 of the LuaTeX manual:
+
+\begin{displayquote}
+LuaTEX is able to use the kpathsea library to find require()d modules. For this
+purpose, \texttt{package.searchers[2]} is replaced by a different loader function,
+that decides at runtime whether to use kpathsea or the built-in core Lua
+function. It uses kpathsea when that is already initialized at that point in
+ time, otherwise it reverts to using the normal \texttt{package.path} loader.
+\end{displayquote}
+
+What this means is that once kpathsea is initialized, the normal package
+loading behavior is no longer available.
+
+This package allows Lua package loading behavior inside LuaTeX to use \textit{both}
+kpathsea and the default loading mechanism. If the module is not available in kpathsea,
+LuaTeX will try to load it from \texttt{package.path}. This functionality is very useful,
+for instance when you need to use \href{https://luarocks.org/}{LuaRocks} modules inside LuaTeX.
+
+\section{Installation}
+
+Install this package like any other \TeX~or \LaTeX~package.
+
+\section{Dependencies}
+
+This package depends on \href{https://www.ctan.org/pkg/ifluatex}{ifluatex} CTAN package.
+
+\section{Usage}
+
+\subsection{Plain \TeX}
+In Plain \TeX, you can import the module as follows:
+
+\begin{minted}[bgcolor=LG, fontsize=\footnotesize]{tex}
+\input luapackageloader.sty
+\end{minted}
+
+\subsection{\LaTeX}
+
+In \LaTeX, add the \texttt{luapackageloader} packages to your document:
+
+\begin{minted}[bgcolor=LG, fontsize=\footnotesize]{tex}
+\usepackage{luapackageloader}
+\end{minted}
+
+\subsection{Loading Packages}
+
+Once you have imported \texttt{luapackageloader}, it adds a table called
+\texttt{luapackageloader} under the global namepace, and automatically
+overrides the default LuaTeX package searchers. It should be possible to load a
+Lua package (including \href{https://luarocks.org/}{LuaRocks} modules, as long
+as \texttt{package.path} and \texttt{package.cpath} is setup properly in your
+environment) as follows:
+
+\begin{minted}[bgcolor=LG, fontsize=\footnotesize]{tex}
+\directlua{
+ local serpent = require("serpent") % luarocks install serpent
+}
+\end{minted}
+
+\subsection{Reverting to default loading behavior}
+
+The package loading can be reverted back to the default LuaTeX behavior using the \texttt{restore\_kpse\_searchers()}
+\begin{minted}[bgcolor=LG, fontsize=\footnotesize]{tex}
+\directlua{
+ luapackageloader.resetore_kpse_searchers()
+}
+\end{minted}
+
+\subsection{Manually setting up to load Lua packages}
+
+This package exposes the function \texttt{add\_lua\_searchers()}, to manually setup the package searchers again, if it was reverted for some reason, after loading the package.
+
+\begin{minted}[bgcolor=LG, fontsize=\footnotesize]{tex}
+\input luapackageloader.sty
+\directlua{
+ % Let’s revert the package searchers to their default loading behavior.
+ luapackageloader.restore_kpse_searchers()
+
+ % Some code here...
+
+ % Now let’s setup the package searchers to use Lua searchers again.
+ luapackageloader.add_lua_searchers()
+}
+\end{minted}
+
+\end{document}
diff --git a/macros/luatex/generic/luatexbase/README.md b/macros/luatex/generic/luatexbase/README.md
new file mode 100644
index 0000000000..bbcb8d4654
--- /dev/null
+++ b/macros/luatex/generic/luatexbase/README.md
@@ -0,0 +1,7 @@
+The LaTeX kernel (LaTeX2e 2015/10/01 onward) builds in support for
+LuaTeX functionality, also available as `ltluatex.tex` for users for
+users of plain TeX and those with older LaTeX kernel implementations.
+This support is based on ideas taken from the original `luatexbase`
+package, but there are interface differences. This 'stub' package
+provides a compatibility layer to allow existing packages to upgrade
+smoothly to the new support structure.
diff --git a/macros/luatex/generic/luatexbase/luatexbase.dtx b/macros/luatex/generic/luatexbase/luatexbase.dtx
new file mode 100644
index 0000000000..a00e9481d1
--- /dev/null
+++ b/macros/luatex/generic/luatexbase/luatexbase.dtx
@@ -0,0 +1,860 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2009-2013 by Élie Roux <elie.roux@telecom-bretagne.eu>
+% Copyright (C) 2010, 2011 by Manuel Pégourié-Gonnard <mpg@elzevir.fr>
+% Copyright (C) 2015 David Carlisle and Joseph Wright
+%
+% It may be distributed and/or modified under the conditions of
+% the LaTeX Project Public License (LPPL), either version 1.3c of
+% this license or (at your option) any later version. The latest
+% version of this license is in the file:
+%
+% http://www.latex-project.org/lppl.txt
+%
+%<emu>\ifx\BeginCatcodeRegime\undefined\else\expandafter\endinput\fi
+%<tex,sty>
+%<tex,sty>\ifx
+%<sty> \ProvidesPackage\undefined\begingroup\def\ProvidesPackage
+%<tex> \ProvidesFile\undefined\begingroup\def\ProvidesFile
+%<tex,sty> #1#2[#3]{\endgroup\immediate\write-1{Package: #1 #3}}
+%<tex,sty>\fi
+%<emu>\ProvidesPackage{luatexbase}
+%<emu-cmp>\ProvidesPackage{luatexbase-compat}
+%<emu-mod>\ProvidesPackage{luatexbase-modutils}
+%<emu-loa>\ProvidesPackage{luatexbase-loader}
+%<emu-reg>\ProvidesPackage{luatexbase-regs}
+%<emu-att>\ProvidesPackage{luatexbase-attr}
+%<emu-cct>\ProvidesPackage{luatexbase-cctb}
+%<emu-mcb>\ProvidesPackage{luatexbase-mcb}
+%<*driver>
+\ProvidesFile{luatexbase.dtx}
+%</driver>
+%<*tex,sty>
+[2015/10/04 v1.3
+%</tex,sty>
+%<emu> luatexbase interface to LuaTeX
+%<emu-cmp> luatexbase interface to LuaTeX (legacy subpackage)
+%<emu-mod> luatexbase interface to LuaTeX (legacy subpackage)
+%<emu-loa> luatexbase interface to LuaTeX (legacy subpackage)
+%<emu-reg> luatexbase interface to LuaTeX (legacy subpackage)
+%<emu-att> luatexbase interface to LuaTeX (legacy subpackage)
+%<emu-cct> luatexbase interface to LuaTeX (legacy subpackage)
+%<emu-mcb> luatexbase interface to LuaTeX (legacy subpackage)
+%<*tex,sty>
+]
+%</tex,sty>
+%<*driver>
+\documentclass{ltxdoc}
+\GetFileInfo{luatexbase.dtx}
+\begin{document}
+\title{\filename\\(Lua\TeX{}-specific support, luatexbase interface)}
+\author{David Carlisle and Joseph Wright\footnote{Significant portions
+ of the code here are adapted/simplified from the packages \textsf{luatex} and
+ \textsf{luatexbase} written by Heiko Oberdiek, \'{E}lie Roux,
+ Manuel P\'{e}gouri\'{e}-Gonnar and Philipp Gesang.}}
+\date{\filedate}
+\maketitle
+\setcounter{tocdepth}{2}
+\tableofcontents
+\DocInput{\filename}
+\end{document}
+%</driver>
+% \fi
+%
+% \section{Overview}
+%
+% Lua\TeX{} adds a number of engine-specific functions to \TeX{}. Support
+% for those is now available for this area in the \LaTeX{} kernel and as
+% an equivalent stand-alone file |ltluatex.tex| for plain users. The
+% functionality there is derived from the earlier \textsf{luatex}
+% and \textsf{luatexbase} packages by Heiko Oberdiek, \'{E}lie Roux,
+% Manuel P\'{e}gouri\'{e}-Gonnar and Philipp Gesang. However, the
+% interfaces are not all identical.
+%
+% The interfaces defined in this package are closely modelled on the original
+% \textsf{luatexbase} package, and provide a compatibility layer between
+% the new kernel-level support and existing code using \textsf{luatexbase}.
+%
+% \section{The \textsf{luatexbase} package interface}
+%
+% \subsection
+% [Catcode tables]
+% {Catcode tables\footnote{This
+% interface was previously defined in the \textsf{luatexbase-cctbl}
+% sub-package.}}
+%
+% \subsubsection{\TeX}
+%
+%
+% \noindent
+% \DescribeMacro{\CatcodeTableIniTeX}
+% \DescribeMacro{\CatcodeTableString}
+% \DescribeMacro{\CatcodeTableLaTeX}
+% \DescribeMacro{\CatcodeTableLaTeXAtLetter}
+% \DescribeMacro{\CatcodeTableOther}
+% \DescribeMacro{\CatcodeTableExpl}
+% \TeX\ access to predefined catcode tables.
+%
+% The first four tables are aliases giving alternative names for some
+% catcodetables that are defined in the \textsf{ltluatex} core.
+%
+% |\CatcodeTableOther| is like |\CatcodeTableString| except that
+% the catcode of space is $12$ (other).
+%
+% |\CatcodeTableExpl| is similar to the environment set by the
+% \textsf{expl3} command |\ExplSyntaxOn| note that this only affects
+% catcode settings, not for example |\endlinechar|.
+%
+% One difference between this implementation and the tables defined
+% in the earlier \textsf{luatexbase} package is that these tables are
+% defined to match the settings used by \LaTeX\ over the full Unicode
+% range (as set in the file \textsf{unicode-letters.def}).
+%
+% \noindent
+% \DescribeMacro{\SetCatcodeRange}
+% An alias for |\@setrangecatcode| which is defined in the
+% \textsf{ctablestack} package imported into this version of
+% \textsf{luatexbase}. (The order of arguments is the
+% same despite the variation in the naming). This is useful for
+% setting up a new catcode table and assigns a given catcode to a
+% range of characters.
+%
+% \noindent
+% \DescribeMacro{\BeginCatcodeRegime}
+% \DescribeMacro{\EndCatcodeRegime}
+% A simple wrapper around |\@pushcatcodetable| providing a slightly
+% different interface. The usage is:\\%
+% \verb|\BeginCatcodeRegime|\meta{catcode table}\\
+% \verb| |\meta{code}\\
+% \verb|\EndCatcodeRegime|
+%
+% \noindent
+% \DescribeMacro{\PushCatcodeTableNumStack}
+% \DescribeMacro{\PopCatcodeTableNumStack}
+% These are defined to be aliases for |\@pushcatcodetable| and
+% |\@popcatcodetable| although the actual implementation is quite different
+% to the older packages, the use of the commands should match.
+%
+% \noindent
+% \DescribeMacro{\newluatexcatcodetable}
+% \DescribeMacro{\setluatexcatcodetable}
+% Aliases for the \textsf{ltluatex} functions
+% dropping |luatex| from the name to match the convention of not
+% using |luatex|-prefixed names for the Lua\TeX\ primitives.
+%
+% \subsubsection{Lua}
+%
+% The standard way to access catcode table numbers from Lua in
+% \textsf{ltluatex} is the |registernumber| function. This
+% package provides a |catcodetables| table with a metatable
+% that accesses this function and is extended with aliases for the
+% predefined tables so you can use |catcodetables.expl| as an
+% alternative to |catcodetables.CatcodeTableExpl|, both being
+% equivalent to\\
+% |registernumber('CatcodeTableExpl')|.
+%
+%
+% \subsection
+% [Lua Callbacks]
+% {Lua Callbacks\footnote{This
+% interface was previously defined in the \textsf{luatexbase-mcb}
+% sub-package.}}
+%
+% The |luatexbase| table is extended with some additional Lua
+% functions to provide the interfaces provided by the previous
+% implementation.
+%
+%
+% \noindent
+% \DescribeMacro{priority\_in\_callback}\meta{name}\meta{description}\\%
+% As in the earlier interfaces the function
+% is provided to return a number indicating the position of a
+% specified function in a callback list. However it is usually used
+% just as a boolean test that the function is registered with the
+% callback. Kernel-level support does not directly expose the priority numbers,
+% however the function here is defined to return the number of the specified
+% function in the list returned by |luatexbase.callback_descriptions|.
+%
+%
+% \noindent
+% \DescribeMacro{is\_active\_callback}\meta{name}\meta{description}\\%
+% This boolean function was defined in the development sources
+% of the previous implementation. Here it is defined as an alias for
+% the function |in_callback| provided by \textsf{ltluatex}.
+% Given a callback and a description string, it returns true if a
+% callback function with that description is currently registered.
+%
+% \noindent
+% \DescribeMacro{reset\_callback}\meta{name}\meta{make\_false}\\
+% This function unregisters all functions registered for the callback
+% \meta{name}. If \meta{make\_false} is true, the callback is then set
+% to false (rather than nil). Unlike the earlier implementation
+% This version does call |remove_from_callback| on each function in
+% the callback list for \meta{name}, and each removal will be recorded
+% in the log.
+%
+% \noindent
+% \DescribeMacro{remove\_from\_callback}\meta{name}\meta{description}\\%
+% This function is unchanged from the kernel-level implementation.
+% It is backward compatible with the previous \textsf{luatexbase}
+% package but enhanced as it returns the removed callback and its
+% description.
+% Together with the |callback_descriptions| function this allows much
+% finer control over the order of functions in a callback list as the
+% functions can be removed then re-added to the list in any desired order.
+%
+% \noindent
+% \DescribeMacro{add\_to\_callback}\meta{name}\meta{function}\meta{description}\meta{priority}\\%
+% This function is defined as a wrapper around the kernel-level
+% implementation, which does not have the fourth \meta{priority}
+% argument.
+%
+% If multiple callbacks are registered to a callback of type
+% \textsf{exclusive} then \textsf{ltluatex} raises an error, but
+% here it is allowed if \texttt{priority} is $1$, in which case the
+% \verb|reset_callback| is first called to remove the existing
+% callback.
+%
+% In general the \texttt{priority} argument is implemented by
+% temporarily removing some callbacks from the list and replacing
+% them after having added the new callback.
+%
+% \noindent
+% \DescribeMacro{create\_callback}\meta{name}\meta{type}\meta{default}\\%
+% This function is unchanged from kernel-level
+% implementation, the only change is a change of terminology for the
+% types of callback, the type |first| is now classified as |exclusive|
+% and the kernel code raises an error if multiple callback functions
+% are registered. The previous \textsf{luatexbase} implementation
+% allowed multiple functions to be registered, but only activated the
+% first in the list.
+%
+% \subsection
+% [Module declaration]
+% {Module declaration\footnote{This
+% interface was previously defined in the \textsf{luatexbase-modutils}
+% sub-package.}}
+%
+% \subsubsection{\TeX}
+%
+% \noindent
+% \DescribeMacro{\RequireLuaModule}\meta{file}\oarg{info}\\
+% This command is provided as a wrapper around
+% |\directlua{require(|\meta{file}|}|, and executes the Lua code in
+% the specified file.
+% The optional argument is accepted but ignored.
+%
+% Current versions of Lua\TeX\ all use the |kpse| \TeX\ path searching
+% library with the |require| function, so the more complicated
+% definition used in earlier implementations is no
+% longer needed.
+%
+% \subsubsection{Lua}
+%
+% \noindent
+% \DescribeMacro{provides\_module}\meta{info}\\
+% The \textsf{luatexbase} version of |provides_module| returns a list of log
+% and error functions so that it is usually called as:\\
+% |local err, warning, info, log = luatexbase.provides_module({name=..|
+%
+% The returned functions are all instances of the functions provided by
+% the kernel: |module_error|,
+% |module_warning| and |module_info|, They all use their first argument
+% as a format string fo rany later arguments.
+%
+% \DescribeMacro{errwarinf}\meta{name}\\
+% Returns four error and warning functions associated with \meta{name}
+% mostly a helper function for \verb|provides\_module|, but can be called
+% separately.
+%
+% \subsection
+% [Lua Attributes]
+% {Lua Attributes and Whatsits\footnote{This
+% interface was previously defined in the \textsf{luatexbase-attr}
+% sub-package.}}
+%
+%
+% \subsubsection{\TeX}
+%
+% \noindent
+% \DescribeMacro{\newluatexattribute}
+% \DescribeMacro{\setluatexattribute}
+% \DescribeMacro{\unsetluatexattribute}
+% As for catcode tables, aliases for the attribute allocation functions are
+% provided with |luatex| in the names.
+%
+%
+% \subsubsection{Lua}
+% The lua code in this section is concerned with an experimental
+% whatsit handling suite of functions in the original package.
+% This is not fully documented here and is guraded by the
+% \textsf{docstrip} guard \verb|whatsit| so it may optionally be
+% included or excluded from the sources when the package is built.
+%
+% \subsection{Prefixed names for lua\TeX\ primitives}
+% \noindent
+% \DescribeMacro{\luatexattributedef}
+% \DescribeMacro{\luatexcatcodetable}
+% \DescribeMacro{\luatexluaescapestring}
+% \DescribeMacro{\luatexlatelua}
+% \DescribeMacro{\luatexoutputbox}
+% \DescribeMacro{\luatexscantextokens}
+% Aliases for commonly ued lua\TeX\ primitives that existing packages
+% using \textsf{luatexbase} use with prefixed names.
+%
+% If additional primtives are required it is recommended that the
+% code is updated to use unprefixed names. To ensure that the code
+% works with the original \textsf{luatexbase} package on older formats
+% you may use the lua function \texttt{tex.enableprimitives} to enable
+% some or all primitives to be available with unprefixed names.
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \subsection{\textsf{luatexbase} interface}
+%
+% \begin{macrocode}
+%<*emu>
+\edef\emuatcatcode{\the\catcode`\@}
+\catcode`\@=11
+% \end{macrocode}
+%
+% Load |ctablestack|.
+% \begin{macrocode}
+\ifx\@setrangecatcode\@undefined
+ \ifx\RequirePackage\@undefined
+ \input{ctablestack.sty}%
+ \else
+ \RequirePackage{ctablestack}
+ \fi
+\fi
+% \end{macrocode}
+%
+% Simple require wrapper as we now assume |require| implicitly uses the
+% |kpathsea| search library.
+% \begin{macrocode}
+\def\RequireLuaModule#1{\directlua{require("#1")}\@gobbleoptarg}
+% \end{macrocode}
+%
+% In \LaTeX\ (or plain macro package that has defined |\@ifnextchar|)
+% use |\@ifnextchar| otherwise use a simple alternative, in practice this
+% will never be followed by a brace group, so full version of |\@ifnextchar|
+% not needed.
+% \begin{macrocode}
+\ifdefined\@ifnextchar
+\def\@gobbleoptarg{\@ifnextchar[\@gobble@optarg{}}%
+\else
+\long\def\@gobbleoptarg#1{\ifx[#1\expandafter\@gobble@optarg\fi#1}%
+\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\@gobble@optarg[#1]{}
+% \end{macrocode}
+%
+% Extended catcode table support. Use the names from the previous
+% \textsf{luatexbase} and \textsf{luatex} packages.
+% \begin{macrocode}
+\let\CatcodeTableIniTeX\catcodetable@initex
+\let\CatcodeTableString\catcodetable@string
+\let\CatcodeTableLaTeX\catcodetable@latex
+\let\CatcodeTableLaTeXAtLetter\catcodetable@atletter
+% \end{macrocode}
+%
+% Additional tables declared in the previous interface.
+% \begin{macrocode}
+\newcatcodetable\CatcodeTableOther
+\@setcatcodetable\CatcodeTableOther{%
+ \catcodetable\CatcodeTableString
+ \catcode32 12 }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcatcodetable\CatcodeTableExpl
+\@setcatcodetable\CatcodeTableExpl{%
+ \catcodetable\CatcodeTableLaTeX
+ \catcode126 10 % tilde is a space char
+ \catcode32 9 % space is ignored
+ \catcode9 9 % tab also ignored
+ \catcode95 11 % underscore letter
+ \catcode58 11 % colon letter
+}
+% \end{macrocode}
+%
+% Top level access to catcodetable stack.
+% \begin{macrocode}
+\def\BeginCatcodeRegime#1{%
+ \@pushcatcodetable
+ \catcodetable#1\relax}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\EndCatcodeRegime{%
+ \@popcatcodetable}
+% \end{macrocode}
+%
+% The implementation of the stack is completely
+% different, but usage should match.
+% \begin{macrocode}
+\let\PushCatcodeTableNumStack\@pushcatcodetable
+\let\PopCatcodeTableNumStack\@popcatcodetable
+% \end{macrocode}
+%
+% A simple copy.
+% \begin{macrocode}
+\let\SetCatcodeRange\@setrangecatcode
+% \end{macrocode}
+%
+% Another copy.
+% \begin{macrocode}
+\let\setcatcodetable\@setcatcodetable
+% \end{macrocode}
+%
+% \subsubsection{Additional lua code}
+% \begin{macrocode}
+\directlua{
+% \end{macrocode}
+%
+% Remove all registered callbacks, then disable.
+% Set to false if optional second argument is |true|.
+% \begin{macrocode}
+function luatexbase.reset_callback(name,make_false)
+ for _,v in pairs(luatexbase.callback_descriptions(name))
+ do
+ luatexbase.remove_from_callback(name,v)
+ end
+ if make_false == true then
+ luatexbase.disable_callback(name)
+ end
+end
+% \end{macrocode}
+%
+% Allow exclusive callbacks to be over-written if priority argument is
+% 1 to match the ``first'' semantics of the original package.
+% \changes{v1.1}{2015/10/02}{Fully handle priority argument}
+%
+% First save the kernel function.
+% \begin{macrocode}
+luatexbase.base_add_to_callback=luatexbase.add_to_callback
+% \end{macrocode}
+%
+% Implement the priority argument by taking off existing callbacks
+% that have higher priority than the new one, adding the new one,
+% Then putting the saved callbacks back.
+% \begin{macrocode}
+function luatexbase.add_to_callback(name,fun,description,priority)
+% \end{macrocode}
+%^^A texio.write_nl('\string\n HERE: adding ' ..
+%^^A description ..
+%^^A ' to ' ..
+%^^A name ..
+%^^A ' with priority ' ..
+%^^A (priority or '@@@'))
+%^^A texio.write_nl('Original list')
+%^^A for k,v in pairs(luatexbase.callback_descriptions(name)) do
+%^^A texio.write_nl(' ' .. k .. ': ' .. v)
+%^^A end
+% \begin{macrocode}
+ local priority= priority
+ if priority==nil then
+ priority=\string#luatexbase.callback_descriptions(name)+1
+ end
+ if(luatexbase.callbacktypes[name] == 3 and
+ priority == 1 and
+ \string#luatexbase.callback_descriptions(name)==1) then
+ luatexbase.module_warning("luatexbase",
+ "resetting exclusive callback: " .. name)
+ luatexbase.reset_callback(name)
+ end
+ local saved_callback={},ff,dd
+ for k,v in pairs(luatexbase.callback_descriptions(name)) do
+ if k >= priority then
+ ff,dd= luatexbase.remove_from_callback(name, v)
+ saved_callback[k]={ff,dd}
+ end
+ end
+ luatexbase.base_add_to_callback(name,fun,description)
+ for k,v in pairs(saved_callback) do
+ luatexbase.base_add_to_callback(name,v[1],v[2])
+ end
+% \end{macrocode}
+%^^A texio.write_nl('New list')
+%^^A for k,v in pairs(luatexbase.callback_descriptions(name)) do
+%^^A texio.write_nl(' ' .. k .. ': ' .. v)
+%^^A end
+% \begin{macrocode}
+ return
+end
+% \end{macrocode}
+%
+% Emulate the catcodetables table.
+% Explicitly fill the table rather than rely on the metatable call to
+% |registernumber| as that is unreliable on old Lua\TeX{}.
+% \begin{macrocode}
+luatexbase.catcodetables=setmetatable(
+ {['latex-package'] = \number\CatcodeTableLaTeXAtLetter,
+ ini = \number\CatcodeTableIniTeX,
+ string = \number\CatcodeTableString,
+ other = \number\CatcodeTableOther,
+ latex = \number\CatcodeTableLaTeX,
+ expl = \number\CatcodeTableExpl,
+ expl3 = \number\CatcodeTableExpl},
+ { __index = function(t,key)
+ return luatexbase.registernumber(key) or nil
+ end}
+)}
+% \end{macrocode}
+%
+% On old Lua\TeX{} workaround hashtable issues.
+% Allocate in \TeX{}, and also directly add to |luatexbase.catcodetables|.
+% \begin{macrocode}
+\ifnum\luatexversion<80 %
+\def\newcatcodetable#1{%
+ \e@alloc\catcodetable\chardef
+ \e@alloc@ccodetable@count\m@ne{"8000}#1%
+ \initcatcodetable\allocationnumber
+ {\escapechar=\m@ne
+ \directlua{luatexbase.catcodetables['\string#1']=%
+ \the\allocationnumber}}%
+}
+\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+\directlua{
+% \end{macrocode}
+%
+% |priority_in_callback| returns position in the callback list.
+% Not provided by default by the kernel as usually it is just used
+% as a boolean test, for which |in_callback| is provided.
+% \begin{macrocode}
+function luatexbase.priority_in_callback (name,description)
+ for i,v in ipairs(luatexbase.callback_descriptions(name))
+ do
+ if v == description then
+ return i
+ end
+ end
+ return false
+end
+% \end{macrocode}
+%
+% The (unreleased) version~0.7 of \textsf{luatexbase} provided this
+% boolean test under a different name, so we provide an alias here.
+% \begin{macrocode}
+luatexbase.is_active_callback = luatexbase.in_callback
+% \end{macrocode}
+%
+% \textsf{ltluatex} implementation of |provides_module| does not return
+% print functions so define modified version here.
+% \changes{v1.3}{2015/10/03}{Use the first argument as a format string for
+% later arguments}
+% \begin{macrocode}
+luatexbase.base_provides_module=luatexbase.provides_module
+function luatexbase.errwarinf(name)
+ return
+ function(s,...) return luatexbase.module_error(name, s:format(...)) end,
+ function(s,...) return luatexbase.module_warning(name, s:format(...)) end,
+ function(s,...) return luatexbase.module_info(name, s:format(...)) end,
+ function(s,...) return luatexbase.module_info(name, s:format(...)) end
+end
+function luatexbase.provides_module(info)
+ luatexbase.base_provides_module(info)
+ return luatexbase.errwarinf(info.name)
+end
+}
+% \end{macrocode}
+%
+% Same for attribute table as catcode tables. In old Lua\TeX{}, add to the
+% |luatexbase.attributes| table directly.
+% \begin{macrocode}
+\ifnum\luatexversion<80 %
+\def\newattribute#1{%
+ \e@alloc\attribute\attributedef
+ \e@alloc@attribute@count\m@ne\e@alloc@top#1%
+ {\escapechar=\m@ne
+ \directlua{luatexbase.attributes['\string#1']=%
+ \the\allocationnumber}}%
+}
+\fi
+% \end{macrocode}
+%
+% Define a safe percent command for plain \TeX.
+% \begin{macrocode}
+\ifx\@percentchar\@undefined
+ {\catcode`\%=12 \gdef\@percentchar{%}}
+\fi
+% \end{macrocode}
+% \changes{v1.2a}{2015/10/03}{Add missing local definitions for whatsit code}
+%
+% \begin{macrocode}
+%<*whatsit>
+\directlua{%
+% \end{macrocode}
+%
+% \begin{macrocode}
+local copynode = node.copy
+local newnode = node.new
+local nodesubtype = node.subtype
+local nodetype = node.id
+local stringformat = string.format
+local tableunpack = unpack or table.unpack
+local texiowrite_nl = texio.write_nl
+local texiowrite = texio.write
+local whatsit_t = nodetype"whatsit"
+local user_defined_t = nodesubtype"user_defined"
+local unassociated = "__unassociated"
+local user_whatsits = { __unassociated = { } }
+local whatsit_ids = { }
+local anonymous_whatsits = 0
+local anonymous_prefix = "anon"
+% \end{macrocode}
+%
+% User whatsit allocation is split into two functions:
+% \verb|new_user_whatsit_id| registers a new id (an integer)
+% and returns it. This is a wrapper around \verb|new_whatsit|
+% but with the extra \texttt{package} argument, and recording
+% the mapping in lua tables
+%
+% If no name given, generate a name from a counter.
+%
+% \begin{macrocode}
+local new_user_whatsit_id = function (name, package)
+ if name then
+ if not package then
+ package = unassociated
+ end
+ else % anonymous
+ anonymous_whatsits = anonymous_whatsits + 1
+ warning("defining anonymous user whatsit no. \@percentchar
+ d", anonymous_whatsits)
+ package = unassociated
+ name = anonymous_prefix .. tostring(anonymous_whatsits)
+ end
+
+ local whatsitdata = user_whatsits[package]
+ if not whatsitdata then
+ whatsitdata = { }
+ user_whatsits[package] = whatsitdata
+ end
+
+ local id = whatsitdata[name]
+ if id then %- warning
+ warning("replacing whatsit \@percentchar s:\@percentchar
+ s (\@percentchar d)", package, name, id)
+ else %- new id
+ id=luatexbase.new_whatsit(name)
+ whatsitdata[name] = id
+ whatsit_ids[id] = { name, package }
+ end
+ return id
+end
+luatexbase.new_user_whatsit_id = new_user_whatsit_id
+% \end{macrocode}
+%
+% \verb|new_user_whatsit| first registers a new id and then also
+% creates the corresponding whatsit node of subtype “user-definedâ€.
+% Return a nullary function that delivers copies of the whatsit.
+%
+% Alternatively, the first argument can be a whatsit node that
+% will then be used as prototype.
+%
+% \begin{macrocode}
+local new_user_whatsit = function (req, package)
+ local id, whatsit
+ if type(req) == "string" then
+ id = new_user_whatsit_id(req, package)
+ whatsit = newnode(whatsit_t, user_defined_t)
+ whatsit.user_id = id
+ elseif req.id == whatsit_t and req.subtype == user_defined_t then
+ id = req.user_id
+ whatsit = copynode(req)
+ if not whatsit_ids[id] then
+ warning("whatsit id \@percentchar d unregistered; "
+ .. "inconsistencies may arise", id)
+ end
+ end
+ return function () return copynode(whatsit) end, id
+end
+luatexbase.new_user_whatsit = new_user_whatsit
+% \end{macrocode}
+%
+% If one knows the name of a user whatsit, its corresponding id
+% can be retrieved by means of \verb|get_user_whatsit_id|.
+%
+% \begin{macrocode}
+local get_user_whatsit_id = function (name, package)
+ if not package then
+ package = unassociated
+ end
+ return user_whatsits[package][name]
+end
+luatexbase.get_user_whatsit_id = get_user_whatsit_id
+% \end{macrocode}
+%
+% The inverse lookup is also possible via \verb|get_user_whatsit_name|.
+% \begin{macrocode}
+local get_user_whatsit_name = function (asked)
+ local id
+ if type(asked) == "number" then
+ id = asked
+ elseif type(asked) == "function" then
+ %- node generator
+ local n = asked()
+ id = n.user_id
+ else %- node
+ id = asked.user_id
+ end
+ local metadata = whatsit_ids[id]
+ if not metadata then % unknown
+ warning("whatsit id \@percentchar d unregistered;
+ inconsistencies may arise", id)
+ return "", ""
+ end
+ return tableunpack(metadata)
+end
+luatexbase.get_user_whatsit_name = get_user_whatsit_name
+% \end{macrocode}
+% A function that outputs the
+% current allocation status to the terminal.
+%
+% \begin{macrocode}
+local dump_registered_whatsits = function (asked_package)
+ local whatsit_list = { }
+ if asked_package then
+ local whatsitdata = user_whatsits[asked_package]
+ if not whatsitdata then
+ error("(no user whatsits registered for package
+ \@percentchar s)", asked_package)
+ return
+ end
+ texiowrite_nl("(user whatsit allocation stats for " ..
+ asked_package)
+ for name, id in next, whatsitdata do
+ whatsit_list[\string#whatsit_list+1] =
+ stringformat("(\@percentchar s:\@percentchar
+ s \@percentchar d)", asked_package, name, id)
+ end
+ else
+ texiowrite_nl("(user whatsit allocation stats")
+ texiowrite_nl(stringformat(" ((total \@percentchar d)\string\n
+ (anonymous \@percentchar d))",
+ current_whatsit, anonymous_whatsits))
+ for package, whatsitdata in next, user_whatsits do
+ for name, id in next, whatsitdata do
+ whatsit_list[\string#whatsit_list+1] =
+ stringformat("(\@percentchar s:\@percentchar
+ s \@percentchar d)", package, name, id)
+ end
+ end
+ end
+ texiowrite_nl" ("
+ local first = true
+ for i=1, \string#whatsit_list do
+ if first then
+ first = false
+ else % indent
+ texiowrite_nl" "
+ end
+ texiowrite(whatsit_list[i])
+ end
+ texiowrite"))\string\n"
+end
+luatexbase.dump_registered_whatsits = dump_registered_whatsits
+% \end{macrocode}
+% Lastly, we define a couple synonyms for convenience.
+% \begin{macrocode}
+luatexbase.newattribute = new_attribute
+luatexbase.newuserwhatsit = new_user_whatsit
+luatexbase.newuserwhatsitid = new_user_whatsit_id
+luatexbase.getuserwhatsitid = get_user_whatsit_id
+luatexbase.getuserwhatsitname = get_user_whatsit_name
+luatexbase.dumpregisteredwhatsits = dump_registered_whatsits
+% \end{macrocode}
+%
+% \begin{macrocode}
+}
+%</whatsit>
+% \end{macrocode}
+%
+% Resolve name clashes and prefixed name issues.
+%
+% Top level \textsf{luatexbase} macros
+% \begin{macrocode}
+\let\newluatexattribute\newattribute
+\let\setluatexattribute\setattribute
+\let\unsetluatexattribute\unsetattribute
+\let\newluatexcatcodetable\newcatcodetable
+\let\setluatexcatcodetable\setcatcodetable
+% \end{macrocode}
+%
+% Internal \textsf{luatexbase} macros
+% \begin{macrocode}
+\let\luatexbase@directlua\directlua
+\let\luatexbase@ensure@primitive\@gobble
+% \end{macrocode}
+%
+% Lua\TeX\ primitives
+% \begin{macrocode}
+\let\luatexattribute\attribute
+\let\luatexattributedef\attributedef
+\let\luatexcatcodetable\catcodetable
+\let\luatexluaescapestring\luaescapestring
+\let\luatexlatelua\latelua
+\let\luatexoutputbox\outputbox
+\let\luatexscantextokens\scantextokens
+% \end{macrocode}
+%
+% Reset catcode of |@|.
+% \begin{macrocode}
+\catcode`\@=\emuatcatcode\relax
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</emu>
+% \end{macrocode}
+%
+% \subsection{Legacy \textsf{luatexbase} sub-packages}
+%
+% The original \textsf{luatexbase} was comprised of seven sub packages
+% that could in principle be loaded separately. Here we define them all
+% with the same code that just loads the main package, they are
+% distinguished just by the |\ProvidesPackage| specified above at the start
+% of the file.
+% \begin{macrocode}
+%<*emu-cmp,emu-mod,emu-loa,emu-reg,emu-att,emu-cct,emu-mcb>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ifx\RequirePackage\undefined
+ \input{luatexbase.sty}%
+\else
+ \RequirePackage{luatexbase}
+\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</emu-cmp,emu-mod,emu-loa,emu-reg,emu-att,emu-cct,emu-mcb>
+% \end{macrocode}
+%
+% \subsection{Legacy Lua code}
+%
+% \changes{v1.2}{2015/10/03}{Provide \texttt{luatexbase.loader.lua}}
+%
+% The original \textsf{luatexbase} included a file |luatexbase.loader.lua|
+% that could be loaded independently of the rest of the package. This really
+% doesn't need to do anything!
+% \begin{macrocode}
+%<*emu-lua>
+% \end{macrocode}
+%
+% \begin{macrocode}
+luatexbase = luatexbase or { }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</emu-lua>
+% \end{macrocode}
+%
+% \Finale
diff --git a/macros/luatex/generic/luatexbase/luatexbase.ins b/macros/luatex/generic/luatexbase/luatexbase.ins
new file mode 100644
index 0000000000..9730a75331
--- /dev/null
+++ b/macros/luatex/generic/luatexbase/luatexbase.ins
@@ -0,0 +1,19 @@
+\input docstrip
+\keepsilent
+\nopreamble
+\nopostamble
+
+\askforoverwritefalse
+
+\generate{\file{luatexbase.sty}{\from{luatexbase.dtx}{sty,emu,whatsit}}}
+\generate{\file{luatexbase-compat.sty}{\from{luatexbase.dtx}{sty,emu-cmp}}}
+\generate{\file{luatexbase-modutils.sty}{\from{luatexbase.dtx}{sty,emu-mod}}}
+\generate{\file{luatexbase-loader.sty}{\from{luatexbase.dtx}{sty,emu-loa}}}
+\generate{\file{luatexbase-regs.sty}{\from{luatexbase.dtx}{sty,emu-reg}}}
+\generate{\file{luatexbase-attr.sty}{\from{luatexbase.dtx}{sty,emu-att}}}
+\generate{\file{luatexbase-cctb.sty}{\from{luatexbase.dtx}{sty,emu-cct}}}
+\generate{\file{luatexbase-mcb.sty}{\from{luatexbase.dtx}{sty,emu-mcb}}}
+
+\generate{\file{luatexbase.loader.lua}{\from{luatexbase.dtx}{emu-lua}}}
+
+\endbatchfile
diff --git a/macros/luatex/generic/luatexbase/luatexbase.pdf b/macros/luatex/generic/luatexbase/luatexbase.pdf
new file mode 100644
index 0000000000..71626c1873
--- /dev/null
+++ b/macros/luatex/generic/luatexbase/luatexbase.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/COPYING b/macros/luatex/generic/luatexja/COPYING
new file mode 100644
index 0000000000..3049f8374b
--- /dev/null
+++ b/macros/luatex/generic/luatexja/COPYING
@@ -0,0 +1,23 @@
+Copyright (c) 2011--2016 The LuaTeX-ja project, All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the LuaTeX-ja project nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE LUATEX-JA PROJECT OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/macros/luatex/generic/luatexja/README b/macros/luatex/generic/luatexja/README
new file mode 100644
index 0000000000..ab88e3cb75
--- /dev/null
+++ b/macros/luatex/generic/luatexja/README
@@ -0,0 +1,90 @@
+The LuaTeX-ja Package 20190826.0
+--------------------------------
+Copyright (c) 2011--2019 The LuaTeX-ja project
+License: modified BSD (see COPYING)
+
+LuaTeX-ja is a macro package for typesetting Japanese documents with LuaTeX.
+This package is highly affected by ASCII pTeX engine, but not a porting of it.
+
+Note that this package is still *alpha-stage*; documentations are not complete
+and specifications are subject to change. Documentations are located at
+ doc/luatexja-en.pdf (en), doc/luatexja-ja.pdf (ja).
+
+LuaTeX-ja is developed on
+ <https://osdn.jp/projects/luatex-ja/wiki/FrontPage(en)>.
+If you have questions or recognize bugs/have feature requests,
+we would like you to create a thread in the forum or a ticket
+in the way which OSDN supplies, via links found in the page above.
+
+
+Installation
+------------
+
+0. Please make sure that your TeX distribution is up-to-date.
+ This version of LuaTeX-ja requires
+ - LuaTeX 1.0.0 or later
+ - luaotfload (v2.98 or later recommended)
+ - adobemapping (Adobe CMap files)
+ - everysel package
+ - etoolbox package
+ - ltxcmds package
+ - pdftexcmds package
+ - atbegshi package
+ - filehook package
+ - stfloats package
+ - IPAex fonts (http://ipafont.ipa.go.jp/)
+ Hence this version does not work in TeX Live 2016 (or earlier).
+
+1. If you are using TeX Live 2019 or later, you can install LuaTeX-ja via tlmgr.
+
+2. If you must/want to install manually:
+
+ a. Download the source archive from CTAN,
+ or tagged as 20190826.0 in the Git repository by
+ <http://git.osdn.jp/view?p=luatex-ja/luatexja.git
+ ;a=snapshot;h=refs/tags/20190826.0;sf=tgz>
+
+ b. Extract the archive and process following three files by LuaLaTeX
+ to generate classes for Japanese typesetting:
+ src/ltjclasses.ins
+ src/ltjltxdoc.ins
+ src/ltjsclasses.ins
+
+ c. Process src/ltj-kinsoku_make.tex by (plain) LuaTeX to generate ltj-kinsoku.lua,
+ which stores default "kinsoku" parameters.
+
+ d. Put src/ into your TEXMF tree.
+ An example location is TEXMF/tex/luatex/luatexja.
+
+ If you are updating from old version, you MUST remove it before
+ extracting the new version of LuaTeX-ja.
+
+ e. You may need to update the filename database, by mktexlsr (or by another program).
+
+
+Basic Usage
+-----------
+
+LuaTeX-ja supports both the plain format and LaTeX2e.
+Simply loading luatexja.sty by \input or \usepackage does the minimal setting.
+
+- If you want to create Japanese-based documents, you can consider the use of
+ ltj{article,book,report}.cls or ltjs{article,book,report}.cls.
+- If you want to use functionality of the fontspec package with Japanese fonts,
+ load luatexja-fontspec.sty. It defines control sequences such as \setmainjfont,
+ \setsansjfont and \jfontspec, which can be used for specifying Japanese fonts.
+
+Notes
+-----
+* This archive contains four .{dtx,ins} pairs:
+ src/ltjclasses.{ins,dtx}, src/ltjltxdoc.{ins,dtx}
+ src/ltjsclasses.{ins,dtx}, doc/luatexja.{ins,dtx}
+ Former three pairs generate class files (see above),
+ while the latter doc/luatexja.{ins,dtx} generates documentations.
+ (You will need Kozuka fonts to regenerate documentaion PDFs.)
+
+ No .{dtx,ins} pair generates .sty files of LuaTeX-ja package.
+
+* src/*.{ins.dtx} and src/ltj-kinsoku_make.tex are not needed in regular use.
+
+Last commit date: Mon Aug 26 09:29:22 2019 +0900
diff --git a/macros/luatex/generic/luatexja/doc/jfm-test.lua b/macros/luatex/generic/luatexja/doc/jfm-test.lua
new file mode 100644
index 0000000000..fdee46c356
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/jfm-test.lua
@@ -0,0 +1,110 @@
+luatexja.jfont.define_jfm {
+ dir = 'yoko',
+ zw = 1.0, zh = 1.0,
+ kanjiskip = { 0.1, 0.04, 0.05 },
+ xkanjiskip = { 0.31, 0.045, 0.057 },
+
+ [0] = {
+ chars = { '漢', 'ヒ*' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ },
+ [1] = {
+ chars = { 'ã‚' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = { [3] = { 1.41, 0, 0}, [399] = {1.25, 0.43, 0.87} },
+ kern = { [8] = -1.41 , [2] = 2.0, [99] = 1.21 }
+ },
+ [11] = {
+ chars = { 'ã„' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = { [3] = { 1.41, 0, 0} },
+ kern = { [2] = 2.0, }
+ },
+ [21] = {
+ chars = { 'ã†' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = { [3] = { 1.41, 0, 0}, [99] ={ 1.73, 0, 0} },
+ kern = { [8] = -1.41 , [2] = 2.0, }
+ },
+ [31] = {
+ chars = { 'ãˆ' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = { [3] = { 1.41, 0, 0} },
+ kern = { [2] = 2.0, [99] = 1.73}
+ },
+ [41] = {
+ chars = { 'ãŠ' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ kern = { [8] = -1.41 , [2] = 2.0}
+ },
+ [51] = {
+ chars = { 'ã‹' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ kern = { [199] = 0.85 },
+ },
+
+ [2] = {
+ chars = { 'ã‚¢' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0
+ },
+ [3] = {
+ chars = { 'ウ' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0
+ },
+ [4] = {
+ chars = { 'エ' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = { [199] = { 0.78, 0, 0} },
+ },
+ [2000] = {
+ chars = { '。', 'ã€*', 'ヒ' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ },
+ [100] = {
+ chars = { '「' },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ },
+ [101] = {
+ chars = { 'ã€' },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ },
+ [102] = {
+ chars = { '〔' },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ },
+ [99] = {
+ chars = { 'jcharbdd' },
+ glue = { [11] = { 1.41, 0, 0} },
+ kern = { [21] = 2.0, }
+ },
+ [199] = {
+ chars = { 'boxbdd' },
+ glue = { [51] = { 1.03, 0, 0} , [1] = { 0.94, 0.23, 0.45 }},
+ },
+ [299] = {
+ chars = { 'parbdd' },
+ glue = { [51] = { 0.68, 0.02, 0.04} },
+ kern = { [100] = -0.5, [102] = 0.5 }
+ },
+ [399] = {
+ chars = { -1 }, -- math
+ glue = { [0] = { 0.68, 0.02, 0.04} },
+ },
+ [8] = {
+ chars = { 'lineend' },
+ }
+}
diff --git a/macros/luatex/generic/luatexja/doc/jfm-ujisc33.lua b/macros/luatex/generic/luatexja/doc/jfm-ujisc33.lua
new file mode 100644
index 0000000000..7879f58c3b
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/jfm-ujisc33.lua
@@ -0,0 +1,135 @@
+luatexja.jfont.define_jfm {
+ dir = 'yoko',
+ zw = 1.0, zh = 1.0,
+
+ [0] = {
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0*0.67, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5*0.67 , 0.0, 0.5 },
+ [3] = { 0.25*0.67, 0.0, 0.25 }
+ }
+ },
+
+ [1] = { -- é–‹ã括弧類
+ chars = {
+ '‘', '“', '〈', '《', '「', '『', 'ã€', '〔', '〖',
+ '〘', 'ã€', '(', 'ï¼»', 'ï½›', '⦅'
+ },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.5*0.67, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [3] = { 0.25*0.67, 0.0, 0.25 }
+ }
+ },
+
+ [2] = { -- é–‰ã˜æ‹¬å¼§é¡ž
+ chars = {
+ '’', 'â€', 'ã€', '〉', '》', 'ã€', 'ã€', '】', '〕',
+ '〗', '〙', '〟', ')', ',', 'ï¼½', 'ï½', 'ï½ '
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5*0.67, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.5*0.67 , 0.0, 0.5 },
+ [1] = { 0.5*0.67 , 0.0, 0.5 },
+ [3] = { 0.25*0.67, 0.0, 0.25 },
+ [5] = { 0.5*0.67 , 0.0, 0.5 },
+ [6] = { 0.5*0.67 , 0.0, 0.5 },
+ [7] = { 0.5*0.67 , 0.0, 0.5 }
+ }
+ },
+
+ [3] = { -- 中点類
+ chars = {'・', ':', ';'},
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.5*0.67, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.25*0.67, 0.0, 0.25 },
+ [1] = { 0.25*0.67, 0.0, 0.25 },
+ [2] = { 0.25*0.67, 0.0, 0.25 },
+ [3] = { 0.5*0.67 , 0.0, 0.5 },
+ [4] = { 0.25*0.67, 0.0, 0.25 },
+ [5] = { 0.25*0.67, 0.0, 0.25 },
+ [6] = { 0.25*0.67, 0.0, 0.25 },
+ [7] = { 0.25*0.67, 0.0, 0.25 }
+ }
+ },
+
+ [4] = { -- å¥ç‚¹é¡ž
+ chars = {'。', '.'},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5*0.67, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.5*0.67 , 0.0, 0.0 },
+ [1] = { 0.5*0.67 , 0.0, 0.0 },
+ [3] = { 0.75*0.67, 0.0, 0.25 },
+ [5] = { 0.5*0.67 , 0.0, 0.0 },
+ [6] = { 0.5*0.67 , 0.0, 0.0 },
+ [7] = { 0.5*0.67 , 0.0, 0.0 }
+ }
+ },
+
+ [5] = { -- ダッシュ
+ chars = { '―', '‥', '…' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0*0.67, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5*0.67 , 0.0, 0.5 },
+ [3] = { 0.25*0.67, 0.0, 0.25 }
+ },
+ kern = {
+ [5] = 0.0
+ }
+ },
+
+ [6] = { -- 感嘆符・疑å•ç¬¦
+ chars = { '?', 'ï¼' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.5*0.67 , 0.0, 0.5 },
+ [1] = { 0.5*0.67 , 0.0, 0.5 },
+ [3] = { 0.25*0.67, 0.0, 0.25 },
+ [7] = { 0.5*0.67 , 0.0, 0.5 },
+ },
+ kern = {
+ [5] = 0.0
+ }
+ },
+
+ [7] = { -- åŠè§’カナ
+ chars = {
+ '。', '「', '」', '、', '・', 'ヲ', 'ァ', 'ィ', 'ゥ',
+ 'ェ', 'ォ', 'ャ', 'ュ', 'ョ', 'ッ', 'ー', 'ア', 'イ',
+ 'ウ', 'エ', 'オ', 'カ', 'キ', 'ク', 'ケ', 'コ', 'サ',
+ 'ï½¼', 'ï½½', 'ï½¾', 'ソ', 'ï¾€', 'ï¾', 'ツ', 'テ', 'ト',
+ 'ï¾…', 'ニ', 'ヌ', 'ネ', 'ノ', 'ハ', 'ヒ', 'フ', 'ï¾',
+ 'ホ', 'ï¾', 'ï¾', 'ム', 'ï¾’', 'モ', 'ï¾”', 'ユ', 'ï¾–',
+ 'ï¾—', 'リ', 'ï¾™', 'レ', 'ï¾›', 'ワ', 'ï¾', '゙', '゚',
+ "AJ1-516", "AJ1-517", "AJ1-518", "AJ1-519", "AJ1-520", "AJ1-521", "AJ1-522",
+ "AJ1-523", "AJ1-524", "AJ1-525", "AJ1-526", "AJ1-527", "AJ1-528", "AJ1-529",
+ "AJ1-530", "AJ1-531", "AJ1-532", "AJ1-533", "AJ1-534", "AJ1-535", "AJ1-536",
+ "AJ1-537", "AJ1-538", "AJ1-539", "AJ1-540", "AJ1-541", "AJ1-542", "AJ1-543",
+ "AJ1-544", "AJ1-545", "AJ1-546", "AJ1-547", "AJ1-548", "AJ1-549", "AJ1-550",
+ "AJ1-551", "AJ1-552", "AJ1-553", "AJ1-554", "AJ1-555", "AJ1-556", "AJ1-557",
+ "AJ1-558", "AJ1-559", "AJ1-560", "AJ1-561", "AJ1-562", "AJ1-563", "AJ1-564",
+ "AJ1-565", "AJ1-566", "AJ1-567", "AJ1-568", "AJ1-569", "AJ1-570", "AJ1-571",
+ "AJ1-572", "AJ1-573", "AJ1-574", "AJ1-575", "AJ1-576", "AJ1-577", "AJ1-578",
+ "AJ1-579", "AJ1-580", "AJ1-581", "AJ1-582", "AJ1-583", "AJ1-584", "AJ1-585",
+ "AJ1-586", "AJ1-587", "AJ1-588", "AJ1-589", "AJ1-590", "AJ1-591", "AJ1-592",
+ "AJ1-593", "AJ1-594", "AJ1-595", "AJ1-596", "AJ1-597", "AJ1-598",
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5*0.67, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5*0.67 , 0.0, 0.5 },
+ [3] = { 0.25*0.67, 0.0, 0.25 }
+ }
+ },
+
+ [99] = { -- box末尾
+ chars = {'boxbdd', 'parbdd'},
+ },
+
+} \ No newline at end of file
diff --git a/macros/luatex/generic/luatexja/doc/lltjp-geometry.pdf b/macros/luatex/generic/luatexja/doc/lltjp-geometry.pdf
new file mode 100644
index 0000000000..2f0d74960c
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/lltjp-geometry.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/lltjp-geometry.tex b/macros/luatex/generic/luatexja/doc/lltjp-geometry.tex
new file mode 100644
index 0000000000..2006e4994e
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/lltjp-geometry.tex
@@ -0,0 +1,288 @@
+%#! luajitlatex
+\documentclass[a4paper,10pt]{ltjsarticle}
+\usepackage[textwidth=45\zw, lines=45, footskip=2\zh, verbose]{geometry}
+\usepackage{listings,amsmath,booktabs,lltjext}
+\usepackage[match]{luatexja-fontspec}
+\usepackage{unicode-math}
+\setmathfont{XITS Math}
+\setmainfont{TeX Gyre Termes}
+\setsansfont[Scale=0.95]{TeX Gyre Heros}
+\usepackage[kozuka-pr6n]{luatexja-preset}\normalsize
+\def\emph#1{\textbf{\textgt{\mathversion{bold}#1}}}
+\def\headfont{\normalfont\bfseries\gtfamily}
+\def\pTeX{p\kern-.05em\TeX}
+\def\cs#1{\text{\texttt{\char`\\#1}}}
+\protected\def\Pkg#1{\textsf{#1}}
+\protected\def\>{\hskip\ltjgetparameter{xkanjiskip}}
+\lstset{
+ basicstyle=\ttfamily, basewidth=0.5em,
+}
+\makeatletter\let\SX@Info=\relax\makeatother
+\fboxsep=0mm
+
+\usepackage{hyperref,bookmark,xcolor}
+\hypersetup{%
+ unicode,
+ colorlinks,
+ allbordercolors=1 1 1,
+ allcolors=blue,
+ pdftitle={lltjp-geometryパッケージ}
+}
+
+\def\LuaTeX{Lua\TeX}
+\definecolor{blue}{rgb}{0, 0.25, 1}
+
+\title{\Pkg{lltjp-geometry}パッケージ}
+\author{\LuaTeX-jaプロジェクト\null%
+ \thanks{\url{http://osdn.jp/projects/luatex-ja/wiki/FrontPage}}}
+\begin{document}
+\maketitle
+
+ページレイアウトã®è¨­å®šã¨ã—ã¦ï¼Œ\href{http://www.ctan.org/pkg/geometry}%
+{\Pkg{geometry}パッケージ}ãŒæœ‰åã§ã‚ã‚‹ãŒï¼Œ
+ã“ã‚Œã¯p\LaTeX・\LuaTeX-jaã®ç¸¦çµ„クラスã§ã¯åˆ©ç”¨ãŒä¸å¯èƒ½ã¨ã„ã†å•é¡ŒãŒã‚ã£ãŸï¼Ž
+本文書ã§è§£èª¬ã™ã‚‹\Pkg{lltjp-geometry}パッケージã¯ï¼Œ\Pkg{geometry}パッケージを
+縦組クラスã«å¯¾å¿œã•ã›ã‚‹ãƒ‘ッãƒã§ã‚る.
+
+
+\section{利用方法}
+\Pkg{lltjp-geometry}パッケージã¯ï¼Œ\LuaTeX-jaã«æ¨™æº–ã§å«ã¾ã‚Œã¦ã„る.
+本パッケージã®å‹•ä½œã«ã¯\href{http://www.ctan.org/pkg/ifluatex}{\Pkg{ifluatex}},
+\href{http://www.ctan.org/pkg/filehook}{\Pkg{filehook}}パッケージãŒå¿…è¦ã§ã‚る.
+
+\LuaTeX-jaã§ã¯ï¼Œ\Pkg{geometry}パッケージ読ã¿è¾¼ã¿æ™‚ã«
+自動的ã«\Pkg{lltjp-geometry}パッケージãŒèª­ã¿è¾¼ã¾ã‚Œã‚‹ï¼Ž
+縦組クラスã‹å¦ã‹ã®è‡ªå‹•åˆ¤å®šï¼ˆ\ref{ssec:auto}節)を上書ãã—ãŸã„å ´åˆã¯ï¼Œ
+\begin{lstlisting}
+% \PassOptionsToPackage{force}{lltjp-geometry} % 強制的ã«æœ‰åŠ¹
+\PassOptionsToPackage{disable}{lltjp-geometry} % 強制的ã«ç„¡åŠ¹
+\documentclass{...}
+\usepackage[...]{geometry}
+\end{lstlisting}
+ã®ã‚ˆã†ã«\emph{\Pkg{luatexja}ã®èª­ã¿è¾¼ã¿å‰}ã«\cs{PassOptionsToPackage}ã§
+本パッケージã«æ¸¡ã™ã‚ªãƒ—ションを指定ã™ã‚‹ï¼ˆ\cs{usepackage\{lltjp-geometry\}}\>ã¯ä½¿ãˆãªã„).
+
+\pTeX 系列ã§ã¯ï¼Œ\Pkg{tarticle}, \Pkg{tbook}, \Pkg{treport}ã¨ã„ã£ãŸ
+\emph{縦組クラスを使ã†å ´åˆ}ã«ï¼Œ
+\begin{lstlisting}
+\usepackage[...]{lltjp-geometry}
+\usepackage[...]{geometry}
+\end{lstlisting}
+ã¨ï¼Œ\Pkg{geometry}パッケージã®å‰ã«èª­ã¿è¾¼ã‚€ï¼Ž
+
+\subsection{縦組クラスã‹å¦ã‹ã®åˆ¤å®š}
+\label{ssec:auto}
+本パッケージã¯ï¼Œä»¥ä¸‹ã®ã„ãšã‚Œã‹ãŒè©²å½“ã™ã‚‹å ´åˆã«ã€Œç¾åœ¨ã®ã‚¯ãƒ©ã‚¹ã¯ç¸¦çµ„クラスã€ã¨è‡ªå‹•åˆ¤å®šã—,
+\Pkg{geometry}パッケージ読ã¿è¾¼ã¿ç›´å¾Œã«ãƒ‘ッãƒã‚’当ã¦ã‚‹ï¼š
+\begin{enumerate}
+ \item \Pkg{geometry}パッケージを読ã¿è¾¼ã‚€éš›ã«ï¼Œç¾åœ¨ã®çµ„æ–¹å‘ãŒç¸¦çµ„ã«ãªã£ã¦ã„る.
+ \item \cs{AtBeginDocument}ã«ã‚ˆã‚ŠæŒ‡å®šã•ã‚Œã‚‹ï¼Œ\cs{begin\{document\}}\>時ã«å®Ÿè¡Œã•ã‚Œã‚‹å†…容ã«
+ \cs{tate}(ã¨ã„ã†ãƒˆãƒ¼ã‚¯ãƒ³ï¼‰ãŒå«ã¾ã‚Œã¦ã„る.
+ \item 本パッケージを読ã¿è¾¼ã‚€éš›ã«\texttt{force}オプションãŒæŒ‡å®šã•ã‚Œã¦ã„る.
+\end{enumerate}
+\LuaTeX-jaã§ç¸¦çµ„クラスを利用ã™ã‚‹å ´åˆã¯ä¸»ã«1.ã®ï¼Œ
+\pTeX 系列ã§ç¸¦çµ„クラスを利用ã™ã‚‹å ´åˆã¯ä¸»ã«2.ã®çŠ¶æ³ã¨ãªã‚‹
+\footnote{%
+ 標準縦組クラスã§ã¯ï¼Œ\cs{begin\{document\}}\>ã®å†…部ã§çµ„æ–¹å‘を縦組ã«å¤‰æ›´ã™ã‚‹ï¼Ž
+}.
+
+上記ã®è‡ªå‹•åˆ¤å®šãŒã†ã¾ãè¡Œã‹ãªã‹ã£ãŸã¨ãã«å‚™ãˆï¼Œ
+本パッケージã«ã¯\texttt{force}オプションã¨\texttt{disable}オプションを用æ„ã—ãŸï¼Ž
+\begin{itemize}
+ \item \texttt{force}オプションãŒæŒ‡å®šã•ã‚Œã¦ã„ã‚‹å ´åˆã¯ï¼Œè‡ªå‹•åˆ¤å®šã®çµæžœã«é–¢ã‚らãš
+ \Pkg{geometry}パッケージ読ã¿è¾¼ã¿ç›´å¾Œã«ãƒ‘ッãƒã‚’当ã¦ã‚‹ï¼Ž
+ \item \texttt{disable}オプションãŒæŒ‡å®šã•ã‚Œã¦ã„ã‚‹å ´åˆã¯ï¼Œè‡ªå‹•åˆ¤å®šã®çµæžœã«é–¢ã‚らãš
+ 何もã—ãªã„.
+\end{itemize}
+
+\section{\Pkg{lltjp-geometry}使用時ã®æ³¨æ„事項}
+
+\subsection{\texttt{twoside}指定時}
+縦組ã®æœ¬ã¯é€šå¸¸å³ç¶´ã˜ã§ã‚る.ã“れをå映ã—,
+\texttt{twoside}オプション指定時ã«ã¯
+\begin{itemize}
+\item \texttt{left}, \texttt{lmargin}ã¯å°å£å´ã®ä½™ç™½ï¼Œ
+\texttt{right}, \texttt{rmargin}ã¯ãƒŽãƒ‰å´ã®ä½™ç™½ã‚’指ã™ï¼Ž
+\item å·¦å³ä½™ç™½æ¯” \texttt{hmarginratio}ã®æ¨™æº–値ã¯$3:2$ã«å¤‰æ›´ï¼Ž
+\item \texttt{bindingoffset}ã¯\emph{å³å´}ã«ä½™ç™½ã‚’確ä¿ã™ã‚‹ï¼Ž
+\end{itemize}
+ã¨å¤‰æ›´ã—ã¦ã„る.
+
+\subsection{widthã¨height}
+\cs{textwidth}ãŒå­—é€ã‚Šæ–¹å‘ã®é•·ã•ï¼ˆç¸¦ï¼‰ã‚’表ã™ã®ã¨åŒæ§˜ã«ï¼Œ
+\texttt{width}, \texttt{totalwidth}, \texttt{textwidth}キーã®å€¤ã‚‚å­—é€ã‚Šæ–¹å‘を,ã¾ãŸ
+\texttt{height}, \texttt{totalheight}, \texttt{textheight}キーã®å€¤ã‚‚è¡Œé€ã‚Šæ–¹å‘(横)を表ã™ã‚ˆã†ã«ãªã£ã¦ã„る.
+
+ã—ã‹ã—,\emph{用紙サイズã«ã¤ã„ã¦ã¯ä¾‹å¤–}ã§ã‚り,物ç†çš„ãªæ„味ã§ã®å¹…・高ã•ã‚’表ã™ï¼Ž
+\texttt{paperwidth}, \texttt{layoutwidth}ã¯ãã‚Œãžã‚Œç´™ã®æ¨ªå¹…,レイアウトã®æ¨ªå¹…を,
+\texttt{paperheight}, \texttt{layoutheight}ã¯ãã‚Œãžã‚Œç´™ã®é«˜ã•ï¼Œãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã®é«˜ã•ã‚’表ã—ã¦ã„る.
+
+
+
+\subsection{å‚注}
+縦組ã®å ´åˆï¼Œå‚注ã¯æœ¬æ–‡ã®ä¸Šä¸‹ã«é…ç½®ã•ã‚Œã‚‹\footnote{%
+ 二段組ã®å ´åˆã¯ä¸Šä¸‹å…±ã«ï¼Œä¸€æ®µçµ„ã®å ´åˆã¯æ¨™æº–ã§ã¯ä¸‹å´ã ãŒï¼Œ
+ \texttt{reversemp}ãŒæŒ‡å®šã•ã‚ŒãŸã¨ãã«ã¯ä¸Šå´ã«é…ç½®ã•ã‚Œã‚‹ï¼Ž
+}.ã“ã‚Œã«ã‚ˆã‚Šï¼Œ\emph{\texttt{includemp}(や \texttt{includeall})ãŒ
+未指定ã®å ´åˆï¼Œå‚注ã¯ãƒ˜ãƒƒãƒ€ã‚„フッタã«é‡ãªã‚‹}.
+\texttt{includemp}指定時ã¯ï¼Œ\cs{footskip}, \cs{headsep}ã®ã„ãšã‚Œã‹
+(二段組ã®å ´åˆã¯ä¸¡æ–¹ï¼‰ã‚’$\cs{marginparwidth} + \cs{marginparsep}$ã ã‘
+増加ã•ã›ã‚‹ï¼Ž
+
+\section{\texttt{lines}オプションã«é–¢ã™ã‚‹æ³¨æ„事項}
+本節ã®å†…容ã¯ï¼Œ\Pkg{lltjp-geometry}パッケージを読ã¿è¾¼ã¾ãªã„å ´åˆï¼Œ
+ã¤ã¾ã‚Šï¼Œæ¨ªçµ„クラスã§\Pkg{geometry}パッケージを普通ã«ä½¿ç”¨ã—ãŸå ´åˆã«ã‚‚
+当ã¦ã¯ã¾ã‚‹æ³¨æ„事項ã§ã‚る.
+
+\subsection{\Pkg{fontspec}パッケージã¨ã®å¹²æ¸‰}
+\Pkg{fontspec}パッケージã®ï¼Œèª­ã¿è¾¼ã¿ç›´å¾Œã«
+\Pkg{geometry}パッケージを用ã„ã¦ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã‚’設定ã™ã‚‹ã¨ï¼Œ
+\texttt{lines}ã«ã‚ˆã‚‹æŒ‡å®šãŒæ­£ã—ãåƒã‹ãªã„ã¨ã„ã†ç—‡çŠ¶ãŒç”Ÿã˜ã‚‹ï¼š
+\begin{lstlisting}
+\documentclass{article}
+\usepackage{geometry}
+\usepackage{fontspec}
+\geometry{lines=20}
+\begin{document}
+hoge\typeout{\the\topskip, \the\baselineskip, \the\textheight}
+\end{document}
+\end{lstlisting}
+\cs{typeout}ã§\cs{topskip}, \cs{baselineskip}, \cs{textheight}ã®å€¤ã‚’調ã¹ã‚‹ã¨
+\[
+ \frac{\cs{textheight} - \cs{topskip}}{\cs{baselineskip}} = 15.8\dot 3
+\]
+ã¨ãªã‚‹ã“ã¨ãŒã‚ã‹ã‚‹ã‹ã‚‰ï¼Œ1ページã«ã¯16行分入らãªã„ã“ã¨ãŒã‚ã‹ã‚‹ï¼Ž
+
+ã“ã‚Œã¯ï¼Œ\Pkg{fontspec}ã®èª­ã¿è¾¼ã¿ã«ã‚ˆã£ã¦\cs{baselineskip}ãŒãªãœã‹
+10\,ptã«å¤‰ãˆã‚‰ã‚Œã¦ã—ã¾ã„,\cs{geometry}命令ã¯ãã®å€¤ã«å¾“ã£ã¦æœ¬æ–‡é ˜åŸŸã®é«˜ã•ã‚’計算ã™ã‚‹ãŸã‚ã§
+ã‚る.ã¨ã‚Šã‚ãˆãšã®å¯¾ç­–ã¯ï¼Œ
+\cs{normalsize}ã«ã‚ˆã£ã¦\cs{baselineskip}ã‚’æ­£ã—ã„値ã«å†è¨­å®šã—,ãã®å¾Œ
+レイアウトを設定ã™ã‚Œã°è‰¯ã„:
+\begin{lstlisting}
+\usepackage{geometry}
+\usepackage{fontspec}
+\normalsize\geometry{lines=20}
+\end{lstlisting}
+
+
+\subsection{\cs{maxdepth}ã®èª¿æ•´}
+\LaTeX ã§ã¯ï¼Œ
+最後ã®è¡Œã®æ·±ã•\rensuji{$d$}ã¨
+本文領域ã®ä¸Šç«¯ã‹ã‚‰æœ€å¾Œã®è¡Œã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¾ã§ã®è·é›¢\rensuji{$f$}ã«å¯¾ã—,
+\[
+ \cs{textheight}= f+\max(0, d-\cs{maxdepth})
+\]
+ãŒæˆã‚Šç«‹ã¤ï¼Ž
+
+\pTeX 系列ã®æ¨™æº–縦組クラス\Pkg{[u]tarticle}等,
+åŠã³ãれを\LuaTeX-ja用ã«ç§»æ¤ã—ãŸ\Pkg{ltjtarticle}ç­‰ã§ã¯ï¼Œ
+ \cs{topskip}ã¯\emph{横組時ã«ãŠã‘ã‚‹}全角空白ã®é«˜ã•7.77588\,pt\footnote{%
+ 標準ã®\texttt{10pt}オプション指定時.以下åŒã˜ï¼Ž
+ ã¨ã“ã‚ã§ï¼Œã“ã®é‡ã¯å…¬ç§°ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã®10\,ptã‹ï¼Œã‚‚ã—ãã¯
+ 全角空白ã®é«˜ã•ã¨æ·±ã•ã‚’åˆã‚ã›ãŸå€¤ã®9.16446\,ptã®é–“é•ã„ã§ã¯ãªã„ã‹ï¼Œã¨ç­†è€…ã¯è€ƒãˆã¦ã„る.
+ ãªãŠï¼Œå¥¥æ‘晴彦æ°ã®\href{https://oku.edu.mie-u.ac.jp/~okumura/jsclasses/}%
+ {p\LaTeXe 新ドキュメントクラス}ã§ã¯å…¬ç§°ãƒã‚¤ãƒ³ãƒˆã‚µã‚¤ã‚º10\,ptã«è¨­å®šã•ã‚Œã¦ã„る.
+}ã§ã‚り,\cs{maxdepth}ã¯ãã®åŠåˆ†ã®å€¤ï¼ˆå¾“ã£ã¦3.88794\,pt)ã§ã‚る.
+
+ã„ãã¤ã‹ã®ãƒ•ã‚©ãƒ³ãƒˆã«ã¤ã„ã¦ï¼Œãã®ä¸­ã®æ–‡å­—ã®æ·±ã•ã®æœ€å¤§å€¤ã‚’見ã¦ã¿ã‚‹ã¨
+表\ref{tab:baseline}ã®ã‚ˆã†ã«ãªã£ã¦ã„る.
+\begin{table}[tb]
+ \layoutfloat[c]{%
+ \begin{tabular}<y>{ll}
+ \toprule
+ \bfseries フォント(10\,pt)&\bfseries æ·±ã•ï¼ˆptå˜ä½ï¼‰\\
+ \midrule
+ 横組用ã®æ¨™æº–和文フォント(\pTeX)&1.38855\\
+ 縦組用ã®æ¨™æº–和文フォント(\pTeX)&4.58221\\
+ \midrule
+ Computer Modern Roman 10\,pt&2.5\\
+ Computer Modern Sans Serif 10\,pt&2.5\\
+ Times Roman (\texttt{ptmr8t})&2.16492\\
+ Helvetica Bold Oblique (\texttt{phvbo8t})&2.22491\\
+ Palatino (\texttt{pplr8t})&2.75989\\
+ \bottomrule
+ \end{tabular}}
+ \pcaption{ã„ãã¤ã‹ã®ãƒ•ã‚©ãƒ³ãƒˆä¸­ã®ï¼Œæ–‡å­—ã®æ·±ã•ã®æœ€å¤§å€¤
+ \label{tab:baseline}}
+\end{table}
+欧文フォントã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¯ï¼Œãã®ã¾ã¾ã§ã¯å’Œæ–‡ã¨ã®çµ„ã¿åˆã‚ã›ãŒæ‚ªã„ã®ã§ï¼Œ
+ã•ã‚‰ã«$\Pkg{tbaselineshift}=3.41666\,\textrm{pt}$ã ã‘下ãŒã‚‹ã“ã¨ã‚’考ãˆã‚‹ã¨ï¼Œ
+最後ã®è¡Œã«å’Œæ–‡æ–‡å­—ãŒæ¥ãŸå ´åˆã¯ã»ã¼ç¢ºå®Ÿã«æ·±ã•ãŒ\cs{maxdepth}を超ãˆã¦ã—ã¾ã†ã“ã¨ã«ãªã‚‹ï¼Ž
+従ã£ã¦ï¼Œæœ¬æ–‡é ˜åŸŸã‚’「\rensuji{$n$}行分ã€ã¨ã—ã¦æŒ‡å®šã™ã‚‹ã¨ãã«ã‚ˆã使ã‚れる
+\begin{equation}
+ \cs{textheight} = \cs{topskip} + (n-1)\cs{baselineskip}
+ \label{eq:nline}
+\end{equation}
+ã¯\Pkg{tarticle}クラスã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯é€šç”¨ã—ãªã„.
+
+通常ã®åœ°ã®æ–‡ã®ã¿ã®æ–‡ç« ã«ãŠã„ã¦ã»ã¼ç¢ºå®Ÿã«\eqref{eq:nline}ãŒæˆã‚Šç«‹ã¤ã‚ˆã†ã«ã™ã‚‹ãŸã‚,
+\Pkg{lltjp-geometry}ã§ã¯\emph{\texttt{lines}オプション指定時ã®ã¿}\cs{maxdepth}ã®å€¤ãŒ
+最低ã§ã‚‚
+\begin{quote}
+公称ãƒã‚¤ãƒ³ãƒˆã‚µã‚¤ã‚ºã®åŠåˆ†ã«ï¼Œæ¬§æ–‡ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã®ã‚·ãƒ•ãƒˆé‡ã‚’加ãˆãŸå€¤%
+\footnote{\Pkg{tarticle}ã®å ´åˆã ã¨ï¼Œ
+$5\,\textrm{pt} + 3.41666\,\textrm{pt}=8.41666\,\textrm{pt}$ã§ã‚る.}
+\end{quote}
+ã«ãªã‚‹ã‚ˆã†ã«ã—ã¦ã„る.\texttt{lines}オプションéžæŒ‡å®šæ™‚ã«ã¯ã“ã®ã‚ˆã†ãªèª¿æ•´ã¯
+è¡Œã‚ã‚Œãªã„.
+
+
+\subsection{見ã‹ã‘上ã®åŸºæœ¬ç‰ˆé¢ã®ä½ç½®}
+\LaTeX ã§ã¯ï¼Œ
+本文ã®ä¸€è¡Œç›®ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¯ï¼Œæœ¬æ–‡é ˜åŸŸã®ã€Œä¸Šç«¯ã€ã‹ã‚‰
+ \cs{topskip}\ ã ã‘「下ãŒã£ãŸã€ã¨ã“ã‚ã«æ¥ã‚‹ã“ã¨ã«ãªã£ã¦ã„る.
+ã‚ã¾ã‚Š\cs{topskip}ãŒå°ã•ã„ã¨ï¼Œãƒ¦ãƒ¼ã‚¶ãŒå¤§ãã„文字サイズを指定ã—ãŸæ™‚ã«1行目ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³
+ä½ç½®ãŒç‹‚ã†å±é™ºãŒã‚ã‚‹ãŸã‚,
+\Pkg{geometry}パッケージã§ã¯
+\begin{quote}
+ \texttt{lines}オプション指定時,\cs{topskip}ã®å€¤ã‚’最低ã§ã‚‚
+ \cs{strutbox}ã®é«˜ã•($0.7\cs{baselineskip}$)ã¾ã§å¼•ã上ã’ã‚‹
+\end{quote}
+ã¨ã„ã†ä»•æ§˜ã«ãªã£ã¦ã„る.
+
+縦組ã®å ´åˆã¯ï¼Œ\cs{strutbox}ã«å¯¾å¿œã™ã‚‹ãƒœãƒƒã‚¯ã‚¹ã¯\cs{tstrutbox}ã§ã‚ã‚‹ãŸã‚,
+\Pkg{lltjp-geometry}ã§ã¯
+\begin{quote}
+ \texttt{lines}オプション指定時,\cs{topskip}ã®å€¤ã‚’最低ã§ã‚‚
+ \emph{\cs{tstrutbox}ã®é«˜ã•($\cs{baselineskip}/2$)}ã¾ã§å¼•ã上ã’ã‚‹
+\end{quote}
+ã¨ã„ã†æŒ™å‹•ã«ã—ãŸï¼Žè¦‹ã‹ã‘上ã¯\cs{topskip}ã®å€¤åˆ¶é™ãŒç·©ããªã£ãŸãŒï¼Œå‰ç¯€ã§è¿°ã¹ãŸã‚ˆã†ã«
+欧文フォントã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¯å’Œæ–‡ã«åˆã†ã‚ˆã†ã«ä¸‹ã«ãšã‚‰ã•ã‚Œã‚‹ã®ã§ï¼Œ
+実用上ã¯å•é¡Œã¯èµ·ããªã„ã ã‚ã†ï¼Ž
+
+å‰ç¯€ã®\cs{maxdepth}ã®èª¿æ•´ã‚‚考ãˆåˆã‚ã›ã‚‹ã¨ï¼Œ\emph{\LaTeX ãŒèªè­˜ã™ã‚‹æœ¬æ–‡é ˜åŸŸã¨ï¼Œ
+実際ã®è¦‹ãŸç›®ã®åŸºæœ¬ç‰ˆé¢ã®ä½ç½®ã¨ã¯ç•°ãªã‚‹}ã“ã¨ã«æ³¨æ„ã—ã¦ã»ã—ã„.
+
+\medskip
+例ãˆã°A4縦を縦組ã§ï¼Œå…¬ç§°ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚º10\,pt,行é€ã‚Š18\,pt,30行左å³ä¸­å¤®
+ã¨ã„ã†ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã«ã™ã‚‹ãŸã‚,
+\begin{lstlisting}
+\documentclass{tarticle}
+\usepackage{lltjp-geometry}
+\baselineskip=18pt
+\usepackage[a4paper,hcentering,lines=30]{geometry}
+\end{lstlisting}
+ã¨æŒ‡å®šã™ã‚‹ã¨ï¼Œå®Ÿéš›ã«ã¯ä»¥ä¸‹ã®ã‚ˆã†ã«è¨­å®šã•ã‚Œã‚‹ï¼Ž
+\begin{itemize}
+ \item\cs{topskip}ã¯\cs{tstrutbox}ã®é«˜ã•8.5\,ptã«è¨­å®šã•ã‚Œã‚‹ï¼Ž
+ \item 本文領域ã®ã€Œé«˜ã•ã€\cs{textheight}ã¯
+\[
+ \cs{topskip}+ (30-1)\cs{baselineskip}= 530.5\,\textrm{pt}.
+\]
+ \item 従ã£ã¦ï¼Œå·¦ä½™ç™½ã¨å³ä½™ç™½ã¯
+\[
+ \frac{210\,\textrm{mm}-\cs{textheight}}2 = 33.50394\,\textrm{pt}.
+\]
+\end{itemize}
+ã—ã‹ã—,実際ã«ã¯ãƒšãƒ¼ã‚¸ã®æœ€åˆã®è¡Œã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¯ï¼Œæœ¬æ–‡é ˜åŸŸã®å³ç«¯ã‹ã‚‰
+\cs{topskip}ã ã‘å·¦ã«ãšã‚ŒãŸã¨ã“ã‚ã«ã‚り,
+一方ページã®æœ€çµ‚è¡Œã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¯æœ¬æ–‡é ˜åŸŸã®å·¦ç«¯ã«ã‚る.
+縦組和文フォントã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¯æ–‡å­—ã®å·¦å³ä¸­å¤®ã‚’通るã“ã¨ã‹ã‚‰ï¼Œ
+従ã£ã¦ï¼Œ\emph{見ãŸç›®ã§è¨€ãˆã°ï¼Œå³ä½™ç™½ã®æ–¹ãŒ$\cs{topskip}=8.5\,\textrm{pt}$ã ã‘
+大ãã„}ã¨ã„ã†ã“ã¨ã«ãªã£ã¦ã—ã¾ã†\footnote{%
+ åŒæ§˜ã«ï¼Œæ¨ªçµ„㧠\texttt{vcentering}を指定ã™ã‚‹ã¨ï¼Œè¦‹ã‹ã‘ã§ã¯
+ $\cs{topskip}-\cs{Cht}+\cs{Cdp}$ã ã‘上余白ãŒå¤§ãã„よã†ã«è¦‹ãˆã‚‹ï¼Ž
+}.
+
+
+\end{document}
diff --git a/macros/luatex/generic/luatexja/doc/ltjclasses.pdf b/macros/luatex/generic/luatexja/doc/ltjclasses.pdf
new file mode 100644
index 0000000000..872598852f
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/ltjclasses.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/ltjltxdoc.pdf b/macros/luatex/generic/luatexja/doc/ltjltxdoc.pdf
new file mode 100644
index 0000000000..f963ecb767
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/ltjltxdoc.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/ltjsclasses.pdf b/macros/luatex/generic/luatexja/doc/ltjsclasses.pdf
new file mode 100644
index 0000000000..06aa0a88da
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/ltjsclasses.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/luatexja-en.pdf b/macros/luatex/generic/luatexja/doc/luatexja-en.pdf
new file mode 100644
index 0000000000..ed02760546
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/luatexja-en.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/luatexja-ja.pdf b/macros/luatex/generic/luatexja/doc/luatexja-ja.pdf
new file mode 100644
index 0000000000..eb9c60bca0
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/luatexja-ja.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/luatexja-ruby.pdf b/macros/luatex/generic/luatexja/doc/luatexja-ruby.pdf
new file mode 100644
index 0000000000..935ed02930
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/luatexja-ruby.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/luatexja-ruby.tex b/macros/luatex/generic/luatexja/doc/luatexja-ruby.tex
new file mode 100644
index 0000000000..4d4be4f4f1
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/luatexja-ruby.tex
@@ -0,0 +1,806 @@
+%#! luajitlatex
+%%% a test of ruby.
+\documentclass[a4paper,10pt]{ltjsarticle}
+\usepackage{luatexja-otf,amsmath}
+\usepackage[match]{luatexja-fontspec}
+\usepackage[kozuka-pr6n]{luatexja-preset}\normalsize
+\def\emph#1{\textbf{\textgt{#1}}}
+\def\headfont{\normalfont\bfseries\gtfamily}
+\setmonojfont{KozGoPr6N-Regular.otf}
+
+\usepackage[textwidth=45\zw, lines=45, footskip=6mm]{geometry}
+\advance\leftmargini-1\zw\advance\leftmarginii-1\zw
+\protected\def\Param#1{\underline{\smash{\textsf{\mdseries #1}}}}
+
+\usepackage{luatexja-ruby,showexpl,booktabs}
+\lstset{
+ preset=\normalsize, basicstyle=\small\ttfamily, basewidth=0.5em,
+ explpreset={numberstyle=\tiny, numbers=left, numbersep=1em, columns=fixed},
+}
+\makeatletter\let\SX@Info=\relax\makeatother
+\fboxsep=0mm
+
+\usepackage{hyperref,bookmark,xcolor}
+\hypersetup{%
+ unicode,
+ colorlinks,
+ allbordercolors=1 1 1,
+ allcolors=blue,
+ pdftitle={luatexja-ruby.sty}
+}
+
+\def\Node#1#2{\,\vcenter{\hbox{\fboxsep=1pt\fbox{\vbox{\small\halign{\hfil##\hfil\cr
+ #1\mathstrut\cr\noalign{\hrule height.4pt}\strut#2\cr}}}}\,}}
+\def\LuaTeX{Lua\TeX}
+
+% 三分ルビ用
+\DeclareFontShape{JY3}{mc}{mc}{n}{<-> [0.92487]
+ KozMinPr6N-Regular:extend=0.67;jfm=ujisc33}{}
+
+\title{\textsf{luatexja-ruby}パッケージ}
+\begin{document}
+\catcode`\<=13
+\def<#1>{{\normalfont\rm\itshape$\langle$#1\/$\rangle$}}
+%\fontsize{13.19873}{15}\selectfont%
+
+\maketitle
+
+\begin{abstract}
+\textsf{luatexja-ruby}パッケージã¯ï¼Œ\LuaTeX-jaã®æ©Ÿèƒ½ã‚’利用ã—ã¦ãƒ«ãƒ“ã®çµ„版処ç†ã‚’è¡Œã†è¿½åŠ ãƒ‘ッケージã§ã‚る.
+\LuaTeX, \LuaTeX-jaã®å†…部処ç†ã«å‰²ã‚Šè¾¼ã‚€ã“ã¨ã«ã‚ˆã‚Šï¼Œç†Ÿèªžãƒ«ãƒ“中ã®è¡Œåˆ†å‰²ã‚„,
+行頭形・行中形・行末形ã®è‡ªå‹•æ¤œå‡ºï¼Œã¾ãŸé€²å…¥è¨±å®¹é‡ã®è‡ªå‹•è¨­å®šãªã©ã‚’å¯èƒ½ã¨ã—ãŸï¼Ž
+\end{abstract}
+
+\tableofcontents
+
+\newpage
+\section{\ltjruby{利|用|æ–¹|法}{ã‚Š|よã†|ã»ã†|ã»ã†}}
+パッケージ読ã¿è¾¼ã¿ã¯ï¼Œ\verb+\usepackage{luatexja-ruby}+ ã§è‰¯ã,
+å¿…è¦ãªã‚‰ã°è‡ªå‹•çš„ã«\LuaTeX-ja本体を読ã¿è¾¼ã‚€ï¼Ž
+plain \LuaTeX ã§ã®ãƒ­ãƒ¼ãƒ‰ã¯ã¾ã ã‚µãƒãƒ¼ãƒˆã—ã¦ãŠã‚‰ãšï¼Œ
+\LaTeXe ã®ã¿ã‚µãƒãƒ¼ãƒˆã—ã¦ã„る.
+
+\subsection{\ltjruby{用|語}{よã†|ã”}}
+「進入(intrusion)ã€ã€Œçªå‡º(protrusion)ã€ã¨ã„ã†ç”¨èªžã¯ï¼Œ
+\href{http://zrbabbler.sp.land.to/pxrubrica.html}{\textsf{pxrubrica}パッケージ}%
+ã§ã®ç”¨æ³•ã«æº–ãšã‚‹ï¼Ž
+
+\begin{quotation}
+進入ã‚り:ã¨\ltjruby{æš}{ã‚ã‹ã¤ã}ã®
+
+進入ãªã—:{\setkeys[ltj]{ruby}{mode=0}ã¨\ltjruby{æš}{ã‚ã‹ã¤ã}ã®}
+
+çªå‡ºã‚り:{\setkeys[ltj]{ruby}{stretch={1}{2}{1}}\ltjruby{è´è¡†}{ã¡ã‚ˆã†ã—ゆã†}}
+
+çªå‡ºãªã—:{\setkeys[ltj]{ruby}{stretch={0}{2}{0}}\ltjruby{è´è¡†}{ã¡ã‚ˆã†ã—ゆã†}}
+\end{quotation}
+
+\subsection{\ruby{命|令}{ã‚ã„|ã‚Œã„}}
+\paragraph{\tt\textbackslash ltjruby}
+ルビ出力用命令ã®æœ¬ä½“.\verb+\ruby+ ã¨ã„ã†åˆ¥åを定義ã—ã¦ã„る.
+\begin{quote}
+\tt \textbackslash ltjruby[<option>]\{親|æ–‡|å­—\}\{ãŠã‚„|ã‚‚|ã˜\}
+\end{quote}
+ã®ã‚ˆã†ã«ä½¿ç”¨ã™ã‚‹ï¼Ž
+第2・第3引数内ã®ã€Œ\verb+|+ã€ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã®åŒºåˆ‡ã‚Šã‚’表ã™ï¼Žè©³ç´°ã¯\ref{ssec:grp}\nobreak å°ç¯€ã‚’å‚照.
+
+<option>ã«ã¯ä»¥ä¸‹ã®å†…容をkey-valueリストã§æŒ‡å®šå¯èƒ½ã§ã‚る:
+\begin{description}
+\def\makelabel#1{\tt#1}
+\item[pre=<real>] å‰é€²å…¥è¨±å®¹é‡ã‚’ルビ全角å˜ä½ã§æŒ‡å®šï¼Ž
+è² ã®é•·ã•ã‚’指定ã—ãŸå ´åˆã¯ï¼Œãƒ«ãƒ“ã®çŠ¶æ³ã‚„ç›´å‰ã®æ–‡å­—ã«å¿œã˜ãŸè‡ªå‹•æŒ‡å®šã‚’æ„味ã™ã‚‹ï¼Ž
+既定値ã¯è² ï¼ˆã¤ã¾ã‚Šï¼Œè‡ªå‹•æŒ‡å®šï¼‰ï¼Ž
+
+\item[post=<real>] åŒæ§˜ã«ï¼Œå¾Œé€²å…¥è¨±å®¹é‡ã‚’指定ã™ã‚‹ï¼Žæ—¢å®šå€¤ã¯è² ï¼ˆè‡ªå‹•æŒ‡å®šï¼‰ï¼Ž
+
+\item[mode] 進入処ç†ã®ãƒ¢ãƒ¼ãƒ‰ã‚’表ã™bit vector.下ä½2\,bitã¯ï¼Œ\texttt{pre}ã‚„
+\texttt{post}ãŒè² ã§ã‚ã‚‹å ´åˆã«ã—ã‹åŠ¹åŠ›ã‚’発æ®ã—ãªã„.既定値ã¯$(0001)_2 = 1$.
+\begin{description}
+ \item[bit 0] 進入を無効ã«ã™ã‚‹ãªã‚‰ã°0,有効ã«ã™ã‚‹ãªã‚‰ã°1.
+ \item[bit 1] å‰é€²å…¥è¨±å®¹é‡$B$ã¨å¾Œé€²å…¥è¨±å®¹é‡$A$ãŒç•°ãªã£ãŸå ´åˆï¼Œ
+ãã®ã¾ã¾å‡¦ç†ã™ã‚‹å ´åˆã¯0,å°ã•ã„æ–¹ã«æƒãˆã‚‹ãªã‚‰ã°1.
+ \item[bit 2--3] ルビ文字ã®çªå‡ºé‡$x$ã‹ã‚‰å®Ÿéš›ã®å‰é€²å…¥é‡$b$,後進入é‡$a$ã®è¨ˆç®—方法を指定ã™ã‚‹ï¼Ž
+親文字ã®æ–‡å­—æ•°ãŒ$k+1$,親文字ã®å‰ã«å…¥ã‚‹ç©ºç™½é‡ãƒ»é–“ã®ç©ºç™½é‡ãƒ»å¾Œã‚ã®ç©ºç™½é‡ã®æ¯”ãŒ$p:q:r$ã®ã¨ã,
+\begin{description}
+ \item[00] $b=\min\{B, xp/[p+kq+r]\}$, \ $a=\min\{A, xr/[p+kq+r]\}$
+ \item[01] $b=\min(B, x)$, \ $a=\min[A, \max(x-b,0)]$
+ \item[10] $a=\min(A, x)$, \ $b=\min[B, \max(x-a,0)]$
+ \item[11] $M=\min(B,A)$ã¨ãŠã.もã—$x\le 2M$ãªã‚‰ã°$b=a=x/2$.ãã†ã§ãªã‘ã‚Œã°
+\[
+ b=\min\left(B, M + \frac{(x-2M)p}{p+kp+r}\right),\qquad
+ a=\min\left(A, M + \frac{(x-2M)r}{p+kp+r}\right)
+\]
+\end{description}
+
+組ã¿æ–¹ã®å…·ä½“例を実際ã«ç¤ºã™ï¼Žä¾‹ç¤ºã®ãŸã‚,平仮åã«ã¯ãƒ«ãƒ“ãŒ1å­—ã¾ã§ï¼Œã€Œç«‹ã€ã«ã¯ãƒ«ãƒ“ã‚’
+0.5字分ã¾ã§ã‹ã‘ã¦ã‚ˆã„ã“ã¨ã«ã—ã¦ã„る.
+\begin{description}
+\item[00]{\setkeys[ltj]{ruby}{mode=1}%
+\ltjsetparameter{rubypreintrusion={`ç«‹,0.5}, rubypostintrusion={`ç«‹,0.5}}%
+ã¯\ltjruby{美}{ã†ã¤ã}ã—ã„
+ \quad ã¯\ltjruby{è´è¡†}{ã¡ã‚ˆã†ã—ゆã†}ã¨\quad
+ã¯\ltjruby{æš}{ã‚ã‹ã¤ã}ç«‹\quad
+ã¯\ltjruby{è´è¡†}{ã¡ã‚ˆã†ã—ゆã†}ç«‹\par}
+\item[01]{\setkeys[ltj]{ruby}{mode=5}%
+\ltjsetparameter{rubypreintrusion={`ç«‹,0.5}, rubypostintrusion={`ç«‹,0.5}}%
+ã¯\ltjruby{美}{ã†ã¤ã}ã—ã„
+ \quad ã¯\ltjruby{è´è¡†}{ã¡ã‚ˆã†ã—ゆã†}ã¨\quad
+ã¯\ltjruby{æš}{ã‚ã‹ã¤ã}ç«‹\quad
+ã¯\ltjruby{è´è¡†}{ã¡ã‚ˆã†ã—ゆã†}ç«‹\par}
+\item[10]{\setkeys[ltj]{ruby}{mode=9}%
+\ltjsetparameter{rubypreintrusion={`ç«‹,0.5}, rubypostintrusion={`ç«‹,0.5}}%
+ã¯\ltjruby{美}{ã†ã¤ã}ã—ã„
+ \quad ã¯\ltjruby{è´è¡†}{ã¡ã‚ˆã†ã—ゆã†}ã¨\quad
+ã¯\ltjruby{æš}{ã‚ã‹ã¤ã}ç«‹\quad
+ã¯\ltjruby{è´è¡†}{ã¡ã‚ˆã†ã—ゆã†}ç«‹\par}
+\item[11]{\setkeys[ltj]{ruby}{mode=13}%
+\ltjsetparameter{rubypreintrusion={`ç«‹,0.5}, rubypostintrusion={`ç«‹,0.5}}%
+ã¯\ltjruby{美}{ã†ã¤ã}ã—ã„\quad
+ã¯\ltjruby{è´è¡†}{ã¡ã‚ˆã†ã—ゆã†}ã¨\quad
+ã¯\ltjruby{æš}{ã‚ã‹ã¤ã}ç«‹\quad
+ã¯\ltjruby{è´è¡†}{ã¡ã‚ˆã†ã—ゆã†}ç«‹\par}
+\end{description}
+
+\end{description}
+\item[stretchruby=\{<left>\}\{<middle>\}\{<right>\}] 親文字ã®åˆè¨ˆé•·ãŒ
+ルビ文字ã®åˆè¨ˆé•·ã‚ˆã‚Šé•·ã„時ã«ï¼Œãƒ«ãƒ“文字ã®å‰ãƒ»é–“・後ã«å…¥ã‚Œã‚‹ç©ºç™½ã®å‰²åˆã§ã‚り,
+ãã‚Œãžã‚Œ0--7ã®è‡ªç„¶æ•°ã§æŒ‡å®šã™ã‚‹ï¼Ž
+既定値ã¯\ \verb+{1}{2}{1}+ ã§ã‚る.
+<left>ã¯ãƒ«ãƒ“文字ã®å…ˆé ­ã¾ã§ã®ç©ºãé‡ï¼Œ<middle>ã¯ãƒ«ãƒ“文字間ã®ç©ºãé‡ï¼Œ<right>ã¯ãƒ«ãƒ“文字ã®æœ«å°¾ã‹ã‚‰ã®
+空ãé‡ï¼ˆã®æ¯”)を表ã™ï¼Žä»¥ä¸‹ãŒä¾‹ã§ã‚る.
+\begin{LTXexample}[width=0.3\textwidth, preset=\Large]
+\ltjruby[stretchruby=123,maxmargin=2]%
+ {◯◯◯◯}{◆◆}
+\end{LTXexample}
+\item[stretch=\{<left>\}\{<middle>\}\{<right>\}]
+行中形ã§ãƒ«ãƒ“文字ã®æ–¹ãŒé•·ã„å ´åˆï¼Œè¦ªæ–‡å­—ã®å‰ãƒ»ä¸­ãƒ»å¾Œã«å…¥ã‚Œã‚‹ç©ºç™½ã®å‰²åˆï¼Ž
+既定値ã¯\ \verb+{1}{2}{1}+ ã§ã‚る.ãれ以外ã®ä»£è¡¨çš„ãªå€¤ã¨ã—ã¦ã¯ï¼Œä¾‹ãˆã°æ¬¡ã®ã‚ˆã†ãªã‚‚ã®ãŒã‚る.
+\begin{description}
+\item[親文字å‡ç­‰å‰²ç¦æ­¢] \verb+{1}{0}{1}+\ ãªã©<middle>ã‚’0ã«ã—ãŸå€¤
+\item[å‰çªå‡ºç¦æ­¢] \verb+{0}{1}{1}+
+\item[後çªå‡ºç¦æ­¢] \verb+{1}{1}{0}+
+\end{description}
+
+\item[stretchbol=\{<left>\}\{<middle>\}\{<right>\}] 行頭形〜.
+既定値ã¯\ \verb+{0}{1}{1}+ ã§ã‚る.
+\item[stretcheol=\{<left>\}\{<middle>\}\{<right>\}] 行末形〜.
+既定値ã¯\ \verb+{1}{1}{0}+ ã§ã‚る.
+
+\item[maxmargin=<real>] 親文字ã®æ–¹ãŒãƒ«ãƒ“より長ã„時ã«ï¼Œãƒ«ãƒ“ã®å…ˆé ­ã¨è¦ªæ–‡å­—ã®å…ˆé ­ï¼ŒåŠã³
+ルビ末尾ã¨è¦ªæ–‡å­—ã®æœ«å°¾ã®é–“ã«è¨±ã•ã‚Œã‚‹æœ€å¤§ã®ç©ºç™½é‡ï¼Ž\textbf{親文字全角å˜ä½}ã§æŒ‡å®šã—,既定値ã¯0.5.
+
+\medskip
+\item[size=<real>] ルビ文字ã®è¦ªæ–‡å­—ã«å¯¾ã™ã‚‹å¤§ãã•ï¼Žæ—¢å®šå€¤ã¯0.5.
+\item[intergap=<real>] ルビ文字ã¨è¦ªæ–‡å­—ã¨ã®ç©ºãを親文字全角å˜ä½ã§æŒ‡å®šï¼Žæ—¢å®šå€¤ã¯0.
+\item[rubysmash=<bool>] ルビã®é«˜ã•ã‚’0ã«ã™ã‚‹ã‹ï¼Žæ—¢å®šå€¤ã¯å½ï¼Žæ¬¡ãŒä¾‹ã§ã‚る.
+\begin{LTXexample}[width=0.3\textwidth, preset=\Large]
+\ \vrule width 0pt height 2\zw depth 1\zw
+\frame{\ltjruby[rubysmash=false]{本}{ã»ã‚“}}\
+\frame{\ltjruby[rubysmash=true]{本}{ã»ã‚“}}\
+\frame{\ltjruby[rubysmash=false,intergap=0.2]
+ {本}{ã»ã‚“}}\
+\frame{\ltjruby[rubysmash=true,intergap=0.2]
+ {本}{ã»ã‚“}}\
+\frame{\ltjruby[rubysmash=false,intergap=-1.5]
+ {本}{ã»ã‚“}}
+\end{LTXexample}
+
+
+\item[kenten=<command>]å„文字ã«ã¤ãåœç‚¹ã®å‡ºåŠ›å‘½ä»¤ã‚’指定ã™ã‚‹ï¼Žæ—¢å®šå€¤ã¯ã€Œ\verb+\ltjalchar`•+ã€
+ã§ã‚り,\texttt{U+2022} (Bullet)ã‚’\textbf{ALchar}ã¨ã—ã¦å‡ºåŠ›ã™ã‚‹ã“ã¨ã‚’指定ã—ã¦ã„る.
+
+\item[fontcmd=<command>]ルビ用ã®ãƒ•ã‚©ãƒ³ãƒˆåˆ‡ã‚Šæ›¿ãˆå‘½ä»¤ã‚’指定ã™ã‚‹ï¼Ž
+ã“ã®ã‚­ãƒ¼ã®å†…容ãŒå®Ÿè¡Œã•ã‚ŒãŸå¾Œã«\ \verb+\fontsize...\selectfont+\ ãŒå®Ÿè¡Œã•ã‚Œã‚‹ã®ã§ï¼Œ
+ã“ã®ã‚­ãƒ¼ã®æŒ‡å®šã§ã¯æœ€å¾Œã«\ \verb+\selectfont+ を加ãˆã‚‹å¿…è¦ã¯ãªã„.
+
+ã“ã® \texttt{fontcmd} キーã®å†…容ã¯å¤šãã®å›žæ•°å®Ÿè¡Œã•ã‚Œã‚‹ï¼Ž
+例ãˆã°ï¼Œ\textsf{luatexja-fontspec}パッケージを用ã„ã¦OpenTypeフォントを用ã„ã‚‹å ´åˆï¼Œ
+\begin{lstlisting}
+ fontcmd=\addjfontfeatures{Style=Ruby}
+\end{lstlisting}
+ã®ã‚ˆã†ã«ã—ã¦ãƒ«ãƒ“用字形を用ã„ã‚‹ã“ã¨ãŒå¯èƒ½ã ãŒï¼Œç¾åœ¨ã®å®Ÿè£…ã§ã¯ã‚¿ã‚¤ãƒ—セットã«æ™‚é–“ãŒã‹ã‹ã‚‹ã‚ˆã†ã«ãªã‚‹ï¼Ž
+
+
+\end{description}
+
+\medskip
+次ã®2ã¤ã¯ï¼Œä»¥ä¸Šã§èª¬æ˜Žã—ãŸè¤‡æ•°ã®ã‚ªãƒ—ションを一度ã«è¨­å®šã™ã‚‹ãŸã‚ã®ã‚‚ã®ã§ã‚る.
+普通ã¯ã“ã®2ã¤ã®ã†ã¡ã„ãšã‚Œã‹ã‚’設定ã™ã‚‹ã ã‘ã§è¶³ã‚Šã‚‹ã ã‚ã†ï¼Ž
+
+\begin{description}
+\def\makelabel#1{\tt#1}
+\item[naka] 以下ã®ã‚ªãƒ—ションをåŒæ™‚ã«è¨­å®šã™ã‚‹ï¼Žä¸»ã«ä¸­ä»˜ãルビを組むã¨ãã«ç”¨ã„る.
+\begin{verbatim}
+mode=1, stretch={1}{2}{1}, stretchruby={1}{2}{1}
+\end{verbatim}
+\item[kata] åŒæ§˜ã«ï¼Œè‚©ä»˜ãルビ用ã«ï¼Œæ¬¡ã‚’設定ã™ã‚‹ï¼Ž
+\begin{verbatim}
+mode=9, stretch={1}{2}{1}, stretchruby={0}{0}{1}
+\end{verbatim}
+\end{description}
+
+\paragraph{\tt\textbackslash ltjsetruby\{<option>\}}
+<option>ã®æ—¢å®šå€¤ã‚’指定ã™ã‚‹ï¼Ž\textsf{luatexja-ruby}読ã¿è¾¼ã¿æ™‚ã®å€¤ã¯
+å„é …ç›®ã®æ‰€ã§æ—¢ã«èª¬æ˜Žã—ã¦ã‚ã‚‹ãŒï¼Œæ¬¡ã®ã‚ˆã†ã«ãªã£ã¦ã„る.
+\begin{verbatim}
+ pre=-1, post=-1, mode=1,
+ stretchruby={1}{2}{1}, stretch = {1}{2}{1},
+ stretchbol={0}{1}{1}, stretcheol={1}{1}{0},
+ maxmargin=0.5, size=0.5, intergap=0, rubysmash=false,
+ kenten=\ltjalchar`•, fontcmd=\relax
+\end{verbatim}
+
+\paragraph{\texttt{\textbackslash ltjsetparamater} ã«è¿½åŠ ã•ã‚Œã‚‹ã‚­ãƒ¼}
+\begin{description}
+\item[\Param{rubypreintrusion}\tt =\{<chr\_code>, <pre\_int>\}]
+文字<chr\_code> ã«ï¼Œãã®\textbf{直後}ã®ãƒ«ãƒ“ã«ã‚ˆã£ã¦æŽ›ã‘られるルビ文字列ã®æœ€å¤§é•·ã‚’ルビ全角å˜ä½ã§æŒ‡å®šï¼Ž
+\item[\Param{rubypostintrusion}\tt =\{<chr\_code>, <post\_int>\}]
+文字<chr\_code> ã«ï¼Œãã®\textbf{ç›´å‰}ã®ãƒ«ãƒ“ã«ã‚ˆã£ã¦æŽ›ã‘られるルビ文字列ã®æœ€å¤§é•·ã‚’ルビ全角å˜ä½ã§æŒ‡å®šï¼Ž
+\end{description}
+既定値ã¯ï¼Œ\Param{rubypreintrusion},~\Param{rubypostintrusion}ã¨ã‚‚
+以下ã®æ–‡å­—ã«å¯¾ã—ã¦ã¯1,ãã®ä»–ã®æ–‡å­—ã«ã¤ã„ã¦ã¯0ã§ã‚る:
+\begin{quote}
+ 平仮å(\texttt{U+3040}--\texttt{U+309F}),カギ括弧「ã€ï¼Œèª­ç‚¹ã€Œï¼Œã€ã€Œã€ã€ï¼Œä¸­é»’「・ã€
+\end{quote}
+ã¾ãŸï¼Œã“ã“ã§ã¯ã€Œæ–‡å­—コード$-1$ã®æ–‡å­—ã€ã¯ï¼Œã€Œæ®µè½é–‹å§‹ã® \verb+\parindent+ã€ã‚’表ã™%
+\footnote{通常ã®\LuaTeX-jaã«ãŠã‘る指定ã§ã¯æ–‡ä¸­æ•°å¼å¢ƒç•Œã‚’表ã—ã¦ã„ã‚‹ã“ã¨ã«æ³¨æ„.}.
+ã“ã®ã€Œæ–‡å­—ã€ã«å¯¾ã™ã‚‹\Param{rubypreintrusion}ã®å€¤ã‚‚1ã§ã‚る.
+
+\paragraph{\texttt{\textbackslash ltjkenten}}
+åœç‚¹ã‚’出力ã™ã‚‹å‘½ä»¤ã§ï¼Œ\verb+\kenten+ ã¨ã„ã†åˆ¥åを定義ã—ã¦ã„る.
+\begin{quote}
+ \tt \textbackslash ltjkenten[<option>]\{親文字\}
+\end{quote}
+ã®ã‚ˆã†ã«ä½¿ç”¨ã™ã‚‹ï¼Žè¤‡æ•°æ–‡å­—ã«åœç‚¹ã‚’ã¤ã‘ã‚‹å ´åˆã§ã‚‚,\verb+\ltjruby+ ã®ã‚ˆã†ã«ã€Œ\texttt{|}ã€ã‚’使ã£ã¦
+文字を区切る\textbf{å¿…è¦ã¯ãªã„}ã“ã¨ã«æ³¨æ„ã—ã¦ã»ã—ã„.
+
+åœç‚¹ã¨ã—ã¦å‡ºåŠ›ã•ã‚Œã‚‹æ–‡å­—㯠\texttt{kenten} キーã«ã‚ˆã£ã¦æŒ‡å®šã—,
+åœç‚¹è‡ªèº«ã®å¤§ãã•ã¯ï¼ˆãƒ«ãƒ“ã¨åŒæ§˜ã«ï¼‰\texttt{size} キーã§æŒ‡å®šã™ã‚‹ï¼Ž
+
+\subsection{グループã®\ruby{指|定}{ã—|ã¦ã„}}
+\label{ssec:grp}
+\begin{quote}
+\tt \textbackslash ltjruby[<option>]\{親|æ–‡|å­—\}\{ãŠã‚„|ã‚‚|ã˜\}
+\end{quote}
+ã®ã‚ˆã†ã«ï¼Œ\verb+\ltjruby+\ ã®ç¬¬2・第3引数内ã®ã€Œ\verb+|+ã€ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã®åŒºåˆ‡ã‚Šã‚’表ã™ï¼Ž
+グループã®æ•°ã¯ä¸¡è€…ã§ä¸€è‡´ã—ãªã‘ã‚Œã°ãªã‚‰ãšï¼Œ
+\verb+\ltjruby{ç´‹ç« }{ã‚‚ã‚“|ã—よã†}+ ã®ã‚ˆã†ã«ã¯\emph{ã§ããªã„}.
+
+1グループã®ã¿ã®ãƒ«ãƒ“(å˜ç´”グループルビ)ã¯ã‚°ãƒ«ãƒ¼ãƒ—ルビã¨ã—ã¦çµ„ã¾ã‚Œã‚‹ï¼Žãã®ãŸã‚,
+ã‚‚ã—モノルビを使ã„ãŸã‘ã‚Œã°ï¼Œé¢å€’ã§ã‚‚
+\begin{LTXexample}[width=0.4\textwidth, preset=\Large]
+ã®\ltjruby{ç´‹}{ã‚‚ã‚“}\ltjruby{ç« }{ã—よã†}ãŒ
+\end{LTXexample}
+ã®ã‚ˆã†ã«ï¼Œè¤‡æ•°å›žä½¿ç”¨ã™ã‚‹ã“ã¨ï¼Ž
+ã¾ãŸï¼Œå…¨ã¦ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«ãŠã„ã¦ã€Œãƒ«ãƒ“文字列ã®é•·ã•ã¯è¦ªæ–‡å­—列以下ã€ã§ã‚ã‚Œã°ï¼Œ
+å˜ç´”グループルビã®ä¸¦ã³ã¨ã—ã¦æ‰±ã‚れる.ã™ãªã‚ã¡ï¼Œæ¬¡ã®2è¡Œã¯å…¨ãã®ç­‰ä¾¡ã¨ãªã‚‹ï¼Ž
+\begin{verbatim}
+\ltjruby{æ™®|通|車}{ãµ|ã¤ã†|ã—ã‚„}
+\ltjruby{æ™®}{ãµ}\ltjruby{通}{ã¤ã†}\ltjruby{車}{ã—ã‚„}
+\end{verbatim}
+
+\newpage
+複数グループã‹ã¤ä¸Šè¨˜ã®æ¡ä»¶ã‚’満ãŸã•ãªã„å ´åˆã¯ï¼Œ
+所謂「å¯å‹•ã‚°ãƒ«ãƒ¼ãƒ—ルビã€ã§ã‚り,ルビã®å‰å¾Œã‚„å„グループã®åˆ‡ã‚Œç›®ã§è¡Œåˆ†å‰²ãŒå¯èƒ½ã¨ãªã‚‹ï¼Ž
+例ãˆã°
+\begin{verbatim}
+…ã®\ltjruby{表|ç¾|力}{ã²ã‚ˆã†|ã’ã‚“|りよã}ã¯â€¦
+\end{verbatim}
+ã¨ã„ã†å…¥åŠ›ã‹ã‚‰ã¯å¾—られる組版çµæžœã¯ï¼Œæ¬¡ã®ã„ãšã‚Œã‹ã«ãªã‚‹ï¼Ž
+\begin{center}
+ \begin{tabular}{ll}
+ \toprule
+ 改行ãªã—(行中形)&\Large …ã®\ltjruby{表|ç¾|力}{ã²ã‚ˆã†|ã’ã‚“|りよã}ã¯â€¦\\
+ ç›´å‰ã§æ”¹è¡Œ&\Large \vrule \ltjruby[stretch=011]{表|ç¾|力}{ã²ã‚ˆã†|ã’ã‚“|りよã}ã¯â€¦\\
+&\Large …ã®\ltjruby[stretch=110]{表}{ã²ã‚ˆã†}
+ \vrule\ltjruby[stretch=011]{ç¾|力}{ã’ã‚“|りよã}ã¯â€¦\\
+&\Large …ã®\ltjruby[stretch=110]{表|ç¾}{ã²ã‚ˆã†|ã’ã‚“}
+ \vrule\ltjruby[stretch=011]{力}{りよã}ã¯â€¦\\
+ 直後ã«æ”¹è¡Œ&\Large …ã®\ltjruby[stretch=110]{表|ç¾|力}{ã²ã‚ˆã†|ã’ã‚“|りよã}\vrule\\
+\bottomrule
+ \end{tabular}
+\end{center}
+\begin{itemize}
+ \item ã“れらã®è¡Œåˆ†å‰²ã«ã‚ˆã£ã¦ãƒšãƒŠãƒ«ãƒ†ã‚£ã¯ç™ºç”Ÿã—ãªã„.
+ \item 上記ã®ä¾‹ã§è¦‹ã‚‰ã‚Œã‚‹ã‚ˆã†ã«ï¼Œ
+2ブロック以上をã¾ã¨ã‚ã¦çµ„ã‚€ã¨ãã¯ï¼Œå…¨ä½“ã‚’1ã¤ã®ã‚°ãƒ«ãƒ¼ãƒ—ルビã®ã‚ˆã†ã«çµ„版ã™ã‚‹ï¼ˆJIS~X~4051ã¨åŒæ§˜ï¼‰ï¼Ž
+『日本語組版処ç†ã®è¦ä»¶ã€ã§ã¯ï¼Œ
+附属書Fã«ã€Œç†Ÿèªžã®æ§‹æˆï¼Œã•ã‚‰ã«ãã®ç†Ÿèªžã®å‰å¾Œã«ãる文字ã®ç¨®é¡žã‚’考慮ã—ã¦é…ç½®ã™ã‚‹æ–¹æ³•ã€ã¨ã—ã¦
+別ã®æ–¹æ³•ã‚’解説ã—ã¦ã„ã‚‹ãŒï¼Œã“ã¡ã‚‰ã®æ–¹æ³•ã¯ç¾æ™‚点ã§ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„ã®ã§ï¼Œ
+é¢å€’ã§ã‚‚手動㧠\texttt{pre}, \texttt{post} ãªã©ã‚’使ã£ã¦é ‘å¼µã£ã¦æ¬²ã—ã„.
+ \item 実装方法ã®éƒ½åˆã«ã‚ˆã‚Šï¼Œãƒ«ãƒ“ã®ç›´å‰ãƒ»ç›´å¾Œãƒ»é€”中ã§2箇所以上ã®æ”¹è¡ŒãŒèµ·ãã‚‹å ´åˆï¼Œä¾‹ãˆã°
+\begin{center}
+ \begin{tabular}{lll}
+ \toprule
+ \Large …ã®\ltjruby[stretch=110]{表}{ã²ã‚ˆã†}
+ \vrule\ltjruby[stretch=010]{ç¾|力}{ã’ã‚“|りよã}\vrule&
+\Large \vrule\ltjruby[stretch=010]{表|ç¾}{ã²ã‚ˆã†|ã’ã‚“}
+ \vrule\ltjruby[stretch=011]{力}{りよã}ã¯â€¦&
+\Large \vrule\ltjruby[stretch=010]{表|ç¾|力}{ã²ã‚ˆã†|ã’ã‚“|りよã}\vrule\\
+\bottomrule
+ \end{tabular}
+\end{center}
+ãªã©ã®çµ„ã¿æ–¹ã¯\emph{想定ã—ã¦ã„ãªã„}.
+\end{itemize}
+
+\newpage
+
+\section{\ruby{注|æ„|点}{ã¡ã‚†ã†|ã„|ã¦ã‚“}}
+\begin{description}
+\item[ルビ文字ã®ã¯ã¿å‡ºã—]
+「日本語組版処ç†ã®è¦ä»¶ã€ã®å›³3.82ã®ã‚ˆã†ã«ï¼Œ
+ルビ文字ã®ã¯ã¿å‡ºã—ãŒç¹‹ãŒã‚‰ãªã„よã†ã«ã™ã‚‹å‡¦ç†ã«ã¤ã„ã¦è¿°ã¹ã‚‹ï¼Ž
+
+例ãˆã°ï¼Œ
+\begin{LTXexample}[preset=\Large,width=0.3\textwidth]
+\ltjruby{陵}{りよã†}ã¨\ltjruby{陵}{ã¿ã•ã•ãŽ}\\
+\ltjruby{陵}{りよã†}ã¨\ltjruby[pre=1]{陵}{ã¿ã•ã•ãŽ}
+\end{LTXexample}
+ã«ãŠã„ã¦ï¼Œ1行目å³å´ã®ã€Œ\ltjruby{陵}{ã¿ã•ã•ãŽ}ã€ã®ãƒ«ãƒ“ãŒå‰ã®ã€Œã¨ã€ã«ã‹ã‹ã‚‹é‡ã¯æ¬¡ã®ã‚ˆã†ã«æ±ºã¾ã‚‹ï¼š
+\begin{enumerate}
+\item 1回目ã®å®Ÿè¡Œã§ã¯ï¼Œè¡Œåˆ†å‰²å‰ã«ã€Œ\ltjruby{陵}{りよã†}ã€ã®å¾Œå´é€²å…¥é‡ã¯å‰ã‚‚ã£ã¦çŸ¥ã‚‹ã“ã¨ã¯ã§ã
+ ãªã„.ãªã®ã§ï¼Œã€Œ\ltjruby{陵}{りよã†}ã€ã¯è¡Œä¸­å½¢ã§çµ„ã¾ã‚Œã‚‹ã‚‚ã®ã¨ã—ã¦
+「\ltjruby{陵}{ã¿ã•ã•ãŽ}ã€å‰å´é€²å…¥è¨±å®¹é‡ã¯
+\[
+ \underbrace{0.5\,\mathrm{zw}}_{\text{元々ã®è¨±å®¹é‡}}
+-\underbrace{0.25\,\mathrm{zw}}_{\text{å‰ã®ãƒ«ãƒ“ã®å¾Œå´é€²å…¥é‡ï¼ˆè¡Œä¸­å½¢ï¼‰}}=0.25\,\mathrm{zw}
+\]
+ã¨ãªã‚‹ï¼Žè¡Œåˆ†å‰²å¾Œï¼Œã€Œ\ltjruby{陵}{りよã†}ã€ã®å®Ÿéš›ã®å¾Œå´é€²å…¥é‡ã¯
+auxファイルã«è¨˜è¿°ã•ã‚Œã‚‹ï¼Ž
+\item 2回目以é™ã®å®Ÿè¡Œã§ã¯ï¼Œauxファイルã«ä¿å­˜ã•ã‚ŒãŸã€Œ\ltjruby{陵}{りよã†}ã€ã®å¾Œå´é€²å…¥é‡
+を用ã„ã¦ï¼Œã€Œ\ltjruby{陵}{ã¿ã•ã•ãŽ}ã€å‰å´é€²å…¥è¨±å®¹é‡ã‚’次ã®ã‚ˆã†ã«è¨ˆç®—ã™ã‚‹ï¼š
+\[
+ \underbrace{0.5\,\mathrm{zw}}_{\text{元々ã®è¨±å®¹é‡}}
+-\underbrace{0.25\,\mathrm{zw}}_{\text{å‰ã®ãƒ«ãƒ“ã®å¾Œå´é€²å…¥é‡ (from aux)}}=0.25\,\mathrm{zw}.
+\]
+\end{enumerate}
+auxファイルã«ä¿å­˜ã™ã‚‹éš›ï¼Œå„ \verb+\ltjruby+ 命令ã®å‘¼ã³å‡ºã—を識別ã™ã‚‹ã‚­ãƒ¼ãŒå¿…è¦ã«ãªã‚‹ãŒï¼Œ
+ãã®ã‚­ãƒ¼ã¨ã—ã¦ã¯å˜ç´”ã«ã€Œä½•å€‹ç›®ã® \verb+\ltjruby+ 命令ã‹ã€ã§ã‚る.
+
+ãªãŠï¼Œä»¥ä¸Šã®å‡¦ç†ã¯ï¼Œ1行目ã¨2行目を比較ã™ã‚Œã°åˆ†ã‹ã‚‹ã‚ˆã†ã«ï¼Œ
+「\ltjruby{陵}{ã¿ã•ã•ãŽ}ã€ã®\emph{å‰é€²å…¥è¨±å®¹é‡æŒ‡å®š(\texttt{pre})ãŒè‡ªå‹•}ã«ãªã£ã¦ã„ã‚‹å ´åˆã®ã¿
+実施ã•ã‚Œã‚‹ï¼Ž
+
+\item[段è½æœ«å°¾ã®ãƒ«ãƒ“]
+段è½ãŒãƒ«ãƒ“ã§çµ‚ã‚ã£ãŸå ´åˆï¼Œãã®ãƒ«ãƒ“ãŒè¡Œæœ«å½¢ã§çµ„ã¾ã‚Œã‚‹ã“ã¨ã¯ãªã„.
+ã“ã‚Œã¯ï¼Œæ®µè½ã®ã€Œæœ¬å½“ã®ã€æœ«å°¾ã«ã¯ \verb+\penalty10000\parfillskip+ ãŒã‚ã‚‹ãŸã‚ã§ï¼Œ
+ルビ処ç†ç”¨ã«ä½œã£ãŸæœ€å¾Œã®ã‚°ãƒ«ãƒ¼ï¼ˆ\ref{sec:impl}\nobreak 節ã®èª¬æ˜Žã§ã¯$g_2$)ãŒæ¶ˆåŽ»ã•ã‚Œãªã„ã“ã¨ã«ã‚ˆã‚‹ï¼Ž
+
+\verb+\parfillskip+ ã®é•·ã•ï¼ˆã‚„,場åˆã«ã‚ˆã£ã¦ã¯ \verb+\rightskip+)を実測ã—,
+ãã‚Œã«ã‚ˆã£ã¦å‡¦ç†ã‚’変ãˆã‚‹ã®ã‚‚å¯èƒ½ã ãŒï¼Œãã®ã‚ˆã†ãªã“ã¨ã¯ã—ãªã‹ã£ãŸï¼Ž
+段è½ãŒãƒ«ãƒ“ã§çµ‚ã‚ã‚‹ã“ã¨ã¯æ™®é€šãªã„(最低ã§ã‚‚å¥ç‚¹ãŒç¶šãã ã‚ã†ï¼‰ã¨æ€ã†ã‹ã‚‰ã§ã‚る.
+
+
+
+\item[段è½å…ˆé ­ã®ãƒ«ãƒ“]
+åŒæ§˜ã«ï¼Œæ®µè½å…ˆé ­ã®ãƒ«ãƒ“ã¯è¡Œé ­å½¢ã«ã¯ãªã‚‰ãªã„.
+\texttt{pre}ãŒè² ï¼ˆã¤ã¾ã‚Šï¼Œè‡ªå‹•æŒ‡å®šï¼‰ã®ã¨ã,段è½æœ€åˆã® \verb+\parindent+ 部分ã¸ã®
+進入ã¯å¯èƒ½ã§ã‚る.\verb+\parindent+ 部分ã¸ã®é€²å…¥è¨±å®¹é‡ã¯
+「文字$-1$ã€ã«å¯¾ã™ã‚‹\Param{rubypreintrusion}(既定値ã¯1,ルビ全角å˜ä½ï¼‰ã¨
+\ \verb+\parindent+ ã®é•·ã•ã®ã†ã¡å°ã•ã„æ–¹ã§ã‚る.
+\begin{LTXexample}[preset=\Large,width=0.4\textwidth]
+\parindent1\zw\noindent ï¼ï¼‘2345\par
+\ltjruby{陵}{ã¿ã•ã•ãŽ}ã¯â€¦â€¦\par
+\ltjruby{承}{ã†ã‘ãŸã¾ã‚}り……\par
+\parindent0.25\zw\ltjruby{陵}{ã¿ã•ã•ãŽ}ã¯â€¦â€¦
+\end{LTXexample}
+
+
+\end{description}
+
+\newpage
+\section{\ruby{実|装}{ã˜ã¤|ãã†}ã«ã¤ã„ã¦}
+\label{sec:impl}
+次ã®ä¾‹ã§å®Ÿè£…ã®å¤§ã¾ã‹ãªæ–¹æ³•ã‚’説明ã™ã‚‹ï¼Ž
+\begin{LTXexample}[preset=\Large]
+……を\ltjruby{æµ|暢}{りゆã†|ã¡ã‚ˆã†}ã«â€¦â€¦
+\end{LTXexample}
+
+\begin{enumerate}
+\item \verb|\ltjruby|コマンド自体ã¯ï¼Œä¸€æ—¦æ¬¡ã®node listを値ã¨ã™ã‚‹whatsit~$W$を作ã£ã¦ï¼Œ
+ç¾åœ¨ã®æ°´å¹³ãƒªã‚¹ãƒˆã¸ã¨æŒ¿å…¥ã™ã‚‹ï¼ˆå¿…è¦ãªã‚‰ã°\verb|\leavevmode|も実行):
+\[
+ \Node{whatsit $w$}{value: 2}\longrightarrow
+ \Node{hlist $s_1$}{「りゆã†ã€}\longrightarrow
+ \Node{hlist $p_1$}{「æµã€}\longrightarrow
+ \Node{hlist $s_2$}{「ã¡ã‚ˆã†ã€}\longrightarrow
+ \Node{hlist $p_2$}{「暢ã€}
+\]
+ã“ã“ã§ï¼Œæœ€åˆã®$w$ã®å€¤2ã¯ï¼Œãƒ«ãƒ“ãŒ2ã¤ã®ãƒ‘ーツ「\ltjruby{æµ}{りゆã†}ã€ã€Œ\ltjruby{暢}{ã¡ã‚ˆã†}ã€ã‹ã‚‰ãªã£ã¦ã„ã‚‹ã“ã¨ã‚’
+表ã—ã¦ã„る.ã“ã®å€¤ã‚’$\mathit{cmp}$ã¨ãŠã“ã†ï¼Ž
+$s_i$é”ã®ä¸­ã®æ–‡å­—ã¯æ—¢ã«ãƒ«ãƒ“ã®å¤§ãã•ã§ã‚る.
+\item \LuaTeX-jaã®å’Œæ–‡å‡¦ç†ã‚°ãƒ«ãƒ¼æŒ¿å…¥å‡¦ç†ã«ãŠã„ã¦ï¼Œ
+ã“ã®whatsit~$W$ã¯ã¾ã¨ã‚ã¦
+「先頭ãŒã€Žæµã€ï¼Œæœ€å¾ŒãŒã€Žæš¢ã€ã§ã‚るよã†ãªhboxã‚’ \verb|\unhbox| ã§å±•é–‹ã—ãŸã‚‚ã®ã€ã¨æ‰±ã‚れる.
+言ã„æ›ãˆã‚Œã°ï¼Œãƒ«ãƒ“部分を無視ã—ãŸå˜ãªã‚‹ã€Œæµæš¢ã€ã¨ã„ã†å’Œæ–‡æ–‡å­—ã®ä¸¦ã³ã¨ã—ã¦æ‰±ã‚れる\footnote{「æµã€ã€Œæš¢ã€ã®é–“ã®ã‚°ãƒ«ãƒ¼ã¯æ—¢ã«å…¥ã£ã¦ã„る,ã¨æ‰±ã‚れる.}.
+次ã®ã‚µãƒ³ãƒ—ルをå‚ç…§
+\begin{LTXexample}[preset=\Large]
+\leavevmode\hbox{.}A\\
+%↑xkanjiskip
+\ltjruby{.}{}A
+%↑2分
+\end{LTXexample}
+\item 和文処ç†ã‚°ãƒ«ãƒ¼ã®æŒ¿å…¥ãŒçµ‚ã‚ã£ãŸå¾Œã§ï¼Œå¯å‹•ã‚°ãƒ«ãƒ¼ãƒ—ルビã®ãŸã‚ã®ãƒŽãƒ¼ãƒ‰ã®æŒ¿å…¥ã«å…¥ã‚‹ï¼Ž
+\begin{enumerate}
+\item $W$ã®å‰å¾Œã«$2\mathit{cmp}+1=5$個ã®ãƒŽãƒ¼ãƒ‰ãŒæŒ¿å…¥ã•ã‚Œï¼Œ$W$ã®å‘¨è¾ºã¯æ¬¡ã®ã‚ˆã†ãªãƒŽãƒ¼ãƒ‰åˆ—ã«ãªã‚‹ï¼Ž
+\begin{align*}
+ (\text{other nodes})&\longrightarrow
+ \Node{glue $g_0$}{}\longrightarrow \Node{whatsit~$W$}{å…ƒã‹ã‚‰ã‚ã‚‹}\longrightarrow \Node{rule $r_1$}{}
+\\&\longrightarrow
+ \Node{glue $g_1$}{}\longrightarrow \Node{rule $r_2$}{}\longrightarrow
+ \Node{glue $g_2$}{}\longrightarrow (\text{other nodes})
+\end{align*}
+
+\item ã“ã®ã‚ˆã†ã«ãƒŽãƒ¼ãƒ‰ã‚’挿入ã™ã‚‹ç›®çš„ã¯ï¼Œ\TeX ã®è¡Œåˆ†å‰²å‡¦ç†è‡ªä½“ã«å½±éŸ¿ã‚’加ãˆãšã«å¯å‹•ã‚°ãƒ«ãƒ¼ãƒ—ルビ
+を実ç¾ã•ã›ã‚‹ã“ã¨ã«ã‚る.
+\begin{gather*}
+ (\text{other nodes})\longrightarrow
+ \Node{glue $g_0$}{}\longrightarrow \Node{whatsit~$W$}{å…ƒã‹ã‚‰ã‚ã‚‹}\longrightarrow \Node{rule $r_1$}{}\\
+\noalign{\hrulefill è¡Œã®å¢ƒç›®\hrulefill}
+\Node{rule $r_2$}{}\longrightarrow
+ \Node{glue $g_2$}{}\longrightarrow (\text{other nodes})
+\end{gather*}
+ã®ã‚ˆã†ã«ãªã£ãŸã¨ã—ãŸã‚‰ï¼Œã€Œ\ltjruby{æµ}{りゆã†}ã€ã€Œ\ltjruby{暢}{ã¡ã‚ˆã†}ã€ã®é–“ã§è¡Œåˆ†å‰²ãŒèµ·ããŸï¼Œã¨ã„ã†ã“ã¨ãŒã‚ã‹ã‚Šï¼Œ
+$g_i$,~$r_i$é”ã®ãƒŽãƒ¼ãƒ‰ã‚’é©åˆ‡ã«ç½®ãæ›ãˆã‚Œã°ã‚ˆã„(後ã§è©³ã—ã説明ã™ã‚‹ï¼‰ï¼Ž
+
+\begin{figure}\centering\small
+\begin{tabular}{cllll}
+\toprule
+\multicolumn{1}{c}{\bf ノード}&\multicolumn{1}{c}{\bf 組ã¿æ–¹}&\multicolumn{1}{c}{\bf サンプル}%
+&\multicolumn{1}{c}{\bf 対応ã™ã‚‹ãƒŽãƒ¼ãƒ‰ä¸¦ã³}\\
+\midrule
+$n_1$&行末1グループ&
+\Large
+\fbox{ã‚’}{\color{blue!50!black}\gt\ltjruby[pre=1,mode=5,stretch=110]{æµ}{りゆã†}}\vrule
+&
+$g_0\rightarrow W\rightarrow r_1$\\
+$n_2$&行末2グループ&
+\Large
+\fbox{ã‚’}{\color{blue!50!black}\gt\ltjruby[pre=1,mode=1,stretch=110]{æµ|暢}{りゆã†|ã¡ã‚ˆã†}}\vrule
+&
+$g_0\rightarrow W\rightarrow r_1\rightarrow g_2 \rightarrow r_2$\\
+$n_3$&行頭1グループ&
+\Large
+\vrule{\color{blue!50!black}\gt\ltjruby[post=1,mode=1,stretch=011]{暢}{ã¡ã‚ˆã†}}\fbox{ã«}
+&
+$r_2\rightarrow g_2$\\
+$n_4$&行頭2グループ&
+\Large
+\vrule{\color{blue!50!black}\gt\ltjruby[post=1,mode=1,stretch=011]{æµ|暢}{りゆã†|ã¡ã‚ˆã†}}\fbox{ã«}
+&
+$W\rightarrow r_1\rightarrow g_2 \rightarrow r_2\rightarrow g_2$\\
+$n_5$&行中&
+\Large
+\fbox{ã‚’}{\color{blue!50!black}\gt\ltjruby[post=0.5,pre=0.5,mode=1]{æµ|暢}{りゆã†|ã¡ã‚ˆã†}}\fbox{ã«}
+&
+$g_0\rightarrow W\rightarrow r_1\rightarrow g_2 \rightarrow r_2\rightarrow g_2$\\
+
+\bottomrule
+\end{tabular}
+\caption{ルビã®çµ„ã¿æ–¹ã¨å¯¾å¿œã™ã‚‹ãƒŽãƒ¼ãƒ‰ä¸¦ã³}
+\label{fig:node}
+\end{figure}
+
+\item ãªãŠï¼Œ$r_i$é”ã®é«˜ã•ãƒ»æ·±ã•ã¯çµ„ã¿ä¸ŠãŒã£ãŸå¾Œã®ãã‚Œã§ã‚る.
+$g_i$,~$r_i$é”ã®å¹…ã¯ï¼Œå›³\nobreak\ref{fig:node}ã«ç¤ºã—ãŸã‚ˆã†ãªå¯¾å¿œã«æ²¿ã£ã¦ç®—出ã™ã‚‹ï¼Ž
+例ãˆã°ã“ã®å ´åˆï¼Œè¡Œä¸­å½¢$n_5$ã«å¯¾ã—ã¦
+\[
+ g_0+r_1+g_2+r_2+g_2 = 3\,\mathrm{zw}-(0.25\,\mathrm{zw}\times 2)=2.5\,\mathrm{zw}
+\]
+ã¨ã„ã†æ–¹ç¨‹å¼ãŒç«‹ã¤ï¼ˆzwã¯è¦ªæ–‡å­—全角ã®å¹…,進入é‡è¾¼ï¼‰ï¼Ž
+$n_1$ã‹ã‚‰$n_5$ã¾ã§è¨ˆ5本ã®æ–¹ç¨‹å¼ãŒç«‹ã¤ãŒï¼Œã“れらã¯Gau\ss ã®æ¶ˆåŽ»æ³•ã§è§£ãã“ã¨ãŒã§ãã¦
+$g_i$,~$r_i$é”ã®å¹…ãŒæ±‚ã¾ã‚‹ï¼Ž
+\item ã¾ãŸï¼Œãƒ«ãƒ“処ç†ã‚’統括ã—ã¦ã„ã‚‹whatsit~$W$ã®å€¤ã‚‚
+\[
+ \Node{whatsit $w$}{value: 2}\longrightarrow
+ \Node{vlist $n_1$}{末1}\longrightarrow
+ \Node{vlist $n_2$}{末2}\longrightarrow
+ \Node{vlist $n_3$}{é ­1}\longrightarrow
+ \Node{vlist $n_4$}{é ­2}\longrightarrow
+ \Node{vlist $n_5$}{中}
+\]
+ã«ç½®ãæ›ãˆã¦ãŠã.
+
+\end{enumerate}
+
+\item \LuaTeX ã®è¡Œåˆ†å‰²å‡¦ç†ã‚’普通ã«è¡Œã†ï¼Ž
+\item 行分割ã®çµæžœã«å¾“ã£ã¦ï¼Œ$g_i$,~$r_i$é”ã‚’é©åˆ‡ã«ç½®æ›ã™ã‚‹ï¼Ž
+
+例ãˆã°è¡Œåˆ†å‰²ã®çµæžœ
+\begin{gather*}
+ (\text{other nodes})\longrightarrow
+ \Node{glue $g_0$}{}\longrightarrow \Node{whatsit~$W$}{å…ƒã‹ã‚‰ã‚ã‚‹}\longrightarrow \Node{rule $r_1$}{}
+ \tag{è¡ŒA}\\
+\noalign{\hrulefill è¡Œã®å¢ƒç›®\hrulefill}
+\Node{rule $r_2$}{}\longrightarrow
+ \Node{glue $g_2$}{}\longrightarrow (\text{other nodes})\tag{è¡ŒB}
+\end{gather*}
+ã®ã‚ˆã†ã«ãªã£ãŸã¨ã—よã†ï¼Ž
+\begin{enumerate}
+\item 処ç†ã¯æ®µè½ã®ä¸Šã®è¡Œã‹ã‚‰é †ç•ªã«è¡Œã‚れる.行Aã®å‡¦ç†ãŒã¾ã‚ã£ã¦ããŸã¨ã—よã†ï¼Ž
+
+\item è¡ŒAã®å…ˆé ­ã‹ã‚‰é †ç•ªã«çœºã‚ã¦ã„ã.ã™ã‚‹ã¨ã€Œwhatsit~$W$ç”±æ¥ã€ã®ãƒŽãƒ¼ãƒ‰ï¼Œ$g_0$,~$W$,~$r_1$ãŒè¦‹ã¤ã‹ã‚Šï¼Œ
+è¡ŒAã¯ã“ã“ã§çµ‚ã‚ã£ã¦ã„る.
+
+ã¾ãšï¼Œè¡ŒAã®hboxã®ä¸­èº«ã‹ã‚‰whatsit~$W$を消去(リストã‹ã‚‰å–り除ãã ã‘ã§ï¼Œ$W$ã®ãƒ¡ãƒ¢ãƒªã‚’解放ã™ã‚‹ã‚ã‘ã§ã¯ãªã„)ã™ã‚‹ï¼Ž
+$g_0$,~($W$,)~$r_1$ã¨ã„ã†ãƒŽãƒ¼ãƒ‰ã®ä¸¦ã³ã¯ï¼Œã€Œè¡Œæœ«1グループã€$n_1$ã«å¯¾å¿œã—ã¦ã„ã‚‹ã®ã§ï¼Œ
+$g_0$,~$r_1$ã‚’è¡ŒAã‹ã‚‰é™¤åŽ»ãƒ»ãƒ¡ãƒ¢ãƒªè§£æ”¾ã—,代ã‚ã‚Šã«$n_1$ã‚’è¡ŒAã®ä¸­èº«ã«è¿½åŠ ã™ã‚‹ï¼Ž
+
+\item 次ã«è¡ŒBã®å‡¦ç†ã«ã†ã¤ã‚‹ï¼Žè¡ŒAã§ãƒ«ãƒ“ã®å‡¦ç†ã¯å®Œäº†ã—ã¦ã„ãªã„(2グループã®ãƒ«ãƒ“ãªã®ã«ã¾ã 1グループã—ã‹ä½¿ã£ã¦ã„ãªã„)ã®ã§ï¼Œ
+「whatsit~$W$ç”±æ¥ã€ã®ãƒŽãƒ¼ãƒ‰ãŒã„ãã¤ã‹è¡ŒB内ã«æ®‹ã£ã¦ã„ã‚‹ã¯ãšã§ã‚る.
+
+案ã®å®šï¼Œ$r_2$,~$g_2$ã¨ã„ã†ãƒŽãƒ¼ãƒ‰åˆ—ãŒè¦‹ã¤ã‹ã£ãŸï¼Žã“ã‚Œã¯ã€Œè¡Œé ­1グループã€$n_3$ã«å¯¾å¿œã—ã¦ã„ã‚‹ã®ã§ï¼Œ
+$r_2$,~$g_2$ã‚’è¡ŒBã‹ã‚‰é™¤åŽ»ãƒ»ãƒ¡ãƒ¢ãƒªè§£æ”¾ã—,代ã‚ã‚Šã«$n_3$ã‚’è¡ŒBã®ä¸­èº«ã«æŒ¿å…¥ã™ã‚‹ï¼Ž
+
+\item ã“ã‚Œã§2グループã¨ã‚‚使ã„切ã£ãŸã“ã¨ã«ãªã‚‹ã®ã§ï¼Œ
+隔離ã—ã¦ãŠã„ãŸ$W$を,(使ã‚ã‚Œãªã‹ã£ãŸ$n_2$,~$n_4$,~$n_5$ãªã©ã¨å…±ã«ï¼‰ãƒ¡ãƒ¢ãƒªè§£æ”¾ã™ã‚‹ï¼Žçµæžœã¨ã—ã¦
+次ã®ã‚ˆã†ã«ãªã£ãŸï¼š
+\begin{gather*}
+ (\text{other nodes})\longrightarrow
+ \Node{vlist $n_1$}{末1}\tag{行A}\\
+\noalign{\hrulefill è¡Œã®å¢ƒç›®\hrulefill}
+\Node{vlist $n_3$}{é ­1}\longrightarrow (\text{other nodes})\tag{è¡ŒB}
+\end{gather*}
+\end{enumerate}
+\end{enumerate}
+
+\newpage
+\section{ã„ãã¤ã‹ã®ä¾‹}
+\def\rubytest{\ruby{黄金橋}{ゴールデンゲートブリッジ}\relax}
+
+\setbox0=\vbox{\hsize=22\zw%
+ã‚ã‚ã‚ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“}
+%\directlua{ltj.ext_show_node_list(tex.box[0], '? ', print)}
+\fbox{\box0}
+
+\def\rubytest{\ruby{国府津}{ã“ã†ã¥}\relax}
+% グループルビ
+
+\setbox0=\vbox{\hsize=18\zw%
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“}
+%\directlua{ltj.ext_show_node_list(tex.box[0], '? ', print)}
+\fbox{\box0}
+
+\def\rubytest{\ruby{â—â—|â—†}{◆◆◆◆◆◆|â—â—â—}\relax}
+\setbox0=\vbox{\hsize=19\zw%
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“イ
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“ウ
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“エ
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“}
+%\directlua{ltj.ext_show_node_list(tex.box[0], '? ', print)}
+\fbox{\box0}
+
+\def\rubytest{\ruby{â—â—|â–¡}{◆◆◆|â—â—â—}\relax}
+\setbox0=\vbox{\hsize=19\zw%
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“イ
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“ウ
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“エ
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“}
+%\directlua{ltj.ext_show_node_list(tex.box[0], '? ', print)}
+\fbox{\box0}
+
+\def\rubytest{\ruby{ç•°|様}{ã„|よã†}\relax}
+\setbox0=\vbox{\hsize=19\zw%
+ã‚\rubytest ã„ã†ãˆãã‘
+ã‚\rubytest ã„ã†ãˆãã‘ã“
+ã‚\rubytest ã„ã†ãˆãã‘ã“
+ã‚\rubytest ã„ã†ãˆãã‘ã“イ
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“}
+%\directlua{ltj.ext_show_node_list(tex.box[0], '? ', print)}
+\fbox{\box0}
+
+\def\rubytest{\ruby{â–¡|â– |â–¡}{â– â– |â–¡â–¡â–¡|â– â– }\relax}
+
+\setbox0=\vbox{\hsize=23\zw%
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†â–¡ãŠã‹ããã‘ã“ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†â–¡ãŠã‹ããã‘ã“ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†â–¡ãŠã‹ããã‘ã“ã†ãˆãŠã‹ããã‘ã“
+ã‚\rubytest ã„ã†ãˆãŠã‹ããã‘ã“}
+\fbox{\box0}
+
+\begin{description}
+\def\sample{åˆ\ruby{承}{ã†ã‘ãŸã¾ã‚}ã‚‹\quad \ruby{ç–Ž}{ã}\quad ã¯\ruby{ä¿„}{ã«ã‚ã‹}勉強
+ \quad 後\ruby{ä¿„}{ã«ã‚ã‹}勉強\quad ã¯\ruby{æš}{ã‚ã‹ã¤ã}ã«
+ ã¯\ruby{ä¿„}{ã«ã‚ã‹}ã«
+ \quad \ruby{休|憩|中}{ãゆã†|ã‘ã„|ã¡ã‚†ã†}ã‹ã¤\ruby{視|è´|中}{ã—|ã¡ã‚ˆã†|ã¡ã‚†ã†}}
+\item[標準] \sample
+\item[è‚©ã¤ã] {\ltjsetruby{kata}\sample}
+\end{description}
+
+\newpage
+\begin{LTXexample}[pos=t]
+{\ltjsetruby{stretch=101}% 親文字å‡ç­‰å‰²ã‚Šç¦æ­¢
+ \ruby{休|憩|中}{ãゆã†|ã‘ã„|ã¡ã‚†ã†}ã‹ã¤\ruby{視|è´|中}{ã—|ã¡ã‚ˆã†|ã¡ã‚†ã†}%
+}\quad
+\textgt{\ruby{勉|å¼·}{ã¹ã‚“|ãよã†}ã¨%
+ \ruby[fontcmd=\mcfamily]{勉|å¼·}{ã¹ã‚“|ãよã†}}\quad% ルビã¯æ˜Žæœä½“
+\ruby{コギト・エルゴ・スム}{Cogito ergo sum}\quad % 欧文空白ã¯ä¼¸é•·ã—ãªã„
+\ruby[size=1]{Cogito ergo sum}{コギト・エルゴ・スム}% 欧文空白ã¯ä¼¸é•·ã—ãªã„
+\end{LTXexample}
+
+\newpage
+\section{『日本語組版処ç†ã®è¦ä»¶ã€20120403ã®ä¾‹}
+
+\newcommand*{\噂}{\CID{7642}}
+\newcommand*{\倦}{\CID{7674}}
+%================================== 横組
+\paragraph{3.3.1節}\
+\begin{LTXexample}[pos=t]
+\obeylines
+3.49 \ruby{å›|å­}{ãã‚“|ã—}ã¯\ruby{å’Œ}{ã‚}ã—ã¦\ruby{åŒ}{ã©ã†}ãœãš
+3.50 \ruby{人}{ã²ã¨}ã«\ruby{誨}{ãŠã—}ãˆã¦\ruby{\倦}{ã†}ã¾ãš
+% モノルビ.é¢å€’ã§ã‚‚複数回ã®å®Ÿè¡ŒãŒå¿…è¦
+3.51 \ruby{鬼}{ã}\ruby{é–€}{ã‚‚ã‚“}ã®\ruby{æ–¹}{ã»ã†}\ruby{角}{ãŒã}ã‚’%
+ \ruby{å‡}{ãŽã‚‡ã†}\ruby{視}{ã—}ã™ã‚‹
+% 熟語ルビ
+3.52 \ruby{鬼|é–€}{ã|ã‚‚ã‚“}ã®\ruby{æ–¹|角}{ã»ã†|ãŒã}ã‚’\ruby{å‡|視}{ãŽã‚ˆã†|ã—}ã™ã‚‹
+3.53 \ruby{茅場町}{ã‹ã‚„ã°ã¡ã‚ˆã†}\quad\ruby{茅|å ´}{ã‹ã‚„|ã°}\ruby{町}{ã¡ã‚ˆã†}
+% 熟字訓
+3.54 \ruby{紫陽花}{ã‚ã˜ã•ã„}\quad\ruby{å©å }{ã‚‹ã¤ã¼}\quad\ruby{田舎}{ã„ãªã‹}
+% グループルビ
+3.55 \ruby{模型}{モデル}\quad\ruby{顧客}{クライアント}\quad%
+ \ruby{境界é¢}{インターフエース}\quad\ruby{é¿é›£æ‰€}{アジール}
+3.56 \ruby{編集者}{editor}\quad \ruby{editor}{エデイター}
+\end{LTXexample}
+
+\paragraph{3.3.3節}\
+\begin{LTXexample}[pos=t]
+\obeylines
+3.58 ã«\ruby{幟}{ã®ã¼ã‚Š}ã‚’\quad ã«\ruby[kata]{幟}{ã®ã¼ã‚Š}ã‚’\quad%
+ \ruby{韋}{ã„}\ruby{ç·¨}{ã¸ã‚“}\ruby{三}{ã•ã‚“}\ruby{絶}{ãœã¤}
+% 三分ルビ.JY3/mc/mc ã¯æœ¬æ–‡æ›¸ã®ãƒ—リアンブルã§ç‹¬è‡ªã«å®šç¾©
+3.59 ã«\ruby[fontcmd=\kanjifamily{mc}\kanjiseries{mc}]{幟}{ã®ã¼ã‚Š}ã‚’
+% ルビ文字をå°ã•ãã™ã‚‹
+3.60 {\Large%
+ \ruby{韋}{ã„}\ruby{ç·¨}{ã¸ã‚“}\ruby{三}{ã•ã‚“}\ruby{絶}{ãœã¤}\quad% 比較用
+ \ltjsetruby{size=0.375}% 0.5 -> 0.375
+ \ruby{韋}{ã„}\ruby{ç·¨}{ã¸ã‚“}\ruby{三}{ã•ã‚“}\ruby{絶}{ãœã¤}}
+\end{LTXexample}
+
+\paragraph{3.3.4節}
+3.61図(両å´ãƒ«ãƒ“)ã¯æœªã‚µãƒãƒ¼ãƒˆã«ã‚ˆã‚Šçœç•¥
+
+\newpage
+\paragraph{3.3.5節 モノルビ}\
+\begin{LTXexample}[pos=t]
+\obeylines
+3.62 ã®\ruby{葯}{ã‚„ã}ã«
+3.63 版é¢ã®\ruby{地}{ã¡}ã«\quad 版é¢ã®\ruby[kata]{地}{ã¡}ã«
+% 横組肩ã¤ãã¯ã—ãªã„ãŒï¼Œç¾çŠ¶ã§ã¯ç¸¦çµ„未サãƒãƒ¼ãƒˆã ã—,仕方ãªã„ã­
+3.65 ã®\ruby{ç ¦}{ã¨ã‚Šã§}ã«
+{\ltjsetruby{kata}%
+3.66上 ã®\ruby{æ—¬}{ã—ゆん}ã«\quad 後\ruby{æ—¬}{ã—ゆん}ã«
+3.66下 ã®\ruby{æ—¬}{ã—ゆん}åˆ\quad 後\ruby{æ—¬}{ã—ゆん}åˆ}
+\end{LTXexample}
+
+
+\paragraph{3.3.6節 グループルビ}\
+\begin{LTXexample}[pos=t]
+\obeylines
+3.67 ã¯\ruby{冊å­ä½“}{コーデツクス}ã¨
+3.68 \ruby{模型}{モデル}\quad \ruby{利用許諾}{ライセンス}
+% 両端をæƒãˆã‚‹æµå„€
+3.69 {\ltjsetruby{stretchruby=010}%
+ \ruby{模型}{モデル}\quad \ruby{利用許諾}{ライセンス}}
+% ルビãŒæ¥µç«¯ã«çŸ­ã„å ´åˆ
+3.70 \ruby{ãªã’ãã®è–æ¯åƒ}{ピエタ}\quad% ルビ全角ã¾ã§è¨±å®¹
+ \ruby[maxmargin=0.75]{ãªã’ãã®è–æ¯åƒ}{ピエタ}% ルビ全角1.5å€ã¾ã§
+% ルビãŒé•·ã„å ´åˆ
+3.71 \ruby{顧客}{クライアント}\quad \ruby{境界é¢}{インターフエース}
+3.72 {\ltjsetruby{stretch=010, stretchbol=010, stretcheol=010}% ã¯ã¿å‡ºã•ãªã„æµå„€
+ \ruby{顧客}{クライアント}\quad \ruby{境界é¢}{インターフエース}}
+\end{LTXexample}
+
+\newpage
+\paragraph{3.3.7節 熟語ルビ}\
+\begin{LTXexample}[pos=t]
+\obeylines
+3.73 \ruby{æž|憂}{ã|ゆã†}\quad \ruby{ç•|怖}{ã„|ãµ}\quad%
+ \ruby[kata]{æž|憂}{ã|ゆã†}\quad \ruby[kata]{ç•|怖}{ã„|ãµ}
+3.74 ã®\ruby{æµ|å„€}{りゆã†|ãŽ}ã‚’\quad ã®\ruby{ç„¡|常}{ã‚€|ã˜ã‚ˆã†}ã‚’\quad%
+ ã®\ruby{æˆ|å°±}{ã˜ã‚ˆã†|ã˜ã‚†}ã‚’\quad ã®\ruby{ç´‹|ç« }{ã‚‚ã‚“|ã—よã†}ã‚’\quad%
+ ã®\ruby{象|å¾´}{ã—よã†|ã¡ã‚ˆã†}ã‚’
+% 熟語ã®æ§‹æˆã‚’考慮ã—ãŸæ–¹æ³•ã¯ç¾è¡Œã§ã¯ã§ããªã„.
+% 行分割ã¯ã§ãã‚‹ã®ã ãŒï¼Œã€Œä»–ã®æ¼¢å­—ã«ãƒ«ãƒ“全角ã¾ã§ã‹ã‹ã£ã¦è‰¯ã„ã€ã¯é›£ã—ã„.
+3.75 {\ltjsetruby{kata}%
+ ã®\ruby{æµ|å„€}{りゆã†|ãŽ}ã‚’\quad ã®\ruby{ç„¡|常}{ã‚€|ã˜ã‚ˆã†}ã‚’\quad%
+ ã®\ruby{æˆ|å°±}{ã˜ã‚ˆã†|ã˜ã‚†}ã‚’\quad ã®\ruby{ç´‹|ç« }{ã‚‚ã‚“|ã—よã†}ã‚’\quad%
+ ã®\ruby{象|å¾´}{ã—よã†|ã¡ã‚ˆã†}ã‚’}
+% モノルビé…置.望ã¾ã—ããªã„
+3.76× ã®\ruby{æµ}{りゆã†}\ruby{å„€}{ãŽ}ã‚’\quad ã®\ruby{ç„¡}{ã‚€}\ruby{常}{ã˜ã‚ˆã†}ã‚’\quad%
+
+è¦èª¿æ•´ 3.77\ {\ltjsetruby{stretchbol=121, stretcheol=121}% 行頭・行末æƒãˆãš
+ \hbox{\vrule\vbox{\hsize=10\zw ã‚ã‚ã‚ã‚ã‚ã‚ã‚ã‚ã®%
+ \ruby{æµ|å„€}{りゆã†|ãŽ}ãŒã‚る.}\vrule}\textbf{â†ãªãœæ”¹è¡Œã§ããªã„}\quad%
+ \hbox{\vrule\vbox{\hsize=5\zw ……等ã®\ruby{ç„¡|常}{ã‚€|ã˜ã‚ˆã†}ã‚’}\vrule}}
+\end{LTXexample}
+
+\paragraph{3.3.8節 ルビã¯ã¿å‡ºã—}\
+\begin{LTXexample}[pos=t]
+\obeylines
+3.78 \ruby{人}{ã²ã¨}ã¯\ruby{æ­»}{ã—}ã—ã¦\ruby{å}{ãª}ã‚’\ruby{残}{ã®ã“}ã™
+% ç¾åœ¨ã®è‡ªå‹•è¨­å®šã®ä»•æ§˜ã§ã¯ã€Œè„šã€ã®å‰ãŒå››åˆ†ã ã‘「è¦ä»¶ã€ã®ä¾‹ã‚ˆã‚Šç©ºã
+3.79 漢字ã®éƒ¨é¦–ã«ã¯\ruby{å}{ã¸ã‚“}・\ruby{冠}{ã‹ã‚“むり}・\ruby{è„š}{ãã‚„ã}・%
+ \ruby{æ—}{ã¤ãã‚Š}ãŒã‚ã‚‹
+3.79 漢字ã®éƒ¨é¦–ã«ã¯\ruby{å}{ã¸ã‚“},\ruby{冠}{ã‹ã‚“むり},\ruby{è„š}{ãã‚„ã},%
+ \ruby{æ—}{ã¤ãã‚Š}ãŒã‚ã‚‹
+\end{LTXexample}
+\begin{LTXexample}[pos=t]
+\obeylines
+% ã‚‚ã¡ã‚ん手動ã§é€²å…¥é‡ã‚’指定ã™ã‚Œã°è©±ã¯åˆ¥
+3.79 漢字ã®éƒ¨é¦–ã«ã¯\ruby{å}{ã¸ã‚“}・\ruby{冠}{ã‹ã‚“むり}・\ruby[pre=1]{è„š}{ãã‚„ã}・%
+ \ruby{æ—}{ã¤ãã‚Š}ãŒã‚ã‚‹
+3.79 漢字ã®éƒ¨é¦–ã«ã¯\ruby{å}{ã¸ã‚“},\ruby{冠}{ã‹ã‚“むり},\ruby[pre=1]{è„š}{ãã‚„ã},%
+ \ruby{æ—}{ã¤ãã‚Š}ãŒã‚ã‚‹
+3.79 ã“ã®\ruby{\噂}{ã†ã‚ã•}ã®å¥½ããªäººã¯\ruby{æ‡}{ãµã¨ã“ã‚}ãã‚ã„もよãã€\ruby{檜}{ã²ã®ã}ã‚’
+3.80 漢字ã®éƒ¨é¦–ã«ã¯ã€Œ\ruby{å}{ã¸ã‚“}ã€ã€Œ\ruby{冠}{ã‹ã‚“むり}ã€ã€Œ\ruby{è„š}{ãã‚„ã}ã€%
+「\ruby{æ—}{ã¤ãã‚Š}ã€ãŒã‚ã‚‹
+3.80 ã“ã®\ruby{\噂}{ã†ã‚ã•}好ããªäººã¯\ruby{æ‡}{ãµã¨ã“ã‚}å…·åˆã‚‚よãã€\ruby{檜}{ã²ã®ã}æã‚’
+3.81× ã«\ruby{æš}{ã‚ã‹ã¤ã}ã®\kern-1\zw ã®\ruby{趣}{ãŠã‚‚ã‚€ã}ã‚’
+3.82 ã«\ruby{æš}{ã‚ã‹ã¤ã}ã®\ruby{趣}{ãŠã‚‚ã‚€ã}ã‚’
+
+% 漢字ã«ãƒ«ãƒ“ã‚’2分ã¾ã§æŽ›ã‘ã¦ã‚‚良ã„æµå„€
+{%
+ \ltjsetparameter{rubypostintrusion={`好,0.5}}
+ \ltjsetparameter{rubypostintrusion={`å…·,0.5}}
+ \ltjsetparameter{rubypostintrusion={`æ,0.5}}
+3.83 ã“ã®\ruby{\噂}{ã†ã‚ã•}ã®å¥½ããªäººã¯\ruby{æ‡}{ãµã¨ã“ã‚}ãã‚ã„もよãã€\ruby{檜}{ã²ã®ã}ã‚’
+3.83 ã“ã®\ruby{\噂}{ã†ã‚ã•}好ããªäººã¯\ruby{æ‡}{ãµã¨ã“ã‚}å…·åˆã‚‚よãã€\ruby{檜}{ã²ã®ã}æã‚’
+}
+% 平仮åã«ã‚‚ルビを掛ã‘ãªã„æµå„€
+{\catcode`\<12%
+ \makeatletter\count@="3040\loop\relax\ifnum \count@<"30A0%
+ \ltjsetparameter{rubypreintrusion={\the\count@,0}, %
+ rubypostintrusion={\the\count@,0}}%
+ \advance\count@1 \repeat
+3.84 ã“ã®\ruby{\噂}{ã†ã‚ã•}ã®å¥½ããªäººã¯\ruby{æ‡}{ãµã¨ã“ã‚}ãã‚ã„もよãã€\ruby{檜}{ã²ã®ã}ã‚’
+3.84 ã“ã®\ruby{\噂}{ã†ã‚ã•}好ããªäººã¯\ruby{æ‡}{ãµã¨ã“ã‚}å…·åˆã‚‚よãã€\ruby{檜}{ã²ã®ã}æã‚’
+}
+\end{LTXexample}
+\begin{LTXexample}[pos=t]
+\obeylines
+3.85\ {\ltjsetruby{stretchbol=121, stretcheol=121}% 行頭・行末æƒãˆãš
+\hbox{\vrule\vbox{\hsize=15\zw
+ \hskip9.5\zw……ã®\ruby{徑}{ã“ã¿ã¡}を……%
+\hskip9\zw……ã®\ruby{徑}{ã“ã¿ã¡}を……}\vrule}}
+3.86\ \hbox{\vrule\vbox{\hsize=15\zw
+ \hskip10\zw……ã®\ruby{徑}{ã“ã¿ã¡}を……%
+\hskip9\zw……ã®\ruby{徑}{ã“ã¿ã¡}を……}\vrule}
+3.87\ \hbox{\vrule\vbox{\hsize=15\zw
+ \hskip8\zw……共\ruby{飾り}{アクセサリー}等……%
+\hskip9\zw……共\ruby{飾り}{アクセサリー}等……}\vrule}
+\end{LTXexample}
+
+
+\paragraph{åœç‚¹ã®ä¾‹ï¼ˆå¸¸ç”¨æ¼¢å­—表å‰æ›¸ãより)}
+ã“ã®è¡¨ã¯ï¼Œæ³•ä»¤ï¼Œå…¬â½¤â½‚書,新èžï¼Œé›‘誌,放é€ãªã©ï¼Œâ¼€èˆ¬ã®ç¤¾ä¼šâ½£æ´»ã«ãŠã„%
+ã¦\kenten[kenten=ï¹…]{ç¾ä»£ã®å›½èªžã‚’書ã表ã™}å ´åˆã®\kenten{漢字使⽤ã®â½¬å®‰ã‚’â½°ã™}ã‚‚ã®ã§ã‚る。
+
+\subparagraph{「﹅ã€ã®å¤§ãã•ã‚’親文字ã®0.33å€ã«ã—ãŸä¾‹}
+ã“ã®è¡¨ã¯ï¼Œæ³•ä»¤ï¼Œå…¬â½¤â½‚書,新èžï¼Œé›‘誌,放é€ãªã©ï¼Œâ¼€èˆ¬ã®ç¤¾ä¼šâ½£æ´»ã«ãŠã„%
+ã¦\kenten[size=0.33, kenten=ï¹…]{ç¾ä»£ã®å›½èªžã‚’書ã表ã™}å ´åˆã®\kenten{漢字使⽤ã®â½¬å®‰ã‚’â½°ã™}ã‚‚ã®ã§ã‚る。
+\end{document}
diff --git a/macros/luatex/generic/luatexja/doc/luatexja-zhfonts.pdf b/macros/luatex/generic/luatexja/doc/luatexja-zhfonts.pdf
new file mode 100644
index 0000000000..6b6ee65fdf
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/luatexja-zhfonts.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/luatexja-zhfonts.tex b/macros/luatex/generic/luatexja/doc/luatexja-zhfonts.tex
new file mode 100644
index 0000000000..e220c0de05
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/luatexja-zhfonts.tex
@@ -0,0 +1,280 @@
+\documentclass[DIV=13]{article}
+\usepackage{typearea}
+\usepackage{hologo}
+\makeatletter
+\def\verbatim{\@verbatim \frenchspacing\@vobeyspaces\luatexlocalleftbox{\hskip3\zw} \@xverbatim}
+\makeatother
+\def\pTeX{p\TeX}
+\def\LuaTeX{Lua\TeX}
+\def\XeTeX{\hologo{XeTeX}}
+\def\ConTeXt{Con\TeX t}
+\usepackage{booktabs}
+\usepackage{multicol}
+\usepackage{indentfirst}
+\usepackage{luatexja-fontspec}
+\parindent2\zw
+\linespread{1.25}
+\setmainjfont{FandolSong}
+\title{\textbf{\LuaTeX-ja简体中文字体é…ç½®}}
+\author{马起园\hskip2.5\zw è‹ã€€æ°}
+\date{2013年5月}
+\begin{document}
+\maketitle
+\section{\LuaTeX-ja项目简介}
+\LuaTeX-ja项目旨在将\pTeX 处ç†æ±‰å­—的机制åŠç›¸å…³åŠŸèƒ½ç§»æ¤åˆ°\LuaTeX 下,当å‰é¡¹ç›®
+çš„æˆå‘˜æœ‰ï¼šåŒ—å·å¼˜å…¸ã€å‰ç”°ä¸€è´µã€å…«ç™»å´‡ä¹‹ã€é»‘木裕介 ã€é˜¿éƒ¨çºªè¡Œã€å±±æœ¬å®—å®ã€æœ¬ç”°çŸ¥
+亮ã€æ–‹è—¤ä¿®ä¸‰éƒŽå’Œé©¬èµ·å›­ã€‚
+
+\LuaTeX 虽然在编ç ä¸Šæ”¯æŒUnicode,但并ä¸èƒ½ç›´æŽ¥å¤„ç†æ±‰å­—断行以åŠç¦åˆ™åº”用,而
+在\pTeX 系列中则能够处ç†æ–­è¡Œå¹¶åº”用ç¦åˆ™ï¼Œä½†å¹¶ä¸æ”¯æŒPDF输出。\LuaTeX 下处ç†
+汉字的断行和应用ç¦åˆ™éœ€è¦ä½¿ç”¨å…¶å†…建的诸多callbackæ¥è¿›è¡Œã€‚\pTeX 扩展TFM为JFM,
+但是JFM抽象程度更高,该文件涉åŠåˆ°çš„内容是字体的标点压缩,å¯ä»¥ç”¨äºŽå¤šä¸ªæ±‰å­—字体。
+
+当å‰ç‰ˆæœ¬çš„\LuaTeX-ja å¯ä»¥åº”用于\TeX\ Liveå’ŒW32\TeX,在旧版本MikTeX下使用会
+出问题,因为MikTeX下的\LuaTeX 存在编译上的bug。
+
+\section{字体使用}
+
+\subsection{关于\LuaTeX-ja的字体调用}
+
+\XeTeX 在调用字体的时候需è¦ä½¿ç”¨freetypeå’Œfontconfig库,所以需è¦æ›´æ–°å­—体缓
+存,但是在\LuaTeX 下就ä¸å¤ªä¸€æ ·ã€‚\LuaTeX åªéœ€è¦åœ¨åˆæ¬¡ä½¿ç”¨çš„时候刷新字体数æ®
+库å³å¯ï¼ˆæ­¤æ•°æ®åº“是一个lua文件)。\LuaTeX 下的字体缓存实际上是将字体的å„ç§
+ä¿¡æ¯å¯¼å‡ºå¹¶ä¿å­˜çš„文件,在调用一个新字体的时候会生æˆä¸€ä¸ªã€‚\LuaTeX 对于字体的
+处ç†å¹¶æ²¡æœ‰ä½¿ç”¨freetype,而是使用了fontforge,ä¸è¿‡å¯èƒ½ç”±äºŽè¯¥åº“的接å£æœ‰ä¸€äº›
+问题,导致部分字体无法在\LuaTeX 下使用。
+
+在使用\LuaTeX-ja的时候,需è¦å…ˆåˆ·æ–°å­—体数æ®åº“,该命令的使用方法如下:
+\begin{verbatim}
+Usage: mkluatexfontdb [OPTION]...
+
+Rebuild the LuaTeX font database.
+
+Valid options:
+ -f --force force re-indexing all fonts
+ -q --quiet don't output anything
+ -v --verbose=LEVEL be more verbose (print the searched directories)
+ -vv print the loaded fonts
+ -vvv print all steps of directory searching
+ -V --version print version and exit
+ -h --help print this message
+\end{verbatim}
+
+在新版本的\texttt{luaotfload}包中,æ供了新的命令\texttt{luaotfload-tool},
+但如上所述的\texttt{mkluatexfontdb}ä¾ç„¶èƒ½å¤Ÿä½¿ç”¨ã€‚
+
+åˆæ˜¯å¯èƒ½é‡åˆ°é€šä¸è¿‡çš„字体,需è¦å°†è¿™ä¸ªå­—体的ç»å¯¹è·¯å¾„添加到\texttt{luaotfload-blacklist.cnf}中,
+这个文件的内容如下:
+\begin{verbatim}
+% Takes ages to load
+LastResort.ttf % a MacOSX font, but also available for free from unicode.org
+% Segfaults under LuaTeX 0.76
+lingoes.ttf
+% http://tug.org/pipermail/luatex/2013-May/004239.html
+Diablindall.ttf
+spltfgbd.ttf
+spltfgbi.ttf
+spltfgit.ttf
+spltfgrg.ttf
+\end{verbatim}
+
+如果你在\texttt{texmf-local}下添加了æŸäº›ç§æœ‰å­—体,请åŠæ—¶è¿è¡Œ\texttt{texhash},
+这样能够方便在è¿è¡Œ\LuaTeX 的时候能够通过kpathsea库找到他们。
+
+Lua\TeX 调用TrueTypeå’ŒOpenType字体并没有固定的方å¼ï¼Œ\XeTeX 使用了固定的接å£ï¼Œ
+而Lua\TeX 需è¦ä½¿ç”¨luaotfload包æ¥è¿›è¡Œå­—体的调用。这两ç§å­—体一般都有高级特性,
+在\TeX\ Live或者W32\TeX 中å¯ä»¥ä½¿ç”¨\texttt{otfinfo}命令æ¥æŸ¥çœ‹ç›¸å…³çš„ä¿¡æ¯ï¼š
+\begin{verbatim}
+'Otfinfo' reports information about an OpenType font to standard output.
+Options specify what information to print.
+
+Usage: otfinfo [-sfzpg | OPTIONS] [OTFFILES...]
+
+Query options:
+ -s, --scripts Report font's supported scripts.
+ -f, --features Report font's GSUB/GPOS features.
+ -z, --optical-size Report font's optical size information.
+ -p, --postscript-name Report font's PostScript name.
+ -a, --family Report font's family name.
+ -v, --font-version Report font's version information.
+ -i, --info Report font's names and designer/vendor info.
+ -g, --glyphs Report font's glyph names.
+ -t, --tables Report font's OpenType tables.
+ -T, --dump-table NAME Output font's 'NAME' table.
+
+Other options:
+ --script=SCRIPT[.LANG] Set script used for --features [latn].
+ -V, --verbose Print progress information to standard error.
+ -h, --help Print this message and exit.
+ -q, --quiet Do not generate any error messages.
+ --version Print version number and exit.
+
+Report bugs to <ekohler@gmail.com>.
+\end{verbatim}
+
+\subsection{使用字体的方法}
+
+ç›®å‰\LuaTeX-ja支æŒåœ¨plain \TeX å’Œ\LaTeX 下使用。如果你使用texinfo,那么很
+ä¸å¹¸ï¼Œä½ ä¸å¤ªå¯èƒ½ä½¿ç”¨\LuaTeX-jaæ¥å¤„ç†ä¸­æ–‡ï¼Œå› ä¸ºtexinfo是针对pdf\TeX 设计的,
+在\LuaTeX 下使用已ç»æœ‰äº†ä¸€å®šçš„ä¸å…¼å®¹çŽ°è±¡ï¼Œå³ä½¿å®Œå…¨å…¼å®¹ä¹Ÿéœ€è¦å¯¹texinfo中的
+字体é…置进行调整,如果你急需使用texinfoæ¥å¤„ç†ä¸­æ–‡ï¼Œè¯·å°è¯•W32\TeX 下的texinfo,
+这个å‘行版中的texinfoå·²ç»æ‰“了补ä¸ã€‚对于\ConTeXt 用户,请使用æŽå»¶ç‘žçš„zhfonts模å—
+\footnote{è§https://github.com/liyanrui/zhfonts}。
+
+在plain \TeX 中使用Lua\TeX-jaå¯ä»¥åœ¨æºæ–‡ä»¶ä¸­å†™å…¥ï¼š
+\begin{verbatim}
+\input luatexja-core.sty
+\end{verbatim}
+
+Lua\TeX-ja移æ¤çš„了\verb!\jfont!命令,在plain \TeX 下需è¦é€šè¿‡è¯¥å‘½ä»¤æ¥
+控制输出的汉字字体,例如:
+\begin{verbatim}
+\jfont\song={name:SimSun:jfm=banjiao} at 10pt
+\song 我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“。
+\end{verbatim}
+
+上文中的\verb!jfm=banjiao!使用æ¥æŽ§åˆ¶æ ‡ç‚¹åŽ‹ç¼©çš„,如果此项未设定,则
+使用默认的\verb!ujis!压缩模å¼ï¼Œå¯¹äºŽç®€ä½“中文æ¥è®²ï¼Œå¯ç”¨çš„模å¼æœ‰ï¼š
+\texttt{quanjiao,banjiao,kaiming, CCT}。
+
+而在\LaTeX 下使用则较为简å•ï¼Œä½¿ç”¨ï¼š
+\begin{verbatim}
+\usepackage{luatexja-fontspec}
+\end{verbatim}
+这个包对fontspec包进行了å°è£…,令其能够较为便利地设定汉字字体。
+这个包æ供的命令如下:
+\begin{table}[htbp]
+ \centering
+ \begin{tabular}{ll}
+ \toprule
+ \multicolumn{1}{c}{\textbf{命令}} & \multicolumn{1}{c}{\textbf{用途}} \\
+ \midrule
+ \verb!\jfontspec! & 改å˜å½“å‰æ±‰å­—字体 \\
+ \verb!\setmainjfont! & 设定文档主汉字字体 \\
+ \verb!\setsansjfont! & 设定文档的无衬线汉字字体(黑体) \\
+ \verb!\newjfontfamily! & 设定新的汉字字体æ—命令 \\
+ \verb!\newjfontface! & 设定新的汉字字体命令 \\
+ \verb!\defaultjfontfeatures! & 默认汉字字体的特性 \\
+ \verb!\addjfontfeatures! & 设定当å‰å­—体的特性 \\
+ \bottomrule
+ \end{tabular}%
+\end{table}%
+
+\subsection{ä¸å¯ç”¨å­—体系列}
+
+中文字体在丰度上与日文字体对比并ä¸å ä¼˜åŠ¿ï¼Œæ‰€ä»¥ä¸­æ–‡\TeX 文档在使用使用字体
+上没有太大å˜åŒ–。当你想在\LuaTeX-ja下是有部分特色字体的时候,请åšå¥½æ­¤ç§å­—体
+å¯èƒ½æ— æ³•ä½¿ç”¨çš„准备。目å‰æŠ¥é”™æ˜Žæ˜¾çš„字体有数个:
+\begin{itemize}
+\item çµæ ¼æ–¯è¯å…¸é™„带的音标字体,这些字体会安装到系统字体文件夹下,在更新
+ 字体数æ®åº“的时候会出现程åºå´©æºƒçš„情况,这是字体本身的原因,需è¦æ·»åŠ åˆ°é»‘åå•ä¸­
+\item 康熙字典体,这是中国大陆一ä½ä¸šä½™å­—体设计者所设计的字体,由于该作者
+ 缺ä¹ç›¸å…³æŠ€æœ¯çŸ¥è¯†ï¼Œå¯¼è‡´æ­¤å­—体的CMap出错,无论是完全版还是试用版都会出现
+ 问题,此外该字体的boundingbox也是错误的,在嵌入pdf文档中å分影å“阅读
+\item 信黑体,这个字体也是CMap的问题,无法使用
+\end{itemize}
+\subsection{Fandol字体系列}
+Fandol系列字体由本文档两ä½ä½œè€…è”åˆå¼€å‘,å«æœ‰æ•°ç§æ ·å¼ã€‚
+该套字体å¯ä»¥åœ¨TeXLive下进行更新。
+
+\begin{table}[htbp]
+ \centering
+ \begin{tabular}{lll}
+ \toprule
+ \multicolumn{1}{c}{\textbf{字体å}} & \multicolumn{1}{c}{\textbf{文件å}} & \multicolumn{1}{c}{\textbf{样例}} \\
+ \midrule
+ FandolSong-Regular & \texttt{FandolSong-Regular.otf} & {我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ FandolSong-Bold & \texttt{FandolSong-Bold.otf} & {\bf 我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ FandolHei-Regular & \texttt{FandolHei-Regular.otf} & {\jfontspec{FandolHei-Regular}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ FandolHei-Bold & \texttt{FandolHei-Bold.otf} & {\jfontspec{FandolHei-Bold}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ FandolFang-Regular & \texttt{FandolFang-Regular.otf} & {\jfontspec{FandolFang-Regular}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“}\\
+ FandolKai-Regular & \texttt{FandolKai-Regular} & {\jfontspec{FandolKai-Regular}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“}\\
+ \bottomrule
+ \end{tabular}%
+\end{table}%
+
+
+\subsection{åŽæ–‡å­—体系列}
+在微软æ供的Office套装中附带了一定数é‡çš„中文字体,
+这些字体是常州åŽæ–‡å°åˆ·æ–°æŠ€æœ¯æœ‰é™å…¬å¸åˆ¶é€ çš„。
+这些字体安装在系统字体文件夹下,在使用\LuaTeX-ja 的时候
+å¯ä»¥é…Œæƒ…使用。在本文档中,我们推è简体中文用户使用
+此套字体,从使用率上看,å„大学都会装有微软的æ“作系统
+和微软的Office,å¯ä»¥è¯´å·²ç»ç›¸å½“æ™®åŠï¼Œæ•…åšæŽ¨è。
+
+\begin{table}[htbp]
+ \centering
+ \begin{tabular}{llll}
+ \toprule
+ \multicolumn{1}{c}{\textbf{字体å}} & \multicolumn{1}{c}{\textbf{文件å}} & \multicolumn{1}{c}{\textbf{PostScriptå}} & \multicolumn{1}{c}{\textbf{样例}} \\
+ \midrule
+ åŽæ–‡å®‹ä½“ & \texttt{STSONG.TTF} & STSong & {\jfontspec{STSong}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ åŽæ–‡ä¸­å®‹ & \texttt{STZHONGS.TTF} & STZhongsong & {\jfontspec{STZhongsong}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ åŽæ–‡ç»†é»‘ & \texttt{STXIHEI.TTF} & STXihei & {\jfontspec{STXihei}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ åŽæ–‡æ¥·ä½“ & \texttt{STKAITI.TTF} & STKaiti & {\jfontspec{STKaiti}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ åŽæ–‡ä»¿å®‹ & \texttt{STFANGSO.TTF} & STFangsong & {\jfontspec{STFangsong}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ \bottomrule
+ \end{tabular}%
+\end{table}
+
+\subsection{中易字体系列}
+在Windows系统简体中文版中,附带了数ç§ä¸­æ–‡å­—体。
+这些字体为中易中标电å­ä¿¡æ¯æŠ€æœ¯æœ‰é™å…¬å¸åˆ¶é€ çš„。
+åŒæˆ‘们强烈推è的第一ç§æ–¹æ¡ˆæ¯”较,没有中宋。
+如果按照CCT的传统,一般使用黑体替æ¢ã€‚
+
+\begin{table}[htbp]
+ \centering
+ \begin{tabular}{llll}
+ \toprule
+ \multicolumn{1}{c}{\textbf{字体å}} & \multicolumn{1}{c}{\textbf{文件å}} & \multicolumn{1}{c}{\textbf{PostScriptå}} & \multicolumn{1}{c}{\textbf{样例}} \\
+ \midrule
+ 宋体 & \texttt{simsun.ttc} & SimSun & {\jfontspec{SimSun}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ 黑体 & \texttt{simhei.ttf} & SimHei & {\jfontspec{SimHei}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ 楷体 & \texttt{simkai.ttf} & KaiTi & {\jfontspec{KaiTi}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ 仿宋 & \texttt{simkai.ttf} & FangSong & {\jfontspec{FangSong}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ \bottomrule
+ \end{tabular}%
+\end{table}%
+
+\subsection{Adobe字体系列}
+在Adobe Reader简体中文版中,附带了宋体和黑体两ç§å­—体。
+这两ç§å­—体实际上是åŽæ–‡å­—体,但是和åŽæ–‡å­—体ä¸èƒ½æ··ç”¨ï¼Œ
+因为Adobe Reader中的中文字体的基线都进行了调整,
+ä¸èƒ½äº’相匹é…。在Adobe InDesign中还附带了楷体和仿宋体。
+Adobe的中文字体的Postscriptåå³ä¸ºæ–‡ä»¶å去掉åŽç¼€å。
+
+\begin{table}[htbp]
+ \centering
+ \begin{tabular}{lll}
+ \toprule
+ \multicolumn{1}{c}{\textbf{字体å}} & \multicolumn{1}{c}{\textbf{文件å}} & \multicolumn{1}{c}{\textbf{样例}} \\
+ \midrule
+ Adobe 宋体 Std & \texttt{AdobeSongStd-Light.otf} & {\jfontspec{AdobeSongStd-Light}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ Adobe 黑体 Std & \texttt{AdobeHeitiStd-Regular.otf} & {\jfontspec{AdobeHeitiStd-Regular}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ Adobe 楷体 Std & \texttt{AdobeKaitiStd-Regular.otf} & {\jfontspec{AdobeKaitiStd-Regular}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ Adobe 仿宋 Std & \texttt{AdobeFangsongStd-Regular.otf} & {\jfontspec{AdobeFangsongStd-Regular}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ \bottomrule
+ \end{tabular}%
+\end{table}%
+
+\subsection{方正字体系列}
+方正字体的æ¥æºæœ‰ä¸¤ç§ï¼Œç¬¬ä¸€ç§æ˜¯ä½¿ç”¨æ–¹æ­£çš„排版系统的时候会
+安装到Windows系统的字体文件夹下,第二ç§æ˜¯é’ˆå¯¹Linux系统
+æ¥è¯´çš„,WPS for Linux附带了部分方正字体。
+
+\begin{table}[htbp]
+ \centering
+ \begin{tabular}{llll}
+ \toprule
+ \multicolumn{1}{c}{\textbf{字体å}} & \multicolumn{1}{c}{\textbf{文件å}} & \multicolumn{1}{c}{\textbf{å…¨å}} & \multicolumn{1}{c}{\textbf{样例}} \\
+ \midrule
+ 方正书宋\_GBK & \texttt{FZSSK.TTF} & FZShuSong-Z01 & {\jfontspec{FZShuSong-Z01}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ 方正å°æ ‡å®‹\_GBK & \texttt{FZXBSK.TTF} & FZXiaoBiaoSong-B05 & {\jfontspec{FZXiaoBiaoSong-B05}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ 方正黑体\_GBK & \texttt{FZHTK.TTF} & FZHei-B01 & {\jfontspec{FZHei-B01}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ 方正楷体\_GBK & \texttt{FZKTK.TTF} & FZKai-Z03 & {\jfontspec{FZKai-Z03}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ 方正仿宋\_GBK & \texttt{FZFSK.TTF} & FZFangSong-Z02 & {\jfontspec{FZFangSong-Z02}我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“} \\
+ \bottomrule
+ \end{tabular}%
+\end{table}%
+\end{document}
diff --git a/macros/luatex/generic/luatexja/doc/luatexja.dtx b/macros/luatex/generic/luatexja/doc/luatexja.dtx
new file mode 100644
index 0000000000..d65b7165b8
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/luatexja.dtx
@@ -0,0 +1,11274 @@
+%<*!showexpl>
+%#! lualatex -shell-escape
+
+% To typeset this manual, you need following two fonts:
+% - KozMinPr6N-Regular.otf
+% - KozGoPr6N-Medium.otf
+% - KozGoPr6N-Regular.otf
+
+%%%%% section ==> ç« 
+%%%%% subsection => 節
+\IfFileExists{luatex85.sty}{\RequirePackage{luatex85}}{}
+
+%<en>\documentclass[a4paper,titlepage]{article}
+%<ja>\documentclass[a4paper,10ptj,titlepage]{ltjsarticle}
+
+%%%%%%%%
+\makeatletter
+%%%%%%%%
+\def\pgfsysdriver{pgfsys-pdftex.def}
+\directlua{if jit then jit.on() end}
+\usepackage{metalogo,amsmath,array,tikz,pict2e,multienum,float}
+\usepackage{booktabs,multicol,luatexja-ruby}
+\usepackage[all]{xy}
+\usepackage{lltjext,alltt,comment}
+
+%%%%%%%% Lua GC
+\patchcmd\@outputpage{\stepcounter{page}}{%
+ \directlua{%
+ if jit then
+ local k = collectgarbage("count")
+ if k>900000 then
+ collectgarbage("collect")
+ texio.write_nl("term and log", "GC: ", math.floor(k), math.floor(collectgarbage("count")))
+ end
+ end
+ }%
+ \stepcounter{page}%
+}{}{}
+
+%%%%%%%% fonts
+\usepackage{luatexja-otf}
+\usepackage[no-math]{fontspec}
+\setmainfont[Ligatures=TeX,RawFeature=-notdef]{Linux Libertine O}
+\setmonofont[Scale=MatchLowercase, ItalicFont=lmmono10-italic.otf,
+ BoldFont=lmmonolt10-bold.otf, BoldItalicFont=lmmonolt10-boldoblique.otf,
+ RawFeature=-notdef
+]{lmmono10-regular.otf}
+\setsansfont[Scale=MatchLowercase,Ligatures=TeX,RawFeature=-notdef]{Linux Biolinum O}
+\usepackage[match]{luatexja-fontspec}
+\usepackage[kozuka-pr6n]{luatexja-preset}
+\usepackage{unicode-math}
+\setmonojfont{KozGoPr6N-Regular.otf}
+\setmathfont[Scale=MatchLowercase]{XITSMath}
+
+\setLaTeXa{\scshape a}
+%<*ja>
+\def\emph#1{\textbf{\textgt{#1}}}
+\def\headfont{\normalfont\bfseries\gtfamily}\normalsize
+%</ja>
+%<*en>
+\frenchspacing\sloppy
+\usepackage[margin=25mm,lmargin=30mm,rmargin=30mm,footskip=6mm]{geometry}
+\usepackage{luatexja-adjust}\ltjdisableadjust
+\parskip=\smallskipamount
+\makeatletter
+\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}%
+ {3.25ex \@plus1ex \@minus.2ex}%
+ {-1em}%
+ {\normalfont\normalsize\bfseries\raisebox{.2ex}{$\mdlgblksquare\mkern1mu$}}}
+%</en>
+%<*ja>
+\usepackage[textwidth=44\zw, lines=41, footskip=6mm]{geometry}
+\usepackage{luatexja-adjust}%\ltjdisableadjust
+\advance\leftmargini-1\zw\advance\leftmarginii-1\zw
+%</ja>
+%<en>\long\def\fakefn#1#2{\par\noindent{\footnotesize\hbox to1.8em{\hss#1}#2\par}}
+%<*ja>
+\long\def\fakefn#1#2{%
+ \par{\footnotesize\advance\leftskip 3\zw\parindent1\zw\noindent
+ \llap{#1\hskip.3\zw}#2\par}}
+%</ja>
+%%%%%%%% listings
+
+%%%%%%%% IVS
+
+\def\IVS#1{\char\numexpr "E0100+#1\relax}%"
+\def\IVSA#1#2#3#4#5{%
+ \textcolor{blue}{\raisebox{3.5pt}{\tt%
+ \fboxsep=0.5pt\fbox{\tiny \oalign{0#1#2\crcr#3#4#5\crcr}}}}%
+}
+{\catcode`\%=11
+ \gdef\IVSB#1{\expandafter\IVSA\directlua{
+ local cat_str = luatexbase.catcodetables['string']
+ tex.sprint(cat_str, string.format('%X', 0xE00EF+#1))
+}}}
+
+\usepackage{listings,showexpl,enumitem}
+\lstset{
+ basicstyle=\ttfamily\small, pos=r, breaklines=true,
+ numbers=none, rframe={}, basewidth=0.5em, numberstyle=\tiny, numbersep=0.5em,
+ explpreset={numberstyle=\tiny, numbers=left, numbersep=1em, columns=fixed}
+}
+% Suppress output from showexpl to stdout.
+\makeatletter
+\let\SX@Info\relax
+
+%%%%%%%% colors
+%% modified from http://jfly.iam.u-tokyo.ac.jp/colorset/
+\usepackage{transparent}
+\definecolor{red}{rgb}{1, 0.16, 0}
+\definecolor{blue}{rgb}{0, 0.25, 1}
+\definecolor{gray}{rgb}{.50, .53, .56}
+\definecolor{green}{rgb}{.21, .63, .42}
+\definecolor{cyan}{rgb}{0.40, .80, 1}
+\definecolor{b_gray}{rgb}{0.78, 0.78, 0.80}
+\definecolor{b_pink}{rgb}{1, 0.82, 0.82}
+\definecolor{b_green}{rgb}{.53, .91, .69}
+\definecolor{b_cyan}{rgb}{0.70, .92, 98}
+
+%%%%%%%% hyperref
+\usepackage{hyperref,bookmark}
+%<*en>
+\title{The \LuaTeX-ja package}
+\author{The \LuaTeX-ja project team}
+\date{\LuaTeXjaversion~(\today)}
+%</en>
+%<*ja>
+\title{\LuaTeX-jaパッケージ}
+\author{\LuaTeX-jaプロジェクトãƒãƒ¼ãƒ }
+\date{\LuaTeXjaversion(\today)}
+%</ja>
+\hypersetup{%
+ unicode,
+ colorlinks,
+ allbordercolors=1 1 1,
+ allcolors=blue,
+%<*en>
+ pdfauthor={The LuaTeX-ja project team},
+ pdftitle={The LuaTeX-ja package}
+%</en>
+%<*ja>
+ pdfauthor={LuaTeX-jaプロジェクトãƒãƒ¼ãƒ },
+ pdftitle={LuaTeX-jaパッケージ}
+%</ja>
+}
+%<*ja>
+\def\HyRef@autoref#1#2{%
+ \begingroup
+ \Hy@safe@activestrue
+ \expandafter\HyRef@autosetref\csname r@#2\endcsname{#2}{#1}%
+ \endgroup\ltjalchar"200C %" 欧文ゴースト
+}
+\def\figureautorefname{図}
+\def\tableautorefname{表}
+%</ja>
+
+%%%%%%%% definition env.
+\usepackage{amsthm}
+\theoremstyle{definition}
+%<en>\newtheorem{defn}{Definition}
+%<ja>\newtheorem{defn}{定義}
+
+%%%%%%%% logo
+\usepackage{metalogo}
+\DeclareRobustCommand\eTeX{\ensuremath{\varepsilon}-\kern-.125em\TeX}
+\DeclareRobustCommand\LuaTeX{Lua\TeX}
+\DeclareRobustCommand\pdfTeX{pdf\TeX}
+\DeclareRobustCommand\pTeX{p\kern-.15em\TeX}
+\DeclareRobustCommand\upTeX{up\kern-.15em\TeX}
+\DeclareRobustCommand\pLaTeX{p\kern-.05em\LaTeX}
+\DeclareRobustCommand\pLaTeXe{p\kern-.05em\LaTeXe}
+\DeclareRobustCommand\epTeX{\ensuremath{\varepsilon}-\pTeX}
+
+%%%%%%%% other macros
+\newlist{cslist}{description}{2}
+\setlist[cslist]{%
+ style=nextline,font=\mdseries\ttfamily,
+ before*=\def\<{\char`\<}\def\>{\char`\>}\def\{{\char`\{}\def\}{\char`\}},
+ topsep=\medskipamount,
+%<ja> leftmargin=2\zw,
+%<en> leftmargin=2em,
+}
+
+\def\labelenumii{(\arabic{enumii})}
+\long\def\@makecaption#1#2{%
+ \vskip\abovecaptionskip
+ \sbox\@tempboxa{{\small #1. #2}}%
+ \ifdim \wd\@tempboxa >\hsize
+ {\small #1. #2}\par
+ \else
+ \global \@minipagefalse
+ \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
+ \fi
+ \vskip\belowcaptionskip}
+
+\def\_{\leavevmode \kern .06em\vbox {\hrule \@width .333em}}
+\def\cs#1{\texttt{\upshape
+ \texorpdfstring{\textbackslash\hbox{\ltjsetparameter{autoxspacing=false}#1}}{\textbackslash#1}}}
+\ltjsetparameter{alxspmode={`\\,allow}}
+\def\text@#1{%
+ \ifnum\mathstyle<\scriptstyle
+ \mbox{#1}
+ \else\ifnum\mathstyle<\scriptscriptstyle
+ \mbox{\let\f@size\sf@size\selectfont#1}
+ \else
+ \mbox{\let\f@size\ssf@size\selectfont#1}
+ \fi\fi
+}
+%%%%%%%%
+\makeatother
+%%%%%%%%
+
+\def\Node#1#2{\,\vcenter{\hbox{\fboxsep=1pt\fbox{\vbox{\small\halign{\hfil##\hfil\cr
+ #1\mathstrut\cr\noalign{\vskip1pt\hrule height.4pt\vskip1pt}\strut#2\cr}}}}}\,}
+\def\HNode#1#2#3#4{\,\vcenter{\hbox{\fboxsep=1pt\fbox{\vbox{\small\halign{\hfil##\hfil\cr
+ #1\mathstrut\cr\noalign{\vskip1pt\hrule height.4pt\vskip1pt}%
+ width:\hfill\ #2\cr height:\hfill\ #3\cr depth:\hfill\ #4\cr
+ }}}}}\,}
+
+\makeatletter
+\def\myghost{\ifmmode\else\ltjalchar"200C \fi}
+\def\Param#1{\texorpdfstring{\@Param{#1}}{#1}} % parameter name
+\protected\def\@Param#1{\myghost\hyperlink{fld:#1}{\underline{\smash{\textsf{#1}}}}\myghost}
+\protected\def\DParam#1{\myghost\hypertarget{fld:#1}{\underline{\smash{\textsf{#1}}}}\myghost} % parameter name (definition)
+\def\Pkg#1{\texorpdfstring{\textsf{#1}}{#1}} % packages/classes
+\ltjsetparameter{alxspmode={"200C,allow}}
+
+\begin{document}
+\lstset{
+ vscmd=\IVSB
+}
+
+\catcode`\<=13
+\def<#1>{{\normalfont\rm\itshape$\langle$#1\/$\rangle$}}
+\let\LARG=<
+\maketitle
+
+\tableofcontents
+\bigskip
+
+%<*en>
+\textbf{This documentation is far from complete. It may have many
+grammatical (and contextual) errors.} Also, several parts
+are written in Japanese only.
+%</en>
+%<*ja>
+\emph{\large 本ドキュメントã¯ã¾ã ã¾ã æœªå®Œæˆã§ã™ï¼Ž}
+%</ja>
+
+\clearpage
+%<en>\part{User's manual}
+%<ja>\part{ユーザーズマニュアル}
+
+%<en>\section{Introduction}
+%<ja>\section{ã¯ã˜ã‚ã«}
+
+
+%<*en>
+The \LuaTeX-ja package is a macro package for typesetting high-quality
+Japanese documents when using \LuaTeX.
+%</en>
+%<*ja>
+\LuaTeX-jaパッケージã¯ï¼Œæ¬¡ä¸–代標準\TeX ã§ã‚ã‚‹\LuaTeX ã®ä¸Šã§ï¼Œ\pTeX ã¨åŒç­‰
+ï¼ãれ以上ã®å“質ã®æ—¥æœ¬èªžçµ„版を実ç¾ã•ã›ã‚ˆã†ã¨ã™ã‚‹ãƒžã‚¯ãƒ­ãƒ‘ッケージã§ã‚る.
+%</ja>
+%<en>\subsection{Backgrounds}
+%<ja>\subsection{背景}
+
+%<*en>
+Traditionally, ASCII \pTeX, an extension of \TeX, and its derivatives
+are used to typeset Japanese documents in \TeX. \pTeX\ is an engine
+extension of \TeX: so it can produce high-quality Japanese documents
+without using very complicated macros. But this point is a mixed
+blessing: \pTeX\ is left behind from other extensions of \TeX,
+especially \eTeX\ and \pdfTeX, and from changes about
+Japanese processing in computers (\textit{e.g.}, the UTF-8 encoding).
+%</en>
+%<*ja>
+従æ¥ï¼Œã€Œ\TeX を用ã„ã¦æ—¥æœ¬èªžçµ„版を行ã†ã€ã¨ã„ã£ãŸã¨ã,エンジンã¨ã—ã¦ã¯
+ASCII \pTeX ã‚„ãã‚Œã®æ‹¡å¼µç‰©ãŒç”¨ã„られるã“ã¨ãŒä¸€èˆ¬çš„ã§ã‚ã£ãŸï¼Ž\pTeX ã¯\TeX
+ã®ã‚¨ãƒ³ã‚¸ãƒ³æ‹¡å¼µã§ã‚り,(少々仕様上ä¸ä¾¿ãªç‚¹ã¯ã‚ã‚‹ã‚‚ã®ã®ï¼‰å•†æ¥­å°åˆ·ã®åˆ†é‡Žã«
+も用ã„られるã»ã©ã®é«˜å“質ãªæ—¥æœ¬èªžçµ„版をå¯èƒ½ã¨ã—ã¦ã„る.ã ãŒï¼Œãã‚Œã¯å¼±ç‚¹ã«
+ã‚‚ãªã£ã¦ã—ã¾ã£ãŸï¼Ž\pTeX ã¨ã„ã†ï¼ˆçµ„版的ã«ï¼‰æº€è¶³ãªã‚‚ã®ãŒã‚ã£ãŸãŸã‚,海外ã§
+è¡Œã‚ã‚Œã¦ã„る数々ã®\TeX ã®æ‹¡å¼µâ€•â€•ä¾‹ãˆã°\eTeX ã‚„\pdfTeX ――や,TrueType,
+OpenType, Unicodeã¨ã„ã£ãŸè¨ˆç®—æ©Ÿã§æ—¥æœ¬èªžã‚’扱ã†éš›ã®çŠ¶æ³ã®å¤‰åŒ–ã«è¿½å¾“ã™ã‚‹ã“ã¨
+を怠ã£ã¦ã—ã¾ã£ãŸã®ã ï¼Ž
+%</ja>
+
+%<*en>
+Recently extensions of \pTeX, namely \upTeX\ (Unicode-implementation
+of \pTeX) and \epTeX\ (merging of \pTeX\ and
+\eTeX\ extension), have developed to fill those gaps to some
+extent, but gaps still exist.
+%</en>
+%<*ja>
+ã“ã“数年,若干状æ³ã¯æ”¹å–„ã•ã‚Œã¦ããŸï¼Žç¾åœ¨æ‰‹ã«å…¥ã‚‹å¤§åŠã®\pTeX ãƒã‚¤ãƒŠãƒªã§ã¯
+外部UTF-8入力ãŒåˆ©ç”¨å¯èƒ½ã¨ãªã‚Šï¼Œã•ã‚‰ã«Unicode化を推進ã—,\pTeX ã®å†…部処ç†
+ã¾ã§Unicode化ã—ãŸ\upTeX も開発ã•ã‚Œã¦ã„る.ã¾ãŸï¼Œ\pTeX ã«\eTeX 拡張をマー
+ジã—ãŸ\epTeX も登場ã—,\TeX\ Live\ 2011ã§ã¯\pLaTeX ãŒ\epTeX ã®ä¸Šã§å‹•ä½œã™
+るよã†ã«ãªã£ãŸï¼Žã ãŒï¼Œ\pdfTeX 拡張(PDF直接出力やmicro-typesetting)を
+\pTeX ã«å¯¾å¿œã•ã›ã‚ˆã†ã¨ã„ã†å‹•ãã¯ãªã,海外ã¨ã®gapã¯æœªã ã«ã‚ã‚‹ã®ãŒç¾çŠ¶ã§ã‚
+る.
+%</ja>
+
+%<*en>
+However, the appearance of \LuaTeX\ changed the whole situation. With
+using Lua ``callbacks'', users can customize the internal processing of
+\LuaTeX. So there is no need to modify sources of engines to
+support Japanese typesetting: to do this, we only have to write Lua
+scripts for appropriate callbacks.
+%</en>
+%<*ja>
+ã—ã‹ã—,\LuaTeX ã®ç™»å ´ã§ï¼ŒçŠ¶æ³ã¯å¤§ãã変ã‚ã‚‹ã“ã¨ã«ãªã£ãŸï¼ŽLuaコードã§
+``callback''を書ãã“ã¨ã«ã‚ˆã‚Šï¼Œ\LuaTeX ã®å†…部処ç†ã«å‰²ã‚Šè¾¼ã¿ã‚’ã‹ã‘ã‚‹ã“ã¨ãŒå¯
+能ã¨ãªã£ãŸï¼Žã“ã‚Œã¯ï¼Œã‚¨ãƒ³ã‚¸ãƒ³æ‹¡å¼µã¨ã„ã†çœŸä¼¼ã‚’ã—ãªãã¦ã‚‚,Luaコードã¨ãã‚Œã«
+é–¢ã™ã‚‹\TeX マクロを書ã‘ã°ï¼Œã‚¨ãƒ³ã‚¸ãƒ³æ‹¡å¼µã¨ã»ã¼åŒç¨‹åº¦ã®ã“ã¨ãŒã§ãるよã†ã«ãªã£
+ãŸã¨ã„ã†ã“ã¨ã‚’æ„味ã™ã‚‹ï¼Ž\LuaTeX-jaã¯ï¼Œã“ã®ã‚¢ãƒ—ローãƒã«ã‚ˆã£ã¦Luaコード・
+\TeX マクロã«ã‚ˆã£ã¦æ—¥æœ¬èªžçµ„版を\LuaTeX ã®ä¸Šã§å®Ÿç¾ã•ã›ã‚ˆã†ã¨ã„ã†ç›®çš„ã§é–‹ç™º
+ãŒå§‹ã¾ã£ãŸãƒ‘ッケージã§ã‚る.
+%</ja>
+
+%<en>\subsection{Major changes from \pTeX}
+%<ja>\subsection{\pTeX ã‹ã‚‰ã®ä¸»ãªå¤‰æ›´ç‚¹}
+\label{ssec:chgptex}
+
+%<*en>
+The \LuaTeX-ja package is under much influence of \pTeX\ engine. The initial
+target of development was to implement features of \pTeX. However,
+implementing all feature of \pTeX\ is impossible,
+since all process of \LuaTeX-ja must be implemented only by Lua and \TeX\ macros.
+Hence \emph{\LuaTeX-ja is not a just porting of \pTeX; unnatural
+specifications/behaviors of \pTeX\ were not adopted}.
+%</en>
+%<*ja>
+\LuaTeX-jaã¯ï¼Œ\pTeX ã«å¤šå¤§ãªå½±éŸ¿ã‚’å—ã‘ã¦ã„る.åˆæœŸã®é–‹ç™ºç›®æ¨™ã¯ï¼Œ\pTeX ã®æ©Ÿ
+能をLuaコードã«ã‚ˆã‚Šå®Ÿè£…ã™ã‚‹ã“ã¨ã§ã‚ã£ãŸï¼Žã—ã‹ã—,(\pTeX ã¯ã‚¨ãƒ³ã‚¸ãƒ³æ‹¡å¼µã§ã‚ã£ãŸã®ã«å¯¾ã—)
+\LuaTeX-jaã¯Luaコードã¨\TeX マクロを用ã„ã¦å…¨ã¦ã‚’実装ã—ã¦ã„ãªã‘ã‚Œã°ãªã‚‰ãªã„ãŸã‚,\pTeX
+ã®å®Œå…¨ãªç§»æ¤ã¯ä¸å¯èƒ½ã§ã‚り,ã¾ãŸ\pTeX ã«ãŠã‘る実装ãŒã„ã•ã•ã‹ä¸å¯è§£ã«ãªã£
+ã¦ã„るよã†ãªçŠ¶æ³ã‚‚発見ã•ã‚ŒãŸï¼Žãã®ãŸã‚,\emph{\LuaTeX-jaã¯ï¼Œã‚‚ã¯ã‚„
+\pTeX ã®å®Œå…¨ãªç§»æ¤ã¯ç›®æ¨™ã¨ã¯ã—ãªã„.\pTeX ã«ãŠã‘ã‚‹ä¸è‡ªç„¶ãªä»•æ§˜ãƒ»æŒ™å‹•ãŒã‚
+ã‚Œã°ï¼Œãã“ã¯ç©æ¥µçš„ã«æ”¹ã‚る.}
+%</ja>
+
+%<*en>
+The followings are major changes from \pTeX.
+For more detailed information, see Part~\ref{part-imp} or other sections of this manual.
+%</en>
+%<*ja>
+以下㯠\pTeX ã‹ã‚‰ã®ä¸»ãªå¤‰æ›´ç‚¹ã§ã‚る.
+より詳細ã«ã¤ã„ã¦ã¯ç¬¬\ref{part-imp}部ãªã©æœ¬æ–‡æ›¸ã®æ®‹ã‚Šã‚’å‚照.
+%</ja>
+
+%<*en>
+\paragraph{Command names} \pTeX\ addes several primitives, such as \cs{kanjiskip},
+\cs{prebreakpenalty},~and \cs{ifydir}. They can be used as follows:
+%</en>
+%<*ja>
+\paragraph{命令ã®å称} 例ãˆã°\pTeX ã§è¿½åŠ ã•ã‚ŒãŸæ¬¡ã®ã‚ˆã†ãªãƒ—リミティブ
+%</ja>
+\begin{verbatim}
+\kanjiskip=10pt \dimen0=kanjiskip
+\tbaselineshift=0.1zw
+\dimen0=\tbaselineshift
+\prebreakpenalty`ã=100
+\ifydir ... \fi
+\end{verbatim}
+%<en> However, we cannot use them under \LuaTeX-ja.
+%<en> Instead of them, we have to write as the following.
+%<ja> ã¯\LuaTeX-jaã«ã¯å­˜åœ¨ã—ãªã„.\LuaTeX-jaã§ã¯ä»¥ä¸‹ã®ã‚ˆã†ã«è¨˜è¿°ã™ã‚‹ã“ã¨ã«ãªã‚‹ï¼Ž
+\begin{verbatim}
+\ltjsetparameter{kanjiskip=10pt} \dimen0=\ltjgetparameter{kanjiskip}
+\ltjsetparameter{talbaselineshift=0.1\zw}
+\dimen0=\ltjgetparameter{talbaselineshift}
+\ltjsetparameter{prebreakpenalty={`ã,100}}
+\ifnum\ltjgetparemeter{direction}=4 ... \fi
+\end{verbatim}
+%<*en>
+Note that \pTeX\ adds new two useful units, namely \texttt{zw}~and~\texttt{zh}.
+As shown above, they are changed by \cs{zw}~and~\cs{zh} respectively, in \LuaTeX-ja.
+%</en>
+%<*ja>
+特ã«æ³¨æ„ã—ã¦ã»ã—ã„ã®ã¯ï¼Œ\pTeX ã§è¿½åŠ ã•ã‚ŒãŸ \texttt{zw} 㨠\texttt{zh} ã¨ã„ã†å˜ä½ã¯
+\LuaTeX-ja ã§ã¯ä½¿ç”¨ã§ããšï¼Œ\cs{zw}, \cs{zh} ã¨åˆ¶å¾¡ç¶´ã®å½¢ã«ã—ãªã„ã¨ã„ã‘ãªã„ã¨ã„ã†ç‚¹ã§ã‚る.
+%</ja>
+
+%<*en>
+\paragraph{Linebreak after a Japanese character}
+In \pTeX, a line break after Japanese character is ignored (and
+ doesn't yield a space), since line breaks (in source files) are
+ permitted almost everywhere in Japanese texts. However, \LuaTeX-ja
+ doesn't have this feature completely, because of a specification
+ of \LuaTeX. For the detail, see Section~\ref{sec-lbreak}.
+%</en>
+%<*ja>
+\paragraph{和文文字直後ã®æ”¹è¡Œ}
+日本語ã®æ–‡æ›¸ä¸­ã§ã¯æ”¹è¡Œã¯ã»ã¨ã‚“ã©ã©ã“ã§ã‚‚許ã•ã‚Œã‚‹ã®ã§ï¼Œ\pTeX ã§ã¯å’Œæ–‡æ–‡å­—
+ 直後ã®æ”¹è¡Œã¯ç„¡è¦–ã•ã‚Œã‚‹ï¼ˆã‚¹ãƒšãƒ¼ã‚¹ãŒå…¥ã‚‰ãªã„)よã†ã«ãªã£ã¦ã„ãŸï¼Žã—ã‹ã—,
+ \LuaTeX-ja ã§ã¯ \LuaTeX ã®ä»•æ§˜ã®ãŸã‚ã«ã“ã®æ©Ÿèƒ½ã¯å®Œå…¨ã«ã¯å®Ÿè£…ã•ã‚Œã¦ã„ãªã„.
+ 詳ã—ãã¯\ref{sec-lbreak}ç« ã‚’å‚照.
+%</ja>
+
+%<*en>
+\paragraph{Spaces related to Japanese characters}
+The insertion process of glues/kerns between two Japanese
+ characters and between a Japanese character and other characters
+ (we refer glues/kerns of both kinds as \textbf{JAglue}) is rewritten from
+ scratch.
+%</en>
+%<*ja>
+\paragraph{和文関連ã®ç©ºç™½}
+2ã¤ã®å’Œæ–‡æ–‡å­—ã®é–“や,和文文字ã¨æ¬§æ–‡æ–‡å­—ã®é–“ã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³
+ (両者をã‚ã‚ã›ã¦\textbf{JAglue}ã¨å‘¼ã¶ï¼‰ã®æŒ¿å…¥å‡¦ç†ãŒ0ã‹ã‚‰æ›¸ãç›´ã•ã‚Œã¦ã„る.
+%</ja>
+
+\begin{itemize}
+%<*en>
+\item As \LuaTeX's internal ligature handling is \emph{node-based}
+ (\textit{e.g.}, \verb+of{}fice+ doesn't prevent ligatures), the
+ insertion process of \textbf{JAglue} is now \emph{node-based}.
+%</en>
+%<*ja>
+\item \LuaTeX ã®å†…部ã§ã®åˆå­—ã®æ‰±ã„ã¯ã€ŒãƒŽãƒ¼ãƒ‰ã€ã‚’å˜ä½ã¨ã—ã¦è¡Œã‚れるよã†ã«ãªã£ã¦ã„る(例ãˆã°ï¼Œ
+ \verb+of{}fice+ ã§åˆå­—ã¯æŠ‘制ã•ã‚Œãªã„).ãã‚Œã«åˆã‚ã›ï¼Œ\textbf{JAglue}ã®æŒ¿å…¥å‡¦ç†ã‚‚
+ ノードå˜ä½ã§å®Ÿè¡Œã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+\item Furthermore, nodes between two characters which have no effects in
+ line break (\textit{e.g.}, \cs{special} node) and kerns from
+ italic correction are ignored in the insertion process.
+%</en>
+%<*ja>
+\item ã•ã‚‰ã«ï¼Œ2ã¤ã®æ–‡å­—ã®é–“ã«ã‚る行末ã§ã¯åŠ¹æžœã‚’æŒãŸãªã„ノード(例ãˆã° \cs{special} ノード)や,
+ イタリック補正ã«ä¼´ã„挿入ã•ã‚Œã‚‹ã‚«ãƒ¼ãƒ³ã¯æŒ¿å…¥å‡¦ç†ä¸­ã§ã¯ç„¡è¦–ã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+\item \emph{Caution: due to above two points, many methods which did for the
+ dividing the process of the insertion of \textbf{JAglue} in \pTeX\ are not
+ effective anymore.} In concrete terms, the following two methods are not effective anymore:
+%</en>
+%<*ja>
+\item \emph{注æ„:上ã®2ã¤ã®å¤‰æ›´ã«ã‚ˆã‚Šï¼Œå¾“æ¥\textbf{JAglue}ã®æŒ¿å…¥å‡¦ç†ã‚’分断ã™ã‚‹ã®ã«
+ 使ã‚ã‚Œã¦ã„ãŸã„ãã¤ã‹ã®æ–¹æ³•ã¯ç”¨ã„ã‚‹ã“ã¨ãŒã§ããªã„.具体的ã«ã¯ï¼Œæ¬¡ã®æ–¹æ³•ã¯ã‚‚ã¯ã‚„無効ã§ã‚る:}
+%</ja>
+\begin{lstlisting}
+ã¡ã‚‡{}ã£ã¨ ã¡ã‚‡\/ã£ã¨
+\end{lstlisting}
+%<*en>
+ If you want to do so, please put an empty horizontal box (hbox) between it instead:
+%</en>
+%<*ja>
+ ã‚‚ã—åŒã˜ã“ã¨ã‚’ã‚„ã‚ŠãŸã‘ã‚Œã°ï¼Œç©ºã®æ°´å¹³ãƒœãƒƒã‚¯ã‚¹(hbox)ã‚’é–“ã«æŒŸã‚ã°ã‚ˆã„:
+%</ja>
+\begin{lstlisting}
+ã¡ã‚‡\hbox{}ã£ã¨
+\end{lstlisting}
+
+%<*en>
+\item In the process, two Japanese fonts which only differ in their ``real''
+ fonts are identified.
+%</en>
+%<*ja>
+\item 処ç†ä¸­ã§ã¯ï¼Œ2ã¤ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã¯ï¼Œå®Ÿãƒ•ã‚©ãƒ³ãƒˆãŒç•°ãªã‚‹ã ã‘ã®å ´åˆã«ã¯åŒä¸€è¦–
+ ã•ã‚Œã‚‹ï¼Ž
+%</ja>
+\end{itemize}
+
+%<*en>
+\paragraph{Directions}
+From version~20150420.0, \LuaTeX-ja supports vertical writing.
+We implement this feature by using callbacks of \LuaTeX; so it must \emph{not} be confused
+with $\Omega$-style direction support of \LuaTeX\ itself.
+Due to implementation, the dimension returned by \cs{wd},~\cs{ht}, or~\cs{dp} depends
+on the content of the register \emph{only}. This is major difference with \pTeX.
+%</en>
+%<*ja>
+\paragraph{組方å‘}
+ãƒãƒ¼ã‚¸ãƒ§ãƒ³20150420.0ã‹ã‚‰ã¯ï¼Œä¸å®‰å®šãªãŒã‚‰ã‚‚\LuaTeX-ja ã«ãŠã‘る縦組ã¿ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„る.
+ãªãŠï¼Œ\LuaTeX 本体も$\Omega$æµã®çµ„æ–¹å‘をサãƒãƒ¼ãƒˆã—ã¦ã„ã‚‹ãŒï¼Œãã‚Œã¨ã¯å…¨ãã®åˆ¥ç‰©ã§ã‚ã‚‹ã“ã¨
+ã«æ³¨æ„ã—ã¦ã»ã—ã„.
+特ã«ï¼Œç•°ãªã£ãŸçµ„æ–¹å‘ã®ãƒœãƒƒã‚¯ã‚¹ã‚’扱ã†å ´åˆã«ã¯
+\cs{wd}, \cs{ht}, \cs{dp}ç­‰ã®ä»•æ§˜ãŒ\pTeX ã¨ç•°ãªã‚‹ã®ã§æ³¨æ„.詳細ã¯ç¬¬\ref{sec-direction}ç« ã‚’å‚照.
+%</ja>
+
+%<*en>
+\paragraph{\cs{discretionary}}
+Japanese characters in discretionary break (\cs{discretionary}) is not supported.
+%</en>
+%<*ja>
+\paragraph{\cs{discretionary}}
+ \cs{discretionary} 内ã«ç›´æŽ¥å’Œæ–‡æ–‡å­—を記述ã™ã‚‹ã“ã¨ã¯ï¼Œ\pTeX ã«ãŠã„ã¦ã‚‚想定ã•ã‚Œã¦ã„ãªã‹ã£ãŸ
+ æ„ŸãŒã‚ã‚‹ãŒï¼Ž\LuaTeX-jaã«ãŠã„ã¦ã‚‚想定ã—ã¦ã„ãªã„.和文文字をã©ã†
+ ã—ã¦ã‚‚使ã„ãŸã„å ´åˆã¯ \cs{hbox} ã§æ‹¬ã‚‹ã“ã¨ï¼Ž
+%</ja>
+
+%<*en>
+\paragraph{Greek and Cyrillic letters, and ISO~8859-1 symbols}
+By default, \LuaTeX-ja uses Japanese fonts to typeset Greek and Cyrillic letters,
+ To change this behavior,
+ put \verb!\ltjsetparameter{jacharrange={-2,-3}}! in the preamble.
+ For the detailed description, see Subsection~\ref{ssec:setrange}.
+
+From version~20150906.0, characters which belongs both ISO~8859-1 and JIS~X~0208,
+such as \P~and~\S, are now typeset in alphabetic fonts.
+If you are using \LaTeXe\ prior to 2017/01/01, these characters are not typeset correctly
+without the \cs{fontspec} (and~\Pkg{luatexja-fontspec}) package.
+%</en>
+%<*ja>
+\paragraph{ギリシャ文字・キリル文字ã¨ISO~8859-1ã®è¨˜å·}
+標準ã§ã¯ï¼Œ\LuaTeX-jaã¯ã‚®ãƒªã‚·ãƒ£æ–‡å­—やキリル文字を和文フォントを使ã£
+ ã¦çµ„む.ギリシャ語ãªã©ã‚’本格的ã«çµ„ã‚€ãªã©ã“ã®çŠ¶æ³ãŒæœ›ã¾ã—ããªã„å ´åˆï¼Œ
+ プリアンブルã«
+\begin{lstlisting}
+ \ltjsetparameter{jacharrange={-2,-3}}
+\end{lstlisting}
+ を入れるã¨
+ 上記種類ã®æ–‡å­—ã¯æ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚’用ã„ã¦çµ„ã¾ã‚Œã‚‹ã‚ˆã†ã«ãªã‚‹ï¼Ž
+ 詳ã—ã„説明ã¯\ref{ssec:setrange}節をå‚ç…§ã—ã¦ã»ã—ã„.
+
+ã¾ãŸï¼Œ\P,~\S ã¨ã„ã£ãŸISO~8859-1ã®ä¸Šä½é ˜åŸŸã¨JIS~X~0208ã®å…±é€šéƒ¨åˆ†ã®æ–‡å­—ã¯
+ ãƒãƒ¼ã‚¸ãƒ§ãƒ³20150906.0ã‹ã‚‰æ¨™æº–ã§æ¬§æ–‡æ‰±ã„ã¨ãªã£ãŸï¼Ž\LaTeXe\ 2017/01/01以é™ã§ã¯
+標準ã§TUエンコーディングã®Latin ModernフォントãŒä½¿ã‚れるã®ã§ï¼Œ
+特ã«ä½•ã‚‚ã›ãšã‚½ãƒ¼ã‚¹ä¸­ã«ãã®ã¾ã¾è¨˜è¿°ã—ã¦ã‚‚ã“れらã®æ–‡å­—ãŒå‡ºåŠ›ã•ã‚Œã‚‹
+\footnote{\LaTeXe\ 2017/01/01よりå‰ã§ã¯ï¼Œã‚½ãƒ¼ã‚¹ä¸­ã«ç›´æŽ¥è¨˜è¿°ã—ã¦ã‚‚
+ \Pkg{fontspec}パッケージ(ãŠã‚ˆã³\Pkg{luatexja-fontspec}パッケージ)éžèª­ã¿è¾¼ã¿ã®çŠ¶æ…‹ã§ã¯å‡ºåŠ›ã•ã‚Œãªã„.}.
+和文扱ã„ã§å‡ºåŠ›ã™ã‚‹ã«ã¯ \verb+\ltjjachar`§+ ã®ã‚ˆã†ã« \cs{ltjjachar} 命令
+を使ãˆã°ã‚ˆã„.
+%</ja>
+
+%<en>\subsection{Notations}
+%<ja>\subsection{用語ã¨è¨˜æ³•}
+
+%<*en>
+In this document, the following terms and notations are used:
+%</en>
+%<*ja>
+本ドキュメントã§ã¯ï¼Œä»¥ä¸‹ã®ç”¨èªžã¨è¨˜æ³•ã‚’用ã„る:
+%</ja>
+\begin{itemize}
+%<*en>
+\item Characters are classified into following two types.
+ Note that the classification can be customized by a user
+ (see Subsection~\ref{ssec:setrange}).
+%</en>
+%<*ja>
+\item 文字ã¯æ¬¡ã®2種類ã«åˆ†ã‘られる.ã“ã®é¡žåˆ¥ã¯å›ºå®šã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã§ã¯ãªã,ユーザãŒå¾Œã‹ã‚‰å¤‰æ›´å¯èƒ½ã§ã‚ã‚‹
+ (\ref{ssec:setrange}節をå‚照).
+%</ja>
+\begin{itemize}
+%<*en>
+\item \textbf{JAchar}: standing for characters which is used in Japanese typesetting,
+ such as Hiragana,~Katakana, Kanji, and~other Japanese punctuation marks.
+%</en>
+%<*ja>
+\item \textbf{JAchar}: ã²ã‚‰ãŒãªï¼Œã‚«ã‚¿ã‚«ãƒŠï¼Œæ¼¢å­—,和文用ã®ç´„物ã¨ã„ã£ãŸ
+ 日本語組版ã«ä½¿ã‚れる文字ã®ã“ã¨ã‚’指ã™ï¼Ž
+%</ja>
+
+%<en>\item \textbf{ALchar}: standing for all other characters like latin alphabets.
+%<ja>\item \textbf{ALchar}: ラテンアルファベットを始ã‚ã¨ã™ã‚‹ï¼Œãã®ä»–å…¨ã¦ã®æ–‡å­—を指ã™ï¼Ž
+\end{itemize}
+
+%<*en>
+We say \emph{alphabetic fonts} for fonts used in \textbf{ALchar},
+and \emph{Japanese fonts} for fonts used in \textbf{JAchar}.
+%</en>
+%<*ja>
+ãã—ã¦ï¼Œ\textbf{ALchar}ã®å‡ºåŠ›ã«ç”¨ã„られるフォントを\emph{欧文フォント}ã¨å‘¼ã³ï¼Œ
+\textbf{JAchar}ã®å‡ºåŠ›ã«ç”¨ã„られるフォントを\emph{和文フォント}ã¨å‘¼ã¶ï¼Ž
+%</ja>
+%<*en>
+\item A word in a sans-serif font with underline (like \Param{prebreakpenalty})
+ means an internal parameter for Japanese typesetting, and it
+ is used as a key in \cs{ltjsetparameter} command.
+%</en>
+%<*ja>
+\item 下線ã¤ãローマン体ã§æ›¸ã‹ã‚ŒãŸèªžï¼ˆä¾‹ï¼š\Param{prebreakpenalty})ã¯æ—¥æœ¬èªžçµ„版用ã®
+ パラメータを表ã—,ã“れら㯠\cs{ltjsetparameter} 命令ã®ã‚­ãƒ¼ã¨ã—ã¦
+ 用ã„られる.
+%</ja>
+%<*en>
+\item A word in a sens-serif font without underline (like \Pkg{fontspec})
+ means a package or a class of \LaTeX.
+%</en>
+%<*ja>
+\item 下線ãªã—サンセリフ体ã®èªžï¼ˆä¾‹ï¼š\Pkg{fontspec})ã¯\LaTeX ã®
+ パッケージやクラスを表ã™ï¼Ž
+%</ja>
+%<*en>
+\item In this document, natural numbers start from~zero.
+ $\omega$ denotes the set of all natural numbers which can be used in \TeX.
+%</en>
+%<*ja>
+\item 本ドキュメントã§ã¯ï¼Œè‡ªç„¶æ•°ã¯0ã‹ã‚‰å§‹ã¾ã‚‹ï¼Žï¼ˆ\TeX ã§æ‰±ãˆã‚‹ï¼‰è‡ªç„¶æ•°å…¨ä½“ã®é›†åˆã¯$\omega$ã¨è¡¨è¨˜ã™ã‚‹ï¼Ž
+%</ja>
+\end{itemize}
+
+%<en>\subsection{About the project}
+%<ja>\subsection{プロジェクトã«ã¤ã„ã¦}
+
+%<en>\paragraph{Project Wiki} Project Wiki is under construction.
+%<ja>\paragraph{プロジェクトWiki} プロジェクトWikiã¯æ§‹ç¯‰ä¸­ã§ã‚る.
+%<*en>
+\begin{itemize}
+\item \url{https://osdn.jp/projects/luatex-ja/wiki/FrontPage%28en%29} (English)
+\item \url{https://osdn.jp/projects/luatex-ja/wiki/FrontPage} (Japanese)
+\item \url{https://osdn.jp/projects/luatex-ja/wiki/FrontPage%28zh%29} (Chinese)
+\end{itemize}
+%</en>
+%<*ja>
+\begin{itemize}
+\item \url{https://osdn.jp/projects/luatex-ja/wiki/FrontPage}(日本語)
+\item \url{https://osdn.jp/projects/luatex-ja/wiki/FrontPage%28en%29}(英語)
+\item \url{https://osdn.jp/projects/luatex-ja/wiki/FrontPage%28zh%29}(中国語)
+\end{itemize}
+%</ja>
+
+%<en>This project is hosted by OSDN.
+%<ja>本プロジェクトã¯OSDNã®ã‚µãƒ¼ãƒ“スを用ã„ã¦é‹å–¶ã•ã‚Œã¦ã„る.
+
+%<en>\paragraph{Members}\
+%<ja>\clearpage\paragraph{開発メンãƒãƒ¼}\
+
+%<*en>
+\begin{multienumerate}
+\def\labelenumi{$\bullet$}
+\mitemxxx{Hironori KITAGAWA}{Kazuki MAEDA}{Takayuki YATO}
+\mitemxxx{Yusuke KUROKI}{Noriyuki ABE}{Munehiro YAMAMOTO}
+\mitemxxx{Tomoaki HONDA}{Shuzaburo SAITO}{MA Qiyuan}
+\end{multienumerate}
+%</en>
+%<*ja>
+\begin{multienumerate}
+\def\labelenumi{$\bullet$}
+\mitemxxx{åŒ—å· å¼˜å…¸}{å‰ç”° 一貴}{å…«ç™» 崇之}
+\mitemxxx{黒木 裕介}{阿部 紀行}{山本 å®—å®}
+\mitemxxx{本田 知亮}{齋藤 修三郎}{馬 起園}
+\end{multienumerate}
+%</ja>
+
+% \paragraph{Acknowledgments} -- 挿入ã™ã‚‹ãªã‚‰ã“ã“
+
+%<en>\clearpage
+%<en>\section{Getting Started}
+%<ja>\section{使ã„æ–¹}
+%<en>\subsection{Installation}
+%<ja>\subsection{インストール}
+
+%<en>The following packages are needed for the \LuaTeX-ja\ package.
+%<ja>\LuaTeX-jaパッケージã®å‹•ä½œã«ã¯æ¬¡ã®ãƒ‘ッケージ類ãŒå¿…è¦ã§ã‚る.
+\begin{itemize}
+\item \LuaTeX\ 1.0.0 (or later)
+\item recent \Pkg{luaotfload} (v2.98 or later recommended)
+\item \Pkg{adobemapping} (Adobe cmap and pdfmapping files)
+\item \Pkg{etoolbox}, \Pkg{everysel} (if you want to use \LuaTeX-ja with \LaTeXe)
+\item \Pkg{ltxcmds}, \Pkg{pdftexcmds}, \Pkg{filehook}, \Pkg{atbegshi}
+\item \Pkg{fontspec} v2.7c (or later)
+%<en>\item \emph{IPAex fonts} (\url{http://ipafont.ipa.go.jp/})
+%<ja>\item \emph{IPAexフォント(\url{http://ipafont.ipa.go.jp/})}
+\end{itemize}
+%<en>In summary, \LuaTeX-ja version 20180825.0 (or~later) no longer supports \TeX~Live~2016.
+%<*ja>
+è¦ç´„ã™ã‚‹ã¨ï¼Œãƒãƒ¼ã‚¸ãƒ§ãƒ³20180825.0以é™ã®\LuaTeX-jaã¯\TeX~Live~2016以å‰ã§ã¯å‹•ä½œã—ãªã„\footnote{%
+ ã‚‚ã£ã¨ã‚‚,自分ã§\LuaTeX ã®ãƒã‚¤ãƒŠãƒªã‚’Subversionリãƒã‚¸ãƒˆãƒªã‹ã‚‰ãƒ“ルドã—ã¦ã„ã‚Œã°è©±ã¯åˆ¥ã§ã‚る.
+}.
+%</ja>
+
+%<*en>
+Now \LuaTeX-ja is available from
+CTAN (in the \texttt{macros/luatex/generic/luatexja} directory), and
+the following distributions:
+ \begin{itemize}
+ \item MiK\TeX\ (in \texttt{luatexja.tar.lzma}); see the next subsection
+ \item \TeX\ Live (in \texttt{texmf-dist/tex/luatex/luatexja})
+ \item W32\TeX\ (in \texttt{luatexja.tar.xz})
+ \end{itemize}
+IPAex fonts are also available in these distributions.
+%</en>
+%<*ja>
+ç¾åœ¨ï¼Œ\LuaTeX-jaã¯CTAN (\texttt{macros/luatex/generic/luatexja})ã«åŽéŒ²ã•ã‚Œã¦ã„る他,
+以下ã®ãƒ‡ã‚£ã‚¹ãƒˆãƒªãƒ“ューションã«ã‚‚åŽéŒ²ã•ã‚Œã¦ã„る:
+ \begin{itemize}
+ \item MiK\TeX\ (\texttt{luatexja.tar.lzma})
+ \item \TeX\ Live (\texttt{texmf-dist/tex/luatex/luatexja})
+ \item W32\TeX\ (\texttt{luatexja.tar.xz})
+ \end{itemize}
+ã“れらã®ãƒ‡ã‚£ã‚¹ãƒˆãƒªãƒ“ューションã¯IPAexフォントもåŽéŒ²ã—ã¦ã„る.
+W32\TeX ã«ãŠã„ã¦ã¯IPAexフォント㯠\texttt{luatexja.tar.xz} 内ã«ã‚る.
+%</ja>
+
+%<en>\paragraph{Manual installation}
+%<ja>\paragraph{手動インストール方法}
+
+\begin{enumerate}
+%<*en>
+\item Download the source, by one of the following method.
+ At the present, \LuaTeX-ja has no \emph{stable} release.
+
+\begin{itemize}
+\item Clone the Git repository:
+\begin{lstlisting}
+$ git clone git://git.osdn.jp/gitroot/luatex-ja/luatexja.git
+\end{lstlisting}
+\item Download the \texttt{tar.gz} archive of HEAD in the \texttt{master} branch from
+\begin{flushleft}
+\url{http://git.osdn.jp/view?p=luatex-ja/luatexja.git;a=snapshot;h=HEAD;sf=tgz}.
+\end{flushleft}
+\end{itemize}
+
+Note that the \texttt{master} branch, and hence the archive in CTAN, are not updated frequently;
+the forefront of development is not the \texttt{master} branch.
+%</en>
+%<*ja>
+\item ソースを以下ã®ã„ãšã‚Œã‹ã®æ–¹æ³•ã§å–å¾—ã™ã‚‹ï¼Žç¾åœ¨å…¬é–‹ã•ã‚Œã¦ã„ã‚‹ã®ã¯ã‚ãã¾ã§ã‚‚
+ 開発版ã§ã‚ã£ã¦ï¼Œå®‰å®šç‰ˆã§ãªã„ã“ã¨ã«æ³¨æ„.
+
+\begin{itemize}
+\item Gitリãƒã‚¸ãƒˆãƒªã‚’クローンã™ã‚‹ï¼š
+\begin{lstlisting}
+$ git clone git://git.osdn.jp/gitroot/luatex-ja/luatexja.git
+\end{lstlisting}
+\item \texttt{master} ブランãƒã®ã‚¹ãƒŠãƒƒãƒ—ショット(\texttt{tar.gz} å½¢å¼ï¼‰ã‚’ダウンロードã™ã‚‹ï¼Ž
+\begin{flushleft}
+\url{http://git.osdn.jp/view?p=luatex-ja/luatexja.git;a=snapshot;h=HEAD;sf=tgz}.
+\end{flushleft}
+\end{itemize}
+\texttt{master} ブランãƒï¼ˆå¾“ã£ã¦ï¼ŒCTAN内ã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–も)ã¯ãŸã¾ã«ã—ã‹æ›´æ–°ã•ã‚Œãªã„ã“ã¨ã«æ³¨æ„.
+主ãªé–‹ç™ºã¯\texttt{master}ã®å¤–ã§è¡Œã‚れ,比較的ã¾ã¨ã¾ã£ã¦ããŸã‚‰ãれを \texttt{master} ã«
+å映ã•ã›ã‚‹ã“ã¨ã«ã—ã¦ã„る.
+%</ja>
+
+%<*en>
+\item Extract the archive. You will see \texttt{src/} and several other sub-directories.
+But only the contents in \texttt{src/} are needed to work \LuaTeX-ja.
+%</en>
+%<*ja>
+\item 「Gitリãƒã‚¸ãƒˆãƒªã‚’クローンã€ä»¥å¤–ã®æ–¹æ³•ã§ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã‚’å–å¾—ã—ãŸãªã‚‰ã°ï¼Œãれを展開ã™ã‚‹ï¼Ž
+ \texttt{src/} ã‚’ã¯ã˜ã‚ã¨ã—ãŸã„ãã¤ã‹ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒã§ãã‚‹ãŒï¼Œ
+ 動作ã«ã¯ \texttt{src/} 以下ã®å†…容ã ã‘ã§å分.
+%</ja>
+
+%<*en>
+\item If you downloaded this package from CTAN, you have to run following commands
+ to generate classes
+ and \texttt{ltj-kinsoku.lua} (the file which stores default ``\textit{kinsoku}'' parameters):
+%</en>
+%<*ja>
+\item ã‚‚ã—CTANã‹ã‚‰æœ¬ãƒ‘ッケージをå–å¾—ã—ãŸã®ã§ã‚ã‚Œã°ï¼Œæ—¥æœ¬èªžç”¨ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã‚„
+標準ã®ç¦å‰‡å‡¦ç†ç”¨ãƒ‘ラメータを
+æ ¼ç´ã—㟠\texttt{ltj-kinsoku.lua} を生æˆã™ã‚‹ãŸã‚ã«ï¼Œ
+以下を実行ã™ã‚‹å¿…è¦ãŒã‚る:
+%</ja>
+\begin{lstlisting}
+$ cd src
+$ lualatex ltjclasses.ins
+$ lualatex ltjsclasses.ins
+$ lualatex ltjltxdoc.ins
+$ luatex ltj-kinsoku_make.tex
+\end{lstlisting}
+%<*en>
+\emph{Do not forget The last line (processing \texttt{ltj-kinsoku\_make.tex})}.
+\texttt{*.\{dtx,ins\}} and \texttt{ltj-kinsoku\_make.tex} used here are not needed in regular use.
+%</en>
+%<*ja>
+\emph{最後㮠\texttt{ltj-kinsoku\_make.tex} ã®å®Ÿè¡Œã‚’忘れãªã„よã†ã«æ³¨æ„}.
+ã“ã“ã§ä½¿ç”¨ã—㟠\texttt{*.\{dtx,ins\}} 㨠\texttt{ltj-kinsoku\_make.tex} ã¯
+通常ã®ä½¿ç”¨ã«ã‚ãŸã£ã¦ã¯å¿…è¦ãªã„.
+%</ja>
+
+
+
+%<*en>
+\item Copy all the contents of \texttt{src/} into one of your \texttt{TEXMF} tree.
+ \texttt{TEXMF/tex/luatex/luatexja/} is an example location.
+ If you cloned entire Git repository, making a symbolic link of \texttt{src/}
+ instead copying is also good.
+%</en>
+%<*ja>
+\item \texttt{src} ã®ä¸­èº«ã‚’自分㮠\texttt{TEXMF} ツリーã«ã‚³ãƒ”ーã™ã‚‹ï¼Ž
+ 場所ã®ä¾‹ã¨ã—ã¦ã¯ï¼Œä¾‹ãˆã°
+\begin{quote}
+ \texttt{TEXMF/tex/luatex/luatexja/}
+\end{quote}
+ ãŒã‚る.
+ シンボリックリンクãŒåˆ©ç”¨ã§ãる環境ã§ï¼Œã‹ã¤ãƒªãƒã‚¸ãƒˆãƒªã‚’直接å–å¾—ã—ãŸã®ã§ã‚ã‚Œã°ï¼Œ
+ (更新を容易ã«ã™ã‚‹ãŸã‚ã«ï¼‰ã‚³ãƒ”ーã§ã¯ãªãリンクを貼るã“ã¨ã‚’勧ã‚る.
+%</ja>
+%<*en>
+\item If \texttt{mktexlsr} is needed to update the file name database, make it so.
+%</en>
+%<*ja>
+\item å¿…è¦ãŒã‚ã‚Œã°ï¼Œ\texttt{mktexlsr} を実行ã™ã‚‹ï¼Ž
+%</ja>
+\end{enumerate}
+
+%<*en>
+\subsection{Cautions}
+For changes from \pTeX, see Subsection~\ref{ssec:chgptex}.
+%</en>
+%<*ja>
+\subsection{注æ„点}
+\pTeX ã‹ã‚‰ã®å¤‰æ›´ç‚¹ã¨ã—ã¦ï¼Œ\ref{ssec:chgptex}節も熟読ã™ã‚‹ã®ãŒæœ›ã¾ã—ã„.
+ã“ã“ã§ã¯ä¸€èˆ¬çš„ãªæ³¨æ„点を述ã¹ã‚‹ï¼Ž
+%</ja>
+\begin{itemize}
+%<*en>
+\item The encoding of your source file must be UTF-8. Other
+ encodings, such as EUC-JP or Shift-JIS, are not supported.
+%</en>
+%<*ja>
+\item 原稿ã®ã‚½ãƒ¼ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã®æ–‡å­—コードã¯UTF-8固定ã§ã‚る.
+ 従æ¥æ—¥æœ¬èªžã®æ–‡å­—コードã¨ã—ã¦ç”¨ã„られã¦ããŸEUC-JPã‚„Shift-JISã¯ä½¿ç”¨ã§ããªã„.
+%</ja>
+%<*en>
+\item \LuaTeX-ja is very slower than \pTeX.
+ % Generally speaking, LuaJIT\TeX\ processes \LuaTeX-ja
+ % about 30\% faster than \LuaTeX, but not always%
+ % \footnote{%
+ % LuaJIT has several limitations such as 1\,GB~(or~2\,GB) memory limitation.
+ % So typesetting a large source by LuaJIT\TeX may cause an ``out of memory'' error,
+ % or failure of loading/saving font cache of \Pkg{luaotfload}.
+ % }.
+%</en>
+%<*ja>
+\item \LuaTeX-jaã¯å‹•ä½œãŒ\pTeX ã«æ¯”ã¹ã¦éžå¸¸ã«é…ã„.
+コードを調整ã—ã¦å¾ã€…ã«é€Ÿãã—ã¦ã„ã‚‹ãŒï¼Œã¾ã æº€è¶³ã§ãる速度ã§ã¯ãªã„.
+% LuaJIT\TeX を用ã„ã‚‹ã¨\LuaTeX ã®ã ã„ãŸã„1.3å€ã®é€Ÿåº¦ã§å‹•ãよã†ã§ã‚ã‚‹ãŒï¼Œ
+% IPA mj明æœãªã©ã®å¤§ãã„フォントを用ã„ãŸå ´åˆã«ã¯\LuaTeX よりもé…ããªã‚‹ã“ã¨ã‚‚ã‚ã‚‹
+% \footnote{%
+% LuaJITã¯1\,GB(ã‚ã‚‹ã„ã¯2\,GB)ã®ãƒ¡ãƒ¢ãƒªåˆ¶é™ãªã©ï¼Œã„ãã¤ã‹ã®åˆ¶é™äº‹é …ãŒã‚ã‚‹ã“ã¨ãŒçŸ¥ã‚‰ã‚Œã¦ã„る.ãã®ãŸã‚,
+% 大ãã„ソースファイルをLuaJIT\TeX ã§ã‚¿ã‚¤ãƒ—セットã™ã‚‹ã¨Luaã®å´ã§``out of memory''エラーãŒç™ºç”Ÿã—ã¦ã—ã¾ã†ï¼Ž
+% 本ドキュメントã®ã‚ˆã†ã«ï¼Œã€Œå„ページã”ã¨ã«Luaã§ä½¿ã£ã¦ã„るメモリ容é‡ã‚’ãƒã‚§ãƒƒã‚¯ã—,
+% å¿…è¦ãªã‚‰\texttt{collectgarbage("collect")}ã§ã‚¬ãƒ™ãƒ¼ã‚¸ã‚³ãƒ¬ã‚¯ã‚¿ã‚’実行ã€ã™ã‚‹ã¨
+% 状æ³ãŒå¤šå°‘改善ã•ã‚Œã‚‹ã‹ã‚‚ã—ã‚Œãªã„.
+% ã¾ãŸï¼ŒLuaJIT\TeX ã§IPA mj明æœãªã©ã®ã€Œå¤§ãã„ã€ãƒ•ã‚©ãƒ³ãƒˆã‚’利用ã—ãŸå ´åˆã¯ãƒ•ã‚©ãƒ³ãƒˆã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®ä¿å­˜ã«å¤±æ•—ã—,
+% 毎回フォントを読ã¿è¾¼ã¾ãªã‘ã‚Œã°ãªã‚‰ãšçµæžœçš„ã«æ™‚é–“ãŒã‹ã‹ã‚‹ã“ã¨ãŒã‚る.
+% }.
+%</ja>
+
+\item%
+%<*en>
+\textbf{(Outdated) note for MiK\TeX\ users}\quad
+\LuaTeX-ja requires that several CMap files%
+\footnote{\texttt{UniJIS2004-UTF32-\{H,V\}} and \texttt{Adobe-Japan1-UCS2}.}
+must be found from \LuaTeX.
+Strictly speaking, those CMaps are needed
+only in the first run of \LuaTeX-ja after installing or updating.
+But it seems that MiK\TeX\ does not satisfy this condition,
+so you will encounter an error like the following:
+%</en>
+%<*ja>
+\LuaTeX-jaãŒå‹•ä½œã™ã‚‹ãŸã‚ã«ã¯ï¼Œ\emph{導入・更新後ã®åˆå›žèµ·å‹•æ™‚ã«}
+\texttt{UniJIS2004-UTF32-\{H,V\}}, \texttt{Adobe-Japan1-UCS2}ã¨ã„ã†3ã¤ã®CMapãŒ
+\LuaTeX ã«ã‚ˆã£ã¦è¦‹ã¤ã‘られるã“ã¨ãŒå¿…è¦ã§ã‚る.
+ã—ã‹ã—å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®MiK\TeX ã§ã¯ãã®ã‚ˆã†ã«ãªã£ã¦ã„ãªã„ã®ã§ï¼Œæ¬¡ã®ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã™ã‚‹ã ã‚ã†ï¼š
+%</ja>
+\begin{lstlisting}
+! LuaTeX error ...iles (x86)/MiKTeX 2.9/tex/luatex/luatexja/ltj-rmlgbm.lua
+bad argument #1 to 'open' (string expected, got nil)
+\end{lstlisting}
+
+%<*en>
+If so, please execute a batch file which is written on
+\href{https://osdn.jp/projects/luatex-ja/wiki/FrontPage%28en%29}{ the Project Wiki (English)}.
+This batch file creates a temporary directory, copy CMaps in it,
+run a test file which loads \LuaTeX-ja in this directory,
+and finally delete the temporary directory.
+%</en>
+%<*ja>
+ãã®ã‚ˆã†ãªå ´åˆã«ã¯ï¼Œ
+\href{https://osdn.jp/projects/luatex-ja/wiki/FrontPage%28en%29}{%
+ プロジェクトWiki英語版トップページ}中ã«æ›¸ã‹ã‚Œã¦ã„ã‚‹ãƒãƒƒãƒãƒ•ã‚¡ã‚¤ãƒ«ã‚’
+実行ã—ã¦æ¬²ã—ã„.ã“ã®ãƒãƒƒãƒãƒ•ã‚¡ã‚¤ãƒ«ã¯ï¼Œä½œæ¥­ç”¨ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«CMapé”ã‚’
+コピーã—,ãã®ä¸­ã§\LuaTeX-jaã®åˆå›žèµ·å‹•ã‚’è¡Œã„,作業用ディレクトリを消ã™ä½œæ¥­ã‚’ã—ã¦ã„る.
+%</ja>
+
+\end{itemize}
+
+%<en>\subsection{Using in plain \TeX}
+%<ja>\subsection{plain \TeX ã§ä½¿ã†}
+\label{ssec:plain}
+
+%<en>To use \LuaTeX-ja in plain \TeX, simply put the following at the beginning of the document:
+%<ja>\LuaTeX-jaã‚’ plain \TeX ã§ä½¿ã†ãŸã‚ã«ã¯ï¼Œå˜ã«æ¬¡ã®è¡Œã‚’ソースファイルã®å†’é ­ã«è¿½åŠ ã™ã‚Œã°ã‚ˆã„:
+\begin{lstlisting}
+\input luatexja.sty
+\end{lstlisting}
+%<en>This does minimal settings (like \texttt{ptex.tex}) for typesetting Japanese documents:
+%<ja>ã“ã‚Œã§ï¼ˆ\texttt{ptex.tex}ã®ã‚ˆã†ã«ï¼‰æ—¥æœ¬èªžçµ„版ã®ãŸã‚ã®æœ€ä½Žé™ã®è¨­å®šãŒãªã•ã‚Œã‚‹ï¼š
+
+\begin{itemize}
+%<*en>
+\item The following 12~Japanese fonts are preloaded:
+\begin{center}\small
+\begin{tabular}{llllll}
+\toprule
+\textbf{direction}&
+\textbf{classification}&\textbf{font name}&\bfseries ``10\,pt''&\bfseries ``7\,pt''&\bfseries ``5\,pt''\\\midrule
+\smash{\raisebox{-1ex}{\emph{yoko} (horizontal)}}&
+\emph{mincho}&IPAex Mincho&\cs{tenmin}&\cs{sevenmin}&\cs{fivemin}\\
+&\emph{gothic}&IPAex Gothic&\cs{tengt} &\cs{sevengt} &\cs{fivegt}\\
+\midrule
+\smash{\raisebox{-1ex}{\emph{tate} (vertical)}}&
+\emph{mincho}&IPAex Mincho&\cs{tentmin}&\cs{seventmin}&\cs{fivetmin}\\
+&\emph{gothic}&IPAex Gothic&\cs{tentgt} &\cs{seventgt} &\cs{fivetgt}\\
+\bottomrule
+\end{tabular}
+\end{center}
+%</en>
+%<*ja>
+\item 以下ã®12個ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãŒå®šç¾©ã•ã‚Œã‚‹ï¼š
+\begin{center}\small
+\begin{tabular}{llllll}
+\toprule
+\emph{組方å‘}&\emph{字体}&\emph{フォントå}&\bfseries``10\,pt''&\bfseries``7\,pt''&\bfseries``5\,pt''\\\midrule
+\smash{\raisebox{-0.7\zh}{横組}}&
+明æœä½“&IPAex明æœ&\cs{tenmin}&\cs{sevenmin}&\cs{fivemin}\\
+&\textgt{ゴシック体}&IPAexゴシック&\cs{tengt} &\cs{sevengt} &\cs{fivegt}\\
+\midrule
+\smash{\raisebox{-0.7\zh}{縦組}}&
+明æœä½“&IPAex明æœ&\cs{tentmin}&\cs{seventmin}&\cs{fivetmin}\\
+&\textgt{ゴシック体}&IPAexゴシック&\cs{tentgt} &\cs{seventgt} &\cs{fivetgt}\\
+\bottomrule
+\end{tabular}
+\end{center}
+%</ja>
+\begin{itemize}
+%<*en>
+\item The ``default'' Japanese fonts (and~JFMs for them) can be
+ modified by defining \cs{ltj@stdmcfont} etc.\ \emph{before}
+ one inputs \texttt{luatexja.sty} (Subsection~\ref{ssec:cfg}).
+%</en>
+%<*ja>
+\item 標準和文フォントやJFMã‚’IPAexフォントã‹ã‚‰åˆ¥ã®ã‚‚ã®ã«ç½®ãæ›ãˆã‚‹ã«ã¯ï¼Œ
+ \cs{ltj@stdmcfont}等を\texttt{luatexja.sty}読ã¿è¾¼ã¿\emph{å‰}ã«å®šç¾©ã™ã‚Œã°ã‚ˆã„.
+ \ref{ssec:cfg}節をå‚照.
+%</ja>
+
+%<*en>
+\item A character in an alphabetic font is generally smaller than a
+ Japanese font in the same size. So actual size specification of
+ these Japanese fonts is in fact smaller than that of alphabetic
+ fonts, namely scaled by 0.962216.
+%</en>
+%<*ja>
+\item 欧文フォントã®æ–‡å­—ã¯å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®æ–‡å­—よりも,åŒã˜æ–‡å­—サイズã§ã‚‚
+ 一般ã«å°ã•ãデザインã•ã‚Œã¦ã„る.ãã“ã§ï¼Œæ¨™æº–ã§ã¯ã“れらã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®å®Ÿéš›ã®ã‚µã‚¤ã‚ºã¯æŒ‡å®šã•ã‚ŒãŸå€¤ã‚ˆã‚Šã‚‚
+ å°ã•ããªã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ãŠã‚Šï¼Œå…·ä½“çš„ã«ã¯æŒ‡å®šã®0.962216å€ã«ã‚¹ã‚±ãƒ¼ãƒ«ã•ã‚Œã‚‹ï¼Ž
+ ã“ã®0.962216ã¨ã„ã†æ•°å€¤ã‚‚,\pTeX ã«ãŠã‘るスケーリングをè¸è¥²ã—ãŸå€¤ã§ã‚る.
+%</ja>
+\end{itemize}
+
+%<*en>
+\item The amount of glue that are inserted between a \textbf{JAchar} and
+ an \textbf{ALchar} (the parameter \Param{xkanjiskip}) is set to
+%</en>
+%<*ja>
+\item \textbf{JAchar}ã¨\textbf{ALchar}ã®é–“ã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼(\Param{xkanjiskip})ã®
+ é‡ã¯æ¬¡ã®ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„る:
+%</ja>
+\[
+ (0.25\cdot 0.962216\cdot 10\,\mathrm{pt})^{+1\,\text{pt}}_{-1\,\text{pt}}
+ = 2.40554\,\mathrm{pt}^{+1\,\text{pt}}_{-1\,\text{pt}}.
+\]
+\end{itemize}
+
+%<en>\subsection{Using in \LaTeX}
+%<ja>\subsection{\LaTeX ã§ä½¿ã†}
+\label{ssec:ltx}
+
+%<*en>
+Using in \LaTeXe\ is basically same. To set up the minimal environment
+for Japanese, you only have to load \texttt{luatexja.sty}:
+%</en>
+%<*ja>
+\LaTeXe を用ã„ã‚‹å ´åˆã‚‚基本的ã«ã¯åŒã˜ã§ã‚る.日本語組版ã®ãŸã‚ã®æœ€ä½Žé™ã®ç’°å¢ƒã‚’
+設定ã™ã‚‹ãŸã‚ã«ã¯ï¼Œ\texttt{luatexja.sty}を読ã¿è¾¼ã‚€ã ã‘ã§ã‚ˆã„:
+%</ja>
+\begin{lstlisting}
+\usepackage{luatexja}
+\end{lstlisting}
+%<*en>
+It also does minimal settings (counterparts in \pLaTeX\ are \texttt{%
+plfonts.dtx} and \texttt{pldefs.ltx}).
+%</en>
+%<*ja>
+ã“ã‚Œã§\pLaTeX ã®\texttt{plfonts.dtx}ã¨\texttt{pldefs.ltx}ã«ç›¸å½“ã™ã‚‹æœ€ä½Žé™ã®è¨­å®šãŒ
+ãªã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+\begin{itemize}
+%<*en>
+\item Font encodings for Japanese fonts are \texttt{JY3}~(for horizontal direction) and
+\texttt{JT3}~(for vertical direction).
+%</en>
+%<*ja>
+\item 和文フォントã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã¨ã—ã¦ã¯ï¼Œæ¨ªçµ„用ã«ã¯ \texttt{JY3},縦組用ã«ã¯\
+\texttt{JT3}ãŒç”¨ã„られる.
+%</ja>
+
+%<*en>
+\item Traditionally, Japanese documents use only two families: \emph{mincho}~(明æœä½“) and
+ \emph{gothic}~(\textgt{ゴシック体}). \emph{mincho} is used in the main text, while \emph{gothic}
+ is used in the headings or for emphasis.
+\begin{center}\small
+\begin{tabular}{lllc}
+\toprule
+\textbf{classification}&&&\textbf{commands}\\\midrule
+\emph{mincho} (明æœä½“)&\verb+\textmc{...}+&\verb+{\mcfamily ...}+&\cs{mcdefault}\\
+\emph{gothic} (\textgt{ゴシック体})&\verb+\textgt{...}+&\verb+{\gtfamily ...}+&\cs{gtdefault}\\
+\bottomrule
+\end{tabular}
+\end{center}
+\item
+By default, the following fonts are used for these two families.
+\begin{center}\small
+\begin{tabular}{lllll}
+\toprule
+\textbf{classification}&\textbf{family}&\cs{mdseries}&\cs{bfseries}&\textbf{scale}\\\midrule
+\emph{mincho} (明æœä½“)&\tt mc&IPAex Mincho&IPAex Gothic&0.962216\\
+\emph{gothic} (\textgt{ゴシック体})&\tt gt&IPAex Gothic&IPAex Gothic&0.962216\\
+\bottomrule
+\end{tabular}
+\end{center}
+\item Note that the bold series (series \texttt{bx}~or~\texttt{b}) in both family
+ are same as the medium series of gothic family.
+ There is no italic nor slanted shape for these \texttt{mc}~and~\texttt{gt}.
+%</en>
+%<*ja>
+\item \pLaTeX ã¨åŒæ§˜ã«ï¼Œæ¨™æº–ã§ã¯ã€Œæ˜Žæœä½“ã€ã€Œã‚´ã‚·ãƒƒã‚¯ä½“ã€ã®2種類を用ã„る:
+\begin{center}\small
+\begin{tabular}{llll}
+\toprule
+\emph{字体}&&&\emph{ファミリå}\\\midrule
+明æœä½“&\verb+\textmc{...}+&\verb+{\mcfamily ...}+&\cs{mcdefault}\\
+\textgt{ゴシック体}&\verb+\textgt{...}+&\verb+{\gtfamily ...}+&\cs{gtdefault}\\
+\bottomrule
+\end{tabular}
+\end{center}
+ \newpage
+\item 標準ã§ã¯ï¼Œæ¬¡ã®ãƒ•ã‚©ãƒ³ãƒˆãŒç”¨ã„られる:
+\begin{center}\small
+\begin{tabular}{lllll}
+\toprule
+\emph{字体}&\emph{ファミリ}&\cs{mdseries}&\cs{bfseries}&\emph{スケール}\\\midrule
+明æœä½“&\tt mc&IPAex明æœ&IPAexゴシック&0.962216\\
+\textgt{ゴシック体}&\tt gt&IPAexゴシック&IPAexゴシック&0.962216\\
+\bottomrule
+\end{tabular}
+\end{center}
+
+明æœãƒ»ã‚´ã‚·ãƒƒã‚¯ã©ã¡ã‚‰ã®ãƒ•ã‚¡ãƒŸãƒªã«ãŠã„ã¦ã‚‚,太字(\cs{bfseries})ã®ãƒ•ã‚©ãƒ³ãƒˆã¯
+ゴシック体中字(\cs{gtfamily}\cs{mdseries})ã§ä½¿ã‚れるフォントã¨åŒã˜ã§ã‚ã‚‹ã“ã¨ã«æ³¨æ„.
+ã¾ãŸï¼Œã©ã¡ã‚‰ã®ãƒ•ã‚¡ãƒŸãƒªã§ã‚‚イタリック体・スラント体ã¯å®šç¾©ã•ã‚Œãªã„.
+
+ \item 和文ã®å¤ªå­—を表ã™ã‚·ãƒªãƒ¼ã‚ºåã¯ï¼Œï¼ˆå…ƒã€…ã®Computer ModernãŒ
+ 太字ã«\texttt{bx}を用ã„ã¦ã„ãŸã“ã¨ã‹ã‚‰ï¼‰ä¼çµ±çš„ã«\texttt{bx}~(Bold Extended)ãŒä½¿ã‚ã‚Œã¦ããŸï¼Ž
+ ã—ã‹ã—,太字ã«ã‚·ãƒªãƒ¼ã‚º\texttt{b}を使ã†ãƒ•ã‚©ãƒ³ãƒˆã‚‚増ãˆã¦ããŸãŸã‚,
+ ãƒãƒ¼ã‚¸ãƒ§ãƒ³20180616.0以é™ã§ã¯å’Œæ–‡ã®å¤ªå­—ã¨ã—ã¦\texttt{bx},~\texttt{b}ã®ä¸¡æ–¹ã‚’扱ãˆã‚‹ã‚ˆã†ã«ã—ãŸï¼Ž
+%</ja>
+
+%<*en>
+ \item From version~20181102.0, one can specifies \texttt{disablejfam} option at
+ loading \LuaTeX-ja. This option prevents loading a patch for \LaTeX, which are
+ needed to support Japanese characters in math mode.
+
+ Without \texttt{disablejfam} option, one can typeset Japanese characters in
+ math mode as~\verb+$ã‚$+ (see Page~\pageref{para:jachar_in_math}) as before.
+ Japanese characters in math mode are typeset by the font family \texttt{mc}.
+%</en>
+%<*ja>
+ \item ãƒãƒ¼ã‚¸ãƒ§ãƒ³20181102.0以é™ã§ã¯ï¼Œ\texttt{disablejfam}オプションを\LuaTeX-ja読ã¿è¾¼ã¿æ™‚ã«
+ 指定ã§ãるよã†ã«ãªã£ãŸï¼Žã“ã®ã‚ªãƒ—ションã¯ï¼Œæ•°å¼ãƒ¢ãƒ¼ãƒ‰ä¸­ã«ç›´ã«å’Œæ–‡æ–‡å­—を書ã‘るよã†ã«ã™ã‚‹ãŸã‚ã®
+ \LaTeX ã¸ã®ãƒ‘ッãƒã‚’読ã¿è¾¼ã¾ãªã„.
+
+ \texttt{disablejfam}ã®ãªã„状æ³ã§ã¯ï¼Œä»¥å‰ã¨åŒæ§˜ã«å’Œæ–‡æ–‡å­—ã‚’æ•°å¼ãƒ¢ãƒ¼ãƒ‰ä¸­ã«
+ ç›´ã«æ›¸ãã“ã¨ãŒã§ãる(但ã—\autoref{para:jachar_in_math}ページã®è¨˜è¿°ã‚‚å‚照).
+ ãã®éš›ã«ã¯æ˜Žæœä½“(\texttt{mc})ã§å‡ºåŠ›ã•ã‚Œã‚‹ï¼Ž
+%</ja>
+%<*en>
+ \item \cs{jttdefault}%
+ \footnote{%
+ When \Pkg{ltjsclasses} classes are used, or
+ \Pkg{luatexja-fontspec} (or \Pkg{luatexja-preset}) is loaded with \texttt{match} option,
+ \cs{ttfamily} changes the current Japanese font amily to \cs{jttdefault}.
+ These classes and packages also redefine \cs{jttdefault} to
+ \cs{gtdefault} (\emph{gothic}~family).
+ } specifies the Japanese font family in \cs{verb}~or~\texttt{verbatim} environment.
+ The default value of \cs{jttdefault} is \cs{mcdefault}, so the mincho family is used.
+%</en>
+%<*ja>
+ \item \cs{verb} ã‚„ \texttt{verbatim} 環境中ã®å’Œæ–‡æ–‡å­—ã«ä½¿ã‚れる和文フォントファミリã¯
+ \ \cs{jttdefault} ã§æŒ‡å®šã™ã‚‹%
+ \footnote{%
+ \Pkg{ltjsclasses}を使用ã—ãŸã‚Šï¼Œã‚ã‚‹ã„㯠\texttt{match} オプションを指定ã—ã¦\Pkg{luatexja-fontspec}%
+ ã‚„\Pkg{luatexja-preset}パッケージを読ã¿è¾¼ã‚“ã ã¨ãã¯ï¼Œå˜ãªã‚‹ \cs{ttfamily} ã«ã‚ˆã£ã¦ã‚‚和文フォントãŒ
+ \ \cs{jttdefault}\ ã«å¤‰æ›´ã•ã‚Œã‚‹ï¼Žã¾ãŸï¼Œã“れらã®ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã‚„パッケージã¯
+ \ \cs{jttdefault}\ ã‚’ \cs{gtdefault}(ゴシック体)ã«å†å®šç¾©ã™ã‚‹ï¼Ž
+ }.標準値㯠\cs{mcdefault},ã¤ã¾ã‚Šæ˜Žæœä½“ã¨ã—ã¦ç”¨ã„ã‚‹ã®ã¨
+ åŒã˜ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã§ã‚る.
+%</ja>
+
+%<*en>
+\item If you use the \Pkg{beamer} class with the default font theme (which uses sans serif
+ fonts) and with \LuaTeX-ja, you might want to change default Japanese fonts to
+ the gothic family. The following line changes the default Japanese font family
+ to it:
+%</en>
+%<*ja>
+\item \Pkg{beamer}クラスを既定ã®ãƒ•ã‚©ãƒ³ãƒˆè¨­å®šã§ä½¿ã†å ´åˆï¼Œæ—¢å®šæ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆãŒã‚µãƒ³ã‚»ãƒªãƒ•ãªã®
+ ã§ï¼Œæ—¢å®šå’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚‚ゴシック体ã«ã—ãŸã„ã¨æ€ã†ã‹ã‚‚ã—ã‚Œãªã„.ãã®å ´åˆã¯ãƒ—リアンブルã«
+次を書ã‘ã°ã‚ˆã„:
+%</ja>
+\begin{lstlisting}
+ \renewcommand{\kanjifamilydefault}{\gtdefault}
+\end{lstlisting}
+
+%<*ja>
+\item \pLaTeX ã¨åŒæ§˜ã«ï¼Œ\texttt{mc},~\texttt{gt}両ファミリã«ã¯ã€Œå¾“属欧文ã€æ›¸ä½“ãŒå®šç¾©ã•ã‚Œã¦ã„る.
+ ã“れらã¯\cs{userelfont}ã‚’\cs{selectfont}(や,ãã®ä»–ã®ã€Œå®Ÿéš›ã«ã€
+ フォントを変更ã™ã‚‹å‘½ä»¤ï¼‰ã®å‰ã§å®Ÿè¡Œã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šä½¿ã†ã“ã¨ãŒã§ãる.
+
+ \pLaTeX ã§ã¯æ¨™æº–ã®æ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆã¯OT1エンコーディングã®Computer Modern Roman (\texttt{cmr})%
+ ã§ã‚ã£ãŸãŒï¼Œ2017年以é™ã®\LuaLaTeX ã§ã¯TUエンコーディングã®latin Modern Roman (\texttt{lmr})%
+ ã«å¤‰æ›´ã•ã‚Œã¦ã„る.ãã®ãŸã‚,å‰æ®µè½ã§è¿°ã¹ãŸã€Œå¾“属欧文ã€ã‚‚,Latin Modern Romanã«è¨­å®šã—ã¦ã„る.
+%</ja>
+
+\end{itemize}
+
+%<*en>
+However, above settings are not sufficient for Japanese-based
+documents. To typeset Japanese-based documents, you are better to use
+class files other than \texttt{article.cls}, \texttt{book.cls}, and so on. At
+the present, \LuaTeX-ja has the counterparts of \Pkg{jclasses} (standard
+classes in \pLaTeX) and \Pkg{jsclasses} (classes by Haruhiko
+Okumura), namely, \Pkg{ltjclasses}\footnote{%
+ \texttt{ltjarticle.cls},~\texttt{ltjbook.cls}, \texttt{ltjreport.cls},
+ \texttt{ltjtarticle.cls}, \texttt{ltjtbook.cls}, \texttt{ltjtreport.cls}.
+ The latter \texttt{ltjt*.cls} are for vertically written Japanese documents.
+} and \Pkg{ltjsclasses}\footnote{%
+ \texttt{ltjsarticle.cls},~\texttt{ltjsbook.cls}, \texttt{ltjsreport.cls},~\texttt{ltjskiyou.cls}.}.
+
+Original \Pkg{jsclasses} use \cs{mag}~primitive to set the main document font size.
+However, \LuaTeX\ does not support \cs{mag} in PDF~output,
+so \Pkg{ltjsclasses} uses the \texttt{nomag*} option\footnote{Same effect as
+ the \Pkg{BXjscls} classes (by Takayuki Yato) and \Pkg{jsclasses}.
+ However, these classes uses only \TeX\ code, but \Pkg{ltjsclasses} uses Lua code.}
+ by default to set the main font size. If this causes some unexpected behavior, specify
+\texttt{nomag} option in \cs{documentclass}.
+%</en>
+%<*ja>
+ã—ã‹ã—ãªãŒã‚‰ï¼Œä¸Šè¨˜ã®è¨­å®šã¯æ—¥æœ¬èªžã®æ–‡æ›¸ã«ã¨ã£ã¦å分ã¨ã¯è¨€ãˆãªã„.
+日本語文書を組版ã™ã‚‹ãŸã‚ã«ã¯ï¼Œ\texttt{article.cls}, \texttt{book.cls}ã¨ã„ã£ãŸ
+欧文用ã®ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã§ã¯ãªã,和文用ã®ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã‚’用ã„ãŸæ–¹ãŒã‚ˆã„.
+ç¾æ™‚点ã§ã¯ï¼Œ\Pkg{jclasses}(\pLaTeX ã®æ¨™æº–クラス)ã¨\Pkg{jsclasses}%
+(奥æ‘晴彦æ°ã«ã‚ˆã‚‹ã€Œ\pLaTeXe 新ドキュメントクラスã€ï¼‰ã«å¯¾å¿œã™ã‚‹ã‚‚ã®ã¨ã—ã¦ï¼Œ
+\Pkg{ltjclasses}\footnote{%
+ 横組用㯠\texttt{ltjarticle.cls},~\texttt{ltjbook.cls}, \texttt{ltjreport.cls} ã§ã‚り,
+ 縦組用㯠\texttt{ltjtarticle.cls}, \texttt{ltjtbook.cls}, \texttt{ltjtreport.cls} ã§ã‚る.
+},
+\Pkg{ltjsclasses}\footnote{%
+ \texttt{ltjsarticle.cls},~\texttt{ltjsbook.cls}, \texttt{ltjsreport.cls},~\texttt{ltjskiyou.cls}.}%
+ãŒãã‚Œãžã‚Œ\LuaTeX-ja標準ã§ç”¨æ„ã•ã‚Œã¦ã„る.
+
+元々ã®\Pkg{jsclasses}ã§ã¯æœ¬æ–‡ã®ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã‚’設定ã™ã‚‹ã®ã«\cs{mag}プリミティブãŒä½¿ã‚ã‚Œã¦ã„ãŸãŒï¼Œ
+\LuaTeX ã§ã¯PDF出力時ã®\cs{mag}ã®ã‚µãƒãƒ¼ãƒˆãŒå»ƒæ­¢ã•ã‚ŒãŸï¼Ž
+ãã®ãŸã‚,\Pkg{ltjsclasses}ã§ã¯\texttt{nomag*}オプション
+\footnote{\Pkg{jsclasses}や,八登崇之æ°ã«ã‚ˆã‚‹\Pkg{BXjscls}クラスã«ãŠã‘ã‚‹åŒåã®ã‚ªãƒ—ションã¨
+ åŒã˜ï¼Žä¸Šè¨˜ã‚¯ãƒ©ã‚¹ã¯\TeX コードã®ã¿ã§å®Ÿè£…ã—ã¦ã„ã‚‹ãŒï¼Œ\Pkg{ltjsclasses}ã§ã¯Luaコードも用ã„ã¦ã„る.}ãŒæ¨™æº–ã§
+有効ã«ãªã£ã¦ãŠã‚Šï¼Œã“れを使ã£ã¦æœ¬æ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã®è¨­å®šã‚’è¡Œã£ã¦ã„る.
+ã—ã‹ã—,ã“ã®\texttt{nomag*}オプションã§ã¯ï¼ˆ20180121.0版よりå‰ã®ç‰ˆã«ãŠã„ã¦\Pkg{unicode-math}パッケージ使用時ã«
+èµ·ããŸã‚ˆã†ã«ï¼‰äºˆæƒ³å¤–ã®æ„図ã—ãªã„ç¾è±¡ã«é­é‡ã™ã‚‹å±é™ºãŒã‚る.ãã®ã‚ˆã†ãªå ´åˆã¯
+\cs{documentclass}ã«ãŠã„ã¦\texttt{nomag}オプションを指定ã—ã¦ã»ã—ã„.
+%</ja>
+
+%<*ja>
+\paragraph{脚注ã¨ãƒœãƒˆãƒ ãƒ•ãƒ­ãƒ¼ãƒˆã®å‡ºåŠ›é †åº}
+オリジナルã®\LaTeX ã§ã¯è„šæ³¨ã¯ãƒœãƒˆãƒ ãƒ•ãƒ­ãƒ¼ãƒˆã®ä¸Šã«å‡ºåŠ›ã•ã‚Œï¼Œã¾ãŸ\cs{raggedbottom}命令ã§ãƒšãƒ¼ã‚¸ã®é«˜ã•ãŒä¸æƒã„ã§ã‚ã‚‹ã“ã¨ã‚’許ã—ãŸå ´åˆã«ã¯
+脚注ã®ä¸‹ç«¯ã®åž‚ç›´ä½ç½®ã‚‚ページã«å¿œã˜ã¦å¤‰ã‚るよã†ã«ãªã£ã¦ã„る.
+一方,日本語ã®çµ„版ã§ã¯è„šæ³¨ã¯ãƒœãƒˆãƒ ãƒ•ãƒ­ãƒ¼ãƒˆã®ä¸‹ã«æ¥ã‚‹ã®ãŒä¸€èˆ¬çš„ã§ã‚ã‚‹ã®ã§ï¼Œ
+\pLaTeX ã§ã¯ãã®ã‚ˆã†ã«å¤‰æ›´ã•ã‚Œã¦ãŠã‚Šï¼Œ
+ã•ã‚‰ã«\cs{raggedbottom}命令を実行ã—ãŸå¾Œã§ã‚‚脚注ã¯å¸¸ã«ãƒšãƒ¼ã‚¸ã®ä¸‹ç«¯ã«å›ºå®šã•ã‚Œã‚‹ã‚ˆã†ã«ãªã£ã¦ã„る.
+
+\LuaTeX-jaã§ã¯ã€Œæ¬§æ–‡ã‚¯ãƒ©ã‚¹ã®ä¸­ã«ã¡ã‚‡ã£ã¨ã ã‘日本語を入れるã€ã¨ã„ã†åˆ©ç”¨ã‚‚考慮ã—,
+脚注ã¨ãƒœãƒˆãƒ ãƒ•ãƒ­ãƒ¼ãƒˆã®é †åºï¼ŒåŠã³\cs{raggedbottom}時ã®è„šæ³¨ã®åž‚ç›´ä½ç½®ã¯\LaTeX 通りã¨ã—ãŸï¼Ž
+ã“れらを制御ã™ã‚‹ã«ã¯ä»¥ä¸‹ã®æ‰‹æ®µãŒã‚る:
+\begin{itemize}
+ \item \pLaTeX ã®ã‚ˆã†ã«ï¼Œè„šæ³¨ã‚’ボトムフロートã®ä¸‹ã«çµ„む場åˆã«ã¯
+ \Pkg{stfloats}パッケージを利用ã—ã¦
+ \begin{lstlisting}
+ \usepackage{stfloats}\fnbelowfloat
+ \end{lstlisting}
+ ã¨ã™ã‚‹ï¼Žã“ã®çŠ¶æ³ã‹ã‚‰ã€Œè„šæ³¨ã‚’ボトムフロートã®ä¸Šã«çµ„ã‚€ã€ã¨ã„ã†\LaTeX ã®æ¨™æº–ã®æŒ™å‹•ã«æˆ»ã—ãŸã‘ã‚Œã°ï¼Œ
+ \Pkg{stfloats}パッケージã®\cs{fnunderfloat}命令を使用ã™ã‚‹ï¼Ž
+ \item \cs{raggedbottom}時ã®è„šæ³¨ã®åž‚ç›´ä½ç½®ã¯ï¼Œ\cs{iffnfixbottom}ã¨ã„ã†çœŸå½å€¤ã§åˆ¶å¾¡ã™ã‚‹ï¼Ž
+ \begin{description}
+ \item[å½(\cs{fnfixbottomfalse})ã®å ´åˆ] \LaTeX 標準ã¨åŒã˜ã,本文ã¨è„šæ³¨ã®é–“ã®ç©ºç™½ã¯\cs{skip}\cs{footins}ã®ã¿ï¼Ž
+ 従ã£ã¦è„šæ³¨ã®åž‚ç›´ä½ç½®ã¯ãƒšãƒ¼ã‚¸ã«ã‚ˆã‚Šå¤‰å‹•ã™ã‚‹ï¼Ž
+ \item[真(\cs{fnfixbottomtrue})ã®å ´åˆ] \pLaTeX ã‚„\Pkg{footmisc}パッケージを\texttt{bottom}オプションã§
+ 読ã¿è¾¼ã‚“ã å ´åˆã®ã‚ˆã†ã«ï¼Œè„šæ³¨ã¯å¸¸ã«ãƒšãƒ¼ã‚¸ã®ä¸‹ç«¯ã«å›ºå®šã•ã‚Œã‚‹ï¼Ž
+ \end{description}
+\item ãŸã ã—,\LuaTeX-jaãŒæä¾›ã™ã‚‹ã€Œäº’æ›ã‚¯ãƒ©ã‚¹ã€(\Pkg{ltjclasses}, \Pkg{ltjsclasses})ã§ã¯ï¼Œ
+ \pLaTeX ã¨åˆã‚ã›ã‚‹ãŸã‚ã«ä»¥ä¸‹ã®ã‚ˆã†ã«ã—ã¦ã„る:
+ \begin{itemize}
+ \item \cs{fnfixbottomtrue}ãŒè‡ªå‹•çš„ã«å®Ÿè¡Œã•ã‚Œã‚‹
+ \item \Pkg{stfloats}パッケージãŒ\LuaTeX ã‹ã‚‰å‚ç…§ã§ãる場所ã«ã‚ã£ãŸå ´åˆã¯
+ 自動的ã«èª­ã¿è¾¼ã¿ï¼Œ\cs{fnbelowfloat}を実行ã™ã‚‹ï¼Ž
+ \end{itemize}
+\end{itemize}
+ãªãŠï¼Œ\Pkg{stfloats}パッケージを使ã†ä»£ã‚ã‚Šã«ï¼Œ
+\Pkg{footmisc}パッケージを \texttt{bottom}オプションを指定ã—ã¦èª­ã¿è¾¼ã‚€
+ã¨ã„ã†ã€Œè§£æ±ºæ³•ã€ã‚‚ã‚る.
+%</ja>
+%%% ↑ã¯è‹±è¨³ã—ãªã„
+
+%<*en>
+\paragraph{\Pkg{geometry} package and classes for vertical writing}
+It is well-known that the \Pkg{geometry} package produces the following error, when classes for
+vertical writing is used:
+%</en>
+%<*ja>
+\paragraph{縦組ã§ã®\Pkg{geometry}パッケージ}
+\pLaTeX ã®ç¸¦çµ„用標準クラスファイルã§ã¯\Pkg{geometry}パッケージを利用ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ãšï¼Œ
+%</ja>
+\begin{lstlisting}
+! Incompatible direction list can't be unboxed.
+\@begindvi ->\unvbox \@begindvibox
+ \global \let \@begindvi \@empty
+\end{lstlisting}
+%<*en>
+Now, \LuaTeX-ja automatically applies the patch \Pkg{lltjp-geometry} to the
+\Pkg{geometry} package, when the direction of the document is \emph{tate} (vertical
+writing).
+This patch \Pkg{lltjp-geometry} also can be used in \pLaTeX; for the detail, please refer
+\url{lltjp-geometry.pdf}~(Japanese).
+%</en>
+%<*ja>
+ã¨ã„ã†ã‚ˆã†ãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã™ã‚‹ã“ã¨ãŒçŸ¥ã‚‰ã‚Œã¦ã„る.
+\LuaTeX-jaã§ã¯ï¼Œ \texttt{ltjtarticle.cls} ã¨ã„ã£ãŸç¸¦çµ„クラスã®ä¸‹ã§ã‚‚
+\Pkg{geometry}パッケージãŒåˆ©ç”¨ã§ãるよã†ã«ãƒ‘ッãƒ\Pkg{lltjp-geometry}パッケージを自動的ã«å½“ã¦ã¦ã„る.
+
+ãªãŠï¼Œ\Pkg{lltjp-geometry}パッケージã¯\pTeX 系列ã§ã‚‚明示的ã«èª­ã¿è¾¼ã‚€ã“ã¨ã«ã‚ˆã£ã¦
+使用å¯èƒ½ã§ã‚る.詳細や注æ„事項㯠\url{lltjp-geometry.pdf} ã‚’å‚ç…§ã®ã“ã¨ï¼Ž
+%</ja>
+
+
+%<en>\section{Changing Fonts}
+%<ja>\section{フォントã®å¤‰æ›´}
+
+\subsection{plain \TeX~and~\LaTeXe}
+\label{ssec:chgfnt}
+
+\paragraph{plain \TeX}
+%<*en>
+To change Japanese fonts in plain \TeX, you must use the command
+\cs{jfont}~and~\cs{tfont}. So please see Subsection~\ref{ssec:jfont}.
+%</en>
+%<*ja>
+plain \TeX ã§å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚’変更ã™ã‚‹ãŸã‚ã«ã¯ï¼Œ
+\pTeX ã®ã‚ˆã†ã« \cs{jfont} 命令や \cs{tfont} 命令を直接用ã„る.
+\ref{ssec:jfont}節をå‚照.
+%</ja>
+
+\paragraph{\LaTeXe\ (NFSS2)}
+%<*en>
+For \LaTeXe, \LuaTeX-ja adopted most of the font selection system of \pLaTeXe\ (in \texttt{plfonts.dtx}).
+%</en>
+%<*ja>
+\LaTeX ã§ç”¨ã„ã‚‹éš›ã«ã¯ï¼Œ\pLaTeXe\ (\texttt{plfonts.dtx})用ã®ãƒ•ã‚©ãƒ³ãƒˆé¸æŠžæ©Ÿæ§‹ã®å¤§éƒ¨åˆ†ã‚’æµç”¨ã—ã¦ã„る.
+%</ja>
+\begin{itemize}
+%<*en>
+\item Commands \cs{fontfamily}, \cs{fontseries}, and \cs{fontshape} can be used to change
+ attributes of Japanese fonts.
+%</en>
+%<*ja>
+\item 和文フォントã®å±žæ€§ã‚’変更ã™ã‚‹ã«ã¯ï¼Œ\cs{fontfamily}, \cs{fontseries}, \cs{fontshape} を使用ã™ã‚‹ï¼Ž
+ ã‚‚ã¡ã‚ん,ãれらを実際ã«å映ã•ã›ã‚‹ã«ã¯æ‰‹å‹•ã§ \cs{selectfont} を実行ã™ã‚‹å¿…è¦ãŒã‚る.
+%</ja>
+
+%<*en>
+\begin{center}\small
+\begin{tabular}{llllll}
+\toprule
+&\textbf{encoding}&\textbf{family}&\textbf{series}&\textbf{shape}&\textbf{selection}\\\midrule
+alphabetic fonts
+&\cs{romanencoding}&\cs{romanfamily}&\cs{romanseries}&\cs{romanshape}
+&\cs{useroman}\\
+Japanese fonts
+&\cs{kanjiencoding}&\cs{kanjifamily}&\cs{kanjiseries}&\cs{kanjishape}
+&\cs{usekanji}\\
+both&---&--&\cs{fontseries}&\cs{fontshape}&---\\
+auto select&\cs{fontencoding}&\cs{fontfamily}&---&---&\cs{usefont}\\
+\bottomrule
+\end{tabular}
+\end{center}
+%</en>
+%<*ja>
+\begin{center}\small
+\begin{tabular}{llllll}
+\toprule
+&\emph{エンコーディング}&\emph{ファミリ}&\emph{シリーズ}&\emph{シェープ}&\emph{é¸æŠž}\\\midrule
+\emph{欧文}
+&\cs{romanencoding}&\cs{romanfamily}&\cs{romanseries}&\cs{romanshape}
+&\cs{useroman}\\
+\emph{和文}
+&\cs{kanjiencoding}&\cs{kanjifamily}&\cs{kanjiseries}&\cs{kanjishape}
+&\cs{usekanji}\\
+\emph{両方}&---&--&\cs{fontseries}&\cs{fontshape}&---\\
+\emph{自動é¸æŠž}&\cs{fontencoding}&\cs{fontfamily}&---&---&\cs{usefont}\\
+\bottomrule
+\end{tabular}
+\end{center}
+%</ja>
+
+%<*en>
+ \verb+\fontencoding{+<encoding>\verb+}+ changes the encoding of alphabetic fonts
+ or Japanese fonts depending on the argument. For example,
+ \verb+\fontencoding{JY3}+ changes the encoding of Japanese fonts to
+ \texttt{JY3}, and \verb+\fontencoding{T1}+ changes the encoding of
+ alphabetic fonts to \texttt{T1}.
+ \cs{fontfamily} also changes the current Japanese font family,
+ the current alphabetic font family, \emph{or both}.
+ For the detail, see Subsection~\ref{ssec:nfsspat}.
+%</en>
+%<*ja>
+ ã“ã“ã§ï¼Œ\verb+\fontencoding{+<encoding>\verb+}+ ã¯ï¼Œå¼•æ•°ã«ã‚ˆã‚Šå’Œæ–‡å´ã‹æ¬§æ–‡
+ å´ã‹ã®ã©ã¡ã‚‰ã‹ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã‚’変更ã™ã‚‹ï¼Žä¾‹ãˆã°ï¼Œ
+ \verb+\fontencoding{JY3}+ ã¯å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã‚’
+ \texttt{JY3}ã«å¤‰æ›´ã—,\verb+\fontencoding{T1}+ ã¯æ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆå´ã‚’
+ \texttt{T1}ã¸ã¨å¤‰æ›´ã™ã‚‹ï¼Ž\cs{fontfamily} も引数ã«ã‚ˆã‚Šå’Œæ–‡å´ï¼Œæ¬§æ–‡
+ å´ï¼Œ\emph{ã‚ã‚‹ã„ã¯ä¸¡æ–¹}ã®ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã‚’変更ã™ã‚‹ï¼Žè©³ç´°ã¯
+ \ref{ssec:nfsspat}節をå‚ç…§ã™ã‚‹ã“ã¨ï¼Ž
+%</ja>
+
+%<*en>
+\item For defining a Japanese font family, use
+ \cs{DeclareKanjiFamily} instead of
+ \cs{DeclareFontFamily}. (In previous version of \LuaTeX-ja,
+ using \cs{DeclareFontFamily} didn't cause any problem. But this no longer applies
+ the current version.)
+\item Defining a Japanese font shape can be done by usual \cs{DeclareFontShape}:
+%</en>
+%<*ja>
+\item 和文フォントファミリã®å®šç¾©ã«ã¯ \cs{DeclareFontFamily} ã®
+ 代ã‚ã‚Šã« \cs{DeclareKanjiFamily} を用ã„る.以å‰ã®
+ 実装ã§ã¯ \cs{DeclareFontFamily} を用ã„ã¦ã‚‚å•é¡Œã¯ç”Ÿã˜ãªã‹ã£ãŸãŒï¼Œç¾åœ¨ã®å®Ÿè£…ã§ã¯
+ ãã†ã¯ã„ã‹ãªã„.
+\item 和文フォントã®ã‚·ã‚§ã‚¤ãƒ—を定義ã™ã‚‹ã«ã¯ï¼Œé€šå¸¸ã® \cs{DeclareFontShape} を使ãˆã°è‰¯ã„:
+%</ja>
+\begin{lstlisting}
+\DeclareFontShape{JY3}{mc}{bx}{n}{<-> s*KozMinPr6N-Bold:jfm=ujis;-kern}{}
+ % Kozuka Mincho Pr6N Bold
+\end{lstlisting}
+%<*ja>
+ä»®å書体を使ã†å ´åˆãªã©ï¼Œè¤‡æ•°ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚’組ã¿åˆã‚ã›ã¦ä½¿ã„ãŸã„å ´åˆã¯
+\ref{ssec:altfont}節㮠\cs{ltjdeclarealtfont} ã¨ï¼Œãã®\LaTeX 版ã®\
+\cs{DeclareAlternateKanjiFont}(\ref{ssec:nfsspat}節)をå‚ç…§ã›ã‚ˆï¼Ž
+%</ja>
+
+\end{itemize}
+
+%<*en>
+\paragraph{Japanese characters in math mode}
+\label{para:jachar_in_math}
+
+Since \pTeX\ supports Japanese characters in math mode, there are
+sources like the following:
+%</en>
+%<*ja>
+\paragraph{æ•°å¼ãƒ¢ãƒ¼ãƒ‰ä¸­ã®å’Œæ–‡æ–‡å­—}
+\label{para:jachar_in_math}
+
+\pTeX ã§ã¯ï¼Œç‰¹ã«ä½•ã‚‚ã—ãªã„ã§ã‚‚æ•°å¼ä¸­ã«å’Œæ–‡æ–‡å­—を記述ã™ã‚‹ã“ã¨ãŒã§ããŸï¼Žãã®ãŸã‚,
+以下ã®ã‚ˆã†ãªã‚½ãƒ¼ã‚¹ãŒè¦‹ã‚‰ã‚ŒãŸï¼š
+%</ja>
+
+\begin{LTXexample}
+$f_{高温}$~($f_{\text{high temperature}}$).
+\[ y=(x-1)^2+2\quad よã£ã¦\quad y>0 \]
+$5\in ç´ :=\{\,p\in\mathbb N:\text{$p$ is a prime}\,\}$.
+\end{LTXexample}
+%<*en>
+We (the project members of \LuaTeX-ja) think that using
+Japanese characters in math mode are allowed if and only if these are used as identifiers.
+In this point of view,
+%</en>
+%<*ja>
+\LuaTeX-jaプロジェクトã§ã¯ï¼Œæ•°å¼ãƒ¢ãƒ¼ãƒ‰ä¸­ã§ã®å’Œæ–‡æ–‡å­—ã¯ãれらãŒè­˜åˆ¥å­ã¨ã—ã¦ç”¨ã„られる
+ã¨ãã®ã¿è¨±ã•ã‚Œã‚‹ã¨è€ƒãˆã¦ã„る.
+ã“ã®è¦³ç‚¹ã‹ã‚‰ï¼Œ
+%</ja>
+
+\begin{itemize}
+%<*en>
+\item The lines 1~and~2 above are not correct, since ``高温'' in above is used as a textual label, and
+``よã£ã¦'' is used as a conjunction.
+%</en>
+%<*ja>
+\item 上記数å¼ã®ã†ã¡1, 2行目ã¯æ­£ã—ããªã„.ãªãœãªã‚‰ã°ã€Œé«˜æ¸©ã€ãŒæ„味ã®ã‚るラベルã¨
+ ã—ã¦ï¼Œã€Œã‚ˆã£ã¦ã€ãŒæŽ¥ç¶šè©žã¨ã—ã¦ç”¨ã„られã¦ã„ã‚‹ã‹ã‚‰ã§ã‚る.
+%</ja>
+%<en>\item However, the line~3 is correct, since ``ç´ '' is used as an identifier.
+%<ja>\item ã—ã‹ã—ãªãŒã‚‰ï¼Œ3行目ã¯ã€Œç´ ã€ãŒå˜ãªã‚‹è­˜åˆ¥å­ã¨ã—ã¦ç”¨ã„られã¦ã„ã‚‹ã®ã§æ­£ã—ã„.
+\end{itemize}
+%<en>Hence, in our opinion, the above input should be corrected as:
+%<ja>ã—ãŸãŒã£ã¦ï¼Œ\LuaTeX-jaプロジェクトã®æ„見ã¨ã—ã¦ã¯ï¼Œä¸Šè¨˜ã®å…¥åŠ›ã¯æ¬¡ã®ã‚ˆã†ã«ç›´ã•ã‚Œã‚‹ã¹ãã§ã‚る:
+\begin{LTXexample}
+$f_{\text{高温}}$~%
+($f_{\text{high temperature}}$).
+\[ y=(x-1)^2+2\quad
+ \mathrel{\mbox{よã£ã¦}}\quad y>0 \]
+$5\in ç´ :=\{\,p\in\mathbb N:\text{$p$ is a prime}\,\}$.
+\end{LTXexample}
+
+%<*en>
+We also believe that using Japanese characters as identifiers is rare,
+hence we don't describe how to change Japanese fonts in math mode in
+this chapter. For the method, please see Subsection~\ref{ssec:math}.
+
+{\emshape When \LuaTeX-ja is loaded with \texttt{disablejfam}~option,
+ one cannot write Japanese characters in math mode as~\verb+$ç´ $+.
+ At that case, one have to use \cs{mbox} (or~\cs{text} in the \Pkg{amsmath} package).
+}
+%</en>
+%<*ja>
+ãªãŠ\LuaTeX-jaプロジェクトã§ã¯ï¼Œå’Œæ–‡æ–‡å­—ãŒè­˜åˆ¥å­ã¨ã—ã¦ç”¨ã„られるã“ã¨ã¯ã»ã¨ã‚“ã©ãªã„
+ã¨è€ƒãˆã¦ãŠã‚Šï¼Œã—ãŸãŒã£ã¦ã“ã®ç¯€ã§ã¯æ•°å¼ãƒ¢ãƒ¼ãƒ‰ä¸­ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚’変更ã™ã‚‹æ–¹æ³•ã«ã¤ã„ã¦ã¯
+記述ã—ãªã„.ã“ã®æ–¹æ³•ã«ã¤ã„ã¦ã¯\ref{ssec:math}節をå‚ç…§ã®ã“ã¨ï¼Ž
+
+{\gtfamily\bfseries
+ æ—¢ã«è¨˜è¿°ã—ãŸé€šã‚Šï¼Œ\texttt{disablejfam}オプションを指定ã—ã¦\LuaTeX-jaを読ã¿è¾¼ã‚“ã å ´åˆã¯ï¼Œ
+ \verb+$ç´ $+ ã®ã‚ˆã†ã«ç›´æŽ¥å’Œæ–‡æ–‡å­—ã‚’æ•°å¼ãƒ¢ãƒ¼ãƒ‰ä¸­ã«è¨˜è¿°ã™ã‚‹ã“ã¨ã¯ã§ããªããªã‚‹ï¼Ž
+ \cs{mbox},ã‚ã‚‹ã„ã¯\Pkg{amsmath}パッケージã®æä¾›ã™ã‚‹\cs{text}命令ãªã©ã‚’使ã†ã“ã¨ã«ãªã‚‹ï¼Ž
+}
+%</ja>
+
+
+
+%<en>\subsection{\Pkg{luatexja-fontspec} package}
+%<ja>\subsection{\Pkg{luatexja-fontspec}パッケージ}
+\label{ssec:fontspec}
+%<*en>
+To use the functionality of the \Pkg{fontspec} package to Japanese fonts,
+it is needed to load the \Pkg{luatexja-fontspec} package in the preamble, as follows:
+\begin{quote}
+\ttfamily \textbackslash usepackage[<options>]\{luatexja-fontspec\}
+\end{quote}
+This \Pkg{luatexja-fontspec} package
+automatically loads \Pkg{luatexja} and \Pkg{fontspec}
+packages, if needed.
+%</en>
+%<*ja>
+\Pkg{fontspec}パッケージã¯ï¼Œ\LuaTeX・\XeTeX ã«ãŠã„ã¦
+TrueType・OpenTypeフォントを容易ã«æ‰±ã†ãŸã‚ã®ãƒ‘ッケージã§ã‚り,ã“ã®ãƒ‘ッケージを読ã¿è¾¼ã‚“ã§ãŠ
+ã‘ã°Unicodeã«ã‚ˆã‚‹å„種記å·ã®ç›´æŽ¥å…¥åŠ›ã‚‚ã§ãるよã†ã«ãªã‚‹ï¼Ž
+\LuaTeX-jaã§ã¯å’Œæ–‡ã¨æ¬§æ–‡ã‚’区別ã—ã¦ã„ã‚‹ãŸã‚,\Pkg{fontspec}パッケージã®æ©Ÿèƒ½ã¯æ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆã«
+対ã—ã¦ã®ã¿æœ‰åŠ¹ãªã‚‚ã®ã¨ãªã£ã¦ã„る.
+
+\LuaTeX-ja上ã«ãŠã„ã¦ï¼Œ\Pkg{fontspec}パッケージã¨åŒæ§˜ã®æ©Ÿèƒ½ã‚’和文フォントã«å¯¾ã—ã¦ã‚‚用ã„ã‚‹å ´
+åˆã¯\Pkg{luatexja-fontspec}パッケージを読ã¿è¾¼ã‚€ï¼š
+\begin{quote}
+\ttfamily \textbackslash usepackage[<options>]\{luatexja-fontspec\}
+\end{quote}
+ã“ã®ãƒ‘ッケージã¯è‡ªå‹•ã§\Pkg{luatexja}パッケージã¨\Pkg{fontspec}パッケージを読ã¿è¾¼ã‚€ï¼Ž
+%</ja>
+
+%<*en>
+In the \Pkg{luatexja-fontspec} package, several commands are defined as
+counterparts of original commands in the \Pkg{fontspec} package
+(see \autoref{tab:ltj_fntspc}):
+%</en>
+%<*ja>
+\Pkg{luatexja-fontspec}パッケージã§ã¯ï¼Œ\autoref{tab:ltj_fntspc}ã®
+「和文ã€è¡Œã«ç¤ºã—ãŸå‘½ä»¤ã‚’\Pkg{fontspec}パッケージã®å…ƒã®ã‚³ãƒžãƒ³ãƒ‰ï¼ˆã€Œæ¬§æ–‡ã€è¡Œï¼‰
+ã«å¯¾å¿œã™ã‚‹ã‚‚ã®ã¨ã—ã¦å®šç¾©ã—ã¦ã„る:
+%</ja>
+%<*en>
+\begin{table}
+\caption{Commands of \Pkg{luatexja-fontspec}}\label{tab:ltj_fntspc}
+\medskip
+{\centering\small
+\begin{tabular}{cllll}
+\toprule
+Japanese fonts
+&\cs{jfontspec}&\cs{setmainjfont}&\cs{setsansjfont}&\cs{setmonojfont}$^*$\\
+alphabetic fonts
+&\cs{fontspec}&\cs{setmainfont}&\cs{setsansfont}&\cs{setmonofont}\\
+\midrule
+Japanese fonts
+&\cs{newjfontfamily}&\cs{renewjfontfamily}$^{**}$&\cs{setjfontfamily}$^{**}$\\
+alphabetic fonts
+&\cs{newfontfamily}&\cs{renewfontfamily}$^{**}$&\cs{setfontfamily}$^{**}$\\
+\midrule
+Japanese fonts
+&\cs{newjfontface}&\cs{defaultjfontfeatures}&\cs{addjfontfeatures}\\
+alphabetic fonts
+&\cs{newfontface}&\cs{defaultfontfeatures}&\cs{addfontfeatures}\\
+\bottomrule
+\end{tabular}\par}
+\medskip
+\fakefn{$^*$}{%
+ \cs{setmonojfont} is defined if and only if \texttt{match} option is specified.}
+\fakefn{$^{**}$}{%
+ \cs{renewfontfamily}~and~\cs{setfontfamily} are new commands
+ in \Pkg{fontspec}~v2.6h (2018/7/30).
+ Hence, \Pkg{luatexja-fontspec} define \cs{renewjfontfamily}~and~\cs{setjfontfamily}
+ only when \Pkg{fontspec}~v2.6h (or later) is used.
+}
+\end{table}
+%</en>
+%<*ja>
+\begin{table}
+\caption{\Pkg{luatexja-fontspec}ã§å®šç¾©ã•ã‚Œã‚‹å‘½ä»¤}\label{tab:ltj_fntspc}
+\medskip
+{\centering\small
+\begin{tabular}{lllll}
+\toprule
+\emph{和文}
+&\cs{jfontspec}&\cs{setmainjfont}&\cs{setsansjfont}&\cs{setmonojfont}$^*$\\
+\emph{欧文}
+&\cs{fontspec}&\cs{setmainfont}&\cs{setsansfont}&\cs{setmonofont}\\
+\midrule
+\emph{和文}
+&\cs{newjfontfamily}&\cs{renewjfontfamily}$^{**}$&\cs{setjfontfamily}$^{**}$\\
+\emph{欧文}
+&\cs{newfontfamily}&\cs{renewfontfamily}$^{**}$&\cs{setfontfamily}$^{**}$\\
+\midrule
+\emph{和文}
+&\cs{newjfontface}&\cs{defaultjfontfeatures}&\cs{addjfontfeatures}\\
+\emph{欧文}
+&\cs{newfontface}&\cs{defaultfontfeatures}&\cs{addfontfeatures}\\
+\bottomrule
+\end{tabular}\par}
+
+\medskip
+\fakefn{$^*$}{\cs{setmonojfont} 㯠\texttt{match} オプションãŒ
+指定ã•ã‚ŒãŸæ™‚ã®ã¿å®šç¾©ã•ã‚Œã‚‹ï¼Ž}
+\fakefn{$^{**}$}{%
+ \cs{renewfontfamily} 㨠\cs{setfontfamily} ã¯
+ \Pkg{fontspec}~v2.6h (2018/7/30)ã§æ–°ãŸã«è¿½åŠ ã•ã‚ŒãŸå‘½ä»¤ã§ã‚る.
+ ãã®ãŸã‚,\Pkg{luatexja-fontspec}㌠\cs{renewjfontfamily} 㨠\cs{setjfontfamily} ã‚’
+ 定義ã™ã‚‹ã®ã¯v2.6h以é™ã®\Pkg{fontspec}を使用ã—ãŸæ™‚ã®ã¿ã«ãªã£ã¦ã„る.
+}
+
+\end{table}
+%</ja>
+
+%<en> The package option of \Pkg{luatexja-fontspec} are the followings:
+%<ja> \Pkg{luatexja-fontspec} パッケージã®ã‚ªãƒ—ションã¯ä»¥ä¸‹ã®é€šã‚Šã§ã‚る:
+\begin{cslist}
+ \item[match]
+%<*en>
+If this option is specified, usual family-changing commands such as
+\cs{rmfamily},~\cs{textrm}, \cs{sffamily},~\dots\ also change Japanese font family.
+
+Note that \emph{\cs{setmonojfont} is defined
+if and only if this \texttt{\textup{match}} option is specified}.
+%</en>
+
+%<*ja>
+ã“ã®ã‚ªãƒ—ションãŒæŒ‡å®šã•ã‚Œã‚‹ã¨ï¼Œã€Œ\pLaTeXe 新ドキュメントクラスã€ã®ã‚ˆã†ã«\
+\cs{rmfamily}, \verb+\textrm{...}+, \cs{sffamily} ç­‰ãŒ
+欧文フォントã ã‘ã§ãªã和文フォントも変更ã™ã‚‹ã‚ˆã†ã«ãªã‚‹ï¼Ž
+
+\emph{ãªãŠï¼Œ\cs{setmonojfont} ã¯ã“ã® \texttt{match} オプションãŒ
+指定ã•ã‚ŒãŸæ™‚ã®ã¿å®šç¾©ã•ã‚Œã‚‹ï¼Ž}ã“ã®å‘½ä»¤ã¯æ¨™æº–ã®ã€Œã‚¿ã‚¤ãƒ—ライタ体ã«å¯¾å¿œã™ã‚‹å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã€ã‚’指定ã™ã‚‹ï¼Ž
+%</ja>
+
+ \item[pass=<opts>]
+%<en> \emph{(Obsoleted)}\ Specify options <opts> which will be passed to the \Pkg{fontspec} package.
+%<ja> \Pkg{fontspec} パッケージã«æ¸¡ã™ã‚ªãƒ—ション <opts> を指定ã™ã‚‹ï¼Žæœ¬ã‚ªãƒ—ションã¯æ™‚代é…ã‚Œã§ã‚る.
+
+\item[scale=<float>]
+%<*en>
+Override the ratio of the font size of Japanese fonts to that of alphabetic fonts.
+The default value is determined as follows:
+ \begin{itemize}
+ \item The value of \cs{Cjascale} is used, if this control sequence is already defined.
+ \item It is calculated automatically from the current Japanese font at the loading of the
+ package, if \cs{Cjascale} is not defined.
+ \end{itemize}
+\cs{Cjascale} is defined in \Pkg{ltjclasses} and \Pkg{ltjsclasses}.
+%</en>
+%<*ja>
+欧文ã«å¯¾ã™ã‚‹å’Œæ–‡ã®æ¯”率を手動ã§ä¸Šæ›¸ãã™ã‚‹ã¨ãã«ä½¿ç”¨ã™ã‚‹ï¼Ž
+標準ã§ã¯
+\begin{itemize}
+ \item \cs{Cjascale}ãŒå®šç¾©ã•ã‚Œã¦ã„ã‚‹å ´åˆ
+ \footnote{\LuaTeX-ja ãŒç”¨æ„ã—ã¦ã„るクラスファイル(\Pkg{ltjclasses},~\Pkg{ltjsclasses})ã‚’
+ 使ã†å ´åˆã¯ã“ã¡ã‚‰ã«å½“ã¦ã¯ã¾ã‚‹ï¼Ž}ã¯ï¼Œãれを用ã„る.
+ \item \cs{Cjascale}ãŒæœªå®šç¾©ã®å ´åˆã¯ï¼Œ\Pkg{luatexja-fontspec}読ã¿è¾¼ã¿æ™‚ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‹ã‚‰è‡ªå‹•è¨ˆç®—ã•ã‚Œã‚‹ï¼Ž
+\end{itemize}
+%</ja>
+\end{cslist}
+
+%<*en>
+All other options listed above are simply passed to the \Pkg{fontspec} package.
+This means that two lines below are equivalent, for example.
+%</en>
+%<*ja>
+上記ã«ãªã„オプションã¯å…¨ã¦ \Pkg{fontspec} パッケージã«æ¸¡ã•ã‚Œã‚‹ï¼Ž
+例ãˆã°ï¼Œä¸‹ã®2è¡Œã¯åŒã˜æ„味ã«ãªã‚‹ï¼š
+%</ja>
+\begin{lstlisting}
+\usepackage[no-math]{fontspec}\usepackage{luatexja-fontspec}
+\usepackage[no-math]{luatexja-fontspec}
+\end{lstlisting}
+
+
+%<*en>
+The reason that \cs{setmonojfont} is not defined by default is that
+it is popular for Japanese fonts that nearly all Japanese glyphs have same
+widths. Also note that kerning information in a font is not used
+(that is, \texttt{kern} feature is set off) by default in these seven (or~eight) commands.
+This is because of the compatibility with previous versions of \LuaTeX-ja
+(see \ref{para-kern}).
+
+Below is an example of \cs{jfontspec}.
+%</en>
+%<*ja>
+標準㧠\cs{setmonojfont} コマンドãŒå®šç¾©ã•ã‚Œãªã„ã®ã¯ï¼Œ
+和文フォントã§ã¯ã»ã¼å…¨ã¦ã®å’Œæ–‡æ–‡å­—ã®ã‚°ãƒªãƒ•ãŒç­‰å¹…ã§ã‚ã‚‹ã®ãŒä¼çµ±çš„ã§ã‚ã£ãŸã“ã¨ã«ã‚ˆã‚‹ï¼Ž
+ã¾ãŸï¼Œã“れらã®å’Œæ–‡ç”¨ã®ã‚³ãƒžãƒ³ãƒ‰ã§ã¯ãƒ•ã‚©ãƒ³ãƒˆå†…ã®ãƒšã‚¢ã‚«ãƒ¼ãƒ‹ãƒ³ã‚°æƒ…å ±ã¯æ¨™æº–ã§ã¯ä½¿ç”¨ã•ã‚Œãªã„,
+言ã„æ›ãˆã‚Œã° \texttt{kern} featureã¯æ¨™æº–ã§ã¯ç„¡åŠ¹åŒ–ã¨ãªã£ã¦ã„る.
+ã“ã‚Œã¯ä»¥å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®\LuaTeX-jaã¨ã®äº’æ›æ€§ã®ãŸã‚ã§ã‚る(\ref{para-kern}節をå‚照).
+
+以下ã«\cs{jfontspec}ã®ä½¿ç”¨ä¾‹ã‚’示ã™ï¼Ž
+%</ja>
+
+\begin{LTXexample}[width=0.4\textwidth]
+\jfontspec[CJKShape=NLC]{KozMinPr6N-Regular}
+JIS~X~0213:2004→辻\par
+\jfontspec[CJKShape=JIS1990]{KozMinPr6N-Regular}
+JIS~X~0208:1990→辻
+\end{LTXexample}
+
+%<en>\subsection{Presets of Japanese fonts}
+%<ja>\subsection{和文フォントã®ãƒ—リセット設定}
+\label{ssec:preset-abst}
+
+%<*en>
+With \Pkg{luatexja-preset} package,
+one use one of ``preset'' to simplify Japanese font setting.
+For details of package options, and those of each presets, please see Subsecion~\ref{ssec:preset}.
+The following presets are defined:
+%</en>
+%<*ja>
+よã使ã‚ã‚Œã¦ã„る和文フォント設定を一行ã§æŒ‡å®šã§ãるよã†ã«ã—ãŸã®ãŒ
+\Pkg{luatexja-preset}パッケージã§ã‚る.オプションやå„プリセットã®è©³ç´°ã«ã¤ã„ã¦ã¯
+\ref{ssec:preset}節をå‚ç…§ã—ã¦æ¬²ã—ã„.
+ç¾æ™‚点ã§ã¯ä»¥ä¸‹ã®ãƒ—リセットãŒå®šç¾©ã•ã‚Œã¦ã„る:
+%</ja>
+\begin{quote}
+ \ttfamily
+ \hyphenchar\font=-1 \exhyphenchar=-1
+ hiragino-pro, hiragino-pron, ipa, ipa-hg, ipaex, ipaex-hg,
+ kozuka-pr6, kozuka-pr6n, kozuka-pro, moga-mobo, moga-mobo-ex,
+ bizud, morisawa-pr6n, morisawa-pro, ms, ms-hg, noembed, noto-otc, noto-otf,
+ sourcehan, sourcehan-jp, ume, yu-osx, yu-win, yu-win10
+\end{quote}
+
+%<ja> 例ãˆã°ï¼Œæœ¬ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã§ã¯\Pkg{luatexja-preset}パッケージを
+%<en> For example, this document loads \Pkg{luatexja-preset} package by
+\begin{lstlisting}
+\usepackage[kozuka-pr6n]{luatexja-preset}
+\end{lstlisting}
+%<ja>ã¨ã—ã¦èª­ã¿è¾¼ã¿ï¼Œå°å¡šæ›¸ä½“(Pr6N)を使ã†ã“ã¨ã‚’指定ã—ã¦ã„る.
+%<en> which means that Kozuka~Pr6N fonts will be used in this document.
+
+
+%<*en>
+\subsection{\cs{CID}, \cs{UTF}, and macros in \Pkg{japanese-otf} package}
+Under \pLaTeX, \Pkg{japanese-otf} package (developed by Shuzaburo Saito) is
+used for typesetting characters which is in Adobe-Japan1-6 CID but not
+in JIS~X~0208. Since this package is widely used, \LuaTeX-ja
+supports some of functions in the \Pkg{japanese-otf} package,
+as an external package \Pkg{luatexja-otf}.
+%</en>
+%<*ja>
+\subsection{\cs{CID}, \cs{UTF}ã¨\Pkg{otf}パッケージã®ãƒžã‚¯ãƒ­}
+\pLaTeX ã§ã¯ï¼ŒJIS~X~0208ã«ãªã„Adobe-Japan1-6ã®æ–‡å­—を出力ã™ã‚‹ãŸã‚ã«ï¼Œ
+齋藤修三郎æ°ã«ã‚ˆã‚‹\Pkg{otf}パッケージãŒç”¨ã„られã¦ã„ãŸï¼Žã“ã®ãƒ‘ッケージã¯
+広ã用ã„られã¦ã„ã‚‹ãŸã‚,\LuaTeX-jaã«ãŠã„ã¦ã‚‚\Pkg{otf}パッケージã®æ©Ÿèƒ½ã®
+一部を(\Pkg{luatexja-otf}ã¨ã„ã†åˆ¥ã®ãƒ‘ッケージã¨ã—ã¦ï¼‰å®Ÿè£…ã—ãŸï¼Ž
+%</ja>
+
+\begin{LTXexample}
+\jfontspec{KozMinPr6N-Regular.otf}
+森\UTF{9DD7}外ã¨å†…田百\UTF{9592}ã¨ãŒ\UTF{9AD9}島屋ã«è¡Œã。
+
+\CID{7652}飾区ã®\CID{13706}野家,
+\CID{1481}城市,葛西駅,
+高崎ã¨\CID{8705}\UTF{FA11}
+
+\ajåŠè§’{ã¯ã‚“ã‹ãカタカナ}
+\end{LTXexample}
+
+%<*ja>
+\Pkg{otf}パッケージã§ã¯ï¼Œãã‚Œãžã‚Œæ¬¡ã®ã‚ˆã†ãªã‚ªãƒ—ションãŒå­˜åœ¨ã—ãŸï¼š
+\begin{cslist}
+\item[deluxe] 明æœä½“・ゴシック体å„3ウェイトã¨ï¼Œä¸¸ã‚´ã‚·ãƒƒã‚¯ä½“を扱ãˆã‚‹ã‚ˆã†ã«ãªã‚‹ï¼Ž
+\item[expert] ä»®åãŒæ¨ªçµ„・縦組専用ã®ã‚‚ã®ã«åˆ‡ã‚Šæ›¿ã‚り,ルビ用仮åã‚‚
+\ \cs{rubyfamily}\ ã«ã‚ˆã£ã¦æ‰±ãˆã‚‹ã‚ˆã†ã«ãªã‚‹ï¼Ž
+\item[bold] ゴシック体を標準ã§å¤ªã„ウェイトã®ã‚‚ã®ã«è¨­å®šã™ã‚‹ï¼Ž
+\end{cslist}
+ã—ã‹ã—ã“れらã®ã‚ªãƒ—ションã¯\Pkg{luatexja-otf}パッケージã«ã¯å­˜åœ¨ã—ãªã„.
+\Pkg{otf}パッケージãŒæ–‡æ›¸ä¸­ã§ä½¿ç”¨ã™ã‚‹å’Œæ–‡ç”¨TFMを自å‰ã®ç‰©ã«ç½®ãæ›ãˆã¦ã„ãŸã®ã«å¯¾ã—,
+\Pkg{luatexja-otf}パッケージã§ã¯ï¼Œãã®ã‚ˆã†ãªã“ã¨ã¯è¡Œã‚ãªã„ã‹ã‚‰ã§ã‚る.
+
+ã“れら3オプションã«ã¤ã„ã¦ã¯ï¼Œ
+\Pkg{luatexja-preset} パッケージã«ãƒ—リセットを使ã†æ™‚ã«ä¸€ç·’ã«æŒ‡å®šã™ã‚‹ã‹ï¼Œ
+ã‚ã‚‹ã„ã¯å¯¾å¿œã™ã‚‹å†…容を\ref{ssec:chgfnt}節,\ref{ssec:nfsspat}節 (NFSS2) ã‚„
+\ref{ssec:fontspec}節 (\Pkg{fontspec}) ã®æ–¹æ³•ã§æ‰‹å‹•ã§æŒ‡å®šã™ã‚‹å¿…è¦ãŒã‚る.
+%</ja>
+
+%<en>\section{Changing Internal Parameters}
+%<ja>\section{パラメータã®å¤‰æ›´}
+
+%<*en>
+There are many internal parameters in \LuaTeX-ja. And due to the behavior of \LuaTeX,
+most of them are not stored as internal register of \TeX, but as an
+original storage system in \LuaTeX-ja. Hence, to assign or acquire those
+parameters, you have to use commands \cs{ltjsetparameter} and
+\cs{ltjgetparameter}.
+%</en>
+%<*ja>
+\LuaTeX-jaã«ã¯å¤šãã®ãƒ‘ラメータãŒå­˜åœ¨ã™ã‚‹ï¼Žãã—ã¦\LuaTeX ã®ä»•æ§˜ã®ãŸã‚ã«ï¼Œ
+ãã®å¤šãã¯\TeX ã®ãƒ¬ã‚¸ã‚¹ã‚¿ã«ã§ã¯ãªã,\LuaTeX-ja独自ã®æ–¹æ³•ã§ä¿æŒã•ã‚Œã¦ã„る.
+ã“れらã®ãƒ‘ラメータを設定・å–å¾—ã™ã‚‹ãŸã‚ã«ã¯ \cs{ltjsetparameter} 㨠\cs{ltjgetparameter} ã‚’
+用ã„る.
+%</ja>
+
+%<en>\subsection{Range of \textbf{JAchar}s}
+%<ja>\subsection{\textbf{JAchar}ã®ç¯„囲}
+\label{ssec:setrange}
+
+%<*en>
+\LuaTeX-ja divides the Unicode codespace \texttt{U+0080}--\texttt{U+10FFFF}
+into \emph{character ranges},
+numbered 1 to 217. The grouping can be (globally) customized by \cs{ltjdefcharrange}.
+The next line adds whole characters in Supplementary Ideographic Plane
+and the character ``æ¼¢'' to the character range~100.
+%</en>
+%<*ja>
+\LuaTeX-jaã¯ï¼ŒUnicodeã® \texttt{U+0080}--\texttt{U+10FFFF} ã®ç©ºé–“ã‚’
+1番ã‹ã‚‰217番ã¾ã§ã®\emph{文字範囲}ã«åˆ†å‰²ã—ã¦ã„る.
+区分ã‘㯠\cs{ltjdefcharrange} を用ã„ã‚‹ã“ã¨ã§ï¼ˆã‚°ãƒ­ãƒ¼ãƒãƒ«ã«ï¼‰å¤‰æ›´ã™ã‚‹ã“ã¨ãŒã§ã,
+例ãˆã°ï¼Œæ¬¡ã¯è¿½åŠ æ¼¢å­—é¢(SIP)ã«ã‚ã‚‹å…¨ã¦ã®æ–‡å­—ã¨ã€Œæ¼¢ã€ã‚’「100番ã®æ–‡å­—範囲ã€ã«è¿½åŠ ã™ã‚‹ï¼Ž
+%</ja>
+\begin{lstlisting}
+\ltjdefcharrange{100}{"20000-"2FFFF,`æ¼¢}
+\end{lstlisting}
+
+%<*en>
+A character can belong to only one character range.
+For example, whole SIP belong to the range~4 in the default setting of \LuaTeX-ja,
+and if one executes the above line, then SIP will belong to the range~100 and be
+removed from the range~4.
+%</en>
+%<*ja>
+å„文字ã¯ãŸã ä¸€ã¤ã®æ–‡å­—範囲ã«æ‰€å±žã™ã‚‹ã“ã¨ãŒã§ãる.
+例ãˆã°ï¼ŒSIP内ã®æ–‡å­—ã¯å…¨ã¦\LuaTeX-jaã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯4番ã®æ–‡å­—範囲ã«
+属ã—ã¦ã„ã‚‹ãŒï¼Œä¸Šè¨˜ã®æŒ‡å®šã‚’è¡Œãˆã°SIP内ã®æ–‡å­—ã¯100番ã«å±žã™ã‚ˆã†ã«ãªã‚Šï¼Œ4番ã‹ã‚‰ã¯é™¤ã‹ã‚Œã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+The distinction between \textbf{ALchar} and \textbf{JAchar} is performed by character ranges.
+This can be edited by setting the \textsf{jacharrange} parameter.
+For example, the code below is just the default setting of \LuaTeX-ja, and
+it sets
+\begin{itemize}
+ \item a character which belongs character ranges 1,~4, 5, and~8 is \textbf{ALchar},
+ \item a character which belongs character ranges 2,~3, 6, and~7 is \textbf{JAchar}.
+\end{itemize}
+%</en>
+%<*ja>
+\textbf{ALchar}ã¨\textbf{JAchar}ã®åŒºåˆ¥ã¯æ–‡å­—範囲ã”ã¨ã«è¡Œã‚れる.
+ã“ã‚Œã¯\textsf{jacharrange}パラメータã«ã‚ˆã£ã¦ç·¨é›†ã§ãる.
+例ãˆã°ï¼Œä»¥ä¸‹ã¯\LuaTeX-jaã®åˆæœŸè¨­å®šã§ã‚り,次ã®å†…容を設定ã—ã¦ã„る:
+\begin{itemize}
+ \item 1番,4番,5番,8番ã®æ–‡å­—範囲ã«å±žã™ã‚‹æ–‡å­—ã¯\textbf{ALchar}.
+ \item 2番,3番,6番,7番ã®æ–‡å­—範囲ã«å±žã™ã‚‹æ–‡å­—ã¯\textbf{JAchar}.
+\end{itemize}
+%</ja>
+\begin{lstlisting}
+\ltjsetparameter{jacharrange={-1, +2, +3, -4, -5, +6, +7, -8}}
+\end{lstlisting}
+%<*en>
+The argument to \textsf{jacharrange} parameter is a list of non-zero integer.
+Negative integer $-n$ in the list means that ``each character in the range~$n$ is an
+\textbf{ALchar}'',
+and positive integer $+n$ means that ``\dots\ is a \textbf{JAchar}''.
+%</en>
+%<*ja>
+\textsf{jacharrange}パラメータã®å¼•æ•°ã¯éžé›¶ã®æ•´æ•°ã®ãƒªã‚¹ãƒˆã§ã‚る.
+リスト中ã®è² ã®æ•´æ•°$-n$ã¯ã€Œæ–‡å­—範囲$n$ã«å±žã™ã‚‹æ–‡å­—ã¯\textbf{ALchar}ã¨ã—ã¦
+扱ã†ã€ã“ã¨ã‚’æ„味ã—,正ã®æ•´æ•°$+n$ã¯ã€Œ\textbf{JAchar}ã¨ã—ã¦æ‰±ã†ã€ã“ã¨ã‚’æ„味ã™ã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+Note that characters \texttt{U+0000}--\texttt{U+007F} are always treated as an
+\textbf{ALchar} (this cannot be customized).
+%</en>
+%<*ja>
+ãªãŠï¼Œ\texttt{U+0000}--\texttt{U+007F} ã¯å¸¸ã«\textbf{ALchar}ã¨ã—ã¦æ‰±ã‚れる(利用者ãŒå¤‰æ›´ã™
+ã‚‹ã“ã¨ã¯å‡ºæ¥ãªã„).
+%</ja>
+
+%<*en>
+\paragraph{Default character ranges}
+\LuaTeX-ja predefines eight character ranges for convenience. They are
+determined from the following data:
+%</en>
+%<*ja>
+\paragraph{文字範囲ã®åˆæœŸå€¤}
+\LuaTeX-jaã§ã¯8ã¤ã®æ–‡å­—範囲を予ã‚定義ã—ã¦ãŠã‚Šï¼Œ
+ã“れらã¯ä»¥ä¸‹ã®ãƒ‡ãƒ¼ã‚¿ã«åŸºã¥ã„ã¦æ±ºå®šã—ã¦ã„る.
+%</ja>
+\begin{itemize}
+%<en>\item Blocks in Unicode~12.0.0.
+%<ja>\item Unicode~11.0ã®ãƒ–ロック.
+%<en>\item The \texttt{Adobe-Japan1-UCS2} mapping between a CID Adobe-Japan1-6 and Unicode.
+%<ja>\item Adobe-Japan1-6ã®CIDã¨Unicodeã®é–“ã®å¯¾å¿œè¡¨\texttt{Adobe-Japan1-UCS2}.
+%<en>\item The \Pkg{PXbase} bundle for \upTeX\ by Takayuki Yato.
+%<ja>\item 八登崇之æ°ã«ã‚ˆã‚‹\upTeX 用ã®\Pkg{PXbase}ãƒãƒ³ãƒ‰ãƒ«ï¼Ž
+\end{itemize}
+
+%<*en>
+Now we describe these eight ranges. The superscript ``J'' or ``A'' after the
+number shows whether each character in the range is treated as
+\textbf{JAchar}s or not by default. These settings are similar to the
+\texttt{prefercjk} settings defined in \texttt{PXbase} bundle.
+Any characters equal to or above \texttt{U+0080} which does not belong to
+these eight ranges belongs to the character range~217.
+%</en>
+%<*ja>
+以下ã§ã¯ã“れら8ã¤ã®æ–‡å­—範囲ã«ã¤ã„ã¦è¨˜è¿°ã™ã‚‹ï¼Žæ·»å­—ã®ã‚¢ãƒ«ãƒ•ã‚¡ãƒ™ãƒƒãƒˆã€ŒJã€ã€ŒAã€
+ã¯ï¼Œãã®æ–‡å­—範囲内ã®æ–‡å­—ãŒ\textbf{JAchar}ã‹\textbf{ALchar}ã‹ã‚’表ã—ã¦ã„る.ã“れらã®åˆæœŸè¨­å®šã¯
+\texttt{PXbase}ãƒãƒ³ãƒ‰ãƒ«ã§å®šç¾©ã•ã‚Œã¦ã„ã‚‹\texttt{prefercjk}ã¨é¡žä¼¼ã®ã‚‚ã®ã§ã‚ã‚‹ãŒï¼Œ
+8ビットフォント使用時ã®ãƒˆãƒ©ãƒ–ルを防ããŸã‚ã« \texttt{U+0080}--\texttt{U+00FF} ã®æ–‡å­—ã¯å…¨éƒ¨
+\textbf{ALchar}ã¨ã—ã¦ã„る.
+ãªãŠï¼Œ\texttt{U+0080} 以é™ã§ã“れら8ã¤ã®æ–‡å­—範囲ã«å±žã•ãªã„文字ã¯ï¼Œ217番ã®æ–‡å­—範囲ã«å±žã™ã‚‹ã“ã¨ã«ãªã£ã¦ã„る.
+%</ja>
+\begin{description}
+%<*en>
+
+\item[Range~8${}^{\text{A}}$] The intersection of the upper half of ISO~8859-1
+ (Latin-1 Supplement) and JIS~X~0208 (a basic character set for Japanese). This character range
+ consists of the following characters:
+%</en>
+%<*ja>
+\item[範囲8${}^{\text{A}}$] ISO~8859-1ã®ä¸Šä½é ˜åŸŸï¼ˆãƒ©ãƒ†ãƒ³1補助)ã¨
+ JIS~X~0208ã®å…±é€šéƒ¨åˆ†ï¼Žã“ã®æ–‡å­—範囲ã¯
+ 以下ã®æ–‡å­—ã§æ§‹æˆã•ã‚Œã‚‹ï¼š
+%</ja>
+\begin{multicols}{2}
+\begin{itemize}
+\def\ch#1#2{\item \char"#1\ (\texttt{U+00#1}, #2)}%"
+\ch{A7}{Section Sign}
+\ch{A8}{Diaeresis}
+\ch{B0}{Degree sign}
+\ch{B1}{Plus-minus sign}
+\ch{B4}{Spacing acute}
+\ch{B6}{Paragraph sign}
+\ch{D7}{Multiplication sign}
+\ch{F7}{Division Sign}
+\end{itemize}
+\end{multicols}
+
+%<*en>
+\item[Range~1${}^{\text{A}}$] Latin characters that some of them are included in Adobe-Japan1-6.
+This range consists of the following Unicode ranges, \emph{except characters in the range~8 above}:
+%</en>
+%<*ja>
+\item[範囲1${}^{\text{A}}$] ラテン文字ã®ã†ã¡ï¼ŒAdobe-Japan1-6ã¨ã®å…±é€šéƒ¨åˆ†ãŒã‚ã‚‹ã‚‚ã®ï¼Ž
+ ã“ã®ç¯„囲ã¯ä»¥ä¸‹ã®Unicodeã®ãƒ–ロックã®ã†ã¡
+ \emph{範囲8を除ã„ãŸ}部分ã§æ§‹æˆã•ã‚Œã¦ã„る:
+%</ja>
+\begin{multicols}{2}
+\begin{itemize}
+\item \texttt{U+0080}--\texttt{U+00FF}: Latin-1 Supplement
+\item \texttt{U+0100}--\texttt{U+017F}: Latin Extended-A
+\item \texttt{U+0180}--\texttt{U+024F}: Latin Extended-B
+\item \texttt{U+0250}--\texttt{U+02AF}: IPA Extensions
+\item \texttt{U+02B0}--\texttt{U+02FF}: Spacing Modifier Letters
+%<en>\par\
+\item \texttt{U+0300}--\texttt{U+036F}: \\*\null\hfill Combining Diacritical Marks
+\item \texttt{U+1E00}--\texttt{U+1EFF}: \\*\null\hfill Latin Extended Additional
+%<ja>\par\
+\end{itemize}
+\end{multicols}
+%<*en>
+\item[Range~2${}^{\text{\kern.1emJ}}$] Greek and Cyrillic letters. JIS~X~0208 (hence most of Japanese
+ fonts) has some of these characters.
+%</en>
+%<*ja>
+\item[範囲2${}^{\text{\kern.1emJ}}$] ギリシャ文字ã¨ã‚­ãƒªãƒ«æ–‡å­—.JIS~X~0208(ã—ãŸãŒã£ã¦ã»ã¨ã‚“ã©ã®
+ 和文フォント)ã«ã¯ï¼Œã“れらã®æ–‡å­—ã®ä¸€éƒ¨ãŒå«ã¾ã‚Œã¦ã„る.
+%</ja>
+\begin{multicols}{2}
+\begin{itemize}
+\item \texttt{U+0370}--\texttt{U+03FF}: Greek and Coptic
+\item \texttt{U+0400}--\texttt{U+04FF}: Cyrillic
+\item \texttt{U+1F00}--\texttt{U+1FFF}: Greek Extended
+\\\
+\end{itemize}
+\end{multicols}
+%<*en>
+\item[Range~3${}^{\text{\kern.1emJ}}$] Punctuations and Miscellaneous symbols. The block list is
+ indicated in \autoref{tab:rng3}.
+%</en>
+%<*ja>
+\item[範囲3${}^{\text{\kern.1emJ}}$] å¥èª­ç‚¹ã¨è¨˜å·é¡žï¼Žãƒ–ロックã®ãƒªã‚¹ãƒˆã¯\autoref{tab:rng3}%
+ ã«ç¤ºã—ã¦ã‚る.
+%</ja>
+\begin{table}[!tb]
+%<en>\caption{Unicode blocks in predefined character range~3.}\medskip
+%<ja>\caption{文字範囲3ã«æŒ‡å®šã•ã‚Œã¦ã„ã‚‹Unicodeブロック.}
+\label{tab:rng3}
+\catcode`\"=13\def"#1#2#3#4{\texttt{U+#1#2#3#4}}%"
+\centering\footnotesize
+\begin{tabular}{llll}
+"2000--"206F&General Punctuation&
+"2070--"209F&Superscripts and Subscripts\\
+"20A0--"20CF&Currency Symbols&
+"20D0--"20FF&Comb.\ Diacritical Marks for Symbols\\
+"2100--"214F&Letterlike Symbols&
+"2150--"218F&Number Forms\\
+"2190--"21FF&Arrows&
+"2200--"22FF&Mathematical Operators\\
+"2300--"23FF&Miscellaneous Technical&
+"2400--"243F&Control Pictures\\
+"2500--"257F&Box Drawing&
+"2580--"259F&Block Elements\\
+"25A0--"25FF&Geometric Shapes&
+"2600--"26FF&Miscellaneous Symbols\\
+"2700--"27BF&Dingbats&
+"2900--"297F&Supplemental Arrows-B\\
+"2980--"29FF&Misc.\ Math Symbols-B&
+"2B00--"2BFF&Misc.\ Symbols and Arrows
+\end{tabular}
+\end{table}
+%<*en>
+\item[Range~4${}^{\text{A}}$] Characters usually not in Japanese fonts. This range consists
+ of almost all Unicode blocks which are not in other
+ predefined ranges. Hence, instead of showing the block list,
+ we put the definition of this range itself:
+%</en>
+%<*ja>
+\item[範囲4${}^{\text{A}}$] 通常和文フォントã«ã¯å«ã¾ã‚Œã¦ã„ãªã„文字.
+ ã“ã®ç¯„囲ã¯ä»–ã®ç¯„囲ã«ãªã„ã»ã¨ã‚“ã©å…¨ã¦ã®Unicodeブロック
+ ã§æ§‹æˆã•ã‚Œã¦ã„る.ã—ãŸãŒã£ã¦ï¼Œãƒ–ロックã®ãƒªã‚¹ãƒˆã‚’示ã™
+ 代ã‚ã‚Šã«ï¼Œç¯„囲ã®å®šç¾©ãã®ã‚‚ã®ã‚’示ã™ï¼š
+%</ja>
+\begin{lstlisting}
+\ltjdefcharrange{4}{%
+ "500-"10FF, "1200-"1DFF, "2440-"245F, "27C0-"28FF, "2A00-"2AFF,
+ "2C00-"2E7F, "4DC0-"4DFF, "A4D0-"A95F, "A980-"ABFF, "E000-"F8FF,
+ "FB00-"FE0F, "FE20-"FE2F, "FE70-"FEFF, "10000-"1AFFF, "1B170-"1F0FF,
+ "1F300-"1FFFF
+} % non-Japanese
+\end{lstlisting}
+%<en>\item[Range~5${}^{\text{A}}$] Surrogates and Supplementary Private Use Areas.
+%<ja>\item[範囲5${}^{\text{A}}$] 代用符å·ã¨è£œåŠ©ç§ç”¨é ˜åŸŸï¼Ž
+%<en>\item[Range~6${}^{\text{\kern.1emJ}}$] Characters used in Japanese. The block list is indicated in \autoref{tab:rng6}.
+%<ja>\item[範囲6${}^{\text{\kern.1emJ}}$] 日本語ã§ç”¨ã„られる文字.ブロックã®ãƒªã‚¹ãƒˆã¯\autoref{tab:rng6}ã«ç¤ºã™ï¼Ž
+\begin{table}[!tb]
+%<en>\caption{Unicode blocks in predefined character range~6.}\medskip
+%<ja>\caption{文字範囲6ã«æŒ‡å®šã•ã‚Œã¦ã„ã‚‹Unicodeブロック.}
+\label{tab:rng6}
+\catcode`\"=13\def"#1#2#3#4{\texttt{U+#1#2#3#4}}%"
+\centering\footnotesize
+\begin{tabular}{llll}
+"2460--"24FF&Enclosed Alphanumerics&
+"2E80--"2EFF&CJK Radicals Supplement\\
+"3000--"303F&CJK Symbols and Punctuation&
+"3040--"309F&Hiragana\\
+"30A0--"30FF&Katakana&
+"3190--"319F&Kanbun\\
+"31F0--"31FF&Katakana Phonetic Extensions&
+"3200--"32FF&Enclosed CJK Letters and Months\\
+"3300--"33FF&CJK Compatibility&
+"3400--"4DBF&CJK Unified Ideographs Ext-A\\
+"4E00--"9FFF&CJK Unified Ideographs&
+"F900--"FAFF&CJK Compatibility Ideographs\\
+"FE10--"FE1F&Vertical Forms&
+"FE30--"FE4F&CJK Compatibility Forms\\
+"FE50--"FE6F&Small Form Variants&
+"FF00--"FFEF&Halfwidth and Fullwidth Forms\\
+"{1B}000--"{1B}0FF&Kana Supplement&
+"{1B}100--"{1B}12F&Kana Extended-A\\
+%"{1B}130--"{1B}16F&Small Kana Extension
+"{1F}100--"{1F}1FF&Enclosed Alphanumeric Supp.&
+"{1F}200--"{1F}2FF&Enclosed Ideographic Supp.\\
+"{20}000--"{2F}FFF&(Supp. Ideographic Plane)&
+"{E0}100--"{E0}1EF&Variation Selectors Supp.
+\end{tabular}
+\end{table}
+%<*en>
+\item[Range~7${}^{\text{\kern.1emJ}}$] Characters used in CJK languages, but not included in Adobe-Japan1-6.
+The block list is indicated in \autoref{tab:rng7}.
+%</en>
+%<*ja>
+\item[範囲7${}^{\text{\kern.1emJ}}$] CJK言語ã§ç”¨ã„られる文字ã®ã†ã¡ï¼ŒAdobe-Japan1-6ã«
+ å«ã¾ã‚Œã¦ã„ãªã„ã‚‚ã®ï¼Ž
+ ブロックã®ãƒªã‚¹ãƒˆã¯\autoref{tab:rng7}ã«ç¤ºã™ï¼Ž
+%</ja>
+\begin{table}[!tb]
+%<en>\caption{Unicode blocks in predefined character range~7.}\medskip
+%<ja>\caption{文字範囲7ã«æŒ‡å®šã•ã‚Œã¦ã„ã‚‹Unicodeブロック.}
+\label{tab:rng7}
+\catcode`\"=13\def"#1#2#3#4{\texttt{U+#1#2#3#4}}%"
+\centering\small
+\begin{tabular}{llll}
+"1100--"11FF&Hangul Jamo&
+"2F00--"2FDF&Kangxi Radicals\\
+"2FF0--"2FFF&Ideographic Description Characters&
+"3100--"312F&Bopomofo\\
+"3130--"318F&Hangul Compatibility Jamo&
+"31A0--"31BF&Bopomofo Extended\\
+"31C0--"31EF&CJK Strokes&
+"A000--"A48F&Yi Syllables\\
+"A490--"A4CF&Yi Radicals&
+"A960--"A97F&Hangul Jamo Extended-A\\
+"AC00--"D7AF&Hangul Syllables&
+"D7B0--"D7FF&Hangul Jamo Extended-B
+\end{tabular}
+\end{table}
+\end{description}
+
+%<*en>
+\paragraph{Notes on \texttt{U+0080}--\texttt{U+00FF}}
+You should treat characters in \\texttt{U+0080}--\texttt{U+00FF} as \textbf{ALchar},
+when you use traditional 8-bit fonts, such as the \Pkg{marvosym} package.
+
+For example, \cs{Frowny} which is provided by the \Pkg{marvosym} package has
+the same codepoint as \S\ (\text{U+00A7}).
+Hence, as previous versions of \LuaTeX-ja, if these characters are treated as
+\text{JAchar}s, then \cs{Frowny} produces ``\ltjjachar`§'' (in a Japanese font).
+
+To avoid such situations, the default setting of \LuaTeX-ja is changed in version~20150906.0
+so that all characters \texttt{U+0080}--\texttt{U+00FF} are treated as \textbf{ALchar}.
+
+If you want to output a character as \textbf{ALchar} and \textbf{JAchar} regardless the range
+setting, you can use \cs{ltjalchar} and \cs{ltjjachar} respectively, as the following example.
+\begin{LTXexample}[width=0.3\textwidth]
+\gtfamily\large % default, ALchar, JAchar
+¶, \ltjalchar`¶, \ltjjachar`¶\\ % default: ALchar
+α, \ltjalchar`α, \ltjjachar`α % default: JAchar
+\end{LTXexample}
+%</en>
+%<*ja>
+\paragraph{\texttt{U+0080}--\texttt{U+00FF}ã«ã¤ã„ã¦ã®æ³¨æ„}
+\LuaTeX-jaã§ï¼Œ\Pkg{marvosym}パッケージ等,Unicodeフォントã§ãªã
+ä¼çµ±çš„ãª8ビットフォントを用ã„ã‚‹å ´åˆã«ã¯æ³¨æ„ãŒå¿…è¦ã§ã‚る.
+
+例ãˆã°ï¼Œ\Pkg{marvosym}パッケージã®æä¾›ã™ã‚‹ \cs{Frowny} も,符å·ä½ç½®ã¯167,ã¤ã¾ã‚ŠUnicodeã«ãŠã‘ã‚‹
+\S\ (\text{U+00A7}) ã¨åŒã˜ç¬¦å·ä½ç½®ã«ã‚る.
+å³ã¡ï¼Œä»¥å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã‚ˆã†ã«ï¼Œã€Œå‰ç¯€ã®æ–‡å­—範囲8内ã®æ–‡å­—ã¯\textbf{JAchar}ã€ã¨ã„ã†è¨­å®šã§
+ã‚ã£ãŸã¨ã™ã‚‹ã¨ï¼Œä¸Šè¨˜ã® \cs{Frowny} ã¯å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã§ã€Œ\ltjjachar`§ã€ã‚’出力ã™ã‚‹ã“ã¨ã«ãªã‚‹ï¼Ž
+
+ã“ã®ã‚ˆã†ãªäº‹æ…‹ã‚’é¿ã‘ã‚‹ãŸã‚ã«ï¼Œãƒãƒ¼ã‚¸ãƒ§ãƒ³20150906.0ã‹ã‚‰ã¯ \texttt{U+0080}--\texttt{U+00FF} ã®ç¯„囲ã®
+文字ã¯å…¨ã¦\textbf{ALchar}ã¨ãªã‚‹ã‚ˆã†ã«åˆæœŸè¨­å®šã‚’変更ã—ã¦ã„る.
+
+ãªãŠï¼Œæ–‡å­—範囲ã®è¨­å®šã«é–¢ã‚らãš1ã¤ã®æ–‡å­—ã‚’\textbf{ALchar}, \textbf{JAchar}ã§å‡ºåŠ›ã—ãŸã„å ´åˆã«ã¯ï¼Œ
+以下ã®ä¾‹ã®ã‚ˆã†ã«ãã‚Œãžã‚Œ \cs{ltjalchar},~\cs{ltjjachar} ã«è©²å½“文字ã®æ–‡å­—コードを渡ã›ã°ã‚ˆã„.
+\begin{LTXexample}[width=0.3\textwidth]
+\gtfamily\large % default, ALchar, JAchar
+¶, \ltjalchar`¶, \ltjjachar`¶\\ % default: ALchar
+α, \ltjalchar`α, \ltjjachar`α % default: JAchar
+\end{LTXexample}
+%</ja>
+
+
+%<en>\subsection{\Param{kanjiskip} and \Param{xkanjiskip}}
+%<ja>\subsection{\Param{kanjiskip}ã¨\Param{xkanjiskip}}
+\label{subs-kskip}
+
+%<en>\textbf{JAglue} is divided into the following three categories:
+%<ja>\textbf{JAglue}ã¯ä»¥ä¸‹ã®3ã¤ã®ã‚«ãƒ†ã‚´ãƒªã«åˆ†é¡žã•ã‚Œã‚‹ï¼š
+\begin{itemize}
+%<*en>
+\item Glues/kerns specified in JFM. If \cs{inhibitglue} is issued
+ around a \textbf{JAchar}, this glue will not be inserted at the
+ place.
+%</en>
+%<*ja>
+\item JFMã§æŒ‡å®šã•ã‚ŒãŸã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ï¼Žã‚‚ã— \cs{inhibitglue} ãŒ\textbf{JAchar}ã®å‘¨ã‚Šã§
+ 発行ã•ã‚Œã¦ã„ã‚Œã°ï¼Œã“ã®ã‚°ãƒ«ãƒ¼ã¯æŒ¿å…¥ã•ã‚Œãªã„.
+%</ja>
+%<*en>
+\item The default glue which inserted between two \textbf{JAchar}s (\Param{%
+ kanjiskip}).
+%</en>
+%<*ja>
+\item デフォルトã§2ã¤ã®\textbf{JAchar}ã®é–“ã«æŒ¿å…¥ã•ã‚Œã‚‹ã‚°ãƒ«ãƒ¼(\Param{kanjiskip}).
+%</ja>
+%<*en>
+\item The default glue which inserted between a \textbf{JAchar} and an
+ \textbf{ALchar} (\Param{xkanjiskip}).
+%</en>
+%<*ja>
+\item デフォルトã§\textbf{JAchar}ã¨\textbf{ALchar}ã®é–“ã«æŒ¿å…¥ã•ã‚Œã‚‹ã‚°ãƒ«ãƒ¼(\Param{xkanjiskip}).
+%</ja>
+\end{itemize}
+%<*en>
+The value (a skip) of \Param{kanjiskip} or
+\Param{xkanjiskip} can be changed as the following.
+Note that only their values \emph{at the end of a paragraph or a hbox are
+adopted in the whole paragraph or the whole hbox.
+}
+%</en>
+%<*ja>
+\Param{kanjiskip}ã‚„\Param{xkanjiskip}ã®å€¤
+ã¯ä»¥ä¸‹ã®ã‚ˆã†ã«ã—ã¦å¤‰æ›´å¯èƒ½ã§ã‚る.
+%</ja>
+\begin{lstlisting}
+\ltjsetparameter{kanjiskip={0pt plus 0.4pt minus 0.4pt},
+ xkanjiskip={0.25\zw plus 1pt minus 1pt}}
+\end{lstlisting}
+%<*en>
+Here \cs{zw} is a internal dimension
+which stores fullwidth of the current Japanese font.
+This \cs{zw} can be used as the unit \texttt{zw} in \pTeX.
+
+The value of these parameter can be get by \cs{ltjgetparameter}.
+Note that the result by \cs{ltjgetparameter} is \emph{not} the internal quantities,
+but \emph{a string} (hence \cs{the} cannot be prefixed).
+%</en>
+%<*ja>
+ã“ã“ã§ï¼Œ\cs{zw} ã¯ç¾åœ¨ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®å…¨è§’幅を表ã™é•·ã•ã§ã‚り,
+\pTeX ã«ãŠã‘ã‚‹é•·ã•å˜ä½ \texttt{zw} ã¨åŒã˜ã‚ˆã†ã«ä½¿ç”¨ã§ãる.
+
+ã“れらã®ãƒ‘ラメータã®å€¤ã¯ä»¥ä¸‹ã®ã‚ˆã†ã«å–å¾—ã§ãる.
+戻り値ã¯å†…部値ã§ã¯ãªã\emph{文字列}ã§ã‚る(\cs{the} ã¯å‰ç½®ã§ããªã„)ã“ã¨ã«æ³¨æ„ã—ã¦ã»ã—ã„:
+%</ja>
+\begin{LTXexample}
+kanjiskip: \ltjgetparameter{kanjiskip},\\
+xkanjiskip: \ltjgetparameter{xkanjiskip}
+\end{LTXexample}
+
+%<*en>
+It may occur that JFM contains the data of ``ideal width of
+\Param{kanjiskip}''
+and/or ``ideal width of \Param{xkanjiskip}''.
+To use these data from JFM, set the value of \Param{kanjiskip} or
+\Param{xkanjiskip} to \cs{maxdimen}
+(these ``ideal width'' cannot be retrived by \cs{ltjgetparameter}).
+%</en>
+%<*ja>
+JFMã¯ã€Œæœ›ã¾ã—ã„\Param{kanjiskip}ã®å€¤ã€ã‚„
+「望ã¾ã—ã„\Param{xkanjiskip}ã®å€¤ã€ã‚’æŒã£ã¦ã„ã‚‹ã“ã¨ãŒã‚る.
+ã“れらã®ãƒ‡ãƒ¼ã‚¿ã‚’使ã†ãŸã‚ã«ã¯ï¼Œ\Param{kanjiskip}ã‚„%
+\Param{xkanjiskip}ã®å€¤ã‚’ \cs{maxdimen} ã®å€¤ã«è¨­å®šã™ã‚Œã°ã‚ˆã„ãŒï¼Œ
+\cs{ltjgetparameter} ã«ã‚ˆã£ã¦å–å¾—ã™ã‚‹ã“ã¨ã¯ã§ããªã„ã®ã§æ³¨æ„ãŒå¿…è¦ã§ã‚る.
+%</ja>
+
+%<en>\subsection{Insertion setting of \Param{xkanjiskip}}
+%<ja>\subsection{\Param{xkanjiskip} ã®æŒ¿å…¥è¨­å®š}
+
+%<*en>
+It is not desirable that \Param{xkanjiskip} is inserted into every
+boundary between \textbf{JAchar}s and \textbf{ALchar}s. For example,
+\Param{xkanjiskip} should not be inserted after opening parenthesis
+(\textit{e.g.}, compare ``(ã‚'' and ``(\hskip\ltjgetparameter{xkanjiskip}ã‚'').
+\LuaTeX-ja can control whether \Param{xkanjiskip} can be inserted
+before/after a character, by changing \Param{jaxspmode} for \textbf{JAchar}s and
+\Param{alxspmode} parameters \textbf{ALchar}s respectively.
+%</en>
+%<*ja>
+\Param{xkanjiskip}ãŒã™ã¹ã¦ã®\textbf{JAchar}ã¨\textbf{ALchar}ã®å¢ƒç•Œã«
+挿入ã•ã‚Œã‚‹ã®ã¯æœ›ã¾ã—ã„ã“ã¨ã§ã¯ãªã„.例ãˆã°ï¼Œ\Param{xkanjiskip}ã¯é–‹ã括弧ã®
+後ã«ã¯æŒ¿å…¥ã•ã‚Œã‚‹ã¹ãã§ã¯ãªã„(「(ã‚ã€ã¨ã€Œ(\hskip\ltjgetparameter{xkanjiskip}ã‚ã€ã‚’
+比ã¹ã¦ã¿ã‚ˆï¼‰ï¼Ž
+\LuaTeX-jaã§ã¯\Param{xkanjiskip}ã‚’ã‚る文字ã®å‰ï¼å¾Œã«æŒ¿å…¥ã™ã‚‹ã‹ã©ã†ã‹ã‚’,
+\textbf{JAchar}ã«å¯¾ã—ã¦ã¯\Param{jaxspmode}を,\textbf{ALchar}ã«å¯¾ã—ã¦ã¯
+\Param{alxspmode}ã‚’ãã‚Œãžã‚Œå¤‰ãˆã‚‹ã“ã¨ã§åˆ¶å¾¡ã™ã‚‹ã“ã¨ãŒã§ãる.
+%</ja>
+\begin{LTXexample}
+\ltjsetparameter{jaxspmode={`ã‚,preonly}, alxspmode={`\!,postonly}}
+pã‚q ã„!ã†
+\end{LTXexample}
+
+%<*en>
+The second argument \texttt{preonly} means that the insertion of
+\Param{xkanjiskip} is allowed before this character, but not after.
+the other possible values are \texttt{postonly}, \texttt{allow}, and \texttt{inhibit}.
+%</en>
+%<*ja>
+2ã¤ç›®ã®å¼•æ•°ã® \texttt{preonly}ã¯ã€Œ\Param{xkanjiskip}ã®æŒ¿å…¥ã¯ã“ã®æ–‡å­—ã®
+å‰ã§ã®ã¿è¨±ã•ã‚Œï¼Œå¾Œã§ã¯è¨±ã•ãªã„ã€ã“ã¨ã‚’æ„味ã™ã‚‹ï¼Žä»–ã«æŒ‡å®šå¯èƒ½ãªå€¤ã¯
+\texttt{postonly}, \texttt{allow}, \texttt{inhibit}ã§ã‚る.
+%</ja>
+
+%<*en>
+\Param{jaxspmode} and \Param{alxspmode} use a same table to store the parameters
+on the current version. Therefore, line~1 in the code above can be rewritten
+as follows:
+%</en>
+%<*ja>
+ãªãŠï¼Œç¾è¡Œã®
+仕様ã§ã¯ï¼Œ\Param{jaxspmode}, \Param{alxspmode}ã¯ãƒ†ãƒ¼ãƒ–ルを共有ã—ã¦ãŠã‚Šï¼Œ
+上ã®ã‚³ãƒ¼ãƒ‰ã®1行目を次ã®ã‚ˆã†ã«å¤‰ãˆã¦ã‚‚åŒã˜ã“ã¨ã«ãªã‚‹ï¼š
+%</ja>
+\begin{lstlisting}
+\ltjsetparameter{alxspmode={`ã‚,preonly}, jaxspmode={`\!,postonly}}
+\end{lstlisting}
+%<*en>
+One can use also numbers to specify these two parameters (see Subsection~\ref{ssec:param}).
+%</en>
+%<*ja>
+ã¾ãŸï¼Œã“れら2パラメータã«ã¯æ•°å€¤ã§å€¤ã‚’指定ã™ã‚‹ã“ã¨ã‚‚ã§ãる(\ref{ssec:param}節をå‚照).
+%</ja>
+
+%<*en>
+If you want to enable/disable all insertions of \Param{kanjiskip} and
+\Param{xkanjiskip}, set \Param{autospacing} and \Param{autoxspacing}
+parameters to \texttt{true}/\texttt{false}, respectively.
+%</en>
+%<*ja>
+ã‚‚ã—å…¨ã¦ã®\Param{kanjiskip}ã¨\Param{xkanjiskip}ã®æŒ¿å…¥ã‚’有効化ï¼ç„¡åŠ¹åŒ–
+ã—ãŸã‘ã‚Œã°ï¼Œãã‚Œãžã‚Œ\Param{autospacing}ã¨\Param{autoxspacing}ã‚’
+\texttt{true}/\texttt{false}ã«è¨­å®šã™ã‚Œã°ã‚ˆã„.
+%</ja>
+
+%<en>\subsection{Shifting the baseline}
+%<ja>\subsection{ベースラインã®ç§»å‹•}
+%<*en>
+To make a match between a Japanese font and an alphabetic font, sometimes
+shifting of the baseline of one of the pair is needed. In \pTeX, this is achieved
+by setting \cs{ybaselineshift} (or \cs{tbaselineshift}) to a non-zero length (the
+baseline of \textbf{ALchar} is shifted below). However, for documents
+whose main language is not Japanese, it is good to shift the baseline of
+Japanese fonts, but not that of alphabetic fonts.
+Because of this, \LuaTeX-ja can independently set the shifting amount
+of the baseline of alphabetic fonts and that of Japanese fonts.
+\begin{center}
+ \small
+\begin{tabular}{>{\bfseries}lcc}
+\toprule
+&\bfseries Horizontal writing (\emph{yoko} direction) etc.
+&\bfseries Vertical writing(\emph{tate} direction)\\
+\midrule
+Alphabetic fonts&\Param{yalbaselineshift}
+ parameter&\Param{talbaselineshift} parameter\\
+Japanese fonts&\Param{yjabaselineshift}
+ parameter&\Param{tjabaselineshift} parameter\\
+\bottomrule
+\end{tabular}
+\end{center}
+%</en>
+%<*ja>
+和文フォントã¨æ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚’åˆã‚ã›ã‚‹ãŸã‚ã«ã¯ï¼Œæ™‚々ã©ã¡ã‚‰ã‹ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã®ç§»å‹•ãŒ
+å¿…è¦ã«ãªã‚‹ï¼Ž\pTeX ã§ã¯ã“れ㯠\cs{ybaselineshift}(ã¾ãŸã¯\cs{tbaselineshift})を設定ã™ã‚‹ã“ã¨ã§
+ãªã•ã‚Œã¦ã„ãŸï¼ˆ\textbf{ALchar}ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ãŒãã®åˆ†ã ã‘下ãŒã‚‹ï¼‰ï¼Žã—ã‹ã—,日本語ãŒä¸»ã§ã¯ãªã„
+文書ã«å¯¾ã—ã¦ã¯ï¼Œæ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆã§ã¯ãªã和文フォントã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã‚’移動ã—ãŸæ–¹ãŒã‚ˆã„.
+ã“ã®ãŸã‚,\LuaTeX-jaã§ã¯æ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã®ã‚·ãƒ•ãƒˆé‡
+ã¨å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã®ã‚·ãƒ•ãƒˆé‡ã‚’独立ã«è¨­å®šã§ãるよã†ã«ãªã£ã¦ã„る.
+\begin{center}
+ \small
+\begin{tabular}{>{\bfseries}lcc}
+\toprule
+&\bfseries 横組ãªã©&\bfseries 縦組\\
+\midrule
+欧文フォントã®ã‚·ãƒ•ãƒˆé‡&\Param{yalbaselineshift}
+ parameter&\Param{talbaselineshift} parameter\\
+和文フォントã®ã‚·ãƒ•ãƒˆé‡&\Param{yjabaselineshift}
+ parameter&\Param{tjabaselineshift} parameter\\
+\bottomrule
+\end{tabular}
+\end{center}
+%</ja>
+
+%<*en>
+Here the horizontal line in the below example is the baseline of a line.
+%</en>
+%<*ja>
+下ã®ä¾‹ã«ãŠã„ã¦å¼•ã‹ã‚Œã¦ã„る水平線ãŒãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã§ã‚る.
+%</ja>
+\begin{LTXexample}
+\vrule width 150pt height 0.2pt depth 0.2pt \hskip-120pt
+\ltjsetparameter{yjabaselineshift=0pt, yalbaselineshift=0pt}abcã‚ã„ã†
+\ltjsetparameter{yjabaselineshift=5pt, yalbaselineshift=2pt}abcã‚ã„ã†
+\end{LTXexample}
+
+%<*en>
+There is an interesting side-effect: characters in different size can be
+vertically aligned center in a line, by setting two parameters appropriately.
+The following is an example (beware the value is not well tuned):
+%</en>
+%<*ja>
+ã“ã®æ©Ÿèƒ½ã«ã¯é¢ç™½ã„使ã„æ–¹ãŒã‚る:2ã¤ã®ãƒ‘ラメータをé©åˆ‡ã«è¨­å®šã™ã‚‹ã“ã¨ã§ï¼Œã‚µã‚¤ã‚ºã®
+ç•°ãªã‚‹æ–‡å­—を中心線ã«æƒãˆã‚‹ã“ã¨ãŒã§ãる.
+以下ã¯ä¸€ã¤ã®ä¾‹ã§ã‚る(値ã¯ã‚ã¾ã‚Šèª¿æ•´ã•ã‚Œã¦ã„ãªã„ã“ã¨ã«æ³¨æ„):
+%</ja>
+\begin{LTXexample}[width=0.4\textwidth]
+\vrule width 150pt height4.417pt depth-4.217pt%
+\kern-150pt
+\large xyz漢字
+{\scriptsize
+ \ltjsetparameter{yjabaselineshift=-1.757pt,
+ yalbaselineshift=-1.757pt}
+ 漢字xyzã‚ã„ã†
+}ã‚ã„ã†abc
+\end{LTXexample}
+
+%<*en>
+Note that setting positive \Param{yalbaselineshift}~or~\Param{talbaselineshift}
+parameters does not increase the depth of one-letter \emph{syllable} $p$ of \textbf{Alchar}, if
+its left-protrusion~(\cs{lpcode}) and right-protrusion~(\cs{rpcode}) are both non-zero.
+This is because
+\begin{itemize}
+\item These two parameters are implemented by setting \texttt{yoffset} field of a
+glyph node, and this does not increase the depth of the glyph.
+\item To cope with the above situation, \LuaTeX-ja automatically supplies
+a rule in every syllable.
+\item However, we cannot use this ``supplying a rule'' method if a syllable comprises just
+ one letter whose \cs{lpcode}~and~\cs{rpcode} are both non-zero.
+\end{itemize}
+
+This problem does not apply for \Param{yjabaselineshift}~nor~\Param{tjabaselineshift},
+becuse a \emph{JAchar} is encapsulated by a horizontal box if needed.
+%</en>
+%<*ja>
+ãªãŠï¼Œä»¥ä¸‹ã®å ´åˆã«ã¯1文字ã®\textbf{ALchar}ã‹ã‚‰ãªã‚‹ã€ŒéŸ³ç¯€ã€ã®æ·±ã•ã¯å¢—加ã—ãªã„ã“ã¨ã«æ³¨æ„.
+\begin{itemize}
+ \item \Param{yalbaselineshift},~\Param{talbaselineshift}パラメータãŒæ­£ã«ãªã£ã¦ã„る.
+ \item 「音節ã€ã‚’構æˆã™ã‚‹å”¯ä¸€ã®æ–‡å­—$p$ã®
+左余白ã¸ã®çªå‡ºé‡(\cs{lpcode}),å³ä½™ç™½ã¸ã®çªå‡ºé‡(\cs{rpcode})ãŒã©ã¡ã‚‰ã‚‚éžé›¶ã§ã‚る.
+\end{itemize}
+\emph{JAchar}ã¯å¿…è¦ã«å¿œã˜ã¦1文字ãšã¤ãƒœãƒƒã‚¯ã‚¹ã«ã‚«ãƒ—セル化ã•ã‚Œã‚‹ãŸã‚,
+\Param{yjabaselineshift},~\Param{tjabaselineshift}パラメータã«ã¤ã„ã¦ã¯ã“ã®ã‚ˆã†ãªå•é¡Œã¯èµ·ã“らãªã„.
+%</ja>
+
+%<*ja>
+\paragraph{æ•°å¼ã«ãŠã‘る挙動:\pTeX ã¨ã®é•ã„}
+\textbf{ALchar}ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã‚’補正ã™ã‚‹\Param{yalbaselineshift}, \Param{talbaselineshift}パラメータã¯
+ã»ã¼\pTeX ã«ãŠã‘ã‚‹ \cs{ybaselineshift}, \cs{tbaselineshift} ã«å¯¾å¿œã—ã¦ã„ã‚‹ã‚‚ã®ã§ã‚ã‚‹ãŒï¼Œ
+æ•°å¼ä¸­ã®æŒ™å‹•ã¯ç•°ãªã£ã¦ã„ã‚‹ã®ã§æ³¨æ„ãŒå¿…è¦ã§ã‚る.
+例ãˆã°ï¼Œ\autoref{tab:math_bsa}ã®ã‚ˆã†ã«ï¼Œæ•°å¼ä¸­ã«æ˜Žç¤ºçš„ã«ç¾ã‚ŒãŸ \cs{hbox},~\cs{vbox} ã¯ï¼Œæ¨ªçµ„ã«ãŠã„ã¦
+\begin{itemize}
+ \item 2015年以å‰ã®\pTeX ã§ã¯ï¼Œãƒœãƒƒã‚¯ã‚¹å…¨ä½“㌠\cs{ybaselineshift} ã ã¨ã‚·ãƒ•ãƒˆã•ã‚Œã‚‹ã®ã§ï¼Œ
+ \autoref{tab:math_bsa}中ã®``ã„''ã®ã‚ˆã†ã«ï¼Œãƒœãƒƒã‚¯ã‚¹ä¸­ã®å’Œæ–‡æ–‡å­—ã¯
+ \ \cs{ybaselineshift} ã ã‘シフトã•ã‚Œï¼Œä¸€æ–¹ï¼Œ``for all''ã®ã‚ˆã†ã«ï¼Œ
+ ボックス内ã®æ¬§æ–‡æ–‡å­—ã¯2é‡ã«ã‚·ãƒ•ãƒˆã•ã‚Œã‚‹ã“ã¨ã«ãªã‚‹ï¼Ž
+ \item 一方,\LuaTeX-jaã§ã¯ãã®ã‚ˆã†ãªã“ã¨ã¯ãŠã“らãšï¼Œ
+ æ•°å¼ä¸­ã«æ˜Žç¤ºçš„ã«ç¾ã‚ŒãŸ \cs{hbox},~\cs{vbox} ã¯ã‚·ãƒ•ãƒˆã—ãªã„.ãã®ãŸã‚,
+ \autoref{tab:math_bsa}中ã®``ã„''ã‚‚``for all''も,ãã‚Œãžã‚Œæœ¬æ–‡ä¸­ã«
+ 書ã‹ã‚ŒãŸã¨ãã¨åŒã˜ä¸Šä¸‹ä½ç½®ã«çµ„ã¾ã‚Œã‚‹ï¼Ž
+
+ ãªãŠï¼Œ\TeX~Live~2016以é™ã®\pTeX ã§ã¯æ”¹ä¿®ãŒãªã•ã‚Œï¼Œ\LuaTeX-jaã¨
+ è¿‘ã„挙動ã«ãªã‚‹ã‚ˆã†ã«ã—ã¦ã„ã‚‹ãŒï¼Œæ•°å¼ä¸­ã«ç›´ã«æ›¸ã‹ã‚ŒãŸ``ã‚''ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã«ã¤ã„ã¦ã¯
+ ã¾ã é•ã„ãŒè¦‹ã‚‰ã‚Œã‚‹ï¼Ž
+\end{itemize}
+
+ãªãŠï¼Œãƒãƒ¼ã‚¸ãƒ§ãƒ³20170401.0以é™ã®\LuaTeX-jaã§ã¯ï¼Œ\cs{vcenter} ã«ã‚ˆã‚‹ãƒœãƒƒã‚¯ã‚¹ã«ã¯
+全体ãŒ\Param{yalbaselineshift}, \Param{talbaselineshift} パラメータãŒå映ã•ã‚Œã‚‹ã‚ˆã†ã«ã—ã¦ã„る.
+ãã®æ–¹ãŒçµæžœãŒè‡ªç„¶ã§ã‚ã‚‹ã“ã¨ã«ã‚ˆã‚‹å¤‰æ›´ãªã®ã ãŒï¼Œçµæžœçš„ã«\cs{vcenter} ã«ã¤ã„ã¦ã¯\pTeX ã¨åŒã˜æŒ™å‹•ã¨ãªã£ãŸï¼Ž
+
+\begin{table}
+\small\centering
+\caption{æ•°å¼é–¢ä¿‚ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³è£œæ­£($\Param{yalbaselineshift}=10\,\textrm{pt}$)}
+\label{tab:math_bsa}
+\newdimen\origbaselineskip
+\origbaselineskip=\baselineskip
+\begin{tabular}{lp{30\zw}}
+\toprule
+\emph{入力}&\vspace*{\dimexpr-\origbaselineskip-\smallskipamount}
+\begin{lstlisting}
+æ•°å¼abc: $ã‚a\hbox{ã„}$, $\int_0^x t\,dt=x^2/2$,
+$\Phi\vdash F(x)\ \hbox{for all}\ x\in A$
+\end{lstlisting}\\
+\noalign{\vskip-\origbaselineskip}
+\midrule
+\emph{\pTeX~(--2015)}&
+{\ltjsetparameter{yalbaselineshift=10pt}%
+æ•°å¼abc: $\lower10pt\hbox{ã‚}a\lower10pt\hbox{ã„}$, $\int_0^x t\,dt=x^2/2$,
+$\Phi\vdash F(x)\ \lower10pt\hbox{for all}\ x\in A$
+\par}\\\noalign{\vskip-\origbaselineskip}\midrule
+\emph{\pTeX~(2016--)}&
+{\ltjsetparameter{yalbaselineshift=10pt}%
+æ•°å¼abc: $\lower10pt\hbox{ã‚}a\hbox{ã„}$, $\int_0^x t\,dt=x^2/2$,
+$\Phi\vdash F(x)\ \hbox{for all}\ x\in A$
+\par}\\\noalign{\vskip-\origbaselineskip}\midrule
+\emph{\LuaTeX-ja}&
+{\ltjsetparameter{yalbaselineshift=10pt}%
+æ•°å¼abc: $ã‚a\hbox{ã„}$, $\int_0^x t\,dt=x^2/2$,
+$\Phi\vdash F(x)\ \hbox{for all}\ x\in A$
+\par}\\
+\noalign{\vskip-\origbaselineskip}
+\bottomrule
+\end{tabular}
+\end{table}
+%</ja>
+
+%<*en>
+\subsection{\emph{kinsoku} parameters and OpenType features}
+Among parameters which related to Japanese word-wrapping process (\emph{kinsoku shori}),
+\begin{quote}
+ \Param{jaxspmode},~\Param{alxspmode}, \Param{prebreakpenalty},
+ \Param{postbreakpenalty}~and~\Param{kcatcode}
+\end{quote}
+are stored by each character codes.
+
+OpenType font features are ignored in these parameters.
+For example, a fullwidth katakana ``ã‚¢'' on line~10 in the below input is replaced to
+its halfwidth variant ``ï½±'', by \verb+hwid+ feature.
+However, the penalty inserted after it is 10 which is the \Param{postbreakpenalty} of
+``ã‚¢'', not 20.
+%</en>
+%<*ja>
+\subsection{ç¦å‰‡å‡¦ç†é–¢é€£ãƒ‘ラメータã¨OpenType機能}
+ç¦å‰‡å‡¦ç†ã‚„ \Param{kanjiskip}, \Param{xkanjiskip} ã®æŒ¿å…¥ã«é–¢é€£ã—ãŸãƒ‘ラメータã®ã†ã¡
+\begin{quote}
+ \Param{jaxspmode},~\Param{alxspmode}, \Param{prebreakpenalty},
+ \Param{postbreakpenalty}, \Param{kcatcode}
+\end{quote}
+ã¯ï¼Œæ–‡å­—コードã”ã¨ã«è¨­å®šã™ã‚‹é‡ã§ã‚る.
+
+\Pkg{fontspec}パッケージを使ã†ï¼ˆ\ref{ssec:fontspec}節)場åˆãªã©ï¼Œ
+å„種ã®OpenType機能をé©ç”¨ã™ã‚‹ã“ã¨ã‚‚ã‚ã‚‹ã¨æ€ã†ãŒï¼Œå‰æ®µè½ã«è¿°ã¹ãŸãƒ‘ラメータ類ã¯ï¼Œ
+\emph{OpenType機能ã®é©ç”¨å‰ã®æ–‡å­—コードã«ã‚ˆã£ã¦é©ç”¨ã•ã‚Œã‚‹ï¼Ž}
+例ãˆã°ï¼Œä»¥ä¸‹ã®ä¾‹ã«ãŠã„ã¦10行目ã®ã€Œã‚¢ã€ã¯ï¼Œ\verb+hwid+ featureã®é©ç”¨ã«ã‚ˆã‚ŠåŠè§’カタカナã®ã€Œï½±ã€
+ã«ç½®ãæ›ã‚る.ã—ã‹ã—,ãã®ç›´å¾Œã«æŒ¿å…¥ã•ã‚Œã‚‹ \Param{postbreakpenalty}ã¯ï¼Œç½®æ›å‰ã®ã€Œã‚¢ã€ã«å¯¾ã™ã‚‹å€¤10ã§ã‚る.
+%</ja>
+
+\begin{LTXexample}[width=0.2\textwidth]
+\ltjsetparameter{postbreakpenalty={`ã‚¢, 10}}
+\ltjsetparameter{postbreakpenalty={`ï½±, 20}}
+
+\newcommand\showpostpena[1]{%
+ \leavevmode\setbox0=\hbox{#1\hbox{}}%
+ \unhbox0\setbox0=\lastbox\the\lastpenalty}
+
+\showpostpena{ã‚¢},
+\showpostpena{ï½±},
+{\addjfontfeatures{CharacterWidth=Half}\showpostpena{ã‚¢}}
+\end{LTXexample}
+
+\clearpage
+%<en>\part{Reference}
+%<ja>\part{リファレンス}
+\label{part-ref}
+\suppressfloats[t]
+%<*ja>
+\section{\LuaTeX-jaã«ãŠã‘ã‚‹ \cs{catcode}}
+\label{sec-catcode}
+\subsection{予備知識:\pTeX ã¨\upTeX ã«ãŠã‘ã‚‹ \cs{kcatcode}}
+\pTeX,\upTeX ã«ãŠã„ã¦ã¯ï¼Œå’Œæ–‡æ–‡å­—ãŒåˆ¶å¾¡ç¶´å†…ã§åˆ©ç”¨ã§ãã‚‹ã‹ã©ã†ã‹
+㯠\cs{kcatcode} ã®å€¤ã«ã‚ˆã£ã¦æ±ºå®šã•ã‚Œã‚‹ã®ã§ã‚ã£ãŸï¼Ž
+詳細ã¯\autoref{tab:kcat}ã‚’å‚ç…§ã•ã‚ŒãŸã„.
+%</ja>
+%<*en>
+\section{\cs{catcode} in \LuaTeX-ja}
+\label{sec-catcode}
+\subsection{Preliminaries: \cs{kcatcode} in \pTeX\ and \upTeX}
+In \pTeX~and~\upTeX, the value of \cs{kcatcode} determines
+whether a Japanese character can be used in a control word.
+For the detail, see \autoref{tab:kcat}.
+%</en>
+
+\begin{table}[t]
+\small
+\caption{\cs{kcatcode} in \upTeX}
+\label{tab:kcat}
+%<en>\medskip
+
+\noindent\hfill
+\begin{tabular}{llccc}
+\toprule
+\bfseries \cs{kcatcode}&
+%<*en>
+\bfseries meaning&
+\bfseries control word&
+\bfseries widow penalty&
+\bfseries linebreak\\
+%</en>
+%<*ja>
+\bfseries æ„図&
+\bfseries 制御綴中ã«ä½¿ç”¨&
+\bfseries 文字ウィドウ処ç†&
+\bfseries 直後ã§ã®æ”¹è¡Œ\\
+%</ja>
+\midrule
+15&non-cjk&\multicolumn{3}{c}{(treated as usual \LaTeX)}\\
+16&kanji&Y&Y&ignored\\
+17&kana&Y&Y&ignored\\
+18&other&N&N&ignored\\
+19&hangul&Y&Y&space\\
+\bottomrule
+\end{tabular}\hfill\null
+
+\medskip
+
+%<*ja>
+文字ウィドウ処ç†ï¼šã€Œæ¼¢å­—ãŒä¸€æ–‡å­—ã ã‘次ã®è¡Œã«è¡Œãã®ã‚’防ãã€
+\cs{jcharwidowpenalty} ãŒï¼Œ
+ãã®æ–‡å­—ã®ç›´å‰ã«æŒ¿å…¥ã•ã‚Œã†ã‚‹ã‹å¦ã‹ï¼Œã‚’示ã™ï¼Ž
+%</ja>
+\end{table}
+
+%<*en>
+\cs{kcatcode} can be set by a row of JIS~X~0208 in \pTeX,
+and generally by a Unicode block\footnote{%
+ \upTeX\ divides \texttt{U+FF00}--\texttt{U+FFEF} (Halfwidth and Fullwidth Forms)
+ into three subblocks, and \cs{kcatcode} can be set by a subblock.
+}
+in \upTeX. So characters which can be used in a control word
+slightly differ between \pTeX~and~\upTeX.
+%</en>
+%<*ja>
+\pTeX ã§ã¯ \cs{kcatcode} ã¯JIS~X~0208ã®åŒºå˜ä½ï¼Œ
+\upTeX ã§ã¯æ¦‚ã­Unicodeブロックå˜ä½\footnote{%
+ \texttt{U+FF00}--\texttt{U+FFEF} (Halfwidth and Fullwidth Forms)ã¯
+ 「全角英数字ã€ã€ŒåŠè§’カナã€ã€Œãã®ä»–ã€ã¨3ã¤ã«åˆ†å‰²ã•ã‚Œã¦ãŠã‚Šï¼Œ
+ ãã‚Œãžã‚Œåˆ¥ã€…ã« \cs{kcatcode} ãŒæŒ‡å®šã§ãるよã†ã«ãªã£ã¦ã„る.
+}ã§è¨­å®šå¯èƒ½ã«ãªã£ã¦ã„る.ãã®ãŸã‚,\pTeX ã¨\upTeX ã®åˆæœŸçŠ¶æ…‹ã§ã¯
+制御綴内ã§ä½¿ç”¨å¯èƒ½ãªæ–‡å­—ãŒå¾®å¦™ã«ç•°ãªã£ã¦ã„る.
+%</ja>
+
+%<*en>
+\subsection{Case of \LuaTeX-ja}
+The role of \cs{kcatcode} in \pTeX~and~\upTeX\ can be
+divided into the following four kinds,
+and \LuaTeX-ja can control these four kinds separately:
+\begin{itemize}
+ \item
+\emph{Distinction between \textbf{JAchar} or \textbf{ALchar}}
+is controlled by the character range, see Subsection~\ref{ssec:setrange}.
+ \item
+\emph{Whether the character can be used in a control word}
+is controlled by setting \cs{catcode} to 11~(enabled) or 12~(disabled), as usual.
+ \item
+\emph{Whether \Param{jcharwidowpenalty} can be inserted before the character}
+is controlled by the lowermost bit of the \Param{kcatcode} parameter.
+ \item
+\emph{Linebreak after a \textbf{JAchar}} does not produce a space.
+\end{itemize}
+%</en>
+%<*ja>
+\subsection{\LuaTeX-jaã®å ´åˆ}
+\LuaTeX-jaã§ã¯ï¼Œå¾“æ¥ã®\pTeX・\upTeX ã«ãŠã‘ã‚‹ \cs{kcatcode} ã®å½¹å‰²ã‚’
+分割ã—ã¦ã„る:
+\begin{description}
+ \item[欧文/和文ã®åŒºåˆ¥ (\upTeX)]
+\cs{ltjdefcharrange} ã¨\textsf{jacharrange}パラメータ(\ref{ssec:setrange}節)
+ \item[制御綴中ã«ä½¿ç”¨å¯ã‹]
+\LuaTeX 自身㮠\cs{catcode} ã§ã‚ˆã„
+ \item[\Param{jcharwidowpenalty}ãŒæŒ¿å…¥å¯ã‹]
+\Param{kcatcode}パラメータã®æœ€ä¸‹ä½ãƒ“ット
+ \item[直後ã®æ”¹è¡Œ]
+日本語ã—ã‹æƒ³å®šã—ã¦ã„ãªã„ã®ã§ï¼Œ\textbf{JAchar}直後ã®æ”¹è¡Œã§åŠè§’スペースãŒæŒ¿å…¥ã•ã‚Œã‚‹ã“ã¨ã¯ãªã„.
+\end{description}
+%</ja>
+
+%<*en>
+Default setting of \cs{catcode} of Unicode characters are located in
+\begin{description}
+ \item[plain \LuaTeX] \texttt{luatex-unicode-letters.tex}, which is based on \texttt{unicode-letters.tex}
+(for \XeTeX).
+ \item[\LuaLaTeX] now included in \LaTeX\ kernel as~\texttt{unicode-letters.def}.
+\end{description}
+However, the default setting of \cs{catcode} differs
+between \XeTeX\ and \LuaTeX, by the following reasons:
+\begin{itemize}
+ \item (plain format) \texttt{luatex-unicode-letters.tex} is based on old \texttt{unicode-letters.tex}.
+ \item The latter half of \texttt{unicode-letters.tex}~and~\texttt{unicode-letters.def}
+sets\cs{catcode} of several characters to 11, via setting \cs{XeTeXcharclass}.
+However, this latter half does not exist (plain case), or not executed (\LaTeX~case) in \LuaTeX.
+\end{itemize}
+In other words,
+\begin{description}
+\item[plain \LuaTeX]
+Kanji nor kana characters cannot be used in
+a control word, in the default setting of plain \LuaTeX.
+\item[\LuaLaTeX]
+In recent (2015-10-01 or later) \LuaLaTeX, Kanji and kana characters in a control word is supported (these catcode are 11),
+but not fullwidth alphanumerics and several other characters.
+\end{description}
+
+This would be inconvenient for \pTeX~users to shifting to \LuaTeX-ja,
+since several control words containing Kanji or other fullwidth characters, such as
+\verb+\西暦+~or~\verb+\1年目西暦+ are used in \pTeX.
+Hence, \LuaTeX-ja have a counterpart of \texttt{unicode-letters.tex}
+for \LuaTeX, \emph{to match the \cs{catcode} setting with that of \XeTeX.}
+%</en>
+%<*ja>
+ãƒã‚¤ãƒ†ã‚£ãƒ–ã«Unicode全部ã®æ–‡å­—を扱ãˆã‚‹\XeTeX ã‚„\LuaTeX ã§ã¯ï¼Œ
+文字ãŒåˆ¶å¾¡ç¶´å†…ã§ä½¿ç”¨ã§ãã‚‹ã‹ã¯é€šå¸¸ã®æ¬§æ–‡æ–‡å­—ã¨åŒã˜ã\cs{catcode}%
+ã§æŒ‡å®šã™ã‚‹ã“ã¨ã¨ãªã‚‹ï¼Žplain \XeTeX ã«ãŠã‘ã‚‹\cs{catcode}ã®åˆæœŸè¨­å®šã¯%
+\texttt{unicode-letters.tex}中ã«è¨˜è¿°ã•ã‚Œã¦ãŠã‚Šï¼Œplain \LuaTeX ã§ã¯ãれを
+å…ƒã«ã—ãŸ\texttt{luatex-unicode-letters.tex}を用ã„ã¦ã„る.
+\LaTeX ã§ã¯\cs{catcode}ã®è¨­å®šã¯ã‚«ãƒ¼ãƒãƒ«ã«\texttt{unicode-letters.def}ã¨ã—ã¦çµ±åˆã•ã‚Œï¼Ž
+ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’\XeLaTeX, \LuaLaTeX ã®ä¸¡æ–¹ãŒç”¨ã„ã¦ã„る.
+
+ã ãŒï¼Œ\XeTeX ã«ãŠã‘ã‚‹\cs{catcode}ã®åˆæœŸè¨­å®šã¨
+\LuaTeX ã«ãŠã‘ã‚‹ãã‚Œã¯ä¸€è‡´ã—ã¦ã„ãªã„:
+\begin{itemize}
+ \item \texttt{luatex-unicode-letters.tex} ã®å…ƒã«ãªã£ãŸ
+ \texttt{unicode-letters.tex}ãŒå¤ã„
+ \item \texttt{unicode-letters.tex} 後åŠéƒ¨ã‚„\texttt{unicode-letters.def}後åŠéƒ¨ã§ã¯
+\cs{XeTeXcharclass}ã®è¨­å®šã‚’è¡Œãªã£ã¦ãŠã‚Šï¼Œ
+ãã‚Œã«ã‚ˆã£ã¦æ¼¢å­—ã‚„ä»®å,ãŠã‚ˆã³å…¨è§’英数字ã®\cs{catcode}ãŒ11ã«è¨­å®šã•ã‚Œã¦ã„る.
+ã—ã‹ã—,\texttt{luatex-unicode-letters.tex}ã§ã¯ã“ã®ã€Œå¾ŒåŠéƒ¨ã€ãŒ
+ã¾ã‚‹ã”ã¨çœç•¥ã•ã‚Œã¦ãŠã‚Šï¼Œã¾ãŸ\LuaLaTeX ã§ã‚‚\texttt{unicode-letters.def}後åŠéƒ¨ã¯å®Ÿè¡Œã•ã‚Œãª
+ ã„.
+\end{itemize}
+言ã„æ›ãˆã‚‹ã¨ï¼Œ
+\begin{description}
+ \item[plain \LuaTeX] 漢字や仮åを制御綴内ã«
+使用ã™ã‚‹ã“ã¨ã¯ã§ããªã„.
+ \item[\LuaLaTeX] 最近ã®ï¼ˆ2015-10-01以é™ã®ï¼‰
+\LuaLaTeX ã§ã¯æ¼¢å­—ã‚„ä»®åを制御綴内ã«
+使用ã™ã‚‹ã“ã¨ãŒå¯èƒ½ã«ãªã£ãŸãŒï¼Œå…¨è§’英数字ã¯ç›¸å¤‰ã‚らãšä½¿ç”¨ã§ããªã„,
+\end{description}
+ã“ã‚Œã§ã¯\pTeX ã§ä½¿ç”¨ã§ããŸ\verb+\1年目西暦+\footnote{科研費\LaTeX ã§ä½¿ç”¨ã•ã‚Œã¦ã„ã‚‹ãã†ã§ã™ï¼Ž}ãªã©ãŒä½¿ãˆãªã„ã“ã¨ã¨ãªã‚Šï¼Œ
+\LuaTeX-jaã¸ã®ç§»è¡Œã§æ‰‹é–“ãŒç”Ÿã˜ã‚‹ï¼Žãã®ãŸã‚,\LuaTeX-jaã§ã¯
+\texttt{unicode-letters.tex}ã®å¾ŒåŠéƒ¨ã«ã‚ãŸã‚‹å†…容を自å‰ã§ãƒ‘ッãƒã—,
+çµæžœã¨ã—ã¦\emph{\XeTeX ã«ãŠã‘ã‚‹åˆæœŸè¨­å®šã¨åŒã˜ã«ãªã‚‹ã‚ˆã†ã«ã—ã¦ã„る.}
+%</ja>
+
+\begin{table}
+ \centering\small
+%<en>\caption{Difference of the set of non-kanji JIS~X~0208 characters which can be used in a control word}
+%<ja>\caption{制御綴中ã«ä½¿ç”¨å‡ºæ¥ã‚‹JIS~X~0208éžæ¼¢å­—ã®é•ã„}
+%<en>\medskip
+\label{tab:kcat-diff}
+\def\D#1#2#3#4{%
+ {\fboxsep0pt\fcolorbox{cyan}{white}%
+ {\large\char"#1#2#3#4}}\ (\texttt{U+#1#2#3#4})} %"
+\leavevmode\hbox to 0pt{\hss\begin{tabular}{cccccc}
+\toprule
+%<en>&\textbf{row}&\textbf{col.}&\textbf{\pTeX}&\textbf{\upTeX}&\textbf{\LuaTeX-ja}\\
+%<ja>&\emph{区}&\emph{点}&\emph{\pTeX}&\emph{\upTeX}&\emph{\LuaTeX-ja}\\
+\midrule
+%\D 3000&1&1&N&N&Y\\
+\D 30FB&1&6&N&Y&N\\
+\D 309B&1&11&N&Y&N\\
+\D 309C&1&12&N&Y&N\\
+\D FF40&1&14&N&N&Y\\
+\D FF3E&1&16&N&N&Y\\
+\D FFE3&1&17&N&N&Y\\
+\D FF3F&1&18&N&N&Y\\
+%\D 30FD&1&19&N&Y&Y\\
+%\D 30FE&1&20&N&Y&Y\\
+%\D 309D&1&21&N&Y&Y\\
+%\D 309E&1&22&N&Y&Y\\
+\D 3003&1&23&N&N&Y\\
+\D 4EDD&1&24&N&Y&Y\\
+\D 3005&1&25&N&N&Y\\
+\D 3006&1&26&N&N&Y\\
+\D 3007&1&27&N&N&Y\\
+\D 30FC&1&28&N&Y&Y\\
+\D FF0F&1&31&N&N&Y\\
+\D FF3C&1&32&N&N&Y\\
+\bottomrule
+\end{tabular}\qquad
+\begin{tabular}{cccccc}
+\toprule
+%<en>&\textbf{row}&\textbf{col.}&\textbf{\pTeX}&\textbf{\upTeX}&\textbf{\LuaTeX-ja}\\
+%<ja>&\emph{区}&\emph{点}&\emph{\pTeX}&\emph{\upTeX}&\emph{\LuaTeX-ja}\\
+\midrule
+\D FF5C&1&35&N&N&Y\\
+\D FF0B&1&60&N&N&Y\\
+\D FF1D&1&65&N&N&Y\\
+\D FF1C&1&67&N&N&Y\\
+\D FF1E&1&68&N&N&Y\\
+\D FF03&1&84&N&N&Y\\
+\D FF06&1&85&N&N&Y\\
+\D FF0A&1&86&N&N&Y\\
+\D FF20&1&87&N&N&Y\\
+\D 3012&2&9&N&N&Y\\
+\D 3013&2&14&N&N&Y\\
+\D FFE2&2&44&N&N&Y\\
+\D 212B&2&82&N&N&Y\\
+%<en>\multicolumn{3}{c}{$\vphantom{\D 3000}$\hbox{}Greek letters (row 6)}&Y&N&Y\\
+%<en>\multicolumn{3}{c}{$\vphantom{\D 3000}$\hbox{}Cyrillic letters (row 7)}&N&N&Y\\
+%<ja>\multicolumn{3}{c}{$\vphantom{\D 3000}$\hbox{}ギリシャ文字(6区)}&Y&N&Y\\
+%<ja>\multicolumn{3}{c}{$\vphantom{\D 3000}$\hbox{}キリル文字(7区)}&N&N&Y\\
+\bottomrule
+\end{tabular}\hss}\par
+\end{table}
+
+%<*en>
+\subsection{Non-kanji characters in a control word}
+Because the engine differ, so non-kanji JIS~X~0208 characters
+which can be used in a control word differ in \pTeX, in \upTeX,~and~in \LuaTeX-ja.
+\autoref{tab:kcat-diff} shows the difference.
+Except for four characters ``・'',~``゛'', ``゜'',~``゠'',
+\LuaTeX-ja admits more characters in a control word than \upTeX.
+
+Difference becomes larger, if we consider
+non-kanji JIS~X~0213 characters.
+For the detail, see \url{https://github.com/h-kitagawa/kct}.
+%</en>
+%<*ja>
+\subsection{制御綴中ã«ä½¿ç”¨å‡ºæ¥ã‚‹JISéžæ¼¢å­—ã®é•ã„}
+
+エンジンãŒç•°ãªã‚‹ã®ã§ï¼Œ\pTeX, \upTeX, \LuaTeX-ja
+ã«ãŠã„ã¦åˆ¶å¾¡ç¶´ä¸­ã«ä½¿ç”¨å¯èƒ½ãªJIS~X~0208ã®æ–‡å­—ã¯ç•°ãªã‚‹ï¼Ž
+ç•°ãªã£ã¦ã„ã‚‹ã¨ã“ã‚ã ã‘を載ã›ã‚‹ã¨ï¼Œ\autoref{tab:kcat-diff}ã®ã‚ˆã†ã«ãªã‚‹ï¼Ž
+「・ã€ã€Œã‚›ã€ã€Œã‚œã€ã€Œã‚ ã€ã‚’除ã‘ã°ï¼Œ\LuaTeX-jaã§ã¯\upTeX より多ãã®æ–‡å­—ãŒ
+制御綴ã«ä½¿ç”¨å¯èƒ½ã«ãªã£ã¦ã„る.
+
+JIS~X~0213ã®ç¯„囲ã«åºƒã’ã‚‹ã¨ï¼Œå·®ç•°ã¯ã•ã‚‰ã«å¤§ãããªã‚‹ï¼Ž
+詳細ã«ã¤ã„ã¦ã¯ä¾‹ãˆã° \url{https://github.com/h-kitagawa/kct} 中ã®\
+\texttt{kct-out.pdf} ãªã©ã‚’å‚ç…§ã™ã‚‹ã“ã¨ï¼Ž
+%</ja>
+
+
+%<*en>
+\section{Directions}
+\LuaTeX\ supports four $\Omega$-style directions: \texttt{TLT},~\texttt{TRT}, \texttt{RTT}
+and \texttt{LTL}.
+However, neither directions are not well-suited for typesetting Japanese vertically, hence we
+implemented vertical writing by rotating \texttt{TLT}-box by 90~degrees.
+%</en>
+%<*ja>
+\section{縦組}
+\label{sec-direction}
+\LuaTeX 本体ã§ã‚‚,$\Omega$・$\aleph$ç”±æ¥ã®æ©Ÿèƒ½ã¨ã—ã¦ï¼Œè¤‡æ•°ã®çµ„æ–¹å‘をサãƒãƒ¼ãƒˆã—ã¦ã„る.
+ã—ã‹ã—,\LuaTeX ãŒã‚µãƒãƒ¼ãƒˆã™ã‚‹ã®ã¯ \texttt{TLT},~\texttt{TRT}, \texttt{RTT},~\texttt{LTL}\
+ã®ã¿ã§ã‚り,日本語ã®ç¸¦çµ„ã«ä½¿ã†ã®ã¯æœ›ã¾ã—ããªã„\footnote{%
+和文文字ã ã‘ãªã‚‰ã° \texttt{RTT} を使ãˆã°ãªã‚“ã¨ã‹ãªã‚‹ã¨æ€ã†ãŒï¼Œ
+欧文文字ãŒå…¥ã£ã¦ããŸå ´åˆã¯ã†ã¾ãã„ã‹ãšï¼Œ\texttt{RTR} ã¨ã„ã†çµ„æ–¹å‘ãŒå¿…è¦ã«ãªã‚‹ï¼Ž
+}.ãã®ãŸã‚,\LuaTeX-jaã§ã¯æ¨ªçµ„(\texttt{TLT})ã§çµ„ã‚“ã ãƒœãƒƒã‚¯ã‚¹ã‚’回転ã•ã›ã‚‹æ–¹å¼ã§
+縦組を実装ã—ãŸï¼Ž
+%</ja>
+
+%<ja>\subsection{サãƒãƒ¼ãƒˆã™ã‚‹çµ„æ–¹å‘}
+\begin{table}[t]
+%<ja>\caption{\LuaTeX-ja ã®ã‚µãƒãƒ¼ãƒˆã™ã‚‹çµ„æ–¹å‘}
+%<en>\caption{Directions supported by \LuaTeX-ja}
+%<en>\medskip
+\label{tab-dir}
+\centering\small
+\def\obox#1{%
+ \setbox0=\hbox{\yoko\hbox{#1%
+ \large\ltjsetparameter{talbaselineshift=0pt}%
+ \vrule height 25pt width 0.4pt depth 15pt\kern-.2pt%
+ \raise25pt\hbox to 0pt{\hss\composite{*r^@{>>}}\hss}%
+ \raise-15pt\hbox to 0pt{\hss\composite{*l^@{>|}}\hss}\kern.2pt%
+ \vrule height.2pt depth.2pt width 60pt\hbox to 0pt{\hss\composite{*d^@{>}}\hss}\kern-60pt
+ \hbox to 60pt{\,銀ã¯ã€Ag\hss}}}%
+ \raise\dimexpr 0.5\ltjgetdp0-0.5\ltjgetht0\box0%
+}
+%<*ja>
+\begin{tabular}{>{\bfseries}lcccc}
+\toprule
+&横組&縦組 &「dtouæ–¹å‘ã€&「utodæ–¹å‘ã€\\
+\midrule
+命令&\cs{yoko}&\cs{tate}&\cs{dtou}&\cs{utod}\\
+å­—é€ã‚Šæ–¹å‘&æ°´å¹³å³å‘ã(→)&垂直下å‘ã(↓)&垂直上å‘ã(↑)&垂直下å‘ã(↓)\\
+è¡Œé€ã‚Šæ–¹å‘&垂直下å‘ã(↓)&水平左å‘ã(â†ï¼‰&æ°´å¹³å³å‘ã(→)&水平左å‘ã(â†ï¼‰\\
+使用ã™ã‚‹å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆ&横組用(\cs{jfont})&縦組用(\cs{tfont})&
+\multicolumn{2}{c}{%
+ 横組用(\cs{jfont})ã®$90^\circ$回転}\\[\smallskipamount]
+組版例\null $^*$ &\obox{\yoko}&\obox{\tate}&\obox{\dtou}&\obox{\utod}\\
+\noalign{\medskip}
+\bottomrule
+\end{tabular}
+
+\medskip\raggedright
+\def\R#1{%
+ \raise0.38\zw\hbox{%
+ \vrule height.2pt depth.2pt width2\zw%
+ \hbox to 0pt{\hss\composite{*d^@{#1}}\hss}%
+ }%
+}
+$^*$\ å¹…(width),高ã•(height),深ã•(depth)ã®å¢—加方å‘を,
+ãã‚Œãžã‚Œã€Œ\R{>}ã€ï¼Œã€Œ\R{>>}ã€ï¼Œã€Œ\R{>|}ã€ã§è¡¨ã—ã¦ã„る.
+\raggedright
+%</ja>
+
+%<*en>
+\begin{tabular}{>{\bfseries}lcccc}
+\toprule
+&horizontal (\emph{yoko}~direction)&vertical (\emph{tate}~direction)&%
+ \emph{dtou} direction&\emph{utod} direction\\
+\midrule
+Commands&\cs{yoko}&\cs{tate}&\cs{dtou}&\cs{utod}\\
+Beginning of the page&Top&Right&Left&Right\\
+Beginning of the line&Left&Top&Bottom&Top\\
+Used Japanese font&horizontal (\cs{jfont})&vertical (\cs{tfont})&
+\multicolumn{2}{c}{%
+ horizontal ($90^\circ$ rotated)}\\[\smallskipamount]
+Example&\obox{\yoko}&\obox{\tate}&\obox{\dtou}&\obox{\utod}\\
+\noalign{\medskip}
+(Notation used in $\Omega$)&TLT&RTR, RTT&LBL&RTR\\
+\bottomrule
+\end{tabular}
+
+\medskip\raggedright
+\def\R#1{%
+ \raise0.38\zw\hbox{%
+ \vrule height.2pt depth.2pt width2\zw%
+ \hbox to 0pt{\hss\composite{*d^@{#1}}\hss}%
+ }%
+}
+\raggedright
+%</en>
+\end{table}
+
+%<*en>
+\LuaTeX-ja supports four directions, as shown in \autoref{tab-dir}.
+The second column (\emph{yoko} direction) is just horizontal writing,
+and the third column (\emph{tate} direction) is vertical writing.
+The fourth column (\emph{dtou} direction) is actually a hidden feature of \pTeX.
+We implemented this for debugging purpose.
+The fifth column (\emph{utod} direction) corresponds the ``\texttt{tate (math) direction}'' of \pTeX.
+
+Directions can be changed by \cs{yoko},~\cs{tate}, \cs{dtou},~\cs{utod},
+only when the current list is null.
+These commands cannot be executed in unrestricted horizontal modes, nor math modes.
+The direction of a math formula is changed to
+\emph{utod}, when the direction outside the math formula is \emph{tate} (vertical writing).
+%</en>
+
+%<*ja>
+\LuaTeX-jaãŒã‚µãƒãƒ¼ãƒˆã™ã‚‹çµ„æ–¹å‘ã¯\autoref{tab-dir}ã«ç¤ºã™4ã¤ã§ã‚る.
+4列目㮠\cs{dtou} ã¯èžã慣れãªã„命令ã ã¨æ€ã†ãŒï¼Œ
+実ã¯\pTeX ã«åŒåã®å‘½ä»¤ãŒï¼ˆãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã«ã¯æ›¸ã‹ã‚Œã¦ã„ãªã„ãŒï¼‰å­˜åœ¨ã™ã‚‹ï¼Ž
+Down-TO-Upã®æ„味ãªã®ã ã‚ã†ï¼Ž\cs{dtou} を使用ã™ã‚‹æ©Ÿä¼šã¯ãªã„ã ã‚ã†ãŒï¼Œ
+\LuaTeX-jaã§ã¯ãƒ‡ãƒãƒƒã‚°ç”¨ã«å®Ÿè£…ã—ã¦ã„る.
+5列目㮠\cs{utod} ã¯ï¼Œ\pTeX ã§è¨€ã†ã€Œç¸¦æ•°å¼ãƒ‡ã‚£ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã€ã«ç›¸å½“ã™ã‚‹ã‚‚ã®ã§ã‚る.
+
+組方å‘ã¯ï¼Œ\cs{yoko},~\cs{tate}, \cs{dtou},~\cs{utod} ã‚’ãã‚Œãžã‚Œä½¿ç”¨ã™ã‚‹ã“ã¨ã§ï¼Œ
+ç¾åœ¨ä½œæˆä¸­ã®ãƒªã‚¹ãƒˆã‚„ボックスãŒç©ºã®æ™‚ã«ã®ã¿å¤‰æ›´å¯èƒ½ã§ã‚る.
+ãŸã ã—,ç¾åœ¨ã®ãƒ¢ãƒ¼ãƒ‰ãŒéžåˆ¶é™æ°´å¹³ãƒ¢ãƒ¼ãƒ‰ã‚„(文中,別行立ã¦å•ã‚ãšï¼‰æ•°å¼ãƒ¢ãƒ¼ãƒ‰ã§ã‚ã‚‹ã¨ãã«ã¯
+組方å‘を変更ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ãªã„.
+ã¾ãŸï¼Œç¸¦çµ„中ã®æ•°å¼å†…ã®ãƒœãƒƒã‚¯ã‚¹ã¯\pTeX ã¨åŒã˜ã‚ˆã†ã«çµ„æ–¹å‘㌠\cs{utod} ã¨ãªã‚‹ï¼Ž
+
+ãªãŠï¼Œ\LaTeX ã®ä¸‹ã§\LuaTeX-jaを使用ã™ã‚‹å ´åˆï¼Œçµ„æ–¹å‘変更命令ã«ã¯
+「新ãŸãªçµ„æ–¹å‘下ã§ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚’å¿…è¦ãªã‚‰èª­ã¿è¾¼ã¿ï¼ˆãƒ»é¸æŠžã™ã‚‹ï¼‰ã€ã¨ã„ã†
+処ç†ãŒä»˜ã‘加ãˆã‚‰ã‚Œã¦ã„る(\ref{ssec:ltx-jfm}節å‚照).
+%</ja>
+
+%<*en>
+\subsection{Boxes in different direction}
+
+As in \pTeX, one can use boxes of different direction in one document.
+The below is an example.
+\begin{LTXexample}
+ã“ã“ã¯æ¨ªçµ„% yoko
+\hbox{\tate % tate
+ \hbox{縦組}% tate
+ ã®ä¸­ã«
+ \hbox{\yoko 横組ã®å†…容}% yoko
+ を挿入ã™ã‚‹
+}
+ã¾ãŸæ¨ªçµ„ã«æˆ»ã‚‹% yoko
+\end{LTXexample}
+
+\autoref{tab-diffdir} shows how a box is arranged when
+the direction inside the box and that outside the box differ.
+%</en>
+%<*ja>
+\subsection{ç•°æ–¹å‘ã®ãƒœãƒƒã‚¯ã‚¹}
+
+縦組ã®ä¸­ã«ã€Œ42ã€ãªã©ã®2æ¡ä»¥ä¸Šã®ç®—用数字を横組ã§çµ„ã‚€ãªã©ï¼Œ
+ç•°ãªã‚‹çµ„æ–¹å‘を混在ã•ã›ã‚‹ã“ã¨ãŒã—ã°ã—ã°è¡Œã‚れる.
+組方å‘ã®æ··åœ¨ã‚‚\pTeX ã¨åŒã˜ã‚ˆã†ã«ã§ãる:
+\begin{LTXexample}
+ã“ã“ã¯æ¨ªçµ„% yoko
+\hbox{\tate % tate
+ \hbox{縦組}% tate
+ ã®ä¸­ã«
+ \hbox{\yoko 横組ã®å†…容}% yoko
+ を挿入ã™ã‚‹
+}
+ã¾ãŸæ¨ªçµ„ã«æˆ»ã‚‹% yoko
+\end{LTXexample}
+
+ç•°ãªã‚‹çµ„æ–¹å‘ã®ãƒœãƒƒã‚¯ã‚¹ã‚’é…ç½®ã—ãŸå ´åˆã«ã©ã†çµ„ã¾ã‚Œã‚‹ã‹ã®ä»•æ§˜ã‚‚,\pTeX ã‚’
+è¸è¥²ã—ã¦ã„る.\autoref{tab-diffdir}ã«ç¤ºã™ï¼Ž
+%</ja>
+
+\begin{table}[t]
+%<ja>\caption{ç•°æ–¹å‘ã®ãƒœãƒƒã‚¯ã‚¹ã®é…ç½®}
+%<en>\caption{Boxes in different direction}
+%<en>\medskip
+\label{tab-diffdir}
+ \centering\small\unitlength3mm
+ \def\TATEeg{%
+ \hbox{\smash{\begin{picture}(0,0)(-2,0)
+ \thicklines
+ \polyline(-2,0)(-2,-7)(5,-7)(5,0)
+ \put(0,0){\circle*{0.3}}
+ \put(2.5,-4){\makebox(0,0){\hbox{\tate\bfseries \emph{tate}/\emph{utod}}}}
+ \put(0,0){\vector(1,0){5}} \put(2.5,-0.2){\makebox(0,0)[t]{$h_{\mathrm{T}}$}}
+ \put(0,0){\vector(-1,0){2}}\put(-1,-0.2){\makebox(0,0)[t]{$d_{\mathrm{T}}$}}
+ \put(0,0){\vector(0,-1){7}}\put(0.2,-3.5){\makebox(0,0)[l]{$w_{\mathrm{T}}$}}
+ \end{picture}}}%
+ }
+ \def\DTOUeg{%
+ \hbox{\smash{\begin{picture}(0,0)(-5,0)
+ \thicklines
+ \polyline(-5,0)(-5,7)(2,7)(2,0)
+ \put(0,0){\circle*{0.3}}
+ \put(-2.5,4){\makebox(0,0){\hbox{\dtou\bfseries \emph{dtou}}}}
+ \put(0,0){\vector(-1,0){5}} \put(-2.5,0.3){\makebox(0,0)[b]{$h_{\mathrm{D}}$}}
+ \put(0,0){\vector(1,0){2}}\put(1,0.3){\makebox(0,0)[b]{$d_{\mathrm{D}}$}}
+ \put(0,0){\vector(0,1){7}}\put(-0.2,3.5){\makebox(0,0)[r]{$w_{\mathrm{D}}$}}
+ \end{picture}}}%
+ }
+ \def\YOKOeg{%
+ \hbox{\smash{\begin{picture}(0,0)
+ \thicklines
+ \polyline(0,5)(7,5)(7,-2)(0,-2)
+ \put(4,2.5){\makebox(0,0){\hbox{\yoko\bfseries \emph{yoko}}}}
+ \put(0,0){\circle*{0.3}}
+ \put(0,0){\vector(0,1){5}} \put(0.3,2.5){\makebox(0,0)[l]{$h_{\mathrm{Y}}$}}
+ \put(0,0){\vector(0,-1){2}}\put(0.3,-1){\makebox(0,0)[l]{$d_{\mathrm{Y}}$}}
+ \put(0,0){\vector(1,0){7}}\put(3.5,0.2){\makebox(0,0)[b]{$w_{\mathrm{Y}}$}}
+ \end{picture}}}%
+ }
+\begin{tabular}{ccc}
+\toprule
+%<ja>\emph{横組中ã«é…ç½®}&\emph{縦組中ã«é…ç½®}&%
+%<ja>\emph{çµ„æ–¹å‘ \cs{dtou} 中ã«é…ç½®}\\
+%<en>\textbf{typeset in \emph{yoko} direction}
+%<en>&\textbf{typeset in \emph{tate} or \emph{utod} direction}
+%<en>&\textbf{typeset in \emph{dtou} direction}\\
+\midrule
+ \parbox[c]{15\unitlength}{\begin{picture}(15,15)(0,-4)
+ \put(0,0){\line(1,0){3.8}}
+ \put(4,7){\TATEeg}
+ \put(11.2,0){\line(1,0){3.8}}
+%
+ \put(2,7){\line(1,0){1.8}}
+ \put(3,3.5){\vector(0,1){3.5}\vector(0,-1){3.5}}
+ \put(2.8,3.5){\makebox(0,0)[r]{$H_{\mathrm{Y}}$}}
+ \put(3,-2){\vector(0,1){2}}
+ \put(2.8,-1){\makebox(0,0)[r]{$D_{\mathrm{Y}}$}}
+%
+ \put(4,7.2){\line(0,1){1.8}}
+ \put(11,7.2){\line(0,1){1.8}}
+ \put(6,8){\vector(-1,0){2}}
+ \put(9,8){\vector(1,0){2}}
+ \put(7.5,8){\makebox(0,0){$W_{\mathrm{Y}}$}}
+%
+ \end{picture}\vspace{-\baselineskip}
+ \begin{align*}
+ W_{\mathrm{Y}} &= h_{\mathrm{T}}+d_{\mathrm{T}},\\
+ H_{\mathrm{Y}} &= w_{\mathrm{T}},\\
+ D_{\mathrm{Y}} &=0\,\mathrm{pt}
+ \end{align*}%
+ }&
+ \parbox[c]{15\unitlength}{\begin{picture}(15,15)(0,-4)
+ \put(7.5,-0.2){\line(0,-1){2.8}}
+ \put(4,2){\YOKOeg}
+ \put(7.5, 7.2){\line(0,1){3.8}}
+%
+ \put(2,7){\line(1,0){1.8}}
+ \put(2,0){\line(1,0){1.8}}
+ \put(3,5){\vector(0,1){2}}
+ \put(3,2){\vector(0,-1){2}}
+ \put(3,3.5){\makebox(0,0){$W_{\mathrm{T}}$}}
+%
+ \put(4,7.2){\line(0,1){1.8}}
+ \put(11,7.2){\line(0,1){1.8}}
+ \put(8,8){\vector(-1,0){0.5}\vector(1,0){3}}
+ \put(7,8){\vector(-1,0){3}\vector(1,0){0.5}}
+ \put(9.25,8.2){\makebox(0,0)[b]{$H_{\mathrm{T}}$}}
+ \put(5.75,8.2){\makebox(0,0)[b]{$D_{\mathrm{T}}$}}
+%
+ \end{picture}\vspace{-\baselineskip}
+ \begin{align*}
+ W_{\mathrm{T}} &= h_{\mathrm{Y}}+d_{\mathrm{Y}},\\
+ H_{\mathrm{T}} &= w_{\mathrm{Y}}/2,\\
+ D_{\mathrm{T}} &= w_{\mathrm{Y}}/2
+ \end{align*}%
+ }&
+ \parbox[c]{15\unitlength}{\begin{picture}(15,15)(0,-4)
+ \put(11,-0.2){\line(0,-1){2.8}}
+ \put(4,2){\YOKOeg}
+ \put(11, 7.2){\line(0,1){3.8}}
+%
+ \put(2,7){\line(1,0){1.8}}
+ \put(2,0){\line(1,0){1.8}}
+ \put(3,5){\vector(0,1){2}}
+ \put(3,2){\vector(0,-1){2}}
+ \put(3,3.5){\makebox(0,0){$W_{\mathrm{D}}$}}
+%
+ \put(4,7.2){\line(0,1){1.8}}
+ \put(11,7.2){\line(0,1){1.8}}
+ \put(7.5,8){\vector(-1,0){3.5}\vector(1,0){3.5}}
+ \put(13,8){\vector(-1,0){2}}
+ \put(7.5,8.2){\makebox(0,0)[b]{$H_{\mathrm{D}}$}}
+ \put(12,8.2){\makebox(0,0)[b]{$D_{\mathrm{D}}$}}
+%
+ \end{picture}\vspace{-\baselineskip}
+ \begin{align*}
+ W_{\mathrm{D}} &= h_{\mathrm{Y}}+d_{\mathrm{Y}},\\
+ H_{\mathrm{D}} &= w_{\mathrm{Y}},\\
+ D_{\mathrm{D}} &= 0\,\mathrm{pt}
+ \end{align*}%
+ }%
+\\\midrule
+ \parbox[c]{15\unitlength}{\begin{picture}(15,15)(0,-4)
+ \put(0,0){\line(1,0){3.8}}
+ \put(4,0){\DTOUeg}
+ \put(11.2,0){\line(1,0){3.8}}
+%
+ \put(2,7){\line(1,0){1.8}}
+ \put(3,3.5){\vector(0,1){3.5}\vector(0,-1){3.5}}
+ \put(2.8,3.5){\makebox(0,0)[r]{$H_{\mathrm{Y}}$}}
+ \put(3,-2){\vector(0,1){2}}
+ \put(2.8,-1){\makebox(0,0)[r]{$D_{\mathrm{Y}}$}}
+%
+ \put(4,7.2){\line(0,1){1.8}}
+ \put(11,7.2){\line(0,1){1.8}}
+ \put(6,8){\vector(-1,0){2}}
+ \put(9,8){\vector(1,0){2}}
+ \put(7.5,8){\makebox(0,0){$W_{\mathrm{Y}}$}}
+%
+ \end{picture}\vspace{-\baselineskip}
+ \begin{align*}
+ W_{\mathrm{Y}} &= h_{\mathrm{D}}+d_{\mathrm{D}},\\
+ H_{\mathrm{Y}} &= w_{\mathrm{D}},\\
+ D_{\mathrm{Y}} &= 0\,\mathrm{pt}
+ \end{align*}%
+ }&
+ \parbox[c]{15\unitlength}{\begin{picture}(15,15)(0,-4)
+ \put(9,-0.2){\line(0,-1){2.8}}
+ \put(4,0){\DTOUeg}
+ \put(9, 7.2){\line(0,1){3.8}}
+%
+ \put(2,7){\line(1,0){1.8}}
+ \put(2,0){\line(1,0){1.8}}
+ \put(3,5){\vector(0,1){2}}
+ \put(3,2){\vector(0,-1){2}}
+ \put(3,3.5){\makebox(0,0){$W_{\mathrm{T}}$}}
+%
+ \put(4,7.2){\line(0,1){1.8}}
+ \put(11,7.2){\line(0,1){1.8}}
+ \put(6.5,8){\vector(-1,0){2.5}\vector(1,0){2.5}}
+ \put(10,8){\vector(-1,0){1}\vector(1,0){1}}
+ \put(10,8.2){\makebox(0,0)[b]{$H_{\mathrm{T}}$}}
+ \put(6.5,8.2){\makebox(0,0)[b]{$D_{\mathrm{T}}$}}
+%
+ \end{picture}\vspace{-\baselineskip}
+ \begin{align*}
+ W_{\mathrm{T}} &= h_{\mathrm{D}}+d_{\mathrm{D}},\\
+ H_{\mathrm{T}} &= d_{\mathrm{D}},\\
+ D_{\mathrm{T}} &= h_{\mathrm{D}}
+ \end{align*}%
+ }&
+ \parbox[c]{15\unitlength}{\begin{picture}(15,15)(0,-4)
+ \put(6,-0.2){\line(0,-1){2.8}}
+ \put(4,7){\TATEeg}
+ \put(6, 7.2){\line(0,1){3.8}}
+%
+ \put(2,7){\line(1,0){1.8}}
+ \put(2,0){\line(1,0){1.8}}
+ \put(3,5){\vector(0,1){2}}
+ \put(3,2){\vector(0,-1){2}}
+ \put(3,3.5){\makebox(0,0){$W_{\mathrm{D}}$}}
+%
+ \put(4,7.2){\line(0,1){1.8}}
+ \put(11,7.2){\line(0,1){1.8}}
+ \put(5,8){\vector(-1,0){1}\vector(1,0){1}}
+ \put(8.5,8){\vector(-1,0){2.5}\vector(1,0){2.5}}
+ \put(5,8.2){\makebox(0,0)[b]{$H_{\mathrm{D}}$}}
+ \put(8.5,8.2){\makebox(0,0)[b]{$D_{\mathrm{D}}$}}
+%
+ \end{picture}\vspace{-\baselineskip}
+ \begin{align*}
+ W_{\mathrm{D}} &= w_{\mathrm{T}},\\
+ H_{\mathrm{D}} &= d_{\mathrm{T}},\\
+ D_{\mathrm{D}} &= h_{\mathrm{T}}
+ \end{align*}%
+ }\\
+\bottomrule
+\end{tabular}
+\end{table}
+
+
+
+%<*en>
+\paragraph{\cs{wd} and direction}
+In \pTeX, \cs{wd},~\cs{ht},~\cs{dp} means the dimensions of a box register
+\emph{with respact to the current direction}.
+This means that the value of \cs{wd0} etc.\ might differ when the current direction is
+different, even if \cs{box0} stores the same box.
+However, this no longer applies in \LuaTeX-ja.
+
+\begin{LTXexample}
+% yoko direction
+\setbox0=\hbox to 20pt{foo}
+\the\wd0,~\hbox{\tate\vrule\the\wd0}
+\wd0=100pt
+\the\wd0,~\hbox{\tate \the\wd0}
+\end{LTXexample}
+
+To access box dimensions \emph{with respect to current direction},
+one have to use the following commands instead of \cs{wd} wtc.
+\begin{cslist}
+
+ \item[\cs{ltjgetwd}<num>\textrm{, }\cs{ltjgetht}<num>\textrm{, }%
+ \cs{ltjgetdp}<num>]
+These commands return \emph{an internal dimension} of \cs{box<num>} with respect to
+the current direction. One can use these in \cs{dimexpr} primitive, as the followings.
+\begin{lstlisting}
+\dimexpr 2\ltjgetwd42-3pt\relax, \the\ltjgetwd1701
+\end{lstlisting}
+The following is an example.
+\begin{LTXexample}[width=0.3\textwidth]
+\parindent0pt
+\setbox32767=\hbox{\yoko よã“ãã¿}
+\fboxsep=0mm\fbox{\copy32767}
+\vbox{\hsize=20mm
+\yoko YOKO \the\ltjgetwd32767, \\
+ \the\ltjgetht32767, \\ \the\ltjgetdp32767.}
+\vbox{\hsize=20mm\raggedleft
+\tate TATE \the\ltjgetwd32767, \\
+ \the\ltjgetht32767, \\ \the\ltjgetdp32767.}
+\vbox{\hsize=20mm\raggedleft
+\dtou DTOU \the\ltjgetwd32767, \\
+ \the\ltjgetht32767, \\ \the\ltjgetdp32767.}
+\end{LTXexample}
+
+ \item[\cs{ltjsetwd}<num>=<dimen>\textrm{, }\cs{ltjsetht}<num>=<dimen>\textrm{, }%
+ \cs{ltjsetdp}<num>=<dimen>]
+These commands set the dimension of \cs{box<num>}. One does not need
+ to group the argument <num>; four calls of \cs{ltjsetwd} below have the same meaning.
+\begin{lstlisting}
+\ltjsetwd42 20pt, \ltjsetwd42=20pt, \ltjsetwd=42 20pt, \ltjsetwd=42=20pt
+\end{lstlisting}
+
+\end{cslist}
+%</en>
+%<*ja>
+\paragraph{\cs{wd} é”ã¨çµ„æ–¹å‘}
+ボックスレジスタ \cs{box}<num> ã«ã‚»ãƒƒãƒˆã•ã‚Œã¦ã„るボックスã®å¹…・高ã•ãƒ»æ·±ã•ã®å–å¾—ã‚„
+変更ã«ã¯ãã‚Œãžã‚Œ \cs{wd},~\cs{ht},~\cs{dp} プリミティブを用ã„ã‚‹ã®ã§ã‚ã£ãŸï¼Ž
+\pTeX ã§ã¯ã“れらã®ãƒ—リミティブã¯ï¼Œã€Œç¾åœ¨ã®çµ„æ–¹å‘ã«ãŠã‘るボックスã®å¯¸æ³•ã€ã‚’指ã™ã‚‚ã®ã§ï¼Œ
+åŒã˜ãƒœãƒƒã‚¯ã‚¹ã«å¯¾ã—ã¦ã‚‚ç¾åœ¨ã®çµ„æ–¹å‘ã«ã‚ˆã£ã¦è¿”る値ã¯ç•°ãªã‚‹ã‚‚ã§ã‚ã£ãŸï¼Ž
+
+\LuaTeX-jaã«ãŠã„ã¦ã¯çŠ¶æ³ãŒç•°ãªã‚Šï¼Œ\cs{wd},~\cs{ht},~\cs{dp} ãŒè¿”ã™å€¤ã¯
+ç¾åœ¨ã®çµ„æ–¹å‘ã«ã¯ä¾å­˜ã—ãªã„.下ã®ä¾‹ã®ã‚ˆã†ã«ï¼Œæ¨ªçµ„ã®ãƒœãƒƒã‚¯ã‚¹ãŒæ ¼ç´ã•ã‚Œã¦ã„ã‚Œã°
+\cs{wd}ç­‰ã¯å¸¸ã«ã€Œæ¨ªçµ„ã«ãŠã‘るボックスã®å¯¸æ³•ã€ã‚’æ„味ã™ã‚‹ï¼Ž
+
+\begin{LTXexample}
+% yoko direction
+\setbox0=\hbox to 20pt{foo}
+\the\wd0,~\hbox{\tate\vrule\the\wd0}
+\wd0=100pt
+\the\wd0,~\hbox{\tate \the\wd0}
+\end{LTXexample}
+
+\pTeX ã®ã‚ˆã†ã«ç¾åœ¨ã®çµ„æ–¹å‘ã«å¿œã˜ãŸãƒœãƒƒã‚¯ã‚¹ã®å¯¸æ³•ã®å–得・設定を行ã†ã«ã¯ï¼Œ
+代ã‚ã‚Šã«æ¬¡ã®å‘½ä»¤ã‚’使用ã™ã‚‹ï¼Ž
+
+\begin{cslist}
+
+ \item[\cs{ltjgetwd}<num>\textrm{, }\cs{ltjgetht}<num>\textrm{, }%
+ \cs{ltjgetdp}<num>]
+ç¾åœ¨ã®çµ„æ–¹å‘ã«å¿œã˜ãŸãƒœãƒƒã‚¯ã‚¹ã®å¯¸æ³•ã®å–å¾—ã‚’è¡Œã†ï¼Žçµæžœã¯å†…部長ã•ã§ã‚ã‚‹ãŸã‚,
+\begin{lstlisting}
+\dimexpr 2\ltjgetwd42-3pt\relax, \the\ltjgetwd1701
+\end{lstlisting}
+ã®ã‚ˆã†ã« \cs{wd}<num> ã®ä»£ã‚ã‚Šã¨ã—ã¦æ‰±ã†ã“ã¨ãŒã§ãる.
+使用例ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã‚る.
+\begin{LTXexample}[width=0.3\textwidth]
+\parindent0pt
+\setbox32767=\hbox{\yoko よã“ãã¿}
+\fboxsep=0mm\fbox{\copy32767}
+\vbox{\hsize=20mm
+\yoko YOKO \the\ltjgetwd32767, \\
+ \the\ltjgetht32767, \\ \the\ltjgetdp32767.}
+\vbox{\hsize=20mm\raggedleft
+\tate TATE \the\ltjgetwd32767, \\
+ \the\ltjgetht32767, \\ \the\ltjgetdp32767.}
+\vbox{\hsize=20mm\raggedleft
+\dtou DTOU \the\ltjgetwd32767, \\
+ \the\ltjgetht32767, \\ \the\ltjgetdp32767.}
+\end{LTXexample}
+
+ \item[\cs{ltjsetwd}<num>=<dimen>\textrm{, }\cs{ltjsetht}<num>=<dimen>\textrm{, }%
+ \cs{ltjsetdp}<num>=<dimen>]
+ç¾åœ¨ã®çµ„æ–¹å‘ã«å¿œã˜ãŸãƒœãƒƒã‚¯ã‚¹ã®å¯¸æ³•ã®è¨­å®šã‚’è¡Œã†ï¼Ž\cs{afterassignment} ã‚’2回利用ã—ã¦
+実装ã—ã¦ã„ã‚‹ã®ã§ï¼Œæ¬¡ã®4通りã¯å…¨ã¦åŒã˜æ„味ã§ã‚る.
+\begin{lstlisting}
+\ltjsetwd42 20pt, \ltjsetwd42=20pt, \ltjsetwd=42 20pt, \ltjsetwd=42=20pt
+\end{lstlisting}
+
+設定値ã¯ã€Œæ¨ªçµ„ã€ã€Œç¸¦çµ„åŠã³utodæ–¹å‘ã€ã€Œdtouæ–¹å‘ã€
+ã®3種ã”ã¨ã«ç‹¬ç«‹ã—ã¦è¨˜éŒ²ã•ã‚Œã‚‹ï¼Žå‚考ã¨ã—ã¦ï¼ŒGitリãƒã‚¸ãƒˆãƒªå†…ã®
+ \verb+test/test55-boxdim_diffdir.{tex,pdf}+ を挙ã’ã¦ãŠã.
+
+\end{cslist}
+%</ja>
+
+%<*en>
+\subsection{Getting current direction}
+The \Param{direction} parameter returns the current direction, and
+the \Param{boxdir} parameter (with the argument <num>)
+returns the direction of a box register \cs{box}<num>.
+The returned value of these parameters are a \emph{string}:
+\begin{center}
+\small
+\begin{tabular}{>{\bfseries}lccccc}
+\toprule
+Direction&\emph{yoko}&\emph{tate}&\emph{dtou}&\emph{utod}&(empty)\\
+\midrule
+Returned value&\texttt{4}&\texttt{3}&\texttt{1}&\texttt{11}&\texttt{0}\\
+\bottomrule
+\end{tabular}
+\end{center}
+\begin{LTXexample}[width=0.3\textwidth]
+\leavevmode\def\DIR{\ltjgetparameter{direction}}
+\hbox{\yoko \DIR}, \hbox{\tate\DIR},
+\hbox{\dtou\DIR}, \hbox{\utod\DIR},
+\hbox{\tate$\hbox{tate math: \DIR}$}
+
+\setbox2=\hbox{\tate}\ltjgetparameter{boxdir}{2}
+\end{LTXexample}
+%</en>
+%<*ja>
+\subsection{組方å‘ã®å–å¾—}
+「ç¾åœ¨ã®çµ„æ–¹å‘ã€ã‚„「<num>番ã®ãƒœãƒƒã‚¯ã‚¹ã®çµ„æ–¹å‘ã€ã¯ï¼Œ
+\pTeX ã§ã¯ \cs{ifydir} ã‚„ \cs{ifybox}<num> ã¨ã„ã£ãŸæ¡ä»¶åˆ¤æ–­æ–‡ã‚’使ã£ã¦
+判断ã™ã‚‹ã“ã¨ãŒã§ããŸï¼Ž
+ã—ã‹ã—,\LuaTeX-jaã¯ã‚ãã¾ã§ã‚‚\TeX マクロã¨Luaコードã§
+記述ã•ã‚Œã¦ãŠã‚Šï¼Œãã‚Œã§ã¯æ–°ãŸãªæ¡ä»¶åˆ¤æ–­å‘½ä»¤ã‚’作るã®ã¯é›£ã—ã„.
+
+\LuaTeX-jaã§ã¯ï¼Œ\Param{direction}パラメータã§ç¾åœ¨ã®çµ„æ–¹å‘を,
+\Param{boxdir}パラメータ(ã¨è¿½åŠ ã®å¼•æ•°<num>)ã«ã‚ˆã£ã¦
+\cs{box}<num>ã®çµ„æ–¹å‘ã‚’ãã‚Œãžã‚Œå–å¾—ã§ãるよã†ã«ã—ãŸï¼Ž
+戻り値ã¯æ–‡å­—列ã§ã‚る:
+\begin{center}
+\small
+\begin{tabular}{>{\bfseries}lccccc}
+\toprule
+組方å‘&\emph{横組}&\emph{tate縦組}&\emph{dtouæ–¹å‘}&\emph{utodæ–¹å‘}&(未割り当ã¦)\\
+\midrule
+戻り値&\texttt{4}&\texttt{3}&\texttt{1}&\texttt{11}&\texttt{0}\\
+\bottomrule
+\end{tabular}
+\end{center}
+
+\begin{LTXexample}[width=0.3\textwidth]
+\leavevmode\def\DIR{\ltjgetparameter{direction}}
+\hbox{\yoko\DIR}, \hbox{\tate\DIR},
+\hbox{\dtou\DIR}, \hbox{\utod\DIR},
+\hbox{\tate$\hbox{tate math: \DIR}$}
+
+\setbox2=\hbox{\tate}\ltjgetparameter{boxdir}{2}
+\end{LTXexample}
+
+ã“れらを用ã„ã‚Œã°ï¼Œä¾‹ãˆã°
+\pTeX ã® \cs{ifydir},~\cs{ifybox200} ã¨åŒç­‰ã®æ¡ä»¶åˆ¤æ–­ã‚’
+\begin{lstlisting}
+\ifnum\ltjgetparameter{direction}=4
+\ifnum\ltjgetparameter{boxdir}{200}=4
+\end{lstlisting}
+ã®ã‚ˆã†ã«è¡Œã†ã“ã¨ãŒã§ãる.
+\cs{iftdir} ã¯å°‘々é¢å€’ã§ã‚ã‚‹ãŒï¼Œ8ã§å‰²ã£ãŸä½™ã‚ŠãŒ3ã§ã‚ã‚‹ã‹å¦ã‹ã‚’判断ã™ã‚Œã°è‰¯ã„ã‹ã‚‰
+\begin{lstlisting}
+\ifnum\numexpr
+ \ltjgetparameter{direction}-(\ltjgetparameter{direction}/8)*8=3
+\end{lstlisting}
+ã¨ã™ã‚Œã°ã‚ˆã„.
+%</ja>
+
+%<*en>
+\subsection{Overridden box primitives}
+To cope with multiple directions, the following primitives are
+overridden by \LuaTeX-ja, using~\verb+\protected\def+.
+\begin{cslist}[style=standard]
+ \item[\cs{unhbox}<num>\textrm{, }\cs{unvbox}<num>\textrm{, }\cs{unhcopy}<num>\textrm{, }\cs{unvcopy}<num>]
+ \item[\cs{vadjust}\{<material>\}]
+ \item[\cs{insert}<number>\{<material>\}]
+ \item[\cs{lastbox}]
+ \item[\cs{raise}<dimen><box>\textrm{, }\cs{lower}<dimen><box>\textrm{\ etc., }\cs{vcenter}]
+ \item[\cs{vcenter}]
+\end{cslist}
+%</en>
+%<*ja>
+\subsection{プリミティブã®å†å®šç¾©}
+ç•°ãªã‚‹çµ„æ–¹å‘ã«å¯¾å¿œã™ã‚‹ãŸã‚ã«ï¼Œä»¥ä¸‹ã«æŒ™ã’るプリミティブã¯
+\LuaTeX-jaã«ã‚ˆã‚‹å‰å‡¦ç†ã‚‚ã—ãã¯å¾Œå‡¦ç†ãŒè¡Œã‚れるよã†ã«
+\ \verb+\protected\def+ ã«ã‚ˆã‚Šå†å®šç¾©ã—ã¦ã‚る.
+
+\begin{cslist}
+ \item[\cs{unhbox}<num>\textrm{, }\cs{unvbox}<num>\textrm{, }\cs{unhcopy}<num>\textrm{, }\cs{unvcopy}<num>]
+ ボックスã®çµ„æ–¹å‘ãŒç¾åœ¨ã®ãƒªã‚¹ãƒˆã¨ç•°ãªã‚‹å ´åˆã¯äº‹å‰ã«ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’出力ã™ã‚‹ï¼Ž
+ \pTeX ã¨ç•°ãªã‚Šï¼Œã‚¨ãƒ©ãƒ¼ã‚’無視ã—ã¦ç„¡ç†çŸ¢ç† \cs{unhbox}, \cs{unvbox} ã‚’
+ 続行ã•ã›ã‚‹ã“ã¨ã‚‚ã§ãã‚‹ãŒï¼Œãã®å ´åˆã®çµ„版çµæžœã¯ä¿è¨¼ã—ãªã„.
+ \item[\cs{vadjust}\{<material>\}] 一旦プリミティブ本æ¥ã®æŒ™å‹•ã‚’è¡Œã†ï¼Žãã®å¾Œï¼Œ<material>ã®çµ„æ–¹å‘ãŒ
+ 周囲ã®åž‚直リストã®çµ„æ–¹å‘ã¨ä¸€è‡´ã—ãªã„å ´åˆã«ã‚¨ãƒ©ãƒ¼ã‚’出力ã—,
+ 該当㮠\cs{vadjust} を無効ã«ã™ã‚‹ï¼Ž
+ \item[\cs{insert}<number>\{<material>\}]
+ 一旦プリミティブ本æ¥ã®æŒ™å‹•ã‚’è¡Œã„,ãã®å¾Œ<material>内ã®å„ボックス・罫線ã®ç›´å‰ã«çµ„æ–¹å‘を示
+ ã™direction whatsitを挿入ã™ã‚‹ï¼Ž
+ \item[\cs{lastbox}] ボックスã®ã€Œä¸­èº«ã€ã‚’ç¾åœ¨ã®çµ„æ–¹å‘ã«åˆã‚ã›ã‚‹ãŸã‚ã®ãƒŽãƒ¼ãƒ‰
+ (\textit{dir\_box}ã¨ã„ã†ï¼‰ã‚’å¿…è¦ãªã‚‰ã°é™¤åŽ»ã—,
+ æ­£ã—ã「中身ã€ã®ãƒœãƒƒã‚¯ã‚¹ãŒè¿”ã•ã‚Œã‚‹ã‚ˆã†ã«å‰å‡¦ç†ã‚’ã™ã‚‹ï¼Ž
+ \item[\cs{raise}<dimen><box>\textrm{, }\cs{lower}<dimen><box>\textrm{\ etc., }\cs{vcenter}]
+ 一方,ã“ã¡ã‚‰ã§ã¯å¿…è¦ã«å¿œã˜ã¦\textit{dir\_box}を作æˆã™ã‚‹å‰å‡¦ç†ã‚’追加ã—ã¦ã„る.
+\end{cslist}
+%</ja>
+
+%<en>\section{Font Metric and Japanese Font}
+%<ja>\section{フォントメトリックã¨å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆ}
+%<en>\subsection{\cs{jfont}}
+%<ja>\subsection{\cs{jfont} 命令}
+\label{ssec:jfont}
+
+%<*en>
+To load a font as a Japanese font (for horizontal direction), you must use the
+\cs{jfont} instead of~\cs{font}, while
+\cs{jfont} admits the same syntax used in~\cs{font}.
+\LuaTeX-ja automatically loads \Pkg{luaotfload} package,
+so TrueType/OpenType fonts with features can be used for Japanese fonts:
+%</en>
+%<*ja>
+フォントを(横組用)和文フォントã¨ã—ã¦èª­ã¿è¾¼ã‚€ãŸã‚ã«ã¯ï¼Œ\cs{jfont} ã‚’
+\ \cs{font} プリミティブã®ä»£ã‚ã‚Šã«ç”¨ã„る.
+\cs{jfont} ã®æ–‡æ³•ã¯ \cs{font} ã¨åŒã˜ã§ã‚る.
+\LuaTeX-jaã¯\Pkg{luaotfload}パッケージを自動的ã«èª­ã¿è¾¼ã‚€ã®ã§ï¼Œ
+TrueType/OpenTypeフォントã«featureを指定ã—ãŸã‚‚ã®ã‚’和文フォントã¨ã—ã¦ç”¨ã„ã‚‹
+ã“ã¨ãŒã§ãる:
+%</ja>
+\begin{LTXexample}[width=0.3\textwidth]
+\jfont\tradgt={file:KozMinPr6N-Regular.otf:script=latn;%
+ +trad;-kern;jfm=ujis} at 14pt
+\tradgt 当ï¼ä½“ï¼åŒ»ï¼åŒº
+\end{LTXexample}
+
+%<*en>
+Note that the defined control sequence
+(\cs{tradgt} in the example above) using \cs{jfont} is not a
+\textit{font\_def} token, but a macro.
+Hence the input like \verb+\fontname\tradgt+
+causes a error. We denote control sequences which are defined in
+\cs{jfont} by <jfont\_cs>.
+%</en>
+%<*ja>
+ãªãŠï¼Œ\cs{jfont} ã§å®šç¾©ã•ã‚ŒãŸåˆ¶å¾¡ç¶´ï¼ˆä¸Šã®ä¾‹ã ã¨ \cs{tradgt})
+ã¯\textit{font\_def}トークンã§ã¯ãªãマクロã§ã‚る.従ã£ã¦ï¼Œ\verb+\fontname\tradgt+ ã®ã‚ˆã†ãª
+入力ã¯ã‚¨ãƒ©ãƒ¼ã¨ãªã‚‹ï¼Žä»¥ä¸‹ã§ã¯ \cs{jfont} ã§å®šç¾©ã•ã‚ŒãŸ
+制御綴を<jfont\_cs>ã§è¡¨ã™ï¼Ž
+%</ja>
+
+\paragraph{JFM}
+%<*en>
+a JFM has measurements of characters and
+glues/kerns that are automatically inserted for Japanese
+typesetting. The structure of JFM will be described in the next
+subsection. At the calling of \cs{jfont}, you must specify
+which JFM will be used for this font by the following keys:
+%</en>
+%<*ja>
+JFMã¯æ–‡å­—ã¨å’Œæ–‡çµ„版ã§è‡ªå‹•çš„ã«æŒ¿å…¥ã•ã‚Œã‚‹
+グルーï¼ã‚«ãƒ¼ãƒ³ã®å¯¸æ³•æƒ…報をæŒã£ã¦ã„る.JFMã®æ§‹é€ ã¯æ¬¡ã®ç¯€ã§è¿°ã¹ã‚‹ï¼Ž
+\cs{jfont} 命令ã®å‘¼ã³å‡ºã—ã®éš›ã«ã¯ï¼Œã©ã®JFMを用ã„ã‚‹ã®ã‹ã‚’以下ã®ã‚­ãƒ¼ã§
+指定ã™ã‚‹å¿…è¦ãŒã‚る:
+%</ja>
+
+
+\begin{table}[t]
+%<en>\caption{Differences between horizontal JFMs shipped with \LuaTeX-ja}
+%<ja>\caption{\LuaTeX-ja ã«åŒæ¢±ã•ã‚Œã¦ã„る横組用JFMã®é•ã„}
+%<en>\medskip
+\label{tab-difjfm}
+\ltjsetparameter{jacharrange={+3}}
+\centering\small
+\def\r#1#2{%
+ \hbox{\Large\vrule
+ \parbox[b]{7\zw}{%
+ \addjfontfeatures{YokoFeatures={Opacity=0.5, Color=#2, JFM=#1}}\noindent
+ ◆◆◆◆◆◆◆
+ ã‚る日モモã¡ã‚ƒã‚“ãŒãŠä½¿ã„ã§è¿·å­ã«ãªã£ã¦æ³£ãã¾ã—ãŸï¼Ž
+ }\vrule}}
+\def\s#1#2{%
+ \Large
+ \parbox[b]{7\zw}{%
+ \addjfontfeatures{YokoFeatures={Opacity=0.5, Color=#2, JFM=#1}}\noindent
+ ã¡ã‚‡ã£ã¨ï¼ä½•
+ }}
+\def\t#1#2#3{\hbox to 0pt{\hss%
+ \setbox0=\hbox{\addjfontfeatures{YokoFeatures={JFM=#1}}\huge #3}%
+ \textcolor{#2}{\transparent{0.5}\vrule width 0.4pt height\ht0 depth\dp0}\kern-.2pt\copy0
+ \textcolor{#2}{\transparent{0.5}\kern-\wd0\vrule width\wd0height .2pt depth .2pt
+ \kern-\wd0\raise\ht0\hbox{\vrule width\wd0height .2pt depth .2pt}%
+ \kern-\wd0\lower\dp0\hbox{\vrule width\wd0height .2pt depth .2pt}%
+ \kern-.2pt\vrule width 0.4pt height\ht0 depth \dp0}\hss}}
+{\Large\tabcolsep0pt
+\begin{tabular}{m{8\zw}m{8\zw}m{8\zw}}
+\leavevmode\hbox to 0pt{\r{ujis}{blue}\hss}\r{jis}{black}&
+\leavevmode\hbox to 0pt{\r{jis}{black}\hss}\r{min}{red}&
+\leavevmode\hbox to 0pt{\r{ujis}{blue}\hss}\r{min}{red}\\
+\leavevmode\hbox to 0pt{\s{ujis}{blue}\hss}\s{jis}{black}&
+\leavevmode\hbox to 0pt{\s{jis}{black}\hss}\s{min}{red}&
+\leavevmode\hbox to 0pt{\s{ujis}{blue}\hss}\s{min}{red}\\
+\leavevmode\qquad\t{ujis}{blue}{æ¼¢}\t{jis}{black}{æ¼¢}\qquad
+ \t{ujis}{blue}{ã£}\t{jis}{black}{ã£}&
+\leavevmode\qquad\t{jis}{black}{æ¼¢}\t{min}{red}{æ¼¢}\qquad
+ \t{jis}{black}{ã£}\t{min}{red}{ã£}&
+\leavevmode\qquad\t{ujis}{blue}{æ¼¢}\t{min}{red}{æ¼¢}\qquad
+ \t{ujis}{blue}{ã£}\t{min}{red}{ã£}\\
+\end{tabular}\par}
+
+(\textcolor{blue}{Blue: \texttt{jfm-ujis.lua}},
+\textcolor{black}{Black: \texttt{jfm-jis.lua}},
+\textcolor{red}{Red: \texttt{jfm-min.lua}})
+\ltjsetparameter{jacharrange={-3}}
+\end{table}
+
+\begin{cslist}
+\item[jfm=<name>]
+%<*en>
+Specify the name of (horizontal) JFM.
+If specified JFM has not been loaded, \LuaTeX-ja search and load
+a file named \texttt{jfm-<name>.lua}.
+
+The following horizontal JFMs are shipped with \LuaTeX-ja:
+%</en>
+%<*ja>
+用ã„る(横組用)JFMã®åå‰ã‚’指定ã™ã‚‹ï¼Žã‚‚ã—以å‰ã«æŒ‡å®šã•ã‚ŒãŸJFMãŒèª­ã¿è¾¼ã¾ã‚Œã¦ã„ãªã‘ã‚Œã°ï¼Œ
+\texttt{jfm-<name>.lua}を読ã¿è¾¼ã‚€ï¼Žä»¥ä¸‹ã®æ¨ªçµ„用JFMãŒ\LuaTeX-jaã«ã¯åŒæ¢±ã•ã‚Œã¦ã„る:
+%</ja>
+\begin{description}
+%<*en>
+\item[\tt jfm-ujis.lua] A standard horizontal JFM in \LuaTeX-ja. This JFM is
+ based on \verb+upnmlminr-h.tfm+, a metric for UTF/OTF package that
+ is used in \upTeX. When you use the \Pkg{luatexja-otf} package, you should use this JFM.
+%</en>
+%<*ja>
+\item[\tt jfm-ujis.lua] \LuaTeX-jaã®æ¨™æº–JFMã§ã‚る.ã“ã®JFMã¯\upTeX ã§
+ 用ã„られるUTF/OTFパッケージ用ã®å’Œæ–‡ç”¨TFMã§ã‚ã‚‹ \verb+upnmlminr-h.tfm+ ã‚’
+ å…ƒã«ã—ã¦ã„る.\Pkg{luatexja-otf}パッケージを使ã†ã¨ãã¯ã“ã®JFMを指定ã™ã‚‹ã¹ãã§ã‚る.
+%</ja>
+%<*en>
+\item[\tt jfm-jis.lua] A counterpart for \verb+jis.tfm+, ``JIS font
+ metric'' which is widely used in \pTeX. A major difference between
+ \texttt{jfm-ujis.lua} and this \texttt{jfm-jis.lua} is that
+ most characters under \texttt{jfm-ujis.lua} are square-shaped,
+ while that under \texttt{jfm-jis.lua} are horizontal
+ rectangles.
+%</en>
+%<*ja>
+\item[\tt jfm-jis.lua] \pTeX ã§åºƒã用ã„られã¦ã„る「JISフォントメトリックã€
+ \verb+jis.tfm+ ã«ç›¸å½“ã™ã‚‹JFMã§ã‚る.\texttt{jfm-ujis.lua} ã¨ã“ã®
+ \texttt{jfm-jis.lua} ã®ä¸»ãªé•ã„ã¯ï¼Œ\texttt{jfm-ujis.lua} ã§ã¯ã»ã¨ã‚“ã©ã®æ–‡å­—ãŒ
+ 正方形状ã§ã‚ã‚‹ã®ã«å¯¾ã—,\texttt{jfm-jis.lua} ã§ã¯æ¨ªé•·ã®é•·æ–¹å½¢çŠ¶ã§ã‚ã‚‹ã“ã¨ã¨ï¼Œ
+ \texttt{jfm-ujis.lua} ã§ã¯ã€Œï¼Ÿã€ã€Œï¼ã€ã®ç›´å¾Œã«åŠè§’空白ãŒæŒ¿å…¥ã•ã‚Œã‚‹ã“ã¨ã§ã‚る.
+%</ja>
+%<*en>
+\item[\tt jfm-min.lua] A counterpart for \verb+min10.tfm+, which is one
+ of the default Japanese font metric shipped with \pTeX.
+%</en>
+%<*ja>
+\item[\tt jfm-min.lua] \pTeX ã«åŒæ¢±ã•ã‚Œã¦ã„るデフォルトã®å’Œæ–‡ç”¨TFM
+(\verb+min10.tfm+)ã«ç›¸å½“ã—,行末ã§æ–‡å­—ãŒæƒã†ã‚ˆã†ã«ã™ã‚‹ãŸã‚ã«ã€Œã£ã€ãªã©ä¸€éƒ¨ã®æ–‡å­—å¹…ãŒå¤‰ã‚ã£
+ ã¦ã„る.\verb+min10.tfm+ ã«ã¤ã„ã¦ã¯\cite{min10}ãŒè©³ã—ã„.
+%</ja>
+\end{description}
+%<*en>
+The difference among these three~JFMs is shown in \autoref{tab-difjfm}.
+%</en>
+%<*ja>
+ã“れら3ã¤ã®JFMã®é•ã„ã¯\autoref{tab-difjfm}ã«ç¤ºã—ãŸï¼Žè¡¨ä¸­ã®æ–‡ä¾‹ã®ä¸€éƒ¨ã«ã¯ï¼Œ
+\cite{min10}ã®å›³3,~4ã®ã‚‚ã®ã‚’用ã„ãŸï¼Ž
+%</ja>
+
+\begin{figure}
+\begin{LTXexample}[width=0.3\textwidth]
+\ltjsetparameter{differentjfm=both}
+\jfont\F=file:KozMinPr6N-Regular.otf:jfm=ujis
+\jfont\G=file:KozGoPr6N-Medium.otf:jfm=ujis
+\jfont\H=file:KozGoPr6N-Medium.otf:jfm=ujis;jfmvar=hoge
+\F ){\G ã€ã€‘}( % halfwidth space
+ ){\H 『ã€}( % fullwidth space
+
+ã»ã’,{\G 「ã»ã’ã€}(ã»ã’)\par
+ã»ã’,{\H 「ã»ã’ã€}(ã»ã’)% pTeX-like
+
+\ltjsetparameter{differentjfm=paverage}
+\end{LTXexample}
+\caption{Example of \texttt{jfmvar} key}
+\label{fig:jfmvar}
+\end{figure}
+
+%<*en>
+\item[jfmvar=<string>]
+Sometimes there is a need that \ldots.
+%</en>
+%<*ja>
+\item[jfmvar=<string>]
+標準ã§ã¯ï¼ŒJFMã¨ã‚µã‚¤ã‚ºãŒåŒã˜ã§ï¼Œ
+ 実フォントã ã‘ãŒç•°ãªã‚‹2ã¤ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã¯ã€ŒåŒºåˆ¥ã•ã‚Œãªã„ã€ï¼Žä¾‹ãˆã°
+\autoref{fig:jfmvar}ã«ãŠã„ã¦ï¼Œæœ€åˆã®ã€Œï¼‰ã€ã¨ã€Œã€ã€ã®å®Ÿãƒ•ã‚©ãƒ³ãƒˆã¯ç•°ãªã‚‹ãŒï¼Œ
+JFMもサイズもåŒã˜ãªã®ã§ï¼Œæ™®é€šã«ã€Œï¼‰ã€ã€ã¨å…¥åŠ›ã—ãŸæ™‚ã¨åŒã˜ã‚ˆã†ã«åŠè§’空ãã¨ãªã‚‹ï¼Ž
+
+ã—ã‹ã—,JFMã¨ã‚µã‚¤ã‚ºãŒåŒã˜ã§ã‚ã£ã¦ã‚‚,\texttt{jfmvar} キーã®ç•°ãªã‚‹
+2ã¤ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆï¼Œä¾‹ãˆã°\autoref{fig:jfmvar}ã§è¨€ã† \cs{F} 㨠\cs{H},
+ã¯ã€ŒåŒºåˆ¥ã•ã‚Œã‚‹ã€ï¼Žç•°ãªã‚‹å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã«ç•°ãªã‚‹ \texttt{jfmvar} キーを割り当ã¦ï¼Œ
+ã‹ã¤\Param{differentjfm}パラメータを \texttt{both} ã«è¨­å®šã™ã‚Œã°ï¼Œ
+\pTeX ã¨ä¼¼ãŸçŠ¶æ³ã§çµ„版ã•ã‚Œã‚‹ã“ã¨ã«ãªã‚‹ï¼Ž
+%</ja>
+\end{cslist}
+
+\begin{figure}
+\begin{LTXexample}[pos=t]
+\newcommand\test{\vrule ダイナミックダイクマ\vrule\\}
+\jfont\KMFW = KozMinPr6N-Regular:jfm=prop;-kern at 17pt
+\jfont\KMFK = KozMinPr6N-Regular:jfm=prop at 17pt % kern is activated
+\jfont\KMPW = KozMinPr6N-Regular:jfm=prop;script=dflt;+pwid;-kern at 17pt
+\jfont\KMPK = KozMinPr6N-Regular:jfm=prop;script=dflt;+pwid;+kern at 17pt
+\begin{multicols}{2}
+\ltjsetparameter{kanjiskip=0pt}
+{\KMFW\test \KMFK\test \KMPW\test \KMPK\test}
+
+\ltjsetparameter{kanjiskip=3pt}
+{\KMFW\test \KMFK\test \KMPW\test \KMPK\test}
+\end{multicols}
+\end{LTXexample}
+\caption{Kerning information and \Param{kanjiskip}}
+\label{fig:kern-jfm}
+\end{figure}
+
+%<en>\paragraph{Using kerning information in a font}
+%<ja>\paragraph{ペアカーニング情報ã®ä½¿ç”¨}
+\label{para-kern}
+%<*en>
+Some fonts have information for inter-glyph spacing.
+\LuaTeX-ja 20140324.0 or later treats kerning spaces like an italic correction;
+any glue and/or kern from the JFM and a kerning space can coexist.
+See \autoref{fig:kern-jfm} for detail.
+
+Note that in \cs{setmainjfont} etc.\ which are provided by \Pkg{luatexja-fontspec}
+package, kerning option is set \emph{off} (\texttt{Kerning=Off}) by default,
+because of the compatibility with previous versions of \LuaTeX-ja.
+%</en>
+%<*ja>
+ã„ãã¤ã‹ã®ãƒ•ã‚©ãƒ³ãƒˆã¯ã‚°ãƒªãƒ•é–“ã®ã‚¹ãƒšãƒ¼ã‚¹ã«ã¤ã„ã¦ã®æƒ…報をæŒã£ã¦ã„る.
+ã“ã®ã‚«ãƒ¼ãƒ‹ãƒ³ã‚°æƒ…å ±ã¯ä»¥å‰ã®\LuaTeX-ja ã¨ã¯ã‚ã¾ã‚Šç›¸æ€§ãŒè‰¯ããªã‹ã£ãŸãŒï¼Œ
+ãƒãƒ¼ã‚¸ãƒ§ãƒ³20140324.0以é™ã§ã¯ã‚«ãƒ¼ãƒ‹ãƒ³ã‚°ã«ã‚ˆã‚‹ç©ºç™½ã¯ã‚¤ã‚¿ãƒªãƒƒã‚¯è£œæ­£ã¨åŒæ§˜ã«æ‰±ã†ã“ã¨ã«ãªã£ã¦ã„る.
+ã¤ã¾ã‚Šï¼Œã‚«ãƒ¼ãƒ‹ãƒ³ã‚°ç”±æ¥ã®ç©ºç™½ã¨JFMç”±æ¥ã®ã‚°ãƒ«ãƒ¼ãƒ»ã‚«ãƒ¼ãƒ³ã¯åŒæ™‚ã«å…¥ã‚Šã†ã‚‹ï¼Ž
+\autoref{fig:kern-jfm}ã‚’å‚照.
+\begin{itemize}
+ \item \emph{\cs{jfont} や,
+NFSS2用ã®å‘½ä»¤ï¼ˆ\ref{ssec:chgfnt}節,\ref{ssec:nfsspat}節)ã«ãŠã‘る指定ã§ã¯
+カーニング情報ã¯æ¨™æº–ã§ä½¿ç”¨ã™ã‚‹}ã“ã¨ã«ãªã£ã¦ã„るよã†ã§ã‚る.
+言ã„æ›ãˆã‚Œã°ï¼Œã‚«ãƒ¼ãƒ‹ãƒ³ã‚°æƒ…報を使用ã—ãªã„設定ã«ã™ã‚‹ã«ã¯ï¼Œé¢å€’ã§ã‚‚
+\begin{lstlisting}
+\jfont\hoge=KozMinPr6N-Regular:jfm=ujis;-kern at 3.5mm
+\DeclareFontShape{JY3}{fuga}{m}{n} {<-> s*KozMinPr6N-Regular:jfm=ujis;-kern}{}
+\end{lstlisting}
+ã®ã‚ˆã†ã«ï¼Œ\texttt{-kern} ã¨ã„ã†æŒ‡å®šã‚’自分ã§è¿½åŠ ã—ãªã‘ã‚Œã°ã„ã‘ãªã„.
+ \item
+一方,\emph{\Pkg{luatexja-fontspec} ã®æä¾›ã™ã‚‹ \cs{setmainjfont}\
+ãªã©ã®å‘½ä»¤ã®æ¨™æº–設定ã§ã¯ã‚«ãƒ¼ãƒ‹ãƒ³ã‚°æƒ…å ±ã¯ä½¿ç”¨ã—ãªã„}(\texttt{Kerning=Off})
+ã“ã¨ã«ãªã£ã¦ã„る.ã“ã‚Œã¯ä»¥å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®\LuaTeX-jaã¨ã®äº’æ›æ€§ã®ãŸã‚ã§ã‚る.
+\end{itemize}
+%</ja>
+
+%<*ja>
+\paragraph{\texttt{extend}ã¨\texttt{slant}}
+OpenType機能ã¨è¦‹ã‹ã‘上åŒã˜ã‚ˆã†ãªå½¢å¼ã§æŒ‡å®šã§ãã‚‹ã‚‚ã®ã«ï¼Œ
+\begin{description}
+\item[\texttt{extend=}<extend>] 横方å‘ã«<extend>å€æ‹¡å¤§ã™ã‚‹ï¼Ž
+\item[\texttt{slant=}<slant>] <slant>ã«æŒ‡å®šã•ã‚ŒãŸå‰²åˆã ã‘傾ã‘る.
+\end{description}
+ã®2ã¤ãŒã‚る.
+\texttt{extend}ã‚„\texttt{slant}を指定ã—ãŸå ´åˆã¯ï¼Œãã‚Œã«å¿œã˜ãŸJFMを指定ã™ã¹ãã§ã‚ã‚‹%
+\footnote{\LuaTeX-jaã§ã¯ï¼Œã“れらã«å¯¾ã™ã‚‹JFMを特ã«æä¾›ã™ã‚‹ã“ã¨ã¯ã—ãªã„予定ã§ã‚る.}.
+例ãˆã°ï¼Œæ¬¡ã®ä¾‹ã§ã¯ç„¡ç†ã‚„り通常ã®JFMを使ã£ã¦ã„ã‚‹ãŸã‚ã«ï¼Œæ–‡å­—間隔やイタリック補正é‡ãŒ
+æ­£ã—ããªã„:
+%</ja>
+%<*en>
+\paragraph{\texttt{extend} and \texttt{slant}}
+The following setting can be specified as OpenType font features:
+\begin{cslist}[style=standard]
+\item[\texttt{extend=}<extend>] expand the font horizontally by <extend>.
+\item[\texttt{slant=}<slant>] slant the font.
+\end{cslist}
+Note that \LuaTeX-ja doesn't adjust JFMs by these \texttt{extend} and \texttt{slant}
+settings; you have to write new JFMs on purpose.
+For example, the following example uses the standard JFM \texttt{jfm-ujis.lua}, hence
+letter-spacing and the width of italic correction are not correct:
+%</en>
+\begin{LTXexample}[width=0.3\textwidth]
+\jfont\E=KozMinPr6N-Regular:extend=1.5;jfm=ujis;-kern
+\E ã‚ã„ã†ãˆãŠ
+
+\jfont\S=KozMinPr6N-Regular:slant=1;jfm=ujis;-kern
+\S ã‚ã„ã†\/ABC
+\end{LTXexample}
+
+%<*ja>
+\paragraph{\texttt{ltjksp} 指定}
+\label{pg:ltjksp}
+\LuaTeX-ja標準ã§ã¯ï¼Œ
+JFM中ã«ãŠã‘ã‚‹ \texttt{kanjiskip\_natural}, \texttt{kanjiskip\_stretch},\
+\texttt{kanjiskip\_shrink}キー(\pageref{pg:ksp_nat}ページ)ã®ä½¿ç”¨ã«ã‚ˆã£ã¦ï¼Œ
+「JFMç”±æ¥ã®ã‚°ãƒ«ãƒ¼ã®ä»–ã«ï¼Œ\Param{kanjiskip}ã®è‡ªç„¶é•·/伸ã³é‡/縮ã¿é‡ã®ä¸€éƒ¨ãŒ
+åŒã˜å ´æ‰€ã«æŒ¿å…¥ã•ã‚Œã‚‹ã€ã¨ã„ã†çŠ¶æ³ãŒèµ·ã“ã‚Šã†ã‚‹ï¼Ž
+ã“ã®æ©Ÿèƒ½ã‚’無効化ã—,ãƒãƒ¼ã‚¸ãƒ§ãƒ³20150922.0以å‰ã¨åŒã˜ã‚ˆã†ãªçµ„版を得るãŸã‚ã«ã¯
+ä»–ã®OpenType機能ã¨åŒã˜ã‚ˆã†ã«\ \texttt{-ltjksp}\ 指定を行ãˆã°è‰¯ã„.
+\begin{LTXexample}[width=16\zw]
+\leavevmode
+\ltjsetparameter{kanjiskip=0pt plus 3\zw}
+\vrule\hbox to 15\zw{ã‚「ã„ã€ã†ï¼ŒãˆãŠ}\vrule
+
+\jfont\G=file:KozMinPr6N-Regular.otf%
+ :jfm=ujis;-ltjksp at 9.2487pt
+\G\leavevmode%
+\vrule\hbox to 15\zw{ã‚「ã„ã€ã†ï¼ŒãˆãŠ}\vrule
+\end{LTXexample}
+ãªãŠï¼Œ
+\begin{lstlisting}
+ \jfont\G=file:KozMinPr6N-Regular.otf:jfm=ujis;-ltjksp;+ltjksp at 9.2487pt
+\end{lstlisting}
+ã®ã‚ˆã†ã« \texttt{+ltjksp} 指定を行ã£ãŸå ´åˆã¯ï¼Œ\texttt{kanjiskip\_natural} ãªã©
+3キーã¯å†ã³æœ‰åŠ¹åŒ–ã•ã‚Œã‚‹ï¼Ž\texttt{-ltjksp}, \texttt{+ltjksp} を複数回指定ã—ãŸå ´åˆã¯ï¼Œ
+最後ã«æŒ‡å®šã—ãŸã‚‚ã®ãŒæœ‰åŠ¹ã¨ãªã‚‹ï¼Ž
+%</ja>
+%<*en>
+\paragraph{\texttt{ltjksp}}
+\label{pg:ltjksp}
+\texttt{kanjiskip\_natural}, \texttt{kanjiskip\_stretch},\
+\texttt{kanjiskip\_shrink} keys (Page~\pageref{pg:ksp_nat}) makes tha
+\LuaTeX-ja inserts not only a glue which is specified by a JFM, and also
+the natural width/stretch part/shrink part of \Param{kanjiskip}.
+
+This functionality is disabled by \texttt{-ltjksp} specification.
+\begin{LTXexample}[width=16\zw]
+\leavevmode
+\ltjsetparameter{kanjiskip=0pt plus 3\zw}
+\vrule\hbox to 15\zw{ã‚「ã„ã€ã†ï¼ŒãˆãŠ}\vrule
+
+\jfont\G=file:KozMinPr6N-Regular.otf%
+ :jfm=ujis;-ltjksp at 9.2487pt
+\G\leavevmode%
+\vrule\hbox to 15\zw{ã‚「ã„ã€ã†ï¼ŒãˆãŠ}\vrule
+\end{LTXexample}
+%</en>
+
+
+
+
+%<en>\subsection{\cs{tfont}}
+%<ja>\subsection{\cs{tfont} 命令}
+\label{ssec:tfont}
+
+\begin{comment}
+ {\catcode`\<=12\catcode`\>=12
+\begin{table}[t]
+%<en>\caption{Differences between vertical JFMs shipped with \LuaTeX-ja}
+%<ja>\caption{\LuaTeX-ja ã«åŒæ¢±ã•ã‚Œã¦ã„る縦組用 JFM ã®é•ã„}
+%<en>\medskip
+\label{tab-difjfm-tate}
+\ltjsetparameter{jacharrange={+3}}
+\small
+\def\r#1#2{%
+ \hbox{\tate\Large\vrule
+ \parbox{7\zw}{%
+ \addjfontfeatures{TateFeatures={Opacity=0.5, Color=#2, JFM=#1}}\noindent
+ ◆◆◆◆◆◆◆
+ ã‚る日モモã¡ã‚ƒã‚“ãŒã€ŒãŠä½¿ã„ã€ã§è¿·å­ã«ãªã£ã¦æ³£ãã¾ã—ãŸã€‚
+ }\vrule}}
+\def\s#1#2{%
+ \hbox{\tate\Large
+ \parbox{7\zw}{%
+ \addjfontfeatures{TateFeatures={Opacity=0.5, Color=#2, JFM=#1}}\noindent
+ ã¡ã‚‡ã£ã¨ï¼ä½•
+ }}}
+\def\t#1#2#3{\hbox to 0pt{\hss%
+ \setbox0=\hbox{\addjfontfeatures{TateFeatures={JFM=#1}}\huge #3}%
+ \textcolor{#2}{\transparent{0.5}\vrule width 0.4pt height\ht0 depth\dp0}\kern-.2pt\copy0
+ \textcolor{#2}{\transparent{0.5}\kern-\wd0\vrule width\wd0height .2pt depth .2pt
+ \kern-\wd0\raise\ht0\hbox{\vrule width\wd0height .2pt depth .2pt}%
+ \kern-\wd0\lower\dp0\hbox{\vrule width\wd0height .2pt depth .2pt}%
+ \kern-.2pt\vrule width 0.4pt height\ht0 depth \dp0}\hss}}
+
+\begin{minipage}{.7\textwidth}
+\centering
+\leavevmode\hbox to 0pt{\r{ujisv}{blue}\hss}\r{tmin}{red}\quad
+\leavevmode\hbox to 0pt{\s{ujisv}{blue}\hss}\s{tmin}{red}\quad
+\raise4\zw\hbox{\tate\Large\t{ujisv}{black}{æ¼¢}\t{tmin}{red}{æ¼¢}\qquad
+ \t{ujisv}{black}{ã£}\t{tmin}{red}{ã£}}
+\end{minipage}%
+\begin{minipage}{.3\textwidth}
+\textcolor{blue}{Blue: \texttt{jfm-ujisv.lua}}\\
+\textcolor{red}{Red: \texttt{jfm-tmin.lua}}
+\end{minipage}
+\ltjsetparameter{jacharrange={-3}}
+\end{table}
+}
+\end{comment}
+
+%<*en>
+\cs{tfont} loads a font as a Japanese font for vertical direction.
+This command admits the same syntax used in \cs{font}~and~\cs{jfont}.
+A font defined by~\cs{tfont} differs the following points from that by~\cs{jfont}:
+\begin{itemize}
+ \item OpenType Feature~\texttt{vrt2}%
+ \footnote{If the font does not define \texttt{vrt2} feature,
+ use \texttt{vert} instead.} is automatically activated,
+ unless \texttt{vert}~and//or~\texttt{vrt2} are explicitly activated
+ or deactivated (as the second line in the example below).
+\begin{lstlisting}
+\tfont\S=file:KozMinPr6N-Regular.otf:jfm=ujisv % vrt2 is automatically activated
+\tfont\T=file:KozMinPr6N-Regular.otf:jfm=ujisv;-vert % vert and vrt2 are not activated
+\tfont\U=file:ipaexm.ttf:jfm=ujisv
+ % vert is automatically activated, since this font does not have vrt2
+\end{lstlisting}
+ \item Sometimes \texttt{vert} and/or \texttt{vrt2} are not activated
+ while one specified activation of these feature.
+ This is because the font does not define these features in current combination of
+ script~tag and language~system~identifier.
+
+ In this situation, \LuaTeX-ja performs all replacements which is defined in~\texttt{vert}
+ feature for \emph{some} scripts for \emph{some} languages.
+ \item Furthermore, a glyph is automatically rotated 90~degrees,
+ if it is not replaced by \texttt{vert} feature for \emph{any} script
+ for \emph{any} language, and if it is marked as `r''~or~``Tr'' in UAX~\#50.
+ \item One have to specify the name of vertical JFM in \texttt{jfm=<name>}.
+\LuaTeX-ja ships following vertical JFMs:
+\begin{description}
+\item[\tt jfm-ujisv.lua] A standard vertical JFM in \LuaTeX-ja. This JFM is
+ based on \verb+upnmlminr-v.tfm+, a metric for UTF/OTF package that
+ is used in \upTeX.
+\item[\tt jfm-tmin.lua] A counterpart for \verb+tmin10.tfm+, which is one
+ of the default Japanese font metric shipped with \pTeX.
+\end{description}
+\begin{figure}[!tb]
+\begin{LTXexample}[pos=b]
+\jfont\X=[KozMinPr6N-Regular.otf]:jfm=ujis
+\tfont\U=[KozMinPr6N-Regular.otf]:jfm=ujisv
+\tfont\V=[KozMinPr6N-Regular.otf]:jfm=ujisv;jpotf
+\def\TEST#1#2{\leavevmode\hbox{#1#2\string#2 “引用,ã¨å¥èª­ç‚¹ï¼Žâ€}}
+\ttfamily\centering\TEST\yoko\X \quad \TEST\tate\U \quad \TEST\tate\V
+\end{LTXexample}
+\caption{\texttt{jpotf} ``feature''}
+\label{fig:jpotf}
+\end{figure}
+
+ \item If \texttt{vert}~and/or~\texttt{vrt2} features are activated,
+ one can specify \texttt{jpotf} to additional substitutions.
+ By default, it substitutes ideographic comma/period for fullwidth comma/period,
+ and double prime quotation marks for double quotation marks
+ (See~\autoref{fig:jpotf}).
+\end{itemize}
+%</en>
+%<*ja>
+\cs{tfont} ã¯ãƒ•ã‚©ãƒ³ãƒˆã‚’縦組用ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã¨ã—ã¦èª­ã¿è¾¼ã‚€å‘½ä»¤ã§ã‚り,
+\cs{tfont} ã®æ–‡æ³•ã¯ \cs{jfont} ã¨åŒã˜ã§ã‚る.
+\cs{tfont} ã§å®šç¾©ã•ã‚ŒãŸç¸¦çµ„用和文フォントã¯ï¼Œ
+以下ã®ç‚¹ãŒ \cs{jfont} ã«ã‚ˆã‚‹æ¨ªçµ„用和文フォントã¨ã¯ç•°ãªã‚‹ï¼š
+\begin{itemize}
+ \item 明示的㫠\texttt{vert}, \texttt{vrt2}(ã®ã„ãšã‚Œã‹ï¼‰ã®
+ 有効・無効を指定ã—ãŸå ´åˆã‚’除ã,自動的㫠OpenType機能 \texttt{vrt2} ã®æœ‰åŠ¹åŒ–ãŒ
+ 指定ã•ã‚ŒãŸã‚‚ã®ã¨ã¿ãªã•ã‚Œã‚‹
+ \footnote{ã‚‚ã—フォントãŒ\texttt{vrt2}を定義ã—ã¦ã„ãªã‹ã£ãŸå ´åˆï¼Œä»£ã‚ã‚Šã«
+ \texttt{vert}を用ã„る.}.
+\begin{lstlisting}
+\tfont\S=file:KozMinPr6N-Regular.otf:jfm=ujisv % vrt2 is automatically activated
+\tfont\T=file:KozMinPr6N-Regular.otf:jfm=ujisv;-vert % vert and vrt2 are not activated
+\tfont\U=file:ipaexm.ttf:jfm=ujisv
+ % vert is automatically activated, since this font does not have vrt2
+\end{lstlisting}
+ \item \texttt{vert}, \texttt{vrt2} ã®å°‘ãªãã¨ã‚‚一ã¤ã®æœ‰åŠ¹ã‚’指定ã—ãŸå ´åˆã«ã‚‚é–¢ã‚らãšï¼Œ
+ script tagã¨language system identifierã®å€¤ã®çµ„ã¿åˆã‚ã›ã«ã‚ˆã£ã¦
+ 実際ã«ã¯æœ‰åŠ¹ã«ãªã‚‰ãªã‹ã£ãŸå ´åˆï¼Œ\LuaTeX-jaã¯
+ \begin{quote}
+ ã©ã‚Œã‹ã®script,~languageã§å®šç¾©ã•ã‚Œã¦ã„ã‚‹\texttt{vert}ã«ã‚ˆã‚‹
+ (å˜ä¸€ã‚°ãƒªãƒ•ã‹ã‚‰å˜ä¸€ã‚°ãƒªãƒ•ã¸ã®ï¼‰ç½®æ›ã‚’全部é©ç”¨ã™ã‚‹
+ \end{quote}
+ ã¨ã„ã†æŒ™å‹•ã‚’å–ã‚‹\footnote{%
+ 例ãˆã°ï¼ŒWindows~7ã«ä»˜å±žã—ã¦ã„ã‚‹SimHeiã§ã¯ï¼Œ\texttt{vert}ã¯ScriptãŒ\texttt{hani},
+ LanguageãŒ\texttt{CHN}ã¨ã„ã†çŠ¶æ³ã§ã®ã¿å®šç¾©ã•ã‚Œã¦ã„る.ã—ã‹ã—,\Pkg{luaotfload}ã§ã¯
+ ã“ã®script,~languageã®çµ„ã¿åˆã‚ã›ã‚’指定ã™ã‚‹ã“ã¨ã¯ã§ããªã„ã®ã§ï¼Œ
+ \Pkg{luaotfload}ãã®ã¾ã¾ã§ã¯\texttt{vert}ã‚’é©ç”¨ã•ã›ã‚‹ã“ã¨ã¯ã§ããªã„.
+ }.
+ \item ã•ã‚‰ã«ï¼Œã€Œã„ã‹ãªã‚‹script,~languageã§ã‚‚\texttt{vert}ã«ã‚ˆã‚Šç½®æ›ã•ã‚Œãªã„ã€ã‚°ãƒªãƒ•
+ ã®ã†ã¡ï¼ŒUAX~\#50ã§``r''ã‚‚ã—ãã¯``Tr''ã¨æŒ‡å®šã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã¯90度自動回転ã•ã›ã‚‹ï¼Ž
+ \item \ref{ssec:math}節ã§è¿°ã¹ã‚‹ï¼Œæ•°å¼ä¸­ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã«ã¯ç¸¦çµ„用和文フォントã¯æŒ‡å®šã§ããªã„.
+ \item \texttt{jfm=<name>}\ ã®éƒ¨åˆ†ã«ã¯ç¸¦çµ„用JFMを指定ã™ã‚‹ï¼Ž
+以下ã®ç¸¦çµ„用JFMãŒ\LuaTeX-jaã«ã¯åŒæ¢±ã•ã‚Œã¦ã„る.%ãŠã‚Šï¼Œé•ã„ã‚’\autoref{tab-difjfm-tate}ã«ç¤ºã—ãŸï¼Ž
+\begin{description}
+\item[\tt jfm-ujisv.lua] \LuaTeX-jaã®æ¨™æº–縦組用JFMã§ã‚る.ã“ã®JFMã¯\upTeX ã§
+ 用ã„られるUTF/OTFパッケージ用ã®å’Œæ–‡ç”¨TFMã§ã‚ã‚‹ \verb+upnmlminr-v.tfm+ ã‚’
+ å…ƒã«ã—ã¦ã„る.
+\item[\tt jfm-tmin.lua] \pTeX ã«åŒæ¢±ã•ã‚Œã¦ã„るデフォルトã®å’Œæ–‡ç”¨ç¸¦çµ„TFM
+ ã§ã‚ã‚‹ \verb+tmin10.tfm+ ã«ç›¸å½“ã—,\texttt{min10.tfm} ã¨åŒæ§˜ã«
+ 「ã£ã€ãªã©ä¸€éƒ¨ã®æ–‡å­—å¹…ãŒç‹­ã‚られã¦ã„る.
+\end{description}
+
+\begin{figure}[!tb]
+\begin{LTXexample}[pos=b]
+\jfont\X=[KozMinPr6N-Regular.otf]:jfm=ujis
+\tfont\U=[KozMinPr6N-Regular.otf]:jfm=ujisv
+\tfont\V=[KozMinPr6N-Regular.otf]:jfm=ujisv;jpotf
+\def\TEST#1#2{\leavevmode\hbox{#1#2\string#2 “引用,ã¨å¥èª­ç‚¹ï¼Žâ€}}
+\ttfamily\centering\TEST\yoko\X \quad \TEST\tate\U \quad \TEST\tate\V
+\end{LTXexample}
+\caption{\texttt{jpotf} ``feature''}
+\label{fig:jpotf}
+\end{figure}
+
+ \item \texttt{vert}, \texttt{vrt2}ã®å°‘ãªãã¨ã‚‚片方ãŒï¼ˆæ˜Žç¤ºçš„・自動的をå•ã‚ãšï¼‰
+ 有効ã«ãªã£ã¦ã„ãŸå ´åˆï¼Œã•ã‚‰ã«\texttt{jpotf}を指定ã™ã‚‹ã“ã¨ã§
+ 「通常ã§ã¯è¡Œã‚ãªã„縦組用字形ã¸ã®å¤‰æ›ã€ã‚’è¡Œã†ã“ã¨ãŒã§ãる.
+
+ 標準ã§ã¯ï¼Œã“ã®ã€Œå¤‰æ›ã€ã¯å…¨è§’ã®ã‚³ãƒ³ãƒžãƒ»ãƒ”リオドをå¥èª­ç‚¹ã«ï¼Œ
+ ã¾ãŸå…¨è§’ã®äºŒé‡å¼•ç”¨ç¬¦ã‚’ダブルミニュートã¸ç½®ãæ›ãˆã‚‹
+ \footnote{%
+ \texttt{jpotf}ã¨ã„ã†åå‰ã«ã—ãŸã®ã¯ï¼Œ
+ OTFパッケージã®ç¸¦çµ„用和文TFMã§ã»ã¼åŒã˜ã®å‡¦ç†ï¼ˆãã¡ã‚‰ã§ã¯ã•ã‚‰ã«ä¸€é‡å¼•ç”¨ç¬¦ã‚’
+ 「シングルミニュートã€ã«ç½®æ›ã™ã‚‹æ©Ÿèƒ½ã‚‚ã‚ã£ãŸï¼‰ã‚’è¡Œã£ã¦ã„ãŸã“ã¨ã«ç”±æ¥ã™ã‚‹ï¼Ž
+ }.\autoref{fig:jpotf}ã‚’å‚照.
+
+ ユーザå´ã§ã€Œå¤‰æ›ã€ã‚’カスタマイズã—ãŸã„å ´åˆï¼Œ
+ \verb+luatexja.jfont.register_vert_replace+ 関数ã«å¤‰æ›´å†…容を記ã—ãŸãƒ†ãƒ¼ãƒ–ルを渡ã™ï¼Ž
+ 例ãˆã°ç¸¦çµ„中ã§ã¯ã€Œã‚ã€ã‚’「ã„ã€ã«ç½®æ›ã—,ã¾ãŸã€Œï¼Œã€ã¯ï¼ˆã€Œã€ã€ã«ç½®æ›ã›ãšï¼‰ã€Œï¼Œã€ã®ã¾ã¾ã«
+ ã—ãŸã„å ´åˆã¯æ¬¡ã®ã‚ˆã†ã«ã™ã‚Œã°è‰¯ã„.
+\begin{lstlisting}
+\directlua{luatexja.jfont.register_vert_replace{
+ ['ã‚']='ã„', [',']=false,
+}}
+\end{lstlisting}
+ \verb+luatexja.jfont.register_vert_replace+ ã«ã‚ˆã‚‹å¤‰æ›´ã¯ã“ã®é–¢æ•°ã®\emph{実行後}ã«å®šç¾©ã•ã‚Œã‚‹
+ フォントã«ã¤ã„ã¦ã®ã¿æœ‰åŠ¹ã§ã‚る.
+
+\end{itemize}
+
+ãªãŠï¼Œ\pTeX ã§ã¯ï¼Œ\cs{font},~\cs{jfont},~\cs{tfont}ã®ã©ã‚Œã§ã‚‚欧文フォント・横組用和文フォン
+ト・縦組用和文フォントã®å®šç¾©ãŒå¯èƒ½ã§ã‚ã£ãŸãŒï¼Œ\LuaTeX-jaã§ã¯ãã†ã§ãªã„ã®ã§æ³¨æ„.
+%</ja>
+
+%<en>\subsection{Default Japanese fonts and JFMs}
+%<ja>\subsection{標準和文フォント・JFMã®å¤‰æ›´}
+\label{ssec:cfg}
+%<*en>
+If following commands are defined at loading \LuaTeX-ja package, these change
+default Japanese fonts and JFMs for them:
+%</en>
+%<*ja>
+\LuaTeX-jaãŒèª­ã¿è¾¼ã¾ã‚Œã‚‹å‰ã«ä»¥ä¸‹ã®å‘½ä»¤ãŒå®šç¾©ã•ã‚Œã¦ã„ãŸå ´åˆã¯ï¼Œ
+ãれらãŒæ¨™æº–和文フォントやãれらã«ç”¨ã„ã‚‹JFMã¨ã—ã¦ä½¿ã‚れる.
+%</ja>
+
+\begin{cslist}[style=standard]
+ \item[\cs{ltj@stdmcfont}]
+%<en>The default Japanese font for the mincho family.
+%<ja>明æœä½“ã¨ã—ã¦ç”¨ã„るフォント.
+ \item[\cs{ltj@stdgtfont}]
+%<en>The default Japanese font for the gothic family.
+%<ja>ゴシック体ã¨ã—ã¦ç”¨ã„るフォント.
+ \item[\cs{ltj@stdyokojfm}]
+%<en>The default JFM for horizontal direction.
+%<ja>標準ã§ç”¨ã„る横組用JFM.
+ \item[\cs{ltj@stdtatejfm}]
+%<en>The default JFM for vertical direction.
+%<ja>標準ã§ç”¨ã„る縦組用JFM.
+\end{cslist}
+
+%<*en>
+For example,
+\begin{lstlisting}
+\def\ltj@stdmcfont{IPAMincho}
+\def\ltj@stdgtfont{IPAGothic}
+\end{lstlisting}
+makes that IPA~Mincho and IPA~Gothic will be used as default Japanese fonts, instead of
+IPAex~Mincho and IPAex~Gothic.
+
+This feature is intended for classes which use special JFMs
+\footnote{This is because commands has \texttt{@} in their names.}.
+It is recommended to use \cs{luatexja-preset}~or~\cs{luatexja-fontspec} package
+to select standard fonts in ordinary \LaTeX\ sources.
+%</en>
+%<*ja>
+例ãˆã°
+\begin{lstlisting}
+\def\ltj@stdmcfont{IPAMincho}
+\def\ltj@stdgtfont{IPAGothic}
+\end{lstlisting}
+ã¨è¨˜è¿°ã—ã¦ãŠã‘ã°ï¼Œæ¨™æº–和文フォントãŒIPA明æœãƒ»IPAゴシックã¸ã¨å¤‰
+æ›´ã•ã‚Œã‚‹ï¼Ž
+
+ã“ã®æ©Ÿèƒ½ã¯ï¼Œç‰¹åˆ¥ã®JFMを用ã„るクラス
+\footnote{例ãˆã°é˜¿éƒ¨ç´€è¡Œæ°ã«ã‚ˆã‚‹jlreqãŒãã‚Œã«ã‚ãŸã‚‹ï¼Ž}%
+ãªã©ã§ã®ä½¿ç”¨ã‚’æ„図ã—ã¦ãŠã‚Šï¼Œå‘½ä»¤åã«\texttt{@}ãŒå«ã¾ã‚Œã‚‹ã“ã¨ã‹ã‚‰
+通常ã®\TeX/\LaTeX 文書ã§ã®ä½¿ç”¨ã¯æ„図ã—ã¦ã„ãªã„.
+通常ã®\LaTeX 文書ã§ã¯\Pkg{luatexja-preset}ã‚„\Pkg{luatexja-fontspec}ãªã©ã§
+使用フォントをé¸æŠžã™ã‚‹ã“ã¨ã‚’推奨ã™ã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+For compatibility with earlier versions,
+\LuaTeX-ja reads \texttt{luatexja.cfg} automatically if it is found by \LuaTeX.
+One should not overuse this \texttt{luatexja.cfg}; it will overwrite
+the definition of \cs{ltj@stdmcfont} and others.
+%</en>
+%<*ja>
+æ—§ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨ã®äº’æ›æ€§ã®ãŸã‚,
+\LuaTeX ã‹ã‚‰è¦‹ãˆã‚‹ä½ç½®ã«\texttt{luatexja.cfg}ãŒã‚ã‚Œã°ï¼Œ\LuaTeX-jaã¯ãれを読ã¿è¾¼ã‚€ï¼Ž
+ã—ã‹ã—,\texttt{luatexja.cfg}内ã§\cs{ltj@stdmcfont}ç­‰ãŒå®šç¾©ã•ã‚Œã¦ã„ãŸå ´åˆã¯ãã¡ã‚‰ãŒ
+優先ã•ã‚Œã‚‹ã®ã§ï¼Œã‚‚ã¯ã‚„\texttt{luatexja.cfg}ã¯ä½¿ã‚ãªã„ã»ã†ãŒè‰¯ã„ã ã‚ã†ï¼Ž
+%</ja>
+
+%<en>\subsection{Prefix \texttt{psft}}
+%<ja>\subsection{\texttt{psft}プリフィックス}
+\label{ssec:psft}
+%<*en>
+Besides ``\texttt{file:}''\ and ``\texttt{name:}''\ prefixes which
+are introduced in the \Pkg{luaotfload} package,
+\LuaTeX-ja adds ``\texttt{psft:}''\ prefix in \cs{jfont} (and~\cs{font}),
+to specify a ``name-only'' Japanese font which
+will not be embedded to PDF.
+Note that these non-embedded fonts under current \LuaTeX\ has Identity-H encoding,
+and this violates the standard ISO32000-1:2008~(\cite{pdfstd}).
+
+\emph{OpenType font features, such as ``{\tt +jp90}'',
+have no meaning in name-only fonts using ``{\tt psft:}''\ prefix,
+because we can't expect what fonts are actually used by the PDF reader.}
+Note that \texttt{extend}~and~\texttt{slant} settings (see~above) are supported
+with \texttt{psft} prefix, because they are only simple linear transformations.
+%</en>
+%<*ja>
+\Pkg{luaotfload}ã§ä½¿ç”¨å¯èƒ½ã«ãªã£ãŸ
+\texttt{file:}\ 㨠\texttt{name:}\ ã®ãƒ—リフィックスã«åŠ ãˆã¦ï¼Œ
+\cs{jfont}(㨠\cs{font} プリミティブ)ã§ã¯
+\texttt{psft:}プリフィックスを用ã„ã‚‹ã“ã¨ãŒã§ãる.
+ã“ã®ãƒ—リフィックスを用ã„ã‚‹ã“ã¨ã§ï¼ŒPDFã«ã¯åŸ‹ã‚è¾¼ã¾ã‚Œãªã„「åå‰ã ã‘ã®ã€
+和文フォントを指定ã™ã‚‹ã“ã¨ãŒã§ãる.
+ãªãŠï¼Œç¾è¡Œã®\LuaTeX ã§éžåŸ‹ã‚è¾¼ã¿ãƒ•ã‚©ãƒ³ãƒˆã‚’作æˆã™ã‚‹ã¨PDF内ã§ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ãŒ
+Identity-Hã¨ãªã‚Šï¼ŒPDFã®æ¨™æº–è¦æ ¼ISO32000-1:2008~(\cite{pdfstd})ã«éžæº–æ‹ ã«ãªã£ã¦ã—ã¾ã†
+ã®ã§æ³¨æ„ã—ã¦ã»ã—ã„.
+
+\emph{\texttt{psft} プリフィックスã®ä¸‹ã§ã¯
+\texttt{+jp90} ãªã©ã®OpenType機能ã®åŠ¹åŠ›ã¯ãªã„.
+éžåŸ‹è¾¼ãƒ•ã‚©ãƒ³ãƒˆã‚’PDFã«ä½¿ç”¨ã™ã‚‹ã¨ï¼Œå®Ÿéš›ã«ã©ã®ã‚ˆã†ãªãƒ•ã‚©ãƒ³ãƒˆãŒ
+表示ã«ç”¨ã„られるã‹äºˆæ¸¬ã§ããªã„ã‹ã‚‰ã§ã‚る.}\
+\texttt{extend} 㨠\texttt{slant} 指定ã¯å˜ãªã‚‹å¤‰å½¢ã®ãŸã‚
+\texttt{psft} プリフィックスã§ã‚‚使用å¯èƒ½ã§ã‚る.
+%</ja>
+
+%<en>\paragraph{\texttt{cid} key}
+%<ja>\paragraph{\texttt{cid}キー}
+\label{para-cid}
+
+%<*en>
+The default font defined by using \texttt{psft:} prefix is for Japanese typesetting;
+it is Adobe-Japan1-7 CID-keyed font.
+One can specify \texttt{cid} key to use other CID-keyed non-embedded fonts
+for Chinese or Korean typesetting.
+%</en>
+%<*ja>
+標準ã§\texttt{psft:}プリフィックスã§å®šç¾©ã•ã‚Œã‚‹ãƒ•ã‚©ãƒ³ãƒˆã¯æ—¥æœ¬èªžç”¨ã®ã‚‚ã®ã§
+ã‚り,Adobe-Japan1-7ã®CIDã«å¯¾å¿œã—ãŸã‚‚ã®ã¨ãªã‚‹ï¼Žã—ã‹ã—,\LuaTeX-jaã¯ä¸­å›½èªž
+ã®çµ„版ã«ã‚‚å¨åŠ›ã‚’発æ®ã™ã‚‹ã“ã¨ãŒåˆ†ã‹ã‚Šï¼Œæ—¥æœ¬èªžãƒ•ã‚©ãƒ³ãƒˆã§ãªã„éžåŸ‹è¾¼ãƒ•ã‚©ãƒ³ãƒˆ
+ã®å¯¾å¿œã‚‚å¿…è¦ã¨ãªã£ãŸï¼Žãã®ãŸã‚ã«è¿½åŠ ã•ã‚ŒãŸã®ãŒ\texttt{cid}キーã§ã‚る.
+
+\texttt{cid}キーã«å€¤ã‚’指定ã™ã‚‹ã¨ï¼Œãã®CIDã‚’æŒã£ãŸéžåŸ‹è¾¼ãƒ•ã‚©ãƒ³ãƒˆã‚’定義ã™ã‚‹ã“ã¨ãŒã§ãる:
+%</ja>
+\begin{lstlisting}[numbers=left]
+\jfont\testJ={psft:Ryumin-Light:cid=Adobe-Japan1-7;jfm=jis} % Japanese
+\jfont\testD={psft:Ryumin-Light:jfm=jis} % default: Adobe-Japan1-7
+\jfont\testC={psft:AdobeMingStd-Light:cid=Adobe-CNS1-7;jfm=jis}% Traditional Chinese
+\jfont\testG={psft:SimSun:cid=Adobe-GB1-5;jfm=jis} % Simplified Chinese
+\jfont\testK={psft:Batang:cid=Adobe-Korea1-2;jfm=jis} % Korean
+\jfont\testKR={psft:SourceHanSerifAKR9:cid=Adobe-KR-9;jfm=jis} % Korean
+\end{lstlisting}
+%<*en>
+Note that the code above specifies \texttt{jfm-jis.lua}, which is for Japanese fonts,
+as JFM for Chinese and Korean fonts.
+%</en>
+%<*ja>
+上ã®ã‚³ãƒ¼ãƒ‰ã§ã¯ä¸­å›½èªžãƒ»éŸ“国語用フォントã«å¯¾ã—ã¦ã‚‚JFMã«
+日本語用ã®\texttt{jfm-jis.lua}を指定ã—ã¦ã„ã‚‹ã®ã§æ³¨æ„ã•ã‚ŒãŸã„.
+%</ja>
+
+%<*en>
+At present, \LuaTeX-ja supports only 5 values written in the sample code above.
+Specifying other values, e.g.,
+%</en>
+%<*ja>
+今ã®ã¨ã“ã‚,\LuaTeX-jaã¯ä¸Šã®ã‚µãƒ³ãƒ—ルコード中ã«æ›¸ã„ãŸ5ã¤ã®å€¤ã—ã‹ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„.
+%</ja>
+\begin{lstlisting}
+\jfont\test={psft:Ryumin-Light:cid=Adobe-Japan2;jfm=jis}
+\end{lstlisting}
+%<*en>
+produces the following error:
+%</en>
+%<*ja>
+ã®ã‚ˆã†ã«ãれら以外ã®å€¤ã‚’指定ã™ã‚‹ã¨ï¼Œã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã™ã‚‹ï¼š
+%</ja>
+\begin{lstlisting}[numbers=left]
+! Package luatexja Error: bad cid key `Adobe-Japan2'.
+
+See the luatexja package documentation for explanation.
+Type H <return> for immediate help.
+<to be read again>
+ \par
+l.78
+
+? h
+I couldn't find any non-embedded font information for the CID
+`Adobe-Japan2'. For now, I'll use `Adobe-Japan1-6'.
+Please contact the LuaTeX-ja project team.
+?
+\end{lstlisting}
+
+%<en>\subsection{Structure of a JFM file}
+%<ja>\subsection{JFMファイルã®æ§‹é€ }
+\label{ssec:jfm-str}
+%<en>A JFM file is a Lua script which has only one function call:
+%<ja>JFMファイルã¯ãŸã ä¸€ã¤ã®é–¢æ•°å‘¼ã³å‡ºã—ã‚’å«ã‚€Luaスクリプトã§ã‚る:
+\begin{lstlisting}
+luatexja.jfont.define_jfm { ... }
+\end{lstlisting}
+%<*en>
+Real data are stored in the table which indicated above by
+\verb+{ ... }+. So, the rest of this subsection are devoted to describe the
+structure of this table. Note that all lengths in a JFM file are
+floating-point numbers in design-size unit.
+%</en>
+%<*ja>
+実際ã®ãƒ‡ãƒ¼ã‚¿ã¯ä¸Šã§ \verb+{ ... }+ ã§ç¤ºã•ã‚ŒãŸãƒ†ãƒ¼ãƒ–ルã®ä¸­ã«æ ¼ç´ã•ã‚Œã¦ã„る.
+以下ã§ã¯ã“ã®ãƒ†ãƒ¼ãƒ–ルã®æ§‹é€ ã«ã¤ã„ã¦è¨˜ã™ï¼Ž
+ãªãŠï¼ŒJFMファイル中ã®é•·ã•ã¯å…¨ã¦design-sizeã‚’å˜ä½ã¨ã™ã‚‹æµ®å‹•å°æ•°ç‚¹æ•°ã§ã‚ã‚‹ã“ã¨ã«
+注æ„ã™ã‚‹ï¼Ž
+%</ja>
+
+\begin{cslist}[style=standard]
+
+\item[version=<version>]
+%<en>(optional, default value is~1)
+%<ja>(任æ„,既定値ã¯1)
+
+%<*en>
+The version JFM. Currently 1,~2,~and,~3 are supported
+%</en>
+%<*ja>
+JFMã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼Ž1,~2,~3ãŒã‚µãƒãƒ¼ãƒˆã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+\item[dir=<direction>]
+%<en>(required)
+%<ja>(必須)
+
+%<*en>
+The direction of JFM. \texttt{'yoko'}~(horizontal)
+or \texttt{'tate'}~(vertical) are supported.
+%</en>
+%<*ja>
+JFMã®æ›¸å­—æ–¹å‘.\texttt{'yoko'}(横組)㨠\texttt{'tate'}(縦組)ãŒã‚µãƒãƒ¼ãƒˆã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+\item[zw=<length>]
+%<en>(required)
+%<ja>(必須)
+
+%<en>The amount of the length of the ``full-width''.
+%<*ja>
+「全角幅ã€ã®é•·ã•ï¼Žã“ã®é‡ãŒ \cs{zw} ã®é•·ã•ã¨ãªã‚‹ï¼Ž\pTeX ã§ã¯
+「全角幅ã€\texttt{1zw} ã¯ã€Œæ–‡å­—クラス0ã®æ–‡å­—ã€ã®å¹…ã¨æ±ºã‚られã¦ã„ãŸãŒï¼Œ
+\LuaTeX-jaã§ã¯ã“ã“ã§æŒ‡å®šã™ã‚‹ï¼Ž
+%</ja>
+
+\item[zh=<length>]
+%<en>(required)
+%<ja>(必須)
+
+%<en>The amount of the ``full-height'' (height + depth).
+%<*ja>
+「全角高ã•ã€(height + depth)ã®é•·ã•ï¼Žé€šå¸¸ã¯å…¨è§’å¹…ã¨åŒã˜é•·ã•ã«ãªã‚‹ã ã‚ã†ï¼Ž
+\pTeX ã§ã¯ 「全角高ã•ã€\texttt{1zh} ã¯ã€Œæ–‡å­—クラス0ã®æ–‡å­—ã€ã®é«˜ã•ã¨æ·±ã•ã®å’Œã¨æ±ºã‚られã¦ã„ãŸãŒï¼Œ
+\LuaTeX-jaã§ã¯ã“ã“ã§æŒ‡å®šã™ã‚‹ï¼Ž
+%</ja>
+
+\item[kanjiskip=\{<natural>, <stretch>, <shrink>\}]
+%<en>(optional)
+%<ja>(任æ„)
+
+%<*en>
+This field specifies the ``ideal'' amount of \Param{kanjiskip}. As noted
+ in Subsection~\ref{subs-kskip}, if the parameter
+ \Param{kanjiskip} is \cs{maxdimen}, the value specified
+ in this field is actually used (if this field is not specified in
+ JFM, it is regarded as 0\,pt). Note that <stretch> and <shrink>
+ fields are in design-size unit too.
+%</en>
+%<*ja>
+ç†æƒ³çš„ãª\Param{kanjiskip}ã®é‡ã‚’指定ã™ã‚‹ï¼Ž\ref{subs-kskip}節ã§è¿°ã¹ãŸã‚ˆã†ã«ï¼Œ
+ã‚‚ã—\Param{kanjiskip}㌠\cs{maxdimen} ã®å€¤ãªã‚‰ã°ï¼Œã“ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã§æŒ‡å®šã•ã‚ŒãŸ
+値ãŒå®Ÿéš›ã«ã¯ç”¨ã„られる(指定ãªã—ã¯0\,ptã¨ã—ã¦æ‰±ã‚れる).<stretch>ã¨<shrink>ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚‚design-size
+ãŒå˜ä½ã§ã‚ã‚‹ã“ã¨ã«æ³¨æ„ã›ã‚ˆï¼Ž
+%</ja>
+
+\item[xkanjiskip=\{<natural>, <stretch>, <shrink>\}]
+%<en>(optional)
+%<ja>(任æ„)
+
+%<*en>
+Like the \texttt{kanjiskip} field, this field specifies the ``ideal''
+ amount of \Param{xkanjiskip}.
+%</en>
+%<*ja>
+\texttt{kanjiskip}フィールドã¨åŒæ§˜ã«ï¼Œ\Param{xkanjiskip}ã®ç†æƒ³çš„ãªé‡ã‚’
+指定ã™ã‚‹ï¼Ž
+%</ja>
+\end{cslist}
+
+%<*en>
+\paragraph{Character classes}
+Besides from above fields, a JFM file have several sub-tables those
+indices are natural numbers. The table indexed by~$i\in\omega$ stores
+information of \emph{character class}~$i$. At least, the character class~0 is
+always present, so each JFM file must have a sub-table whose index is
+\texttt{[0]}. Each sub-table (its numerical index is denoted by $i$) has
+the following fields:
+%</en>
+%<*ja>
+\paragraph{文字クラス}
+上記ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«åŠ ãˆã¦ï¼ŒJFMファイルã¯ãã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒè‡ªç„¶æ•°ã§ã‚ã‚‹ã„ãã¤ã‹ã®
+サブテーブルをæŒã¤ï¼Žã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒ$i\in\omega$ã§ã‚るテーブルã¯\emph{文字クラス}$i$ã®
+情報を格ç´ã™ã‚‹ï¼Žå°‘ãªãã¨ã‚‚,文字クラス0ã¯å¸¸ã«å­˜åœ¨ã™ã‚‹ã®ã§ï¼ŒJFMファイルã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹
+ãŒ\texttt{[0]}ã®ã‚µãƒ–テーブルをæŒãŸãªã‘ã‚Œã°ãªã‚‰ãªã„.ãã‚Œãžã‚Œã®ã‚µãƒ–テーブル
+(ãã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’$i$ã§è¡¨ã‚ã™ï¼‰ã¯ä»¥ä¸‹ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’æŒã¤ï¼š
+%</ja>
+
+\begin{cslist}[style=standard]
+\item[chars=\{<character>, ...\}]
+%<en>(required except character class~0)
+%<ja>(文字クラス0を除ã„ã¦å¿…須)
+
+%<*en>
+This field is a list of characters which are in this character
+ type~$i$. This field is optional if $i=0$, since all
+ \textbf{JAchar} which do not belong any character classes other
+ than 0 are in the character class 0
+ (hence, the character class~0 contains most of
+ \textbf{JAchar}s). In the list, character(s) can be specified in the following form:
+\begin{itemize}
+\item a Unicode code point
+\item the character itself (as a Lua string, like \hbox{\ltjsetparameter{autoxspacing=false}\verb+'ã‚'+})
+\item a string like \hbox{\ltjsetparameter{autoxspacing=false}\verb+'ã‚*'+} (the character followed by an asterisk)
+\item several ``imaginary'' characters (We will describe these later.)
+\end{itemize}
+%</en>
+%<*ja>
+ã“ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã¯æ–‡å­—クラス$i$ã«å±žã™ã‚‹æ–‡å­—ã®ãƒªã‚¹ãƒˆã§ã‚る.ã“ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã¯$i=0$ã®
+å ´åˆã«ã¯ä»»æ„ã§ã‚る(文字クラス0ã«ã¯ï¼Œ0以外ã®æ–‡å­—クラスã«å±žã™ã‚‹ã‚‚ã®ã‚’
+除ã„ãŸå…¨ã¦ã®\textbf{JAchar}ãŒå±žã™ã‚‹ã‹ã‚‰ï¼‰ï¼Žã“ã®ãƒªã‚¹ãƒˆä¸­ã§æ–‡å­—を指定ã™ã‚‹ã«ã¯ï¼Œä»¥ä¸‹ã®æ–¹æ³•ãŒã‚る:
+\begin{itemize}
+\item Unicode ã«ãŠã‘るコード番å·
+\item 「\hbox{\ltjsetparameter{autoxspacing=false}\verb+'ã‚'+}ã€ã®ã‚ˆã†ãªï¼Œæ–‡å­—ãれ自体
+\item 「\hbox{\ltjsetparameter{autoxspacing=false}\verb+'ã‚*'+}ã€ã®ã‚ˆã†ãªï¼Œæ–‡å­—ãれ自体ã®å¾Œã«ã‚¢ã‚¹ã‚¿ãƒªã‚¹ã‚¯ã‚’ã¤ã‘ãŸã‚‚ã®
+\item ã„ãã¤ã‹ã®ã€Œä»®æƒ³çš„ãªæ–‡å­—ã€ï¼ˆå¾Œã«èª¬æ˜Žã™ã‚‹ï¼‰
+\end{itemize}
+%</ja>
+
+\item[width=<length>, height=<length>, depth=<length>, italic=<length>]
+%<en>(required)
+%<ja>(必須)
+
+%<*en>
+\begin{table}[t]
+ \centering
+\begin{tabular}{llr}
+\toprule
+Direction of JFM&\textbf{\texttt{'yoko'} (horizontal)}&\multicolumn{1}{l}{\textbf{\texttt{'tate'} (vertical)}}\\
+\midrule
+\texttt{width} field&\multicolumn{2}{c}{the width of the ``real'' glyph}\\
+\texttt{height} field&the height of the ``real'' glyph&0.0\\
+\texttt{depth} field&the depth of the ``real'' glyph&0.0\\
+\midrule
+\texttt{italic} field&\multicolumn{2}{c}{0.0}\\
+\bottomrule
+\end{tabular}
+\caption{Default values of \texttt{width} field and other fields}
+\label{tab-wid}
+\end{table}
+Specify the width of characters in character class~$i$, the height, the depth and
+the amount of italic correction. All characters in character class~$i$ are regarded that its width, height, and depth are
+as values of these fields. The default values are shown in \autoref{tab-wid}.
+%</en>
+%<*ja>
+\begin{table}[t]
+ \centering
+\begin{tabular}{llr}
+\toprule
+JFM書字方å‘&\emph{\texttt{'yoko'}(横組)}&\multicolumn{1}{l}{\emph{\texttt{'tate'}(縦組)}}\\
+\midrule
+\texttt{width}&\multicolumn{2}{c}{「実際ã®ã‚°ãƒªãƒ•ã€ã®å¹…}\\
+\texttt{height}&「実際ã®ã‚°ãƒªãƒ•ã€ã®é«˜ã•&0.0\\
+\texttt{depth}&「実際ã®ã‚°ãƒªãƒ•ã€ã®æ·±ã•&0.0\\
+\midrule
+\texttt{italic}&\multicolumn{2}{c}{0.0}\\
+\bottomrule
+\end{tabular}
+\caption{\texttt{width} フィールド等ã®æ¨™æº–値}
+\label{tab-wid}
+\end{table}
+文字クラス$i$ã«å±žã™ã‚‹æ–‡å­—ã®å¹…,高ã•ï¼Œæ·±ã•ï¼Œã‚¤ã‚¿ãƒªãƒƒã‚¯è£œæ­£ã®é‡ã‚’指定ã™ã‚‹ï¼Ž
+文字クラス$i$ã«å±žã™ã‚‹å…¨ã¦ã®æ–‡å­—ã¯ï¼Œãã®å¹…,高ã•ï¼Œæ·±ã•ãŒã“ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã§æŒ‡å®šã—ãŸ
+値ã§ã‚ã‚‹ã‚‚ã®ã¨ã—ã¦æ‰±ã‚れる.çœç•¥æ™‚や,数ã§ãªã„値を指定ã—ãŸæ™‚ã«ã¯è¡¨\nobreak\ref{tab-wid}ã«
+ 示ã•ã‚Œã¦ã„る値を用ã„る.例ãˆã°ï¼Œæ¨ªçµ„用JFM㧠\texttt{width} フィールドã«ã¯æ•°å€¤ä»¥å¤–ã®å€¤ã‚’指
+ 定ã—ãŸå ´åˆï¼Œæ–‡å­—ã®å¹…ã¯ãã®ã€Œå®Ÿéš›ã®ã€ã‚°ãƒªãƒ•ã®å¹…ã¨ãªã‚‹ï¼ŽOpenTypeã® \texttt{prop} featureã¨ä½µç”¨
+ ã™ã‚Œã°ï¼Œã“ã‚Œã«ã‚ˆã£ã¦ãƒ—ロãƒãƒ¼ã‚·ãƒ§ãƒŠãƒ«çµ„ã‚’è¡Œã†ã“ã¨ãŒã§ãる.
+%</ja>
+
+\item[left=<length>, down=<length>, align=<align>]\
+
+%<*en>
+These fields are for adjusting the position of the ``real'' glyph. Legal
+ values of \texttt{align} field are \texttt{'left'},
+ \texttt{'middle'}, and \texttt{'right'}. If one of these
+ 3~fields are omitted, \texttt{left} and \texttt{down} are
+ treated as~0, and \texttt{align} field is treated as
+ \texttt{'left'}.
+The effects of these 3~fields are indicated in
+\autoref{fig:pos}~and~\autoref{fig:pos-tate}.
+%</en>
+%<*ja>
+ã“れらã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã¯å®Ÿéš›ã®ã‚°ãƒªãƒ•ã®ä½ç½®ã‚’調整ã™ã‚‹ãŸã‚ã«ã‚る.
+\texttt{align} フィールドã«æŒ‡å®šã§ãる値㯠\texttt{'left'}, \texttt{'middle'},
+\texttt{'right'} ã®ã„ãšã‚Œã‹ã§ã‚る.もã—ã“れら3ã¤ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã®ã†ã¡ã®1ã¤ãŒçœã‹ã‚ŒãŸ
+å ´åˆï¼Œ\texttt{left} 㨠\texttt{down} ã¯0,\texttt{align} フィールドã¯
+\ \texttt{'left'} ã§ã‚ã‚‹ã‚‚ã®ã¨ã—ã¦æ‰±ã‚れる.
+ã“れら3ã¤ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã®æ„味ã«ã¤ã„ã¦ã¯\autoref{fig:pos}(横組用和文フォント),
+\autoref{fig:pos-tate}(縦組用和文フォント)ã§èª¬æ˜Žã™ã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+In most cases, \texttt{left} and \texttt{down} fields are~0, while
+it is not uncommon that the \texttt{align} field is \texttt{'middle'} or \texttt{'right'}.
+For example, setting the \texttt{align} field to \texttt{'right'} is practically needed
+when the current character class is the class for opening delimiters'.
+%</en>
+%<*ja>
+多ãã®å ´åˆï¼Œ\texttt{left}ã¨\texttt{down}ã¯0ã§ã‚る一方,
+\texttt{align}フィールドãŒ\texttt{'middle'}ã‚„\texttt{'right'}ã§ã‚ã‚‹ã“ã¨ã¯
+çã—ã„ã“ã¨ã§ã¯ãªã„.
+例ãˆã°ï¼Œ\texttt{align}フィールドを\texttt{'right'}ã«æŒ‡å®šã™ã‚‹ã“ã¨ã¯ï¼Œ
+文字クラスãŒé–‹ã括弧類ã§ã‚ã‚‹ã¨ãã«å®Ÿéš›å¿…è¦ã§ã‚る.
+%</ja>
+
+\begin{figure}[!tb]
+\begin{minipage}{0.4\textwidth}%
+\begin{center}\unitlength=10pt\small
+\begin{picture}(15,12)(-1,-4)
+\color{b_gray}% jfm
+\put(0,0){\vrule width 12\unitlength height 8\unitlength depth 3\unitlength}
+
+\color{b_pink}% step1
+\put(-1,-1.5){\vrule width 6\unitlength height 7\unitlength depth 2.5\unitlength}
+
+\color{red}% real glyph
+\thicklines
+\put(-1,-1.5){\vector(0,1){7}\vector(0,-1){2.5}\vector(1,0){6}}
+\put(5,-1.5){\line(0,1){7}\line(0,-1){2.5}}
+\put(-1,5.5){\line(1,0){6}}
+\put(-1,-4){\line(1,0){6}}
+
+\color{b_green}% real glyph
+\put(3,0){\vrule width 6\unitlength height 7\unitlength depth 2.5\unitlength}
+
+\color{black}% jfm
+\thicklines
+\put(0,0){\vector(0,1){8}\line(0,-1){3}\vector(1,0){12}}
+\put(12,0){\line(0,1){8}\vector(0,-1){3}}
+\put(0,8){\line(1,0){12}}
+\put(0,-3){\line(1,0){12}}
+\put(0.2,4){\makebox(0,0)[l]{\texttt{height}}}
+\put(12.2,-1.5){\makebox(0,0)[l]{\texttt{depth}}}
+\put(6,0.2){\makebox(0,0)[b]{\texttt{width}}}
+
+\color{green}% step1
+\thicklines
+\put(3,0){\vector(0,1){7}\vector(0,-1){2.5}\vector(1,0){6}}
+\put(9,0){\line(0,1){7}\line(0,-1){2.5}}
+\put(3,7){\line(1,0){6}}
+\put(3,-2.5){\line(1,0){6}}
+\newsavebox{\eqdist}
+\savebox{\eqdist}(0,0)[b]{%
+ \thinlines
+ \put(-0.08,0.2){\line(0,-1){0.4}}%
+ \put(0.08,0.2){\line(0,-1){0.4}}}
+\put(1.5,0){\usebox{\eqdist}}
+\put(10.5,0){\usebox{\eqdist}}
+
+\color{blue}% shifted
+\thicklines
+\put(3,-1.5){\vector(-1,0){4}}
+\put(1,-1.7){\makebox(0,0)[t]{\texttt{left}}}
+\put(3,0){\vector(0,-1){1.5}}
+\put(3.2,-0.75){\makebox(0,0)[l]{\texttt{down}}}
+\end{picture}
+\end{center}
+\end{minipage}%
+\begin{minipage}{0.6\textwidth}%
+%<*en>
+Consider a Japanese character node which belongs to
+a character class whose the \texttt{align}
+field is \texttt{'middle'}.
+%</en>
+%<*ja>
+\texttt{align}フィールドã®å€¤ãŒ \texttt{'middle'} ã§ã‚るよã†ãªæ–‡å­—クラスã«å±žã™ã‚‹
+和文文字ノードを考ãˆã‚ˆã†ï¼Ž
+%</ja>
+\begin{itemize}
+\item
+%<*en>
+The black rectangle is the imaginary body of the node.
+Its width, height, and depth are specified by JFM.
+%</en>
+%<*ja>
+黒色ã®é•·æ–¹å½¢ã¯ãƒŽãƒ¼ãƒ‰ã®æž ã§ã‚り,
+ãã®å¹…,高ã•ï¼Œæ·±ã•ã¯JFMã«ã‚ˆã£ã¦æŒ‡å®šã•ã‚Œã¦ã„る.
+%</ja>
+\item
+%<*en>
+Since the \texttt{align} field is \texttt{'middle'},
+the ``real'' glyph is centered horizontally (the green rectangle) first.
+%</en>
+%<*ja>
+\texttt{align}フィールド㯠\texttt{'middle'} ãªã®ã§ï¼Œ
+実際ã®ã‚°ãƒªãƒ•ã®ä½ç½®ã¯ã¾ãšæ°´å¹³æ–¹å‘ã«ä¸­å¤®æƒãˆã—ãŸã‚‚ã®ã¨ãªã‚‹ï¼ˆç·‘色ã®é•·æ–¹å½¢ï¼‰ï¼Ž
+%</ja>
+\item
+%<*en>
+Furthermore, the glyph is shifted according to values of fields
+ \texttt{left} and \texttt{down}. The ultimate position of the real
+ glyph is indicated by the red rectangle.
+%</en>
+%<*ja>
+ã•ã‚‰ã«ï¼Œã‚°ãƒªãƒ•ã¯ \texttt{left} 㨠\texttt{down} ã®å€¤ã«å¾“ã£ã¦ã‚·ãƒ•ãƒˆã•ã‚Œã‚‹ï¼Ž
+最終的ãªå®Ÿéš›ã®ã‚°ãƒªãƒ•ã®ä½ç½®ã¯èµ¤è‰²ã®é•·æ–¹å½¢ã§ç¤ºã•ã‚ŒãŸä½ç½®ã«ãªã‚‹ï¼Ž
+%</ja>
+\end{itemize}
+\end{minipage}
+\medskip
+
+\caption{%
+%<en>The position of the real glyph (horizontal Japanese fonts)
+%<ja>横組和文フォントã«ãŠã‘る「実際ã®ã€ã‚°ãƒªãƒ•ã®ä½ç½®
+}
+\label{fig:pos}
+\end{figure}
+\begin{figure}[!tb]
+\begin{minipage}{0.4\textwidth}%
+\begin{center}\unitlength=10pt\small
+\begin{picture}(15,12)(-6,0)
+\color{b_gray}% jfm
+\put(-6,0){\vrule width 12\unitlength height 11\unitlength}
+
+\color{b_pink}% real glyph
+\put(-6.5,5.5){\vrule width 8\unitlength height 6\unitlength depth 3\unitlength}
+
+\color{red}% real glyph
+\thicklines
+\put(-6.5,5.5){\vector(0,1){6}\vector(0,-1){3}\vector(1,0){8}}
+\put( 1.5,5.5){\line(0,1){6}\line(0,-1){3}}
+\put(-6.5,11.5){\line(1,0){8}}
+\put(-6.5,2.5){\line(1,0){8}}
+
+\color{b_green}% step1
+\put(-4,3){\vrule width 8\unitlength height 6\unitlength depth 3\unitlength}
+
+\color{black}% jfm
+\thicklines
+\put(0,11){\vector(1,0){6}\vector(-1,0){6}\vector(0,-1){11}}
+\put(0,0){\line(1,0){6}\line(-1,0){6}}
+\put(-6,0){\line(0,1){11}}
+\put( 6,0){\line(0,1){11}}
+\put( 3,10.8){\makebox(0,0)[t]{\texttt{height}}}
+\put(-3,10.8){\makebox(0,0)[t]{\texttt{depth}}}
+\put(0.2,5.5){\makebox(0,0)[l]{\texttt{width}}}
+
+\color{green}% step1
+\thicklines
+\put(-4,3){\vector(0,1){6}\vector(0,-1){3}\vector(1,0){8}}
+\put( 4,3){\line(0,1){6}\line(0,-1){3}}
+\put(-4,9){\line(1,0){8}}
+\put(-4,0){\line(1,0){8}}
+\savebox{\eqdist}(0,0)[b]{%
+ \thinlines
+ \put(-0.08,0.2){\line(0,-1){0.4}}%
+ \put(0.08,0.2){\line(0,-1){0.4}}}
+\put(2,9){\usebox{\eqdist}}
+\put(-2,9){\usebox{\eqdist}}
+
+
+\color{blue}% shifted
+\thicklines
+\put(-4,3){\vector(0,1){2.5}}
+\put(-3.8,4.25){\makebox(0,0)[l]{\texttt{left}}}
+\put(-4,5.5){\vector(-1,0){2.5}}
+\put(-5.,5.7){\makebox(0,0)[b]{\texttt{down}}}
+\end{picture}
+\end{center}
+\end{minipage}%
+\begin{minipage}{0.6\textwidth}%
+%<*en>
+(\dots)
+%</en>
+%<*ja>
+\texttt{align}フィールドã®å€¤ãŒ \texttt{'right'} ã§ã‚るよã†ãªæ–‡å­—クラスã«å±žã™ã‚‹
+和文文字を考ãˆã‚ˆã†ï¼Ž
+\begin{itemize}
+\item
+実際ã®ã‚°ãƒªãƒ•ã®ã€Œåž‚ç›´ä½ç½®ã€ã¯ï¼Œã¾ãšãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ãŒæ–‡å­—ã®ç‰©ç†çš„ãªå·¦å³æ–¹å‘ã®ä¸­å¤®ã‚’通る
+ä½ç½®ã¨ãªã‚‹ï¼Ž
+\item
+ã¾ãŸï¼Œã“ã®å ´åˆ \texttt{align} フィールド㯠\texttt{'right'} ãªã®ã§ï¼Œ
+「水平ä½ç½®ã€ã¯å­—é€ã‚Šæ–¹å‘ã«ã€Œå³å¯„ã›ã€ã—ãŸã‚‚ã®ã¨ãªã‚‹ï¼ˆç·‘色ã®é•·æ–¹å½¢ï¼‰ï¼Ž
+\item
+ãã®å¾Œã•ã‚‰ã« \texttt{left} 㨠\texttt{down} ã®å€¤ã«å¾“ã£ã¦ã‚·ãƒ•ãƒˆã•ã‚Œã‚‹
+ã®ã¯æ¨ªçµ„用和文フォントã¨å¤‰ã‚らãªã„.
+\end{itemize}
+%</ja>
+\end{minipage}
+\medskip
+
+\caption{%
+%<en>The position of the real glyph (vertical Japanese fonts)
+%<ja>縦組和文フォントã«ãŠã‘る「実際ã®ã€ã‚°ãƒªãƒ•ã®ä½ç½®
+}
+\label{fig:pos-tate}
+\end{figure}
+
+\item[kern={\{[$j$]=<kern>, [$j'$]=\{<kern>, [ratio=<ratio>]\}, ...\}}]
+\nopagebreak
+\item[glue={\{[$j$]=\{<width>, <stretch>, <shrink>, [ratio=<ratio>, ...]\}, ...\}}]\leavevmode
+%<*ja>
+
+文字クラス$i$ã®æ–‡å­—ã¨$j$ã®æ–‡å­—ã®é–“ã«æŒ¿å…¥ã•ã‚Œã‚‹ã‚«ãƒ¼ãƒ³ã‚„グルーã®é‡ã‚’指定ã™ã‚‹ï¼Ž
+
+<ratio>ã¯ï¼Œã‚°ãƒ«ãƒ¼ã®è‡ªç„¶é•·ã®ã†ã¡ã©ã‚Œã ã‘ã®å‰²åˆãŒã€Œå¾Œã®æ–‡å­—ã€ç”±æ¥ã‹ã‚’示ã™é‡ã§ï¼Œ
+$0$ã‹ã‚‰$+1$ã®å®Ÿæ•°å€¤ã‚’ã¨ã‚‹ï¼Žçœç•¥æ™‚ã®å€¤ã¯$0.5$ã§ã‚る.
+ã“ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã®å€¤ã¯\Param{differentjfm}ã®å€¤ãŒ
+\texttt{pleft},~\texttt{pright},~\texttt{paverage}ã®å€¤ã®ã¨ãã®ã¿å®Ÿéš›ã«ç”¨ã„られる.
+
+例ãˆã°ï¼Œ\cite{x4051}ã§ã¯ï¼Œå¥ç‚¹ã¨ä¸­ç‚¹ã®é–“ã«ã¯ï¼Œ
+å¥ç‚¹ç”±æ¥ã®äºŒåˆ†ç©ºãã¨ä¸­ç‚¹ç”±æ¥ã®å››åˆ†ç©ºããŒæŒ¿å…¥ã•ã‚Œã‚‹ãŒï¼Œã“ã®å ´åˆã«ã¯
+\begin{itemize}
+\item <width>ã«ã¯$0.5+0.25=0.75$を指定ã™ã‚‹ï¼Ž
+\item <ratio>ã«ã¯$0.25/(0.5+0.25)=1/3$を指定ã™ã‚‹ï¼Ž
+\end{itemize}
+%</ja>
+%<*en>
+\
+
+Specifies the amount of kern or glue which will be inserted
+between characters in character class~$i$ and those in character class~$j$.
+
+<ratio> specifies how much the glue is originated in the ``right'' character.
+It is a real number between 0 and 1, and treated as 0.5 if omitted. For example,
+The width of a glue between an ideographic full stop ``。''
+and a fullwidth middle dot ``・'' is three-fourth of fullwidth,
+namely halfwidth from the ideographic full stop, and
+quarter-width from the fullwidth middle dot. In this case,
+we specify <ratio> to $0.25/(0.5+0.25)=1/3$.
+%</en>
+
+%<*ja>
+グルーã®æŒ‡å®šã«ãŠã„ã¦ã¯ï¼Œä¸Šè¨˜ã«åŠ ãˆã¦å„ \texttt{[$j$]} ã®å„サブテーブル内ã«
+次ã®ã‚­ãƒ¼ã‚’指定ã§ãる,
+\begin{cslist}[style=standard]
+\item[priority=<priority>]
+ \Pkg{luatexja-adjust}ã«ã‚ˆã‚‹å„ªå…ˆé †ä½ä»˜ã
+ 行長調整(\ref{ssec:adj}節)ã«ãŠã„ã¦ï¼Œã“ã®ã‚°ãƒ«ãƒ¼ã®å„ªå…ˆåº¦ã‚’指定ã™ã‚‹ï¼Žè¨±ã•ã‚Œã‚‹å€¤ã¯ä»¥ä¸‹ã®é€šã‚Šï¼š
+ \begin{description}
+ \item[ãƒãƒ¼ã‚¸ãƒ§ãƒ³1] $-4$ã‹ã‚‰$+3$ã®é–“ã®æ•´æ•°
+ \item[ãƒãƒ¼ã‚¸ãƒ§ãƒ³2以é™] $-4$ã‹ã‚‰$+3$ã®é–“ã®æ•´æ•°ã®2ã¤çµ„\texttt{\{<stretch>, <shrink>\}}ã‹ï¼Œ
+ ã¾ãŸã¯$-4$ã‹ã‚‰$+3$ã®é–“ã®æ•´æ•°ï¼Ž<stretch>, <shrink>ã¯ãã‚Œãžã‚Œã“ã®ã‚°ãƒ«ãƒ¼ãŒä¼¸ã³ã‚‹ã¨ãã®å„ªå…ˆåº¦ï¼Œç¸®ã‚€ã¨ãã®
+ 優先度ã§ã‚り,å˜ã«æ•´æ•°$i$ãŒæŒ‡å®šã•ã‚ŒãŸå ´åˆã¯\texttt{\{$i$, $i$\}}ã§ã‚ã‚‹ã¨è§£é‡ˆã•ã‚Œã‚‹ï¼Ž
+ \end{description}
+ ã“ã“ã§æŒ‡å®šã™ã‚‹å€¤ã¯ï¼Œå¤§ãã„値ã»ã©ã€Œå…ˆã«ä¼¸ã°ã•ã‚Œã‚‹ã€ã€Œå…ˆã«ç¸®ã¾ã›ã‚‹ã€ã“ã¨ã‚’æ„味ã—ã¦ãŠã‚Šï¼Œçœç•¥æ™‚ã®å€¤
+ ã¯0ã§ã‚る.範囲外ã®å€¤ãŒæŒ‡å®šã•ã‚ŒãŸã¨ãã®å‹•ä½œã¯æœªå®šç¾©ã§ã‚る.
+\item[kanjiskip\_natural=<num>\textrm{, }%
+ kanjiskip\_stretch=<num>\textrm{, }kanjiskip\_shrink=<num>]\leavevmode
+ \label{pg:ksp_nat}
+
+JFMã«ã‚ˆã£ã¦æœ¬æ¥æŒ¿å…¥ã•ã‚Œã‚‹ã‚°ãƒ«ãƒ¼ã®ä»–ã«
+\Param{kanjiskip}分ã®ç©ºç™½ã‚’自然長(\texttt{kanjiskip\_natural}),伸ã³é‡(\texttt{kanjiskip\_stretch}),
+縮ã¿é‡(\texttt{kanjiskip\_shrink})ã”ã¨ã«æŒ¿å…¥ã™ã‚‹\footnote{本æ¥\Param{xkanjiskip}ãŒæŒ¿å…¥ã•ã‚Œã‚‹å ´æ‰€ã«ãŠã„ã¦ã¯
+ \Param{xkanjiskip}分ã®ç©ºç™½ã‚’自然長・伸ã³é‡ãƒ»ç¸®ã¿é‡ã”ã¨ã«ï¼Žè¿½åŠ ã§ãる.}%
+ãŸã‚ã®æŒ‡å®šã§ã‚る.ã„ãšã‚Œã‚‚çœç•¥ã•ã‚ŒãŸå ´åˆã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã¯0(追加ã—ãªã„)ã§ã‚る.
+
+例ãˆã°ï¼Œ\LuaTeX-jaã®æ¨ªçµ„標準JFMã® \texttt{jfm-ujis.lua} ã§ã¯ï¼Œ
+\begin{itemize}
+ \item 通常ã®æ–‡å­—「ã‚ã€ã¨é–‹ã括弧類ã®é–“ã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼ã¯ï¼Œè‡ªç„¶é•·ãƒ»ç¸®ã¿é‡åŠè§’,伸ã³é‡0ã®ã‚°ãƒ«ãƒ¼
+ã¨ãªã£ã¦ã„ã‚‹ãŒï¼Œã•ã‚‰ã«\Param{kanjiskip}ã®ä¼¸ã³é‡ã« \texttt{kanjiskip\_stretch}(ã“ã“ã§ã¯1)を掛ã‘
+ ãŸåˆ†ã ã‘伸ã³ã‚‹ã“ã¨ãŒè¨±ã•ã‚Œã‚‹ï¼Ž
+ \item åŒæ§˜ã«ï¼Œé–‰ã˜æ‹¬å¼§é¡žï¼ˆå…¨è§’コンマ「,ã€ã‚‚å«ã‚€ï¼‰ã¨é€šå¸¸ã®æ–‡å­—「ã†ã€ã€Œãˆã€ã®é–“ã«ã‚‚
+自然長・縮ã¿é‡åŠè§’,伸ã³é‡0ã®ã‚°ãƒ«ãƒ¼
+ã¨ãªã£ã¦ã„ã‚‹ãŒï¼Œã•ã‚‰ã«\Param{kanjiskip}ã®ä¼¸ã³é‡ã« \texttt{kanjiskip\_stretch}(ã“ã“ã§ã¯1)を掛ã‘
+ ãŸåˆ†ã ã‘伸ã³ã‚‹ã“ã¨ãŒè¨±ã•ã‚Œã‚‹ï¼Ž
+ \item 一方,開ã括弧類ã¨é€šå¸¸ã®æ–‡å­—ã®é–“,ã¾ãŸé€šå¸¸ã®æ–‡å­—ã¨é–‰ã˜æ‹¬å¼§é¡žã®é–“ã¯
+ 自然長・縮ã¿é‡ãƒ»ä¼¸ã³é‡0ã®ã‚°ãƒ«ãƒ¼ã ãŒï¼Œ\Param{kanjiskip}ã®ç¸®ã¿é‡ã«
+ \texttt{kanjiskip\_shrink}(ã“ã“ã§ã¯1)を掛ã‘ãŸåˆ†ã ã‘縮むã“ã¨ãŒè¨±ã•ã‚Œã‚‹ï¼Ž
+\end{itemize}
+ã¨ãªã£ã¦ã„る.従ã£ã¦ï¼Œä»¥ä¸‹ã®ã‚ˆã†ãªçµ„版çµæžœã‚’得る.
+
+\medskip
+\begin{LTXexample}[width=16\zw]
+\leavevmode
+\ltjsetparameter{kanjiskip=0pt plus 3\zw}
+\vrule\hbox to 15\zw{ã‚「ã„ã€ã†ï¼ŒãˆãŠ}\vrule
+
+\vrule\hbox{ã‚「ã„ã€ã†ï¼ŒãˆãŠ}\vrule\par
+\ltjsetparameter{kanjiskip=0pt minus \zw}
+\vrule\hbox to 6.5\zw{ã‚「ã„ã€ã†ï¼ŒãˆãŠ}\vrule
+\end{LTXexample}
+
+\end{cslist}
+%</ja>
+%<*en>
+In case of glue, one can specify following additional keys in each \texttt{[$j$]}
+ subtable:
+\begin{cslist}[style=standard]
+\item[priority=<priority>]
+An integer in $[-4,3]$ (treated as 0 if omitted), or
+a pair of these integers \texttt{\{<stretch>, <shrink>\}} (version 2~or~later).
+This is
+used only in line adjustment with priority by \Pkg{luatexja-adjust}
+(see Subsection~\ref{ssec:adj}). Higher value means the glue is easy to stretch,
+and is also easy to shrink.
+\item[kanjiskip\_natural=<num>\textrm{, }%
+ kanjiskip\_stretch=<num>\textrm{, }kanjiskip\_shrink=<num>]\leavevmode
+
+These keys specifies the amount of the natural width of \Param{kanjiskip}
+(the stretch/shrink part, respectively) which will be inserted
+in addition to the original JFM glue. Default values of them are all 0.
+
+As an example, in \texttt{jfm-ujis.lua}, the standard JFM in horizontal writing, we have
+\begin{itemize}
+ \item Between an ordinal letter ``ã‚'' and an ideographic opening bracket, we have
+a glue whose natural part and shrink part are both half-width, while its stretch part is
+ zero. However, this glue also can be stretched
+ as much as the stretch part of \Param{kanjiskip} times the value of
+ \texttt{kanjiskip\_stretch} key (1 in this case).
+ \item Between an ideographic closeing brackets (the ideographic comma ``,''
+ is included) and an ordinal letter, we have the same glue.
+ Again, this glue also can be stretched
+ as much as the stretch part of \Param{kanjiskip} times the value of
+ \texttt{kanjiskip\_stretch} key (1 in this case).
+ \item Between an ideographic opening bracket and an ordinal letter
+ and between an ordinal letter and an ideographic closing bracket,
+ we have a glue whose natural part and stretch part are both zero, while its shrink part as much as
+ the shrink part of \Param{kanjiskip}.
+\end{itemize}
+Hence we have the following result:
+
+\medskip
+\begin{LTXexample}[width=16\zw]
+\leavevmode
+\ltjsetparameter{kanjiskip=0pt plus 3\zw}
+\vrule\hbox to 15\zw{ã‚「ã„ã€ã†ï¼ŒãˆãŠ}\vrule
+
+\vrule\hbox{ã‚「ã„ã€ã†ï¼ŒãˆãŠ}\vrule\par
+\ltjsetparameter{kanjiskip=0pt minus \zw}
+\vrule\hbox to 6.5\zw{ã‚「ã„ã€ã†ï¼ŒãˆãŠ}\vrule
+\end{LTXexample}
+
+\end{cslist}
+%</en>
+
+\item[end\_stretch=<kern>, end\_shrink=<kern>]
+%<*ja>
+(任æ„,ãƒãƒ¼ã‚¸ãƒ§ãƒ³1ã®ã¿ï¼‰
+
+優先順ä½ä»˜ã行長調整ãŒæœ‰åŠ¹ã§ã‚り,ã‹ã¤ç¾åœ¨ã®æ–‡å­—クラスã®æ–‡å­—ãŒè¡Œ
+ 末ã«æ¥ãŸæ™‚ã«ï¼Œè¡Œé•·ã‚’è©°ã‚る調整・伸ã°ã™èª¿æ•´ã®ãŸ
+ ã‚ã«ã“ã®æ–‡å­—ã¨è¡Œæœ«ã®é–“ã«æŒ¿å…¥å¯èƒ½ãªã‚«ãƒ¼ãƒ³ã®å¤§ãã•ã‚’指定ã™ã‚‹ï¼Ž
+%</ja>
+%<*en>
+(optional, version~1 only)
+%</en>
+
+ \item[end\_adjust=\{<kern>, <kern>, ...\}]
+%<*ja>
+(任æ„,ãƒãƒ¼ã‚¸ãƒ§ãƒ³2以é™ï¼‰
+
+優先順ä½ä»˜ã行長調整ãŒæœ‰åŠ¹ã§ã‚り,ã‹ã¤ç¾åœ¨ã®æ–‡å­—クラスã®æ–‡å­—ãŒ
+ 行末ã«æ¥ãŸæ™‚ã«ï¼Œã“ã®æ–‡å­—ã¨è¡Œæœ«ã®é–“ã«ã¯æŒ‡å®šã•ã‚ŒãŸå€¤ã®ã„ãšã‚Œã‹ã®å¤§ãã•ã®ã‚«ãƒ¼ãƒ³ãŒ
+ 挿入ã•ã‚Œã‚‹ï¼ˆ\autoref{ssec:adj}å‚照).
+
+ãƒãƒ¼ã‚¸ãƒ§ãƒ³1ã«ãŠã‘ã‚‹
+\begin{lstlisting}[escapechar=\$]
+ end_stretch = $a$, end_shrink = $b$
+\end{lstlisting}
+ã¨ã„ã†æŒ‡å®šã¯ï¼Œãƒãƒ¼ã‚¸ãƒ§ãƒ³2以é™ã§ã¯æ¬¡ã®æŒ‡å®šã¨åŒã˜ã«ãªã‚‹ï¼Ž
+\begin{lstlisting}[escapechar=\$]
+ end_adjust = {$-b$, 0.0, $a$}
+\end{lstlisting}
+ã‚‚ã—真ん中㮠\texttt{0.0} ãŒãªã„å ´åˆã¯ï¼Œ$a$ã‹$-b$ã‹ã„ãšã‚Œã‹ã®ã‚«ãƒ¼ãƒ³ãŒå¸¸ã«è¡Œæœ«ã«è¿½åŠ ã•ã‚Œã‚‹ï¼Ž
+%</ja>
+%<*en>
+(optional, version~2 or~later)
+%</en>
+
+\end{cslist}
+
+%<*ja>
+\paragraph{文字クラスã®æ±ºå®š}
+文字ã‹ã‚‰ãã®æ–‡å­—ã®å±žã™ã‚‹æ–‡å­—クラスを算出ã™ã‚‹éŽç¨‹ã«ã¤ã„ã¦ï¼Œ
+次ã®å†…容をå«ã‚“ã  \texttt{jfm-test.lua} を用ã„ã¦èª¬æ˜Žã™ã‚‹ï¼Ž
+%</ja>
+%<*en>
+\paragraph{Character to character classes}
+We explain how the character class of a character is determined,
+using \texttt{jfm-test.lua} which contains the following:
+%</en>
+\begin{lstlisting}
+ [0] = {
+ chars = { 'æ¼¢' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ },
+ [2000] = {
+ chars = { '。', 'ヒ' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ },
+\end{lstlisting}
+%<ja>ã“ã“ã§ï¼Œæ¬¡ã®ã‚ˆã†ãªå…¥åŠ›ã¨ãã®å®Ÿè¡Œçµæžœã‚’考ãˆã‚‹ï¼š
+%<en>Now consider the following input/output:
+\begin{LTXexample}[width=0.3\textwidth]
+\jfont\a=file:KozMinPr6N-Regular.otf:jfm=test;+hwid
+\setbox0\hbox{\a ヒ漢}
+\the\wd0
+\end{LTXexample}
+%<*en>
+Now we look why the above source outputs 15\,pt.
+\begin{enumerate}
+\item The character ``ヒ'' is converted to its half width form ``ヒ'' by \verb+hwid+ feature.
+\item According to the JFM, the character class of ``ヒ'' is 2000, hence its width is halfwidth.
+\item The character class of ``æ¼¢'' is zero, hence its width is fullwidth.
+\item Hence the width of \cs{hbox} equals to 15\,pt.
+\end{enumerate}
+This example shows that the character class of a character is generally determined \emph{after
+applying font features by \Pkg{luaotfload}}.
+%</en>
+%<*ja>
+上記ã®å‡ºåŠ›çµæžœãŒï¼Œ15\,ptã¨ãªã£ã¦ã„ã‚‹ã®ã¯ç†ç”±ã«ã‚ˆã‚‹ã‚‚ã®ã§ã‚る:
+\begin{enumerate}
+\item \verb+hwid+ featureã«ã‚ˆã£ã¦ã€Œãƒ’ã€ãŒåŠè§’å¹…ã®ã‚°ãƒªãƒ•ã€Œï¾‹ã€ã¨ç½®ãæ›ã‚る(\Pkg{luaotfload} ã«ã‚ˆã‚‹å‡¦ç†ï¼‰ï¼Ž
+\item JFMã«ã‚ˆã‚Œã°ï¼Œã“ã®ã€Œï¾‹ã€ã®ã‚°ãƒªãƒ•ã®æ–‡å­—クラスã¯2000ã§ã‚る.
+\item 以上ã«ã‚ˆã‚Šæ–‡å­—クラス2000ã¨ã¿ãªã•ã‚Œã‚‹ãŸã‚,çµæžœã¨ã—ã¦ã€Œï¾‹ã€ã®å¹…ã¯åŠè§’ã ã¨èªè­˜ã•ã‚Œã‚‹ï¼Ž
+\end{enumerate}
+ã“ã®ä¾‹ã¯ï¼Œ\emph{文字クラスã®æ±ºå®šã¯OpenType機能ã®é©ç”¨ã«ã‚ˆã‚‹ã‚°ãƒªãƒ•ç½®æ›ã®çµæžœã«åŸºã¥ã}ã“ã¨ã‚’
+示ã—ã¦ã„る.
+%</ja>
+
+%<*en>
+However, if the class determined by the glyph after application of features is zero,
+\LuaTeX-ja adopts the class determined by the glyph \emph{before} application of features.
+The following input is an example.
+%</en>
+%<*ja>
+但ã—,JFMã«ã‚ˆã£ã¦æ±ºã¾ã‚‹ç½®æ›å¾Œã®ã‚°ãƒªãƒ•ã®æ–‡å­—クラスãŒ0ã§ã‚ã‚‹å ´åˆã¯ï¼Œç½®æ›å‰ã®æ–‡å­—クラスを採用ã™ã‚‹ï¼Ž
+%</ja>
+\begin{LTXexample}[width=0.3\textwidth]
+\jfont\a=file:KozMinPr6N-Regular.otf:jfm=test;+vert
+\a 漢。\inhibitglue 漢
+\end{LTXexample}
+%<*en>
+Here, the character class of the ideographic full stop ``。''~(\texttt{U+3002}) is determined
+as follows:
+\begin{enumerate}
+\item As the case of ``ヒ'', the ideographic full stop ``。'' is converted to its vertical
+ form ``\char"FE12''~(\texttt{U+FE12}) by \verb+vert+ feature.%"
+\item The character class of ``\char"FE12'', according to the JFM is \emph{zero}.
+\item However, \LuaTeX-ja remembers that this ``\char"FE12'' is obtained from ``。'' by
+ font features. The character class of ``。'' is \emph{non-zero value}, namely, 2000.
+\item Hence the ideographic full stop ``。'' in above belongs the character class~2000.
+\end{enumerate}
+%</en>
+%<*ja>
+ã“ã“ã§ï¼Œå¥ç‚¹ã€Œã€‚ã€(\texttt{U+3002})ã®æ–‡å­—クラスã¯ï¼Œä»¥ä¸‹ã®ã‚ˆã†ã«ã—ã¦æ±ºã¾ã‚‹ï¼Ž
+\begin{enumerate}
+\item \Pkg{luaotfload}ã«ã‚ˆã£ã¦ç¸¦çµ„用å¥ç‚¹ã®ã‚°ãƒªãƒ•ã«ç½®ãæ›ã‚る.
+\item ç½®æ›å¾Œã®ã‚°ãƒªãƒ•ã¯ \texttt{U+FE12} ã§ã‚り,JFMã«å¾“ãˆã°æ–‡å­—クラスã¯\emph{0}ã¨åˆ¤å®šã•ã‚Œã‚‹ï¼Ž
+\item ã“ã®å ´åˆï¼Œç½®æ›å‰ã®æ¨ªçµ„用å¥ç‚¹ã®ã‚°ãƒªãƒ•ã«ã‚ˆã£ã¦æ–‡å­—クラスを判定ã™ã‚‹ï¼Ž
+\item çµæžœã¨ã—ã¦ï¼Œä¸Šã®å‡ºåŠ›ä¾‹ä¸­ã®å¥ç‚¹ã®æ–‡å­—クラスã¯2000ã¨ãªã‚‹ï¼Ž
+\end{enumerate}
+%</ja>
+
+
+%<ja>\paragraph{仮想的ãªæ–‡å­—}
+%<en>\paragraph{Imaginary characters}
+%<*en>
+As described before, you can specify several ``imaginary characters'' in
+\texttt{chars} field. The most of these characters are regarded as the
+characters of class 0 in \pTeX.
+As a result, \LuaTeX-ja can control typesetting finer than \pTeX.
+The following is the list of imaginary characters:
+%</en>
+%<*ja>
+上ã§èª¬æ˜Žã—ãŸé€šã‚Šï¼Œ\texttt{chars}フィールド中ã«ã¯ã„ãã¤ã‹ã®ã€Œç‰¹æ®Šæ–‡å­—ã€ã‚‚
+指定å¯èƒ½ã§ã‚る.ã“れらã¯ï¼Œå¤§åŠãŒ\pTeX ã®JFMグルーã®æŒ¿å…¥å‡¦ç†ã§ã¯ã¿ãªã€Œæ–‡å­—
+クラス0ã®æ–‡å­—ã€ã¨ã—ã¦æ‰±ã‚ã‚Œã¦ã„ãŸæ–‡å­—ã§ã‚り,ãã®çµæžœã¨ã—ã¦\pTeX より細ã‹
+ã„組版調整ãŒã§ãるよã†ã«ãªã£ã¦ã„る.以下ã§ãã®ä¸€è¦§ã‚’è¿°ã¹ã‚‹ï¼š
+%</ja>
+
+\begin{cslist}
+%%\item['diffmet']
+%%<en>Used at a boundary between two \textbf{JAchar}s whose JFM or size is different.
+%%<ja>JFMやサイズãŒç•°ãªã‚‹2ã¤ã®\textbf{JAchar}ã®é–“ã®å¢ƒç•Œã¨ã—ã¦ç”¨ã„られる.
+
+\item['boxbdd']
+%<*en>
+The beginning/ending of a hbox, and the beginning of a noindented (i.e., began by \cs{noindent}) paragraph.
+If a hbox~$b$ begins (resp.~ends) a glue or kern between this ``charater'' and a \textbf{JAchar},
+\textbf{JAglue} won't be inserted before(resp.~after) the hbox~$b$.
+\Param{kanjiskip}~and~\Param{xkanjiskip} around a hbox.
+%</en>
+%<*ja>
+hboxã®å…ˆé ­ã¨æœ«å°¾ï¼ŒåŠã³ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã•ã‚Œã¦ã„ãªã„(\cs{noindent} ã§é–‹å§‹ã•ã‚ŒãŸï¼‰æ®µè½ã®å…ˆé ­ã‚’表ã™ï¼Ž
+ã“ã®ã€Œæ–‡å­—ã€ã¨ã®é–“ã«è¨­å®šã—ãŸã‚°ãƒ«ãƒ¼ãƒ»ã‚«ãƒ¼ãƒ³ãŒãƒœãƒƒã‚¯ã‚¹$b$ã®å…ˆé ­ï¼ˆã‚‚ã—ãã¯æœ«å°¾ï¼‰ã«æ¥ãŸå ´åˆï¼Œ
+ ãã®ãƒœãƒƒã‚¯ã‚¹$b$ã®ç›´å‰ï¼ˆã‚‚ã—ãã¯ç›´å¾Œï¼‰ã«ã¯å’Œæ–‡å‡¦ç†ã‚°ãƒ«ãƒ¼ã¯å…¥ã‚‰ãªã„.
+%</ja>
+
+\item['parbdd']
+%<en>The beginning of an (indented) paragraph.
+%<ja>通常ã®ï¼ˆ\cs{noindent} ã§é–‹å§‹ã•ã‚Œã¦ã„ãªã„)段è½ã®å…ˆé ­ï¼Ž
+
+\item['jcharbdd']
+%<en>A boundary between \textbf{JAchar} and anything else.
+%<*ja>
+\textbf{JAchar}ã¨ã€Œãã®ä»–ã®ã‚‚ã®ã€ã¨ã®å¢ƒç•Œï¼Ž
+
+ãƒãƒ¼ã‚¸ãƒ§ãƒ³2以å‰ã§ã¯\textbf{ALchar},箱,罫線(rule),glue,~kernãªã©ã„ã‚ã„ã‚ãªã‚‚ã®ã¨\textbf{JAchar}ã®å¢ƒç•Œã«å¯¾ã—ã¦
+本特殊文字ãŒç”¨ã„られã¦ã„ãŸãŒï¼Œ
+ãƒãƒ¼ã‚¸ãƒ§ãƒ³3以é™ã§ã¯\ \texttt{'jcharbdd'}, \texttt{'alchar'}, \texttt{'nox\_alchar'},
+\texttt{'glue'} ã¨ç´°åˆ†åŒ–ã•ã‚Œï¼Œ
+\texttt{'jcharbdd'} ã¯ä¸»ã«\textbf{JAchar}ã¨ãƒœãƒƒã‚¯ã‚¹ã‚„罫線(rule)ã¨ã®å¢ƒç•Œã«ä½¿ã‚れるよã†ã«ãªã£ãŸï¼Ž
+%</ja>
+
+\item['alchar', 'nox\_alchar']
+%<*en>
+(version 3~or~later) A boundary between \textbf{JAchar} and \textbf{ALchar}.
+%</en>
+%<*ja>
+(ãƒãƒ¼ã‚¸ãƒ§ãƒ³3以é™ï¼‰\textbf{JAchar}ã¨\textbf{ALchar}ã¨ã®å¢ƒç•Œï¼Ž
+\textbf{JAchar}ã¨\textbf{ALchar}ã®é–“ã«\Param{xkanjiskip}ãŒå…¥ã‚‹ã“ã¨ãŒå¯èƒ½ãªå ´åˆã¯
+\ \texttt{'alchar'}\ ãŒï¼Œãã†ã§ãªã„å ´åˆã¯\ \texttt{'nox\_alchar'}\ ãŒç”¨ã„られる
+(ã“ã®åŒºåˆ¥ã¯\textbf{ALchar}å´ã®\Param{alxspmode}ã®å€¤ã«ã‚ˆã£ã¦ã®ã¿è¡Œã‚れる).
+%</ja>
+
+\item['glue']
+%<en>(version 3~or~later) A boundary between \textbf{JAchar}, and, a glue or kern.
+%<ja>(ãƒãƒ¼ã‚¸ãƒ§ãƒ³3以é™ï¼‰\textbf{JAchar}ã¨glue,kernã¨ã®å¢ƒç•Œï¼Ž
+
+\item[$-1$]
+%<en>The left/right boundary of an inline math formula.
+%<ja>行中数å¼ã¨åœ°ã®æ–‡ã¨ã®å¢ƒç•Œï¼Ž
+\end{cslist}
+
+%<en>\paragraph{Porting JFM from \pTeX}
+%<ja>\paragraph{\pTeX 用和文用TFMã®ç§»æ¤}
+
+% ToDo: English version.
+
+%<*en>
+See Japanese version of this manual.
+%</en>
+
+%<*ja>
+以下ã«ï¼Œ\pTeX 用ã«ä½œã‚‰ã‚ŒãŸå’Œæ–‡ç”¨TFMã‚’\LuaTeX-ja用ã«ç§»æ¤ã™ã‚‹å ´åˆã®æ³¨æ„点を挙ã’ã¦ãŠã.
+\begin{itemize}
+\item 実際ã«å‡ºåŠ›ã•ã‚Œã‚‹å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®ã‚µã‚¤ã‚ºãŒdesign sizeã¨ãªã‚‹ï¼Ž
+ã“ã®ãŸã‚,例ãˆã°$1\,\textrm{zw}$ãŒdesign sizeã®0.962216å€ã§ã‚ã‚‹JISフォン
+ トメトリック等を移æ¤ã™ã‚‹å ´åˆã¯ï¼Œæ¬¡ã®ã‚ˆã†ã«ã™ã‚‹ã¹ãã§ã‚る:
+\begin{itemize}
+\item JFM中ã®å…¨ã¦ã®æ•°å€¤ã‚’$1/0.962216$å€ã—ã¦ãŠã.
+\item \TeX ソース中ã§ä½¿ç”¨ã™ã‚‹ã¨ã“ã‚ã§ï¼Œã‚µã‚¤ã‚ºæŒ‡å®šã‚’0.962216å€ã«ã™ã‚‹ï¼Ž
+ \LaTeX ã§ã®ãƒ•ã‚©ãƒ³ãƒˆå®£è¨€ãªã‚‰ï¼Œä¾‹ãˆã°æ¬¡ã®ã‚ˆã†ã«ï¼š
+\begin{lstlisting}
+\DeclareFontShape{JY3}{mc}{m}{n}{<-> s*[0.962216] psft:Ryumin-Light:jfm=jis}{}
+\end{lstlisting}
+\end{itemize}
+\item 上ã«è¿°ã¹ãŸç‰¹æ®Šæ–‡å­—ã¯ï¼Œ\texttt{'boxbdd'}を除ã文字クラスを全部0ã¨ã™ã‚‹
+ (JFM中ã«å˜ã«æ›¸ã‹ãªã‘ã‚Œã°ã‚ˆã„).
+\item \texttt{'boxbdd'}ã«ã¤ã„ã¦ã¯ï¼Œãã‚Œã®ã¿ã§ä¸€ã¤ã®æ–‡å­—クラスを形æˆã—,ãã®
+ 文字クラスã«é–¢ã—ã¦ã¯ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ã®è¨­å®šã¯ã—ãªã„.
+
+ã“ã‚Œã¯ï¼Œ\pTeX ã§ã¯ï¼Œ
+ hboxã®å…ˆé ­ãƒ»æœ«å°¾ã¨ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã•ã‚Œã¦ã„ãªã„(\cs{noindent} ã§é–‹å§‹ã•
+ ã‚ŒãŸï¼‰æ®µè½ã®å…ˆé ­ã«ã¯JFMグルーã¯å…¥ã‚‰ãªã„ã¨ã„ã†ä»•æ§˜ã‚’実ç¾ã•ã›ã‚‹ãŸã‚ã§ã‚る.
+\item \pTeX ã®çµ„版をå†ç¾ã•ã›ã‚ˆã†ã¨ã„ã†ã®ãŒç›®çš„ã§ã‚ã‚Œã°ä»¥ä¸Šã®æ³¨æ„を守れã°å分ã§ã‚る.
+
+ã¨ã“ã‚ã§ï¼Œ\pTeX ã§ã¯é€šå¸¸ã®æ®µè½ã®å…ˆé ­ã«JFMグルーãŒæ®‹ã‚‹ã¨ã„ã†ä»•æ§˜ãŒã‚ã‚‹ã®ã§ï¼Œ
+ 段è½å…ˆé ­ã®é–‹ã括弧ã¯å…¨è§’二分下ãŒã‚Šã«ãªã‚‹ï¼Žå…¨è§’下ãŒã‚Šã‚’実ç¾ã•ã›ã‚‹ã«
+ ã¯ï¼Œæ®µè½ã®æœ€åˆã«æ‰‹å‹•ã§ \cs{inhibitglue} を追加ã™ã‚‹ã‹ï¼Œã‚ã‚‹ã„ã¯
+ \ \cs{everypar} ã®ãƒãƒƒã‚¯ã‚’è¡Œã„,ãれを自動化ã•ã›ã‚‹ã—ã‹ãªã‹ã£ãŸï¼Ž
+
+一方,\LuaTeX-jaã§ã¯ï¼Œ\texttt{'parbdd'}ã«ã‚ˆã£ã¦ï¼Œãã‚ŒãŒJFMå´ã§èª¿æ•´ã§ãるよ
+ã†ã«ãªã£ãŸï¼Žä¾‹ãˆã°ï¼Œ\LuaTeX-jaåŒæ¢±ã®JFMã®ã‚ˆã†ã«ï¼Œ\texttt{'boxbdd'}ã¨åŒã˜æ–‡å­—クラスã«
+\texttt{'parbdd'}を入れれã°å…¨è§’下ãŒã‚Šã¨ãªã‚‹ï¼Ž
+
+\begin{LTXexample}[width=0.4\textwidth]
+\jfont\g=KozMinPr6N-Regular:jfm=test \g
+\parindent1\zw\noindent{}◆◆◆◆◆
+\par 「◆◆â†äºŒåˆ†ä¸‹ãŒã‚Š
+\par ã€â—†â—†â†å…¨è§’下ãŒã‚Š
+\par 〔◆◆â†å…¨è§’二分下ãŒã‚Š
+\end{LTXexample}
+\end{itemize}
+
+但ã—,\cs{everypar} を利用ã—ã¦ã„ã‚‹å ´åˆã«ã¯ã“ã®ä»•çµ„ã¿ã¯æ­£ã—ãå‹•ã‹ãªã„.
+ãã®ã‚ˆã†ãªä¾‹ã¨ã—ã¦ã¯ç®‡æ¡æ›¸ã中㮠\cs{item} ã§å§‹ã¾ã‚‹æ®µè½ãŒã‚り,\Pkg{ltjsclasses}ã§ã¯
+人工的ã«ã€Œ\texttt{'parbdd'}ã®æ„味をæŒã¤ã€whatsitノードを作るã“ã¨ã«ã‚ˆã£ã¦å¯¾å‡¦ã—ã¦ã„ã‚‹%
+\footnote{\texttt{ltjsclasses.dtx} ã‚’å‚ç…§ã•ã‚ŒãŸã„.
+JFMå´ã§ä¸€éƒ¨ã®å¯¾å‡¦ãŒã§ãã‚‹ã“ã¨ã«ã‚ˆã‚Šï¼Œ\Pkg{jsclasses}ã®ã‚ˆã†ã«ifæ–‡ã®åˆ¤å®šã¯ã—ã¦ã„ãªã„.}.
+%</ja>
+
+
+%<en>\subsection{Math font family}
+%<ja>\subsection{æ•°å¼ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒª}
+\label{ssec:math}
+
+%<*en>
+\TeX\ handles fonts in math formulas by 16~font families\footnote{Omega,
+Aleph, \LuaTeX~and $\varepsilon$-\kern-.125em(u)\pTeX\ can handles 256~families, but
+an external package is needed to support this in plain \TeX\ and
+\LaTeX.}, and each family has three fonts:
+\cs{textfont}, \cs{scriptfont} and \cs{scriptscriptfont}.
+%</en>
+%<*ja>
+\TeX\ ã¯æ•°å¼ãƒ•ã‚©ãƒ³ãƒˆã‚’16ã®ãƒ•ã‚¡ãƒŸãƒª\footnote{Omega, Aleph, \LuaTeX,ãã—ã¦
+ $\varepsilon$-\kern-.125em(u)\pTeX\ ã§ã¯256ã®æ•°å¼ãƒ•ã‚¡ãƒŸãƒªã‚’扱ã†ã“ã¨ãŒã§ãã‚‹ãŒï¼Œ
+ ã“れをサãƒãƒ¼ãƒˆã™ã‚‹ãŸã‚ã«plain \TeX ã¨\LaTeX ã§ã¯å¤–部パッケージを読ã¿è¾¼ã‚€å¿…è¦ãŒ
+ ã‚る.}ã§ç®¡ç†ã—,ãã‚Œãžã‚Œã®ãƒ•ã‚¡ãƒŸãƒªã¯3ã¤ã®ãƒ•ã‚©ãƒ³ãƒˆã‚’æŒã£ã¦ã„る:
+\cs{textfont}, \cs{scriptfont} ãã—㦠\cs{scriptscriptfont} ã§ã‚ã‚‹.
+%</ja>
+
+%<*en>
+\LuaTeX-ja's handling of Japanese fonts in math formulas is similar;
+\autoref{tab-math} shows counterparts to \TeX's primitives for math
+font families. There is no relation between the value of
+\cs{fam} and that of \cs{jfam}; with appropriate settings,
+you can set both \cs{fam} and \cs{jfam} to the same value.
+Here <jfont\_cs> in the argument of \Param{jatextfont} etc.\ is
+a control sequence which is defined by \cs{jfont}, i.e.,
+a \emph{horizontal} Japanese font.
+%</en>
+%<*ja>
+\LuaTeX-jaã®æ•°å¼ä¸­ã§ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®æ‰±ã„ã‚‚åŒæ§˜ã§ã‚る.
+\autoref{tab-math}ã¯æ•°å¼ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã«å¯¾ã™ã‚‹ \TeX ã®ãƒ—リミティブã¨å¯¾å¿œã™ã‚‹
+ã‚‚ã®ã‚’示ã—ã¦ã„る.\cs{fam} 㨠\cs{jfam} ã®å€¤ã®é–“ã«ã¯é–¢ä¿‚ã¯ãªã,
+é©åˆ‡ãªè¨­å®šã®ä¸‹ã§ã¯ \cs{fam} 㨠\cs{jfam} ã®ä¸¡æ–¹ã«åŒã˜å€¤ã‚’設定ã™ã‚‹ã“ã¨ãŒã§ãる.
+\Param{jatextfont} ä»–ã®ç¬¬2引数<jfont\_cs>ã¯ï¼Œ\cs{jfont} ã§å®šç¾©ã•ã‚ŒãŸ
+\emph{横組用}和文フォントã§ã‚る.\cs{tfont} ã§å®šç¾©ã•ã‚ŒãŸ
+\emph{縦組用}和文フォントを指定ã™ã‚‹ã“ã¨ã¯æƒ³å®šã—ã¦ã„ãªã„.
+%</ja>
+
+\begin{table}[!tb]
+%<en>\caption{Commands for Japanese math fonts}
+%<ja>\caption{和文数å¼ãƒ•ã‚©ãƒ³ãƒˆã«å¯¾ã™ã‚‹å‘½ä»¤}
+\label{tab-math}
+%<en>\medskip
+\centering
+\def\{{\char`\{}\def\}{\char`\}}\small
+\begin{tabular}{ll}
+\toprule
+%<en>\bf Japanese fonts&\bf alphabetic fonts\\
+%<ja>\bf 和文フォント&\bf 欧文フォント\\
+\midrule
+\cs{jfam}${}\in [0,256)$&\cs{fam}\\
+\tt\Param{jatextfont}\,=\{<jfam>,<jfont\_cs>\}&\tt\cs{textfont}<fam>=<font\_cs>\\
+\tt\Param{jascriptfont}\,=\{<jfam>,<jfont\_cs>\}&\tt\cs{scriptfont}<fam>=<font\_cs>\\
+\tt\Param{jascriptscriptfont}\,=\{<jfam>,<jfont\_cs>\}&\tt\cs{scriptscriptfont}<fam>=<font\_cs>\\
+\bottomrule
+\end{tabular}
+\end{table}
+
+%<en>\subsection{Callbacks}
+%<ja>\subsection{コールãƒãƒƒã‚¯}
+
+%<*en>
+\LuaTeX-ja also has several callbacks. These callbacks can
+be accessed via \verb+luatexbase.add_to_callback+ function and so on, as other callbacks.
+%</en>
+%<*ja>
+\LuaTeX 自体ã®ã‚‚ã®ã«åŠ ãˆã¦ï¼Œ\LuaTeX-jaもコールãƒãƒƒã‚¯ã‚’æŒã£ã¦ã„る.
+ã“れらã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã«ã¯ï¼Œä»–ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¨åŒæ§˜ã« \verb+luatexbase.add_to_callback+
+関数ãªã©ã‚’用ã„ã‚‹ã“ã¨ã§ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã“ã¨ãŒã§ãる.
+%</ja>
+\begin{description}[font=\bfseries, style=nextline]
+%<en>\item[\texttt{luatexja.load\_jfm} callback]
+%<ja>\item[\texttt{luatexja.load\_jfm}コールãƒãƒƒã‚¯]
+%<*en>
+With this callback you can overwrite JFMs.
+This callback is called when a new JFM is loaded.
+%</en>
+%<*ja>
+ã“ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã‚’用ã„ã‚‹ã“ã¨ã§JFMを上書ãã™ã‚‹ã“ã¨ãŒã§ãる.
+ã“ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯æ–°ã—ã„JFMãŒèª­ã¿è¾¼ã¾ã‚Œã‚‹ã¨ãã«å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+\begin{lstlisting}[numbers=left]
+function (<table> jfm_info, <string> jfm_name)
+ return <table> new_jfm_info
+end
+\end{lstlisting}
+
+%<*en>
+The argument \verb+jfm_info+ contains a table similar to the table in a JFM file, except
+this argument has \texttt{chars} field which contains character codes
+ whose character class is not~0.
+%</en>
+%<*ja>
+引数 \verb+jfm_info+ ã¯JFMファイルã®ãƒ†ãƒ¼ãƒ–ルã¨ä¼¼ãŸã‚‚ã®ãŒæ ¼ç´ã•ã‚Œã‚‹ãŒï¼Œ
+クラス0を除ã„ãŸæ–‡å­—ã®ã‚³ãƒ¼ãƒ‰ã‚’å«ã‚“ã \texttt{chars}フィールドをæŒã¤ç‚¹ãŒç•°ãªã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+An example of this callback is the \texttt{ltjarticle} class, with
+ forcefully assigning character class~0 to \texttt{'parbdd'}
+ in the JFM \texttt{jfm-min.lua}.
+%</en>
+%<*ja>
+ã“ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã®ä½¿ç”¨ä¾‹ã¯\texttt{ltjarticle}クラスã«ã‚り,
+\texttt{jfm-min.lua}中ã®\texttt{'parbdd'}を強制的ã«ã‚¯ãƒ©ã‚¹0ã«å‰²ã‚Šå½“ã¦ã¦ã„る.
+%</ja>
+
+%<en>\item[\texttt{luatexja.define\_jfont} callback]
+%<ja>\item[\texttt{luatexja.define\_jfont}コールãƒãƒƒã‚¯]
+%<*en>
+This callback and the next callback form a pair, and you can assign characters
+ which do not have fixed code points in Unicode to non-zero character classes.
+This \texttt{luatexja.define\_font} callback is called just when new Japanese font is loaded.
+%</en>
+%<*ja>
+ã“ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¨æ¬¡ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯çµ„ã‚’ãªã—ã¦ãŠã‚Šï¼ŒUnicode中ã«å›ºå®šã•ã‚ŒãŸæ–‡å­—コード
+番å·ã‚’æŒãŸãªã„文字をéžé›¶ã®æ–‡å­—クラスã«å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãる.
+ã“ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯æ–°ã—ã„和文フォントãŒèª­ã¿è¾¼ã¾ã‚ŒãŸã¨ãã«å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+\begin{lstlisting}[numbers=left]
+function (<table> jfont_info, <number> font_number)
+ return <table> new_jfont_info
+end
+\end{lstlisting}
+%<*en>
+\verb+jfont_info+ has the following fields,
+\emph{which may not overwritten by a user}:
+\begin{description}
+\item[\texttt{size}]
+The font size specified at \cs{jfont} in scaled points ($1\,\mathrm{sp}=2^{-16}\,\mathrm{pt}$).
+\item[\texttt{zw}, \texttt{zh}, \texttt{kanjiskip}, \texttt{xkanjiskip}]
+These are scaled value of those specified by the JFM, by the font size.
+\item[\texttt{jfm}]
+The internal number of the JFM.
+\item[\texttt{var}]
+The value of \texttt{jfmvar}~key, which is specified at \cs{jfont}.
+The default value is the empty string.
+\item[\texttt{chars}]
+The mapping table from character codes to its character classes.\\
+The specification \texttt{[i].chars=\{<character>, ...\}} in the JFM will be stored in this
+ field as \texttt{chars=\{[<character>]=\,$i$, ...\}}.
+\item[\texttt{char\_type}]
+For $i\in\omega$, \texttt{char\_type[$i$]} is information of characters whose class is
+ $i$, and has the following fields:
+\begin{itemize}
+ \item \texttt{width},~\texttt{height}, \texttt{depth},
+ \texttt{italic}, \texttt{down},~\texttt{left}\ are just
+ scaled value of those specified by the JFM, by the font size.
+ \item \texttt{align} is a number which is determined from \texttt{align}~field in the JFM:
+\[
+ \begin{cases}
+ 0&\text{\texttt{'left'} (default)}\\0.5&\text{\tt 'middle'}\\1&\text{\tt 'right'}
+ \end{cases}
+\]
+\end{itemize}
+For $i$,~$j\in \omega$, \texttt{char\_type[$i$][$j$]} stores a kern or a glue which will be inserted
+between character class~$i$ and class~$j$.
+\end{description}
+%</en>
+%<*ja>
+\verb+jfont_info+ ã¯æœ€ä½Žé™ä»¥ä¸‹ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’æŒã¤ãŒï¼Œã“れらを書ãæ›ãˆã¦ã¯ãªã‚‰ãªã„:
+\begin{cslist}
+\item[size]
+実際ã«ä½¿ã‚れるフォントサイズ(spå˜ä½ï¼‰ï¼Ž$1\,\mathrm{sp}=2^{-16}\,\mathrm{pt}$.
+\item[zw\textrm{, }zh\textrm{, }kanjiskip\textrm{, }xkanjiskip]
+JFMファイルã§æŒ‡å®šã•ã‚Œã¦ã„ã‚‹ãã‚Œãžã‚Œã®å€¤ã‚’フォントサイズã«åˆã‚ã›ã¦ã‚¹ã‚±ãƒ¼ãƒªãƒ³ã‚°ã—ãŸã‚‚ã®ã‚’
+spå˜ä½ã§æ ¼ç´ã—ã¦ã„る.
+\item[jfm]
+利用ã•ã‚Œã¦ã„ã‚‹JFMを識別ã™ã‚‹ãŸã‚ã®ç•ªå·ï¼Ž
+\item[var]
+\cs{jfont},~\cs{tfont} ã§æŒ‡å®šã•ã‚ŒãŸ \texttt{jfmvar} キーã®å€¤ï¼ˆæœªæŒ‡å®šã®ã¨ãã¯ç©ºæ–‡å­—列).
+\item[chars]
+文字コードã‹ã‚‰æ–‡å­—クラスã¸ã®å¯¾å¿œãŒè¨˜è¿°ã•ã‚ŒãŸãƒ†ãƒ¼ãƒ–ル.\\
+JFM内㮠\texttt{[i].chars=\{<character>, ...\}} ã¨ã„ã†æŒ‡å®šã¯\
+\texttt{chars=\{[<character>]=\,$i$, ...\}} ã¨ã„ã†å½¢å¼ã«å¤‰æ›ã•ã‚Œã¦ã„る.
+\item[char\_type]
+$i\in\omega$ã«å¯¾ã—ã¦ï¼Œ\texttt{char\_type[$i$]} ã¯æ–‡å­—クラス$i$ã®æ–‡å­—ã®å¯¸æ³•ã‚’æ ¼ç´ã—ã¦ãŠã‚Šï¼Œ
+以下ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’æŒã¤ï¼Ž
+\begin{itemize}
+ \item \texttt{width},~\texttt{height}, \texttt{depth},
+ \texttt{italic}, \texttt{down},~\texttt{left}\ ã¯
+JFMã§æŒ‡å®šã•ã‚Œã¦ã„ã‚‹ãã‚Œãžã‚Œã®å€¤ã‚’スケーリングã—ãŸã‚‚ã®ã§ã‚る.
+ \item \texttt{align} ã¯JFMã§æŒ‡å®šã•ã‚Œã¦ã„る値ã«ã‚ˆã£ã¦ï¼Œ
+\[
+ \begin{cases}
+ 0&\text{\texttt{'left'}ã‚„çœç•¥æ™‚}\\0.5&\text{\tt 'middle'}\\1&\text{\tt 'right'}
+ \end{cases}
+\]
+ã®ã„ãšã‚Œã‹ã®å€¤ã‚’ã¨ã‚‹ï¼Ž
+\end{itemize}
+$i$,~$j\in \omega$ã«å¯¾ã—ã¦ï¼Œ\texttt{char\_type[$i$][$j$]} ã¯
+文字クラス$i$ã®æ–‡å­—ã¨$j$ã®æ–‡å­—ã®é–“ã«æŒ¿å…¥ã•ã‚Œã‚‹ã‚°ãƒ«ãƒ¼ã‚„カーンを格ç´ã—ã¦ã„る.
+\begin{itemize}
+ \item é–“ã«å…¥ã‚‹ã‚‚ã®ãŒã‚«ãƒ¼ãƒ³ã§ã‚ã‚Œã°ï¼Œã“ã®å€¤ã¯\
+\texttt{[$j$]=\{[1]=<kern\_node>, ratio=<ratio>\}} ã§ã‚り,
+<kern\_node>ã¯ã‚«ãƒ¼ãƒ³ã‚’表ã™ãƒŽãƒ¼ãƒ‰ã§ã‚ã‚‹\footnote{%
+ ãƒãƒ¼ã‚¸ãƒ§ãƒ³20150420.0以é™ã§ã¯ãƒŽãƒ¼ãƒ‰ã®ã‚¢ã‚¯ã‚»ã‚¹æ‰‹æ³•ã«direct access
+ modelを用ã„ã¦ã„ã‚‹ãŸã‚,ノードãã®ã‚‚ã®ã‚’表ã™ãƒ¦ãƒ¼ã‚¶ãƒ¼ãƒ‡ãƒ¼ã‚¿ã§ã¯ãªã,
+ 内部ã§å‚ç…§ã®ãŸã‚ã«ä½¿ã‚れる添字(整数)ã§ã‚る.
+}.
+ \item グルーã§ã‚ã‚Œã°ï¼Œã“ã®å€¤ã¯ä»¥ä¸‹ã®ã‚­ãƒ¼ã‚’æŒã¤ãƒ†ãƒ¼ãƒ–ルã§ã‚る.
+ \begin{description}
+ \item[\texttt{width}, \texttt{stretch}, \texttt{shrink}]
+ グルーã®ãã‚Œãžã‚Œè‡ªç„¶é•·ï¼Œä¼¸ã³é‡ï¼Œç¸®ã¿é‡ã‚’spå˜ä½ã§è¡¨ã—ãŸã‚‚ã®ï¼Ž
+ \item[\texttt{priority}] ãƒï¼ˆãƒ¼ã‚¸ãƒ§ãƒ³2以é™ã®ï¼‰JFMã§ã®æŒ‡å®š \texttt{\{<stretch>,<shrink>\}} ã‚’
+ \[
+ (\text{<stretch>}+4)\cdot 8+\text{<shrink>}+4
+ \]
+ ã¨ã—ã¦0--63ã®æ•´æ•°ã«ãƒ‘ックã—ãŸã‚‚ã®ï¼Ž
+ \item[\texttt{ratio}, \texttt{kanjiskip\_natural}, \texttt{kanjiskip\_stretch}, \texttt{kanjiskip\_shrink}]
+ JFM中ã®åŒåã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã®å€¤ãŒãã®ã¾ã¾ä½¿ã‚ã‚Œã¦ã„る.
+ \end{description}
+\end{itemize}
+\item[ascent\textrm{, }descent]
+ 縦組時ã«å€‹ã€…ã®ã‚°ãƒªãƒ•ã‚’90度回転ã•ã›ã‚‹å ´åˆï¼Œãã®ã‚°ãƒªãƒ•ã¯ï¼ˆå®Ÿéš›ã®é«˜ã•ãƒ»æ·±ã•ã«ã‹ã‹ã‚らãšï¼‰
+ 便宜的ã«é«˜ã•\texttt{ascent},深ã•\texttt{descent}ã‚’æŒã¤ã‚‚ã®ã ã¨æƒ³å®šã—ã¦å›žè»¢ã•ã›ã‚‹ï¼Ž
+ ã“ã®ä»•æ§˜ã¯\Pkg{luaotfload}ãŒOpenTypeフォントã®VORGテーブルを読ã¾ãªã„ãŸã‚ã®æš«å®šçš„ãªã‚‚ã®ã§ã‚る.
+\item[chars\_cbcache]
+文字クラス決定ã®å‡¦ç†ã§ï¼Žã‚­ãƒ£ãƒƒã‚·ãƒ¥ã¨ã—ã¦ä½¿ã‚れる.
+\end{cslist}
+%</ja>
+
+%<*en>
+The returned table \verb+new_jfont_info+ also should include these fields, but
+you are free to add more fields (to use them in the \texttt{luatexja.find\_char\_class} callback).
+The \verb+font_number+ is a font number.
+%</en>
+%<*ja>
+戻り値㮠\verb+new_jfont_info+ テーブルも上ã«è¿°ã¹ãŸãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ãã®ã¾ã¾å«ã¾ãªã‘ã‚Œã°ãªã‚‰ãªã„ãŒï¼Œ
+ãれ以外ã«ãƒ¦ãƒ¼ã‚¶ãŒå‹æ‰‹ã«ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’付ã‘加ãˆã‚‹ã“ã¨ã¯è‡ªç”±ã§ã‚る.
+\verb+font_number+ ã¯ãƒ•ã‚©ãƒ³ãƒˆç•ªå·ã§ã‚る.
+%</ja>
+
+%<*en>
+A good example of this and the next callbacks is the \Pkg{luatexja-otf}
+ package, supporting \verb+"AJ1-xxx"+ form for Adobe-Japan1
+ CID characters in a JFM. This callback doesn't replace any
+ code of \LuaTeX-ja.
+%</en>
+%<*ja>
+ã“ã‚Œã¨æ¬¡ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã®è‰¯ã„使用例ã¯\Pkg{luatexja-otf}パッケージã§ã‚り,
+JFM中ã§Adobe-Japan1 CIDã®æ–‡å­—ã‚’ \verb+"AJ1-xxx"+ ã®å½¢ã§æŒ‡å®šã™ã‚‹ãŸã‚ã«
+用ã„られã¦ã„る.
+%</ja>
+
+%<en>\item[\texttt{luatexja.find\_char\_class} callback]
+%<ja>\item[\texttt{luatexja.find\_char\_class}コールãƒãƒƒã‚¯]
+%<*en>
+This callback is called just when \LuaTeX-ja is trying to determine which
+ character class a character \verb+chr_code+ belongs.
+A function used in this callback should be in the following form:
+%</en>
+%<*ja>
+ã“ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯\LuaTeX-ja㌠\verb+chr_code+ ã®æ–‡å­—ãŒã©ã®æ–‡å­—クラスã«
+属ã™ã‚‹ã‹ã‚’決定ã—よã†ã¨ã™ã‚‹éš›ã«å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Ž
+ã“ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã§å‘¼ã³å‡ºã•ã‚Œã‚‹é–¢æ•°ã¯æ¬¡ã®å½¢ã‚’ã—ã¦ã„ãªã‘ã‚Œã°ãªã‚‰ãªã„:
+%</ja>
+\begin{lstlisting}[numbers=left]
+function (<number> char_class, <table> jfont_info, <number> chr_code)
+ if char_class~=0 then return char_class
+ else
+ ....
+ return (<number> new_char_class or 0)
+ end
+end
+\end{lstlisting}
+
+%<*en>
+The argument \verb+char_class+ is the result of \LuaTeX-ja's default
+ routine or previous function calls in this callback, hence
+ this argument may not be 0. Moreover, the returned
+ \verb+new_char_class+ should be as same as \verb+char_class+ when \verb+char_class+
+ is not~0, otherwise you will overwrite the \LuaTeX-ja's
+ default routine.
+%</en>
+%<*ja>
+引数 \verb+char_class+ ã¯\LuaTeX-jaã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãƒ«ãƒ¼ãƒãƒ³ã‹ï¼Œã“ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã®
+ç›´å‰ã®é–¢æ•°å‘¼ã³å‡ºã—ã®çµæžœã‚’å«ã‚“ã§ãŠã‚Šï¼Œã—ãŸãŒã£ã¦ã“ã®å€¤ã¯0ã§ã¯ãªã„ã‹ã‚‚ã—ã‚Œãªã„.
+ã•ã‚‰ã«ï¼Œæˆ»ã‚Šå€¤ã® \verb+new_char_class+ 㯠\verb+char_class+ ãŒéžé›¶ã®ã¨ãã«ã¯
+\verb+char_class+ ã®å€¤ã¨åŒã˜ã§ã‚ã‚‹ã¹ãã§ï¼Œãã†ã§ãªã„ã¨ãã¯\LuaTeX-jaã®
+デフォルトルーãƒãƒ³ã‚’書ãæ›ãˆã‚‹ã“ã¨ã«ãªã‚‹ï¼Ž
+%</ja>
+
+%<en>\item[\texttt{luatexja.set\_width} callback]
+%<ja>\item[\texttt{luatexja.set\_width}コールãƒãƒƒã‚¯]
+%<*en>
+This callback is called when \LuaTeX-ja is trying to encapsule a
+ \textbf{JAchar} \textit{glyph\_node}, to adjust its
+ dimension and position.
+%</en>
+%<*ja>
+ã“ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯\LuaTeX-jaãŒ\textbf{JAchar}ã®å¯¸æ³•ã¨ä½ç½®ã‚’調節ã™ã‚‹ãŸã‚ã«
+ãã®\textit{glyph\_node}をカプセル化ã—よã†ã¨ã™ã‚‹éš›ã«å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Ž
+%</ja>
+\begin{lstlisting}[numbers=left]
+function (<table> shift_info, <table> jfont_info, <table> char_type)
+ return <table> new_shift_info
+end
+\end{lstlisting}
+
+%<*en>
+The argument \verb+shift_info+ and the returned \verb+new_shift_info+ have
+\texttt{down} and \texttt{left} fields, which are the amount of shifting
+ down/left the character in a scaled point.
+%</en>
+%<*ja>
+引数 \verb+shift_info+ ã¨æˆ»ã‚Šå€¤ã® \verb+new_shift_info+ ã¯
+\texttt{down}ã¨\texttt{left}ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’æŒã¡ï¼Œã“れらã®å€¤ã¯
+文字ã®ä¸‹ï¼å·¦ã¸ã®ã‚·ãƒ•ãƒˆé‡ï¼ˆspå˜ä½ï¼‰ã§ã‚る.
+%</ja>
+
+%<*en>
+A good example is \Pkg{test/valign.lua}.
+After loading this file, the vertical position of glyphs is automatically
+adjusted; the ratio $(\hbox{height}:\hbox{depth})$ of glyphs is adjusted
+to be that of letters in the character class~0. For example, suppose that
+\begin{itemize}
+\item The setting of the JFM: $(\hbox{height})=88x$, $(\hbox{depth})=12x$
+ (the standard values of Japanese OpenType fonts);
+\item The value of the real font: $(\hbox{height})=28y$, $(\hbox{depth})=5y$
+ (the standard values of Japanese TrueType fonts).
+\end{itemize}
+Then, the position of glyphs is shifted up by
+%</en>
+%<*ja>
+良ã„例ãŒ\Pkg{test/valign.lua}ã§ã‚る.ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ãŒèª­ã¿è¾¼ã¾ã‚ŒãŸçŠ¶æ…‹ã§ã¯ï¼Œ
+ JFM内ã§è¦å®šã•ã‚ŒãŸæ–‡å­—クラス0ã®æ–‡å­—ã«ãŠã‘ã‚‹$(\hbox{高
+ ã•}):(\hbox{æ·±ã•})$ã®æ¯”ã«ãªã‚‹ã‚ˆã†ã«ï¼Œå®Ÿéš›ã®ãƒ•ã‚©ãƒ³ãƒˆã®å‡ºåŠ›ä¸Š
+ 下ä½ç½®ãŒè‡ªå‹•èª¿æ•´ã•ã‚Œã‚‹ï¼Žä¾‹ãˆã°ï¼Œ
+\begin{itemize}
+\item JFMå´ã®è¨­å®šï¼š$(\hbox{高ã•})=88x$, $(\hbox{æ·±ã•})=12x$%
+(和文OpenTypeフォントã®æ¨™æº–値)
+\item 実フォントå´ã®æ•°å€¤ï¼š$(\hbox{高ã•})=28y$, $(\hbox{æ·±ã•})=5y$(和文TrueTypeフォントã®æ¨™æº–値)
+\end{itemize}
+ã¨ãªã£ã¦ã„ãŸã¨ã™ã‚‹ï¼Žã™ã‚‹ã¨ï¼Œå®Ÿéš›ã®æ–‡å­—ã®å‡ºåŠ›ä½ç½®ã¯ï¼Œä»¥ä¸‹ã®é‡ã ã‘上ã«ãšã‚‰ã•ã‚Œã‚‹ã“ã¨ã¨ãªã‚‹ï¼š
+%</ja>
+\[
+ \frac{88x}{88x+12x} (28y+5y) - 28y = \frac{26}{25}y= 1.04y.
+\]
+\end{description}
+
+%<en>\section{Parameters}
+%<ja>\section{パラメータ}
+\subsection{\cs{ltjsetparameter}}
+\label{ssec:param}
+
+%<*en>
+As described before, \cs{ltjsetparameter} and \cs{ltjgetparameter} are
+commands for accessing most parameters of \LuaTeX-ja. One of the main
+reason that \LuaTeX-ja didn't adopted the syntax similar to that of \pTeX\
+(\textit{e.g.},~\verb+\prebreakpenalty`)=10000+)
+is the position of \verb+hpack_filter+ callback in the source
+of \LuaTeX, see Section~\ref{sec-para}.
+%</en>
+%<*ja>
+å…ˆã«è¿°ã¹ãŸã‚ˆã†ã«ï¼Œ\LuaTeX-jaã®å†…部パラメータã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯
+\cs{ltjsetparameter}(ã¾ãŸã¯ \cs{ltjglobalsetparameter})㨠\cs{ltjgetparameter} を用ã„る.
+\LuaTeX-jaãŒ\pTeX ã®ã‚ˆã†ãªæ–‡æ³•ï¼ˆä¾‹ãˆã°ï¼Œ\verb+\prebreakpenalty`)=10000+)を
+採用ã—ãªã„ç†ç”±ã®ä¸€ã¤ã¯ï¼Œ\LuaTeX ã®ã‚½ãƒ¼ã‚¹ã«ãŠã‘ã‚‹ \verb+hpack_filter+
+コールãƒãƒƒã‚¯ã®ä½ç½®ã«ã‚る.\ref{sec-para}ç« ã‚’å‚照.
+%</ja>
+
+%<*en>
+\cs{ltjsetparameter} and \cs{ltjglobalsetparameter} are commands
+for assigning parameters. These take one argument which is a
+\texttt{<key>=<value>} list.
+The difference between these two commands is the
+scope of assignment;
+\cs{ltjsetparameter} does a local assignment and
+\cs{ltjglobalsetparameter} does a global one.
+They also obey the value of \cs{globaldefs}, like other assignments.
+%</en>
+%<*ja>
+\cs{ltjsetparameter} 㨠\cs{ltjglobalsetparameter} ã¯ãƒ‘ラメータを
+指定ã™ã‚‹ãŸã‚ã®å‘½ä»¤ã§ï¼Œ\texttt{<key>=<value>}ã®ãƒªã‚¹ãƒˆã‚’
+引数ã¨ã—ã¦ã¨ã‚‹ï¼Žä¸¡è€…ã®é•ã„ã¯ã‚¹ã‚³ãƒ¼ãƒ—ã§ã‚り,
+\cs{ltjsetparameter} ã¯ãƒ­ãƒ¼ã‚«ãƒ«ãªè¨­å®šã‚’è¡Œã†ã®ã«å¯¾ã—,
+\cs{ltjglobalsetparameter} ã¯ã‚°ãƒ­ãƒ¼ãƒãƒ«ãªè¨­å®šã‚’è¡Œã†ï¼Ž
+ã¾ãŸï¼Œä»–ã®ãƒ‘ラメータ指定ã¨åŒæ§˜ã« \cs{globaldefs} ã®å€¤ã«ã‚‚従ã†ï¼Ž
+%</ja>
+
+%<*en>
+The following is the list of parameters which can be specified by the
+\cs{ltjsetparameter} command. [\cs{cs}] indicates the counterpart
+in \pTeX, and symbols beside each parameter has the following meaning:
+%</en>
+%<*ja>
+以下㯠\cs{ltjsetparameter} ã«æŒ‡å®šã™ã‚‹ã“ã¨ãŒã§ãるパラメータã®ä¸€è¦§ã§ã‚る.
+[\cs{cs}]ã¯\pTeX ã«ãŠã‘る対応物を示ã™ï¼Ž
+ã¾ãŸï¼Œãã‚Œãžã‚Œã®ãƒ‘ラメータã®å³ä¸Šã®è¨˜å·ã«ã¯æ¬¡ã®æ„味ãŒã‚る:
+%</ja>
+\begin{itemize}
+%<*en>
+\item ``$\ast$'' : values at the end of a paragraph or a hbox are
+adopted in the whole paragraph or the whole hbox.
+%</en>
+%<*ja>
+\item ``$\ast$'':段è½ã‚„hboxã®çµ‚端ã§ã®å€¤ãŒãã®æ®µè½ï¼hbox全体ã§ç”¨ã„られる.
+%</ja>
+%<*en>
+\item ``\dagger'': assignments are always global.
+%</en>
+%<*ja>
+\item ``\dagger'':指定ã¯å¸¸ã«ã‚°ãƒ­ãƒ¼ãƒãƒ«ã«ãªã‚‹ï¼Ž
+%</ja>
+\end{itemize}
+
+\begin{cslist}[style=standard]
+\item[\DParam{jcharwidowpenalty}\,=<penalty>$^\ast$] [\cs{jcharwidowpenalty}]\
+
+%<*en>
+Penalty value for suppressing orphans. This penalty is inserted just
+ after the last \textbf{JAchar} which is not regarded as a
+ (Japanese) punctuation mark.
+%</en>
+%<*ja>
+パラグラフã®æœ€å¾Œã®å­—ãŒå­¤ç«‹ã—ã¦æ”¹è¡Œã•ã‚Œã‚‹ã®ã‚’防ããŸã‚ã®ãƒšãƒŠãƒ«ãƒ†ã‚£ã®å€¤ï¼Ž
+ã“ã®ãƒšãƒŠãƒ«ãƒ†ã‚£ã¯ï¼ˆæ—¥æœ¬èªžã®ï¼‰å¥èª­ç‚¹ã¨ã—ã¦æ‰±ã‚ã‚Œãªã„最後ã®\textbf{JAchar}ã®ç›´å¾Œã«
+挿入ã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+\item[\DParam{kcatcode}\,=\{<chr\_code>,<natural number>\}$^\ast$]\
+
+%<*en>
+An additional attributes which each character whose character code is <chr\_code> has.
+At version~20120506.0 or later, the lowermost bit of <natural number> indicates
+ whether the character is considered as a punctuation mark
+ (see the description of \Param{jcharwidowpenalty} above).
+%</en>
+%<*ja>
+文字コードãŒ<chr\_code>ã®æ–‡å­—ãŒæŒã¤ä»˜åŠ çš„ãªå±žæ€§å€¤ï¼Ž
+ãƒãƒ¼ã‚¸ãƒ§ãƒ³20120506.0以é™ã§ã¯ï¼Œ<natural number>ã®æœ€ä¸‹ä½ãƒ“ットãŒï¼Œãã®æ–‡å­—ãŒå¥èª­ç‚¹ã¨
+ã¿ãªã•ã‚Œã‚‹ã‹ã©ã†ã‹ã‚’表ã—ã¦ã„る(上ã®\Param{jcharwidowpenalty}ã®è¨˜è¿°ã‚’å‚照).
+%</ja>
+
+\item[\DParam{prebreakpenalty}\,=\{<chr\_code>,<penalty>\}$^\ast$] [\cs{prebreakpenalty}]\
+
+%<*ja>
+文字コード<chr\_code>ã®\textbf{JAchar}ãŒè¡Œé ­ã«ãã‚‹ã“ã¨ã‚’抑止ã™ã‚‹ãŸã‚ã«ï¼Œ
+ ã“ã®æ–‡å­—ã®å‰ã«æŒ¿å…¥/追加ã•ã‚Œã‚‹ãƒšãƒŠãƒ«ãƒ†ã‚£ã®é‡ã‚’指定ã™ã‚‹ï¼Ž
+
+例ãˆã°é–‰ã˜æ‹¬å¼§ã€Œã€—ã€ã¯çµ¶å¯¾ã«è¡Œé ­ã«ãã¦ã¯ãªã‚‰ãªã„ã®ã§ï¼Œ
+\begin{lstlisting}
+\ltjsetparameter{prebreakpenalty={`〙,10000}}
+\end{lstlisting}
+ã¨ï¼Œæœ€å¤§å€¤ã®10000ãŒæ¨™æº–ã§æŒ‡å®šã•ã‚Œã¦ã„る.他ã«ã‚‚,å°æ›¸ãã®ã‚«ãƒŠãªã©ï¼Œçµ¶å¯¾ç¦æ­¢ã¨ã„
+ ã†ã‚ã‘ã§ã¯ãªã„ãŒã§ãã‚Œã°è¡Œé ­ã«ã¯ãã¦æ¬²ã—ããªã„å ´åˆã«ï¼Œ0ã¨
+ 10000ã®é–“ã®å€¤ã‚’指定ã™ã‚‹ã®ã‚‚有用ã§ã‚ã‚ã†ï¼Ž
+
+\pTeX ã§ã¯ï¼Œ\cs{prebreakpenalty}, \cs{postbreakpenalty}ã«ãŠã„ã¦ï¼Œ
+\begin{itemize}
+\item 一ã¤ã®æ–‡å­—ã«å¯¾ã—ã¦ï¼Œpre, postã©ã¡ã‚‰ã‹ä¸€ã¤ã—ã‹æŒ‡å®šã™ã‚‹ã“ã¨ãŒã§ããªã„%
+ \footnote{後ã‹ã‚‰æŒ‡å®šã—ãŸæ–¹ã§ä¸Šæ›¸ãã•ã‚Œã‚‹ï¼Ž}
+\item pre, poståˆã‚ã›ã¦256文字分ã®æƒ…報を格ç´ã™ã‚‹ã“ã¨ã—ã‹ã§ããªã„
+\end{itemize}
+ã¨ã„ã†åˆ¶é™ãŒã‚ã£ãŸãŒï¼Œ\LuaTeX-jaã§ã¯ã“れらã®åˆ¶é™ã¯è§£æ¶ˆã•ã‚Œã¦ã„る.
+%</ja>
+%<*en>
+Set a penalty which is inserted automatically before the character <chr\_code>,
+to prevent a line starts from this character. For example, a line cannot started
+with one of closing brackets ``〗'', so \LuaTeX-ja sets
+\begin{lstlisting}
+\ltjsetparameter{prebreakpenalty={`〙,10000}}
+\end{lstlisting}
+by default.
+
+\pTeX\ has following restrictions on \cs{prebreakpenalty} and \cs{postbreakpenalty},
+but they don't exist in \LuaTeX-ja:
+\begin{itemize}
+ \item Both \cs{prebreakpenalty} and \cs{postbreakpenalty} cannot be set
+for the same character.
+ \item We can set \cs{prebreakpenalty} and \cs{postbreakpenalty} up to 256~characters.
+\end{itemize}
+%</en>
+
+\item[\DParam{postbreakpenalty}\,=\{<chr\_code>,<penalty>\}$^\ast$]
+ [\cs{postbreakpenalty}]\
+
+%<*ja>
+文字コード<chr\_code>ã®\textbf{JAchar}ãŒè¡Œæœ«ã«ãã‚‹ã“ã¨ã‚’抑止ã™ã‚‹ãŸã‚ã«ï¼Œ
+ ã“ã®æ–‡å­—ã®å¾Œã«æŒ¿å…¥/追加ã•ã‚Œã‚‹ãƒšãƒŠãƒ«ãƒ†ã‚£ã®é‡ã‚’指定ã™ã‚‹ï¼Ž
+%</ja>
+%<*en>
+Set a penalty which is inserted automatically after the character <chr\_code>,
+to prevent a line ends with this character.
+%</en>
+
+\item[\DParam{jatextfont}\,=\{<jfam>,<jfont\_cs>\}$^\ast$]
+%<en>[\cs{textfont} in \TeX]
+%<ja>[\TeX ã® \cs{textfont}]
+\item[\DParam{jascriptfont}\,=\{<jfam>,<jfont\_cs>\}$^\ast$]
+%<en>[\cs{scriptfont} in \TeX]
+%<ja>[\TeX ã® \cs{scriptfont}]
+\item[\DParam{jascriptscriptfont}\,=\{<jfam>,<jfont\_cs>\}$^\ast$]
+%<en>[\cs{scriptscriptfont} in \TeX]
+%<ja>[\TeX ã® \cs{scriptscriptfont}]
+\item[\DParam{yjabaselineshift}\,=<dimen>]\
+\item[\DParam{yalbaselineshift}\,=<dimen>] [\cs{ybaselineshift}]
+\item[\DParam{tjabaselineshift}\,=<dimen>]\
+\item[\DParam{talbaselineshift}\,=<dimen>] [\cs{tbaselineshift}]
+
+\item[\DParam{jaxspmode}\,=\{<chr\_code>,<mode>\}$^\ast$]\
+
+%<*en>
+Set whether inserting \Param{xkanjiskip} is allowed before/after a \textbf{JAchar} whose character code is <chr\_code>.
+The followings are allowed for <mode>:
+%</en>
+%<*ja>
+文字コードãŒ<chr\_code>ã®\textbf{JAchar}ã®å‰ï¼å¾Œã‚ã«\Param{xkanjiskip}ã®
+挿入を許ã™ã‹ã©ã†ã‹ã®è¨­å®šï¼Ž
+以下ã®<mode>ãŒè¨±ã•ã‚Œã‚‹ï¼š
+%</ja>
+\begin{description}
+%<en>\item[0, \texttt{inhibit}] Insertion of \Param{xkanjiskip} is inhibited before the character, nor after the character.
+%<ja>\item[0, \texttt{inhibit}] \Param{xkanjiskip}ã®æŒ¿å…¥ã¯æ–‡å­—ã®å‰ï¼å¾Œã‚ã®ã„ãšã‚Œã§ã‚‚ç¦æ­¢ã•ã‚Œã‚‹ï¼Ž
+%<en>\item[1, \texttt{preonly}] Insertion of \Param{xkanjiskip} is allowed before the character, but not after.
+%<ja>\item[1, \texttt{preonly}] \Param{xkanjiskip}ã®æŒ¿å…¥ã¯æ–‡å­—ã®å‰ã§ã¯è¨±ã•ã‚Œã‚‹ãŒï¼Œå¾Œã‚ã§ã¯è¨±ã•ã‚Œãªã„.
+%<en>\item[2, \texttt{postonly}] Insertion of \Param{xkanjiskip} is allowed after the character, but not before.
+%<ja>\item[2, \texttt{postonly}] \Param{xkanjiskip}ã®æŒ¿å…¥ã¯æ–‡å­—ã®å¾Œã‚ã§ã¯è¨±ã•ã‚Œã‚‹ãŒï¼Œå‰ã§ã¯è¨±ã•ã‚Œãªã„.
+%<en>\item[3, \texttt{allow}] Insertion of \Param{xkanjiskip} is allowed both before the character and after the character. This is the default value.
+%<ja>\item[3, \texttt{allow}] \Param{xkanjiskip}ã®æŒ¿å…¥ã¯æ–‡å­—ã®å‰ï¼å¾Œã‚ã®ã„ãšã‚Œã§ã‚‚許ã•ã‚Œã‚‹ï¼Žã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®å€¤ã§ã‚る.
+\end{description}
+%<*en>
+This parameter is similar to the \cs{inhibitxspcode} primitive of \pTeX, but not compatible with \cs{inhibitxspcode}.
+%</en>
+%<*ja>
+ã“ã®ãƒ‘ラメータã¯\pTeX ã® \cs{inhibitxspcode} プリミティブã¨ä¼¼ã¦ã„ã‚‹ãŒï¼Œ
+互æ›æ€§ã¯ãªã„.
+%</ja>
+\item[\DParam{alxspmode}\,=\{<chr\_code>,<mode>\}$^\ast$] [\cs{xspcode}]\
+
+%<*en>
+Set whether inserting \Param{xkanjiskip} is allowed before/after a
+ \textbf{ALchar} whose character code is <chr\_code>.
+ The followings are allowed for <mode>:
+%</en>
+%<*ja>
+文字コードãŒ<chr\_code>ã®\textbf{ALchar}ã®å‰ï¼å¾Œã‚ã«\Param{xkanjiskip}ã®
+挿入を許ã™ã‹ã©ã†ã‹ã®è¨­å®šï¼Ž
+以下ã®<mode>ãŒè¨±ã•ã‚Œã‚‹ï¼š
+%</ja>
+\begin{description}
+%<en>\item[0, \texttt{inhibit}] Insertion of \Param{xkanjiskip} is inhibited before the character, nor after the character.
+%<ja>\item[0, \texttt{inhibit}] \Param{xkanjiskip}ã®æŒ¿å…¥ã¯æ–‡å­—ã®å‰ï¼å¾Œã‚ã®ã„ãšã‚Œã§ã‚‚ç¦æ­¢ã•ã‚Œã‚‹ï¼Ž
+%<en>\item[1, \texttt{preonly}] Insertion of \Param{xkanjiskip} is allowed before the character, but not after.
+%<ja>\item[1, \texttt{preonly}] \Param{xkanjiskip}ã®æŒ¿å…¥ã¯æ–‡å­—ã®å‰ã§ã¯è¨±ã•ã‚Œã‚‹ãŒï¼Œå¾Œã‚ã§ã¯è¨±ã•ã‚Œãªã„.
+%<en>\item[2, \texttt{postonly}] Insertion of \Param{xkanjiskip} is allowed after the character, but not before.
+%<ja>\item[2, \texttt{postonly}] \Param{xkanjiskip}ã®æŒ¿å…¥ã¯æ–‡å­—ã®å¾Œã‚ã§ã¯è¨±ã•ã‚Œã‚‹ãŒï¼Œå‰ã§ã¯è¨±ã•ã‚Œãªã„.
+%<en>\item[3, \texttt{allow}] Insertion of \Param{xkanjiskip} is allowed before the character and after the character. This is the default value.
+%<ja>\item[3, \texttt{allow}] \Param{xkanjiskip}ã®æŒ¿å…¥ã¯æ–‡å­—ã®å‰ï¼å¾Œã‚ã®ã„ãšã‚Œã§ã‚‚許ã•ã‚Œã‚‹ï¼Žã“ã‚ŒãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®å€¤ã§ã‚る.
+\end{description}
+%<*en>
+Note that parameters \Param{jaxspmode} and \Param{alxspmode} share a common table, hence these two parameters are synonyms of each other.
+%</en>
+%<*ja>
+\Param{jaxspmode}ã¨\Param{alxspmode}ã¯å…±é€šã®ãƒ†ãƒ¼ãƒ–ルを用ã„ã¦ã„ã‚‹ãŸã‚,
+ã“れら2ã¤ã®ãƒ‘ラメータã¯äº’ã„ã®åˆ¥åã¨ãªã£ã¦ã„ã‚‹ã“ã¨ã«æ³¨æ„ã™ã‚‹ï¼Ž
+%</ja>
+
+\item[\DParam{autospacing}\,=<bool>] [\cs{autospacing}]
+\item[\DParam{autoxspacing}\,=<bool>] [\cs{autoxspacing}]
+\item[\DParam{kanjiskip}\,=<skip>$^\ast$] [\cs{kanjiskip}]\
+
+%<*ja>
+デフォルトã§2ã¤ã®\textbf{JAchar}ã®é–“ã«æŒ¿å…¥ã•ã‚Œã‚‹ã‚°ãƒ«ãƒ¼ã§ã‚る.
+通常ã§ã¯ï¼Œ\pTeX ã¨åŒã˜ã‚ˆã†ã«ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã«æ¯”例ã—ã¦å¤‰ã‚ã‚‹ã“ã¨ã¯ãªã„.
+ã—ã‹ã—,自然長㌠\cs{maxdimen} ã®å ´åˆã¯ï¼Œä¾‹å¤–çš„ã«å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®JFMå´ã§æŒ‡å®šã•ã‚Œã¦ã„ã‚‹
+値を採用(ã“ã¡ã‚‰ã¯ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã«æ¯”例)ã™ã‚‹ã“ã¨ã«ãªã£ã¦ã„る.
+%</ja>
+%<*en>
+The default glue which inserted between two \textbf{JAchar}s.
+Changing current Japanese font does not alter this parameter, as \pTeX.
+
+If the natural width of this parameter is \cs{maxdimen}, \LuaTeX-ja uses
+the value which is specified in the JFM for current Japanese font (See Subsection~\ref{ssec:jfm-str}).
+%</en>
+
+\item[\DParam{xkanjiskip}\,=<skip>$^\ast$] [\cs{xkanjiskip}]\
+
+%<*ja>
+デフォルトã§\textbf{JAchar}ã¨\textbf{ALchar}ã®é–“ã«æŒ¿å…¥ã•ã‚Œã‚‹ã‚°ãƒ«ãƒ¼ã§ã‚る.
+\Param{kanjiskip}ã¨åŒã˜ã‚ˆã†ã«ï¼Œé€šå¸¸ã§ã¯ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã«æ¯”例ã—ã¦å¤‰ã‚ã‚‹ã“ã¨ã¯ãªã„ãŒï¼Œ
+自然長㌠\cs{maxdimen} ã®å ´åˆãŒä¾‹å¤–ã§ã‚る.
+%</ja>
+%<*en>
+The default glue which inserted between a \textbf{JAchar} and an
+ \textbf{ALchar}.
+Changing current font does not alter this parameter, as \pTeX.
+
+As \Param{kanjiskip}, if the natural width of this parameter is \cs{maxdimen}, \LuaTeX-ja uses
+the value which is specified in the JFM for current Japanese font (See Subsection~\ref{ssec:jfm-str}).
+%</en>
+
+
+\item[\DParam{differentjfm}\,=<mode>$^\dagger$]\
+
+%<*en>
+Specify how glues/kerns between two \textbf{JAchar}s whose JFM (or size) are different.
+The allowed arguments are the followings:
+%</en>
+%<*ja>
+JFM(もã—ãã¯ã‚µã‚¤ã‚ºï¼‰ãŒç•°ãªã‚‹2ã¤ã®\textbf{JAchar}ã®é–“ã«ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ã‚’ã©ã®ã‚ˆã†ã«
+入れるã‹ã‚’指定ã™ã‚‹ï¼Ž
+許ã•ã‚Œã‚‹å€¤ã¯ä»¥ä¸‹ã®é€šã‚Šï¼š
+%</ja>
+\begin{quote}
+\texttt{average},
+\texttt{both},
+\texttt{large},
+\texttt{small},
+\texttt{pleft},
+\texttt{pright},
+\texttt{paverage}
+\end{quote}
+%<*en>
+The default value is \texttt{paverage}. \dots
+%</en>
+%<*ja>
+デフォルト値㯠\texttt{paverage} ã§ã‚る.
+å„々ã®å€¤ã«ã‚ˆã‚‹å·®ç•°ã®è©³ç´°ã¯\ref{ssec:cluster-wa}節ã®ã€Œã€Žå³ç©ºç™½ã€ã®ç®—出ã€ã‚’å‚ç…§ã—ã¦ã»ã—ã„.
+%</ja>
+
+\item[\DParam{jacharrange}\,=<ranges>]
+\item[\DParam{kansujichar}\,=\{<digit>, <chr\_code>\}$^\ast$] [\cs{kansujichar}]
+
+\item[\DParam{direction}\,=<dir>\ \hbox{\rm (always local)}]\
+
+%<*en>
+Assigning to this parameter has the same effect as
+\cs{yoko}~(if $\hbox{<dir>}=4$), \cs{tate}~(if $\hbox{<dir>}=3$),
+\cs{dtou}~(if $\hbox{<dir>}=1$) or \cs{utod}~(if $\hbox{<dir>}=11$).
+If the argument <dir> is not one of 4,~3, 1~nor~11,
+the behavior of this assignment is undefined.
+%</en>
+%<*ja>
+組方å‘を変更ã™ã‚‹ \cs{yoko}~(if $\hbox{<dir>}=4$), \cs{tate}~(if $\hbox{<dir>}=3$),
+\cs{dtou}~(if $\hbox{<dir>}=1$), \cs{utod}~(if $\hbox{<dir>}=11$) ã¨åŒã˜å½¹å‰²ã‚’æŒã¤ï¼Ž
+利用å¯èƒ½ãªçŠ¶æ³ã‚‚ã“れら4命令ã¨åŒä¸€ã§ã‚る.引数<dir>ãŒ4,~3, 1,~11ã®ã„ãšã‚Œã§ã‚‚ç„¡ã„ã¨ãã®
+動作ã¯æœªå®šç¾©ã§ã‚る.
+%</ja>
+
+\end{cslist}
+
+
+\subsection{\cs{ltjgetparameter}}
+\label{ssec:getpar}
+%<*en>
+\cs{ltjgetparameter} is a control sequence for acquiring parameters. It
+always takes a parameter name as first argument.
+%</en>
+%<*ja>
+\cs{ltjgetparameter} ã¯ãƒ‘ラメータã®å€¤ã‚’å–å¾—ã™ã‚‹ãŸã‚ã®å‘½ä»¤ã§ã‚り,
+常ã«ãƒ‘ラメータã®åå‰ã‚’第一引数ã«ã¨ã‚‹ï¼Ž
+%</ja>
+\begin{LTXexample}
+\ltjgetparameter{differentjfm},
+\ltjgetparameter{autospacing},
+\ltjgetparameter{kanjiskip},
+\ltjgetparameter{prebreakpenalty}{`)}.
+\end{LTXexample}
+
+%<*en>
+\emph{The return value of\/ \cs{ltjgetparameter} is
+always a string}, which is outputted by \texttt{tex.write()}.
+Hence any character other than space~``\texttt{\char32}''~(\texttt{U+0020}) has the category code
+12~(other), while the space has 10~(space).
+%</en>
+%<*ja>
+\emph{\cs{ltjgetparameter} ã®æˆ»ã‚Šå€¤ã¯å¸¸ã«æ–‡å­—列ã§ã‚る.}
+ã“ã‚Œã¯\texttt{tex.write()}ã«ã‚ˆã£ã¦å‡ºåŠ›ã—ã¦ã„ã‚‹ãŸã‚ã§ï¼Œç©ºç™½ã€Œ\texttt{\char32}ã€
+(\texttt{U+0020})を除ã„ãŸæ–‡å­—ã®ã‚«ãƒ†ã‚´ãƒªãƒ¼ã‚³ãƒ¼ãƒ‰ã¯å…¨ã¦12~(other)ã¨ãªã‚‹ï¼Ž
+一方,空白ã®ã‚«ãƒ†ã‚´ãƒªãƒ¼ã‚³ãƒ¼ãƒ‰ã¯10~(space)ã§ã‚る.
+%</ja>
+
+\begin{itemize}
+\item
+%<*en>
+If first argument is one of the
+following, no additional argument is needed.
+%</en>
+%<*ja>
+第1引数ãŒæ¬¡ã®ã„ãšã‚Œã‹ã®å ´åˆã«ã¯ï¼Œè¿½åŠ ã®å¼•æ•°ã¯å¿…è¦ãªã„.
+%</ja>
+\begin{quote}
+\sffamily
+jcharwidowpenalty, yjabaselineshift, yalbaselineshift, autospacing, autoxspacing,\\
+kanjiskip, xkanjiskip, differentjfm, direction
+\end{quote}
+%<*en>
+Note that \verb+\ltjgetparameter{autospacing}+~and~\verb+\ltjgetparameter{autoxspacing}+
+returns 1 or 0, not
+\texttt{true}~nor~\texttt{false}.
+%</en>
+%<*ja>
+\verb+\ltjgetparameter{autospacing}+ 㨠\verb+\ltjgetparameter{autoxspacing}+ ã¯ï¼Œ
+\texttt{true}ã‚„\texttt{false}ã‚’è¿”ã™ã®\emph{ã§ã¯ãªã},
+1ã‹0ã®ã„ãšã‚Œã‹ã‚’è¿”ã™ã“ã¨ã«æ³¨æ„,
+%</ja>
+
+\item
+%<*en>
+If first argument is one of the
+following, an additional argument---a character code, for example---is needed.
+%</en>
+%<*ja>
+第1引数ãŒæ¬¡ã®ã„ãšã‚Œã‹ã®å ´åˆã«ã¯ï¼Œã•ã‚‰ã«æ–‡å­—コードを第2引数ã¨ã—ã¦ã¨ã‚‹ï¼Ž
+%</ja>
+\begin{quote}
+\sffamily
+kcatcode, prebreakpenalty, postbreakpenalty, jaxspmode, alxspmode
+\end{quote}
+%<*en>
+\verb+\ltjgetparameter{jaxspmode}{...}+~and~\verb+\ltjgetparameter{alxspmode}{...}+
+returns 0,~1, 2,~or~3, instead of \texttt{preonly} etc.
+%</en>
+%<*ja>
+\verb+\ltjgetparameter{jaxspmode}{...}+ ã‚„ \verb+\ltjgetparameter{alxspmode}{...}+\
+ã¯ï¼Œ\texttt{preonly} ãªã©ã¨ã„ã£ãŸæ–‡å­—列ã§ã¯ãªã,0ã‹ã‚‰3ã¾ã§ã®å€¤ã‚’è¿”ã™ï¼Ž
+%</ja>
+
+\item
+%<*en>
+\verb+\ltjgetparameter{jacharrange}{+<range>\verb+}+ returns \texttt{0}
+if ``characters which belong to the character range~<range> are \textbf{JAchar}'',
+\texttt{1} if ``\dots~are \textbf{ALchar}''.
+Although there is no character range~$-1$, specifying $-1$ to <range> does not cause an
+ error (returns 1).
+%</en>
+%<*ja>
+\verb+\ltjgetparameter{jacharrange}{+<range>\verb+}+ ã¯ï¼Œ<range>ãŒ\textbf{JAchar}é”ã®
+範囲ãªã‚‰ã°0を,ãã†ã§ãªã‘ã‚Œã°1ã‚’è¿”ã™ï¼Žã€Œ$-1$番ã®æ–‡å­—範囲ã€ã¯å­˜åœ¨ã—ãªã„ãŒï¼Œ<range>ã«$-1$ã‚’
+指定ã—ã¦ã‚‚エラーã¯ç™ºç”Ÿã—ãªã„(1ã‚’è¿”ã™ï¼‰ï¼Ž
+%</ja>
+
+\item
+%<*en>
+For an integer~<digit> between 0~and~9,
+ \verb+\ltjgetparameter{kansujichar}{+<digit>\verb+}+ returns the character code
+of the result of \cs{kansuji}<digit>.
+%</en>
+%<*ja>
+0--9ã®æ•°<digit>ã«å¯¾ã—ã¦ï¼Œ
+\verb+\ltjgetparameter{kansujichar}{+<digit>\verb+}+ ã¯ï¼Œ\cs{kansuji}<digit>ã§å‡ºåŠ›ã•ã‚Œ
+ る文字ã®æ–‡å­—コードを返ã™ï¼Ž
+%</ja>
+
+\item
+%<*en>
+\verb+\ltjgetparameter{adjustdir}+ returns a integer which represents
+the direction of the surrounding vertical list.
+As \Param{direction}, the return value 1 means \emph{down-to-up} direction,
+3 means \emph{tate} direction (vertical typesetting),
+and 4 means \emph{yoko} direction (horizontal typesetting).
+%</en>
+%<*ja>
+\verb+\ltjgetparameter{adjustdir}+ ã¯ï¼Œå‘¨å›²ã®vboxã®çµ„æ–¹å‘(言ã„æ›ãˆã‚Œã°ï¼Œ
+\cs{vadjust} ã§ç”¨ã„られる組方å‘)を表ã™æ•°å€¤ã‚’è¿”ã™ï¼Ž
+\Param{direction}ã¨åŒæ§˜ã«ï¼Œ1㯠\cs{dtou} æ–¹å‘を,
+3ã¯ç¸¦çµ„ã¿ã‚’,4ã¯æ¨ªçµ„ã¿ã‚’表ã™ï¼Ž
+%</ja>
+
+\item
+%<*en>
+For an integer~<reg\_num> between 0~and~65535,
+\verb+\ltjgetparameter{boxdim}{+<reg\_num>\verb+}+ returns the direction of
+\cs{box}<reg\_num>. If this box register is void, the returned value is zero.
+%</en>
+%<*ja>
+0--65535ã®æ•°<reg\_num>ã«å¯¾ã—ã¦ï¼Œ
+\verb+\ltjgetparameter{boxdim}{+<reg\_num>\verb+}+ ã¯ï¼Œ\cs{box}<reg\_num>ã«
+æ ¼ç´ã•ã‚Œã¦ã„るボックスã®çµ„æ–¹å‘を表ã™ï¼Žã‚‚ã—ã“ã®ãƒ¬ã‚¸ã‚¹ã‚¿ãŒç©ºã®å ´åˆã¯ï¼Œ0ãŒè¿”ã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+\item
+%<*en>
+The following parameter names \emph{cannot be specified} in \cs{ltjgetparameter}.
+%</en>
+%<*ja>
+次ã®ãƒ‘ラメータåã‚’ \cs{ltjgetparameter} ã«æŒ‡å®šã™ã‚‹ã“ã¨ã¯ã§ããªã„.
+%</ja>
+\begin{quote}
+\sffamily
+jatextfont, jascriptfont, jascriptscriptfont, jacharrange
+\end{quote}
+
+\item
+%<*en>
+\verb+\ltjgetparameter{chartorange}{+<chr\_code>\verb+}+ returns
+the range number which <chr\_code> belongs to
+(although there is no parameter named ``chartorange'').
+
+If <chr\_code> is between 0 and 127, this <chr\_code> does not belong to
+any character range. In this case,
+ \verb+\ltjgetparameter{chartorange}{+<chr\_code>\verb+}+
+returns $-1$.
+
+Hence, one can know whether <chr\_code> is \textbf{JAchar} or not
+by the following:
+%</en>
+%<*ja>
+\verb+\ltjgetparameter{chartorange}{+<chr\_code>\verb+}+ ã«ã‚ˆã£ã¦
+<chr\_code>ã®å±žã™ã‚‹æ–‡å­—範囲ã®ç•ªå·ã‚’知るã“ã¨ãŒã§ãる.
+
+<chr\_code>ã«0--127ã®å€¤ã‚’指定ã—ãŸå ´åˆï¼ˆã“ã®ã¨ã,<chr\_code>ãŒå±žã™ã‚‹
+文字範囲ã¯å­˜åœ¨ã—ãªã„)ã¯$-1$ãŒè¿”る.
+
+ãã®ãŸã‚,<chr\_code>ãŒ\textbf{JAchar}ã‹\textbf{ALchar}ã‹ã¯
+次ã§çŸ¥ã‚‹ã“ã¨ãŒã§ãる:
+%</ja>
+\begin{quote}
+\ttfamily \verb+\ltjgetparameter{jacharrange}{\ltjgetparameter{chartorange}{+%
+ <chr\_code>\verb+}}+\\\null\hfill\verb+% 0 if JAchar, 1 if ALchar+
+\end{quote}
+
+%<*en>
+\item Because the returned value is string, the following conditionals do not work
+if \Param{kanjiskip} (or~\Param{xkanjiskip}) has the stretch part or the shrink part.
+\begin{lstlisting}
+\ifdim\ltjgetparameter{kanjiskip}>\z@ ... \fi
+\ifdim\ltjgetparameter{xkanjiskip}>\z@ ... \fi
+\end{lstlisting}
+The correct way is using a temporary register.
+\begin{lstlisting}
+\@tempskipa=\ltjgetparameter{kanjiskip} \ifdim\@tempskipa>\z@ ... \fi
+\@tempskipa=\ltjgetparameter{xkanjiskip}\ifdim\@tempskipa>\z@ ... \fi
+\end{lstlisting}
+%</en>
+%<*ja>
+\item 返り値ãŒæ–‡å­—列ã§ã‚ã‚‹ã“ã¨ã‹ã‚‰ï¼Œ\Param{kanjiskip}ã‚„\Param{xkanjiskip}を直接
+\ \cs{ifdim} を使ã£ã¦æ¯”較ã™ã‚‹ã“ã¨ã¯æœ›ã¾ã—ããªã„.伸ã³é‡ã‚„縮ã¿é‡ã‚’æŒã£ã¦ã„る時ã«ã¯ï¼Œ
+次ã¯ã‚¨ãƒ©ãƒ¼ã‚’発生ã•ã›ã‚‹ï¼š
+\begin{lstlisting}
+\ifdim\ltjgetparameter{kanjiskip}>\z@ ... \fi
+\ifdim\ltjgetparameter{xkanjiskip}>\z@ ... \fi
+\end{lstlisting}
+レジスタã«ä¸€æ—¦ä»£å…¥ã™ã‚‹ã®ãŒè‰¯ã„:
+\begin{lstlisting}
+\@tempskipa=\ltjgetparameter{kanjiskip} \ifdim\@tempskipa>\z@ ... \fi
+\@tempskipa=\ltjgetparameter{xkanjiskip}\ifdim\@tempskipa>\z@ ... \fi
+\end{lstlisting}
+%</ja>
+
+\end{itemize}
+
+
+%<*en>
+\subsection{Alternative Commands to \cs{ltjsetparameter}}
+The basic method to set parameters of \LuaTeX-ja is to use
+\cs{ltjsetparameter}~or~\cs{ltjglobalsetparameter}.
+However, these commands are slow, because they parse a key-value list,
+so several alternative commands are used in \LuaTeX-ja.
+\emph{This subsection is not for general \LuaTeX-ja users.}
+
+\paragraph{Setting \Param{kanjiskip}~or~\Param{xkanjiskip}}
+In \Pkg{ltjsclasses}, every size-changing command such as \cs{Large}
+changes \cs{kanjiskip}~and~\cs{xkanjiskip}.
+But a simple implementation, as the code below, is slow since
+two key-value lists are parsed by \cs{ltjsetparameter}:
+\begin{lstlisting}
+ \ltjsetparameter{kanjiskip=0\zw plus .1\zw minus .01\zw}
+ \@tempskipa=\ltjgetparameter{xkanjiskip}
+ \ifdim\@tempskipa>\z@
+ \if@slide
+ \ltjsetparameter{xkanjiskip=0.1em}
+ \else
+ \ltjsetparameter{xkanjiskip=0.25em plus 0.15em minus 0.06em}
+ \fi
+ \fi
+\end{lstlisting}
+
+Hence, \LuaTeX-ja defines more primitive commands, namely \cs{ltj@setpar@global},
+\cs{ltjsetkanjiskip}, and~\cs{ltjsetxkanjiskip}. Here
+\begin{quote}
+ \lstinline+\ltj@setpar@global\ltjsetkanjiskip 10pt+
+\end{quote}
+and \lstinline+\ltjsetparameter{kanjiskip=10pt}+ has the same effect.
+The actual code of \Pkg{ltjsclasses} is shown below:
+\begin{lstlisting}
+ \ltj@setpar@global
+ \ltjsetkanjiskip{\z@ plus .1\zw minus .01\zw}
+ \@tempskipa=\ltjgetparameter{xkanjiskip}
+ \ifdim\@tempskipa>\z@
+ \if@slide
+ \ltjsetxkanjiskip.1em
+ \else
+ \ltjsetxkanjiskip.25em plus .15em minus .06em
+ \fi
+ \fi
+\end{lstlisting}
+
+Note that using \cs{ltjsetkanjiskip}~or~\cs{ltjsetxkanjiskip} alone,
+that is, without executing \cs{ltj@setpar@global} in advance, is \emph{not} supported.
+%</en>
+
+%<*ja>
+\subsection{\cs{ltjsetparameter} ã®ä»£æ›¿}
+原則ã¨ã—ã¦å„種内部パラメータã®è¨­å®šã«ã¯ \cs{ltjsetparameter} ã‚‚ã—ãã¯
+\ \cs{ltjglobalsetparameter}\ を用ã„ã‚‹ã“ã¨ã«ãªã‚‹ãŒï¼Œ
+\cs{ltjsetparameter} ã®å®Ÿè¡Œã«ã¯æ™‚é–“ãŒã‹ã‹ã‚‹ã¨ã„ã†é›£ç‚¹ãŒã‚り,
+\LuaTeX-ja ã®å†…部ã§ã¯ã‚ˆã‚Šé«˜é€Ÿã«å®Ÿè¡Œã§ãる別ã®å½¢å¼ã‚’用ã„ã¦ã„る.
+\emph{本節ã¯ä¸€èˆ¬åˆ©ç”¨è€…ã‚€ã‘ã®å†…容ã§ã¯ãªã„.}
+
+\paragraph{\Param{kanjiskip}, \Param{xkanjiskip}ã®è¨­å®š}
+\pLaTeXe 新ドキュメントクラスã§ã¯ï¼Œ
+\begin{lstlisting}
+\def\@setfontsize#1#2#3{%
+ ...
+ \kanjiskip=0zw plus .1zw minus .01zw
+ \ifdim\xkanjiskip>\z@
+ \if@slide \xkanjiskip=0.1em \else
+ \xkanjiskip=0.25em plus 0.15em minus 0.06em
+ \fi
+ \fi}
+\end{lstlisting}
+ã¨ï¼Œãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã‚’変更ã™ã‚‹ã”ã¨ã« \cs{kanjiskip}, \cs{xkanjiskip} を変更ã—ã¦ã„る.
+ã“ã® \cs{@setfontsize} ã¯æ–‡æ›¸ã®ä¸­ã§å¤šæ•°å›žå®Ÿè¡Œã•ã‚Œã‚‹ã®ã§ï¼Ž
+\LuaTeX-ja 用ã«ç´ ç›´ã«æ›¸ãæ›ãˆãŸ
+\begin{lstlisting}
+ \ltjsetparameter{kanjiskip=0\zw plus .1\zw minus .01\zw}
+ \@tempskipa=\ltjgetparameter{xkanjiskip}
+ \ifdim\@tempskipa>\z@
+ \if@slide
+ \ltjsetparameter{xkanjiskip=0.1em}
+ \else
+ \ltjsetparameter{xkanjiskip=0.25em plus 0.15em minus 0.06em}
+ \fi
+ \fi
+\end{lstlisting}
+ã¨ã—ãŸã®ã§ã¯ã‚¿ã‚¤ãƒ—セットãŒé…ããªã£ã¦ã—ã¾ã†ï¼Ž
+ãã“ã§ï¼Œ\cs{ltjsetparameter} ã®ä¸­ã§
+\begin{itemize}
+\item \cs{globaldefs} ã®å€¤ã‚’読ã¿å–ã‚‹ \cs{ltj@setpar@global}
+\item \Param{kanjiskip} ã®è¨­å®šã‚’行ㆠ\cs{ltjsetkanjiskip}
+\item \Param{xkanjiskip} ã®è¨­å®šã‚’行ㆠ\cs{ltjsetxkanjiskip}
+\end{itemize}
+を独立ã•ã›ï¼Œ\Pkg{ltjsclasses}ã§ã¯ï¼Œ
+\begin{lstlisting}
+ \ltj@setpar@global
+ \ltjsetkanjiskip{\z@ plus .1\zw minus .01\zw}
+ \@tempskipa=\ltjgetparameter{xkanjiskip}
+ \ifdim\@tempskipa>\z@
+ \if@slide
+ \ltjsetxkanjiskip.1em
+ \else
+ \ltjsetxkanjiskip.25em plus .15em minus .06em
+ \fi
+ \fi
+\end{lstlisting}
+ã¨ã—ã¦ã„る.
+\cs{ltj@setpar@global}ã‚’ç›´å‰ã«å®Ÿè¡Œã›ãšï¼Œå˜ç‹¬ã§
+\cs{ltjsetkanjiskip}, \cs{ltjsetxkanjiskip}を実行ã™ã‚‹ã“ã¨ã¯æƒ³å®šã•ã‚Œã¦ã„ãªã„ã®ã§æ³¨æ„.
+
+
+
+\paragraph{ベースライン補正é‡ã®è¨­å®š}
+\pLaTeX ã®\Pkg{ascmac}パッケージã§ã¯ï¼Œç¸¦çµ„ã®æ¬§æ–‡ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³è£œæ­£é‡ã®ä¸€æ™‚å¾…é¿ãƒ»å¾©å¸°å‡¦ç†ã«
+\ \cs{@saveybaselineshift}\ ã¨ã„ã†å¯¸æ³•ãƒ¬ã‚¸ã‚¹ã‚¿ã‚’用ã„
+\begin{lstlisting}
+\@savetbaselineshift\tbaselineshift\tbaselineshift\z@
+...
+\tbaselineshift\@savetbaselineshift
+\end{lstlisting}
+ã¨ã„ã†å‡¦ç†ã‚’è¡Œã£ã¦ã„る.
+
+ã“れを\LuaTeX-ja 用㫠\cs{ltjsetparameter} を使ã£ã¦æ›¸ãç›´ã™ã¨ï¼Œ
+\begin{lstlisting}
+\@savetbaselineshift\ltjgetparameter{talbaselineshift}
+\ltjsetparameter{talbaselineshift=\z@}
+...
+\ltjsetparameter{talbaselineshift=\@savetbaselineshift}
+\end{lstlisting}
+ã¨ãªã‚‹ï¼Ž
+
+ã•ã¦ï¼Œç¸¦çµ„ã®æ¬§æ–‡ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³è£œæ­£é‡\Param{talbaselineshift}ã¯ï¼Œ
+実際ã«ã¯ \cs{ltj@tablshift} ã¨ã„ã†å±žæ€§ãƒ¬ã‚¸ã‚¹ã‚¿ã«æ ¼ç´ã•ã‚Œã¦ã„ã‚‹
+(\ref{sec-para}\nobreak 節å‚照).属性レジスタã¯é•·ã•ã§ã¯ãªã整数値を格ç´ã™ã‚‹\footnote{%
+ 従ã£ã¦ï¼Œ\texttt{\textbackslash @savetbaselineshift=\textbackslash ltj@tablshift}\
+ ã®ã‚ˆã†ã«è¨˜è¿°ã™ã‚‹ã“ã¨ã¯ã§ããªã„.属性レジスタを \cs{tbaselineshift} ã¨ã„ã†å称ã«ã—ãªã‹ã£
+ ãŸã®ã¯ãã®ãŸã‚ã§ã‚る.
+}ã‚‚ã®ã§ã‚り,\cs{ltj@tablshift} ã¯è£œæ­£é‡ã‚’ sp å˜ä½ã§ä¿æŒã™ã‚‹ã“ã¨ã‹ã‚‰ï¼Œ
+上記ã®ã‚³ãƒ¼ãƒ‰ã¨åŒã˜å†…容をより速ã„以下ã®ã‚³ãƒ¼ãƒ‰ã§å®Ÿç¾ã™ã‚‹ã“ã¨ãŒã§ãる.
+\begin{lstlisting}
+\@savetbaselineshift\ltj@tablshift sp%
+\ltj@tablshift\z@
+...
+\ltj@tablshift\@savetbaselineshift
+\end{lstlisting}
+ã“ã®æ‰‹æ³•ã¯ \Pkg{ascmac} パッケージã®\LuaTeX-ja対応パッム\Pkg{lltjp-tascmac.sty} ã§
+実際ã«ç”¨ã„られã¦ã„る.\Pkg{lltjp-tascmac.sty} ã¯è‡ªå‹•çš„ã«èª­ã¿è¾¼ã¾ã‚Œã‚‹ã®ã§ï¼Œ
+ユーザã¯ä½•ã‚‚æ°—ã«ã›ãšæ™®é€šã« \Pkg{ascmac} パッケージを \cs{usepackage} ã§èª­ã¿ã“ã‚ã°è‰¯ã„.
+%</ja>
+
+
+%<en>\section{Other Commands for plain \TeX\ and \LaTeXe}
+%<ja>\section{plainã§ã‚‚\LaTeX ã§ã‚‚利用å¯èƒ½ãªãã®ä»–ã®å‘½ä»¤}
+%<en>\subsection{Commands for compatibility with \pTeX}
+%<ja>\subsection{\pTeX 互æ›ç”¨å‘½ä»¤}
+
+%<*en>
+The following commands are implemented for compatibility with \pTeX.
+Note that the former five commands don't support JIS~X~0213, but only JIS~X~0208.
+The last \cs{kansuji} converts an integer into its Chinese numerals.
+%</en>
+%<*ja>
+以下ã®å‘½ä»¤ã¯\pTeX ã¨ã®äº’æ›æ€§ã®ãŸã‚ã«å®Ÿè£…ã•ã‚Œã¦ã„る.ãã®ãŸã‚,JIS~X~0213ã«ã¯å¯¾å¿œã›ãšï¼Œ
+\pTeX ã¨åŒã˜ã‚ˆã†ã«JIS~X~0208ã®ç¯„囲ã—ã‹ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„.
+%</ja>
+\begin{center}
+\cs{kuten}, \cs{jis}, \cs{euc}, \cs{sjis}, \cs{ucs}, \cs{kansuji}
+\end{center}
+%<*en>
+These six commands takes an internal integer, and returns a \emph{string}.
+%</en>
+%<*ja>
+ã“れら6命令ã¯å†…部整数を引数ã¨ã™ã‚‹ãŒï¼Œå®Ÿè¡Œçµæžœã¯\textbf{文字列}ã§ã‚ã‚‹ã“ã¨ã«æ³¨æ„.
+%</ja>
+\begin{LTXexample}
+\newcount\hoge
+\hoge="2423 %"
+\the\hoge, \kansuji\hoge\\
+\jis\hoge, \char\jis\hoge\\
+\kansuji1701
+\end{LTXexample}
+
+%<*en>
+To change characters of Chinese numerals for each digit, set \Param{kansujichar} parameter:
+\begin{LTXexample}
+\ltjsetparameter{kansujichar={1,`壹}}
+\ltjsetparameter{kansujichar={7,`漆}}
+\ltjsetparameter{kansujichar={0,`零}}
+\kansuji1701
+\end{LTXexample}
+%</en>
+
+
+\subsection{\cs{inhibitglue}}
+%<*en>
+\cs{inhibitglue} suppresses the insertion of \textbf{JAglue}.
+The following is an example, using a special JFM that there will be a glue between
+the beginning of a box and ``ã‚'', and also between ``ã‚''~and~``ウ''.
+%</en>
+%<*ja>
+\cs{inhibitglue} ã¯\textbf{JAglue}ã®æŒ¿å…¥ã‚’抑制ã™ã‚‹ï¼Ž
+以下ã¯ï¼Œãƒœãƒƒã‚¯ã‚¹ã®å§‹ã‚ã¨ã€Œã‚ã€ã®é–“,「ã‚ã€ã€Œã‚¦ã€ã®é–“ã«ã‚°ãƒ«ãƒ¼ãŒå…¥ã‚‹ç‰¹åˆ¥ãªJFMを用ã„ãŸä¾‹ã§
+ã‚る.
+%</ja>
+
+\begin{LTXexample}[width=0.4\textwidth]
+\jfont\g=file:KozMinPr6N-Regular.otf:jfm=test \g
+\fbox{\hbox{ã‚ウã‚\inhibitglue ウ}}
+\inhibitglue\par\noindent ã‚1
+\par\inhibitglue\noindent ã‚2
+\par\noindent\inhibitglue ã‚3
+\par\hrule\noindent ã‚off\inhibitglue ice
+\end{LTXexample}
+
+%<*en>
+With the help of this example, we remark the specification of \cs{inhibitglue}:
+%</en>
+%<*ja>
+ã“ã®ä¾‹ã‚’æ´ç”¨ã—ã¦ï¼Œ\cs{inhibitglue} ã®ä»•æ§˜ã«ã¤ã„ã¦è¿°ã¹ã‚‹ï¼Ž
+%</ja>
+\begin{itemize}
+%<*en>
+\item The call of \cs{inhibitglue} in the (internal) vertical mode is
+ simply ignored.
+%</en>
+%<*ja>
+\item \emph{\cs{inhibitglue} ã®åž‚直モード中ã§ã®å‘¼ã³å‡ºã—ã¯æ„味をæŒãŸãªã„}\footnote{%
+ ã“ã®ç‚¹ã¯\TeX~Live~2014ã§ã®\pTeX ã«ãŠã‘ã‚‹ \cs{inhibitglue} ã®ä»•æ§˜å¤‰æ›´ã¨åŒã˜ã§ã‚る.
+}.
+4行目ã®å…¥åŠ›ã§æœ‰åŠ¹ã«ãªã‚‰ãªã„ã®ã¯ï¼Œ\cs{inhibitglue} ã®æ™‚点ã§ã¯åž‚直モードã§ã‚り,
+\cs{noindent} ã®æ™‚点ã§æ°´å¹³ãƒ¢ãƒ¼ãƒ‰ã«ãªã‚‹ã‹ã‚‰ã§ã‚る.
+%</ja>
+
+%<*en>
+\item The call of \cs{inhibitglue} in the (restricted) horizontal
+ mode is only effective on the spot; does not get over boundary of
+ paragraphs. Moreover, \cs{inhibitglue} cancels ligatures and
+ kernings, as shown in the last line of above example.
+%</en>
+%<*ja>
+\item \cs{inhibitglue} ã®ï¼ˆåˆ¶é™ã•ã‚ŒãŸï¼‰æ°´å¹³ãƒ¢ãƒ¼ãƒ‰ä¸­ã§ã®å‘¼ã³å‡ºã—ã¯ãã®å ´ã§ã®ã¿
+ 有効ã§ã‚り,段è½ã®å¢ƒç•Œã‚’乗り越ãˆãªã„.
+ ã•ã‚‰ã«ï¼Œ\cs{inhibitglue} ã¯ä¸Šã®ä¾‹ã®æœ€çµ‚è¡Œã®ã‚ˆã†ã«ï¼ˆæ¬§æ–‡ã«ãŠã‘る)リガãƒãƒ£ã¨ã‚«ãƒ¼ãƒ‹ãƒ³ã‚°ã‚’
+ 打ã¡æ¶ˆã™ï¼Žã“ã‚Œã¯ï¼Œ\cs{inhibitglue} ãŒå†…部的ã«ã¯ã€Œç¾åœ¨ã®ãƒªã‚¹ãƒˆä¸­ã«whatsitノードを
+ 追加ã™ã‚‹ã€ã“ã¨ã‚’è¡Œãªã£ã¦ã„ã‚‹ã‹ã‚‰ã§ã‚る.
+%</ja>
+
+%<*en>
+\item The call of \cs{inhibitglue} in math mode is just ignored.
+%</en>
+%<*ja>
+\item \cs{inhibitglue} ã‚’æ•°å¼ãƒ¢ãƒ¼ãƒ‰ä¸­ã§å‘¼ã³å‡ºã—ãŸå ´åˆã¯ãŸã ç„¡è¦–ã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+%<*ja>
+\item \LaTeX ã§\LuaTeX-ja を使用ã™ã‚‹å ´åˆã¯ï¼Œ
+\cs{inhibitglue} ã®ä»£ã‚ã‚Šã¨ã—㦠\verb+\<+ を使ã†ã“ã¨ãŒã§ãる.
+既㫠\verb+\<+ ãŒå®šç¾©ã•ã‚Œã¦ã„ãŸå ´åˆã¯ï¼Œ\LuaTeX-ja ã®èª­ã¿è¾¼ã¿ã§å¼·åˆ¶çš„ã«ä¸Šæ›¸ãã•ã‚Œã‚‹ã®ã§
+注æ„ã™ã‚‹ã“ã¨ï¼Ž
+%</ja>
+\end{itemize}
+
+
+\subsection{\cs{ltjfakeboxbdd}, \cs{ltjfakeparbegin}}
+%<*en>
+Sometimes \texttt{'parbdd'}~and~\texttt{'boxbdd'} specifications~look like ``fail'',
+especially in paragraphs inside list environments.
+This is because \cs{everypar} inserts some nodes such as boxes and kerns, so
+the ``first letter'' in a paragraph is in fact not the first letter.
+%</en>
+%<*ja>
+リスト環境内ã§ã®\cs{item}ã§å§‹ã¾ã‚‹å„é …ç›®ãªã©ã§ã¯ï¼Œ
+「段è½æœ€åˆã®éµæ‹¬å¼§ãŒä½™è¨ˆã«åŠè§’字下ã’ã•ã‚Œã‚‹ã€ãªã©ï¼Œ
+JFMã«ã‚ã‚‹\texttt{'parbdd'}, \texttt{'boxbdd'}ã®æŒ‡å®šãŒè¦‹ã‹ã‘上破綻ã—ã¦ã„ã‚‹ã“ã¨ãŒã‚る.
+
+ã“ã‚Œã¯\TeX ãŒ\cs{everypar}を用ã„ã¦æ®µè½é–‹å§‹æ™‚ã«è¨˜å·é¡žã‚„空白ãªã©ã‚’挿入ã—ã¦ã—ã¾ã£ã¦ã„ã‚‹ãŸã‚,
+段è½æœ€åˆã®éµæ‹¬å¼§ãŒå®Ÿéš›ã«ã¯æ®µè½æœ€åˆã®ãƒŽãƒ¼ãƒ‰ã§ã¯ãªã„ã“ã¨ã«èµ·å› ã™ã‚‹ï¼Žä»¥ä¸‹ã«ä¾‹ã‚’示ã—ãŸï¼Ž
+%</ja>
+\begin{LTXexample}[width=0.3\textwidth]
+\parindent1\zw
+\noindent ã‚ã‚ã‚ã‚ã‚ã‚ã‚ã‚\par % for comparison
+「ã‚ã‚ã‚ã‚ã‚ã‚ \par % normal paragraph
+
+\everypar{\null}
+「ã‚ã‚ã‚ã‚ã‚ã‚ \par % ???
+\end{LTXexample}
+%<*en>
+\cs{ltjfakeboxbdd}~and~\cs{ltjfakeparbegin} primitives resolve this situation.
+\begin{itemize}
+ \item \cs{ltjfakeparbegin} creates a node which indicates
+ ``beginning of an indented paragraph'' to the insertion process of \textbf{JAglue}.
+ \item \cs{ltjfakeboxbdd} creates a node which indicates
+ ``beginning/ending of a box'' to the insertion process of \textbf{JAglue}.
+\end{itemize}
+As an example, the example above can be improved as follows:
+%</en>
+%<*ja>
+\cs{ltjfakeboxbdd}, \cs{ltjfakeparbegin}ã¯ã“ã®çŠ¶æ³ã‚’改善ã™ã‚‹å‘½ä»¤ã§ã‚る.
+実際ã«ã¯\cs{everypar}ã®æœ«å°¾ã«ã“れらを追加ã™ã‚‹ã¨ã„ã†ä½¿ã„æ–¹ãŒã»ã¨ã‚“ã©ã«ãªã‚‹ã ã‚ã†ï¼Ž
+\begin{itemize}
+ \item \cs{ltjfakeparbegin}ã¯ï¼Œå®Ÿè¡Œã•ã‚ŒãŸç®‡æ‰€ãŒã€Œã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã‚り段è½ã®é–‹å§‹ã€ã§ã‚ã‚‹ã¨\LuaTeX-jaã®
+ 和文処ç†ã‚°ãƒ«ãƒ¼æŒ¿å…¥å‡¦ç†ã«èªè­˜ã•ã›ã‚‹ï¼Žã“ã®å‘½ä»¤ã®ç›´å‰ã«\textbf{JAchar}ãŒã‚ã£ãŸå ´åˆï¼Œ
+ ã“ã®æ–‡å­—ã®å¾Œã‚ã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼ç­‰ã®å‡¦ç†ã«ã¤ã„ã¦ã¯æœªå®šç¾©ã§ã‚ã‚‹
+ \footnote{%
+ ã“ã®å‘½ä»¤ã¨åŒç­‰ã®å†…容ã¯ï¼Œ\cs{dirrctlua}ã®å½¢ã§\Pkg{ltjsclasses}内ã§ä»¥å‰ã‹ã‚‰ä½¿ã‚ã‚Œã¦ã„ãŸï¼Ž
+ 一般ユーザã§ã‚‚利用ã—ã‚„ã™ãã™ã‚‹ãŸã‚,ãƒãƒ¼ã‚¸ãƒ§ãƒ³20170505.0ã§æ–°ãŸã«å‘½ä»¤ã¨ã—ã¦å®šç¾©ã—ãŸï¼Ž
+ }.
+ \item \cs{ltjfakeboxbdd}ã¯ï¼Œå®Ÿè¡Œã•ã‚ŒãŸç®‡æ‰€ãŒã€Œãƒœãƒƒã‚¯ã‚¹ã®å…ˆé ­ã¨æœ«å°¾ã€ã§ã‚ã‚‹ã¨\LuaTeX-jaã®
+ 和文処ç†ã‚°ãƒ«ãƒ¼æŒ¿å…¥å‡¦ç†ã«èªè­˜ã•ã›ã‚‹ï¼Ž
+\end{itemize}
+例ãˆã°ï¼Œå…ˆã»ã©ã®ä¾‹ã«å¯¾ã—ã¦é©ç”¨ã™ã‚‹ã¨ï¼Œæ¬¡ã®ã‚ˆã†ã«ãªã‚‹ï¼Ž
+%</ja>
+\begin{LTXexample}[width=0.3\textwidth]
+\parindent1\zw
+\noindent ã‚ã‚ã‚ã‚ã‚ã‚ã‚ã‚\par % for comparison
+「ã‚ã‚ã‚ã‚ã‚ã‚ \par % normal paragraph
+
+\everypar{\null\ltjfakeparbegin}
+「ã‚ã‚ã‚ã‚ã‚ã‚ \par
+\end{LTXexample}
+
+
+\subsection{\cs{ltjdeclarealtfont}}
+\label{ssec:altfont}
+%<*en>
+Using \cs{ltjdeclarealtfont}, one can ``compose'' more than one Japanese fonts.
+This \cs{ltjdeclarealtfont} uses in the following form:
+\begin{quote}
+\ttfamily \textbackslash ltjdeclarealtfont<base\_font\_cs><alt\_font\_cs>\{<range>\}
+\end{quote}
+where <base\_font\_cs>~and~<alt\_font\_cs> are defined by \cs{jfont}.
+Its meaning is
+\begin{quote}
+If the current Japanese font is <base\_font\_cs>, characters which belong to <range>
+is typeset by another Japanese font <alt\_font\_cs>, instead of <base\_font\_cs>.
+\end{quote}
+Here <range> is a comma-separated list of character codes, but also accepts negative integers:
+$-n$~($n≥1$) means that all characters of character classes~$n$, with respect to JFM used
+by <base\_font\_cs>. Note that characters which do not exist in <alt\_font\_cs> are
+ignored.
+
+For example, if \cs{hoge} uses \texttt{jfm-ujis.lua}, the standard JFM of \LuaTeX-ja,
+then
+\begin{lstlisting}
+\ltjdeclarealtfont\hoge\piyo{"3000-"30FF, {-1}-{-1}}
+\end{lstlisting}
+does
+\begin{quote}
+If the current Japanese font is \cs{hoge}, \texttt{U+3000}--\texttt{U+30FF}
+and characters in class~1 (ideographic opening brackets)
+are typeset by \cs{piyo}.
+\end{quote}
+%</en>
+%<*ja>
+\cs{jfont} ã®æ›¸å¼ã‚’見れã°ã‚ã‹ã‚‹ã‚ˆã†ã«ï¼ŒåŸºæœ¬çš„ã«ã¯\LuaTeX-jaã«ãŠã‘ã‚‹1ã¤ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã«
+使用出æ¥ã‚‹ã€Œå®Ÿéš›ã®ãƒ•ã‚©ãƒ³ãƒˆã€ã¯1ã¤ã§ã‚る.
+ã—ã‹ã—,\cs{ltjdeclarealtfont} を用ã„ã‚‹ã¨ï¼Œã“ã®åŽŸå‰‡ã‹ã‚‰å¤–れるã“ã¨ãŒã§ãる.
+
+\cs{ltjdeclarealtfont} ã¯ä»¥ä¸‹ã®æ›¸å¼ã§ä½¿ç”¨ã™ã‚‹ï¼š
+\begin{quote}
+\ttfamily \textbackslash ltjdeclarealtfont<base\_font\_cs><alt\_font\_cs>\{<range>\}
+\end{quote}
+ã“ã‚Œã¯ã€Œç¾åœ¨ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã€ãŒ<base\_font\_cs>ã§ã‚ã‚‹ã¨ã,
+<range>ã«å±žã™ã‚‹æ–‡å­—ã¯<alt\_font\_cs>を用ã„ã¦çµ„版ã•ã‚Œã‚‹ï¼Œã¨ã„ã†æ„味ã§ã‚る.
+\begin{itemize}
+ \item <base\_font\_cs>, <alt\_font\_cs>ã¯
+\cs{jfont} ã«ã‚ˆã£ã¦å®šç¾©ã•ã‚ŒãŸå’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã§ã‚る.
+ \item <range>ã¯æ–‡å­—コードã®ç¯„囲を表ã™ã‚³ãƒ³ãƒžåŒºåˆ‡ã‚Šã®ãƒªã‚¹ãƒˆã§ã‚ã‚‹ãŒï¼Œ
+ 例外ã¨ã—ã¦è² æ•°$-n$ã¯ã€Œ<base\_font\_cs>ã®JFMã®æ–‡å­—クラス$n$ã«å±žã™ã‚‹å…¨ã¦ã®æ–‡å­—ã€
+ ã‚’æ„味ã™ã‚‹ï¼Ž
+
+<range>中ã«<alt\_font\_cs>中ã«å®Ÿéš›ã«ã¯å­˜åœ¨ã—ãªã„文字ãŒæŒ‡å®šã•ã‚ŒãŸå ´åˆã¯ï¼Œ
+ãã®æ–‡å­—ã«å¯¾ã™ã‚‹è¨­å®šã¯ç„¡è¦–ã•ã‚Œã‚‹ï¼Ž
+\end{itemize}
+
+例ãˆã°ï¼Œ\cs{hoge} ã®JFMãŒ\LuaTeX-ja標準ã®
+\ \texttt{jfm-ujis.lua} ã§ã‚ã£ãŸå ´åˆï¼Œ
+\begin{lstlisting}
+\ltjdeclarealtfont\hoge\piyo{"3000-"30FF, {-1}-{-1}}
+\end{lstlisting}
+ã¯ã€Œ\cs{hoge} を利用ã—ã¦ã„ã‚‹ã¨ã,
+\texttt{U+3000}--\texttt{U+30FF}ã¨
+文字クラス1(開ã括弧類)中ã®æ–‡å­—ã ã‘㯠\cs{piyo} を用ã„ã‚‹ã€
+ã“ã¨ã‚’設定ã™ã‚‹ï¼Ž\verb+{-1}-{-1}+ ã¨ã„ã†å¤‰ã‚ã£ãŸæŒ‡å®šã®ä»•æ–¹ã‚’ã—ã¦ã„ã‚‹ã®ã¯ï¼Œ
+普通㫠\texttt{-1} ã¨æŒ‡å®šã—ãŸã®ã§ã¯æ­£ã—ã$-1$ã¨èª­ã¿å–られãªã„ã¨ã„ã†
+マクロã®éƒ½åˆã«ã‚ˆã‚‹ï¼Ž
+%</ja>
+
+%<*ja>
+\subsection{\cs{ltjalchar} 㨠\cs{ltjjachar}}
+文字コードãŒ$\text{<chr\_code>}~(\geq 128=\mathtt{0x80})$ã®æ–‡å­—ã‚’
+\ \cs{char} プリミティブを使ㄠ\cs{char}<chr\_code> ã¨ã—ã¦å‡ºåŠ›ã•ã›ã‚‹ã¨ï¼Œ
+ãã®æ–‡å­—ã®å±žã™ã‚‹æ–‡å­—範囲(\ref{ssec:setrange}節å‚照)ã«ã‚ˆã£ã¦
+\textbf{ALchar}ã‹\textbf{JAchar}ã‹ï¼Œã¤ã¾ã‚Šæ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆã§å‡ºåŠ›ã•ã‚Œã‚‹ã‹å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã§å‡ºåŠ›ã•ã‚Œ
+ã‚‹ã‹ãŒæ±ºã¾ã‚‹ï¼Ž
+
+文字範囲ã®è¨­å®šã‚’無視ã—,文字コードãŒ$\text{<chr\_code>}~(\geq 128=\mathtt{0x80})$ã®æ–‡å­—を強制的ã«
+\textbf{ALchar}, \textbf{JAchar}ã§å‡ºåŠ›ã™ã‚‹å‘½ä»¤ãŒãã‚Œãžã‚Œ
+\ \cs{ltjalchar},~\cs{ltjjachar} ã§ã‚る.使用方法㯠\cs{char} ã¨åŒã˜ã
+\ \cs{ltjalchar}<chr\_code>, \cs{ltjjachar}<chr\_code>ã¨ã™ã‚Œã°ã‚ˆã„.
+<chr\_code>ãŒ127以下ã®å ´åˆã¯ï¼Œ\cs{ltjjachar} ã§ã‚ã£ã¦ã‚‚\textbf{ALchar}ã¨ã—ã¦å‡ºåŠ›ã•ã‚Œã‚‹ã“ã¨
+ã«æ³¨æ„.
+
+以下ã¯\ref{ssec:setrange}節ã«è¼‰ã›ãŸä¾‹ã«ï¼Œ\cs{char} ã®å‹•ä½œã‚’追加ã—ãŸã‚‚ã®ã§ã‚る.
+\begin{LTXexample}[width=0.25\textwidth]
+\gtfamily\large % default, ALchar, JAchar
+¶, \char`¶, \ltjalchar`¶, \ltjjachar`¶\\ % default: ALchar
+α, \char`α, \ltjalchar`α, \ltjjachar`α % default: JAchar
+\end{LTXexample}
+%</ja>
+
+%<en>\section{Commands for \LaTeXe}
+%<ja>\section{\LaTeXe 用ã®å‘½ä»¤}
+
+%<*en>
+\subsection{Loading Japanese fonts in \LaTeXe}
+\label{ssec:ltx-jfm}
+From versoin~20190107,
+\emph{\LuaTeX-ja does not load Japanese fonts for horizontal direction and
+ that for vertical direction at same time},
+to reduce the number of loaded fonts.
+This will save time for typesetting and memory consumption of Lua side (\cite{tc18ltja}).
+
+\begin{itemize}
+ \item \cs{selectfont} loads (and chooses) only the Japanese font for current direction,
+ and does not load the Japanese font for other direction
+ (\LuaTeX-ja only detects its size and JFM, to calculate the amount of shifting the baseline).
+
+ \item Direction changing commands (\cs{yoko},~\cs{tate}, \cs{dtou},~\cs{utod}) are patched to
+ include the following process:
+ \begin{quote}
+ If the Japanese font for new direction is not loaded,
+ \LuaTeX-ja loads it automatically.
+ \end{quote}
+ Original commands are saved as \cs{ltj@@orig@yoko} etc.
+
+ \item Specifying Japanese font command which is
+ defined by \cs{jfont},~\cs{tfont}, or~\cs{DeclareFixedFont} directly
+ actually loads (and selects) the Japanese font.
+ For example, \textbf{JAchar}s in \cs{box0} will be typeset in \cs{HOGE},
+ in the following code:
+\begin{lstlisting}
+ % in horizontal direction (\yoko)
+ \DeclareFixedFont\HOGE{JT3}{gt}{m}{n}{12} % JT3: for vertical direction
+ \HOGE
+ \setbox0=\hbox{\tate ã‚ã„ã†}
+\end{lstlisting}
+ \end{itemize}
+%</en>
+
+%<*ja>
+\subsection{\LaTeXe 下ã§ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®èª­ã¿è¾¼ã¿}
+\label{ssec:ltx-jfm}
+ãƒãƒ¼ã‚¸ãƒ§ãƒ³20190107以é™ã§ã¯ï¼Œ\LaTeXe ã®ä¸‹ã§\LuaTeX-jaを使用ã—ãŸéš›ã«ï¼Œ
+\emph{横組用和文フォントã¨ç¸¦çµ„ã¿ç”¨å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚’両方一度ã«èª­ã¿è¾¼ã¿ãƒ»é¸æŠžã›ãšã«ï¼Œ
+ 実際ã«ãã‚Œãžã‚Œã‚’使ã†çµ„æ–¹å‘ã«ãªã£ãŸã¨ãã«è¡Œã†}ã¨ã„ã†æ–¹é‡ã«ã—ãŸï¼Ž
+ã“ã‚Œã¯å®Ÿéš›ã«èª­ã¿è¾¼ã‚€ãƒ•ã‚©ãƒ³ãƒˆæ•°ã‚’削減ã™ã‚‹ã“ã¨ã§ï¼Œ
+タイプセットã«ã‹ã‹ã‚‹æ™‚é–“ã¨ï¼ˆä¸»ã«Luaã®ï¼‰ãƒ¡ãƒ¢ãƒªæ¶ˆè²»ã‚’削減ã™ã‚‹ãŸã‚ã§ã‚ã‚‹(\cite{tc18ltja}).
+
+\begin{itemize}
+ \item \cs{selectfont}ã¯æ¨ªçµ„用・縦組用和文フォントã®ã†ã¡ï¼Œç¾åœ¨ã®çµ„æ–¹å‘ã§ä½¿ã†æ–¹ã‚’
+ 実際ã«èª­ã¿è¾¼ã¿ï¼ˆãƒ»é¸æŠžã—),ãã†ã§ãªã„æ–¹ã¯ã€Œãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã¨JFMã®ã¿\LuaTeX-jaãŒæŠŠæ¡ã—ã¦ã„る状態ã€
+ (以下,\emph{JFM把æ¡çŠ¶æ…‹})ã¨ã™ã‚‹ï¼Ž
+
+ \item 組方å‘変更命令\cs{yoko},~\cs{tate}, \cs{dtou},~\cs{utod}ã«ã¯
+ \begin{quote}
+ æ–°ãŸãªçµ„æ–¹å‘ã§ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãŒèª­ã¿è¾¼ã¾ã‚Œã¦ã„ãªã„(JFM把æ¡çŠ¶æ…‹ï¼‰ãªã‚‰ã°ï¼Œ
+ ç¾åœ¨ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ãƒ»ãƒ•ã‚¡ãƒŸãƒªãƒ»ã‚·ãƒªãƒ¼ã‚ºãƒ»ã‚·ã‚§ã‚¤ãƒ—ã‹ã‚‰æ”¹ã‚ã¦èª­ã¿è¾¼ã‚€ï¼ˆã¾ãŸã¯é¸æŠžã™ã‚‹ï¼‰
+ \end{quote}
+ 処ç†ãŒä»˜ã‘加ãˆã‚‰ã‚Œã¦ã„る.
+ ã‚‚ã¨ã®ã€Œçµ„æ–¹å‘を変更ã™ã‚‹ã ã‘ã€ã®å‘½ä»¤ã¯\cs{ltj@@orig@yoko}ã®ã‚ˆã†ã«\texttt{ltj@@orig@}ãŒå‰ã«ã¤ã„ãŸ
+ 命令ã«ä¿å­˜ã•ã‚Œã¦ã„る.
+
+ \item \cs{jfont},~\cs{tfont},~\cs{DeclareFixedFont}ã§å®šç¾©ã•ã‚ŒãŸå’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã¯
+ ãã®æ™‚点ã§å®Ÿéš›ã«ãƒ•ã‚©ãƒ³ãƒˆãŒèª­ã¿è¾¼ã¾ã‚Œã‚‹ï¼Žã™ãªã‚ã¡ï¼Œä»¥ä¸‹ã®ã‚³ãƒ¼ãƒ‰ã«ãŠã„ã¦ï¼Œ
+ \cs{box0}中ã®\textbf{JAchar}ã¯\cs{HOGE}ã§ã‚¿ã‚¤ãƒ—セットã•ã‚Œã‚‹ï¼Ž
+\begin{lstlisting}
+ % in horizontal direction (\yoko)
+ \DeclareFixedFont\HOGE{JT3}{gt}{m}{n}{12} % JT3: for vertical direction
+ \HOGE
+ \setbox0=\hbox{\tate ã‚ã„ã†}
+\end{lstlisting}
+ \end{itemize}
+%</ja>
+
+%<en>\subsection{Patch for NFSS2}
+%<ja>\subsection{NFSS2ã¸ã®ãƒ‘ッãƒ}
+\label{ssec:nfsspat}
+
+%<*en>
+Japanese patch for NFSS2 in \LuaTeX-ja
+is based on \texttt{plfonts.dtx} which plays the same role in \pLaTeXe.
+We will describe
+commands which are not described in Subsection~\ref{ssec:chgfnt}.
+%</en>
+%<*ja>
+\LuaTeX-jaã®NFSS2ã¸ã®æ—¥æœ¬èªžãƒ‘ッãƒã¯
+\pLaTeXe ã§åŒæ§˜ã®å½¹å‰²ã‚’æžœãŸã™ \texttt{plfonts.dtx} をベースã«ï¼Œ
+和文エンコーディングã®ç®¡ç†ç­‰ã‚’Luaã§æ›¸ããªãŠã—ãŸã‚‚ã®ã§ã‚る.
+ã“ã“ã§ã¯\ref{ssec:chgfnt}節ã§è¿°ã¹ã¦ã„ãªã‹ã£ãŸå‘½ä»¤ã«ã¤ã„ã¦
+記述ã—ã¦ãŠã.
+%</ja>
+
+\begin{cslist}%
+\item[\normalfont\bfseries %
+%<ja>追加ã®é•·ã•å¤‰æ•°é”
+%<en>additonal dimensions
+]
+%<*en>
+Like \pLaTeXe, \LuaTeX-ja defines the following dimensions
+for information of current Japanese font:
+%</en>
+%<*ja>
+\pLaTeXe ã¨åŒæ§˜ã«ï¼Œ\LuaTeX-jaã¯ã€Œç¾åœ¨ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®æƒ…å ±ã€ã‚’æ ¼ç´ã™ã‚‹é•·ã•å¤‰æ•°
+%</ja>
+\begin{quote}
+ \cs{cht}~(height), \cs{cdp}~(depth), \cs{cHT}~(sum of former two),\\
+ \cs{cwd}~(width), \cs{cvs}~(lineskip), \cs{chs}~(equals to \cs{cwd})
+\end{quote}
+%<en>and its \cs{normalsize} version:
+%<ja>ã¨ï¼Œãã® \cs{normalsize} 版ã§ã‚ã‚‹
+\begin{quote}
+ \cs{Cht}~(height), \cs{Cdp}~(depth),
+ \cs{Cwd}~(width), \\\cs{Cvs}~(equals to \cs{baselineskip}),
+ \cs{Chs}~(equals to \cs{cwd})%
+%<en>.
+\end{quote}
+%<*ja>
+を定義ã—ã¦ã„る.ãªãŠï¼Œ\cs{cwd} 㨠\cs{zw},ã¾ãŸ
+\cs{cHT} 㨠\cs{zh} ã¯ä¸€è‡´ã—ãªã„å¯èƒ½æ€§ãŒã‚る.ãªãœãªã‚‰ï¼Œ
+\cs{cwd},~\cs{cHT} ã¯ã€Œã‚ã€ã®å¯¸æ³•ã‹ã‚‰æ±ºå®šã•ã‚Œã‚‹ã®ã«å¯¾ã—,
+\cs{zw} 㨠\cs{zh} ã¯JFMã«æŒ‡å®šã•ã‚ŒãŸå€¤ã«éŽãŽãªã„ã‹ã‚‰ã§ã‚る.
+%</ja>
+%<*en>
+Note that \cs{cwd}~and~\cs{cHT} may differ from \cs{zw}~and~\cs{zh}
+respectively.
+On the one hand the former dimensions are determined from the character ``ã‚'',
+but on the other hand \cs{zw}~and~\cs{zh} are specified by JFM.
+%</en>
+
+
+\item[\cs{DeclareYokoKanjiEncoding}\{<encoding>\}\{<text-settings>\}\{<math-settings>\}]
+%<en>\ \\[\dimexpr-\medskipamount-2\baselineskip\relax]
+%<ja>\ \\[\dimexpr-2\baselineskip\relax]
+\item[\cs{DeclareTateKanjiEncoding}\{<encoding>\}\{<text-settings>\}\{<math-settings>\}]
+
+%<*en>
+In NFSS2 under \LuaTeX-ja, distinction between alphabetic fonts
+ and Japanese fonts are only made by their
+ encodings. For example, encodings OT1 and T1 are encodings for
+ alphabetic fonts, and Japanese fonts cannot
+ have these encodings. These command define a new encoding
+ scheme for Japanese font families.
+%</en>
+%<*ja>
+\LuaTeX-jaã®NFSS2ã«ãŠã„ã¦ã¯ï¼Œæ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆã¨å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã¯
+ãã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã«ã‚ˆã£ã¦ã®ã¿åŒºåˆ¥ã•ã‚Œã‚‹ï¼Ž
+例ãˆã°ï¼ŒOT1ã¨T1ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã¯æ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã§ã‚り,
+和文フォントã¯ã“れらã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã‚’æŒã¤ã“ã¨ã¯ã§ããªã„.
+ã“れらコマンドã¯æ¨ªçµ„用・縦組用和文フォントã®ãŸã‚ã®æ–°ã—ã„エンコーディングを
+ãã‚Œãžã‚Œå®šç¾©ã™ã‚‹ï¼Ž
+%</ja>
+
+\item[\cs{DeclareKanjiEncodingDefaults}\{<text-settings>\}\{<math-settings>\}]
+%<en>\ \\[\dimexpr-\medskipamount-2\baselineskip\relax]
+%<ja>\ \\[\dimexpr-2\baselineskip\relax]
+\item[\cs{DeclareKanjiSubstitution}\{<encoding>\}\{<family>\}\{<series>\}\{<shape>\}]
+%<en>\ \\[\dimexpr-\medskipamount-2\baselineskip\relax]
+%<ja>\ \\[\dimexpr-2\baselineskip\relax]
+\item[\cs{DeclareErrorKanjiFont}\{<encoding>\}\{<family>\}\{<series>\}\{<shape>\}\{<size>\}]
+
+%<*en>
+The above 3~commands are just the counterparts for \cs{DeclareFontEncodingDefaults} and~others.
+%</en>
+%<*ja>
+上記3ã¤ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ã¡ã‚‡ã†ã©NFSS2 ã® \cs{DeclareFontEncodingDefaults} ãªã©ã«å¯¾å¿œã™ã‚‹ã‚‚ã®ã§ã‚る.
+%</ja>
+
+\item[\cs{reDeclareMathAlphabet}\{<unified-cmd>\}\{<al-cmd>\}\{<ja-cmd>\}]
+
+% ToDo: en
+%<*ja>
+和文・欧文ã®æ•°å¼ç”¨ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã‚’一度ã«å¤‰æ›´ã™ã‚‹å‘½ä»¤ã‚’作æˆã™ã‚‹ï¼Ž
+具体的ã«ã¯ï¼Œæ¬§æ–‡æ•°å¼ç”¨ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªå¤‰æ›´ã®å‘½ä»¤<al-cmd>(\cs{mathrm} 等)ã¨ï¼Œå’Œæ–‡æ•°å¼ç”¨ãƒ•ã‚©
+ ントファミリ変更ã®å‘½ä»¤<ja-cmd>(\cs{mathmc} 等)ã®2ã¤ã‚’åŒæ™‚ã«è¡Œã†å‘½ä»¤ã¨ã—ã¦
+ <unified-cmd>を(å†ï¼‰å®šç¾©ã™ã‚‹ï¼Žå®Ÿéš›ã®ä½¿ç”¨ã§ã¯<unified-cmd>ã¨
+ <al-cmd>ã«åŒã˜ã‚‚ã®ã‚’指定ã™ã‚‹ï¼Œã™ãªã‚ã¡ï¼Œ<al-cmd>ã§å’Œæ–‡å´ã‚‚変
+ æ›´ã•ã›ã‚‹ã‚ˆã†ã«ã™ã‚‹ã®ãŒä¸€èˆ¬çš„ã¨æ€ã‚れる.
+
+本命令ã¯
+\begin{center}\tt
+<unified-cmd>\{<arg>\}\quad$\longrightarrow$\quad
+(<al-cmd>ã®1段展開çµæžœ)\{<ja-cmd>ã®1段展開çµæžœ)\{<arg>\}\}
+\end{center}
+ã¨å®šç¾©ã‚’è¡Œã†ã®ã§ï¼Œä½¿ç”¨ã«ã¯æ³¨æ„ãŒå¿…è¦ã§ã‚る:
+%<en>\vspace{-\medskipamount}
+\begin{itemize}
+\item <al-cmd>,~<ja-cmd>ã¯æ—¢ã«å®šç¾©ã•ã‚Œã¦ã„ãªã‘ã‚Œã°ãªã‚‰ãªã„.
+ \cs{reDeclareMathAlphabet}\\ã®å¾Œã«
+両命令ã®å†…容をå†å®šç¾©ã—ã¦ã‚‚,<unified-cmd>ã®å†…容ã«ãã‚Œã¯å映ã•ã‚Œãªã„.
+\item <al-cmd>,~<ja-cmd>ã«\verb+\@mathrm+ãªã©ã¨ \texttt{@} ã‚’ã¤ã‘ãŸå‘½ä»¤ã‚’指定ã—ãŸæ™‚ã®å‹•ä½œã¯ä¿è¨¼ã§ããªã„.
+\end{itemize}
+%</ja>
+
+\item[\cs{DeclareRelationFont}\{<ja-encoding>\}\{<ja-family>\}\{<ja-series>\}\{<ja-shape>\}\\*
+ \null\hfill\{<al-encoding>\}\{<al-family>\}\{<al-series>\}\{<al-shape>\}]
+%<*en>
+This command sets the ``accompanied'' alphabetic font (given by the latter 4~arguments)
+with respect to a Japanese font given by the former 4~arguments.
+%</en>
+%<*ja>
+ã„ã‚ゆる「従属欧文ã€ã‚’設定ã™ã‚‹ãŸã‚ã®å‘½ä»¤ã§ã‚る.å‰åŠã®4引数ã§è¡¨ã•ã‚Œã‚‹å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã«å¯¾ã—ã¦ï¼Œ
+ãã®ãƒ•ã‚©ãƒ³ãƒˆã«å¯¾å¿œã™ã‚‹ã€Œå¾“属欧文ã€ã®ãƒ•ã‚©ãƒ³ãƒˆã‚’後åŠã®4引数ã«ã‚ˆã‚Šä¸Žãˆã‚‹ï¼Ž
+%</ja>
+\item[\cs{SetRelationFont}]
+%<*en>
+This command is almost same as \cs{DeclareRelationFont}, except that this command does a local
+assignment, where \cs{DeclareRelationFont} does a global assignment.
+%</en>
+%<*ja>
+ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ \cs{DeclareRelationFont} ã¨ãƒ­ãƒ¼ã‚«ãƒ«ãªæŒ‡å®šã§ã‚ã‚‹ã“ã¨ã‚’除ã„ã¦
+ã»ã¨ã‚“ã©åŒã˜ã§ã‚る(\cs{DeclareRelationFont} ã¯ã‚°ãƒ­ãƒ¼ãƒãƒ«ï¼‰ï¼Ž
+%</ja>
+
+\item[\cs{userelfont}]
+%<*en>
+(Only)~at the next call of \cs{selectfont},
+ change current alphabetic font encoding/family/\dots\ to the `accompanied' alphabetic
+ font family with respect to current Japanese font family,
+ which was set by
+ \cs{DeclareRelationFont} or \cs{SetRelationFont}.
+
+ The following is an example of \cs{SetRelationFont} and \cs{userelfont}:
+%</en>
+%<*ja>
+次回(ã®ã¿ï¼‰ã®\cs{selectfont}ã®å®Ÿè¡Œæ™‚ã«ï¼Œç¾åœ¨ã®æ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ï¼ãƒ•ã‚¡ãƒŸãƒªï¼â€¦â€¦ を,
+\cs{DeclareRelationFont} ã‹ \cs{SetRelationFont} ã§æŒ‡å®šã•ã‚ŒãŸ
+ç¾åœ¨ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã«å¯¾å¿œã™ã‚‹ã€Œå¾“属欧文ã€ãƒ•ã‚©ãƒ³ãƒˆã«å¤‰æ›´ã™ã‚‹ï¼Ž
+
+ 以下㫠\cs{SetRelationFont} 㨠\cs{userelfont} ã®ä¾‹ã‚’
+紹介ã—ã¦ãŠã“ã†ï¼Ž\cs{userelfont} ã®ä½¿ç”¨ã«ã‚ˆã£ã¦ï¼Œã€Œabcã€ã®éƒ¨åˆ†ã®ãƒ•ã‚©ãƒ³ãƒˆãŒ
+Latin Modern Sans Serif (TU/lmss/m/n) ã«å¤‰ã‚ã£ã¦ã„ã‚‹ã“ã¨ãŒã‚ã‹ã‚‹ï¼Ž
+%</ja>
+\begin{LTXexample}[width=0.3\textwidth]
+\makeatletter
+\SetRelationFont{JY3}{\k@family}{m}{n}{TU}{lmss}{m}{n}
+ % \k@family: current Japanese font family
+\userelfont\selectfont ã‚ã„ã†abc
+\end{LTXexample}
+
+\item[\cs{adjustbaseline}]
+%<*en>
+In \pLaTeXe, \cs{adjustbaseline} sets \cs{tbaselineshift}
+to match the vertical center of ``M'' and that of ``ã‚'' in vertical typesetting:
+\[
+\text{\cs{tbaselineshift}} \leftarrow
+\frac{(h_{\text{M}}+d_{\text{M}}) - (h_{\text{ã‚}}+d_{\text{ã‚}})}2
+ + d_{\text{ã‚}} - d_{\text{M}},
+\]
+where $h_{a}$~and~$d_{a}$ denote the height of ``$a$'' and the depth, respectively.
+In \LuaTeX-ja, this \cs{adjustbaseline} does similar task, namely setting the
+ \Param{talbaselineshift} parameter.
+If the \LaTeX\ is 2015/10/01 release or later, \LuaTeX-ja use a Japanese
+character whose character class is zero, instead of `ã‚'.
+%</en>
+%<*ja>
+\pLaTeXe ã§ã¯ï¼Œ\cs{adjustbaseline} ã¯ç¸¦çµ„時ã«ã€ŒMã€ã¨ã€Œã‚ã€ã®ä¸­å¿ƒç·šã‚’一致ã•ã›ã‚‹ãŸã‚ã«ï¼Œ
+\cs{tbaselineshift} を設定ã™ã‚‹å½¹å‰²ã‚’æŒã£ã¦ã„ãŸï¼š
+\[
+\text{\cs{tbaselineshift}} \leftarrow
+\frac{(h_{\text{M}}+d_{\text{M}}) - (h_{\text{ã‚}}+d_{\text{ã‚}})}2
+ + d_{\text{ã‚}} - d_{\text{M}},
+\]
+ã“ã“ã§ï¼Œ$h_{a}$,~$d_{a}$ã¯ãã‚Œãžã‚Œã€Œ$a$ã€ã®é«˜ã•ãƒ»æ·±ã•ã‚’表ã™ï¼Ž
+\LuaTeX-jaã«ãŠã„ã¦ã‚‚\cs{adjustbaseline} ã¯åŒæ§˜ã«\Param{talbaselineshift}パラメータã®èª¿æ•´å‡¦
+ ç†ã‚’è¡Œã£ã¦ã„る.
+
+åŒæ™‚ã«ï¼Œã“れも\pLaTeXe ã® \cs{adjustbaseline} ã§åŒæ§˜ã®å‡¦ç†ãŒè¡Œã‚ã‚Œã¦ã„ãŸãŒï¼Œ
+「漢ã€ã®å¯¸æ³•ã‚’å…ƒã«ï¼ˆæœ¬ç¯€ã®æœ€åˆã«è¿°ã¹ãŸï¼Œå°æ–‡å­—ã§å§‹ã¾ã‚‹ï¼‰\cs{cht}, \cs{cwd}
+ã¨ã„ã£ãŸé•·ã•å¤‰æ•°ã‚’設定ã™ã‚‹ï¼Ž
+
+ãªãŠï¼Œ\LaTeX ãŒ2015/10/01版以é™ã®å ´åˆã¯ï¼Œã€Œã‚ã€ã€Œæ¼¢ã€ã®ä»£ã‚ã‚Šã«
+「文字クラス0ã®å’Œæ–‡æ–‡å­—ã€ã‚’用ã„る.
+%</ja>
+
+\item[\cs{fontfamily}\{<family>\}]
+%<*en>
+As in \LaTeXe, this command changes current font family (alphabetic, Japanese,~\emph{or both})
+to <family>. See Subsection~\ref{ssec:fontfamilycmd} for detail.
+%</en>
+%<*ja>
+元々ã®\LaTeXe ã«ãŠã‘ã‚‹ã‚‚ã®ã¨åŒæ§˜ã«ï¼Œã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç¾åœ¨ã®ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªï¼ˆæ¬§æ–‡ï¼Œ
+和文,\emph{ã‚‚ã—ãã¯ä¸¡æ–¹})を<family>ã«å¤‰æ›´ã™ã‚‹ï¼Žè©³ç´°ã¯\ref{ssec:fontfamilycmd}節をå‚ç…§ã™ã‚‹ã“ã¨ï¼Ž
+%</ja>
+
+
+\begin{figure}[!tb]
+\begin{LTXexample}[pos=b]
+\DeclareKanjiFamily{JY3}{edm}{}
+\DeclareFontShape{JY3}{edm}{m}{n} {<-> s*KozMinPr6N-Regular:jfm=ujis;}{}
+\DeclareFontShape{JY3}{edm}{m}{green}{<-> s*KozMinPr6N-Regular:jfm=ujis;color=007F00}{}
+\DeclareFontShape{JY3}{edm}{m}{blue} {<-> s*KozMinPr6N-Regular:jfm=ujis;color=0000FF}{}
+\DeclareAlternateKanjiFont{JY3}{edm}{m}{n}{JY3}{edm}{m}{green}{"4E00-"67FF,{-2}-{-2}}
+\DeclareAlternateKanjiFont{JY3}{edm}{m}{n}{JY3}{edm}{m}{blue}{ "6800-"9FFF}
+{\kanjifamily{edm}\selectfont
+日本国民ã¯ã€æ­£å½“ã«é¸æŒ™ã•ã‚ŒãŸå›½ä¼šã«ãŠã‘る代表者を通ã˜ã¦è¡Œå‹•ã—ã€â€¦â€¦}
+\end{LTXexample}
+%<ja>\caption{\cs{DeclareAlternateKanjiFont} ã®ä½¿ç”¨ä¾‹}
+%<en>\caption{An example of \cs{DeclareAlternateKanjiFont}}
+\label{fig:altkanji}
+\end{figure}
+
+\item[\cs{DeclareAlternateKanjiFont}\{<base-encoding>\}\{<base-family>\}\{<base-series>\}\{<base-shape>\}\\
+ \null\hfill\{<alt-encoding>\}\{<alt-family>\}\{<alt-series>\}\{<alt-shape>\}\{<range>\}]
+%<*ja>
+\ref{ssec:altfont}節ã®\
+\cs{ltjdeclarealtfont} ã¨åŒæ§˜ã«ï¼Œå‰åŠã®4引数ã®
+和文フォント(基底フォント)ã®ã†ã¡<range>中ã®æ–‡å­—ã‚’
+第5ã‹ã‚‰ç¬¬8引数ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚’使ã£ã¦çµ„むよã†ã«æŒ‡ç¤ºã™ã‚‹ï¼Ž
+使用例を図\nobreak\ref{fig:altkanji}ã«è¼‰ã›ãŸï¼Ž
+
+\begin{itemize}
+ \item
+\cs{ltjdeclarealtfont} ã§ã¯åŸºåº•ãƒ•ã‚©ãƒ³ãƒˆãƒ»ç½®ãæ›ãˆå…ˆå’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã¯ã‚らã‹ã˜ã‚定義ã•ã‚Œã¦ã„
+ ãªã„ã¨ã„ã‘ãªã„(ãã®ä»£ã‚ã‚Šå³æ™‚発効)ã§ã‚ã£ãŸãŒï¼Œ
+\cs{DeclareAlternateKanjiFont} ã®è¨­å®šãŒ
+実際ã«åŠ¹åŠ›ãŒç™ºæ®ã™ã‚‹ã®ã¯ï¼Œæ›¸ä½“変更やサイズ変更を行ã£ãŸæ™‚,
+ã‚ã‚‹ã„ã¯ï¼ˆã“れらをå«ã‚€ãŒï¼‰\cs{selectfont} ãŒå®Ÿè¡Œã•ã‚ŒãŸæ™‚ã§ã‚る.
+ \item
+段è½ã‚„hboxã®æœ€å¾Œã§ã®è¨­å®šå€¤ãŒæ®µè½ï¼hbox全体ã«ã‚ãŸã£ã¦é€šç”¨ã™ã‚‹ç‚¹ã‚„,
+<range>ã«è² æ•°$-n$を指定ã—ãŸå ´åˆï¼Œãã‚ŒãŒã€ŒåŸºåº•ãƒ•ã‚©ãƒ³ãƒˆã®æ–‡å­—クラス$n$ã«å±žã™ã‚‹æ–‡å­—全体ã€
+ã¨è§£é‡ˆã•ã‚Œã‚‹ã®ã¯ \cs{ltjdeclarealtfont} ã¨åŒã˜ã§ã‚る.
+\end{itemize}%
+%</ja>
+%<*en>
+As \cs{ltjdeclarealtfont}~(Subsection~\ref{ssec:altfont}),
+characters in <range> of the Japanese font (we say the \emph{base font})
+which specified by first 4 arguments are typeset
+by the Japanese font which specified by fifth to eighth arguments
+(we say the \emph{alternate font}).
+An example is shown in \autoref{fig:altkanji}.
+
+\begin{itemize}
+ \item
+In \cs{ltjdeclarealtfont}, the base font and the alternate font must be already defined.
+But this \cs{DeclareAlternateKanjiFont} is not so.
+In other words, \cs{DeclareAlternateKanjiFont} is effective only after
+current Japanese font is changed, or only after \cs{selectfont} is executed.
+ \item \dots
+\end{itemize}%
+\vspace{-\medskipamount}
+%</en>
+\end{cslist}
+
+
+%<*en>
+Furthermore, \LuaTeX-ja applies patches which enables NFSS2 commands,
+such~as \cs{DeclareSymbolFont}~and~\cs{SetSymbolFont}, to specify
+Japanee fonts as math fonts.
+
+Specifying \texttt{disablejfam} option in \cs{usepackage} prevents
+applying these patches.
+Hence one cannot write Japanese Characters in math mode directly
+if \texttt{disablejfam} option is specified.
+The code below does not work either:
+\begin{lstlisting}
+\DeclareSymbolFont{mincho}{JY3}{mc}{m}{n}
+\DeclareSymbolFontAlphabet{\mathmc}{mincho}
+\end{lstlisting}
+%</en>
+%<*ja>
+ã“ã®ä»–ã«ã‚‚,標準ã§ã¯
+\cs{DeclareSymbolFont}, \cs{SetSymbolFont} ãªã©ã®å‘½ä»¤ã§
+(NFSS2ã®æž çµ„ã¿ã§ï¼‰æ•°å¼ãƒ•ã‚©ãƒ³ãƒˆã¨ã—ã¦æ—¥æœ¬èªžãƒ•ã‚©ãƒ³ãƒˆã‚’使ãˆã‚‹ã‚ˆã†ã«ã™ã‚‹ãŸã‚ã®ãƒ‘ッãƒã‚’当ã¦ã¦ã„る.
+
+一方,\texttt{disablejfam}オプション指定時ã«ã¯ï¼Œã“れらã®ãƒ‘ッãƒã‚’当ã¦ãªã„ã®ã§
+\begin{lstlisting}
+\DeclareSymbolFont{mincho}{JY3}{mc}{m}{n}
+\DeclareSymbolFontAlphabet{\mathmc}{mincho}
+\end{lstlisting}
+ã®ã‚ˆã†ã«è¨­å®šã—ã¦ã‚‚,数å¼ãƒ¢ãƒ¼ãƒ‰ä¸­ã«ç›´ã«æ—¥æœ¬èªžã‚’記述ã™ã‚‹ã“ã¨ã¯ã§ããªã„.
+\verb|$\mathmc{ã‚}$| ã®ã‚ˆã†ã« \cs{mathmc} ã§å›²ã‚“ã§ã‚‚ã§ããªã„.
+%</ja>
+
+%<en>\subsection{Detail of \cs{fontfamily} command}
+%<ja>\subsection{\cs{fontfamily}コマンドã®è©³ç´°}
+\label{ssec:fontfamilycmd}
+%<*en>
+In this subsection, we describe when \cs{fontfamily}<family> changes current
+Japanese/alphabetic font family. Basically, current Japanese fotn family is changed to
+<family> if it is recognized as a Japanese font family, and similar with alphabetic font
+family. There is a case that current Japanese/alphabetic font family are both changed to
+<family>, and another case that <family> isn't recognized as a Japanese/alphabetic font
+family either.
+
+\paragraph{Recognition as Japanese font family}
+First, Whether Japanese font family will be changed is determined in following order.
+This order is very similar to \cs{fontfamily} in \pLaTeXe, but we re-implemented in Lua.
+We use an auxiliary list~$N_{\mathrm{J}}$.
+%</en>
+%<*ja>
+本節ã§ã¯ï¼Œ\cs{fontfamily}<family> ãŒã„ã¤å’Œæ–‡/欧文フォントファミリを変更ã™ã‚‹ã‹ã«ã¤ã„ã¦è§£èª¬
+ã™ã‚‹ï¼ŽåŸºæœ¬çš„ã«ã¯ï¼Œ<family>ãŒå’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã ã¨èªè­˜ã•ã‚Œã‚Œã°å’Œæ–‡å´ãŒï¼Œæ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡
+ミリã ã¨èªè­˜ã•ã‚Œã‚Œã°æ¬§æ–‡å´ãŒå¤‰æ›´ã•ã‚Œã‚‹ï¼Žã©ã¡ã‚‰ã¨ã‚‚èªè­˜ã•ã‚Œã‚Œã°å’Œæ–‡ãƒ»æ¬§æ–‡ã®ä¸¡æ–¹ãŒå¤‰ã‚ã‚‹ã“
+ã¨ã«ãªã‚‹ã—,当然ã©ã¡ã‚‰ã¨ã‚‚èªè­˜ã•ã‚Œãªã„ã“ã¨ã‚‚ã‚る.
+
+\paragraph{和文フォントファミリã¨ã—ã¦ã®èªè­˜}
+ã¾ãšï¼Œ<family>ãŒå’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã¨ã—ã¦èªè­˜ã•ã‚Œã‚‹ã‹ã¯ä»¥ä¸‹ã®é †åºã§æ±ºå®šã•ã‚Œã‚‹ï¼Ž
+ã“ã‚Œã¯\pLaTeXe ã® \cs{fontfamily} ã«ã¨ã¦ã‚‚ä¼¼ã¦ã„ã‚‹ãŒï¼Œã“ã“ã§ã¯Luaã«ã‚ˆã£ã¦å®Ÿè£…ã—ã¦ã„る.
+補助的ã«ã€Œå’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã§ã¯ãªã„ã¨èªè­˜ã•ã‚ŒãŸã€ãƒ•ã‚¡ãƒŸãƒªã‚’æ ¼ç´ã—ãŸãƒªã‚¹ãƒˆ$N_{\mathrm{J}}$を用ã„る.
+%</ja>
+\begin{enumerate}
+%<*en>
+\item If the family~<family> has been defined already by \cs{DeclareKanjiFamily},
+ <family> is recognized as a Japanese font family.
+ Note that <family> need not be defined under \emph{current} Japanese font encoding.
+%</en>
+%<*ja>
+\item ファミリ<family>ãŒæ—¢ã« \cs{DeclareKanjiFamily} ã«ã‚ˆã£ã¦å®šç¾©ã•ã‚Œã¦ã„ã‚‹å ´åˆï¼Œ
+ <family>ã¯å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã§ã‚ã‚‹ã¨èªè­˜ã•ã‚Œã‚‹ï¼Ž
+ ã“ã“ã§ï¼Œ<family>ã¯ç¾åœ¨ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã§å®šç¾©ã•ã‚Œã¦ã„ãªãã¦ã‚‚よã„.
+%</ja>
+%<*en>
+\item If the family~<family> has been listed in a list~$N_{\mathrm{J}}$, this means
+ that <family> is not a Japanese font family.
+%</en>
+%<*ja>
+\item ファミリ<family>ãŒãƒªã‚¹ãƒˆ$N_{\mathrm{J}}$ã«æ—¢ã«å«ã¾ã‚Œã¦ã„ã‚Œã°ï¼Œãã‚Œã¯
+ <family>ãŒå’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã§ã¯ãªã„ã“ã¨ã‚’æ„味ã™ã‚‹ï¼Ž
+%</ja>
+%<*en>
+\item If the \Pkg{luatexja-fontspec} package is loaded, we stop here, and <family> is not
+ recognized as a Japanese font family.
+
+ If the \Pkg{luatexja-fontspec} package is \emph{not} loaded,
+now \LuaTeX-ja looks whether there exists a Japanese font encoding~<enc> such that
+ a font definition named \texttt{<enc><family>.fd} (the file name is
+ all lowercase) exists. If so, <family> is recognized as a Japanese font family (the font definition file won't be loaded here).
+ If not, <family> is not a Japanese font family, and
+ <family> is appended to the list~$N_{\mathrm{J}}$.
+%</en>
+%<*ja>
+\item ã‚‚ã—\Pkg{luatexja-fontspec}パッケージãŒèª­ã¿è¾¼ã¾ã‚Œã¦ã„ã‚Œã°ï¼Œã“ã“ã§çµ‚了ã§ã‚り,
+<family>ã¯å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã¨ã—ã¦èªè­˜ã•ã‚Œãªã„ã“ã¨ã«ãªã‚‹ï¼Ž
+
+ã‚‚ã—\Pkg{luatexja-fontspec}パッケージãŒèª­ã¿è¾¼ã¾ã‚Œã¦ã„ãªã‘ã‚Œã°ï¼Œå’Œæ–‡ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°<enc>ã§
+フォント定義ファイル\texttt{<enc><family>.fd}(ファイルåã¯å…¨ã¦å°æ–‡å­—)ãŒå­˜åœ¨ã™ã‚‹ã‚ˆã†ãªã‚‚
+ ã®ãŒã‚ã‚‹ã‹ã©ã†ã‹ã‚’調ã¹ã‚‹ï¼Ž
+存在ã™ã‚Œã°ï¼Œ<family>ã¯å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã¨èªè­˜ã•ã‚Œã‚‹ï¼ˆãƒ•ã‚©ãƒ³ãƒˆå®šç¾©ãƒ•ã‚¡ã‚¤ãƒ«ã¯èª­ã¿è¾¼ã¾ã‚Œãª
+ ã„).
+存在ã—ãªã‘ã‚Œã°ï¼Œ<family>ã¯å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã§ãªã„ã¨èªè­˜ã•ã‚Œï¼Œãƒªã‚¹ãƒˆ$N_{\mathrm{J}}$ã«<family>を追加ã™ã‚‹ã“ã¨ã§ãれを記憶ã™ã‚‹ï¼Ž
+
+%</ja>
+\end{enumerate}
+
+%<*en>
+\paragraph{Recognition as alphabetic font family}
+Next, whether alphabetic font family will be changed is determined in following order.
+We use auxiliary lists $F_{\mathrm{A}}$~and~$N_{\mathrm{A}}$,
+%</en>
+%<*ja>
+\paragraph{欧文フォントファミリã¨ã—ã¦ã®èªè­˜}
+åŒæ§˜ã«ï¼Œ<family>ãŒå’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã¨ã—ã¦èªè­˜ã•ã‚Œã‚‹ã‹ã¯ä»¥ä¸‹ã®é †åºã§æ±ºå®šã•ã‚Œã‚‹ï¼Ž
+補助的ã«ã€Œæ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã¨æ—¢ã«èªè­˜ã•ã‚ŒãŸã€ãƒ•ã‚¡ãƒŸãƒªã®ãƒªã‚¹ãƒˆ$F_{\textrm{A}}$ã¨ï¼Œ
+「欧文フォントファミリã§ã¯ãªã„ã¨èªè­˜ã•ã‚ŒãŸã€ãƒ•ã‚¡ãƒŸãƒªã‚’æ ¼ç´ã—ãŸãƒªã‚¹ãƒˆ$N_{\mathrm{A}}$を用ã„る.
+%</ja>
+
+\begin{enumerate}
+%<*en>
+\item If the family~<family> has been listed in a list~$F_{\mathrm{A}}$,
+ <family> is recognized as an alphabetic font family.
+%</en>
+%<*ja>
+\item ファミリ<family>ãŒãƒªã‚¹ãƒˆ$F_{\mathrm{A}}$ã«æ—¢ã«å«ã¾ã‚Œã¦ã„ã‚Œã°ï¼Œ
+ <family>ã¯æ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã¨èªè­˜ã•ã‚Œã‚‹ï¼Ž
+%</ja>
+%<*en>
+\item If the family~<family> has been listed in a list~$N_{\mathrm{A}}$, this means
+ that <family> is not an alphabetic font family.
+%</en>
+%<*ja>
+\item ファミリ<family>ãŒãƒªã‚¹ãƒˆ$N_{\mathrm{A}}$ã«æ—¢ã«å«ã¾ã‚Œã¦ã„ã‚Œã°ï¼Œãã‚Œã¯
+ <family>ãŒæ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã§ã¯ãªã„ã“ã¨ã‚’æ„味ã™ã‚‹ï¼Ž
+%</ja>
+%<*en>
+\item If there exists an alphabetic font encoding such that the family~<family> has been
+ defined under it, <family> is recognized as an alphabetic font family, and
+ to memorize this, <family> is appended to the list~$F_{\mathrm{A}}$.
+%</en>
+%<*ja>
+\item ã‚る欧文フォントエンコーディング下ã§ãƒ•ã‚¡ãƒŸãƒª<family>ãŒå®šç¾©ã•ã‚Œã¦ã„ã‚Œã°ï¼Œ
+ <family>ã¯æ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã¨èªè­˜ã•ã‚Œï¼Œãƒªã‚¹ãƒˆ$F_{\mathrm{A}}$ã«<family>を追加ã™ã‚‹ã“ã¨ã§ã“ã®ã“ã¨ã‚’記憶ã™ã‚‹ï¼Ž
+%</ja>
+%<*en>
+\item Now \LuaTeX-ja looks whether there exists an alphabetic font encoding~<enc> such that
+ a font definition named \texttt{<enc><family>.fd} (the file name is
+ all lowercase) exists. If so, current alphabetic font family will be changed to
+ <family>~(the font definition file won't be loaded here).
+ If not, current alphabetic font family won't be changed, and
+ <family> is appended to the list~$N_{\mathrm{A}}$.
+%</en>
+%<*ja>
+\item 最終段階ã§ã¯ï¼Œæ¬§æ–‡ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°<enc>ã§
+フォント定義ファイル\texttt{<enc><family>.fd}(ファイルåã¯å…¨ã¦å°æ–‡å­—)ãŒå­˜åœ¨ã™ã‚‹ã‚ˆã†ãªã‚‚
+ ã®ãŒã‚ã‚‹ã‹ã©ã†ã‹ã‚’調ã¹ã‚‹ï¼Ž
+存在ã™ã‚Œã°ï¼Œ<family>ã¯æ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã¨èªè­˜ã•ã‚Œã‚‹ï¼ˆãƒ•ã‚©ãƒ³ãƒˆå®šç¾©ãƒ•ã‚¡ã‚¤ãƒ«ã¯èª­ã¿è¾¼ã¾ã‚Œãªã„).
+存在ã—ãªã‘ã‚Œã°ï¼Œ<family>ã¯æ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã¨èªè­˜ã•ã‚Œãªã„ã®ã§ï¼Œãƒªã‚¹ãƒˆ$N_{\mathrm{A}}$ã«
+ <family>を追加ã—ã¦ãã®ã“ã¨ã‚’記憶ã™ã‚‹ï¼Ž
+%</ja>
+\end{enumerate}
+
+%<*en>
+Also, each call of \cs{DeclareFontFamily} \emph{after} loading of \LuaTeX-ja makes
+the second argument (family) is appended to the list~$F_{\mathrm{A}}$.
+%</en>
+%<*ja>
+ã¾ãŸï¼Œ\cs{DeclareFontFamily}ãŒ\LuaTeX-jaã®èª­ã¿è¾¼ã¿å¾Œã«å®Ÿè¡Œã•ã‚ŒãŸå ´åˆã¯ï¼Œ
+第2引数(ファミリå)ãŒè‡ªå‹•çš„ã«$F_{\mathrm{A}}$ã«è¿½åŠ ã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+The above order is very similar to \cs{fontfamily} in \pLaTeXe, but more complicated (clause~3.).
+This is because \pLaTeXe\ is a \emph{format} however \LuaTeX-ja is not,
+hence \LuaTeX-ja does not know calls of \cs{DeclareFontFamily} \emph{before} itself is
+loaded.
+%</en>
+%<*ja>
+以上ã®æ–¹é‡ã¯\pLaTeXe ã«ãŠã‘ã‚‹ \cs{fontfamily} ã«ã‚„ã¯ã‚Šé¡žä¼¼ã—ã¦ã„ã‚‹ãŒï¼Œ3.ãŒåŠ ã‚り若干複雑ã«ãªã£ã¦ã„る.
+ãã‚Œã¯\pLaTeXe ãŒãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã§ã‚ã‚‹ã®ã«å¯¾ã—\LuaTeX-jaã¯ãã†ã§ãªã„ãŸã‚,
+\LuaTeX-jaã¯è‡ªèº«ãŒèª­ã¿è¾¼ã¾ã‚Œã‚‹å‰ã«ã©ã†ã„ã†\cs{DeclareFontFamily}ã®å‘¼ã³å‡ºã—ãŒã‚ã£ãŸã‹
+把æ¡ã§ããªã„ã‹ã‚‰ã§ã‚る.
+%</ja>
+
+%<en>\paragraph{Remarks}
+%<ja>\paragraph{注æ„}
+%<*en>
+Of course, there is a case that <family> is not recognized as a Japanese font family, nor
+an alphabetic font family.
+In this case, \LuaTeX-ja treats ``the argument <family> is wrong'', so
+set both current alphabetic and Japanese font family to <family>,
+to use the default family for font substitution.
+%</en>
+%<*ja>
+ã•ã¦ï¼Œå¼•æ•°ã«ã‚ˆã£ã¦ã¯ï¼Œã€Œå’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã¨ã‚‚欧文フォントファミリもèªè­˜ã•ã‚Œãªã‹ã£ãŸã€
+ã¨ã„ã†äº‹æ…‹ã‚‚ã‚り得る.
+ ã“ã®å ´åˆï¼Œå¼•æ•°<family>ã¯ä¸æ­£ã ã£ãŸï¼Œã¨ã„ã†ã“ã¨ã«ãªã‚‹ã®ã§ï¼Œ
+和文・欧文ã®ä¸¡æ–¹ã®ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã‚’<family>ã«è¨­å®šã—,代用フォントãŒä½¿ã‚れるã«ä»»ã›ã‚‹ã“ã¨ã«ã™ã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+\subsection{Notes on \cs{DeclareTextSymbol}}
+From \LaTeX~2017/01/01, the standard encoding of \LuaLaTeX\ is changed to the \texttt{TU}
+encoding. This menas that symbols defined by \texttt{T1}~and~\texttt{TS1} encodings can be used
+without loading any package. To produces these symbols in alphabetic fonts in \LuaTeX-ja,
+\LuaTeX-ja patches \cs{DeclareTextSymbol}, and reloads \texttt{tuenc.def}.
+
+Under original definition of \cs{DeclareTextSymbol},
+internal commands which is defined by \cs{DeclareTextSymbol} (such as \cs{T1\cs{textquotedblleft}})
+are \textit{chardef} tokens. However, this no longer holds in \LuaTeX-ja;
+for example, the meaning of \cs{TU\cs{textquotedblleft}} is \cs{ltjalchar8220\ltjalchar"2423 }.
+%</en>
+%<*ja>
+\subsection{\cs{DeclareTextSymbol}使用時ã®æ³¨æ„}
+\LaTeX~(2017/01/01)以é™ã§ã¯ï¼Œ\texttt{TU}エンコーディングãŒæ¨™æº–ã¨ãªã‚Šï¼Œç‰¹ã«ä½•ã‚‚ã—ãªãã¦ã‚‚
+\texttt{T1},~\texttt{TS1}エンコーディングã§å®šç¾©ã•ã‚Œã¦ã„ãŸè¨˜å·é¡žãŒ
+使ãˆã‚‹ã‚ˆã†ã«ãªã£ãŸï¼Ž\LuaTeX-jaã§ã¯ã“れらã®å‘½ä»¤ã«ã‚ˆã£ã¦è¨˜å·ãŒæ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆã§å‡ºåŠ›ã•ã‚Œã‚‹ã‚ˆã†ã«ã™ã‚‹ãŸã‚,
+\cs{DeclareTextSymbol}命令を改変ã—,ãã—ã¦\texttt{TU}エンコーディングã®å®šç¾©ã§ã‚ã‚‹
+\texttt{tuenc.def}ã‚’å†èª­è¾¼ã—ã¦ã„る.
+
+従æ¥ã¯ \cs{DeclareTextSymbol} ã§å†…部的ã«å®šç¾©ã•ã‚ŒãŸ\cs{T1\cs{textquotedblleft}}ã¨ã„ã£ãŸå‘½ä»¤ã¯
+\textit{chardef}トークンã§ã‚ã£ãŸï¼Žã—ã‹ã—å‰æ®µè½ã§è¿°ã¹ãŸæ”¹å¤‰ã«ã‚ˆã‚Šã‚‚ã¯ã‚„ãã†ã§ã¯ãªããªã£ã¦ãŠã‚Šï¼Œä¾‹ãˆã°
+\cs{TU\cs{textquotedblleft}}㯠\cs{ltjalchar8220\ltjalchar"2423 } ã¨ã„ã†å®šç¾©ã«ãªã£ã¦ã„る.%"
+%</ja>
+
+\begin{table}[t]
+ \centering\small
+ \caption{strut}\label{tab:strutbox}\medskip
+ \begin{tabular}{llcccl}
+ \toprule
+ \textbf{box}&\textbf{direction}&\textbf{width}&\textbf{height}&\textbf{depth}
+ &\textbf{user command}\\
+ \midrule
+ \cs{ystrutbox}&yoko&0&0.7\cs{baselineskip}&0.3\cs{baselineskip}&\cs{ystrut}\\\midrule
+ \cs{tstrutbox}&tate, utod&0&0.5\cs{baselineskip}&0.5\cs{baselineskip}&\cs{tstrut}\\\midrule
+ \cs{dstrutbox}&dtou&0&0.7\cs{baselineskip}&0.3\cs{baselineskip}&\cs{dstrut}\\\midrule
+ \cs{zstrutbox}&---&0&0.7\cs{baselineskip}&0.3\cs{baselineskip}&\cs{zstrut}\\\bottomrule
+ \end{tabular}
+\end{table}
+%<*en>
+\subsection{\cs{strutbox}}
+As \pLaTeX~(2017/04/08 or later), \cs{strutbox} is \emph{a macro} which is expanded to one of
+\cs{ystrutbox},~\cs{tstrutbox},~and~\cs{dstrutbox}
+(all of them are shown in \autoref{tab:strutbox}), according to the current direction.
+Similarly, \cs{strut} now uses one of these boxes.
+%</en>
+%<*ja>
+\subsection{\cs{strutbox}}
+\pLaTeX~2017/04/08以é™ã¨åŒã˜ã‚ˆã†ã«ï¼Œ
+\cs{strutbox}ã¯ç¾åœ¨ã®çµ„æ–¹å‘ã«ã‚ˆã£ã¦\cs{ystrutbox}, \cs{tstrutbox}, \cs{dstrutbox}ã®
+ã„ãšã‚Œã‹ã«å±•é–‹ã•ã‚Œã‚‹\emph{マクロ}ã¨ãªã£ã¦ã„る(ã“れらã«ã¤ã„ã¦ã¯\autoref{tab:strutbox}å‚照).
+åŒæ§˜ã«\cs{strut}ã‚‚ã“ã®3\nobreak ボックスã®ã„ãšã‚Œã‹ã‚’組方å‘ã«ã‚ˆã£ã¦ä½¿ã„分ã‘るよã†ã«ãªã£ã¦ã„る.
+
+\cs{zstrutbox}ã¯utodæ–¹å‘(\pTeX ã§ã„ã†ç¸¦æ•°å¼ãƒ‡ã‚£ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ï¼‰ã§ä½¿ã‚れる支柱ボックスã§ã‚ã‚‹ãŒï¼Œ
+実際ã«ä½¿ã‚れるã®ã¯\cs{zstrut}ãŒæ˜Žç¤ºçš„ã«ç™ºè¡Œã•ã‚ŒãŸæ™‚,ãã—ã¦
+\Pkg{lltjext}パッケージã§è¿½åŠ ã•ã‚Œã‚‹çµ„æ–¹å‘指定㧠\texttt{<u>} を指定ã—ãŸæ™‚,ãŠã‚ˆã³
+周囲ãŒç¸¦çµ„ã®çŠ¶æ³ã§ \texttt{<z>} を指定ã—ãŸæ™‚ã«é™ã‚‰ã‚Œã¦ã„る.
+%</ja>
+
+%<*en>
+\section{Addon packages}
+\LuaTeX-ja has several addon packages.
+These addons are written as \LaTeX\ packages, but
+\Pkg{luatexja-otf} and~\Pkg{luatexja-adjust} can be loaded in plain \LuaTeX\
+by \cs{input}.
+%</en>
+%<*ja>
+\section{拡張パッケージ}
+\LuaTeX-jaã«ã¯ï¼ˆå‹•ä½œã«ã¯å¿…é ˆã§ã¯ãªã„ãŒï¼‰è‡ªç”±ã«èª­ã¿è¾¼ã‚ã‚‹æ‹¡å¼µãŒä»˜å±žã—ã¦ã„る.
+ã“れらã¯\LaTeX ã®ãƒ‘ッケージã¨ã—ã¦åˆ¶ä½œã—ã¦ã„ã‚‹ãŒï¼Œ
+\Pkg{luatexja-otf}ã¨\Pkg{luatexja-adjust}ã«ã¤ã„ã¦ã¯plain \LuaTeX ã§ã‚‚\
+\cs{input} ã§èª­ã¿è¾¼ã¿å¯èƒ½ã§ã‚る.
+%</ja>
+\subsection{\Pkg{luatexja-fontspec}}
+\label{ssec:fontspec2}
+%<*en>
+As described in Subsection~\ref{ssec:fontspec}, this optional package
+provides the counterparts for several commands defined in the
+\Pkg{fontspec} package (requires \Pkg{fontspec}~v2.4).
+In addition to OpenType font features in the original \Pkg{fontspec},
+the following ``font features'' specifications are allowed for
+the commands of Japanese version:
+%</en>
+%<*ja>
+\ref{ssec:fontspec}節ã§è¿°ã¹ãŸã‚ˆã†ã«ï¼Œã“ã®è¿½åŠ ãƒ‘ッケージã¯\Pkg{fontspec}%
+パッケージã§å®šç¾©ã•ã‚Œã¦ã„るコマンドã«å¯¾å¿œã™ã‚‹å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆç”¨ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’æä¾›ã™ã‚‹ï¼Ž
+
+\Pkg{fontspec}パッケージã§æŒ‡å®šå¯èƒ½ãªå„種OpenType機能ã«åŠ ãˆã¦ï¼Œå’Œæ–‡ç‰ˆã®ã‚³ãƒžãƒ³ãƒ‰ã«ã¯
+以下ã®ã€Œãƒ•ã‚©ãƒ³ãƒˆæ©Ÿèƒ½ã€ã‚’指定ã™ã‚‹ã“ã¨ãŒã§ãる:
+%</ja>
+
+
+\begin{cslist}
+\item[CID=<name>\textrm{, }JFM=<name>\textrm{, }JFM-var=<name>]
+
+%<*en>
+These 3 keys correspond to \texttt{cid}, \texttt{jfm} and
+\texttt{jfmvar} keys for \cs{jfont}~and~\cs{tfont} respectively.
+See Subsections~\ref{ssec:jfont} and \ref{ssec:psft} for details
+ of \texttt{cid}, \texttt{jfm} and
+\texttt{jfmvar} keys.
+
+The \texttt{CID} key is effective only when with \texttt{NoEmbed}
+described below. The same JFM cannot be used in both horizontal Japanese fonts and
+ vertical Japanese fonts, hence the \texttt{JFM} key
+will be actually used in \texttt{YokoFeatures}~and~\texttt{TateFeatures} keys.
+%</en>
+%<*ja>
+ã“れら3ã¤ã®ã‚­ãƒ¼ã¯ãã‚Œãžã‚Œ \cs{jfont},~\cs{tfont}ã«å¯¾ã™ã‚‹
+\texttt{cid}, \texttt{jfm}, \texttt{jfmvar}キーã¨ãã‚Œãžã‚Œå¯¾å¿œã™ã‚‹ï¼Ž
+\texttt{cid}, \texttt{jfm}, \texttt{jfmvar}キーã®è©³ç´°ã¯\ref{ssec:jfont}節
+ ã¨\ref{ssec:psft}節をå‚照.
+
+\texttt{CID} キーã¯ä¸‹ã® \texttt{NoEmbed} ã¨åˆã‚ã›ã¦ç”¨ã„られãŸã¨ãã®ã¿æœ‰åŠ¹ã§ã‚る.
+ã¾ãŸï¼Œæ¨ªçµ„用JFMã¨ç¸¦çµ„用JFMã¯å…±ç”¨ã§ããªã„ãŸã‚,実際㫠\texttt{JFM} キーを用ã„ã‚‹éš›ã¯
+後ã«è¿°ã¹ã‚‹\ \texttt{YokoFeatures} キーや \texttt{TateFeatures}\ ã®ä¸­ã§ç”¨ã„ã‚‹
+ã“ã¨ã«ãªã‚‹ï¼Ž
+%</ja>
+
+\item[NoEmbed]
+%<*en>
+By specifying this key, one can use ``name-only'' Japanese font which
+will not be embedded in the output PDF file. See Subsection~\ref{ssec:psft}.
+%</en>
+%<*ja>
+ã“れを指定ã™ã‚‹ã“ã¨ã§ï¼ŒPDFã«åŸ‹ã‚è¾¼ã¾ã‚Œãªã„「åå‰ã ã‘ã€ã®ãƒ•ã‚©ãƒ³ãƒˆã‚’指定ã™ã‚‹ã“ã¨ãŒ
+ã§ãる.\ref{ssec:psft}節をå‚照.
+%</ja>
+
+\begin{figure}[!tb]
+\begin{LTXexample}[width=0.25\textwidth]
+\jfontspec[
+ YokoFeatures={Color=007F00}, TateFeatures={Color=00007F},
+ TateFont=KozGoPr6N-Regular
+]{KozMinPr6N-Regular}
+\hbox{\yoko 横組ã®ãƒ†ã‚¹ãƒˆ}\hbox{\tate 縦組ã®ãƒ†ã‚¹ãƒˆ}
+\addjfontfeatures{Color=FF0000}
+\hbox{\yoko 横組}\hbox{\tate 縦組}
+\end{LTXexample}
+%<ja>\caption{\texttt{TateFeatures} ç­‰ã®ä½¿ç”¨ä¾‹}
+%<en>\caption{An example of \texttt{TateFeatures} etc.}
+\label{fig:yokotate-fontspec}
+\end{figure}
+
+\item[Kanjiskip=<bool>]
+%<*ja>
+\pageref{pg:ltjksp}ページã§èª¬æ˜Žã—㟠\verb+\jfont+ 中ã§ã® \texttt{ltjksp} 指定ã¨
+åŒä¸€ã®åŠ¹åŠ›ã‚’æŒã¡ï¼Œ
+JFM中ã«ãŠã‘ã‚‹ \texttt{kanjiskip\_natural}, \texttt{kanjiskip\_stretch},\
+\texttt{kanjiskip\_shrink}キー(\pageref{pg:ksp_nat}ページ)ã®æœ‰åŠ¹/無効を切り替ãˆã‚‹ï¼Ž
+標準値㯠\texttt{true} ã§ã‚る.
+%</ja>
+
+\item[TateFeatures=\{<features>\}\textrm{, }TateFont=<font>]
+%<*en>
+The \texttt{TateFeatures} key specifies font features which are only turned~on in
+vertical writing, such as \texttt{Style=VerticalKana}~(\texttt{vkna} feature).
+Similarly, the \texttt{TateFont} key specifies the Japanese font which will be used only
+ in vertical writing.
+A demonstrarion is shown in \autoref{fig:yokotate-fontspec}.
+%</en>
+%<*ja>
+縦組ã«ãŠã„ã¦ä½¿ç”¨ã•ã‚Œã‚‹ãƒ•ã‚©ãƒ³ãƒˆã‚„,縦組ã«ãŠã„ã¦ã®ã¿é©ç”¨ã•ã‚Œã‚‹ãƒ•ã‚©ãƒ³ãƒˆæ©Ÿèƒ½é”ã‚’
+指定ã™ã‚‹ï¼Žä½¿ç”¨ä¾‹ã¯\autoref{fig:yokotate-fontspec}å‚照.
+%</ja>
+
+\item[YokoFeatures=\{<features>\}]
+%<*en>
+The \texttt{YokoFeatures} key specifies font features which are only turned~on in
+horizontal writing,.
+A demonstrarion is shown in \autoref{fig:yokotate-fontspec}.
+%</en>
+%<*ja>
+åŒæ§˜ã«ï¼Œæ¨ªçµ„ã«ãŠã„ã¦ã®ã¿é©ç”¨ã•ã‚Œã‚‹ãƒ•ã‚©ãƒ³ãƒˆæ©Ÿèƒ½é”ã‚’
+指定ã™ã‚‹ï¼Žä½¿ç”¨ä¾‹ã¯\autoref{fig:yokotate-fontspec}å‚照.
+%</ja>
+
+
+\begin{figure}[!tb]
+\begin{LTXexample}[pos=b]
+\jfontspec[
+ AltFont={
+ {Range="4E00-"67FF, Color=007F00},
+ {Range="6800-"9EFF, Color=0000FF},
+ {Range="3040-"306F, Font=KozGoPr6N-Regular},
+ }
+]{KozMinPr6N-Regular}
+日本国民ã¯ã€æ­£å½“ã«é¸æŒ™ã•ã‚ŒãŸå›½ä¼šã«ãŠã‘る代表者を通ã˜ã¦è¡Œå‹•ã—ã€ã‚れらã¨ã‚れらã®å­å­«ã®ãŸã‚ã«ã€
+諸国民ã¨ã®å”å’Œã«ã‚ˆã‚‹æˆæžœã¨ã€ã‚ãŒå›½å…¨åœŸã«ã‚ãŸã¤ã¦è‡ªç”±ã®ã‚‚ãŸã‚‰ã™æµæ²¢ã‚’確ä¿ã—ã€â€¦â€¦
+\end{LTXexample}
+%<ja>\caption{\texttt{AltFont} ã®ä½¿ç”¨ä¾‹}
+%<en>\caption{An example of \texttt{AltFont}}
+\label{fig:altkanji-fontspec}
+\end{figure}
+
+\item[AltFont]
+
+%<*en>
+As \cs{ltjdeclarealtfont}~(Subsection~\ref{ssec:altfont}) and
+\cs{DeclareAlternateKanjiFont}~(Subsection~\ref{ssec:nfsspat}),
+with this key, one can typeset some Japanese characters
+by a different font and/or using different features.
+The \texttt{AltFont} feature takes a comma-separated list of comma-separated lists,
+as the following:
+%</en>
+%<*ja>
+\ref{ssec:altfont}節㮠\cs{ltjdeclarealtfont} や,
+\ref{ssec:nfsspat}節㮠\cs{DeclareAlternateKanjiFont} ã¨åŒæ§˜ã«ï¼Œ
+ã“ã®ã‚­ãƒ¼ã‚’用ã„ã‚‹ã¨ä¸€éƒ¨ã®æ–‡å­—ã‚’ç•°ãªã£ãŸãƒ•ã‚©ãƒ³ãƒˆã‚„機能ãŸã¡ã‚’使ã£ã¦çµ„ã‚€ã“ã¨ãŒã§ãる.
+\texttt{AltFont} キーã«æŒ‡å®šã™ã‚‹å€¤ã¯ï¼Œæ¬¡ã®ã‚ˆã†ã«äºŒé‡ã®ã‚³ãƒ³ãƒžåŒºåˆ‡ã‚Šãƒªã‚¹ãƒˆã§ã‚る:
+%</ja>
+\begin{lstlisting}[escapechar=\#]
+AltFont = {
+ ...
+ { Range=#\LARG range>#, #\LARG features>#},
+ { Range=#\LARG range>#, Font=#\LARG font~name>#, #\LARG features># },
+ { Range=#\LARG range>#, Font=#\LARG font~name># },
+ ...
+}
+\end{lstlisting}
+%<*en>
+Each sublist should have the \texttt{Range} key
+(sublist which does not contain \texttt{Range} key is simply ignored).
+A demonstrarion is shown in \autoref{fig:altkanji-fontspec}.
+%</en>
+%<*ja>
+å„部分リストã«ã¯ \texttt{Range} キーãŒå¿…é ˆã§ã‚る(å«ã¾ã‚Œãªã„部分リストã¯
+å˜ç´”ã«ç„¡è¦–ã•ã‚Œã‚‹ï¼‰ï¼ŽæŒ‡å®šä¾‹ã¯\autoref{fig:altkanji-fontspec}ã«ç¤ºã—ãŸï¼Ž
+%</ja>
+\end{cslist}
+
+%<*ja>
+ãªãŠï¼Œ\Pkg{luatexja-fontspec} 読ã¿è¾¼ã¿æ™‚ã«ã¯å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆå®šç¾©ãƒ•ã‚¡ã‚¤ãƒ«%
+\texttt{<ja-enc><family>.fd}ã¯å…¨ãå‚ç…§ã•ã‚Œãªããªã‚‹ï¼Ž
+%</ja>
+
+
+%<*en>
+\paragraph{Remark on \texttt{AltFont}, \texttt{YokoFeatures}, \texttt{TateFeatures} keys}
+\leavevmode\par
+In \texttt{AltFont},~\texttt{YokoFeatures},~\texttt{TateFeatures} keys,
+one cannot specify per-shape settings such as \texttt{BoldFeatures}.
+For example,
+\begin{lstlisting}
+AltFont = {
+ { Font=HogeraMin-Light, BoldFont=HogeraMin-Bold,
+ Range="3000-"30FF, BoldFeatures={Color=007F00} }
+}
+\end{lstlisting}
+does \emph{not} work. Instead, one have to write
+\begin{lstlisting}
+UprightFeatures = {
+ AltFont = { { Font=HogeraMin-Light, Range="3000-"30FF, } },
+},
+BoldFeatures = {
+ AltFont = { { Font=HogeraMin-Bold, Range="3000-"30FF, Color=007F00 } },
+}
+\end{lstlisting}
+
+On the other hand, \texttt{YokoFeatures}, \texttt{TateFeatures} and \texttt{TateFont}
+keys can be specified in each list in the \texttt{AltFont} key. Also,
+one can specify \texttt{AltFont} inside \texttt{YokoFeatures},~\texttt{TateFeatures}.
+
+Note that features which are specified in \texttt{YokoFeatures}~and~\texttt{TateFeatures}
+are always interpreted \emph{after} other ``direction-independent'' features.
+This explains why \cs{addjfontfeatures} at~line~6 in~\autoref{fig:yokotate-fontspec}
+has no effect, because a color specification is already done in
+\texttt{YokoFeatures}~and~\texttt{TateFeatures} keys.
+%</en>
+%<*ja>
+\paragraph{\texttt{AltFont}, \texttt{YokoFeatures}, \texttt{TateFeatures} ç­‰ã®åˆ¶é™}
+\texttt{AltFont},~\texttt{YokoFeatures},~\texttt{TateFeatures}ã®å„キーã¯
+シェイプ別ã«æŒ‡å®šã•ã‚Œã‚‹ã¹ãã‚‚ã®ã§ã‚り,
+内部ã§ã¯ \texttt{BoldFeatures} ãªã©ã®ã‚·ã‚§ã‚¤ãƒ—別ã®æŒ‡å®šã¯è¡Œã†ã“ã¨ãŒå‡ºæ¥ãªã„.
+例ãˆã°ï¼Ž
+\begin{lstlisting}
+AltFont = {
+ { Font=HogeraMin-Light, BoldFont=HogeraMin-Bold,
+ Range="3000-"30FF, BoldFeatures={Color=007F00} }
+}
+\end{lstlisting}
+ã®ã‚ˆã†ã«æŒ‡å®šã™ã‚‹ã“ã¨ã¯å‡ºæ¥ãšï¼Œ
+\begin{lstlisting}
+UprightFeatures = {
+ AltFont = { { Font=HogeraMin-Light, Range="3000-"30FF, } },
+},
+BoldFeatures = {
+ AltFont = { { Font=HogeraMin-Bold, Range="3000-"30FF, Color=007F00 } },
+}
+\end{lstlisting}
+ã®ã‚ˆã†ã«æŒ‡å®šã—ãªã‘ã‚Œã°ãªã‚‰ãªã„.
+
+一方,\texttt{AltFont} キー内ã®å„リストã§ã¯
+\ \texttt{YokoFeatures},~\texttt{TateFeatures} åŠã³ \texttt{TateFont} キーを
+指定ã™ã‚‹ã“ã¨ã¯å¯èƒ½ã§ã‚り.ã¾ãŸ\ \texttt{YokoFeatures},~\texttt{TateFeatures} キーã®
+中身㫠\texttt{AltFont} を指定ã™ã‚‹ã“ã¨ãŒã§ãる.
+
+ã¾ãŸï¼Œ\autoref{fig:yokotate-fontspec}後åŠéƒ¨ã§ã¯6行目ã®è‰²ã®æŒ‡å®šãŒåŠ¹ã‹ãšï¼Œ
+2行目ã§æŒ‡å®šã—ãŸ\ \texttt{YokoFeatures},~\texttt{TateFeatures}\ ã«ã‚ˆã‚‹è‰²ã®æŒ‡å®šãŒæœ‰åŠ¹ã«ãªã£
+ãŸã¾ã¾ã§ã‚る.ã“ã‚Œã¯\emph{\ \texttt{YokoFeatures},~\texttt{TateFeatures}\ ã«ã‚ˆã‚‹
+OpenType機能指定ã¯
+組方å‘ã«ä¾å­˜ã—ãªã„OpenType機能ã®æŒ‡å®šã‚ˆã‚Šå¾Œã«è§£é‡ˆã•ã‚Œã‚‹}ã‹ã‚‰ã§ã‚る.
+
+%</ja>
+
+
+\subsection{\Pkg{luatexja-otf}}
+\label{ssec:ltjotf}
+%<*en>
+This optional package supports typesetting glyphs
+by specifying a CID number.
+The package \Pkg{luatexja-otf} offers the following 2~low-level
+commands:
+%</en>
+%<*ja>
+ã“ã®è¿½åŠ ãƒ‘ッケージã¯CID番å·ã«ã‚ˆã‚‹æ–‡å­—ã®å‡ºåŠ›ã‚’サãƒãƒ¼ãƒˆã™ã‚‹ï¼Ž
+\Pkg{luatexja-otf}ã¯ä»¥ä¸‹ã®2ã¤ã®ä½Žãƒ¬ãƒ™ãƒ«ã‚³ãƒžãƒ³ãƒ‰ã‚’æä¾›ã™ã‚‹ï¼š
+%</ja>
+\begin{cslist}
+\item[\cs{CID}\{<number>\}]
+%<*en>
+Typeset a glyph whose CID number is <number>.
+If the Japanese font is neither Adobe-Japan1,~Adobe-GB1, Adobe-CNS1,
+Adobe-Korea1,~nor~Adobe-KR CID-keyed font,
+\LuaTeX-ja treats that <number> is a CID number of Adobe-Japan1 character collection,
+and tries to typeset a ``most suitable glyph''.
+%</en>
+%<*ja>
+CID番å·ãŒ<number>ã®æ–‡å­—を出力ã™ã‚‹ï¼Ž
+ã‚‚ã—ç¾åœ¨ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãŒAdobe-Japan1,~Adobe-GB1, Adobe-CNS1, Adobe-Korea1,~Adobe-KRã®
+ ã„ãšã‚Œã®CID-keyed fontã§ã‚‚ãªã„å ´åˆï¼Œ<number>ã¯Adobe-Japan1ã®CID番å·ã§ã‚ã‚‹ã¨è§£é‡ˆã—
+ 「é©åˆ‡ãªã‚°ãƒªãƒ•ã€\footnote{%
+ 特ã«ç¸¦çµ„用グリフã®CID番å·ã‚’指定ã—ãŸå ´åˆã¯ï¼ˆLuaTeX-ja 20190504.0以é™ã§ã¯è‹¥å¹²æ”¹è‰¯ã•ã‚Œã¦ã„ã‚‹ãŒï¼‰
+ æ„図ã—ãªã„çµæžœã«ãªã‚‹å¯èƒ½æ€§ãŒé«˜ã„.
+ ãªãŠï¼Œãƒãƒ¼ã‚¸ãƒ§ãƒ³20190708.0以é™ã§ã¯ï¼ŒCIDã‹ã‚‰ã‚°ãƒªãƒ•ã¸ã®é¸æŠžã«ã‚°ãƒªãƒ•åã®æƒ…報を使用ã—ã¦ã„ãªã„.
+ ã¾ãŸï¼Œãƒ•ã‚©ãƒ³ãƒˆã«IVDコレクションAdobe-Japan1ãŒå«ã¾ã‚Œã¦ã„ã‚Œã°ï¼Œãã®æƒ…報を用ã„ã¦
+ グリフをé¸æŠžã™ã‚‹ï¼Ž
+}を出力ã™ã‚‹ï¼Ž
+%</ja>
+
+\item[\cs{UTF}\{<hex\_number>\}]
+%<*en>
+Typeset a character whose character code is <hex\_number> (in hexadecimal).
+This command is similar to \verb+\char"+<hex\_number>,\ %"
+but please remind remarks below.
+%</en>
+%<*ja>
+文字コードãŒï¼ˆ16進ã§ï¼‰<hex\_number>ã®æ–‡å­—を出力ã™ã‚‹ï¼Ž
+ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ \verb+\char"+<hex\_number>ã¨ä¼¼ã¦ã„ã‚‹ãŒï¼Œä¸‹ã®æ³¨æ„ã‚’å‚ç…§ã™ã‚‹ã“ã¨ï¼Ž%"
+%</ja>
+\end{cslist}
+
+%<*ja>
+ã“ã®ãƒ‘ッケージã¯ï¼Œãƒžã‚¯ãƒ­é›† \texttt{luatexja-ajmacros.sty}\footnote{\Pkg{otf}パッケージ付属ã®äº•ä¸Šæµ©ä¸€æ°ã«ã‚ˆã‚‹ãƒžã‚¯ãƒ­é›†
+\texttt{ajmacros.sty} ã«å¯¾ã—ã¦
+漢字コードをUTF-8ã«ã—ãŸã‚Šï¼Œplain \LuaTeX ã§ã‚‚利用å¯èƒ½ã«ã™ã‚‹ã¨ã„ã†
+修正を加ãˆãŸã‚‚ã®ã§ã‚る.}\ も自動的ã«èª­ã¿è¾¼ã‚€ï¼Ž
+\texttt{luatexja-ajmacros.sty} ã¯ï¼Œ
+ãã®ãŸã‚,\Pkg{luatexja-otf} を読ã¿ã“ã‚ã° \texttt{ajmacros.sty} マクロ集ã«ã‚ã‚‹ \cs{ajåŠè§’} ãªã©ã®ãƒžã‚¯ãƒ­ã‚‚ãã®ã¾ã¾ä½¿ã†ã“ã¨ãŒã§ãる.
+%</ja>
+%<*en>
+This package automatically loads \texttt{luatexja-ajmacros.sty}, which is slightly
+modified version of \texttt{ajmacros.sty}\footnote{Useful macros by iNOUE Koich!, for the
+\Pkg{japanese-otf} package.}.
+Hence one can use macros which sre defined in \texttt{ajmacros.sty}, such as~\cs{ajåŠè§’}.
+%</en>
+
+%<en>\paragraph{Remarks}
+%<ja>\paragraph{注æ„}
+%<*en>
+Characters by \cs{CID} and \cs{UTF} commands are different from
+ordinary characters in the following points:
+%</en>
+%<*ja>
+\cs{CID} 㨠\cs{UTF} コマンドã«ã‚ˆã£ã¦å‡ºåŠ›ã•ã‚Œã‚‹æ–‡å­—ã¯
+以下ã®ç‚¹ã§é€šå¸¸ã®æ–‡å­—ã¨ç•°ãªã‚‹ï¼š
+%</ja>
+\begin{itemize}
+%<*en>
+\item Always treated as \textbf{JAchar}s.
+%</en>
+%<*ja>
+\item 常ã«\textbf{JAchar}ã¨ã—ã¦æ‰±ã‚れる.
+%</ja>
+%<*en>
+\item In vertical direction, \texttt{vert}/\texttt{vrt2} feature are automatically applied to
+ characters by \cs{UTF}, regardless these feature are not activated in current Japanese font.
+%</en>
+%<*ja>
+\item 縦組時ã«ã¯ï¼Œç¾åœ¨ã®ç¸¦çµ„用和文フォント㧠\texttt{vert}/\texttt{vrt2} 機能ãŒ
+ 有効ã‹ç„¡åŠ¹ã‹ã‚’å•ã‚ãšï¼Œ\cs{UTF} ã§å‡ºåŠ›ã•ã‚Œã‚‹æ–‡å­—ã«ã¯ã“れらã®OpenType機能ãŒåƒã„ãŸå­—å½¢ã«ãªã‚‹ï¼Ž
+%</ja>
+%<*en>
+\item Processing codes for supporting other OpenType features (for example,
+ glyph replacement and kerning) by the \Pkg{luaotfload} package
+ is not performed to these characters.
+%</en>
+%<*ja>
+\item ãã®ä»–ã®OpenType機能(例ãˆã°ã‚°ãƒªãƒ•ç½®æ›ã‚„カーニング)をサãƒãƒ¼ãƒˆã™ã‚‹ãŸã‚ã®
+ \Pkg{luaotfload}パッケージã®ã‚³ãƒ¼ãƒ‰ã¯ã“れらã®æ–‡å­—ã«ã¯åƒã‹ãªã„.
+%</ja>
+\end{itemize}
+
+%<en>\paragraph{Additional syntax of JFM}
+%<ja>\paragraph{JFMã¸ã®è¨˜æ³•ã®è¿½åŠ }
+
+%<*en>
+The package \Pkg{luatexja-otf} extends the syntax of JFM; the entries of \texttt{
+chars} table in JFM now allows a string in the form
+\verb+'AJ1-xxx'+, which stands for the character
+whose CID number in Adobe-Japan1 is \verb+xxx+.
+
+This extended notation is used in the standard JFM \texttt{jfm-ujis.lua}
+to typeset halfwidth Hiragana glyphs (CID~516--598) in halfwidth.
+%</en>
+%<*ja>
+\Pkg{luatexja-otf}パッケージを読ã¿è¾¼ã‚€ã¨ï¼Œ
+JFMã®\texttt{chars}テーブルã®ã‚¨ãƒ³ãƒˆãƒªã¨ã—㦠\verb+'AJ1-xxx'+ ã®å½¢ã®æ–‡å­—列ãŒ
+使ãˆã‚‹ã‚ˆã†ã«ãªã‚‹ï¼Žã“ã‚Œã¯Adobe-Japan1ã«ãŠã‘ã‚‹CID番å·ãŒ \verb+xxx+ ã®æ–‡å­—を表ã™ï¼Ž
+
+ã“ã®æ‹¡å¼µè¨˜æ³•ã¯ï¼Œæ¨™æº–JFM~\texttt{jfm-ujis.lua}ã§ï¼ŒåŠè§’ã²ã‚‰ãŒãªã®ã‚°ãƒªãƒ•ï¼ˆCID~516--598)を
+æ­£ã—ãåŠè§’å¹…ã§çµ„ã‚€ãŸã‚ã«åˆ©ç”¨ã•ã‚Œã¦ã„る.
+%</ja>
+
+\subsection{\Pkg{luatexja-adjust}}
+\label{ssec:adj}
+\begin{figure}[t]
+\def\sq{%
+ \hbox to 1\zw{\hss\fboxsep=-.5\fboxrule\fbox{%
+  \hskip\dimexpr-.5\zw-.2pt\vrule width.4pt height.08\zw depth.12\zw%
+ \hskip\dimexpr.5\zw-.2pt\relax}\hss}}
+\def\sb{\hbox to 1\zw{\hss\fboxsep=-.5\fboxrule\fbox{%
+ â– \hskip\dimexpr-.5\zw-.2pt\vrule width.4pt height.08\zw depth.12\zw%
+ \hskip\dimexpr.5\zw-.2pt\relax}\hss}}
+\newbox\gridbox
+\def\outbox#1{{\Large%
+ \ltjsetparameter{kanjiskip=0pt plus .2\zw minus .2\zw}%
+ \setbox\gridbox=\hbox to 20\zw{\sq\sq\sq\sq\sb\sq\sq\sq\sq\sb\sq\sq\sq\sq\sb\sq\sq\sq\sq\sb}%
+ \hbox{\textcolor{cyan}{\copy\gridbox}\hskip-20\zw%
+ \vbox{\hsize=20\zw\noindent\leftskip0pt\rightskip0pt\parfillskip0pt#1}\vrule}%
+}}
+
+{\centering
+\begin{tabular}{lc}
+\toprule
+no adjustment&\outbox{以上ã®åŽŸç†ã¯ï¼Œã€ŒåŒ…除原ç†ã€ã¨ã‚ˆã呼ã°ã‚Œã‚‹ãŒ\hskip-.5\zw\null}\\
+without priority&%
+\ltjdisableadjust
+\outbox{以上ã®åŽŸç†ã¯ï¼Œã€ŒåŒ…除原ç†ã€ã¨ã‚ˆã呼ã°ã‚Œã‚‹ãŒ}%
+\ltjenableadjust\\
+with priority&%
+\outbox{以上ã®åŽŸç†ã¯ï¼Œã€ŒåŒ…除原ç†ã€ã¨ã‚ˆã呼ã°ã‚Œã‚‹ãŒ}
+%<en>\ltjdisableadjust
+\\
+\bottomrule
+\end{tabular}\par}
+\medskip
+
+\fakefn{}{The value of
+\Param{kanjiskip} is 0\,pt${}^{+1/5\,\mathrm{em}}_{-1/5\,\mathrm{em}}$ in this figure,
+for making the difference obvious.}
+%<ja>\caption{行長調整}\label{fig:adj}
+%<en>\caption{Line adjustment}\label{fig:adj}
+\end{figure}
+
+
+%<*en>
+(see Japanese version of this manual)
+%</en>
+%<*ja>
+ã“ã®è¿½åŠ ãƒ‘ッケージã¯ä»¥ä¸‹ã®æ©Ÿèƒ½ã‚’æä¾›ã™ã‚‹ï¼Žè©³ç´°ãªä»•æ§˜ã«ã¤ã„ã¦ã¯\ref{sec-adjspec}ç« ã‚’å‚ç…§ã—ã¦ã»ã—ã„.
+\begin{description}
+ \item[行末文字ã®ä½ç½®èª¿æ•´]
+ \pTeX ã§ã¯ï¼Œï¼ˆæ˜¯éžã¯ã¨ã‚‚ã‹ã)「行末ã®èª­ç‚¹ã¯ã¶ã‚‰ä¸‹ã’ã‹äºŒåˆ†å–ã‚Šã‹å…¨è§’å–ã‚Šã®ã„ãšã‚Œã‹ã«ã€ã®ã‚ˆã†ã«
+ 行末文字ã¨å®Ÿéš›ã®è¡Œæœ«ã®ä½ç½®é–¢ä¿‚ã‚’2通り以上ã«ã™ã‚‹ã“ã¨ã¯é¢å€’ã§ã‚ã£ãŸï¼Ž
+ 和文フォントメトリックã ã‘ã§ã¯ã€Œå¸¸ã«è¡Œæœ«ã®èª­ç‚¹ã¯ã¶ã‚‰ä¸‹ã’ã€ã¨ã„ã£ãŸã“ã¨ã—ã‹ã§ããšï¼Œ
+ å‰ã®æ–‡ã«æ›¸ã„ãŸã“ã¨ã‚’実ç¾ã™ã‚‹ã«ã¯
+ \begin{lstlisting}
+\def\。{%
+ \penalty10000 % ç¦å‰‡ãƒšãƒŠãƒ«ãƒ†ã‚£
+ \hbox to0pt{。\hss}\penalty0 % ã¶ã‚‰ä¸‹ã’ã®å ´åˆ
+ \kern.5\zw\penalty0 % 二分å–ã‚Šã®å ´åˆ
+ \kern.5\zw\penalty0 % 全角å–ã‚Šã®å ´åˆ
+}
+\end{lstlisting}
+ ã®ã‚ˆã†ãªå‘½ä»¤ã‚’定義ã—,文中ã®å…¨ã¦ã®å¥ç‚¹ã‚’ \lstinline+\。+ ã§æ›¸ãã“ã¨ãŒå¿…è¦ã ã£ãŸï¼Ž
+
+ \Pkg{luatexja-adjust}パッケージã¯ï¼Œä¸Šã§è¿°ã¹ãŸè¡Œæœ«æ–‡å­—ã¨å®Ÿéš›ã®è¡Œæœ«ã¨ã®ä½ç½®é–¢ä¿‚ã‚’
+ 2通り以上ã‹ã‚‰è‡ªå‹•çš„ã«é¸æŠžã™ã‚‹æ©Ÿèƒ½ã‚’æä¾›ã™ã‚‹ï¼Ž
+ \pdfTeX ã¨åŒã˜ã‚ˆã†ã«ï¼Œã€Œ\TeX ã«ã‚ˆã‚‹è¡Œåˆ†å‰²ã®å¾Œã§è¡Œæœ«æ–‡å­—ã®ä½ç½®ã‚’補正ã™ã‚‹ã€æ–¹æ³•ã¨
+ 「行分割ã®éŽç¨‹ã§è¡Œæœ«æ–‡å­—ã®ä½ç½®ã‚’考慮ã«å…¥ã‚Œã‚‹ã€æ–¹æ³•ã‚’é¸ã¹ã‚‹ã‚ˆã†ã«ã—ãŸ
+ (\Pkg{luatexja-adjust}パッケージã®æ—¢å®šã§ã¯å‰è€…).
+
+ \item[優先順ä½ä»˜ãã®è¡Œé•·èª¿æ•´]
+ \pTeX ã§ã¯ï¼Œè¡Œé•·èª¿æ•´ã«ãŠã„ã¦å„ªå…ˆåº¦ã®æ¦‚念ãŒå­˜åœ¨ã—ãªã‹ã£ãŸãŸã‚,図
+ \ref{fig:adj}上段ã«ãŠã‘ã‚‹åŠè§’分ã®åŠç«¯ã¯ï¼Œ\autoref{fig:adj}中段ã®ã‚ˆã†ã«ï¼Œéµ
+ 括弧周辺ã®ç©ºç™½ã¨å’Œæ–‡é–“空白(\Param{kanjiskip})ã®ä¸¡æ–¹ã«ã‚ˆã£ã¦è² æ‹…ã•ã‚Œã‚‹ï¼Žã—
+ ã‹ã—,「日本語組版処ç†ã®è¦ä»¶ã€\cite{jlreq}ã‚„JIS~X~4051~\cite{x4051}ã«ãŠã„
+ ã¦ã¯ï¼Œã“ã®ã‚ˆã†ãªçŠ¶æ³ã§ã¯åŠç«¯ã¯éµæ‹¬å¼§å‘¨è¾ºã®ç©ºç™½ã®ã¿ã§è² æ‹…ã—,ãã®ä»–ã®å’Œæ–‡
+ 文字ã¯ãƒ™ã‚¿çµ„ã§çµ„ã¾ã‚Œã‚‹ï¼ˆ\autoref{fig:adj}下段)ã“ã¨ã«ãªã£ã¦ã„る.
+ \Pkg{luatexja-adjust}パッケージã®æä¾›ã™ã‚‹ç¬¬2ã®æ©Ÿèƒ½ã¯ï¼Œ
+ \cite{jlreq}ã‚„\cite{x4051}ã«ãŠã‘ã‚‹è¦å®šã®ã‚ˆã†ãªï¼Œå„ªå…ˆé †ä½ä»˜ã
+ ã®è¡Œé•·èª¿æ•´ã§ã‚る.
+ \begin{itemize}
+ \item 優先度付ã行長調整ã¯ï¼Œæ®µè½ã‚’行分割ã—ãŸå¾Œã«å€‹ã€…ã®è¡Œã«ã¤ã„ã¦è¡Œã‚れるもã®ã§ã‚る.
+ ãã®ãŸã‚,行分割ã®ä½ç½®ã¯å¤‰åŒ–ã™ã‚‹ã“ã¨ã¯ãªã„.
+
+ \verb+\hbox{...}+ ã¨ã„ã£ãŸã€Œé€”中ã§æ”¹è¡Œã§ããªã„水平ボックスã€ã§ã¯ï¼ˆãŸã¨ãˆå¹…ãŒæŒ‡å®šã•ã‚Œã¦ã„ã¦ã‚‚)無効ã§ã‚る.
+ \item 優先度付ã行長調整を行ã†ã¨ï¼Œå’Œæ–‡å‡¦ç†ã‚°ãƒ«ãƒ¼ã®è‡ªç„¶é•·ã¯å¤‰åŒ–ã—ãªã„ãŒï¼Œä¼¸ã³é‡ã‚„縮ã¿é‡ã¯
+ 一般ã«å¤‰åŒ–ã™ã‚‹ï¼Žãã®ãŸã‚,既ã«çµ„ã¾ã‚ŒãŸæ®µè½ã‚’ \cs{unhbox} ãªã©ã‚’利用ã—ã¦çµ„ã¿ç›´ã™å‡¦ç†ã‚’
+ è¡Œã†å ´åˆã«ã¯æ³¨æ„ãŒå¿…è¦ã§ã‚る.
+ \end{itemize}
+
+ \item[「中身ã¾ã§ã¿ãŸã€è¡Œé€ã‚Šè¨ˆç®—]
+ 複数行ã«æ¸¡ã‚‹æ–‡ç« ã‚’組版ã™ã‚‹ã¨ãã«ã¯è¡Œé–“ã«ç©ºããŒå…¥ã‚‹ã“ã¨ãŒæ™®é€šã§ã‚る.
+ \TeX ã§ã¯å„è¡ŒãŒä¸€ã¤ãšã¤ã®æ°´å¹³ãƒœãƒƒã‚¯ã‚¹ã‚’ãªã—ã¦ã„ã‚‹ã“ã¨ã‚’æ€ã„出ã™ã¨ï¼Œéš£ã‚Šåˆã£ãŸ
+ 2ã¤ã®è¡Œï¼ˆã¤ã¾ã‚Šæ°´å¹³ãƒœãƒƒã‚¯ã‚¹ï¼‰ã®é–“ã®ç©ºãã¯æ¬¡ã®ã‚ˆã†ã«ã—ã¦æ±ºã¾ã‚‹ã®ã ã£ãŸï¼š
+ \begin{itemize}
+ \item 「通常ã«çµ„ã‚“ã ã¨ãã®è¡Œé–“ã€$d$を,\cs{baselineskip}ã‹ã‚‰
+ 「å‰ã®è¡Œã€ã®æ·±ã•ã¨ã€Œæ¬¡ã®è¡Œã€ã®é«˜ã•ã‚’加ãˆãŸã‚‚ã®ã‚’引ã„ãŸå€¤ã¨ã™ã‚‹ï¼Ž
+ \item $d\ge\cs{lineskiplimit}$ã®å ´åˆï¼Œ
+ 標準ã®è¡Œé€ã‚Š\cs{baselineskip}ã§çµ„ã‚“ã§ã‚‚å分ãªé–“éš”ãŒã‚ã‚‹ã¨åˆ¤æ–­ã•ã‚Œï¼Œ
+ 2è¡Œã®é–“ã«ã¯é•·ã•$d$ã®ç©ºç™½ãŒæŒ¿å…¥ã•ã‚Œã‚‹ï¼Žã¤ã¾ã‚Šè¡Œé€ã‚Šã¯\cs{baselineskip}.
+ \item {\catcode`\<=12$d<\cs{lineskiplimit}$}ã®å ´åˆï¼Œ
+ 2è¡Œã®é–“ã«ã¯é•·ã•\cs{lineskip}ã®ç©ºç™½ãŒæŒ¿å…¥ã•ã‚Œã‚‹ï¼Ž
+ ãã®ãŸã‚(設定値ã«ã‚ˆã‚‹ãŒï¼Œå¤šãã®å ´åˆï¼‰è¡Œé€ã‚Šã¯\cs{baselineskip}より広ãŒã‚‹ï¼Ž
+ \end{itemize}
+
+ \begin{figure}[t]
+ \noindent\centering
+ \begin{minipage}[b]{18\zw}
+ \ltjenableadjust[profile=false, linestep=false]
+ ……ã ã‹ã‚‰ï¼Œâ‘ ã‚ˆã‚Š$\dfrac{a^2}{b} = \dfrac{1+\sqrt{5}}2$.\\
+ よã£ã¦$b=\dfrac{1-\sqrt{5}}2$ã§ã‚る.\\
+ ã“れを②å¼ã«ä»£å…¥ã™ã‚‹ã¨â€¦â€¦
+ \par\vskip\abovecaptionskip
+ \ltjenableadjust[profile=false, linestep=false]
+ \par\centering\leavevmode{\small (a)}
+ \end{minipage}%
+ \kern2\zw
+ \begin{minipage}[b]{18\zw}
+ \ltjenableadjust[profile]
+ ……ã ã‹ã‚‰ï¼Œâ‘ ã‚ˆã‚Š$\dfrac{a^2}{b} = \dfrac{1+\sqrt{5}}2$.\\
+ よã£ã¦$b=\dfrac{1-\sqrt{5}}2$ã§ã‚る.\\
+ ã“れを②å¼ã«ä»£å…¥ã™ã‚‹ã¨â€¦â€¦
+ \par\vskip\abovecaptionskip
+ \ltjenableadjust[profile=false, linestep=false]
+ \par\centering\leavevmode{\small (b)}
+ \end{minipage}\par
+ \caption{高ã„è¡ŒãŒé€£ç¶šã—ãŸã¨ãã®çŠ¶æ³}\label{fig:linegap1}
+ \end{figure}
+
+ ã“ã“ã§ï¼Œ\TeX ã¯è¡Œé€ã‚Šã®æ±ºå®šã§ã€Œé«˜ã•ãƒ»æ·±ã•ã‚’å–ã£ã¦ã„ã‚‹ã‚‚ã®ãŒ
+ è¡Œã®ã©ã®æ°´å¹³ä½ç½®ã«ã‚ã‚‹ã‹ã€ã¯ä¸€åˆ‡è€ƒæ…®ã—ãªã„ã“ã¨ã«æ³¨æ„ã—ã¦ã»ã—ã„.ãã®ãŸã‚,
+ \autoref{fig:linegap1}~(a)ã®ã‚ˆã†ã«ã€Œå¿…è¦ä»¥ä¸Šã«è¡Œé–“ãŒç©ºã„ã¦è¦‹ãˆã‚‹ã€çŠ¶æ³ãŒèµ·ã“ã‚‹ã“ã¨ãŒã‚る.
+
+ \Pkg{luatexja-adjust}パッケージã§ã¯ï¼Œã€Œé€šå¸¸ã«çµ„ã‚“ã ã¨ãã®è¡Œé–“ã€$d$ã‚’
+ å„è¡Œã®ä¸­èº«ã®æ–‡å­—・グルー・ボックスã®å¯¸æ³•ã‚’勘案ã—ã¦è¨ˆç®—ã™ã‚‹ã¨ã„ã†æ–¹æ³•ã‚’
+ 利用ã§ãるよã†ã«ã—ãŸï¼Žã“ã®æ©Ÿèƒ½ã‚’使ã†ã¨ï¼Œ\autoref{fig:linegap1}~(b)ã®ã‚ˆã†ã«
+ 行間ã®ç©ºããŒå¿…è¦ä»¥ä¸Šã«å¤§ãããªã‚‹ã“ã¨ã‚’é¿ã‘ã‚‹ã“ã¨ãŒã§ãる.
+ \begin{itemize}
+ \item 段è½ä¸­ã®éš£ã‚Šåˆã£ãŸäºŒè¡Œã ã‘ã§ãªã,行間ã®ç©ºãã¯
+ æ–°ãŸã«æ°´å¹³ãƒœãƒƒã‚¯ã‚¹$h$を(内部・外部å•ã‚ãšï¼‰åž‚直モードã§è¿½åŠ ã—ãŸæ™‚ã«ã‚‚自動ã§æŒ¿å…¥ã•ã‚Œã‚‹ï¼Ž
+ ãã®å ´åˆã«ã¯ï¼Œå‰æ®µè½ã§è¿°ã¹ãŸã€Œä¸­èº«ã¾ã§ã¿ã‚‹ã€å‡¦ç†ã¯
+ \begin{itemize}
+ \item ç¾åœ¨ã®ãƒªã‚¹ãƒˆã«ãŠã‘る最後ã®ãƒŽãƒ¼ãƒ‰
+ \footnote{最後ã®ãƒŽãƒ¼ãƒ‰ãŒ\cs{parskip}ã«ã‚ˆã‚‹ã‚°ãƒ«ãƒ¼ã§ã‚ã£ãŸå ´åˆã®ã¿
+ ã•ã‚‰ã«ä¸€ã¤å‰ã®ãƒŽãƒ¼ãƒ‰ã‚’å‚ç…§ã™ã‚‹}ãŒæ°´å¹³ãƒœãƒƒã‚¯ã‚¹$h'$ã§ã‚り,ã‹ã¤
+ \item \cs{prevdepth}ã®å€¤ã¨ãã®$h'$ã®æ·±ã•ã®å€¤ãŒä¸€è‡´ã—ã¦ã„ã‚‹
+ \end{itemize}
+ å ´åˆã«ã®ã¿ç™ºå‹•ã™ã‚‹ã‚ˆã†ã«ã—ã¦ã„る.
+ \item è¡Œã®ä¸­èº«ã«æ°´å¹³ãƒœãƒƒã‚¯ã‚¹$h''$ãŒå…¥ã£ã¦ãã‚‹ã“ã¨ã‚‚ã‚ã‚‹ãŒï¼Œãã®å ´åˆã¯$h''$ã®ä¸­èº«ã®é«˜ã•ãƒ»æ·±ã•ã¾ã§ã¯
+ å‚ç…§ã›ãšï¼Œã‚ãã¾ã§ã‚‚$h''$自身ã®é«˜ã•ãƒ»æ·±ã•ã®ã¿ã‚’å‚ç…§ã™ã‚‹ï¼Ž
+ å‚ç…§ã™ã‚‹ã‚ˆã†ã«ã—ã¦ã—ã¾ã†ã¨ï¼Œ\cs{smash}ãªã©æ‰‹å‹•ã§è¡Œã£ãŸé«˜ã•ãƒ»æ·±ã•èª¿æ•´ã®æ„味ãŒãªããªã£ã¦ã—ã¾ã†ã‹ã‚‰ã§ã‚る.
+ \end{itemize}
+
+ \begin{figure}[t]
+ \noindent\centering
+ \begin{minipage}[b]{16\zw}
+ \ltjenableadjust[profile]
+ ……ã ã‹ã‚‰ï¼Œâ‘ ã‚ˆã‚Š$\dfrac{a^2}{b}= \dfrac{1+\sqrt{5}}2$.\\
+ よã£ã¦$b=\dfrac{1-\sqrt{5}}2$ã§ã‚る.\\
+ ã“れを②å¼ã«ä»£å…¥ã™ã‚‹ã¨â€¦â€¦
+ \par\vskip\abovecaptionskip
+ \ltjenableadjust[profile=false, linestep=false]
+ \par\centering\leavevmode{\small (a): 無効}
+ \end{minipage}%
+ \kern2\zw
+ \begin{minipage}[b]{16\zw}
+ \ltjsetparameter{linestep_factor=0.25}
+ \ltjenableadjust[profile, linestep]
+ ……ã ã‹ã‚‰ï¼Œâ‘ ã‚ˆã‚Š$\dfrac{a^2}{b} = \dfrac{1+\sqrt{5}}2$.\\
+ よã£ã¦$b=\dfrac{1-\sqrt{5}}2$ã§ã‚る.\\
+ ã“れを②å¼ã«ä»£å…¥ã™ã‚‹ã¨â€¦â€¦
+ \par\vskip\abovecaptionskip
+ \ltjenableadjust[profile=false, linestep=false]
+ \par\centering\leavevmode{\small (b): $0.25$\cs{baselineskip}刻ã¿}
+ \end{minipage}\par\medskip
+ \begin{minipage}[b]{16\zw}
+ \ltjsetparameter{linestep_factor=0.5}
+ \ltjenableadjust[profile, linestep]
+ ……ã ã‹ã‚‰ï¼Œâ‘ ã‚ˆã‚Š$\dfrac{a^2}{b} = \dfrac{1+\sqrt{5}}2$.\\
+ よã£ã¦$b=\dfrac{1-\sqrt{5}}2$ã§ã‚る.\\
+ ã“れを②å¼ã«ä»£å…¥ã™ã‚‹ã¨â€¦â€¦
+ \par\vskip\abovecaptionskip
+ \ltjenableadjust[profile=false, linestep=false]
+ \par\centering\leavevmode{\small (c): 0.5\cs{baselineskip}刻ã¿}
+ \end{minipage}%
+ \kern2\zw
+ \begin{minipage}[b]{16\zw}
+ \ltjsetparameter{linestep_factor=1}
+ \ltjenableadjust[profile, linestep]
+ ……ã ã‹ã‚‰ï¼Œâ‘ ã‚ˆã‚Š$\dfrac{a^2}{b} = \dfrac{1+\sqrt{5}}2$.\\
+ よã£ã¦$b=\dfrac{1-\sqrt{5}}2$ã§ã‚る.\\
+ ã“れを②å¼ã«ä»£å…¥ã™ã‚‹ã¨â€¦â€¦
+ \par\vskip\abovecaptionskip
+ \ltjenableadjust[profile=false, linestep=false]
+ \par\centering\leavevmode{\small (d): \cs{baselineskip}刻ã¿}
+ \end{minipage}\par
+ \caption{段階的ãªè¡Œé€ã‚Šå¢—加}\label{fig:linegap2}
+ \end{figure}
+
+ \item[段階的ãªè¡Œé€ã‚Šèª¿æ•´]
+ æ—¢ã«è¿°ã¹ãŸã‚ˆã†ã«ï¼Œ
+ 「通常ã«çµ„ã‚“ã ã¨ãã®è¡Œé–“ã€$d$ãŒ\cs{lineskiplimit}よりå°ã•ã„å ´åˆï¼Œ\TeX 標準ã§ã¯
+ 行間ã¯\cs{lineskip}ã¨ãªã‚‹ã®ã ã£ãŸï¼Ž
+ ã“ã®ã¨ãè¡Œé€ã‚Šã¯ã€Œå‰ã®è¡Œã®æ·±ã•ã€ï¼Œã€Œæ¬¡ã®è¡Œã®é«˜ã•ã€ï¼Œ\cs{lineskip}ã®3ã¤ã®å’Œã«ãªã‚‹ã‚ã‘ã ãŒï¼Œ
+ å ´åˆã«ã‚ˆã£ã¦ã¯è¡Œé€ã‚Šã‚’「\cs{baselineskip}ã®æ•´æ•°å€ã€ãªã©ã¨åˆ‡ã‚Šã®ã„ã„値ã«æƒãˆãŸã„ã¨ã„ã†çŠ¶æ³ãŒ
+ 考ãˆã‚‰ã‚Œãªãã‚‚ãªã„.
+
+ \Pkg{luatexja-adjust}パッケージã§ã¯ï¼Œ{\catcode`\<=12$d<\cs{lineskiplimit}$}ã®ã¨ãã«
+ è¡Œé€ã‚Šã‚’\cs{baselineskip}ã®\Param{linestep\_factor}å€ãšã¤å¢—減ã•ã›ã¦
+ \begin{quote}
+ 行間ãŒ\cs{lineskip}以上ã¨ãªã‚‹ã‚ˆã†ãªï¼Œ
+ 最å°ã®$(1+k\cdot \Param{linestep\_factor})\cs{baselineskip}$($k$ã¯æ•´æ•°ï¼‰ã®å€¤
+ \end{quote}
+ ã¨ã™ã‚‹æ©Ÿèƒ½ã‚’利用ã§ãるよã†ã«ã—ãŸï¼Ž
+ \autoref{fig:linegap2}ã®(a)ãŒã“ã®æ©Ÿèƒ½ã‚’無効ã«ã—ãŸçŠ¶æ³ã§ï¼Œ(b),~(c),~(d)ãŒ
+ ãã‚Œãžã‚Œ\Param{linestep\_factor}ã‚’0.25,~0.5,~1ã¨ã—ãŸçŠ¶æ³ã§ã‚る.
+
+ ãªãŠï¼Œã“ã®æ©Ÿèƒ½ã¯è¡¨çµ„時(\cs{halign},~\cs{valign})ã«ã¯ç„¡åŠ¹ã§ã‚る.
+ \LaTeX ã«ãŠã‘る表組環境(tabular, arrayãªã©ï¼‰ã§ã¯ï¼Œ\cs{baselineskip},~\cs{lineskip}ã¯ã©ã¡ã‚‰ã‚‚0ã«è¨­å®šã•ã‚Œã¦ã„ã‚‹ã®ã§
+ (代ã‚ã‚Šã«å„è¡Œã«\cs{@arstrut}ã¨ã„ã†æ”¯æŸ±ãŒå…¥ã‚‹ï¼‰ãŸã‚ã«æ„味ãŒãªã„ã“ã¨ã¨ï¼Œ
+ æ•°å¼ã‚’内部ã§è¡¨çµ„を使ã£ã¦çµ„ã‚€align環境ãªã©ã§ã¯ã‹ãˆã£ã¦è¡Œé–“ãŒä¸æƒã„ã«ãªã£ã¦ã—ã¾ã†ã‹ã‚‰ã§ã‚る.
+\end{description}
+
+\Pkg{luatexja-adjust}パッケージã¯ï¼Œä¸Šè¨˜ã§è¿°ã¹ãŸ4機能を有効化/無効化ã™ã‚‹ãŸã‚ã®
+以下ã®å‘½ä»¤ã‚’æä¾›ã™ã‚‹ï¼Žã“れらã¯ã™ã¹ã¦ã‚°ãƒ­ãƒ¼ãƒãƒ«ã«åŠ¹åŠ›ã‚’発æ®ã™ã‚‹ï¼Ž
+
+\begin{cslist}
+\item[\cs{ltjenableadjust[...]}]
+\verb+...+ ã«æŒ‡å®šã—ãŸkey-valueリストã«å¾“ã„,「行末文字ã®ä½ç½®èª¿æ•´ã€ã€Œå„ªå…ˆé †ä½ä»˜ãã®è¡Œé•·èª¿æ•´ã€
+ 「『中身ã¾ã§ã¿ãŸã€è¡Œé€ã‚Šè¨ˆç®—ã€ã€Œæ®µéšŽçš„ãªè¡Œé€ã‚Šèª¿æ•´ã€ã‚’有効化/無効化ã™ã‚‹ï¼Ž
+指定ã§ãるキーã¯ä»¥ä¸‹ã®é€šã‚Šï¼Ž
+\begin{description}
+ \item[\texttt{lineend=[false,true,extended]}]
+ 行末文字ã®ä½ç½®èª¿æ•´ã®æ©Ÿèƒ½ã‚’無効化(\texttt{false}),「行分割後ã«èª¿æ•´ã€ã®å½¢ã§æœ‰åŠ¹åŒ–(\texttt{true}),
+ 「行分割ã®éŽç¨‹ã§è€ƒæ…®ã€ã®å½¢ã§æœ‰åŠ¹åŒ–(\texttt{extended})ã™ã‚‹ï¼Ž
+ \item[\texttt{priority=[false,true]}]
+ 優先順ä½ä»˜ãã®è¡Œé•·èª¿æ•´ã‚’無効化(\texttt{false}),ã¾ãŸã¯æœ‰åŠ¹åŒ–(\texttt{true}).
+ \item[\texttt{profile=[false,true]}]
+ 「中身ã¾ã§ã¿ãŸã€è¡Œé€ã‚Šè¨ˆç®—を無効化(\texttt{false}),ã¾ãŸã¯æœ‰åŠ¹åŒ–(\texttt{true}).
+ \item[\texttt{linestep=[false,true]}]
+ 段階的ãªè¡Œé€ã‚Šèª¿æ•´ã‚’無効化(\texttt{false}),ã¾ãŸã¯æœ‰åŠ¹åŒ–(\texttt{true}).
+\end{description}
+ã©ã®ã‚­ãƒ¼ã¨ã‚‚キーåã®ã¿ã‚’指定ã—ãŸå ´åˆã¯å€¤ã¨ã—ã¦\texttt{true}ãŒæŒ‡å®šã•ã‚ŒãŸã‚‚ã®ã¨æ‰±ã‚れる.
+
+互æ›æ€§ã®ç‚ºï¼Œã‚ªãƒ—ション無ã—ã§ãŸã \cs{ltjenableadjust}ãŒå‘¼ã³å‡ºã•ã‚ŒãŸå ´åˆã¯ï¼Œ
+\begin{lstlisting}
+\ltjenableadjust[lineend=true,priority=true]
+\end{lstlisting}
+ã¨æ‰±ã‚れる.
+
+\item[\cs{ltjdisableadjust}]
+\Pkg{luatexja-adjust}パッケージã®æ©Ÿèƒ½ã‚’無効化ã™ã‚‹ï¼Ž
+\begin{lstlisting}
+\ltjenableadjust[lineend=false,priority=false,profile=false,linestep=false]
+\end{lstlisting}
+ã¨åŒç¾©ï¼Ž
+\end{cslist}
+
+ã¾ãŸï¼Œæ¬¡ã®ãƒ‘ラメータãŒ\cs{ltjsetparameter}内ã§
+追加ã•ã‚Œã‚‹ï¼Žã„ãšã‚Œã‚‚グローãƒãƒ«ã«åŠ¹åŠ›ã‚’発æ®ã™ã‚‹ï¼Ž
+\begin{cslist}[style=standard]
+\item[\DParam{stretch\_priority}\,=\{<list>\}]
+\Param{kanjiskip}, \Param{xkanjiskip},ãŠã‚ˆã³ã€Œ\textbf{JAglue}以外ã®ã‚°ãƒ«ãƒ¼ã€ã‚’,
+「行を自然長より伸ã°ã™ã€å ´åˆã®èª¿æ•´ã«ç”¨ã„る優先度を指定ã™ã‚‹ï¼Ž
+
+指定方法ã¯ï¼Œ<list>ã®ä¸­ã«key-value listã®å½¢ã§
+\begin{lstlisting}
+stretch_priority={kanjiskip=-35,xkanjiskip=-25,others=50}
+\end{lstlisting}
+ã®ã‚ˆã†ã«ã—ã¦è¡Œã†ï¼Žã‚­ãƒ¼å\texttt{kanjiskip},~\texttt{xkanjiskip}ã«ã¤ã„ã¦ã¯
+ãã®ã¾ã¾ã®æ„味ã§ã‚り,
+\texttt{others}キーãŒã€Œ\textbf{JAglue}以外ã®ã‚°ãƒ«ãƒ¼ã€ã‚’表ã™ï¼Ž
+å„キーã®å€¤ã¯ï¼ŒJFMグルーã«ãŠã‘る「優先度$i$ã€ã‚’$10i$ã«å¯¾å¿œã•ã›ãŸæ•´æ•°å€¤ã§ã‚り,
+ 大ãã„æ–¹ãŒå…ˆã«ä¼¸ã°ã•ã‚Œã‚‹ã“ã¨ã‚’æ„味ã—ã¦ã„る.
+ åˆæœŸå€¤ã¯
+\begin{lstlisting}
+{kanjiskip=-35,xkanjiskip=-25,others=50}
+\end{lstlisting}
+ã§ã‚り,「優先度$-4$ã€ã¨æŒ‡å®šã•ã‚Œã¦ã„ã‚‹JFMグルーãŒæœ€ã‚‚伸ã³ã«ãã„よã†ã«ãªã£ã¦ã„る.
+
+\item[\DParam{shrink\_priority}\,=\{<list>\}]
+åŒæ§˜ã«ï¼Œã€Œè¡Œã‚’自然長より縮ã‚ã‚‹ã€å ´åˆã®èª¿æ•´ã«ç”¨ã„る優先度を指定ã™ã‚‹ï¼Ž
+ãれ以外ã¯\Param{stretch\_priority}ã¨æŒ‡å®šã®å½¢å¼ã¯å¤‰ã‚らãªã„(åˆæœŸå€¤ã‚‚変ã‚らãªã„).
+
+ \item[\DParam{linestep\_factor}\,=<float>]
+ 段階的ãªè¡Œé€ã‚Šèª¿æ•´ã®éš›ï¼Œ\cs{baselineskip}ã®è‡ªç„¶é•·ã®ä½•å€å˜ä½ã§è¡Œé€ã‚Šã‚’変ãˆã‚‹ã‹ã‚’指定ã™ã‚‹ï¼Ž
+ 0を指定ã™ã‚‹ã¨ç„¡åŠ¹ã«ãªã‚‹ã®ã¨å¤‰ã‚らãªã„.ã¾ãŸè² æ•°ã‚’指定ã™ã‚‹ã¨ï¼Œ
+ ãã®çµ¶å¯¾å€¤ãŒæŒ‡å®šã•ã‚ŒãŸã‹ã®ã‚ˆã†ã«æ‰±ã‚れる.
+ åˆæœŸå€¤ã¯0.5(ã¤ã¾ã‚ŠåŠè¡Œå˜ä½ï¼‰ã§ã‚る.
+
+ \item[\DParam{profile\_hgap\_factor}\,=<float>]
+ 「中身ã¾ã§è¦‹ãŸã€è¡Œé€ã‚Šè¨ˆç®—ã®éš›ï¼Œ
+ å‰ã®è¡Œã«ã‚ã‚‹æ·±ã•ãŒå¤§ãã„ã‚‚ã®ã¨æ¬¡ã®è¡Œã«ã‚る高ã•ãŒå¤§ãã„ã‚‚ã®ãŒ
+ 水平方å‘ã«ã©ã‚Œã ã‘離れã¦ã„ãªã„ã¨ã„ã‘ãªã„ã‹ã‚’
+ 「\cs{lineskip}ã®è‡ªç„¶é•·ã®ä½•å€ã‹ã€ã§æŒ‡å®šã™ã‚‹ï¼Ž
+ 負数を指定ã™ã‚‹ã¨ï¼Œãã®çµ¶å¯¾å€¤ãŒæŒ‡å®šã•ã‚ŒãŸã‹ã®ã‚ˆã†ã«æ‰±ã‚れる.
+ åˆæœŸå€¤ã¯1(ã¤ã¾ã‚Š\cs{lineskip}(ã®è‡ªç„¶é•·ï¼‰ï¼‰ã§ã‚る.
+\end{cslist}
+%</ja>
+
+\subsection{\Pkg{luatexja-ruby}}
+%<*en>
+This addon package provides functionality of ``ruby'' (\emph{furigana}) annotations
+using callbacks of \LuaTeX-ja.
+There is no detailed manual of \Pkg{luatexja-ruby.sty} in English.
+(Japanese manual is another PDF file, \url{luatexja-ruby.pdf}.)
+%</en>
+%<*ja>
+ã“ã®è¿½åŠ ãƒ‘ッケージã¯ï¼Œ\LuaTeX-jaã®æ©Ÿèƒ½ã‚’利用ã—ãŸãƒ«ãƒ“(振り仮å)ã®çµ„版機能をæä¾›ã™ã‚‹ï¼Ž
+å‰å¾Œã®æ–‡å­—種ã«å¿œã˜ãŸå‰å¾Œã¸ã®è‡ªå‹•é€²å…¥ã‚„,
+行頭形・行中形・行末形ã®è‡ªå‹•çš„ãªä½¿ã„分ã‘ãŒç‰¹å¾´ã§ã‚る.
+
+ルビ組版ã«è¨­å®šå¯èƒ½ãªé …目や注æ„事項ãŒå¤šã„ãŸã‚,本追加パッケージã®è©³ç´°ãªèª¬æ˜Žã¯
+使用例ã¨å…±ã« \url{luatexja-ruby.pdf}\ ã¨ã„ã†åˆ¥ãƒ•ã‚¡ã‚¤ãƒ«ã«è¼‰ã›ã¦ã„る.
+ã“ã®ç¯€ã§ã¯ç°¡å˜ãªä½¿ç”¨æ–¹æ³•ã®ã¿è¿°ã¹ã‚‹ï¼Ž
+%</ja>
+
+\begin{description}
+%<*en>
+ \item[Group-ruby]
+By default, ruby characters (the second argument of \cs{ruby})
+are attached to base characters (the first argument), as one object.
+This type of ruby is called \emph{group-ruby}.
+%</en>
+%<*ja>
+ \item[グループルビ] 標準ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ—ルビã®å½¢ã§çµ„ã¾ã‚Œã‚‹ï¼Žç¬¬1引数ã«è¦ªæ–‡å­—,
+第2引数ã«ãƒ«ãƒ“を記述ã™ã‚‹ï¼Ž
+%</ja>
+\begin{LTXexample}[width=0.3\textwidth]
+æ±è¥¿ç·š\ruby{妙典}{ã¿ã‚ˆã†ã§ã‚“}駅ã¯â€¦â€¦\\
+æ±è¥¿ç·šã®\ruby{妙典}{ã¿ã‚ˆã†ã§ã‚“}駅ã¯â€¦â€¦\\
+æ±è¥¿ç·šã®\ruby{妙典}{ã¿ã‚ˆã†ã§ã‚“}ã¨ã„ã†é§………\\
+æ±è¥¿ç·š\ruby{葛西}{ã‹ã•ã„}駅ã¯â€¦â€¦
+\end{LTXexample}
+%<*en>
+As the above example, ruby hangover is allowed on the Hiragana before/after
+its base characters.
+%</en>
+%<ja> ã“ã®ä¾‹ã®ã‚ˆã†ã«ï¼Œæ¨™æº–ã§ã¯å‰å¾Œã®å¹³ä»®åã«ãƒ«ãƒ“全角ã¾ã§ã‹ã‹ã‚‹ã‚ˆã†ã«ãªã£ã¦ã„る.
+
+%<*en>
+\item[Mono-ruby]
+To attach ruby characters to each base characters (\emph{mono-ruby}),
+one should use \cs{ruby} multiple times:
+%</en>
+%<*ja>
+ \item[モノルビ] 親文字を1文字ã«ã™ã‚‹ã¨ãƒ¢ãƒŽãƒ«ãƒ“ã¨ãªã‚‹ï¼Ž
+2文字以上ã®ç†Ÿèªžã‚’モノルビã®å½¢ã§çµ„ã¿ãŸã„å ´åˆã¯ï¼Œé¢å€’ã§ã‚‚
+ãã®æ•°ã ã‘ \cs{ruby} を書ãå¿…è¦ãŒã‚る.
+%</ja>
+\begin{LTXexample}[width=0.3\textwidth]
+æ±è¥¿ç·šã®\ruby{妙}{ã¿ã‚ˆã†}\ruby{å…¸}{ã§ã‚“}駅ã¯â€¦â€¦
+\end{LTXexample}
+
+%<*en>
+ \item[Jukugo-ruby]
+Vertical bar~\verb+|+ denotes a boundary of \emph{groups}.
+%</en>
+%<*ja>
+ \item[熟語ルビ] 引数内ã®ç¸¦æ£’ \verb+|+ ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã®åŒºåˆ‡ã‚Šã‚’表ã—,
+複数グループã®ãƒ«ãƒ“ã¯ç†Ÿèªžãƒ«ãƒ“ã¨ã—ã¦çµ„ã¾ã‚Œã‚‹ï¼Ž
+\cite{x4051}ã«ã‚るよã†ã«ï¼Œ
+ã©ã®ã‚°ãƒ«ãƒ¼ãƒ—ã§ã‚‚「親文字ã€ãŒå¯¾å¿œã™ã‚‹ãƒ«ãƒ“以上ã®é•·ã•ã®å ´åˆã¯
+å„グループã”ã¨ã«ï¼Œãã†ã§ãªã„ã¨ãã¯å…¨ä½“ã‚’ã¾ã¨ã‚ã¦1ã¤ã®ã‚°ãƒ«ãƒ¼ãƒ—ルビã¨ã—ã¦çµ„ã¾ã‚Œã‚‹ï¼Ž
+\cite{jlreq}ã§è¦å®šã•ã‚Œã¦ã„る組ã¿æ–¹ã¨ã¯ç•°ãªã‚‹ã®ã§æ³¨æ„.
+%</ja>
+\begin{LTXexample}
+\ruby{妙|å…¸}{ã¿ã‚ˆã†|ã§ã‚“}\
+\ruby{è‘›|西}{ã‹|ã•ã„}\
+\ruby{神楽|å‚}{ã‹ãら|ã–ã‹}
+\end{LTXexample}
+%<*en>
+If there are multiple groups in one \cs{ruby} call,
+A linebreak between two groups is allowed.
+%</en>
+%<ja> 複数ルビã§ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã¨ã‚°ãƒ«ãƒ¼ãƒ—ã®é–“ã§æ”¹è¡ŒãŒå¯èƒ½ã§ã‚る.
+\begin{LTXexample}[width=0.3\textwidth]
+\vbox{\hsize=6\zw\noindent
+ \hbox to 2.5\zw{}\ruby{京|急|è’²|ç”°}{ã‘ã„|ãゆã†|ã‹ã¾|ãŸ}
+ \hbox to 2.5\zw{}\ruby{京|急|è’²|ç”°}{ã‘ã„|ãゆã†|ã‹ã¾|ãŸ}
+ \hbox to 3\zw{}\ruby{京|急|è’²|ç”°}{ã‘ã„|ãゆã†|ã‹ã¾|ãŸ}
+}
+\end{LTXexample}
+\end{description}
+
+%<*en>
+If the width of ruby characters are longer than that of base characters,
+\cs{ruby} automatically selects the appropriate form
+among the line-head form, the line-middle form, and the line-end form.
+%</en>
+%<*ja>
+ã¾ãŸï¼Œãƒ«ãƒ“文字ã®ã»ã†ãŒè¦ªæ–‡å­—よりも長ã„å ´åˆã¯ï¼Œè‡ªå‹•çš„ã«
+行頭形・行中形・行末形ã®ã„ãšã‚Œã‹é©åˆ‡ãªã‚‚ã®ã‚’é¸æŠžã™ã‚‹ï¼Ž
+%</ja>
+\begin{LTXexample}[width=0.3\textwidth]
+\vbox{\hsize=8\zw\noindent
+\null\kern3\zw ……を\ruby{承}{ã†ã‘ãŸã¾ã‚}ã‚‹
+ \kern1\zw ……を\ruby{承}{ã†ã‘ãŸã¾ã‚}ã‚‹\\
+\null\kern5\zw ……を\ruby{承}{ã†ã‘ãŸã¾ã‚}ã‚‹
+}
+\end{LTXexample}
+
+
+%<*ja>
+\subsection{\Pkg{lltjext}}
+\pLaTeX ã§ã¯ç¸¦çµ„用ã®æ‹¡å¼µã¨ã—㦠\Pkg{plext} パッケージãŒç”¨æ„ã•ã‚Œã¦ã„ãŸãŒï¼Œ
+ãれを\LuaTeX-ja用ã«æ›¸ããªãŠã—ãŸã‚‚ã®ãŒæœ¬è¿½åŠ ãƒ‘ッケージ \Pkg{lltjext} ã§ã‚る.
+
+従æ¥ã® \Pkg{plext} パッケージã¨ã®é•ã„ã¯ï¼Œ
+{\catcode`\<=12
+\begin{itemize}
+ \item 組方å‘オプション \texttt{<y>}(横組),\texttt{<t>}(縦組),
+\texttt{<z>}\ ã®ä»–ã«\ \texttt{<d>}(dtouæ–¹å‘),\texttt{<u>}(utodæ–¹å‘)を追加ã—ãŸï¼Ž
+\texttt{<z>} 㨠\texttt{<u>} ã®é•ã„ã¯ï¼Œ\texttt{<z>} ãŒï¼ˆ\Pkg{plext} パッケージã¨åŒæ§˜ã«ï¼‰
+周囲ã®çµ„æ–¹å‘ãŒç¸¦çµ„ã®ã¨ãã«ã—ã‹æ„味をæŒãŸãªã„
+ \footnote{%
+ 周囲ã®çµ„æ–¹å‘ãŒç¸¦çµ„以外ã®ã¨ãã¯ï¼Œ\texttt{<z>} を指定ã—ã¦ã‚‚中身ã®çµ„æ–¹å‘ã¯å‘¨å›²ã®çµ„æ–¹å‘ã¨å¤‰ã‚らãªã„.
+ }%
+ã®ã«å¯¾ã—,\texttt{<u>} ã«ã¯ãã®ã‚ˆã†ãªåˆ¶é™ãŒãªã„ã“ã¨ã§ã‚る.
+ \item 連数字用命令 \cs{rensuji} ã«ãŠã‘ã‚‹ä½ç½®åˆã‚ã›ã‚ªãƒ—ション \texttt{[l]}, \texttt{[c]},
+ \texttt{[r]} ã®æŒ™å‹•ã‚’若干変更ã—ãŸï¼Ž
+\end{itemize}
+}
+
+%</ja>
+%<*en>
+\subsection{\texttt{lltjext.sty}}
+\pLaTeX\ supplies additional macros for vertical writing in the \Pkg{plext} package.
+The \Pkg{lltjext} package which we want to describe here is the \LuaTeX-ja
+counterpart of the \Pkg{plext} package.
+%</en>
+
+%<*ja>
+念ã®ç‚ºï¼Œæœ¬ \Pkg{lltjext} パッケージã§è¿½åŠ ãƒ»å¤‰æ›´ã—ã¦ã„る命令ã®ä¸€è¦§ã‚’載ã›ã¦ãŠã.
+\begin{cslist}
+\item[tabular\textrm{, }array\textrm{, }minipage環境]
+ã“れらã®ç’°å¢ƒã¯ï¼Œ
+\begin{lstlisting}
+\begin{tabular}<dir>[pos]{table spec} ... \end{tabular}
+\begin{array}<dir>[pos]{table spec} ... \end{array}
+\begin{minipage}<dir>[pos]{width} ... \end{minipage}
+\end{lstlisting}
+ã®ã‚ˆã†ã«ï¼Œçµ„æ–¹å‘オプション \texttt{\<dir\>} ãŒæ‹¡å¼µã•ã‚Œã¦ã„る.
+æ—¢ã«è¿°ã¹ãŸã‚ˆã†ã«ï¼Œçµ„æ–¹å‘オプションã«æŒ‡å®šã§ãる値ã¯ä»¥ä¸‹ã®5ã¤ã§ã‚り,
+ãれ以外を指定ã—ãŸæ™‚や無指定時ã¯å‘¨å›²ã®çµ„æ–¹å‘ã¨åŒã˜çµ„æ–¹å‘ã«ãªã‚‹ï¼Ž
+\begin{description}
+ \item[y] 横組(\cs{yoko})
+ \item[t] 縦組(\cs{tate})
+ \item[z] 周囲ãŒç¸¦çµ„ã®æ™‚ã¯utodæ–¹å‘,ãれ以外ã¯ãã®ã¾ã¾
+ \item[d] dtouæ–¹å‘
+ \item[u] utodæ–¹å‘
+\end{description}
+\item[\cs{parbox}\<<dir>\>{[<pos>]}\{<width>\}\{<contents>\}]
+\cs{parbox} 命令もåŒæ§˜ã«ï¼Œçµ„æ–¹å‘ã®æŒ‡å®šãŒã§ãるよã†ã«æ‹¡å¼µã•ã‚Œã¦ã„る.
+
+\item[\cs{pbox}\<<dir>\>{[<width>][<pos>]}\{<contents>\}]
+組方å‘<dir>ã§<contents>ã®ä¸­èº«ã‚’LRモードã§çµ„む命令ã§ã‚る.
+<width>ãŒæ­£ã®å€¤ã§ã‚ã‚‹ã¨ãã¯ï¼Œãƒœãƒƒã‚¯ã‚¹å…¨ä½“ã®å¹…ãŒãã®å€¤ã¨ãªã‚‹ï¼Ž
+ãã®éš›ï¼Œä¸­èº«ã¯<pos>ã®å€¤ã«å¾“ã„,左寄ã›(\texttt{l}),å³æƒãˆ(\texttt{r}),
+中央æƒãˆï¼ˆãれ以外)ã•ã‚Œã‚‹ï¼Ž
+\item[picture環境]
+図表作æˆã«ç”¨ã„ã‚‹\texttt{picture}環境も,
+\begin{lstlisting}
+\begin{picture}<dir>(x_size, y_size)(x_offset,y_offset)
+ ...
+\end{picture}
+\end{lstlisting}
+ã¨çµ„æ–¹å‘ãŒæŒ‡å®šã§ãるよã†ã«æ‹¡å¼µã•ã‚Œã¦ã„る.
+$x$æˆåˆ†ã®å¢—加方å‘ã¯å­—é€ã‚Šæ–¹å‘,$y$æˆåˆ†ã®å¢—加方å‘ã¯è¡Œé€ã‚Šæ–¹å‘ã®\emph{å対方å‘}ã¨ãªã‚‹ï¼Ž
+\Pkg{plext} パッケージã¨åŒæ§˜ã«
+内部ã§ã¯ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³è£œæ­£ï¼ˆ\Param{yalbaselineshift}パラメータãªã©ï¼‰ã®å½±éŸ¿ã‚’å—ã‘ãªã„よã†ã«ï¼Œ
+\cs{put},~\cs{line}, \cs{vector}, \cs{dashbox}, \cs{oval},~\cs{circle}ã‚‚
+ベースライン補正をå—ã‘ãªã„よã†ã«å†å®šç¾©ã•ã‚Œã¦ã„る.
+
+\item[\cs{rensuji}{[<pos>]}\{<contents>\}\textrm{, }\cs{rensujiskip}]
+
+\item[\cs{Kanji}\{<counter\_name>\}]
+
+\item[\cs{kasen}\{<contents>\}\textrm{, }\cs{bou}\{<contents>\}\textrm{,
+ }\cs{boutenchar}]
+
+\item[å‚照番å·]
+\end{cslist}
+%</ja>
+%<*en>
+\begin{cslist}
+\item[tabular\textrm{, }array\textrm{, }minipage\textrm{ environments}]
+These environments are extended by \texttt{\<dir\>}, which specifies the direction,
+as follows:
+\begin{lstlisting}
+\begin{tabular}<dir>[pos]{table spec} ... \end{tabular}
+\begin{array}<dir>[pos]{table spec} ... \end{array}
+\begin{minipage}<dir>[pos]{width} ... \end{minipage}
+\end{lstlisting}
+This option permits one of the following five values. If none of them is specified,
+the direction inside the environment is same as that outside the enviromnent.
+\begin{description}
+ \item[y] \emph{yoko} direction (horizontal writing)
+ \item[t] \emph{tate} direction (vertical writing)
+ \item[z] \emph{utod} direction if direction outside the env.\ is \emph{tate}.
+ \item[d] \emph{dtou} direction
+ \item[u] \emph{utod} direction
+\end{description}
+\item[\cs{parbox}\<<dir>\>{[<pos>]}\{<width>\}\{<contents>\}]
+\cs{parbox} command is also extended by \texttt{\<<dir>\>}.
+
+\item[\cs{pbox}\<<dir>\>{[<width>][<pos>]}\{<contents>\}]
+This commands typeset <contents> in LR-mode, in <dir> direction.
+If <width> is positive, the width of the box becomes this <width>.
+In this case, <contents> will be aligned to left (when <pos> is \texttt{l}),
+center (\texttt{c}), or~right (\texttt{r}).
+
+\item[picture\textrm{\ environment}]
+\texttt{picture} environment also extended by \texttt{\<<dir>\>}, as follows:
+\begin{lstlisting}
+\begin{picture}<dir>(x_size, y_size)(x_offset,y_offset)
+ ...
+\end{picture}
+\end{lstlisting}
+
+\item[\cs{rensuji}{[<pos>]}\{<contents>\}\textrm{, }\cs{rensujiskip}]
+
+\item[\cs{Kanji}\{<counter\_name>\}]
+
+\item[\cs{kasen}\{<contents>\}\textrm{, }\cs{bou}\{<contents>\}\textrm{,
+ }\cs{boutenchar}]
+
+\item[å‚照番å·]
+\end{cslist}
+%</en>
+
+%<*ja>
+\paragraph{表組他ã®æƒãˆä½ç½®}
+表組(\texttt{array}, \texttt{tabular}環境),\cs{parbox}命令,\cs{minipage}環境ã®
+æƒãˆä½ç½®ã«ã¤ã„ã¦ã¯\autoref{tab:lltjext_dir}ã‚’å‚照.\pLaTeX~2017-07-29ã¨
+ã§ãã‚‹ã ã‘åŒã˜æŒ™å‹•ã«ãªã‚‹ã‚ˆã†ã«ã—ã¦ã„る.\autoref{tab:lltjext_dir}中ã®A--Dã®æ„味ã¯æ¬¡ã®é€šã‚Šï¼Ž
+
+\begin{table}
+ \caption{\Pkg{lltjext}パッケージã«ãŠã‘る表組・\cs{parbox}命令他ã®æƒãˆä½ç½®}
+ \label{tab:lltjext_dir}
+ {\centering
+ \begin{tabular}{lcccc}
+ \toprule
+ ↓中身\周囲→&\cs{yoko}&\cs{tate}&\cs{utod}&\cs{dtou}\\
+ \midrule
+ \cs{yoko}&A&B&B&B\\
+ \cs{tate}&B&A&D&C\\
+ \cs{utod}&B&D&A&C\\
+ \cs{dtou}&B&C&C&A\\
+ \bottomrule
+ \end{tabular}\par}
+\end{table}
+
+\begin{description}
+ \item[A] 周囲ã®çµ„æ–¹å‘ã¨ä¸­èº«ã®çµ„æ–¹å‘ãŒåŒã˜å ´åˆï¼Ž
+ \begin{itemize}
+ \item \texttt{[t]}指定ã®ã¨ã:
+ 中身ã®å…ˆé ­è¡Œã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ãŒå‘¨å›²ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¨ä¸€è‡´ã™ã‚‹ï¼Ž
+ 表組ã§å…ˆé ­è¡Œã®ä¸Šã«ç½«ç·šãŒã‚ã£ãŸå ´åˆã¯ï¼Œãã‚ŒãŒãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã®ä½ç½®
+ \footnote{\LuaTeX-jaã§ã¯å’Œæ–‡å´ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã®ä½ç½®ã‚‚上下移動ã§ãã‚‹ã“ã¨ã«æ³¨æ„.
+ ãã®ãŸã‚「和文ベースラインã€ã®ä½ç½®ã«æ¥ã‚‹ã¨ã¯é™ã‚‰ãªã„.}ã¨ãªã‚‹ï¼Ž
+ \item \texttt{[c]}指定ã®ã¨ã:
+ 中身ã®ä¸Šä¸‹ã®ä¸­å¿ƒãŒå‘¨å›²ã®æ•°å¼ã®è»¸ã‚’通る.
+ \item \texttt{[b]}指定ã®ã¨ã:
+ 中身ã®æœ€çµ‚è¡Œã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ãŒå‘¨å›²ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¨ä¸€è‡´ã™ã‚‹ï¼Ž
+ 表組ã§æœ€çµ‚è¡Œã®ä¸‹ã«ç½«ç·šãŒã‚ã£ãŸå ´åˆã¯ï¼Œãã‚ŒãŒãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã®ä½ç½®ã¨ãªã‚‹ï¼Ž
+ \end{itemize}
+ \item[B] 周囲ã®çµ„æ–¹å‘ã¨ä¸­èº«ã®çµ„æ–¹å‘ãŒ90度ãšã‚Œã¦ã„ã‚‹å ´åˆï¼Ž
+ \begin{itemize}
+ \item \texttt{[t]}指定ã®ã¨ã:
+ 表組ã«ãŠã„ã¦ã¯ï¼Œä¸Šç«¯ãŒå‘¨å›²ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¨ä¸€è‡´ã™ã‚‹ï¼Ž
+ \cs{parbox}ã‚„\cs{minipage}環境ã«ãŠã„ã¦ã¯ï¼Œä¸Šç«¯ãŒå‘¨å›²ã®å’Œæ–‡æ–‡å­—ã®ä¸Šç«¯ã¨ä¸€è‡´ã™ã‚‹ï¼Ž
+ \item \texttt{[c]}指定ã®ã¨ã:
+ 中身ã®ä¸Šä¸‹ã®ä¸­å¿ƒãŒå‘¨å›²ã®æ•°å¼ã®è»¸ã‚’通る.
+ \item \texttt{[b]}指定ã®ã¨ã:
+ 表組ã«ãŠã„ã¦ã¯ï¼Œä¸‹ç«¯ãŒå‘¨å›²ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¨ä¸€è‡´ã™ã‚‹ï¼Ž
+ \cs{parbox}ã‚„\cs{minipage}環境ã«ãŠã„ã¦ã¯ï¼Œä¸‹ç«¯ãŒå‘¨å›²ã®å’Œæ–‡æ–‡å­—ã®ä¸‹ç«¯ã¨ä¸€è‡´ã™ã‚‹ï¼Ž
+ \end{itemize}
+ \item[C] 周囲ã®çµ„æ–¹å‘ã¨ä¸­èº«ã®çµ„æ–¹å‘ãŒ180度ãšã‚Œã¦ã„ã‚‹å ´åˆï¼Ž
+ \cs{parbox}ã‚„\cs{minipage}環境ã«ãŠã„ã¦ã¯ï¼Œä¸Šã®Bã®å ´åˆã¨åŒã˜æŒ™å‹•ã§ã‚る.表組ã«ãŠã„ã¦ã¯ï¼Œ
+ Aã§\texttt{[t]}ã¨\texttt{[b]}を入れ替ãˆãŸ
+ \begin{itemize}
+ \item \texttt{[t]}指定ã®ã¨ã:
+ 中身ã®æœ€çµ‚è¡Œã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ãŒå‘¨å›²ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¨ä¸€è‡´ã™ã‚‹ï¼Ž
+ 最終行ã®ä¸‹ã«ç½«ç·šãŒã‚ã£ãŸå ´åˆã¯ï¼Œãã‚ŒãŒãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã®ä½ç½®ã¨ãªã‚‹ï¼Ž
+ \item \texttt{[c]}指定ã®ã¨ã:
+ 中身ã®ä¸Šä¸‹ã®ä¸­å¿ƒãŒå‘¨å›²ã®æ•°å¼ã®è»¸ã‚’通る.
+ \item \texttt{[b]}指定ã®ã¨ã:
+ 中身ã®å…ˆé ­è¡Œã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ãŒå‘¨å›²ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¨ä¸€è‡´ã™ã‚‹ï¼Ž
+ 表組ã§å…ˆé ­è¡Œã®ä¸Šã«ç½«ç·šãŒã‚ã£ãŸå ´åˆã¯ï¼Œãã‚ŒãŒãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã®ä½ç½®ã¨ãªã‚‹ï¼Ž
+ \end{itemize}
+ \item[D] 通常ã®ç¸¦çµ„(\cs{tate})ã¨ã€Œç¸¦æ•°å¼ãƒ‡ã‚£ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã€ã«ç›¸å½“ã™ã‚‹\cs{utod}æ–¹å‘ãŒçµ¡ã‚“ã å ´åˆï¼Ž
+ \cs{parbox}ã‚„\cs{minipage}環境ã«ãŠã„ã¦ã¯ï¼Œä¸Šã®Bã®å ´åˆã¨åŒã˜æŒ™å‹•ã§ã‚る.表組ã«ãŠã„ã¦ã¯ï¼Œ
+ \begin{itemize}
+ \item \texttt{[t]}指定ã®ã¨ã:
+ 中身ã®å…ˆé ­è¡Œã®æ¬§æ–‡ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ãŒå‘¨å›²ã®æ¬§æ–‡ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¨ä¸€è‡´ã™ã‚‹ï¼Ž
+ \item \texttt{[c]}指定ã®ã¨ã:
+ 中身ã®ä¸Šä¸‹ã®ä¸­å¿ƒãŒå‘¨å›²ã®æ•°å¼ã®è»¸ã‚’通る.
+ \item \texttt{[b]}指定ã®ã¨ã:
+ 中身ã®æœ€çµ‚è¡Œã®æ¬§æ–‡ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ãŒå‘¨å›²ã®æ¬§æ–‡ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¨ä¸€è‡´ã™ã‚‹ï¼Ž
+ \end{itemize}
+\end{description}
+%</ja>
+
+\subsection{\Pkg{luatexja-preset}}
+\label{ssec:preset}
+
+%<*en>
+As described in Subsection~\ref{ssec:preset-abst},
+One can load the \Pkg{luatexja-preset}
+package to use several ``presets'' of Japanese fonts.
+This package provides functions in a part of \Pkg{japanese-otf} package (changing fonts)
+and a part of \Pkg{PXchfon} package (presets) by Takayuki Yato.
+
+Options which are given in \cs{usepackage} but not described in this~subsection
+are simply passed to the \Pkg{luatexja-fontspec}\footnote{if \texttt{nfssonly} option is
+\emph{not} specified; in this case these options are simply ignored.}.
+For example, the line~5 in below example is equivalent to lines 1--3.
+%</en>
+%<*ja>
+\ref{ssec:preset-abst}節ã§è¿°ã¹ãŸã‚ˆã†ã«ï¼Œã‚ˆã使ã‚ã‚Œã¦ã„る和文フォント設定を一行ã§æŒ‡å®šã§ãるよã†ã«ã—ãŸã®ãŒ
+\Pkg{luatexja-preset}パッケージã§ã‚る.ã“ã®ãƒ‘ッケージã¯ï¼Œ
+\Pkg{otf}パッケージã®ä¸€éƒ¨ï¼ˆå¤šæ›¸ä½“化)ã¨å…«ç™»å´‡ä¹‹æ°ã«ã‚ˆã‚‹\Pkg{PXchfon}パッケージã®ä¸€éƒ¨ï¼ˆãƒ—リセット指定)
+ã¨ã‚’åˆã‚ã›ãŸã‚ˆã†ãªæ ¼å¥½ã‚’ã—ã¦ã„る.
+
+パッケージ読ã¿è¾¼ã¿æ™‚ã«æ¸¡ã•ã‚ŒãŸã‚ªãƒ—ションã®ã†ã¡ï¼Œ
+本節ã«ãªã„ã‚‚ã®ã‚’指定ã—ãŸå ´åˆï¼Œãれらã¯ãã®ã¾ã¾
+\Pkg{luatexja-fontspec}パッケージã«æ¸¡ã•ã‚Œã‚‹\footnote{\texttt{nfssonly} オプションãŒ
+指定ã•ã‚Œã¦ã„ãŸå ´åˆã¯ï¼Œ\Pkg{luatexja-fontspec}パッケージã¯èª­ã¿è¾¼ã¾ã‚Œãªã„ã®ã§å˜ç´”ã«ç„¡è¦–ã•ã‚Œ
+る.}.例ãˆã°ï¼Œä¸‹ã®1--3行目ã¯5行目ã®ã‚ˆã†ã«ä¸€è¡Œã«ã¾ã¨ã‚ã‚‹ã“ã¨ãŒã§ãる.
+%</ja>
+\begin{lstlisting}
+\usepackage[no-math]{fontspec}
+\usepackage[match]{luatexja-fontspec}
+\usepackage[kozuka-pr6n]{luatexja-preset}
+%%--------
+\usepackage[no-math,match,kozuka-pr6n]{luatexja-preset}
+\end{lstlisting}
+
+%<en>\subsubsection{General Options}
+%<ja>\subsubsection{一般的ãªã‚ªãƒ—ション}
+\label{sssec:ltjpreset-general}
+
+\begin{cslist}[before*=]
+\item[fontspec%
+%<en>\textrm{~(enabled by default)}
+%<ja>\emph{\gtfamily (既定)}
+]
+%<*en>
+With this option, Japanese fonts are selected using functionality of
+the \Pkg{luatexja-fontspec} package. This means that the \Pkg{fontspec} package is
+ automatically loaded by this package.
+
+If you need to pass some options to \Pkg{fontspec}, you can load \Pkg{fontspec} manually
+before \Pkg{luatexja-preset}:
+%</en>
+%<*ja>
+\Pkg{luatexja-fontspec}パッケージã®æ©Ÿèƒ½ã‚’用ã„ã¦å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚’é¸æŠžã™ã‚‹ï¼Ž
+ã“ã‚Œã¯ï¼Œ\Pkg{fontspec}パッケージãŒè‡ªå‹•ã§èª­ã¿è¾¼ã¾ã‚Œã‚‹ã“ã¨ã‚’æ„味ã™ã‚‹ï¼Ž
+
+ã‚‚ã—\Pkg{fontspec}パッケージã«ä½•ã‚‰ã‹ã®ã‚ªãƒ—ションを渡ã™å¿…è¦ãŒã‚ã‚‹
+\footnote{例ãˆã°ï¼Œæ•°å¼ãƒ•ã‚©ãƒ³ãƒˆã¾ã§ç½®æ›ã•ã‚Œã¦ã—ã¾ã„,\cs{mathit}ã«ã‚ˆã£ã¦ã‚®ãƒªã‚·ãƒ£æ–‡å­—ã®
+斜体大文字ãŒå‡ºãªããªã‚‹ï¼Œãªã©ï¼Ž}å ´åˆã¯ï¼Œ
+次ã®ã‚ˆã†ã«\Pkg{luatexja-preset}ã®å‰ã«\Pkg{fontspec}を手動ã§èª­ã¿ã“ã‚ã°è‰¯ã„:
+%</ja>
+\begin{lstlisting}
+\usepackage[no-math]{fontspec}
+\usepackage[...]{luatexja-preset}
+\end{lstlisting}
+
+\item[nfssonly]
+%<*en>
+With this option, selecting Japanese fonts won't be performed using the functionality of
+ the \Pkg{fontspec} package, but only standard NFSS2 (hence without
+ \cs{addjfontfeatures} etc.).
+This option is ignored when \Pkg{luatexja-fontspec} package is loaded.
+
+When this option is specified, \Pkg{fontspec}~and~\Pkg{luatexja-fontspec} are
+\emph{not} loaded by default. Nevertheless,
+the package\Pkg{fontspec} can coexist with the option, as the following:
+\begin{lstlisting}
+\usepackage{fontspec}
+\usepackage[hiragino-pron,nfssonly]{luatexja-preset}
+\end{lstlisting}
+In this case, one can use \cs{setmainfont} etc.\ to select \emph{alphabetic} fonts.
+%</en>
+%<*ja>
+\LaTeX 標準ã®ãƒ•ã‚©ãƒ³ãƒˆé¸æŠžæ©Ÿæ§‹(NFSS2)を用ã„ã¦
+\texttt{ltjpm}$n$(明æœï¼‰ï¼Œ\texttt{ltjpg}$n$(ゴシック),
+ãã‚Œã«å¾Œã«è¿°ã¹ã‚‹\texttt{deluxe}オプションãŒæŒ‡å®šã•ã‚ŒãŸå ´åˆã«ã¯
+\texttt{ltjpmg}$n$(丸ゴシック)ã¨ã„ã†
+和文フォントファミリを定義%
+\footnote{%
+ $n$ã¯è‡ªç„¶æ•°ã§ã‚り,\cs{ltjapplypreset}ã®å®Ÿè¡Œï¼ˆã“ã®å‘½ä»¤ã¯\Pkg{luatexja-preset}パッケージ
+ 読ã¿è¾¼ã¿æ™‚ã«è‡ªå‹•çš„ã«å®Ÿè¡Œã•ã‚Œã‚‹ï¼‰ã”ã¨ã«å¢—加ã—ã¦ã„ã.
+}ã—,ã“れらを用ã„る.
+
+本オプション指定時ã«ã¯\Pkg{fontspec}・\Pkg{luatexja-fontspec}パッケージã¯
+自動ã§ã¯èª­ã¿è¾¼ã¾ã‚Œãªã„,ã—ã‹ã—,
+\begin{lstlisting}
+\usepackage{fontspec}
+\usepackage[hiragino-pron,nfssonly]{luatexja-preset}
+\end{lstlisting}
+ã®ã‚ˆã†ã«ã™ã‚Œã°ï¼Œã“ã®ã‚ªãƒ—ションを指定ã™ã‚Œã°
+欧文フォントを\Pkg{fontspec}パッケージã®æ©Ÿèƒ½ã‚’使ã£ã¦æŒ‡å®šã™ã‚‹ã“ã¨ãŒã§ãる.
+
+一方,\Pkg{luatexja-preset}パッケージ読ã¿è¾¼ã¿æ™‚ã«
+æ—¢ã«\Pkg{luatexja-fontspec}パッケージãŒèª­ã¿è¾¼ã¾ã‚Œã¦ã„ã‚‹å ´åˆã¯
+\texttt{nfssonly}オプションã¯ç„¡è¦–ã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+\item[match]
+%<*en>
+If this option is specified, usual family-changing commands such as
+\cs{rmfamily},~\cs{textrm}, \cs{sffamily},~\dots\ also change Japanese font family.
+This option is passed to \Pkg{luatexja-fontspec}, if \texttt{fontspec}
+option is specifed.
+%</en>
+
+%<*ja>
+ã“ã®ã‚ªãƒ—ションãŒæŒ‡å®šã•ã‚Œã‚‹ã¨ï¼Œã€Œ\pLaTeXe 新ドキュメントクラスã€ã®ã‚ˆã†ã«\
+\cs{rmfamily}, \verb+\textrm{...}+, \cs{sffamily} ç­‰ãŒ
+欧文フォントã ã‘ã§ãªã和文フォントも変更ã™ã‚‹ã‚ˆã†ã«ãªã‚‹ï¼Ž
+\ \texttt{fontspec}\
+オプションãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã‚‹å ´åˆã¯ï¼Œã“ã®ã‚ªãƒ—ション㯠\Pkg{luatexja-fontspec} パッケージã¸ã¨æ¸¡ã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+
+\item[nodeluxe%
+%<en>\textrm{~(enabled by default)}
+%<ja>\emph{\gtfamily (既定)}
+]
+%<*en>
+The nagation of \texttt{deluxe} option.
+Use one-weighted \textit{mincho} and \textit{gothic} font families.
+This means that \verb+\mcfamily\bfseries+, \verb+\gtfamily\bfseries+ and
+\verb+\gtfamily\mdseries+ use the same font.
+%</en>
+%<*ja>
+\texttt{deluxe}オプションã®å¦å®šï¼Ž
+\LaTeXe 環境下ã®æ¨™æº–設定ã®ã‚ˆã†ã«ï¼Œæ˜Žæœä½“・ゴシック体をå„1ウェイトã§ä½¿ç”¨ã™ã‚‹ï¼Ž
+より具体的ã«è¨€ã†ã¨ï¼Œã“ã®è¨­å®šã®ä¸‹ã§ã¯
+\ \verb+\mcfamily\bfseries+, \verb+\gtfamily\bfseries+,
+\verb+\gtfamily\mdseries+ã¯ã¿ãªåŒã˜ãƒ•ã‚©ãƒ³ãƒˆã¨ãªã‚‹ï¼Ž
+%</ja>
+\item[deluxe]
+%<*en>
+Use the mincho family with three weights (light, medium, and~bold),
+the gothic family with three weights (medium, bold, and extra~bold), and \textit{rounded gothic}%
+\footnote{Provided by \cs{mgfamily} and \cs{textmg},
+because ``rounded gothic'' is called \textit{maru gothic} (丸ゴシック) in Japanese.}.
+Mincho light and gothic extra~bold can be by
+\cs{mcfamily}\cs{ltseries}~and~\cs{gtfamily}\cs{ebseries}, respectively.
+
+\begin{itemize}
+ \item Some presets do not have the light weight of mincho.
+ In this case, we substitute the medium weight for the light weight.
+ \item \Pkg{luatexja-preset} does not produce an error (only produces a warning), even if
+ (one of) fonts for \cs{mcfamily}\cs{ltseries}, \cs{gtfamily}\cs{ebseries}, \cs{mgfamily}
+ do not exist.
+\end{itemize}
+%</en>
+%<*ja>
+明æœä½“・ゴシック体å„3ウェイトã¨ï¼Œ
+丸ゴシック体 (\cs{mgfamily}, \verb+\textmg{...}+) を利用å¯èƒ½ã«ã™ã‚‹ï¼Ž
+明æœä½“ã¯ç´°å­—・中字・太字ã®3ウェイトãŒã‚り,
+明æœä½“ã®ç´°å­—㯠\cs{mcfamily}\cs{ltseries} ã§åˆ©ç”¨ã§ãる.
+ã¾ãŸï¼Œã‚´ã‚·ãƒƒã‚¯ä½“ã¯ä¸­å­—・太字・極太ã®3ウェイトãŒã‚り,
+ゴシック体ã®æ¥µå¤ªã¯ \cs{gtfamily}\cs{ebseries} ã§åˆ©ç”¨ã§ãã‚‹%
+\footnote{éŽåŽ»ã¨ã®äº’æ›æ€§ã®ãŸã‚,\cs{gtebfamily}, \cs{textgteb\{...\}} ã‚‚
+ ä¾ç„¶ã¨ã—ã¦åˆ©ç”¨å¯èƒ½ã§ã‚る.}.
+
+\begin{itemize}
+ \item プリセット設定ã«ã‚ˆã£ã¦ã¯æ˜Žæœä½“ç´°å­—ãŒç”¨æ„ã•ã‚Œã¦ã„ãªã„ã‚‚ã®ã‚‚ã‚る.ãã®å ´åˆã¯
+ 明æœä½“中字ãŒä»£ç”¨ã•ã‚Œã‚‹ï¼Ž
+ \item 明æœä½“細字,ゴシック体極太,丸ゴシック体ã®3フォントã«ã¤ã„ã¦ã¯
+ 実際ã«ãƒ•ã‚©ãƒ³ãƒˆã‚’ロードã™ã‚‹å‰ã«å­˜åœ¨ã™ã‚‹ã‹ãƒã‚§ãƒƒã‚¯ã‚’è¡Œã†ï¼Ž
+ 存在ã—ãªã‹ã£ãŸã‚‚ã®ã«ã¤ã„ã¦ã¯è­¦å‘Šã‚’発ã—,
+ ãã‚Œãžã‚Œæ˜Žæœä½“中字.ゴシック体太字,ゴシック体太字ã§ä»£ç”¨ã™ã‚‹ï¼Ž
+\end{itemize}
+%</ja>
+\item[expert]
+%<*en>
+Use horizontal/vertical kana alternates, and define a command \cs{rubyfamily} to use kana
+characters designed for ruby.
+%</en>
+%<*ja>
+横組・縦組専用仮åを用ã„る.ã¾ãŸï¼Œ\cs{rubyfamily} ã§ãƒ«ãƒ“用仮åãŒä½¿ç”¨å¯èƒ½ã¨ãªã‚‹\footnote{%
+ \cs{rubyfamily}ã¨ã¯ã„ã„ã¤ã¤ï¼Œå®Ÿéš›ã«ã¯ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã‚’切り替ãˆã‚‹ã®ã§ã¯ãªã„(通常ã§ã¯
+ OpenType機能ã®æœ‰åŠ¹åŒ–ã§ã‚り,\texttt{nfssonly} 指定時ã«ã¯ã‚·ã‚§ã‚¤ãƒ—ã‚’ \texttt{rb} ã«åˆ‡ã‚Šæ›¿ãˆã‚‹ï¼‰ï¼Ž
+}.
+%</ja>
+\item[bold]
+%<*en>
+Substitute bold series of gothic for bold series of mincho.
+If \texttt{nodeluxe} option is enabled, medium series of gothic is also changed,
+since we use same font for both series of gothic.
+%</en>
+%<*ja>
+「明æœã®å¤ªå­—ã€ã‚’ゴシック体ã®å¤ªå­—ã«ã‚ˆã£ã¦ä»£æ›¿ã™ã‚‹ï¼Ž
+ã‚‚ã—\texttt{nodeluxe}オプションãŒæŒ‡å®šã•ã‚Œã¦ã„ã‚‹å ´åˆã¯ï¼Œã‚´ã‚·ãƒƒã‚¯ä½“ã¯1ウェイトã—ã‹ä½¿ç”¨ã•ã‚Œãª
+ ã„ãŸã‚,
+「ゴシック体ã®ä¸­å­—ã€ã‚‚åŒæ™‚ã«å¤‰æ›´ã•ã‚Œã‚‹ã“ã¨ã«ãªã‚‹ï¼Ž
+%</ja>
+\item[jis90\textrm{,~}90jis]
+%<en>Use JIS~X~0208:1990 glyph variants if possible.
+%<ja>出æ¥ã‚‹é™ã‚ŠJIS~X~0208:1990ã®å­—形を使ã†ï¼Ž
+\item[jis2004\textrm{,~}2004jis]
+%<en>Use JIS~X~0213:2004 glyph variants if possible.
+%<ja>出æ¥ã‚‹é™ã‚ŠJIS~X~0213:2004ã®å­—形を使ã†ï¼Ž
+\item[jfm\_yoko=<jfm>]
+%<*en>
+Use the JFM \texttt{jfm-<jfm>.lua} for horizontal direction, instead of \texttt{jfm-ujis.lua}~(default JFM).
+%</en>
+%<*ja>
+横組用和文フォントã§ç”¨ã„ã‚‹JFMã‚’\texttt{jfm-<jfm>.lua}ã«ã™ã‚‹ï¼Žã“ã®ã‚ªãƒ—ションãŒãªã„時ã¯
+\LuaTeX\nobreakdash -ja標準ã®\texttt{jfm-ujis.lua}ãŒç”¨ã„られる.
+%</ja>
+\item[jfm\_tate=<jfm>]
+%<*en>
+Use the JFM \texttt{jfm-<jfm>.lua} for vertical direction, instead of \texttt{jfm-ujisv.lua}~(default JFM).
+%</en>
+%<*ja>
+縦用和文フォントã§ç”¨ã„ã‚‹JFMã‚’\texttt{jfm-<jfm>.lua}ã«ã™ã‚‹ï¼Žã“ã®ã‚ªãƒ—ションãŒãªã„時ã¯
+\LuaTeX-ja標準ã®\texttt{jfm-ujisv.lua}ãŒç”¨ã„られる.
+%</ja>
+
+\item[jis]
+%<en>Same as \texttt{jfm\_yoko=jis}.
+%<ja>\texttt{jfm\_yoko=jis}ã¨åŒã˜ï¼Žã“ã“ã§ç”¨ã„ã‚‹JFM\texttt{jfm-jis.lua}ã¯JISフォントメトリックを元ã«ã—ãŸã‚‚ã®ã§ã‚る.
+
+\end{cslist}
+%<*en>
+Note that \texttt{jis90},~\texttt{90jis}, \texttt{jis2004}~and~\texttt{2004jis} only affect with mincho,
+gothic (and, possibly rounded gothic) families defined by this package.
+We didn't taken account of when more than one options among them are specified.
+%</en>
+%<*ja>
+\texttt{jis90},~\texttt{90jis}, \texttt{jis2004},~\texttt{2004jis}ã«ã¤ã„ã¦ã¯æœ¬ãƒ‘ッケージã§å®šç¾©ã•ã‚ŒãŸ
+明æœä½“・ゴシック体(・丸ゴシック体)ã«ã®ã¿æœ‰åŠ¹ã§ã‚る.
+ã“れら4オプションã®ã†ã¡è¤‡æ•°ãŒåŒæ™‚ã«æŒ‡å®šã•ã‚ŒãŸå ´åˆã®å‹•ä½œã«ã¤ã„ã¦ã¯å…¨ã考慮ã—ã¦ã„ãªã„.
+%</ja>
+
+%<en>\subsubsection{Presets which support multi weights}
+%<ja>\subsubsection{多ウェイト用プリセットã®ä¸€è¦§}
+\label{sssec:ltjpreset-multi}
+
+%<*en>
+Besides \texttt{bizud}, \texttt{morisawa-pro},~and~\texttt{morisawa-pr6n} presets,
+fonts are specified by font name, not by file name.
+In following tables, starred fonts (e.g.~KozGo\dots-Regular) are used for medium series of \textit{gothic},
+\emph{if and only if \texttt{deluxe} option is specified}.
+%</en>
+%<*ja>
+\texttt{bizud}, \texttt{morisawa-pro}, \texttt{morisawa-pr6n}以外ã¯ãƒ•ã‚©ãƒ³ãƒˆã®æŒ‡å®šã¯
+(ファイルåã§ãªã)フォントåã§è¡Œã‚れる.
+以下ã®è¡¨ã«ãŠã„ã¦ï¼Œ*\,ã¤ãã®ãƒ•ã‚©ãƒ³ãƒˆ(e.g.,~KozGo\dots-Regular)ã¯ï¼Œ\emph{\texttt{deluxe}オプション指定時ã«}
+ゴシック体中字ã¨ã—ã¦ç”¨ã„られるもã®ã‚’示ã—ã¦ã„る.
+%</ja>
+\begin{cslist}[style=standard]
+ \item[kozuka-pro] Kozuka Pro (Adobe-Japan1-4) fonts.
+%<en> \\*[-\dimexpr\medskipamount+\baselineskip\relax]
+ \item[kozuka-pr6] Kozuka Pr6 (Adobe-Japan1-6) fonts.
+%<en> \\*[-\dimexpr\medskipamount+\baselineskip\relax]
+ \item[kozuka-pr6n] Kozuka Pr6N (Adobe-Japan1-6, JIS04-savvy) fonts.
+
+%<*en>
+Kozuka Pro/Pr6N fonts are bundled with Adobe's software, such as Adobe~InDesign.
+There is not rounded gothic family in Kozuka fonts.
+%</en>
+%<*ja>
+å°å¡šPro書体・Pr6N書体ã¯Adobe InDesignç­‰ã®Adobe製å“ã«ãƒãƒ³ãƒ‰ãƒ«ã•ã‚Œã¦ã„る.
+「å°å¡šä¸¸ã‚´ã‚·ãƒƒã‚¯ã€ã¯å­˜åœ¨ã—ãªã„ã®ã§ï¼Œä¾¿å®œçš„ã«å°å¡šã‚´ã‚·ãƒƒã‚¯Hã«ã‚ˆã£ã¦ä»£ç”¨ã—ã¦ã„る.
+%</ja>
+\begin{center}\small
+\begin{tabular}{lllll}
+\toprule
+\bfseries family&\bfseries series&\ttfamily kozuka-pro&\ttfamily kozuka-pr6&\ttfamily kozuka-pr6n\\
+\midrule
+ &light&KozMinPro-Light&KozMinProVI-Light&KozMinPr6N-Light\\
+%<en>\textit{mincho}%
+%<ja>\textgt{明æœ}%
+ &medium&KozMinPro-Regular&KozMinProVI-Regular&KozMinPr6N-Regular\\
+ &bold&KozMinPro-Bold&KozMinProVI-Bold&KozMinPr6N-Bold\\
+\midrule
+ &&KozGoPro-Regular*&KozGoProVI-Regular*&KozGoPr6N-Regular*\\
+ &\smash{\raisebox{1.5ex}{medium}}
+ &KozGoPro-Medium&KozGoProVI-Medium&KozGoPr6N-Medium\\
+\cmidrule(l){2-5}
+%<en>\smash{\raisebox{2ex}{\textit{gothic}}}%
+%<ja>\smash{\raisebox{2ex}{\gt ゴシック}}%
+ &bold&KozGoPro-Bold&KozGoProVI-Bold&KozGoPr6N-Bold\\
+ &extra bold&KozGoPro-Heavy&KozGoProVI-Heavy&KozGoPr6N-Heavy\\
+\midrule
+%<en>\textit{rounded gothic}
+%<ja>\gt 丸ゴシック
+&&KozGoPro-Heavy&KozGoProVI-Heavy&KozGoPr6N-Heavy\\
+\bottomrule
+\end{tabular}
+\end{center}
+
+ \item[hiragino-pro] Hiragino Pro (Adobe-Japan1-5) fonts.
+%<en> \\*[-\dimexpr\medskipamount+\baselineskip\relax]
+ \item[hiragino-pron] Hiragino ProN (Adobe-Japan1-5, JIS04-savvy) fonts.
+
+%<*en>
+Hiragino fonts (except Hiragino~Mincho~W2) are bundled with Mac OS~X 10.5 or later.
+Some editions of a Japanese word-processor ``一太郎2012'' includes Hiragino ProN fonts.
+Note that fonts for gothic extra~bold (HiraKakuStd[N]-W8) only contains characters in
+Adobe-Japan1-3 character collection, while others contains those in
+Adobe-Japan1-5 character collection.
+%</en>
+%<*ja>
+ヒラギノフォントã¯ï¼ŒMac OS~X以外ã«ã‚‚,一太郎2012ã®ä¸Šä½ã‚¨ãƒ‡ã‚£ã‚·ãƒ§ãƒ³ã«ã‚‚ãƒãƒ³ãƒ‰ãƒ«ã•ã‚Œã¦ã„る.
+極太ゴシック体ã¨ã—ã¦ç”¨ã„るヒラギノ角ゴW8ã¯ï¼ŒAdobe-Japan1-3ã®ç¯„囲ã—ã‹ã‚«ãƒãƒ¼ã—ã¦ã„ãªã„
+Std/StdNフォントã§ã‚り,ãã®ä»–ã¯Adobe-Japan1-5対応ã§ã‚る.
+
+ãªãŠï¼Œæ˜Žæœä½“ç´°å­—ã¨ã—ã¦ç”¨ã„るヒラギノ明æœä½“W2ã¯OS~Xや一太郎ã«ã¯ãƒãƒ³ãƒ‰ãƒ«ã•ã‚Œã¦ãŠã‚‰ãšï¼Œ
+別途購入ã™ã‚‹å¿…è¦ãŒã‚る.
+%</ja>
+\begin{center}\small
+\begin{tabular}{llll}
+\toprule
+\bf family&\bf series&\tt hiragino-pro&\tt hiragino-pron\\
+\midrule
+ &light&Hiragino~Mincho~Pro~W2&Hiragino~Mincho~ProN~W2\\
+%<en>\textit{mincho}%
+%<ja>\textgt{明æœ}%
+ &medium&Hiragino~Mincho~Pro~W3&Hiragino~Mincho~ProN~W3\\
+ &bold&Hiragino~Mincho~Pro~W6&Hiragino~Mincho~ProN~W6\\
+\midrule
+ &&Hiragino~Kaku~Gothic~Pro~W3*&Hiragino~Kaku~Gothic~ProN~W3*\\
+ &\smash{\raisebox{1.5ex}{medium}}
+ &Hiragino~Kaku~Gothic~Pro~W6&Hiragino~Kaku~Gothic~ProN~W6\\
+\cmidrule(l){2-4}
+%<en>\smash{\raisebox{2ex}{\textit{gothic}}}%
+%<ja>\smash{\raisebox{2ex}{\gt ゴシック}}%
+ &bold&Hiragino~Kaku~Gothic~Pro~W6&Hiragino~Kaku~Gothic~ProN~W6\\
+ &extra bold&Hiragino~Kaku~Gothic~Std~W8&Hiragino~Kaku~Gothic~StdN~W8\\
+\midrule
+%<en>\textit{rounded gothic}
+%<ja>\gt 丸ゴシック
+&&Hiragino~Maru~Gothic~Pro~W4&Hiragino~Maru~Gothic~ProN~W4\\
+\bottomrule
+\end{tabular}
+\end{center}
+
+%<ja>\newpage
+\item[bizud] BIZ UD fonts (by Morisawa Inc.) bundled with
+ Windows~10 October 2018 Update.
+\begin{center}\small
+\begin{tabular}{ll>{\ttfamily}l}
+\toprule
+\textbf{family}&\textbf{series}\\
+\midrule
+%<en>\textit{mincho}
+%<ja>\textgt{明æœ}%
+ &&BIZ-UDMinchoM.ttc\\
+\midrule
+ &medium&BIZ-UDGothicR.ttc\\
+\cmidrule(l){2-3}
+%<en>\textit{gothic}%
+%<ja>\gt ゴシック
+ &bold&BIZ-UDGothicB.ttc\\
+ &extra bold&BIZ-UDGothicB.ttc\\
+\midrule
+%<en>\textit{rounded gothic}
+%<ja>\gt 丸ゴシック
+&&BIZ-UDGothicB.ttc\\
+\bottomrule
+\end{tabular}
+\end{center}
+
+%<en>\newpage
+
+ \item[morisawa-pro] Morisawa Pro (Adobe-Japan1-4) fonts.
+%<en> \\*[-\dimexpr\medskipamount+\baselineskip\relax]
+ \item[morisawa-pr6n] Morisawa Pr6N (Adobe-Japan1-6, JIS04-savvy) fonts.
+\begin{center}\footnotesize
+\begin{tabular}{ll>{\tt}l>{\tt}l}
+\toprule
+\bf family&\bf series&morisawa-pro&morisawa-pr6n\\
+\midrule
+ &medium&A-OTF-RyuminPro-Light.otf&A-OTF-RyuminPr6N-Light.otf\\
+%<en>\smash{\raisebox{1.5ex}{\textit{mincho}}}%
+%<ja>\smash{\raisebox{1.5ex}{\gt 明æœ}}%
+ &bold&A-OTF-FutoMinA101Pro-Bold.otf&A-OTF-FutoMinA101Pr6N-Bold.otf\\
+\midrule
+ &medium
+ &A-OTF-GothicBBBPro-Medium.otf&A-OTF-GothicBBBPr6N-Medium.otf\\
+%<en>\textit{gothic}%
+%<ja>\gt ゴシック
+ &bold&A-OTF-FutoGoB101Pro-Bold.otf&A-OTF-FutoGoB101Pr6N-Bold.otf\\
+ &extra bold&A-OTF-MidashiGoPro-MB31.otf&A-OTF-MidashiGoPr6N-MB31.otf\\
+\midrule
+%<en>\textit{rounded gothic}
+%<ja>\gt 丸ゴシック
+&&A-OTF-Jun101Pro-Light.otf&A-OTF-ShinMGoPr6N-Light.otf\\
+\bottomrule
+\end{tabular}
+\end{center}
+
+
+ \item[yu-win] Yu fonts bundled with Windows~8.1.
+%<en> \\*[-\dimexpr\medskipamount+\baselineskip\relax]
+ \item[yu-win10] Yu fonts bundled with Windows~10.
+%<en> \\*[-\dimexpr\medskipamount+\baselineskip\relax]
+ \item[yu-osx] Yu fonts bundled with OSX~Mavericks.
+\begin{center}\small
+\begin{tabular}{lllll}
+\toprule
+\bf family&\bf series&\texttt{yu-win}&\texttt{yu-win10}&\texttt{yu-osx}\\
+\midrule
+ &light&YuMincho-Light&YuMincho-Light&(YuMincho~Medium)\\
+%<en>\textit{mincho}%
+%<ja>\textgt{明æœ}%
+ &medium&YuMincho-Regular&YuMincho-Regular&YuMincho~Medium\\
+ &bold&YuMincho-Demibold&YuMincho-Demibold&YuMincho~Demibold\\
+\midrule
+ &&YuGothic-Regular*&YuGothic-Regular*&YuGothic~Medium*\\
+ &\smash{\raisebox{1.5ex}{medium}}%
+ &YuGothic-Regular&YuGothic-Medium&YuGothic~Medium\\
+\cmidrule(l){2-5}
+%<en>\textit{gothic}%
+%<ja>\gt ゴシック
+ &bold&YuGothic-Bold&YuGothic-Bold&YuGothic~Bold\\
+ &extra bold&YuGothic-Bold&YuGothic-Bold&YuGothic~Bold\\
+\midrule
+%<en>\textit{rounded gothic}
+%<ja>\gt 丸ゴシック
+&&YuGothic-Bold&YuGothic-Bold&YuGothic~Bold\\
+\bottomrule
+\end{tabular}
+\end{center}
+
+\item[moga-mobo] MogaMincho, MogaGothic, and MoboGothic.
+%<en> \\*[-\dimexpr\medskipamount+\baselineskip\relax]
+\item[moga-mobo-ex] MogaExMincho, MogaExGothic, and MoboExGothic.
+%<en>\par These fonts can be downloaded from \url{http://yozvox.web.fc2.com/}.
+%<ja>ã“れらã®ãƒ•ã‚©ãƒ³ãƒˆã¯ \url{http://yozvox.web.fc2.com/} ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã§ãる.
+\begin{center}\small
+\begin{tabular}{llll}
+\toprule
+\bf family&\bf series&\bf default, \texttt{90jis}~option&\bf \texttt{jis2004} option\\
+\midrule
+ &medium&Moga90Mincho&MogaMincho\\
+%<en>\smash{\raisebox{1.5ex}{\textit{mincho}}}%
+%<ja>\smash{\raisebox{1.5ex}{\gt 明æœ}}%
+ &bold&Moga90Mincho Bold&MogaMincho Bold\\
+\midrule
+ &medium&Moga90Gothic&MogaGothic\\
+%<en>\textit{gothic}%
+%<ja>\gt ゴシック
+ &bold&Moga90Gothic Bold&MogaGothic Bold\\
+ &extra bold&Moga90Gothic Bold&MogaGothic Bold\\
+\midrule
+%<en>\textit{rounded gothic}
+%<ja>\gt 丸ゴシック
+&&Mobo90Gothic&MoboGothic\\
+\bottomrule
+\end{tabular}
+\end{center}
+%<en>When \texttt{moga-mobo-ex} is specified, the font ``MogaEx90Mincho'' etc.\ are used.
+%<ja>\texttt{moga-mobo-ex}オプション指定時ã«ã¯MogaEx90Minchoãªã©ã®ExãŒåå‰ã«ã¤ã„ãŸãƒ•ã‚©ãƒ³ãƒˆãŒä½¿ã‚れる.
+
+\item[ume] Ume Mincho and Ume Gothic.
+%<en>\par These fonts can be downloaded from\\\hfill \url{https://ja.osdn.net/projects/ume-font/wiki/FrontPage}.
+%<ja>ã“れらã®ãƒ•ã‚©ãƒ³ãƒˆã¯ \url{https://ja.osdn.net/projects/ume-font/wiki/FrontPage} ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã§ãる.
+\begin{center}\small
+\begin{tabular}{lll}
+\toprule
+\bf family&\bf series&\bf default\\
+\midrule
+ &medium&Ume Mincho\\
+%<en>\smash{\raisebox{1.5ex}{\textit{mincho}}}%
+%<ja>\smash{\raisebox{1.5ex}{\gt 明æœ}}%
+ &bold&Ume Mincho\\
+\midrule
+ &&Ume Gothic*\\
+ &\smash{\raisebox{1.5ex}{medium}}&Ume Gothic O5\\
+\cmidrule(l){2-3}
+%<en>\textit{gothic}%
+%<ja>\gt ゴシック
+ &bold&Ume Gothic O5\\
+ &extra bold&Ume Gothic O5\\
+\midrule
+%<en>\textit{rounded gothic}
+%<ja>\gt 丸ゴシック
+&&Ume Gothic O5\\
+\bottomrule
+\end{tabular}
+\end{center}
+
+%<en>\newpage
+ \item[sourcehan] Source Han Serif and Source Han Sans fonts (Language-specific OTF \textit{or} OTC)
+%<en> \\*[-\dimexpr\medskipamount+\baselineskip\relax]
+ \item[sourcehan-jp] Source Han Serif JP and Source Han Sans JP fonts (Region-specific Subset OTF)
+\begin{center}\small
+\def\AD#1#2{Source Han #1 #2&Source Han #1 JP #2}%
+\begin{tabular}{lllll}
+\toprule
+\bf family&\bf series&\texttt{sourcehan}&\texttt{sourcehan-jp}\\
+\midrule
+ &light&\AD{Serif}{Light}\\
+%<en>\textit{mincho}%
+%<ja>\textgt{明æœ}%
+ &medium&\AD{Serif}{Regular}\\
+ &bold&\AD{Serif}{Bold}\\
+\midrule
+ &&\AD{Sans}{Regular*}\\
+ &\smash{\raisebox{1.5ex}{medium}}
+ &\AD{Sans}{Medium}\\
+\cmidrule(l){2-4}
+%<en>\smash{\raisebox{2ex}{\textit{gothic}}}%
+%<ja>\smash{\raisebox{2ex}{\gt ゴシック}}%
+ &bold&\AD{Sans}{Bold}\\
+ &extra bold&\AD{Sans}{Heavy}\\
+\midrule
+%<en>\textit{rounded gothic}
+%<ja>\gt 丸ゴシック
+&&\AD{Sans}{Heavy}\\
+\bottomrule
+\end{tabular}
+\end{center}
+
+
+ \item[noto-otc] Noto Serif CJK and Noto Sans CJK fonts (OTC)
+%<en> \\*[-\dimexpr\medskipamount+\baselineskip\relax]
+ \item[noto-otf] Noto Serif CJK and Noto Sans CJK fonts (Language-specific OTF)
+\begin{center}\small
+\def\AD#1#2{Noto #1 CJK #2&Noto #1 CJK JP #2}%
+\begin{tabular}{lllll}
+\toprule
+\bf family&\bf series&\texttt{noto-otc}&\texttt{noto-otf}\\
+\midrule
+ &light&\AD{Serif}{Light}\\
+%<en>\textit{mincho}%
+%<ja>\textgt{明æœ}%
+ &medium&\AD{Serif}{Regular}\\
+ &bold&\AD{Serif}{Bold}\\
+\midrule
+ &&\AD{Sans}{Regular*}\\
+ &\smash{\raisebox{1.5ex}{medium}}
+ &\AD{Sans}{Medium}\\
+\cmidrule(l){2-4}
+%<en>\smash{\raisebox{2ex}{\textit{gothic}}}%
+%<ja>\smash{\raisebox{2ex}{\gt ゴシック}}%
+ &bold&\AD{Sans}{Bold}\\
+ &extra bold&\AD{Sans}{Black}\\
+\midrule
+%<en>\textit{rounded gothic}
+%<ja>\gt 丸ゴシック
+&&\AD{Sans}{Black}\\
+\bottomrule
+\end{tabular}
+\end{center}
+
+\end{cslist}
+%<en>\subsubsection{Presets which do not support multi weights}
+%<ja>\subsubsection{å˜ã‚¦ã‚§ã‚¤ãƒˆç”¨ãƒ—リセット一覧}
+\label{sssec:ltjpreset-single}
+
+%<*en>
+Next, we describe settings for using only single weight.
+%</en>
+%<*ja>
+次ã«ï¼Œå˜ã‚¦ã‚§ã‚¤ãƒˆç”¨ã®è¨­å®šã‚’è¿°ã¹ã‚‹ï¼Žã“ã®4設定ã§ã¯
+明æœä½“太字・丸ゴシック体ã¯ã‚´ã‚·ãƒƒã‚¯ä½“ã¨åŒã˜ãƒ•ã‚©ãƒ³ãƒˆãŒç”¨ã„られる.
+%</ja>
+\par\nobreak\medskip
+{\centering\small
+\begin{tabular}{lllll}
+\toprule
+&\tt noembed&\tt ipa&\tt ipaex&\tt ms\\
+\midrule
+%<*en>
+\it mincho&Ryumin-Light (non-embedded)
+&IPA Mincho&IPAex Mincho&MS Mincho\\
+\it gothic&GothicBBB-Medium (non-embedded)
+&IPA Gothic&IPAex Gothic&MS Gothic\\
+%</en>
+%<*ja>
+\gtfamily 明æœ&Ryumin-Light(éžåŸ‹è¾¼ï¼‰
+&IPA明æœ&IPAex明æœ&MS明æœ\\
+\gtfamily ゴシック&GothicBBB-Medium(éžåŸ‹è¾¼ï¼‰
+&IPAゴシック&IPAexゴシック&MSゴシック\\
+%</ja>
+\bottomrule
+\end{tabular}\par\medskip}
+
+%<en>\subsubsection{Presets which use HG fonts}
+%<ja>\subsubsection{HGフォントを使ã†ãƒ—リセット}
+\label{sssec:ltjpreset-hg}
+%<*en>
+We can use HG~fonts bundled with Microsoft~Office for realizing multiple weights.
+In the table below, starred fonts (e.g., IPA~Gothic*) are used
+only if \texttt{jis2004} or \texttt{nodeluxe} option is spefified.
+%</en>
+%<*ja>
+ã™ãå‰ã«æ›¸ã„ãŸå˜ã‚¦ã‚§ã‚¤ãƒˆç”¨è¨­å®šã‚’,Microsoft Officeç­‰ã«ä»˜å±žã™ã‚‹HGフォントを使ã£ã¦
+多ウェイト化ã—ãŸè¨­å®šã‚‚ã‚る.以下ã®è¡¨ã§ã¯ï¼Œ*~付ãã®ãƒ•ã‚©ãƒ³ãƒˆï¼ˆä¾‹ï¼šIPAゴシック*)ã¯
+\texttt{jis2004}ã¨\texttt{nodeluxe}ã®ã„ãšã‚Œã‹ã®ã‚ªãƒ—ションãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã‚‹ã¨ãã«ä½¿ã‚れる.
+%</ja>
+\par\nobreak\medskip
+{\centering\small
+\begin{tabular}{lllll}
+\toprule
+\textbf{family}&\textbf{series}&\tt ipa-hg&\tt ipaex-hg&\tt ms-hg\\
+\midrule
+%<*en>
+&medium&IPA Mincho&IPAex Mincho&MS Mincho\\
+\smash{\raisebox{1.5ex}{\textit{mincho}}}%
+&bold&HG Mincho E&HG Mincho E&HG Mincho E\\\midrule
+&&IPA Gothic*&IPAex Gothic*&MS Gothic*\\
+&\smash{\raisebox{1.5ex}{medium}}%
+&HG Gothic M&HG Gothic M&HG Gothic M\\\cmidrule{2-5}
+\textit{gothic}&bold&HG Gothic E&HG Gothic E&HG Gothic E\\\cmidrule{2-5}
+&extra bold&HG Soei Kaku Gothic UB&HG Soei Kaku Gothic UB&HG Soei Kaku Gothic UB\\\midrule
+\textit{rounded gothic}&&
+HG MaruGothic M PRO&HG MaruGothic M PRO&HG MaruGothic M PRO\\
+%</en>
+%<*ja>
+&medium&IPA明æœ&IPAex明æœ&MS明æœ\\
+\smash{\raisebox{1.5ex}{\textgt{明æœ}}}%
+&bold&HG明æœE&HG明æœE&HG明æœE\\\midrule
+&&IPAゴシック*&IPAexゴシック*&MSゴシック*\\
+&\smash{\raisebox{1.5ex}{medium}}%
+&HGゴシックM&HGゴシックM&HGゴシックM\\\cmidrule{2-5}
+\textgt{ゴシック}&bold&HGゴシックE&HGゴシックE&HGゴシックE\\\cmidrule{2-5}
+&extra bold&HG創英角ゴシックUB&HG創英角ゴシックUB&HG創英角ゴシックUB\\\midrule
+\textgt{丸ゴシック}&&
+HG丸ゴシックM-PRO&HG丸ゴシックM-PRO&HG丸ゴシックM-PRO\\
+%</ja>
+\bottomrule
+\end{tabular}\par\medskip}
+
+%<*en>
+Note that HG~Mincho~E, HG~Gothic~E, HG Soei Kaku Gothic UB, and HG Maru Gothic PRO
+are internally specified by:
+\begin{description}
+\item[default] by font name (\texttt{HGMinchoE}, etc.).
+\item[\texttt{jis90}, \texttt{90jis}] by file name (\texttt{hgrme.ttc}, \texttt{hgrge.ttc}, \texttt{hgrsgu.ttc}, \texttt{hgrsmp.ttf}).
+\item[\texttt{jis2004}, \texttt{2004jis}] by file name (\texttt{hgrme04.ttc}, \texttt{hgrge04.ttc}, \texttt{hgrsgu04.ttc}, \texttt{hgrsmp04.ttf}).
+\end{description}
+%</en>
+%<*ja>
+ãªãŠï¼ŒHG明æœE・HGゴシックE・HG創英角ゴシックUB・HG丸ゴシック体PROã®4ã¤ã«ã¤ã„ã¦ã¯ï¼Œå†…部ã§
+\begin{description}
+\item[標準] フォントå(\texttt{HGMinchoE} ãªã©ï¼‰
+\item[\texttt{jis90}, \texttt{90jis}指定時] ファイルå (%
+\texttt{hgrme.ttc}, \texttt{hgrge.ttc}, \texttt{hgrsgu.ttc}, \texttt{hgrsmp.ttf})
+\item[\texttt{jis2004}, \texttt{2004jis}指定時] ファイルå (%
+\texttt{hgrme04.ttc}, \texttt{hgrge04.ttc}, \texttt{hgrsgu04.ttc}, \texttt{hgrsmp04.ttf})
+\end{description}
+ã¨ã—ã¦æŒ‡å®šã‚’è¡Œã£ã¦ã„ã‚‹ã®ã§æ³¨æ„ã™ã‚‹ã“ã¨ï¼Ž
+%</ja>
+
+%<en>\subsubsection{Define/Use Custom Presets}
+%<ja>\subsubsection{æ–°ãŸãªãƒ—リセットã®å®šç¾©}
+
+%<*ja>
+ãƒãƒ¼ã‚¸ãƒ§ãƒ³20170904.0以é™ã§ã¯ï¼Œè‡ªåˆ†ã§æ–°ãŸãªãƒ—リセットを定義ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã‚‹ã‚ˆã†ã«ãªã£ãŸï¼Ž
+以下ã«èª¬æ˜Žã™ã‚‹2命令ã¯ãƒ—リアンブルã§ã—ã‹å®Ÿè¡Œã§ããªã„.
+%</ja>
+%<*en>
+From version~20170904.0, one can define new presets using \cs{ltjnewpreset},
+and use them by \cs{ltjapplypreset}. These two commands can only be used in the preamble.
+%</en>
+\begin{cslist}
+ \item[\cs{ltjnewpreset}\{<name>\}\{<specification>\}]
+%<*ja>
+ æ–°ãŸã«<name>ã¨ã„ã†å称ã®ãƒ—リセットを定義ã™ã‚‹ï¼Žã“ã®å称ã¯ï¼Œ
+ ã™ã§ã«å®šç¾©ã•ã‚Œã¦ã„るプリセットåや,
+ \ref{sssec:ltjpreset-general}ã§å®šç¾©ã•ã‚Œã¦ã„るオプション,ã•ã‚‰ã«
+ 次ã®9ã¤ã¨é‡è¤‡ã—ã¦ã¯ãªã‚‰ãªã„.
+ \begin{quote}
+ \ttfamily
+ mc mc-l mc-m mc-bx gt gt-m gt-bx gt-eb mg-m
+ \end{quote}
+
+ <specification>ã¯ï¼Œãƒ—リセットåや以下ã®ã‚­ãƒ¼é”ã®ã‚³ãƒ³ãƒžåŒºåˆ‡ã‚Šãƒªã‚¹ãƒˆã‚’指定ã™ã‚‹ï¼š
+ \begin{description}
+ \item[\ttfamily mc-l=<font>] 明æœä½“ç´°å­—(\cs{mcfamily}\cs{ltseries})
+ \item[\ttfamily mc-m=<font>] 明æœä½“中字(\cs{mcfamily}\cs{mdseries})
+ \item[\ttfamily mc-bx=<font>] 明æœä½“太字(\cs{mcfamily}\cs{bfseries})
+ \item[\ttfamily gt-m=<font>] ゴシック体中字(\cs{gtfamily}\cs{mdseries})
+ \item[\ttfamily gt-bx=<font>] ゴシック体太字(\cs{gtfamily}\cs{bfseries})
+ \item[\ttfamily gt-eb=<font>] ゴシック体太字(\cs{gtfamily}\cs{ebseries})
+ \item[\ttfamily mg-m=<font>] 丸ゴシック体(\cs{mgfamily})
+ \item[\ttfamily mc=<font>] 明æœä½“ã®ç´°å­—・中字・太字全部を設定.
+ 以下を指定ã—ãŸã“ã¨ã¨åŒã˜ã§ã‚る:
+ \begin{quote}
+ \ttfamily mc-l=<font>, mc-m=<font>, mc-bx=<font>
+ \end{quote}
+ \item[\ttfamily gt=<font>] ゴシック体ã®ä¸­å­—・太字・極太全部を設定.
+ 以下を指定ã—ãŸã“ã¨ã¨åŒã˜ã§ã‚る:
+ \begin{quote}
+ \ttfamily gt-m=<font>, gt-bx=<font>, gt-eb=<font>
+ \end{quote}
+ \end{description}
+ ãªãŠï¼Œãƒ‘ッケージ読ã¿è¾¼ã¿æ™‚ã« \texttt{deluxe} ãŒæœ‰åŠ¹ã§ãªã„å ´åˆã¯ï¼Œ
+ 上記9キーã®ã†ã¡\texttt{mc}, \texttt{gt}ã—ã‹å®Ÿè³ªçš„ã«æ„味をæŒãŸãªã„.
+%</ja>
+%<*en>
+ Define new preset~<name>. This <name> cannot be same as other presets,
+ options described in Subsubsection~\ref{sssec:ltjpreset-general}, nor
+ following nine strings:
+ \begin{quote}
+ \ttfamily
+ mc mc-l mc-m mc-bx gt gt-m gt-bx gt-eb mg-m
+ \end{quote}
+
+ <specification> is a comma-separated list which consists of
+ other presets and/or the following keys:
+ \begin{description}
+ \item[\ttfamily mc-l=<font>] mincho light
+ \item[\ttfamily mc-m=<font>] mincho medium
+ \item[\ttfamily mc-bx=<font>] mincho bold
+ \item[\ttfamily gt-m=<font>] gothic medium
+ \item[\ttfamily gt-bx=<font>] gothic bold
+ \item[\ttfamily gt-eb=<font>] gothic extra~bold
+ \item[\ttfamily mg-m=<font>] rounded gothic
+ \item[\ttfamily mc=<font>] Same as
+ \begin{quote}
+ \ttfamily mc-l=<font>, mc-m=<font>, mc-bx=<font>
+ \end{quote}
+ \item[\ttfamily gt=<font>] Same as
+ \begin{quote}
+ \ttfamily gt-m=<font>, gt-bx=<font>, gt-eb=<font>
+ \end{quote}
+ \end{description}
+ If \texttt{deluxe} is not specified at loading the package,
+ only \texttt{mc}~and~\texttt{gt} keys (among above 9~keys) have a meaning.
+%</en>
+ \item[\cs{ltjnewpreset}*\{<name>\}\{<specification>\}]
+%<*ja>
+ \cs{ltjnewpreset}ã¨ã»ã¼åŒã˜ã§ã‚ã‚‹ãŒï¼Œã“ã¡ã‚‰ã¯ã™ã§ã«å®šç¾©ã•ã‚Œã¦ã„るプリセットå
+ ã‚’<name>ã«æŒ‡å®šã—ãŸå ´åˆã«ã¯ã‚¨ãƒ©ãƒ¼ã‚’出ã•ãšã«å®šç¾©ã‚’ç½®ãæ›ãˆã‚‹ï¼Ž
+%</ja>
+%<*en>
+ Almost same as \cs{ltjnewpreset}. However, if <name> matches a preset which already defined,
+ this command simply overwrite it.
+%</en>
+ \item[\cs{ltjapplypreset}\{<name>\}]
+%<ja> <name>ã§æŒ‡å®šã•ã‚ŒãŸãƒ—リセットを使ã£ã¦å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚’設定ã™ã‚‹ï¼Ž
+%<en> Set Japanese font families using preset~<name>.
+\end{cslist}
+
+%<*ja>
+ãªãŠï¼Œ\cs{ltjnewpreset}ã®ç¬¬äºŒå¼•æ•°<specification>ã«å«ã¾ã‚Œã‚‹
+プリセットåã¯\cs{ltjnewpreset}ã®æ™‚点ã§å®šç¾©ã•ã‚Œã¦ã„ã‚‹å¿…è¦ã¯ãªã,
+\cs{ltjapplypreset}ã§å®Ÿéš›ã«ä½¿ã†ã¨ãã«å®šç¾©ã•ã‚Œã¦ã„ã‚Œã°è‰¯ã„.
+ãã®ãŸã‚,次ã®ã‚ˆã†ãªè¨˜è¿°ã‚‚å¯èƒ½ã§ã‚る:
+\begin{lstlisting}
+ \ltjnewpreset{hoge}{piyo,mc-bx=HiraMinProN-W6}
+ \ltjnewpreset{piyo}{mg-m=HiraMaruProN-W4}
+ \ltjapplypreset{hoge}
+\end{lstlisting}
+
+\paragraph{注æ„}
+\cs{ltjnewpreset}ã§å®šç¾©ã—ãŸãƒ—リセットã«ã¯ä»¥ä¸‹ã®åˆ¶é™ãŒã‚る.
+\begin{itemize}
+ \item éžåŸ‹ã‚è¾¼ã¿ã®ãƒ•ã‚©ãƒ³ãƒˆã‚’指定ã™ã‚‹ã“ã¨ã¯ã§ããªã„.
+ \item \texttt{ipa-hg}ãªã©ã®ã„ãã¤ã‹ã®ãƒ—リセットã§ã¯
+ 「\texttt{90jis}, \texttt{jis2004}ãŒæŒ‡å®šã•ã‚Œã¦ã„ã‚‹ã‹å¦ã‹ã§ãƒ•ã‚©ãƒ³ãƒˆã®æŒ‡å®šã‚’変ãˆã‚‹ã€å‡¦ç†ãŒ
+ è¡Œã‚ã‚Œã¦ã„ãŸãŒï¼Œ\cs{ltjnewpreset}ã§å®šç¾©ã—ãŸãƒ—リセットã§ã¯ã“ã®å‡¦ç†ã¯åƒã‹ãªã„.
+ HGフォントやモガ明æœãªã©ã‚’使ã†ãƒ—リセットを定義ã™ã‚‹å ´åˆã«ã¯æ³¨æ„ã™ã‚‹ã“ã¨ï¼Ž
+\end{itemize}
+%</ja>
+%<*en>
+Note that \cs{ltjnewpreset} does not ``expand'' the definition to define a preset.
+This means that one can write as the following:
+\begin{lstlisting}
+ \ltjnewpreset{hoge}{piyo,mc-bx=HiraMinProN-W6}
+ \ltjnewpreset{piyo}{mg-m=HiraMaruProN-W4}
+ \ltjapplypreset{hoge}
+\end{lstlisting}
+
+\paragraph{Restrictions}
+Presets which are defined by \cs{ltjnewpreset} have following restrictions:
+\begin{itemize}
+ \item One cannot specify non-embedded fonts (such as Ryumin-Light).
+ \item Some presets, such as \texttt{ipa-hg}, have a feature that
+ fonts are changed according to whether \texttt{90jis}~or~\texttt{jis2004} is speified.
+ This feature is not usable in presets which are defined by \cs{ltjnewpreset}.
+\end{itemize}
+%</en>
+
+
+\clearpage
+%<en>\part{Implementations}
+%<ja>\part{実装}
+\label{part-imp}
+%<en>\section{Storing Parameters}
+%<ja>\section{パラメータã®ä¿æŒ}
+\label{sec-para}
+%<en>\subsection{Used dimensions, attributes and whatsit nodes}
+%<ja>\subsection{\LuaTeX-jaã§ç”¨ã„られるレジスタã¨whatsitノード}
+
+%<*en>
+Here the following is the list of dimensions and attributes which are used in \LuaTeX-ja.
+%</en>
+%<*ja>
+以下ã¯\LuaTeX-jaã§ç”¨ã„られる寸法レジスタ(dimension),属性レジスタ(attribute)ã®
+リストã§ã‚る.
+%</ja>
+\begin{list}{}{%
+\def\makelabel{\ttfamily}\advance\leftmargin1\zw
+\def\dim#1{\item[\textbackslash #1\ \textrm{(dimension)}]}
+\def\cnt#1{\item[\textbackslash #1\ \textrm{(counter)}]}
+\def\attr#1{\item[\textbackslash #1\ \textrm{(attribute)}]}
+}
+
+\dim{jQ}
+%<*en>
+\cs{jQ} is equal to
+ $1\,\textrm{Q}=0.25\,\textrm{mm}$, where ``Q''~(also called ``ç´š'') is
+ a unit used in Japanese phototypesetting.
+So one should not change the value of this dimension.
+%</en>
+%<*ja>
+\cs{jQ} ã¯å†™æ¤ã§ç”¨ã„られãŸ$1\,\textrm{Q}=0.25\,\textrm{mm}$%
+(「級ã€ã¨ã‚‚書ã‹ã‚Œã‚‹ï¼‰ã«ç­‰ã—ã„.ã—ãŸãŒã£ã¦ï¼Œ
+ã“ã®å¯¸æ³•ãƒ¬ã‚¸ã‚¹ã‚¿ã®å€¤ã‚’変更ã—ã¦ã¯ãªã‚‰ãªã„.
+%</ja>
+
+\dim{jH}
+%<*en>
+There is also a unit called ``æ­¯'' which equals to $0.25\,\textrm{mm}$ and
+ used in Japanese phototypesetting.
+This \cs{jH} is the same \cs{dimen} register as \cs{jQ}.
+%</en>
+%<*ja>
+åŒã˜ã写æ¤ã§ç”¨ã„られã¦ã„ãŸå˜ä½ã¨ã—ã¦ã€Œæ­¯ã€ãŒã‚り,ã“れも$0.25\,\textrm{mm}$ã¨
+ç­‰ã—ã„.ã“ã® \cs{jH} 㯠\cs{jQ} ã¨åŒã˜å¯¸æ³•ãƒ¬ã‚¸ã‚¹ã‚¿ã‚’指ã™ï¼Ž
+%</ja>
+
+\dim{ltj@zw}
+%<*en>
+A temporal register for the ``full-width'' of current Japanese font.
+The command \cs{zw} sets this register to the correct value, and
+``return'' this register itself.
+%</en>
+%<*ja>
+ç¾åœ¨ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®ã€Œå…¨è§’å¹…ã€ã‚’ä¿æŒã™ã‚‹ä¸€æ™‚レジスタ.
+\cs{zw} 命令ã¯ï¼Œã“ã®ãƒ¬ã‚¸ã‚¹ã‚¿ã‚’é©åˆ‡ãªå€¤ã«è¨­å®šã—ãŸå¾Œï¼Œ
+「ã“ã®ãƒ¬ã‚¸ã‚¹ã‚¿è‡ªä½“ã‚’è¿”ã™ã€ï¼Ž
+%</ja>
+
+\dim{ltj@zh}
+%<*en>
+A temporal register for the ``full-height'' (usually the sum of height of imaginary body and its depth) of current Japanese font.
+The command \cs{zh} sets this register to the correct value, and
+``return'' this register itself.
+%</en>
+%<*ja>
+ç¾åœ¨ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®ã€Œå…¨è§’高ã•ã€ï¼ˆé€šå¸¸ï¼Œé«˜ã•ã¨æ·±ã•ã®å’Œï¼‰ã‚’ä¿æŒã™ã‚‹ä¸€æ™‚レジスタ.
+\cs{zh} 命令ã¯ï¼Œã“ã®ãƒ¬ã‚¸ã‚¹ã‚¿ã‚’é©åˆ‡ãªå€¤ã«è¨­å®šã—ãŸå¾Œï¼Œ
+「ã“ã®ãƒ¬ã‚¸ã‚¹ã‚¿è‡ªä½“ã‚’è¿”ã™ã€ï¼Ž
+%</ja>
+
+\attr{jfam}
+%<*en>
+Current number of Japanese font family for math formulas.
+%</en>
+%<*ja>
+æ•°å¼ç”¨ã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã®ç¾åœ¨ã®ç•ªå·ï¼Ž
+%</ja>
+
+\attr{ltj@curjfnt}
+%<*en>
+If this attribute is a positive number, it stores the font number of current Japanese font for horizontal direction.
+If this attribute is negative, it means that the Japanese font for horizontal direction is
+not loaded---\LuaTeX-ja only knows its size and JFM.
+%</en>
+%<*ja>
+基本的ã«ã¯ç¾åœ¨ã®æ¨ªçµ„用和文フォントã®ãƒ•ã‚©ãƒ³ãƒˆç•ªå·ã‚’æ ¼ç´ã—ã¦ã„ã‚‹ãŒï¼Œ
+\LaTeX 下ã§ä½¿ç”¨ã™ã‚‹å ´åˆã¯ï¼ˆ$-2$以下ã®ï¼‰è² æ•°ã¨ãªã‚‹ã“ã¨ãŒã‚る.
+ è² æ•°ã®å ´åˆã¯ã€Œæ¨ªçµ„用和文フォントã¯å®Ÿéš›ã«ã¯èª­ã¿è¾¼ã¾ã‚Œã¦ãŠã‚‰ãšï¼Œãã®ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã¨JFMã ã‘ãŒ
+ \LuaTeX-jaãŒæŠŠæ¡ã—ã¦ã„ã‚‹ã€çŠ¶æ…‹ã‚’表ã™ï¼Ž
+%</ja>
+
+\attr{ltj@curtfnt}
+%<*en>
+Similar to \cs{ltj@curjfnt}, but with current Japanese font for vertical direction.
+%</en>
+%<*ja>
+縦組用和文フォントã«é–¢ã™ã‚‹\cs{ltj@curjfnt}ã¨åŒæ§˜ã®å€¤ï¼Ž
+%</ja>
+
+\attr{ltj@charclass}
+%<*en>
+The character class of a \textbf{JAchar}. This attribute is only set on a
+ \textit{glyph\_node} which contains a \textbf{JAchar}.
+%</en>
+%<*ja>
+\textbf{JAchar}ã®æ–‡å­—クラス.\textbf{JAchar}ãŒæ ¼ç´ã•ã‚ŒãŸ\textit{glyph\_node}ã§ã®ã¿ä½¿ã‚れる.
+%</ja>
+
+\attr{ltj@yablshift}
+%<*en>
+The amount of shifting the baseline of alphabetic fonts in scaled point ($2^{-16}\,\textrm{pt}$).
+%</en>
+%<*ja>
+スケールド・ãƒã‚¤ãƒ³ãƒˆ($2^{-16}\,\textrm{pt}$)ã‚’å˜ä½ã¨ã—ãŸæ¬§æ–‡ãƒ•ã‚©ãƒ³ãƒˆã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã®ç§»å‹•é‡ï¼Ž
+%</ja>
+
+\attr{ltj@ykblshift}
+%<*en>
+The amount of shifting the baseline of Japanese fonts in scaled point ($2^{-16}\,\textrm{pt}$).
+%</en>
+%<*ja>
+スケールド・ãƒã‚¤ãƒ³ãƒˆ($2^{-16}\,\textrm{pt}$)ã‚’å˜ä½ã¨ã—ãŸå’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã®ç§»å‹•é‡ï¼Ž
+%</ja>
+
+\attr{ltj@tablshift}
+\attr{ltj@tkblshift}
+
+\attr{ltj@autospc}
+%<*en>
+Whether the auto insertion of \Param{kanjiskip} is allowed at the node.
+%</en>
+%<*ja>
+ãã®ãƒŽãƒ¼ãƒ‰ã§\Param{kanjiskip}ã®è‡ªå‹•æŒ¿å…¥ãŒè¨±ã•ã‚Œã‚‹ã‹ã©ã†ã‹ï¼Ž
+%</ja>
+
+\attr{ltj@autoxspc}
+%<*en>
+Whether the auto insertion of \Param{xkanjiskip} is allowed at the node.
+%</en>
+%<*ja>
+ãã®ãƒŽãƒ¼ãƒ‰ã§\Param{xkanjiskip}ã®è‡ªå‹•æŒ¿å…¥ãŒè¨±ã•ã‚Œã‚‹ã‹ã©ã†ã‹ï¼Ž
+%</ja>
+
+\attr{ltj@icflag}
+%<*en>
+An attribute for distinguishing ``kinds'' of a node. One of the following value is
+assigned to this attribute:
+%</en>
+%<*ja>
+ノードã®ã€Œç¨®é¡žã€ã‚’区別ã™ã‚‹ãŸã‚ã®å±žæ€§ï¼Žä»¥ä¸‹ã®ã†ã¡ã®ã²ã¨ã¤ãŒå€¤ã¨ã—ã¦å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã‚‹ï¼š
+%</ja>
+\begin{description}
+\item[\textit{italic} (1)]
+%<*en>
+Kerns from italic correction (\verb+\/+), or from kerning information of a Japanese font.
+These kerns are ``ignored'' in the insertion process of \textbf{JAglue},
+unlike explicit \cs{kern}.
+%</en>
+%<*ja>
+イタリック補正(\verb+\/+)ã«ã‚ˆã‚‹ã‚«ãƒ¼ãƒ³ï¼Œ
+ã¾ãŸã¯ \Pkg{luaotfload} ã«ã‚ˆã£ã¦æŒ¿å…¥ã•ã‚ŒãŸãƒ•ã‚©ãƒ³ãƒˆã®ã‚«ãƒ¼ãƒ‹ãƒ³ã‚°æƒ…報由æ¥ã®ã‚«ãƒ¼ãƒ³ï¼Ž
+ã“れらã®ã‚«ãƒ¼ãƒ³ã¯é€šå¸¸ã® \cs{kern} ã¨ã¯ç•°ãªã‚Šï¼Œ
+\textbf{JAglue}ã®æŒ¿å…¥å‡¦ç†ã«ãŠã„ã¦ã¯é€éŽã™ã‚‹ï¼Ž
+%</ja>
+
+\item[\textit{packed} (2)]
+
+\item[\textit{kinsoku} (3)]
+%<*en>
+Penalties inserted for the word-wrapping process (\emph{kinsoku shori}) of Japanese characters.
+%</en>
+%<ja>ç¦å‰‡å‡¦ç†ã®ãŸã‚ã«æŒ¿å…¥ã•ã‚ŒãŸãƒšãƒŠãƒ«ãƒ†ã‚£ï¼Ž
+\item[\mathversion{bold}$(\textit{from\_jfm}-2)$--$(\textit{from\_jfm}+2)$~(4--8)]
+%<en>Glues/kerns from JFM.
+%<ja>JFMç”±æ¥ã®ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ï¼Ž
+\item[\textit{kanji\_skip}~(9), \textit{kanji\_skip\_jfm}~(10)]
+%<en>Glues from \Param{kanjiskip}.
+%<ja>和文間空白\Param{kanjiskip}を表ã™ã‚°ãƒ«ãƒ¼ï¼Ž
+\item[\textit{xkanji\_skip}~(11), \textit{xkanji\_skip\_jfm}~(12)]
+%<en>Glues from \Param{xkanjiskip}.
+%<ja>和欧文間空白\Param{xkanjiskip}を表ã™ã‚°ãƒ«ãƒ¼ï¼Ž
+\item[\textit{processed} (13)]
+%<en>Nodes which is already processed by \ldots.
+%<ja>\LuaTeX-ja ã®å†…部処ç†ã«ã‚ˆã£ã¦æ—¢ã«å‡¦ç†ã•ã‚ŒãŸãƒŽãƒ¼ãƒ‰ï¼Ž
+\item[\textit{ic\_processed} (14)]
+%<*en>
+Glues from an italic correction, but already processed in the insertion process of \textbf{JAglue}s.
+%</en>
+%<ja>イタリック補正ã«ç”±æ¥ã™ã‚‹ã‚°ãƒ«ãƒ¼ã§ã‚ã£ã¦ï¼Œæ—¢ã« \textbf{JAglue} 挿入処ç†ã«ã‹ã‹ã£ãŸã‚‚ã®ï¼Ž
+\item[\textit{boxbdd} (15)]
+%<en>Glues/kerns that inserted just the beginning or the ending of an hbox or a paragraph.
+%<ja>hboxã‹æ®µè½ã®æœ€åˆã‹æœ€å¾Œã«æŒ¿å…¥ã•ã‚ŒãŸã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ï¼Ž
+\end{description}
+
+%<*ja>
+ã¾ãŸï¼ŒæŒ¿å…¥å‡¦ç†ã®çµæžœã§ã‚るリストã®æœ€åˆã®ãƒŽãƒ¼ãƒ‰ã§ã¯ï¼Œ\verb+\ltj@icflag+ ã®å€¤ã«
+\textit{processed\_begin\_flag}~(128)ãŒè¿½åŠ ã•ã‚Œã‚‹ï¼Žã“ã‚Œã«ã‚ˆã£ã¦ï¼Œ\cs{unhbox} ãŒ
+連続ã—ãŸå ´åˆã§ã‚‚「ボックスã®å¢ƒç•Œã€ãŒè­˜åˆ¥ã§ãるよã†ã«ãªã£ã¦ã„る.
+%</ja>
+
+\attr{ltj@kcat\,$i$}
+%<*en>
+Where $i$~is a natural number which is less than~7.
+These 7~attributes store bit~vectors indicating which character block is regarded as a block of \textbf{JAchar}s.
+%</en>
+%<*ja>
+$i$ã¯7よりå°ã•ã„自然数.
+ã“れら7ã¤ã®å±žæ€§ãƒ¬ã‚¸ã‚¹ã‚¿ã¯ï¼Œã©ã®æ–‡å­—ブロックãŒ\textbf{JAchar}ã®ãƒ–ロックã¨ã—ã¦
+扱ã‚れるã‹ã‚’示ã™ãƒ“ットベクトルを格ç´ã™ã‚‹ï¼Ž
+%</ja>
+
+\attr{ltj@dir}
+%<*ja>
+\textit{direction}~whatsit(後述)ã«ãŠã„ã¦çµ„æ–¹å‘を示ã™ãŸã‚ã«ï¼Œã‚ã‚‹ã„ã¯\textit{dir\_box}ã®
+ 組方å‘を用ã„る.\textit{direction}~whatsitã«ãŠã„ã¦ã¯å€¤ã¯
+\begin{quote}
+ \textit{dir\_dtou} (1), \textit{dir\_tate} (3),
+ \textit{dir\_yoko} (4), \textit{dir\_utod} (11)
+\end{quote}
+ã®ã„ãšã‚Œã‹ã§ã‚り,\textit{dir\_box}ã§ã¯ã“れらã«æ¬¡ã‚’加ãˆãŸå€¤ã‚’ã¨ã‚‹ï¼ˆ\ref{sec-dir-imp}ç« å‚照).
+%</ja>
+\begin{description}
+\item[\textit{dir\_node\_auto} (128)]
+%<ja> ç•°ãªã‚‹çµ„æ–¹å‘ã«é…ç½®ã™ã‚‹ãŸã‚ã«è‡ªå‹•çš„ã«ä½œã‚‰ã‚ŒãŸãƒœãƒƒã‚¯ã‚¹ï¼Ž
+\item[\textit{dir\_node\_manual} (256)]
+%<ja> \cs{ltjsetwd} ã«ã‚ˆã£ã¦ã€Œãƒœãƒƒã‚¯ã‚¹ã®æœ¬æ¥ã®çµ„æ–¹å‘ã¨ã¯ç•°ãªã‚‹çµ„æ–¹å‘ã§ã®å¯¸æ³•ã€ã‚’
+%<ja> 設定ã—ãŸã¨ãã«ï¼Œãれを記録ã™ã‚‹ãŸã‚ã®ãƒœãƒƒã‚¯ã‚¹ï¼Ž
+\end{description}
+%<ja> \TeX å´ã‹ã‚‰è¦‹ãˆã‚‹å€¤ï¼Œã¤ã¾ã‚Š \verb+\the\ltj@dir+ ã®å€¤ã¯å¸¸ã«0ã§ã‚る.
+
+\cnt{ltjlineendcomment}
+%<*ja>
+ \LuaTeX-jaã¯\textbf{JAchar}ã§å…¥åŠ›è¡ŒãŒçµ‚了ã—ãŸå ´åˆï¼Œãã®ç›´å¾Œã«ã‚³ãƒ¡ãƒ³ãƒˆæ–‡å­—ã‚’
+ ãŠãã“ã¨ã§ä½™è¨ˆãªç©ºç™½ãŒæŒ¿å…¥ã•ã‚Œã‚‹ã“ã¨ã‚’防ã„ã§ã„る.
+ \cs{ltjlineendcomment}ã¯ãã®éš›ã®ã‚³ãƒ¡ãƒ³ãƒˆæ–‡å­—ã®Unicodeã«ãŠã‘る符å·ä½ç½®ã‚’指定ã™ã‚‹
+ (詳細ã¯\ref{ssec:lineend}節をå‚照).
+
+ \LuaTeX-jaã«ãŠã‘る既定値ã¯$\texttt{"FFFFF}=1048575$ã§ã‚り,
+ ユーザã¯å†…部動作を熟知ã—ã¦ã„ãªã„é™ã‚Šã“ã®ã‚«ã‚¦ãƒ³ã‚¿ã®å€¤ã‚’変更ã—ã¦ã¯ãªã‚‰ãªã„.
+ \cs{ltjlineendcomment}ã®å€¤ãŒUnicodeã®ç¯„囲外(負や,$\texttt{"10FFFF}=1114111$を超ãˆãŸå ´åˆï¼‰
+ ã«ãã‚‹ã“ã¨ã¯æƒ³å®šã•ã‚Œã¦ã„ãªã„.
+%</ja>
+\end{list}
+
+%<*en>
+Furthermore, \LuaTeX-ja uses several user-defined whatsit nodes for
+internal processing. All those nodes except \emph{direction} whatsits
+store a natural number (hence its \texttt{type} is 100).
+\emph{direction} whatsits store a node list, hence its \texttt{type} is 110.
+Their \texttt{user\_id} (used for distinguish user-defined whatsits)
+are allocated by \texttt{luatexbase.newuserwhatsitid}.
+%</en>
+%<*ja>
+ã•ã‚‰ã«ï¼Œ\LuaTeX-jaã¯ã„ãã¤ã‹ã®user-defined whatsit nodeを内部処ç†ã«ç”¨ã„る.
+\textit{direction} whatsitã¯ãƒŽãƒ¼ãƒ‰ãƒªã‚¹ãƒˆã‚’æ ¼ç´ã™ã‚‹ãŒï¼Œ
+ãれ以外ã®whatsitノード㮠\texttt{type} ã¯100ã§ã‚り,ノードã¯è‡ªç„¶æ•°ã‚’æ ¼ç´ã—ã¦ã„る.
+user-defined whatsitを識別ã™ã‚‹ãŸã‚ã® \texttt{user\_id} ã¯\
+\texttt{luatexbase.newuserwhatsitid} ã«ã‚ˆã‚Šç¢ºä¿ã•ã‚Œã¦ãŠã‚Šï¼Œ
+下ã®è¦‹å‡ºã—ã¯å˜ãªã‚‹è­˜åˆ¥ç”¨ã§ã—ã‹ãªã„.
+%</ja>
+\begin{description}
+\item[\textit{inhibitglue}]
+%<*en>
+Nodes for indicating that \cs{inhibitglue} is
+ specified. The \texttt{value} field of these nodes doesn't matter.
+%</en>
+%<*ja>
+\cs{inhibitglue} ãŒæŒ‡å®šã•ã‚ŒãŸã“ã¨ã‚’示ã™ãƒŽãƒ¼ãƒ‰ï¼Žã“れらã®ãƒŽãƒ¼ãƒ‰ã®\
+\texttt{value} フィールドã¯æ„味をæŒãŸãªã„.
+%</ja>
+
+\item[\textit{stack\_marker}]
+%<*en>
+Nodes for \LuaTeX-ja's stack system (see the next
+ subsection). The \texttt{value} field of these nodes is
+ current group level.
+%</en>
+%<*ja>
+\LuaTeX-jaã®ã‚¹ã‚¿ãƒƒã‚¯ã‚·ã‚¹ãƒ†ãƒ ï¼ˆæ¬¡ã®ç¯€ã‚’å‚照)ã®ãŸã‚ã®ãƒŽãƒ¼ãƒ‰ï¼Ž
+ã“れらã®ãƒŽãƒ¼ãƒ‰ã® \texttt{value} フィールドã¯ç¾åœ¨ã®ã‚°ãƒ«ãƒ¼ãƒ—ãƒã‚¹ãƒˆãƒ¬ãƒ™ãƒ«ã‚’表ã™ï¼Ž
+%</ja>
+
+\item[\textit{char\_by\_cid}]
+%<*en>
+Nodes for \textbf{JAchar} which the callback process of
+ \Pkg{luaotfload} won't be applied, and the character code is
+ stored in the \texttt{value} field. Each node of this type are
+ converted to a \textit{glyph\_node} \emph{after}
+ the callback process of luaotfload.
+Nodes of this type is used in \cs{CID}, \cs{UTF} and IVS support.
+%</en>
+%<*ja>
+\Pkg{luaotfload}ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã«ã‚ˆã‚‹å‡¦ç†ãŒé©ç”¨ã•ã‚Œãªã„\textbf{JAchar}ã®ãŸã‚ã®ãƒŽãƒ¼ãƒ‰ã§ï¼Œ
+\texttt{value} フィールドã«æ–‡å­—コードãŒæ ¼ç´ã•ã‚Œã¦ã„る.
+ã“ã®ç¨®é¡žã®ãƒŽãƒ¼ãƒ‰ã¯ãã‚Œãžã‚ŒãŒ\Pkg{luaotfload}ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã®å‡¦ç†ã®
+\emph{後ã§}\textit{glyph\_node}ã«å¤‰æ›ã•ã‚Œã‚‹ï¼Ž
+\cs{CID}, \cs{UTF}ã‚„IVS対応処ç†ã§ã“ã®ç¨®é¡žã®ãƒŽãƒ¼ãƒ‰ãŒåˆ©ç”¨ã•ã‚Œã¦ã„る.
+%</ja>
+
+\item[\textit{replace\_vs}]
+%<*en>
+Similar to \textit{char\_by\_cid} whatsits above.
+These nodes are for \textbf{ALchar} which the callback process of
+ \Pkg{luaotfload} won't be applied.
+%</en>
+%<*ja>
+上ã®\textit{char\_by\_cid}ã¨åŒæ§˜ã«ï¼Œ
+ã“れらã®ãƒŽãƒ¼ãƒ‰ã¯\Pkg{luaotfload}ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã«ã‚ˆã‚‹å‡¦ç†ãŒé©ç”¨ã•ã‚Œãªã„\textbf{ALchar}ã®ãŸ
+ ã‚ã‚‚ã®ã§ã‚る.
+%</ja>
+
+\item[\textit{begin\_par}]
+%<*en>
+Nodes for indicating beginning of a paragraph.
+A paragraph which is started by \cs{item} in list-like environments has a horizontal box
+for its label before the actual contents. So \dots
+%</en>
+%<*ja>
+「段è½ã®é–‹å§‹ã€ã‚’æ„味ã™ã‚‹ãƒŽãƒ¼ãƒ‰ï¼Ž
+\texttt{list}環境,\texttt{itemize}環境ãªã©ã«ãŠã„ã¦ï¼Œ\cs{item} ã§å§‹ã¾ã‚‹å„é …ç›®ã¯â€¦â€¦
+%</ja>
+
+\item[\textit{direction}]
+
+\end{description}
+
+%<*en>
+These whatsits will be removed during the process of inserting \textbf{JAglue}s.
+%</en>
+%<*ja>
+ã“れらã®whatsitノードã¯\textbf{JAglue}ã®æŒ¿å…¥å‡¦ç†ã®é–“ã«å–り除ã‹ã‚Œã‚‹ï¼Ž
+%</ja>
+
+%<en>\subsection{Stack system of \LuaTeX-ja}
+%<ja>\subsection{\LuaTeX-jaã®ã‚¹ã‚¿ãƒƒã‚¯ã‚·ã‚¹ãƒ†ãƒ }
+\label{ssec:stack}
+
+%<en>\paragraph{Background}
+%<ja>\paragraph{背景}
+%<*en>
+\LuaTeX-ja has its own stack system, and most parameters of \LuaTeX-ja
+are stored in it. To clarify the reason, imagine the parameter
+\Param{kanjiskip} is stored by a skip, and consider the following
+source:
+%</en>
+%<*ja>
+\LuaTeX-jaã¯ç‹¬è‡ªã®ã‚¹ã‚¿ãƒƒã‚¯ã‚·ã‚¹ãƒ†ãƒ ã‚’æŒã¡ï¼Œ\LuaTeX-jaã®ã»ã¨ã‚“ã©ã®ãƒ‘ラメータã¯
+ã“れを用ã„ã¦ä¿æŒã•ã‚Œã¦ã„る.ãã®ç†ç”±ã‚’明らã‹ã«ã™ã‚‹ãŸã‚ã«ï¼Œ
+\Param{kanjiskip}パラメータãŒã‚¹ã‚­ãƒƒãƒ—レジスタã§ä¿æŒã•ã‚Œã¦ã„ã‚‹ã¨ã—,
+以下ã®ã‚³ãƒ¼ãƒ‰ã‚’考ãˆã¦ã¿ã‚ˆã†ï¼š
+%</ja>
+\begin{LTXexample}
+\ltjsetparameter{kanjiskip=0pt}ãµãŒãµãŒ.%
+\setbox0=\hbox{%
+ \ltjsetparameter{kanjiskip=5pt}ã»ã’ã»ã’}
+\box0.ã´ã‚ˆã´ã‚ˆ\par
+\end{LTXexample}
+
+%<*en>
+As described in Subsection~\ref{ssec:param}, the only effective value of
+\Param{kanjiskip} in an hbox is the latest value, so the value of
+\Param{kanjiskip} which applied in the entire hbox should be 5\,pt.
+However, by the implementation method of \LuaTeX, this ``5\,pt'' cannot be
+known from any callbacks. In the \texttt{tex/packaging.w}, which is a
+file in the source of \LuaTeX, there are the following codes:
+%</en>
+%<*ja>
+\ref{ssec:param}節ã§è¿°ã¹ãŸã‚ˆã†ã«ï¼Œã‚ã‚‹hboxã®ä¸­ã§åŠ¹åŠ›ã‚’æŒã¤
+\Param{kanjiskip}ã®å€¤ã¯æœ€å¾Œã«ç¾ã‚ŒãŸå€¤ã®ã¿ã§ã‚り,ã—ãŸãŒã£ã¦ãƒœãƒƒã‚¯ã‚¹å…¨ä½“ã«é©ç”¨ã•ã‚Œã‚‹
+\Param{kanjiskip}ã¯5\,ptã§ã‚ã‚‹ã¹ãã§ã‚る.ã—ã‹ã—,\LuaTeX ã®å®Ÿ
+装を観察ã™ã‚‹ã¨ï¼Œã“ã®5\,ptã¨ã„ã†é•·ã•ã¯ã©ã®ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã‹ã‚‰ã‚‚知るã“ã¨ã¯ã§ããªã„ã“ã¨ãŒã‚ã‹ã‚‹ï¼Ž
+\LuaTeX ã®ã‚½ãƒ¼ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã®1㤠\texttt{tex/packaging.w} ã®ä¸­ã«ï¼Œ
+以下ã®ã‚³ãƒ¼ãƒ‰ãŒã‚る:
+%</ja>
+\begin{lstlisting}[numbers=left,firstnumber=1226]
+void package(int c)
+{
+ scaled h; /* height of box */
+ halfword p; /* first node in a box */
+ scaled d; /* max depth */
+ int grp;
+ grp = cur_group;
+ d = box_max_depth;
+ unsave();
+ save_ptr -= 4;
+ if (cur_list.mode_field == -hmode) {
+ cur_box = filtered_hpack(cur_list.head_field,
+ cur_list.tail_field, saved_value(1),
+ saved_level(1), grp, saved_level(2));
+ subtype(cur_box) = HLIST_SUBTYPE_HBOX;
+\end{lstlisting}
+%<*en>
+Notice that \texttt{unsave()} is executed \emph{before}
+\texttt{filtered\_hpack()}, where \texttt{hpack\_filter} callback is
+executed) here. So ``5\,pt'' in the above source is orphaned at
+\texttt{unsave()}, and hence it can't be accessed from \texttt{hpack\_filter}
+callback.
+%</en>
+%<*ja>
+\texttt{unsave()} ㌠\texttt{filtered\_hpack()}(ã“れ㯠\texttt{hpack\_filter} コールãƒãƒƒã‚¯ãŒ
+実行ã•ã‚Œã‚‹ã¨ã“ã‚ã§ã‚る)ã®\emph{å‰ã«}実行ã•ã‚Œã¦ã„ã‚‹ã“ã¨ã«æ³¨æ„ã™ã‚‹ï¼Ž
+ã—ãŸãŒã£ã¦ï¼Œä¸Šè¨˜ã‚½ãƒ¼ã‚¹ä¸­ã§5\,pt㯠\texttt{unsave()} ã®ã¨ã“ã‚ã§æ¨ã¦ã‚‰ã‚Œï¼Œ
+\texttt{hpack\_filter} コールãƒãƒƒã‚¯ã‹ã‚‰ã¯ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã“ã¨ãŒã§ããªã„.
+%</ja>
+
+%<en>\paragraph{Implementation}
+%<ja>\paragraph{解決法}
+
+%<*en>
+The code of stack system is based on that in a post of Dev-luatex mailing list\footnote{%
+\texttt{[Dev-luatex] tex.currentgrouplevel}, a post at 2008/8/19 by Jonathan Sauer.}.
+%</en>
+%<*ja>
+スタックシステムã®ã‚³ãƒ¼ãƒ‰ã¯Dev-luatexメーリングリストã®ã‚る投稿\footnote{%
+\texttt{[Dev-luatex] tex.currentgrouplevel}: Jonathan Sauerã«ã‚ˆã‚‹2008/8/19ã®æŠ•ç¨¿ï¼Ž}ã‚’
+ベースã«ã—ã¦ã„る.
+%</ja>
+
+%<*en>
+These are two \TeX\ count registers for maintaining information:
+\verb+\ltj@@stack+ for the stack level, and \verb+\ltj@@group@level+ for
+the \TeX's group level when the last assignment was done. Parameters
+are stored in one big table named \texttt{charprop\_stack\_table}, where
+\texttt{charprop\_stack\_table[$i$]} stores data of stack level~$i$. If
+a new stack level is created by \cs{ltjsetparameter}, all data of the
+previous level is copied.
+%</en>
+%<*ja>
+情報をä¿æŒã™ã‚‹ãŸã‚ã«ï¼Œ2ã¤ã®\TeX ã®æ•´æ•°ãƒ¬ã‚¸ã‚¹ã‚¿ã‚’用ã„ã¦ã„る:
+\verb+\ltj@@stack+ ã«ã‚¹ã‚¿ãƒƒã‚¯ãƒ¬ãƒ™ãƒ«ï¼Œ\verb+\ltj@@group@level+ ã«æœ€å¾Œã®ä»£å…¥ãŒ
+ãªã•ã‚ŒãŸæ™‚点ã§ã®\TeX ã®ã‚°ãƒ«ãƒ¼ãƒ—レベルをä¿æŒã—ã¦ã„る.
+パラメータã¯\texttt{charprop\_stack\_table}ã¨ã„ã†åå‰ã®ã²ã¨ã¤ã®å¤§ããªãƒ†ãƒ¼ãƒ–ルã«
+æ ¼ç´ã•ã‚Œã‚‹ï¼Žã“ã“ã§ï¼Œ\texttt{charprop\_stack\_table[$i$]}ã¯ã‚¹ã‚¿ãƒƒã‚¯ãƒ¬ãƒ™ãƒ«$i$ã®
+データを格ç´ã—ã¦ã„る.もã—æ–°ã—ã„スタックレベル㌠\cs{ltjsetparameter} ã«ã‚ˆã£ã¦
+生æˆã•ã‚ŒãŸã‚‰ï¼Œå‰ã®ãƒ¬ãƒ™ãƒ«ã®å…¨ã¦ã®ãƒ‡ãƒ¼ã‚¿ãŒã‚³ãƒ”ーã•ã‚Œã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+To resolve the problem mentioned in above paragraph ``Background'', \LuaTeX-ja uses
+another trick. When the stack level is about to be increased, a whatsit
+node whose type, subtype and value are 44~(\textit{user\_defined}),
+\textit{stack\_marker} and the current group level respectively is appended to the current
+list (we refer this node by \textit{stack\_flag}). This enables us to
+know whether assignment is done just inside a hbox. Suppose that the
+stack level is~$s$ and the \TeX's group level is~$t$ just after the hbox
+group, then:
+%</en>
+%<*ja>
+上ã®ã€ŒèƒŒæ™¯ã€ã§è¿°ã¹ãŸå•é¡Œã‚’解決ã™ã‚‹ãŸã‚ã«ï¼Œ\LuaTeX-jaã§ã¯æ¬¡ã®æ‰‹æ³•ã‚’用ã„る:
+スタックレベルãŒå¢—加ã™ã‚‹ã™ã‚‹ã¨ã,type, subtype, valueãŒãã‚Œãžã‚Œ
+44~(\textit{user\_defined}), \textit{stack\_marker},ãã—ã¦ç¾åœ¨ã®ã‚°ãƒ«ãƒ¼ãƒ—レベルã§ã‚ã‚‹whatsitノード
+ã‚’ç¾åœ¨ã®ãƒªã‚¹ãƒˆã«ä»˜ã‘加ãˆã‚‹ï¼ˆã“ã®ãƒŽãƒ¼ãƒ‰ã‚’\textit{stack\_flag}ã¨ã™ã‚‹ï¼‰ï¼Ž
+ã“ã‚Œã«ã‚ˆã‚Šï¼Œã‚ã‚‹hboxã®ä¸­ã§ä»£å…¥ãŒãªã•ã‚ŒãŸã‹ã©ã†ã‹ã‚’知るã“ã¨ãŒå¯èƒ½
+ã¨ãªã‚‹ï¼Žã‚¹ã‚¿ãƒƒã‚¯ãƒ¬ãƒ™ãƒ«ã‚’$s$,ãã®hbox groupã®ç›´å¾Œã®\TeX ã®ã‚°ãƒ«ãƒ¼ãƒ—レベルを
+$t$ã¨ã™ã‚‹ã¨ï¼š
+%</ja>
+\begin{itemize}
+%<*en>
+\item If there is no \textit{stack\_flag} node in the list of the contents of the hbox, then
+ no assignment was occurred inside the hbox. Hence values of
+ parameters at the end of the hbox are stored in the stack
+ level~$s$.
+%</en>
+%<*ja>
+\item ã‚‚ã—ãã®hboxã®ä¸­èº«ã‚’表ã™ãƒªã‚¹ãƒˆã®ä¸­ã«\textit{stack\_flag}ノードãŒãªã‘ã‚Œã°ï¼Œ
+ hboxã®ä¸­ã§ã¯ä»£å…¥ã¯èµ·ã“らãªã‹ã£ãŸã¨ã„ã†ã“ã¨ã«ãªã‚‹ï¼Ž
+ ã—ãŸãŒã£ã¦ï¼Œãã®hboxã®çµ‚ã‚ã‚Šã«ãŠã‘るパラメータã®å€¤ã¯ã‚¹ã‚¿ãƒƒã‚¯ãƒ¬ãƒ™ãƒ«$s$ã«
+ æ ¼ç´ã•ã‚Œã¦ã„る.
+%</ja>
+
+%<*en>
+\item If there is a \textit{stack\_flag} node whose value is~$t+1$, then
+ an assignment was occurred just inside the hbox group. Hence
+ values of parameters at the end of the hbox are stored in the
+ stack level~$s+1$.
+%</en>
+%<*ja>
+\item ã‚‚ã—値ãŒ$t+1$ã®\textit{stack\_flag}ノードãŒã‚ã‚Œã°ï¼Œãã®
+ hboxã®ä¸­ã§ä»£å…¥ãŒèµ·ã“ã£ãŸã“ã¨ã«ãªã‚‹ï¼Ž
+ ã—ãŸãŒã£ã¦ï¼Œhboxã®çµ‚ã‚ã‚Šã«ãŠã‘るパラメータã®å€¤ã¯ã‚¹ã‚¿ãƒƒã‚¯ãƒ¬ãƒ™ãƒ«$s+1$ã«
+ æ ¼ç´ã•ã‚Œã¦ã„る.
+%</ja>
+
+%<*en>
+\item If there are \textit{stack\_flag} nodes but all of their values
+ are more than~$t+1$, then an assignment was occurred in the box,
+ but it is done in more internal group. Hence values of
+ parameters at the end of the hbox are stored in the stack
+ level~$s$.
+%</en>
+%<*ja>
+\item ã‚‚ã—\textit{stack\_flag}ノードãŒã‚ã‚‹ãŒãれらã®å€¤ãŒå…¨ã¦$t+1$より大ãã„
+ å ´åˆï¼Œãã®ãƒœãƒƒã‚¯ã‚¹ã®ä¸­ã§ä»£å…¥ãŒèµ·ã“ã£ãŸãŒï¼Œãã‚Œã¯ã€Œã‚ˆã‚Šå†…部ã®ã€ã‚°ãƒ«ãƒ¼ãƒ—ã§
+ èµ·ã“ã£ãŸã¨ã„ã†ã“ã¨ã«ãªã‚‹ï¼Žã—ãŸãŒã£ã¦ï¼Œhboxã®çµ‚ã‚ã‚Šã§ã®ãƒ‘ラメータã®
+ 値ã¯ã‚¹ã‚¿ãƒƒã‚¯ãƒ¬ãƒ™ãƒ«$s$ã«æ ¼ç´ã•ã‚Œã¦ã„る.
+%</ja>
+\end{itemize}
+
+%<*en>
+Note that to work this trick correctly, assignments to
+\verb+\ltj@@stack+ and \verb+\ltj@@group@level+ have to be local always,
+regardless the value of \cs{globaldefs}.
+To solve this problem, we use another trick: the assignment
+\hbox{\verb+\directlua{tex.globaldefs=0}+} is always local.
+%</en>
+%<*ja>
+ã“ã®ãƒˆãƒªãƒƒã‚¯ã‚’æ­£ã—ãåƒã‹ã›ã‚‹ãŸã‚ã«ã¯ï¼Œ\verb+\ltj@@stack+ 㨠\verb+\ltj@@group@level+ ã¸ã®
+代入㯠\cs{globaldefs} ã®å€¤ã«ã‚ˆã‚‰ãšå¸¸ã«ãƒ­ãƒ¼ã‚«ãƒ«ã§ãªã‘ã‚Œã°ãªã‚‰ãªã„ã“ã¨ã«æ³¨æ„ã™ã‚‹ï¼Ž
+ã“ã®å•é¡Œã¯ \hbox{\verb+\directlua{tex.globaldefs=0}+}(ã“ã®ä»£å…¥ã¯å¸¸ã«ãƒ­ãƒ¼ã‚«ãƒ«ï¼‰ã‚’
+用ã„ã‚‹ã“ã¨ã§è§£æ±ºã—ã¦ã„る.
+%</ja>
+
+%<*en>
+\subsection{Lua functions of the stack system}
+In this subsection, we will see how a user use \LuaTeX-ja's stack system to
+store some data which obeys the grouping of \TeX.
+%</en>
+%<*ja>
+\subsection{スタックシステムã§ä½¿ç”¨ã•ã‚Œã‚‹é–¢æ•°}
+本節ã§ã¯ï¼Œãƒ¦ãƒ¼ã‚¶ãŒ\LuaTeX-jaã®ã‚¹ã‚¿ãƒƒã‚¯ã‚·ã‚¹ãƒ†ãƒ ã‚’使用ã—ã¦ï¼Œ
+\TeX ã®ã‚°ãƒ«ãƒ¼ãƒ”ングã«å¾“ã†ã‚ˆã†ãª
+独自ã®ãƒ‡ãƒ¼ã‚¿ã‚’å–り扱ã†æ–¹æ³•ã‚’è¿°ã¹ã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+The following function can be used to store data into a stack:
+\begin{lstlisting}
+luatexja.stack.set_stack_table(index, <any> data)
+\end{lstlisting}
+Any values which except \texttt{nil}~and~NaN are usable as \textit{index}.
+However, a user should use only negative integers or strings as \textit{index},
+since natural numbers are used by \LuaTeX-ja itself.
+Also, whether \textit{data} is stored locally or globally
+is determined by \texttt{luatexja.isglobal}
+(stored globally if and only if \texttt{luatexja.isglobal == 'global'}).
+%</en>
+%<*ja>
+スタックã«å€¤ã‚’設定ã™ã‚‹ã«ã¯ï¼Œä»¥ä¸‹ã®Lua関数を呼ã³å‡ºã›ã°è‰¯ã„:
+\begin{lstlisting}
+luatexja.stack.set_stack_table(<any> index, <any> data)
+\end{lstlisting}
+ç›´æ„Ÿçš„ã«ã¯ï¼Œã‚¹ã‚¿ãƒƒã‚¯ãƒ†ãƒ¼ãƒ–ル中ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\textit{index}ã®å€¤ã‚’\textit{data}ã«ã™ã‚‹ï¼Œã¨ã„ã†æ„味ã§ã‚る.
+\textit{index}ã®å€¤ã¨ã—ã¦ã¯ \texttt{nil} ã¨NaN以外ã®ä»»æ„ã®å€¤ã‚’使ãˆã‚‹ãŒï¼Œ
+自然数ã¯\LuaTeX-jaãŒä½¿ç”¨ã™ã‚‹ï¼ˆå°†æ¥ã®æ‹¡å¼µç”¨ã‚‚å«ã‚€ï¼‰ã®ã§ï¼Œ
+ユーザãŒä½¿ç”¨ã™ã‚‹å ´åˆã¯è² ã®æ•´æ•°å€¤ã‹æ–‡å­—列ã®å€¤ã«ã™ã‚‹ã“ã¨ãŒæœ›ã¾ã—ã„.
+ã¾ãŸï¼Œãƒ­ãƒ¼ã‚«ãƒ«ã«è¨­å®šã•ã‚Œã‚‹ã‹ã‚°ãƒ­ãƒ¼ãƒãƒ«ã«è¨­å®šã•ã‚Œã‚‹ã‹ã¯ï¼Œ\texttt{luatexja.isglobal} ã®å€¤ã«ä¾å­˜ã™ã‚‹
+(グローãƒãƒ«ã«è¨­å®šã•ã‚Œã‚‹ã®ã¯ï¼Œ\texttt{luatexja.isglobal == 'global'} ã§ã‚ã‚‹ã¡ã‚‡ã†ã©ãã®æ™‚).
+%</ja>
+
+%<*en>
+Stored data can be obtained as the return value of
+\begin{lstlisting}
+luatexja.stack.get_stack_table(index, <any> default, <number> level)
+\end{lstlisting}
+where \textit{level} is the stack level, which is usually the value of \verb+\ltj@@stack+,
+and \textit{default} is the default value which will be returned if no values are stored
+in the stack table whose level is \textit{level}.
+%</en>
+%<*ja>
+スタックã®å€¤ã¯ï¼Œ
+\begin{lstlisting}
+luatexja.stack.get_stack_table(<any> index, <any> default, <number> level)
+\end{lstlisting}
+ã®æˆ»ã‚Šå€¤ã§å–å¾—ã§ãる.\textit{level}ã¯ã‚¹ã‚¿ãƒƒã‚¯ãƒ¬ãƒ™ãƒ«ã§ã‚り,
+通常㯠\verb+\ltj@@stack+ ã®å€¤ã‚’指定ã™ã‚‹ã“ã¨ã«ãªã‚‹ã ã‚ã†ï¼Ž
+\textit{default}ã¯ãƒ¬ãƒ™ãƒ«\textit{level}ã®ã‚¹ã‚¿ãƒƒã‚¯ã«å€¤ãŒè¨­å®šã•ã‚Œã¦ã„ãªã‹ã£ãŸå ´åˆã«
+è¿”ã™ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã§ã‚る.
+%</ja>
+
+\begin{figure}[tb]
+\begin{lstlisting}[numbers=left, firstnumber=380]
+\protected\def\ltj@setpar@global{%
+ \relax\ifnum\globaldefs>0\directlua{luatexja.isglobal='global'}%
+ \else\directlua{luatexja.isglobal=''}\fi
+}
+\protected\def\ltjsetparameter#1{%
+ \ltj@setpar@global\setkeys[ltj]{japaram}{#1}\ignorespaces}
+\protected\def\ltjglobalsetparameter#1{%
+ \relax\ifnum\globaldefs<0\directlua{luatexja.isglobal=''}%
+ \else\directlua{luatexja.isglobal='global'}\fi%
+ \setkeys[ltj]{japaram}{#1}\ignorespaces}
+\end{lstlisting}
+%<ja>\caption{パラメータ設定命令ã®å®šç¾©}
+%<en>\caption{Definiton of parameter setting commands}
+\label{fig:setpar-def}
+\end{figure}
+
+%<*en>
+\subsection{Extending Parameters}
+Keys for \cs{ltjsetparameter}~and~\cs{ltjgetparameter} can be extended,
+as in \Pkg{luatexja-adjust}.
+%</en>
+%<*ja>
+\subsection{パラメータã®æ‹¡å¼µ}
+ã“ã“ã§ã¯ï¼Œ\Pkg{luatexja-adjust}ã§è¡Œãªã£ã¦ã„るよã†ã«ï¼Œ
+\cs{ltjsetparameter},~\cs{ltjgetparameter}ã«æŒ‡å®šå¯èƒ½ãªã‚­ãƒ¼ã‚’追加ã™ã‚‹æ–¹æ³•
+ã‚’è¿°ã¹ã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+\paragraph{Setting parameters}
+\autoref{fig:setpar-def} shows the \emph{most outer} definition of
+two commands,
+\cs{ltjsetparameter} and \cs{ltjglobalsetparameter}.
+Most important part is the last \cs{setkeys},
+which is offered by the \Pkg{xkeyval} package.
+
+Hence, to add a key in \cs{ltjsetparameter}, one only have to add a key
+whose prefix is \texttt{ltj} and whose family is \texttt{japaram}, as the following.
+\begin{lstlisting}
+\define@key[ltj]{japaram}{...}{...}
+\end{lstlisting}
+
+\cs{ltjsetparameter}~and~\cs{ltjglobalsetparameter} automatically sets
+\texttt{luatexja.isglobal}. Its meaning is the following.
+\begin{align}
+ \texttt{luatexja.isglobal} =
+\begin{cases}
+ \texttt{'global'}&\text{global}\\
+ \texttt{''}&\text{local}
+\end{cases}
+\end{align}
+This is determined not only by command name
+(\cs{ltjsetparameter}~or~\cs{ltjglobalsetparameter}),
+but also by the value of \cs{globaldefs}.
+%</en>
+%<*ja>
+\paragraph{パラメータã®è¨­å®š}
+\cs{ltjsetparameter} ã¨ï¼Œ\cs{ltjglobalsetparameter} ã®å®šç¾©ã¯\autoref{fig:setpar-def}ã®
+ã®ã‚ˆã†ã«ãªã£ã¦ã„る.
+本質的ãªã®ã¯æœ€å¾Œã® \cs{setkeys} ã§ï¼Œã“ã‚Œã¯\Pkg{xkeyval}パッケージã®æä¾›ã™ã‚‹å‘½ä»¤ã§ã‚る.
+
+ã“ã®ãŸã‚,\cs{ltjsetparameter} ã«æŒ‡å®šå¯èƒ½ãªãƒ‘ラメータを追加ã™ã‚‹ã«ã¯ï¼Œ
+<prefix>ã‚’ \texttt{ltj},<family>ã‚’ \texttt{japaram} ã¨ã—ãŸã‚­ãƒ¼ã‚’
+\begin{lstlisting}
+\define@key[ltj]{japaram}{...}{...}
+\end{lstlisting}
+ã®ã‚ˆã†ã«å®šç¾©ã™ã‚Œã°è‰¯ã„ã ã‘ã§ã‚る.
+ãªãŠï¼Œãƒ‘ラメータ指定ãŒã‚°ãƒ­ãƒ¼ãƒãƒ«ã‹ãƒ­ãƒ¼ã‚«ãƒ«ã‹ã©ã†ã‹ã‚’示㙠\texttt{luatexja.isglobal} ãŒï¼Œ
+\begin{align}
+ \texttt{luatexja.isglobal} =
+\begin{cases}
+ \texttt{'global'}&\text{パラメータ設定ã¯ã‚°ãƒ­ãƒ¼ãƒãƒ«}\\
+ \texttt{''}&\text{パラメータ設定ã¯ãƒ­ãƒ¼ã‚«ãƒ«}
+\end{cases}
+\end{align}
+ã¨ã—ã¦è‡ªå‹•çš„ã«ã‚»ãƒƒãƒˆã•ã‚Œã‚‹\footnote{命令㌠\cs{ltjglobalsetparameter} ã‹ã©ã†ã‹ã ã‘ã§ã¯
+ãªã,実行時㮠\cs{globaldefs} ã®å€¤ã«ã‚‚ä¾å­˜ã—ã¦å®šã¾ã‚‹ï¼Ž}.
+%</ja>
+
+%<*en>
+\paragraph{Getting parameters}
+\cs{ltjgetparameter} is implemented by a Lua script.
+
+For parameters that do not need additional arguments, one only have to
+define a function in the table \verb+luatexja.unary_pars+.
+For example, with the following function,
+\verb+\ltjgetparameter{hoge}+ returns a \emph{string} \texttt{42}.
+\begin{lstlisting}[numbers=left]
+function luatexja.unary_pars.hoge (t)
+ return 42
+end
+\end{lstlisting}
+Here the argument of \verb+luatexja.unary_pars.hoge+ is
+the stack level of \LuaTeX-ja's stack system (see Subsection~\ref{ssec:stack}).
+
+On the other hand, for parameters that need an additional argument
+(this must be an integer), one have to define a function in
+\verb+luatexja.binary_pars+ first. For example,
+\begin{lstlisting}[numbers=left]
+function luatexja.binary_pars.fuga (c, t)
+ return tostring(c) .. ', ' .. tostring(42)
+end
+\end{lstlisting}
+Here the first argument $t$ is the stack level, as before.
+The second argument $c$ is just the second argument of \cs{ltjgetparameter}.
+
+For parameters that need an additional argument, one also have to
+execute the \TeX\ code like
+\begin{lstlisting}
+\ltj@@decl@array@param{fuga}
+\end{lstlisting}
+to indicate that ``the parameter \texttt{fuga} needs an additional argument''.
+%</en>
+%<*ja>
+\paragraph{パラメータã®å–å¾—}
+一方,\cs{ltjgetparameter} ã¯Luaスクリプトã«ã‚ˆã£ã¦å®Ÿè£…ã•ã‚Œã¦ã„る.
+値をå–å¾—ã™ã‚‹ã®ã«è¿½åŠ å¼•æ•°ã®è¦ã‚‰ãªã„パラメータã«ã¤ã„ã¦ã¯ï¼Œ\verb+luatexja.unary_pars+\
+内ã«å‡¦ç†å†…容を記述ã—ãŸé–¢æ•°ã‚’定義ã™ã‚Œã°è‰¯ã„.例ãˆã°ï¼ŒLuaスクリプトã§
+\begin{lstlisting}[numbers=left]
+function luatexja.unary_pars.hoge (t)
+ return 42
+end
+\end{lstlisting}
+を実行ã™ã‚‹ã¨ï¼Œ\verb+\ltjgetparameter{hoge}+ 㯠\texttt{42} ã¨ã„ã†\emph{文字列}ã‚’è¿”ã™ï¼Ž
+関数 \verb+luatexja.unary_pars.hoge+ ã®å¼•æ•°$t$ã¯ï¼Œ\ref{ssec:stack}節ã§è¿°ã¹ãŸ
+\LuaTeX-jaã®ã‚¹ã‚¿ãƒƒã‚¯ã‚·ã‚¹ãƒ†ãƒ ã«ãŠã‘るスタックレベルã§ã‚る.
+戻り値ã¯ã„ã‹ãªã‚‹å€¤ã§ã‚ã£ã¦ã‚‚,最終的ã«ã¯æ–‡å­—列ã¨ã—ã¦å‡ºåŠ›ã•ã‚Œã‚‹ã“ã¨ã«æ³¨æ„.
+
+一方,追加引数(\emph{数値ã—ã‹è¨±å®¹ã—ãªã„})ãŒå¿…è¦ãªãƒ‘ラメータã«ã¤ã„ã¦ã¯ï¼Œ
+ã¾ãšLuaスクリプトã§å‡¦ç†å†…容ã®æœ¬ä½“を記述ã—ã¦ãŠã:
+\begin{lstlisting}[numbers=left]
+function luatexja.binary_pars.fuga (c, t)
+ return tostring(c) .. ', ' .. tostring(42)
+end
+\end{lstlisting}
+引数$t$ã¯ï¼Œå…ˆã«è¿°ã¹ãŸé€šã‚Šã®ã‚¹ã‚¿ãƒƒã‚¯ãƒ¬ãƒ™ãƒ«ã§ã‚る.一方,引数$c$ã¯\
+\cs{ltjgetparameter} ã®ç¬¬2引数を表ã™æ•°å€¤ã§ã‚る.
+ã—ã‹ã—ã“ã‚Œã ã‘ã§ã¯é§„ç›®ã§ï¼Œ
+\begin{lstlisting}
+\ltj@@decl@array@param{fuga}
+\end{lstlisting}
+を実行ã—,\TeX インターフェースå´ã«
+「\verb+\ltjgetparameter{fuga}+ ã¯è¿½åŠ å¼•æ•°ãŒå¿…è¦ã€ã¨ã„ã†ã“ã¨ã‚’通知ã™ã‚‹å¿…è¦ãŒã‚る.
+%</ja>
+
+%<en>\section{Linebreak after a Japanese Character}
+%<ja>\section{和文文字直後ã®æ”¹è¡Œ}
+\label{sec-lbreak}
+%<en>\subsection{Reference: behavior in \pTeX}
+%<ja>\subsection{å‚考:\pTeX ã®å‹•ä½œ}
+%<*en>
+In~\pTeX, a line break after a Japanese character doesn't emit a space,
+since words are not separated by spaces in Japanese writings. However,
+this feature isn't fully implemented in \LuaTeX-ja due to the
+specification of callbacks in~\LuaTeX. To clarify the difference between
+\pTeX~and~\LuaTeX, We briefly describe the handling of a line break in~\pTeX, in
+this subsection.
+
+\pTeX's input processor can be described in terms of a finite state
+automaton, as that of~\TeX\ in~Section~2.5 of~\cite{texbytopic}. The
+internal states are as follows:
+\begin{itemize}
+\item State~$N$: new line
+\item State~$S$: skipping spaces
+\item State~$M$: middle of line
+\item State~$K$: after a Japanese character
+\end{itemize}
+The first three states---$N$,~$S$, and~$M$---are as same as \TeX's input
+processor. State~$K$ is similar to state~$M$, and is entered after
+Japanese characters. The diagram of state transitions are indicated in
+\autoref{fig:ptexipro}. Note that \pTeX\ doesn't leave state~$K$
+after ``beginning/ending of a group'' characters.
+%</en>
+
+%<*ja>
+欧文ã§ã¯æ–‡ç« ã®æ”¹è¡Œã¯å˜èªžé–“ã§ã—ã‹è¡Œã‚ãªã„.ãã®ãŸã‚,\TeX ã§ã¯ï¼Œï¼ˆæ–‡å­—ã®ç›´å¾Œã®ï¼‰æ”¹è¡Œã¯
+空白文字ã¨åŒã˜æ‰±ã„ã¨ã—ã¦æ‰±ã‚れる.一方,和文ã§ã¯ã»ã¨ã‚“ã©ã©ã“ã§ã‚‚改行ãŒå¯èƒ½ãªãŸã‚,
+\pTeX ã§ã¯å’Œæ–‡æ–‡å­—ã®ç›´å¾Œã®æ”¹è¡Œã¯å˜ç´”ã«ç„¡è¦–ã•ã‚Œã‚‹ã‚ˆã†ã«ãªã£ã¦ã„る.
+
+ã“ã®ã‚ˆã†ãªå‹•ä½œã¯ï¼Œ\pTeX ãŒ\TeX ã‹ã‚‰ã‚¨ãƒ³ã‚¸ãƒ³ã¨ã—ã¦æ‹¡å¼µã•ã‚ŒãŸã“ã¨ã«ã‚ˆã£ã¦å¯èƒ½ã«ãªã£ãŸã“ã¨ã§ã‚る.
+\pTeX ã®å…¥åŠ›å‡¦ç†éƒ¨ã¯ï¼Œ\TeX ã«ãŠã‘ã‚‹ãã‚Œã¨åŒã˜ã‚ˆã†ã«ï¼Œæœ‰é™ã‚ªãƒ¼ãƒˆãƒžãƒˆãƒ³ã¨ã—ã¦è¨˜è¿°ã™ã‚‹ã“ã¨ãŒã§ã,
+以下ã«è¿°ã¹ã‚‹ã‚ˆã†ãª4状態をæŒã£ã¦ã„る.
+
+\begin{itemize}
+\item State~$N$: è¡Œã®é–‹å§‹ï¼Ž
+\item State~$S$: 空白読ã¿é£›ã°ã—.
+\item State~$M$: 行中.
+\item State~$K$: 行中(和文文字ã®å¾Œï¼‰ï¼Ž
+\end{itemize}
+ã¾ãŸï¼ŒçŠ¶æ…‹é·ç§»ã¯ï¼Œ\autoref{fig:ptexipro}ã®ã‚ˆã†ã«ãªã£ã¦ãŠã‚Šï¼Œå›³ä¸­ã®æ•°å­—ã¯
+カテゴリーコードを表ã—ã¦ã„る.最åˆã®3状態ã¯\TeX ã®å…¥åŠ›å‡¦ç†éƒ¨ã¨åŒã˜ã§ã‚り,
+図中ã‹ã‚‰çŠ¶æ…‹$K$ã¨ã€Œ$j$ã€ã¨æ›¸ã‹ã‚ŒãŸçŸ¢å°ã‚’å–り除ã‘ã°ï¼Œ\TeX ã®å…¥åŠ›å‡¦ç†éƒ¨ã¨åŒ
+ã˜ã‚‚ã®ã«ãªã‚‹ï¼Ž
+
+ã“ã®å›³ã‹ã‚‰åˆ†ã‹ã‚‹ã“ã¨ã¯ï¼Œ
+\begin{quote}
+è¡ŒãŒå’Œæ–‡æ–‡å­—(ã¨ã‚°ãƒ«ãƒ¼ãƒ—境界文字)ã§çµ‚ã‚ã£ã¦ã„ã‚Œã°ï¼Œæ”¹è¡Œã¯ç„¡è¦–ã•ã‚Œã‚‹
+\end{quote}
+ã¨ã„ã†ã“ã¨ã§ã‚る.
+%</ja>
+
+\begin{figure}[!tb]
+\let\sp\textvisiblespace\small
+\begin{minipage}{.6\textwidth}%
+\begin{center}
+\unitlength=6.5mm\sf\mathversion{bold}
+\begin{tikzpicture}[
+ ->, auto, shorten >=1pt
+]
+\node [shape=rectangle, font=\scriptsize] (init) at (2,7) {start};
+\node [shape=circle,draw, fill=b_cyan] (newline) at (4,7) {$N$};
+\node [shape=circle,draw, fill=b_cyan] (midline) at (4,4) {$M$};
+\node [shape=circle,draw, fill=b_cyan] (skipspc) at (8,7) {$S$};
+\node [shape=circle,draw, fill=b_pink] (kanji) at (8,4) {$K$};
+\node [shape=rectangle,draw, fill=b_green] (scanacs) at (6,8) {scan a c.s.};
+\node (endk) at (8,2.5) {} ;
+\node (endm) at (4,2.5) {} ;
+\node (ends) at (8,8.5) {} ;
+\node (endn) at (4,8.5) {} ;
+\begin{scope}[font=\scriptsize]
+\path (newline) edge [bend right] node [left]{G, O} (midline)
+ (init) edge node {} (newline)
+ (midline) edge [bend right=10] node {10} (skipspc)
+ (skipspc) edge [bend right] node [left,right=10,above=7]{G, O} (midline)
+ (skipspc) edge [loop right] node {10} (skipspc)
+ (newline) edge [loop right] node {10} (newline)
+ (scanacs) edge [bend left] node [left=3,below]{$(*)$} (skipspc)
+ (scanacs) edge [bend right] node [right=30,above=20]{$(*)$} (midline)
+ (midline) edge node {5\ [\sp]} (endm)
+ (midline) edge [loop left] node {G, O} (midline)
+ (skipspc) edge node [right] {5} (ends)
+ (newline) edge node {5 [\cs{par}]} (endn);
+\begin{scope}[red]
+\path (newline) edge [bend right] node [right=25,below=3]{J} (kanji)
+ (midline) edge node [below]{J} (kanji)
+ (kanji) edge [bend left] node {O} (midline)
+ (kanji) edge node {10} (skipspc)
+ (kanji) edge [loop right] node {G, J} (kanji)
+ (skipspc) edge [bend left] node {J} (kanji)
+ (kanji) edge node {5} (endk)
+;
+\end{scope}
+\end{scope}
+\end{tikzpicture}
+\end{center}
+\end{minipage}%
+\begin{minipage}{.4\textwidth}
+\begin{description}
+\item[\textsf{G}] Beginning of group (usually \verb+{+)\\
+ and ending of group (usually \verb+}+).
+\item[\textsf{J}] Japanese characters.
+\item[\textsf{5}] \textit{end-of-line} (usually \verb+^+\verb+^J+).
+\item[\textsf{10}] space (usually \sp).
+\item[\textsf{O}] other characters, whose category code is in $\{3,4,6,7,8,11,12,13\}$.
+\item[\textsf{[\sp]}, \textsf{[\cs{par}]}]
+emits a space, or~\cs{par}.
+\end{description}
+\end{minipage}
+\begin{itemize}
+\item We omitted about category codes
+9~(\textit{ignored}), 14~(\textit{comment}), and~15~(\textit{invalid})
+from the above diagram. We also ignored the input like ``\verb+^+\verb+^A+'' or ``\verb+^+\verb+^df+''.
+\item When a character whose category code is 0 (\textit{escape character}) is seen by \TeX,
+the input processor scans a control sequence (\textsf{scan a c.s.}).
+These paths are not shown in the above diagram.
+
+After that, the state is changed to State~$S$ (skipping blanks) in most cases, but
+to State~$M$ (middle of line) sometimes.
+\end{itemize}
+%<en>\caption{State transitions of \pTeX's input processor}
+%<ja>\caption{\pTeX ã®å…¥åŠ›å‡¦ç†éƒ¨ã®çŠ¶æ…‹é·ç§»}
+\label{fig:ptexipro}
+\end{figure}
+
+
+%<en>\subsection{Behavior in \LuaTeX-ja}
+%<ja>\subsection{\LuaTeX-jaã®å‹•ä½œ}
+ \label{ssec:lineend}
+%<*en>
+States in the input processor of \LuaTeX\ is the same as that of \TeX,
+and they can't be customized by any callbacks. Hence, we can only use
+\verb+process_input_buffer+ and \verb+token_filter+ callbacks for to
+suppress a space by a line break which is after Japanese characters.
+
+However, \verb+token_filter+ callback cannot be used either, since a
+character in category code 5~(\textit{end-of-line}) is converted into an space
+token \emph{in the input processor}. So we can use only the
+\verb+process_input_buffer+ callback. This means that suppressing a
+space must be done \emph{just before} an input line is read.
+
+Considering these situations, handling of an end-of-line in \LuaTeX-ja are as follows:
+\begin{quote}
+A character whose character code is \cs{ltjlineendcomment}%
+\footnote{Its default value is \texttt{"FFFFF}, so \texttt{U+FFFFF} is used.
+The category code of \texttt{U+FFFFF} is set to 14~(\textit{comment}) by
+\LuaTeX-ja.} is appended to an input line, \emph{before \LuaTeX\ actually
+process it}, if and only if the following three conditions are satisfied:
+\begin{enumerate}
+\item The category code of \cs{endlinechar}%
+\footnote{Usually, it is $\langle$\textit{return}$\rangle$
+ (whose character code is 13).} is 5~(\textit{end-of-line}).
+\item The category code of \cs{ltjlineendcomment} itself is 14~(\textit{comment}).
+\item The input line matches the following ``regular expression'':
+\[
+ (\text{any char})^*(\textbf{JAchar})
+ \bigl(\{\text{catcode}=1\}\cup\{\text{catcode}=2\}\bigr)^*
+\]
+\end{enumerate}
+\end{quote}
+
+\paragraph{Remark}
+The following example shows the major difference from the behavior of \pTeX.
+\begin{LTXexample}
+\fontspec[Ligatures=TeX]{Linux Libertine O}
+\ltjsetparameter{autoxspacing=false}
+\ltjsetparameter{jacharrange={-6}}xã‚
+y\ltjsetparameter{jacharrange={+6}}zã„
+u
+\end{LTXexample}
+It is not strange that ``ã‚'' does not printed in the above output.
+This is because \TeX\ Gyre\ Termes does not contain ``ã‚'', and because
+``ã‚'' in line~3 is considered as an \textbf{ALchar}.
+
+Note that there is no space before ``y'' in the output, but
+there is a space before ``u''. This follows from following reasons:
+\begin{itemize}
+\item When line~3 is processed by \texttt{process\_input\_buffer} callback,
+``ã‚'' is considered as an \textbf{JAchar}.
+Since line~3 ends with an \textbf{JAchar},
+the comment character (whose character code is \cs{ltjlineendcomment}) is appended to this line,
+and hence the linebreak immediately after this line is ignored.
+\item When line~4 is processed by \texttt{process\_input\_buffer} callback,
+``ã„'' is considered as an \textbf{ALchar}.
+Since line~4 ends with an \textbf{ALchar}, the linebreak immediately after this line
+emits a space.
+\end{itemize}
+%</en>
+
+%<*ja>
+\LuaTeX ã®å…¥åŠ›å‡¦ç†éƒ¨ã¯\TeX ã®ãã‚Œã¨å…¨ãåŒã˜ã§ã‚り,コールãƒãƒƒã‚¯ã«ã‚ˆã‚Šãƒ¦ãƒ¼ã‚¶ãŒ
+カスタマイズã™ã‚‹ã“ã¨ã¯ã§ããªã„.ã“ã®ãŸã‚,改行抑制ã®ç›®çš„ã§ãƒ¦ãƒ¼ã‚¶ãŒåˆ©ç”¨ã§
+ããã†ãªã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¨ã—ã¦ã¯ï¼Œ\verb+process_input_buffer+ã‚„
+\verb+token_filter+ã«é™ã‚‰ã‚Œã¦ã—ã¾ã†ï¼Žã—ã‹ã—,\TeX ã®å…¥åŠ›å‡¦ç†éƒ¨ã‚’よã見る
+ã¨ï¼Œå¾Œè€…ã‚‚å½¹ã«ã¯çµŒãŸãªã„ã“ã¨ãŒåˆ†ã‹ã‚‹ï¼šæ”¹è¡Œæ–‡å­—ã¯ï¼Œå…¥åŠ›å‡¦ç†éƒ¨ã«ã‚ˆã£ã¦ãƒˆãƒ¼
+クン化ã•ã‚Œã‚‹æ™‚ã«ï¼Œã‚«ãƒ†ã‚´ãƒªãƒ¼ã‚³ãƒ¼ãƒ‰10ã®32番文字ã¸ã¨ç½®ãæ›ãˆã‚‰ã‚Œã¦ã—ã¾ã†ãŸ
+ã‚,\verb+token_filter+ã§éžæ¨™æº–ãªãƒˆãƒ¼ã‚¯ãƒ³èª­ã¿å‡ºã—ã‚’è¡ŒãŠã†ã¨ã—ã¦ã‚‚,空白文
+å­—ç”±æ¥ã®ãƒˆãƒ¼ã‚¯ãƒ³ã¨ï¼Œæ”¹è¡Œæ–‡å­—ç”±æ¥ã®ãƒˆãƒ¼ã‚¯ãƒ³ã¯åŒºåˆ¥ã§ããªã„ã®ã ï¼Ž
+
+ã™ã‚‹ã¨ï¼Œæˆ‘々ã®ã¨ã‚Œã‚‹é“ã¯ï¼Œ\verb+process_input_buffer+を用ã„ã¦
+\LuaTeX ã®å…¥åŠ›å‡¦ç†éƒ¨ã«å¼•ã渡ã•ã‚Œã‚‹å‰ã«å…¥åŠ›æ–‡å­—列を編集ã™ã‚‹ã¨ã„ã†ã‚‚ã®ã—ã‹ãªã„.
+以上をè¸ã¾ãˆï¼Œ\LuaTeX-jaã«ãŠã‘る「和文文字直後ã®æ”¹è¡ŒæŠ‘制ã€ã®å‡¦ç†ã¯ï¼Œæ¬¡ã®ã‚ˆã†ã«ãªã£ã¦ã„る:
+
+\begin{quote}
+å„入力行ã«å¯¾ã—,\emph{ãã®å…¥åŠ›è¡ŒãŒèª­ã¾ã‚Œã‚‹å‰ã®å†…部状態ã§}
+以下ã®3æ¡ä»¶ãŒæº€ãŸã•ã‚Œã¦ã„ã‚‹å ´åˆï¼Œ\LuaTeX-jaã¯\cs{ltjlineendcomment}番ã®æ–‡å­—
+\footnote{\cs{ltjlineendcomment}ã®æ—¢å®šå€¤ã¯\texttt{"FFFFF}ã§ã‚ã‚‹ã®ã§ï¼Œ
+ 既定ã§ã¯\texttt{U+FFFFF}ãŒä½¿ã‚れるã“ã¨ã«ãªã‚‹ï¼Žã“ã®æ–‡å­—ã¯ã‚³ãƒ¡ãƒ³ãƒˆæ–‡å­—ã¨ã—ã¦æ‰±ã‚れるよã†ã«
+ \LuaTeX-ja内部ã§è¨­å®šã‚’ã—ã¦ã„る.}%
+を末尾ã«è¿½åŠ ã™ã‚‹ï¼Žã‚ˆã£ã¦ï¼Œãã®å ´åˆã«æ”¹è¡Œã¯ç©ºç™½ã¨ã¯è¦‹åšã•ã‚Œãªã„ã“ã¨ã¨ãªã‚‹ï¼Ž
+\begin{enumerate}
+\item \cs{endlinechar}ã®æ–‡å­—\footnote{普通ã¯ï¼Œæ”¹è¡Œæ–‡å­—(文字コード13番)ã§ã‚る.}
+ã®ã‚«ãƒ†ã‚´ãƒªãƒ¼ã‚³ãƒ¼ãƒ‰ãŒ5~(\textit{end-of-line})ã§ã‚る.
+\item \cs{ltjlineendcomment}ã®ã‚«ãƒ†ã‚´ãƒªãƒ¼ã‚³ãƒ¼ãƒ‰ãŒ14~(\textit{comment})ã§ã‚る.
+\item 入力行ã¯æ¬¡ã®ã€Œæ­£è¦è¡¨ç¾ã€ã«ãƒžãƒƒãƒã—ã¦ã„る:
+\[
+ (\text{any char})^*(\textbf{JAchar})
+ \bigl(\{\text{catcode}=1\}\cup\{\text{catcode}=2\}\bigr)^*
+\]
+\end{enumerate}
+\end{quote}
+
+ã“ã®ä»•æ§˜ã¯ï¼Œå‰ç¯€ã§è¿°ã¹ãŸ\pTeX ã®ä»•æ§˜ã«ã§ãã‚‹ã ã‘è¿‘ã¥ã‘ãŸã‚‚ã®ã¨ãªã£ã¦ã„る.æ¡ä»¶1.ã¯ï¼Œ
+\texttt{lstlisting}系環境ãªã©ã®æ—¥æœ¬èªžå¯¾å¿œãƒžã‚¯ãƒ­ã‚’書ã‹ãªãã¦ã™ã¾ã›ã‚‹ãŸã‚ã®ã‚‚ã®ã§ã‚る.
+
+ã—ã‹ã—ãªãŒã‚‰ï¼Œ\pTeX ã¨å®Œå…¨ã«åŒã˜æŒ™å‹•ãŒå®Ÿç¾ã§ããŸã‚ã‘ã§ã¯ãªã„.
+次ã®ã‚ˆã†ã«ï¼Œ\textbf{JAchar}ã®ç¯„囲を変更ã—ãŸã¡ã‚‡ã†ã©ãã®è¡Œã«ãŠã„ã¦ã¯æŒ™å‹•ãŒç•°ãªã‚‹ï¼š
+\begin{LTXexample}
+\fontspec[Ligatures=TeX]{TeX Gyre Termes}
+\ltjsetparameter{autoxspacing=false}
+\ltjsetparameter{jacharrange={-6}}xã‚
+y\ltjsetparameter{jacharrange={+6}}zã„
+u
+\end{LTXexample}
+上ソース中ã®ã€Œã‚ã€ã¯\textbf{ALchar}(欧文扱ã„)ã§ã‚り.
+ã“ã“ã§ä½¿ç”¨ã—ã¦ã„る欧文フォント\TeX\ Gyre Termesã¯ã€Œã‚ã€ã‚’å«ã¾ãªã„.
+よã£ã¦ï¼Œå‡ºåŠ›ã«ã€Œã‚ã€ã¯ç¾ã‚Œãªã„ã“ã¨ã¯ä¸æ€è­°ã§ã¯ãªã„.
+ãã‚Œã§ã‚‚,\pTeX ã¨ã¾ã£ãŸãåŒã˜æŒ™å‹•ã‚’示ã™ãªã‚‰ã°ï¼Œå‡ºåŠ›ã¯
+「\hbox{\ltjsetparameter{autoxspacing=false}x yzã„u}ã€ã¨ãªã‚‹ã¯ãšã§ã‚る.ã—ã‹ã—,実際ã«ã¯
+上ã®ã‚ˆã†ã«ç•°ãªã‚‹æŒ™å‹•ã¨ãªã£ã¦ã„ã‚‹ãŒï¼Œãã‚Œã¯ä»¥ä¸‹ã®ç†ç”±ã«ã‚ˆã‚‹ï¼š
+\begin{itemize}
+\item 3行目を \texttt{process\_input\_buffer} ã§å‡¦ç†ã™ã‚‹æ™‚点ã§ã¯ï¼Œ
+ 「ã‚ã€ã¯\textbf{JAchar}(和文扱ã„)ã§ã‚る.よã£ã¦3行目ã¯\textbf{JAchar}ã§çµ‚ã‚ã‚‹ã“ã¨ã«ãªã‚Šï¼Œ
+ \cs{ltjlineendcomment}番ã®ã‚³ãƒ¡ãƒ³ãƒˆæ–‡å­—ãŒè¿½åŠ ã•ã‚Œã‚‹ï¼Ž
+ よã£ã¦ï¼Œç›´å¾Œã®æ”¹è¡Œæ–‡å­—ã¯ç„¡è¦–ã•ã‚Œã‚‹ã“ã¨ã«ãªã‚Šï¼Œç©ºç™½ã¯å…¥ã‚‰ãªã„.
+\item 4行目を \texttt{process\_input\_buffer} ã§å‡¦ç†ã™ã‚‹æ™‚点ã§ã¯ï¼Œ
+ 「ã„ã€ã¯\textbf{ALchar}ã§ã‚る.よã£ã¦4行目ã¯\textbf{ALchar}ã§çµ‚ã‚ã‚‹ã“ã¨ã«ãªã‚Šï¼Œ
+ 直後ã®æ”¹è¡Œæ–‡å­—ã¯ç©ºç™½ã«ç½®ãæ›ã‚る.
+\end{itemize}
+ã“ã®ãŸã‚,トラブルをé¿ã‘ã‚‹ãŸã‚ã«ï¼Œ\textbf{JAchar}ã®ç¯„囲を\cs{ltjsetparameter}ã§ç·¨é›†ã—ãŸå ´åˆï¼Œ
+ãã®è¡Œã¯ãã“ã§æ”¹è¡Œã™ã‚‹ã‚ˆã†ã«ã—ãŸæ–¹ãŒã„ã„ã ã‚ã†ï¼Ž
+%</ja>
+
+%<*ja>
+
+%<en>\section{Insertion of JFM glues, \Param{kanjiskip} and \Param{xkanjiskip}}
+%<ja>\section{JFMグルーã®æŒ¿å…¥ï¼Œ\Param{kanjiskip}ã¨\Param{xkanjiskip}}
+\label{sec-jfmglue}
+%<en>\subsection{Overview}
+%<ja>\subsection{概è¦}
+
+\LuaTeX-jaã«ãŠã‘ã‚‹ \textbf{JAglue} ã®æŒ¿å…¥æ–¹æ³•ã¯ï¼Œ\pTeX ã®ãã‚Œã¨ã¯å…¨ãç•°ãªã‚‹ï¼Ž
+\pTeX ã§ã¯æ¬¡ã®ã‚ˆã†ãªä»•æ§˜ã§ã‚ã£ãŸï¼š
+\begin{itemize}
+\item JFMグルーã®æŒ¿å…¥ã¯ï¼Œå’Œæ–‡æ–‡å­—を表ã™ãƒˆãƒ¼ã‚¯ãƒ³ã‚’å…ƒã«æ°´å¹³ãƒªã‚¹ãƒˆã«ï¼ˆæ–‡å­—を表ã™ï¼‰<char\_node>ã‚’
+追加ã™ã‚‹éŽç¨‹ã§è¡Œã‚れる.
+\item \Param{xkanjiskip}ã®æŒ¿å…¥ã¯ï¼Œhboxã¸ã®ãƒ‘ッケージングや行分割å‰ã«è¡Œã‚れる.
+\item \Param{kanjiskip}ã¯ãƒŽãƒ¼ãƒ‰ã¨ã—ã¦ã¯æŒ¿å…¥ã•ã‚Œãªã„.パッケージングや行分割ã®è¨ˆç®—時ã«
+「和文文字を表ã™2ã¤ã®<char\_node>ã®é–“ã«ã¯\Param{kanjiskip}ãŒã‚ã‚‹ã€ã‚‚ã®ã¨ã¿ãªã•ã‚Œã‚‹ï¼Ž
+\end{itemize}
+ã—ã‹ã—,\LuaTeX-jaã§ã¯ï¼Œhboxã¸ã®ãƒ‘ッケージングや行分割å‰ã«å…¨ã¦ã®
+\textbf{JAglue},å³ã¡JFMグルー・\Param{xkanjiskip}・\Param{kanjiskip}ã®
+3種類を一度ã«æŒ¿å…¥ã™ã‚‹ã“ã¨ã«ãªã£ã¦ã„る.ã“ã‚Œã¯ï¼Œ\LuaTeX ã«ãŠã„ã¦æ¬§æ–‡ã®åˆå­—・
+カーニング処ç†ãŒãƒŽãƒ¼ãƒ‰ãƒ™ãƒ¼ã‚¹ã«ãªã£ãŸã“ã¨ã«å¯¾å¿œã™ã‚‹å¤‰æ›´ã§ã‚る.
+
+\LuaTeX-jaã«ãŠã‘ã‚‹\textbf{JAglue}挿入処ç†ã§ã¯ï¼Œæ¬¡ç¯€ã§å®šç¾©ã™ã‚‹
+「クラスタã€ã‚’å˜ä½ã«ã—ã¦è¡Œã‚れる.大雑把ã«ã„ã†ã¨ï¼Œã€Œã‚¯ãƒ©ã‚¹ã‚¿ã€ã¯æ–‡å­—ã¨ãã‚Œã«ä»˜éšã™
+るノードé”(アクセントä½ç½®è£œæ­£ç”¨ã®ã‚«ãƒ¼ãƒ³ã‚„,イタリック補正)をã¾ã¨ã‚ãŸã‚‚ã®
+ã§ã‚り,2ã¤ã®ã‚¯ãƒ©ã‚¹ã‚¿ã®é–“ã«ã¯ï¼ŒãƒšãƒŠãƒ«ãƒ†ã‚£ï¼Œ\cs{vadjust},whatsitãªã©ï¼Œè¡Œçµ„版
+ã«ã¯é–¢ä¿‚ã—ãªã„ã‚‚ã®ãŒã‚る.
+
+
+%<en>\subsection{Definition of a Cluster}
+%<ja>\subsection{「クラスタã€ã®å®šç¾©}
+
+\def\OA{$\text{\sf O}_{\text{\sf A}}$}
+\def\OB{$\text{\sf O}_{\text{\sf B}}$}
+\def\NA{$\text{\sf N}_{\text{\sf A}}$}
+\def\NB{$\text{\sf N}_{\text{\sf B}}$}
+\begin{defn}
+%<*en>
+A \emph{cluster} is consecutive nodes in one of the following forms,
+with the \textit{id} of it:
+%</en>
+%<*ja>
+\emph{クラスタ}ã¯ä»¥ä¸‹ã®å½¢ã®ã†ã¡ã®ã©ã‚Œã‹ã²ã¨ã¤ã‚’ã¨ã‚‹ãƒŽãƒ¼ãƒ‰ã®ãƒªã‚¹ãƒˆã§ã‚る:
+%</ja>
+\begin{enumerate}
+%<*en>
+\item Nodes whose value of\ \verb+\ltj@icflag+ is in $[3,15)$. These
+ nodes come from a hbox which is already packaged, by unpackaging
+ (\cs{unhbox}).
+ The \textit{id} of the cluster is \textit{id\_pbox}.
+%</en>
+%<*ja>
+\item ãã® \verb+\ltj@icflag+ ã®å€¤ãŒ$[3,15)$ã«å…¥ã‚‹ãƒŽãƒ¼ãƒ‰ã®ãƒªã‚¹ãƒˆï¼Ž
+ ã“れらã®ãƒŽãƒ¼ãƒ‰ã¯ã‚ã‚‹æ—¢ã«ãƒ‘ッケージングã•ã‚ŒãŸhboxã‹ã‚‰ \cs{unhbox} ã§
+ アンパックã•ã‚ŒãŸã‚‚ã®ã§ã‚る.
+ ã“ã®å ´åˆï¼Œã‚¯ãƒ©ã‚¹ã‚¿ã®\textit{id}ã¯\textit{id\_pbox}ã§ã‚る.
+%</ja>
+
+%<*en>
+\item A inline math formula, including two \textit{math\_node}s at the boundary of it.
+ The \textit{id} of the cluster is \textit{id\_math}.
+%</en>
+%<*ja>
+\item インライン数å¼ã§ãã®å¢ƒç•Œã«2ã¤ã®\textit{math\_node}ã‚’å«ã‚€ã‚‚ã®ï¼Ž
+ ã“ã®å ´åˆï¼Œã‚¯ãƒ©ã‚¹ã‚¿ã®\textit{id}ã¯\textit{id\_math}ã§ã‚る.
+%</ja>
+
+%<*en>
+\item A \textit{glyph\_node}~$p$, which represents a \textbf{JAchar}, with nodes which relate with it:
+%</en>
+%<*ja>
+\item \textbf{JAchar}を表ã™\textit{glyph\_node}~$p$ã¨ãã‚Œã«é–¢ä¿‚ã™ã‚‹ãƒŽãƒ¼ãƒ‰ï¼š
+%</ja>
+\begin{enumerate}
+%<*en>
+\item[(a)] A kern for the italic correction of~$p$.
+%</en>
+%<*ja>
+\item[(a)] $p$ã®ã‚¤ã‚¿ãƒªãƒƒã‚¯è£œæ­£ã®ãŸã‚ã®ã‚«ãƒ¼ãƒ³ï¼Ž
+%</ja>
+
+%<*en>
+\item[(b)] An accent attached to $p$ by \cs{accent}.
+%</en>
+%<*ja>
+\item[(b)] \cs{accent} ã«ã‚ˆã‚‹$p$ã«ä»˜éšã—ãŸã‚¢ã‚¯ã‚»ãƒ³ãƒˆï¼Ž
+%</ja>
+\end{enumerate}
+\[
+\overbrace{%
+ \Node{kern}{$\mathit{subtype}=2$}\longrightarrow
+\left\{\begin{array}{c}
+\Node{glyph}{accent}\\\noalign{\medskip}
+\Node{hbox}{accent (shifted vert.)}
+\end{array}\right\}\longrightarrow
+\Node{kern}{$\mathit{subtype}=2$}}^{\text{(b)}}
+\longrightarrow
+\Node{glyph}{$p$}\longrightarrow
+\overbrace{%
+\Node{kern}{italic corr.}}^{\text{(a)}}
+\]
+
+%<*en>
+In this case, the \textit{id} is \textit{id\_jglyph}.
+%</en>
+%<*ja>
+ã“ã®å ´åˆã®\textit{id}ã¯\textit{id\_jglyph}ã§ã‚る.
+%</ja>
+
+%<*en>
+\item A list which begins from a \textit{glyph\_node} which represents a \textbf{ALchar},
+ and consists of \textbf{ALchar} \textit{glyph\_node}s,
+ kerns for adjusting accents~(its subtype is 2), kerns for italic corrections and
+ kerns which are automatically inserted by \LuaTeX~or~luaotfload.
+ In this case, the \textit{id} is \textit{id\_glyph}.
+%</en>
+%<*ja>
+\item \textbf{ALchar}を表ã™\textit{glyph\_node},\cs{accent} ã«ã‚ˆã‚‹ã‚¢ã‚¯ã‚»ãƒ³ãƒˆä½ç½®è£œæ­£ç”¨ã®
+ カーン(subtypeãŒ2),ãã—ã¦ã‚¤ã‚¿ãƒªãƒƒã‚¯è£œæ­£ãƒ»ã‚«ãƒ¼ãƒ‹ãƒ³ã‚°ã«ã‚ˆã£ã¦æŒ¿å…¥ã•ã‚ŒãŸã‚«ãƒ¼ãƒ³é”ãŒé€£ç¶š
+ ã—ãŸã‚‚ã®ï¼Žã“ã®å ´åˆã®\textit{id}ã¯\textit{id\_glyph}ã§ã‚る.
+%</ja>
+
+%<*en>
+\item An box-like node, that is, an hbox, a vbox, a rule (\cs{vrule}) and an \textit{unset\_node}.
+The \textit{id} of the cluster is \textit{id\_hlist} if the node is an
+ hbox which is not shifted vertically, or \textit{id\_box\_like}
+ otherwise.
+%</en>
+%<*ja>
+\item 水平ボックス(hbox),垂直ボックス,罫線 (\cs{vrule}),
+ ãã—ã¦\textit{unset\_node}.
+ クラスタã®\textit{id}ã¯åž‚ç›´ã«ç§»å‹•ã—ã¦ã„ãªã„hboxãªã‚‰ã°\textit{id\_hlist},
+ ãã†ã§ãªã‘ã‚Œã°\textit{id\_box\_like}ã¨ãªã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+\item A glue, a kern whose subtype is not 2~(\textit{accent}), and a discretionary break.
+The \textit{id} of the cluster is \textit{id\_glue}, \textit{id\_kern}
+ and \textit{id\_disc}, respectively.
+%</en>
+%<*ja>
+\item グルー,subtype㌠2~(\textit{accent})ã§ã¯ãªã„カーン,ãã—ã¦discretionary break.
+ ãã®\textit{id} of the clusterã¯ãã‚Œãžã‚Œ\textit{id\_glue}, \textit{id\_kern},ãã—ã¦
+ \textit{id\_disc}ã§ã‚る.
+%</ja>
+\end{enumerate}
+%<*en>
+We use \textit{Np}, \textit{Nq} and \textit{Nr} to denote a cluster.
+%</en>
+%<*ja>
+以下ã§ã¯\textit{Np}, \textit{Nq}, \textit{Nr}ã§ã‚¯ãƒ©ã‚¹ã‚¿ã‚’表ã™ï¼Ž
+%</ja>
+\end{defn}
+
+\paragraph{\textit{id}ã®æ„味}
+$\mathit{Np}.\mathit{id}$ã®æ„味を述ã¹ã‚‹ã¨ã¨ã‚‚ã«ï¼Œ
+「先頭ã®æ–‡å­—ã€ã‚’表ã™\textit{glyph\_node}~$\mathit{Np}.\mathit{head}$ã¨ï¼Œ
+「最後ã®æ–‡å­—ã€ã‚’表ã™\textit{glyph\_node}~$\mathit{Np}.\mathit{tail}$を次ã®ã‚ˆã†ã«å®šç¾©ã™ã‚‹ï¼Ž
+ç›´æ„Ÿçš„ã«è¨€ã†ã¨ï¼Œ\textit{Np}ã¯$\mathit{Np}.\mathit{head}$ã§å§‹ã¾ã‚Š$\mathit{Np}.\mathit{tail}$ã§çµ‚ã‚るよã†ãªå˜èªžï¼Œ
+ã¨è¦‹åšã™ã“ã¨ãŒã§ãる.ã“れら$\mathit{Np}.\mathit{head}$, $\mathit{Np}.\mathit{tail}$ã¯
+説明用ã«æº–å‚™ã—ãŸæ¦‚念ã§ã‚ã£ã¦ï¼Œå®Ÿéš›ã®Luaコード中ã«ãã®ã‚ˆã†ã«æ›¸ã‹ã‚Œã¦ã„ã‚‹ã‚ã‘ã§ã¯ãªã„ã“ã¨ã«æ³¨æ„.
+
+\begin{description}
+\item[\textit{id\_jglyph}] \textbf{JAchar}(和文文字).\\
+$\mathit{Np}.\mathit{head}$, $\mathit{Np}.\mathit{tail}$ã¯ï¼Œãã®\textbf{JAchar}を表ã—ã¦ã„ã‚‹
+\textit{glyph\_node}ãã®ã‚‚ã®ã§ã‚る.
+\item[\textit{id\_glyph}] \textbf{JAchar}(和文文字)以外ã®ã‚‚ã®ã‚’表ã™\textit{glyph\_node}~$p$.\\
+多ãã®å ´åˆï¼Œ$p$ã¯\textbf{ALchar}(欧文文字)を格ç´ã—ã¦ã„ã‚‹ãŒï¼Œã€Œffiã€ãªã©ã®åˆå­—ã«ã‚ˆã£ã¦ä½œã‚‰ã‚ŒãŸ
+\textit{glyph\_node}ã§ã‚ã‚‹å¯èƒ½æ€§ã‚‚ã‚る.
+å‰è€…ã®å ´åˆï¼Œ$\mathit{Np}.\mathit{head}$,~$\mathit{Np}.\mathit{tail} = p$ã§ã‚る.
+一方,後者ã®å ´åˆï¼Œ
+\begin{itemize}
+\item $\mathit{Np}.\mathit{head}$ã¯ï¼Œ
+åˆå­—ã®æ§‹æˆè¦ç´ ã®å…ˆé ­â†’(ãã®\textit{glyph\_node}ã«ãŠã‘る)åˆå­—ã®æ§‹æˆè¦ç´ ã®å…ˆé ­â†’……
+ã¨å†å¸°çš„ã«æ¤œç´¢ã—ã¦ã„ã£ã¦ãŸã©ã‚Šç€ã„ãŸ\textit{glyph\_node}ã§ã‚る.
+\item $\mathit{Np}.\mathit{last}$ã¯ï¼ŒåŒæ§˜ã«æœ«å°¾â†’末尾→ã¨æ¤œç´¢ã—ã¦ãŸã©ã‚Šç€ã„ãŸ\textit{glyph\_node}ã§ã‚る.
+\end{itemize}
+\item[\textit{id\_math}] インライン数å¼ï¼Ž\\
+便宜的ã«ï¼Œ$\mathit{Np}.\mathit{head}$, $\mathit{Np}.\mathit{tail}$ã¨ã‚‚ã«
+「文字コード$-1$ã®æ¬§æ–‡æ–‡å­—ã€ã¨ãŠã.
+\item[\textit{id\_hlist}] 縦方å‘ã«ã‚·ãƒ•ãƒˆã•ã‚Œã¦ã„ãªã„hbox.\\
+ã“ã®å ´åˆï¼Œ$\mathit{Np}.\mathit{head}$, $\mathit{Np}.\mathit{tail}$ã¯ãã‚Œãžã‚Œ$p$ã®å†…容を表ã™ãƒªã‚¹ãƒˆã®ï¼Œ
+先頭・末尾ã®ãƒŽãƒ¼ãƒ‰ã§ã‚る.
+\medskip
+\begin{itemize}
+\item 状æ³ã«ã‚ˆã£ã¦ã¯ï¼Œ\TeX ソースã§è¨€ã†ã¨
+\begin{lstlisting}
+\hbox{\hbox{abc}...\hbox{\lower1pt\hbox{xyz}}}
+\end{lstlisting}
+ã®ã‚ˆã†ã«ï¼Œ$p$ã®å†…容ãŒåˆ¥ã®hboxã§é–‹å§‹ãƒ»çµ‚了ã—ã¦ã„ã‚‹å¯èƒ½æ€§ã‚‚å分ã‚り得る.ãã®ã‚ˆã†ãªå ´åˆï¼Œ
+$\mathit{Np}.\mathit{head}$, $\mathit{Np}.\mathit{tail}$ã®ç®—出ã¯ï¼Œ
+\emph{åž‚ç›´æ–¹å‘ã«ã‚·ãƒ•ãƒˆã•ã‚Œã¦ã„ãªã„}hboxã®
+å ´åˆã ã‘内部をå†å¸°çš„ã«æŽ¢ç´¢ã™ã‚‹ï¼Žä¾‹ãˆã°ä¸Šã®ä¾‹ã§ã¯ï¼Œ$\mathit{Np}.\mathit{head}$ã¯æ–‡å­—「aã€ã‚’表ã™ãƒŽãƒ¼ãƒ‰ã§ã‚り,
+一方$\mathit{Np}.\mathit{tail}$ã¯åž‚ç›´æ–¹å‘ã«ã‚·ãƒ•ãƒˆã•ã‚ŒãŸhbox,
+\verb+\lower1pt\hbox{xyz}+ ã«å¯¾å¿œã™ã‚‹ãƒŽãƒ¼ãƒ‰ã§ã‚る.
+\item ã¾ãŸï¼Œå…ˆé ­ã«ã‚¢ã‚¯ã‚»ãƒ³ãƒˆä»˜ãã®æ–‡å­—ãŒããŸã‚Šï¼Œæœ«å°¾ã«ã‚¤ã‚¿ãƒªãƒƒã‚¯è£œæ­£ç”¨ã®ã‚«ãƒ¼ãƒ³ãŒ
+æ¥ã‚‹ã“ã¨ã‚‚ã‚り得る.ã“ã®å ´åˆã¯ï¼Œã‚¯ãƒ©ã‚¹ã‚¿ã®å®šç¾©ã®ã¨ã“ã‚ã«ã‚‚ã‚ã£ãŸã‚ˆã†ã«ï¼Œãれらã¯ç„¡è¦–ã—ã¦ç®—出を行ã†ï¼Ž
+\item 最åˆãƒ»æœ€å¾Œã®ãƒŽãƒ¼ãƒ‰ãŒåˆå­—ã«ã‚ˆã£ã¦ä½œã‚‰ã‚ŒãŸ\textit{glyph\_node}ã®ã¨ãã¯ï¼Œãã‚Œãžã‚Œã«å¯¾ã—ã¦\textit{id\_glyph}%
+ã¨åŒæ§˜ã«å†å¸°çš„ã«æ§‹æˆè¦ç´ ã‚’ãŸã©ã£ã¦ã„ã.
+\end{itemize}
+\item[\textit{id\_pbox}] 「既ã«å‡¦ç†ã•ã‚ŒãŸã€ãƒŽãƒ¼ãƒ‰ã®ãƒªã‚¹ãƒˆã§ã‚り,ã“れらã®ãƒŽãƒ¼ãƒ‰ãŒäºŒåº¦å‡¦ç†ã‚’å—ã‘ãªã„ãŸã‚ã«
+ã¾ã¨ã‚ã¦1ã¤ã®ã‚¯ãƒ©ã‚¹ã‚¿ã¨ã—ã¦å–り扱ã†ã ã‘ã§ã‚る.
+\textit{id\_hlist}ã¨åŒã˜æ–¹æ³•ã§$\mathit{Np}.\mathit{head}$, $\mathit{Np}.\mathit{tail}$を算出ã™ã‚‹ï¼Œ
+\item[\textit{id\_disc}] discretionary break (\verb+\discretionary{pre}{post}{nobreak}+).\\
+\textit{id\_hlist}ã¨åŒã˜æ–¹æ³•ã§$\mathit{Np}.\mathit{head}$, $\mathit{Np}.\mathit{tail}$を算出ã™ã‚‹ãŒï¼Œ
+第3引数㮠\texttt{nobreak}(行分割ãŒè¡Œã‚ã‚Œãªã„時ã®å†…容)を使ã†ï¼Žè¨€ã„æ›ãˆã‚Œã°ï¼Œã“ã“ã§è¡Œåˆ†å‰²ãŒç™ºç”Ÿã—ãŸæ™‚ã®çŠ¶æ³ã¯
+å…¨ã考慮ã«å…¥ã‚Œãªã„.
+\item[\textit{id\_box\_like}] \textit{id\_hlist}ã¨ãªã‚‰ãªã„boxや,rule.\\
+ã“ã®å ´åˆã¯ï¼Œ$\mathit{Np}.\mathit{head}$, $\mathit{Np}.\mathit{tail}$ã®ãƒ‡ãƒ¼ã‚¿ã¯åˆ©ç”¨ã•ã‚Œãªã„ã®ã§ï¼Œ2ã¤ã®ç®—出ã¯ç„¡æ„味ã§ã‚る.
+æ•¢ãˆã¦æ˜Žç¤ºã™ã‚‹ãªã‚‰ã°ï¼Œ$\mathit{Np}.\mathit{head}$, $\mathit{Np}.\mathit{tail}$ã¯å…±ã«nil値ã§ã‚る.
+\item[ä»–] 以上ã«ãªã„\textit{id}ã«å¯¾ã—ã¦ã‚‚,$\mathit{Np}.\mathit{head}$, $\mathit{Np}.\mathit{tail}$ã®ç®—出ã¯ç„¡æ„味.
+\end{description}
+
+\paragraph{クラスタã®åˆ¥ã®åˆ†é¡ž}
+ã•ã‚‰ã«ï¼ŒJFMグルー挿入処ç†ã®å®Ÿéš›ã®èª¬æ˜Žã«ã‚ˆã‚Šä¾¿åˆ©ãªã‚ˆã†ã«ï¼Œ\textit{id}ã¨ã¯åˆ¥ã®ã‚¯ãƒ©ã‚¹ã‚¿ã®åˆ†é¡žã‚’è¡Œã£ã¦ãŠã.
+挿入処ç†ã§ã¯2ã¤ã®éš£ã‚Šåˆã£ãŸã‚¯ãƒ©ã‚¹ã‚¿ã®é–“ã«
+空白等ã®å®Ÿéš›ã®æŒ¿å…¥ã‚’è¡Œã†ã“ã¨ã¯å‰ã«æ›¸ã„ãŸãŒï¼Œã“ã“ã§ã®èª¬æ˜Žã§ã¯ï¼Œå•é¡Œã«ã—ã¦ã„るクラスタ\textit{Np}ã¯ã€Œå¾Œã‚å´ã€ã®ã‚¯ãƒ©ã‚¹ã‚¿ã§ã‚ã‚‹
+ã¨ã™ã‚‹ï¼Žã€Œå‰å´ã€ã®ã‚¯ãƒ©ã‚¹ã‚¿ã«ã¤ã„ã¦ã¯ï¼Œä»¥ä¸‹ã®èª¬æ˜Žã§\textit{head}ãŒ\textit{last}ã«ç½®ãæ›ã‚ã‚‹ã“ã¨ã«æ³¨æ„ã™ã‚‹ã“ã¨ï¼Ž
+\begin{description}
+\item[和文A] リスト中ã«ç›´æŽ¥å‡ºç¾ã—ã¦ã„ã‚‹\textbf{JAchar}.
+\textit{id}ãŒ\textit{id\_jglyph}ã§ã‚ã‚‹ã‹ï¼Œ\\
+\textit{id}ãŒ\textit{id\_pbox}ã§ã‚ã£ã¦$\mathit{Np}.\mathit{head}$ãŒ\textbf{JAchar}ã§ã‚ã‚‹ã¨ã.
+
+\item[和文B] リスト中ã®hboxã®ä¸­èº«ã®å…ˆé ­ã¨ã—ã¦å‡ºç¾ã—ãŸ\textbf{JAchar}.和文Aã¨ã®é•ã„ã¯ï¼Œã“ã‚Œã®å‰ã«
+JFMグルーã®æŒ¿å…¥ãŒè¡Œã‚ã‚Œãªã„(\Param{xkanjiskip},~\Param{kanjiskip}ã¯å…¥ã‚Šå¾—る)ã“ã¨ã§ã‚る.\\
+\textit{id}ãŒ\textit{id\_hlist}ã‹\textit{id\_disc}ã§ã‚ã£ã¦$\mathit{Np}.\mathit{head}$ãŒ\textbf{JAchar}ã§ã‚ã‚‹ã¨ã.
+
+\item[欧文] リスト中ã«ç›´æŽ¥ï¼hboxã®ä¸­èº«ã¨ã—ã¦å‡ºç¾ã—ã¦ã„る「\textbf{JAchar}以外ã®æ–‡å­—ã€ï¼Žæ¬¡ã®3ã¤ã®å ´åˆãŒè©²å½“:
+\begin{itemize}
+\item \textit{id}ãŒ\textit{id\_glyph}ã§ã‚る.
+\item \textit{id}ãŒ\textit{id\_math}ã§ã‚る(ã¤ã¾ã‚Šã“ã®ã‚¯ãƒ©ã‚¹ã‚¿ã¯1ã¤ã®æ–‡ä¸­æ•°å¼ã‚’ãªã™ï¼‰ï¼Ž
+\item \textit{id}ãŒ\textit{id\_pbox}ã‹\textit{id\_hlist}ã‹\textit{id\_disc}ã§ã‚ã£ã¦ï¼Œ$\mathit{Np}.\mathit{head}$ãŒ\textbf{ALchar}.
+\end{itemize}
+\item[ç®±] box,ã¾ãŸã¯ãã‚Œã«é¡žä¼¼ã™ã‚‹ã‚‚ã®ï¼Žæ¬¡ã®2ã¤ãŒè©²å½“:
+\begin{itemize}
+\item \textit{id}ãŒ\textit{id\_pbox}ã‹\textit{id\_hlist}ã‹\textit{id\_disc}ã§ã‚ã£ã¦ï¼Œ$\mathit{Np}.\mathit{head}$ãŒ\textit{glyph\_node}ã§ãªã„.
+\item \textit{id}ãŒ\textit{id\_box\_like}ã§ã‚る.
+\end{itemize}
+
+\end{description}
+
+\subsection{段è½ï¼hboxã®å…ˆé ­ã‚„末尾}
+\paragraph{先頭部ã®å‡¦ç†}
+ã¾ãšï¼Œæ®µè½ï¼hboxã®ä¸€ç•ªæœ€åˆã«ã‚るクラスタ\textit{Np}を探索ã™ã‚‹ï¼Ž
+hboxã®å ´åˆã¯ä½•ã®å•é¡Œã‚‚ãªã„ãŒï¼Œæ®µè½ã®å ´åˆã§ã¯ä»¥ä¸‹ã®ãƒŽãƒ¼ãƒ‰é”を事å‰ã«èª­ã¿é£›ã°ã—ã¦ãŠã:
+\begin{itemize}
+\item \cs{parindent} ç”±æ¥ã®hbox($\mathit{subtype}=3$)
+\item \textit{subtype}ãŒ44~(\textit{user\_defined})ã§ãªã„よã†ãªwhatsit
+\end{itemize}
+ã“ã‚Œã¯ï¼Œ\cs{parindent}ç”±æ¥ã®hboxãŒã‚¯ãƒ©ã‚¹ã‚¿ã‚’構æˆã—ãªã„よã†ã«ã™ã‚‹ãŸã‚ã§ã‚る.
+
+次ã«ï¼Œ\textit{Np}ã®ç›´å‰ã«ç©ºç™½$g$ã‚’å¿…è¦ãªã‚‰æŒ¿å…¥ã™ã‚‹ï¼š
+\begin{enumerate}
+\item ã“ã®å‡¦ç†ãŒåƒãよã†ãª\textit{Np}ã¯\textsf{和文A}ã§ã‚る.
+\item å•é¡Œã®ãƒªã‚¹ãƒˆãŒå­—下ã’ã‚ã‚Šã®æ®µè½ï¼ˆ\cs{parindent} ç”±æ¥ã®hboxã‚り)ã®å ´åˆã¯ï¼Œ
+ã“ã®ç©ºç™½$g$ã¯ã€Œæ–‡å­—コード \texttt{'parbdd'} ã®æ–‡å­—ã€ã¨\textit{Np}ã®é–“ã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ã§ã‚る.
+\item ãã†ã§ãªã„ã¨ã(\verb+noindent+ ã§é–‹å§‹ã•ã‚ŒãŸæ®µè½ã‚„hbox)ã¯ï¼Œ
+$g$ã¯ã€Œæ–‡å­—コード \texttt{'boxbdd'} ã®æ–‡å­—ã€ã¨\textit{Np}ã®é–“ã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ã§ã‚る.
+\end{enumerate}
+ãŸã ã—,もã—$g$ãŒglueã§ã‚ã£ãŸå ´åˆï¼Œã“ã®æŒ¿å…¥ã«ã‚ˆã£ã¦\textit{Np}ã«ã‚ˆã‚‹è¡Œåˆ†å‰²ãŒæ–°ãŸã«å¯èƒ½ã«ãªã‚‹ã¹ãã§ã¯ãªã„.
+ãã“ã§ï¼Œä»¥ä¸‹ã®å ´åˆã«ã¯ï¼Œ$g$ã®ç›´å‰ã« \cs{penalty10000} を挿入ã™ã‚‹ï¼š
+\begin{itemize}
+\item å•é¡Œã«ã—ã¦ã„るリストãŒæ®µè½ã§ã‚り,ã‹ã¤
+\item \textit{Np}ã®å‰ã«ã¯äºˆã‚ペナルティãŒãªã,$g$ã¯glue.
+\end{itemize}
+
+\paragraph{末尾ã®å‡¦ç†}
+末尾ã®å‡¦ç†ã¯ï¼Œå•é¡Œã®ãƒªã‚¹ãƒˆãŒæ®µè½ã®ã‚‚ã®ã‹hboxã®ã‚‚ã®ã‹ã«ã‚ˆã£ã¦ç•°ãªã‚‹ï¼Ž
+後者ã®å ´åˆã¯å®¹æ˜“ã„:最後ã®ã‚¯ãƒ©ã‚¹ã‚¿ã‚’\textit{Nq}ã¨ãŠãã¨ï¼Œ\textit{Nq}ã¨ã€Œæ–‡å­—コード\
+\texttt{'boxbdd'} ã®æ–‡å­—ã€ã®é–“ã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ã‚’,
+\textit{Nq}ã®ç›´å¾Œã«æŒ¿å…¥ã™ã‚‹ã®ã¿ã§ã‚る.
+
+一方.å‰è€…(段è½ï¼‰ã®å ´åˆã¯ï¼Œãƒªã‚¹ãƒˆã®æœ«å°¾ã¯å¸¸ã« \cs{penalty10000} ã¨ï¼Œ
+\cs{parfillskip} ç”±æ¥ã®ã‚°ãƒ«ãƒ¼ãŒå­˜åœ¨ã™ã‚‹ï¼Ž%よã£ã¦ï¼Œæœ€å¾Œã®ã‚¯ãƒ©ã‚¹ã‚¿\textit{Np}ã¯
+%ã“ã® \cs{parfillskip} ç”±æ¥ã®ã‚°ãƒ«ãƒ¼ã¨ãªã‚Šï¼Œå®Ÿè³ªçš„ãªä¸­èº«ã®æœ€å¾Œã¯ãã®1ã¤å‰ã®ã‚¯ãƒ©ã‚¹ã‚¿\textit{Nq}ã¨ãªã‚‹ï¼Ž
+段è½ã®æœ€å¾Œã®ã€Œé€šå¸¸ã®\textbf{JAchar}${}+{}$å¥ç‚¹ã€ãŒç‹¬ç«‹ã—ãŸè¡Œã¨ãªã‚‹ã®ã‚’防ããŸã‚ã«ï¼Œ
+\Param{jcharwidowpenalty}ã®å€¤ã®åˆ†ã ã‘é©åˆ‡ãªå ´æ‰€ã®ãƒšãƒŠãƒ«ãƒ†ã‚£ã‚’増やã™ï¼Ž
+
+ペナルティé‡ã‚’増やã™å ´æ‰€ã¯ï¼Œ\textit{head}ãŒ\textbf{JAchar}ã§ã‚り,
+ã‹ã¤ãã®æ–‡å­—ã®\Param{kcatcode}ãŒå¶æ•°ã§ã‚るよã†ãª
+最後ã®ã‚¯ãƒ©ã‚¹ã‚¿ã®ç›´å‰ã«ã‚ã‚‹ã‚‚ã®ãŸã¡ã§ã‚ã‚‹%
+\footnote{大雑把ã«è¨€ãˆã°ï¼Œ\Param{kcatcode}ãŒå¥‡æ•°ã§ã‚るよã†ãª\textbf{JAchar}%
+を約物ã¨ã—ã¦è€ƒãˆã¦ã„ã‚‹ã“ã¨ã«ãªã‚‹ï¼Ž
+\Param{kcatcode}ã®æœ€ä¸‹ä½ãƒ“ットã¯ã“ã®\Param{jcharwidowpenalty}用ã«ã®ã¿åˆ©ç”¨ã•ã‚Œã‚‹ï¼Ž}.
+
+\subsection{概観ã¨å…¸åž‹ä¾‹ï¼š2ã¤ã®ã€Œå’Œæ–‡Aã€ã®å ´åˆ}
+\label{ssec:cluster-wa}
+å…ˆã«è¿°ã¹ãŸã‚ˆã†ã«ï¼Œ2ã¤ã®éš£ã‚Šåˆã£ãŸã‚¯ãƒ©ã‚¹ã‚¿ï¼Œ\textit{Nq}ã¨\textit{Np}ã®é–“ã«ã¯ï¼Œ
+ペナルティ,\cs{vadjust},whatsitãªã©ï¼Œè¡Œçµ„版ã«ã¯é–¢ä¿‚ã—ãªã„ã‚‚ã®ãŒã‚る.模å¼çš„ã«è¡¨ã™ã¨ï¼Œ
+\[
+ \Node{cluster}{\textit{Nq}}\longrightarrow
+\overbrace{
+\Node{penalty}{$p$}\longrightarrow \cdots\longrightarrow \Node{whatsit}{}}^{\textrm{(a)}}
+\longrightarrow \Node{cluster}{\textit{Np}}
+\]
+ã®ã‚ˆã†ã«ãªã£ã¦ã„る.間ã®(a)ã«ç›¸å½“ã™ã‚‹éƒ¨åˆ†ã«ã¯ï¼Œä½•ã®ãƒŽãƒ¼ãƒ‰ã‚‚ãªã„å ´åˆã‚‚ã‚‚ã¡ã‚ã‚“ã‚り得る.
+ãã†ã—ã¦ï¼ŒJFMグルー挿入後ã«ã¯ï¼Œã“ã®2クラスタ間ã¯æ¬¡ã®ã‚ˆã†ã«ãªã‚‹ï¼š
+\[
+ \Node{cluster}{\textit{Nq}}\longrightarrow%\Node{kern}{左空白}\longrightarrow
+\overbrace{
+\Node{penalty}{$p+x$}\longrightarrow \cdots\longrightarrow
+\Node{whatsit}{}}^{\textrm{(a)}}\longrightarrow
+\Node{glue or kern}{\raisebox{-.2\zw}{å³ç©ºç™½}}\longrightarrow
+\Node{cluster}{\textit{Np}}
+\]
+
+以後,\emph{典型的ãªä¾‹ã¨ã—ã¦ï¼Œã‚¯ãƒ©ã‚¹ã‚¿\textit{Nq}ã¨\textit{Np}ãŒå…±ã«\textsf{\textmd{和文A}}ã§ã‚ã‚‹å ´åˆã‚’見ã¦ã„ã“ã†ï¼Œ}
+ã“ã®å ´åˆãŒå…¨ã¦ã®å ´åˆã®åŸºæœ¬ã¨ãªã‚‹ï¼Ž
+
+\paragraph{「å³ç©ºç™½ã€ã®ç®—出}
+ã¾ãšï¼Œã€Œå³ç©ºç™½ã€ã«ã‚ãŸã‚‹é‡ã‚’算出ã™ã‚‹ï¼Žé€šå¸¸ã¯ã“ã‚ŒãŒï¼Œéš£ã‚Šåˆã£ãŸ2ã¤ã®\textbf{JAchar}é–“ã«å…¥ã‚‹ç©ºç™½é‡ã¨ãªã‚‹ï¼Ž
+\begin{description}
+\item[JFMç”±æ¥{[M]}] JFMã®æ–‡å­—クラス指定ã«ã‚ˆã£ã¦å…¥ã‚‹ç©ºç™½ã‚’以下ã«ã‚ˆã£ã¦æ±‚ã‚る.ã“ã®æ®µéšŽã§ç©ºç™½é‡ãŒæœªå®šç¾©ï¼ˆæœªæŒ‡å®šï¼‰ã ã£ãŸå ´åˆï¼Œ
+ デフォルト値\Param{kanjiskip}を採用ã™ã‚‹ã“ã¨ã¨ãªã‚‹ã®ã§ï¼Œæ¬¡ã¸ï¼Ž
+\begin{enumerate}
+\item ã‚‚ã—両クラスタã®é–“㧠\cs{inhibitglue} ãŒå®Ÿè¡Œã•ã‚Œã¦ã„ãŸå ´åˆï¼ˆè¨¼ã¨ã—ã¦whatsitノードãŒè‡ªå‹•æŒ¿å…¥ã•ã‚Œã‚‹ï¼‰ï¼Œ
+ 代ã‚ã‚Šã«\Param{kanjiskip}ãŒæŒ¿å…¥ã•ã‚Œã‚‹ã“ã¨ã¨ãªã‚‹ï¼Žæ¬¡ã¸ï¼Ž
+\item \textit{Nq}ã¨\textit{Np}ãŒåŒã˜JFM・åŒã˜\texttt{jfmvar}キー・åŒã˜ã‚µã‚¤ã‚ºã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã§ã‚ã£ãŸãªã‚‰ã°ï¼Œ
+ 共通ã«ä½¿ã£ã¦ã„ã‚‹JFM内ã§æŒ¿å…¥ã•ã‚Œã‚‹ç©ºç™½ï¼ˆã‚°ãƒ«ãƒ¼ã‹ã‚«ãƒ¼ãƒ³ï¼‰ãŒæ±ºã¾ã£ã¦ã„ã‚‹ã‹èª¿ã¹ï¼Œæ±ºã¾ã£ã¦ã„ã‚Œã°ãれを採用.
+\item 1.ã§ã‚‚2.ã§ã‚‚ãªã„å ´åˆã¯ï¼ŒJFM・\texttt{jfmvar}・サイズã®3ã¤çµ„ã¯\textit{Nq}ã¨\textit{Np}ã§ç•°ãªã‚‹ï¼Ž
+ã“ã®å ´åˆï¼Œã¾ãš
+\[
+\vcenter{\halign{\hfil$#:={}$&\inhibitglue#\inhibitglue\cr
+gb&(\textit{Nq}ã¨ã€Œä½¿ç”¨ãƒ•ã‚©ãƒ³ãƒˆãŒ\textit{Nq}ã®ãã‚Œã¨åŒã˜ã§ï¼Œ\hfil\cr
+\omit&\quad 文字コードãŒ\textit{Np}ã®ãã‚Œã®æ–‡å­—ã€ã¨ã®é–“ã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³)\hfil\cr
+ga&(\inhibitglue 「使用フォントãŒ\textit{Np}ã®ãã‚Œã¨åŒã˜ã§ï¼Œ\hfil\cr
+\omit&\quad 文字コードãŒ\textit{Nq}ã®ãã‚Œã®æ–‡å­—ã€ã¨\textit{Np}ã¨ã®é–“ã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³)\hfil\cr
+}}
+\]
+ã¨ã—ã¦ï¼Œå‰å´ã®æ–‡å­—ã®JFMを使ã£ãŸæ™‚ã®ç©ºç™½ï¼ˆã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ï¼‰ã¨ï¼Œå¾Œå´ã®æ–‡å­—ã®JFMを使ã£ãŸæ™‚ã®ãれを求ã‚る.
+
+$\mathit{gb}$,~$\mathit{ga}$ãã‚Œãžã‚Œã«å¯¾ã™ã‚‹<ratio>ã®å€¤ã‚’$d_b$,~$d_a$ã¨ã™ã‚‹ï¼Ž
+\begin{itemize}
+\item
+$\mathit{ga}$ã¨$\mathit{gb}$ã®ä¸¡æ–¹ãŒæœªå®šç¾©ã§ã‚ã‚‹ãªã‚‰ã°ï¼ŒJFMç”±æ¥ã®ã‚°ãƒ«ãƒ¼ã¯æŒ¿å…¥ã•ã‚Œãšï¼Œ
+\Param{kanjiskip}を採用ã™ã‚‹ã“ã¨ã¨ãªã‚‹ï¼Ž
+ã©ã¡ã‚‰ã‹ç‰‡æ–¹ã®ã¿ãŒæœªå®šç¾©ã§ã‚ã‚‹ãªã‚‰ã°ï¼Œæ¬¡ã®ã‚¹ãƒ†ãƒƒãƒ—ã§ãã®æœªå®šç¾©ã®æ–¹ã¯é•·ã•0ã®kernã§ï¼Œ<ratio>ã®å€¤ã¯0ã§ã‚ã‚‹ã‹ã®ã‚ˆã†ã«æ‰±ã‚れる.
+\item
+\Param{diffrentjfm}ã®å€¤ãŒ \texttt{pleft}, \texttt{pright},
+ \texttt{paverage} ã®ã¨ã,
+<ratio>ã®æŒ‡å®šã«å¾“ã£ã¦æ¯”例é…分を行ã†ï¼Ž
+JFMç”±æ¥ã®ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ã¯ä»¥ä¸‹ã®å€¤ã¨ãªã‚‹ï¼š
+\[
+ f\left(\frac{1-d_b}2\textit{gb} + \frac{1+d_b}2\textit{ga},
+\frac{1-d_a}2\textit{gb} + \frac{1+d_a}2\textit{ga}\right)
+\]
+ã“ã“ã§ï¼Ž$f(x,y)$ã¯
+\[
+ f(x,y)=\begin{cases}
+x&\text{if\ }\Param{diffrentjfm}=\texttt{pleft};\\
+y&\text{if\ }\Param{diffrentjfm}=\texttt{pright};\\
+(x+y)/2&\text{if\ }\Param{diffrentjfm}=\texttt{paverage};
+\end{cases}.
+\]
+\item
+\Param{differentjfm}ãŒãれ以外ã®å€¤ã®æ™‚ã¯ï¼Œ<ratio>ã®å€¤ã¯ç„¡è¦–ã•ã‚Œï¼ŒJFMç”±æ¥ã®ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ã¯ä»¥ä¸‹ã®å€¤ã¨ãªã‚‹ï¼š
+\[
+ f(\textit{gb},\textit{ga})
+\]
+ã“ã“ã§ï¼Ž$f(x,y)$ã¯
+\[
+ f(x,y)=\begin{cases}
+\min(x,y)&\text{if\ }\Param{diffrentjfm}=\texttt{small};\\
+\max(x,y)&\text{if\ }\Param{diffrentjfm}=\texttt{large};\\
+(x+y)/2&\text{if\ }\Param{diffrentjfm}=\texttt{average};\\
+x+y&\text{if\ }\Param{diffrentjfm}=\texttt{both};
+\end{cases}.
+\]
+\end{itemize}
+\end{enumerate}
+
+例ãˆã°ï¼Œ
+\begin{lstlisting}
+\jfont\foo=psft:Ryumin-Light:jfm=ujis;-kern
+\jfont\bar=psft:GothicBBB-Medium:jfm=ujis;-kern
+\jfont\baz=psft:GothicBBB-Medium:jfm=ujis;jfmvar=piyo;-kern
+\end{lstlisting}
+ã¨ã„ã†3フォントを考ãˆï¼Œ
+\[
+ \overbrace{\Node{glyph}{\cs{ foo}, `ã‚'}}^{p}
+\longrightarrow \overbrace{\Node{glyph}{\cs{bar}, `ã„'}}^{q}
+\longrightarrow \overbrace{\Node{glyph}{\cs{baz}, `ã†'}}^{r}
+\]
+ã¨ã„ã†3ノードを考ãˆã‚‹ï¼ˆãã‚Œãžã‚Œå˜ç‹¬ã§ã‚¯ãƒ©ã‚¹ã‚¿ã‚’ãªã™ï¼‰ï¼Ž
+ã“ã®å ´åˆï¼Œ$p$ã¨$q$ã®é–“ã¯ï¼Œå®Ÿãƒ•ã‚©ãƒ³ãƒˆãŒç•°ãªã‚‹ã«ã‚‚ã‹ã‹ã‚らãš2.ã®çŠ¶æ³ã¨ãªã‚‹ä¸€æ–¹ã§ï¼Œ
+$q$ã¨$r$ã®é–“ã¯ï¼ˆå®Ÿãƒ•ã‚©ãƒ³ãƒˆãŒåŒã˜ãªã®ã«ï¼‰\texttt{jfmvar} キーã®å†…容ãŒç•°ãªã‚‹ã®ã§3.ã®çŠ¶æ³ã¨ãªã‚‹ï¼Ž
+\item[\Param{kanjiskip}~{[K]}] 上ã®[M]ã«ãŠã„ã¦ç©ºç™½ãŒå®šã¾ã‚‰ãªã‹ã£ãŸå ´åˆï¼Œ
+以下ã§å®šã‚ãŸé‡ã€Œå³ç©ºç™½ã€ã¨ã—ã¦æŽ¡ç”¨ã™ã‚‹ï¼Ž
+ã“ã®æ®µéšŽã«ãŠã„ã¦ã¯ï¼Œ\cs{inhibitglue} ã¯åŠ¹åŠ›ã‚’æŒãŸãªã„ãŸã‚,
+çµæžœã¨ã—ã¦ï¼Œ2ã¤ã®\textbf{JAchar}é–“ã«ã¯å¸¸ã«ä½•ã‚‰ã‹ã®ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ãŒæŒ¿å…¥ã•ã‚Œã‚‹ã“ã¨ã¨ãªã‚‹ï¼Ž
+\begin{enumerate}
+\item 両クラスタ(厳密ã«ã¯$\mathit{Nq}.\mathit{tail}$,$\mathit{Np}.\mathit{head}$)ã®ä¸­èº«ã®æ–‡å­—コードã«å¯¾ã™ã‚‹
+\Param{autospacing}パラメタãŒä¸¡æ–¹ã¨ã‚‚falseã ã£ãŸå ´åˆã¯ï¼Œé•·ã•0ã®glueã¨ã™ã‚‹ï¼Ž
+\item ユーザå´ã‹ã‚‰è¦‹ãŸ\Param{kanjiskip}パラメタã®è‡ªç„¶é•·ãŒ$\cs{maxdimen}=(2^{30}-1)\,{\rm sp}$ã§
+ãªã‘ã‚Œã°ï¼Œ\Param{kanjiskip}パラメタã®å€¤ã‚’æŒã¤glueを採用ã™ã‚‹ï¼Ž
+\item 2.ã§ãªã„å ´åˆã¯ï¼Œ\textit{Nq}, \textit{Np}ã§ä½¿ã‚ã‚Œã¦ã„ã‚‹JFMã«æŒ‡å®šã•ã‚Œã¦ã„ã‚‹\Param{kanjiskip}ã®å€¤ã‚’用ã„る.
+ã©ã¡ã‚‰ã‹ç‰‡æ–¹ã®ã‚¯ãƒ©ã‚¹ã‚¿ã ã‘ãŒ\textbf{JAchar}(\textsf{和文A}・\textsf{和文B})ã®ã¨ãã¯ï¼Œãã¡ã‚‰ã®ã‚¯ãƒ©ã‚¹ã‚¿ã§ä½¿ã‚ã‚Œã¦ã„ã‚‹
+JFMç”±æ¥ã®å€¤ã ã‘を用ã„る.もã—両者ã§ä½¿ã‚ã‚Œã¦ã„ã‚‹JFMãŒç•°ãªã£ãŸå ´åˆã¯ï¼Œä¸Šã®[M]~3.ã¨åŒæ§˜ã®æ–¹æ³•ã‚’用ã„ã¦èª¿æ•´ã™ã‚‹ï¼Ž
+\end{enumerate}
+\end{description}
+%\paragraph{「左空白ã€ã®ç®—出ã¨ãã‚Œã«ä¼´ã†è£œæ­£}
+%「左空白ã€ã¯éŽåŽ»ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯å®šç¾©ã—ã¦ã„ãŸãŒï¼Œã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯
+%挿入ã¯ä¸€åˆ‡è¡Œã‚ã‚Œãªã„(機能自体削除ã—ã¦ã„る).
+%ã—ã‹ã—,仕様ã¯æµå‹•çš„ã§ã‚り,将æ¥å¾©æ´»ã™ã‚‹å¯èƒ½æ€§ã‚‚ã‚ã‚‹ãŸã‚,マニュアル中ã®è¨˜è¿°ã¯ä»Šã®ã¨ã“ã‚極力変更ã—ãªã„.
+\paragraph{ç¦å‰‡ç”¨ãƒšãƒŠãƒ«ãƒ†ã‚£ã®æŒ¿å…¥}
+ã¾ãšï¼Œ
+\[
+ a:=(\text{\textit{Nq}{\footnotemark}ã®æ–‡å­—ã«å¯¾ã™ã‚‹\Param{postbreakpenalty}ã®å€¤})
++(\text{\textit{Np}{\footnotemark}ã®æ–‡å­—ã«å¯¾ã™ã‚‹\Param{prebreakpenalty}ã®å€¤})
+\]
+ã¨ãŠã\footnotetext{厳密ã«ã¯ãã‚Œãžã‚Œ$\mathit{Nq}.\mathit{tail}$,$\mathit{Np}.\mathit{head}$.}.
+ペナルティã¯é€šå¸¸$[-10000,10000]$ã®æ•´æ•°å€¤ã‚’ã¨ã‚Šï¼Œã¾ãŸ$\pm 10000$ã¯æ­£è² ã®ç„¡é™å¤§ã‚’æ„味ã™ã‚‹ã“ã¨ã«ãªã£ã¦ã„ã‚‹ãŒï¼Œã“ã®$a$ã®
+算出ã§ã¯å˜ç´”ãªæ•´æ•°ã®åŠ æ¸›ç®—ã‚’è¡Œã†ï¼Ž
+
+$a$ã¯ç¦å‰‡å‡¦ç†ç”¨ã«\textit{Nq}ã¨\textit{Np}ã®é–“ã«åŠ ãˆã‚‰ã‚Œã‚‹ã¹ãペナルティé‡ã§ã‚る.
+\begin{description}
+\item[P-normal~{[PN]}]
+\textit{Nq}ã¨\textit{Np}ã®é–“ã®(a)部分ã«ãƒšãƒŠãƒ«ãƒ†ã‚£(\textit{penalty\_node})ãŒã‚ã‚Œã°å‡¦ç†ã¯ç°¡å˜ã§ã‚る:
+ãれらã®å„ノードã«ãŠã„ã¦ï¼ŒãƒšãƒŠãƒ«ãƒ†ã‚£å€¤ã‚’($\pm 10000$ã‚’ç„¡é™å¤§ã¨ã—ã¦æ‰±ã„ã¤ã¤ï¼‰$a$ã ã‘増加ã•ã›ã‚Œã°ã‚ˆã„.
+ã¾ãŸï¼Œ$10000 + (-10000) = 0$ã¨ã—ã¦ã„る.
+
+少々困るã®ã¯ï¼Œ(a)部分ã«ãƒšãƒŠãƒ«ãƒ†ã‚£ãŒå­˜åœ¨ã—ã¦ã„ãªã„å ´åˆã§ã‚る.
+ç›´æ„Ÿçš„ã«ï¼Œè£œæ­£ã™ã¹ãé‡$a$ãŒ0ã§ãªã„ã¨ã,ãã®å€¤ã‚’ã‚‚ã¤\textit{penalty\_node}を作ã£ã¦
+「å³ç©ºç™½ã€ã®ï¼ˆã‚‚ã—未定義ãªã‚‰\textit{Np}ã®ï¼‰ç›´å‰ã«æŒ¿å…¥â€¦â€¦
+ã¨ã„ã†ã“ã¨ã«ãªã‚‹ãŒï¼Œå®Ÿéš›ã«ã¯åƒ…ã‹ã«ã“れより複雑ã§ã‚る.
+\begin{itemize}
+\item 「å³ç©ºç™½ã€ãŒã‚«ãƒ¼ãƒ³ã§ã‚ã‚‹ã¨ã,
+ãã‚Œã¯ã€Œ\textit{Nq}ã¨\textit{Np}ã®é–“ã§æ”¹è¡Œã¯è¨±ã•ã‚Œãªã„ã€ã“ã¨ã‚’æ„図ã—ã¦ã„る.ãã®ãŸã‚,
+ã“ã®å ´åˆã¯$a\neq 0$ã§ã‚ã£ã¦ã‚‚ペナルティã®æŒ¿å…¥ã¯ã—ãªã„.
+\item ãã†ã§ãªã„ãªã„ã¨ãã¯ï¼Œ$a\neq 0$ãªã‚‰ã°\textit{penalty\_node}を作ã£ã¦æŒ¿å…¥ã™ã‚‹ï¼Ž
+%\item 「左空白ã€ãŒã‚«ãƒ¼ãƒ³ã¨ã—ã¦ãã£ã¡ã‚Šå®šç¾©ã•ã‚Œã¦ã„る時(ã“ã®ã¨ã,「å³ç©ºç™½ã€ã¯ã‚«ãƒ¼ãƒ³ã§ãªã„),
+%ã“ã®ã€Œå·¦ç©ºç™½ã€ã®ç›´å¾Œã§ã®è¡Œåˆ†å‰²ã‚’許容ã—ãªã„ã¨ã„ã‘ãªã„ã®ã§ï¼Œ$a=0$ã§ã‚ã£ã¦ã‚‚
+%\textit{penalty\_node}を作ã£ã¦æŒ¿å…¥ã™ã‚‹ï¼Ž
+%\item 以上ã®ã©ã‚Œã§ã‚‚ãªã„ã¨ãã¯ï¼Œ$a\neq 0$ãªã‚‰ã°\textit{penalty\_node}を作ã£ã¦æŒ¿å…¥ã™ã‚‹ï¼Ž
+\end{itemize}
+\end{description}
+
+\def\gkf#1#2#3{\sf$\displaystyle\vphantom{\Bigg(}%
+ \frac{\hbox to 4\zw{\hss#2\hss}}{\hbox{#3}}$}
+\begin{table}[t]
+%<en>\caption{Summary of JFM glues}
+%<ja>\caption{JFM グルーã®æ¦‚è¦}
+\label{tab-jfmglue}
+%<en>\medskip
+\begin{center}
+\small
+\begin{tabular}{c|cccccc}
+\toprule
+{\bf\textit{Np}}↓&\sf 和文A&\sf 和文B&\sf 欧文&\sf 箱&\sf glue&\sf kern\\\midrule
+\sf 和文A&
+\gkf{E}{M→K}{PN}&
+\gkf{---}{\OA →K}{PN}&
+\gkf{---}{\NA →X}{PN}&
+\gkf{---}{\OA}{PA}&
+\gkf{---}{\OA}{PN}&
+\gkf{---}{\OA}{PS}\\
+\sf 和文B&
+\gkf{E}{\OB→K}{PA}&
+\gkf{---}{K}{PS}&
+\gkf{---}{X}{PS}\\
+\sf 欧文&
+\gkf{E}{\NB →X}{PA}&
+\gkf{---}{X}{PS}\cr
+\sf ç®±&\gkf{E}{\OB}{PA}\\
+\sf glue&\gkf{E}{\OB}{PN}\\
+\sf kern&\gkf{E}{\OB}{PS}\\
+\bottomrule
+\end{tabular}
+\end{center}
+\begin{quote}
+%<*en>
+In the table above, {\small\gkf{E}{M→K}{PN}} means that
+%</en>
+%<*ja>
+上ã®è¡¨ã«ãŠã„ã¦ï¼Œ{\small\gkf{E}{M→K}{PN}}ã¯æ¬¡ã®æ„味ã§ã‚る:
+%</ja>
+\begin{enumerate}
+%<*en>
+\item To determine the ``right-space'', \LuaTeX-ja first attempts by the method ``\textsf{JFM-origin~[M]}''.
+If this attempt fails, \LuaTeX-ja use the method ``\textsf{\Param{kanjiskip}~[K]}''.
+%</en>
+%<*ja>
+\item 「å³ç©ºç™½ã€ã‚’決ã‚ã‚‹ãŸã‚ã«ï¼Œ\LuaTeX-ja ã¯ã¾ãšã€ŒJFMç”±æ¥{[M]}ã€ã®æ–¹æ³•ã‚’試ã¿ã‚‹ï¼Ž
+ ã“ã‚ŒãŒå¤±æ•—ã—ãŸã‚‰ï¼Œ\LuaTeX-ja ã¯ã€Œ\Param{kanjiskip}~{[K]}ã€ã®æ–¹æ³•ã‚’試ã¿ã‚‹ï¼Ž
+%</ja>
+
+% %<*en>
+% \item The ``left space'' between \textit{Nq}~and~\textit{Np} is
+% determined by the method ``\textsf{line-end~[E]}''.
+% %</en>
+% %<*ja>
+% \item \textit{Nq} 㨠\textit{Np} ã®é–“ã®ã€Œå·¦ç©ºç™½ã€ã¯ã€Œ\textsf{line-end~[E]}ã€ã®
+% 方法ã§æ±ºå®šã•ã‚Œã‚‹ï¼Ž
+% %</ja>
+
+%<*en>
+\item \LuaTeX-ja adopts the method ``\textsf{P-normal~[PN]}'' to adjust the penalty
+ between two clusters for \emph{kinsoku shori}.
+%</en>
+%<*ja>
+\item \LuaTeX-jaã¯2ã¤ã®ã‚¯ãƒ©ã‚¹ã‚¿ã®é–“ã®ç¦å‰‡å‡¦ç†ç”¨ã®ãƒšãƒŠãƒ«ãƒ†ã‚£ã‚’設定ã™ã‚‹ãŸã‚ã«ã€Œ\textsf{P-normal~[PN]}ã€ã®æ–¹æ³•ã‚’採用ã™ã‚‹ï¼Ž
+%</ja>
+\end{enumerate}
+\end{quote}
+\end{table}
+
+\subsection{ãã®ä»–ã®å ´åˆ}
+本節ã®å†…容ã¯\autoref{tab-jfmglue}ã«ã¾ã¨ã‚ã¦ã‚る.
+
+\paragraph{和文Aã¨æ¬§æ–‡ã®é–“}
+\textit{Nq}ãŒ\textsf{和文A}ã§ï¼Œ\textit{Np}ãŒ\textsf{欧文}ã®å ´åˆï¼ŒJFMグルー挿入処ç†ã¯æ¬¡ã®ã‚ˆã†ã«ã—ã¦è¡Œã‚れる.
+\begin{itemize}
+\item 「å³ç©ºç™½ã€ã«ã¤ã„ã¦ã¯ï¼Œã¾ãšä»¥ä¸‹ã«è¿°ã¹ã‚‹\textsf{欧文境界B~[\NB]}ã«ã‚ˆã‚Šç©ºç™½ã‚’決定ã—よã†ã¨è©¦ã¿ã‚‹ï¼Ž
+ãã‚ŒãŒå¤±æ•—ã—ãŸå ´åˆã¯ï¼Œ\textsf{\Param{xkanjiskip}~[X]}ã«ã‚ˆã£ã¦å®šã‚る.
+%\item 「左空白ã€ã«ã¤ã„ã¦ã¯ï¼Œæ—¢ã«è¿°ã¹ãŸ\textsf{line-end~[E]}ã‚’ãã®ã¾ã¾æŽ¡ç”¨ã™ã‚‹ï¼Žãã‚Œã«ä¼´ã†ã€Œå³ç©ºç™½ã€ã®è£œæ­£ã‚‚%åŒã˜ï¼Ž
+\item ç¦å‰‡ç”¨ãƒšãƒŠãƒ«ãƒ†ã‚£ã‚‚,以å‰è¿°ã¹ãŸ\textsf{P-normal~[PN]}ã¨åŒã˜ã§ã‚る.
+\end{itemize}
+\begin{description}
+\item[欧文境界B~{[\NB]}] 以下ã§æ±‚ã‚ãŸé‡ã‚’「å³ç©ºç™½ã€ã¨ã—ã¦æŽ¡ç”¨ã™ã‚‹ï¼Ž
+ã“ã®å‡¦ç†ã¯\textsf{JFM-origin~[M]}ã®å¤‰ç¨®ã¨è€ƒãˆã¦è‰¯ã,
+典型例ã¯ã€Œå’Œæ–‡ã®é–‰ã˜æ‹¬å¼§ã¨æ¬§æ–‡æ–‡å­—ã®é–“ã«å…¥ã‚‹åŠè§’アキã€ã§ã‚る.
+\begin{enumerate}
+\item ã‚‚ã—両クラスタã®é–“㧠\cs{inhibitglue} ãŒå®Ÿè¡Œã•ã‚Œã¦ã„ãŸå ´åˆ%
+(証ã¨ã—ã¦whatsitノードãŒè‡ªå‹•æŒ¿å…¥ã•ã‚Œã‚‹ï¼‰ï¼Œæœªå®šç¾©ï¼Ž
+\item ãã†ã§ãªã‘ã‚Œã°ï¼Œ
+\textit{Nq}ã¨ã€Œæ–‡å­—コードãŒ$x$ã®æ–‡å­—ã€ã¨ã®é–“ã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ã¨ã™ã‚‹ï¼Ž
+ã“ã®$x$ã¯æ¬¡ã®å ´åˆåˆ†ã‘ã«ã‚ˆã‚‹ï¼š
+ \begin{itemize}
+ \item $\mathit{Np}.\mathit{id}$ãŒ\textit{id\_math}ã®ã¨ã(ã¤ã¾ã‚Šã‚¯ãƒ©ã‚¹ã‚¿\textit{Np}ãŒæ–‡ä¸­æ•°å¼ã‚’表ã™ï¼‰
+ ã¨ãã¯ï¼Œ$x=-1$.
+ \item \textit{Np}ã®ä¸­èº«ã®ä¸­èº«ã®æ–‡å­—コードã«ã¤ã„ã¦ï¼Œã€Œç›´å‰ã¸ã®\Param{xkanjiskip}ã®æŒ¿å…¥ã€ãŒç¦æ­¢ã•ã‚Œã¦ã„ã‚‹
+(ã¤ã¾ã‚Šï¼Œ\Param{jaxspmode}~(or \Param{alxspmode})パラメタãŒå¶æ•°ï¼‰ã¨ãã¯ï¼Œ
+ $x=\text{\texttt{'nox\_alchar'}}$.
+ \item 以上ã®ã„ãšã‚Œã§ã‚‚ãªã„ã¨ãã¯ï¼Œ$x=\text{\texttt{'alchar'}}$.
+ \end{itemize}
+\end{enumerate}
+\item[\Param{xkanjiskip}~{[X]}]
+ã“ã®æ®µéšŽã§ã¯ï¼Œ\textsf{\Param{kanjiskip}~[K]}ã®ã¨ãã¨åŒã˜ã‚ˆã†ã«ï¼Œ
+以下ã§å®šã‚ãŸé‡ã‚’「å³ç©ºç™½ã€ã¨ã—ã¦æŽ¡ç”¨ã™ã‚‹ï¼Ž
+\cs{inhibitglue} ã¯åŠ¹åŠ›ã‚’æŒãŸãªã„.
+\begin{enumerate}
+\item 以下ã®ã„ãšã‚Œã‹ã®å ´åˆã¯ï¼Œ\Param{xkanjiskip}ã®æŒ¿å…¥ã¯æŠ‘æ­¢ã•ã‚Œã‚‹ï¼Žã—ã‹ã—,実際ã«ã¯è¡Œåˆ†å‰²ã‚’許容ã™ã‚‹ãŸã‚ã«ï¼Œé•·ã•0ã®glueを採用ã™ã‚‹ï¼š
+\begin{itemize}
+\item 両クラスタã«ãŠã„ã¦ï¼Œãれらã®ä¸­èº«ã®æ–‡å­—コードã«å¯¾ã™ã‚‹\Param{autoxspacing}パラメタãŒå…±ã«falseã§ã‚る.
+\item \textit{Nq}ã®ä¸­èº«ã®æ–‡å­—コードã«ã¤ã„ã¦ï¼Œã€Œç›´å¾Œã¸ã®\Param{xkanjiskip}ã®æŒ¿å…¥ã€ãŒç¦æ­¢ã•ã‚Œã¦ã„ã‚‹
+(ã¤ã¾ã‚Šï¼Œ\Param{jaxspmode}~(or \Param{alxspmode})パラメタãŒ2以上).
+\item \textit{Np}ã®ä¸­èº«ã®æ–‡å­—コードã«ã¤ã„ã¦ï¼Œã€Œç›´å‰ã¸ã®\Param{xkanjiskip}ã®æŒ¿å…¥ã€ãŒç¦æ­¢ã•ã‚Œã¦ã„ã‚‹
+(ã¤ã¾ã‚Šï¼Œ\Param{jaxspmode}~(or \Param{alxspmode})パラメタãŒå¶æ•°ï¼‰ï¼Ž
+\end{itemize}
+\item ユーザå´ã‹ã‚‰è¦‹ãŸ\Param{xkanjiskip}パラメタã®è‡ªç„¶é•·ãŒ$\cs{maxdimen}=(2^{30}-1)\,{\rm sp}$ã§
+ãªã‘ã‚Œã°ï¼Œ\Param{xkanjiskip}パラメタã®å€¤ã‚’æŒã¤glueを採用ã™ã‚‹ï¼Ž
+\item 2.ã§ãªã„å ´åˆã¯ï¼Œ\textit{Nq}, \textit{Np}(\textsf{和文A}/\textsf{和文B}ãªã®ã¯ç‰‡æ–¹ã ã‘)
+ã§ä½¿ã‚ã‚Œã¦ã„ã‚‹JFMã«æŒ‡å®šã•ã‚Œã¦ã„ã‚‹\Param{xkanjiskip}ã®å€¤ã‚’用ã„る.
+\end{enumerate}
+\end{description}
+
+\paragraph{欧文ã¨å’Œæ–‡Aã®é–“}
+\textit{Nq}ãŒ\textsf{欧文}ã§ï¼Œ\textit{Np}ãŒ\textsf{和文A}ã®å ´åˆï¼ŒJFMグルー挿入処ç†ã¯ä¸Šã®å ´åˆã¨ã»ã¼åŒã˜ã§ã‚る.
+\textsf{和文A}ã®ã‚¯ãƒ©ã‚¹ã‚¿ãŒé€†ã«ãªã‚‹ã®ã§ï¼Œ\textsf{欧文境界B~[\NB]}ã®éƒ¨åˆ†ãŒå¤‰ã‚ã‚‹ã ã‘ã§ã‚る.
+\begin{itemize}
+\item 「å³ç©ºç™½ã€ã«ã¤ã„ã¦ã¯ï¼Œã¾ãšä»¥ä¸‹ã«è¿°ã¹ã‚‹\textsf{欧文境界A~[\OA]}ã«ã‚ˆã‚Šç©ºç™½ã‚’決定ã—よã†ã¨è©¦ã¿ã‚‹ï¼Ž
+ãã‚ŒãŒå¤±æ•—ã—ãŸå ´åˆã¯ï¼Œ\textsf{\Param{xkanjiskip}~[X]}ã«ã‚ˆã£ã¦å®šã‚る.
+%\item \textit{Nq}ãŒå’Œæ–‡ã§ãªã„ã®ã§ï¼Œã€Œå·¦ç©ºç™½ã€ã¯ç®—出ã•ã‚Œãªã„.
+\item ç¦å‰‡ç”¨ãƒšãƒŠãƒ«ãƒ†ã‚£ã¯ï¼Œä»¥å‰è¿°ã¹ãŸ\textsf{P-normal~[PN]}ã¨åŒã˜ã§ã‚る.
+\end{itemize}
+\begin{description}
+\item[欧文境界A~{[\NA]}] ã“ã‚Œã¯\textsf{欧文境界B~[\NB]}ã§\textit{Np}ã¨\textit{Nq}ã®å½¹å‰²ãŒ
+ 交æ›ã•ã‚ŒãŸã‚‚ã®ã¨æ€ãˆã°è‰¯ã„.
+ ã“ã®å‡¦ç†ã§å®šã¾ã‚‹ç©ºç™½ã®å…¸åž‹ä¾‹ã¯ï¼Œæ¬§æ–‡æ–‡å­—ã¨å’Œæ–‡ã®é–‹ã括弧ã¨ã®é–“ã«å…¥ã‚‹åŠè§’アキã§ã‚る.
+\begin{enumerate}
+\item ã‚‚ã—両クラスタã®é–“㧠\cs{inhibitglue} ãŒå®Ÿè¡Œã•ã‚Œã¦ã„ãŸå ´åˆï¼ˆè¨¼ã¨ã—ã¦whatsitノードãŒè‡ªå‹•æŒ¿å…¥ã•ã‚Œã‚‹ï¼‰ï¼Œ
+ 未定義.
+\item ãã†ã§ãªã‘ã‚Œã°ï¼Œ
+「文字コードãŒ$x$ã®æ–‡å­—ã€ã¨\textit{Np}ã¨ã®é–“ã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼ï¼ã‚«ãƒ¼ãƒ³ã¨å®šã‚る.
+$x$ã¯\textit{Nq}ã‹ã‚‰\textsf{欧文境界B~[\NB]}ã«ãŠã‘ã‚‹ãã‚Œã¨åŒã˜æ–¹æ³•ã§å®šã‚ã‚‹ãŒï¼Œ
+\texttt{'nox\_alchar'}ã‹\texttt{'alchar'}ã¯
+\begin{quote}
+ \textit{Nq}ã®ä¸­èº«ã®æ–‡å­—コードã«ã¤ã„ã¦ï¼Œã€Œç›´å¾Œã¸ã®\Param{xkanjiskip}ã®æŒ¿å…¥ã€ãŒç¦æ­¢ã•ã‚Œã¦ã„ã‚‹
+(ã¤ã¾ã‚Šï¼Œ\Param{jaxspmode}~(or \Param{alxspmode})パラメタãŒ2以上).
+\end{quote}
+ ã‹å¦ã‹ã§åˆ¤æ–­ã™ã‚‹ï¼Ž
+\end{enumerate}
+\end{description}
+
+\paragraph{和文Aã¨ç®±ãƒ»ã‚°ãƒ«ãƒ¼ãƒ»ã‚«ãƒ¼ãƒ³ã®é–“}
+\textit{Nq}ãŒ\textsf{和文A}ã§ï¼Œ\textit{Np}ãŒ\textsf{ç®±}・グルー・カーンã®ã„ãšã‚Œã‹ã§ã‚ã£ãŸå ´åˆï¼Œ
+両者ã®é–“ã«æŒ¿å…¥ã•ã‚Œã‚‹JFMグルーã«ã¤ã„ã¦ã¯åŒã˜å‡¦ç†ã§ã‚る.ã—ã‹ã—,ãã“ã§ã®è¡Œåˆ†å‰²ã«å¯¾ã™ã‚‹ä»•æ§˜ãŒç•°ãªã‚‹ã®ã§ï¼Œ
+ペナルティã®æŒ¿å…¥å‡¦ç†ã¯è‹¥å¹²ç•°ãªã£ãŸã‚‚ã®ã¨ãªã£ã¦ã„る.
+\begin{itemize}
+\item 「å³ç©ºç™½ã€ã«ã¤ã„ã¦ã¯ï¼Œä»¥ä¸‹ã«è¿°ã¹ã‚‹\textsf{Boundary-B~[\OB]}ã«ã‚ˆã‚Šç©ºç™½ã‚’決定ã—よã†ã¨è©¦ã¿ã‚‹ï¼Ž
+ãã‚ŒãŒå¤±æ•—ã—ãŸå ´åˆã¯ï¼Œã€Œå³ç©ºç™½ã€ã¯æŒ¿å…¥ã•ã‚Œãªã„.
+%\item 「左空白ã€ã«ã¤ã„ã¦ã¯ï¼Œæ—¢ã«è¿°ã¹ãŸ\textsf{line-end~[E]}ã®ç®—出方法をãã®ã¾ã¾æŽ¡ç”¨ã™ã‚‹ï¼Žãã‚Œã«ä¼´ã†ã€Œå³ç©ºç™½ã€ã®è£œæ­£ã‚‚åŒã˜ï¼Ž
+\item ç¦å‰‡ç”¨ãƒšãƒŠãƒ«ãƒ†ã‚£ã®å‡¦ç†ã¯ï¼Œå¾Œã‚ã®ã‚¯ãƒ©ã‚¹ã‚¿\textit{Np}ã®ç¨®é¡žã«ã‚ˆã£ã¦ç•°ãªã‚‹ï¼Ž
+ãªãŠï¼Œ$\mathit{Np}.\mathit{head}$ã¯ç„¡æ„味ã§ã‚ã‚‹ã‹ã‚‰ï¼Œ
+「$\mathit{Np}.\mathit{head}$ã«å¯¾ã™ã‚‹\Param{prebreakpenalty}ã®å€¤ã€ã¯0ã¨ã¿ãªã•ã‚Œã‚‹ï¼Žè¨€ã„æ›ãˆã‚Œã°ï¼Œ
+\[
+ a:=(\text{\textit{Nq}ã®æ–‡å­—ã«å¯¾ã™ã‚‹\Param{postbreakpenalty}ã®å€¤}).
+\]
+\begin{description}
+\item[ç®±] \textit{Np}ãŒ\textsf{ç®±}ã§ã‚ã£ãŸå ´åˆã¯ï¼Œä¸¡ã‚¯ãƒ©ã‚¹ã‚¿ã®é–“ã§ã®è¡Œåˆ†å‰²ã¯
+(明示的ã«ä¸¡ã‚¯ãƒ©ã‚¹ã‚¿ã®é–“ã« \cs{penalty10000} ãŒã‚ã£ãŸå ´åˆã‚’除ã)ã„ã¤ã‚‚許容ã•ã‚Œã‚‹ï¼Žãã®ãŸã‚,
+ペナルティ処ç†ã¯ï¼Œå¾Œã«è¿°ã¹ã‚‹\textsf{P-allow~[PA]}ãŒ\textsf{P-normal~[PN]}ã®ä»£ã‚ã‚Šã«ç”¨ã„られる.
+\item[グルー] \textit{Np}ãŒã‚°ãƒ«ãƒ¼ã®å ´åˆï¼ŒãƒšãƒŠãƒ«ãƒ†ã‚£å‡¦ç†ã¯\textsf{P-normal~[PN]}を用ã„る.
+\item[カーン] \textit{Np}ãŒã‚«ãƒ¼ãƒ³ã§ã‚ã£ãŸå ´åˆã¯ï¼Œä¸¡ã‚¯ãƒ©ã‚¹ã‚¿ã®é–“ã§ã®è¡Œåˆ†å‰²ã¯
+(明示的ã«ä¸¡ã‚¯ãƒ©ã‚¹ã‚¿ã®é–“ã«ãƒšãƒŠãƒ«ãƒ†ã‚£ãŒã‚ã£ãŸå ´åˆã‚’除ã)許容ã•ã‚Œãªã„.
+ペナルティ処ç†ã¯ï¼Œå¾Œã«è¿°ã¹ã‚‹\textsf{P-suppress~[PS]}を使ã†ï¼Ž
+\end{description}
+ã“れらã®\textsf{P-normal~[PN]},\textsf{P-allow~[PA]},\textsf{P-suppress~[PS]}ã®é•ã„ã¯ï¼Œ
+\textit{Nq}ã¨\textit{Np}ã®é–“(以å‰ã®å›³ã ã¨(a)ã®éƒ¨åˆ†ï¼‰ã«ãƒšãƒŠãƒ«ãƒ†ã‚£ãŒå­˜åœ¨ã—ãªã„å ´åˆã«ã®ã¿å­˜åœ¨ã™ã‚‹ï¼Ž
+\end{itemize}
+
+\begin{description}
+\item[Boundary-B~{[\OB]}] ã“ã®å‡¦ç†ã¯\textsf{欧文境界B~[\NB]}ã¨åŒæ§˜ã§ã‚り,
+ $x$ãŒæ¬¡ã«ã‚ˆã£ã¦æ±ºã¾ã‚‹ã“ã¨ã®ã¿ãŒç•°ãªã‚‹ï¼š
+ \begin{itemize}
+ \item \textit{Np}ãŒã‚°ãƒ«ãƒ¼ã‚„カーンã®ã¨ãã¯ï¼Œ$x=\text{\texttt{'glue'}}$.
+ \item ãã†ã§ãªã„(\textit{Np}ãŒ\textsf{ç®±})ã¨ãã¯ï¼Œ$x=\text{\texttt{'jcharbdd'}}$.
+ \end{itemize}
+\item[P-allow~{[PA]}]
+\textit{Nq}ã¨\textit{Np}ã®é–“ã®(a)部分ã«ãƒšãƒŠãƒ«ãƒ†ã‚£ãŒã‚ã‚Œã°ï¼Œ\textsf{P-normal~[PN]}ã¨åŒæ§˜ã«ï¼Œ
+ãれらã®å„ノードã«ãŠã„ã¦ãƒšãƒŠãƒ«ãƒ†ã‚£å€¤ã‚’$a$ã ã‘増加ã•ã›ã‚‹ï¼Ž
+
+(a)部分ã«ãƒšãƒŠãƒ«ãƒ†ã‚£ãŒå­˜åœ¨ã—ã¦ã„ãªã„å ´åˆï¼Œ
+\LuaTeX-ja ã¯\textit{Nq}ã¨\textit{Np}ã®é–“ã®è¡Œåˆ†å‰²ã‚’å¯èƒ½ã«ã—よã†ã¨ã™ã‚‹ï¼Ž
+ãã®ãŸã‚ã«ï¼Œä»¥ä¸‹ã®ã„ãšã‚Œã‹ã®å ´åˆã«$a$ã‚’ã‚‚ã¤\textit{penalty\_node}を作ã£ã¦
+「å³ç©ºç™½ã€ã®ï¼ˆã‚‚ã—未定義ãªã‚‰\textit{Np}ã®ï¼‰ç›´å‰ã«æŒ¿å…¥ã™ã‚‹ï¼š
+\begin{itemize}
+\item 「å³ç©ºç™½ã€ãŒã‚°ãƒ«ãƒ¼ã§ãªã„(カーンã‹æœªå®šç¾©ï¼‰ã§ã‚ã‚‹ã¨ã.
+\item $a\neq 0$ã®ã¨ãã¯ï¼Œã€Œå³ç©ºç™½ã€ãŒã‚°ãƒ«ãƒ¼ã§ã‚ã£ã¦ã‚‚\textit{penalty\_node}を作る.
+\end{itemize}
+
+\item[P-suppress~{[PS]}]
+\textit{Nq}ã¨\textit{Np}ã®é–“ã®(a)部分ã«ãƒšãƒŠãƒ«ãƒ†ã‚£ãŒã‚ã‚Œã°ï¼Œ\textsf{P-normal~[PN]}ã¨åŒæ§˜ã«ï¼Œ
+ãれらã®å„ノードã«ãŠã„ã¦ãƒšãƒŠãƒ«ãƒ†ã‚£å€¤ã‚’$a$ã ã‘増加ã•ã›ã‚‹ï¼Ž
+
+(a)部分ã«ãƒšãƒŠãƒ«ãƒ†ã‚£ãŒå­˜åœ¨ã—ã¦ã„ãªã„å ´åˆï¼Œ
+\textit{Nq}ã¨\textit{Np}ã®é–“ã®è¡Œåˆ†å‰²ã¯å…ƒã€…ä¸å¯èƒ½ã®ã¯ãšã ã£ãŸã®ã§ã‚ã‚‹ãŒï¼Œ
+\LuaTeX-ja ã¯ãれをã‚ã–ã‚ã–行分割å¯èƒ½ã«ã¯ã—ãªã„.
+ãã®ãŸã‚,「å³ç©ºç™½ã€ãŒglueã§ã‚ã‚Œã°ï¼Œãã®ç›´å‰ã« \cs{penalty10000} を挿入ã™ã‚‹ï¼Ž
+\end{description}
+
+\paragraph{箱・グルー・カーンã¨å’Œæ–‡Aã®é–“}
+\textit{Np}ãŒ\textsf{ç®±}・グルー・カーンã®ã„ãšã‚Œã‹ã§ï¼Œ\textit{Np}ãŒ\textsf{和文A}ã§ã‚ã£ãŸå ´åˆã¯ï¼Œ
+ã™ã上ã®ï¼ˆ\textit{Nq}ã¨\textit{Np}ã®é †åºãŒé€†ã«ãªã£ã¦ã„る)場åˆã¨åŒã˜ã§ã‚る.
+%ãŒï¼Œã€Œå·¦ç©ºç™½ã€ãŒãªããªã‚‹ã“ã¨ã«ã®ã¿æ³¨æ„.
+\begin{itemize}
+\item 「å³ç©ºç™½ã€ã«ã¤ã„ã¦ã¯ï¼Œä»¥ä¸‹ã«è¿°ã¹ã‚‹\textsf{Boundary-A~[\OA]}ã«ã‚ˆã‚Šç©ºç™½ã‚’決定ã—よã†ã¨è©¦ã¿ã‚‹ï¼Ž
+ãã‚ŒãŒå¤±æ•—ã—ãŸå ´åˆã¯ï¼Œã€Œå³ç©ºç™½ã€ã¯æŒ¿å…¥ã•ã‚Œãªã„.
+%\item \textit{Nq}ãŒå’Œæ–‡ã§ãªã„ã®ã§ï¼Œã€Œå·¦ç©ºç™½ã€ã¯ç®—出ã•ã‚Œãªã„.
+\item ç¦å‰‡ç”¨ãƒšãƒŠãƒ«ãƒ†ã‚£ã®å‡¦ç†ã¯ï¼Œ\textit{Nq}ã®ç¨®é¡žã«ã‚ˆã£ã¦ç•°ãªã‚‹ï¼Ž
+$\mathit{Nq}.\mathit{tail}$ã¯ç„¡æ„味ãªã®ã§ï¼Œ
+\[
+ a:=(\text{\textit{Np}ã®æ–‡å­—ã«å¯¾ã™ã‚‹\Param{prebreakpenalty}ã®å€¤}).
+\]
+\begin{description}
+\item[ç®±] \textit{Nq}ãŒ\textsf{ç®±}ã®å ´åˆã¯ï¼Œ\textsf{P-allow~[PA]}を用ã„る.
+\item[グルー] \textit{Nq}ãŒã‚°ãƒ«ãƒ¼ã®å ´åˆã¯ï¼Œ\textsf{P-normal~[PN]}を用ã„る.
+\item[カーン] \textit{Nq}ãŒã‚«ãƒ¼ãƒ³ã®å ´åˆã¯ï¼Œ\textsf{P-suppress~[PS]}を用ã„る.
+\end{description}
+\end{itemize}
+
+\begin{description}
+\item[Boundary-A~{[\OA]}] ã“ã®å‡¦ç†ã¯\textsf{欧文境界A~[\NA]}ã¨åŒæ§˜ã§ã‚り,
+ $x$ãŒæ¬¡ã«ã‚ˆã£ã¦æ±ºã¾ã‚‹ã“ã¨ã®ã¿ãŒç•°ãªã‚‹ï¼š
+ \begin{itemize}
+ \item \textit{Nq}ãŒã‚°ãƒ«ãƒ¼ã‚„カーンã®ã¨ãã¯ï¼Œ$x=\text{\texttt{'glue'}}$.
+ \item ãã†ã§ãªã„(\textit{Nq}ãŒ\textsf{ç®±})ã¨ãã¯ï¼Œ$x=\text{\texttt{'jcharbdd'}}$.
+ \end{itemize}
+\end{description}
+
+\paragraph{和文Aã¨å’Œæ–‡Bã®é•ã„}
+å…ˆã«è¿°ã¹ãŸã‚ˆã†ã«ï¼Œ\textsf{和文B}ã¯hboxã®ä¸­èº«ã®å…ˆé ­ï¼ˆor 末尾)ã¨ã—ã¦å‡ºç¾ã—ã¦ã„ã‚‹
+\textbf{JAchar}ã§ã‚る.リスト内ã«ç›´æŽ¥ãƒŽãƒ¼ãƒ‰ã¨ã—ã¦ç¾ã‚Œã¦ã„ã‚‹\textbf{JAchar}(\textsf{和文A})ã¨ã®é•ã„ã¯ï¼Œ
+\begin{itemize}
+\item \textsf{和文B}ã«å¯¾ã—ã¦ã¯ï¼ŒJFMã®æ–‡å­—クラス指定ã‹ã‚‰å®šã¾ã‚‹ç©ºç™½
+(\textsf{JFMç”±æ¥[M]},\textsf{Boundary-A~[\OA]}ãªã©ï¼‰ã®æŒ¿å…¥ã¯è¡Œã‚ã‚Œãªã„.
+%「左空白ã€ã®ç®—出も行ã‚ã‚Œãªã„.
+例ãˆã°ï¼Œ
+\begin{itemize}
+\item 片方ãŒ\textsf{和文A},もã†ç‰‡æ–¹ãŒ\textsf{和文B}ã®ã‚¯ãƒ©ã‚¹ã‚¿ã®å ´åˆï¼Œ
+\textsf{Boundary-A~[\OA]}ã¾ãŸã¯\textsf{Boundary-B~[\OB]}ã®æŒ¿å…¥ã‚’試ã¿ï¼Œãã‚ŒãŒãƒ€ãƒ¡ãªã‚‰
+\Param{kanjiskip}~\textsf{[K]}ã®æŒ¿å…¥ã‚’è¡Œã†ï¼Ž
+\item \textsf{和文B}ã®2ã¤ã®ã‚¯ãƒ©ã‚¹ã‚¿ã®é–“ã«ã¯ï¼Œ\Param{kanjiskip}~\textsf{[K]}ãŒè‡ªå‹•çš„ã«å…¥ã‚‹ï¼Ž
+\end{itemize}
+\item \textsf{和文B}ã¨ç®±ãƒ»ã‚°ãƒ«ãƒ¼ãƒ»ã‚«ãƒ¼ãƒ³ãŒéš£æŽ¥ã—ãŸã¨ã(ã©ã¡ã‚‰ãŒå‰ã‹ã¯é–¢ä¿‚ãªã„),間ã«JFMグルー・ペナルティã®æŒ¿å…¥ã¯ä¸€åˆ‡ã—ãªã„.
+\item \textsf{和文B}ã¨\textsf{和文B},ã¾ãŸ\textsf{和文B}ã¨\textsf{欧文}ã¨ãŒéš£æŽ¥ã—ãŸæ™‚ã¯ï¼Œç¦å‰‡ç”¨ãƒšãƒŠãƒ«ãƒ†ã‚£æŒ¿å…¥å‡¦ç†ã¯
+\textsf{P-suppress~[PS]}ãŒç”¨ã„られる.
+\item \textsf{和文B}ã®æ–‡å­—ã«å¯¾ã™ã‚‹\Param{prebreakpenalty},~\Param{postbreakpenalty}ã®å€¤ã¯ä½¿ã‚ã‚Œãšï¼Œ0ã¨ã—ã¦è¨ˆç®—ã•ã‚Œã‚‹ï¼Ž
+\end{itemize}
+
+
+次ãŒå…·ä½“例ã§ã‚る:
+\begin{LTXexample}
+ã‚.\inhibitglue A\\
+\hbox{ã‚.}A\\
+ã‚.A
+\end{LTXexample}
+\begin{itemize}
+\item 1行目ã®\cs{inhibitglue}ã¯\textsf{欧文境界B~[\NB]}ã®å‡¦ç†ã®ã¿ã‚’抑止ã™ã‚‹ã®ã§ï¼Œãƒ”リオドã¨ã€ŒAã€ã®é–“ã«ã¯
+\Param{xkanjiskip}(四分アキ)ãŒå…¥ã‚‹ã“ã¨ã«æ³¨æ„.
+\item 2行目ã®ãƒ”リオドã¨ã€ŒAã€ã®é–“ã«ãŠã„ã¦ã¯ï¼Œå‰è€…ãŒ\textsf{和文B}ã¨ãªã‚‹ï¼ˆhboxã®ä¸­èº«ã®æœ«å°¾ã¨ã—ã¦ç™»å ´ã—ã¦ã„ã‚‹ã‹ã‚‰ï¼‰ã®ã§ï¼Œ
+ãã‚‚ãã‚‚\textsf{欧文境界B~[\NB]}ã®å‡¦ç†ã¯è¡Œã‚ã‚Œãªã„.よã£ã¦ï¼Œ\Param{xkanjiskip}ãŒå…¥ã‚‹ã“ã¨ã¨ãªã‚‹ï¼Ž
+\item 3行目ã§ã¯ï¼Œãƒ”リオドã®å±žã™ã‚‹ã‚¯ãƒ©ã‚¹ã‚¿ã¯\textsf{和文A}ã§ã‚る.ã“ã‚Œã«ã‚ˆã£ã¦ï¼Œ
+ピリオドã¨ã€ŒAã€ã®é–“ã«ã¯\textsf{欧文境界B~[\NB]}ç”±æ¥ã®åŠè§’アキãŒå…¥ã‚‹ã“ã¨ã«ãªã‚‹ï¼Ž
+\end{itemize}
+%</ja>
+
+%<*ja>
+\section{ベースライン補正ã®æ–¹æ³•}
+\subsection{\texttt{yoffset} フィールド}
+\Param{yalbaselineshift}ç­‰ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³è£œæ­£ã¯ï¼ŒåŸºæœ¬çš„ã«ã¯å¯¾è±¡ã¨ãªã£ã¦ã„ã‚‹
+\textit{glyph\_node}ã® \texttt{yoffset} フィールドã®å€¤ã‚’増減ã™ã‚‹ã“ã¨ã«ã‚ˆã£ã¦
+実装ã•ã‚Œã¦ã„る.ãªãŠï¼Œ\texttt{yoffset} ã®å€¤ã¯ä¸Šæ–¹å‘ã¸ã®ç§»å‹•é‡ã§ã‚ã‚‹ã®ã«å¯¾ã—,
+\Param{yalbaselineshift}ãªã©ã¯ä¸‹æ–¹å‘ã¸ã®ç§»å‹•é‡ã§ã‚る.
+
+ã•ã¦ï¼Œ\texttt{yoffset} ã®å¢—減ã«ã‚ˆã£ã¦è¦‹ã‹ã‘ã®ã‚°ãƒªãƒ•ä½ç½®ã¯ä¸Šä¸‹ã«ç§»å‹•ã™ã‚‹ãŒï¼Œ
+仮想ボディã®é«˜ã•$h$,深ã•$d$ã«ã¤ã„ã¦ã¯
+\begin{description}
+\catcode`\<=12\catcode`\>=12
+ \item[$\texttt{yoffset}\geq 0$ã®ã¨ã]
+$h = \max(\texttt{height} + \texttt{yoffset}, 0)$,
+$d = \max(\texttt{depth} - \texttt{yoffset}, 0)$,
+ \item[$\texttt{yoffset}<0$ã®ã¨ã]
+$h = \max(\texttt{height} + \texttt{yoffset}, 0)$, $d=\texttt{depth}$.
+\end{description}
+ã¨ã„ã†ä»•æ§˜ã«ãªã£ã¦ã„る.ã¤ã¾ã‚Šï¼Œ\texttt{yoffset} ãŒè² ï¼ˆã‚°ãƒªãƒ•ã‚’下ã‘る)ã®å ´åˆã«æ·±ã•ã¯å¢—加ã—ãª
+ã„(\autoref{tab:yoffset_and_im}å‚照).
+
+\begin{table}[t]
+\caption{\texttt{yoffset} and imaginary body}
+\label{tab:yoffset_and_im}
+\centering\small
+\fboxsep0pt
+\def\T#1#2{\fcolorbox{blue}{white}{%
+ \setbox0=\hbox{\LARGE #1%
+ \directlua{
+ local p = tex.nest[tex.nest.ptr].tail
+ p.yoffset = #2 * 65536
+ }%
+ }%
+ \copy0\kern-\wd0\smash{\color{red}\vrule width \wd0 height 0.2pt depth 0.2pt}%
+}}
+\begin{tabular}{>{\bfseries}lccccc}
+\toprule
+\texttt{yoffset}&10\,pt&5\,pt&0&$-5$\,pt&$-10$\,pt\\
+\midrule
+仮想ボディ&\T{y}{10}, \T{H}{10}&\T{y}{5}, \T{H}{5}&\T{y}{0}, \T{H}{0}%
+&\T{y}{-5}, \T{H}{-5}&\T{y}{-10}, \T{H}{-10}\\[10pt]
+\bottomrule
+\end{tabular}
+\end{table}
+
+\subsection{\textbf{ALchar}ã®è£œæ­£}
+上記ã®å•é¡Œã«ã¤ã„ã¦ï¼Œ\textbf{ALchar}ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³è£œæ­£ã§ã¯
+「正ã—ã„æ·±ã•ã€ã‚’æŒã£ãŸç½«ç·š(rule)を補ã†ã¨ã„ã†å¯¾å¿œç­–ã‚’ã¨ã£ãŸï¼Ž
+ã“ã®ç½«ç·šã«ã‚ˆã‚‹è£œæ­£ã¯ï¼Œ\textit{id}ãŒ\textit{id\_glyph}ã§ã‚るクラスタå˜ä½ï¼Œ
+大雑把ã«è¨€ãˆã°éŸ³ç¯€å˜ä½ã§è¡Œã‚れる.
+文字列``Typeset''を
+\begin{itemize}
+ \item フォントã¯Latin Modern Roman (\texttt{lmroman10-regular.otf}) 10\,pt
+ \item \Param{yalbaselineshift}ã¯5\,pt
+\end{itemize}
+ã¨ã„ã†çŠ¶æ³ã§çµ„ã‚“ã å ´åˆã‚’例ã«ã¨ã£ã¦èª¬æ˜Žã—よã†ï¼Ž
+
+\LuaTeX・\Pkg{luaotfload}ã«ã‚ˆã‚‹ã‚«ãƒ¼ãƒ‹ãƒ³ã‚°ãƒ»ãƒã‚¤ãƒ•ãƒãƒ¼ã‚·ãƒ§ãƒ³ãŒçµ‚ã‚ã£ãŸæ®µéšŽã§ã¯ï¼Œâ€¦â€¦
+
+
+
+%</ja>
+
+%<en>\section{Patch for the \Pkg{listings} Package}
+%<ja>\section{\Pkg{listings} パッケージã¸ã®å¯¾å¿œ}
+
+%<*en>
+It is well-known that the \Pkg{listings} package outputs weird results
+for Japanese input.
+The \Pkg{listings} package makes most of letters active and assigns
+output command for each letter~(\cite{listings}).
+But Japanese characters are not included in these activated letters.
+For \pTeX{} series, there is no method to make Japanese characters active;
+a patch \Pkg{jlisting.sty}~(\cite{jlisting}) resolves the problem forcibly.
+%</en>
+%<*ja>
+\Pkg{listings} パッケージãŒï¼Œãã®ã¾ã¾ã§ã¯æ—¥æœ¬èªžã‚’ã¾ã¨ã‚‚ã«å‡ºåŠ›ã§ããªã„ã“ã¨
+ã¯ã‚ˆã知られã¦ã„る.ãã¡ã‚“ã¨æ•´å½¢ã—ã¦å‡ºåŠ›ã™ã‚‹ãŸã‚ã«ï¼Œ\Pkg{listings}パッケー
+ジã¯å†…部ã§ã€Œã»ã¨ã‚“ã©ã®æ–‡å­—ã€ã‚’アクティブã«ã—,å„文字ã«å¯¾ã—ã¦ãã®æ–‡å­—ã®å‡º
+力命令を割り当ã¦ã¦ã„ã‚‹(\cite{listings}).
+ã—ã‹ã—,ãã“ã§ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã«ã™ã‚‹æ–‡å­—ã®ä¸­ã«ï¼Œå’Œæ–‡æ–‡
+å­—ãŒãªã„ãŸã‚ã§ã‚る.\pTeX 系列ã§ã¯ï¼Œå’Œæ–‡æ–‡å­—をアクティブã«ã™ã‚‹æ‰‹æ³•ãŒãªã,
+\Pkg{jlisting.sty} ã¨ã„ã†ãƒ‘ッãƒ(\cite{jlisting})を用ã„ã‚‹ã“ã¨ã§ç„¡ç†ã‚„り解決ã—ã¦ã„ãŸï¼Ž
+%</ja>
+
+%<*en>
+In \LuaTeX-ja, the problem is resolved by using the \verb+process_input_buffer+ callback.
+The callback function inserts the output command (active character \cs{ltjlineendcomment})
+before each letter above \texttt{U+0080}.
+This method can omits the process to make all Japanese characters active
+(most of the activated characters are not used in many cases).
+%</en>
+%<*ja>
+\LuaTeX-jaã§ã¯ï¼Œ\verb+process_input_buffer+ コールãƒãƒƒã‚¯ã‚’利用ã™ã‚‹ã“ã¨ã§ï¼Œ
+「å„è¡Œã«å‡ºç¾ã™ã‚‹\texttt{U+0080}以é™ã®æ–‡å­—ã«å¯¾ã—ã¦ï¼Œãれらã®å‡ºåŠ›å‘½ä»¤ã‚’å‰ç½®ã™ã‚‹ã€
+ã¨ã„ã†æ–¹æ³•ã‚’ã¨ã£ã¦ã„る.出力命令ã¨ã—ã¦ã¯ï¼Œã‚¢ã‚¯ãƒ†ã‚£ãƒ–文字化ã—ãŸ\cs{ltjlineendcomment}を用ã„ã¦ã„る.
+ã“ã‚Œã«ã‚ˆã‚Šï¼Œï¼ˆå…¥åŠ›ã«ã¯ä½¿ç”¨ã•ã‚Œã¦ã„ãªã„ã‹ã‚‚ã—ã‚Œãªã„)和文文字をもã™ã¹ã¦ã‚¢ã‚¯ãƒ†ã‚£ãƒ–化ã™ã‚‹æ‰‹é–“ã‚‚ãªã,
+見通ã—ãŒè‰¯ã„実装ã«ãªã£ã¦ã„る.
+%</ja>
+
+
+%<*en>
+If the \Pkg{listings} package and \LuaTeX-ja were loaded,
+then the patch \Pkg{lltjp-listings} is loaded automatically at \verb+\begin{document}+.
+%</en>
+%<*ja>
+\LuaTeX-ja ã§åˆ©ç”¨ã•ã‚Œã‚‹ \Pkg{listings} パッケージã¸ã®ãƒ‘ッム\Pkg{lltjp-listings} ã¯ï¼Œ
+\Pkg{listings} ã¨\LuaTeX-jaを読ã¿è¾¼ã‚“ã§ãŠã‘ã°ï¼Œ
+\verb+\begin{document}+ ã®ç®‡æ‰€ã«ãŠã„ã¦è‡ªå‹•çš„ã«èª­ã¿è¾¼ã¾ã‚Œã‚‹ã®ã§ï¼Œé€šå¸¸ã¯ã‚ã¾ã‚Š
+æ„è­˜ã™ã‚‹å¿…è¦ã¯ãªã„.
+%</ja>
+
+%<en>\subsection{Notes and additional keys}
+%<ja>\subsection{注æ„}
+% %<*en>
+% \paragraph{Escaping to \LaTeX}
+% We used the \verb+process_input_buffer+ callback to output \textbf{JAchar}s.
+% But it has a drawback; any commands whose name contains a \textbf{JAchar}
+% cannot be used in any ``escape to \LaTeX''.
+
+% Consider the following input:
+% %</en>
+% %<*ja>
+% \paragraph{\LaTeX ã¸ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—}
+% 日本語対応を行ã†ãŸã‚ã« \verb+process_input_buffer+ を使用ã—ãŸã“ã¨ã§ï¼Œ
+% \texttt{texcl},~\texttt{escapeinside}ã¨ã„ã£ãŸ\emph{「\LaTeX ã¸ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã€ä¸­ã§ã¯ï¼Œ
+% \textbf{JAchar}ã‚’å称ã®ä¸€éƒ¨ã«å«ã‚€åˆ¶å¾¡ç¶´ã¯ä½¿ç”¨ä¸å¯èƒ½}ã§ã‚る.
+% 例ãˆã°æ¬¡ã®ã‚ˆã†ãªå…¥åŠ›ã‚’考ãˆã‚ˆã†ï¼š
+% %</ja>
+% \begin{verbatim*}
+% \begin{lstlisting}[escapechar=\#]
+% #\ã»ã’ xã´ã‚ˆ#
+% \end{lstlisting}
+% \end{verbatim*}
+% %<en>The line~2 is transformed by the callback to
+% %<ja>ã“ã“ã§ï¼Œ2行目㯠\verb+process_input_buffer+ ã®ä½œç”¨ã«ã‚ˆã‚Šï¼Œ
+% \begin{lstlisting}[showspaces, escapechar=\!]
+% #\!\IVSA FFFFF!ã»!\IVSA FFFFF!ã’ x!\IVSA FFFFF!ã´!\IVSA FFFFF!よ#
+% \end{lstlisting}
+% %<*en>
+% before the line is actually processed.
+% In the escape (between the character ``\verb+#+''),
+% the category code of \texttt{U+FFFFF} is set to 9~(\emph{ignored}).
+% Hence the control symbol ``\cs{}\IVSA FFFFF'' will be executed,
+% instead of ``\verb+\ã»ã’+''.
+% %</en>
+% %<*ja>
+% ã¨å¤‰æ›ã•ã‚Œã¦ã‹ã‚‰ï¼Œå®Ÿéš›ã®å‡¦ç†ã«å›žã•ã‚Œã‚‹ï¼Ž
+% 「\verb+#+ã€ã§æŒŸã¾ã‚ŒãŸã€Œ\LaTeX ã¸ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã€ä¸­ã§ã¯\
+% \texttt{U+FFFFF} ã®ã‚«ãƒ†ã‚´ãƒªãƒ¼ã‚³ãƒ¼ãƒ‰ã¯9~(\textit{ignored})ã¨ãªã‚‹ã®ã§ï¼Œ
+% çµå±€ã€Œ\verb+\ã»ã’+ã€ã®ä»£ã‚ã‚Šã«
+% 「\cs{}\IVSA FFFFFã€ã¨ã„ã†control symbolãŒå®Ÿè¡Œã•ã‚Œã‚‹ã“ã¨ã«ãªã‚‹ï¼Ž
+% %</ja>
+
+%<*en>
+\paragraph{Variation selectors}
+\Pkg{lltjp-listings} add two keys, namely \texttt{vsraw}~and~\texttt{vscmd},
+which specify how variation selectors are treated in
+\texttt{lstlisting} or other enviroments.
+Note that these additional keys are not usable in the preamble,
+since \Pkg{lltjp-listings} is loaded at \verb+\begin{document}+.
+
+\texttt{vsraw} is a key which takes a boolean value, and its default value is
+false.
+\begin{itemize}
+ \item If the \texttt{vsraw} key is true, then
+variation selectors are ``combined'' with the previous character.
+%</en>
+%<*ja>
+\paragraph{異体字セレクタã®æ‰±ã„}
+\texttt{lstlisting} 環境ãªã©ã®å†…部ã«ã‚る異体字セレクタを扱ã†ãŸã‚,
+\Pkg{lltjp-listings} ã§ã¯ \texttt{vsraw} 㨠\texttt{vscmd} ã¨ã„ã†2ã¤ã®ã‚­ãƒ¼ã‚’追加ã—ãŸï¼Ž
+ã—ã‹ã—,\Pkg{lltjp-listings} ãŒå®Ÿéš›ã«èª­ã¿è¾¼ã¾ã‚Œã‚‹ã®ã¯ \verb+\begin{document}+\
+ã®ã¨ã“ã‚ã§ã‚ã‚‹ã®ã§ï¼Œãƒ—リアンブル内ã§ã¯ã“れらã®è¿½åŠ ã‚­ãƒ¼ã¯ä½¿ç”¨ã§ããªã„.
+
+\texttt{vsraw}ã¯ï¼Œãƒ–ール値ã®å€¤ã‚’ã¨ã‚‹ã‚­ãƒ¼ã§ã‚り,標準ã§ã¯falseã§ã‚る.
+\begin{itemize}
+ \item trueã®å ´åˆã¯ï¼Œç•°ä½“字セレクタã¯ã€Œç›´å‰ã®æ–‡å­—ã«ç¶šã‘ã¦ã€å‡ºåŠ›ã•ã‚Œã‚‹ï¼Ž
+ã‚‚ã—ã‚‚IVSサãƒãƒ¼ãƒˆï¼ˆ\ref{ssec:ltjotf}節)ãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ãŸå ´åˆã¯ï¼Œ
+以下ã®ä¾‹ï¼ˆå·¦å´ã¯å…¥åŠ›ï¼Œå³å´ã¯ãã®å‡ºåŠ›ï¼‰ã®ã‚ˆã†ã«ãªã‚‹ï¼Ž
+%</ja>
+\begin{LTXexample}
+\begin{lstlisting}[vsraw=true]
+葛󠄀城市,葛ó „飾区,葛西
+\end{lstlisting}
+\end{LTXexample}
+%<*en>
+\item If the \texttt{vsraw} key is false, then
+variation selectors are typeset by an appropriate command, which is specified by
+ the \texttt{vscmd} key.
+The default setting of the \texttt{vscmd} key produces the following.
+%</en>
+%<*ja>
+\item falseã®å ´åˆã¯ï¼Œç•°ä½“字セレクタã¯é©å½“ãªå‘½ä»¤ã«ã‚ˆã£ã¦ã€Œè¦‹ãˆã‚‹å½¢ã§ã€å‡ºåŠ›ã•ã‚Œã‚‹ï¼Ž
+ã©ã®ã‚ˆã†ãªå½¢ã§å‡ºåŠ›ã•ã‚Œã‚‹ã‹ã‚’è¦å®šã™ã‚‹ã®ãŒ \texttt{vscmd} キーã§ã‚り,
+\Pkg{lltjp-listings} ã®æ¨™æº–設定ã§ã¯ä»¥ä¸‹ã®ä¾‹ã®å³å´ã®ã‚ˆã†ã«å‡ºåŠ›ã•ã‚Œã‚‹ï¼Ž
+%</ja>
+\begin{LTXexample}
+\begin{lstlisting}[vsraw=false,
+ vscmd=\ltjlistingsvsstdcmd]
+葛󠄀城市,葛ó „飾区,葛西
+\end{lstlisting}
+\end{LTXexample}
+%<ja> ã¡ãªã¿ã«ï¼Œæœ¬ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã§ã¯æ¬¡ã®ã‚ˆã†ã«ã—ã¦ã„る:
+%<en> For example, the following code is the setting of the \texttt{vscmd} key in this document.
+\begin{lstlisting}[numbers=left]
+\def\IVSA#1#2#3#4#5{%
+ \textcolor{blue}{\raisebox{3.5pt}{\tt%
+ \fboxsep=0.5pt\fbox{\tiny \oalign{0#1#2\crcr#3#4#5\crcr}}}}%
+}
+{\catcode`\%=11
+ \gdef\IVSB#1{\expandafter\IVSA\directlua{
+ local cat_str = luatexbase.catcodetables['string']
+ tex.sprint(cat_str, string.format('%X', 0xE00EF+#1))
+}}}
+\lstset{vscmd=\IVSB}
+\end{lstlisting}
+\end{itemize}
+%<*en>
+The default output command of variation selectors is stored in \verb+\ltjlistingsvsstdcmd+.
+%</en>
+%<*ja>
+既定ã®å‡ºåŠ›å‘½ä»¤ã‚’復活ã•ã›ãŸã„å ´åˆã¯\ \verb+vscmd=\ltjlistingsvsstdcmd+\
+ã¨ã™ã‚Œã°è‰¯ã„.
+%</ja>
+
+%<*en>
+\paragraph{The \texttt{doubleletterspace} key}
+Even the column format is \texttt{[c]fixed}, sometimes characters are not vertically aligned.
+The following example is typeset with \texttt{basewidth=2em}, and
+you'll see the leftmost ``\texttt{H}'' are not vertically aligned.
+\begin{lstlisting}[basewidth=2em, basicstyle=\tt,numbers=left]
+:H:
+:HHHH:
+\end{lstlisting}
+
+\Pkg{lltjp-listing} adds the \texttt{doubleletterspace} key (not activated by default, for
+compatibility) to
+improve the situation, namely doubles inter-character space in each output unit.
+With this key, the above input now produces better output.
+\begin{lstlisting}[basewidth=2em, basicstyle=\tt,numbers=left, doubleletterspace]
+:H:
+:HHHH:
+\end{lstlisting}
+%</en>
+%<*ja>
+\paragraph{\texttt{doubleletterspace}キー}
+\Pkg{listings}パッケージã§åˆ—æƒãˆãŒ \texttt{[c]fixed} ã¨ãªã£ã¦ã„ã‚‹å ´åˆã§ã‚‚,
+å ´åˆã«ã‚ˆã£ã¦ã¯æ–‡å­—ãŒç¸¦ã«æƒã‚ãªã„å ´åˆã‚‚ã‚る.
+例を以下ã«ç¤ºãã†ï¼Žã“ã‚Œã¯å¼·èª¿ã™ã‚‹ãŸã‚ã« \texttt{basewidth=2em} を設定ã—ã¦ã„る.
+\begin{lstlisting}[basewidth=2em, basicstyle=\tt,numbers=left]
+:H:
+:HHHH:
+\end{lstlisting}
+1行目ã¨2行目ã®ã€Œ\texttt{H}ã€ã®ä½ç½®ãŒæƒã£ã¦ã„ãªã„ãŒï¼Œ
+ã“ã‚Œã¯å‡ºåŠ›å˜ä½ã”ã¨ã«ï¼Œå…ˆé ­ãƒ»æœ«å°¾ãƒ»å„文字間ã«åŒã˜é‡ã®ç©ºç™½ã‚’挿入ã™ã‚‹ã“ã¨ã«ã‚ˆã‚‹ï¼Ž
+
+\Pkg{lltjp-listing}ã§ã¯ï¼Œã“ã®ã‚ˆã†ãªç—‡çŠ¶ã‚’改善ã•ã›ã‚‹ãŸã‚ã« \texttt{doubleletterspace} キー
+を追加ã—ãŸï¼ˆæ¨™æº–ã§ã¯äº’æ›æ€§ã®ãŸã‚ã«ç„¡åŠ¹ã«ãªã£ã¦ã„る).ã“ã®ã‚­ãƒ¼ã‚’有効ã«ã™ã‚‹ã¨ï¼Œ
+出力å˜ä½ä¸­ã®å„文字間ã®ç©ºç™½ã‚’2å€ã«ã™ã‚‹ã“ã¨ã§æ–‡å­—ã‚’æƒã„ã‚„ã™ãã—ã¦ã„る.
+上ã¨åŒã˜ã‚‚ã®ã‚’ \texttt{doubleletterspace} キーを有効ã«ã—ã¦çµ„ã‚“ã ã‚‚ã®ãŒä»¥ä¸‹ã§ã‚り,
+ãã¡ã‚“ã¨ã€Œ\texttt{H}ã€ã®ä½ç½®ãŒæƒã£ã¦ã„ã‚‹ã“ã¨ãŒåˆ†ã‹ã‚‹ï¼Ž
+\begin{lstlisting}[basewidth=2em, basicstyle=\tt,numbers=left, doubleletterspace]
+:H:
+:HHHH:
+\end{lstlisting}
+%</ja>
+
+%<en>\subsection{Class of characters}
+%<ja>\subsection{文字種}
+
+%<en>Roughly speaking, the \Pkg{listings} package processes input as follows:
+%<ja>\Pkg{listings} パッケージã®å†…部ã§ã¯ï¼Œå¤§é›‘把ã«è¨€ã†ã¨
+\begin{enumerate}
+%<en>\item Collects \textit{letters} and \textit{digits}, which can be used for the name of identifiers.
+%<ja>\item 識別å­ã¨ã—ã¦ä½¿ãˆã‚‹æ–‡å­— (``letter'',~``digit'') ãŸã¡ã‚’集ã‚る.
+%<en>\item When reading an \textit{other}, outputs the collected character string (with modification, if needed).
+%<ja>\item letterã§ã‚‚digitã§ã‚‚ãªã„文字ãŒç¾ã‚ŒãŸæ™‚ã«ï¼ŒåŽé›†ã—ãŸæ–‡å­—列を(必è¦ãªã‚‰ä¿®é£¾ã—ã¦ï¼‰å‡ºåŠ›ã™ã‚‹ï¼Ž
+%<en>\item Collects \textit{others}.
+%<ja>\item 今度ã¯é€†ã«ï¼Œletterã§ãªã„文字ãŸã¡ã‚’letterãŒç¾ã‚Œã‚‹ã¾ã§é›†ã‚る.
+%<en>\item When reading a \textit{letter} or a \textit{digit}, outputs the collected character string.
+%<ja>\item letterãŒå‡ºç¾ã—ãŸã‚‰é›†ã‚ãŸæ–‡å­—列を出力ã™ã‚‹ï¼Ž
+%<en>\item Turns back to 1.
+%<ja>\item 1.ã«æˆ»ã‚‹ï¼Ž
+\end{enumerate}
+%<*en>
+By the above process, line breaks inside of an identifier are blocked.
+A flag \verb+\lst@ifletter+ indicates whether the previous character can be used
+for the name of identifiers or not.
+%</en>
+%<*ja>
+ã¨ã„ã†å‡¦ç†ãŒè¡Œã‚ã‚Œã¦ã„る.ã“ã‚Œã«ã‚ˆã‚Šï¼Œè­˜åˆ¥å­ã®é€”中ã§ã¯è¡Œåˆ†å‰²ãŒè¡Œã‚ã‚Œãªã„よã†ã«ãªã£ã¦ã„る.
+ç›´å‰ã®æ–‡å­—ãŒè­˜åˆ¥å­ã¨ã—ã¦ä½¿ãˆã‚‹ã‹å¦ã‹ã¯ \verb+\lst@ifletter+ ã¨ã„ã†ãƒ•ãƒ©ã‚°ã«æ ¼ç´ã•ã‚Œã¦ã„る.
+%</ja>
+
+%<*en>
+For Japanese characters, line breaks are permitted on both sides
+except for brackets, dashes, etc.
+Hence the patch \Pkg{lltjp-listings} introduces
+a new flag \verb+\lst@ifkanji+, which indicates
+whether the previous character is a Japanese character or not.
+For illustration, we introduce following classes of characters:
+%</en>
+%<*ja>
+ã•ã¦ï¼Œæ—¥æœ¬èªžã®å‡¦ç†ã§ã‚る.殆ã©ã®å’Œæ–‡æ–‡å­—ã®å‰å¾Œã§ã¯è¡Œåˆ†å‰²ãŒå¯èƒ½ã§ã‚ã‚‹ãŒï¼Œãã®ä¸€æ–¹ã§
+括弧類や音引ããªã©ã§ã¯ç¦å‰‡å‡¦ç†ãŒå¿…è¦ãªã“ã¨ã‹ã‚‰ï¼Œ\Pkg{lltjp-listings} ã§ã¯ï¼Œ
+ç›´å‰ãŒå’Œæ–‡æ–‡å­—ã§ã‚ã‚‹ã‹ã‚’示ã™ãƒ•ãƒ©ã‚° \verb+\lst@ifkanji+ ã‚’æ–°ãŸã«å°Žå…¥ã—ãŸï¼Ž
+以é™ï¼Œèª¬æ˜Žã®ãŸã‚ã«ä»¥ä¸‹ã®ã‚ˆã†ã«æ–‡å­—を分類ã™ã‚‹ï¼š
+%</ja>
+%<*ja>
+\begin{center}
+\small
+\begin{tabular}{llllll}
+\toprule
+&\emph{Letter}&\emph{Other}&\emph{Kanji}&\emph{Open}&\emph{Close}\\\midrule
+\verb+\lst@ifletter+&T&F&T&F&T\\
+\verb+\lst@ifkanji+&F&F&T&T&F\\
+\emph{æ„図}&識別å­ä¸­ã®æ–‡å­—&ãã®ä»–欧文文字&殆ã©ã®å’Œæ–‡æ–‡å­—&é–‹ã括弧類&é–‰ã˜æ‹¬å¼§é¡ž\\
+\bottomrule
+\end{tabular}
+\end{center}
+%</ja>
+%<*en>
+\begin{center}
+\small
+\begin{tabular}{llll}
+\toprule
+&\textbf{Letter}&\textbf{Other}&\\\midrule
+\verb+\lst@ifletter+&T&F&\\
+\verb+\lst@ifkanji+&F&F&\\
+\textbf{Meaning}&char in an identifier&other alphabet&\\
+ \midrule
+&\textbf{Kanji}&\textbf{Open}&\textbf{Close}\\\midrule
+\verb+\lst@ifletter+&T&F&T\\
+\verb+\lst@ifkanji+&T&T&F\\
+\textbf{Meaning}&most of Japanese char&opening brackets&closing brackets\\
+\bottomrule
+\end{tabular}
+\end{center}
+%</en>
+%<*en>
+Note that \textit{digits} in the \Pkg{listings} package can be Letter or
+Other according to circumstances.
+%</en>
+%<*ja>
+ãªãŠï¼Œæœ¬æ¥ã®\Pkg{listings} パッケージã§ã®åˆ†é¡ž``digit''ã¯ï¼Œ
+出ç¾çŠ¶æ³ã«ã‚ˆã£ã¦ï¼Œä¸Šã®è¡¨ã®Letterã¨Otherã®ã©ã¡ã‚‰ã«ã‚‚ãªã‚Šã†ã‚‹ï¼Ž
+ã¾ãŸï¼ŒKanjiã¨Close㯠\verb+\lst@ifletter+ 㨠\verb+\lst@ifkanji+ ã®å€¤ãŒä¸€è‡´ã—ã¦ã„ã‚‹ãŒï¼Œ
+ã“ã‚Œã¯é–“é•ã„ã§ã¯ãªã„.
+%</ja>
+
+%<*en>
+For example, let us consider the case an Open comes after a Letter.
+Since an Open represents Japanese open brackets,
+it is preferred to be permitted to insert line break after the Letter.
+Therefore, the collected character string is output in this case.
+%</en>
+%<*ja>
+例ãˆã°ï¼ŒLetterã®ç›´å¾Œã«OpenãŒæ¥ãŸå ´åˆã‚’考ãˆã‚‹ï¼Ž
+文字種Openã¯å’Œæ–‡é–‹ã括弧類を想定ã—ã¦ã„ã‚‹ã®ã§ï¼ŒLetterã®ç›´å¾Œã§ã¯è¡Œåˆ†å‰²ãŒå¯èƒ½ã§ã‚ã‚‹ã“ã¨ãŒæœ›ã¾ã—ã„.
+ãã®ãŸã‚,ã“ã®å ´åˆã§ã¯ï¼Œã™ã§ã«åŽé›†ã•ã‚Œã¦ã„る文字列を出力ã™ã‚‹ã“ã¨ã§è¡Œåˆ†å‰²ã‚’許容ã™ã‚‹ã‚ˆã†ã«ã—ãŸï¼Ž
+%</ja>
+
+%<*en>
+The following table summarizes $5\times 5=25$ cases:
+%</en>
+%<*ja>
+åŒã˜ã‚ˆã†ã«ï¼Œ$5\times 5=25$通り全ã¦ã«ã¤ã„ã¦æ›¸ãã¨ï¼Œæ¬¡ã®ã‚ˆã†ã«ãªã‚‹ï¼š
+%</ja>
+\begin{center}
+\small
+\begin{tabular}{lllllll}
+\toprule
+%<*en>
+&&\multicolumn{4}{c}{\textbf{Next}}\\\cmidrule(lr){3-7}
+&&\hbox to 4em{Letter\hss}&\hbox to 4em{Other\hss}
+&\hbox to 4em{Kanji\hss}&\hbox to 4em{Open\hss}&Close\\\midrule
+&Letter&collects&\multicolumn{3}{c}{\hrulefill \ outputs\ \hrulefill}&collects\\
+&Other&outputs&collects&\multicolumn{2}{c}{\hrulefill \ outputs\ \hrulefill}&collects\\
+\textbf{Prev}&Kanji&\multicolumn{4}{c}{\hrulefill \ outputs\ \hrulefill}&collects\\
+&Open&\multicolumn{5}{c}{\hrulefill \ collects\ \hrulefill}\\
+&Close&\multicolumn{4}{c}{\hrulefill \ outputs\ \hrulefill}&collects\\
+%</en>
+%<*ja>
+&&\multicolumn{4}{c}{\textbf{後å´æ–‡å­—種}}\\\cmidrule(lr){3-7}
+&&\hbox to 4em{Letter\hss}&\hbox to 4em{Other\hss}
+&\hbox to 4em{Kanji\hss}&\hbox to 4em{Open\hss}&Close\\\midrule
+\emph{ç›´}&Letter&åŽé›†&\multicolumn{3}{c}{\hrulefill \ 出力\ \hrulefill}&åŽé›†\\
+\emph{å‰}&Other&出力&åŽé›†&\multicolumn{2}{c}{\hrulefill \ 出力\ \hrulefill}&åŽé›†\\
+\emph{æ–‡}&Kanji&\multicolumn{4}{c}{\hrulefill \ 出力\ \hrulefill}&åŽé›†\\
+\emph{å­—}&Open&\multicolumn{5}{c}{\hrulefill \ åŽé›†\ \hrulefill}\\
+\emph{種}&Close&\multicolumn{4}{c}{\hrulefill \ 出力\ \hrulefill}&åŽé›†\\
+%</ja>
+\bottomrule
+\end{tabular}
+\end{center}
+%<en>In the above table,
+%<ja>上ã®è¡¨ã«ãŠã„ã¦ï¼Œ
+\begin{itemize}
+%<en>\item ``outputs'' means to output the collected character string (i.e., line breaking is permitted there).
+%<ja>\item 「出力ã€ã¯ï¼Œãã‚Œã¾ã§ã«é›†ã‚ãŸæ–‡å­—列を出力(≒ã“ã“ã§è¡Œåˆ†å‰²å¯èƒ½ï¼‰ã‚’æ„味ã™ã‚‹ï¼Ž
+
+%<en>\item ``collects'' means to append the next character to the collected character string (i.e., line breaking is prohibited there).
+%<ja>\item 「åŽé›†ã€ã¯ï¼Œå¾Œå´ã®æ–‡å­—を,ç¾åœ¨åŽé›†ã•ã‚ŒãŸæ–‡å­—列ã«è¿½åŠ ï¼ˆè¡Œåˆ†å‰²ä¸å¯ï¼‰ã‚’æ„味ã™ã‚‹ï¼Ž
+\end{itemize}
+
+%<*en>
+Characters above or equal to~\texttt{U+0080} \emph{except Variation Selectors}
+are classified into above 5~classes by the following rules:
+%</en>
+%<*ja>
+\texttt{U+0080}以é™ã®\emph{異体字セレクタ以外ã®}å„文字ãŒ
+Letter, Other, Kanji, Open, Closeã®ã©ã‚Œã«å±žã™ã‚‹ã‹ã¯æ¬¡ã«ã‚ˆã£ã¦æ±ºã¾ã‚‹ï¼š
+%</ja>
+\begin{itemize}
+%<en>\item \textbf{ALchar}s above or equal to~\texttt{U+0080} are classified as Letter.
+%<ja>\item \<(\texttt{U+0080}以é™ã®ï¼‰\textbf{ALchar}ã¯ï¼Œã™ã¹ã¦Letter扱ã„ã§ã‚る.
+
+%<en>\item \textbf{JAchar}s are classified in the order as follows:
+%<ja>\item \textbf{JAchar}ã«ã¤ã„ã¦ã¯ï¼Œä»¥ä¸‹ã®é †åºã«å¾“ã£ã¦æ–‡å­—種を決ã‚る:
+\begin{enumerate}
+%<en>\item Characters whose \Param{prebreakpenalty} is greater than or equal to 0 are classified as Open.
+%<ja>\item \Param{prebreakpenalty}ãŒ0以上ã®æ–‡å­—ã¯Open扱ã„ã§ã‚る.
+
+%<en>\item Characters whose \Param{postbreakpenalty} is greater than or equal to 0 are classified as Close.
+%<ja>\item \Param{postbreakpenalty}ãŒ0以上ã®æ–‡å­—ã¯Close扱ã„ã§ã‚る.
+
+%<en>\item Characters that don't satisfy the above two conditions are classified as Kanji.
+%<ja>\item 上ã®3æ¡ä»¶ã®ã©ã¡ã‚‰ã«ã‚‚当ã¦ã¯ã¾ã‚‰ãªã‹ã£ãŸæ–‡å­—ã¯ï¼ŒKanji扱ã„ã§ã‚る.
+\end{enumerate}
+\end{itemize}
+
+%<*en>
+The width of halfwidth kana (\texttt{U+FF61}--\texttt{U+FF9F})
+is same as the width of \textbf{ALchar};
+the width of the other \textbf{JAchar}s is double the width of \textbf{ALchar}.
+%</en>
+%<*ja>
+ãªãŠï¼ŒåŠè§’カナ(U+FF61--U+FF9F)以外ã®\textbf{JAchar}ã¯æ¬§æ–‡æ–‡å­—2文字分ã®å¹…ã‚’ã¨ã‚‹ã‚‚ã®ã¨ã¿ãªã•ã‚Œã‚‹ï¼Ž
+åŠè§’カナã¯æ¬§æ–‡æ–‡å­—1文字分ã®å¹…ã¨ãªã‚‹ï¼Ž
+%</ja>
+
+%<*en>
+This classification process is executed every time a character appears in
+the \texttt{lstlisting} environment or other environments/commands.
+%</en>
+%<*ja>
+ã“れらã®æ–‡å­—種決定ã¯ï¼Œå®Ÿéš›ã« \texttt{lstlisting} 環境ãªã©ã®å†…部ã§æ–‡å­—ãŒå‡ºã¦ãã‚‹ãŸã³ã«è¡Œã‚れる.
+%</ja>
+
+%<*ja>
+\section{和文ã®è¡Œé•·è£œæ­£æ–¹æ³•}
+\label{sec-adjspec}
+\Pkg{luatexja-adjust}ã§æä¾›ã•ã‚Œã‚‹å„ªå…ˆé †ä½ä»˜ãã®è¡Œé•·èª¿æ•´ã®è©³ç´°ã‚’大ã¾ã‹ã«è¿°ã¹ã‚‹ã¨ï¼Œæ¬¡ã®ã‚ˆã†ã«ãªã‚‹ï¼Ž
+\begin{itemize}
+\item (\texttt{lineend=extended}ã®å ´åˆï¼‰\textbf{JAglue}ã®æŒ¿å…¥å‡¦ç†ã®ã¨ã“ã‚ã§ï¼Œ
+ ……
+\item 通常ã®\TeX ã®è¡Œåˆ†å‰²æ–¹æ³•ã«å¾“ã£ã¦ï¼Œæ®µè½ã‚’行分割ã™ã‚‹ï¼Žã“ã®æ®µéšŽã§ã¯ï¼Œè¡Œ
+ é•·ã«åŠç«¯ãŒå‡ºãŸå ´åˆï¼Œãã®åŠç«¯åˆ†ã¯\textbf{JAglue}(\Param{xkanjiskip},
+ \Param{kanjiskip},JFMグルー)ã¨
+ ãれ以外ã®ã‚°ãƒ«ãƒ¼ã®å…¨ã¦ã§ï¼ˆå„ªå…ˆé †ä½ãªã)負担ã•ã‚Œã‚‹ï¼Ž
+\item ãã®å¾Œï¼Œ\texttt{post\_linebreak\_filter} callbackを使ã„,\emph{段
+ è½ä¸­ã®å„è¡Œã”ã¨ã«},行末文字ã®ä½ç½®ã‚’調整(\texttt{lineend=true}ã®å ´åˆï¼‰ã—ãŸã‚Šï¼Œå„ªå…ˆåº¦ä»˜ãã®è¡Œé•·èª¿æ•´
+ を実ç¾ã™ã‚‹ãŸã‚ã«ã‚°ãƒ«ãƒ¼ã®ä¼¸ç¸®åº¦ã‚’調整ã™ã‚‹ï¼Ž
+ ãã®å‡¦ç†ã«ãŠã„ã¦ã¯ï¼Œã‚°ãƒ«ãƒ¼ã®è‡ªç„¶é•·ã¨\textbf{JAglue}以外ã®
+ グルーã®ä¼¸ã³é‡ãƒ»ç¸®ã¿é‡ã¯å¤‰æ›´ã›ãšï¼Œå¿…è¦ã«å¿œã˜ã¦\textbf{JAglue}ã®ä¼¸ã³é‡ãƒ»ç¸®ã¿é‡ã®ã¿ã‚’
+ 変更ã™ã‚‹è¨­è¨ˆã¨ã—ãŸï¼Ž
+\end{itemize}
+ã“ã®ç« ã®æ®‹ã‚Šã§ã¯å„処ç†ã«ã¤ã„ã¦è§£èª¬ã™ã‚‹ï¼Ž
+
+\paragraph{準備:åˆè¨ˆä¼¸ç¸®é‡ã®è¨ˆç®—}
+グルーã®ä¼¸ç¸®åº¦ï¼ˆ\texttt{plus} ã‚„ \texttt{minus} ã§æŒ‡å®šã•ã‚Œã¦ã„る値)ã«ã¯ï¼Œ
+有é™å€¤ã®ä»–ã«ï¼Œ\texttt{fi},\texttt{fil},\texttt{fill},\texttt{filll}ã¨
+ã„ã†4ã¤ã®ç„¡é™å¤§ãƒ¬ãƒ™ãƒ«ï¼ˆå¾Œã‚ã®æ–¹ã»ã©å¤§ãã„)ãŒã‚る.行ã®èª¿æ•´ã«
+\texttt{fi} ãªã©ã®\emph{ç„¡é™å¤§ãƒ¬ãƒ™ãƒ«ã®ä¼¸ç¸®åº¦ãŒç”¨ã„られã¦ã„ã‚‹è¡Œã§ã¯ï¼Œ
+「行末文字ã®ä½ç½®èª¿æ•´ã€ã®ã¿è¡Œã„,「グルーã®èª¿æ•´ã€ã¯è¡Œã‚ãªã„.}
+
+ã¾ãšï¼Œæ®µè½ä¸­ã®è¡Œä¸­ã®ã‚°ãƒ«ãƒ¼ã‚’
+\begin{itemize}
+\item \textbf{JAglue}ã§ã¯ãªã„グルー
+\item JFMグルー(優先度\footnote{%
+ \ref{ssec:jfm-str}節ã«ã‚るよã†ã«ï¼Œ
+ å„JFMグルーã«ã¯$-4$ã‹ã‚‰3ã¾ã§ã®å„ªå…ˆåº¦ãŒã¤ã„ã¦ã„る.場åˆã«ã‚ˆã£ã¦ã¯
+ 伸ã³ã¨ç¸®ã¿ã§ç•°ãªã‚‹å„ªå…ˆåº¦ãŒä»˜ã„ã¦ã„ã‚‹ã‹ã‚‚ã—ã‚Œãªã„.}%
+別ã«ã¾ã¨ã‚られる)
+\item 和欧文間空白(\Param{xkanjiskip})
+\item 和文間空白(\Param{kanjiskip})
+\end{itemize}
+ã®$1+1+8+1=10$ã¤ã«é¡žåˆ¥ã™ã‚‹ï¼Ž
+ãã—ã¦è¨±å®¹ã•ã‚Œã¦ã„る伸ã³é‡ï¼ˆ\texttt{stretch}ã®å€¤ï¼‰ã®åˆè¨ˆã‚’
+ç„¡é™ã®ãƒ¬ãƒ™ãƒ«ã”ã¨ã«
+\begin{align*}
+ T^{+}_{l}&:= \sum_{\text{$\texttt{stretch\_order}(p) = l$}} \texttt{stretch}(p),&
+ l\in \{\text{(finite)}, \texttt{fi}, \texttt{fil}, \texttt{fill}, \texttt{filll}\}
+\end{align*}
+ã¨è¨ˆç®—ã™ã‚‹ï¼Žã•ã‚‰ã«ï¼Œ
+\begin{align*}
+T^{+}&:=T^{+}_{L^+},&L^{+} = \max \{l\in
+ \{\text{(finite)}, \texttt{fi}, \texttt{fil}, \texttt{fill}, \texttt{filll}\}:
+ T^{+}_l\neq 0\}
+\end{align*}
+ã¨ãŠã.有é™ã®ä¼¸ã³é‡ã«ã¤ã„ã¦ã¯ï¼Œä¸Šè¨˜ã®8種類ã®é¡žåˆ¥ã”ã¨ã«ã‚‚åˆè¨ˆã‚’計算ã™ã‚‹ï¼Ž
+ã•ã‚‰ã«ç¸®ã¿é‡ï¼ˆ\texttt{shrink}ã®å€¤ï¼‰ã«ã¤ã„ã¦ã‚‚åŒæ§˜ã®å‡¦ç†ã‚’è¡Œã„,$T^{-}$を計算ã™ã‚‹ï¼Ž
+
+ã¾ãŸï¼Œè¡Œé•·ã‹ã‚‰è‡ªç„¶é•·ã‚’引ã„ãŸå€¤ã‚’\textit{total}ã¨ãŠã.
+
+\subsection{行末文字ã®ä½ç½®èª¿æ•´ï¼ˆè¡Œåˆ†å‰²å¾Œã®å ´åˆï¼‰}
+行末ãŒ\textbf{JAchar}ã§ã‚り,ã“ã®æ–‡å­—ã®å±žã™ã‚‹æ–‡å­—クラスã§ã¯
+\begin{quote}
+ \texttt{end\_adjust = \{$a_{1}$, $a_{2}$, ..., $a_{n}$\}}
+\end{quote}
+ã§ã‚ã£ãŸã¨ã™ã‚‹ï¼Ž
+ã“ã®ã¨ã,以下ã®æ¡ä»¶ã‚’満ãŸã—ãŸå ´åˆï¼Œ
+ã“ã®æ–‡å­—クラスã«å¯¾ã™ã‚‹\texttt{end\_adjust}ã®å€¤ã®ã„ãšã‚Œã‹ã ã‘ã“ã®æ–‡å­—ã®ä½ç½®ã‚’移動ã•ã›ã‚‹ï¼Ž
+\begin{description}
+ \item[最終行以外] 行長調整ã«ç„¡é™å¤§ã®ä¼¸ç¸®åº¦ãŒç”¨ã„られã¦ã„ãªã„.
+ ã™ãªã‚ã¡ï¼Œ$\textit{total}>0$ãªã‚‰ã°$L^{+}=(\text{finite})$ã§ã‚り,
+ $\textit{total}>0$ãªã‚‰ã°$L^{-}=(\text{finite})$ã§ã‚る.
+ \item[最終行] 行長調整ã«ç„¡é™å¤§ã«ä¼¸ã³ç¸®ã¿ã™ã‚‹ã‚°ãƒ«ãƒ¼ãŒç”¨ã„られãŸãªã‚‰ï¼Œãã‚Œã¯\cs{parfillskip}ã®ã¿ã§ã‚り,
+ ã‹ã¤ï¼Œæ¬¡ã®ä¸ç­‰å¼ãŒæˆç«‹ã™ã‚‹ï¼š
+ \[
+ \min\{0,a_{1}\}\text{\cs{zw}}\leq (\text{\cs{parfillskip}ã®å®Ÿéš›ã®é•·ã•}) \leq \max\{0,a_{n}\}\text{\cs{zw}}
+ \]
+\end{description}
+
+å„$1\leq i\leq n$ã«å¯¾ã—ã¦ï¼Œ
+「行末ã«$a_{i}$全角ã ã‘ã®ã‚«ãƒ¼ãƒ³ã‚’追加ã—ãŸæ™‚ã®ï¼Œ\textit{glue\_set}ã®å€¤ã€ã‚’
+$b_{i}$ã¨ãŠã.å¼ã§æ›¸ãã¨ï¼Œ
+\[
+\catcode`\<=12
+b_{i} = \begin{cases}
+ |\textit{total}-a_{i}\text{\cs{zw}}|/T^{+}
+ &(\textit{total}-a_{i}\text{\cs{zw}}\geq 0)\\
+ |\textit{total}-a_{i}\text{\cs{zw}}|/T^{-}
+ &(\textit{total}-a_{i}\text{\cs{zw}}<0)
+\end{cases}.
+\]
+$b_{i}$é”ã®æœ€å°å€¤ã‚’与ãˆã‚‹ã‚ˆã†ãª$i$ã‚’$j$ã¨ã—ãŸã¨ã\footnote{%
+ ãã®ã‚ˆã†ãª$i$ãŒ2ã¤ä»¥ä¸Šã‚ã‚‹ã¨ãã¯ï¼Œ$|\textit{total}-a_{i}\cdot \text{\cs{zw}}|$,
+ $|a_{i}|$, $a_i$ã®é †ã§æ¯”較ã—ã¦ä¸€ç•ªå°ã•ããªã‚‹ã‚‚ã®ãŒé¸ã°ã‚Œã‚‹ï¼Ž
+},
+行末ã«å¤§ãã•$a_{j}$ã®ã‚«ãƒ¼ãƒ³ã‚’追加ã™ã‚‹ï¼Ž
+\textit{total}ã‹ã‚‰$a_{j}$全角ã®å¤§ãã•ã ã‘引ã„ã¦ãŠã.
+
+\subsection{行末文字ã®ä½ç½®èª¿æ•´ï¼ˆè¡Œåˆ†å‰²ã§ã®è€ƒæ…®ï¼‰}
+\texttt{lineend=extended}ãŒæŒ‡å®šã•ã‚Œã¦ã„ã‚‹å ´åˆï¼Œ\TeX ã«ã‚ˆã‚‹è¡Œåˆ†å‰²ãŒè¡Œã‚れるå‰ã«
+å„\textbf{JAchar}ã®ç›´å¾Œã«ï¼Œãã®æ–‡å­—ãŒè¡Œæœ«ã«æ¥ãŸã¨ãã®ä½ç½®è£œæ­£ç”¨ã®ãƒŽãƒ¼ãƒ‰ã‚’挿入ã—ã¦ã„ã.
+
+\ref{sec-jfmglue}ç« ã®ç”¨èªžã‚’使ã£ã¦è¿°ã¹ã‚‹ï¼Ž
+å‰å´ã®ã‚¯ãƒ©ã‚¹ã‚¿\textit{Nq}ãŒã€Œå’Œæ–‡Aã€ã€Œå’Œæ–‡Bã€ã§ã‚り,
+JFMã«ã‚ˆã£ã¦\texttt{end\_adjust}ã®å€¤ãŒ
+\begin{quote}
+ \texttt{end\_adjust = \{$a_{1}$, $a_{2}$, ..., $a_{n}$\}}
+\end{quote}
+ã§ã‚ã£ãŸã¨ã™ã‚‹ï¼Žã“ã®ã¨ã,次ã®ã‚¯ãƒ©ã‚¹ã‚¿\textit{Np}ã®ç›´å‰ã«ä»¥ä¸‹ã®ãƒŽãƒ¼ãƒ‰åˆ—を挿入ã™ã‚‹ï¼Ž
+\textbf{JAglue}ã®æŒ¿å…¥éŽç¨‹ã§ç¦å‰‡å‡¦ç†ã®ãŸã‚ã«ã€Œ\textit{Nq}ã¨\textit{Np}ã®é–“ã®ãƒšãƒŠãƒ«ãƒ†ã‚£å€¤ã‚’増やã™ã€ã“ã¨ãŒ
+è¡Œã‚れるã“ã¨ãŒã‚ã‚‹ãŒï¼Œä»¥ä¸‹ã§è¿°ã¹ã‚‰ã‚Œã¦ã„ã‚‹$(n+1)$個ã®ãƒšãƒŠãƒ«ãƒ†ã‚£ã¯ã¿ãªãã®å‡¦ç†å¯¾è±¡ã«ãªã£ã¦ã„る.
+\begin{align*}
+ \Node{kern}{$a_{1}\text{\cs{zw}}$}
+ &\longrightarrow \Node{penalty}{$0$} \longrightarrow\Node{kern}{$(a_{2}-a_{1})\text{\cs{zw}}$}
+ \longrightarrow \Node{penalty}{$0$} \longrightarrow\Node{kern}{$(a_{3}-a_{2})\text{\cs{zw}}$}\\
+ &\longrightarrow
+ \cdots \longrightarrow\Node{penalty}{$0$} \longrightarrow
+ \Node{kern}{$(a_{n}-a_{n-1})\text{\cs{zw}}$}
+ \longrightarrow \Node{penalty}{$0$} \longrightarrow
+ \Node{kern}{$-a_{n}\text{\cs{zw}}$} \longrightarrow \Node{penalty}{$10000$}
+\end{align*}
+$n$個ã‚るペナルティã®ç®‡æ‰€ãŒæ”¹è¡Œå¯èƒ½ç®‡æ‰€ã§ã‚る.ã„ãšã‚Œã‹ã§æ”¹è¡Œã•ã‚ŒãŸå ´åˆã¯ï¼Œ
+ãã®å‰ã«ã‚るカーン($n$箇所ã®ã†ã¡ã©ã“ã§æ”¹è¡Œã—ã¦ã‚‚,åˆè¨ˆã®é•·ã•ã¯$a_{i}$ã®å½¢ï¼‰ã¯è¡Œæœ«ã«æ®‹ã‚‹ãŒï¼Œ
+後ã‚ã®ãƒšãƒŠãƒ«ãƒ†ã‚£ãƒ»ã‚«ãƒ¼ãƒ³ã¯é™¤åŽ»ã•ã‚Œã‚‹ï¼ŽãªãŠï¼Œ$a_1=0$ã®ã¨ãã¯æœ€åˆã®å¹…ãŒ$a_{1}\text{\cs{zw}}$ã®ã‚«ãƒ¼ãƒ³ã¯ä¸è¦ãªã®ã§æŒ¿å…¥ã•ã‚Œãšï¼Œ
+ã•ã‚‰ã«ã‹ã¤$n=1$ã§ã‚ã£ãŸå ´åˆã¯å¾Œã‚ã®ãƒšãƒŠãƒ«ãƒ†ã‚£ã‚‚挿入ã•ã‚Œãªã„.
+
+ãªãŠï¼Œæ®µè½ã®æœ«å°¾ã«ã¯\cs{penalty10000}ã¨\cs{parfillskip}ç”±æ¥ã®ã‚°ãƒ«ãƒ¼ãŒè‡ªå‹•çš„ã«å…¥ã‚‹ãŒï¼Œ
+ã“れらã¨ã®å…¼ã­åˆã„ã®ãŸã‚\emph{最後ã®ã‚¯ãƒ©ã‚¹ã‚¿ã«ã¤ã„ã¦ã¯ä¸Šè¨˜ã®ãƒŽãƒ¼ãƒ‰æŒ¿å…¥å‡¦ç†ã¯è¡Œã‚ã‚Œãªã„}.
+段è½æœ€çµ‚è¡Œã®è¡Œæœ«æ–‡å­—ã®ä½ç½®èª¿æ•´ã¯ï¼Œã™ã§ã«è¿°ã¹ãŸã€Œè¡Œåˆ†å‰²å¾Œã®å ´åˆã€ã«ãŠã‘る最終行ã®å‡¦ç†ã‚’ãã®ã¾ã¾ç”¨ã„ã¦ã„る.
+
+\subsection{グルーã®èª¿æ•´}
+$|\textit{total}|$ã®åˆ†ã ã‘ãŒï¼Œè¡Œä¸­ã®ã‚°ãƒ«ãƒ¼ã®ä¼¸ã³é‡ï¼Œã‚ã‚‹ã„ã¯ç¸®ã¿é‡ã«å¿œã˜ã¦è² æ‹…ã•ã‚Œã‚‹ã“ã¨ã«ãªã‚‹ï¼Ž
+以下,$\textit{total}\geq 0$ã§ã‚ã‚‹ã¨ä»®å®šã—ã¦è©±ã‚’進ã‚ã‚‹ãŒï¼Œè² ã®ã¨ãã‚‚åŒæ§˜ã§ã‚る.
+\Pkg{luatexja-adjust}ã®åˆæœŸå€¤ã§ã¯ä»¥ä¸‹ã®é †ã«ä¼¸ã³é‡ã‚’è² æ‹…ã™ã‚‹ã‚ˆã†ã«ãªã£ã¦ãŠã‚Šï¼Œ
+(優先度$-4$ã®JFMグルーã¯ä¾‹å¤–ã¨ã—ã¦ï¼‰ã§ãã‚‹ã ã‘\Param{kanjiskip}を自然長ã®ã¾ã¾ã«ã™ã‚‹ã“ã¨ã‚’
+試ã¿ã¦ã„る.ã“ã®é †ç•ªã¯\Param{stretch\_priority}(縮ã¿é‡ã«ã¤ã„ã¦ã¯\Param{shrink\_priority})
+パラメータã§å¤‰æ›´å¯èƒ½ã§ã‚る.
+\begin{enumerate}\def\labelenumi{(\Alph{enumi})}
+ \item \textbf{JAglue}以外ã®ã‚°ãƒ«ãƒ¼
+ \item 優先度3ã®JFMグルー
+ \item 優先度2ã®JFMグルー
+ \item 優先度1ã®JFMグルー
+ \item 優先度0ã®JFMグルー
+ \item 優先度$-1$ã®JFMグルー
+ \item 優先度$-2$ã®JFMグルー
+ \item \Param{xkanjiskip}
+ \item 優先度$-3$ã®JFMグルー
+ \item \Param{kanjiskip}
+ \item 優先度$-4$ã®JFMグルー
+\end{enumerate}
+\begin{enumerate}
+ \item 行末ã®\textbf{JAchar}を移動ã—ãŸã“ã¨ã§$\textit{total}=0$ã¨ãªã‚Œã°ï¼Œ
+調整ã®å¿…è¦ã¯ãªã,行ãŒæ ¼ç´ã•ã‚Œã¦ã„ã‚‹hboxã®
+\texttt{glue\_set}, \texttt{glue\_sign}, \texttt{glue\_order}ã‚’å†è¨ˆç®—ã™ã‚Œã°ã‚ˆã„.
+以é™ï¼Œ$\textit{total}\neq 0$ã¨ä»®å®šã™ã‚‹ï¼Ž
+ \item \textit{total}ãŒã€Œ\textbf{JAglue}以外ã®ã‚°ãƒ«ãƒ¼ã®ä¼¸ã³é‡ã®åˆè¨ˆã€ï¼ˆä»¥ä¸‹ï¼Œ(A)ã®ä¼¸ã³é‡ã®
+ åˆè¨ˆï¼Œã¨ç§°ã™ï¼‰ã‚ˆã‚Šã‚‚å°ã•ã‘ã‚Œã°ï¼Œ
+ãれらã®ã‚°ãƒ«ãƒ¼ã«\textit{total}ã‚’è² æ‹…ã•ã›ï¼Œ\textbf{JAglue}é”自身ã¯è‡ªç„¶é•·ã§çµ„ã‚€ã“ã¨ãŒã§ãる.
+よã£ã¦ï¼Œä»¥ä¸‹ã®å‡¦ç†ã‚’è¡Œã†ï¼š
+\begin{enumerate}
+\item å„\textbf{JAglue}ã®ä¼¸ã³é‡ã‚’0ã¨ã™ã‚‹ï¼Ž
+\item è¡ŒãŒæ ¼ç´ã•ã‚Œã¦ã„ã‚‹hboxã®
+\texttt{glue\_set}, \texttt{glue\_sign}, \texttt{glue\_order}ã‚’å†è¨ˆç®—ã™ã‚‹ï¼Ž
+ã“ã‚Œã«ã‚ˆã£ã¦ï¼Œ\textit{total}ã¯\textbf{JAglue}以外ã®ã‚°ãƒ«ãƒ¼ã«ã‚ˆã£ã¦è² æ‹…ã•ã‚Œã‚‹ï¼Ž
+\end{enumerate}
+\item \textit{total}ãŒã€Œ(A)ã®ä¼¸ã³é‡ã®åˆè¨ˆã€ä»¥ä¸Šãªã‚‰ã°ï¼Œ(A)--(K)ã®ã©ã“ã¾ã§è² æ‹…ã™ã‚Œã°
+\textit{total}以上ã«ãªã‚‹ã‹ã‚’計算ã™ã‚‹ï¼Ž
+例ãˆã°ï¼Œ
+\[\catcode`\<=12
+ \textit{total} = (\text{(A)--(B)ã®ä¼¸ã³é‡ã®åˆè¨ˆ}) + p\cdot (\text{(C)ã®ä¼¸ã³é‡ã®åˆè¨ˆ}),
+ \qquad 0\le p<1
+\]
+ã§ã‚ã£ãŸå ´åˆï¼Œå„グルーã¯æ¬¡ã®ã‚ˆã†ã«çµ„ã¾ã‚Œã‚‹ï¼š
+\begin{itemize}
+ \item (A),~(B)ã«å±žã™ã‚‹ã‚°ãƒ«ãƒ¼ã¯å„グルーã§è¨±ã•ã‚ŒãŸä¼¸ã³é‡ã¾ã§ä¼¸ã°ã™ï¼Ž
+ \item (C)ã«å±žã™ã‚‹ã‚°ãƒ«ãƒ¼ã¯ãã‚Œãžã‚Œ$p\times (\text{伸ã³é‡})$ã ã‘伸ã³ã‚‹ï¼Ž
+ \item (D)--(K)ã«å±žã™ã‚‹ã‚°ãƒ«ãƒ¼ã¯è‡ªç„¶é•·ã®ã¾ã¾ï¼Ž
+\end{itemize}
+実際ã«ã¯ï¼Œå‰ã«è¿°ã¹ãŸã€Œè¨­è¨ˆã€ã«å¾“ã„,次ã®ã‚ˆã†ã«å‡¦ç†ã—ã¦ã„る:
+\begin{enumerate}
+\item (C)ã«å±žã™ã‚‹ã‚°ãƒ«ãƒ¼ã®ä¼¸ã³é‡ã‚’$p$å€ã™ã‚‹ï¼Ž
+\item (D)--(K)ã«å±žã™ã‚‹ã‚°ãƒ«ãƒ¼ã®ä¼¸ã³é‡ã‚’0ã¨ã™ã‚‹ï¼Ž
+\item è¡ŒãŒæ ¼ç´ã•ã‚Œã¦ã„ã‚‹hboxã®
+\texttt{glue\_set}, \texttt{glue\_sign}, \texttt{glue\_order}ã‚’å†è¨ˆç®—ã™ã‚‹ï¼Ž
+ã“ã‚Œã«ã‚ˆã£ã¦ï¼Œ\textit{total}ã¯\textbf{JAglue}以外ã®ã‚°ãƒ«ãƒ¼ã«ã‚ˆã£ã¦è² æ‹…ã•ã‚Œã‚‹ï¼Ž
+\end{enumerate}
+\item \textit{total}ãŒ(A)--(K)ã®ä¼¸ã³é‡ã®åˆè¨ˆã‚ˆã‚Šã‚‚大ãã„å ´åˆï¼Œã©ã†ã—よã†ã‚‚ãªã„ã®ã§
+ \verb+^^;+何もã—ãªã„.
+\end{enumerate}
+
+%</ja>
+
+%<*ja>
+\section{複数フォントã®ã€Œåˆæˆã€ï¼ˆæœªå®Œï¼‰}
+\section{\LuaTeX-jaã«ãŠã‘るキャッシュ}
+\Pkg{luaotfload}パッケージãŒï¼Œå„TrueType・OpenTypeフォントã®æƒ…報を
+キャッシュã¨ã—ã¦ä¿å­˜ã—ã¦ã„ã‚‹ã®ã¨åŒæ§˜ã®æ–¹æ³•ã§ï¼Œ
+\LuaTeX-jaã‚‚ã„ãã¤ã‹ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãƒ•ã‚¡ã‚¤ãƒ«ã‚’作æˆã™ã‚‹ã‚ˆã†ã«ãªã£ãŸï¼Ž
+\begin{itemize}
+ \item 通常,キャッシュã¯\texttt{\$TEXMFVAR/luatexja/}以下ã«ä¿å­˜ã•ã‚Œï¼Œ
+ãã“ã‹ã‚‰èª­ã¿è¾¼ã¿ãŒè¡Œã‚れる.
+ \item 「通常ã®ã€ãƒ†ã‚­ã‚¹ãƒˆå½¢å¼ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ï¼ˆæ‹¡å¼µå­ã¯ \texttt{.lua})以外ã«ã‚‚,
+ãれをãƒã‚¤ãƒŠãƒªå½¢å¼ï¼ˆãƒã‚¤ãƒˆã‚³ãƒ¼ãƒ‰ï¼‰ã«å¤‰æ›ã—ãŸã‚‚ã®ã‚‚サãƒãƒ¼ãƒˆã—ã¦ã„る.
+\begin{itemize}
+ \item \LuaTeX ã¨LuaJIT\TeX ã§ã¯ãƒã‚¤ãƒˆã‚³ãƒ¼ãƒ‰ã®å½¢å¼ãŒç•°ãªã‚‹ãŸã‚,ãƒã‚¤ãƒŠãƒªå½¢å¼ã®
+キャッシュã¯å…±æœ‰ã§ããªã„.\LuaTeX 用ã®ãƒã‚¤ãƒŠãƒªã‚­ãƒ£ãƒƒã‚·ãƒ¥ã¯ \texttt{.luc},
+LuaJIT\TeX 用ã®ã¯ \texttt{.lub} ã¨æ‹¡å¼µå­ã‚’変ãˆã‚‹ã“ã¨ã§å¯¾å¿œã—ã¦ã„る.
+ \item キャッシュを読ã¿è¾¼ã‚€æ™‚,åŒåã®ãƒã‚¤ãƒŠãƒªã‚­ãƒ£ãƒƒã‚·ãƒ¥ãŒã‚ã‚Œã°ï¼Œ
+テキスト形å¼ã®ã‚‚ã®ã‚ˆã‚Šãã¡ã‚‰ã‚’優先ã—ã¦èª­ã¿è¾¼ã‚€ï¼Ž
+ \item テキスト形å¼ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãŒæ›´æ–°/作æˆã•ã‚Œã‚‹éš›ã¯ï¼Œãã®ãƒã‚¤ãƒŠãƒªç‰ˆã‚‚
+åŒæ™‚ã«æ›´æ–°ã•ã‚Œã‚‹ï¼Ž
+ã¾ãŸï¼Œï¼ˆãƒã‚¤ãƒŠãƒªç‰ˆãŒè¦‹ã¤ã‹ã‚‰ãšï¼‰ãƒ†ã‚­ã‚¹ãƒˆå½¢å¼ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥å´ãŒèª­ã¿è¾¼ã¾ã‚ŒãŸã¨ãã¯ï¼Œ
+\LuaTeX-jaã¯ãƒã‚¤ãƒŠãƒªã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’作æˆã™ã‚‹ï¼Ž
+\end{itemize}
+\end{itemize}
+%</ja>
+%<*en>
+\section{Cache Management of \LuaTeX-ja}
+\LuaTeX-ja creates some cache files to reduce the loading time.
+in a similar way to the \Pkg{luaotfload} package:
+\begin{itemize}
+ \item Cache files are usually stored in (and loaded from)
+\texttt{\$TEXMFVAR/luatexja/}.
+ \item In addition to caches of the text form (the extension is ``\texttt{.lua}''),
+caches of the \emph{binary}, precompiled form are supported.
+\begin{itemize}
+ \item We cannot share same binary cache for \LuaTeX\ and LuaJIT\TeX.
+Hence we distinguish them by their extension, ``\texttt{.luc}'' for \LuaTeX\
+and ``\texttt{.lub}'' for LuaJIT\TeX.
+ \item In loading a cache, the binary cache precedes
+the text form.
+ \item When \LuaTeX-ja updates a cache \texttt{hoge.lua},
+its binary version is also updated.
+\end{itemize}
+\end{itemize}
+%</en>
+
+%<*ja>
+\subsection{キャッシュã®ä½¿ç”¨ç®‡æ‰€}
+
+\LuaTeX-ja ã§ã¯ä»¥ä¸‹ã®3種類ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’使用ã—ã¦ã„る:
+\begin{cslist}
+\item[ltj-cid-auto-adobe-japan1.lua]
+Ryumin-Lightã®ã‚ˆã†ãªéžåŸ‹ã‚è¾¼ã¿ãƒ•ã‚©ãƒ³ãƒˆã®æƒ…報を格ç´ã—ã¦ãŠã‚Šï¼Œ
+(ãれらãŒ\LuaTeX-jaã®æ¨™æº–和文フォントãªã®ã§ï¼‰\LuaTeX-jaã®èª­ã¿è¾¼ã¿æ™‚ã«è‡ªå‹•ã§èª­ã¾ã‚Œã‚‹ï¼Ž
+生æˆã«ã¯\texttt{UniJIS2004-UTF32-\{H, V\}}, \texttt{Adobe-Japan1-UCS2}ã¨ã„ã†3ã¤ã®
+CMapãŒå¿…è¦ã§ã‚る.
+
+\pageref{para-cid}ページã§è¿°ã¹ãŸã‚ˆã†ã«ï¼Œ\texttt{cid}キーを使ã£ã¦
+éžåŸ‹ã‚è¾¼ã¿ã®ä¸­å›½èªžãƒ»éŸ“国語フォントを定義ã™ã‚‹å ´åˆï¼ŒåŒæ§˜ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãŒç”Ÿæˆã•ã‚Œã‚‹ï¼Ž
+キャッシュã®å称,必è¦ã¨ãªã‚‹CMapã«ã¤ã„ã¦ã¯\autoref{tab:cid-cache}ã‚’å‚ç…§ã—ã¦æ¬²ã—ã„.
+
+\item[extra\_***.lua]
+フォント``\texttt{***}''ã«ãŠã‘る異体字セレクタã®æƒ…報,縦組用字形ã¸ã®å¤‰æ›ãƒ†ãƒ¼ãƒ–ル,ãã—ã¦
+縦組時ã«ãŠã‘ã‚‹å¹…ã‚’æ ¼ç´ã—ã¦ã„る.構造ã¯ä»¥ä¸‹ã®é€šã‚Šï¼š
+%</ja>
+%<*en>
+\subsection{Use of cache}
+
+\LuaTeX-ja uses the following cache:
+\begin{cslist}
+\item[ltj-cid-auto-adobe-japan1.lua]
+The font table of a CID-keyed non-embedded Japanese font.
+This is loaded in every run.
+It is created from three CMaps, \texttt{UniJIS2004-UTF32-\{H,V\}} and
+ \texttt{Adobe-Japan1-UCS2},
+and this is why these two CMaps are needed in the first run of \LuaTeX-ja.
+
+Similar caches are created as \autoref{tab:cid-cache},
+if you specified \texttt{cid} key in \cs{jfont}
+to use other CID-keyed non-embedded fonts for Chinese or Korean,
+as in Page~\pageref{para-cid}.
+
+\item[extra\_***.lua]
+This file stores the table which stores the following.
+\begin{itemize}
+ \item unicode variants in a font ``\texttt{***}''
+ \item vertical width of glyphs, if it is not equal to the sum of
+the height of ascender and the depth of descender
+ \item vertical variants
+\end{itemize}
+The following is the structure of the that table.
+%</en>
+
+\begin{table}[!tb]
+ \centering\small
+\caption{\texttt{cid} key and corresponding files}
+\label{tab:cid-cache}
+\vspace*{\medskipamount}
+\begin{tabular}{>{\tt}l>{\tt}l>{\tt}l>{\tt}l}
+\toprule
+\bf \texttt{cid} key&\bf name of the cache &
+\multicolumn{2}{c}{\bf used CMaps}\\
+\midrule
+Adobe-Japan1-*&ltj-cid-auto-adobe-japan1.lua&UniJIS2004-UTF32-*&Adobe-Japan1-UCS2\\
+Adobe-Korea1-*&ltj-cid-auto-adobe-korea1.lua&UniKS-UTF32-*&Adobe-Korea1-UCS2\\
+Adobe-KR-*&ltj-cid-auto-adobe-kr.lua&UniAKR-UTF32-*&Adobe-KR-UCS2\\
+Adobe-GB1-*&ltj-cid-auto-adobe-gb1.lua&UniGB-UTF32-*&Adobe-GB1-UCS2\\
+Adobe-CNS1-*&ltj-cid-auto-adobe-cns1.lua&UniCNS-UTF32-*&Adobe-CNS1-UCS2\\
+\bottomrule
+\end{tabular}
+\end{table}
+
+\begin{lstlisting}
+return {
+ {
+ [10955]={ -- U+2ACB "Subset Of Above Not Equal To"
+ [65024]=983879, -- <2ACB FE00>
+ ["vwidth"]=0.98, -- vertical width
+ },
+ [37001]={ -- U+9089 "邉"
+ [0]=37001, -- <9089 E0100>
+ 991049, -- <9089 E0101>
+ ...
+ ["vform"]=995025, -- vertical variant
+ },
+ ...
+ ["unicodes"]={
+ ["aj102.pe.vert"]=984163, -- glyph name to unicode
+ ...
+ }
+ },
+ ["chksum"]="FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", -- checksum of the fontfile
+ ["version"]=11, -- version of the cache
+}
+\end{lstlisting}
+%<*ja>
+\item[ltj-jisx0208.\{luc|lub\}]
+\LuaTeX-jaé…布中ã®\texttt{ltj-jisx0208.lua}ã‚’ãƒã‚¤ãƒŠãƒªåŒ–ã—ãŸã‚‚ã®ã§ã‚る.
+ã“ã‚Œã¯JIS~X~0208ã¨Unicodeã¨ã®å¤‰æ›ãƒ†ãƒ¼ãƒ–ルã§ã‚り,
+\pTeX ã¨ã®äº’æ›ç›®çš„ã®æ–‡å­—コード変æ›å‘½ä»¤ã§ç”¨ã„られる.
+%</ja>
+%<*en>
+\item[ltj-jisx0208.\{luc|lub\}]
+The binary version of \texttt{ltj-jisx0208.lua}.
+This is the conversion table between JIS~X~0208 and Unicode
+which is used in Kanji-code conversion commands for compatibility with \pTeX.
+%</en>
+\end{cslist}
+
+%<*en>
+\subsection{Internal}
+Cache management system of \LuaTeX-ja is stored in \texttt{luatexja.base}
+(\texttt{ltj-base.lua}).
+There are three public functions for cache management in \texttt{luatexja.base},
+where <filename> stands for the file name \emph{without suffix}:
+\begin{cslist}
+\item[save\_cache(<filename>, <data>)]
+Save a non-nil table <data> into a cache <filename>.
+Both the text form <filename>\texttt{.lua} and its binary version
+are created or updated.
+
+\item[save\_cache\_luc(<filename>, <data>{[, <serialized\_data>]})]
+
+Same as \texttt{save\_cache}, except that only the binary cache is updated.
+The third argument <serialized\_data> is not usually given.
+But if this is given, it is treated as a string representation of <data>.
+
+\item[load\_cache(<filename>, <outdate>)]
+Load the cache <filename>.
+<outdate> is a function which takes one argument (the contents of the cache),
+and its return value is whether the cache is outdated.
+
+\texttt{load\_cache} first tries to
+read the binary cache <filename>\texttt{.\{luc|lub\}}.
+If its contents is up-to-date, \texttt{load\_cache} returns the contents.
+If the binary cache is not found or
+its contents is outdated, \texttt{load\_cache} tries to
+read the text form <filename>\texttt{.lua}.
+Hence, the return value of \texttt{load\_cache} is non-nil,
+if and only if the updated cache is found.
+\end{cslist}
+%</en>
+%<*ja>
+\subsection{内部命令}
+\LuaTeX-jaã«ãŠã‘るキャッシュ管ç†ã¯ï¼Œ\texttt{luatexja.base}~(\texttt{ltj-base.lua})ã«
+実装ã—ã¦ãŠã‚Šï¼Œä»¥ä¸‹ã®3関数ãŒå…¬é–‹ã•ã‚Œã¦ã„る.
+ã“ã“ã§ï¼Œ<filename>ã¯ä¿å­˜ã™ã‚‹ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®ãƒ•ã‚¡ã‚¤ãƒ«åã‚’\emph{æ‹¡å¼µå­ãªã—ã§}指定ã™ã‚‹ï¼Ž
+\begin{cslist}
+\item[save\_cache(<filename>, <data>)]
+nilã§ãªã„<data>をキャッシュ<filename>ã«ä¿å­˜ã™ã‚‹ï¼Ž
+テキスト形å¼ã®<filename>\texttt{.lua}ã®ã¿ãªã‚‰ãšï¼Œ
+ãã®ãƒã‚¤ãƒŠãƒªç‰ˆã‚‚作æˆ/æ›´æ–°ã•ã‚Œã‚‹ï¼Ž
+
+\item[save\_cache\_luc(<filename>, <data>{[, <serialized\_data>]})]
+
+\texttt{save\_cache}ã¨åŒæ§˜ã ãŒï¼Œãƒã‚¤ãƒŠãƒªã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®ã¿ãŒæ›´æ–°ã•ã‚Œã‚‹ï¼Ž
+第3引数<serialized\_data>ãŒä¸Žãˆã‚‰ã‚ŒãŸå ´åˆï¼Œãれを
+<data>ã®æ–‡å­—列化表ç¾ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ï¼Ž
+ãã®ãŸã‚,<serialized\_data>ã¯æ™®é€šã¯æŒ‡å®šã—ãªã„ã“ã¨ã«ãªã‚‹ã ã‚ã†ï¼Ž
+
+\item[load\_cache(<filename>, <outdate>)]
+キャッシュ<filename>を読ã¿è¾¼ã‚€ï¼Ž
+<outdate>ã¯1引数(キャッシュã®ä¸­èº«ï¼‰ã‚’ã¨ã‚‹é–¢æ•°ã§ã‚り,
+ãã®æˆ»ã‚Šå€¤ã¯ã€Œã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®æ›´æ–°ãŒå¿…è¦ã€ã‹ã©ã†ã‹ã‚’示ã™ãƒ–ール値ã§ãªã„ã¨ã„ã‘ãªã„.
+
+\texttt{load\_cache}ã¯ï¼Œã¾ãšãƒã‚¤ãƒŠãƒªã‚­ãƒ£ãƒƒã‚·ãƒ¥<filename>\texttt{.\{luc|lub\}}ã‚’
+読ã¿ã“む.もã—ãã®å†…容ãŒã€Œæ–°ã—ã„ã€ï¼Œã¤ã¾ã‚Š<outdate>ã®è©•ä¾¡çµæžœãŒ \texttt{false} ãªã‚‰
+\texttt{load\_cache}ã¯ã“ã®ãƒã‚¤ãƒŠãƒªã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®ä¸­èº«ã‚’è¿”ã™ï¼Ž
+ã‚‚ã—ãƒã‚¤ãƒŠãƒªã‚­ãƒ£ãƒƒã‚·ãƒ¥ãŒè¦‹ã¤ã‹ã‚‰ãªã‹ã£ãŸã‹ï¼Œã€Œå¤ã™ãŽã‚‹ã€ãªã‚‰ã°ãƒ†ã‚­ã‚¹ãƒˆç‰ˆ
+ <filename>\texttt{.lua}を読ã¿è¾¼ã¿ï¼Œãã®å€¤ã‚’è¿”ã™ï¼Ž
+
+以上より,\texttt{load\_cache}自体ãŒnilã§ãªã„値を返ã™ã®ã¯ï¼Œã¡ã‚‡ã†ã©ã€Œæ–°ã—ã„ã€ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãŒ
+見ã¤ã‹ã£ãŸå ´åˆã§ã‚る.
+\end{cslist}
+%</ja>
+
+
+%<*ja>
+\section{縦組ã®å®Ÿè£…}
+\label{sec-dir-imp}
+\ref{sec-direction}ç« ã®æœ€åˆã§ã‚‚è¿°ã¹ãŸã‚ˆã†ã«ï¼Œ
+\LuaTeX-jaã¯æ¨ªçµ„(\texttt{TLT})ã§çµ„ã‚“ã ãƒœãƒƒã‚¯ã‚¹ã‚’回転ã•ã›ã‚‹æ–¹å¼ã§
+縦組を実装ã—ã¦ã„る.
+
+\LuaTeX-jaã«ãŠã‘る縦組ã®å®Ÿè£…ã¯
+\pTeX ã«ãŠã‘る実装(\cite{ptexdoc,ptextug})をベースã«ã—ã¦ã„る.
+
+\subsection{direction~whatsit}
+\textit{direction}~whatsitã¨ã¯ï¼Œ\textit{direction}ã¨ã„ã†ç‰¹å®šã® \verb+user_id+ ã‚’æŒã¤
+whatsitã®ã“ã¨ã§ã‚り,以下ã®ã‚¿ã‚¤ãƒŸãƒ³ã‚°ã§ä½œã‚‰ã‚Œã‚‹ï¼Ž
+\begin{itemize}
+ \item 組方å‘ã‚’ \cs{tate} ç­‰ã§å¤‰æ›´ã—ãŸã¨ã.
+ \item \cs{hbox}, \cs{vbox}, \cs{vtop} ã«ã‚ˆã‚‹æ˜Žç¤ºçš„ãªãƒœãƒƒã‚¯ã‚¹ã®é–‹å§‹æ™‚.\\
+\verb+\hbox{}+, \verb+\vbox{}+ ã¨ã„ã£ãŸï¼Œ
+\begin{itemize}
+ \item \cs{tate} ç­‰ã«ã‚ˆã‚Šãƒœãƒƒã‚¯ã‚¹å†…部ã®çµ„æ–¹å‘を変更ã—ã¦ã„ãªã„
+ \item ボックスã®ä¸­èº«ã®ãƒªã‚¹ãƒˆãŒç©ºã§ã‚ã‚‹
+\end{itemize}
+å ´åˆã¯ï¼Œ\LuaTeX ã® \verb+hpack_filter+, \verb+vpack_filter+ ã¨ã„ã£ãŸ
+callbackã«å‡¦ç†ãŒå›žã‚‰ãªã„.ãã“ã§ï¼Œ\LuaTeX-ja ã§ã¯ï¼Œ\cs{everyhbox}, \cs{everyvbox} を利用ã™
+ ã‚‹ã“ã¨ã§å„ボックスã®å…ˆé ­ã«ç¢ºå®Ÿã«è¿½åŠ ã™ã‚‹ã‚ˆã†ã«ã—ã¦ã„ã‚‹\footnote{%
+ å•é¡Œã¯ \cs{hbox to 25pt\{\}} ã¨ã„ã†çŠ¶æ³ã§ã‚る.実際ã®ã“ã®ãƒœãƒƒã‚¯ã‚¹ã®ä¸­èº«ã¯ç©ºã§ãªã„(少ãª
+ ãã¨ã‚‚direction whatsitãŒã‚る)ãŸã‚,何も対策をã—ãªã‘ã‚Œã°hpack時ã«Underfill警告ãŒç™º
+ 生ã—ã¦ã—ã¾ã†ã“ã¨ã«ãªã‚‹ï¼Ž\LuaTeX-jaã§ã¯ãã†ãªã‚‰ãªã„よã†ã«ã€Œ\cs{hbadness},
+ \cs{vbadness} を一時的ã«10000ã«å¤‰æ›´ã—,hpack, vpack後ã«å…ƒã®å€¤ã«æˆ»ã™ã€å‡¦ç†ã‚’è¡Œã£ã¦ã„
+ る.
+}.
+ \item \cs{vsplit}ã«ã‚ˆã£ã¦vboxを分割ã—ãŸæ™‚ã®ã€Œæ®‹ã‚Šã€ã®å…ˆé ­ï¼Ž
+ \item \LuaTeX-ja読ã¿è¾¼ã¿å‰ã«ä½œæˆã—ãŸãƒœãƒƒã‚¯ã‚¹ã®å¯¸æ³•ã‚’ \cs{ltjsetwd} ç­‰ã«ã‚ˆã£ã¦å¤‰æ›´ã—ãŸæ™‚.
+ \item \cs{insert} ã«ã‚ˆã‚‹insertionã§ã¯ï¼Œä¸­èº«ã®å…ˆé ­ã«\textit{direction}~whatsitã¯ä½œã‚‰ã‚Œãšï¼Œ
+ãã®ä»£ã‚ã‚Šã«ä¸­èº«ã®å„ボックス・罫線ã®ç›´å‰ã«ä½œã‚‰ã‚Œã‚‹\footnote{%
+ ã“ã‚Œã¯ï¼Œãƒšãƒ¼ã‚¸åˆ†å‰²ã®éŽç¨‹ã§insertionãŒåˆ†å‰²ã•ã‚Œã‚‹æ™‚,「ç¾åœ¨ã®ãƒšãƒ¼ã‚¸ã§å‡ºåŠ›ã•ã‚Œã‚‹éƒ¨åˆ†ã€ãŒç©ºã¨
+ ãªã‚‹ã“ã¨ãŒã‚ã‚‹ã“ã¨ã«ã‚ˆã‚‹ï¼Žå…ˆé ­ã«whatsitã‚’ç½®ãã¨ï¼Œæœ€æ‚ªã§ã‚‚「ç¾åœ¨ã®ãƒšãƒ¼ã‚¸ã«whatsitãŒ
+ 残るã€ã“ã¨ã«ãªã£ã¦ã—ã¾ã†ï¼Ž}.
+\end{itemize}
+ãªãŠï¼Œ\verb+\vtop{...}+ ã®å ´åˆã¯ï¼Œå…ˆé ­ã«direction whatsitã‚’ç½®ãã¨
+ボックスã®é«˜ã•ãŒå¸¸ã«0\,ptã«ãªã‚‹ã¨ã„ã†å•é¡ŒãŒç™ºç”Ÿã™ã‚‹ï¼Žãã®ãŸã‚,ã“ã®å ´åˆã«é™ã£ã¦ã¯
+vpack時ã«direction whatsitをリストã®2番目ã«ç§»å‹•ã•ã›ã¦ã„る.
+
+direction whatsitã¯ã‚ãã¾ã§ã‚‚組方å‘処ç†ã®ãŸã‚ã®è£œåŠ©çš„ãªãƒŽãƒ¼ãƒ‰ã§ã‚ã‚‹ã®ã§ï¼Œ
+\cs{unhbox}, \cs{unhcopy} ã«ã‚ˆã£ã¦ãƒœãƒƒã‚¯ã‚¹ã®ä¸­èº«ãŒå±•é–‹ã•ã‚Œã‚‹æ™‚ã«ã¯å±•é–‹ç›´å‰ã«å‰Šé™¤ã•ã‚Œã‚‹ï¼Ž
+ã“ã‚Œã¯
+\begin{lstlisting}
+ % yoko direction
+\setbox0=\hbox{\tate B}
+\noindent % 水平モードã«å…¥ã‚‹ï¼Žã“ã®æ™‚点ã§ã®ãƒªã‚¹ãƒˆã®ä¸­èº«ã¯ç©º
+\unhbox0 A
+\end{lstlisting}
+ã¨ã„ã£ãŸå ´åˆã«ï¼Œæ®µè½ãŒç¸¦çµ„ã§çµ„ã¾ã‚ŒãŸã‚Šï¼Œã‚ã‚‹ã„ã¯
+\begin{lstlisting}
+\setbox0=\hbox{}
+\leavevmode \hbox{A}\unhbox0
+\setbox1=\lastbox % \box1 ã¯ã©ã†ãªã‚‹ï¼Ÿ
+\end{lstlisting}
+㧠\cs{box1} ㌠\cs{hbox\{A\}} ã§ãªã空ã«ãªã£ã¦ã—ã¾ã†ã“ã¨ã‚’防ããŸã‚ã§ã‚る.
+
+
+\subsection{\textit{dir\_box}}
+縦中横ãªã©ç•°æ–¹å‘ã®ãƒœãƒƒã‚¯ã‚¹ã‚’é…ç½®ã™ã‚‹å ´åˆã«ï¼Œå‘¨å›²ã®çµ„æ–¹å‘ã¨å¤§ãã•ã‚’æ•´åˆã•ã›ã‚‹ãŸã‚,
+\LuaTeX-jaã§ã¯ \verb+\ltj@dir+ ãŒ128以é™ã®\textit{hlist\_node}, \textit{vlist\_node}ã‚’
+用ã„る.ã“れらã¯\pTeX ã«ãŠã‘ã‚‹\textit{dir\_node}ã®å½¹å‰²ã¨åŒã˜æžœãŸã—ã¦ãŠã‚Šï¼Œ
+ã“ã®æ–‡ç« ä¸­ã§ã¯\textit{dir\_box}ã¨å‘¼ç§°ã™ã‚‹ï¼Ž
+
+\subsubsection{ç•°æ–¹å‘ã®ãƒœãƒƒã‚¯ã‚¹ã®æ•´åˆ}
+\textit{dir\_box}ã®ç¬¬ä¸€ã®ä½¿ç”¨ç›®çš„ã¯ï¼Œç•°æ–¹å‘ã®ãƒœãƒƒã‚¯ã‚¹ã®å¤§ãã•ã‚’æ•´åˆã•ã›ã‚‹ã“ã¨ã§ã‚る.
+例ãˆã°ï¼Œ
+\begin{lstlisting}
+ % yoko direction
+å¹³æˆ\hbox{\tate 26}å¹´
+\end{lstlisting}
+ã¯æ®µè½ä¸­ã§
+\[
+ \xymatrix{
+ {}\Node{glyph}{`å¹³'}\ar[r]&{}\Node{glyph}{`æˆ'}\ar[r]&
+ {}\HNode{hbox}{10.00003}{3.02779}{0.0}\ar[r]\ar[d]^{\text{中身}}&{}\Node{glyph}{`年'}\\
+ &&{}\Node{whatsit}{\cs{tate}}\ar[r]&{}\Node{glyph}{`2'}\ar[r]&{}\Node{glyph}{`6'}
+ }
+\]
+ã¨ã„ã†ãƒªã‚¹ãƒˆã‚’作る.ãã®å¾Œï¼Œã“ã®æ®µè½ãŒçµ‚了ã—ãŸã¨ãã«ï¼Œ
+\LuaTeX-jaã®\textbf{JAglue}挿入処ç†ãŒè¡Œã‚ã‚Œ
+\[
+ \xymatrix{
+ {}\Node{glyph}{`å¹³'}\ar[r]
+ &{}\textcolor{blue}{\Node{glue}{\Param{xkanjiskip}}}\ar[r]
+ &{}\Node{glyph}{`æˆ'}\ar[r]
+ &{}\textcolor{blue}{\Node{penalty}{0}}
+ \ar`r[d] `[l] `[ddll] `[dl] [dl]
+ \\
+ &&{}\textcolor{red}{\HNode{\textit{dir\_box} (\cs{yoko})}{3.02779}{10.00003}{0.0}}\ar[r]\ar[d]^{\text{中身}}
+ &{}\textcolor{blue}{\Node{penalty}{0}}\ar[r]
+ &{}\Node{glyph}{`å¹´'}\\
+ &&{}\HNode{hbox}{10.00003}{3.02779}{0.0}\ar[d]^{\text{中身}}\\
+ &&{}\Node{whatsit}{\cs{tate}}\ar[r]&{}\Node{glyph}{`2'}\ar[r]&{}\Node{glyph}{`6'}
+ }
+\]
+ã®ã‚ˆã†ã«ãªã‚‹ï¼ˆé’å­—ã¯\textbf{JAglue},赤字ãŒæ•´åˆå‡¦ç†ã®ãŸã‚ã®\textit{dir\_box}ã§ã‚る).
+\TeX ã® \cs{showbox} å½¢å¼ã§æ›¸ã‘ã°
+
+\medskip{\narrowbaselines\ttfamily\obeylines\parindent0pt
+\catcode`\@=0 @catcode`@\=12
+.\tenmin å¹³
+@textcolor{blue}{.\glue 0.0 plus 0.4 minus 0.4}
+.\tenmin æˆ
+@textcolor{blue}{.\penalty 0}
+@textcolor{red}{.\hbox(10.00003+0.0)x3.02779, direction TLT}
+..\hbox(3.02779+0.0)x10.00003, direction TLT
+...\whatsit4=[]
+...\tenrm 2
+...\tenrm 6
+@textcolor{blue}{.\penalty 0}
+.\tenmin å¹´
+}\medskip
+
+\noindent ã§ã‚る.
+
+ãªãŠï¼Œ\cs{raise},~\cs{lower}, \cs{moveleft},~\cs{moveright} ã¨ã„ã£ãŸãƒœãƒƒã‚¯ã‚¹ç§»å‹•å‘½ä»¤ã§ã¯ï¼Ž
+移動を正ã—ã表ç¾ã™ã‚‹ãŸã‚ã«æ®µè½ã‚„ボックスã®é€”中ã§ã‚‚ç•°æ–¹å‘ã®ãƒœãƒƒã‚¯ã‚¹ã¯\textit{dir\_box}ã«ã‚«
+プセル化ã—ã¦ã„る.
+例ãˆã°
+\begin{lstlisting}
+ % yoko direction
+å¹³æˆ\raise1pt\hbox{\tate 26}å¹´\showlists
+\end{lstlisting}
+ã¯ä»¥ä¸‹ã®ã‚ˆã†ãªçµæžœã‚’得る.
+
+\medskip{\narrowbaselines\ttfamily\obeylines\parindent0pt
+\catcode`\@=0 @catcode`@\=12
+(å‰ç•¥ï¼‰
+\tenrm å¹³
+\tenrm æˆ
+@textcolor{red}{\hbox(10.00003+0.0)x3.02779, shifted -1.0, direction TLT}
+.\hbox(3.02779+0.0)x10.00003, direction TLT
+..\whatsit4=[]
+..\tenrm 2
+..\tenrm 6
+\tenrm å¹´
+}\medskip
+
+ã¾ãŸï¼Œãƒ¡ã‚¤ãƒ³ã®åž‚直リストã«ç•°æ–¹å‘ã®ãƒœãƒƒã‚¯ã‚¹ãŒè¿½åŠ ã•ã‚Œã‚‹å ´åˆã«ã‚‚åŒæ§˜ã«å³åº§ã«
+\textit{dir\_box}ã«ã‚«ãƒ—セル化ã—ã¦ã„る.ページ分割ã®ã‚¿ã‚¤ãƒŸãƒ³ã‚°ã‚’æ­£
+ã—ã\TeX ãŒåˆ¤æ–­ã™ã‚‹ãŸã‚ã§ã‚る.
+\cs{lastbox} ã«ã‚ˆã‚‹ãƒœãƒƒã‚¯ã‚¹ã®å–å¾—ã§ã¯ï¼Œ\textit{dir\_box}ã¯å‰Šé™¤ã•ã‚Œã‚‹ï¼Ž
+
+\subsubsection{ç•°æ–¹å‘ã®ãƒœãƒƒã‚¯ã‚¹å¯¸æ³•ã®æ ¼ç´}
+第二ã®ä½¿ç”¨ç›®çš„ã¯ï¼Œç¾åœ¨ã®çµ„æ–¹å‘ãŒãƒœãƒƒã‚¯ã‚¹æœ¬æ¥ã®çµ„æ–¹å‘ã¨ã¯ç•°ãªã‚‹çŠ¶æ³ã§ï¼Œ
+\cs{ltjsetwd} ã«ã‚ˆã£ã¦ãƒœãƒƒã‚¯ã‚¹å¯¸æ³•ã‚’設定ã•ã‚ŒãŸã“ã¨ã‚’記録ã™ã‚‹ã“ã¨ã§ã‚る.
+
+例ãˆã°
+\begin{lstlisting}[numbers=left]
+\setbox0=\hbox{\vrule width 10pt height 5pt depth 2pt}
+\setbox1=\hbox{\tate\ltjsetwd0=20pt}
+\wd0=9pt
+\setbox1=\hbox{\dtou\ltjsetwd0=20pt}
+\setbox0=\hbox{\dtou a\box0}
+\end{lstlisting}
+ã¨ã„ã†ã‚³ãƒ¼ãƒ‰ã‚’考ãˆã‚‹ï¼Ž1行目㧠\cs{box0} ã«ã¯æ¨ªçµ„ã®
+å¹…10\,pt,高ã•5\,pt,深ã•2\,ptã®ãƒœãƒƒã‚¯ã‚¹ãŒä»£å…¥ã•ã‚Œã‚‹ï¼Ž
+よã£ã¦ï¼Œ
+\begin{itemize}
+ \item 縦組下ã§ã¯ \cs{box0} ã¯å¹…7\,pt,高ã•ãƒ»æ·±ã•5\,ptã®ãƒœãƒƒã‚¯ã‚¹ã¨ã—ã¦æ‰±ã‚れる.
+ \item \cs{dtou} 下ã§ã¯ \cs{box0} ã¯å¹…7\,pt,高ã•10\,pt,深ã•0\,ptã®ãƒœãƒƒã‚¯ã‚¹ã¨ã—ã¦æ‰±ã‚れる.
+\end{itemize}
+ã“ã®ã¨ã,\cs{box0} ã®\emph{中身}ã¯
+\[
+ \xymatrix{
+ {}\Node{whatsit}{\cs{yoko}}\ar[r]&{}\Node{rule}{}
+ }
+\]
+ã§ã‚る.
+
+ã•ã¦ï¼Œ2行目ã§ç¸¦çµ„時㮠\cs{box0} ã®å¹…ãŒ20\,ptã«è¨­å®šã•ã‚Œã‚‹ï¼Žã“ã®æƒ…å ±ãŒ
+direction~whatsit内部ã®ãƒŽãƒ¼ãƒ‰ãƒªã‚¹ãƒˆã«ï¼Œ\textit{dir\_box}ã¨ã—ã¦æ ¼ç´ã•ã‚Œã‚‹ï¼š
+\[
+ \xymatrix{
+ {}\Node{whatsit}{\cs{yoko}}\ar[r]\ar[d]_{\text{中身}}&{}\Node{rule}{}\\
+ {}\textcolor{red}{\HNode{\textit{dir\_box} (\cs{tate})}{20.0}{5.0}{5.0}}
+ }
+\]
+
+次ã«ï¼Œ3行目ã§ã¯æ¨ªçµ„時ã®ï¼Œã¤ã¾ã‚Š \cs{box0} 本æ¥ã®çµ„æ–¹å‘ã§ã®æ·±ã•ãŒ9\,ptã«å¤‰æ›´ã•ã‚Œã‚‹ï¼Ž
+ã“ã®ã¨ã,\cs{box0} ã¯
+\begin{itemize}
+ \item 縦組下ã§ã¯å¯¸æ³•ä»£å…¥ãŒæ—¢ã«è¡Œã‚ã‚Œã¦ã„ã‚‹ã®ã§ï¼Œ2行目ã§ä½œæˆã•ã‚ŒãŸ\textit{dir\_box}ã®é€šã‚Š
+ ã«å¹…20\,pt,高ã•ãƒ»æ·±ã•5\,ptã®ãƒœãƒƒã‚¯ã‚¹ã¨ã—ã¦æ‰±ã‚れる.
+ \item \cs{dtou} 下ã§ã¯ã¾ã å¯¸æ³•ä»£å…¥ãŒè¡Œã‚ã‚Œã¦ã„ãªã„ã®ã§ï¼Œ
+\cs{box0} ã®å¯¸æ³•å¤‰æ›´ã«è¿½å¾“ã—,幅7\,pt,高ã•9\,pt,深ã•0\,ptã®ãƒœãƒƒã‚¯ã‚¹ã¨ã—ã¦æ‰±ã‚れる.
+\end{itemize}
+
+4行目ã§ã¯ \cs{dtou} 下ã§ã®\cs{box0} ã®å¹…ãŒ20\,ptã«è¨­å®šã•ã‚Œã‚‹ã®ã§ï¼Œ2行目ã¨åŒã˜ã‚ˆã†ã«
+\[
+ \xymatrix{
+ {}\Node{whatsit}{\cs{yoko}}\ar[r]\ar[d]_{\text{中身}}&{}\Node{rule}{}\\
+ {}\textcolor{red}{\HNode{\textit{dir\_box} (\cs{dtou})}{20.0}{9.0}{0.0}}\ar[r]&
+ {}\HNode{\textit{dir\_box} (\cs{tate})}{20.0}{5.0}{5.0}
+ }
+\]
+ã¨\textit{dir\_box}ãŒä½œæˆã•ã‚Œã‚‹ï¼Ž
+
+ã“ã®ã‚ˆã†ã«å¯¸æ³•ä»£å…¥ã«ã‚ˆã£ã¦ã¤ãられãŸ\textit{dir\_box}ã¯ï¼Œå‰ç¯€ã®æ•´åˆéŽç¨‹ã®ã¨ãã«å†åˆ©ç”¨ã•ã‚Œ
+る.上記ã®ä¾‹ã§ã„ãˆã°ï¼Œ5行目を実行ã—ãŸå¾Œã® \cs{box0} ã®å†…容ã¯
+\[
+ \xymatrix{
+ {}\Node{whatsit}{\cs{dtou}}\ar[r]&
+ {}\Node{glyph}{`a'}\ar[r]&
+ {}\textcolor{red}{\HNode{\textit{dir\_box} (\cs{dtou})}{20.0}{9.0}{0.0}}\ar[d]_{\text{中身}}\\
+ &&{}\HNode{hbox}{9.0}{5.0}{2.0}\ar[d]_{\text{中身}}\\
+ &&{}\Node{whatsit}{\cs{yoko}}\ar[r]&{}\Node{rule}{}
+ }
+\]
+ã®ã‚ˆã†ã«ãªã‚‹ï¼Ž
+
+\subsection{縦組用字形ã®å–å¾—}
+縦組時ã«ã¯ï¼Œã€Œ\hbox to \zw{ã€}ã€(\texttt{U+3001})ã‹ã‚‰ã€Œ\ltjjachar"FE11ã€(\texttt{U+FE11})%"
+ã®ã‚ˆã†ã«ç¸¦çµ„用字形ã¸ã®ç½®ãæ›ãˆã«é–¢ä¿‚ã™ã‚‹å‡¦ç†ã¯ï¼Œä»¥ä¸‹ã®ã‚ˆã†ã«ãªã£ã¦ã„る.
+ \begin{itemize}
+ \item å„縦組用和文フォントã¯èª­ã¿è¾¼ã¿æ™‚ã«ä»¥ä¸‹ã®å±žæ€§ãŒè¨­å®šã•ã‚Œã‚‹ï¼š
+ \begin{description}
+ \item[\textit{vert\_activated}] 真ã¨ãªã‚‹ã®ã¯ï¼Œ
+ 明示的㫠\texttt{-vert} ã‚‚ \texttt{-vrt2} ã®ã„ãšã‚Œã‚‚指定ã•ã‚Œã¦ã„ãªã„ã¡ã‚‡ã†ã©ãã®æ™‚.
+ \item[\textit{auto\_enable\_vrt2}] 真ã¨ãªã‚‹ã®ã¯ï¼Œ
+ \texttt{vert}, \texttt{vrt2}ã®ã„ãšã‚Œã«ã¤ã„ã¦ã‚‚有効・無効ãŒæŒ‡å®šã•ã‚Œã¦ã„ãªã„ã¡ã‚‡ã†ã©ãã®æ™‚.
+ \end{description}
+ \textit{vert\_activated}ã«ã¤ã„ã¦ã¯\texttt{luatexja.define\_jfont}コールãƒãƒƒã‚¯ã§æ¸¡ã•ã‚Œã‚‹å¼•æ•°
+ \texttt{jfont\_info}ã‹ã‚‰å–å¾—å¯èƒ½ã§ã‚る.
+
+ \item \textit{auto\_enable\_vrt2}ãŒçœŸã®å ´åˆã¯ï¼Œç¾åœ¨ã®script tagã¨language system identifierã®å€¤ã§
+ \texttt{vrt2}機能ãŒåˆ©ç”¨å¯èƒ½ã‹èª¿ã¹ã‚‹ï¼Žåˆ©ç”¨å¯èƒ½ãªã‚‰ã°\texttt{vrt2}を,ãã†ã§ãªã‘ã‚Œã°
+ \texttt{vert}を有効化ã™ã‚‹ï¼Ž
+ \item ã¾ãŸï¼Œå„和文フォント読ã¿è¾¼ã¿æ™‚ã«ã¯ï¼Œ
+ 「OpenType機能ã«ã‚ˆã‚‹ç½®æ›ä»¥å‰ã«è¡Œã†ç¸¦çµ„å½¢ã¸ã®ç½®æ›ã€ã‚’æ ¼ç´ã—ãŸãƒ†ãƒ¼ãƒ–ル\textit{vform}も作æˆã™ã‚‹ï¼Ž
+ \begin{enumerate}
+ \item \LuaTeX-jaã«ã¯ï¼Œã€Œ\hbox to \zw{ã€}ã€(\texttt{U+3001})→「\ltjjachar"FE11ã€(\texttt{U+FE11})ã¨ã„ã£ãŸ
+ ã„ãã¤ã‹ã®ç½®æ›ãŒãƒãƒ¼ãƒ‰ã‚³ãƒ¼ãƒ‰ã•ã‚Œã¦ã„る.ãã®ã‚ˆã†ãªå„ç½®æ›$i\longmapsto v$ã«å¯¾ã—ã¦ï¼Œ
+ \begin{quote}
+ ç½®æ›å…ƒ$i$ãŒï¼ˆã‚ã‚‹script, languageã«ãŠã‘る)\texttt{vert}ã§ã¯ç½®æ›å¯¾è±¡ã§ãªã,
+ ã‹ã¤ç½®æ›å…ˆ$v$ãŒãƒ•ã‚©ãƒ³ãƒˆå†…ã«å­˜åœ¨ã™ã‚‹æ–‡å­—コードã§ã‚ã‚‹
+ \end{quote}
+ ãªã‚‰ã°ï¼Œ$i\longmapsto v$ã‚’\textit{vform}ã«ç™»éŒ²ã™ã‚‹ï¼Ž
+ \item \ref{ssec:tfont}節ã«ã‚ã‚‹\texttt{jpotf}ãŒæŒ‡å®šã•ã‚ŒãŸå ´åˆï¼Œ
+ ……
+ \item ã‚‚ã—\texttt{vert}ã‚‚\texttt{vrt2}ã‚‚ç¾åœ¨ã®script, languageã§ã¯æœ‰åŠ¹ã«ã§ããªã„å ´åˆï¼Œ
+ ã©ã“ã‹ã®script, languageã«ãŠã‘ã‚‹\texttt{vert}ã§å®šç¾©ã•ã‚Œã¦ã„ã‚‹
+ ç½®æ›$i\longmapsto v$ã‚’ã™ã¹ã¦\textit{vform}ã«ç™»éŒ²ã™ã‚‹ï¼Ž
+ \end{enumerate}
+
+ ã‚ã¨ã§èª¬æ˜Žã™ã‚‹ã‚ˆã†ã«ï¼Œ\textit{vform}ã¯\textit{vert\_activated}ãŒçœŸã§ã‚るよã†ãªç¸¦çµ„用和文フォントã§ã—ã‹
+ 利用ã•ã‚Œãªã„.
+
+ \item 「ç¾åœ¨ã®æ°´å¹³ãƒªã‚¹ãƒˆã€å†…ã®\textbf{JAchar}を(欧文フォントã‹ã‚‰ï¼‰å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã¸ç½®ãæ›ãˆã‚‹å‡¦ç†ã«ãŠã„ã¦ï¼Œ
+ ãã®æ™‚点ã§ã®çµ„æ–¹å‘ãŒç¸¦çµ„ã§ã‚り,ã‹ã¤å‡¦ç†å¯¾è±¡ã®å„ノードã®ç¸¦çµ„用フォントã§
+ \textit{vert\_activated}ãŒçœŸã§ã‚ã‚‹å ´åˆï¼Œ\textit{vform}ã«å¾“ã„グリフãŒç½®ãæ›ãˆã‚‰ã‚Œã‚‹ï¼Ž
+
+ \Pkg{luaotfload}ãŒè¡Œã†ï¼ŒOpenType機能ã«æ²¿ã£ãŸã‚°ãƒªãƒ•ç½®æ›ã¯ã“ã®å¾Œã®å‡¦ç†ã¨ãªã‚‹ï¼ŽG
+ \end{itemize}
+
+%</ja>
+
+\newpage
+\begin{thebibliography}{99}
+ \addcontentsline{toc}{section}{\refname}
+\bibitem{texbytopic}
+Victor Eijkhout. \newblock \textit{\TeX\ by Topic, A \TeX nician's Reference}, Addison-Wesley, 1992.
+\bibitem{listings} C.\ Heinz, B.\ Moses. \newblock The \textsf{Listings} Package.
+\bibitem{uptex} Takuji Tanaka. \newblock
+upTeX---Unicode version of pTeX with CJK extensions,
+TUG 2013, October 2013.
+%<ja>\newblock
+%<en>\\\null\hfill
+\url{http://tug.org/tug2013/slides/TUG2013_upTeX.pdf}
+\bibitem{jlisting} Thor Watanabe. \newblock Listings\ -\ MyTeXpert.
+%<en>\newblock
+%<ja>\\\null\hfill
+\url{http://mytexpert.osdn.jp/index.php?Listings}
+\bibitem{jlreq} W3C Japanese Layout Task Force~(ed). \newblock
+Requirements for Japanese Text Layout (W3C Working Group Note), 2011, 2012. \newblock
+\url{http://www.w3.org/TR/jlreq/}%
+%<ja> \\日本語訳ã®æ›¸ç±ç‰ˆï¼šW3C日本語組版タスクフォース(編),『W3C技術ノート 日本語組版処ç†ã®è¦ä»¶ã€ï¼Œæ±äº¬é›»æ©Ÿå¤§å­¦å‡ºç‰ˆå±€ï¼Œ2012.
+\bibitem{min10} 乙部厳己.「min10フォントã«ã¤ã„ã¦ã€\\\null\hfill
+\url{http://argent.shinshu-u.ac.jp/~otobe/tex/files/min10.pdf}
+\bibitem{x4051} 日本工業è¦æ ¼(Japanese Industrial Standard). 「JIS~X~4051,
+日本語文書ã®çµ„版方法(Formatting rules for Japanese documents)ã€, 1993, 1995, 2004.
+\bibitem{ptexdoc} 濱野尚人,田æ‘明å²ï¼Œå€‰æ²¢è‰¯ä¸€ï¼Žã€Œ\TeX ã®å‡ºç‰ˆã¸ã®å¿œç”¨â€”縦組ã¿æ©Ÿèƒ½ã®çµ„ã¿è¾¼ã¿â€”ã€ï¼Ž
+\\\null\hfill\texttt{.../texmf-dist/doc/ptex/base/ptexdoc.pdf}
+\bibitem{ptextug} Hisato Hamano. \newblock
+\textit{Vertical Typesetting with \TeX}, TUGBoat~\textbf{11}(3), 346--352, 1990.
+\bibitem{pdfstd} International Organization for Standardization. \newblock
+ISO 32000-1:2008, \textit{Document management -- Portable document format -- Part 1: PDF
+ 1.7}, 2008. \newblock
+\\\null\hfill
+\url{http://www.iso.org/iso/iso\_catalogue/catalogue_tc/catalogue\_detail.htm?csnumber=51502}
+\bibitem{tc18ltja} 北å·å¼˜å…¸ï¼Žã€Œ\LuaTeX-jaã®è¿‘æ³ã€ï¼Œ\TeX Conf~2018.\\
+ \url{https://osdn.net/projects/luatex-ja/wiki/Documentation/attach/tc18ltja.pdf}
+\end{thebibliography}
+
+\end{document}
+%</!showexpl>
+%<*showexpl>
+%%
+%% config file for showexpl.sty
+%%
+%% Copyright The LuaTeX-ja project team, 2012
+%%
+\ProvidesFile{showexpl.cfg}
+ [2012/05/20 v0.01 Definitions for the showexpl package (luatexja)]
+\lstset{}
+\def\SX@Info{}
+\endinput
+%</*showexpl>
diff --git a/macros/luatex/generic/luatexja/doc/luatexja.ins b/macros/luatex/generic/luatexja/doc/luatexja.ins
new file mode 100644
index 0000000000..7d6d3c5d1f
--- /dev/null
+++ b/macros/luatex/generic/luatexja/doc/luatexja.ins
@@ -0,0 +1,10 @@
+%#! lualatex -shell-escape luatex.ins
+\input docstrip.tex
+\askforoverwritefalse
+\generate{\file{luatexja-ja.tex}{\from{luatexja.dtx}{ja}}
+ \file{luatexja-en.tex}{\from{luatexja.dtx}{en}}
+ \file{showexpl.cfg}{\from{luatexja.dtx}{showexpl}}
+}
+\immediate\write18{lualatex luatexja-ja}
+\immediate\write18{lualatex luatexja-en}
+\endbatchfile
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-adjust.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-adjust.sty
new file mode 100644
index 0000000000..c4cc54c2f9
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-adjust.sty
@@ -0,0 +1,144 @@
+%
+% luatexja-adjust.sty
+%
+
+%% Avoid multiple loading.
+\csname\if11luatexjaadjustLoaded\fi\endcsname
+\edef\x{%
+\catcode32=\the\catcode32%
+\catcode33=\the\catcode33%
+\catcode35=\the\catcode35%
+\catcode40=\the\catcode40%
+\catcode41=\the\catcode41%
+\catcode42=\the\catcode42%
+\catcode43=\the\catcode43%
+\catcode44=\the\catcode44%
+\catcode45=\the\catcode45%
+\catcode46=\the\catcode46%
+\catcode58=\the\catcode58%
+\catcode59=\the\catcode59%
+\catcode60=\the\catcode60%
+\catcode61=\the\catcode61%
+\catcode62=\the\catcode62%
+\catcode64=\the\catcode64%
+\catcode91=\the\catcode91%
+\catcode93=\the\catcode93%
+\catcode94=\the\catcode94%
+\catcode95=\the\catcode95%
+\catcode126=\the\catcode126%
+\endlinechar=\the\endlinechar
+\relax}
+\catcode32=10 %< >
+\catcode33=12 %<">
+\catcode35=6 %<#>
+\catcode40=12 %<(>
+\catcode41=12 %<)>
+\catcode42=12 %<*>
+\catcode43=12 %<+>
+\catcode44=12 %<,>
+\catcode45=12 %<->
+\catcode46=12 %<.>
+\catcode58=12 %<:>
+\catcode59=12 %<;>
+\catcode60=12 %<<>
+\catcode61=12 %<=>
+\catcode62=12 %<>>
+\catcode64=11 %<@>
+\catcode91=12 %<[>
+\catcode93=12 %<]>
+\catcode94=7 %<^>
+\catcode95=8 %<_>
+\catcode126=13 %<~>
+\endlinechar=-1 %
+
+\edef\ltj@adjust@AtEnd{\x
+ \noexpand\let\noexpand\ltj@adjust@AtEnd\relax}
+\def\luatexjaadjustLoaded{\endinput}
+
+%% Check if LaTeX is used.
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax %<*!LaTeX>
+ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname
+ \csname iffalse\endcsname
+\else %<*LaTeX>
+ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname
+ \csname iftrue\endcsname
+ \NeedsTeXFormat{LaTeX2e}
+ \ProvidesPackage{luatexja-adjust}[2018/07/24]
+\fi %</LaTeX>
+
+% Load core module if not yet.
+% xkeyval.sty is already required in luatexja.sty.
+\ifx\luatexjacoreLoaded\@undefined
+ \ifltj@in@latex %<*LaTeX>
+ \RequirePackage{luatexja}
+ \else %<*!LaTeX>
+ \input luatexja.sty %
+ \fi %</LaTeX>
+\fi
+
+%% When environment check fails, exit now.
+\ifx\LuaTeXjaAvailable\@undefined
+ \ltj@otf@AtEnd
+\expandafter\endinput\fi\relax
+
+%%------------------
+
+%! Main part of luatexja-adjust
+\RequireLuaTeXjaSubmodule{adjust}
+
+\newcount\ltjadj@status@le
+\newcount\ltjadj@status@lp
+\newcount\ltjadj@status@pr
+\newcount\ltjadj@status@ls
+\let\ltj@adjust@temp=\relax
+\define@choicekey[ltj]{adjust}{lineend}[\@@temp\ltj@adjust@temp]%
+{false,true,extended}[true]{%
+ \ifnum\ltj@adjust@temp=-1 \else\ltjadj@status@le=\ltj@adjust@temp\fi\relax}
+\define@boolkey[ltj]{adjust}{priority}[true]{%
+ \ltjadj@status@pr=\ifltj@adjust@priority1\else0\fi\relax}
+\define@boolkey[ltj]{adjust}{profile}[true]{%
+ \ltjadj@status@lp=\ifltj@adjust@profile1\else0\fi\relax}
+\define@boolkey[ltj]{adjust}{linestep}[true]{%
+ \ltjadj@status@ls=\ifltj@adjust@linestep1\else0\fi\relax}
+
+\protected\def\@@ltjenableadjust[#1]{%
+ \setkeys[ltj]{adjust}{#1}%
+ \directlua{luatexja.adjust.enable_cb(
+ \the\ltjadj@status@le, \the\ltjadj@status@pr,
+ \the\ltjadj@status@lp, \the\ltjadj@status@ls)}\ignorespaces
+}
+\protected\def\ltjdisableadjust{%
+ \ltjenableadjust[lineend=false,priority=false,profile=false,linestep=false]}
+\protected\def\ltjenableadjust{%
+ \ltx@ifnextchar[{\@@ltjenableadjust}{\@@ltjenableadjust[lineend,priority]}}%]
+
+\ltjenableadjust
+
+%%% 優先順ä½ã®è¨­å®š
+\define@key[ltj]{adjpri}{kanjiskip}{%
+ \directlua{luatexja.adjust.priority_table[\the\count@][1] = token.scan_int()}#1\relax}
+\define@key[ltj]{adjpri}{xkanjiskip}{%
+ \directlua{luatexja.adjust.priority_table[\the\count@][2] = token.scan_int()}#1\relax}
+\define@key[ltj]{adjpri}{others}{%
+ \directlua{luatexja.adjust.priority_table[\the\count@][3] = token.scan_int()}#1\relax}
+\define@key[ltj]{japaram}{stretch_priority}{%
+ \begingroup\count@=1 \setkeys[ltj]{adjpri}{#1}\relax
+ \directlua{luatexja.adjust.make_priority_table(1)}\endgroup}
+\define@key[ltj]{japaram}{shrink_priority}{%
+ \begingroup\count@=2 \setkeys[ltj]{adjpri}{#1}\relax
+ \directlua{luatexja.adjust.make_priority_table(2)}\endgroup}
+\ltjsetparameter{%
+ stretch_priority={kanjiskip=-35, xkanjiskip=-25, others=50},
+ shrink_priority={kanjiskip=-35, xkanjiskip=-25, others=50},
+}
+\define@key[ltj]{japaram}{linestep_factor}{%
+ \directlua{local d = #1; luatexja.adjust.step_factor=math.abs(d)}\relax}
+\define@key[ltj]{japaram}{profile_hgap_factor}{%
+ \directlua{luatexja.adjust.profile_hgap_factor = math.abs(#1)}\relax}
+
+
+%%------------------ all done
+\ltj@adjust@AtEnd
+\endinput
+%% EOF
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-ajmacros.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-ajmacros.sty
new file mode 100644
index 0000000000..ca187cc900
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-ajmacros.sty
@@ -0,0 +1,844 @@
+%
+% luatexja-ajmacros.sty
+%
+% Original:
+% \ProvidesPackage{ajmacros}[2019/04/01 21:00 iNOUE Koich! <inoue@ma.ns.musashi-tech.ac.jp>]
+%
+
+
+%% Avoid multiple loading.
+\csname\if11luatexjaajmacrosLoaded\fi\endcsname
+\edef\x{%
+\catcode32=\the\catcode32%
+\catcode33=\the\catcode33%
+\catcode35=\the\catcode35%
+\catcode40=\the\catcode40%
+\catcode41=\the\catcode41%
+\catcode42=\the\catcode42%
+\catcode43=\the\catcode43%
+\catcode44=\the\catcode44%
+\catcode45=\the\catcode45%
+\catcode46=\the\catcode46%
+\catcode58=\the\catcode58%
+\catcode59=\the\catcode59%
+\catcode60=\the\catcode60%
+\catcode61=\the\catcode61%
+\catcode62=\the\catcode62%
+\catcode64=\the\catcode64%
+\catcode91=\the\catcode91%
+\catcode93=\the\catcode93%
+\catcode94=\the\catcode94%
+\catcode95=\the\catcode95%
+\catcode126=\the\catcode126%
+\endlinechar=\the\endlinechar
+\relax}
+\catcode32=10 %< >
+\catcode33=12 %<">
+\catcode35=6 %<#>
+\catcode40=12 %<(>
+\catcode41=12 %<)>
+\catcode42=12 %<*>
+\catcode43=12 %<+>
+\catcode44=12 %<,>
+\catcode45=12 %<->
+\catcode46=12 %<.>
+\catcode58=12 %<:>
+\catcode59=12 %<;>
+\catcode60=12 %<<>
+\catcode61=12 %<=>
+\catcode62=12 %<>>
+\catcode64=11 %<@>
+\catcode91=12 %<[>
+\catcode93=12 %<]>
+\catcode94=7 %<^>
+\catcode95=8 %<_>
+\catcode126=13 %<~>
+\endlinechar=-1 %
+
+\edef\ltj@ajmacros@AtEnd{\x
+ \noexpand\let\noexpand\ltj@ajmacros@AtEnd\relax}
+\def\luatexjaajmacrosLoaded{\endinput}
+
+%% Check if LaTeX is used.
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax %<*!LaTeX>
+ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname
+ \csname iffalse\endcsname
+\else %<*LaTeX>
+ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname
+ \csname iftrue\endcsname
+ \NeedsTeXFormat{LaTeX2e}
+ \ProvidesPackage{luatexja-ajmacros}[2017/05/05]
+\fi %</LaTeX>
+
+%%------------------
+%! Main part of luatexja-ajmacros
+\newif\if@kana\@kanafalse
+%% for plain TeX
+\newcount\@tempcnta
+\newcount\@tempcntb
+\ifltj@in@latex\else
+ \def\@tw{\char"2}
+ \def\@ifstar#1#2#3{\ifx*#3\expandafter#1\else#2{#3}\fi}
+ \long\def\@gobble#1{}
+\fi
+
+{%
+\gdef\shift@CID#1#2{{\@tempcnta#1\advance\@tempcnta#2\CID{\@tempcnta}}}
+\gdef\ajTsumesuji{\@ifstar{\@@ajTsumesuji}{\@ajTsumesuji}}
+\global\let\ajTumesuji\ajTsumesuji
+\gdef\@ajTsumesuji#1#2{{\@tempcnta\unless\ifnum\ltjgetparameter{direction}=3 \ifcase#1\or780\or247\or9758\or9738\fi
+ \else\ifcase#1\or8736\or8966\or13274\or13254\fi\fi
+ \aj@expand\aj@Tsumesuji#2\@nil}}
+\gdef\@@ajTsumesuji#1{\@ajTsumesuji{\aj@expand\aj@count@toks#14321\@nil}{#1}}
+\gdef\aj@expand#1#2{\expandafter\@aj@expand\number#2!#1}
+\gdef\@aj@expand#1!#2{#2#1}
+\gdef\aj@count@toks#1#2#3#4#5#6\@nil{#5}
+\gdef\aj@Tsumesuji#1{\ifx\@nil#1\else\shift@CID{\@tempcnta}{#1}%
+ \expandafter\aj@Tsumesuji
+ \fi}
+\gdef\ajMaru{\@ifstar{\@aj@Maru}{\aj@Maru}}
+\gdef\aj@Maru#1{\ifnum#1=\z@ \CID{8224}%
+ \else\ifnum#1<21 \shift@CID{#1}{7554}%
+ \else\ifnum#1=21 \CID{8091}%
+ \else\ifnum#1<32 \shift@CID{#1}{8080}%
+ \else\shift@CID{#1}{10212}%
+ \fi\fi\fi\fi}
+\gdef\@aj@Maru#1{\ifnum#1<10 \shift@CID{#1}{10234}%
+ \else\ifnum#1<21 \shift@CID{#1}{7554}%
+ \else\ifnum#1=21 \CID{8091}%
+ \else\ifnum#1<32 \shift@CID{#1}{8080}%
+ \else\shift@CID{#1}{10212}%
+ \fi\fi\fi\fi}
+\gdef\ajKuroMaru{\@ifstar{\@aj@KuroMaru}{\aj@KuroMaru}}
+\gdef\aj@KuroMaru#1{\ifnum#1=\z@ \CID{10503}%
+ \else\ifnum#1<10 \shift@CID{#1}{8285}%
+ \else\shift@CID{#1}{10504}%
+ \fi\fi}
+\gdef\@aj@KuroMaru#1{\shift@CID{#1}{10504}}
+\gdef\ajKaku{\@ifstar{\@aj@Kaku}{\aj@Kaku}}
+\gdef\aj@Kaku#1{\ifnum#1<10{\@tempcnta#1\multiply\@tempcnta\tw@
+ \shift@CID{\@tempcnta}{10764}}%
+ \else\shift@CID{#1}{10774}%
+ \fi}
+\gdef\@aj@Kaku#1{\ifnum#1<10{\@tempcnta#1\multiply\@tempcnta\tw@
+ \shift@CID{\@tempcnta}{10765}}%
+ \else\shift@CID{#1}{10774}%
+ \fi}
+\gdef\ajKuroKaku{\@ifstar{\@aj@KuroKaku}{\aj@KuroKaku}}
+\gdef\aj@KuroKaku#1{\ifnum#1<10{\@tempcnta#1\multiply\@tempcnta\tw@
+ \shift@CID{\@tempcnta}{11037}}%
+ \else\shift@CID{#1}{11047}%
+ \fi}
+\gdef\@aj@KuroKaku#1{\ifnum#1<10{\@tempcnta#1\multiply\@tempcnta\tw@
+ \shift@CID{\@tempcnta}{11038}}%
+ \else\shift@CID{#1}{11047}%
+ \fi}
+\gdef\ajMaruKaku{\@ifstar{\@aj@MaruKaku}{\aj@MaruKaku}}
+\gdef\aj@MaruKaku#1{\ifnum#1<10{\@tempcnta#1\multiply\@tempcnta\tw@
+ \shift@CID{\@tempcnta}{11307}}%
+ \else\shift@CID{#1}{11317}%
+ \fi}
+\gdef\@aj@MaruKaku#1{\ifnum#1<10{\@tempcnta#1\multiply\@tempcnta\tw@
+ \shift@CID{\@tempcnta}{11308}}%
+ \else\shift@CID{#1}{11317}%
+ \fi}
+\gdef\ajKuroMaruKaku{\@ifstar{\@aj@KuroMaruKaku}{\aj@KuroMaruKaku}}
+\gdef\aj@KuroMaruKaku#1{\ifnum#1<10{\@tempcnta#1\multiply\@tempcnta\tw@
+ \shift@CID{\@tempcnta}{11576}}%
+ \else\shift@CID{#1}{11586}%
+ \fi}
+\gdef\@aj@KuroMaruKaku#1{\ifnum#1<10{\@tempcnta#1\multiply\@tempcnta\tw@
+ \shift@CID{\@tempcnta}{11577}}%
+ \else\shift@CID{#1}{11586}%
+ \fi}
+\gdef\ajKakko{\@ifstar{\@aj@Kakko}{\aj@Kakko}}
+\gdef\aj@Kakko#1{\ifnum#1=\z@ \CID{8227}%
+ \else\ifnum#1<21 \shift@CID{#1}{8070}%
+ \else\shift@CID{#1}{9873}%
+ \fi\fi}
+\gdef\@aj@Kakko#1{\ifnum#1<10 \shift@CID{#1}{9884}%
+ \else\ifnum#1<21 \shift@CID{#1}{8070}%
+ \else\shift@CID{#1}{9873}%
+ \fi\fi}
+\gdef\ajRoman{\@ifstar{\@aj@Roman}{\aj@Roman}}
+\gdef\aj@Roman#1{\ifnum#1<11 \shift@CID{#1}{7574}%
+ \else\ifnum#1<13 \shift@CID{#1}{8214}%
+ \else\shift@CID{#1}{8282}%
+ \fi\fi}
+\gdef\@aj@Roman#1{\ifnum#1=4 \CID{9883}\else\aj@Roman{#1}\fi}
+\gdef\ajroman#1{\ifnum#1<11 \shift@CID{#1}{8091}%
+ \else\shift@CID{#1}{8287}%
+ \fi}
+\gdef\ajPeriod#1{\ifnum#1<10 \shift@CID{#1}{8061}\else\shift@CID{#1}{20577}\fi}%AJ1-6
+\gdef\ajKakkoalph#1{\shift@CID{#1}{8111}}
+\gdef\ajKakkoYobi#1{\shift@CID{#1}{8196}}
+\gdef\ajKakkoroman#1{\shift@CID{#1}{9973}}
+\gdef\ajKakkoRoman#1{\shift@CID{#1}{9988}}
+\gdef\ajKakkoAlph#1{\shift@CID{#1}{10003}}
+\gdef\ajKakkoHira#1{\shift@CID{#1}{10029}}
+\gdef\ajKakkoKata#1{\shift@CID{#1}{10077}}
+\gdef\ajKakkoKansuji#1{\shift@CID{#1}{10125}}
+\gdef\ajMaruKansuji#1{\shift@CID{#1}{10460}}
+\gdef\ajNijuMaru#1{\shift@CID{#1}{16222}}
+\gdef\ajRecycle#1{\shift@CID{#1}{16314}}
+\gdef\ajHasenKakuAlph#1{\shift@CID{#1}{20496}}%AJ1-6
+\gdef\ajCross#1{\shift@CID{#1}{20523}}%AJ1-6
+\gdef\ajSlanted{\@ifstar{\aj@Slanted}{\@aj@Slanted}}%AJ1-6
+\gdef\aj@Slanted#1{\shift@CID{#1}{20589}}%AJ1-6
+\gdef\@aj@Slanted#1{\ifnum#1<10 \shift@CID{#1}{9460}\else\shift@CID{#1}{20589}\fi}%AJ1-6
+\gdef\ajApostrophe#1{\shift@CID{#1}{20649}}%AJ1-6
+\global\let\ajYear\ajApostrophe%AJ1-6
+\gdef\ajSquareMark{\@ifstar{\aj@SquareMark}{\@ifnextchar+{\@aj@SquareMark}{\@ajSquareMark}}}
+\gdef\@ajSquareMark#1{\shift@CID{#1}{12229}}
+\gdef\aj@SquareMark#1{\shift@CID{#1}{12241}}
+\gdef\@aj@SquareMark+#1{\shift@CID{#1}{\ifodd\@tempcnta24459\else24482\fi
+ \divide\@tempcnta\tw@}}
+\gdef\ajHishi#1{\shift@CID{#1}{12256}}
+%
+\let\offsetalph\z@
+\chardef\offsetAlph26
+\chardef\offsetHira26
+\chardef\offsetKata48
+\chardef\offsetYobi48
+\let\offsetMaru\z@
+\chardef\offsetKuroMaru144
+\chardef\offsetKaku122
+\chardef\offsetKuroKaku125
+\chardef\offsetMaruKaku122
+\chardef\offsetKuroMaruKaku121
+\@tempcnta10312
+\def\@aj@sujidef#1{\ifx\@nil#1%
+ \else\advance\@tempcnta\csname offset#1\endcsname
+ \expandafter\xdef\csname aj\@ajsujifam#1\endcsname##1%
+ {\noexpand\shift@CID{##1}{\number\@tempcnta}}%
+ \expandafter\@aj@sujidef\fi}
+\def\@ajsujidef#1{\ifx\@nil#1%
+ \else\advance\@tempcnta\csname offset#1\endcsname
+ \def\@ajsujifam{#1}%
+ \@aj@sujidef{alph}{Alph}{Hira}{Kata}{Yobi}\@nil
+ \expandafter\@ajsujidef\fi}
+\@ajsujidef{Maru}{KuroMaru}{Kaku}{KuroKaku}{MaruKaku}{KuroMaruKaku}\@nil
+\gdef\ajMaruYobi#1{\ifnum#1<8 \shift@CID{#1}{10470}%
+ \else\ifnum#1=8 \CID{10492}%
+ \else\ifnum#1=9 \CID{10487}%
+ \fi\fi\fi}
+%
+\gdef\ajTsumekakko#1{\aj@expand\@ajTsumekakko#1\@nil}
+\global\let\ajTumekakko\ajTsumekakko
+\gdef\@ajTsumekakko#1#2{\ifx\@nil#2\mbox{\unless\ifnum\ltjgetparameter{direction}=3 \rlap{\CID{10233}}\shift@CID{#1}{9872}%
+ \else\CID{13268}\shift@CID{#1}{10185}\CID{13269}\fi}%
+ \expandafter\@gobble
+ \else\shift@CID{#1}{\unless\ifnum\ltjgetparameter{direction}=3 10152\else10174\fi}%
+ \expandafter\aj@Tsumekakko
+ \fi#2}
+\gdef\aj@Tsumekakko#1#2{\ifx\@nil#2\shift@CID{#1}{\unless\ifnum\ltjgetparameter{direction}=3 10162\else10196\fi}%
+ \expandafter\@gobble
+ \else\shift@CID{#1}{\unless\ifnum\ltjgetparameter{direction}=3 247\else10185\fi}%
+ \expandafter\aj@Tsumekakko
+ \fi#2}
+\gdef\ajNenrei#1{\ifcase#1\relax\expandafter\ajTsumekakko\or\expandafter\aj@NenreiTu
+ \or\expandafter\aj@NenreiSai\or\expandafter\aj@Nenrei@Tu
+ \or\expandafter\aj@Nenrei@Sai
+ \fi}
+\gdef\aj@NenreiTu#1{\aj@expand\@aj@NenreiTu#1\@nil}
+\gdef\@aj@NenreiTu#1#2{\shift@CID{#1}{\unless\ifnum\ltjgetparameter{direction}=3 10152\else10174\fi}%
+ \ifx\@nil#2\CID{\unless\ifnum\ltjgetparameter{direction}=3 10172\else10206\fi}\expandafter\@gobble
+ \else\expandafter\aj@Tsumekakko
+ \fi#2}
+\gdef\aj@NenreiSai#1{\aj@expand\@aj@NenreiSai#1\@nil}
+\gdef\@aj@NenreiSai#1{\shift@CID{#1}{\unless\ifnum\ltjgetparameter{direction}=3 10152\else10174\fi}\@aj@NenreiSai@}
+\gdef\@aj@NenreiSai@#1{\ifx\@nil#1\CID{\unless\ifnum\ltjgetparameter{direction}=3 10173\else10207\fi}%
+ \else\shift@CID{#1}{\unless\ifnum\ltjgetparameter{direction}=3 247\else10185\fi}%
+ \expandafter\@aj@NenreiSai@\fi}
+\gdef\aj@Nenrei@Tu#1{\ifnum#1<10 \shift@CID{#1}{10174}\CID{10206}%
+ \else\expandafter\@aj@Nenrei@Tu\number#1%
+ \fi}
+\gdef\@aj@Nenrei@Tu#1#2{\ifnum#2=\z@ \shift@CID{#1}{10174}\CID{10196}%
+ \else\ifnum#1<\tw@ \CID{10184}%
+ \else\shift@CID{#1}{10174}\CID{10195}%
+ \fi
+ \shift@CID{#2}{10196}%
+ \fi}
+\gdef\aj@Nenrei@Sai#1{\ifnum#1<10 \shift@CID{#1}{10174}%
+ \else\expandafter\@aj@Nenrei@Sai\number#1%
+ \fi\CID{10207}}
+\gdef\@aj@Nenrei@Sai#1#2{\ifnum#1<\tw@ \CID{10184}%
+ \else\shift@CID{#1}{10174}\CID{10195}%
+ \fi
+ \ifnum#2>\z@ \shift@CID{#2}{10185}%
+ \fi}
+\gdef\ajnenrei#1#2{\hskip\ltjgetparameter{kanjiskip}\hbox{\tate\ifnum#2<10
+ \shift@CID{#2}{10207}\CID{\ifcase#1\or10230\or10232\or10231\or10229\fi}%
+ \else\ifnum#2=10\CID{\ifodd#1 10208\else10217\fi}%
+ \CID{\ifcase#1\or10218\or10232\or10218\or10229\fi}%
+ \else\ifnum#2<20\CID{\ifodd#1 10208\else10217\fi}\shift@CID{#2}{10208}%
+ \else\expandafter\aj@nenrei\number#2{#1}%
+ \fi\fi\fi}}
+\gdef\aj@nenrei#1#2#3{\shift@CID{#1}{10207}%
+ \ifcase#2 \CID{\ifodd#3 10218\else10228\fi}%
+ \else\shift@CID{#2}{10218}%
+ \fi}
+\gdef\ajKosu{\ajnenrei4}
+%
+\gdef\ajLabel#1#2#{\ifx\\#2\\\aj@Label#1\else\@aj@Label#1#2\fi}
+\gdef\aj@Label#1\else#2\fi#3{\fi
+ \expandafter\protect
+ \expandafter#1%
+ \expandafter{\number\csname c@#3\endcsname}}
+\gdef\@aj@Label#1#2\fi#3{\fi
+ \expandafter\protect
+ \expandafter#1%
+ \expandafter#2%
+ \expandafter{\number\csname c@#3\endcsname}}
+%
+%
+\gdef\ajFrac{\@ifstar{\@aj@Frac}{\aj@Frac}}
+\gdef\@ajFrac#1#2{\ifcase#2\or
+ \or\ifcase#1\or9826\fi
+ \or\ifcase#1+9825\or9827\or9828\fi
+ \or\ifcase#1\or9829\or9826\or9830\fi
+ \or\ifcase#1\or9831\or9832\or9833\or9834\fi
+ \or\ifcase#1\or9835\or9827\or9826\or9828\or9836\fi
+ \or\ifcase#1\or9837\or9838\or9839\or9840\or9841\or9842\fi
+ \or\ifcase#1\or9843\or9829\or9844\or9826\or9845\or9830\or9846\fi
+ \or\ifcase#1\or9847\or9848\or9827\or9849\or9850\or9828\or9851\or9852\fi
+ \or\ifcase#1\or9853\or9831\or9854\or9832\or9826\or9833\or9855\or9834\or9856\fi
+ \or\ifcase#1\or9857\or9858\or9859\or9860\or9861\or9862\or9863\or9864\or9865\or9866\fi
+ \or\ifcase#1\or9867\or9835\or9829\or9827\or9868\or9826\or9869\or9828\or9830\or9836
+ \or9870\fi
+ \else\ifnum#2=100 \ifnum#1=1 9871\fi\fi
+ \fi}
+\gdef\@aj@Frac#1#2{\CID{\@ajFrac{#1}{#2}}}
+\gdef\aj@Frac#1#2{{\@tempcnta\@ajFrac{#1}{#2}%
+ \advance\@tempcnta-9825
+ \advance\@tempcnta\ifcase\@tempcnta9780\or8183\or9779\or9779\or8181\else9778\fi\relax
+ \CID{\@tempcnta}}}
+%1/4 161 8880 9604 13120
+%1/2 162 8881 9605 13121
+%3/4 163 8882 9606 13122
+%1/8 9371 12887 9691 13207
+%3/8 9372 12888 9692 13208
+%5/8 9373 12889 9693 13209
+%7/8 9374 12890 9694 13210
+%1/3 9375 12891 9695 13211
+%2/3 9376 12892 9696 13212
+%
+%
+\def\@ajåŠè§’def#1{\ifx\@nil#1\else
+ \expandafter\xdef\csname ajåŠè§’@#1\endcsname{\noexpand\CID
+ {\noexpand\unless\noexpand\ifnum\noexpand\ltjgetparameter\noexpand{direction\noexpand}=3 \number\@tempcnta\noexpand\else\number\@tempcntb\noexpand\fi}}%
+ \advance\@tempcnta\@ne\advance\@tempcntb\@ne
+ \expandafter\@ajåŠè§’def\fi}
+\@tempcnta326
+\@tempcntb9084
+\@ajåŠè§’def  。「ã€ã€ãƒ»ãƒ²ã‚¡ã‚£ã‚¥ã‚§ã‚©ãƒ£ãƒ¥ãƒ§ãƒƒãƒ¼ã‚¢ã‚¤ã‚¦ã‚¨ã‚ªã‚«ã‚­ã‚¯ã‚±ã‚³ã‚µã‚·ã‚¹ã‚»ã‚½ã‚¿ãƒãƒ„テトナニヌãƒãƒŽãƒãƒ’フヘホマミムメモヤユヨラリルレロワン゛゜`ヰヱヮヵヶヴガギグゲゴザジズゼゾダヂヅデドãƒãƒ‘ビピブプベペボãƒ\@nil
+\@tempcnta516
+\@ajåŠè§’def ã‚’ããƒã…ã‡ã‰ã‚ƒã‚…ょã£ã‚ã„ã†ãˆãŠã‹ããã‘ã“ã•ã—ã™ã›ããŸã¡ã¤ã¦ã¨ãªã«ã¬ã­ã®ã¯ã²ãµã¸ã»ã¾ã¿ã‚€ã‚もやゆよらりるれã‚ã‚ã‚“ã‚ã‚‘ã‚ŽãŒãŽãã’ã”ã–ã˜ãšãœãžã ã¢ã¥ã§ã©ã°ã±ã³ã´ã¶ã·ã¹ãºã¼ã½\@nil
+\gdef\ajåŠè§’#1{\aj@åŠè§’#1\@nil}
+\gdef\aj@åŠè§’#1{\ifx\@nil#1\else
+ \expandafter\ifx\csname ajåŠè§’@#1\endcsname\relax
+ #1\else\csname ajåŠè§’@#1\endcsname\fi
+ \expandafter\aj@åŠè§’\fi}
+%
+%
+\def\@ajligdef#1#2{\expandafter\xdef\csname ajLig\@ajmojifam#1\endcsname{\noexpand\CID{#2}}}
+\def\@ajligaturedef#1{\ifx\@nil#1\else
+ \@ajligdef{#1}{\number\@tempcnta}\advance\@tempcnta\@ne
+ \expandafter\@ajligaturedef\fi}
+\def\@aj@ligdef#1#2#3{\expandafter\xdef\csname ajLig\@ajmojifam#1\endcsname
+ {\unexpanded{\unless\ifnum\ltjgetparameter{direction}=3 }%
+ \noexpand\CID{#2}\noexpand\else\noexpand\CID{#3}\noexpand\fi}}
+\def\@aj@ligaturedef#1{\ifx\@nil#1\else
+ \@aj@ligdef{#1}{\number\@tempcnta}{\number\@tempcntb}%
+ \advance\@tempcnta\@ne\advance\@tempcntb\@ne
+ \expandafter\@aj@ligaturedef\fi}
+%
+\let\@ajmojifam\@empty
+\@tempcnta12111
+\@ajligaturedef{!!}{!?}{!*}{!!*}{!?*}\@nil
+\@ajligdef{?!}{16279}
+\@ajligdef{??}{16278}
+%
+\let\@ajmojifam\@empty
+\@tempcnta7601
+\@ajligaturedef{mm}{cm}{km}{mg}{kg}{cc}{m2}\@nil
+\@tempcnta7610
+\@ajligaturedef{No.}{K.K.}{TEL}\@nil
+\@tempcnta8020
+\@ajligaturedef{cm2}{km2}{cm3}{m3}{dl}{l}{kl}{ms}{micros}{ns}{ps}{KB}{MB}{GB}{HP}{Hz}{mb}{ml}\@nil
+\@ajligdef{KK.}{8053}
+\@ajligdef{Tel}{8055}
+\@ajligdef{in}{8182}
+\@tempcnta8186
+\@ajligaturedef{mm2}{mm3}{km3}{sec}{min}\@nil
+\@tempcnta8192
+\@ajligaturedef{cal}{kcal}{dB}\@nil
+\@tempcnta8303
+\@ajligaturedef{m}{g}{F}{TB}{FAX}{JIS}\@nil
+\@ajligdef{euro}{9779}
+\@aj@ligdef{euro*}{9354}{12870}
+\@aj@ligdef{ohm*}{9355}{12871}
+\@ajligdef{mho}{16204}
+\@aj@ligdef{mho*}{15515}{16526}
+\@aj@ligdef{No*}{20321}{20965}%AJ1-6
+\@tempcnta11846
+\@ajligaturedef{AM}{KK}{No}{PH}{PM}{PR}{tel}{tm}{VS}{a/c}{a.m.}{c/c}{c.c.}{c/o}{dl*}{hPa}{kl*}{l*}{microg}{microm}{ml*}{m/m}{n/m}{pH}{p.m.}\@nil
+\@ajligdef{JAS}{12088}
+\@tempcnta20919
+\@ajligaturedef{ppb}{ppm}{'S}{H2}{O2}{Ox}{Nx}{Q2}{Jr.}{Dr.}\@nil%AJ1-6
+%
+\let\@ajmojifam\@empty
+\@tempcnta7621
+\@tempcntb12041
+\@aj@ligaturedef{明治}{大正}{昭和}\@nil
+\@tempcnta7585
+\@tempcntb7940
+\@aj@ligaturedef{ミリ}{キロ}{センãƒ*}{メートル}{グラム*}{トン}{アール*}{ヘクタール}{リットル}{ワット*}{カロリー}{ドル}{セント*}{パーセント}{ミリãƒãƒ¼ãƒ«}{ページ*}\@nil
+\@aj@ligdef{センãƒ}{8038}{8329}
+\@aj@ligdef{キロメートル}{8039}{8330}
+\@aj@ligdef{グラム}{8040}{8339}
+\@aj@ligdef{キログラム}{8041}{8340}
+\@aj@ligdef{アール}{8042}{8338}
+\@aj@ligdef{セント}{8043}{8348}
+\@aj@ligdef{ワット}{8044}{8344}
+\@aj@ligdef{ホーン}{8045}{8347}
+\@aj@ligdef{ヘルツ}{8046}{8343}
+\@aj@ligdef{ページ}{8047}{8349}
+\@aj@ligdef{アパート}{8048}{8350}
+\@aj@ligdef{ビル}{8049}{8358}
+\@aj@ligdef{マンション}{8050}{8357}
+\@aj@ligdef{コーãƒ}{8051}{8353}
+\@aj@ligdef{ãƒã‚¤ãƒ„}{8052}{8356}
+\@aj@ligdef{æ ªå¼ä¼šç¤¾}{8054}{8324}
+\@aj@ligdef{インãƒ}{8183}{8333}
+\@aj@ligdef{有é™ä¼šç¤¾}{8321}{8325}
+\@aj@ligdef{財団法人}{8322}{8326}
+\@aj@ligdef{å¹³æˆ}{8323}{12044}
+\@aj@ligdef{フィート}{8327}{8334}
+\@aj@ligdef{ヤード}{8328}{8337}
+\@aj@ligdef{インãƒ*}{8331}{8332}
+\@aj@ligdef{ヤード*}{8335}{8336}
+\@aj@ligdef{ヘルツ*}{8341}{8342}
+\@aj@ligdef{ホーン*}{8345}{8346}
+\@aj@ligdef{コーãƒ*}{8351}{8352}
+\@aj@ligdef{ãƒã‚¤ãƒ„*}{8354}{8355}
+\@aj@ligdef{ã•ã˜}{11871}{11872}
+\@tempcnta11873
+\@tempcntb11957
+\@aj@ligaturedef{アト}{アルファ}{アンペア}{イニング}{ウォン}{ウルシ}{エーカー}{エクサ}{エスクード}{オーム}{オングストローム}{オンス}{オントロ}{カイリ}%
+{カップ}{カラット}{ガロン}{ガンマ}{ギガ}{ギニー}{キュリー}{ギルダー}{キロリットル}{キロワット}{グスーム}{グラムトン}{クルサード}{クルゼイロ}{クローãƒ}%
+{ケース}{コルナ}{サイクル}{サンãƒãƒ¼ãƒ }{シリング}{ダース}{デカ}{デシ}{テラ}{ドラクマ}{ナノ}{ノット}{ãƒãƒ¼ãƒ„}{ãƒãƒ¼ãƒ¬ãƒ«}{パスカル}{ãƒãƒ¬ãƒ«}{ピアストル}{ピクル}%
+{ピコ}{ファラッド}{ファラド}{フェムト}{ブッシェル}{フラン}{ベータ}{ヘクト}{ヘクトパスカル}{ペセタ}{ペソ}{ペタ}{ペニヒ}{ペンス}{ãƒã‚¤ãƒ³ãƒˆ}{ホール}{ボルト}{ホン}%
+{ãƒãƒ³ãƒ‰}{マイクロ}{マイル}{マッãƒ}{マルク}{ミクロン}{メガ}{メガトン}{ヤール}{ユアン}{ユーロ}{ラド}{リラ}{ルーブル}{ルクス}{ルピア}{ルピー}{レム}{レントゲン}\@nil
+\@tempcnta12045
+\@tempcntb12054
+\@aj@ligaturedef{医療法人}{学校法人}{å…±åŒçµ„åˆ}{å”åŒçµ„åˆ}{åˆè³‡ä¼šç¤¾}{åˆå会社}{社団法人}{宗教法人}{郵便番å·}\@nil
+\expandafter\gdef\csname ajLigオングストローム*\endcsname
+ {\mbox{\kern.05zw\ajLig{オントロ}\kern-.1zw\ajLig{グスーム}\kern.05zw}}
+\@tempcnta20929
+\@tempcntb20943
+\@aj@ligaturedef{ガル}{グレイ}{クローナ}{シーベルト}{シェケル}{ジュール}{デシベル}{ドット}{ãƒã‚¤ãƒˆ}{ビット}{ベクレル}{ボー}{ランド}{リンギット}\@nil%AJ1-6
+\@ajligdef{より}{12181}
+\@ajligdef{å‡}{16194}
+\@ajligdef{コト}{16195}
+\@aj@ligdef{令和}{23058}{23059}%AJ1-7
+%
+\def\@ajmojifam{â—‹}
+\@tempcnta7613
+\@ajligaturedef 上中下左å³\@nil
+\@ajligdef{〒}{8057}
+\@tempcnta8152
+\@ajligaturedef 夜ä¼åŒ»å”å宗労学有株社監資財\@nil
+\@ajligdef{å°}{8191}
+\@ajligdef{秘}{8223}
+\@tempcnta8317
+\@ajligaturedef 大å°å„ªæŽ§\@nil
+\@tempcnta10478
+\@ajligaturedef 調注副減標欠基ç¦é …休女男正写ç¥å‡ºé©ç‰¹æ¸ˆå¢—å•ç­”例電\@nil%
+\@ajligdef{å¹´}{20553}%AJ1-6
+%
+\def\@ajmojifam#1{(#1)}
+\@ajligdef{æ ª}{7618}
+\@ajligdef{有}{7619}
+\@ajligdef{代}{7620}
+\@tempcnta8138
+\@ajligaturedef 至ä¼å”å労社監自資財特学祭呼\@nil
+\@ajligdef{ç¥}{8204}
+\@ajligdef{休}{8205}
+\@tempcnta10146
+\@ajligaturedef å–¶åˆæ³¨å•ç­”例\@nil
+%
+\def\@ajmojifam{â–¡}
+\@ajligdef{å°}{8196}
+\@ajligdef{è² }{11030}
+\@ajligdef{å‹}{11031}
+\@tempcnta20497
+\@ajligaturedef{:A}{:B}{:C}{:D}{:E}{:F}{:終}\@nil%AJ1-6
+\@tempcnta20505
+\@ajligaturedef{:CL}{:KCL}{:BEL}{:AS}{:AM}{:段}{:ゴ}{:ミ}\@nil%AJ1-6
+%
+\def\@ajmojifam{â—‡}
+\@tempcnta20554
+\@ajligaturedef {News}天å†æ–°æ˜ å£°å‰å¾Œçµ‚立交{ã»ã‹}劇å¸è§£æ ªæ°—二多文手{PV}{MV}åŒ{SS}{S1}{S2}{S3}デ{HV}\@nil%AJ1-6
+%
+\def\@ajmojifam{â–½}
+\@ajligdef{〒}{12180}
+\@ajligdef{â–½}{12193}
+%
+\def\@ajmojifam{â–³}
+\@ajligdef{!}{12192}
+%
+\def\@ajmojifam{â– }
+\@ajligdef{â—‡}{12231}
+%
+\expandafter\chardef\csname offsetâ—\endcsname\z@
+\expandafter\mathchardef\csname offsetâ–¡\endcsname269
+\expandafter\mathchardef\csname offsetâ– \endcsname268
+\expandafter\mathchardef\csname offsetâ—‡\endcsname267
+\expandafter\mathchardef\csname offsetâ—†\endcsname266
+\@tempcnta10760
+\def\@ajmojidef#1{\ifx\@nil#1%
+ \else\advance\@tempcnta\csname offset#1\endcsname
+ \def\@ajmojifam{#1}%
+ \@ajligaturedef å•ç­”例\@nil
+ \expandafter\@ajmojidef\fi}
+\@ajmojidef â—□■◇◆\@nil
+%
+\def\@ajkanadef#1#2#3#4#5#6#7{\expandafter\gdef\csname ajLig#1\endcsname
+ {\if@kana\def\reserved@a{ruby}%
+ \ifx\k@family\reserved@a
+ \unless\ifnum\ltjgetparameter{direction}=3 \CID{#6}\else\CID{#7}\fi
+ \else\unless\ifnum\ltjgetparameter{direction}=3 \CID{#4}\else\CID{#5}\fi
+ \fi
+ \else\unless\ifnum\ltjgetparameter{direction}=3 \CID{#2}\else\CID{#3}\fi
+ \fi}}
+\newcount\@tempcntc
+\newcount\@tempcntd
+\newcount\@tempcnte
+\newcount\@tempcntf
+\def\@aj@kanadef#1{\ifx\@nil#1%
+ \else\edef\reserved@b{\noexpand\@ajkanadef{#1}%
+ {\number\@tempcnta}{\number\@tempcntb}{\number\@tempcntc}%
+ {\number\@tempcntd}{\number\@tempcnte}{\number\@tempcntf}}\reserved@b
+ \advance\@tempcnta\@ne\advance\@tempcntb\@ne\advance\@tempcntc\@ne
+ \advance\@tempcntd\@ne\advance\@tempcnte\@ne\advance\@tempcntf\@ne
+ \expandafter\@aj@kanadef\fi}
+\@ajkanadef{ã†ã‚›}{7958}{7958}{12361}{12544}{12756}{12756}
+\@tempcnta8313
+\@tempcntb8313
+\@tempcntc12452
+\@tempcntd12635
+\@tempcnte16444
+\@tempcntf16444
+\@aj@kanadef{ワ゛}{ヰ゛}{ヱ゛}{ヲ゛}\@nil
+\@tempcnta16209
+\@tempcntb16209
+\@tempcntc16352
+\@tempcntd16382
+\@tempcnte16414
+\@tempcntf16414
+\@aj@kanadef{ã‹ã‚œ}{ãã‚œ}{ãã‚œ}{ã‘ã‚œ}{ã“ã‚œ}{ã‚«ã‚œ}{ã‚­ã‚œ}{ク゜}{ケ゜}{コ゜}{セ゜}{ツ゜}{ト゜}\@nil
+\@ajkanadef{å°ã‹}{7959}{8264}{12285}{12468}{12682}{12762}
+\@ajkanadef{å°ã‘}{7960}{8265}{12292}{12475}{12689}{12763}
+\@ajkanadef{å°ã“}{12269}{12270}{12295}{12478}{16448}{16467}
+\@ajkanadef{å°ã‚³}{12271}{12272}{12385}{12568}{16449}{16468}
+\@tempcnta16236
+\@tempcntb16333
+\@tempcntc16365
+\@tempcntd16395
+\@tempcnte16427
+\@tempcntf16450
+\@aj@kanadef{å°ã‚¯}{å°ã‚·}{å°ã‚¹}{å°ãƒˆ}{å°ãƒŒ}{å°ãƒ}{å°ãƒ’}{å°ãƒ•}{å°ãƒ˜}{å°ãƒ›}{å°ãƒ—}{å°ãƒ }{å°ãƒ©}{å°ãƒª}{å°ãƒ«}{å°ãƒ¬}{å°ãƒ­}\@nil
+%
+\def\@aj@numberdef#1#2{\ifx\@nil#2\expandafter\@gobble
+ \else\expandafter\xdef\csname ajnumber#2\endcsname{{#1}{\number\@tempcnta}}%
+ \advance\@tempcnta\@ne
+ \expandafter\@aj@numberdef\fi{#1}}
+\@tempcnta\@ne
+\@aj@numberdef{alph}abcdefghijklmnopqrstuvwxyz\@nil
+\@tempcnta\@ne
+\@aj@numberdef{Alph}ABCDEFGHIJKLMNOPQRSTUVWXYZ\@nil
+\@tempcnta\@ne
+\@aj@numberdef{Hira}ã‚ã„ã†ãˆãŠã‹ããã‘ã“ã•ã—ã™ã›ããŸã¡ã¤ã¦ã¨ãªã«ã¬ã­ã®ã¯ã²ãµã¸ã»ã¾ã¿ã‚€ã‚もやゆよらりるれã‚ã‚ã‚ã‚‘ã‚’ã‚“\@nil
+\@tempcnta\@ne
+\@aj@numberdef{Kata}アイウエオカキクケコサシスセソタãƒãƒ„テトナニヌãƒãƒŽãƒãƒ’フヘホマミムメモヤユヨラリルレロワヰヱヲン\@nil
+\@tempcnta\@ne
+\@aj@numberdef{Yobi}日月ç«æ°´æœ¨é‡‘土ç¥ä¼‘\@nil
+\gdef\@ajnumber#1{\expandafter\expandafter\expandafter\aj@number\csname ajnumber#1\endcsname}
+\gdef\aj@number#1{\ifx\relax#1\expandafter\@gobbletwo\else\expandafter\@aj@number\fi{#1}}
+\gdef\@aj@number#1#2#3{\csname aj#3#1\endcsname{#2}}
+%
+\def\@aj@kakomidef#1#2{\expandafter\gdef\csname#1\endcsname##1%
+ {\expandafter\ifx\csname ajLig#1##1\endcsname\relax\@ajnumber{##1}{#2}%
+ \else\csname ajLig#1##1\endcsname\fi}}
+\@aj@kakomidef{â—‹}{Maru}
+\@aj@kakomidef{â—}{KuroMaru}
+\@aj@kakomidef{â–¡}{Kaku}
+\@aj@kakomidef{â– }{KuroKaku}
+\@aj@kakomidef{â—‡}{MaruKaku}
+\@aj@kakomidef{â—†}{KuroMaruKaku}
+\gdef\â–³#1{\csname ajLigâ–³#1\endcsname}
+\gdef\â–½#1{\csname ajLigâ–½#1\endcsname}
+\gdef\(#1){\expandafter\ifx\csname ajLig(#1)\endcsname\relax\@ajnumber{#1}{Kakko}%
+ \else\csname ajLig(#1)\endcsname\fi}
+\gdef\ã‚›#1{\csname ajLig#1ã‚›\endcsname}
+\gdef\゜#1{\csname ajLig#1゜\endcsname}
+\gdef\ï¼#1{\csname ajLigå°#1\endcsname}
+\gdef\ajLig#1{\csname ajLig#1\endcsname}
+%
+%
+\def\@ajPICTdef#1#2{\expandafter\xdef\csname ajPICT#1\endcsname{\noexpand\CID{#2}}}
+\def\@aj@PICTdef#1{\ifx\@nil#1\else
+ \@ajPICTdef{#1}{\number\@tempcnta}\advance\@tempcnta\@ne
+ \expandafter\@aj@PICTdef\fi}
+\@tempcnta8016
+\@aj@PICTdef{Club}{Heart}{Spade}{Diamond}\@nil
+\@ajPICTdef{電話}{8056}
+\@ajPICTdef{〒}{8058}
+\@tempcnta8211
+\@aj@PICTdef{Spade*}{Heart*}{Club*}{Diamond*}\@nil
+\@tempcnta8215
+\@aj@PICTdef 晴曇雨雪→â†â†‘↓\@nil
+\@ajPICTdef{野çƒ}{12097}
+\@ajPICTdef{湯}{12098}
+\@ajPICTdef{花}{12228}
+\@ajPICTdef{花*}{12229}
+\@ajPICTdef{サッカー}{20957}%AJ1-6
+\gdef\ajPICT#1{\csname ajPICT#1\endcsname}
+\global\let\※\ajPICT
+%
+%
+\def\@ajArrowdef#1#2{\expandafter\xdef\csname ajArrow#1\endcsname{\noexpand\CID{#2}}}
+\def\@aj@Arrowdef#1{\ifx\@nil#1\else
+ \@ajArrowdef{#1}{\number\@tempcnta}\advance\@tempcnta\@ne
+ \expandafter\@aj@Arrowdef\fi}
+\@tempcnta8009
+\@aj@Arrowdef{LeftTriangle}{RightTriangle}{DOWN}{UP}{LEFT}{RIGHT}\@nil
+\@tempcnta8206
+\@aj@Arrowdef{RIGHT*}{LEFT*}{UP*}{DOWN*}\@nil
+\@tempcnta8219
+\@aj@Arrowdef{RightHand}{LeftHand}{UpHand}{DownHand}\@nil
+\@tempcnta8309
+\@aj@Arrowdef{Left/Right}{Right/Left}{Up/Down}{Down/Up}\@nil
+\@tempcnta12175
+\@aj@Arrowdef{LeftScissors}{RightScissors}{UpScissors}{DownScissors}\@nil
+\@tempcnta12194
+\@aj@Arrowdef
+{LeftTriangle*}{RightTriangle*}{Left}{Right}{Up}{Down}{LeftDouble}{LeftRight*}{RightDown}{LeftDown}{LeftUp}{RightUp}%
+{Right/Left*}{Left/Right*}{Right/Left+}{Down/Up+}{Left+}{Right+}{Up+}{Down+}{LeftRight+}{UpDown+}\@nil
+\@tempcnta12261
+\@aj@Arrowdef
+{LeftAngle}{RightAngle}{UpAngle}{DownAngle}{LeftAngle*}{RightAngle*}{UpAngle*}{DownAngle*}\@nil
+\@ajArrowdef{RightDouble}{15482}%752 16493
+\@ajArrowdef{LeftRightDouble}{15483}%753 16494
+%\@ajArrowdef{LeftRight}{15511}%12201 16522
+\@ajArrowdef{RightUp*}{16201}
+\@ajArrowdef{RightDown*}{16202}
+%\@ajArrowdef{DOWNLEFT*}{16273}
+\gdef\ajArrow#1{\csname ajArrow#1\endcsname}
+%
+%
+\def\@aj@kuntendef#1{\ifx\@nil#1%
+ \else\expandafter\xdef\csname aj訓点#1\endcsname
+ {\noexpand\CID{\number\@tempcnta}}%
+ \advance\@tempcnta\@ne
+ \expandafter\@aj@kuntendef
+ \fi}
+\@tempcnta16283
+\@aj@kuntendef |レ一二三四上中下甲乙丙ä¸å¤©åœ°äºº\@nil
+\gdef\aj@smallReten{{\@tempdimb\f@size pt\@tempskipa\f@baselineskip
+ \@tempdimb.94\@tempdimb
+ \@tempskipa.94\@tempskipa
+ \fontsize{\@tempdimb}{\@tempskipa}\selectfont\aj訓点レ}}
+\gdef\aj訓点一レ{\mbox{\tate\kern-.24zw\aj訓点一\kern-.65zw\raise.15zw\hbox{\aj@smallReten}}}
+\gdef\aj訓点上レ{\mbox{\tate\aj訓点上\kern-.3zw\raise.15zw\hbox{\aj@smallReten}}}
+\gdef\aj訓点甲レ{\mbox{\tate\aj訓点甲\kern-.25zw\raise.15zw\hbox{\aj@smallReten}}}
+\gdef\aj訓点天レ{\mbox{\tate\aj訓点天\kern-.4zw\raise.1zw\hbox{\aj@smallReten}}}
+\def\@ajongofudef#1{\ifx\@nil#1%
+ \else\expandafter\xdef\csname aj訓点#1|\endcsname
+ {\noexpand\mbox{\yoko\expandafter\noexpand\csname aj訓点#1\endcsname
+ \hbox to\z@{\hss\expandafter\noexpand\csname aj訓点|\endcsname\kern-.5zw}}}%
+ \expandafter\@ajongofudef\fi}
+\@ajongofudef 二三四中下乙丙ä¸åœ°äºº\@nil
+\expandafter\gdef\csname aj訓点 |\endcsname{\mbox{\yoko{ }\hbox to\z@{\hss\csname aj訓点|\endcsname\kern-.5zw}}}
+\def\@ajkungofudef#1{\ifx\@nil#1%
+ \else\expandafter\xdef\csname aj訓点|#1\endcsname
+ {\noexpand\mbox{\yoko\hbox to\z@{\hss\expandafter\noexpand\csname aj訓点|\endcsname\kern-.5zw}%
+ \expandafter\noexpand\csname aj訓点#1\endcsname}}%
+ \expandafter\@ajkungofudef\fi}
+\@ajkungofudef 二三四中下乙丙ä¸åœ°äºº\@nil
+\expandafter\gdef\csname aj訓点| \endcsname{\mbox{\yoko\hbox to\z@{\hss\csname aj訓点|\endcsname\kern-.5zw}{ }}}
+%
+\gdef\ajKunten#1{\csname aj訓点#1\endcsname}
+%
+\newtoks\@temptokenb
+\newtoks\@temptokenc
+\gdef\ajRedefine@KundokuMacros{\ifx\kokana\@undefined
+ \else\let\orig@kokana\kokana
+ \let\orig@retenform\retenform
+ \let\orig@reten\reten
+ \let\orig@retenkana\retenkana
+ \let\orig@kaeriten\kaeriten
+ \def\aj@kokana##1##2{\orig@kokana{\aj@kundokusize\if@kana\rubyfamily\fi##1}%
+ {\aj@kundokusize\ajKunten{##2}}}%
+ \def\aj@retenform{\aj@kundokusize\aj訓点レ}%
+ \def\aj@reten{\orig@kaeriten{\aj@kundokusize\aj訓点レ}}%
+ \def\aj@retenkana##1{\orig@retenkana{\aj@kundokusize\if@kana\rubyfamily\fi##1}}%
+ \def\aj@kaeriten##1{\orig@kaeriten{\aj@kundokusize\ajKunten{##1}}}%
+ \let\aj@kundokusize\tiny
+ \fi
+ \ifx\@k@nd@ku@\@undefined
+ \else{\global\let\orig@k@nd@ku@\@k@nd@ku@
+ \def\get@hbox##1\hbox##2##3\get@hbox
+ {\@temptokena{##1}\@temptokenb{##2}\@temptokenc{##3}}%
+ \expandafter\get@hbox
+ \@k@nd@ku@[##1]{##2}{##3}{##4}{\ajKunten{##5}}[\ajKunten{##6}]<##7>(##8)\get@hbox
+ \def\change@reten##1\def\temptopleft##2\def\tempbottomleft##3##4\change@reten
+ {\@temptokenb{##1\def\temptopleft{####6}\def\tempbottomleft{####5}##4}}%
+ \expandafter\change@reten\the\@temptokenb\change@reten
+ \edef\redefine@k@nd@ku@##1{\gdef\noexpand\aj@k@nd@ku@##1%
+ {\the\@temptokena\hbox{\the\@temptokenb}\the\@temptokenc}}%
+ \redefine@k@nd@ku@{[##1]##2##3##4##5[##6]<##7>(##8)}}%
+ \let\aj@kundokusize\kundokusize
+ \fi}
+\ifltj@in@latex
+ \@onlypreamble\ajRedefine@KundokuMacros
+ \AtBeginDocument{\ajRedefine@KundokuMacros}
+\fi
+\gdef\DeclareOriginalKundokuStyle{\@ifnextchar[%]
+ {\Declare@OriginalKundokuStyle}%
+ {\Declare@OriginalKundokuStyle[\aj@kundokusize]}}
+\gdef\Declare@OriginalKundokuStyle[#1]{\let\aj@kundokusize#1%
+ \ifx\orig@k@nd@ku@\@undefined
+ \else\let\@k@nd@ku@\orig@k@nd@ku@
+ \let\kundokusize\aj@kundokusize
+ \fi
+ \ifx\orig@kokana\@undefined
+ \else
+ \let\kokana\orig@kokana
+ \let\retenform\orig@retenform
+ \let\reten\orig@reten
+ \let\retenkana\orig@retenkana
+ \let\kaeriten\orig@kaeriten
+ \fi}
+\gdef\DeclareAJKundokuStyle{\@ifnextchar[%]
+ {\Declare@AJKundokuStyle}%
+ {\Declare@AJKundokuStyle[\aj@kundokusize]}}
+\gdef\Declare@AJKundokuStyle[#1]{\let\aj@kundokusize#1%
+ \ifx\aj@k@nd@ku@\@undefined
+ \else\let\@k@nd@ku@\aj@k@nd@ku@
+ \def\kundokusize{\aj@kundokusize\if@kana\rubyfamily\fi}%
+ \fi
+ \ifx\aj@kokana\@undefined
+ \else
+ \let\kokana\aj@kokana
+ \let\retenform\aj@retenform
+ \let\reten\aj@reten
+ \let\retenkana\aj@retenkana
+ \let\kaeriten\aj@kaeriten
+ \fi}
+%
+%
+\gdef\ajCIDVarDef{\aj@VarDef\CID}
+\gdef\ajUTFVarDef{\aj@VarDef\UTF}
+\gdef\aj@VarDef#1#2#3{\expandafter\xdef\csname ajVar#2\endcsname{\noexpand#1{#3}}}
+\gdef\ajCIDVarList#1{{\@ajCIDVarList#1\relax}}
+\gdef\@ajCIDVarList#1{\ifx\relax#1\else\def\reserved@a{#1}\expandafter\aj@CIDVarList\fi}
+\gdef\aj@CIDVarList{\afterassignment\@aj@CIDVarList\@tempcnta}
+\gdef\@aj@CIDVarList{\aj@VarDef\CID\reserved@a{\number\@tempcnta}\@ajCIDVarList}
+\gdef\ajUTFVarList#1{{\@ajUTFVarList#1 \relax}}
+\gdef\@ajUTFVarList#1{\ifx\relax#1\else\def\reserved@a{#1}\expandafter\aj@UTFVarList\fi}
+\gdef\aj@UTFVarList#1#2{\ifx=#1\expandafter\@aj@UTFVarList\else\expandafter\@aj@UTFVarList\expandafter#1\fi#2}
+\gdef\@aj@UTFVarList#1 {\aj@VarDef\UTF\reserved@a{#1}\@ajUTFVarList}
+\gdef\ajVar#1{\csname ajVar#1\endcsname}
+\ifltj@in@latex
+ \@onlypreamble\ajCIDVarDef
+ \@onlypreamble\ajUTFVarDef
+ \@onlypreamble\ajCIDVarList
+ \@onlypreamble\ajUTFVarList
+\fi
+%\ajCIDVarList{å‰=13706 æ•™=8471 高=8705 é´Ž=7646 å´Ž=14290 碕=17009 第=13910 角=13682 浜=8531}
+\gdef\ajHashigoTaka{\CID{8705}}
+\gdef\ajTsuchiYoshi{\CID{13706}}
+\gdef\ajTatsuSaki{\CID{14290}}
+\gdef\ajMayuHama{\CID{8531}}
+%
+%
+%\gdef\ajRedefine@ajVar{\@ifpackageloaded{hyperref}{%
+% \let\aj@Var\ajVar
+% \def\ajVar##1{\ifHy@pdfstring
+% \expandafter\expandafter
+% \expandafter\check@UTF\csname ajVar##1\endcsname{##1}%
+% \else\aj@Var{##1}\fi}
+% \def\check@UTF##1##2##3{\ifx\UTF##1\0x##2\else##3\fi}}{}}
+\gdef\ajRedefine@ajCommands{\@ifpackageloaded{hyperref}{%
+ \let\hyperref@ajLabel\ajLabel
+ \def\ajLabel##1##{\ifHy@pdfstring\Hy@ReturnAfterElseFi\hyperref@ajLabel\@arabic\else\ltx@ReturnAfterFi\hyperref@ajLabel##1\fi}%
+ \ajRedefine@ajCommand\â–³{Ligâ–³}\â–½{Ligâ–½}\ï¼{Ligå°}\ajLig{Lig}\ajPICT{PICT}\※{PICT}\ajVar{Var}\@nil\@nil
+ \aj@Redefine@ajCommandâ—‹{Maru}â—{KuroMaru}â–¡{Kaku}â– {KuroKaku}â—‡{MaruKaku}â—†{KuroMaruKaku}\@nil\@nil
+ \def\(##1){\ifHy@pdfstring(##1)\else\expandafter\ifx\csname ajLig(##1)\endcsname\relax\@ajnumber{##1}{Kakko}%
+ \else\csname ajLig(##1)\endcsname\fi\fi}%
+ \def\ã‚›##1{\ifHy@pdfstring##1ã‚›\else\csname ajLig##1ã‚›\endcsname\fi}%
+ \def\゜##1{\ifHy@pdfstring##1゜\else\csname ajLig##1゜\endcsname\fi}%
+ }{}}
+\gdef\ajRedefine@ajCommand#1#2{\ifx\@nil#1\else\def#1##1{\ifHy@pdfstring##1\else\csname aj#2##1\endcsname\fi}%
+ \expandafter\ajRedefine@ajCommand\fi}
+\gdef\aj@Redefine@ajCommand#1#2{\ifx\@nil#1\else\expandafter\def\csname#1\endcsname##1%
+ {\ifHy@pdfstring##1\else\expandafter\ifx\csname ajLig#1##1\endcsname\relax\@ajnumber{##1}{#2}\else
+ \csname ajLig#1##1\endcsname\fi\fi}%
+ \expandafter\aj@Redefine@ajCommand\fi}
+\ifltj@in@latex
+ \AtBeginDocument{\ajRedefine@ajCommands}
+\fi
+%
+%
+\gdef\ajLeader{\@ifnextchar[{\aj@Leader}{\aj@Leader[\z@ plus1fill]}}
+\gdef\aj@Leader[#1]#2{{\@tempcnta#2\multiply\@tempcnta\tw@
+ \advance\@tempcnta1221\ifhmode\unless\ifnum\ltjgetparameter{direction}=3 4\else5\fi\else\unless\ifnum\ltjgetparameter{direction}=3 5\else4\fi\fi
+ \leaders\hbox{\CID{\@tempcnta}}\ifhmode\hskip\else\vskip\fi#1}}
+%
+%
+\endlinechar=13
+\toks0{}\toks1{}\toks2{}\toks3{}
+\def\ajQuotedef#1 #2 #3 #4 {\ifx*#1\else
+ \toks0\expandafter{\the\toks0 \or#1}%
+ \toks1\expandafter{\the\toks1 \or#2}%
+ \toks2\expandafter{\the\toks2 \or#3}%
+ \toks3\expandafter{\the\toks3 \or#4}%
+ \expandafter\ajQuotedef\fi}
+\ajQuotedef
+670 671 12173 12174
+672 673 7956 7957
+674 675 7899 7900
+676 677 7901 7902
+678 679 7903 7904
+680 681 7905 7906
+682 683 7907 7908
+684 685 7909 7910
+686 687 7911 7912
+688 689 7913 7914
+690 691 7915 7916
+7608 7609 7956 7957
+12125 12126 12135 12136
+12127 12128 12137 12138
+12129 12130 12139 12140
+12131 12132 12141 12142
+12171 12172 12173 12174
+16197 16198 16329 16330
+* * * *
+\def\@removetop#1{\toks#1\expandafter\expandafter\expandafter{\expandafter\@gobble\the\toks#1}}
+\@removetop0\@removetop1\@removetop2\@removetop3
+\xdef\ajQuote#1#2{\noexpand\CID{\noexpand\unless\noexpand\ifnum\noexpand\ltjgetparameter\noexpand{direction\noexpand}=3 \noexpand\ifcase#1 \the\toks0
+ \noexpand\fi\noexpand\else\noexpand\ifcase#1 \the\toks2
+ \noexpand\fi\noexpand\fi}#2\inhibitglue\noexpand\CID{\noexpand\unless\noexpand\ifnum\noexpand\ltjgetparameter\noexpand{direction\noexpand}=3 \noexpand\ifcase#1 \the\toks1
+ \noexpand\fi\noexpand\else\noexpand\ifcase#1 \the\toks3
+ \noexpand\fi\noexpand\fi}}
+}
+\ifltj@in@latex\else
+ \ajRedefine@KundokuMacros
+\fi
+%%------------------ all done
+\ltj@ajmacros@AtEnd
+\endinput
+%% EOF
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-25c.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-25c.sty
new file mode 100644
index 0000000000..9c67b70358
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-25c.sty
@@ -0,0 +1,357 @@
+%
+% luatexja-fontspec-25c.sty
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{luatexja-fontspec-25c}[2019/05/14 fontspec support of LuaTeX-ja]
+\RequirePackage{l3keys2e}
+\ExplSyntaxOn
+
+%%%%%%%% Change Japanese font family by \rmfamily or not
+\cs_new:Npn \ltj_fontspec_match_cmd {
+ \renewcommand\jttdefault{\gtdefault}
+ \@ltj@match@familytrue
+ \DeclareDocumentCommand \setmonojfont { O{} m O{} } {
+ \ltj_fontspec_set_family:Nnn \jttdefault {##1,##3}{##2}
+ \normalfont
+ }
+}
+\bool_if:NT \__ltj_fontspec_match_bool \ltj_fontspec_match_cmd
+
+%%%%%%%% Messages
+\msg_new:nnn {luatexja-fontspec} {addjfontfeatures-ignored}
+{
+ \string\addjfontfeature (s)~ ignored;\\
+ it~ cannot~ be~ used~ with~ a~ font~ that~ wasn't~ selected~ by~ luatexja-fontspec.
+}
+
+\msg_new:nnn {luatexja-fontspec} {altfont-ignored-by-norange}
+{
+ ignored~ sublist~ `#1'~ in~ AltFont~ (no~ range~ is~ specified).
+}
+
+\msg_new:nnn {luatexja-fontspec} {altfont-ignored-by-rangeonly}
+{
+ ignored~ sublist~ `#1'~ in~ AltFont~ (only~ range~ is~ specified).
+}
+
+\cs_generate_variant:Nn \prg_new_conditional:Nnn {Nnx}
+
+%%%%%%%% Internal control sequences
+%% Each CS is ltj_fontspec version that corresponds to original CS of fontspec.
+\cs_new:Nn \ltj_fontspec_define_option:nn {
+ \__fontspec_keys_define_code:nnn {fontspec} {#1} {#2}
+}
+\cs_new:Nn \ltj_fontspec_define_preparse_external:nn {
+ \__fontspec_keys_define_code:nnn {fontspec-preparse-external} {#1} {#2}
+}
+\cs_new:Nn \ltj_fontspec_define_altfont_option:nn {
+ \__fontspec_keys_define_code:nnn {fontspec-ltjaltfont} {#1} {#2}
+}
+
+%% Alternate Fonts
+%% Spec: AltFont = {
+%% ...
+%% { Range = <range>, <font features> },
+%% { Range = <range>, Font = <font name>, <font features> },
+%% { Range = <range>, Font = <font name> },
+%% ...
+%% }
+\tl_new:N \l_ltj_fontspec_altname_tl
+\tl_new:N \l_ltj_fontspec_altrange_tl
+\clist_new:N \l_ltj_fontspec_altfont_clist
+\clist_new:N \l_ltj_fontspec_altfont_leftover_clist
+\int_new:N \g_ltj_fontspec_altnumber_int
+
+\ltj_fontspec_define_altfont_option:nn {Range} {
+ \tl_set:Nn \l_ltj_fontspec_altrange_tl {#1}
+}
+\ltj_fontspec_define_altfont_option:nn {Font} {
+ \fontspec_complete_fontname:Nn \l_ltj_fontspec_altname_tl {#1}
+}
+\__fontspec_keys_define_code:nnn {fontspec-ltjaltfont-reparse} {AltFont} {
+ \clist_put_right:Nn \l_ltj_fontspec_altfont_clist { #1 }
+}
+\__fontspec_keys_define_code:nnn {fontspec-ltjaltfont-reparse} {YokoFeatures} {
+ \clist_put_right:Nn \l_ltj_fontspec_fontfeat_yoko_clist { #1 }
+}
+\__fontspec_keys_define_code:nnn {fontspec-ltjaltfont-reparse} {TateFeatures} {
+ \clist_put_right:Nn \l_ltj_fontspec_fontfeat_tate_clist { #1 }
+}
+\__fontspec_keys_define_code:nnn {fontspec-ltjaltfont-reparse} {TateFont} {
+ \tl_if_empty:nF {#1} {
+ \fontspec_complete_fontname:Nn \l_ltj_fontspec_fontname_tate_tl {#1}
+ }
+}
+%%
+\clist_new:N \l_ltj_fontspec_fontfeat_yoko_clist
+\clist_new:N \l_ltj_fontspec_fontfeat_tate_clist
+\tl_new:N \l_ltj_fontspec_fontname_tate_tl
+
+\cs_new:Npn \ltj_fontspec_DeclareFontFamily #1 #2 #3 {
+ \DeclareKanjiFamily {JY3} {#2} {#3}
+ \DeclareKanjiFamily {JT3} {#2} {#3}
+}
+
+\cs_set_eq:NN \__ltj_orig_fontspec_select_font_family:nn \__fontspec_select_font_family:nn
+\cs_new_protected:Nn \ltj_fontspec_select_font_family:nn {
+ \group_begin:
+ \ltj_fontspec_define_option:nn {NoEmbed} {}
+ \ltj_fontspec_define_option:nn {AltFont} {
+ \clist_put_right:Nn \l_ltj_fontspec_altfont_clist { ##1 }
+ }
+ \ltj_fontspec_define_option:nn {CID} {
+ \__fontspec_update_featstr:n {cid=##1}
+ }
+ \ltj_fontspec_define_option:nn {Kanjiskip} {
+ \str_if_eq_x:nnTF {false} { \str_lower_case:n { ##1 } }{
+ \__fontspec_update_featstr:n {-ltjksp}
+ } {
+ \__fontspec_update_featstr:n {+ltjksp}
+ }
+ }
+ \ltj_fontspec_define_option:nn {JFM} {
+ \__fontspec_update_featstr:n {jfm=##1}
+ }
+ % vary by shape
+ \ltj_fontspec_define_option:nn {YokoFeatures} {
+ \clist_put_right:Nn \l_ltj_fontspec_fontfeat_yoko_clist { ##1 }
+ }
+ \ltj_fontspec_define_option:nn {TateFeatures} {
+ \clist_put_right:Nn \l_ltj_fontspec_fontfeat_tate_clist { ##1 }
+ }
+ \ltj_fontspec_define_option:nn {TateFont}
+ {
+ \tl_if_empty:nF {##1} {
+ \fontspec_complete_fontname:Nn \l_ltj_fontspec_fontname_tate_tl {##1}
+ }
+ }
+ \ltj_fontspec_define_option:nn {JFM-var} {
+ \__fontspec_update_featstr:n {jfmvar=##1}
+ }
+ \ltj_fontspec_define_preparse_external:nn {NoEmbed} {
+ \cs_set:Npn \__fontspec_fontname_wrap:n ##1 {psft:##1}
+ }
+
+ %% Omit the warning message
+ %% "OpenType feature 'Kerning=Off' (-kern) not available ..."
+ \keys_define:nn {fontspec-opentype} {
+ Kerning/Off.code:n=\__fontspec_update_featstr:n {-kern}
+ }
+ \clist_set:Nx \g__fontspec_default_fontopts_clist {
+ YokoFeatures = { JFM=\ltj@stdyokojfm }, TateFeatures = { JFM=\ltj@stdtatejfm },
+ Scale=\Cjascale, Kerning=Off, Script=CJK,
+ \g__ltj_fontspec_default_fontopts_clist
+ }
+ \prop_set_eq:NN \g__fontspec_fontopts_prop \g__ltj_fontspec_fontopts_prop
+ \cs_set_eq:NN \__fontspec_make_font_shapes:Nnnnn \ltj_fontspec_make_font_shapes:Nnnnn
+ \cs_set_eq:NN \DeclareFontFamily \ltj_fontspec_DeclareFontFamily
+ \tl_set:Nn \g_fontspec_encoding_tl {JY3}
+ \__ltj_orig_fontspec_select_font_family:nn{#1}{#2}
+ \group_end:
+}
+
+%% declare_shape
+
+\cs_new:Nn \ltj_fontspec_declare_shape_yoko:nnnn {
+ \ltj_fontspec_declare_shape_aux:nnnnnn {#1} {#2} {#3} {#4} { JY3 } { \l_ltj_fontspec_fontfeat_yoko_clist }
+}
+\cs_new:Nn \ltj_fontspec_declare_shape_tate:nnnn {
+ \ltj_fontspec_declare_shape_aux:nnnnnn {#1} {#2} {#3} {#4} { JT3 } { \l_ltj_fontspec_fontfeat_tate_clist }
+}
+\cs_new:Nn \ltj_fontspec_declare_shape:nnnn {
+ \ltj_fontspec_declare_shape_yoko:nnnn {#1} {#2} {#3} {#4}
+ \ltj_fontspec_declare_shape_tate:nnnn {#1} {#2} {#3} {#4}
+}
+\cs_generate_variant:Nn \ltj_fontspec_declare_shape:nnnn {nnxx}
+\cs_generate_variant:Nn \ltj_fontspec_declare_shape_yoko:nnnn {nnxx}
+\cs_generate_variant:Nn \ltj_fontspec_declare_shape_tate:nnnn {nnxx}
+
+\cs_new:Nn \ltj_fontspec_declare_shape_aux:nnnnnn
+ {
+ \tl_clear:N \l__fontspec_nfss_tl
+ \tl_clear:N \l__fontspec_nfss_sc_tl
+ \tl_set_eq:NN \l__fontspec_saved_fontname_tl \l_fontspec_fontname_tl
+
+ \tl_set:Nn \g_fontspec_encoding_tl {#5}
+ \tl_set:Nn \l__fontspec_nfss_enc_tl {#5}
+ \exp_args:Nx \clist_map_inline:nn {#4}
+ {
+ \tl_clear:N \l__fontspec_size_tl
+ \tl_set_eq:NN \l__fontspec_sizedfont_tl \l__fontspec_saved_fontname_tl % in case not spec'ed
+
+ \keys_set_known:nxN {fontspec-sizing} { \exp_after:wN \use:n ##1 }
+ \l__fontspec_sizing_leftover_clist
+ \tl_if_empty:NT \l__fontspec_size_tl { \__fontspec_error:n {no-size-info} }
+
+ \str_if_eq:nnTF { #5 } { JY3 } {
+ % "normal"
+ \__fontspec_load_fontname:n {\l__fontspec_sizedfont_tl}
+ } {
+ \tl_if_empty:NTF \l_ltj_fontspec_fontname_tate_tl
+ { \__fontspec_load_fontname:n {\l__fontspec_sizedfont_tl} }
+ { \__fontspec_load_fontname:n {\l_ltj_fontspec_fontname_tate_tl} }
+ }
+ \__fontspec_setup_nfss:Nnnn \l__fontspec_nfss_tl {#3} {#6} {}
+ }
+ \bool_set_true:N \l__fontspec_nosc_bool
+ \__fontspec_declare_shapes_normal:nn {#1} {#2}
+ \__fontspec_declare_shape_slanted:nn {#1} {#2}
+ }
+
+\cs_new:Nn \ltj_fontspec_set_family:Nnn {
+ \cs_set_eq:NN \__fontspec_select_font_family:nn \ltj_fontspec_select_font_family:nn
+ \__ltj_orig_fontspec_set_family:Nnn #1 {#2} {#3}
+ \cs_set_eq:NN \__fontspec_select_font_family:nn \__ltj_orig_fontspec_select_font_family:nn
+}
+\cs_set_eq:NN \__ltj_orig_fontspec_set_family:Nnn \fontspec_set_family:Nnn
+\cs_set_eq:NN \__ltj_orig_fontspec_make_font_shapes:Nnnnn \__fontspec_make_font_shapes:Nnnnn
+\cs_set_eq:NN \__ltj_fontspec_orig_DeclareFontShape \DeclareFontShape
+
+\cs_new:Nn \ltj_fontspec_make_font_shapes:Nnnnn {
+ \group_begin:
+ %% 基底フォント
+ \cs_set_eq:NN \__fontspec_font_set:Nnn \use_none:nnn
+ \cs_set_eq:NN \__fontspec_font_if_null:NT \use_none:nn
+ \cs_set_eq:NN \__fontspec_declare_shape:nnxx \ltj_fontspec_declare_shape:nnxx
+ \__ltj_orig_fontspec_make_font_shapes:Nnnnn {#1} {#2} {#3} {#4} {#5}
+ %%
+ \ltj_fontspec_make_font_shapes_alt:Nnnnnn {#1}{#2}{#3}
+ {#4, \l_ltj_fontspec_fontfeat_yoko_clist}{#5} {JY3 }
+ \ltj_fontspec_make_font_shapes_alt:Nnnnnn {#1}{#2}{#3}
+ {#4, \l_ltj_fontspec_fontfeat_tate_clist}{#5} {JT3}
+ \group_end:
+ }
+
+%%% Altfont 内部処ç†éƒ¨
+\cs_new:Nn \ltj_fontspec_make_font_shapes_alt:Nnnnnn {
+ \group_begin:
+ \str_if_eq:nnTF { #6 } { JY3 } {
+ \cs_set_eq:NN \__fontspec_declare_shape:nnxx \ltj_fontspec_declare_shape_yoko:nnxx
+ }{
+ \cs_set_eq:NN \__fontspec_declare_shape:nnxx \ltj_fontspec_declare_shape_tate:nnxx
+ }
+ \keys_set_known:nn {fontspec-ltjaltfont-reparse} { #4 }
+ \clist_if_empty:NF \l_ltj_fontspec_altfont_clist {
+ \int_gzero:N \g_ltj_fontspec_altnumber_int
+ \clist_map_inline:Nn \l_ltj_fontspec_altfont_clist {
+ \tl_clear:N \l_ltj_fontspec_altrange_tl
+ \tl_set:Nn \l_ltj_fontspec_altname_tl { #1 }
+ \tl_set:Nn \l_tmpa_tl { #1 }
+
+ \keys_set_known:nxN {fontspec-ltjaltfont} { \exp_after:wN \use:n ##1 }
+ \l_ltj_fontspec_altfont_leftover_clist
+ \keys_set_known:nn {fontspec-ltjaltfont-reparse} { \exp_after:wN \use:n ##1 }
+
+ \tl_if_empty:NT \l_ltj_fontspec_altrange_tl {
+ \msg_warning:nnn {luatexja-fontspec} {altfont-ignored-by-norange} { ##1 }
+ } {
+ \bool_if:nTF {
+ \tl_if_eq_p:NN \l_ltj_fontspec_altname_tl \l_tmpa_tl
+ &&
+ \tl_if_empty_p:N \l_ltj_fontspec_altfont_leftover_clist
+ } {
+ \msg_warning:nnn {luatexja-fontspec} {altfont-ignored-by-rangeonly} { ##1 }
+ } {
+ \__ltj_orig_fontspec_make_font_shapes:Nnnnn
+ { \l_ltj_fontspec_altname_tl } {#2}
+ {#3 _ alt \int_use:N \g_ltj_fontspec_altnumber_int }
+ {#4, \l_ltj_fontspec_altfont_leftover_clist }
+ {#5}
+ \DeclareAlternateKanjiFont
+ { #6 }{ \l_fontspec_family_tl }{#2}{#3}%
+ { #6 }{ \l_fontspec_family_tl }{#2}
+ { #3 _alt \int_use:N \g_ltj_fontspec_altnumber_int }
+ { \l_ltj_fontspec_altrange_tl }
+ \int_gincr:N \g_ltj_fontspec_altnumber_int
+ }
+ }
+ }
+ }
+ \group_end:
+}
+
+
+%%%%%%%% User commands
+\DeclareDocumentCommand \jfontspec { O{} m O{} } {
+ \ltj_fontspec_set_family:Nnn \k@family {#1,#3}{#2}
+ \selectfont
+ \ignorespaces
+}
+
+\DeclareDocumentCommand \setmainjfont { O{} m O{} } {
+ \ltj_fontspec_set_family:Nnn \mcdefault {#1,#3}{#2}
+ \unless\ifltj@disablejfam
+ \DeclareSymbolFont{mincho}{JY3}{\l_fontspec_family_tl}{\mddefault}{n}
+ \SetSymbolFont{mincho}{bold}{JY3}{\l_fontspec_family_tl}{\bfdefault}{n}
+ \fi
+ \normalfont
+}
+
+\DeclareDocumentCommand \setsansjfont { O{} m O{} } {
+ \ltj_fontspec_set_family:Nnn \gtdefault {#1,#3}{#2}
+ \unless\ifltj@disablejfam
+ \DeclareMathAlphabet{\mathgt}{JY3}{\l_fontspec_family_tl}{\mddefault}{n}
+ \fi
+ \normalfont
+}
+
+\DeclareDocumentCommand \newjfontfamily { m O{} m O{} } {
+ \cs_set_eq:NN \fontspec_set_family:Nnn \ltj_fontspec_set_family:Nnn
+ \newfontfamily #1 [#2,#4] {#3}
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
+}
+
+\DeclareDocumentCommand \newjfontface { m O{} m O{} } {
+ \newjfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
+}
+
+\clist_new:N \g__ltj_fontspec_default_fontopts_clist
+\prop_new:N \g__ltj_fontspec_fontopts_prop
+\DeclareDocumentCommand \defaultjfontfeatures { t+ o m }
+ {
+ \IfNoValueTF {#2}
+ { \__ltj_fontspec_set_default_features:nn {#1} {#3} }
+ { \__ltj_fontspec_set_font_default_features:nnn {#1} {#2} {#3} }
+ \ignorespaces
+ }
+\cs_new:Nn \__ltj_fontspec_set_default_features:nn
+ {
+ \clist_set_eq:NN \l__ltj_fontspec_tmp_clist \g__fontspec_default_fontopts_clist
+ \clist_set_eq:NN \g__fontspec_default_fontopts_clist \g__ltj_fontspec_default_fontopts_clist
+ \__fontspec_set_default_features:nn {#1} {#2}
+ \clist_set_eq:NN \g__ltj_fontspec_default_fontopts_clist \g__fontspec_default_fontopts_clist
+ \clist_set_eq:NN \g__fontspec_default_fontopts_clist \l__ltj_fontspec_tmp_clist
+ }
+\cs_new:Nn \__ltj_fontspec_set_font_default_features:nnn
+ {
+ \prop_set_eq:NN \l__ltj_fontspec_tmp_prop \g__fontspec_fontopts_prop
+ \prop_set_eq:NN \g__fontspec_fontopts_prop \g__ltj_fontspec_fontopts_prop
+ \__fontspec_set_font_default_features:nnn {#1} {#2} {#3}
+ \prop_set_eq:NN \g__ltj_fontspec_fontopts_prop \g__fontspec_fontopts_prop
+ \prop_set_eq:NN \g__fontspec_fontopts_prop \l__ltj_fontspec_tmp_prop
+ }
+
+\DeclareDocumentCommand \addjfontfeatures {m} {
+ \ltj_fontspec_if_fontspec_font:TF
+ {
+ \group_begin:
+ \tl_set_eq:NN \f@family \k@family
+ \cs_set_eq:NN \__fontspec_select_font_family:nn \ltj_fontspec_select_font_family:nn
+ \addfontfeatures {#1}
+ \group_end:
+ \fontfamily\l_fontspec_family_tl\selectfont
+ }{
+ \msg_warning:nn {luatexja-fontspec} {addjfontfeatures-ignored}
+ }
+ \ignorespaces
+}
+
+\cs_set_eq:NN \addjfontfeature \addjfontfeatures
+
+\prg_new_conditional:Nnn \ltj_fontspec_if_fontspec_font: {TF,T,F}
+{
+ \cs_if_exist:cTF {g__fontspec_ \k@family _prop} \prg_return_true: \prg_return_false:
+}
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-26h.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-26h.sty
new file mode 100644
index 0000000000..1472633bb0
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-26h.sty
@@ -0,0 +1,412 @@
+%
+% luatexja-fontspec-26h.sty
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{luatexja-fontspec-26h}[2019/05/14 fontspec support of LuaTeX-ja]
+\RequirePackage{l3keys2e}
+\ExplSyntaxOn
+
+%%%%%%%% Change Japanese font family by \rmfamily or not
+\cs_new:Npn \__ltj_fontspec_match_cmd {
+ \renewcommand\jttdefault{\gtdefault}
+ \@ltj@match@familytrue
+ \DeclareDocumentCommand \setmonojfont { O{} m O{} } {
+ \__ltj_fontspec_set_family:Nnn \jttdefault {##1,##3}{##2}
+ \normalfont
+ }
+}
+\bool_if:NT \__ltj_fontspec_match_bool \__ltj_fontspec_match_cmd
+
+%%%%%%%% Messages
+\msg_new:nnn {luatexja-fontspec} {addjfontfeatures-ignored}
+{
+ \string\addjfontfeature (s)~ ignored;\\
+ it~ cannot~ be~ used~ with~ a~ font~ that~ wasn't~ selected~ by~ luatexja-fontspec.
+}
+
+\msg_new:nnn {luatexja-fontspec} {altfont-ignored-by-norange}
+{
+ ignored~ sublist~ `#1'~ in~ AltFont~ (no~ range~ is~ specified).
+}
+
+\msg_new:nnn {luatexja-fontspec} {altfont-ignored-by-rangeonly}
+{
+ ignored~ sublist~ `#1'~ in~ AltFont~ (only~ range~ is~ specified).
+}
+
+\cs_generate_variant:Nn \prg_new_conditional:Nnn {Nnx}
+
+%%%%%%%% Internal control sequences
+%% Each CS is ltj_fontspec version that corresponds to original CS of fontspec.
+\cs_new:Nn \__ltj_fontspec_define_option:nn {
+ \__fontspec_keys_define_code:nnn {fontspec} {#1} {#2}
+}
+\cs_new:Nn \__ltj_fontspec_define_preparse_external:nn {
+ \__fontspec_keys_define_code:nnn {fontspec-preparse-external} {#1} {#2}
+}
+\cs_new:Nn \__ltj_fontspec_define_altfont_option:nn {
+ \__fontspec_keys_define_code:nnn {fontspec-ltjaltfont} {#1} {#2}
+}
+
+%% Alternate Fonts
+%% Spec: AltFont = {
+%% ...
+%% { Range = <range>, <font features> },
+%% { Range = <range>, Font = <font name>, <font features> },
+%% { Range = <range>, Font = <font name> },
+%% ...
+%% }
+\tl_new:N \l__ltj_fontspec_altname_tl
+\tl_new:N \l__ltj_fontspec_altrange_tl
+\clist_new:N \l__ltj_fontspec_altfont_clist
+\clist_new:N \l__ltj_fontspec_altfont_leftover_clist
+\int_new:N \g__ltj_fontspec_altnumber_int
+
+\__ltj_fontspec_define_altfont_option:nn {Range} {
+ \tl_set:Nn \l__ltj_fontspec_altrange_tl {#1}
+}
+\__ltj_fontspec_define_altfont_option:nn {Font} {
+ \fontspec_complete_fontname:Nn \l__ltj_fontspec_altname_tl {#1}
+}
+\__fontspec_keys_define_code:nnn {fontspec-ltjaltfont-reparse} {AltFont} {
+ \clist_put_right:Nn \l__ltj_fontspec_altfont_clist { #1 }
+}
+\__fontspec_keys_define_code:nnn {fontspec-ltjaltfont-reparse} {YokoFeatures} {
+ \clist_put_right:Nn \l__ltj_fontspec_fontfeat_yoko_clist { #1 }
+}
+\__fontspec_keys_define_code:nnn {fontspec-ltjaltfont-reparse} {TateFeatures} {
+ \clist_put_right:Nn \l__ltj_fontspec_fontfeat_tate_clist { #1 }
+}
+\__fontspec_keys_define_code:nnn {fontspec-ltjaltfont-reparse} {TateFont} {
+ \tl_if_empty:nF {#1} {
+ \fontspec_complete_fontname:Nn \l__ltj_fontspec_fontname_tate_tl {#1}
+ }
+}
+%%
+\clist_new:N \l__ltj_fontspec_fontfeat_yoko_clist
+\clist_new:N \l__ltj_fontspec_fontfeat_tate_clist
+\tl_new:N \l__ltj_fontspec_fontname_tate_tl
+
+\cs_new:Npn \__ltj_fontspec_DeclareFontFamily #1 #2 #3 {
+ \DeclareKanjiFamily {JY3} {#2} {#3}
+ \DeclareKanjiFamily {JT3} {#2} {#3}
+}
+
+%% save and restore global variable
+\tl_new:N \g__ltj_fontspec_kanji_nfss_family_tl
+\tl_new:N \g__ltj_fontspec_orig_nfss_family_tl
+\seq_new:N \g__ltj_fontspec_kanji_bf_series_seq
+\seq_new:N \g__ltj_fontspec_orig_bf_series_seq
+\clist_new:N \g__ltj_fontspec_kanji_default_fontopts_clist
+\clist_new:N \g__ltj_fontspec_orig_default_fontopts_clist
+
+\cs_new:Nn \__ltj_set_global_variable_for_kanji: {
+ \tl_gset_eq:NN \g__ltj_fontspec_orig_nfss_family_tl \g__fontspec_nfss_family_tl
+ \tl_gset_eq:NN \g__fontspec_nfss_family_tl \g__ltj_fontspec_kanji_nfss_family_tl
+ \seq_gset_eq:NN \g__ltj_fontspec_orig_bf_series_seq \g__fontspec_bf_series_seq
+ \seq_gset_eq:NN \g__fontspec_bf_series_seq \g__ltj_fontspec_kanji_bf_series_seq
+ %\seq_gclear:N \g__fontspec_bf_series_seq
+ \clist_set_eq:NN \g__ltj_fontspec_orig_default_fontopts_clist \g__fontspec_default_fontopts_clist
+ \clist_set_eq:NN \g__fontspec_default_fontopts_clist \g__ltj_fontspec_kanji_default_fontopts_clist
+}
+
+\cs_new:Nn \__ltj_restore_global_variable: {
+ \tl_gset_eq:NN \g__ltj_fontspec_kanji_nfss_family_tl \g__fontspec_nfss_family_tl
+ \tl_gset_eq:NN \g__fontspec_nfss_family_tl \g__ltj_fontspec_orig_nfss_family_tl
+ \seq_gset_eq:NN \g__ltj_fontspec_kanji_bf_series_seq \g__fontspec_bf_series_seq
+ \seq_gset_eq:NN \g__fontspec_bf_series_seq \g__ltj_fontspec_orig_bf_series_seq
+ \clist_set_eq:NN \g__ltj_fontspec_kanji_default_fontopts_clist \g__fontspec_default_fontopts_clist
+ \clist_set_eq:NN \g__fontspec_default_fontopts_clist \g__ltj_fontspec_orig_default_fontopts_clist
+}
+
+\cs_set_eq:NN \__ltj_orig_fontspec_select_font_family:nn \__fontspec_select_font_family:nn
+\cs_new_protected:Nn \__ltj_fontspec_select_font_family:nn {
+ \group_begin:
+ \__ltj_fontspec_define_option:nn {NoEmbed} {}
+ \__ltj_fontspec_define_option:nn {AltFont} {
+ \clist_put_right:Nn \l__ltj_fontspec_altfont_clist { ##1 }
+ }
+ \__ltj_fontspec_define_option:nn {CID} {
+ \__fontspec_update_featstr:n {cid=##1}
+ }
+ \__ltj_fontspec_define_option:nn {Kanjiskip} {
+ \str_if_eq_x:nnTF {false} { \str_lower_case:n { ##1 } }{
+ \__fontspec_update_featstr:n {-ltjksp}
+ } {
+ \__fontspec_update_featstr:n {+ltjksp}
+ }
+ }
+ \__ltj_fontspec_define_option:nn {JFM} {
+ \__fontspec_update_featstr:n {jfm=##1}
+ }
+ % vary by shape
+ \__ltj_fontspec_define_option:nn {YokoFeatures} {
+ \clist_put_right:Nn \l__ltj_fontspec_fontfeat_yoko_clist { ##1 }
+ }
+ \__ltj_fontspec_define_option:nn {TateFeatures} {
+ \clist_put_right:Nn \l__ltj_fontspec_fontfeat_tate_clist { ##1 }
+ }
+ \__ltj_fontspec_define_option:nn {TateFont}
+ {
+ \tl_if_empty:nF {##1} {
+ \fontspec_complete_fontname:Nn \l__ltj_fontspec_fontname_tate_tl {##1}
+ }
+ }
+ \__ltj_fontspec_define_option:nn {JFM-var} {
+ \__fontspec_update_featstr:n {jfmvar=##1}
+ }
+ \__ltj_fontspec_define_preparse_external:nn {NoEmbed} {
+ \cs_set:Npn \__fontspec_fontname_wrap:n ##1 {psft:##1}
+ }
+
+ %% Omit the warning message
+ %% "OpenType feature 'Kerning=Off' (-kern) not available ..."
+ \keys_define:nn {fontspec-opentype} {
+ Kerning/Off.code:n=\__fontspec_update_featstr:n {-kern}
+ }
+ \clist_set:Nx \g__fontspec_default_fontopts_clist {
+ YokoFeatures = { JFM=\ltj@stdyokojfm }, TateFeatures = { JFM=\ltj@stdtatejfm },
+ Scale=\Cjascale, Kerning=Off, Script=CJK,
+ \g__ltj_fontspec_kanji_default_fontopts_clist
+ }
+ \prop_set_eq:NN \g__fontspec_fontopts_prop \g__ltj_fontspec_fontopts_prop
+ \cs_set_eq:NN \__fontspec_make_font_shapes:Nnnnn \__ltj_fontspec_make_font_shapes:Nnnnn
+ \cs_set_eq:NN \DeclareFontFamily \__ltj_fontspec_DeclareFontFamily
+ \tl_set:Nn \g_fontspec_encoding_tl {JY3}
+ \__ltj_orig_fontspec_select_font_family:nn{#1}{#2}
+
+ \cs_gset:Npx \__ltj_fontspec_aftergroup {
+ \exp_not:N \tl_set:Nn \exp_not:N \l_fontspec_family_tl { \l_fontspec_family_tl }
+ }
+ \aftergroup \__ltj_fontspec_aftergroup
+ \group_end:
+}
+
+%% declare_shape
+
+\cs_new:Nn \__ltj_fontspec_declare_shape_yoko:nnnn {
+ \__ltj_fontspec_declare_shape_aux:nnnnnn {#1} {#2} {#3} {#4} { JY3 } { \l__ltj_fontspec_fontfeat_yoko_clist }
+}
+\cs_new:Nn \__ltj_fontspec_declare_shape_tate:nnnn {
+ \__ltj_fontspec_declare_shape_aux:nnnnnn {#1} {#2} {#3} {#4} { JT3 } { \l__ltj_fontspec_fontfeat_tate_clist }
+}
+\cs_new:Nn \__ltj_fontspec_declare_shape:nnnn {
+ \__ltj_fontspec_declare_shape_yoko:nnnn {#1} {#2} {#3} {#4}
+ \__ltj_fontspec_declare_shape_tate:nnnn {#1} {#2} {#3} {#4}
+}
+\cs_generate_variant:Nn \__ltj_fontspec_declare_shape:nnnn {nnxx}
+\cs_generate_variant:Nn \__ltj_fontspec_declare_shape_yoko:nnnn {nnxx}
+\cs_generate_variant:Nn \__ltj_fontspec_declare_shape_tate:nnnn {nnxx}
+
+\cs_new:Nn \__ltj_fontspec_declare_shape_aux:nnnnnn
+ {
+ \tl_clear:N \l__fontspec_nfss_tl
+ \tl_clear:N \l__fontspec_nfss_sc_tl
+ \tl_set_eq:NN \l__fontspec_saved_fontname_tl \l_fontspec_fontname_tl
+
+ \tl_set:Nn \g_fontspec_encoding_tl {#5}
+ \tl_set:Nn \g__fontspec_nfss_enc_tl {#5}
+ \exp_args:Nx \clist_map_inline:nn {#4}
+ {
+ \tl_clear:N \l__fontspec_size_tl
+ \tl_set_eq:NN \l__fontspec_sizedfont_tl \l__fontspec_saved_fontname_tl % in case not spec'ed
+
+ \keys_set_known:nxN {fontspec-sizing} { \exp_after:wN \use:n ##1 }
+ \l__fontspec_sizing_leftover_clist
+ \tl_if_empty:NT \l__fontspec_size_tl { \__fontspec_error:n {no-size-info} }
+
+ \cs_if_exist:NTF \__fontspec_load_fontname:Nn
+ { %% >= v2.7
+ \str_if_eq:nnTF { #5 } { JY3 } {
+ % "normal"
+ \__fontspec_load_fontname:Nn \l_fontspec_fontname_tl {\l__fontspec_sizedfont_tl}
+ } {
+ \tl_if_empty:NTF \l__ltj_fontspec_fontname_tate_tl
+ { \__fontspec_load_fontname:Nn \l_fontspec_fontname_tl {\l__fontspec_sizedfont_tl} }
+ { \__fontspec_load_fontname:Nn \l_fontspec_fontname_tl {\l__ltj_fontspec_fontname_tate_tl} }
+ }
+ } { %% < v2.7
+ \str_if_eq:nnTF { #5 } { JY3 } {
+ % "normal"
+ \__fontspec_load_fontname:n {\l__fontspec_sizedfont_tl}
+ } {
+ \tl_if_empty:NTF \l__ltj_fontspec_fontname_tate_tl
+ { \__fontspec_load_fontname:n {\l__fontspec_sizedfont_tl} }
+ { \__fontspec_load_fontname:n {\l__ltj_fontspec_fontname_tate_tl} }
+ }
+ }
+ \__fontspec_setup_nfss:Nnnn \l__fontspec_nfss_tl {#3} {#6} {}
+ }
+ \bool_set_true:N \l__fontspec_nosc_bool
+ \__fontspec_declare_shapes_normal:nn {#1} {#2}
+ \__fontspec_declare_shape_slanted:nn {#1} {#2}
+ }
+
+\cs_new:Nn \__ltj_fontspec_set_family:Nnn {
+ \__ltj_set_global_variable_for_kanji:
+ \cs_set_eq:NN \__fontspec_select_font_family:nn \__ltj_fontspec_select_font_family:nn
+ \__ltj_orig_fontspec_set_family:Nnn #1 {#2} {#3}
+ \cs_set_eq:NN \__fontspec_select_font_family:nn \__ltj_orig_fontspec_select_font_family:nn
+ \__ltj_restore_global_variable:
+}
+\cs_set_eq:NN \__ltj_orig_fontspec_set_family:Nnn \fontspec_set_family:Nnn
+\cs_set_eq:NN \__ltj_orig_fontspec_make_font_shapes:Nnnnn \__fontspec_make_font_shapes:Nnnnn
+\cs_set_eq:NN \__ltj_fontspec_orig_DeclareFontShape \DeclareFontShape
+
+\cs_new:Nn \__ltj_fontspec_make_font_shapes:Nnnnn {
+ \group_begin:
+ %% 基底フォント
+ \cs_set_eq:NN \__fontspec_font_set:Nnn \use_none:nnn
+ \cs_set_eq:NN \__fontspec_font_if_null:NT \use_none:nn
+ \cs_set_eq:NN \__fontspec_declare_shape:nnxx \__ltj_fontspec_declare_shape:nnxx
+ \__ltj_orig_fontspec_make_font_shapes:Nnnnn {#1} {#2} {#3} {#4} {#5}
+ %%
+ \__ltj_fontspec_make_font_shapes_alt:Nnnnnn {#1}{#2}{#3}
+ {#4, \l__ltj_fontspec_fontfeat_yoko_clist}{#5} {JY3 }
+ \__ltj_fontspec_make_font_shapes_alt:Nnnnnn {#1}{#2}{#3}
+ {#4, \l__ltj_fontspec_fontfeat_tate_clist}{#5} {JT3}
+ \group_end:
+ }
+
+%%% Altfont 内部処ç†éƒ¨
+\cs_new:Nn \__ltj_fontspec_make_font_shapes_alt:Nnnnnn {
+ \group_begin:
+ \str_if_eq:nnTF { #6 } { JY3 } {
+ \cs_set_eq:NN \__fontspec_declare_shape:nnxx \__ltj_fontspec_declare_shape_yoko:nnxx
+ }{
+ \cs_set_eq:NN \__fontspec_declare_shape:nnxx \__ltj_fontspec_declare_shape_tate:nnxx
+ }
+ \keys_set_known:nn {fontspec-ltjaltfont-reparse} { #4 }
+ \clist_if_empty:NF \l__ltj_fontspec_altfont_clist {
+ \int_gzero:N \g__ltj_fontspec_altnumber_int
+ \clist_map_inline:Nn \l__ltj_fontspec_altfont_clist {
+ \tl_clear:N \l__ltj_fontspec_altrange_tl
+ \tl_set:Nn \l__ltj_fontspec_altname_tl { #1 }
+ \tl_set:Nn \l_tmpa_tl { #1 }
+
+ \keys_set_known:nxN {fontspec-ltjaltfont} { \exp_after:wN \use:n ##1 }
+ \l__ltj_fontspec_altfont_leftover_clist
+ \keys_set_known:nn {fontspec-ltjaltfont-reparse} { \exp_after:wN \use:n ##1 }
+
+ \tl_if_empty:NT \l__ltj_fontspec_altrange_tl {
+ \msg_warning:nnn {luatexja-fontspec} {altfont-ignored-by-norange} { ##1 }
+ } {
+ \bool_if:nTF {
+ \tl_if_eq_p:NN \l__ltj_fontspec_altname_tl \l_tmpa_tl
+ &&
+ \tl_if_empty_p:N \l__ltj_fontspec_altfont_leftover_clist
+ } {
+ \msg_warning:nnn {luatexja-fontspec} {altfont-ignored-by-rangeonly} { ##1 }
+ } {
+ \__ltj_orig_fontspec_make_font_shapes:Nnnnn
+ { \l__ltj_fontspec_altname_tl } {#2}
+ {#3 _ alt \int_use:N \g__ltj_fontspec_altnumber_int }
+ {#4, \l__ltj_fontspec_altfont_leftover_clist }
+ {#5}
+ \DeclareAlternateKanjiFont
+ { #6 }{ \g__fontspec_nfss_family_tl }{#2}{#3}%
+ { #6 }{ \g__fontspec_nfss_family_tl }{#2}
+ { #3 _alt \int_use:N \g__ltj_fontspec_altnumber_int }
+ { \l__ltj_fontspec_altrange_tl }
+ \int_gincr:N \g__ltj_fontspec_altnumber_int
+ }
+ }
+ }
+ }
+ \group_end:
+}
+
+
+%%%%%%%% User commands
+\DeclareDocumentCommand \jfontspec { O{} m O{} } {
+ \__ltj_fontspec_set_family:Nnn \k@family {#1,#3}{#2}
+ \selectfont
+ \ignorespaces
+}
+
+\DeclareDocumentCommand \setmainjfont { O{} m O{} } {
+ \__ltj_fontspec_set_family:Nnn \mcdefault {#1,#3}{#2}
+ \unless\ifltj@disablejfam
+ \DeclareSymbolFont{mincho}{JY3}{\mcdefault}{\mddefault}{n}
+ \SetSymbolFont{mincho}{bold}{JY3}{\mcdefault}{\bfdefault}{n}
+ \fi
+ \normalfont
+}
+
+\DeclareDocumentCommand \setsansjfont { O{} m O{} } {
+ \__ltj_fontspec_set_family:Nnn \gtdefault {#1,#3}{#2}
+ \unless\ifltj@disablejfam
+ \DeclareMathAlphabet{\mathgt}{JY3}{\gtdefault}{\mddefault}{n}
+ \fi
+ \normalfont
+}
+
+\DeclareDocumentCommand \newjfontfamily { m O{} m O{} } {
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_fontspec_set_family:Nnn
+ \newfontfamily #1 [#2,#4] {#3}
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
+}
+\DeclareDocumentCommand \renewjfontfamily { m O{} m O{} } {
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_fontspec_set_family:Nnn
+ \renewfontfamily #1 [#2,#4] {#3}
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
+}
+\DeclareDocumentCommand \setjfontfamily { m O{} m O{} } {
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_fontspec_set_family:Nnn
+ \setfontfamily #1 [#2,#4] {#3}
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
+}
+
+\DeclareDocumentCommand \newjfontface { m O{} m O{} } {
+ \newjfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
+}
+
+\prop_new:N \g__ltj_fontspec_fontopts_prop
+\DeclareDocumentCommand \defaultjfontfeatures { t+ o m }
+ {
+ \IfNoValueTF {#2}
+ { \__ltj_fontspec_set_default_features:nn {#1} {#3} }
+ { \__ltj_fontspec_set_font_default_features:nnn {#1} {#2} {#3} }
+ \ignorespaces
+ }
+\cs_new:Nn \__ltj_fontspec_set_default_features:nn
+ {
+ \__ltj_set_global_variable_for_kanji:
+ \__fontspec_set_default_features:nn {#1} {#2}
+ \__ltj_restore_global_variable:
+ }
+\cs_new:Nn \__ltj_fontspec_set_font_default_features:nnn
+ {
+ \prop_set_eq:NN \l__ltj_fontspec_tmp_prop \g__fontspec_fontopts_prop
+ \prop_set_eq:NN \g__fontspec_fontopts_prop \g__ltj_fontspec_fontopts_prop
+ \__fontspec_set_font_default_features:nnn {#1} {#2} {#3}
+ \prop_set_eq:NN \g__ltj_fontspec_fontopts_prop \g__fontspec_fontopts_prop
+ \prop_set_eq:NN \g__fontspec_fontopts_prop \l__ltj_fontspec_tmp_prop
+ }
+
+\DeclareDocumentCommand \addjfontfeatures {m} {
+ \__ltj_fontspec_if_fontspec_font:TF
+ {
+ \__ltj_set_global_variable_for_kanji:
+ \group_begin:
+ \tl_set_eq:NN \f@family \k@family
+ \cs_set_eq:NN \__fontspec_select_font_family:nn \__ltj_fontspec_select_font_family:nn
+ \addfontfeatures {#1}
+ \group_end:
+ \kanjifamily\g__fontspec_nfss_family_tl\selectfont
+ \__ltj_restore_global_variable:
+ }{
+ \msg_warning:nn {luatexja-fontspec} {addjfontfeatures-ignored}
+ }
+ \ignorespaces
+}
+
+\cs_set_eq:NN \addjfontfeature \addjfontfeatures
+
+\prg_new_conditional:Nnn \__ltj_fontspec_if_fontspec_font: {TF,T,F}
+{
+ \cs_if_exist:cTF {g__fontspec_fontinfo_ \k@family _prop} \prg_return_true: \prg_return_false:
+}
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-27c.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-27c.sty
new file mode 100644
index 0000000000..88d6b37b58
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec-27c.sty
@@ -0,0 +1,406 @@
+%
+% luatexja-fontspec-27c.sty
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{luatexja-fontspec-27c}[2019/05/14 fontspec support of LuaTeX-ja]
+\RequirePackage{l3keys2e}
+\ExplSyntaxOn
+
+%%%%%%%% Change Japanese font family by \rmfamily or not
+\cs_new:Npn \__ltj_fontspec_match_cmd {
+ \renewcommand\jttdefault{\gtdefault}
+ \@ltj@match@familytrue
+ \DeclareDocumentCommand \setmonojfont { O{} m O{} } {
+ \__ltj_fontspec_set_family:Nnn \jttdefault {##1,##3}{##2}
+ \normalfont
+ }
+}
+\bool_if:NT \__ltj_fontspec_match_bool \__ltj_fontspec_match_cmd
+
+%%%%%%%% Messages
+\msg_new:nnn {luatexja-fontspec} {addjfontfeatures-ignored}
+{
+ \string\addjfontfeature (s)~ ignored;\\
+ it~ cannot~ be~ used~ with~ a~ font~ that~ wasn't~ selected~ by~ luatexja-fontspec.
+}
+
+\msg_new:nnn {luatexja-fontspec} {altfont-ignored-by-norange}
+{
+ ignored~ sublist~ `#1'~ in~ AltFont~ (no~ range~ is~ specified).
+}
+
+\msg_new:nnn {luatexja-fontspec} {altfont-ignored-by-rangeonly}
+{
+ ignored~ sublist~ `#1'~ in~ AltFont~ (only~ range~ is~ specified).
+}
+
+\cs_generate_variant:Nn \prg_new_conditional:Nnn {Nnx}
+
+%%%%%%%% Internal control sequences
+%% Each CS is ltj_fontspec version that corresponds to original CS of fontspec.
+\cs_new:Nn \__ltj_fontspec_define_option:nn {
+ \__fontspec_keys_define_code:nnn {fontspec} {#1} {#2}
+}
+\cs_new:Nn \__ltj_fontspec_define_preparse_external:nn {
+ \__fontspec_keys_define_code:nnn {fontspec-preparse-external} {#1} {#2}
+}
+\cs_new:Nn \__ltj_fontspec_define_altfont_option:nn {
+ \__fontspec_keys_define_code:nnn {fontspec-ltjaltfont} {#1} {#2}
+}
+
+%% Alternate Fonts
+%% Spec: AltFont = {
+%% ...
+%% { Range = <range>, <font features> },
+%% { Range = <range>, Font = <font name>, <font features> },
+%% { Range = <range>, Font = <font name> },
+%% ...
+%% }
+\tl_new:N \l__ltj_fontspec_altname_tl
+\tl_new:N \l__ltj_fontspec_altrange_tl
+\clist_new:N \l__ltj_fontspec_altfont_clist
+\clist_new:N \l__ltj_fontspec_altfont_leftover_clist
+\int_new:N \g__ltj_fontspec_altnumber_int
+
+\__ltj_fontspec_define_altfont_option:nn {Range} {
+ \tl_set:Nn \l__ltj_fontspec_altrange_tl {#1}
+}
+\__ltj_fontspec_define_altfont_option:nn {Font} {
+ \fontspec_complete_fontname:Nn \l__ltj_fontspec_altname_tl {#1}
+}
+\__fontspec_keys_define_code:nnn {fontspec-ltjaltfont-reparse} {AltFont} {
+ \clist_put_right:Nn \l__ltj_fontspec_altfont_clist { #1 }
+}
+\__fontspec_keys_define_code:nnn {fontspec-ltjaltfont-reparse} {YokoFeatures} {
+ \clist_put_right:Nn \l__ltj_fontspec_fontfeat_yoko_clist { #1 }
+}
+\__fontspec_keys_define_code:nnn {fontspec-ltjaltfont-reparse} {TateFeatures} {
+ \clist_put_right:Nn \l__ltj_fontspec_fontfeat_tate_clist { #1 }
+}
+\__fontspec_keys_define_code:nnn {fontspec-ltjaltfont-reparse} {TateFont} {
+ \tl_if_empty:nF {#1} {
+ \fontspec_complete_fontname:Nn \l__ltj_fontspec_fontname_tate_tl {#1}
+ }
+}
+%%
+\clist_new:N \l__ltj_fontspec_fontfeat_yoko_clist
+\clist_new:N \l__ltj_fontspec_fontfeat_tate_clist
+\tl_new:N \l__ltj_fontspec_fontname_tate_tl
+
+\cs_new:Npn \__ltj_fontspec_DeclareFontFamily #1 #2 #3 {
+ \DeclareKanjiFamily {JY3} {#2} {#3}
+ \DeclareKanjiFamily {JT3} {#2} {#3}
+}
+
+%% save and restore global variable
+\tl_new:N \g__ltj_fontspec_kanji_nfss_family_tl
+\tl_new:N \g__ltj_fontspec_orig_nfss_family_tl
+\seq_new:N \g__ltj_fontspec_kanji_bf_series_seq
+\seq_new:N \g__ltj_fontspec_orig_bf_series_seq
+\clist_new:N \g__ltj_fontspec_kanji_default_fontopts_clist
+\clist_new:N \g__ltj_fontspec_orig_default_fontopts_clist
+
+\cs_new:Nn \__ltj_set_global_variable_for_kanji: {
+ \tl_gset_eq:NN \g__ltj_fontspec_orig_nfss_family_tl \g__fontspec_nfss_family_tl
+ \tl_gset_eq:NN \g__fontspec_nfss_family_tl \g__ltj_fontspec_kanji_nfss_family_tl
+ \seq_gset_eq:NN \g__ltj_fontspec_orig_bf_series_seq \g__fontspec_bf_series_seq
+ \seq_gset_eq:NN \g__fontspec_bf_series_seq \g__ltj_fontspec_kanji_bf_series_seq
+ %\seq_gclear:N \g__fontspec_bf_series_seq
+ \clist_set_eq:NN \g__ltj_fontspec_orig_default_fontopts_clist \g__fontspec_default_fontopts_clist
+ \clist_set_eq:NN \g__fontspec_default_fontopts_clist \g__ltj_fontspec_kanji_default_fontopts_clist
+}
+
+\cs_new:Nn \__ltj_restore_global_variable: {
+ \tl_gset_eq:NN \g__ltj_fontspec_kanji_nfss_family_tl \g__fontspec_nfss_family_tl
+ \tl_gset_eq:NN \g__fontspec_nfss_family_tl \g__ltj_fontspec_orig_nfss_family_tl
+ \seq_gset_eq:NN \g__ltj_fontspec_kanji_bf_series_seq \g__fontspec_bf_series_seq
+ \seq_gset_eq:NN \g__fontspec_bf_series_seq \g__ltj_fontspec_orig_bf_series_seq
+ \clist_set_eq:NN \g__ltj_fontspec_kanji_default_fontopts_clist \g__fontspec_default_fontopts_clist
+ \clist_set_eq:NN \g__fontspec_default_fontopts_clist \g__ltj_fontspec_orig_default_fontopts_clist
+}
+
+\cs_set_eq:NN \__ltj_orig_fontspec_select_font_family:nn \__fontspec_select_font_family:nn
+\cs_new_protected:Nn \__ltj_fontspec_select_font_family:nn {
+ \group_begin:
+ \__ltj_fontspec_define_option:nn {NoEmbed} {}
+ \__ltj_fontspec_define_option:nn {AltFont} {
+ \clist_put_right:Nn \l__ltj_fontspec_altfont_clist { ##1 }
+ }
+ \__ltj_fontspec_define_option:nn {CID} {
+ \__fontspec_update_featstr:n {cid=##1}
+ }
+ \__ltj_fontspec_define_option:nn {Kanjiskip} {
+ \str_if_eq_x:nnTF {false} { \str_lower_case:n { ##1 } }{
+ \__fontspec_update_featstr:n {-ltjksp}
+ } {
+ \__fontspec_update_featstr:n {+ltjksp}
+ }
+ }
+ \__ltj_fontspec_define_option:nn {JFM} {
+ \__fontspec_update_featstr:n {jfm=##1}
+ }
+ % vary by shape
+ \__ltj_fontspec_define_option:nn {YokoFeatures} {
+ \clist_put_right:Nn \l__ltj_fontspec_fontfeat_yoko_clist { ##1 }
+ }
+ \__ltj_fontspec_define_option:nn {TateFeatures} {
+ \clist_put_right:Nn \l__ltj_fontspec_fontfeat_tate_clist { ##1 }
+ }
+ \__ltj_fontspec_define_option:nn {TateFont}
+ {
+ \tl_if_empty:nF {##1} {
+ \fontspec_complete_fontname:Nn \l__ltj_fontspec_fontname_tate_tl {##1}
+ }
+ }
+ \__ltj_fontspec_define_option:nn {JFM-var} {
+ \__fontspec_update_featstr:n {jfmvar=##1}
+ }
+ \__ltj_fontspec_define_preparse_external:nn {NoEmbed} {
+ \cs_set:Npn \__fontspec_fontname_wrap:n ##1 {psft:##1}
+ }
+
+ %% Omit the warning message
+ %% "OpenType feature 'Kerning=Off' (-kern) not available ..."
+ \keys_define:nn {fontspec-opentype} {
+ Kerning/Off.code:n=\__fontspec_update_featstr:n {-kern}
+ }
+ \clist_set:Nx \g__fontspec_default_fontopts_clist {
+ YokoFeatures = { JFM=\ltj@stdyokojfm }, TateFeatures = { JFM=\ltj@stdtatejfm },
+ Scale=\Cjascale, Kerning=Off, Script=CJK,
+ \g__ltj_fontspec_kanji_default_fontopts_clist
+ }
+ \prop_set_eq:NN \g__fontspec_fontopts_prop \g__ltj_fontspec_fontopts_prop
+ \cs_set_eq:NN \__fontspec_make_font_shapes:Nnnnn \__ltj_fontspec_make_font_shapes:Nnnnn
+ \cs_set_eq:NN \DeclareFontFamily \__ltj_fontspec_DeclareFontFamily
+ \tl_set:Nn \g_fontspec_encoding_tl {JY3}
+ \__ltj_orig_fontspec_select_font_family:nn{#1}{#2}
+
+ \cs_gset:Npx \__ltj_fontspec_aftergroup {
+ \exp_not:N \tl_set:Nn \exp_not:N \l_fontspec_family_tl { \l_fontspec_family_tl }
+ }
+ \aftergroup \__ltj_fontspec_aftergroup
+ \group_end:
+}
+
+%% declare_shape
+
+\cs_new:Nn \__ltj_fontspec_declare_shape_yoko:nnnn {
+ \__ltj_fontspec_declare_shape_aux:nnnnnn {#1} {#2} {#3} {#4} { JY3 } { \l__ltj_fontspec_fontfeat_yoko_clist }
+}
+\cs_new:Nn \__ltj_fontspec_declare_shape_tate:nnnn {
+ \__ltj_fontspec_declare_shape_aux:nnnnnn {#1} {#2} {#3} {#4} { JT3 } { \l__ltj_fontspec_fontfeat_tate_clist }
+}
+\cs_new:Nn \__ltj_fontspec_declare_shape:nnnn {
+ \__ltj_fontspec_declare_shape_yoko:nnnn {#1} {#2} {#3} {#4}
+ \__ltj_fontspec_declare_shape_tate:nnnn {#1} {#2} {#3} {#4}
+}
+\cs_generate_variant:Nn \__ltj_fontspec_declare_shape:nnnn {nnxx}
+\cs_generate_variant:Nn \__ltj_fontspec_declare_shape_yoko:nnnn {nnxx}
+\cs_generate_variant:Nn \__ltj_fontspec_declare_shape_tate:nnnn {nnxx}
+
+\cs_new:Nn \__ltj_fontspec_declare_shape_aux:nnnnnn
+{
+ \tl_build_begin:N \l__fontspec_nfss_tl
+ \tl_build_begin:N \l__fontspec_nfss_sc_tl
+ \tl_set_eq:NN \l__fontspec_saved_fontname_tl \l_fontspec_fontname_tl
+
+ \tl_set:Nn \g_fontspec_encoding_tl {#5}
+ \tl_set:Nn \g__fontspec_nfss_enc_tl {#5}
+ \exp_args:Nx \clist_map_inline:nn {#4}
+ { \__ltj_fontspec_setup_single_size:nnn {#3} {#6} {##1} }
+ \tl_build_end:N \l__fontspec_nfss_tl
+ \tl_build_end:N \l__fontspec_nfss_sc_tl
+
+ \bool_set_true:N \l__fontspec_nosc_bool
+ \__fontspec_declare_shapes_normal:nn {#1} {#2}
+ \__fontspec_declare_shape_slanted:nn {#1} {#2}
+}
+
+\cs_new:Nn \__ltj_fontspec_setup_single_size:nnn
+{
+ \tl_clear:N \l__fontspec_size_tl
+ \tl_set_eq:NN \l__fontspec_sizedfont_tl \l__fontspec_saved_fontname_tl % in case not spec'ed
+
+ \keys_set_known:nxN {fontspec-sizing} { \exp_after:wN \use:n #3 }
+ \l__fontspec_sizing_leftover_clist
+ \tl_if_empty:NT \l__fontspec_size_tl { \__fontspec_error:n {no-size-info} }
+
+ \str_if_eq:nnTF { \g__fontspec_nfss_enc_tl } { JY3 } {
+ % "normal"
+ \__fontspec_load_fontname:Nn \l_fontspec_fontname_tl {\l__fontspec_sizedfont_tl}
+ } {
+ \tl_if_empty:NTF \l__ltj_fontspec_fontname_tate_tl
+ { \__fontspec_load_fontname:Nn \l_fontspec_fontname_tl {\l__fontspec_sizedfont_tl} }
+ { \__fontspec_load_fontname:Nn \l_fontspec_fontname_tl {\l__ltj_fontspec_fontname_tate_tl} }
+ }
+ \__fontspec_setup_nfss:Nnnn \l__fontspec_nfss_tl {#1} {#2} {}
+}
+
+\cs_new:Nn \__ltj_fontspec_set_family:Nnn {
+ \__ltj_set_global_variable_for_kanji:
+ \cs_set_eq:NN \__fontspec_select_font_family:nn \__ltj_fontspec_select_font_family:nn
+ \__ltj_orig_fontspec_set_family:Nnn #1 {#2} {#3}
+ \cs_set_eq:NN \__fontspec_select_font_family:nn \__ltj_orig_fontspec_select_font_family:nn
+ \__ltj_restore_global_variable:
+}
+\cs_set_eq:NN \__ltj_orig_fontspec_set_family:Nnn \fontspec_set_family:Nnn
+\cs_set_eq:NN \__ltj_orig_fontspec_make_font_shapes:Nnnnn \__fontspec_make_font_shapes:Nnnnn
+\cs_set_eq:NN \__ltj_fontspec_orig_DeclareFontShape \DeclareFontShape
+
+\cs_new:Nn \__ltj_fontspec_make_font_shapes:Nnnnn {
+ \group_begin:
+ %% 基底フォント
+ \cs_set_eq:NN \__fontspec_font_set:Nnn \use_none:nnn
+ \cs_set_eq:NN \__fontspec_font_if_null:NT \use_none:nn
+ \cs_set_eq:NN \__fontspec_declare_shape:nnxx \__ltj_fontspec_declare_shape:nnxx
+ \__ltj_orig_fontspec_make_font_shapes:Nnnnn {#1} {#2} {#3} {#4} {#5}
+ %%
+ \__ltj_fontspec_make_font_shapes_alt:Nnnnnn {#1}{#2}{#3}
+ {#4, \l__ltj_fontspec_fontfeat_yoko_clist}{#5} {JY3 }
+ \__ltj_fontspec_make_font_shapes_alt:Nnnnnn {#1}{#2}{#3}
+ {#4, \l__ltj_fontspec_fontfeat_tate_clist}{#5} {JT3}
+ \group_end:
+ }
+
+%%% Altfont 内部処ç†éƒ¨
+\cs_new:Nn \__ltj_fontspec_make_font_shapes_alt:Nnnnnn {
+ \group_begin:
+ \str_if_eq:nnTF { #6 } { JY3 } {
+ \cs_set_eq:NN \__fontspec_declare_shape:nnxx \__ltj_fontspec_declare_shape_yoko:nnxx
+ }{
+ \cs_set_eq:NN \__fontspec_declare_shape:nnxx \__ltj_fontspec_declare_shape_tate:nnxx
+ }
+ \keys_set_known:nn {fontspec-ltjaltfont-reparse} { #4 }
+ \clist_if_empty:NF \l__ltj_fontspec_altfont_clist {
+ \int_gzero:N \g__ltj_fontspec_altnumber_int
+ \clist_map_inline:Nn \l__ltj_fontspec_altfont_clist {
+ \tl_clear:N \l__ltj_fontspec_altrange_tl
+ \tl_set:Nn \l__ltj_fontspec_altname_tl { #1 }
+ \tl_set:Nn \l_tmpa_tl { #1 }
+
+ \keys_set_known:nxN {fontspec-ltjaltfont} { \exp_after:wN \use:n ##1 }
+ \l__ltj_fontspec_altfont_leftover_clist
+ \keys_set_known:nn {fontspec-ltjaltfont-reparse} { \exp_after:wN \use:n ##1 }
+
+ \tl_if_empty:NT \l__ltj_fontspec_altrange_tl {
+ \msg_warning:nnn {luatexja-fontspec} {altfont-ignored-by-norange} { ##1 }
+ } {
+ \bool_if:nTF {
+ \tl_if_eq_p:NN \l__ltj_fontspec_altname_tl \l_tmpa_tl
+ &&
+ \tl_if_empty_p:N \l__ltj_fontspec_altfont_leftover_clist
+ } {
+ \msg_warning:nnn {luatexja-fontspec} {altfont-ignored-by-rangeonly} { ##1 }
+ } {
+ \__ltj_orig_fontspec_make_font_shapes:Nnnnn
+ { \l__ltj_fontspec_altname_tl } {#2}
+ {#3 _ alt \int_use:N \g__ltj_fontspec_altnumber_int }
+ {#4, \l__ltj_fontspec_altfont_leftover_clist }
+ {#5}
+ \DeclareAlternateKanjiFont
+ { #6 }{ \g__fontspec_nfss_family_tl }{#2}{#3}%
+ { #6 }{ \g__fontspec_nfss_family_tl }{#2}
+ { #3 _alt \int_use:N \g__ltj_fontspec_altnumber_int }
+ { \l__ltj_fontspec_altrange_tl }
+ \int_gincr:N \g__ltj_fontspec_altnumber_int
+ }
+ }
+ }
+ }
+ \group_end:
+}
+
+
+%%%%%%%% User commands
+\DeclareDocumentCommand \jfontspec { O{} m O{} } {
+ \__ltj_fontspec_set_family:Nnn \k@family {#1,#3}{#2}
+ \selectfont
+ \ignorespaces
+}
+
+\DeclareDocumentCommand \setmainjfont { O{} m O{} } {
+ \__ltj_fontspec_set_family:Nnn \mcdefault {#1,#3}{#2}
+ \unless\ifltj@disablejfam
+ \DeclareSymbolFont{mincho}{JY3}{\mcdefault}{\mddefault}{n}
+ \SetSymbolFont{mincho}{bold}{JY3}{\mcdefault}{\bfdefault}{n}
+ \fi
+ \normalfont
+}
+
+\DeclareDocumentCommand \setsansjfont { O{} m O{} } {
+ \__ltj_fontspec_set_family:Nnn \gtdefault {#1,#3}{#2}
+ \unless\ifltj@disablejfam
+ \DeclareMathAlphabet{\mathgt}{JY3}{\gtdefault}{\mddefault}{n}
+ \fi
+ \normalfont
+}
+
+\DeclareDocumentCommand \newjfontfamily { m O{} m O{} } {
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_fontspec_set_family:Nnn
+ \newfontfamily #1 [#2,#4] {#3}
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
+}
+\DeclareDocumentCommand \renewjfontfamily { m O{} m O{} } {
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_fontspec_set_family:Nnn
+ \renewfontfamily #1 [#2,#4] {#3}
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
+}
+\DeclareDocumentCommand \setjfontfamily { m O{} m O{} } {
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_fontspec_set_family:Nnn
+ \setfontfamily #1 [#2,#4] {#3}
+ \cs_set_eq:NN \fontspec_set_family:Nnn \__ltj_orig_fontspec_set_family:Nnn
+}
+
+\DeclareDocumentCommand \newjfontface { m O{} m O{} } {
+ \newjfontfamily #1 [ BoldFont={},ItalicFont={},SmallCapsFont={},#2,#4 ] {#3}
+}
+
+\prop_new:N \g__ltj_fontspec_fontopts_prop
+\DeclareDocumentCommand \defaultjfontfeatures { t+ o m }
+ {
+ \IfNoValueTF {#2}
+ { \__ltj_fontspec_set_default_features:nn {#1} {#3} }
+ { \__ltj_fontspec_set_font_default_features:nnn {#1} {#2} {#3} }
+ \ignorespaces
+ }
+\cs_new:Nn \__ltj_fontspec_set_default_features:nn
+ {
+ \__ltj_set_global_variable_for_kanji:
+ \__fontspec_set_default_features:nn {#1} {#2}
+ \__ltj_restore_global_variable:
+ }
+\cs_new:Nn \__ltj_fontspec_set_font_default_features:nnn
+ {
+ \prop_set_eq:NN \l__ltj_fontspec_tmp_prop \g__fontspec_fontopts_prop
+ \prop_set_eq:NN \g__fontspec_fontopts_prop \g__ltj_fontspec_fontopts_prop
+ \__fontspec_set_font_default_features:nnn {#1} {#2} {#3}
+ \prop_set_eq:NN \g__ltj_fontspec_fontopts_prop \g__fontspec_fontopts_prop
+ \prop_set_eq:NN \g__fontspec_fontopts_prop \l__ltj_fontspec_tmp_prop
+ }
+
+\DeclareDocumentCommand \addjfontfeatures {m} {
+ \__ltj_fontspec_if_fontspec_font:TF
+ {
+ \__ltj_set_global_variable_for_kanji:
+ \group_begin:
+ \tl_set_eq:NN \f@family \k@family
+ \cs_set_eq:NN \__fontspec_select_font_family:nn \__ltj_fontspec_select_font_family:nn
+ \addfontfeatures {#1}
+ \group_end:
+ \kanjifamily\g__fontspec_nfss_family_tl\selectfont
+ \__ltj_restore_global_variable:
+ }{
+ \msg_warning:nn {luatexja-fontspec} {addjfontfeatures-ignored}
+ }
+ \ignorespaces
+}
+
+\cs_set_eq:NN \addjfontfeature \addjfontfeatures
+
+\prg_new_conditional:Nnn \__ltj_fontspec_if_fontspec_font: {TF,T,F}
+{
+ \cs_if_exist:cTF {g__fontspec_fontinfo_ \k@family _prop} \prg_return_true: \prg_return_false:
+}
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec.sty
new file mode 100644
index 0000000000..e98fbc7b95
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-fontspec.sty
@@ -0,0 +1,60 @@
+%
+% luatexja-fontspec.sty
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{luatexja-fontspec}[2019/03/20 fontspec support of LuaTeX-ja]
+\RequirePackage{l3keys2e,luatexja}
+\ExplSyntaxOn
+
+\cs_if_exist:NF \Cjascale {
+ %% Default scale value for jfont.
+ \group_begin:
+ \fontsize{16}{16}\selectfont
+ \cs_gset:Npx \Cjascale { \fp_to_decimal:n {\zw / 16} }
+ \group_end:
+}
+
+\bool_new:N \__ltj_fontspec_match_bool
+\keys_define:nn { luatexja-fontspec }
+ {
+ match .bool_set:N = \__ltj_fontspec_match_bool,
+ match .default:n = true,
+ pass .code:n = \PassOptionsToPackage{#1} {fontspec},
+ % 互æ›æ€§ã®ãŸã‚ã«æ®‹ã—ãŸã‚ªãƒ—ション
+ scale .code:n = \gdef\Cjascale{#1},
+ unknown .code:n = \PassOptionsToPackage { \l_keys_key_tl } {fontspec},
+ }
+\ProcessKeysOptions{ luatexja-fontspec }
+
+\RequirePackage{fontspec}[2017/01/01]% v2.5c
+\@ifpackagelater{fontspec}{2018/07/29}%
+ {\@ifpackagelater{fontspec}{2019/03/15}%
+ {\RequirePackage{luatexja-fontspec-27c}} % v2.7c
+ {\RequirePackage{luatexja-fontspec-26h}}}% v2.6h
+ {\RequirePackage{luatexja-fontspec-25c}} % v2.5c
+
+\ExplSyntaxOff
+%%%%%%%% Now we completely ignore kanjifont definition file.
+\def\@ltj@use@fd{false}
+
+% We must redefine \try@load@fontshape to ignore kanjifont definitions at all.
+\def\try@load@fontshape{%
+ \expandafter
+ \ifx\csname \f@encoding+\f@family\endcsname\relax
+ \directlua{luatexja.jfont.is_kenc('\luatexluaescapestring{\f@encoding}')}%
+\ifin@\else % Alphabetic font
+ \@font@info{Try loading font information for \f@encoding+\f@family}%
+ \global\expandafter\let
+ \csname\f@encoding+\f@family\endcsname\@empty
+ \nfss@catcodes
+ \let\nfss@catcodes\relax
+ \edef\reserved@a{%
+ \lowercase{%
+ \noexpand\InputIfFileExists{\f@encoding\f@family.fd}}}%
+ \reserved@a\relax
+ {\@input@{\f@encoding\f@family.fd}}%
+\fi
+ \fi}
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-otf.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-otf.sty
new file mode 100644
index 0000000000..082468b97b
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-otf.sty
@@ -0,0 +1,205 @@
+%
+% luatexja-otf.sty
+%
+
+%% Avoid multiple loading.
+\csname\if11luatexjaotfLoaded\fi\endcsname
+\edef\x{%
+\catcode32=\the\catcode32%
+\catcode33=\the\catcode33%
+\catcode35=\the\catcode35%
+\catcode40=\the\catcode40%
+\catcode41=\the\catcode41%
+\catcode42=\the\catcode42%
+\catcode43=\the\catcode43%
+\catcode44=\the\catcode44%
+\catcode45=\the\catcode45%
+\catcode46=\the\catcode46%
+\catcode58=\the\catcode58%
+\catcode59=\the\catcode59%
+\catcode60=\the\catcode60%
+\catcode61=\the\catcode61%
+\catcode62=\the\catcode62%
+\catcode64=\the\catcode64%
+\catcode91=\the\catcode91%
+\catcode93=\the\catcode93%
+\catcode94=\the\catcode94%
+\catcode95=\the\catcode95%
+\catcode126=\the\catcode126%
+\endlinechar=\the\endlinechar
+\relax}
+\catcode32=10 %< >
+\catcode33=12 %<">
+\catcode35=6 %<#>
+\catcode40=12 %<(>
+\catcode41=12 %<)>
+\catcode42=12 %<*>
+\catcode43=12 %<+>
+\catcode44=12 %<,>
+\catcode45=12 %<->
+\catcode46=12 %<.>
+\catcode58=12 %<:>
+\catcode59=12 %<;>
+\catcode60=12 %<<>
+\catcode61=12 %<=>
+\catcode62=12 %<>>
+\catcode64=11 %<@>
+\catcode91=12 %<[>
+\catcode93=12 %<]>
+\catcode94=7 %<^>
+\catcode95=8 %<_>
+\catcode126=13 %<~>
+\endlinechar=-1 %
+
+\edef\ltj@otf@AtEnd{\x
+ \noexpand\let\noexpand\ltj@otf@AtEnd\relax}
+\def\luatexjaotfLoaded{\endinput}
+
+%% Check if LaTeX is used.
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax %<*!LaTeX>
+ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname
+ \csname iffalse\endcsname
+\else %<*LaTeX>
+ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname
+ \csname iftrue\endcsname
+ \NeedsTeXFormat{LaTeX2e}
+ \ProvidesPackage{luatexja-otf}[2017/05/20]
+\fi %</LaTeX>
+
+% Load core module if not yet.
+\ifx\luatexjacoreLoaded\@undefined
+ \ifltj@in@latex %<*LaTeX>
+ \RequirePackage{luatexja}
+ \else %<*!LaTeX>
+ \input luatexja.sty %
+ \fi %</LaTeX>
+\fi
+
+%% When environment check fails, exit now.
+\ifx\LuaTeXjaAvailable\@undefined
+ \ltj@otf@AtEnd
+\expandafter\endinput\fi\relax
+
+%%------------------
+%! Main part of luatexja-otf
+\RequireLuaTeXjaSubmodule{otf}
+
+\newcount\ltj@tempcnta
+
+\protected\def\CID#1{\ifvmode\leavevmode\fi\ltj@tempcnta#1\relax\directlua{luatexja.otf.cid(\the\ltj@tempcnta)}\relax}
+
+%% \UTF compatible with the OTF package for pLaTeX
+\protected\def\UTF#1{\ifvmode\leavevmode\fi\directlua{luatexja.otf.utf(0x#1)}}
+
+%% Load ajmacros
+\ifltj@in@latex %<*LaTeX>
+ \RequirePackage{luatexja-ajmacros}
+\else %<*!LaTeX>
+ \input luatexja-ajmacros.sty %
+ % \bou is defined in lltjext, \mbox is defined in LaTeX kernel
+ \def\boutenchar{\char\euc"A1A2}%"
+ \def\bou#1{\ifvmode\leavevmode\fi\@bou#1\end}
+ \def\@bou#1{%
+ \ifx#1\end \let\ltj@@next=\relax
+ \else
+ \ifnum\ltjgetparameter{direction}=3\relax
+ \hbox to\z@{\vbox to\z@{\boxmaxdepth\maxdimen
+ \vss\moveleft0.2\zw\hbox{\yoko\boutenchar}\nointerlineskip
+ \hbox{\char\euc"A1A1}}\hss}\nobreak#1\relax
+ \else
+ \hbox to\z@{\vbox to\z@{\boxmaxdepth\maxdimen
+ \vss\moveleft-0.2\zw\hbox{\boutenchar}\nointerlineskip
+ \hbox{\char\euc"A1A1}}\hss}\nobreak#1\relax
+ \fi
+ \let\ltj@@next=\@bou
+ \fi\ltj@@next}
+ \long\def\mbox#1{\leavevmode\hbox{#1}}
+\fi %</LaTeX>
+
+% macros from otf.sty
+%for literature
+\protected\def\ajKunoji{%
+ \ifnum\ltjgetparameter{direction}=3 \mbox{\UTF{3033}\UTF{3035}}\else
+ \@PackageError{luatexja-otf}{A TATE character in YOKO mode!}{Change a direction to TATE.}%2003/03/12
+ \fi}
+\protected\def\ajKunojiwithBou{%
+ \ifnum\ltjgetparameter{direction}=3 \mbox{\bou{\mbox{\UTF{3033}}}\bou{\mbox{\UTF{3035}}}}\else
+ \@PackageError{luatexja-otf}{A TATE character in YOKO mode!}{Change a direction to TATE.}%2003/03/12
+ \fi}
+\protected\def\ajDKunoji{%
+ \ifnum\ltjgetparameter{direction}=3 \mbox{\UTF{3034}\UTF{3035}}\else
+ \@PackageError{luatexja-otf}{A TATE character in YOKO mode!}{Change a direction to TATE.}%2003/03/12
+ \fi}
+\protected\def\ajDKunojiwithBou{%
+ \ifnum\ltjgetparameter{direction}=3 \mbox{\bou{\mbox{\UTF{3034}}}\bou{\mbox{\UTF{3035}}}}\else
+ \@PackageError{luatexja-otf}{A TATE character in YOKO mode!}{Change a direction to TATE.}%2003/03/12
+ \fi}
+\protected\def\ajNinoji{\CID{12106}}
+\protected\def\ajvarNinoji{%
+ \ifnum\ltjgetparameter{direction}=3 \CID{12107}\else
+ \@PackageError{luatexja-otf}{A TATE character in YOKO mode!}{Change a direction to TATE.}%2003/03/12
+ \fi}
+\protected\def\ajYusuriten{%
+ \ifnum\ltjgetparameter{direction}=3 \CID{16193}\else
+ \@PackageError{luatexja-otf}{A TATE character in YOKO mode!}{Change a direction to TATE.}%2003/03/12
+ \fi}
+\protected\def\ajMasu{\UTF{303c}}
+\protected\def\ajYori{\UTF{309f}}
+\protected\def\ajKoto{\UTF{30ff}}
+\protected\def\ajUta{\UTF{303d}}
+%dingbats
+\protected\def\ajCommandKey{\UTF{2318}}
+\protected\def\ajReturnKey{\UTF{23ce}}
+\protected\def\ajCheckmark{\UTF{2713}}
+\protected\def\ajVisibleSpace{\UTF{2423}}
+\protected\def\ajSenteMark{\UTF{2617}}
+\protected\def\ajGoteMark{\UTF{2616}}
+\protected\def\ajClub{\UTF{2663}}
+\protected\def\ajHeart{\UTF{2661}}
+\protected\def\ajSpade{\UTF{2660}}
+\protected\def\ajDiamond{\UTF{2662}}
+\protected\def\ajvarClub{\UTF{2667}}
+\protected\def\ajvarHeart{\UTF{2665}}
+\protected\def\ajvarSpade{\UTF{2664}}
+\protected\def\ajvarDiamond{\UTF{2666}}
+\protected\def\ajPhone{\UTF{260e}}
+\protected\def\ajPostal{\UTF{3020}}
+\protected\def\ajvarPostal{\UTF{3036}}
+\protected\def\ajSun{\UTF{2600}}
+\protected\def\ajCloud{\UTF{2601}}
+\protected\def\ajUmbrella{\UTF{2602}}
+\protected\def\ajSnowman{\UTF{2603}}
+\protected\def\ajJIS{\UTF{3004}}
+\protected\def\ajJAS{\CID{12088}}
+\protected\def\ajBall{\CID{12097}}
+\protected\def\ajHotSpring{\UTF{2668}}
+\protected\def\ajWhiteSesame{\UTF{fe46}}
+\protected\def\ajBlackSesame{\UTF{fe45}}
+\protected\def\ajWhiteFlorette{\UTF{2740}}
+\protected\def\ajBlackFlorette{\UTF{273f}}
+\protected\def\ajRightBArrow{\CID{8206}}
+\protected\def\ajLeftBArrow{\CID{8207}}
+\protected\def\ajUpBArrow{\CID{8208}}
+\protected\def\ajDownBArrow{\CID{8209}}
+\protected\def\ajRightHand{\CID{8219}}
+\protected\def\ajLeftHand{\CID{8220}}
+\protected\def\ajUpHand{\CID{8221}}
+\protected\def\ajDownHand{\CID{8222}}
+\protected\def\ajRightScissors{\CID{12176}}
+\protected\def\ajLeftScissors{\CID{12175}}
+\protected\def\ajUpScissors{\CID{12177}}
+\protected\def\ajDownScissors{\CID{12178}}
+\protected\def\ajRightWArrow{\CID{12197}}
+\protected\def\ajLeftWArrow{\CID{12196}}
+\protected\def\ajUpWArrow{\CID{12198}}
+\protected\def\ajDownWArrow{\CID{12199}}
+\protected\def\ajRightDownArrow{\CID{12202}}
+\protected\def\ajLeftDownArrow{\CID{12203}}
+\protected\def\ajLeftUpArrow{\CID{12204}}
+\protected\def\ajRightUpArrow{\CID{12205}}
+
+%%------------------ all done
+\ltj@otf@AtEnd
+\endinput
+%% EOF
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-preset.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-preset.sty
new file mode 100644
index 0000000000..2eb38c8384
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-preset.sty
@@ -0,0 +1,706 @@
+% luatexja-preset.sty
+\ProvidesPackage{luatexja-preset}[2019/03/26 Japanese font presets]
+
+\RequirePackage{expl3,l3keys2e}
+\RequirePackage{luatexja}
+\ExplSyntaxOn
+
+%% messages
+\msg_new:nnn { luatexja-preset }{ ltj-fontspec }{
+ The~ luatexja-fontspec~ package~ is~ loaded~ already.~
+ Hence~ we~ ignore~ `nfssonly'~option.
+}
+\msg_new:nnn { luatexja-preset }{ no-font }{
+ Font~ #1~ (#2)~ is~ not~found.~ Hence~ I~ substitute~ #3~ (#4)~ for~ it.
+}
+\msg_new:nnn { luatexja-preset }{ scale }{
+ Japanese~fonts~will~be~scaled~by~#1.
+}
+
+\msg_new:nnn { luatexja-preset }{ exist-preset-nooverwrite }{
+ The~ preset~ `#1'~ is~ already~ defined.~
+ To~ redefine~ this~ preset,~ use~ \str_use:N \c_backslash_str ltjnewpreset*~ instead.
+}
+\msg_new:nnn { luatexja-preset }{ exist-preset-overwrite }{
+ The~ preset~ `#1'~ is~ redefined.
+}
+
+\msg_new:nnn { luatexja-preset }{ illegal-preset-name }{
+ The~ preset~ `#1'~ cannot~ be~ defined,~
+ since~ the~ luatexja-preset~ package~ an~ option~ with~ the~ same~ name.
+}
+
+\seq_new:N \g__ltjpreset_presets_seq
+
+\keys_define:nn { luatexja-preset }{
+ unknown .code:n =
+ \keys_set_known:noN { ltjpreset-presets } { \tl_use:N \l_keys_tl } \l_tmpa_tl
+ \tl_if_empty:NT \l_tmpa_tl {
+ \PassOptionsToPackage { \l_tmpa_tl } { luatexja-fontspec }
+ },
+ scale .code:n = \gdef\Cjascale{#1},
+ match .code: n =
+ \renewcommand\jttdefault{\gtdefault}\@ltj@match@familytrue
+ \PassOptionsToPackage { match } { luatexja-fontspec },
+ match .value_forbidden:n = true,
+ __custom .bool_set:N = \g__ltjpreset_custom_bool, __custom .groups:n = { preset },
+ __office .bool_set:N = \g__ltjpreset_office_bool, __office .groups:n = { preset },
+ __noembed .bool_set:N = \g__ltjpreset_noembed_bool, __noembed .groups:n = { preset },
+}
+\cs_new:Nn \__ltjpreset_declare_option:nn {
+ \keys_define:nn { luatexja-preset }{
+ #1 .code:n = { #2 },
+ #1 .value_forbidden:n = true
+ }
+}
+\cs_new:Nn \ltjpreset_declare_preset:nn {
+ \keys_define:nn { luatexja-preset }{
+ #1 .meta:n = { #2 },
+ #1 .value_forbidden:n = true, #1 .groups:n = { preset },
+ }
+ \seq_put_right:Nn \g__ltjpreset_presets_seq { #1 }
+}
+\cs_generate_variant:Nn \ltjpreset_declare_preset:nn {nx}
+\cs_new:Nn \__ltjpreset_declare_bool_option:nn {
+ \bool_new:c { g__ltjpreset_#1_bool }
+ \bool_set_false:c { g__ltjpreset_#1_bool }
+ \keys_define:nn { luatexja-preset }{
+ #1 .bool_set:c = { g__ltjpreset_#1_bool },
+ #2 .bool_set_inverse:c = { g__ltjpreset_#1_bool },
+ #1 .default:n = true, #2 .default:n = true,
+ }
+}
+
+%%%%%%%% bool options
+\__ltjpreset_declare_bool_option:nn { nfssonly }{ fontspec }
+\__ltjpreset_declare_bool_option:nn { bold }{ nobold }
+\__ltjpreset_declare_bool_option:nn { expert }{ noexpert }
+\__ltjpreset_declare_bool_option:nn { deluxe }{ nodeluxe }
+
+% JFM
+\tl_new:N \__ltjpreset_use_jfm_yoko_tl % 使用ã™ã‚‹ JFM(横)
+\tl_set:Nn \__ltjpreset_use_jfm_yoko_tl {\ltj@stdyokojfm}
+\tl_new:N \__ltjpreset_use_jfm_tate_tl % 使用ã™ã‚‹ JFM(縦)
+\tl_set:Nn \__ltjpreset_use_jfm_tate_tl {\ltj@stdtatejfm}
+\__ltjpreset_declare_option:nn{jis}{\tl_set:Nn \__ltjpreset_use_jfm_yoko_tl {jis}} % jis
+\__ltjpreset_declare_option:nn{ujis}{\tl_set:Nn \__ltjpreset_use_jfm_yoko_tl {ujis}} % ujis
+
+% 漢字字形
+\tl_new:N \l__ltjpreset_kanji_shape_tl
+\__ltjpreset_declare_option:nn{90jis}{ \tl_set:Nn \l__ltjpreset_kanji_shape_tl { , CJKShape=JIS1990 }} % 90jis
+\__ltjpreset_declare_option:nn{jis90}{ \tl_set:Nn \l__ltjpreset_kanji_shape_tl { , CJKShape=JIS1990 }} % 90jis
+\__ltjpreset_declare_option:nn{jis2004}{\tl_set:Nn \l__ltjpreset_kanji_shape_tl { , CJKShape=JIS2004 }} % jis2004
+\__ltjpreset_declare_option:nn{2004jis}{\tl_set:Nn \l__ltjpreset_kanji_shape_tl { , CJKShape=JIS2004 }} % jis2004
+
+% font preset
+\prop_new:N \g__ltjpreset_font_prop
+\keys_define:nn { luatexja-preset } {
+ mc .code:n =
+ \prop_put:Nnn \g__ltjpreset_font_prop { mc-l } {#1}
+ \prop_put:Nnn \g__ltjpreset_font_prop { mc-m } {#1}
+ \prop_put:Nnn \g__ltjpreset_font_prop { mc-bx } {#1},
+ mc .groups:n = { preset }, mc .value_required:n = true,
+ gt .code:n =
+ \prop_put:Nnn \g__ltjpreset_font_prop { gt-u } {#1}
+ \prop_put:Nnn \g__ltjpreset_font_prop { gt-d } {#1}
+ \prop_put:Nnn \g__ltjpreset_font_prop { gt-bx } {#1}
+ \prop_put:Nnn \g__ltjpreset_font_prop { gt-eb } {#1},
+ gt-m .code:n = % gtfamily , medium series
+ \prop_put:Nnn \g__ltjpreset_font_prop { gt-u } {#1}
+ \prop_put:Nnn \g__ltjpreset_font_prop { gt-d } {#1},
+ % gt-d, gt-u ã¯éš ã—
+ gt .groups:n = { preset }, gt .value_required:n = true,
+ gt-m .groups:n = { preset }, gt-m .value_required:n = true,
+}
+\cs_set:Nn \ltjpreset_define_preset_prop:n {
+ \keys_define:nn { luatexja-preset } {
+ #1 .code:n = \prop_put:Non \g__ltjpreset_font_prop { #1 } { ##1 },
+ #1 .groups:n = { preset }, #1 .value_required:n = true,
+ }
+}
+\ltjpreset_define_preset_prop:n { mc-l }
+\ltjpreset_define_preset_prop:n { mc-m }
+\ltjpreset_define_preset_prop:n { mc-bx }
+\ltjpreset_define_preset_prop:n { gt-u }
+\ltjpreset_define_preset_prop:n { gt-d }
+\ltjpreset_define_preset_prop:n { gt-bx }
+\ltjpreset_define_preset_prop:n { gt-eb}
+\ltjpreset_define_preset_prop:n { mg-m }
+
+\cs_new:Nn \__ltjpreset_set_uni:nn {
+ mc = #1, gt = #2, mc-bx = #2, mg-m = #2,
+ __custom = false, __office = false, __noembed = false,
+}
+\cs_new:Npn \__ltjpreset_set_office:nn #1 #2{
+ mc = #1, mc-bx = HGMinchoE ,
+ gt-d = HGGothicM , gt-bx = HGGothicE ,
+ gt-u = #2 , gt-eb = HGSoeiKakugothicUB ,
+ mg-m = HGMaruGothicMPRO,
+ __custom = false, __office = true, __noembed = false,
+}
+
+%%%%%%%% プリセットé”
+
+% カスタム指定
+ \keys_define:nn { luatexja-preset }{
+ custom .meta:n = { #1, __custom = true, },
+ custom .value_required:n = true,
+ jfm_yoko .tl_set:N = \__ltjpreset_use_jfm_yoko_tl,
+ jfm_tate .tl_set:N = \__ltjpreset_use_jfm_tate_tl,
+}
+
+% å°å¡š (Adobe)
+%% Pro
+\ltjpreset_declare_preset:nx{kozuka-pro}{
+ mc-m = KozMinPro-Regular, mc-bx = KozMinPro-Bold,
+ gt-d = KozGoPro-Regular, gt-bx = KozGoPro-Bold,
+ gt-u = KozGoPro-Medium, gt-eb = KozGoPro-Heavy,
+ mg-m = KozGoPro-Heavy, mc-l = KozMinPro-Light,
+ __custom = false, __office = false, __noembed = false,
+}
+%% Pr6
+\ltjpreset_declare_preset:nx{kozuka-pr6}{
+ mc-m = KozMinProVI-Regular, mc-bx = KozMinProVI-Bold,
+ gt-d = KozGoProVI-Regular, gt-bx = KozGoProVI-Bold,
+ gt-u = KozGoProVI-Medium, gt-eb = KozGoProVI-Heavy,
+ mg-m = KozGoProVI-Heavy, mc-l = KozMinProVI-Light,
+ __custom = false, __office = false, __noembed = false,
+}
+%% Pr6N
+\ltjpreset_declare_preset:nx{kozuka-pr6n}{
+ mc-m = KozMinPr6N-Regular, mc-bx = KozMinPr6N-Bold,
+ gt-d = KozGoPr6N-Regular, gt-bx = KozGoPr6N-Bold,
+ gt-u = KozGoPr6N-Medium, gt-eb = KozGoPr6N-Heavy,
+ mg-m = KozGoPr6N-Heavy, mc-l = KozMinPr6N-Light,
+ __custom = false, __office = false, __noembed = false,
+}
+
+% ヒラギノ (OSX)
+\ltjpreset_declare_preset:nx{hiragino-pro}{
+ mc-m = HiraMinPro-W3, mc-bx = HiraMinPro-W6,
+ gt-d = HiraKakuPro-W3, gt-bx = HiraKakuPro-W6,
+ gt-u = HiraKakuPro-W6, gt-eb = HiraKakuStd-W8,
+ mg-m = HiraMaruPro-W4, mc-l = HiraMinPro-W2,
+ __custom = false, __office = false, __noembed = false,
+}
+\ltjpreset_declare_preset:nx{hiragino-pron}{
+ mc-m = HiraMinProN-W3, mc-bx = HiraMinProN-W6,
+ gt-d = HiraKakuProN-W3, gt-bx = HiraKakuProN-W6,
+ gt-u = HiraKakuProN-W6, gt-eb = HiraKakuStdN-W8,
+ mg-m = HiraMaruProN-W4, mc-l = HiraMinProN-W2,
+ __custom = false, __office = false, __noembed = false,
+}
+
+% モリサワ
+\ltjpreset_declare_preset:nx{bizud}{
+ mc = BIZ-UDMinchoM.ttc,
+ gt-d = BIZ-UDGothicR.ttc, gt-bx = BIZ-UDGothicB.ttc,
+ gt-u = BIZ-UDGothicR.ttc, gt-eb = BIZ-UDGothicB.ttc,
+ mg-m = BIZ-UDGothicB.ttc,
+ __custom = false, __office = false, __noembed = false,
+}
+\ltjpreset_declare_preset:nx{morisawa-pro}{
+ mc = A-OTF-RyuminPro-Light.otf, mc-bx = A-OTF-FutoMinA101Pro-Bold.otf,
+ gt-d = A-OTF-GothicBBBPro-Medium.otf , gt-bx = A-OTF-FutoGoB101Pro-Bold.otf,
+ gt-u = A-OTF-GothicBBBPro-Medium.otf , gt-eb = A-OTF-MidashiGoPro-MB31.otf,
+ mg-m = A-OTF-Jun101Pro-Light.otf,
+ __custom = false, __office = false, __noembed = false,
+}
+\ltjpreset_declare_preset:nx{morisawa-pr6n}{
+ mc = A-OTF-RyuminPr6N-Light.otf, mc-bx = A-OTF-FutoMinA101Pr6N-Bold.otf,
+ gt-d = A-OTF-GothicBBBPr6N-Medium.otf , gt-bx = A-OTF-FutoGoB101Pr6N-Bold.otf,
+ gt-u = A-OTF-GothicBBBPr6N-Medium.otf , gt-eb = A-OTF-MidashiGoPr6N-MB31.otf,
+ mg-m = A-OTF-Jun101Pr6N-Light.otf,
+ __custom = false, __office = false, __noembed = false,
+}
+
+% 游明æœ/游ゴシック (Win8.1)
+\ltjpreset_declare_preset:nx{yu-win}{
+ mc-m = YuMincho-Regular, mc-bx = YuMincho-Demibold,
+ gt-d = YuGothic-Regular, gt-bx = YuGothic-Bold,
+ gt-u = YuGothic-Regular, gt-eb = YuGothic-Bold,
+ mg-m = YuGothic-Bold, mc-l = YuMincho-Light,
+ __custom = false, __office = false, __noembed = false,
+}
+% Win10
+\ltjpreset_declare_preset:nx{yu-win10}{
+ mc-m = YuMincho-Regular, mc-bx = YuMincho-Demibold,
+ gt-d = YuGothic-Regular, gt-bx = YuGothic-Bold,
+ gt-u = YuGothic-Medium, gt-eb = YuGothic-Bold,
+ mg-m = YuGothic-Bold, mc-l = YuMincho-Light,
+ __custom = false, __office = false, __noembed = false,
+}
+
+% Yu fonts in OSX
+% according to http://support.apple.com/kb/HT5944
+\ltjpreset_declare_preset:nx{yu-osx}{
+ mc = YuMincho~Medium, mc-bx = YuMincho~Demibold,
+ gt-d = YuGothic~Medium, gt-u = YuGothic~Medium,
+ gt-bx = YuGothic~Bold, gt-eb = YuGothic~Bold,
+ mg-m = YuGothic~Bold,
+ __custom = false, __office = false, __noembed = false,
+}
+
+% moga-mobo
+\ltjpreset_declare_preset:nx{moga-mobo}{
+ mc = Moga90Mincho, mc-bx = Moga90Mincho~Bold,
+ gt-d = Moga90Gothic, gt-bx = Moga90Gothic~Bold,
+ gt-u = Moga90Gothic, gt-eb = Moga90Gothic~Bold,
+ mg-m = Mobo90Gothic,
+ __custom = false, __office = false, __noembed = false,
+}
+\ltjpreset_declare_preset:nx{moga-mobo-ex}{
+ mc = MogaEx90Mincho, mc-bx = MogaEx90Mincho~Bold,
+ gt-d = MogaEx90Gothic, gt-bx = MogaEx90Gothic~Bold,
+ gt-u = MogaEx90Gothic, gt-eb = MogaEx90Gothic~Bold,
+ mg-m = MoboEx90Gothic,
+ __custom = false, __office = false, __noembed = false,
+}
+
+% Ume fones
+\ltjpreset_declare_preset:nx{ume}{
+ mc = Ume~Mincho,
+ gt-d = Ume~Gothic, gt-bx = Ume~Gothic~O5,
+ gt-u = Ume~Gothic~O5, gt-eb = Ume~Gothic~O5,
+ mg-m = Ume~Gothic~O4,
+ __custom = false, __office = false, __noembed = false,
+}
+
+% Source Han {Serif,Sans}
+\ltjpreset_declare_preset:nx{sourcehan}{
+ mc-m = Source~Han~Serif~Regular,
+ mc-bx = Source~Han~Serif~Bold,
+ gt-d = Source~Han~Sans~Regular,
+ gt-bx = Source~Han~Sans~Bold,
+ gt-u = Source~Han~Sans~Medium,
+ gt-eb = Source~Han~Sans~Heavy,
+ mg-m = Source~Han~Sans~Heavy,
+ mc-l = Source~Han~Serif~Light,
+ __custom = false, __office = false, __noembed = false,
+}
+\ltjpreset_declare_preset:nx{sourcehan-jp}{
+ mc-m = Source~Han~Serif~JP~Regular,
+ mc-bx = Source~Han~Serif~JP~Bold,
+ gt-d = Source~Han~Sans~JP~Regular,
+ gt-bx = Source~Han~Sans~JP~Bold,
+ gt-u = Source~Han~Sans~JP~Medium,
+ gt-eb = Source~Han~Sans~JP~Heavy,
+ mg-m = Source~Han~Sans~JP~Heavy,
+ mc-l = Source~Han~Serif~JP~Light,
+ __custom = false, __office = false, __noembed = false,
+}
+\ltjpreset_declare_preset:nx{noto-otc}{
+ mc-m = Noto~Serif~CJK~Regular,
+ mc-bx = Noto~Serif~CJK~Bold,
+ gt-d = Noto~Sans~CJK~Regular,
+ gt-bx = Noto~Sans~CJK~Bold,
+ gt-u = Noto~Sans~CJK~Medium,
+ gt-eb = Noto~Sans~CJK~Black,
+ mg-m = Noto~Sans~CJK~Black,
+ mc-l = Noto~Serif~CJK~Light,
+ __custom = false, __office = false, __noembed = false,
+}
+\ltjpreset_declare_preset:nx{noto-otf}{
+ mc-m = Noto~Serif~CJK~JP~Regular,
+ mc-bx = Noto~Serif~CJK~JP~Bold,
+ gt-d = Noto~Sans~CJK~JP~Regular,
+ gt-bx = Noto~Sans~CJK~JP~Bold,
+ gt-u = Noto~Sans~CJK~JP~Medium,
+ gt-eb = Noto~Sans~CJK~JP~Black,
+ mg-m = Noto~Sans~CJK~JP~Black,
+ mc-l = Noto~Serif~CJK~JP~Light,
+ __custom = false, __office = false, __noembed = false,
+}
+
+
+% ipa, ipaex, ms
+\ltjpreset_declare_preset:nx{ipa}{
+ \__ltjpreset_set_uni:nn { IPAMincho } { IPAGothic }
+}
+\ltjpreset_declare_preset:nx{ipaex}{
+ \__ltjpreset_set_uni:nn { IPAExMincho } { IPAExGothic }
+}
+\ltjpreset_declare_preset:nx{ms}{
+ \__ltjpreset_set_uni:nn { MS-Mincho } { MS-Gothic }
+}
+
+% {ipa,ipaex,ms}-dx % Office 付属フォントを利用
+\ltjpreset_declare_preset:nx{ipaex-hg}{
+ \__ltjpreset_set_office:nn { IPAExMincho } { IPAExGothic }
+}
+\ltjpreset_declare_preset:nx{ipa-hg}{
+ \__ltjpreset_set_office:nn { IPAMincho } { IPAGothic }
+}
+\ltjpreset_declare_preset:nx{ms-hg}{
+ \__ltjpreset_set_office:nn { MS-Mincho } { MS-Gothic }
+}
+
+
+% éžåŸ‹è¾¼
+\ltjpreset_declare_preset:nx{noembed}{
+ \__ltjpreset_set_uni:nn { Ryumin-Light } { GothicBBB-Medium },
+ __custom = false, __office = false, __noembed = true,
+}
+
+\keys_set:nn {luatexja-preset} { ipaex }
+\ProcessKeysOptions { luatexja-preset }
+\@ifpackageloaded{luatexja-fontspec}{
+ \bool_if:NT \g__ltjpreset_nfssonly_bool
+ { \msg_warning:nn { luatexja-preset }{ ltj-fontspec } }
+ \bool_set_false:N \g__ltjpreset_nfssonly_bool
+}{}
+
+%%%%%%%% main routine
+
+\cs_new:Nn \__ltjpreset_extract_fonts: {
+ %% MogaMincho ã®å ´åˆã¯ 90 ã‚’ã¤ã‘ã‚‹/ã¯ãšã™
+ \bool_if:NF \g__ltjpreset_custom_bool {
+ \tl_set:Nn \l_tmpa_tl {, CJKShape=JIS2004 }
+ \tl_if_eq:NNT \l__ltjpreset_kanji_shape_tl \l_tmpa_tl {
+ \tl_set:Nx \l_tmpb_tl { \prop_item:Nn \g__ltjpreset_font_prop { mc-m } }
+ \tl_if_in:NnT \l_tmpb_tl { Moga90Mincho } {
+ \prop_clear:N \l_tmpa_prop
+ \prop_map_inline:Nn \g__ltjpreset_font_prop {
+ \tl_set:Nn \l_tmpb_tl { ##2 } \tl_remove_all:Nn \l_tmpb_tl {90}
+ \prop_put:Nnx \l_tmpa_prop { ##1 } { \tl_use:N \l_tmpb_tl }
+ }
+ \prop_set_eq:NN \g__ltjpreset_font_prop \l_tmpa_prop
+ }
+ \tl_if_in:NnT \l_tmpb_tl { MogaEx90Mincho } {
+ \prop_clear:N \l_tmpa_prop
+ \prop_map_inline:Nn \g__ltjpreset_font_prop {
+ \tl_set:Nn \l_tmpb_tl { ##2 } \tl_remove_all:Nn \l_tmpb_tl {90}
+ \prop_put:Nnx \l_tmpa_prop { ##1 } { \tl_use:N \l_tmpb_tl }
+ }
+ \prop_set_eq:NN \g__ltjpreset_font_prop \l_tmpa_prop
+ }
+ }
+ }
+ %%%% リストã‹ã‚‰ã®å±•é–‹
+ \cs_set:Nx \__ltjpreset_font_mc_l: { \prop_item:Nn \g__ltjpreset_font_prop { mc-l } }
+ \cs_set:Nx \__ltjpreset_font_mc_m: { \prop_item:Nn \g__ltjpreset_font_prop { mc-m } }
+ \cs_set:Nx \__ltjpreset_font_mc_bx: { \prop_item:Nn \g__ltjpreset_font_prop { mc-bx } }
+ \cs_set:Nx \__ltjpreset_font_gt_m: { \prop_item:Nn \g__ltjpreset_font_prop { gt-d } }
+ \cs_set:Nx \__ltjpreset_font_gt_u: { \prop_item:Nn \g__ltjpreset_font_prop { gt-u } }
+ \cs_set:Nx \__ltjpreset_font_gt_bx: { \prop_item:Nn \g__ltjpreset_font_prop { gt-bx } }
+ \cs_set:Nx \__ltjpreset_font_gt_eb: { \prop_item:Nn \g__ltjpreset_font_prop { gt-eb } }
+ \cs_set:Nx \__ltjpreset_font_mg_m: { \prop_item:Nn \g__ltjpreset_font_prop { mg-m } }
+ %% HG 系フォント + JIS2004/90JIS ã®ã¨ãã¯ãƒ•ã‚©ãƒ³ãƒˆåã‚’ç½®æ›
+ \bool_if:nT { !\g__ltjpreset_custom_bool && \g__ltjpreset_office_bool } {
+ \tl_set:Nn \l_tmpa_tl {, CJKShape=JIS2004 }
+ \tl_if_eq:NNT \l__ltjpreset_kanji_shape_tl \l_tmpa_tl {
+ \cs_set:Nx \__ltjpreset_font_mc_bx: { hgrme04.ttc }
+ \cs_set:Nx \__ltjpreset_font_gt_bx: { hgrge04.ttc }
+ \cs_set:Nx \__ltjpreset_font_gt_eb: { hgrsgu04.ttc }
+ \cs_set:Nx \__ltjpreset_font_mg_m: { hgrsmp04.ttf }
+ \cs_set_eq:NN \__ltjpreset_font_gt_m: \__ltjpreset_font_gt_u:
+ % HG ゴシックM ã®ã¨ãã¯ãã†ã¯ã„ã‹ãªã„ã®ã§ 1 ウェイト時ã®ã‚´ã‚·ãƒƒã‚¯ä½“を使ã†
+ }
+ \tl_set:Nn \l_tmpa_tl {, CJKShape=JIS1990 }
+ \tl_if_eq:NNT \l__ltjpreset_kanji_shape_tl \l_tmpa_tl {
+ \cs_set:Nx \__ltjpreset_font_mc_bx: { hgrme.ttc }
+ \cs_set:Nx \__ltjpreset_font_gt_bx: { hgrge.ttc }
+ \cs_set:Nx \__ltjpreset_font_gt_eb: { hgrsgu.ttc }
+ \cs_set:Nx \__ltjpreset_font_mg_m: { hgrsmp.ttf }
+ }
+ }
+ % mc/l
+ \tl_set:Nx \l_tmpa_tl { \__ltjpreset_font_mc_l: }
+ \tl_if_empty:NT \l_tmpa_tl {\tl_set:Nn \l_tmpa_tl {~}}
+ \cs_set:Nx \__ltjpreset_font_mc_l: {
+ \tl_if_blank:nTF \l_tmpa_tl { \__ltjpreset_font_mc_m: } {\tl_use:N \l_tmpa_tl }
+ }
+ %% bold オプションã®å‡¦ç†
+ \bool_if:NTF \g__ltjpreset_deluxe_bool {
+ \bool_if:NT \g__ltjpreset_bold_bool {
+ \cs_set_eq:NN \__ltjpreset_font_mc_bx: \__ltjpreset_font_gt_bx:
+ }
+ }{
+ \bool_if:NTF \g__ltjpreset_bold_bool
+ { \cs_set_eq:NN \__ltjpreset_font_gt_m: \__ltjpreset_font_gt_bx: }
+ { \cs_set_eq:NN \__ltjpreset_font_gt_m: \__ltjpreset_font_gt_u: }
+ \cs_set_eq:NN \__ltjpreset_font_gt_bx: \__ltjpreset_font_gt_m:
+ \cs_set_eq:NN \__ltjpreset_font_mc_bx: \__ltjpreset_font_gt_m:
+ }
+}
+
+%%%%%%%% フォントåã‚’ \l__ltjpreset_font_name: ã«æ ¼ç´
+\clist_new:N \l__ltjpreset_extensions_clist
+\clist_set:Nn \l__ltjpreset_extensions_clist {.otf,.ttf,.OTF,.TTF,.ttc,.TTC}
+\prg_new_conditional:Nnn \__ltjpreset_if_detect_external:n {TF} {
+ \clist_map_inline:Nn \l__ltjpreset_extensions_clist {
+ \bool_set_false:N \l_tmpa_bool
+ \tl_if_in:nnT {#1 <= end_of_string} {##1 <= end_of_string}
+ { \bool_set_true:N \l_tmpa_bool \clist_map_break: }
+ }
+ \bool_if:NTF \l_tmpa_bool \prg_return_true: \prg_return_false:
+}
+\cs_new:Nn \__ltjpreset_wrap_fontname:n {
+ \__ltjpreset_if_detect_external:nTF { #1 }
+ { \cs_set:Nn \l__ltjpreset_font_name: { [#1] } }
+ { \cs_set:Nn \l__ltjpreset_font_name: { "#1" } }
+}
+\cs_generate_variant:Nn \__ltjpreset_wrap_fontname:n { e }
+
+%%%%%%%% 存在判定
+\cs_new:Nn \__ltjpreset_substitute:nnnn {
+ \group_begin:
+ \suppressfontnotfounderror=1
+ \cs_if_exist:cT {ltjpreset_font_#1_#2:} {
+ \__ltjpreset_wrap_fontname:e { \cs:w ltjpreset_font_#1_#2: \cs_end: }
+ \font \g__ltjpreset_font_test: = \l__preset_font_name:\relax
+ \ifx \g__ltjpreset_font_test: \nullfont
+ \msg_warning:nnxxxx { luatexja-preset }{ no-font }
+ { \cs:w ltjpreset_font_#1_#2: \cs_end: }{ #1/#2 }
+ { \cs:w ltjpreset_font_#3_#4: \cs_end: }{ #3/#4 }
+ \cs_gset_eq:cc { ltjpreset_font_#1_#2: } { ltjpreset_font_#3_#4: }
+ \fi
+ } { \cs_gset_eq:cc { ltjpreset_font_#1_#2: } { ltjpreset_font_#3_#4: } }
+ \group_end:
+}
+
+%%%%%%%% deluxe (\mgfamily ã¯ã‚ã¨ã§å®šç¾©ï¼‰
+\bool_if:NTF \g__ltjpreset_deluxe_bool {
+ \cs_new:Nn \__ltjpreset_check_deluxe_existence: {
+ \__ltjpreset_substitute:nnnn { gt } { eb } { gt } { bx }
+ \__ltjpreset_substitute:nnnn { mg } { m } { gt } { bx }
+ \__ltjpreset_substitute:nnnn { mc } { l } { mc } { m }
+ }
+ \def\ltdefault{l}
+ \DeclareRobustCommand\ltseries { \not@math@alphabet\ltseries\relax\fontseries\ltdefault\selectfont }
+ \def\ebdefault{eb}
+ \DeclareRobustCommand\ebseries { \not@math@alphabet\ebseries\relax\fontseries\ebdefault\selectfont }
+ \DeclareRobustCommand\gtebfamily { \gtfamily\fontseries{\ebdefault}\selectfont }
+} {
+ \cs_set_eq:NN \__ltjpreset_check_deluxe_existence: \prg_do_nothing:
+}
+
+\int_new:N \g__ltjpreset_applycount_int
+
+\bool_if:NTF \g__ltjpreset_nfssonly_bool {
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%% nfss only
+ \cs_if_exist:NF \Cjascale {
+ \group_begin:
+ \fontsize{16}{16}\selectfont
+ \cs_gset:Npx \Cjascale { \fp_to_decimal:n {\zw / 16} }
+ \group_end:
+ }
+
+ \msg_warning:nnx { luatexja-preset }{ scale }{ \Cjascale }
+
+ % {1: encoding}{2: family}{3: series}{4: shape}{5: fontname}{6: feature}{7: scale}
+ \cs_new:Nn \__ltjpreset_declare_font_shape:nnnnnnn {
+ \DeclareFontShape{#1}{#2}{#3}{#4}{ <-> s*[#7]
+ \bool_if:NT \g__ltjpreset_noembed_bool {psft:} #5
+ ;-kern \tl_use:N \l__ltjpreset_kanji_shape_tl; #6 } {}
+ }
+ \cs_new:Nn \__ltjpreset_define_family:nnn {
+ \__ltjpreset_wrap_fontname:e { #3 }
+ \__ltjpreset_declare_font_shape:nnnnnnn { JY3 }
+ { ltjp #1 \int_to_arabic:n { \g__ltjpreset_applycount_int }} { #2 } { n }
+ { \l__ltjpreset_font_name: : jfm=\tl_use:N \__ltjpreset_use_jfm_yoko_tl }
+ { script=hani \bool_if:NT \g__ltjpreset_expert_bool { ;+hkna } }
+ { \Cjascale }
+ \__ltjpreset_declare_font_shape:nnnnnnn { JT3 }
+ { ltjp #1 \int_to_arabic:n { \g__ltjpreset_applycount_int }} { #2 } { n }
+ { \l__ltjpreset_font_name: : jfm=\tl_use:N \__ltjpreset_use_jfm_tate_tl }
+ { script=hani \bool_if:NT \g__ltjpreset_expert_bool { ;+vkna } }
+ { \Cjascale }
+ \bool_if:NT \g__ltjpreset_expert_bool {
+ \__ltjpreset_declare_font_shape:nnnnnnn { JY3 }
+ { ltjp #1 \int_to_arabic:n { \g__ltjpreset_applycount_int }} { #2 } { rb }
+ { \l__ltjpreset_font_name: : jfm=\tl_use:N \__ltjpreset_use_jfm_yoko_tl } { script=kana; +ruby }
+ { \Cjascale }
+ \__ltjpreset_declare_font_shape:nnnnnnn { JT3 }
+ { ltjp #1 \int_to_arabic:n { \g__ltjpreset_applycount_int }} { #2 } { rb }
+ { \l__ltjpreset_font_name: : jfm=\tl_use:N \__ltjpreset_use_jfm_tate_tl } { script=kana; +ruby }
+ { \Cjascale }
+ }
+ \cs_if_exist:NT \ltjpreset_define_family_hook_nfssonly:nnn
+ { \ltjpreset_define_family_hook_nfssonly:nnn { #1 } { #2 } { #3 } }
+ }
+ \bool_if:NT \g__ltjpreset_deluxe_bool {
+ \let\mgfamily\undefined
+ \DeclareRobustCommand\mgfamily {
+ \not@math@alphabet\mgfamily\relax
+ \kanjifamily{ltjpmg \int_to_arabic:n { \g__ltjpreset_applycount_int }}\selectfont
+ }
+ \DeclareTextFontCommand{\textmg}{\mgfamily}
+ }
+ \bool_if:NT \g__ltjpreset_expert_bool {
+ \DeclareRobustCommand\rubyfamily { \kanjishape{rb}\selectfont }
+ }
+ %
+ \cs_new:Nn \__ltjpreset_do_fontset: { \group_begin:
+ % ======
+ \xdef\mcdefault{ltjpmc \int_to_arabic:n { \g__ltjpreset_applycount_int }}
+ \xdef\gtdefault{ltjpgt \int_to_arabic:n { \g__ltjpreset_applycount_int }}
+ \DeclareKanjiFamily{JY3}{\mcdefault}{}
+ \DeclareKanjiFamily{JT3}{\mcdefault}{}
+ \DeclareKanjiFamily{JY3}{\gtdefault}{}
+ \DeclareKanjiFamily{JT3}{\gtdefault}{}
+ \unless\ifltj@disablejfam
+ \SetSymbolFont{mincho}{normal}{JY3}{\mcdefault}{m}{n}
+ \SetSymbolFont{mincho}{bold}{JY3}{\mcdefault}{bx}{n}
+ \DeclareMathAlphabet{\mathgt}{JY3}{\gtdefault}{m}{n}
+ \fi
+ \bool_if:NT \g__ltjpreset_deluxe_bool {
+ \DeclareKanjiFamily{JY3}{ltjpmg \int_to_arabic:n { \g__ltjpreset_applycount_int }}{}
+ \DeclareKanjiFamily{JT3}{ltjpmg \int_to_arabic:n { \g__ltjpreset_applycount_int }}{}
+ }
+ % ======
+ \tl_set:Nn \l_tmpa_tl {, CJKShape=JIS1990 }
+ \tl_if_eq:NNT \l__ltjpreset_kanji_shape_tl \l_tmpa_tl {
+ \tl_set:Nn \l__ltjpreset_kanji_shape_tl { ;+jp90 }
+ }
+ \tl_set:Nn \l_tmpa_tl {, CJKShape=JIS2004 }
+ \tl_if_eq:NNT \l__ltjpreset_kanji_shape_tl \l_tmpa_tl {
+ \tl_set:Nx \l__ltjpreset_kanji_shape_tl { ;+jp04 }
+ }
+ \__ltjpreset_define_family:nnn {mc} {m} {\__ltjpreset_font_mc_m:}
+ \__ltjpreset_define_family:nnn {mc} {bx} {\__ltjpreset_font_mc_bx:}
+ \__ltjpreset_define_family:nnn {mc} {b} {\__ltjpreset_font_mc_bx:}
+ \__ltjpreset_define_family:nnn {gt} {m} {\__ltjpreset_font_gt_m:}
+ \__ltjpreset_define_family:nnn {gt} {bx} {\__ltjpreset_font_gt_bx:}
+ \__ltjpreset_define_family:nnn {gt} {b} {\__ltjpreset_font_gt_bx:}
+ \normalfont
+ \bool_if:NT \g__ltjpreset_deluxe_bool {
+ \__ltjpreset_define_family:nnn {mc} {l} {\__ltjpreset_font_mc_l:}
+ \__ltjpreset_define_family:nnn {gt} {eb} {\__ltjpreset_font_gt_eb:}
+ \__ltjpreset_define_family:nnn {mg} {m} {\__ltjpreset_font_mg_m:}
+ }
+ \group_end:
+ }
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%% fontspec
+} {
+ \RequirePackage{luatexja-fontspec}
+ % scale
+ \msg_warning:nnx { luatexja-preset }{ scale }{ \Cjascale }
+ \tl_new:N \l__ltjpreset_add_features_tl
+
+ \bool_if:NT \g__ltjpreset_expert_bool {
+ \cs_set:Npn \rubyfamily { \addjfontfeatures {
+ Style=Ruby , YokoFeatures={RawFeature=-hkna} , TateFeatures={RawFeature=-vkna}
+ } }
+ }
+ \addjfontfeature{ Kerning=Off }
+ % 実際㮠fontspec ã®å‘¼ã³ã ã—
+ \cs_new:Nn \__ltjpreset_do_fontset: { \group_begin:
+ \tl_gset:Nx \l__ltjpreset_add_features_tl {
+ \tl_use:N \l__ltjpreset_kanji_shape_tl,
+ YokoFeatures = { JFM = \tl_use:N \__ltjpreset_use_jfm_yoko_tl },
+ TateFeatures = { JFM = \tl_use:N \__ltjpreset_use_jfm_tate_tl },
+ Script=CJK, \bool_if:NT \g__ltjpreset_noembed_bool { , NoEmbed }
+ }
+ \group_end:
+ \bool_if:NT \g__ltjpreset_expert_bool {
+ \tl_put_left:Nn \l__ltjpreset_add_features_tl {
+ , YokoFeatures = {Style = HorizontalKana}, TateFeatures = {Style = VerticalKana}
+ }
+ }
+ \setmainjfont [
+ \bool_if:NT \g__ltjpreset_deluxe_bool {
+ FontFace={l}{n}{ Font = \__ltjpreset_font_mc_l:,
+ \cs_if_exist:NT \ltjpreset_define_family_hook_fontspec:nnn {
+ \ltjpreset_define_family_hook_fontspec:nnn
+ { mc } { l } { \__ltjpreset_font_mc_l: }
+ }
+ },
+ }
+ BoldFont = \__ltjpreset_font_mc_bx: \tl_use:N \l__ltjpreset_add_features_tl,
+ \cs_if_exist:NT \ltjpreset_define_family_hook_fontspec:nnn {
+ UprightFeatures = { \ltjpreset_define_family_hook_fontspec:nnn
+ { mc } { m } { \__ltjpreset_font_mc_m: } },
+ BoldFeatures = { \ltjpreset_define_family_hook_fontspec:nnn
+ { mc } { bx } { \__ltjpreset_font_mc_bx: } },
+ }
+ ] { \__ltjpreset_font_mc_m: }
+ \setsansjfont [
+ \bool_if:NT \g__ltjpreset_deluxe_bool {
+ FontFace={eb}{n}{ Font = \__ltjpreset_font_gt_eb:,
+ \cs_if_exist:NT \ltjpreset_define_family_hook_fontspec:nnn {
+ \ltjpreset_define_family_hook_fontspec:nnn
+ { gt } { eb } { \__ltjpreset_font_gt_eb: }
+ }
+ },
+ }
+ BoldFont = \__ltjpreset_font_gt_bx: \tl_use:N \l__ltjpreset_add_features_tl,
+ \cs_if_exist:NT \ltjpreset_define_family_hook_fontspec:nnn {
+ UprightFeatures = { \ltjpreset_define_family_hook_fontspec:nnn
+ { gt } { m } { \__ltjpreset_font_gt_m: } },
+ BoldFeatures = { \ltjpreset_define_family_hook_fontspec:nnn
+ { gt } { bx } { \__ltjpreset_font_gt_bx: } },
+ }
+ ] { \__ltjpreset_font_gt_m: }
+ \bool_if:NT \g__ltjpreset_deluxe_bool {
+ %% mg
+ \bool_if_exist:NTF \setfontfamily {
+ \setjfontfamily \mgfamily [
+ BoldFont = \__ltjpreset_font_mg_m: \tl_use:N \l__ltjpreset_add_features_tl,
+ \cs_if_exist:NT \ltjpreset_define_family_hook_fontspec:nnn {
+ \ltjpreset_define_family_hook_fontspec:nnn
+ { mg } { m } { \__ltjpreset_font_mg_m: },
+ }
+ ] { \__ltjpreset_font_mg_m: }
+ } {
+ \newjfontfamily \mgfamily [
+ BoldFont = \__ltjpreset_font_mg_m: \tl_use:N \l__ltjpreset_add_features_tl,
+ \cs_if_exist:NT \ltjpreset_define_family_hook_fontspec:nnn {
+ \ltjpreset_define_family_hook_fontspec:nnn
+ { mg } { m } { \__ltjpreset_font_mg_m: },
+ }
+ ] { \__ltjpreset_font_mg_m: }
+ }
+ \DeclareTextFontCommand{\textmg}{\mgfamily}
+ }
+ }
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+}
+
+\def\ltjnewpreset{
+ \@ifstar{\__ltjpreset_new_preset:nnn{ true }}{\__ltjpreset_new_preset:nnn{ false }}}
+\cs_set:Nn \__ltjpreset_new_preset:nnn {
+ \keys_if_exist:nnTF { luatexja-preset } { #2 } {
+ \seq_if_in:NnTF \g__ltjpreset_presets_seq { #2 } {
+ \bool_if:cTF { c_ #1 _bool } {
+ \msg_warning:nnn { luatexja-preset }{ exist-preset-overwrite } { #2 }
+ \keys_define:nn { luatexja-preset } {
+ #2 .meta:n = { #3, __custom = true, __noembed = false, __office = false, },
+ #2 .value_forbidden:n = true, #2 .groups:n = { preset },
+ }
+ } {
+ \msg_error:nnn { luatexja-preset }{ exist-preset-nooverwrite } { #2 }
+ }
+ } {
+ \msg_error:nnn { luatexja-preset }{ illegal-preset-name } { #2 }
+ }
+ } {
+ \keys_define:nn { luatexja-preset } {
+ #2 .meta:n = { #3, __custom = true, __noembed = false, __office = false, },
+ #2 .value_forbidden:n = true, #2 .groups:n = { preset },
+ }
+ \seq_put_right:Nn \g__ltjpreset_presets_seq { #2 }
+ }
+}
+
+
+\cs_set:Npn \ltjapplypreset #1 {
+ \int_gincr:N \g__ltjpreset_applycount_int
+ \keys_set_groups:nnn { luatexja-preset } { preset } { #1 }
+ % \prop_map_inline:Nn \g__ltjpreset_font_prop {\typeout{ [##1] = "##2" } }
+ \__ltjpreset_extract_fonts:
+ \__ltjpreset_check_deluxe_existence:
+ \__ltjpreset_do_fontset:
+ \normalfont
+}
+
+\ltjapplypreset {}
+
+\@onlypreamble\ltjnewpreset
+\@onlypreamble\ltjapplypreset
+
+\ExplSyntaxOff
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-ruby.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-ruby.sty
new file mode 100644
index 0000000000..813ab31a43
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-ruby.sty
@@ -0,0 +1,210 @@
+%
+% luatexja-ruby.sty
+%
+
+% LaTeX only!
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{luatexja-ruby}[2017/05/05 v0.23]
+\RequirePackage{luatexja}
+
+%%------------------
+\newattribute\ltj@rubyattr
+\ltj@rubyattr=0
+\RequireLuaTeXjaSubmodule{ruby}
+
+% ltjset/getparameter ã¸ã®è¿½åŠ è¨­å®š
+% ã“れらã¯æ®µè½å˜ä½ã®è¨­å®šï¼Ž
+
+%% 引数:ルビ全角をå˜ä½ã¨ã—ãŸå®Ÿæ•°
+%% ã“ã®æ–‡å­—ã¸ã® pre-, post-intrusion ã®è¨±å®¹é‡
+\define@key[ltj]{japaram}{rubypreintrusion}{%
+ \ltj@@set@stack@real{RIPRE}{0}{0x7FFFFFFF}#1 }
+\define@key[ltj]{japaram}{rubypostintrusion}{%
+ \ltj@@set@stack@real{RIPOST}{0}{0x7FFFFFFF}#1 }
+\def\ltj@@set@stack@real#1#2#3{%
+ \directlua{luatexja.stack.set_stack_perchar(luatexja.stack_table_index.#1,
+ #2, #3, token.scan_word)}}
+
+% ルビ用ã®ã‚­ãƒ¼è¨­å®š
+\def\ltj@@rkeydef#1{
+ \define@key[ltj]{ruby}{#1}{\expandafter\def\csname ltj@@rubyip@#1\endcsname{##1}}
+}
+%% attr_ruby_mode
+%% bit 0: intrusion を有効ã«ã™ã‚‹ã‹ï¼ˆ1: 有効)
+%% bit 1: å‰å¾Œã® intrusion 許容é‡ã‚’å°ã•ã„æ–¹ã«æƒãˆã‚‹ (1: yes)
+%% bit 2, 3: intrusion ã‚’ã©ã†ä½¿ã£ã¦è¦ªæ–‡å­—ã‚’é…ç½®ã™ã‚‹ã‹
+%% 00: intrusion ãªã—ã§ã¨ã‚Šã‚ãˆãšè¨ˆç®—ã—,左å³ã®çªå‡ºåˆ†ã‚’進入ã«å‰²ã‚Šå½“ã¦ã‚‹
+%% 01: pre-intrusion ã§ã¾ã‹ãªãˆã‚‹ã ã‘ã¾ã‹ãªã„,無ç†ãªã‚‰ post- も使ã†
+%% 10: post を優先
+%% 11: 2 min (pre,post) ã¾ã§ã¯ pre, post ã«å‡ç­‰é…分ã—よã†ã¨ã™ã‚‹
+%% >=01 ã§ï¼Œintrusion ã§è³„ãˆãã‚Œãªã‹ã£ãŸå ´åˆã¯ã„ã¤ã‚‚ã®ã‚ˆã†ã«ä¼¸é•·ã™ã‚‹ï¼Ž
+%% bit 4: 熟語ルビã®éš›ã®å‡¦ç†æ–¹æ³•ï¼ˆ0: 常ã«ã‚°ãƒ«ãƒ¼ãƒ—,1: å¯èƒ½ãªé™ã‚Šãƒ–ロックã”ã¨ã«ï¼‰
+%% ↑bit 4 ã¯ä»Šã¯ç„¡åŠ¹
+\ltj@@rkeydef{mode}
+%% intrusion é‡å¼·åˆ¶å›ºå®šï¼ˆbit 0, bit 1 より優先,負数ã§ã€Œè‡ªå‹•ã€ï¼‰
+%% attr 㯠sp å˜ä½ã ãŒï¼Œãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ãƒ«ãƒ“全角å˜ä½ã§æŒ‡å®šã™ã‚‹
+%% attr_ruby_maxprep, attr_ruby_maxpostp
+\ltj@@rkeydef{pre}
+\ltj@@rkeydef{post}
+%% 親文字伸長ã®éš›ã®æ¯”,{0}{1}{1} ãªã©ã¨0--7 ã®æ•° 3 ã¤ã§æŒ‡å®š
+%% attr_ruby_stretch (bol left,middle,right)(eol)(middle) 27-bits
+\ltj@@rkeydef{stretchbol} % 行頭形
+\ltj@@rkeydef{stretcheol} % 行末形
+\ltj@@rkeydef{stretch} % 行中形
+%% ルビãŒä¼¸é•·ã™ã‚‹ã¨ãã®æ¯” {1}{2}{1} ãªã©ã¨0--7 ã®æ•° 3 ã¤ã§æŒ‡å®š
+%% attr_ruby_mode 上ä½éƒ¨åˆ†
+\ltj@@rkeydef{stretchruby}
+%% ルビ<親ã®ã¨ã,ルビã¨è¦ªæ–‡å­—ã®ç«¯ã®æœ€å¤§å€¤
+%% attr_ruby_maxmargin
+%% attr 㯠sp å˜ä½ã ãŒï¼Œãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯è¦ªæ–‡å­—全角å˜ä½ã§æŒ‡å®š
+\ltj@@rkeydef{maxmargin}
+%% ルビã¨è¦ªæ–‡å­—ã®åž‚ç›´æ–¹å‘ã®ç©ºã
+%% attr_ruby_intergap
+%% attr 㯠sp å˜ä½ã ãŒï¼Œãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯è¦ªæ–‡å­—全角å˜ä½ã§æŒ‡å®š
+\ltj@@rkeydef{intergap}
+
+\ltj@@rkeydef{kenten}%% åœç‚¹æ–‡å­—
+\ltj@@rkeydef{fontcmd}%% フォント
+\define@boolkey[ltj]{ruby}{rubysmash}[true]{}
+
+
+%%%%%%%% setkeys ã®åˆ¥å
+\protected\def\ltjsetruby{\setkeys[ltj]{ruby}}
+
+% ã“ã“ã‹ã‚‰ã¯ ruby マクロ内ã§ãªã‚“ã¨ã‹ã•ã‚Œã‚‹äº‹é …
+%% ルビã¨è¦ªæ–‡å­—ã®å¤§ãã•ã®æ¯”
+\ltj@@rkeydef{size}
+
+% 中ã¤ã用簡易設定.
+\define@key[ltj]{ruby}{naka}[none]{\setkeys[ltj]{ruby}{mode=1, stretch=121, stretchruby=121}}
+% è‚©ã¤ã用簡易設定.
+\define@key[ltj]{ruby}{kata}[none]{\setkeys[ltj]{ruby}{mode=9, stretch=121, stretchruby=001}}
+
+%%%%%%%% 補助関数
+
+% Lua ソースã«æ¸¡ã™ table 生æˆ
+\def\ltj@@ruby@create@table#1{% #1: ルビ全角
+ \string{
+ rubyzw = \ltj@safe@dimen{#1},
+ maxmargin = \ltj@safe@dimen{\ltj@@rubyip@maxmargin\zw},
+ pre = \ltj@safe@dimen{\ltj@@rubyip@pre#1},
+ post = \ltj@safe@dimen{\ltj@@rubyip@post#1},
+ intergap = \ltj@safe@dimen{\ltj@@rubyip@intergap\zw},
+ stretch
+ = 262144 * \expandafter\ltj@@ruby@cts\ltj@@rubyip@stretchbol
+ + 512 * \expandafter\ltj@@ruby@cts\ltj@@rubyip@stretcheol
+ + \expandafter\ltj@@ruby@cts\ltj@@rubyip@stretch,
+ mode
+ = 2097152 * \expandafter\ltj@@ruby@cts\ltj@@rubyip@stretchruby
+ + \ltj@safe@num{\ltj@@rubyip@mode}
+ + 1048576 * \ifltj@ruby@rubysmash1\else0\fi
+ \string}
+}
+%%%
+%%% 1098765432109876543210976543210
+%%% |st_ruby|! |--| ↠mode
+\def\ltj@@ruby@cts#1#2#3{%
+ ((\ltj@safe@num{#1}) * 64 + (\ltj@safe@num{#2}) * 8 + \ltj@safe@num{#3})%
+}
+
+
+%%%%%%%% ZR ã•ã‚“ã® PXrubrica パッケージ中ã®ã‚³ãƒ¼ãƒ‰ã‹ã‚‰å¼•ç”¨ãƒ»æ”¹å¤‰
+% \pxrr@decompbar: a|bc -> \ltj@@ruby@mark{a}\ltj@@ruby@mark{bc}
+\let\pxrr@res\empty
+\def\pxrr@ifx#1{%
+ \ifx#1\expandafter\@firstoftwo
+ \else\expandafter\@secondoftwo
+ \fi
+}
+\def\pxrr@nil{\noexpand\pxrr@nil}
+\def\pxrr@end{\noexpand\pxrr@end}
+\def\pxrr@appto#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+\def\pxrr@decompbar#1{%
+ \let\pxrr@res\@empty
+ \pxrr@decompbar@loopa\pxrr@nil#1|\pxrr@end|%
+}
+\def\pxrr@decompbar@loopa#1|{%
+ \expandafter\pxrr@decompbar@loopb\expandafter{\@gobble#1}%
+}
+\def\pxrr@decompbar@loopb#1{%
+ \pxrr@decompbar@loopc#1\relax\pxrr@nil{#1}%
+}
+\def\pxrr@decompbar@loopc#1#2\pxrr@nil#3{%
+ \pxrr@ifx{#1\pxrr@end}{}{%
+ \ifx\pxrr@res\@empty
+ \def\pxrr@res{\ltj@@ruby@mark}%
+ \else
+ \pxrr@appto\pxrr@res{\ltj@@ruby@mark}%
+ \fi
+ \pxrr@appto\pxrr@res{{#3}}%
+ \pxrr@decompbar@loopa\pxrr@nil
+ }%
+}
+%%%%%%%% ã“ã“ã¾ã§
+
+%%%%%%%% TeX command
+\protected\def\ltjruby{\@ifnextchar[\ltj@@ruby{\ltj@@ruby[]}}%]
+\AtBeginDocument{%
+ \ifdefined\ruby\else\let\ruby=\ltjruby\fi
+ \directlua{luatexja.ruby.read_old_break_info()}%
+}
+\def\ltj@@ruby[#1]#2#3{{% #1: option #2: 親文字群,#3: ルビ文字列群,共ã«| 区切り
+ \setkeys[ltj]{ruby}{#1}%
+ \directlua{ruby_tmplist_r = \string{\string}; ruby_tmplist_p = \string{\string}}%
+ \leavevmode\dimen0=\f@size pt\dimen1=\ltj@@rubyip@size\dimen0%
+ % 引数展開,テーブルã«ã‚»ãƒƒãƒˆ
+ \pxrr@decompbar{#2}{\let\ltj@@ruby@mark\ltj@@ruby@sp\pxrr@res}%
+ \pxrr@decompbar{#3}{\let\ltj@@ruby@mark\ltj@@ruby@sr\pxrr@res}%
+ {\fontsize{\ltj@@rubyip@size\dimen0}\z@\selectfont\ltj@@rubyip@fontcmd\global\dimen1=\zw}%
+ \directlua{%
+ luatexja.ruby.texiface(\ltj@@ruby@create@table{\dimen1},
+ ruby_tmplist_r, ruby_tmplist_p)}%
+}}
+
+\def\ltj@@ruby@sr#1{%
+ \setbox0=\hbox{\fontsize{\dimen1}\z@\ltj@@rubyip@fontcmd\selectfont#1}%
+ \directlua{table.insert(ruby_tmplist_r, luatexja.ruby.cpbox())}%
+}
+\def\ltj@@ruby@sp#1{%
+ \setbox0=\hbox{\selectfont#1}%
+ \directlua{table.insert(ruby_tmplist_p, luatexja.ruby.cpbox())}%
+}
+
+\protected\def\ltjkenten{\@ifnextchar[\ltj@@kenten{\ltj@@kenten[]}}%]
+\let\kenten=\ltjkenten
+\def\ltj@@kenten[#1]#2{{%
+ \setkeys[ltj]{ruby}{#1, stretchruby=101}%
+ \@tfor\ltj@@kenten@temp:=#2\do{\ltj@@ruby[]{\ltj@@kenten@temp}{\ltj@@rubyip@kenten}}%
+}}
+
+% åˆæœŸå€¤ï¼Žè¦èª¿æ•´
+%% ã²ã‚‰ãŒãª
+\count@="3040\loop\relax\ifnum \count@<"30A0
+ \ltjsetparameter{rubypreintrusion={\the\count@,1},
+ rubypostintrusion={\the\count@,1}}
+ \advance\count@1\repeat
+%% 「ã€
+\ltjsetparameter{rubypreintrusion={`「,1},
+ rubypostintrusion={`ã€,1}}
+%% ,ã€
+\ltjsetparameter{rubypreintrusion={`,,1},
+ rubypostintrusion={`,,1}}
+\ltjsetparameter{rubypreintrusion={`ã€,1},
+ rubypostintrusion={`ã€,1}}
+%% ・
+\ltjsetparameter{rubypreintrusion={`・,1},
+ rubypostintrusion={`・,1}}
+%% 段è½ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆéƒ¨åˆ†
+\ltjsetparameter{rubypreintrusion={-1,1}}
+
+\setkeys[ltj]{ruby}{
+ pre=-1, post=-1, mode=1,
+ stretchruby={1}{2}{1}, stretch = {1}{2}{1},
+ stretchbol={0}{1}{1}, stretcheol={1}{1}{0},
+ maxmargin=0.5, size=0.5, intergap=0, rubysmash=false,
+ kenten=\ltjalchar`•, fontcmd=\relax
+}
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-zhfonts.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-zhfonts.sty
new file mode 100644
index 0000000000..8e215d3f6e
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-zhfonts.sty
@@ -0,0 +1,77 @@
+% luatexja-zhfonts.sty
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{luatexja-zhfonts}[2013/09/10 Setting for Chinese fonts]
+\RequirePackage{luatexja-fontspec}
+
+% SinoType åŽæ–‡å­—体
+\DeclareOption{SinoType}{
+\setmainjfont[BoldFont=STZhongsong]{STSong}
+\setsansjfont[BoldFont=STXihei]{STXihei}
+\newjfontface\kai{STKaiti}
+\newjfontface\fang{STFangsong}
+}
+
+% ZhongYi 中易字体
+\DeclareOption{ZhongYi}{
+\setmainjfont[BoldFont=SimHei]{SimSun}
+\setsansjfont[BoldFont=SimHei]{SimHei}
+\newjfontface\kai{KaiTi}
+\newjfontface\fang{FangSong}
+}
+
+% Adobe Adobe字体
+\DeclareOption{Adobe}{
+\setmainjfont[BoldFont=AdobeHeitiStd-Regular]{AdobeSongStd-Light}
+\setsansjfont[BoldFont=AdobeHeitiStd-Regular]{AdobeHeitiStd-Regular}
+\newjfontface\kai{AdobeKaitiStd-Regular}
+\newjfontface\fang{AdobeFangsongStd-Regular}
+}
+
+% Founder 方正字体
+\DeclareOption{Founder}{
+\setmainjfont[BoldFont=FZXiaoBiaoSong-B05]{FZShuSong-Z01}
+\setsansjfont[BoldFont=FZHei-B01]{FZHei-B01}
+\newjfontface\kai{FZKai-Z03}
+\newjfontface\fang{FZFangSong-Z02}
+}
+
+% HanYi-J 汉仪字体-文房字å®-简体
+% HanYi-F 汉仪字体-文房字å®-ç¹ä½“
+% 书宋一简 HYA9GJM.ttf
+% 中宋简  HYA3GJM.ttf
+% 中黑简  HYB1GJM.ttf
+% 粗黑简  HYB9GJM.ttf
+% 楷体简  HYC1GJM.ttf
+% 仿宋简  HYD1GJM.ttf
+\DeclareOption{HanYi-J}{
+\setmainjfont[BoldFont=HYA9GJM.ttf]{HYA3GJM.ttf}
+\setsansjfont[BoldFont=HYB9GJM.ttf]{HYB1GJM.ttf}
+\newjfontface\kai{HYC1GJM.ttf}
+\newjfontface\fang{HYD1GJM.ttf}
+}
+
+\DeclareOption{HanYi-F}{
+\setmainjfont[BoldFont=HYA9GFM.ttf]{HYA3GFM.ttf}
+\setsansjfont[BoldFont=HYB9GFM.ttf]{HYB1GFM.ttf}
+\newjfontface\kai{HYC1GFM.ttf}
+\newjfontface\fang{HYD1GFM.ttf}
+}
+
+% cwTeX TrueType (in Debian/Ubuntu)
+\DeclareOption{cwttf}{
+\setmainjfont[BoldFont=cwTeXHeiBold]{cwTeXMing}
+\setsansjfont[BoldFont=cwTeXHeiBold]{cwTeXHeiBold}
+\newjfontface\kai{cwTeXKai}
+\newjfontface\fang{cwTeXFangSong}
+}
+
+% Fandol fonts http://fandol-doc.googlecode.com/files/fandol-fonts.7z
+\DeclareOption{Fandol}{
+\setmainjfont[BoldFont=FandolSong-Bold]{FandolSong-Regular}
+\setsansjfont[BoldFont=FandolHei-Bold]{FandolHei-Regular}
+\newjfontface\kai{FandolKai-Regular}
+\newjfontface\fang{FandolFang-Regular}
+}
+
+\ProcessOptions\relax
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/jfm-CCT.lua b/macros/luatex/generic/luatexja/src/jfm-CCT.lua
new file mode 100644
index 0000000000..c41f6da311
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/jfm-CCT.lua
@@ -0,0 +1,84 @@
+luatexja.jfont.define_jfm {
+ dir = 'yoko',
+ zw = 1.0, zh = 1.0,
+
+ [0] = {
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.25 , 0.0, 0.0 },
+ [3] = { 0.125, 0.0, 0.125 }
+ }
+ },
+
+ [1] = { -- fw. opening punctuations
+ chars = {
+ 0x2018, 0x201C, 0x3008, 0x300A, 0x300C, 0x300E, 0x3010, 0x3014, 0x3016,
+ 0x3018, 0x301D, 0xFF08, 0xFF3B, 0xFF5B, 0xFF5F
+ },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [3] = { 0.25, 0.0, 0.25 }
+ }
+ },
+
+ [2] = { -- fw. closing/colon punctuations
+ chars = {
+ 0x2019, 0x201D, 0x3001, 0x3009, 0x300B, 0x300D, 0x300F, 0x3011, 0x3015,
+ 0x3017, 0x3019, 0x301F, 0xFF09, 0xFF0C, 0xFF3D, 0xFF5D, 0xFF60,
+ 0xFF1A, 0xFF1B
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.25 , 0.0, 0.0 },
+ [3] = { 0.125, 0.0, 0.0 },
+ [5] = { 0.25 , 0.0, 0.25 }
+ }
+ },
+
+ [3] = { -- fw. middle dot punctuations
+ chars = {0x30FB, 0x00B7},
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.125, 0.0, 0.125 },
+ [1] = { 0.125, 0.0, 0.125 },
+ [2] = { 0.125, 0.0, 0.125 },
+ [3] = { 0.5 , 0.0, 0.5 },
+ [4] = { 0.25, 0.0, 0.25 },
+ [5] = { 0.25, 0.0, 0.25 },
+ }
+ },
+
+ [4] = { -- fw. stop punctuations
+ chars = {0x3002, 0xFF01, 0xFF0E, 0xFF1F},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.5, 0.0, 0.0 },
+ [1] = { 0.5, 0.0, 0.0 },
+ [3] = { 0.5, 0.0, 0.0 },
+ [5] = { 0.5, 0.0, 0.0 }
+ }
+ },
+
+ [5] = { -- fw. dash punctuations
+ chars = { 0x2015, 0x2025, 0x2026, 0x2014, 0x301C, 0xFF5E },
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.25, 0.0, 0.25 }
+ },
+ kern = {
+ [5] = -0.1
+ }
+ },
+
+ [6] = { -- box end
+ chars = {'boxbdd'},
+ },
+
+}
diff --git a/macros/luatex/generic/luatexja/src/jfm-banjiao.lua b/macros/luatex/generic/luatexja/src/jfm-banjiao.lua
new file mode 100644
index 0000000000..783e836ba2
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/jfm-banjiao.lua
@@ -0,0 +1,98 @@
+luatexja.jfont.define_jfm {
+ dir = 'yoko',
+ zw = 1.0, zh = 1.0,
+
+ [0] = {
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ --[1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.125, 0.0, 0.125 }
+ }
+ },
+
+ [1] = { -- fw. opening punctuations
+ chars = {
+ 0x2018, 0x201C, 0x3008, 0x300A, 0x300C, 0x300E, 0x3010, 0x3014, 0x3016,
+ 0x3018, 0x301D, 0xFF08, 0xFF3B, 0xFF5B, 0xFF5F
+ },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [3] = { 0.25, 0.0, 0.25 }
+ }
+ },
+
+ [2] = { -- fw. closing/colon/dot punctuations, except 4 & 7
+ chars = {
+ 0x2019, 0x201D, 0x3009, 0x300B, 0x300D, 0x300F, 0x3011, 0x3015,
+ 0x3017, 0x3019, 0x301F, 0xFF09, 0xFF0C, 0xFF3D, 0xFF5D, 0xFF60,
+ 0xFF0E, 0xFF1A, 0xFF1B, 0xFF01, 0xFF1F
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ --[0] = { 0.5 , 0.0, 0.5 },
+ --[1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.125, 0.0, 0.125 },
+ [5] = { 0.5 , 0.0, 0.5 }
+ }
+ },
+
+ [3] = { -- fw. middle dot punctuations
+ chars = {0x30FB, 0x00B7},
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.125, 0.0, 0.125 },
+ [1] = { 0.125, 0.0, 0.125 },
+ [2] = { 0.125, 0.0, 0.125 },
+ [3] = { 0.5 , 0.0, 0.5 },
+ [4] = { 0.25, 0.0, 0.25 },
+ [5] = { 0.25, 0.0, 0.25 },
+ [7] = { 0.25, 0.0, 0.25 }
+ }
+ },
+
+ [4] = { -- ideographic full stop
+ chars = {0x3002},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ --[0] = { 0.5 , 0.0, 0.0 },
+ [1] = { 0.5 , 0.0, 0.0 },
+ [3] = { 0.75, 0.0, 0.25 },
+ [5] = { 0.5 , 0.0, 0.0 }
+ }
+ },
+
+ [5] = { -- fw. dash punctuations
+ chars = { 0x2015, 0x2025, 0x2026, 0x2014, 0x301C, 0xFF5E },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.25, 0.0, 0.25 }
+ },
+ kern = {
+ [5] = 0.0
+ }
+ },
+
+ [6] = { -- box end
+ chars = {'boxbdd'},
+ },
+
+ [7] = { -- ideographic comma
+ chars = {0x3001},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.5 , 0.0, 0.25 },
+ [1] = { 0.5 , 0.0, 0.25 },
+ [3] = { 0.25, 0.0, 0.25 },
+ [5] = { 0.5 , 0.0, 0.25 }
+ }
+ },
+
+}
diff --git a/macros/luatex/generic/luatexja/src/jfm-jis.lua b/macros/luatex/generic/luatexja/src/jfm-jis.lua
new file mode 100644
index 0000000000..642a2475e5
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/jfm-jis.lua
@@ -0,0 +1,92 @@
+-- -*- coding: utf-8 -*-
+-- jfm-jis.lua: JISフォントメトリック互æ›
+-- Besed on ujis.tfm (a counterpart of jis.tfm for upTeX).
+-- * Do not confuse with jfm-ujis.lua.
+
+local vscale = 0.916443 / 0.962216
+local vht = 0.777588 / 0.962216
+local vdp = 0.138855 / 0.962216
+luatexja.jfont.define_jfm {
+ dir = 'yoko',
+ zw = 1.0, zh = vscale,
+
+ [0] = {
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.25, 0.0, 0.25 }
+ }
+ },
+
+ [1] = { -- é–‹ã括弧類
+ chars = {
+ '‘', '“', '〈', '《', '「', '『', 'ã€', '〔', '〖',
+ '〘', 'ã€', '(', 'ï¼»', 'ï½›', '⦅'
+ },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.5, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [3] = { 0.25, 0.0, 0.25 }
+ }
+ },
+
+ [2] = { -- é–‰ã˜æ‹¬å¼§é¡ž
+ chars = {
+ '’', 'â€', 'ã€', '〉', '》', 'ã€', 'ã€', '】', '〕',
+ '〗', '〙', '〟', ')', ',', 'ï¼½', 'ï½', 'ï½ '
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [0] = { 0.5 , 0.0, 0.5 },
+ [1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.25, 0.0, 0.25 },
+ [5] = { 0.5 , 0.0, 0.5 },
+ }
+ },
+
+ [3] = { -- 中点類
+ chars = {'・', ':', ';'},
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.5, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [0] = { 0.25, 0.0, 0.25 },
+ [1] = { 0.25, 0.0, 0.25 },
+ [2] = { 0.25, 0.0, 0.25 },
+ [3] = { 0.5 , 0.0, 0.5 },
+ [4] = { 0.25, 0.0, 0.25 },
+ [5] = { 0.25, 0.0, 0.25 },
+ }
+ },
+
+ [4] = { -- å¥ç‚¹é¡ž
+ chars = {'。', '.'},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [0] = { 0.5 , 0.0, 0.0 },
+ [1] = { 0.5 , 0.0, 0.0 },
+ [3] = { 0.75, 0.0, 0.25 },
+ [5] = { 0.5 , 0.0, 0.0 },
+ }
+ },
+
+ [5] = { -- ダッシュ
+ chars = { '―', '‥', '…' },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.25, 0.0, 0.25 }
+ },
+ kern = {
+ [5] = 0.0
+ }
+ },
+
+ [99] = { -- box末尾
+ chars = {'boxbdd', 'parbdd'},
+ },
+
+} \ No newline at end of file
diff --git a/macros/luatex/generic/luatexja/src/jfm-kaiming.lua b/macros/luatex/generic/luatexja/src/jfm-kaiming.lua
new file mode 100644
index 0000000000..cb166ec436
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/jfm-kaiming.lua
@@ -0,0 +1,98 @@
+luatexja.jfont.define_jfm {
+ dir = 'yoko',
+ zw = 1.0, zh = 1.0,
+
+ [0] = {
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ --[1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.125, 0.0, 0.125 }
+ }
+ },
+
+ [1] = { -- fw. opening punctuations
+ chars = {
+ 0x2018, 0x201C, 0x3008, 0x300A, 0x300C, 0x300E, 0x3010, 0x3014, 0x3016,
+ 0x3018, 0x301D, 0xFF08, 0xFF3B, 0xFF5B, 0xFF5F
+ },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [3] = { 0.25, 0.0, 0.25 }
+ }
+ },
+
+ [2] = { -- fw. closing/colon/dot punctuations, except 4 & 7
+ chars = {
+ 0x2019, 0x201D, 0x3009, 0x300B, 0x300D, 0x300F, 0x3011, 0x3015,
+ 0x3017, 0x3019, 0x301F, 0xFF09, 0xFF0C, 0xFF3D, 0xFF5D, 0xFF60,
+ 0xFF0E, 0xFF1A, 0xFF1B
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ --[0] = { 0.5 , 0.0, 0.5 },
+ --[1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.125, 0.0, 0.125 },
+ [5] = { 0.5 , 0.0, 0.5 }
+ }
+ },
+
+ [3] = { -- fw. middle dot punctuations
+ chars = {0x30FB, 0x00B7},
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.125, 0.0, 0.125 },
+ [1] = { 0.125, 0.0, 0.125 },
+ [2] = { 0.125, 0.0, 0.125 },
+ [3] = { 0.5 , 0.0, 0.5 },
+ [4] = { 0.25, 0.0, 0.25 },
+ [5] = { 0.25, 0.0, 0.25 },
+ [7] = { 0.25, 0.0, 0.25 }
+ }
+ },
+
+ [4] = { -- ideographic full stop
+ chars = {0x3002, 0xFF1F, 0xFF01},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.5 , 0.0, 0.0 },
+ [1] = { 0.5 , 0.0, 0.0 },
+ [3] = { 0.75, 0.0, 0.25 },
+ [5] = { 0.5 , 0.0, 0.0 }
+ }
+ },
+
+ [5] = { -- fw. dash punctuations
+ chars = { 0x2015, 0x2025, 0x2026, 0x2014, 0x301C, 0xFF5E },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.25, 0.0, 0.25 }
+ },
+ kern = {
+ [5] = 0.0
+ }
+ },
+
+ [6] = { -- box end
+ chars = {'boxbdd'},
+ },
+
+ [7] = { -- ideographic comma
+ chars = {0x3001},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.5 , 0.0, 0.25 },
+ [1] = { 0.5 , 0.0, 0.25 },
+ [3] = { 0.25, 0.0, 0.25 },
+ [5] = { 0.5 , 0.0, 0.25 }
+ }
+ },
+
+}
diff --git a/macros/luatex/generic/luatexja/src/jfm-min.lua b/macros/luatex/generic/luatexja/src/jfm-min.lua
new file mode 100644
index 0000000000..b59b5329c4
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/jfm-min.lua
@@ -0,0 +1,261 @@
+-- -*- coding: utf-8 -*-
+-- jfm-min.lua: min10 互æ›
+-- Based on umin10.tfm (a counterpart of min10.tfm for upTeX).
+
+local vscale = 0.916443 / 0.962216
+local vht = 0.777588 / 0.962216
+local vdp = 0.138855 / 0.962216
+
+luatexja.jfont.define_jfm {
+ dir = 'yoko',
+ zw = 1.0, zh = vscale,
+ kanjiskip = { 0.0, 0.091641/0.962216, 0.0 },
+ xkanjiskip = { 0.229101/0.962216, 0.183283/0.962216, 0.114551/0.962216 },
+ [0] = {
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [4] = { 0.316224, 0.0, 0.316224 },
+ [5] = { 0.238097, 0.0, 0.238097 },
+ [3] = { 0.111608, 0.0, 0.111608 },
+ [6] = { 0.476196, 0.0, 0.476196 },
+ }
+ },
+
+ [1] = {
+ chars = {
+ '〉', '》', 'ã€', 'ã€', '】', '〕', '〗', '〙', '〟', ')', 'ï¼½', 'ï½', 'ï½  '
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.523804, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [0] = { 0.476196, 0.0, 0.238097 },
+ [7] = { 0.476196, 0.0, 0.238097 },
+ [12] = { 0.476196, 0.0, 0.238097 },
+ [13] = { 0.476196, 0.0, 0.238097 },
+ [14] = { 0.476196, 0.0, 0.238097 },
+ [10] = { 0.238097, 0.238097, 0.238097 },
+ [2] = { 0.238097, 0.238097, 0.238097 },
+ [4] = { 0.238097, 0.238097, 0.238097 },
+ [5] = { 0.238097, 0.238097, 0.238097 },
+ [3] = { 0.476196, 0.0, 0.238097 },
+ [6] = { 0.476196, 0.0, 0.238097 },
+ [11] = { 0.0, 0.476196, 0.0 },
+ [1] = { 0.0, 0.476196, 0.0 },
+ }
+ },
+
+ [2] = {
+ chars = {
+ '゛', '゜'
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.367552, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [0] = { 0.632447, 0.0, 0.238097 },
+ [7] = { 0.632447, 0.0, 0.238097 },
+ [12] = { 0.632447, 0.0, 0.238097 },
+ [13] = { 0.632447, 0.0, 0.238097 },
+ [14] = { 0.632447, 0.0, 0.238097 },
+ [10] = { 0.0, 0.316224, 0.0 },
+ [2] = { 0.0, 0.316224, 0.0 },
+ [4] = { 0.476196, 0.0, 0.238097 },
+ [5] = { 0.476196, 0.0, 0.238097 },
+ [3] = { 0.476196, 0.0, 0.238097 },
+ [6] = { 0.238097, 0.238097, 0.238097 },
+ }
+ },
+ [3] = {
+ chars = {
+ '∴', '♀', '♂', '〃', '々', 'ã', 'ãƒ', 'ã…', 'ã‡', 'ã‰', 'ã£', 'ゃ', 'ã‚… ',
+ 'ょ', 'ゎ', 'ゕ', 'ゖ', 'ゞ', 'ァ', 'ィ', 'ゥ', 'ェ', 'ォ', 'ッ', 'ャ', 'ュ', 'ョ',
+ 'ヮ', 'ヵ', 'ヶ', 'ㇰ', 'ㇱ', 'ㇲ', 'ㇳ', 'ㇴ', 'ㇵ', 'ㇶ', 'ㇷ', 'ㇸ', 'ㇹ', 'ㇺ',
+ 'ㇻ', 'ㇼ', 'ㇽ', 'ㇾ', 'ㇿ', '$', '¢', '£'
+ },
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.776784, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [0] = { 0.111608, 0.0, 0.111608 },
+ [7] = { 0.111608, 0.0, 0.111608 },
+ [12] = { 0.111608, 0.0, 0.111608 },
+ [13] = { 0.111608, 0.0, 0.111608 },
+ [14] = { 0.111608, 0.0, 0.111608 },
+ [10] = { 0.0, 0.316224, 0.0},
+ [2] = { 0.0, 0.316224, 0.0},
+ [4] = { 0.316224, 0.0, 0.316224 },
+ [5] = { 0.238097, 0.0, 0.238097 },
+ [6] = { 0.476196, 0.0, 0.476196 },
+ [11] = { 0.111608, 0.0, 0.111608 },
+ [1] = { 0.111608, 0.0, 0.111608 },
+ },
+ },
+ [4] = {
+ chars = {
+ '´', 'â€', '‖', '‘', '’', '・', 'ï¼', ':', 'ï¼›', 'ï½€', '|'
+ },
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.367552, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [0] = { 0.316224, 0.0, 0.316224 },
+ [7] = { 0.316224, 0.0, 0.316224 },
+ [12] = { 0.316224, 0.0, 0.316224 },
+ [13] = { 0.316224, 0.0, 0.316224 },
+ [14] = { 0.316224, 0.0, 0.316224 },
+ [10] = { 0.0, 0.316224, 0.0 },
+ [2] = { 0.0, 0.316224, 0.0 },
+ [4] = { 0.0, 0.316224, 0.0 },
+ [5] = { 0.0, 0.316224, 0.0 },
+ [3] = { 0.316224, 0.0, 0.316224 },
+ [6] = { 0.238097, 0.238097, 0.238097 },
+ [11] = { 0.316224, 0.0, 0.316224 },
+ [1] = { 0.316224, 0.0, 0.316224 },
+ }
+ },
+ [5] = {
+ chars = {
+ '§', '¨', '°', '“', 'â€', '′', '″', 'ã‚', 'ヽ', '?', 'ï¼¾'
+ },
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.523804, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [0] = { 0.238097, 0.0, 0.238097 },
+ [7] = { 0.238097, 0.0, 0.238097 },
+ [12] = { 0.238097, 0.0, 0.238097 },
+ [13] = { 0.238097, 0.0, 0.238097 },
+ [14] = { 0.238097, 0.0, 0.238097 },
+ [10] = { 0.0, 0.316224, 0.0 },
+ [2] = { 0.0, 0.316224, 0.0 },
+ [4] = { 0.0, 0.316224, 0.0 },
+ [5] = { 0.0, 0.316224, 0.0 },
+ [3] = { 0.238097, 0.0, 0.238097 },
+ [6] = { 0.238097, 0.238097, 0.238097 },
+ [11] = { 0.238097, 0.0, 0.238097 },
+ [1] = { 0.238097, 0.0, 0.238097 },
+ },
+ },
+ [6] = {
+ chars = {
+ '〈', '《', '「', '『', 'ã€', '〔', '〖', '〘', 'ã€', '(', 'ï¼»', 'ï½›', '⦅'
+ },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.523804, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [4] = { 0.316224, 0.0, 0.316224 },
+ [5] = { 0.238097, 0.0, 0.238097 },
+ [3] = { 0.111608, 0.0, 0.111608 },
+ [6] = { 0.0, 0.476196, 0.0 },
+ },
+ },
+ [7] = {
+ chars = {
+ 'ã†', 'ã', 'ã', 'ã‘', 'ã’', 'ã™', 'ãš', 'ã‚Š', 'テ', 'デ', 'ヤ'
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [4] = { 0.316224, 0.0, 0.316224 },
+ [5] = { 0.238097, 0.0, 0.238097 },
+ [3] = { 0.111608, 0.0, 0.111608 },
+ [6] = { 0.476196, 0.0, 0.238097 },
+ },
+ kern = {
+ [10] = -0.05, [11] = -0.05
+ },
+ },
+
+ [10] = {
+ chars = {
+ ',', '.'
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.367552, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [0] = { 0.632447, 0.0, 0.238097 },
+ [7] = { 0.632447, 0.0, 0.238097 },
+ [12] = { 0.632447, 0.0, 0.238097 },
+ [13] = { 0.632447, 0.0, 0.238097 },
+ [14] = { 0.632447, 0.0, 0.238097 },
+ [10] = { 0.0, 0.316224, 0.0 },
+ [2] = { 0.0, 0.316224, 0.0 },
+ [4] = { 0.476196, 0.0, 0.238097 },
+ [5] = { 0.476196, 0.0, 0.238097 },
+ [3] = { 0.476196, 0.0, 0.238097 },
+ [6] = { 0.238097, 0.238097, 0.238097 },
+ }
+ },
+ [11] = {
+ chars = {
+ 'ã€', '。 '
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.523804, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [0] = { 0.476196, 0.0, 0.238097 },
+ [7] = { 0.476196, 0.0, 0.238097 },
+ [12] = { 0.476196, 0.0, 0.238097 },
+ [13] = { 0.476196, 0.0, 0.238097 },
+ [14] = { 0.476196, 0.0, 0.238097 },
+ [10] = { 0.238097, 0.238097, 0.238097 },
+ [2] = { 0.238097, 0.238097, 0.238097 },
+ [4] = { 0.238097, 0.238097, 0.238097 },
+ [5] = { 0.238097, 0.238097, 0.238097 },
+ [3] = { 0.476196, 0.0, 0.238097 },
+ [6] = { 0.476196, 0.0, 0.238097 },
+ [11] = { 0.0, 0.476196, 0.0 },
+ [1] = { 0.0, 0.476196, 0.0 },
+ }
+ },
+ [12] = {
+ chars = {
+ 'ã‚¢', 'イ', 'ウ', 'オ', 'ケ', 'ゲ', 'サ', 'ザ', 'ソ', 'ゾ', 'ãƒ', 'ヂ', 'ツ',
+ 'ヅ', 'ト', 'ド', 'ナ', 'フ', 'ブ', 'プ', 'ミ', 'メ', 'ラ', 'リ', 'ワ', 'ヲ'
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [4] = { 0.316224, 0.0, 0.316224 },
+ [5] = { 0.238097, 0.0, 0.238097 },
+ [3] = { 0.111608, 0.0, 0.111608 },
+ [6] = { 0.476196, 0.0, 0.238097 },
+ },
+ kern = {
+ [10] = -0.1, [11] = -0.1
+ },
+ },
+ [13] = {
+ chars = {
+ 'ク', 'グ', 'タ', 'ダ'
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [4] = { 0.316224, 0.0, 0.316224 },
+ [5] = { 0.238097, 0.0, 0.238097 },
+ [3] = { 0.111608, 0.0, 0.111608 },
+ [6] = { 0.476196, 0.0, 0.238097 },
+ },
+ kern = {
+ [10] = -0.15, [11] = -0.15
+ },
+ },
+ [14] = {
+ chars = {
+ 'ノ'
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = vht, depth = vdp, italic=0.0,
+ glue = {
+ [4] = { 0.316224, 0.0, 0.316224 },
+ [5] = { 0.238097, 0.0, 0.238097 },
+ [3] = { 0.111608, 0.0, 0.111608 },
+ [6] = { 0.476196, 0.0, 0.238097 },
+ },
+ kern = {
+ [10] = -0.2, [11] = -0.2
+ },
+ },
+
+ [99] = { -- box末尾
+ chars = {'boxbdd', 'parbdd'},
+ },
+}
diff --git a/macros/luatex/generic/luatexja/src/jfm-mono.lua b/macros/luatex/generic/luatexja/src/jfm-mono.lua
new file mode 100644
index 0000000000..185e817182
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/jfm-mono.lua
@@ -0,0 +1,9 @@
+luatexja.jfont.define_jfm {
+ dir = 'yoko',
+ zw = 1.0, zh = 1.0,
+
+ [0] = {
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ }
+} \ No newline at end of file
diff --git a/macros/luatex/generic/luatexja/src/jfm-prop.lua b/macros/luatex/generic/luatexja/src/jfm-prop.lua
new file mode 100644
index 0000000000..71dc1ae694
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/jfm-prop.lua
@@ -0,0 +1,9 @@
+luatexja.jfont.define_jfm {
+ dir = 'yoko',
+ zw = 1.0, zh = 1.0,
+
+ [0] = {
+ align = 'left', left = 0.0, down = 0.0,
+ width = 'prop', height = 0.88, depth = 0.12, italic=0.0,
+ }
+}
diff --git a/macros/luatex/generic/luatexja/src/jfm-propv.lua b/macros/luatex/generic/luatexja/src/jfm-propv.lua
new file mode 100644
index 0000000000..320ed62648
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/jfm-propv.lua
@@ -0,0 +1,9 @@
+luatexja.jfont.define_jfm {
+ dir = 'tate',
+ zw = 1.0, zh = 1.0,
+
+ [0] = {
+ align = 'left', left = 0.0, down = 0.0,
+ width = 'prop', height = 0.50, depth = 0.50, italic=0.0,
+ }
+}
diff --git a/macros/luatex/generic/luatexja/src/jfm-quanjiao.lua b/macros/luatex/generic/luatexja/src/jfm-quanjiao.lua
new file mode 100644
index 0000000000..20590b6a96
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/jfm-quanjiao.lua
@@ -0,0 +1,98 @@
+luatexja.jfont.define_jfm {
+ dir = 'yoko',
+ zw = 1.0, zh = 1.0,
+
+ [0] = {
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.25, 0.0, 0.25 }
+ }
+ },
+
+ [1] = { -- fw. opening punctuations
+ chars = {
+ 0x2018, 0x201C, 0x3008, 0x300A, 0x300C, 0x300E, 0x3010, 0x3014, 0x3016,
+ 0x3018, 0x301D, 0xFF08, 0xFF3B, 0xFF5B, 0xFF5F
+ },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [3] = { 0.25, 0.0, 0.25 }
+ }
+ },
+
+ [2] = { -- fw. closing/colon/dot punctuations, except 4 & 7
+ chars = {
+ 0x2019, 0x201D, 0x3009, 0x300B, 0x300D, 0x300F, 0x3011, 0x3015,
+ 0x3017, 0x3019, 0x301F, 0xFF09, 0xFF0C, 0xFF3D, 0xFF5D, 0xFF60,
+ 0xFF0E, 0xFF1A, 0xFF1B, 0xFF01, 0xFF1F
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.5 , 0.0, 0.5 },
+ [1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.25, 0.0, 0.25 },
+ [5] = { 0.5 , 0.0, 0.5 }
+ }
+ },
+
+ [3] = { -- fw. middle dot punctuations
+ chars = {0x30FB},
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.25, 0.0, 0.25 },
+ [1] = { 0.25, 0.0, 0.25 },
+ [2] = { 0.25, 0.0, 0.25 },
+ [3] = { 0.5 , 0.0, 0.5 },
+ [4] = { 0.25, 0.0, 0.25 },
+ [5] = { 0.25, 0.0, 0.25 },
+ [7] = { 0.25, 0.0, 0.25 }
+ }
+ },
+
+ [4] = { -- ideographic full stop
+ chars = {0x3002},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.5 , 0.0, 0.0 },
+ [1] = { 0.5 , 0.0, 0.0 },
+ [3] = { 0.75, 0.0, 0.25 },
+ [5] = { 0.5 , 0.0, 0.0 }
+ }
+ },
+
+ [5] = { -- fw. dash punctuations
+ chars = { 0x2015, 0x2025, 0x2026, 0x2014, 0x301C, 0xFF5E },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5 },
+ [3] = { 0.25, 0.0, 0.25 }
+ },
+ kern = {
+ [5] = 0.0
+ }
+ },
+
+ [6] = { -- box end
+ chars = {'boxbdd'},
+ },
+
+ [7] = { -- ideographic comma
+ chars = {0x3001},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.5 , 0.0, 0.25 },
+ [1] = { 0.5 , 0.0, 0.25 },
+ [3] = { 0.25, 0.0, 0.25 },
+ [5] = { 0.5 , 0.0, 0.25 }
+ }
+ },
+
+}
diff --git a/macros/luatex/generic/luatexja/src/jfm-tmin.lua b/macros/luatex/generic/luatexja/src/jfm-tmin.lua
new file mode 100644
index 0000000000..2d9f85b59f
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/jfm-tmin.lua
@@ -0,0 +1,189 @@
+-- -*- coding: utf-8 -*-
+-- jfm-tmin.lua: tmin10 互æ›
+-- Based on utmin10.tfm (a counterpart of tmin10.tfm for upTeX).
+
+local vscale = 0.916443 / 0.962216
+local vht = 0.458221 / 0.962216
+
+luatexja.jfont.define_jfm {
+ dir = 'tate',
+ zw = 1.0, zh = vscale,
+ kanjiskip = { 0.0, 0.091641/0.962216, 0.0 },
+ xkanjiskip = { 0.229101/0.962216, 0.183283/0.962216, 0.114551/0.962216 },
+ [0] = {
+ align = 'middle', left = 0.00, down = 0.00,
+ width = 1.0, height = vht, depth = vht, italic=0.0,
+ glue = {
+ [1] = { 0, 0, 0 },
+ [2] = { 0, 0, 0 },
+ [3] = { 0.111608, 0.0, 0.111608 },
+ [5] = { 0, 0, 0 },
+ [6] = { 0.5, 0.190480, 0.5 },
+ [7] = { 0.25, 0.190480, 0.25 },
+ [10] = { 0, 0, 0 },
+ }
+ },
+
+ [1] = {
+ chars = {
+ ',', '.'
+ },
+ align = 'left', left = 0.00, down = 0.00,
+ width = 0.5, height = vht, depth = vht, italic=0.0,
+ glue = {
+ [0] = { 0.5, 0.190480, 0.5 },
+ [1] = { 0, 0, 0 },
+ [2] = { 0, 0, 0 },
+ [3] = { 0.5, 0.190480, 0.5 },
+ [4] = { 0, 0, 0 },
+ [5] = { 0.5, 0.190480, 0.5 },
+ [6] = { 0.5, 0.190480, 0.5 },
+ [7] = { 0.5, 0.190480, 0.5 },
+ [10] = { 0, 0, 0 },
+ }
+ },
+
+ [2] = {
+ chars = {
+ 'ã€', '。'
+ },
+ align = 'left', left = 0.00, down = 0.00,
+ width = 0.5, height = vht, depth = vht, italic=0.0,
+ glue = {
+ [0] = { 0.5, 0.190480, 0.5 },
+ [1] = { 0, 0, 0 },
+ [2] = { 0, 0, 0 },
+ [3] = { 0.5, 0.190480, 0.5 },
+ [4] = { 0, 0, 0 },
+ [5] = { 0.5, 0.190480, 0.5 },
+ [6] = { 0.5, 0.190480, 0.5 },
+ [7] = { 0.5, 0.190480, 0.5 },
+ [10] = { 0, 0, 0 },
+ }
+ },
+
+ [3] = {
+ chars = {
+ '〃', '々', 'ã', 'ãƒ', 'ã…', 'ã‡', 'ã‰', 'ã£', 'ゃ', 'ã‚…',
+ 'ょ', 'ã‚Ž', 'ã‚•', 'ã‚–', 'ã‚', 'ã‚ž', 'ã‚¡', 'ã‚£', 'ã‚¥', 'ェ',
+ 'ォ', 'ッ', 'ャ', 'ュ', 'ョ', 'ヮ', 'ヵ', 'ヶ', 'ヽ', 'ヾ',
+ 'ㇰ', 'ㇱ', 'ㇲ', 'ㇳ', 'ㇴ', 'ㇵ', 'ㇶ', 'ㇷ', 'ㇸ', 'ㇹ',
+ 'ㇺ', 'ㇻ', 'ㇼ', 'ㇽ', 'ㇾ', 'ㇿ',
+ },
+ align = 'middle', left = 0.00, down = 0.00,
+ width = 0.776784, height = vht, depth = vht, italic=0.0,
+ glue = {
+ [0] = { 0.111608, 0.0, 0.111608 },
+ [1] = { 0, 0, 0 },
+ [2] = { 0, 0, 0 },
+ [3] = { 0.111608, 0.0, 0.111608 },
+ [5] = { 0, 0, 0 },
+ [6] = { 0.5, 0.190480, 0.5 },
+ [7] = { 0.25, 0.190480, 0.25 },
+ [10] = { 0, 0, 0 },
+ }
+ },
+
+ [4] = {
+ chars = {
+ 'ï¼', '?'
+ },
+ align = 'middle', left = 0.00, down = 0.00,
+ width = 1.0, height = vht, depth = vht, italic=0.0,
+ glue = {
+ [0] = { 1.0, 0.0, 0.5 },
+ [1] = { 0, 0, 0 },
+ [2] = { 0, 0, 0 },
+ [3] = { 1.0, 0.0, 0.5 },
+ [5] = { 0, 0, 0 },
+ [6] = { 1.0, 0.0, 0.5 },
+ [7] = { 1.0, 0.0, 0.5 },
+ [10] = { 0, 0, 0 },
+ }
+ },
+
+ [5] = {
+ chars = {
+ '―', '‥', '…'
+ },
+ align = 'middle', left = 0.00, down = 0.00,
+ width = 1.0, height = vht, depth = vht, italic=0.0,
+ glue = {
+ [0] = { 0, 0, 0 },
+ [1] = { 0, 0, 0 },
+ [2] = { 0, 0, 0 },
+ [3] = { 0, 0, 0 },
+ [4] = { 0, 0, 0 },
+ [5] = { 0, 0, 0 },
+ [6] = { 0.25, 0.190480, 0.25 },
+ [7] = { 0.25, 0.190480, 0.25 },
+ [10] = { 0, 0, 0 },
+ }
+ },
+
+ [6] = { -- é–‹ã括弧類
+ chars = {
+ '‘', '“', '〈', '《', '「', '『', 'ã€', '〔', '〖',
+ '〘', 'ã€', '(', 'ï¼»', 'ï½›', '⦅'
+ },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.5, height = vht, depth = vht, italic=0.0,
+ glue = {
+ [0] = {0, 0, 0},
+ [1] = {0, 0, 0},
+ [2] = {0, 0, 0},
+ [3] = {0, 0, 0},
+ [4] = {0, 0, 0},
+ [5] = {0, 0, 0},
+ [6] = {0, 0, 0},
+ [7] = { 0.25, 0.0, 0.25 },
+ [8] = {0, 0, 0},
+ [9] = {0, 0, 0},
+ }
+ },
+
+ [7] = {
+ chars = {
+ 'â€', '‖', '・', '|'
+ },
+ align = 'middle', left = 0.00, down = 0.00,
+ width = 0.5, height = vht, depth = vht, italic=0.0,
+ glue = {
+ [0] = { 0.25, 0.190480, 0.25 },
+ [1] = { 0.25, 0, 0.25 },
+ [2] = { 0.25, 0, 0.25 },
+ [3] = { 0.111608, 0.0, 0.111608 },
+ [4] = { 0.25, 0.190480, 0.25 },
+ [5] = { 0.25, 0.190480, 0.25 },
+ [6] = { 0.25, 0.190480, 0.25 },
+ [7] = { 0, 0.190480, 0.0 },
+ [10] = { 0.25, 0, 0.25 },
+ }
+ },
+
+ [10] = { -- é–‰ã˜æ‹¬å¼§é¡ž
+ chars = {
+ '’', 'â€', '〉', '》', 'ã€', 'ã€', '】', '〕',
+ '〗', '〙', '〟', ')', 'ï¼½', 'ï½', 'ï½ '
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = vht, depth = vht, italic=0.0,
+ glue = {
+-- 3 ã¯å››åˆ†, 2, 4, 9 ã¯0, ã‚ã¨ã¯0.5
+ [0] = { 0.5 , 0.190480, 0.5 },
+ [1] = { 0, 0, 0 },
+ [2] = { 0, 0, 0 },
+ [3] = { 0.5 , 0.190480, 0.5 },
+ [4] = { 0, 0, 0 },
+ [5] = { 0.25 , 0.190480, 0.25 },
+ [6] = { 0.5 , 0.190480, 0.5 },
+ [7] = { 0.25 , 0.190480, 0.25 },
+ [10] = {0, 0, 0},
+ }
+ },
+
+ [99] = { -- box末尾
+ chars = {'boxbdd', 'parbdd'},
+ },
+
+}
diff --git a/macros/luatex/generic/luatexja/src/jfm-ujis.lua b/macros/luatex/generic/luatexja/src/jfm-ujis.lua
new file mode 100644
index 0000000000..10b44d8103
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/jfm-ujis.lua
@@ -0,0 +1,304 @@
+-- -*- coding: utf-8 -*-
+-- jfm-ujis.lua: LuaTeX-ja 標準 JFM
+-- based on upnmlminr-h.tfm (a metric in UTF/OTF package used by upTeX).
+
+-- JIS X 4051:2004 ã§ã¯ï¼Œè¡Œæœ«ã®å¥èª­ç‚¹ã‚„中点ã¯ãƒ™ã‚¿ãªã®ã§ãã‚Œã«å¾“ã†
+-- kanjiskip: 0pt plus .25zw minus 0pt
+-- xkanjiskip: .25zw plus .25zw (or .0833zw) minus .125zw
+
+
+local t = {
+ version = 3,
+ dir = 'yoko',
+ zw = 1.0, zh = 1.0,
+ kanjiskip = { 0.0, 0.25, 0 },
+ xkanjiskip = { 0.25, 0.25, .125 },
+ [0] = {
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [007] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [107] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [207] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ },
+ kern = { [307] = 0 },
+ },
+
+ [1] = { -- é–‹ã括弧類
+ chars = {
+ '‘', '“', '〈', '《', '「', '『', 'ã€', '〔', '〖',
+ '〘', 'ã€', '(', 'ï¼»', 'ï½›', '⦅'
+ },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+-- 3 ã®ã¿å››åˆ†ï¼Œã‚ã¨ã¯0
+ [0] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [1] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1, kanjiskip_stretch=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [5] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [105] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [007] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [107] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [207] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ }
+ },
+
+ [2] = { -- é–‰ã˜æ‹¬å¼§é¡ž
+ chars = {
+ '’', 'â€', '〉', '》', 'ã€', 'ã€', '】', '〕',
+ '〗', '〙', '〟', ')', 'ï¼½', 'ï½', 'ï½ ', 'ã€', ',*'
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+-- 3 ã¯å››åˆ†, 2, 4, 9 ã¯0, ã‚ã¨ã¯0.5
+ [0] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [1] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1},
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [5] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [105] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [6] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [007] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [107] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [207] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [8] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ }
+ },
+
+ [3] = { -- 中点類
+ chars = {'・', ':', ';', '·'},
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ --end_stretch = 0.25,
+ glue = {
+-- 3 ã®ã¿ 0.5,ã‚ã¨ã¯0.25
+ [0] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [1] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [2] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [3] = { 0.5 , 0.0, 0.5 , priority=1 },
+ [4] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [5] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [105] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [6] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [007] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [107] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [207] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [8] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ }
+ },
+
+ [4] = { -- å¥ç‚¹é¡ž
+ chars = {'。', '.'},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ -- 3 ã¯.75, 2, 4 ã¯0, ã‚ã¨ã¯0.5
+ [0] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [1] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [3] = { 0.75, 0.0, 0.25, priority=1, ratio=1./3, kanjiskip_stretch=1 },
+ [5] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [105] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [6] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [007] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [107] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [207] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [8] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ }
+ },
+
+ [5] = { -- 分離ç¦æ­¢æ–‡å­—
+ chars = { '—', '―', '‥', '…', '〳', '〴', '〵', },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ },
+ kern = {
+ [5] = 0.0,
+ [105] = 0.0
+ }
+ },
+
+ [105] = { -- 二分(二é‡ï¼‰ãƒ€ãƒƒã‚·ãƒ¥
+ chars = { '゠', '–' },
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ },
+ kern = {
+ [5] = 0.0,
+ [105] = 0.0
+ }
+ },
+
+ [6] = { -- 感嘆符・疑å•ç¬¦
+ chars = { '?', 'ï¼', '‼', 'â‡', 'âˆ', 'â‰', },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [0] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.75, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [007] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [107] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [207] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ },
+ kern = {
+ [5] = 0.0,
+ [105] = 0.0
+ }
+ },
+
+ [007] = { -- åŠè§’カナ,ãã®ä»–åŠè§’CID
+ chars = {
+ '。', '「', '」', '、', '・', 'ヲ', 'ァ', 'ィ', 'ゥ',
+ 'ェ', 'ォ', 'ャ', 'ュ', 'ョ', 'ッ', 'ー', 'ア', 'イ',
+ 'ウ', 'エ', 'オ', 'カ', 'キ', 'ク', 'ケ', 'コ', 'サ',
+ 'ï½¼', 'ï½½', 'ï½¾', 'ソ', 'ï¾€', 'ï¾', 'ツ', 'テ', 'ト',
+ 'ï¾…', 'ニ', 'ヌ', 'ネ', 'ノ', 'ハ', 'ヒ', 'フ', 'ï¾',
+ 'ホ', 'ï¾', 'ï¾', 'ム', 'ï¾’', 'モ', 'ï¾”', 'ユ', 'ï¾–',
+ 'ï¾—', 'リ', 'ï¾™', 'レ', 'ï¾›', 'ワ', 'ï¾', '゙', '゚',
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ },
+ kern = { [307] = 0 },
+ },
+
+ [107] = { -- 1/3 角
+ chars = {},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1/3, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [107] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ }
+ },
+
+ [207] = { -- 1/4 角
+ chars = {},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.25, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [207] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ }
+ },
+
+ [307] = { -- 1/4 角
+ chars = { 0x3099, 0x309A },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [207] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ }
+ },
+
+ [8] = { -- 罫線類.
+ chars = {
+ '─', 'â”', '│', '┃', '┄', 'â”…', '┆', '┇',
+ '┈', '┉', '┊', '┋', '┌', 'â”', '┎', 'â”',
+ 'â”', '┑', 'â”’', '┓', 'â””', '┕', 'â”–', 'â”—',
+ '┘', 'â”™', '┚', 'â”›', '├', 'â”', '┞', '┟',
+ '┠', '┡', '┢', '┣', '┤', '┥', '┦', '┧',
+ '┨', '┩', '┪', '┫', '┬', '┭', '┮', '┯',
+ '┰', '┱', '┲', '┳', '┴', '┵', '┶', '┷',
+ '┸', '┹', '┺', '┻', '┼', '┽', '┾', '┿',
+ 'â•€', 'â•', 'â•‚', '╃', 'â•„', 'â•…', '╆', '╇',
+ '╈', '╉', 'â•Š', 'â•‹', 'â•Œ', 'â•', 'â•Ž', 'â•',
+ 'â•', 'â•‘', 'â•’', 'â•“', 'â•”', 'â••', 'â•–', 'â•—',
+ '╘', 'â•™', 'â•š', 'â•›', 'â•œ', 'â•', 'â•ž', 'â•Ÿ',
+ '╠', '╡', '╢', '╣', '╤', '╥', '╦', '╧',
+ '╨', '╩', '╪', '╫', '╬', '╭', '╮', '╯',
+ '╰', '╱', '╲', '╳', '╴', '╵', '╶', '╷',
+ '╸', '╹', '╺', '╻', '╼', '╽', '╾', '╿',
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.88, depth = 0.12, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ },
+ kern = {
+ [8] = 0.0
+ }
+ },
+
+
+ [99] = { -- box末尾
+ chars = {'boxbdd', 'parbdd', 'glue'},
+ },
+
+}
+
+local ht = t[007].chars
+for i=231,632 do ht[#ht+1] = 'AJ1-' .. tostring(i) end
+for i=8718,8719 do ht[#ht+1] = 'AJ1-' .. tostring(i) end
+for i=12063,12087 do ht[#ht+1] = 'AJ1-' .. tostring(i) end
+local ht = t[107].chars
+for i=9758,9778 do ht[#ht+1] = 'AJ1-' .. tostring(i) end
+local ht = t[207].chars
+for i=9738,9757 do ht[#ht+1] = 'AJ1-' .. tostring(i) end
+
+t[100]=table.fastcopy(t[0])
+t[100].chars={'nox_alchar'}
+for i,v in pairs(t) do
+ if i~=6 and type(i)=='number' and type(v)=='table' then -- 感嘆符以外
+ if v.glue and v.glue[0] then v.glue[100] = v.glue[0] end
+ if v.kern and v.kern[0] then v.kern[100] = v.kern[0] end
+ end
+end
+
+luatexja.jfont.define_jfm(t)
diff --git a/macros/luatex/generic/luatexja/src/jfm-ujisv.lua b/macros/luatex/generic/luatexja/src/jfm-ujisv.lua
new file mode 100644
index 0000000000..ccae212f88
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/jfm-ujisv.lua
@@ -0,0 +1,307 @@
+-- -*- coding: utf-8 -*-
+-- jfm-ujisv.lua: LuaTeX-ja 標準 JFM(縦組ã¿ç”¨ï¼‰
+-- based on upnmlminr-h.tfm (a metric in UTF/OTF package used by upTeX).
+
+-- JIS X 4051:2004 ã§ã¯ï¼Œè¡Œæœ«ã®å¥èª­ç‚¹ã‚„中点ã¯ãƒ™ã‚¿ãªã®ã§ãã‚Œã«å¾“ã†
+-- kanjiskip: 0pt plus .25zw minus 0pt
+-- xkanjiskip: .25zw plus .25zw (or .0833zw) minus .125zw
+
+
+local t = {
+ version = 3,
+ dir = 'tate',
+ zw = 1.0, zh = 1.0,
+ kanjiskip = { 0.0, 0.25, 0 },
+ xkanjiskip = { 0.25, 0.25, .125 },
+ [0] = {
+ align = 'middle', left = 0.00, down = 0.00,
+ width = 1.0, height = 0.50, depth = 0.50, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [7] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [107] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [207] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ },
+ kern = { [307] = 0 },
+ },
+
+ [1] = { -- é–‹ã括弧類
+ chars = {
+ '‘', '“', '〈', '《', '「', '『', 'ã€', '〔', '〖',
+ '〘', 'ã€', '(', 'ï¼»', 'ï½›', '⦅'
+ },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.50, depth = 0.50, italic=0.0,
+ glue = {
+-- 3 ã®ã¿å››åˆ†ï¼Œã‚ã¨ã¯0
+ [0] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [1] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [2] = { 0, 0, 0, kanjiskip_stretch=1, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [5] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [105] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [7] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [107] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [207] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ }
+ },
+
+ [2] = { -- é–‰ã˜æ‹¬å¼§é¡ž
+ chars = {
+ '’', 'â€', '〉', '》', 'ã€', 'ã€', '】', '〕',
+ '〗', '〙', '〟', ')', 'ï¼½', 'ï½', 'ï½ ', 'ã€', ','
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.50, depth = 0.50, italic=0.0,
+ glue = {
+-- 3 ã¯å››åˆ†, 2, 4, 9 ã¯0, ã‚ã¨ã¯0.5
+ [0] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [1] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [5] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [105] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [6] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [7] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [107] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [207] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [8] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ }
+ },
+
+ [3] = { -- 中点類
+ chars = {'・', ':', ';', '·'},
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.50, depth = 0.50, italic=0.0,
+ --end_stretch = 0.25,
+ glue = {
+-- 3 ã®ã¿ 0.5,ã‚ã¨ã¯0.25
+ [0] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [1] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [2] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [3] = { 0.5 , 0.0, 0.25, priority=1 },
+ [4] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [5] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [105] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [6] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [7] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [107] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [207] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [8] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ }
+ },
+
+ [4] = { -- å¥ç‚¹é¡ž
+ chars = {'。', '.'},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.50, depth = 0.50, italic=0.0,
+ glue = {
+-- 3 ã¯.75, 2, 4 ã¯0, ã‚ã¨ã¯0.5
+ [0] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [1] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [3] = { 0.75, 0.0, 0.25, priority=1, ratio=1./3, kanjiskip_stretch=1 },
+ [5] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [105] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [6] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [7] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [107] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [207] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ [8] = { 0.5 , 0.0, 0.5, ratio=0, kanjiskip_stretch=1 },
+ }
+ },
+
+ [5] = { -- 分離ç¦æ­¢æ–‡å­—
+ chars = { '—', '―', '‥', '…', '〳', '〴', '〵', },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.50, depth = 0.50, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ },
+ kern = {
+ [5] = 0.0,
+ [105] = 0.0,
+ }
+ },
+
+ [5] = { -- -- 二分(二é‡ï¼‰ãƒ€ãƒƒã‚·ãƒ¥
+ chars = { '゠', '–' },
+ align = 'middle', left = 0.0, down = 0.0,
+ width = 0.50, height = 0.50, depth = 0.50, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ },
+ kern = {
+ [5] = 0.0,
+ [105] = 0.0
+ }
+ },
+
+ [6] = { -- 感嘆符・疑å•ç¬¦
+ chars = { '?', 'ï¼', '‼', 'â‡', 'âˆ', 'â‰', },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.50, depth = 0.50, italic=0.0,
+ glue = {
+ [0] = { 1.0 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.75, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [7] = { 1.0 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [107] = { 1.0 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [207] = { 1.0 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ },
+ kern = {
+ [5] = 0.0,
+ [105] = 0.0,
+ }
+ },
+
+ [7] = { -- åŠè§’カナ,ãã®ä»–åŠè§’CID
+ chars = {
+ '。', '「', '」', '、', '・', 'ヲ', 'ァ', 'ィ', 'ゥ',
+ 'ェ', 'ォ', 'ャ', 'ュ', 'ョ', 'ッ', 'ー', 'ア', 'イ',
+ 'ウ', 'エ', 'オ', 'カ', 'キ', 'ク', 'ケ', 'コ', 'サ',
+ 'ï½¼', 'ï½½', 'ï½¾', 'ソ', 'ï¾€', 'ï¾', 'ツ', 'テ', 'ト',
+ 'ï¾…', 'ニ', 'ヌ', 'ネ', 'ノ', 'ハ', 'ヒ', 'フ', 'ï¾',
+ 'ホ', 'ï¾', 'ï¾', 'ム', 'ï¾’', 'モ', 'ï¾”', 'ユ', 'ï¾–',
+ 'ï¾—', 'リ', 'ï¾™', 'レ', 'ï¾›', 'ワ', 'ï¾', '゙', '゚',
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 0.5, height = 0.5, depth = 0.5, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [7] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ }
+ },
+
+ [107] = { -- 1/3 角
+ chars = {},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1/3, height = 0.5, depth = 0.5, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [107] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ }
+ },
+ [207] = { -- 1/4 角
+ chars = {},
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1/4, height = 0.5, depth = 0.5, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [207] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ }
+ },
+ [307] = { -- åˆæˆç”¨æ¿ç‚¹ãƒ»åŠæ¿ç‚¹
+ chars = { 0x3099, 0x309A },
+ align = 'right', left = 0.0, down = 0.0,
+ width = 0, height = 0.5, depth = 0.5, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [8] = { 0, 0, 0, kanjiskip_shrink=1 },
+ }
+ },
+
+ [8] = { -- 罫線類.
+ chars = {
+ '─', 'â”', '│', '┃', '┄', 'â”…', '┆', '┇',
+ '┈', '┉', '┊', '┋', '┌', 'â”', '┎', 'â”',
+ 'â”', '┑', 'â”’', '┓', 'â””', '┕', 'â”–', 'â”—',
+ '┘', 'â”™', '┚', 'â”›', '├', 'â”', '┞', '┟',
+ '┠', '┡', '┢', '┣', '┤', '┥', '┦', '┧',
+ '┨', '┩', '┪', '┫', '┬', '┭', '┮', '┯',
+ '┰', '┱', '┲', '┳', '┴', '┵', '┶', '┷',
+ '┸', '┹', '┺', '┻', '┼', '┽', '┾', '┿',
+ 'â•€', 'â•', 'â•‚', '╃', 'â•„', 'â•…', '╆', '╇',
+ '╈', '╉', 'â•Š', 'â•‹', 'â•Œ', 'â•', 'â•Ž', 'â•',
+ 'â•', 'â•‘', 'â•’', 'â•“', 'â•”', 'â••', 'â•–', 'â•—',
+ '╘', 'â•™', 'â•š', 'â•›', 'â•œ', 'â•', 'â•ž', 'â•Ÿ',
+ '╠', '╡', '╢', '╣', '╤', '╥', '╦', '╧',
+ '╨', '╩', '╪', '╫', '╬', '╭', '╮', '╯',
+ '╰', '╱', '╲', '╳', '╴', '╵', '╶', '╷',
+ '╸', '╹', '╺', '╻', '╼', '╽', '╾', '╿',
+ },
+ align = 'left', left = 0.0, down = 0.0,
+ width = 1.0, height = 0.50, depth = 0.50, italic=0.0,
+ glue = {
+ [1] = { 0.5 , 0.0, 0.5, ratio=1, kanjiskip_stretch=1 },
+ [2] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [3] = { 0.25, 0.0, 0.25, priority=1, ratio=1 },
+ [4] = { 0, 0, 0, kanjiskip_shrink=1 },
+ [6] = { 0, 0, 0, kanjiskip_shrink=1 },
+ },
+ kern = {
+ [8] = 0.0
+ }
+ },
+
+ [99] = { -- box末尾
+ chars = {'boxbdd', 'parbdd', 'glue'},
+ },
+
+}
+local ht = t[007].chars
+for i=8950,9353 do ht[#ht+1] = 'AJ1-' .. tostring(i) end
+for i=10185,10195 do ht[#ht+1] = 'AJ1-' .. tostring(i) end
+local ht = t[107].chars
+for i=13274,13294 do ht[#ht+1] = 'AJ1-' .. tostring(i) end
+local ht = t[207].chars
+for i=13254,13273 do ht[#ht+1] = 'AJ1-' .. tostring(i) end
+
+t[100]=table.fastcopy(t[0])
+t[100].chars={'nox_alchar'}
+for i,v in pairs(t) do
+ if i~=6 and type(i)=='number' and type(v)=='table' then -- 感嘆符以外
+ if v.glue and v.glue[0] then v.glue[100] = v.glue[0] end
+ if v.kern and v.kern[0] then v.kern[100] = v.kern[0] end
+ end
+end
+t[200]=table.fastcopy(t[0])
+t[200].chars={'〱', '〲'}
+t[200].width = 2.0
+for i,v in pairs(t) do
+ if type(v)=='table' then
+ if v.glue and v.glue[0] then v.glue[200] = v.glue[0] end
+ if v.kern and v.kern[0] then v.kern[200] = v.kern[0] end
+ end
+end
+
+luatexja.jfont.define_jfm(t)
diff --git a/macros/luatex/generic/luatexja/src/lltjext.sty b/macros/luatex/generic/luatexja/src/lltjext.sty
new file mode 100644
index 0000000000..eb1087ad6b
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/lltjext.sty
@@ -0,0 +1,758 @@
+%
+% lltjext.sty: derived from plext.sty in pLaTeX.
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lltjext}[2018/10/07 v1.2k-ltj-10 Macros for vertical writing]
+\RequirePackage{luatexja}
+\newcount\ltj@ext@dir
+\let\ltj@lltjext@orig@tabular=\tabular
+\let\ltj@lltjext@orig@array=\array
+
+%%% array and tabular
+\def\array{\let\@acol\@arrayacol \let\@classz\@arrayclassz
+ \let\@classiv\@arrayclassiv
+ \let\\\@arraycr\let\@halignto\@empty
+ \ltj@ext@dir=\ltjgetparameter{direction}\relax\X@tabarray}
+\def\tabular{\let\@halignto\@empty\X@tabular}
+\@namedef{tabular*}{\@ifnextchar<%>
+ {\p@stabular}{\p@stabular<Z>}}
+{\catcode`\*=11
+\global\let\ltj@lltjext@orig@tabularS=\tabular*
+}%
+\def\X@tabarray{\@ifnextchar<%>
+ {\p@tabarray}{\p@tabarray<Z>}}
+\def\X@tabular{\@ifnextchar<%>
+ {\p@tabular}{\p@tabular<Z>}}
+\def\p@stabular<#1>#2{%
+ \setlength\dimen@{#2}%
+ \edef\@halignto{to\the\dimen@}\p@tabular<#1>}
+\def\p@tabular<#1>{\leavevmode \hbox \bgroup
+ \ltj@ext@dir=\ltjgetparameter{direction}
+ $\let\@acol\@tabacol
+ \let\@classz\@tabclassz
+ \let\@classiv\@tabclassiv \let\\\@tabularcr\p@tabarray<#1>}
+\def\p@tabarray<#1>{\m@th\@ifnextchar[%]
+ {\p@array<#1>}{\p@array<#1>[c]}}
+
+\def\p@array<#1>[#2]#3{%
+ \let\box@dir\relax
+ \if #1z\relax
+ \ifnum\ltj@ext@dir=3\relax
+ \let\box@dir\utod\@tempcnta=\zstrutbox
+ \fi
+ \else
+ \if #1y\relax
+ \let\box@dir\yoko\@tempcnta=\ystrutbox
+ \else\if #1t\relax
+ \let\box@dir\tate\@tempcnta=\tstrutbox
+ \else\if #1d\relax
+ \let\box@dir\dtou\@tempcnta=\dstrutbox
+ \else\if #1u\relax
+ \let\box@dir\utod\@tempcnta=\zstrutbox
+ \fi\fi\fi\fi
+ \fi
+ \ifx\box@dir\relax
+ \ifcase\ltj@ext@dir
+ \or \let\box@dir\dtou\@tempcnta=\dstrutbox% dtou
+ \or\or\let\box@dir\tate\@tempcnta=\tstrutbox% tate
+ \or \let\box@dir\yoko\@tempcnta=\ystrutbox% yoko
+ \else \let\box@dir\utod\@tempcnta=\zstrutbox% utod
+ \fi
+ \fi
+ \fork@array@option<#1>[#2]\@begin@alignbox
+ \bgroup\box@dir\adjustbaseline
+ \setbox\@arstrutbox\hbox{%
+ \box@dir
+ \vrule\@height\arraystretch\ltjgetht\@tempcnta
+ \@depth\arraystretch\ltjgetdp\@tempcnta \@width\z@}%
+ \@mkpream{#3}\edef\@preamble{\ialign \noexpand\@halignto
+ \bgroup\@arstrut \@preamble \tabskip\z@skip \cr}%
+ \let\@startpbox\@@startpbox \let\@endpbox\@@endpbox
+ \let\tabularnewline\\%
+ \let\par\@empty
+ \let\@sharp##%
+ \set@typeset@protect
+ \lineskip\z@skip\baselineskip\z@skip
+ \ifhmode \@preamerr\z@ \@@par\fi
+ \@preamble}
+\def\endarray{\crcr\egroup\egroup\@end@alignbox}
+\def\endtabular{\endarray$\egroup}
+\expandafter \let \csname endtabular*\endcsname = \endtabular
+% ↓中身\周囲→ yoko tate utod dtou
+% yoko A* B* B B
+% tate B* A* D C
+% utod B D* A C
+% dtou B C C A
+% A: 周囲ã¨ä¸­èº«ã®çµ„æ–¹å‘ãŒä¸€è‡´ï¼Žãã®ã¾ã¾ \vtop/\vcenter/\vbox
+% B: 周囲ã¨ä¸­èº«ãŒ90度ãšã‚Œï¼Žä¸Šç«¯/下端ãŒãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã«æƒã†ã‚ˆã†ã«
+% C: 周囲ã¨ä¸­èº«ãŒ180度ãšã‚Œï¼Ž\vtop, \vbox 入れ替ãˆ
+% D: 欧文ベースラインåŒå£«ã‚’æƒãˆã‚‹ã‚ˆã†ã«ã™ã‚‹
+
+\def\fork@array@option@@A#1{%
+ \let\@end@alignbox\relax
+ \if #1t\relax \let\@begin@alignbox\vtop
+ \else\if #1b\relax\let\@begin@alignbox\vbox
+ \else \let\@begin@alignbox\vcenter
+ \fi\fi}
+\def\fork@array@option@@B#1{%
+ \if #1t\relax
+ \def\@begin@alignbox{\vtop\bgroup\kern\z@\vbox}%
+ \let\@end@alignbox\egroup
+ \else\if #1b\relax
+ \def\@begin@alignbox{\vbox\bgroup\vbox}%
+ \def\@end@alignbox{\kern\z@\egroup}%
+ \else
+ \let\@begin@alignbox\vcenter
+ \let\@end@alignbox\relax
+ \fi\fi}
+\def\fork@array@option@@C#1{%
+ \let\@end@alignbox\relax
+ \if #1t\relax \let\@begin@alignbox\vbox
+ \else\if #1b\relax\let\@begin@alignbox\vtop
+ \else \let\@begin@alignbox\vcenter
+ \fi\fi}
+\def\fork@array@option<#1>[#2]{%
+\ifnum\ltj@ext@dir=4 % yoko
+ \ifx\box@dir\yoko \fork@array@option@@A{#2}%
+ \else \fork@array@option@@B{#2}%
+ \fi
+\else\ifnum\ltj@ext@dir=1 % dtou
+ \ifx\box@dir\yoko \fork@array@option@@B{#2}%
+ \else\ifx\box@dir\dtou \fork@array@option@@A{#2}%
+ \else \fork@array@option@@C{#2}%
+ \fi\fi
+\else\ifnum\ltj@ext@dir=3 % tate
+ \ifx\box@dir\yoko \fork@array@option@@B{#2}%
+ \else\ifx\box@dir\tate \fork@array@option@@A{#2}%
+ \else\ifx\box@dir\dtou \fork@array@option@@C{#2}%
+ \else
+ \if #2t\relax
+ \def\@begin@alignbox{\lower\dimexpr
+ \ltjgetparameter{talbaselineshift}-\ltjgetparameter{yalbaselineshift}\vtop}
+ \let\@end@alignbox\relax
+ \else\if #2b\relax
+ \def\@begin@alignbox{\lower\dimexpr
+ \ltjgetparameter{talbaselineshift}-\ltjgetparameter{yalbaselineshift}\vbox}
+ \let\@end@alignbox\relax
+ \else
+ \let\@begin@alignbox\vcenter
+ \let\@end@alignbox\relax
+ \fi\fi
+ \fi\fi\fi
+\else % utod
+ \ifx\box@dir\yoko \fork@array@option@@B{#2}%
+ \else\ifx\box@dir\utod \fork@array@option@@A{#2}%
+ \else\ifx\box@dir\dtou \fork@array@option@@C{#2}%
+ \else
+ \if #2t\relax
+ \def\@begin@alignbox{\lower\dimexpr
+ \ltjgetparameter{yalbaselineshift}-\ltjgetparameter{talbaselineshift}\vtop}
+ \let\@end@alignbox\relax
+ \else\if #2b\relax
+ \def\@begin@alignbox{\lower\dimexpr
+ \ltjgetparameter{yalbaselineshift}-\ltjgetparameter{talbaselineshift}\vbox}
+ \let\@end@alignbox\relax
+ \else
+ \let\@begin@alignbox\vcenter
+ \let\@end@alignbox\relax
+ \fi\fi
+ \fi\fi\fi
+\fi\fi\fi}
+
+%%% caption
+\newbox\@floatbox
+\newdimen\floatwidth
+\newdimen\floatheight
+\newdimen\floatruletick \floatruletick=0.4pt
+\newdimen\captionfloatsep \captionfloatsep=10pt
+\def\caption@dir{Z}
+\let\captiondir\relax
+\newdimen\captionwidth \captionwidth\z@
+\def\caption@posa{Z}
+\def\caption@posb{Z}
+\newbox\@captionbox
+\def\captionfontsetup{\normalfont\normalsize}
+\def\layoutfloat{\@ifnextchar(%)
+ {\X@layoutfloat}{\X@layoutfloat(-5\p@,-5\p@)}}
+\def\X@layoutfloat(#1,#2){\@ifnextchar[%]
+ {\@layoutfloat(#1,#2)}{\@layoutfloat(#1,#2)[c]}}
+\long\def\@layoutfloat(#1,#2)[#3]#4{%
+ \setbox\z@\hbox{#4}%
+ \floatwidth=#1 \floatheight=#2 \edef\float@pos{#3}%
+ \ifdim\floatwidth<\z@
+ \floatwidth\ltjgetwd\z@\floatruletick\z@
+ \fi
+ \ifdim\floatheight<\z@
+ \floatheight\ltjgetht\z@\advance\floatheight\ltjgetdp\z@\relax
+ \floatruletick\z@
+ \fi
+ \setbox\@floatbox\vbox to\floatheight{\offinterlineskip
+ \hrule width\floatwidth height\floatruletick depth\z@
+ \vss\hbox to\floatwidth{%
+ \vrule width\floatruletick height\floatheight depth\z@
+ \hss\vbox to\floatheight{\hsize\floatwidth\vss#4\vss}\hss
+ \vrule width\floatruletick height\floatheight depth\z@
+ }\hrule width\floatwidth height\floatruletick depth\z@}}
+\def\DeclareLayoutCaption#1<#2>(#3)[#4#5]{%
+ \expandafter
+ \ifx\csname #1@layoutc@ption\endcsname\relax \else
+ \@latex@info{Redeclaring capiton layout setting of '#1'}%
+ \fi
+ \expandafter
+ \gdef\csname #1@layoutc@ption\endcsname{%
+ \if Z\caption@dir\def\caption@dir{#2}\fi
+ \ifdim\captionwidth=\z@ \captionwidth=#3\relax\fi
+ \if Z\caption@posa\def\caption@posa{#4}\fi
+ \if Z\caption@posb\def\caption@posb{#5}\fi}}
+\@onlypreamble\DeclareLayoutCaption
+\DeclareLayoutCaption{figure}<n>(.8\linewidth)[cd]
+\DeclareLayoutCaption{table}<n>(.8\linewidth)[cu]
+\def\layoutcaption{\def\caption@dir{Z}\captionwidth\z@
+ \def\caption@posa{Z}\def\caption@posb{Z}%
+ \@ifnextchar<\X@layoutcaption{%
+ \@ifnextchar(\@ilayoutcaption{%
+ \@ifnextchar[\@iilayoutcaption\relax}}}
+\def\X@layoutcaption<#1>{\def\caption@dir{#1}%
+ \@ifnextchar(\@ilayoutcaption{%
+ \@ifnextchar[\@iilayoutcaption\relax}}
+\def\@ilayoutcaption(#1){\setlength\captionwidth{#1}%
+ \@ifnextchar[{\@iilayoutcaption}{\relax}}
+\def\@iilayoutcaption[#1#2]{%
+ \def\caption@posa{#1}\def\caption@posb{#2}}
+\def\pcaption{%
+ \ifx\@captype\@undefined
+ \@latex@error{\noexpand\pcaption outside float}\@ehd
+ \expandafter\@gobble
+ \else
+ \refstepcounter\@captype
+ \expandafter\@firstofone
+ \fi
+ {\@dblarg{\@pcaption\@captype}}%
+}
+\long\def\@pcaption#1[#2]#3{%
+ \addcontentsline{\csname ext@#1\endcsname}{#1}{%
+ \protect\numberline{\csname the#1\endcsname}{\ignorespaces#2}}%
+ \ifvoid\@floatbox
+ \@latex@error{Use \noexpand\pcaption with `\protect\layoutfloat'}\@eha
+ \fi
+ \make@pcaptionbox{#3}%
+ \@pboxswfalse
+ \setbox\@tempboxa\vbox{\hbox to\hsize{\if l\float@pos\else\hss\fi
+ \if l\caption@posb\box\@captionbox\kern\captionfloatsep\fi
+ \if t\caption@posa\vtop
+ \else\if b\caption@posa\vbox
+ \else\@pboxswtrue $\vcenter \fi\fi
+ {\if u\caption@posb\box\@captionbox\kern\captionfloatsep\fi
+ \unvbox\@floatbox
+ \if d\caption@posb\kern\captionfloatsep\box\@captionbox\fi}%
+ \if@pboxsw \m@th$\fi
+ \if r\caption@posb\kern\captionfloatsep\box\@captionbox\fi
+ \if r\float@pos\else\hss\fi}}%
+ \par\vskip.25\baselineskip
+ \box\@tempboxa}
+\def\make@pcaptionbox#1{%
+ \expandafter
+ \ifx\csname\@captype @layoutc@ption\endcsname\relax
+ \@latex@warning{Default caption layout of `\@captype' unknown.}%
+ \def\caption@dir{Z}\captionwidth\z@
+ \def\caption@posa{Z}\def\caption@posb{Z}%
+ \else
+ \csname \@captype @layoutc@ption\endcsname
+ \fi
+ \@tempswafalse
+ % \@tempswa: 基本組ã®çµ„æ–¹å‘ã¨ã‚­ãƒ£ãƒ—ションã®çµ„æ–¹å‘ãŒç›´äº¤ã™ã‚‹ã‹ï¼Ÿ
+ \if y\caption@dir \let\captiondir\yoko
+ \ifodd\ltjgetparameter{direction}\relax\@tempswatrue\fi
+ \else\if z\caption@dir \let\captiondir\relax
+ \ifnum\ltjgetparameter{direction}=3\relax\let\captiondir\utod\fi
+ \else\if d\caption@dir \let\captiondir\dtou
+ \ifodd\ltjgetparameter{direction}\else\@tempswatrue\fi
+ \else\if u\caption@dir \let\captiondir\utod
+ \ifodd\ltjgetparameter{direction}\else\@tempswatrue\fi
+ \else\if t\caption@dir \let\captiondir\tate
+ \ifodd\ltjgetparameter{direction}\else\@tempswatrue\fi
+ \fi\fi\fi\fi\fi
+ \setbox0\hbox{\hbox{\captiondir
+ \captionfontsetup\parindent\z@\inhibitglue
+ \csname fnum@\@captype\endcsname  #1}}%"
+ \if@tempswa\@tempdima\ltjgetht0 \advance\@tempdima\ltjgetdp0
+ \else\@tempdima\ltjgetwd0 \fi
+ \ifdim\@tempdima>\captionwidth \@tempdima\captionwidth \fi
+ \@pboxswfalse
+ \setbox0\hbox{%
+ \if u\caption@posb\vbox
+ \else\if d\caption@posb\vbox
+ \else\if t\caption@posa\vtop
+ \else\if b\caption@posa\vbox
+ \else\ifmmode\vcenter\else\@pboxswtrue $\vcenter\fi
+ \fi\fi\fi\fi
+ {\hsize\@tempdima\kern\z@
+ \vbox{\captiondir\hsize\@tempdima
+ \captionfontsetup\parindent\z@\inhibitglue
+ \csname fnum@\@captype\endcsname  #1}\kern\z@
+ }\if@pboxsw \m@th$\fi}%
+ \let\to@captionboxwidth\relax
+ \if l\caption@posb \else\if r\caption@posb\else
+ \def\to@captionboxwidth{to\floatwidth}\fi\fi
+ \setbox\@captionbox\hbox\to@captionboxwidth{%
+ \if t\caption@posa\else\hss\fi
+ \unhbox0\relax
+ \if b\caption@posa\else\hss\fi}}
+
+%%% minipage and parbox
+\def\minipage{\@ifnextchar<%>
+ {\X@minipage}{\X@minipage<Z>}}
+\def\X@minipage<#1>{\@ifnextchar[%]
+ {\@iminipage<#1>}{\@iiiminipage<#1>{c}\relax[s]}}
+\def\@iminipage<#1>[#2]{\@ifnextchar[%]
+ {\@iiminipage<#1>{#2}}{\@iiiminipage<#1>{#2}\relax[s]}}
+\def\@iiminipage<#1>#2[#3]{\@ifnextchar[%]
+ {\@iiiminipage<#1>{#2}{#3}}{\@iiiminipage<#1>{#2}{#3}[#2]}}
+\def\@iiiminipage<#1>#2#3[#4]#5{%
+ \leavevmode\bgroup
+ \setlength\@tempdima{#5}%
+ \def\@mpargs{<#1>{#2}{#3}[#4]{#5}}%
+ \let\box@dir\relax
+ \if #1z\relax
+ \ifnum\ltjgetparameter{direction}=3\relax
+ \let\box@dir\utod
+ \fi
+ \else
+ \if #1y\relax \let\box@dir\yoko
+ \else\if #1t\relax\let\box@dir\tate
+ \else\if #1d\relax\let\box@dir\dtou
+ \else\if #1u\relax\let\box@dir\utod
+ \fi\fi\fi\fi
+ \fi
+ \ifx\box@dir\relax
+ \ifcase\ltjgetparameter{direction}\relax
+ \or \let\box@dir\dtou
+ \or\or\let\box@dir\tate
+ \or \let\box@dir\yoko
+ \else \let\box@dir\utod
+ \fi
+ \fi
+ \setbox\@tempboxa\vbox\bgroup\box@dir
+ \adjustbaseline
+ \color@begingroup
+ \hsize\@tempdima
+ \textwidth\hsize \columnwidth\hsize
+ \@parboxrestore
+ \def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}%
+ \c@mpfootnote\z@
+ \let\@footnotetext\@mpfootnotetext
+ \let\@listdepth\@mplistdepth \@mplistdepth\z@
+ \@minipagerestore
+ \@setminipage}
+\def\endminipage{%
+ \par
+ \unskip
+ \ifvoid\@mpfootins\else
+ \vskip\skip\@mpfootins
+ \normalcolor
+ \footnoterule
+ \unvbox\@mpfootins
+ \fi
+ \@minipagefalse %% added 24 May 89
+ \color@endgroup
+ \egroup
+ \expandafter\@iiiparbox\@mpargs{\unvbox\@tempboxa}\egroup}
+\DeclareRobustCommand\parbox{\@ifnextchar<%>
+ {\X@parbox}{\X@parbox<Z>}}
+\def\X@parbox<#1>{\@ifnextchar[%]
+ {\@iparbox<#1>}{\@iiiparbox<#1>{c}\relax[s]}}
+\def\@iparbox<#1>[#2]{\@ifnextchar[%]
+ {\@iiparbox<#1>{#2}}{\@iiiparbox<#1>{#2}\relax[s]}}
+\def\@iiparbox<#1>#2[#3]{\@ifnextchar[%]%
+ {\@iiiparbox<#1>{#2}{#3}}{\@iiiparbox<#1>{#2}{#3}[#2]}}
+\long\def\@iiiparbox<#1>#2#3[#4]#5#6{%
+ \leavevmode
+ \setlength\@tempdima{#5}%
+ \fork@parbox@option<#1>[#2]%
+ \@begin@tempboxa\vbox{\box@dir
+ \hsize\@tempdima\@parboxrestore\adjustbaseline#6\@@par}%
+ \ifx\relax#3\else
+ \setlength\@tempdimb{#3}%
+ \edef\@parboxto{to\the\@tempdimb}%
+ \fi
+ \@begin@parbox\@parboxto{\box@dir\adjustbaseline
+ \let\hss\vss\let\unhbox\unvbox
+ \csname bm@#4\endcsname}\@end@parbox
+ \@end@tempboxa}
+
+
+% ↓中身\周囲→ yoko tate utod dtou
+% yoko A* B* B B
+% tate B* A* D C
+% utod B D* A C
+% dtou B C C A
+% A: 周囲ã¨ä¸­èº«ã®çµ„æ–¹å‘ãŒä¸€è‡´ï¼Žãã®ã¾ã¾ \vtop/\vcenter/\vbox
+% B: 周囲ã¨ä¸­èº«ãŒ90度ãšã‚Œï¼Žä¸Šç«¯ãŒå’Œæ–‡ã®é«˜ã• or 下端ãŒå’Œæ–‡ã®æ·±ã•ã«æƒã†ã‚ˆã†ã«
+% C: 周囲ã¨ä¸­èº«ãŒ180度ãšã‚Œï¼Žï¼ˆã‚³ãƒ¼ãƒ‰ã¯ B ã®ã‚‚ã®ã‚’æµç”¨ï¼‰
+% D: 上端ãŒå’Œæ–‡ã®é«˜ã• or 下端ãŒå’Œæ–‡ã®æ·±ã•ã«æƒã†ã‚ˆã†ã«ï¼ˆã‚³ãƒ¼ãƒ‰ã¯ B ã®ã‚‚ã®ã‚’æµç”¨ï¼‰
+
+\def\fork@parbox@option@@A#1{%
+ \let\@end@parbox\relax
+ \if #1t\relax \let\@begin@parbox\vtop
+ \else\if #1b\relax\let\@begin@parbox\vbox
+ \else
+ \ifmmode
+ \let\@begin@parbox\vcenter\let\@end@parbox\relax
+ \else
+ \def\@begin@parbox{\null$\vcenter}%
+ \def\@end@parbox{\m@th$\null}%
+ \fi
+ \fi\fi}
+\def\lltjext@getjablshift{%
+ \ifnum\ltj@ext@dir=3 \ltjgetparameter{tjabaselineshift}\else
+ \ltjgetparameter{yjabaselineshift}\fi}
+\def\fork@parbox@option@@B#1{%
+ \if #1t\relax
+ \def\@begin@parbox{\raise\dimexpr\cht-\lltjext@getjablshift\vtop\bgroup\kern\z@\vbox}%
+ \let\@end@parbox\egroup
+ \else\if #1b\relax
+ \def\@begin@parbox{\lower\dimexpr\cdp+\lltjext@getjablshift\vbox\bgroup\vbox}%
+ \def\@end@parbox{\kern\z@\egroup}%
+ \else
+ \ifmmode
+ \let\@begin@parbox\vcenter\let\@end@parbox\relax
+ \else
+ \def\@begin@parbox{\null$\vcenter}%
+ \def\@end@parbox{\m@th$\null}%
+ \fi
+ \fi\fi}
+\let\fork@parbox@option@@C=\fork@parbox@option@@B
+\def\fork@parbox@option<#1>[#2]{%
+ \let\box@dir\relax \ltj@ext@dir=\ltjgetparameter{direction}\relax
+ \if #1z\relax
+ \ifnum\ltj@ext@dir=3\relax
+ \let\box@dir\utod
+ \fi
+ \else
+ \if #1y\relax \let\box@dir\yoko
+ \else\if #1t\relax\let\box@dir\tate
+ \else\if #1d\relax\let\box@dir\dtou
+ \else\if #1u\relax\let\box@dir\utod
+ \fi\fi\fi\fi
+ \fi
+ \ifx\box@dir\relax
+ \ifcase\ltj@ext@dir
+ \or \let\box@dir\dtou
+ \or\or\let\box@dir\tate
+ \or \let\box@dir\yoko
+ \else \let\box@dir\utod
+ \fi
+ \fi
+\ifnum\ltj@ext@dir=4 % yoko
+ \ifx\box@dir\yoko \fork@parbox@option@@A{#2}%
+ \else \fork@parbox@option@@B{#2}%
+ \fi
+\else\ifnum\ltj@ext@dir=1 % dtou
+ \ifx\box@dir\yoko \fork@parbox@option@@B{#2}%
+ \else\ifx\box@dir\dtou \fork@parbox@option@@A{#2}%
+ \else \fork@parbox@option@@C{#2}%
+ \fi\fi
+\else\ifnum\ltj@ext@dir=3 % tate
+ \ifx\box@dir\yoko \fork@parbox@option@@B{#2}%
+ \else\ifx\box@dir\tate \fork@parbox@option@@A{#2}%
+ \else\ifx\box@dir\dtou \fork@parbox@option@@C{#2}%
+ \else \fork@parbox@option@@B{#2}% D
+ \fi\fi\fi
+\else % utod
+ \ifx\box@dir\yoko \fork@parbox@option@@B{#2}%
+ \else\ifx\box@dir\utod \fork@parbox@option@@A{#2}%
+ \else\ifx\box@dir\dtou \fork@parbox@option@@C{#2}%
+ \else \fork@parbox@option@@B{#2}% D
+ \fi\fi\fi
+\fi\fi\fi}
+
+%%% pbox
+\DeclareRobustCommand\pbox{\leavevmode\@ifnextchar<{\X@makePbox}{\X@makePbox<Z>}}
+\def\X@makePbox<#1>{%
+ \@ifnextchar[{\@imakePbox<#1>}{\@imakePbox<#1>[-5\p@]}}
+\def\@imakePbox<#1>[#2]{\@ifnextchar[%]
+ {\@iimakePbox<#1>{#2}}{\@iimakePbox<#1>{#2}[c]}}
+\def\@iimakePbox<#1>#2[#3]#4{%
+ \bgroup\let\box@dir\relax
+ \if #1z\relax
+ \ifnum\ltjgetparameter{direction}=3 \relax
+ \let\box@dir\utod
+ \fi
+ \else
+ \if #1y\relax \let\box@dir\yoko
+ \else\if #1t\relax\let\box@dir\tate
+ \else\if #1d\relax\let\box@dir\dtou
+ \else\if #1u\relax\let\box@dir\utod
+ \fi\fi\fi\fi
+ \fi
+ \ifx\box@dir\relax
+ \ifcase\ltjgetparameter{direction}
+ \or \let\box@dir\dtou
+ \or\or\let\box@dir\tate
+ \or \let\box@dir\yoko
+ \else \let\box@dir\utod
+ \fi
+ \fi
+ \setlength{\@tempdima}{#2}%
+ \ifdim\@tempdima<\z@ \hbox{\box@dir#4}\else
+ \hb@xt@\@tempdima{\box@dir
+ \if #3l\relax\else\hss\fi
+ #4\relax
+ \if #3r\relax\else\hss\fi}\fi\egroup}
+
+%%% picture
+\def\picture{\@ifnextchar<%>
+ {\X@picture}{\X@picture<Z>}}
+\def\X@picture<#1>(#2,#3){\@ifnextchar(%)
+ {\@@picture<#1>(#2,#3)}{\@@picture<#1>(#2,#3)(0,0)}}
+\newdimen\@picwd
+\def\ltj@@pic@reset@blshift{%
+ \ltj@yablshift\z@\ltj@ykblshift\z@
+ \ltj@tablshift\z@\ltj@tkblshift\z@
+}%
+\def\@@picture<#1>(#2,#3)(#4,#5){%
+ \edef\ltj@@pic@save@blshift{%
+ \noexpand\ltj@yablshift\the\ltj@yablshift\noexpand\relax
+ \noexpand\ltj@ykblshift\the\ltj@ykblshift\noexpand\relax
+ \noexpand\ltj@tablshift\the\ltj@tablshift\noexpand\relax
+ \noexpand\ltj@tkblshift\the\ltj@tkblshift\noexpand\relax
+ }%
+ \bgroup\let\box@dir\relax
+ \if #1z\relax
+ \ifnum\ltjgetparameter{direction}=3 \relax
+ \let\box@dir\utod
+ \fi
+ \else
+ \if #1y\relax \let\box@dir\yoko
+ \else\if #1t\relax\let\box@dir\tate
+ \else\if #1d\relax\let\box@dir\dtou
+ \else\if #1u\relax\let\box@dir\utod
+ \fi\fi\fi\fi
+ \fi
+ \ifx\box@dir\relax
+ \ifcase\ltjgetparameter{direction}
+ \or \let\box@dir\dtou
+ \or\or\let\box@dir\tate
+ \or \let\box@dir\yoko
+ \else \let\box@dir\utod
+ \fi
+ \fi
+ \@picwd=#2\unitlength \@picht=#3\unitlength
+ \setbox\@picbox\hbox to\@picwd\bgroup\box@dir
+ \hskip-#4\unitlength\lower#5\unitlength\hbox\bgroup
+ \ltj@@pic@reset@blshift
+ \ignorespaces}
+\def\endpicture{%
+ \egroup\hss\egroup
+ \setbox0=\hbox{\box@dir%
+ \ltjsetht\@picbox\@picht \ltjsetdp\@picbox\z@
+ }%
+ \@tempswafalse
+ \ifnum\ltjgetparameter{direction}=3 \@tempswatrue\fi
+ \ifnum\ltjgetparameter{direction}=11 \@tempswatrue\fi
+ \if@tempswa
+ \ifx\box@dir\yoko % ã“ã®å ´åˆã ã‘åž‚ç›´ä½ç½®è£œæ­£ãŒå¿…è¦
+ \ltjsetht\@picbox\dimexpr\ltjgetht\@picbox+\ltjgetdp\@picbox\relax
+ \ltjsetdp\@picbox\z@
+ \fi
+ \fi
+ \mbox{\box\@picbox}%
+ \egroup\ltj@@pic@save@blshift}
+\let\org@put\put
+\def\put{\ltj@@pic@reset@blshift\org@put}
+\let\org@line\line
+\def\line{\ltj@@pic@reset@blshift\org@line}
+\let\org@vector\vector
+\def\vector{\ltj@@pic@reset@blshift\org@vector}
+\let\org@dashbox\dashbox
+\def\dashbox{\ltj@@pic@reset@blshift\org@dashbox}
+\let\org@oval\oval
+\def\oval{\ltj@@pic@reset@blshift\org@oval}
+\let\org@circle\circle
+\def\circle{\ltj@@pic@reset@blshift\org@circle}
+
+%%% rensuji
+\newif\ifnot@advanceline
+\newskip\rensujiskip
+\rensujiskip=0.25\chs plus.25\zw minus.25\zw
+\DeclareRobustCommand\rensuji{%
+ \@ifstar{\not@advancelinetrue\@rensuji}{\@rensuji}}
+\def\@rensuji{\@ifnextchar[{\@@rensuji}{\@@rensuji[c]}}
+\def\@@rensuji[#1]#2{%
+ \ifvmode\leavevmode\fi
+ \ifnum\ltjgetparameter{direction}=4\relax\hbox{#2}\else
+ \hskip\rensujiskip
+ \setbox\tw@\hbox{æ¼¢}% 「ã‚ã€ã§ã¯ä»®å書体使用時ãŒã¾ãšãã†
+ \@tempdimb\ltjgetht\tw@ \advance\@tempdimb\ltjgetdp\tw@
+ \ifnot@advanceline\not@advancelinefalse\else
+ \setbox\z@\hbox{\yoko#2}%
+ \@tempdima\ltjgetht\z@ \advance\@tempdima\ltjgetdp\z@
+ \ifnum\ltjgetparameter{direction}=1\relax
+ % 周囲㌠dtou ã®å ´åˆã«ã¯ï¼Œé«˜ã• \ltjgetht\tw@, 深㕠\ltjgetdp\tw@ ã®ãƒœãƒƒã‚¯ã‚¹ã‚’基準ã¨ã—ã¦ã„る.
+ \if #1c\relax\vrule \@width \z@ \@height\dimexpr.5\@tempdima+.5\ltjgetht\tw@-.5\ltjgetdp\tw@
+ \@depth\dimexpr.5\@tempdima-.5\ltjgetht\tw@+.5\ltjgetdp\tw@
+ \else\if #1l\relax\vrule\@width \z@\@height\ltjgetht\tw@ \@depth\dimexpr\@tempdima-\ltjgetht\tw@
+ \else\vrule\@width \z@ \@height\dimexpr\@tempdima-\ltjgetdp\tw@ \@depth\ltjgetdp\tw@
+ \fi\fi
+ \else
+ % 周囲㌠tate, utod ã®å ´åˆã‚‚åŒã˜
+ \if #1c\relax\vrule \@width \z@ \@height\dimexpr.5\@tempdima+.5\ltjgetht\tw@-.5\ltjgetdp\tw@
+ \@depth\dimexpr.5\@tempdima-.5\ltjgetht\tw@+.5\ltjgetdp\tw@
+ \else\if #1r\relax\vrule\@width \z@\@height\ltjgetht\tw@ \@depth\dimexpr\@tempdima-\ltjgetht\tw@
+ \else\vrule\@width \z@ \@height\dimexpr\@tempdima-\ltjgetdp\tw@ \@depth\ltjgetdp\tw@
+ \fi\fi
+ \fi
+ \fi
+ \ifnum\ltjgetparameter{direction}=1\relax
+ \if #1c\relax\hbox to\@tempdimb{\yoko\hss#2\hss\kern-\ltjgetdp\tw@}%
+ \else\if #1r\relax\vbox{\hbox to\@tempdimb{\yoko\hss#2\kern-\ltjgetdp\tw@}}%
+ \else\lower\ltjgetdp\tw@\vtop{\hbox to\@tempdimb{\yoko#2\hss}}%
+ \fi\fi
+ \else
+ \if #1c\relax\raise\dimexpr.5\@tempdimb-\ltjgetdp\tw@
+ \hbox to\@tempdimb{\yoko \hss#2\hss}%
+ \else\if #1r\relax\raise\dimexpr.5\@tempdimb-\ltjgetdp\tw@
+ \vbox{\hbox to\@tempdimb{\yoko\hss#2}}%
+ \else\raise\dimexpr.5\@tempdimb-\ltjgetdp\tw@
+ \vtop{\hbox to\@tempdimb{\yoko #2\hss}}%
+ \fi\fi
+ \fi
+ \hskip\rensujiskip
+\fi}
+\let\Rensuji\rensuji
+\let\prensuji\rensuji
+
+%%% kanji
+\def\Kanji#1{\expandafter\@Kanji\csname c@#1\endcsname}
+\def\@Kanji#1{\kansuji #1}
+\def\kanji{\ifnum\ltjgetparameter{direction}=3 \expandafter\kansuji\fi}
+
+%%% bou
+%%%
+\def\boutenchar{\char\euc"A1A2}%"
+\def\bou#1{\ifvmode\leavevmode\fi\@bou#1\end}
+\def\@bou#1{%
+ \ifx#1\end \let\ltj@@next=\relax
+ \else
+ \ifnum\ltjgetparameter{direction}=3\relax
+ \hbox to\z@{\vbox to\z@{\boxmaxdepth\maxdimen
+ \vss\moveleft0.2\zw\hbox{\yoko\boutenchar}\nointerlineskip
+ \hbox{\char\euc"A1A1}}\hss}\nobreak#1\relax
+ \else
+ \hbox to\z@{\vbox to\z@{\boxmaxdepth\maxdimen
+ \vss\moveleft-0.2\zw\hbox{\boutenchar}\nointerlineskip
+ \hbox{\char\euc"A1A1}}\hss}\nobreak#1\relax
+ \fi
+ \let\ltj@@next=\@bou
+ \fi\ltj@@next}
+
+%%% kasen
+\def\kasen#1{%
+ \ifnum\ltjgetparameter{direction}=3\relax
+ \setbox\z@\hbox{#1}\leavevmode\raise.7\zw
+ \hbox to\z@{\vrule\@width\wd\z@ \@depth\z@ \@height.4\p@\hss}%
+ \box\z@
+ \else\underline{#1}\fi}
+
+%%% references
+\def\@eqnnum{{\reset@font\rmfamily \normalcolor
+ \ifnum\ltjgetparameter{direction}=11\raise.25\zh\hbox{\yoko(\theequation)}%
+ \else (\theequation)\fi}}
+\def\@thecounter#1{\noexpand\rensuji{\noexpand\arabic{#1}}}
+\def\@thmcounter#1{\noexpand\rensuji{\noexpand\arabic{#1}}}
+
+%% Compatibility with array package
+
+\def\ltj@lltjext@patch@array{%
+ \patchcmd{\@tabular}{\hbox\bgroup}{%
+ \hbox\bgroup\ltj@ext@dir=\ltjgetparameter{direction}}{}{}
+ \pretocmd{\array}%
+ {\ltj@ext@dir=\ltjgetparameter{direction}\relax}{}{}
+ \expandafter\let\csname tabular*\endcsname=\ltj@lltjext@orig@tabularS
+ \patchcmd{\p@stabular}{\p@tabular}{\@tabular}{}{}
+ \@ifpackagelater{array}{2018/09/13}
+ {\expandafter\@firstoftwo}
+ {\expandafter\@secondoftwo}
+ {% = for 2018/09/13 v2.4i or newer
+ \def\@startpbox##1{\bgroup
+ \color@begingroup
+ \box@dir\adjustbaseline%%% ã“れを追加
+ \setlength\hsize{##1}\@arrayparboxrestore
+ \everypar{%
+ \vrule \@height \ltjgetht\@arstrutbox \@width \z@
+ \everypar{}}%
+ }%
+ }{ % = for 2018/04/30 v2.4h or older
+ \def\@startpbox##1{\bgroup
+ \box@dir\adjustbaseline%%% ã“れを追加
+ \setlength\hsize{##1}\@arrayparboxrestore
+ \everypar{%
+ \vrule \@height \ltjgetht\@arstrutbox \@width \z@
+ \everypar{}}%
+ }%
+ }%
+ \def\@tabarray{\@ifnextchar<\p@tabarray{\p@tabarray<z>}}
+ \def\p@array<##1>[##2]##3{%
+ \let\box@dir\relax
+ \if ##1z\relax
+ \ifnum\ltj@ext@dir=3\relax
+ \let\box@dir\utod\@tempcnta=\zstrutbox
+ \fi
+ \else
+ \if ##1y\relax
+ \let\box@dir\yoko\@tempcnta=\ystrutbox
+ \else\if ##1t\relax
+ \let\box@dir\tate\@tempcnta=\tstrutbox
+ \else\if ##1d\relax
+ \let\box@dir\dtou\@tempcnta=\dstrutbox
+ \else\if ##1u\relax
+ \let\box@dir\utod\@tempcnta=\zstrutbox
+ \fi\fi\fi\fi
+ \fi
+ \ifx\box@dir\relax
+ \ifcase\ltj@ext@dir
+ \or \let\box@dir\dtou\@tempcnta=\dstrutbox% dtou
+ \or\or\let\box@dir\tate\@tempcnta=\tstrutbox% tate
+ \or \let\box@dir\yoko\@tempcnta=\ystrutbox% yoko
+ \else \let\box@dir\utod\@tempcnta=\zstrutbox% utod
+ \fi
+ \fi
+ \setbox \@arstrutbox \hbox{\box@dir\vrule
+ \@height \arraystretch
+ \dimexpr \ltjgetht\@tempcnta+\extrarowheight\relax
+ \@depth \arraystretch \ltjgetdp \@tempcnta
+ \@width \z@}%
+ \fork@array@option<##1>[##2]%
+ \begingroup
+ \@mkpream{##3}%
+ \xdef\@preamble{\ialign \noexpand \@halignto
+ \bgroup \tabskip \z@skip \@arstrut \@preamble
+ \tabskip \z@ \cr}%
+ \endgroup
+ \@arrayleft
+ \@begin@alignbox\bgroup\box@dir\adjustbaseline
+ \let\par\@empty
+ \let\@sharp####\let\protect\relax
+ \let\\\@arraycr\let\tabularnewline\\\let\par\@empty
+ \lineskip\z@skip\baselineskip\z@skip\@preamble}
+ \def\endarray{\crcr\egroup\egroup\@end@alignbox\@arrayright}
+}
+
+\@ifpackageloaded{array}{%
+ \let\tabular=\ltj@lltjext@orig@tabular
+ \let\array=\ltj@lltjext@orig@array
+ \ltj@lltjext@patch@array
+}{%
+ \let\ltj@lltjext@orig@tabular\relax
+ \let\ltj@lltjext@orig@array\relax
+ \RequirePackage{filehook,etoolbox}
+ \AtEndOfPackageFile{array}{\ltj@lltjext@patch@array}
+}
+
+%%%%%%%%%%%%%%%% LuaTeX-ja original
+
+%%\define@key[ltj]{japaram}{autouprightnum}{% %COUNT
+%% \ltj@@set@stack{AURN}{0}{10000}\z@#1 }
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/ltj-adjust.lua b/macros/luatex/generic/luatexja/src/ltj-adjust.lua
new file mode 100644
index 0000000000..3d7e31e0c4
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-adjust.lua
@@ -0,0 +1,551 @@
+--
+-- ltj-adjust.lua
+--
+luatexja.load_module('base'); local ltjb = luatexja.base
+luatexja.load_module('jfont'); local ltjf = luatexja.jfont
+luatexja.load_module('jfmglue'); local ltjj = luatexja.jfmglue
+luatexja.load_module('stack'); local ltjs = luatexja.stack
+luatexja.load_module('direction'); local ltjd = luatexja.direction
+luatexja.load_module('lineskip'); local ltjl = luatexja.lineskip
+luatexja.adjust = luatexja.adjust or {}
+
+local to_node = node.direct.tonode
+local to_direct = node.direct.todirect
+
+local setfield = node.direct.setfield
+local setglue = luatexja.setglue
+local getfield = node.direct.getfield
+local getlist = node.direct.getlist
+local getid = node.direct.getid
+local getfont = node.direct.getfont
+local getsubtype = node.direct.getsubtype
+
+local node_traverse_id = node.direct.traverse_id
+local node_new = node.direct.new
+local node_next = node.direct.getnext
+local node_free = node.direct.free
+local node_prev = node.direct.getprev
+local node_tail = node.direct.tail
+local has_attr = node.direct.has_attribute
+local set_attr = node.direct.set_attribute
+local insert_after = node.direct.insert_after
+
+local id_glyph = node.id('glyph')
+local id_kern = node.id('kern')
+local id_hlist = node.id('hlist')
+local id_glue = node.id('glue')
+local id_whatsit = node.id('whatsit')
+local id_penalty = node.id('penalty')
+local attr_icflag = luatexbase.attributes['ltj@icflag']
+local attr_jchar_class = luatexbase.attributes['ltj@charclass']
+local lang_ja = luatexja.lang_ja
+
+local ltjf_font_metric_table = ltjf.font_metric_table
+local ipairs, pairs = ipairs, pairs
+
+local PACKED = luatexja.icflag_table.PACKED
+local LINEEND = luatexja.icflag_table.LINEEND
+local FROM_JFM = luatexja.icflag_table.FROM_JFM
+local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP
+local KANJI_SKIP_JFM = luatexja.icflag_table.KANJI_SKIP_JFM
+local XKANJI_SKIP = luatexja.icflag_table.XKANJI_SKIP
+local XKANJI_SKIP_JFM = luatexja.icflag_table.XKANJI_SKIP_JFM
+
+local get_attr_icflag
+do
+ local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
+ get_attr_icflag = function(p)
+ return (has_attr(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG
+ end
+end
+
+local priority_num = { 0, 0 }
+local at2pr = { {}, {} }
+local at2pr_st, at2pr_sh = at2pr[1], at2pr[2]
+do
+ local priority_table = {{},{}}
+ luatexja.adjust.priority_table = priority_table
+ local tmp = {}
+ local function cmp(a,b) return a[1]>b[1] end -- 大ãã„ã»ã†ãŒå…ˆï¼
+ local function make_priority_table(glue_sign)
+ for i,_ in pairs(tmp) do tmp[i]=nil end
+ if glue_sign==2 then -- shrink
+ for i=0,63 do tmp[#tmp+1] = { (i%8)-4, FROM_JFM+i } end
+ else -- stretch
+ for i=0,63 do tmp[#tmp+1] = { math.floor(i/8)-4, FROM_JFM+i } end
+ end
+ local pt = priority_table[glue_sign]
+ tmp[#tmp+1] = { pt[2]/10, XKANJI_SKIP }
+ tmp[#tmp+1] = { pt[2]/10, XKANJI_SKIP_JFM }
+ tmp[#tmp+1] = { pt[1]/10, KANJI_SKIP }
+ tmp[#tmp+1] = { pt[1]/10, KANJI_SKIP_JFM }
+ tmp[#tmp+1] = { pt[3]/10, -1 }
+ table.sort(tmp, cmp)
+ local a, m, n = at2pr[glue_sign], 10000000, 0
+ for i=1,#tmp do
+ if tmp[i][1]<m then n,m = n+1,tmp[i][1] end
+ a[tmp[i][2]] = n
+ end
+ local o = a[-1]
+ priority_num[glue_sign] = n
+ setmetatable(a, {__index = function () return o end })
+ end
+ luatexja.adjust.make_priority_table = make_priority_table
+end
+
+-- box 内ã§ä¼¸ç¸®ã•ã‚ŒãŸ glue ã®åˆè¨ˆå€¤ã‚’計算
+
+local total_stsh = {{},{}}
+local total_st, total_sh = total_stsh[1], total_stsh[2]
+local get_total_stretched
+do
+local dimensions = node.direct.dimensions
+function get_total_stretched(p)
+-- return value: <補正値(sp)>
+ local ph = getlist(p)
+ if not ph then return 0 end
+ for i,_ in pairs(total_st) do total_st[i]=nil; total_sh[i]=nil end
+ for i=1,priority_num[1] do total_st[i]=0 end
+ for i=1,priority_num[2] do total_sh[i]=0 end
+ for i=0,4 do total_st[i*65536]=0; total_sh[i*65536]=0 end
+ for q in node_traverse_id(id_glue, ph) do
+ local a = getfield(q, 'stretch_order')
+ if a==0 then
+ local b = at2pr_st[get_attr_icflag(q)];
+ total_st[b] = total_st[b]+getfield(q, 'stretch')
+ end
+ total_st[a*65536] = total_st[a]+getfield(q, 'stretch')
+ local a = getfield(q, 'shrink_order')
+ if a==0 then
+ local b = at2pr_sh[get_attr_icflag(q)];
+ total_sh[b] = total_sh[b]+getfield(q, 'shrink')
+ end
+ total_sh[a*65536] = total_sh[a]+getfield(q, 'shrink')
+ end
+ for i=4,1,-1 do if total_st[i*65536]~=0 then total_st.order=i; break end; end
+ if not total_st.order then
+ total_st.order, total_st[-65536] = -1,0.1 -- dummy
+ end
+ for i=4,1,-1 do if total_sh[i*65536]~=0 then total_sh.order=i; break end; end
+ if not total_sh.order then
+ total_sh.order, total_sh[-65536] = -1,0.1 -- dummy
+ end
+ return getfield(p,'width') - dimensions(ph)
+end
+end
+
+-- step 1: 行末㫠kern を挿入(å¥èª­ç‚¹ï¼Œä¸­ç‚¹ç”¨ï¼‰
+local abs = math.abs
+local ltjd_glyph_from_packed = ltjd.glyph_from_packed
+local function aw_step1(p, total)
+ local head = getlist(p)
+ local x = node_tail(head); if not x then return total, false end
+ -- x: \rightskip
+ x = node_prev(x); if not x then return total, false end
+ local xi, xc = getid(x)
+ -- x may be penalty
+ while xi==id_penalty do
+ x = node_prev(x); if not x then return total, false end
+ xi = getid(x)
+ end
+ if (total>0 and total_st.order>0) or (total<0 and total_sh.order>0) then
+ -- ç„¡é™å¤§ã®ã‚°ãƒ«ãƒ¼ã§å‡¦ç†ãŒè¡Œã‚ã‚Œã¦ã„ã‚‹ã¨ãã¯å‡¦ç†ä¸­æ­¢ï¼Ž
+ return total, false
+ end
+ if xi == id_glyph and getfield(x, 'lang')==lang_ja then
+ -- 和文文字
+ xc = x
+ elseif xi == id_hlist and get_attr_icflag(x) == PACKED then
+ -- packed JAchar
+ xc = ltjd_glyph_from_packed(x)
+ while getid(xc) == id_whatsit do xc = node_next(xc) end -- ã“ã‚Œã¯ãªã‚“ã®ãŸã‚ã«ï¼Ÿ
+ else
+ return total, false-- ãれ以外ã¯å¯¾è±¡å¤–.
+ end
+ local eadt = ltjf_font_metric_table[getfont(xc)]
+ .char_type[has_attr(xc, attr_jchar_class) or 0].end_adjust
+ if not eadt then
+ return total, false
+ end
+ local eadt_ratio = {}
+ for i, v in ipairs(eadt) do
+ local t = total - v
+ if t>0 then
+ eadt_ratio[i] = {i, t/total_st[65536*total_st.order], t, v}
+ else
+ eadt_ratio[i] = {i, t/total_sh[65536*total_sh.order], t, v}
+ end
+ end
+ table.sort(eadt_ratio,
+ function (a,b)
+ for i=2,4 do
+ local at, bt = abs(a[i]), abs(b[i])
+ if at~=bt then return at<bt end
+ end
+ return a[4]<b[4]
+ end)
+ if eadt[eadt_ratio[1][1]]~=0 then
+ local kn = node_new(id_kern, 1)
+ setfield(kn, 'kern', eadt[eadt_ratio[1][1]]); set_attr(kn, attr_icflag, LINEEND)
+ insert_after(head, x, kn)
+ return eadt_ratio[1][3], true
+ else
+ return total, false
+ end
+end
+
+-- step 1 最終行用
+local min, max = math.min, math.max
+local function aw_step1_last(p, total)
+ local head = getlist(p)
+ local x = node_tail(head); if not x then return total, false end
+ -- x: \rightskip
+ pf = node_prev(x); if not x then return total, false end
+ if getid(pf) ~= id_glue or getsubtype(pf) ~= 15 then return total, false end
+ x = node_prev(node_prev(pf)); xi = getid(x)
+ local xi, xc = getid(x)
+ if xi == id_glyph and getfield(x, 'lang')==lang_ja then
+ -- 和文文字
+ xc = x
+ elseif xi == id_hlist and get_attr_icflag(x) == PACKED then
+ -- packed JAchar
+ xc = ltjd_glyph_from_packed(x)
+ while getid(xc) == id_whatsit do xc = node_next(xc) end -- ã“ã‚Œã¯ãªã‚“ã®ãŸã‚ã«ï¼Ÿ
+ else
+ return total, false-- ãれ以外ã¯å¯¾è±¡å¤–.
+ end
+ -- 続行æ¡ä»¶1:無é™ã®ä¼¸ç¸®åº¦ã‚’æŒã¤ã‚°ãƒ«ãƒ¼ã¯ \parfillskipã®ã¿
+ if total>0 and total_st.order>0 then
+ if total_st.order ~= getfield(pf, 'stretch_order') then return total, false end
+ if total_st[total_st.order*65536] ~= getfield(pf, 'stretch') then return total, false end
+ for i=total_st.order-1, 1, -1 do
+ if total_st[i*65536] ~= 0 then return total, false end
+ end
+ end
+ if total<0 and total_sh.order>0 then
+ if total_sh.order ~= getfield(pf, 'shrink_order') then return total, false end
+ if total_sh[total_sh.order*65536] ~= getfield(pf, 'shrink') then return total, false end
+ for i=total_sh.order-1, 1, -1 do
+ if total_sh[i*65536] ~= 0 then return total, false end
+ end
+ end
+ local eadt = ltjf_font_metric_table[getfont(xc)]
+ .char_type[has_attr(xc, attr_jchar_class) or 0].end_adjust
+ if not eadt then
+ return total, false
+ end
+ -- 続行æ¡ä»¶2: min(eadt[1], 0)<= \parfillskip <= max(eadt[#eadt], 0)
+ local pfw = getfield(pf, 'width')
+ + (total>0 and getfield(pf, 'stretch') or -getfield(pf, 'shrink')) *getfield(p, 'glue_set')
+ if pfw<min(0,eadt[1]) or max(0,eadt[#eadt])<pfw then return total, false end
+ -- \parfillskip ã‚’ 0 ã«ã™ã‚‹
+ total = total + getfield(pf, 'width')
+ total_st.order, total_sh.order = 0, 0
+ if getfield(pf, 'stretch_order')==0 then
+ local i = at2pr_st[-1]
+ total_st[0] = total_st[0] - getfield(pf, 'stretch')
+ total_st[i] = total_st[i] - getfield(pf, 'stretch')
+ total_st.order = (total_st[0]==0) and -1 or 0
+ end
+ if getfield(pf, 'shrink_order')==0 then
+ local i = at2pr_sh[-1]
+ total_sh[0] = total_sh[0] - getfield(pf, 'shrink')
+ total_sh[i] = total_sh[i] - getfield(pf, 'shrink')
+ total_sh.order = (total_sh[0]==0) and -1 or 0
+ end
+ setfield(pf, 'subtype', 1); setglue(pf)
+ local eadt_ratio = {}
+ for i, v in ipairs(eadt) do
+ local t = total - v
+ if t>0 then
+ eadt_ratio[i] = {i, t/total_st[65536*total_st.order], t, v}
+ else
+ eadt_ratio[i] = {i, t/total_sh[65536*total_sh.order], t, v}
+ end
+ end
+ table.sort(eadt_ratio,
+ function (a,b)
+ for i=2,4 do
+ local at, bt = abs(a[i]), abs(b[i])
+ if at~=bt then return at<bt end
+ end
+ return a[4]<b[4]
+ end)
+ if eadt[eadt_ratio[1][1]]~=0 then
+ local kn = node_new(id_kern, 1)
+ setfield(kn, 'kern', eadt[eadt_ratio[1][1]]); set_attr(kn, attr_icflag, LINEEND)
+ insert_after(head, x, kn)
+ return eadt_ratio[1][3], true
+ else
+ return total, false
+ end
+end
+
+
+-- step 2: 行中㮠glue を変ãˆã‚‹
+local aw_step2, aw_step2_dummy
+do
+local node_hpack = node.direct.hpack
+local function repack(p)
+ local f = node_hpack(getlist(p), getfield(p, 'width'), 'exactly')
+ setfield(f, 'head', nil)
+ setfield(p, 'glue_set', getfield(f, 'glue_set'))
+ setfield(p, 'glue_order', getfield(f, 'glue_order'))
+ setfield(p, 'glue_sign', getfield(f, 'glue_sign'))
+ node_free(f)
+ return
+end
+function aw_step2_dummy(p, _, added_flag)
+ if added_flag then return repack(p) end
+end
+
+local function clear_stretch(p, ind, ap, name)
+ for q in node_traverse_id(id_glue, getlist(p)) do
+ local f = ap[get_attr_icflag(q)]
+ if f == ind then
+ setfield(q, name..'_order', 0)
+ setfield(q, name, 0)
+ end
+ end
+end
+
+local function set_stretch(p, after, before, ind, ap, name)
+ if before > 0 then
+ local ratio = after/before
+ for q in node_traverse_id(id_glue, getlist(p)) do
+ local f = ap[get_attr_icflag(q)]
+ if (f==ind) and getfield(q, name..'_order')==0 then
+ setfield(q, name, getfield(q, name)*ratio)
+ end
+ end
+ end
+end
+
+function aw_step2(p, total, added_flag)
+ local name = (total>0) and 'stretch' or 'shrink'
+ local id = (total>0) and 1 or 2
+ local res = total_stsh[id]
+ local pnum = priority_num[id]
+ if total==0 or res.order > 0 then
+ -- ã‚‚ã¨ã‚‚ã¨ä¼¸ç¸®ã®å¿…è¦ãªã—ã‹ï¼Œæ®‹ã‚Šã®ä¼¸ç¸®é‡ã¯ç„¡é™å¤§
+ if added_flag then return repack(p) end
+ end
+ total = abs(total)
+ for i = 1, pnum do
+ if total <= res[i] then
+ local a = at2pr[id]
+ for j = i+1,pnum do
+ clear_stretch(p, j, a, name)
+ end
+ set_stretch(p, total, res[i], i, a, name); break
+ end
+ total = total - res[i]
+ end
+ return repack(p)
+end
+end
+
+-- step 1': lineend=extended ã®å ´åˆï¼ˆè¡Œåˆ†å‰²æ™‚ã«è€ƒæ…®ï¼‰ï¼‰
+local insert_lineend_kern
+do
+ local insert_before = node.direct.insert_before
+ local KINSOKU = luatexja.icflag_table.KINSOKU
+ function insert_lineend_kern(head, nq, np, Bp)
+ if nq.met then
+ local eadt = nq.met.char_type[nq.class].end_adjust
+ if not eadt then return end
+ if eadt[1]~=0 then
+ local x = node_new(id_kern, 1)
+ setfield(x, 'kern', eadt[1]); set_attr(x, attr_icflag, LINEEND)
+ insert_before(head, np.first, x)
+ end
+ local eadt_num = #eadt
+ for i=2,eadt_num do
+ local x = node_new(id_penalty)
+ setfield(x, 'penalty', 0); set_attr(x, attr_icflag, KINSOKU)
+ insert_before(head, np.first, x); Bp[#Bp+1] = x
+ local x = node_new(id_kern, 1)
+ setfield(x, 'kern', eadt[i]-eadt[i-1]); set_attr(x, attr_icflag, LINEEND)
+ insert_before(head, np.first, x)
+ end
+ if eadt_num>1 or eadt[1]~=0 then
+ local x = node_new(id_penalty)
+ setfield(x, 'penalty', 0); set_attr(x, attr_icflag, KINSOKU)
+ insert_before(head, np.first, x); Bp[#Bp+1] = x
+ local x = node_new(id_kern, 1)
+ setfield(x, 'kern', -eadt[eadt_num]); set_attr(x, attr_icflag, LINEEND)
+ insert_before(head, np.first, x)
+ local x = node_new(id_penalty)
+ setfield(x, 'penalty', 10000); set_attr(x, attr_icflag, KINSOKU)
+ insert_before(head, np.first, x); Bp[#Bp+1] = x
+ end
+ end
+ end
+end
+
+local adjust_width
+do
+ local myaw_atep1, myaw_step2, myaw_step1_last
+ local dummy = function(p,t,n) return t, false end
+ local ltjs_fast_get_stack_skip = ltjs.fast_get_stack_skip
+ function adjust_width(head)
+ if not head then return head end
+ local last_p
+ for p in node_traverse_id(id_hlist, to_direct(head)) do
+ if last_p then
+ myaw_step2(last_p, myaw_step1(last_p, get_total_stretched(last_p)))
+ end
+ last_p = p
+ end
+ if last_p then
+ myaw_step2(last_p, myaw_step1_last(last_p, get_total_stretched(last_p)))
+ end
+ return to_node(head)
+ end
+ local is_reg = false
+ function enable_cb(status_le, status_pr, status_lp, status_ls)
+ if (status_le>0 or status_pr>0) and (not is_reg) then
+ ltjb.add_to_callback('post_linebreak_filter',
+ adjust_width, 'Adjust width',
+ luatexbase.priority_in_callback('post_linebreak_filter', 'ltj.lineskip')-1)
+ is_reg = true
+ elseif is_reg and (status_le==0 and status_pr==0) then
+ luatexbase.remove_from_callback('post_linebreak_filter', 'Adjust width')
+ is_reg = false
+ end
+ if status_le==2 then
+ if not luatexbase.in_callback('luatexja.adjust_jfmglue', 'luatexja.adjust') then
+ ltjb.add_to_callback('luatexja.adjust_jfmglue', insert_lineend_kern, 'luatexja.adjust')
+ end
+ myaw_step1, myaw_step1_last = dummy, aw_step1_last
+ else
+ if status_le==0 then
+ myaw_step1, myaw_step1_last = dummy, dummy
+ else
+ myaw_step1, myaw_step1_last = aw_step1, aw_step1_last
+ end
+ if luatexbase.in_callback('luatexja.adjust_jfmglue', 'luatexja.adjust') then
+ luatexbase.remove_from_callback('luatexja.adjust_jfmglue', 'luatexja.adjust')
+ end
+ end
+ myaw_step2 = (status_pr>0) and aw_step2 or aw_step2_dummy
+ luatexja.lineskip.setting(
+ status_lp>0 and 'profile' or 'dummy',
+ status_ls>0 and 'step' or 'dummy'
+ )
+ end
+ function disable_cb() -- only for compatibility
+ enable_cs(0,0,0,0)
+ end
+ luatexja.adjust.enable_cb=enable_cb
+ luatexja.adjust.disable_cb=disable_cb
+end
+
+luatexja.unary_pars.adjust = function(t)
+ return is_reg and 1 or 0
+end
+
+-- ----------------------------------
+do
+ local max, ins, sort = math.max, table.insert, table.sort
+ local function insert(package, ind, d, b, e)
+ local bound = package[2]
+ bound[b], bound[e]=true, true
+ ins(package[1], {b,e,[ind]=d})
+ end
+ local function flatten(package)
+ local bd={} for i,_ in pairs(package[2]) do ins(bd,{i}) end
+ sort(bd, function (a,b) return a[1]<b[1] end)
+ local bdc=#bd; local t = package[1]
+ sort(t, function (a,b) return a[1]<b[1] end)
+ local bdi =1
+ for i=1,#t do
+ while bd[bdi][1]<t[i][1] do bdi=bdi+1 end
+ local j = bdi
+ while j<bdc and bd[j+1][1]<=t[i][2] do
+ for k,w in pairs(t[i]) do
+ if k>=3 then
+ bd[j][k]=bd[j][k] and max(bd[j][k],w) or w
+ end
+ end
+ j=j+1
+ end
+ end
+ package[2]=nil; package[1]=nil; package.flatten, package.insert=nil, nil
+ bd[#bd]=nil
+ return bd
+ end
+ function init_range()
+ return {{},{}, insert=insert, flatten=flatten}
+ end
+end
+
+-- -----------------------------------
+luatexja.adjust.step_factor = 0.5
+luatexja.unary_pars.linestep_factor = function(t)
+ return luatexja.adjust.step_factor
+end
+luatexja.adjust.profile_hgap_factor = 1
+luatexja.unary_pars.profile_hgap_factor = function(t)
+ return luatexja.adjust.profile_hgap_factor
+end
+do
+ local insert = table.insert
+ local rangedimensions, max = node.direct.rangedimensions, math.max
+ local function profile_inner(box, range, ind, vmirrored, adj)
+ local w_acc, d_before = getfield(box,'shift'), 0
+ local x = getlist(box); local xn = node_next(x)
+ while x do
+ local w, h, d
+ if xn then w, h, d= rangedimensions(box,x,xn)
+ else w, h, d= rangedimensions(box,x) end
+ if vmirrored then h=d end
+ local w_new = w_acc + w
+ if w>=0 then
+ range:insert(ind, h, w_acc-adj, w_new)
+ else
+ range:insert(ind, h, w_new-adj, w_acc)
+ end
+ w_acc = w_new; x = xn; if x then xn = node_next(x) end
+ end
+ end
+ function ltjl.p_profile(before, after, mirrored, bw)
+ local range, tls
+ = init_range(), luatexja.adjust.profile_hgap_factor*tex.lineskip.width
+ profile_inner(before, range, 3, true, tls)
+ profile_inner(after, range, 4, mirrored, tls)
+ range = range:flatten()
+ do
+ local dmax, d, hmax, h, lmin = 0, 0, 0, 0, 1/0
+ for i,v in ipairs(range) do
+ d, h = (v[3] or 0), (v[4] or 0)
+ if d>dmax then dmax=d end
+ if h>hmax then hmax=h end
+ if bw-h-d<lmin then lmin=bw-h-d end
+ end
+ if lmin==1/0 then lmin = bw end
+ return lmin,
+ bw - lmin - getfield(before, 'depth')
+ - getfield(after, mirrored and 'depth' or 'height')
+ end
+ end
+end
+
+do
+ local ltja = luatexja.adjust
+ local copy_glue = ltjl.copy_glue
+ local floor, max = math.floor, math.max
+ function ltjl.l_step(dist, g, adj, normal, bw, loc)
+ if loc=='alignment' then
+ return ltjl.l_dummy(dist, g, adj, normal, bw, loc)
+ end
+ if dist < tex.lineskiplimit then
+ local f = max(1, bw*ltja.step_factor)
+ copy_glue(g, tex.baselineskip, 1, normal - f * floor((dist-tex.lineskip.width)/f))
+ else
+ copy_glue(g, tex.baselineskip, 2, normal)
+ end
+ end
+end
+
+
diff --git a/macros/luatex/generic/luatexja/src/ltj-base.lua b/macros/luatex/generic/luatexja/src/ltj-base.lua
new file mode 100644
index 0000000000..4182a603c3
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-base.lua
@@ -0,0 +1,403 @@
+--
+-- luatexja/ltj-base.lua
+--
+local ltb = luatexbase
+local tostring = tostring
+local node, table, tex, token = node, table, tex, token
+
+local cat_lp = luatexbase.catcodetables['latex-package']
+
+--------------------
+local ltjb = {}
+luatexja.base = ltjb
+
+local public_name = 'luatexja'
+local public_version = 'alpha'
+ltjb.public_name = public_name
+ltjb.public_version = public_version
+
+
+-------------------- Fully-expandable error messaging
+local _error_set_break, _error_set_message, _error_show
+local generic_error, _generic_warn_info
+local generic_warning, generic_warning_no_line
+local generic_info, generic_info_no_line
+local package_error, package_warning, package_warning_no_line
+local package_info, package_info_no_line
+local ltj_error, ltj_warning_no_line
+
+do
+--! LaTeX å½¢å¼ã®ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸(\PackageError ç­‰)ã‚’
+--! Lua 関数ã®å‘¼ã³å‡ºã—ã§è¡Œã†.
+
+ local LF = "\n"
+ local err_break = ""
+ local err_main = ""
+ local err_help = ""
+
+ local function message_cont(str, c)
+ return str:gsub(err_break, LF .. c)
+ end
+ local function into_lines(str)
+ return str:gsub(err_break, LF):explode(LF)
+ end
+
+ _error_set_break = function (str)
+ err_break = str
+ end
+
+ _error_set_message = function (msgcont, main, help)
+ err_main = message_cont(main, msgcont)
+ err_help = into_lines(help)
+ end
+
+ _error_show = function (escchar)
+ local escapechar = tex.escapechar
+ local newlinechar = tex.newlinechar
+ local errorcontextlines = tex.errorcontextlines
+ if not escchar then tex.escapechar = -1 end
+ tex.newlinechar = 10
+ tex.errorcontextlines = -1
+ tex.error(err_main, err_help)
+ tex.escapechar = escapechar
+ tex.newlinechar = newlinechar
+ tex.errorcontextlines = errorcontextlines
+ end
+
+ local message_a = "Type H <return> for immediate help"
+
+ generic_error = function (msgcont, main, ref, help)
+ local mainref = main..".\n\n"..ref.."\n"..message_a
+ _error_set_message(msgcont, mainref, help)
+ _error_show(true)
+ end
+
+ _generic_warn_info = function (msgcont, main, warn, line)
+ local mainc = message_cont(main, msgcont)
+ local br = warn and "\n" or ""
+ local out = warn and "term and log" or "log"
+ local on_line = line and (" on input line "..tex.inputlineno) or ""
+ local newlinechar = tex.newlinechar
+ tex.newlinechar = -1
+ texio.write_nl(out, br..main..on_line.."."..br)
+ tex.newlinechar = newlinechar
+ end
+
+ generic_warning = function (msgcont, main)
+ _generic_warn_info(msgcont, main, true, true)
+ end
+ generic_warning_no_line = function (msgcont, main)
+ _generic_warn_info(msgcont, main, true, false)
+ end
+ generic_info = function (msgcont, main)
+ _generic_warn_info(msgcont, main, false, true)
+ end
+ generic_info_no_line = function (msgcont, main)
+ _generic_warn_info(msgcont, main, false, false)
+ end
+
+ package_error = function (pkgname, main, help)
+ generic_error("("..pkgname.." ",
+ "Package "..pkgname.." Error: "..main,
+ "See the "..pkgname.." package documentation for explanation.",
+ help)
+ end
+ package_warning = function (pkgname, main)
+ generic_warning("("..pkgname.." ",
+ "Package "..pkgname.." Warning: "..main)
+ end
+ package_warning_no_line = function (pkgname, main)
+ generic_warning_no_line("("..pkgname.." ",
+ "Package "..pkgname.." Warning: "..main)
+ end
+ package_info = function (pkgname, main)
+ generic_info("("..pkgname.." ",
+ "Package "..pkgname.." Info: "..main)
+ end
+ package_info_no_line = function (pkgname, main)
+ generic_info_no_line("("..pkgname.." ",
+ "Package "..pkgname.." Info: "..main)
+ end
+
+ ltj_error = function (main, help)
+ package_error(public_name, main, help)
+ end
+ ltj_warning_no_line = function (main)
+ package_warning_no_line(public_name, main, help)
+ end
+
+end
+-------------------- TeX stream I/O
+--! ixbase.print() ã¨åŒã˜
+--- Extension to tex.print(). Each argument string may contain
+-- newline characters, in which case the string is output (to
+-- TeX input stream) as multiple lines.
+-- @param ... (string) string to output
+local function mprint(...)
+ local arg = {...}
+ local lines = {}
+ if type(arg[1]) == "number" then
+ table.insert(lines, arg[1])
+ table.remove(arg, 1)
+ end
+ for _, cnk in ipairs(arg) do
+ local ls = cnk:explode("\n")
+ if ls[#ls] == "" then
+ table.remove(ls, #ls)
+ end
+ for _, l in ipairs(ls) do
+ table.insert(lines, l)
+ end
+ end
+ return tex.print(unpack(lines))
+end
+ltjb.mprint = mprint
+
+-------------------- Handling of TeX values
+do
+
+--! ixbase.to_dimen() ã¨åŒã˜
+ local function to_dimen(val)
+ if val == nil then
+ return 0
+ elseif type(val) == "number" then
+ return val
+ else
+ return tex.sp(tostring(val))
+ end
+ end
+
+ local function parse_dimen(val)
+ val = tostring(val):lower()
+ local r, fil = val:match("([-.%d]+)fi(l*)")
+ if r then
+ val, fil = r.."pt", fil:len() + 1
+ else
+ fil = 0
+ end
+ return tex.sp(val), fil
+ end
+
+ ltjb.to_dimen = to_dimen
+end
+
+-------------------- Virtual table for LaTeX counters
+-- not used in current LuaTeX-ja
+do
+--! ixbase.counter ã¨åŒã˜
+ counter = {}
+ local mt_counter = {}
+ setmetatable(counter, mt_counter)
+
+ function mt_counter.__index(tbl, key)
+ return tex.count['c@'..key]
+ end
+ function mt_counter.__newindex(tbl, key, val)
+ tex.count['c@'..key] = val
+ end
+ ltjb.counter = counter
+
+--! ixbase.length 㯠tex.skip ã¨å…¨ãåŒã˜ãªã®ã§ä¸è¦.
+end
+
+-------------------- common error message
+do
+ local function in_unicode(c, admit_math)
+ local low = admit_math and -1 or 0
+ if type(c)~='number' or c<low or c>0x10FFFF then
+ local s = 'A character number must be between ' .. tostring(low)
+ .. ' and 0x10ffff.\n'
+ .. (admit_math and "(-1 is used for denoting `math boundary')\n" or '')
+ .. 'So I changed this one to zero.'
+ package_error('luatexja',
+ 'bad character code (' .. tostring(c) .. ')', s)
+ c=0
+ end
+ return c
+ end
+ ltjb.in_unicode = in_unicode
+end
+
+-------------------- cache management
+-- load_cache (filename, outdate)
+-- * filename: without suffix '.lua'
+-- * outdate(t): return true iff the cache is outdated
+-- * return value: non-nil iff the cache is up-to-date
+-- save_cache (filename, t): no return value
+-- save_cache_luc (filename, t): no return value
+-- save_cache always calls save_cache_luc.
+-- But sometimes we want to create only the precompiled cache,
+-- when its 'text' version is already present in LuaTeX-ja distribution.
+
+require('lualibs-lpeg') -- string.split
+require('lualibs-os') -- os.type
+
+do
+ local kpse_var_value = kpse.var_value
+ local path, pathtmp = kpse_var_value("TEXMFVAR")
+ pathtmp = kpse_var_value("TEXMFSYSVAR")
+ if pathtmp then path = (path and path .. ';' or '') .. pathtmp end
+ pathtmp = kpse_var_value("TEXMFCACHE")
+ if pathtmp then path = (path and path .. ';' or '') .. pathtmp end
+
+ if os.type~='windows' then path = string.gsub(path, ':', ';') end
+ path = table.unique(string.split(path, ';'))
+
+ local cache_dir = '/luatexja'
+ local find_file = kpse.find_file
+ local join, isreadable = file.join, file.isreadable
+ local tofile, serialize = table.tofile, table.serialize
+ local luc_suffix = jit and '.lub' or '.luc'
+
+ -- determine save path
+ local savepath = ''
+ for _,v in pairs(path) do
+ local testpath = join(v, cache_dir)
+ if not lfs.isdir(testpath) then dir.mkdirs(testpath) end
+ if lfs.isdir(testpath) then savepath = testpath; break end
+ end
+
+ local function save_cache_luc(filename, t, serialized)
+ local fullpath = savepath .. '/' .. filename .. luc_suffix
+ local s = serialized or serialize(t, 'return', false)
+ if s then
+ local sa = load(s)
+ local f = io.open(fullpath, 'wb')
+ if f and sa then
+ f:write(string.dump(sa, true))
+ texio.write('(save cache: ' .. fullpath .. ')')
+ end
+ f:close()
+ end
+ end
+
+ local function save_cache(filename, t)
+ local fullpath = savepath .. '/' .. filename .. '.lua'
+ local s = serialize(t, 'return', false)
+ if s then
+ local f = io.open(fullpath, 'w')
+ if f then
+ f:write(s)
+ texio.write('(save cache: ' .. fullpath .. ')')
+ end
+ f:close()
+ save_cache_luc(filename, t, s)
+ end
+ end
+
+ local function load_cache_a(filename, outdate)
+ local result
+ for _,v in pairs(path) do
+ local fn = join(v, cache_dir, filename)
+ if isreadable(fn) then
+ texio.write('(load cache: ' .. fn .. ')')
+ result = loadfile(fn)
+ result = result and result(); break
+ end
+ end
+ if (not result) or outdate(result) then
+ return nil
+ else
+ return result
+ end
+ end
+
+ local function load_cache(filename, outdate)
+ local r = load_cache_a(filename .. luc_suffix, outdate)
+ if r then
+ return r
+ else
+ local r = load_cache_a(filename .. '.lua', outdate)
+ if r then save_cache_luc(filename, r) end -- update the precompiled cache
+ return r
+ end
+ end
+
+ local function remove_file_if_exist(name)
+ if os.rename(name,name) then os.remove(name) end
+ end
+ local function remove_cache (filename)
+ local fullpath_wo_ext = savepath .. '/' .. filename .. '.lu'
+ remove_file_if_exist(fullpath_wo_ext .. 'a')
+ remove_file_if_exist(fullpath_wo_ext .. 'b')
+ remove_file_if_exist(fullpath_wo_ext .. 'c')
+ end
+
+ ltjb.remove_cache = remove_cache
+ ltjb.load_cache = load_cache
+ ltjb.save_cache_luc = save_cache_luc
+ ltjb.save_cache = save_cache
+end
+
+----
+do
+ local tex_set_attr, tex_get_attr = tex.setattribute, tex.getattribute
+ function ltjb.ensure_tex_attr(a, v)
+ if tex_get_attr(a)~=v then
+ tex_set_attr(a, v)
+ end
+ end
+end
+----
+
+ltjb._error_set_break = _error_set_break
+ltjb._error_set_message = _error_set_message
+ltjb._error_show = _error_show
+ltjb._generic_warn_info = _generic_warn_info
+
+ltjb.package_error = package_error
+ltjb.package_warning = package_warning
+ltjb.package_warning_no_line = package_warning_no_line
+ltjb.package_info = package_info
+ltjb.package_info_no_line = package_info_no_line
+
+ltjb.generic_error = generic_error
+ltjb.generic_warning = generic_warning
+ltjb.generic_warning_no_line = generic_warning_no_line
+ltjb.generic_info = generic_info
+ltjb.generic_info_no_line = generic_info_no_line
+
+ltjb.ltj_warning_no_line = ltj_warning_no_line
+ltjb.ltj_error = ltj_error
+
+---- deterministic version of luatexbase.add_to_callback
+function ltjb.add_to_callback(name,fun,description,priority)
+ local priority= priority
+ if priority==nil then
+ priority=#luatexbase.callback_descriptions(name)+1
+ end
+ if(luatexbase.callbacktypes[name] == 3 and
+ priority == 1 and
+ #luatexbase.callback_descriptions(name)==1) then
+ luatexbase.module_warning("luatexbase",
+ "resetting exclusive callback: " .. name)
+ luatexbase.reset_callback(name)
+ end
+ local saved_callback={},ff,dd
+ for k,v in ipairs(luatexbase.callback_descriptions(name)) do
+ if k >= priority then
+ ff,dd= luatexbase.remove_from_callback(name, v)
+ saved_callback[#saved_callback+1]={ff,dd}
+ end
+ end
+ luatexbase.base_add_to_callback(name,fun,description)
+ for _,v in ipairs(saved_callback) do
+ luatexbase.base_add_to_callback(name,v[1],v[2])
+ end
+ return
+end
+
+-------------------- mock of debug logger
+if not ltjb.out_debug then
+ local function no_op() end
+ ltjb.start_time_measure = no_op
+ ltjb.stop_time_measure = no_op
+ ltjb.out_debug = no_op
+ ltjb.package_debug = no_op
+ ltjb.debug_logger = function() return no_op end
+ ltjb.show_term = no_op
+ ltjb.show_log = no_op
+end
+
+-------------------- all done
+-- EOF
diff --git a/macros/luatex/generic/luatexja/src/ltj-base.sty b/macros/luatex/generic/luatexja/src/ltj-base.sty
new file mode 100644
index 0000000000..717105e3a5
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-base.sty
@@ -0,0 +1,472 @@
+%
+% ltj-base.sty
+%
+
+%! ã“ã‚Œã¯å¤–ã‹ã‚‰èª­ã¾ã‚Œãªã„
+%% Avoid multiple loading.
+\csname luatexjabaseLoaded\endcsname
+\edef\ltj@base@AtEnd{%
+\endlinechar=\the\endlinechar
+\relax}
+\endlinechar=-1 %
+\def\luatexjabaseLoaded{\endinput}
+
+\ifltj@in@latex %<*LaTeX>
+ \NeedsTeXFormat{LaTeX2e}
+ \ProvidesPackage{ltj-base}[2017/05/05]
+\fi %</LaTeX>
+
+%%------------------ Tiny helpers
+
+%% Registers
+%\newcount\ltj@tempcnta % defined at luatexja-core.sty
+\newcount\ltj@tempcntb
+\newcount\ltj@tempcntc
+\newdimen\ltj@tempdima
+% \newskip\ltj@tempskipa unused
+% \newtoks\ltj@temptoks unused
+
+\countdef\ltj@@count@zero=0 %
+\luatexattributedef\ltj@@attr@zero=0 %
+\dimendef\ltj@@dimen@zero=0 %
+\skipdef\ltj@@skip@zero=0 %
+
+%% Quarks
+%! ãŸã  expl3 ã® quark ã¨ã¯ç•°ãªã‚Šå±•é–‹ã•ã‚Œã‚‹ã¨ã‚¨ãƒ©ãƒ¼ã«ãªã‚‹.
+%% \ltj@q@stop
+\protected\def\ltj@q@stop{\ltj@q@stop@}
+%% \ltj@q@nil
+\protected\def\ltj@q@nil{\ltj@q@nil@}
+%% \ltj@q@mark
+\protected\def\ltj@q@mark{\ltj@q@mark@}
+
+%! etoolbox ã® \letcs, \cslet, \csletcs.
+%% \ltj@letcs
+\protected\def\ltj@letcs#1#2{
+ \expandafter\let\expandafter#1\csname#2\endcsname
+}
+
+%% \ltj@cslet
+\protected\def\ltj@cslet#1#2{
+ \expandafter\let\csname#1\endcsname#2
+}
+
+%% \ltj@csletcs
+\protected\def\ltj@csletcs#1#2{
+ \expandafter\let\csname#1\expandafter\endcsname
+ \csname#2\endcsname
+}
+
+%% \ltj@ifx{<sutff>}{<yes>}{<no>}
+%! LaTeX å½¢å¼ã® \ifx. ã“ã®å½¢å¼ã®åˆ©ç‚¹ã¯è‡ªå‹•çš„ã«æ¡ä»¶ãƒã‚¹ãƒˆã‹ã‚‰ã®
+%! 脱出ãŒå¯èƒ½ã§ã‚ã‚‹ã“ã¨.
+% Does \ifx<stuff> test in LaTeX style.
+\long\def\ltj@ifx#1{
+ \ifx#1\expandafter\ltx@firstoftwo
+ \else\expandafter\ltx@secondoftwo\fi
+}
+
+%% \ltj@if@empty{<stuff>}{<yes>}{<no>}
+%! <stuff> ãŒç©ºã§ã‚ã‚‹ã‹.
+% Checks if <stuff> is empty.
+\long\def\ltj@if@empty#1{
+ \ltj@ifx{\ltj@@q@empty#1\ltj@@q@empty}
+}
+\protected\def\ltj@@q@empty{\ltj@@q@empty@}
+
+%% \ltj@if@blank{<stuff>}{<yes>}{<no>}
+%! <stuff> ãŒç©ºã¾ãŸã¯ç©ºç™½æ–‡å­—ã‹ã‚‰ãªã‚‹ã‹.
+% Checks if <stuff> is either empty or consisting only of spaces.
+\def\ltj@if@blank#1{
+ \ltj@@if@blankA#1\ltj@@q@empty\ltj@@q@empty
+ \ltx@secondoftwo\ltx@firstoftwo\ltj@q@nil
+}
+\long\def\ltj@@if@blankA#1#2\ltj@@q@empty#3#4#5\ltj@q@nil{
+ #4
+}
+
+%%------------------ LaTeX vs plain
+\ifltj@in@latex %<*LaTeX>
+
+%% \ifltj@in@latex
+%! LaTeX ã§ã‚ã‚‹ã‹.
+%(Defined in luatexja-core.sty.)
+
+%% \ifltj@in@plain
+%! plain ã§ã‚ã‚‹ã‹.
+\ltj@csletcs{ifltj@in@plain}{iffalse}
+
+%% \ltj@require@package{<package>}{<date>}
+%! サブパッケージを読ã¿è¾¼ã‚€. LaTeX ã§ã¯ \RequirePackageã€ãれ以外ã§ã¯
+%! \input を使ã†. <date> ã¯å¿…é ˆã ãŒç©ºã§ã‚‚よã„.
+\def\ltj@require@package#1#2{
+ \RequirePackage{#1}[#2]
+}
+
+%% \ltj@print{<message>}
+%! 端末ã¸ã®å‡ºåŠ›.
+\let\ltj@print\typeout
+
+\else %<*!LaTeX>
+
+%% \ifltj@in@plain
+\ifnum\pdf@strcmp{\fmtname}{plain}=0 %
+ \ltj@csletcs{ifltj@in@plain}{iftrue}
+\else
+ \ltj@csletcs{ifltj@in@plain}{iffalse}
+\fi
+
+%% \ltj@require@package{<package>}{<date>}
+\def\ltj@require@package#1#2{
+ \input #1.sty\relax
+}
+
+%% \ltj@print{<message>}
+\def\ltj@print#1{
+ \immediate\write16{#1}
+}
+
+\fi %</LaTeX>
+%%------------------ Value-token handling
+
+%% helper stuffs
+
+%% \ltj@gobble@num <number>
+%! 次ã«ç¶šãæ•´æ•°ã‚’(2 回展開ã§)読ã¿æ¨ã¦ã‚‹.
+\def\ltj@gobble@num{
+ \directlua{token.scan_int()}
+}
+
+%% \ltj@gobble@glue <glue>
+%! 次ã«ç¶šãグルー値を(2 回展開ã§)読ã¿æ¨ã¦ã‚‹.
+\def\ltj@gobble@glue{
+ \directlua{token.scan_glue()}
+}
+
+%% \ltj@gobble@dimen <dimen>
+%! 次ã«ç¶šã寸法値を(2 回展開ã§)読ã¿æ¨ã¦ã‚‹.
+\def\ltj@gobble@dimen{
+ \directlua{token.scan_dimen()}
+}
+
+%% \ltj@grab@num <number>
+%! 次ã«ç¶šã整数を読ã¿å–ã£ã¦, ãã‚Œã¨ç­‰ã—ã„整数を表ã™ãƒˆãƒ¼ã‚¯ãƒ³åˆ—
+%! (å¿…ãšã—も整数表記ã¨ã¯é™ã‚‰ãªã„)ã‚’ { } ã«å…¥ã‚ŒãŸã‚‚ã®ã«(2 回ã§)
+%! 展開ã™ã‚‹.
+%! ãŸã ã—, æ•´æ•°ã¯ä»¥ä¸‹ã®å½¢å¼ã®ã„ãšã‚Œã‹ã§ãªã‘ã‚Œã°ãªã‚‰ãªã„.
+%! - 整数表記(10 進, 8 進, 16 進, 文字)
+%! - chardef トークン
+%! - 内部整数パラメタ, countdef トークン
+%! (command_name ㌠"assign_int" ã§ã‚るトークン).
+%! (注æ„: ã¾ã æ–‡å­—表記(`A)ã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“.)
+\def\ltj@grab@num{
+ \directlua{tex.sprint('{' .. token.scan_int() .. '}')}
+}
+
+%%------------------ Safe passing
+
+% These macros convert a token sequence denoting a TeX value to its
+% suitable notation in Lua, and when the argument is malformed then
+% 'nil' is returned. They are all fully-expandable.
+%! TeX ã®å€¤ã‚’ Lua 上ã®è¡¨è¨˜ã«å¤‰æ›ã™ã‚‹. ä¸æ­£å½¢å¼ã ã¨ nil ã«ã™ã‚‹.
+
+\def\ltj@@safe@end{\noexpand\ltj@@safe@end}
+ % behaves same as \relax but is distinct from it
+
+%% \ltj@safe@invalid
+% The value passed to lua instead of malformed value tokens.
+\def\ltj@safe@invalid{(nil)}
+
+%% \ltj@safe@num{<number>}
+%! æ•´æ•°.
+% For a number (integer).
+\def\ltj@safe@num{
+ \ltj@safe@num@or\ltj@safe@invalid
+}
+\def\ltj@safe@num@or#1#2{
+ \expandafter\expandafter\expandafter\ltj@@safe@numA
+ \ltj@gobble@num#2\ltj@@safe@end{#2}{#1}
+}
+\def\ltj@@safe@numA#1\ltj@@safe@end#2#3{
+ \ltj@if@blank{#1}{
+ (\number#2)
+ }{
+ #3
+ }
+}
+
+%% \ltj@safe@dimen{<dimen>}
+%! 寸法値.
+% For a dimension. The result is a scaled-point value.
+\def\ltj@safe@dimen{
+ \ltj@safe@dimen@or\ltj@safe@invalid
+}
+\def\ltj@safe@dimen@or#1#2{
+ \expandafter\expandafter\expandafter\ltj@@safe@dimenA
+ \ltj@gobble@dimen#2\ltj@@safe@end{#2}{#1}
+}
+\def\ltj@@safe@dimenA#1\ltj@@safe@end#2#3{
+ \ltj@if@blank{#1}{
+ (\number\dimexpr#2\relax)
+ }{
+ #3
+ }
+}
+
+%% \ltj@safe@real{<real>}
+%! 実数. ã“ã‚Œã¯å進表記ã«é™ã‚‹.
+% For a real number given in decimal notation or a macro that
+% expands to such notation.
+\def\ltj@safe@real#1{
+ (tonumber("\luatexluaescapestring{#1}"))
+}
+
+%% \ltj@val@counter{<counter>}
+%! LaTeX カウンタã®ç¾åœ¨å€¤.
+% For the current value of a LaTeX counter.
+\def\ltj@val@counter#1{
+ (\expandafter\number\csname c@#1\endcsname)
+}
+
+%% \ltj@val@skip{<skip>}
+% For the current value of a skip (or LaTeX-length) parameter.
+%! グルーレジスタ(LaTeX é•·ã•å¤‰æ•°).
+%! æ•´å½¢å¼ã®ã‚°ãƒ«ãƒ¼å€¤ã«ã‚‚使ãˆã‚‹.
+\def\ltj@val@skip#1{
+ (luatexja.base.to_skip("\the\glueexpr#1\relax"))
+}
+%! æ•´å½¢å¼ã®æ•´æ•° → 数値 : \number#1
+%! 内部寸法 → 数値 : \number#1
+%! æ•´å½¢å¼ã®å¯¸æ³• → 数値 : \number\dimexpr#1\relax
+
+%% \ltj@safe@str{<text>}
+%! 文字列. (トークン列をéžãƒˆãƒ¼ã‚¯ãƒ³åŒ–)
+% Converts a token sequence to Lua string notation.
+\def\ltj@safe@str#1{
+ "\luatexluaescapestring{\detokenize{#1}}"
+}
+
+%% \ltj@luaescape{<text>}
+%! éžãƒˆãƒ¼ã‚¯ãƒ³åŒ–ã—㦠Lua エスケープ.
+\def\ltj@luaescape#1{
+ \luatexluaescapestring{\detokenize{#1}}
+}
+%% \ltj@luaxescape{<text>}
+%! éžãƒˆãƒ¼ã‚¯ãƒ³åŒ–ã›ãšã«(展開ã‚ã‚Šã§) Lua エスケープ.
+%! ã¤ã¾ã‚Šå˜ãªã‚‹ \luatexescape.
+\let\ltj@luaxescape\luatexluaescapestring
+
+%%------------------ Fully-expandable error messaging
+
+%! ixerrtrick パッケージã‹ã‚‰ç§»æ¤.
+%! 展開é™å®šæ–‡è„ˆã§ã‚‚使ãˆã‚‹ \PackageError ç­‰.
+%! Lua 関数版(luatexja/base.lua å‚ç…§)ã‚‚ã‚ã‚‹.
+
+%% \ltj@@error@message@a
+\begingroup
+\def~{ }
+\xdef\ltj@@error@message@a{%
+ Type~~H <return>~~for immediate help%
+}%
+\endgroup
+
+%%<+> \ltj@MessageBreak
+% An analogue of \MessageBreak that is used in \ltj@GenericError, etc.
+% (\MessageBreak cannot be used there.)
+% NB: It is realized as a macro that expands to two instances
+% of the character of code 127. This marker is later detected
+% by the Lua process.
+\begingroup
+\lccode42=127
+\lowercase{
+ \gdef\ltj@MessageBreak{**}
+ \directlua{
+ luatexja.base._error_set_break("**")
+ }
+}
+\endgroup
+
+%%<+> \ltj@GenericError{<cont>}{<msg-main>}{<msg-ref>}{<msg-help>}
+% A variant of \GenericError that can be used in expansion-only
+% situation. The meanings of arguments are the same as the original
+% \GenericError.
+%%<+> \ltj@PlainError{<msg-main>}{<msg-help>}
+% A simpler error messenger available in expansion-only situations.
+% It behaves similarly to:
+% \errhelp{<msg-help}\errmessage{<msg-main>}
+\begingroup
+% with the same hack as in \GenericError...
+\lccode`\@=`\ %
+\lccode`\~=`\ %
+\lccode`\}=`\ %
+\lccode`\{=`\ %
+\catcode`\ =11\relax%
+\lowercase{%
+\endgroup%
+\def\ltj@GenericError#1#2#3#4{% not protected
+\directlua{%
+luatexja.base._error_set_message("\ltj@luaxescape{#1}",%
+"\ltj@luaxescape{#2.^^J^^J#3^^J\ltj@@error@message@a}",%
+"\ltj@luaxescape{#4}")%
+}%
+\ % use csname with four spaces as last expander
+}
+\def\ {% csname with four spaces
+\directlua{%
+luatexja.base._error_show(false)% and many spaces trail!
+ %
+ %
+}%
+}%
+\def\ltj@PlainError#1#2{%
+\directlua{%
+luatexja.base._error_set_message(" ",%
+"\ltj@luaxescape{#1}",%
+"\ltj@luaxescape{#2}")%
+}%
+\error % again a weird name is used
+}
+\def\error {% csname with two trailing spaces
+\directlua{%
+luatexja.base._error_show(true)% and many spaces trail!
+ %
+ %
+}%
+}%
+}
+
+%% \ltj@@error@on@line
+\def\ltj@@error@on@line{
+ on input line \the \inputlineno
+}
+
+%% \ltj@generic@warn@info
+\def\ltj@@generic@warn@info#1#2#3#4{
+ \begingroup
+ \directlua{
+ luatexja.base._generic_warn_info("\ltj@luaxescape{#3}",
+ "\ltj@luaxescape{#4}", (#1 > 0), (#2 > 0))
+ }
+ \endgroup
+}
+
+%% \ltj@GenericWarning{<cont>}{<msg-main>}
+\def\ltj@GenericWarning{
+ \ltj@@generic@warn@info{1}{1}
+}
+%% \ltj@GenericWarningNoLine{<cont>}{<msg-main>}
+\def\ltj@GenericWarningNoLine{
+ \ltj@@generic@warn@info{1}{0}
+}
+%% \ltj@GenericInfo{<cont>}{<msg-main>}
+\def\ltj@GenericInfo{
+ \ltj@@generic@warn@info{0}{1}
+}
+%% \ltj@GenericInfoNoLine{<cont>}{<msg-main>}
+\def\ltj@GenericInfoNoLine{
+ \ltj@@generic@warn@info{0}{0}
+}
+
+%% \ltj@@space@seq@a
+\begingroup
+\def~{ }
+\xdef\ltj@@space@seq@a{~~~~~~~~~~~~~~~~}
+\xdef\ltj@@space@seq@b{~~~~~~~~~~~~~}
+\endgroup
+
+%% \ltj@PackageError{<pkg-name>}{<msg-main>}{<msg-help>}
+\def\ltj@PackageError#1#2#3{%
+ \ltj@GenericError{(#1)\ltj@@space@seq@a}%
+ {Package #1 Error: #2}%
+ {See the #1 package documentation for explanation.}%
+ {#3}%
+}
+%% \ltj@PackageWarning{<pkg-name>}{<msg-main>}
+\def\ltj@PackageWarning#1#2{%
+ \ltj@GenericWarning{(#1)\ltj@@space@seq@a}%
+ {Package #1 Warning: #2}%
+}
+%% \ltj@PackageWarningNoLine{<pkg-name>}{<msg-main>}
+\def\ltj@PackageWarningNoLine#1#2{%
+ \ltj@GenericWarningNoLine{(#1)\ltj@@space@seq@a}%
+ {Package #1 Warning: #2}%
+}
+%% \ltj@PackageInfo{<pkg-name>}{<msg-main>}
+\def\ltj@PackageInfo#1#2{%
+ \ltj@GenericInfo{(#1)\ltj@@space@seq@b}%
+ {Package #1 Info: #2}%
+}
+%% \ltj@PackageInfoNoLine{<pkg-name>}{<msg-main>}
+\def\ltj@PackageInfoNoLine#1#2{%
+ \ltj@GenericInfoNoLine{(#1)\ltj@@space@seq@b}%
+ {Package #1 Info: #2}%
+}
+
+%%------------------ debug logging
+\ifdefined\LuaTeXjaDebugEnabled
+
+%% Load Lua module
+\RequireLuaModule{luatexja.debug}
+
+%% \ltj@debug{<format>}{<arg>,...}
+\def\ltj@debug#1#2{
+ \directlua{
+ luatexja.base.debug(\ltj@safe@str{#1}
+ \ltj@if@blank{#2}{}{, }
+ #2)
+ }
+}
+
+%% \ltj@package@debug{<package>}{<format>}{<arg>,...}
+\def\ltj@package@debug#1#2#3{
+ \directlua{
+ luatexja.base.package_debug(\ltj@safe@str{#1},
+ \ltj@safe@str{#2}
+ \ltj@if@blank{#3}{}{, }
+ #3)
+ }
+}
+
+\else
+
+\def\ltj@debug#1#2{}
+\def\ltj@package@debug#1#2#3{}
+
+\fi
+
+%% \ltj@debug@logger\CS{<package>}
+\def\ltj@debug@logger#1#2{
+ \def#1{\ltj@package@debug{#2}}
+}
+
+%% \ltj@afterbox <token><box>
+%% -> \setbox\ltj@afbox<box><token>
+%% from Sonja Maus, ``Looking Ahead for a <box>'',
+%% TUGBoat, 11, No. 4, 1990.
+\newbox\ltj@afbox
+\protected\def\ltj@afterbox#1{%
+ \def\ltj@afb@xarg{#1}%
+ \afterassignment\ltj@afb@x
+ \chardef\ltj@@next`.}
+\def\ltj@afb@x{\futurelet\ltj@@next\ltj@afb@xtest}
+\def\ltj@afb@xtest{%
+ \ifcase\ifx\ltj@@next\hbox\tw@\fi
+ \ifx\ltj@@next\vbox\tw@\fi
+ \ifx\ltj@@next\vtop\tw@\fi
+ \ifx\ltj@@next\box\@ne\fi
+ \ifx\ltj@@next\copy\@ne\fi
+ \ifx\ltj@@next\vsplit\@ne\fi
+ \ifx\ltj@@next\lastbox\@ne\fi
+ 0% ``A <box> was ...'' error will be causes by \setbox later anyway.
+ \or\afterassignment\ltj@afb@xarg
+ \or\afterassignment\ltj@afb@xagarg
+ \fi
+ \setbox\ltj@afbox
+}
+\def\ltj@afb@xagarg{\aftergroup\ltj@afb@xarg}
+
+
+%%------------------ all done
+\ltj@base@AtEnd
+\endinput
+%% EOF
diff --git a/macros/luatex/generic/luatexja/src/ltj-charrange.lua b/macros/luatex/generic/luatexja/src/ltj-charrange.lua
new file mode 100644
index 0000000000..96fbd885ab
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-charrange.lua
@@ -0,0 +1,112 @@
+--
+-- luatexja/charrange.lua
+--
+luatexbase.provides_module({
+ name = 'luatexja.charrange',
+ date = '2019/04/01',
+ description = 'Handling the range of Japanese characters',
+})
+luatexja.charrange = {}
+luatexja.load_module('base'); local ltjb = luatexja.base
+
+local getchar = node.direct.getchar
+local has_attr = node.direct.has_attribute
+local has_attr_node = node.has_attribute
+local tex_getattr = tex.getattribute
+
+local ATTR_RANGE = 7
+luatexja.charrange.ATTR_RANGE = ATTR_RANGE
+local jcr_cjk, jcr_noncjk = 0, 1
+local floor = math.floor
+local kcat_attr_table = {}
+local pow_table = {}
+local fn_table = {} -- used in is_ucs_in_japanese_char_direct
+local nfn_table = {} -- used in is_ucs_in_japanese_char_node
+for i = 0, 31*ATTR_RANGE-1 do
+ local ka, pw = luatexbase.attributes['ltj@kcat'..floor(i/31)], 1/(2^(i%31))
+ local jcr_noncjk = jcr_noncjk
+ kcat_attr_table[i], pow_table[i] = ka, 2^(i%31)
+ fn_table[i] = function(p) return floor(has_attr(p, ka)*pw)%2 ~= jcr_noncjk end
+ nfn_table[i] = function(p) return floor(has_attr_node(p, ka)*pw)%2 ~= jcr_noncjk end
+end
+fn_table[-1] = function() return false end -- for char --U+007F
+nfn_table[-1] = function() return false end -- for char --U+007F
+pow_table[31*ATTR_RANGE] = 2^31
+
+-- jcr_table_main[chr_code] = index
+-- index : internal 0, 1, 2, ..., 216 0: 'other'
+-- external 217, 1 2 216, 217 and (out of range): 'other'
+
+-- initialize
+local jcr_table_main = {}
+local ucs_out = 0x110000
+
+for i=0x0 ,0x7F do jcr_table_main[i]=-1 end
+for i=0x80 ,0xFF do jcr_table_main[i]=1 end
+for i=0x100,ucs_out-1 do jcr_table_main[i]=0 end
+
+-- EXT: add characters to a range
+function luatexja.charrange.add_char_range(b,e,ind) -- ind: external range number
+ if not ind or ind<0 or ind>31*ATTR_RANGE then -- 0 ã¯ã‚¨ãƒ©ãƒ¼ã«ã—ãªã„(隠ã—)
+ ltjb.package_error('luatexja',
+ "invalid character range number (" .. ind .. ")",
+ "A character range number should be in the range 1.."
+ .. 31*ATTR_RANGE .. ",\n" ..
+ "ignored.")
+ return
+ elseif b<0x80 or e>=ucs_out then
+ ltjb.package_warning('luatexja',
+ 'bad character range ([' .. b .. ',' .. e .. ']). ' ..
+ 'I take the intersection with [0x80, 0x10ffff].')
+ elseif b>e then
+ local j=b; e=b; b=j
+ end
+ if ind == 31*ATTR_RANGE then ind=0 end
+ for i=math.max(0x80,b),math.min(ucs_out-1,e) do
+ jcr_table_main[i]=ind
+ end
+end
+
+function luatexja.charrange.char_to_range(c) -- return the external range number
+ local r = jcr_table_main[ltjb.in_unicode(c, false)] or 217
+ return (r~=0) and r or 217
+end
+
+local function get_range_setting(i) -- i: internal range number
+ return floor(tex_getattr(kcat_attr_table[i])/pow_table[i])%2
+end
+
+-- glyph_node p ã¯å’Œæ–‡æ–‡å­—ã‹ï¼Ÿ
+function luatexja.charrange.is_ucs_in_japanese_char(p)
+ return nfn_table[jcr_table_main[c or p.char]](p)
+end
+
+function luatexja.charrange.is_ucs_in_japanese_char_direct(p ,c)
+ return fn_table[jcr_table_main[c or getchar(p)]](p)
+end
+
+function luatexja.charrange.is_japanese_char_curlist(c) -- assume that c>=0x80
+ return get_range_setting(jcr_table_main[c])~= jcr_noncjk
+end
+
+-- EXT
+function luatexja.charrange.toggle_char_range(g, i) -- i: external range number
+ if type(i)~='number' then
+ ltjb.package_error('luatexja',
+ "invalid character range number (" .. tostring(i).. ")",
+ "A character range number must be a number, ignored.")
+ elseif i==0 then return
+ else
+ local kc
+ if i>0 then kc=0 else kc=1; i=-i end
+ if i>=7*ATTR_RANGE then i=0 end
+ local attr = kcat_attr_table[i]
+ local a = tex_getattr(attr)
+ tex.setattribute(g, attr,
+ (floor(a/pow_table[i+1])*2+kc)*pow_table[i]+a%pow_table[i])
+ end
+end
+
+luatexja.charrange.get_range_setting=get_range_setting
+
+-- EOF
diff --git a/macros/luatex/generic/luatexja/src/ltj-compat.lua b/macros/luatex/generic/luatexja/src/ltj-compat.lua
new file mode 100644
index 0000000000..bd798545f3
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-compat.lua
@@ -0,0 +1,140 @@
+--
+-- luatexja/ltj-compat.lua
+--
+
+luatexja.load_module('base'); local ltjb = luatexja.base
+luatexja.load_module('stack'); local ltjs = luatexja.stack
+local stack_table_index = luatexja.stack_table_index
+
+-- load jisx0208 table
+local cache_ver = 2
+
+local cache_outdate_fn = function (t) return t.version~=cache_ver end
+local jisx0208 = ltjb.load_cache('ltj-jisx0208',cache_outdate_fn)
+if not jisx0208 then -- make cache
+ jisx0208 = require('ltj-jisx0208.lua')
+ ltjb.save_cache_luc('ltj-jisx0208', jisx0208)
+end
+
+
+-- \kuten, \jis, \euc, \sjis, \ucs, \kansuji
+local utfchar=utf.char
+local function to_kansuji(num)
+ if not num then num=0; return
+ elseif num<0 then
+ num = -num; tex.write('-')
+ end
+ local s = ""
+ while num~=0 do
+ s = utfchar(
+ ltjs.get_stack_table(luatexja.stack_table_index.KSJ + num%10,
+ '', tex.getcount('ltj@@stack'))) .. s
+ num=math.floor(num/10)
+ end
+ tex.write(s)
+end
+
+-- \ucs: å˜ãªã‚‹ identity
+local function from_ucs(i)
+ if type(i)~='number' then
+ ltjb.package_error('luatexja',
+ "invalid character code (".. tostring(i) .. ")",
+ "I'm going to use 0 instead of that illegal character code.")
+ i=0
+ end
+ tex.write(i)
+end
+
+-- \kuten: é¢åŒºç‚¹ (ãã‚Œãžã‚Œã§16進2æ¡ã‚’使用)=> Unicode 符å·ä½ç½®
+local function from_kuten(i)
+ if type(i)~='number' then
+ ltjb.package_error('luatexja',
+ "invalid character code (".. tostring(i) .. ")",
+ "I'm going to use 0 instead of that illegal character code.")
+ i=0
+ end
+ tex.write(tostring(jisx0208.table_jisx0208_uptex[i] or 0))
+end
+
+-- \euc: EUC-JP ã«ã‚ˆã‚‹ç¬¦å·ä½ç½® => Unicode 符å·ä½ç½®
+local function from_euc(i)
+ if type(i)~='number' then
+ ltjb.package_error('luatexja',
+ "invalid character code (".. tostring(i) .. ")",
+ "I'm going to use 0 instead of that illegal character code.")
+ i=0
+ elseif i>=0x10000 or i<0xa0a0 then
+ i=0
+ end
+ from_kuten(i-0xa0a0)
+end
+
+-- \jis: ISO-2022-JP ã«ã‚ˆã‚‹ç¬¦å·ä½ç½® => Unicode 符å·ä½ç½®
+local function from_jis(i)
+ if (type(i)~='number') or i>=0x10000 or i<0 then
+ ltjb.package_error('luatexja',
+ "invalid character code (".. tostring(i) .. ")",
+ "I'm going to use 0 instead of that illegal character code.")
+ i=0
+ end
+ from_kuten(i-0x2020)
+end
+
+-- \sjis: Shift_JIS ã«ã‚ˆã‚‹ç¬¦å·ä½ç½® => Unicode 符å·ä½ç½®
+local function from_sjis(i)
+ if (type(i)~='number') or i>=0x10000 or i<0 then
+ ltjb.package_error('luatexja',
+ "invalid character code (".. tostring(i) .. ")",
+ "I'm going to use 0 instead of that illegal character code.")
+ tex.write('0'); return
+ end
+ local c2 = math.floor(i/256)
+ local c1 = i%256
+ local shift_jisx0213_s1a3_table = {
+ { [false]= 1, [true]= 8},
+ { [false]= 3, [true]= 4},
+ { [false]= 5, [true]=12},
+ { [false]=13, [true]=14},
+ { [false]=15 } }
+ if c2 >= 0x81 then
+ if c2 >= 0xF0 then -- this if block won't be true
+ if (c2 <= 0xF3 or (c2 == 0xF4 and c1 < 0x9F)) then
+ c2 = 0x100 + shift_jisx0213_s1a3_table[c2 - 0xF0 + 1][(0x9E < c1)];
+ else -- 78<=k<=94
+ c2 = c2 * 2 - 413 + 0x100; if 0x9E < c1 then c2=c2+1 end
+ end
+ else
+ if c2<=0x9f then i=0x101 else i=0x181 end
+ c2 = c2 + c2 - i; if 0x9E < c1 then c2=c2+1 end
+ end
+ if c1 < 0x9F then
+ if c1>0x7f then i=0x40 else i=0x3f end
+ c1 = c1 - i
+ else
+ c1 = c1 - 0x9e
+ end
+ from_kuten(c2*256+c1)
+ end
+end
+
+luatexja.binary_pars.kansujichar = function(c, t)
+ if type(c)~='number' or c<0 or c>9 then
+ ltjb.package_error('luatexja',
+ 'Invalid KANSUJI number (' .. tostring(c) .. ')',
+ 'A KANSUJI number should be in the range 0..9.\n'..
+ 'So I changed this one to zero.')
+ c=0
+ end
+ return ltjs.get_stack_table(stack_table_index.KSJ + c, 0, t)
+end
+
+
+local t = {
+ from_euc = from_euc,
+ from_kuten = from_kuten,
+ from_jis = from_jis,
+ from_sjis = from_sjis,
+ from_ucs = from_ucs,
+ to_kansuji = to_kansuji,
+}
+luatexja.compat = t
diff --git a/macros/luatex/generic/luatexja/src/ltj-debug.lua b/macros/luatex/generic/luatexja/src/ltj-debug.lua
new file mode 100644
index 0000000000..ac517500e8
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-debug.lua
@@ -0,0 +1,187 @@
+--
+-- luatexja/debug.lua
+--
+local ltjdbg = {}
+luatexja.debug = ltjdbg
+local table, string = table, string
+
+-------------------- pretty-print
+
+local function get_serialize_param()
+ return table.serialize_functions,
+ table.serialize_compact,
+ table.serialize_inline
+end
+local function set_serialize_param(s_f, s_c, s_i)
+ table.serialize_functions = s_f
+ table.serialize_compact = s_c
+ table.serialize_inline = s_i
+end
+
+local function normal_serialize(t)
+ local s_f, s_c, s_i = get_serialize_param()
+ set_serialize_param(true, true, true)
+ local ret = table.serialize(t, false, false, true)
+ set_serialize_param(s_f, s_c, s_i)
+ return ret
+end
+
+local function table_tosource(t)
+ if not next(t) then return "{}" end
+ local res_n = "\127"..normal_serialize({t}).."\127"
+ local s, e, cap = res_n:find("\127{\n ({ .* }),\n}\127")
+ if s == 1 and e == res_n:len() then return cap
+ else return normal_serialize(t)
+ end
+end
+ltjdbg.table_tosource = table_tosource
+
+local function function_tosource(f)
+ local res = normal_serialize({f})
+ return res:sub(4, res:len() - 3)
+end
+ltjdbg.function_tosource = function_tosource
+
+--! 値 v ã‚’ãれを表ã™ã‚½ãƒ¼ã‚¹æ–‡å­—列ã«å¤‰æ›ã™ã‚‹.
+--! lualibs ã® table.serialize() ã®å‡¦ç†ã‚’利用ã—ã¦ã„ã‚‹.
+local function tosource(v)
+ local tv = type(v)
+ if tv == "function" then return function_tosource(v)
+ elseif tv == "table" then return table_tosource(v)
+ elseif tv == "string" then return string.format('%q', v)
+ else return tostring(v)
+ end
+end
+ltjdbg.tosource = tosource
+
+local function coerce(f, v)
+ if f == "q" then return "s", tosource(v)
+ elseif f == "s" then return f, tostring(v)
+ else return f, tonumber(v) or 0
+ end
+end
+
+local function do_pformat(fmt, ...)
+ fmt = fmt:gsub("``", "\127"):gsub("`", "%%"):gsub("\127", "`")
+ local i, na, a = 0, {}, {...}
+ local function proc(p, f)
+ i = i + 1; f, na[i] = coerce(f, a[i])
+ return p..f
+ end
+ fmt = fmt:gsub("(%%[-+#]?[%d%.]*)([a-zA-Z])", proc)
+ return fmt:format(unpack(na))
+end
+
+--! string.format() ã®æ‹¡å¼µç‰ˆ. 以下ã®ç‚¹ãŒç•°ãªã‚‹.
+--! - %q ã¯å…¨ã¦ã®åž‹ã«ã¤ã„㦠tosource() ã«å¤‰æ›
+--! - <%> ã®ä»£ã‚ã‚Šã« <`> も使ãˆã‚‹ (TeX ã§ã®ä½¿ç”¨ã®ãŸã‚)
+--! - %d, %s ç­‰ã§ã‚­ãƒ£ã‚¹ãƒˆã‚’è¡Œã†
+local function pformat(fmt, ...)
+ if type(fmt) == "string" then
+ return do_pformat(fmt, ...)
+ else
+ return tosource(fmt)
+ end
+end
+ltjdbg.pformat = pformat
+
+-------------------- 所è¦æ™‚é–“åˆè¨ˆ
+require("socket")
+do
+ local max = math.max
+ local gettime = socket.gettime
+ local time_stat = {}
+ local function start_time_measure(n)
+ if not time_stat[n] then
+ time_stat[n] = {1, -gettime()}
+ else
+ local t = time_stat[n]
+ t[1], t[2] = t[1]+1, t[2]-gettime()
+ end
+ end
+ local function stop_time_measure(n)
+ local t = time_stat[n]
+ t[2] = t[2] + gettime()
+ end
+
+ local function print_measure()
+ stop_time_measure('RUN')
+ local temp = {}
+ for i,v in pairs(time_stat) do
+ temp[#temp+1] = { i, v[1], v[2], v[2]/v[1] }
+ end
+ table.sort(temp, function (a,b) return (a[4]>b[4]) end)
+ print()
+ print('desc', 'ave. (us)', 'times', 'total (ms)')
+ for _,v in ipairs(temp) do
+ print ((v[1] .. ' '):sub(1,16), 1000000*v[4], v[2], 1000*v[3])
+ end
+ end
+ if luatexja.base then
+ luatexja.base.start_time_measure = start_time_measure
+ luatexja.base.stop_time_measure = stop_time_measure
+ luatexbase.add_to_callback('stop_run', print_measure, 'luatexja.time_measure', 1)
+ luatexbase.add_to_callback('pre_linebreak_filter',
+ function(p)
+ start_time_measure('tex_linebreak'); return p
+ end,
+ 'measure_tex_linebreak', 20000)
+ end
+end
+
+-------------------- debug logging
+do
+local debug_show_term = true
+local debug_show_log = true
+--! デãƒãƒƒã‚°ãƒ­ã‚°ã‚’端末ã«å‡ºåŠ›ã™ã‚‹ã‹
+local function show_term(v)
+ debug_show_term = v
+end
+ltjdbg.show_term = show_term
+--! デãƒãƒƒã‚°ãƒ­ã‚°ã‚’ログファイルã«å‡ºåŠ›ã™ã‚‹ã‹
+function show_log(v)
+ debug_show_log = v
+end
+ltjdbg.show_log = show_log
+
+local function write_debug_log(s)
+ local target
+ if debug_show_term and debug_show_log then
+ texio.write_nl("term and log", s)
+ elseif debug_show_term and not debug_show_log then
+ texio.write_nl("term", s)
+ elseif not debug_show_term and debug_show_log then
+ texio.write_nl("log", s)
+ end
+end
+
+--! デãƒãƒƒã‚°ãƒ­ã‚°å‡ºåŠ›. 引数㯠pformat() ã¨åŒã˜.
+local function out_debug(...)
+ if debug_show_term or debug_show_log then
+ write_debug_log("%DEBUG:"..pformat(...))
+ end
+end
+
+--! デãƒãƒƒã‚°ãƒ­ã‚°å‡ºåŠ›, パッケージå付ã.
+local function package_debug(pkg, ...)
+ if debug_show_term or debug_show_log then
+ write_debug_log("%DEBUG("..pkg.."):"..pformat(...))
+ end
+end
+
+--! パッケージå付ãデãƒãƒƒã‚°ãƒ­ã‚°å‡ºåŠ›å™¨ã‚’å¾—ã‚‹.
+local function debug_logger(pkg)
+ return function(...) package_debug(pkg, ...) end
+end
+
+if luatexja.base then
+ luatexja.base.out_debug = out_debug
+ luatexja.base.package_debug = package_debug
+ luatexja.base.debug_logger = debug_logger
+ luatexja.base.show_term = show_term
+ luatexja.base.show_log = show_log
+end
+end
+
+-------------------- all done
+-- EOF
diff --git a/macros/luatex/generic/luatexja/src/ltj-direction.lua b/macros/luatex/generic/luatexja/src/ltj-direction.lua
new file mode 100644
index 0000000000..107d27a897
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-direction.lua
@@ -0,0 +1,1147 @@
+--
+-- src/ltj-direction.lua
+--
+
+luatexja.load_module('base'); local ltjb = luatexja.base
+luatexja.load_module('stack'); local ltjs = luatexja.stack
+luatexja.direction = {}
+
+local attr_dir = luatexbase.attributes['ltj@dir']
+local attr_icflag = luatexbase.attributes['ltj@icflag']
+
+local cat_lp = luatexbase.catcodetables['latex-package']
+local to_node = node.direct.tonode
+local to_direct = node.direct.todirect
+local has_attr = node.direct.has_attribute
+local set_attr = node.direct.set_attribute
+local insert_before = node.direct.insert_before
+local insert_after = node.direct.insert_after
+local getid = node.direct.getid
+local getsubtype = node.direct.getsubtype
+local getlist = node.direct.getlist
+local setfield = node.direct.setfield
+local getfield = node.direct.getfield
+local node_new = node.direct.new
+local node_tail = node.direct.tail
+local node_free = node.direct.free
+local node_remove = node.direct.remove
+local node_next = node.direct.getnext
+local traverse = node.direct.traverse
+local traverse_id = node.direct.traverse_id
+local start_time_measure, stop_time_measure
+ = ltjb.start_time_measure, ltjb.stop_time_measure
+local abs = math.abs
+
+local id_kern = node.id('kern')
+local id_hlist = node.id('hlist')
+local id_vlist = node.id('vlist')
+local id_whatsit = node.id('whatsit')
+local sid_save = node.subtype('pdf_save')
+local sid_restore = node.subtype('pdf_restore')
+local sid_matrix = node.subtype('pdf_setmatrix')
+local sid_user = node.subtype('user_defined')
+
+local tex_nest = tex.nest
+local tex_getcount = tex.getcount
+local ensure_tex_attr = ltjb.ensure_tex_attr
+local PROCESSED = luatexja.icflag_table.PROCESSED
+local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
+local PACKED = luatexja.icflag_table.PACKED
+local DIR = luatexja.userid_table.DIR
+local dir_tate = luatexja.dir_table.dir_tate
+local dir_yoko = luatexja.dir_table.dir_yoko
+local dir_dtou = luatexja.dir_table.dir_dtou
+local dir_utod = luatexja.dir_table.dir_utod
+local dir_math_mod = luatexja.dir_table.dir_math_mod
+local dir_node_auto = luatexja.dir_table.dir_node_auto
+local dir_node_manual = luatexja.dir_table.dir_node_manual
+local function get_attr_icflag(p)
+ return (has_attr(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG
+end
+
+local page_direction
+--
+local dir_pool
+do
+ local node_copy = node.direct.copy
+ dir_pool = {}
+ for _,i in pairs({dir_tate, dir_yoko, dir_dtou, dir_utod}) do
+ local w = node_new(id_whatsit, sid_user)
+ set_attr(w, attr_dir, i)
+ setfield(w, 'user_id', DIR)
+ setfield(w, 'type', 110)
+ setfield(w, 'next', nil)
+ dir_pool[i] = function () return node_copy(w) end
+ end
+end
+
+--
+local function adjust_badness(hd)
+ if not node_next(hd) and getid(hd)==id_whatsit and getsubtype(hd)==sid_user
+ and getfield(hd, 'user_id')==DIR then
+ -- avoid double whatsit
+ luatexja.global_temp=tex.globaldefs; tex.globaldefs=0
+ luatexja.hbadness_temp=tex.hbadness; tex.hbadness=10000
+ luatexja.vbadness_temp=tex.vbadness; tex.vbadness=10000
+ else
+ luatexja.global_temp = nil
+ luatexja.hbadness_temp=nil
+ luatexja.vbadness_temp=nil
+ end
+end
+
+local get_dir_count, get_adjust_dir_count
+do
+ local function get_dir_count_inner(h)
+ if h then
+ if h.id==id_whatsit and h.subtype==sid_user and h.user_id==DIR then
+ local ic = node.has_attribute(h, attr_icflag) or 0
+ return (ic<PROCESSED_BEGIN_FLAG)
+ and (node.has_attribute(h,attr_dir)%dir_node_auto) or 0
+ else
+ return 0
+ end
+ else
+ return 0
+ end
+ end
+ function get_dir_count()
+ for i=tex_nest.ptr, 1, -1 do
+ local h = tex_nest[i].head.next
+ if h then
+ local t = get_dir_count_inner(h)
+ if t~=0 then return t end
+ end
+ end
+ return page_direction
+ end
+ function get_adjust_dir_count()
+ for i=tex_nest.ptr, 1, -1 do
+ local v = tex_nest[i]
+ local h, m = v.head.next, v.mode
+ if abs(m)== ltjs.vmode and h then
+ local t = get_dir_count_inner(h)
+ if t~=0 then return t end
+ end
+ end
+ return page_direction
+ end
+ luatexja.direction.get_dir_count = get_dir_count
+ luatexja.direction.get_adjust_dir_count = get_adjust_dir_count
+end
+
+
+-- \tate, \yoko,\dtou, \utod
+do
+ local node_next = node.next
+ local node_set_attr = node.set_attribute
+ local node_traverse = node.traverse
+ local STCK = luatexja.userid_table.STCK
+ local IHB = luatexja.userid_table.IHB
+ local id_local = node.id('local_par')
+
+ local function test_list(h, lv)
+ if not h then
+ return 2 -- need to create dir_whatsit
+ else
+ local flag = 2 -- need to create dir_whatsit
+ local w
+ for p in node_traverse(h) do
+ if p.id==id_whatsit then
+ local ps = p.subtype
+ if ps==sid_user then
+ local uid= p.user_id
+ if uid==DIR then
+ flag = 1; w = w or p -- found
+ elseif not(uid==IHB or uid==STCK) then
+ flag = 0; break -- error
+ end
+ end
+ elseif p.id~=id_local then
+ flag = 0; break
+ end
+ end
+ if flag==1 then -- dir_whatsit already exists
+ return 1,w
+ else
+ return flag
+ end
+ end
+ end
+ local node_next_node, node_tail_node = node.next, node.tail
+ local insert_after_node = node.insert_after
+ function luatexja.direction.set_list_direction_hook(v)
+ local lv = tex_nest.ptr -- must be >= 1
+ if not v then
+ v = get_dir_count()
+ if abs(tex_nest[lv-1].mode) == ltjs.mmode and v == dir_tate then
+ v = dir_utod
+ end
+ elseif v=='adj' then
+ v = get_adjust_dir_count()
+ end
+ local h = tex_nest[lv].head
+ local hn = node.next(h)
+ hn = (hn and hn.id==id_local) and hn or h
+ local w = to_node(dir_pool[v]())
+ insert_after_node(h, hn, w)
+ tex_nest[lv].tail = node_tail_node(w)
+ ensure_tex_attr(attr_icflag, 0)
+ ensure_tex_attr(attr_dir, 0)
+ end
+
+ local function set_list_direction(v, name)
+ local lv = tex_nest.ptr
+ if not v then
+ v,name = get_dir_count(), nil
+ if lv>=1 and abs(tex_nest[lv-1].mode) == ltjs.mmode and v == dir_tate then
+ v = dir_utod
+ end
+ elseif v=='adj' then
+ v,name = get_adjust_dir_count(), nil
+ end
+ local current_nest = tex_nest[lv]
+ if tex.currentgrouptype==6 then
+ ltjb.package_error(
+ 'luatexja',
+ "You can't use `\\" .. name .. "' in an align",
+ "To change the direction in an align, \n"
+ .. "you shold use \\hbox or \\vbox.")
+ elseif current_nest.mode == ltjs.hmode or abs(current_nest.mode) == ltjs.mmode then
+ ltjb.package_error(
+ 'luatexja',
+ "Improper `\\" .. name .. "'",
+ 'You cannot change the direction in unrestricted horizontal mode \n'
+ .. 'nor math modes.')
+ else
+ local h = (lv==0) and tex.lists.page_head or current_nest.head.next
+ local flag,w = test_list(h,lv)
+ if flag==0 then
+ if lv==0 and not page_direction then
+ page_direction = v -- for first call of \yoko (in luatexja-core.sty)
+ else
+ ltjb.package_error(
+ 'luatexja',
+ "Use `\\" .. tostring(name) .. "' at top of list",
+ 'Direction change command by LuaTeX-ja is available\n'
+ .. 'only when the current list is null.')
+ end
+ elseif flag==1 then
+ node_set_attr(w, attr_dir, v)
+ if lv==0 then page_direction = v end
+ elseif lv==0 then
+ page_direction = v
+ else -- flag == 2: need to create dir whatsit.
+ local h = current_nest.head
+ local hn = node.next(h)
+ hn = (hn and hn.id==id_local) and hn or h
+ local w = to_node(dir_pool[v]())
+ insert_after_node(h,hn,w)
+ current_nest.tail = node_tail_node(w)
+ end
+ ensure_tex_attr(attr_icflag, 0)
+ end
+ ensure_tex_attr(attr_dir, 0)
+ end
+ luatexja.direction.set_list_direction = set_list_direction
+end
+
+-- ボックス㫠dir whatsit を追加
+local function create_dir_whatsit(hd, gc, new_dir)
+ if getid(hd)==id_whatsit and
+ getsubtype(hd)==sid_user and getfield(hd, 'user_id')==DIR then
+ set_attr(hd, attr_icflag,
+ get_attr_icflag(hd) + PROCESSED_BEGIN_FLAG)
+ local n =node_next(hd)
+ if n then
+ set_attr(n, attr_icflag,
+ get_attr_icflag(n) + PROCESSED_BEGIN_FLAG)
+ end
+ ensure_tex_attr(attr_icflag, 0)
+ return hd
+ else
+ local w = dir_pool[new_dir]()
+ setfield(w, 'next', hd)
+ set_attr(w, attr_icflag, PROCESSED_BEGIN_FLAG)
+ set_attr(hd, attr_icflag,
+ get_attr_icflag(hd) + PROCESSED_BEGIN_FLAG)
+ ensure_tex_attr(attr_icflag, 0)
+ ensure_tex_attr(attr_dir, 0)
+ return w
+ end
+end
+
+-- hpack_filter, vpack_filter, post_line_break_filter
+-- ã®çµæžœã‚’組方å‘を明示ã™ã‚‹ãŸã‚,先頭㫠dir_node を設置
+local get_box_dir
+do
+ local function create_dir_whatsit_hpack(h, gc)
+ local hd = to_direct(h)
+ if gc=='fin_row' then
+ if hd then
+ for p in traverse_id(15, hd) do -- unset
+ if get_box_dir(p, 0)==0 then
+ setfield(p, 'head', create_dir_whatsit(getlist(p), 'fin_row', ltjs.list_dir))
+ end
+ end
+ set_attr(hd, attr_icflag, PROCESSED_BEGIN_FLAG)
+ ensure_tex_attr(attr_icflag, 0)
+ end
+ return h
+ elseif gc == 'preamble' then
+ else
+ adjust_badness(hd)
+ return to_node(create_dir_whatsit(hd, gc, ltjs.list_dir))
+ end
+ end
+
+ ltjb.add_to_callback('hpack_filter',
+ create_dir_whatsit_hpack, 'ltj.create_dir_whatsit', 10000)
+end
+
+do
+ local function create_dir_whatsit_parbox(h, gc)
+ stop_time_measure('tex_linebreak');
+ -- start å´ã¯ ltj-debug.lua ã«
+ local new_dir = ltjs.list_dir
+ for line in traverse_id(id_hlist, to_direct(h)) do
+ setfield(line, 'head', create_dir_whatsit(getlist(line), gc, new_dir) )
+ end
+ ensure_tex_attr(attr_dir, 0)
+ return h
+ end
+ ltjb.add_to_callback('post_linebreak_filter',
+ create_dir_whatsit_parbox, 'ltj.create_dir_whatsit', 10000)
+end
+
+local create_dir_whatsit_vbox
+do
+ local wh = {}
+ local id_glue, sid_parskip = node.id('glue'), 3
+ create_dir_whatsit_vbox = function (hd, gc)
+ ltjs.list_dir = get_dir_count()
+ -- remove dir whatsit
+ for x in traverse_id(id_whatsit, hd) do
+ if getsubtype(x)==sid_user and getfield(x, 'user_id')==DIR then
+ wh[#wh+1]=x
+ end
+ end
+ if hd==wh[1] then
+ ltjs.list_dir =has_attr(hd,attr_dir)
+ local x = node_next(hd)
+ if getid(x)==id_glue and getsubtype(x)==sid_parskip then
+ node_remove(hd,x); node_free(x)
+ end
+ end
+ for i=1,#wh do
+ hd = node_remove(hd, wh[i]); node_free(wh[i]); wh[i] = nil
+ end
+ if gc=='fin_row' then -- gc == 'preamble' case is treated in dir_adjust_vpack
+ if hd then
+ set_attr(hd, attr_icflag, PROCESSED_BEGIN_FLAG)
+ ensure_tex_attr(attr_icflag, 0)
+ end
+ return hd
+ else
+ local n =node_next(hd)
+ if gc=='vtop' then
+ local w = create_dir_whatsit(hd, gc, ltjs.list_dir)
+ -- move dir whatsit after hd
+ setfield(hd, 'next', w); setfield(w, 'next', n)
+ return hd
+ else
+ hd = create_dir_whatsit(hd, gc, ltjs.list_dir)
+ return hd
+ end
+ end
+ end
+end
+
+-- dir_node ã«åŒ…む方法を書ã„ãŸãƒ†ãƒ¼ãƒ–ル
+local dir_node_aux
+do
+ local floor = math.floor
+ local get_h =function (w,h,d) return h end
+ local get_d =function (w,h,d) return d end
+ local get_h_d =function (w,h,d) return h+d end
+ local get_h_d_neg =function (w,h,d) return -h-d end
+ local get_d_neg =function (w,h,d) return -d end
+ local get_w_half =function (w,h,d) return floor(0.5*w) end
+ local get_w_half_rem =function (w,h,d) return w-floor(0.5*w) end
+ local get_w_neg =function (w,h,d) return -w end
+ local get_w =function (w,h,d) return w end
+ local zero = function() return 0 end
+ dir_node_aux = {
+ [dir_yoko] = { -- yoko ã‚’
+ [dir_tate] = { -- tate 中ã§çµ„ã‚€
+ width = get_h_d,
+ height = get_w_half,
+ depth = get_w_half_rem,
+ [id_hlist] = {
+ { 'whatsit', sid_save },
+ { 'rotate', '0 1 -1 0' },
+ { 'kern', function(w,h,d,nw,nh,nd) return -nd end },
+ { 'box' , get_h},
+ { 'kern', function(w,h,d,nw,nh,nd) return nd-w end },
+ { 'whatsit', sid_restore },
+ },
+ [id_vlist] = {
+ { 'whatsit', sid_save },
+ { 'rotate', '0 1 -1 0' },
+ { 'kern' , zero },
+ { 'box' , function(w,h,d,nw,nh,nd) return -nh-nd end },
+ { 'kern', get_h_d_neg},
+ { 'whatsit', sid_restore },
+ },
+ },
+ [dir_dtou] = { -- dtou 中ã§çµ„ã‚€
+ width = get_h_d,
+ height = get_w,
+ depth = zero,
+ [id_hlist] = {
+ { 'whatsit', sid_save },
+ { 'rotate', '0 -1 1 0' },
+ { 'kern', function(w,h,d,nw,nh,nd) return -nh end },
+ { 'box', get_d_neg },
+ { 'kern', function(w,h,d,nw,nh,nd) return nh-w end },
+ { 'whatsit', sid_restore },
+ },
+ [id_vlist] = {
+ { 'whatsit', sid_save },
+ { 'rotate', '0 -1 1 0' },
+ { 'kern', get_h_d_neg },
+ { 'box', zero },
+ { 'whatsit', sid_restore },
+ },
+ },
+ },
+ [dir_tate] = { -- tate ã‚’
+ [dir_yoko] = { -- yoko 中ã§çµ„ã‚€
+ width = get_h_d,
+ height = get_w,
+ depth = zero,
+ [id_hlist] = {
+ { 'whatsit', sid_save },
+ { 'rotate', '0 -1 1 0' },
+ { 'kern', function (w,h,d,nw,nh,nd) return -nh end },
+ { 'box' , get_d_neg },
+ { 'kern', function (w,h,d,nw,nh,nd) return nh-w end },
+ { 'whatsit', sid_restore },
+ },
+ [id_vlist] = {
+ { 'whatsit', sid_save },
+ { 'rotate', '0 -1 1 0' },
+ { 'kern', get_h_d_neg },
+ { 'box', zero },
+ { 'whatsit', sid_restore },
+ },
+ },
+ [dir_dtou] = { -- dtou 中ã§çµ„ã‚€
+ width = get_w,
+ height = get_d,
+ depth = get_h,
+ [id_hlist] = {
+ { 'whatsit', sid_save },
+ { 'rotate', '-1 0 0 -1' },
+ { 'kern', get_w_neg },
+ { 'box', function (w,h,d,nw,nh,nd) return h-nd end },
+ { 'whatsit', sid_restore },
+ },
+ [id_vlist] = {
+ { 'whatsit', sid_save },
+ { 'rotate', '-1 0 0 -1' },
+ { 'kern', get_h_d_neg },
+ { 'box', get_w_neg },
+ { 'whatsit', sid_restore },
+ },
+ },
+ },
+ [dir_dtou] = { -- dtou ã‚’
+ [dir_yoko] = { -- yoko 中ã§çµ„ã‚€
+ width = get_h_d,
+ height = get_w,
+ depth = zero,
+ [id_hlist] = {
+ { 'whatsit', sid_save },
+ { 'rotate', '0 1 -1 0' },
+ { 'kern', function (w,h,d,nw,nh,nd) return -nd end },
+ { 'box', get_h },
+ { 'kern', function (w,h,d,nw,nh,nd) return nd-w end },
+ { 'whatsit', sid_restore },
+ },
+ [id_vlist] = {
+ { 'kern', zero },
+ { 'whatsit', sid_save },
+ { 'rotate', '0 1 -1 0' },
+ { 'box', function (w,h,d,nw,nh,nd) return -nd-nh end },
+ { 'kern', get_h_d_neg },
+ { 'whatsit', sid_restore },
+ },
+ },
+ [dir_tate] = { -- tate 中ã§çµ„ã‚€
+ width = get_w,
+ height = get_d,
+ depth = get_h,
+ [id_hlist] = {
+ { 'whatsit', sid_save },
+ { 'rotate', '-1 0 0 -1' },
+ { 'kern', get_w_neg },
+ { 'box', function (w,h,d,nw,nh,nd) return h-nd end },
+ { 'whatsit', sid_restore },
+ },
+ [id_vlist] = {
+ { 'whatsit', sid_save },
+ { 'rotate', ' -1 0 0 -1' },
+ { 'kern', function (w,h,d,nw,nh,nd) return -nh-nd end },
+ { 'box', get_w_neg },
+ { 'kern', function (w,h,d,nw,nh,nd) return nh+nd-h-d end },
+ { 'whatsit', sid_restore },
+ },
+ },
+ },
+ }
+end
+
+-- 1st ret val: b ã®çµ„æ–¹å‘
+-- 2nd ret val ã¯ãã® DIR whatsit
+function get_box_dir(b, default)
+ start_time_measure('get_box_dir')
+ local dir = has_attr(b, attr_dir) or 0
+ local bh = getfield(b,'head')
+ -- b 㯠insert node ã¨ãªã‚Šã†ã‚‹ã®ã§ getlist() ã¯ä½¿ãˆãªã„
+ local c
+ if bh~=0 then -- bh != nil
+ for bh in traverse_id(id_whatsit, bh) do
+ if getsubtype(bh)==sid_user and getfield(bh, 'user_id')==DIR then
+ c = bh
+ dir = (dir==0) and has_attr(bh, attr_dir) or dir
+ end
+ end
+ end
+ -- for i=1,2 do
+ -- if bh and getid(bh)==id_whatsit
+ -- and getsubtype(bh)==sid_user and getfield(bh, 'user_id')==DIR then
+ -- c = bh
+ -- dir = (dir==0) and has_attr(bh, attr_dir) or dir
+ -- end
+ -- bh = node_next(bh)
+ -- end
+ stop_time_measure('get_box_dir')
+ return (dir==0 and default or dir), c
+end
+
+do
+ local getbox = tex.getbox
+ local dir_backup
+ function luatexja.direction.unbox_check_dir(is_copy)
+ start_time_measure('box_primitive_hook')
+ local list_dir = get_dir_count()%dir_math_mod
+ local b = getbox(tex_getcount('ltj@tempcnta'))
+ if b and getlist(to_direct(b)) then
+ local box_dir = get_box_dir(to_direct(b), dir_yoko)
+ if box_dir%dir_math_mod ~= list_dir then
+ ltjb.package_error(
+ 'luatexja',
+ "Incompatible direction list can't be unboxed",
+ 'I refuse to unbox a box in differrent direction.')
+ tex.sprint(cat_lp, '\\@gobbletwo')
+ else
+ dir_backup = nil
+ local bd = to_direct(b)
+ local hd = getlist(bd)
+ local nh = hd
+ while hd do
+ if getid(hd)==id_whatsit and getsubtype(hd)==sid_user
+ and getfield(hd, 'user_id')==DIR then
+ local d = hd
+ nh, hd = node_remove(nh, hd)
+ if is_copy and (not dir_backup) then
+ dir_backup = d
+ setfield(dir_backup, 'next', nil)
+ else
+ node_free(d)
+ end
+ else
+ hd = node_next(hd)
+ end
+ end
+ setfield(bd, 'head', nh)
+ end
+ end
+ if luatexja.global_temp and tex.globaldefs~=luatexja.global_temp then
+ tex.globaldefs = luatexja.global_temp
+ end
+ stop_time_measure('box_primitive_hook')
+ end
+ function luatexja.direction.uncopy_restore_whatsit()
+ local b = getbox(tex_getcount('ltj@tempcnta'))
+ if b then
+ local bd = to_direct(b)
+ if dir_backup then
+ setfield(dir_backup, 'next', getlist(bd))
+ setfield(bd, 'head', dir_backup)
+ dir_backup = nil
+ end
+ end
+ end
+end
+
+-- dir_node ã«åŒ…ã¾ã‚Œã¦ã„る「本æ¥ã®ä¸­èº«ã€ã‚’å–り出ã—,
+-- dir_node を全部消去
+local function unwrap_dir_node(b, head, box_dir)
+ -- b: dir_node, head: the head of list, box_dir:
+ -- return values are (new head), (next of b), (contents), (dir of contents)
+ local bh = getlist(b)
+ local nh, nb
+ if head then
+ nh = insert_before(head, b, bh)
+ nh, nb = node_remove(nh, b)
+ setfield(b, 'next', nil)
+ node_free(b)
+ end
+ local shift_old, b_dir, wh = nil, get_box_dir(bh, 0)
+ if wh then
+ node.direct.flush_list(getfield(wh, 'value'))
+ setfield(wh, 'value', nil)
+ end
+ return nh, nb, bh, b_dir
+end
+
+-- is_manual: 寸法変更ã«ä¼´ã†ã‚‚ã®ã‹ï¼Ÿ
+local function create_dir_node(b, b_dir, new_dir, is_manual)
+ local info = dir_node_aux[b_dir%dir_math_mod][new_dir%dir_math_mod]
+ local w = getfield(b, 'width')
+ local h = getfield(b, 'height')
+ local d = getfield(b, 'depth')
+ local db = node_new(getid(b)) -- dir_node
+ set_attr(db, attr_dir,
+ new_dir + (is_manual and dir_node_manual or dir_node_auto))
+ set_attr(db, attr_icflag, PROCESSED)
+ set_attr(b, attr_icflag, PROCESSED)
+ ensure_tex_attr(attr_dir, 0)
+ ensure_tex_attr(attr_icflag, 0)
+ setfield(db, 'dir', getfield(b, 'dir'))
+ setfield(db, 'shift', 0)
+ setfield(db, 'width', info.width(w,h,d))
+ setfield(db, 'height', info.height(w,h,d))
+ setfield(db, 'depth', info.depth(w,h,d))
+ return db
+end
+
+-- ç•°æ–¹å‘ã®ãƒœãƒƒã‚¯ã‚¹ã®å‡¦ç†
+local make_dir_whatsit, process_dir_node
+do
+ make_dir_whatsit = function (head, b, new_dir, origin)
+ new_dir = new_dir%dir_math_mod
+ -- head: list head, b: box
+ -- origin: コール元 (for debug)
+ -- return value: (new head), (next of b), (new b), (is_b_dir_node)
+ -- (new b): b ã‹ dir_node ã«è¢«ã›ã‚‰ã‚ŒãŸ b
+ local bh = getlist(b)
+ local box_dir, dn = get_box_dir(b, ltjs.list_dir)
+ -- 既㫠b ã®ä¸­èº«ã«ã‚ã‚‹whatsit
+ if (box_dir<dir_node_auto) and (not dn) then
+ bh = create_dir_whatsit(bh, 'make_dir_whatsit', dir_yoko)
+ dn = bh; setfield(b, 'head', bh)
+ end
+ if box_dir%dir_math_mod==new_dir then
+ if box_dir>=dir_node_auto then
+ -- dir_node ã¨ã—ã¦ã‚«ãƒ—セル化ã•ã‚Œã¦ã„ã‚‹
+ local _, dnc = get_box_dir(b, 0)
+ if dnc then -- free all other dir_node
+ node.direct.flush_list(getfield(dnc, 'value'))
+ setfield(dnc, 'value', nil)
+ end
+ set_attr(b, attr_dir, box_dir%dir_math_mod + dir_node_auto)
+ return head, node_next(b), b, true
+ else
+ -- 組方å‘ãŒä¸€ç·’ (up to math dir) ã®ãƒœãƒƒã‚¯ã‚¹ãªã®ã§ï¼Œä½•ã‚‚ã—ãªãã¦è‰¯ã„
+ return head, node_next(b), b, false
+ end
+ else
+ -- 組方å‘ã‚’åˆã‚ã›ã‚‹å¿…è¦ã‚ã‚Š
+ local nh, nb, ret, flag
+ if box_dir>= dir_node_auto then -- unwrap
+ local b_dir
+ head, nb, b, b_dir = unwrap_dir_node(b, head, box_dir)
+ bh = getlist(b)
+ if b_dir%dir_math_mod==new_dir then
+ -- dir_node ã®ä¸­èº«ãŒå‘¨å›²ã®çµ„æ–¹å‘ã¨ã‚ã£ã¦ã„ã‚‹
+ return head, nb, b, false
+ else box_dir = b_dir end
+ end
+ box_dir = box_dir%dir_math_mod
+ local db
+ local dnh = getfield(dn, 'value')
+ for x in traverse(dnh) do
+ if has_attr(x, attr_dir)%dir_math_mod == new_dir then
+ setfield(dn, 'value', to_node(node_remove(dnh, x)))
+ db=x; break
+ end
+ end
+ node.direct.flush_list(getfield(dn, 'value'))
+ setfield(dn, 'value', nil)
+ db = db or create_dir_node(b, box_dir, new_dir, false)
+ local w = getfield(b, 'width')
+ local h = getfield(b, 'height')
+ local d = getfield(b, 'depth')
+ local dn_w = getfield(db, 'width')
+ local dn_h = getfield(db, 'height')
+ local dn_d = getfield(db, 'depth')
+ nh, nb = insert_before(head, b, db), nil
+ nh, nb = node_remove(nh, b)
+ setfield(b, 'next', nil); setfield(db, 'head', b)
+ ret, flag = db, true
+ return nh, nb, ret, flag
+ end
+ end
+ process_dir_node = function (hd, gc)
+ local x, new_dir = hd, ltjs.list_dir or dir_yoko
+ while x do
+ local xid = getid(x)
+ if (xid==id_hlist and get_attr_icflag(x)~=PACKED)
+ or xid==id_vlist then
+ hd, x = make_dir_whatsit(hd, x, new_dir, 'process_dir_node:' .. gc)
+ else
+ x = node_next(x)
+ end
+ end
+ return hd
+ end
+
+ -- lastbox
+ local node_prev = (node.direct~=node) and node.direct.getprev or node.prev
+ local id_glue = node.id('glue')
+ local function lastbox_hook()
+ start_time_measure('box_primitive_hook')
+ local bn = tex_nest[tex_nest.ptr].tail
+ if bn then
+ local b, head = to_direct(bn), to_direct(tex_nest[tex_nest.ptr].head)
+ local bid = getid(b)
+ if bid==id_hlist or bid==id_vlist then
+ local p = getlist(b)
+ -- alignment ã®å„è¡Œã®ä¸­èº«ãŒå…¥ã£ãŸãƒœãƒƒã‚¯ã‚¹
+ if p and getid(p)==id_glue and getsubtype(p)==12 then -- tabskip
+ local np = node_next(p); local npid = getid(np)
+ if npid==id_hlist or npid==id_vlist then
+ setfield(b, 'head', create_dir_whatsit(p, 'align', get_box_dir(np, 0)))
+ end
+ end
+ local box_dir = get_box_dir(b, 0)
+ if box_dir>= dir_node_auto then -- unwrap dir_node
+ local p = node_prev(b)
+ local dummy1, dummy2, nb = unwrap_dir_node(b, nil, box_dir)
+ setfield(p, 'next', nb); tex_nest[tex_nest.ptr].tail = to_node(nb)
+ setfield(b, 'next', nil); setfield(b, 'head', nil)
+ node_free(b); b = nb
+ end
+ local _, wh = get_box_dir(b, 0) -- clean dir_node attached to the box
+ if wh then
+ node.direct.flush_list(getfield('value', wh))
+ setfield(wh, 'value', nil)
+ end
+ end
+ end
+ stop_time_measure('box_primitive_hook')
+ end
+
+ luatexja.direction.make_dir_whatsit = make_dir_whatsit
+ luatexja.direction.lastbox_hook = lastbox_hook
+end
+
+-- \wd, \ht, \dp ã®ä»£ã‚ã‚Š
+do
+ local getbox, setdimen = tex.getbox, tex.setdimen
+ local function get_box_dim_common(key, s, l_dir)
+ -- s: not dir_node.
+ local s_dir, wh = get_box_dir(s, dir_yoko)
+ s_dir = s_dir%dir_math_mod
+ if s_dir ~= l_dir then
+ local not_found = true
+ for x in traverse(getfield(wh, 'value')) do
+ if l_dir == has_attr(x, attr_dir)%dir_node_auto then
+ setdimen('ltj@tempdima', getfield(x, key))
+ not_found = false; break
+ end
+ end
+ if not_found then
+ local w = getfield(s, 'width')
+ local h = getfield(s, 'height')
+ local d = getfield(s, 'depth')
+ setdimen('ltj@tempdima',
+ dir_node_aux[s_dir][l_dir][key](w,h,d))
+ end
+ else
+ setdimen('ltj@tempdima', getfield(s, key))
+ end
+ end
+ local function get_box_dim(key, n)
+ local gt = tex.globaldefs; tex.globaldefs = 0
+ local s = getbox(n)
+ if s then
+ local l_dir = (get_dir_count())%dir_math_mod
+ s = to_direct(s)
+ local b_dir = get_box_dir(s,dir_yoko)
+ if b_dir<dir_node_auto then
+ get_box_dim_common(key, s, l_dir)
+ elseif b_dir%dir_math_mod==l_dir then
+ setdimen('ltj@tempdima', getfield(s, key))
+ else
+ get_box_dim_common(key, getlist(s), l_dir)
+ end
+ else
+ setdimen('ltj@tempdima', 0)
+ end
+ tex.sprint(cat_lp, '\\ltj@tempdima')
+ tex.globaldefs = gt
+ end
+ luatexja.direction.get_box_dim = get_box_dim
+
+ -- return value: (changed dimen of box itself?)
+ local scan_dimen, scan_int = token.scan_dimen, token.scan_int
+ local scan_keyword = token.scan_keyword
+ local function set_box_dim_common(key, s, l_dir)
+ local s_dir, wh = get_box_dir(s, dir_yoko)
+ s_dir = s_dir%dir_math_mod
+ if s_dir ~= l_dir then
+ if not wh then
+ wh = create_dir_whatsit(getlist(s), 'set_box_dim', s_dir)
+ setfield(s, 'head', wh)
+ end
+ local db
+ local dnh = getfield(wh, 'value')
+ for x in traverse(dnh) do
+ if has_attr(x, attr_dir)%dir_node_auto==l_dir then
+ db = x; break
+ end
+ end
+ if not db then
+ db = create_dir_node(s, s_dir, l_dir, true)
+ setfield(db, 'next', dnh)
+ setfield(wh, 'value',to_node(db))
+ end
+ setfield(db, key, scan_dimen())
+ return false
+ else
+ setfield(s, key, scan_dimen())
+ if wh then
+ -- change dimension of dir_nodes which are created "automatically"
+ local bw, bh, bd
+ = getfield(s,'width'), getfield(s, 'height'), getfield(s, 'depth')
+ for x in traverse(getfield(wh, 'value')) do
+ local x_dir = has_attr(x, attr_dir)
+ if x_dir<dir_node_manual then
+ local info = dir_node_aux[s_dir][x_dir%dir_node_auto]
+ setfield(x, 'width', info.width(bw,bh,bd))
+ setfield(x, 'height', info.height(bw,bh,bd))
+ setfield(x, 'depth', info.depth(bw,bh,bd))
+ end
+ end
+ end
+ return true
+ end
+ end
+ local function set_box_dim(key)
+ local s = getbox(scan_int()); scan_keyword('=')
+ if s then
+ local l_dir = (get_dir_count())%dir_math_mod
+ s = to_direct(s)
+ local b_dir = get_box_dir(s,dir_yoko)
+ if b_dir<dir_node_auto then
+ set_box_dim_common(key, s, l_dir)
+ elseif b_dir%dir_math_mod == l_dir then
+ -- s is dir_node
+ setfield(s, key, scan_dimen())
+ if b_dir<dir_node_manual then
+ set_attr(s, attr_dir, b_dir%dir_node_auto + dir_node_manual)
+ end
+ else
+ local sid, b = getid(s), getlist(s)
+ local info = dir_node_aux[get_box_dir(b,dir_yoko)%dir_math_mod][b_dir%dir_node_auto]
+ local bw, bh, bd
+ = getfield(b,'width'), getfield(b, 'height'), getfield(b, 'depth')
+ local sw, sh, sd
+ = getfield(s,'width'), getfield(s, 'height'), getfield(s, 'depth')
+ if set_box_dim_common(key, b, l_dir) and b_dir<dir_node_manual then
+ -- re-calculate dimension of s, if s is created "automatically"
+ if b_dir<dir_node_manual then
+ setfield(s, 'width', info.width(bw,bh,bd))
+ setfield(s, 'height', info.height(bw,bh,bd))
+ setfield(s, 'depth', info.depth(bw,bh,bd))
+ end
+ end
+ end
+ end
+ end
+ luatexja.direction.set_box_dim = set_box_dim
+end
+
+do
+ local getbox = tex.getbox
+ local function get_register_dir(n)
+ local s = getbox(n)
+ if s then
+ s = to_direct(s)
+ local b_dir = get_box_dir(s, dir_yoko)
+ if b_dir<dir_node_auto then
+ return b_dir
+ else
+ local b_dir = get_box_dir(
+ node_next(node_next(node_next(getlist(s)))), dir_yoko)
+ return b_dir
+ end
+ else
+ return 0
+ end
+ end
+ luatexja.direction.get_register_dir = get_register_dir
+end
+
+do
+ local getbox, setbox, copy_list = tex.getbox, tex.setbox, node.direct.copy_list
+ -- raise, lower
+ function luatexja.direction.raise_box()
+ start_time_measure('box_primitive_hook')
+ local list_dir = get_dir_count()
+ local s = getbox('ltj@afbox')
+ if s then
+ local sd = to_direct(s)
+ local box_dir = get_box_dir(sd, dir_yoko)
+ if box_dir%dir_math_mod ~= list_dir then
+ setbox(
+ 'ltj@afbox',
+ to_node(copy_list(make_dir_whatsit(sd, sd, list_dir, 'box_move')))
+ -- copy_list ã—ãªã„ã¨ãƒªã‚¹ãƒˆã®æ•´åˆæ€§ãŒå´©ã‚Œã‚‹â€¦â€¦ï¼Ÿ
+ )
+ end
+ end
+ stop_time_measure('box_primitive_hook')
+ end
+end
+
+-- PACKED ã® hbox ã‹ã‚‰æ–‡å­—ã‚’å–り出ã™
+-- luatexja.jfmglue.check_box ãªã©ã§ä½¿ç”¨
+do
+ local function glyph_from_packed(h)
+ local b = getlist(h)
+ return (getid(b)==id_kern or (getid(b)==id_whatsit and getsubtype(b)==sid_save) )
+ and node_next(node_next(node_next(b))) or b
+ end
+ luatexja.direction.glyph_from_packed = glyph_from_packed
+end
+
+-- adjust
+do
+ local id_adjust = node.id('adjust')
+ function luatexja.direction.check_adjust_direction()
+ start_time_measure('box_primitive_hook')
+ local list_dir = get_adjust_dir_count()
+ local a = tex_nest[tex_nest.ptr].tail
+ local ad = to_direct(a)
+ if a and getid(ad)==id_adjust then
+ local adj_dir = get_box_dir(ad)
+ if list_dir~=adj_dir then
+ ltjb.package_error(
+ 'luatexja',
+ 'Direction Incompatible',
+ "\\vadjust's argument and outer vlist must have same direction.")
+ node.direct.last_node()
+ end
+ end
+ stop_time_measure('box_primitive_hook')
+ end
+end
+
+-- insert
+do
+ local id_ins = node.id('ins')
+ local id_rule = node.id('rule')
+ function luatexja.direction.populate_insertion_dir_whatsit()
+ start_time_measure('box_primitive_hook')
+ local list_dir = get_dir_count()
+ local a = tex_nest[tex_nest.ptr].tail
+ local ad = to_direct(a)
+ if (not a) or getid(ad)~=id_ins then
+ a = node.tail(tex.lists.page_head); ad = to_direct(a)
+ end
+ if a and getid(ad)==id_ins then
+ local h = getfield(ad, 'head')
+ if getid(h)==id_whatsit and
+ getsubtype(h)==sid_user and getfield(h, 'user_id')==DIR then
+ local n = h; h = node_remove(h,h)
+ node_free(n)
+ end
+ for box_rule in traverse(h) do
+ if getid(box_rule)<id_rule then
+ h = insert_before(h, box_rule, dir_pool[list_dir]())
+ end
+ end
+ ensure_tex_attr(attr_dir, 0)
+ setfield(ad, 'head', h)
+ end
+ stop_time_measure('box_primitive_hook')
+ end
+end
+
+-- vsplit
+do
+ local split_dir_whatsit, split_dir_head
+ local cat_lp = luatexbase.catcodetables['latex-package']
+ local sprint, scan_int, tex_getbox = tex.sprint, token.scan_int, tex.getbox
+ function luatexja.direction.vsplit()
+ local n = scan_int();
+ local p = to_direct(tex_getbox(n))
+ split_dir_head = nil
+ if p then
+ local bh = getlist(p)
+ if getid(bh)==id_whatsit and getsubtype(bh)==sid_user and getfield(bh, 'user_id')==DIR
+ and node_next(bh) then
+ ltjs.list_dir = has_attr(bh, attr_dir)
+ local q = node_next(p)
+ setfield(p, 'head', node_remove(bh,bh,bh))
+ split_dir_head = bh
+ end
+ end
+ sprint(cat_lp, '\\ltj@@orig@vsplit' .. tostring(n))
+ end
+ local function dir_adjust_vpack(h, gc)
+ start_time_measure('direction_vpack')
+ local hd = to_direct(h)
+ if gc=='split_keep' then
+ -- supply dir_whatsit
+ hd = create_dir_whatsit_vbox(hd, gc)
+ split_dir_whatsit = hd
+ elseif gc=='split_off' then
+ if split_dir_head then
+ list_dir = has_attr(split_dir_head, attr_dir)
+ hd = insert_before(hd, hd, split_dir_head)
+ split_dir_head=nil
+ end
+ if split_dir_whatsit then
+ -- adjust direction of 'split_keep'
+ set_attr(split_dir_whatsit, attr_dir, ltjs.list_dir)
+ end
+ split_dir_whatsit=nil
+ elseif gc=='preamble' then
+ split_dir_whatsit=nil
+ else
+ adjust_badness(hd)
+ -- hd = process_dir_node(create_dir_whatsit_vbox(hd, gc), gc)
+ -- done in append_to_vpack callback
+ hd = create_dir_whatsit_vbox(hd, gc)
+ split_dir_whatsit=nil
+ end
+ stop_time_measure('direction_vpack')
+ return to_node(hd)
+ end
+ ltjb.add_to_callback('vpack_filter',
+ dir_adjust_vpack,
+ 'ltj.direction', 10000)
+end
+
+do
+ -- supply direction whatsit to the main vertical list "of the next page"
+ local function dir_adjust_pre_output(h, gc)
+ return to_node(create_dir_whatsit_vbox(to_direct(h), gc))
+ end
+ ltjb.add_to_callback('pre_output_filter',
+ dir_adjust_pre_output,
+ 'ltj.direction', 10000)
+
+ function luatexja.direction.remove_end_whatsit()
+ local h=tex.lists.page_head
+ if h and (not h.next) and
+ h.id==id_whatsit and h.subtype==sid_user and
+ h.user_id == DIR then
+ tex.lists.page_head = nil
+ node.free(h)
+ end
+ end
+end
+
+-- append_to_vlist filter: done in ltj-lineskip.lua
+
+-- finalize (executed just before \shipout)
+-- we supply correct pdfsavematrix nodes etc. inside dir_node
+do
+ local finalize_inner
+ local function finalize_dir_node(db,new_dir)
+ local b = getlist(db)
+ if getid(b)==id_whatsit and getsubtype(b)==sid_user
+ and getfield(b, 'user_id')==DIR then
+ local ob = b; b = node_remove(b,b); setfield(db, 'head', b);
+ node_free(ob)
+ end
+ finalize_inner(b)
+ local w = getfield(b, 'width')
+ local h = getfield(b, 'height')
+ local d = getfield(b, 'depth')
+ local dn_w = getfield(db, 'width')
+ local dn_h = getfield(db, 'height')
+ local dn_d = getfield(db, 'depth')
+ local db_head, db_tail
+ local t = dir_node_aux[get_box_dir(b, dir_yoko)%dir_math_mod][new_dir]
+ t = t and t[getid(b)]; if not t then return end
+ for _,v in ipairs(t) do
+ local cmd, arg, nn = v[1], v[2]
+ if cmd=='kern' then
+ nn = node_new(id_kern, 1)
+ setfield(nn, 'kern', arg(w, h, d, dn_w, dn_h, dn_d))
+ elseif cmd=='whatsit' then
+ nn = node_new(id_whatsit, arg)
+ elseif cmd=='rotate' then
+ nn = node_new(id_whatsit, sid_matrix)
+ setfield(nn, 'data', arg)
+ elseif cmd=='box' then
+ nn = b; setfield(b, 'next', nil)
+ setfield(nn, 'shift', arg(w, h, d, dn_w, dn_h, dn_d))
+ end
+ if db_head then
+ insert_after(db_head, db_tail, nn)
+ db_tail = nn
+ else
+ setfield(db, 'head', nn)
+ db_head, db_tail = nn, nn
+ end
+ end
+ end
+
+ tex.setattribute(attr_dir, dir_yoko)
+ local shipout_temp = node_new(id_hlist)
+ tex.setattribute(attr_dir, 0)
+
+ finalize_inner = function (box)
+ for n in traverse(getlist(box)) do
+ local nid = getid(n)
+ if (nid==id_hlist or nid==id_vlist) then
+ local ndir = get_box_dir(n, dir_yoko)
+ if ndir>=dir_node_auto then -- n is dir_node
+ finalize_dir_node(n, ndir%dir_math_mod)
+ else
+ finalize_inner(n)
+ end
+ end
+ end
+ end
+ local getbox = tex.getbox
+ local setbox, copy = node.direct.setbox, node.direct.copy
+ local lua_mem_kb = 0
+ function luatexja.direction.finalize()
+ local a = to_direct(tex.getbox("AtBeginShipoutBox"))
+ local a_dir = get_box_dir(a, dir_yoko)
+ if a_dir~=dir_yoko then
+ local b = create_dir_node(a, a_dir, dir_yoko, false)
+ setfield(b, 'head', a); a = b
+ end
+ setfield(shipout_temp, 'head', a)
+ finalize_inner(shipout_temp)
+ setbox('global', "AtBeginShipoutBox", copy(getlist(shipout_temp)))
+ setfield(shipout_temp, 'head',nil)
+ -- garbage collect
+ --local m = collectgarbage('count')
+ --if m>lua_mem_kb+20480 then
+ -- collectgarbage(); lua_mem_kb = collectgarbage('count')
+ --end
+ --print('Lua Memory Usage', lua_mem_kb)
+ end
+end
diff --git a/macros/luatex/generic/luatexja/src/ltj-inputbuf.lua b/macros/luatex/generic/luatexja/src/ltj-inputbuf.lua
new file mode 100644
index 0000000000..e901d43891
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-inputbuf.lua
@@ -0,0 +1,53 @@
+--
+-- luatexja/ltj-inputbuf.lua
+--
+
+luatexja.load_module('base'); local ltjb = luatexja.base
+luatexja.load_module('charrange'); local ltjc = luatexja.charrange
+
+require("unicode")
+local utflen = utf.len
+local utfbyte = utf.byte
+local utfchar = utf.char
+local node_new = node.new
+local node_free = node.free
+local id_glyph = node.id('glyph')
+local getcatcode, getcount = tex.getcatcode, tex.getcount
+local ltjc_is_japanese_char_curlist = ltjc.is_japanese_char_curlist
+
+--- the following function is modified from jafontspec.lua (by K. Maeda).
+--- Instead of "%", we use U+FFFFF for suppressing spaces.
+--DEBUG require"socket"
+local time_line = 0
+local start_time_measure, stop_time_measure
+ = ltjb.start_time_measure, ltjb.stop_time_measure
+local function add_comment(buffer)
+ start_time_measure('inputbuf')
+ local i = utflen(buffer)
+ while (i>0) and (getcatcode(utfbyte(buffer, i))==1
+ or getcatcode(utfbyte(buffer, i))==2) do
+ i=i-1
+ end
+ if i>0 then
+ local c = utfbyte(buffer, i)
+ if c>=0x80 then
+ local ct = getcatcode(c)
+ local te = tex.endlinechar
+ local ctl = (te ~= -1) and (getcatcode(te)==5) and (getcatcode(getcount('ltjlineendcomment'))==14)
+ -- Is the catcode of endline character is 5 (end-of-line)?
+ -- Is the catcode of \ltjlineendcomment (new comment char) is 14 (comment)?
+ if ((ct==11) or (ct==12)) and ctl then
+ if ltjc_is_japanese_char_curlist(c) then
+ buffer = buffer .. utfchar(getcount('ltjlineendcomment'))
+ end
+ end
+ end
+ end
+ stop_time_measure('inputbuf')
+ return buffer
+end
+
+luatexbase.add_to_callback('process_input_buffer',
+ add_comment,'ltj.process_input_buffer')
+
+--EOF
diff --git a/macros/luatex/generic/luatexja/src/ltj-ivd_aj1.lua b/macros/luatex/generic/luatexja/src/ltj-ivd_aj1.lua
new file mode 100644
index 0000000000..424b1ef472
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-ivd_aj1.lua
@@ -0,0 +1,23096 @@
+return {
+version = 2,
+table_ivd_aj1 = {
+-- # IVD_Sequences
+-- #
+-- # History:
+-- #
+-- # 2017-12-12 Registration of additional sequences in the Adobe-Japan1
+-- # collection. Combined registration of the KRName collection
+-- # and of sequences in that collection. Registration of
+-- # additional sequences in the Moji_Joho collection.
+-- #
+-- # 2016-08-15 Combined registration of the MSARG collection and of
+-- # sequences in that collection.
+-- #
+-- # 2014-05-16 Combined registration of the Moji_Joho collection and of
+-- # sequences in that collection.
+-- #
+-- # 2012-07-02 File restored due to corruption on the server.
+-- #
+-- # 2012-03-02 Registration of additional sequences in the Adobe-Japan1
+-- # collection. Registration of additional sequences in the
+-- # Hanyo-Denshi collection.
+-- #
+-- # 2010-11-14 Combined registration of the Hanyo-Denshi collection and
+-- # of sequences in that collection.
+-- #
+-- # 2007-12-14 Combined registration of the Adobe-Japan1 collection and
+-- # of sequences in that collection.
+-- #
+-- # This file is part of the Unicode Ideographic Variation Database (IVD).
+-- # For more details on the IVD, see UTS #37:
+-- # http://www.unicode.org/reports/tr37/
+-- #
+-- # Copyright 2006-2017 Unicode, Inc.
+-- # For terms of use, see: http://www.unicode.org/terms_of_use.html
+-- #
+-- # EOF
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ 2117341,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ 2117276,
+ 2118934,
+ 2120195,
+ 2135615,
+ 2118848,
+ 2122011,
+ 2122536,
+ 2120182,
+ 2134050,
+ 2131061,
+ 2130716,
+ 2128464,
+ 2121898,
+ 2122721,
+ 2125349,
+ 2123245,
+ 2131046,
+ 2130598,
+ 2137077,
+ 2123923,
+ 2119463,
+ 2123169,
+ 2122353,
+ 2120603,
+ 2120144,
+ 2131579,
+ 2136308,
+ 2129250,
+ 2129342,
+ 2136974,
+ 2122262,
+ 2129055,
+ 2132151,
+ 2120585,
+ 2121397,
+ 2122505,
+ 2123415,
+ 2123848,
+ 2135495,
+ 2135949,
+ 2123599,
+ 2117349,
+ 2117386,
+ 2117453,
+ 2117533,
+ 2117705,
+ 2119410,
+ 2119991,
+ 2120148,
+ 2120193,
+ 2120713,
+ 2121951,
+ 2121999,
+ 2122096,
+ 2123283,
+ 2124037,
+ 2126010,
+ 2127183,
+ 2127216,
+ 2128379,
+ 2129325,
+ 2129391,
+ 2130115,
+ 2130958,
+ 2132067,
+ 2132738,
+ 2134101,
+ 2134138,
+ 2118459,
+ 2117269,
+ 2117285,
+ 2119647,
+ 2130098,
+ 2134209,
+ 2128111,
+ 2117120,
+ 2119921,
+ 2125474,
+ 2134072,
+ 2128434,
+ 2130728,
+ 2130571,
+ 2137135,
+ 2117953,
+ 2118512,
+ 2118845,
+ 2118881,
+ 2119392,
+ 2120187,
+ 2121493,
+ 2136306,
+ 2125291,
+ 2130148,
+ 2131245,
+ 2135650,
+ 2135664,
+ 2135712,
+ 2136059,
+ 2118667,
+ 2118643,
+ 2120583,
+ 2126031,
+ 4227005,
+ 2133954,
+ 2135784,
+ 2118511,
+ 2137436,
+ 2128570,
+ 2117137,
+ 2128019,
+ 2130428,
+ 2125350,
+ 2119192,
+ 2118916,
+ 2124573,
+ 2131226,
+ 2137147,
+ 2120165,
+ 2118569,
+ 2125158,
+ 2127068,
+ 2135439,
+ 2119234,
+ 2117265,
+ 2134091,
+ 2135794,
+ 2130767,
+ 2136332,
+ 2118625,
+ 2119094,
+ 2120496,
+ 2121585,
+ 2123296,
+ 2123507,
+ 2123780,
+ 2124856,
+ 2125043,
+ 2125097,
+ 2126939,
+ 2127560,
+ 2128462,
+ 2136116,
+ 2130673,
+ 2132059,
+ 2132576,
+ 2134765,
+ 2125234,
+ 2127275,
+ 2127562,
+ 2136517,
+ 2121894,
+ 4229889,
+ 2133386,
+ 2135474,
+ 2124174,
+ 2118573,
+ 2118022,
+ 2119442,
+ 2119728,
+ 2120004,
+ 2120628,
+ 2121462,
+ 2121768,
+ 2122665,
+ 2122740,
+ 4222143,
+ 2125588,
+ 2125966,
+ 2126100,
+ 2126169,
+ 2126293,
+ 2126655,
+ 2129409,
+ 2130550,
+ 2130641,
+ 2131351,
+ 2134112,
+ 2134619,
+ 2137371,
+ 2119785,
+ 2123196,
+ 2124890,
+ 2127141,
+ 2118137,
+ 2119982,
+ 2120037,
+ 2121600,
+ 2121692,
+ 2122428,
+ 2123258,
+ 2124330,
+ 2124583,
+ 2124724,
+ 2126731,
+ 2129857,
+ 2132310,
+ 2137388,
+ 2137358,
+ 2137796,
+ 2120865,
+ 2124950,
+ 2130811,
+ 2117892,
+ 2120779,
+ 2122166,
+ 2130374,
+ 2123894,
+ 2126433,
+ 2117209,
+ 2117626,
+ 2118520,
+ 2121833,
+ 2125353,
+ 2128463,
+ 2136051,
+ 2117131,
+ 2118422,
+ 2117358,
+ 2117461,
+ 2117437,
+ 2117537,
+ 2117491,
+ 2118304,
+ 2118639,
+ 2119177,
+ 2119951,
+ 2120385,
+ 2120630,
+ 2120673,
+ 2128337,
+ 2123399,
+ 2123676,
+ 2123702,
+ 2124620,
+ 2124979,
+ 2125931,
+ 2126786,
+ 4225421,
+ 2128318,
+ 2128444,
+ 2128775,
+ 2130609,
+ 2130651,
+ 2130692,
+ 2130807,
+ 2130927,
+ 2130899,
+ 2131814,
+ 2132658,
+ 2119209,
+ 2133160,
+ 2133990,
+ 2134094,
+ 2135838,
+ 2131594,
+ 2117572,
+ 2120936,
+ 2122257,
+ 2126425,
+ 2127163,
+ 2130405,
+ 4227773,
+ 2131710,
+ 2133184,
+ 2135749,
+ 2136339,
+ 2136533,
+ 2117323,
+ 2117402,
+ 2132451,
+ 2119390,
+ 2119754,
+ 2119882,
+ 2121467,
+ 2121707,
+ 2121770,
+ 4219028,
+ 2121826,
+ 2122192,
+ 2122258,
+ 2122448,
+ 2123065,
+ 2136897,
+ 2123366,
+ 2123952,
+ 4222327,
+ 2125936,
+ 2127180,
+ 2127494,
+ 2129269,
+ 2130597,
+ 2131961,
+ 2135435,
+ 2135694,
+ 2133149,
+ 2118129,
+ 2118334,
+ 2119958,
+ 2118835,
+ 2120627,
+ 2120982,
+ 2122088,
+ 2124162,
+ 2125231,
+ 2128013,
+ 2131147,
+ 2132055,
+ 2132594,
+ 2134951,
+ 2136760,
+ 2125164,
+ 2136488,
+ 2131673,
+ 2119587,
+ 2123775,
+ 2131662,
+ 2134542,
+ 2118275,
+ 2119303,
+ 2118660,
+ 2121427,
+ 2122465,
+ 2122937,
+ 2123836,
+ 2123832,
+ 2124731,
+ 2126706,
+ 2128058,
+ 2128491,
+ 2132378,
+ 4229586,
+ 2133355,
+ 2133763,
+ 2134253,
+ 2135459,
+ 2135700,
+ 2135913,
+ 2120550,
+ 2120883,
+ 2124157,
+ 2136141,
+ 2136142,
+ 2122651,
+ 2128672,
+ 2124331,
+ 2124415,
+ 2123958,
+ 2137101,
+ 2125663,
+ 4215410,
+ 2119069,
+ 2121840,
+ 2122476,
+ 2125115,
+ 2125319,
+ 2125521,
+ 2131035,
+ 2132240,
+ 2133828,
+ 2117140,
+ 2137145,
+ 2118646,
+ 2124059,
+ 2124346,
+ 2135940,
+ 2123818,
+ 2117980,
+ 2128579,
+ 2131122,
+ 2134492,
+ 2134924,
+ 2119259,
+ 2137384,
+ 2123810,
+ 2130693,
+ 2130993,
+ 2129061,
+ 2118152,
+ 2130629,
+ 2127078,
+ 2117246,
+ 2117507,
+ 2118048,
+ 2120658,
+ 2118154,
+ 2118360,
+ 2118375,
+ 2121211,
+ 2119066,
+ 2119722,
+ 2120166,
+ 2120588,
+ 2120600,
+ 2120667,
+ 2121330,
+ 2121337,
+ 2121891,
+ 2122015,
+ 2122083,
+ 2122174,
+ 2122715,
+ 2123106,
+ 2123729,
+ 2123859,
+ 2124026,
+ 2124606,
+ 2124627,
+ 2124887,
+ 2125602,
+ 2125719,
+ 2125637,
+ 2127024,
+ 2127128,
+ 2127587,
+ 2127627,
+ 2128639,
+ 2128801,
+ 2128929,
+ 2129385,
+ 2129718,
+ 2129904,
+ 2130077,
+ 2130534,
+ 2130846,
+ 2132403,
+ 2132684,
+ 2133163,
+ 2134148,
+ 2135121,
+ 2135443,
+ 2135441,
+ 2135458,
+ 2135653,
+ 2136019,
+ 2136360,
+ 2130456,
+ 2117176,
+ 2118699,
+ 2120888,
+ 2121164,
+ 2126761,
+ 2127436,
+ 2127676,
+ 2120873,
+ 2129899,
+ 2133259,
+ 2135745,
+ 2136081,
+ 2136148,
+ 2136152,
+ 2117377,
+ 2117390,
+ 2118513,
+ 2119068,
+ 2119272,
+ 2119674,
+ 2120007,
+ 2120457,
+ 2120644,
+ 2120848,
+ 2121228,
+ 2121342,
+ 2121676,
+ 2122734,
+ 2123578,
+ 2123223,
+ 4220386,
+ 2123551,
+ 2123979,
+ 2123972,
+ 2124383,
+ 2121264,
+ 2124741,
+ 2124823,
+ 2124925,
+ 2127231,
+ 4225352,
+ 2120547,
+ 2128384,
+ 2129152,
+ 2121661,
+ 2132367,
+ 2132504,
+ 2133172,
+ 2133367,
+ 2133708,
+ 2133789,
+ 2136290,
+ 2136590,
+ 2136892,
+ 2117248,
+ 2117757,
+ 2117888,
+ 2120083,
+ 2120604,
+ 2122287,
+ 2122368,
+ 2122988,
+ 2124602,
+ 2126496,
+ 2127249,
+ 2128199,
+ 2129833,
+ 2131963,
+ 2132668,
+ 2132848,
+ 2122668,
+ 2130890,
+ 2135968,
+ 2118665,
+ 2118659,
+ 2119083,
+ 2123860,
+ 2124376,
+ 2132592,
+ 2127911,
+ 2123637,
+ 2137805,
+ 2118516,
+ 2120610,
+ 2130202,
+ 2131536,
+ 2134022,
+ 2117144,
+ 2117189,
+ 2117319,
+ 2117393,
+ 2118602,
+ 2118712,
+ 2120622,
+ 2121491,
+ 2121765,
+ 2123089,
+ 2123581,
+ 2124866,
+ 2124914,
+ 2125027,
+ 2125944,
+ 2126851,
+ 2128502,
+ 2128558,
+ 2128648,
+ 2129178,
+ 2129150,
+ 2129254,
+ 2123239,
+ 2126427,
+ 2118587,
+ 2120773,
+ 2121192,
+ 2122450,
+ 2122464,
+ 2122521,
+ 2125344,
+ 2131546,
+ 2132529,
+ 2133469,
+ 2134776,
+ 2125569,
+ 2128294,
+ 2136922,
+ 2117288,
+ 2117291,
+ 2117292,
+ 2117531,
+ 2117536,
+ 2117841,
+ 2117959,
+ 2128630,
+ 2118001,
+ 2118134,
+ 2118484,
+ 2118433,
+ 4215679,
+ 2118635,
+ 2119084,
+ 2119811,
+ 2120929,
+ 2121527,
+ 2121546,
+ 2121775,
+ 2121808,
+ 2121837,
+ 2122527,
+ 2123097,
+ 2124363,
+ 2124993,
+ 2126530,
+ 2126573,
+ 2127855,
+ 2130168,
+ 2130181,
+ 2130440,
+ 2131278,
+ 2134263,
+ 2135009,
+ 2136063,
+ 2136407,
+ 2136666,
+ 2117360,
+ 2118109,
+ 2120749,
+ 2123393,
+ 2124141,
+ 2120768,
+ 2123506,
+ 2124149,
+ 2126729,
+ 2123856,
+ 2129025,
+ 2117829,
+ 2118372,
+ 2119495,
+ 2121214,
+ 2134822,
+ 2123172,
+ 2124579,
+ 2124605,
+ 2126900,
+ 2128257,
+ 2128317,
+ 2128715,
+ 2129354,
+ 2130617,
+ 2130892,
+ 2132095,
+ 2132319,
+ 4229945,
+ 2133969,
+ 2134481,
+ 2118687,
+ 2134656,
+ 2117213,
+ 2117686,
+ 2118629,
+ 2118458,
+ 2126551,
+ 2126742,
+ 2127849,
+ 2130662,
+ 2133679,
+ 2136518,
+ 2136520,
+ 2136530,
+ 2118007,
+ 2122010,
+ 2131550,
+ 2119088,
+ 2128506,
+ 2117750,
+ 2120659,
+ 2134087,
+ 2135685,
+ 2117170,
+ 4221659,
+ 2134503,
+ 2120785,
+ 2120776,
+ 2122648,
+ 2128543,
+ 2124947,
+ 2135924,
+ 2133857,
+ 2128554,
+ 2126218,
+ 2135688,
+ 2129026,
+ 2123799,
+ 2129520,
+ 2123857,
+ 2134892,
+ 2118386,
+ 2118683,
+ 2131371,
+ 2132499,
+ 2129828,
+ 2133709,
+ 2134241,
+ 2118502,
+ 2132104,
+ 2128193,
+ 2117570,
+ 2117822,
+ 2118161,
+ 2117956,
+ 2118995,
+ 2119469,
+ 2126826,
+ 2119563,
+ 2120017,
+ 2121570,
+ 2121604,
+ 2121845,
+ 2122102,
+ 2122087,
+ 2122153,
+ 2122674,
+ 2122810,
+ 2123116,
+ 2123375,
+ 2123842,
+ 2125331,
+ 2127206,
+ 2128445,
+ 2129147,
+ 2129228,
+ 2129305,
+ 2129483,
+ 2129771,
+ 2130702,
+ 2130762,
+ 2131661,
+ 2132488,
+ 2132579,
+ 2132838,
+ 2133757,
+ 2136090,
+ 2137487,
+ 2130616,
+ 2133966,
+ 2137064,
+ 2118279,
+ 2122271,
+ 2122883,
+ 2125760,
+ 2135705,
+ 2123841,
+ 2117777,
+ 2124576,
+ 2124922,
+ 2125652,
+ 2128500,
+ 2129232,
+ 2132032,
+ 2132515,
+ 2123528,
+ 2117366,
+ 2117689,
+ 2117670,
+ 2117733,
+ 2118012,
+ 2118200,
+ 2118243,
+ 2119079,
+ 2119439,
+ 2119685,
+ 2120396,
+ 2121466,
+ 2122162,
+ 2122232,
+ 2122483,
+ 2122610,
+ 2124060,
+ 2124329,
+ 2126461,
+ 2126508,
+ 2126638,
+ 2127892,
+ 2127983,
+ 2129273,
+ 2127628,
+ 2130089,
+ 2132363,
+ 2132761,
+ 2133218,
+ 2133714,
+ 2134115,
+ 2134901,
+ 2135674,
+ 2136149,
+ 2136595,
+ 2137720,
+ 2117955,
+ 2118559,
+ 2118579,
+ 2121339,
+ 2121510,
+ 2125339,
+ 2125456,
+ 2126724,
+ 2126846,
+ 2129219,
+ 2130487,
+ 2132480,
+ 2132730,
+ 2135632,
+ 2117198,
+ 2117643,
+ 2118628,
+ 2118780,
+ 2119418,
+ 2120145,
+ 2120548,
+ 2121201,
+ 2121387,
+ 2121511,
+ 2122296,
+ 2123077,
+ 2123695,
+ 2125398,
+ 2126544,
+ 2129098,
+ 2132148,
+ 2130081,
+ 2130145,
+ 2130928,
+ 2131534,
+ 2132615,
+ 2133480,
+ 2134583,
+ 2135751,
+ 2136167,
+ 2137875,
+ 2117268,
+ 2117266,
+ 2117389,
+ 2118472,
+ 2118729,
+ 2118718,
+ 2120239,
+ 2121612,
+ 2121633,
+ 2121887,
+ 2123943,
+ 2124430,
+ 2126938,
+ 2128001,
+ 2132638,
+ 2132644,
+ 2132855,
+ 2134416,
+ 2117214,
+ 2137033,
+ 2117284,
+ 2117500,
+ 2117551,
+ 2117657,
+ 2117654,
+ 2117961,
+ 2117996,
+ 2118303,
+ 2118329,
+ 2118398,
+ 2118554,
+ 2118627,
+ 2118673,
+ 2118670,
+ 2119049,
+ 2119505,
+ 2119586,
+ 2120061,
+ 2120532,
+ 2120541,
+ 2120591,
+ 2121189,
+ 2121191,
+ 2121207,
+ 2121336,
+ 2121347,
+ 2121370,
+ 2121399,
+ 2121496,
+ 2121810,
+ 2122060,
+ 2122391,
+ 2122456,
+ 2122663,
+ 2123067,
+ 2123266,
+ 2123331,
+ 2123508,
+ 2123629,
+ 2123809,
+ 2123927,
+ 2124235,
+ 2124895,
+ 2125098,
+ 2125161,
+ 2125359,
+ 2125469,
+ 2127154,
+ 2127495,
+ 2127980,
+ 2128447,
+ 2129120,
+ 2129157,
+ 2129176,
+ 2129246,
+ 2129329,
+ 2129941,
+ 2129923,
+ 2130095,
+ 2130097,
+ 2130260,
+ 2130319,
+ 2130474,
+ 2130770,
+ 2132044,
+ 2132065,
+ 2132763,
+ 2133154,
+ 2133244,
+ 2134218,
+ 2134389,
+ 2134641,
+ 2127935,
+ 2134780,
+ 2135460,
+ 2135629,
+ 2136069,
+ 2136473,
+ 2136792,
+ 2137403,
+ 2118235,
+ 2118315,
+ 2118647,
+ 2118664,
+ 2119893,
+ 2122487,
+ 2125792,
+ 2133098,
+ 2133855,
+ 2137785,
+ 2117963,
+ 2118203,
+ 2118730,
+ 2119421,
+ 4225600,
+ 2134391,
+ 2137440,
+ 2137810,
+ 2126660,
+ 2125577,
+ 2130288,
+ 2127121,
+ 2121725,
+ 2121946,
+ 2136744,
+ 2126555,
+ 2133948,
+ 2124644,
+ 2136067,
+ 2117322,
+ 2119408,
+ 2119524,
+ 2119870,
+ 2120282,
+ 2121832,
+ 2122183,
+ 2123279,
+ 2123270,
+ 2123833,
+ 2123953,
+ 2125303,
+ 2127317,
+ 2129210,
+ 2130542,
+ 2136898,
+ 2117275,
+ 2117456,
+ 2118601,
+ 2118918,
+ 2121071,
+ 2121190,
+ 2121198,
+ 2123771,
+ 2124953,
+ 2126963,
+ 2127874,
+ 2132560,
+ 2134934,
+ 2132191,
+ 2119504,
+ 2121383,
+ 2122539,
+ 2117813,
+ 2117804,
+ 4215181,
+ 2123520,
+ 2118857,
+ 2119774,
+ 2120123,
+ 2120624,
+ 2121577,
+ 2122317,
+ 2122657,
+ 2123837,
+ 2124659,
+ 2125320,
+ 2125949,
+ 2134471,
+ 2126464,
+ 2127893,
+ 2127910,
+ 2128237,
+ 2123150,
+ 2129200,
+ 2130908,
+ 2132161,
+ 2133769,
+ 2135707,
+ 2118244,
+ 2119464,
+ 2123600,
+ 2129770,
+ 2133153,
+ 2118068,
+ 2119490,
+ 2135594,
+ 2119738,
+ 2124170,
+ 2130100,
+ 2118834,
+ 2120974,
+ 2119676,
+ 2128021,
+ 2137594,
+ 2117468,
+ 2118218,
+ 2118795,
+ 2122814,
+ 2123304,
+ 2123540,
+ 2123765,
+ 2128516,
+ 2128726,
+ 2129186,
+ 2134831,
+ 2123868,
+ 2137005,
+ 2128697,
+ 2118425,
+ 2118026,
+ 2118199,
+ 2120671,
+ 2122486,
+ 2122926,
+ 2122982,
+ 2123565,
+ 4221882,
+ 2131369,
+ 2135761,
+ 2127504,
+ 2137046,
+ 2122572,
+ 2134790,
+ 2137003,
+ 2127551,
+ 2123346,
+ 2117129,
+ 2117784,
+ 2118594,
+ 2120817,
+ 2121960,
+ 2122898,
+ 2123107,
+ 2123871,
+ 2126310,
+ 2126794,
+ 2127139,
+ 2128791,
+ 2129538,
+ 2131605,
+ 2132867,
+ 2133211,
+ 2134392,
+ 2136336,
+ 2123180,
+ 2123435,
+ 2124683,
+ 2117333,
+ 2117332,
+ 2117434,
+ 2117503,
+ 2118202,
+ 2118648,
+ 2118642,
+ 2119139,
+ 2119387,
+ 2119915,
+ 2120139,
+ 2120137,
+ 2120191,
+ 2120528,
+ 2120781,
+ 2121218,
+ 2121259,
+ 2121687,
+ 2121757,
+ 2122503,
+ 2123055,
+ 2120540,
+ 2123183,
+ 2123197,
+ 2123240,
+ 2123677,
+ 2124642,
+ 2124667,
+ 2124815,
+ 2126661,
+ 2128201,
+ 2128321,
+ 2129144,
+ 2129177,
+ 2129195,
+ 2130082,
+ 2130178,
+ 2130419,
+ 2132374,
+ 2132574,
+ 2132585,
+ 2132582,
+ 2132620,
+ 2132718,
+ 2133191,
+ 2133212,
+ 2135756,
+ 2136316,
+ 2124655,
+ 2117259,
+ 2117436,
+ 2117517,
+ 2117968,
+ 2120535,
+ 2120698,
+ 2122056,
+ 2122497,
+ 2123330,
+ 2124577,
+ 2125515,
+ 2124987,
+ 2126398,
+ 2127037,
+ 2127316,
+ 2128065,
+ 4225338,
+ 2129932,
+ 2129971,
+ 2130410,
+ 2131092,
+ 2133918,
+ 2124880,
+ 2137727,
+ 2121487,
+ 2132824,
+ 2137387,
+ 2128634,
+ 2133752,
+ 2120589,
+ 2135787,
+ 2117123,
+ 2118641,
+ 2119671,
+ 2119985,
+ 2120393,
+ 2120612,
+ 2121865,
+ 2125439,
+ 2125574,
+ 2127294,
+ 2133226,
+ 2120607,
+ 2131200,
+ 2128864,
+ 2117746,
+ 2123764,
+ 2130589,
+ 2120801,
+ 2131274,
+ 2129438,
+ 2130446,
+ 2118041,
+ 2120708,
+ 2122600,
+ 2133350,
+ 2123164,
+ 4223342,
+ 2128190,
+ 2129175,
+ 2129925,
+ 2132765,
+ 2133706,
+ 2134126,
+ 2131655,
+ 2134186,
+ 2117663,
+ 4215546,
+ 2120762,
+ 2123603,
+ 2125948,
+ 4223541,
+ 2134348,
+ 2134472,
+ 2134827,
+ 2130661,
+ 2120642,
+ 2121521,
+ 2121977,
+ 2117179,
+ 2118614,
+ 2120584,
+ 2122315,
+ 2123569,
+ 2124682,
+ 2126569,
+ 2126816,
+ 2128430,
+ 2130283,
+ 2133411,
+ 2134354,
+ 2136470,
+ 2117906,
+ 2118615,
+ 2118762,
+ 2120703,
+ 2122632,
+ 2124345,
+ 2129324,
+ 2135808,
+ 2119386,
+ 2118606,
+ 4215912,
+ 2120599,
+ 2120753,
+ 2121182,
+ 2117614,
+ 2121985,
+ 2122494,
+ 2125106,
+ 2128320,
+ 2128331,
+ 2129218,
+ 2129485,
+ 2129874,
+ 2130413,
+ 2130463,
+ 2131088,
+ 2132038,
+ 2132338,
+ 2132880,
+ 2133620,
+ 2133807,
+ 2134065,
+ 2134347,
+ 2134380,
+ 2135750,
+ 2134428,
+ 2117312,
+ 2117455,
+ 2117957,
+ 2118465,
+ 2121619,
+ 2122254,
+ 2123732,
+ 2124865,
+ 2125323,
+ 2126691,
+ 2129446,
+ 2134477,
+ 2134659,
+ 2118612,
+ 2119961,
+ 2120639,
+ 2125265,
+ 4225373,
+ 2129454,
+ 2129051,
+ 2119806,
+ 2126239,
+ 2118138,
+ 2132051,
+ 2134000,
+ 2117578,
+ 2120955,
+ 2123301,
+ 2127788,
+ 2128611,
+ 2130460,
+ 2136575,
+ 2118086,
+ 2121642,
+ 2123244,
+ 2124143,
+ 2124681,
+ 2125299,
+ 2125462,
+ 2125668,
+ 2127614,
+ 2129172,
+ 2121185,
+ 2134133,
+ 2134407,
+ 2136070,
+ 2118118,
+ 2118173,
+ 2122304,
+ 2123409,
+ 2123481,
+ 4222490,
+ 2121398,
+ 2129362,
+ 4226930,
+ 2123512,
+ 2131375,
+ 2131447,
+ 4229880,
+ 2118313,
+ 2118617,
+ 2120051,
+ 2121359,
+ 2121616,
+ 2121813,
+ 2134756,
+ 2135652,
+ 2117815,
+ 2117919,
+ 2118365,
+ 2118432,
+ 2118471,
+ 2118636,
+ 2118888,
+ 2118982,
+ 2118961,
+ 2119191,
+ 2120040,
+ 2120126,
+ 2120252,
+ 2120629,
+ 4217862,
+ 2120719,
+ 2120721,
+ 2120730,
+ 2121348,
+ 2121354,
+ 2121440,
+ 2121584,
+ 2122367,
+ 2122372,
+ 2122459,
+ 2122636,
+ 2122615,
+ 2123271,
+ 2123276,
+ 2123309,
+ 2123382,
+ 2123646,
+ 2123938,
+ 2124319,
+ 2124341,
+ 2124988,
+ 2125192,
+ 2125321,
+ 2125400,
+ 2126140,
+ 2126118,
+ 2126183,
+ 2127303,
+ 2127617,
+ 2127965,
+ 2128129,
+ 4225381,
+ 2128368,
+ 2128608,
+ 2128657,
+ 2129063,
+ 2129209,
+ 2130070,
+ 2130902,
+ 2131083,
+ 2131273,
+ 2132061,
+ 2132211,
+ 2132511,
+ 2132540,
+ 2132564,
+ 2132595,
+ 2133089,
+ 2133214,
+ 2134436,
+ 2134630,
+ 2134910,
+ 2135064,
+ 2135708,
+ 2135960,
+ 2117130,
+ 2117128,
+ 2117150,
+ 2117207,
+ 2118039,
+ 2118256,
+ 4216782,
+ 2119732,
+ 2119884,
+ 2120482,
+ 2121272,
+ 2121925,
+ 2123006,
+ 2123617,
+ 2123606,
+ 2125124,
+ 2126518,
+ 2127219,
+ 2128483,
+ 2131128,
+ 2132850,
+ 2134456,
+ 2134816,
+ 2119217,
+ 2119668,
+ 2136318,
+ 2122477,
+ 2124045,
+ 2124694,
+ 2126317,
+ 2129492,
+ 2130039,
+ 2130546,
+ 2132454,
+ 2136287,
+ 2131797,
+ 2133937,
+ 2120763,
+ 2117432,
+ 2117601,
+ 2117557,
+ 2118919,
+ 2120224,
+ 2120669,
+ 2120681,
+ 2121667,
+ 2122062,
+ 2122543,
+ 2123184,
+ 2123339,
+ 2124014,
+ 2124187,
+ 2125176,
+ 2125297,
+ 2127155,
+ 2127289,
+ 2127647,
+ 4225374,
+ 2128358,
+ 2129203,
+ 2130403,
+ 2130607,
+ 2131370,
+ 2132394,
+ 2132538,
+ 2133675,
+ 2133915,
+ 2134066,
+ 2134493,
+ 2135815,
+ 2117306,
+ 2117313,
+ 2118147,
+ 2119797,
+ 2119916,
+ 2120715,
+ 2127130,
+ 2120765,
+ 2130254,
+ 2132490,
+ 2133957,
+ 2135651,
+ 2135917,
+ 2128677,
+ 2132687,
+ 2136072,
+ 2134370,
+ 2119411,
+ 2118568,
+ 2134039,
+ 2118713,
+ 2119554,
+ 2121253,
+ 2122664,
+ 2124852,
+ 2125962,
+ 2127713,
+ 2129035,
+ 2129888,
+ 2132080,
+ 2134082,
+ 2134356,
+ 2134800,
+ 2134808,
+ 2135695,
+ 2126942,
+ 2136772,
+ 2120967,
+ 2121065,
+ 2123120,
+ 2123682,
+ 2133416,
+ 2135771,
+ 2122606,
+ 2123593,
+ 2124057,
+ 2130885,
+ 2136087,
+ 2135744,
+ 2132222,
+ 2125700,
+ 2122874,
+ 2120696,
+ 2117142,
+ 2125868,
+ 2127197,
+ 2123311,
+ 2118084,
+ 2118198,
+ 2118370,
+ 2120147,
+ 2121601,
+ 2121767,
+ 2122256,
+ 2123071,
+ 2123124,
+ 2123295,
+ 4220532,
+ 2124018,
+ 2123798,
+ 2124643,
+ 2125317,
+ 2126450,
+ 2127135,
+ 2127579,
+ 4226238,
+ 2130006,
+ 2119920,
+ 2132221,
+ 2132351,
+ 2132640,
+ 2132627,
+ 2132683,
+ 2134045,
+ 2134418,
+ 2135890,
+ 2135897,
+ 2123145,
+ 2128398,
+ 2130182,
+ 2135739,
+ 2121261,
+ 2121948,
+ 2122266,
+ 2123173,
+ 2123284,
+ 2123664,
+ 2127859,
+ 2128461,
+ 2128973,
+ 2129470,
+ 2130186,
+ 2133164,
+ 2133348,
+ 2133473,
+ 2133599,
+ 2128041,
+ 2118151,
+ 2122457,
+ 2122661,
+ 2122818,
+ 2122392,
+ 2132525,
+ 2128515,
+ 2128832,
+ 2132652,
+ 2135786,
+ 2129270,
+ 2130444,
+ 2131785,
+ 2117337,
+ 2117960,
+ 2118467,
+ 2118496,
+ 2120611,
+ 2120706,
+ 2120726,
+ 2121181,
+ 2122278,
+ 2122311,
+ 2122928,
+ 2123795,
+ 2123828,
+ 2125001,
+ 2125125,
+ 2125079,
+ 2123731,
+ 2125660,
+ 2126158,
+ 2126205,
+ 2123211,
+ 2128511,
+ 2128813,
+ 2129370,
+ 2129482,
+ 2129832,
+ 2130298,
+ 2130459,
+ 2130489,
+ 2131366,
+ 2132590,
+ 2133198,
+ 2133493,
+ 2134136,
+ 2134135,
+ 2134701,
+ 2134673,
+ 2135427,
+ 2137006,
+ 2118221,
+ 2119044,
+ 2125624,
+ 2126134,
+ 2117992,
+ 2128261,
+ 2129493,
+ 2130355,
+ 2129102,
+ 2119244,
+ 2119761,
+ 2120872,
+ 2122666,
+ 2123518,
+ 2123517,
+ 2124122,
+ 2126553,
+ 2127247,
+ 2127246,
+ 2128142,
+ 2128214,
+ 2128351,
+ 2129047,
+ 2129184,
+ 2129220,
+ 2131463,
+ 2132532,
+ 2135611,
+ 2134113,
+ 2137888,
+ 2117863,
+ 2118261,
+ 2118604,
+ 2118626,
+ 2117641,
+ 2119082,
+ 2119918,
+ 2120015,
+ 2126397,
+ 2120587,
+ 2120804,
+ 2118429,
+ 2121955,
+ 2121971,
+ 2122588,
+ 2122627,
+ 2122559,
+ 2122683,
+ 2122957,
+ 2123241,
+ 2123513,
+ 2121187,
+ 2124237,
+ 2124285,
+ 2125589,
+ 2126309,
+ 2117257,
+ 2127337,
+ 2127608,
+ 2128531,
+ 2129119,
+ 2129359,
+ 2129308,
+ 2130017,
+ 2130761,
+ 2130776,
+ 2131052,
+ 2131132,
+ 2131451,
+ 2132165,
+ 2133360,
+ 2134017,
+ 2134125,
+ 2134935,
+ 2135836,
+ 2136594,
+ 2117839,
+ 2119831,
+ 4219278,
+ 2130387,
+ 2131253,
+ 2133256,
+ 2134048,
+ 2117571,
+ 2117748,
+ 2118215,
+ 2118515,
+ 2121839,
+ 2122569,
+ 2123615,
+ 2125356,
+ 2133427,
+ 2134047,
+ 2117591,
+ 2120798,
+ 2133194,
+ 2123215,
+ 2129306,
+ 2118482,
+ 2132118,
+ 2118006,
+ 2122691,
+ 2120536,
+ 2120555,
+ 2120714,
+ 2122765,
+ 2123601,
+ 2134108,
+ 2117334,
+ 2119962,
+ 2119978,
+ 2124912,
+ 2132561,
+ 2118974,
+ 2119701,
+ 2120101,
+ 2121968,
+ 2122323,
+ 2123713,
+ 2130485,
+ 2124117,
+ 2135616,
+ 2136516,
+ 2136616,
+ 2117459,
+ 2119686,
+ 2120702,
+ 2129936,
+ 2120881,
+ 2121263,
+ 2121605,
+ 2121760,
+ 2122059,
+ 2122292,
+ 2123519,
+ 2125040,
+ 2125534,
+ 2130126,
+ 2130303,
+ 2130644,
+ 2132107,
+ 2133176,
+ 2134016,
+ 2134062,
+ 2135690,
+ 2137819,
+ 2137051,
+ 2117347,
+ 2118640,
+ 2119975,
+ 2128684,
+ 2134413,
+ 2136140,
+ 2137593,
+ 2125533,
+ 2125863,
+ 2118483,
+ 2118980,
+ 2120581,
+ 2122328,
+ 2122398,
+ 2122451,
+ 2124962,
+ 2125807,
+ 4224034,
+ 2132503,
+ 2135096,
+ 2125761,
+ 2132734,
+ 2130744,
+ 2118119,
+ 2131704,
+ 2118634,
+ 2118633,
+ 2117446,
+ 2134100,
+ 2133936,
+ 2120042,
+ 2130225,
+ 4218365,
+ 2128618,
+ 2133951,
+ 2123994,
+ 2133047,
+ 2126584,
+ 2137160,
+ 2124349,
+ 2132656,
+ 2117177,
+ 2118488,
+ 4216326,
+ 2119526,
+ 2122437,
+ 2122658,
+ 2123238,
+ 2124622,
+ 2125281,
+ 2125403,
+ 2125997,
+ 2127853,
+ 2128623,
+ 2128810,
+ 2129339,
+ 2129981,
+ 2130118,
+ 2131659,
+ 2132629,
+ 2134875,
+ 2119395,
+ 2119879,
+ 2121534,
+ 2123181,
+ 2123414,
+ 2124416,
+ 2124725,
+ 2127159,
+ 2132679,
+ 2117668,
+ 2127845,
+ 2119472,
+ 2121499,
+ 2121829,
+ 2123386,
+ 2124896,
+ 2127348,
+ 2128410,
+ 2129774,
+ 2130420,
+ 2131736,
+ 2134085,
+ 2136499,
+ 2128841,
+ 2127196,
+ 2128633,
+ 2128721,
+ 2131140,
+ 2134032,
+ 2128361,
+ 2128530,
+ 2130742,
+ 2120417,
+ 2127680,
+ 2117165,
+ 2117362,
+ 2120601,
+ 2121696,
+ 2122429,
+ 2123324,
+ 2123761,
+ 2125032,
+ 2131563,
+ 2132087,
+ 2132539,
+ 2134350,
+ 2134771,
+ 2136528,
+ 2124311,
+ 2125862,
+ 4223786,
+ 2130663,
+ 2131031,
+ 2133167,
+ 2117121,
+ 2117958,
+ 2118091,
+ 2119051,
+ 2120693,
+ 2121238,
+ 2121267,
+ 2121345,
+ 2121492,
+ 2121525,
+ 2121579,
+ 2121652,
+ 2122226,
+ 2122513,
+ 2123426,
+ 2123549,
+ 4222830,
+ 2126418,
+ 2127162,
+ 2127674,
+ 2130036,
+ 2130233,
+ 2130296,
+ 2131830,
+ 2132671,
+ 2132700,
+ 2133381,
+ 2133491,
+ 2134682,
+ 2135415,
+ 2136066,
+ 2137317,
+ 2118341,
+ 2122583,
+ 2127604,
+ 2123541,
+ 2124936,
+ 2126797,
+ 2133187,
+ 2134958,
+ 2135667,
+ 2125093,
+ 2119836,
+ 2124046,
+ 2124236,
+ 2134013,
+ 2134938,
+ 2127323,
+ 2134042,
+ 2119770,
+ 2123778,
+ 2122676,
+ 2124283,
+ 2117443,
+ 2125612,
+ 2123736,
+ 2133947,
+ 2131238,
+ 2129332,
+ 2134868,
+ 2124095,
+ 2125680,
+ 2119530,
+ 2119927,
+ 2120492,
+ 2129196,
+ 2126378,
+ 2118666,
+ 2134499,
+ 4234676,
+ 2117293,
+ 2117454,
+ 2117724,
+ 2117749,
+ 2118211,
+ 2133150,
+ 2118728,
+ 2119716,
+ 2120602,
+ 2121245,
+ 2121365,
+ 2121389,
+ 2121463,
+ 2121503,
+ 2121868,
+ 2122421,
+ 2122554,
+ 2122704,
+ 2123951,
+ 2124864,
+ 2128007,
+ 2128270,
+ 2128395,
+ 2129376,
+ 2130503,
+ 2132482,
+ 2132710,
+ 2133572,
+ 2134035,
+ 2134200,
+ 2134317,
+ 2134488,
+ 2137870,
+ 2125029,
+ 2122840,
+ 2122978,
+ 2123125,
+ 2125556,
+ 2127492,
+ 2128667,
+ 2134121,
+ 2134993,
+ 2125498,
+ 2118898,
+ 2121657,
+ 2122916,
+ 2133837,
+ 2133997,
+ 2134596,
+ 2118008,
+ 2119787,
+ 2119977,
+ 2120789,
+ 2121367,
+ 2125307,
+ 2129551,
+ 2127132,
+ 2133180,
+ 2133730,
+ 2136155,
+ 2126009,
+ 2117405,
+ 2124735,
+ 2125745,
+ 2127152,
+ 2135803,
+ 2117966,
+ 2118672,
+ 2119733,
+ 2119767,
+ 2120108,
+ 2120800,
+ 2121618,
+ 2123159,
+ 2123612,
+ 2125345,
+ 2127483,
+ 2130911,
+ 2133229,
+ 2134036,
+ 4231421,
+ 2134861,
+ 2127909,
+ 2127930,
+ 2118314,
+ 2121382,
+ 2119455,
+ 2120052,
+ 2121746,
+ 2117650,
+ 2117978,
+ 4215212,
+ 2118093,
+ 2118144,
+ 2118928,
+ 2119764,
+ 2119768,
+ 2120023,
+ 2120597,
+ 2120950,
+ 2121099,
+ 2121916,
+ 2122389,
+ 2122797,
+ 2123633,
+ 2123843,
+ 2123964,
+ 2123999,
+ 2127575,
+ 2125272,
+ 2125423,
+ 2125211,
+ 2125935,
+ 2126280,
+ 2121555,
+ 2127320,
+ 2128247,
+ 2128713,
+ 2128724,
+ 2128722,
+ 4226262,
+ 2129265,
+ 2118192,
+ 2131043,
+ 2131305,
+ 2131428,
+ 2132494,
+ 2132740,
+ 2133062,
+ 2133519,
+ 2134019,
+ 2134031,
+ 2135065,
+ 2135670,
+ 2136109,
+ 2136624,
+ 2135512,
+ 2117837,
+ 2118357,
+ 2118668,
+ 2119682,
+ 2120718,
+ 2122151,
+ 2122910,
+ 2125086,
+ 2127795,
+ 2128613,
+ 2130164,
+ 2130948,
+ 2134099,
+ 2134661,
+ 2120928,
+ 2137351,
+ 2118463,
+ 2121623,
+ 2121651,
+ 2125212,
+ 2126457,
+ 2127715,
+ 2128319,
+ 2128868,
+ 2124754,
+ 2126572,
+ 2132653,
+ 2123779,
+ 2124385,
+ 2118136,
+ 2128513,
+ 2124084,
+ 2120778,
+ 2137334,
+ 2130667,
+ 2120645,
+ 2134345,
+ 2125854,
+ 2119288,
+ 2120815,
+ 2121927,
+ 2123110,
+ 2124940,
+ 2133082,
+ 2134081,
+ 2136083,
+ 2118737,
+ 2123463,
+ 2134541,
+ 2120008,
+ 2134179,
+ 2118021,
+ 2117197,
+ 2118122,
+ 2131353,
+ 2132750,
+ 2125912,
+ 2122618,
+ 2134859,
+ 2124130,
+ 2136500,
+ 2129412,
+ 2127223,
+ 2118487,
+ 2124128,
+ 2133727,
+ 4232931,
+ 2124893,
+ 2117260,
+ 2120764,
+ 2121488,
+ 2133993,
+ 2118402,
+ 2133201,
+ 2130057,
+ 2131577,
+ 2121471,
+ 2123237,
+ 2117235,
+ 2117989,
+ 2120066,
+ 2120767,
+ 2136046,
+ 2117371,
+ 2120074,
+ 2121677,
+ 2132621,
+ 2125793,
+ 2128304,
+ 2128226,
+ 4217831,
+ 2131057,
+ 2126635,
+ 2126257,
+ 2121332,
+ 2121717,
+ 2122619,
+ 2122906,
+ 2126275,
+ 2129048,
+ 2117187,
+ 2121468,
+ 2117195,
+ 2119644,
+ 2119330,
+ 2121897,
+ 2125763,
+ 2129165,
+ 2130173,
+ 2130227,
+ 2130367,
+ 2133938,
+ 2132375,
+ 2131620,
+ 2121204,
+ 2122378,
+ 2122925,
+ 2132359,
+ 2123639,
+ 2125026,
+ 2125118,
+ 2126902,
+ 2127924,
+ 2120262,
+ 2129781,
+ 2130605,
+ 2136492,
+ 2117619,
+ 2121411,
+ 2122461,
+ 2122642,
+ 2123095,
+ 2123631,
+ 2127555,
+ 2126412,
+ 2130124,
+ 2130106,
+ 2133801,
+ 2134349,
+ 2117645,
+ 2119673,
+ 2120338,
+ 4221061,
+ 2124147,
+ 2126180,
+ 2126589,
+ 2133175,
+ 2119922,
+ 2133216,
+ 2135658,
+ 2134041,
+ 2131839,
+ 2128356,
+ 2127847,
+ 2130985,
+ 2117423,
+ 2118245,
+ 2118490,
+ 2122445,
+ 2123727,
+ 2125002,
+ 2127485,
+ 2128788,
+ 2129045,
+ 2130486,
+ 2131332,
+ 2133995,
+ 2123485,
+ 2125600,
+ 2126342,
+ 2129435,
+ 2130859,
+ 2136513,
+ 2137766,
+ 2118141,
+ 2128817,
+ 2127986,
+ 2128824,
+ 2130055,
+ 2128712,
+ 2124520,
+ 2121313,
+ 2130060,
+ 2127185,
+ 2127200,
+ 2117995,
+ 2134626,
+ 2125452,
+ 2127482,
+ 2134423,
+ 2136810,
+ 2117392,
+ 2129776,
+ 2122396,
+ 2128719,
+ 2135461,
+ 2137321,
+ 2119290,
+ 2119769,
+ 2131684,
+ 2135740,
+ 2117428,
+ 2118180,
+ 2118474,
+ 2118605,
+ 2118619,
+ 2121222,
+ 2122796,
+ 2123153,
+ 2123647,
+ 2124862,
+ 2124878,
+ 2126408,
+ 2126511,
+ 2126829,
+ 2127188,
+ 2129473,
+ 2130476,
+ 2131433,
+ 2133161,
+ 2128836,
+ 2134470,
+ 2126185,
+ 2136082,
+ 4233455,
+ 2122557,
+ 2123369,
+ 2127210,
+ 2127588,
+ 2128080,
+ 2131267,
+ 2131694,
+ 2118442,
+ 4215633,
+ 2118694,
+ 2120067,
+ 2121351,
+ 2121596,
+ 2121906,
+ 2122313,
+ 2122361,
+ 2122411,
+ 2123152,
+ 2124756,
+ 2125004,
+ 2127282,
+ 2127534,
+ 4225169,
+ 2128344,
+ 2129355,
+ 2129783,
+ 2130085,
+ 2132139,
+ 2132665,
+ 2133179,
+ 2134143,
+ 2135902,
+ 2136283,
+ 2124299,
+ 2128952,
+ 2117785,
+ 2120766,
+ 2121646,
+ 2123655,
+ 2124760,
+ 2126901,
+ 2127625,
+ 2129806,
+ 2137915,
+ 2123722,
+ 2128407,
+ 2118457,
+ 2127243,
+ 2136813,
+ 2121574,
+ 2130333,
+ 2130929,
+ 2130072,
+ 2121532,
+ 2121669,
+ 2127202,
+ 2128710,
+ 2134076,
+ 2123879,
+ 2120171,
+ 2120347,
+ 2129168,
+ 2127486,
+ 2132780,
+ 2117621,
+ 2121578,
+ 2124313,
+ 2124855,
+ 2125570,
+ 2127074,
+ 2128232,
+ 2132072,
+ 2132565,
+ 2133113,
+ 2121439,
+ 2122703,
+ 2127301,
+ 2128338,
+ 2130647,
+ 2134824,
+ 2134770,
+ 2131100,
+ 2131693,
+ 2137133,
+ 2118849,
+ 2121580,
+ 2123148,
+ 2125148,
+ 2125845,
+ 2133159,
+ 4230355,
+ 4233275,
+ 4220239,
+ 2127094,
+ 2117133,
+ 2117336,
+ 2119648,
+ 2119979,
+ 2120294,
+ 2120652,
+ 2118056,
+ 2121219,
+ 2121372,
+ 2121750,
+ 2122358,
+ 2123127,
+ 2123175,
+ 2123374,
+ 2125166,
+ 2126390,
+ 2128678,
+ 2130256,
+ 2130330,
+ 2130585,
+ 2132828,
+ 2133152,
+ 2133222,
+ 2133364,
+ 2135580,
+ 2135620,
+ 2117550,
+ 2122923,
+ 2124646,
+ 2130462,
+ 2131041,
+ 2131306,
+ 2134248,
+ 2120705,
+ 2124115,
+ 2136232,
+ 2131066,
+ 2131287,
+ 2117391,
+ 2118255,
+ 2121641,
+ 2121285,
+ 2123533,
+ 2128271,
+ 2130297,
+ 2132231,
+ 2132358,
+ 2125301,
+ 2121495,
+ 2122325,
+ 2124984,
+ 2117327,
+ 2126441,
+ 2136978,
+ 2118150,
+ 2118715,
+ 2119284,
+ 2119859,
+ 2122148,
+ 2122350,
+ 2126106,
+ 2120046,
+ 2129033,
+ 2129118,
+ 2129179,
+ 2135792,
+ 2123143,
+ 2130014,
+ 2117145,
+ 2117493,
+ 2118005,
+ 2119744,
+ 2121315,
+ 2121331,
+ 2121482,
+ 2123716,
+ 2117158,
+ 2131261,
+ 2135433,
+ 2135643,
+ 2129011,
+ 2136065,
+ 2117883,
+ 2119873,
+ 2127446,
+ 2128039,
+ 2118181,
+ 2127781,
+ 2131217,
+ 2128774,
+ 2117711,
+ 2119945,
+ 2126407,
+ 2128839,
+ 2129384,
+ 2133946,
+ 2133972,
+ 2134093,
+ 2117567,
+ 4215497,
+ 2120233,
+ 2121473,
+ 2135981,
+ 2117597,
+ 2130455,
+ 2134762,
+ 2119427,
+ 2122581,
+ 2124649,
+ 2127147,
+ 2132188,
+ 2133780,
+ 2128450,
+ 2118367,
+ 2119827,
+ 2122069,
+ 2122250,
+ 2123438,
+ 2124749,
+ 2128959,
+ 2130921,
+ 2117667,
+ 2117624,
+ 2118405,
+ 2118726,
+ 2119729,
+ 2120009,
+ 2120605,
+ 2120944,
+ 2120943,
+ 2121001,
+ 2121366,
+ 2122417,
+ 2122599,
+ 2123070,
+ 2123193,
+ 2123531,
+ 2125013,
+ 2125025,
+ 2126073,
+ 2127922,
+ 2129451,
+ 2130142,
+ 2130611,
+ 2130956,
+ 2131180,
+ 2131714,
+ 2132242,
+ 2132522,
+ 2133066,
+ 2134182,
+ 2134738,
+ 2136317,
+ 2137331,
+ 2137452,
+ 2117199,
+ 2117281,
+ 2117773,
+ 2118230,
+ 2119498,
+ 2120104,
+ 2121277,
+ 2121688,
+ 2121689,
+ 2122303,
+ 2123444,
+ 2123547,
+ 2123728,
+ 2123986,
+ 2118034,
+ 2129185,
+ 2130090,
+ 2130344,
+ 2132736,
+ 2133132,
+ 2133183,
+ 2134654,
+ 2135602,
+ 2118688,
+ 2136108,
+ 2118423,
+ 2117845,
+ 2118492,
+ 4217000,
+ 2122930,
+ 2123572,
+ 2126439,
+ 2127718,
+ 2128454,
+ 2134502,
+ 2118339,
+ 2124961,
+ 2124678,
+ 2119680,
+ 2121292,
+ 2120020,
+ 2123564,
+ 2129915,
+ 2118113,
+ 2127558,
+ 2122857,
+ 2128104,
+ 2136916,
+ 2137787,
+ 2119627,
+ 2120121,
+ 2123303,
+ 2123674,
+ 2124750,
+ 2118889,
+ 2124249,
+ 2121301,
+ 2130332,
+ 2123669,
+ 2137002,
+ 2123774,
+ 2137170,
+ 2123869,
+ 2117286,
+ 2117603,
+ 2118600,
+ 2122425,
+ 2123563,
+ 2124971,
+ 2133956,
+ 2117549,
+ 2129517,
+ 2137791,
+ 2117127,
+ 2122082,
+ 2125440,
+ 2125611,
+ 2131219,
+ 2118771,
+ 2123562,
+ 2136901,
+ 2121203,
+ 2128789,
+ 2120876,
+ 2120646,
+ 2131740,
+ 2125386,
+ 2131153,
+ 2128404,
+ 2130184,
+ 2120089,
+ 2129037,
+ 2124817,
+ 2127648,
+ 2118361,
+ 2119970,
+ 2126113,
+ 2126431,
+ 2127835,
+ 2135847,
+ 2137441,
+ 2124043,
+ 2120319,
+ 2120216,
+ 2118053,
+ 2118669,
+ 2118781,
+ 2123278,
+ 2127583,
+ 2134007,
+ 2134680,
+ 2137332,
+ 2120170,
+ 2126429,
+ 2125509,
+ 2117965,
+ 2123977,
+ 2129343,
+ 2129388,
+ 2135906,
+ 2137786,
+ 2122872,
+ 2124321,
+ 2130690,
+ 2120068,
+ 2120543,
+ 2124763,
+ 2126619,
+ 2127602,
+ 2129330,
+ 2129943,
+ 2131097,
+ 2117938,
+ 2123560,
+ 2137817,
+ 2127598,
+ 2123618,
+ 2118399,
+ 2136325,
+ 2120740,
+ 2122299,
+ 2129022,
+ 2133168,
+ 2118991,
+ 2121910,
+ 2129163,
+ 2135424,
+ 2118401,
+ 2117215,
+ 2118070,
+ 2119964,
+ 2126394,
+ 2129974,
+ 2134478,
+ 2121509,
+ 2127842,
+ 2118532,
+ 2121593,
+ 2129156,
+ 2131372,
+ 2132531,
+ 2133645,
+ 2135894,
+ 2123763,
+ 2131374,
+ 2135123,
+ 2121993,
+ 2121992,
+ 2124985,
+ 2127442,
+ 4229869,
+ 2133816,
+ 2118959,
+ 2117457,
+ 2117930,
+ 2118343,
+ 2118603,
+ 2120613,
+ 2121341,
+ 2121888,
+ 2122114,
+ 2122710,
+ 2123529,
+ 2123738,
+ 2125415,
+ 2125196,
+ 2126646,
+ 2126647,
+ 2127153,
+ 4225360,
+ 2132181,
+ 2132632,
+ 2134090,
+ 2134161,
+ 2134261,
+ 2135748,
+ 2131853,
+ 2119957,
+ 2117256,
+ 2117465,
+ 2117134,
+ 2132617,
+ 2133823,
+ 2136080,
+ 2117805,
+ 2121340,
+ 2120086,
+ 2120633,
+ 2121400,
+ 2122714,
+ 2122746,
+ 2122945,
+ 2123484,
+ 2124106,
+ 2124248,
+ 2125067,
+ 2125494,
+ 2126228,
+ 2127144,
+ 2128559,
+ 4226954,
+ 2129920,
+ 2131017,
+ 2131145,
+ 2132353,
+ 2132769,
+ 2133514,
+ 2134117,
+ 2135677,
+ 2136330,
+ 2122110,
+ 2122385,
+ 2124594,
+ 2124931,
+ 2125172,
+ 2129868,
+ 2129916,
+ 2125248,
+ 2129797,
+ 2131898,
+ 2132216,
+ 2123621,
+ 2130865,
+ 2136124,
+ 2135799,
+ 2125083,
+ 2129249,
+ 2131005,
+ 2134378,
+ 2117233,
+ 2118517,
+ 2121040,
+ 4221700,
+ 2125803,
+ 2131405,
+ 2131501,
+ 2132391,
+ 2118185,
+ 2118671,
+ 2120805,
+ 2123598,
+ 2123944,
+ 2126854,
+ 2126979,
+ 2127330,
+ 2132175,
+ 2132193,
+ 2134476,
+ 2135778,
+ 2135672,
+ 2121611,
+ 2126727,
+ 2128587,
+ 2131022,
+ 2122656,
+ 2127205,
+ 2118281,
+ 2125121,
+ 2125468,
+ 2126857,
+ 2127193,
+ 2127979,
+ 2129042,
+ 2135686,
+ 2128604,
+ 2137997,
+ 2117558,
+ 2122094,
+ 2123205,
+ 4228700,
+ 2117254,
+ 2117294,
+ 2117850,
+ 2117153,
+ 2118092,
+ 2120686,
+ 2123161,
+ 2123905,
+ 2125244,
+ 2126623,
+ 2127426,
+ 2127789,
+ 2128412,
+ 2129127,
+ 2130543,
+ 2132690,
+ 2134140,
+ 2134479,
+ 2135669,
+ 2136088,
+ 2118299,
+ 2129361,
+ 2117675,
+ 2118552,
+ 2123671,
+ 2125259,
+ 2126288,
+ 2126899,
+ 2130408,
+ 2133802,
+ 2135715,
+ 2137175,
+ 2137759,
+ 2126944,
+ 2119745,
+ 2125209,
+ 2129199,
+ 4233310,
+ 2117348,
+ 2117430,
+ 2117515,
+ 2118071,
+ 2118321,
+ 2121146,
+ 2121756,
+ 2126770,
+ 2128188,
+ 2130643,
+ 2134580,
+ 2135735,
+ 2135798,
+ 2135818,
+ 2137751,
+ 2137954,
+ 2123430,
+ 2124660,
+ 2118167,
+ 2118307,
+ 2126024,
+ 2132162,
+ 4218569,
+ 2121803,
+ 2122128,
+ 4222755,
+ 4223305,
+ 2128958,
+ 4226548,
+ 2130031,
+ 4228334,
+ 4231203,
+ 2134828,
+ 2118722,
+ 2136943,
+ 2124499,
+ 2125961,
+ 2133186,
+ 2133487,
+ 2135858,
+ 2118324,
+ 2120257,
+ 2121418,
+ 2121476,
+ 4220695,
+ 2124156,
+ 2124180,
+ 2125162,
+ 2125583,
+ 2126434,
+ 2126588,
+ 2128877,
+ 2129921,
+ 2130046,
+ 2131787,
+ 2134222,
+ 2117997,
+ 2137747,
+ 2128260,
+ 2130059,
+ 2134834,
+ 2132694,
+ 2117677,
+ 2118796,
+ 2132593,
+ 2124650,
+ 2133188,
+ 2130183,
+ 2121937,
+ 2123680,
+ 2137586,
+ 2117273,
+ 2117272,
+ 2137104,
+ 2132587,
+ 2131393,
+ 2131304,
+ 2124032,
+ 2125438,
+ 2128023,
+ 2130261,
+ 2121484,
+ 2117136,
+ 2117141,
+ 2117162,
+ 2117169,
+ 2117174,
+ 2117180,
+ 2117183,
+ 2117186,
+ 2117206,
+ 2117208,
+ 2117250,
+ 2117253,
+ 2133099,
+ 2117258,
+ 2130450,
+ 2121485,
+ 2117262,
+ 2117278,
+ 2117279,
+ 2117280,
+ 2117282,
+ 2117296,
+ 2117299,
+ 2117302,
+ 2117326,
+ 2117325,
+ 2117316,
+ 2117318,
+ 2117314,
+ 2117335,
+ 2117342,
+ 2117357,
+ 2117343,
+ 2117367,
+ 2117385,
+ 2117466,
+ 2117424,
+ 2117467,
+ 2117469,
+ 2117463,
+ 2117447,
+ 2117494,
+ 2117512,
+ 2117519,
+ 2117528,
+ 2117499,
+ 2117481,
+ 2117488,
+ 2117521,
+ 2117487,
+ 2117510,
+ 2117526,
+ 2117912,
+ 2117588,
+ 2117599,
+ 2117582,
+ 2117592,
+ 2117595,
+ 2117585,
+ 2117594,
+ 2117584,
+ 2117604,
+ 2117605,
+ 2117658,
+ 2117672,
+ 2117652,
+ 2117674,
+ 2117669,
+ 2117637,
+ 2117404,
+ 2117622,
+ 2117665,
+ 2117673,
+ 2117676,
+ 2117630,
+ 2117615,
+ 2117649,
+ 2117638,
+ 2117699,
+ 2117703,
+ 2123523,
+ 2117717,
+ 2117712,
+ 2117704,
+ 2117722,
+ 2117718,
+ 2117740,
+ 2117752,
+ 2117760,
+ 2117786,
+ 2117765,
+ 2117812,
+ 2117810,
+ 2117833,
+ 2117834,
+ 2117811,
+ 2117826,
+ 2117846,
+ 2117854,
+ 2117861,
+ 2117869,
+ 2117859,
+ 2117870,
+ 2117881,
+ 2117877,
+ 2117897,
+ 2117889,
+ 2117890,
+ 2117910,
+ 2117909,
+ 2117908,
+ 2117914,
+ 2117921,
+ 2117946,
+ 2117943,
+ 2117948,
+ 2117947,
+ 2117951,
+ 2117952,
+ 2117970,
+ 2117964,
+ 4215124,
+ 2117986,
+ 2128632,
+ 2117993,
+ 2117994,
+ 2117998,
+ 2118016,
+ 2118018,
+ 2119384,
+ 2118028,
+ 2118025,
+ 2118031,
+ 2118033,
+ 2118035,
+ 4215189,
+ 2118038,
+ 2118052,
+ 2118054,
+ 2118050,
+ 2118057,
+ 2118058,
+ 2118059,
+ 2118067,
+ 2118065,
+ 2118066,
+ 2118064,
+ 2118069,
+ 2118077,
+ 2118085,
+ 2118089,
+ 2118107,
+ 2118112,
+ 2131541,
+ 2118121,
+ 2118125,
+ 2118128,
+ 2118133,
+ 2118142,
+ 2118148,
+ 2118155,
+ 2118164,
+ 2118158,
+ 2118183,
+ 2118186,
+ 2118190,
+ 2118195,
+ 2118201,
+ 2118223,
+ 2118212,
+ 2118219,
+ 2118220,
+ 2118238,
+ 2118228,
+ 2118250,
+ 2118260,
+ 2118249,
+ 2118259,
+ 2118271,
+ 2118269,
+ 2118285,
+ 2118292,
+ 2118290,
+ 2118257,
+ 2118280,
+ 2118289,
+ 2133928,
+ 2133927,
+ 2118316,
+ 2118317,
+ 2118332,
+ 2118325,
+ 2118337,
+ 2118349,
+ 2118359,
+ 2118366,
+ 2118371,
+ 2118374,
+ 2136301,
+ 2118368,
+ 2118387,
+ 2118389,
+ 2118392,
+ 2118393,
+ 2118406,
+ 2118408,
+ 2127160,
+ 2118413,
+ 2118416,
+ 2118415,
+ 2118421,
+ 2118426,
+ 2118435,
+ 2118447,
+ 2118449,
+ 2118451,
+ 2118456,
+ 2118464,
+ 2118470,
+ 2118469,
+ 2117143,
+ 2118473,
+ 2118477,
+ 2118102,
+ 2118494,
+ 2118505,
+ 2118510,
+ 2119960,
+ 2118523,
+ 2118519,
+ 2118530,
+ 2118550,
+ 2118560,
+ 2118566,
+ 2118565,
+ 2118574,
+ 2118576,
+ 2118582,
+ 2118595,
+ 2128914,
+ 2135769,
+ 2118623,
+ 2123516,
+ 2126318,
+ 2118638,
+ 2118632,
+ 2118637,
+ 2118650,
+ 2118657,
+ 2118717,
+ 2118720,
+ 2118700,
+ 2118701,
+ 2118716,
+ 2118702,
+ 2118710,
+ 2118697,
+ 2118685,
+ 2118734,
+ 2118799,
+ 2118773,
+ 2118798,
+ 2118751,
+ 2118769,
+ 2118775,
+ 2118768,
+ 2118802,
+ 2118779,
+ 2118784,
+ 2118774,
+ 2118788,
+ 2118800,
+ 2118790,
+ 2118855,
+ 2118818,
+ 2118840,
+ 2118821,
+ 2118828,
+ 2118852,
+ 2118856,
+ 2118824,
+ 2118827,
+ 2118850,
+ 2118820,
+ 2118846,
+ 2118844,
+ 2118872,
+ 2118885,
+ 2118886,
+ 2118927,
+ 2118932,
+ 2118909,
+ 2118894,
+ 2118893,
+ 2118906,
+ 2118882,
+ 2118969,
+ 2118976,
+ 2119011,
+ 2118988,
+ 2118958,
+ 2119004,
+ 2118981,
+ 2118998,
+ 2118999,
+ 2118968,
+ 2118963,
+ 2119005,
+ 2119065,
+ 2119040,
+ 2118831,
+ 2119050,
+ 2119071,
+ 2119035,
+ 2119038,
+ 2119064,
+ 2119070,
+ 2119086,
+ 2119036,
+ 2119043,
+ 2119081,
+ 2119047,
+ 2119080,
+ 2119130,
+ 2119109,
+ 2119135,
+ 2119108,
+ 2119132,
+ 2119140,
+ 2119124,
+ 2119188,
+ 2119159,
+ 2119190,
+ 2119166,
+ 2119165,
+ 2119195,
+ 2119161,
+ 2119246,
+ 2119248,
+ 2126303,
+ 2119220,
+ 2119222,
+ 2119218,
+ 2119224,
+ 2119275,
+ 2119268,
+ 2119215,
+ 2119276,
+ 2119274,
+ 2119302,
+ 2119296,
+ 2119306,
+ 2119328,
+ 2119316,
+ 2119311,
+ 2119333,
+ 2119342,
+ 2119350,
+ 2119348,
+ 2119362,
+ 2119356,
+ 2119361,
+ 2119363,
+ 2119360,
+ 2119368,
+ 2119374,
+ 2119377,
+ 2119379,
+ 2119383,
+ 2119406,
+ 2119417,
+ 2119424,
+ 2119423,
+ 2119428,
+ 2119433,
+ 2119432,
+ 2119435,
+ 2119437,
+ 2119443,
+ 2119448,
+ 2119446,
+ 2119111,
+ 2119452,
+ 2119462,
+ 2119479,
+ 2119480,
+ 2119502,
+ 2119483,
+ 2119488,
+ 2119503,
+ 2119529,
+ 2119616,
+ 2119560,
+ 2119521,
+ 2119551,
+ 2119561,
+ 2119571,
+ 2119584,
+ 2119603,
+ 2119588,
+ 2119594,
+ 2119600,
+ 2119619,
+ 2119622,
+ 2119636,
+ 2119634,
+ 2119635,
+ 2119690,
+ 2119638,
+ 2119651,
+ 2119691,
+ 2119705,
+ 2119709,
+ 2119794,
+ 2119713,
+ 2119778,
+ 2119755,
+ 2119792,
+ 2124736,
+ 2119762,
+ 2119741,
+ 2119801,
+ 2119813,
+ 2119865,
+ 2119839,
+ 2119851,
+ 2119866,
+ 2119902,
+ 2119867,
+ 2119864,
+ 2119854,
+ 2119877,
+ 2119891,
+ 2119889,
+ 2119895,
+ 2119897,
+ 2119896,
+ 2119909,
+ 2119900,
+ 2119908,
+ 2119903,
+ 2119919,
+ 2119930,
+ 2119929,
+ 2119931,
+ 2119932,
+ 2119933,
+ 2119938,
+ 2119946,
+ 2119952,
+ 2119963,
+ 2123942,
+ 2119973,
+ 2119980,
+ 2119981,
+ 2119986,
+ 2119992,
+ 2119998,
+ 2128594,
+ 2120021,
+ 2120016,
+ 2120014,
+ 2120026,
+ 2120024,
+ 2120034,
+ 2120032,
+ 2120039,
+ 2120044,
+ 2120041,
+ 2120056,
+ 2120065,
+ 2120093,
+ 2117470,
+ 2117547,
+ 2120099,
+ 2120114,
+ 2120134,
+ 2120168,
+ 2120156,
+ 2120077,
+ 2120153,
+ 2120154,
+ 2120229,
+ 2120223,
+ 2120209,
+ 2120220,
+ 2120201,
+ 2120218,
+ 2120256,
+ 2120300,
+ 2120265,
+ 2120245,
+ 2120246,
+ 2120290,
+ 2120298,
+ 2120346,
+ 2120380,
+ 2120382,
+ 2120395,
+ 2120386,
+ 2120381,
+ 2120419,
+ 2120407,
+ 2120422,
+ 2120425,
+ 2120406,
+ 2120442,
+ 2120443,
+ 2120460,
+ 2120459,
+ 2120470,
+ 2120498,
+ 2120400,
+ 2120490,
+ 2120502,
+ 2120510,
+ 2120515,
+ 2120517,
+ 2120512,
+ 2120529,
+ 2120533,
+ 2120538,
+ 2120539,
+ 2120549,
+ 2120553,
+ 2120560,
+ 2120563,
+ 2120565,
+ 2120568,
+ 2123144,
+ 2120570,
+ 2120576,
+ 2120579,
+ 2120614,
+ 2120632,
+ 2120643,
+ 2120647,
+ 2120649,
+ 2120660,
+ 2120656,
+ 2120676,
+ 2120678,
+ 2120674,
+ 2120670,
+ 2120677,
+ 2120683,
+ 2120688,
+ 2120694,
+ 2120691,
+ 2120709,
+ 2120711,
+ 2120712,
+ 2120717,
+ 2120723,
+ 2120736,
+ 2120738,
+ 2120744,
+ 2120760,
+ 2120761,
+ 2120769,
+ 2120774,
+ 2120782,
+ 2120787,
+ 2120784,
+ 2120783,
+ 2120561,
+ 2120812,
+ 4217966,
+ 2117218,
+ 2120822,
+ 2120825,
+ 2120844,
+ 2120849,
+ 2120852,
+ 2120091,
+ 2120875,
+ 2120891,
+ 2120886,
+ 2120892,
+ 2120887,
+ 2120901,
+ 2120894,
+ 2120903,
+ 2120921,
+ 2120937,
+ 2120957,
+ 2120954,
+ 2120941,
+ 2121100,
+ 2120938,
+ 2120971,
+ 2120981,
+ 2120983,
+ 2121052,
+ 2120991,
+ 2120987,
+ 2120977,
+ 2120980,
+ 2120994,
+ 2120986,
+ 2120985,
+ 2120984,
+ 2121036,
+ 2121042,
+ 2121038,
+ 2121035,
+ 2121068,
+ 2121075,
+ 2121078,
+ 2121095,
+ 2121092,
+ 2121090,
+ 2121122,
+ 2121117,
+ 2121132,
+ 2121134,
+ 2121149,
+ 2121104,
+ 2121143,
+ 2121148,
+ 2121161,
+ 2121165,
+ 2121171,
+ 2121170,
+ 2121174,
+ 2121179,
+ 2121195,
+ 2121202,
+ 2121205,
+ 2121227,
+ 2121242,
+ 2121241,
+ 2121233,
+ 2121243,
+ 2121270,
+ 2121271,
+ 2121284,
+ 2121283,
+ 2121280,
+ 2121294,
+ 2121303,
+ 2121300,
+ 2121311,
+ 2121314,
+ 2121316,
+ 2121287,
+ 2121333,
+ 2121334,
+ 2121338,
+ 2137788,
+ 2121343,
+ 2121376,
+ 2121409,
+ 2121410,
+ 2121416,
+ 2121424,
+ 2121423,
+ 2121430,
+ 2121443,
+ 2121437,
+ 2121434,
+ 2121435,
+ 2121442,
+ 2121441,
+ 2121448,
+ 2121449,
+ 2121452,
+ 2121457,
+ 2121459,
+ 2121456,
+ 2121460,
+ 2121464,
+ 2121470,
+ 2121475,
+ 2121481,
+ 2121565,
+ 2121564,
+ 2121483,
+ 2121489,
+ 2121494,
+ 2121513,
+ 2121517,
+ 2121528,
+ 2121537,
+ 2121544,
+ 2121548,
+ 2121550,
+ 2121519,
+ 2121553,
+ 2121558,
+ 2121559,
+ 2121561,
+ 2121569,
+ 2121581,
+ 2121587,
+ 2121591,
+ 2121603,
+ 2121602,
+ 2121599,
+ 2121610,
+ 2121608,
+ 2121617,
+ 2121607,
+ 2121630,
+ 2121625,
+ 2121624,
+ 2121632,
+ 2121640,
+ 2121645,
+ 2121660,
+ 2121686,
+ 2121723,
+ 2121700,
+ 2121720,
+ 2121713,
+ 2121693,
+ 2121907,
+ 2121727,
+ 2121761,
+ 2121824,
+ 2121753,
+ 2121744,
+ 2121769,
+ 2121742,
+ 2121777,
+ 2121755,
+ 2121749,
+ 2121771,
+ 2121766,
+ 2121743,
+ 2121786,
+ 2121818,
+ 2121793,
+ 2121834,
+ 2121847,
+ 2121823,
+ 2121802,
+ 2121798,
+ 2121805,
+ 2121827,
+ 2121795,
+ 2121828,
+ 2121794,
+ 2121836,
+ 2121835,
+ 2121817,
+ 2121857,
+ 2121869,
+ 2121959,
+ 2121859,
+ 2121882,
+ 2121860,
+ 2121883,
+ 2121878,
+ 2121879,
+ 2121874,
+ 2121895,
+ 2121867,
+ 2121953,
+ 2121912,
+ 2121952,
+ 2121939,
+ 2121908,
+ 2121712,
+ 2121917,
+ 2121926,
+ 2121909,
+ 2121944,
+ 2122061,
+ 2122005,
+ 2121990,
+ 2121974,
+ 2121975,
+ 2121984,
+ 2121972,
+ 2121978,
+ 2121987,
+ 2122017,
+ 2121979,
+ 2121969,
+ 2121997,
+ 2121998,
+ 2122055,
+ 2122046,
+ 2122024,
+ 2122023,
+ 2122058,
+ 2122047,
+ 2122044,
+ 2122028,
+ 2122036,
+ 2122045,
+ 2122050,
+ 2122052,
+ 2122099,
+ 2122103,
+ 2122072,
+ 2122073,
+ 2122074,
+ 2122091,
+ 2122100,
+ 2122095,
+ 2122085,
+ 2122097,
+ 2122079,
+ 2122077,
+ 2122067,
+ 2122101,
+ 2122137,
+ 2122134,
+ 2122119,
+ 2122156,
+ 2122132,
+ 2122138,
+ 2122122,
+ 2122129,
+ 2122155,
+ 2122158,
+ 2122188,
+ 2122186,
+ 2122185,
+ 2122231,
+ 2122184,
+ 2122179,
+ 2122182,
+ 2122170,
+ 2122187,
+ 2129785,
+ 2122189,
+ 2122214,
+ 2122211,
+ 2122230,
+ 2122234,
+ 2122228,
+ 2122239,
+ 2122237,
+ 2122236,
+ 2122238,
+ 2122240,
+ 2122248,
+ 2122249,
+ 2122253,
+ 2122252,
+ 2122260,
+ 2122267,
+ 2122270,
+ 2122273,
+ 2122282,
+ 2122286,
+ 2122288,
+ 2122290,
+ 2122291,
+ 2122305,
+ 2122318,
+ 2122334,
+ 2122339,
+ 2122331,
+ 2122336,
+ 2122344,
+ 2122364,
+ 2122370,
+ 2122377,
+ 2122366,
+ 2122386,
+ 2122387,
+ 2122390,
+ 4219604,
+ 2122371,
+ 2122388,
+ 2122455,
+ 2122449,
+ 2122427,
+ 2122447,
+ 2122495,
+ 2122438,
+ 2122964,
+ 2122440,
+ 2122460,
+ 2122444,
+ 2122442,
+ 2122434,
+ 2122439,
+ 2122395,
+ 2122441,
+ 2122508,
+ 2122478,
+ 2122481,
+ 2122535,
+ 2122498,
+ 2122504,
+ 2122479,
+ 2122485,
+ 2122576,
+ 2122558,
+ 2122573,
+ 2122780,
+ 2122575,
+ 2122646,
+ 2122638,
+ 2122624,
+ 2122667,
+ 2122614,
+ 2122659,
+ 2122639,
+ 2122633,
+ 2122655,
+ 2122677,
+ 2122603,
+ 2122601,
+ 2122686,
+ 2122729,
+ 2122688,
+ 2122694,
+ 2122723,
+ 2122697,
+ 2122706,
+ 2122742,
+ 2122692,
+ 2122774,
+ 2122804,
+ 2122758,
+ 2122771,
+ 2122790,
+ 2122806,
+ 2123037,
+ 2122775,
+ 2122792,
+ 2122767,
+ 2122855,
+ 2122863,
+ 2122870,
+ 2122830,
+ 2123050,
+ 2122901,
+ 2122899,
+ 2122917,
+ 2122921,
+ 2122888,
+ 2122940,
+ 2122970,
+ 2122962,
+ 2122949,
+ 2122951,
+ 2122939,
+ 2122968,
+ 2122946,
+ 2122993,
+ 2122983,
+ 2130441,
+ 2122976,
+ 2122977,
+ 2122412,
+ 2122979,
+ 2122991,
+ 2123052,
+ 2122998,
+ 2122996,
+ 2122994,
+ 2123002,
+ 2123008,
+ 2123005,
+ 2123032,
+ 2123036,
+ 2123013,
+ 2123044,
+ 2123043,
+ 2123051,
+ 2123060,
+ 2123061,
+ 2123063,
+ 2123062,
+ 2123064,
+ 2127179,
+ 2123080,
+ 2123094,
+ 2123093,
+ 2123085,
+ 2123096,
+ 2123102,
+ 2123101,
+ 2123122,
+ 2123128,
+ 2123138,
+ 2123139,
+ 2132874,
+ 2123163,
+ 2123167,
+ 2123179,
+ 2123191,
+ 2123203,
+ 2123206,
+ 2123201,
+ 2123204,
+ 2123212,
+ 2123218,
+ 2123227,
+ 2123225,
+ 2123232,
+ 2123233,
+ 2123249,
+ 2123634,
+ 2123274,
+ 2123267,
+ 2123259,
+ 2123635,
+ 2123317,
+ 2123318,
+ 2123316,
+ 2123292,
+ 2123343,
+ 2123332,
+ 2123337,
+ 2123329,
+ 2123358,
+ 2123357,
+ 2123364,
+ 2123367,
+ 2123368,
+ 2123359,
+ 2123362,
+ 2123376,
+ 2123395,
+ 2123400,
+ 2123406,
+ 2123401,
+ 2123396,
+ 2123416,
+ 2123421,
+ 2123457,
+ 2123449,
+ 2123465,
+ 2123454,
+ 2123452,
+ 2123460,
+ 2123448,
+ 2123478,
+ 2123482,
+ 2123488,
+ 2123327,
+ 2123494,
+ 2123497,
+ 2123504,
+ 2123509,
+ 2123511,
+ 2123535,
+ 2123542,
+ 2123550,
+ 2123558,
+ 2123559,
+ 2135864,
+ 2123566,
+ 2123583,
+ 2123574,
+ 2123585,
+ 2123576,
+ 2123575,
+ 2123590,
+ 2123614,
+ 2123616,
+ 2123609,
+ 2123619,
+ 2123620,
+ 2123657,
+ 2123632,
+ 2123689,
+ 2123644,
+ 2123626,
+ 2123660,
+ 2123659,
+ 2123686,
+ 2123681,
+ 2123653,
+ 2123703,
+ 2123759,
+ 2123700,
+ 2123756,
+ 2123699,
+ 2123753,
+ 2123704,
+ 2123748,
+ 2123742,
+ 2123741,
+ 2123746,
+ 2123758,
+ 2123705,
+ 2123726,
+ 2123718,
+ 2123751,
+ 2124444,
+ 2123806,
+ 2123846,
+ 2123817,
+ 2123840,
+ 2123853,
+ 2123826,
+ 2123854,
+ 2123955,
+ 2123819,
+ 2123865,
+ 2123875,
+ 2123895,
+ 2123903,
+ 2123935,
+ 2123919,
+ 2123949,
+ 2123924,
+ 2123933,
+ 2123931,
+ 2123907,
+ 2124462,
+ 2123961,
+ 2123892,
+ 2123957,
+ 2123936,
+ 2123962,
+ 2124047,
+ 2123917,
+ 2123902,
+ 2124033,
+ 2123978,
+ 2124040,
+ 2123992,
+ 2124066,
+ 2124070,
+ 2124001,
+ 2124044,
+ 2123981,
+ 2123988,
+ 2124007,
+ 2123989,
+ 2124086,
+ 2124050,
+ 2124036,
+ 2123991,
+ 2124003,
+ 2124069,
+ 2124025,
+ 2124000,
+ 2124015,
+ 2124072,
+ 2124074,
+ 2124058,
+ 2124067,
+ 2124065,
+ 2123974,
+ 2124153,
+ 2124151,
+ 2124124,
+ 2124152,
+ 2124139,
+ 2124116,
+ 2124158,
+ 2124142,
+ 2124089,
+ 2124148,
+ 2124093,
+ 2124121,
+ 2124080,
+ 2124129,
+ 2124126,
+ 2124125,
+ 2124161,
+ 2124138,
+ 2124210,
+ 2124206,
+ 2124240,
+ 2124223,
+ 2124225,
+ 2124243,
+ 2124222,
+ 2124238,
+ 2120680,
+ 2124234,
+ 2124253,
+ 2124219,
+ 2124227,
+ 2124199,
+ 2124334,
+ 2124177,
+ 2124192,
+ 2124188,
+ 2124181,
+ 2124212,
+ 2124254,
+ 2124264,
+ 2124290,
+ 2124315,
+ 2124287,
+ 2124554,
+ 2124281,
+ 2124274,
+ 2124263,
+ 2124293,
+ 2124209,
+ 2124318,
+ 2124269,
+ 2124308,
+ 2124267,
+ 2124298,
+ 2124306,
+ 2124481,
+ 2124323,
+ 2124307,
+ 2124356,
+ 2124300,
+ 2124402,
+ 2124342,
+ 2124408,
+ 2124359,
+ 2124386,
+ 2124377,
+ 2124390,
+ 2124360,
+ 2124344,
+ 2124322,
+ 2124432,
+ 2124429,
+ 2124448,
+ 2124420,
+ 2124450,
+ 2124451,
+ 2124439,
+ 2131479,
+ 2124475,
+ 2124483,
+ 2124482,
+ 2124472,
+ 2124467,
+ 2124460,
+ 2124510,
+ 2124497,
+ 2124511,
+ 2124458,
+ 2124506,
+ 2124522,
+ 2124539,
+ 2124549,
+ 2131478,
+ 2124538,
+ 2124562,
+ 2124566,
+ 2136881,
+ 2124575,
+ 2124600,
+ 2124599,
+ 2127580,
+ 2124601,
+ 2136302,
+ 2124615,
+ 2124611,
+ 2124617,
+ 2124624,
+ 2124633,
+ 2124628,
+ 2124635,
+ 2124639,
+ 2124641,
+ 2124664,
+ 2124665,
+ 2124671,
+ 2124672,
+ 2124676,
+ 2124675,
+ 2124685,
+ 2124696,
+ 2124693,
+ 2124702,
+ 2124708,
+ 2124714,
+ 2124715,
+ 2124719,
+ 2124722,
+ 2124721,
+ 2124723,
+ 2124727,
+ 2124732,
+ 2124742,
+ 2124747,
+ 2124755,
+ 2124767,
+ 2124780,
+ 2124779,
+ 2124787,
+ 2124783,
+ 2137790,
+ 2124808,
+ 2124819,
+ 2124820,
+ 2124827,
+ 2124836,
+ 2124835,
+ 2124894,
+ 2124885,
+ 2124898,
+ 2124906,
+ 2124930,
+ 2124941,
+ 2124954,
+ 2124929,
+ 2124955,
+ 2124926,
+ 2124904,
+ 2124915,
+ 2124946,
+ 2124944,
+ 2124996,
+ 2125041,
+ 2125011,
+ 2124989,
+ 2125015,
+ 2124997,
+ 2125021,
+ 2124974,
+ 2124977,
+ 2124990,
+ 2124986,
+ 2125019,
+ 2125039,
+ 2125017,
+ 2125034,
+ 2125087,
+ 2132045,
+ 2125110,
+ 2125099,
+ 2125117,
+ 2125112,
+ 2125081,
+ 2125109,
+ 2125107,
+ 2125074,
+ 2125068,
+ 2125155,
+ 2125203,
+ 2125156,
+ 2125146,
+ 2125177,
+ 2125145,
+ 2125198,
+ 2125205,
+ 2125796,
+ 2125189,
+ 2125305,
+ 2125333,
+ 2125322,
+ 2125237,
+ 2125255,
+ 2125286,
+ 2125240,
+ 2125254,
+ 2125292,
+ 2125278,
+ 2125260,
+ 2125288,
+ 2125266,
+ 2125253,
+ 2125306,
+ 2125273,
+ 2125284,
+ 2125269,
+ 2125290,
+ 2125294,
+ 2125357,
+ 2125422,
+ 2125358,
+ 2125337,
+ 2125426,
+ 2125407,
+ 2125374,
+ 2125347,
+ 2125419,
+ 2125355,
+ 2125430,
+ 2125389,
+ 2125343,
+ 2125379,
+ 2125370,
+ 2125390,
+ 2125348,
+ 2125567,
+ 2125341,
+ 2125368,
+ 2125442,
+ 2125482,
+ 2125464,
+ 2125513,
+ 2125495,
+ 2125523,
+ 2125501,
+ 2125487,
+ 2125508,
+ 2125490,
+ 2125524,
+ 2125525,
+ 2125455,
+ 2125477,
+ 2125506,
+ 2125471,
+ 2125633,
+ 2125585,
+ 2125900,
+ 2125548,
+ 2125560,
+ 2125566,
+ 2125631,
+ 2125554,
+ 2125617,
+ 2125551,
+ 2125618,
+ 2125516,
+ 2125630,
+ 2125587,
+ 2125559,
+ 2125702,
+ 2125690,
+ 2125688,
+ 2125697,
+ 2125696,
+ 2125679,
+ 2125659,
+ 2125811,
+ 2125677,
+ 2125698,
+ 2125692,
+ 2125656,
+ 2125710,
+ 2125713,
+ 2125762,
+ 2125670,
+ 2125747,
+ 2125731,
+ 2125729,
+ 2125732,
+ 2125753,
+ 2125766,
+ 2125738,
+ 2125791,
+ 2125781,
+ 2125804,
+ 2125780,
+ 2125784,
+ 2125809,
+ 2125806,
+ 2125787,
+ 2125833,
+ 2125835,
+ 2125818,
+ 2125841,
+ 2125825,
+ 2125839,
+ 2125822,
+ 2125851,
+ 2125850,
+ 2125684,
+ 2125853,
+ 2125848,
+ 2125855,
+ 2125872,
+ 2125886,
+ 2125874,
+ 2125905,
+ 2125923,
+ 2125977,
+ 2125970,
+ 2125999,
+ 2126065,
+ 2125996,
+ 2126008,
+ 2126003,
+ 2125998,
+ 2126047,
+ 2126027,
+ 2126045,
+ 2126041,
+ 2126089,
+ 2126077,
+ 2126108,
+ 2126105,
+ 2126181,
+ 2126165,
+ 2126216,
+ 2126182,
+ 2126178,
+ 2126156,
+ 2126166,
+ 2126188,
+ 2126223,
+ 2126331,
+ 2126212,
+ 2126229,
+ 2126248,
+ 2126252,
+ 2126295,
+ 2126265,
+ 2126270,
+ 2126290,
+ 2126281,
+ 2126292,
+ 2126286,
+ 2126304,
+ 2126316,
+ 2126311,
+ 2126325,
+ 2126332,
+ 2126329,
+ 2126335,
+ 2126349,
+ 2126352,
+ 2126363,
+ 4223528,
+ 2126381,
+ 2126380,
+ 2126384,
+ 2126386,
+ 2126395,
+ 2126396,
+ 2126399,
+ 2126400,
+ 2126406,
+ 2126411,
+ 2126424,
+ 2126452,
+ 2126462,
+ 2126466,
+ 2126465,
+ 2126471,
+ 2126482,
+ 2126486,
+ 2126498,
+ 2126503,
+ 2126521,
+ 2126514,
+ 2126531,
+ 2126534,
+ 2126532,
+ 2126542,
+ 2126546,
+ 2126562,
+ 2126560,
+ 2126561,
+ 2126585,
+ 2126583,
+ 2117647,
+ 2126615,
+ 2126602,
+ 2126620,
+ 2126614,
+ 2126621,
+ 2126644,
+ 2126639,
+ 2126633,
+ 2126629,
+ 2126654,
+ 2126670,
+ 2126671,
+ 2137816,
+ 2126679,
+ 2126698,
+ 2126696,
+ 2126704,
+ 2126712,
+ 2126709,
+ 2126715,
+ 2126714,
+ 2126792,
+ 2126771,
+ 2126798,
+ 2126779,
+ 2126784,
+ 2126821,
+ 2126830,
+ 2126814,
+ 2127010,
+ 2126853,
+ 2126959,
+ 2126885,
+ 2126840,
+ 2126898,
+ 2126906,
+ 2126933,
+ 2126911,
+ 2126943,
+ 2126937,
+ 2126913,
+ 2126940,
+ 2126953,
+ 2126960,
+ 2126947,
+ 2126954,
+ 2126966,
+ 2126974,
+ 2126987,
+ 2127006,
+ 2127015,
+ 2127050,
+ 2127055,
+ 2127060,
+ 2126833,
+ 2127072,
+ 2127075,
+ 2127079,
+ 2127081,
+ 2127086,
+ 2127090,
+ 2127088,
+ 2127089,
+ 2127096,
+ 2127095,
+ 2127108,
+ 2127107,
+ 2127109,
+ 2127116,
+ 2127118,
+ 2127117,
+ 2127125,
+ 2127123,
+ 2127134,
+ 2127142,
+ 2127148,
+ 2127164,
+ 2127172,
+ 2127181,
+ 2127178,
+ 2127177,
+ 2127195,
+ 2127174,
+ 2127194,
+ 2127209,
+ 2127204,
+ 2127207,
+ 2127211,
+ 2127213,
+ 2127224,
+ 2127222,
+ 2127238,
+ 2127239,
+ 2127220,
+ 2127242,
+ 2127241,
+ 2127234,
+ 2127252,
+ 2127258,
+ 2127261,
+ 2127269,
+ 2127267,
+ 2127298,
+ 2127283,
+ 2127299,
+ 2127285,
+ 2127293,
+ 2127288,
+ 2127292,
+ 2127281,
+ 2127309,
+ 2127306,
+ 2127314,
+ 2127321,
+ 2127331,
+ 2127326,
+ 2127358,
+ 2127359,
+ 2127356,
+ 2127361,
+ 2127344,
+ 2127354,
+ 2127346,
+ 2127347,
+ 2127371,
+ 2127373,
+ 2127369,
+ 2127391,
+ 2127399,
+ 2127392,
+ 2127393,
+ 2127394,
+ 2127396,
+ 2127412,
+ 2127408,
+ 2127419,
+ 2127431,
+ 2127432,
+ 2127430,
+ 2127452,
+ 2127448,
+ 2127457,
+ 2127458,
+ 2127464,
+ 2127465,
+ 2127466,
+ 2127463,
+ 2127468,
+ 2127472,
+ 2127474,
+ 2127478,
+ 2127480,
+ 2127484,
+ 2127488,
+ 2127491,
+ 2127496,
+ 2127499,
+ 2127502,
+ 2127510,
+ 2127507,
+ 2127513,
+ 2127514,
+ 2127536,
+ 2127540,
+ 2127544,
+ 2127545,
+ 2127546,
+ 2127554,
+ 2127565,
+ 2127574,
+ 2127570,
+ 2127582,
+ 2127585,
+ 2127589,
+ 2127591,
+ 2127594,
+ 2131503,
+ 2127611,
+ 2127624,
+ 2127623,
+ 2127620,
+ 2127657,
+ 2127652,
+ 4224798,
+ 2127653,
+ 2127654,
+ 2127643,
+ 2127671,
+ 2127672,
+ 2127687,
+ 2127706,
+ 2127720,
+ 2127723,
+ 2127707,
+ 2127717,
+ 2127743,
+ 2127742,
+ 2127737,
+ 2127758,
+ 2127755,
+ 2127761,
+ 2127776,
+ 2127774,
+ 2127792,
+ 2127798,
+ 2127801,
+ 2127807,
+ 2127804,
+ 2127805,
+ 2127803,
+ 2127815,
+ 2127821,
+ 2127831,
+ 2127834,
+ 2127836,
+ 2127843,
+ 2127854,
+ 2127868,
+ 2127884,
+ 2127890,
+ 2128166,
+ 2127904,
+ 2128170,
+ 2127941,
+ 2128014,
+ 2127988,
+ 2128006,
+ 2127996,
+ 2128026,
+ 2128012,
+ 2128035,
+ 2128053,
+ 2128042,
+ 2128047,
+ 2128081,
+ 2128070,
+ 2128075,
+ 2128084,
+ 2128062,
+ 2128060,
+ 2128069,
+ 2128074,
+ 2128108,
+ 2128103,
+ 2128090,
+ 2128125,
+ 2128116,
+ 2128135,
+ 2128146,
+ 2128145,
+ 2128153,
+ 2128172,
+ 2128171,
+ 2128192,
+ 2128224,
+ 2128215,
+ 2128223,
+ 2128218,
+ 2128213,
+ 2128211,
+ 2128250,
+ 2128255,
+ 2128266,
+ 2128285,
+ 2128295,
+ 2137931,
+ 2128298,
+ 2128302,
+ 2128307,
+ 2128313,
+ 2128314,
+ 2128329,
+ 2128341,
+ 2128359,
+ 2128364,
+ 2128353,
+ 2128355,
+ 2128392,
+ 2128397,
+ 2128408,
+ 2128409,
+ 2128416,
+ 2128415,
+ 2128256,
+ 2128433,
+ 2128443,
+ 2128446,
+ 2128439,
+ 2128451,
+ 2128471,
+ 2128457,
+ 2128481,
+ 2128482,
+ 2128489,
+ 2138013,
+ 2128496,
+ 2128505,
+ 2128509,
+ 2128520,
+ 2128535,
+ 2128533,
+ 2128536,
+ 2128534,
+ 2128553,
+ 2128584,
+ 2128560,
+ 2128566,
+ 2128581,
+ 2128580,
+ 2128575,
+ 2134147,
+ 2128583,
+ 2128586,
+ 2128589,
+ 2128591,
+ 2128597,
+ 2128595,
+ 2128601,
+ 2128602,
+ 2128605,
+ 2128609,
+ 2128610,
+ 2128614,
+ 2128621,
+ 2128624,
+ 2128642,
+ 2128655,
+ 2128650,
+ 2128646,
+ 2128691,
+ 2128664,
+ 2128665,
+ 2128670,
+ 2128693,
+ 2128680,
+ 2128694,
+ 2128720,
+ 2128762,
+ 2128644,
+ 2128717,
+ 2128651,
+ 2128716,
+ 2128709,
+ 2128757,
+ 2128741,
+ 2128756,
+ 2128743,
+ 2128752,
+ 2128753,
+ 2128748,
+ 2128750,
+ 2128797,
+ 2128792,
+ 2128799,
+ 2128781,
+ 2128796,
+ 2128794,
+ 2128779,
+ 2128786,
+ 2128783,
+ 2128733,
+ 2128793,
+ 2128843,
+ 2128833,
+ 2128844,
+ 2128847,
+ 2128820,
+ 2128838,
+ 2128861,
+ 2128873,
+ 2128913,
+ 2128916,
+ 2128870,
+ 2128869,
+ 2128992,
+ 2128896,
+ 2128903,
+ 2128915,
+ 2128883,
+ 2128887,
+ 2128919,
+ 2128909,
+ 2128886,
+ 2128931,
+ 2128935,
+ 2128938,
+ 2128927,
+ 2128951,
+ 2128939,
+ 2128957,
+ 2128972,
+ 2128963,
+ 2128980,
+ 2128975,
+ 2128960,
+ 2128976,
+ 2128984,
+ 2128991,
+ 2128996,
+ 2128982,
+ 2128997,
+ 2129004,
+ 2129013,
+ 2129027,
+ 2129040,
+ 2129060,
+ 2129069,
+ 2129058,
+ 2129067,
+ 2129057,
+ 2129064,
+ 2129075,
+ 2129074,
+ 2129073,
+ 2129070,
+ 2129081,
+ 2129085,
+ 2129088,
+ 2129093,
+ 2129090,
+ 2129112,
+ 2129106,
+ 2129116,
+ 2129122,
+ 2136891,
+ 2129135,
+ 2129138,
+ 2129140,
+ 2129142,
+ 2129146,
+ 2129158,
+ 2129154,
+ 2129180,
+ 2129173,
+ 2129162,
+ 2129221,
+ 2129227,
+ 2129198,
+ 2129202,
+ 2129215,
+ 2129205,
+ 2129222,
+ 2129267,
+ 2129238,
+ 2129230,
+ 2129266,
+ 2129256,
+ 2129262,
+ 2129231,
+ 2129251,
+ 2129299,
+ 2129289,
+ 2129243,
+ 2129295,
+ 2129277,
+ 2129307,
+ 2129338,
+ 2129326,
+ 2129315,
+ 2129333,
+ 2129351,
+ 2129341,
+ 2129323,
+ 2129469,
+ 2129314,
+ 2129327,
+ 2129372,
+ 2129336,
+ 2129311,
+ 2129328,
+ 2129368,
+ 2129373,
+ 2129380,
+ 2129374,
+ 2129403,
+ 2129394,
+ 2129377,
+ 2129413,
+ 2129418,
+ 2129443,
+ 2129441,
+ 2129426,
+ 2129457,
+ 2129439,
+ 2129417,
+ 2129419,
+ 2129442,
+ 2129478,
+ 2129510,
+ 2129467,
+ 2129461,
+ 2129465,
+ 2129475,
+ 2129463,
+ 2129458,
+ 2129466,
+ 2129511,
+ 2129501,
+ 2129494,
+ 2129502,
+ 2129497,
+ 2129498,
+ 2129529,
+ 2129514,
+ 2129513,
+ 2129532,
+ 2129531,
+ 2129539,
+ 2129365,
+ 2129533,
+ 2133934,
+ 2129535,
+ 2129544,
+ 2129545,
+ 2129548,
+ 2129554,
+ 2129552,
+ 2129555,
+ 2129556,
+ 2129558,
+ 2129550,
+ 2129563,
+ 2129564,
+ 2129720,
+ 2129722,
+ 2129733,
+ 2129740,
+ 2129741,
+ 2129742,
+ 2129744,
+ 2129745,
+ 2129749,
+ 2129748,
+ 2129752,
+ 2129759,
+ 2129760,
+ 2129768,
+ 2129769,
+ 2129767,
+ 2129784,
+ 2129794,
+ 2129798,
+ 2129795,
+ 2129800,
+ 2129799,
+ 2129804,
+ 2129812,
+ 2129822,
+ 2129821,
+ 2129818,
+ 2129827,
+ 2129839,
+ 2129842,
+ 2129849,
+ 2129838,
+ 2129846,
+ 2129848,
+ 2132849,
+ 2129861,
+ 2129862,
+ 2129866,
+ 2129877,
+ 2129876,
+ 2129889,
+ 2129894,
+ 2129897,
+ 2129907,
+ 2129913,
+ 2136284,
+ 2129926,
+ 2129924,
+ 2129931,
+ 2129938,
+ 2129944,
+ 2129945,
+ 2129948,
+ 2129953,
+ 2129960,
+ 2129983,
+ 2129979,
+ 2129994,
+ 2129990,
+ 2130002,
+ 2130008,
+ 2130010,
+ 2130015,
+ 2130018,
+ 2130024,
+ 2130035,
+ 2130034,
+ 2130032,
+ 2130038,
+ 2130041,
+ 2130045,
+ 2130047,
+ 2130052,
+ 2130054,
+ 2130053,
+ 2130075,
+ 2130067,
+ 2130074,
+ 2130093,
+ 2118032,
+ 2130092,
+ 2130139,
+ 2130149,
+ 2130137,
+ 2130141,
+ 2130116,
+ 2130138,
+ 2130134,
+ 2130185,
+ 2130159,
+ 2130161,
+ 2130203,
+ 2130217,
+ 2130211,
+ 2130223,
+ 2130251,
+ 2135691,
+ 2130246,
+ 2130238,
+ 2130259,
+ 2130257,
+ 2130172,
+ 2130289,
+ 2130286,
+ 2130277,
+ 2130278,
+ 2130292,
+ 2130307,
+ 2130312,
+ 2130314,
+ 2130304,
+ 2130306,
+ 2130336,
+ 2130325,
+ 2130340,
+ 2130339,
+ 2130271,
+ 2130323,
+ 2130345,
+ 2130352,
+ 2130357,
+ 2130366,
+ 2130360,
+ 2130365,
+ 2130368,
+ 2130370,
+ 2130362,
+ 2130377,
+ 2130381,
+ 2130385,
+ 2130393,
+ 2130392,
+ 2130376,
+ 2130394,
+ 2130399,
+ 2130400,
+ 2130407,
+ 2130426,
+ 2130427,
+ 2130430,
+ 2130433,
+ 2130434,
+ 2130437,
+ 2130439,
+ 2130442,
+ 2130445,
+ 2130448,
+ 2130454,
+ 2130473,
+ 2130475,
+ 2130488,
+ 2130483,
+ 2130496,
+ 2130521,
+ 2130520,
+ 2130525,
+ 2130522,
+ 2130527,
+ 2130532,
+ 2130530,
+ 2130536,
+ 2130538,
+ 2130539,
+ 2130478,
+ 2130545,
+ 2130551,
+ 2130552,
+ 2130558,
+ 2130573,
+ 2130578,
+ 2130603,
+ 2130591,
+ 2130619,
+ 2130604,
+ 2130657,
+ 2130659,
+ 2130655,
+ 2130642,
+ 2130676,
+ 2130675,
+ 2130682,
+ 2130835,
+ 2130691,
+ 2130683,
+ 2130681,
+ 2130654,
+ 2130694,
+ 2130652,
+ 2130697,
+ 2130649,
+ 2130741,
+ 2130740,
+ 2130710,
+ 2130738,
+ 2130737,
+ 2130752,
+ 2130745,
+ 2130768,
+ 2130757,
+ 2130735,
+ 2130731,
+ 2130711,
+ 2130712,
+ 2130821,
+ 2130842,
+ 2130858,
+ 2130847,
+ 2130850,
+ 2130838,
+ 2130723,
+ 2130830,
+ 2130823,
+ 2130826,
+ 2130812,
+ 2130869,
+ 2130803,
+ 2130805,
+ 2130848,
+ 2130825,
+ 2130856,
+ 2130932,
+ 2130963,
+ 2130923,
+ 2130894,
+ 2130941,
+ 2130947,
+ 2130904,
+ 2130955,
+ 2130881,
+ 2130935,
+ 2130951,
+ 2130912,
+ 2130930,
+ 2130957,
+ 2130978,
+ 2130976,
+ 2130877,
+ 2131000,
+ 2131206,
+ 2130939,
+ 2131053,
+ 2130986,
+ 2131004,
+ 2131290,
+ 2131076,
+ 2131063,
+ 2131051,
+ 2131117,
+ 2131054,
+ 2131074,
+ 2131049,
+ 2131014,
+ 2130988,
+ 2131055,
+ 2131065,
+ 2130997,
+ 2131146,
+ 2131042,
+ 2131129,
+ 2131135,
+ 2131103,
+ 2131161,
+ 2131149,
+ 2131131,
+ 2131162,
+ 2131152,
+ 2131137,
+ 2131142,
+ 2131158,
+ 2131105,
+ 2131233,
+ 2131199,
+ 2131188,
+ 2131223,
+ 2131224,
+ 2131244,
+ 2131231,
+ 2131221,
+ 2131220,
+ 2131196,
+ 2131264,
+ 2131299,
+ 2131288,
+ 2131272,
+ 2131265,
+ 2131458,
+ 2131275,
+ 2131285,
+ 2131328,
+ 2131364,
+ 2131336,
+ 2131345,
+ 2131338,
+ 2131368,
+ 2131309,
+ 2131348,
+ 2131355,
+ 2131434,
+ 2131335,
+ 2131356,
+ 2131319,
+ 2131326,
+ 2131344,
+ 2131401,
+ 2131386,
+ 2131407,
+ 2131385,
+ 2131408,
+ 2131413,
+ 2131421,
+ 2131429,
+ 2131420,
+ 2131449,
+ 2131466,
+ 2131475,
+ 2131467,
+ 2131454,
+ 2131450,
+ 2131462,
+ 2131490,
+ 2131482,
+ 2131504,
+ 2131519,
+ 2131533,
+ 2117205,
+ 2131540,
+ 2131551,
+ 2131559,
+ 2131569,
+ 2131603,
+ 2131619,
+ 2131625,
+ 2131626,
+ 2131595,
+ 2131596,
+ 2131638,
+ 2131631,
+ 2131652,
+ 2131654,
+ 2131632,
+ 2131657,
+ 2132003,
+ 2131627,
+ 2131668,
+ 2131678,
+ 2131689,
+ 2131692,
+ 2131679,
+ 2131675,
+ 2131695,
+ 2131730,
+ 2131718,
+ 2131720,
+ 2131712,
+ 2131715,
+ 2131707,
+ 2131729,
+ 2131721,
+ 2131725,
+ 2131705,
+ 2131722,
+ 2131764,
+ 2131775,
+ 2131767,
+ 2131771,
+ 2131749,
+ 2131753,
+ 2131738,
+ 2131808,
+ 2131807,
+ 2131832,
+ 2131788,
+ 2131790,
+ 2131828,
+ 2131799,
+ 2131816,
+ 2131822,
+ 2131801,
+ 2131795,
+ 2131811,
+ 2131818,
+ 2131973,
+ 2131874,
+ 2131871,
+ 2131842,
+ 2131887,
+ 2131915,
+ 2131901,
+ 2131904,
+ 2131920,
+ 2135766,
+ 2131883,
+ 2131908,
+ 2131891,
+ 2131911,
+ 2131910,
+ 2131899,
+ 2131951,
+ 2131954,
+ 2131936,
+ 2131983,
+ 2131981,
+ 2131966,
+ 2131958,
+ 2131959,
+ 2131982,
+ 2131922,
+ 2131985,
+ 2131990,
+ 2131989,
+ 2132002,
+ 2132001,
+ 2132017,
+ 2132022,
+ 2132025,
+ 2132007,
+ 2132027,
+ 2132036,
+ 2132034,
+ 2132050,
+ 2132057,
+ 2132062,
+ 2132066,
+ 2132075,
+ 2132097,
+ 2132094,
+ 2132126,
+ 2132085,
+ 2132093,
+ 2132149,
+ 2132082,
+ 2132098,
+ 2132119,
+ 2132114,
+ 2132142,
+ 2132121,
+ 2132130,
+ 2132109,
+ 2132132,
+ 2132144,
+ 2132159,
+ 2132145,
+ 2132163,
+ 2132164,
+ 2132180,
+ 2132184,
+ 2132185,
+ 2132189,
+ 2132217,
+ 2132226,
+ 2132220,
+ 2132212,
+ 2132200,
+ 2132210,
+ 2132228,
+ 2132236,
+ 2132234,
+ 2132243,
+ 2132291,
+ 2132254,
+ 2132261,
+ 2132266,
+ 2132267,
+ 2132289,
+ 2132292,
+ 2132283,
+ 2132278,
+ 2132280,
+ 2132300,
+ 2132253,
+ 2132320,
+ 2132318,
+ 2132326,
+ 2132324,
+ 2132333,
+ 2132330,
+ 2132335,
+ 2132340,
+ 2132343,
+ 2132350,
+ 2132355,
+ 2132360,
+ 2132362,
+ 2132371,
+ 2132376,
+ 2132385,
+ 2132393,
+ 2132390,
+ 2132396,
+ 2132399,
+ 2132402,
+ 2132410,
+ 2132413,
+ 2132415,
+ 2132416,
+ 2132442,
+ 2132444,
+ 2132445,
+ 2132455,
+ 2132468,
+ 2132472,
+ 2132483,
+ 2132502,
+ 2132496,
+ 2132492,
+ 2132507,
+ 2132509,
+ 2132517,
+ 2132534,
+ 2132545,
+ 2132571,
+ 2132562,
+ 2132550,
+ 2132552,
+ 2132604,
+ 2132589,
+ 2132588,
+ 2132578,
+ 2132613,
+ 2132610,
+ 2132612,
+ 2132648,
+ 2132641,
+ 2132625,
+ 2132645,
+ 2132646,
+ 2132634,
+ 2132643,
+ 2132676,
+ 2132685,
+ 2132674,
+ 2132698,
+ 2132715,
+ 2132723,
+ 2132711,
+ 2132708,
+ 2132721,
+ 2132756,
+ 2132704,
+ 2132706,
+ 2132727,
+ 2132702,
+ 2132699,
+ 2132748,
+ 2132743,
+ 2132762,
+ 2132705,
+ 2132758,
+ 2132752,
+ 2132759,
+ 2132768,
+ 2132787,
+ 2135979,
+ 2132774,
+ 2132779,
+ 2132798,
+ 2132776,
+ 2132801,
+ 2132812,
+ 2132815,
+ 2132814,
+ 2132809,
+ 2132822,
+ 2132827,
+ 2132826,
+ 2132843,
+ 2132831,
+ 2132844,
+ 2132847,
+ 2132852,
+ 2132861,
+ 2132864,
+ 2132876,
+ 2132878,
+ 2132882,
+ 2132883,
+ 2132886,
+ 2132889,
+ 2132890,
+ 2133050,
+ 2133057,
+ 2133055,
+ 2133064,
+ 2133068,
+ 2133070,
+ 2133072,
+ 2133077,
+ 2133090,
+ 2133100,
+ 2133112,
+ 2133114,
+ 2133122,
+ 2133129,
+ 2133125,
+ 2133130,
+ 2133133,
+ 2133134,
+ 2133140,
+ 2133116,
+ 2133144,
+ 2122269,
+ 2133165,
+ 2133162,
+ 2133181,
+ 2133170,
+ 2133171,
+ 2133166,
+ 2133174,
+ 2133192,
+ 2133185,
+ 2133220,
+ 2133219,
+ 2133210,
+ 2133245,
+ 2133242,
+ 2133243,
+ 2133252,
+ 2133253,
+ 2133258,
+ 2133255,
+ 2133263,
+ 2133261,
+ 2133264,
+ 2137934,
+ 2133267,
+ 2133197,
+ 2133268,
+ 2133270,
+ 2133351,
+ 2133357,
+ 2133361,
+ 2133363,
+ 2133377,
+ 2133401,
+ 2133442,
+ 2133438,
+ 2133434,
+ 2133455,
+ 2133466,
+ 2133462,
+ 2133452,
+ 2133467,
+ 2133451,
+ 2133482,
+ 2133483,
+ 2133471,
+ 2133475,
+ 2133500,
+ 2133512,
+ 2133513,
+ 2133503,
+ 2133533,
+ 2133534,
+ 2133520,
+ 2133535,
+ 2133570,
+ 2133557,
+ 2133552,
+ 2133556,
+ 2133578,
+ 2133575,
+ 2133577,
+ 2133580,
+ 2133584,
+ 2133576,
+ 2133593,
+ 2133604,
+ 2133600,
+ 2133546,
+ 2133603,
+ 2133589,
+ 2133622,
+ 2133618,
+ 2133628,
+ 2133633,
+ 2133639,
+ 2133637,
+ 2133636,
+ 2133643,
+ 2133642,
+ 2133651,
+ 2133649,
+ 2133652,
+ 2133657,
+ 2133674,
+ 2133665,
+ 2133676,
+ 2133680,
+ 2133702,
+ 2133681,
+ 2133694,
+ 2133701,
+ 2133704,
+ 2133707,
+ 2133723,
+ 2133731,
+ 2133756,
+ 2133755,
+ 2133739,
+ 2133758,
+ 2133770,
+ 2133765,
+ 2133781,
+ 2133778,
+ 2133785,
+ 2133779,
+ 2133788,
+ 2133791,
+ 2133787,
+ 2133772,
+ 2133798,
+ 2133811,
+ 2133819,
+ 2133817,
+ 2133829,
+ 2133826,
+ 2133822,
+ 2133836,
+ 2133833,
+ 2133830,
+ 2133838,
+ 2133847,
+ 2133852,
+ 2133858,
+ 2133859,
+ 2133860,
+ 2133916,
+ 2133919,
+ 2133923,
+ 2133933,
+ 2133935,
+ 2133943,
+ 2133978,
+ 2133989,
+ 2133986,
+ 2133994,
+ 2133999,
+ 2134151,
+ 2134004,
+ 2134021,
+ 2134009,
+ 2134010,
+ 2134033,
+ 2134037,
+ 2134049,
+ 2134029,
+ 2134046,
+ 2134038,
+ 2134027,
+ 2134055,
+ 2134070,
+ 2134069,
+ 2134073,
+ 2134008,
+ 2134095,
+ 2134096,
+ 2134097,
+ 2134098,
+ 2134030,
+ 2134089,
+ 2134078,
+ 2134102,
+ 2134104,
+ 2134110,
+ 2134120,
+ 2134127,
+ 2134134,
+ 2135720,
+ 2134130,
+ 2134146,
+ 2134141,
+ 2134145,
+ 2134144,
+ 2134154,
+ 2134153,
+ 2134159,
+ 2134184,
+ 2134191,
+ 2134193,
+ 2134197,
+ 2134242,
+ 2134244,
+ 2122312,
+ 2134235,
+ 2134274,
+ 2134290,
+ 2134297,
+ 2134322,
+ 2134320,
+ 2134346,
+ 2134358,
+ 2134360,
+ 2134371,
+ 2134373,
+ 2134377,
+ 2134387,
+ 2134386,
+ 2134411,
+ 2134409,
+ 2134402,
+ 2134434,
+ 2134443,
+ 2134447,
+ 2134442,
+ 2134453,
+ 2134452,
+ 2134458,
+ 2134464,
+ 2134465,
+ 2134473,
+ 2134475,
+ 2134480,
+ 2134486,
+ 2134495,
+ 2134497,
+ 2134491,
+ 2134524,
+ 2134517,
+ 2134518,
+ 2134558,
+ 2134527,
+ 2134548,
+ 2134572,
+ 2134549,
+ 2134545,
+ 2134622,
+ 2134615,
+ 2134597,
+ 2134601,
+ 2134628,
+ 2134600,
+ 2134677,
+ 2134591,
+ 2134603,
+ 2134608,
+ 2134684,
+ 2134678,
+ 2134675,
+ 2134683,
+ 2134618,
+ 2134735,
+ 2134713,
+ 2134711,
+ 2134761,
+ 2134799,
+ 2134778,
+ 2134852,
+ 2134830,
+ 2134809,
+ 2134818,
+ 2134810,
+ 2134819,
+ 2134842,
+ 2134837,
+ 2134843,
+ 2134876,
+ 2134880,
+ 2134908,
+ 2134894,
+ 2134870,
+ 2134960,
+ 2134956,
+ 2134957,
+ 2134932,
+ 2134969,
+ 2134998,
+ 2134999,
+ 2135016,
+ 2135013,
+ 2135000,
+ 2134979,
+ 2135005,
+ 2134992,
+ 2134984,
+ 2135012,
+ 2135066,
+ 2135060,
+ 2135059,
+ 2135043,
+ 2135047,
+ 2135056,
+ 2135094,
+ 2135083,
+ 2135093,
+ 2135073,
+ 2135098,
+ 2135105,
+ 2135122,
+ 2135108,
+ 2135131,
+ 2135136,
+ 2135138,
+ 2135134,
+ 2135146,
+ 2134569,
+ 2135152,
+ 2135157,
+ 2135159,
+ 2135165,
+ 2135130,
+ 2135164,
+ 2135166,
+ 2135169,
+ 2135167,
+ 2135426,
+ 2135431,
+ 2135434,
+ 2135444,
+ 2135446,
+ 2135448,
+ 2135449,
+ 2135456,
+ 2135464,
+ 2135463,
+ 2135469,
+ 2135484,
+ 2135483,
+ 2135481,
+ 2135486,
+ 2135498,
+ 2125814,
+ 2135491,
+ 2135501,
+ 2135500,
+ 2135509,
+ 2135508,
+ 2135510,
+ 2135516,
+ 2135521,
+ 2135525,
+ 2135522,
+ 2135585,
+ 2135592,
+ 2135598,
+ 2135599,
+ 2135618,
+ 2135628,
+ 2135631,
+ 2135627,
+ 2135671,
+ 2135644,
+ 2135646,
+ 2135645,
+ 2135647,
+ 2135654,
+ 2135666,
+ 2135660,
+ 2135693,
+ 2135704,
+ 2135701,
+ 2135703,
+ 2135722,
+ 2135719,
+ 2135729,
+ 2135730,
+ 2135728,
+ 2135732,
+ 2135734,
+ 2135736,
+ 2135737,
+ 2135758,
+ 2135755,
+ 2135753,
+ 2135757,
+ 2132301,
+ 2135772,
+ 2135821,
+ 2135765,
+ 2135801,
+ 2135812,
+ 2135814,
+ 2135816,
+ 2135827,
+ 2135822,
+ 2135825,
+ 2135823,
+ 2135830,
+ 2135833,
+ 2135844,
+ 2135850,
+ 2135856,
+ 2135865,
+ 2135869,
+ 2135870,
+ 2135876,
+ 2135878,
+ 2135880,
+ 2135874,
+ 2135881,
+ 2135900,
+ 2135904,
+ 2135908,
+ 2135910,
+ 2135912,
+ 2118354,
+ 2135915,
+ 2135921,
+ 2135929,
+ 2135941,
+ 2135932,
+ 2135937,
+ 2135930,
+ 2135942,
+ 2135947,
+ 2135951,
+ 2135952,
+ 2135964,
+ 2135976,
+ 2135974,
+ 2135971,
+ 2135987,
+ 2135988,
+ 2136003,
+ 2136006,
+ 2136008,
+ 2136011,
+ 2136028,
+ 2136045,
+ 2137935,
+ 2136050,
+ 2128607,
+ 2136054,
+ 2136053,
+ 2136079,
+ 2136076,
+ 2136120,
+ 2136100,
+ 2136097,
+ 2136119,
+ 2136125,
+ 2136134,
+ 2136143,
+ 2136139,
+ 2136171,
+ 2136175,
+ 2136176,
+ 2136177,
+ 2136180,
+ 2136179,
+ 2136234,
+ 2136239,
+ 2136241,
+ 2136246,
+ 2136260,
+ 2136259,
+ 2136262,
+ 2136297,
+ 2136299,
+ 2136323,
+ 2136329,
+ 2136338,
+ 2136340,
+ 2136344,
+ 2136353,
+ 2136349,
+ 2136350,
+ 2136356,
+ 2136352,
+ 2136364,
+ 2136366,
+ 2136381,
+ 2136382,
+ 2136386,
+ 2136393,
+ 2136389,
+ 2136400,
+ 2136395,
+ 2136401,
+ 2136402,
+ 2136396,
+ 2136405,
+ 2136471,
+ 2136472,
+ 2136485,
+ 2136493,
+ 2136494,
+ 2136508,
+ 2136543,
+ 2136539,
+ 2136541,
+ 2136536,
+ 2136529,
+ 2136557,
+ 2136558,
+ 2136561,
+ 2136562,
+ 2136571,
+ 2136568,
+ 2136577,
+ 2136591,
+ 2136581,
+ 2136546,
+ 2136601,
+ 2136619,
+ 2136631,
+ 2136645,
+ 2136642,
+ 2136640,
+ 2136643,
+ 2136638,
+ 2136661,
+ 2136653,
+ 2136667,
+ 2136663,
+ 2136671,
+ 2136674,
+ 2136677,
+ 2136676,
+ 2136681,
+ 2136683,
+ 2136682,
+ 2136749,
+ 2136752,
+ 2136764,
+ 2136768,
+ 2136783,
+ 2136785,
+ 2136787,
+ 2136788,
+ 2136798,
+ 2136799,
+ 2136802,
+ 2136803,
+ 2136806,
+ 2136815,
+ 2136811,
+ 2136814,
+ 2136820,
+ 2136817,
+ 2136823,
+ 2136827,
+ 2136838,
+ 2136856,
+ 2136858,
+ 2136863,
+ 2136866,
+ 2136867,
+ 2136869,
+ 2136871,
+ 2136872,
+ 2136873,
+ 2136874,
+ 2136878,
+ 2136879,
+ 2136882,
+ 2136900,
+ 2136899,
+ 2136911,
+ 2136909,
+ 2136910,
+ 2136913,
+ 2136920,
+ 2136948,
+ 2136979,
+ 2136963,
+ 2136977,
+ 2136982,
+ 2136983,
+ 2136991,
+ 2136992,
+ 2137000,
+ 2137012,
+ 2137024,
+ 2137034,
+ 2137017,
+ 2137030,
+ 2137039,
+ 2137041,
+ 2137042,
+ 2137059,
+ 2137058,
+ 2137060,
+ 2137044,
+ 2137057,
+ 2137146,
+ 2137074,
+ 2137073,
+ 2137072,
+ 2137109,
+ 2137108,
+ 2137097,
+ 2137107,
+ 2137100,
+ 2137094,
+ 2137096,
+ 2137106,
+ 2137098,
+ 2137092,
+ 2137134,
+ 2137115,
+ 2137125,
+ 2137124,
+ 2137121,
+ 2137136,
+ 2137159,
+ 2137138,
+ 2137158,
+ 2137150,
+ 2137178,
+ 2137184,
+ 2137191,
+ 2137206,
+ 2137208,
+ 2137319,
+ 2137324,
+ 2137328,
+ 2137353,
+ 2137352,
+ 2137323,
+ 2137347,
+ 2137350,
+ 2137386,
+ 2137382,
+ 2137519,
+ 2137379,
+ 2137375,
+ 2137412,
+ 2137365,
+ 2137362,
+ 2137409,
+ 2137407,
+ 2137406,
+ 2137414,
+ 2137416,
+ 2137437,
+ 2137438,
+ 2137444,
+ 2137425,
+ 2137424,
+ 2137433,
+ 2137458,
+ 2137481,
+ 2137479,
+ 2137515,
+ 2137455,
+ 2137466,
+ 2137498,
+ 2137508,
+ 2137513,
+ 2137522,
+ 2137540,
+ 2137537,
+ 2137531,
+ 2137528,
+ 2137530,
+ 2137542,
+ 2137551,
+ 2137538,
+ 2137561,
+ 2137555,
+ 2137592,
+ 2137574,
+ 2137581,
+ 2137583,
+ 2137597,
+ 2137626,
+ 2137627,
+ 2137630,
+ 2137717,
+ 2137721,
+ 2137725,
+ 2137729,
+ 2137736,
+ 2137739,
+ 2137740,
+ 2137746,
+ 2137749,
+ 2137745,
+ 2137757,
+ 2137765,
+ 2137769,
+ 2137784,
+ 2137770,
+ 2137773,
+ 2135905,
+ 2137804,
+ 2137806,
+ 2137807,
+ 2137808,
+ 2137812,
+ 2137820,
+ 2137822,
+ 2137821,
+ 2137824,
+ 2137829,
+ 2137832,
+ 2137839,
+ 2137844,
+ 2137846,
+ 2137847,
+ 2137849,
+ 2137851,
+ 2137852,
+ 2137853,
+ 2137863,
+ 2137864,
+ 2127543,
+ 2137877,
+ 2137889,
+ 2137900,
+ 2137918,
+ 2137930,
+ 2137938,
+ 2137940,
+ 2137955,
+ 2137951,
+ 2137952,
+ 2137953,
+ 2137958,
+ 2137959,
+ 2137964,
+ 2137962,
+ 2137975,
+ 2137970,
+ 2137974,
+ 2138005,
+ 2138012,
+ 2138016,
+ 2119727,
+ 2124231,
+ 2134105,
+ 2126948,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ 2119006,
+ 4233460,
+ 4222626,
+ 4234287,
+ 4222443,
+ 4231106,
+ 4221725,
+ 4215721,
+ 2264285,
+ 4216386,
+ 4233484,
+ 2126128,
+ 4229462,
+ 2137559,
+ 4231142,
+ 4218978,
+ 4219600,
+ 4220518,
+ 4216221,
+ 4228187,
+ 4233092,
+ 2119321,
+ 2112846,
+ 4227056,
+ 4227051,
+ 4218813,
+ 4225351,
+ 2117600,
+ 6312831,
+ 4214981,
+ 2133696,
+ 4216240,
+ 2124507,
+ 4217937,
+ 4233076,
+ 4225345,
+ 4219239,
+ 2250868,
+ 2129515,
+ 2130758,
+ 2264822,
+ 4214822,
+ 4217548,
+ 4219762,
+ 2137724,
+ 4229882,
+ 4218359,
+ 2123323,
+ 4222621,
+ 2137780,
+ 4234592,
+ 4224273,
+ 4231623,
+ 4221322,
+ 2123781,
+ 4228521,
+ 4234198,
+ 4231942,
+ 4223946,
+ 4215793,
+ 2120802,
+ 4231278,
+ 4220755,
+ 4223100,
+ 2129505,
+ 4231499,
+ 4220633,
+ 2125338,
+ 4228527,
+ 4228599,
+ 4216040,
+ 4218592,
+ 4221090,
+ 2131235,
+ 2134444,
+ 4233112,
+ 4228949,
+ 4233073,
+ 4231191,
+ 4227040,
+ 4220026,
+ 4231197,
+ 2131948,
+ 4220080,
+ 4220947,
+ 4223310,
+ 4223357,
+ 4229742,
+ 4216396,
+ 4231265,
+ 4215413,
+ 2122772,
+ 4224550,
+ 4231260,
+ 2136658,
+ 4227455,
+ 4234971,
+ 4216132,
+ 4222959,
+ 2126882,
+ 4228856,
+ 2121213,
+ 4231103,
+ 4221146,
+ 4234312,
+ 4221501,
+ 2128926,
+ 4229691,
+ 4223014,
+ 4215243,
+ 4219735,
+ 4221388,
+ 4232090,
+ 4216922,
+ 2122833,
+ 4231469,
+ 4220130,
+ 4222650,
+ 2119777,
+ 2136154,
+ 4216885,
+ 4217952,
+ 4228063,
+ 4230381,
+ 4216920,
+ 2128305,
+ 4234503,
+ 2125830,
+ 4223006,
+ 4216440,
+ 4231233,
+ 4233235,
+ 4231331,
+ 4229902,
+ 4223064,
+ 4221282,
+ 4225456,
+ 2119370,
+ 4223564,
+ 4231193,
+ 4225508,
+ 2118237,
+ 4225976,
+ 2125649,
+ 2134449,
+ 4219709,
+ 4219465,
+ 4221451,
+ 4220874,
+ 4225559,
+ 4231228,
+ 4217499,
+ 4229932,
+ 4218591,
+ 4222997,
+ 2136123,
+ 4228413,
+ 4224933,
+ 4217385,
+ 4218518,
+ 4222177,
+ 4228332,
+ 2136112,
+ 4234322,
+ 2137781,
+ 4215090,
+ 4233477,
+ 4226174,
+ 4232275,
+ 4219144,
+ 4224594,
+ 4223799,
+ 4223380,
+ 4227072,
+ 2130954,
+ 4231292,
+ 2125603,
+ 2126153,
+ 2131182,
+ 4221332,
+ 2131999,
+ 2117972,
+ 4215177,
+ 2118037,
+ 4215204,
+ 4216121,
+ 4216115,
+ 4216292,
+ 4216370,
+ 4216485,
+ 4216843,
+ 4217534,
+ 2234906,
+ 2120795,
+ 4218468,
+ 4219031,
+ 4219753,
+ 4219910,
+ 2123042,
+ 4220291,
+ 4220838,
+ 2123770,
+ 4221083,
+ 2123918,
+ 4222574,
+ 2245584,
+ 2126376,
+ 4223950,
+ 4224260,
+ 4224269,
+ 4224277,
+ 4224659,
+ 4225148,
+ 4225585,
+ 4235165,
+ 4225945,
+ 4226192,
+ 4226222,
+ 4226459,
+ 4226478,
+ 4226463,
+ 4227028,
+ 4227630,
+ 4227725,
+ 4227794,
+ 4227875,
+ 4227957,
+ 4228375,
+ 2131262,
+ 4228994,
+ 4229074,
+ 4229386,
+ 4229551,
+ 4229854,
+ 4229953,
+ 4230618,
+ 4230665,
+ 4230931,
+ 4231146,
+ 4231145,
+ 4231256,
+ 4219464,
+ 4231617,
+ 4232635,
+ 2127714,
+ 4232996,
+ 4233056,
+ 4233069,
+ 4233252,
+ 4234030,
+ 4234135,
+ 4234226,
+ 4234922,
+ 4235164,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ 4227750,
+ 4227880,
+ 2119251,
+ 6312873,
+ 4223577,
+ 4222066,
+ 4225800,
+ 4233559,
+ 4219635,
+ 4233488,
+ 6330221,
+ 6320509,
+ 4225663,
+ 4225965,
+ 4219843,
+ 6325215,
+ 4225378,
+ 4215771,
+ 4225991,
+ 4231108,
+ 4226110,
+ 4214986,
+ 4215573,
+ 4216233,
+ 4216494,
+ 4216857,
+ 4217115,
+ 4217896,
+ 4218576,
+ 4218575,
+ 4219457,
+ 4220609,
+ 4221960,
+ 4222499,
+ 4222700,
+ 4225687,
+ 4226013,
+ 4227049,
+ 4228130,
+ 4228953,
+ 4229134,
+ 6326226,
+ 4233753,
+ 4234925,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ 4231202,
+ 4231099,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ 2118108,
+ 2126233,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ 2129546,
+ 2132252,
+ 2134856,
+ 2134664,
+ 2131164,
+ 2117577,
+ 2126011,
+ 2123313,
+ 2123976,
+ 2134777,
+ 2123515,
+ 2121541,
+ 2117160,
+ 2117345,
+ 2117372,
+ 2117376,
+ 2117379,
+ 2117433,
+ 2117462,
+ 2117522,
+ 2117514,
+ 2117530,
+ 2117524,
+ 2117581,
+ 2117696,
+ 2117666,
+ 2117631,
+ 2117662,
+ 2117702,
+ 2117744,
+ 2117698,
+ 2117780,
+ 2117876,
+ 2117848,
+ 2117962,
+ 2117988,
+ 2118045,
+ 2118078,
+ 2118124,
+ 2118165,
+ 2118300,
+ 2118310,
+ 2118336,
+ 2118363,
+ 2118400,
+ 4215559,
+ 2118436,
+ 2118514,
+ 2118547,
+ 2118578,
+ 2118621,
+ 2161166,
+ 2118812,
+ 2118794,
+ 2118825,
+ 2118911,
+ 2119046,
+ 2119513,
+ 2119525,
+ 2119596,
+ 2119624,
+ 2119623,
+ 2161167,
+ 6314074,
+ 2119838,
+ 2119858,
+ 2119947,
+ 2120019,
+ 2120027,
+ 2120029,
+ 2120035,
+ 2120100,
+ 2120122,
+ 2120534,
+ 2120640,
+ 2127151,
+ 2120664,
+ 4217819,
+ 2120734,
+ 2120870,
+ 2120890,
+ 2120949,
+ 2120999,
+ 2121043,
+ 4258321,
+ 2121026,
+ 2121069,
+ 2121144,
+ 2121145,
+ 2121168,
+ 2121505,
+ 2121524,
+ 2121575,
+ 2121655,
+ 2121694,
+ 2121821,
+ 2121861,
+ 2121866,
+ 2121950,
+ 2121941,
+ 2122016,
+ 2121970,
+ 2122001,
+ 2122039,
+ 2122032,
+ 2122136,
+ 2122259,
+ 2122406,
+ 2122741,
+ 2122848,
+ 2122909,
+ 2122958,
+ 2123086,
+ 2123264,
+ 2123285,
+ 2123273,
+ 2123310,
+ 4220446,
+ 2123300,
+ 2123365,
+ 2123351,
+ 2123353,
+ 2123380,
+ 2123379,
+ 2123417,
+ 2123424,
+ 2123442,
+ 2123455,
+ 2123514,
+ 2123534,
+ 6317847,
+ 2123622,
+ 2123707,
+ 4221010,
+ 2123712,
+ 4220929,
+ 2123844,
+ 2123983,
+ 2161171,
+ 2124136,
+ 2161172,
+ 2124184,
+ 2124258,
+ 2124336,
+ 2124395,
+ 2124358,
+ 2124403,
+ 2124414,
+ 2124514,
+ 2124516,
+ 2124758,
+ 2124863,
+ 2124892,
+ 2124934,
+ 2124911,
+ 2125018,
+ 2125060,
+ 2125191,
+ 2125167,
+ 2125206,
+ 2125228,
+ 2125263,
+ 2125304,
+ 2125298,
+ 2125308,
+ 2125369,
+ 2125404,
+ 2125351,
+ 2125372,
+ 2125503,
+ 2125704,
+ 2125749,
+ 2125813,
+ 2125829,
+ 2125831,
+ 2125864,
+ 2125957,
+ 2125995,
+ 2126095,
+ 2126084,
+ 2126172,
+ 2126150,
+ 2126151,
+ 10506718,
+ 2126273,
+ 2126334,
+ 2126513,
+ 2126526,
+ 2126628,
+ 2126634,
+ 2126711,
+ 2126781,
+ 2126793,
+ 2126806,
+ 2126819,
+ 2126802,
+ 2126855,
+ 2126837,
+ 2126886,
+ 2126890,
+ 2126889,
+ 2126894,
+ 4224098,
+ 2126985,
+ 2127007,
+ 2127105,
+ 2127215,
+ 2127490,
+ 2127516,
+ 2127518,
+ 2127515,
+ 2127526,
+ 4224714,
+ 2127686,
+ 2118319,
+ 2127905,
+ 2127950,
+ 2127972,
+ 2127994,
+ 2128176,
+ 4225340,
+ 2128222,
+ 2128229,
+ 2128276,
+ 4225423,
+ 2128283,
+ 2128593,
+ 2128615,
+ 4233046,
+ 2128619,
+ 2128798,
+ 2129086,
+ 2129224,
+ 4226396,
+ 2129335,
+ 2129312,
+ 2129366,
+ 2129490,
+ 2129735,
+ 2129825,
+ 2129853,
+ 2130689,
+ 2130786,
+ 2130815,
+ 2130887,
+ 2130934,
+ 2131016,
+ 2131124,
+ 2131283,
+ 2131289,
+ 2131307,
+ 2161183,
+ 2131376,
+ 4228626,
+ 2161185,
+ 2131975,
+ 2132213,
+ 2132498,
+ 2132535,
+ 2132601,
+ 2132647,
+ 2132670,
+ 2132703,
+ 2132728,
+ 2132726,
+ 2132819,
+ 2132863,
+ 2133232,
+ 2133236,
+ 2133266,
+ 2133366,
+ 2161187,
+ 2133711,
+ 4258340,
+ 6328376,
+ 2134119,
+ 2134238,
+ 2134269,
+ 2134293,
+ 2134311,
+ 2134490,
+ 2134487,
+ 2134494,
+ 2134509,
+ 2134510,
+ 2134500,
+ 2134501,
+ 2134534,
+ 2134544,
+ 2134538,
+ 2134586,
+ 2134592,
+ 2134588,
+ 2134606,
+ 2134617,
+ 2134609,
+ 2134585,
+ 2134631,
+ 2134695,
+ 2134647,
+ 2134648,
+ 2134759,
+ 2134743,
+ 2134745,
+ 2134736,
+ 2161191,
+ 2134741,
+ 2134752,
+ 2134739,
+ 2134821,
+ 2134817,
+ 2134779,
+ 2161192,
+ 2134814,
+ 2134783,
+ 2134813,
+ 2134786,
+ 2134896,
+ 2134871,
+ 2134948,
+ 2134982,
+ 2135006,
+ 2135032,
+ 2135089,
+ 2135109,
+ 2135112,
+ 2135442,
+ 6329990,
+ 2161193,
+ 2135709,
+ 2135727,
+ 2135859,
+ 2135867,
+ 2135875,
+ 2135885,
+ 2135887,
+ 2135889,
+ 4233045,
+ 2136151,
+ 2136165,
+ 2136303,
+ 4233468,
+ 2136359,
+ 4233512,
+ 2136478,
+ 2136654,
+ 2136793,
+ 2136796,
+ 2136949,
+ 2136946,
+ 2136975,
+ 2137009,
+ 2137019,
+ 2137088,
+ 2137456,
+ 2137451,
+ 2137524,
+ 2137625,
+ 2137809,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ 6319336,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ 4231224,
+ 2132737,
+ 2129379,
+ 2137795,
+ 2125483,
+ 2128269,
+ 2121876,
+ 2125175,
+ 4219240,
+ 2124266,
+ 2125364,
+ 4229392,
+ 4222754,
+ 4216424,
+ 2123234,
+ 2128200,
+ 2131547,
+ 4233215,
+ 4215524,
+ 2132793,
+ 2122733,
+ 2122954,
+ 2127951,
+ 2128448,
+ 2124730,
+ 4225353,
+ 4229526,
+ 2126190,
+ 4225342,
+ 4227077,
+ 4227565,
+ 2128221,
+ 4220561,
+ 2129778,
+ 2125193,
+ 2126528,
+ 4219214,
+ 2127646,
+ 4225984,
+ 4225366,
+ 4215015,
+ 4217956,
+ 2121186,
+ 2122126,
+ 4230408,
+ 2118525,
+ 2119174,
+ 4228183,
+ 2121653,
+ 4219378,
+ 4232110,
+ 4225422,
+ 4234029,
+ 4225665,
+ 2135779,
+ 2123909,
+ 4226625,
+ 2123354,
+ 2118481,
+ 2128017,
+ 2133203,
+ 2123087,
+ 4214702,
+ 4214645,
+ 4216896,
+ 2118345,
+ 2124645,
+ 2119848,
+ 2124751,
+ 4215117,
+ 2122302,
+ 2128208,
+ 2124548,
+ 4232838,
+ 2131548,
+ 2125274,
+ 2136158,
+ 2123462,
+ 2124663,
+ 2129396,
+ 2134858,
+ 6315722,
+ 2134788,
+ 4221314,
+ 4215220,
+ 4219724,
+ 4228827,
+ 4231305,
+ 6328354,
+ 4214857,
+ 4226543,
+ 4231253,
+ 8410025,
+ 6330636,
+ 4229211,
+ 4218614,
+ 6319295,
+ 4231771,
+ 4227009,
+ 6324925,
+ 4232901,
+ 4217779,
+ 6316392,
+ 6318466,
+ 4221883,
+ 4220258,
+ 4230315,
+ 4218316,
+ 4233233,
+ 4218416,
+ 4230860,
+ 4225710,
+ 4216647,
+ 4214929,
+ 4225652,
+ 4214885,
+ 4218618,
+ 4231735,
+ 4221582,
+ 4214436,
+ 4215148,
+ 4220660,
+ 4220961,
+ 4225132,
+ 4226398,
+ 4227075,
+ 4230396,
+ 4232781,
+ 4219639,
+ 4226922,
+ 4214655,
+ 4215794,
+ 4217289,
+ 4229917,
+ 4231338,
+ 4215758,
+ 4230959,
+ 4220884,
+ 4224940,
+ 4227612,
+ 4221295,
+ 4220798,
+ 4229663,
+ 4214280,
+ 4216820,
+ 4221197,
+ 4227191,
+ 4229546,
+ 4231234,
+ 4219758,
+ 4219970,
+ 4227641,
+ 4226511,
+ 4227169,
+ 4214991,
+ 4229781,
+ 4218981,
+ 4215110,
+ 4224826,
+ 4227188,
+ 4230643,
+ 4218541,
+ 4218615,
+ 4227655,
+ 4220995,
+ 4231171,
+ 4222270,
+ 4219794,
+ 4230953,
+ 4223981,
+ 4233234,
+ 4219058,
+ 6316617,
+ 4220304,
+ 4226507,
+ 4229817,
+ 4230311,
+ 4223542,
+ 4228218,
+ 4215302,
+ 4216436,
+ 4219300,
+ 4226185,
+ 4226331,
+ 4232944,
+ 6325565,
+ 4214719,
+ 4219751,
+ 4224710,
+ 4221021,
+ 4227336,
+ 4227126,
+ 4227068,
+ 4215823,
+ 4232867,
+ 4234911,
+ 4234903,
+ 4227183,
+ 4227198,
+ 4222590,
+ 4214917,
+ 4215187,
+ 4215259,
+ 2230542,
+ 4215616,
+ 4232921,
+ 6313385,
+ 4216513,
+ 4216589,
+ 4217003,
+ 4217306,
+ 4217398,
+ 6314686,
+ 4218190,
+ 4218247,
+ 4218313,
+ 4218323,
+ 4218669,
+ 4218776,
+ 4219096,
+ 4219197,
+ 4219390,
+ 4219496,
+ 4219599,
+ 4220189,
+ 4219919,
+ 4220146,
+ 4220253,
+ 4220511,
+ 4220841,
+ 4220903,
+ 4221291,
+ 4221232,
+ 4221351,
+ 4221508,
+ 4221584,
+ 6319112,
+ 4221971,
+ 6319651,
+ 4222737,
+ 4222718,
+ 4222782,
+ 4223487,
+ 4223973,
+ 4224050,
+ 4224095,
+ 4224224,
+ 4224268,
+ 4224626,
+ 4225322,
+ 4225236,
+ 4225466,
+ 4225561,
+ 4225685,
+ 4226290,
+ 4226419,
+ 4226525,
+ 4226613,
+ 4226990,
+ 4227041,
+ 4227162,
+ 4227167,
+ 4227187,
+ 4227184,
+ 4227190,
+ 4227411,
+ 4227466,
+ 4227509,
+ 4227533,
+ 4228082,
+ 4228437,
+ 4228565,
+ 4228890,
+ 4229174,
+ 4229278,
+ 4229336,
+ 4229364,
+ 4229419,
+ 4229435,
+ 4229482,
+ 4229487,
+ 4229661,
+ 4230405,
+ 4230415,
+ 4235086,
+ 4230801,
+ 4230817,
+ 4231250,
+ 4231182,
+ 4231472,
+ 4231510,
+ 4231512,
+ 4231525,
+ 4231539,
+ 4231538,
+ 4231586,
+ 4231599,
+ 4231594,
+ 4231604,
+ 4231610,
+ 4232311,
+ 4232856,
+ 4233021,
+ 6330208,
+ 6330225,
+ 4233228,
+ 4233331,
+ 4233411,
+ 4233797,
+ 4234061,
+ 4234072,
+ 4234182,
+ 4234209,
+ 4234225,
+ 4234568,
+ 4234703,
+ 4235016,
+ 4219505,
+ 4220567,
+ 4219151,
+ 4229219,
+ 6328405,
+ 4231290,
+ 4225263,
+ 2133151,
+ 4232936,
+ 2255185,
+ 10507177,
+ 4224220,
+ 4231243,
+ 8427788,
+ 2275288,
+ 2134707,
+ 2135473,
+ 6315766,
+ 4219892,
+ 2124991,
+ 4223321,
+ 4231264,
+ 6328923,
+ 4220348,
+ 4218752,
+ 6324161,
+ 4215672,
+ 4233203,
+ 4215574,
+ 4227761,
+ 4228051,
+ 4230312,
+ 4231246,
+ 2130621,
+ 6330053,
+ 4233491,
+ 4218619,
+ 4223088,
+ 6314931,
+ 8413544,
+ 10510696,
+ 12607848,
+ 4221418,
+ 8415618,
+ 2123630,
+ 2132434,
+ 4232852,
+ 2118258,
+ 4230980,
+ 4232076,
+ 4227781,
+ 4217810,
+ 4224176,
+ 4226537,
+ 2253346,
+ 4231300,
+ 4232594,
+ 4233171,
+ 4227608,
+ 4215665,
+ 4207618,
+ 2110466,
+ 6304770,
+ 4218494,
+ 2123235,
+ 4220703,
+ 4221535,
+ 4230519,
+ 4233442,
+ 2231223,
+ 4216235,
+ 4228688,
+ 4231174,
+ 4215754,
+ 4215864,
+ 4218917,
+ 4226330,
+ 4218344,
+ 4219602,
+ 4230621,
+ 2268491,
+ 4365643,
+ 2118527,
+ 2121530,
+ 4218960,
+ 4221377,
+ 4339258,
+ 2275214,
+ 4231415,
+ 6330367,
+ 6330711,
+ 4220545,
+ 4223883,
+ 4231121,
+ 2117617,
+ 4225001,
+ 4215159,
+ 4228702,
+ 4225658,
+ 4231239,
+ 6318811,
+ 4216147,
+ 4217169,
+ 4218997,
+ 6316391,
+ 4231118,
+ 6312081,
+ 4222804,
+ 6322804,
+ 4220680,
+ 4227615,
+ 4215164,
+ 4215352,
+ 4219314,
+ 2123587,
+ 4227241,
+ 4229913,
+ 4231267,
+ 2230884,
+ 2132481,
+ 2122294,
+ 4232903,
+ 4233319,
+ 2118707,
+ 2120219,
+ 4229796,
+ 4218341,
+ 4219212,
+ 2122373,
+ 4219815,
+ 4221387,
+ 4222313,
+ 4222511,
+ 4227093,
+ 4227412,
+ 4227922,
+ 4229915,
+ 6327548,
+ 2118719,
+ 4231543,
+ 4227440,
+ 6321425,
+ 4231100,
+ 2275142,
+ 4232086,
+ 2275191,
+ 4218729,
+ 4219809,
+ 2124658,
+ 4228060,
+ 6312372,
+ 4215986,
+ 4215370,
+ 2127138,
+ 2116408,
+ 4217343,
+ 6314495,
+ 2121215,
+ 4229870,
+ 6327022,
+ 4230343,
+ 6327495,
+ 4221729,
+ 6318881,
+ 4222667,
+ 2126778,
+ 2231199,
+ 4219752,
+ 4220316,
+ 6328490,
+ 2118394,
+ 6320693,
+ 2126389,
+ 4231500,
+ 4218673,
+ 4214331,
+ 4215767,
+ 4219784,
+ 2118760,
+ 4226370,
+ 4227026,
+ 4229190,
+ 4231217,
+ 4214607,
+ 4229203,
+ 4231152,
+ 4218337,
+ 4231285,
+ 6328437,
+ 4219456,
+ 4220664,
+ 4217203,
+ 4215517,
+ 4216134,
+ 4217781,
+ 2120710,
+ 4217871,
+ 2282820,
+ 2120729,
+ 4222344,
+ 4225117,
+ 4227222,
+ 2228235,
+ 2120578,
+ 2119630,
+ 4219077,
+ 6313972,
+ 4233470,
+ 6318349,
+ 4221846,
+ 4233439,
+ 2136288,
+ 2266751,
+ 2111373,
+ 4214709,
+ 2111738,
+ 4222328,
+ 4224799,
+ 4231218,
+ 2117307,
+ 2228642,
+ 4215299,
+ 4217867,
+ 4229642,
+ 6326794,
+ 4231109,
+ 2286953,
+ 6328386,
+ 2110751,
+ 2275153,
+ 4219408,
+ 4224731,
+ 4227158,
+ 2132352,
+ 4229792,
+ 4229835,
+ 4233052,
+ 6330204,
+ 2128389,
+ 4227334,
+ 4232891,
+ 4226125,
+ 6323136,
+ 2132650,
+ 4232938,
+ 2129237,
+ 4219463,
+ 2125720,
+ 4226977,
+ 6324793,
+ 4231288,
+ 4231287,
+ 4215373,
+ 4215144,
+ 4219779,
+ 2122743,
+ 2127398,
+ 4230512,
+ 4231169,
+ 4231277,
+ 4231200,
+ 2260919,
+ 4231199,
+ 4230346,
+ 4217866,
+ 6315018,
+ 4217253,
+ 2243838,
+ 4231168,
+ 4231214,
+ 4232842,
+ 4234203,
+ 4217127,
+ 2110503,
+ 4223015,
+ 4231252,
+ 2130219,
+ 4214329,
+ 4221774,
+ 4223149,
+ 6326933,
+ 4220566,
+ 4214820,
+ 4226926,
+ 4225993,
+ 2251479,
+ 4225873,
+ 4231184,
+ 4220913,
+ 4222184,
+ 4233680,
+ 4218731,
+ 4218805,
+ 6316530,
+ 4220701,
+ 2125678,
+ 4229823,
+ 4224756,
+ 4220693,
+ 6317845,
+ 4216988,
+ 4231165,
+ 4231194,
+ 4216682,
+ 4231651,
+ 4215880,
+ 4218397,
+ 4225547,
+ 4224644,
+ 4231273,
+ 4231149,
+ 4222459,
+ 4215118,
+ 4231188,
+ 4225082,
+ 2119457,
+ 2232893,
+ 2118060,
+ 4216080,
+ 2129110,
+ 4228580,
+ 4229892,
+ 6328323,
+ 4231183,
+ 4233776,
+ 4217870,
+ 4231251,
+ 2118686,
+ 2112392,
+ 2117991,
+ 4227209,
+ 4214387,
+ 4218829,
+ 4229773,
+ 2120679,
+ 4226317,
+ 4229511,
+ 6319422,
+ 4227258,
+ 4215642,
+ 4228484,
+ 4231147,
+ 4226587,
+ 4227207,
+ 2117175,
+ 4222801,
+ 4231601,
+ 4214580,
+ 4215332,
+ 4215626,
+ 4218374,
+ 4224340,
+ 4220521,
+ 4228419,
+ 4231295,
+ 4218798,
+ 4235067,
+ 4215609,
+ 2247956,
+ 2121573,
+ 2120172,
+ 4217324,
+ 4229717,
+ 2121369,
+ 4224453,
+ 4217446,
+ 4220279,
+ 4222318,
+ 4230304,
+ 6327456,
+ 4220685,
+ 4229510,
+ 4214297,
+ 4218467,
+ 4218483,
+ 4218634,
+ 4228369,
+ 4214863,
+ 4226536,
+ 4231124,
+ 4231245,
+ 4226111,
+ 4215557,
+ 4218153,
+ 4219569,
+ 4220683,
+ 4225074,
+ 4226603,
+ 4227294,
+ 4228108,
+ 4231334,
+ 6328486,
+ 4233469,
+ 4234604,
+ 4214433,
+ 4218429,
+ 4218840,
+ 4218841,
+ 4219455,
+ 4220699,
+ 6317851,
+ 4215186,
+ 4220009,
+ 4227067,
+ 4215265,
+ 4225256,
+ 4234068,
+ 4234939,
+ 4221401,
+ 6318173,
+ 2110568,
+ 2138036,
+ 4226669,
+ 4234943,
+ 6324488,
+ 4220430,
+ 4224735,
+ 4231159,
+ 4217220,
+ 2118352,
+ 4224754,
+ 4227095,
+ 4219451,
+ 4226315,
+ 2135528,
+ 4226308,
+ 4230797,
+ 2275209,
+ 6318202,
+ 2123777,
+ 4219145,
+ 2132717,
+ 4230968,
+ 4215495,
+ 4220681,
+ 4223798,
+ 6320950,
+ 6320951,
+ 2250367,
+ 4231242,
+ 4220636,
+ 2129802,
+ 4229505,
+ 4233482,
+ 4227020,
+ 6324220,
+ 2133686,
+ 4228653,
+ 4223879,
+ 4235149,
+ 6332301,
+ 4220357,
+ 2138052,
+ 4223440,
+ 6330019,
+ 4234327,
+ 6332063,
+ 2129019,
+ 2121417,
+ 4219280,
+ 2134051,
+ 8414999,
+ 2129922,
+ 2254512,
+ 6312138,
+ 4215066,
+ 6312276,
+ 6312341,
+ 2229800,
+ 4215437,
+ 4215511,
+ 2228362,
+ 2230660,
+ 2110782,
+ 4215775,
+ 4220668,
+ 6313267,
+ 6313444,
+ 2118741,
+ 4216512,
+ 2119993,
+ 4217372,
+ 4217538,
+ 2120566,
+ 4217795,
+ 2120724,
+ 2111458,
+ 2120934,
+ 4218452,
+ 2117192,
+ 4218595,
+ 6316183,
+ 2122452,
+ 4219596,
+ 4219932,
+ 4219846,
+ 4219944,
+ 2255257,
+ 2122523,
+ 6317663,
+ 8414815,
+ 2123363,
+ 4220661,
+ 2241484,
+ 4221085,
+ 4221069,
+ 2124278,
+ 2124166,
+ 2271718,
+ 4217832,
+ 4221371,
+ 2124748,
+ 6319889,
+ 2125335,
+ 4222872,
+ 4222122,
+ 2124970,
+ 4223003,
+ 4223330,
+ 4223547,
+ 2117164,
+ 4223772,
+ 4224202,
+ 2127087,
+ 2127221,
+ 2127340,
+ 2127438,
+ 2113457,
+ 2127722,
+ 2127785,
+ 4225344,
+ 2138054,
+ 6322515,
+ 4235083,
+ 4225454,
+ 4231299,
+ 2128723,
+ 2275261,
+ 4226068,
+ 2114148,
+ 4226128,
+ 4226136,
+ 4226374,
+ 4226403,
+ 4226594,
+ 6323746,
+ 2129480,
+ 6323765,
+ 4226627,
+ 4226700,
+ 2286200,
+ 2229567,
+ 2253418,
+ 4350576,
+ 4227013,
+ 4227014,
+ 6324201,
+ 2130241,
+ 2114643,
+ 4227672,
+ 2130553,
+ 6324857,
+ 4227705,
+ 4227811,
+ 2118009,
+ 2130778,
+ 4228128,
+ 4228029,
+ 4228340,
+ 2114853,
+ 4228487,
+ 2131444,
+ 2228400,
+ 4228919,
+ 4228923,
+ 4229125,
+ 4229053,
+ 2131581,
+ 6326326,
+ 2110510,
+ 2132166,
+ 4229565,
+ 4229851,
+ 4229950,
+ 4229978,
+ 4230515,
+ 4230553,
+ 2115558,
+ 4230708,
+ 2287338,
+ 4231151,
+ 4231303,
+ 4231162,
+ 4231198,
+ 4231221,
+ 4231248,
+ 2133960,
+ 4231297,
+ 4231306,
+ 6328458,
+ 8425610,
+ 10522762,
+ 12619914,
+ 14717066,
+ 6328457,
+ 8425609,
+ 10522761,
+ 12619913,
+ 14717065,
+ 16814217,
+ 18911369,
+ 21008521,
+ 23105673,
+ 25202825,
+ 27299977,
+ 29397129,
+ 2263431,
+ 4232157,
+ 4232636,
+ 2264599,
+ 4232882,
+ 4233049,
+ 2136121,
+ 4233451,
+ 4233475,
+ 4233481,
+ 4233541,
+ 6330693,
+ 4233547,
+ 2136584,
+ 4233823,
+ 4233829,
+ 4233967,
+ 4234008,
+ 2137055,
+ 4234505,
+ 4234504,
+ 4234917,
+ 4234956,
+ 6332168,
+ 4235082,
+ 2275354,
+ 4235111,
+ 4367898,
+ 4342510,
+ 2245358,
+ 4229404,
+ 4221128,
+ 4220667,
+ 4218693,
+ 4215552,
+ 2118537,
+ 4217171,
+ 2161169,
+ 2123858,
+ 4221555,
+ 2243774,
+ 2229777,
+ 4229650,
+ 2117124,
+ 2117125,
+ 2117151,
+ 2117163,
+ 2117167,
+ 2117168,
+ 2117184,
+ 2117185,
+ 2117188,
+ 2117210,
+ 2117247,
+ 2117261,
+ 2117270,
+ 2117305,
+ 2117328,
+ 2117344,
+ 2117373,
+ 2117375,
+ 2117387,
+ 2117397,
+ 2117472,
+ 2117435,
+ 2117449,
+ 2117460,
+ 2117498,
+ 2117501,
+ 2117502,
+ 2117527,
+ 2117566,
+ 2117583,
+ 2117629,
+ 2117632,
+ 2117633,
+ 2117648,
+ 2117659,
+ 2117671,
+ 2117678,
+ 2117719,
+ 2117734,
+ 2117738,
+ 2117691,
+ 2117775,
+ 2117782,
+ 2117788,
+ 2117836,
+ 2117862,
+ 2117865,
+ 2117871,
+ 2117896,
+ 2117899,
+ 2117904,
+ 2117915,
+ 2117918,
+ 2117983,
+ 2118049,
+ 2118076,
+ 6312414,
+ 2118126,
+ 2118132,
+ 2118145,
+ 2118146,
+ 2118163,
+ 2118217,
+ 2118241,
+ 2118246,
+ 2118291,
+ 2118344,
+ 2118384,
+ 2118410,
+ 2118411,
+ 2118462,
+ 2118476,
+ 2118475,
+ 2118497,
+ 2118508,
+ 2118571,
+ 2118618,
+ 2118630,
+ 2118645,
+ 2118695,
+ 2118733,
+ 2118758,
+ 2118763,
+ 2118772,
+ 2118797,
+ 2118806,
+ 2118817,
+ 2118829,
+ 2118841,
+ 2118847,
+ 2118854,
+ 2118861,
+ 2118926,
+ 2118955,
+ 2118965,
+ 2118986,
+ 2119008,
+ 4216161,
+ 2119048,
+ 2119054,
+ 2119176,
+ 2119182,
+ 2119183,
+ 2119223,
+ 2119231,
+ 2119241,
+ 2119243,
+ 2119247,
+ 2119270,
+ 2119273,
+ 2119279,
+ 2119281,
+ 2119282,
+ 2119317,
+ 2119322,
+ 2119340,
+ 2119341,
+ 2119345,
+ 2119369,
+ 2119389,
+ 2119396,
+ 2119434,
+ 2119445,
+ 2119459,
+ 2119471,
+ 2119475,
+ 2119476,
+ 2119500,
+ 2119536,
+ 2119564,
+ 2119580,
+ 2119608,
+ 2119654,
+ 2119661,
+ 2119669,
+ 2119670,
+ 2119679,
+ 2119689,
+ 2119712,
+ 2119730,
+ 2119804,
+ 2119808,
+ 2119849,
+ 2119886,
+ 2119888,
+ 2119892,
+ 2119898,
+ 2119913,
+ 2119948,
+ 2119972,
+ 2119983,
+ 2120033,
+ 2120045,
+ 2120138,
+ 2120146,
+ 2120157,
+ 2120163,
+ 2120164,
+ 2120196,
+ 2120204,
+ 2120227,
+ 2120263,
+ 2120277,
+ 2120291,
+ 2120301,
+ 2120318,
+ 2120350,
+ 2120359,
+ 2120364,
+ 2120371,
+ 2120416,
+ 2120448,
+ 2120473,
+ 2120485,
+ 2120493,
+ 2120513,
+ 2120572,
+ 2120574,
+ 2120575,
+ 2120586,
+ 2120739,
+ 2120747,
+ 2120752,
+ 2120803,
+ 2120809,
+ 2120828,
+ 2120907,
+ 2120914,
+ 2120948,
+ 2120996,
+ 2120998,
+ 2121027,
+ 2121030,
+ 2121034,
+ 2121106,
+ 2121108,
+ 2121113,
+ 2121120,
+ 2121176,
+ 2121184,
+ 2121208,
+ 2121216,
+ 2121234,
+ 2121236,
+ 2121237,
+ 2121240,
+ 2121262,
+ 2121304,
+ 2121323,
+ 2121324,
+ 2121384,
+ 2121386,
+ 2121406,
+ 2121407,
+ 4218571,
+ 2121426,
+ 2121479,
+ 2121486,
+ 2121500,
+ 2121501,
+ 2121506,
+ 2121512,
+ 2121526,
+ 2121531,
+ 2121536,
+ 2121552,
+ 2121560,
+ 2121572,
+ 2121609,
+ 2121628,
+ 2121639,
+ 2121636,
+ 2121647,
+ 2121656,
+ 2121668,
+ 2121673,
+ 2121697,
+ 2121705,
+ 2121709,
+ 2121724,
+ 2121751,
+ 2121754,
+ 2121779,
+ 2121825,
+ 2121855,
+ 2121886,
+ 2121892,
+ 2121904,
+ 2121931,
+ 2121947,
+ 2121976,
+ 2122002,
+ 2122003,
+ 2122004,
+ 2122012,
+ 2122108,
+ 2122125,
+ 2122143,
+ 2122152,
+ 2122178,
+ 2122207,
+ 2122261,
+ 2122281,
+ 2122307,
+ 2122310,
+ 2122316,
+ 2122321,
+ 2122326,
+ 2122436,
+ 2122492,
+ 2122506,
+ 2122509,
+ 2122520,
+ 2122553,
+ 2122562,
+ 2122563,
+ 2122597,
+ 2122612,
+ 2122621,
+ 2122628,
+ 2122631,
+ 2122640,
+ 2122654,
+ 2122705,
+ 2122716,
+ 2122761,
+ 2122768,
+ 2122786,
+ 2122836,
+ 2122843,
+ 2122861,
+ 2122875,
+ 2122942,
+ 2122943,
+ 2122981,
+ 2122999,
+ 2123003,
+ 2123012,
+ 2123030,
+ 2123033,
+ 2123079,
+ 2123111,
+ 2123137,
+ 2123141,
+ 2123202,
+ 2123248,
+ 2123250,
+ 2123308,
+ 2123340,
+ 2123355,
+ 2123356,
+ 2123361,
+ 2123371,
+ 4220535,
+ 2123428,
+ 2123464,
+ 2123500,
+ 2123525,
+ 2123539,
+ 2123571,
+ 2123592,
+ 2123596,
+ 2123638,
+ 2123643,
+ 2123696,
+ 2123698,
+ 2123769,
+ 2123735,
+ 2123737,
+ 2123760,
+ 2123820,
+ 2123824,
+ 2123825,
+ 2123867,
+ 2123890,
+ 2123893,
+ 2123898,
+ 2123908,
+ 2123941,
+ 2123954,
+ 2123984,
+ 2123990,
+ 2124008,
+ 2124013,
+ 2124016,
+ 2124017,
+ 2124028,
+ 2124049,
+ 2124051,
+ 2124085,
+ 2124091,
+ 2124119,
+ 2124131,
+ 2124146,
+ 2124159,
+ 2124160,
+ 2124198,
+ 2124205,
+ 2124215,
+ 2124246,
+ 2124247,
+ 2124289,
+ 2124303,
+ 2124309,
+ 2124328,
+ 2124340,
+ 2124350,
+ 2124357,
+ 2124368,
+ 2124369,
+ 2124374,
+ 2124379,
+ 2124419,
+ 2124425,
+ 2124433,
+ 2124445,
+ 2124446,
+ 2124447,
+ 2124508,
+ 2124519,
+ 2124524,
+ 2124574,
+ 2124580,
+ 2124597,
+ 2124614,
+ 2124630,
+ 2124640,
+ 2124674,
+ 2124734,
+ 2124769,
+ 2124785,
+ 2124816,
+ 2124851,
+ 2124853,
+ 4222010,
+ 2124889,
+ 2124918,
+ 2124923,
+ 2124933,
+ 2124949,
+ 2124956,
+ 2125008,
+ 2125012,
+ 2125014,
+ 2125024,
+ 2125035,
+ 2125036,
+ 2125038,
+ 2125066,
+ 2125070,
+ 2125073,
+ 2125102,
+ 2125143,
+ 2125150,
+ 2125157,
+ 2125186,
+ 2125247,
+ 2125252,
+ 2125258,
+ 2125270,
+ 2125289,
+ 2125346,
+ 2125393,
+ 2125511,
+ 2125514,
+ 2125518,
+ 2125565,
+ 2125594,
+ 2125610,
+ 2125615,
+ 2125619,
+ 2125658,
+ 2125662,
+ 2125666,
+ 2125693,
+ 2125707,
+ 2125709,
+ 2125714,
+ 2125716,
+ 2125722,
+ 2125735,
+ 2125736,
+ 2125750,
+ 2125786,
+ 2125790,
+ 4222969,
+ 2125881,
+ 2125884,
+ 4223050,
+ 2125908,
+ 2125917,
+ 2125918,
+ 2125924,
+ 2125932,
+ 2125950,
+ 2125953,
+ 2125973,
+ 2126007,
+ 2126035,
+ 2126036,
+ 2126040,
+ 2126044,
+ 2126087,
+ 2126112,
+ 2126129,
+ 2126154,
+ 2126162,
+ 2126176,
+ 2126201,
+ 2126226,
+ 4223411,
+ 2126283,
+ 2126291,
+ 2126294,
+ 2126336,
+ 2126365,
+ 2126379,
+ 2126392,
+ 2126401,
+ 2126419,
+ 2126421,
+ 2126422,
+ 2126428,
+ 2126477,
+ 2126509,
+ 2126516,
+ 2126535,
+ 2126587,
+ 2126596,
+ 2126597,
+ 2126632,
+ 2126641,
+ 2126659,
+ 2126700,
+ 2126716,
+ 2126723,
+ 2126725,
+ 2126726,
+ 2126741,
+ 2126750,
+ 2126751,
+ 2126752,
+ 2126758,
+ 2126763,
+ 2126773,
+ 2126775,
+ 2126780,
+ 2126799,
+ 2126809,
+ 2126825,
+ 2126836,
+ 2126845,
+ 2126852,
+ 2126858,
+ 2126874,
+ 2126875,
+ 2126884,
+ 2126888,
+ 2126892,
+ 2126895,
+ 2126896,
+ 2126897,
+ 2126905,
+ 2126916,
+ 2126919,
+ 2126923,
+ 2126925,
+ 2126929,
+ 2126935,
+ 2126950,
+ 2126955,
+ 2126961,
+ 2126976,
+ 2126981,
+ 2126982,
+ 2126983,
+ 2126992,
+ 2127000,
+ 2127004,
+ 2127008,
+ 2127011,
+ 2127016,
+ 2127019,
+ 2127029,
+ 2127039,
+ 2127048,
+ 2127066,
+ 2127070,
+ 2127182,
+ 2127225,
+ 2127233,
+ 2127248,
+ 2127250,
+ 2127251,
+ 2127284,
+ 2127332,
+ 2127353,
+ 2127360,
+ 2127370,
+ 2127381,
+ 2127382,
+ 2127385,
+ 2127390,
+ 2127405,
+ 2127413,
+ 2127427,
+ 2127435,
+ 2127461,
+ 2127469,
+ 2127471,
+ 2127473,
+ 2127476,
+ 2127524,
+ 2127525,
+ 2127557,
+ 2127564,
+ 2127596,
+ 2127612,
+ 2127668,
+ 2127670,
+ 2127708,
+ 2127711,
+ 2127712,
+ 2127730,
+ 2127741,
+ 2127765,
+ 2127786,
+ 2127846,
+ 2127856,
+ 2127860,
+ 2127878,
+ 2127906,
+ 2127917,
+ 2127918,
+ 2127920,
+ 2127925,
+ 2127976,
+ 2128030,
+ 2128072,
+ 2128076,
+ 2128078,
+ 2128100,
+ 2128096,
+ 2128097,
+ 2128114,
+ 2128119,
+ 2128123,
+ 2128177,
+ 4225332,
+ 2128187,
+ 2128189,
+ 2128197,
+ 2128219,
+ 2128220,
+ 2128267,
+ 2128278,
+ 2128280,
+ 2128312,
+ 2128315,
+ 2128330,
+ 2128346,
+ 2128387,
+ 2128393,
+ 2128401,
+ 2128414,
+ 2128429,
+ 2128441,
+ 2128453,
+ 2128460,
+ 2128477,
+ 4225632,
+ 2128493,
+ 2128504,
+ 2128544,
+ 2128547,
+ 2128563,
+ 2128571,
+ 2128572,
+ 2128582,
+ 2128647,
+ 2128660,
+ 2128679,
+ 2128689,
+ 2128711,
+ 2128718,
+ 2128736,
+ 2128745,
+ 2128749,
+ 2128754,
+ 2128785,
+ 2128815,
+ 2128855,
+ 2128857,
+ 2128907,
+ 2128911,
+ 2128928,
+ 2128934,
+ 2128945,
+ 2128950,
+ 2128977,
+ 2128985,
+ 2128999,
+ 2129006,
+ 2129008,
+ 2129084,
+ 2129087,
+ 2129096,
+ 2129097,
+ 2129111,
+ 2129113,
+ 2129117,
+ 2129131,
+ 2129159,
+ 2129160,
+ 2129161,
+ 2129171,
+ 2129181,
+ 2129187,
+ 2129217,
+ 2129235,
+ 2129241,
+ 2129245,
+ 2129274,
+ 2129286,
+ 2129291,
+ 2129292,
+ 2129356,
+ 2129387,
+ 2129393,
+ 2129401,
+ 2129416,
+ 2129425,
+ 2129429,
+ 2129440,
+ 2129479,
+ 2129506,
+ 2129518,
+ 2129523,
+ 2129549,
+ 2129553,
+ 2129560,
+ 2129732,
+ 2129743,
+ 2129746,
+ 2129747,
+ 2129761,
+ 2129809,
+ 2129855,
+ 2129870,
+ 2129887,
+ 2129893,
+ 2129900,
+ 2129902,
+ 2129903,
+ 2129914,
+ 2129934,
+ 2129937,
+ 2129940,
+ 2129956,
+ 2129958,
+ 2129978,
+ 2129980,
+ 2130016,
+ 2130033,
+ 2130037,
+ 2130078,
+ 2130086,
+ 2130091,
+ 2130135,
+ 2130136,
+ 2130198,
+ 2130200,
+ 2130234,
+ 2130250,
+ 2130252,
+ 2130305,
+ 2130308,
+ 2130356,
+ 2130383,
+ 2130425,
+ 2130435,
+ 2130465,
+ 2130482,
+ 2130484,
+ 2130502,
+ 2130507,
+ 2130511,
+ 2130574,
+ 2130606,
+ 2130615,
+ 2130622,
+ 2130630,
+ 2130686,
+ 2130755,
+ 2130769,
+ 2130773,
+ 2130822,
+ 2130829,
+ 2130834,
+ 2130840,
+ 2130857,
+ 2130879,
+ 2130880,
+ 2130922,
+ 2130959,
+ 2130961,
+ 2131018,
+ 2131062,
+ 2131112,
+ 2131119,
+ 2131136,
+ 2131138,
+ 2131184,
+ 2131197,
+ 2131212,
+ 2131252,
+ 2131294,
+ 2131343,
+ 2131383,
+ 2131406,
+ 2131373,
+ 2131474,
+ 2131497,
+ 2131538,
+ 2131555,
+ 2131564,
+ 2131567,
+ 2131578,
+ 2131597,
+ 2131601,
+ 2131608,
+ 2131623,
+ 2131624,
+ 2131706,
+ 2131709,
+ 2131723,
+ 2131731,
+ 2131737,
+ 2131742,
+ 2131752,
+ 2131774,
+ 2131825,
+ 2131848,
+ 2131865,
+ 2131884,
+ 2131885,
+ 2131893,
+ 2131926,
+ 2131947,
+ 2131949,
+ 2131969,
+ 4229123,
+ 2131974,
+ 2131979,
+ 2131988,
+ 2131996,
+ 2132054,
+ 2132063,
+ 2132068,
+ 2132120,
+ 2132138,
+ 2132157,
+ 2132158,
+ 2132170,
+ 2132178,
+ 2132187,
+ 2132208,
+ 2132209,
+ 2132230,
+ 2132248,
+ 2132249,
+ 2132250,
+ 2132263,
+ 2132272,
+ 2132286,
+ 2132347,
+ 2132436,
+ 2132438,
+ 2132453,
+ 2132465,
+ 2132487,
+ 2132495,
+ 2132501,
+ 2132514,
+ 2132558,
+ 2132607,
+ 2132724,
+ 2132767,
+ 2132791,
+ 2132803,
+ 2132804,
+ 2132820,
+ 2132892,
+ 2132894,
+ 2133063,
+ 2133076,
+ 2133107,
+ 2133156,
+ 2133209,
+ 2133217,
+ 2133240,
+ 2133246,
+ 2133275,
+ 2133353,
+ 2133356,
+ 2133380,
+ 2133389,
+ 2133397,
+ 2133414,
+ 2133446,
+ 2133454,
+ 2133476,
+ 2133484,
+ 2133536,
+ 2133579,
+ 2133612,
+ 2133616,
+ 2133626,
+ 2133650,
+ 2133678,
+ 2133683,
+ 2133713,
+ 4230868,
+ 2133753,
+ 2133783,
+ 2133814,
+ 2133926,
+ 2133941,
+ 2133942,
+ 4231110,
+ 2133984,
+ 2133988,
+ 2134006,
+ 2134018,
+ 2134060,
+ 2134084,
+ 2134152,
+ 2134165,
+ 2134169,
+ 2134171,
+ 2134178,
+ 2134196,
+ 2134231,
+ 2134237,
+ 2134260,
+ 2134295,
+ 2134300,
+ 2134321,
+ 2134330,
+ 2134333,
+ 2134344,
+ 2134363,
+ 2134369,
+ 2134372,
+ 2134414,
+ 2134430,
+ 2134440,
+ 2134445,
+ 2134446,
+ 2134450,
+ 2134460,
+ 2134512,
+ 2134519,
+ 2134523,
+ 2134535,
+ 2134568,
+ 2134579,
+ 2134584,
+ 2134595,
+ 2134599,
+ 2134607,
+ 2134624,
+ 2134722,
+ 2134731,
+ 2134732,
+ 2134751,
+ 2134797,
+ 2134805,
+ 2134815,
+ 2134823,
+ 2134855,
+ 2134866,
+ 4232037,
+ 2134890,
+ 2134893,
+ 2134939,
+ 2134970,
+ 2134953,
+ 2134977,
+ 2134986,
+ 2135010,
+ 2135034,
+ 2135037,
+ 2135055,
+ 2135092,
+ 2135103,
+ 2135125,
+ 2135147,
+ 2135154,
+ 2135416,
+ 2135462,
+ 2135465,
+ 4232619,
+ 2135476,
+ 2135485,
+ 2135514,
+ 2135581,
+ 2135617,
+ 2135640,
+ 2135684,
+ 2135716,
+ 2135721,
+ 2135762,
+ 2121138,
+ 2135774,
+ 2135785,
+ 2135793,
+ 2135810,
+ 2135817,
+ 2135898,
+ 2135907,
+ 2135918,
+ 2135923,
+ 2135962,
+ 2135970,
+ 2135989,
+ 2135990,
+ 2136025,
+ 2136030,
+ 2136052,
+ 2136074,
+ 2136078,
+ 2136094,
+ 2136099,
+ 2136107,
+ 2136126,
+ 2136146,
+ 2136147,
+ 2136153,
+ 2136172,
+ 2136248,
+ 2136250,
+ 2136255,
+ 2136264,
+ 2136293,
+ 2136370,
+ 2136371,
+ 2136384,
+ 2136397,
+ 2136412,
+ 2136415,
+ 2136497,
+ 2136505,
+ 2136506,
+ 2136521,
+ 2136578,
+ 2136598,
+ 2136612,
+ 2136615,
+ 2136621,
+ 2136622,
+ 2136630,
+ 2136632,
+ 2136650,
+ 2136662,
+ 2136757,
+ 2136758,
+ 2136825,
+ 2136835,
+ 2136864,
+ 2136883,
+ 2136884,
+ 2136947,
+ 2136953,
+ 2136999,
+ 2137025,
+ 2137031,
+ 2137047,
+ 2137063,
+ 2137067,
+ 2137079,
+ 2137082,
+ 2137085,
+ 2137099,
+ 2137127,
+ 2137130,
+ 2137142,
+ 2137153,
+ 2137171,
+ 2137187,
+ 2137200,
+ 2137207,
+ 2137346,
+ 2137410,
+ 2137415,
+ 2137443,
+ 2137449,
+ 2137468,
+ 2137470,
+ 2137485,
+ 2137521,
+ 2137539,
+ 2137543,
+ 2137558,
+ 2137567,
+ 2137579,
+ 2137588,
+ 2137621,
+ 2137629,
+ 2137764,
+ 2137768,
+ 2137772,
+ 2137831,
+ 2137838,
+ 2137872,
+ 2137874,
+ 2137879,
+ 2137881,
+ 2137903,
+ 2137911,
+ 2137913,
+ 2137921,
+ 2137925,
+ 2137943,
+ 2137960,
+ 2137969,
+ 2137973,
+ 2138000,
+ 2138004,
+ 2138018,
+ 4214320,
+ 2110469,
+ 4214624,
+ 2119200,
+ 2121419,
+ 4218704,
+ 4219044,
+ 2242106,
+ 4221732,
+ 2125817,
+ 2125542,
+ 2126259,
+ 4223531,
+ 4225734,
+ 4226913,
+ 4227185,
+ 4227230,
+ 4231094,
+ 4231676,
+ 4218290,
+ 4233182,
+ 2117587,
+ 2117849,
+ 2117872,
+ 2118083,
+ 2119286,
+ 2124372,
+ 2125057,
+ 2125264,
+ 2125378,
+ 2125529,
+ 2126820,
+ 2126881,
+ 2127212,
+ 2127953,
+ 2131957,
+ 2241534,
+ 2126760,
+ 2112243,
+ 2110683,
+ 2114572,
+ 2113162,
+ 4339140,
+ 2138045,
+ 2116584,
+ 2138044,
+ 2113242,
+ 2112290,
+ 2138046,
+ 2114938,
+ 2113683,
+ 4365885,
+ 2115173,
+ 2113795,
+ 2114195,
+ 2115246,
+ 2110600,
+ 2237961,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ 2117448,
+ 2117471,
+ 2117482,
+ 2117484,
+ 2117646,
+ 2117656,
+ 2117697,
+ 2117874,
+ 2117840,
+ 2117894,
+ 2117891,
+ 2117941,
+ 2117973,
+ 2117975,
+ 2110645,
+ 2118090,
+ 2118114,
+ 2118231,
+ 2118348,
+ 2118358,
+ 2118395,
+ 2118428,
+ 2118499,
+ 2118557,
+ 2118674,
+ 2118783,
+ 2118792,
+ 2118992,
+ 2119041,
+ 2119085,
+ 2119118,
+ 2119227,
+ 2119326,
+ 2119337,
+ 2119347,
+ 2119543,
+ 2119548,
+ 2233115,
+ 2119631,
+ 2119652,
+ 2119780,
+ 2119817,
+ 2233454,
+ 2119890,
+ 2119904,
+ 2131521,
+ 2120075,
+ 2120082,
+ 2120131,
+ 2120211,
+ 2120295,
+ 2120311,
+ 2120324,
+ 2120388,
+ 2234557,
+ 2120573,
+ 2120595,
+ 2120722,
+ 2120814,
+ 2234036,
+ 2120826,
+ 2120847,
+ 2120863,
+ 2120867,
+ 2120874,
+ 2120912,
+ 2235956,
+ 2120973,
+ 2121031,
+ 2121089,
+ 2121124,
+ 2121127,
+ 2121163,
+ 2121310,
+ 2121465,
+ 2121472,
+ 2121474,
+ 2121507,
+ 2121533,
+ 2121556,
+ 2121597,
+ 2121741,
+ 2121748,
+ 2121752,
+ 2121781,
+ 2121799,
+ 2121885,
+ 2121940,
+ 2121949,
+ 2122027,
+ 2122172,
+ 2122169,
+ 2122274,
+ 2122330,
+ 2122351,
+ 2122454,
+ 2122620,
+ 2122725,
+ 2122873,
+ 2122948,
+ 2122960,
+ 2123049,
+ 2123165,
+ 2123322,
+ 2123298,
+ 2123307,
+ 2123312,
+ 2123315,
+ 2123336,
+ 2240964,
+ 2123383,
+ 2123384,
+ 2123405,
+ 2123451,
+ 2123483,
+ 2123496,
+ 2123591,
+ 2123649,
+ 2123667,
+ 2123672,
+ 2123675,
+ 2123772,
+ 2123805,
+ 2123939,
+ 2124042,
+ 2124105,
+ 2241988,
+ 2124098,
+ 2124132,
+ 2124197,
+ 2124239,
+ 2112438,
+ 2112451,
+ 2124265,
+ 2124277,
+ 2242367,
+ 2124347,
+ 2242403,
+ 2124436,
+ 2124453,
+ 2112527,
+ 2124571,
+ 2124588,
+ 2124647,
+ 2124713,
+ 2124717,
+ 2124759,
+ 2124799,
+ 2124805,
+ 2124916,
+ 2124952,
+ 2125051,
+ 2124998,
+ 2125105,
+ 2125113,
+ 2125119,
+ 2125144,
+ 2125204,
+ 2125226,
+ 2125275,
+ 2125277,
+ 2125380,
+ 2125406,
+ 2125489,
+ 2125505,
+ 2125584,
+ 2125657,
+ 2125665,
+ 2125694,
+ 2125708,
+ 2125728,
+ 2125756,
+ 2125767,
+ 2125770,
+ 2125808,
+ 2125902,
+ 2125941,
+ 2125988,
+ 2126052,
+ 2126123,
+ 2126110,
+ 2126126,
+ 2126161,
+ 2126184,
+ 2126213,
+ 2126215,
+ 2126266,
+ 2126276,
+ 2126357,
+ 2113087,
+ 2126491,
+ 2246641,
+ 2126631,
+ 2126672,
+ 2126694,
+ 2126754,
+ 2126891,
+ 2126918,
+ 2126946,
+ 2126957,
+ 2127014,
+ 2127017,
+ 2127049,
+ 2127103,
+ 2127127,
+ 2113394,
+ 2127310,
+ 2127362,
+ 2127368,
+ 2127460,
+ 2127489,
+ 2127517,
+ 2127530,
+ 2127542,
+ 2127566,
+ 2127572,
+ 2127590,
+ 2127601,
+ 2127626,
+ 2127641,
+ 2127693,
+ 2127694,
+ 2127738,
+ 2127744,
+ 2127764,
+ 2127840,
+ 2249870,
+ 2127939,
+ 2127982,
+ 2128048,
+ 2249998,
+ 2128045,
+ 2128128,
+ 2128156,
+ 2128174,
+ 2128180,
+ 2128198,
+ 2128249,
+ 2128328,
+ 2250609,
+ 2128340,
+ 2128350,
+ 2128363,
+ 2128365,
+ 2128517,
+ 2251204,
+ 2128590,
+ 2128637,
+ 2128658,
+ 2128685,
+ 2128699,
+ 2128751,
+ 2128897,
+ 2128947,
+ 2252193,
+ 2129005,
+ 2129017,
+ 2129039,
+ 2129044,
+ 2129056,
+ 2129109,
+ 2129201,
+ 2129244,
+ 2129283,
+ 2129318,
+ 2129346,
+ 2129448,
+ 2129815,
+ 2129883,
+ 2129973,
+ 2129975,
+ 2130122,
+ 2130144,
+ 2130163,
+ 2130272,
+ 2130279,
+ 2130280,
+ 2130285,
+ 2130363,
+ 2130378,
+ 2130391,
+ 2114651,
+ 2130528,
+ 2130548,
+ 2255615,
+ 2130593,
+ 2130595,
+ 2130596,
+ 2130601,
+ 2130623,
+ 2130645,
+ 2130685,
+ 2130688,
+ 2130722,
+ 2130733,
+ 2130746,
+ 2130759,
+ 2130813,
+ 2130855,
+ 2130895,
+ 2130897,
+ 2130913,
+ 2130945,
+ 2130950,
+ 2131039,
+ 2131056,
+ 2131059,
+ 2131077,
+ 2131102,
+ 2131130,
+ 2256448,
+ 2131250,
+ 2131230,
+ 2131247,
+ 2131300,
+ 2131322,
+ 2131340,
+ 2131362,
+ 2131403,
+ 2131437,
+ 2131455,
+ 2131460,
+ 2131461,
+ 2131472,
+ 2257140,
+ 2131480,
+ 2131512,
+ 2131543,
+ 2131554,
+ 2114973,
+ 2131573,
+ 2131640,
+ 2131708,
+ 2131847,
+ 2115050,
+ 2131978,
+ 2131984,
+ 2132174,
+ 2258564,
+ 2132274,
+ 2132281,
+ 2132288,
+ 2132372,
+ 2132470,
+ 2132551,
+ 2132573,
+ 2132577,
+ 2132597,
+ 2132688,
+ 2132806,
+ 2132825,
+ 2132841,
+ 2132893,
+ 2133065,
+ 2133096,
+ 2133423,
+ 2133457,
+ 2133463,
+ 2133539,
+ 2133565,
+ 2133627,
+ 2261623,
+ 2115652,
+ 2133754,
+ 2133790,
+ 2133805,
+ 2133844,
+ 2261965,
+ 2133992,
+ 2133998,
+ 2134024,
+ 2134061,
+ 2134167,
+ 2134195,
+ 2134206,
+ 2134212,
+ 2134213,
+ 2134215,
+ 2134255,
+ 2134292,
+ 2134294,
+ 2134306,
+ 2134307,
+ 2134319,
+ 2134324,
+ 2134403,
+ 2134513,
+ 2134857,
+ 2134884,
+ 2134885,
+ 2134947,
+ 2135007,
+ 2135044,
+ 2135091,
+ 2135114,
+ 2135139,
+ 2135153,
+ 2135438,
+ 2135455,
+ 2135468,
+ 2135478,
+ 2135499,
+ 2135504,
+ 2135507,
+ 2116016,
+ 2135518,
+ 2135717,
+ 2135791,
+ 2135886,
+ 2135957,
+ 2135982,
+ 2135994,
+ 2136001,
+ 2136009,
+ 2136027,
+ 2136150,
+ 2136295,
+ 2136408,
+ 2136579,
+ 2136769,
+ 2136771,
+ 2136782,
+ 2136790,
+ 2136834,
+ 2136840,
+ 2116631,
+ 2136877,
+ 2136926,
+ 2136934,
+ 2136964,
+ 2136970,
+ 2136990,
+ 2137038,
+ 2137061,
+ 2137080,
+ 2137123,
+ 2137167,
+ 2137168,
+ 2137189,
+ 2137373,
+ 2137374,
+ 2137411,
+ 2137426,
+ 2137482,
+ 2137494,
+ 2137536,
+ 2137516,
+ 2137532,
+ 2269584,
+ 2137575,
+ 2137607,
+ 2137758,
+ 2137775,
+ 2138007,
+ 2228361,
+ 2117122,
+ 2117135,
+ 2117138,
+ 2117161,
+ 2117166,
+ 2117191,
+ 2228386,
+ 2117201,
+ 2110470,
+ 2228388,
+ 2117225,
+ 2117277,
+ 2110508,
+ 2117308,
+ 2117315,
+ 2117320,
+ 2117355,
+ 2117338,
+ 2117361,
+ 2117365,
+ 2117398,
+ 2117476,
+ 2117431,
+ 2117438,
+ 2117464,
+ 2228755,
+ 2117495,
+ 2117496,
+ 2117506,
+ 2117509,
+ 2117606,
+ 2117554,
+ 2117573,
+ 2117579,
+ 2117586,
+ 2110570,
+ 2117618,
+ 2117651,
+ 2117660,
+ 2117710,
+ 2117715,
+ 2117731,
+ 2117795,
+ 2117768,
+ 2117778,
+ 2117779,
+ 2117781,
+ 2117802,
+ 2229035,
+ 2117809,
+ 2117818,
+ 2117819,
+ 2117828,
+ 2117831,
+ 2117875,
+ 2229121,
+ 2117838,
+ 2229105,
+ 2117844,
+ 2117857,
+ 2110610,
+ 2229241,
+ 2117911,
+ 2229322,
+ 2117984,
+ 2229513,
+ 2118003,
+ 2118019,
+ 2118027,
+ 2110652,
+ 2118040,
+ 2118051,
+ 2118061,
+ 2110663,
+ 2229718,
+ 2118131,
+ 2118162,
+ 2118166,
+ 2230095,
+ 2118229,
+ 2118236,
+ 2118252,
+ 2118263,
+ 2118276,
+ 2118274,
+ 2230279,
+ 2118296,
+ 2230330,
+ 2118308,
+ 2118330,
+ 2118331,
+ 2118346,
+ 2118353,
+ 2230457,
+ 2118391,
+ 2118453,
+ 2118466,
+ 2230652,
+ 2230685,
+ 2118503,
+ 2118522,
+ 2118564,
+ 2118580,
+ 2230995,
+ 2118583,
+ 2118592,
+ 2231069,
+ 2110813,
+ 2110814,
+ 2118613,
+ 2110819,
+ 2118644,
+ 2118692,
+ 2118696,
+ 2110830,
+ 2118723,
+ 2118754,
+ 2118764,
+ 2118805,
+ 2118816,
+ 2118822,
+ 2118830,
+ 2118839,
+ 2118842,
+ 2118851,
+ 2231621,
+ 2118892,
+ 2118895,
+ 2118897,
+ 2118899,
+ 2118912,
+ 2118913,
+ 2118921,
+ 2118972,
+ 2118977,
+ 2110886,
+ 2118983,
+ 2110888,
+ 2119012,
+ 2231777,
+ 2119037,
+ 2119042,
+ 2119057,
+ 2110917,
+ 2119122,
+ 2231957,
+ 2231917,
+ 2119103,
+ 2119113,
+ 2119116,
+ 2119121,
+ 2119133,
+ 2110938,
+ 2119138,
+ 2231908,
+ 2119145,
+ 2119208,
+ 2232159,
+ 2119175,
+ 2119184,
+ 2119216,
+ 2110964,
+ 2119229,
+ 2119232,
+ 2119239,
+ 2119262,
+ 2119264,
+ 2119277,
+ 2110981,
+ 2119304,
+ 2119308,
+ 2119325,
+ 2119336,
+ 2119346,
+ 2119365,
+ 2119373,
+ 2119391,
+ 2119400,
+ 2119414,
+ 2119415,
+ 2232833,
+ 2232917,
+ 2119465,
+ 2232955,
+ 2119493,
+ 2119494,
+ 2119501,
+ 2232948,
+ 2119528,
+ 2119535,
+ 2119539,
+ 2119540,
+ 2119541,
+ 2119547,
+ 2233060,
+ 2233047,
+ 2119578,
+ 2119581,
+ 2119582,
+ 2119592,
+ 2119639,
+ 2233085,
+ 2119628,
+ 2233142,
+ 2233156,
+ 2119646,
+ 2119664,
+ 2111050,
+ 2119672,
+ 2119675,
+ 2119677,
+ 2119684,
+ 2119710,
+ 2119719,
+ 2119737,
+ 2233284,
+ 2119753,
+ 2119756,
+ 2119783,
+ 2119818,
+ 2119819,
+ 2119821,
+ 2119823,
+ 2119824,
+ 2119828,
+ 2119837,
+ 2119850,
+ 2119857,
+ 2233453,
+ 2119875,
+ 2119885,
+ 2119906,
+ 2119923,
+ 2119924,
+ 2119941,
+ 2119942,
+ 2119949,
+ 2119956,
+ 2233815,
+ 2111121,
+ 2119997,
+ 2111129,
+ 2120006,
+ 2111126,
+ 2255913,
+ 2120031,
+ 2233927,
+ 2120053,
+ 2120054,
+ 2120060,
+ 2120095,
+ 2120110,
+ 2120124,
+ 2120136,
+ 2120141,
+ 2120158,
+ 2120167,
+ 2120174,
+ 2234118,
+ 2234178,
+ 2111183,
+ 2120205,
+ 2120215,
+ 2120231,
+ 2120237,
+ 2120293,
+ 2120314,
+ 2120331,
+ 2120348,
+ 2120351,
+ 2120352,
+ 2120354,
+ 2120369,
+ 2120373,
+ 2120378,
+ 2120383,
+ 2120410,
+ 2120412,
+ 2120421,
+ 2120432,
+ 2120430,
+ 2120437,
+ 2120456,
+ 2120471,
+ 2120500,
+ 2120524,
+ 2120530,
+ 2120552,
+ 2120559,
+ 2120577,
+ 2120580,
+ 2234819,
+ 2120598,
+ 2120620,
+ 2111329,
+ 2111330,
+ 2120654,
+ 2120662,
+ 2111340,
+ 2111339,
+ 2120689,
+ 2120701,
+ 2111349,
+ 2120707,
+ 2120745,
+ 2235478,
+ 2120799,
+ 2120807,
+ 2120808,
+ 2120816,
+ 2235693,
+ 2235717,
+ 2235768,
+ 2235746,
+ 2120840,
+ 2120842,
+ 2111425,
+ 2235809,
+ 2235804,
+ 2120864,
+ 2120866,
+ 2120871,
+ 2235794,
+ 2120877,
+ 2120885,
+ 2235831,
+ 2120905,
+ 2235872,
+ 2235955,
+ 2120966,
+ 2120976,
+ 2121003,
+ 2120989,
+ 2120992,
+ 2121009,
+ 2121017,
+ 2111464,
+ 2121057,
+ 2121066,
+ 2111476,
+ 2121072,
+ 2236190,
+ 2111485,
+ 2121096,
+ 2111488,
+ 2121111,
+ 2121136,
+ 2121140,
+ 2236278,
+ 2121169,
+ 2121175,
+ 2236410,
+ 2121188,
+ 2121193,
+ 2111535,
+ 2111542,
+ 2111552,
+ 2121247,
+ 2121278,
+ 2121289,
+ 2111580,
+ 2121302,
+ 2111585,
+ 2121325,
+ 2121326,
+ 2236795,
+ 2121381,
+ 2121388,
+ 2121401,
+ 2121414,
+ 2121433,
+ 2237214,
+ 2121469,
+ 2121480,
+ 2237357,
+ 2121502,
+ 2121543,
+ 2121571,
+ 2121586,
+ 2121598,
+ 2121615,
+ 2121634,
+ 2121671,
+ 2121675,
+ 2121682,
+ 2121683,
+ 2121684,
+ 2121698,
+ 2121710,
+ 2121711,
+ 2121715,
+ 2111767,
+ 2121762,
+ 2121764,
+ 2111770,
+ 2121804,
+ 2121877,
+ 2121896,
+ 2238195,
+ 2121905,
+ 2121918,
+ 2121928,
+ 2121945,
+ 2121966,
+ 2121973,
+ 2122000,
+ 2122009,
+ 2122014,
+ 2122042,
+ 2111855,
+ 2122049,
+ 2122054,
+ 2122080,
+ 2238555,
+ 2122130,
+ 2122131,
+ 2122135,
+ 2122149,
+ 2122157,
+ 2238635,
+ 2122197,
+ 2122205,
+ 2122229,
+ 2238863,
+ 2122275,
+ 2122322,
+ 2122337,
+ 2122340,
+ 2122363,
+ 2122349,
+ 2122355,
+ 2122393,
+ 2122453,
+ 2239160,
+ 2122493,
+ 2122499,
+ 2122512,
+ 2239311,
+ 2239312,
+ 2122546,
+ 2122549,
+ 2122555,
+ 2122556,
+ 2122561,
+ 2122564,
+ 2122574,
+ 2239302,
+ 2122585,
+ 2239517,
+ 2239398,
+ 2122604,
+ 2122649,
+ 2239524,
+ 2122644,
+ 2122685,
+ 2122708,
+ 2122709,
+ 2122720,
+ 2122731,
+ 2122732,
+ 2122738,
+ 2122782,
+ 2122789,
+ 2122793,
+ 2122799,
+ 2122842,
+ 2122845,
+ 2122867,
+ 2122877,
+ 2122887,
+ 2122897,
+ 2122911,
+ 2122955,
+ 2122956,
+ 2122965,
+ 2122967,
+ 2239969,
+ 2122980,
+ 2123007,
+ 2112110,
+ 2123023,
+ 2123028,
+ 2112115,
+ 2123038,
+ 2123058,
+ 2123076,
+ 2123092,
+ 2123115,
+ 2123130,
+ 2123140,
+ 2123146,
+ 2123186,
+ 2123189,
+ 2123192,
+ 2123199,
+ 2123209,
+ 2123220,
+ 2112214,
+ 2123257,
+ 2123260,
+ 2123268,
+ 2123272,
+ 2123297,
+ 2123306,
+ 2123333,
+ 2123345,
+ 2123342,
+ 2112234,
+ 2240963,
+ 2241013,
+ 2240950,
+ 2123370,
+ 2123372,
+ 2123373,
+ 2123387,
+ 2123392,
+ 2123408,
+ 2123410,
+ 2112270,
+ 2123437,
+ 2123441,
+ 2123445,
+ 2112282,
+ 2112284,
+ 2112215,
+ 2123521,
+ 2123538,
+ 2241394,
+ 2123545,
+ 2241491,
+ 2241490,
+ 2123597,
+ 2123604,
+ 2123613,
+ 2241488,
+ 2241508,
+ 2241493,
+ 2123636,
+ 2241498,
+ 2123666,
+ 2241503,
+ 2130787,
+ 2123792,
+ 2123715,
+ 2123720,
+ 2123730,
+ 2123739,
+ 2123767,
+ 2241610,
+ 2241617,
+ 2241611,
+ 2123800,
+ 2123807,
+ 2123821,
+ 2241637,
+ 2123827,
+ 2123835,
+ 2123838,
+ 2123845,
+ 2123849,
+ 2123852,
+ 2123861,
+ 2123863,
+ 2112375,
+ 2123883,
+ 2123886,
+ 2123900,
+ 2123906,
+ 2123920,
+ 2123926,
+ 2112365,
+ 2123928,
+ 2123929,
+ 2123930,
+ 2123932,
+ 2123946,
+ 2123947,
+ 2123956,
+ 2123963,
+ 2124027,
+ 2241764,
+ 2241882,
+ 2123971,
+ 2123973,
+ 2123980,
+ 2123993,
+ 2124004,
+ 2124005,
+ 2124012,
+ 2124023,
+ 2124035,
+ 2124039,
+ 2112391,
+ 2241940,
+ 2112397,
+ 2124102,
+ 2124137,
+ 2124140,
+ 2124154,
+ 2124178,
+ 2112420,
+ 2124182,
+ 2124208,
+ 2124218,
+ 2124220,
+ 2124224,
+ 2124241,
+ 2242105,
+ 2242119,
+ 2242104,
+ 2124259,
+ 2124270,
+ 2124271,
+ 2124275,
+ 2112461,
+ 2124276,
+ 2124286,
+ 2124305,
+ 2124314,
+ 2124317,
+ 2242332,
+ 2124338,
+ 2124339,
+ 2124351,
+ 2124361,
+ 2124410,
+ 2124366,
+ 2124370,
+ 2124388,
+ 2242316,
+ 2124427,
+ 2112496,
+ 2124449,
+ 2242404,
+ 2124459,
+ 2124477,
+ 2124486,
+ 2124500,
+ 2124496,
+ 2124509,
+ 2242559,
+ 2242535,
+ 2124529,
+ 2124530,
+ 2124531,
+ 2124541,
+ 2242596,
+ 2124555,
+ 2124559,
+ 2124560,
+ 2124561,
+ 2242621,
+ 2124567,
+ 2112550,
+ 2124591,
+ 2124618,
+ 2124632,
+ 2124652,
+ 2124661,
+ 2124666,
+ 2124673,
+ 2124699,
+ 2124718,
+ 2243224,
+ 2124733,
+ 2124743,
+ 2124744,
+ 2124745,
+ 2124762,
+ 2124774,
+ 2124775,
+ 2124782,
+ 2124802,
+ 2124810,
+ 2124814,
+ 2124854,
+ 2243711,
+ 2124877,
+ 2124891,
+ 2124909,
+ 2124932,
+ 2124937,
+ 2112707,
+ 2124948,
+ 2124951,
+ 2124973,
+ 2124994,
+ 2112722,
+ 2125020,
+ 2125033,
+ 2125037,
+ 2243840,
+ 2125056,
+ 2125092,
+ 2125094,
+ 2125095,
+ 2124903,
+ 2125103,
+ 2125116,
+ 2125147,
+ 2125152,
+ 2125168,
+ 2125184,
+ 2125185,
+ 2125194,
+ 2125197,
+ 2125201,
+ 2125208,
+ 2243904,
+ 2244090,
+ 2244089,
+ 2244051,
+ 2125227,
+ 2125230,
+ 2125236,
+ 2125250,
+ 2125108,
+ 2125256,
+ 2125262,
+ 2125279,
+ 2125302,
+ 2125366,
+ 2125342,
+ 2112785,
+ 2125362,
+ 2125384,
+ 2125385,
+ 2125387,
+ 2125388,
+ 2125391,
+ 2125395,
+ 2125396,
+ 2125399,
+ 2125411,
+ 2112798,
+ 2125459,
+ 2125479,
+ 2125492,
+ 2125507,
+ 2125621,
+ 2125547,
+ 2125561,
+ 2125563,
+ 2125578,
+ 2125580,
+ 2125592,
+ 2125605,
+ 2125622,
+ 2125628,
+ 2244478,
+ 2125650,
+ 2125655,
+ 2125664,
+ 2125672,
+ 2125712,
+ 2125718,
+ 2125758,
+ 2125727,
+ 2125733,
+ 2125743,
+ 2112868,
+ 2125768,
+ 2125769,
+ 2125801,
+ 2244758,
+ 2125820,
+ 2125824,
+ 2125834,
+ 2125859,
+ 2244867,
+ 2125882,
+ 2125891,
+ 2125895,
+ 2125899,
+ 2112922,
+ 2125925,
+ 2125929,
+ 2125934,
+ 2125942,
+ 2125958,
+ 2125975,
+ 2245062,
+ 2125983,
+ 2126001,
+ 2245118,
+ 2126060,
+ 2126026,
+ 2126033,
+ 2126083,
+ 2126086,
+ 2126088,
+ 2126092,
+ 2112960,
+ 2126127,
+ 2126160,
+ 2126163,
+ 2126174,
+ 2112980,
+ 2126230,
+ 2126208,
+ 2126235,
+ 2126240,
+ 2126242,
+ 2126254,
+ 2126255,
+ 2245564,
+ 2126297,
+ 2126300,
+ 2126343,
+ 2113029,
+ 2126388,
+ 2126393,
+ 2126402,
+ 2126423,
+ 2126435,
+ 2246185,
+ 2126446,
+ 2126447,
+ 2126456,
+ 2126463,
+ 2126478,
+ 2246309,
+ 2126510,
+ 2126512,
+ 2126529,
+ 2113120,
+ 2126540,
+ 2113126,
+ 2113128,
+ 2126579,
+ 2126586,
+ 2126599,
+ 2126610,
+ 2126616,
+ 2126617,
+ 2113155,
+ 2126649,
+ 2126636,
+ 2126643,
+ 2126653,
+ 2126674,
+ 2113172,
+ 2126699,
+ 2246806,
+ 2126702,
+ 2126703,
+ 2126705,
+ 2126721,
+ 2126730,
+ 2126740,
+ 2126744,
+ 2126748,
+ 2126757,
+ 2126777,
+ 2126783,
+ 2126789,
+ 2126795,
+ 2126817,
+ 2126823,
+ 2126841,
+ 2126867,
+ 2126842,
+ 2126849,
+ 2126931,
+ 2126912,
+ 2126915,
+ 2126930,
+ 2126941,
+ 2126977,
+ 2126984,
+ 2247245,
+ 2126994,
+ 2126999,
+ 2127001,
+ 2127009,
+ 2127013,
+ 2127018,
+ 2127033,
+ 2127035,
+ 2127034,
+ 2127062,
+ 2127064,
+ 2127083,
+ 2247510,
+ 2127098,
+ 2247535,
+ 2127136,
+ 2127140,
+ 2127146,
+ 2113367,
+ 2247702,
+ 2127165,
+ 2127166,
+ 2127168,
+ 2127176,
+ 2127184,
+ 2127186,
+ 2127218,
+ 2127217,
+ 2127226,
+ 2127229,
+ 2127230,
+ 2127244,
+ 2113397,
+ 2127266,
+ 2113399,
+ 2127280,
+ 2127287,
+ 2127295,
+ 2127296,
+ 2127302,
+ 2127311,
+ 2127315,
+ 2127325,
+ 2127327,
+ 2127328,
+ 2127335,
+ 2127342,
+ 2127345,
+ 2127363,
+ 2127384,
+ 2127367,
+ 2127375,
+ 2113454,
+ 2248206,
+ 2127379,
+ 2127387,
+ 2127388,
+ 2248247,
+ 2127397,
+ 2127400,
+ 2127420,
+ 2127411,
+ 2248298,
+ 2113481,
+ 2127425,
+ 2248331,
+ 2127433,
+ 2127445,
+ 2113495,
+ 2127470,
+ 2127509,
+ 2127521,
+ 2127520,
+ 2127527,
+ 2127528,
+ 2127535,
+ 2248778,
+ 2127561,
+ 2248789,
+ 2127592,
+ 2248994,
+ 2127639,
+ 2127642,
+ 2127661,
+ 2127669,
+ 2249129,
+ 2113593,
+ 2249189,
+ 2249165,
+ 2127704,
+ 2249246,
+ 2127740,
+ 2249292,
+ 2113624,
+ 2127770,
+ 2127775,
+ 2127778,
+ 2127780,
+ 2127838,
+ 2127839,
+ 2127844,
+ 2127850,
+ 2127852,
+ 2127867,
+ 2249774,
+ 2127877,
+ 2127881,
+ 2127885,
+ 2127897,
+ 2127916,
+ 2127943,
+ 2127978,
+ 2249945,
+ 2128010,
+ 2128020,
+ 2128036,
+ 2128029,
+ 2128031,
+ 2128059,
+ 2128085,
+ 2128102,
+ 2128121,
+ 2128122,
+ 2128126,
+ 2250151,
+ 2128144,
+ 2128155,
+ 2128165,
+ 2128202,
+ 2128216,
+ 2113797,
+ 2128231,
+ 2128242,
+ 2128277,
+ 2128289,
+ 2128297,
+ 2128308,
+ 2128322,
+ 2128327,
+ 2128332,
+ 2128333,
+ 2128342,
+ 2113864,
+ 2250665,
+ 2250676,
+ 2113871,
+ 2128394,
+ 2128405,
+ 2128411,
+ 2113891,
+ 2128440,
+ 2128455,
+ 2128470,
+ 2128473,
+ 2128476,
+ 2128479,
+ 2128487,
+ 2128490,
+ 2128501,
+ 2128514,
+ 2128522,
+ 2128528,
+ 2128556,
+ 2251220,
+ 2113972,
+ 2128569,
+ 2128574,
+ 2113983,
+ 2128588,
+ 2128616,
+ 2128628,
+ 2251492,
+ 2251491,
+ 2251505,
+ 2128701,
+ 2128682,
+ 2128686,
+ 2128687,
+ 2114022,
+ 2114035,
+ 2128767,
+ 2128705,
+ 2114030,
+ 2128725,
+ 2128761,
+ 2128740,
+ 2128742,
+ 2128755,
+ 2251698,
+ 2114055,
+ 2128784,
+ 2128795,
+ 2114062,
+ 2128821,
+ 2128828,
+ 2128837,
+ 2128842,
+ 2251851,
+ 2251876,
+ 2128852,
+ 2128854,
+ 2128858,
+ 2128874,
+ 2128880,
+ 2128899,
+ 2128910,
+ 2128965,
+ 2128970,
+ 2128983,
+ 2128990,
+ 2128993,
+ 2129001,
+ 2129007,
+ 2252334,
+ 2252374,
+ 2252389,
+ 2129062,
+ 2252386,
+ 2129078,
+ 2129079,
+ 2252504,
+ 2129092,
+ 2252482,
+ 2129101,
+ 2252520,
+ 2252579,
+ 2129126,
+ 2252636,
+ 2129141,
+ 2129155,
+ 2114246,
+ 2129170,
+ 2129182,
+ 2252768,
+ 2252756,
+ 2129213,
+ 2129214,
+ 2129216,
+ 2129223,
+ 2252812,
+ 2252795,
+ 2114262,
+ 2129242,
+ 2129258,
+ 2129264,
+ 2114269,
+ 2129279,
+ 2252823,
+ 2129288,
+ 2129303,
+ 2252896,
+ 2129309,
+ 2129319,
+ 2129322,
+ 2129334,
+ 2129344,
+ 2129367,
+ 2129369,
+ 2129382,
+ 2114306,
+ 2253037,
+ 4226569,
+ 2129424,
+ 2129431,
+ 2129437,
+ 2129447,
+ 2129452,
+ 2129477,
+ 2129525,
+ 2129534,
+ 2129542,
+ 2129543,
+ 2114347,
+ 2129562,
+ 2114371,
+ 2129724,
+ 2129723,
+ 2129726,
+ 2129731,
+ 2110657,
+ 2253424,
+ 2253446,
+ 2129763,
+ 2129764,
+ 2129773,
+ 2129789,
+ 2129790,
+ 2129808,
+ 2118011,
+ 2243854,
+ 2129814,
+ 2129820,
+ 2129837,
+ 2253826,
+ 2129859,
+ 2129871,
+ 2129891,
+ 2129906,
+ 2129930,
+ 2129928,
+ 2129942,
+ 2129964,
+ 2129968,
+ 2129987,
+ 2130022,
+ 2130043,
+ 2130073,
+ 2130076,
+ 2130084,
+ 2130087,
+ 2130104,
+ 2254462,
+ 2130117,
+ 2130133,
+ 2130150,
+ 2130189,
+ 2130165,
+ 2130171,
+ 2114542,
+ 2130229,
+ 2130206,
+ 2114544,
+ 2130212,
+ 2130215,
+ 2130220,
+ 2254621,
+ 2130237,
+ 2114568,
+ 2130281,
+ 2114583,
+ 2114588,
+ 2130309,
+ 2114594,
+ 2130328,
+ 2130354,
+ 2130369,
+ 2130371,
+ 2130390,
+ 2130395,
+ 2255069,
+ 2130404,
+ 2255082,
+ 2130412,
+ 2130429,
+ 2130431,
+ 2255215,
+ 2130436,
+ 2255325,
+ 2130457,
+ 2130466,
+ 2255390,
+ 2130492,
+ 2130505,
+ 2130501,
+ 2255448,
+ 2114678,
+ 2114682,
+ 2130519,
+ 2255500,
+ 2130524,
+ 2130531,
+ 2255543,
+ 2114705,
+ 2130557,
+ 2130559,
+ 2130563,
+ 2130570,
+ 2130579,
+ 2130599,
+ 2130600,
+ 2130610,
+ 2130612,
+ 2130618,
+ 2130620,
+ 2130658,
+ 2130664,
+ 2130679,
+ 2130695,
+ 2130696,
+ 2130700,
+ 2130772,
+ 2130715,
+ 2130717,
+ 2130736,
+ 2130748,
+ 2130756,
+ 2130775,
+ 2114750,
+ 2114772,
+ 2114739,
+ 2130836,
+ 2130837,
+ 2130843,
+ 2130845,
+ 2130889,
+ 2130896,
+ 2130900,
+ 2130909,
+ 2130917,
+ 2130937,
+ 2130965,
+ 2255987,
+ 2130967,
+ 2131001,
+ 2131023,
+ 2131025,
+ 2131026,
+ 2131033,
+ 2131034,
+ 2131036,
+ 2256093,
+ 2131045,
+ 2131064,
+ 2131068,
+ 2131073,
+ 2114829,
+ 2131095,
+ 2131110,
+ 2131134,
+ 2114824,
+ 2131150,
+ 2131151,
+ 2131155,
+ 2256485,
+ 2131175,
+ 2131178,
+ 2131183,
+ 2131185,
+ 2131194,
+ 2131227,
+ 2131236,
+ 2131237,
+ 2131243,
+ 2131279,
+ 2131311,
+ 2114883,
+ 2131281,
+ 2131297,
+ 2131298,
+ 2256788,
+ 2131323,
+ 2131325,
+ 2131327,
+ 2131329,
+ 2131334,
+ 2131347,
+ 2131357,
+ 2131359,
+ 2256888,
+ 2256886,
+ 2256887,
+ 2131388,
+ 2131399,
+ 2131402,
+ 2131416,
+ 2131417,
+ 2131423,
+ 2131425,
+ 2131430,
+ 2131446,
+ 2131456,
+ 2131473,
+ 2131486,
+ 2131489,
+ 2131492,
+ 2131495,
+ 2257165,
+ 2131513,
+ 2131516,
+ 2257209,
+ 2131520,
+ 2131539,
+ 2131542,
+ 2131575,
+ 2131591,
+ 2131593,
+ 2131612,
+ 2131613,
+ 2131633,
+ 2131635,
+ 2131649,
+ 2131651,
+ 2131665,
+ 2131669,
+ 2131671,
+ 2131683,
+ 2131686,
+ 2115000,
+ 2131717,
+ 2131719,
+ 2131726,
+ 2131728,
+ 2131743,
+ 2131745,
+ 2131747,
+ 2131761,
+ 2131770,
+ 2131776,
+ 2131779,
+ 2131793,
+ 2131800,
+ 2131812,
+ 2131813,
+ 2131826,
+ 2131836,
+ 2257883,
+ 2257882,
+ 2131879,
+ 2131849,
+ 2131851,
+ 2131859,
+ 2131872,
+ 2257918,
+ 2115045,
+ 2131902,
+ 2257936,
+ 2131905,
+ 2131918,
+ 2131935,
+ 2257993,
+ 2131939,
+ 2131941,
+ 2131942,
+ 2131946,
+ 2131987,
+ 2132008,
+ 2132014,
+ 2132018,
+ 2132028,
+ 2115087,
+ 2132042,
+ 2132056,
+ 2258453,
+ 2258452,
+ 2132073,
+ 2258481,
+ 2132079,
+ 2132128,
+ 2132156,
+ 2132160,
+ 2258579,
+ 2132177,
+ 2132179,
+ 2115137,
+ 2132225,
+ 2258702,
+ 2132279,
+ 2258723,
+ 2132290,
+ 2132293,
+ 2132297,
+ 2258770,
+ 2132322,
+ 2132361,
+ 2132368,
+ 2132383,
+ 2132400,
+ 2132407,
+ 2132440,
+ 2132459,
+ 2115233,
+ 2132467,
+ 2132477,
+ 2132479,
+ 2115247,
+ 2132497,
+ 2132500,
+ 2259333,
+ 2132513,
+ 2132533,
+ 2132542,
+ 2132549,
+ 2132557,
+ 2132568,
+ 2132654,
+ 2132624,
+ 2132663,
+ 2132695,
+ 2132732,
+ 2259588,
+ 2132746,
+ 2132741,
+ 2132749,
+ 2132764,
+ 2132781,
+ 2115340,
+ 2132817,
+ 2132830,
+ 2132854,
+ 2132865,
+ 2132875,
+ 2132884,
+ 2132885,
+ 2133049,
+ 2259891,
+ 2133053,
+ 2259902,
+ 2259911,
+ 2133061,
+ 2133071,
+ 2133079,
+ 2133097,
+ 2133101,
+ 2260152,
+ 2133139,
+ 2133138,
+ 2133145,
+ 2115428,
+ 2133147,
+ 2133206,
+ 2133205,
+ 2260384,
+ 2133233,
+ 2260496,
+ 2133257,
+ 2133262,
+ 2133448,
+ 2133465,
+ 2133516,
+ 2115581,
+ 2133501,
+ 2133510,
+ 2261130,
+ 2133524,
+ 2133526,
+ 2133537,
+ 2133538,
+ 2133543,
+ 2261179,
+ 2115606,
+ 2133558,
+ 2133561,
+ 2133588,
+ 2133602,
+ 2133613,
+ 2133615,
+ 2133656,
+ 2133662,
+ 2133685,
+ 2133691,
+ 2261634,
+ 2115662,
+ 2261747,
+ 2133760,
+ 2133768,
+ 2133803,
+ 2133824,
+ 2133834,
+ 2133848,
+ 2262028,
+ 2133924,
+ 2133940,
+ 2262101,
+ 2133953,
+ 2133958,
+ 2161188,
+ 2133962,
+ 2133965,
+ 2133971,
+ 2133973,
+ 2134001,
+ 2134005,
+ 2134011,
+ 2134028,
+ 2134071,
+ 2262379,
+ 2134083,
+ 2134109,
+ 2262472,
+ 2262473,
+ 2134149,
+ 2134156,
+ 2134160,
+ 2134177,
+ 2115765,
+ 2134192,
+ 2134198,
+ 2134211,
+ 2134216,
+ 2262743,
+ 2134236,
+ 2134239,
+ 2262778,
+ 2134262,
+ 2134258,
+ 2134272,
+ 2134251,
+ 2134270,
+ 2134271,
+ 2134276,
+ 2134278,
+ 2134296,
+ 2134302,
+ 2134327,
+ 2134329,
+ 2134342,
+ 2134343,
+ 2134359,
+ 2134361,
+ 2134388,
+ 2134393,
+ 2134405,
+ 2134451,
+ 2134454,
+ 2134467,
+ 2134468,
+ 2263369,
+ 2263366,
+ 2134508,
+ 2134529,
+ 2134550,
+ 2134551,
+ 2263403,
+ 2134594,
+ 2134602,
+ 2134614,
+ 2134625,
+ 2134629,
+ 2134632,
+ 2263432,
+ 2134652,
+ 2134653,
+ 2134655,
+ 2134665,
+ 2134669,
+ 2134679,
+ 2134681,
+ 2134687,
+ 2134699,
+ 2263482,
+ 2263483,
+ 2134706,
+ 2134719,
+ 2134720,
+ 2134726,
+ 2134734,
+ 2134757,
+ 2134801,
+ 2263582,
+ 2263593,
+ 2134775,
+ 2134825,
+ 2263665,
+ 2263619,
+ 2134865,
+ 2134874,
+ 2134891,
+ 2134897,
+ 2134899,
+ 2134945,
+ 2263705,
+ 2263757,
+ 2134920,
+ 2134923,
+ 2134927,
+ 2134942,
+ 2135029,
+ 2263780,
+ 2263773,
+ 2135025,
+ 2134983,
+ 2135004,
+ 2135015,
+ 2135049,
+ 2135062,
+ 2135063,
+ 2135035,
+ 2135090,
+ 2135099,
+ 2264001,
+ 2264047,
+ 2135149,
+ 2135151,
+ 2135417,
+ 2135430,
+ 2135436,
+ 2135437,
+ 2264336,
+ 2264433,
+ 2135496,
+ 2264571,
+ 2264607,
+ 2135596,
+ 2135603,
+ 2135604,
+ 2264630,
+ 2135612,
+ 2135649,
+ 2264713,
+ 2135682,
+ 2264811,
+ 2135706,
+ 2264882,
+ 2116071,
+ 2135731,
+ 2135738,
+ 2135741,
+ 2116090,
+ 2265080,
+ 2135768,
+ 2135770,
+ 2135773,
+ 2116100,
+ 2135828,
+ 2135843,
+ 2116137,
+ 2135862,
+ 2135873,
+ 2135879,
+ 2135895,
+ 2135899,
+ 2135914,
+ 2265760,
+ 2265777,
+ 2135958,
+ 2135966,
+ 2135985,
+ 2135986,
+ 2135998,
+ 2136012,
+ 2136017,
+ 2136020,
+ 2136024,
+ 2136033,
+ 2136049,
+ 2136068,
+ 2136077,
+ 2136084,
+ 2136086,
+ 2116284,
+ 2266256,
+ 2136114,
+ 2136115,
+ 2136101,
+ 2136135,
+ 2136166,
+ 2136235,
+ 2136237,
+ 2136240,
+ 2266575,
+ 2136247,
+ 2136251,
+ 2136252,
+ 2136258,
+ 2136263,
+ 2136267,
+ 2136289,
+ 2136291,
+ 2136298,
+ 2136304,
+ 2136305,
+ 2136307,
+ 2136328,
+ 2116411,
+ 2266864,
+ 2136342,
+ 2136343,
+ 2266905,
+ 2136346,
+ 2136347,
+ 2136348,
+ 2266960,
+ 2136369,
+ 2136378,
+ 2136379,
+ 2136380,
+ 2136385,
+ 2136390,
+ 2136398,
+ 2136416,
+ 2136483,
+ 2136486,
+ 2136509,
+ 2136511,
+ 2136515,
+ 2136532,
+ 2136537,
+ 2136542,
+ 2267334,
+ 2136560,
+ 2136569,
+ 2136572,
+ 2136586,
+ 2136593,
+ 2136602,
+ 2136608,
+ 2136625,
+ 2136644,
+ 2136652,
+ 2136664,
+ 2116546,
+ 2136751,
+ 2116554,
+ 2136759,
+ 2116562,
+ 2136761,
+ 2267762,
+ 2136774,
+ 2136784,
+ 2136786,
+ 2136789,
+ 2136800,
+ 2136805,
+ 2136809,
+ 2136844,
+ 2136848,
+ 2136850,
+ 2136854,
+ 2136860,
+ 2136875,
+ 2136893,
+ 2116640,
+ 2136907,
+ 2136931,
+ 2136933,
+ 2136939,
+ 2136940,
+ 2136950,
+ 2136951,
+ 2136998,
+ 2137004,
+ 2268635,
+ 2137010,
+ 2137016,
+ 2137022,
+ 2137075,
+ 2137048,
+ 2137053,
+ 2137066,
+ 2137071,
+ 2137070,
+ 2268693,
+ 2268810,
+ 2268745,
+ 2137110,
+ 2137112,
+ 2137113,
+ 2137114,
+ 2137117,
+ 2137122,
+ 2137129,
+ 2268868,
+ 2137137,
+ 2137143,
+ 2137157,
+ 2137180,
+ 2268905,
+ 2137161,
+ 2137162,
+ 2268891,
+ 2137172,
+ 2137176,
+ 2137179,
+ 2137181,
+ 2137183,
+ 2137193,
+ 2137194,
+ 2137195,
+ 2137197,
+ 2137198,
+ 2137202,
+ 2137205,
+ 2137210,
+ 2137318,
+ 2137330,
+ 2137355,
+ 2269143,
+ 2137361,
+ 2137367,
+ 2137368,
+ 2269231,
+ 2116804,
+ 2269210,
+ 2137394,
+ 2116817,
+ 2137418,
+ 2137439,
+ 2137442,
+ 2269433,
+ 2269314,
+ 2137459,
+ 2137462,
+ 2137463,
+ 2137476,
+ 2137497,
+ 2137505,
+ 2137535,
+ 2137525,
+ 2137529,
+ 2137533,
+ 2137545,
+ 2137562,
+ 2137568,
+ 2137571,
+ 2116871,
+ 2137610,
+ 2137602,
+ 2137613,
+ 2137628,
+ 2137723,
+ 2236952,
+ 2137728,
+ 2137733,
+ 2137755,
+ 2270092,
+ 2137789,
+ 2270263,
+ 2137823,
+ 2137855,
+ 2137858,
+ 2116983,
+ 2137859,
+ 2137914,
+ 2137917,
+ 2137926,
+ 2137939,
+ 2137941,
+ 2137944,
+ 2270705,
+ 2137949,
+ 2270722,
+ 2137961,
+ 2137965,
+ 2137968,
+ 2270898,
+ 2128186,
+ 2110996,
+ 2111661,
+ 2112972,
+ 2113500,
+ 2115006,
+ 2115088,
+ 2116478,
+ 2116664,
+ 2116833,
+ 2117132,
+ 2117155,
+ 2117156,
+ 2117241,
+ 2117363,
+ 2117388,
+ 2117401,
+ 2117419,
+ 2117422,
+ 2117425,
+ 2117508,
+ 2117534,
+ 2117559,
+ 2117636,
+ 2117644,
+ 2117708,
+ 2117727,
+ 2117730,
+ 2117751,
+ 2117774,
+ 2117790,
+ 2117794,
+ 2117827,
+ 2117864,
+ 2117873,
+ 2117886,
+ 2117895,
+ 2117900,
+ 2117901,
+ 2117902,
+ 2117939,
+ 2117944,
+ 2118004,
+ 2118020,
+ 2118072,
+ 2118074,
+ 2118088,
+ 2118095,
+ 2118097,
+ 2118099,
+ 2118100,
+ 2118104,
+ 2118111,
+ 2118149,
+ 2118182,
+ 2118184,
+ 2118187,
+ 2118193,
+ 2118194,
+ 2118197,
+ 2118204,
+ 2118234,
+ 2118240,
+ 2118254,
+ 2118264,
+ 2118265,
+ 2118282,
+ 2118284,
+ 2118369,
+ 2118377,
+ 2118385,
+ 2118403,
+ 2118417,
+ 2118431,
+ 2118445,
+ 2118450,
+ 2118461,
+ 2118501,
+ 2118509,
+ 2118521,
+ 2118526,
+ 2118548,
+ 2118553,
+ 2118570,
+ 2118575,
+ 2118586,
+ 2118593,
+ 2118596,
+ 2118597,
+ 2118624,
+ 2118675,
+ 2118698,
+ 2118705,
+ 2118708,
+ 2118709,
+ 2118732,
+ 2118823,
+ 2118826,
+ 2118833,
+ 2118843,
+ 2118862,
+ 2118890,
+ 2118908,
+ 2118917,
+ 2118920,
+ 2118933,
+ 2118951,
+ 2118954,
+ 2118966,
+ 2118993,
+ 2119014,
+ 2119055,
+ 2119058,
+ 2119060,
+ 2119076,
+ 2119090,
+ 2119107,
+ 2119110,
+ 2119123,
+ 2119131,
+ 2119148,
+ 2119150,
+ 2119153,
+ 2119158,
+ 2119160,
+ 2119173,
+ 2119181,
+ 2119185,
+ 2119186,
+ 2119212,
+ 2119221,
+ 2119225,
+ 2119245,
+ 2119252,
+ 2119301,
+ 2119327,
+ 2119334,
+ 2119351,
+ 2119372,
+ 2119375,
+ 2119385,
+ 2119393,
+ 2119403,
+ 2119405,
+ 2119409,
+ 2119431,
+ 2119436,
+ 2119450,
+ 2119451,
+ 2119453,
+ 2119468,
+ 2119470,
+ 2119485,
+ 2119486,
+ 2119519,
+ 2119531,
+ 2119533,
+ 2119546,
+ 2119555,
+ 2119575,
+ 2119598,
+ 2119637,
+ 2119655,
+ 2119693,
+ 2119718,
+ 2119757,
+ 2119759,
+ 2119775,
+ 2119789,
+ 2119807,
+ 2119809,
+ 2119832,
+ 2119868,
+ 2119967,
+ 2119971,
+ 2120025,
+ 2120057,
+ 2120087,
+ 2120111,
+ 2120115,
+ 2120159,
+ 2120177,
+ 2120184,
+ 2120370,
+ 2120376,
+ 2120426,
+ 2120438,
+ 2120475,
+ 2120477,
+ 2120481,
+ 2120504,
+ 2120631,
+ 2120663,
+ 2120672,
+ 2120735,
+ 2120746,
+ 2120748,
+ 2120758,
+ 2120793,
+ 2120796,
+ 2120813,
+ 2120925,
+ 2120961,
+ 2121012,
+ 2121021,
+ 2121049,
+ 2121086,
+ 2121091,
+ 2121159,
+ 2121209,
+ 2121256,
+ 2121266,
+ 2121269,
+ 2121307,
+ 2121320,
+ 2121322,
+ 2121335,
+ 2121344,
+ 2121355,
+ 2121395,
+ 2121405,
+ 2121425,
+ 2121428,
+ 2121429,
+ 2121549,
+ 2121644,
+ 2121706,
+ 2121735,
+ 2121801,
+ 2121812,
+ 2121831,
+ 2121915,
+ 2121924,
+ 2121981,
+ 2121994,
+ 2122006,
+ 2122026,
+ 2122038,
+ 2122078,
+ 2122084,
+ 2122107,
+ 2122109,
+ 2122111,
+ 2122141,
+ 2122168,
+ 2122204,
+ 2122210,
+ 2122213,
+ 2122216,
+ 2122244,
+ 2122247,
+ 2122289,
+ 2122297,
+ 2122301,
+ 2122362,
+ 2122384,
+ 2122408,
+ 2122458,
+ 2122484,
+ 2122518,
+ 2122538,
+ 2122550,
+ 2122566,
+ 2122571,
+ 2122579,
+ 2122609,
+ 2122613,
+ 2122623,
+ 2122626,
+ 2122634,
+ 2122670,
+ 2122671,
+ 2122730,
+ 2122744,
+ 2122745,
+ 2122770,
+ 2122776,
+ 2122784,
+ 2122788,
+ 2122794,
+ 2122805,
+ 2122813,
+ 2122815,
+ 2122834,
+ 2122847,
+ 2122868,
+ 2122896,
+ 2122904,
+ 2122905,
+ 2122924,
+ 2122931,
+ 2122989,
+ 2122992,
+ 2123035,
+ 2123039,
+ 2123054,
+ 2123081,
+ 2123104,
+ 2123154,
+ 2123157,
+ 2123188,
+ 2123198,
+ 2123208,
+ 2123214,
+ 2123216,
+ 2123231,
+ 2123390,
+ 2123403,
+ 2123404,
+ 2123443,
+ 2123456,
+ 2123471,
+ 2123557,
+ 2123573,
+ 2123605,
+ 2123648,
+ 2123663,
+ 2123665,
+ 2123684,
+ 2123697,
+ 2123701,
+ 2123710,
+ 2123816,
+ 2123910,
+ 2124011,
+ 2124021,
+ 2124055,
+ 2124083,
+ 2124088,
+ 2124123,
+ 2124133,
+ 2124200,
+ 2124203,
+ 2124207,
+ 2124261,
+ 2124273,
+ 2124362,
+ 2124373,
+ 2124391,
+ 2124401,
+ 2124463,
+ 2124488,
+ 2124489,
+ 2124547,
+ 2124603,
+ 2124607,
+ 2124669,
+ 2124670,
+ 2124720,
+ 2124791,
+ 2124793,
+ 2124804,
+ 2124809,
+ 2124813,
+ 2124844,
+ 2124874,
+ 2124882,
+ 2124884,
+ 2124921,
+ 2124972,
+ 2124980,
+ 2125010,
+ 2125153,
+ 2125180,
+ 2125241,
+ 2125296,
+ 2125381,
+ 2125427,
+ 2125435,
+ 2125437,
+ 2125449,
+ 2125500,
+ 2125530,
+ 2125531,
+ 2125606,
+ 2125609,
+ 2125616,
+ 2125703,
+ 2125725,
+ 2125742,
+ 2125751,
+ 2125837,
+ 2125856,
+ 2125897,
+ 2125976,
+ 2126000,
+ 2126037,
+ 2126038,
+ 2126149,
+ 2126258,
+ 2126324,
+ 2126359,
+ 2126367,
+ 2126403,
+ 2126415,
+ 2126416,
+ 2126426,
+ 2126432,
+ 2126440,
+ 2126455,
+ 2126468,
+ 2126537,
+ 2126565,
+ 2126580,
+ 2126594,
+ 2126603,
+ 2126622,
+ 2126626,
+ 2126650,
+ 2126651,
+ 2126669,
+ 2126680,
+ 2126695,
+ 2126962,
+ 2127023,
+ 2127071,
+ 2127076,
+ 2127092,
+ 2127099,
+ 2127126,
+ 2127137,
+ 2127167,
+ 2127198,
+ 2127257,
+ 2127268,
+ 2127297,
+ 2127300,
+ 2127308,
+ 2127319,
+ 2127324,
+ 2127329,
+ 2127343,
+ 2127364,
+ 2127372,
+ 2127389,
+ 2127410,
+ 2127416,
+ 2127429,
+ 2127434,
+ 2127455,
+ 2127533,
+ 2127549,
+ 2127577,
+ 2127595,
+ 2127600,
+ 2127609,
+ 2127616,
+ 2127630,
+ 2127650,
+ 2127656,
+ 2127663,
+ 2127673,
+ 2127678,
+ 2127685,
+ 2127690,
+ 2127695,
+ 2127710,
+ 2127716,
+ 2127719,
+ 2127724,
+ 2127748,
+ 2127756,
+ 2127757,
+ 2127766,
+ 2127783,
+ 2127791,
+ 2127799,
+ 2127806,
+ 2127817,
+ 2127825,
+ 2127833,
+ 2127857,
+ 2127927,
+ 2127964,
+ 2127998,
+ 2128024,
+ 2128033,
+ 2128049,
+ 2128051,
+ 2128073,
+ 2128083,
+ 2128140,
+ 2128159,
+ 2128167,
+ 2128168,
+ 2128191,
+ 2128194,
+ 2128212,
+ 2128235,
+ 2128252,
+ 2128299,
+ 2128324,
+ 2128362,
+ 2128386,
+ 2128396,
+ 2128432,
+ 2128442,
+ 2128452,
+ 2128512,
+ 2128518,
+ 2128532,
+ 2128565,
+ 2128573,
+ 2128638,
+ 2128683,
+ 2128759,
+ 2128800,
+ 2128812,
+ 2128816,
+ 2128872,
+ 2128882,
+ 2128888,
+ 2128892,
+ 2128894,
+ 2128905,
+ 2128936,
+ 2128943,
+ 2128962,
+ 2128978,
+ 2128979,
+ 2128987,
+ 2128988,
+ 2128989,
+ 2129010,
+ 2129021,
+ 2129031,
+ 2129054,
+ 2129082,
+ 2129095,
+ 2129107,
+ 2129114,
+ 2129212,
+ 2129229,
+ 2129282,
+ 2129285,
+ 2129293,
+ 2129297,
+ 2129310,
+ 2129331,
+ 2129337,
+ 2129360,
+ 2129381,
+ 2129397,
+ 2129398,
+ 2129455,
+ 2129462,
+ 2129476,
+ 2129519,
+ 2129528,
+ 2129537,
+ 2129725,
+ 2129755,
+ 2129757,
+ 2129765,
+ 2129777,
+ 2129791,
+ 2129792,
+ 2129803,
+ 2129826,
+ 2129917,
+ 2129918,
+ 2129919,
+ 2129927,
+ 2129933,
+ 2129950,
+ 2129977,
+ 2130056,
+ 2130062,
+ 2130127,
+ 2130132,
+ 2130157,
+ 2130160,
+ 2130167,
+ 2130170,
+ 2130174,
+ 2130179,
+ 2130199,
+ 2130224,
+ 2130263,
+ 2130287,
+ 2130291,
+ 2130315,
+ 2130320,
+ 2130331,
+ 2130334,
+ 2130379,
+ 2130389,
+ 2130397,
+ 2130398,
+ 2130401,
+ 2130415,
+ 2130422,
+ 2130432,
+ 2130443,
+ 2130451,
+ 2130452,
+ 2130458,
+ 2130490,
+ 2130500,
+ 2130541,
+ 2130564,
+ 2130569,
+ 2130577,
+ 2130602,
+ 2130608,
+ 2130640,
+ 2130666,
+ 2130671,
+ 2130678,
+ 2130774,
+ 2130808,
+ 2130936,
+ 2130940,
+ 2131032,
+ 2131091,
+ 2131121,
+ 2131133,
+ 2131195,
+ 2131270,
+ 2131286,
+ 2131293,
+ 2131333,
+ 2131352,
+ 2131522,
+ 2131526,
+ 2131648,
+ 2131732,
+ 2131746,
+ 2131758,
+ 2131769,
+ 2131805,
+ 2131835,
+ 2131852,
+ 2131854,
+ 2131863,
+ 2131864,
+ 2131870,
+ 2131875,
+ 2131886,
+ 2131903,
+ 2131913,
+ 2131930,
+ 2131992,
+ 2131995,
+ 2132013,
+ 2132026,
+ 2132037,
+ 2132043,
+ 2132046,
+ 2132053,
+ 2132058,
+ 2132078,
+ 2132122,
+ 2132123,
+ 2132124,
+ 2132173,
+ 2132192,
+ 2132207,
+ 2132238,
+ 2132239,
+ 2132262,
+ 2132277,
+ 2132314,
+ 2132316,
+ 2132331,
+ 2132336,
+ 2132348,
+ 2132389,
+ 2132405,
+ 2132412,
+ 2132437,
+ 2132553,
+ 2132567,
+ 2132583,
+ 2132606,
+ 2132614,
+ 2132630,
+ 2132662,
+ 2132681,
+ 2132689,
+ 2132701,
+ 2132716,
+ 2132725,
+ 2132742,
+ 2132751,
+ 2132753,
+ 2132805,
+ 2132818,
+ 2132845,
+ 2132856,
+ 2132860,
+ 2132862,
+ 2132869,
+ 2132895,
+ 2133067,
+ 2133075,
+ 2133115,
+ 2133178,
+ 2133189,
+ 2133193,
+ 2133202,
+ 2133228,
+ 2133237,
+ 2133239,
+ 2133249,
+ 2133251,
+ 2133271,
+ 2133276,
+ 2133358,
+ 2133393,
+ 2133407,
+ 2133419,
+ 2133426,
+ 2133461,
+ 2133479,
+ 2133489,
+ 2133490,
+ 2133492,
+ 2133505,
+ 2133515,
+ 2133542,
+ 2133553,
+ 2133568,
+ 2133569,
+ 2133581,
+ 2133583,
+ 2133596,
+ 2133601,
+ 2133609,
+ 2133617,
+ 2133621,
+ 2133623,
+ 2133641,
+ 2133648,
+ 2133653,
+ 2133658,
+ 2133671,
+ 2133673,
+ 2133677,
+ 2133736,
+ 2133744,
+ 2133767,
+ 2133784,
+ 2133797,
+ 2133799,
+ 2133804,
+ 2133813,
+ 2133818,
+ 2133827,
+ 2133831,
+ 2133841,
+ 2133845,
+ 2133920,
+ 2133921,
+ 2133922,
+ 2133925,
+ 2134020,
+ 2134043,
+ 2134063,
+ 2134092,
+ 2134107,
+ 2134128,
+ 2134132,
+ 2134137,
+ 2134155,
+ 2134168,
+ 2134176,
+ 2134194,
+ 2134205,
+ 2134217,
+ 2134256,
+ 2134277,
+ 2134309,
+ 2134362,
+ 2134375,
+ 2134394,
+ 2134410,
+ 2134417,
+ 2134421,
+ 2134448,
+ 2134459,
+ 2134461,
+ 2134466,
+ 2134469,
+ 2134528,
+ 2134537,
+ 2134563,
+ 2134646,
+ 2134670,
+ 2134703,
+ 2134715,
+ 2134716,
+ 2134721,
+ 2134723,
+ 2134725,
+ 2134728,
+ 2134804,
+ 2134835,
+ 2134838,
+ 2134872,
+ 2134911,
+ 2134914,
+ 2134922,
+ 2134971,
+ 2134988,
+ 2135014,
+ 2135033,
+ 2135042,
+ 2135053,
+ 2135054,
+ 2135086,
+ 2135116,
+ 2135432,
+ 2135457,
+ 2135487,
+ 2135494,
+ 2135497,
+ 2135505,
+ 2135506,
+ 2135520,
+ 2135524,
+ 2135526,
+ 2135588,
+ 2135601,
+ 2135608,
+ 2135613,
+ 2135636,
+ 2135668,
+ 2135675,
+ 2135679,
+ 2135681,
+ 2135683,
+ 2135689,
+ 2135702,
+ 2135726,
+ 2135811,
+ 2135835,
+ 2135841,
+ 2135842,
+ 2135848,
+ 2135857,
+ 2135911,
+ 2135926,
+ 2135933,
+ 2135935,
+ 2135961,
+ 2135967,
+ 2135980,
+ 2135993,
+ 2136013,
+ 2136032,
+ 2136047,
+ 2136071,
+ 2136102,
+ 2136110,
+ 2136162,
+ 2136163,
+ 2136244,
+ 2136261,
+ 2136322,
+ 2136337,
+ 2136341,
+ 2136373,
+ 2136392,
+ 2136404,
+ 2136414,
+ 2136545,
+ 2136588,
+ 2136592,
+ 2136611,
+ 2136641,
+ 2136657,
+ 2136765,
+ 2136766,
+ 2136833,
+ 2136841,
+ 2136843,
+ 2136845,
+ 2136846,
+ 2136857,
+ 2136885,
+ 2136904,
+ 2136917,
+ 2136936,
+ 2136960,
+ 2136966,
+ 2136976,
+ 2136989,
+ 2137008,
+ 2137023,
+ 2137032,
+ 2137087,
+ 2137090,
+ 2137116,
+ 2137141,
+ 2137156,
+ 2137174,
+ 2137185,
+ 2137192,
+ 2137392,
+ 2137405,
+ 2137450,
+ 2137467,
+ 2137573,
+ 2137577,
+ 2137587,
+ 2137722,
+ 2137730,
+ 2137731,
+ 2137732,
+ 2137776,
+ 2137828,
+ 2137840,
+ 2137842,
+ 2137865,
+ 2137871,
+ 2137876,
+ 2137883,
+ 2137890,
+ 2137894,
+ 2137898,
+ 2137899,
+ 2137908,
+ 2137946,
+ 2137967,
+ 2138014,
+ 2138021,
+ 2228469,
+ 2248196,
+ 2248690,
+ 2260339,
+ 2118029,
+ 4216196,
+ 4218722,
+ 4219208,
+ 4220959,
+ 2133716,
+ 2110942,
+ 2138047,
+ 2138048,
+ 2138049,
+ 2138050,
+ 2269874,
+ 4214286,
+ 4214310,
+ 2228568,
+ 4214643,
+ 4214870,
+ 4215021,
+ 4215147,
+ 2229681,
+ 8409566,
+ 4215293,
+ 2229996,
+ 4215396,
+ 4215409,
+ 6312562,
+ 4215615,
+ 2275155,
+ 4215872,
+ 2231640,
+ 4216220,
+ 6313387,
+ 4216329,
+ 6313646,
+ 8410798,
+ 2275162,
+ 2275164,
+ 4216526,
+ 4216558,
+ 4216790,
+ 4216893,
+ 4216921,
+ 4217167,
+ 6314321,
+ 4217184,
+ 4217186,
+ 4217562,
+ 4217690,
+ 4217715,
+ 4217724,
+ 8412083,
+ 2251212,
+ 4218435,
+ 2275190,
+ 6315747,
+ 4218680,
+ 4218785,
+ 4218845,
+ 4219234,
+ 6316466,
+ 4219384,
+ 2111908,
+ 2111928,
+ 2240066,
+ 2275196,
+ 4220150,
+ 2112092,
+ 2230216,
+ 4220254,
+ 2240491,
+ 4220295,
+ 4220297,
+ 2259380,
+ 4220302,
+ 2112196,
+ 2112203,
+ 4220385,
+ 4220519,
+ 4220526,
+ 6317761,
+ 2275202,
+ 2112133,
+ 4220672,
+ 4220769,
+ 4220868,
+ 4220930,
+ 4221245,
+ 4221278,
+ 2275211,
+ 4221596,
+ 2112499,
+ 2242545,
+ 2275220,
+ 4222008,
+ 6319274,
+ 2138060,
+ 4222436,
+ 2112817,
+ 4222472,
+ 4222578,
+ 6319819,
+ 4222677,
+ 4222683,
+ 4222811,
+ 6319963,
+ 4222820,
+ 4222836,
+ 2244683,
+ 4223550,
+ 2113088,
+ 2111649,
+ 6321098,
+ 4224189,
+ 4224349,
+ 4224444,
+ 2275244,
+ 4224520,
+ 4224612,
+ 4224617,
+ 2275247,
+ 4224823,
+ 4224894,
+ 4225447,
+ 4225457,
+ 4225726,
+ 4226016,
+ 6323280,
+ 4226313,
+ 4226482,
+ 6323634,
+ 4226878,
+ 6324193,
+ 4227090,
+ 2275273,
+ 4227286,
+ 4227337,
+ 4227369,
+ 4227596,
+ 4227611,
+ 4227648,
+ 2275279,
+ 4228052,
+ 4228111,
+ 2275282,
+ 4228330,
+ 2256030,
+ 4228433,
+ 4228451,
+ 4228559,
+ 4228686,
+ 4228706,
+ 4228746,
+ 4229186,
+ 4229239,
+ 4229441,
+ 4229974,
+ 6327126,
+ 4229980,
+ 2115359,
+ 2260028,
+ 4230250,
+ 4230265,
+ 6327498,
+ 4230503,
+ 2115614,
+ 4230915,
+ 6328132,
+ 6328261,
+ 6328276,
+ 4231158,
+ 6328439,
+ 8425591,
+ 31494281,
+ 16814218,
+ 4231336,
+ 4231501,
+ 4231913,
+ 4231989,
+ 4232075,
+ 2275312,
+ 4232653,
+ 4232746,
+ 6330008,
+ 4232871,
+ 8427519,
+ 10524671,
+ 2275173,
+ 4233505,
+ 8427863,
+ 4234152,
+ 4234158,
+ 4234169,
+ 4234248,
+ 4234276,
+ 4234299,
+ 2275341,
+ 4234470,
+ 4234688,
+ 4234690,
+ 2275351,
+ 6330607,
+ 4339773,
+ 6322952,
+ 4220015,
+ 6323262,
+ 4225909,
+ 6321429,
+ 6326813,
+ 6316130,
+ 4223096,
+ 12604329,
+ 4226178,
+ 4232857,
+ 4228692,
+ 4227441,
+ 4232053,
+ 4215980,
+ 4223713,
+ 4221079,
+ 4234155,
+ 4215753,
+ 4220758,
+ 4224294,
+ 8418577,
+ 4225736,
+ 4219706,
+ 6328385,
+ 4233665,
+ 4220327,
+ 4231644,
+ 4233133,
+ 4227730,
+ 6323326,
+ 4223546,
+ 6326277,
+ 4228867,
+ 2136861,
+ 2136876,
+ 2117634,
+ 2118110,
+ 2118407,
+ 2120684,
+ 4218570,
+ 2123294,
+ 2123543,
+ 2125898,
+ 4215262,
+ 2119009,
+ 2124858,
+ 2128480,
+ 2253644,
+ 2131971,
+ 2135467,
+ 2135893,
+ 2268733,
+ 2270746,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ 6319778,
+ 8413682,
+ 6325778,
+ 4230015,
+ 2117173,
+ 2117212,
+ 2117219,
+ 2117224,
+ 2117236,
+ 2117237,
+ 2117271,
+ 2117295,
+ 2117339,
+ 2117346,
+ 2117352,
+ 2117359,
+ 2117374,
+ 2117378,
+ 2117384,
+ 2117394,
+ 2117399,
+ 2117427,
+ 2117429,
+ 2117440,
+ 2117442,
+ 2117451,
+ 2117452,
+ 2117458,
+ 2117475,
+ 2117486,
+ 2117489,
+ 2117497,
+ 2117505,
+ 2117513,
+ 2117516,
+ 2117518,
+ 2117520,
+ 2117523,
+ 2117529,
+ 2117535,
+ 2117561,
+ 2117563,
+ 2117564,
+ 2117565,
+ 2117568,
+ 2117569,
+ 2117574,
+ 2117576,
+ 2117580,
+ 2117596,
+ 2117602,
+ 2117616,
+ 2117628,
+ 2117639,
+ 2117642,
+ 2117655,
+ 2117661,
+ 2117680,
+ 2117682,
+ 2117683,
+ 2117685,
+ 2117701,
+ 2117706,
+ 2117713,
+ 2117714,
+ 2117721,
+ 2117728,
+ 2117735,
+ 2117741,
+ 2117745,
+ 2117761,
+ 2117763,
+ 2117764,
+ 2117766,
+ 2117770,
+ 2117776,
+ 2117787,
+ 2117791,
+ 2117792,
+ 2117793,
+ 2117807,
+ 2117808,
+ 2117817,
+ 2117821,
+ 2117824,
+ 2117843,
+ 2117852,
+ 2117853,
+ 2117855,
+ 2117858,
+ 2117860,
+ 2117878,
+ 2117882,
+ 4215026,
+ 2117913,
+ 2117916,
+ 2117917,
+ 2117923,
+ 2117927,
+ 2117928,
+ 2117932,
+ 2117933,
+ 2117935,
+ 2117937,
+ 2117940,
+ 2117945,
+ 2117954,
+ 2117967,
+ 2117971,
+ 2117976,
+ 2117990,
+ 2118014,
+ 2118030,
+ 2118079,
+ 2118082,
+ 2118098,
+ 2118101,
+ 2118117,
+ 2118130,
+ 2118135,
+ 2118168,
+ 2118178,
+ 2118213,
+ 2118232,
+ 2118239,
+ 2118272,
+ 2118277,
+ 2118293,
+ 2118294,
+ 2118295,
+ 2118298,
+ 2118309,
+ 2118311,
+ 2118320,
+ 2118326,
+ 2118327,
+ 2118328,
+ 2118333,
+ 2118340,
+ 2118342,
+ 2118351,
+ 2118356,
+ 2118364,
+ 2118373,
+ 2118376,
+ 2118378,
+ 2118380,
+ 2118388,
+ 2118390,
+ 2118412,
+ 2118419,
+ 2118424,
+ 2118427,
+ 2118430,
+ 2118437,
+ 2118439,
+ 2118440,
+ 2118441,
+ 2118443,
+ 2118444,
+ 2118448,
+ 2118460,
+ 2118489,
+ 2118491,
+ 4215653,
+ 2118531,
+ 2118535,
+ 2118536,
+ 2118542,
+ 2118561,
+ 2118581,
+ 2118584,
+ 2118589,
+ 2118607,
+ 2118610,
+ 2118611,
+ 2118622,
+ 4215776,
+ 2118631,
+ 2118658,
+ 2118682,
+ 2118689,
+ 2118703,
+ 2118724,
+ 2118727,
+ 2118735,
+ 2118750,
+ 2118756,
+ 2118759,
+ 2118761,
+ 2118765,
+ 2118766,
+ 2118785,
+ 2118787,
+ 2118789,
+ 2118793,
+ 2118801,
+ 2118815,
+ 2118858,
+ 2118880,
+ 2118902,
+ 2118910,
+ 2118924,
+ 2118925,
+ 2118962,
+ 2118971,
+ 2118973,
+ 2118985,
+ 2118989,
+ 2119000,
+ 2119002,
+ 2119003,
+ 2119039,
+ 2119059,
+ 2119063,
+ 2119075,
+ 2119105,
+ 2119115,
+ 2119127,
+ 2119128,
+ 2119134,
+ 2119167,
+ 4216325,
+ 2119178,
+ 2119193,
+ 2119219,
+ 2119228,
+ 2119233,
+ 2119235,
+ 2119236,
+ 2119238,
+ 2119265,
+ 2119266,
+ 2119267,
+ 2119285,
+ 2119300,
+ 2119307,
+ 2119335,
+ 2119339,
+ 2119358,
+ 2119371,
+ 2119376,
+ 2119388,
+ 2119397,
+ 2119398,
+ 2119399,
+ 2119425,
+ 2119426,
+ 2119441,
+ 2119456,
+ 2119458,
+ 2119460,
+ 2119461,
+ 2119466,
+ 2119487,
+ 2119506,
+ 2119522,
+ 2119527,
+ 2119534,
+ 2119537,
+ 2119545,
+ 2119550,
+ 2119553,
+ 2119572,
+ 2119577,
+ 2119583,
+ 2119585,
+ 2119573,
+ 2119591,
+ 2119593,
+ 2119613,
+ 2119645,
+ 2119657,
+ 2119678,
+ 2119683,
+ 2119688,
+ 2119649,
+ 2119692,
+ 2119707,
+ 2119711,
+ 2119725,
+ 2119743,
+ 2119760,
+ 2119765,
+ 2119784,
+ 2119800,
+ 2119815,
+ 2119816,
+ 2119820,
+ 2119830,
+ 2119840,
+ 2119841,
+ 2119842,
+ 2119846,
+ 2119876,
+ 2119874,
+ 2119880,
+ 2119894,
+ 2119901,
+ 2119905,
+ 4217094,
+ 2119954,
+ 2119955,
+ 2119965,
+ 2119969,
+ 2119976,
+ 2119984,
+ 2119987,
+ 2119989,
+ 2119990,
+ 2119999,
+ 2120003,
+ 2120018,
+ 2120030,
+ 2120043,
+ 2120047,
+ 2120050,
+ 2120059,
+ 2120076,
+ 2120078,
+ 2120085,
+ 2120103,
+ 2120109,
+ 2120112,
+ 2120119,
+ 2120129,
+ 2120132,
+ 2120175,
+ 2120178,
+ 2120180,
+ 2120183,
+ 2120192,
+ 2120206,
+ 2120210,
+ 2120222,
+ 2120228,
+ 2120232,
+ 2120234,
+ 2120240,
+ 2120260,
+ 2120261,
+ 2120264,
+ 2120268,
+ 2120272,
+ 2120286,
+ 2120315,
+ 2120336,
+ 2120339,
+ 2120342,
+ 2120345,
+ 2120379,
+ 2120390,
+ 2120392,
+ 2120399,
+ 2120445,
+ 2120449,
+ 2120523,
+ 2120542,
+ 2120558,
+ 2120582,
+ 2120590,
+ 2120592,
+ 2120593,
+ 2120596,
+ 2120616,
+ 2120617,
+ 2120621,
+ 2120623,
+ 2120625,
+ 2120626,
+ 2120634,
+ 2120636,
+ 2120641,
+ 2120653,
+ 2120655,
+ 2120665,
+ 2120666,
+ 2120687,
+ 2120692,
+ 2120716,
+ 2120727,
+ 2120742,
+ 2120750,
+ 2120754,
+ 2120757,
+ 2120794,
+ 2120820,
+ 2120821,
+ 2120827,
+ 2120829,
+ 2120839,
+ 2120850,
+ 2120861,
+ 2120882,
+ 2120884,
+ 2120919,
+ 2120942,
+ 2120945,
+ 2120946,
+ 2120978,
+ 2120995,
+ 2121023,
+ 2121032,
+ 2121045,
+ 2121041,
+ 2121055,
+ 2121056,
+ 2121058,
+ 2121060,
+ 2121081,
+ 2121082,
+ 2121087,
+ 2121098,
+ 2121107,
+ 2121109,
+ 2121115,
+ 2121119,
+ 2121131,
+ 2121155,
+ 2121166,
+ 2121177,
+ 2121223,
+ 2121229,
+ 2121248,
+ 2121291,
+ 2121296,
+ 2121297,
+ 2121308,
+ 2121328,
+ 2121358,
+ 2121378,
+ 2121380,
+ 2121393,
+ 2121420,
+ 2121422,
+ 2121436,
+ 2121438,
+ 2121445,
+ 2121451,
+ 2121478,
+ 2121497,
+ 2121508,
+ 2121515,
+ 2121516,
+ 2121518,
+ 2121520,
+ 2121535,
+ 2121540,
+ 2121563,
+ 2121568,
+ 2121583,
+ 2121588,
+ 2121589,
+ 2121592,
+ 2121594,
+ 2121613,
+ 2121622,
+ 2121629,
+ 2121643,
+ 2121648,
+ 2121649,
+ 2121672,
+ 2121680,
+ 2121681,
+ 2121704,
+ 2121708,
+ 2121714,
+ 2121718,
+ 2121722,
+ 2121738,
+ 2121747,
+ 2121759,
+ 2121773,
+ 2121792,
+ 2121800,
+ 2121809,
+ 2121814,
+ 2121815,
+ 2121841,
+ 2121854,
+ 2121858,
+ 2121862,
+ 2121864,
+ 2121870,
+ 2121873,
+ 2121875,
+ 2121880,
+ 4219038,
+ 2121890,
+ 2121893,
+ 2121911,
+ 2121922,
+ 2121929,
+ 2121930,
+ 2121934,
+ 2121935,
+ 2121954,
+ 2121957,
+ 2121980,
+ 2121986,
+ 2121991,
+ 2121996,
+ 2122007,
+ 2122018,
+ 2122033,
+ 2122037,
+ 2122041,
+ 2122053,
+ 2122057,
+ 2122092,
+ 2122098,
+ 2122104,
+ 2122112,
+ 2122113,
+ 2122115,
+ 2122116,
+ 2122123,
+ 2122140,
+ 2122144,
+ 2122154,
+ 2122176,
+ 2122177,
+ 2122190,
+ 2122191,
+ 2122206,
+ 2122209,
+ 2122215,
+ 2122217,
+ 2122220,
+ 2122221,
+ 2122223,
+ 2122241,
+ 2122243,
+ 2122268,
+ 2122272,
+ 2122279,
+ 2122283,
+ 2122306,
+ 2122308,
+ 2122320,
+ 2122324,
+ 2122332,
+ 2122365,
+ 2122381,
+ 2122382,
+ 2122383,
+ 2122419,
+ 2122422,
+ 2122423,
+ 2122426,
+ 2122430,
+ 2122431,
+ 2122446,
+ 2122474,
+ 2122482,
+ 2122500,
+ 2122507,
+ 2122515,
+ 2122537,
+ 2122541,
+ 2122570,
+ 2122578,
+ 2122580,
+ 2122584,
+ 2122587,
+ 2122598,
+ 2122605,
+ 2122616,
+ 2122645,
+ 2122650,
+ 2122660,
+ 2122662,
+ 2122669,
+ 2122689,
+ 2122693,
+ 2122696,
+ 2122702,
+ 2122707,
+ 2122739,
+ 2122762,
+ 2122800,
+ 2122827,
+ 2122831,
+ 2122835,
+ 2122844,
+ 2122849,
+ 2122851,
+ 2122885,
+ 2122895,
+ 2122907,
+ 2122913,
+ 2122915,
+ 2122918,
+ 2122920,
+ 2122941,
+ 2122953,
+ 2122961,
+ 2122985,
+ 2122986,
+ 2122997,
+ 2123009,
+ 2123016,
+ 2123017,
+ 2123018,
+ 2123027,
+ 2123046,
+ 2123057,
+ 2123066,
+ 2123068,
+ 2123069,
+ 2123075,
+ 2123088,
+ 2123090,
+ 2123103,
+ 2123133,
+ 2123160,
+ 2123168,
+ 2123171,
+ 2123174,
+ 2123182,
+ 2123187,
+ 2123222,
+ 2123224,
+ 4220383,
+ 2123252,
+ 2123253,
+ 2123262,
+ 2123263,
+ 2123277,
+ 2123281,
+ 2123282,
+ 2123286,
+ 2123293,
+ 2123299,
+ 2123302,
+ 2123305,
+ 2123321,
+ 2123319,
+ 2123328,
+ 2123334,
+ 2123338,
+ 2123352,
+ 2123360,
+ 2123381,
+ 2123391,
+ 2123385,
+ 2123388,
+ 2123418,
+ 2123419,
+ 2123420,
+ 2123423,
+ 4220597,
+ 2123458,
+ 2123459,
+ 2123468,
+ 2123470,
+ 2123476,
+ 2123487,
+ 2123499,
+ 2123502,
+ 2123527,
+ 2123548,
+ 2123552,
+ 2123554,
+ 2123582,
+ 2123589,
+ 2123628,
+ 2123652,
+ 2123662,
+ 2123670,
+ 2123673,
+ 2123708,
+ 2123709,
+ 2123714,
+ 2123717,
+ 2123721,
+ 2123740,
+ 2123745,
+ 2123750,
+ 2123762,
+ 2123766,
+ 2123796,
+ 2123801,
+ 2123815,
+ 2123823,
+ 2123839,
+ 2123850,
+ 2123864,
+ 2123887,
+ 2123888,
+ 2123889,
+ 2123897,
+ 2123899,
+ 2123912,
+ 2123937,
+ 2123945,
+ 2123950,
+ 2123985,
+ 2123987,
+ 2123996,
+ 2123997,
+ 2124010,
+ 2124022,
+ 2124029,
+ 2124038,
+ 2124041,
+ 2124048,
+ 2124054,
+ 2124081,
+ 2124101,
+ 2124110,
+ 2124134,
+ 2124144,
+ 2124145,
+ 2124155,
+ 2124173,
+ 2124193,
+ 2124216,
+ 2124229,
+ 2124232,
+ 4221438,
+ 2124288,
+ 2124291,
+ 2124320,
+ 2124324,
+ 2124343,
+ 4221525,
+ 2124394,
+ 2124417,
+ 2124422,
+ 2124423,
+ 2124443,
+ 2124464,
+ 2124465,
+ 2124468,
+ 2124478,
+ 2124479,
+ 2124492,
+ 2124501,
+ 2124502,
+ 2124528,
+ 2124540,
+ 2124546,
+ 2124550,
+ 2124551,
+ 2124553,
+ 2124584,
+ 2124587,
+ 2124598,
+ 2124621,
+ 2124626,
+ 2124637,
+ 2124651,
+ 2124654,
+ 2124656,
+ 2124677,
+ 2124695,
+ 2124703,
+ 2124704,
+ 2124706,
+ 2124707,
+ 2124712,
+ 2124716,
+ 2124728,
+ 2124729,
+ 2124739,
+ 2124740,
+ 2124771,
+ 2124818,
+ 2124825,
+ 2124831,
+ 2124838,
+ 2124839,
+ 2124840,
+ 2124846,
+ 2124859,
+ 2124875,
+ 2124879,
+ 2124907,
+ 2124920,
+ 2124935,
+ 2124959,
+ 2124976,
+ 2124978,
+ 2125005,
+ 2125007,
+ 2125009,
+ 2125031,
+ 2125042,
+ 2125044,
+ 2125063,
+ 2125071,
+ 2125075,
+ 2125082,
+ 2125096,
+ 2125151,
+ 2125159,
+ 2125202,
+ 2125207,
+ 2125239,
+ 2125245,
+ 2125280,
+ 2125282,
+ 2125285,
+ 2125295,
+ 2125300,
+ 2125312,
+ 2125316,
+ 2125371,
+ 2125394,
+ 2125405,
+ 2125410,
+ 2125416,
+ 2125453,
+ 2125465,
+ 2125472,
+ 2125485,
+ 2125486,
+ 2125491,
+ 2125499,
+ 2125504,
+ 2125512,
+ 2125517,
+ 2125519,
+ 2125549,
+ 2125550,
+ 2125572,
+ 2125576,
+ 2125581,
+ 2125590,
+ 2125595,
+ 2125627,
+ 2125613,
+ 2125647,
+ 2125651,
+ 2125661,
+ 2125676,
+ 2125699,
+ 2125715,
+ 2125734,
+ 2125744,
+ 2125765,
+ 2125800,
+ 2125821,
+ 2125847,
+ 2125871,
+ 2125876,
+ 2125879,
+ 2125892,
+ 2125896,
+ 2125909,
+ 2125972,
+ 2125974,
+ 2125979,
+ 2126004,
+ 2126074,
+ 2126085,
+ 2126091,
+ 2126125,
+ 2126136,
+ 2126145,
+ 2126155,
+ 4223314,
+ 2126167,
+ 2126170,
+ 2126220,
+ 2126234,
+ 2126256,
+ 2126271,
+ 2126272,
+ 2126284,
+ 2126298,
+ 2126328,
+ 2126344,
+ 2126345,
+ 2126355,
+ 2126362,
+ 2126372,
+ 2126383,
+ 2126405,
+ 2126414,
+ 2126430,
+ 2126443,
+ 2126449,
+ 2126459,
+ 2126460,
+ 2126473,
+ 2126483,
+ 2126504,
+ 2126549,
+ 2126550,
+ 2126552,
+ 2126559,
+ 2126590,
+ 2126605,
+ 2126611,
+ 2126642,
+ 2126645,
+ 2126678,
+ 2126685,
+ 2126686,
+ 2126687,
+ 2126688,
+ 2126697,
+ 2126713,
+ 2126720,
+ 2126734,
+ 2126736,
+ 2126739,
+ 2126743,
+ 2126762,
+ 2126765,
+ 2126790,
+ 2126796,
+ 2126803,
+ 2126813,
+ 2126822,
+ 2126839,
+ 2126843,
+ 2126847,
+ 2126848,
+ 2126865,
+ 2126893,
+ 2126951,
+ 2126952,
+ 2126958,
+ 2126991,
+ 2126993,
+ 2127002,
+ 2127022,
+ 2127025,
+ 2127026,
+ 2127052,
+ 2127056,
+ 2127059,
+ 4224216,
+ 2127067,
+ 2127080,
+ 2127082,
+ 4224239,
+ 2127100,
+ 2127110,
+ 2127122,
+ 2127143,
+ 2127145,
+ 2127158,
+ 2127161,
+ 2127171,
+ 2127175,
+ 2127191,
+ 2127199,
+ 2127201,
+ 2127227,
+ 2127228,
+ 2127237,
+ 2127253,
+ 2127260,
+ 2127290,
+ 2127378,
+ 2127395,
+ 2127401,
+ 2127417,
+ 2127418,
+ 2127424,
+ 2127428,
+ 2127449,
+ 2127493,
+ 2127500,
+ 2127501,
+ 2127519,
+ 2127522,
+ 2127523,
+ 2127553,
+ 2127563,
+ 4224724,
+ 2127584,
+ 2127606,
+ 2127622,
+ 2127634,
+ 2127636,
+ 2127637,
+ 2127644,
+ 2127662,
+ 2127677,
+ 2127682,
+ 2127698,
+ 2127702,
+ 2127703,
+ 2127728,
+ 2127731,
+ 2127732,
+ 4224909,
+ 4224930,
+ 2127790,
+ 2127793,
+ 2127797,
+ 2127811,
+ 2127826,
+ 2127829,
+ 2127864,
+ 2127886,
+ 2127889,
+ 2127901,
+ 2127907,
+ 2127940,
+ 2127944,
+ 2127948,
+ 2127954,
+ 2127966,
+ 2127968,
+ 2127969,
+ 2127971,
+ 2128015,
+ 2128040,
+ 2128044,
+ 2128050,
+ 2128061,
+ 2128063,
+ 2128071,
+ 2128082,
+ 2128086,
+ 2128091,
+ 2128095,
+ 2128106,
+ 2128115,
+ 2128118,
+ 2128127,
+ 2128134,
+ 2128154,
+ 2128158,
+ 2128160,
+ 2128169,
+ 2128173,
+ 2128181,
+ 2128196,
+ 2128203,
+ 2128207,
+ 2128209,
+ 2128233,
+ 2128251,
+ 2128254,
+ 2128268,
+ 2128273,
+ 2128275,
+ 2128284,
+ 2128296,
+ 2128303,
+ 2128335,
+ 2128349,
+ 2128352,
+ 2128354,
+ 2128357,
+ 2128369,
+ 2128376,
+ 2128380,
+ 2128391,
+ 2128417,
+ 2128423,
+ 2128427,
+ 2128431,
+ 2128436,
+ 2128437,
+ 2128456,
+ 2128469,
+ 2128485,
+ 2128510,
+ 2128523,
+ 2128529,
+ 2128542,
+ 2128585,
+ 2128603,
+ 2128617,
+ 2128620,
+ 2128625,
+ 2128635,
+ 2128671,
+ 2128675,
+ 2128681,
+ 2128688,
+ 2128692,
+ 2128703,
+ 2128704,
+ 2128746,
+ 2128772,
+ 2128777,
+ 2128782,
+ 2128790,
+ 2128805,
+ 2128818,
+ 2128822,
+ 2128826,
+ 2128827,
+ 2128829,
+ 2128834,
+ 2128840,
+ 2128859,
+ 2128884,
+ 2128885,
+ 2128889,
+ 2128890,
+ 2128898,
+ 2128900,
+ 2128902,
+ 2128908,
+ 2128921,
+ 2128923,
+ 2128933,
+ 2128940,
+ 2128948,
+ 2128953,
+ 2128954,
+ 2128966,
+ 2128981,
+ 2128986,
+ 2128995,
+ 4226153,
+ 2129020,
+ 2129030,
+ 2129072,
+ 2129083,
+ 2129103,
+ 2129108,
+ 2129129,
+ 2129167,
+ 2129169,
+ 2129174,
+ 2129190,
+ 2129194,
+ 2129197,
+ 2129233,
+ 2129239,
+ 2129253,
+ 2129255,
+ 2129272,
+ 2129275,
+ 2129281,
+ 2129302,
+ 2129347,
+ 2129348,
+ 2129349,
+ 2129350,
+ 2129357,
+ 2129358,
+ 2129408,
+ 2129378,
+ 2129386,
+ 2129389,
+ 2129402,
+ 2129436,
+ 2129453,
+ 2129459,
+ 2129471,
+ 2129486,
+ 2129488,
+ 2129496,
+ 2129503,
+ 2129509,
+ 2129557,
+ 2129565,
+ 2129566,
+ 2129727,
+ 2129756,
+ 2129766,
+ 4226944,
+ 2129805,
+ 2129807,
+ 2129830,
+ 2129834,
+ 2129844,
+ 2129852,
+ 2129856,
+ 2129864,
+ 2129896,
+ 2129935,
+ 2129939,
+ 2129949,
+ 2129951,
+ 2129952,
+ 2129966,
+ 2129972,
+ 2129982,
+ 2129984,
+ 2129988,
+ 2130020,
+ 2130029,
+ 2130049,
+ 2130105,
+ 2130120,
+ 2130125,
+ 2130130,
+ 2130158,
+ 2130162,
+ 2130166,
+ 2130169,
+ 2130187,
+ 2130204,
+ 2130208,
+ 2130236,
+ 2130245,
+ 2130247,
+ 2130258,
+ 2130273,
+ 2130295,
+ 2130310,
+ 2130318,
+ 2130326,
+ 2130338,
+ 2130350,
+ 2130373,
+ 2130382,
+ 2130411,
+ 2130416,
+ 2130417,
+ 2130418,
+ 2130421,
+ 2130424,
+ 4227584,
+ 2130447,
+ 2130461,
+ 2130472,
+ 2130499,
+ 2130510,
+ 2130513,
+ 2130518,
+ 2130535,
+ 2130555,
+ 2130560,
+ 2130561,
+ 2130567,
+ 2130580,
+ 2130582,
+ 2130584,
+ 2130586,
+ 2130587,
+ 2130592,
+ 2130650,
+ 2130656,
+ 2130660,
+ 2130669,
+ 2130698,
+ 2130699,
+ 2130718,
+ 2130719,
+ 2130721,
+ 2130732,
+ 2130734,
+ 2130739,
+ 2130743,
+ 2130749,
+ 2130754,
+ 2130765,
+ 2130766,
+ 2130800,
+ 2130816,
+ 2130818,
+ 2130820,
+ 2130841,
+ 2130844,
+ 2130854,
+ 2130860,
+ 2130878,
+ 2130771,
+ 2130920,
+ 2130969,
+ 2130861,
+ 2130991,
+ 2131013,
+ 2131015,
+ 2131021,
+ 2131030,
+ 4228188,
+ 2131040,
+ 2131044,
+ 2131047,
+ 2131050,
+ 2131060,
+ 2131069,
+ 2131090,
+ 2131093,
+ 2131113,
+ 2131114,
+ 2131143,
+ 2131144,
+ 2131148,
+ 2131186,
+ 2131191,
+ 2131202,
+ 2131203,
+ 2131207,
+ 2131214,
+ 2131216,
+ 2131228,
+ 2131234,
+ 2131239,
+ 2131242,
+ 2131251,
+ 2131254,
+ 2131263,
+ 2131280,
+ 2131282,
+ 2131292,
+ 4228445,
+ 2131295,
+ 2131296,
+ 2131321,
+ 2131337,
+ 2131339,
+ 2131360,
+ 2131365,
+ 2131367,
+ 2131380,
+ 2131382,
+ 2131384,
+ 2131389,
+ 2131390,
+ 2131391,
+ 2131394,
+ 2131418,
+ 2131424,
+ 2131432,
+ 2131443,
+ 2131452,
+ 2131469,
+ 2131470,
+ 2131481,
+ 2131483,
+ 2131510,
+ 2131514,
+ 2131517,
+ 2131544,
+ 2131545,
+ 2131549,
+ 2131552,
+ 2131553,
+ 2131556,
+ 2131561,
+ 2131574,
+ 2131606,
+ 2131610,
+ 2131617,
+ 2131622,
+ 2131629,
+ 2131636,
+ 2131637,
+ 2131639,
+ 2131641,
+ 2131647,
+ 2131653,
+ 2131666,
+ 2131674,
+ 2131676,
+ 2131680,
+ 2131685,
+ 2131687,
+ 2131592,
+ 2131716,
+ 2131727,
+ 2131759,
+ 2131762,
+ 2131772,
+ 2131773,
+ 2131781,
+ 2131789,
+ 2131809,
+ 2131823,
+ 2131843,
+ 2131844,
+ 2131845,
+ 2131846,
+ 2131856,
+ 2131861,
+ 4229027,
+ 2131889,
+ 2131912,
+ 2131914,
+ 2131925,
+ 2131929,
+ 2131932,
+ 2131938,
+ 2131940,
+ 2131953,
+ 2131955,
+ 2131960,
+ 2131962,
+ 2131967,
+ 2131977,
+ 2131993,
+ 2131986,
+ 2131994,
+ 2131998,
+ 2132016,
+ 2132021,
+ 2132033,
+ 2132035,
+ 2132040,
+ 2132041,
+ 4229195,
+ 2132049,
+ 2132060,
+ 2132064,
+ 2132081,
+ 2132089,
+ 2132091,
+ 2132096,
+ 2132127,
+ 2132136,
+ 2132154,
+ 2132171,
+ 2132172,
+ 2132190,
+ 2132199,
+ 2132215,
+ 2132237,
+ 2132245,
+ 2132246,
+ 2132256,
+ 2132264,
+ 2132273,
+ 2132282,
+ 2132294,
+ 2132303,
+ 2132306,
+ 2132311,
+ 2132315,
+ 2132321,
+ 2132323,
+ 2132334,
+ 2132339,
+ 2132341,
+ 2132346,
+ 2132349,
+ 2132365,
+ 2132373,
+ 2132379,
+ 2132380,
+ 2132384,
+ 2132404,
+ 2132406,
+ 2132439,
+ 2132457,
+ 2132461,
+ 2132473,
+ 2132484,
+ 2132485,
+ 2132510,
+ 2132512,
+ 2132516,
+ 2132518,
+ 2132523,
+ 2132524,
+ 2132527,
+ 2132541,
+ 2132544,
+ 2132547,
+ 2132563,
+ 2132566,
+ 2132572,
+ 2132581,
+ 2132598,
+ 2132599,
+ 2132602,
+ 2132603,
+ 2132608,
+ 2132611,
+ 2132619,
+ 2132623,
+ 2132626,
+ 2132631,
+ 2132633,
+ 2132639,
+ 2132649,
+ 2132655,
+ 2132659,
+ 2132667,
+ 2132675,
+ 2132678,
+ 2132680,
+ 2132682,
+ 2132691,
+ 2132692,
+ 2132693,
+ 2132720,
+ 2132735,
+ 2132747,
+ 2132766,
+ 2132784,
+ 2132796,
+ 2132802,
+ 2132808,
+ 2132813,
+ 2132835,
+ 2132857,
+ 2132868,
+ 2132877,
+ 2132879,
+ 2133048,
+ 2133054,
+ 2133073,
+ 2133080,
+ 2133083,
+ 2133085,
+ 2133081,
+ 2133091,
+ 2133092,
+ 2133094,
+ 2133109,
+ 2133110,
+ 2133118,
+ 2133126,
+ 2133127,
+ 2133131,
+ 2133136,
+ 4230299,
+ 2133148,
+ 2133177,
+ 2133190,
+ 2133195,
+ 2133199,
+ 2133213,
+ 2133224,
+ 2133231,
+ 2133234,
+ 2133247,
+ 2133349,
+ 2133375,
+ 2133378,
+ 2133384,
+ 2133392,
+ 2133406,
+ 2133408,
+ 2133420,
+ 2133429,
+ 2133431,
+ 2133433,
+ 2133435,
+ 2133440,
+ 2133445,
+ 2133447,
+ 2133450,
+ 2133460,
+ 2133477,
+ 2133488,
+ 2133436,
+ 2133508,
+ 2133509,
+ 2133521,
+ 2133555,
+ 2133559,
+ 2133560,
+ 2133582,
+ 2133595,
+ 2133597,
+ 2133598,
+ 2133625,
+ 2133634,
+ 2133635,
+ 2133659,
+ 2133661,
+ 2133666,
+ 2133690,
+ 2133697,
+ 2133699,
+ 2133700,
+ 2133703,
+ 2133724,
+ 2133742,
+ 2133745,
+ 2133751,
+ 2133741,
+ 2133762,
+ 2133775,
+ 2133776,
+ 2133782,
+ 2133792,
+ 2133793,
+ 2133795,
+ 2133800,
+ 2133806,
+ 2133812,
+ 2133815,
+ 2133825,
+ 2133839,
+ 2133842,
+ 2133843,
+ 2133853,
+ 2133854,
+ 2133861,
+ 2133917,
+ 2133944,
+ 2133950,
+ 2133952,
+ 2133963,
+ 2133968,
+ 2133970,
+ 2133987,
+ 2134014,
+ 2134040,
+ 2134056,
+ 2134057,
+ 2134058,
+ 2134067,
+ 2134068,
+ 2134079,
+ 2134114,
+ 2134118,
+ 2134124,
+ 2134158,
+ 2134181,
+ 2134220,
+ 2134229,
+ 2134232,
+ 2134233,
+ 2134245,
+ 2134226,
+ 2134280,
+ 2134285,
+ 2134288,
+ 2134298,
+ 2134304,
+ 2134313,
+ 2134318,
+ 2134326,
+ 2134332,
+ 2134339,
+ 2134351,
+ 2134355,
+ 2134381,
+ 2134395,
+ 2134401,
+ 2134406,
+ 2134419,
+ 2134420,
+ 2134424,
+ 2134433,
+ 2134438,
+ 2134463,
+ 2134483,
+ 2134484,
+ 2134489,
+ 2134505,
+ 2134506,
+ 2134511,
+ 2134521,
+ 2134525,
+ 2134532,
+ 2134533,
+ 2134540,
+ 2134546,
+ 2134547,
+ 2134552,
+ 2134556,
+ 2134557,
+ 2134564,
+ 2134565,
+ 2134566,
+ 2134574,
+ 2134575,
+ 2134576,
+ 2134581,
+ 2134582,
+ 2134590,
+ 2134598,
+ 2134605,
+ 2134616,
+ 2134620,
+ 2134621,
+ 2134633,
+ 2134638,
+ 2134639,
+ 2134640,
+ 2134645,
+ 2134649,
+ 2134651,
+ 2134666,
+ 2134674,
+ 2134688,
+ 2134692,
+ 2134693,
+ 2134696,
+ 2134710,
+ 2134712,
+ 2134714,
+ 2134717,
+ 2134727,
+ 2134733,
+ 2134744,
+ 2134748,
+ 2134749,
+ 2134753,
+ 2134755,
+ 2134760,
+ 2134764,
+ 2134766,
+ 2134768,
+ 2134784,
+ 2134792,
+ 2134812,
+ 2134820,
+ 2134826,
+ 2134836,
+ 2134839,
+ 2134864,
+ 2134869,
+ 2134878,
+ 2134887,
+ 2134889,
+ 2134895,
+ 2134900,
+ 2134902,
+ 2134906,
+ 2134909,
+ 2134912,
+ 2134913,
+ 2134925,
+ 2134930,
+ 2134933,
+ 2134936,
+ 4232097,
+ 2134950,
+ 2134952,
+ 2134955,
+ 2134964,
+ 2134965,
+ 2134966,
+ 2134980,
+ 2134981,
+ 2134985,
+ 2134987,
+ 2134989,
+ 2134995,
+ 2135001,
+ 2135031,
+ 2135041,
+ 2135048,
+ 2135061,
+ 2135071,
+ 2135087,
+ 2135101,
+ 2135107,
+ 2135129,
+ 2135132,
+ 2135135,
+ 2135137,
+ 2135144,
+ 2135150,
+ 2135172,
+ 2135171,
+ 2135422,
+ 2135428,
+ 2135453,
+ 2135454,
+ 2135482,
+ 2135513,
+ 2135517,
+ 2135519,
+ 2135582,
+ 2135586,
+ 2135589,
+ 2135590,
+ 2135607,
+ 2135609,
+ 2135610,
+ 2135634,
+ 2135638,
+ 2135639,
+ 2135662,
+ 2135676,
+ 2135678,
+ 2135697,
+ 2135711,
+ 2135718,
+ 2135754,
+ 4232922,
+ 2135775,
+ 2135802,
+ 2135813,
+ 2135834,
+ 2135837,
+ 4232993,
+ 2135882,
+ 2135896,
+ 2135927,
+ 2135928,
+ 2135931,
+ 2135936,
+ 2135945,
+ 2135959,
+ 2135992,
+ 2135996,
+ 2135999,
+ 2136004,
+ 2136005,
+ 2136007,
+ 2136010,
+ 2136014,
+ 2136016,
+ 2136023,
+ 2136029,
+ 2136036,
+ 2136055,
+ 2136056,
+ 2136058,
+ 2136089,
+ 2136092,
+ 2136096,
+ 2136111,
+ 2136117,
+ 2136132,
+ 2136138,
+ 2136145,
+ 2136170,
+ 2136238,
+ 2136268,
+ 2136294,
+ 2136310,
+ 2136327,
+ 2136351,
+ 2136354,
+ 2136358,
+ 2136363,
+ 2136372,
+ 2136377,
+ 2136391,
+ 2136409,
+ 2136411,
+ 2136475,
+ 2136477,
+ 2136479,
+ 2136496,
+ 2136498,
+ 2136501,
+ 2136531,
+ 2136538,
+ 2136540,
+ 2136551,
+ 2136554,
+ 2136555,
+ 2136556,
+ 2136564,
+ 2136565,
+ 2136573,
+ 2136574,
+ 2136580,
+ 2136587,
+ 2136606,
+ 2136610,
+ 2136627,
+ 2136629,
+ 2136647,
+ 4233802,
+ 2136651,
+ 2136660,
+ 2136669,
+ 2136746,
+ 2136748,
+ 2136750,
+ 2136754,
+ 2136756,
+ 2136763,
+ 2136767,
+ 2136776,
+ 2136791,
+ 2136795,
+ 2136804,
+ 2136807,
+ 2136812,
+ 2136818,
+ 2136819,
+ 2136821,
+ 2136826,
+ 2136829,
+ 2136831,
+ 2136832,
+ 2136836,
+ 2136837,
+ 2136859,
+ 2136870,
+ 4234037,
+ 2136887,
+ 2136889,
+ 2136890,
+ 2136908,
+ 2136918,
+ 2136919,
+ 2136923,
+ 2136929,
+ 2136938,
+ 2136941,
+ 2136942,
+ 2136952,
+ 2136959,
+ 2136965,
+ 2136967,
+ 2136969,
+ 2136971,
+ 2136973,
+ 2136980,
+ 2136986,
+ 2137001,
+ 2137015,
+ 2137020,
+ 2137040,
+ 2137081,
+ 2137103,
+ 2137105,
+ 2137118,
+ 2137126,
+ 2137128,
+ 2137149,
+ 2137155,
+ 2137166,
+ 2137182,
+ 2137211,
+ 2137335,
+ 2137337,
+ 2137372,
+ 2137391,
+ 2137395,
+ 2137396,
+ 2137402,
+ 2137404,
+ 2137413,
+ 2137427,
+ 2137428,
+ 2137445,
+ 2137475,
+ 2137478,
+ 2137486,
+ 2137490,
+ 2137491,
+ 2137493,
+ 2137495,
+ 2137496,
+ 2137514,
+ 2137518,
+ 4234687,
+ 2137546,
+ 2137556,
+ 2137557,
+ 2137566,
+ 2137582,
+ 2137584,
+ 2137598,
+ 2137614,
+ 2137616,
+ 2137617,
+ 2137618,
+ 2137622,
+ 2137735,
+ 2137742,
+ 2137743,
+ 2137750,
+ 2137752,
+ 2137774,
+ 2137779,
+ 2137798,
+ 2137800,
+ 2137803,
+ 2137813,
+ 2137836,
+ 2137837,
+ 2137841,
+ 2137845,
+ 2137848,
+ 2137873,
+ 2137878,
+ 2137882,
+ 2137887,
+ 2137905,
+ 2137906,
+ 2137916,
+ 2137919,
+ 2137923,
+ 2137924,
+ 2137927,
+ 2137942,
+ 2137950,
+ 2137966,
+ 2137971,
+ 2137978,
+ 2137981,
+ 2137999,
+ 2138001,
+ 2138002,
+ 2138006,
+ 2138017,
+ 2138019,
+}}
diff --git a/macros/luatex/generic/luatexja/src/ltj-jfmglue.lua b/macros/luatex/generic/luatexja/src/ltj-jfmglue.lua
new file mode 100644
index 0000000000..f94b028452
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-jfmglue.lua
@@ -0,0 +1,1375 @@
+--
+-- luatexja/ltj-jfmglue.lua
+--
+luatexbase.provides_module({
+ name = 'luatexja.jfmglue',
+ date = '2019/07/26',
+ description = 'Insertion process of JFM glues, [x]kanjiskip and others',
+})
+luatexja.jfmglue = luatexja.jfmglue or {}
+
+luatexja.load_module('base'); local ltjb = luatexja.base
+luatexja.load_module('stack'); local ltjs = luatexja.stack
+luatexja.load_module('jfont'); local ltjf = luatexja.jfont
+luatexja.load_module('direction'); local ltjd = luatexja.direction
+luatexja.load_module('setwidth'); local ltjw = luatexja.setwidth
+local pairs = pairs
+
+--local to_node = node.direct.tonode
+--local to_direct = node.direct.todirect
+
+local setfield = node.direct.setfield
+local setglue = luatexja.setglue
+local getfield = node.direct.getfield
+local getid = node.direct.getid
+local getfont = node.direct.getfont
+local getlist = node.direct.getlist
+local getchar = node.direct.getchar
+local getsubtype = node.direct.getsubtype
+local if_lang_ja
+do
+ local lang_ja = luatexja.lang_ja
+ local getlang = node.direct.getlang
+ if_lang_ja = getlang
+ and function (n) return getlang(n)==lang_ja end
+ or function (n) return getfield(n,'lang')==lang_ja end
+end
+
+local has_attr = node.direct.has_attribute
+local set_attr = node.direct.set_attribute
+local insert_before = node.direct.insert_before
+local insert_after = node.direct.insert_after
+local node_next = node.direct.getnext
+local ltjd_make_dir_whatsit = ltjd.make_dir_whatsit
+local ltjf_font_metric_table = ltjf.font_metric_table
+local ltjf_find_char_class = ltjf.find_char_class
+local node_new = node.direct.new
+local node_copy = node.direct.copy
+local node_tail = node.direct.tail
+local node_free = node.direct.free
+local node_remove = node.direct.remove
+
+local id_glyph = node.id('glyph')
+local id_hlist = node.id('hlist')
+local id_vlist = node.id('vlist')
+local id_rule = node.id('rule')
+local id_ins = node.id('ins')
+local id_mark = node.id('mark')
+local id_adjust = node.id('adjust')
+local id_disc = node.id('disc')
+local id_whatsit = node.id('whatsit')
+local id_math = node.id('math')
+local id_glue = node.id('glue')
+local id_kern = node.id('kern')
+local id_penalty = node.id('penalty')
+
+local id_jglyph = 512 -- Japanese character
+local id_box_like = 256 -- vbox, shifted hbox
+local id_pbox = 257 -- already processed nodes (by \unhbox)
+local id_pbox_w = 258 -- cluster which consists of a whatsit
+local sid_user = node.subtype('user_defined')
+
+local ITALIC = luatexja.icflag_table.ITALIC
+local PACKED = luatexja.icflag_table.PACKED
+local KINSOKU = luatexja.icflag_table.KINSOKU
+local FROM_JFM = luatexja.icflag_table.FROM_JFM
+local PROCESSED = luatexja.icflag_table.PROCESSED
+local IC_PROCESSED = luatexja.icflag_table.IC_PROCESSED
+local BOXBDD = luatexja.icflag_table.BOXBDD
+local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
+
+local attr_icflag = luatexbase.attributes['ltj@icflag']
+local kanji_skip
+local xkanji_skip
+local table_current_stack
+local list_dir
+local capsule_glyph
+local tex_dir
+local attr_ablshift
+local set_np_xspc_jachar, set_np_xspc_alchar
+local set_np_xspc_jachar_hbox
+
+local ltjs_orig_char_table = ltjs.orig_char_table
+
+local function get_attr_icflag(p)
+ return (has_attr(p, attr_icflag) or 0)%PROCESSED_BEGIN_FLAG
+end
+
+-------------------- Helper functions
+
+-- This function is called only for acquiring `special' characters.
+local function fast_find_char_class(c,m)
+ return m.chars[c] or 0
+end
+
+-- 文字クラスã®æ±ºå®š
+local slow_find_char_class
+do
+ local start_time_measure = ltjb.start_time_measure
+ local stop_time_measure = ltjb.stop_time_measure
+ slow_find_char_class = function (c, m, oc)
+ local cls = ltjf_find_char_class(oc, m)
+ if oc~=c and c and cls==0 then
+ return ltjf_find_char_class(c, m)
+ else
+ return cls
+ end
+ end
+end
+
+local function skip_table_to_glue(n)
+ local g, st = node_new(id_glue), ltjs.fast_get_stack_skip(n)
+ setglue(g, st.width, st.stretch, st.shrink, st.stretch_order, st.shrink_order)
+ return g, (st.width==1073741823)
+end
+
+
+-- penalty 値ã®è¨ˆç®—
+local add_penalty
+do
+local setpenalty = node.direct.setpenalty or function(n, a) setfield(n,'penalty',a) end
+local getpenalty = node.direct.getpenalty or function(n) return getfield(n,'penalty') end
+function add_penalty(p,e)
+ local pp = getpenalty(p)
+ if (pp>-10000) and (pp<10000) then
+ if e>=10000 then setpenalty(p, 10000)
+ elseif e<=-10000 then setpenalty(p, -10000)
+ else
+ pp = pp + e
+ if pp>=10000 then setpenalty(p, 10000)
+ elseif pp<=-10000 then setpenalty(p, -10000)
+ else setpenalty(p, pp) end
+ end
+ end
+end
+end
+
+-- 「異ãªã‚‹ JFMã€ã®é–“ã®èª¿æ•´æ–¹æ³•
+luatexja.jfmglue.diffmet_rule = math.two_paverage
+function math.two_add(a,b) return a+b end
+function math.two_average(a,b) return (a+b)*0.5 end
+function math.two_paverage(a,b) return (a+b)/2 end
+function math.two_pleft(a,b) return a end
+function math.two_pright(a,b) return b end
+
+local head -- the head of current list
+
+local Np, Nq, Bp
+local widow_Bp, widow_Np -- \jcharwidowpenalty 挿入ä½ç½®ç®¡ç†ç”¨
+
+local non_ihb_flag -- JFM グルー挿入抑止用 flag
+-- false: \inhibitglue 指定時 true: ãれ以外
+
+-------------------- hlist 内ã®æ–‡å­—ã®æ¤œç´¢
+
+local first_char, last_char, find_first_char
+local check_box_high
+do
+local ltjd_glyph_from_packed = ltjd.glyph_from_packed
+local function check_box(box_ptr, box_end)
+ local p = box_ptr; local found_visible_node = false
+ if not p then
+ find_first_char = false; last_char = nil
+ return true
+ end
+ while p and p~=box_end do
+ local pid = getid(p)
+ if pid==id_kern and getsubtype(p)==2 then
+ p = node_next(node_next(node_next(p))); pid = getid(p) -- p must be glyph_node
+ end
+ if pid==id_glyph then
+ repeat
+ if find_first_char then
+ first_char = p; find_first_char = false
+ end
+ last_char = p; found_visible_node = true; p=node_next(p)
+ if (not p) or p==box_end then
+ return found_visible_node
+ end
+ until getid(p)~=id_glyph
+ pid = getid(p) -- p must be non-nil
+ end
+ if pid==id_kern then
+ local pa = get_attr_icflag(p)
+ if pa==IC_PROCESSED then
+ -- do nothing
+ elseif getsubtype(p)==2 then
+ p = node_next(node_next(p));
+ -- Note that another node_next will be executed outside this if-statement.
+ else
+ found_visible_node = true
+ find_first_char = false; last_char = nil
+ end
+ elseif pid==id_hlist then
+ if PACKED == get_attr_icflag(p) then
+ local s = ltjd_glyph_from_packed(p)
+ if find_first_char then
+ first_char = s; find_first_char = false
+ end
+ last_char = s; found_visible_node = true
+ else
+ if getfield(p, 'shift')==0 then
+ last_char = nil
+ if check_box(getlist(p), nil) then found_visible_node = true end
+ find_first_char = false
+ else
+ find_first_char = false; last_char = nil
+ end
+ end
+ elseif pid==id_math then
+ if find_first_char then
+ first_char = p; find_first_char = false
+ end
+ last_char = p; found_visible_node = true
+ elseif pid==id_rule and get_attr_icflag(p)==PACKED then
+ -- do nothing
+ elseif not (pid==id_ins or pid==id_mark
+ or pid==id_adjust or pid==id_whatsit
+ or pid==id_penalty) then
+ found_visible_node = true
+ find_first_char = false; last_char = nil
+ end
+ p = node_next(p)
+ end
+ return found_visible_node
+end
+
+check_box_high = function (Nx, box_ptr, box_end)
+ first_char = nil; last_char = nil; find_first_char = true
+ if check_box(box_ptr, box_end) then
+ local first_char = first_char
+ if first_char then
+ if getid(first_char)==id_glyph then
+ if if_lang_ja(first_char) then
+ set_np_xspc_jachar_hbox(Nx, first_char)
+ else
+ set_np_xspc_alchar(Nx, getchar(first_char),first_char, 1)
+ end
+ else -- math_node
+ set_np_xspc_alchar(Nx, -1,first_char)
+ end
+ end
+ end
+ return last_char
+end
+end
+-------------------- Np ã®è¨ˆç®—ã¨æƒ…å ±å–å¾—
+
+luatexbase.create_callback("luatexja.jfmglue.whatsit_getinfo", "data",
+ function (Np, lp, Nq)
+ if Np.nuc then return Np
+ else
+ return Np -- your code
+ end
+ end)
+luatexbase.create_callback("luatexja.jfmglue.whatsit_after", "data",
+ function (stat, Nq, Np) return false end)
+
+-- calc next Np
+local calc_np
+do -- 001 -----------------------------------------------
+
+local traverse = node.direct.traverse
+local function check_next_ickern(lp)
+ local lx = Np.nuc
+ while lp and getid(lp) == id_kern and ( getsubtype(lp)==0 or
+ getsubtype(lp)==3 or ITALIC == get_attr_icflag(lp)) do
+ set_attr(lp, attr_icflag, IC_PROCESSED);
+ lx, lp = lp, node_next(lp)
+ end
+ Np.last = lx; return lp
+end
+
+local function calc_np_pbox(lp, last)
+ local first, nc = (not Np.first), nil
+ --local lpa = get_attr_icflag(lp)==PACKED and PACKED or KINSOKU -- KINSOKU: dummy
+ local lpa = get_attr_icflag(lp)
+ Np.first = Np.first or lp; Np.id = id_pbox
+ set_attr(lp, attr_icflag, get_attr_icflag(lp));
+ while lp ~=last and (lpa>=PACKED) and (lpa<BOXBDD) do
+ local lpi = getid(lp)
+ if lpa==PACKED then
+ if lpi==id_rule then lp = node_next(lp) end
+ nc, lp = lp, node_next(lp)
+ elseif lpi==id_hlist or lpi==id_vlist then
+ head, lp, nc = ltjd_make_dir_whatsit(head, lp, list_dir, 'jfm pbox')
+ Np.first = first and nc or Np.first
+ else
+ nc, lp = lp, node_next(lp)
+ end
+ first, lpa = false, (lp and has_attr(lp, attr_icflag) or 0)
+ -- get_attr_icflag() ã§ã¯ã„ã‘ãªã„ï¼
+ end
+ Np.nuc = nc
+ lp = check_next_ickern(lp)
+ Np.last_char = check_box_high(Np, Np.first, lp)
+ return lp
+end
+
+local calc_np_aux_glyph_common
+do -- 002 ---------------------------------------
+ local min, max = math.min, math.max
+ local getwhd = node.direct.getwhd
+ local attr_jchar_class = luatexbase.attributes['ltj@charclass']
+ local attr_jchar_code = luatexbase.attributes['ltj@charcode']
+ local identifiers = fonts.hashes.identifiers
+ local function calc_np_notdef(lp)
+ local ident = identifiers[getfont(lp)]
+ if not ident.descriptions[getchar(lp)] then
+ local ln = node_next(lp)
+ if (ident.shared and ident.shared.features and ident.shared.features.notdef)
+ and ln and getid(ln)==id_glyph then
+ set_attr(lp, attr_icflag, PROCESSED)
+ set_attr(ln, attr_jchar_code, has_attr(lp, attr_jchar_code) or getchar(lp))
+ set_attr(ln, attr_jchar_class, has_attr(lp, attr_jchar_class) or 0)
+ Np.nuc, lp = ln, ln
+ end
+ end
+ return lp
+ end
+function calc_np_aux_glyph_common(lp, acc_flag)
+ Np.nuc, Np.first = lp, (Np.first or lp)
+ if if_lang_ja(lp) then -- JAchar
+ Np.id = id_jglyph
+ local m, mc, cls = set_np_xspc_jachar(Np, lp)
+ local npi, npf
+ local w, h, d = getwhd(lp)
+ if w==0 and h==0 and d==0 then lp = calc_np_notdef(lp) end
+ lp, head, npi, npf = capsule_glyph(lp, m, mc[cls], head, tex_dir)
+ Np.first = (Np.first~=Np.nuc) and Np.first or npf or npi
+ Np.nuc = npi
+ return true, check_next_ickern(lp);
+ else --ALchar
+ Np.id = id_glyph
+ set_np_xspc_alchar(Np, getchar(lp), lp, 1)
+ -- loop
+ local first_glyph, last_glyph = lp
+ set_attr(lp, attr_icflag, PROCESSED); Np.last = lp
+ local y_adjust = has_attr(lp,attr_ablshift) or 0
+ local node_depth = getfield(lp, 'depth') + min(y_adjust, 0)
+ local adj_depth = (y_adjust>0) and (getfield(lp, 'depth') + y_adjust) or 0
+ setfield(lp, 'yoffset', getfield(lp, 'yoffset') - y_adjust)
+ lp = node_next(lp)
+ for lx in traverse(lp) do
+ local lai = get_attr_icflag(lx)
+ if lx==last or lai>=PACKED then
+ lp=lx; break
+ else
+ local lid = getid(lx)
+ if lid==id_glyph and not if_lang_ja(lx) then
+ -- 欧文文字
+ last_glyph = lx; set_attr(lx, attr_icflag, PROCESSED); Np.last = lx
+ y_adjust = has_attr(lx,attr_ablshift) or 0
+ node_depth = max(getfield(lx, 'depth') + min(y_adjust, 0), node_depth)
+ adj_depth = (y_adjust>0) and max(getfield(lx, 'depth') + y_adjust, adj_depth) or adj_depth
+ setfield(lx, 'yoffset', getfield(lx, 'yoffset') - y_adjust)
+ elseif lid==id_kern then
+ local ls = getsubtype(lx)
+ if ls==2 then -- アクセント用㮠kern
+ set_attr(lx, attr_icflag, PROCESSED)
+ lx = node_next(lx) -- lx: アクセント本体
+ if getid(lx)==id_glyph then
+ setfield(lx, 'yoffset', getfield(lx, 'yoffset') - (has_attr(lx,attr_ablshift) or 0))
+ else -- アクセントã¯ä¸Šä¸‹ã«ã‚·ãƒ•ãƒˆã•ã‚Œã¦ã„ã‚‹
+ setfield(lx, 'shift', getfield(lx, 'shift') + (has_attr(lx,attr_ablshift) or 0))
+ end
+ lx = node_next(node_next(lx))
+ elseif ls==0 then
+ Np.last = lx
+ elseif (ls==3) or (lai==ITALIC) then
+ Np.last = lx; set_attr(lx, attr_icflag, IC_PROCESSED)
+ else
+ lp=lx; break
+ end
+ else
+ lp=lx; break
+ end
+ end
+ end
+ local r
+ if adj_depth>node_depth then
+ r = node_new(id_rule,3)
+ setfield(r, 'width', 0); setfield(r, 'height', 0)
+ setfield(r, 'depth',adj_depth); setfield(r, 'dir', tex_dir)
+ set_attr(r, attr_icflag, PROCESSED)
+ end
+ if last_glyph then
+ Np.last_char = last_glyph
+ if r then insert_after(head, first_glyph, r) end
+ else
+ local npn = Np.nuc
+ Np.last_char = npn
+ if r then
+ local nf, nc = getfont(npn), getchar(npn)
+ local ct = (font.getfont(nf) or font.fonts[nf] ).characters[nc]
+ if not ct then -- variation selector
+ node_free(r)
+ elseif (ct.left_protruding or 0) == 0 then
+ head = insert_before(head, npn, r)
+ Np.first = acc_flag and Np.first or ((Np.first==npn) and r or npn)
+ elseif (ct.right_protruding or 0) == 0 then
+ insert_after(head, npn, r); Np.last, lp = r, r
+ else
+ ltjb.package_warning_no_line(
+ 'luatexja',
+ 'Check depth of glyph node ' .. tostring(npn) .. '(font=' .. nf
+ .. ', char=' .. nc .. '), because its \\lpcode is ' .. tostring(ct.left_protruding)
+ .. ' and its \\rpcode is ' .. tostring(ct.right_protruding)
+ ); node_free(r)
+ end
+ end
+ end
+ return true, lp
+ end
+end
+end -- 002 ---------------------------------------
+local calc_np_auxtable
+do -- 002 ---------------------------------------
+local ltjw_apply_ashift_math = ltjw.apply_ashift_math
+local ltjw_apply_ashift_disc = ltjw.apply_ashift_disc
+local node_end_of_math = node.direct.end_of_math
+local dir_tate = luatexja.dir_table.dir_tate
+local sid_start_link = node.subtype('pdf_start_link')
+local sid_start_thread = node.subtype('pdf_start_thread')
+local sid_end_link = node.subtype('pdf_end_link')
+local sid_end_thread = node.subtype('pdf_end_thread')
+calc_np_auxtable = {
+ [id_glyph] = calc_np_aux_glyph_common,
+ [id_hlist] = function(lp)
+ local op, flag
+ head, lp, op, flag = ltjd_make_dir_whatsit(head, lp, list_dir, 'jfm hlist')
+ set_attr(op, attr_icflag, PROCESSED)
+ Np.first = Np.first or op; Np.last = op; Np.nuc = op;
+ if (flag or getfield(op, 'shift')~=0) then
+ Np.id = id_box_like
+ else
+ Np.id = id_hlist
+ Np.last_char = check_box_high(Np, getlist(op), nil)
+ end
+ return true, lp
+ end,
+ [id_vlist] = function(lp)
+ local op
+ head, lp, op = ltjd_make_dir_whatsit(head, lp, list_dir, 'jfm:' .. getid(lp))
+ Np.first = Np.first or op; Np.last = op; Np.nuc = op;
+ Np.id = id_box_like;
+ return true, lp
+ end,
+ box_like = function(lp)
+ Np.first = Np.first or lp; Np.last = lp; Np.nuc = lp;
+ Np.id = id_box_like;
+ return true, node_next(lp)
+ end,
+ [id_whatsit] = function(lp)
+ local lps = getsubtype(lp)
+ if lps==sid_user then
+ if getfield(lp, 'user_id')==luatexja.userid_table.IHB then
+ local lq = node_next(lp);
+ head = node_remove(head, lp); node_free(lp); non_ihb_flag = false
+ return false, lq;
+ elseif getfield(lp, 'user_id')==luatexja.userid_table.JA_AL_BDD then
+ local lq = node_next(lp);
+ head = node_remove(head, lp); node_free(lp)
+ return false, lq;
+ else
+ set_attr(lp, attr_icflag, PROCESSED)
+ luatexbase.call_callback("luatexja.jfmglue.whatsit_getinfo",
+ Np, lp, Nq)
+ if Np.nuc then
+ Np.id = id_pbox_w; Np.first = Np.nuc; Np.last = Np.nuc;
+ return true, node_next(lp)
+ else
+ return false, node_next(lp)
+ end
+ end
+ else
+ -- we do special treatment for these whatsit nodes.
+ if lps == sid_start_link or lps == sid_start_thread then
+ Np.first = lp
+ elseif lps == sid_end_link or lps == sid_end_thread then
+ Np.first, Nq.last = nil, lp;
+ end
+ set_attr(lp, attr_icflag, PROCESSED)
+ return false, node_next(lp)
+ end
+ end,
+ [id_math] = function(lp)
+ Np.first, Np.nuc = (Np.first or lp), lp;
+ set_attr(lp, attr_icflag, PROCESSED)
+ set_np_xspc_alchar(Np, -1, lp)
+ local end_math = node_end_of_math(lp)
+ ltjw_apply_ashift_math(lp, end_math, attr_ablshift)
+ set_attr(end_math, attr_icflag, PROCESSED)
+ Np.last, Np.id = end_math, id_math;
+ return true, node_next(end_math);
+ end,
+ [id_glue] = function(lp)
+ Np.first, Np.nuc, Np.last = (Np.first or lp), lp, lp;
+ Np.id = getid(lp); set_attr(lp, attr_icflag, PROCESSED)
+ return true, node_next(lp)
+ end,
+ [id_disc] = function(lp)
+ Np.first, Np.nuc, Np.last = (Np.first or lp), lp, lp;
+ Np.id = getid(lp); set_attr(lp, attr_icflag, PROCESSED)
+ ltjw_apply_ashift_disc(lp, (list_dir==dir_tate), tex_dir)
+ Np.last_char = check_box_high(Np, getfield(lp, 'replace'), nil)
+ return true, node_next(lp)
+ end,
+ [id_kern] = function(lp)
+ if getsubtype(lp)==2 then
+ Np.first = Np.first or lp
+ set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp)
+ if getid(lp)==id_glyph then -- アクセント本体
+ setfield(lp, 'yoffset', getfield(lp, 'yoffset') - (has_attr(lp,attr_ablshift) or 0))
+ else -- アクセントã¯ä¸Šä¸‹ã«ã‚·ãƒ•ãƒˆã•ã‚Œã¦ã„ã‚‹
+ setfield(lp, 'shift', getfield(lp, 'shift') + (has_attr(lp,attr_ablshift) or 0))
+ end
+ set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp)
+ set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp)
+ set_attr(lp, attr_icflag, PROCESSED);
+ return calc_np_aux_glyph_common(lp, true)
+ else
+ Np.first = Np.first or lp
+ Np.id = id_kern; set_attr(lp, attr_icflag, PROCESSED)
+ Np.last = lp; return true, node_next(lp)
+ end
+ end,
+ [id_penalty] = function(lp)
+ Bp[#Bp+1] = lp; set_attr(lp, attr_icflag, PROCESSED)
+ return false, node_next(lp)
+ end,
+}
+end -- 002 ---------------------------------------
+calc_np_auxtable[id_rule] = calc_np_auxtable.box_like
+calc_np_auxtable[15] = calc_np_auxtable.box_like
+
+local function calc_np_aux_skip (lp)
+ set_attr(lp, attr_icflag, PROCESSED)
+ return false, node_next(lp)
+end
+
+function calc_np(last, lp)
+ local k
+ -- We assume lp = node_next(Np.last)
+ Np, Nq, non_ihb_flag = Nq, Np, true
+ -- We clear `predefined' entries of Np before pairs() loop,
+ -- because using only pairs() loop is slower.
+ Np.post, Np.pre, Np.xspc = nil, nil, nil
+ Np.first, Np.id, Np.last, Np.met, Np.class= nil, nil, nil, nil
+ Np.auto_kspc, Np.auto_xspc, Np.char, Np.nuc = nil, nil, nil, nil
+ for k in pairs(Np) do Np[k] = nil end
+
+ for k = 1,#Bp do Bp[k] = nil end
+ while lp ~= last do
+ local lpa = has_attr(lp, attr_icflag) or 0
+ -- unbox ç”±æ¥ãƒŽãƒ¼ãƒ‰ã®æ¤œå‡º
+ if lpa>=PACKED then
+ if lpa%PROCESSED_BEGIN_FLAG == BOXBDD then
+ local lq = node_next(lp)
+ head = node_remove(head, lp); node_free(lp); lp = lq
+ else
+ return calc_np_pbox(lp, last)
+ end -- id_pbox
+ else
+ k, lp = (calc_np_auxtable[getid(lp)] or calc_np_aux_skip)(lp)
+ if k then return lp end
+ end
+ end
+ Np=nil
+end
+end -- 001 -----------------------------------------------
+
+-- extract informations from Np
+-- We think that "Np is a Japanese character" if Np.met~=nil,
+-- "Np is an alphabetic character" if Np.pre~=nil,
+-- "Np is not a character" otherwise.
+local after_hlist = nil -- global
+local after_alchar, extract_np
+do
+ local PRE = luatexja.stack_table_index.PRE
+ local POST = luatexja.stack_table_index.POST
+ local KCAT = luatexja.stack_table_index.KCAT
+ local XSP = luatexja.stack_table_index.XSP
+ local dir_tate = luatexja.dir_table.dir_tate
+
+-- 和文文字ã®ãƒ‡ãƒ¼ã‚¿ã‚’å–å¾—
+ local attr_jchar_class = luatexbase.attributes['ltj@charclass']
+ local attr_jchar_code = luatexbase.attributes['ltj@charcode']
+ local attr_autospc = luatexbase.attributes['ltj@autospc']
+ local attr_autoxspc = luatexbase.attributes['ltj@autoxspc']
+ local getcomponents = node.direct.getcomponents
+ --local ltjf_get_vert_glyph = ltjf.get_vert_glyph
+ function set_np_xspc_jachar(Nx, x)
+ local m = ltjf_font_metric_table[getfont(x)]
+ local c, c_glyph = (not getcomponents(x) and ltjs_orig_char_table[x]), getchar(x)
+ if c and c~=c_glyph then set_attr(x, attr_jchar_code, c) end
+ c = c or c_glyph
+ local cls = slow_find_char_class(c, m, c_glyph)
+ Nx.met, Nx.class, Nx.char = m, cls, c;
+ local mc = m.char_type; Nx.char_type = mc
+ if cls~=0 then set_attr(x, attr_jchar_class, cls) end
+ Nx.pre = table_current_stack[PRE + c] or 0
+ Nx.post = table_current_stack[POST + c] or 0
+ Nx.xspc = table_current_stack[XSP + c] or 3
+ Nx.kcat = table_current_stack[KCAT + c] or 0
+ Nx.auto_kspc, Nx.auto_xspc = (has_attr(x, attr_autospc)==1), (has_attr(x, attr_autoxspc)==1)
+ return m, mc, cls
+ end
+ function set_np_xspc_jachar_hbox(Nx, x)
+ local m = ltjf_font_metric_table[getfont(x)]
+ local c = has_attr(x, attr_jchar_code) or getchar(x)
+ Nx.met, Nx.char = m, c; Nx.class = has_attr(x, attr_jchar_class) or 0;
+ local mc = m.char_type; Nx.char_type = mc
+ Nx.pre = table_current_stack[PRE + c] or 0
+ Nx.post = table_current_stack[POST + c] or 0
+ Nx.xspc = table_current_stack[XSP + c] or 3
+ Nx.kcat = table_current_stack[KCAT + c] or 0
+ Nx.auto_kspc, Nx.auto_xspc = (has_attr(x, attr_autospc)==1), (has_attr(x, attr_autoxspc)==1)
+ end
+
+-- 欧文文字ã®ãƒ‡ãƒ¼ã‚¿ã‚’å–å¾—
+ local floor = math.floor
+ local nullfunc = function(n) return n end
+ function set_np_xspc_alchar(Nx, c,x, lig)
+ if c~=-1 then
+ local f = (lig ==1) and nullfunc or node_tail
+ local xc, xs = getcomponents(x), getsubtype(x)
+ while xc and xs and xs%4>=2 do
+ x = f(xc);
+ if getid(x)==id_disc then x, xc, xs = nil, getfield(x,'replace'), 2
+ else xc, xs = getcomponents(x), getsubtype(x) end
+ end
+ c = x and getchar(x) or c
+ Nx.pre = table_current_stack[PRE + c] or 0
+ Nx.post = table_current_stack[POST + c] or 0
+ else
+ Nx.pre, Nx.post = 0, 0
+ end
+ Nx.met = nil
+ Nx.xspc = table_current_stack[XSP + c] or 3
+ Nx.auto_xspc = (has_attr(x, attr_autoxspc)==1)
+ end
+ local set_np_xspc_alchar = set_np_xspc_alchar
+
+ -- change the information for the next loop
+ -- (will be done if Nx is an alphabetic character or a hlist)
+ after_hlist = function (Nx)
+ local s = Nx.last_char
+ if s then
+ if getid(s)==id_glyph then
+ if if_lang_ja(s) then
+ set_np_xspc_jachar_hbox(Nx, s)
+ else
+ set_np_xspc_alchar(Nx, getchar(s), s, 2)
+ end
+ else
+ set_np_xspc_alchar(Nx, -1, s)
+ end
+ else
+ Nx.pre, Nx.met = nil, nil
+ end
+ end
+
+ after_alchar = function (Nx)
+ local x = Nx.last_char
+ return set_np_xspc_alchar(Nx, getchar(x), x, 2)
+ end
+
+end
+
+-------------------- 最下層ã®å‡¦ç†
+
+luatexbase.create_callback('luatexja.adjust_jfmglue', 'simple', function(n) return n end)
+
+-- change penalties (or create a new penalty, if needed)
+local function handle_penalty_normal(post, pre, g)
+ luatexbase.call_callback('luatexja.adjust_jfmglue', head, Nq, Np, Bp)
+ local a = (pre or 0) + (post or 0)
+ if #Bp == 0 then
+ if (a~=0 and not(g and getid(g)==id_kern)) then
+ local p = node_new(id_penalty)
+ if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end
+ setfield(p, 'penalty', a)
+ head = insert_before(head, Np.first, p)
+ Bp[1]=p;
+ set_attr(p, attr_icflag, KINSOKU)
+ end
+ else for _, v in pairs(Bp) do add_penalty(v,a) end
+ end
+end
+
+local function handle_penalty_always(post, pre, g)
+ luatexbase.call_callback('luatexja.adjust_jfmglue', head, Nq, Np, Bp)
+ local a = (pre or 0) + (post or 0)
+ if #Bp == 0 then
+ if not (g and getid(g)==id_glue) or a~=0 then
+ local p = node_new(id_penalty)
+ if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end
+ setfield(p, 'penalty', a)
+ head = insert_before(head, Np.first, p)
+ Bp[1]=p
+ set_attr(p, attr_icflag, KINSOKU)
+ end
+ else for _, v in pairs(Bp) do add_penalty(v,a) end
+ end
+end
+
+local function handle_penalty_suppress(post, pre, g)
+ luatexbase.call_callback('luatexja.adjust_jfmglue', head, Nq, Np, Bp)
+ if #Bp == 0 then
+ if g and getid(g)==id_glue then
+ local p = node_new(id_penalty)
+ setfield(p, 'penalty', 10000); head = insert_before(head, Np.first, p)
+ Bp[1]=p
+ set_attr(p, attr_icflag, KINSOKU)
+ end
+ else
+ local a = (pre or 0) + (post or 0)
+ for _, v in pairs(Bp) do add_penalty(v,a) end
+ end
+end
+
+local function handle_penalty_jwp()
+ local a = table_current_stack[luatexja.stack_table_index.JWP]
+ if #widow_Bp == 0 then
+ if a~=0 then
+ local p = node_new(id_penalty)
+ if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end
+ setfield(p, 'penalty', a)
+ head = insert_before(head, widow_Np.first, p)
+ widow_Bp[1]=p;
+ set_attr(p, attr_icflag, KINSOKU)
+ end
+ else for _, v in pairs(widow_Bp) do add_penalty(v,a) end
+ end
+end
+
+-- 和文文字間㮠JFM glue を node 化
+local function new_jfm_glue(mc, bc, ac)
+-- bc, ac: char classes
+ local g = mc[bc][ac]
+ if g then
+ if g[1] then
+ return node_copy(g[1]), g.ratio, false, false, false
+ else
+ local f = node_new(id_glue)
+ set_attr(f, attr_icflag, g.priority)
+ setglue(f, g.width, g.stretch, g.shrink)
+ return f, g.ratio, g.kanjiskip_natural, g.kanjiskip_stretch, g.kanjiskip_shrink
+ end
+ end
+ return false, 0
+end
+
+-- Nq.last (kern w) .... (glue/kern g) Np.first
+local function real_insert(g)
+ if g then
+ head = insert_before(head, Np.first, g)
+ Np.first = g
+ end
+end
+
+
+-------------------- 和文文字間空白é‡ã®æ±ºå®š
+local calc_ja_ja_aux
+do
+ local round = tex.round
+ local bg_ag = 2*id_glue - id_glue
+ local bg_ak = 2*id_glue - id_kern
+ local bk_ag = 2*id_kern - id_glue
+ local bk_ak = 2*id_kern - id_kern
+
+ local function blend_diffmet(b, a, rb, ra)
+ return round(luatexja.jfmglue.diffmet_rule((1-rb)*b+rb*a, (1-ra)*b+ra*a))
+ end
+ calc_ja_ja_aux = function (gb, ga, db, da)
+ if luatexja.jfmglue.diffmet_rule ~= math.two_pleft and diffmet_rule ~= math.two_pright
+ and luatexja.jfmglue.diffmet_rule ~= math.two_paverage then
+ db, da = 0, 1
+ end
+ if not gb then
+ if ga then
+ gb = node_new(id_kern, 1); setfield(gb, 'kern', 0)
+ else return nil end
+ elseif not ga then
+ ga = node_new(id_kern, 1); setfield(ga, 'kern', 0)
+ end
+
+ local k = 2*getid(gb) - getid(ga)
+ if k == bg_ag then
+ -- 両方ã¨ã‚‚ glue.
+ setglue(gb, blend_diffmet(
+ getfield(gb, 'width'), getfield(ga, 'width'), db, da),
+ blend_diffmet(
+ getfield(gb, 'stretch'), getfield(ga, 'stretch'), db, da),
+ -blend_diffmet(
+ -getfield(gb, 'shrink'), -getfield(ga, 'shrink'), db, da))
+ node_free(ga)
+ return gb
+ elseif k == bk_ak then
+ -- 両方ã¨ã‚‚ kern.
+ setfield(gb, 'kern', blend_diffmet(
+ getfield(gb, 'kern'), getfield(ga, 'kern'), db, da))
+ node_free(ga)
+ return gb
+ elseif k == bk_ag then
+ -- gb: kern, ga: glue
+ setglue(ga, blend_diffmet(
+ getfield(gb, 'kern'), getfield(ga, 'width'), db, da),
+ blend_diffmet(
+ 0, getfield(ga, 'stretch'), db, da),
+ -blend_diffmet(
+ 0, -getfield(ga, 'shrink'), db, da))
+ node_free(gb)
+ return ga, 0, 0, 0
+ else
+ -- gb: glue, ga: kern
+ setglue(gb, blend_diffmet(
+ getfield(gb, 'width'), getfield(ga, 'kern'), db, da),
+ blend_diffmet(
+ getfield(gb, 'stretch'), 0, db, da),
+ -blend_diffmet(
+ -getfield(gb, 'shrink'), 0, db, da))
+ node_free(ga)
+ return gb
+ end
+ end
+end
+
+local null_skip_table = {0, 0, 0}
+-- get kanjiskip
+local get_kanjiskip, kanjiskip_jfm_flag
+local get_kanjiskip_low
+local calc_ja_ja_glue
+do
+ local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP
+ local KANJI_SKIP_JFM = luatexja.icflag_table.KANJI_SKIP_JFM
+
+ get_kanjiskip_low = function(flag, qm, bn, bp, bh)
+ if flag or (qm.with_kanjiskip and (bn or bp or bh)) then
+ if kanjiskip_jfm_flag then
+ local g = node_new(id_glue);
+ local bk = qm.kanjiskip or null_skip_table
+ setglue(g, bn and (bn*bk[1]) or 0,
+ bp and (bp*bk[2]) or 0,
+ bh and (bh*bk[3]) or 0, 0, 0)
+ set_attr(g, attr_icflag, KANJI_SKIP_JFM)
+ return g
+ elseif flag then
+ return node_copy(kanji_skip)
+ else
+ local g = node_new(id_glue);
+ setglue(g,
+ bn and (bn*getfield(kanji_skip, 'width')) or 0,
+ bp and (bp*getfield(kanji_skip, 'stretch')) or 0,
+ bh and (bh*getfield(kanji_skip, 'shrink')) or 0,
+ 0, 0)
+ set_attr(g, attr_icflag, KANJI_SKIP_JFM)
+ return g
+ end
+ end
+ end
+
+ get_kanjiskip = function()
+ if Np.auto_kspc==0 or Nq.auto_kspc==0 then
+ return nil
+ elseif Np.auto_kspc or Nq.auto_kspc then
+ local pm, qm = Np.met, Nq.met
+ if (pm.char_type==qm.char_type) and (qm.var==pm.var) then
+ return get_kanjiskip_low(true, qm, 1, 1, 1)
+ else
+ local gb = get_kanjiskip_low(true, qm, 1, 1, 1)
+ local ga = get_kanjiskip_low(true, pm, 1, 1, 1)
+ return calc_ja_ja_aux(gb, ga, 0, 1)
+ end
+ else
+ local g = node_new(id_glue)
+ set_attr(g, attr_icflag, kanjiskip_jfm_flag and KANJI_SKIP_JFM or KANJI_SKIP)
+ return g
+ end
+ end
+
+ calc_ja_ja_glue = function ()
+ local qm, pm = Nq.met, Np.met
+ local qmc, pmc = qm.char_type, pm.char_type
+ if (qmc==pmc) and (qm.var==pm.var) then
+ local g, _, kn, kp, kh = new_jfm_glue(qmc, Nq.class, Np.class)
+ return g, (Np.auto_kspc or Nq.auto_kspc) and get_kanjiskip_low(false, qm, kn, kp, kh)
+ else
+ local npn, nqn = Np.nuc, Nq.nuc
+ local gb, db, bn, bp, bh
+ = new_jfm_glue(qmc, Nq.class,
+ slow_find_char_class(Np.char,
+ qm, getchar(npn)))
+ local ga, da, an, ap, ah
+ = new_jfm_glue(pmc,
+ slow_find_char_class(Nq.char,
+ pm, getchar(nqn)),
+ Np.class)
+ local g = calc_ja_ja_aux(gb, ga, db, da)
+ local k
+ if (pmc==qmc) and (qm.var==pm.var) then
+ gb = get_kanjiskip_low(false, qm, bn, bp, bh)
+ ga = get_kanjiskip_low(false, pm, an, ap, ah)
+ k = calc_ja_ja_aux(gb, ga, db, da)
+ end
+ return g, k
+ end
+ end
+end
+
+-------------------- 和欧文間空白é‡ã®æ±ºå®š
+
+-- get xkanjiskip
+local get_xkanjiskip, xkanjiskip_jfm_flag
+local get_xkanjiskip_normal, get_xkanjiskip_jfm
+local get_xkanjiskip_low
+do
+ local XKANJI_SKIP = luatexja.icflag_table.XKANJI_SKIP
+ local XKANJI_SKIP_JFM = luatexja.icflag_table.XKANJI_SKIP_JFM
+
+ get_xkanjiskip_low = function(flag, qm, bn, bp, bh)
+ if flag or (qm.with_kanjiskip and (bn or bp or bh)) then
+ if xkanjiskip_jfm_flag then
+ local g = node_new(id_glue);
+ local bk = qm.xkanjiskip or null_skip_table
+ setglue(g, bn and bk[1] or 0,
+ bp and bk[2] or 0,
+ bh and bk[3] or 0, 0, 0)
+ set_attr(g, attr_icflag, XKANJI_SKIP_JFM)
+ return g
+ elseif flag then
+ return node_copy(xkanji_skip)
+ else
+ local g = node_new(id_glue);
+ setglue(g,
+ bn and (bn*getfield(xkanji_skip, 'width')) or 0,
+ bp and (bp*getfield(xkanji_skip, 'stretch')) or 0,
+ bh and (bh*getfield(xkanji_skip, 'shrink')) or 0,
+ 0, 0)
+ set_attr(g, attr_icflag, XKANJI_SKIP_JFM)
+ return g
+ end
+ end
+ end
+
+ get_xkanjiskip = function(Nn)
+ if Np.auto_xspc==0 or Nq.auto_xspc==0 then
+ return nil
+ elseif (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then
+ return get_xkanjiskip_low(true, Nn.met, 1, 1, 1)
+ else
+ local g = node_new(id_glue)
+ set_attr(g, attr_icflag, xkanjiskip_jfm_flag and XKANJI_SKIP_JFM or XKANJI_SKIP)
+ return g
+ end
+ end
+end
+
+-------------------- 隣接ã—ãŸã€Œå¡Šã€é–“ã®å‡¦ç†
+
+local function combine_spc(name)
+ return (Np[name] or Nq[name]) and ((Np[name]~=0) and (Nq[name]~=0))
+end
+
+-- NA, NB: alchar or math
+local function get_NA_skip()
+ local pm = Np.met
+ local g, _, kn, kp, kh = new_jfm_glue(
+ pm.char_type,
+ fast_find_char_class(
+ (Nq.id == id_math and -1 or (Nq.xspc>=2 and 'alchar' or 'nox_alchar')), pm),
+ Np.class)
+ local k = ((Nq.xspc>=2) and (Np.xspc%2==1) and combine_spc('auto_xspc'))
+ and get_xkanjiskip_low(false, pm, kn, kp, kh)
+ return g, k
+end
+local function get_NB_skip()
+ local qm = Nq.met
+ local g, _, kn, kp, kh = new_jfm_glue(
+ qm.char_type, Nq.class,
+ fast_find_char_class(
+ (Np.id == id_math and -1 or (Np.xspc%2==1 and 'alchar' or 'nox_alchar')), qm)
+ )
+ local k = ((Nq.xspc>=2) and (Np.xspc%2==1) and combine_spc('auto_xspc'))
+ and get_xkanjiskip_low(false, qm, kn, kp, kh)
+ return g, k
+end
+
+local function get_OA_skip(is_kanji)
+ local pm = Np.met
+ local g, _, kn, kp, kh = new_jfm_glue(
+ pm.char_type,
+ fast_find_char_class(
+ (((Nq.id==id_glue)or(Nq.id==id_kern)) and 'glue' or 'jcharbdd'), pm),
+ Np.class)
+ local k
+ if is_kanji==0 then
+ k = combine_spc('auto_kspc') and get_kanjiskip_low(false, pm, kn, kp, kh)
+ end
+ return g, k
+end
+local function get_OB_skip(is_kanji)
+ local qm = Nq.met
+ local g, _, kn, kp, kh = new_jfm_glue(
+ qm.char_type, Nq.class,
+ fast_find_char_class(
+ (((Np.id==id_glue)or(Np.id==id_kern)) and 'glue' or 'jcharbdd'), qm))
+ local k
+ if is_kanji==0 then
+ k = combine_spc('auto_kspc') and get_kanjiskip_low(false, qm, kn, kp, kh)
+ end
+ return g, k
+end
+
+-- (anything) .. jachar
+local function handle_np_jachar(mode)
+ local qid = Nq.id
+ if qid==id_jglyph or ((qid==id_pbox or qid==id_pbox_w) and Nq.met) then
+ local g, k
+ if non_ihb_flag then g, k = calc_ja_ja_glue() end -- M->K
+ if not g then g = get_kanjiskip() end
+ handle_penalty_normal(Nq.post, Np.pre, g);
+ real_insert(g); real_insert(k)
+ elseif Nq.met then -- qid==id_hlist
+ local g, k
+ if non_ihb_flag then g, k = get_OA_skip(0) end -- O_A->K
+ if not g then g = get_kanjiskip() end
+ handle_penalty_normal(0, Np.pre, g); real_insert(g); real_insert(k)
+ elseif Nq.pre then
+ local g, k
+ if non_ihb_flag then g, k = get_NA_skip() end -- N_A->X
+ if not g then g = get_xkanjiskip(Np) end
+ handle_penalty_normal((qid==id_hlist and 0 or Nq.post), Np.pre, g);
+ real_insert(g); real_insert(k)
+ else
+ local g = non_ihb_flag and (get_OA_skip()) -- O_A
+ if qid==id_glue then handle_penalty_normal(0, Np.pre, g)
+ elseif qid==id_kern then handle_penalty_suppress(0, Np.pre, g)
+ else handle_penalty_always(0, Np.pre, g)
+ end
+ real_insert(g)
+ end
+ if mode and Np.kcat%2~=1 then
+ widow_Np.first, widow_Bp, Bp = Np.first, Bp, widow_Bp
+ end
+end
+
+
+-- jachar .. (anything)
+local function handle_nq_jachar()
+ if Np.pre then
+ local g = non_ihb_flag and get_NB_skip() or get_xkanjiskip(Nq) -- N_B->X
+ handle_penalty_normal(Nq.post, (Np.id==id_hlist and 0 or Np.pre), g); real_insert(g)
+ else
+ local g =non_ihb_flag and (get_OB_skip()) -- O_B
+ if Np.id==id_glue then handle_penalty_normal(Nq.post, 0, g)
+ elseif Np.id==id_kern then handle_penalty_suppress(Nq.post, 0, g)
+ else handle_penalty_always(Nq.post, 0, g)
+ end
+ real_insert(g)
+ end
+end
+
+-- (anything) .. (和文文字ã§å§‹ã¾ã‚‹ hlist)
+local function handle_np_ja_hlist()
+ local qid = Nq.id
+ if qid==id_jglyph or ((qid==id_pbox or qid == id_pbox_w) and Nq.met) then
+ local g = non_ihb_flag and get_OB_skip(0) or get_kanjiskip() -- O_B->K
+ handle_penalty_normal(Nq.post, 0, g); real_insert(g)
+ elseif Nq.met then -- Nq.id==id_hlist
+ local g = get_kanjiskip() -- K
+ handle_penalty_suppress(0, 0, g); real_insert(g)
+ elseif Nq.pre then
+ local g = get_xkanjiskip(Np) -- X
+ handle_penalty_suppress(0, 0, g); real_insert(g)
+ end
+end
+
+-- (和文文字ã§çµ‚ã‚ã‚‹ hlist) .. (anything)
+local function handle_nq_ja_hlist()
+ if Np.pre then
+ local g = get_xkanjiskip(Nq) -- X
+ handle_penalty_suppress(0, 0, g); real_insert(g)
+ end
+end
+
+
+-- Nq ãŒå‰å´ã®ã‚¯ãƒ©ã‚¹ã‚¿ã¨ãªã‚‹ã“ã¨ã«ã‚ˆã‚‹ä¿®æ­£
+local adjust_nq
+do
+ local adjust_nq_aux = {
+ [id_glyph] = function() after_alchar(Nq) end, -- after_alchar(Nq)
+ [id_hlist] = function() after_hlist(Nq) end,
+ [id_pbox] = function() after_hlist(Nq) end,
+ [id_disc] = function() after_hlist(Nq) end,
+ [id_pbox_w] = function()
+ luatexbase.call_callback("luatexja.jfmglue.whatsit_after",
+ false, Nq, Np)
+ end,
+ }
+
+ adjust_nq=function()
+ local x = adjust_nq_aux[Nq.id]
+ if x then x() end
+ end
+end
+
+
+-------------------- 開始・終了時ã®å‡¦ç†
+do
+local node_prev = node.direct.getprev
+-- リスト末尾ã®å‡¦ç†
+local function handle_list_tail(mode, last)
+ adjust_nq()
+ if mode then
+ -- the current list is to be line-breaked.
+ -- Insert \jcharwidowpenalty
+ if widow_Np.first then handle_penalty_jwp() end
+ else
+ Np=Nq
+ -- the current list is the contents of a hbox
+ local npi, pm = Np.id, Np.met
+ if npi == id_jglyph or (npi==id_pbox and pm) then
+ local g = new_jfm_glue(pm.char_type, Np.class, fast_find_char_class('boxbdd', pm))
+ if g then
+ set_attr(g, attr_icflag, BOXBDD)
+ head = insert_after(head, Np.last, g)
+ end
+ end
+ end
+end
+
+-- リスト先頭ã®å‡¦ç†
+local function handle_list_head(par_indented)
+ local npi, pm = Np.id, Np.met
+ if npi == id_jglyph or (npi==id_pbox and pm) then
+ if non_ihb_flag then
+ local g = new_jfm_glue(pm.char_type, fast_find_char_class(par_indented, pm), Np.class)
+ if g then
+ set_attr(g, attr_icflag, BOXBDD)
+ if getid(g)==id_glue and #Bp==0 then
+ local h = node_new(id_penalty)
+ setfield(h, 'penalty', 10000); set_attr(h, attr_icflag, BOXBDD)
+ end
+ head = insert_before(head, Np.first, g)
+ end
+ end
+ end
+end
+
+-- initialize
+-- return value: (the initial cursor lp), (last node)
+local init_var
+do
+ local id_local = node.id('local_par')
+ local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP
+ local XKANJI_SKIP = luatexja.icflag_table.XKANJI_SKIP
+ local KSK = luatexja.stack_table_index.KSK
+ local XSK = luatexja.stack_table_index.XSK
+ local dir_yoko = luatexja.dir_table.dir_yoko
+ local dir_tate = luatexja.dir_table.dir_tate
+ local attr_yablshift = luatexbase.attributes['ltj@yablshift']
+ local attr_tablshift = luatexbase.attributes['ltj@tablshift']
+ local table_pool = {
+ {}, {}, {first=nil},
+ { auto_kspc=nil, auto_xspc=nil, char=nil, class=nil,
+ first=nil, id=nil, last=nil, met=nil, nuc=nil,
+ post=nil, pre=nil, xspc=nil, },
+ { auto_kspc=nil, auto_xspc=nil, char=nil, class=nil,
+ first=nil, id=nil, last=nil, met=nil, nuc=nil,
+ post=nil, pre=nil, xspc=nil, },
+ }
+ init_var = function (mode,dir)
+ -- 1073741823: max_dimen
+ Bp, widow_Bp, widow_Np, Np, Nq
+ = table_pool[1], table_pool[2], table_pool[3], table_pool[4], table_pool[5]
+ for i=1,5 do for j,_ in pairs(table_pool[i]) do table_pool[i][j]=nil end end
+ table_current_stack = ltjs.table_current_stack
+
+ list_dir, tex_dir = (ltjs.list_dir or dir_yoko), (dir or 'TLT')
+ local is_dir_tate = list_dir==dir_tate
+ capsule_glyph = is_dir_tate and ltjw.capsule_glyph_tate or ltjw.capsule_glyph_yoko
+ attr_ablshift = is_dir_tate and attr_tablshift or attr_yablshift
+ local TEMP = node_new(id_glue)
+ -- TEMP is a dummy node, which will be freed at the end of the callback.
+ -- ithout this node, set_attr(kanji_skip, ...) somehow creates an "orphaned" attribute list.
+
+ do
+ kanji_skip, kanjiskip_jfm_flag = skip_table_to_glue(KSK)
+ set_attr(kanji_skip, attr_icflag, KANJI_SKIP)
+ end
+
+ do
+ xkanji_skip, xkanjiskip_jfm_flag = skip_table_to_glue(XSK)
+ set_attr(xkanji_skip, attr_icflag, XKANJI_SKIP)
+ end
+
+ if mode then
+ -- the current list is to be line-breaked:
+ -- hbox from \parindent is skipped.
+ local lp, par_indented, lpi, lps = head, 'boxbdd', getid(head), getsubtype(head)
+ while lp and
+ ((lpi==id_whatsit and lps~=sid_user)
+ or ((lpi==id_hlist) and (lps==3))
+ or (lpi==id_local)) do
+ if (lpi==id_hlist) and (lps==3) then
+ Np.char, par_indented = 'parbdd', 'parbdd'
+ Np.width = getfield(lp, 'width')
+ end
+ lp=node_next(lp); lpi, lps = getid(lp), getsubtype(lp) end
+ return lp, node_tail(head), par_indented, TEMP
+ else
+ return head, nil, 'boxbdd', TEMP
+ end
+ end
+end
+
+local ensure_tex_attr = ltjb.ensure_tex_attr
+local function cleanup(mode, TEMP)
+ -- luatexja.ext_show_node_list(to_node(head), '> ', print)
+ -- adjust attr_icflag for avoiding error
+ if tex.getattribute(attr_icflag)~=0 then ensure_tex_attr(attr_icflag, 0) end
+ node_free(kanji_skip);
+ node_free(xkanji_skip); node_free(TEMP)
+
+ if mode then
+ local h = node_next(head)
+ if getid(h) == id_penalty and getfield(h, 'penalty') == 10000 then
+ h = node_next(h)
+ if getid(h) == id_glue and getsubtype(h) == 15 and not node_next(h) then
+ return false
+ end
+ end
+ end
+ return head
+end
+-------------------- 外部ã‹ã‚‰å‘¼ã°ã‚Œã‚‹é–¢æ•°
+
+-- main interface
+function luatexja.jfmglue.main(ahead, mode, dir)
+ if not ahead then return ahead end
+ --luatexja.ext_show_node_list(to_node(ahead ), '>B ', print)
+ --print()
+ head = ahead;
+ local lp, last, par_indented, TEMP = init_var(mode,dir)
+ lp = calc_np(last, lp)
+ if Np then
+ handle_list_head(par_indented)
+ lp = calc_np(last,lp);
+ while Np do
+ adjust_nq();
+ local pid, pm = Np.id, Np.met
+ -- 挿入部
+ if pid == id_jglyph then
+ handle_np_jachar(mode)
+ elseif pm then
+ if pid==id_hlist then handle_np_ja_hlist()
+ else handle_np_jachar() end
+ elseif Nq.met then
+ if Nq.id==id_hlist then handle_nq_ja_hlist()
+ else handle_nq_jachar() end
+ end
+ lp = calc_np(last,lp)
+ end
+ handle_list_tail(mode, last)
+ end
+ --luatexja.ext_show_node_list(to_node(ahead ), '>A ', print)
+ --print()
+ return cleanup(mode, TEMP)
+end
+end
+
+do
+ local IHB = luatexja.userid_table.IHB
+ local BPAR = luatexja.userid_table.BPAR
+ local BOXB = luatexja.userid_table.BOXB
+ local node_prev = node.direct.getprev
+ local node_write = node.direct.write
+
+ -- \inhibitglue
+ function luatexja.jfmglue.create_inhibitglue_node()
+ local tn = node_new(id_whatsit, sid_user)
+ setfield(tn, 'user_id', IHB)
+ setfield(tn, 'type', 100)
+ setfield(tn, 'value', 1)
+ node_write(tn)
+ end
+
+ -- Node for indicating beginning of a paragraph
+ -- (for ltjsclasses)
+ function luatexja.jfmglue.create_beginpar_node()
+ local tn = node_new(id_whatsit, sid_user)
+ setfield(tn, 'user_id', BPAR)
+ setfield(tn, 'type', 100)
+ setfield(tn, 'value', 1)
+ node_write(tn)
+ end
+
+ -- Node for indicating a head/end of a box
+ function luatexja.jfmglue.create_boxbdd_node()
+ local tn = node_new(id_whatsit, sid_user)
+ setfield(tn, 'user_id', BOXB)
+ setfield(tn, 'type', 100)
+ setfield(tn, 'value', 1)
+ node_write(tn)
+ end
+
+ local function whatsit_callback(Np, lp, Nq)
+ if Np and Np.nuc then return Np
+ elseif Np and getfield(lp, 'user_id') == BPAR then
+ Np.first = lp; Np.nuc = lp; Np.last = lp
+ return Np
+ elseif Np and getfield(lp, 'user_id') == BOXB then
+ Np.first = lp; Np.nuc = lp; Np.last = lp
+ if Nq then
+ if Nq.met then
+ Np.class = fast_find_char_class('boxbdd', Nq.met)
+ end
+ Np.met = Nq.met; Np.pre = 0; Np.post = 0; Np.xspc = 0
+ Np.auto_xspc, Np.auto_kspc = 0, 0
+ end
+ return Np
+ else
+ return Np
+ end
+ end
+
+ local function whatsit_after_callback(s, Nq, Np)
+ if not s and getfield(Nq.nuc, 'user_id') == BPAR then
+ local x, y = node_prev(Nq.nuc), Nq.nuc
+ Nq.first, Nq.nuc, Nq.last = x, x, x
+ if Np then
+ if Np.met then
+ Nq.class = fast_find_char_class('parbdd', Np.met)
+ end
+ Nq.met = Np.met; Nq.pre = 0; Nq.post = 0; Nq.xspc = 0
+ Nq.auto_xspc, Nq.auto_kspc = 0, 0
+ end
+ head = node_remove(head, y)
+ node_free(y)
+ elseif not s and getfield(Nq.nuc, 'user_id') == BOXB then
+ local x, y = node_prev(Nq.nuc), Nq.nuc
+ Nq.first, Nq.nuc, Nq.last = x, x, x
+ if Np then
+ if Np.met then
+ Nq.class = fast_find_char_class('boxbdd', Np.met)
+ end
+ Nq.met = Np.met; Nq.pre = 0; Nq.post = 0; Nq.xspc = 0
+ Nq.auto_xspc, Nq.auto_kspc = 0, 0
+ end
+ head = node_remove(head, y)
+ node_free(y)
+ end
+ return s
+ end
+
+ luatexbase.add_to_callback("luatexja.jfmglue.whatsit_getinfo", whatsit_callback,
+ "luatexja.beginpar.np_info", 1)
+ luatexbase.add_to_callback("luatexja.jfmglue.whatsit_after", whatsit_after_callback,
+ "luatexja.beginpar.np_info_after", 1)
+
+end
+
+luatexja.jfmglue.after_hlist = after_hlist
+luatexja.jfmglue.check_box_high = check_box_high
diff --git a/macros/luatex/generic/luatexja/src/ltj-jfont.lua b/macros/luatex/generic/luatexja/src/ltj-jfont.lua
new file mode 100644
index 0000000000..82e2808e5a
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-jfont.lua
@@ -0,0 +1,1028 @@
+--
+-- luatexja/jfont.lua
+--
+luatexbase.provides_module({
+ name = 'luatexja.jfont',
+ date = '2019/07/08',
+ description = 'Loader for Japanese fonts',
+})
+
+luatexja.load_module('base'); local ltjb = luatexja.base
+luatexja.load_module('charrange'); local ltjc = luatexja.charrange
+luatexja.load_module('rmlgbm'); local ltjr = luatexja.rmlgbm
+luatexja.load_module('direction'); local ltjd = luatexja.direction
+
+local setfield = node.direct.setfield
+local getid = node.direct.getid
+local to_direct = node.direct.todirect
+
+local node_new = node.direct.new
+local node_free = node.direct.free
+local has_attr = node.direct.has_attribute
+local set_attr = node.direct.set_attribute
+local round = tex.round
+local font_getfont = font.getfont
+
+local attr_icflag = luatexbase.attributes['ltj@icflag']
+local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
+local attr_curtfnt = luatexbase.attributes['ltj@curtfnt']
+local id_glyph = node.id('glyph')
+local id_kern = node.id('kern')
+local cat_lp = luatexbase.catcodetables['latex-package']
+local FROM_JFM = luatexja.icflag_table.FROM_JFM
+
+luatexja.jfont = luatexja.jfont or {}
+------------------------------------------------------------------------
+-- LOADING JFM
+------------------------------------------------------------------------
+
+local metrics={} -- this table stores all metric informations
+local font_metric_table={} -- [font number] -> jfm_name, jfm_var, size
+
+luatexbase.create_callback("luatexja.load_jfm", "data", function (ft, jn) return ft end)
+
+local jfm_file_name, jfm_var, jfm_ksp
+local defjfm_res
+local jfm_dir, is_def_jfont, vert_activated, auto_enable_vrt2
+
+local function norm_val(a)
+ if (not a) or (a==0.) then
+ return nil
+ elseif a==true then
+ return 1
+ else
+ return a
+ end
+end
+
+local fastcopy=table.fastcopy
+function luatexja.jfont.define_jfm(to)
+ local t = fastcopy(to)
+ local real_char -- Does current character class have the 'real' character?
+ if t.dir~=jfm_dir then
+ defjfm_res= nil; return
+ elseif type(t.zw)~='number' or type(t.zh)~='number' then
+ defjfm_res= nil; return
+ end
+ t.version = (type(t.version)=='number') and t.version or 1
+ t.char_type = {}; t.chars = {}
+ for i,v in pairs(t) do
+ if type(i) == 'number' then -- char_type
+ if not v.chars then
+ if i ~= 0 then defjfm_res= nil; return end
+ else
+ for j,w in pairs(v.chars) do
+ if type(w) == 'number' and w~=-1 then
+ elseif type(w) == 'string' and utf.len(w)==1 then
+ w = utf.byte(w)
+ elseif type(w) == 'string' and utf.len(w)==2 and utf.sub(w,2) == '*' then
+ w = utf.byte(utf.sub(w,1,1))
+ end
+ if not t.chars[w] then
+ t.chars[w] = i
+ else
+ defjfm_res= nil; return
+ end
+ end
+ v.chars = nil
+ end
+ if type(v.align)~='string' then
+ v.align = 'left' -- left
+ end
+ if type(v.width)~='number' then
+ v.width = nil
+ end
+ if type(v.height)~='number' then
+ v.height = (jfm_dir=='tate') and 0.0
+ end
+ if type(v.depth)~='number' then
+ v.depth = (jfm_dir=='tate') and 0.0
+ end
+ if type(v.italic)~='number' then
+ v.italic = 0.0
+ end
+ if type(v.left)~='number' then
+ v.left = 0.0
+ end
+ if type(v.down)~='number' then
+ v.down = 0.0
+ end
+ if t.version>=2 then
+ if v.end_stretch then defjfm_res= nil; return end
+ if v.end_shrink then defjfm_res= nil; return end
+ if v.end_adjust then
+ if type(v.end_adjust)~='table' then
+ v.end_adjust = nil
+ elseif #(v.end_adjust)==0 then
+ v.end_adjust = nil
+ else
+ table.sort(v.end_adjust)
+ end
+ end
+ else
+ v.end_adjust = nil
+ if v.end_stretch and v.end_stretch~=0.0 then
+ v.end_adjust = (v.end_adjust or {})
+ v.end_adjust[#(v.end_adjust)+1] = v.end_stretch
+ end
+ if v.end_shrink and v.end_ahrink~=0.0 then
+ v.end_adjust = (v.end_adjust or {})
+ v.end_adjust[#(v.end_adjust)+1] = -v.end_shrink
+ end
+ if v.end_adjust then v.end_adjust[#(v.end_adjust)+1] = 0.0 end
+ end
+ v.kern = v.kern or {}; v.glue = v.glue or {}
+ for j,x in pairs(v.glue) do
+ if v.kern[j] then defjfm_res= nil; return end
+ x.ratio, x[5] = (x.ratio or (x[5] and 0.5*(1+x[5]) or 0.5)), nil
+ do
+ local xp
+ xp, x[4] = (x.priority or x[4]), nil
+ if type(xp)=='table' and t.version>=2 then
+ if type(xp[1])~='number' or xp[1]<-4 or xp[1]>3 then defjfm_res=nil end -- stretch
+ if type(xp[2])~='number' or xp[2]<-4 or xp[2]>3 then defjfm_res=nil end -- shrink
+ xp = (xp[1]+4)*8+(xp[2]+4)
+ elseif xp and type(xp)~='number' then
+ defjfm_res = nil
+ else
+ xp = (xp or 0)*9+36
+ if xp<0 or xp>=64 then defjfm_res=nil end
+ end
+ x.priority = xp
+ end
+ x.kanjiskip_natural = norm_val(x.kanjiskip_natural)
+ x.kanjiskip_stretch = norm_val(x.kanjiskip_stretch)
+ x.kanjiskip_shrink = norm_val(x.kanjiskip_shrink)
+ end
+ for j,x in pairs(v.kern) do
+ if type(x)=='number' then
+ v.kern[j] = {x, 0.5}
+ elseif type(x)=='table' then
+ v.kern[j] = { x[1], (x.ratio or (x[2] and 0.5*(1+x[2]) or 0.5)) }
+ end
+ end
+ t.char_type[i] = v
+ t[i] = nil
+ end
+ end
+ if t.version<3 then
+ -- In version 3, 'jcharbdd' is divided into
+ -- 'alchar': ALchar (or math boundary)
+ -- 'nox_alchar': ALchar (or math boundary), where xkanjiskip won't inserted
+ -- 'glue': glue/kern, 'jcharbdd': other cases (和文B, rule, ...)
+ t.chars.alchar = t.chars.jcharbdd
+ t.chars.nox_alchar = t.chars.jcharbdd
+ t.chars.glue = t.chars.jcharbdd
+ end
+ t = luatexbase.call_callback("luatexja.load_jfm", t, jfm_file_name)
+ t.size_cache = {}
+ defjfm_res = t
+end
+
+local update_jfm_cache
+do
+ local floor = math.floor
+ local function myround(a) return floor(a+0.5) end
+ local function mult_table(old,scale) -- modified from table.fastcopy
+ if old then
+ local new = { }
+ for k,v in next, old do
+ if type(v) == "table" then
+ new[k] = mult_table(v,scale)
+ elseif type(v) == "number" then
+ new[k] = myround(v*scale)
+ else
+ new[k] = v
+ end
+ end
+ return new
+ else return nil end
+ end
+ local size_cache_num = 1
+ update_jfm_cache = function (j,sz)
+ if metrics[j].size_cache[sz] then return metrics[j].size_cache[sz].index end
+ local t = {}
+ metrics[j].size_cache[sz] = t
+ t.chars = metrics[j].chars
+ t.char_type = mult_table(metrics[j].char_type, sz)
+ for i,v in pairs(t.char_type) do
+ v.align = (v.align=='left') and 0 or
+ ((v.align=='right') and 1 or 0.5)
+ if type(i) == 'number' then -- char_type
+ for k,w in pairs(v.glue) do
+ v[k] = {
+ nil,
+ ratio=w.ratio/sz,
+ priority=FROM_JFM + w.priority/sz,
+ width = w[1], stretch = w[2], shrink = w[3],
+ kanjiskip_natural = w.kanjiskip_natural and w.kanjiskip_natural/sz,
+ kanjiskip_stretch = w.kanjiskip_stretch and w.kanjiskip_stretch/sz,
+ kanjiskip_shrink = w.kanjiskip_shrink and w.kanjiskip_shrink/sz,
+ }
+ end
+ for k,w in pairs(v.kern) do
+ local g = node_new(id_kern, 1)
+ setfield(g, 'kern', w[1])
+ set_attr(g, attr_icflag, FROM_JFM)
+ v[k] = {g, ratio=w[2]/sz}
+ end
+ end
+ v.glue, v.kern = nil, nil
+ end
+ t.kanjiskip = mult_table(metrics[j].kanjiskip, sz)
+ t.xkanjiskip = mult_table(metrics[j].xkanjiskip,sz)
+ t.zw = round(metrics[j].zw*sz)
+ t.zh = round(metrics[j].zh*sz)
+ t.size = sz
+ size_cache_num = size_cache_num + 1
+ t.index = size_cache_num
+ return size_cache_num
+ end
+end
+
+luatexbase.create_callback("luatexja.find_char_class", "data",
+ function (arg, fmtable, char)
+ return 0
+ end)
+local find_char_class
+do
+ local start_time_measure = ltjb.start_time_measure
+ local stop_time_measure = ltjb.stop_time_measure
+ local fcc_temp = { chars_cbcache = {} }
+ setmetatable(
+ fcc_temp.chars_cbcache,
+ {
+ __index = function () return 0 end,
+ })
+ function find_char_class(c,m)
+ -- c: character code, m:
+ local r = (m or fcc_temp).chars_cbcache[c]
+ if not r then
+ r = m.chars[c] or
+ luatexbase.call_callback("luatexja.find_char_class", 0, m, c)
+ m.chars_cbcache[c or 0] = r
+ end
+ return r
+ end
+end
+
+
+------------------------------------------------------------------------
+-- LOADING JAPANESE FONTS
+------------------------------------------------------------------------
+
+local load_jfont_metric
+do
+ local cstemp
+ local global_flag -- true if \globaljfont, false if \jfont
+ load_jfont_metric = function()
+ if jfm_file_name=='' then
+ ltjb.package_error('luatexja',
+ 'no JFM specified',
+ 'To load and define a Japanese font, a JFM must be specified.'..
+ "The JFM 'ujis' will be used for now.")
+ jfm_file_name='ujis'
+ end
+ for j,v in ipairs(metrics) do
+ if v.name==jfm_file_name then return j end
+ end
+ luatexja.load_lua('jfm-' .. jfm_file_name .. '.lua')
+ if defjfm_res then
+ defjfm_res.name = jfm_file_name
+ table.insert(metrics, defjfm_res)
+ return #metrics
+ else
+ return nil
+ end
+ end
+
+-- EXT
+ local utfbyte = utf.byte
+ function luatexja.jfont.jfontdefX(g, dir, csname)
+ jfm_dir, is_def_jfont = dir, true
+ cstemp = csname:sub( (utfbyte(csname,1,1) == tex.escapechar) and 2 or 1, -1)
+ cstemp = cstemp:sub(1, ((cstemp:sub(-1,-1)==' ') and (cstemp:len()>=2)) and -2 or -1)
+ global_flag = g and '\\global' or ''
+ tex.sprint(cat_lp, '\\expandafter\\font\\csname ',
+ (cstemp==' ') and '\\space' or cstemp, '\\endcsname')
+ end
+
+ luatexbase.create_callback("luatexja.define_jfont", "data", function (ft, fn) return ft end)
+
+-- EXT
+ local identifiers = fonts.hashes.identifiers
+ local provides_feature = luaotfload.aux.provides_feature
+ function luatexja.jfont.jfontdefY()
+ local j = load_jfont_metric(jfm_dir)
+ local fn = font.id(cstemp)
+ local f = font_getfont(fn)
+ if not j then
+ ltjb.package_error('luatexja',
+ "bad JFM `" .. jfm_file_name .. "'",
+ 'The JFM file you specified is not valid JFM file.\n'..
+ 'So defining Japanese font is cancelled.')
+ tex.sprint(cat_lp, global_flag, '\\expandafter\\let\\csname ',
+ (cstemp==' ') and '\\space' or cstemp,
+ '\\endcsname=\\relax')
+ return
+ end
+ if not f then return end
+ update_jfm_cache(j, f.size)
+ local ad = identifiers[fn].parameters
+ local sz = metrics[j].size_cache[f.size]
+ local fmtable = { jfm = j, size = f.size, var = jfm_var,
+ with_kanjiskip = jfm_ksp,
+ zw = sz.zw, zh = sz.zh,
+ ascent = ad.ascender,
+ descent = ad.descender,
+ chars = sz.chars, char_type = sz.char_type,
+ kanjiskip = sz.kanjiskip, xkanjiskip = sz.xkanjiskip,
+ chars_cbcache = {},
+ vert_activated = vert_activated,
+ }
+ local t = identifiers[fn]
+ if auto_enable_vrt2 then
+ local lang, scr = t.properties.language, t.properties.script
+ local vrt2_exist = provides_feature(
+ fn, t.properties.script, t.properties.language, 'vrt2'
+ )
+ t.shared.features[vrt2_exist and 'vrt2' or 'vert'] = true
+ end
+
+ --texio.write_nl('term and log',
+ --'JFNT\t' .. identifiers[fn].name .. '\t' .. identifiers[fn].size .. '\t' .. fn, '')
+
+ fmtable = luatexbase.call_callback("luatexja.define_jfont", fmtable, fn)
+ font_metric_table[fn]=fmtable
+ tex.sprint(cat_lp, global_flag, '\\protected\\expandafter\\def\\csname ',
+ (cstemp==' ') and '\\space' or cstemp, '\\endcsname{\\ltj@cur'..
+ (jfm_dir == 'yoko' and 'j' or 't') .. 'fnt', fn, '\\relax}')
+ jfm_file_name = nil
+ end
+end
+
+do
+ local get_dir_count = ltjd.get_dir_count
+ local dir_tate = luatexja.dir_table.dir_tate
+ local tex_get_attr = tex.getattribute
+ -- PUBLIC function
+ function luatexja.jfont.get_zw()
+ local a = font_metric_table[
+ tex_get_attr((get_dir_count()==dir_tate) and attr_curtfnt or attr_curjfnt)]
+ return a and a.zw or 0
+ end
+ function luatexja.jfont.get_zh()
+ local a = font_metric_table[
+ tex_get_attr((get_dir_count()==dir_tate) and attr_curtfnt or attr_curjfnt)]
+ return a and a.zw or 0
+ end
+end
+
+do
+ local gmatch = string.gmatch
+ -- extract jfm_file_name and jfm_var
+ -- normalize position of 'jfm=' and 'jfmvar=' keys
+ local function extract_metric(name)
+ do
+ local nametemp
+ nametemp = name:match('^{(.*)}$')
+ if nametemp then name = nametemp
+ else
+ nametemp = name:match('^"(.*)"$')
+ name = nametemp or name
+ end
+ end
+ jfm_file_name = ''; jfm_var = ''; jfm_ksp = true
+ local tmp, index = name:sub(1, 5), 1
+ if tmp == 'file:' or tmp == 'name:' or tmp == 'psft:' then
+ index = 6
+ end
+ local p = name:find(":", index); index = p and (p+1) or index
+ while index do
+ local l = name:len()+1
+ local q = name:find(";", index) or l
+ if name:sub(index, index+3)=='jfm=' and q>index+4 then
+ jfm_file_name = name:sub(index+4, q-1)
+ if l~=q then
+ name = name:sub(1,index-1) .. name:sub(q+1)
+ else
+ name = name:sub(1,index-1)
+ index = nil
+ end
+ elseif name:sub(index, index+6)=='jfmvar=' and q>index+6 then
+ jfm_var = name:sub(index+7, q-1)
+ if l~=q then
+ name = name:sub(1,index-1) .. name:sub(q+1)
+ else
+ name = name:sub(1,index-1)
+ index = nil
+ end
+ else
+ index = (l~=q) and (q+1) or nil
+ end
+ end
+ if jfm_file_name~='' then
+ local l = name:sub(-1)
+ name = name
+ .. ((l==':' or l==';') and '' or ';')
+ .. 'jfm=' .. jfm_file_name
+ if jfm_var~='' then
+ name = name .. ';jfmvar=' .. jfm_var
+ end
+ end
+ for x in gmatch (name, "[:;]([+%%-]?)ltjks") do
+ jfm_ksp = not (x=='-')
+ end
+ if jfm_dir == 'tate' then
+ vert_activated = (not name:match('[:;]%-vert')) and (not name:match('[:;]%-vrt2'))
+ auto_enable_vrt2
+ = (not name:match('[:;][+%-]?vert')) and (not name:match('[:;][+%-]?vrt2'))
+ else
+ vert_activated, auto_enable_vrt2 = nil, nil
+ end
+ return name
+ end
+
+ -- define_font callback
+ local otfl_fdr
+ local ltjr_font_callback = ltjr.font_callback
+ function luatexja.font_callback(name, size, id)
+ local new_name = is_def_jfont and extract_metric(name) or name
+ is_def_jfont = false
+ local res = ltjr_font_callback(new_name, size, id, otfl_fdr)
+ luatexbase.call_callback('luatexja.define_font', res, new_name, size, id)
+ -- this callback processes variation selector, so we execute it always
+ return res
+ end
+ luatexbase.create_callback('luatexja.define_font', 'simple', function (n) return n end)
+ otfl_fdr= luatexbase.remove_from_callback('define_font', 'luaotfload.define_font')
+ luatexbase.add_to_callback('define_font',luatexja.font_callback,"luatexja.font_callback", 1)
+
+ local match, sp = string.match, tex.sp
+ local function load_jfmonly(spec, dir)
+ local spec, size = match(spec,'(.+)%s+at%s*([%.%w]*)')
+ size = sp(size); extract_metric(spec)
+ jfm_dir = dir
+ local i = load_jfont_metric()
+ local j = -update_jfm_cache(i, size)
+ font_metric_table[j]=metrics[i].size_cache[s]
+ tex.sprint(cat_lp, '\\ltj@cur' .. (dir=='yoko' and 'j' or 't') .. 'fnt' .. tostring(j) .. '\\relax')
+ end
+ luatexja.jfont.load_jfmonly = load_jfmonly
+end
+
+------------------------------------------------------------------------
+-- LATEX INTERFACE
+------------------------------------------------------------------------
+do
+ -- these function are called from ltj-latex.sty
+ local fenc_list, kyenc_list, ktenc_list = {}, {}, {}
+ function luatexja.jfont.add_fenc_list(enc) fenc_list[enc] = 'true ' end
+ function luatexja.jfont.add_kyenc_list(enc) kyenc_list[enc] = 'true ' end
+ function luatexja.jfont.add_ktenc_list(enc) ktenc_list[enc] = 'true ' end
+ function luatexja.jfont.is_kyenc(enc)
+ tex.sprint(cat_lp, '\\let\\ifin@\\if' .. (kyenc_list[enc] or 'false '))
+ end
+ function luatexja.jfont.is_ktenc(enc)
+ tex.sprint(cat_lp, '\\let\\ifin@\\if' .. (ktenc_list[enc] or 'false '))
+ end
+ function luatexja.jfont.is_kenc(enc)
+ tex.sprint(cat_lp, '\\let\\ifin@\\if'
+ .. (kyenc_list[enc] or ktenc_list[enc] or 'false '))
+ end
+
+ local kfam_list, Nkfam_list = {}, {}
+ function luatexja.jfont.add_kfam(fam)
+ kfam_list[fam]=true
+ end
+ function luatexja.jfont.search_kfam(fam, use_fd)
+ if kfam_list[fam] then
+ tex.sprint(cat_lp, '\\let\\ifin@\\iftrue '); return
+ elseif Nkfam_list[fam] then
+ tex.sprint(cat_lp, '\\let\\ifin@\\iffalse '); return
+ elseif use_fd then
+ for i,_ in pairs(kyenc_list) do
+ if kpse.find_file(string.lower(i)..fam..'.fd') then
+ tex.sprint(cat_lp, '\\let\\ifin@\\iftrue '); return
+ end
+ end
+ for i,_ in pairs(ktenc_list) do
+ if kpse.find_file(string.lower(i)..fam..'.fd') then
+ tex.sprint(cat_lp, '\\let\\ifin@\\iftrue '); return
+ end
+ end
+ Nkfam_list[fam]=true; tex.sprint(cat_lp, '\\let\\ifin@\\iffalse '); return
+ else
+ tex.sprint(cat_lp, '\\let\\ifin@\\iffalse '); return
+ end
+ end
+ local ffam_list, Nffam_list = {}, {}
+ function luatexja.jfont.is_ffam(fam)
+ tex.sprint(cat_lp, '\\let\\ifin@\\if' .. (ffam_list[fam] or 'false '))
+ end
+ function luatexja.jfont.add_ffam(fam)
+ ffam_list[fam]='true '
+ end
+ function luatexja.jfont.search_ffam_declared()
+ local s = ''
+ for i,_ in pairs(fenc_list) do
+ s = s .. '\\cdp@elt{' .. i .. '}'
+ end
+ tex.sprint(cat_lp, s)
+ end
+ function luatexja.jfont.search_ffam_fd(fam)
+ if Nffam_list[fam] then
+ tex.sprint(cat_lp, '\\let\\ifin@\\iffalse '); return
+ else
+ for i,_ in pairs(fenc_list) do
+ if kpse.find_file(string.lower(i)..fam..'.fd') then
+ tex.sprint(cat_lp, '\\let\\ifin@\\iftrue '); return
+ end
+ end
+ Nffam_list[fam]=true; tex.sprint(cat_lp, '\\let\\ifin@\\iffalse '); return
+ end
+ end
+
+end
+------------------------------------------------------------------------
+-- ALTERNATE FONTS
+------------------------------------------------------------------------
+local alt_font_table = {}
+local attr_curaltfnt = {}
+local ucs_out = 0x110000
+
+------ for TeX interface
+-- EXT
+function luatexja.jfont.set_alt_font(b,e,ind,bfnt)
+ -- ind: 新フォント, bfnt: 基底フォント
+ if b>e then b, e = e, b end
+ if b*e<=0 then
+ ltjb.package_error('luatexja',
+ 'bad character range ([' .. b .. ',' .. e .. ']). ' ..
+ 'I take the intersection with [0x80, 0x10ffff].')
+ b, e = math.max(0x80,b),math.min(ucs_out-1,e)
+ elseif e<0 then -- b<e<0
+ -- do nothing
+ elseif b<0x80 or e>=ucs_out then
+ ltjb.package_warning('luatexja',
+ 'bad character range ([' .. b .. ',' .. e .. ']). ' ..
+ 'I take the intersection with [0x80, 0x10ffff].')
+ b, e = math.max(0x80,b), math.min(ucs_out-1,e)
+ end
+ if not alt_font_table[bfnt] then alt_font_table[bfnt]={} end
+ local t = alt_font_table[bfnt]
+ local ac = font_getfont(ind).characters
+ if bfnt==ind then ind = nil end -- ind == bfnt ã®å ´åˆã¯ãƒ†ãƒ¼ãƒ–ルã‹ã‚‰å‰Šé™¤
+ if e>=0 then -- character range
+ for i=b, e do
+ if ac[i]then t[i]=ind end
+ end
+ else
+ b, e = -e, -b
+ local tx = font_metric_table[bfnt].chars
+ for i,v in pairs(tx) do
+ if b<=v and v<=e and ac[i] then t[i]=ind end
+ end
+ end
+end
+
+-- EXT
+function luatexja.jfont.clear_alt_font(bfnt)
+ if alt_font_table[bfnt] then
+ local t = alt_font_table[bfnt]
+ for i,_ in pairs(t) do t[i]=nil; end
+ end
+end
+
+------ used in ltjp.suppress_hyphenate_ja callback
+function luatexja.jfont.replace_altfont(pf, pc)
+ local a = alt_font_table[pf]
+ return a and a[pc] or pf
+end
+
+------ for LaTeX interface
+
+local alt_font_table_latex = {}
+
+-- EXT
+function luatexja.jfont.clear_alt_font_latex(bbase)
+ local t = alt_font_table_latex[bbase]
+ if t then
+ for j,v in pairs(t) do t[j] = nil end
+ end
+end
+
+-- EXT
+function luatexja.jfont.set_alt_font_latex(b,e,ind,bbase)
+ -- ind: Alt font 㮠enc/fam/ser/shape, bbase: 基底フォント㮠enc/fam/ser/shape
+ if b>e then b, e = e, b end
+ if b*e<=0 then
+ ltjb.package_error('luatexja',
+ 'bad character range ([' .. b .. ',' .. e .. ']). ' ..
+ 'I take the intersection with [0x80, 0x10ffff].')
+ b, e = math.max(0x80,b),math.min(ucs_out-1,e)
+ elseif e<0 then -- b<e<0
+ -- do nothing
+ elseif b<0x80 or e>=ucs_out then
+ ltjb.package_warning('luatexja',
+ 'bad character range ([' .. b .. ',' .. e .. ']). ' ..
+ 'I take the intersection with [0x80, 0x10ffff].')
+ b, e = math.max(0x80,b), math.min(ucs_out-1,e)
+ end
+
+ if not alt_font_table_latex[bbase] then alt_font_table_latex[bbase]={} end
+ local t = alt_font_table_latex[bbase]
+ if not t[ind] then t[ind] = {} end
+ for i=b, e do
+ for j,v in pairs(t) do
+ if v[i] then -- remove old entry
+ if j~=ind then v[i]=nil end; break
+ end
+ end
+ t[ind][i]=true
+ end
+ -- remove the empty tables
+ for j,v in pairs(t) do
+ local flag_clear = true
+ for k,_ in pairs(v) do flag_clear = false; break end
+ if flag_clear then t[j]=nil end
+ end
+ if ind==bbase then t[bbase] = nil end
+end
+
+-- ã“ã“ã‹ã‚‰å…ˆã¯ æ–° \selectfont ã®å†…部ã§ã—ã‹å®Ÿè¡Œã•ã‚Œãªã„
+do
+ local alt_font_base, alt_font_base_num
+ local aftl_base
+ -- EXT
+ function luatexja.jfont.does_alt_set(bbase)
+ aftl_base = alt_font_table_latex[bbase]
+ tex.sprint(cat_lp, aftl_base and '\\@firstofone' or '\\@gobble')
+ end
+ -- EXT
+ function luatexja.jfont.print_aftl_address()
+ return ';ltjaltfont' .. tostring(aftl_base):sub(8)
+ end
+
+-- EXT
+ function luatexja.jfont.output_alt_font_cmd(dir, bbase)
+ alt_font_base = bbase
+ if dir == 't' then
+ alt_font_base_num = tex.getattribute(attr_curtfnt)
+ else
+ alt_font_base_num = tex.getattribute(attr_curjfnt)
+ end
+ local t = alt_font_table[alt_font_base_num]
+ if t then
+ for i,_ in pairs(t) do t[i]=nil end
+ end
+ t = alt_font_table_latex[bbase]
+ if t then
+ for i,_ in pairs(t) do
+ tex.sprint(cat_lp, '\\ltj@pickup@altfont@aux' .. dir .. '{' .. i .. '}')
+ end
+ end
+ end
+
+-- EXT
+ function luatexja.jfont.pickup_alt_font_a(size_str)
+ local t = alt_font_table_latex[alt_font_base]
+ if t then
+ for i,v in pairs(t) do
+ tex.sprint(cat_lp, '\\expandafter\\ltj@pickup@altfont@copy'
+ .. '\\csname ' .. i .. '/' .. size_str .. '\\endcsname{' .. i .. '}')
+ end
+ end
+ end
+
+ local function pickup_alt_font_class(class, afnt_num, afnt_chars)
+ local t = alt_font_table[alt_font_base_num]
+ local tx = font_metric_table[alt_font_base_num].chars
+ for i,v in pairs(tx) do
+ if v==class and afnt_chars[i] then t[i]=afnt_num end
+ end
+ end
+
+-- EXT
+ function luatexja.jfont.pickup_alt_font_b(afnt_num, afnt_base)
+ local t = alt_font_table[alt_font_base_num]
+ local ac = font_getfont(afnt_num).characters
+ if not t then t = {}; alt_font_table[alt_font_base_num] = t end
+ for i,v in pairs(alt_font_table_latex[alt_font_base]) do
+ if i == afnt_base then
+ for j,_ in pairs(v) do
+ if j>=0 then
+ if ac[j] then t[j]=afnt_num end
+ else -- -n (n>=1) means that the character class n,
+ -- which is defined in the JFM
+ pickup_alt_font_class(-j, afnt_num, ac)
+ end
+ end
+ return
+ end
+ end
+ end
+
+end
+------------------------------------------------------------------------
+-- 終了時ã«å„種ノードを破棄
+------------------------------------------------------------------------
+do
+ function luatexja.jfont.cleanup_size_cache()
+ --local gs, ke = 0, 0
+ for _,n in pairs(metrics) do
+ for i,t in pairs(n.size_cache) do
+ for _,v in pairs(t.char_type) do
+ for k,w in pairs(v) do
+ if type(k)=='number' then
+ --if w[1] then gs = gs + 1 else ke = ke + 1 end
+ if w[1] then node_free(w[1]) end
+ end
+ end
+ end
+ n.size_cache[i]=nil
+ end
+ end
+ end
+end
+
+------------------------------------------------------------------------
+-- 追加ã®ãƒ•ã‚©ãƒ³ãƒˆæƒ…å ±
+------------------------------------------------------------------------
+local font_extra_info = {}
+luatexja.jfont.font_extra_info= font_extra_info -- key: fontnumber
+local font_extra_basename = {} -- key: basename
+
+local list_rotate_glyphs
+do
+ -- output of function_uax50.lua
+ -- UAX#50 for Unicode 12.1.0
+ -- t[0] = true
+ local t={ 0, 167, 168, 169, 170, 174, 175, 177, 178, 188, 191, 215, 216, 247, 248, 746, 748, 888, 890, 896, 900, 907, 908, 909, 910, 930, 931, 1328, 1329, 1367, 1369, 1419, 1421, 1424, 1425, 1480, 1488, 1515, 1519, 1525, 1536, 1565, 1566, 1806, 1807, 1867, 1869, 1970, 1984, 2043, 2045, 2094, 2096, 2111, 2112, 2140, 2142, 2143, 2144, 2155, 2208, 2229, 2230, 2238, 2259, 2436, 2437, 2445, 2447, 2449, 2451, 2473, 2474, 2481, 2482, 2483, 2486, 2490, 2492, 2501, 2503, 2505, 2507, 2511, 2519, 2520, 2524, 2526, 2527, 2532, 2534, 2559, 2561, 2564, 2565, 2571, 2575, 2577, 2579, 2601, 2602, 2609, 2610, 2612, 2613, 2615, 2616, 2618, 2620, 2621, 2622, 2627, 2631, 2633, 2635, 2638, 2641, 2642, 2649, 2653, 2654, 2655, 2662, 2679, 2689, 2692, 2693, 2702, 2703, 2706, 2707, 2729, 2730, 2737, 2738, 2740, 2741, 2746, 2748, 2758, 2759, 2762, 2763, 2766, 2768, 2769, 2784, 2788, 2790, 2802, 2809, 2816, 2817, 2820, 2821, 2829, 2831, 2833, 2835, 2857, 2858, 2865, 2866, 2868, 2869, 2874, 2876, 2885, 2887, 2889, 2891, 2894, 2902, 2904, 2908, 2910, 2911, 2916, 2918, 2936, 2946, 2948, 2949, 2955, 2958, 2961, 2962, 2966, 2969, 2971, 2972, 2973, 2974, 2976, 2979, 2981, 2984, 2987, 2990, 3002, 3006, 3011, 3014, 3017, 3018, 3022, 3024, 3025, 3031, 3032, 3046, 3067, 3072, 3085, 3086, 3089, 3090, 3113, 3114, 3130, 3133, 3141, 3142, 3145, 3146, 3150, 3157, 3159, 3160, 3163, 3168, 3172, 3174, 3184, 3191, 3213, 3214, 3217, 3218, 3241, 3242, 3252, 3253, 3258, 3260, 3269, 3270, 3273, 3274, 3278, 3285, 3287, 3294, 3295, 3296, 3300, 3302, 3312, 3313, 3315, 3328, 3332, 3333, 3341, 3342, 3345, 3346, 3397, 3398, 3401, 3402, 3408, 3412, 3428, 3430, 3456, 3458, 3460, 3461, 3479, 3482, 3506, 3507, 3516, 3517, 3518, 3520, 3527, 3530, 3531, 3535, 3541, 3542, 3543, 3544, 3552, 3558, 3568, 3570, 3573, 3585, 3643, 3647, 3676, 3713, 3715, 3716, 3717, 3718, 3723, 3724, 3748, 3749, 3750, 3751, 3774, 3776, 3781, 3782, 3783, 3784, 3790, 3792, 3802, 3804, 3808, 3840, 3912, 3913, 3949, 3953, 3992, 3993, 4029, 4030, 4045, 4046, 4059, 4096, 4294, 4295, 4296, 4301, 4302, 4304, 4352, 4608, 4681, 4682, 4686, 4688, 4695, 4696, 4697, 4698, 4702, 4704, 4745, 4746, 4750, 4752, 4785, 4786, 4790, 4792, 4799, 4800, 4801, 4802, 4806, 4808, 4823, 4824, 4881, 4882, 4886, 4888, 4955, 4957, 4989, 4992, 5018, 5024, 5110, 5112, 5118, 5120, 5121, 5760, 5789, 5792, 5881, 5888, 5901, 5902, 5909, 5920, 5943, 5952, 5972, 5984, 5997, 5998, 6001, 6002, 6004, 6016, 6110, 6112, 6122, 6128, 6138, 6144, 6159, 6160, 6170, 6176, 6265, 6272, 6315, 6400, 6431, 6432, 6444, 6448, 6460, 6464, 6465, 6468, 6510, 6512, 6517, 6528, 6572, 6576, 6602, 6608, 6619, 6622, 6684, 6686, 6751, 6752, 6781, 6783, 6794, 6800, 6810, 6816, 6830, 6832, 6847, 6912, 6988, 6992, 7037, 7040, 7156, 7164, 7224, 7227, 7242, 7245, 7305, 7312, 7355, 7357, 7368, 7376, 7419, 7424, 7674, 7675, 7958, 7960, 7966, 7968, 8006, 8008, 8014, 8016, 8024, 8025, 8026, 8027, 8028, 8029, 8030, 8031, 8062, 8064, 8117, 8118, 8133, 8134, 8148, 8150, 8156, 8157, 8176, 8178, 8181, 8182, 8191, 8192, 8214, 8215, 8224, 8226, 8240, 8242, 8251, 8253, 8258, 8259, 8263, 8266, 8273, 8274, 8293, 8294, 8306, 8308, 8335, 8336, 8349, 8352, 8384, 8400, 8413, 8417, 8418, 8421, 8433, 8450, 8451, 8458, 8463, 8464, 8467, 8469, 8470, 8472, 8478, 8484, 8485, 8486, 8487, 8488, 8489, 8490, 8494, 8495, 8501, 8512, 8517, 8523, 8524, 8526, 8527, 8586, 8588, 8592, 8734, 8735, 8756, 8758, 8960, 8968, 8972, 8992, 8996, 9001, 9003, 9004, 9085, 9115, 9150, 9166, 9167, 9168, 9169, 9180, 9186, 9251, 9252, 9472, 9632, 9754, 9760, 10088, 10102, 10132, 11026, 11056, 11088, 11098, 11124, 11126, 11158, 11160, 11192, 11218, 11219, 11244, 11248, 11264, 11311, 11312, 11359, 11360, 11508, 11513, 11558, 11559, 11560, 11565, 11566, 11568, 11624, 11631, 11633, 11647, 11671, 11680, 11687, 11688, 11695, 11696, 11703, 11704, 11711, 11712, 11719, 11720, 11727, 11728, 11735, 11736, 11743, 11744, 11856, 12296, 12306, 12308, 12320, 12336, 12337, 12448, 12449, 12540, 12541, 42192, 42540, 42560, 42744, 42752, 42944, 42946, 42951, 42999, 43052, 43056, 43066, 43072, 43128, 43136, 43206, 43214, 43226, 43232, 43348, 43359, 43360, 43392, 43470, 43471, 43482, 43486, 43519, 43520, 43575, 43584, 43598, 43600, 43610, 43612, 43715, 43739, 43767, 43777, 43783, 43785, 43791, 43793, 43799, 43808, 43815, 43816, 43823, 43824, 43880, 43888, 44014, 44016, 44026, 55296, 57344, 64256, 64263, 64275, 64280, 64285, 64311, 64312, 64317, 64318, 64319, 64320, 64322, 64323, 64325, 64326, 64450, 64467, 64832, 64848, 64912, 64914, 64968, 65008, 65022, 65024, 65040, 65056, 65072, 65097, 65104, 65112, 65119, 65123, 65127, 65136, 65141, 65142, 65277, 65279, 65280, 65288, 65290, 65293, 65294, 65306, 65311, 65339, 65340, 65341, 65342, 65343, 65344, 65371, 65471, 65474, 65480, 65482, 65488, 65490, 65496, 65498, 65501, 65507, 65508, 65512, 65519, 65529, 65532, 65536, 65548, 65549, 65575, 65576, 65595, 65596, 65598, 65599, 65614, 65616, 65630, 65664, 65787, 65792, 65795, 65799, 65844, 65847, 65935, 65936, 65948, 65952, 65953, 66000, 66046, 66176, 66205, 66208, 66257, 66272, 66300, 66304, 66340, 66349, 66379, 66384, 66427, 66432, 66462, 66463, 66500, 66504, 66518, 66560, 66718, 66720, 66730, 66736, 66772, 66776, 66812, 66816, 66856, 66864, 66916, 66927, 66928, 67072, 67383, 67392, 67414, 67424, 67432, 67584, 67590, 67592, 67593, 67594, 67638, 67639, 67641, 67644, 67645, 67647, 67670, 67671, 67743, 67751, 67760, 67808, 67827, 67828, 67830, 67835, 67868, 67871, 67898, 67903, 67904, 68000, 68024, 68028, 68048, 68050, 68100, 68101, 68103, 68108, 68116, 68117, 68120, 68121, 68150, 68152, 68155, 68159, 68169, 68176, 68185, 68192, 68256, 68288, 68327, 68331, 68343, 68352, 68406, 68409, 68438, 68440, 68467, 68472, 68498, 68505, 68509, 68521, 68528, 68608, 68681, 68736, 68787, 68800, 68851, 68858, 68904, 68912, 68922, 69216, 69247, 69376, 69416, 69424, 69466, 69600, 69623, 69632, 69710, 69714, 69744, 69759, 69826, 69837, 69838, 69840, 69865, 69872, 69882, 69888, 69941, 69942, 69959, 69968, 70007, 70016, 70094, 70096, 70112, 70113, 70133, 70144, 70162, 70163, 70207, 70272, 70279, 70280, 70281, 70282, 70286, 70287, 70302, 70303, 70314, 70320, 70379, 70384, 70394, 70400, 70404, 70405, 70413, 70415, 70417, 70419, 70441, 70442, 70449, 70450, 70452, 70453, 70458, 70459, 70469, 70471, 70473, 70475, 70478, 70480, 70481, 70487, 70488, 70493, 70500, 70502, 70509, 70512, 70517, 70656, 70746, 70747, 70748, 70749, 70752, 70784, 70856, 70864, 70874, 71168, 71237, 71248, 71258, 71264, 71277, 71296, 71353, 71360, 71370, 71424, 71451, 71453, 71468, 71472, 71488, 71680, 71740, 71840, 71923, 71935, 71936, 72096, 72104, 72106, 72152, 72154, 72165, 72384, 72441, 72704, 72713, 72714, 72759, 72760, 72774, 72784, 72813, 72816, 72848, 72850, 72872, 72873, 72887, 72960, 72967, 72968, 72970, 72971, 73015, 73018, 73019, 73020, 73022, 73023, 73032, 73040, 73050, 73056, 73062, 73063, 73065, 73066, 73103, 73104, 73106, 73107, 73113, 73120, 73130, 73440, 73465, 73664, 73714, 73727, 74650, 74752, 74863, 74864, 74869, 74880, 75076, 92160, 92729, 92736, 92767, 92768, 92778, 92782, 92784, 92880, 92910, 92912, 92918, 92928, 92998, 93008, 93018, 93019, 93026, 93027, 93048, 93053, 93072, 93760, 93851, 93952, 94027, 94031, 94088, 94095, 94112, 113664, 113771, 113776, 113789, 113792, 113801, 113808, 113818, 113820, 113828, 119296, 119366, 119808, 119893, 119894, 119965, 119966, 119968, 119970, 119971, 119973, 119975, 119977, 119981, 119982, 119994, 119995, 119996, 119997, 120004, 120005, 120070, 120071, 120075, 120077, 120085, 120086, 120093, 120094, 120122, 120123, 120127, 120128, 120133, 120134, 120135, 120138, 120145, 120146, 120486, 120488, 120780, 120782, 120832, 122880, 122887, 122888, 122905, 122907, 122914, 122915, 122917, 122918, 122923, 123136, 123181, 123184, 123198, 123200, 123210, 123214, 123216, 123584, 123642, 123647, 123648, 124928, 125125, 125127, 125143, 125184, 125260, 125264, 125274, 125278, 125280, 126065, 126133, 126209, 126270, 126464, 126468, 126469, 126496, 126497, 126499, 126500, 126501, 126503, 126504, 126505, 126515, 126516, 126520, 126521, 126522, 126523, 126524, 126530, 126531, 126535, 126536, 126537, 126538, 126539, 126540, 126541, 126544, 126545, 126547, 126548, 126549, 126551, 126552, 126553, 126554, 126555, 126556, 126557, 126558, 126559, 126560, 126561, 126563, 126564, 126565, 126567, 126571, 126572, 126579, 126580, 126584, 126585, 126589, 126590, 126591, 126592, 126602, 126603, 126620, 126625, 126628, 126629, 126634, 126635, 126652, 126704, 126706, 129024, 129036, 129040, 129096, 129104, 129114, 129120, 129160, 129168, 129198, 917505, 917506, 917536, 917632, 917760, 918000 }
+ local function rotate_in_uax50(i)
+ local lo, hi = 1, #t
+ while lo < hi do
+ local mi = math.ceil((lo+hi)/2)
+ if t[mi]<=i then lo=mi else hi=mi-1 end
+ end
+ return lo%2==1
+ end
+ list_rotate_glyphs = function (dest, id)
+ if id.specification and id.resources then
+ local rot = {}
+ for i,_ in pairs(id.characters) do
+ if rotate_in_uax50(i) then rot[i] = true end
+ end
+ if id.resources.sequences then
+ for _,i in pairs(id.resources.sequences) do
+ if i.order[1]== 'vert' and i.type == 'gsub_single' and i.steps then
+ for _,j in pairs(i.steps) do
+ if type(j)=='table' then
+ if type(j.coverage)=='table' then
+ for i,_ in pairs(j.coverage) do rot[i]=nil end
+ end
+ end
+ end
+ end
+ end; end
+ -- コードãƒã‚¤ãƒ³ãƒˆãŒå…±æœ‰ã•ã‚Œã¦ã„るグリフã«ã¤ã„ã¦
+ if id.resources.duplicates then
+ for i,v in pairs(id.resources.duplicates) do
+ local f = rot[i]
+ for j,_ in pairs(v) do f = f and rot[j] end
+ rot[i]=f
+ for j,_ in pairs(v) do rot[j] = f end
+ end; end
+
+ for i,_ in pairs(rot) do
+ dest = dest or {}
+ dest.rotation = dest.rotation or {}
+ dest.rotation[i] = true
+ end
+ end
+ return dest
+ end
+end
+
+-- vertical metrics
+local prepare_fl_data
+do
+ local sort = table.sort
+ prepare_fl_data = function (dest, id)
+ local ascent = id.shared.rawdata.metadata.ascender
+ local t_vorigin, t_ind_to_uni = {}, {}
+ for i,v in pairs(id.shared.rawdata.descriptions) do
+ t_ind_to_uni[v.index] = i
+ if v.tsb then
+ local j = v.boundingbox[4] + v.tsb
+ if j~=ascent then t_vorigin[i]=j end
+ end
+ end
+ dest = dest or {}
+ dest.ind_to_uni = t_ind_to_uni
+ dest.vorigin = t_vorigin
+ return dest
+ end
+end
+
+--
+do
+ local function prepare_extra_data_base(id)
+ if (not id) or (not id.filename) then return end
+ local bname = id.psname or file.nameonly(id.filename)
+ if not font_extra_basename[bname] then
+ ltjb.remove_cache("extra_" .. string.lower(bname)) -- remove cache
+ local dat = prepare_fl_data(dat, id)
+ dat = list_rotate_glyphs(dat, id)
+ font_extra_basename[bname] = dat or {}
+ return bname
+ end
+ end
+ local function prepare_extra_data_font(id, res)
+ if type(res)=='table' and res.shared and (res.psname or res.filename) then
+ font_extra_info[id] = font_extra_basename[res.psname or file.nameonly(res.filename)]
+ end
+ end
+ luatexbase.add_to_callback(
+ 'luaotfload.patch_font',
+ function (tfmdata)
+ -- these function is executed one time per one fontfile
+ prepare_extra_data_base(tfmdata); return tfmdata
+ end,
+ 'ltj.prepare_extra_data', 1)
+ luatexbase.add_to_callback(
+ 'luatexja.define_font',
+ function (res, name, size, id)
+ prepare_extra_data_font(id, res)
+ end,
+ 'ltj.prepare_extra_data', 1)
+
+ local nulltable = {} -- dummy
+ ltjr.vert_addfunc = function (n) font_extra_info[n] = nulltable end
+
+ local identifiers = fonts.hashes.identifiers
+ for i=1,font.nextid()-1 do
+ if identifiers[i] then
+ prepare_extra_data_base(identifiers[i])
+ prepare_extra_data_font(i,identifiers[i])
+ end
+ end
+end
+
+------------------------------------------------------------------------
+-- make table of vertical glyphs which does not covered by vert feature
+-- nor UTR#50
+------------------------------------------------------------------------
+do
+------------------------------------------------------------------------
+-- VERT VARIANT TABLE
+------------------------------------------------------------------------
+ local provides_feature = luaotfload.aux.provides_feature
+ local vert_form_table = {
+ [0x3001]=0xFE11, [0x3002]=0xFE12, [0x3016]=0xFE17, [0x3017]=0xFE18,
+ [0x2026]=0xFE19,
+ [0x2025]=0xFE30, [0x2014]=0xFE31, [0x2013]=0xFE32, [0xFF3F]=0xFE33,
+ [0xFF08]=0xFE35, [0xFF09]=0xFE36, [0xFF5B]=0xFE37, [0xFF5D]=0xFE38,
+ [0x3014]=0xFE39, [0x3015]=0xFE3A, [0x3010]=0xFE3B, [0x3011]=0xFE3C,
+ [0x300A]=0xFE3D, [0x300B]=0xFE3E, [0x3008]=0xFE3F, [0x3009]=0xFE40,
+ [0x300C]=0xFE41, [0x300D]=0xFE42, [0x300E]=0xFE43, [0x300F]=0xFE44,
+ [0xFF3B]=0xFE47, [0xFF3D]=0xFE48,
+ }
+ local vert_jpotf_table = {}
+ local function add_vform(coverage, vform, ft, add_vert, jpotf_vert)
+ if type(coverage)~='table' then return end
+ for i,v in pairs(vert_form_table) do
+ if not coverage[i] and ft.characters[v] then vform[i] = v end
+ end
+ if jpotf_vert then
+ for i,v in pairs(vert_jpotf_table) do
+ if ft.characters[v] then vform[i] = coverage[v] or vform[v] or v end
+ end
+ end
+ if add_vert then -- vert feature ãŒæœ‰åŠ¹ã«ãªã‚‰ãªã„å ´åˆ
+ for i,v in pairs(coverage) do vform[i] = vform[i] or v end
+ end
+ end
+
+ local utfbyte, utfsub = utf.byte, utf.sub
+ luatexja.jfont.register_vert_replace = function(t)
+ for i,v in pairs(t) do
+ local ic = (type(i)=='number') and i or
+ ((type(i)=='string') and utfbyte(utfsub(i,1,1)) or nil)
+ if ic then
+ vert_jpotf_table[ic] = (type(v)=='number') and v or
+ ((type(v)=='string') and utfbyte(utfsub(v,1,1)) or nil)
+ end
+ end
+ end
+
+luatexbase.add_to_callback(
+ "luatexja.define_jfont",
+ function (fmtable, fnum)
+ local vform = {}; fmtable.vform = vform
+ local t = font_getfont(fnum)
+ if t.specification and t.resources then
+ local add_vert
+ = not (provides_feature(fnum, t.properties.script, t.properties.language, 'vert'))
+ and not (provides_feature(fnum, t.properties.script, t.properties.language, 'vrt2'))
+ local jpotf_vert = t.shared.features.jpotf
+ -- ç¾åœ¨ã® language, script 㧠vert ã‚‚vrt2 も有効ã«ã§ããªã„å ´åˆï¼Œå¼·åˆ¶çš„ã« vert é©ç”¨
+ for _,i in pairs(t.resources.sequences) do
+ if i.order[1]== 'vert' and i.type == 'gsub_single' and i.steps then
+ for _,j in pairs(i.steps) do
+ if type(j)=='table' then
+ add_vform(j.coverage,vform, t, add_vert, jpotf_vert)
+ end
+ end
+ end
+ end
+ end
+ return fmtable
+ end, 'ltj.get_vert_form', 1
+)
+end
+
+------------------------------------------------------------------------
+-- supply tounicode entries
+------------------------------------------------------------------------
+do
+ local ltjr_prepare_cid_font = ltjr.prepare_cid_font
+ luatexbase.add_to_callback(
+ 'luaotfload.patch_font',
+ function (tfmdata)
+ local cidinfo = tfmdata.cidinfo or tfmdata.resources.cidinfo
+ if cidinfo and cidinfo.registry and cidinfo.ordering then
+ local rd = ltjr_prepare_cid_font(cidinfo.registry, cidinfo.ordering)
+ if rd then
+ local ru, rc = rd.resources.unicodes, rd.characters
+ for i,v in pairs(tfmdata.characters) do
+ local w = ru["Japan1." .. tostring(v.index)]
+ if w then
+ v.tounicode = v.tounicode or rc[w]. tounicode
+ end
+ end
+ end
+ end
+
+ return tfmdata
+ end,
+ 'ltj.supply_tounicode', 1)
+end
+
+
+------------------------------------------------------------------------
+-- MISC
+------------------------------------------------------------------------
+do
+ local getfont = node.direct.getfont
+ local getchar = node.direct.getchar
+ local get_dir_count = ltjd.get_dir_count
+ local is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char_direct
+ local ensure_tex_attr = ltjb.ensure_tex_attr
+ local node_write = node.direct.write
+ local font = font
+ local new_ic_kern
+ local dir_tate = luatexja.dir_table.dir_tate
+ if status.luatex_version>=89 then
+ new_ic_kern = function(g) return node_new(id_kern,3) end
+ else
+ local ITALIC = luatexja.icflag_table.ITALIC
+ new_ic_kern = function()
+ local g = node_new(id_kern, 1)
+ set_attr(g, attr_icflag, ITALIC)
+ return g
+ end
+ end
+ -- EXT: italic correction
+ function luatexja.jfont.append_italic()
+ local p = to_direct(tex.nest[tex.nest.ptr].tail)
+ local TEMP = node_new(id_kern)
+ if p and getid(p)==id_glyph then
+ if is_ucs_in_japanese_char(p) then
+ local j = font_metric_table[
+ has_attr(p, (get_dir_count()==dir_tate) and attr_curtfnt or attr_curjfnt)
+ ]
+ local g = new_ic_kern()
+ setfield(g, 'kern', j.char_type[find_char_class(getchar(p), j)].italic)
+ node_write(g); ensure_tex_attr(attr_icflag, 0)
+ else
+ local f = getfont(p)
+ local h = font_getfont(f) or font.fonts[f]
+ if h then
+ local g = new_ic_kern()
+ if h.characters[getchar(p)] and h.characters[getchar(p)].italic then
+ setfield(g, 'kern', h.characters[getchar(p)].italic)
+ node_write(g); ensure_tex_attr(attr_icflag, 0)
+ end
+ end
+ end
+ end
+ node_free(TEMP)
+ end
+end
+
+luatexja.jfont.metrics = metrics
+luatexja.jfont.font_metric_table = font_metric_table
+luatexja.jfont.find_char_class = find_char_class
+
+luatexja.jfont.update_jfm_cache = update_jfm_cache
diff --git a/macros/luatex/generic/luatexja/src/ltj-jisx0208.lua b/macros/luatex/generic/luatexja/src/ltj-jisx0208.lua
new file mode 100644
index 0000000000..a31dbcd786
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-jisx0208.lua
@@ -0,0 +1,6883 @@
+return {
+version = 2,
+table_jisx0208_uptex = {
+ [0x101] = 0x3000, --( )
+ [0x102] = 0x3001, --(ã€)
+ [0x103] = 0x3002, --(。)
+ [0x104] = 0xFF0C, --(,)
+ [0x105] = 0xFF0E, --(.)
+ [0x106] = 0x30FB, --(・)
+ [0x107] = 0xFF1A, --(:)
+ [0x108] = 0xFF1B, --(ï¼›)
+ [0x109] = 0xFF1F, --(?)
+ [0x10A] = 0xFF01, --(ï¼)
+ [0x10B] = 0x309B, --(ã‚›)
+ [0x10C] = 0x309C, --(゜)
+ [0x10D] = 0xB4,
+ [0x10E] = 0xFF40, --(ï½€)
+ [0x10F] = 0xA8,
+ [0x110] = 0xFF3E, --(ï¼¾)
+ [0x111] = 0xFFE3, --(ï¿£)
+ [0x112] = 0xFF3F, --(_)
+ [0x113] = 0x30FD, --(ヽ)
+ [0x114] = 0x30FE, --(ヾ)
+ [0x115] = 0x309D, --(ã‚)
+ [0x116] = 0x309E, --(ã‚ž)
+ [0x117] = 0x3003, --(〃)
+ [0x118] = 0x4EDD, --(ä»)
+ [0x119] = 0x3005, --(々)
+ [0x11A] = 0x3006, --(〆)
+ [0x11B] = 0x3007, --(〇)
+ [0x11C] = 0x30FC, --(ー)
+ [0x11D] = 0x2015, --(―)
+ [0x11E] = 0x2010, --(â€)
+ [0x11F] = 0xFF0F, --(ï¼)
+ [0x120] = 0xFF3C, --(ï¼¼)
+ [0x121] = 0x301C, --(〜)
+ [0x122] = 0x2016, --(‖)
+ [0x123] = 0xFF5C, --(|)
+ [0x124] = 0x2026, --(…)
+ [0x125] = 0x2025, --(‥)
+ [0x126] = 0x2018, --(‘)
+ [0x127] = 0x2019, --(’)
+ [0x128] = 0x201C, --(“)
+ [0x129] = 0x201D, --(â€)
+ [0x12A] = 0xFF08, --(()
+ [0x12B] = 0xFF09, --())
+ [0x12C] = 0x3014, --(〔)
+ [0x12D] = 0x3015, --(〕)
+ [0x12E] = 0xFF3B, --(ï¼»)
+ [0x12F] = 0xFF3D, --(ï¼½)
+ [0x130] = 0xFF5B, --(ï½›)
+ [0x131] = 0xFF5D, --(ï½)
+ [0x132] = 0x3008, --(〈)
+ [0x133] = 0x3009, --(〉)
+ [0x134] = 0x300A, --(《)
+ [0x135] = 0x300B, --(》)
+ [0x136] = 0x300C, --(「)
+ [0x137] = 0x300D, --(ã€)
+ [0x138] = 0x300E, --(『)
+ [0x139] = 0x300F, --(ã€)
+ [0x13A] = 0x3010, --(ã€)
+ [0x13B] = 0x3011, --(】)
+ [0x13C] = 0xFF0B, --(+)
+ [0x13D] = 0x2212, --(−)
+ [0x13E] = 0xB1,
+ [0x13F] = 0xD7,
+ [0x140] = 0xF7,
+ [0x141] = 0xFF1D, --(ï¼)
+ [0x142] = 0x2260, --(≠)
+ [0x143] = 0xFF1C, --(<)
+ [0x144] = 0xFF1E, --(>)
+ [0x145] = 0x2266, --(≦)
+ [0x146] = 0x2267, --(≧)
+ [0x147] = 0x221E, --(∞)
+ [0x148] = 0x2234, --(∴)
+ [0x149] = 0x2642, --(♂)
+ [0x14A] = 0x2640, --(♀)
+ [0x14B] = 0xB0,
+ [0x14C] = 0x2032, --(′)
+ [0x14D] = 0x2033, --(″)
+ [0x14E] = 0x2103, --(℃)
+ [0x14F] = 0xFFE5, --(ï¿¥)
+ [0x150] = 0xFF04, --($)
+ [0x151] = 0xFFE0, --(ï¿ )
+ [0x152] = 0xFFE1, --(ï¿¡)
+ [0x153] = 0xFF05, --(ï¼…)
+ [0x154] = 0xFF03, --(#)
+ [0x155] = 0xFF06, --(&)
+ [0x156] = 0xFF0A, --(*)
+ [0x157] = 0xFF20, --(ï¼ )
+ [0x158] = 0xA7,
+ [0x159] = 0x2606, --(☆)
+ [0x15A] = 0x2605, --(★)
+ [0x15B] = 0x25CB, --(â—‹)
+ [0x15C] = 0x25CF, --(â—)
+ [0x15D] = 0x25CE, --(â—Ž)
+ [0x15E] = 0x25C7, --(â—‡)
+ [0x201] = 0x25C6, --(â—†)
+ [0x202] = 0x25A1, --(â–¡)
+ [0x203] = 0x25A0, --(â– )
+ [0x204] = 0x25B3, --(â–³)
+ [0x205] = 0x25B2, --(â–²)
+ [0x206] = 0x25BD, --(â–½)
+ [0x207] = 0x25BC, --(â–¼)
+ [0x208] = 0x203B, --(※)
+ [0x209] = 0x3012, --(〒)
+ [0x20A] = 0x2192, --(→)
+ [0x20B] = 0x2190, --(â†)
+ [0x20C] = 0x2191, --(↑)
+ [0x20D] = 0x2193, --(↓)
+ [0x20E] = 0x3013, --(〓)
+ [0x21A] = 0x2208, --(∈)
+ [0x21B] = 0x220B, --(∋)
+ [0x21C] = 0x2286, --(⊆)
+ [0x21D] = 0x2287, --(⊇)
+ [0x21E] = 0x2282, --(⊂)
+ [0x21F] = 0x2283, --(⊃)
+ [0x220] = 0x222A, --(∪)
+ [0x221] = 0x2229, --(∩)
+ [0x22A] = 0x2227, --(∧)
+ [0x22B] = 0x2228, --(∨)
+ [0x22C] = 0xFFE2, --(ï¿¢)
+ [0x22D] = 0x21D2, --(⇒)
+ [0x22E] = 0x21D4, --(⇔)
+ [0x22F] = 0x2200, --(∀)
+ [0x230] = 0x2203, --(∃)
+ [0x23C] = 0x2220, --(∠)
+ [0x23D] = 0x22A5, --(⊥)
+ [0x23E] = 0x2312, --(⌒)
+ [0x23F] = 0x2202, --(∂)
+ [0x240] = 0x2207, --(∇)
+ [0x241] = 0x2261, --(≡)
+ [0x242] = 0x2252, --(≒)
+ [0x243] = 0x226A, --(≪)
+ [0x244] = 0x226B, --(≫)
+ [0x245] = 0x221A, --(√)
+ [0x246] = 0x223D, --(∽)
+ [0x247] = 0x221D, --(âˆ)
+ [0x248] = 0x2235, --(∵)
+ [0x249] = 0x222B, --(∫)
+ [0x24A] = 0x222C, --(∬)
+ [0x252] = 0x212B, --(â„«)
+ [0x253] = 0x2030, --(‰)
+ [0x254] = 0x266F, --(♯)
+ [0x255] = 0x266D, --(â™­)
+ [0x256] = 0x266A, --(♪)
+ [0x257] = 0x2020, --(†)
+ [0x258] = 0x2021, --(‡)
+ [0x259] = 0xB6,
+ [0x25E] = 0x25EF, --(â—¯)
+ [0x310] = 0xFF10, --(ï¼)
+ [0x311] = 0xFF11, --(1)
+ [0x312] = 0xFF12, --(ï¼’)
+ [0x313] = 0xFF13, --(3)
+ [0x314] = 0xFF14, --(ï¼”)
+ [0x315] = 0xFF15, --(5)
+ [0x316] = 0xFF16, --(ï¼–)
+ [0x317] = 0xFF17, --(ï¼—)
+ [0x318] = 0xFF18, --(8)
+ [0x319] = 0xFF19, --(ï¼™)
+ [0x321] = 0xFF21, --(A)
+ [0x322] = 0xFF22, --(ï¼¢)
+ [0x323] = 0xFF23, --(ï¼£)
+ [0x324] = 0xFF24, --(D)
+ [0x325] = 0xFF25, --(ï¼¥)
+ [0x326] = 0xFF26, --(F)
+ [0x327] = 0xFF27, --(G)
+ [0x328] = 0xFF28, --(H)
+ [0x329] = 0xFF29, --(I)
+ [0x32A] = 0xFF2A, --(J)
+ [0x32B] = 0xFF2B, --(K)
+ [0x32C] = 0xFF2C, --(L)
+ [0x32D] = 0xFF2D, --(ï¼­)
+ [0x32E] = 0xFF2E, --(ï¼®)
+ [0x32F] = 0xFF2F, --(O)
+ [0x330] = 0xFF30, --(ï¼°)
+ [0x331] = 0xFF31, --(ï¼±)
+ [0x332] = 0xFF32, --(ï¼²)
+ [0x333] = 0xFF33, --(ï¼³)
+ [0x334] = 0xFF34, --(ï¼´)
+ [0x335] = 0xFF35, --(ï¼µ)
+ [0x336] = 0xFF36, --(V)
+ [0x337] = 0xFF37, --(ï¼·)
+ [0x338] = 0xFF38, --(X)
+ [0x339] = 0xFF39, --(ï¼¹)
+ [0x33A] = 0xFF3A, --(Z)
+ [0x341] = 0xFF41, --(ï½)
+ [0x342] = 0xFF42, --(b)
+ [0x343] = 0xFF43, --(c)
+ [0x344] = 0xFF44, --(d)
+ [0x345] = 0xFF45, --(ï½…)
+ [0x346] = 0xFF46, --(f)
+ [0x347] = 0xFF47, --(g)
+ [0x348] = 0xFF48, --(h)
+ [0x349] = 0xFF49, --(i)
+ [0x34A] = 0xFF4A, --(j)
+ [0x34B] = 0xFF4B, --(k)
+ [0x34C] = 0xFF4C, --(l)
+ [0x34D] = 0xFF4D, --(ï½)
+ [0x34E] = 0xFF4E, --(n)
+ [0x34F] = 0xFF4F, --(ï½)
+ [0x350] = 0xFF50, --(ï½)
+ [0x351] = 0xFF51, --(q)
+ [0x352] = 0xFF52, --(ï½’)
+ [0x353] = 0xFF53, --(s)
+ [0x354] = 0xFF54, --(ï½”)
+ [0x355] = 0xFF55, --(u)
+ [0x356] = 0xFF56, --(ï½–)
+ [0x357] = 0xFF57, --(ï½—)
+ [0x358] = 0xFF58, --(x)
+ [0x359] = 0xFF59, --(ï½™)
+ [0x35A] = 0xFF5A, --(z)
+ [0x401] = 0x3041, --(ã)
+ [0x402] = 0x3042, --(ã‚)
+ [0x403] = 0x3043, --(ãƒ)
+ [0x404] = 0x3044, --(ã„)
+ [0x405] = 0x3045, --(ã…)
+ [0x406] = 0x3046, --(ã†)
+ [0x407] = 0x3047, --(ã‡)
+ [0x408] = 0x3048, --(ãˆ)
+ [0x409] = 0x3049, --(ã‰)
+ [0x40A] = 0x304A, --(ãŠ)
+ [0x40B] = 0x304B, --(ã‹)
+ [0x40C] = 0x304C, --(ãŒ)
+ [0x40D] = 0x304D, --(ã)
+ [0x40E] = 0x304E, --(ãŽ)
+ [0x40F] = 0x304F, --(ã)
+ [0x410] = 0x3050, --(ã)
+ [0x411] = 0x3051, --(ã‘)
+ [0x412] = 0x3052, --(ã’)
+ [0x413] = 0x3053, --(ã“)
+ [0x414] = 0x3054, --(ã”)
+ [0x415] = 0x3055, --(ã•)
+ [0x416] = 0x3056, --(ã–)
+ [0x417] = 0x3057, --(ã—)
+ [0x418] = 0x3058, --(ã˜)
+ [0x419] = 0x3059, --(ã™)
+ [0x41A] = 0x305A, --(ãš)
+ [0x41B] = 0x305B, --(ã›)
+ [0x41C] = 0x305C, --(ãœ)
+ [0x41D] = 0x305D, --(ã)
+ [0x41E] = 0x305E, --(ãž)
+ [0x41F] = 0x305F, --(ãŸ)
+ [0x420] = 0x3060, --(ã )
+ [0x421] = 0x3061, --(ã¡)
+ [0x422] = 0x3062, --(ã¢)
+ [0x423] = 0x3063, --(ã£)
+ [0x424] = 0x3064, --(ã¤)
+ [0x425] = 0x3065, --(ã¥)
+ [0x426] = 0x3066, --(ã¦)
+ [0x427] = 0x3067, --(ã§)
+ [0x428] = 0x3068, --(ã¨)
+ [0x429] = 0x3069, --(ã©)
+ [0x42A] = 0x306A, --(ãª)
+ [0x42B] = 0x306B, --(ã«)
+ [0x42C] = 0x306C, --(ã¬)
+ [0x42D] = 0x306D, --(ã­)
+ [0x42E] = 0x306E, --(ã®)
+ [0x42F] = 0x306F, --(ã¯)
+ [0x430] = 0x3070, --(ã°)
+ [0x431] = 0x3071, --(ã±)
+ [0x432] = 0x3072, --(ã²)
+ [0x433] = 0x3073, --(ã³)
+ [0x434] = 0x3074, --(ã´)
+ [0x435] = 0x3075, --(ãµ)
+ [0x436] = 0x3076, --(ã¶)
+ [0x437] = 0x3077, --(ã·)
+ [0x438] = 0x3078, --(ã¸)
+ [0x439] = 0x3079, --(ã¹)
+ [0x43A] = 0x307A, --(ãº)
+ [0x43B] = 0x307B, --(ã»)
+ [0x43C] = 0x307C, --(ã¼)
+ [0x43D] = 0x307D, --(ã½)
+ [0x43E] = 0x307E, --(ã¾)
+ [0x43F] = 0x307F, --(ã¿)
+ [0x440] = 0x3080, --(ã‚€)
+ [0x441] = 0x3081, --(ã‚)
+ [0x442] = 0x3082, --(ã‚‚)
+ [0x443] = 0x3083, --(ゃ)
+ [0x444] = 0x3084, --(ã‚„)
+ [0x445] = 0x3085, --(ã‚…)
+ [0x446] = 0x3086, --(ゆ)
+ [0x447] = 0x3087, --(ょ)
+ [0x448] = 0x3088, --(よ)
+ [0x449] = 0x3089, --(ら)
+ [0x44A] = 0x308A, --(ã‚Š)
+ [0x44B] = 0x308B, --(ã‚‹)
+ [0x44C] = 0x308C, --(れ)
+ [0x44D] = 0x308D, --(ã‚)
+ [0x44E] = 0x308E, --(ã‚Ž)
+ [0x44F] = 0x308F, --(ã‚)
+ [0x450] = 0x3090, --(ã‚)
+ [0x451] = 0x3091, --(ã‚‘)
+ [0x452] = 0x3092, --(ã‚’)
+ [0x453] = 0x3093, --(ã‚“)
+ [0x501] = 0x30A1, --(ã‚¡)
+ [0x502] = 0x30A2, --(ã‚¢)
+ [0x503] = 0x30A3, --(ã‚£)
+ [0x504] = 0x30A4, --(イ)
+ [0x505] = 0x30A5, --(ã‚¥)
+ [0x506] = 0x30A6, --(ウ)
+ [0x507] = 0x30A7, --(ェ)
+ [0x508] = 0x30A8, --(エ)
+ [0x509] = 0x30A9, --(ã‚©)
+ [0x50A] = 0x30AA, --(オ)
+ [0x50B] = 0x30AB, --(ã‚«)
+ [0x50C] = 0x30AC, --(ガ)
+ [0x50D] = 0x30AD, --(ã‚­)
+ [0x50E] = 0x30AE, --(ã‚®)
+ [0x50F] = 0x30AF, --(ク)
+ [0x510] = 0x30B0, --(ã‚°)
+ [0x511] = 0x30B1, --(ケ)
+ [0x512] = 0x30B2, --(ゲ)
+ [0x513] = 0x30B3, --(コ)
+ [0x514] = 0x30B4, --(ã‚´)
+ [0x515] = 0x30B5, --(サ)
+ [0x516] = 0x30B6, --(ザ)
+ [0x517] = 0x30B7, --(ã‚·)
+ [0x518] = 0x30B8, --(ジ)
+ [0x519] = 0x30B9, --(ス)
+ [0x51A] = 0x30BA, --(ズ)
+ [0x51B] = 0x30BB, --(ã‚»)
+ [0x51C] = 0x30BC, --(ゼ)
+ [0x51D] = 0x30BD, --(ソ)
+ [0x51E] = 0x30BE, --(ゾ)
+ [0x51F] = 0x30BF, --(ã‚¿)
+ [0x520] = 0x30C0, --(ダ)
+ [0x521] = 0x30C1, --(ãƒ)
+ [0x522] = 0x30C2, --(ヂ)
+ [0x523] = 0x30C3, --(ッ)
+ [0x524] = 0x30C4, --(ツ)
+ [0x525] = 0x30C5, --(ヅ)
+ [0x526] = 0x30C6, --(テ)
+ [0x527] = 0x30C7, --(デ)
+ [0x528] = 0x30C8, --(ト)
+ [0x529] = 0x30C9, --(ド)
+ [0x52A] = 0x30CA, --(ナ)
+ [0x52B] = 0x30CB, --(ニ)
+ [0x52C] = 0x30CC, --(ヌ)
+ [0x52D] = 0x30CD, --(ãƒ)
+ [0x52E] = 0x30CE, --(ノ)
+ [0x52F] = 0x30CF, --(ãƒ)
+ [0x530] = 0x30D0, --(ãƒ)
+ [0x531] = 0x30D1, --(パ)
+ [0x532] = 0x30D2, --(ヒ)
+ [0x533] = 0x30D3, --(ビ)
+ [0x534] = 0x30D4, --(ピ)
+ [0x535] = 0x30D5, --(フ)
+ [0x536] = 0x30D6, --(ブ)
+ [0x537] = 0x30D7, --(プ)
+ [0x538] = 0x30D8, --(ヘ)
+ [0x539] = 0x30D9, --(ベ)
+ [0x53A] = 0x30DA, --(ペ)
+ [0x53B] = 0x30DB, --(ホ)
+ [0x53C] = 0x30DC, --(ボ)
+ [0x53D] = 0x30DD, --(ãƒ)
+ [0x53E] = 0x30DE, --(マ)
+ [0x53F] = 0x30DF, --(ミ)
+ [0x540] = 0x30E0, --(ム)
+ [0x541] = 0x30E1, --(メ)
+ [0x542] = 0x30E2, --(モ)
+ [0x543] = 0x30E3, --(ャ)
+ [0x544] = 0x30E4, --(ヤ)
+ [0x545] = 0x30E5, --(ュ)
+ [0x546] = 0x30E6, --(ユ)
+ [0x547] = 0x30E7, --(ョ)
+ [0x548] = 0x30E8, --(ヨ)
+ [0x549] = 0x30E9, --(ラ)
+ [0x54A] = 0x30EA, --(リ)
+ [0x54B] = 0x30EB, --(ル)
+ [0x54C] = 0x30EC, --(レ)
+ [0x54D] = 0x30ED, --(ロ)
+ [0x54E] = 0x30EE, --(ヮ)
+ [0x54F] = 0x30EF, --(ワ)
+ [0x550] = 0x30F0, --(ヰ)
+ [0x551] = 0x30F1, --(ヱ)
+ [0x552] = 0x30F2, --(ヲ)
+ [0x553] = 0x30F3, --(ン)
+ [0x554] = 0x30F4, --(ヴ)
+ [0x555] = 0x30F5, --(ヵ)
+ [0x556] = 0x30F6, --(ヶ)
+ [0x601] = 0x391, --(Α)
+ [0x602] = 0x392, --(Î’)
+ [0x603] = 0x393, --(Γ)
+ [0x604] = 0x394, --(Δ)
+ [0x605] = 0x395, --(Ε)
+ [0x606] = 0x396, --(Ζ)
+ [0x607] = 0x397, --(Η)
+ [0x608] = 0x398, --(Θ)
+ [0x609] = 0x399, --(Ι)
+ [0x60A] = 0x39A, --(Κ)
+ [0x60B] = 0x39B, --(Λ)
+ [0x60C] = 0x39C, --(Μ)
+ [0x60D] = 0x39D, --(Î)
+ [0x60E] = 0x39E, --(Ξ)
+ [0x60F] = 0x39F, --(Ο)
+ [0x610] = 0x3A0, --(Π)
+ [0x611] = 0x3A1, --(Ρ)
+ [0x612] = 0x3A3, --(Σ)
+ [0x613] = 0x3A4, --(Τ)
+ [0x614] = 0x3A5, --(Î¥)
+ [0x615] = 0x3A6, --(Φ)
+ [0x616] = 0x3A7, --(Χ)
+ [0x617] = 0x3A8, --(Ψ)
+ [0x618] = 0x3A9, --(Ω)
+ [0x621] = 0x3B1, --(α)
+ [0x622] = 0x3B2, --(β)
+ [0x623] = 0x3B3, --(γ)
+ [0x624] = 0x3B4, --(δ)
+ [0x625] = 0x3B5, --(ε)
+ [0x626] = 0x3B6, --(ζ)
+ [0x627] = 0x3B7, --(η)
+ [0x628] = 0x3B8, --(θ)
+ [0x629] = 0x3B9, --(ι)
+ [0x62A] = 0x3BA, --(κ)
+ [0x62B] = 0x3BB, --(λ)
+ [0x62C] = 0x3BC, --(μ)
+ [0x62D] = 0x3BD, --(ν)
+ [0x62E] = 0x3BE, --(ξ)
+ [0x62F] = 0x3BF, --(ο)
+ [0x630] = 0x3C0, --(Ï€)
+ [0x631] = 0x3C1, --(Ï)
+ [0x632] = 0x3C3, --(σ)
+ [0x633] = 0x3C4, --(Ï„)
+ [0x634] = 0x3C5, --(Ï…)
+ [0x635] = 0x3C6, --(φ)
+ [0x636] = 0x3C7, --(χ)
+ [0x637] = 0x3C8, --(ψ)
+ [0x638] = 0x3C9, --(ω)
+ [0x701] = 0x410, --(Ð)
+ [0x702] = 0x411, --(Б)
+ [0x703] = 0x412, --(Ð’)
+ [0x704] = 0x413, --(Г)
+ [0x705] = 0x414, --(Д)
+ [0x706] = 0x415, --(Е)
+ [0x707] = 0x401, --(Ð)
+ [0x708] = 0x416, --(Ж)
+ [0x709] = 0x417, --(З)
+ [0x70A] = 0x418, --(И)
+ [0x70B] = 0x419, --(Й)
+ [0x70C] = 0x41A, --(К)
+ [0x70D] = 0x41B, --(Л)
+ [0x70E] = 0x41C, --(М)
+ [0x70F] = 0x41D, --(Ð)
+ [0x710] = 0x41E, --(О)
+ [0x711] = 0x41F, --(П)
+ [0x712] = 0x420, --(Р)
+ [0x713] = 0x421, --(С)
+ [0x714] = 0x422, --(Т)
+ [0x715] = 0x423, --(У)
+ [0x716] = 0x424, --(Ф)
+ [0x717] = 0x425, --(Ð¥)
+ [0x718] = 0x426, --(Ц)
+ [0x719] = 0x427, --(Ч)
+ [0x71A] = 0x428, --(Ш)
+ [0x71B] = 0x429, --(Щ)
+ [0x71C] = 0x42A, --(Ъ)
+ [0x71D] = 0x42B, --(Ы)
+ [0x71E] = 0x42C, --(Ь)
+ [0x71F] = 0x42D, --(Э)
+ [0x720] = 0x42E, --(Ю)
+ [0x721] = 0x42F, --(Я)
+ [0x731] = 0x430, --(а)
+ [0x732] = 0x431, --(б)
+ [0x733] = 0x432, --(в)
+ [0x734] = 0x433, --(г)
+ [0x735] = 0x434, --(д)
+ [0x736] = 0x435, --(е)
+ [0x737] = 0x451, --(Ñ‘)
+ [0x738] = 0x436, --(ж)
+ [0x739] = 0x437, --(з)
+ [0x73A] = 0x438, --(и)
+ [0x73B] = 0x439, --(й)
+ [0x73C] = 0x43A, --(к)
+ [0x73D] = 0x43B, --(л)
+ [0x73E] = 0x43C, --(м)
+ [0x73F] = 0x43D, --(н)
+ [0x740] = 0x43E, --(о)
+ [0x741] = 0x43F, --(п)
+ [0x742] = 0x440, --(Ñ€)
+ [0x743] = 0x441, --(Ñ)
+ [0x744] = 0x442, --(Ñ‚)
+ [0x745] = 0x443, --(у)
+ [0x746] = 0x444, --(Ñ„)
+ [0x747] = 0x445, --(Ñ…)
+ [0x748] = 0x446, --(ц)
+ [0x749] = 0x447, --(ч)
+ [0x74A] = 0x448, --(ш)
+ [0x74B] = 0x449, --(щ)
+ [0x74C] = 0x44A, --(ÑŠ)
+ [0x74D] = 0x44B, --(Ñ‹)
+ [0x74E] = 0x44C, --(ь)
+ [0x74F] = 0x44D, --(Ñ)
+ [0x750] = 0x44E, --(ÑŽ)
+ [0x751] = 0x44F, --(Ñ)
+ [0x801] = 0x2500, --(─)
+ [0x802] = 0x2502, --(│)
+ [0x803] = 0x250C, --(┌)
+ [0x804] = 0x2510, --(â”)
+ [0x805] = 0x2518, --(┘)
+ [0x806] = 0x2514, --(â””)
+ [0x807] = 0x251C, --(├)
+ [0x808] = 0x252C, --(┬)
+ [0x809] = 0x2524, --(┤)
+ [0x80A] = 0x2534, --(â”´)
+ [0x80B] = 0x253C, --(┼)
+ [0x80C] = 0x2501, --(â”)
+ [0x80D] = 0x2503, --(┃)
+ [0x80E] = 0x250F, --(â”)
+ [0x80F] = 0x2513, --(┓)
+ [0x810] = 0x251B, --(â”›)
+ [0x811] = 0x2517, --(â”—)
+ [0x812] = 0x2523, --(┣)
+ [0x813] = 0x2533, --(┳)
+ [0x814] = 0x252B, --(┫)
+ [0x815] = 0x253B, --(â”»)
+ [0x816] = 0x254B, --(â•‹)
+ [0x817] = 0x2520, --(â” )
+ [0x818] = 0x252F, --(┯)
+ [0x819] = 0x2528, --(┨)
+ [0x81A] = 0x2537, --(â”·)
+ [0x81B] = 0x253F, --(┿)
+ [0x81C] = 0x251D, --(â”)
+ [0x81D] = 0x2530, --(â”°)
+ [0x81E] = 0x2525, --(┥)
+ [0x81F] = 0x2538, --(┸)
+ [0x820] = 0x2542, --(â•‚)
+ [0x1001] = 0x4E9C, --(亜)
+ [0x1002] = 0x5516, --(å”–)
+ [0x1003] = 0x5A03, --(娃)
+ [0x1004] = 0x963F, --(阿)
+ [0x1005] = 0x54C0, --(å“€)
+ [0x1006] = 0x611B, --(æ„›)
+ [0x1007] = 0x6328, --(挨)
+ [0x1008] = 0x59F6, --(姶)
+ [0x1009] = 0x9022, --(逢)
+ [0x100A] = 0x8475, --(葵)
+ [0x100B] = 0x831C, --(茜)
+ [0x100C] = 0x7A50, --(ç©)
+ [0x100D] = 0x60AA, --(悪)
+ [0x100E] = 0x63E1, --(æ¡)
+ [0x100F] = 0x6E25, --(渥)
+ [0x1010] = 0x65ED, --(æ—­)
+ [0x1011] = 0x8466, --(葦)
+ [0x1012] = 0x82A6, --(芦)
+ [0x1013] = 0x9BF5, --(鯵)
+ [0x1014] = 0x6893, --(梓)
+ [0x1015] = 0x5727, --(圧)
+ [0x1016] = 0x65A1, --(æ–¡)
+ [0x1017] = 0x6271, --(扱)
+ [0x1018] = 0x5B9B, --(å®›)
+ [0x1019] = 0x59D0, --(å§)
+ [0x101A] = 0x867B, --(è™»)
+ [0x101B] = 0x98F4, --(飴)
+ [0x101C] = 0x7D62, --(çµ¢)
+ [0x101D] = 0x7DBE, --(綾)
+ [0x101E] = 0x9B8E, --(鮎)
+ [0x101F] = 0x6216, --(或)
+ [0x1020] = 0x7C9F, --(粟)
+ [0x1021] = 0x88B7, --(袷)
+ [0x1022] = 0x5B89, --(安)
+ [0x1023] = 0x5EB5, --(庵)
+ [0x1024] = 0x6309, --(按)
+ [0x1025] = 0x6697, --(æš—)
+ [0x1026] = 0x6848, --(案)
+ [0x1027] = 0x95C7, --(é—‡)
+ [0x1028] = 0x978D, --(éž)
+ [0x1029] = 0x674F, --(æ)
+ [0x102A] = 0x4EE5, --(以)
+ [0x102B] = 0x4F0A, --(伊)
+ [0x102C] = 0x4F4D, --(ä½)
+ [0x102D] = 0x4F9D, --(ä¾)
+ [0x102E] = 0x5049, --(å‰)
+ [0x102F] = 0x56F2, --(囲)
+ [0x1030] = 0x5937, --(夷)
+ [0x1031] = 0x59D4, --(委)
+ [0x1032] = 0x5A01, --(å¨)
+ [0x1033] = 0x5C09, --(å°‰)
+ [0x1034] = 0x60DF, --(惟)
+ [0x1035] = 0x610F, --(æ„)
+ [0x1036] = 0x6170, --(æ…°)
+ [0x1037] = 0x6613, --(易)
+ [0x1038] = 0x6905, --(椅)
+ [0x1039] = 0x70BA, --(為)
+ [0x103A] = 0x754F, --(ç•)
+ [0x103B] = 0x7570, --(ç•°)
+ [0x103C] = 0x79FB, --(移)
+ [0x103D] = 0x7DAD, --(維)
+ [0x103E] = 0x7DEF, --(ç·¯)
+ [0x103F] = 0x80C3, --(胃)
+ [0x1040] = 0x840E, --(èŽ)
+ [0x1041] = 0x8863, --(è¡£)
+ [0x1042] = 0x8B02, --(謂)
+ [0x1043] = 0x9055, --(é•)
+ [0x1044] = 0x907A, --(éº)
+ [0x1045] = 0x533B, --(医)
+ [0x1046] = 0x4E95, --(井)
+ [0x1047] = 0x4EA5, --(亥)
+ [0x1048] = 0x57DF, --(域)
+ [0x1049] = 0x80B2, --(育)
+ [0x104A] = 0x90C1, --(éƒ)
+ [0x104B] = 0x78EF, --(磯)
+ [0x104C] = 0x4E00, --(一)
+ [0x104D] = 0x58F1, --(壱)
+ [0x104E] = 0x6EA2, --(溢)
+ [0x104F] = 0x9038, --(逸)
+ [0x1050] = 0x7A32, --(稲)
+ [0x1051] = 0x8328, --(茨)
+ [0x1052] = 0x828B, --(芋)
+ [0x1053] = 0x9C2F, --(é°¯)
+ [0x1054] = 0x5141, --(å…)
+ [0x1055] = 0x5370, --(å°)
+ [0x1056] = 0x54BD, --(å’½)
+ [0x1057] = 0x54E1, --(å“¡)
+ [0x1058] = 0x56E0, --(å› )
+ [0x1059] = 0x59FB, --(姻)
+ [0x105A] = 0x5F15, --(引)
+ [0x105B] = 0x98F2, --(飲)
+ [0x105C] = 0x6DEB, --(æ·«)
+ [0x105D] = 0x80E4, --(胤)
+ [0x105E] = 0x852D, --(è”­)
+ [0x1101] = 0x9662, --(院)
+ [0x1102] = 0x9670, --(é™°)
+ [0x1103] = 0x96A0, --(éš )
+ [0x1104] = 0x97FB, --(韻)
+ [0x1105] = 0x540B, --(å‹)
+ [0x1106] = 0x53F3, --(å³)
+ [0x1107] = 0x5B87, --(宇)
+ [0x1108] = 0x70CF, --(çƒ)
+ [0x1109] = 0x7FBD, --(ç¾½)
+ [0x110A] = 0x8FC2, --(è¿‚)
+ [0x110B] = 0x96E8, --(雨)
+ [0x110C] = 0x536F, --(å¯)
+ [0x110D] = 0x9D5C, --(鵜)
+ [0x110E] = 0x7ABA, --(窺)
+ [0x110F] = 0x4E11, --(丑)
+ [0x1110] = 0x7893, --(碓)
+ [0x1111] = 0x81FC, --(臼)
+ [0x1112] = 0x6E26, --(渦)
+ [0x1113] = 0x5618, --(嘘)
+ [0x1114] = 0x5504, --(唄)
+ [0x1115] = 0x6B1D, --(æ¬)
+ [0x1116] = 0x851A, --(蔚)
+ [0x1117] = 0x9C3B, --(é°»)
+ [0x1118] = 0x59E5, --(姥)
+ [0x1119] = 0x53A9, --(厩)
+ [0x111A] = 0x6D66, --(浦)
+ [0x111B] = 0x74DC, --(瓜)
+ [0x111C] = 0x958F, --(é–)
+ [0x111D] = 0x5642, --(噂)
+ [0x111E] = 0x4E91, --(云)
+ [0x111F] = 0x904B, --(é‹)
+ [0x1120] = 0x96F2, --(雲)
+ [0x1121] = 0x834F, --(è)
+ [0x1122] = 0x990C, --(餌)
+ [0x1123] = 0x53E1, --(å¡)
+ [0x1124] = 0x55B6, --(å–¶)
+ [0x1125] = 0x5B30, --(嬰)
+ [0x1126] = 0x5F71, --(å½±)
+ [0x1127] = 0x6620, --(映)
+ [0x1128] = 0x66F3, --(曳)
+ [0x1129] = 0x6804, --(æ „)
+ [0x112A] = 0x6C38, --(æ°¸)
+ [0x112B] = 0x6CF3, --(æ³³)
+ [0x112C] = 0x6D29, --(æ´©)
+ [0x112D] = 0x745B, --(ç‘›)
+ [0x112E] = 0x76C8, --(盈)
+ [0x112F] = 0x7A4E, --(ç©Ž)
+ [0x1130] = 0x9834, --(é ´)
+ [0x1131] = 0x82F1, --(英)
+ [0x1132] = 0x885B, --(è¡›)
+ [0x1133] = 0x8A60, --(è© )
+ [0x1134] = 0x92ED, --(é‹­)
+ [0x1135] = 0x6DB2, --(液)
+ [0x1136] = 0x75AB, --(ç–«)
+ [0x1137] = 0x76CA, --(益)
+ [0x1138] = 0x99C5, --(駅)
+ [0x1139] = 0x60A6, --(悦)
+ [0x113A] = 0x8B01, --(è¬)
+ [0x113B] = 0x8D8A, --(越)
+ [0x113C] = 0x95B2, --(é–²)
+ [0x113D] = 0x698E, --(榎)
+ [0x113E] = 0x53AD, --(厭)
+ [0x113F] = 0x5186, --(円)
+ [0x1140] = 0x5712, --(園)
+ [0x1141] = 0x5830, --(å °)
+ [0x1142] = 0x5944, --(奄)
+ [0x1143] = 0x5BB4, --(å®´)
+ [0x1144] = 0x5EF6, --(延)
+ [0x1145] = 0x6028, --(怨)
+ [0x1146] = 0x63A9, --(掩)
+ [0x1147] = 0x63F4, --(æ´)
+ [0x1148] = 0x6CBF, --(沿)
+ [0x1149] = 0x6F14, --(æ¼”)
+ [0x114A] = 0x708E, --(ç‚Ž)
+ [0x114B] = 0x7114, --(ç„”)
+ [0x114C] = 0x7159, --(ç…™)
+ [0x114D] = 0x71D5, --(燕)
+ [0x114E] = 0x733F, --(猿)
+ [0x114F] = 0x7E01, --(ç¸)
+ [0x1150] = 0x8276, --(艶)
+ [0x1151] = 0x82D1, --(è‹‘)
+ [0x1152] = 0x8597, --(è–—)
+ [0x1153] = 0x9060, --(é )
+ [0x1154] = 0x925B, --(鉛)
+ [0x1155] = 0x9D1B, --(é´›)
+ [0x1156] = 0x5869, --(å¡©)
+ [0x1157] = 0x65BC, --(æ–¼)
+ [0x1158] = 0x6C5A, --(汚)
+ [0x1159] = 0x7525, --(甥)
+ [0x115A] = 0x51F9, --(凹)
+ [0x115B] = 0x592E, --(央)
+ [0x115C] = 0x5965, --(奥)
+ [0x115D] = 0x5F80, --(å¾€)
+ [0x115E] = 0x5FDC, --(応)
+ [0x1201] = 0x62BC, --(押)
+ [0x1202] = 0x65FA, --(æ—º)
+ [0x1203] = 0x6A2A, --(横)
+ [0x1204] = 0x6B27, --(欧)
+ [0x1205] = 0x6BB4, --(æ®´)
+ [0x1206] = 0x738B, --(王)
+ [0x1207] = 0x7FC1, --(ç¿)
+ [0x1208] = 0x8956, --(襖)
+ [0x1209] = 0x9D2C, --(é´¬)
+ [0x120A] = 0x9D0E, --(é´Ž)
+ [0x120B] = 0x9EC4, --(黄)
+ [0x120C] = 0x5CA1, --(岡)
+ [0x120D] = 0x6C96, --(æ²–)
+ [0x120E] = 0x837B, --(è»)
+ [0x120F] = 0x5104, --(å„„)
+ [0x1210] = 0x5C4B, --(屋)
+ [0x1211] = 0x61B6, --(憶)
+ [0x1212] = 0x81C6, --(臆)
+ [0x1213] = 0x6876, --(桶)
+ [0x1214] = 0x7261, --(牡)
+ [0x1215] = 0x4E59, --(ä¹™)
+ [0x1216] = 0x4FFA, --(俺)
+ [0x1217] = 0x5378, --(å¸)
+ [0x1218] = 0x6069, --(æ©)
+ [0x1219] = 0x6E29, --(温)
+ [0x121A] = 0x7A4F, --(ç©)
+ [0x121B] = 0x97F3, --(音)
+ [0x121C] = 0x4E0B, --(下)
+ [0x121D] = 0x5316, --(化)
+ [0x121E] = 0x4EEE, --(ä»®)
+ [0x121F] = 0x4F55, --(何)
+ [0x1220] = 0x4F3D, --(ä¼½)
+ [0x1221] = 0x4FA1, --(価)
+ [0x1222] = 0x4F73, --(ä½³)
+ [0x1223] = 0x52A0, --(加)
+ [0x1224] = 0x53EF, --(å¯)
+ [0x1225] = 0x5609, --(嘉)
+ [0x1226] = 0x590F, --(å¤)
+ [0x1227] = 0x5AC1, --(å«)
+ [0x1228] = 0x5BB6, --(家)
+ [0x1229] = 0x5BE1, --(寡)
+ [0x122A] = 0x79D1, --(科)
+ [0x122B] = 0x6687, --(暇)
+ [0x122C] = 0x679C, --(果)
+ [0x122D] = 0x67B6, --(架)
+ [0x122E] = 0x6B4C, --(歌)
+ [0x122F] = 0x6CB3, --(æ²³)
+ [0x1230] = 0x706B, --(ç«)
+ [0x1231] = 0x73C2, --(ç‚)
+ [0x1232] = 0x798D, --(ç¦)
+ [0x1233] = 0x79BE, --(禾)
+ [0x1234] = 0x7A3C, --(稼)
+ [0x1235] = 0x7B87, --(箇)
+ [0x1236] = 0x82B1, --(花)
+ [0x1237] = 0x82DB, --(è‹›)
+ [0x1238] = 0x8304, --(茄)
+ [0x1239] = 0x8377, --(è·)
+ [0x123A] = 0x83EF, --(è¯)
+ [0x123B] = 0x83D3, --(è“)
+ [0x123C] = 0x8766, --(è¦)
+ [0x123D] = 0x8AB2, --(課)
+ [0x123E] = 0x5629, --(嘩)
+ [0x123F] = 0x8CA8, --(貨)
+ [0x1240] = 0x8FE6, --(迦)
+ [0x1241] = 0x904E, --(éŽ)
+ [0x1242] = 0x971E, --(霞)
+ [0x1243] = 0x868A, --(蚊)
+ [0x1244] = 0x4FC4, --(ä¿„)
+ [0x1245] = 0x5CE8, --(峨)
+ [0x1246] = 0x6211, --(我)
+ [0x1247] = 0x7259, --(牙)
+ [0x1248] = 0x753B, --(ç”»)
+ [0x1249] = 0x81E5, --(臥)
+ [0x124A] = 0x82BD, --(芽)
+ [0x124B] = 0x86FE, --(蛾)
+ [0x124C] = 0x8CC0, --(è³€)
+ [0x124D] = 0x96C5, --(é›…)
+ [0x124E] = 0x9913, --(餓)
+ [0x124F] = 0x99D5, --(駕)
+ [0x1250] = 0x4ECB, --(介)
+ [0x1251] = 0x4F1A, --(会)
+ [0x1252] = 0x89E3, --(解)
+ [0x1253] = 0x56DE, --(回)
+ [0x1254] = 0x584A, --(å¡Š)
+ [0x1255] = 0x58CA, --(壊)
+ [0x1256] = 0x5EFB, --(å»»)
+ [0x1257] = 0x5FEB, --(å¿«)
+ [0x1258] = 0x602A, --(怪)
+ [0x1259] = 0x6094, --(æ‚”)
+ [0x125A] = 0x6062, --(æ¢)
+ [0x125B] = 0x61D0, --(æ‡)
+ [0x125C] = 0x6212, --(戒)
+ [0x125D] = 0x62D0, --(æ‹)
+ [0x125E] = 0x6539, --(改)
+ [0x1301] = 0x9B41, --(é­)
+ [0x1302] = 0x6666, --(晦)
+ [0x1303] = 0x68B0, --(械)
+ [0x1304] = 0x6D77, --(æµ·)
+ [0x1305] = 0x7070, --(ç°)
+ [0x1306] = 0x754C, --(界)
+ [0x1307] = 0x7686, --(皆)
+ [0x1308] = 0x7D75, --(çµµ)
+ [0x1309] = 0x82A5, --(芥)
+ [0x130A] = 0x87F9, --(蟹)
+ [0x130B] = 0x958B, --(é–‹)
+ [0x130C] = 0x968E, --(階)
+ [0x130D] = 0x8C9D, --(è²)
+ [0x130E] = 0x51F1, --(凱)
+ [0x130F] = 0x52BE, --(劾)
+ [0x1310] = 0x5916, --(外)
+ [0x1311] = 0x54B3, --(å’³)
+ [0x1312] = 0x5BB3, --(害)
+ [0x1313] = 0x5D16, --(å´–)
+ [0x1314] = 0x6168, --(æ…¨)
+ [0x1315] = 0x6982, --(概)
+ [0x1316] = 0x6DAF, --(涯)
+ [0x1317] = 0x788D, --(ç¢)
+ [0x1318] = 0x84CB, --(è“‹)
+ [0x1319] = 0x8857, --(è¡—)
+ [0x131A] = 0x8A72, --(該)
+ [0x131B] = 0x93A7, --(鎧)
+ [0x131C] = 0x9AB8, --(骸)
+ [0x131D] = 0x6D6C, --(浬)
+ [0x131E] = 0x99A8, --(馨)
+ [0x131F] = 0x86D9, --(è›™)
+ [0x1320] = 0x57A3, --(垣)
+ [0x1321] = 0x67FF, --(柿)
+ [0x1322] = 0x86CE, --(蛎)
+ [0x1323] = 0x920E, --(鈎)
+ [0x1324] = 0x5283, --(劃)
+ [0x1325] = 0x5687, --(嚇)
+ [0x1326] = 0x5404, --(å„)
+ [0x1327] = 0x5ED3, --(廓)
+ [0x1328] = 0x62E1, --(æ‹¡)
+ [0x1329] = 0x64B9, --(æ’¹)
+ [0x132A] = 0x683C, --(æ ¼)
+ [0x132B] = 0x6838, --(æ ¸)
+ [0x132C] = 0x6BBB, --(æ®»)
+ [0x132D] = 0x7372, --(ç²)
+ [0x132E] = 0x78BA, --(確)
+ [0x132F] = 0x7A6B, --(ç©«)
+ [0x1330] = 0x899A, --(覚)
+ [0x1331] = 0x89D2, --(角)
+ [0x1332] = 0x8D6B, --(赫)
+ [0x1333] = 0x8F03, --(較)
+ [0x1334] = 0x90ED, --(郭)
+ [0x1335] = 0x95A3, --(é–£)
+ [0x1336] = 0x9694, --(éš”)
+ [0x1337] = 0x9769, --(é©)
+ [0x1338] = 0x5B66, --(å­¦)
+ [0x1339] = 0x5CB3, --(å²³)
+ [0x133A] = 0x697D, --(楽)
+ [0x133B] = 0x984D, --(é¡)
+ [0x133C] = 0x984E, --(é¡Ž)
+ [0x133D] = 0x639B, --(掛)
+ [0x133E] = 0x7B20, --(笠)
+ [0x133F] = 0x6A2B, --(樫)
+ [0x1340] = 0x6A7F, --(æ©¿)
+ [0x1341] = 0x68B6, --(梶)
+ [0x1342] = 0x9C0D, --(é°)
+ [0x1343] = 0x6F5F, --(潟)
+ [0x1344] = 0x5272, --(割)
+ [0x1345] = 0x559D, --(å–)
+ [0x1346] = 0x6070, --(æ°)
+ [0x1347] = 0x62EC, --(括)
+ [0x1348] = 0x6D3B, --(æ´»)
+ [0x1349] = 0x6E07, --(渇)
+ [0x134A] = 0x6ED1, --(滑)
+ [0x134B] = 0x845B, --(è‘›)
+ [0x134C] = 0x8910, --(è¤)
+ [0x134D] = 0x8F44, --(轄)
+ [0x134E] = 0x4E14, --(且)
+ [0x134F] = 0x9C39, --(é°¹)
+ [0x1350] = 0x53F6, --(å¶)
+ [0x1351] = 0x691B, --(椛)
+ [0x1352] = 0x6A3A, --(樺)
+ [0x1353] = 0x9784, --(éž„)
+ [0x1354] = 0x682A, --(æ ª)
+ [0x1355] = 0x515C, --(兜)
+ [0x1356] = 0x7AC3, --(竃)
+ [0x1357] = 0x84B2, --(è’²)
+ [0x1358] = 0x91DC, --(釜)
+ [0x1359] = 0x938C, --(鎌)
+ [0x135A] = 0x565B, --(å™›)
+ [0x135B] = 0x9D28, --(é´¨)
+ [0x135C] = 0x6822, --(æ ¢)
+ [0x135D] = 0x8305, --(茅)
+ [0x135E] = 0x8431, --(è±)
+ [0x1401] = 0x7CA5, --(ç²¥)
+ [0x1402] = 0x5208, --(刈)
+ [0x1403] = 0x82C5, --(è‹…)
+ [0x1404] = 0x74E6, --(瓦)
+ [0x1405] = 0x4E7E, --(ä¹¾)
+ [0x1406] = 0x4F83, --(侃)
+ [0x1407] = 0x51A0, --(冠)
+ [0x1408] = 0x5BD2, --(寒)
+ [0x1409] = 0x520A, --(刊)
+ [0x140A] = 0x52D8, --(勘)
+ [0x140B] = 0x52E7, --(勧)
+ [0x140C] = 0x5DFB, --(å·»)
+ [0x140D] = 0x559A, --(å–š)
+ [0x140E] = 0x582A, --(å ª)
+ [0x140F] = 0x59E6, --(姦)
+ [0x1410] = 0x5B8C, --(完)
+ [0x1411] = 0x5B98, --(官)
+ [0x1412] = 0x5BDB, --(寛)
+ [0x1413] = 0x5E72, --(å¹²)
+ [0x1414] = 0x5E79, --(å¹¹)
+ [0x1415] = 0x60A3, --(æ‚£)
+ [0x1416] = 0x611F, --(æ„Ÿ)
+ [0x1417] = 0x6163, --(æ…£)
+ [0x1418] = 0x61BE, --(憾)
+ [0x1419] = 0x63DB, --(æ›)
+ [0x141A] = 0x6562, --(æ•¢)
+ [0x141B] = 0x67D1, --(柑)
+ [0x141C] = 0x6853, --(æ¡“)
+ [0x141D] = 0x68FA, --(棺)
+ [0x141E] = 0x6B3E, --(款)
+ [0x141F] = 0x6B53, --(æ­“)
+ [0x1420] = 0x6C57, --(æ±—)
+ [0x1421] = 0x6F22, --(æ¼¢)
+ [0x1422] = 0x6F97, --(æ¾—)
+ [0x1423] = 0x6F45, --(æ½…)
+ [0x1424] = 0x74B0, --(ç’°)
+ [0x1425] = 0x7518, --(甘)
+ [0x1426] = 0x76E3, --(監)
+ [0x1427] = 0x770B, --(看)
+ [0x1428] = 0x7AFF, --(ç«¿)
+ [0x1429] = 0x7BA1, --(管)
+ [0x142A] = 0x7C21, --(ç°¡)
+ [0x142B] = 0x7DE9, --(ç·©)
+ [0x142C] = 0x7F36, --(缶)
+ [0x142D] = 0x7FF0, --(ç¿°)
+ [0x142E] = 0x809D, --(è‚)
+ [0x142F] = 0x8266, --(艦)
+ [0x1430] = 0x839E, --(莞)
+ [0x1431] = 0x89B3, --(観)
+ [0x1432] = 0x8ACC, --(諌)
+ [0x1433] = 0x8CAB, --(貫)
+ [0x1434] = 0x9084, --(é‚„)
+ [0x1435] = 0x9451, --(é‘‘)
+ [0x1436] = 0x9593, --(é–“)
+ [0x1437] = 0x9591, --(é–‘)
+ [0x1438] = 0x95A2, --(é–¢)
+ [0x1439] = 0x9665, --(陥)
+ [0x143A] = 0x97D3, --(韓)
+ [0x143B] = 0x9928, --(館)
+ [0x143C] = 0x8218, --(舘)
+ [0x143D] = 0x4E38, --(丸)
+ [0x143E] = 0x542B, --(å«)
+ [0x143F] = 0x5CB8, --(岸)
+ [0x1440] = 0x5DCC, --(巌)
+ [0x1441] = 0x73A9, --(玩)
+ [0x1442] = 0x764C, --(癌)
+ [0x1443] = 0x773C, --(眼)
+ [0x1444] = 0x5CA9, --(岩)
+ [0x1445] = 0x7FEB, --(ç¿«)
+ [0x1446] = 0x8D0B, --(è´‹)
+ [0x1447] = 0x96C1, --(é›)
+ [0x1448] = 0x9811, --(é ‘)
+ [0x1449] = 0x9854, --(é¡”)
+ [0x144A] = 0x9858, --(願)
+ [0x144B] = 0x4F01, --(ä¼)
+ [0x144C] = 0x4F0E, --(伎)
+ [0x144D] = 0x5371, --(å±)
+ [0x144E] = 0x559C, --(喜)
+ [0x144F] = 0x5668, --(器)
+ [0x1450] = 0x57FA, --(基)
+ [0x1451] = 0x5947, --(奇)
+ [0x1452] = 0x5B09, --(嬉)
+ [0x1453] = 0x5BC4, --(寄)
+ [0x1454] = 0x5C90, --(å²)
+ [0x1455] = 0x5E0C, --(希)
+ [0x1456] = 0x5E7E, --(å¹¾)
+ [0x1457] = 0x5FCC, --(忌)
+ [0x1458] = 0x63EE, --(æ®)
+ [0x1459] = 0x673A, --(机)
+ [0x145A] = 0x65D7, --(æ——)
+ [0x145B] = 0x65E2, --(æ—¢)
+ [0x145C] = 0x671F, --(期)
+ [0x145D] = 0x68CB, --(棋)
+ [0x145E] = 0x68C4, --(棄)
+ [0x1501] = 0x6A5F, --(æ©Ÿ)
+ [0x1502] = 0x5E30, --(帰)
+ [0x1503] = 0x6BC5, --(毅)
+ [0x1504] = 0x6C17, --(æ°—)
+ [0x1505] = 0x6C7D, --(æ±½)
+ [0x1506] = 0x757F, --(ç•¿)
+ [0x1507] = 0x7948, --(祈)
+ [0x1508] = 0x5B63, --(å­£)
+ [0x1509] = 0x7A00, --(稀)
+ [0x150A] = 0x7D00, --(ç´€)
+ [0x150B] = 0x5FBD, --(å¾½)
+ [0x150C] = 0x898F, --(è¦)
+ [0x150D] = 0x8A18, --(記)
+ [0x150E] = 0x8CB4, --(è²´)
+ [0x150F] = 0x8D77, --(èµ·)
+ [0x1510] = 0x8ECC, --(軌)
+ [0x1511] = 0x8F1D, --(è¼)
+ [0x1512] = 0x98E2, --(飢)
+ [0x1513] = 0x9A0E, --(騎)
+ [0x1514] = 0x9B3C, --(鬼)
+ [0x1515] = 0x4E80, --(亀)
+ [0x1516] = 0x507D, --(å½)
+ [0x1517] = 0x5100, --(å„€)
+ [0x1518] = 0x5993, --(妓)
+ [0x1519] = 0x5B9C, --(宜)
+ [0x151A] = 0x622F, --(戯)
+ [0x151B] = 0x6280, --(技)
+ [0x151C] = 0x64EC, --(擬)
+ [0x151D] = 0x6B3A, --(欺)
+ [0x151E] = 0x72A0, --(犠)
+ [0x151F] = 0x7591, --(ç–‘)
+ [0x1520] = 0x7947, --(祇)
+ [0x1521] = 0x7FA9, --(義)
+ [0x1522] = 0x87FB, --(蟻)
+ [0x1523] = 0x8ABC, --(誼)
+ [0x1524] = 0x8B70, --(è­°)
+ [0x1525] = 0x63AC, --(掬)
+ [0x1526] = 0x83CA, --(èŠ)
+ [0x1527] = 0x97A0, --(éž )
+ [0x1528] = 0x5409, --(å‰)
+ [0x1529] = 0x5403, --(åƒ)
+ [0x152A] = 0x55AB, --(å–«)
+ [0x152B] = 0x6854, --(æ¡”)
+ [0x152C] = 0x6A58, --(橘)
+ [0x152D] = 0x8A70, --(è©°)
+ [0x152E] = 0x7827, --(ç §)
+ [0x152F] = 0x6775, --(æµ)
+ [0x1530] = 0x9ECD, --(é»)
+ [0x1531] = 0x5374, --(å´)
+ [0x1532] = 0x5BA2, --(客)
+ [0x1533] = 0x811A, --(è„š)
+ [0x1534] = 0x8650, --(è™)
+ [0x1535] = 0x9006, --(逆)
+ [0x1536] = 0x4E18, --(丘)
+ [0x1537] = 0x4E45, --(ä¹…)
+ [0x1538] = 0x4EC7, --(仇)
+ [0x1539] = 0x4F11, --(休)
+ [0x153A] = 0x53CA, --(åŠ)
+ [0x153B] = 0x5438, --(å¸)
+ [0x153C] = 0x5BAE, --(å®®)
+ [0x153D] = 0x5F13, --(弓)
+ [0x153E] = 0x6025, --(急)
+ [0x153F] = 0x6551, --(æ•‘)
+ [0x1540] = 0x673D, --(朽)
+ [0x1541] = 0x6C42, --(求)
+ [0x1542] = 0x6C72, --(æ±²)
+ [0x1543] = 0x6CE3, --(æ³£)
+ [0x1544] = 0x7078, --(ç¸)
+ [0x1545] = 0x7403, --(çƒ)
+ [0x1546] = 0x7A76, --(究)
+ [0x1547] = 0x7AAE, --(窮)
+ [0x1548] = 0x7B08, --(笈)
+ [0x1549] = 0x7D1A, --(ç´š)
+ [0x154A] = 0x7CFE, --(ç³¾)
+ [0x154B] = 0x7D66, --(給)
+ [0x154C] = 0x65E7, --(æ—§)
+ [0x154D] = 0x725B, --(牛)
+ [0x154E] = 0x53BB, --(去)
+ [0x154F] = 0x5C45, --(å±…)
+ [0x1550] = 0x5DE8, --(å·¨)
+ [0x1551] = 0x62D2, --(æ‹’)
+ [0x1552] = 0x62E0, --(æ‹ )
+ [0x1553] = 0x6319, --(挙)
+ [0x1554] = 0x6E20, --(渠)
+ [0x1555] = 0x865A, --(虚)
+ [0x1556] = 0x8A31, --(許)
+ [0x1557] = 0x8DDD, --(è·)
+ [0x1558] = 0x92F8, --(鋸)
+ [0x1559] = 0x6F01, --(æ¼)
+ [0x155A] = 0x79A6, --(禦)
+ [0x155B] = 0x9B5A, --(é­š)
+ [0x155C] = 0x4EA8, --(亨)
+ [0x155D] = 0x4EAB, --(享)
+ [0x155E] = 0x4EAC, --(京)
+ [0x1601] = 0x4F9B, --(ä¾›)
+ [0x1602] = 0x4FA0, --(ä¾ )
+ [0x1603] = 0x50D1, --(僑)
+ [0x1604] = 0x5147, --(å…‡)
+ [0x1605] = 0x7AF6, --(競)
+ [0x1606] = 0x5171, --(å…±)
+ [0x1607] = 0x51F6, --(凶)
+ [0x1608] = 0x5354, --(å”)
+ [0x1609] = 0x5321, --(匡)
+ [0x160A] = 0x537F, --(å¿)
+ [0x160B] = 0x53EB, --(å«)
+ [0x160C] = 0x55AC, --(å–¬)
+ [0x160D] = 0x5883, --(境)
+ [0x160E] = 0x5CE1, --(峡)
+ [0x160F] = 0x5F37, --(å¼·)
+ [0x1610] = 0x5F4A, --(彊)
+ [0x1611] = 0x602F, --(怯)
+ [0x1612] = 0x6050, --(æ)
+ [0x1613] = 0x606D, --(æ­)
+ [0x1614] = 0x631F, --(挟)
+ [0x1615] = 0x6559, --(æ•™)
+ [0x1616] = 0x6A4B, --(æ©‹)
+ [0x1617] = 0x6CC1, --(æ³)
+ [0x1618] = 0x72C2, --(ç‹‚)
+ [0x1619] = 0x72ED, --(ç‹­)
+ [0x161A] = 0x77EF, --(矯)
+ [0x161B] = 0x80F8, --(胸)
+ [0x161C] = 0x8105, --(è„…)
+ [0x161D] = 0x8208, --(興)
+ [0x161E] = 0x854E, --(è•Ž)
+ [0x161F] = 0x90F7, --(郷)
+ [0x1620] = 0x93E1, --(é¡)
+ [0x1621] = 0x97FF, --(響)
+ [0x1622] = 0x9957, --(饗)
+ [0x1623] = 0x9A5A, --(é©š)
+ [0x1624] = 0x4EF0, --(ä»°)
+ [0x1625] = 0x51DD, --(å‡)
+ [0x1626] = 0x5C2D, --(å°­)
+ [0x1627] = 0x6681, --(æš)
+ [0x1628] = 0x696D, --(業)
+ [0x1629] = 0x5C40, --(å±€)
+ [0x162A] = 0x66F2, --(曲)
+ [0x162B] = 0x6975, --(極)
+ [0x162C] = 0x7389, --(玉)
+ [0x162D] = 0x6850, --(æ¡)
+ [0x162E] = 0x7C81, --(ç²)
+ [0x162F] = 0x50C5, --(僅)
+ [0x1630] = 0x52E4, --(勤)
+ [0x1631] = 0x5747, --(å‡)
+ [0x1632] = 0x5DFE, --(å·¾)
+ [0x1633] = 0x9326, --(錦)
+ [0x1634] = 0x65A4, --(æ–¤)
+ [0x1635] = 0x6B23, --(欣)
+ [0x1636] = 0x6B3D, --(欽)
+ [0x1637] = 0x7434, --(ç´)
+ [0x1638] = 0x7981, --(ç¦)
+ [0x1639] = 0x79BD, --(禽)
+ [0x163A] = 0x7B4B, --(ç­‹)
+ [0x163B] = 0x7DCA, --(ç·Š)
+ [0x163C] = 0x82B9, --(芹)
+ [0x163D] = 0x83CC, --(èŒ)
+ [0x163E] = 0x887F, --(è¡¿)
+ [0x163F] = 0x895F, --(襟)
+ [0x1640] = 0x8B39, --(謹)
+ [0x1641] = 0x8FD1, --(è¿‘)
+ [0x1642] = 0x91D1, --(金)
+ [0x1643] = 0x541F, --(åŸ)
+ [0x1644] = 0x9280, --(銀)
+ [0x1645] = 0x4E5D, --(ä¹)
+ [0x1646] = 0x5036, --(倶)
+ [0x1647] = 0x53E5, --(å¥)
+ [0x1648] = 0x533A, --(区)
+ [0x1649] = 0x72D7, --(ç‹—)
+ [0x164A] = 0x7396, --(玖)
+ [0x164B] = 0x77E9, --(矩)
+ [0x164C] = 0x82E6, --(苦)
+ [0x164D] = 0x8EAF, --(躯)
+ [0x164E] = 0x99C6, --(駆)
+ [0x164F] = 0x99C8, --(駈)
+ [0x1650] = 0x99D2, --(駒)
+ [0x1651] = 0x5177, --(å…·)
+ [0x1652] = 0x611A, --(æ„š)
+ [0x1653] = 0x865E, --(虞)
+ [0x1654] = 0x55B0, --(å–°)
+ [0x1655] = 0x7A7A, --(空)
+ [0x1656] = 0x5076, --(å¶)
+ [0x1657] = 0x5BD3, --(寓)
+ [0x1658] = 0x9047, --(é‡)
+ [0x1659] = 0x9685, --(éš…)
+ [0x165A] = 0x4E32, --(串)
+ [0x165B] = 0x6ADB, --(æ«›)
+ [0x165C] = 0x91E7, --(釧)
+ [0x165D] = 0x5C51, --(屑)
+ [0x165E] = 0x5C48, --(屈)
+ [0x1701] = 0x6398, --(掘)
+ [0x1702] = 0x7A9F, --(窟)
+ [0x1703] = 0x6C93, --(沓)
+ [0x1704] = 0x9774, --(é´)
+ [0x1705] = 0x8F61, --(轡)
+ [0x1706] = 0x7AAA, --(窪)
+ [0x1707] = 0x718A, --(熊)
+ [0x1708] = 0x9688, --(隈)
+ [0x1709] = 0x7C82, --(粂)
+ [0x170A] = 0x6817, --(æ —)
+ [0x170B] = 0x7E70, --(ç¹°)
+ [0x170C] = 0x6851, --(æ¡‘)
+ [0x170D] = 0x936C, --(é¬)
+ [0x170E] = 0x52F2, --(勲)
+ [0x170F] = 0x541B, --(å›)
+ [0x1710] = 0x85AB, --(è–«)
+ [0x1711] = 0x8A13, --(訓)
+ [0x1712] = 0x7FA4, --(群)
+ [0x1713] = 0x8ECD, --(è»)
+ [0x1714] = 0x90E1, --(郡)
+ [0x1715] = 0x5366, --(å¦)
+ [0x1716] = 0x8888, --(袈)
+ [0x1717] = 0x7941, --(ç¥)
+ [0x1718] = 0x4FC2, --(ä¿‚)
+ [0x1719] = 0x50BE, --(傾)
+ [0x171A] = 0x5211, --(刑)
+ [0x171B] = 0x5144, --(å…„)
+ [0x171C] = 0x5553, --(å•“)
+ [0x171D] = 0x572D, --(圭)
+ [0x171E] = 0x73EA, --(çª)
+ [0x171F] = 0x578B, --(åž‹)
+ [0x1720] = 0x5951, --(契)
+ [0x1721] = 0x5F62, --(å½¢)
+ [0x1722] = 0x5F84, --(径)
+ [0x1723] = 0x6075, --(æµ)
+ [0x1724] = 0x6176, --(æ…¶)
+ [0x1725] = 0x6167, --(æ…§)
+ [0x1726] = 0x61A9, --(憩)
+ [0x1727] = 0x63B2, --(掲)
+ [0x1728] = 0x643A, --(æº)
+ [0x1729] = 0x656C, --(敬)
+ [0x172A] = 0x666F, --(景)
+ [0x172B] = 0x6842, --(æ¡‚)
+ [0x172C] = 0x6E13, --(渓)
+ [0x172D] = 0x7566, --(畦)
+ [0x172E] = 0x7A3D, --(稽)
+ [0x172F] = 0x7CFB, --(ç³»)
+ [0x1730] = 0x7D4C, --(経)
+ [0x1731] = 0x7D99, --(継)
+ [0x1732] = 0x7E4B, --(繋)
+ [0x1733] = 0x7F6B, --(罫)
+ [0x1734] = 0x830E, --(茎)
+ [0x1735] = 0x834A, --(èŠ)
+ [0x1736] = 0x86CD, --(è›)
+ [0x1737] = 0x8A08, --(計)
+ [0x1738] = 0x8A63, --(è©£)
+ [0x1739] = 0x8B66, --(è­¦)
+ [0x173A] = 0x8EFD, --(軽)
+ [0x173B] = 0x981A, --(é š)
+ [0x173C] = 0x9D8F, --(é¶)
+ [0x173D] = 0x82B8, --(芸)
+ [0x173E] = 0x8FCE, --(è¿Ž)
+ [0x173F] = 0x9BE8, --(鯨)
+ [0x1740] = 0x5287, --(劇)
+ [0x1741] = 0x621F, --(戟)
+ [0x1742] = 0x6483, --(æ’ƒ)
+ [0x1743] = 0x6FC0, --(æ¿€)
+ [0x1744] = 0x9699, --(éš™)
+ [0x1745] = 0x6841, --(æ¡)
+ [0x1746] = 0x5091, --(å‚‘)
+ [0x1747] = 0x6B20, --(欠)
+ [0x1748] = 0x6C7A, --(決)
+ [0x1749] = 0x6F54, --(æ½”)
+ [0x174A] = 0x7A74, --(ç©´)
+ [0x174B] = 0x7D50, --(çµ)
+ [0x174C] = 0x8840, --(è¡€)
+ [0x174D] = 0x8A23, --(訣)
+ [0x174E] = 0x6708, --(月)
+ [0x174F] = 0x4EF6, --(件)
+ [0x1750] = 0x5039, --(倹)
+ [0x1751] = 0x5026, --(倦)
+ [0x1752] = 0x5065, --(å¥)
+ [0x1753] = 0x517C, --(å…¼)
+ [0x1754] = 0x5238, --(券)
+ [0x1755] = 0x5263, --(剣)
+ [0x1756] = 0x55A7, --(å–§)
+ [0x1757] = 0x570F, --(åœ)
+ [0x1758] = 0x5805, --(å …)
+ [0x1759] = 0x5ACC, --(嫌)
+ [0x175A] = 0x5EFA, --(建)
+ [0x175B] = 0x61B2, --(憲)
+ [0x175C] = 0x61F8, --(懸)
+ [0x175D] = 0x62F3, --(拳)
+ [0x175E] = 0x6372, --(æ²)
+ [0x1801] = 0x691C, --(検)
+ [0x1802] = 0x6A29, --(権)
+ [0x1803] = 0x727D, --(牽)
+ [0x1804] = 0x72AC, --(犬)
+ [0x1805] = 0x732E, --(献)
+ [0x1806] = 0x7814, --(ç ”)
+ [0x1807] = 0x786F, --(硯)
+ [0x1808] = 0x7D79, --(çµ¹)
+ [0x1809] = 0x770C, --(県)
+ [0x180A] = 0x80A9, --(è‚©)
+ [0x180B] = 0x898B, --(見)
+ [0x180C] = 0x8B19, --(謙)
+ [0x180D] = 0x8CE2, --(è³¢)
+ [0x180E] = 0x8ED2, --(è»’)
+ [0x180F] = 0x9063, --(é£)
+ [0x1810] = 0x9375, --(éµ)
+ [0x1811] = 0x967A, --(険)
+ [0x1812] = 0x9855, --(é¡•)
+ [0x1813] = 0x9A13, --(験)
+ [0x1814] = 0x9E78, --(鹸)
+ [0x1815] = 0x5143, --(å…ƒ)
+ [0x1816] = 0x539F, --(原)
+ [0x1817] = 0x53B3, --(厳)
+ [0x1818] = 0x5E7B, --(å¹»)
+ [0x1819] = 0x5F26, --(弦)
+ [0x181A] = 0x6E1B, --(減)
+ [0x181B] = 0x6E90, --(æº)
+ [0x181C] = 0x7384, --(玄)
+ [0x181D] = 0x73FE, --(ç¾)
+ [0x181E] = 0x7D43, --(絃)
+ [0x181F] = 0x8237, --(舷)
+ [0x1820] = 0x8A00, --(言)
+ [0x1821] = 0x8AFA, --(諺)
+ [0x1822] = 0x9650, --(é™)
+ [0x1823] = 0x4E4E, --(乎)
+ [0x1824] = 0x500B, --(個)
+ [0x1825] = 0x53E4, --(å¤)
+ [0x1826] = 0x547C, --(呼)
+ [0x1827] = 0x56FA, --(固)
+ [0x1828] = 0x59D1, --(姑)
+ [0x1829] = 0x5B64, --(å­¤)
+ [0x182A] = 0x5DF1, --(å·±)
+ [0x182B] = 0x5EAB, --(庫)
+ [0x182C] = 0x5F27, --(弧)
+ [0x182D] = 0x6238, --(戸)
+ [0x182E] = 0x6545, --(æ•…)
+ [0x182F] = 0x67AF, --(枯)
+ [0x1830] = 0x6E56, --(æ¹–)
+ [0x1831] = 0x72D0, --(ç‹)
+ [0x1832] = 0x7CCA, --(糊)
+ [0x1833] = 0x88B4, --(袴)
+ [0x1834] = 0x80A1, --(è‚¡)
+ [0x1835] = 0x80E1, --(胡)
+ [0x1836] = 0x83F0, --(è°)
+ [0x1837] = 0x864E, --(虎)
+ [0x1838] = 0x8A87, --(誇)
+ [0x1839] = 0x8DE8, --(è·¨)
+ [0x183A] = 0x9237, --(鈷)
+ [0x183B] = 0x96C7, --(雇)
+ [0x183C] = 0x9867, --(顧)
+ [0x183D] = 0x9F13, --(鼓)
+ [0x183E] = 0x4E94, --(五)
+ [0x183F] = 0x4E92, --(互)
+ [0x1840] = 0x4F0D, --(ä¼)
+ [0x1841] = 0x5348, --(åˆ)
+ [0x1842] = 0x5449, --(呉)
+ [0x1843] = 0x543E, --(å¾)
+ [0x1844] = 0x5A2F, --(娯)
+ [0x1845] = 0x5F8C, --(後)
+ [0x1846] = 0x5FA1, --(御)
+ [0x1847] = 0x609F, --(æ‚Ÿ)
+ [0x1848] = 0x68A7, --(梧)
+ [0x1849] = 0x6A8E, --(檎)
+ [0x184A] = 0x745A, --(ç‘š)
+ [0x184B] = 0x7881, --(ç¢)
+ [0x184C] = 0x8A9E, --(語)
+ [0x184D] = 0x8AA4, --(誤)
+ [0x184E] = 0x8B77, --(è­·)
+ [0x184F] = 0x9190, --(é†)
+ [0x1850] = 0x4E5E, --(乞)
+ [0x1851] = 0x9BC9, --(鯉)
+ [0x1852] = 0x4EA4, --(交)
+ [0x1853] = 0x4F7C, --(ä½¼)
+ [0x1854] = 0x4FAF, --(侯)
+ [0x1855] = 0x5019, --(候)
+ [0x1856] = 0x5016, --(倖)
+ [0x1857] = 0x5149, --(å…‰)
+ [0x1858] = 0x516C, --(å…¬)
+ [0x1859] = 0x529F, --(功)
+ [0x185A] = 0x52B9, --(効)
+ [0x185B] = 0x52FE, --(勾)
+ [0x185C] = 0x539A, --(厚)
+ [0x185D] = 0x53E3, --(å£)
+ [0x185E] = 0x5411, --(å‘)
+ [0x1901] = 0x540E, --(åŽ)
+ [0x1902] = 0x5589, --(å–‰)
+ [0x1903] = 0x5751, --(å‘)
+ [0x1904] = 0x57A2, --(垢)
+ [0x1905] = 0x597D, --(好)
+ [0x1906] = 0x5B54, --(å­”)
+ [0x1907] = 0x5B5D, --(å­)
+ [0x1908] = 0x5B8F, --(å®)
+ [0x1909] = 0x5DE5, --(å·¥)
+ [0x190A] = 0x5DE7, --(å·§)
+ [0x190B] = 0x5DF7, --(å··)
+ [0x190C] = 0x5E78, --(幸)
+ [0x190D] = 0x5E83, --(広)
+ [0x190E] = 0x5E9A, --(庚)
+ [0x190F] = 0x5EB7, --(康)
+ [0x1910] = 0x5F18, --(弘)
+ [0x1911] = 0x6052, --(æ’)
+ [0x1912] = 0x614C, --(慌)
+ [0x1913] = 0x6297, --(抗)
+ [0x1914] = 0x62D8, --(拘)
+ [0x1915] = 0x63A7, --(控)
+ [0x1916] = 0x653B, --(æ”»)
+ [0x1917] = 0x6602, --(昂)
+ [0x1918] = 0x6643, --(晃)
+ [0x1919] = 0x66F4, --(æ›´)
+ [0x191A] = 0x676D, --(æ­)
+ [0x191B] = 0x6821, --(æ ¡)
+ [0x191C] = 0x6897, --(梗)
+ [0x191D] = 0x69CB, --(構)
+ [0x191E] = 0x6C5F, --(江)
+ [0x191F] = 0x6D2A, --(æ´ª)
+ [0x1920] = 0x6D69, --(浩)
+ [0x1921] = 0x6E2F, --(港)
+ [0x1922] = 0x6E9D, --(æº)
+ [0x1923] = 0x7532, --(甲)
+ [0x1924] = 0x7687, --(皇)
+ [0x1925] = 0x786C, --(硬)
+ [0x1926] = 0x7A3F, --(稿)
+ [0x1927] = 0x7CE0, --(ç³ )
+ [0x1928] = 0x7D05, --(ç´…)
+ [0x1929] = 0x7D18, --(ç´˜)
+ [0x192A] = 0x7D5E, --(絞)
+ [0x192B] = 0x7DB1, --(綱)
+ [0x192C] = 0x8015, --(耕)
+ [0x192D] = 0x8003, --(考)
+ [0x192E] = 0x80AF, --(肯)
+ [0x192F] = 0x80B1, --(肱)
+ [0x1930] = 0x8154, --(è…”)
+ [0x1931] = 0x818F, --(è†)
+ [0x1932] = 0x822A, --(航)
+ [0x1933] = 0x8352, --(è’)
+ [0x1934] = 0x884C, --(行)
+ [0x1935] = 0x8861, --(è¡¡)
+ [0x1936] = 0x8B1B, --(講)
+ [0x1937] = 0x8CA2, --(è²¢)
+ [0x1938] = 0x8CFC, --(è³¼)
+ [0x1939] = 0x90CA, --(郊)
+ [0x193A] = 0x9175, --(é…µ)
+ [0x193B] = 0x9271, --(鉱)
+ [0x193C] = 0x783F, --(ç ¿)
+ [0x193D] = 0x92FC, --(鋼)
+ [0x193E] = 0x95A4, --(é–¤)
+ [0x193F] = 0x964D, --(é™)
+ [0x1940] = 0x9805, --(é …)
+ [0x1941] = 0x9999, --(香)
+ [0x1942] = 0x9AD8, --(高)
+ [0x1943] = 0x9D3B, --(é´»)
+ [0x1944] = 0x525B, --(剛)
+ [0x1945] = 0x52AB, --(劫)
+ [0x1946] = 0x53F7, --(å·)
+ [0x1947] = 0x5408, --(åˆ)
+ [0x1948] = 0x58D5, --(壕)
+ [0x1949] = 0x62F7, --(æ‹·)
+ [0x194A] = 0x6FE0, --(æ¿ )
+ [0x194B] = 0x8C6A, --(豪)
+ [0x194C] = 0x8F5F, --(轟)
+ [0x194D] = 0x9EB9, --(麹)
+ [0x194E] = 0x514B, --(å…‹)
+ [0x194F] = 0x523B, --(刻)
+ [0x1950] = 0x544A, --(å‘Š)
+ [0x1951] = 0x56FD, --(国)
+ [0x1952] = 0x7A40, --(ç©€)
+ [0x1953] = 0x9177, --(é…·)
+ [0x1954] = 0x9D60, --(éµ )
+ [0x1955] = 0x9ED2, --(é»’)
+ [0x1956] = 0x7344, --(ç„)
+ [0x1957] = 0x6F09, --(漉)
+ [0x1958] = 0x8170, --(è…°)
+ [0x1959] = 0x7511, --(甑)
+ [0x195A] = 0x5FFD, --(忽)
+ [0x195B] = 0x60DA, --(惚)
+ [0x195C] = 0x9AA8, --(骨)
+ [0x195D] = 0x72DB, --(ç‹›)
+ [0x195E] = 0x8FBC, --(è¾¼)
+ [0x1A01] = 0x6B64, --(æ­¤)
+ [0x1A02] = 0x9803, --(é ƒ)
+ [0x1A03] = 0x4ECA, --(今)
+ [0x1A04] = 0x56F0, --(å›°)
+ [0x1A05] = 0x5764, --(å¤)
+ [0x1A06] = 0x58BE, --(墾)
+ [0x1A07] = 0x5A5A, --(å©š)
+ [0x1A08] = 0x6068, --(æ¨)
+ [0x1A09] = 0x61C7, --(懇)
+ [0x1A0A] = 0x660F, --(æ˜)
+ [0x1A0B] = 0x6606, --(昆)
+ [0x1A0C] = 0x6839, --(æ ¹)
+ [0x1A0D] = 0x68B1, --(梱)
+ [0x1A0E] = 0x6DF7, --(æ··)
+ [0x1A0F] = 0x75D5, --(ç—•)
+ [0x1A10] = 0x7D3A, --(ç´º)
+ [0x1A11] = 0x826E, --(艮)
+ [0x1A12] = 0x9B42, --(é­‚)
+ [0x1A13] = 0x4E9B, --(些)
+ [0x1A14] = 0x4F50, --(ä½)
+ [0x1A15] = 0x53C9, --(å‰)
+ [0x1A16] = 0x5506, --(唆)
+ [0x1A17] = 0x5D6F, --(嵯)
+ [0x1A18] = 0x5DE6, --(å·¦)
+ [0x1A19] = 0x5DEE, --(å·®)
+ [0x1A1A] = 0x67FB, --(査)
+ [0x1A1B] = 0x6C99, --(æ²™)
+ [0x1A1C] = 0x7473, --(瑳)
+ [0x1A1D] = 0x7802, --(ç ‚)
+ [0x1A1E] = 0x8A50, --(è©)
+ [0x1A1F] = 0x9396, --(鎖)
+ [0x1A20] = 0x88DF, --(裟)
+ [0x1A21] = 0x5750, --(å)
+ [0x1A22] = 0x5EA7, --(座)
+ [0x1A23] = 0x632B, --(挫)
+ [0x1A24] = 0x50B5, --(債)
+ [0x1A25] = 0x50AC, --(催)
+ [0x1A26] = 0x518D, --(å†)
+ [0x1A27] = 0x6700, --(最)
+ [0x1A28] = 0x54C9, --(哉)
+ [0x1A29] = 0x585E, --(å¡ž)
+ [0x1A2A] = 0x59BB, --(妻)
+ [0x1A2B] = 0x5BB0, --(å®°)
+ [0x1A2C] = 0x5F69, --(彩)
+ [0x1A2D] = 0x624D, --(æ‰)
+ [0x1A2E] = 0x63A1, --(採)
+ [0x1A2F] = 0x683D, --(æ ½)
+ [0x1A30] = 0x6B73, --(æ­³)
+ [0x1A31] = 0x6E08, --(済)
+ [0x1A32] = 0x707D, --(ç½)
+ [0x1A33] = 0x91C7, --(采)
+ [0x1A34] = 0x7280, --(犀)
+ [0x1A35] = 0x7815, --(ç •)
+ [0x1A36] = 0x7826, --(ç ¦)
+ [0x1A37] = 0x796D, --(祭)
+ [0x1A38] = 0x658E, --(æ–Ž)
+ [0x1A39] = 0x7D30, --(ç´°)
+ [0x1A3A] = 0x83DC, --(èœ)
+ [0x1A3B] = 0x88C1, --(è£)
+ [0x1A3C] = 0x8F09, --(載)
+ [0x1A3D] = 0x969B, --(éš›)
+ [0x1A3E] = 0x5264, --(剤)
+ [0x1A3F] = 0x5728, --(在)
+ [0x1A40] = 0x6750, --(æ)
+ [0x1A41] = 0x7F6A, --(罪)
+ [0x1A42] = 0x8CA1, --(財)
+ [0x1A43] = 0x51B4, --(冴)
+ [0x1A44] = 0x5742, --(å‚)
+ [0x1A45] = 0x962A, --(阪)
+ [0x1A46] = 0x583A, --(å º)
+ [0x1A47] = 0x698A, --(榊)
+ [0x1A48] = 0x80B4, --(è‚´)
+ [0x1A49] = 0x54B2, --(å’²)
+ [0x1A4A] = 0x5D0E, --(å´Ž)
+ [0x1A4B] = 0x57FC, --(埼)
+ [0x1A4C] = 0x7895, --(碕)
+ [0x1A4D] = 0x9DFA, --(é·º)
+ [0x1A4E] = 0x4F5C, --(作)
+ [0x1A4F] = 0x524A, --(削)
+ [0x1A50] = 0x548B, --(å’‹)
+ [0x1A51] = 0x643E, --(æ¾)
+ [0x1A52] = 0x6628, --(昨)
+ [0x1A53] = 0x6714, --(朔)
+ [0x1A54] = 0x67F5, --(柵)
+ [0x1A55] = 0x7A84, --(窄)
+ [0x1A56] = 0x7B56, --(ç­–)
+ [0x1A57] = 0x7D22, --(ç´¢)
+ [0x1A58] = 0x932F, --(錯)
+ [0x1A59] = 0x685C, --(桜)
+ [0x1A5A] = 0x9BAD, --(é®­)
+ [0x1A5B] = 0x7B39, --(笹)
+ [0x1A5C] = 0x5319, --(匙)
+ [0x1A5D] = 0x518A, --(冊)
+ [0x1A5E] = 0x5237, --(刷)
+ [0x1B01] = 0x5BDF, --(察)
+ [0x1B02] = 0x62F6, --(拶)
+ [0x1B03] = 0x64AE, --(æ’®)
+ [0x1B04] = 0x64E6, --(擦)
+ [0x1B05] = 0x672D, --(札)
+ [0x1B06] = 0x6BBA, --(殺)
+ [0x1B07] = 0x85A9, --(è–©)
+ [0x1B08] = 0x96D1, --(雑)
+ [0x1B09] = 0x7690, --(çš)
+ [0x1B0A] = 0x9BD6, --(鯖)
+ [0x1B0B] = 0x634C, --(æŒ)
+ [0x1B0C] = 0x9306, --(錆)
+ [0x1B0D] = 0x9BAB, --(鮫)
+ [0x1B0E] = 0x76BF, --(çš¿)
+ [0x1B0F] = 0x6652, --(æ™’)
+ [0x1B10] = 0x4E09, --(三)
+ [0x1B11] = 0x5098, --(傘)
+ [0x1B12] = 0x53C2, --(å‚)
+ [0x1B13] = 0x5C71, --(å±±)
+ [0x1B14] = 0x60E8, --(惨)
+ [0x1B15] = 0x6492, --(æ’’)
+ [0x1B16] = 0x6563, --(æ•£)
+ [0x1B17] = 0x685F, --(æ¡Ÿ)
+ [0x1B18] = 0x71E6, --(燦)
+ [0x1B19] = 0x73CA, --(çŠ)
+ [0x1B1A] = 0x7523, --(産)
+ [0x1B1B] = 0x7B97, --(ç®—)
+ [0x1B1C] = 0x7E82, --(纂)
+ [0x1B1D] = 0x8695, --(èš•)
+ [0x1B1E] = 0x8B83, --(讃)
+ [0x1B1F] = 0x8CDB, --(è³›)
+ [0x1B20] = 0x9178, --(é…¸)
+ [0x1B21] = 0x9910, --(é¤)
+ [0x1B22] = 0x65AC, --(æ–¬)
+ [0x1B23] = 0x66AB, --(æš«)
+ [0x1B24] = 0x6B8B, --(残)
+ [0x1B25] = 0x4ED5, --(仕)
+ [0x1B26] = 0x4ED4, --(ä»”)
+ [0x1B27] = 0x4F3A, --(伺)
+ [0x1B28] = 0x4F7F, --(使)
+ [0x1B29] = 0x523A, --(刺)
+ [0x1B2A] = 0x53F8, --(å¸)
+ [0x1B2B] = 0x53F2, --(å²)
+ [0x1B2C] = 0x55E3, --(å—£)
+ [0x1B2D] = 0x56DB, --(å››)
+ [0x1B2E] = 0x58EB, --(士)
+ [0x1B2F] = 0x59CB, --(始)
+ [0x1B30] = 0x59C9, --(姉)
+ [0x1B31] = 0x59FF, --(姿)
+ [0x1B32] = 0x5B50, --(å­)
+ [0x1B33] = 0x5C4D, --(å±)
+ [0x1B34] = 0x5E02, --(市)
+ [0x1B35] = 0x5E2B, --(師)
+ [0x1B36] = 0x5FD7, --(å¿—)
+ [0x1B37] = 0x601D, --(æ€)
+ [0x1B38] = 0x6307, --(指)
+ [0x1B39] = 0x652F, --(支)
+ [0x1B3A] = 0x5B5C, --(孜)
+ [0x1B3B] = 0x65AF, --(æ–¯)
+ [0x1B3C] = 0x65BD, --(æ–½)
+ [0x1B3D] = 0x65E8, --(æ—¨)
+ [0x1B3E] = 0x679D, --(æž)
+ [0x1B3F] = 0x6B62, --(æ­¢)
+ [0x1B40] = 0x6B7B, --(æ­»)
+ [0x1B41] = 0x6C0F, --(æ°)
+ [0x1B42] = 0x7345, --(ç…)
+ [0x1B43] = 0x7949, --(祉)
+ [0x1B44] = 0x79C1, --(ç§)
+ [0x1B45] = 0x7CF8, --(糸)
+ [0x1B46] = 0x7D19, --(ç´™)
+ [0x1B47] = 0x7D2B, --(ç´«)
+ [0x1B48] = 0x80A2, --(è‚¢)
+ [0x1B49] = 0x8102, --(è„‚)
+ [0x1B4A] = 0x81F3, --(至)
+ [0x1B4B] = 0x8996, --(視)
+ [0x1B4C] = 0x8A5E, --(è©ž)
+ [0x1B4D] = 0x8A69, --(è©©)
+ [0x1B4E] = 0x8A66, --(試)
+ [0x1B4F] = 0x8A8C, --(誌)
+ [0x1B50] = 0x8AEE, --(è«®)
+ [0x1B51] = 0x8CC7, --(資)
+ [0x1B52] = 0x8CDC, --(賜)
+ [0x1B53] = 0x96CC, --(雌)
+ [0x1B54] = 0x98FC, --(飼)
+ [0x1B55] = 0x6B6F, --(æ­¯)
+ [0x1B56] = 0x4E8B, --(事)
+ [0x1B57] = 0x4F3C, --(ä¼¼)
+ [0x1B58] = 0x4F8D, --(ä¾)
+ [0x1B59] = 0x5150, --(å…)
+ [0x1B5A] = 0x5B57, --(å­—)
+ [0x1B5B] = 0x5BFA, --(寺)
+ [0x1B5C] = 0x6148, --(æ…ˆ)
+ [0x1B5D] = 0x6301, --(æŒ)
+ [0x1B5E] = 0x6642, --(時)
+ [0x1C01] = 0x6B21, --(次)
+ [0x1C02] = 0x6ECB, --(滋)
+ [0x1C03] = 0x6CBB, --(æ²»)
+ [0x1C04] = 0x723E, --(爾)
+ [0x1C05] = 0x74BD, --(ç’½)
+ [0x1C06] = 0x75D4, --(ç—”)
+ [0x1C07] = 0x78C1, --(ç£)
+ [0x1C08] = 0x793A, --(示)
+ [0x1C09] = 0x800C, --(而)
+ [0x1C0A] = 0x8033, --(耳)
+ [0x1C0B] = 0x81EA, --(自)
+ [0x1C0C] = 0x8494, --(è’”)
+ [0x1C0D] = 0x8F9E, --(辞)
+ [0x1C0E] = 0x6C50, --(æ±)
+ [0x1C0F] = 0x9E7F, --(鹿)
+ [0x1C10] = 0x5F0F, --(å¼)
+ [0x1C11] = 0x8B58, --(è­˜)
+ [0x1C12] = 0x9D2B, --(é´«)
+ [0x1C13] = 0x7AFA, --(竺)
+ [0x1C14] = 0x8EF8, --(軸)
+ [0x1C15] = 0x5B8D, --(å®)
+ [0x1C16] = 0x96EB, --(雫)
+ [0x1C17] = 0x4E03, --(七)
+ [0x1C18] = 0x53F1, --(å±)
+ [0x1C19] = 0x57F7, --(執)
+ [0x1C1A] = 0x5931, --(失)
+ [0x1C1B] = 0x5AC9, --(嫉)
+ [0x1C1C] = 0x5BA4, --(室)
+ [0x1C1D] = 0x6089, --(悉)
+ [0x1C1E] = 0x6E7F, --(湿)
+ [0x1C1F] = 0x6F06, --(漆)
+ [0x1C20] = 0x75BE, --(ç–¾)
+ [0x1C21] = 0x8CEA, --(質)
+ [0x1C22] = 0x5B9F, --(実)
+ [0x1C23] = 0x8500, --(蔀)
+ [0x1C24] = 0x7BE0, --(篠)
+ [0x1C25] = 0x5072, --(å²)
+ [0x1C26] = 0x67F4, --(柴)
+ [0x1C27] = 0x829D, --(èŠ)
+ [0x1C28] = 0x5C61, --(屡)
+ [0x1C29] = 0x854A, --(è•Š)
+ [0x1C2A] = 0x7E1E, --(縞)
+ [0x1C2B] = 0x820E, --(舎)
+ [0x1C2C] = 0x5199, --(写)
+ [0x1C2D] = 0x5C04, --(å°„)
+ [0x1C2E] = 0x6368, --(æ¨)
+ [0x1C2F] = 0x8D66, --(赦)
+ [0x1C30] = 0x659C, --(斜)
+ [0x1C31] = 0x716E, --(ç…®)
+ [0x1C32] = 0x793E, --(社)
+ [0x1C33] = 0x7D17, --(ç´—)
+ [0x1C34] = 0x8005, --(者)
+ [0x1C35] = 0x8B1D, --(è¬)
+ [0x1C36] = 0x8ECA, --(車)
+ [0x1C37] = 0x906E, --(é®)
+ [0x1C38] = 0x86C7, --(蛇)
+ [0x1C39] = 0x90AA, --(邪)
+ [0x1C3A] = 0x501F, --(借)
+ [0x1C3B] = 0x52FA, --(勺)
+ [0x1C3C] = 0x5C3A, --(å°º)
+ [0x1C3D] = 0x6753, --(æ“)
+ [0x1C3E] = 0x707C, --(ç¼)
+ [0x1C3F] = 0x7235, --(爵)
+ [0x1C40] = 0x914C, --(酌)
+ [0x1C41] = 0x91C8, --(釈)
+ [0x1C42] = 0x932B, --(錫)
+ [0x1C43] = 0x82E5, --(è‹¥)
+ [0x1C44] = 0x5BC2, --(寂)
+ [0x1C45] = 0x5F31, --(å¼±)
+ [0x1C46] = 0x60F9, --(惹)
+ [0x1C47] = 0x4E3B, --(主)
+ [0x1C48] = 0x53D6, --(å–)
+ [0x1C49] = 0x5B88, --(守)
+ [0x1C4A] = 0x624B, --(手)
+ [0x1C4B] = 0x6731, --(朱)
+ [0x1C4C] = 0x6B8A, --(殊)
+ [0x1C4D] = 0x72E9, --(ç‹©)
+ [0x1C4E] = 0x73E0, --(ç )
+ [0x1C4F] = 0x7A2E, --(種)
+ [0x1C50] = 0x816B, --(è…«)
+ [0x1C51] = 0x8DA3, --(趣)
+ [0x1C52] = 0x9152, --(é…’)
+ [0x1C53] = 0x9996, --(首)
+ [0x1C54] = 0x5112, --(å„’)
+ [0x1C55] = 0x53D7, --(å—)
+ [0x1C56] = 0x546A, --(呪)
+ [0x1C57] = 0x5BFF, --(寿)
+ [0x1C58] = 0x6388, --(授)
+ [0x1C59] = 0x6A39, --(樹)
+ [0x1C5A] = 0x7DAC, --(綬)
+ [0x1C5B] = 0x9700, --(需)
+ [0x1C5C] = 0x56DA, --(囚)
+ [0x1C5D] = 0x53CE, --(åŽ)
+ [0x1C5E] = 0x5468, --(周)
+ [0x1D01] = 0x5B97, --(å®—)
+ [0x1D02] = 0x5C31, --(å°±)
+ [0x1D03] = 0x5DDE, --(å·ž)
+ [0x1D04] = 0x4FEE, --(ä¿®)
+ [0x1D05] = 0x6101, --(æ„)
+ [0x1D06] = 0x62FE, --(拾)
+ [0x1D07] = 0x6D32, --(æ´²)
+ [0x1D08] = 0x79C0, --(秀)
+ [0x1D09] = 0x79CB, --(秋)
+ [0x1D0A] = 0x7D42, --(終)
+ [0x1D0B] = 0x7E4D, --(ç¹)
+ [0x1D0C] = 0x7FD2, --(ç¿’)
+ [0x1D0D] = 0x81ED, --(臭)
+ [0x1D0E] = 0x821F, --(舟)
+ [0x1D0F] = 0x8490, --(è’)
+ [0x1D10] = 0x8846, --(衆)
+ [0x1D11] = 0x8972, --(襲)
+ [0x1D12] = 0x8B90, --(è®)
+ [0x1D13] = 0x8E74, --(è¹´)
+ [0x1D14] = 0x8F2F, --(輯)
+ [0x1D15] = 0x9031, --(週)
+ [0x1D16] = 0x914B, --(é…‹)
+ [0x1D17] = 0x916C, --(é…¬)
+ [0x1D18] = 0x96C6, --(集)
+ [0x1D19] = 0x919C, --(醜)
+ [0x1D1A] = 0x4EC0, --(什)
+ [0x1D1B] = 0x4F4F, --(ä½)
+ [0x1D1C] = 0x5145, --(å……)
+ [0x1D1D] = 0x5341, --(å)
+ [0x1D1E] = 0x5F93, --(従)
+ [0x1D1F] = 0x620E, --(戎)
+ [0x1D20] = 0x67D4, --(柔)
+ [0x1D21] = 0x6C41, --(æ±)
+ [0x1D22] = 0x6E0B, --(渋)
+ [0x1D23] = 0x7363, --(ç£)
+ [0x1D24] = 0x7E26, --(縦)
+ [0x1D25] = 0x91CD, --(é‡)
+ [0x1D26] = 0x9283, --(銃)
+ [0x1D27] = 0x53D4, --(å”)
+ [0x1D28] = 0x5919, --(夙)
+ [0x1D29] = 0x5BBF, --(宿)
+ [0x1D2A] = 0x6DD1, --(æ·‘)
+ [0x1D2B] = 0x795D, --(ç¥)
+ [0x1D2C] = 0x7E2E, --(縮)
+ [0x1D2D] = 0x7C9B, --(ç²›)
+ [0x1D2E] = 0x587E, --(塾)
+ [0x1D2F] = 0x719F, --(熟)
+ [0x1D30] = 0x51FA, --(出)
+ [0x1D31] = 0x8853, --(è¡“)
+ [0x1D32] = 0x8FF0, --(è¿°)
+ [0x1D33] = 0x4FCA, --(ä¿Š)
+ [0x1D34] = 0x5CFB, --(å³»)
+ [0x1D35] = 0x6625, --(春)
+ [0x1D36] = 0x77AC, --(瞬)
+ [0x1D37] = 0x7AE3, --(ç«£)
+ [0x1D38] = 0x821C, --(舜)
+ [0x1D39] = 0x99FF, --(駿)
+ [0x1D3A] = 0x51C6, --(准)
+ [0x1D3B] = 0x5FAA, --(循)
+ [0x1D3C] = 0x65EC, --(æ—¬)
+ [0x1D3D] = 0x696F, --(楯)
+ [0x1D3E] = 0x6B89, --(殉)
+ [0x1D3F] = 0x6DF3, --(æ·³)
+ [0x1D40] = 0x6E96, --(準)
+ [0x1D41] = 0x6F64, --(潤)
+ [0x1D42] = 0x76FE, --(盾)
+ [0x1D43] = 0x7D14, --(ç´”)
+ [0x1D44] = 0x5DE1, --(å·¡)
+ [0x1D45] = 0x9075, --(éµ)
+ [0x1D46] = 0x9187, --(醇)
+ [0x1D47] = 0x9806, --(é †)
+ [0x1D48] = 0x51E6, --(処)
+ [0x1D49] = 0x521D, --(åˆ)
+ [0x1D4A] = 0x6240, --(所)
+ [0x1D4B] = 0x6691, --(æš‘)
+ [0x1D4C] = 0x66D9, --(æ›™)
+ [0x1D4D] = 0x6E1A, --(渚)
+ [0x1D4E] = 0x5EB6, --(庶)
+ [0x1D4F] = 0x7DD2, --(ç·’)
+ [0x1D50] = 0x7F72, --(ç½²)
+ [0x1D51] = 0x66F8, --(書)
+ [0x1D52] = 0x85AF, --(è–¯)
+ [0x1D53] = 0x85F7, --(è—·)
+ [0x1D54] = 0x8AF8, --(諸)
+ [0x1D55] = 0x52A9, --(助)
+ [0x1D56] = 0x53D9, --(å™)
+ [0x1D57] = 0x5973, --(女)
+ [0x1D58] = 0x5E8F, --(åº)
+ [0x1D59] = 0x5F90, --(å¾)
+ [0x1D5A] = 0x6055, --(æ•)
+ [0x1D5B] = 0x92E4, --(鋤)
+ [0x1D5C] = 0x9664, --(除)
+ [0x1D5D] = 0x50B7, --(å‚·)
+ [0x1D5E] = 0x511F, --(å„Ÿ)
+ [0x1E01] = 0x52DD, --(å‹)
+ [0x1E02] = 0x5320, --(匠)
+ [0x1E03] = 0x5347, --(å‡)
+ [0x1E04] = 0x53EC, --(å¬)
+ [0x1E05] = 0x54E8, --(哨)
+ [0x1E06] = 0x5546, --(商)
+ [0x1E07] = 0x5531, --(å”±)
+ [0x1E08] = 0x5617, --(嘗)
+ [0x1E09] = 0x5968, --(奨)
+ [0x1E0A] = 0x59BE, --(妾)
+ [0x1E0B] = 0x5A3C, --(娼)
+ [0x1E0C] = 0x5BB5, --(宵)
+ [0x1E0D] = 0x5C06, --(å°†)
+ [0x1E0E] = 0x5C0F, --(å°)
+ [0x1E0F] = 0x5C11, --(å°‘)
+ [0x1E10] = 0x5C1A, --(å°š)
+ [0x1E11] = 0x5E84, --(庄)
+ [0x1E12] = 0x5E8A, --(床)
+ [0x1E13] = 0x5EE0, --(å» )
+ [0x1E14] = 0x5F70, --(å½°)
+ [0x1E15] = 0x627F, --(承)
+ [0x1E16] = 0x6284, --(抄)
+ [0x1E17] = 0x62DB, --(æ‹›)
+ [0x1E18] = 0x638C, --(掌)
+ [0x1E19] = 0x6377, --(æ·)
+ [0x1E1A] = 0x6607, --(昇)
+ [0x1E1B] = 0x660C, --(昌)
+ [0x1E1C] = 0x662D, --(昭)
+ [0x1E1D] = 0x6676, --(晶)
+ [0x1E1E] = 0x677E, --(æ¾)
+ [0x1E1F] = 0x68A2, --(梢)
+ [0x1E20] = 0x6A1F, --(樟)
+ [0x1E21] = 0x6A35, --(樵)
+ [0x1E22] = 0x6CBC, --(æ²¼)
+ [0x1E23] = 0x6D88, --(消)
+ [0x1E24] = 0x6E09, --(渉)
+ [0x1E25] = 0x6E58, --(湘)
+ [0x1E26] = 0x713C, --(焼)
+ [0x1E27] = 0x7126, --(焦)
+ [0x1E28] = 0x7167, --(ç…§)
+ [0x1E29] = 0x75C7, --(ç—‡)
+ [0x1E2A] = 0x7701, --(çœ)
+ [0x1E2B] = 0x785D, --(ç¡)
+ [0x1E2C] = 0x7901, --(ç¤)
+ [0x1E2D] = 0x7965, --(祥)
+ [0x1E2E] = 0x79F0, --(称)
+ [0x1E2F] = 0x7AE0, --(ç« )
+ [0x1E30] = 0x7B11, --(笑)
+ [0x1E31] = 0x7CA7, --(粧)
+ [0x1E32] = 0x7D39, --(ç´¹)
+ [0x1E33] = 0x8096, --(è‚–)
+ [0x1E34] = 0x83D6, --(è–)
+ [0x1E35] = 0x848B, --(è’‹)
+ [0x1E36] = 0x8549, --(蕉)
+ [0x1E37] = 0x885D, --(è¡)
+ [0x1E38] = 0x88F3, --(裳)
+ [0x1E39] = 0x8A1F, --(訟)
+ [0x1E3A] = 0x8A3C, --(証)
+ [0x1E3B] = 0x8A54, --(è©”)
+ [0x1E3C] = 0x8A73, --(詳)
+ [0x1E3D] = 0x8C61, --(象)
+ [0x1E3E] = 0x8CDE, --(賞)
+ [0x1E3F] = 0x91A4, --(醤)
+ [0x1E40] = 0x9266, --(鉦)
+ [0x1E41] = 0x937E, --(é¾)
+ [0x1E42] = 0x9418, --(é˜)
+ [0x1E43] = 0x969C, --(障)
+ [0x1E44] = 0x9798, --(鞘)
+ [0x1E45] = 0x4E0A, --(上)
+ [0x1E46] = 0x4E08, --(丈)
+ [0x1E47] = 0x4E1E, --(丞)
+ [0x1E48] = 0x4E57, --(ä¹—)
+ [0x1E49] = 0x5197, --(冗)
+ [0x1E4A] = 0x5270, --(剰)
+ [0x1E4B] = 0x57CE, --(城)
+ [0x1E4C] = 0x5834, --(å ´)
+ [0x1E4D] = 0x58CC, --(壌)
+ [0x1E4E] = 0x5B22, --(嬢)
+ [0x1E4F] = 0x5E38, --(常)
+ [0x1E50] = 0x60C5, --(情)
+ [0x1E51] = 0x64FE, --(擾)
+ [0x1E52] = 0x6761, --(æ¡)
+ [0x1E53] = 0x6756, --(æ–)
+ [0x1E54] = 0x6D44, --(浄)
+ [0x1E55] = 0x72B6, --(状)
+ [0x1E56] = 0x7573, --(畳)
+ [0x1E57] = 0x7A63, --(ç©£)
+ [0x1E58] = 0x84B8, --(è’¸)
+ [0x1E59] = 0x8B72, --(è­²)
+ [0x1E5A] = 0x91B8, --(醸)
+ [0x1E5B] = 0x9320, --(錠)
+ [0x1E5C] = 0x5631, --(嘱)
+ [0x1E5D] = 0x57F4, --(埴)
+ [0x1E5E] = 0x98FE, --(飾)
+ [0x1F01] = 0x62ED, --(æ‹­)
+ [0x1F02] = 0x690D, --(æ¤)
+ [0x1F03] = 0x6B96, --(æ®–)
+ [0x1F04] = 0x71ED, --(燭)
+ [0x1F05] = 0x7E54, --(ç¹”)
+ [0x1F06] = 0x8077, --(è·)
+ [0x1F07] = 0x8272, --(色)
+ [0x1F08] = 0x89E6, --(触)
+ [0x1F09] = 0x98DF, --(食)
+ [0x1F0A] = 0x8755, --(è•)
+ [0x1F0B] = 0x8FB1, --(è¾±)
+ [0x1F0C] = 0x5C3B, --(å°»)
+ [0x1F0D] = 0x4F38, --(伸)
+ [0x1F0E] = 0x4FE1, --(ä¿¡)
+ [0x1F0F] = 0x4FB5, --(ä¾µ)
+ [0x1F10] = 0x5507, --(唇)
+ [0x1F11] = 0x5A20, --(娠)
+ [0x1F12] = 0x5BDD, --(å¯)
+ [0x1F13] = 0x5BE9, --(審)
+ [0x1F14] = 0x5FC3, --(心)
+ [0x1F15] = 0x614E, --(æ…Ž)
+ [0x1F16] = 0x632F, --(振)
+ [0x1F17] = 0x65B0, --(æ–°)
+ [0x1F18] = 0x664B, --(晋)
+ [0x1F19] = 0x68EE, --(森)
+ [0x1F1A] = 0x699B, --(榛)
+ [0x1F1B] = 0x6D78, --(浸)
+ [0x1F1C] = 0x6DF1, --(æ·±)
+ [0x1F1D] = 0x7533, --(申)
+ [0x1F1E] = 0x75B9, --(ç–¹)
+ [0x1F1F] = 0x771F, --(真)
+ [0x1F20] = 0x795E, --(神)
+ [0x1F21] = 0x79E6, --(秦)
+ [0x1F22] = 0x7D33, --(ç´³)
+ [0x1F23] = 0x81E3, --(臣)
+ [0x1F24] = 0x82AF, --(芯)
+ [0x1F25] = 0x85AA, --(è–ª)
+ [0x1F26] = 0x89AA, --(親)
+ [0x1F27] = 0x8A3A, --(診)
+ [0x1F28] = 0x8EAB, --(身)
+ [0x1F29] = 0x8F9B, --(è¾›)
+ [0x1F2A] = 0x9032, --(進)
+ [0x1F2B] = 0x91DD, --(é‡)
+ [0x1F2C] = 0x9707, --(震)
+ [0x1F2D] = 0x4EBA, --(人)
+ [0x1F2E] = 0x4EC1, --(ä»)
+ [0x1F2F] = 0x5203, --(刃)
+ [0x1F30] = 0x5875, --(塵)
+ [0x1F31] = 0x58EC, --(壬)
+ [0x1F32] = 0x5C0B, --(å°‹)
+ [0x1F33] = 0x751A, --(甚)
+ [0x1F34] = 0x5C3D, --(å°½)
+ [0x1F35] = 0x814E, --(è…Ž)
+ [0x1F36] = 0x8A0A, --(訊)
+ [0x1F37] = 0x8FC5, --(è¿…)
+ [0x1F38] = 0x9663, --(陣)
+ [0x1F39] = 0x976D, --(é­)
+ [0x1F3A] = 0x7B25, --(笥)
+ [0x1F3B] = 0x8ACF, --(è«)
+ [0x1F3C] = 0x9808, --(é ˆ)
+ [0x1F3D] = 0x9162, --(é…¢)
+ [0x1F3E] = 0x56F3, --(図)
+ [0x1F3F] = 0x53A8, --(厨)
+ [0x1F40] = 0x9017, --(逗)
+ [0x1F41] = 0x5439, --(å¹)
+ [0x1F42] = 0x5782, --(åž‚)
+ [0x1F43] = 0x5E25, --(帥)
+ [0x1F44] = 0x63A8, --(推)
+ [0x1F45] = 0x6C34, --(æ°´)
+ [0x1F46] = 0x708A, --(ç‚Š)
+ [0x1F47] = 0x7761, --(ç¡)
+ [0x1F48] = 0x7C8B, --(粋)
+ [0x1F49] = 0x7FE0, --(ç¿ )
+ [0x1F4A] = 0x8870, --(è¡°)
+ [0x1F4B] = 0x9042, --(é‚)
+ [0x1F4C] = 0x9154, --(é…”)
+ [0x1F4D] = 0x9310, --(éŒ)
+ [0x1F4E] = 0x9318, --(錘)
+ [0x1F4F] = 0x968F, --(éš)
+ [0x1F50] = 0x745E, --(ç‘ž)
+ [0x1F51] = 0x9AC4, --(é«„)
+ [0x1F52] = 0x5D07, --(å´‡)
+ [0x1F53] = 0x5D69, --(嵩)
+ [0x1F54] = 0x6570, --(æ•°)
+ [0x1F55] = 0x67A2, --(枢)
+ [0x1F56] = 0x8DA8, --(趨)
+ [0x1F57] = 0x96DB, --(é››)
+ [0x1F58] = 0x636E, --(æ®)
+ [0x1F59] = 0x6749, --(æ‰)
+ [0x1F5A] = 0x6919, --(椙)
+ [0x1F5B] = 0x83C5, --(è…)
+ [0x1F5C] = 0x9817, --(é —)
+ [0x1F5D] = 0x96C0, --(雀)
+ [0x1F5E] = 0x88FE, --(裾)
+ [0x2001] = 0x6F84, --(澄)
+ [0x2002] = 0x647A, --(摺)
+ [0x2003] = 0x5BF8, --(寸)
+ [0x2004] = 0x4E16, --(世)
+ [0x2005] = 0x702C, --(瀬)
+ [0x2006] = 0x755D, --(ç•)
+ [0x2007] = 0x662F, --(是)
+ [0x2008] = 0x51C4, --(凄)
+ [0x2009] = 0x5236, --(制)
+ [0x200A] = 0x52E2, --(å‹¢)
+ [0x200B] = 0x59D3, --(姓)
+ [0x200C] = 0x5F81, --(å¾)
+ [0x200D] = 0x6027, --(性)
+ [0x200E] = 0x6210, --(æˆ)
+ [0x200F] = 0x653F, --(政)
+ [0x2010] = 0x6574, --(æ•´)
+ [0x2011] = 0x661F, --(星)
+ [0x2012] = 0x6674, --(æ™´)
+ [0x2013] = 0x68F2, --(棲)
+ [0x2014] = 0x6816, --(æ –)
+ [0x2015] = 0x6B63, --(æ­£)
+ [0x2016] = 0x6E05, --(清)
+ [0x2017] = 0x7272, --(牲)
+ [0x2018] = 0x751F, --(生)
+ [0x2019] = 0x76DB, --(ç››)
+ [0x201A] = 0x7CBE, --(ç²¾)
+ [0x201B] = 0x8056, --(è–)
+ [0x201C] = 0x58F0, --(声)
+ [0x201D] = 0x88FD, --(製)
+ [0x201E] = 0x897F, --(西)
+ [0x201F] = 0x8AA0, --(誠)
+ [0x2020] = 0x8A93, --(誓)
+ [0x2021] = 0x8ACB, --(è«‹)
+ [0x2022] = 0x901D, --(é€)
+ [0x2023] = 0x9192, --(醒)
+ [0x2024] = 0x9752, --(é’)
+ [0x2025] = 0x9759, --(é™)
+ [0x2026] = 0x6589, --(æ–‰)
+ [0x2027] = 0x7A0E, --(税)
+ [0x2028] = 0x8106, --(脆)
+ [0x2029] = 0x96BB, --(éš»)
+ [0x202A] = 0x5E2D, --(席)
+ [0x202B] = 0x60DC, --(惜)
+ [0x202C] = 0x621A, --(戚)
+ [0x202D] = 0x65A5, --(æ–¥)
+ [0x202E] = 0x6614, --(昔)
+ [0x202F] = 0x6790, --(æž)
+ [0x2030] = 0x77F3, --(石)
+ [0x2031] = 0x7A4D, --(ç©)
+ [0x2032] = 0x7C4D, --(ç±)
+ [0x2033] = 0x7E3E, --(績)
+ [0x2034] = 0x810A, --(è„Š)
+ [0x2035] = 0x8CAC, --(責)
+ [0x2036] = 0x8D64, --(赤)
+ [0x2037] = 0x8DE1, --(è·¡)
+ [0x2038] = 0x8E5F, --(蹟)
+ [0x2039] = 0x78A9, --(碩)
+ [0x203A] = 0x5207, --(切)
+ [0x203B] = 0x62D9, --(æ‹™)
+ [0x203C] = 0x63A5, --(接)
+ [0x203D] = 0x6442, --(æ‘‚)
+ [0x203E] = 0x6298, --(折)
+ [0x203F] = 0x8A2D, --(設)
+ [0x2040] = 0x7A83, --(窃)
+ [0x2041] = 0x7BC0, --(節)
+ [0x2042] = 0x8AAC, --(説)
+ [0x2043] = 0x96EA, --(雪)
+ [0x2044] = 0x7D76, --(絶)
+ [0x2045] = 0x820C, --(舌)
+ [0x2046] = 0x8749, --(è‰)
+ [0x2047] = 0x4ED9, --(ä»™)
+ [0x2048] = 0x5148, --(å…ˆ)
+ [0x2049] = 0x5343, --(åƒ)
+ [0x204A] = 0x5360, --(å )
+ [0x204B] = 0x5BA3, --(宣)
+ [0x204C] = 0x5C02, --(å°‚)
+ [0x204D] = 0x5C16, --(å°–)
+ [0x204E] = 0x5DDD, --(å·)
+ [0x204F] = 0x6226, --(戦)
+ [0x2050] = 0x6247, --(扇)
+ [0x2051] = 0x64B0, --(æ’°)
+ [0x2052] = 0x6813, --(æ “)
+ [0x2053] = 0x6834, --(æ ´)
+ [0x2054] = 0x6CC9, --(泉)
+ [0x2055] = 0x6D45, --(æµ…)
+ [0x2056] = 0x6D17, --(æ´—)
+ [0x2057] = 0x67D3, --(染)
+ [0x2058] = 0x6F5C, --(潜)
+ [0x2059] = 0x714E, --(ç…Ž)
+ [0x205A] = 0x717D, --(ç…½)
+ [0x205B] = 0x65CB, --(æ—‹)
+ [0x205C] = 0x7A7F, --(ç©¿)
+ [0x205D] = 0x7BAD, --(ç®­)
+ [0x205E] = 0x7DDA, --(ç·š)
+ [0x2101] = 0x7E4A, --(繊)
+ [0x2102] = 0x7FA8, --(羨)
+ [0x2103] = 0x817A, --(è…º)
+ [0x2104] = 0x821B, --(舛)
+ [0x2105] = 0x8239, --(船)
+ [0x2106] = 0x85A6, --(è–¦)
+ [0x2107] = 0x8A6E, --(è©®)
+ [0x2108] = 0x8CCE, --(賎)
+ [0x2109] = 0x8DF5, --(è·µ)
+ [0x210A] = 0x9078, --(é¸)
+ [0x210B] = 0x9077, --(é·)
+ [0x210C] = 0x92AD, --(銭)
+ [0x210D] = 0x9291, --(銑)
+ [0x210E] = 0x9583, --(é–ƒ)
+ [0x210F] = 0x9BAE, --(é®®)
+ [0x2110] = 0x524D, --(å‰)
+ [0x2111] = 0x5584, --(å–„)
+ [0x2112] = 0x6F38, --(漸)
+ [0x2113] = 0x7136, --(然)
+ [0x2114] = 0x5168, --(å…¨)
+ [0x2115] = 0x7985, --(禅)
+ [0x2116] = 0x7E55, --(繕)
+ [0x2117] = 0x81B3, --(膳)
+ [0x2118] = 0x7CCE, --(糎)
+ [0x2119] = 0x564C, --(噌)
+ [0x211A] = 0x5851, --(å¡‘)
+ [0x211B] = 0x5CA8, --(岨)
+ [0x211C] = 0x63AA, --(措)
+ [0x211D] = 0x66FE, --(曾)
+ [0x211E] = 0x66FD, --(曽)
+ [0x211F] = 0x695A, --(楚)
+ [0x2120] = 0x72D9, --(ç‹™)
+ [0x2121] = 0x758F, --(ç–)
+ [0x2122] = 0x758E, --(ç–Ž)
+ [0x2123] = 0x790E, --(礎)
+ [0x2124] = 0x7956, --(祖)
+ [0x2125] = 0x79DF, --(租)
+ [0x2126] = 0x7C97, --(ç²—)
+ [0x2127] = 0x7D20, --(ç´ )
+ [0x2128] = 0x7D44, --(組)
+ [0x2129] = 0x8607, --(蘇)
+ [0x212A] = 0x8A34, --(訴)
+ [0x212B] = 0x963B, --(阻)
+ [0x212C] = 0x9061, --(é¡)
+ [0x212D] = 0x9F20, --(é¼ )
+ [0x212E] = 0x50E7, --(僧)
+ [0x212F] = 0x5275, --(創)
+ [0x2130] = 0x53CC, --(åŒ)
+ [0x2131] = 0x53E2, --(å¢)
+ [0x2132] = 0x5009, --(倉)
+ [0x2133] = 0x55AA, --(å–ª)
+ [0x2134] = 0x58EE, --(壮)
+ [0x2135] = 0x594F, --(å¥)
+ [0x2136] = 0x723D, --(爽)
+ [0x2137] = 0x5B8B, --(宋)
+ [0x2138] = 0x5C64, --(層)
+ [0x2139] = 0x531D, --(åŒ)
+ [0x213A] = 0x60E3, --(惣)
+ [0x213B] = 0x60F3, --(想)
+ [0x213C] = 0x635C, --(æœ)
+ [0x213D] = 0x6383, --(掃)
+ [0x213E] = 0x633F, --(挿)
+ [0x213F] = 0x63BB, --(掻)
+ [0x2140] = 0x64CD, --(æ“)
+ [0x2141] = 0x65E9, --(æ—©)
+ [0x2142] = 0x66F9, --(曹)
+ [0x2143] = 0x5DE3, --(å·£)
+ [0x2144] = 0x69CD, --(æ§)
+ [0x2145] = 0x69FD, --(槽)
+ [0x2146] = 0x6F15, --(漕)
+ [0x2147] = 0x71E5, --(燥)
+ [0x2148] = 0x4E89, --(争)
+ [0x2149] = 0x75E9, --(ç—©)
+ [0x214A] = 0x76F8, --(相)
+ [0x214B] = 0x7A93, --(窓)
+ [0x214C] = 0x7CDF, --(糟)
+ [0x214D] = 0x7DCF, --(ç·)
+ [0x214E] = 0x7D9C, --(綜)
+ [0x214F] = 0x8061, --(è¡)
+ [0x2150] = 0x8349, --(è‰)
+ [0x2151] = 0x8358, --(è˜)
+ [0x2152] = 0x846C, --(葬)
+ [0x2153] = 0x84BC, --(è’¼)
+ [0x2154] = 0x85FB, --(è—»)
+ [0x2155] = 0x88C5, --(装)
+ [0x2156] = 0x8D70, --(èµ°)
+ [0x2157] = 0x9001, --(é€)
+ [0x2158] = 0x906D, --(é­)
+ [0x2159] = 0x9397, --(鎗)
+ [0x215A] = 0x971C, --(霜)
+ [0x215B] = 0x9A12, --(騒)
+ [0x215C] = 0x50CF, --(åƒ)
+ [0x215D] = 0x5897, --(増)
+ [0x215E] = 0x618E, --(憎)
+ [0x2201] = 0x81D3, --(臓)
+ [0x2202] = 0x8535, --(蔵)
+ [0x2203] = 0x8D08, --(è´ˆ)
+ [0x2204] = 0x9020, --(造)
+ [0x2205] = 0x4FC3, --(促)
+ [0x2206] = 0x5074, --(å´)
+ [0x2207] = 0x5247, --(則)
+ [0x2208] = 0x5373, --(å³)
+ [0x2209] = 0x606F, --(æ¯)
+ [0x220A] = 0x6349, --(æ‰)
+ [0x220B] = 0x675F, --(æŸ)
+ [0x220C] = 0x6E2C, --(測)
+ [0x220D] = 0x8DB3, --(足)
+ [0x220E] = 0x901F, --(速)
+ [0x220F] = 0x4FD7, --(ä¿—)
+ [0x2210] = 0x5C5E, --(属)
+ [0x2211] = 0x8CCA, --(賊)
+ [0x2212] = 0x65CF, --(æ—)
+ [0x2213] = 0x7D9A, --(続)
+ [0x2214] = 0x5352, --(å’)
+ [0x2215] = 0x8896, --(袖)
+ [0x2216] = 0x5176, --(å…¶)
+ [0x2217] = 0x63C3, --(æƒ)
+ [0x2218] = 0x5B58, --(å­˜)
+ [0x2219] = 0x5B6B, --(å­«)
+ [0x221A] = 0x5C0A, --(å°Š)
+ [0x221B] = 0x640D, --(æ)
+ [0x221C] = 0x6751, --(æ‘)
+ [0x221D] = 0x905C, --(éœ)
+ [0x221E] = 0x4ED6, --(ä»–)
+ [0x221F] = 0x591A, --(多)
+ [0x2220] = 0x592A, --(太)
+ [0x2221] = 0x6C70, --(æ±°)
+ [0x2222] = 0x8A51, --(è©‘)
+ [0x2223] = 0x553E, --(唾)
+ [0x2224] = 0x5815, --(å •)
+ [0x2225] = 0x59A5, --(妥)
+ [0x2226] = 0x60F0, --(惰)
+ [0x2227] = 0x6253, --(打)
+ [0x2228] = 0x67C1, --(æŸ)
+ [0x2229] = 0x8235, --(舵)
+ [0x222A] = 0x6955, --(楕)
+ [0x222B] = 0x9640, --(陀)
+ [0x222C] = 0x99C4, --(駄)
+ [0x222D] = 0x9A28, --(騨)
+ [0x222E] = 0x4F53, --(体)
+ [0x222F] = 0x5806, --(å †)
+ [0x2230] = 0x5BFE, --(対)
+ [0x2231] = 0x8010, --(è€)
+ [0x2232] = 0x5CB1, --(å²±)
+ [0x2233] = 0x5E2F, --(帯)
+ [0x2234] = 0x5F85, --(å¾…)
+ [0x2235] = 0x6020, --(怠)
+ [0x2236] = 0x614B, --(æ…‹)
+ [0x2237] = 0x6234, --(戴)
+ [0x2238] = 0x66FF, --(替)
+ [0x2239] = 0x6CF0, --(æ³°)
+ [0x223A] = 0x6EDE, --(滞)
+ [0x223B] = 0x80CE, --(胎)
+ [0x223C] = 0x817F, --(è…¿)
+ [0x223D] = 0x82D4, --(è‹”)
+ [0x223E] = 0x888B, --(袋)
+ [0x223F] = 0x8CB8, --(貸)
+ [0x2240] = 0x9000, --(退)
+ [0x2241] = 0x902E, --(逮)
+ [0x2242] = 0x968A, --(隊)
+ [0x2243] = 0x9EDB, --(é»›)
+ [0x2244] = 0x9BDB, --(鯛)
+ [0x2245] = 0x4EE3, --(代)
+ [0x2246] = 0x53F0, --(å°)
+ [0x2247] = 0x5927, --(大)
+ [0x2248] = 0x7B2C, --(第)
+ [0x2249] = 0x918D, --(é†)
+ [0x224A] = 0x984C, --(題)
+ [0x224B] = 0x9DF9, --(é·¹)
+ [0x224C] = 0x6EDD, --(æ»)
+ [0x224D] = 0x7027, --(瀧)
+ [0x224E] = 0x5353, --(å“)
+ [0x224F] = 0x5544, --(å•„)
+ [0x2250] = 0x5B85, --(å®…)
+ [0x2251] = 0x6258, --(托)
+ [0x2252] = 0x629E, --(択)
+ [0x2253] = 0x62D3, --(æ‹“)
+ [0x2254] = 0x6CA2, --(æ²¢)
+ [0x2255] = 0x6FEF, --(濯)
+ [0x2256] = 0x7422, --(ç¢)
+ [0x2257] = 0x8A17, --(託)
+ [0x2258] = 0x9438, --(é¸)
+ [0x2259] = 0x6FC1, --(æ¿)
+ [0x225A] = 0x8AFE, --(諾)
+ [0x225B] = 0x8338, --(茸)
+ [0x225C] = 0x51E7, --(凧)
+ [0x225D] = 0x86F8, --(蛸)
+ [0x225E] = 0x53EA, --(åª)
+ [0x2301] = 0x53E9, --(å©)
+ [0x2302] = 0x4F46, --(但)
+ [0x2303] = 0x9054, --(é”)
+ [0x2304] = 0x8FB0, --(è¾°)
+ [0x2305] = 0x596A, --(奪)
+ [0x2306] = 0x8131, --(脱)
+ [0x2307] = 0x5DFD, --(å·½)
+ [0x2308] = 0x7AEA, --(竪)
+ [0x2309] = 0x8FBF, --(辿)
+ [0x230A] = 0x68DA, --(棚)
+ [0x230B] = 0x8C37, --(è°·)
+ [0x230C] = 0x72F8, --(狸)
+ [0x230D] = 0x9C48, --(鱈)
+ [0x230E] = 0x6A3D, --(樽)
+ [0x230F] = 0x8AB0, --(誰)
+ [0x2310] = 0x4E39, --(丹)
+ [0x2311] = 0x5358, --(å˜)
+ [0x2312] = 0x5606, --(嘆)
+ [0x2313] = 0x5766, --(å¦)
+ [0x2314] = 0x62C5, --(æ‹…)
+ [0x2315] = 0x63A2, --(探)
+ [0x2316] = 0x65E6, --(æ—¦)
+ [0x2317] = 0x6B4E, --(æ­Ž)
+ [0x2318] = 0x6DE1, --(æ·¡)
+ [0x2319] = 0x6E5B, --(æ¹›)
+ [0x231A] = 0x70AD, --(ç‚­)
+ [0x231B] = 0x77ED, --(短)
+ [0x231C] = 0x7AEF, --(端)
+ [0x231D] = 0x7BAA, --(箪)
+ [0x231E] = 0x7DBB, --(綻)
+ [0x231F] = 0x803D, --(耽)
+ [0x2320] = 0x80C6, --(胆)
+ [0x2321] = 0x86CB, --(蛋)
+ [0x2322] = 0x8A95, --(誕)
+ [0x2323] = 0x935B, --(é›)
+ [0x2324] = 0x56E3, --(団)
+ [0x2325] = 0x58C7, --(壇)
+ [0x2326] = 0x5F3E, --(å¼¾)
+ [0x2327] = 0x65AD, --(æ–­)
+ [0x2328] = 0x6696, --(æš–)
+ [0x2329] = 0x6A80, --(檀)
+ [0x232A] = 0x6BB5, --(段)
+ [0x232B] = 0x7537, --(ç”·)
+ [0x232C] = 0x8AC7, --(談)
+ [0x232D] = 0x5024, --(値)
+ [0x232E] = 0x77E5, --(知)
+ [0x232F] = 0x5730, --(地)
+ [0x2330] = 0x5F1B, --(å¼›)
+ [0x2331] = 0x6065, --(æ¥)
+ [0x2332] = 0x667A, --(智)
+ [0x2333] = 0x6C60, --(æ± )
+ [0x2334] = 0x75F4, --(ç—´)
+ [0x2335] = 0x7A1A, --(稚)
+ [0x2336] = 0x7F6E, --(ç½®)
+ [0x2337] = 0x81F4, --(致)
+ [0x2338] = 0x8718, --(蜘)
+ [0x2339] = 0x9045, --(é…)
+ [0x233A] = 0x99B3, --(馳)
+ [0x233B] = 0x7BC9, --(築)
+ [0x233C] = 0x755C, --(畜)
+ [0x233D] = 0x7AF9, --(竹)
+ [0x233E] = 0x7B51, --(ç­‘)
+ [0x233F] = 0x84C4, --(è“„)
+ [0x2340] = 0x9010, --(é€)
+ [0x2341] = 0x79E9, --(秩)
+ [0x2342] = 0x7A92, --(窒)
+ [0x2343] = 0x8336, --(茶)
+ [0x2344] = 0x5AE1, --(å«¡)
+ [0x2345] = 0x7740, --(ç€)
+ [0x2346] = 0x4E2D, --(中)
+ [0x2347] = 0x4EF2, --(仲)
+ [0x2348] = 0x5B99, --(å®™)
+ [0x2349] = 0x5FE0, --(å¿ )
+ [0x234A] = 0x62BD, --(抽)
+ [0x234B] = 0x663C, --(昼)
+ [0x234C] = 0x67F1, --(柱)
+ [0x234D] = 0x6CE8, --(注)
+ [0x234E] = 0x866B, --(虫)
+ [0x234F] = 0x8877, --(è¡·)
+ [0x2350] = 0x8A3B, --(註)
+ [0x2351] = 0x914E, --(é…Ž)
+ [0x2352] = 0x92F3, --(鋳)
+ [0x2353] = 0x99D0, --(é§)
+ [0x2354] = 0x6A17, --(樗)
+ [0x2355] = 0x7026, --(瀦)
+ [0x2356] = 0x732A, --(猪)
+ [0x2357] = 0x82E7, --(苧)
+ [0x2358] = 0x8457, --(è‘—)
+ [0x2359] = 0x8CAF, --(貯)
+ [0x235A] = 0x4E01, --(ä¸)
+ [0x235B] = 0x5146, --(å…†)
+ [0x235C] = 0x51CB, --(凋)
+ [0x235D] = 0x558B, --(å–‹)
+ [0x235E] = 0x5BF5, --(寵)
+ [0x2401] = 0x5E16, --(帖)
+ [0x2402] = 0x5E33, --(帳)
+ [0x2403] = 0x5E81, --(åº)
+ [0x2404] = 0x5F14, --(å¼”)
+ [0x2405] = 0x5F35, --(å¼µ)
+ [0x2406] = 0x5F6B, --(彫)
+ [0x2407] = 0x5FB4, --(å¾´)
+ [0x2408] = 0x61F2, --(懲)
+ [0x2409] = 0x6311, --(挑)
+ [0x240A] = 0x66A2, --(暢)
+ [0x240B] = 0x671D, --(æœ)
+ [0x240C] = 0x6F6E, --(æ½®)
+ [0x240D] = 0x7252, --(牒)
+ [0x240E] = 0x753A, --(町)
+ [0x240F] = 0x773A, --(眺)
+ [0x2410] = 0x8074, --(è´)
+ [0x2411] = 0x8139, --(脹)
+ [0x2412] = 0x8178, --(è…¸)
+ [0x2413] = 0x8776, --(è¶)
+ [0x2414] = 0x8ABF, --(調)
+ [0x2415] = 0x8ADC, --(諜)
+ [0x2416] = 0x8D85, --(超)
+ [0x2417] = 0x8DF3, --(è·³)
+ [0x2418] = 0x929A, --(銚)
+ [0x2419] = 0x9577, --(é•·)
+ [0x241A] = 0x9802, --(é ‚)
+ [0x241B] = 0x9CE5, --(é³¥)
+ [0x241C] = 0x52C5, --(å‹…)
+ [0x241D] = 0x6357, --(æ—)
+ [0x241E] = 0x76F4, --(ç›´)
+ [0x241F] = 0x6715, --(朕)
+ [0x2420] = 0x6C88, --(沈)
+ [0x2421] = 0x73CD, --(ç)
+ [0x2422] = 0x8CC3, --(賃)
+ [0x2423] = 0x93AE, --(鎮)
+ [0x2424] = 0x9673, --(陳)
+ [0x2425] = 0x6D25, --(æ´¥)
+ [0x2426] = 0x589C, --(墜)
+ [0x2427] = 0x690E, --(椎)
+ [0x2428] = 0x69CC, --(槌)
+ [0x2429] = 0x8FFD, --(追)
+ [0x242A] = 0x939A, --(鎚)
+ [0x242B] = 0x75DB, --(ç—›)
+ [0x242C] = 0x901A, --(通)
+ [0x242D] = 0x585A, --(å¡š)
+ [0x242E] = 0x6802, --(æ ‚)
+ [0x242F] = 0x63B4, --(掴)
+ [0x2430] = 0x69FB, --(槻)
+ [0x2431] = 0x4F43, --(佃)
+ [0x2432] = 0x6F2C, --(漬)
+ [0x2433] = 0x67D8, --(柘)
+ [0x2434] = 0x8FBB, --(è¾»)
+ [0x2435] = 0x8526, --(蔦)
+ [0x2436] = 0x7DB4, --(綴)
+ [0x2437] = 0x9354, --(é”)
+ [0x2438] = 0x693F, --(椿)
+ [0x2439] = 0x6F70, --(æ½°)
+ [0x243A] = 0x576A, --(åª)
+ [0x243B] = 0x58F7, --(壷)
+ [0x243C] = 0x5B2C, --(嬬)
+ [0x243D] = 0x7D2C, --(ç´¬)
+ [0x243E] = 0x722A, --(爪)
+ [0x243F] = 0x540A, --(åŠ)
+ [0x2440] = 0x91E3, --(釣)
+ [0x2441] = 0x9DB4, --(鶴)
+ [0x2442] = 0x4EAD, --(亭)
+ [0x2443] = 0x4F4E, --(低)
+ [0x2444] = 0x505C, --(åœ)
+ [0x2445] = 0x5075, --(åµ)
+ [0x2446] = 0x5243, --(剃)
+ [0x2447] = 0x8C9E, --(貞)
+ [0x2448] = 0x5448, --(呈)
+ [0x2449] = 0x5824, --(å ¤)
+ [0x244A] = 0x5B9A, --(定)
+ [0x244B] = 0x5E1D, --(å¸)
+ [0x244C] = 0x5E95, --(底)
+ [0x244D] = 0x5EAD, --(庭)
+ [0x244E] = 0x5EF7, --(å»·)
+ [0x244F] = 0x5F1F, --(弟)
+ [0x2450] = 0x608C, --(悌)
+ [0x2451] = 0x62B5, --(抵)
+ [0x2452] = 0x633A, --(挺)
+ [0x2453] = 0x63D0, --(æ)
+ [0x2454] = 0x68AF, --(梯)
+ [0x2455] = 0x6C40, --(æ±€)
+ [0x2456] = 0x7887, --(碇)
+ [0x2457] = 0x798E, --(禎)
+ [0x2458] = 0x7A0B, --(程)
+ [0x2459] = 0x7DE0, --(ç· )
+ [0x245A] = 0x8247, --(艇)
+ [0x245B] = 0x8A02, --(訂)
+ [0x245C] = 0x8AE6, --(諦)
+ [0x245D] = 0x8E44, --(蹄)
+ [0x245E] = 0x9013, --(逓)
+ [0x2501] = 0x90B8, --(邸)
+ [0x2502] = 0x912D, --(é„­)
+ [0x2503] = 0x91D8, --(釘)
+ [0x2504] = 0x9F0E, --(鼎)
+ [0x2505] = 0x6CE5, --(æ³¥)
+ [0x2506] = 0x6458, --(摘)
+ [0x2507] = 0x64E2, --(æ“¢)
+ [0x2508] = 0x6575, --(敵)
+ [0x2509] = 0x6EF4, --(æ»´)
+ [0x250A] = 0x7684, --(çš„)
+ [0x250B] = 0x7B1B, --(笛)
+ [0x250C] = 0x9069, --(é©)
+ [0x250D] = 0x93D1, --(é‘)
+ [0x250E] = 0x6EBA, --(溺)
+ [0x250F] = 0x54F2, --(哲)
+ [0x2510] = 0x5FB9, --(å¾¹)
+ [0x2511] = 0x64A4, --(æ’¤)
+ [0x2512] = 0x8F4D, --(è½)
+ [0x2513] = 0x8FED, --(è¿­)
+ [0x2514] = 0x9244, --(鉄)
+ [0x2515] = 0x5178, --(å…¸)
+ [0x2516] = 0x586B, --(å¡«)
+ [0x2517] = 0x5929, --(天)
+ [0x2518] = 0x5C55, --(展)
+ [0x2519] = 0x5E97, --(店)
+ [0x251A] = 0x6DFB, --(æ·»)
+ [0x251B] = 0x7E8F, --(çº)
+ [0x251C] = 0x751C, --(甜)
+ [0x251D] = 0x8CBC, --(è²¼)
+ [0x251E] = 0x8EE2, --(転)
+ [0x251F] = 0x985B, --(é¡›)
+ [0x2520] = 0x70B9, --(点)
+ [0x2521] = 0x4F1D, --(ä¼)
+ [0x2522] = 0x6BBF, --(殿)
+ [0x2523] = 0x6FB1, --(æ¾±)
+ [0x2524] = 0x7530, --(ç”°)
+ [0x2525] = 0x96FB, --(é›»)
+ [0x2526] = 0x514E, --(å…Ž)
+ [0x2527] = 0x5410, --(å)
+ [0x2528] = 0x5835, --(å µ)
+ [0x2529] = 0x5857, --(å¡—)
+ [0x252A] = 0x59AC, --(妬)
+ [0x252B] = 0x5C60, --(å± )
+ [0x252C] = 0x5F92, --(å¾’)
+ [0x252D] = 0x6597, --(æ–—)
+ [0x252E] = 0x675C, --(æœ)
+ [0x252F] = 0x6E21, --(渡)
+ [0x2530] = 0x767B, --(ç™»)
+ [0x2531] = 0x83DF, --(èŸ)
+ [0x2532] = 0x8CED, --(è³­)
+ [0x2533] = 0x9014, --(途)
+ [0x2534] = 0x90FD, --(都)
+ [0x2535] = 0x934D, --(é)
+ [0x2536] = 0x7825, --(ç ¥)
+ [0x2537] = 0x783A, --(ç º)
+ [0x2538] = 0x52AA, --(努)
+ [0x2539] = 0x5EA6, --(度)
+ [0x253A] = 0x571F, --(土)
+ [0x253B] = 0x5974, --(奴)
+ [0x253C] = 0x6012, --(怒)
+ [0x253D] = 0x5012, --(倒)
+ [0x253E] = 0x515A, --(å…š)
+ [0x253F] = 0x51AC, --(冬)
+ [0x2540] = 0x51CD, --(å‡)
+ [0x2541] = 0x5200, --(刀)
+ [0x2542] = 0x5510, --(å”)
+ [0x2543] = 0x5854, --(å¡”)
+ [0x2544] = 0x5858, --(塘)
+ [0x2545] = 0x5957, --(套)
+ [0x2546] = 0x5B95, --(宕)
+ [0x2547] = 0x5CF6, --(島)
+ [0x2548] = 0x5D8B, --(嶋)
+ [0x2549] = 0x60BC, --(悼)
+ [0x254A] = 0x6295, --(投)
+ [0x254B] = 0x642D, --(æ­)
+ [0x254C] = 0x6771, --(æ±)
+ [0x254D] = 0x6843, --(桃)
+ [0x254E] = 0x68BC, --(梼)
+ [0x254F] = 0x68DF, --(棟)
+ [0x2550] = 0x76D7, --(ç›—)
+ [0x2551] = 0x6DD8, --(æ·˜)
+ [0x2552] = 0x6E6F, --(湯)
+ [0x2553] = 0x6D9B, --(涛)
+ [0x2554] = 0x706F, --(ç¯)
+ [0x2555] = 0x71C8, --(燈)
+ [0x2556] = 0x5F53, --(当)
+ [0x2557] = 0x75D8, --(ç—˜)
+ [0x2558] = 0x7977, --(祷)
+ [0x2559] = 0x7B49, --(ç­‰)
+ [0x255A] = 0x7B54, --(ç­”)
+ [0x255B] = 0x7B52, --(ç­’)
+ [0x255C] = 0x7CD6, --(ç³–)
+ [0x255D] = 0x7D71, --(çµ±)
+ [0x255E] = 0x5230, --(到)
+ [0x2601] = 0x8463, --(è‘£)
+ [0x2602] = 0x8569, --(è•©)
+ [0x2603] = 0x85E4, --(è—¤)
+ [0x2604] = 0x8A0E, --(討)
+ [0x2605] = 0x8B04, --(謄)
+ [0x2606] = 0x8C46, --(豆)
+ [0x2607] = 0x8E0F, --(è¸)
+ [0x2608] = 0x9003, --(逃)
+ [0x2609] = 0x900F, --(é€)
+ [0x260A] = 0x9419, --(é™)
+ [0x260B] = 0x9676, --(陶)
+ [0x260C] = 0x982D, --(é ­)
+ [0x260D] = 0x9A30, --(騰)
+ [0x260E] = 0x95D8, --(é—˜)
+ [0x260F] = 0x50CD, --(åƒ)
+ [0x2610] = 0x52D5, --(å‹•)
+ [0x2611] = 0x540C, --(åŒ)
+ [0x2612] = 0x5802, --(å ‚)
+ [0x2613] = 0x5C0E, --(å°Ž)
+ [0x2614] = 0x61A7, --(憧)
+ [0x2615] = 0x649E, --(æ’ž)
+ [0x2616] = 0x6D1E, --(æ´ž)
+ [0x2617] = 0x77B3, --(çž³)
+ [0x2618] = 0x7AE5, --(ç«¥)
+ [0x2619] = 0x80F4, --(胴)
+ [0x261A] = 0x8404, --(è„)
+ [0x261B] = 0x9053, --(é“)
+ [0x261C] = 0x9285, --(銅)
+ [0x261D] = 0x5CE0, --(å³ )
+ [0x261E] = 0x9D07, --(é´‡)
+ [0x261F] = 0x533F, --(匿)
+ [0x2620] = 0x5F97, --(å¾—)
+ [0x2621] = 0x5FB3, --(å¾³)
+ [0x2622] = 0x6D9C, --(涜)
+ [0x2623] = 0x7279, --(特)
+ [0x2624] = 0x7763, --(ç£)
+ [0x2625] = 0x79BF, --(禿)
+ [0x2626] = 0x7BE4, --(篤)
+ [0x2627] = 0x6BD2, --(毒)
+ [0x2628] = 0x72EC, --(独)
+ [0x2629] = 0x8AAD, --(読)
+ [0x262A] = 0x6803, --(æ ƒ)
+ [0x262B] = 0x6A61, --(æ©¡)
+ [0x262C] = 0x51F8, --(凸)
+ [0x262D] = 0x7A81, --(çª)
+ [0x262E] = 0x6934, --(椴)
+ [0x262F] = 0x5C4A, --(届)
+ [0x2630] = 0x9CF6, --(鳶)
+ [0x2631] = 0x82EB, --(è‹«)
+ [0x2632] = 0x5BC5, --(寅)
+ [0x2633] = 0x9149, --(é…‰)
+ [0x2634] = 0x701E, --(瀞)
+ [0x2635] = 0x5678, --(噸)
+ [0x2636] = 0x5C6F, --(屯)
+ [0x2637] = 0x60C7, --(惇)
+ [0x2638] = 0x6566, --(敦)
+ [0x2639] = 0x6C8C, --(沌)
+ [0x263A] = 0x8C5A, --(豚)
+ [0x263B] = 0x9041, --(é)
+ [0x263C] = 0x9813, --(é “)
+ [0x263D] = 0x5451, --(å‘‘)
+ [0x263E] = 0x66C7, --(曇)
+ [0x263F] = 0x920D, --(éˆ)
+ [0x2640] = 0x5948, --(奈)
+ [0x2641] = 0x90A3, --(é‚£)
+ [0x2642] = 0x5185, --(内)
+ [0x2643] = 0x4E4D, --(ä¹)
+ [0x2644] = 0x51EA, --(凪)
+ [0x2645] = 0x8599, --(è–™)
+ [0x2646] = 0x8B0E, --(謎)
+ [0x2647] = 0x7058, --(ç˜)
+ [0x2648] = 0x637A, --(æº)
+ [0x2649] = 0x934B, --(é‹)
+ [0x264A] = 0x6962, --(楢)
+ [0x264B] = 0x99B4, --(馴)
+ [0x264C] = 0x7E04, --(縄)
+ [0x264D] = 0x7577, --(ç•·)
+ [0x264E] = 0x5357, --(å—)
+ [0x264F] = 0x6960, --(楠)
+ [0x2650] = 0x8EDF, --(軟)
+ [0x2651] = 0x96E3, --(難)
+ [0x2652] = 0x6C5D, --(æ±)
+ [0x2653] = 0x4E8C, --(二)
+ [0x2654] = 0x5C3C, --(å°¼)
+ [0x2655] = 0x5F10, --(å¼)
+ [0x2656] = 0x8FE9, --(è¿©)
+ [0x2657] = 0x5302, --(匂)
+ [0x2658] = 0x8CD1, --(賑)
+ [0x2659] = 0x8089, --(肉)
+ [0x265A] = 0x8679, --(虹)
+ [0x265B] = 0x5EFF, --(廿)
+ [0x265C] = 0x65E5, --(æ—¥)
+ [0x265D] = 0x4E73, --(ä¹³)
+ [0x265E] = 0x5165, --(å…¥)
+ [0x2701] = 0x5982, --(如)
+ [0x2702] = 0x5C3F, --(å°¿)
+ [0x2703] = 0x97EE, --(韮)
+ [0x2704] = 0x4EFB, --(ä»»)
+ [0x2705] = 0x598A, --(妊)
+ [0x2706] = 0x5FCD, --(å¿)
+ [0x2707] = 0x8A8D, --(èª)
+ [0x2708] = 0x6FE1, --(æ¿¡)
+ [0x2709] = 0x79B0, --(禰)
+ [0x270A] = 0x7962, --(祢)
+ [0x270B] = 0x5BE7, --(寧)
+ [0x270C] = 0x8471, --(葱)
+ [0x270D] = 0x732B, --(猫)
+ [0x270E] = 0x71B1, --(熱)
+ [0x270F] = 0x5E74, --(å¹´)
+ [0x2710] = 0x5FF5, --(念)
+ [0x2711] = 0x637B, --(æ»)
+ [0x2712] = 0x649A, --(æ’š)
+ [0x2713] = 0x71C3, --(燃)
+ [0x2714] = 0x7C98, --(粘)
+ [0x2715] = 0x4E43, --(乃)
+ [0x2716] = 0x5EFC, --(廼)
+ [0x2717] = 0x4E4B, --(之)
+ [0x2718] = 0x57DC, --(埜)
+ [0x2719] = 0x56A2, --(嚢)
+ [0x271A] = 0x60A9, --(æ‚©)
+ [0x271B] = 0x6FC3, --(濃)
+ [0x271C] = 0x7D0D, --(ç´)
+ [0x271D] = 0x80FD, --(能)
+ [0x271E] = 0x8133, --(脳)
+ [0x271F] = 0x81BF, --(膿)
+ [0x2720] = 0x8FB2, --(è¾²)
+ [0x2721] = 0x8997, --(覗)
+ [0x2722] = 0x86A4, --(蚤)
+ [0x2723] = 0x5DF4, --(å·´)
+ [0x2724] = 0x628A, --(把)
+ [0x2725] = 0x64AD, --(æ’­)
+ [0x2726] = 0x8987, --(覇)
+ [0x2727] = 0x6777, --(æ·)
+ [0x2728] = 0x6CE2, --(æ³¢)
+ [0x2729] = 0x6D3E, --(æ´¾)
+ [0x272A] = 0x7436, --(ç¶)
+ [0x272B] = 0x7834, --(ç ´)
+ [0x272C] = 0x5A46, --(婆)
+ [0x272D] = 0x7F75, --(ç½µ)
+ [0x272E] = 0x82AD, --(芭)
+ [0x272F] = 0x99AC, --(馬)
+ [0x2730] = 0x4FF3, --(俳)
+ [0x2731] = 0x5EC3, --(廃)
+ [0x2732] = 0x62DD, --(æ‹)
+ [0x2733] = 0x6392, --(排)
+ [0x2734] = 0x6557, --(æ•—)
+ [0x2735] = 0x676F, --(æ¯)
+ [0x2736] = 0x76C3, --(盃)
+ [0x2737] = 0x724C, --(牌)
+ [0x2738] = 0x80CC, --(背)
+ [0x2739] = 0x80BA, --(肺)
+ [0x273A] = 0x8F29, --(輩)
+ [0x273B] = 0x914D, --(é…)
+ [0x273C] = 0x500D, --(å€)
+ [0x273D] = 0x57F9, --(培)
+ [0x273E] = 0x5A92, --(媒)
+ [0x273F] = 0x6885, --(梅)
+ [0x2740] = 0x6973, --(楳)
+ [0x2741] = 0x7164, --(ç…¤)
+ [0x2742] = 0x72FD, --(狽)
+ [0x2743] = 0x8CB7, --(è²·)
+ [0x2744] = 0x58F2, --(売)
+ [0x2745] = 0x8CE0, --(è³ )
+ [0x2746] = 0x966A, --(陪)
+ [0x2747] = 0x9019, --(這)
+ [0x2748] = 0x877F, --(è¿)
+ [0x2749] = 0x79E4, --(秤)
+ [0x274A] = 0x77E7, --(矧)
+ [0x274B] = 0x8429, --(è©)
+ [0x274C] = 0x4F2F, --(伯)
+ [0x274D] = 0x5265, --(剥)
+ [0x274E] = 0x535A, --(åš)
+ [0x274F] = 0x62CD, --(æ‹)
+ [0x2750] = 0x67CF, --(æŸ)
+ [0x2751] = 0x6CCA, --(泊)
+ [0x2752] = 0x767D, --(白)
+ [0x2753] = 0x7B94, --(ç®”)
+ [0x2754] = 0x7C95, --(粕)
+ [0x2755] = 0x8236, --(舶)
+ [0x2756] = 0x8584, --(è–„)
+ [0x2757] = 0x8FEB, --(è¿«)
+ [0x2758] = 0x66DD, --(æ›)
+ [0x2759] = 0x6F20, --(æ¼ )
+ [0x275A] = 0x7206, --(爆)
+ [0x275B] = 0x7E1B, --(縛)
+ [0x275C] = 0x83AB, --(莫)
+ [0x275D] = 0x99C1, --(é§)
+ [0x275E] = 0x9EA6, --(麦)
+ [0x2801] = 0x51FD, --(函)
+ [0x2802] = 0x7BB1, --(ç®±)
+ [0x2803] = 0x7872, --(硲)
+ [0x2804] = 0x7BB8, --(箸)
+ [0x2805] = 0x8087, --(肇)
+ [0x2806] = 0x7B48, --(ç­ˆ)
+ [0x2807] = 0x6AE8, --(櫨)
+ [0x2808] = 0x5E61, --(幡)
+ [0x2809] = 0x808C, --(肌)
+ [0x280A] = 0x7551, --(ç•‘)
+ [0x280B] = 0x7560, --(ç• )
+ [0x280C] = 0x516B, --(å…«)
+ [0x280D] = 0x9262, --(鉢)
+ [0x280E] = 0x6E8C, --(溌)
+ [0x280F] = 0x767A, --(発)
+ [0x2810] = 0x9197, --(醗)
+ [0x2811] = 0x9AEA, --(髪)
+ [0x2812] = 0x4F10, --(ä¼)
+ [0x2813] = 0x7F70, --(ç½°)
+ [0x2814] = 0x629C, --(抜)
+ [0x2815] = 0x7B4F, --(ç­)
+ [0x2816] = 0x95A5, --(é–¥)
+ [0x2817] = 0x9CE9, --(鳩)
+ [0x2818] = 0x567A, --(噺)
+ [0x2819] = 0x5859, --(å¡™)
+ [0x281A] = 0x86E4, --(蛤)
+ [0x281B] = 0x96BC, --(éš¼)
+ [0x281C] = 0x4F34, --(ä¼´)
+ [0x281D] = 0x5224, --(判)
+ [0x281E] = 0x534A, --(åŠ)
+ [0x281F] = 0x53CD, --(å)
+ [0x2820] = 0x53DB, --(å›)
+ [0x2821] = 0x5E06, --(帆)
+ [0x2822] = 0x642C, --(æ¬)
+ [0x2823] = 0x6591, --(æ–‘)
+ [0x2824] = 0x677F, --(æ¿)
+ [0x2825] = 0x6C3E, --(æ°¾)
+ [0x2826] = 0x6C4E, --(汎)
+ [0x2827] = 0x7248, --(版)
+ [0x2828] = 0x72AF, --(犯)
+ [0x2829] = 0x73ED, --(ç­)
+ [0x282A] = 0x7554, --(ç•”)
+ [0x282B] = 0x7E41, --(ç¹)
+ [0x282C] = 0x822C, --(般)
+ [0x282D] = 0x85E9, --(è—©)
+ [0x282E] = 0x8CA9, --(販)
+ [0x282F] = 0x7BC4, --(範)
+ [0x2830] = 0x91C6, --(釆)
+ [0x2831] = 0x7169, --(ç…©)
+ [0x2832] = 0x9812, --(é ’)
+ [0x2833] = 0x98EF, --(飯)
+ [0x2834] = 0x633D, --(挽)
+ [0x2835] = 0x6669, --(晩)
+ [0x2836] = 0x756A, --(番)
+ [0x2837] = 0x76E4, --(盤)
+ [0x2838] = 0x78D0, --(ç£)
+ [0x2839] = 0x8543, --(蕃)
+ [0x283A] = 0x86EE, --(è›®)
+ [0x283B] = 0x532A, --(匪)
+ [0x283C] = 0x5351, --(å‘)
+ [0x283D] = 0x5426, --(å¦)
+ [0x283E] = 0x5983, --(妃)
+ [0x283F] = 0x5E87, --(庇)
+ [0x2840] = 0x5F7C, --(å½¼)
+ [0x2841] = 0x60B2, --(悲)
+ [0x2842] = 0x6249, --(扉)
+ [0x2843] = 0x6279, --(批)
+ [0x2844] = 0x62AB, --(披)
+ [0x2845] = 0x6590, --(æ–)
+ [0x2846] = 0x6BD4, --(比)
+ [0x2847] = 0x6CCC, --(泌)
+ [0x2848] = 0x75B2, --(ç–²)
+ [0x2849] = 0x76AE, --(çš®)
+ [0x284A] = 0x7891, --(碑)
+ [0x284B] = 0x79D8, --(秘)
+ [0x284C] = 0x7DCB, --(ç·‹)
+ [0x284D] = 0x7F77, --(ç½·)
+ [0x284E] = 0x80A5, --(è‚¥)
+ [0x284F] = 0x88AB, --(被)
+ [0x2850] = 0x8AB9, --(誹)
+ [0x2851] = 0x8CBB, --(è²»)
+ [0x2852] = 0x907F, --(é¿)
+ [0x2853] = 0x975E, --(éž)
+ [0x2854] = 0x98DB, --(飛)
+ [0x2855] = 0x6A0B, --(樋)
+ [0x2856] = 0x7C38, --(ç°¸)
+ [0x2857] = 0x5099, --(å‚™)
+ [0x2858] = 0x5C3E, --(å°¾)
+ [0x2859] = 0x5FAE, --(å¾®)
+ [0x285A] = 0x6787, --(枇)
+ [0x285B] = 0x6BD8, --(毘)
+ [0x285C] = 0x7435, --(çµ)
+ [0x285D] = 0x7709, --(眉)
+ [0x285E] = 0x7F8E, --(美)
+ [0x2901] = 0x9F3B, --(é¼»)
+ [0x2902] = 0x67CA, --(柊)
+ [0x2903] = 0x7A17, --(稗)
+ [0x2904] = 0x5339, --(匹)
+ [0x2905] = 0x758B, --(ç–‹)
+ [0x2906] = 0x9AED, --(é«­)
+ [0x2907] = 0x5F66, --(彦)
+ [0x2908] = 0x819D, --(è†)
+ [0x2909] = 0x83F1, --(è±)
+ [0x290A] = 0x8098, --(肘)
+ [0x290B] = 0x5F3C, --(å¼¼)
+ [0x290C] = 0x5FC5, --(å¿…)
+ [0x290D] = 0x7562, --(ç•¢)
+ [0x290E] = 0x7B46, --(ç­†)
+ [0x290F] = 0x903C, --(逼)
+ [0x2910] = 0x6867, --(桧)
+ [0x2911] = 0x59EB, --(姫)
+ [0x2912] = 0x5A9B, --(媛)
+ [0x2913] = 0x7D10, --(ç´)
+ [0x2914] = 0x767E, --(百)
+ [0x2915] = 0x8B2C, --(謬)
+ [0x2916] = 0x4FF5, --(俵)
+ [0x2917] = 0x5F6A, --(彪)
+ [0x2918] = 0x6A19, --(標)
+ [0x2919] = 0x6C37, --(æ°·)
+ [0x291A] = 0x6F02, --(漂)
+ [0x291B] = 0x74E2, --(ç“¢)
+ [0x291C] = 0x7968, --(票)
+ [0x291D] = 0x8868, --(表)
+ [0x291E] = 0x8A55, --(è©•)
+ [0x291F] = 0x8C79, --(è±¹)
+ [0x2920] = 0x5EDF, --(廟)
+ [0x2921] = 0x63CF, --(æ)
+ [0x2922] = 0x75C5, --(ç—…)
+ [0x2923] = 0x79D2, --(秒)
+ [0x2924] = 0x82D7, --(è‹—)
+ [0x2925] = 0x9328, --(錨)
+ [0x2926] = 0x92F2, --(鋲)
+ [0x2927] = 0x849C, --(蒜)
+ [0x2928] = 0x86ED, --(è›­)
+ [0x2929] = 0x9C2D, --(é°­)
+ [0x292A] = 0x54C1, --(å“)
+ [0x292B] = 0x5F6C, --(彬)
+ [0x292C] = 0x658C, --(斌)
+ [0x292D] = 0x6D5C, --(浜)
+ [0x292E] = 0x7015, --(瀕)
+ [0x292F] = 0x8CA7, --(貧)
+ [0x2930] = 0x8CD3, --(賓)
+ [0x2931] = 0x983B, --(é »)
+ [0x2932] = 0x654F, --(æ•)
+ [0x2933] = 0x74F6, --(瓶)
+ [0x2934] = 0x4E0D, --(ä¸)
+ [0x2935] = 0x4ED8, --(付)
+ [0x2936] = 0x57E0, --(埠)
+ [0x2937] = 0x592B, --(夫)
+ [0x2938] = 0x5A66, --(婦)
+ [0x2939] = 0x5BCC, --(富)
+ [0x293A] = 0x51A8, --(冨)
+ [0x293B] = 0x5E03, --(布)
+ [0x293C] = 0x5E9C, --(府)
+ [0x293D] = 0x6016, --(怖)
+ [0x293E] = 0x6276, --(扶)
+ [0x293F] = 0x6577, --(æ•·)
+ [0x2940] = 0x65A7, --(æ–§)
+ [0x2941] = 0x666E, --(æ™®)
+ [0x2942] = 0x6D6E, --(æµ®)
+ [0x2943] = 0x7236, --(父)
+ [0x2944] = 0x7B26, --(符)
+ [0x2945] = 0x8150, --(è…)
+ [0x2946] = 0x819A, --(膚)
+ [0x2947] = 0x8299, --(芙)
+ [0x2948] = 0x8B5C, --(譜)
+ [0x2949] = 0x8CA0, --(è² )
+ [0x294A] = 0x8CE6, --(賦)
+ [0x294B] = 0x8D74, --(èµ´)
+ [0x294C] = 0x961C, --(阜)
+ [0x294D] = 0x9644, --(附)
+ [0x294E] = 0x4FAE, --(ä¾®)
+ [0x294F] = 0x64AB, --(æ’«)
+ [0x2950] = 0x6B66, --(æ­¦)
+ [0x2951] = 0x821E, --(舞)
+ [0x2952] = 0x8461, --(è‘¡)
+ [0x2953] = 0x856A, --(蕪)
+ [0x2954] = 0x90E8, --(部)
+ [0x2955] = 0x5C01, --(å°)
+ [0x2956] = 0x6953, --(楓)
+ [0x2957] = 0x98A8, --(風)
+ [0x2958] = 0x847A, --(葺)
+ [0x2959] = 0x8557, --(è•—)
+ [0x295A] = 0x4F0F, --(ä¼)
+ [0x295B] = 0x526F, --(副)
+ [0x295C] = 0x5FA9, --(復)
+ [0x295D] = 0x5E45, --(å¹…)
+ [0x295E] = 0x670D, --(æœ)
+ [0x2A01] = 0x798F, --(ç¦)
+ [0x2A02] = 0x8179, --(è…¹)
+ [0x2A03] = 0x8907, --(複)
+ [0x2A04] = 0x8986, --(覆)
+ [0x2A05] = 0x6DF5, --(æ·µ)
+ [0x2A06] = 0x5F17, --(å¼—)
+ [0x2A07] = 0x6255, --(払)
+ [0x2A08] = 0x6CB8, --(沸)
+ [0x2A09] = 0x4ECF, --(ä»)
+ [0x2A0A] = 0x7269, --(物)
+ [0x2A0B] = 0x9B92, --(é®’)
+ [0x2A0C] = 0x5206, --(分)
+ [0x2A0D] = 0x543B, --(å»)
+ [0x2A0E] = 0x5674, --(å™´)
+ [0x2A0F] = 0x58B3, --(墳)
+ [0x2A10] = 0x61A4, --(憤)
+ [0x2A11] = 0x626E, --(扮)
+ [0x2A12] = 0x711A, --(ç„š)
+ [0x2A13] = 0x596E, --(奮)
+ [0x2A14] = 0x7C89, --(粉)
+ [0x2A15] = 0x7CDE, --(糞)
+ [0x2A16] = 0x7D1B, --(ç´›)
+ [0x2A17] = 0x96F0, --(é›°)
+ [0x2A18] = 0x6587, --(æ–‡)
+ [0x2A19] = 0x805E, --(èž)
+ [0x2A1A] = 0x4E19, --(丙)
+ [0x2A1B] = 0x4F75, --(ä½µ)
+ [0x2A1C] = 0x5175, --(å…µ)
+ [0x2A1D] = 0x5840, --(å¡€)
+ [0x2A1E] = 0x5E63, --(å¹£)
+ [0x2A1F] = 0x5E73, --(å¹³)
+ [0x2A20] = 0x5F0A, --(弊)
+ [0x2A21] = 0x67C4, --(柄)
+ [0x2A22] = 0x4E26, --(並)
+ [0x2A23] = 0x853D, --(蔽)
+ [0x2A24] = 0x9589, --(é–‰)
+ [0x2A25] = 0x965B, --(é™›)
+ [0x2A26] = 0x7C73, --(ç±³)
+ [0x2A27] = 0x9801, --(é )
+ [0x2A28] = 0x50FB, --(僻)
+ [0x2A29] = 0x58C1, --(å£)
+ [0x2A2A] = 0x7656, --(ç™–)
+ [0x2A2B] = 0x78A7, --(碧)
+ [0x2A2C] = 0x5225, --(別)
+ [0x2A2D] = 0x77A5, --(瞥)
+ [0x2A2E] = 0x8511, --(蔑)
+ [0x2A2F] = 0x7B86, --(箆)
+ [0x2A30] = 0x504F, --(å)
+ [0x2A31] = 0x5909, --(変)
+ [0x2A32] = 0x7247, --(片)
+ [0x2A33] = 0x7BC7, --(篇)
+ [0x2A34] = 0x7DE8, --(ç·¨)
+ [0x2A35] = 0x8FBA, --(辺)
+ [0x2A36] = 0x8FD4, --(è¿”)
+ [0x2A37] = 0x904D, --(é)
+ [0x2A38] = 0x4FBF, --(便)
+ [0x2A39] = 0x52C9, --(勉)
+ [0x2A3A] = 0x5A29, --(娩)
+ [0x2A3B] = 0x5F01, --(å¼)
+ [0x2A3C] = 0x97AD, --(éž­)
+ [0x2A3D] = 0x4FDD, --(ä¿)
+ [0x2A3E] = 0x8217, --(舗)
+ [0x2A3F] = 0x92EA, --(鋪)
+ [0x2A40] = 0x5703, --(圃)
+ [0x2A41] = 0x6355, --(æ•)
+ [0x2A42] = 0x6B69, --(æ­©)
+ [0x2A43] = 0x752B, --(甫)
+ [0x2A44] = 0x88DC, --(補)
+ [0x2A45] = 0x8F14, --(è¼”)
+ [0x2A46] = 0x7A42, --(ç©‚)
+ [0x2A47] = 0x52DF, --(å‹Ÿ)
+ [0x2A48] = 0x5893, --(墓)
+ [0x2A49] = 0x6155, --(æ…•)
+ [0x2A4A] = 0x620A, --(戊)
+ [0x2A4B] = 0x66AE, --(æš®)
+ [0x2A4C] = 0x6BCD, --(æ¯)
+ [0x2A4D] = 0x7C3F, --(ç°¿)
+ [0x2A4E] = 0x83E9, --(è©)
+ [0x2A4F] = 0x5023, --(倣)
+ [0x2A50] = 0x4FF8, --(俸)
+ [0x2A51] = 0x5305, --(包)
+ [0x2A52] = 0x5446, --(呆)
+ [0x2A53] = 0x5831, --(å ±)
+ [0x2A54] = 0x5949, --(奉)
+ [0x2A55] = 0x5B9D, --(å®)
+ [0x2A56] = 0x5CF0, --(å³°)
+ [0x2A57] = 0x5CEF, --(峯)
+ [0x2A58] = 0x5D29, --(å´©)
+ [0x2A59] = 0x5E96, --(庖)
+ [0x2A5A] = 0x62B1, --(抱)
+ [0x2A5B] = 0x6367, --(æ§)
+ [0x2A5C] = 0x653E, --(放)
+ [0x2A5D] = 0x65B9, --(æ–¹)
+ [0x2A5E] = 0x670B, --(朋)
+ [0x2B01] = 0x6CD5, --(法)
+ [0x2B02] = 0x6CE1, --(泡)
+ [0x2B03] = 0x70F9, --(烹)
+ [0x2B04] = 0x7832, --(ç ²)
+ [0x2B05] = 0x7E2B, --(縫)
+ [0x2B06] = 0x80DE, --(胞)
+ [0x2B07] = 0x82B3, --(芳)
+ [0x2B08] = 0x840C, --(èŒ)
+ [0x2B09] = 0x84EC, --(蓬)
+ [0x2B0A] = 0x8702, --(蜂)
+ [0x2B0B] = 0x8912, --(褒)
+ [0x2B0C] = 0x8A2A, --(訪)
+ [0x2B0D] = 0x8C4A, --(豊)
+ [0x2B0E] = 0x90A6, --(邦)
+ [0x2B0F] = 0x92D2, --(é‹’)
+ [0x2B10] = 0x98FD, --(飽)
+ [0x2B11] = 0x9CF3, --(é³³)
+ [0x2B12] = 0x9D6C, --(鵬)
+ [0x2B13] = 0x4E4F, --(ä¹)
+ [0x2B14] = 0x4EA1, --(亡)
+ [0x2B15] = 0x508D, --(å‚)
+ [0x2B16] = 0x5256, --(剖)
+ [0x2B17] = 0x574A, --(åŠ)
+ [0x2B18] = 0x59A8, --(妨)
+ [0x2B19] = 0x5E3D, --(帽)
+ [0x2B1A] = 0x5FD8, --(忘)
+ [0x2B1B] = 0x5FD9, --(å¿™)
+ [0x2B1C] = 0x623F, --(房)
+ [0x2B1D] = 0x66B4, --(æš´)
+ [0x2B1E] = 0x671B, --(望)
+ [0x2B1F] = 0x67D0, --(æŸ)
+ [0x2B20] = 0x68D2, --(棒)
+ [0x2B21] = 0x5192, --(冒)
+ [0x2B22] = 0x7D21, --(ç´¡)
+ [0x2B23] = 0x80AA, --(肪)
+ [0x2B24] = 0x81A8, --(膨)
+ [0x2B25] = 0x8B00, --(謀)
+ [0x2B26] = 0x8C8C, --(貌)
+ [0x2B27] = 0x8CBF, --(貿)
+ [0x2B28] = 0x927E, --(鉾)
+ [0x2B29] = 0x9632, --(防)
+ [0x2B2A] = 0x5420, --(å )
+ [0x2B2B] = 0x982C, --(é ¬)
+ [0x2B2C] = 0x5317, --(北)
+ [0x2B2D] = 0x50D5, --(僕)
+ [0x2B2E] = 0x535C, --(åœ)
+ [0x2B2F] = 0x58A8, --(墨)
+ [0x2B30] = 0x64B2, --(æ’²)
+ [0x2B31] = 0x6734, --(朴)
+ [0x2B32] = 0x7267, --(牧)
+ [0x2B33] = 0x7766, --(ç¦)
+ [0x2B34] = 0x7A46, --(穆)
+ [0x2B35] = 0x91E6, --(釦)
+ [0x2B36] = 0x52C3, --(勃)
+ [0x2B37] = 0x6CA1, --(没)
+ [0x2B38] = 0x6B86, --(殆)
+ [0x2B39] = 0x5800, --(å €)
+ [0x2B3A] = 0x5E4C, --(幌)
+ [0x2B3B] = 0x5954, --(奔)
+ [0x2B3C] = 0x672C, --(本)
+ [0x2B3D] = 0x7FFB, --(ç¿»)
+ [0x2B3E] = 0x51E1, --(凡)
+ [0x2B3F] = 0x76C6, --(盆)
+ [0x2B40] = 0x6469, --(æ‘©)
+ [0x2B41] = 0x78E8, --(磨)
+ [0x2B42] = 0x9B54, --(é­”)
+ [0x2B43] = 0x9EBB, --(麻)
+ [0x2B44] = 0x57CB, --(埋)
+ [0x2B45] = 0x59B9, --(妹)
+ [0x2B46] = 0x6627, --(昧)
+ [0x2B47] = 0x679A, --(æžš)
+ [0x2B48] = 0x6BCE, --(毎)
+ [0x2B49] = 0x54E9, --(å“©)
+ [0x2B4A] = 0x69D9, --(槙)
+ [0x2B4B] = 0x5E55, --(幕)
+ [0x2B4C] = 0x819C, --(膜)
+ [0x2B4D] = 0x6795, --(æž•)
+ [0x2B4E] = 0x9BAA, --(鮪)
+ [0x2B4F] = 0x67FE, --(柾)
+ [0x2B50] = 0x9C52, --(é±’)
+ [0x2B51] = 0x685D, --(æ¡)
+ [0x2B52] = 0x4EA6, --(亦)
+ [0x2B53] = 0x4FE3, --(ä¿£)
+ [0x2B54] = 0x53C8, --(åˆ)
+ [0x2B55] = 0x62B9, --(抹)
+ [0x2B56] = 0x672B, --(末)
+ [0x2B57] = 0x6CAB, --(沫)
+ [0x2B58] = 0x8FC4, --(è¿„)
+ [0x2B59] = 0x4FAD, --(ä¾­)
+ [0x2B5A] = 0x7E6D, --(ç¹­)
+ [0x2B5B] = 0x9EBF, --(麿)
+ [0x2B5C] = 0x4E07, --(万)
+ [0x2B5D] = 0x6162, --(æ…¢)
+ [0x2B5E] = 0x6E80, --(満)
+ [0x2C01] = 0x6F2B, --(漫)
+ [0x2C02] = 0x8513, --(蔓)
+ [0x2C03] = 0x5473, --(味)
+ [0x2C04] = 0x672A, --(未)
+ [0x2C05] = 0x9B45, --(é­…)
+ [0x2C06] = 0x5DF3, --(å·³)
+ [0x2C07] = 0x7B95, --(箕)
+ [0x2C08] = 0x5CAC, --(岬)
+ [0x2C09] = 0x5BC6, --(密)
+ [0x2C0A] = 0x871C, --(蜜)
+ [0x2C0B] = 0x6E4A, --(湊)
+ [0x2C0C] = 0x84D1, --(è“‘)
+ [0x2C0D] = 0x7A14, --(稔)
+ [0x2C0E] = 0x8108, --(脈)
+ [0x2C0F] = 0x5999, --(妙)
+ [0x2C10] = 0x7C8D, --(ç²)
+ [0x2C11] = 0x6C11, --(æ°‘)
+ [0x2C12] = 0x7720, --(眠)
+ [0x2C13] = 0x52D9, --(å‹™)
+ [0x2C14] = 0x5922, --(夢)
+ [0x2C15] = 0x7121, --(ç„¡)
+ [0x2C16] = 0x725F, --(牟)
+ [0x2C17] = 0x77DB, --(矛)
+ [0x2C18] = 0x9727, --(霧)
+ [0x2C19] = 0x9D61, --(鵡)
+ [0x2C1A] = 0x690B, --(椋)
+ [0x2C1B] = 0x5A7F, --(å©¿)
+ [0x2C1C] = 0x5A18, --(娘)
+ [0x2C1D] = 0x51A5, --(冥)
+ [0x2C1E] = 0x540D, --(å)
+ [0x2C1F] = 0x547D, --(命)
+ [0x2C20] = 0x660E, --(明)
+ [0x2C21] = 0x76DF, --(盟)
+ [0x2C22] = 0x8FF7, --(è¿·)
+ [0x2C23] = 0x9298, --(銘)
+ [0x2C24] = 0x9CF4, --(é³´)
+ [0x2C25] = 0x59EA, --(姪)
+ [0x2C26] = 0x725D, --(ç‰)
+ [0x2C27] = 0x6EC5, --(æ»…)
+ [0x2C28] = 0x514D, --(å…)
+ [0x2C29] = 0x68C9, --(棉)
+ [0x2C2A] = 0x7DBF, --(綿)
+ [0x2C2B] = 0x7DEC, --(ç·¬)
+ [0x2C2C] = 0x9762, --(é¢)
+ [0x2C2D] = 0x9EBA, --(麺)
+ [0x2C2E] = 0x6478, --(摸)
+ [0x2C2F] = 0x6A21, --(模)
+ [0x2C30] = 0x8302, --(茂)
+ [0x2C31] = 0x5984, --(妄)
+ [0x2C32] = 0x5B5F, --(å­Ÿ)
+ [0x2C33] = 0x6BDB, --(毛)
+ [0x2C34] = 0x731B, --(猛)
+ [0x2C35] = 0x76F2, --(盲)
+ [0x2C36] = 0x7DB2, --(網)
+ [0x2C37] = 0x8017, --(耗)
+ [0x2C38] = 0x8499, --(è’™)
+ [0x2C39] = 0x5132, --(儲)
+ [0x2C3A] = 0x6728, --(木)
+ [0x2C3B] = 0x9ED9, --(é»™)
+ [0x2C3C] = 0x76EE, --(ç›®)
+ [0x2C3D] = 0x6762, --(æ¢)
+ [0x2C3E] = 0x52FF, --(å‹¿)
+ [0x2C3F] = 0x9905, --(餅)
+ [0x2C40] = 0x5C24, --(å°¤)
+ [0x2C41] = 0x623B, --(戻)
+ [0x2C42] = 0x7C7E, --(ç±¾)
+ [0x2C43] = 0x8CB0, --(è²°)
+ [0x2C44] = 0x554F, --(å•)
+ [0x2C45] = 0x60B6, --(悶)
+ [0x2C46] = 0x7D0B, --(ç´‹)
+ [0x2C47] = 0x9580, --(é–€)
+ [0x2C48] = 0x5301, --(åŒ)
+ [0x2C49] = 0x4E5F, --(也)
+ [0x2C4A] = 0x51B6, --(冶)
+ [0x2C4B] = 0x591C, --(夜)
+ [0x2C4C] = 0x723A, --(爺)
+ [0x2C4D] = 0x8036, --(耶)
+ [0x2C4E] = 0x91CE, --(野)
+ [0x2C4F] = 0x5F25, --(å¼¥)
+ [0x2C50] = 0x77E2, --(矢)
+ [0x2C51] = 0x5384, --(厄)
+ [0x2C52] = 0x5F79, --(å½¹)
+ [0x2C53] = 0x7D04, --(ç´„)
+ [0x2C54] = 0x85AC, --(è–¬)
+ [0x2C55] = 0x8A33, --(訳)
+ [0x2C56] = 0x8E8D, --(èº)
+ [0x2C57] = 0x9756, --(é–)
+ [0x2C58] = 0x67F3, --(柳)
+ [0x2C59] = 0x85AE, --(è–®)
+ [0x2C5A] = 0x9453, --(é‘“)
+ [0x2C5B] = 0x6109, --(愉)
+ [0x2C5C] = 0x6108, --(愈)
+ [0x2C5D] = 0x6CB9, --(æ²¹)
+ [0x2C5E] = 0x7652, --(ç™’)
+ [0x2D01] = 0x8AED, --(è«­)
+ [0x2D02] = 0x8F38, --(輸)
+ [0x2D03] = 0x552F, --(唯)
+ [0x2D04] = 0x4F51, --(佑)
+ [0x2D05] = 0x512A, --(優)
+ [0x2D06] = 0x52C7, --(勇)
+ [0x2D07] = 0x53CB, --(å‹)
+ [0x2D08] = 0x5BA5, --(宥)
+ [0x2D09] = 0x5E7D, --(å¹½)
+ [0x2D0A] = 0x60A0, --(æ‚ )
+ [0x2D0B] = 0x6182, --(憂)
+ [0x2D0C] = 0x63D6, --(æ–)
+ [0x2D0D] = 0x6709, --(有)
+ [0x2D0E] = 0x67DA, --(柚)
+ [0x2D0F] = 0x6E67, --(湧)
+ [0x2D10] = 0x6D8C, --(涌)
+ [0x2D11] = 0x7336, --(猶)
+ [0x2D12] = 0x7337, --(猷)
+ [0x2D13] = 0x7531, --(ç”±)
+ [0x2D14] = 0x7950, --(ç¥)
+ [0x2D15] = 0x88D5, --(裕)
+ [0x2D16] = 0x8A98, --(誘)
+ [0x2D17] = 0x904A, --(éŠ)
+ [0x2D18] = 0x9091, --(é‚‘)
+ [0x2D19] = 0x90F5, --(郵)
+ [0x2D1A] = 0x96C4, --(雄)
+ [0x2D1B] = 0x878D, --(èž)
+ [0x2D1C] = 0x5915, --(夕)
+ [0x2D1D] = 0x4E88, --(予)
+ [0x2D1E] = 0x4F59, --(ä½™)
+ [0x2D1F] = 0x4E0E, --(与)
+ [0x2D20] = 0x8A89, --(誉)
+ [0x2D21] = 0x8F3F, --(輿)
+ [0x2D22] = 0x9810, --(é )
+ [0x2D23] = 0x50AD, --(å‚­)
+ [0x2D24] = 0x5E7C, --(å¹¼)
+ [0x2D25] = 0x5996, --(妖)
+ [0x2D26] = 0x5BB9, --(容)
+ [0x2D27] = 0x5EB8, --(庸)
+ [0x2D28] = 0x63DA, --(æš)
+ [0x2D29] = 0x63FA, --(æº)
+ [0x2D2A] = 0x64C1, --(æ“)
+ [0x2D2B] = 0x66DC, --(曜)
+ [0x2D2C] = 0x694A, --(楊)
+ [0x2D2D] = 0x69D8, --(様)
+ [0x2D2E] = 0x6D0B, --(æ´‹)
+ [0x2D2F] = 0x6EB6, --(溶)
+ [0x2D30] = 0x7194, --(熔)
+ [0x2D31] = 0x7528, --(用)
+ [0x2D32] = 0x7AAF, --(窯)
+ [0x2D33] = 0x7F8A, --(羊)
+ [0x2D34] = 0x8000, --(耀)
+ [0x2D35] = 0x8449, --(葉)
+ [0x2D36] = 0x84C9, --(蓉)
+ [0x2D37] = 0x8981, --(è¦)
+ [0x2D38] = 0x8B21, --(謡)
+ [0x2D39] = 0x8E0A, --(踊)
+ [0x2D3A] = 0x9065, --(é¥)
+ [0x2D3B] = 0x967D, --(陽)
+ [0x2D3C] = 0x990A, --(養)
+ [0x2D3D] = 0x617E, --(æ…¾)
+ [0x2D3E] = 0x6291, --(抑)
+ [0x2D3F] = 0x6B32, --(欲)
+ [0x2D40] = 0x6C83, --(沃)
+ [0x2D41] = 0x6D74, --(æµ´)
+ [0x2D42] = 0x7FCC, --(翌)
+ [0x2D43] = 0x7FFC, --(翼)
+ [0x2D44] = 0x6DC0, --(æ·€)
+ [0x2D45] = 0x7F85, --(ç¾…)
+ [0x2D46] = 0x87BA, --(螺)
+ [0x2D47] = 0x88F8, --(裸)
+ [0x2D48] = 0x6765, --(æ¥)
+ [0x2D49] = 0x83B1, --(莱)
+ [0x2D4A] = 0x983C, --(é ¼)
+ [0x2D4B] = 0x96F7, --(é›·)
+ [0x2D4C] = 0x6D1B, --(æ´›)
+ [0x2D4D] = 0x7D61, --(絡)
+ [0x2D4E] = 0x843D, --(è½)
+ [0x2D4F] = 0x916A, --(é…ª)
+ [0x2D50] = 0x4E71, --(ä¹±)
+ [0x2D51] = 0x5375, --(åµ)
+ [0x2D52] = 0x5D50, --(åµ)
+ [0x2D53] = 0x6B04, --(欄)
+ [0x2D54] = 0x6FEB, --(æ¿«)
+ [0x2D55] = 0x85CD, --(è—)
+ [0x2D56] = 0x862D, --(蘭)
+ [0x2D57] = 0x89A7, --(覧)
+ [0x2D58] = 0x5229, --(利)
+ [0x2D59] = 0x540F, --(å)
+ [0x2D5A] = 0x5C65, --(å±¥)
+ [0x2D5B] = 0x674E, --(æŽ)
+ [0x2D5C] = 0x68A8, --(梨)
+ [0x2D5D] = 0x7406, --(ç†)
+ [0x2D5E] = 0x7483, --(ç’ƒ)
+ [0x2E01] = 0x75E2, --(ç—¢)
+ [0x2E02] = 0x88CF, --(è£)
+ [0x2E03] = 0x88E1, --(裡)
+ [0x2E04] = 0x91CC, --(里)
+ [0x2E05] = 0x96E2, --(離)
+ [0x2E06] = 0x9678, --(陸)
+ [0x2E07] = 0x5F8B, --(律)
+ [0x2E08] = 0x7387, --(率)
+ [0x2E09] = 0x7ACB, --(ç«‹)
+ [0x2E0A] = 0x844E, --(è‘Ž)
+ [0x2E0B] = 0x63A0, --(掠)
+ [0x2E0C] = 0x7565, --(ç•¥)
+ [0x2E0D] = 0x5289, --(劉)
+ [0x2E0E] = 0x6D41, --(æµ)
+ [0x2E0F] = 0x6E9C, --(溜)
+ [0x2E10] = 0x7409, --(ç‰)
+ [0x2E11] = 0x7559, --(ç•™)
+ [0x2E12] = 0x786B, --(ç¡«)
+ [0x2E13] = 0x7C92, --(ç²’)
+ [0x2E14] = 0x9686, --(隆)
+ [0x2E15] = 0x7ADC, --(竜)
+ [0x2E16] = 0x9F8D, --(é¾)
+ [0x2E17] = 0x4FB6, --(侶)
+ [0x2E18] = 0x616E, --(æ…®)
+ [0x2E19] = 0x65C5, --(æ—…)
+ [0x2E1A] = 0x865C, --(虜)
+ [0x2E1B] = 0x4E86, --(了)
+ [0x2E1C] = 0x4EAE, --(亮)
+ [0x2E1D] = 0x50DA, --(僚)
+ [0x2E1E] = 0x4E21, --(両)
+ [0x2E1F] = 0x51CC, --(凌)
+ [0x2E20] = 0x5BEE, --(寮)
+ [0x2E21] = 0x6599, --(æ–™)
+ [0x2E22] = 0x6881, --(æ¢)
+ [0x2E23] = 0x6DBC, --(涼)
+ [0x2E24] = 0x731F, --(猟)
+ [0x2E25] = 0x7642, --(療)
+ [0x2E26] = 0x77AD, --(çž­)
+ [0x2E27] = 0x7A1C, --(稜)
+ [0x2E28] = 0x7CE7, --(糧)
+ [0x2E29] = 0x826F, --(良)
+ [0x2E2A] = 0x8AD2, --(è«’)
+ [0x2E2B] = 0x907C, --(é¼)
+ [0x2E2C] = 0x91CF, --(é‡)
+ [0x2E2D] = 0x9675, --(陵)
+ [0x2E2E] = 0x9818, --(é ˜)
+ [0x2E2F] = 0x529B, --(力)
+ [0x2E30] = 0x7DD1, --(ç·‘)
+ [0x2E31] = 0x502B, --(倫)
+ [0x2E32] = 0x5398, --(厘)
+ [0x2E33] = 0x6797, --(æž—)
+ [0x2E34] = 0x6DCB, --(æ·‹)
+ [0x2E35] = 0x71D0, --(ç‡)
+ [0x2E36] = 0x7433, --(ç³)
+ [0x2E37] = 0x81E8, --(臨)
+ [0x2E38] = 0x8F2A, --(輪)
+ [0x2E39] = 0x96A3, --(隣)
+ [0x2E3A] = 0x9C57, --(é±—)
+ [0x2E3B] = 0x9E9F, --(麟)
+ [0x2E3C] = 0x7460, --(ç‘ )
+ [0x2E3D] = 0x5841, --(å¡)
+ [0x2E3E] = 0x6D99, --(涙)
+ [0x2E3F] = 0x7D2F, --(ç´¯)
+ [0x2E40] = 0x985E, --(é¡ž)
+ [0x2E41] = 0x4EE4, --(令)
+ [0x2E42] = 0x4F36, --(伶)
+ [0x2E43] = 0x4F8B, --(例)
+ [0x2E44] = 0x51B7, --(冷)
+ [0x2E45] = 0x52B1, --(励)
+ [0x2E46] = 0x5DBA, --(嶺)
+ [0x2E47] = 0x601C, --(怜)
+ [0x2E48] = 0x73B2, --(玲)
+ [0x2E49] = 0x793C, --(礼)
+ [0x2E4A] = 0x82D3, --(è‹“)
+ [0x2E4B] = 0x9234, --(鈴)
+ [0x2E4C] = 0x96B7, --(éš·)
+ [0x2E4D] = 0x96F6, --(零)
+ [0x2E4E] = 0x970A, --(霊)
+ [0x2E4F] = 0x9E97, --(麗)
+ [0x2E50] = 0x9F62, --(é½¢)
+ [0x2E51] = 0x66A6, --(暦)
+ [0x2E52] = 0x6B74, --(æ­´)
+ [0x2E53] = 0x5217, --(列)
+ [0x2E54] = 0x52A3, --(劣)
+ [0x2E55] = 0x70C8, --(烈)
+ [0x2E56] = 0x88C2, --(裂)
+ [0x2E57] = 0x5EC9, --(廉)
+ [0x2E58] = 0x604B, --(æ‹)
+ [0x2E59] = 0x6190, --(æ†)
+ [0x2E5A] = 0x6F23, --(æ¼£)
+ [0x2E5B] = 0x7149, --(ç…‰)
+ [0x2E5C] = 0x7C3E, --(ç°¾)
+ [0x2E5D] = 0x7DF4, --(ç·´)
+ [0x2E5E] = 0x806F, --(è¯)
+ [0x2F01] = 0x84EE, --(è“®)
+ [0x2F02] = 0x9023, --(連)
+ [0x2F03] = 0x932C, --(錬)
+ [0x2F04] = 0x5442, --(å‘‚)
+ [0x2F05] = 0x9B6F, --(é­¯)
+ [0x2F06] = 0x6AD3, --(æ«“)
+ [0x2F07] = 0x7089, --(炉)
+ [0x2F08] = 0x8CC2, --(賂)
+ [0x2F09] = 0x8DEF, --(è·¯)
+ [0x2F0A] = 0x9732, --(露)
+ [0x2F0B] = 0x52B4, --(労)
+ [0x2F0C] = 0x5A41, --(å©)
+ [0x2F0D] = 0x5ECA, --(廊)
+ [0x2F0E] = 0x5F04, --(弄)
+ [0x2F0F] = 0x6717, --(朗)
+ [0x2F10] = 0x697C, --(楼)
+ [0x2F11] = 0x6994, --(榔)
+ [0x2F12] = 0x6D6A, --(浪)
+ [0x2F13] = 0x6F0F, --(æ¼)
+ [0x2F14] = 0x7262, --(牢)
+ [0x2F15] = 0x72FC, --(狼)
+ [0x2F16] = 0x7BED, --(篭)
+ [0x2F17] = 0x8001, --(è€)
+ [0x2F18] = 0x807E, --(è¾)
+ [0x2F19] = 0x874B, --(è‹)
+ [0x2F1A] = 0x90CE, --(郎)
+ [0x2F1B] = 0x516D, --(å…­)
+ [0x2F1C] = 0x9E93, --(麓)
+ [0x2F1D] = 0x7984, --(禄)
+ [0x2F1E] = 0x808B, --(è‚‹)
+ [0x2F1F] = 0x9332, --(録)
+ [0x2F20] = 0x8AD6, --(è«–)
+ [0x2F21] = 0x502D, --(倭)
+ [0x2F22] = 0x548C, --(和)
+ [0x2F23] = 0x8A71, --(話)
+ [0x2F24] = 0x6B6A, --(æ­ª)
+ [0x2F25] = 0x8CC4, --(賄)
+ [0x2F26] = 0x8107, --(脇)
+ [0x2F27] = 0x60D1, --(惑)
+ [0x2F28] = 0x67A0, --(æž )
+ [0x2F29] = 0x9DF2, --(é·²)
+ [0x2F2A] = 0x4E99, --(亙)
+ [0x2F2B] = 0x4E98, --(亘)
+ [0x2F2C] = 0x9C10, --(é°)
+ [0x2F2D] = 0x8A6B, --(è©«)
+ [0x2F2E] = 0x85C1, --(è—)
+ [0x2F2F] = 0x8568, --(蕨)
+ [0x2F30] = 0x6900, --(椀)
+ [0x2F31] = 0x6E7E, --(æ¹¾)
+ [0x2F32] = 0x7897, --(碗)
+ [0x2F33] = 0x8155, --(è…•)
+ [0x3001] = 0x5F0C, --(弌)
+ [0x3002] = 0x4E10, --(ä¸)
+ [0x3003] = 0x4E15, --(丕)
+ [0x3004] = 0x4E2A, --(个)
+ [0x3005] = 0x4E31, --(丱)
+ [0x3006] = 0x4E36, --(丶)
+ [0x3007] = 0x4E3C, --(丼)
+ [0x3008] = 0x4E3F, --(丿)
+ [0x3009] = 0x4E42, --(乂)
+ [0x300A] = 0x4E56, --(ä¹–)
+ [0x300B] = 0x4E58, --(乘)
+ [0x300C] = 0x4E82, --(亂)
+ [0x300D] = 0x4E85, --(亅)
+ [0x300E] = 0x8C6B, --(豫)
+ [0x300F] = 0x4E8A, --(亊)
+ [0x3010] = 0x8212, --(舒)
+ [0x3011] = 0x5F0D, --(å¼)
+ [0x3012] = 0x4E8E, --(于)
+ [0x3013] = 0x4E9E, --(亞)
+ [0x3014] = 0x4E9F, --(亟)
+ [0x3015] = 0x4EA0, --(亠)
+ [0x3016] = 0x4EA2, --(亢)
+ [0x3017] = 0x4EB0, --(亰)
+ [0x3018] = 0x4EB3, --(亳)
+ [0x3019] = 0x4EB6, --(亶)
+ [0x301A] = 0x4ECE, --(从)
+ [0x301B] = 0x4ECD, --(ä»)
+ [0x301C] = 0x4EC4, --(仄)
+ [0x301D] = 0x4EC6, --(仆)
+ [0x301E] = 0x4EC2, --(仂)
+ [0x301F] = 0x4ED7, --(ä»—)
+ [0x3020] = 0x4EDE, --(仞)
+ [0x3021] = 0x4EED, --(ä»­)
+ [0x3022] = 0x4EDF, --(仟)
+ [0x3023] = 0x4EF7, --(ä»·)
+ [0x3024] = 0x4F09, --(伉)
+ [0x3025] = 0x4F5A, --(佚)
+ [0x3026] = 0x4F30, --(ä¼°)
+ [0x3027] = 0x4F5B, --(ä½›)
+ [0x3028] = 0x4F5D, --(ä½)
+ [0x3029] = 0x4F57, --(ä½—)
+ [0x302A] = 0x4F47, --(佇)
+ [0x302B] = 0x4F76, --(佶)
+ [0x302C] = 0x4F88, --(侈)
+ [0x302D] = 0x4F8F, --(ä¾)
+ [0x302E] = 0x4F98, --(侘)
+ [0x302F] = 0x4F7B, --(ä½»)
+ [0x3030] = 0x4F69, --(佩)
+ [0x3031] = 0x4F70, --(ä½°)
+ [0x3032] = 0x4F91, --(侑)
+ [0x3033] = 0x4F6F, --(佯)
+ [0x3034] = 0x4F86, --(來)
+ [0x3035] = 0x4F96, --(ä¾–)
+ [0x3036] = 0x5118, --(儘)
+ [0x3037] = 0x4FD4, --(ä¿”)
+ [0x3038] = 0x4FDF, --(ä¿Ÿ)
+ [0x3039] = 0x4FCE, --(ä¿Ž)
+ [0x303A] = 0x4FD8, --(俘)
+ [0x303B] = 0x4FDB, --(ä¿›)
+ [0x303C] = 0x4FD1, --(ä¿‘)
+ [0x303D] = 0x4FDA, --(ä¿š)
+ [0x303E] = 0x4FD0, --(ä¿)
+ [0x303F] = 0x4FE4, --(俤)
+ [0x3040] = 0x4FE5, --(ä¿¥)
+ [0x3041] = 0x501A, --(倚)
+ [0x3042] = 0x5028, --(倨)
+ [0x3043] = 0x5014, --(倔)
+ [0x3044] = 0x502A, --(倪)
+ [0x3045] = 0x5025, --(倥)
+ [0x3046] = 0x5005, --(倅)
+ [0x3047] = 0x4F1C, --(伜)
+ [0x3048] = 0x4FF6, --(俶)
+ [0x3049] = 0x5021, --(倡)
+ [0x304A] = 0x5029, --(倩)
+ [0x304B] = 0x502C, --(倬)
+ [0x304C] = 0x4FFE, --(俾)
+ [0x304D] = 0x4FEF, --(俯)
+ [0x304E] = 0x5011, --(們)
+ [0x304F] = 0x5006, --(倆)
+ [0x3050] = 0x5043, --(åƒ)
+ [0x3051] = 0x5047, --(å‡)
+ [0x3052] = 0x6703, --(會)
+ [0x3053] = 0x5055, --(å•)
+ [0x3054] = 0x5050, --(å)
+ [0x3055] = 0x5048, --(åˆ)
+ [0x3056] = 0x505A, --(åš)
+ [0x3057] = 0x5056, --(å–)
+ [0x3058] = 0x506C, --(å¬)
+ [0x3059] = 0x5078, --(å¸)
+ [0x305A] = 0x5080, --(å‚€)
+ [0x305B] = 0x509A, --(å‚š)
+ [0x305C] = 0x5085, --(å‚…)
+ [0x305D] = 0x50B4, --(å‚´)
+ [0x305E] = 0x50B2, --(傲)
+ [0x3101] = 0x50C9, --(僉)
+ [0x3102] = 0x50CA, --(僊)
+ [0x3103] = 0x50B3, --(傳)
+ [0x3104] = 0x50C2, --(僂)
+ [0x3105] = 0x50D6, --(僖)
+ [0x3106] = 0x50DE, --(僞)
+ [0x3107] = 0x50E5, --(僥)
+ [0x3108] = 0x50ED, --(僭)
+ [0x3109] = 0x50E3, --(僣)
+ [0x310A] = 0x50EE, --(僮)
+ [0x310B] = 0x50F9, --(價)
+ [0x310C] = 0x50F5, --(僵)
+ [0x310D] = 0x5109, --(儉)
+ [0x310E] = 0x5101, --(å„)
+ [0x310F] = 0x5102, --(å„‚)
+ [0x3110] = 0x5116, --(å„–)
+ [0x3111] = 0x5115, --(å„•)
+ [0x3112] = 0x5114, --(å„”)
+ [0x3113] = 0x511A, --(å„š)
+ [0x3114] = 0x5121, --(å„¡)
+ [0x3115] = 0x513A, --(儺)
+ [0x3116] = 0x5137, --(å„·)
+ [0x3117] = 0x513C, --(儼)
+ [0x3118] = 0x513B, --(å„»)
+ [0x3119] = 0x513F, --(å„¿)
+ [0x311A] = 0x5140, --(å…€)
+ [0x311B] = 0x5152, --(å…’)
+ [0x311C] = 0x514C, --(兌)
+ [0x311D] = 0x5154, --(å…”)
+ [0x311E] = 0x5162, --(å…¢)
+ [0x311F] = 0x7AF8, --(竸)
+ [0x3120] = 0x5169, --(å…©)
+ [0x3121] = 0x516A, --(å…ª)
+ [0x3122] = 0x516E, --(å…®)
+ [0x3123] = 0x5180, --(冀)
+ [0x3124] = 0x5182, --(冂)
+ [0x3125] = 0x56D8, --(囘)
+ [0x3126] = 0x518C, --(册)
+ [0x3127] = 0x5189, --(冉)
+ [0x3128] = 0x518F, --(å†)
+ [0x3129] = 0x5191, --(冑)
+ [0x312A] = 0x5193, --(冓)
+ [0x312B] = 0x5195, --(冕)
+ [0x312C] = 0x5196, --(冖)
+ [0x312D] = 0x51A4, --(冤)
+ [0x312E] = 0x51A6, --(冦)
+ [0x312F] = 0x51A2, --(冢)
+ [0x3130] = 0x51A9, --(冩)
+ [0x3131] = 0x51AA, --(冪)
+ [0x3132] = 0x51AB, --(冫)
+ [0x3133] = 0x51B3, --(决)
+ [0x3134] = 0x51B1, --(冱)
+ [0x3135] = 0x51B2, --(冲)
+ [0x3136] = 0x51B0, --(冰)
+ [0x3137] = 0x51B5, --(况)
+ [0x3138] = 0x51BD, --(冽)
+ [0x3139] = 0x51C5, --(凅)
+ [0x313A] = 0x51C9, --(凉)
+ [0x313B] = 0x51DB, --(凛)
+ [0x313C] = 0x51E0, --(几)
+ [0x313D] = 0x8655, --(處)
+ [0x313E] = 0x51E9, --(凩)
+ [0x313F] = 0x51ED, --(凭)
+ [0x3140] = 0x51F0, --(凰)
+ [0x3141] = 0x51F5, --(凵)
+ [0x3142] = 0x51FE, --(凾)
+ [0x3143] = 0x5204, --(刄)
+ [0x3144] = 0x520B, --(刋)
+ [0x3145] = 0x5214, --(刔)
+ [0x3146] = 0x520E, --(刎)
+ [0x3147] = 0x5227, --(刧)
+ [0x3148] = 0x522A, --(刪)
+ [0x3149] = 0x522E, --(刮)
+ [0x314A] = 0x5233, --(刳)
+ [0x314B] = 0x5239, --(刹)
+ [0x314C] = 0x524F, --(å‰)
+ [0x314D] = 0x5244, --(剄)
+ [0x314E] = 0x524B, --(剋)
+ [0x314F] = 0x524C, --(剌)
+ [0x3150] = 0x525E, --(剞)
+ [0x3151] = 0x5254, --(剔)
+ [0x3152] = 0x526A, --(剪)
+ [0x3153] = 0x5274, --(剴)
+ [0x3154] = 0x5269, --(剩)
+ [0x3155] = 0x5273, --(剳)
+ [0x3156] = 0x527F, --(剿)
+ [0x3157] = 0x527D, --(剽)
+ [0x3158] = 0x528D, --(åŠ)
+ [0x3159] = 0x5294, --(劔)
+ [0x315A] = 0x5292, --(劒)
+ [0x315B] = 0x5271, --(剱)
+ [0x315C] = 0x5288, --(劈)
+ [0x315D] = 0x5291, --(劑)
+ [0x315E] = 0x8FA8, --(辨)
+ [0x3201] = 0x8FA7, --(辧)
+ [0x3202] = 0x52AC, --(劬)
+ [0x3203] = 0x52AD, --(劭)
+ [0x3204] = 0x52BC, --(劼)
+ [0x3205] = 0x52B5, --(劵)
+ [0x3206] = 0x52C1, --(å‹)
+ [0x3207] = 0x52CD, --(å‹)
+ [0x3208] = 0x52D7, --(å‹—)
+ [0x3209] = 0x52DE, --(å‹ž)
+ [0x320A] = 0x52E3, --(å‹£)
+ [0x320B] = 0x52E6, --(勦)
+ [0x320C] = 0x98ED, --(飭)
+ [0x320D] = 0x52E0, --(å‹ )
+ [0x320E] = 0x52F3, --(勳)
+ [0x320F] = 0x52F5, --(勵)
+ [0x3210] = 0x52F8, --(勸)
+ [0x3211] = 0x52F9, --(勹)
+ [0x3212] = 0x5306, --(匆)
+ [0x3213] = 0x5308, --(匈)
+ [0x3214] = 0x7538, --(甸)
+ [0x3215] = 0x530D, --(åŒ)
+ [0x3216] = 0x5310, --(åŒ)
+ [0x3217] = 0x530F, --(åŒ)
+ [0x3218] = 0x5315, --(匕)
+ [0x3219] = 0x531A, --(匚)
+ [0x321A] = 0x5323, --(匣)
+ [0x321B] = 0x532F, --(匯)
+ [0x321C] = 0x5331, --(匱)
+ [0x321D] = 0x5333, --(匳)
+ [0x321E] = 0x5338, --(匸)
+ [0x321F] = 0x5340, --(å€)
+ [0x3220] = 0x5346, --(å†)
+ [0x3221] = 0x5345, --(å…)
+ [0x3222] = 0x4E17, --(丗)
+ [0x3223] = 0x5349, --(å‰)
+ [0x3224] = 0x534D, --(å)
+ [0x3225] = 0x51D6, --(凖)
+ [0x3226] = 0x535E, --(åž)
+ [0x3227] = 0x5369, --(å©)
+ [0x3228] = 0x536E, --(å®)
+ [0x3229] = 0x5918, --(夘)
+ [0x322A] = 0x537B, --(å»)
+ [0x322B] = 0x5377, --(å·)
+ [0x322C] = 0x5382, --(厂)
+ [0x322D] = 0x5396, --(厖)
+ [0x322E] = 0x53A0, --(厠)
+ [0x322F] = 0x53A6, --(厦)
+ [0x3230] = 0x53A5, --(厥)
+ [0x3231] = 0x53AE, --(厮)
+ [0x3232] = 0x53B0, --(厰)
+ [0x3233] = 0x53B6, --(厶)
+ [0x3234] = 0x53C3, --(åƒ)
+ [0x3235] = 0x7C12, --(ç°’)
+ [0x3236] = 0x96D9, --(é›™)
+ [0x3237] = 0x53DF, --(åŸ)
+ [0x3238] = 0x66FC, --(曼)
+ [0x3239] = 0x71EE, --(燮)
+ [0x323A] = 0x53EE, --(å®)
+ [0x323B] = 0x53E8, --(å¨)
+ [0x323C] = 0x53ED, --(å­)
+ [0x323D] = 0x53FA, --(åº)
+ [0x323E] = 0x5401, --(å)
+ [0x323F] = 0x543D, --(å½)
+ [0x3240] = 0x5440, --(å‘€)
+ [0x3241] = 0x542C, --(å¬)
+ [0x3242] = 0x542D, --(å­)
+ [0x3243] = 0x543C, --(å¼)
+ [0x3244] = 0x542E, --(å®)
+ [0x3245] = 0x5436, --(å¶)
+ [0x3246] = 0x5429, --(å©)
+ [0x3247] = 0x541D, --(å)
+ [0x3248] = 0x544E, --(å‘Ž)
+ [0x3249] = 0x548F, --(å’)
+ [0x324A] = 0x5475, --(呵)
+ [0x324B] = 0x548E, --(å’Ž)
+ [0x324C] = 0x545F, --(å‘Ÿ)
+ [0x324D] = 0x5471, --(呱)
+ [0x324E] = 0x5477, --(å‘·)
+ [0x324F] = 0x5470, --(å‘°)
+ [0x3250] = 0x5492, --(å’’)
+ [0x3251] = 0x547B, --(å‘»)
+ [0x3252] = 0x5480, --(å’€)
+ [0x3253] = 0x5476, --(呶)
+ [0x3254] = 0x5484, --(å’„)
+ [0x3255] = 0x5490, --(å’)
+ [0x3256] = 0x5486, --(å’†)
+ [0x3257] = 0x54C7, --(哇)
+ [0x3258] = 0x54A2, --(å’¢)
+ [0x3259] = 0x54B8, --(å’¸)
+ [0x325A] = 0x54A5, --(å’¥)
+ [0x325B] = 0x54AC, --(å’¬)
+ [0x325C] = 0x54C4, --(å“„)
+ [0x325D] = 0x54C8, --(哈)
+ [0x325E] = 0x54A8, --(å’¨)
+ [0x3301] = 0x54AB, --(å’«)
+ [0x3302] = 0x54C2, --(å“‚)
+ [0x3303] = 0x54A4, --(å’¤)
+ [0x3304] = 0x54BE, --(å’¾)
+ [0x3305] = 0x54BC, --(å’¼)
+ [0x3306] = 0x54D8, --(哘)
+ [0x3307] = 0x54E5, --(å“¥)
+ [0x3308] = 0x54E6, --(哦)
+ [0x3309] = 0x550F, --(å”)
+ [0x330A] = 0x5514, --(å””)
+ [0x330B] = 0x54FD, --(哽)
+ [0x330C] = 0x54EE, --(å“®)
+ [0x330D] = 0x54ED, --(å“­)
+ [0x330E] = 0x54FA, --(哺)
+ [0x330F] = 0x54E2, --(å“¢)
+ [0x3310] = 0x5539, --(唹)
+ [0x3311] = 0x5540, --(å•€)
+ [0x3312] = 0x5563, --(å•£)
+ [0x3313] = 0x554C, --(啌)
+ [0x3314] = 0x552E, --(å”®)
+ [0x3315] = 0x555C, --(啜)
+ [0x3316] = 0x5545, --(å•…)
+ [0x3317] = 0x5556, --(å•–)
+ [0x3318] = 0x5557, --(å•—)
+ [0x3319] = 0x5538, --(唸)
+ [0x331A] = 0x5533, --(唳)
+ [0x331B] = 0x555D, --(å•)
+ [0x331C] = 0x5599, --(å–™)
+ [0x331D] = 0x5580, --(å–€)
+ [0x331E] = 0x54AF, --(å’¯)
+ [0x331F] = 0x558A, --(å–Š)
+ [0x3320] = 0x559F, --(å–Ÿ)
+ [0x3321] = 0x557B, --(å•»)
+ [0x3322] = 0x557E, --(啾)
+ [0x3323] = 0x5598, --(å–˜)
+ [0x3324] = 0x559E, --(å–ž)
+ [0x3325] = 0x55AE, --(å–®)
+ [0x3326] = 0x557C, --(啼)
+ [0x3327] = 0x5583, --(å–ƒ)
+ [0x3328] = 0x55A9, --(å–©)
+ [0x3329] = 0x5587, --(å–‡)
+ [0x332A] = 0x55A8, --(å–¨)
+ [0x332B] = 0x55DA, --(å—š)
+ [0x332C] = 0x55C5, --(å—…)
+ [0x332D] = 0x55DF, --(å—Ÿ)
+ [0x332E] = 0x55C4, --(å—„)
+ [0x332F] = 0x55DC, --(嗜)
+ [0x3330] = 0x55E4, --(å—¤)
+ [0x3331] = 0x55D4, --(å—”)
+ [0x3332] = 0x5614, --(嘔)
+ [0x3333] = 0x55F7, --(å—·)
+ [0x3334] = 0x5616, --(嘖)
+ [0x3335] = 0x55FE, --(å—¾)
+ [0x3336] = 0x55FD, --(å—½)
+ [0x3337] = 0x561B, --(嘛)
+ [0x3338] = 0x55F9, --(å—¹)
+ [0x3339] = 0x564E, --(噎)
+ [0x333A] = 0x5650, --(å™)
+ [0x333B] = 0x71DF, --(營)
+ [0x333C] = 0x5634, --(嘴)
+ [0x333D] = 0x5636, --(嘶)
+ [0x333E] = 0x5632, --(嘲)
+ [0x333F] = 0x5638, --(嘸)
+ [0x3340] = 0x566B, --(噫)
+ [0x3341] = 0x5664, --(噤)
+ [0x3342] = 0x562F, --(嘯)
+ [0x3343] = 0x566C, --(噬)
+ [0x3344] = 0x566A, --(噪)
+ [0x3345] = 0x5686, --(嚆)
+ [0x3346] = 0x5680, --(嚀)
+ [0x3347] = 0x568A, --(嚊)
+ [0x3348] = 0x56A0, --(åš )
+ [0x3349] = 0x5694, --(åš”)
+ [0x334A] = 0x568F, --(åš)
+ [0x334B] = 0x56A5, --(嚥)
+ [0x334C] = 0x56AE, --(åš®)
+ [0x334D] = 0x56B6, --(嚶)
+ [0x334E] = 0x56B4, --(åš´)
+ [0x334F] = 0x56C2, --(囂)
+ [0x3350] = 0x56BC, --(åš¼)
+ [0x3351] = 0x56C1, --(å›)
+ [0x3352] = 0x56C3, --(囃)
+ [0x3353] = 0x56C0, --(囀)
+ [0x3354] = 0x56C8, --(囈)
+ [0x3355] = 0x56CE, --(囎)
+ [0x3356] = 0x56D1, --(囑)
+ [0x3357] = 0x56D3, --(囓)
+ [0x3358] = 0x56D7, --(å›—)
+ [0x3359] = 0x56EE, --(å›®)
+ [0x335A] = 0x56F9, --(囹)
+ [0x335B] = 0x5700, --(圀)
+ [0x335C] = 0x56FF, --(囿)
+ [0x335D] = 0x5704, --(圄)
+ [0x335E] = 0x5709, --(圉)
+ [0x3401] = 0x5708, --(圈)
+ [0x3402] = 0x570B, --(國)
+ [0x3403] = 0x570D, --(åœ)
+ [0x3404] = 0x5713, --(圓)
+ [0x3405] = 0x5718, --(團)
+ [0x3406] = 0x5716, --(圖)
+ [0x3407] = 0x55C7, --(å—‡)
+ [0x3408] = 0x571C, --(圜)
+ [0x3409] = 0x5726, --(圦)
+ [0x340A] = 0x5737, --(圷)
+ [0x340B] = 0x5738, --(圸)
+ [0x340C] = 0x574E, --(åŽ)
+ [0x340D] = 0x573B, --(圻)
+ [0x340E] = 0x5740, --(å€)
+ [0x340F] = 0x574F, --(å)
+ [0x3410] = 0x5769, --(å©)
+ [0x3411] = 0x57C0, --(埀)
+ [0x3412] = 0x5788, --(垈)
+ [0x3413] = 0x5761, --(å¡)
+ [0x3414] = 0x577F, --(å¿)
+ [0x3415] = 0x5789, --(垉)
+ [0x3416] = 0x5793, --(åž“)
+ [0x3417] = 0x57A0, --(åž )
+ [0x3418] = 0x57B3, --(åž³)
+ [0x3419] = 0x57A4, --(垤)
+ [0x341A] = 0x57AA, --(垪)
+ [0x341B] = 0x57B0, --(åž°)
+ [0x341C] = 0x57C3, --(埃)
+ [0x341D] = 0x57C6, --(埆)
+ [0x341E] = 0x57D4, --(埔)
+ [0x341F] = 0x57D2, --(埒)
+ [0x3420] = 0x57D3, --(埓)
+ [0x3421] = 0x580A, --(å Š)
+ [0x3422] = 0x57D6, --(埖)
+ [0x3423] = 0x57E3, --(埣)
+ [0x3424] = 0x580B, --(å ‹)
+ [0x3425] = 0x5819, --(å ™)
+ [0x3426] = 0x581D, --(å )
+ [0x3427] = 0x5872, --(塲)
+ [0x3428] = 0x5821, --(å ¡)
+ [0x3429] = 0x5862, --(å¡¢)
+ [0x342A] = 0x584B, --(å¡‹)
+ [0x342B] = 0x5870, --(å¡°)
+ [0x342C] = 0x6BC0, --(毀)
+ [0x342D] = 0x5852, --(å¡’)
+ [0x342E] = 0x583D, --(å ½)
+ [0x342F] = 0x5879, --(塹)
+ [0x3430] = 0x5885, --(墅)
+ [0x3431] = 0x58B9, --(墹)
+ [0x3432] = 0x589F, --(墟)
+ [0x3433] = 0x58AB, --(墫)
+ [0x3434] = 0x58BA, --(墺)
+ [0x3435] = 0x58DE, --(壞)
+ [0x3436] = 0x58BB, --(墻)
+ [0x3437] = 0x58B8, --(墸)
+ [0x3438] = 0x58AE, --(墮)
+ [0x3439] = 0x58C5, --(壅)
+ [0x343A] = 0x58D3, --(壓)
+ [0x343B] = 0x58D1, --(壑)
+ [0x343C] = 0x58D7, --(壗)
+ [0x343D] = 0x58D9, --(壙)
+ [0x343E] = 0x58D8, --(壘)
+ [0x343F] = 0x58E5, --(壥)
+ [0x3440] = 0x58DC, --(壜)
+ [0x3441] = 0x58E4, --(壤)
+ [0x3442] = 0x58DF, --(壟)
+ [0x3443] = 0x58EF, --(壯)
+ [0x3444] = 0x58FA, --(壺)
+ [0x3445] = 0x58F9, --(壹)
+ [0x3446] = 0x58FB, --(壻)
+ [0x3447] = 0x58FC, --(壼)
+ [0x3448] = 0x58FD, --(壽)
+ [0x3449] = 0x5902, --(夂)
+ [0x344A] = 0x590A, --(夊)
+ [0x344B] = 0x5910, --(å¤)
+ [0x344C] = 0x591B, --(夛)
+ [0x344D] = 0x68A6, --(梦)
+ [0x344E] = 0x5925, --(夥)
+ [0x344F] = 0x592C, --(夬)
+ [0x3450] = 0x592D, --(夭)
+ [0x3451] = 0x5932, --(夲)
+ [0x3452] = 0x5938, --(夸)
+ [0x3453] = 0x593E, --(夾)
+ [0x3454] = 0x7AD2, --(ç«’)
+ [0x3455] = 0x5955, --(奕)
+ [0x3456] = 0x5950, --(å¥)
+ [0x3457] = 0x594E, --(奎)
+ [0x3458] = 0x595A, --(奚)
+ [0x3459] = 0x5958, --(奘)
+ [0x345A] = 0x5962, --(奢)
+ [0x345B] = 0x5960, --(奠)
+ [0x345C] = 0x5967, --(奧)
+ [0x345D] = 0x596C, --(奬)
+ [0x345E] = 0x5969, --(奩)
+ [0x3501] = 0x5978, --(奸)
+ [0x3502] = 0x5981, --(å¦)
+ [0x3503] = 0x599D, --(å¦)
+ [0x3504] = 0x4F5E, --(佞)
+ [0x3505] = 0x4FAB, --(侫)
+ [0x3506] = 0x59A3, --(妣)
+ [0x3507] = 0x59B2, --(妲)
+ [0x3508] = 0x59C6, --(姆)
+ [0x3509] = 0x59E8, --(姨)
+ [0x350A] = 0x59DC, --(姜)
+ [0x350B] = 0x598D, --(å¦)
+ [0x350C] = 0x59D9, --(姙)
+ [0x350D] = 0x59DA, --(姚)
+ [0x350E] = 0x5A25, --(娥)
+ [0x350F] = 0x5A1F, --(娟)
+ [0x3510] = 0x5A11, --(娑)
+ [0x3511] = 0x5A1C, --(娜)
+ [0x3512] = 0x5A09, --(娉)
+ [0x3513] = 0x5A1A, --(娚)
+ [0x3514] = 0x5A40, --(å©€)
+ [0x3515] = 0x5A6C, --(婬)
+ [0x3516] = 0x5A49, --(婉)
+ [0x3517] = 0x5A35, --(娵)
+ [0x3518] = 0x5A36, --(娶)
+ [0x3519] = 0x5A62, --(å©¢)
+ [0x351A] = 0x5A6A, --(婪)
+ [0x351B] = 0x5A9A, --(媚)
+ [0x351C] = 0x5ABC, --(媼)
+ [0x351D] = 0x5ABE, --(媾)
+ [0x351E] = 0x5ACB, --(å«‹)
+ [0x351F] = 0x5AC2, --(å«‚)
+ [0x3520] = 0x5ABD, --(媽)
+ [0x3521] = 0x5AE3, --(å«£)
+ [0x3522] = 0x5AD7, --(å«—)
+ [0x3523] = 0x5AE6, --(嫦)
+ [0x3524] = 0x5AE9, --(å«©)
+ [0x3525] = 0x5AD6, --(å«–)
+ [0x3526] = 0x5AFA, --(嫺)
+ [0x3527] = 0x5AFB, --(å«»)
+ [0x3528] = 0x5B0C, --(嬌)
+ [0x3529] = 0x5B0B, --(嬋)
+ [0x352A] = 0x5B16, --(嬖)
+ [0x352B] = 0x5B32, --(嬲)
+ [0x352C] = 0x5AD0, --(å«)
+ [0x352D] = 0x5B2A, --(嬪)
+ [0x352E] = 0x5B36, --(嬶)
+ [0x352F] = 0x5B3E, --(嬾)
+ [0x3530] = 0x5B43, --(å­ƒ)
+ [0x3531] = 0x5B45, --(å­…)
+ [0x3532] = 0x5B40, --(å­€)
+ [0x3533] = 0x5B51, --(å­‘)
+ [0x3534] = 0x5B55, --(å­•)
+ [0x3535] = 0x5B5A, --(å­š)
+ [0x3536] = 0x5B5B, --(å­›)
+ [0x3537] = 0x5B65, --(å­¥)
+ [0x3538] = 0x5B69, --(å­©)
+ [0x3539] = 0x5B70, --(å­°)
+ [0x353A] = 0x5B73, --(å­³)
+ [0x353B] = 0x5B75, --(å­µ)
+ [0x353C] = 0x5B78, --(å­¸)
+ [0x353D] = 0x6588, --(æ–ˆ)
+ [0x353E] = 0x5B7A, --(å­º)
+ [0x353F] = 0x5B80, --(宀)
+ [0x3540] = 0x5B83, --(它)
+ [0x3541] = 0x5BA6, --(宦)
+ [0x3542] = 0x5BB8, --(宸)
+ [0x3543] = 0x5BC3, --(寃)
+ [0x3544] = 0x5BC7, --(寇)
+ [0x3545] = 0x5BC9, --(寉)
+ [0x3546] = 0x5BD4, --(寔)
+ [0x3547] = 0x5BD0, --(å¯)
+ [0x3548] = 0x5BE4, --(寤)
+ [0x3549] = 0x5BE6, --(實)
+ [0x354A] = 0x5BE2, --(寢)
+ [0x354B] = 0x5BDE, --(寞)
+ [0x354C] = 0x5BE5, --(寥)
+ [0x354D] = 0x5BEB, --(寫)
+ [0x354E] = 0x5BF0, --(寰)
+ [0x354F] = 0x5BF6, --(寶)
+ [0x3550] = 0x5BF3, --(寳)
+ [0x3551] = 0x5C05, --(å°…)
+ [0x3552] = 0x5C07, --(å°‡)
+ [0x3553] = 0x5C08, --(å°ˆ)
+ [0x3554] = 0x5C0D, --(å°)
+ [0x3555] = 0x5C13, --(å°“)
+ [0x3556] = 0x5C20, --(å° )
+ [0x3557] = 0x5C22, --(å°¢)
+ [0x3558] = 0x5C28, --(å°¨)
+ [0x3559] = 0x5C38, --(å°¸)
+ [0x355A] = 0x5C39, --(å°¹)
+ [0x355B] = 0x5C41, --(å±)
+ [0x355C] = 0x5C46, --(屆)
+ [0x355D] = 0x5C4E, --(屎)
+ [0x355E] = 0x5C53, --(屓)
+ [0x3601] = 0x5C50, --(å±)
+ [0x3602] = 0x5C4F, --(å±)
+ [0x3603] = 0x5B71, --(å­±)
+ [0x3604] = 0x5C6C, --(屬)
+ [0x3605] = 0x5C6E, --(å±®)
+ [0x3606] = 0x4E62, --(ä¹¢)
+ [0x3607] = 0x5C76, --(屶)
+ [0x3608] = 0x5C79, --(å±¹)
+ [0x3609] = 0x5C8C, --(岌)
+ [0x360A] = 0x5C91, --(岑)
+ [0x360B] = 0x5C94, --(å²”)
+ [0x360C] = 0x599B, --(妛)
+ [0x360D] = 0x5CAB, --(岫)
+ [0x360E] = 0x5CBB, --(å²»)
+ [0x360F] = 0x5CB6, --(岶)
+ [0x3610] = 0x5CBC, --(å²¼)
+ [0x3611] = 0x5CB7, --(å²·)
+ [0x3612] = 0x5CC5, --(å³…)
+ [0x3613] = 0x5CBE, --(å²¾)
+ [0x3614] = 0x5CC7, --(峇)
+ [0x3615] = 0x5CD9, --(å³™)
+ [0x3616] = 0x5CE9, --(峩)
+ [0x3617] = 0x5CFD, --(å³½)
+ [0x3618] = 0x5CFA, --(峺)
+ [0x3619] = 0x5CED, --(å³­)
+ [0x361A] = 0x5D8C, --(嶌)
+ [0x361B] = 0x5CEA, --(峪)
+ [0x361C] = 0x5D0B, --(å´‹)
+ [0x361D] = 0x5D15, --(å´•)
+ [0x361E] = 0x5D17, --(å´—)
+ [0x361F] = 0x5D5C, --(嵜)
+ [0x3620] = 0x5D1F, --(å´Ÿ)
+ [0x3621] = 0x5D1B, --(å´›)
+ [0x3622] = 0x5D11, --(å´‘)
+ [0x3623] = 0x5D14, --(å´”)
+ [0x3624] = 0x5D22, --(å´¢)
+ [0x3625] = 0x5D1A, --(å´š)
+ [0x3626] = 0x5D19, --(å´™)
+ [0x3627] = 0x5D18, --(å´˜)
+ [0x3628] = 0x5D4C, --(嵌)
+ [0x3629] = 0x5D52, --(åµ’)
+ [0x362A] = 0x5D4E, --(嵎)
+ [0x362B] = 0x5D4B, --(嵋)
+ [0x362C] = 0x5D6C, --(嵬)
+ [0x362D] = 0x5D73, --(åµ³)
+ [0x362E] = 0x5D76, --(嵶)
+ [0x362F] = 0x5D87, --(嶇)
+ [0x3630] = 0x5D84, --(嶄)
+ [0x3631] = 0x5D82, --(嶂)
+ [0x3632] = 0x5DA2, --(嶢)
+ [0x3633] = 0x5D9D, --(å¶)
+ [0x3634] = 0x5DAC, --(嶬)
+ [0x3635] = 0x5DAE, --(嶮)
+ [0x3636] = 0x5DBD, --(嶽)
+ [0x3637] = 0x5D90, --(å¶)
+ [0x3638] = 0x5DB7, --(嶷)
+ [0x3639] = 0x5DBC, --(嶼)
+ [0x363A] = 0x5DC9, --(å·‰)
+ [0x363B] = 0x5DCD, --(å·)
+ [0x363C] = 0x5DD3, --(å·“)
+ [0x363D] = 0x5DD2, --(å·’)
+ [0x363E] = 0x5DD6, --(å·–)
+ [0x363F] = 0x5DDB, --(å·›)
+ [0x3640] = 0x5DEB, --(å·«)
+ [0x3641] = 0x5DF2, --(å·²)
+ [0x3642] = 0x5DF5, --(å·µ)
+ [0x3643] = 0x5E0B, --(帋)
+ [0x3644] = 0x5E1A, --(帚)
+ [0x3645] = 0x5E19, --(帙)
+ [0x3646] = 0x5E11, --(帑)
+ [0x3647] = 0x5E1B, --(帛)
+ [0x3648] = 0x5E36, --(帶)
+ [0x3649] = 0x5E37, --(帷)
+ [0x364A] = 0x5E44, --(幄)
+ [0x364B] = 0x5E43, --(幃)
+ [0x364C] = 0x5E40, --(å¹€)
+ [0x364D] = 0x5E4E, --(幎)
+ [0x364E] = 0x5E57, --(å¹—)
+ [0x364F] = 0x5E54, --(å¹”)
+ [0x3650] = 0x5E5F, --(幟)
+ [0x3651] = 0x5E62, --(å¹¢)
+ [0x3652] = 0x5E64, --(幤)
+ [0x3653] = 0x5E47, --(幇)
+ [0x3654] = 0x5E75, --(å¹µ)
+ [0x3655] = 0x5E76, --(并)
+ [0x3656] = 0x5E7A, --(幺)
+ [0x3657] = 0x9EBC, --(麼)
+ [0x3658] = 0x5E7F, --(广)
+ [0x3659] = 0x5EA0, --(庠)
+ [0x365A] = 0x5EC1, --(å»)
+ [0x365B] = 0x5EC2, --(廂)
+ [0x365C] = 0x5EC8, --(廈)
+ [0x365D] = 0x5ED0, --(å»)
+ [0x365E] = 0x5ECF, --(å»)
+ [0x3701] = 0x5ED6, --(å»–)
+ [0x3702] = 0x5EE3, --(廣)
+ [0x3703] = 0x5EDD, --(å»)
+ [0x3704] = 0x5EDA, --(廚)
+ [0x3705] = 0x5EDB, --(å»›)
+ [0x3706] = 0x5EE2, --(廢)
+ [0x3707] = 0x5EE1, --(廡)
+ [0x3708] = 0x5EE8, --(廨)
+ [0x3709] = 0x5EE9, --(廩)
+ [0x370A] = 0x5EEC, --(廬)
+ [0x370B] = 0x5EF1, --(å»±)
+ [0x370C] = 0x5EF3, --(廳)
+ [0x370D] = 0x5EF0, --(å»°)
+ [0x370E] = 0x5EF4, --(å»´)
+ [0x370F] = 0x5EF8, --(廸)
+ [0x3710] = 0x5EFE, --(廾)
+ [0x3711] = 0x5F03, --(弃)
+ [0x3712] = 0x5F09, --(弉)
+ [0x3713] = 0x5F5D, --(å½)
+ [0x3714] = 0x5F5C, --(彜)
+ [0x3715] = 0x5F0B, --(弋)
+ [0x3716] = 0x5F11, --(弑)
+ [0x3717] = 0x5F16, --(å¼–)
+ [0x3718] = 0x5F29, --(弩)
+ [0x3719] = 0x5F2D, --(å¼­)
+ [0x371A] = 0x5F38, --(弸)
+ [0x371B] = 0x5F41, --(å½)
+ [0x371C] = 0x5F48, --(彈)
+ [0x371D] = 0x5F4C, --(彌)
+ [0x371E] = 0x5F4E, --(彎)
+ [0x371F] = 0x5F2F, --(弯)
+ [0x3720] = 0x5F51, --(彑)
+ [0x3721] = 0x5F56, --(å½–)
+ [0x3722] = 0x5F57, --(å½—)
+ [0x3723] = 0x5F59, --(å½™)
+ [0x3724] = 0x5F61, --(彡)
+ [0x3725] = 0x5F6D, --(å½­)
+ [0x3726] = 0x5F73, --(å½³)
+ [0x3727] = 0x5F77, --(å½·)
+ [0x3728] = 0x5F83, --(徃)
+ [0x3729] = 0x5F82, --(徂)
+ [0x372A] = 0x5F7F, --(彿)
+ [0x372B] = 0x5F8A, --(徊)
+ [0x372C] = 0x5F88, --(很)
+ [0x372D] = 0x5F91, --(徑)
+ [0x372E] = 0x5F87, --(徇)
+ [0x372F] = 0x5F9E, --(從)
+ [0x3730] = 0x5F99, --(å¾™)
+ [0x3731] = 0x5F98, --(徘)
+ [0x3732] = 0x5FA0, --(å¾ )
+ [0x3733] = 0x5FA8, --(徨)
+ [0x3734] = 0x5FAD, --(å¾­)
+ [0x3735] = 0x5FBC, --(å¾¼)
+ [0x3736] = 0x5FD6, --(å¿–)
+ [0x3737] = 0x5FFB, --(å¿»)
+ [0x3738] = 0x5FE4, --(忤)
+ [0x3739] = 0x5FF8, --(忸)
+ [0x373A] = 0x5FF1, --(忱)
+ [0x373B] = 0x5FDD, --(å¿)
+ [0x373C] = 0x60B3, --(悳)
+ [0x373D] = 0x5FFF, --(å¿¿)
+ [0x373E] = 0x6021, --(怡)
+ [0x373F] = 0x6060, --(æ )
+ [0x3740] = 0x6019, --(怙)
+ [0x3741] = 0x6010, --(æ€)
+ [0x3742] = 0x6029, --(怩)
+ [0x3743] = 0x600E, --(怎)
+ [0x3744] = 0x6031, --(怱)
+ [0x3745] = 0x601B, --(怛)
+ [0x3746] = 0x6015, --(怕)
+ [0x3747] = 0x602B, --(怫)
+ [0x3748] = 0x6026, --(怦)
+ [0x3749] = 0x600F, --(æ€)
+ [0x374A] = 0x603A, --(怺)
+ [0x374B] = 0x605A, --(æš)
+ [0x374C] = 0x6041, --(æ)
+ [0x374D] = 0x606A, --(æª)
+ [0x374E] = 0x6077, --(æ·)
+ [0x374F] = 0x605F, --(æŸ)
+ [0x3750] = 0x604A, --(æŠ)
+ [0x3751] = 0x6046, --(æ†)
+ [0x3752] = 0x604D, --(æ)
+ [0x3753] = 0x6063, --(æ£)
+ [0x3754] = 0x6043, --(æƒ)
+ [0x3755] = 0x6064, --(æ¤)
+ [0x3756] = 0x6042, --(æ‚)
+ [0x3757] = 0x606C, --(æ¬)
+ [0x3758] = 0x606B, --(æ«)
+ [0x3759] = 0x6059, --(æ™)
+ [0x375A] = 0x6081, --(æ‚)
+ [0x375B] = 0x608D, --(æ‚)
+ [0x375C] = 0x60E7, --(惧)
+ [0x375D] = 0x6083, --(悃)
+ [0x375E] = 0x609A, --(æ‚š)
+ [0x3801] = 0x6084, --(æ‚„)
+ [0x3802] = 0x609B, --(æ‚›)
+ [0x3803] = 0x6096, --(æ‚–)
+ [0x3804] = 0x6097, --(æ‚—)
+ [0x3805] = 0x6092, --(æ‚’)
+ [0x3806] = 0x60A7, --(悧)
+ [0x3807] = 0x608B, --(æ‚‹)
+ [0x3808] = 0x60E1, --(惡)
+ [0x3809] = 0x60B8, --(悸)
+ [0x380A] = 0x60E0, --(惠)
+ [0x380B] = 0x60D3, --(惓)
+ [0x380C] = 0x60B4, --(æ‚´)
+ [0x380D] = 0x5FF0, --(å¿°)
+ [0x380E] = 0x60BD, --(悽)
+ [0x380F] = 0x60C6, --(惆)
+ [0x3810] = 0x60B5, --(悵)
+ [0x3811] = 0x60D8, --(惘)
+ [0x3812] = 0x614D, --(æ…)
+ [0x3813] = 0x6115, --(æ„•)
+ [0x3814] = 0x6106, --(愆)
+ [0x3815] = 0x60F6, --(惶)
+ [0x3816] = 0x60F7, --(惷)
+ [0x3817] = 0x6100, --(æ„€)
+ [0x3818] = 0x60F4, --(惴)
+ [0x3819] = 0x60FA, --(惺)
+ [0x381A] = 0x6103, --(愃)
+ [0x381B] = 0x6121, --(æ„¡)
+ [0x381C] = 0x60FB, --(惻)
+ [0x381D] = 0x60F1, --(惱)
+ [0x381E] = 0x610D, --(æ„)
+ [0x381F] = 0x610E, --(æ„Ž)
+ [0x3820] = 0x6147, --(æ…‡)
+ [0x3821] = 0x613E, --(愾)
+ [0x3822] = 0x6128, --(愨)
+ [0x3823] = 0x6127, --(愧)
+ [0x3824] = 0x614A, --(æ…Š)
+ [0x3825] = 0x613F, --(æ„¿)
+ [0x3826] = 0x613C, --(愼)
+ [0x3827] = 0x612C, --(愬)
+ [0x3828] = 0x6134, --(æ„´)
+ [0x3829] = 0x613D, --(愽)
+ [0x382A] = 0x6142, --(æ…‚)
+ [0x382B] = 0x6144, --(æ…„)
+ [0x382C] = 0x6173, --(æ…³)
+ [0x382D] = 0x6177, --(æ…·)
+ [0x382E] = 0x6158, --(æ…˜)
+ [0x382F] = 0x6159, --(æ…™)
+ [0x3830] = 0x615A, --(æ…š)
+ [0x3831] = 0x616B, --(æ…«)
+ [0x3832] = 0x6174, --(æ…´)
+ [0x3833] = 0x616F, --(æ…¯)
+ [0x3834] = 0x6165, --(æ…¥)
+ [0x3835] = 0x6171, --(æ…±)
+ [0x3836] = 0x615F, --(æ…Ÿ)
+ [0x3837] = 0x615D, --(æ…)
+ [0x3838] = 0x6153, --(æ…“)
+ [0x3839] = 0x6175, --(æ…µ)
+ [0x383A] = 0x6199, --(憙)
+ [0x383B] = 0x6196, --(憖)
+ [0x383C] = 0x6187, --(憇)
+ [0x383D] = 0x61AC, --(憬)
+ [0x383E] = 0x6194, --(憔)
+ [0x383F] = 0x619A, --(憚)
+ [0x3840] = 0x618A, --(憊)
+ [0x3841] = 0x6191, --(憑)
+ [0x3842] = 0x61AB, --(憫)
+ [0x3843] = 0x61AE, --(憮)
+ [0x3844] = 0x61CC, --(懌)
+ [0x3845] = 0x61CA, --(懊)
+ [0x3846] = 0x61C9, --(應)
+ [0x3847] = 0x61F7, --(懷)
+ [0x3848] = 0x61C8, --(懈)
+ [0x3849] = 0x61C3, --(懃)
+ [0x384A] = 0x61C6, --(懆)
+ [0x384B] = 0x61BA, --(憺)
+ [0x384C] = 0x61CB, --(懋)
+ [0x384D] = 0x7F79, --(ç½¹)
+ [0x384E] = 0x61CD, --(æ‡)
+ [0x384F] = 0x61E6, --(懦)
+ [0x3850] = 0x61E3, --(懣)
+ [0x3851] = 0x61F6, --(懶)
+ [0x3852] = 0x61FA, --(懺)
+ [0x3853] = 0x61F4, --(懴)
+ [0x3854] = 0x61FF, --(懿)
+ [0x3855] = 0x61FD, --(懽)
+ [0x3856] = 0x61FC, --(懼)
+ [0x3857] = 0x61FE, --(懾)
+ [0x3858] = 0x6200, --(戀)
+ [0x3859] = 0x6208, --(戈)
+ [0x385A] = 0x6209, --(戉)
+ [0x385B] = 0x620D, --(æˆ)
+ [0x385C] = 0x620C, --(戌)
+ [0x385D] = 0x6214, --(戔)
+ [0x385E] = 0x621B, --(戛)
+ [0x3901] = 0x621E, --(戞)
+ [0x3902] = 0x6221, --(戡)
+ [0x3903] = 0x622A, --(截)
+ [0x3904] = 0x622E, --(戮)
+ [0x3905] = 0x6230, --(戰)
+ [0x3906] = 0x6232, --(戲)
+ [0x3907] = 0x6233, --(戳)
+ [0x3908] = 0x6241, --(æ‰)
+ [0x3909] = 0x624E, --(扎)
+ [0x390A] = 0x625E, --(扞)
+ [0x390B] = 0x6263, --(扣)
+ [0x390C] = 0x625B, --(扛)
+ [0x390D] = 0x6260, --(扠)
+ [0x390E] = 0x6268, --(扨)
+ [0x390F] = 0x627C, --(扼)
+ [0x3910] = 0x6282, --(抂)
+ [0x3911] = 0x6289, --(抉)
+ [0x3912] = 0x627E, --(找)
+ [0x3913] = 0x6292, --(抒)
+ [0x3914] = 0x6293, --(抓)
+ [0x3915] = 0x6296, --(抖)
+ [0x3916] = 0x62D4, --(æ‹”)
+ [0x3917] = 0x6283, --(抃)
+ [0x3918] = 0x6294, --(抔)
+ [0x3919] = 0x62D7, --(æ‹—)
+ [0x391A] = 0x62D1, --(æ‹‘)
+ [0x391B] = 0x62BB, --(抻)
+ [0x391C] = 0x62CF, --(æ‹)
+ [0x391D] = 0x62FF, --(æ‹¿)
+ [0x391E] = 0x62C6, --(拆)
+ [0x391F] = 0x64D4, --(æ“”)
+ [0x3920] = 0x62C8, --(拈)
+ [0x3921] = 0x62DC, --(拜)
+ [0x3922] = 0x62CC, --(拌)
+ [0x3923] = 0x62CA, --(æ‹Š)
+ [0x3924] = 0x62C2, --(æ‹‚)
+ [0x3925] = 0x62C7, --(拇)
+ [0x3926] = 0x629B, --(抛)
+ [0x3927] = 0x62C9, --(拉)
+ [0x3928] = 0x630C, --(挌)
+ [0x3929] = 0x62EE, --(æ‹®)
+ [0x392A] = 0x62F1, --(拱)
+ [0x392B] = 0x6327, --(挧)
+ [0x392C] = 0x6302, --(挂)
+ [0x392D] = 0x6308, --(挈)
+ [0x392E] = 0x62EF, --(拯)
+ [0x392F] = 0x62F5, --(拵)
+ [0x3930] = 0x6350, --(æ)
+ [0x3931] = 0x633E, --(挾)
+ [0x3932] = 0x634D, --(æ)
+ [0x3933] = 0x641C, --(æœ)
+ [0x3934] = 0x634F, --(æ)
+ [0x3935] = 0x6396, --(掖)
+ [0x3936] = 0x638E, --(掎)
+ [0x3937] = 0x6380, --(掀)
+ [0x3938] = 0x63AB, --(掫)
+ [0x3939] = 0x6376, --(æ¶)
+ [0x393A] = 0x63A3, --(掣)
+ [0x393B] = 0x638F, --(æŽ)
+ [0x393C] = 0x6389, --(掉)
+ [0x393D] = 0x639F, --(掟)
+ [0x393E] = 0x63B5, --(掵)
+ [0x393F] = 0x636B, --(æ«)
+ [0x3940] = 0x6369, --(æ©)
+ [0x3941] = 0x63BE, --(掾)
+ [0x3942] = 0x63E9, --(æ©)
+ [0x3943] = 0x63C0, --(æ€)
+ [0x3944] = 0x63C6, --(æ†)
+ [0x3945] = 0x63E3, --(æ£)
+ [0x3946] = 0x63C9, --(æ‰)
+ [0x3947] = 0x63D2, --(æ’)
+ [0x3948] = 0x63F6, --(æ¶)
+ [0x3949] = 0x63C4, --(æ„)
+ [0x394A] = 0x6416, --(æ–)
+ [0x394B] = 0x6434, --(æ´)
+ [0x394C] = 0x6406, --(æ†)
+ [0x394D] = 0x6413, --(æ“)
+ [0x394E] = 0x6426, --(æ¦)
+ [0x394F] = 0x6436, --(æ¶)
+ [0x3950] = 0x651D, --(æ”)
+ [0x3951] = 0x6417, --(æ—)
+ [0x3952] = 0x6428, --(æ¨)
+ [0x3953] = 0x640F, --(æ)
+ [0x3954] = 0x6467, --(摧)
+ [0x3955] = 0x646F, --(摯)
+ [0x3956] = 0x6476, --(摶)
+ [0x3957] = 0x644E, --(æ‘Ž)
+ [0x3958] = 0x652A, --(攪)
+ [0x3959] = 0x6495, --(æ’•)
+ [0x395A] = 0x6493, --(æ’“)
+ [0x395B] = 0x64A5, --(æ’¥)
+ [0x395C] = 0x64A9, --(æ’©)
+ [0x395D] = 0x6488, --(æ’ˆ)
+ [0x395E] = 0x64BC, --(æ’¼)
+ [0x3A01] = 0x64DA, --(æ“š)
+ [0x3A02] = 0x64D2, --(æ“’)
+ [0x3A03] = 0x64C5, --(æ“…)
+ [0x3A04] = 0x64C7, --(擇)
+ [0x3A05] = 0x64BB, --(æ’»)
+ [0x3A06] = 0x64D8, --(擘)
+ [0x3A07] = 0x64C2, --(æ“‚)
+ [0x3A08] = 0x64F1, --(擱)
+ [0x3A09] = 0x64E7, --(擧)
+ [0x3A0A] = 0x8209, --(舉)
+ [0x3A0B] = 0x64E0, --(æ“ )
+ [0x3A0C] = 0x64E1, --(æ“¡)
+ [0x3A0D] = 0x62AC, --(抬)
+ [0x3A0E] = 0x64E3, --(æ“£)
+ [0x3A0F] = 0x64EF, --(擯)
+ [0x3A10] = 0x652C, --(攬)
+ [0x3A11] = 0x64F6, --(擶)
+ [0x3A12] = 0x64F4, --(æ“´)
+ [0x3A13] = 0x64F2, --(擲)
+ [0x3A14] = 0x64FA, --(擺)
+ [0x3A15] = 0x6500, --(攀)
+ [0x3A16] = 0x64FD, --(擽)
+ [0x3A17] = 0x6518, --(攘)
+ [0x3A18] = 0x651C, --(攜)
+ [0x3A19] = 0x6505, --(æ”…)
+ [0x3A1A] = 0x6524, --(攤)
+ [0x3A1B] = 0x6523, --(攣)
+ [0x3A1C] = 0x652B, --(攫)
+ [0x3A1D] = 0x6534, --(æ”´)
+ [0x3A1E] = 0x6535, --(攵)
+ [0x3A1F] = 0x6537, --(æ”·)
+ [0x3A20] = 0x6536, --(收)
+ [0x3A21] = 0x6538, --(攸)
+ [0x3A22] = 0x754B, --(ç•‹)
+ [0x3A23] = 0x6548, --(效)
+ [0x3A24] = 0x6556, --(æ•–)
+ [0x3A25] = 0x6555, --(æ••)
+ [0x3A26] = 0x654D, --(æ•)
+ [0x3A27] = 0x6558, --(敘)
+ [0x3A28] = 0x655E, --(æ•ž)
+ [0x3A29] = 0x655D, --(æ•)
+ [0x3A2A] = 0x6572, --(敲)
+ [0x3A2B] = 0x6578, --(數)
+ [0x3A2C] = 0x6582, --(æ–‚)
+ [0x3A2D] = 0x6583, --(æ–ƒ)
+ [0x3A2E] = 0x8B8A, --(變)
+ [0x3A2F] = 0x659B, --(æ–›)
+ [0x3A30] = 0x659F, --(æ–Ÿ)
+ [0x3A31] = 0x65AB, --(æ–«)
+ [0x3A32] = 0x65B7, --(æ–·)
+ [0x3A33] = 0x65C3, --(æ—ƒ)
+ [0x3A34] = 0x65C6, --(æ—†)
+ [0x3A35] = 0x65C1, --(æ—)
+ [0x3A36] = 0x65C4, --(æ—„)
+ [0x3A37] = 0x65CC, --(旌)
+ [0x3A38] = 0x65D2, --(æ—’)
+ [0x3A39] = 0x65DB, --(æ—›)
+ [0x3A3A] = 0x65D9, --(æ—™)
+ [0x3A3B] = 0x65E0, --(æ— )
+ [0x3A3C] = 0x65E1, --(æ—¡)
+ [0x3A3D] = 0x65F1, --(æ—±)
+ [0x3A3E] = 0x6772, --(æ²)
+ [0x3A3F] = 0x660A, --(昊)
+ [0x3A40] = 0x6603, --(昃)
+ [0x3A41] = 0x65FB, --(æ—»)
+ [0x3A42] = 0x6773, --(æ³)
+ [0x3A43] = 0x6635, --(昵)
+ [0x3A44] = 0x6636, --(昶)
+ [0x3A45] = 0x6634, --(昴)
+ [0x3A46] = 0x661C, --(昜)
+ [0x3A47] = 0x664F, --(æ™)
+ [0x3A48] = 0x6644, --(晄)
+ [0x3A49] = 0x6649, --(晉)
+ [0x3A4A] = 0x6641, --(æ™)
+ [0x3A4B] = 0x665E, --(晞)
+ [0x3A4C] = 0x665D, --(æ™)
+ [0x3A4D] = 0x6664, --(晤)
+ [0x3A4E] = 0x6667, --(晧)
+ [0x3A4F] = 0x6668, --(晨)
+ [0x3A50] = 0x665F, --(晟)
+ [0x3A51] = 0x6662, --(晢)
+ [0x3A52] = 0x6670, --(æ™°)
+ [0x3A53] = 0x6683, --(暃)
+ [0x3A54] = 0x6688, --(暈)
+ [0x3A55] = 0x668E, --(暎)
+ [0x3A56] = 0x6689, --(暉)
+ [0x3A57] = 0x6684, --(æš„)
+ [0x3A58] = 0x6698, --(暘)
+ [0x3A59] = 0x669D, --(æš)
+ [0x3A5A] = 0x66C1, --(æ›)
+ [0x3A5B] = 0x66B9, --(æš¹)
+ [0x3A5C] = 0x66C9, --(曉)
+ [0x3A5D] = 0x66BE, --(æš¾)
+ [0x3A5E] = 0x66BC, --(æš¼)
+ [0x3B01] = 0x66C4, --(曄)
+ [0x3B02] = 0x66B8, --(暸)
+ [0x3B03] = 0x66D6, --(æ›–)
+ [0x3B04] = 0x66DA, --(曚)
+ [0x3B05] = 0x66E0, --(æ› )
+ [0x3B06] = 0x663F, --(昿)
+ [0x3B07] = 0x66E6, --(曦)
+ [0x3B08] = 0x66E9, --(曩)
+ [0x3B09] = 0x66F0, --(æ›°)
+ [0x3B0A] = 0x66F5, --(曵)
+ [0x3B0B] = 0x66F7, --(æ›·)
+ [0x3B0C] = 0x670F, --(æœ)
+ [0x3B0D] = 0x6716, --(朖)
+ [0x3B0E] = 0x671E, --(朞)
+ [0x3B0F] = 0x6726, --(朦)
+ [0x3B10] = 0x6727, --(朧)
+ [0x3B11] = 0x9738, --(霸)
+ [0x3B12] = 0x672E, --(朮)
+ [0x3B13] = 0x673F, --(朿)
+ [0x3B14] = 0x6736, --(朶)
+ [0x3B15] = 0x6741, --(æ)
+ [0x3B16] = 0x6738, --(朸)
+ [0x3B17] = 0x6737, --(朷)
+ [0x3B18] = 0x6746, --(æ†)
+ [0x3B19] = 0x675E, --(æž)
+ [0x3B1A] = 0x6760, --(æ )
+ [0x3B1B] = 0x6759, --(æ™)
+ [0x3B1C] = 0x6763, --(æ£)
+ [0x3B1D] = 0x6764, --(æ¤)
+ [0x3B1E] = 0x6789, --(枉)
+ [0x3B1F] = 0x6770, --(æ°)
+ [0x3B20] = 0x67A9, --(æž©)
+ [0x3B21] = 0x677C, --(æ¼)
+ [0x3B22] = 0x676A, --(æª)
+ [0x3B23] = 0x678C, --(枌)
+ [0x3B24] = 0x678B, --(æž‹)
+ [0x3B25] = 0x67A6, --(枦)
+ [0x3B26] = 0x67A1, --(æž¡)
+ [0x3B27] = 0x6785, --(æž…)
+ [0x3B28] = 0x67B7, --(æž·)
+ [0x3B29] = 0x67EF, --(柯)
+ [0x3B2A] = 0x67B4, --(æž´)
+ [0x3B2B] = 0x67EC, --(柬)
+ [0x3B2C] = 0x67B3, --(æž³)
+ [0x3B2D] = 0x67E9, --(柩)
+ [0x3B2E] = 0x67B8, --(枸)
+ [0x3B2F] = 0x67E4, --(柤)
+ [0x3B30] = 0x67DE, --(柞)
+ [0x3B31] = 0x67DD, --(æŸ)
+ [0x3B32] = 0x67E2, --(柢)
+ [0x3B33] = 0x67EE, --(柮)
+ [0x3B34] = 0x67B9, --(æž¹)
+ [0x3B35] = 0x67CE, --(柎)
+ [0x3B36] = 0x67C6, --(柆)
+ [0x3B37] = 0x67E7, --(柧)
+ [0x3B38] = 0x6A9C, --(檜)
+ [0x3B39] = 0x681E, --(æ ž)
+ [0x3B3A] = 0x6846, --(框)
+ [0x3B3B] = 0x6829, --(æ ©)
+ [0x3B3C] = 0x6840, --(æ¡€)
+ [0x3B3D] = 0x684D, --(æ¡)
+ [0x3B3E] = 0x6832, --(æ ²)
+ [0x3B3F] = 0x684E, --(æ¡Ž)
+ [0x3B40] = 0x68B3, --(梳)
+ [0x3B41] = 0x682B, --(æ «)
+ [0x3B42] = 0x6859, --(æ¡™)
+ [0x3B43] = 0x6863, --(æ¡£)
+ [0x3B44] = 0x6877, --(æ¡·)
+ [0x3B45] = 0x687F, --(æ¡¿)
+ [0x3B46] = 0x689F, --(梟)
+ [0x3B47] = 0x688F, --(æ¢)
+ [0x3B48] = 0x68AD, --(梭)
+ [0x3B49] = 0x6894, --(梔)
+ [0x3B4A] = 0x689D, --(æ¢)
+ [0x3B4B] = 0x689B, --(梛)
+ [0x3B4C] = 0x6883, --(梃)
+ [0x3B4D] = 0x6AAE, --(檮)
+ [0x3B4E] = 0x68B9, --(梹)
+ [0x3B4F] = 0x6874, --(æ¡´)
+ [0x3B50] = 0x68B5, --(梵)
+ [0x3B51] = 0x68A0, --(梠)
+ [0x3B52] = 0x68BA, --(梺)
+ [0x3B53] = 0x690F, --(æ¤)
+ [0x3B54] = 0x688D, --(æ¢)
+ [0x3B55] = 0x687E, --(桾)
+ [0x3B56] = 0x6901, --(æ¤)
+ [0x3B57] = 0x68CA, --(棊)
+ [0x3B58] = 0x6908, --(椈)
+ [0x3B59] = 0x68D8, --(棘)
+ [0x3B5A] = 0x6922, --(椢)
+ [0x3B5B] = 0x6926, --(椦)
+ [0x3B5C] = 0x68E1, --(棡)
+ [0x3B5D] = 0x690C, --(椌)
+ [0x3B5E] = 0x68CD, --(æ£)
+ [0x3C01] = 0x68D4, --(棔)
+ [0x3C02] = 0x68E7, --(棧)
+ [0x3C03] = 0x68D5, --(棕)
+ [0x3C04] = 0x6936, --(椶)
+ [0x3C05] = 0x6912, --(椒)
+ [0x3C06] = 0x6904, --(椄)
+ [0x3C07] = 0x68D7, --(棗)
+ [0x3C08] = 0x68E3, --(棣)
+ [0x3C09] = 0x6925, --(椥)
+ [0x3C0A] = 0x68F9, --(棹)
+ [0x3C0B] = 0x68E0, --(棠)
+ [0x3C0C] = 0x68EF, --(棯)
+ [0x3C0D] = 0x6928, --(椨)
+ [0x3C0E] = 0x692A, --(椪)
+ [0x3C0F] = 0x691A, --(椚)
+ [0x3C10] = 0x6923, --(椣)
+ [0x3C11] = 0x6921, --(椡)
+ [0x3C12] = 0x68C6, --(棆)
+ [0x3C13] = 0x6979, --(楹)
+ [0x3C14] = 0x6977, --(楷)
+ [0x3C15] = 0x695C, --(楜)
+ [0x3C16] = 0x6978, --(楸)
+ [0x3C17] = 0x696B, --(楫)
+ [0x3C18] = 0x6954, --(楔)
+ [0x3C19] = 0x697E, --(楾)
+ [0x3C1A] = 0x696E, --(楮)
+ [0x3C1B] = 0x6939, --(椹)
+ [0x3C1C] = 0x6974, --(楴)
+ [0x3C1D] = 0x693D, --(椽)
+ [0x3C1E] = 0x6959, --(楙)
+ [0x3C1F] = 0x6930, --(椰)
+ [0x3C20] = 0x6961, --(楡)
+ [0x3C21] = 0x695E, --(楞)
+ [0x3C22] = 0x695D, --(æ¥)
+ [0x3C23] = 0x6981, --(æ¦)
+ [0x3C24] = 0x696A, --(楪)
+ [0x3C25] = 0x69B2, --(榲)
+ [0x3C26] = 0x69AE, --(榮)
+ [0x3C27] = 0x69D0, --(æ§)
+ [0x3C28] = 0x69BF, --(榿)
+ [0x3C29] = 0x69C1, --(æ§)
+ [0x3C2A] = 0x69D3, --(槓)
+ [0x3C2B] = 0x69BE, --(榾)
+ [0x3C2C] = 0x69CE, --(槎)
+ [0x3C2D] = 0x5BE8, --(寨)
+ [0x3C2E] = 0x69CA, --(槊)
+ [0x3C2F] = 0x69DD, --(æ§)
+ [0x3C30] = 0x69BB, --(榻)
+ [0x3C31] = 0x69C3, --(槃)
+ [0x3C32] = 0x69A7, --(榧)
+ [0x3C33] = 0x6A2E, --(樮)
+ [0x3C34] = 0x6991, --(榑)
+ [0x3C35] = 0x69A0, --(榠)
+ [0x3C36] = 0x699C, --(榜)
+ [0x3C37] = 0x6995, --(榕)
+ [0x3C38] = 0x69B4, --(榴)
+ [0x3C39] = 0x69DE, --(槞)
+ [0x3C3A] = 0x69E8, --(槨)
+ [0x3C3B] = 0x6A02, --(樂)
+ [0x3C3C] = 0x6A1B, --(樛)
+ [0x3C3D] = 0x69FF, --(槿)
+ [0x3C3E] = 0x6B0A, --(權)
+ [0x3C3F] = 0x69F9, --(槹)
+ [0x3C40] = 0x69F2, --(槲)
+ [0x3C41] = 0x69E7, --(槧)
+ [0x3C42] = 0x6A05, --(樅)
+ [0x3C43] = 0x69B1, --(榱)
+ [0x3C44] = 0x6A1E, --(樞)
+ [0x3C45] = 0x69ED, --(槭)
+ [0x3C46] = 0x6A14, --(樔)
+ [0x3C47] = 0x69EB, --(槫)
+ [0x3C48] = 0x6A0A, --(樊)
+ [0x3C49] = 0x6A12, --(樒)
+ [0x3C4A] = 0x6AC1, --(æ«)
+ [0x3C4B] = 0x6A23, --(樣)
+ [0x3C4C] = 0x6A13, --(樓)
+ [0x3C4D] = 0x6A44, --(æ©„)
+ [0x3C4E] = 0x6A0C, --(樌)
+ [0x3C4F] = 0x6A72, --(橲)
+ [0x3C50] = 0x6A36, --(樶)
+ [0x3C51] = 0x6A78, --(橸)
+ [0x3C52] = 0x6A47, --(橇)
+ [0x3C53] = 0x6A62, --(æ©¢)
+ [0x3C54] = 0x6A59, --(æ©™)
+ [0x3C55] = 0x6A66, --(橦)
+ [0x3C56] = 0x6A48, --(橈)
+ [0x3C57] = 0x6A38, --(樸)
+ [0x3C58] = 0x6A22, --(樢)
+ [0x3C59] = 0x6A90, --(æª)
+ [0x3C5A] = 0x6A8D, --(æª)
+ [0x3C5B] = 0x6AA0, --(檠)
+ [0x3C5C] = 0x6A84, --(檄)
+ [0x3C5D] = 0x6AA2, --(檢)
+ [0x3C5E] = 0x6AA3, --(檣)
+ [0x3D01] = 0x6A97, --(檗)
+ [0x3D02] = 0x8617, --(蘗)
+ [0x3D03] = 0x6ABB, --(檻)
+ [0x3D04] = 0x6AC3, --(櫃)
+ [0x3D05] = 0x6AC2, --(æ«‚)
+ [0x3D06] = 0x6AB8, --(檸)
+ [0x3D07] = 0x6AB3, --(檳)
+ [0x3D08] = 0x6AAC, --(檬)
+ [0x3D09] = 0x6ADE, --(æ«ž)
+ [0x3D0A] = 0x6AD1, --(æ«‘)
+ [0x3D0B] = 0x6ADF, --(æ«Ÿ)
+ [0x3D0C] = 0x6AAA, --(檪)
+ [0x3D0D] = 0x6ADA, --(æ«š)
+ [0x3D0E] = 0x6AEA, --(櫪)
+ [0x3D0F] = 0x6AFB, --(æ«»)
+ [0x3D10] = 0x6B05, --(欅)
+ [0x3D11] = 0x8616, --(蘖)
+ [0x3D12] = 0x6AFA, --(櫺)
+ [0x3D13] = 0x6B12, --(欒)
+ [0x3D14] = 0x6B16, --(欖)
+ [0x3D15] = 0x9B31, --(鬱)
+ [0x3D16] = 0x6B1F, --(欟)
+ [0x3D17] = 0x6B38, --(欸)
+ [0x3D18] = 0x6B37, --(欷)
+ [0x3D19] = 0x76DC, --(盜)
+ [0x3D1A] = 0x6B39, --(欹)
+ [0x3D1B] = 0x98EE, --(飮)
+ [0x3D1C] = 0x6B47, --(æ­‡)
+ [0x3D1D] = 0x6B43, --(æ­ƒ)
+ [0x3D1E] = 0x6B49, --(æ­‰)
+ [0x3D1F] = 0x6B50, --(æ­)
+ [0x3D20] = 0x6B59, --(æ­™)
+ [0x3D21] = 0x6B54, --(æ­”)
+ [0x3D22] = 0x6B5B, --(æ­›)
+ [0x3D23] = 0x6B5F, --(æ­Ÿ)
+ [0x3D24] = 0x6B61, --(æ­¡)
+ [0x3D25] = 0x6B78, --(æ­¸)
+ [0x3D26] = 0x6B79, --(æ­¹)
+ [0x3D27] = 0x6B7F, --(æ­¿)
+ [0x3D28] = 0x6B80, --(殀)
+ [0x3D29] = 0x6B84, --(殄)
+ [0x3D2A] = 0x6B83, --(殃)
+ [0x3D2B] = 0x6B8D, --(æ®)
+ [0x3D2C] = 0x6B98, --(殘)
+ [0x3D2D] = 0x6B95, --(殕)
+ [0x3D2E] = 0x6B9E, --(殞)
+ [0x3D2F] = 0x6BA4, --(殤)
+ [0x3D30] = 0x6BAA, --(殪)
+ [0x3D31] = 0x6BAB, --(殫)
+ [0x3D32] = 0x6BAF, --(殯)
+ [0x3D33] = 0x6BB2, --(殲)
+ [0x3D34] = 0x6BB1, --(æ®±)
+ [0x3D35] = 0x6BB3, --(殳)
+ [0x3D36] = 0x6BB7, --(æ®·)
+ [0x3D37] = 0x6BBC, --(殼)
+ [0x3D38] = 0x6BC6, --(毆)
+ [0x3D39] = 0x6BCB, --(毋)
+ [0x3D3A] = 0x6BD3, --(毓)
+ [0x3D3B] = 0x6BDF, --(毟)
+ [0x3D3C] = 0x6BEC, --(毬)
+ [0x3D3D] = 0x6BEB, --(毫)
+ [0x3D3E] = 0x6BF3, --(毳)
+ [0x3D3F] = 0x6BEF, --(毯)
+ [0x3D40] = 0x9EBE, --(麾)
+ [0x3D41] = 0x6C08, --(æ°ˆ)
+ [0x3D42] = 0x6C13, --(æ°“)
+ [0x3D43] = 0x6C14, --(æ°”)
+ [0x3D44] = 0x6C1B, --(æ°›)
+ [0x3D45] = 0x6C24, --(æ°¤)
+ [0x3D46] = 0x6C23, --(æ°£)
+ [0x3D47] = 0x6C5E, --(汞)
+ [0x3D48] = 0x6C55, --(汕)
+ [0x3D49] = 0x6C62, --(æ±¢)
+ [0x3D4A] = 0x6C6A, --(汪)
+ [0x3D4B] = 0x6C82, --(沂)
+ [0x3D4C] = 0x6C8D, --(æ²)
+ [0x3D4D] = 0x6C9A, --(沚)
+ [0x3D4E] = 0x6C81, --(æ²)
+ [0x3D4F] = 0x6C9B, --(æ²›)
+ [0x3D50] = 0x6C7E, --(æ±¾)
+ [0x3D51] = 0x6C68, --(汨)
+ [0x3D52] = 0x6C73, --(æ±³)
+ [0x3D53] = 0x6C92, --(æ²’)
+ [0x3D54] = 0x6C90, --(æ²)
+ [0x3D55] = 0x6CC4, --(泄)
+ [0x3D56] = 0x6CF1, --(æ³±)
+ [0x3D57] = 0x6CD3, --(泓)
+ [0x3D58] = 0x6CBD, --(æ²½)
+ [0x3D59] = 0x6CD7, --(æ³—)
+ [0x3D5A] = 0x6CC5, --(æ³…)
+ [0x3D5B] = 0x6CDD, --(æ³)
+ [0x3D5C] = 0x6CAE, --(æ²®)
+ [0x3D5D] = 0x6CB1, --(æ²±)
+ [0x3D5E] = 0x6CBE, --(æ²¾)
+ [0x3E01] = 0x6CBA, --(沺)
+ [0x3E02] = 0x6CDB, --(æ³›)
+ [0x3E03] = 0x6CEF, --(泯)
+ [0x3E04] = 0x6CD9, --(æ³™)
+ [0x3E05] = 0x6CEA, --(泪)
+ [0x3E06] = 0x6D1F, --(æ´Ÿ)
+ [0x3E07] = 0x884D, --(è¡)
+ [0x3E08] = 0x6D36, --(æ´¶)
+ [0x3E09] = 0x6D2B, --(æ´«)
+ [0x3E0A] = 0x6D3D, --(æ´½)
+ [0x3E0B] = 0x6D38, --(æ´¸)
+ [0x3E0C] = 0x6D19, --(æ´™)
+ [0x3E0D] = 0x6D35, --(æ´µ)
+ [0x3E0E] = 0x6D33, --(æ´³)
+ [0x3E0F] = 0x6D12, --(æ´’)
+ [0x3E10] = 0x6D0C, --(洌)
+ [0x3E11] = 0x6D63, --(æµ£)
+ [0x3E12] = 0x6D93, --(涓)
+ [0x3E13] = 0x6D64, --(浤)
+ [0x3E14] = 0x6D5A, --(浚)
+ [0x3E15] = 0x6D79, --(æµ¹)
+ [0x3E16] = 0x6D59, --(æµ™)
+ [0x3E17] = 0x6D8E, --(涎)
+ [0x3E18] = 0x6D95, --(涕)
+ [0x3E19] = 0x6FE4, --(濤)
+ [0x3E1A] = 0x6D85, --(涅)
+ [0x3E1B] = 0x6DF9, --(æ·¹)
+ [0x3E1C] = 0x6E15, --(渕)
+ [0x3E1D] = 0x6E0A, --(渊)
+ [0x3E1E] = 0x6DB5, --(涵)
+ [0x3E1F] = 0x6DC7, --(æ·‡)
+ [0x3E20] = 0x6DE6, --(æ·¦)
+ [0x3E21] = 0x6DB8, --(涸)
+ [0x3E22] = 0x6DC6, --(æ·†)
+ [0x3E23] = 0x6DEC, --(æ·¬)
+ [0x3E24] = 0x6DDE, --(æ·ž)
+ [0x3E25] = 0x6DCC, --(淌)
+ [0x3E26] = 0x6DE8, --(æ·¨)
+ [0x3E27] = 0x6DD2, --(æ·’)
+ [0x3E28] = 0x6DC5, --(æ·…)
+ [0x3E29] = 0x6DFA, --(æ·º)
+ [0x3E2A] = 0x6DD9, --(æ·™)
+ [0x3E2B] = 0x6DE4, --(æ·¤)
+ [0x3E2C] = 0x6DD5, --(æ·•)
+ [0x3E2D] = 0x6DEA, --(æ·ª)
+ [0x3E2E] = 0x6DEE, --(æ·®)
+ [0x3E2F] = 0x6E2D, --(渭)
+ [0x3E30] = 0x6E6E, --(æ¹®)
+ [0x3E31] = 0x6E2E, --(渮)
+ [0x3E32] = 0x6E19, --(渙)
+ [0x3E33] = 0x6E72, --(æ¹²)
+ [0x3E34] = 0x6E5F, --(湟)
+ [0x3E35] = 0x6E3E, --(渾)
+ [0x3E36] = 0x6E23, --(渣)
+ [0x3E37] = 0x6E6B, --(湫)
+ [0x3E38] = 0x6E2B, --(渫)
+ [0x3E39] = 0x6E76, --(湶)
+ [0x3E3A] = 0x6E4D, --(æ¹)
+ [0x3E3B] = 0x6E1F, --(渟)
+ [0x3E3C] = 0x6E43, --(湃)
+ [0x3E3D] = 0x6E3A, --(渺)
+ [0x3E3E] = 0x6E4E, --(湎)
+ [0x3E3F] = 0x6E24, --(渤)
+ [0x3E40] = 0x6EFF, --(滿)
+ [0x3E41] = 0x6E1D, --(æ¸)
+ [0x3E42] = 0x6E38, --(游)
+ [0x3E43] = 0x6E82, --(溂)
+ [0x3E44] = 0x6EAA, --(溪)
+ [0x3E45] = 0x6E98, --(溘)
+ [0x3E46] = 0x6EC9, --(滉)
+ [0x3E47] = 0x6EB7, --(溷)
+ [0x3E48] = 0x6ED3, --(滓)
+ [0x3E49] = 0x6EBD, --(溽)
+ [0x3E4A] = 0x6EAF, --(溯)
+ [0x3E4B] = 0x6EC4, --(滄)
+ [0x3E4C] = 0x6EB2, --(溲)
+ [0x3E4D] = 0x6ED4, --(æ»”)
+ [0x3E4E] = 0x6ED5, --(滕)
+ [0x3E4F] = 0x6E8F, --(æº)
+ [0x3E50] = 0x6EA5, --(溥)
+ [0x3E51] = 0x6EC2, --(滂)
+ [0x3E52] = 0x6E9F, --(溟)
+ [0x3E53] = 0x6F41, --(æ½)
+ [0x3E54] = 0x6F11, --(漑)
+ [0x3E55] = 0x704C, --(çŒ)
+ [0x3E56] = 0x6EEC, --(滬)
+ [0x3E57] = 0x6EF8, --(滸)
+ [0x3E58] = 0x6EFE, --(滾)
+ [0x3E59] = 0x6F3F, --(漿)
+ [0x3E5A] = 0x6EF2, --(滲)
+ [0x3E5B] = 0x6F31, --(æ¼±)
+ [0x3E5C] = 0x6EEF, --(滯)
+ [0x3E5D] = 0x6F32, --(æ¼²)
+ [0x3E5E] = 0x6ECC, --(滌)
+ [0x3F01] = 0x6F3E, --(æ¼¾)
+ [0x3F02] = 0x6F13, --(漓)
+ [0x3F03] = 0x6EF7, --(æ»·)
+ [0x3F04] = 0x6F86, --(澆)
+ [0x3F05] = 0x6F7A, --(潺)
+ [0x3F06] = 0x6F78, --(潸)
+ [0x3F07] = 0x6F81, --(æ¾)
+ [0x3F08] = 0x6F80, --(æ¾€)
+ [0x3F09] = 0x6F6F, --(潯)
+ [0x3F0A] = 0x6F5B, --(æ½›)
+ [0x3F0B] = 0x6FF3, --(濳)
+ [0x3F0C] = 0x6F6D, --(æ½­)
+ [0x3F0D] = 0x6F82, --(澂)
+ [0x3F0E] = 0x6F7C, --(æ½¼)
+ [0x3F0F] = 0x6F58, --(潘)
+ [0x3F10] = 0x6F8E, --(澎)
+ [0x3F11] = 0x6F91, --(澑)
+ [0x3F12] = 0x6FC2, --(æ¿‚)
+ [0x3F13] = 0x6F66, --(潦)
+ [0x3F14] = 0x6FB3, --(æ¾³)
+ [0x3F15] = 0x6FA3, --(æ¾£)
+ [0x3F16] = 0x6FA1, --(澡)
+ [0x3F17] = 0x6FA4, --(澤)
+ [0x3F18] = 0x6FB9, --(æ¾¹)
+ [0x3F19] = 0x6FC6, --(濆)
+ [0x3F1A] = 0x6FAA, --(澪)
+ [0x3F1B] = 0x6FDF, --(æ¿Ÿ)
+ [0x3F1C] = 0x6FD5, --(æ¿•)
+ [0x3F1D] = 0x6FEC, --(濬)
+ [0x3F1E] = 0x6FD4, --(æ¿”)
+ [0x3F1F] = 0x6FD8, --(濘)
+ [0x3F20] = 0x6FF1, --(濱)
+ [0x3F21] = 0x6FEE, --(æ¿®)
+ [0x3F22] = 0x6FDB, --(æ¿›)
+ [0x3F23] = 0x7009, --(瀉)
+ [0x3F24] = 0x700B, --(瀋)
+ [0x3F25] = 0x6FFA, --(濺)
+ [0x3F26] = 0x7011, --(瀑)
+ [0x3F27] = 0x7001, --(ç€)
+ [0x3F28] = 0x700F, --(ç€)
+ [0x3F29] = 0x6FFE, --(濾)
+ [0x3F2A] = 0x701B, --(瀛)
+ [0x3F2B] = 0x701A, --(瀚)
+ [0x3F2C] = 0x6F74, --(æ½´)
+ [0x3F2D] = 0x701D, --(ç€)
+ [0x3F2E] = 0x7018, --(瀘)
+ [0x3F2F] = 0x701F, --(瀟)
+ [0x3F30] = 0x7030, --(瀰)
+ [0x3F31] = 0x703E, --(瀾)
+ [0x3F32] = 0x7032, --(瀲)
+ [0x3F33] = 0x7051, --(ç‘)
+ [0x3F34] = 0x7063, --(ç£)
+ [0x3F35] = 0x7099, --(ç‚™)
+ [0x3F36] = 0x7092, --(ç‚’)
+ [0x3F37] = 0x70AF, --(炯)
+ [0x3F38] = 0x70F1, --(烱)
+ [0x3F39] = 0x70AC, --(炬)
+ [0x3F3A] = 0x70B8, --(炸)
+ [0x3F3B] = 0x70B3, --(炳)
+ [0x3F3C] = 0x70AE, --(ç‚®)
+ [0x3F3D] = 0x70DF, --(烟)
+ [0x3F3E] = 0x70CB, --(烋)
+ [0x3F3F] = 0x70DD, --(çƒ)
+ [0x3F40] = 0x70D9, --(烙)
+ [0x3F41] = 0x7109, --(焉)
+ [0x3F42] = 0x70FD, --(烽)
+ [0x3F43] = 0x711C, --(焜)
+ [0x3F44] = 0x7119, --(ç„™)
+ [0x3F45] = 0x7165, --(ç…¥)
+ [0x3F46] = 0x7155, --(ç…•)
+ [0x3F47] = 0x7188, --(熈)
+ [0x3F48] = 0x7166, --(ç…¦)
+ [0x3F49] = 0x7162, --(ç…¢)
+ [0x3F4A] = 0x714C, --(煌)
+ [0x3F4B] = 0x7156, --(ç…–)
+ [0x3F4C] = 0x716C, --(ç…¬)
+ [0x3F4D] = 0x718F, --(ç†)
+ [0x3F4E] = 0x71FB, --(燻)
+ [0x3F4F] = 0x7184, --(熄)
+ [0x3F50] = 0x7195, --(熕)
+ [0x3F51] = 0x71A8, --(熨)
+ [0x3F52] = 0x71AC, --(熬)
+ [0x3F53] = 0x71D7, --(燗)
+ [0x3F54] = 0x71B9, --(熹)
+ [0x3F55] = 0x71BE, --(熾)
+ [0x3F56] = 0x71D2, --(燒)
+ [0x3F57] = 0x71C9, --(燉)
+ [0x3F58] = 0x71D4, --(燔)
+ [0x3F59] = 0x71CE, --(燎)
+ [0x3F5A] = 0x71E0, --(燠)
+ [0x3F5B] = 0x71EC, --(燬)
+ [0x3F5C] = 0x71E7, --(燧)
+ [0x3F5D] = 0x71F5, --(燵)
+ [0x3F5E] = 0x71FC, --(燼)
+ [0x4001] = 0x71F9, --(燹)
+ [0x4002] = 0x71FF, --(燿)
+ [0x4003] = 0x720D, --(çˆ)
+ [0x4004] = 0x7210, --(çˆ)
+ [0x4005] = 0x721B, --(爛)
+ [0x4006] = 0x7228, --(爨)
+ [0x4007] = 0x722D, --(爭)
+ [0x4008] = 0x722C, --(爬)
+ [0x4009] = 0x7230, --(爰)
+ [0x400A] = 0x7232, --(爲)
+ [0x400B] = 0x723B, --(爻)
+ [0x400C] = 0x723C, --(爼)
+ [0x400D] = 0x723F, --(爿)
+ [0x400E] = 0x7240, --(牀)
+ [0x400F] = 0x7246, --(牆)
+ [0x4010] = 0x724B, --(牋)
+ [0x4011] = 0x7258, --(牘)
+ [0x4012] = 0x7274, --(牴)
+ [0x4013] = 0x727E, --(牾)
+ [0x4014] = 0x7282, --(犂)
+ [0x4015] = 0x7281, --(çŠ)
+ [0x4016] = 0x7287, --(犇)
+ [0x4017] = 0x7292, --(犒)
+ [0x4018] = 0x7296, --(犖)
+ [0x4019] = 0x72A2, --(犢)
+ [0x401A] = 0x72A7, --(犧)
+ [0x401B] = 0x72B9, --(犹)
+ [0x401C] = 0x72B2, --(犲)
+ [0x401D] = 0x72C3, --(狃)
+ [0x401E] = 0x72C6, --(狆)
+ [0x401F] = 0x72C4, --(ç‹„)
+ [0x4020] = 0x72CE, --(ç‹Ž)
+ [0x4021] = 0x72D2, --(ç‹’)
+ [0x4022] = 0x72E2, --(ç‹¢)
+ [0x4023] = 0x72E0, --(ç‹ )
+ [0x4024] = 0x72E1, --(ç‹¡)
+ [0x4025] = 0x72F9, --(狹)
+ [0x4026] = 0x72F7, --(ç‹·)
+ [0x4027] = 0x500F, --(å€)
+ [0x4028] = 0x7317, --(猗)
+ [0x4029] = 0x730A, --(猊)
+ [0x402A] = 0x731C, --(猜)
+ [0x402B] = 0x7316, --(猖)
+ [0x402C] = 0x731D, --(çŒ)
+ [0x402D] = 0x7334, --(猴)
+ [0x402E] = 0x732F, --(猯)
+ [0x402F] = 0x7329, --(猩)
+ [0x4030] = 0x7325, --(猥)
+ [0x4031] = 0x733E, --(猾)
+ [0x4032] = 0x734E, --(çŽ)
+ [0x4033] = 0x734F, --(ç)
+ [0x4034] = 0x9ED8, --(默)
+ [0x4035] = 0x7357, --(ç—)
+ [0x4036] = 0x736A, --(çª)
+ [0x4037] = 0x7368, --(ç¨)
+ [0x4038] = 0x7370, --(ç°)
+ [0x4039] = 0x7378, --(ç¸)
+ [0x403A] = 0x7375, --(çµ)
+ [0x403B] = 0x737B, --(ç»)
+ [0x403C] = 0x737A, --(çº)
+ [0x403D] = 0x73C8, --(çˆ)
+ [0x403E] = 0x73B3, --(玳)
+ [0x403F] = 0x73CE, --(çŽ)
+ [0x4040] = 0x73BB, --(玻)
+ [0x4041] = 0x73C0, --(ç€)
+ [0x4042] = 0x73E5, --(ç¥)
+ [0x4043] = 0x73EE, --(ç®)
+ [0x4044] = 0x73DE, --(çž)
+ [0x4045] = 0x74A2, --(ç’¢)
+ [0x4046] = 0x7405, --(ç…)
+ [0x4047] = 0x746F, --(瑯)
+ [0x4048] = 0x7425, --(ç¥)
+ [0x4049] = 0x73F8, --(ç¸)
+ [0x404A] = 0x7432, --(ç²)
+ [0x404B] = 0x743A, --(çº)
+ [0x404C] = 0x7455, --(ç‘•)
+ [0x404D] = 0x743F, --(ç¿)
+ [0x404E] = 0x745F, --(ç‘Ÿ)
+ [0x404F] = 0x7459, --(ç‘™)
+ [0x4050] = 0x7441, --(ç‘)
+ [0x4051] = 0x745C, --(瑜)
+ [0x4052] = 0x7469, --(ç‘©)
+ [0x4053] = 0x7470, --(ç‘°)
+ [0x4054] = 0x7463, --(ç‘£)
+ [0x4055] = 0x746A, --(瑪)
+ [0x4056] = 0x7476, --(瑶)
+ [0x4057] = 0x747E, --(瑾)
+ [0x4058] = 0x748B, --(ç’‹)
+ [0x4059] = 0x749E, --(ç’ž)
+ [0x405A] = 0x74A7, --(ç’§)
+ [0x405B] = 0x74CA, --(ç“Š)
+ [0x405C] = 0x74CF, --(ç“)
+ [0x405D] = 0x74D4, --(ç“”)
+ [0x405E] = 0x73F1, --(ç±)
+ [0x4101] = 0x74E0, --(ç“ )
+ [0x4102] = 0x74E3, --(ç“£)
+ [0x4103] = 0x74E7, --(瓧)
+ [0x4104] = 0x74E9, --(ç“©)
+ [0x4105] = 0x74EE, --(ç“®)
+ [0x4106] = 0x74F2, --(瓲)
+ [0x4107] = 0x74F0, --(ç“°)
+ [0x4108] = 0x74F1, --(瓱)
+ [0x4109] = 0x74F8, --(瓸)
+ [0x410A] = 0x74F7, --(ç“·)
+ [0x410B] = 0x7504, --(甄)
+ [0x410C] = 0x7503, --(甃)
+ [0x410D] = 0x7505, --(ç”…)
+ [0x410E] = 0x750C, --(甌)
+ [0x410F] = 0x750E, --(甎)
+ [0x4110] = 0x750D, --(ç”)
+ [0x4111] = 0x7515, --(甕)
+ [0x4112] = 0x7513, --(甓)
+ [0x4113] = 0x751E, --(甞)
+ [0x4114] = 0x7526, --(甦)
+ [0x4115] = 0x752C, --(甬)
+ [0x4116] = 0x753C, --(甼)
+ [0x4117] = 0x7544, --(ç•„)
+ [0x4118] = 0x754D, --(ç•)
+ [0x4119] = 0x754A, --(ç•Š)
+ [0x411A] = 0x7549, --(畉)
+ [0x411B] = 0x755B, --(ç•›)
+ [0x411C] = 0x7546, --(畆)
+ [0x411D] = 0x755A, --(ç•š)
+ [0x411E] = 0x7569, --(ç•©)
+ [0x411F] = 0x7564, --(畤)
+ [0x4120] = 0x7567, --(畧)
+ [0x4121] = 0x756B, --(ç•«)
+ [0x4122] = 0x756D, --(ç•­)
+ [0x4123] = 0x7578, --(畸)
+ [0x4124] = 0x7576, --(當)
+ [0x4125] = 0x7586, --(ç–†)
+ [0x4126] = 0x7587, --(ç–‡)
+ [0x4127] = 0x7574, --(ç•´)
+ [0x4128] = 0x758A, --(ç–Š)
+ [0x4129] = 0x7589, --(ç–‰)
+ [0x412A] = 0x7582, --(ç–‚)
+ [0x412B] = 0x7594, --(ç–”)
+ [0x412C] = 0x759A, --(ç–š)
+ [0x412D] = 0x759D, --(ç–)
+ [0x412E] = 0x75A5, --(ç–¥)
+ [0x412F] = 0x75A3, --(ç–£)
+ [0x4130] = 0x75C2, --(ç—‚)
+ [0x4131] = 0x75B3, --(ç–³)
+ [0x4132] = 0x75C3, --(ç—ƒ)
+ [0x4133] = 0x75B5, --(ç–µ)
+ [0x4134] = 0x75BD, --(ç–½)
+ [0x4135] = 0x75B8, --(ç–¸)
+ [0x4136] = 0x75BC, --(ç–¼)
+ [0x4137] = 0x75B1, --(ç–±)
+ [0x4138] = 0x75CD, --(ç—)
+ [0x4139] = 0x75CA, --(ç—Š)
+ [0x413A] = 0x75D2, --(ç—’)
+ [0x413B] = 0x75D9, --(ç—™)
+ [0x413C] = 0x75E3, --(ç—£)
+ [0x413D] = 0x75DE, --(ç—ž)
+ [0x413E] = 0x75FE, --(ç—¾)
+ [0x413F] = 0x75FF, --(ç—¿)
+ [0x4140] = 0x75FC, --(ç—¼)
+ [0x4141] = 0x7601, --(ç˜)
+ [0x4142] = 0x75F0, --(ç—°)
+ [0x4143] = 0x75FA, --(ç—º)
+ [0x4144] = 0x75F2, --(ç—²)
+ [0x4145] = 0x75F3, --(ç—³)
+ [0x4146] = 0x760B, --(瘋)
+ [0x4147] = 0x760D, --(ç˜)
+ [0x4148] = 0x7609, --(瘉)
+ [0x4149] = 0x761F, --(瘟)
+ [0x414A] = 0x7627, --(瘧)
+ [0x414B] = 0x7620, --(瘠)
+ [0x414C] = 0x7621, --(瘡)
+ [0x414D] = 0x7622, --(瘢)
+ [0x414E] = 0x7624, --(瘤)
+ [0x414F] = 0x7634, --(瘴)
+ [0x4150] = 0x7630, --(瘰)
+ [0x4151] = 0x763B, --(瘻)
+ [0x4152] = 0x7647, --(癇)
+ [0x4153] = 0x7648, --(癈)
+ [0x4154] = 0x7646, --(癆)
+ [0x4155] = 0x765C, --(癜)
+ [0x4156] = 0x7658, --(癘)
+ [0x4157] = 0x7661, --(癡)
+ [0x4158] = 0x7662, --(癢)
+ [0x4159] = 0x7668, --(癨)
+ [0x415A] = 0x7669, --(癩)
+ [0x415B] = 0x766A, --(癪)
+ [0x415C] = 0x7667, --(癧)
+ [0x415D] = 0x766C, --(癬)
+ [0x415E] = 0x7670, --(ç™°)
+ [0x4201] = 0x7672, --(癲)
+ [0x4202] = 0x7676, --(癶)
+ [0x4203] = 0x7678, --(癸)
+ [0x4204] = 0x767C, --(發)
+ [0x4205] = 0x7680, --(皀)
+ [0x4206] = 0x7683, --(皃)
+ [0x4207] = 0x7688, --(皈)
+ [0x4208] = 0x768B, --(çš‹)
+ [0x4209] = 0x768E, --(皎)
+ [0x420A] = 0x7696, --(çš–)
+ [0x420B] = 0x7693, --(çš“)
+ [0x420C] = 0x7699, --(çš™)
+ [0x420D] = 0x769A, --(çšš)
+ [0x420E] = 0x76B0, --(çš°)
+ [0x420F] = 0x76B4, --(çš´)
+ [0x4210] = 0x76B8, --(皸)
+ [0x4211] = 0x76B9, --(çš¹)
+ [0x4212] = 0x76BA, --(皺)
+ [0x4213] = 0x76C2, --(盂)
+ [0x4214] = 0x76CD, --(ç›)
+ [0x4215] = 0x76D6, --(ç›–)
+ [0x4216] = 0x76D2, --(ç›’)
+ [0x4217] = 0x76DE, --(盞)
+ [0x4218] = 0x76E1, --(盡)
+ [0x4219] = 0x76E5, --(盥)
+ [0x421A] = 0x76E7, --(盧)
+ [0x421B] = 0x76EA, --(盪)
+ [0x421C] = 0x862F, --(蘯)
+ [0x421D] = 0x76FB, --(ç›»)
+ [0x421E] = 0x7708, --(眈)
+ [0x421F] = 0x7707, --(眇)
+ [0x4220] = 0x7704, --(眄)
+ [0x4221] = 0x7729, --(眩)
+ [0x4222] = 0x7724, --(眤)
+ [0x4223] = 0x771E, --(眞)
+ [0x4224] = 0x7725, --(眥)
+ [0x4225] = 0x7726, --(眦)
+ [0x4226] = 0x771B, --(眛)
+ [0x4227] = 0x7737, --(眷)
+ [0x4228] = 0x7738, --(眸)
+ [0x4229] = 0x7747, --(ç‡)
+ [0x422A] = 0x775A, --(çš)
+ [0x422B] = 0x7768, --(ç¨)
+ [0x422C] = 0x776B, --(ç«)
+ [0x422D] = 0x775B, --(ç›)
+ [0x422E] = 0x7765, --(ç¥)
+ [0x422F] = 0x777F, --(ç¿)
+ [0x4230] = 0x777E, --(ç¾)
+ [0x4231] = 0x7779, --(ç¹)
+ [0x4232] = 0x778E, --(瞎)
+ [0x4233] = 0x778B, --(çž‹)
+ [0x4234] = 0x7791, --(çž‘)
+ [0x4235] = 0x77A0, --(çž )
+ [0x4236] = 0x779E, --(çžž)
+ [0x4237] = 0x77B0, --(çž°)
+ [0x4238] = 0x77B6, --(瞶)
+ [0x4239] = 0x77B9, --(çž¹)
+ [0x423A] = 0x77BF, --(çž¿)
+ [0x423B] = 0x77BC, --(çž¼)
+ [0x423C] = 0x77BD, --(çž½)
+ [0x423D] = 0x77BB, --(çž»)
+ [0x423E] = 0x77C7, --(矇)
+ [0x423F] = 0x77CD, --(çŸ)
+ [0x4240] = 0x77D7, --(矗)
+ [0x4241] = 0x77DA, --(矚)
+ [0x4242] = 0x77DC, --(矜)
+ [0x4243] = 0x77E3, --(矣)
+ [0x4244] = 0x77EE, --(矮)
+ [0x4245] = 0x77FC, --(矼)
+ [0x4246] = 0x780C, --(砌)
+ [0x4247] = 0x7812, --(ç ’)
+ [0x4248] = 0x7926, --(礦)
+ [0x4249] = 0x7820, --(ç  )
+ [0x424A] = 0x792A, --(礪)
+ [0x424B] = 0x7845, --(ç¡…)
+ [0x424C] = 0x788E, --(碎)
+ [0x424D] = 0x7874, --(ç¡´)
+ [0x424E] = 0x7886, --(碆)
+ [0x424F] = 0x787C, --(硼)
+ [0x4250] = 0x789A, --(碚)
+ [0x4251] = 0x788C, --(碌)
+ [0x4252] = 0x78A3, --(碣)
+ [0x4253] = 0x78B5, --(碵)
+ [0x4254] = 0x78AA, --(碪)
+ [0x4255] = 0x78AF, --(碯)
+ [0x4256] = 0x78D1, --(磑)
+ [0x4257] = 0x78C6, --(磆)
+ [0x4258] = 0x78CB, --(磋)
+ [0x4259] = 0x78D4, --(磔)
+ [0x425A] = 0x78BE, --(碾)
+ [0x425B] = 0x78BC, --(碼)
+ [0x425C] = 0x78C5, --(磅)
+ [0x425D] = 0x78CA, --(磊)
+ [0x425E] = 0x78EC, --(磬)
+ [0x4301] = 0x78E7, --(磧)
+ [0x4302] = 0x78DA, --(磚)
+ [0x4303] = 0x78FD, --(磽)
+ [0x4304] = 0x78F4, --(磴)
+ [0x4305] = 0x7907, --(礇)
+ [0x4306] = 0x7912, --(礒)
+ [0x4307] = 0x7911, --(礑)
+ [0x4308] = 0x7919, --(礙)
+ [0x4309] = 0x792C, --(礬)
+ [0x430A] = 0x792B, --(礫)
+ [0x430B] = 0x7940, --(祀)
+ [0x430C] = 0x7960, --(祠)
+ [0x430D] = 0x7957, --(祗)
+ [0x430E] = 0x795F, --(祟)
+ [0x430F] = 0x795A, --(祚)
+ [0x4310] = 0x7955, --(祕)
+ [0x4311] = 0x7953, --(祓)
+ [0x4312] = 0x797A, --(祺)
+ [0x4313] = 0x797F, --(祿)
+ [0x4314] = 0x798A, --(禊)
+ [0x4315] = 0x799D, --(ç¦)
+ [0x4316] = 0x79A7, --(禧)
+ [0x4317] = 0x9F4B, --(齋)
+ [0x4318] = 0x79AA, --(禪)
+ [0x4319] = 0x79AE, --(禮)
+ [0x431A] = 0x79B3, --(禳)
+ [0x431B] = 0x79B9, --(禹)
+ [0x431C] = 0x79BA, --(禺)
+ [0x431D] = 0x79C9, --(秉)
+ [0x431E] = 0x79D5, --(秕)
+ [0x431F] = 0x79E7, --(秧)
+ [0x4320] = 0x79EC, --(秬)
+ [0x4321] = 0x79E1, --(秡)
+ [0x4322] = 0x79E3, --(秣)
+ [0x4323] = 0x7A08, --(稈)
+ [0x4324] = 0x7A0D, --(ç¨)
+ [0x4325] = 0x7A18, --(稘)
+ [0x4326] = 0x7A19, --(稙)
+ [0x4327] = 0x7A20, --(稠)
+ [0x4328] = 0x7A1F, --(稟)
+ [0x4329] = 0x7980, --(禀)
+ [0x432A] = 0x7A31, --(稱)
+ [0x432B] = 0x7A3B, --(稻)
+ [0x432C] = 0x7A3E, --(稾)
+ [0x432D] = 0x7A37, --(稷)
+ [0x432E] = 0x7A43, --(穃)
+ [0x432F] = 0x7A57, --(ç©—)
+ [0x4330] = 0x7A49, --(穉)
+ [0x4331] = 0x7A61, --(ç©¡)
+ [0x4332] = 0x7A62, --(ç©¢)
+ [0x4333] = 0x7A69, --(ç©©)
+ [0x4334] = 0x9F9D, --(é¾)
+ [0x4335] = 0x7A70, --(ç©°)
+ [0x4336] = 0x7A79, --(穹)
+ [0x4337] = 0x7A7D, --(穽)
+ [0x4338] = 0x7A88, --(窈)
+ [0x4339] = 0x7A97, --(窗)
+ [0x433A] = 0x7A95, --(窕)
+ [0x433B] = 0x7A98, --(窘)
+ [0x433C] = 0x7A96, --(窖)
+ [0x433D] = 0x7AA9, --(窩)
+ [0x433E] = 0x7AC8, --(竈)
+ [0x433F] = 0x7AB0, --(窰)
+ [0x4340] = 0x7AB6, --(窶)
+ [0x4341] = 0x7AC5, --(ç«…)
+ [0x4342] = 0x7AC4, --(ç«„)
+ [0x4343] = 0x7ABF, --(窿)
+ [0x4344] = 0x9083, --(邃)
+ [0x4345] = 0x7AC7, --(竇)
+ [0x4346] = 0x7ACA, --(ç«Š)
+ [0x4347] = 0x7ACD, --(ç«)
+ [0x4348] = 0x7ACF, --(ç«)
+ [0x4349] = 0x7AD5, --(ç«•)
+ [0x434A] = 0x7AD3, --(ç«“)
+ [0x434B] = 0x7AD9, --(ç«™)
+ [0x434C] = 0x7ADA, --(ç«š)
+ [0x434D] = 0x7ADD, --(ç«)
+ [0x434E] = 0x7AE1, --(ç«¡)
+ [0x434F] = 0x7AE2, --(ç«¢)
+ [0x4350] = 0x7AE6, --(竦)
+ [0x4351] = 0x7AED, --(ç«­)
+ [0x4352] = 0x7AF0, --(ç«°)
+ [0x4353] = 0x7B02, --(笂)
+ [0x4354] = 0x7B0F, --(ç¬)
+ [0x4355] = 0x7B0A, --(笊)
+ [0x4356] = 0x7B06, --(笆)
+ [0x4357] = 0x7B33, --(笳)
+ [0x4358] = 0x7B18, --(笘)
+ [0x4359] = 0x7B19, --(笙)
+ [0x435A] = 0x7B1E, --(笞)
+ [0x435B] = 0x7B35, --(笵)
+ [0x435C] = 0x7B28, --(笨)
+ [0x435D] = 0x7B36, --(笶)
+ [0x435E] = 0x7B50, --(ç­)
+ [0x4401] = 0x7B7A, --(ç­º)
+ [0x4402] = 0x7B04, --(笄)
+ [0x4403] = 0x7B4D, --(ç­)
+ [0x4404] = 0x7B0B, --(笋)
+ [0x4405] = 0x7B4C, --(筌)
+ [0x4406] = 0x7B45, --(ç­…)
+ [0x4407] = 0x7B75, --(ç­µ)
+ [0x4408] = 0x7B65, --(ç­¥)
+ [0x4409] = 0x7B74, --(ç­´)
+ [0x440A] = 0x7B67, --(ç­§)
+ [0x440B] = 0x7B70, --(ç­°)
+ [0x440C] = 0x7B71, --(ç­±)
+ [0x440D] = 0x7B6C, --(ç­¬)
+ [0x440E] = 0x7B6E, --(ç­®)
+ [0x440F] = 0x7B9D, --(ç®)
+ [0x4410] = 0x7B98, --(箘)
+ [0x4411] = 0x7B9F, --(箟)
+ [0x4412] = 0x7B8D, --(ç®)
+ [0x4413] = 0x7B9C, --(箜)
+ [0x4414] = 0x7B9A, --(箚)
+ [0x4415] = 0x7B8B, --(箋)
+ [0x4416] = 0x7B92, --(ç®’)
+ [0x4417] = 0x7B8F, --(ç®)
+ [0x4418] = 0x7B5D, --(ç­)
+ [0x4419] = 0x7B99, --(ç®™)
+ [0x441A] = 0x7BCB, --(篋)
+ [0x441B] = 0x7BC1, --(ç¯)
+ [0x441C] = 0x7BCC, --(篌)
+ [0x441D] = 0x7BCF, --(ç¯)
+ [0x441E] = 0x7BB4, --(ç®´)
+ [0x441F] = 0x7BC6, --(篆)
+ [0x4420] = 0x7BDD, --(ç¯)
+ [0x4421] = 0x7BE9, --(篩)
+ [0x4422] = 0x7C11, --(ç°‘)
+ [0x4423] = 0x7C14, --(ç°”)
+ [0x4424] = 0x7BE6, --(篦)
+ [0x4425] = 0x7BE5, --(篥)
+ [0x4426] = 0x7C60, --(ç± )
+ [0x4427] = 0x7C00, --(ç°€)
+ [0x4428] = 0x7C07, --(ç°‡)
+ [0x4429] = 0x7C13, --(ç°“)
+ [0x442A] = 0x7BF3, --(篳)
+ [0x442B] = 0x7BF7, --(篷)
+ [0x442C] = 0x7C17, --(ç°—)
+ [0x442D] = 0x7C0D, --(ç°)
+ [0x442E] = 0x7BF6, --(篶)
+ [0x442F] = 0x7C23, --(ç°£)
+ [0x4430] = 0x7C27, --(ç°§)
+ [0x4431] = 0x7C2A, --(ç°ª)
+ [0x4432] = 0x7C1F, --(ç°Ÿ)
+ [0x4433] = 0x7C37, --(ç°·)
+ [0x4434] = 0x7C2B, --(ç°«)
+ [0x4435] = 0x7C3D, --(ç°½)
+ [0x4436] = 0x7C4C, --(籌)
+ [0x4437] = 0x7C43, --(籃)
+ [0x4438] = 0x7C54, --(ç±”)
+ [0x4439] = 0x7C4F, --(ç±)
+ [0x443A] = 0x7C40, --(ç±€)
+ [0x443B] = 0x7C50, --(ç±)
+ [0x443C] = 0x7C58, --(籘)
+ [0x443D] = 0x7C5F, --(籟)
+ [0x443E] = 0x7C64, --(籤)
+ [0x443F] = 0x7C56, --(ç±–)
+ [0x4440] = 0x7C65, --(ç±¥)
+ [0x4441] = 0x7C6C, --(籬)
+ [0x4442] = 0x7C75, --(ç±µ)
+ [0x4443] = 0x7C83, --(粃)
+ [0x4444] = 0x7C90, --(ç²)
+ [0x4445] = 0x7CA4, --(粤)
+ [0x4446] = 0x7CAD, --(ç²­)
+ [0x4447] = 0x7CA2, --(ç²¢)
+ [0x4448] = 0x7CAB, --(粫)
+ [0x4449] = 0x7CA1, --(粡)
+ [0x444A] = 0x7CA8, --(粨)
+ [0x444B] = 0x7CB3, --(ç²³)
+ [0x444C] = 0x7CB2, --(ç²²)
+ [0x444D] = 0x7CB1, --(ç²±)
+ [0x444E] = 0x7CAE, --(ç²®)
+ [0x444F] = 0x7CB9, --(ç²¹)
+ [0x4450] = 0x7CBD, --(ç²½)
+ [0x4451] = 0x7CC0, --(ç³€)
+ [0x4452] = 0x7CC5, --(ç³…)
+ [0x4453] = 0x7CC2, --(糂)
+ [0x4454] = 0x7CD8, --(糘)
+ [0x4455] = 0x7CD2, --(ç³’)
+ [0x4456] = 0x7CDC, --(糜)
+ [0x4457] = 0x7CE2, --(ç³¢)
+ [0x4458] = 0x9B3B, --(鬻)
+ [0x4459] = 0x7CEF, --(糯)
+ [0x445A] = 0x7CF2, --(ç³²)
+ [0x445B] = 0x7CF4, --(ç³´)
+ [0x445C] = 0x7CF6, --(糶)
+ [0x445D] = 0x7CFA, --(糺)
+ [0x445E] = 0x7D06, --(ç´†)
+ [0x4501] = 0x7D02, --(ç´‚)
+ [0x4502] = 0x7D1C, --(紜)
+ [0x4503] = 0x7D15, --(ç´•)
+ [0x4504] = 0x7D0A, --(ç´Š)
+ [0x4505] = 0x7D45, --(çµ…)
+ [0x4506] = 0x7D4B, --(絋)
+ [0x4507] = 0x7D2E, --(ç´®)
+ [0x4508] = 0x7D32, --(ç´²)
+ [0x4509] = 0x7D3F, --(ç´¿)
+ [0x450A] = 0x7D35, --(ç´µ)
+ [0x450B] = 0x7D46, --(絆)
+ [0x450C] = 0x7D73, --(çµ³)
+ [0x450D] = 0x7D56, --(çµ–)
+ [0x450E] = 0x7D4E, --(絎)
+ [0x450F] = 0x7D72, --(çµ²)
+ [0x4510] = 0x7D68, --(絨)
+ [0x4511] = 0x7D6E, --(çµ®)
+ [0x4512] = 0x7D4F, --(çµ)
+ [0x4513] = 0x7D63, --(çµ£)
+ [0x4514] = 0x7D93, --(經)
+ [0x4515] = 0x7D89, --(綉)
+ [0x4516] = 0x7D5B, --(çµ›)
+ [0x4517] = 0x7D8F, --(ç¶)
+ [0x4518] = 0x7D7D, --(çµ½)
+ [0x4519] = 0x7D9B, --(綛)
+ [0x451A] = 0x7DBA, --(綺)
+ [0x451B] = 0x7DAE, --(綮)
+ [0x451C] = 0x7DA3, --(綣)
+ [0x451D] = 0x7DB5, --(綵)
+ [0x451E] = 0x7DC7, --(ç·‡)
+ [0x451F] = 0x7DBD, --(綽)
+ [0x4520] = 0x7DAB, --(綫)
+ [0x4521] = 0x7E3D, --(總)
+ [0x4522] = 0x7DA2, --(綢)
+ [0x4523] = 0x7DAF, --(綯)
+ [0x4524] = 0x7DDC, --(緜)
+ [0x4525] = 0x7DB8, --(綸)
+ [0x4526] = 0x7D9F, --(綟)
+ [0x4527] = 0x7DB0, --(綰)
+ [0x4528] = 0x7DD8, --(ç·˜)
+ [0x4529] = 0x7DDD, --(ç·)
+ [0x452A] = 0x7DE4, --(ç·¤)
+ [0x452B] = 0x7DDE, --(ç·ž)
+ [0x452C] = 0x7DFB, --(ç·»)
+ [0x452D] = 0x7DF2, --(ç·²)
+ [0x452E] = 0x7DE1, --(ç·¡)
+ [0x452F] = 0x7E05, --(縅)
+ [0x4530] = 0x7E0A, --(縊)
+ [0x4531] = 0x7E23, --(縣)
+ [0x4532] = 0x7E21, --(縡)
+ [0x4533] = 0x7E12, --(縒)
+ [0x4534] = 0x7E31, --(縱)
+ [0x4535] = 0x7E1F, --(縟)
+ [0x4536] = 0x7E09, --(縉)
+ [0x4537] = 0x7E0B, --(縋)
+ [0x4538] = 0x7E22, --(縢)
+ [0x4539] = 0x7E46, --(繆)
+ [0x453A] = 0x7E66, --(繦)
+ [0x453B] = 0x7E3B, --(縻)
+ [0x453C] = 0x7E35, --(縵)
+ [0x453D] = 0x7E39, --(縹)
+ [0x453E] = 0x7E43, --(繃)
+ [0x453F] = 0x7E37, --(縷)
+ [0x4540] = 0x7E32, --(縲)
+ [0x4541] = 0x7E3A, --(縺)
+ [0x4542] = 0x7E67, --(繧)
+ [0x4543] = 0x7E5D, --(ç¹)
+ [0x4544] = 0x7E56, --(ç¹–)
+ [0x4545] = 0x7E5E, --(繞)
+ [0x4546] = 0x7E59, --(ç¹™)
+ [0x4547] = 0x7E5A, --(繚)
+ [0x4548] = 0x7E79, --(ç¹¹)
+ [0x4549] = 0x7E6A, --(繪)
+ [0x454A] = 0x7E69, --(繩)
+ [0x454B] = 0x7E7C, --(ç¹¼)
+ [0x454C] = 0x7E7B, --(ç¹»)
+ [0x454D] = 0x7E83, --(纃)
+ [0x454E] = 0x7DD5, --(ç·•)
+ [0x454F] = 0x7E7D, --(ç¹½)
+ [0x4550] = 0x8FAE, --(è¾®)
+ [0x4551] = 0x7E7F, --(繿)
+ [0x4552] = 0x7E88, --(纈)
+ [0x4553] = 0x7E89, --(纉)
+ [0x4554] = 0x7E8C, --(續)
+ [0x4555] = 0x7E92, --(纒)
+ [0x4556] = 0x7E90, --(çº)
+ [0x4557] = 0x7E93, --(纓)
+ [0x4558] = 0x7E94, --(纔)
+ [0x4559] = 0x7E96, --(纖)
+ [0x455A] = 0x7E8E, --(纎)
+ [0x455B] = 0x7E9B, --(纛)
+ [0x455C] = 0x7E9C, --(纜)
+ [0x455D] = 0x7F38, --(缸)
+ [0x455E] = 0x7F3A, --(缺)
+ [0x4601] = 0x7F45, --(ç½…)
+ [0x4602] = 0x7F4C, --(罌)
+ [0x4603] = 0x7F4D, --(ç½)
+ [0x4604] = 0x7F4E, --(罎)
+ [0x4605] = 0x7F50, --(ç½)
+ [0x4606] = 0x7F51, --(网)
+ [0x4607] = 0x7F55, --(罕)
+ [0x4608] = 0x7F54, --(ç½”)
+ [0x4609] = 0x7F58, --(罘)
+ [0x460A] = 0x7F5F, --(罟)
+ [0x460B] = 0x7F60, --(ç½ )
+ [0x460C] = 0x7F68, --(罨)
+ [0x460D] = 0x7F69, --(罩)
+ [0x460E] = 0x7F67, --(罧)
+ [0x460F] = 0x7F78, --(罸)
+ [0x4610] = 0x7F82, --(羂)
+ [0x4611] = 0x7F86, --(羆)
+ [0x4612] = 0x7F83, --(羃)
+ [0x4613] = 0x7F88, --(羈)
+ [0x4614] = 0x7F87, --(羇)
+ [0x4615] = 0x7F8C, --(羌)
+ [0x4616] = 0x7F94, --(ç¾”)
+ [0x4617] = 0x7F9E, --(羞)
+ [0x4618] = 0x7F9D, --(ç¾)
+ [0x4619] = 0x7F9A, --(羚)
+ [0x461A] = 0x7FA3, --(ç¾£)
+ [0x461B] = 0x7FAF, --(羯)
+ [0x461C] = 0x7FB2, --(ç¾²)
+ [0x461D] = 0x7FB9, --(ç¾¹)
+ [0x461E] = 0x7FAE, --(ç¾®)
+ [0x461F] = 0x7FB6, --(羶)
+ [0x4620] = 0x7FB8, --(羸)
+ [0x4621] = 0x8B71, --(è­±)
+ [0x4622] = 0x7FC5, --(ç¿…)
+ [0x4623] = 0x7FC6, --(翆)
+ [0x4624] = 0x7FCA, --(ç¿Š)
+ [0x4625] = 0x7FD5, --(ç¿•)
+ [0x4626] = 0x7FD4, --(ç¿”)
+ [0x4627] = 0x7FE1, --(ç¿¡)
+ [0x4628] = 0x7FE6, --(翦)
+ [0x4629] = 0x7FE9, --(ç¿©)
+ [0x462A] = 0x7FF3, --(翳)
+ [0x462B] = 0x7FF9, --(翹)
+ [0x462C] = 0x98DC, --(飜)
+ [0x462D] = 0x8006, --(耆)
+ [0x462E] = 0x8004, --(耄)
+ [0x462F] = 0x800B, --(耋)
+ [0x4630] = 0x8012, --(耒)
+ [0x4631] = 0x8018, --(耘)
+ [0x4632] = 0x8019, --(耙)
+ [0x4633] = 0x801C, --(耜)
+ [0x4634] = 0x8021, --(耡)
+ [0x4635] = 0x8028, --(耨)
+ [0x4636] = 0x803F, --(耿)
+ [0x4637] = 0x803B, --(耻)
+ [0x4638] = 0x804A, --(èŠ)
+ [0x4639] = 0x8046, --(è†)
+ [0x463A] = 0x8052, --(è’)
+ [0x463B] = 0x8058, --(è˜)
+ [0x463C] = 0x805A, --(èš)
+ [0x463D] = 0x805F, --(èŸ)
+ [0x463E] = 0x8062, --(è¢)
+ [0x463F] = 0x8068, --(è¨)
+ [0x4640] = 0x8073, --(è³)
+ [0x4641] = 0x8072, --(è²)
+ [0x4642] = 0x8070, --(è°)
+ [0x4643] = 0x8076, --(è¶)
+ [0x4644] = 0x8079, --(è¹)
+ [0x4645] = 0x807D, --(è½)
+ [0x4646] = 0x807F, --(è¿)
+ [0x4647] = 0x8084, --(è‚„)
+ [0x4648] = 0x8086, --(肆)
+ [0x4649] = 0x8085, --(è‚…)
+ [0x464A] = 0x809B, --(è‚›)
+ [0x464B] = 0x8093, --(è‚“)
+ [0x464C] = 0x809A, --(è‚š)
+ [0x464D] = 0x80AD, --(è‚­)
+ [0x464E] = 0x5190, --(å†)
+ [0x464F] = 0x80AC, --(肬)
+ [0x4650] = 0x80DB, --(胛)
+ [0x4651] = 0x80E5, --(胥)
+ [0x4652] = 0x80D9, --(胙)
+ [0x4653] = 0x80DD, --(èƒ)
+ [0x4654] = 0x80C4, --(胄)
+ [0x4655] = 0x80DA, --(胚)
+ [0x4656] = 0x80D6, --(胖)
+ [0x4657] = 0x8109, --(脉)
+ [0x4658] = 0x80EF, --(胯)
+ [0x4659] = 0x80F1, --(胱)
+ [0x465A] = 0x811B, --(è„›)
+ [0x465B] = 0x8129, --(è„©)
+ [0x465C] = 0x8123, --(è„£)
+ [0x465D] = 0x812F, --(脯)
+ [0x465E] = 0x814B, --(è…‹)
+ [0x4701] = 0x968B, --(éš‹)
+ [0x4702] = 0x8146, --(è…†)
+ [0x4703] = 0x813E, --(脾)
+ [0x4704] = 0x8153, --(è…“)
+ [0x4705] = 0x8151, --(è…‘)
+ [0x4706] = 0x80FC, --(胼)
+ [0x4707] = 0x8171, --(è…±)
+ [0x4708] = 0x816E, --(è…®)
+ [0x4709] = 0x8165, --(è…¥)
+ [0x470A] = 0x8166, --(è…¦)
+ [0x470B] = 0x8174, --(è…´)
+ [0x470C] = 0x8183, --(膃)
+ [0x470D] = 0x8188, --(膈)
+ [0x470E] = 0x818A, --(膊)
+ [0x470F] = 0x8180, --(膀)
+ [0x4710] = 0x8182, --(膂)
+ [0x4711] = 0x81A0, --(膠)
+ [0x4712] = 0x8195, --(膕)
+ [0x4713] = 0x81A4, --(膤)
+ [0x4714] = 0x81A3, --(膣)
+ [0x4715] = 0x815F, --(è…Ÿ)
+ [0x4716] = 0x8193, --(膓)
+ [0x4717] = 0x81A9, --(膩)
+ [0x4718] = 0x81B0, --(膰)
+ [0x4719] = 0x81B5, --(膵)
+ [0x471A] = 0x81BE, --(膾)
+ [0x471B] = 0x81B8, --(膸)
+ [0x471C] = 0x81BD, --(膽)
+ [0x471D] = 0x81C0, --(臀)
+ [0x471E] = 0x81C2, --(臂)
+ [0x471F] = 0x81BA, --(膺)
+ [0x4720] = 0x81C9, --(臉)
+ [0x4721] = 0x81CD, --(è‡)
+ [0x4722] = 0x81D1, --(臑)
+ [0x4723] = 0x81D9, --(臙)
+ [0x4724] = 0x81D8, --(臘)
+ [0x4725] = 0x81C8, --(臈)
+ [0x4726] = 0x81DA, --(臚)
+ [0x4727] = 0x81DF, --(臟)
+ [0x4728] = 0x81E0, --(臠)
+ [0x4729] = 0x81E7, --(臧)
+ [0x472A] = 0x81FA, --(臺)
+ [0x472B] = 0x81FB, --(臻)
+ [0x472C] = 0x81FE, --(臾)
+ [0x472D] = 0x8201, --(èˆ)
+ [0x472E] = 0x8202, --(舂)
+ [0x472F] = 0x8205, --(舅)
+ [0x4730] = 0x8207, --(與)
+ [0x4731] = 0x820A, --(舊)
+ [0x4732] = 0x820D, --(èˆ)
+ [0x4733] = 0x8210, --(èˆ)
+ [0x4734] = 0x8216, --(舖)
+ [0x4735] = 0x8229, --(舩)
+ [0x4736] = 0x822B, --(舫)
+ [0x4737] = 0x8238, --(舸)
+ [0x4738] = 0x8233, --(舳)
+ [0x4739] = 0x8240, --(艀)
+ [0x473A] = 0x8259, --(艙)
+ [0x473B] = 0x8258, --(艘)
+ [0x473C] = 0x825D, --(è‰)
+ [0x473D] = 0x825A, --(艚)
+ [0x473E] = 0x825F, --(艟)
+ [0x473F] = 0x8264, --(艤)
+ [0x4740] = 0x8262, --(艢)
+ [0x4741] = 0x8268, --(艨)
+ [0x4742] = 0x826A, --(艪)
+ [0x4743] = 0x826B, --(艫)
+ [0x4744] = 0x822E, --(舮)
+ [0x4745] = 0x8271, --(艱)
+ [0x4746] = 0x8277, --(艷)
+ [0x4747] = 0x8278, --(艸)
+ [0x4748] = 0x827E, --(艾)
+ [0x4749] = 0x828D, --(èŠ)
+ [0x474A] = 0x8292, --(芒)
+ [0x474B] = 0x82AB, --(芫)
+ [0x474C] = 0x829F, --(芟)
+ [0x474D] = 0x82BB, --(芻)
+ [0x474E] = 0x82AC, --(芬)
+ [0x474F] = 0x82E1, --(è‹¡)
+ [0x4750] = 0x82E3, --(è‹£)
+ [0x4751] = 0x82DF, --(è‹Ÿ)
+ [0x4752] = 0x82D2, --(è‹’)
+ [0x4753] = 0x82F4, --(è‹´)
+ [0x4754] = 0x82F3, --(苳)
+ [0x4755] = 0x82FA, --(苺)
+ [0x4756] = 0x8393, --(莓)
+ [0x4757] = 0x8303, --(范)
+ [0x4758] = 0x82FB, --(è‹»)
+ [0x4759] = 0x82F9, --(苹)
+ [0x475A] = 0x82DE, --(è‹ž)
+ [0x475B] = 0x8306, --(茆)
+ [0x475C] = 0x82DC, --(苜)
+ [0x475D] = 0x8309, --(茉)
+ [0x475E] = 0x82D9, --(è‹™)
+ [0x4801] = 0x8335, --(茵)
+ [0x4802] = 0x8334, --(茴)
+ [0x4803] = 0x8316, --(茖)
+ [0x4804] = 0x8332, --(茲)
+ [0x4805] = 0x8331, --(茱)
+ [0x4806] = 0x8340, --(è€)
+ [0x4807] = 0x8339, --(茹)
+ [0x4808] = 0x8350, --(è)
+ [0x4809] = 0x8345, --(è…)
+ [0x480A] = 0x832F, --(茯)
+ [0x480B] = 0x832B, --(茫)
+ [0x480C] = 0x8317, --(茗)
+ [0x480D] = 0x8318, --(茘)
+ [0x480E] = 0x8385, --(莅)
+ [0x480F] = 0x839A, --(莚)
+ [0x4810] = 0x83AA, --(莪)
+ [0x4811] = 0x839F, --(莟)
+ [0x4812] = 0x83A2, --(莢)
+ [0x4813] = 0x8396, --(莖)
+ [0x4814] = 0x8323, --(茣)
+ [0x4815] = 0x838E, --(莎)
+ [0x4816] = 0x8387, --(莇)
+ [0x4817] = 0x838A, --(莊)
+ [0x4818] = 0x837C, --(è¼)
+ [0x4819] = 0x83B5, --(莵)
+ [0x481A] = 0x8373, --(è³)
+ [0x481B] = 0x8375, --(èµ)
+ [0x481C] = 0x83A0, --(莠)
+ [0x481D] = 0x8389, --(莉)
+ [0x481E] = 0x83A8, --(莨)
+ [0x481F] = 0x83F4, --(è´)
+ [0x4820] = 0x8413, --(è“)
+ [0x4821] = 0x83EB, --(è«)
+ [0x4822] = 0x83CE, --(èŽ)
+ [0x4823] = 0x83FD, --(è½)
+ [0x4824] = 0x8403, --(èƒ)
+ [0x4825] = 0x83D8, --(è˜)
+ [0x4826] = 0x840B, --(è‹)
+ [0x4827] = 0x83C1, --(è)
+ [0x4828] = 0x83F7, --(è·)
+ [0x4829] = 0x8407, --(è‡)
+ [0x482A] = 0x83E0, --(è )
+ [0x482B] = 0x83F2, --(è²)
+ [0x482C] = 0x840D, --(è)
+ [0x482D] = 0x8422, --(è¢)
+ [0x482E] = 0x8420, --(è )
+ [0x482F] = 0x83BD, --(莽)
+ [0x4830] = 0x8438, --(è¸)
+ [0x4831] = 0x8506, --(蔆)
+ [0x4832] = 0x83FB, --(è»)
+ [0x4833] = 0x846D, --(è‘­)
+ [0x4834] = 0x842A, --(èª)
+ [0x4835] = 0x843C, --(è¼)
+ [0x4836] = 0x855A, --(è•š)
+ [0x4837] = 0x8484, --(è’„)
+ [0x4838] = 0x8477, --(è‘·)
+ [0x4839] = 0x846B, --(è‘«)
+ [0x483A] = 0x84AD, --(è’­)
+ [0x483B] = 0x846E, --(è‘®)
+ [0x483C] = 0x8482, --(è’‚)
+ [0x483D] = 0x8469, --(è‘©)
+ [0x483E] = 0x8446, --(葆)
+ [0x483F] = 0x842C, --(è¬)
+ [0x4840] = 0x846F, --(葯)
+ [0x4841] = 0x8479, --(葹)
+ [0x4842] = 0x8435, --(èµ)
+ [0x4843] = 0x84CA, --(è“Š)
+ [0x4844] = 0x8462, --(è‘¢)
+ [0x4845] = 0x84B9, --(è’¹)
+ [0x4846] = 0x84BF, --(è’¿)
+ [0x4847] = 0x849F, --(è’Ÿ)
+ [0x4848] = 0x84D9, --(è“™)
+ [0x4849] = 0x84CD, --(è“)
+ [0x484A] = 0x84BB, --(è’»)
+ [0x484B] = 0x84DA, --(è“š)
+ [0x484C] = 0x84D0, --(è“)
+ [0x484D] = 0x84C1, --(è“)
+ [0x484E] = 0x84C6, --(蓆)
+ [0x484F] = 0x84D6, --(è“–)
+ [0x4850] = 0x84A1, --(è’¡)
+ [0x4851] = 0x8521, --(蔡)
+ [0x4852] = 0x84FF, --(è“¿)
+ [0x4853] = 0x84F4, --(è“´)
+ [0x4854] = 0x8517, --(è”—)
+ [0x4855] = 0x8518, --(蔘)
+ [0x4856] = 0x852C, --(蔬)
+ [0x4857] = 0x851F, --(蔟)
+ [0x4858] = 0x8515, --(蔕)
+ [0x4859] = 0x8514, --(è””)
+ [0x485A] = 0x84FC, --(蓼)
+ [0x485B] = 0x8540, --(è•€)
+ [0x485C] = 0x8563, --(è•£)
+ [0x485D] = 0x8558, --(蕘)
+ [0x485E] = 0x8548, --(蕈)
+ [0x4901] = 0x8541, --(è•)
+ [0x4902] = 0x8602, --(蘂)
+ [0x4903] = 0x854B, --(è•‹)
+ [0x4904] = 0x8555, --(è••)
+ [0x4905] = 0x8580, --(è–€)
+ [0x4906] = 0x85A4, --(è–¤)
+ [0x4907] = 0x8588, --(è–ˆ)
+ [0x4908] = 0x8591, --(è–‘)
+ [0x4909] = 0x858A, --(è–Š)
+ [0x490A] = 0x85A8, --(è–¨)
+ [0x490B] = 0x856D, --(è•­)
+ [0x490C] = 0x8594, --(è–”)
+ [0x490D] = 0x859B, --(è–›)
+ [0x490E] = 0x85EA, --(è—ª)
+ [0x490F] = 0x8587, --(è–‡)
+ [0x4910] = 0x859C, --(薜)
+ [0x4911] = 0x8577, --(è•·)
+ [0x4912] = 0x857E, --(蕾)
+ [0x4913] = 0x8590, --(è–)
+ [0x4914] = 0x85C9, --(è—‰)
+ [0x4915] = 0x85BA, --(è–º)
+ [0x4916] = 0x85CF, --(è—)
+ [0x4917] = 0x85B9, --(è–¹)
+ [0x4918] = 0x85D0, --(è—)
+ [0x4919] = 0x85D5, --(è—•)
+ [0x491A] = 0x85DD, --(è—)
+ [0x491B] = 0x85E5, --(è—¥)
+ [0x491C] = 0x85DC, --(藜)
+ [0x491D] = 0x85F9, --(è—¹)
+ [0x491E] = 0x860A, --(蘊)
+ [0x491F] = 0x8613, --(蘓)
+ [0x4920] = 0x860B, --(蘋)
+ [0x4921] = 0x85FE, --(è—¾)
+ [0x4922] = 0x85FA, --(è—º)
+ [0x4923] = 0x8606, --(蘆)
+ [0x4924] = 0x8622, --(蘢)
+ [0x4925] = 0x861A, --(蘚)
+ [0x4926] = 0x8630, --(蘰)
+ [0x4927] = 0x863F, --(蘿)
+ [0x4928] = 0x864D, --(è™)
+ [0x4929] = 0x4E55, --(乕)
+ [0x492A] = 0x8654, --(è™”)
+ [0x492B] = 0x865F, --(號)
+ [0x492C] = 0x8667, --(虧)
+ [0x492D] = 0x8671, --(è™±)
+ [0x492E] = 0x8693, --(èš“)
+ [0x492F] = 0x86A3, --(蚣)
+ [0x4930] = 0x86A9, --(èš©)
+ [0x4931] = 0x86AA, --(蚪)
+ [0x4932] = 0x868B, --(èš‹)
+ [0x4933] = 0x868C, --(蚌)
+ [0x4934] = 0x86B6, --(蚶)
+ [0x4935] = 0x86AF, --(蚯)
+ [0x4936] = 0x86C4, --(蛄)
+ [0x4937] = 0x86C6, --(蛆)
+ [0x4938] = 0x86B0, --(èš°)
+ [0x4939] = 0x86C9, --(蛉)
+ [0x493A] = 0x8823, --(è £)
+ [0x493B] = 0x86AB, --(èš«)
+ [0x493C] = 0x86D4, --(è›”)
+ [0x493D] = 0x86DE, --(蛞)
+ [0x493E] = 0x86E9, --(蛩)
+ [0x493F] = 0x86EC, --(蛬)
+ [0x4940] = 0x86DF, --(蛟)
+ [0x4941] = 0x86DB, --(è››)
+ [0x4942] = 0x86EF, --(蛯)
+ [0x4943] = 0x8712, --(蜒)
+ [0x4944] = 0x8706, --(蜆)
+ [0x4945] = 0x8708, --(蜈)
+ [0x4946] = 0x8700, --(蜀)
+ [0x4947] = 0x8703, --(蜃)
+ [0x4948] = 0x86FB, --(è›»)
+ [0x4949] = 0x8711, --(蜑)
+ [0x494A] = 0x8709, --(蜉)
+ [0x494B] = 0x870D, --(èœ)
+ [0x494C] = 0x86F9, --(蛹)
+ [0x494D] = 0x870A, --(蜊)
+ [0x494E] = 0x8734, --(蜴)
+ [0x494F] = 0x873F, --(蜿)
+ [0x4950] = 0x8737, --(蜷)
+ [0x4951] = 0x873B, --(蜻)
+ [0x4952] = 0x8725, --(蜥)
+ [0x4953] = 0x8729, --(蜩)
+ [0x4954] = 0x871A, --(蜚)
+ [0x4955] = 0x8760, --(è )
+ [0x4956] = 0x875F, --(èŸ)
+ [0x4957] = 0x8778, --(è¸)
+ [0x4958] = 0x874C, --(èŒ)
+ [0x4959] = 0x874E, --(èŽ)
+ [0x495A] = 0x8774, --(è´)
+ [0x495B] = 0x8757, --(è—)
+ [0x495C] = 0x8768, --(è¨)
+ [0x495D] = 0x876E, --(è®)
+ [0x495E] = 0x8759, --(è™)
+ [0x4A01] = 0x8753, --(è“)
+ [0x4A02] = 0x8763, --(è£)
+ [0x4A03] = 0x876A, --(èª)
+ [0x4A04] = 0x8805, --(è …)
+ [0x4A05] = 0x87A2, --(螢)
+ [0x4A06] = 0x879F, --(螟)
+ [0x4A07] = 0x8782, --(èž‚)
+ [0x4A08] = 0x87AF, --(螯)
+ [0x4A09] = 0x87CB, --(蟋)
+ [0x4A0A] = 0x87BD, --(èž½)
+ [0x4A0B] = 0x87C0, --(蟀)
+ [0x4A0C] = 0x87D0, --(èŸ)
+ [0x4A0D] = 0x96D6, --(é›–)
+ [0x4A0E] = 0x87AB, --(èž«)
+ [0x4A0F] = 0x87C4, --(蟄)
+ [0x4A10] = 0x87B3, --(èž³)
+ [0x4A11] = 0x87C7, --(蟇)
+ [0x4A12] = 0x87C6, --(蟆)
+ [0x4A13] = 0x87BB, --(èž»)
+ [0x4A14] = 0x87EF, --(蟯)
+ [0x4A15] = 0x87F2, --(蟲)
+ [0x4A16] = 0x87E0, --(蟠)
+ [0x4A17] = 0x880F, --(è )
+ [0x4A18] = 0x880D, --(è )
+ [0x4A19] = 0x87FE, --(蟾)
+ [0x4A1A] = 0x87F6, --(蟶)
+ [0x4A1B] = 0x87F7, --(蟷)
+ [0x4A1C] = 0x880E, --(è Ž)
+ [0x4A1D] = 0x87D2, --(蟒)
+ [0x4A1E] = 0x8811, --(è ‘)
+ [0x4A1F] = 0x8816, --(è –)
+ [0x4A20] = 0x8815, --(è •)
+ [0x4A21] = 0x8822, --(è ¢)
+ [0x4A22] = 0x8821, --(è ¡)
+ [0x4A23] = 0x8831, --(è ±)
+ [0x4A24] = 0x8836, --(è ¶)
+ [0x4A25] = 0x8839, --(è ¹)
+ [0x4A26] = 0x8827, --(è §)
+ [0x4A27] = 0x883B, --(è »)
+ [0x4A28] = 0x8844, --(è¡„)
+ [0x4A29] = 0x8842, --(è¡‚)
+ [0x4A2A] = 0x8852, --(è¡’)
+ [0x4A2B] = 0x8859, --(è¡™)
+ [0x4A2C] = 0x885E, --(è¡ž)
+ [0x4A2D] = 0x8862, --(è¡¢)
+ [0x4A2E] = 0x886B, --(è¡«)
+ [0x4A2F] = 0x8881, --(è¢)
+ [0x4A30] = 0x887E, --(衾)
+ [0x4A31] = 0x889E, --(袞)
+ [0x4A32] = 0x8875, --(衵)
+ [0x4A33] = 0x887D, --(衽)
+ [0x4A34] = 0x88B5, --(袵)
+ [0x4A35] = 0x8872, --(衲)
+ [0x4A36] = 0x8882, --(袂)
+ [0x4A37] = 0x8897, --(袗)
+ [0x4A38] = 0x8892, --(袒)
+ [0x4A39] = 0x88AE, --(袮)
+ [0x4A3A] = 0x8899, --(袙)
+ [0x4A3B] = 0x88A2, --(袢)
+ [0x4A3C] = 0x888D, --(è¢)
+ [0x4A3D] = 0x88A4, --(袤)
+ [0x4A3E] = 0x88B0, --(袰)
+ [0x4A3F] = 0x88BF, --(袿)
+ [0x4A40] = 0x88B1, --(袱)
+ [0x4A41] = 0x88C3, --(裃)
+ [0x4A42] = 0x88C4, --(裄)
+ [0x4A43] = 0x88D4, --(裔)
+ [0x4A44] = 0x88D8, --(裘)
+ [0x4A45] = 0x88D9, --(裙)
+ [0x4A46] = 0x88DD, --(è£)
+ [0x4A47] = 0x88F9, --(裹)
+ [0x4A48] = 0x8902, --(褂)
+ [0x4A49] = 0x88FC, --(裼)
+ [0x4A4A] = 0x88F4, --(裴)
+ [0x4A4B] = 0x88E8, --(裨)
+ [0x4A4C] = 0x88F2, --(裲)
+ [0x4A4D] = 0x8904, --(褄)
+ [0x4A4E] = 0x890C, --(褌)
+ [0x4A4F] = 0x890A, --(褊)
+ [0x4A50] = 0x8913, --(褓)
+ [0x4A51] = 0x8943, --(襃)
+ [0x4A52] = 0x891E, --(褞)
+ [0x4A53] = 0x8925, --(褥)
+ [0x4A54] = 0x892A, --(褪)
+ [0x4A55] = 0x892B, --(褫)
+ [0x4A56] = 0x8941, --(è¥)
+ [0x4A57] = 0x8944, --(襄)
+ [0x4A58] = 0x893B, --(褻)
+ [0x4A59] = 0x8936, --(褶)
+ [0x4A5A] = 0x8938, --(褸)
+ [0x4A5B] = 0x894C, --(襌)
+ [0x4A5C] = 0x891D, --(è¤)
+ [0x4A5D] = 0x8960, --(襠)
+ [0x4A5E] = 0x895E, --(襞)
+ [0x4B01] = 0x8966, --(襦)
+ [0x4B02] = 0x8964, --(襤)
+ [0x4B03] = 0x896D, --(襭)
+ [0x4B04] = 0x896A, --(襪)
+ [0x4B05] = 0x896F, --(襯)
+ [0x4B06] = 0x8974, --(襴)
+ [0x4B07] = 0x8977, --(襷)
+ [0x4B08] = 0x897E, --(襾)
+ [0x4B09] = 0x8983, --(覃)
+ [0x4B0A] = 0x8988, --(覈)
+ [0x4B0B] = 0x898A, --(覊)
+ [0x4B0C] = 0x8993, --(覓)
+ [0x4B0D] = 0x8998, --(覘)
+ [0x4B0E] = 0x89A1, --(覡)
+ [0x4B0F] = 0x89A9, --(覩)
+ [0x4B10] = 0x89A6, --(覦)
+ [0x4B11] = 0x89AC, --(覬)
+ [0x4B12] = 0x89AF, --(覯)
+ [0x4B13] = 0x89B2, --(覲)
+ [0x4B14] = 0x89BA, --(覺)
+ [0x4B15] = 0x89BD, --(覽)
+ [0x4B16] = 0x89BF, --(覿)
+ [0x4B17] = 0x89C0, --(觀)
+ [0x4B18] = 0x89DA, --(觚)
+ [0x4B19] = 0x89DC, --(觜)
+ [0x4B1A] = 0x89DD, --(è§)
+ [0x4B1B] = 0x89E7, --(觧)
+ [0x4B1C] = 0x89F4, --(觴)
+ [0x4B1D] = 0x89F8, --(觸)
+ [0x4B1E] = 0x8A03, --(訃)
+ [0x4B1F] = 0x8A16, --(訖)
+ [0x4B20] = 0x8A10, --(è¨)
+ [0x4B21] = 0x8A0C, --(訌)
+ [0x4B22] = 0x8A1B, --(訛)
+ [0x4B23] = 0x8A1D, --(è¨)
+ [0x4B24] = 0x8A25, --(訥)
+ [0x4B25] = 0x8A36, --(訶)
+ [0x4B26] = 0x8A41, --(è©)
+ [0x4B27] = 0x8A5B, --(è©›)
+ [0x4B28] = 0x8A52, --(è©’)
+ [0x4B29] = 0x8A46, --(詆)
+ [0x4B2A] = 0x8A48, --(詈)
+ [0x4B2B] = 0x8A7C, --(詼)
+ [0x4B2C] = 0x8A6D, --(è©­)
+ [0x4B2D] = 0x8A6C, --(詬)
+ [0x4B2E] = 0x8A62, --(è©¢)
+ [0x4B2F] = 0x8A85, --(誅)
+ [0x4B30] = 0x8A82, --(誂)
+ [0x4B31] = 0x8A84, --(誄)
+ [0x4B32] = 0x8AA8, --(誨)
+ [0x4B33] = 0x8AA1, --(誡)
+ [0x4B34] = 0x8A91, --(誑)
+ [0x4B35] = 0x8AA5, --(誥)
+ [0x4B36] = 0x8AA6, --(誦)
+ [0x4B37] = 0x8A9A, --(誚)
+ [0x4B38] = 0x8AA3, --(誣)
+ [0x4B39] = 0x8AC4, --(è«„)
+ [0x4B3A] = 0x8ACD, --(è«)
+ [0x4B3B] = 0x8AC2, --(è«‚)
+ [0x4B3C] = 0x8ADA, --(è«š)
+ [0x4B3D] = 0x8AEB, --(è««)
+ [0x4B3E] = 0x8AF3, --(諳)
+ [0x4B3F] = 0x8AE7, --(諧)
+ [0x4B40] = 0x8AE4, --(諤)
+ [0x4B41] = 0x8AF1, --(諱)
+ [0x4B42] = 0x8B14, --(謔)
+ [0x4B43] = 0x8AE0, --(è« )
+ [0x4B44] = 0x8AE2, --(è«¢)
+ [0x4B45] = 0x8AF7, --(è«·)
+ [0x4B46] = 0x8ADE, --(è«ž)
+ [0x4B47] = 0x8ADB, --(è«›)
+ [0x4B48] = 0x8B0C, --(謌)
+ [0x4B49] = 0x8B07, --(謇)
+ [0x4B4A] = 0x8B1A, --(謚)
+ [0x4B4B] = 0x8AE1, --(è«¡)
+ [0x4B4C] = 0x8B16, --(謖)
+ [0x4B4D] = 0x8B10, --(è¬)
+ [0x4B4E] = 0x8B17, --(謗)
+ [0x4B4F] = 0x8B20, --(謠)
+ [0x4B50] = 0x8B33, --(謳)
+ [0x4B51] = 0x97AB, --(éž«)
+ [0x4B52] = 0x8B26, --(謦)
+ [0x4B53] = 0x8B2B, --(謫)
+ [0x4B54] = 0x8B3E, --(謾)
+ [0x4B55] = 0x8B28, --(謨)
+ [0x4B56] = 0x8B41, --(è­)
+ [0x4B57] = 0x8B4C, --(譌)
+ [0x4B58] = 0x8B4F, --(è­)
+ [0x4B59] = 0x8B4E, --(è­Ž)
+ [0x4B5A] = 0x8B49, --(è­‰)
+ [0x4B5B] = 0x8B56, --(è­–)
+ [0x4B5C] = 0x8B5B, --(è­›)
+ [0x4B5D] = 0x8B5A, --(è­š)
+ [0x4B5E] = 0x8B6B, --(è­«)
+ [0x4C01] = 0x8B5F, --(è­Ÿ)
+ [0x4C02] = 0x8B6C, --(è­¬)
+ [0x4C03] = 0x8B6F, --(è­¯)
+ [0x4C04] = 0x8B74, --(è­´)
+ [0x4C05] = 0x8B7D, --(è­½)
+ [0x4C06] = 0x8B80, --(讀)
+ [0x4C07] = 0x8B8C, --(讌)
+ [0x4C08] = 0x8B8E, --(讎)
+ [0x4C09] = 0x8B92, --(è®’)
+ [0x4C0A] = 0x8B93, --(讓)
+ [0x4C0B] = 0x8B96, --(è®–)
+ [0x4C0C] = 0x8B99, --(è®™)
+ [0x4C0D] = 0x8B9A, --(讚)
+ [0x4C0E] = 0x8C3A, --(è°º)
+ [0x4C0F] = 0x8C41, --(è±)
+ [0x4C10] = 0x8C3F, --(è°¿)
+ [0x4C11] = 0x8C48, --(豈)
+ [0x4C12] = 0x8C4C, --(豌)
+ [0x4C13] = 0x8C4E, --(豎)
+ [0x4C14] = 0x8C50, --(è±)
+ [0x4C15] = 0x8C55, --(豕)
+ [0x4C16] = 0x8C62, --(è±¢)
+ [0x4C17] = 0x8C6C, --(豬)
+ [0x4C18] = 0x8C78, --(豸)
+ [0x4C19] = 0x8C7A, --(豺)
+ [0x4C1A] = 0x8C82, --(貂)
+ [0x4C1B] = 0x8C89, --(貉)
+ [0x4C1C] = 0x8C85, --(è²…)
+ [0x4C1D] = 0x8C8A, --(貊)
+ [0x4C1E] = 0x8C8D, --(è²)
+ [0x4C1F] = 0x8C8E, --(貎)
+ [0x4C20] = 0x8C94, --(è²”)
+ [0x4C21] = 0x8C7C, --(è±¼)
+ [0x4C22] = 0x8C98, --(貘)
+ [0x4C23] = 0x621D, --(æˆ)
+ [0x4C24] = 0x8CAD, --(è²­)
+ [0x4C25] = 0x8CAA, --(貪)
+ [0x4C26] = 0x8CBD, --(è²½)
+ [0x4C27] = 0x8CB2, --(è²²)
+ [0x4C28] = 0x8CB3, --(è²³)
+ [0x4C29] = 0x8CAE, --(è²®)
+ [0x4C2A] = 0x8CB6, --(貶)
+ [0x4C2B] = 0x8CC8, --(賈)
+ [0x4C2C] = 0x8CC1, --(è³)
+ [0x4C2D] = 0x8CE4, --(賤)
+ [0x4C2E] = 0x8CE3, --(è³£)
+ [0x4C2F] = 0x8CDA, --(賚)
+ [0x4C30] = 0x8CFD, --(è³½)
+ [0x4C31] = 0x8CFA, --(賺)
+ [0x4C32] = 0x8CFB, --(è³»)
+ [0x4C33] = 0x8D04, --(è´„)
+ [0x4C34] = 0x8D05, --(è´…)
+ [0x4C35] = 0x8D0A, --(è´Š)
+ [0x4C36] = 0x8D07, --(è´‡)
+ [0x4C37] = 0x8D0F, --(è´)
+ [0x4C38] = 0x8D0D, --(è´)
+ [0x4C39] = 0x8D10, --(è´)
+ [0x4C3A] = 0x9F4E, --(齎)
+ [0x4C3B] = 0x8D13, --(è´“)
+ [0x4C3C] = 0x8CCD, --(è³)
+ [0x4C3D] = 0x8D14, --(è´”)
+ [0x4C3E] = 0x8D16, --(è´–)
+ [0x4C3F] = 0x8D67, --(赧)
+ [0x4C40] = 0x8D6D, --(èµ­)
+ [0x4C41] = 0x8D71, --(èµ±)
+ [0x4C42] = 0x8D73, --(èµ³)
+ [0x4C43] = 0x8D81, --(è¶)
+ [0x4C44] = 0x8D99, --(趙)
+ [0x4C45] = 0x8DC2, --(è·‚)
+ [0x4C46] = 0x8DBE, --(趾)
+ [0x4C47] = 0x8DBA, --(趺)
+ [0x4C48] = 0x8DCF, --(è·)
+ [0x4C49] = 0x8DDA, --(è·š)
+ [0x4C4A] = 0x8DD6, --(è·–)
+ [0x4C4B] = 0x8DCC, --(跌)
+ [0x4C4C] = 0x8DDB, --(è·›)
+ [0x4C4D] = 0x8DCB, --(è·‹)
+ [0x4C4E] = 0x8DEA, --(è·ª)
+ [0x4C4F] = 0x8DEB, --(è·«)
+ [0x4C50] = 0x8DDF, --(è·Ÿ)
+ [0x4C51] = 0x8DE3, --(è·£)
+ [0x4C52] = 0x8DFC, --(è·¼)
+ [0x4C53] = 0x8E08, --(踈)
+ [0x4C54] = 0x8E09, --(踉)
+ [0x4C55] = 0x8DFF, --(è·¿)
+ [0x4C56] = 0x8E1D, --(è¸)
+ [0x4C57] = 0x8E1E, --(踞)
+ [0x4C58] = 0x8E10, --(è¸)
+ [0x4C59] = 0x8E1F, --(踟)
+ [0x4C5A] = 0x8E42, --(蹂)
+ [0x4C5B] = 0x8E35, --(踵)
+ [0x4C5C] = 0x8E30, --(踰)
+ [0x4C5D] = 0x8E34, --(踴)
+ [0x4C5E] = 0x8E4A, --(蹊)
+ [0x4D01] = 0x8E47, --(蹇)
+ [0x4D02] = 0x8E49, --(蹉)
+ [0x4D03] = 0x8E4C, --(蹌)
+ [0x4D04] = 0x8E50, --(è¹)
+ [0x4D05] = 0x8E48, --(蹈)
+ [0x4D06] = 0x8E59, --(è¹™)
+ [0x4D07] = 0x8E64, --(蹤)
+ [0x4D08] = 0x8E60, --(è¹ )
+ [0x4D09] = 0x8E2A, --(踪)
+ [0x4D0A] = 0x8E63, --(è¹£)
+ [0x4D0B] = 0x8E55, --(蹕)
+ [0x4D0C] = 0x8E76, --(蹶)
+ [0x4D0D] = 0x8E72, --(è¹²)
+ [0x4D0E] = 0x8E7C, --(è¹¼)
+ [0x4D0F] = 0x8E81, --(èº)
+ [0x4D10] = 0x8E87, --(躇)
+ [0x4D11] = 0x8E85, --(躅)
+ [0x4D12] = 0x8E84, --(躄)
+ [0x4D13] = 0x8E8B, --(躋)
+ [0x4D14] = 0x8E8A, --(躊)
+ [0x4D15] = 0x8E93, --(躓)
+ [0x4D16] = 0x8E91, --(躑)
+ [0x4D17] = 0x8E94, --(躔)
+ [0x4D18] = 0x8E99, --(躙)
+ [0x4D19] = 0x8EAA, --(躪)
+ [0x4D1A] = 0x8EA1, --(躡)
+ [0x4D1B] = 0x8EAC, --(躬)
+ [0x4D1C] = 0x8EB0, --(躰)
+ [0x4D1D] = 0x8EC6, --(軆)
+ [0x4D1E] = 0x8EB1, --(躱)
+ [0x4D1F] = 0x8EBE, --(躾)
+ [0x4D20] = 0x8EC5, --(è»…)
+ [0x4D21] = 0x8EC8, --(軈)
+ [0x4D22] = 0x8ECB, --(軋)
+ [0x4D23] = 0x8EDB, --(è»›)
+ [0x4D24] = 0x8EE3, --(軣)
+ [0x4D25] = 0x8EFC, --(軼)
+ [0x4D26] = 0x8EFB, --(è»»)
+ [0x4D27] = 0x8EEB, --(軫)
+ [0x4D28] = 0x8EFE, --(軾)
+ [0x4D29] = 0x8F0A, --(輊)
+ [0x4D2A] = 0x8F05, --(è¼…)
+ [0x4D2B] = 0x8F15, --(輕)
+ [0x4D2C] = 0x8F12, --(è¼’)
+ [0x4D2D] = 0x8F19, --(è¼™)
+ [0x4D2E] = 0x8F13, --(輓)
+ [0x4D2F] = 0x8F1C, --(輜)
+ [0x4D30] = 0x8F1F, --(輟)
+ [0x4D31] = 0x8F1B, --(è¼›)
+ [0x4D32] = 0x8F0C, --(輌)
+ [0x4D33] = 0x8F26, --(輦)
+ [0x4D34] = 0x8F33, --(è¼³)
+ [0x4D35] = 0x8F3B, --(è¼»)
+ [0x4D36] = 0x8F39, --(è¼¹)
+ [0x4D37] = 0x8F45, --(è½…)
+ [0x4D38] = 0x8F42, --(轂)
+ [0x4D39] = 0x8F3E, --(è¼¾)
+ [0x4D3A] = 0x8F4C, --(轌)
+ [0x4D3B] = 0x8F49, --(轉)
+ [0x4D3C] = 0x8F46, --(轆)
+ [0x4D3D] = 0x8F4E, --(轎)
+ [0x4D3E] = 0x8F57, --(è½—)
+ [0x4D3F] = 0x8F5C, --(轜)
+ [0x4D40] = 0x8F62, --(è½¢)
+ [0x4D41] = 0x8F63, --(è½£)
+ [0x4D42] = 0x8F64, --(轤)
+ [0x4D43] = 0x8F9C, --(辜)
+ [0x4D44] = 0x8F9F, --(辟)
+ [0x4D45] = 0x8FA3, --(è¾£)
+ [0x4D46] = 0x8FAD, --(è¾­)
+ [0x4D47] = 0x8FAF, --(辯)
+ [0x4D48] = 0x8FB7, --(è¾·)
+ [0x4D49] = 0x8FDA, --(è¿š)
+ [0x4D4A] = 0x8FE5, --(è¿¥)
+ [0x4D4B] = 0x8FE2, --(è¿¢)
+ [0x4D4C] = 0x8FEA, --(迪)
+ [0x4D4D] = 0x8FEF, --(迯)
+ [0x4D4E] = 0x9087, --(邇)
+ [0x4D4F] = 0x8FF4, --(è¿´)
+ [0x4D50] = 0x9005, --(逅)
+ [0x4D51] = 0x8FF9, --(迹)
+ [0x4D52] = 0x8FFA, --(迺)
+ [0x4D53] = 0x9011, --(逑)
+ [0x4D54] = 0x9015, --(逕)
+ [0x4D55] = 0x9021, --(逡)
+ [0x4D56] = 0x900D, --(é€)
+ [0x4D57] = 0x901E, --(逞)
+ [0x4D58] = 0x9016, --(逖)
+ [0x4D59] = 0x900B, --(逋)
+ [0x4D5A] = 0x9027, --(逧)
+ [0x4D5B] = 0x9036, --(逶)
+ [0x4D5C] = 0x9035, --(逵)
+ [0x4D5D] = 0x9039, --(逹)
+ [0x4D5E] = 0x8FF8, --(迸)
+ [0x4E01] = 0x904F, --(é)
+ [0x4E02] = 0x9050, --(é)
+ [0x4E03] = 0x9051, --(é‘)
+ [0x4E04] = 0x9052, --(é’)
+ [0x4E05] = 0x900E, --(逎)
+ [0x4E06] = 0x9049, --(é‰)
+ [0x4E07] = 0x903E, --(逾)
+ [0x4E08] = 0x9056, --(é–)
+ [0x4E09] = 0x9058, --(é˜)
+ [0x4E0A] = 0x905E, --(éž)
+ [0x4E0B] = 0x9068, --(é¨)
+ [0x4E0C] = 0x906F, --(é¯)
+ [0x4E0D] = 0x9076, --(é¶)
+ [0x4E0E] = 0x96A8, --(隨)
+ [0x4E0F] = 0x9072, --(é²)
+ [0x4E10] = 0x9082, --(é‚‚)
+ [0x4E11] = 0x907D, --(é½)
+ [0x4E12] = 0x9081, --(é‚)
+ [0x4E13] = 0x9080, --(é‚€)
+ [0x4E14] = 0x908A, --(é‚Š)
+ [0x4E15] = 0x9089, --(邉)
+ [0x4E16] = 0x908F, --(é‚)
+ [0x4E17] = 0x90A8, --(邨)
+ [0x4E18] = 0x90AF, --(邯)
+ [0x4E19] = 0x90B1, --(邱)
+ [0x4E1A] = 0x90B5, --(邵)
+ [0x4E1B] = 0x90E2, --(郢)
+ [0x4E1C] = 0x90E4, --(郤)
+ [0x4E1D] = 0x6248, --(扈)
+ [0x4E1E] = 0x90DB, --(郛)
+ [0x4E1F] = 0x9102, --(é„‚)
+ [0x4E20] = 0x9112, --(é„’)
+ [0x4E21] = 0x9119, --(é„™)
+ [0x4E22] = 0x9132, --(鄲)
+ [0x4E23] = 0x9130, --(é„°)
+ [0x4E24] = 0x914A, --(é…Š)
+ [0x4E25] = 0x9156, --(é…–)
+ [0x4E26] = 0x9158, --(é…˜)
+ [0x4E27] = 0x9163, --(é…£)
+ [0x4E28] = 0x9165, --(é…¥)
+ [0x4E29] = 0x9169, --(é…©)
+ [0x4E2A] = 0x9173, --(é…³)
+ [0x4E2B] = 0x9172, --(é…²)
+ [0x4E2C] = 0x918B, --(醋)
+ [0x4E2D] = 0x9189, --(醉)
+ [0x4E2E] = 0x9182, --(醂)
+ [0x4E2F] = 0x91A2, --(醢)
+ [0x4E30] = 0x91AB, --(醫)
+ [0x4E31] = 0x91AF, --(醯)
+ [0x4E32] = 0x91AA, --(醪)
+ [0x4E33] = 0x91B5, --(醵)
+ [0x4E34] = 0x91B4, --(醴)
+ [0x4E35] = 0x91BA, --(醺)
+ [0x4E36] = 0x91C0, --(釀)
+ [0x4E37] = 0x91C1, --(é‡)
+ [0x4E38] = 0x91C9, --(釉)
+ [0x4E39] = 0x91CB, --(釋)
+ [0x4E3A] = 0x91D0, --(é‡)
+ [0x4E3B] = 0x91D6, --(釖)
+ [0x4E3C] = 0x91DF, --(釟)
+ [0x4E3D] = 0x91E1, --(釡)
+ [0x4E3E] = 0x91DB, --(釛)
+ [0x4E3F] = 0x91FC, --(釼)
+ [0x4E40] = 0x91F5, --(釵)
+ [0x4E41] = 0x91F6, --(釶)
+ [0x4E42] = 0x921E, --(鈞)
+ [0x4E43] = 0x91FF, --(釿)
+ [0x4E44] = 0x9214, --(鈔)
+ [0x4E45] = 0x922C, --(鈬)
+ [0x4E46] = 0x9215, --(鈕)
+ [0x4E47] = 0x9211, --(鈑)
+ [0x4E48] = 0x925E, --(鉞)
+ [0x4E49] = 0x9257, --(鉗)
+ [0x4E4A] = 0x9245, --(鉅)
+ [0x4E4B] = 0x9249, --(鉉)
+ [0x4E4C] = 0x9264, --(鉤)
+ [0x4E4D] = 0x9248, --(鉈)
+ [0x4E4E] = 0x9295, --(銕)
+ [0x4E4F] = 0x923F, --(鈿)
+ [0x4E50] = 0x924B, --(鉋)
+ [0x4E51] = 0x9250, --(é‰)
+ [0x4E52] = 0x929C, --(銜)
+ [0x4E53] = 0x9296, --(銖)
+ [0x4E54] = 0x9293, --(銓)
+ [0x4E55] = 0x929B, --(銛)
+ [0x4E56] = 0x925A, --(鉚)
+ [0x4E57] = 0x92CF, --(é‹)
+ [0x4E58] = 0x92B9, --(銹)
+ [0x4E59] = 0x92B7, --(銷)
+ [0x4E5A] = 0x92E9, --(é‹©)
+ [0x4E5B] = 0x930F, --(éŒ)
+ [0x4E5C] = 0x92FA, --(鋺)
+ [0x4E5D] = 0x9344, --(é„)
+ [0x4E5E] = 0x932E, --(錮)
+ [0x4F01] = 0x9319, --(錙)
+ [0x4F02] = 0x9322, --(錢)
+ [0x4F03] = 0x931A, --(錚)
+ [0x4F04] = 0x9323, --(錣)
+ [0x4F05] = 0x933A, --(錺)
+ [0x4F06] = 0x9335, --(錵)
+ [0x4F07] = 0x933B, --(錻)
+ [0x4F08] = 0x935C, --(éœ)
+ [0x4F09] = 0x9360, --(é )
+ [0x4F0A] = 0x937C, --(é¼)
+ [0x4F0B] = 0x936E, --(é®)
+ [0x4F0C] = 0x9356, --(é–)
+ [0x4F0D] = 0x93B0, --(鎰)
+ [0x4F0E] = 0x93AC, --(鎬)
+ [0x4F0F] = 0x93AD, --(鎭)
+ [0x4F10] = 0x9394, --(鎔)
+ [0x4F11] = 0x93B9, --(鎹)
+ [0x4F12] = 0x93D6, --(é–)
+ [0x4F13] = 0x93D7, --(é—)
+ [0x4F14] = 0x93E8, --(é¨)
+ [0x4F15] = 0x93E5, --(é¥)
+ [0x4F16] = 0x93D8, --(é˜)
+ [0x4F17] = 0x93C3, --(éƒ)
+ [0x4F18] = 0x93DD, --(é)
+ [0x4F19] = 0x93D0, --(é)
+ [0x4F1A] = 0x93C8, --(éˆ)
+ [0x4F1B] = 0x93E4, --(é¤)
+ [0x4F1C] = 0x941A, --(éš)
+ [0x4F1D] = 0x9414, --(é”)
+ [0x4F1E] = 0x9413, --(é“)
+ [0x4F1F] = 0x9403, --(éƒ)
+ [0x4F20] = 0x9407, --(é‡)
+ [0x4F21] = 0x9410, --(é)
+ [0x4F22] = 0x9436, --(é¶)
+ [0x4F23] = 0x942B, --(é«)
+ [0x4F24] = 0x9435, --(éµ)
+ [0x4F25] = 0x9421, --(é¡)
+ [0x4F26] = 0x943A, --(éº)
+ [0x4F27] = 0x9441, --(é‘)
+ [0x4F28] = 0x9452, --(é‘’)
+ [0x4F29] = 0x9444, --(é‘„)
+ [0x4F2A] = 0x945B, --(é‘›)
+ [0x4F2B] = 0x9460, --(é‘ )
+ [0x4F2C] = 0x9462, --(é‘¢)
+ [0x4F2D] = 0x945E, --(é‘ž)
+ [0x4F2E] = 0x946A, --(鑪)
+ [0x4F2F] = 0x9229, --(鈩)
+ [0x4F30] = 0x9470, --(é‘°)
+ [0x4F31] = 0x9475, --(鑵)
+ [0x4F32] = 0x9477, --(é‘·)
+ [0x4F33] = 0x947D, --(鑽)
+ [0x4F34] = 0x945A, --(é‘š)
+ [0x4F35] = 0x947C, --(鑼)
+ [0x4F36] = 0x947E, --(鑾)
+ [0x4F37] = 0x9481, --(é’)
+ [0x4F38] = 0x947F, --(é‘¿)
+ [0x4F39] = 0x9582, --(é–‚)
+ [0x4F3A] = 0x9587, --(é–‡)
+ [0x4F3B] = 0x958A, --(é–Š)
+ [0x4F3C] = 0x9594, --(é–”)
+ [0x4F3D] = 0x9596, --(é––)
+ [0x4F3E] = 0x9598, --(é–˜)
+ [0x4F3F] = 0x9599, --(é–™)
+ [0x4F40] = 0x95A0, --(é– )
+ [0x4F41] = 0x95A8, --(é–¨)
+ [0x4F42] = 0x95A7, --(é–§)
+ [0x4F43] = 0x95AD, --(é–­)
+ [0x4F44] = 0x95BC, --(é–¼)
+ [0x4F45] = 0x95BB, --(é–»)
+ [0x4F46] = 0x95B9, --(é–¹)
+ [0x4F47] = 0x95BE, --(é–¾)
+ [0x4F48] = 0x95CA, --(é—Š)
+ [0x4F49] = 0x6FF6, --(濶)
+ [0x4F4A] = 0x95C3, --(é—ƒ)
+ [0x4F4B] = 0x95CD, --(é—)
+ [0x4F4C] = 0x95CC, --(闌)
+ [0x4F4D] = 0x95D5, --(é—•)
+ [0x4F4E] = 0x95D4, --(é—”)
+ [0x4F4F] = 0x95D6, --(é—–)
+ [0x4F50] = 0x95DC, --(關)
+ [0x4F51] = 0x95E1, --(é—¡)
+ [0x4F52] = 0x95E5, --(é—¥)
+ [0x4F53] = 0x95E2, --(é—¢)
+ [0x4F54] = 0x9621, --(阡)
+ [0x4F55] = 0x9628, --(阨)
+ [0x4F56] = 0x962E, --(阮)
+ [0x4F57] = 0x962F, --(阯)
+ [0x4F58] = 0x9642, --(陂)
+ [0x4F59] = 0x964C, --(陌)
+ [0x4F5A] = 0x964F, --(é™)
+ [0x4F5B] = 0x964B, --(陋)
+ [0x4F5C] = 0x9677, --(é™·)
+ [0x4F5D] = 0x965C, --(陜)
+ [0x4F5E] = 0x965E, --(陞)
+ [0x5001] = 0x965D, --(é™)
+ [0x5002] = 0x965F, --(陟)
+ [0x5003] = 0x9666, --(陦)
+ [0x5004] = 0x9672, --(陲)
+ [0x5005] = 0x966C, --(陬)
+ [0x5006] = 0x968D, --(éš)
+ [0x5007] = 0x9698, --(隘)
+ [0x5008] = 0x9695, --(éš•)
+ [0x5009] = 0x9697, --(éš—)
+ [0x500A] = 0x96AA, --(險)
+ [0x500B] = 0x96A7, --(隧)
+ [0x500C] = 0x96B1, --(éš±)
+ [0x500D] = 0x96B2, --(éš²)
+ [0x500E] = 0x96B0, --(éš°)
+ [0x500F] = 0x96B4, --(éš´)
+ [0x5010] = 0x96B6, --(隶)
+ [0x5011] = 0x96B8, --(隸)
+ [0x5012] = 0x96B9, --(éš¹)
+ [0x5013] = 0x96CE, --(雎)
+ [0x5014] = 0x96CB, --(雋)
+ [0x5015] = 0x96C9, --(雉)
+ [0x5016] = 0x96CD, --(é›)
+ [0x5017] = 0x894D, --(è¥)
+ [0x5018] = 0x96DC, --(雜)
+ [0x5019] = 0x970D, --(éœ)
+ [0x501A] = 0x96D5, --(雕)
+ [0x501B] = 0x96F9, --(雹)
+ [0x501C] = 0x9704, --(霄)
+ [0x501D] = 0x9706, --(霆)
+ [0x501E] = 0x9708, --(霈)
+ [0x501F] = 0x9713, --(霓)
+ [0x5020] = 0x970E, --(霎)
+ [0x5021] = 0x9711, --(霑)
+ [0x5022] = 0x970F, --(éœ)
+ [0x5023] = 0x9716, --(霖)
+ [0x5024] = 0x9719, --(霙)
+ [0x5025] = 0x9724, --(霤)
+ [0x5026] = 0x972A, --(霪)
+ [0x5027] = 0x9730, --(霰)
+ [0x5028] = 0x9739, --(霹)
+ [0x5029] = 0x973D, --(霽)
+ [0x502A] = 0x973E, --(霾)
+ [0x502B] = 0x9744, --(é„)
+ [0x502C] = 0x9746, --(é†)
+ [0x502D] = 0x9748, --(éˆ)
+ [0x502E] = 0x9742, --(é‚)
+ [0x502F] = 0x9749, --(é‰)
+ [0x5030] = 0x975C, --(éœ)
+ [0x5031] = 0x9760, --(é )
+ [0x5032] = 0x9764, --(é¤)
+ [0x5033] = 0x9766, --(é¦)
+ [0x5034] = 0x9768, --(é¨)
+ [0x5035] = 0x52D2, --(å‹’)
+ [0x5036] = 0x976B, --(é«)
+ [0x5037] = 0x9771, --(é±)
+ [0x5038] = 0x9779, --(é¹)
+ [0x5039] = 0x9785, --(éž…)
+ [0x503A] = 0x977C, --(é¼)
+ [0x503B] = 0x9781, --(éž)
+ [0x503C] = 0x977A, --(éº)
+ [0x503D] = 0x9786, --(鞆)
+ [0x503E] = 0x978B, --(éž‹)
+ [0x503F] = 0x978F, --(éž)
+ [0x5040] = 0x9790, --(éž)
+ [0x5041] = 0x979C, --(鞜)
+ [0x5042] = 0x97A8, --(鞨)
+ [0x5043] = 0x97A6, --(鞦)
+ [0x5044] = 0x97A3, --(鞣)
+ [0x5045] = 0x97B3, --(éž³)
+ [0x5046] = 0x97B4, --(éž´)
+ [0x5047] = 0x97C3, --(韃)
+ [0x5048] = 0x97C6, --(韆)
+ [0x5049] = 0x97C8, --(韈)
+ [0x504A] = 0x97CB, --(韋)
+ [0x504B] = 0x97DC, --(韜)
+ [0x504C] = 0x97ED, --(韭)
+ [0x504D] = 0x9F4F, --(é½)
+ [0x504E] = 0x97F2, --(韲)
+ [0x504F] = 0x7ADF, --(ç«Ÿ)
+ [0x5050] = 0x97F6, --(韶)
+ [0x5051] = 0x97F5, --(韵)
+ [0x5052] = 0x980F, --(é )
+ [0x5053] = 0x980C, --(頌)
+ [0x5054] = 0x9838, --(é ¸)
+ [0x5055] = 0x9824, --(é ¤)
+ [0x5056] = 0x9821, --(é ¡)
+ [0x5057] = 0x9837, --(é ·)
+ [0x5058] = 0x983D, --(é ½)
+ [0x5059] = 0x9846, --(顆)
+ [0x505A] = 0x984F, --(é¡)
+ [0x505B] = 0x984B, --(é¡‹)
+ [0x505C] = 0x986B, --(é¡«)
+ [0x505D] = 0x986F, --(顯)
+ [0x505E] = 0x9870, --(é¡°)
+ [0x5101] = 0x9871, --(顱)
+ [0x5102] = 0x9874, --(é¡´)
+ [0x5103] = 0x9873, --(顳)
+ [0x5104] = 0x98AA, --(颪)
+ [0x5105] = 0x98AF, --(颯)
+ [0x5106] = 0x98B1, --(颱)
+ [0x5107] = 0x98B6, --(颶)
+ [0x5108] = 0x98C4, --(飄)
+ [0x5109] = 0x98C3, --(飃)
+ [0x510A] = 0x98C6, --(飆)
+ [0x510B] = 0x98E9, --(飩)
+ [0x510C] = 0x98EB, --(飫)
+ [0x510D] = 0x9903, --(餃)
+ [0x510E] = 0x9909, --(餉)
+ [0x510F] = 0x9912, --(餒)
+ [0x5110] = 0x9914, --(餔)
+ [0x5111] = 0x9918, --(餘)
+ [0x5112] = 0x9921, --(餡)
+ [0x5113] = 0x991D, --(é¤)
+ [0x5114] = 0x991E, --(餞)
+ [0x5115] = 0x9924, --(餤)
+ [0x5116] = 0x9920, --(餠)
+ [0x5117] = 0x992C, --(餬)
+ [0x5118] = 0x992E, --(餮)
+ [0x5119] = 0x993D, --(餽)
+ [0x511A] = 0x993E, --(餾)
+ [0x511B] = 0x9942, --(饂)
+ [0x511C] = 0x9949, --(饉)
+ [0x511D] = 0x9945, --(饅)
+ [0x511E] = 0x9950, --(é¥)
+ [0x511F] = 0x994B, --(饋)
+ [0x5120] = 0x9951, --(饑)
+ [0x5121] = 0x9952, --(饒)
+ [0x5122] = 0x994C, --(饌)
+ [0x5123] = 0x9955, --(饕)
+ [0x5124] = 0x9997, --(馗)
+ [0x5125] = 0x9998, --(馘)
+ [0x5126] = 0x99A5, --(馥)
+ [0x5127] = 0x99AD, --(馭)
+ [0x5128] = 0x99AE, --(馮)
+ [0x5129] = 0x99BC, --(馼)
+ [0x512A] = 0x99DF, --(駟)
+ [0x512B] = 0x99DB, --(駛)
+ [0x512C] = 0x99DD, --(é§)
+ [0x512D] = 0x99D8, --(駘)
+ [0x512E] = 0x99D1, --(駑)
+ [0x512F] = 0x99ED, --(駭)
+ [0x5130] = 0x99EE, --(駮)
+ [0x5131] = 0x99F1, --(駱)
+ [0x5132] = 0x99F2, --(駲)
+ [0x5133] = 0x99FB, --(駻)
+ [0x5134] = 0x99F8, --(駸)
+ [0x5135] = 0x9A01, --(é¨)
+ [0x5136] = 0x9A0F, --(é¨)
+ [0x5137] = 0x9A05, --(騅)
+ [0x5138] = 0x99E2, --(駢)
+ [0x5139] = 0x9A19, --(騙)
+ [0x513A] = 0x9A2B, --(騫)
+ [0x513B] = 0x9A37, --(騷)
+ [0x513C] = 0x9A45, --(é©…)
+ [0x513D] = 0x9A42, --(é©‚)
+ [0x513E] = 0x9A40, --(é©€)
+ [0x513F] = 0x9A43, --(驃)
+ [0x5140] = 0x9A3E, --(騾)
+ [0x5141] = 0x9A55, --(é©•)
+ [0x5142] = 0x9A4D, --(é©)
+ [0x5143] = 0x9A5B, --(é©›)
+ [0x5144] = 0x9A57, --(é©—)
+ [0x5145] = 0x9A5F, --(é©Ÿ)
+ [0x5146] = 0x9A62, --(é©¢)
+ [0x5147] = 0x9A65, --(é©¥)
+ [0x5148] = 0x9A64, --(驤)
+ [0x5149] = 0x9A69, --(é©©)
+ [0x514A] = 0x9A6B, --(é©«)
+ [0x514B] = 0x9A6A, --(驪)
+ [0x514C] = 0x9AAD, --(骭)
+ [0x514D] = 0x9AB0, --(骰)
+ [0x514E] = 0x9ABC, --(骼)
+ [0x514F] = 0x9AC0, --(é«€)
+ [0x5150] = 0x9ACF, --(é«)
+ [0x5151] = 0x9AD1, --(é«‘)
+ [0x5152] = 0x9AD3, --(é«“)
+ [0x5153] = 0x9AD4, --(é«”)
+ [0x5154] = 0x9ADE, --(é«ž)
+ [0x5155] = 0x9ADF, --(é«Ÿ)
+ [0x5156] = 0x9AE2, --(é«¢)
+ [0x5157] = 0x9AE3, --(é«£)
+ [0x5158] = 0x9AE6, --(髦)
+ [0x5159] = 0x9AEF, --(髯)
+ [0x515A] = 0x9AEB, --(é««)
+ [0x515B] = 0x9AEE, --(é«®)
+ [0x515C] = 0x9AF4, --(é«´)
+ [0x515D] = 0x9AF1, --(髱)
+ [0x515E] = 0x9AF7, --(é«·)
+ [0x5201] = 0x9AFB, --(é«»)
+ [0x5202] = 0x9B06, --(鬆)
+ [0x5203] = 0x9B18, --(鬘)
+ [0x5204] = 0x9B1A, --(鬚)
+ [0x5205] = 0x9B1F, --(鬟)
+ [0x5206] = 0x9B22, --(鬢)
+ [0x5207] = 0x9B23, --(鬣)
+ [0x5208] = 0x9B25, --(鬥)
+ [0x5209] = 0x9B27, --(鬧)
+ [0x520A] = 0x9B28, --(鬨)
+ [0x520B] = 0x9B29, --(鬩)
+ [0x520C] = 0x9B2A, --(鬪)
+ [0x520D] = 0x9B2E, --(鬮)
+ [0x520E] = 0x9B2F, --(鬯)
+ [0x520F] = 0x9B32, --(鬲)
+ [0x5210] = 0x9B44, --(é­„)
+ [0x5211] = 0x9B43, --(é­ƒ)
+ [0x5212] = 0x9B4F, --(é­)
+ [0x5213] = 0x9B4D, --(é­)
+ [0x5214] = 0x9B4E, --(é­Ž)
+ [0x5215] = 0x9B51, --(é­‘)
+ [0x5216] = 0x9B58, --(é­˜)
+ [0x5217] = 0x9B74, --(é­´)
+ [0x5218] = 0x9B93, --(鮓)
+ [0x5219] = 0x9B83, --(鮃)
+ [0x521A] = 0x9B91, --(鮑)
+ [0x521B] = 0x9B96, --(é®–)
+ [0x521C] = 0x9B97, --(é®—)
+ [0x521D] = 0x9B9F, --(鮟)
+ [0x521E] = 0x9BA0, --(é® )
+ [0x521F] = 0x9BA8, --(鮨)
+ [0x5220] = 0x9BB4, --(é®´)
+ [0x5221] = 0x9BC0, --(鯀)
+ [0x5222] = 0x9BCA, --(鯊)
+ [0x5223] = 0x9BB9, --(鮹)
+ [0x5224] = 0x9BC6, --(鯆)
+ [0x5225] = 0x9BCF, --(é¯)
+ [0x5226] = 0x9BD1, --(鯑)
+ [0x5227] = 0x9BD2, --(鯒)
+ [0x5228] = 0x9BE3, --(鯣)
+ [0x5229] = 0x9BE2, --(鯢)
+ [0x522A] = 0x9BE4, --(鯤)
+ [0x522B] = 0x9BD4, --(鯔)
+ [0x522C] = 0x9BE1, --(鯡)
+ [0x522D] = 0x9C3A, --(é°º)
+ [0x522E] = 0x9BF2, --(鯲)
+ [0x522F] = 0x9BF1, --(鯱)
+ [0x5230] = 0x9BF0, --(鯰)
+ [0x5231] = 0x9C15, --(é°•)
+ [0x5232] = 0x9C14, --(é°”)
+ [0x5233] = 0x9C09, --(é°‰)
+ [0x5234] = 0x9C13, --(é°“)
+ [0x5235] = 0x9C0C, --(鰌)
+ [0x5236] = 0x9C06, --(é°†)
+ [0x5237] = 0x9C08, --(é°ˆ)
+ [0x5238] = 0x9C12, --(é°’)
+ [0x5239] = 0x9C0A, --(é°Š)
+ [0x523A] = 0x9C04, --(é°„)
+ [0x523B] = 0x9C2E, --(é°®)
+ [0x523C] = 0x9C1B, --(é°›)
+ [0x523D] = 0x9C25, --(é°¥)
+ [0x523E] = 0x9C24, --(é°¤)
+ [0x523F] = 0x9C21, --(é°¡)
+ [0x5240] = 0x9C30, --(é°°)
+ [0x5241] = 0x9C47, --(鱇)
+ [0x5242] = 0x9C32, --(é°²)
+ [0x5243] = 0x9C46, --(鱆)
+ [0x5244] = 0x9C3E, --(é°¾)
+ [0x5245] = 0x9C5A, --(鱚)
+ [0x5246] = 0x9C60, --(é± )
+ [0x5247] = 0x9C67, --(鱧)
+ [0x5248] = 0x9C76, --(鱶)
+ [0x5249] = 0x9C78, --(鱸)
+ [0x524A] = 0x9CE7, --(鳧)
+ [0x524B] = 0x9CEC, --(鳬)
+ [0x524C] = 0x9CF0, --(é³°)
+ [0x524D] = 0x9D09, --(é´‰)
+ [0x524E] = 0x9D08, --(é´ˆ)
+ [0x524F] = 0x9CEB, --(鳫)
+ [0x5250] = 0x9D03, --(é´ƒ)
+ [0x5251] = 0x9D06, --(é´†)
+ [0x5252] = 0x9D2A, --(é´ª)
+ [0x5253] = 0x9D26, --(é´¦)
+ [0x5254] = 0x9DAF, --(鶯)
+ [0x5255] = 0x9D23, --(é´£)
+ [0x5256] = 0x9D1F, --(é´Ÿ)
+ [0x5257] = 0x9D44, --(鵄)
+ [0x5258] = 0x9D15, --(é´•)
+ [0x5259] = 0x9D12, --(é´’)
+ [0x525A] = 0x9D41, --(éµ)
+ [0x525B] = 0x9D3F, --(é´¿)
+ [0x525C] = 0x9D3E, --(é´¾)
+ [0x525D] = 0x9D46, --(鵆)
+ [0x525E] = 0x9D48, --(鵈)
+ [0x5301] = 0x9D5D, --(éµ)
+ [0x5302] = 0x9D5E, --(鵞)
+ [0x5303] = 0x9D64, --(鵤)
+ [0x5304] = 0x9D51, --(鵑)
+ [0x5305] = 0x9D50, --(éµ)
+ [0x5306] = 0x9D59, --(éµ™)
+ [0x5307] = 0x9D72, --(éµ²)
+ [0x5308] = 0x9D89, --(鶉)
+ [0x5309] = 0x9D87, --(鶇)
+ [0x530A] = 0x9DAB, --(鶫)
+ [0x530B] = 0x9D6F, --(鵯)
+ [0x530C] = 0x9D7A, --(鵺)
+ [0x530D] = 0x9D9A, --(鶚)
+ [0x530E] = 0x9DA4, --(鶤)
+ [0x530F] = 0x9DA9, --(鶩)
+ [0x5310] = 0x9DB2, --(鶲)
+ [0x5311] = 0x9DC4, --(é·„)
+ [0x5312] = 0x9DC1, --(é·)
+ [0x5313] = 0x9DBB, --(鶻)
+ [0x5314] = 0x9DB8, --(鶸)
+ [0x5315] = 0x9DBA, --(鶺)
+ [0x5316] = 0x9DC6, --(é·†)
+ [0x5317] = 0x9DCF, --(é·)
+ [0x5318] = 0x9DC2, --(é·‚)
+ [0x5319] = 0x9DD9, --(é·™)
+ [0x531A] = 0x9DD3, --(é·“)
+ [0x531B] = 0x9DF8, --(é·¸)
+ [0x531C] = 0x9DE6, --(é·¦)
+ [0x531D] = 0x9DED, --(é·­)
+ [0x531E] = 0x9DEF, --(é·¯)
+ [0x531F] = 0x9DFD, --(é·½)
+ [0x5320] = 0x9E1A, --(鸚)
+ [0x5321] = 0x9E1B, --(鸛)
+ [0x5322] = 0x9E1E, --(鸞)
+ [0x5323] = 0x9E75, --(é¹µ)
+ [0x5324] = 0x9E79, --(é¹¹)
+ [0x5325] = 0x9E7D, --(é¹½)
+ [0x5326] = 0x9E81, --(éº)
+ [0x5327] = 0x9E88, --(麈)
+ [0x5328] = 0x9E8B, --(麋)
+ [0x5329] = 0x9E8C, --(麌)
+ [0x532A] = 0x9E92, --(麒)
+ [0x532B] = 0x9E95, --(麕)
+ [0x532C] = 0x9E91, --(麑)
+ [0x532D] = 0x9E9D, --(éº)
+ [0x532E] = 0x9EA5, --(麥)
+ [0x532F] = 0x9EA9, --(麩)
+ [0x5330] = 0x9EB8, --(麸)
+ [0x5331] = 0x9EAA, --(麪)
+ [0x5332] = 0x9EAD, --(麭)
+ [0x5333] = 0x9761, --(é¡)
+ [0x5334] = 0x9ECC, --(黌)
+ [0x5335] = 0x9ECE, --(黎)
+ [0x5336] = 0x9ECF, --(é»)
+ [0x5337] = 0x9ED0, --(é»)
+ [0x5338] = 0x9ED4, --(é»”)
+ [0x5339] = 0x9EDC, --(黜)
+ [0x533A] = 0x9EDE, --(點)
+ [0x533B] = 0x9EDD, --(é»)
+ [0x533C] = 0x9EE0, --(é» )
+ [0x533D] = 0x9EE5, --(黥)
+ [0x533E] = 0x9EE8, --(黨)
+ [0x533F] = 0x9EEF, --(黯)
+ [0x5340] = 0x9EF4, --(é»´)
+ [0x5341] = 0x9EF6, --(黶)
+ [0x5342] = 0x9EF7, --(é»·)
+ [0x5343] = 0x9EF9, --(黹)
+ [0x5344] = 0x9EFB, --(é»»)
+ [0x5345] = 0x9EFC, --(黼)
+ [0x5346] = 0x9EFD, --(黽)
+ [0x5347] = 0x9F07, --(鼇)
+ [0x5348] = 0x9F08, --(鼈)
+ [0x5349] = 0x76B7, --(çš·)
+ [0x534A] = 0x9F15, --(鼕)
+ [0x534B] = 0x9F21, --(鼡)
+ [0x534C] = 0x9F2C, --(鼬)
+ [0x534D] = 0x9F3E, --(é¼¾)
+ [0x534E] = 0x9F4A, --(齊)
+ [0x534F] = 0x9F52, --(é½’)
+ [0x5350] = 0x9F54, --(é½”)
+ [0x5351] = 0x9F63, --(é½£)
+ [0x5352] = 0x9F5F, --(齟)
+ [0x5353] = 0x9F60, --(é½ )
+ [0x5354] = 0x9F61, --(齡)
+ [0x5355] = 0x9F66, --(齦)
+ [0x5356] = 0x9F67, --(齧)
+ [0x5357] = 0x9F6C, --(齬)
+ [0x5358] = 0x9F6A, --(齪)
+ [0x5359] = 0x9F77, --(é½·)
+ [0x535A] = 0x9F72, --(é½²)
+ [0x535B] = 0x9F76, --(齶)
+ [0x535C] = 0x9F95, --(龕)
+ [0x535D] = 0x9F9C, --(龜)
+ [0x535E] = 0x9FA0, --(é¾ )
+ [0x5401] = 0x582F, --(å ¯)
+ [0x5402] = 0x69C7, --(槇)
+ [0x5403] = 0x9059, --(é™)
+ [0x5404] = 0x7464, --(瑤)
+ [0x5405] = 0x51DC, --(凜)
+ [0x5406] = 0x7199, --(熙)
+}}
diff --git a/macros/luatex/generic/luatexja/src/ltj-kinsoku_make.tex b/macros/luatex/generic/luatexja/src/ltj-kinsoku_make.tex
new file mode 100644
index 0000000000..5d25ff0f11
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-kinsoku_make.tex
@@ -0,0 +1,456 @@
+%#!luatex ltj-kinsoku_make.tex
+%\tracingall
+\input luatexja.sty
+
+\catcode`\@=11
+\ltj@tempcnta="0%"
+\loop\ifnum\ltj@tempcnta<"100%"
+ \ltjsetparameter{alxspmode={\ltj@tempcnta,0}}%
+ \advance\ltj@tempcnta by1
+\repeat
+
+\ltj@tempcnta=`\0%"
+\loop\ifnum\ltj@tempcnta<`\:%"
+ \ltjsetparameter{alxspmode={\ltj@tempcnta,3}}%
+ \advance\ltj@tempcnta by1
+\repeat
+
+\ltj@tempcnta=`\A%"
+\loop\ifnum\ltj@tempcnta<`\[%"
+ \ltjsetparameter{alxspmode={\ltj@tempcnta,3}}%
+ \advance\ltj@tempcnta by1
+\repeat
+
+\ltj@tempcnta=`\a%"
+\loop\ifnum\ltj@tempcnta<`\{%"
+ \ltjsetparameter{alxspmode={\ltj@tempcnta,3}}%
+ \advance\ltj@tempcnta by1
+\repeat
+
+\ltj@tempcnta="2000%" General Punctuation
+\loop\ifnum\ltj@tempcnta<"2070%"
+ \ltjsetparameter{kcatcode={\ltj@tempcnta,1}}%
+ \advance\ltj@tempcnta by1
+\repeat
+
+\ltj@tempcnta="2500%" 罫線
+\loop\ifnum\ltj@tempcnta<"2580%"
+ \ltjsetparameter{alxspmode={\ltj@tempcnta,0}}%
+ \advance\ltj@tempcnta by1
+\repeat
+
+\ltj@tempcnta="3000%" CJK Symbols and Punctuation
+\loop\ifnum\ltj@tempcnta<"3040%"
+ \ltjsetparameter{kcatcode={\ltj@tempcnta,1}}%
+ \advance\ltj@tempcnta by1
+\repeat
+
+\ltj@tempcnta="FF00%" åŠè§’・全角形
+\loop\ifnum\ltj@tempcnta<"FFF0%"
+ \ltjsetparameter{kcatcode={\ltj@tempcnta,1}}%
+ \advance\ltj@tempcnta by1
+\repeat
+
+%
+% 行頭ã€è¡Œæœ«ç¦å‰‡ãƒ‘ラメータ
+%
+% 1byte characters
+\ltjsetparameter{prebreakpenalty={`!,10000}}
+\ltjsetparameter{prebreakpenalty={`",10000}}
+\ltjsetparameter{postbreakpenalty={`\#,500}}
+\ltjsetparameter{postbreakpenalty={`\$,500}}
+\ltjsetparameter{prebreakpenalty={`\%,500}}
+\ltjsetparameter{prebreakpenalty={`\&,500}}
+\ltjsetparameter{postbreakpenalty={`\`,10000}}
+\ltjsetparameter{prebreakpenalty={`',10000}}
+\ltjsetparameter{prebreakpenalty={`),10000}}
+\ltjsetparameter{postbreakpenalty={`(,10000}}
+\ltjsetparameter{prebreakpenalty={`*,500}}
+\ltjsetparameter{prebreakpenalty={`+,500}}
+\ltjsetparameter{prebreakpenalty={`-,10000}}
+\ltjsetparameter{prebreakpenalty={`.,10000}}
+\ltjsetparameter{prebreakpenalty={44,10000}}
+\ltjsetparameter{prebreakpenalty={`/,500}}
+\ltjsetparameter{prebreakpenalty={`;,10000}}
+\ltjsetparameter{prebreakpenalty={`?,10000}}
+\ltjsetparameter{prebreakpenalty={`:,10000}}
+\ltjsetparameter{prebreakpenalty={`],10000}}
+\ltjsetparameter{postbreakpenalty={`[,10000}}
+%全角文字
+\ltjsetparameter{prebreakpenalty={`ã€,10000}}
+\ltjsetparameter{prebreakpenalty={`。,10000}}
+\ltjsetparameter{prebreakpenalty={`,,10000}}
+\ltjsetparameter{prebreakpenalty={`.,10000}}
+\ltjsetparameter{prebreakpenalty={`・,10000}}
+\ltjsetparameter{prebreakpenalty={`:,10000}}
+\ltjsetparameter{prebreakpenalty={`ï¼›,10000}}
+\ltjsetparameter{prebreakpenalty={`?,10000}}
+\ltjsetparameter{prebreakpenalty={`ï¼,10000}}
+\ltjsetparameter{prebreakpenalty={`ã‚›,10000}}%\jis"212B
+\ltjsetparameter{prebreakpenalty={`゜,10000}}%\jis"212C
+\ltjsetparameter{prebreakpenalty={`´,10000}}%\jis"212D
+\ltjsetparameter{postbreakpenalty={`ï½€,10000}}%\jis"212E
+\ltjsetparameter{prebreakpenalty={`々,10000}}%\jis"2139
+\ltjsetparameter{prebreakpenalty={`…,250}}%\jis"2144
+\ltjsetparameter{prebreakpenalty={`‥,250}}%\jis"2145
+\ltjsetparameter{postbreakpenalty={`‘,10000}}%\jis"2146
+\ltjsetparameter{prebreakpenalty={`’,10000}}%\jis"2147
+\ltjsetparameter{postbreakpenalty={`“,10000}}%\jis"2148
+\ltjsetparameter{prebreakpenalty={`â€,10000}}%\jis"2149
+\ltjsetparameter{prebreakpenalty={`),10000}}
+\ltjsetparameter{postbreakpenalty={`(,10000}}
+\ltjsetparameter{prebreakpenalty={`ï½,10000}}
+\ltjsetparameter{postbreakpenalty={`ï½›,10000}}
+\ltjsetparameter{prebreakpenalty={`ï¼½,10000}}
+\ltjsetparameter{postbreakpenalty={`ï¼»,10000}}
+%\ltjsetparameter{postbreakpenalty={`‘,10000}}
+%\ltjsetparameter{prebreakpenalty={`’,10000}}
+\ltjsetparameter{postbreakpenalty={`〔,10000}}%\jis"214C
+\ltjsetparameter{prebreakpenalty={`〕,10000}}%\jis"214D
+\ltjsetparameter{postbreakpenalty={`〈,10000}}%\jis"2152
+\ltjsetparameter{prebreakpenalty={`〉,10000}}%\jis"2153
+\ltjsetparameter{postbreakpenalty={`《,10000}}%\jis"2154
+\ltjsetparameter{prebreakpenalty={`》,10000}}%\jis"2155
+\ltjsetparameter{postbreakpenalty={`「,10000}}%\jis"2156
+\ltjsetparameter{prebreakpenalty={`ã€,10000}}%\jis"2157
+\ltjsetparameter{postbreakpenalty={`『,10000}}%\jis"2158
+\ltjsetparameter{prebreakpenalty={`ã€,10000}}%\jis"2159
+\ltjsetparameter{postbreakpenalty={`ã€,10000}}%\jis"215A
+\ltjsetparameter{prebreakpenalty={`】,10000}}%\jis"215B
+\ltjsetparameter{prebreakpenalty={`ー,10000}}
+\ltjsetparameter{prebreakpenalty={`+,200}}
+\ltjsetparameter{prebreakpenalty={`−,200}}% U+2212 MINUS SIGN
+\ltjsetparameter{prebreakpenalty={`ï¼,200}}% U+FF0D FULLWIDTH HYPHEN-MINUS
+\ltjsetparameter{prebreakpenalty={`ï¼,200}}
+\ltjsetparameter{postbreakpenalty={`#,200}}
+\ltjsetparameter{postbreakpenalty={`$,200}}
+\ltjsetparameter{prebreakpenalty={`ï¼…,200}}
+\ltjsetparameter{prebreakpenalty={`&,200}}
+\ltjsetparameter{prebreakpenalty={`ã,150}}
+\ltjsetparameter{prebreakpenalty={`ãƒ,150}}
+\ltjsetparameter{prebreakpenalty={`ã…,150}}
+\ltjsetparameter{prebreakpenalty={`ã‡,150}}
+\ltjsetparameter{prebreakpenalty={`ã‰,150}}
+\ltjsetparameter{prebreakpenalty={`ã£,150}}
+\ltjsetparameter{prebreakpenalty={`ゃ,150}}
+\ltjsetparameter{prebreakpenalty={`ã‚…,150}}
+\ltjsetparameter{prebreakpenalty={`ょ,150}}
+\ltjsetparameter{prebreakpenalty={`ã‚Ž,150}}%\jis"246E
+\ltjsetparameter{prebreakpenalty={`ã‚¡,150}}
+\ltjsetparameter{prebreakpenalty={`ã‚£,150}}
+\ltjsetparameter{prebreakpenalty={`ã‚¥,150}}
+\ltjsetparameter{prebreakpenalty={`ェ,150}}
+\ltjsetparameter{prebreakpenalty={`ã‚©,150}}
+\ltjsetparameter{prebreakpenalty={`ッ,150}}
+\ltjsetparameter{prebreakpenalty={`ャ,150}}
+\ltjsetparameter{prebreakpenalty={`ュ,150}}
+\ltjsetparameter{prebreakpenalty={`ョ,150}}
+\ltjsetparameter{prebreakpenalty={`ヮ,150}}%\jis"256E
+\ltjsetparameter{prebreakpenalty={`ヵ,150}}%\jis"2575
+\ltjsetparameter{prebreakpenalty={`ヶ,150}}%\jis"2576
+% kinsoku JIS X 0208 additional
+\ltjsetparameter{prebreakpenalty={`ヽ,10000}}
+\ltjsetparameter{prebreakpenalty={`ヾ,10000}}
+\ltjsetparameter{prebreakpenalty={`ã‚,10000}}
+\ltjsetparameter{prebreakpenalty={`ã‚ž,10000}}
+
+%
+% kinsoku JIS X 0213
+%
+\ltjsetparameter{prebreakpenalty={`〳,10000}}
+\ltjsetparameter{prebreakpenalty={`〴,10000}}
+\ltjsetparameter{prebreakpenalty={`〵,10000}}
+\ltjsetparameter{prebreakpenalty={`〻,10000}}
+\ltjsetparameter{postbreakpenalty={`⦅,10000}}
+\ltjsetparameter{prebreakpenalty={`⦆,10000}}
+\ltjsetparameter{postbreakpenalty={`⦅,10000}}
+\ltjsetparameter{prebreakpenalty={`ï½ ,10000}}
+\ltjsetparameter{postbreakpenalty={`〘,10000}}
+\ltjsetparameter{prebreakpenalty={`〙,10000}}
+\ltjsetparameter{postbreakpenalty={`〖,10000}}
+\ltjsetparameter{prebreakpenalty={`〗,10000}}
+\ltjsetparameter{postbreakpenalty={`«,10000}}
+\ltjsetparameter{prebreakpenalty={`»,10000}}
+\ltjsetparameter{postbreakpenalty={`ã€,10000}}
+\ltjsetparameter{prebreakpenalty={`〟,10000}}
+\ltjsetparameter{prebreakpenalty={`‼,10000}}
+\ltjsetparameter{prebreakpenalty={`â‡,10000}}
+\ltjsetparameter{prebreakpenalty={`âˆ,10000}}
+\ltjsetparameter{prebreakpenalty={`â‰,10000}}
+\ltjsetparameter{postbreakpenalty={`¡,10000}}
+\ltjsetparameter{postbreakpenalty={`¿,10000}}
+\ltjsetparameter{prebreakpenalty={`Ë,10000}}
+\ltjsetparameter{prebreakpenalty={`·,10000}}
+\ltjsetparameter{prebreakpenalty={`ª,10000}}
+\ltjsetparameter{prebreakpenalty={`º,10000}}
+\ltjsetparameter{prebreakpenalty={`¹,10000}}
+\ltjsetparameter{prebreakpenalty={`²,10000}}
+\ltjsetparameter{prebreakpenalty={`³,10000}}
+\ltjsetparameter{postbreakpenalty={`€,10000}}
+\ltjsetparameter{prebreakpenalty={`ã‚•,150}}
+\ltjsetparameter{prebreakpenalty={`ã‚–,150}}
+\ltjsetparameter{prebreakpenalty={`ㇰ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇱ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇲ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇳ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇴ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇵ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇶ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇷ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇸ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇹ,150}}
+%\ltjsetparameter{prebreakpenalty={`ㇷ゚,150}}
+\ltjsetparameter{prebreakpenalty={`ㇺ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇻ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇼ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇽ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇾ,150}}
+\ltjsetparameter{prebreakpenalty={`ㇿ,150}}
+%
+% kinsoku JIS X 0212
+%
+%\ltjsetparameter{postbreakpenalty={`¡,10000}}
+%\ltjsetparameter{postbreakpenalty={`¿,10000}}
+%\ltjsetparameter{prebreakpenalty={`º,10000}}
+%\ltjsetparameter{prebreakpenalty={`ª,10000}}
+\ltjsetparameter{prebreakpenalty={`â„¢,10000}}
+%
+% kinsoku åŠè§’片仮å
+%
+\ltjsetparameter{prebreakpenalty={`。,10000}}
+\ltjsetparameter{prebreakpenalty={`、,10000}}
+\ltjsetparameter{prebreakpenalty={`゙,10000}}
+\ltjsetparameter{prebreakpenalty={`゚,10000}}
+\ltjsetparameter{prebreakpenalty={`ï½£,10000}}
+\ltjsetparameter{postbreakpenalty={`ï½¢,10000}}
+%
+% xspcode
+\ltjsetparameter{alxspmode={`(,preonly}}
+\ltjsetparameter{alxspmode={`),postonly}}
+\ltjsetparameter{alxspmode={`[,preonly}}
+\ltjsetparameter{alxspmode={`],postonly}}
+\ltjsetparameter{alxspmode={``,preonly}}
+\ltjsetparameter{alxspmode={`',postonly}}
+\ltjsetparameter{alxspmode={`;,postonly}}
+\ltjsetparameter{alxspmode={44,postonly}}
+\ltjsetparameter{alxspmode={`.,postonly}}
+% for 8bit Latin
+\ltjsetparameter{alxspmode={"80,allow}}
+\ltjsetparameter{alxspmode={"81,allow}}
+\ltjsetparameter{alxspmode={"82,allow}}
+\ltjsetparameter{alxspmode={"83,allow}}
+\ltjsetparameter{alxspmode={"84,allow}}
+\ltjsetparameter{alxspmode={"85,allow}}
+\ltjsetparameter{alxspmode={"86,allow}}
+\ltjsetparameter{alxspmode={"87,allow}}
+\ltjsetparameter{alxspmode={"88,allow}}
+\ltjsetparameter{alxspmode={"89,allow}}
+\ltjsetparameter{alxspmode={"8A,allow}}
+\ltjsetparameter{alxspmode={"8B,allow}}
+\ltjsetparameter{alxspmode={"8C,allow}}
+\ltjsetparameter{alxspmode={"8D,allow}}
+\ltjsetparameter{alxspmode={"8E,allow}}
+\ltjsetparameter{alxspmode={"8F,allow}}
+\ltjsetparameter{alxspmode={"90,allow}}
+\ltjsetparameter{alxspmode={"91,allow}}
+\ltjsetparameter{alxspmode={"92,allow}}
+\ltjsetparameter{alxspmode={"93,allow}}
+\ltjsetparameter{alxspmode={"94,allow}}
+\ltjsetparameter{alxspmode={"95,allow}}
+\ltjsetparameter{alxspmode={"96,allow}}
+\ltjsetparameter{alxspmode={"97,allow}}
+\ltjsetparameter{alxspmode={"98,allow}}
+\ltjsetparameter{alxspmode={"99,allow}}
+\ltjsetparameter{alxspmode={"9A,allow}}
+\ltjsetparameter{alxspmode={"9B,allow}}
+\ltjsetparameter{alxspmode={"9C,allow}}
+\ltjsetparameter{alxspmode={"9D,allow}}
+\ltjsetparameter{alxspmode={"9E,allow}}
+\ltjsetparameter{alxspmode={"9F,allow}}
+\ltjsetparameter{alxspmode={"A0,allow}}
+\ltjsetparameter{alxspmode={"A1,allow}}
+\ltjsetparameter{alxspmode={"A2,allow}}
+\ltjsetparameter{alxspmode={"A3,allow}}
+\ltjsetparameter{alxspmode={"A4,allow}}
+\ltjsetparameter{alxspmode={"A5,allow}}
+\ltjsetparameter{alxspmode={"A6,allow}}
+\ltjsetparameter{alxspmode={"A7,allow}}
+\ltjsetparameter{alxspmode={"A8,allow}}
+\ltjsetparameter{alxspmode={"A9,allow}}
+\ltjsetparameter{alxspmode={"AA,allow}}
+\ltjsetparameter{alxspmode={"AB,allow}}
+\ltjsetparameter{alxspmode={"AC,allow}}
+\ltjsetparameter{alxspmode={"AD,allow}}
+\ltjsetparameter{alxspmode={"AE,allow}}
+\ltjsetparameter{alxspmode={"AF,allow}}
+\ltjsetparameter{alxspmode={"B0,allow}}
+\ltjsetparameter{alxspmode={"B1,allow}}
+\ltjsetparameter{alxspmode={"B2,allow}}
+\ltjsetparameter{alxspmode={"B3,allow}}
+\ltjsetparameter{alxspmode={"B4,allow}}
+\ltjsetparameter{alxspmode={"B5,allow}}
+\ltjsetparameter{alxspmode={"B6,allow}}
+\ltjsetparameter{alxspmode={"B7,allow}}
+\ltjsetparameter{alxspmode={"B8,allow}}
+\ltjsetparameter{alxspmode={"B9,allow}}
+\ltjsetparameter{alxspmode={"BA,allow}}
+\ltjsetparameter{alxspmode={"BB,allow}}
+\ltjsetparameter{alxspmode={"BC,allow}}
+\ltjsetparameter{alxspmode={"BD,allow}}
+\ltjsetparameter{alxspmode={"BE,allow}}
+\ltjsetparameter{alxspmode={"BF,allow}}
+\ltjsetparameter{alxspmode={"C0,allow}}
+\ltjsetparameter{alxspmode={"C1,allow}}
+\ltjsetparameter{alxspmode={"C2,allow}}
+\ltjsetparameter{alxspmode={"C3,allow}}
+\ltjsetparameter{alxspmode={"C4,allow}}
+\ltjsetparameter{alxspmode={"C5,allow}}
+\ltjsetparameter{alxspmode={"C6,allow}}
+\ltjsetparameter{alxspmode={"C7,allow}}
+\ltjsetparameter{alxspmode={"C8,allow}}
+\ltjsetparameter{alxspmode={"C9,allow}}
+\ltjsetparameter{alxspmode={"CA,allow}}
+\ltjsetparameter{alxspmode={"CB,allow}}
+\ltjsetparameter{alxspmode={"CC,allow}}
+\ltjsetparameter{alxspmode={"CD,allow}}
+\ltjsetparameter{alxspmode={"CE,allow}}
+\ltjsetparameter{alxspmode={"CF,allow}}
+\ltjsetparameter{alxspmode={"D0,allow}}
+\ltjsetparameter{alxspmode={"D1,allow}}
+\ltjsetparameter{alxspmode={"D2,allow}}
+\ltjsetparameter{alxspmode={"D3,allow}}
+\ltjsetparameter{alxspmode={"D4,allow}}
+\ltjsetparameter{alxspmode={"D5,allow}}
+\ltjsetparameter{alxspmode={"D6,allow}}
+\ltjsetparameter{alxspmode={"D7,allow}}
+\ltjsetparameter{alxspmode={"D8,allow}}
+\ltjsetparameter{alxspmode={"D9,allow}}
+\ltjsetparameter{alxspmode={"DA,allow}}
+\ltjsetparameter{alxspmode={"DB,allow}}
+\ltjsetparameter{alxspmode={"DC,allow}}
+\ltjsetparameter{alxspmode={"DD,allow}}
+\ltjsetparameter{alxspmode={"DE,allow}}
+\ltjsetparameter{alxspmode={"DF,allow}}
+\ltjsetparameter{alxspmode={"E0,allow}}
+\ltjsetparameter{alxspmode={"E1,allow}}
+\ltjsetparameter{alxspmode={"E2,allow}}
+\ltjsetparameter{alxspmode={"E3,allow}}
+\ltjsetparameter{alxspmode={"E4,allow}}
+\ltjsetparameter{alxspmode={"E5,allow}}
+\ltjsetparameter{alxspmode={"E6,allow}}
+\ltjsetparameter{alxspmode={"E7,allow}}
+\ltjsetparameter{alxspmode={"E8,allow}}
+\ltjsetparameter{alxspmode={"E9,allow}}
+\ltjsetparameter{alxspmode={"EA,allow}}
+\ltjsetparameter{alxspmode={"EB,allow}}
+\ltjsetparameter{alxspmode={"EC,allow}}
+\ltjsetparameter{alxspmode={"ED,allow}}
+\ltjsetparameter{alxspmode={"EE,allow}}
+\ltjsetparameter{alxspmode={"EF,allow}}
+\ltjsetparameter{alxspmode={"F0,allow}}
+\ltjsetparameter{alxspmode={"F1,allow}}
+\ltjsetparameter{alxspmode={"F2,allow}}
+\ltjsetparameter{alxspmode={"F3,allow}}
+\ltjsetparameter{alxspmode={"F4,allow}}
+\ltjsetparameter{alxspmode={"F5,allow}}
+\ltjsetparameter{alxspmode={"F6,allow}}
+\ltjsetparameter{alxspmode={"F7,allow}}
+\ltjsetparameter{alxspmode={"F8,allow}}
+\ltjsetparameter{alxspmode={"F9,allow}}
+\ltjsetparameter{alxspmode={"FA,allow}}
+\ltjsetparameter{alxspmode={"FB,allow}}
+\ltjsetparameter{alxspmode={"FC,allow}}
+\ltjsetparameter{alxspmode={"FD,allow}}
+\ltjsetparameter{alxspmode={"FE,allow}}
+\ltjsetparameter{alxspmode={"FF,allow}}
+%
+% inhibitxspcode
+\ltjsetparameter{jaxspmode={`ã€,postonly}}
+\ltjsetparameter{jaxspmode={`。,postonly}}
+\ltjsetparameter{jaxspmode={`,,postonly}}
+\ltjsetparameter{jaxspmode={`.,postonly}}
+\ltjsetparameter{jaxspmode={`ï¼›,postonly}}
+\ltjsetparameter{jaxspmode={`?,postonly}}
+\ltjsetparameter{jaxspmode={`),postonly}}
+\ltjsetparameter{jaxspmode={`(,preonly}}
+\ltjsetparameter{jaxspmode={`ï¼½,postonly}}
+\ltjsetparameter{jaxspmode={`ï¼»,preonly}}
+\ltjsetparameter{jaxspmode={`ï½,postonly}}
+\ltjsetparameter{jaxspmode={`ï½›,preonly}}
+\ltjsetparameter{jaxspmode={`‘,preonly}}
+\ltjsetparameter{jaxspmode={`’,postonly}}
+\ltjsetparameter{jaxspmode={`“,preonly}}
+\ltjsetparameter{jaxspmode={`â€,postonly}}
+\ltjsetparameter{jaxspmode={`〔,preonly}}
+\ltjsetparameter{jaxspmode={`〕,postonly}}
+\ltjsetparameter{jaxspmode={`〈,preonly}}
+\ltjsetparameter{jaxspmode={`〉,postonly}}
+\ltjsetparameter{jaxspmode={`《,preonly}}
+\ltjsetparameter{jaxspmode={`》,postonly}}
+\ltjsetparameter{jaxspmode={`「,preonly}}
+\ltjsetparameter{jaxspmode={`ã€,postonly}}
+\ltjsetparameter{jaxspmode={`『,preonly}}
+\ltjsetparameter{jaxspmode={`ã€,postonly}}
+\ltjsetparameter{jaxspmode={`ã€,preonly}}
+\ltjsetparameter{jaxspmode={`】,postonly}}
+\ltjsetparameter{jaxspmode={`—,inhibit}}% U+2014 EM DASH
+\ltjsetparameter{jaxspmode={`―,inhibit}}% U+2015 HORIZONTAL BAR
+\ltjsetparameter{jaxspmode={`〜,inhibit}}% U+301C WAVE DASH
+\ltjsetparameter{jaxspmode={`~,inhibit}}% U+FF5E FULLWIDTH TILDE
+\ltjsetparameter{jaxspmode={`…,inhibit}}
+\ltjsetparameter{jaxspmode={`Â¥,inhibit}}% U+00A5 YEN SIGN
+\ltjsetparameter{jaxspmode={`ï¿¥,inhibit}}% U+FFE5 FULLWIDTH YEN SIGN
+\ltjsetparameter{jaxspmode={`°,postonly}}
+\ltjsetparameter{jaxspmode={`′,postonly}}
+\ltjsetparameter{jaxspmode={`″,postonly}}
+%
+% inhibitxspcode JIS X 0213
+%
+\ltjsetparameter{jaxspmode={`⦅,preonly}}
+\ltjsetparameter{jaxspmode={`⦆,postonly}}
+\ltjsetparameter{jaxspmode={`⦅,preonly}}
+\ltjsetparameter{jaxspmode={`ï½ ,postonly}}
+\ltjsetparameter{jaxspmode={`〘,preonly}}
+\ltjsetparameter{jaxspmode={`〙,postonly}}
+\ltjsetparameter{jaxspmode={`〖,preonly}}
+\ltjsetparameter{jaxspmode={`〗,postonly}}
+\ltjsetparameter{jaxspmode={`«,preonly}}
+\ltjsetparameter{jaxspmode={`»,postonly}}
+\ltjsetparameter{jaxspmode={`ã€,preonly}}
+\ltjsetparameter{jaxspmode={`〟,postonly}}
+\ltjsetparameter{jaxspmode={`‼,postonly}}
+\ltjsetparameter{jaxspmode={`â‡,postonly}}
+\ltjsetparameter{jaxspmode={`âˆ,postonly}}
+\ltjsetparameter{jaxspmode={`â‰,postonly}}
+\ltjsetparameter{jaxspmode={`¡,preonly}}
+\ltjsetparameter{jaxspmode={`¿,preonly}}
+\ltjsetparameter{jaxspmode={`ª,postonly}}
+\ltjsetparameter{jaxspmode={`º,postonly}}
+\ltjsetparameter{jaxspmode={`¹,postonly}}
+\ltjsetparameter{jaxspmode={`²,postonly}}
+\ltjsetparameter{jaxspmode={`³,postonly}}
+\ltjsetparameter{jaxspmode={`€,preonly}}
+%
+% inhibitxspcode JIS X 0212
+%
+%\ltjsetparameter{jaxspmode={`¡,preonly}}
+%\ltjsetparameter{jaxspmode={`¿,preonly}}
+%\ltjsetparameter{jaxspmode={`º,postonly}}
+%\ltjsetparameter{jaxspmode={`ª,postonly}}
+\ltjsetparameter{jaxspmode={`â„¢,postonly}}
+%
+% inhibitxspcode åŠè§’片仮å
+%
+\ltjsetparameter{jaxspmode={`。,postonly}}
+\ltjsetparameter{jaxspmode={`、,postonly}}
+\ltjsetparameter{jaxspmode={`ï½¢,preonly}}
+\ltjsetparameter{jaxspmode={`ï½£,postonly}}
+
+\catcode`\_=12
+\directlua{
+ s = table.copy(luatexja.stack.charprop_stack_table[0])
+ s.kanjiskip = nil; s.xkanjiskip = nil
+ table.tofile('ltj-kinsoku.lua', s, 'return', false, true, false)
+}
+
+\bye
diff --git a/macros/luatex/generic/luatexja/src/ltj-latex.sty b/macros/luatex/generic/luatexja/src/ltj-latex.sty
new file mode 100644
index 0000000000..446707bd69
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-latex.sty
@@ -0,0 +1,91 @@
+%
+% ltj-latex.sty
+%
+
+%! ã“ã‚Œã¯å¤–ã‹ã‚‰èª­ã¾ã‚Œãªã„
+%% Avoid multiple loading.
+\csname luatexjalatexLoaded\endcsname
+\edef\ltj@latex@AtEnd{%
+\endlinechar=\the\endlinechar
+\relax}
+\endlinechar\m@ne%
+\def\luatexjalatexLoaded{\endinput}
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{ltj-latex}[2018/08/24 LaTeX support of LuaTeX-ja]
+
+% cleanup at end of the document
+%\let\ltj@@orig@end=\@@end
+%\protected\def\@@end{%
+% \directlua{luatexja.ext_cleanup()}\ltj@@orig@end}
+
+\endlinechar=13
+
+%%% patch for LaTeX
+\usepackage{lltjfont}
+\usepackage{lltjdefs}
+\usepackage{lltjcore}
+
+%%% patching commands
+\RequirePackage{filehook}
+
+\def\ltj@pkgpatch@im#1{%
+ \@ifnextchar[{\ltj@pkgpatch@im@{#1}}{\ltj@pkgpatch@im@{#1}[lltjp-#1]}}%]
+\def\ltj@pkgpatch@im@#1[#2]{%
+ \AtEndOfPackageFile*{#1}{%
+ \@ifpackageloaded{#2}{}{%
+ \@namedef{ver@#2.\@pkgextension}{0000/00/00}%dummy
+ \if\catcode`@=11\let\ltj@temp\relax\else
+ \edef\ltj@temp{\noexpand\catcode`@=\the\catcode`@\relax}\makeatletter
+ \fi
+ \@@input{#2.\@pkgextension}\ltj@temp
+ }%
+ }%
+}
+
+\def\ltj@pkgpatch#1{%
+ \@ifnextchar[{\ltj@pkgpatch@@{#1}}{\ltj@pkgpatch@@{#1}[lltjp-#1]}}%]
+\def\ltj@pkgpatch@@#1[#2]{%
+ \gpreto\@begindocumenthook{%
+ \@ifpackageloaded{#1}{%
+ \@ifpackageloaded{#2}{}{\RequirePackage{#2}}%
+ }{}%
+ }%
+}
+
+%%% default parameters
+\directlua{
+ local s = kpse.find_file('ltj-kinsoku.lua', 'tex')
+ luatexja.stack.charprop_stack_table[0] = s and dofile(s) or {}
+}
+
+\ltjsetparameter{kanjiskip=\z@ plus .4pt minus .5pt,
+ xkanjiskip=.25\zw plus 1pt minus 1pt,
+ autospacing, autoxspacing, jacharrange={-1},
+ yalbaselineshift=\z@, yjabaselineshift=\z@,
+ jcharwidowpenalty=500, differentjfm=paverage
+}
+
+\expandafter\let\csname JY3/mc/m/n/10\endcsname\relax
+
+%%% patch for packages
+\ltj@pkgpatch@im{listings}
+\ltj@pkgpatch{xunicode} %% at \begin{document}
+\ltj@pkgpatch@im{fontspec}
+\ltj@pkgpatch{footmisc} %% at \begin{document}
+\ltj@pkgpatch{tascmac}
+\ltj@pkgpatch{ascmac}[lltjp-tascmac]
+\ltj@pkgpatch@im{stfloats}
+\ltj@pkgpatch{preview} %% at \begin{document}
+ % (preview package has delayed option)
+\ltj@pkgpatch{array} %% at \begin{document}
+\ltj@pkgpatch@im{unicode-math}
+\ltj@pkgpatch@im{siunitx}
+\ltj@pkgpatch@im{microtype}
+
+\RequirePackage{lltjp-geometry}
+
+%%------------------ all done
+\ltj@latex@AtEnd
+\endinput
+%% EOF
diff --git a/macros/luatex/generic/luatexja/src/ltj-lineskip.lua b/macros/luatex/generic/luatexja/src/ltj-lineskip.lua
new file mode 100644
index 0000000000..f5c439e559
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-lineskip.lua
@@ -0,0 +1,116 @@
+--
+-- ltj-lineskip.lua
+--
+luatexja.load_module('base'); local ltjb = luatexja.base
+luatexja.load_module('direction'); local ltjd = luatexja.direction
+luatexja.lineskip = luatexja.lineskip or {}
+
+local to_direct = node.direct.todirect
+local ltjl = luatexja.lineskip
+local id_glue = node.id('glue')
+local id_penalty = node.id('penalty')
+local id_hlist = node.id('hlist')
+local setfield = node.direct.setfield
+local getfield = node.direct.getfield
+local getlist = node.direct.getlist
+local node_new = node.direct.new
+local node_prev = node.direct.getprev
+local node_next = node.direct.getnext
+local getid = node.direct.getid
+local getsubtype = node.direct.getsubtype
+
+local node_getglue = node.getglue
+local setglue = node.direct.setglue
+local function copy_glue (new_glue, old_glue, subtype, new_w)
+ setfield(new_glue, 'subtype', subtype)
+ local w,st,sp,sto,spo = node_getglue(old_glue)
+ setglue(new_glue, new_w or w, st, sp, sto, spo)
+end
+ltjl.copy_glue = copy_glue
+
+function ltjl.p_dummy(before, after)
+ return nil, 0
+end
+function ltjl.l_dummy(dist, g, adj, normal, bw, loc)
+ if dist < tex.lineskiplimit then
+ copy_glue(g, tex.lineskip, 1, tex.lineskip.width + adj)
+ else
+ copy_glue(g, tex.baselineskip, 2, normal)
+ end
+end
+
+local ltj_profiler, ltj_skip = ltjl.p_dummy, ltjl.l_dummy
+function ltjl.setting(profiler, skip_method)
+ ltj_profiler = ltjl['p_'..tostring(profiler)] or ltjl.p_dummy
+ ltj_skip = ltjl['l_'..tostring(skip_method)] or ltjl.l_dummy
+end
+
+do
+ local traverse_id = node.direct.traverse_id
+ local function adjust_glue(nh)
+ local h = to_direct(nh)
+ local bw = tex.baselineskip.width
+ for x in traverse_id(id_glue, h) do
+ local xs = getsubtype(x)
+ if (xs==1) or (xs==2) then
+ local p, n = node_prev(x), node_next(x)
+ if p then
+ local pid = getid(p)
+ while (id_glue<=pid) and (pid<=id_penalty) and node_prev(p) do
+ p = node_prev(p); pid = getid(p)
+ end
+ if pid==id_hlist and getid(n)==id_hlist then
+ local normal = bw - getfield(p, 'depth') - getfield(n, 'height')
+ local lmin, adj = ltj_profiler(p, n, false, bw)
+ ltj_skip(lmin or normal, x, adj, normal, bw)
+ end
+ end
+ end
+ end
+ return true
+ end
+ ltjb.add_to_callback('post_linebreak_filter',
+ adjust_glue, 'ltj.lineskip', 10000)
+end
+
+do
+ local p_dummy = ltjl.p_dummy
+ local make_dir_whatsit = luatexja.direction.make_dir_whatsit
+ local get_dir_count = luatexja.direction.get_dir_count
+ local node_write = node.direct.write
+
+ local function dir_adjust_append_vlist(b, loc, prev, mirrored)
+ local old_b = to_direct(b)
+ local new_b = loc=='box' and
+ make_dir_whatsit(old_b, old_b, get_dir_count(), 'append_vlist') or old_b
+ if prev > -65536000 then
+ local bw = tex.baselineskip.width
+ local normal = bw - prev
+ - getfield(new_b, mirrored and 'depth' or 'height')
+ local lmin, adj = nil, 0
+ local tail = to_direct(tex.nest[tex.nest.ptr].tail)
+ if p_dummy~=ltj_profiler then
+ while tail and (id_glue<=getid(tail)) and (getid(tail)<=id_penalty) do
+ tail = node_prev(tail)
+ end
+ end
+ if tail then
+ if getid(tail)==id_hlist and getid(new_b)==id_hlist then
+ if getfield(tail, 'depth')==prev then
+ lmin, adj = ltj_profiler(tail, new_b, mirrored, bw)
+ end
+ end
+ end
+ local g = node_new(id_glue)
+ ltj_skip(lmin or normal, g, adj, normal, bw, loc)
+ node_write(g)
+ end
+ node_write(new_b)
+ tex.prevdepth = getfield(new_b, mirrored and 'height' or 'depth')
+ return nil -- do nothing on tex side
+ end
+ ltjb.add_to_callback('append_to_vlist_filter',
+ dir_adjust_append_vlist,
+ 'ltj.lineskip', 10000)
+end
+
diff --git a/macros/luatex/generic/luatexja/src/ltj-math.lua b/macros/luatex/generic/luatexja/src/ltj-math.lua
new file mode 100644
index 0000000000..53bcdb340f
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-math.lua
@@ -0,0 +1,181 @@
+--
+-- luatexja/ltj-math.lua
+--
+
+luatexja.load_module('base'); local ltjb = luatexja.base
+luatexja.load_module('direction'); local ltjd = luatexja.direction
+luatexja.load_module('charrange'); local ltjc = luatexja.charrange
+luatexja.load_module('jfont'); local ltjf = luatexja.jfont
+luatexja.load_module('stack'); local ltjs = luatexja.stack
+luatexja.load_module('setwidth'); local ltjw = luatexja.setwidth
+
+local setfield = node.direct.setfield
+local getfield = node.direct.getfield
+local getid = node.direct.getid
+local getsubtype = node.direct.getsubtype
+local getlist = node.direct.getlist
+-- getlist cannot be used for sub_box nodes. Use instead λp. getfield(p, 'head')
+local getchar = node.direct.getchar
+
+local to_node = node.direct.tonode
+local to_direct = node.direct.todirect
+
+local node_traverse = node.direct.traverse
+local node_new = node.direct.new
+local node_next = node.direct.getnext
+local node_remove = node.direct.remove
+local node_free = node.direct.free
+local has_attr = node.direct.has_attribute
+local set_attr = node.direct.set_attribute
+local tex_getcount = tex.getcount
+
+local attr_jchar_class = luatexbase.attributes['ltj@charclass']
+local attr_dir = luatexbase.attributes['ltj@dir']
+local attr_icflag = luatexbase.attributes['ltj@icflag']
+local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
+local attr_jfam = luatexbase.attributes['jfam']
+local attr_yablshift = luatexbase.attributes['ltj@yablshift']
+
+local id_glyph = node.id('glyph')
+local id_hlist = node.id('hlist')
+local id_vlist = node.id('vlist')
+local id_mchar = node.id('math_char')
+local id_sub_box = node.id('sub_box')
+local id_radical = node.id('radical')
+local id_choice = node.id('choice')
+local id_accent = node.id('accent')
+local id_style = node.id('style')
+local id_frac = node.id('fraction')
+local id_simple = node.id('noad')
+local id_sub_mlist = node.id('sub_mlist')
+local id_whatsit = node.id('whatsit')
+local sid_user = node.subtype('user_defined')
+local DIR = luatexja.userid_table.DIR
+local dir_node_auto = luatexja.dir_table.dir_node_auto
+
+local PROCESSED = luatexja.icflag_table.PROCESSED
+
+local ltjf_font_metric_table = ltjf.font_metric_table
+local ltjf_find_char_class = ltjf.find_char_class
+local ltjd_get_dir_count = ltjd.get_dir_count
+local ltjd_make_dir_whatsit = ltjd.make_dir_whatsit
+
+-- table of mathematical characters
+local is_math_letters = {}
+local list_dir
+
+-- vcenter noad ã¯è»¸ã«æƒãˆã‚‹ãŸã‚,欧文ベースライン補正ãŒã‹ã‹ã‚‹
+local function conv_vcenter(sb)
+ local h = getfield(sb, 'head');local hd = getlist(h)
+ if getid(hd)==id_whatsit and
+ getsubtype(hd)==sid_user and getfield(hd, 'user_id')==DIR then
+ local d = node_next(hd)
+ if getid(d)==id_vlist and has_attr(d, attr_dir)>=dir_node_auto then
+ node_free(hd); setfield(h, 'head', nil); node_free(h)
+ setfield(sb, 'head', d); set_attr(d, attr_icflag, 0)
+ end
+ end
+ return sb
+end
+
+local conv_jchar_to_hbox_A
+
+-- sty : 0 (display or text), 1 (script), >=2 (scriptscript)
+local function conv_jchar_to_hbox(head, sty)
+ for p in node_traverse(head) do
+ local pid = getid(p)
+ if pid == id_simple or pid == id_accent then
+ if getsubtype(p)==12 then
+ conv_vcenter(getfield(p, 'nucleus'))
+ else
+ setfield(p, 'nucleus', conv_jchar_to_hbox_A(getfield(p, 'nucleus'), sty))
+ end
+ setfield(p, 'sub', conv_jchar_to_hbox_A(getfield(p, 'sub'), sty+1))
+ setfield(p, 'sup', conv_jchar_to_hbox_A(getfield(p, 'sup'), sty+1))
+ elseif pid == id_choice then
+ setfield(p, 'display', conv_jchar_to_hbox_A(getfield(p, 'display'), 0))
+ setfield(p, 'text', conv_jchar_to_hbox_A(getfield(p, 'text'), 0))
+ setfield(p, 'script', conv_jchar_to_hbox_A(getfield(p, 'script'), 1))
+ setfield(p, 'scriptscript', conv_jchar_to_hbox_A(getfield(p, 'scriptscript'), 2))
+ elseif pid == id_frac then
+ setfield(p, 'num', conv_jchar_to_hbox_A(getfield(p, 'num'), sty+1))
+ setfield(p, 'denom', conv_jchar_to_hbox_A(getfield(p, 'denom'), sty+1))
+ elseif pid == id_radical then
+ setfield(p, 'nucleus', conv_jchar_to_hbox_A(getfield(p, 'nucleus'), sty))
+ setfield(p, 'sub', conv_jchar_to_hbox_A(getfield(p, 'sub'), sty+1))
+ setfield(p, 'sup', conv_jchar_to_hbox_A(getfield(p, 'sup'), sty+1))
+ if getfield(p, 'degree') then
+ setfield(p, 'degree', conv_jchar_to_hbox_A(getfield(p, 'degree'), sty + 1))
+ end
+ elseif pid == id_style then
+ local ps = getfield(p, 'style')
+ if ps == "display'" or ps == 'display'
+ or ps == "text'" or ps == 'text' then
+ sty = 0
+ elseif ps == "script'" or ps == 'script' then
+ sty = 1
+ else sty = 2
+ end
+ end
+ end
+ return head
+end
+
+local MJT = luatexja.stack_table_index.MJT
+local MJS = luatexja.stack_table_index.MJS
+local MJSS = luatexja.stack_table_index.MJSS
+local capsule_glyph_math = ltjw.capsule_glyph_math
+local is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char_direct
+
+conv_jchar_to_hbox_A =
+function (p, sty)
+ if not p then return nil
+ else
+ local pid = getid(p)
+ if pid == id_sub_mlist then
+ if getfield(p, 'head') then
+ setfield(p, 'head', conv_jchar_to_hbox(getfield(p, 'head'), sty))
+ end
+ elseif pid == id_mchar then
+ local fam = has_attr(p, attr_jfam) or -1
+ local pc = getchar(p)
+ if (not is_math_letters[pc]) and is_ucs_in_japanese_char(p) and fam>=0 then
+ local f = ltjs.get_stack_table(MJT + 0x100 * sty + fam, -1, tex_getcount('ltj@@stack'))
+ if f ~= -1 then
+ local q = node_new(id_sub_box)
+ local r = node_new(id_glyph); setfield(r, 'next', nil)
+ setfield(r, 'char', pc); setfield(r, 'font', f); setfield(r, 'subtype', 256)
+ local k = has_attr(r,attr_ykblshift) or 0
+ set_attr(r, attr_ykblshift, 0)
+ -- ltj-setwidth 内ã§å®Ÿéš›ã®ä½ç½®è£œæ­£ã¯ãŠã“ãªã†ã®ã§ï¼Œè£œæ­£é‡ã‚’退é¿
+ local met = ltjf_font_metric_table[f]
+ r = capsule_glyph_math(r, met, met.char_type[ltjf_find_char_class(pc, met)]);
+ setfield(q, 'head', r); node_free(p); p=q;
+ set_attr(r, attr_yablshift, k)
+ end
+ end
+ elseif pid == id_sub_box and getfield(p, 'head') then
+ -- \hbox ã§ç›´ã«ä¸Žãˆã‚‰ã‚ŒãŸå†…容ã¯ä¸Šä¸‹ä½ç½®ã‚’補正ã™ã‚‹å¿…è¦ã¯ãªã„
+ local h = getfield(p, 'head')
+ h = ltjd_make_dir_whatsit(h, h, list_dir, 'math')
+ setfield(p, 'head', h)
+ set_attr(h, attr_icflag, PROCESSED)
+ end
+ end
+ return p
+end
+
+luatexbase.add_to_callback('mlist_to_hlist',
+ function (n, display_type, penalties)
+ n = to_direct(n); list_dir = ltjd_get_dir_count()
+ if getid(n)==id_whatsit and getsubtype(n)==sid_user and
+ getfield(n, 'user_id') == DIR then
+ local old_n = n; n = node_remove(n, n)
+ node_free(old_n); if not n then return nil end
+ end
+ return node.mlist_to_hlist(
+ to_node(conv_jchar_to_hbox(n, 0)),
+ display_type, penalties)
+ end,'ltj.mlist_to_hlist', 1)
+
+luatexja.math = { is_math_letters = is_math_letters }
diff --git a/macros/luatex/generic/luatexja/src/ltj-otf.lua b/macros/luatex/generic/luatexja/src/ltj-otf.lua
new file mode 100644
index 0000000000..0e54210227
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-otf.lua
@@ -0,0 +1,296 @@
+--
+-- luatexja/ltj-otf.lua
+--
+require('unicode')
+require('lualibs')
+
+luatexja.load_module('base'); local ltjb = luatexja.base
+luatexja.load_module('jfont'); local ltjf = luatexja.jfont
+luatexja.load_module('rmlgbm'); local ltjr = luatexja.rmlgbm
+luatexja.load_module('charrange'); local ltjc = luatexja.charrange
+luatexja.load_module('direction'); local ltjd = luatexja.direction
+luatexja.load_module('stack'); local ltjs = luatexja.stack
+
+local id_glyph = node.id('glyph')
+local id_whatsit = node.id('whatsit')
+local sid_user = node.subtype('user_defined')
+
+local setfield = node.direct.setfield
+local getfield = node.direct.getfield
+local getid = node.direct.getid
+local getfont = node.direct.getfont
+local getchar = node.direct.getchar
+local getsubtype = node.direct.getsubtype
+
+local to_node = node.direct.tonode
+local to_direct = node.direct.todirect
+
+local node_new = node.direct.new
+local node_remove = node.direct.remove
+local node_next = node.direct.getnext
+local node_free = node.direct.free
+local has_attr = node.direct.has_attribute
+local set_attr = node.direct.set_attribute
+local unset_attr = node.direct.unset_attribute
+local node_insert_after = node.direct.insert_after
+local node_write = node.direct.write
+local node_traverse_id = node.direct.traverse_id
+
+
+local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
+local attr_curtfnt = luatexbase.attributes['ltj@curtfnt']
+local attr_yablshift = luatexbase.attributes['ltj@yablshift']
+local attr_ykblshift = luatexbase.attributes['ltj@ykblshift']
+local attr_tablshift = luatexbase.attributes['ltj@tablshift']
+local attr_tkblshift = luatexbase.attributes['ltj@tkblshift']
+local lang_ja = luatexja.lang_ja
+local identifiers = fonts.hashes.identifiers
+
+local ltjf_font_metric_table = ltjf.font_metric_table
+local ltjf_font_extra_info = ltjf.font_extra_info
+local ltjf_find_char_class = ltjf.find_char_class
+local ltjr_cidfont_data = ltjr.cidfont_data
+local ltjc_is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char
+local ltjd_get_dir_count = ltjd.get_dir_count
+local dir_tate = luatexja.dir_table.dir_tate
+
+luatexja.userid_table.OTF = luatexbase.newuserwhatsitid('char_by_cid', 'luatexja')
+local OTF = luatexja.userid_table.OTF
+local tex_get_attr = tex.getattribute
+
+local cache_var = 2
+local cache_outdate_fn = function (t) return t.version~=cache_ver end
+local ivd_aj1 = ltjb.load_cache('ltj-ivd_aj1',cache_outdate_fn)
+if not ivd_aj1 then -- make cache
+ ivd_aj1 = require('ltj-ivd_aj1.lua')
+ ltjb.save_cache_luc('ltj-ivd_aj1', ivd_aj1)
+end
+
+
+local function get_ucs_from_rmlgbm(c)
+ local v = (ivd_aj1 and ivd_aj1.table_ivd_aj1[c]
+ or ltjr_cidfont_data["Adobe-Japan1"].resources.unicodes["Japan1." .. tostring(c)])
+ or 0
+ if v>=0x200000 then -- table
+ local curjfnt_num = tex_get_attr((ltjd_get_dir_count()==dir_tate)
+ and attr_curtfnt or attr_curjfnt)
+ local curjfnt = identifiers[curjfnt_num].resources
+ local base, ivs = v % 0x200000, 0xE00FF + math.floor(v/0x200000)
+ curjfnt = curjfnt and curjfnt.variants
+ curjfnt = curjfnt and curjfnt[ivs]
+ return curjfnt and curjfnt[base] or base
+ elseif v<0xF0000 then -- ç´ ç›´ã« Unicode ã«ãƒžãƒƒãƒ—å¯èƒ½
+ return v
+ else -- privete use area
+ local r, aj = nil, ltjr_cidfont_data["Adobe-Japan1"]
+ -- 先㫠ltj_vert_table を見る
+ for i,w in pairs(aj.shared.ltj_vert_table) do
+ if w==v then r=i; break end
+ end
+ if not r then
+ -- ãªã‘れ㰠ToUnicode ã‹ã‚‰å¼•ã
+ local w = aj.characters[v].tounicode -- must be non-nil!
+ local i = string.len(w)
+ if i==4 then -- UCS2
+ r = tonumber(w,16)
+ elseif i==8 then
+ i,w = tonumber(string.sub(w,1,4),16), tonumber(string.sub(w,-4),16)
+ if (w>=0xD800) and (w<=0xDB7F) and (i>=0xDC00) and (i<=0xDFFF) then -- Surrogate pair
+ r = (w-0xD800)*0x400 + (i-0xDC00)
+ else
+ r = 0
+ end
+ end
+ end
+ if aj.shared.ltj_vert_table[r] then
+ -- CID ãŒç¸¦çµ„用字形ã ã£ãŸå ´åˆ
+ local curjfnt_num = tex_get_attr((ltjd_get_dir_count()==dir_tate)
+ and attr_curtfnt or attr_curjfnt)
+ local t = identifiers[curjfnt_num]
+ if t.resources.sequences then
+ for _,i in pairs(t.resources.sequences) do
+ if (i.order[1]=='vert' or i.order[1]=='vrt2')
+ and i.type == 'gsub_single' and i.steps then
+ for _,j in pairs(i.steps) do
+ if type(j)=='table' then
+ if type(j.coverage)=='table' then
+ for i,k in pairs(j.coverage) do
+ if i==r then return k end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return r
+ end
+end
+
+-- Append a whatsit node to the list.
+-- This whatsit node will be extracted to a glyph_node
+local function append_jglyph(char)
+ local p = node_new(id_whatsit,sid_user)
+ setfield(p, 'user_id', OTF)
+ setfield(p, 'type', 100)
+ setfield(p, 'value', char)
+ node_write(p)
+end
+
+local utf
+do
+ utf = function (ucs)
+ local char = ucs
+ if ltjd_get_dir_count()==dir_tate then
+ local curjfnt_num = tex_get_attr((ltjd_get_dir_count()==dir_tate)
+ and attr_curtfnt or attr_curjfnt)
+ local t = identifiers[curjfnt_num]
+ if t.resources.sequences then
+ for _,i in pairs(t.resources.sequences) do
+ if (i.order[1]=='vert' or i.order[1]=='vrt2')
+ and i.type == 'gsub_single' and i.steps then
+ for _,j in pairs(i.steps) do
+ if type(j)=='table' then
+ if type(j.coverage)=='table' then
+ for i,k in pairs(j.coverage) do
+ if i==char then return append_jglyph(k) end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return append_jglyph(char)
+ end
+end
+
+local cid
+do
+ cid = function (key)
+ if key==0 then return append_jglyph(0) end
+ local curjfnt_num = tex_get_attr((ltjd_get_dir_count()==dir_tate)
+ and attr_curtfnt or attr_curjfnt)
+ local curjfnt = identifiers[curjfnt_num]
+ local cidinfo = curjfnt.resources.cidinfo
+ if not cidinfo or
+ cidinfo.ordering ~= "Japan1" and
+ cidinfo.ordering ~= "GB1" and
+ cidinfo.ordering ~= "CNS1" and
+ cidinfo.ordering ~= "Korea1" and
+ cidinfo.ordering ~= "KR" then
+ -- ltjb.package_warning('luatexja-otf',
+ -- 'Current Japanese font (or other CJK font) "'
+ -- ..curjfnt.psname..'" is not a CID-Keyed font (Adobe-Japan1 etc.)')
+ return append_jglyph(get_ucs_from_rmlgbm(key))
+ else
+ local char = ltjf_font_extra_info[curjfnt_num].ind_to_uni[key]
+ if not char then
+-- ltjb.package_warning('luatexja-otf',
+-- '"' ..curjfnt.psname..'" does not have CID character '
+-- ..tostring(key),
+-- 'Use a font including the specified CID character.')
+ char = 0
+ end
+ return append_jglyph(char)
+ end
+ end
+end
+
+local function extract(head)
+ head = to_direct(head)
+ local p = head
+ local is_dir_tate = ltjs.list_dir == dir_tate
+ local attr_ablshift = is_dir_tate and attr_tablshift or attr_yablshift
+ local attr_kblshift = is_dir_tate and attr_tkblshift or attr_ykblshift
+ local attr_curfnt = is_dir_tate and attr_curtfnt or attr_curjfnt
+ while p do
+ if getid(p)==id_whatsit then
+ if getsubtype(p)==sid_user then
+ local puid = getfield(p, 'user_id')
+ if puid==OTF then
+ --if puid==OTF or puid==VSR then
+ local g = node_new(id_glyph)
+ setfield(g, 'subtype', 0)
+ setfield(g, 'char', getfield(p, 'value'))
+ local v = has_attr(p, attr_curfnt); setfield(g, 'font',v)
+ --if puid==OTF then
+ setfield(g, 'lang', lang_ja)
+ set_attr(g, attr_kblshift, has_attr(p, attr_kblshift))
+ --else
+ -- set_attr(g, attr_ablshift, has_attr(p, attr_ablshift))
+ --end
+ head = node_insert_after(head, p, g)
+ head = node_remove(head, p)
+ node_free(p); p = g
+ end
+ end
+ end
+ p = node_next(p)
+ end
+ return to_node(head)
+end
+
+ltjb.add_to_callback('hpack_filter', extract,'ltj.otf',
+ luatexbase.priority_in_callback('hpack_filter', 'ltj.main'))
+ltjb.add_to_callback('pre_linebreak_filter', extract,'ltj.otf',
+ luatexbase.priority_in_callback('pre_linebreak_filter', 'ltj.main'))
+-- additional callbacks
+-- 以下ã¯ï¼ŒLuaTeX-ja ã«ç”¨æ„ã•ã‚ŒãŸ callback ã®ã‚µãƒ³ãƒ—ルã«ãªã£ã¦ã„る.
+-- JFM ã®æ–‡å­—クラスã®æŒ‡å®šã®æ‰€ã§ï¼Œ"AJ1-xxx" å½¢å¼ã§ã®æŒ‡å®šã‚’å¯èƒ½ã¨ã—ãŸï¼Ž
+
+-- 和文フォント読ã¿è¾¼ã¿æ™‚ã«ï¼Œind -> unicode 対応をã¨ã£ã¦ãŠã.
+local function ind_to_uni(fmtable, fn)
+ local fi = identifiers[fn]
+ local t = ltjf_font_extra_info[fn].ind_to_uni
+ if t and fi.resources and fi.resources.cidinfo
+ and fi.resources.cidinfo.ordering == "Japan1" then
+ for i, v in pairs(fmtable.chars) do
+ local j = string.match(i, "^AJ1%-([0-9]*)")
+ if j then
+ j = t[i]
+ if j then
+ fmtable.cid_char_type = fmtable.cid_char_type or {}
+ fmtable.cid_char_type[j] = v
+ end
+ end
+ end
+ end
+ return fmtable
+end
+luatexbase.add_to_callback("luatexja.define_jfont",
+ ind_to_uni, "ltj.otf.define_jfont", 1)
+-- æ—¢ã«èª­ã¿è¾¼ã¾ã‚Œã¦ã„るフォントã«å¯¾ã—ã¦ã‚‚,åŒã˜ã“ã¨ã‚’やらãªã„ã¨ã„ã‘ãªã„
+for fn, v in pairs(ltjf_font_metric_table) do
+ ltjf_font_metric_table[fn] = ind_to_uni(v, fn)
+end
+
+
+local function cid_set_char_class(arg, fmtable, char)
+ if arg~=0 then return arg
+ elseif fmtable.cid_char_type then
+ return fmtable.cid_char_type[char] or 0
+ else return 0
+ end
+end
+luatexbase.add_to_callback("luatexja.find_char_class",
+ cid_set_char_class, "ltj.otf.find_char_class", 1)
+
+--IVS
+local function enable_ivs()
+ ltjb.package_warning('luatexja-otf',
+ 'luatexja.otf.enable_ivs() has now no effect.')
+end
+local disable_ivs = enable_ivs
+
+luatexja.otf = {
+ append_jglyph = append_jglyph,
+ enable_ivs = enable_ivs, -- éš ã—機能: IVS
+ disable_ivs = disable_ivs, -- éš ã—機能: IVS
+ cid = cid, utf = utf,
+}
+
+
+-- EOF
diff --git a/macros/luatex/generic/luatexja/src/ltj-plain.sty b/macros/luatex/generic/luatexja/src/ltj-plain.sty
new file mode 100644
index 0000000000..4277998e9d
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-plain.sty
@@ -0,0 +1,110 @@
+%
+% ltj-plain.sty
+%
+
+%! ã“ã‚Œã¯å¤–ã‹ã‚‰èª­ã¾ã‚Œãªã„
+%% Avoid multiple loading.
+\csname luatexjaplainLoaded\endcsname
+\edef\ltj@plain@AtEnd{%
+\endlinechar=\the\endlinechar
+\relax}
+\endlinechar=-1 %
+\def\luatexjaplainLoaded{\endinput}
+
+\ifltj@in@latex %<*LaTeX>
+ \NeedsTeXFormat{LaTeX2e}
+ \PackageWarning{ltj-plain}{Don't load this package directly; load luatexja.sty instead.}
+ \ProvidesPackage{ltj-plain}[2019/05/01]
+\fi %</LaTeX>
+
+%%------------------
+
+\endlinechar=13
+%! ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
+% LuaTeX-ja macros against plain TeX
+
+\ifdefined\ltj@stdmcfont\else\def\ltj@stdmcfont{IPAExMincho}\fi
+\ifdefined\ltj@stdgtfont\else\def\ltj@stdgtfont{IPAExGothic}\fi
+\ifdefined\ltj@stdyokojfm\else\def\ltj@stdyokojfm{ujis}\fi
+\ifdefined\ltj@stdtatejfm\else\def\ltj@stdtatejfm{ujisv}\fi
+\newread\ltj@@cfgread
+\openin\ltj@@cfgread{luatexja.cfg}%
+\ifeof\ltj@@cfgread
+ \@PackageInfoNoLine{ltj-plain}{Cannot find file `luatexja.cfg'}%
+\else
+ \closein\ltj@@cfgread
+ \input luatexja.cfg
+\fi
+\let\ltj@@cfgread\relax\advance\count16\m@ne\relax
+
+\jfont\tenmin=\ltj@stdmcfont:jfm=\ltj@stdyokojfm\space at 9.62216pt
+\jfont\sevenmin=\ltj@stdmcfont:jfm=\ltj@stdyokojfm\space at 6.73551pt
+\jfont\fivemin=\ltj@stdmcfont:jfm=\ltj@stdyokojfm\space at 4.81108pt
+\jfont\tengt=\ltj@stdgtfont:jfm=\ltj@stdyokojfm\space at 9.62216pt
+\jfont\sevengt=\ltj@stdgtfont:jfm=\ltj@stdyokojfm\space at 6.73551pt
+\jfont\fivegt=\ltj@stdgtfont:jfm=\ltj@stdyokojfm\space at 4.81108pt
+
+\tfont\tentmin=\ltj@stdmcfont:jfm=\ltj@stdtatejfm\space at 9.62216pt
+\tfont\seventmin=\ltj@stdmcfont:jfm=\ltj@stdtatejfm\space at 6.73551pt
+\tfont\fivetmin=\ltj@stdmcfont:jfm=\ltj@stdtatejfm\space at 4.81108pt
+\tfont\tentgt=\ltj@stdgtfont:jfm=\ltj@stdtatejfm\space at 9.62216pt
+\tfont\seventgt=\ltj@stdgtfont:jfm=\ltj@stdtatejfm\space at 6.73551pt
+\tfont\fivetgt=\ltj@stdgtfont:jfm=\ltj@stdtatejfm\space at 4.81108pt
+
+\def\mc{\tenmin\tentmin}
+\def\gt{\tengt\tentgt}
+\mc
+
+\directlua{
+ local s = kpse.find_file('ltj-kinsoku.lua', 'tex')
+ luatexja.stack.charprop_stack_table[0] = s and dofile(s) or {}
+}
+
+\ltjsetparameter{kanjiskip=\z@ plus .4pt minus .4pt,
+ xkanjiskip=.25\zw plus 1pt minus 1pt,
+ autospacing, autoxspacing, jacharrange={-1},
+ yalbaselineshift=\z@, yjabaselineshift=\z@,
+ jcharwidowpenalty=500, differentjfm=paverage,
+ jatextfont={0, \tenmin}, jascriptfont={0, \sevenmin},
+ jascriptscriptfont={0, \fivemin},
+}
+\setbox\z@=\hbox{M}
+\jfam\z@
+\ltjsetparameter{talbaselineshift=.5\ht0, tjabaselineshift=\z@}
+
+\ltjdefcharrange{1}{"80-"36F, "1E00-"1EFF}
+\ltjdefcharrange{2}{"370-"4FF, "1F00-"1FFF}
+\ltjdefcharrange{3}{%
+ "2000-"243F, "2500-"27BF, "2900-"29FF, "2B00-"2BFF}
+\ltjdefcharrange{4}{%
+ "500-"10FF, "1200-"1DFF, "2440-"245F, "27C0-"28FF, "2A00-"2AFF,
+ "2C00-"2E7F, "4DC0-"4DFF, "A4D0-"A95F, "A980-"ABFF, "E000-"F8FF,
+ "FB00-"FE0F, "FE20-"FE2F, "FE70-"FEFF, "10000-"1AFFF, "1B170-"1F0FF,
+ "1F300-"1FFFF
+} % non-Japanese
+\ltjdefcharrange{5}{"D800-"DFFF, "E0000-"E00FF, "E01F0-"10FFFF}
+\ltjdefcharrange{6}{%
+ "2460-"24FF, "2E80-"2EFF, "3000-"30FF, "3190-"319F, "31F0-"4DBF,
+ "4E00-"9FFF, "F900-"FAFF, "FE10-"FE1F, "FE30-"FE6F, "FF00-"FFEF,
+ "1B000-"1B16F, "1F100-"1F2FF, "20000-"2FFFF, "E0100-"E01EF
+}
+\ltjdefcharrange{7}{%
+ "1100-"11FF, "2F00-"2FFF, "3100-"318F, "31A0-"31EF, "A000-"A4CF,
+ "A960-"A97F, "AC00-"D7FF
+}
+\ltjdefcharrange{8}{"A7, "A8, "B0, "B1, "B4, "B6, "D7, "F7}
+\ltjsetparameter{jacharrange={-1, +2, +3, -4, -5, +6, +7, -8}}
+
+\directlua{for x=128,255 do luatexja.math.is_math_letters[x] = true end}
+\let\ltj@@orig@end=\@@end
+\protected\def\@@end{%
+ \directlua{luatexja.ext_cleanup()}\ltj@@orig@end}
+
+\directlua{luatexja.jfont.register_vert_replace{
+ [',']='ã€', ['.']='。', ['“']=0x301D, ['â€']=0x301F,
+}}
+
+%%------------------ all done
+\ltj@plain@AtEnd
+\endinput
+%% EOF
diff --git a/macros/luatex/generic/luatexja/src/ltj-pretreat.lua b/macros/luatex/generic/luatexja/src/ltj-pretreat.lua
new file mode 100644
index 0000000000..3f37278e54
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-pretreat.lua
@@ -0,0 +1,188 @@
+--
+-- luatexja/ltj-pretreat.lua
+--
+
+luatexja.load_module('base'); local ltjb = luatexja.base
+luatexja.load_module('charrange'); local ltjc = luatexja.charrange
+luatexja.load_module('stack'); local ltjs = luatexja.stack
+luatexja.load_module('jfont'); local ltjf = luatexja.jfont
+luatexja.load_module('direction'); local ltjd = luatexja.direction
+
+local to_node = node.direct.tonode
+local to_direct = node.direct.todirect
+
+local setfield = node.direct.setfield
+local getid = node.direct.getid
+local getfont = node.direct.getfont
+local getchar = node.direct.getchar
+local getfield = node.direct.getfield
+local getsubtype = node.direct.getsubtype
+local getlang = node.direct.getlang or function (n) return getfield(n,'lang') end
+
+local pairs = pairs
+local floor = math.floor
+local has_attr = node.direct.has_attribute
+local set_attr = node.direct.set_attribute
+local node_traverse = node.direct.traverse
+local node_remove = node.direct.remove
+local node_next = node.direct.getnext
+local node_free = node.direct.free
+local node_end_of_math = node.direct.end_of_math
+local tex_getcount = tex.getcount
+
+local id_glyph = node.id('glyph')
+local id_math = node.id('math')
+local id_whatsit = node.id('whatsit')
+local sid_user = node.subtype('user_defined')
+
+local attr_dir = luatexbase.attributes['ltj@dir']
+local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
+local attr_curtfnt = luatexbase.attributes['ltj@curtfnt']
+local attr_icflag = luatexbase.attributes['ltj@icflag']
+
+local is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char_direct
+local ltjs_orig_char_table = ltjs.orig_char_table
+local ltjf_replace_altfont = ltjf.replace_altfont
+local STCK = luatexja.userid_table.STCK
+local DIR = luatexja.userid_table.DIR
+local JA_AL_BDD = luatexja.userid_table.JA_AL_BDD
+local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
+
+local dir_tate = luatexja.dir_table.dir_tate
+local lang_ja = luatexja.lang_ja
+
+local setlang = node.direct.setlang or function(n,l) setfield(n,'lang',l) end
+local setfont = node.direct.setfont or function(n,l) setfield(n,'font',l) end
+local setchar = node.direct.setchar or function(n,l) setfield(n,'char',l) end
+
+------------------------------------------------------------------------
+-- MAIN PROCESS STEP 1: replace fonts
+------------------------------------------------------------------------
+local wt, wtd = {}, {}
+do
+ local ltjd_get_dir_count = ltjd.get_dir_count
+ local start_time_measure, stop_time_measure
+ = ltjb.start_time_measure, ltjb.stop_time_measure
+ local head
+ local suppress_hyphenate_ja_aux = {
+ [id_math] = function(p) return node_next(node_end_of_math(node_next(p))) end,
+ [id_whatsit] = function(p)
+ if getsubtype(p)==sid_user then
+ local uid = getfield(p, 'user_id')
+ if uid==STCK then
+ wt[#wt+1] = p; node_remove(head, p)
+ elseif uid==DIR then
+ if has_attr(p, attr_icflag)<PROCESSED_BEGIN_FLAG then
+ ltjs.list_dir = has_attr(p, attr_dir)
+ else -- ã“ã£ã¡ã®ã‚±ãƒ¼ã‚¹ã¯é€šå¸¸ä½¿ç”¨ã§ã¯èµ·ã“らãªã„
+ wtd[#wtd+1] = p; node_remove(head, p)
+ end
+ end
+ end
+ return node_next(p)
+ end,
+ }
+ setmetatable(suppress_hyphenate_ja_aux,
+ {
+ __index = function() return node_next end,
+ })
+ local id_boundary = node.id('boundary')
+ local node_new, insert_before = node.direct.new, node.direct.insert_before
+ local setsubtype = node.direct.setsubtype or function(n,l) setfield(n,'subtype',l) end
+ local function suppress_hyphenate_ja (h)
+ start_time_measure('ltj_hyphenate')
+ head = to_direct(h)
+ for i = 1,#wt do wt[i]=nil end
+ for i = 1,#wtd do wtd[i]=nil end
+ for i,_ in pairs(ltjs_orig_char_table) do
+ ltjs_orig_char_table[i] = nil
+ end
+ ltjs.list_dir=ltjd_get_dir_count()
+ do
+ local p = head
+ while p do
+ local pid, prev_chartype = getid(p), 0
+ -- prev_chartype: 0: not char 1: ALchar 2: JAchar
+ while pid==id_glyph do
+ local pc = getchar(p)
+ if has_attr(p, attr_icflag, 0) and is_ucs_in_japanese_char(p, pc) then
+ if prev_chartype==1 then
+ local b = node_new(id_whatsit,sid_user);
+ setfield(b, 'type', 100); setfield(b, 'user_id', JA_AL_BDD);
+ insert_before(head, p, b)
+ end
+ local pf = has_attr(p, attr_curjfnt)
+ pf = (pf and pf>0 and pf) or getfont(p)
+ setfont(p, ltjf_replace_altfont(pf, pc))
+ setlang(p, lang_ja)
+ ltjs_orig_char_table[p], prev_chartype = pc, 2
+ elseif prev_chartype==2 then
+ local b = node_new(id_whatsit,sid_user);
+ setfield(b, 'type', 100); setfield(b, 'user_id', JA_AL_BDD);
+ insert_before(head, p, b); prev_chartype = 1
+ else prev_chartype = 1
+ end
+ p = node_next(p); pid = getid(p)
+ end
+ p = (suppress_hyphenate_ja_aux[pid])(p)
+ end
+ end
+ stop_time_measure('ltj_hyphenate'); start_time_measure('tex_hyphenate')
+ lang.hyphenate(h, nil)
+ stop_time_measure('tex_hyphenate')
+ return h
+ end
+
+ ltjb.add_to_callback('hyphenate',
+ function (head,tail)
+ return suppress_hyphenate_ja(head)
+ end,'ltj.hyphenate')
+end
+
+-- mode: true iff this function is called from hpack_filter
+local ltjs_report_stack_level = ltjs.report_stack_level
+local ltjf_font_metric_table = ltjf.font_metric_table
+local font_getfont = font.getfont
+local function set_box_stack_level(head, mode)
+ local box_set, cl = 0, tex.currentgrouplevel + 1
+ if mode then
+ for _,p in pairs(wt) do
+ if getfield(p, 'value')==cl then box_set = 1 end; node_free(p)
+ end
+ else
+ for _,p in pairs(wt) do node_free(p) end
+ end
+ ltjs_report_stack_level(tex_getcount('ltj@@stack') + box_set)
+ for _,p in pairs(wtd) do
+ node_free(p)
+ end
+ if ltjs.list_dir == dir_tate then
+ for p in node.direct.traverse_id(id_glyph,to_direct(head)) do
+ if has_attr(p, attr_icflag, 0) and getlang(p)==lang_ja then
+ local nf = ltjf_replace_altfont( has_attr(p, attr_curtfnt) or getfont(p) , ltjs_orig_char_table[p])
+ setfont(p, nf)
+ if ltjf_font_metric_table[nf].vert_activated then
+ local pc = getchar(p)
+ pc = ltjf_font_metric_table[nf].vform[pc]
+ if pc then setchar(p, pc) end
+ end
+ end
+ end
+ end
+ return head
+end
+
+-- CALLBACKS
+ltjb.add_to_callback('hpack_filter',
+ function (head)
+ return set_box_stack_level(head, true)
+ end,'ltj.set_stack_level',1)
+ltjb.add_to_callback('pre_linebreak_filter',
+ function (head)
+ return set_box_stack_level(head, false)
+ end,'ltj.set_stack_level',1)
+
+luatexja.pretreat = {
+ set_box_stack_level = set_box_stack_level,
+ orig_char_table = orig_char_table,
+}
diff --git a/macros/luatex/generic/luatexja/src/ltj-rmlgbm.lua b/macros/luatex/generic/luatexja/src/ltj-rmlgbm.lua
new file mode 100644
index 0000000000..357560c4bf
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-rmlgbm.lua
@@ -0,0 +1,416 @@
+--
+-- luatexja/ltj-rmlgbm.lua
+--
+luatexja.load_module('base'); local ltjb = luatexja.base
+
+local cidfont_data = {}
+local cache_chars = {}
+local cache_ver = 8
+local identifiers = fonts.hashes.identifiers
+
+local cid_reg, cid_order, cid_supp, cid_name
+local cid_replace = {
+ ["Adobe-Japan1"] = {"UniJIS2004-UTF32", 23059, 7,
+ function (i)
+ if (231<=i and i<=632) or (8718<=i and i<=8719)
+ or (12063<=i and i<=12087) then
+ return 327680 -- 655360/2
+ elseif 9758<=i and i<=9778 then
+ return 218453 -- 655360/3
+ elseif 9738<=i and i<=9757 then
+ return 163840 -- 655360/4
+ end
+ end},
+ -- 基本的ã«ã¯ JIS X 0213:2004 ã«æ²¿ã£ãŸãƒžãƒƒãƒ”ング
+ ["Adobe-Korea1"] = {"UniKS-UTF32", 18351, 2,
+ function (i)
+ if 8094<=i and i<=8100 then
+ return 327680 -- 655360/2
+ end
+ end},
+ ["Adobe-GB1"] = {"UniGB-UTF32", 30283, 5,
+ function (i)
+ if (814<=i and i<=939) or (i==7716)
+ or (22355<=i and i<=22357) then
+ return 327680 -- 655360/2
+ end
+ end},
+ ["Adobe-CNS1"] = {"UniCNS-UTF32", 19178, 7,
+ function (i)
+ if (13648<=i and i<=13742) or (i==17603) then
+ return 327680 -- 655360/2
+ end
+ end},
+ ["Adobe-KR"] = {"UniAKR-UTF32", 22896, 9,
+ function (i)
+ if i==3057 then
+ return 655360*2
+ elseif i==3058 then
+ return 655360*3
+ elseif i==12235 or i==12236 then
+ return 163840 -- 655360/4
+ end
+ end},
+}
+
+-- reading CID maps
+local make_cid_font
+do
+ local line, fh -- line, file handler
+ local tt,cidm -- characters, cid->(Unicode)
+
+ local function load_cid_char(cid_dec, mke)
+ local cid, ucs, ucsa
+ line = fh:read("*l")
+ while line do
+ if string.find(line, "end...?char") then
+ line = fh:read("*l"); return
+ else -- WMA l is in the form "<%x+>%s%d+"
+ ucs, cid = string.match(line, "<(%x+)>%s+<?(%x+)>?")
+ cid = cid_dec(cid); ucs = tonumber(ucs, 16);
+ if not tt[ucs] then
+ tt[ucs] = mke(cid); cidm[cid]=ucs
+ end
+ end
+ line = fh:read("*l")
+ end
+ end
+
+ local function load_cid_range(inc, cid_dec, mke)
+ local bucs, eucs, cid
+ line = fh:read("*l")
+ while line do
+ if string.find(line, "end...?range") then
+ line = fh:read("*l"); return
+ else -- WMA l is in the form "<%x+>%s+<%x+>"
+ bucs, eucs, cid = string.match(line, "<(%x+)>%s+<(%x+)>%s+<?(%x+)>?")
+ cid = cid_dec(cid);
+ bucs = tonumber(bucs, 16); eucs = tonumber(eucs, 16)
+ for ucs = bucs, eucs do
+ if not tt[ucs] then
+ tt[ucs] = mke(cid); cidm[cid]=ucs
+ end
+ cid = inc(cid)
+ end
+ end
+ line = fh:read("*l")
+ end
+ end
+
+ local function open_cmap_file(name, inc, cid_dec, mke)
+ local fn = kpse.find_file(name, 'cmap files')
+ if fn then
+ fh = io.open(fn, "r")
+ line = fh:read("*l")
+ while line do
+ if string.find(line, "%x+%s+begin...?char") then
+ load_cid_char(cid_dec, mke)
+ elseif string.find(line, "%x+%s+begin...?range") then
+ load_cid_range(inc, cid_dec, mke)
+ else
+ line = fh:read("*l")
+ end
+ end
+ fh:close();
+ end
+ end
+
+ local function increment(a) return a+1 end
+ local function entry(a)
+ return {index = a}
+ end
+ local feat_dummy_vert = { gsub={vert={dflt={dflt=true}}} }
+ local seq_dummy_vert={{
+ features={vert={dflt={dflt=true}}},
+ --flags={false,false,false,false},
+ --index=1, name="s_s_0", skiphash=false, steps={coverage={},index=1},
+ ["type"]="gsub_single", order='vert',
+ }}
+ make_cid_font = function ()
+ local kx = cid_replace[cid_name]
+ if not kx then return end
+ local k = {
+ cidinfo = { ordering=cid_order, registry=cid_reg, supplement=kx[3] },
+ encodingbytes = 2, extend=1000, format = 'opentype',
+ direction = 0, characters = {}, parameters = {
+ ascender = 655360*0.88,
+ descender = 655360*0.12,
+ },
+ embedding = "no", cache = "yes", factor = 0, hfactor = 0, vfactor = 0,
+ tounicode = 1,
+ properties = { language = "dflt", script = "dflt" },
+ }
+ cidfont_data[cid_name] = k
+
+ -- CID => Unicode 符å·ç©ºé–“
+ local tth, cidmo = {}, {}
+ tt, cidm = tth, cidmo
+ for i = 0,kx[2] do cidm[i] = -1 end
+ open_cmap_file(kx[1] .. "-H", increment, tonumber, entry)
+ k.characters = tth
+
+ -- Unicode ã«ãƒžãƒƒãƒ—ã•ã‚Œãªã‹ã£ãŸæ–‡å­—ã®å‡¦ç†
+ -- ã“れら㯠TrueType フォントを使ã£ã¦è¡¨ç¤ºã™ã‚‹ã¨ãã¯ãŠã‹ã—ããªã‚‹
+ local ttu, pricode = {}, 0xF0000
+ for i,v in ipairs(cidmo) do
+ if v==-1 then
+ tth[pricode], cidmo[i], pricode
+ = { index = i }, pricode, pricode+1;
+ end
+ ttu[cid_order .. '.' .. i] = cidmo[i]
+ end
+
+ -- shared
+ k.shared = {
+ otfdata = {
+ cidinfo= k.cidinfo, verbose = false,
+ shared = { featuredata = {}, },
+ },
+ dynamics = {}, processes = {},
+ rawdata = {}, features={},
+ }
+ k.resources = {
+ unicodes = ttu,
+ features = feat_dummy_vert,
+ sequences = seq_dummy_vert,
+ }
+ k.descriptions = {}
+ k.shared.rawdata.resources=k.resources
+ k.shared.rawdata.descriptions=k.descriptions
+ cache_chars[cid_name] = { [655360] = k.characters }
+
+ -- 縦書用字形
+ tt, cidm = {}, {}
+ local ttv = {}; k.shared.ltj_vert_table = ttv
+ for i = 0,kx[2] do cidm[i] = -1 end
+ open_cmap_file(kx[1] .. "-V", increment, tonumber, entry)
+ for i,v in pairs(tt) do
+ ttv[i] = cidmo[v.index] -- "unicode" of vertical variant
+ end
+
+ -- tounicode エントリ
+ local cidp = {nil, nil}; tt, ttu, cidm = {}, {}, {}
+ open_cmap_file(cid_name .. "-UCS2",
+ function(a)
+ a[2] = a[2] +1 ; return a
+ end,
+ function(a)
+ cidp[1] = string.upper(string.sub(a,1,string.len(a)-4))
+ cidp[2] = tonumber(string.sub(a,-4),16)
+ return cidp
+ end,
+ function(a) return a[1] ..string.format('%04X',a[2]) end)
+ -- tt 㯠cid -> tounicode ã«ãªã£ã¦ã„ã‚‹ã®ã§ cidm -> tounicode ã«å¤‰æ›
+ local kxf = kx[4]
+ for i,v in ipairs(cidmo) do
+ k.characters[v].width = kxf(i)
+ if v>=0xF0000 then
+ k.characters[v].tounicode = tt[i]
+ end
+ end
+
+ -- Save
+ k.characters[46].width = math.floor(655360/14);
+ ltjb.save_cache( "ltj-cid-auto-" .. string.lower(cid_name),
+ {
+ version = cache_ver,
+ k,
+ })
+ end
+end
+
+--
+local cidf_vert_processor
+do
+ local traverse_id, is_node = node.direct.traverse_id, node.is_node
+ local to_direct = node.direct.todirect
+ local id_glyph = node.id('glyph')
+ local getfont = node.direct.getfont
+ local getchar = node.direct.getchar
+ local setchar = node.direct.setchar
+ cidf_vert_processor = {
+ function (head, fnum)
+ local fontdata = identifiers[fnum]
+ if head and luatexja.jfont.font_metric_table[fnum].vert_activated then
+ local vt = fontdata.shared.ltj_vert_table
+ local nh = is_node(head) and to_direct(head) or head
+ for n in traverse_id(id_glyph, head) do
+ if getfont(n)==fnum then
+ local c = getchar(n); setchar(n, vt[c] or c)
+ end
+ end
+ return head, false
+ end
+ end
+ }
+end
+
+local function cid_cache_outdated(t) return t.version~=cache_ver end
+local function read_cid_font()
+ local dat = ltjb.load_cache("ltj-cid-auto-" .. string.lower(cid_name),
+ cid_cache_outdated )
+ if dat then
+ cidfont_data[cid_name] = dat[1]
+ cache_chars[cid_name] = { [655360] = cidfont_data[cid_name].characters }
+ else
+ -- Now we must create the virtual metrics from CMap.
+ make_cid_font()
+ end
+ if cidfont_data[cid_name] then
+ cidfont_data[cid_name].shared.processes = cidf_vert_processor
+ for i,v in pairs(cidfont_data[cid_name].characters) do
+ if not v.width then v.width = 655360 end
+ v.height, v.depth = 576716.8, 78643.2 -- optimized for jfm-ujis.lua
+ end
+ return cidfont_data[cid_name]
+ else
+ return nil
+ end
+end
+
+-- High-level
+local function prepare_cid_font(reg, ord)
+ cid_reg, cid_order, cid_name, cid_supp = reg, ord, reg .. '-' .. ord
+ return cidfont_data[cid_name] or read_cid_font()
+end
+
+
+local definers = fonts.definers
+local function mk_rml(name, size, id)
+ local specification = definers.analyze(name,size)
+ --specification = definers.resolve(specification) (not needed)
+ specification.detail = specification.detail or ''
+ do
+ local n = specification.name
+ if n:sub(1,1)=="{" then n=n:sub(2) end
+ if n:sub(-1)=="}" then n=n:sub(1,-2) end
+ specification.name=n
+ end
+ local fontdata = {}
+ local cachedata = {}
+ local s = cidfont_data[cid_name]
+ luatexja.rmlgbm.vert_addfunc(id)
+ for k, v in pairs(s) do
+ fontdata[k] = v
+ cachedata[k] = v
+ end
+ fontdata.characters = nil
+ cachedata.characters = nil
+ fontdata.shared = nil
+ cachedata.shared = nil
+ if s.shared then
+ cachedata.shared = {}
+ local shared = cachedata.shared
+ for k, v in pairs(s.shared) do
+ shared[k] = v
+ end
+ end
+
+ -- characters & scaling
+ if size < 0 then size = -size * 655.36 end
+ local scale = size / 655360
+
+ do
+ local def_height = 0.88 * size
+ -- character's default height (optimized for jfm-ujis.lua)
+ local def_depth = 0.12 * size -- and depth.
+ if not cache_chars[cid_name][size] then
+ cache_chars[cid_name][size] = {}
+ for k, v in pairs(cache_chars[cid_name][655360]) do
+ cache_chars[cid_name][size][k] = {
+ index = v.index, width = v.width * scale,
+ height = def_height, depth = def_depth, tounicode = v.tounicode,
+ }
+ end
+ end
+ fontdata.characters = cache_chars[cid_name][size]
+ cachedata.characters = cache_chars[cid_name][size]
+ end
+
+ -- other parameters
+ do
+ local parameters = {}
+ for k, v in pairs(s.parameters) do
+ parameters[k] = v * scale
+ end
+ fontdata.parameters = parameters
+ fontdata.size = size
+ fontdata.resources = s.resources
+ cachedata.parameters = parameters
+ cachedata.size = size
+ cachedata.resources = s.resources
+ end
+
+ -- no embedding
+ local var = ''
+ local s = string.match(specification.detail, 'slant=([+-]*%d*%.?%d)')
+ if s and e~=0 then
+ s = s * 1000
+ var, fontdata.slant = var .. 's' .. tostring(s), s
+ end
+ local e = string.match(specification.detail, 'extend=([+-]*%d*%.?%d)')
+ if e and e~=1 then
+ e = e * 1000
+ var, fontdata.extend = var .. 'x' .. tostring(e), e
+ end
+ fontdata.name = specification.name .. size .. var; cachedata.name = fontdata.name
+ fontdata.fullname = specification.name .. var; cachedata.fullname = fontdata.fullname
+ fontdata.psname = specification.name; cachedata.psname = fontdata.psname
+ identifiers[id] = cachedata
+
+ return fontdata
+end
+
+local function font_callback(name, size, id, fallback)
+ if name:sub(1,1)=="{" and name:sub(-1)=="}" then name = name:sub(2,-2) end
+ local p = name:find(":") or 0
+ if name:sub(1, p-1) == 'psft' then
+ local s = "Adobe-Japan1-7"
+ local basename = name:sub(p+1)
+ local p = basename:find(":")
+ local q = basename:find("/[BI][BI]?")
+ if q and p and q<=p then
+ basename = basename:gsub('/[BI][BI]?', '', 1)
+ p = basename:find(":")
+ end
+ if p then
+ local xname = basename:sub(p+1)
+ p = 1
+ while p do
+ local q = xname:find(";", p+1) or xname:len()+1
+ if xname:sub(p, p+3)=='cid=' and q>p+4 then
+ s = xname:sub(p+4, q-1)
+ end
+ if xname:len()+1==q then p = nil else p = q + 1 end
+ end
+ end
+ cid_reg, cid_order = string.match(s, "^(.-)%-(.-)%-(%d-)$")
+ if not cid_reg then
+ cid_reg, cid_order = string.match(s, "^(.-)%-(.-)$")
+ end
+ if not prepare_cid_font(cid_reg, cid_order) then
+ ltjb.package_error('luatexja',
+ "bad cid key `" .. s .. "'",
+ "I couldn't find any non-embedded font information for the CID\n" ..
+ '`' .. s .. "'. For now, I'll use `Adobe-Japan1-6'.\n"..
+ 'Please contact the LuaTeX-ja project team.')
+ cid_name = "Adobe-Japan1"
+ end
+ return mk_rml(basename, size, id)
+ else
+ local tfmdata=fallback(name, size, id)
+ if type (tfmdata) == "table" and tfmdata.shared then
+ luatexbase.call_callback("luaotfload.patch_font", tfmdata, name)
+ end
+ return tfmdata
+ end
+end
+
+luatexja.rmlgbm = {
+ prepare_cid_font = prepare_cid_font,
+ cidfont_data = cidfont_data,
+ font_callback = font_callback,
+ vert_addfunc = function () end, -- dummy, set in ltj-direction.lua
+}
+
+prepare_cid_font('Adobe', 'Japan1')
diff --git a/macros/luatex/generic/luatexja/src/ltj-ruby.lua b/macros/luatex/generic/luatexja/src/ltj-ruby.lua
new file mode 100644
index 0000000000..060b3226ad
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-ruby.lua
@@ -0,0 +1,782 @@
+--
+-- ltj-ruby.lua
+--
+luatexbase.provides_module({
+ name = 'luatexja.ruby',
+ date = '2018/09/29',
+ description = 'Ruby annotation',
+})
+luatexja.ruby = {}
+luatexja.load_module('stack'); local ltjs = luatexja.stack
+luatexja.load_module('base'); local ltjb = luatexja.base
+
+local to_node = node.direct.tonode
+local to_direct = node.direct.todirect
+
+local setfield = node.direct.setfield
+local setglue = luatexja.setglue
+local getfield = node.direct.getfield
+local getid = node.direct.getid
+local getfont = node.direct.getfont
+local getlist = node.direct.getlist
+local getchar = node.direct.getchar
+local getsubtype = node.direct.getsubtype
+
+local node_new = node.direct.new
+local node_remove = node.direct.remove
+local node_next = node.direct.getnext
+local node_copy, node_free, node_tail = node.direct.copy, node.direct.free, node.direct.tail
+local has_attr, set_attr = node.direct.has_attribute, node.direct.set_attribute
+local insert_before, insert_after = node.direct.insert_before, node.direct.insert_after
+
+local id_hlist = node.id('hlist')
+local id_vlist = node.id('vlist')
+local id_rule = node.id('rule')
+local id_whatsit = node.id('whatsit')
+local id_glue = node.id('glue')
+local id_kern = node.id('kern')
+local id_penalty = node.id('penalty')
+local sid_user = node.subtype('user_defined')
+local ltjs_get_stack_table = luatexja.stack.get_stack_table
+local id_pbox_w = 258 -- cluster which consists of a whatsit
+
+local attr_icflag = luatexbase.attributes['ltj@icflag']
+-- ルビ処ç†ç”¨ã® attribute ã¯ä»–ã®ã‚„ã¤ã®æµç”¨ãªã®ã§æ³¨æ„ï¼
+-- é€²å…¥è¨±å®¹é‡ (sp)
+local attr_ruby_maxprep = luatexbase.attributes['ltj@charclass']
+local attr_ruby_maxpostp = luatexbase.attributes['ltj@kcat0']
+local attr_ruby_maxmargin = luatexbase.attributes['ltj@kcat1']
+local attr_ruby_stretch = luatexbase.attributes['ltj@kcat2']
+local attr_ruby_mode = luatexbase.attributes['ltj@kcat3']
+local attr_ruby_id = luatexbase.attributes['ltj@kcat4'] -- uniq id
+local attr_ruby_intergap = luatexbase.attributes['ltj@kcat5']
+local attr_ruby = luatexbase.attributes['ltj@rubyattr']
+-- ルビ内部処ç†ç”¨ï¼Œä»¥ä¸‹ã®ã‚ˆã†ã«ãƒŽãƒ¼ãƒ‰ã«ã‚ˆã£ã¦ä½¿ã‚れ方ãŒç•°ãªã‚‹
+-- * (whatsit) ã§ã¯ JAglue 処ç†æ™‚ã«ï¼Œ
+-- 「2ã¤å‰ã®ã‚¯ãƒ©ã‚¹ã‚¿ã‚‚ルビ〠==> ãã®ãƒ«ãƒ“クラスタ㮠id
+-- otherwise ==> unset
+-- * (whatsit).value node ã§ã¯ãƒ«ãƒ“全角ã®å€¤ï¼ˆspå˜ä½ï¼‰
+-- * 行分割㧠whatsit ã®å‰å¾Œã«ä¸¦ã¶ãƒŽãƒ¼ãƒ‰ã§ã¯ï¼Œã€Œä½•ç•ªç›®ã®ãƒ«ãƒ“関連ノードã€ã‹
+-- * (whatsit).value ã«ç¶šã整形済㿠vbox ãŸã¡ã§ã¯ post_intrusion ã®å€¤
+local cat_lp = luatexbase.catcodetables['latex-package']
+
+local round, floor = tex.round, math.floor
+local min, max = math.min, math.max
+
+luatexja.userid_table.RUBY_PRE = luatexbase.newuserwhatsitid('ruby_pre', 'luatexja')
+luatexja.userid_table.RUBY_POST = luatexbase.newuserwhatsitid('ruby_post', 'luatexja')
+local RUBY_PRE = luatexja.userid_table.RUBY_PRE
+local RUBY_POST = luatexja.userid_table.RUBY_POST
+local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
+
+----------------------------------------------------------------
+-- TeX interface 0
+----------------------------------------------------------------
+do
+ local getbox = node.direct.getbox
+ function luatexja.ruby.cpbox() return node_copy(getbox(0)) end
+end
+
+----------------------------------------------------------------
+-- 補助関数群 1
+----------------------------------------------------------------
+
+local function gauss(coef)
+ -- #coef å¼ï¼Œ#coef 変数ã®é€£ç«‹1次方程å¼ç³»ã‚’掃ãã ã—法ã§è§£ã.
+ local deg = #coef
+ for i = 1, deg do
+ if coef[i][i]==0 then
+ for j = i+1, deg do
+ if coef[j][i]~=0 then
+ coef[i], coef[j] = coef[j], coef[i]; break
+ end
+ end
+ end
+ for j = 1,deg do
+ local d = coef[i][i];
+ if j~=i then
+ local e = coef[j][i]
+ for k = 1, deg+1 do coef[j][k] = coef[j][k] - e*coef[i][k]/d end
+ else
+ for k = 1, deg+1 do coef[i][k] = coef[i][k]/d end
+ end
+ end
+ end
+end
+
+local function solve_1(coef)
+ local a, b, c = coef[1][4], coef[2][4], coef[3][4]
+ coef[1][4], coef[2][4], coef[3][4] = c-b, a+b-c, c-a
+ return coef
+end
+
+local function solve_2(coef)
+ local a, b, c, d, e = coef[1][6], coef[2][6], coef[3][6], coef[4][6], coef[5][6]
+ coef[1][6], coef[2][6], coef[3][6], coef[4][6], coef[5][6]
+ = e-c, a+c-e, e-a-d, b+d-e, e-b
+ return coef
+end
+
+
+-- 実行回数 + ルビ中身 ã‹ã‚‰ uniq_id を作る関数
+luatexja.ruby.old_break_info = {} -- public, å‰ run 時ã®åˆ†å‰²æƒ…å ±
+local old_break_info = luatexja.ruby.old_break_info
+local cache_handle
+function luatexja.ruby.read_old_break_info()
+ if tex.jobname then
+ local fname = tex.jobname .. '.ltjruby'
+ local real_file = kpse.find_file(fname)
+ if real_file then dofile(real_file) end
+ cache_handle = io.open(fname, 'w')
+ end
+end
+local make_uniq_id
+do
+ local exec_count = 0
+ make_uniq_id = function (w)
+ exec_count = exec_count + 1
+ return exec_count
+ end
+end
+
+-- concatenation of boxes: reusing nodes
+-- ルビ組版ãŒè¡Œã‚ã‚Œã¦ã„る段è½/hboxã§ã®è¨­å®šãŒä½¿ã‚れる.
+-- ルビ文字を格ç´ã—ã¦ã„るボックスã§ã®è¨­å®šã§ã¯ãªã„ï¼
+local concat
+do
+ local node_prev = node.direct.getprev
+ local function get_attr_icflag(p)
+ return (has_attr(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG
+ end
+ function concat(f, b)
+ if f then
+ if b then
+ local h, nh = getlist(f), getlist(b)
+ if getid(nh)==id_whatsit and getsubtype(nh)==sid_user then
+ nh=node_next(nh); node_free(node_prev(nh))
+ end
+ set_attr(nh, attr_icflag,
+ get_attr_icflag(nh) + PROCESSED_BEGIN_FLAG)
+ setfield(node_tail(h), 'next', nh)
+ setfield(f, 'head', nil); node_free(f)
+ setfield(b, 'head', nil); node_free(b)
+ local g = luatexja.jfmglue.main(h,false)
+ return node.direct.hpack(g)
+ else
+ return f
+ end
+ elseif b then
+ return b
+ else
+ local h = node_new(id_hlist)
+ setfield(h, 'subtype', 0)
+ setfield(h, 'width', 0)
+ setfield(h, 'height', 0)
+ setfield(h, 'depth', 0)
+ setfield(h, 'glue_set', 0)
+ setfield(h, 'glue_order', 0)
+ setfield(h, 'head', nil)
+ return h
+ end
+ end
+end
+
+local function expand_3bits(num)
+ local t = {}; local a = num
+ for i = 1, 10 do
+ t[i] = a%8; a = floor(a/8)
+ end
+ return t
+end
+----------------------------------------------------------------
+-- 補助関数群 2
+----------------------------------------------------------------
+
+-- box ã®ä¸­èº«ã®ãƒŽãƒ¼ãƒ‰ã¯å†åˆ©ç”¨ã•ã‚Œã‚‹
+local enlarge
+do
+ local FROM_JFM = luatexja.icflag_table.FROM_JFM
+ local PROCESSED = luatexja.icflag_table.PROCESSED
+ local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP
+ local KANJI_SKIP_JFM = luatexja.icflag_table.KANJI_SKIP_JFM
+ local XKANJI_SKIP = luatexja.icflag_table.XKANJI_SKIP
+ local XKANJI_SKIP_JFM= luatexja.icflag_table.XKANJI_SKIP_JFM
+ enlarge = function (box, new_width, pre, middle, post, prenw, postnw)
+ -- pre, middle, post: 伸縮比率
+ -- prenw, postnw: å‰å¾Œã®è‡ªç„¶é•· (sp)
+ local h = getlist(box);
+ local hh, hd = getfield(box, 'height'), getfield(box, 'depth')
+ local hx = h
+ while hx do
+ local hic = has_attr(hx, attr_icflag) or 0
+ if (hic == KANJI_SKIP) or (hic == KANJI_SKIP_JFM)
+ or (hic == XKANJI_SKIP) or (hic == XKANJI_SKIP_JFM)
+ or ((hic<=FROM_JFM+63) and (hic>=FROM_JFM)) then
+ -- ã“ã® 5 種類ã®ç©ºç™½ã‚’ã®ã°ã™
+ if getid(hx) == id_kern then
+ local k = node_new(id_glue)
+ setglue(k, getfield(hx, 'kern'), round(middle*65536), 0,
+ 2, 0)
+ setfield(k, 'subtype', 0);
+ h = insert_after(h, hx, k);
+ h = node_remove(h, hx); node_free(hx); hx = k
+ else -- glue
+ setglue(hx, getfield(hx, 'width'), round(middle*65536), 0,
+ 2, 0)
+ end
+ end
+ hx = node_next(hx)
+ end
+ -- 先頭ã®ç©ºç™½ã‚’挿入
+ local k = node_new(id_glue);
+ setglue(k, prenw, round(pre*65536), 0, 2, 0)
+ h = insert_before(h, h, k);
+ -- 末尾ã®ç©ºç™½ã‚’挿入
+ local k = node_new(id_glue);
+ setglue(k, postnw, round(post*65536), 0, 2, 0)
+ insert_after(h, node_tail(h), k);
+ -- hpack
+ setfield(box, 'head', nil); node_free(box)
+ box = node.direct.hpack(h, new_width, 'exactly')
+ setfield(box, 'height', hh)
+ setfield(box, 'depth', hd)
+ return box
+ end
+end
+
+
+----------------------------------------------------------------
+-- TeX interface
+----------------------------------------------------------------
+
+-- rtlr: ルビ部分ã®ãƒœãƒƒã‚¯ã‚¹ãŸã¡ r1, r2, ...
+-- rtlp: 親文字 ã®ãƒœãƒƒã‚¯ã‚¹ãŸã¡ p1, p2, ...
+local function texiface_low(rst, rtlr, rtlp)
+ local w = node_new(id_whatsit, sid_user)
+ setfield(w, 'type', 110); setfield(w, 'user_id', RUBY_PRE)
+ local wv = node_new(id_whatsit, sid_user)
+ setfield(w, 'value', to_node(wv))
+ setfield(wv, 'type', 100)
+ setfield(wv, 'value', floor(#rtlr))
+ setfield(wv, 'user_id', RUBY_PRE) -- dummy
+ set_attr(wv, attr_ruby, rst.rubyzw)
+ set_attr(wv, attr_ruby_maxmargin, rst.maxmargin)
+ set_attr(wv, attr_ruby_maxprep, rst.pre)
+ set_attr(wv, attr_ruby_maxpostp, rst.post)
+ set_attr(wv, attr_ruby_intergap, rst.intergap)
+ set_attr(wv, attr_ruby_stretch, rst.stretch)
+ set_attr(wv, attr_ruby_mode, rst.mode)
+ local n = wv
+ for i = 1, #rtlr do
+ _, n = insert_after(wv, n, rtlr[i])
+ _, n = insert_after(wv, n, rtlp[i])
+ end
+ -- w.value: (whatsit) .. r1 .. p1 .. r2 .. p2
+ node.direct.write(w); return w,wv
+end
+
+-- rst: table
+function luatexja.ruby.texiface(rst, rtlr, rtlp)
+ if #rtlr ~= #rtlp then
+ for i=1, #rtlr do node_free(rtlr[i]) end
+ for i=1, #rtlp do node_free(rtlp[i]) end
+ ltjb.package_error('luatexja-ruby',
+ 'Group count mismatch between the ruby and\n' ..
+ 'the body (' .. #rtlr .. ' != ' .. #rtlp .. ').',
+ '')
+ else
+ local f = true
+ for i = 1,#rtlr do
+ if getfield(rtlr[i], 'width') > getfield(rtlp[i], 'width') then
+ f = false; break
+ end
+ end
+ if f then -- モノルビ * n
+ local r,p = {true}, {true}
+ for i = 1,#rtlr do
+ r[1] = rtlr[i]; p[1] = rtlp[i]; texiface_low(rst, r, p)
+ end
+ else
+ local w, wv = texiface_low(rst, rtlr, rtlp)
+ local id = make_uniq_id(w)
+ set_attr(wv, attr_ruby_id, id)
+ end
+ end
+end
+
+----------------------------------------------------------------
+-- pre_line_break
+----------------------------------------------------------------
+
+-- r, p ã®ä¸­èº«ã®ãƒŽãƒ¼ãƒ‰ã¯å†åˆ©ç”¨ã•ã‚Œã‚‹
+local function enlarge_parent(r, p, ppre, pmid, ppost, mapre, mapost, intmode)
+ -- r: ルビ部分ã®æ ¼ç´ã•ã‚ŒãŸ box,p: åŒï¼Œè¦ªæ–‡å­—
+ local rwidth = getfield(r, 'width')
+ local sumprot = rwidth - getfield(p, 'width') -- >0
+ local pre_intrusion, post_intrusion
+ if intmode == 0 then -- ã¨ã‚Šã‚ãˆãšçµ„ã‚“ã§ã‹ã‚‰æ±ºã‚ã‚‹
+ p = enlarge(p, rwidth, ppre, pmid, ppost, 0, 0)
+ pre_intrusion = min(mapre, round(ppre*getfield(p, 'glue_set')*65536))
+ post_intrusion = min(mapost, round(ppost*getfield(p, 'glue_set')*65536))
+ elseif intmode == 1 then
+ pre_intrusion = min(mapre, sumprot);
+ post_intrusion = min(mapost, max(sumprot-pre_intrusion, 0))
+ p = enlarge(p, rwidth, ppre, pmid, ppost, pre_intrusion, post_intrusion)
+ elseif intmode == 2 then
+ post_intrusion = min(mapost, sumprot);
+ pre_intrusion = min(mapre, max(sumprot-post_intrusion, 0))
+ p = enlarge(p, rwidth, ppre, pmid, ppost, pre_intrusion, post_intrusion)
+ else -- intmode == 3
+ local n = min(mapre, mapost)*2
+ if n < sumprot then
+ pre_intrusion = n/2; post_intrusion = n/2
+ else
+ pre_intrusion = floor(sumprot/2); post_intrusion = sumprot - pre_intrusion
+ end
+ p = enlarge(p, rwidth, ppre, pmid, ppost, pre_intrusion, post_intrusion)
+ pre_intrusion = min(mapre, pre_intrusion + round(ppre*getfield(p, 'glue_set')*65536))
+ post_intrusion = min(mapost, post_intrusion + round(ppost*getfield(p, 'glue_set')*65536))
+ end
+ setfield(r, 'shift', -pre_intrusion)
+ local rwidth = rwidth - pre_intrusion - post_intrusion
+ setfield(r, 'width', rwidth)
+ setfield(p, 'width', rwidth)
+ local ps = getlist(p)
+ setfield(ps, 'width', getfield(ps, 'width') - pre_intrusion)
+ return r, p, post_intrusion
+end
+
+-- ルビボックスã®ç”Ÿæˆï¼ˆå˜ä¸€ã‚°ãƒ«ãƒ¼ãƒ—)
+-- returned value: <new box>, <ruby width>, <post_intrusion>
+local max_margin
+local function new_ruby_box(r, p, ppre, pmid, ppost,
+ mapre, mapost, imode, rgap)
+ local post_intrusion = 0
+ local intmode = imode%4
+ local rpre, rmid, rpost, rsmash
+ imode = floor(imode/262144); rsmash = (imode%2 ==1)
+ imode = floor(imode/2); rpost = imode%8;
+ imode = (imode-rpost)/8; rmid = imode%8;
+ imode = (imode-rmid)/8; rpre = imode%8
+ if getfield(r, 'width') > getfield(p, 'width') then -- change the width of p
+ r, p, post_intrusion = enlarge_parent(r, p, ppre, pmid, ppost, mapre, mapost, intmode)
+ elseif getfield(r, 'width') < getfield(p, 'width') then -- change the width of r
+ r = enlarge(r, getfield(p, 'width'), rpre, rmid, rpost, 0, 0)
+ post_intrusion = 0
+ local need_repack = false
+ -- margin ãŒå¤§ãããªã‚Šã™ãŽãŸæ™‚ã®å‡¦ç†
+ if round(rpre*getfield(r, 'glue_set')*65536) > max_margin then
+ local ps = getlist(r); need_repack = true
+ setfield(ps, 'width', max_margin)
+ setfield(ps, 'stretch', 1) -- å…¨ã伸縮ã—ãªã„ã®ã‚‚å›°ã‚‹
+ end
+ if round(rpost*getfield(r, 'glue_set')*65536) > max_margin then
+ local ps = node_tail(getlist(r)); need_repack = true
+ setfield(ps, 'width', max_margin)
+ setfield(ps, 'stretch', 1) -- å…¨ã伸縮ã—ãªã„ã®ã‚‚å›°ã‚‹
+ end
+ if need_repack then
+ local rt = r
+ r = node.direct.hpack(getlist(r), getfield(r, 'width'), 'exactly')
+ setfield(rt, 'head', nil); node_free(rt);
+ end
+ end
+ local a, k = node_new(id_rule), node_new(id_kern, 1)
+ setfield(a, 'width', 0); setfield(a, 'height', 0)
+ setfield(a, 'depth', 0); setfield(k, 'kern', rgap)
+ insert_after(r, r, a); insert_after(r, a, k);
+ insert_after(r, k, p); setfield(p, 'next', nil)
+ a = node.direct.vpack(r); setfield(a, 'shift', 0)
+ set_attr(a, attr_ruby, post_intrusion)
+ if rsmash or getfield(a, 'height')<getfield(p, 'height') then
+ local k = node_new(id_kern, 1)
+ setfield(k, 'kern', -getfield(a, 'height')+getfield(p, 'height'))
+ setfield(a, 'head', k); insert_before(r, r, k)
+ setfield(a, 'height', getfield(p, 'height'))
+ end
+
+ return a, getfield(r, 'width'), post_intrusion
+end
+
+
+-- High-level routine in pre_linebreak_filter
+local post_intrusion_backup
+local max_allow_pre, max_allow_post
+
+
+-- 中付ã熟語ルビ,cmp containers
+-- 「文字ã®æ§‹æˆã‚’考ãˆãŸã€ã‚„ã¤ã¯ã©ã†ã—よã†
+local function pre_low_cal_box(w, cmp)
+ local rb = {}
+ local pb = {}
+ local kf = {}
+ -- kf[i] : container 1--i ã‹ã‚‰ãªã‚‹è¡Œæœ«å½¢
+ -- kf[cmp+i] : container i--cmp ã‹ã‚‰ãªã‚‹è¡Œé ­å½¢
+ -- kf[2cmp+1] : 行中形
+ local wv = getfield(w, 'value')
+ local mdt -- nt*: node temp
+ local coef = {} -- 連立一次方程å¼ã®æ‹¡å¤§ä¿‚数行列
+ local rtb = expand_3bits(has_attr(wv, attr_ruby_stretch))
+ local rgap = has_attr(wv, attr_ruby_intergap)
+ local intmode = floor(has_attr(wv, attr_ruby_mode)/4)
+
+ -- node list 展開・行末形ã®è¨ˆç®—
+ local nt, nta, ntb = wv, nil, nil -- nt*: node temp
+ for i = 1, cmp do
+ nt = node_next(nt); rb[i] = nt; nta = concat(nta, node_copy(nt))
+ nt = node_next(nt); pb[i] = nt; ntb = concat(ntb, node_copy(nt))
+ coef[i] = {}
+ for j = 1, 2*i do coef[i][j] = 1 end
+ for j = 2*i+1, 2*cmp+1 do coef[i][j] = 0 end
+ kf[i], coef[i][2*cmp+2]
+ = new_ruby_box(node_copy(nta), node_copy(ntb),
+ rtb[6], rtb[5], rtb[4], max_allow_pre, 0, intmode, rgap)
+ end
+ node_free(nta); node_free(ntb)
+
+ -- 行頭形ã®è¨ˆç®—
+ local nta, ntb = nil, nil
+ for i = cmp,1,-1 do
+ coef[cmp+i] = {}
+ for j = 1, 2*i-1 do coef[cmp+i][j] = 0 end
+ for j = 2*i, 2*cmp+1 do coef[cmp+i][j] = 1 end
+ nta = concat(node_copy(rb[i]), nta); ntb = concat(node_copy(pb[i]), ntb)
+ kf[cmp+i], coef[cmp+i][2*cmp+2]
+ = new_ruby_box(node_copy(nta), node_copy(ntb),
+ rtb[9], rtb[8], rtb[7], 0, max_allow_post, intmode, rgap)
+ end
+
+ -- ã“ã“ã§ï¼Œnta, ntb ã«ã¯å…¨ container を連çµã—㟠box ãŒå…¥ã£ã¦ã„ã‚‹ã®ã§
+ -- ãれを使ã£ã¦è¡Œä¸­å½¢ã‚’計算ã™ã‚‹ï¼Ž
+ coef[2*cmp+1] = {}
+ for j = 1, 2*cmp+1 do coef[2*cmp+1][j] = 1 end
+ kf[2*cmp+1], coef[2*cmp+1][2*cmp+2], post_intrusion_backup
+ = new_ruby_box(nta, ntb, rtb[3], rtb[2], rtb[1],
+ max_allow_pre, max_allow_post, intmode, rgap)
+
+ -- w.value 㮠node list 更新.
+ local nt = wv
+ node.direct.flush_list(node_next(wv))
+ for i = 1, 2*cmp+1 do setfield(nt, 'next', kf[i]); nt = kf[i] end
+
+ if cmp==1 then solve_1(coef)
+ elseif cmp==2 then solve_2(coef)
+ else
+ gauss(coef) -- 掃ãã ã—法ã§é€£ç«‹æ–¹ç¨‹å¼å½¢ coef を解ã
+ end
+ return coef
+end
+
+local first_whatsit
+do
+ local traverse_id = node.direct.traverse_id
+ function first_whatsit(n) -- n 以後ã§æœ€åˆã® whatsit
+ for h in traverse_id(id_whatsit, n) do
+ return h
+ end
+ return nil
+ end
+end
+
+local next_cluster_array = {}
+-- ノード追加
+local function pre_low_app_node(head, w, cmp, coef, ht, dp)
+ -- メイン㮠node list 更新
+ local nt = node_new(id_glue)
+ setglue(nt, coef[1][2*cmp+2], 0, 0, 0, 0)
+ set_attr(nt, attr_ruby, 1); set_attr(w, attr_ruby, 2)
+ head = insert_before(head, w, nt)
+ nt = w
+ for i = 1, cmp do
+ -- rule
+ local nta = node_new(id_rule);
+ setfield(nta, 'width', coef[i*2][2*cmp+2])
+ setfield(nta, 'height', ht); setfield(nta, 'depth', dp)
+ setfield(nta, 'subtype', 0)
+ insert_after(head, nt, nta)
+ set_attr(nta, attr_ruby, 2*i+1)
+ -- glue
+ if i~=cmp or not next_cluster_array[w] then
+ nt = node_new(id_glue); insert_after(head, nta, nt)
+ else
+ nt = next_cluster_array[w]
+ end
+ setglue(nt, coef[i*2+1][2*cmp+2], 0, 0, 0, 0)
+ set_attr(nt, attr_ruby, 2*i+2)
+ end
+ tex.setattribute('global', attr_ruby, -0x7FFFFFFF)
+ setfield(w, 'user_id', RUBY_POST)
+ next_cluster_array[w]=nil
+ return head, first_whatsit(node_next(nt))
+end
+
+local function pre_high(ahead)
+ if not ahead then return ahead end
+ local head = to_direct(ahead)
+ post_intrusion_backup = 0
+ local n = first_whatsit(head)
+ while n do
+ if getsubtype(n) == sid_user and getfield(n, 'user_id') == RUBY_PRE then
+ local nv = getfield(n, 'value')
+ max_allow_pre = has_attr(nv, attr_ruby_maxprep) or 0
+ local atr = has_attr(n, attr_ruby) or 0
+ if max_allow_pre < 0 then
+ if atr>0 then
+ -- ç›´å‰ã®ãƒ«ãƒ“㧠intrusion ãŒãŠã“ã‚‹å¯èƒ½æ€§ã‚り.
+ -- å‰ run ã®ãƒ‡ãƒ¼ã‚¿ãŒæ®‹ã£ã¦ã„ã‚Œã°ãれを使用,
+ -- ãã†ã§ãªã‘ã‚Œã°è¡Œä¸­å½¢ã®ãƒ‡ãƒ¼ã‚¿ã‚’利用ã™ã‚‹
+ local op = old_break_info[atr] or post_intrusion_backup
+ max_allow_pre = max(0, -max_allow_pre - op)
+ else
+ max_allow_pre = -max_allow_pre
+ end
+ end
+ post_intrusion_backup = 0
+ max_allow_post = has_attr(nv, attr_ruby_maxpostp) or 0
+ max_margin = has_attr(nv, attr_ruby_maxmargin) or 0
+ local coef = pre_low_cal_box(n, getfield(nv, 'value'))
+ local s = node_tail(nv) --ルビ文字
+ head, n = pre_low_app_node(
+ head, n, getfield(nv, 'value'), coef,
+ getfield(s, 'height'), getfield(s, 'depth')
+ )
+ else
+ n = first_whatsit(node_next(n))
+ end
+ end
+ return to_node(head)
+end
+luatexbase.add_to_callback('pre_linebreak_filter', pre_high, 'ltj.ruby.pre', 100)
+luatexbase.add_to_callback('hpack_filter', pre_high, 'ltj.ruby.pre', 100)
+
+----------------------------------------------------------------
+-- post_line_break
+----------------------------------------------------------------
+local post_lown
+do
+ local function write_aux(wv, num)
+ local id = has_attr(wv, attr_ruby_id)
+ if id>0 and cache_handle then
+ cache_handle:write(
+ 'luatexja.ruby.old_break_info['
+ .. tostring(id) .. ']=' .. num
+ .. '\n')
+ end
+ end
+
+ post_lown = function (rs, rw, cmp, ch)
+ -- ch: the head of `current' hlist
+ if #rs ==0 or not rw then return ch end
+ local hn = has_attr(rs[1], attr_ruby)
+ local fn = has_attr(rs[#rs], attr_ruby)
+ local wv = getfield(rw, 'value')
+ if hn==1 then
+ if fn==2*cmp+2 then
+ local hn = node_tail(wv)
+ node_remove(wv, hn)
+ insert_after(ch, rs[1], hn)
+ set_attr(hn, attr_icflag, PROCESSED)
+ write_aux(wv, has_attr(hn, attr_ruby))-- 行中形
+ else
+ local deg, hn = (fn-1)/2, wv
+ for i = 1, deg do hn = node_next(hn) end;
+ node_remove(wv, hn)
+ setfield(hn, 'next', nil)
+ insert_after(ch, rs[1], hn)
+ set_attr(hn, attr_icflag, PROCESSED)
+ write_aux(wv, has_attr(hn, attr_ruby))
+ end
+ else
+ local deg, hn = max((hn-1)/2,2), wv
+ for i = 1, cmp+deg-1 do hn = node_next(hn) end
+ -- -1 is needed except the case hn = 3,
+ -- because a ending-line form is removed already from the list
+ node_remove(wv, hn); setfield(hn, 'next', nil)
+ insert_after(ch, rs[1], hn)
+ set_attr(hn, attr_icflag, PROCESSED)
+ if fn == 2*cmp-1 then
+ write_aux(wv, has_attr(hn, attr_ruby))
+ end
+ end
+ for i = 1,#rs do
+ local ri = rs[i]
+ ch = node_remove(ch, ri); node_free(ri);
+ end
+ -- cleanup
+ if fn >= 2*cmp+1 then node_free(rw) end
+ return ch;
+ end
+end
+
+local function post_high_break(head)
+ local rs = {} -- rs: sequence of ruby_nodes,
+ local rw = nil -- rw: main whatsit
+ local cmp = -2 -- dummy
+ for h in node.direct.traverse_id(id_hlist, to_direct(head)) do
+ for i = 1, #rs do rs[i] = nil end
+ local ha = getlist(h)
+ while ha do
+ local hai = getid(ha)
+ local i = ((hai == id_glue and getsubtype(ha)==0)
+ or (hai == id_rule and getsubtype(ha)==0)
+ or (hai == id_whatsit and getsubtype(ha)==sid_user
+ and getfield(ha, 'user_id', RUBY_POST)))
+ and has_attr(ha, attr_ruby) or 0
+ if i==0 then
+ ha = node_next(ha)
+ elseif i==1 then
+ setfield(h, 'head', post_lown(rs, rw, cmp, getlist(h)))
+ for i = 2, #rs do rs[i] = nil end -- rs[1] is set by the next statement
+ rs[1], rw = ha, nil; ha = node_next(ha)
+ elseif i==2 then
+ rw = ha
+ cmp = getfield(getfield(rw, 'value'), 'value')
+ local hb, hc = node_remove(getlist(h), rw)
+ setfield(h, 'head', hb); ha = hc
+ else -- i>=3
+ rs[#rs+1] = ha; ha = node_next(ha)
+ end
+ end
+ setfield(h, 'head', post_lown(rs, rw, cmp, getlist(h)))
+ end
+ return head
+end
+
+local function post_high_hbox(ahead)
+ local ha = to_direct(ahead); local head = ha
+ local rs = {}; -- rs: sequence of ruby_nodes,
+ local rw = nil; -- rw: main whatsit
+ local cmp
+ while ha do
+ local hai = getid(ha)
+ local i = ((hai == id_glue and getsubtype(ha)==0)
+ or (hai == id_rule and getsubtype(ha)==0)
+ or (hai == id_whatsit and getsubtype(ha)==sid_user
+ and getfield(ha, 'user_id', RUBY_POST)))
+ and has_attr(ha, attr_ruby) or 0
+ if i==0 then
+ ha = node_next(ha)
+ elseif i==1 then
+ head = post_lown(rs, rw, cmp, head)
+ for i = 2, #rs do rs[i] = nil end -- rs[1] is set by the next statement
+ rs[1], rw = ha, nil; ha = node_next(ha)
+ elseif i==2 then
+ rw = ha
+ cmp = getfield(getfield(rw, 'value'), 'value')
+ head, ha = node_remove(head, rw)
+ else -- i >= 3
+ rs[#rs+1] = ha; ha = node_next(ha)
+ end
+ end
+ return to_node(post_lown(rs, rw, cmp, head))
+end
+
+luatexbase.add_to_callback('post_linebreak_filter', post_high_break, 'ltj.ruby.post_break', 100)
+luatexbase.add_to_callback('hpack_filter', post_high_hbox, 'ltj.ruby.post_hbox', 101)
+
+
+----------------------------------------------------------------
+-- for jfmglue callbacks
+----------------------------------------------------------------
+do
+ local RIPRE = luatexja.stack_table_index.RIPRE
+ local function whatsit_callback(Np, lp, Nq)
+ if Np.nuc then return Np
+ elseif getfield(lp, 'user_id') == RUBY_PRE then
+ Np.first, Np.nuc, Np.last = lp, lp, lp
+ local lpv = getfield(lp, 'value')
+ local x = node_next(node_next(lpv))
+ Np.last_char = luatexja.jfmglue.check_box_high(Np, getlist(x), nil)
+ if Nq.id ~=id_pbox_w then
+ if type(Nq.char)=='number' then
+ -- Nq is a JAchar
+ if has_attr(lpv, attr_ruby_maxprep) < 0 then -- auto
+ local p = round((ltjs.table_current_stack[RIPRE + Nq.char] or 0)
+ *has_attr(lpv, attr_ruby))
+ if has_attr(lpv, attr_ruby_mode)%2 == 0 then -- intrusion 無効
+ p = 0
+ end
+ set_attr(lpv, attr_ruby_maxprep, -p)
+ end
+ if Nq.prev_ruby then
+ set_attr(lp, attr_ruby, Nq.prev_ruby)
+ end
+ elseif has_attr(lpv, attr_ruby_maxprep) < 0 then -- auto
+ if Nq.char == 'parbdd' then
+ local p = round((ltjs.table_current_stack[RIPRE-1] or 0)
+ *has_attr(lpv, attr_ruby))
+ p = min(p, Nq.width)
+ if has_attr(lpv, attr_ruby_mode)%2 == 0 then -- intrusion 無効
+ p = 0
+ end
+ set_attr(lpv, attr_ruby_maxprep, p)
+ else
+ set_attr(lpv, attr_ruby_maxprep, 0)
+ end
+ end
+ elseif has_attr(lpv, attr_ruby_maxprep) < 0 then -- auto
+ set_attr(lpv, attr_ruby_maxprep, 0)
+ end
+ return Np
+ else
+ return Np
+ end
+ end
+ luatexbase.add_to_callback("luatexja.jfmglue.whatsit_getinfo", whatsit_callback,
+ "luatexja.ruby.np_info", 1)
+end
+
+do
+ local RIPOST = luatexja.stack_table_index.RIPOST
+ local function whatsit_after_callback(s, Nq, Np)
+ if not s and getfield(Nq.nuc, 'user_id') == RUBY_PRE then
+ if Np then
+ local last_glue = node_new(id_glue)
+ set_attr(last_glue, attr_icflag, 0)
+ insert_before(Nq.nuc, Np.first, last_glue)
+ Np.first = last_glue
+ next_cluster_array[Nq.nuc] = last_glue -- ルビ処ç†ç”¨ã®ã‚°ãƒ«ãƒ¼
+ end
+ local nqnv = getfield(Nq.nuc, 'value')
+ local x = node_next(node_next(nqnv))
+ for i = 2, getfield(nqnv, 'value') do x = node_next(node_next(x)) end
+ Nq.last_char = luatexja.jfmglue.check_box_high(Nq, getlist(x), nil)
+ luatexja.jfmglue.after_hlist(Nq)
+ if Np and Np.id ~=id_pbox_w and type(Np.char)=='number' then
+ -- Np is a JAchar
+ local rm = has_attr(nqnv, attr_ruby_mode)
+ if has_attr(nqnv, attr_ruby_maxpostp) < 0 then -- auto
+ local p = round((ltjs.table_current_stack[RIPOST + Np.char] or 0)
+ *has_attr(nqnv, attr_ruby))
+ if rm%2 == 0 then -- intrusion 無効
+ p = 0
+ end
+ if rm%4 >= 2 then
+ local q = has_attr(nqnv, attr_ruby_maxprep)
+ if q < p then p = q
+ elseif q > p then
+ set_attr(nqnv, attr_ruby_maxprep, p)
+ end
+ end
+ set_attr(nqnv, attr_ruby_maxpostp, p)
+ end
+ Np.prev_ruby = has_attr(getfield(Nq.nuc, 'value'), attr_ruby_id)
+ -- å‰ã®ã‚¯ãƒ©ã‚¹ã‚¿ãŒãƒ«ãƒ“ã§ã‚ã£ãŸã“ã¨ã®ãƒ•ãƒ©ã‚°
+ else -- ç›´å‰ãŒæ–‡å­—以外
+ local nqnv = getfield(Nq.nuc, 'value')
+ if has_attr(nqnv, attr_ruby_maxpostp) < 0 then -- auto
+ set_attr(nqnv, attr_ruby_maxpostp, 0)
+ if has_attr(nqnv, attr_ruby_mode)%4 >= 2 then
+ set_attr(nqnv, attr_ruby_maxprep, 0)
+ end
+ end
+ end
+ return true
+ else
+ return s
+ end
+ end
+ luatexbase.add_to_callback("luatexja.jfmglue.whatsit_after", whatsit_after_callback,
+ "luatexja.ruby.np_info_after", 1)
+end
+
diff --git a/macros/luatex/generic/luatexja/src/ltj-setwidth.lua b/macros/luatex/generic/luatexja/src/ltj-setwidth.lua
new file mode 100644
index 0000000000..9f13c97c61
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-setwidth.lua
@@ -0,0 +1,311 @@
+--
+-- src/ltj-setwidth.lua
+--
+
+luatexja.load_module('base'); local ltjb = luatexja.base
+luatexja.load_module('stack'); local ltjs = luatexja.stack
+luatexja.load_module('jfont'); local ltjf = luatexja.jfont
+luatexja.load_module('direction'); local ltjd = luatexja.direction
+
+local setfield = node.direct.setfield
+local getfield = node.direct.getfield
+local getid = node.direct.getid
+local getfont = node.direct.getfont
+local getlist = node.direct.getlist
+local getchar = node.direct.getchar
+local getsubtype = node.direct.getsubtype
+local getwidth = node.direct.getwidth or function(n) return getfield(n,'width') end
+local getdepth = node.direct.getdepth or function(n) return getfield(n,'depth') end
+local getwhd = node.direct.getwhd or function(n)
+ return getfield(n,'width'), getfield(n,'height'),getfield(n,'depth') end
+
+local setwhd = node.direct.setwhd or function(n,w,h,d)
+ setfield(n,'width',w); setfield(n,'height',h); setfield(n,'depth',d) end
+local setchar = node.direct.setchar or function(n,c) setfield(n,'char',c) end
+local setnext = node.direct.setnext or function(n,c) setfield(n,'next',c) end
+local setdir = node.direct.setdir or function(n,c) setfield(n,'dir',c) end
+local setkern = node.direct.setkern or function(n,c) setfield(n,'kern',c) end
+local setoffsets = node.direct.setoffsets or function(n,x,y)
+ setfield(n,'xoffset',x); setfield(n,'yoffset',y) end
+local getoffsets = node.direct.getoffsets or function(n)
+ return getfield(n,'xoffset'), getfield(n,'yoffset') end
+
+local node_traverse_id = node.direct.traverse_id
+local node_traverse = node.direct.traverse
+local node_new = node.direct.new
+local node_copy = node.direct.copy
+local node_remove = node.direct.remove
+local node_tail = node.direct.tail
+local node_next = node.direct.getnext
+local has_attr = node.direct.has_attribute
+local set_attr = node.direct.set_attribute
+local node_insert_before = node.direct.insert_before
+local node_insert_after = node.direct.insert_after
+local round = tex.round
+
+local id_glyph = node.id('glyph')
+local id_kern = node.id('kern')
+local id_hlist = node.id('hlist')
+local id_vlist = node.id('vlist')
+local id_rule = node.id('rule')
+local id_math = node.id('math')
+local id_whatsit = node.id('whatsit')
+local sid_save = node.subtype('pdf_save')
+local sid_restore = node.subtype('pdf_restore')
+local sid_matrix = node.subtype('pdf_setmatrix')
+local dir_tate = luatexja.dir_table.dir_tate
+
+local attr_ykblshift = luatexbase.attributes['ltj@ykblshift']
+local attr_tkblshift = luatexbase.attributes['ltj@tkblshift']
+local attr_icflag = luatexbase.attributes['ltj@icflag']
+local attr_vert_ori = luatexbase.attributes['ltj@vert@ori']
+
+local ltjf_font_extra_info = ltjf.font_extra_info
+
+local PACKED = luatexja.icflag_table.PACKED
+local PROCESSED = luatexja.icflag_table.PROCESSED
+
+local get_pr_begin_flag
+do
+ local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
+ local floor = math.floor
+ get_pr_begin_flag = function (p)
+ local i = has_attr(p, attr_icflag) or 0
+ return i - i%PROCESSED_BEGIN_FLAG
+ end
+end
+
+local ltjw = {} --export
+luatexja.setwidth = ltjw
+
+luatexbase.create_callback("luatexja.set_width", "data",
+ function (fstable, fmtable, char_data)
+ return fstable
+ end)
+local call_callback = luatexbase.call_callback
+
+local fshift = { down = 0, left = 0 }
+
+local min, max = math.min, math.max
+
+local rule_subtype = (status.luatex_version>=85) and 3 or 0
+
+-- 和文文字ã®ä½ç½®è£œæ­£ï¼ˆæ¨ªï¼‰
+local function capsule_glyph_yoko(p, met, char_data, head, dir)
+ if not char_data then return node_next(p), head, p end
+ fshift.down = char_data.down; fshift.left = char_data.left
+ fshift = call_callback("luatexja.set_width", fshift, met, char_data)
+ local kbl = has_attr(p, attr_ykblshift) or 0
+ --
+ -- f*: whd specified in JFM
+ local pwidth, pheight,pdepth = getwhd(p)
+ local fwidth = char_data.width or pwidth
+ local fheight= char_data.height or pheight
+ local fdepth = char_data.depth or pdepth
+ if pwidth==fwidth then
+ -- 補正後glyph node 㯠ht: p.height - kbl - down, dp: p.depth + min(0, kbl+down) ã‚’æŒã¤
+ -- 設定ã•ã‚Œã‚‹ã¹ã寸法: ht: fheight - kbl, dp: fdepth + kbl
+ local ht_diff = fheight + fshift.down - pheight
+ local dp_diff = fdepth + kbl - pdepth - min(kbl + fshift.down, 0)
+ if ht_diff == 0 and dp_diff ==0 then -- offset only
+ set_attr(p, attr_icflag, PROCESSED)
+ local xo, yo = getoffsets(p)
+ setoffsets(p, xo - fshift.left, yo - kbl - fshift.down)
+ return node_next(p), head, p
+ elseif ht_diff >= 0 and dp_diff >=0 then -- rule
+ local box = node_new(id_rule,rule_subtype)
+ local xo, yo = getoffsets(p)
+ setoffsets(p, xo, yo - kbl - fshift.down)
+ setwhd(box, 0, fheight - kbl, fdepth + kbl)
+ setdir(box, dir)
+ set_attr(box, attr_icflag, PACKED)
+ set_attr(p, attr_icflag, PROCESSED)
+ head = p and node_insert_before(head, p, box)
+ or node_insert_after(head, node_tail(head), box)
+ return node_next(p), head, p, box
+ end
+ end
+
+ local q
+ head, q = node_remove(head, p)
+ local xo, yo = getoffsets(p)
+ setoffsets(p, xo + char_data.align*(fwidth-pwidth) - fshift.left,
+ yo - fshift.down);
+ setnext(p, nil)
+ local box = node_new(id_hlist)
+ setwhd(box, fwidth, fheight, fdepth)
+ setfield(box, 'head', p)
+ setfield(box, 'shift', kbl)
+ setdir(box, dir)
+ set_attr(box, attr_icflag, PACKED)
+ head = q and node_insert_before(head, q, box)
+ or node_insert_after(head, node_tail(head), box)
+ return q, head, box
+end
+
+luatexja.setwidth.capsule_glyph_yoko = capsule_glyph_yoko
+
+-- 和文文字ã®ä½ç½®è£œæ­£ï¼ˆç¸¦ï¼‰
+-- UTR#50 㧠R ã‚‚ã—ã㯠Tr ã¨æŒ‡å®šã•ã‚Œã¦ã„ã‚‹ãŒï¼Œç¸¦çµ„用グリフãŒãªã„ã‚‚ã®
+local function capsule_glyph_tate_rot(p, met, char_data, head, dir, asc)
+ fshift.down = char_data.down; fshift.left = char_data.left
+ fshift = call_callback("luatexja.set_width", fshift, met, char_data)
+ local kbl = has_attr(p, attr_tkblshift) or 0
+ -- f*: whd specified in JFM
+ local pwidth, pheight,pdepth = getwhd(p)
+ local fwidth = char_data.width or pwidth
+ local fheight= char_data.height or pheight
+ local fdepth = char_data.depth or pdepth
+ local q
+ head, q = node_remove(head, p)
+ local xo, yo = getoffsets(p)
+ setoffsets(p, xo + char_data.align*(fwidth-pwidth) - fshift.left,
+ yo - fshift.down - asc);
+ setnext(p, nil)
+ local box = node_new(id_hlist)
+ setwhd(box, fwidth, fheight, fdepth)
+ setfield(box, 'head', p)
+ setfield(box, 'shift', kbl)
+ setdir(box, dir)
+ set_attr(box, attr_icflag, PACKED)
+ head = q and node_insert_before(head, q, box)
+ or node_insert_after(head, node_tail(head), box)
+ return q, head, box
+end
+
+local function capsule_glyph_tate(p, met, char_data, head, dir)
+ if not char_data then return node_next(p), head end
+ local ascent, descent = met.ascent, met.descent
+ local fwidth, pwidth = char_data.width
+ do
+ local pf, pc = getfont(p), getchar(p)
+ local feir = ltjf_font_extra_info[pf]
+ if feir and feir.rotation and met.vert_activated then
+ if feir.rotation[pc] and (has_attr(p, attr_vert_ori) or 0)<=0 then
+ return capsule_glyph_tate_rot(p, met, char_data, head, dir, 0.5*(ascent-descent))
+ end
+ end
+ local ident = fonts.hashes.identifiers[pf]
+ pwidth = (ident.descriptions and ident.descriptions[pc]
+ and ident.descriptions[pc].vheight
+ and ident.descriptions[pc].vheight / ident.units * met.size)
+ or (ident.metadata and ident.metadata.defaultvheight) or (ascent+descent)
+ ascent = feir.vorigin[pc] and (feir.vorigin[pc] / ident.units * met.size) or ascent
+ end
+ fwidth = fwidth or pwidth
+ fshift.down = char_data.down; fshift.left = char_data.left
+ fshift = call_callback("luatexja.set_width", fshift, met, char_data)
+ local fheight = char_data.height or 0
+ local fdepth = char_data.depth or 0
+ local xo, yo = getoffsets(p)
+ local y_shift = xo + (has_attr(p,attr_tkblshift) or 0)
+ local q
+ head, q = node_remove(head, p)
+ local box = node_new(id_hlist)
+ setwhd(box, fwidth, fheight, fdepth)
+ setfield(box, 'shift', y_shift)
+ setdir(box, dir)
+
+ setoffsets(p, -fshift.down,
+ yo -(ascent + char_data.align*(fwidth-pwidth) - fshift.left) )
+ local ws = node_new(id_whatsit, sid_save)
+ local wm = node_new(id_whatsit, sid_matrix)
+ setfield(wm, 'data', '0 1 -1 0')
+ local pwnh = -round(0.5*getwidth(p))
+ local k2 = node_new(id_kern, 1); setkern(k2, pwnh)
+ local k3 = node_new(id_kern, 1); setkern(k3, -getwidth(p)-pwnh)
+ local wr = node_new(id_whatsit, sid_restore)
+ setfield(box, 'head', ws)
+ setnext(ws, wm); setnext(wm, k2);
+ setnext(k2, p); setnext(p, k3);
+ setnext(k3, wr);
+
+ set_attr(box, attr_icflag, PACKED)
+ head = q and node_insert_before(head, q, box)
+ or node_insert_after(head, node_tail(head), box)
+ return q, head, box
+end
+luatexja.setwidth.capsule_glyph_tate = capsule_glyph_tate
+
+local function capsule_glyph_math(p, met, char_data)
+ if not char_data then return nil end
+ local fwidth, pwidth = char_data.width, getwidth(p)
+ fwidth = fwidth or pwidth
+ fshift.down = char_data.down; fshift.left = char_data.left
+ fshift = call_callback("luatexja.set_width", fshift, met, char_data)
+ local fheight, fdepth = char_data.height, char_data.depth
+ local y_shift
+ = - getfield(p, 'yoffset') + (has_attr(p,attr_ykblshift) or 0)
+ setfield(p, 'yoffset', -fshift.down)
+ setfield(p, 'xoffset', getfield(p, 'xoffset') + char_data.align*(fwidth-pwidth) - fshift.left)
+ local box = node_new(id_hlist);
+ setwhd(box, fwidth, fheight, fdepth)
+ setfield(box, 'head', p)
+ setfield(box, 'shift', y_shift)
+ setdir(box, tex.mathdir)
+ set_attr(box, attr_icflag, PACKED)
+ return box
+end
+luatexja.setwidth.capsule_glyph_math = capsule_glyph_math
+
+-- æ•°å¼ã®ä½ç½®è£œæ­£
+function luatexja.setwidth.apply_ashift_math(head, last, attr_ablshift)
+ for p in node_traverse(head) do
+ local pid = getid(p)
+ if p==last then
+ return
+ elseif (has_attr(p, attr_icflag) or 0) ~= PROCESSED then
+ if pid==id_hlist or pid==id_vlist then
+ setfield(p, 'shift', getfield(p, 'shift') + (has_attr(p,attr_ablshift) or 0))
+ elseif pid==id_rule then
+ local v = has_attr(p,attr_ablshift) or 0
+ setfield(p, 'height', getfield(p, 'height')-v)
+ setfield(p, 'depth', getdepth(p)+v)
+ set_attr(p, attr_icflag, PROCESSED)
+ elseif pid==id_glyph then
+ -- 欧文文字; 和文文字㯠pid == id_hlist ã®å ´åˆã§å‡¦ç†ã•ã‚Œã‚‹
+ -- (see conv_jchar_to_hbox_A in ltj-math.lua)
+ setfield(p, 'yoffset',
+ getfield(p, 'yoffset') - (has_attr(p,attr_ablshift) or 0))
+ end
+ set_attr(p, attr_icflag, PROCESSED)
+ end
+ end
+end
+
+-- discretionary ã®ä½ç½®è£œæ­£
+do
+ local attr_yablshift = luatexbase.attributes['ltj@yablshift']
+ local attr_tablshift = luatexbase.attributes['ltj@tablshift']
+ local attr_ablshift
+ local disc, tex_dir
+ local function ashift_disc_inner(field)
+ local head = getfield(disc, field)
+ if not head then return end
+ local y_adjust, node_depth, adj_depth = 0, 0, 0
+ for lp in node_traverse_id(id_glyph, head) do
+ y_adjust = has_attr(lp,attr_ablshift) or 0
+ local ld = getdepth(lp)
+ node_depth = max(ld + min(y_adjust, 0), node_depth)
+ adj_depth = (y_adjust>0) and max(ld + y_adjust, adj_depth) or adj_depth
+ setfield(lp, 'yoffset', getfield(lp, 'yoffset') - y_adjust)
+ end
+ if adj_depth>node_depth then
+ local r = node_new(id_rule,rule_subtype)
+ setwhd(r, 0, 0, adj_depth); setdir(r, tex_dir)
+ set_attr(r, attr_icflag, PROCESSED)
+ if field=='post' then
+ node_insert_after(head, head, r)
+ else
+ setfield(disc, field, (node_insert_before(head, head, r)))
+ end
+ end
+ end
+ function luatexja.setwidth.apply_ashift_disc(d, is_dir_tate, dir)
+ attr_ablshift = is_dir_tate and attr_tablshift or attr_yablshift
+ disc, tex_dir = d, dir
+ ashift_disc_inner('pre')
+ ashift_disc_inner('post')
+ ashift_disc_inner('replace')
+ end
+end
diff --git a/macros/luatex/generic/luatexja/src/ltj-stack.lua b/macros/luatex/generic/luatexja/src/ltj-stack.lua
new file mode 100644
index 0000000000..121804d20c
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-stack.lua
@@ -0,0 +1,143 @@
+--
+-- luatexja/stack.lua
+--
+luatexbase.provides_module({
+ name = 'luatexja.stack',
+ date = '2018/02/18',
+ description = 'LuaTeX-ja stack system',
+})
+luatexja.stack = {}
+local ltjs=luatexja.stack
+luatexja.load_module('base'); local ltjb = luatexja.base
+
+--------------------------------------------------------------------------------
+-- stack table (obeys TeX's grouping)
+--------------------------------------------------------------------------------
+local node_new = node.new
+local id_whatsit = node.id('whatsit')
+local sid_user = node.subtype('user_defined')
+local STCK = luatexja.userid_table.STCK
+local fastcopy = table.fastcopy
+local setcount = tex.setcount
+local scan_int, scan_keyword = token.scan_int, token.scan_keyword
+ltjs.hmode = 0 -- dummy
+
+local charprop_stack_table={};
+ltjs.charprop_stack_table = charprop_stack_table
+charprop_stack_table[0]={}
+
+
+local function get_stack_level()
+ local i = tex.getcount('ltj@@stack')
+ local j = tex.currentgrouplevel
+ if j > tex.getcount('ltj@@group@level') then
+ i = i+1 -- new stack level
+ local gd = tex.globaldefs
+ if gd~=0 then tex.globaldefs = 0 end
+ -- 'tex.globaldefs = 0' is local even if \globaldefs > 0.
+ setcount('ltj@@group@level', j)
+ for k,v in pairs(charprop_stack_table) do -- clear the stack above i
+ if k>=i then charprop_stack_table[k]=nil end
+ end
+ charprop_stack_table[i] = fastcopy(charprop_stack_table[i-1])
+ setcount('ltj@@stack', i)
+ if gd~=0 then tex.globaldefs = gd end
+ if tex.nest[tex.nest.ptr].mode == -ltjs.hmode then -- rest. hmode ã®ã¿
+ local g = node_new(id_whatsit, sid_user)
+ g.user_id=STCK; g.type=100; g.value=j; node.write(g)
+ end
+ end
+ return i
+end
+ltjs.get_stack_level = get_stack_level
+
+local function set_stack_table(m, p)
+ local i = get_stack_level()
+ charprop_stack_table[i][m] = p
+ if luatexja.isglobal=='global' then
+ for j,v in pairs(charprop_stack_table) do
+ charprop_stack_table[j][m] = p
+ end
+ end
+end
+ltjs.set_stack_table = set_stack_table
+
+-- EXT
+function ltjs.set_stack_perchar(m,lb,ub, getter)
+ local c = scan_int()
+ scan_keyword(',')
+ local p = tonumber((getter or scan_int)())
+ if p<lb or p>ub then
+ ltjb.package_error('luatexja',
+ "invalid code (".. tostring(p) .. ")",
+ "The code should in the range "..tostring(lb) .. '..' ..
+ tostring(ub) .. ".\n" ..
+ "I'm going to use 0 instead of that illegal code value.")
+ p=0
+ end
+ set_stack_table(m+ltjb.in_unicode(c, true), p)
+end
+
+-- EXT
+function ltjs.set_stack_font(m,c,p)
+ if type(c)~='number' or c<0 or c>255 then
+ ltjb.package_error('luatexja',
+ "invalid family number (".. tostring(c) .. ")",
+ "The family number should in the range 0 .. 255.\n" ..
+ "I'm going to use 0 instead of that illegal family number.")
+ c=0
+ end
+ set_stack_table(m+c, p)
+end
+
+-- EXT: sp: glue_spec
+function ltjs.set_stack_skip(m,sp)
+ local i = get_stack_level()
+ if not sp then return end
+ if not charprop_stack_table[i][m] then
+ charprop_stack_table[i][m] = {}
+ end
+ charprop_stack_table[i][m].width = sp.width
+ charprop_stack_table[i][m].stretch = sp.stretch
+ charprop_stack_table[i][m].shrink = sp.shrink
+ charprop_stack_table[i][m].stretch_order = sp.stretch_order
+ charprop_stack_table[i][m].shrink_order = sp.shrink_order
+ if luatexja.isglobal=='global' then
+ for j,v in pairs(charprop_stack_table) do
+ if not charprop_stack_table[j][m] then charprop_stack_table[j][m] = {} end
+ charprop_stack_table[j][m].width = sp.width
+ charprop_stack_table[j][m].stretch = sp.stretch
+ charprop_stack_table[j][m].shrink = sp.shrink
+ charprop_stack_table[j][m].stretch_order = sp.stretch_order
+ charprop_stack_table[j][m].shrink_order = sp.shrink_order
+ end
+ end
+end
+
+-- These three functions are used in ltj-jfmglue.lua.
+-- list_dir and orig_char_table are used in other lua files.
+local orig_char_table = {}
+ltjs.orig_char_table = orig_char_table
+ltjs.list_dir = nil -- dummy
+ltjs.table_current_stack = nil -- dummy
+function ltjs.report_stack_level(bsl)
+ ltjs.table_current_stack = charprop_stack_table[bsl]
+ return bsl
+end
+function ltjs.fast_get_stack_skip(m)
+ return ltjs.table_current_stack[m]
+ or { width = 0, stretch = 0, shrink = 0, stretch_order = 0, shrink_order = 0 }
+end
+
+-- For other situations, use the following instead:
+function ltjs.get_stack_skip(m, idx)
+ return charprop_stack_table[idx][m]
+ or { width = 0, stretch = 0, shrink = 0, stretch_order = 0, shrink_order = 0 }
+end
+function ltjs.get_stack_table(mc, d, idx)
+ local i = charprop_stack_table[idx][mc]
+ return i or d
+end
+
+
+-- EOF
diff --git a/macros/luatex/generic/luatexja/src/ltj-unicode-ccfix.lua b/macros/luatex/generic/luatexja/src/ltj-unicode-ccfix.lua
new file mode 100644
index 0000000000..47f41f359e
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltj-unicode-ccfix.lua
@@ -0,0 +1,276 @@
+-- Do not edit this file!
+-- Created from LineBreak.txt by ltj-unicode-ccfix_make.pl on 2019年 7月 8日 月曜日 06:15:17 JST.
+-- In case of errors, fix the Perl script instead.
+local tex_catcode = tex.setcatcode
+local tex_getcc = tex.getcatcode
+local function set_letter(b,e)
+ if tex_getcc(b)~=11 then
+ for i=b,e do tex_catcode('global', i, 11) end
+ end
+end
+set_letter(0x231A,0x231B)
+set_letter(0x23F0,0x23F3)
+set_letter(0x2600,0x2603)
+set_letter(0x2614,0x2615)
+set_letter(0x2618,0x2618)
+set_letter(0x261A,0x261C)
+set_letter(0x261E,0x261F)
+set_letter(0x2639,0x263B)
+set_letter(0x2668,0x2668)
+set_letter(0x267F,0x267F)
+set_letter(0x26BD,0x26C8)
+set_letter(0x26CD,0x26CD)
+set_letter(0x26CF,0x26D1)
+set_letter(0x26D3,0x26D4)
+set_letter(0x26D8,0x26D9)
+set_letter(0x26DC,0x26DC)
+set_letter(0x26DF,0x26E1)
+set_letter(0x26EA,0x26EA)
+set_letter(0x26F1,0x26F5)
+set_letter(0x26F7,0x26F8)
+set_letter(0x26FA,0x26FA)
+set_letter(0x26FD,0x26FF)
+set_letter(0x2700,0x2704)
+set_letter(0x2708,0x2709)
+set_letter(0x2764,0x2764)
+set_letter(0x2E80,0x2E99)
+set_letter(0x2E9B,0x2EF3)
+set_letter(0x2F00,0x2FD5)
+set_letter(0x2FF0,0x2FFB)
+set_letter(0x3003,0x3003)
+set_letter(0x3004,0x3004)
+set_letter(0x3006,0x3006)
+set_letter(0x3007,0x3007)
+set_letter(0x3012,0x3013)
+set_letter(0x3020,0x3020)
+set_letter(0x3021,0x3029)
+set_letter(0x3030,0x3030)
+set_letter(0x3031,0x3034)
+set_letter(0x3036,0x3037)
+set_letter(0x3038,0x303A)
+set_letter(0x303D,0x303D)
+set_letter(0x303E,0x303F)
+set_letter(0x3042,0x3042)
+set_letter(0x3044,0x3044)
+set_letter(0x3046,0x3046)
+set_letter(0x3048,0x3048)
+set_letter(0x304A,0x3062)
+set_letter(0x3064,0x3082)
+set_letter(0x3084,0x3084)
+set_letter(0x3086,0x3086)
+set_letter(0x3088,0x308D)
+set_letter(0x308F,0x3094)
+set_letter(0x309F,0x309F)
+set_letter(0x30A2,0x30A2)
+set_letter(0x30A4,0x30A4)
+set_letter(0x30A6,0x30A6)
+set_letter(0x30A8,0x30A8)
+set_letter(0x30AA,0x30C2)
+set_letter(0x30C4,0x30E2)
+set_letter(0x30E4,0x30E4)
+set_letter(0x30E6,0x30E6)
+set_letter(0x30E8,0x30ED)
+set_letter(0x30EF,0x30F4)
+set_letter(0x30F7,0x30FA)
+set_letter(0x30FF,0x30FF)
+set_letter(0x3105,0x312F)
+set_letter(0x3131,0x318E)
+set_letter(0x3190,0x3191)
+set_letter(0x3192,0x3195)
+set_letter(0x3196,0x319F)
+set_letter(0x31A0,0x31BA)
+set_letter(0x31C0,0x31E3)
+set_letter(0x3200,0x321E)
+set_letter(0x3220,0x3229)
+set_letter(0x322A,0x3247)
+set_letter(0x3250,0x3250)
+set_letter(0x3251,0x325F)
+set_letter(0x3260,0x327F)
+set_letter(0x3280,0x3289)
+set_letter(0x328A,0x32B0)
+set_letter(0x32B1,0x32BF)
+set_letter(0x32C0,0x32FF)
+set_letter(0x3300,0x33FF)
+set_letter(0x3400,0x4DB5)
+set_letter(0x4DB6,0x4DBF)
+set_letter(0x4E00,0x9FEF)
+set_letter(0x9FF0,0x9FFF)
+set_letter(0xA000,0xA014)
+set_letter(0xA016,0xA48C)
+set_letter(0xA490,0xA4C6)
+set_letter(0xF900,0xFA6D)
+set_letter(0xFA6E,0xFA6F)
+set_letter(0xFA70,0xFAD9)
+set_letter(0xFADA,0xFAFF)
+set_letter(0xFE30,0xFE30)
+set_letter(0xFE31,0xFE32)
+set_letter(0xFE33,0xFE34)
+set_letter(0xFE45,0xFE46)
+set_letter(0xFE49,0xFE4C)
+set_letter(0xFE4D,0xFE4F)
+set_letter(0xFE51,0xFE51)
+set_letter(0xFE58,0xFE58)
+set_letter(0xFE5F,0xFE61)
+set_letter(0xFE62,0xFE62)
+set_letter(0xFE63,0xFE63)
+set_letter(0xFE64,0xFE66)
+set_letter(0xFE68,0xFE68)
+set_letter(0xFE6B,0xFE6B)
+set_letter(0xFF02,0xFF03)
+set_letter(0xFF06,0xFF07)
+set_letter(0xFF0A,0xFF0A)
+set_letter(0xFF0B,0xFF0B)
+set_letter(0xFF0D,0xFF0D)
+set_letter(0xFF0F,0xFF0F)
+set_letter(0xFF10,0xFF19)
+set_letter(0xFF1C,0xFF1E)
+set_letter(0xFF20,0xFF20)
+set_letter(0xFF21,0xFF3A)
+set_letter(0xFF3C,0xFF3C)
+set_letter(0xFF3E,0xFF3E)
+set_letter(0xFF3F,0xFF3F)
+set_letter(0xFF40,0xFF40)
+set_letter(0xFF41,0xFF5A)
+set_letter(0xFF5C,0xFF5C)
+set_letter(0xFF5E,0xFF5E)
+set_letter(0xFF66,0xFF66)
+set_letter(0xFF71,0xFF9D)
+set_letter(0xFFA0,0xFFBE)
+set_letter(0xFFC2,0xFFC7)
+set_letter(0xFFCA,0xFFCF)
+set_letter(0xFFD2,0xFFD7)
+set_letter(0xFFDA,0xFFDC)
+set_letter(0xFFE2,0xFFE2)
+set_letter(0xFFE3,0xFFE3)
+set_letter(0xFFE4,0xFFE4)
+set_letter(0x17000,0x187F7)
+set_letter(0x18800,0x18AF2)
+set_letter(0x1B000,0x1B0FF)
+set_letter(0x1B100,0x1B11E)
+set_letter(0x1B170,0x1B2FB)
+set_letter(0x1F000,0x1F02B)
+set_letter(0x1F02C,0x1F02F)
+set_letter(0x1F030,0x1F093)
+set_letter(0x1F094,0x1F09F)
+set_letter(0x1F0A0,0x1F0AE)
+set_letter(0x1F0AF,0x1F0B0)
+set_letter(0x1F0B1,0x1F0BF)
+set_letter(0x1F0C0,0x1F0C0)
+set_letter(0x1F0C1,0x1F0CF)
+set_letter(0x1F0D0,0x1F0D0)
+set_letter(0x1F0D1,0x1F0F5)
+set_letter(0x1F0F6,0x1F0FF)
+set_letter(0x1F10D,0x1F10F)
+set_letter(0x1F16D,0x1F16F)
+set_letter(0x1F1AD,0x1F1E5)
+set_letter(0x1F200,0x1F202)
+set_letter(0x1F203,0x1F20F)
+set_letter(0x1F210,0x1F23B)
+set_letter(0x1F23C,0x1F23F)
+set_letter(0x1F240,0x1F248)
+set_letter(0x1F249,0x1F24F)
+set_letter(0x1F250,0x1F251)
+set_letter(0x1F252,0x1F25F)
+set_letter(0x1F260,0x1F265)
+set_letter(0x1F266,0x1F2FF)
+set_letter(0x1F300,0x1F384)
+set_letter(0x1F386,0x1F39B)
+set_letter(0x1F39E,0x1F3B4)
+set_letter(0x1F3B7,0x1F3BB)
+set_letter(0x1F3BD,0x1F3C1)
+set_letter(0x1F3C5,0x1F3C6)
+set_letter(0x1F3C8,0x1F3C9)
+set_letter(0x1F3CD,0x1F3FA)
+set_letter(0x1F400,0x1F441)
+set_letter(0x1F444,0x1F445)
+set_letter(0x1F451,0x1F465)
+set_letter(0x1F479,0x1F47B)
+set_letter(0x1F47D,0x1F480)
+set_letter(0x1F484,0x1F484)
+set_letter(0x1F488,0x1F48E)
+set_letter(0x1F490,0x1F490)
+set_letter(0x1F492,0x1F49F)
+set_letter(0x1F4A1,0x1F4A1)
+set_letter(0x1F4A3,0x1F4A3)
+set_letter(0x1F4A5,0x1F4A9)
+set_letter(0x1F4AB,0x1F4AE)
+set_letter(0x1F4B0,0x1F4B0)
+set_letter(0x1F4B3,0x1F4FF)
+set_letter(0x1F507,0x1F516)
+set_letter(0x1F525,0x1F531)
+set_letter(0x1F54A,0x1F573)
+set_letter(0x1F576,0x1F579)
+set_letter(0x1F57B,0x1F58F)
+set_letter(0x1F591,0x1F594)
+set_letter(0x1F597,0x1F5D3)
+set_letter(0x1F5DC,0x1F5F3)
+set_letter(0x1F5FA,0x1F5FF)
+set_letter(0x1F600,0x1F644)
+set_letter(0x1F648,0x1F64A)
+set_letter(0x1F680,0x1F6A2)
+set_letter(0x1F6A4,0x1F6B3)
+set_letter(0x1F6B7,0x1F6BF)
+set_letter(0x1F6C1,0x1F6CB)
+set_letter(0x1F6CD,0x1F6D5)
+set_letter(0x1F6D6,0x1F6DF)
+set_letter(0x1F6E0,0x1F6EC)
+set_letter(0x1F6ED,0x1F6EF)
+set_letter(0x1F6F0,0x1F6FA)
+set_letter(0x1F6FB,0x1F6FF)
+set_letter(0x1F774,0x1F77F)
+set_letter(0x1F7D5,0x1F7D8)
+set_letter(0x1F7D9,0x1F7DF)
+set_letter(0x1F7E0,0x1F7EB)
+set_letter(0x1F7EC,0x1F7FF)
+set_letter(0x1F80C,0x1F80F)
+set_letter(0x1F848,0x1F84F)
+set_letter(0x1F85A,0x1F85F)
+set_letter(0x1F888,0x1F88F)
+set_letter(0x1F8AE,0x1F8FF)
+set_letter(0x1F90C,0x1F90C)
+set_letter(0x1F90D,0x1F90E)
+set_letter(0x1F910,0x1F917)
+set_letter(0x1F920,0x1F925)
+set_letter(0x1F927,0x1F92F)
+set_letter(0x1F93A,0x1F93B)
+set_letter(0x1F93F,0x1F971)
+set_letter(0x1F972,0x1F972)
+set_letter(0x1F973,0x1F976)
+set_letter(0x1F977,0x1F979)
+set_letter(0x1F97A,0x1F9A2)
+set_letter(0x1F9A3,0x1F9A4)
+set_letter(0x1F9A5,0x1F9AA)
+set_letter(0x1F9AB,0x1F9AD)
+set_letter(0x1F9AE,0x1F9B4)
+set_letter(0x1F9B7,0x1F9B7)
+set_letter(0x1F9BA,0x1F9BA)
+set_letter(0x1F9BC,0x1F9CA)
+set_letter(0x1F9CB,0x1F9CC)
+set_letter(0x1F9D0,0x1F9D0)
+set_letter(0x1F9DE,0x1F9FF)
+set_letter(0x1FA54,0x1FA5F)
+set_letter(0x1FA60,0x1FA6D)
+set_letter(0x1FA6E,0x1FA6F)
+set_letter(0x1FA70,0x1FA73)
+set_letter(0x1FA74,0x1FA77)
+set_letter(0x1FA78,0x1FA7A)
+set_letter(0x1FA7B,0x1FA7F)
+set_letter(0x1FA80,0x1FA82)
+set_letter(0x1FA83,0x1FA8F)
+set_letter(0x1FA90,0x1FA95)
+set_letter(0x1FA96,0x1FAFF)
+set_letter(0x1FB00,0x1FFFD)
+set_letter(0x20000,0x2A6D6)
+set_letter(0x2A6D7,0x2A6FF)
+set_letter(0x2A700,0x2B734)
+set_letter(0x2B735,0x2B73F)
+set_letter(0x2B740,0x2B81D)
+set_letter(0x2B81E,0x2B81F)
+set_letter(0x2B820,0x2CEA1)
+set_letter(0x2CEA2,0x2CEAF)
+set_letter(0x2CEB0,0x2EBE0)
+set_letter(0x2EBE1,0x2F7FF)
+set_letter(0x2F800,0x2FA1D)
+set_letter(0x2FA1E,0x2FA1F)
+set_letter(0x2FA20,0x2FFFD)
+set_letter(0x30000,0x3FFFD)
diff --git a/macros/luatex/generic/luatexja/src/ltjclasses.dtx b/macros/luatex/generic/luatexja/src/ltjclasses.dtx
new file mode 100644
index 0000000000..3112fd1c22
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltjclasses.dtx
@@ -0,0 +1,4676 @@
+% \iffalse meta-comment
+%% File: ltjclasses.dtx
+% -----------------------------------------
+% Original: jclasses.dtx
+%
+% Copyright 1995-2001 ASCII Corporation.
+% Copyright (c) 2010 ASCII MEDIA WORKS
+% Copyright (c) 2016-2018 Japanese TeX Development Community
+%
+% This file is part of the pLaTeX2e system (community edition).
+% -------------------------------------------------------------
+%
+% \fi
+%
+%
+% \setcounter{StandardModuleDepth}{1}
+% \StopEventually{}
+%
+% \iffalse
+% \changes{v1.0}{1995/04/19}{first edition}
+% \changes{v1.0a}{1995/08/30}{ページスタイル部分ã®èª¿æ•´}
+% \changes{v1.0b}{1995/11/08}{ページスタイル部分ã®èª¿æ•´}
+% \changes{v1.0c}{1996/01/30}{\LaTeX\ \texttt{!<1995/12/01!>}ã§ã®ä¿®æ­£ã‚’å映}
+% \changes{v1.0d}{1996/02/29}{デフォルトページスタイルã®ä¿®æ­£}
+% \changes{v1.0e}{1996/03/14}{itemize, enumerate環境ã®ä¿®æ­£}
+% \changes{v1.0f}{1996/07/10}{é¢ä»˜ã‘オプションを追加}
+% \changes{v1.0g}{1996/09/03}{トンボã®æ¨ªã«ä½œæˆæ—¥æ™‚を出力ã™ã‚‹ã‚ˆã†ã«ã—ãŸ}
+% \changes{v1.1}{1997/01/16}{\LaTeX\ \texttt{!<1996/06/01!>}版ã«å¯¾å¿œ}
+% \changes{v1.1a}{1997/01/23}{\LaTeX\ \texttt{!<1996/12/01!>}版ã«å¯¾å¿œ}
+% \changes{v1.1a}{1997/01/25}{互æ›ãƒ¢ãƒ¼ãƒ‰ã§p\LaTeX~2.09ã®a4jãªã©ã®
+% 用紙オプションã«å¯¾å¿œ}
+% \changes{v1.1b}{1997/01/28}{日本語ファミリã®å®£è¨€ã‚’å†åº¦ã€å®Ÿè£…}
+% \changes{v1.1d}{1997/01/29}{2eモードã§a4jãªã©ã®ã‚ªãƒ—ションã«å¯¾å¿œ}
+% \changes{v1.1e}{1997/04/08}{トップマージンã®å€¤ã‚’修正}
+% \changes{v1.1f}{1997/07/08}{縦組クラスã§ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ãŒãŠã‹ã—ã„ã®ã‚’修正}
+% \changes{v1.1g}{1997/08/25}{片é¢å°åˆ·ã®ã¨ãã€sectionレベルãŒå‡ºåŠ›ã•ã‚Œãªã„
+% ã®ã‚’修正}
+% \changes{v1.1h}{1997/09/03}{landscape指定時ã®å€¤ã‚’修正}
+% \changes{v1.1i}{1997/12/12}{report, bookクラスã§ç‰‡é¢å°åˆ·æ™‚ã«ã€
+% bothstyleスタイルã«ã™ã‚‹ã¨ã€ã‚³ãƒ³ãƒ‘イルエラーã«ãªã‚‹ã®ã‚’修正}
+% \changes{v1.1j}{1998/02/03}{互æ›ãƒ¢ãƒ¼ãƒ‰æ™‚ã®a5pã®ãƒˆãƒƒãƒ—マージンを0.7in増加}
+% \changes{v1.1k}{1998/03/23}{reportã¨bookクラスã§ç•ªå·ã‚’付ã‘ãªã„見出ã—ã®
+% ペナルティãŒ\cs{M@}ã ã£ãŸã®ã‚’\cs{@M}ã«ä¿®æ­£}
+% \changes{v1.1m}{1998/04/07}{\cs{today}ã®è¨ˆç®—手順を変更}
+% \changes{v1.1n}{1998/10/13}{report,bookクラスã®è¡¨ç•ªå·ãŒ
+% 見出ã—レベルã«é–¢ä¿‚ãªãchapter番å·ãŒå‡ºåŠ›ã•ã‚Œã¦ã—ã¾ã†ã®ã‚’修正}
+% \changes{v1.1n}{1998/10/13}{mentukeオプションãŒã‚¨ãƒ©ãƒ¼ã«ãªã£ã¦ã„ãŸã®ã‚’修正}
+% \changes{v1.1o}{1998/12/24}{secnumdepthカウンタを$-1$以下ã«ã™ã‚‹ã¨ã€
+% 見出ã—文字列も消ãˆã¦ã—ã¾ã†ã®ã‚’修正}
+% \changes{v1.1p}{1999/1/6}{\cs{oddsidemargin}ã®ãƒã‚¤ãƒ³ãƒˆã¸ã®å¤‰æ›ã‚’後ã‚ã«}
+% \changes{v1.1q}{1999/05/18}{縦組時ã®ã¿ã«è¨­å®šã™ã‚‹ã‚ˆã†ã«ã—ãŸ}
+% \changes{v1.1r}{1999/08/09}{トップマージンã®è¨ˆç®—å¼ã‚’修正}
+% \changes{v1.2}{2001/09/04}{\cs{chapter}ã®å‡ºåŠ›ä½ç½®ãŒã‚¢ã‚¹ã‚¿ãƒªã‚¹ã‚¯å½¢å¼ã¨
+% ãã†ã§ãªã„ã¨ãã¨é•ã†ã®ã‚’修正(ã‚ã‚ŠãŒã¨ã†ã€éˆ´æœ¨ï¼ æ´¥ã•ã‚“)}
+% \changes{v1.3}{2001/10/04}{目次ã®ãƒšãƒ¼ã‚¸ç•ªå·ã®æ›¸ä½“ã‚’\cs{rmfamily}ã‹ã‚‰
+% \cs{normalfont}ã«å¤‰æ›´(ã‚ã‚ŠãŒã¨ã†ã€éˆ´æœ¨ãŸï¼ MILNã•ã‚“)}
+% \changes{v1.4}{2002/04/09}{縦組スタイルã§\cs{flushbottom}ã—ãªã„よã†ã«ã—ãŸ}
+% \changes{v1.5}{2004/01/15}{\cs{part},\cs{chapter}ã®\cs{@afterindentfalse}ã‚’
+% \cs{@afterindenttrue}ã«å¤‰æ›´ã€‚
+% \cs{section},\cs{subsection},\cs{subsubsection}ã®å‰å¾Œç©ºãã®ä¼¸ç¸®å¹…を修正。
+% (ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€éˆ´æœ¨ãŸï¼ MILNã•ã‚“)}
+% \changes{v1.6}{2006/06/27}{フォントコマンドを修正。ã‚ã‚ŠãŒã¨ã†ã€ymtã•ã‚“。}
+% \changes{v1.6-ltj}{2011/09/27}{jclasses.dtx v1.6 をベースã«Lua\LaTeX-ja用ã«ä¿®æ­£ã€‚}
+% \changes{v1.6-ltj-2}{2013/06/06}{luatexja.cfgã«å¯¾å¿œï¼Ž}
+% \changes{v1.6-ltj-3}{2014/06/08}{縦組クラスã®æ™‚ã®geometry.styã«å¯¾å¿œï¼Ž}
+% \changes{v1.6-ltj-4}{2014/06/30}{組方å‘ã®å¤‰æ›´ç®‡æ‰€ã‚’ç¾è¡Œã®Lua\TeX-jaã®ä»•æ§˜ã«åˆã†ã‚ˆã†ã«ä¿®æ­£ï¼Ž}
+% \changes{v1.6-ltj-5}{2014/07/02}{\cs{ifydir}, \cs{iftdir}を使ã‚ãªã„よã†ã«ä¿®æ­£ï¼Ž}
+% \changes{v1.6-ltj-6}{2014/07/28}{縦組クラスã§lltjext.styを読ã¿è¾¼ã‚€ã‚ˆã†ã«ä¿®æ­£ï¼Ž}
+% \changes{v1.6-ltj-7}{2014/11/15}{縦組クラスã¨everyshi.styã¨ã®ç›¸æ€§ãŒæ‚ªã„å•é¡Œã‚’修正.}
+% \changes{v1.6-ltj-8}{2014/11/22}{縦組時ã®geometry.styã¸ã®å¯¾å¿œã‚’別ファイル(lltjp-geometry.sty)ã«åˆ†é›¢ï¼Žãã‚Œã«ä¼´ã„v1.6-ltj-3ã§ã®å¤‰æ›´ã‚’削除.}
+% \changes{v1.6-ltj-9}{2015/01/01}{縦組クラスã®æ—¥ä»˜å‡ºåŠ›ã§ã‚¨ãƒ©ãƒ¼ã«ãªã‚‹ã“ã¨ãªã©ã‚’修正.}
+% \changes{v1.6-ltj-10}{2015/10/18}{Lua\TeX\ 0.81.0ã«ä¼´ã†ãƒ—リミティブåã®å¤‰æ›´ã«å¯¾å¿œï¼Ž}
+% \changes{v1.6-ltj-11}{2016/07/19}{トンボ使用時ã®ç”¨ç´™ã‚µã‚¤ã‚ºã®è¨­å®šæ–¹æ³•ã‚’変更(aminophenã•ã‚“,ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ï¼‰ï¼Ž}
+% \changes{v1.7}{2016/11/12}{ドキュメントã«åã—ã¦\cs{@maketitle}ãŒ
+% 空ã«ãªã£ã¦ã„ãªã‹ã£ãŸã®ã‚’修正}
+% \changes{v1.7}{2016/11/12}{use \cs{@width} (sync with classes.dtx v1.3a)}
+% \changes{v1.7}{2016/11/12}{Replaced all \cs{hbox to} by
+% \cs{hb@xt@} (sync with classes.dtx v1.3a)}
+% \changes{v1.7}{2016/11/12}{Moved \cs{@mkboth} out of heading
+% arg (sync with classes.dtx v1.4c)}
+% \changes{v1.7}{2016/11/12}{\cs{columnsep}ã¨\cs{columnseprule}ã®
+% 変更を後ã‚ã«ç§»å‹•(sync with classes.dtx v1.4f)}
+% \changes{v1.7a}{2016/11/16}{Check \texttt{@noskipsec} switch and
+% possibly force horizontal mode (sync with classes.dtx v1.4a)}
+% \changes{v1.7a}{2016/11/16}{replace \cs{reset@font} with
+% \cs{normalfont} (sync with classes.dtx v1.3c)}
+% \changes{v1.7a}{2016/11/16}{Added \cs{nobreak} for
+% latex/2343 (sync with ltsect.dtx v1.0z)}
+% \changes{v1.7a}{2016/11/16}{Use \cs{expandafter}
+% (sync with ltlists.dtx v1.0j)}
+% \changes{v1.7b}{2016/11/22}{補足ドキュメントを追加}
+% \changes{v1.7c}{2016/12/18}{Only add empty page after part if
+% twoside and openright (sync with classes.dtx v1.4b)}
+% \changes{v1.7c-ltj-12}{2017/01/17}{|\stockwidth|,~|\stockheight|をトンボオプション指定時ã«ã®ã¿å®šç¾©
+% (aminophenã•ã‚“,ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ï¼‰ï¼Ž}
+% \changes{v1.7c}{2016/12/18}{奇妙ãªarticleガードã¨ã‚³ãƒ¼ãƒ‰ã‚’削除ã—ã¦
+% ドキュメントを追加}
+% \changes{v1.7d}{2017/02/15}{\cs{if@openleft}スイッãƒè¿½åŠ }
+% \changes{v1.7d}{2017/02/15}{openleftオプション追加}
+% \changes{v1.7d}{2017/02/15}{\cs{cleardoublepage}ã®ä»£ç”¨ã¨ãªã‚‹å‘½ä»¤ç¾¤ã‚’追加}
+% \changes{v1.7d}{2017/02/15}{bookクラスã§titlepageã‚’å¿…ãšå¥‡æ•°ãƒšãƒ¼ã‚¸
+% ã«é€ã‚‹ã‚ˆã†ã«å¤‰æ›´}
+% \changes{v1.7d}{2017/02/15}{titlepageã®ãƒšãƒ¼ã‚¸ç•ªå·ã‚’奇数ãªã‚‰ã°1ã«ã€
+% å¶æ•°ãªã‚‰ã°0ã«ãƒªã‚»ãƒƒãƒˆã™ã‚‹ã‚ˆã†ã«å¤‰æ›´}
+% \changes{v1.7d}{2017/02/15}{縦組クラスã®æ‰€å±žè¡¨ç¤ºã®ç•ªå·ã‚’ç›´ç«‹ã«ã—ãŸ}
+% \changes{v1.7d-ltj-13}{2017/02/19}{縦組時クラスã§|ftnright|パッケージを使ã†ã¨
+% 脚注番å·ãŒä¸Šæ›¸ãã•ã‚Œæ¨ªã«å¯ã¦ã—ã¾ã†å•é¡Œã‚’修正(aminophenã•ã‚“,ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ï¼‰ï¼Ž}
+% \changes{v1.7d-ltj-14}{2017/02/20}{openleftオプションã®å‡¦ç†ã§\cs{iftdir}, \cs{ifydir}ã‚’
+% 誤ã£ã¦ä½¿ã£ã¦ã„ã‚‹å•é¡Œã‚’修正(aminophenã•ã‚“,ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ï¼‰ï¼Ž}
+% \changes{v1.7e}{2017/03/05}{トンボã«è¡¨ç¤ºã™ã‚‹ã‚¸ãƒ§ãƒ–情報ã®æ›¸å¼ã‚’変更}
+% \changes{v1.7e}{2017/03/05}{\cs{frontmatter}ã¨\cs{mainmatter}ã‚’
+% 奇数ページã«é€ã‚‹ã‚ˆã†ã«å¤‰æ›´}
+% \changes{v1.7e-ltj-15}{2017/08/31}{本ドキュメントã®ã‚¿ã‚¤ãƒ—セットã§ï¼Œå°å¡šãƒ•ã‚©ãƒ³ãƒˆãŒå­˜åœ¨ã™ã‚‹ã¨ãã«ã¯
+% ãれを用ã„るよã†ã«å¤‰æ›´ï¼ˆPDFサイズ削減ã®ãŸã‚).}
+% \changes{v1.7f}{2017/08/31}{和文書体ã®åŸºæº–を全角空白ã‹ã‚‰ã€Œæ¼¢ã€ã«å¤‰æ›´}
+% \changes{v1.7g}{2017/09/19}{内部処ç†ã§ä½¿ã£ãŸãƒœãƒƒã‚¯ã‚¹0を空ã«ã—ãŸ}
+% \changes{v1.7h}{2018/02/04}{和文スケール値\cs{Cjascale}を定義}
+% \changes{v1.8}{2018/07/03}{\cs{today}ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã‚’和暦ã‹ã‚‰è¥¿æš¦ã«å¤‰æ›´}
+% \changes{v1.8-ltj-16}{2018/10/08}{Lua\TeX-jaãŒ|disablejfam|オプションをサãƒãƒ¼ãƒˆã—ãŸã“ã¨ã«ã‚ˆã‚‹å¤‰æ›´}
+% \changes{v1.8a}{2018/10/25}{ファイル書ã出ã—時ã®è¡Œæœ«æ–‡å­—対策
+% (sync with ltsect.dtx 2018/09/26 v1.1c)}
+% \changes{v1.8b}{2019/04/02}{æ–°å…ƒå·å¯¾å¿œ}
+% \changes{v1.8b-ltj-17}{2019/08/12}{disablejfamã®``Unused global option(s)''警告を出ã•ãªã„よã†ã«ã—ãŸ}
+
+% \fi
+%
+% \iffalse
+\NeedsTeXFormat{LaTeX2e}
+%<*driver>
+\ProvidesFile{ltjclasses.dtx}
+%</driver>
+%<*yoko>
+%<article>\ProvidesClass{ltjarticle}
+%<report>\ProvidesClass{ltjreport}
+%<book>\ProvidesClass{ltjbook}
+%<10pt&!bk>\ProvidesFile{ltjsize10.clo}
+%<11pt&!bk>\ProvidesFile{ltjsize11.clo}
+%<12pt&!bk>\ProvidesFile{ltjsize12.clo}
+%<10pt&bk>\ProvidesFile{ltjbk10.clo}
+%<11pt&bk>\ProvidesFile{ltjbk11.clo}
+%<12pt&bk>\ProvidesFile{ltjbk12.clo}
+%</yoko>
+%<*tate>
+%<article>\ProvidesClass{ltjtarticle}
+%<report>\ProvidesClass{ltjtreport}
+%<book>\ProvidesClass{ltjtbook}
+%<10pt&!bk>\ProvidesFile{ltjtsize10.clo}
+%<11pt&!bk>\ProvidesFile{ltjtsize11.clo}
+%<12pt&!bk>\ProvidesFile{ltjtsize12.clo}
+%<10pt&bk>\ProvidesFile{ltjtbk10.clo}
+%<11pt&bk>\ProvidesFile{ltjtbk11.clo}
+%<12pt&bk>\ProvidesFile{ltjtbk12.clo}
+%</tate>
+ [2019/08/12 v1.8b-ltj-17
+%<article|report|book> Standard LuaLaTeX-ja class]
+%<10pt|11pt|12pt> Standard LuaLaTeX-ja file (size option)]
+%<*driver>
+]
+\documentclass{ltjltxdoc}
+\GetFileInfo{ltjclasses.dtx}
+\begingroup
+ \suppressfontnotfounderror=1
+ \global\font\testfont=file:KozMinPr6N-Regular.otf
+\endgroup
+\ifx\testfont\nullfont
+ \usepackage[ipaex,nfssonly]{luatexja-preset}
+\else
+ \usepackage[kozuka-pr6n,nfssonly]{luatexja-preset}
+\fi
+\def\pLaTeX{p\kern-.05em\LaTeX}
+\usepackage[unicode]{hyperref}
+\title{Lua\LaTeX-ja用\texttt{jclasses}互æ›ã‚¯ãƒ©ã‚¹}
+\author{Lua\TeX-jaプロジェクト}
+\date{\filedate}
+\begin{document}
+ \maketitle
+ \tableofcontents
+ \DocInput{\filename}
+\end{document}
+%</driver>
+% \fi
+%
+% \section{ã¯ã˜ã‚ã«}
+% ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ã€Lua\LaTeX-ja用ã®|jclasses|互æ›ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã§ã™ã€‚
+% コミュニティ版をベースã«ä½œæˆã—ã¦ã„ã¾ã™ã€‚
+% \dst{}プログラムã«ã‚ˆã£ã¦ã€æ¨ªçµ„用ã®ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã¨ç¸¦çµ„用ã®ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«
+% を作æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+%
+% 次ã«\dst{}プログラムã®ãŸã‚ã®ã‚ªãƒ—ションを示ã—ã¾ã™ã€‚
+%
+% \DeleteShortVerb{\|}
+% \begin{center}
+% \begin{tabular}{l|l}
+% \emph{オプション} & \emph{æ„味}\\\hline
+% article & articleクラスを生æˆ\\
+% report & reportクラスを生æˆ\\
+% book & bookクラスを生æˆ\\
+% 10pt & 10ptサイズã®è¨­å®šã‚’生æˆ\\
+% 11pt & 11ptサイズã®è¨­å®šã‚’生æˆ\\
+% 12pt & 12ptサイズã®è¨­å®šã‚’生æˆ\\
+% bk & bookクラス用ã®ã‚µã‚¤ã‚ºã®è¨­å®šã‚’生æˆ\\
+% tate & 縦組用ã®è¨­å®šã‚’生æˆ\\
+% yoko & 横組用ã®è¨­å®šã‚’生æˆ\\
+% \end{tabular}
+% \end{center}
+% \MakeShortVerb{\|}
+%
+% \subsection{\texttt{jclasses.dtx} ã‹ã‚‰ã®ä¸»ãªå¤‰æ›´ç‚¹}
+% å…¨ã¦ã®å¤‰æ›´ç‚¹ã‚’知りãŸã„å ´åˆã¯ã€|jclasses.dtx|ã¨|ltjclasses.dtx|ã§|diff|ã‚’
+% ã¨ã£ã¦ä¸‹ã•ã„。
+% \begin{itemize}
+% \item ã‚‚ã—
+% \begin{quotation}
+% |! LaTeX Error: Too many math alphabets used in version ****.|
+% \end{quotation}
+% ã®ã‚¨ãƒ©ãƒ¼ãŒèµ·ã“ã£ãŸå ´åˆã¯ã€|lualatex-math|パッケージを読ã¿è¾¼ã‚“ã§ã¿ã¦ä¸‹ã•ã„。
+% \item 出力PDFã®ç”¨ç´™ã‚µã‚¤ã‚ºãŒè‡ªå‹•çš„ã«è¨­å®šã•ã‚Œã‚‹ã‚ˆã†ã«ã—ã¦ã‚ã‚Šã¾ã™ã€‚
+% %%%\item 縦組ã¿ã‚¯ãƒ©ã‚¹ã«ãŠã„ã¦ã€|geometry|パッケージを読ã¿è¾¼ã‚“ã ã¨ãã«æ„図通りã«ãªã‚‰ãªã„å•é¡Œã«å¯¾å¿œã—ã¾ã—ãŸã€‚%
+% \end{itemize}
+%
+% \section{Lua\TeX-ja ã®èª­ã¿è¾¼ã¿}
+% 最åˆã«|luatexja|を読ã¿è¾¼ã¿ã¾ã™ã€‚
+% \begin{macrocode}
+%<*article|report|book>
+\RequirePackage{luatexja}
+% \end{macrocode}
+%
+% \section{オプションスイッãƒ}
+% ã“ã“ã§ã¯ã€å¾Œã»ã©ä½¿ç”¨ã™ã‚‹ã„ãã¤ã‹ã®ã‚³ãƒžãƒ³ãƒ‰ã‚„スイッãƒã‚’定義ã—ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macro}{\c@@paper}
+% 用紙サイズを示ã™ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚
+% A4, A5, B4, B5用紙ã¯ãã‚Œãžã‚Œã€1, 2, 3, 4ã¨ã—ã¦è¡¨ã•ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+\newcounter{@paper}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if@landscape}
+% 用紙を横å‘ãã«ã™ã‚‹ã‹ã©ã†ã‹ã®ã‚¹ã‚¤ãƒƒãƒã§ã™ã€‚デフォルトã¯ã€ç¸¦å‘ãã§ã™ã€‚
+% \begin{macrocode}
+\newif\if@landscape \@landscapefalse
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@ptsize}
+% 組版をã™ã‚‹ãƒã‚¤ãƒ³ãƒˆæ•°ã®ä¸€ã®ä½ã‚’ä¿å­˜ã™ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚
+% 0, 1, 2ã®ã„ãšã‚Œã‹ã§ã™ã€‚
+% \begin{macrocode}
+\newcommand{\@ptsize}{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if@restonecol}
+% 二段組時ã«ç”¨ã„るテンãƒãƒ©ãƒªã‚¹ã‚¤ãƒƒãƒã§ã™ã€‚
+% \begin{macrocode}
+\newif\if@restonecol
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if@titlepage}
+% タイトルページやアブストラクト(概è¦ï¼‰ã‚’
+% 独立ã—ãŸãƒšãƒ¼ã‚¸ã«ã™ã‚‹ã‹ã©ã†ã‹ã®ã‚¹ã‚¤ãƒƒãƒã§ã™ã€‚
+% reportã¨bookスタイルã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯ã€ç‹¬ç«‹ã—ãŸãƒšãƒ¼ã‚¸ã«ãªã‚Šã¾ã™ã€‚
+% \begin{macrocode}
+\newif\if@titlepage
+%<article>\@titlepagefalse
+%<report|book>\@titlepagetrue
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if@openright}
+% chapterレベルをå³ãƒšãƒ¼ã‚¸ã‹ã‚‰ã¯ã˜ã‚ã‚‹ã‹ã©ã†ã‹ã®ã‚¹ã‚¤ãƒƒãƒã§ã™ã€‚
+% 横組ã§ã¯å¥‡æ•°ãƒšãƒ¼ã‚¸ã€ç¸¦çµ„ã§ã¯å¶æ•°ãƒšãƒ¼ã‚¸ã‹ã‚‰å§‹ã¾ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚
+% reportクラスã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯ã€``no''ã§ã™ã€‚
+% bookクラスã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯ã€``yes''ã§ã™ã€‚
+% \begin{macrocode}
+%<!article>\newif\if@openright
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if@openleft}
+% chapterレベルを左ページã‹ã‚‰ã¯ã˜ã‚ã‚‹ã‹ã©ã†ã‹ã®ã‚¹ã‚¤ãƒƒãƒã§ã™ã€‚
+% 日本語\TeX{}開発コミュニティ版ã§æ–°ãŸã«è¿½åŠ ã•ã‚Œã¾ã—ãŸã€‚
+% 横組ã§ã¯å¶æ•°ãƒšãƒ¼ã‚¸ã€ç¸¦çµ„ã§ã¯å¥‡æ•°ãƒšãƒ¼ã‚¸ã‹ã‚‰å§‹ã¾ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚
+% reportクラスã¨bookクラスã®ä¸¡æ–¹ã§ã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯``no''ã§ã™ã€‚
+% \changes{v1.7d}{2017/02/15}{\cs{if@openleft}スイッãƒè¿½åŠ }
+% \begin{macrocode}
+%<!article>\newif\if@openleft
+% \end{macrocode}
+% \end{macro}
+%
+% \changes{v1.0c}{1995/12/25}{Macro \cs{if@openbib} removed}
+%
+% \begin{macro}{\if@mainmatter}
+% スイッãƒ|\@mainmatter|ãŒçœŸã®å ´åˆã€æœ¬æ–‡ã‚’処ç†ã—ã¦ã„ã¾ã™ã€‚
+% ã“ã®ã‚¹ã‚¤ãƒƒãƒãŒå½ã®å ´åˆã¯ã€|\chapter|コマンドã¯è¦‹å‡ºã—番å·ã‚’出力ã—ã¾ã›ã‚“。
+% \begin{macrocode}
+%<book>\newif\if@mainmatter \@mainmattertrue
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hour}
+% \begin{macro}{\minute}
+% \begin{macrocode}
+\hour\time \divide\hour by 60\relax
+\@tempcnta\hour \multiply\@tempcnta 60\relax
+\minute\time \advance\minute-\@tempcnta
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\if@stysize}
+% \changes{v1.1a}{1997/01/25}{Add \cs{if@stysize}.}
+% \LaTeXe~2.09互æ›ãƒ¢ãƒ¼ãƒ‰ã§ã€ã‚¹ã‚¿ã‚¤ãƒ«ã‚ªãƒ—ションã«a4j, a5pãªã©ãŒæŒ‡å®šã•ã‚ŒãŸ
+% ã¨ãã®å‹•ä½œã‚’エミュレートã™ã‚‹ãŸã‚ã®ãƒ•ãƒ©ã‚°ã§ã™ã€‚
+% \begin{macrocode}
+\newif\if@stysize \@stysizefalse
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if@mathrmmc}
+% 和欧文両対応ã®æ•°å¼æ–‡å­—コマンドを有効ã«ã™ã‚‹ã¨ãã«ç”¨ã„るフラグã§ã™ã€‚
+% マクロã®å±•é–‹é †åºãŒè¤‡é›‘ã«ãªã‚‹ã®ã‚’é¿ã‘ã‚‹ãŸã‚ã€
+% デフォルトã§ã¯falseã¨ã—ã¦ã‚ã‚Šã¾ã™ã€‚
+% \begin{macrocode}
+\newif\if@mathrmmc \@mathrmmcfalse
+% \end{macrocode}
+% \end{macro}
+%
+% \section{オプションã®å®£è¨€}
+% ã“ã“ã§ã¯ã€ã‚¯ãƒ©ã‚¹ã‚ªãƒ—ションã®å®£è¨€ã‚’è¡Œãªã£ã¦ã„ã¾ã™ã€‚
+%
+% \subsection{用紙オプション}
+% 用紙サイズを指定ã™ã‚‹ã‚ªãƒ—ションã§ã™ã€‚
+% \begin{macrocode}
+\DeclareOption{a4paper}{\setcounter{@paper}{1}%
+ \setlength\paperheight {297mm}%
+ \setlength\paperwidth {210mm}}
+\DeclareOption{a5paper}{\setcounter{@paper}{2}%
+ \setlength\paperheight {210mm}
+ \setlength\paperwidth {148mm}}
+\DeclareOption{b4paper}{\setcounter{@paper}{3}%
+ \setlength\paperheight {364mm}
+ \setlength\paperwidth {257mm}}
+\DeclareOption{b5paper}{\setcounter{@paper}{4}%
+ \setlength\paperheight {257mm}
+ \setlength\paperwidth {182mm}}
+% \end{macrocode}
+% \changes{v1.0a}{1995/09/26}{Change b4paper width/height 352x250 to 364x257}
+% \changes{v1.0a}{1995/09/26}{Change b5paper width/height 250x176 to 257x182}
+% ドキュメントクラスã«ã€ä»¥ä¸‹ã®ã‚ªãƒ—ションを指定ã™ã‚‹ã¨ã€é€šå¸¸ã‚ˆã‚Šã‚‚テキストを
+% 組ã¿ç«‹ã¦ã‚‹é ˜åŸŸã®åºƒã„スタイルã¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+% \begin{macrocode}
+%
+\DeclareOption{a4j}{\setcounter{@paper}{1}\@stysizetrue
+ \setlength\paperheight {297mm}%
+ \setlength\paperwidth {210mm}}
+\DeclareOption{a5j}{\setcounter{@paper}{2}\@stysizetrue
+ \setlength\paperheight {210mm}
+ \setlength\paperwidth {148mm}}
+\DeclareOption{b4j}{\setcounter{@paper}{3}\@stysizetrue
+ \setlength\paperheight {364mm}
+ \setlength\paperwidth {257mm}}
+\DeclareOption{b5j}{\setcounter{@paper}{4}\@stysizetrue
+ \setlength\paperheight {257mm}
+ \setlength\paperwidth {182mm}}
+%
+\DeclareOption{a4p}{\setcounter{@paper}{1}\@stysizetrue
+ \setlength\paperheight {297mm}%
+ \setlength\paperwidth {210mm}}
+\DeclareOption{a5p}{\setcounter{@paper}{2}\@stysizetrue
+ \setlength\paperheight {210mm}
+ \setlength\paperwidth {148mm}}
+\DeclareOption{b4p}{\setcounter{@paper}{3}\@stysizetrue
+ \setlength\paperheight {364mm}
+ \setlength\paperwidth {257mm}}
+\DeclareOption{b5p}{\setcounter{@paper}{4}\@stysizetrue
+ \setlength\paperheight {257mm}
+ \setlength\paperwidth {182mm}}
+% \end{macrocode}
+%
+% \subsection{サイズオプション}
+% 基準ã¨ãªã‚‹ãƒ•ã‚©ãƒ³ãƒˆã®å¤§ãã•ã‚’指定ã™ã‚‹ã‚ªãƒ—ションã§ã™ã€‚
+% \begin{macrocode}
+\if@compatibility
+ \renewcommand{\@ptsize}{0}
+\else
+ \DeclareOption{10pt}{\renewcommand{\@ptsize}{0}}
+\fi
+\DeclareOption{11pt}{\renewcommand{\@ptsize}{1}}
+\DeclareOption{12pt}{\renewcommand{\@ptsize}{2}}
+% \end{macrocode}
+%
+% \subsection{横置ãオプション}
+% ã“ã®ã‚ªãƒ—ションãŒæŒ‡å®šã•ã‚Œã‚‹ã¨ã€ç”¨ç´™ã®ç¸¦ã¨æ¨ªã®é•·ã•ã‚’入れæ›ãˆã¾ã™ã€‚
+% \changes{v1.1h}{1997/09/03}{オプションã®å‡¦ç†æ™‚ã«ç¸¦æ¨ªã®å€¤ã‚’交æ›}
+% \changes{v1.1h}{1997/09/03}{landscapeオプションを互æ›ãƒ¢ãƒ¼ãƒ‰ã§ã‚‚有効ã«}
+% \begin{macrocode}
+\DeclareOption{landscape}{\@landscapetrue
+ \setlength\@tempdima{\paperheight}%
+ \setlength\paperheight{\paperwidth}%
+ \setlength\paperwidth{\@tempdima}}
+% \end{macrocode}
+%
+% \subsection{トンボオプション}
+% |tombow|オプションãŒæŒ‡å®šã•ã‚Œã‚‹ã¨ã€ç”¨ç´™ã‚µã‚¤ã‚ºã«åˆã‚ã›ã¦ãƒˆãƒ³ãƒœã‚’出力ã—ã¾ã™ã€‚
+% ã“ã®ã¨ãã€ãƒˆãƒ³ãƒœã®è„‡ã«PDFを作æˆã—ãŸæ—¥ä»˜ãŒå‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+% 作æˆæ—¥ä»˜ã®å‡ºåŠ›ã‚’抑制ã™ã‚‹ã«ã¯ã€|tombow|ã§ã¯ãªãã€|tombo|ã¨æŒ‡å®šã‚’ã—ã¾ã™ã€‚
+%
+% ジョブ情報ã®æ›¸å¼ã¯å…ƒã€…|filename : 2017/3/5(13:3)|ã®ã‚ˆã†ãªæ›¸å¼ã§ã—ãŸãŒã€
+% jsclassesã«ã‚ã‚ã›ã¦æ¡æ•°å›ºå®šã®|filename (2017-03-05 13:03)|ã«ç›´ã—ã¾ã—ãŸã€‚
+% \changes{v1.0g}{1996/09/03}{Add to \cs{@bannertoken}.}
+% \changes{v1.1a}{1997/01/23}{日付出力オプション}
+% \changes{v1.7e}{2017/03/05}{トンボã«è¡¨ç¤ºã™ã‚‹ã‚¸ãƒ§ãƒ–情報ã®æ›¸å¼ã‚’変更}
+% \begin{macrocode}
+\DeclareOption{tombow}{%
+ \tombowtrue \tombowdatetrue
+ \setlength{\@tombowwidth}{.1\p@}%
+ \@bannertoken{%
+ \jobname\space(\number\year-\two@digits\month-\two@digits\day
+ \space\two@digits\hour:\two@digits\minute)}%
+ \maketombowbox}
+\DeclareOption{tombo}{%
+ \tombowtrue \tombowdatefalse
+ \setlength{\@tombowwidth}{.1\p@}%
+ \maketombowbox}
+% \end{macrocode}
+%
+% \subsection{é¢ä»˜ã‘オプション}
+% ã“ã®ã‚ªãƒ—ションãŒæŒ‡å®šã•ã‚Œã‚‹ã¨ã€ãƒˆãƒ³ãƒœã‚ªãƒ—ションを指定ã—ãŸã¨ãã¨åŒã˜
+% ä½ç½®ã«æ–‡ç« ã‚’出力ã—ã¾ã™ã€‚作æˆã—ãŸPDFをフィルムã«é¢ä»˜ã‘出力ã™ã‚‹å ´åˆãªã©
+% ã«æŒ‡å®šã‚’ã—ã¾ã™ã€‚
+% \changes{v1.0f}{1996/07/10}{é¢ä»˜ã‘オプションを追加}
+% \changes{v1.1n}{1998/10/13}
+% {動作ã—ã¦ã„ãªã‹ã£ãŸã®ã‚’修正。ã‚ã‚ŠãŒã¨ã†ã€åˆ€ç¥¢ã•ã‚“}
+% \begin{macrocode}
+\DeclareOption{mentuke}{%
+ \tombowtrue \tombowdatefalse
+ \setlength{\@tombowwidth}{\z@}%
+ \maketombowbox}
+% \end{macrocode}
+%
+% \subsection{組方å‘オプション}
+% ã“ã®ã‚ªãƒ—ションãŒæŒ‡å®šã•ã‚Œã‚‹ã¨ã€ç¸¦çµ„ã§çµ„版をã—ã¾ã™ã€‚
+% \changes{v1.0g}{1997/01/25}{Insert \cs{hbox}, to switch tate-mode.}
+% \changes{v1.1d}{1997/02/05}{開始ページãŒãŠã‹ã—ããªã‚‹ã®ã‚’修正}
+% \changes{v1.1f}{1997/07/08}{縦組時ã«ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ãŒãŠã‹ã—ããªã‚‹ã®ã‚’修正}
+%
+% \changes{v1.6-ltj-4}{2014/06/30}{本文ã®çµ„æ–¹å‘ã‚’ \cs{AtBeginDocument} ã§
+% 変更ã™ã‚‹ã“ã¨ãŒã§ããªããªã£ãŸã“ã¨ã«å¯¾å¿œ}
+% \begin{macrocode}
+\DeclareOption{tate}{%
+ \tate\AtBeginDocument{\message{《縦組モード》}\adjustbaseline}%
+}
+% \end{macrocode}
+%
+% 縦組クラスã¨|everyshi|パッケージã®ç›¸æ€§ãŒæ‚ªã„å•é¡Œã«å¯¾å‡¦ã—ã¾ã™ã€‚
+% ã“ã®å‡¦ç†ã¯ã€ZRã•ã‚“ã®|pxeveryshi|パッケージã¨å®Ÿè³ªçš„ã«åŒã˜å†…容ã§ã™ã€‚
+% \begin{macrocode}
+%<*tate>
+\AtEndOfPackageFile{everyshi}{%
+ \def\@EveryShipout@Output{%
+ \setbox8\vbox{%
+ \yoko
+ \@EveryShipout@Hook
+ \@EveryShipout@AtNextHook
+ \global\setbox\luatexoutputbox=\box\luatexoutputbox
+ }%
+ \gdef\@EveryShipout@AtNextHook{}%
+ \@EveryShipout@Org@Shipout\box\luatexoutputbox
+ }}
+%</tate>
+% \end{macrocode}
+%
+% \subsection{両é¢ã€ç‰‡é¢ã‚ªãƒ—ション}
+% twosideオプションãŒæŒ‡å®šã•ã‚Œã‚‹ã¨ã€ä¸¡é¢å°å­—出力ã«é©ã—ãŸæ•´å½¢ã‚’è¡Œãªã„ã¾ã™ã€‚
+% \begin{macrocode}
+\DeclareOption{oneside}{\@twosidefalse}
+\DeclareOption{twoside}{\@twosidetrue}
+% \end{macrocode}
+%
+% \subsection{二段組オプション}
+% 二段組ã«ã™ã‚‹ã‹ã©ã†ã‹ã®ã‚ªãƒ—ションã§ã™ã€‚
+% \begin{macrocode}
+\DeclareOption{onecolumn}{\@twocolumnfalse}
+\DeclareOption{twocolumn}{\@twocolumntrue}
+% \end{macrocode}
+%
+% \subsection{表題ページオプション}
+% |@titlepage|ãŒçœŸã®å ´åˆã€è¡¨é¡Œã‚’独立ã—ãŸãƒšãƒ¼ã‚¸ã«å‡ºåŠ›ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\DeclareOption{titlepage}{\@titlepagetrue}
+\DeclareOption{notitlepage}{\@titlepagefalse}
+% \end{macrocode}
+%
+% \subsection{å³å·¦èµ·ã“ã—オプション}
+% chapterã‚’å³ãƒšãƒ¼ã‚¸ã‚ã‚‹ã„ã¯å·¦ãƒšãƒ¼ã‚¸ã‹ã‚‰
+% ã¯ã˜ã‚ã‚‹ã‹ã©ã†ã‹ã‚’指定ã™ã‚‹ã‚ªãƒ—ションã§ã™ã€‚
+% |openleft|オプションã¯æ—¥æœ¬èªž\TeX{}開発コミュニティã«ã‚ˆã£ã¦è¿½åŠ ã•ã‚Œã¾ã—ãŸã€‚
+% \changes{v1.7d}{2017/02/15}{openleftオプション追加}
+% \begin{macrocode}
+%<!article>\if@compatibility
+%<book>\@openrighttrue
+%<!article>\else
+%<!article>\DeclareOption{openright}{\@openrighttrue\@openleftfalse}
+%<!article>\DeclareOption{openleft}{\@openlefttrue\@openrightfalse}
+%<!article>\DeclareOption{openany}{\@openrightfalse\@openleftfalse}
+%<!article>\fi
+% \end{macrocode}
+%
+% \subsection{æ•°å¼ã®ã‚ªãƒ—ション}
+% \Lopt{leqno}を指定ã™ã‚‹ã¨ã€æ•°å¼ç•ªå·ã‚’æ•°å¼ã®å·¦å´ã«å‡ºåŠ›ã—ã¾ã™ã€‚
+% \Lopt{fleqn}を指定ã™ã‚‹ã¨ãƒ‡ã‚£ã‚¹ãƒ—レイ数å¼ã‚’å·¦æƒãˆã§å‡ºåŠ›ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\DeclareOption{leqno}{\input{leqno.clo}}
+\DeclareOption{fleqn}{\input{fleqn.clo}}
+% \end{macrocode}
+%
+% \subsection{å‚考文献ã®ã‚ªãƒ—ション}
+% å‚考文献一覧を``オープンスタイル''ã®æ›¸å¼ã§å‡ºåŠ›ã—ã¾ã™ã€‚
+% ã“ã‚Œã¯å„ブロックãŒæ”¹è¡Œã§åŒºåˆ‡ã‚‰ã‚Œã€|\bibindent|ã®ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆãŒä»˜ã書å¼ã§ã™ã€‚
+% \changes{v1.0c}{1995/12/25}{openbibオプションをå†å®Ÿè£…}
+% \begin{macrocode}
+\DeclareOption{openbib}{%
+% \end{macrocode}
+% å‚考文献環境内ã®æœ€åˆã®ã„ãã¤ã‹ã®ãƒ•ãƒƒã‚¯ã‚’満ãŸã—ã¾ã™ã€‚
+% \begin{macrocode}
+ \AtEndOfPackage{%
+ \renewcommand\@openbib@code{%
+ \advance\leftmargin\bibindent
+ \itemindent -\bibindent
+ \listparindent \itemindent
+ \parsep \z@
+ }%
+% \end{macrocode}
+% ãã—ã¦ã€|\newblock|ã‚’å†å®šç¾©ã—ã¾ã™ã€‚
+% \begin{macrocode}
+ \renewcommand\newblock{\par}}}
+% \end{macrocode}
+%
+% \subsection{日本語ファミリ宣言ã®æŠ‘制ã€å’Œæ¬§æ–‡ä¸¡å¯¾å¿œã®æ•°å¼æ–‡å­—}
+% p\TeX ã§ã¯æ•°å¼ãƒ•ã‚¡ãƒŸãƒªã®æ•°ãŒ16個ã ã£ãŸã®ã§æ—¥æœ¬èªžãƒ•ã‚¡ãƒŸãƒªå®£è¨€ã‚’抑制ã™ã‚‹
+% |disablejfam|オプションãŒç”¨æ„ã•ã‚Œã¦ã„ã¾ã—ãŸãŒã€Lua\TeX ã§ã¯Omegaæ‹¡å¼µãŒ
+% å–ã‚Šè¾¼ã¾ã‚Œã¦æ•°å¼ãƒ•ã‚¡ãƒŸãƒªã¯256個ã¾ã§ä½¿ç”¨ã§ãã‚‹ãŸã‚ã€ã“ã®ã‚ªãƒ—ションã¯å¿…è¦ã‚ã‚Šã¾ã›ã‚“。
+% ãŸã ã—ã€\LaTeXe カーãƒãƒ«ã§ã¯æœªã ã«æ•°å¼ãƒ•ã‚¡ãƒŸãƒªã®æ•°ã¯16個ã«åˆ¶é™ã•ã‚Œã¦ã„ã‚‹ã®ã§ã€
+% 実際ã«ä½¿ç”¨å¯èƒ½ãªæ•°å¼ãƒ•ã‚¡ãƒŸãƒªã®æ•°ã‚’増やã™ãŸã‚ã«ã¯|lualatex-math|パッケージを
+% 読ã¿è¾¼ã‚€å¿…è¦ãŒã‚ã‚‹ã“ã¨ã«æ³¨æ„ãŒå¿…è¦ã§ã™ã€‚
+%
+% |mathrmmc|オプションã¯ã€
+% |\mathrm|ã¨|\mathbf|を和欧文両対応ã«ã™ã‚‹ãŸã‚ã®ã‚¯ãƒ©ã‚¹ã‚ªãƒ—ションã§ã™ã€‚
+% \changes{v1.1d}{1992/02/04}{disablejfamã®åˆ¤æ–­ã‚’é–“é•ãˆã¦ãŸã®ã‚’修正}
+% \changes{v1.8-ltj-16}{2018/10/08}{Lua\TeX-ja本体ãŒï¼Œä¸»ã«ãƒ¡ãƒ¢ãƒªæ¶ˆè²»ã‚’抑ãˆã‚‹ç›®çš„ã§
+% |disablejfam|オプションをサãƒãƒ¼ãƒˆã—ã¾ã—ãŸã€‚ãã®ãŸã‚以å‰å‡ºã—ã¦ã„ãŸè­¦å‘Šã¯å‰Šé™¤ã—ã¾ã™ã€‚}
+% \begin{macrocode}
+\if@compatibility
+ \@mathrmmctrue
+\else
+ \DeclareOption{mathrmmc}{\@mathrmmctrue}
+\fi
+% \end{macrocode}
+%
+%
+% \subsection{ドラフトオプション}
+% |draft|オプションを指定ã™ã‚‹ã¨ã€ã‚ªãƒ¼ãƒãƒ•ãƒ«ãƒœãƒƒã‚¯ã‚¹ã®èµ·ããŸç®‡æ‰€ã«ã€
+% 5ptã®ç½«ç·šãŒå¼•ã‹ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+\DeclareOption{draft}{\setlength\overfullrule{5pt}}
+\DeclareOption{final}{\setlength\overfullrule{0pt}}
+%</article|report|book>
+% \end{macrocode}
+%
+% \subsection{フォントメトリックã®å¤‰æ›´}
+%
+% Lua\LaTeX-jaã®æ¨™æº–ã§ã¯ã€OTFパッケージ由æ¥ã®ãƒ¡ãƒˆãƒªãƒƒã‚¯ãŒä½¿ã‚れるよã†ã«ãªã£ã¦ã„ã¾ã™ã€‚
+% 本クラスã§ã¯ã€ã€Œp\TeX ã®çµ„版ã¨äº’æ›æ€§ã‚’ã§ãã‚‹ã ã‘æŒãŸã›ã‚‹ã€ä¾‹ã‚’æ示ã™ã‚‹ãŸã‚ã€
+% \begin{itemize}
+% \item メトリックを\texttt{min10.tfm}ベースã®\texttt{jfm-min.lua}ã«å¤‰æ›´ã€‚
+% \item 明æœã¨ã‚´ã‚·ãƒƒã‚¯ã¯ä¸¡æ–¹ã¨ã‚‚\texttt{jfm-min.lua}を用ã„ã‚‹ãŒã€
+% 和文処ç†ç”¨ã‚°ãƒ«ãƒ¼æŒ¿å…¥æ™‚ã«ã¯ã€Œé•ã†ãƒ¡ãƒˆãƒªãƒƒã‚¯ã‚’使用ã€ã¨ã—ã¦æ€ã‚ã›ã‚‹ã€‚
+% \item p\TeX ã¨åŒæ§˜ã«ã€ã€Œç•°ãªã‚‹ãƒ¡ãƒˆãƒªãƒƒã‚¯ã®2ã¤ã®å’Œæ–‡æ–‡å­—ã€ã®é–“ã«ã¯ã€ä¸¡è€…ã‹ã‚‰å®šã‚ã‚‹
+% グルーを両方挿入ã™ã‚‹ã€‚
+% \item calllbackを利用ã—ã€æ¨™æº–ã§ç”¨ã„ã‚‹\texttt{jfm-min.lua}ã‚’ã€æ®µè½å§‹ã‚ã®æ‹¬å¼§ãŒå…¨è§’二分下ãŒã‚Šã«ãªã‚‹ã‚ˆã†ã«å†…部ã§å¤‰æ›´ã—ã¦ã„る。
+%
+% \end{itemize}
+%
+% |\ltj@stdmcfont|,~|\ltj@stdgtfont| ã«ã‚ˆã‚‹ã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ä½¿ã‚れ明æœãƒ»ã‚´ã‚·ãƒƒã‚¯ã®ãƒ•ã‚©ãƒ³ãƒˆã®
+% 設定ã«å¯¾å¿œã—ã¾ã—ãŸã€‚ã“ã®2ã¤ã®å‘½ä»¤ã®å€¤ã¯ãƒ¦ãƒ¼ã‚¶ãŒæ—¥ã€…ã®åˆ©ç”¨ã§ãã®éƒ½åº¦æŒ‡å®šã™ã‚‹ã‚‚ã®ã§ã¯ãªãã€
+% 何らã‹ã®ç†ç”±ã§éžåŸ‹ã‚è¾¼ã¿ãƒ•ã‚©ãƒ³ãƒˆãŒæ­£ã—ã利用ã§ããªã„å ´åˆã«ã®ã¿ |luatexja.cfg| ã«ã‚ˆã£ã¦
+% セットã•ã‚Œã‚‹ã‚‚ã®ã§ã™ã€‚
+%
+% \changes{v1.6-ltj-9}{2015/01/01}{サイズクラスã®ãƒ­ãƒ¼ãƒ‰å‰ã«ãƒ¡ãƒˆãƒªãƒƒã‚¯ã®å¤‰æ›´ã‚’è¡Œã‚ãªã„ã¨ï¼Œ
+% \cs{Cht}ç­‰ã®å€¤ãŒå映ã•ã‚Œãªã„ã®ã§ã“ã®å ´æ‰€ã«ç§»å‹•ã•ã›ã¾ã—ãŸï¼Ž}
+%
+% \begin{macrocode}
+%<*article|report|book>
+\directlua{luatexbase.add_to_callback('luatexja.load_jfm',
+ function (ji, jn) ji.chars['parbdd'] = 0; return ji end,
+ 'ltj.jclasses_load_jfm', 1)}
+{\jfont\g=\ltj@stdmcfont:jfm=min } % loading jfm-min.lua
+\expandafter\let\csname JY3/mc/m/n/10\endcsname\relax
+\DeclareFontShape{JY3}{mc}{m}{n}{<-> s * [0.962216] \ltj@stdmcfont:jfm=min}{}
+\DeclareFontShape{JY3}{gt}{m}{n}{<-> s * [0.962216] \ltj@stdgtfont:jfm=min;jfmvar=goth}{}
+\ltjglobalsetparameter{differentjfm=both}
+\directlua{luatexbase.remove_from_callback('luatexja.load_jfm', 'ltj.jclasses_load_jfm')}
+%</article|report|book>
+% \end{macrocode}
+%
+% \subsection{disablejfamオプション}
+% \changes{v1.8b-ltj-17}{2019/08/12}{disablejfamã®``Unused global option(s)''警告を出ã•ãªã„よã†ã«ã—ãŸ}
+% disablejfamオプションã¯Lua\TeX-ja本体ã§å‡¦ç†ã—ã¾ã™ãŒï¼Œ
+% ã‚‚ã†Lua\TeX-jaã¯èª­ã¿è¾¼ã‚“ã§ã„ã‚‹ãŸã‚,ã“ã®ã¾ã¾ã§ã¯``Unused global option(s): [disablejfam]''警告ãŒ
+% 出ã¦ã—ã¾ã„ã¾ã™ï¼Žãã®ãŸã‚,「何もã—ãªã„ã€disablejfamオプションをクラス内ã§å®šç¾©ã—ã¦ãŠãã¾ã™ï¼Ž
+%
+% \begin{macrocode}
+%<*article|report|book>
+\DeclareOption{disablejfam}{}
+%</article|report|book>
+% \end{macrocode}
+%
+% \subsection{オプションã®å®Ÿè¡Œ}
+% オプションã®å®Ÿè¡Œã€ãŠã‚ˆã³ã‚µã‚¤ã‚ºã‚¯ãƒ©ã‚¹ã®ãƒ­ãƒ¼ãƒ‰ã‚’è¡Œãªã„ã¾ã™ã€‚
+% \begin{macrocode}
+%<*article|report|book>
+%<*article>
+%<tate>\ExecuteOptions{a4paper,10pt,oneside,onecolumn,final,tate}
+%<yoko>\ExecuteOptions{a4paper,10pt,oneside,onecolumn,final}
+%</article>
+%<*report>
+%<tate>\ExecuteOptions{a4paper,10pt,oneside,onecolumn,final,openany,tate}
+%<yoko>\ExecuteOptions{a4paper,10pt,oneside,onecolumn,final,openany}
+%</report>
+%<*book>
+%<tate>\ExecuteOptions{a4paper,10pt,twoside,onecolumn,final,openright,tate}
+%<yoko>\ExecuteOptions{a4paper,10pt,twoside,onecolumn,final,openright}
+%</book>
+\ProcessOptions\relax
+%<book&tate>\input{ltjtbk1\@ptsize.clo}
+%<!book&tate>\input{ltjtsize1\@ptsize.clo}
+%<book&yoko>\input{ltjbk1\@ptsize.clo}
+%<!book&yoko>\input{ltjsize1\@ptsize.clo}
+% \end{macrocode}
+% 縦組用クラスファイルã®å ´åˆã¯ã€ã“ã“ã§\file{plext.sty}も読ã¿è¾¼ã¿ã¾ã™ã€‚
+% \changes{v1.0e}{1996/03/21}{\cs{usepackage} to \cs{RequirePackage}}
+% \changes{v1.6-ltj-6}{2014/07/28}{Lua\TeX-jaã§ã¯ï¼Œä»£ã‚ã‚Šã«\file{lltjext.sty}を読ã¿è¾¼ã¿ã¾
+% ã™ï¼Žã“ã‚Œã¯\file{plext.sty}ã‚’Lua\TeX-ja用ã«æ›¸ããªãŠã—ãŸã‚‚ã®ã§ã™ï¼Ž}
+% \begin{macrocode}
+%<tate>\RequirePackage{lltjext}
+%</article|report|book>
+% \end{macrocode}
+%
+% \section{フォント}
+%
+% ã“ã“ã§ã¯ã€\LaTeX{}ã®ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã‚³ãƒžãƒ³ãƒ‰ã®å®šç¾©ã‚’ã—ã¦ã„ã¾ã™ã€‚
+% フォントサイズコマンドã®å®šç¾©ã¯ã€æ¬¡ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’用ã„ã¾ã™ã€‚
+%
+% |\@setfontsize||\size|\meta{font-size}\meta{baselineskip}
+%
+% \begin{description}
+% \item[\meta{font-size}] ã“ã‚Œã‹ã‚‰ä½¿ç”¨ã™ã‚‹ã€ãƒ•ã‚©ãƒ³ãƒˆã®å®Ÿéš›ã®å¤§ãã•ã§ã™ã€‚
+% \item[\meta{baselineskip}] é¸æŠžã•ã‚Œã‚‹ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºç”¨ã®é€šå¸¸ã®
+% |\baselineskip|ã®å€¤ã§ã™ï¼ˆå®Ÿéš›ã¯ã€|\baselinestretch| * \meta{baselineskip}
+% ã®å€¤ã§ã™ï¼‰ã€‚
+% \end{description}
+%
+% 数値コマンドã¯ã€æ¬¡ã®ã‚ˆã†ã«\LaTeX{}カーãƒãƒ«ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% \begin{center}
+% \begin{tabular}{ll@{\qquad}ll@{\qquad}ll}
+% \verb=\@vpt= & 5 & \verb=\@vipt= & 6 & \verb=\@viipt= & 7 \\
+% \verb=\@viiipt= & 8 & \verb=\@ixpt= & 9 & \verb=\@xpt= & 10 \\
+% \verb=\@xipt= & 10.95 & \verb=\@xiipt= & 12 & \verb=\@xivpt= & 14.4\\
+% ...
+% \end{tabular}
+% \end{center}
+%
+% \begin{macro}{\normalsize}
+% \begin{macro}{\@normalsize}
+% 基本サイズã¨ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ãƒ¬ãƒ™ãƒ«ã®ã‚³ãƒžãƒ³ãƒ‰ã¯|\normalsize|ã§ã™ã€‚
+% \LaTeX{}ã®å†…部ã§ã¯|\@normalsize|を使用ã—ã¾ã™ã€‚
+%
+% |\normalsize|マクロã¯ã€|\abovedisplayskip|ã¨
+% |\abovedisplayshortskip|ã€ãŠã‚ˆã³|\belowdisplayshortskip|ã®å€¤ã‚‚設定をã—ã¾ã™ã€‚
+% |\belowdisplayskip|ã¯ã€ã¤ã­ã«|\abovedisplayskip|ã¨åŒå€¤ã§ã™ã€‚
+%
+% ã¾ãŸã€ãƒªã‚¹ãƒˆç’°å¢ƒã®ãƒˆãƒƒãƒ—レベルã®ãƒ‘ラメータã¯ã€ã¤ã­ã«|\@listI|ã§ä¸Žãˆã‚‰ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+%<*10pt|11pt|12pt>
+\renewcommand{\normalsize}{%
+%<10pt&yoko> \@setfontsize\normalsize\@xpt{15}%
+%<11pt&yoko> \@setfontsize\normalsize\@xipt{15.5}%
+%<12pt&yoko> \@setfontsize\normalsize\@xiipt{16.5}%
+%<10pt&tate> \@setfontsize\normalsize\@xpt{17}%
+%<11pt&tate> \@setfontsize\normalsize\@xipt{17}%
+%<12pt&tate> \@setfontsize\normalsize\@xiipt{18}%
+%<*10pt>
+ \abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@
+ \abovedisplayshortskip \z@ \@plus3\p@
+ \belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@
+%</10pt>
+%<*11pt>
+ \abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@
+ \abovedisplayshortskip \z@ \@plus3\p@
+ \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
+%</11pt>
+%<*12pt>
+ \abovedisplayskip 12\p@ \@plus3\p@ \@minus7\p@
+ \abovedisplayshortskip \z@ \@plus3\p@
+ \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
+%</12pt>
+ \belowdisplayskip \abovedisplayskip
+ \let\@listi\@listI}
+% \end{macrocode}
+%
+% ã“ã“ã§ã€ãƒŽãƒ¼ãƒžãƒ«ãƒ•ã‚©ãƒ³ãƒˆã‚’é¸æŠžã—ã€åˆæœŸåŒ–ã‚’ã—ã¾ã™ã€‚
+% ã“ã®ã¨ãã€ç¸¦çµ„モードãªã‚‰ã°ã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã‚’変更ã—ã¾ã™ã€‚
+% \begin{macrocode}
+%<tate>\def\kanjiencodingdefault{JT3}%
+%<tate>\kanjiencoding{\kanjiencodingdefault}%
+\normalsize
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\Cht}
+% \begin{macro}{\Cdp}
+% \begin{macro}{\Cwd}
+% \begin{macro}{\Cvs}
+% \begin{macro}{\Chs}
+% 基準ã¨ãªã‚‹é•·ã•ã®è¨­å®šã‚’ã—ã¾ã™ã€‚ã“れらã®ãƒ‘ラメータã¯\file{lltjfont.sty}ã§å®šç¾©
+% ã•ã‚Œã¦ã„ã¾ã™ã€‚基準ã¨ã™ã‚‹æ–‡å­—を「全角空白ã€ï¼ˆEUCコード\texttt{0xA1A1})ã‹ã‚‰
+% 「漢ã€ï¼ˆJISコード\texttt{0x3441})ã¸å¤‰æ›´ã—ã¾ã—ãŸã€‚
+% \changes{v1.7f}{2017/08/31}{和文書体ã®åŸºæº–を全角空白ã‹ã‚‰ã€Œæ¼¢ã€ã«å¤‰æ›´}
+% \changes{v1.7g}{2017/09/19}{内部処ç†ã§ä½¿ã£ãŸãƒœãƒƒã‚¯ã‚¹0を空ã«ã—ãŸ}
+% \begin{macrocode}
+\setbox0\hbox{æ¼¢}
+\setlength\Cht{\ht0}
+\setlength\Cdp{\dp0}
+\setlength\Cwd{\wd0}
+\setlength\Cvs{\baselineskip}
+\setlength\Chs{\wd0}
+\setbox0=\box\voidb@x
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\small}
+% |\small|コマンドã®å®šç¾©ã¯ã€|\normalsize|ã«ä¼¼ã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+\newcommand{\small}{%
+%<*10pt>
+ \@setfontsize\small\@ixpt{11}%
+ \abovedisplayskip 8.5\p@ \@plus3\p@ \@minus4\p@
+ \abovedisplayshortskip \z@ \@plus2\p@
+ \belowdisplayshortskip 4\p@ \@plus2\p@ \@minus2\p@
+ \def\@listi{\leftmargin\leftmargini
+ \topsep 4\p@ \@plus2\p@ \@minus2\p@
+ \parsep 2\p@ \@plus\p@ \@minus\p@
+ \itemsep \parsep}%
+%</10pt>
+%<*11pt>
+ \@setfontsize\small\@xpt\@xiipt
+ \abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@
+ \abovedisplayshortskip \z@ \@plus3\p@
+ \belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@
+ \def\@listi{\leftmargin\leftmargini
+ \topsep 6\p@ \@plus2\p@ \@minus2\p@
+ \parsep 3\p@ \@plus2\p@ \@minus\p@
+ \itemsep \parsep}%
+%</11pt>
+%<*12pt>
+ \@setfontsize\small\@xipt{13.6}%
+ \abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@
+ \abovedisplayshortskip \z@ \@plus3\p@
+ \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
+ \def\@listi{\leftmargin\leftmargini
+ \topsep 9\p@ \@plus3\p@ \@minus5\p@
+ \parsep 4.5\p@ \@plus2\p@ \@minus\p@
+ \itemsep \parsep}%
+%</12pt>
+ \belowdisplayskip \abovedisplayskip}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\footnotesize}
+% |\footnotesize|コマンドã®å®šç¾©ã¯ã€|\normalsize|ã«ä¼¼ã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+\newcommand{\footnotesize}{%
+%<*10pt>
+ \@setfontsize\footnotesize\@viiipt{9.5}%
+ \abovedisplayskip 6\p@ \@plus2\p@ \@minus4\p@
+ \abovedisplayshortskip \z@ \@plus\p@
+ \belowdisplayshortskip 3\p@ \@plus\p@ \@minus2\p@
+ \def\@listi{\leftmargin\leftmargini
+ \topsep 3\p@ \@plus\p@ \@minus\p@
+ \parsep 2\p@ \@plus\p@ \@minus\p@
+ \itemsep \parsep}%
+%</10pt>
+%<*11pt>
+ \@setfontsize\footnotesize\@ixpt{11}%
+ \abovedisplayskip 8\p@ \@plus2\p@ \@minus4\p@
+ \abovedisplayshortskip \z@ \@plus\p@
+ \belowdisplayshortskip 4\p@ \@plus2\p@ \@minus2\p@
+ \def\@listi{\leftmargin\leftmargini
+ \topsep 4\p@ \@plus2\p@ \@minus2\p@
+ \parsep 2\p@ \@plus\p@ \@minus\p@
+ \itemsep \parsep}%
+%</11pt>
+%<*12pt>
+ \@setfontsize\footnotesize\@xpt\@xiipt
+ \abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@
+ \abovedisplayshortskip \z@ \@plus3\p@
+ \belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@
+ \def\@listi{\leftmargin\leftmargini
+ \topsep 6\p@ \@plus2\p@ \@minus2\p@
+ \parsep 3\p@ \@plus2\p@ \@minus\p@
+ \itemsep \parsep}%
+%</12pt>
+ \belowdisplayskip \abovedisplayskip}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\scriptsize}
+% \begin{macro}{\tiny}
+% \begin{macro}{\large}
+% \begin{macro}{\Large}
+% \begin{macro}{\LARGE}
+% \begin{macro}{\huge}
+% \begin{macro}{\Huge}
+% ã“れらã¯å…ˆã»ã©ã®ãƒžã‚¯ãƒ­ã‚ˆã‚Šã‚‚ç°¡å˜ã§ã™ã€‚ã“れらã¯ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã‚’変更ã™ã‚‹
+% ã ã‘ã§ã€ãƒªã‚¹ãƒˆç’°å¢ƒã¨ãƒ‡ã‚£ã‚¹ãƒ—レイ数å¼ã®ãƒ‘ラメータã¯å¤‰æ›´ã—ã¾ã›ã‚“。
+% \begin{macrocode}
+%<*10pt>
+\newcommand{\scriptsize}{\@setfontsize\scriptsize\@viipt\@viiipt}
+\newcommand{\tiny}{\@setfontsize\tiny\@vpt\@vipt}
+\newcommand{\large}{\@setfontsize\large\@xiipt{17}}
+\newcommand{\Large}{\@setfontsize\Large\@xivpt{21}}
+\newcommand{\LARGE}{\@setfontsize\LARGE\@xviipt{25}}
+\newcommand{\huge}{\@setfontsize\huge\@xxpt{28}}
+\newcommand{\Huge}{\@setfontsize\Huge\@xxvpt{33}}
+%</10pt>
+%<*11pt>
+\newcommand{\scriptsize}{\@setfontsize\scriptsize\@viiipt{9.5}}
+\newcommand{\tiny}{\@setfontsize\tiny\@vipt\@viipt}
+\newcommand{\large}{\@setfontsize\large\@xiipt{17}}
+\newcommand{\Large}{\@setfontsize\Large\@xivpt{21}}
+\newcommand{\LARGE}{\@setfontsize\LARGE\@xviipt{25}}
+\newcommand{\huge}{\@setfontsize\huge\@xxpt{28}}
+\newcommand{\Huge}{\@setfontsize\Huge\@xxvpt{33}}
+%</11pt>
+%<*12pt>
+\newcommand{\scriptsize}{\@setfontsize\scriptsize\@viiipt{9.5}}
+\newcommand{\tiny}{\@setfontsize\tiny\@vipt\@viipt}
+\newcommand{\large}{\@setfontsize\large\@xivpt{21}}
+\newcommand{\Large}{\@setfontsize\Large\@xviipt{25}}
+\newcommand{\LARGE}{\@setfontsize\LARGE\@xxpt{28}}
+\newcommand{\huge}{\@setfontsize\huge\@xxvpt{33}}
+\let\Huge=\huge
+%</12pt>
+%</10pt|11pt|12pt>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\Cjascale}
+% ã“ã®ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ„図ã™ã‚‹å’Œæ–‡ã‚¹ã‚±ãƒ¼ãƒ«å€¤
+% ($1\,\mathrm{zw} \div \textmc{è¦æ±‚サイズ}$)を
+% 表ã™å®Ÿæ•°å€¤ãƒžã‚¯ãƒ­|\Cjascale|を定義ã—ã¾ã™ã€‚
+% ã“ã®\texttt{jclasses}互æ›ã‚¯ãƒ©ã‚¹ã§ã¯ã€Lua\TeX-ja読ã¿è¾¼ã¿æ™‚ã®å’Œæ–‡ã‚¹ã‚±ãƒ¼ãƒ«å€¤ãŒãã®ã¾ã¾
+% 使用ã•ã‚Œã€ãã®å€¤ã¯0.962216ã§ã™ã€‚
+% \changes{v1.7h}{2018/02/04}{和文スケール値\cs{Cjascale}を定義}
+% \begin{macrocode}
+%<*article|report|book>
+\def\Cjascale{0.962216}
+%</article|report|book>
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \section{レイアウト}
+%
+% \subsection{用紙サイズã®æ±ºå®š}
+%
+% \begin{macro}{\columnsep}
+% \begin{macro}{\columnseprule}
+% |\columnsep|ã¯ã€äºŒæ®µçµ„ã®ã¨ãã®ã€å·¦å³ï¼ˆã‚ã‚‹ã„ã¯ä¸Šä¸‹ï¼‰ã®æ®µé–“ã®å¹…ã§ã™ã€‚
+% ã“ã®ã‚¹ãƒšãƒ¼ã‚¹ã®ä¸­å¤®ã«|\columnseprule|ã®å¹…ã®ç½«ç·šãŒå¼•ã‹ã‚Œã¾ã™ã€‚
+% \changes{v1.0g}{1997/01/25}{\cs{columnsep}: 10pt to 3\cs{Cwd} or 2\cs{Cwd}.}
+% \begin{macrocode}
+%<*article|report|book>
+\if@stysize
+%<tate> \setlength\columnsep{3\Cwd}
+%<yoko> \setlength\columnsep{2\Cwd}
+\else
+ \setlength\columnsep{10\p@}
+\fi
+\setlength\columnseprule{0\p@}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\pagewidth}
+% \begin{macro}{\pageheight}
+% \begin{macro}{\stockwidth}
+% \begin{macro}{\stockheight}
+% 出力ã®PDFã®ç”¨ç´™ã‚µã‚¤ã‚ºã‚’ã“ã“ã§è¨­å®šã—ã¦ãŠãã¾ã™ã€‚
+% |tombow|ãŒçœŸã®ã¨ãã¯2インãƒè¶³ã—ã¦ãŠãã¾ã™ã€‚
+%
+% [2015-10-18 LTJ] Lua\TeX\ 0.81.0ã§ã¯ãƒ—リミティブã®å称変更ãŒã•ã‚ŒãŸã®ã§ï¼Œ
+% ãã‚Œã«åˆã‚ã›ã¦ãŠãã¾ã™ï¼Ž
+%
+% [2016-07-19 LTJ] luatex.defãŒæ–°ã—ããªã£ãŸã“ã¨ã«å¯¾å¿œã™ã‚‹aminophenã•ã‚“ã®ãƒ‘ッãƒã‚’å–ã‚Šè¾¼ã¿ã¾ã—ãŸã€‚
+%
+% [2017-01-17 LTJ] [lt]jsclassesã«åˆã‚ã›ï¼Œãƒˆãƒ³ãƒœã‚ªãƒ—ションãŒæŒ‡å®šã•ã‚Œã¦ã„ã‚‹ã¨ã「ã ã‘ã€|\stockwidth|,
+% |\stockheight|を定義ã™ã‚‹ã‚ˆã†ã«ã—ã¾ã—ãŸã€‚aminophenã•ã‚“,ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ï¼Ž
+%
+% \begin{macrocode}
+\iftombow
+ \newlength{\stockwidth}
+ \newlength{\stockheight}
+ \setlength{\stockwidth}{\paperwidth}
+ \setlength{\stockheight}{\paperheight}
+ \advance \stockwidth 2in
+ \advance \stockheight 2in
+ \ifdefined\pdfpagewidth
+ \setlength{\pdfpagewidth}{\stockwidth}
+ \setlength{\pdfpageheight}{\stockheight}
+ \else
+ \setlength{\pagewidth}{\stockwidth}
+ \setlength{\pageheight}{\stockheight}
+ \fi
+\else
+ \ifdefined\pdfpagewidth
+ \setlength{\pdfpagewidth}{\paperwidth}
+ \setlength{\pdfpageheight}{\paperheight}
+ \else
+ \setlength{\pagewidth}{\paperwidth}
+ \setlength{\pageheight}{\paperheight}
+ \fi
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{段è½ã®å½¢}
+%
+% \begin{macro}{\lineskip}
+% \begin{macro}{\normallineskip}
+% ã“れらã®å€¤ã¯ã€è¡ŒãŒè¿‘付ãéŽãŽãŸã¨ãã®\TeX ã®å‹•ä½œã‚’制御ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\setlength\lineskip{1\p@}
+\setlength\normallineskip{1\p@}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\baselinestretch}
+% ã“ã‚Œã¯ã€|\baselineskip|ã®å€çŽ‡ã‚’示ã™ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚
+% デフォルトã§ã¯ã€\emph{何もã—ã¾ã›ã‚“}。ã“ã®ã‚³ãƒžãƒ³ãƒ‰ãŒ``empty''ã§ãªã„å ´åˆã€
+% |\baselineskip|ã®æŒ‡å®šã®\texttt{plus}ã‚„\texttt{minus}部分ã¯ç„¡è¦–ã•ã‚Œã‚‹
+% ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。
+% \begin{macrocode}
+\renewcommand{\baselinestretch}{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\parskip}
+% \begin{macro}{\parindent}
+% |\parskip|ã¯æ®µè½é–“ã«æŒ¿å…¥ã•ã‚Œã‚‹ã€ç¸¦æ–¹å‘ã®è¿½åŠ ã‚¹ãƒšãƒ¼ã‚¹ã§ã™ã€‚
+% |\parindent|ã¯æ®µè½ã®å…ˆé ­ã®å­—下ã’å¹…ã§ã™ã€‚
+% \begin{macrocode}
+\setlength\parskip{0\p@ \@plus \p@}
+\setlength\parindent{1\Cwd}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\smallskipamount}
+% \begin{macro}{\medskipamount}
+% \begin{macro}{\bigskipamount}
+% ã“れら3ã¤ã®ãƒ‘ラメータã®å€¤ã¯ã€\LaTeX{}カーãƒãƒ«ã®ä¸­ã§è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚
+% ã“れらã¯ãŠãらãã€ã‚µã‚¤ã‚ºã‚ªãƒ—ションã®æŒ‡å®šã«ã‚ˆã£ã¦å¤‰ãˆã‚‹ã¹ãã§ã™ã€‚
+% ã—ã‹ã—ã€\LaTeX~2.09ã‚„\LaTeXe{}ã®ä»¥å‰ã®ãƒªãƒªãƒ¼ã‚¹ã®ä¸¡æ–¹ã¨ã®äº’æ›æ€§ã‚’ä¿ã¤ãŸã‚ã«ã€
+% ã“れらã¯ã¾ã åŒã˜å€¤ã¨ã—ã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+%<*10pt|11pt|12pt>
+\setlength\smallskipamount{3\p@ \@plus 1\p@ \@minus 1\p@}
+\setlength\medskipamount{6\p@ \@plus 2\p@ \@minus 2\p@}
+\setlength\bigskipamount{12\p@ \@plus 4\p@ \@minus 4\p@}
+%</10pt|11pt|12pt>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@lowpenalty}
+% \begin{macro}{\@medpenalty}
+% \begin{macro}{\@highpenalty}
+% |\nopagebreak|ã¨|\nolinebreak|コマンドã¯ã€ã“れらã®ã‚³ãƒžãƒ³ãƒ‰ãŒç½®ã‹ã‚ŒãŸå ´æ‰€ã«ã€
+% ペナルティを起ã„ã¦ã€åˆ†å‰²ã‚’制御ã—ã¾ã™ã€‚
+% ç½®ã‹ã‚Œã‚‹ãƒšãƒŠãƒ«ãƒ†ã‚£ã¯ã€ã‚³ãƒžãƒ³ãƒ‰ã®å¼•æ•°ã«ã‚ˆã£ã¦ã€
+% |\@lowpenalty|, |\@medpenalty|, |\@highpenalty|ã®ã„ãšã‚Œã‹ãŒä½¿ã‚ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+\@lowpenalty 51
+\@medpenalty 151
+\@highpenalty 301
+%</article|report|book>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{ページレイアウト}
+%
+% \subsubsection{縦方å‘ã®ã‚¹ãƒšãƒ¼ã‚¹}
+%
+% \begin{macro}{\headheight}
+% \begin{macro}{\headsep}
+% \begin{macro}{\topskip}
+% |\headheight|ã¯ã€ãƒ˜ãƒƒãƒ€ãŒå…¥ã‚‹ãƒœãƒƒã‚¯ã‚¹ã®é«˜ã•ã§ã™ã€‚
+% |\headsep|ã¯ã€ãƒ˜ãƒƒãƒ€ã®ä¸‹ç«¯ã¨æœ¬æ–‡é ˜åŸŸã¨ã®é–“ã®è·é›¢ã§ã™ã€‚
+% |\topskip|ã¯ã€æœ¬æ–‡é ˜åŸŸã®ä¸Šç«¯ã¨ï¼‘行目ã®ãƒ†ã‚­ã‚¹ãƒˆã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¨ã®è·é›¢ã§ã™ã€‚
+% \begin{macrocode}
+%<*10pt|11pt|12pt>
+\setlength\headheight{12\p@}
+%<*tate>
+\if@stysize
+ \ifnum\c@@paper=2 % A5
+ \setlength\headsep{6mm}
+ \else % A4, B4, B5 and other
+ \setlength\headsep{8mm}
+ \fi
+\else
+ \setlength\headsep{8mm}
+\fi
+%</tate>
+%<*yoko>
+%<!bk>\setlength\headsep{25\p@}
+%<10pt&bk>\setlength\headsep{.25in}
+%<11pt&bk>\setlength\headsep{.275in}
+%<12pt&bk>\setlength\headsep{.275in}
+%</yoko>
+\setlength\topskip{1\Cht}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\footskip}
+% |\footskip|ã¯ã€æœ¬æ–‡é ˜åŸŸã®ä¸‹ç«¯ã¨ãƒ•ãƒƒã‚¿ã®ä¸‹ç«¯ã¨ã®è·é›¢ã§ã™ã€‚
+% フッタã®ãƒœãƒƒã‚¯ã‚¹ã®é«˜ã•ã‚’示ã™ã€|\footheight|ã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚
+% \begin{macrocode}
+%<tate>\setlength\footskip{14mm}
+%<*yoko>
+%<!bk>\setlength\footskip{30\p@}
+%<10pt&bk>\setlength\footskip{.35in}
+%<11pt&bk>\setlength\footskip{.38in}
+%<12pt&bk>\setlength\footskip{30\p@}
+%</yoko>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\maxdepth}
+% \changes{v1.1c}{1995/12/25}{\cs{@maxdepth}ã®è¨­å®šã‚’除外ã—ãŸ}
+% \TeX ã®ãƒ—リミティブレジスタ|\maxdepth|ã¯ã€|\topskip|ã¨åŒã˜ã‚ˆã†ãª
+% åƒãã‚’ã—ã¾ã™ã€‚|\@maxdepth|レジスタã¯ã€ã¤ã­ã«|\maxdepth|ã®ã‚³ãƒ”ーã§ãªãã¦ã¯
+% ã„ã‘ã¾ã›ã‚“。ã“ã‚Œã¯|\begin{document}|ã®å†…部ã§è¨­å®šã•ã‚Œã¾ã™ã€‚
+% \TeX{}ã¨\LaTeX~2.09ã§ã¯ã€|\maxdepth|ã¯\texttt{4pt}ã«å›ºå®šã§ã™ã€‚
+% \LaTeXe{}ã§ã¯ã€|\maxdepth|$+$|\topskip|を基本サイズã®1.5å€ã«ã—ãŸã„ã®ã§ã€
+% |\maxdepth|ã‚’|\topskip|ã®åŠåˆ†ã®å€¤ã§è¨­å®šã—ã¾ã™ã€‚
+% \begin{macrocode}
+\if@compatibility
+ \setlength\maxdepth{4\p@}
+\else
+ \setlength\maxdepth{.5\topskip}
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{本文領域}
+% |\textheight|ã¨|\textwidth|ã¯ã€æœ¬æ–‡é ˜åŸŸã®é€šå¸¸ã®é«˜ã•ã¨å¹…を示ã—ã¾ã™ã€‚
+% 縦組ã§ã‚‚横組ã§ã‚‚ã€``高ã•''ã¯è¡Œæ•°ã‚’ã€``å¹…''ã¯å­—è©°ã‚ã‚’æ„味ã—ã¾ã™ã€‚
+% 後ã»ã©ã€ã“れらã®é•·ã•ã«|\topskip|ã®å€¤ãŒåŠ ãˆã‚‰ã‚Œã¾ã™ã€‚
+%
+% \begin{macro}{\textwidth}
+% 基本組ã®å­—è©°ã‚ã§ã™ã€‚
+%
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ã®å ´åˆï¼š
+% \begin{macrocode}
+\if@compatibility
+% \end{macrocode}
+% \changes{v1.1a}{1997/01/25}{Add paper option with compatibility mode.}
+% \changes{v1.1h}{1997/09/03}{landscapeã§ã®æŒ‡å®šã‚’追加}
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ï¼š|a4j|ã‚„|b5j|ã®ã‚¯ãƒ©ã‚¹ã‚ªãƒ—ションãŒæŒ‡å®šã•ã‚ŒãŸå ´åˆã®è¨­å®šï¼š
+% \begin{macrocode}
+ \if@stysize
+ \ifnum\c@@paper=2 % A5
+ \if@landscape
+%<10pt&yoko> \setlength\textwidth{47\Cwd}
+%<11pt&yoko> \setlength\textwidth{42\Cwd}
+%<12pt&yoko> \setlength\textwidth{40\Cwd}
+%<10pt&tate> \setlength\textwidth{27\Cwd}
+%<11pt&tate> \setlength\textwidth{25\Cwd}
+%<12pt&tate> \setlength\textwidth{23\Cwd}
+ \else
+%<10pt&yoko> \setlength\textwidth{28\Cwd}
+%<11pt&yoko> \setlength\textwidth{25\Cwd}
+%<12pt&yoko> \setlength\textwidth{24\Cwd}
+%<10pt&tate> \setlength\textwidth{46\Cwd}
+%<11pt&tate> \setlength\textwidth{42\Cwd}
+%<12pt&tate> \setlength\textwidth{38\Cwd}
+ \fi
+ \else\ifnum\c@@paper=3 % B4
+ \if@landscape
+%<10pt&yoko> \setlength\textwidth{75\Cwd}
+%<11pt&yoko> \setlength\textwidth{69\Cwd}
+%<12pt&yoko> \setlength\textwidth{63\Cwd}
+%<10pt&tate> \setlength\textwidth{53\Cwd}
+%<11pt&tate> \setlength\textwidth{49\Cwd}
+%<12pt&tate> \setlength\textwidth{44\Cwd}
+ \else
+%<10pt&yoko> \setlength\textwidth{60\Cwd}
+%<11pt&yoko> \setlength\textwidth{55\Cwd}
+%<12pt&yoko> \setlength\textwidth{50\Cwd}
+%<10pt&tate> \setlength\textwidth{85\Cwd}
+%<11pt&tate> \setlength\textwidth{76\Cwd}
+%<12pt&tate> \setlength\textwidth{69\Cwd}
+ \fi
+ \else\ifnum\c@@paper=4 % B5
+ \if@landscape
+%<10pt&yoko> \setlength\textwidth{60\Cwd}
+%<11pt&yoko> \setlength\textwidth{55\Cwd}
+%<12pt&yoko> \setlength\textwidth{50\Cwd}
+%<10pt&tate> \setlength\textwidth{34\Cwd}
+%<11pt&tate> \setlength\textwidth{31\Cwd}
+%<12pt&tate> \setlength\textwidth{28\Cwd}
+ \else
+%<10pt&yoko> \setlength\textwidth{37\Cwd}
+%<11pt&yoko> \setlength\textwidth{34\Cwd}
+%<12pt&yoko> \setlength\textwidth{31\Cwd}
+%<10pt&tate> \setlength\textwidth{55\Cwd}
+%<11pt&tate> \setlength\textwidth{51\Cwd}
+%<12pt&tate> \setlength\textwidth{47\Cwd}
+ \fi
+ \else % A4 ant other
+ \if@landscape
+%<10pt&yoko> \setlength\textwidth{73\Cwd}
+%<11pt&yoko> \setlength\textwidth{68\Cwd}
+%<12pt&yoko> \setlength\textwidth{61\Cwd}
+%<10pt&tate> \setlength\textwidth{41\Cwd}
+%<11pt&tate> \setlength\textwidth{38\Cwd}
+%<12pt&tate> \setlength\textwidth{35\Cwd}
+ \else
+%<10pt&yoko> \setlength\textwidth{47\Cwd}
+%<11pt&yoko> \setlength\textwidth{43\Cwd}
+%<12pt&yoko> \setlength\textwidth{40\Cwd}
+%<10pt&tate> \setlength\textwidth{67\Cwd}
+%<11pt&tate> \setlength\textwidth{61\Cwd}
+%<12pt&tate> \setlength\textwidth{57\Cwd}
+ \fi
+ \fi\fi\fi
+ \else
+% \end{macrocode}
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ï¼šãƒ‡ãƒ•ã‚©ãƒ«ãƒˆè¨­å®š
+% \begin{macrocode}
+ \if@twocolumn
+ \setlength\textwidth{52\Cwd}
+ \else
+%<10pt&!bk&yoko> \setlength\textwidth{327\p@}
+%<11pt&!bk&yoko> \setlength\textwidth{342\p@}
+%<12pt&!bk&yoko> \setlength\textwidth{372\p@}
+%<10pt&bk&yoko> \setlength\textwidth{4.3in}
+%<11pt&bk&yoko> \setlength\textwidth{4.8in}
+%<12pt&bk&yoko> \setlength\textwidth{4.8in}
+%<10pt&tate> \setlength\textwidth{67\Cwd}
+%<11pt&tate> \setlength\textwidth{61\Cwd}
+%<12pt&tate> \setlength\textwidth{57\Cwd}
+ \fi
+ \fi
+% \end{macrocode}
+% 2eモードã®å ´åˆï¼š
+% \begin{macrocode}
+\else
+% \end{macrocode}
+% 2eモード:|a4j|ã‚„|b5j|ã®ã‚¯ãƒ©ã‚¹ã‚ªãƒ—ションãŒæŒ‡å®šã•ã‚ŒãŸå ´åˆã®è¨­å®šï¼š
+% 二段組ã§ã¯ç”¨ç´™ã‚µã‚¤ã‚ºã®ï¼˜å‰²ã€ä¸€æ®µçµ„ã§ã¯ç”¨ç´™ã‚µã‚¤ã‚ºã®ï¼—割を版é¢ã®å¹…ã¨ã—ã¦
+% 設定ã—ã¾ã™ã€‚
+% \begin{macrocode}
+ \if@stysize
+ \if@twocolumn
+%<yoko> \setlength\textwidth{.8\paperwidth}
+%<tate> \setlength\textwidth{.8\paperheight}
+ \else
+%<yoko> \setlength\textwidth{.7\paperwidth}
+%<tate> \setlength\textwidth{.7\paperheight}
+ \fi
+ \else
+% \end{macrocode}
+% 2eモード:デフォルト設定
+% \begin{macrocode}
+%<tate> \setlength\@tempdima{\paperheight}
+%<yoko> \setlength\@tempdima{\paperwidth}
+ \addtolength\@tempdima{-2in}
+%<tate> \addtolength\@tempdima{-1.3in}
+%<yoko&10pt> \setlength\@tempdimb{327\p@}
+%<yoko&11pt> \setlength\@tempdimb{342\p@}
+%<yoko&12pt> \setlength\@tempdimb{372\p@}
+%<tate&10pt> \setlength\@tempdimb{67\Cwd}
+%<tate&11pt> \setlength\@tempdimb{61\Cwd}
+%<tate&12pt> \setlength\@tempdimb{57\Cwd}
+ \if@twocolumn
+ \ifdim\@tempdima>2\@tempdimb\relax
+ \setlength\textwidth{2\@tempdimb}
+ \else
+ \setlength\textwidth{\@tempdima}
+ \fi
+ \else
+ \ifdim\@tempdima>\@tempdimb\relax
+ \setlength\textwidth{\@tempdimb}
+ \else
+ \setlength\textwidth{\@tempdima}
+ \fi
+ \fi
+ \fi
+\fi
+\@settopoint\textwidth
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\textheight}
+% 基本組ã®è¡Œæ•°ã§ã™ã€‚
+%
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ã®å ´åˆï¼š
+% \begin{macrocode}
+\if@compatibility
+% \end{macrocode}
+% \changes{v1.1a}{1997/01/25}{Add paper option with compatibility mode.}
+% \changes{v1.1f}{1997/09/03}{landscapeã§ã®æŒ‡å®šã‚’追加}
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ï¼š|a4j|ã‚„|b5j|ã®ã‚¯ãƒ©ã‚¹ã‚ªãƒ—ションãŒæŒ‡å®šã•ã‚ŒãŸå ´åˆã®è¨­å®šï¼š
+% \begin{macrocode}
+ \if@stysize
+ \ifnum\c@@paper=2 % A5
+ \if@landscape
+%<10pt&yoko> \setlength\textheight{17\Cvs}
+%<11pt&yoko> \setlength\textheight{17\Cvs}
+%<12pt&yoko> \setlength\textheight{16\Cvs}
+%<10pt&tate> \setlength\textheight{26\Cvs}
+%<11pt&tate> \setlength\textheight{26\Cvs}
+%<12pt&tate> \setlength\textheight{25\Cvs}
+ \else
+%<10pt&yoko> \setlength\textheight{28\Cvs}
+%<11pt&yoko> \setlength\textheight{25\Cvs}
+%<12pt&yoko> \setlength\textheight{24\Cvs}
+%<10pt&tate> \setlength\textheight{16\Cvs}
+%<11pt&tate> \setlength\textheight{16\Cvs}
+%<12pt&tate> \setlength\textheight{15\Cvs}
+ \fi
+ \else\ifnum\c@@paper=3 % B4
+ \if@landscape
+%<10pt&yoko> \setlength\textheight{38\Cvs}
+%<11pt&yoko> \setlength\textheight{36\Cvs}
+%<12pt&yoko> \setlength\textheight{34\Cvs}
+%<10pt&tate> \setlength\textheight{48\Cvs}
+%<11pt&tate> \setlength\textheight{48\Cvs}
+%<12pt&tate> \setlength\textheight{45\Cvs}
+ \else
+%<10pt&yoko> \setlength\textheight{57\Cvs}
+%<11pt&yoko> \setlength\textheight{55\Cvs}
+%<12pt&yoko> \setlength\textheight{52\Cvs}
+%<10pt&tate> \setlength\textheight{33\Cvs}
+%<11pt&tate> \setlength\textheight{33\Cvs}
+%<12pt&tate> \setlength\textheight{31\Cvs}
+ \fi
+ \else\ifnum\c@@paper=4 % B5
+ \if@landscape
+%<10pt&yoko> \setlength\textheight{22\Cvs}
+%<11pt&yoko> \setlength\textheight{21\Cvs}
+%<12pt&yoko> \setlength\textheight{20\Cvs}
+%<10pt&tate> \setlength\textheight{34\Cvs}
+%<11pt&tate> \setlength\textheight{34\Cvs}
+%<12pt&tate> \setlength\textheight{32\Cvs}
+ \else
+%<10pt&yoko> \setlength\textheight{35\Cvs}
+%<11pt&yoko> \setlength\textheight{34\Cvs}
+%<12pt&yoko> \setlength\textheight{32\Cvs}
+%<10pt&tate> \setlength\textheight{21\Cvs}
+%<11pt&tate> \setlength\textheight{21\Cvs}
+%<12pt&tate> \setlength\textheight{20\Cvs}
+ \fi
+ \else % A4 and other
+ \if@landscape
+%<10pt&yoko> \setlength\textheight{27\Cvs}
+%<11pt&yoko> \setlength\textheight{26\Cvs}
+%<12pt&yoko> \setlength\textheight{25\Cvs}
+%<10pt&tate> \setlength\textheight{41\Cvs}
+%<11pt&tate> \setlength\textheight{41\Cvs}
+%<12pt&tate> \setlength\textheight{38\Cvs}
+ \else
+%<10pt&yoko> \setlength\textheight{43\Cvs}
+%<11pt&yoko> \setlength\textheight{42\Cvs}
+%<12pt&yoko> \setlength\textheight{39\Cvs}
+%<10pt&tate> \setlength\textheight{26\Cvs}
+%<11pt&tate> \setlength\textheight{26\Cvs}
+%<12pt&tate> \setlength\textheight{22\Cvs}
+ \fi
+ \fi\fi\fi
+%<yoko> \addtolength\textheight{\topskip}
+%<bk&yoko> \addtolength\textheight{\baselineskip}
+%<tate> \addtolength\textheight{\Cht}
+%<tate> \addtolength\textheight{\Cdp}
+% \end{macrocode}
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ï¼šãƒ‡ãƒ•ã‚©ãƒ«ãƒˆè¨­å®š
+% \begin{macrocode}
+ \else
+%<10pt&!bk&yoko> \setlength\textheight{578\p@}
+%<10pt&bk&yoko> \setlength\textheight{554\p@}
+%<11pt&yoko> \setlength\textheight{580.4\p@}
+%<12pt&yoko> \setlength\textheight{586.5\p@}
+%<10pt&tate> \setlength\textheight{26\Cvs}
+%<11pt&tate> \setlength\textheight{25\Cvs}
+%<12pt&tate> \setlength\textheight{24\Cvs}
+ \fi
+% \end{macrocode}
+% 2eモードã®å ´åˆï¼š
+% \begin{macrocode}
+\else
+% \end{macrocode}
+% 2eモード:|a4j|ã‚„|b5j|ã®ã‚¯ãƒ©ã‚¹ã‚ªãƒ—ションãŒæŒ‡å®šã•ã‚ŒãŸå ´åˆã®è¨­å®šï¼š
+% 縦組ã§ã¯ç”¨ç´™ã‚µã‚¤ã‚ºã®70\%(book)ã‹78\%(ariticle,report)ã€
+% 横組ã§ã¯70\%(book)ã‹75\%(article,report)を版é¢ã®é«˜ã•ã«è¨­å®šã—ã¾ã™ã€‚
+% \begin{macrocode}
+ \if@stysize
+%<tate&bk> \setlength\textheight{.75\paperwidth}
+%<tate&!bk> \setlength\textheight{.78\paperwidth}
+%<yoko&bk> \setlength\textheight{.70\paperheight}
+%<yoko&!bk> \setlength\textheight{.75\paperheight}
+% \end{macrocode}
+% 2eモード:デフォルト値
+% \begin{macrocode}
+ \else
+%<tate> \setlength\@tempdima{\paperwidth}
+%<yoko> \setlength\@tempdima{\paperheight}
+ \addtolength\@tempdima{-2in}
+%<yoko> \addtolength\@tempdima{-1.5in}
+ \divide\@tempdima\baselineskip
+ \@tempcnta\@tempdima
+ \setlength\textheight{\@tempcnta\baselineskip}
+ \fi
+\fi
+% \end{macrocode}
+% 最後ã«ã€|\textheight|ã«|\topskip|ã®å€¤ã‚’加ãˆã¾ã™ã€‚
+% \begin{macrocode}
+\addtolength\textheight{\topskip}
+\@settopoint\textheight
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{マージン}
+%
+% \begin{macro}{\topmargin}
+% |\topmargin|ã¯ã€``å°å­—å¯èƒ½é ˜åŸŸ''---用紙ã®ä¸Šç«¯ã‹ã‚‰ï¼‘インãƒå†…å´---%
+% ã®ä¸Šç«¯ã‹ã‚‰ãƒ˜ãƒƒãƒ€éƒ¨åˆ†ã®ä¸Šç«¯ã¾ã§ã®è·é›¢ã§ã™ã€‚
+%
+% 2.09互æ›ãƒ¢ãƒ¼ãƒ‰ã®å ´åˆï¼š
+% \begin{macrocode}
+\if@compatibility
+%<*yoko>
+ \if@stysize
+ \setlength\topmargin{-.3in}
+ \else
+%<!bk> \setlength\topmargin{27\p@}
+%<10pt&bk> \setlength\topmargin{.75in}
+%<11pt&bk> \setlength\topmargin{.73in}
+%<12pt&bk> \setlength\topmargin{.73in}
+ \fi
+%</yoko>
+%<*tate>
+ \if@stysize
+ \ifnum\c@@paper=2 % A5
+ \setlength\topmargin{.8in}
+ \else % A4, B4, B5 and other
+ \setlength\topmargin{32mm}
+ \fi
+ \else
+ \setlength\topmargin{32mm}
+ \fi
+ \addtolength\topmargin{-1in}
+ \addtolength\topmargin{-\headheight}
+ \addtolength\topmargin{-\headsep}
+%</tate>
+% \end{macrocode}
+% 2eモードã®å ´åˆï¼š
+% \begin{macrocode}
+\else
+ \setlength\topmargin{\paperheight}
+ \addtolength\topmargin{-\headheight}
+ \addtolength\topmargin{-\headsep}
+%<tate> \addtolength\topmargin{-\textwidth}
+%<yoko> \addtolength\topmargin{-\textheight}
+ \addtolength\topmargin{-\footskip}
+% \end{macrocode}
+% \changes{v1.1e}{1997/04/08}{横組クラスã§ã®èª¿æ•´é‡ã‚’
+% -2.4インãƒã‹ã‚‰-2.0インãƒã«ã—ãŸã€‚}
+% \changes{v1.1j}{1998/02/03}{互æ›ãƒ¢ãƒ¼ãƒ‰æ™‚ã®a5pã®ãƒˆãƒƒãƒ—マージンを0.7in増加}
+% \begin{macrocode}
+ \if@stysize
+ \ifnum\c@@paper=2 % A5
+ \addtolength\topmargin{-1.3in}
+ \else
+ \addtolength\topmargin{-2.0in}
+ \fi
+ \else
+%<yoko> \addtolength\topmargin{-2.0in}
+%<tate> \addtolength\topmargin{-2.8in}
+ \fi
+% \end{macrocode}
+% \changes{v1.1d}{1997/02/05}{\cs{tompargin}ã‚’åŠåˆ†ã«ã™ã‚‹ã®ã¯ã‚¢ã‚­é ˜åŸŸã®è¨ˆç®—後}
+% \changes{v1.1r}{1999/08/09}{\cs{if@stysize}フラグã«é™ã‚‰ãšåŠåˆ†ã«ã™ã‚‹}
+% \begin{macrocode}
+ \addtolength\topmargin{-.5\topmargin}
+\fi
+\@settopoint\topmargin
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\marginparsep}
+% \begin{macro}{\marginparpush}
+% |\marginparsep|ã¯ã€æœ¬æ–‡ã¨å‚注ã®é–“ã«ã‚ã‘るスペースã®å¹…ã§ã™ã€‚
+% 横組ã§ã¯æœ¬æ–‡ã®å·¦ï¼ˆå³ï¼‰ç«¯ã¨å‚注ã€
+% 縦組ã§ã¯æœ¬æ–‡ã®ä¸‹ï¼ˆä¸Šï¼‰ç«¯ã¨å‚注ã®é–“ã«ãªã‚Šã¾ã™ã€‚
+% |\marginparpush|ã¯ã€å‚注ã¨å‚注ã¨ã®é–“ã®ã‚¹ãƒšãƒ¼ã‚¹ã®å¹…ã§ã™ã€‚
+% \begin{macrocode}
+\if@twocolumn
+ \setlength\marginparsep{10\p@}
+\else
+%<tate> \setlength\marginparsep{15\p@}
+%<yoko> \setlength\marginparsep{10\p@}
+\fi
+%<tate>\setlength\marginparpush{7\p@}
+%<*yoko>
+%<10pt>\setlength\marginparpush{5\p@}
+%<11pt>\setlength\marginparpush{5\p@}
+%<12pt>\setlength\marginparpush{7\p@}
+%</yoko>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\oddsidemargin}
+% \begin{macro}{\evensidemargin}
+% \begin{macro}{\marginparwidth}
+% ã¾ãšã€äº’æ›ãƒ¢ãƒ¼ãƒ‰ã§ã®é•·ã•ã‚’示ã—ã¾ã™ã€‚
+%
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ã€ç¸¦çµ„ã®å ´åˆï¼š
+% \begin{macrocode}
+\if@compatibility
+%<tate> \setlength\oddsidemargin{0\p@}
+%<tate> \setlength\evensidemargin{0\p@}
+% \end{macrocode}
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ã€æ¨ªçµ„ã€bookクラスã®å ´åˆï¼š
+% \begin{macrocode}
+%<*yoko>
+%<*bk>
+%<10pt> \setlength\oddsidemargin {.5in}
+%<11pt> \setlength\oddsidemargin {.25in}
+%<12pt> \setlength\oddsidemargin {.25in}
+%<10pt> \setlength\evensidemargin {1.5in}
+%<11pt> \setlength\evensidemargin {1.25in}
+%<12pt> \setlength\evensidemargin {1.25in}
+%<10pt> \setlength\marginparwidth {.75in}
+%<11pt> \setlength\marginparwidth {1in}
+%<12pt> \setlength\marginparwidth {1in}
+%</bk>
+% \end{macrocode}
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ã€æ¨ªçµ„ã€reportã¨articleクラスã®å ´åˆï¼š
+% \begin{macrocode}
+%<*!bk>
+ \if@twoside
+%<10pt> \setlength\oddsidemargin {44\p@}
+%<11pt> \setlength\oddsidemargin {36\p@}
+%<12pt> \setlength\oddsidemargin {21\p@}
+%<10pt> \setlength\evensidemargin {82\p@}
+%<11pt> \setlength\evensidemargin {74\p@}
+%<12pt> \setlength\evensidemargin {59\p@}
+%<10pt> \setlength\marginparwidth {107\p@}
+%<11pt> \setlength\marginparwidth {100\p@}
+%<12pt> \setlength\marginparwidth {85\p@}
+ \else
+%<10pt> \setlength\oddsidemargin {60\p@}
+%<11pt> \setlength\oddsidemargin {54\p@}
+%<12pt> \setlength\oddsidemargin {39.5\p@}
+%<10pt> \setlength\evensidemargin {60\p@}
+%<11pt> \setlength\evensidemargin {54\p@}
+%<12pt> \setlength\evensidemargin {39.5\p@}
+%<10pt> \setlength\marginparwidth {90\p@}
+%<11pt> \setlength\marginparwidth {83\p@}
+%<12pt> \setlength\marginparwidth {68\p@}
+ \fi
+%</!bk>
+% \end{macrocode}
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ã€æ¨ªçµ„ã€äºŒæ®µçµ„ã®å ´åˆï¼š
+% \begin{macrocode}
+ \if@twocolumn
+ \setlength\oddsidemargin {30\p@}
+ \setlength\evensidemargin {30\p@}
+ \setlength\marginparwidth {48\p@}
+ \fi
+%</yoko>
+% \end{macrocode}
+% 縦組ã€æ¨ªçµ„ã«ã‹ã‹ã‚らãšã€ã‚¹ã‚¿ã‚¤ãƒ«ã‚ªãƒ—ション設定ã§ã¯ã‚¼ãƒ­ã§ã™ã€‚
+% \changes{v1.0g}{1997/01/25}{\cs{oddsidemargin}, \cs{evensidemagin}:
+% 0pt if specified papersize at \cs{documentstyle} option.}
+% \begin{macrocode}
+ \if@stysize
+ \if@twocolumn\else
+ \setlength\oddsidemargin{0\p@}
+ \setlength\evensidemargin{0\p@}
+ \fi
+ \fi
+% \end{macrocode}
+%
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ã§ãªã„å ´åˆï¼š
+% \begin{macrocode}
+\else
+ \setlength\@tempdima{\paperwidth}
+%<tate> \addtolength\@tempdima{-\textheight}
+%<yoko> \addtolength\@tempdima{-\textwidth}
+% \end{macrocode}
+%
+% |\oddsidemargin|を計算ã—ã¾ã™ã€‚
+% \begin{macrocode}
+ \if@twoside
+%<tate> \setlength\oddsidemargin{.6\@tempdima}
+%<yoko> \setlength\oddsidemargin{.4\@tempdima}
+ \else
+ \setlength\oddsidemargin{.5\@tempdima}
+ \fi
+ \addtolength\oddsidemargin{-1in}
+% \end{macrocode}
+% \changes{v1.1p}{1999/1/6}{\cs{oddsidemargin}ã®ãƒã‚¤ãƒ³ãƒˆã¸ã®å¤‰æ›ã‚’後ã‚ã«}
+% |\evensidemargin|を計算ã—ã¾ã™ã€‚
+% \begin{macrocode}
+ \setlength\evensidemargin{\paperwidth}
+ \addtolength\evensidemargin{-2in}
+%<tate> \addtolength\evensidemargin{-\textheight}
+%<yoko> \addtolength\evensidemargin{-\textwidth}
+ \addtolength\evensidemargin{-\oddsidemargin}
+ \@settopoint\oddsidemargin % 1999.1.6
+ \@settopoint\evensidemargin
+% \end{macrocode}
+% |\marginparwidth|を計算ã—ã¾ã™ã€‚
+% ã“ã“ã§ã€|\@tempdima|ã®å€¤ã¯ã€\linebreak
+% |\paperwidth| $-$ |\textwidth|ã§ã™ã€‚
+% \changes{v1.1d}{1995/11/24}{\break typo: \cs{marginmarwidth} to \cs{marginparwidth}}
+% \begin{macrocode}
+%<*yoko>
+ \if@twoside
+ \setlength\marginparwidth{.6\@tempdima}
+ \addtolength\marginparwidth{-.4in}
+ \else
+ \setlength\marginparwidth{.5\@tempdima}
+ \addtolength\marginparwidth{-.4in}
+ \fi
+ \ifdim \marginparwidth >2in
+ \setlength\marginparwidth{2in}
+ \fi
+%</yoko>
+% \end{macrocode}
+%
+% 縦組ã®å ´åˆã¯ã€å°‘ã—複雑ã§ã™ã€‚
+% \begin{macrocode}
+%<*tate>
+ \setlength\@tempdima{\paperheight}
+ \addtolength\@tempdima{-\textwidth}
+ \addtolength\@tempdima{-\topmargin}
+ \addtolength\@tempdima{-\headheight}
+ \addtolength\@tempdima{-\headsep}
+ \addtolength\@tempdima{-\footskip}
+ \setlength\marginparwidth{.5\@tempdima}
+%</tate>
+ \@settopoint\marginparwidth
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{脚注}
+%
+% \begin{macro}{\footnotesep}
+% |\footnotesep|ã¯ã€ãã‚Œãžã‚Œã®è„šæ³¨ã®å…ˆé ­ã«ç½®ã‹ã‚Œã‚‹``支柱''ã®é«˜ã•ã§ã™ã€‚
+% ã“ã®ã‚¯ãƒ©ã‚¹ã§ã¯ã€é€šå¸¸ã®|\footnotesize|ã®æ”¯æŸ±ã¨åŒã˜é•·ã•ã§ã™ã®ã§ã€
+% 脚注間ã«ä½™è¨ˆãªç©ºç™½ã¯å…¥ã‚Šã¾ã›ã‚“。
+% \begin{macrocode}
+%<10pt>\setlength\footnotesep{6.65\p@}
+%<11pt>\setlength\footnotesep{7.7\p@}
+%<12pt>\setlength\footnotesep{8.4\p@}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\footins}
+% |\skip\footins|ã¯ã€æœ¬æ–‡ã®æœ€çµ‚è¡Œã¨æœ€åˆã®è„šæ³¨ã¨ã®é–“ã®è·é›¢ã§ã™ã€‚
+% \begin{macrocode}
+%<10pt>\setlength{\skip\footins}{9\p@ \@plus 4\p@ \@minus 2\p@}
+%<11pt>\setlength{\skip\footins}{10\p@ \@plus 4\p@ \@minus 2\p@}
+%<12pt>\setlength{\skip\footins}{10.8\p@ \@plus 4\p@ \@minus 2\p@}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{フロート}
+% ã™ã¹ã¦ã®ãƒ•ãƒ­ãƒ¼ãƒˆãƒ‘ラメータã¯ã€\LaTeX{}ã®ã‚«ãƒ¼ãƒãƒ«ã§ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãŒå®šç¾©
+% ã•ã‚Œã¦ã„ã¾ã™ã€‚ãã®ãŸã‚ã€ã‚«ã‚¦ãƒ³ã‚¿ä»¥å¤–ã®ãƒ‘ラメータã¯|\renewcommand|ã§
+% 設定ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+%
+% \subsubsection{フロートパラメータ}
+%
+% \begin{macro}{\floatsep}
+% \begin{macro}{\textfloatsep}
+% \begin{macro}{\intextsep}
+% フロートオブジェクトãŒæœ¬æ–‡ã®ã‚るページã«ç½®ã‹ã‚Œã‚‹ã¨ãã€
+% フロートã¨ãã®ãƒšãƒ¼ã‚¸ã«ã‚る別ã®ã‚ªãƒ–ジェクトã®è·é›¢ã¯ã€
+% ã“れらã®ãƒ‘ラメータã§åˆ¶å¾¡ã•ã‚Œã¾ã™ã€‚ã“れらã®ãƒ‘ラメータã¯ã€ä¸€æ®µçµ„モードã¨
+% 二段組モードã®æ®µæŠœãã§ãªã„フロートã®ä¸¡æ–¹ã§ä½¿ã‚ã‚Œã¾ã™ã€‚
+%
+% |\floatsep|ã¯ã€ãƒšãƒ¼ã‚¸ä¸Šéƒ¨ã‚ã‚‹ã„ã¯ä¸‹éƒ¨ã®ãƒ•ãƒ­ãƒ¼ãƒˆé–“ã®è·é›¢ã§ã™ã€‚
+%
+% |\textfloatsep|ã¯ã€ãƒšãƒ¼ã‚¸ä¸Šéƒ¨ã‚ã‚‹ã„ã¯ä¸‹éƒ¨ã®ãƒ•ãƒ­ãƒ¼ãƒˆã¨æœ¬æ–‡ã¨ã®è·é›¢ã§ã™ã€‚
+%
+% |\intextsep|ã¯ã€æœ¬æ–‡ã®é€”中ã«å‡ºåŠ›ã•ã‚Œã‚‹ãƒ•ãƒ­ãƒ¼ãƒˆã¨æœ¬æ–‡ã¨ã®è·é›¢ã§ã™ã€‚
+% \begin{macrocode}
+%<*10pt>
+\setlength\floatsep {12\p@ \@plus 2\p@ \@minus 2\p@}
+\setlength\textfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
+\setlength\intextsep {12\p@ \@plus 2\p@ \@minus 2\p@}
+%</10pt>
+%<*11pt>
+\setlength\floatsep {12\p@ \@plus 2\p@ \@minus 2\p@}
+\setlength\textfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
+\setlength\intextsep {12\p@ \@plus 2\p@ \@minus 2\p@}
+%</11pt>
+%<*12pt>
+\setlength\floatsep {12\p@ \@plus 2\p@ \@minus 4\p@}
+\setlength\textfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
+\setlength\intextsep {14\p@ \@plus 4\p@ \@minus 4\p@}
+%</12pt>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dblfloatsep}
+% \begin{macro}{\dbltextfloatsep}
+% 二段組モードã§ã€|\textwidth|ã®å¹…ã‚’æŒã¤ã€æ®µæŠœãã®ãƒ•ãƒ­ãƒ¼ãƒˆã‚ªãƒ–ジェクトãŒ
+% 本文ã¨åŒã˜ãƒšãƒ¼ã‚¸ã«ç½®ã‹ã‚Œã‚‹ã¨ãã€æœ¬æ–‡ã¨ãƒ•ãƒ­ãƒ¼ãƒˆã¨ã®è·é›¢ã¯ã€
+% |\dblfloatsep|ã¨|\dbltextfloatsep|ã«ã‚ˆã£ã¦åˆ¶å¾¡ã•ã‚Œã¾ã™ã€‚
+%
+% |\dblfloatsep|ã¯ã€ãƒšãƒ¼ã‚¸ä¸Šéƒ¨ã‚ã‚‹ã„ã¯ä¸‹éƒ¨ã®ãƒ•ãƒ­ãƒ¼ãƒˆã¨æœ¬æ–‡ã¨ã®è·é›¢ã§ã™ã€‚
+%
+% |\dbltextfloatsep|ã¯ã€ãƒšãƒ¼ã‚¸ä¸Šéƒ¨ã‚ã‚‹ã„ã¯ä¸‹éƒ¨ã®ãƒ•ãƒ­ãƒ¼ãƒˆé–“ã®è·é›¢ã§ã™ã€‚
+% \begin{macrocode}
+%<*10pt>
+\setlength\dblfloatsep {12\p@ \@plus 2\p@ \@minus 2\p@}
+\setlength\dbltextfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
+%</10pt>
+%<*11pt>
+\setlength\dblfloatsep {12\p@ \@plus 2\p@ \@minus 2\p@}
+\setlength\dbltextfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
+%</11pt>
+%<*12pt>
+\setlength\dblfloatsep {14\p@ \@plus 2\p@ \@minus 4\p@}
+\setlength\dbltextfloatsep{20\p@ \@plus 2\p@ \@minus 4\p@}
+%</12pt>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@fptop}
+% \begin{macro}{\@fpsep}
+% \begin{macro}{\@fpbot}
+% フロートオブジェクトãŒã€ç‹¬ç«‹ã—ãŸãƒšãƒ¼ã‚¸ã«ç½®ã‹ã‚Œã‚‹ã¨ãã€
+% ã“ã®ãƒšãƒ¼ã‚¸ã®ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã¯ã€æ¬¡ã®ãƒ‘ラメータã§åˆ¶å¾¡ã•ã‚Œã¾ã™ã€‚
+% ã“れらã®ãƒ‘ラメータã¯ã€ä¸€æ®µçµ„モードã‹ã€äºŒæ®µçµ„モードã§ã®ä¸€æ®µå‡ºåŠ›ã®
+% フロートオブジェクトã«å¯¾ã—ã¦ä½¿ã‚ã‚Œã¾ã™ã€‚
+%
+% ページ上部ã§ã¯ã€|\@fptop|ã®ä¼¸ç¸®é•·ãŒæŒ¿å…¥ã•ã‚Œã¾ã™ã€‚
+% ページ下部ã§ã¯ã€|\@fpbot|ã®ä¼¸ç¸®é•·ãŒæŒ¿å…¥ã•ã‚Œã¾ã™ã€‚
+% フロート間ã«ã¯|\@fpsep|ãŒæŒ¿å…¥ã•ã‚Œã¾ã™ã€‚
+%
+% ãªãŠã€ãã®ãƒšãƒ¼ã‚¸ã‚’空白ã§æº€ãŸã™ãŸã‚ã«ã€|\@fptop|ã¨|\@fpbot|ã®
+% å°‘ãªãã¨ã‚‚ã©ã¡ã‚‰ã‹ä¸€æ–¹ã«ã€|plus ...fil|ã‚’å«ã‚ã¦ãã ã•ã„。
+% \begin{macrocode}
+%<*10pt>
+\setlength\@fptop{0\p@ \@plus 1fil}
+\setlength\@fpsep{8\p@ \@plus 2fil}
+\setlength\@fpbot{0\p@ \@plus 1fil}
+%</10pt>
+%<*11pt>
+\setlength\@fptop{0\p@ \@plus 1fil}
+\setlength\@fpsep{8\p@ \@plus 2fil}
+\setlength\@fpbot{0\p@ \@plus 1fil}
+%</11pt>
+%<*12pt>
+\setlength\@fptop{0\p@ \@plus 1fil}
+\setlength\@fpsep{10\p@ \@plus 2fil}
+\setlength\@fpbot{0\p@ \@plus 1fil}
+%</12pt>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@dblfptop}
+% \begin{macro}{\@dblfpsep}
+% \begin{macro}{\@dblfpbot}
+% 二段組モードã§ã®äºŒæ®µæŠœãã®ãƒ•ãƒ­ãƒ¼ãƒˆã«å¯¾ã—ã¦ã¯ã€
+% ã“れらã®ãƒ‘ラメータãŒä½¿ã‚ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+%<*10pt>
+\setlength\@dblfptop{0\p@ \@plus 1fil}
+\setlength\@dblfpsep{8\p@ \@plus 2fil}
+\setlength\@dblfpbot{0\p@ \@plus 1fil}
+%</10pt>
+%<*11pt>
+\setlength\@dblfptop{0\p@ \@plus 1fil}
+\setlength\@dblfpsep{8\p@ \@plus 2fil}
+\setlength\@dblfpbot{0\p@ \@plus 1fil}
+%</11pt>
+%<*12pt>
+\setlength\@dblfptop{0\p@ \@plus 1fil}
+\setlength\@dblfpsep{10\p@ \@plus 2fil}
+\setlength\@dblfpbot{0\p@ \@plus 1fil}
+%</12pt>
+%</10pt|11pt|12pt>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{フロートオブジェクトã®ä¸Šé™å€¤}
+%
+% \begin{macro}{\c@topnumber}
+% \Lcount{topnumber}ã¯ã€æœ¬æ–‡ãƒšãƒ¼ã‚¸ã®ä¸Šéƒ¨ã«å‡ºåŠ›ã§ãるフロートã®æœ€å¤§æ•°ã§ã™ã€‚
+% \begin{macrocode}
+%<*article|report|book>
+\setcounter{topnumber}{2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c@bottomnumber}
+% \Lcount{bottomnumber}ã¯ã€æœ¬æ–‡ãƒšãƒ¼ã‚¸ã®ä¸‹éƒ¨ã«å‡ºåŠ›ã§ãるフロートã®æœ€å¤§æ•°ã§ã™ã€‚
+% \begin{macrocode}
+\setcounter{bottomnumber}{1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c@totalnumber}
+% \Lcount{totalnumber}ã¯ã€æœ¬æ–‡ãƒšãƒ¼ã‚¸ã«å‡ºåŠ›ã§ãるフロートã®æœ€å¤§æ•°ã§ã™ã€‚
+% \begin{macrocode}
+\setcounter{totalnumber}{3}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c@dbltopnumber}
+% \Lcount{dbltopnumber}ã¯ã€äºŒæ®µçµ„時ã«ãŠã‘ã‚‹ã€æœ¬æ–‡ãƒšãƒ¼ã‚¸ã®ä¸Šéƒ¨ã«å‡ºåŠ›ã§ãã‚‹
+% 段抜ãã®ãƒ•ãƒ­ãƒ¼ãƒˆã®æœ€å¤§æ•°ã§ã™ã€‚
+% \begin{macrocode}
+\setcounter{dbltopnumber}{2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\topfraction}
+% ã“ã‚Œã¯ã€æœ¬æ–‡ãƒšãƒ¼ã‚¸ã®ä¸Šéƒ¨ã«å‡ºåŠ›ã•ã‚Œã‚‹ãƒ•ãƒ­ãƒ¼ãƒˆãŒå æœ‰ã§ãる最大ã®å‰²ã‚Šåˆã„ã§ã™ã€‚
+% \begin{macrocode}
+\renewcommand{\topfraction}{.7}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\bottomfraction}
+% ã“ã‚Œã¯ã€æœ¬æ–‡ãƒšãƒ¼ã‚¸ã®ä¸‹éƒ¨ã«å‡ºåŠ›ã•ã‚Œã‚‹ãƒ•ãƒ­ãƒ¼ãƒˆãŒå æœ‰ã§ãる最大ã®å‰²ã‚Šåˆã„ã§ã™ã€‚
+% \begin{macrocode}
+\renewcommand{\bottomfraction}{.3}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\textfraction}
+% ã“ã‚Œã¯ã€æœ¬æ–‡ãƒšãƒ¼ã‚¸ã«æœ€ä½Žé™ã€å…¥ã‚‰ãªãã¦ã¯ãªã‚‰ãªã„本文ã®å‰²ã‚Šåˆã„ã§ã™ã€‚
+% \begin{macrocode}
+\renewcommand{\textfraction}{.2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\floatpagefraction}
+% ã“ã‚Œã¯ã€ãƒ•ãƒ­ãƒ¼ãƒˆã ã‘ã®ãƒšãƒ¼ã‚¸ã§æœ€ä½Žé™ã€å…¥ã‚‰ãªãã¦ã¯ãªã‚‰ãªã„
+% フロートã®å‰²ã‚Šåˆã„ã§ã™ã€‚
+% \begin{macrocode}
+\renewcommand{\floatpagefraction}{.5}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dbltopfraction}
+% ã“ã‚Œã¯ã€ï¼’段組時ã«ãŠã‘る本文ページã«ã€
+% 2段抜ãã®ãƒ•ãƒ­ãƒ¼ãƒˆãŒå ã‚ã‚‹ã“ã¨ãŒã§ãる最大ã®å‰²ã‚Šåˆã„ã§ã™ã€‚
+% \begin{macrocode}
+\renewcommand{\dbltopfraction}{.7}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dblfloatpagefraction}
+% ã“ã‚Œã¯ã€ï¼’段組時ã«ãŠã‘るフロートã ã‘ã®ãƒšãƒ¼ã‚¸ã«æœ€ä½Žé™ã€
+% 入らãªãã¦ã¯ãªã‚‰ãªã„2段抜ãã®ãƒ•ãƒ­ãƒ¼ãƒˆã®å‰²ã‚Šåˆã„ã§ã™ã€‚
+% \begin{macrocode}
+\renewcommand{\dblfloatpagefraction}{.5}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \section{改ページ(日本語\TeX{}開発コミュニティ版ã®ã¿ï¼‰}\label{sec:cleardoublepage}
+%
+% \begin{macro}{\pltx@cleartorightpage}
+% \begin{macro}{\pltx@cleartoleftpage}
+% \begin{macro}{\pltx@cleartooddpage}
+% \begin{macro}{\pltx@cleartoevenpage}
+% |\cleardoublepage|命令ã¯ã€\LaTeX{}カーãƒãƒ«ã§ã¯ã€Œå¥‡æ•°ãƒšãƒ¼ã‚¸ã«ãªã‚‹ã¾ã§ãƒšãƒ¼ã‚¸ã‚’
+% 繰る命令ã€ã¨ã—ã¦å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚ã—ã‹ã—p\LaTeX{}カーãƒãƒ«ã§ã¯ã€ã‚¢ã‚¹ã‚­ãƒ¼ã®æ–¹é‡
+% ã«ã‚ˆã‚Šã€Œæ¨ªçµ„ã§ã¯å¥‡æ•°ãƒšãƒ¼ã‚¸ã«ãªã‚‹ã¾ã§ã€ç¸¦çµ„ã§ã¯å¶æ•°ãƒšãƒ¼ã‚¸ã«ãªã‚‹ã¾ã§ãƒšãƒ¼ã‚¸ã‚’
+% 繰る命令ã€ã«å†å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚ã™ãªã‚ã¡ã€p\LaTeX{}ã§ã¯ç¸¦çµ„ã§ã‚‚横組ã§ã‚‚
+% å³ãƒšãƒ¼ã‚¸ã«ãªã‚‹ã¾ã§ãƒšãƒ¼ã‚¸ã‚’ç¹°ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚
+%
+% p\LaTeX{}標準クラスã®bookã¯ã€æ¨ªçµ„も縦組も|openright|ãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã«ãªã£ã¦ã„ã¦ã€
+% ã“ã‚Œã¯å¾“æ¥p\LaTeX{}カーãƒãƒ«ã§å®šç¾©ã•ã‚ŒãŸ|\cleardoublepage|を利用ã—ã¦ã„ã¾ã—ãŸã€‚
+% ã—ã‹ã—ã€ç¸¦çµ„ã§å¥‡æ•°ãƒšãƒ¼ã‚¸å§‹ã¾ã‚Šã®æ–‡æ›¸ã‚’作りãŸã„å ´åˆã‚‚ã‚ã‚‹ã§ã—ょã†ã‹ã‚‰ã€
+% コミュニティ版クラスã§ã¯ä»¥ä¸‹ã®ï¼ˆéžãƒ¦ãƒ¼ã‚¶å‘ã‘)命令を追加ã—ã¾ã™ã€‚
+% \begin{enumerate}
+% \item|\pltx@cleartorightpage|:å³ãƒšãƒ¼ã‚¸ã«ãªã‚‹ã¾ã§ãƒšãƒ¼ã‚¸ã‚’繰る命令
+% \item|\pltx@cleartoleftpage|:左ページã«ãªã‚‹ã¾ã§ãƒšãƒ¼ã‚¸ã‚’繰る命令
+% \item|\pltx@cleartooddpage|:奇数ページã«ãªã‚‹ã¾ã§ãƒšãƒ¼ã‚¸ã‚’繰る命令
+% \item|\pltx@cleartoevenpage|:å¶æ•°ãƒšãƒ¼ã‚¸ã«ãªã‚‹ã¾ã§ãƒšãƒ¼ã‚¸ã‚’繰る命令
+% \end{enumerate}
+% \changes{v1.7d}{2017/02/15}{\cs{cleardoublepage}ã®ä»£ç”¨ã¨ãªã‚‹å‘½ä»¤ç¾¤ã‚’追加}
+% \changes{v1.7d-ltj-14}{2017/02/20}{\cs{iftdir}, \cs{ifydir}を使ã‚ãªã„よã†ã«ä¿®æ­£}
+% \begin{macrocode}
+\def\pltx@cleartorightpage{\clearpage\if@twoside
+ \unless\ifodd\numexpr\c@page+\ltjgetparameter{direction}\relax
+ \hbox{}\thispagestyle{empty}\newpage
+ \if@twocolumn\hbox{}\newpage\fi
+ \fi\fi}
+\def\pltx@cleartoleftpage{\clearpage\if@twoside
+ \ifodd\numexpr\c@page+\ltjgetparameter{direction}\relax
+ \hbox{}\thispagestyle{empty}\newpage
+ \if@twocolumn\hbox{}\newpage\fi
+ \fi\fi}
+% \end{macrocode}
+%
+% |\pltx@cleartooddpage|ã¯\LaTeX{}ã®|\cleardoublepage|ã«ä¼¼ã¦ã„ã¾ã™ãŒã€
+% 上ã®2ã¤ã«åˆã‚ã›ã‚‹ãŸã‚|\thispagestyle{empty}|を追加ã—ã¦ã‚ã‚Šã¾ã™ã€‚
+% \begin{macrocode}
+\def\pltx@cleartooddpage{\clearpage\if@twoside
+ \ifodd\c@page\else
+ \hbox{}\thispagestyle{empty}\newpage
+ \if@twocolumn\hbox{}\newpage\fi
+ \fi\fi}
+\def\pltx@cleartoevenpage{\clearpage\if@twoside
+ \ifodd\c@page
+ \hbox{}\thispagestyle{empty}\newpage
+ \if@twocolumn\hbox{}\newpage\fi
+ \fi\fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cleardoublepage}
+% ãã—ã¦reportã¨bookクラスã®å ´åˆã¯ã€ãƒ¦ãƒ¼ã‚¶å‘ã‘命令ã§ã‚ã‚‹|\cleardoublepage|ã‚’ã€
+% |openright|オプションãŒæŒ‡å®šã•ã‚Œã¦ã„ã‚‹å ´åˆã¯|\pltx@cleartorightpage|ã«ã€
+% |openleft|オプションãŒæŒ‡å®šã•ã‚Œã¦ã„ã‚‹å ´åˆã¯|\pltx@cleartoleftpage|ã«ã€
+% ãã‚Œãžã‚Œ|\let|ã—ã¾ã™ã€‚|openany|ã®å ´åˆã¯p\LaTeX{}カーãƒãƒ«ã®å®šç¾©ã®ã¾ã¾ã§ã™ã€‚
+% \begin{macrocode}
+%<*!article>
+\if@openleft
+ \let\cleardoublepage\pltx@cleartoleftpage
+\else\if@openright
+ \let\cleardoublepage\pltx@cleartorightpage
+\fi\fi
+%</!article>
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \section{ページスタイル}\label{sec:pagestyle}
+% ã¤ãŽã®6種類ã®ãƒšãƒ¼ã‚¸ã‚¹ã‚¿ã‚¤ãƒ«ã‚’使用ã§ãã¾ã™ã€‚
+% \pstyle{empty}ã¯\file{ltpage.dtx}ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+%
+% \begin{tabular}{ll}
+% empty & ヘッダã«ã‚‚フッタã«ã‚‚出力ã—ãªã„\\
+% plain & フッタã«ãƒšãƒ¼ã‚¸ç•ªå·ã®ã¿ã‚’出力ã™ã‚‹\\
+% headnombre & ヘッダã«ãƒšãƒ¼ã‚¸ç•ªå·ã®ã¿ã‚’出力ã™ã‚‹\\
+% footnombre & フッタã«ãƒšãƒ¼ã‚¸ç•ªå·ã®ã¿ã‚’出力ã™ã‚‹\\
+% headings & ヘッダã«è¦‹å‡ºã—ã¨ãƒšãƒ¼ã‚¸ç•ªå·ã‚’出力ã™ã‚‹\\
+% bothstyle & ヘッダã«è¦‹å‡ºã—ã€ãƒ•ãƒƒã‚¿ã«ãƒšãƒ¼ã‚¸ç•ªå·ã‚’出力ã™ã‚‹\\
+% \end{tabular}
+%
+% ページスタイル\pstyle{foo}ã¯ã€|\ps@foo|コマンドã¨ã—ã¦å®šç¾©ã•ã‚Œã¾ã™ã€‚
+%
+% \begin{macro}{\@evenhead}
+% \begin{macro}{\@oddhead}
+% \begin{macro}{\@evenfoot}
+% \begin{macro}{\@oddfoot}
+% ã“れらã¯|\ps@...|ã‹ã‚‰å‘¼ã³å‡ºã•ã‚Œã€ãƒ˜ãƒƒãƒ€ã¨ãƒ•ãƒƒã‚¿ã‚’出力ã™ã‚‹ãƒžã‚¯ãƒ­ã§ã™ã€‚
+%
+% \DeleteShortVerb{\|}
+% \begin{tabular}{ll}
+% \cs{@oddhead} & 奇数ページã®ãƒ˜ãƒƒãƒ€ã‚’出力\\
+% \cs{@oddfoot} & 奇数ページã®ãƒ•ãƒƒã‚¿ã‚’出力\\
+% \cs{@evenhead} & å¶æ•°ãƒšãƒ¼ã‚¸ã®ãƒ˜ãƒƒãƒ€ã‚’出力\\
+% \cs{@evenfoot} & å¶æ•°ãƒšãƒ¼ã‚¸ã®ãƒ•ãƒƒã‚¿ã‚’出力\\
+% \end{tabular}
+% \MakeShortVerb{\|}
+%
+% ã“れらã®å†…容ã¯ã€æ¨ªçµ„ã®å ´åˆã¯|\textwidth|ã®å¹…ã‚’æŒã¤|\hbox|ã«å…¥ã‚Œã‚‰ã‚Œã€
+% 縦組ã®å ´åˆã¯|\textheight|ã®å¹…ã‚’æŒã¤|\hbox|ã«å…¥ã‚Œã‚‰ã‚Œã¾ã™ã€‚
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{マークã«ã¤ã„ã¦}
+% ヘッダã«å…¥ã‚‹ç« ç•ªå·ã‚„章見出ã—ã¯ã€è¦‹å‡ºã—コマンドã§å®Ÿè¡Œã•ã‚Œã‚‹ãƒžãƒ¼ã‚¯ã‚³ãƒžãƒ³ãƒ‰ã§
+% 決定ã•ã‚Œã¾ã™ã€‚ã“ã“ã§ã¯ã€å®Ÿè¡Œã•ã‚Œã‚‹ãƒžãƒ¼ã‚¯ã‚³ãƒžãƒ³ãƒ‰ã®å®šç¾©ã‚’è¡Œãªã£ã¦ã„ã¾ã™ã€‚
+% ã“れらã®ãƒžãƒ¼ã‚¯ã‚³ãƒžãƒ³ãƒ‰ã¯ã€\TeX{}ã®|\mark|機能を用ã„ã¦ã€
+% `left'ã¨`right'ã®ï¼’種類ã®ãƒžãƒ¼ã‚¯ã‚’生æˆã™ã‚‹ã‚ˆã†ã«å®šç¾©ã—ã¦ã„ã¾ã™ã€‚
+%
+% \begin{flushleft}
+% |\markboth{|\meta{LEFT}|}{|\meta{RIGHT}|}|: 両方ã®ãƒžãƒ¼ã‚¯ã«è¿½åŠ ã—ã¾ã™ã€‚
+%
+% |\markright{|\meta{RIGHT}|}|: `å³'マークã«è¿½åŠ ã—ã¾ã™ã€‚
+%
+% |\leftmark|: |\@oddhead|, |\@oddfoot|, |\@evenhead|, |\@evenfoot|マクロã§
+% 使ã‚ã‚Œã€ç¾åœ¨ã®``å·¦''マークを出力ã—ã¾ã™ã€‚
+% |\leftmark|ã¯\TeX{}ã®|\botmark|コマンドã®ã‚ˆã†ãªåƒãã‚’ã—ã¾ã™ã€‚
+% åˆæœŸå€¤ã¯ç©ºã§ãªãã¦ã¯ã„ã‘ã¾ã›ã‚“。
+%
+% |\rightmark|: |\@oddhead|, |\@oddfoot|, |\@evenhead|, |\@evenfoot|マクロã§
+% 使ã‚ã‚Œã€ç¾åœ¨ã®``å³''マークを出力ã—ã¾ã™ã€‚
+% |\rightmark|ã¯\TeX{}ã®|\firstmark|コマンドã®ã‚ˆã†ãªåƒãã‚’ã—ã¾ã™ã€‚
+% åˆæœŸå€¤ã¯ç©ºã§ãªãã¦ã¯ã„ã‘ã¾ã›ã‚“。
+% \end{flushleft}
+%
+% マークコマンドã®å‹•ä½œã¯ã€å·¦ãƒžãƒ¼ã‚¯ã®`範囲内ã®'å³ãƒžãƒ¼ã‚¯ã®ãŸã‚ã«
+% åˆç†çš„ã«ãªã£ã¦ã„ã¾ã™ã€‚ãŸã¨ãˆã°ã€å·¦ãƒžãƒ¼ã‚¯ã¯|\chapter|コマンドã«ã‚ˆã£ã¦
+% 変更ã•ã‚Œã¾ã™ã€‚ãã—ã¦å³ãƒžãƒ¼ã‚¯ã¯|\section|コマンドã«ã‚ˆã£ã¦å¤‰æ›´ã•ã‚Œã¾ã™ã€‚
+% ã—ã‹ã—ã€åŒä¸€ãƒšãƒ¼ã‚¸ã«è¤‡æ•°ã®|\markboth|コマンドãŒç¾ã‚ŒãŸã¨ãã€
+% ãŠã‹ã—ãªçµæžœã¨ãªã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚
+%
+% |\tableofcontents|ã®ã‚ˆã†ãªã‚³ãƒžãƒ³ãƒ‰ã¯ã€|\@mkboth|コマンドを用ã„ã¦ã€
+% ã‚るページスタイルã®ä¸­ã§ãƒžãƒ¼ã‚¯ã‚’設定ã—ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“。
+% |\@mkboth|ã¯ã€|\ps@...|コマンドã«ã‚ˆã£ã¦ã€|\markboth|(ヘッダを設定ã™ã‚‹ï¼‰ã‹ã€
+% |\@gobbletwo|(何もã—ãªã„)ã«|\let|ã•ã‚Œã¾ã™ã€‚
+%
+% \changes{v1.0a}{1995/08/30}{柱ã®æ›¸ä½“ãŒãƒŽãƒ³ãƒ–ルã«å½±éŸ¿ã™ã‚‹ãƒã‚°ã®ä¿®æ­£}
+%
+% \subsection{plainページスタイル}
+%
+% \begin{macro}{\ps@plain}
+% \pstyle{jpl@in}ã«|\let|ã™ã‚‹ãŸã‚ã«ã€ã“ã“ã§å®šç¾©ã‚’ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\def\ps@plain{\let\@mkboth\@gobbletwo
+ \let\ps@jpl@in\ps@plain
+ \let\@oddhead\@empty
+ \def\@oddfoot{\reset@font\hfil\thepage\hfil}%
+ \let\@evenhead\@empty
+ \let\@evenfoot\@oddfoot}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{jpl@inページスタイル}
+%
+% \begin{macro}{\ps@jpl@in}
+% \changes{v1.0d}{1996/02/29}{\pstyle{jpl@in}ã®åˆæœŸå€¤ã‚’定義}
+%
+% \pstyle{jpl@in}スタイルã¯ã€ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«å†…部ã§ä½¿ç”¨ã™ã‚‹ã‚‚ã®ã§ã™ã€‚
+% \LaTeX{}ã§ã¯ã€bookクラスを\pstyle{headings}ã¨ã—ã¦ã„ã¾ã™ã€‚
+% ã—ã‹ã—ã€\cs{tableofcontents}コマンドã®å†…部ã§ã¯\pstyle{plain}ã¨ã—ã¦
+% 設定ã•ã‚Œã‚‹ãŸã‚ã€ä¸€ã¤ã®æ–‡æ›¸ã§ã®ãƒšãƒ¼ã‚¸ç•ªå·ã®ä½ç½®ãŒä¸Šä¸‹ã«å‡ºåŠ›ã•ã‚Œã‚‹
+% ã“ã¨ã«ãªã‚Šã¾ã™ã€‚
+%
+% ãã“ã§ã€ã“ã“ã§ã¯\cs{tableofcontents}ã‚„\cs{theindex}ã®ãƒšãƒ¼ã‚¸ã‚¹ã‚¿ã‚¤ãƒ«
+% ã‚’\pstyle{jpl@in}ã«ã—ã€å®Ÿéš›ã«å‡ºåŠ›ã•ã‚Œã‚‹å½¢å¼ã¯ã€ã»ã‹ã®ãƒšãƒ¼ã‚¸ã‚¹ã‚¿ã‚¤ãƒ«
+% ã§|\let|ã‚’ã—ã¦ã„ã¾ã™ã€‚ã—ãŸãŒã£ã¦ã€\pstyle{headings}ã®ã¨ãã€ç›®æ¬¡ãƒšãƒ¼ã‚¸ã®
+% ページ番å·ã¯ãƒ˜ãƒƒãƒ€ä½ç½®ã«å‡ºåŠ›ã•ã‚Œã€\pstyle{plain}ã®ã¨ãã«ã¯ã€ãƒ•ãƒƒã‚¿ä½ç½®ã«
+% 出力ã•ã‚Œã¾ã™ã€‚
+%
+% ã“ã“ã§ã€å®šç¾©ã‚’ã—ã¦ã„ã‚‹ã®ã¯ã€ãã®åˆæœŸå€¤ã§ã™ã€‚
+% \begin{macrocode}
+\let\ps@jpl@in\ps@plain
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{headnombreページスタイル}
+%
+% \begin{macro}{\ps@headnombre}
+% \pstyle{headnombre}スタイルã¯ã€ãƒ˜ãƒƒãƒ€ã«ãƒšãƒ¼ã‚¸ç•ªå·ã®ã¿ã‚’出力ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\def\ps@headnombre{\let\@mkboth\@gobbletwo
+ \let\ps@jpl@in\ps@headnombre
+%<yoko> \def\@evenhead{\thepage\hfil}%
+%<yoko> \def\@oddhead{\hfil\thepage}%
+%<tate> \def\@evenhead{\hfil\thepage}%
+%<tate> \def\@oddhead{\thepage\hfil}%
+ \let\@oddfoot\@empty\let\@evenfoot\@empty}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{footnombreページスタイル}
+%
+% \begin{macro}{\ps@footnombre}
+% \pstyle{footnombre}スタイルã¯ã€ãƒ•ãƒƒã‚¿ã«ãƒšãƒ¼ã‚¸ç•ªå·ã®ã¿ã‚’出力ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\def\ps@footnombre{\let\@mkboth\@gobbletwo
+ \let\ps@jpl@in\ps@footnombre
+%<yoko> \def\@evenfoot{\thepage\hfil}%
+%<yoko> \def\@oddfoot{\hfil\thepage}%
+%<tate> \def\@evenfoot{\hfil\thepage}%
+%<tate> \def\@oddfoot{\thepage\hfil}%
+ \let\@oddhead\@empty\let\@evenhead\@empty}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{headingsスタイル}
+% \pstyle{headings}スタイルã¯ã€ãƒ˜ãƒƒãƒ€ã«è¦‹å‡ºã—ã¨ãƒšãƒ¼ã‚¸ç•ªå·ã‚’出力ã—ã¾ã™ã€‚
+%
+% \begin{macro}{\ps@headings}
+% ã“ã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯ã€ä¸¡é¢å°åˆ·ã¨ç‰‡é¢å°åˆ·ã¨ã§å½¢å¼ãŒç•°ãªã‚Šã¾ã™ã€‚
+% \begin{macrocode}
+\if@twoside
+% \end{macrocode}
+% 横組ã®å ´åˆã¯ã€å¥‡æ•°ãƒšãƒ¼ã‚¸ãŒå³ã«ã€å¶æ•°ãƒšãƒ¼ã‚¸ãŒå·¦ã«ãã¾ã™ã€‚
+% 縦組ã®å ´åˆã¯ã€å¥‡æ•°ãƒšãƒ¼ã‚¸ãŒå·¦ã«ã€å¶æ•°ãƒšãƒ¼ã‚¸ãŒå³ã«ãã¾ã™ã€‚
+% \begin{macrocode}
+ \def\ps@headings{\let\ps@jpl@in\ps@headnombre
+ \let\@oddfoot\@empty\let\@evenfoot\@empty
+%<yoko> \def\@evenhead{\thepage\hfil\leftmark}%
+%<yoko> \def\@oddhead{{\rightmark}\hfil\thepage}%
+%<tate> \def\@evenhead{{\leftmark}\hfil\thepage}%
+%<tate> \def\@oddhead{\thepage\hfil\rightmark}%
+ \let\@mkboth\markboth
+%<*article>
+ \def\sectionmark##1{\markboth{%
+ \ifnum \c@secnumdepth >\z@ \thesection.\hskip1\zw\fi
+ ##1}{}}%
+ \def\subsectionmark##1{\markright{%
+ \ifnum \c@secnumdepth >\@ne \thesubsection.\hskip1\zw\fi
+ ##1}}%
+%</article>
+%<*report|book>
+ \def\chaptermark##1{\markboth{%
+ \ifnum \c@secnumdepth >\m@ne
+%<book> \if@mainmatter
+ \@chapapp\thechapter\@chappos\hskip1\zw
+%<book> \fi
+ \fi
+ ##1}{}}%
+ \def\sectionmark##1{\markright{%
+ \ifnum \c@secnumdepth >\z@ \thesection.\hskip1\zw\fi
+ ##1}}%
+%</report|book>
+ }
+% \end{macrocode}
+% 片é¢å°åˆ·ã®å ´åˆï¼š
+% \changes{v1.1g}{1997/08/25}{片é¢å°åˆ·ã®ã¨ãã€sectionレベルãŒå‡ºåŠ›ã•ã‚Œãªã„
+% ã®ã‚’修正}
+% \begin{macrocode}
+\else % if not twoside
+ \def\ps@headings{\let\ps@jpl@in\ps@headnombre
+ \let\@oddfoot\@empty
+%<yoko> \def\@oddhead{{\rightmark}\hfil\thepage}%
+%<tate> \def\@oddhead{\thepage\hfil\rightmark}%
+ \let\@mkboth\markboth
+%<*article>
+ \def\sectionmark##1{\markright{%
+ \ifnum \c@secnumdepth >\m@ne \thesection.\hskip1\zw\fi
+ ##1}}%
+%</article>
+%<*report|book>
+\def\chaptermark##1{\markright{%
+ \ifnum \c@secnumdepth >\m@ne
+%<book> \if@mainmatter
+ \@chapapp\thechapter\@chappos\hskip1\zw
+%<book> \fi
+ \fi
+ ##1}}%
+%</report|book>
+ }
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{bothstyleスタイル}
+%
+% \begin{macro}{\ps@bothstyle}
+% \pstyle{bothstyle}スタイルã¯ã€
+% ヘッダã«è¦‹å‡ºã—ã‚’ã€ãƒ•ãƒƒã‚¿ã«ãƒšãƒ¼ã‚¸ç•ªå·ã‚’出力ã—ã¾ã™ã€‚
+%
+% ã“ã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯ã€ä¸¡é¢å°åˆ·ã¨ç‰‡é¢å°åˆ·ã¨ã§å½¢å¼ãŒç•°ãªã‚Šã¾ã™ã€‚
+% \changes{v1.0d}{1995/08/23}{横組ã®evenfootãŒä¸­å¤®æƒãˆã«ãªã£ã¦ã„ãŸã®ã‚’修正}
+% \changes{v1.0d}{1996/03/05}{横組ã§å¶æ•°ãƒšãƒ¼ã‚¸ã¨å¥‡æ•°ãƒšãƒ¼ã‚¸ã®è¨­å®šãŒé€†ãªã®ã‚’修正}
+% \begin{macrocode}
+\if@twoside
+ \def\ps@bothstyle{\let\ps@jpl@in\ps@footnombre
+%<*yoko>
+ \def\@evenhead{\leftmark\hfil}% right page
+ \def\@evenfoot{\thepage\hfil}% right page
+ \def\@oddhead{\hfil\rightmark}% left page
+ \def\@oddfoot{\hfil\thepage}% left page
+%</yoko>
+%<*tate>
+ \def\@evenhead{\hfil\leftmark}% right page
+ \def\@evenfoot{\hfil\thepage}% right page
+ \def\@oddhead{\rightmark\hfil}% left page
+ \def\@oddfoot{\thepage\hfil}% left page
+%</tate>
+ \let\@mkboth\markboth
+%<*article>
+ \def\sectionmark##1{\markboth{%
+ \ifnum \c@secnumdepth >\z@ \thesection.\hskip1\zw\fi
+ ##1}{}}%
+ \def\subsectionmark##1{\markright{%
+ \ifnum \c@secnumdepth >\@ne \thesubsection.\hskip1\zw\fi
+ ##1}}%
+%</article>
+%<*report|book>
+\def\chaptermark##1{\markboth{%
+ \ifnum \c@secnumdepth >\m@ne
+%<book> \if@mainmatter
+ \@chapapp\thechapter\@chappos\hskip1\zw
+%<book> \fi
+ \fi
+ ##1}{}}%
+ \def\sectionmark##1{\markright{%
+ \ifnum \c@secnumdepth >\z@ \thesection.\hskip1\zw\fi
+ ##1}}%
+%</report|book>
+ }
+% \end{macrocode}
+% \changes{v1.1g}{1997/08/25}{片é¢å°åˆ·ã®ã¨ãã€sectionレベルãŒå‡ºåŠ›ã•ã‚Œãªã„
+% ã®ã‚’修正}
+% \changes{v1.1i}{1997/12/12}{report, bookクラスã§ç‰‡é¢å°åˆ·æ™‚ã«ã€
+% bothstyleスタイルã«ã™ã‚‹ã¨ã€ã‚³ãƒ³ãƒ‘イルエラーã«ãªã‚‹ã®ã‚’修正}
+% \begin{macrocode}
+\else % if one column
+ \def\ps@bothstyle{\let\ps@jpl@in\ps@footnombre
+%<yoko> \def\@oddhead{\hfil\rightmark}%
+%<yoko> \def\@oddfoot{\hfil\thepage}%
+%<tate> \def\@oddhead{\rightmark\hfil}%
+%<tate> \def\@oddfoot{\thepage\hfil}%
+ \let\@mkboth\markboth
+%<*article>
+ \def\sectionmark##1{\markright{%
+ \ifnum \c@secnumdepth >\m@ne \thesection.\hskip1\zw\fi
+ ##1}}%
+%</article>
+%<*report|book>
+ \def\chaptermark##1{\markright{%
+ \ifnum \c@secnumdepth >\m@ne
+%<book> \if@mainmatter
+ \@chapapp\thechapter\@chappos\hskip1\zw
+%<book> \fi
+ \fi
+ ##1}}%
+%</report|book>
+ }
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{myheadingスタイル}
+%
+% \begin{macro}{\ps@myheadings}
+% \changes{v1.0d}{1995/08/23}{横組モードã®å·¦å³ãŒé€†ã§ã‚ã£ãŸã®ã‚’修正}
+% \pstyle{myheadings}ページスタイルã¯ç°¡æ½”ã«å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% ユーザãŒãƒšãƒ¼ã‚¸ã‚¹ã‚¿ã‚¤ãƒ«ã‚’設計ã™ã‚‹ã¨ãã®ãƒ’ナ型ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+% \begin{macrocode}
+\def\ps@myheadings{\let\ps@jpl@in\ps@plain%
+ \let\@oddfoot\@empty\let\@evenfoot\@empty
+%<yoko> \def\@evenhead{\thepage\hfil\leftmark}%
+%<yoko> \def\@oddhead{{\rightmark}\hfil\thepage}%
+%<tate> \def\@evenhead{{\leftmark}\hfil\thepage}%
+%<tate> \def\@oddhead{\thepage\hfil\rightmark}%
+ \let\@mkboth\@gobbletwo
+%<!article> \let\chaptermark\@gobble
+ \let\sectionmark\@gobble
+%<article> \let\subsectionmark\@gobble
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \section{文書コマンド}
+%
+% \subsection{表題}
+%
+% \begin{macro}{\title}
+% \begin{macro}{\author}
+% \begin{macro}{\date}
+% 文書ã®ã‚¿ã‚¤ãƒˆãƒ«ã€è‘—者ã€æ—¥ä»˜ã®æƒ…å ±ã®ãŸã‚ã®ã€
+% ã“れらã®ï¼“ã¤ã®ã‚³ãƒžãƒ³ãƒ‰ã¯\file{ltsect.dtx}ã§æä¾›ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% ã“れらã®ã‚³ãƒžãƒ³ãƒ‰ã¯æ¬¡ã®ã‚ˆã†ã«å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+%\newcommand*{\title}[1]{\gdef\@title{#1}}
+%\newcommand*{\author}[1]{\gdef\@author{#1}}
+%\newcommand*{\date}[1]{\gdef\@date{#1}}
+% \end{macrocode}
+% |\date|マクロã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯ã€ä»Šæ—¥ã®æ—¥ä»˜ã§ã™ã€‚
+% \begin{macrocode}
+%\date{\today}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{environment}{titlepage}
+% 通常ã®ç’°å¢ƒã§ã¯ã€ãƒšãƒ¼ã‚¸ã®æœ€åˆã¨æœ€å¾Œã‚’除ãã€ã‚¿ã‚¤ãƒˆãƒ«ãƒšãƒ¼ã‚¸ç’°å¢ƒã¯ä½•ã‚‚ã—ã¾ã›ã‚“。
+% ã¾ãŸã€ãƒšãƒ¼ã‚¸ç•ªå·ã®å‡ºåŠ›ã‚’抑制ã—ã¾ã™ã€‚レãƒãƒ¼ãƒˆã‚¹ã‚¿ã‚¤ãƒ«ã§ã¯ã€
+% ページ番å·ã‚’1ã«ãƒªã‚»ãƒƒãƒˆã—ã€ãã—ã¦æœ€å¾Œã§1ã«æˆ»ã—ã¾ã™ã€‚
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ã§ã¯ã€ãƒšãƒ¼ã‚¸ç•ªå·ã¯ã‚¼ãƒ­ã«è¨­å®šã•ã‚Œã¾ã™ãŒã€
+% å³èµ·ã“ã—ページ用ã®ãƒšãƒ¼ã‚¸ãƒ‘ラメータã§ã¯èª¤ã£ãŸçµæžœã«ãªã‚Šã¾ã™ã€‚
+% 二段組スタイルã§ã‚‚一段組ã®ãƒšãƒ¼ã‚¸ãŒä½œã‚‰ã‚Œã¾ã™ã€‚
+%
+% \noindent\emph{日本語\TeX{}開発コミュニティã«ã‚ˆã‚‹å¤‰æ›´}:
+% 上ã«ã‚ã‚‹ã®ã¯ã‚¢ã‚¹ã‚­ãƒ¼ç‰ˆã®èª¬æ˜Žã§ã™ã€‚改ã‚ã¦ã‚¢ã‚¹ã‚­ãƒ¼ç‰ˆã®æŒ™å‹•ã‚’æ•´ç†ã™ã‚‹ã¨ã€
+% 以下ã®ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚
+% \begin{enumerate}
+% \item アスキー版ã§ã¯ã€ã‚¿ã‚¤ãƒˆãƒ«ãƒšãƒ¼ã‚¸ã®ç•ªå·ã‚’å¿…ãš1ã«ãƒªã‚»ãƒƒãƒˆã—ã¦ã„ã¾ã—ãŸãŒã€
+% ã“ã‚Œã¯æ­£ã—ãã‚ã‚Šã¾ã›ã‚“。ã“ã‚Œã¯ã€ã‚¿ã‚¤ãƒˆãƒ«ãƒšãƒ¼ã‚¸ãŒå¥‡æ•°ãƒšãƒ¼ã‚¸ç›®ã‹å¶æ•°ãƒšãƒ¼ã‚¸ç›®
+% ã‹ã«ã‹ã‹ã‚らãšã€ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã ã‘奇数ページ用ãŒé©ç”¨ã•ã‚Œã¦ã—ã¾ã†ã‹ã‚‰ã§ã™ã€‚
+% ã•ã‚‰ã«ã€ã‚¿ã‚¤ãƒˆãƒ«ã®æ¬¡ã®ãƒšãƒ¼ã‚¸ã‚‚å¶æ•°ã®ãƒšãƒ¼ã‚¸ç•ªå·ã‚’æŒã£ã¦ã—ã¾ã†ãŸã‚ã€ä¸¡é¢å°åˆ·
+% ã§å¥‡æ•°ãƒšãƒ¼ã‚¸ã¨å¶æ•°ãƒšãƒ¼ã‚¸ãŒäº¤äº’ã«å‡ºãªããªã‚‹ã¨ã„ã†å•é¡Œã‚‚ã‚ã‚Šã¾ã™ã€‚
+% \item アスキー版bookクラスã¯ã€ã‚¿ã‚¤ãƒˆãƒ«ãƒšãƒ¼ã‚¸ã‚’å¿…ãš|\cleardoublepage|ã§å§‹ã‚ã¦
+% ã„ã¾ã—ãŸã€‚p\LaTeX{}カーãƒãƒ«ã§ã®|\cleardoublepage|ã®å®šç¾©ã‹ã‚‰ã€ç¸¦çµ„ã®æ—¢å®šã§ã¯
+% タイトルãŒå¶æ•°ãƒšãƒ¼ã‚¸ç›®ã«å‡ºã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚ã“れ自体ãŒæ­£ã—ããªã„ã¨æ–­å®šã™ã‚‹
+% ã“ã¨ã¯ã§ãã¾ã›ã‚“ãŒã€ã‚¿ã‚¤ãƒˆãƒ«ã®ãƒšãƒ¼ã‚¸ç•ªå·ã‚’1ã«ãƒªã‚»ãƒƒãƒˆã™ã‚‹ã“ã¨ã¨åˆã‚ã•ã£ã¦ã€
+% å¶æ•°ãƒšãƒ¼ã‚¸ã«é€ã£ãŸã‚¿ã‚¤ãƒˆãƒ«ã«å¥‡æ•°ãƒšãƒ¼ã‚¸ç”¨ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆãŒé©ç”¨ã•ã‚Œã¦ã—ã¾ã†ã¨ã„ã†
+% çµæžœã¯æ­£ã—ãã‚ã‚Šã¾ã›ã‚“。
+% \end{enumerate}
+% ãã“ã§ã€ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ç‰ˆã§ã¯ã‚¿ã‚¤ãƒˆãƒ«ã®ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆãŒå¿…ãšå¥‡æ•°ãƒšãƒ¼ã‚¸ç”¨ã«ãªã‚‹ã¨ã„ã†
+% 挙動を支æŒã—ã€bookクラスã§ã¯ã‚¿ã‚¤ãƒˆãƒ«ãƒšãƒ¼ã‚¸ã‚’奇数ページ目ã«é€ã‚‹ã“ã¨ã«ã—ã¾ã—ãŸã€‚
+% ã“ã‚Œã§ã‚¿ã‚¤ãƒˆãƒ«ãƒšãƒ¼ã‚¸ãŒè¡¨ç´™ã‚‰ã—ã見ãˆã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚ã¾ãŸã€reportクラスã®
+% よã†ãªã‚¿ã‚¤ãƒˆãƒ«ãŒæˆã‚Šè¡Œãã«å¾“ã£ã¦å‡ºã‚‹å ´åˆã«ã¯
+% \begin{itemize}
+% \item 奇数ページ目ã«å‡ºã‚‹å ´åˆã€ãƒšãƒ¼ã‚¸ç•ªå·ã‚’1(奇数)ã«ãƒªã‚»ãƒƒãƒˆ
+% \item å¶æ•°ãƒšãƒ¼ã‚¸ç›®ã«å‡ºã‚‹å ´åˆã€ãƒšãƒ¼ã‚¸ç•ªå·ã‚’0(å¶æ•°ï¼‰ã«ãƒªã‚»ãƒƒãƒˆ
+% \end{itemize}
+% ã¨ã—ã¾ã—ãŸã€‚
+%
+% 一ã¤ã‚ã®ä¾‹ã‚’考ãˆã¾ã™ã€‚
+%\begin{verbatim}
+% \documentclass{tbook}
+% \title{タイトル}\author{著者}
+% \begin{document}
+% \maketitle
+% \chapter{ãƒãƒ£ãƒ—ター}
+% \end{document}
+%\end{verbatim}
+% アスキー版tbookクラスã§ã®çµæžœã¯
+%\begin{verbatim}
+% 1ページ目:空白(ページ番å·1ã¯éžè¡¨ç¤ºï¼‰
+% 2ページ目:タイトル(奇数レイアウトã€ãƒšãƒ¼ã‚¸ç•ªå·1ã¯éžè¡¨ç¤ºï¼‰
+% 3ページ目:ãƒãƒ£ãƒ—ター(å¶æ•°ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã€ãƒšãƒ¼ã‚¸ç•ªå·2)
+%\end{verbatim}
+% ã§ã™ãŒã€ä»®ã«æœ€åˆã®ç©ºç™½ãƒšãƒ¼ã‚¸ã•ãˆãªã‘ã‚Œã°
+%\begin{verbatim}
+% 1ページ目:タイトルã™ãªã‚ã¡è¡¨ç´™ï¼ˆå¥‡æ•°ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã€ãƒšãƒ¼ã‚¸ç•ªå·1ã¯éžè¡¨ç¤ºï¼‰
+% 2ページ目:ãƒãƒ£ãƒ—ター(å¶æ•°ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã€ãƒšãƒ¼ã‚¸ç•ªå·2)
+%\end{verbatim}
+% ã¨ã¿ãªã›ã‚‹ãŸã‚ã€ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ç‰ˆã§ã¯ç©ºç™½ãƒšãƒ¼ã‚¸ã‚’発生ã•ã›ãªã„よã†ã«ã—ã¾ã—ãŸã€‚
+%
+% 二ã¤ã‚ã®ä¾‹ã‚’考ãˆã¾ã™ã€‚
+%\begin{verbatim}
+% \documentclass{tbook}
+% \title{タイトル}\author{著者}
+% \begin{document}
+% テスト文章
+% \maketitle
+% \chapter{ãƒãƒ£ãƒ—ター}
+% \end{document}
+%\end{verbatim}
+% アスキー版tbookクラスã§ã®çµæžœã¯
+%\begin{verbatim}
+% 1ページ目:テスト文章(奇数レイアウトã€ãƒšãƒ¼ã‚¸ç•ªå·1)
+% 2ページ目:タイトル(奇数レイアウトã€ãƒšãƒ¼ã‚¸ç•ªå·1ã¯éžè¡¨ç¤ºï¼‰
+% 3ページ目:ãƒãƒ£ãƒ—ター(å¶æ•°ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã€ãƒšãƒ¼ã‚¸ç•ªå·2)
+%\end{verbatim}
+% ã§ã™ãŒã€ã“ã‚Œã§ã¯å¥‡æ•°ã¨å¶æ•°ã®ãƒšãƒ¼ã‚¸ç•ªå·ãŒäº¤äº’ã«ãªã£ã¦ã„ãªã„ã®ã§æ­£ã—ã
+% ã‚ã‚Šã¾ã›ã‚“。ãã“ã§ã€ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ç‰ˆã§ã¯
+%\begin{verbatim}
+% 1ページ目:テスト文章(奇数レイアウトã€ãƒšãƒ¼ã‚¸ç•ªå·1)
+% 2ページ目:空白ページ(ページ番å·2ã¯éžè¡¨ç¤ºï¼‰
+% 3ページ目:タイトル(奇数レイアウトã€ãƒšãƒ¼ã‚¸ç•ªå·1ã¯éžè¡¨ç¤ºï¼‰
+% 4ページ目:ãƒãƒ£ãƒ—ター(å¶æ•°ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã€ãƒšãƒ¼ã‚¸ç•ªå·2)
+%\end{verbatim}
+% ã¨ç›´ã—ã¾ã—ãŸã€‚
+%
+% ãªãŠã€p\LaTeX~2.09互æ›ãƒ¢ãƒ¼ãƒ‰ã¯ã‚¢ã‚¹ã‚­ãƒ¼ç‰ˆã®ã¾ã¾ã€ã™ãªã‚ã¡ã€Œãƒšãƒ¼ã‚¸ç•ªå·ã‚’ゼロã«
+% 設定ã€ã¨ã—ã¦ã‚ã‚Šã¾ã™ã€‚ã“ã‚Œã¯ã€æ¨ªçµ„ã®å³èµ·ã“ã—ã®æŒ™å‹•ã¨ã—ã¦ã¯èª¤ã‚Šã§ã™ãŒã€ç¸¦çµ„ã®
+% å³èµ·ã“ã—ã®æŒ™å‹•ã¨ã—ã¦ã¯ä¸€å¿œæ­£ã—ããªã£ã¦ã„ã‚‹ã¨ã„ãˆã¾ã™ã€‚
+%
+% 最åˆã«äº’æ›ãƒ¢ãƒ¼ãƒ‰ã®å®šç¾©ã‚’作りã¾ã™ã€‚
+% \begin{macrocode}
+\if@compatibility
+\newenvironment{titlepage}
+ {%
+%<book> \cleardoublepage
+ \if@twocolumn\@restonecoltrue\onecolumn
+ \else\@restonecolfalse\newpage\fi
+ \thispagestyle{empty}%
+ \setcounter{page}\z@
+ }%
+ {\if@restonecol\twocolumn\else\newpage\fi
+ }
+% \end{macrocode}
+%
+% ãã—ã¦ã€\LaTeX{}ãƒã‚¤ãƒ†ã‚£ãƒ–ã®ãŸã‚ã®å®šç¾©ã§ã™ã€‚
+% \changes{v1.7d}{2017/02/15}{bookクラスã§titlepageã‚’å¿…ãšå¥‡æ•°ãƒšãƒ¼ã‚¸
+% ã«é€ã‚‹ã‚ˆã†ã«å¤‰æ›´}
+% \changes{v1.7d}{2017/02/15}{titlepageã®ãƒšãƒ¼ã‚¸ç•ªå·ã‚’奇数ãªã‚‰ã°1ã«ã€
+% å¶æ•°ãªã‚‰ã°0ã«ãƒªã‚»ãƒƒãƒˆã™ã‚‹ã‚ˆã†ã«å¤‰æ›´}
+% \begin{macrocode}
+\else
+\newenvironment{titlepage}
+ {%
+%<book> \pltx@cleartooddpage %% 2017/02/15
+ \if@twocolumn
+ \@restonecoltrue\onecolumn
+ \else
+ \@restonecolfalse\newpage
+ \fi
+ \thispagestyle{empty}%
+ \ifodd\c@page\setcounter{page}\@ne\else\setcounter{page}\z@\fi %% 2017/02/15
+ }%
+ {\if@restonecol\twocolumn \else \newpage \fi
+% \end{macrocode}
+% 両é¢ãƒ¢ãƒ¼ãƒ‰ã§ãªã‘ã‚Œã°ã€ã‚¿ã‚¤ãƒˆãƒ«ãƒšãƒ¼ã‚¸ã®ç›´å¾Œã®ãƒšãƒ¼ã‚¸ã®ãƒšãƒ¼ã‚¸ç•ªå·ã‚‚1ã«
+% ã—ã¾ã™ã€‚
+% \begin{macrocode}
+ \if@twoside\else
+ \setcounter{page}\@ne
+ \fi
+ }
+\fi
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\maketitle}
+% ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ã€è¡¨é¡Œã‚’作æˆã—ã€å‡ºåŠ›ã—ã¾ã™ã€‚
+% 表題ページを独立ã•ã›ã‚‹ã‹ã©ã†ã‹ã«ã‚ˆã£ã¦å®šç¾©ãŒç•°ãªã‚Šã¾ã™ã€‚
+% reportã¨bookクラスã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯ç‹¬ç«‹ã—ãŸè¡¨é¡Œã§ã™ã€‚
+% articleクラスã¯ã‚ªãƒ—ションã§ç‹¬ç«‹ã•ã›ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+%
+% \begin{macro}{\p@thanks}
+% 縦組ã®ã¨ãã¯ã€|\thanks|コマンドを|\p@thanks|ã«|\let|ã—ã¾ã™ã€‚
+% ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯|\footnotetext|を使ã‚ãšã€ç›´æŽ¥ã€æ–‡å­—ã‚’|\@thanks|ã«æ ¼ç´
+% ã—ã¦ã„ãã¾ã™ã€‚
+%
+% 著者åã®è„‡ã«è¡¨ç¤ºã•ã‚Œã‚‹åˆå°ã¯ç›´ç«‹ã—ãŸæ•°å­—ã€æ³¨é‡ˆå´ã¯æ¨ªã«å¯ãŸæ•°å­—ã¨ãªã£ã¦ã„ã¾ã—
+% ãŸãŒã€ä¸è‡ªç„¶ãªã®ã§|\hbox{\yoko ...}|を追加ã—ã€ä¸¡æ–¹ã¨ã‚‚ç›´ç«‹ã™ã‚‹ã‚ˆã†ã«ã—ã¾ã—ãŸã€‚
+% \changes{v1.7d}{2017/02/15}{縦組クラスã®æ‰€å±žè¡¨ç¤ºã®ç•ªå·ã‚’ç›´ç«‹ã«ã—ãŸ}
+% \begin{macrocode}
+\def\p@thanks#1{\footnotemark
+ \protected@xdef\@thanks{\@thanks
+ \protect{\noindent\hbox{\yoko$\m@th^\thefootnote$}#1\protect\par}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\if@titlepage
+ \newcommand{\maketitle}{\begin{titlepage}%
+ \let\footnotesize\small
+ \let\footnoterule\relax
+%<tate> \let\thanks\p@thanks
+ \let\footnote\thanks
+% \end{macrocode}
+% \changes{v1.1d}{1997/02/12}{縦組クラスã®è¡¨ç´™ã‚’縦書ãã«ã™ã‚‹ã‚ˆã†ã«ã—ãŸ}
+% \begin{macrocode}
+%<tate> \vbox to\textheight\bgroup\tate\hsize\textwidth
+ \null\vfil
+ \vskip 60\p@
+ \begin{center}%
+ {\LARGE \@title \par}%
+ \vskip 3em%
+ {\Large
+ \lineskip .75em%
+ \begin{tabular}[t]{c}%
+ \@author
+ \end{tabular}\par}%
+ \vskip 1.5em%
+ {\large \@date \par}% % Set date in \large size.
+ \end{center}\par
+%<tate> \vfil{\centering\@thanks}\vfil\null
+%<tate> \egroup
+%<yoko> \@thanks\vfil\null
+ \end{titlepage}%
+% \end{macrocode}
+% \Lcount{footnote}カウンタをリセットã—ã€|\thanks|ã¨|\maketitle|コマンドを
+% 無効ã«ã—ã€ã„ãã¤ã‹ã®å†…部マクロを空ã«ã—ã¦æ ¼ç´é ˜åŸŸã‚’節約ã—ã¾ã™ã€‚
+% \begin{macrocode}
+ \setcounter{footnote}{0}%
+ \global\let\thanks\relax
+ \global\let\maketitle\relax
+ \global\let\p@thanks\relax
+ \global\let\@thanks\@empty
+ \global\let\@author\@empty
+ \global\let\@date\@empty
+ \global\let\@title\@empty
+% \end{macrocode}
+% タイトルãŒçµ„版ã•ã‚ŒãŸã‚‰ã€|\title|コマンドãªã©ã®å®£è¨€ã‚’無効ã«ã§ãã¾ã™ã€‚
+% |\and|ã®å®šç¾©ã¯ã€|\author|ã®å¼•æ•°ã§ã®ã¿ä½¿ç”¨ã—ã¾ã™ã®ã§ã€ç ´æ£„ã—ã¾ã™ã€‚
+% \begin{macrocode}
+ \global\let\title\relax
+ \global\let\author\relax
+ \global\let\date\relax
+ \global\let\and\relax
+ }%
+\else
+ \newcommand{\maketitle}{\par
+ \begingroup
+ \renewcommand{\thefootnote}{\fnsymbol{footnote}}%
+ \def\@makefnmark{\hbox{\unless\ifnum\ltjgetparameter{direction}=3 $\m@th^{\@thefnmark}$
+ \else\hbox{\yoko$\m@th^{\@thefnmark}$}\fi}}%
+%<*tate>
+ \long\def\@makefntext##1{\parindent 1\zw\noindent
+ \hb@xt@ 2\zw{\hss\@makefnmark}##1}%
+%</tate>
+%<*yoko>
+ \long\def\@makefntext##1{\parindent 1em\noindent
+ \hb@xt@1.8em{\hss$\m@th^{\@thefnmark}$}##1}%
+%</yoko>
+ \if@twocolumn
+ \ifnum \col@number=\@ne \@maketitle
+ \else \twocolumn[\@maketitle]%
+ \fi
+ \else
+ \newpage
+ \global\@topnum\z@ % Prevents figures from going at top of page.
+ \@maketitle
+ \fi
+ \thispagestyle{jpl@in}\@thanks
+% \end{macrocode}
+% ã“ã“ã§ã‚°ãƒ«ãƒ¼ãƒ—ã‚’é–‰ã˜ã€\Lcount{footnote}カウンタをリセットã—ã€
+% |\thanks|, |\maketitle|, |\@maketitle|を無効ã«ã—ã€
+% ã„ãã¤ã‹ã®å†…部マクロを空ã«ã—ã¦æ ¼ç´é ˜åŸŸã‚’節約ã—ã¾ã™ã€‚
+% \changes{v1.7}{2016/11/12}{ドキュメントã«åã—ã¦\cs{@maketitle}ãŒ
+% 空ã«ãªã£ã¦ã„ãªã‹ã£ãŸã®ã‚’修正}
+% \begin{macrocode}
+ \endgroup
+ \setcounter{footnote}{0}%
+ \global\let\thanks\relax
+ \global\let\maketitle\relax
+ \global\let\@maketitle\relax
+ \global\let\p@thanks\relax
+ \global\let\@thanks\@empty
+ \global\let\@author\@empty
+ \global\let\@date\@empty
+ \global\let\@title\@empty
+ \global\let\title\relax
+ \global\let\author\relax
+ \global\let\date\relax
+ \global\let\and\relax
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@maketitle}
+% 独立ã—ãŸè¡¨é¡Œãƒšãƒ¼ã‚¸ã‚’作らãªã„å ´åˆã®ã€è¡¨é¡Œã®å‡ºåŠ›å½¢å¼ã§ã™ã€‚
+% \begin{macrocode}
+ \def\@maketitle{%
+ \newpage\null
+ \vskip 2em%
+ \begin{center}%
+%<yoko> \let\footnote\thanks
+%<tate> \let\footnote\p@thanks
+ {\LARGE \@title \par}%
+ \vskip 1.5em%
+ {\large
+ \lineskip .5em%
+ \begin{tabular}[t]{c}%
+ \@author
+ \end{tabular}\par}%
+ \vskip 1em%
+ {\large \@date}%
+ \end{center}%
+ \par\vskip 1.5em}
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{概è¦}
+%
+% \begin{environment}{abstract}
+% è¦ç´„æ–‡ã®ãŸã‚ã®ç’°å¢ƒã§ã™ã€‚bookクラスã§ã¯ä½¿ãˆã¾ã›ã‚“。
+% reportスタイルã¨ã€|titlepage|オプションを指定ã—ãŸarticleスタイルã§ã¯ã€
+% 独立ã—ãŸãƒšãƒ¼ã‚¸ã«å‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+%<*article|report>
+\if@titlepage
+ \newenvironment{abstract}{%
+ \titlepage
+ \null\vfil
+ \@beginparpenalty\@lowpenalty
+ \begin{center}%
+ {\bfseries\abstractname}%
+ \@endparpenalty\@M
+ \end{center}}%
+ {\par\vfil\null\endtitlepage}
+\else
+ \newenvironment{abstract}{%
+ \if@twocolumn
+ \section*{\abstractname}%
+ \else
+ \small
+ \begin{center}%
+ {\bfseries\abstractname\vspace{-.5em}\vspace{\z@}}%
+ \end{center}%
+ \quotation
+ \fi}{\if@twocolumn\else\endquotation\fi}
+\fi
+%</article|report>
+% \end{macrocode}
+% \end{environment}
+%
+%
+% \subsection{章見出ã—}
+%
+% \subsubsection{マークコマンド}
+%
+% \begin{macro}{\chaptermark}
+% \begin{macro}{\sectionmark}
+% \begin{macro}{\subsectionmark}
+% \begin{macro}{\subsubsectionmark}
+% \begin{macro}{\paragraphmark}
+% \begin{macro}{\subparagraphmark}
+% |\...mark|コマンドをåˆæœŸåŒ–ã—ã¾ã™ã€‚ã“れらã®ã‚³ãƒžãƒ³ãƒ‰ã¯ãƒšãƒ¼ã‚¸ã‚¹ã‚¿ã‚¤ãƒ«ã®
+% 定義ã§ä½¿ã‚ã‚Œã¾ã™ï¼ˆç¬¬\ref{sec:pagestyle}節å‚照)。
+% ã“れらã®ãŸã„ã¦ã„ã®ã‚³ãƒžãƒ³ãƒ‰ã¯\file{ltsect.dtx}ã§ã™ã§ã«å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+%<!article>\newcommand*{\chaptermark}[1]{}
+%\newcommand*{\sectionmark}[1]{}
+%\newcommand*{\subsectionmark}[1]{}
+%\newcommand*{\subsubsectionmark}[1]{}
+%\newcommand*{\paragraphmark}[1]{}
+%\newcommand*{\subparagraphmark}[1]{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{カウンタã®å®šç¾©}
+%
+% \begin{macro}{\c@secnumdepth}
+% \Lcount{secnumdepth}ã«ã¯ã€ç•ªå·ã‚’付ã‘ã‚‹ã€è¦‹å‡ºã—コマンドã®ãƒ¬ãƒ™ãƒ«ã‚’設定ã—ã¾ã™ã€‚
+% \begin{macrocode}
+%<article>\setcounter{secnumdepth}{3}
+%<!article>\setcounter{secnumdepth}{2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c@chapter}
+% \begin{macro}{\c@section}
+% \begin{macro}{\c@subsection}
+% \begin{macro}{\c@subsubsection}
+% \begin{macro}{\c@paragraph}
+% \begin{macro}{\c@subparagraph}
+% ã“れらã®ã‚«ã‚¦ãƒ³ã‚¿ã¯è¦‹å‡ºã—番å·ã«ä½¿ã‚ã‚Œã¾ã™ã€‚
+% 最åˆã®å¼•æ•°ã¯ã€äºŒç•ªç›®ã®å¼•æ•°ãŒå¢—加ã™ã‚‹ãŸã³ã«ãƒªã‚»ãƒƒãƒˆã•ã‚Œã¾ã™ã€‚
+% 二番目ã®ã‚«ã‚¦ãƒ³ã‚¿ã¯ã™ã§ã«å®šç¾©ã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã§ãªãã¦ã¯ã„ã‘ã¾ã›ã‚“。
+% \begin{macrocode}
+\newcounter{part}
+%<*book|report>
+\newcounter{chapter}
+\newcounter{section}[chapter]
+%</book|report>
+%<article>\newcounter{section}
+\newcounter{subsection}[section]
+\newcounter{subsubsection}[subsection]
+\newcounter{paragraph}[subsubsection]
+\newcounter{subparagraph}[paragraph]
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\thepart}
+% \begin{macro}{\thechapter}
+% \begin{macro}{\thesection}
+% \begin{macro}{\thesubsection}
+% \begin{macro}{\thesubsubsection}
+% \begin{macro}{\theparagraph}
+% \begin{macro}{\thesubparagraph}
+% |\theCTR|ãŒå®Ÿéš›ã«å‡ºåŠ›ã•ã‚Œã‚‹å½¢å¼ã®å®šç¾©ã§ã™ã€‚
+%
+% |\arabic{|\Lcount{COUNTER}|}|ã¯ã€\Lcount{COUNTER}ã®å€¤ã‚’
+% 算用数字ã§å‡ºåŠ›ã—ã¾ã™ã€‚
+%
+% |\roman{|\Lcount{COUNTER}|}|ã¯ã€\Lcount{COUNTER}ã®å€¤ã‚’
+% å°æ–‡å­—ã®ãƒ­ãƒ¼ãƒžæ•°å­—ã§å‡ºåŠ›ã—ã¾ã™ã€‚
+%
+% |\Roman{|\Lcount{COUNTER}|}|ã¯ã€\Lcount{COUNTER}ã®å€¤ã‚’
+% 大文字ã®ãƒ­ãƒ¼ãƒžæ•°å­—ã§å‡ºåŠ›ã—ã¾ã™ã€‚
+%
+% |\alph{|\Lcount{COUNTER}|}|ã¯ã€\Lcount{COUNTER}ã®å€¤ã‚’
+% $1=$~a, $2=$~b ã®ã‚ˆã†ã«ã—ã¦å‡ºåŠ›ã—ã¾ã™ã€‚
+%
+% |\Alph{|\Lcount{COUNTER}|}|ã¯ã€\Lcount{COUNTER}ã®å€¤ã‚’
+% $1=$~A, $2=$~B ã®ã‚ˆã†ã«ã—ã¦å‡ºåŠ›ã—ã¾ã™ã€‚
+%
+% |\Kanji{|\Lcount{COUNTER}|}|ã¯ã€\Lcount{COUNTER}ã®å€¤ã‚’
+% 漢数字ã§å‡ºåŠ›ã—ã¾ã™ã€‚
+%
+% |\rensuji{|\meta{obj}|}|ã¯ã€\meta{obj}を横ã«ä¸¦ã¹ã¦å‡ºåŠ›ã—ã¾ã™ã€‚
+% ã—ãŸãŒã£ã¦ã€æ¨ªçµ„ã®ã¨ãã«ã¯ã€ä½•ã‚‚影響ã—ã¾ã›ã‚“。
+%
+% \begin{macrocode}
+%<*tate>
+\renewcommand{\thepart}{\rensuji{\@Roman\c@part}}
+%<article>\renewcommand{\thesection}{\rensuji{\@arabic\c@section}}
+%<*report|book>
+\renewcommand{\thechapter}{\rensuji{\@arabic\c@chapter}}
+\renewcommand{\thesection}{\thechapter・\rensuji{\@arabic\c@section}}
+%</report|book>
+\renewcommand{\thesubsection}{\thesection・\rensuji{\@arabic\c@subsection}}
+\renewcommand{\thesubsubsection}{%
+ \thesubsection・\rensuji{\@arabic\c@subsubsection}}
+\renewcommand{\theparagraph}{%
+ \thesubsubsection・\rensuji{\@arabic\c@paragraph}}
+\renewcommand{\thesubparagraph}{%
+ \theparagraph・\rensuji{\@arabic\c@subparagraph}}
+%</tate>
+%<*yoko>
+\renewcommand{\thepart}{\@Roman\c@part}
+%<article>\renewcommand{\thesection}{\@arabic\c@section}
+%<*report|book>
+\renewcommand{\thechapter}{\@arabic\c@chapter}
+\renewcommand{\thesection}{\thechapter.\@arabic\c@section}
+%</report|book>
+\renewcommand{\thesubsection}{\thesection.\@arabic\c@subsection}
+\renewcommand{\thesubsubsection}{%
+ \thesubsection.\@arabic\c@subsubsection}
+\renewcommand{\theparagraph}{%
+ \thesubsubsection.\@arabic\c@paragraph}
+\renewcommand{\thesubparagraph}{%
+ \theparagraph.\@arabic\c@subparagraph}
+%</yoko>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@chapapp}
+% \begin{macro}{\@chappos}
+% |\@chapapp|ã®åˆæœŸå€¤ã¯`|\prechaptername|'ã§ã™ã€‚
+%
+% |\@chappos|ã®åˆæœŸå€¤ã¯`|\postchaptername|'ã§ã™ã€‚
+%
+% |\appendix|コマンドã¯|\@chapapp|ã‚’`|\appendixname|'ã«ã€
+% |\@chappos|を空ã«å†å®šç¾©ã—ã¾ã™ã€‚
+% \begin{macrocode}
+%<*report|book>
+\newcommand{\@chapapp}{\prechaptername}
+\newcommand{\@chappos}{\postchaptername}
+%</report|book>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{å‰ä»˜ã‘ã€æœ¬æ–‡ã€å¾Œä»˜ã‘}
+%
+% \begin{macro}{\frontmatter}
+% \begin{macro}{\mainmatter}
+% \begin{macro}{\backmatter}
+% \changes{v1.1}{1997/01/15}{\cs{frontmatter}, \cs{mainmatter}, \cs{backmatter}
+% ã‚’\LaTeX{}ã®å®šç¾©ã«ä¿®æ­£}
+% 一冊ã®æœ¬ã¯è«–ç†çš„ã«ï¼“ã¤ã«åˆ†å‰²ã•ã‚Œã¾ã™ã€‚
+% 表題や目次や「ã¯ã˜ã‚ã«ã€ã‚ã‚‹ã„ã¯æ¨©åˆ©ãªã©ã®å‰ä»˜ã‘ã€
+% ãã—ã¦æœ¬æ–‡ã€ãã‚Œã‹ã‚‰ç”¨èªžé›†ã‚„索引や奥付ã‘ãªã©ã®å¾Œä»˜ã‘ã§ã™ã€‚
+%
+% \emph{日本語\TeX{}開発コミュニティã«ã‚ˆã‚‹è£œè¶³}:
+% \LaTeX{}ã®classes.dtxã¯ã€1996/05/26 (v1.3r)ã¨1998/05/05 (v1.3y)ã®
+% 計2回ã€|\frontmatter|ã¨|\mainmatter|ã®å®šç¾©ã‚’修正ã—ã¦ã„ã¾ã™ã€‚一回目ã¯
+% ã“れらã®å‘½ä»¤ã‚’|openany|オプションã«å¿œã˜ã¦åˆ‡ã‚Šæ›¿ãˆã€äºŒå›žç›®ã¯ãれを
+% å…ƒã«æˆ»ã—ã¦ã„ã¾ã™ã€‚アスキーã«ã‚ˆã‚‹jclasses.dtxã¯ã€1997/01/15ã«
+% 一回目ã®ä¿®æ­£ã«è¿½éšã—ã¾ã—ãŸãŒã€äºŒå›žç›®ã®ä¿®æ­£ã«ã¯è¿½éšã—ã¦ã„ã¾ã›ã‚“。
+% コミュニティ版ã§ã¯ã€ä¸€æ—¦ã¯ã‚¢ã‚¹ã‚­ãƒ¼ã«ã‚ˆã‚‹ä»•æ§˜ã‚’維æŒã—よã†ã¨è€ƒãˆ
+% ã¾ã—ãŸ(2016/11/22)ãŒã€ä»¥ä¸‹ã®ç†ç”±ã«ã‚ˆã‚ŠäºŒå›žç›®ã®ä¿®æ­£ã«ã‚‚追éšã™ã‚‹
+% ã“ã¨ã«ã—ã¾ã—ãŸ(2017/03/05)。
+%
+% アスキー版ã§ã®|\frontmatter|ã¨|\mainmatter|ã®æ”¹ãƒšãƒ¼ã‚¸æŒ™å‹•ã¯
+%\begin{quote}
+% |openright|ãªã‚‰|\cleardoublepage|ã€|openany|ãªã‚‰|\clearpage|を実行
+%\end{quote}
+% ã¨ã„ã†ã‚‚ã®ã§ã—ãŸã€‚ã—ã‹ã—ã€|\frontmatter|åŠã³|\mainmatter|ã¯ãƒŽãƒ³ãƒ–ルを
+% 1ã«ãƒªã‚»ãƒƒãƒˆã—ã¾ã™ã‹ã‚‰ã€æ”¹ãƒšãƒ¼ã‚¸ã®çµæžœãŒå¶æ•°ãƒšãƒ¼ã‚¸ç›®ã«ãªã‚‹å ´åˆ
+% \footnote{縦tbookã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆ(openright)ãŒè©²å½“ã™ã‚‹ã»ã‹ã€æ¨ªjbookã¨
+% 縦tbookã®openanyã®ã¨ãã«ã¯æˆã‚Šè¡Œã次第ã§è©²å½“ã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚}ã«
+% ノンブルãŒå¶å¥‡é€†è»¢ã—ã¦ã—ã¾ã„ã¾ã—ãŸã€‚ã“ã®ã¾ã¾ã§ã¯|openany|ã®å ´åˆã«ä¸¡é¢
+% å°åˆ·ãŒã†ã¾ãã„ã‹ãªã„ãŸã‚ã€æ–°ã—ã„コミュニティ版ã§ã¯
+%\begin{quote}
+% å¿…ãš|\pltx@cleartooddpage|を実行
+%\end{quote}
+% ã¨ã—ã¾ã—ãŸã€‚ã“ã‚Œã¯ä¸¡é¢å°åˆ·(twoside)ã®å ´åˆã¯å¥‡æ•°ãƒšãƒ¼ã‚¸ã«é€ã‚Šã€
+% 片é¢å°åˆ·(oneside)ã®å ´åˆã¯å˜ã«æ”¹ãƒšãƒ¼ã‚¸ã¨ãªã‚Šã¾ã™ã€‚(å‚考:latex/2754)
+% \changes{v1.7b}{2016/11/22}{補足ドキュメントを追加}
+% \changes{v1.7e}{2017/03/05}{\cs{frontmatter}ã¨\cs{mainmatter}ã‚’
+% 奇数ページã«é€ã‚‹ã‚ˆã†ã«å¤‰æ›´}
+% \begin{macrocode}
+%<*book>
+\newcommand{\frontmatter}{%
+ \pltx@cleartooddpage
+ \@mainmatterfalse\pagenumbering{roman}}
+\newcommand{\mainmatter}{%
+ \pltx@cleartooddpage
+ \@mainmattertrue\pagenumbering{arabic}}
+\newcommand{\backmatter}{%
+ \if@openleft \cleardoublepage \else
+ \if@openright \cleardoublepage \else \clearpage \fi \fi
+ \@mainmatterfalse}
+%</book>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{ボックスã®çµ„ã¿ç«‹ã¦}
+% クラスファイル定義ã®ã€ã“ã®éƒ¨åˆ†ã§ã¯ã€|\@startsection|ã¨|\secdef|ã®
+% 二ã¤ã®å†…部マクロを使ã„ã¾ã™ã€‚ã“れらã®æ§‹æ–‡ã‚’次ã«ç¤ºã—ã¾ã™ã€‚
+%
+% |\@startsection|マクロã¯ï¼–ã¤ã®å¼•æ•°ã¨ï¼‘ã¤ã®ã‚ªãƒ—ション引数`*'ã‚’å–ã‚Šã¾ã™ã€‚
+%
+% |\@startsection|\meta{name}\meta{level}\meta{indent}^^A
+% \meta{beforeskip}\meta{afterskip}\meta{style}
+% optional *\\
+% \null\hphantom{\bslash @startsection}^^A
+% |[|\meta{altheading}|]|\meta{heading}
+%
+% ãã‚Œãžã‚Œã®å¼•æ•°ã®æ„味ã¯ã€æ¬¡ã®ã¨ãŠã‚Šã§ã™ã€‚
+%
+% \begin{description}
+% \item[\meta{name}] レベルコマンドã®åå‰ã§ã™ï¼ˆä¾‹:section)。
+% \item[\meta{level}] 見出ã—ã®æ·±ã•ã‚’示ã™æ•°å€¤ã§ã™ï¼ˆchapter=1, section=2,
+% $\ldots$)。``\meta{level}$<=$カウンタ\Lcount{secnumdepth}ã®å€¤''ã®ã¨ãã€
+% 見出ã—番å·ãŒå‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+% \item[\meta{indent}] 見出ã—ã«å¯¾ã™ã‚‹ã€å·¦ãƒžãƒ¼ã‚¸ãƒ³ã‹ã‚‰ã®ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆé‡ã§ã™ã€‚
+% \item[\meta{beforeskip}] 見出ã—ã®ä¸Šã«ç½®ã‹ã‚Œã‚‹ç©ºç™½ã®çµ¶å¯¾å€¤ã§ã™ã€‚
+% è² ã®å ´åˆã¯ã€è¦‹å‡ºã—ã«ç¶šãテキストã®ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã‚’抑制ã—ã¾ã™ã€‚
+% \item[\meta{afterskip}] æ­£ã®ã¨ãã€è¦‹å‡ºã—ã®å¾Œã®åž‚ç›´æ–¹å‘ã®ã‚¹ãƒšãƒ¼ã‚¹ã¨ãªã‚Šã¾ã™ã€‚
+% è² ã®å ´åˆã¯ã€è¦‹å‡ºã—ã®å¾Œã®æ°´å¹³æ–¹å‘ã®ã‚¹ãƒšãƒ¼ã‚¹ã¨ãªã‚Šã¾ã™ã€‚
+% \item[\meta{style}] 見出ã—ã®ã‚¹ã‚¿ã‚¤ãƒ«ã‚’設定ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚
+% \item[\meta{$*$}] 見出ã—番å·ã‚’付ã‘ãªã„ã¨ãã€å¯¾å¿œã™ã‚‹ã‚«ã‚¦ãƒ³ã‚¿ã¯å¢—加ã—ã¾ã™ã€‚
+% \item[\meta{heading}] æ–°ã—ã„見出ã—ã®æ–‡å­—列ã§ã™ã€‚
+% \end{description}
+%
+% 見出ã—コマンドã¯é€šå¸¸ã€|\@startsection|ã¨ï¼–ã¤ã®å¼•æ•°ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+%
+% |\secdef|マクロã¯ã€
+% 見出ã—コマンドを|\@startsection|を用ã„ãªã„ã§å®šç¾©ã™ã‚‹ã¨ãã«ä½¿ã„ã¾ã™ã€‚
+% ã“ã®ãƒžã‚¯ãƒ­ã¯ã€ï¼’ã¤ã®å¼•æ•°ã‚’æŒã¡ã¾ã™ã€‚
+%
+% |\secdef|\meta{unstarcmds}\meta{starcmds}
+%
+% \begin{description}
+% \item[\meta{unstarcmds}] 見出ã—コマンドã®æ™®é€šã®å½¢å¼ã§ä½¿ã‚ã‚Œã¾ã™ã€‚
+% \item[\meta{starcmds}] $*$å½¢å¼ã®è¦‹å‡ºã—コマンドã§ä½¿ã‚ã‚Œã¾ã™ã€‚
+% \end{description}
+%
+% |\secdef|ã¯æ¬¡ã®ã‚ˆã†ã«ã—ã¦ä½¿ã†ã“ã¨ãŒã§ãã¾ã™ã€‚
+%\begin{verbatim}
+% \def\chapter {... \secdef \CMDA \CMDB }
+% \def\CMDA [#1]#2{....} % \chapter[...]{...} ã®å®šç¾©
+% \def\CMDB #1{....} % \chapter*{...} ã®å®šç¾©
+%\end{verbatim}
+%
+%
+% \subsubsection{partレベル}
+%
+% \begin{macro}{\part}
+% ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ã€æ–°ã—ã„パート(部)をã¯ã˜ã‚ã¾ã™ã€‚
+%
+% articleクラスã®å ´åˆã¯ã€ç°¡å˜ã§ã™ã€‚
+%
+% æ–°ã—ã„段è½ã‚’開始ã—ã€å°ã•ãªç©ºç™½ã‚’入れã€æ®µè½å¾Œã®ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã‚’è¡Œã„ã€
+% |\secdef|ã§ä½œæˆã—ã¾ã™ã€‚(アスキーã«ã‚ˆã‚‹å…ƒã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã«ã¯
+% 「段è½å¾Œã®ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã‚’ã—ãªã„よã†ã«ã—ã€ã¨æ›¸ã‹ã‚Œã¦ã„ã¾ã—ãŸãŒã€
+% 実際ã®ã‚³ãƒ¼ãƒ‰ã§ã¯æ®µè½å¾Œã®ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã‚’è¡Œã£ã¦ã„ã¾ã—ãŸã€‚ãã“ã§
+% 日本語\TeX{}開発コミュニティã¯ã€ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’コードã«åˆã‚ã›ã¦
+% 「段è½å¾Œã®ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã‚’è¡Œã„ã€ã¸ã¨ä¿®æ­£ã—ã¾ã—ãŸã€‚)
+% \changes{v1.7a}{2016/11/16}{Check \texttt{@noskipsec} switch and
+% possibly force horizontal mode (sync with classes.dtx v1.4a)}
+% \begin{macrocode}
+%<*article>
+\newcommand{\part}{%
+ \if@noskipsec \leavevmode \fi
+ \par\addvspace{4ex}%
+ \@afterindenttrue
+ \secdef\@part\@spart}
+%</article>
+% \end{macrocode}
+% reportã¨bookスタイルã®å ´åˆã¯ã€å°‘ã—複雑ã§ã™ã€‚
+%
+% ã¾ãšã€å³ãƒšãƒ¼ã‚¸ã‹ã‚‰ã¯ã˜ã¾ã‚‹ã‚ˆã†ã«æ”¹ãƒšãƒ¼ã‚¸ã‚’ã—ã¾ã™ã€‚
+% ãã—ã¦ã€éƒ¨æ‰‰ã®ãƒšãƒ¼ã‚¸ã‚¹ã‚¿ã‚¤ãƒ«ã‚’\pstyle{empty}ã«ã—ã¾ã™ã€‚
+% 2段組ã®å ´åˆã§ã‚‚ã€ï¼‘段組ã§ä½œæˆã—ã¾ã™ãŒã€å¾Œã»ã©ï¼’段組ã«æˆ»ã™ãŸã‚ã«ã€
+% |\@restonecol|スイッãƒã‚’使ã„ã¾ã™ã€‚
+% \changes{v1.1}{1997/01/15}{\cs{part}ã‚’\LaTeX\ ã®å®šç¾©ã«ä¿®æ­£}
+% \begin{macrocode}
+%<*report|book>
+\newcommand{\part}{%
+ \if@openleft \cleardoublepage \else
+ \if@openright \cleardoublepage \else \clearpage \fi \fi
+ \thispagestyle{empty}%
+ \if@twocolumn\onecolumn\@tempswatrue\else\@tempswafalse\fi
+ \null\vfil
+ \secdef\@part\@spart}
+%</report|book>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@part}
+% ã“ã®ãƒžã‚¯ãƒ­ãŒå®Ÿéš›ã«éƒ¨ãƒ¬ãƒ™ãƒ«ã®è¦‹å‡ºã—を作æˆã—ã¾ã™ã€‚
+% ã“ã®ãƒžã‚¯ãƒ­ã‚‚文書クラスã«ã‚ˆã£ã¦å®šç¾©ãŒç•°ãªã‚Šã¾ã™ã€‚
+%
+% articleクラスã®å ´åˆã¯ã€\Lcount{secnumdepth}ãŒ$-1$よりも大ãã„ã¨ãã€
+% 見出ã—番å·ã‚’付ã‘ã¾ã™ã€‚ã“ã®ã‚«ã‚¦ãƒ³ã‚¿ãŒ$-1$以下ã®å ´åˆã«ã¯ä»˜ã‘ã¾ã›ã‚“。
+% \changes{v1.7a}{2016/11/16}{replace \cs{reset@font} with
+% \cs{normalfont} (sync with classes.dtx v1.3c)}
+% \begin{macrocode}
+%<*article>
+\def\@part[#1]#2{%
+ \ifnum \c@secnumdepth >\m@ne
+ \refstepcounter{part}%
+ \addcontentsline{toc}{part}{%
+ \prepartname\thepart\postpartname\hspace{1\zw}#1}%
+ \else
+ \addcontentsline{toc}{part}{#1}%
+ \fi
+ \markboth{}{}%
+ {\parindent\z@\raggedright
+ \interlinepenalty\@M\normalfont
+ \ifnum \c@secnumdepth >\m@ne
+ \Large\bfseries\prepartname\thepart\postpartname
+ \par\nobreak
+ \fi
+ \huge\bfseries#2\par}%
+ \nobreak\vskip3ex\@afterheading}
+%</article>
+% \end{macrocode}
+%
+% reportã¨bookクラスã®å ´åˆã¯ã€\Lcount{secnumdepth}ãŒ$-2$よりも大ãã„ã¨ãã«ã€
+% 見出ã—番å·ã‚’付ã‘ã¾ã™ã€‚$-2$以下ã§ã¯ä»˜ã‘ã¾ã›ã‚“。
+%
+% \begin{macrocode}
+%<*report|book>
+\def\@part[#1]#2{%
+ \ifnum \c@secnumdepth >-2\relax
+ \refstepcounter{part}%
+ \addcontentsline{toc}{part}{%
+ \prepartname\thepart\postpartname\hspace{1em}#1}%
+ \else
+ \addcontentsline{toc}{part}{#1}%
+ \fi
+ \markboth{}{}%
+ {\centering
+ \interlinepenalty\@M\normalfont
+ \ifnum \c@secnumdepth >-2\relax
+ \huge\bfseries\prepartname\thepart\postpartname
+ \par\vskip20\p@
+ \fi
+ \Huge\bfseries#2\par}%
+ \@endpart}
+%</report|book>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@spart}
+% ã“ã®ãƒžã‚¯ãƒ­ã¯ã€ç•ªå·ã‚’付ã‘ãªã„ã¨ãã®ä½“è£ã§ã™ã€‚
+% \changes{v1.7a}{2016/11/16}{replace \cs{reset@font} with
+% \cs{normalfont} (sync with classes.dtx v1.3c)}
+% \begin{macrocode}
+%<*article>
+\def\@spart#1{{%
+ \parindent\z@\raggedright
+ \interlinepenalty\@M\normalfont
+ \huge\bfseries#1\par}%
+ \nobreak\vskip3ex\@afterheading}
+%</article>
+% \end{macrocode}
+% \changes{v1.1k}{1998/03/23}{reportã¨bookクラスã§ç•ªå·ã‚’付ã‘ãªã„見出ã—ã®
+% ペナルティãŒ\cs{M@}ã ã£ãŸã®ã‚’\cs{@M}ã«ä¿®æ­£}
+% \begin{macrocode}
+%<*report|book>
+\def\@spart#1{{%
+ \centering
+ \interlinepenalty\@M\normalfont
+ \Huge\bfseries#1\par}%
+ \@endpart}
+%</report|book>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@endpart}
+% |\@part|ã¨|\@spart|ã®æœ€å¾Œã§å®Ÿè¡Œã•ã‚Œã‚‹ãƒžã‚¯ãƒ­ã§ã™ã€‚
+% 両é¢å°åˆ·ãƒ¢ãƒ¼ãƒ‰ã®ã¨ãã¯ã€ç™½ãƒšãƒ¼ã‚¸ã‚’追加ã—ã¾ã™ã€‚
+% 二段組モードã®ã¨ãã«ã¯ã€ã“れ以é™ã®ãƒšãƒ¼ã‚¸ã‚’二段組ã«æˆ»ã—ã¾ã™ã€‚
+% 2016å¹´12月ã‹ã‚‰ã€|openany| ã®ã¨ãã«ç™½ãƒšãƒ¼ã‚¸ã‚’追加ã™ã‚‹ã®ã‚’ã‚„ã‚ã¾ã—ãŸã€‚
+% ã“ã®ãƒã‚°ã¯\LaTeX{}ã§ã¯classes.dtx v1.4b (2000/05/19)ã§ä¿®æ­£ã•ã‚Œã¦ã„ã¾ã—ãŸã€‚
+% (å‚考:latex/3155ã€texjporg/jsclasses\#48)
+% \changes{v1.7c}{2016/12/18}{Only add empty page after part if
+% twoside and openright (sync with classes.dtx v1.4b)}
+% \begin{macrocode}
+%<*report|book>
+\def\@endpart{\vfil\newpage
+ \if@twoside
+ \if@openleft %% \if@openleft added (2017/02/15)
+ \null\thispagestyle{empty}\newpage
+ \else\if@openright %% \if@openright added (2016/12/18)
+ \null\thispagestyle{empty}\newpage
+ \fi\fi %% added (2016/12/18, 2017/02/15)
+ \fi
+% \end{macrocode}
+% 二段組文書ã®ã¨ãã€ã‚¹ã‚¤ãƒƒãƒã‚’二段組モードã«æˆ»ã™å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+% \begin{macrocode}
+ \if@tempswa\twocolumn\fi}
+%</report|book>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{chapterレベル}
+%
+% \begin{macro}{chapter}
+% 章レベルã¯ã€å¿…ãšãƒšãƒ¼ã‚¸ã®å…ˆé ­ã‹ã‚‰é–‹å§‹ã—ã¾ã™ã€‚
+% |openright|オプションãŒæŒ‡å®šã•ã‚Œã¦ã„ã‚‹å ´åˆã¯ã€å³ãƒšãƒ¼ã‚¸ã‹ã‚‰ã¯ã˜ã¾ã‚‹
+% よã†ã«|\cleardoublepage|を呼ã³å‡ºã—ã¾ã™ã€‚
+% ãã†ã§ãªã‘ã‚Œã°ã€|\clearpage|を呼ã³å‡ºã—ã¾ã™ã€‚
+% ãªãŠã€ç¸¦çµ„ã®å ´åˆã§ã‚‚å³ãƒšãƒ¼ã‚¸ã‹ã‚‰ã¯ã˜ã¾ã‚‹ã‚ˆã†ã«ã€
+% フォーマットファイルã§|\clerdoublepage|ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+%
+% \emph{日本語\TeX{}開発コミュニティã«ã‚ˆã‚‹è£œè¶³}:コミュニティ版ã®å®Ÿè£…ã§ã¯ã€
+% |openright|ã¨|openleft|ã®å ´åˆã«|\cleardoublepage|をクラスファイルã®ä¸­ã§
+% å†ã€…定義ã—ã¦ã„ã¾ã™ã€‚\ref{sec:cleardoublepage}ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+%
+% 章見出ã—ãŒå‡ºåŠ›ã•ã‚Œã‚‹ãƒšãƒ¼ã‚¸ã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯ã€\pstyle{jpl@in}ã«ãªã‚Šã¾ã™ã€‚
+% \pstyle{jpl@in}ã¯ã€\pstyle{headnomble}ã‹\pstyle{footnomble}ã®ã„ãšã‚Œã‹ã§ã™ã€‚
+% 詳細ã¯ã€ç¬¬\ref{sec:pagestyle}節をå‚ç…§ã—ã¦ãã ã•ã„。
+%
+% ã¾ãŸã€|\@topnum|をゼロã«ã—ã¦ã€
+% 章見出ã—ã®ä¸Šã«ãƒˆãƒƒãƒ—フロートãŒç½®ã‹ã‚Œãªã„よã†ã«ã—ã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+%<*report|book>
+\newcommand{\chapter}{%
+ \if@openleft \cleardoublepage \else
+ \if@openright \cleardoublepage \else \clearpage \fi \fi
+ \thispagestyle{jpl@in}%
+ \global\@topnum\z@
+ \@afterindenttrue
+ \secdef\@chapter\@schapter}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@chapter}
+% ã“ã®ãƒžã‚¯ãƒ­ã¯ã€ç« è¦‹å‡ºã—ã«ç•ªå·ã‚’付ã‘ã‚‹ã¨ãã«å‘¼ã³å‡ºã•ã‚Œã¾ã™ã€‚
+% \Lcount{secnumdepth}ãŒ$-1$よりも大ããã€
+% |\@mainmatter|ãŒçœŸï¼ˆbookクラスã®å ´åˆï¼‰ã®ã¨ãã«ã€ç•ªå·ã‚’出力ã—ã¾ã™ã€‚
+%
+% \emph{日本語\TeX{}開発コミュニティã«ã‚ˆã‚‹è£œè¶³}:本家\LaTeX{}ã®
+% \file{classes}ã§ã¯ã€äºŒæ®µçµ„ã®ã¨ããƒãƒ£ãƒ—タータイトルã¯ä¸€æ®µçµ„ã«æˆ»ã•ã‚Œ
+% ã¾ã™ãŒã€ã‚¢ã‚¹ã‚­ãƒ¼ã«ã‚ˆã‚‹\file{jclasses}ã§ã¯äºŒæ®µçµ„ã®ã¾ã¾ã«ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% ã—ãŸãŒã£ã¦ã€ãƒãƒ£ãƒ—タータイトルより高ã„ä½ç½®ã«å³ã‚«ãƒ©ãƒ ã®å§‹ç‚¹ãŒæ¥ã‚‹ã¨ã„ã†
+% 挙動ã«ãªã£ã¦ã„ã¾ã™ãŒã€ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ç‰ˆã§ã‚‚アスキー版ã®æŒ™å‹•ã‚’維æŒã—ã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+\def\@chapter[#1]#2{%
+ \ifnum \c@secnumdepth >\m@ne
+%<book> \if@mainmatter
+ \refstepcounter{chapter}%
+ \typeout{\@chapapp\space\thechapter\space\@chappos}%
+ \addcontentsline{toc}{chapter}%
+ {\protect\numberline{\@chapapp\thechapter\@chappos}#1}%
+%<book> \else\addcontentsline{toc}{chapter}{#1}\fi
+ \else
+ \addcontentsline{toc}{chapter}{#1}%
+ \fi
+ \chaptermark{#1}%
+ \addtocontents{lof}{\protect\addvspace{10\p@}}%
+ \addtocontents{lot}{\protect\addvspace{10\p@}}%
+ \@makechapterhead{#2}\@afterheading}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@makechapterhead}
+% ã“ã®ãƒžã‚¯ãƒ­ãŒå®Ÿéš›ã«ç« è¦‹å‡ºã—を組ã¿ç«‹ã¦ã¾ã™ã€‚
+% \changes{v1.1o}{1998/12/24}{secnumdepthカウンタを$-1$以下ã«ã™ã‚‹ã¨ã€
+% 見出ã—文字列も消ãˆã¦ã—ã¾ã†ã®ã‚’修正}
+% \changes{v1.2}{2001/09/04}{\cs{chapter}ã®å‡ºåŠ›ä½ç½®ãŒã‚¢ã‚¹ã‚¿ãƒªã‚¹ã‚¯å½¢å¼ã¨
+% ãã†ã§ãªã„ã¨ãã¨é•ã†ã®ã‚’修正(ã‚ã‚ŠãŒã¨ã†ã€éˆ´æœ¨ï¼ æ´¥ã•ã‚“)}
+% \changes{v1.7a}{2016/11/16}{replace \cs{reset@font} with
+% \cs{normalfont} (sync with classes.dtx v1.3c)}
+% \begin{macrocode}
+\def\@makechapterhead#1{\hbox{}%
+ \vskip2\Cvs
+ {\parindent\z@
+ \raggedright
+ \normalfont\huge\bfseries
+ \leavevmode
+ \ifnum \c@secnumdepth >\m@ne
+ \setlength\@tempdima{\linewidth}%
+%<book> \if@mainmatter
+ \setbox\z@\hbox{\@chapapp\thechapter\@chappos\hskip1\zw}%
+ \addtolength\@tempdima{-\wd\z@}%
+ \unhbox\z@\nobreak
+%<book> \fi
+ \vtop{\hsize\@tempdima#1}%
+ \else
+ #1\relax
+ \fi}\nobreak\vskip3\Cvs}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@schapter}
+% ã“ã®ãƒžã‚¯ãƒ­ã¯ã€ç« è¦‹å‡ºã—ã«ç•ªå·ã‚’付ã‘ãªã„ã¨ãã«å‘¼ã³å‡ºã•ã‚Œã¾ã™ã€‚
+%
+% \emph{日本語\TeX{}開発コミュニティã«ã‚ˆã‚‹è£œè¶³}:やã¯ã‚ŠäºŒæ®µçµ„ã§ãƒãƒ£ãƒ—ター
+% タイトルより高ã„ä½ç½®ã«å³ã‚«ãƒ©ãƒ ã®å§‹ç‚¹ãŒæ¥ã‚‹ã¨ã„ã†æŒ™å‹•ã‚’維æŒã—ã¦ã‚ã‚Šã¾ã™ã€‚
+% \changes{v1.7c}{2016/12/18}{奇妙ãªarticleガードã¨ã‚³ãƒ¼ãƒ‰ã‚’削除ã—ã¦
+% ドキュメントを追加}
+% \begin{macrocode}
+\def\@schapter#1{%
+ \@makeschapterhead{#1}\@afterheading
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@makeschapterhead}
+% 番å·ã‚’付ã‘ãªã„å ´åˆã®å½¢å¼ã§ã™ã€‚
+% \changes{v1.2}{2001/09/04}{\cs{chapter}ã®å‡ºåŠ›ä½ç½®ãŒã‚¢ã‚¹ã‚¿ãƒªã‚¹ã‚¯å½¢å¼ã¨
+% ãã†ã§ãªã„ã¨ãã¨é•ã†ã®ã‚’修正(ã‚ã‚ŠãŒã¨ã†ã€éˆ´æœ¨ï¼ æ´¥ã•ã‚“)}
+% \changes{v1.7a}{2016/11/16}{replace \cs{reset@font} with
+% \cs{normalfont} (sync with classes.dtx v1.3c)}
+% \begin{macrocode}
+\def\@makeschapterhead#1{\hbox{}%
+ \vskip2\Cvs
+ {\parindent\z@
+ \raggedright
+ \normalfont\huge\bfseries
+ \leavevmode
+ \setlength\@tempdima{\linewidth}%
+ \vtop{\hsize\@tempdima#1}}\vskip3\Cvs}
+%</report|book>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{下ä½ãƒ¬ãƒ™ãƒ«ã®è¦‹å‡ºã—}
+%
+% \begin{macro}{\section}
+% 見出ã—ã®å‰å¾Œã«ç©ºç™½ã‚’付ã‘ã€|\Large\bfseries|ã§å‡ºåŠ›ã‚’ã—ã¾ã™ã€‚
+% \changes{v1.7a}{2016/11/16}{replace \cs{reset@font} with
+% \cs{normalfont} (sync with classes.dtx v1.3c)}
+% \begin{macrocode}
+\newcommand{\section}{\@startsection{section}{1}{\z@}%
+ {1.5\Cvs \@plus.5\Cvs \@minus.2\Cvs}%
+ {.5\Cvs \@plus.3\Cvs}%
+ {\normalfont\Large\bfseries}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\subsection}
+% 見出ã—ã®å‰å¾Œã«ç©ºç™½ã‚’付ã‘ã€|\large\bfseries|ã§å‡ºåŠ›ã‚’ã—ã¾ã™ã€‚
+% \changes{v1.7a}{2016/11/16}{replace \cs{reset@font} with
+% \cs{normalfont} (sync with classes.dtx v1.3c)}
+% \begin{macrocode}
+\newcommand{\subsection}{\@startsection{subsection}{2}{\z@}%
+ {1.5\Cvs \@plus.5\Cvs \@minus.2\Cvs}%
+ {.5\Cvs \@plus.3\Cvs}%
+ {\normalfont\large\bfseries}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\subsubsection}
+% 見出ã—ã®å‰å¾Œã«ç©ºç™½ã‚’付ã‘ã€|\normalsize\bfseries|ã§å‡ºåŠ›ã‚’ã—ã¾ã™ã€‚
+% \changes{v1.7a}{2016/11/16}{replace \cs{reset@font} with
+% \cs{normalfont} (sync with classes.dtx v1.3c)}
+% \begin{macrocode}
+\newcommand{\subsubsection}{\@startsection{subsubsection}{3}{\z@}%
+ {1.5\Cvs \@plus.5\Cvs \@minus.2\Cvs}%
+ {.5\Cvs \@plus.3\Cvs}%
+ {\normalfont\normalsize\bfseries}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\paragraph}
+% 見出ã—ã®å‰ã«ç©ºç™½ã‚’付ã‘ã€|\normalsize\bfseries|ã§å‡ºåŠ›ã‚’ã—ã¾ã™ã€‚
+% 見出ã—ã®å¾Œã‚ã§æ”¹è¡Œã•ã‚Œã¾ã›ã‚“。
+% \changes{v1.7a}{2016/11/16}{replace \cs{reset@font} with
+% \cs{normalfont} (sync with classes.dtx v1.3c)}
+% \begin{macrocode}
+\newcommand{\paragraph}{\@startsection{paragraph}{4}{\z@}%
+ {3.25ex \@plus 1ex \@minus .2ex}%
+ {-1em}%
+ {\normalfont\normalsize\bfseries}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\subparagraph}
+% 見出ã—ã®å‰ã«ç©ºç™½ã‚’付ã‘ã€|\normalsize\bfseries|ã§å‡ºåŠ›ã‚’ã—ã¾ã™ã€‚
+% 見出ã—ã®å¾Œã‚ã§æ”¹è¡Œã•ã‚Œã¾ã›ã‚“。
+% \changes{v1.7a}{2016/11/16}{replace \cs{reset@font} with
+% \cs{normalfont} (sync with classes.dtx v1.3c)}
+% \begin{macrocode}
+\newcommand{\subparagraph}{\@startsection{subparagraph}{5}{\z@}%
+ {3.25ex \@plus 1ex \@minus .2ex}%
+ {-1em}%
+ {\normalfont\normalsize\bfseries}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{付録}
+%
+% \begin{macro}{\appendix}
+% articleクラスã®å ´åˆã€|\appendix|コマンドã¯æ¬¡ã®ã“ã¨ã‚’è¡Œãªã„ã¾ã™ã€‚
+%
+% \begin{itemize}
+% \item \Lcount{section}ã¨\Lcount{subsection}カウンタをリセットã™ã‚‹ã€‚
+% \item |\thesection|を英å°æ–‡å­—ã§å‡ºåŠ›ã™ã‚‹ã‚ˆã†ã«å†å®šç¾©ã™ã‚‹ã€‚
+% \end{itemize}
+%
+% \begin{macrocode}
+%<*article>
+\newcommand{\appendix}{\par
+ \setcounter{section}{0}%
+ \setcounter{subsection}{0}%
+%<tate> \renewcommand{\thesection}{\rensuji{\@Alph\c@section}}}
+%<yoko> \renewcommand{\thesection}{\@Alph\c@section}}
+%</article>
+% \end{macrocode}
+%
+% reportã¨bookクラスã®å ´åˆã€|\appendix|コマンドã¯æ¬¡ã®ã“ã¨ã‚’è¡Œãªã„ã¾ã™ã€‚
+%
+% \begin{itemize}
+% \item \Lcount{chapter}ã¨\Lcount{section}カウンタをリセットã™ã‚‹ã€‚
+% \item |\@chapapp|ã‚’|\appendixname|ã«è¨­å®šã™ã‚‹ã€‚
+% \item |\@chappos|を空ã«ã™ã‚‹ã€‚
+% \item |\thechapter|を英å°æ–‡å­—ã§å‡ºåŠ›ã™ã‚‹ã‚ˆã†ã«å†å®šç¾©ã™ã‚‹ã€‚
+% \end{itemize}
+%
+% \begin{macrocode}
+%<*report|book>
+\newcommand{\appendix}{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \renewcommand{\@chapapp}{\appendixname}%
+ \renewcommand{\@chappos}\space%
+%<tate> \renewcommand{\thechapter}{\rensuji{\@Alph\c@chapter}}}
+%<yoko> \renewcommand{\thechapter}{\@Alph\c@chapter}}
+%</report|book>
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{リスト環境}
+% ã“ã“ã§ã¯ãƒªã‚¹ãƒˆç’°å¢ƒã«ã¤ã„ã¦èª¬æ˜Žã‚’ã—ã¦ã„ã¾ã™ã€‚
+%
+% リスト環境ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯æ¬¡ã®ã‚ˆã†ã«è¨­å®šã•ã‚Œã¾ã™ã€‚
+%
+% ã¾ãšã€|\rigtmargin|, |\listparindent|, |\itemindent|をゼロã«ã—ã¾ã™ã€‚
+% ãã—ã¦ã€K番目ã®ãƒ¬ãƒ™ãƒ«ã®ãƒªã‚¹ãƒˆã¯|\@listK|ã§ç¤ºã•ã‚Œã‚‹ãƒžã‚¯ãƒ­ãŒå‘¼ã³å‡ºã•ã‚Œã¾ã™ã€‚
+% ã“ã“ã§`K'ã¯å°æ–‡å­—ã®ãƒ­ãƒ¼ãƒžæ•°å­—ã§ç¤ºã•ã‚Œã¾ã™ã€‚ãŸã¨ãˆã°ã€ï¼“番目ã®ãƒ¬ãƒ™ãƒ«ã®ãƒªã‚¹ãƒˆ
+% ã¨ã—ã¦|\@listiii|ãŒå‘¼ã³å‡ºã•ã‚Œã¾ã™ã€‚
+% |\@listK|ã¯|\leftmargin|ã‚’|\leftmarginK|ã«è¨­å®šã—ã¾ã™ã€‚
+%
+% \begin{macro}{\leftmargin}
+% \begin{macro}{\leftmargini}
+% \begin{macro}{\leftmarginii}
+% \begin{macro}{\leftmarginiii}
+% \begin{macro}{\leftmarginiv}
+% \begin{macro}{\leftmarginv}
+% \begin{macro}{\leftmarginvi}
+% 二段組モードã®ãƒžãƒ¼ã‚¸ãƒ³ã¯å°‘ã—ã ã‘å°ã•ã設定ã—ã¦ã‚ã‚Šã¾ã™ã€‚
+% \begin{macrocode}
+\if@twocolumn
+ \setlength\leftmargini {2em}
+\else
+ \setlength\leftmargini {2.5em}
+\fi
+% \end{macrocode}
+% 次ã®ï¼“ã¤ã®å€¤ã¯ã€|\labelsep|ã¨ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãƒ©ãƒ™ãƒ«ï¼ˆ`(m)', `vii.', `M.')ã®
+% å¹…ã®åˆè¨ˆã‚ˆã‚Šã‚‚大ããã—ã¦ã‚ã‚Šã¾ã™ã€‚
+% \begin{macrocode}
+\setlength\leftmarginii {2.2em}
+\setlength\leftmarginiii {1.87em}
+\setlength\leftmarginiv {1.7em}
+\if@twocolumn
+ \setlength\leftmarginv {.5em}
+ \setlength\leftmarginvi{.5em}
+\else
+ \setlength\leftmarginv {1em}
+ \setlength\leftmarginvi{1em}
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\labelsep}
+% \begin{macro}{\labelwidth}
+% |\labelsep|ã¯ãƒ©ãƒ™ãƒ«ã¨ãƒ†ã‚­ã‚¹ãƒˆã®é …ç›®ã®é–“ã®è·é›¢ã§ã™ã€‚
+% |\labelwidth|ã¯ãƒ©ãƒ™ãƒ«ã®å¹…ã§ã™ã€‚
+% \begin{macrocode}
+\setlength \labelsep {.5em}
+\setlength \labelwidth{\leftmargini}
+\addtolength\labelwidth{-\labelsep}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@beginparpenalty}
+% \begin{macro}{\@endparpenalty}
+% ã“れらã®ãƒšãƒŠãƒ«ãƒ†ã‚£ã¯ã€ãƒªã‚¹ãƒˆã‚„段è½ç’°å¢ƒã®å‰å¾Œã«æŒ¿å…¥ã•ã‚Œã¾ã™ã€‚
+% \begin{macro}{\@itempenalty}
+% ã“ã®ãƒšãƒŠãƒ«ãƒ†ã‚£ã¯ã€ãƒªã‚¹ãƒˆé …ç›®ã®é–“ã«æŒ¿å…¥ã•ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+\@beginparpenalty -\@lowpenalty
+\@endparpenalty -\@lowpenalty
+\@itempenalty -\@lowpenalty
+%</article|report|book>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\partopsep}
+% リスト環境ã®å‰ã«ç©ºè¡ŒãŒã‚ã‚‹å ´åˆã€|\parskip|ã¨|\topsep|ã«|\partopsep|ãŒ
+% 加ãˆã‚‰ã‚ŒãŸå€¤ã®ç¸¦æ–¹å‘ã®ç©ºç™½ãŒå–られã¾ã™ã€‚
+% \begin{macrocode}
+%<10pt>\setlength\partopsep{2\p@ \@plus 1\p@ \@minus 1\p@}
+%<11pt>\setlength\partopsep{3\p@ \@plus 1\p@ \@minus 1\p@}
+%<12pt>\setlength\partopsep{3\p@ \@plus 2\p@ \@minus 2\p@}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@listi}
+% \begin{macro}{\@listI}
+% |\@listi|ã¯ã€|\leftmargin|, |\parsep|, |\topsep|, |\itemsep|ãªã©ã®
+% トップレベルã®å®šç¾©ã‚’ã—ã¾ã™ã€‚
+% ã“ã®å®šç¾©ã¯ã€ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã‚³ãƒžãƒ³ãƒ‰ã«ã‚ˆã£ã¦å¤‰æ›´ã•ã‚Œã¾ã™ï¼ˆãŸã¨ãˆã°ã€
+% |\small|ã®ä¸­ã§ã¯``å°ã•ã„''リストパラメータã«ãªã‚Šã¾ã™ï¼‰ã€‚
+%
+% ã“ã®ãŸã‚ã€|\normalsize|ãŒã™ã¹ã¦ã®ãƒ‘ラメータを戻ã›ã‚‹ã‚ˆã†ã«ã€
+% |\@listI|ã¯|\@listi|ã®ã‚³ãƒ”ーをä¿å­˜ã™ã‚‹ã‚ˆã†ã«å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+%<*10pt|11pt|12pt>
+\def\@listi{\leftmargin\leftmargini
+%<*10pt>
+ \parsep 4\p@ \@plus2\p@ \@minus\p@
+ \topsep 8\p@ \@plus2\p@ \@minus4\p@
+ \itemsep4\p@ \@plus2\p@ \@minus\p@}
+%</10pt>
+%<*11pt>
+ \parsep 4.5\p@ \@plus2\p@ \@minus\p@
+ \topsep 9\p@ \@plus3\p@ \@minus5\p@
+ \itemsep4.5\p@ \@plus2\p@ \@minus\p@}
+%</11pt>
+%<*12pt>
+ \parsep 5\p@ \@plus2.5\p@ \@minus\p@
+ \topsep 10\p@ \@plus4\p@ \@minus6\p@
+ \itemsep5\p@ \@plus2.5\p@ \@minus\p@}
+%</12pt>
+\let\@listI\@listi
+% \end{macrocode}
+% ã“ã“ã§ã€ãƒ‘ラメータをåˆæœŸåŒ–ã—ã¾ã™ãŒã€åŽ³å¯†ã«ã¯å¿…è¦ã‚ã‚Šã¾ã›ã‚“。
+% \begin{macrocode}
+\@listi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@listii}
+% \begin{macro}{\@listiii}
+% \begin{macro}{\@listiv}
+% \begin{macro}{\@listv}
+% \begin{macro}{\@listvi}
+% 下ä½ãƒ¬ãƒ™ãƒ«ã®ãƒªã‚¹ãƒˆç’°å¢ƒã®ãƒ‘ラメータã®è¨­å®šã§ã™ã€‚
+% ã“れらã¯ä¿å­˜ç”¨ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’æŒãŸãªã„ã“ã¨ã¨ã€
+% フォントサイズコマンドã«ã‚ˆã£ã¦å¤‰æ›´ã•ã‚Œãªã„ã“ã¨ã«æ³¨æ„ã‚’ã—ã¦ãã ã•ã„。
+% 言ã„æ›ãˆã‚Œã°ã€ã“ã®ã‚¯ãƒ©ã‚¹ã¯ã€æœ¬æ–‡ã‚µã‚¤ã‚ºãŒ
+% |\normalsize|ã§ç¾ã‚Œã‚‹ãƒªã‚¹ãƒˆã®å…¥ã‚Œå­ã«ã¤ã„ã¦ã ã‘考ãˆã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+\def\@listii{\leftmargin\leftmarginii
+ \labelwidth\leftmarginii \advance\labelwidth-\labelsep
+%<*10pt>
+ \topsep 4\p@ \@plus2\p@ \@minus\p@
+ \parsep 2\p@ \@plus\p@ \@minus\p@
+%</10pt>
+%<*11pt>
+ \topsep 4.5\p@ \@plus2\p@ \@minus\p@
+ \parsep 2\p@ \@plus\p@ \@minus\p@
+%</11pt>
+%<*12pt>
+ \topsep 5\p@ \@plus2.5\p@ \@minus\p@
+ \parsep 2.5\p@ \@plus\p@ \@minus\p@
+%</12pt>
+ \itemsep\parsep}
+\def\@listiii{\leftmargin\leftmarginiii
+ \labelwidth\leftmarginiii \advance\labelwidth-\labelsep
+%<10pt> \topsep 2\p@ \@plus\p@\@minus\p@
+%<11pt> \topsep 2\p@ \@plus\p@\@minus\p@
+%<12pt> \topsep 2.5\p@\@plus\p@\@minus\p@
+ \parsep\z@
+ \partopsep \p@ \@plus\z@ \@minus\p@
+ \itemsep\topsep}
+\def\@listiv {\leftmargin\leftmarginiv
+ \labelwidth\leftmarginiv
+ \advance\labelwidth-\labelsep}
+\def\@listv {\leftmargin\leftmarginv
+ \labelwidth\leftmarginv
+ \advance\labelwidth-\labelsep}
+\def\@listvi {\leftmargin\leftmarginvi
+ \labelwidth\leftmarginvi
+ \advance\labelwidth-\labelsep}
+%</10pt|11pt|12pt>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsubsection{enumerate環境}
+% enumerate環境ã¯ã€ã‚«ã‚¦ãƒ³ã‚¿\Lcount{enumi}, \Lcount{enumii}, \Lcount{enumiii},
+% \Lcount{enumiv}を使ã„ã¾ã™ã€‚\Lcount{enumN}ã¯N番目ã®ãƒ¬ãƒ™ãƒ«ã®ç•ªå·ã‚’制御ã—ã¾ã™ã€‚
+%
+% \begin{macro}{\theenumi}
+% \begin{macro}{\theenumii}
+% \begin{macro}{\theenumiii}
+% \begin{macro}{\theenumiv}
+% 出力ã™ã‚‹ç•ªå·ã®æ›¸å¼ã‚’設定ã—ã¾ã™ã€‚
+% ã“れらã¯ã€ã™ã§ã«\file{ltlists.dtx}ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+%<*article|report|book>
+%<*tate>
+\renewcommand{\theenumi}{\rensuji{\@arabic\c@enumi}}
+\renewcommand{\theenumii}{\rensuji{(\@alph\c@enumii)}}
+\renewcommand{\theenumiii}{\rensuji{\@roman\c@enumiii}}
+\renewcommand{\theenumiv}{\rensuji{\@Alph\c@enumiv}}
+%</tate>
+%<*yoko>
+\renewcommand{\theenumi}{\@arabic\c@enumi}
+\renewcommand{\theenumii}{\@alph\c@enumii}
+\renewcommand{\theenumiii}{\@roman\c@enumiii}
+\renewcommand{\theenumiv}{\@Alph\c@enumiv}
+%</yoko>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\labelenumi}
+% \begin{macro}{\labelenumii}
+% \begin{macro}{\labelenumiii}
+% \begin{macro}{\labelenumiv}
+% enumerate環境ã®ãã‚Œãžã‚Œã®é …ç›®ã®ãƒ©ãƒ™ãƒ«ã¯ã€
+% |\labelenumi| \ldots\ |\labelenumiv|ã§ç”Ÿæˆã•ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+%<*tate>
+\newcommand{\labelenumi}{\theenumi}
+\newcommand{\labelenumii}{\theenumii}
+\newcommand{\labelenumiii}{\theenumiii}
+\newcommand{\labelenumiv}{\theenumiv}
+%</tate>
+%<*yoko>
+\newcommand{\labelenumi}{\theenumi.}
+\newcommand{\labelenumii}{(\theenumii)}
+\newcommand{\labelenumiii}{\theenumiii.}
+\newcommand{\labelenumiv}{\theenumiv.}
+%</yoko>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\p@enumii}
+% \begin{macro}{\p@enumiii}
+% \begin{macro}{\p@enumiv}
+% |\ref|コマンドã«ã‚ˆã£ã¦ã€
+% enumerate環境ã®N番目ã®ãƒªã‚¹ãƒˆé …ç›®ãŒå‚ç…§ã•ã‚Œã‚‹ã¨ãã®æ›¸å¼ã§ã™ã€‚
+% \begin{macrocode}
+\renewcommand{\p@enumii}{\theenumi}
+\renewcommand{\p@enumiii}{\theenumi(\theenumii)}
+\renewcommand{\p@enumiv}{\p@enumiii\theenumiii}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{environment}{enumerate}
+% \changes{v1.1q}{1999/05/18}{縦組時ã®ã¿ã«è¨­å®šã™ã‚‹ã‚ˆã†ã«ã—ãŸ}
+% トップレベルã§ä½¿ã‚ã‚ŒãŸã¨ãã«ã€æœ€åˆã¨æœ€å¾Œã«åŠè¡Œåˆ†ã®ã‚¹ãƒšãƒ¼ã‚¹ã‚’é–‹ã‘るよã†ã«ã€
+% 変更ã—ã¾ã™ã€‚ã“ã®ç’°å¢ƒã¯ã€\file{ltlists.dtx}ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% \changes{v1.7a}{2016/11/16}{Use \cs{expandafter}
+% (sync with ltlists.dtx v1.0j)}
+%
+% \begin{macrocode}
+\renewenvironment{enumerate}
+ {\ifnum \@enumdepth >\thr@@\@toodeep\else
+ \advance\@enumdepth\@ne
+ \edef\@enumctr{enum\romannumeral\the\@enumdepth}%
+ \expandafter \list \csname label\@enumctr\endcsname{%
+ \ifnum\ltjgetparameter{direction}=3
+ \ifnum \@listdepth=\@ne \topsep.5\normalbaselineskip
+ \else\topsep\z@\fi
+ \parskip\z@ \itemsep\z@ \parsep\z@
+ \labelwidth1\zw \labelsep.3\zw
+ \ifnum \@enumdepth=\@ne \leftmargin1\zw\relax
+ \else\leftmargin\leftskip\fi
+ \advance\leftmargin 1\zw
+ \fi
+ \usecounter{\@enumctr}%
+ \def\makelabel##1{\hss\llap{##1}}}%
+ \fi}{\endlist}
+% \end{macrocode}
+% \end{environment}
+%
+%
+% \subsubsection{itemize環境}
+%
+% \begin{macro}{\labelitemi}
+% \begin{macro}{\labelitemii}
+% \begin{macro}{\labelitemiii}
+% \begin{macro}{\labelitemiv}
+% itemize環境ã®ãã‚Œãžã‚Œã®é …ç›®ã®ãƒ©ãƒ™ãƒ«ã¯ã€
+% |\labelenumi| \ldots\ |\labelenumiv|ã§ç”Ÿæˆã•ã‚Œã¾ã™ã€‚
+% \changes{v1.1a}{1997/01/28}{Bug fix: \cs{labelitemii}.}
+% \begin{macrocode}
+\newcommand{\labelitemi}{\textbullet}
+\newcommand{\labelitemii}{%
+ \ifnum\ltjgetparameter{direction}=3
+ {\textcircled{~}}
+ \else
+ {\normalfont\bfseries\textendash}
+ \fi
+}
+\newcommand{\labelitemiii}{\textasteriskcentered}
+\newcommand{\labelitemiv}{\textperiodcentered}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{environment}{itemize}
+% \changes{v1.0e}{1996/03/14}{縦組時ã®ã¿ã«è¨­å®šã™ã‚‹ã‚ˆã†ã«ã—ãŸ}
+% トップレベルã§ä½¿ã‚ã‚ŒãŸã¨ãã«ã€æœ€åˆã¨æœ€å¾Œã«åŠè¡Œåˆ†ã®ã‚¹ãƒšãƒ¼ã‚¹ã‚’é–‹ã‘るよã†ã«ã€
+% 変更ã—ã¾ã™ã€‚ã“ã®ç’°å¢ƒã¯ã€\file{ltlists.dtx}ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% \changes{v1.7a}{2016/11/16}{Use \cs{expandafter}
+% (sync with ltlists.dtx v1.0j)}
+% \begin{macrocode}
+\renewenvironment{itemize}
+ {\ifnum \@itemdepth >\thr@@\@toodeep\else
+ \advance\@itemdepth\@ne
+ \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}%
+ \expandafter \list \csname \@itemitem\endcsname{%
+ \ifnum\ltjgetparameter{direction}=3
+ \ifnum \@listdepth=\@ne \topsep.5\normalbaselineskip
+ \else\topsep\z@\fi
+ \parskip\z@ \itemsep\z@ \parsep\z@
+ \labelwidth1\zw \labelsep.3\zw
+ \ifnum \@itemdepth =\@ne \leftmargin1\zw\relax
+ \else\leftmargin\leftskip\fi
+ \advance\leftmargin 1\zw
+ \fi
+ \def\makelabel##1{\hss\llap{##1}}}%
+ \fi}{\endlist}
+% \end{macrocode}
+% \end{environment}
+%
+%
+% \subsubsection{description環境}
+%
+% \begin{environment}{description}
+% \changes{v1.0e}{1996/03/14}{\cs{topskip}ã‚„\cs{parkip}ãªã©ã®å€¤ã‚’縦組時ã®ã¿ã«
+% 設定ã™ã‚‹ã‚ˆã†ã«ã—ãŸ}
+% description環境を定義ã—ã¾ã™ã€‚
+% 縦組時ã«ã¯ã€ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆãŒï¼“字分ã ã‘æ·±ããªã‚Šã¾ã™ã€‚
+% \begin{macrocode}
+\newenvironment{description}
+ {\list{}{\labelwidth\z@ \itemindent-\leftmargin
+ \ifnum\ltjgetparameter{direction}=3
+ \leftmargin\leftskip \advance\leftmargin3\Cwd
+ \rightmargin\rightskip
+ \labelsep=1\zw \itemsep\z@
+ \listparindent\z@ \topskip\z@ \parskip\z@ \partopsep\z@
+ \fi
+ \let\makelabel\descriptionlabel}}{\endlist}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\descriptionlabel}
+% ラベルã®å½¢å¼ã‚’変更ã™ã‚‹å¿…è¦ãŒã‚ã‚‹å ´åˆã¯ã€|\descriptionlabel|ã‚’
+% å†å®šç¾©ã—ã¦ãã ã•ã„。
+% \begin{macrocode}
+\newcommand{\descriptionlabel}[1]{%
+ \hspace\labelsep\normalfont\bfseries #1}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{verse環境}
+%
+% \begin{environment}{verse}
+% verse環境ã¯ã€ãƒªã‚¹ãƒˆç’°å¢ƒã®ãƒ‘ラメータを使ã£ã¦å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% 改行をã™ã‚‹ã«ã¯|\\|を用ã„ã¾ã™ã€‚|\\|ã¯|\@centercr|ã«|\let|ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+\newenvironment{verse}
+ {\let\\\@centercr
+ \list{}{\itemsep\z@ \itemindent -1.5em%
+ \listparindent\itemindent
+ \rightmargin\leftmargin \advance\leftmargin 1.5em}%
+ \item\relax}{\endlist}
+% \end{macrocode}
+% \end{environment}
+%
+% \subsubsection{quotation環境}
+%
+% \begin{environment}{quotation}
+% quotation環境もã¾ãŸã€list環境ã®ãƒ‘ラメータを使用ã—ã¦å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% ã“ã®ç’°å¢ƒã®å„è¡Œã¯ã€|\textwidth|よりもå°ã•ã設定ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% ã“ã®ç’°å¢ƒã«ãŠã‘ã‚‹ã€æ®µè½ã®æœ€åˆã®è¡Œã¯ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã•ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+\newenvironment{quotation}
+ {\list{}{\listparindent 1.5em%
+ \itemindent\listparindent
+ \rightmargin\leftmargin
+ \parsep\z@ \@plus\p@}%
+ \item\relax}{\endlist}
+% \end{macrocode}
+% \end{environment}
+%
+% \subsubsection{quote環境}
+%
+% \begin{environment}{quote}
+% quote環境ã¯ã€æ®µè½ãŒã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã•ã‚Œãªã„ã“ã¨ã‚’除ãã€quotation環境ã¨åŒã˜ã§ã™ã€‚
+% \begin{macrocode}
+\newenvironment{quote}
+ {\list{}{\rightmargin\leftmargin}%
+ \item\relax}{\endlist}
+% \end{macrocode}
+% \end{environment}
+%
+%
+%
+% \subsection{フロート}
+%
+% \file{ltfloat.dtx}ã§ã¯ã€ãƒ•ãƒ­ãƒ¼ãƒˆã‚ªãƒ–ジェクトをæ“作ã™ã‚‹ãŸã‚ã®ãƒ„ールã—ã‹
+% 定義ã—ã¦ã„ã¾ã›ã‚“。タイプãŒ\texttt{TYPE}ã®ãƒ•ãƒ­ãƒ¼ãƒˆã‚ªãƒ–ジェクトを
+% 扱ã†ãƒžã‚¯ãƒ­ã‚’定義ã™ã‚‹ã«ã¯ã€æ¬¡ã®å¤‰æ•°ãŒå¿…è¦ã§ã™ã€‚
+%
+% \begin{description}
+% \item[\texttt{\bslash fps@TYPE}]
+% タイプ\texttt{TYPE}ã®ãƒ•ãƒ­ãƒ¼ãƒˆã‚’ç½®ãデフォルトã®ä½ç½®ã§ã™ã€‚
+%
+% \item[\texttt{\bslash ftype@TYPE}]
+% タイプ\texttt{TYPE}ã®ãƒ•ãƒ­ãƒ¼ãƒˆã®ç•ªå·ã§ã™ã€‚
+% å„\texttt{TYPE}ã«ã¯ã€ä¸€æ„ãªã€2ã®å€æ•°ã®\texttt{TYPE}番å·ã‚’割り当ã¦ã¾ã™ã€‚
+% ãŸã¨ãˆã°ã€å›³ãŒç•ªå·1ãªã‚‰ã°ã€è¡¨ã¯2ã§ã™ã€‚次ã®ã‚¿ã‚¤ãƒ—ã¯4ã¨ãªã‚Šã¾ã™ã€‚
+%
+% \item[\texttt{\bslash ext@TYPE}]
+% タイプ\texttt{TYPE}ã®ãƒ•ãƒ­ãƒ¼ãƒˆã®ç›®æ¬¡ã‚’出力ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã®æ‹¡å¼µå­ã§ã™ã€‚
+% ãŸã¨ãˆã°ã€|\ext@figure|ã¯`lot'ã§ã™ã€‚
+%
+% \item[\texttt{\bslash fnum@TYPE}]
+% キャプション用ã®å›³ç•ªå·ã‚’生æˆã™ã‚‹ãƒžã‚¯ãƒ­ã§ã™ã€‚
+% ãŸã¨ãˆã°ã€|\fnum@figure|ã¯`図|\thefigure|'を作りã¾ã™ã€‚
+% \end{description}
+%
+% \subsubsection{figure環境}
+% ã“ã“ã§ã¯ã€figure環境を実装ã—ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macro}{\c@figure}
+% \begin{macro}{\thefigure}
+% 図番å·ã§ã™ã€‚
+% \begin{macrocode}
+%<article>\newcounter{figure}
+%<report|book>\newcounter{figure}[chapter]
+%<*tate>
+%<article>\renewcommand{\thefigure}{\rensuji{\@arabic\c@figure}}
+% \end{macrocode}
+% \changes{v1.1d}{1997/02/14}{\cs{ifnum}æ–‡ã®æ§‹æ–‡ã‚¨ãƒ©ãƒ¼ã‚’訂正。}
+% \begin{macrocode}
+%<*report|book>
+\renewcommand{\thefigure}{%
+ \ifnum\c@chapter>\z@\thechapter{}・\fi\rensuji{\@arabic\c@figure}}
+%</report|book>
+%</tate>
+%<*yoko>
+%<article>\renewcommand{\thefigure}{\@arabic\c@figure}
+%<*report|book>
+\renewcommand{\thefigure}{%
+ \ifnum\c@chapter>\z@\thechapter.\fi\@arabic\c@figure}
+%</report|book>
+%</yoko>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fps@figure}
+% \begin{macro}{\ftype@figure}
+% \begin{macro}{\ext@figure}
+% \begin{macro}{\fnum@figure}
+% フロートオブジェクトタイプ``figure''ã®ãŸã‚ã®ãƒ‘ラメータã§ã™ã€‚
+% \begin{macrocode}
+\def\fps@figure{tbp}
+\def\ftype@figure{1}
+\def\ext@figure{lof}
+%<tate>\def\fnum@figure{\figurename\thefigure}
+%<yoko>\def\fnum@figure{\figurename~\thefigure}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{environment}{figure}
+% \begin{environment}{figure*}
+% |*|å½¢å¼ã¯ï¼’段抜ãã®ãƒ•ãƒ­ãƒ¼ãƒˆã¨ãªã‚Šã¾ã™ã€‚
+% \begin{macrocode}
+\newenvironment{figure}
+ {\@float{figure}}
+ {\end@float}
+\newenvironment{figure*}
+ {\@dblfloat{figure}}
+ {\end@dblfloat}
+% \end{macrocode}
+% \end{environment}
+% \end{environment}
+%
+% \subsubsection{table環境}
+% ã“ã“ã§ã¯ã€table環境を実装ã—ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macro}{\c@table}
+% \begin{macro}{\thetable}
+% \changes{v1.1n}{1998/10/13}
+% {report, bookクラスã§chapterカウンタを考慮ã—ã¦ã„ãªã‹ã£ãŸã®ã‚’修正。
+% ã‚ã‚ŠãŒã¨ã†ã€å¹³å·ï¼ æ…¶æ‡‰å¤§ã•ã‚“。}
+% 表番å·ã§ã™ã€‚
+% \begin{macrocode}
+%<article>\newcounter{table}
+%<report|book>\newcounter{table}[chapter]
+%<*tate>
+%<article>\renewcommand{\thetable}{\rensuji{\@arabic\c@table}}
+%<*report|book>
+\renewcommand{\thetable}{%
+ \ifnum\c@chapter>\z@\thechapter{}・\fi\rensuji{\@arabic\c@table}}
+%</report|book>
+%</tate>
+%<*yoko>
+%<article>\renewcommand{\thetable}{\@arabic\c@table}
+%<*report|book>
+\renewcommand{\thetable}{%
+ \ifnum\c@chapter>\z@\thechapter.\fi\@arabic\c@table}
+%</report|book>
+%</yoko>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fps@table}
+% \begin{macro}{\ftype@table}
+% \begin{macro}{\ext@table}
+% \begin{macro}{\fnum@table}
+% フロートオブジェクトタイプ``table''ã®ãŸã‚ã®ãƒ‘ラメータã§ã™ã€‚
+% \begin{macrocode}
+\def\fps@table{tbp}
+\def\ftype@table{2}
+\def\ext@table{lot}
+%<tate>\def\fnum@table{\tablename\thetable}
+%<yoko>\def\fnum@table{\tablename~\thetable}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{environment}{table}
+% \begin{environment}{table*}
+% |*|å½¢å¼ã¯ï¼’段抜ãã®ãƒ•ãƒ­ãƒ¼ãƒˆã¨ãªã‚Šã¾ã™ã€‚
+% \begin{macrocode}
+\newenvironment{table}
+ {\@float{table}}
+ {\end@float}
+\newenvironment{table*}
+ {\@dblfloat{table}}
+ {\end@dblfloat}
+% \end{macrocode}
+% \end{environment}
+% \end{environment}
+%
+% \subsection{キャプション}
+%
+% \begin{macro}{\@makecaption}
+% |\caption|コマンドã¯ã€ã‚­ãƒ£ãƒ—ションを組ã¿ç«‹ã¦ã‚‹ãŸã‚ã«|\@mkcaption|を呼出ã¾ã™ã€‚
+% ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯äºŒã¤ã®å¼•æ•°ã‚’å–ã‚Šã¾ã™ã€‚
+% 一ã¤ã¯ã€\meta{number}ã§ã€ãƒ•ãƒ­ãƒ¼ãƒˆã‚ªãƒ–ジェクトã®ç•ªå·ã§ã™ã€‚
+% ã‚‚ã†ä¸€ã¤ã¯ã€\meta{text}ã§ã‚­ãƒ£ãƒ—ション文字列ã§ã™ã€‚
+% \meta{number}ã«ã¯é€šå¸¸ã€`図 3.2'ã®ã‚ˆã†ãªæ–‡å­—列ãŒå…¥ã£ã¦ã„ã¾ã™ã€‚
+% ã“ã®ãƒžã‚¯ãƒ­ã¯ã€|\parbox|ã®ä¸­ã§å‘¼ã³å‡ºã•ã‚Œã¾ã™ã€‚書体ã¯|\normalsize|ã§ã™ã€‚
+%
+% \begin{macro}{\abovecaptionskip}
+% \begin{macro}{\belowcaptionskip}
+% ã“れらã®é•·ã•ã¯ã‚­ãƒ£ãƒ—ションã®å‰å¾Œã«æŒ¿å…¥ã•ã‚Œã‚‹ã‚¹ãƒšãƒ¼ã‚¹ã§ã™ã€‚
+% \begin{macrocode}
+\newlength\abovecaptionskip
+\newlength\belowcaptionskip
+\setlength\abovecaptionskip{10\p@}
+\setlength\belowcaptionskip{0\p@}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% キャプション内ã§è¤‡æ•°ã®æ®µè½ã‚’作æˆã™ã‚‹ã“ã¨ãŒã§ãるよã†ã«ã€
+% ã“ã®ãƒžã‚¯ãƒ­ã¯|\long|ã§å®šç¾©ã‚’ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\long\def\@makecaption#1#2{%
+ \vskip\abovecaptionskip
+ \ifnum\ltjgetparameter{direction}=3 \sbox\@tempboxa{#1\hskip1\zw#2}%
+ \else\sbox\@tempboxa{#1: #2}%
+ \fi
+ \ifdim \wd\@tempboxa >\hsize
+ \ifnum\ltjgetparameter{direction}=3 #1\hskip1\zw#2\relax\par
+ \else #1: #2\relax\par\fi
+ \else
+ \global \@minipagefalse
+ \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
+ \fi
+ \vskip\belowcaptionskip}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{コマンドパラメータã®è¨­å®š}
+%
+% \subsubsection{arrayã¨tabular環境}
+%
+% \begin{macro}{\arraycolsep}
+% array環境ã®ã‚«ãƒ©ãƒ ã¯2|\arraycolsep|ã§åˆ†é›¢ã•ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+\setlength\arraycolsep{5\p@}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tabcolsep}
+% tabular環境ã®ã‚«ãƒ©ãƒ ã¯2|\tabcolsep|ã§åˆ†é›¢ã•ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+\setlength\tabcolsep{6\p@}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\arrayrulewidth}
+% arrayã¨tabular環境内ã®ç½«ç·šã®å¹…ã§ã™ã€‚
+% \begin{macrocode}
+\setlength\arrayrulewidth{.4\p@}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\doublerulesep}
+% arrayã¨tabular環境内ã®ç½«ç·šé–“を調整ã™ã‚‹ç©ºç™½ã§ã™ã€‚
+% \begin{macrocode}
+\setlength\doublerulesep{2\p@}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{tabbing環境}
+%
+% \begin{macro}{\tabbingsep}
+% |\'|コマンドã§ç½®ã‹ã‚Œã‚‹ã‚¹ãƒšãƒ¼ã‚¹ã‚’制御ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\setlength\tabbingsep{\labelsep}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{minipage環境}
+%
+% \begin{macro}{\@mpfootins}
+% minipageã«ã‚‚脚注を付ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+% |\skip||\@mpfootins|ã¯ã€é€šå¸¸ã®|\skip||\footins|ã¨åŒã˜ã‚ˆã†ãªå‹•ä½œã‚’ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\skip\@mpfootins = \skip\footins
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{framebox環境}
+%
+% \begin{macro}{\fboxsep}
+% \begin{macro}{\fboxrule}
+% |\fboxsep|ã¯ã€|\fbox|ã¨|\framebox|ã§ã®ã€
+% テキストã¨ãƒœãƒƒã‚¯ã‚¹ã®é–“ã«å…¥ã‚‹ç©ºç™½ã§ã™ã€‚
+% |\fboxrule|ã¯|\fbox|ã¨|\framebox|ã§ä½œæˆã•ã‚Œã‚‹ç½«ç·šã®å¹…ã§ã™ã€‚
+% \begin{macrocode}
+\setlength\fboxsep{3\p@}
+\setlength\fboxrule{.4\p@}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{equationã¨eqnarray環境}
+%
+% \begin{macro}{\theequation}
+% equationカウンタã¯ã€æ–°ã—ã„ç« ã®é–‹å§‹ã§ãƒªã‚»ãƒƒãƒˆã•ã‚Œã¾ã™ã€‚
+% ã¾ãŸã€equation番å·ã«ã¯ã€ç« ç•ªå·ãŒä»˜ãã¾ã™ã€‚
+%
+% ã“ã®ã‚³ãƒ¼ãƒ‰ã¯|\chapter|定義ã®å¾Œã€ã‚ˆã‚Šæ­£ç¢ºã«ã¯chapterカウンタã®å®šç¾©ã®å¾Œã€
+% ã§ãªãã¦ã¯ã„ã‘ã¾ã›ã‚“。
+% \begin{macrocode}
+%<article>\renewcommand{\theequation}{\@arabic\c@equation}
+%<*report|book>
+\@addtoreset{equation}{chapter}
+\renewcommand{\theequation}{%
+ \ifnum\c@chapter>\z@\thechapter.\fi \@arabic\c@equation}
+%</report|book>
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \section{フォントコマンド}
+% ã¾ãšã€æ•°å¼å†…ã«æ—¥æœ¬èªžã‚’直接ã€è¨˜è¿°ã™ã‚‹ãŸã‚ã«æ•°å¼è¨˜å·ç”¨æ–‡å­—ã«
+% ``JY3/mc/m/n''を登録ã—ã¾ã™ã€‚æ•°å¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒboldã®å ´åˆã¯ã€
+% ``JY3/gt/m/n''を用ã„ã¾ã™ã€‚
+% ã“れらã¯ã€|\mathmc|, |\mathgt|ã¨ã—ã¦ç™»éŒ²ã•ã‚Œã¾ã™ã€‚
+% ã¾ãŸã€æ—¥æœ¬èªžæ•°å¼ãƒ•ã‚¡ãƒŸãƒªã¨ã—ã¦|\symmincho|ãŒã“ã®æ®µéšŽã§è¨­å®šã•ã‚Œã¾ã™ã€‚
+% |mathrmmc|オプションãŒæŒ‡å®šã•ã‚Œã¦ã„ãŸå ´åˆã«ã¯ã€ã“ã‚Œã«å¼•ã続ã
+% |\mathrm|ã¨|\mathbf|を和欧文両対応ã«ã™ã‚‹ãŸã‚ã®ä½œæ¥­ãŒãªã•ã‚Œã¾ã™ã€‚ã“ã®éš›ã€
+% ä»–ã®ãƒžã‚¯ãƒ­ã¨ã®è¡çªã‚’é¿ã‘ã‚‹ãŸã‚|\AtBeginDocument|
+% を用ã„ã¦å±•é–‹é †åºã‚’é…らã›ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+%
+% \textbf{変更}
+%
+% \changes{v1.6}{2006/06/27}{フォントコマンドを修正。ã‚ã‚ŠãŒã¨ã†ã€ymtã•ã‚“。}
+% \LaTeX{} 2.09
+% compatibility mode ã§ã¯å’Œæ–‡æ•°å¼ãƒ•ã‚©ãƒ³ãƒˆfamãŒ2é‡å®šç¾©ã•ã‚Œã¦ã„ãŸ
+% ã®ã§ã€ãã®éƒ¨åˆ†ã‚’変更ã—ã¾ã—ãŸã€‚
+%
+% \changes{v1.8-ltj-14}{2018/10/08}{Lua\TeX-ja本体ãŒ|disablejfam|オプションをサãƒãƒ¼ãƒˆã—ã¾ã—ãŸã€‚
+% クラス読ã¿è¾¼ã¿æ™‚ã«|disablejfam|オプションを指定ã—ãŸå ´åˆã¯ã€ãã‚ŒãŒLua\TeX-jaã«æ¸¡ã•ã‚Œã¦
+% æ•°å¼ä¸­ã«æ—¥æœ¬èªžã‚’記述ã™ã‚‹ã“ã¨ãŒã§ããªããªã‚Šã¾ã™ï¼ˆ|\mathmc|, |\mathgt|も定義ã•ã‚Œã¾ã›ã‚“)。}
+% \begin{macrocode}
+\unless\ifltj@disablejfam
+\if@compatibility\else
+ \DeclareSymbolFont{mincho}{JY3}{mc}{m}{n}
+ \DeclareSymbolFontAlphabet{\mathmc}{mincho}
+ \SetSymbolFont{mincho}{bold}{JY3}{gt}{m}{n}
+ \jfam\symmincho
+ \DeclareMathAlphabet{\mathgt}{JY3}{gt}{m}{n}
+\fi
+\if@mathrmmc
+ \AtBeginDocument{%
+ \reDeclareMathAlphabet{\mathrm}{\mathrm}{\mathmc}
+ \reDeclareMathAlphabet{\mathbf}{\mathbf}{\mathgt}
+}%
+\fi
+\fi
+% \end{macrocode}
+%
+% ã“ã“ã§ã¯\LaTeX~2.09ã§ä¸€èˆ¬çš„ã«ä½¿ã‚ã‚Œã¦ã„ãŸã‚³ãƒžãƒ³ãƒ‰ã‚’定義ã—ã¦ã„ã¾ã™ã€‚
+% ã“れらã®ã‚³ãƒžãƒ³ãƒ‰ã¯ãƒ†ã‚­ã‚¹ãƒˆãƒ¢ãƒ¼ãƒ‰ã¨æ•°å¼ãƒ¢ãƒ¼ãƒ‰ã®\emph{ã©ã¡ã‚‰ã§ã‚‚}動作ã—ã¾ã™ã€‚
+% ã“れらã¯äº’æ›æ€§ã®ãŸã‚ã«æ供をã—ã¾ã™ãŒã€ã§ãã‚‹ã ã‘|\text...|ã¨|\math...|ã‚’
+% 使ã†ã‚ˆã†ã«ã—ã¦ãã ã•ã„。
+%
+% \begin{macro}{\mc}
+% \begin{macro}{\gt}
+% \begin{macro}{\rm}
+% \begin{macro}{\sf}
+% \begin{macro}{\tt}
+% ã“れらã®ã‚³ãƒžãƒ³ãƒ‰ã¯ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã‚’変更ã—ã¾ã™ã€‚
+% 互æ›ãƒ¢ãƒ¼ãƒ‰ã®åŒåコマンドã¨ç•°ãªã‚Šã€ã™ã¹ã¦ã®ã‚³ãƒžãƒ³ãƒ‰ãŒãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãƒ•ã‚©ãƒ³ãƒˆã«
+% リセットã—ã¦ã‹ã‚‰ã€å¯¾å¿œã™ã‚‹å±žæ€§ã‚’変更ã™ã‚‹ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。
+% \begin{macrocode}
+\DeclareOldFontCommand{\mc}{\normalfont\mcfamily}{\mathmc}
+\DeclareOldFontCommand{\gt}{\normalfont\gtfamily}{\mathgt}
+\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm}
+\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}
+\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\bf}
+% ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ãƒœãƒ¼ãƒ«ãƒ‰æ›¸ä½“ã«ã—ã¾ã™ã€‚ノーマル書体ã«å¤‰æ›´ã™ã‚‹ã«ã¯ã€
+% |\mdseries|ã¨æŒ‡å®šã‚’ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\it}
+% \begin{macro}{\sl}
+% \begin{macro}{\sc}
+% ã“れらã®ã‚³ãƒžãƒ³ãƒ‰ã¯ãƒ•ã‚©ãƒ³ãƒˆã‚·ã‚§ã‚¤ãƒ—を切替ãˆã¾ã™ã€‚
+% スラント体ã¨ã‚¹ãƒ¢ãƒ¼ãƒ«ã‚­ãƒ£ãƒƒãƒ—ã®æ•°å¼ã‚¢ãƒ«ãƒ•ã‚¡ãƒ™ãƒƒãƒˆã¯ã‚ã‚Šã¾ã›ã‚“ã®ã§ã€
+% æ•°å¼ãƒ¢ãƒ¼ãƒ‰ã§ã¯ä½•ã‚‚ã—ã¾ã›ã‚“ãŒã€è­¦å‘Šãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’出力ã—ã¾ã™ã€‚
+% |\upshape|コマンドã§é€šå¸¸ã®ã‚·ã‚§ã‚¤ãƒ—ã«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+% \begin{macrocode}
+\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit}
+\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl}
+\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cal}
+% \begin{macro}{\mit}
+% ã“れらã®ã‚³ãƒžãƒ³ãƒ‰ã¯æ•°å¼ãƒ¢ãƒ¼ãƒ‰ã§ã ã‘使ã†ã“ã¨ãŒã§ãã¾ã™ã€‚
+% æ•°å¼ãƒ¢ãƒ¼ãƒ‰ä»¥å¤–ã§ã¯ä½•ã‚‚ã—ã¾ã›ã‚“。
+% ç¾åœ¨ã®NFSSã¯ã€ã“れらã®ã‚³ãƒžãƒ³ãƒ‰ãŒè­¦å‘Šã‚’生æˆã™ã‚‹ã‚ˆã†ã«å®šç¾©ã—ã¦ã„ã¾ã™ã®ã§ã€
+% `手ãšã‹ã‚‰'定義ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+% \begin{macrocode}
+\DeclareRobustCommand*{\cal}{\@fontswitch\relax\mathcal}
+\DeclareRobustCommand*{\mit}{\@fontswitch\relax\mathnormal}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \section{相互å‚ç…§}
+%
+% \subsection{目次}
+% |\section|コマンドã¯ã€\file{.toc}ファイルã«ã€æ¬¡ã®ã‚ˆã†ãªè¡Œã‚’出力ã—ã¾ã™ã€‚
+%
+% |\contentsline{section}{|\meta{title}|}{|\meta{page}|}|
+%
+% \meta{title}ã«ã¯é …ç›®ãŒã€\meta{page}ã«ã¯ãƒšãƒ¼ã‚¸ç•ªå·ãŒå…¥ã‚Šã¾ã™ã€‚
+% |\section|ã«è¦‹å‡ºã—番å·ãŒä»˜ãå ´åˆã¯ã€\meta{title}ã¯ã€
+% |\numberline{|\meta{num}|}{|\meta{heading}|}|ã¨ãªã‚Šã¾ã™ã€‚
+% \meta{num}ã¯|\thesection|コマンドã§ç”Ÿæˆã•ã‚ŒãŸè¦‹å‡ºã—番å·ã§ã™ã€‚
+% \meta{heading}ã¯è¦‹å‡ºã—文字列ã§ã™ã€‚ã“ã®ä»–ã®è¦‹å‡ºã—コマンドもåŒæ§˜ã§ã™ã€‚
+%
+% figure環境ã§ã®|\caption|コマンドã¯ã€\file{.lof}ファイルã«ã€
+% 次ã®ã‚ˆã†ãªè¡Œã‚’出力ã—ã¾ã™ã€‚
+%
+% |\contentsline{figure}{\numberline{|\meta{num}|}{|%
+% \meta{caption}|}}{|\meta{page}|}|
+%
+% \meta{num}ã¯ã€|\thefigure|コマンドã§ç”Ÿæˆã•ã‚ŒãŸå›³ç•ªå·ã§ã™ã€‚
+% \meta{caption}ã¯ã€ã‚­ãƒ£ãƒ—ション文字列ã§ã™ã€‚table環境もåŒæ§˜ã§ã™ã€‚
+%
+% |\contentsline{|\meta{name}|}|コマンドã¯ã€|\l@|\meta{name}ã«å±•é–‹ã•ã‚Œã¾ã™ã€‚
+% ã—ãŸãŒã£ã¦ã€ç›®æ¬¡ã®ä½“è£ã‚’記述ã™ã‚‹ã«ã¯ã€|\l@chapter|, |\l@section|ãªã©ã‚’
+% 定義ã—ã¾ã™ã€‚図目次ã®ãŸã‚ã«ã¯|\l@figure|ã§ã™ã€‚
+% ã“れらã®å¤šãã®ã‚³ãƒžãƒ³ãƒ‰ã¯|\@dottedtocline|コマンドã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯æ¬¡ã®ã‚ˆã†ãªæ›¸å¼ã¨ãªã£ã¦ã„ã¾ã™ã€‚
+%
+% |\@dottedtocline{|\meta{level}|}{|\meta{indent}|}{|^^A
+% \meta{numwidth}|}{|\meta{title}|}{|\meta{page}|}|
+%
+% \begin{description}
+% \item[\meta{level}] ``\meta{level} $<=$ \Lcount{tocdepth}''ã®ã¨ãã«ã ã‘ã€
+% 生æˆã•ã‚Œã¾ã™ã€‚|\chapter|ã¯ãƒ¬ãƒ™ãƒ«ï¼ã€|\section|ã¯ãƒ¬ãƒ™ãƒ«ï¼‘ã€$\ldots$ ã§ã™ã€‚
+% \item[\meta{indent}] 一番外å´ã‹ã‚‰ã®å·¦ãƒžãƒ¼ã‚¸ãƒ³ã§ã™ã€‚
+% \item[\meta{numwidth}] 見出ã—番å·ï¼ˆ|\numberline|コマンドã®\meta{num})ãŒ
+% 入るボックスã®å¹…ã§ã™ã€‚
+% \end{description}
+%
+% \begin{macro}{\c@tocdepth}
+% \Lcount{tocdepth}ã¯ã€ç›®æ¬¡ãƒšãƒ¼ã‚¸ã«å‡ºåŠ›ã‚’ã™ã‚‹è¦‹å‡ºã—レベルã§ã™ã€‚
+% \begin{macrocode}
+%<article>\setcounter{tocdepth}{3}
+%<!article>\setcounter{tocdepth}{2}
+% \end{macrocode}
+% \end{macro}
+%
+% ã¾ãŸã€ç›®æ¬¡ã‚’生æˆã™ã‚‹ãŸã‚ã«æ¬¡ã®ãƒ‘ラメータも使ã„ã¾ã™ã€‚
+%
+% \begin{macro}{\@pnumwidth}
+% ページ番å·ã®å…¥ã‚‹ãƒœãƒƒã‚¯ã‚¹ã®å¹…ã§ã™ã€‚
+% \begin{macrocode}
+\newcommand{\@pnumwidth}{1.55em}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@tocrmarg}
+% 複数行ã«ã‚ãŸã‚‹å ´åˆã®å³ãƒžãƒ¼ã‚¸ãƒ³ã§ã™ã€‚
+% \begin{macrocode}
+\newcommand{\@tocrmarg}{2.55em}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@dotsep}
+% ドットã®é–“隔(muå˜ä½ï¼‰ã§ã™ã€‚2ã‚„1.7ã®ã‚ˆã†ã«æŒ‡å®šã‚’ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\newcommand{\@dotsep}{4.5}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\toclineskip}
+% ã“ã®é•·ã•å¤‰æ•°ã¯ã€ç›®æ¬¡é …ç›®ã®é–“ã«å…¥ã‚‹ã‚¹ãƒšãƒ¼ã‚¹ã®é•·ã•ã§ã™ã€‚
+% デフォルトã¯ã‚¼ãƒ­ã¨ãªã£ã¦ã„ã¾ã™ã€‚縦組ã®ã¨ãã€ã‚¹ãƒšãƒ¼ã‚¹ã‚’å°‘ã—広ã’ã¾ã™ã€‚
+% \begin{macrocode}
+\newdimen\toclineskip
+%<yoko>\setlength\toclineskip{\z@}
+%<tate>\setlength\toclineskip{2\p@}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\numberline}
+% \begin{macro}{\@lnumwidth}
+% |\numberline|マクロã®å®šç¾©ã‚’示ã—ã¾ã™ã€‚オリジナルã®å®šç¾©ã§ã¯ã€ãƒœãƒƒã‚¯ã‚¹ã®å¹…ã‚’
+% |\@tempdima|ã«ã—ã¦ã„ã¾ã™ãŒã€ã“ã®å¤‰æ•°ã¯ã„ã‚ã„ã‚ãªç®‡æ‰€ã§ä½¿ã‚ã‚Œã¾ã™ã®ã§ã€
+% 期待ã—ãŸå€¤ãŒå…¥ã‚‰ãªã„å ´åˆãŒã‚ã‚Šã¾ã™ã€‚
+%
+% ^^A ãŸã¨ãˆã°ã€|lltjfont.sty|ã§ã®|\selectfont|ã¯ã€å’Œæ¬§æ–‡ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã‚’調整ã™ã‚‹
+% ^^A ãŸã‚ã«|\@tempdima|変数を用ã„ã¦ã„ã¾ã™ã€‚ãã®ãŸã‚ã€|\l@...|マクロã®ä¸­ã§
+% ^^A フォントを切替ãˆã‚‹ã¨ã€|\numberline|マクロã®ãƒœãƒƒã‚¯ã‚¹
+% ^^A ã®å¹…ãŒã€ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã‚’調整ã™ã‚‹ã¨ãã«è¨ˆç®—ã—ãŸå€¤ã«ãªã£ã¦ã—ã¾ã„ã¾ã™ã€‚
+% ^^A →修正(texjporg):最近ã®|\adjustbaseline|ã§ã¯|\adjust@dimen|ãŒä½¿ã‚ã‚Œã¦
+% ^^A ã„ã‚‹ãŸã‚ã€è¨˜è¿°ã‚’コメントアウトã—ã¾ã—ãŸã€‚
+%
+% フォントé¸æŠžã‚³ãƒžãƒ³ãƒ‰ã®å¾Œã€ã‚ã‚‹ã„ã¯|\numberline|マクロã®ä¸­ã§ãƒ•ã‚©ãƒ³ãƒˆã‚’
+% 切替ãˆã¦ã‚‚よã„ã®ã§ã™ãŒã€ä¸€æ™‚変数をæ„è­˜ã—ãŸããªã„ã®ã§ã€
+% 見出ã—番å·ã®å…¥ã‚‹ãƒœãƒƒã‚¯ã‚¹ã‚’|\@lnumwidth|変数を用ã„ã¦çµ„ã¿ç«‹ã¦ã‚‹ã‚ˆã†ã«
+% |\numberline|マクロをå†å®šç¾©ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\newdimen\@lnumwidth
+\def\numberline#1{\hb@xt@\@lnumwidth{#1\hfil}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@dottedtocline}
+% 目次ã®å„行間ã«|\toclineskip|を入れるよã†ã«å¤‰æ›´ã—ã¾ã™ã€‚
+% ã“ã®ãƒžã‚¯ãƒ­ã¯\file{ltsect.dtx}ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% \changes{v1.3}{2001/10/04}{第5引数ã®æ›¸ä½“ã‚’\cs{rmfamily}ã‹ã‚‰\cs{normalfont}ã«å¤‰æ›´}
+% \changes{v1.7a}{2016/11/16}{Added \cs{nobreak} for
+% latex/2343 (sync with ltsect.dtx v1.0z)}
+% \begin{macrocode}
+\def\@dottedtocline#1#2#3#4#5{%
+ \ifnum #1>\c@tocdepth \else
+ \vskip\toclineskip \@plus.2\p@
+ {\leftskip #2\relax \rightskip \@tocrmarg \parfillskip -\rightskip
+ \parindent #2\relax\@afterindenttrue
+ \interlinepenalty\@M
+ \leavevmode
+ \@lnumwidth #3\relax
+ \advance\leftskip \@lnumwidth \null\nobreak\hskip -\leftskip
+ {#4}\nobreak
+ \leaders\hbox{$\m@th \mkern \@dotsep mu.\mkern \@dotsep mu$}%
+ \hfill\nobreak
+ \hb@xt@\@pnumwidth{\hss\normalfont \normalcolor #5}%
+ \par}%
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\addcontentsline}
+% 縦組ã®å ´åˆã«ãƒšãƒ¼ã‚¸ç•ªå·ã‚’|\rensuji|ã§å›²ã‚€ã‚ˆã†ã«å¤‰æ›´ã—ã¾ã™ã€‚
+% ^^A 横組ã®ã¨ãã«ã‚‚`|\rensuji|'コマンドãŒå‡ºåŠ›ã•ã‚Œã¾ã™ãŒã€
+% ^^A ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã«ã‚ˆã‚‹å½±éŸ¿ã¯ã‚ã‚Šã¾ã›ã‚“。
+%
+% ã“ã®ãƒžã‚¯ãƒ­ã¯\file{ltsect.dtx}ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% \changes{v1.8a}{2018/10/25}{ファイル書ã出ã—時ã®è¡Œæœ«æ–‡å­—対策
+% (sync with ltsect.dtx 2018/09/26 v1.1c)}
+% \begin{macrocode}
+\providecommand*\protected@file@percent{}
+\def\addcontentsline#1#2#3{%
+ \protected@write\@auxout
+ {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble
+%<tate> \@temptokena{\rensuji{\thepage}}}%
+%<yoko> \@temptokena{\thepage}}%
+ {\string\@writefile{#1}%
+ {\protect\contentsline{#2}{#3}{\the\@temptokena}%
+ \protected@file@percent}}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{本文目次}
+%
+% \begin{macro}{\tableofcontents}
+% 目次を生æˆã—ã¾ã™ã€‚
+% \begin{macrocode}
+\newcommand{\tableofcontents}{%
+%<*report|book>
+ \if@twocolumn\@restonecoltrue\onecolumn
+ \else\@restonecolfalse\fi
+%</report|book>
+%<article> \section*{\contentsname
+%<!article> \chapter*{\contentsname
+% \end{macrocode}
+% |\tableofcontents|ã§ã¯ã€|\@mkboth|ã¯headingã®ä¸­ã«å…¥ã‚Œã¦ã‚ã‚Šã¾ã™ã€‚
+% ã»ã‹ã®å‘½ä»¤ï¼ˆ|\listoffigures|ãªã©ï¼‰ã«ã¤ã„ã¦ã¯ã€|\@mkboth|ã¯headingã®
+% 外ã«å‡ºã—ã¦ã‚ã‚Šã¾ã™ã€‚ã“ã‚Œã¯\LaTeX ã®\file{classes.dtx}ã«åˆã‚ã›ã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+ \@mkboth{\contentsname}{\contentsname}%
+ }\@starttoc{toc}%
+%<report|book> \if@restonecol\twocolumn\fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l@part}
+% partレベルã®ç›®æ¬¡ã§ã™ã€‚
+% \begin{macrocode}
+\newcommand*{\l@part}[2]{%
+ \ifnum \c@tocdepth >-2\relax
+%<article> \addpenalty{\@secpenalty}%
+%<!article> \addpenalty{-\@highpenalty}%
+ \addvspace{2.25em \@plus\p@}%
+ \begingroup
+ \parindent\z@\rightskip\@pnumwidth
+ \parfillskip-\@pnumwidth
+ {\leavevmode\large\bfseries
+ \setlength\@lnumwidth{4\zw}%
+ #1\hfil\nobreak
+ \hb@xt@\@pnumwidth{\hss#2}}\par
+ \nobreak
+%<article> \if@compatibility
+ \global\@nobreaktrue
+ \everypar{\global\@nobreakfalse\everypar{}}%
+%<article> \fi
+ \endgroup
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l@chapter}
+% chapterレベルã®ç›®æ¬¡ã§ã™ã€‚
+% \begin{macrocode}
+%<*report|book>
+\newcommand*{\l@chapter}[2]{%
+ \ifnum \c@tocdepth >\m@ne
+ \addpenalty{-\@highpenalty}%
+ \addvspace{1.0em \@plus\p@}%
+ \begingroup
+ \parindent\z@ \rightskip\@pnumwidth \parfillskip-\rightskip
+ \leavevmode\bfseries
+ \setlength\@lnumwidth{4\zw}%
+ \advance\leftskip\@lnumwidth \hskip-\leftskip
+ #1\nobreak\hfil\nobreak\hb@xt@\@pnumwidth{\hss#2}\par
+ \penalty\@highpenalty
+ \endgroup
+ \fi}
+%</report|book>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l@section}
+% sectionレベルã®ç›®æ¬¡ã§ã™ã€‚
+% \begin{macrocode}
+%<*article>
+\newcommand*{\l@section}[2]{%
+ \ifnum \c@tocdepth >\z@
+ \addpenalty{\@secpenalty}%
+ \addvspace{1.0em \@plus\p@}%
+ \begingroup
+ \parindent\z@ \rightskip\@pnumwidth \parfillskip-\rightskip
+ \leavevmode\bfseries
+ \setlength\@lnumwidth{1.5em}%
+ \advance\leftskip\@lnumwidth \hskip-\leftskip
+ #1\nobreak\hfil\nobreak\hb@xt@\@pnumwidth{\hss#2}\par
+ \endgroup
+ \fi}
+%</article>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*report|book>
+%<tate>\newcommand*{\l@section}{\@dottedtocline{1}{1\zw}{4\zw}}
+%<yoko>\newcommand*{\l@section}{\@dottedtocline{1}{1.5em}{2.3em}}
+%</report|book>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l@subsection}
+% \begin{macro}{\l@subsubsection}
+% \begin{macro}{\l@paragraph}
+% \begin{macro}{\l@subparagraph}
+% 下ä½ãƒ¬ãƒ™ãƒ«ã®ç›®æ¬¡é …ç›®ã®ä½“è£ã§ã™ã€‚
+% \begin{macrocode}
+%<*tate>
+%<*article>
+\newcommand*{\l@subsection} {\@dottedtocline{2}{1\zw}{4\zw}}
+\newcommand*{\l@subsubsection}{\@dottedtocline{3}{2\zw}{6\zw}}
+\newcommand*{\l@paragraph} {\@dottedtocline{4}{3\zw}{8\zw}}
+\newcommand*{\l@subparagraph} {\@dottedtocline{5}{4\zw}{9\zw}}
+%</article>
+%<*report|book>
+\newcommand*{\l@subsection} {\@dottedtocline{2}{2\zw}{6\zw}}
+\newcommand*{\l@subsubsection}{\@dottedtocline{3}{3\zw}{8\zw}}
+\newcommand*{\l@paragraph} {\@dottedtocline{4}{4\zw}{9\zw}}
+\newcommand*{\l@subparagraph} {\@dottedtocline{5}{5\zw}{10\zw}}
+%</report|book>
+%</tate>
+%<*yoko>
+%<*article>
+\newcommand*{\l@subsection} {\@dottedtocline{2}{1.5em}{2.3em}}
+\newcommand*{\l@subsubsection}{\@dottedtocline{3}{3.8em}{3.2em}}
+\newcommand*{\l@paragraph} {\@dottedtocline{4}{7.0em}{4.1em}}
+\newcommand*{\l@subparagraph} {\@dottedtocline{5}{10em}{5em}}
+%</article>
+%<*report|book>
+\newcommand*{\l@subsection} {\@dottedtocline{2}{3.8em}{3.2em}}
+\newcommand*{\l@subsubsection}{\@dottedtocline{3}{7.0em}{4.1em}}
+\newcommand*{\l@paragraph} {\@dottedtocline{4}{10em}{5em}}
+\newcommand*{\l@subparagraph} {\@dottedtocline{5}{12em}{6em}}
+%</report|book>
+%</yoko>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsubsection{図目次ã¨è¡¨ç›®æ¬¡}
+%
+% \begin{macro}{\listoffigures}
+% 図ã®ä¸€è¦§ã‚’作æˆã—ã¾ã™ã€‚
+% \changes{v1.7}{2016/11/12}{Moved \cs{@mkboth} out of heading
+% arg (sync with classes.dtx v1.4c)}
+% \begin{macrocode}
+\newcommand{\listoffigures}{%
+%<*report|book>
+ \if@twocolumn\@restonecoltrue\onecolumn
+ \else\@restonecolfalse\fi
+ \chapter*{\listfigurename}%
+%</report|book>
+%<article> \section*{\listfigurename}%
+ \@mkboth{\listfigurename}{\listfigurename}%
+ \@starttoc{lof}%
+%<report|book> \if@restonecol\twocolumn\fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l@figure}
+% 図目次ã®ä½“è£ã§ã™ã€‚
+% \begin{macrocode}
+%<tate>\newcommand*{\l@figure}{\@dottedtocline{1}{1\zw}{4\zw}}
+%<yoko>\newcommand*{\l@figure}{\@dottedtocline{1}{1.5em}{2.3em}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\listoftables}
+% \changes{v1.0c}{1995/12/28}{fix the \cs{listoftable} typo.}
+% 表ã®ä¸€è¦§ã‚’作æˆã—ã¾ã™ã€‚
+% \changes{v1.7}{2016/11/12}{Moved \cs{@mkboth} out of heading
+% arg (sync with classes.dtx v1.4c)}
+% \begin{macrocode}
+\newcommand{\listoftables}{%
+%<*report|book>
+ \if@twocolumn\@restonecoltrue\onecolumn
+ \else\@restonecolfalse\fi
+ \chapter*{\listtablename}%
+%</report|book>
+%<article> \section*{\listtablename}%
+ \@mkboth{\listtablename}{\listtablename}%
+ \@starttoc{lot}%
+%<report|book> \if@restonecol\twocolumn\fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l@table}
+% 表目次ã®ä½“è£ã¯ã€å›³ç›®æ¬¡ã¨åŒã˜ã«ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\let\l@table\l@figure
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{å‚考文献}
+%
+% \begin{macro}{\bibindent}
+% オープンスタイルã®å‚考文献ã§ä½¿ã†ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆå¹…ã§ã™ã€‚
+% \begin{macrocode}
+\newdimen\bibindent
+\setlength\bibindent{1.5em}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\newblock}
+% |\newblock|ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå®šç¾©ã¯ã€å°ã•ãªã‚¹ãƒšãƒ¼ã‚¹ã‚’生æˆã—ã¾ã™ã€‚
+% \begin{macrocode}
+\newcommand{\newblock}{\hskip .11em\@plus.33em\@minus.07em}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{thebibliography}
+% å‚考文献や関連図書ã®ãƒªã‚¹ãƒˆã‚’作æˆã—ã¾ã™ã€‚
+% \changes{v1.7}{2016/11/12}{Moved \cs{@mkboth} out of heading
+% arg (sync with classes.dtx v1.4c)}
+% \begin{macrocode}
+\newenvironment{thebibliography}[1]
+%<article>{\section*{\refname}\@mkboth{\refname}{\refname}%
+%<report|book>{\chapter*{\bibname}\@mkboth{\bibname}{\bibname}%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy
+% \end{macrocode}
+% \changes{v1.1a}{1997/01/23}{\break\LaTeX\ \texttt{!<1996/12/01!>}ã«åˆã‚ã›ã¦ä¿®æ­£}
+% \begin{macrocode}
+ \clubpenalty4000
+ \@clubpenalty\clubpenalty
+ \widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\@openbib@code}
+% |\@openbib@code|ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå®šç¾©ã¯ä½•ã‚‚ã—ã¾ã›ã‚“。
+% ã“ã®å®šç¾©ã¯ã€\Lopt{openbib}オプションã«ã‚ˆã£ã¦å¤‰æ›´ã•ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+\let\@openbib@code\@empty
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@biblabel}
+% The label for a |\bibitem[...]| command is produced by this
+% macro. The default from \file{latex.dtx} is used.
+% \begin{macrocode}
+% \renewcommand*{\@biblabel}[1]{[#1]\hfill}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@cite}
+% The output of the |\cite| command is produced by this macro. The
+% default from \file{ltbibl.dtx} is used.
+% \begin{macrocode}
+% \renewcommand*{\@cite}[1]{[#1]}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{索引}
+%
+% \begin{environment}{theindex}
+% 2段組ã®ç´¢å¼•ã‚’作æˆã—ã¾ã™ã€‚
+% 索引ã®å…ˆé ­ã®ãƒšãƒ¼ã‚¸ã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯\pstyle{jpl@in}ã¨ã—ã¾ã™ã€‚ã—ãŸãŒã£ã¦ã€
+% \pstyle{headings}ã¨\pstyle{bothstyle}ã«é©ã—ãŸä½ç½®ã«å‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+\newenvironment{theindex}
+ {\if@twocolumn\@restonecolfalse\else\@restonecoltrue\fi
+%<article> \twocolumn[\section*{\indexname}]%
+%<report|book> \twocolumn[\@makeschapterhead{\indexname}]%
+ \@mkboth{\indexname}{\indexname}%
+ \thispagestyle{jpl@in}\parindent\z@
+% \end{macrocode}
+% パラメータ|\columnseprule|ã¨|\columnsep|ã®å¤‰æ›´ã¯ã€|\twocolumn|ãŒ
+% 実行ã•ã‚ŒãŸå¾Œã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。ãã†ã—ãªã„ã¨ã€ç´¢å¼•ã®å‰ã®ãƒšãƒ¼ã‚¸
+% ã«ã‚‚影響ã—ã¦ã—ã¾ã†ãŸã‚ã§ã™ã€‚
+% \changes{v1.7}{2016/11/12}{\cs{columnsep}ã¨\cs{columnseprule}ã®
+% 変更を後ã‚ã«ç§»å‹•(sync with classes.dtx v1.4f)}
+% \begin{macrocode}
+ \parskip\z@ \@plus .3\p@\relax
+ \columnseprule\z@ \columnsep 35\p@
+ \let\item\@idxitem}
+ {\if@restonecol\onecolumn\else\clearpage\fi}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\@idxitem}
+% \begin{macro}{\subitem}
+% \begin{macro}{\subsubitem}
+% 索引項目ã®å­—下ã’å¹…ã§ã™ã€‚|\@idxitem|ã¯|\item|ã®é …ç›®ã®å­—下ã’å¹…ã§ã™ã€‚
+% \begin{macrocode}
+\newcommand{\@idxitem}{\par\hangindent 40\p@}
+\newcommand{\subitem}{\@idxitem \hspace*{20\p@}}
+\newcommand{\subsubitem}{\@idxitem \hspace*{30\p@}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\indexspace}
+% 索引ã®``文字''見出ã—ã®å‰ã«å…¥ã‚‹ã‚¹ãƒšãƒ¼ã‚¹ã§ã™ã€‚
+% \begin{macrocode}
+\newcommand{\indexspace}{\par \vskip 10\p@ \@plus5\p@ \@minus3\p@\relax}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{脚注}
+%
+% \begin{macro}{\footnoterule}
+% 本文ã¨è„šæ³¨ã®é–“ã«å¼•ã‹ã‚Œã‚‹ç½«ç·šã§ã™ã€‚
+% \changes{v1.7}{2016/11/12}{use \cs{@width} (sync with classes.dtx v1.3a)}
+% \begin{macrocode}
+\renewcommand{\footnoterule}{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern2.6\p@}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c@footnote}
+% reportã¨bookクラスã§ã¯ã€chapterレベルã§ãƒªã‚»ãƒƒãƒˆã•ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+%<!article>\@addtoreset{footnote}{chapter}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@makefntext}
+% ã“ã®ãƒžã‚¯ãƒ­ã«ã—ãŸãŒã£ã¦è„šæ³¨ãŒçµ„ã¾ã‚Œã¾ã™ã€‚
+%
+% |\@makefnmark|ã¯è„šæ³¨è¨˜å·ã‚’組ã¿ç«‹ã¦ã‚‹ãƒžã‚¯ãƒ­ã§ã™ã€‚
+% \changes{v1.7}{2016/11/12}{Replaced all \cs{hbox to} by
+% \cs{hb@xt@} (sync with classes.dtx v1.3a)}
+% \begin{macrocode}
+%<*tate>
+\newcommand\@makefntext[1]{\parindent 1\zw
+ \noindent\hb@xt@ 2\zw{\hss\@makefnmark}#1}
+%</tate>
+%<*yoko>
+\newcommand\@makefntext[1]{\parindent 1em
+ \noindent\hb@xt@ 1.8em{\hss\@makefnmark}#1}
+%</yoko>
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \section{今日ã®æ—¥ä»˜}
+% 組版時ã«ãŠã‘ã‚‹ç¾åœ¨ã®æ—¥ä»˜ã‚’出力ã—ã¾ã™ã€‚
+%
+% \iffalse meta-comment!
+% 注æ„:ã“ã“㧠\DisableCrossrefs, \EnableCrossrefs ã‚’ã—ã¦ã„ã‚‹ã®ã¯ã€
+% platex jclasses.dtx 㧠dvi を作るã¨ãã«ã‚¨ãƒ©ãƒ¼ã«ãªã‚‹ãŸã‚。
+% \fi
+% \DisableCrossrefs
+% \begin{macro}{\if西暦}
+% \begin{macro}{\西暦}
+% \begin{macro}{\和暦}
+% \changes{v1.0h}{1996/12/17}{Typo:和歴 to 和暦}
+% |\today|コマンドã®`å¹´'ã‚’ã€
+% 西暦ã‹å’Œæš¦ã®ã©ã¡ã‚‰ã§å‡ºåŠ›ã™ã‚‹ã‹ã‚’指定ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚
+% 2018å¹´7月以é™ã®æ—¥æœ¬èªž\TeX{}開発コミュニティ版(v1.8)ã§ã¯ã€
+% デフォルトを和暦ã§ã¯ãªã西暦ã«è¨­å®šã—ã¦ã„ã¾ã™ã€‚
+% \changes{v1.8}{2018/07/03}{\cs{today}ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã‚’和暦ã‹ã‚‰è¥¿æš¦ã«å¤‰æ›´}
+% \begin{macrocode}
+\newif\if西暦 \西暦true
+\def\西暦{\西暦true}
+\def\和暦{\西暦false}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \EnableCrossrefs
+%
+% \begin{macro}{\heisei}
+% \changes{v1.1m}{1998/04/07}{\cs{today}ã®è¨ˆç®—手順を変更}
+% \changes{v1.8b}{2019/04/02}{\cs{heisei}ã®å€¤ã¯$\mbox{西暦}-1988$ã§å›ºå®š}
+% |\today|コマンドを|\rightmark|ã§æŒ‡å®šã—ãŸã¨ãã€|\rightmark|を出力ã™ã‚‹éƒ¨åˆ†
+% ã§å’Œæš¦ã®ãŸã‚ã®è¨ˆç®—ãŒã§ããªã„ã®ã§ã€ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã‚’読ã¿è¾¼ã‚€æ™‚点ã§è¨ˆç®—ã—ã¦
+% ãŠãã¾ã™ã€‚
+% \begin{macrocode}
+\newcount\heisei \heisei\year \advance\heisei-1988\relax
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\today}
+% \begin{macro}{\pltx@today@year}
+% 縦組ã®å ´åˆã¯ã€æ¼¢æ•°å­—ã§å‡ºåŠ›ã—ã¾ã™ã€‚
+% \pLaTeX\ 2018-12-01以å‰ã§ã¯ç¸¦æ•°å¼ãƒ‡ã‚£ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³æ™‚ã§ã‚‚漢数字ã§å‡ºåŠ›ã—ã¦ã„ã¾ã—ãŸãŒã€
+% \pLaTeX\ 2019-04-06以é™ã‹ã‚‰ã¯ãã†ã—ãªããªã‚Šã¾ã—ãŸã€‚
+%
+% \changes{v1.6-ltj-9}{2015/01/01}{縦組ã§ã¯ï¼Œã“ã®æ¼¢æ•°å­—ã«ã‚ˆã‚‹æ—¥ä»˜å‡ºåŠ›ã§ã‚¨ãƒ©ãƒ¼ã«ãªã‚Šã¾ã—ãŸï¼Ž
+% Lua\TeX-ja ã§ã¯ï¼Œ\cs{kansuji}ã®å¾Œã«\cs{number}を続ã‘ã‚‹ã“ã¨ã¯å‡ºæ¥ãªã„ã®ã§\cs{number}を削除ã—ã¾ã—ãŸï¼Ž}
+% \changes{v1.8b}{2019/04/02}{\cs{today}ã®è¨ˆç®—・出力方法を変更。}
+% \begin{macrocode}
+\def\pltx@today@year@#1{%
+ \ifnum\numexpr\year-#1=1 å…ƒ\else
+ \ifnum\ltjgetparameter{direction}=3
+ \kansuji\numexpr\year-#1\relax
+ \else
+ \number\numexpr\year-#1\relax\nobreak
+ \fi
+ \fi å¹´
+}
+\def\pltx@today@year{%
+ \ifnum\numexpr\year*10000+\month*100+\day<19890108
+ 昭和\pltx@today@year@{1925}%
+ \else\ifnum\numexpr\year*10000+\month*100+\day<20190501
+ å¹³æˆ\pltx@today@year@{1988}%
+ \else
+ 令和\pltx@today@year@{2018}%
+ \fi\fi}
+\def\today{{%
+ \if西暦
+ \ifnum\ltjgetparameter{direction}=3 \kansuji\year
+ \else\number\year\nobreak\fi å¹´
+ \else
+ \pltx@today@year
+ \fi
+ \ifnum\ltjgetparameter{direction}=3
+ \kansuji\month 月
+ \kansuji\day æ—¥
+ \else
+ \number\month\nobreak 月
+ \number\day\nobreak æ—¥
+ \fi}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+% \section{åˆæœŸè¨­å®š}
+%
+% \begin{macro}{\prepartname}
+% \begin{macro}{\postpartname}
+% \begin{macro}{\prechaptername}
+% \begin{macro}{\postchaptername}
+% \begin{macrocode}
+\newcommand{\prepartname}{第}
+\newcommand{\postpartname}{部}
+%<report|book>\newcommand{\prechaptername}{第}
+%<report|book>\newcommand{\postchaptername}{ç« }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\contentsname}
+% \begin{macro}{\listfigurename}
+% \begin{macro}{\listtablename}
+% \begin{macrocode}
+\newcommand{\contentsname}{目 次}
+\newcommand{\listfigurename}{図 目 次}
+\newcommand{\listtablename}{表 目 次}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\refname}
+% \begin{macro}{\bibname}
+% \begin{macro}{\indexname}
+% \begin{macrocode}
+%<article>\newcommand{\refname}{å‚考文献}
+%<report|book>\newcommand{\bibname}{関連図書}
+\newcommand{\indexname}{索 引}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\figurename}
+% \begin{macro}{\tablename}
+% \begin{macrocode}
+\newcommand{\figurename}{図}
+\newcommand{\tablename}{表}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\appendixname}
+% \begin{macro}{\abstractname}
+% \begin{macrocode}
+\newcommand{\appendixname}{付 録}
+%<article|report>\newcommand{\abstractname}{概 è¦}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% |stfloats|パッケージãŒã‚·ã‚¹ãƒ†ãƒ ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã‚‹å ´åˆã¯ã€ã“ã®ãƒ‘ッケージを使ã£ã¦
+% p\LaTeX ã®æ¨™æº–時ã¨åŒã˜ã‚ˆã†ã«ãƒœãƒˆãƒ ãƒ•ãƒ­ãƒ¼ãƒˆã®ä¸‹ã«è„šæ³¨ãŒçµ„ã¾ã‚Œã‚‹ã‚ˆã†ã«ã—ã¾ã™ã€‚
+% \changes{v1.0d}{1996/02/29}{articleã¨reportã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã‚’
+% \pstyle{plain}ã«ä¿®æ­£}
+% \changes{v1.4}{2002/04/09}{縦組スタイルã§\cs{flushbottom}ã—ãªã„よã†ã«ã—ãŸ}
+% \changes{v1.7d-ltj-13}{2017/02/19}{p\LaTeX ã¨Lua\TeX-jaã®|\@makecol|ãŒé•ã†ã“ã¨ã‚’
+% 考慮ã—ã¦ã„ãªã‹ã£ãŸ}
+% \begin{macrocode}
+%<book>\pagestyle{headings}
+%<!book>\pagestyle{plain}
+\pagenumbering{arabic}
+\raggedbottom
+\fnfixbottomtrue % 2017-02-19
+\IfFileExists{stfloats.sty}{\RequirePackage{stfloats}\fnbelowfloat}{}
+\if@twocolumn
+ \twocolumn
+ \sloppy
+\else
+ \onecolumn
+\fi
+% \end{macrocode}
+% |\@mparswitch|ã¯å‚注を左å³ï¼ˆç¸¦çµ„ã§ã¯ä¸Šä¸‹ï¼‰ã©ã¡ã‚‰ã®ãƒžãƒ¼ã‚¸ãƒ³ã«
+% 出力ã™ã‚‹ã‹ã®æŒ‡å®šã§ã™ã€‚å½ã®å ´åˆã€å‚注ã¯ä¸€æ–¹ã®å´ã«ã—ã‹å‡ºåŠ›ã•ã‚Œã¾ã›ã‚“。
+% ã“ã®ã‚¹ã‚¤ãƒƒãƒã‚’真ã¨ã™ã‚‹ã¨ã€ã¨ãã«ç¸¦çµ„ã®å ´åˆã€å¥‡æ•°ãƒšãƒ¼ã‚¸ã§ã¯æœ¬æ–‡ã®ä¸Šã«ã€
+% å¶æ•°ãƒšãƒ¼ã‚¸ã§ã¯æœ¬æ–‡ã®ä¸‹ã«å‚注ãŒå‡ºåŠ›ã•ã‚Œã¾ã™ã®ã§ã€ãŠã‹ã—ãªã“ã¨ã«ãªã‚Šã¾ã™ã€‚
+%
+% ã¾ãŸã€ç¸¦çµ„ã®ã¨ãã«ã¯ã€å‚注を本文ã®ä¸‹ã«å‡ºã™ã‚ˆã†ã«ã—ã¦ã„ã¾ã™ã€‚
+% |\reversemarginpar|ã¨ã™ã‚‹ã¨æœ¬æ–‡ã®ä¸Šå´ã«å‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+% ãŸã ã—ã€äºŒæ®µçµ„ã®å ´åˆã¯ã€ã¤ã­ã«éš£æŽ¥ã™ã‚‹ãƒ†ã‚­ã‚¹ãƒˆå´ã®ãƒžãƒ¼ã‚¸ãƒ³ã«å‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+%<*tate>
+\normalmarginpar
+\@mparswitchfalse
+%</tate>
+%<*yoko>
+\if@twoside
+ \@mparswitchtrue
+\else
+ \@mparswitchfalse
+\fi
+%</yoko>
+%</article|report|book>
+% \end{macrocode}
+%
+% \section{å„種パッケージã¸ã®å¯¾å¿œ}
+% ã‚‚ã¨ã‚‚ã¨ç¸¦çµ„ã§ã®åˆ©ç”¨ã‚’想定ã•ã‚Œã¦ã„ãªã„ã„ãã¤ã‹ã®ãƒ‘ッケージã«ã¤ã„ã¦ã€
+% 補正ã™ã‚‹ãŸã‚ã®ã‚³ãƒ¼ãƒ‰ã‚’記述ã—ã¦ãŠãã¾ã™ã€‚
+% ã“ã®ç¯€ã®ã‚³ãƒ¼ãƒ‰ã¯|filehook|パッケージ(Lua\TeX-ja読ã¿è¾¼ã¿æ™‚ã«è‡ªå‹•ã§ãƒ­ãƒ¼ãƒ‰ã•ã‚Œã¾ã™ï¼‰
+% ã®æ©Ÿèƒ½ã‚’用ã„ã¦ã„ã¾ã™ã€‚
+%
+% \subsection{\texttt{ftnright}パッケージ}
+% 脚注番å·ã®æ›¸å¼ãŒ|ftnright|パッケージã«ã‚ˆã£ã¦å‹æ‰‹ã«æ›¸ãæ›ãˆã‚‰ã‚Œã‚‹ã®ã§ã€
+% パッケージ読ã¿è¾¼ã¿å‰ã«äºˆã‚退é¿ã—ã¦ãŠãã€èª­ã¿è¾¼ã¿å¾Œã«å¾©å¸°ã•ã›ã¾ã™ã€‚
+% \changes{v1.7d}{2017/02/19}{コード追加}
+% \begin{macrocode}
+%<*article|report|book>
+\AtBeginOfPackageFile*{ftnright}{\let\ltjt@orig@@makefntext=\@makefntext}
+\AtEndOfPackageFile*{ftnright}{\let\@makefntext=\ltjt@orig@@makefntext}
+%</article|report|book>
+% \end{macrocode}
+%
+%
+% \Finale
+%
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/ltjclasses.ins b/macros/luatex/generic/luatexja/src/ltjclasses.ins
new file mode 100644
index 0000000000..a4977146c7
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltjclasses.ins
@@ -0,0 +1,28 @@
+%
+% ltjclasses.ins
+%
+
+\input docstrip
+\keepsilent
+
+\generateFile{ltjarticle.cls}{f}{\from{ltjclasses.dtx}{article,yoko}}
+\generateFile{ltjreport.cls}{f}{\from{ltjclasses.dtx}{report,yoko}}
+\generateFile{ltjbook.cls}{f}{\from{ltjclasses.dtx}{book,yoko}}
+\generateFile{ltjsize10.clo}{f}{\from{ltjclasses.dtx}{10pt,yoko}}
+\generateFile{ltjsize11.clo}{f}{\from{ltjclasses.dtx}{11pt,yoko}}
+\generateFile{ltjsize12.clo}{f}{\from{ltjclasses.dtx}{12pt,yoko}}
+\generateFile{ltjbk10.clo}{f}{\from{ltjclasses.dtx}{10pt,bk,yoko}}
+\generateFile{ltjbk11.clo}{f}{\from{ltjclasses.dtx}{11pt,bk,yoko}}
+\generateFile{ltjbk12.clo}{f}{\from{ltjclasses.dtx}{12pt,bk,yoko}}
+
+\generateFile{ltjtarticle.cls}{f}{\from{ltjclasses.dtx}{article,tate}}
+\generateFile{ltjtreport.cls}{f}{\from{ltjclasses.dtx}{report,tate}}
+\generateFile{ltjtbook.cls}{f}{\from{ltjclasses.dtx}{book,tate}}
+\generateFile{ltjtsize10.clo}{f}{\from{ltjclasses.dtx}{10pt,tate}}
+\generateFile{ltjtsize11.clo}{f}{\from{ltjclasses.dtx}{11pt,tate}}
+\generateFile{ltjtsize12.clo}{f}{\from{ltjclasses.dtx}{12pt,tate}}
+\generateFile{ltjtbk10.clo}{f}{\from{ltjclasses.dtx}{10pt,bk,tate}}
+\generateFile{ltjtbk11.clo}{f}{\from{ltjclasses.dtx}{11pt,bk,tate}}
+\generateFile{ltjtbk12.clo}{f}{\from{ltjclasses.dtx}{12pt,bk,tate}}
+
+\endbatchfile
diff --git a/macros/luatex/generic/luatexja/src/ltjltxdoc.dtx b/macros/luatex/generic/luatexja/src/ltjltxdoc.dtx
new file mode 100644
index 0000000000..0a5c2b370f
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltjltxdoc.dtx
@@ -0,0 +1,218 @@
+% \iffalse meta-comment
+%% File: ltjltxdoc.dtx
+% -------------------------------------
+% Original: jltxdoc.dtx
+%
+% Copyright 1995,1996,1997 ASCII Corporation.
+%
+% This file is part of pLaTeX2e system.
+% -------------------------------------
+%
+% \fi
+%
+% \setcounter{StandardModuleDepth}{1}
+% \StopEventually{}
+%
+% \iffalse
+% \changes{v1.0a}{1997/01/23}{\LaTeX \texttt{!<1996/12/01!>}ã¸ã®å¯¾å¿œã«
+% åˆã‚ã›ã¦ä¿®æ­£}
+% \changes{v1.0b}{1997/07/29}{\cs{}ã¨\texttt{"}ã®\cs{xspcode}を変更}
+% \changes{v1.0b-ltj}{2011/09/27}{Lua\LaTeX-ja 用ã«ä¿®æ­£}
+% \changes{v1.0b-ltj-2}{2014/07/03}{orã‚’æ„味ã™ã‚‹ç¸¦æ£’ã®å‡ºåŠ›ãŒç•°å¸¸ã ã£ãŸã®ã§ä¿®æ­£}
+% \changes{v1.0c}{2016/07/25}{docパッケージãŒä¸Šæ›¸ãã™ã‚‹\cs{verb}ã‚’å†ã€…定義}
+% \changes{v1.0d}{2017/09/24}{\cs{vadjust\{\}}を追加}
+% \changes{v1.0d-ltj-3}{2018/01/01}{\cs{Cjascale}を追加}
+% \fi
+%
+% \iffalse
+%<class>
+%<class>\NeedsTeXFormat{LaTeX2e}
+%<class>\ProvidesClass{ltjltxdoc}[2018/01/01 v1.0d-ltj-3 Standard LuaLaTeX-ja file]
+%<*driver>
+\documentclass{ltjltxdoc}
+\GetFileInfo{ltjltxdoc.cls}
+\usepackage[kozuka-pr6n]{luatexja-preset}
+\usepackage{unicode-math}
+\setmathfont{Latin Modern Math}
+\title{Lua\LaTeX-jaドキュメント記述用クラス}
+\author{Lua\TeX-jaプロジェクト}
+\date{\filedate}
+\begin{document}
+ \maketitle
+ \DocInput{ltjltxdoc.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \file{ltjltxdoc}クラスã¯ã€\file{ltxdoc}をテンプレートã«ã—ã¦ã€æ—¥æœ¬èªžç”¨ã®
+% 修正を加ãˆã¦ã„ã¾ã™ã€‚
+% \begin{macrocode}
+%<*class>
+\DeclareOption*{\PassOptionsToClass{\CurrentOption}{ltxdoc}}
+\ProcessOptions
+\LoadClass{ltxdoc}
+% \end{macrocode}
+% \file{ltxdoc}ã®èª­ã¿è¾¼ã¿å¾Œã«\file{luatexja}を読ã¿è¾¼ã¿ã¾ã™ã€‚
+%
+% \changes{v1.60d-ltj-3}{2018/01/01}{\cs{Cjascale}を追加ã—ã¾ã—ãŸã€‚
+% ã“ã‚Œã¯ã€ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ç‰ˆp\kern-.05em\LaTeX ã§å°Žå…¥ã•ã‚ŒãŸã€
+% 和文スケール($1\,\cs{zw} \div \hbox{è¦æ±‚サイズ}$)を表ã™å®Ÿæ•°å€¤ãƒžã‚¯ãƒ­ã§ã™ã€‚}
+%
+% \begin{macrocode}
+\RequirePackage{luatexja}
+\def\Cjascale{0.962216}
+% \end{macrocode}
+%
+% \begin{macro}{\normalsize}
+% \begin{macro}{\small}
+% \begin{macro}{\parindent}
+% \changes{v1.0a}{1997/01/23}{\cs{normalsize}, \cs{small}ãªã©ã®å†å®šç¾©}
+% \file{ltxdoc}ã‹ã‚‰ãƒ­ãƒ¼ãƒ‰ã•ã‚Œã‚‹\file{article}クラスã§ã®è¡Œé–“ãªã©ã®è¨­å®šå€¤ã§ã€
+% 日本語ã®æ–‡ç« ã‚’組版ã™ã‚‹ã¨ã€è¡Œé–“ãŒç‹­ã„よã†ã«æ€ã‚れるã®ã§ã€å¤šå°‘広ãã™ã‚‹ã‚ˆã†ã«
+% å†è¨­å®šã—ã¾ã™ã€‚ã¾ãŸã€æ®µè½å…ˆé ­ã§ã®å­—下ã’é‡ã‚’全角一文字分ã¨ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\renewcommand{\normalsize}{%
+ \@setfontsize\normalsize\@xpt{15}%
+ \abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@
+ \abovedisplayshortskip \z@ \@plus3\p@
+ \belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@
+ \belowdisplayskip \abovedisplayskip
+ \let\@listi\@listI}
+\renewcommand{\small}{%
+ \@setfontsize\small\@ixpt{11}%
+ \abovedisplayskip 8.5\p@ \@plus3\p@ \@minus4\p@
+ \abovedisplayshortskip \z@ \@plus2\p@
+ \belowdisplayshortskip 4\p@ \@plus2\p@ \@minus2\p@
+ \def\@listi{\leftmargin\leftmargini
+ \topsep 4\p@ \@plus2\p@ \@minus2\p@
+ \parsep 2\p@ \@plus\p@ \@minus\p@
+ \itemsep \parsep}%
+ \belowdisplayskip \abovedisplayskip}
+\normalsize
+\setlength\parindent{1\zw}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\file}
+% |\file|マクロã¯ã€ãƒ•ã‚¡ã‚¤ãƒ«åを示ã™ã®ã«ç”¨ã„ã¾ã™ã€‚
+% \begin{macrocode}
+\providecommand*{\file}[1]{\texttt{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pstyle}
+% |\pstyle|マクロã¯ã€ãƒšãƒ¼ã‚¸ã‚¹ã‚¿ã‚¤ãƒ«åを示ã™ã®ã«ç”¨ã„ã¾ã™ã€‚
+% \begin{macrocode}
+\providecommand*{\pstyle}[1]{\textsl{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\Lcount}
+% |\Lcount|マクロã¯ã€ã‚«ã‚¦ãƒ³ã‚¿åを示ã™ã®ã«ç”¨ã„ã¾ã™ã€‚
+% \begin{macrocode}
+\providecommand*{\Lcount}[1]{\textsl{\small#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\Lopt}
+% |\Lopt|マクロã¯ã€ã‚¯ãƒ©ã‚¹ã‚ªãƒ—ションやパッケージオプションを示ã™ã®ã«ç”¨ã„ã¾ã™ã€‚
+% \begin{macrocode}
+\providecommand*{\Lopt}[1]{\textsf{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dst}
+% |\dst|マクロã¯ã€``\dst''を出力ã™ã‚‹ã€‚
+% \begin{macrocode}
+\providecommand\dst{{\normalfont\scshape docstrip}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\NFSS}
+% |\NFSS|マクロã¯ã€``\NFSS''を出力ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\providecommand\NFSS{\textsf{NFSS}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c@clineno}
+% \begin{macro}{\mlineplus}
+% |\mlineplus|マクロã¯ã€ãã®æ™‚点ã§ã®ãƒžã‚¯ãƒ­ã‚³ãƒ¼ãƒ‰ã®è¡Œç•ªå·ã«ã€å¼•æ•°ã«æŒ‡å®šã•ã‚ŒãŸ
+% 行数ã ã‘を加ãˆãŸæ•°å€¤ã‚’出力ã—ã¾ã™ã€‚ãŸã¨ãˆã°|\mlineplus{3}|ã¨ã™ã‚Œã°ã€
+% ç›´å‰ã®ãƒžã‚¯ãƒ­ã‚³ãƒ¼ãƒ‰ã®è¡Œç•ªå·(\arabic{CodelineNo})ã«3を加ãˆãŸæ•°ã€
+% ``\mlineplus{3}''ãŒå‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+% \begin{macrocode}
+\newcounter{@clineno}
+\def\mlineplus#1{\setcounter{@clineno}{\arabic{CodelineNo}}%
+ \addtocounter{@clineno}{#1}\arabic{@clineno}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{environment}{tsample}
+% |tsample|環境ã¯ã€ç’°å¢ƒå†…ã«æŒ‡å®šã•ã‚ŒãŸå†…容を罫線ã§å›²ã£ã¦å‡ºåŠ›ã‚’ã—ã¾ã™ã€‚
+% 第一引数ã¯ã€å‡ºåŠ›ã™ã‚‹ãƒœãƒƒã‚¯ã‚¹ã®é«˜ã•ã§ã™ã€‚
+% ã“ã®ãƒžã‚¯ãƒ­å†…ã§ã¯ç¸¦çµ„ã«ãªã‚‹ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。
+% \begin{macrocode}
+\def\tsample#1{%
+ \hbox to\linewidth\bgroup\vrule width.1pt\hss
+ \vbox\bgroup\hrule height.1pt
+ \vskip.5\baselineskip
+ \vbox to\linewidth\bgroup\tate\hsize=#1\relax\vss}
+\def\endtsample{%
+ \vss\egroup
+ \vskip.5\baselineskip
+ \hrule height.1pt\egroup
+ \hss\vrule width.1pt\egroup}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\verb}
+% p\LaTeX{}ã§ã¯ã€|\verb|コマンドを修正ã—ã¦ç›´å‰ã«|\xkanjiskip|ãŒå…¥ã‚‹ã‚ˆã†ã«
+% ã—ã¦ã„ã¾ã™ã€‚ã—ã‹ã—ã€\file{ltxdoc.cls}ãŒèª­ã¿è¾¼ã‚€\file{doc.sty}ãŒä¸Šæ›¸ã
+% ã—ã¦ã—ã¾ã„ã¾ã™ã®ã§ã€ã“れをå†ã€…定義ã—ã¾ã™ã€‚\file{doc.sty}ã§ã®å®šç¾©ã¯
+%\begin{verbatim}
+% \def\verb{\relax\ifmmode\hbox\else\leavevmode\null\fi
+% \bgroup \let\do\do@noligs \verbatim@nolig@list
+% \ttfamily \verb@eol@error \let\do\@makeother \dospecials
+% \@ifstar{\@sverb}{\@vobeyspaces \frenchspacing \@sverb}}
+%\end{verbatim}
+% ã¨ãªã£ã¦ã„ã¾ã™ã®ã§ã€\file{plcore.dtx}ã¨åŒæ§˜ã«|\null|を外ã—ã¦|\vadjust{}|ã‚’
+% 入れã¾ã™ã€‚
+% \changes{v1.0c}{2016/07/25}{docパッケージãŒä¸Šæ›¸ãã™ã‚‹\cs{verb}ã‚’å†ã€…定義}
+% \changes{v1.0d}{2017/09/24}{\cs{vadjust\{\}}を追加}
+% \begin{macrocode}
+\def\verb{\relax\ifmmode\hbox\else\leavevmode\vadjust{}\fi
+ \bgroup \let\do\do@noligs \verbatim@nolig@list
+ \ttfamily \verb@eol@error \let\do\@makeother \dospecials
+ \@ifstar{\@sverb}{\@vobeyspaces \frenchspacing \@sverb}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{alxspmode}
+% コマンドåã®|\|ã¨16進数を示ã™ãŸã‚ã®|"|ã®å‰ã«ã‚‚スペースãŒå…¥ã‚‹ã‚ˆã†ã€
+% ã“れらã®|alxspmode|ã®å€¤ã‚’変更ã—ã¾ã™ã€‚
+% \changes{v1.0b}{1997/07/29}{\cs{}ã¨\texttt{"}ã®\cs{xspcode}を変更}
+% \changes{v1.0b-ltj}{2011/09/27}{\cs{xspcode}→\cs{ltjsetparameter{alxspmode={...}}}}
+% \begin{macrocode}
+\ltjsetparameter{alxspmode={"5C,3}} %% \
+\ltjsetparameter{alxspmode={"22,3}} %% "
+%</class>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{mod@math@codes}
+% docパッケージã§ã¯ï¼Œãƒ‰ãƒ©ã‚¤ãƒæŒ‡å®šã®è¡¨ç¤ºã®éƒ¨åˆ†ã«ãŠã‘ã‚‹\texttt{\char`\|}ã®
+% \cs{mathcode}ã¯\texttt{"226A}ã«ãªã£ã¦ãŠã‚Šï¼Œã“ã‚Œã«ã‚ˆã‚Š\texttt{\char`\|}ãŒå°æ–‡å­—ã®jã§è¡¨ç¤ºã•ã‚Œã¦
+% ã—ã¾ã†çŠ¶æ³ã«ãªã£ã¦ã„ã¾ã™ï¼Žæ”¹å–„ã™ã‚‹ãŸã‚,\texttt{"207C}ã«å¤‰æ›´ã—ã¾ã™ï¼Ž
+% \begin{macrocode}
+\def\mod@math@codes{\mathcode`\|="207C \mathcode`\&="2026
+ \mathcode`\-="702D \mathcode`\+="702B
+ \mathcode`\:="703A \mathcode`\=="703D }
+% \end{macrocode}
+% \end{macro}
+% \Finale
+%
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/ltjltxdoc.ins b/macros/luatex/generic/luatexja/src/ltjltxdoc.ins
new file mode 100644
index 0000000000..e07f3bf365
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltjltxdoc.ins
@@ -0,0 +1,10 @@
+%
+% ltjltxdoc.ins
+%
+
+\input docstrip
+\keepsilent
+
+\generateFile{ltjltxdoc.cls}{f}{\from{ltjltxdoc.dtx}{class}}
+
+\endbatchfile
diff --git a/macros/luatex/generic/luatexja/src/ltjsclasses.dtx b/macros/luatex/generic/luatexja/src/ltjsclasses.dtx
new file mode 100644
index 0000000000..be67a2f68e
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltjsclasses.dtx
@@ -0,0 +1,5709 @@
+% \iffalse meta-comment
+%% File: ltjsclasses.dtx
+% -----------------------------------------
+% Original: jsclasses.dtx
+%
+% pLaTeX2ε新ドキュメントクラス(日本語 TeX 開発コミュニティ版)
+% 原作者:奥æ‘晴彦 <okumura@okumuralab.org>
+%
+% Copyright 1993-2016
+% The LaTeX3 Project and any individual authors listed elsewhere
+% in this file.
+%
+% Copyright 1995-1999 ASCII Corporation.
+% Copyright 1999-2016 Haruhiko Okumura
+% Copyright 2016-2018 Japanese TeX Development Community
+% -----------------------------------------
+%
+% \fi
+%% \CharacterTable
+%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%% Digits \0\1\2\3\4\5\6\7\8\9
+%% Exclamation \! Double quote \" Hash (number) \#
+%% Dollar \$ Percent \% Ampersand \&
+%% Acute accent \' Left paren \( Right paren \)
+%% Asterisk \* Plus \+ Comma \,
+%% Minus \- Point \. Solidus \/
+%% Colon \: Semicolon \; Less than \<
+%% Equals \= Greater than \> Question mark \?
+%% Commercial at \@ Left bracket \[ Backslash \\
+%% Right bracket \] Circumflex \^ Underscore \_
+%% Grave accent \` Left brace \{ Vertical bar \|
+%% Right brace \} Tilde \~}
+%
+% \iffalse
+%
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+%<article>\ProvidesClass{ltjsarticle}
+%<book>\ProvidesClass{ltjsbook}
+%<report>\ProvidesClass{ltjsreport}
+%<jspf>\ProvidesClass{ltjspf}
+%<kiyou>\ProvidesClass{ltjskiyou}
+%<*driver>
+\ProvidesFile{ltjsclasses.dtx}
+%</driver>
+ [2019/08/12 ltjsclasses ]
+%<*driver>
+\IfFileExists{luatex85.sty}{\RequirePackage{luatex85}}{}
+\documentclass[disablejfam]{ltjsarticle}
+\usepackage{hypdoc}
+\hypersetup{unicode=true}
+\begingroup
+ \suppressfontnotfounderror=1
+ \global\font\testfont=file:KozMinPr6N-Regular.otf
+\endgroup
+\ifx\testfont\nullfont
+ \usepackage[ipaex,nfssonly]{luatexja-preset}
+\else
+ \usepackage[kozuka-pr6n,nfssonly]{luatexja-preset}
+\fi
+\ltjsetparameter{alxspmode={`\*,allow}}
+\ltjsetparameter{alxspmode={`\\,allow}}
+%%%%\usepackage{unicode-math}
+%%%%\setmathfont{Latin Modern Math}
+\addtolength{\textwidth}{-1in}
+\addtolength{\evensidemargin}{1in}
+\addtolength{\oddsidemargin}{1in}
+\addtolength{\marginparwidth}{1in}
+\setlength\marginparpush{0pt}
+% \OnlyDescription
+\CodelineNumbered
+\EnableCrossrefs
+\setcounter{StandardModuleDepth}{1}
+\GetFileInfo{ltjsclasses.dtx}
+\begin{document}
+\DocInput{ltjsclasses.dtx}
+\end{document}
+%</driver>
+% \end{macrocode}
+%
+% \fi
+%
+% \title{Lua\LaTeX-ja用\texttt{jsclasses}互æ›ã‚¯ãƒ©ã‚¹}
+% \author{Lua\TeX-jaプロジェクト}
+% \date{\filedate}
+% \maketitle
+% \tableofcontents
+%
+% \MakeShortVerb{\|}
+%
+% \section{ã¯ã˜ã‚ã«}
+%
+% ã“ã‚Œã¯ï¼Œå…ƒã€…奥æ‘晴彦先生ã«ã‚ˆã‚Šä½œæˆã•ã‚Œï¼Œç¾åœ¨ã¯æ—¥æœ¬èªž\TeX 開発コミュニティã«ã‚ˆã‚Š
+% 管ç†ã•ã‚Œã¦ã„ã‚‹\texttt{jsclasses.dtx}ã‚’Lua\LaTeX-ja用ã«æ”¹å¤‰ã—ãŸã‚‚ã®ã§ã™ã€‚
+% 次ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚¯ãƒ©ã‚¹ï¼ˆã‚¹ã‚¿ã‚¤ãƒ«ãƒ•ã‚¡ã‚¤ãƒ«ï¼‰ã‚’生æˆã—ã¾ã™ã€‚
+%
+% [2017-02-13] forum:2121ã®è­°è«–ã‚’æ©Ÿã«ï¼Œltjsreportクラスを新設ã—ã¾ã—ãŸã€‚
+% 従æ¥ã®ltjsbookã® |report| オプションã¨æ¯”ã¹ã‚‹ã¨ï¼Œ|abstract| 環境ã®ä½¿ã„æ–¹
+% ãŠã‚ˆã³æŒ™å‹•ãŒã‚¢ã‚¹ã‚­ãƒ¼ã®jreportã«è¿‘ã¥ãã¾ã—ãŸã€‚
+%
+% \begin{quote}
+% \begin{tabular}{lll}
+% $\langle$\textsf{article}$\rangle$ & \texttt{ltjsarticle.cls} & 論文・レãƒãƒ¼ãƒˆç”¨ \\
+% $\langle$\textsf{book}$\rangle$ & \texttt{ltjsbook.cls} & 書ç±ç”¨ \\
+% $\langle$\textsf{report}$\rangle$ & \texttt{ltjsreport.cls} & レãƒãƒ¼ãƒˆç”¨ \\
+% $\langle$\textsf{jspf}$\rangle$ & \texttt{ltjspf.cls} & æŸå­¦ä¼šèªŒç”¨ \\
+% $\langle$\textsf{kiyou}$\rangle$ & \texttt{ltjskiyou.cls} & æŸç´€è¦ç”¨
+% \end{tabular}
+% \end{quote}
+%
+% \subsection{\texttt{jsclasses.dtx}ã‹ã‚‰ã®ä¸»ãªå¤‰æ›´ç‚¹}
+% å…¨ã¦ã®å¤‰æ›´ç‚¹ã‚’知りãŸã„å ´åˆã¯ï¼Œ\texttt{jsclasses.dtx}ã¨\texttt{ltjsclasses.dtx}ã§diffã‚’
+% ã¨ã£ã¦ä¸‹ã•ã„。zw, zh ã¯å…¨ã¦ |\zw|, |\zh| ã«ç½®ãæ›ãˆã‚‰ã‚Œã¦ã„ã¾ã™ã€‚
+% \begin{itemize}
+% \item フォントメトリック関係ã®ã‚ªãƒ—ション\texttt{winjis}ã¯å˜ã«ç„¡è¦–ã•ã‚Œã¾ã™ã€‚
+% \item 標準ã§ã¯\texttt{jfm-ujis.lua}(Lua\TeX-ja標準ã®ãƒ¡ãƒˆãƒªãƒƒã‚¯ï¼ŒOTFパッケージã®ã‚‚ã®ãŒãƒ™ãƒ¼ã‚¹ï¼‰ã‚’使用ã—ã¾ã™ã€‚
+% \item \texttt{uplatex}オプション,\texttt{autodetect-engine}オプションを
+% 削除ã—ã¦ã‚ã‚Šã¾ã™ï¼ˆå‰è€…ã§ã¯ã‚¨ãƒ©ãƒ¼ã‚’出ã™ã‚ˆã†ã«ã—ã¦ã„ã¾ã™ï¼‰ã€‚
+% \item \texttt{disablejfam}オプションã¯ã‚¯ãƒ©ã‚¹å´ã§ã¯ä½•ã‚‚ã—ã¾ã›ã‚“(ãŸã Lua\TeX-ja本体ã«
+% 渡ã•ã‚Œã‚‹ã ã‘ã§ã™ï¼‰ï¼Žã‚‚ã—
+% \begin{quotation}
+% |! LaTeX Error: Too many math alphabets used in version ****.|
+% \end{quotation}
+% ã®ã‚¨ãƒ©ãƒ¼ãŒèµ·ã“ã£ãŸå ´åˆã¯ï¼Œ\texttt{lualatex-math}パッケージを読ã¿è¾¼ã‚“ã§ã¿ã¦ä¸‹ã•ã„。
+% \item \texttt{papersize}オプションã®æŒ‡å®šã«é–¢ã‚らãšPDFã®ãƒšãƒ¼ã‚¸ã‚µã‚¤ã‚ºã¯é©åˆ‡ã«
+% 設定ã•ã‚Œã¾ã™ã€‚
+% \item Lua\TeX-jaåŒæ¢±ã®ãƒ¡ãƒˆãƒªãƒƒã‚¯ã‚’用ã„ã‚‹é™ã‚Šã¯ï¼Œæ®µè½ã®é ­ã«ã‚°ãƒ«ãƒ¼ã¯æŒ¿å…¥ã•ã‚Œã¾ã›ã‚“。
+% ãã®ãŸã‚,オリジナルã®\texttt{jsclasses}内ã«ã‚ã£ãŸhack (|\everyparhook|)ã¯ä¸è¦ã«ãªã£ãŸã®ã§ï¼Œ
+% 削除ã—ã¾ã—ãŸã€‚
+% \item 「\texttt{amsmath}ã¨ã®è¡çªã®å›žé¿ã€ã®ã‚³ãƒ¼ãƒ‰ã¯ï¼Œä¸Šæµã§æ—¢ã«å¯¾å‡¦ã•ã‚Œã¦ã„ã‚‹ã†ãˆï¼Œ
+% ã“ã‚ŒãŒã‚ã‚‹ã¨\texttt{grfext.sty}を読ã¿è¾¼ã‚“ã éš›ã«ã‚¨ãƒ©ãƒ¼ã‚’引ãèµ·ã“ã™ã®ã§å‰Šé™¤ã—ã¾ã—ãŸã€‚
+% \item 本家\texttt{jsclasses}ã§ã¯ |\mag| を用ã„ã¦ã€Œ10\,pt時ã®çµ„版çµæžœã‚’本文フォントサイズã«åˆã‚ã›æ‹¡å¤§ç¸®å°ã€
+% ã¨ã„ã†æ–¹é‡ã§ã—ãŸãŒï¼Œæœ¬\texttt{ltjsclasses}ã§ã¯ãã®ã‚ˆã†ãªæ–¹æ³•ã‚’å–ã£ã¦ã„ã¾ã›ã‚“。
+% \begin{itemize}
+% \item \texttt{nomag}オプション指定時ã«ã¯ï¼Œå˜ã«ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã«ç”¨ã„ã‚‹å„種長ã•ã®å€¤ã‚’スケールã•ã›ã‚‹ã ã‘ã§ã™ã€‚
+% ãã®ãŸã‚,例ãˆã°æœ¬æ–‡ã®æ–‡å­—サイズãŒ17\,ptã®ã¨ãã«ã¯cmr10ã§ãªãcmr17を用ã„ã‚‹ã“ã¨ã«ãªã‚Šï¼Œçµ„版çµæžœã®å°è±¡ãŒ
+% ç•°ãªã‚‹æã‚ŒãŒã‚ã‚Šã¾ã™ã€‚
+% \item \texttt{nomag*}オプション指定時ã«ã¯ï¼Œä¸Šè¨˜ã«åŠ ãˆã¦ã‚ªãƒ—ティカルサイズを調整ã™ã‚‹ï¼ˆæœ¬æ–‡ã§ã¯cmr17ã®ä»£ã‚ã‚Šã«
+% cmr10を拡大縮å°ã™ã‚‹ï¼Œãªã©ï¼‰ãŸã‚,\LaTeX ã®ãƒ•ã‚©ãƒ³ãƒˆé¸æŠžã‚·ã‚¹ãƒ†ãƒ NFSSã¸ãƒ‘ッãƒã‚’当ã¦ã¾ã™ã€‚
+% ã“ã†ã™ã‚‹ã“ã¨ã§å‰é …ã«æ›¸ã„ãŸä¸å…·åˆã¯ãªããªã‚Šã¾ã™ãŒï¼Œã‹ãˆã£ã¦åˆ¥ã®ä¸å…·åˆãŒèµ·ãã‚‹å¯èƒ½æ€§
+% ã¯ã‚ã‚Šã¾ã™\footnote{%
+% \texttt{nomag*}ã¯\texttt{jsclasses}ã§ã‚‚利用å¯èƒ½ã§ã™ãŒï¼Œ\texttt{ltjsclasses}ã§ã¯\texttt{jsclasses}ã¨ã¯
+% 別ã®å®Ÿè£…ã‚’ã—ã¦ã„ã¾ã™ã€‚
+% }。
+% \end{itemize}
+% 標準ã§ã¯\texttt{nomag*}オプションãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚\texttt{jsclasses}ã§ç”¨æ„ã•ã‚Œï¼Œã‹ã¤æ—¢å®šã«ãªã£ã¦ã„ã‚‹
+% \texttt{usemag}オプションを指定ã™ã‚‹ã¨è­¦å‘Šã‚’出ã—ã¾ã™ã€‚
+% \end{itemize}
+%
+% [2014-02-07 LTJ] jsclasses 2014-02-07 ベースã«ã—ã¾ã—ãŸã€‚
+%
+% [2014-07-26 LTJ] 縦組用和文フォントã®è¨­å®šã‚’加ãˆã¾ã—ãŸã€‚
+%
+% [2014-12-24 LTJ] |\@setfontsize| 中ã®å’Œæ¬§æ–‡é–“空白ã®è¨­å®šã§ if æ–‡ãŒæŠœã‘ã¦ã„ãŸã®ã‚’ç›´ã—ã¾ã—ãŸã€‚
+%
+% [2016-01-30 LTJ] |\rmfamily| ä»–ã§å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãƒ•ã‚¡ãƒŸãƒªã‚‚変更ã™ã‚‹ã‚³ãƒ¼ãƒ‰ã‚’
+% Lua\TeX-ja カーãƒãƒ«å†…ã«ç§»ã—ã¾ã—ãŸã€‚
+%
+% [2016-03-21 LTJ] Lua\TeX~beta-0.87.0 ã§ã¯PDF出力時ã«|\mag|ãŒä½¿ç”¨ã§ããªããªã£ãŸã®ã§ï¼Œ
+% ZRã•ã‚“ã®\texttt{bxjscls}ã‚’å‚考ã«ä½¿ã‚ãªã„よã†ã«æ›¸ãæ›ãˆã¾ã—ãŸã€‚
+%
+% [2016-03-31 LTJ] \texttt{xreal}オプションを標準ã§æœ‰åŠ¹ã«ã—ã¾ã—ãŸã€‚
+%
+% [2016-07-12 LTJ] \texttt{jsclasses}開発版ã«åˆã‚ã›ï¼Œ\texttt{real},~\texttt{xreal}オプションã®å称を変更ã™ã‚‹ãªã©ã®å¤‰æ›´ã‚’è¡Œã„ã¾ã—ãŸã€‚
+%
+% [2016-07-18 LTJ] \texttt{usemag}オプションãŒæŒ‡å®šã•ã‚Œã‚‹ã¨è­¦å‘Šã‚’出ã™ã‚ˆã†ã«ã—ã¾ã—ãŸã€‚
+%
+% [2016-07-21 LTJ] \LaTeX ç­‰ã®ãƒ­ã‚´ã®å†å®šç¾©ã§ï¼Œ\texttt{jslogo}パッケージãŒã‚ã‚Œã°ãã¡ã‚‰ã‚’読ã¿è¾¼ã‚€ã“ã¨ã«ã—ã¾ã—ãŸã€‚
+%
+% [2016-10-13 LTJ] \texttt{slide}オプションã®ä½¿ç”¨æ™‚ã«ã‚¨ãƒ©ãƒ¼ãŒå‡ºã‚‹ã®ã‚’修正.
+%
+% \StopEventually{}
+%
+% 以下ã§ã¯å®Ÿéš›ã®ã‚³ãƒ¼ãƒ‰ã«å³ã—ã¦èª¬æ˜Žã—ã¾ã™ã€‚
+%
+% \begin{macro}{\jsc@clsname}
+%
+% 文書クラスã®åå‰ã§ã™ã€‚エラーメッセージ表示ãªã©ã§ä½¿ã‚ã‚Œã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<article>\def\jsc@clsname{ltjsarticle}
+%<book>\def\jsc@clsname{ltjsbook}
+%<report>\def\jsc@clsname{ltjsreport}
+%<jspf>\def\jsc@clsname{ltjspf}
+%<kiyou>\def\jsc@clsname{ltjskiyou}
+% \end{macrocode}
+% \end{macro}
+%
+% \section{Lua\TeX-jaã®èª­ã¿è¾¼ã¿}
+%
+% 和文スケール値を設定ã—ãŸå¾Œã«ï¼ŒLua\TeX-jaを読ã¿è¾¼ã¿ã¾ã™ã€‚
+% \begin{macrocode}
+%<!jspf>\def\Cjascale{0.924715}
+%<jspf>\def\Cjascale{0.903375}
+\RequirePackage{luatexja}
+% \end{macrocode}
+%
+% \section{オプション}
+%
+% ã“れらã®ã‚¯ãƒ©ã‚¹ã¯ |\documentclass{ltjsarticle}|
+% ã‚ã‚‹ã„㯠|\documentclass[オプション]{ltjsarticle}|
+% ã®ã‚ˆã†ã«å‘¼ã³å‡ºã—ã¾ã™ã€‚
+%
+% ã¾ãšï¼Œã‚ªãƒ—ションã«é–¢é€£ã™ã‚‹ã„ãã¤ã‹ã®ã‚³ãƒžãƒ³ãƒ‰ã‚„スイッãƒï¼ˆè«–ç†å¤‰æ•°ï¼‰ã‚’定
+% 義ã—ã¾ã™ã€‚
+%
+% \begin{macro}{\if@restonecol}
+%
+% 段組ã®ã¨ãã«çœŸã«ãªã‚‹è«–ç†å¤‰æ•°ã§ã™ã€‚
+%
+% \begin{macrocode}
+\newif\if@restonecol
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if@titlepage}
+%
+% ã“れを真ã«ã™ã‚‹ã¨è¡¨é¡Œï¼Œæ¦‚è¦ã‚’独立ã—ãŸãƒšãƒ¼ã‚¸ã«å‡ºåŠ›ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\newif\if@titlepage
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if@openright}
+%
+% |\chapter|,|\part| ã‚’å³ãƒšãƒ¼ã‚¸èµ·ã“ã—ã«ã™ã‚‹ã‹ã©ã†ã‹ã§ã™ã€‚
+% 横組ã®æ›¸ç±ã§ã¯çœŸãŒæ¨™æº–ã§ï¼Œè¦ã™ã‚‹ã«ç‰‡èµ·ã“ã—,奇数ページ起ã“ã—ã«ãªã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<book|report>\newif\if@openright
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if@openleft}
+%
+% [2017-02-24] |\chapter|,|\part| を左ページ起ã“ã—ã«ã™ã‚‹ã‹ã©ã†ã‹ã§ã™ã€‚
+%
+% \begin{macrocode}
+%<book|report>\newif\if@openleft
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if@mainmatter}
+%
+% 真ãªã‚‰æœ¬æ–‡ï¼Œå½ãªã‚‰å‰ä»˜ã‘・後付ã‘ã§ã™ã€‚
+% å½ãªã‚‰ |\chapter| ã§ç« ç•ªå·ãŒå‡ºã¾ã›ã‚“。
+%
+% \begin{macrocode}
+%<book>\newif\if@mainmatter \@mainmattertrue
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if@enablejfam}
+%
+% 和文フォントを数å¼ãƒ•ã‚©ãƒ³ãƒˆã¨ã—ã¦ç™»éŒ²ã™ã‚‹ã‹ã©ã†ã‹ã‚’示ã™ã‚¹ã‚¤ãƒƒãƒã§ã™ãŒï¼Œ
+% 実際ã«ã¯ç”¨ã„られã¾ã›ã‚“。
+%
+% \begin{macrocode}
+\newif\if@enablejfam \@enablejfamtrue
+% \end{macrocode}
+% \end{macro}
+%
+% 以下ã§å„オプションを宣言ã—ã¾ã™ã€‚
+%
+% \paragraph{用紙サイズ}
+%
+% JISã‚„ISOã®A0判ã¯é¢ç© $1\,\mathrm{m}^2$,縦横比 $1:\sqrt{2}$
+% ã®é•·æ–¹å½¢ã®è¾ºã®é•·ã•ã‚’ mm å˜ä½ã«åˆ‡ã‚Šæ¨ã¦ãŸã‚‚ã®ã§ã™ã€‚
+% ã“れを基準ã¨ã—ã¦é †ã«åŠæˆªã—ã¦ã¯ mm å˜ä½ã«åˆ‡ã‚Šæ¨ã¦ãŸã‚‚ã®ãŒA1,A2,…ã§ã™ã€‚
+%
+% B判ã¯JISã¨ISOã§å®šç¾©ãŒç•°ãªã‚Šã¾ã™ã€‚
+% JISã§ã¯B0判ã®é¢ç©ãŒ $1.5\,\mathrm{m}^2$ ã§ã™ãŒï¼Œ
+% ISOã§ã¯B1判ã®è¾ºã®é•·ã•ãŒA0判ã¨A1判ã®è¾ºã®é•·ã•ã®å¹¾ä½•å¹³å‡ã§ã™ã€‚
+% ã—ãŸãŒã£ã¦ISOã®B0判㯠$1000\,\mathrm{mm} \times 1414\,\mathrm{mm}$ ã§ã™ã€‚
+% ã“ã®ãŸã‚,\LaTeXe ã® \texttt{b5paper}
+% 㯠$250\,\mathrm{mm} \times 176\,\mathrm{mm}$ ã§ã™ãŒï¼Œ
+% \pLaTeXe ã® \texttt{b5paper}
+% 㯠$257\,\mathrm{mm} \times 182\,\mathrm{mm}$ ã«ãªã£ã¦ã„ã¾ã™ã€‚
+% ã“ã“ã§ã¯\pLaTeXe ã«ãªã‚‰ã£ã¦JISã«å¾“ã„ã¾ã—ãŸã€‚
+%
+% デフォルト㯠\texttt{a4paper} ã§ã™ã€‚
+%
+% \texttt{b5var}(B5変形,182mm×230mm),
+% \texttt{a4var}(A4変形,210mm×283mm)を追加ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\DeclareOption{a3paper}{%
+ \setlength\paperheight {420mm}%
+ \setlength\paperwidth {297mm}}
+\DeclareOption{a4paper}{%
+ \setlength\paperheight {297mm}%
+ \setlength\paperwidth {210mm}}
+\DeclareOption{a5paper}{%
+ \setlength\paperheight {210mm}%
+ \setlength\paperwidth {148mm}}
+\DeclareOption{a6paper}{%
+ \setlength\paperheight {148mm}%
+ \setlength\paperwidth {105mm}}
+\DeclareOption{b4paper}{%
+ \setlength\paperheight {364mm}%
+ \setlength\paperwidth {257mm}}
+\DeclareOption{b5paper}{%
+ \setlength\paperheight {257mm}%
+ \setlength\paperwidth {182mm}}
+\DeclareOption{b6paper}{%
+ \setlength\paperheight {182mm}%
+ \setlength\paperwidth {128mm}}
+\DeclareOption{a4j}{%
+ \setlength\paperheight {297mm}%
+ \setlength\paperwidth {210mm}}
+\DeclareOption{a5j}{%
+ \setlength\paperheight {210mm}%
+ \setlength\paperwidth {148mm}}
+\DeclareOption{b4j}{%
+ \setlength\paperheight {364mm}%
+ \setlength\paperwidth {257mm}}
+\DeclareOption{b5j}{%
+ \setlength\paperheight {257mm}%
+ \setlength\paperwidth {182mm}}
+\DeclareOption{a4var}{%
+ \setlength\paperheight {283mm}%
+ \setlength\paperwidth {210mm}}
+\DeclareOption{b5var}{%
+ \setlength\paperheight {230mm}%
+ \setlength\paperwidth {182mm}}
+\DeclareOption{letterpaper}{%
+ \setlength\paperheight {11in}%
+ \setlength\paperwidth {8.5in}}
+\DeclareOption{legalpaper}{%
+ \setlength\paperheight {14in}%
+ \setlength\paperwidth {8.5in}}
+\DeclareOption{executivepaper}{%
+ \setlength\paperheight {10.5in}%
+ \setlength\paperwidth {7.25in}}
+% \end{macrocode}
+%
+% \paragraph{横置ã}
+%
+% 用紙ã®ç¸¦ã¨æ¨ªã®é•·ã•ã‚’入れæ›ãˆã¾ã™ã€‚
+%
+% \begin{macrocode}
+\newif\if@landscape
+\@landscapefalse
+\DeclareOption{landscape}{\@landscapetrue}
+% \end{macrocode}
+%
+% \paragraph{slide}
+%
+% オプション \texttt{slide} を新設ã—ã¾ã—ãŸã€‚
+%
+% [2016-10-08] \texttt{slide} オプション㯠article 以外ã§ã¯ä½¿ã„物ã«ãªã‚‰ãªã‹ã£ãŸã®ã§ï¼Œ
+% ç°¡å˜ã®ãŸã‚ article ã®ã¿ã§ä½¿ãˆã‚‹ã‚ªãƒ—ションã¨ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\newif\if@slide
+\@slidefalse
+% \end{macrocode}
+%
+% \paragraph{サイズオプション}
+%
+% 10pt,11pt,12pt ã®ã»ã‹ã«ï¼Œ8pt,9pt,14pt,17pt,21pt,25pt,30pt,36pt,43pt を追加ã—ã¾ã—ãŸã€‚
+% ã“ã‚Œã¯ç­‰æ¯”数列ã«ãªã‚‹ã‚ˆã†ã«é¸ã‚“ã ã‚‚ã®ã§ã™ï¼ˆå¾“æ¥ã® 20pt も残ã—ã¾ã—ãŸï¼‰ã€‚
+% |\@ptsize| ã®å®šç¾©ãŒå¤‰ã ã£ãŸã®ã§ã”迷惑をãŠã‹ã‘ã—ã¾ã—ãŸãŒï¼Œ
+% 標準的ãªãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚¯ãƒ©ã‚¹ã¨åŒæ§˜ã«ãƒã‚¤ãƒ³ãƒˆæ•°ã‹ã‚‰10を引ã„ãŸã‚‚ã®ã«ç›´ã—ã¾ã—ãŸã€‚
+%
+% [2003-03-22] 14Qオプションを追加ã—ã¾ã—ãŸã€‚
+%
+% [2003-04-18] 12Qオプションを追加ã—ã¾ã—ãŸã€‚
+%
+% [2016-07-08] |\mag| を使ã‚ãšã«å„種寸法をスケールã•ã›ã‚‹ãŸã‚ã®ã‚ªãƒ—ション \texttt{nomag} を新設ã—ã¾ã—ãŸã€‚
+% \texttt{usemag} オプションã®æŒ‡å®šã§å¾“æ¥é€šã‚Šã®å‹•ä½œã¨ãªã‚Šã¾ã™ã€‚デフォルト㯠\texttt{usemag} ã§ã™ã€‚
+%
+% [2016-07-24] オプティカルサイズを調整ã™ã‚‹ãŸã‚ã«NFSSã¸ãƒ‘ッãƒã‚’当ã¦ã‚‹ã‚ªãƒ—ション \texttt{nomag*} を新設ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\def\jsc@magscale{1}
+%<*article>
+\DeclareOption{slide}{\@slidetrue\def\jsc@magscale{3.583}\@landscapetrue\@titlepagetrue}
+%</article>
+\DeclareOption{8pt} {\def\jsc@magscale{0.833}}% 1.2^(-1)
+\DeclareOption{9pt} {\def\jsc@magscale{0.913}}% 1.2^(-0.5}
+\DeclareOption{10pt}{\def\jsc@magscale{1}}
+\DeclareOption{11pt}{\def\jsc@magscale{1.095}}% 1.2^0.5
+\DeclareOption{12pt}{\def\jsc@magscale{1.200}}
+\DeclareOption{14pt}{\def\jsc@magscale{1.440}}
+\DeclareOption{17pt}{\def\jsc@magscale{1.728}}
+\DeclareOption{20pt}{\def\jsc@magscale{2}}
+\DeclareOption{21pt}{\def\jsc@magscale{2.074}}
+\DeclareOption{25pt}{\def\jsc@magscale{2.488}}
+\DeclareOption{30pt}{\def\jsc@magscale{2.986}}
+\DeclareOption{36pt}{\def\jsc@magscale{3.583}}
+\DeclareOption{43pt}{\def\jsc@magscale{4.300}}
+\DeclareOption{12Q} {\def\jsc@magscale{0.923}}% 1pt*12Q/13Q
+\DeclareOption{14Q} {\def\jsc@magscale{1.077}}% 1pt*14Q/13Q
+\DeclareOption{10ptj}{\def\jsc@magscale{1.085}}% 1pt*10bp/13Q
+\DeclareOption{10.5ptj}{\def\jsc@magscale{1.139}}
+\DeclareOption{11ptj}{\def\jsc@magscale{1.194}}
+\DeclareOption{12ptj}{\def\jsc@magscale{1.302}}
+% \end{macrocode}
+%
+% \paragraph{オプティカルサイズã®è£œæ­£}
+% \texttt{nomag*}オプション指定時ã«ã¯ï¼Œæœ¬æ–‡ã®ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºãŒ10pt以外ã®å ´åˆã«
+% オプティカルサイズã®è£œæ­£ã‚’è¡Œã†ãŸã‚ã«NFSSã«ãƒ‘ッãƒã‚’当ã¦ã¾ã™ã€‚
+% ç¾åœ¨ã®\texttt{ltjsclasses}ã§ã¯ã“ã®ãƒ‘ッãƒå½“ã¦ã¯æ¨™æº–ã§ã¯è¡Œã„ã¾ã™ãŒï¼Œ
+% å°†æ¥ã©ã†ãªã‚‹ã‹ã‚ã‹ã‚‰ãªã„ã®ã§\texttt{nomag}ã§ç„¡åŠ¹åŒ–ã™ã‚‹ã“ã¨ãŒã§ãるよã†ã«ã—ã¾ã—ãŸã€‚
+%
+% \texttt{noxreal},~\texttt{real}ã¯æ—§æ¥ã®äº’æ›æ€§ã¨ã—ã¦ä»Šã¯æ®‹ã—ã¦ã‚ã‚Šã¾ã™ãŒï¼Œ2017å¹´7月ã«å‰Šé™¤ã™ã‚‹äºˆå®šã§ã™ã€‚
+%
+% [2018-01-14] \texttt{noxreal},~\texttt{real} を削除ã—ã¾ã—ãŸï¼Žã¾ãŸï¼Œå†…部命令ã®å称を
+% \texttt{jsclasses}ã«åˆã‚ã›ã¾ã—ãŸï¼Ž
+%
+% \begin{macrocode}
+\newif\ifjsc@mag@xreal
+\jsc@mag@xrealtrue
+\DeclareOption{nomag*}{\jsc@mag@xrealtrue}
+\DeclareOption{nomag}{\jsc@mag@xrealfalse}
+\DeclareOption{usemag}{%
+ \ClassWarningNoLine{\jsc@clsname}{%
+ This \jsc@clsname\space cls does not support `usemag'\MessageBreak
+ option, since LuaTeX does not support \string\mag\MessageBreak in pdf output}%
+ \jsc@mag@xrealtrue}
+% \end{macrocode}
+%
+%
+% \paragraph{トンボオプション}
+%
+% トンボ(crop marks)を出力ã—ã¾ã™ã€‚
+% 実際ã®å‡¦ç†ã¯\texttt{lltjcore.sty}ã§è¡Œã„ã¾ã™ã€‚
+% オプション \texttt{tombow} ã§æ—¥ä»˜ä»˜ãã®ãƒˆãƒ³ãƒœï¼Œ
+% オプション \texttt{tombo} ã§æ—¥ä»˜ãªã—ã®ãƒˆãƒ³ãƒœã‚’出力ã—ã¾ã™ã€‚
+% ã“れらã¯ã‚¢ã‚¹ã‚­ãƒ¼ç‰ˆã®ã¾ã¾ã§ã™ã€‚
+% カウンタ |\hour|,|\minute| ã¯\texttt{luatexja-compat.sty}ã§å®£è¨€ã•ã‚Œã¦ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\hour\time \divide\hour by 60\relax
+\@tempcnta\hour \multiply\@tempcnta 60\relax
+\minute\time \advance\minute-\@tempcnta
+\DeclareOption{tombow}{%
+ \tombowtrue \tombowdatetrue
+ \setlength{\@tombowwidth}{.1\p@}%
+ \@bannertoken{%
+ \jobname\space(\number\year-\two@digits\month-\two@digits\day
+ \space\two@digits\hour:\two@digits\minute)}%
+ \maketombowbox}
+\DeclareOption{tombo}{%
+ \tombowtrue \tombowdatefalse
+ \setlength{\@tombowwidth}{.1\p@}%
+ \maketombowbox}
+% \end{macrocode}
+%
+% \paragraph{é¢ä»˜ã‘}
+%
+% オプション \texttt{mentuke} ã§å¹…ゼロã®ãƒˆãƒ³ãƒœã‚’出力ã—ã¾ã™ã€‚
+% é¢ä»˜ã‘ã«ä¾¿åˆ©ã§ã™ã€‚ã“れもアスキー版ã®ã¾ã¾ã§ã™ã€‚
+%
+% \begin{macrocode}
+\DeclareOption{mentuke}{%
+ \tombowtrue \tombowdatefalse
+ \setlength{\@tombowwidth}{\z@}%
+ \maketombowbox}
+% \end{macrocode}
+%
+% \paragraph{両é¢ï¼Œç‰‡é¢ã‚ªãƒ—ション}
+%
+% \texttt{twoside} ã§å¥‡æ•°ãƒšãƒ¼ã‚¸ãƒ»å¶æ•°ãƒšãƒ¼ã‚¸ã®ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆãŒå¤‰ã‚ã‚Šã¾ã™ã€‚
+%
+% [2003-04-29] \texttt{vartwoside} ã§ã©ã¡ã‚‰ã®ãƒšãƒ¼ã‚¸ã‚‚å‚注ãŒå³å´ã«ãªã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+\DeclareOption{oneside}{\@twosidefalse \@mparswitchfalse}
+\DeclareOption{twoside}{\@twosidetrue \@mparswitchtrue}
+\DeclareOption{vartwoside}{\@twosidetrue \@mparswitchfalse}
+% \end{macrocode}
+%
+% \paragraph{二段組}
+%
+% \texttt{twocolumn} ã§äºŒæ®µçµ„ã«ãªã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+\DeclareOption{onecolumn}{\@twocolumnfalse}
+\DeclareOption{twocolumn}{\@twocolumntrue}
+% \end{macrocode}
+%
+% \paragraph{表題ページ}
+%
+% \texttt{titlepage} ã§è¡¨é¡Œãƒ»æ¦‚è¦ã‚’独立ã—ãŸãƒšãƒ¼ã‚¸ã«å‡ºåŠ›ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\DeclareOption{titlepage}{\@titlepagetrue}
+\DeclareOption{notitlepage}{\@titlepagefalse}
+% \end{macrocode}
+%
+% \paragraph{å³å·¦èµ·ã“ã—}
+%
+% 書ç±ã§ã¯ç« ã¯é€šå¸¸ã¯å¥‡æ•°ãƒšãƒ¼ã‚¸èµ·ã“ã—ã«ãªã‚Šã¾ã™ãŒï¼Œæ¨ªçµ„ã§ã¯ã“れを
+% \texttt{openright} ã¨è¡¨ã™ã“ã¨ã«ã—ã¦ã‚ã‚Šã¾ã™ã€‚
+% \texttt{openany} ã§å¶æ•°ãƒšãƒ¼ã‚¸ã‹ã‚‰ã§ã‚‚始ã¾ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚
+%
+% [2017-02-24] \texttt{openright} ã¯æ¨ªçµ„ã§ã¯å¥‡æ•°ãƒšãƒ¼ã‚¸èµ·ã“ã—,縦組ã§ã¯
+% å¶æ•°ãƒšãƒ¼ã‚¸èµ·ã“ã—を表ã—ã¾ã™ã€‚ã‚„ã‚„ã“ã—ã„ã§ã™ãŒï¼Œã“ã‚Œã¯\LaTeX ã®æ¨™æº–クラスãŒ
+% 西欧ã®æ¨ªçµ„事情ã—ã‹è€ƒæ…®ã›ãšã«ï¼Œå¥‡æ•°ãƒšãƒ¼ã‚¸èµ·ã“ã—ã¨å³èµ·ã“ã—を一緒ã«ã—ã¦ã—ã¾ã£
+% ãŸã›ã„ã§ã™ã€‚縦組ã§ã®å¥‡æ•°ãƒšãƒ¼ã‚¸èµ·ã“ã—ã¨æ¨ªçµ„ã§ã®å¶æ•°ãƒšãƒ¼ã‚¸èµ·ã“ã—も表ç¾ã—ãŸã„
+% ã®ã§ï¼Œltjsclassesã§ã¯æ–°ãŸã« \texttt{openleft} も追加ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+%<book|report>\DeclareOption{openright}{\@openrighttrue\@openleftfalse}
+%<book|report>\DeclareOption{openleft}{\@openlefttrue\@openrightfalse}
+%<book|report>\DeclareOption{openany}{\@openrightfalse\@openleftfalse}
+% \end{macrocode}
+%
+% \paragraph{eqnarray環境ã¨æ•°å¼ã®ä½ç½®}
+%
+% 森本ã•ã‚“ã®ã”教示ã«ã—ãŸãŒã£ã¦å‰ã«ç§»å‹•ã—ã¾ã—ãŸã€‚
+%
+% \begin{environment}{eqnarray}
+%
+% \LaTeX ã® |eqnarray| 環境ã§ã¯ |&| ã§ã§ãるアキãŒå¤§ãã™ãŽã‚‹
+% よã†ã§ã™ã®ã§ï¼Œå°‘ã—å°ã•ãã—ã¾ã™ã€‚
+% ã¾ãŸï¼Œä¸­å¤®ã®è¦ç´ ã‚‚ |\displaystyle| ã«ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\def\eqnarray{%
+ \stepcounter{equation}%
+ \def\@currentlabel{\p@equation\theequation}%
+ \global\@eqnswtrue
+ \m@th
+ \global\@eqcnt\z@
+ \tabskip\@centering
+ \let\\\@eqncr
+ $$\everycr{}\halign to\displaywidth\bgroup
+ \hskip\@centering$\displaystyle\tabskip\z@skip{##}$\@eqnsel
+ &\global\@eqcnt\@ne \hfil$\displaystyle{{}##{}}$\hfil
+ &\global\@eqcnt\tw@ $\displaystyle{##}$\hfil\tabskip\@centering
+ &\global\@eqcnt\thr@@ \hb@xt@\z@\bgroup\hss##\egroup
+ \tabskip\z@skip
+ \cr}
+% \end{macrocode}
+% \end{environment}
+%
+% \texttt{leqno} ã§æ•°å¼ç•ªå·ãŒå·¦å´ã«ãªã‚Šã¾ã™ã€‚
+% \texttt{fleqn} ã§æ•°å¼ãŒæœ¬æ–‡å·¦ç«¯ã‹ã‚‰ä¸€å®šè·é›¢ã®ã¨ã“ã‚ã«å‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+% 森本ã•ã‚“ã«ã—ãŸãŒã£ã¦è¨‚æ­£ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\DeclareOption{leqno}{\input{leqno.clo}}
+\DeclareOption{fleqn}{\input{fleqn.clo}%
+% fleqn用ã®eqnarray環境ã®å†å®šç¾©
+ \def\eqnarray{%
+ \stepcounter{equation}%
+ \def\@currentlabel{\p@equation\theequation}%
+ \global\@eqnswtrue\m@th
+ \global\@eqcnt\z@
+ \tabskip\mathindent
+ \let\\=\@eqncr
+ \setlength\abovedisplayskip{\topsep}%
+ \ifvmode
+ \addtolength\abovedisplayskip{\partopsep}%
+ \fi
+ \addtolength\abovedisplayskip{\parskip}%
+ \setlength\belowdisplayskip{\abovedisplayskip}%
+ \setlength\belowdisplayshortskip{\abovedisplayskip}%
+ \setlength\abovedisplayshortskip{\abovedisplayskip}%
+ $$\everycr{}\halign to\linewidth% $$
+ \bgroup
+ \hskip\@centering$\displaystyle\tabskip\z@skip{##}$\@eqnsel
+ &\global\@eqcnt\@ne \hfil$\displaystyle{{}##{}}$\hfil
+ &\global\@eqcnt\tw@
+ $\displaystyle{##}$\hfil \tabskip\@centering
+ &\global\@eqcnt\thr@@ \hb@xt@\z@\bgroup\hss##\egroup
+ \tabskip\z@skip\cr
+ }}
+% \end{macrocode}
+%
+% \paragraph{文献リスト}
+%
+% 文献リストをopenå½¢å¼ï¼ˆè‘—者åや書åã®å¾Œã«æ”¹è¡ŒãŒå…¥ã‚‹ï¼‰ã§å‡ºåŠ›ã—ã¾ã™ã€‚
+% ã“ã‚Œã¯ä½¿ã‚れるã“ã¨ã¯ãªã„ã®ã§ã‚³ãƒ¡ãƒ³ãƒˆã‚¢ã‚¦ãƒˆã—ã¦ã‚ã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+% \DeclareOption{openbib}{%
+% \AtEndOfPackage{%
+% \renewcommand\@openbib@code{%
+% \advance\leftmargin\bibindent
+% \itemindent -\bibindent
+% \listparindent \itemindent
+% \parsep \z@}%
+% \renewcommand\newblock{\par}}}
+% \end{macrocode}
+%
+% \paragraph{æ•°å¼ãƒ•ã‚©ãƒ³ãƒˆã¨ã—ã¦å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚’登録ã—ãªã„オプション}
+%
+% \pTeX ã§ã¯æ•°å¼ä¸­ã§ã¯16通りã®ãƒ•ã‚©ãƒ³ãƒˆã—ã‹ä½¿ãˆã¾ã›ã‚“ã§ã—ãŸãŒï¼ŒLua\TeX ã§ã¯
+% Omegaæ‹¡å¼µãŒå–ã‚Šè¾¼ã¾ã‚Œã¦ã„ã¦256通りã®ãƒ•ã‚©ãƒ³ãƒˆãŒä½¿ãˆã¾ã™ã€‚
+% ãŸã ã—,\LaTeXe カーãƒãƒ«ã§ã¯æœªã ã«æ•°å¼ãƒ•ã‚¡ãƒŸãƒªã®æ•°ã¯16個ã«åˆ¶é™ã•ã‚Œã¦ã„ã‚‹ã®ã§ï¼Œ
+% 実際ã«ä½¿ç”¨å¯èƒ½ãªæ•°å¼ãƒ•ã‚¡ãƒŸãƒªã®æ•°ã‚’増やã™ãŸã‚ã«ã¯\texttt{lualatex-math}パッケージを
+% 読ã¿è¾¼ã‚€å¿…è¦ãŒã‚ã‚‹ã“ã¨ã«æ³¨æ„ãŒå¿…è¦ã§ã™ã€‚
+%
+% [2018-10-08 LTJ] Lua\TeX-ja本体ãŒ\texttt{disablejfam}オプションをサãƒãƒ¼ãƒˆã—ãŸã®ã§ï¼Œ
+% クラスファイルã‹ã‚‰ã¯å‰Šé™¤ã—ã¾ã™ï¼Ž
+%
+% [2019-08-12 LTJ] ……ã¨æ€ã„ã¾ã—ãŸãŒï¼Œ``Unused global option(s): [disablejfam]''警告ãŒ
+% 出ã¦ã—ã¾ã„ã¾ã™ã®ã§ï¼Œã€Œä½•ã‚‚ã—ãªã„ã€ã‚¯ãƒ©ã‚¹ã‚ªãƒ—ションã¨ã—ã¦å½¢ã ã‘定義ã—ã¾ã™ï¼Ž
+% \begin{macrocode}
+%<*article|report|book>
+\DeclareOption{disablejfam}{}
+%</article|report|book>
+% \end{macrocode}
+%
+% \paragraph{ドラフト}
+%
+% \texttt{draft} ã§overfull boxã®èµ·ããŸè¡Œæœ«ã«5ptã®ç½«ç·šã‚’引ãã¾ã™ã€‚
+%
+% [2016-07-13] |\ifdraft| を定義ã™ã‚‹ã®ã‚’ã‚„ã‚ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\DeclareOption{draft}{\setlength\overfullrule{5pt}}
+\DeclareOption{final}{\setlength\overfullrule{0pt}}
+% \end{macrocode}
+%
+% \paragraph{和文フォントメトリックã®é¸æŠž}
+%
+% ã“ã“ã§ã¯OTFパッケージã®ãƒ¡ãƒˆãƒªãƒƒã‚¯ã‚’å…ƒã¨ã—ãŸï¼Œ\texttt{jfm-ujis.lua}メトリックを標準ã§ä½¿ã„ã¾ã™ã€‚
+% å¤ã„\texttt{min10},\texttt{goth10}互æ›ã®ãƒ¡ãƒˆãƒªãƒƒã‚¯ã‚’使ã„ãŸã„ã¨ãã¯\texttt{mingoth}
+% ã¨ã„ã†ã‚ªãƒ—ションを指定ã—ã¾ã™ã€‚
+% \pTeX ã§ã‚ˆã利用ã•ã‚Œã‚‹\texttt{jis}フォントメトリックã¨äº’æ›ã®ãƒ¡ãƒˆãƒªãƒƒã‚¯ã‚’使ã„ãŸã„å ´åˆã¯ï¼Œ
+% \texttt{ptexjis}ã¨ã„ã†ã‚ªãƒ—ションを指定ã—ã¾ã™ã€‚
+% \texttt{winjis}メトリックã¯ç”¨æ¸ˆã¿ã®ãŸã‚,\texttt{winjis}オプションã¯ç„¡è¦–ã•ã‚Œã¾ã™ã€‚
+%
+% [2016-11-09] pLaTeX / upLaTeX を自動判別ã™ã‚‹ã‚ªãƒ—ション \texttt{autodetect-engine} を新設ã—ã¾ã—ãŸã€‚
+%
+% [2016-11-24 LTJ] \texttt{autodetect-engine} ã¯Lua\TeX-jaã§ã¯æ„味ãŒãªã„ã®ã§è­¦å‘Šã‚’表示ã•ã›ã¾ã™ï¼Ž
+%
+% [2018-07-30 LTJ] \texttt{uplatex} 指定時ã®ã‚¨ãƒ©ãƒ¼ãŒæ­£ã—ã表示ã•ã‚Œãªã‹ã£ãŸã®ã§ä¿®æ­£ã—ã¾ã—ãŸï¼Ž
+%
+% \begin{macrocode}
+\newif\ifmingoth
+\mingothfalse
+\newif\ifjisfont
+\jisfontfalse
+\newif\ifptexjis
+\ptexjisfalse
+\DeclareOption{winjis}{%
+ \ClassWarningNoLine{\jsc@clsname}{this class does not support `winjis' option}}
+\DeclareOption{uplatex}{%
+ \ClassError{\jsc@clsname}{this class does not support `uplatex' option}}
+\DeclareOption{autodetect-engine}{%
+ \ClassWarningNoLine{\jsc@clsname}{this class does not support `autodetect-engine' option}}
+\DeclareOption{mingoth}{\mingothtrue}
+\DeclareOption{ptexjis}{\ptexjistrue}
+\DeclareOption{jis}{\jisfonttrue}
+% \end{macrocode}
+%
+% \paragraph{papersizeスペシャルã®åˆ©ç”¨}
+%
+% \texttt{ltjsclasses}ã§ã¯\texttt{papersize}オプションã®æœ‰ç„¡ã«é–¢ã‚らãšï¼Œ
+% PDFã®ãƒšãƒ¼ã‚¸ã‚µã‚¤ã‚ºã¯é©åˆ‡ã«è¨­å®šã•ã‚Œã‚‹ã®ã§ï¼Œå‰Šé™¤ã—ã¾ã—ãŸã€‚
+%
+% \paragraph{英語化}
+%
+% オプション \texttt{english} を新設ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\newif\if@english
+\@englishfalse
+\DeclareOption{english}{\@englishtrue}
+% \end{macrocode}
+%
+% \paragraph{ltjsbookã‚’ltjsreportã‚‚ã©ãã«}
+%
+% オプション \texttt{report} を新設ã—ã¾ã—ãŸã€‚
+%
+% [2017-02-13] 従æ¥ã¯ã€Œltjsreport相当ã€ã‚’ltjsbookã® \texttt{report} オプションã§æä¾›ã—ã¦
+% ã„ã¾ã—ãŸãŒï¼Œæ–°ã—ãltjsreportクラスも作りã¾ã—ãŸã€‚ã©ã¡ã‚‰ã§ã‚‚ãŠå¥½ããªæ–¹ã‚’使ã£ã¦ãã ã•ã„。
+%
+% \begin{macrocode}
+%<*book>
+\newif\if@report
+\@reportfalse
+\DeclareOption{report}{\@reporttrue\@openrightfalse\@twosidefalse\@mparswitchfalse}
+%</book>
+% \end{macrocode}
+%
+% \paragraph{\texttt{jslogo}パッケージã®èª­ã¿è¾¼ã¿}
+%
+% \LaTeX 関連ã®ãƒ­ã‚´ã‚’å†å®šç¾©ã™ã‚‹\texttt{jslogo}パッケージを
+% 読ã¿è¾¼ã¾ãªã„オプション\texttt{nojslogo}を新設ã—ã¾ã—ãŸã€‚
+% \texttt{jslogo}オプションã®æŒ‡å®šã§å¾“æ¥ã©ãŠã‚Šã®å‹•ä½œã¨ãªã‚Šã¾ã™ã€‚
+% デフォルトã¯\texttt{jslogo}ã§ï¼Œã™ãªã‚ã¡ãƒ‘ッケージを読ã¿è¾¼ã¿ã¾ã™ã€‚
+% \begin{macrocode}
+\newif\if@jslogo \@jslogotrue
+\DeclareOption{jslogo}{\@jslogotrue}
+\DeclareOption{nojslogo}{\@jslogofalse}
+% \end{macrocode}
+%
+% \paragraph{オプションã®å®Ÿè¡Œ}
+%
+% デフォルトã®ã‚ªãƒ—ションを実行ã—ã¾ã™ã€‚
+% |multicols| ã‚„ |url| ã‚’ |\RequirePackage| ã™ã‚‹ã®ã¯ã‚„ã‚ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+%<article>\ExecuteOptions{a4paper,oneside,onecolumn,notitlepage,final}
+%<book>\ExecuteOptions{a4paper,twoside,onecolumn,titlepage,openright,final}
+%<report>\ExecuteOptions{a4paper,oneside,onecolumn,titlepage,openany,final}
+%<jspf>\ExecuteOptions{a4paper,twoside,twocolumn,notitlepage,fleqn,final}
+%<kiyou>\ExecuteOptions{a4paper,twoside,twocolumn,notitlepage,final}
+\ProcessOptions
+% \end{macrocode}
+%
+% 後処ç†
+%
+% \begin{macrocode}
+\if@slide
+ \def\maybeblue{\@ifundefined{ver@color.sty}{}{\color{blue}}}
+\fi
+\if@landscape
+ \setlength\@tempdima {\paperheight}
+ \setlength\paperheight{\paperwidth}
+ \setlength\paperwidth {\@tempdima}
+\fi
+% \end{macrocode}
+%
+% \paragraph{基準ã¨ãªã‚‹è¡Œé€ã‚Š}
+%
+% \begin{macro}{\n@baseline}
+%
+% 基準ã¨ãªã‚‹è¡Œé€ã‚Šã‚’ãƒã‚¤ãƒ³ãƒˆå˜ä½ã§è¡¨ã—ãŸã‚‚ã®ã§ã™ã€‚
+%
+% \begin{macrocode}
+%<article|book|report>\if@slide\def\n@baseline{13}\else\def\n@baseline{16}\fi
+%<jspf>\def\n@baseline{14.554375}
+%<kiyou>\def\n@baseline{14.897}
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{拡大率ã®è¨­å®š}
+%
+% サイズã®å¤‰æ›´ã¯\TeX ã®ãƒ—リミティブ |\mag| を使ã£ã¦è¡Œã„ã¾ã™ã€‚
+% 9ãƒã‚¤ãƒ³ãƒˆã«ã¤ã„ã¦ã¯è¡Œé€ã‚Šã‚‚若干縮ã‚ã¾ã—ãŸã€‚
+% サイズã«ã¤ã„ã¦ã¯å…¨é¢çš„ã«è¦‹ç›´ã—ã¾ã—ãŸã€‚
+%
+% [2008-12-26] 1000 / |\mag| ã«ç›¸å½“ã™ã‚‹ |\inv@mag| を定義ã—ã¾ã—ãŸã€‚
+% |truein| を使ã£ã¦ã„ãŸã¨ã“ã‚ã‚’ |\inv@mag in| ã«ç›´ã—ã¾ã—ãŸã®ã§ï¼Œ
+% |geometry| パッケージã¨å…±å­˜ã§ãã‚‹ã¨æ€ã„ã¾ã™ã€‚
+% ãªãŠï¼Œæ–°ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚¯ãƒ©ã‚¹å´ã§ |10pt| 以外ã«ã™ã‚‹å ´åˆã®æ³¨æ„:
+% \begin{itemize}
+% \item |geometry| å´ã§ã‚ªãƒ—ション |truedimen| を指定ã—ã¦ãã ã•ã„。
+% \item |geometry| å´ã§ã‚ªãƒ—ション |mag| ã¯ä½¿ãˆã¾ã›ã‚“。
+% \end{itemize}
+%
+% [2016-03-21 LTJ] |\mag| を使ã‚ãªã„よã†ã«å…¨é¢çš„ã«æ›¸ãæ›ãˆã¾ã—ãŸã€‚
+% |\ltjs@mpt| ã«ã€Œæ‹¡å¤§çŽ‡ã ã‘大ããã—ãŸptã€ã®å€¤ãŒæ ¼ç´ã•ã‚Œã¾ã™ã€‚
+% \texttt{bxjscls}ã¨åŒæ§˜ã«ï¼Œ|\@ptsize| 㯠|10pt|,~|11pt|,~|12pt| オプションãŒæŒ‡å®šã•ã‚ŒãŸæ™‚ã ã‘
+% 従æ¥é€šã‚Š0,~1,~2ã¨è¨­å®šã—,ãれ以外ã®å ´åˆã¯$-20$ã¨ã™ã‚‹ã“ã¨ã«ã—ã¾ã—ãŸã€‚
+% |\inv@mag| ã¯ã‚‚ã¯ã‚„定義ã—ã¦ã„ã¾ã›ã‚“。
+%
+% [2016-03-26 LTJ] |\ltjs@magscale| ã«æ‹¡å¤§çŽ‡ã‚’æ ¼ç´ã—ãŸå¾Œï¼Œãれを用ã„㦠|\ltjs@mpt| ã‚’
+% 設定ã™ã‚‹ã‚ˆã†ã«ã—ã¾ã—ãŸã€‚
+%
+% [2016-07-08] |\jsc@mpt| ãŠã‚ˆã³ |\jsc@mmm| ã«ï¼Œãã‚Œãžã‚Œ1ptãŠã‚ˆã³1mmを拡大ã•ã›ãŸå€¤ã‚’æ ¼ç´ã—ã¾ã™ã€‚
+% 以é™ã®ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆæŒ‡å®šã§ã¯ã“ã¡ã‚‰ã‚’使ã„ã¾ã™ã€‚
+%
+% [2016-07-12 LTJ] |\ltjs@...| を本家ã«åˆã‚ã›ã¦ |\jsc@...| ã«å称変更ã—ã¾ã—ãŸã€‚
+% \begin{macrocode}
+%<*kiyou>
+\def\jsc@magscale{0.9769230}
+%</kiyou>
+\newdimen\jsc@mpt
+\newdimen\jsc@mmm
+\jsc@mpt=\jsc@magscale\p@
+\jsc@mmm=\jsc@magscale mm
+\ifdim\jsc@mpt<.92\p@ % 8pt, 9pt 指定時
+ \def\n@baseline{15}%
+\fi
+\newcommand{\@ptsize}{0}
+\ifdim\jsc@mpt=1.0954\p@ \renewcommand{\@ptsize}{1}\else
+\ifdim\jsc@mpt=1.2\p@ \renewcommand{\@ptsize}{2}\else
+\renewcommand{\@ptsize}{-20}\fi\fi
+% \end{macrocode}
+%
+% \paragraph{オプティカルサイズã®è£œæ­£}
+% \leavevmode\par
+% [2016-03-26 LTJ] |xreal|オプションã®æŒ‡å®šæ™‚ã«ã¯ï¼Œ\texttt{bxjscls}ã®|magstyle=xreal|
+% オプションã®ã‚ˆã†ã«ï¼Œã‚ªãƒ—ティカルã®è£œæ­£ã‚’è¡Œã†ãŸã‚ã«NFSSã«ãƒ‘ッãƒã‚’当ã¦ã¾ã™ã€‚
+% パッãƒã¯ï¼Œæ¦‚ã­miscã•ã‚“ã«ã‚ˆã‚‹ã€Œjs*.cls åŒæ§˜ã®æ–‡å­—サイズ設定を
+% |\mag|ã«ã‚ˆã‚‰ãšã«è¡Œã†æ–¹æ³•ï¼šè©¦æ¡ˆã€
+% (\texttt{http://oku.edu.mie-u.ac.jp/\textasciitilde okumura/texfaq/qa/28416.html})ã®
+% 方法ã«æ²¿ã£ã¦ã„ã¾ã™ãŒï¼Œæ‹¡å¤§/縮å°ã™ã‚‹ã¨ã“ã‚ã®è¨ˆç®—ã«ã¯Luaを用ã„ã¦ã„ã¾ã™ã€‚
+%
+% ãªãŠï¼Œ\TeX 内部ã§é•·ã•ã¯spå˜ä½ã®æ•´æ•°å€ã§è¡¨ç¾ã•ã‚Œã¦ã„ã‚‹ã®ã§ï¼Œæ•°spã®èª¤å·®ã¯ä»•æ–¹ãŒãªã„ã§ã™ã€‚
+% ãã®ãŸã‚,事å‰ã«\texttt{type1cm}パッケージを読ã¿ã“ã‚“ã§ãŠãã¾ã™ã€‚
+%
+% [2016-03-28 LTJ] |\luafunction|を使ã†ã‚ˆã†ã«ã—,ã¾ãŸæœ¬æ–‡ã®ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºãŒ10\,ptã®ã¨ãã«ã¯
+% (ä¸è¦ãªã®ã§ï¼‰ãƒ‘ッãƒã‚’当ã¦ãªã„ã“ã¨ã«ã—ã¾ã—ãŸã€‚
+%
+% [2016-04-04 LTJ] NFSSã¸ã®ãƒ‘ッãƒã‚’修正。
+%
+% [2017-01-23 LTJ] \LaTeXe\ 2017-01-01以é™ã§ã¯TUエンコーディングãŒæ¨™æº–ãªã®ã§ï¼Œ
+% \texttt{type1cm}パッケージã¯èª­ã¿è¾¼ã¾ãªã„よã†ã«ã—ã¾ã—ãŸï¼Ž
+%
+% [2017-02-17 LTJ] |\directlua|中ã§å‡ºåŠ›ã•ã‚Œã‚‹æ•°å­—ã®ã‚«ãƒ†ã‚´ãƒªãƒ¼ã‚³ãƒ¼ãƒ‰ãŒ12ã«ãªã‚‹ã‚ˆã†ã«ã—ã¾ã—ãŸï¼Ž
+% ã“ã®ä¿è¨¼ã‚’ã—ãªã„ã¨ä¾‹ãˆã°\texttt{listings}パッケージã§ç„¡é™ãƒ«ãƒ¼ãƒ—ã«ãªã‚Šã¾ã™ï¼Ž
+%
+% [2018-07-02 LTJ] 10ptオプションãŒæŒ‡å®šã•ã‚Œã¦ãŠã‚Šï¼Œ
+% 実際ã«ã¯ã‚ªãƒ—ティカルサイズã®è£œæ­£ãŒä¸è¦ãªã¨ãã¯ã€Œ|xreal|オプションã¯æŒ‡å®šã•ã‚Œãªã‹ã£ãŸã€ã¨ã„ã†
+% 扱ã„ã«ã—ã¦ãŠãã¾ã™ï¼Ž
+% \begin{macrocode}
+\ifjsc@mag@xreal
+\ifdim\jsc@mpt=\p@\jsc@mag@xrealfalse\else
+ \expandafter\let\csname OT1/cmr/m/n/10\endcsname\relax
+ \expandafter\let\csname TU/lmr/m/n/10\endcsname\relax
+ \expandafter\let\csname OMX/cmex/m/n/10\endcsname\relax
+ \newluafunction\ltjs@@magnify@font@calc
+ \begingroup\catcode`\%=12\relax
+ \directlua{
+ local getdimen, mpt=tex.getdimen, tex.getdimen('jsc@mpt')/65536
+ local t = lua.get_functions_table()
+ t[\the\ltjs@@magnify@font@calc] = function()
+ tex.sprint(-2,math.floor(0.5+mpt*getdimen('dimen@')))
+ end
+ function luatexja.ltjs_unmagnify_fsize(a)
+ local s = luatexja.print_scaled(math.floor(0.5+a/mpt*65536))
+ tex.sprint(-2, (s:match('%.0$')) and s:sub(1,-3) or s )
+ end
+ }
+ \endgroup
+ \def\ltjs@magnify@external@font#1 at#2 at#3\@nil{%
+ \def\@tempa{#1}\def\@tempb{#2}%
+ \ifx\@tempb\@empty
+ \edef\@tempb{ scaled\directlua{%
+ tex.sprint(-2,math.floor(0.5+\jsc@magscale*1000))
+ }}%
+ \else
+ \dimen@\@tempb\relax
+ \edef\@tempb{ at\luafunction\ltjs@@magnify@font@calc sp}%
+ \fi
+ \edef\@tempa{\def\noexpand\external@font{\@tempa\@tempb}}%
+ }
+ \let\ltjs@orig@get@external@font=\get@external@font
+ \def\get@external@font{%
+ \edef\f@size{\directlua{luatexja.ltjs_unmagnify_fsize(\f@size)}}%
+ \ltjs@orig@get@external@font
+ \begingroup
+ \edef\@tempa{\external@font\space at\space at}%
+ \expandafter\ltjs@magnify@external@font\@tempa\@nil
+ \expandafter\endgroup\@tempa
+ }
+\fi\fi
+% \end{macrocode}
+%
+% [2016-11-16] latex.ltx (ltspace.dtx)ã§å®šç¾©ã•ã‚Œã¦ã„ã‚‹ |\smallskip| ã®ï¼Œ
+% å˜ä½ |pt| ã‚’ |\jsc@mpt| ã«ç½®ãæ›ãˆãŸ |\jsc@smallskip| を定義ã—ã¾ã™ã€‚
+% ã“れ㯠|\maketitle| ã§ç”¨ã„られã¾ã™ã€‚
+% |\jsc@medskip| 㨠|\jsc@bigskip| ã¯å¿…è¦ãªã„ã®ã§ã‚³ãƒ¡ãƒ³ãƒˆã‚¢ã‚¦ãƒˆã—ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macro}{\jsc@smallskip}
+% \begin{macro}{\jsc@medskip}
+% \begin{macro}{\jsc@bigskip}
+% \begin{macrocode}
+\def\jsc@smallskip{\vspace\jsc@smallskipamount}
+%\def\jsc@medskip{\vspace\jsc@medskipamount}
+%\def\jsc@bigskip{\vspace\jsc@bigskipamount}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\jsc@smallskipamount}
+% \begin{macro}{\jsc@medskipamount}
+% \begin{macro}{\jsc@bigskipamount}
+% \begin{macrocode}
+\newskip\jsc@smallskipamount
+\jsc@smallskipamount=3\jsc@mpt plus 1\jsc@mpt minus 1\jsc@mpt
+%\newskip\jsc@medskipamount
+%\jsc@medskipamount =6\jsc@mpt plus 2\jsc@mpt minus 2\jsc@mpt
+%\newskip\jsc@bigskipamount
+%\jsc@bigskipamoun =12\jsc@mpt plus 4\jsc@mpt minus 4\jsc@mpt
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \paragraph{PDFã®ç”¨ç´™ã‚µã‚¤ã‚ºã®è¨­å®š}
+%
+% \begin{macro}{\pagewidth}
+% \begin{macro}{\pageheight}
+% \begin{macro}{\stockwidth}
+% \begin{macro}{\stockheight}
+% 出力ã®PDFã®ç”¨ç´™ã‚µã‚¤ã‚ºã‚’ã“ã“ã§è¨­å®šã—ã¦ãŠãã¾ã™ã€‚
+% |tombow| ãŒçœŸã®ã¨ãã¯2インãƒè¶³ã—ã¦ãŠãã¾ã™ã€‚
+%
+% [2015-10-18 LTJ] Lua\TeX\ 0.81.0ã§ã¯ãƒ—リミティブã®å称変更ãŒã•ã‚ŒãŸã®ã§ï¼Œ
+% ãã‚Œã«åˆã‚ã›ã¦ãŠãã¾ã™ã€‚
+%
+% [2016-07-12 LTJ] luatex.defãŒæ–°ã—ããªã£ãŸã“ã¨ã«å¯¾å¿œã™ã‚‹aminophenã•ã‚“ã®ãƒ‘ッãƒã‚’å–ã‚Šè¾¼ã¿ã¾ã—ãŸã€‚
+%
+% [2017-01-11] トンボオプションãŒæŒ‡å®šã•ã‚Œã¦ã„ã‚‹ã¨ã「ã ã‘ã€|\stockwidth|,
+% |\stockheight|を定義ã™ã‚‹ã‚ˆã†ã«ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\iftombow
+ \newlength{\stockwidth}
+ \newlength{\stockheight}
+ \setlength{\stockwidth}{\paperwidth}
+ \setlength{\stockheight}{\paperheight}
+ \advance \stockwidth 2in
+ \advance \stockheight 2in
+ \ifdefined\pdfpagewidth
+ \setlength{\pdfpagewidth}{\stockwidth}
+ \setlength{\pdfpageheight}{\stockheight}
+ \else
+ \setlength{\pagewidth}{\stockwidth}
+ \setlength{\pageheight}{\stockheight}
+ \fi
+\else
+ \ifdefined\pdfpagewidth
+ \setlength{\pdfpagewidth}{\paperwidth}
+ \setlength{\pdfpageheight}{\paperheight}
+ \else
+ \setlength{\pagewidth}{\paperwidth}
+ \setlength{\pageheight}{\paperheight}
+ \fi
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \section{和文フォントã®å¤‰æ›´}
+%
+% JISã®1ãƒã‚¤ãƒ³ãƒˆã¯0.3514mm(約1/72.28インãƒï¼‰ï¼Œ
+% PostScriptã®1ãƒã‚¤ãƒ³ãƒˆã¯1/72インãƒã§ã™ãŒï¼Œ
+% \TeX ã§ã¯1/72.27インãƒã‚’1pt(ãƒã‚¤ãƒ³ãƒˆï¼‰ï¼Œ
+% 1/72インãƒã‚’1bp(ビッグãƒã‚¤ãƒ³ãƒˆï¼‰ã¨è¡¨ã—ã¾ã™ã€‚
+% QuarkXPressãªã©ã®DTPソフトã¯æ¨™æº–ã§1/72インãƒã‚’1ãƒã‚¤ãƒ³ãƒˆ
+% ã¨ã—ã¾ã™ãŒï¼Œä»¥ä¸‹ã§ã¯ã™ã¹ã¦1/72.27インãƒã‚’1ptã¨ã—ã¦ã„ã¾ã™ã€‚
+% 1インãƒã¯å®šç¾©ã«ã‚ˆã‚Š25.4mmã§ã™ã€‚
+%
+% \pTeX (アスキーãŒæ—¥æœ¬èªžåŒ–ã—ãŸ\TeX )ã§ã¯ï¼Œä¾‹ãˆã°å¾“æ¥ã®ãƒ•ã‚©ãƒ³ãƒˆãƒ¡ãƒˆãƒªãƒƒã‚¯
+% \texttt{min10}ã‚„JISフォントメトリックã§ã¯ã€Œå…¬ç§°10ãƒã‚¤ãƒ³ãƒˆã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã¯ï¼Œ
+% 実際ã«ã¯9.62216ptã§å‡ºåŠ›ã•ã‚Œã‚‹ï¼ˆãƒ¡ãƒˆãƒªãƒƒã‚¯å´ã§0.962216å€ã•ã‚Œã‚‹ï¼‰ã€ã¨ã„ã†
+% 仕様ã«ãªã£ã¦ã„ã¾ã™ã€‚
+% 一方,Lua\TeX-jaã®æä¾›ã™ã‚‹ãƒ¡ãƒˆãƒªãƒƒã‚¯ã§ã¯ï¼Œãã®ã‚ˆã†ãªã“ã¨ã¯ã‚ã‚Šã¾ã›ã‚“。
+% 公称10ãƒã‚¤ãƒ³ãƒˆã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã¯ï¼Œ10ãƒã‚¤ãƒ³ãƒˆã§å‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+%
+% ã“ã®\texttt{ltjsclasses}ã§ã‚‚,派生元ã®\texttt{jsclasses}ã¨åŒã˜ã‚ˆã†ã«ï¼Œ
+% ã“ã®å…¬ç§°10ãƒã‚¤ãƒ³ãƒˆã®ãƒ•ã‚©ãƒ³ãƒˆã‚’ã“ã“ã§ã¯13ç´šã«ç¸®å°ã—ã¦
+% 使ã†ã“ã¨ã«ã—ã¾ã™ã€‚ãã®ãŸã‚ã«ã¯ï¼Œ$13\,\textrm{Q}/10\,\textrm{pt}\simeq 0.924715$å€
+% ã™ã‚Œã°ã„ã„ã“ã¨ã«ãªã‚Šã¾ã™ã€‚
+%
+% |\ltj@stdmcfont|,~|\ltj@stdgtfont| ã«ã‚ˆã‚‹ï¼Œãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ä½¿ã‚れる明æœãƒ»ã‚´ã‚·ãƒƒã‚¯ã®ãƒ•ã‚©ãƒ³ãƒˆã®
+% 設定ã«å¯¾å¿œã—ã¾ã—ãŸã€‚ã“ã®2ã¤ã®å‘½ä»¤ã®å€¤ã¯ãƒ¦ãƒ¼ã‚¶ãŒæ—¥ã€…ã®åˆ©ç”¨ã§ãã®éƒ½åº¦æŒ‡å®šã™ã‚‹ã‚‚ã®ã§ã¯ãªã,
+% 何らã‹ã®ç†ç”±ã§éžåŸ‹ã‚è¾¼ã¿ãƒ•ã‚©ãƒ³ãƒˆãŒæ­£ã—ã利用ã§ããªã„å ´åˆã«ã®ã¿\texttt{luatexja.cfg}ã«ã‚ˆã£ã¦
+% セットã•ã‚Œã‚‹ã‚‚ã®ã§ã™ã€‚
+%
+% [2014-07-26 LTJ] ãªãŠï¼Œç¾çŠ¶ã®ã¨ã“ã‚,縦組用JFMã¯\texttt{jfm-ujisv.lua}ã—ã‹æº–å‚™ã—ã¦ã„ã¾ã›ã‚“。
+%
+% [2016-03-21 LTJ] 拡大率ã®è¨ˆç®—ã§1~ptã‚’$1/72.27$インãƒã§ãªã0.3514\,mmã¨é–“é•ãˆã¦æ‰±ã£ã¦ã„ãŸã®ã‚’修正。
+%
+% [2017-12-31] 和文スケール($1\,\mathrm{zw} \div \hbox{è¦æ±‚サイズ}$)を
+% 表ã™å®Ÿæ•°å€¤ãƒžã‚¯ãƒ­ |\Cjascale| を定義ã—ã¾ã—ãŸã€‚
+%
+%
+% ã“ã‚Œã«ã‚ˆã‚Šï¼Œå…¬ç§°10ãƒã‚¤ãƒ³ãƒˆã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚’0.924715å€ã—ãŸã“ã¨ã«ã‚ˆã‚Šï¼Œ
+% ç´„9.25ãƒã‚¤ãƒ³ãƒˆï¼Œ
+% DTPã§ä½¿ã†å˜ä½ï¼ˆ1/72インãƒï¼‰ã§ã¯9.21ãƒã‚¤ãƒ³ãƒˆã¨ã„ã†ã“ã¨ã«ãªã‚Šï¼Œ
+% 公称10ãƒã‚¤ãƒ³ãƒˆã¨ã„ã£ã¦ã‚‚実ã¯9ãƒã‚¤ãƒ³ãƒˆå¼·ã«ãªã‚Šã¾ã™ã€‚
+%
+% æŸå­¦ä¼šèªŒã§ã¯ï¼Œ
+% 和文フォントをPostScriptã®9ãƒã‚¤ãƒ³ãƒˆã«ã™ã‚‹ãŸã‚ã«ï¼Œ
+% $0.9*72.27/72 \simeq 0.903375$ å€ã—ã¾ã™ã€‚
+%
+% [2018-09-23 LTJ] 実際ã®|\Cjascale|ã®å®šç¾©ã¯Lua\TeX-jaã®èª­ã¿è¾¼ã¿å‰ã«ç§»å‹•ã—ã¾ã—ãŸï¼Ž
+% ã“ã†ã™ã‚‹ã“ã¨ã«ã‚ˆã£ã¦ã€Œ0.962216å€ã•ã‚ŒãŸå’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆã€ã¨ã„ã†å®Ÿéš›ã«ã¯ä½¿ã‚ã‚Œãªã„和文フォントを
+% 読ã¿è¾¼ã‚€å¿…è¦ãŒãªããªã‚Šã¾ã™ï¼Ž
+%
+%
+% 実際ã«ãƒ•ã‚©ãƒ³ãƒˆã®å†å®šç¾©ã‚’è¡Œã†éƒ¨åˆ†ã§ã™ï¼Ž
+%
+% [2018-09-23 LTJ] |\Cjascale|ã®è¨­å®šã‚’å‰å€’ã—ã—ãŸã“ã¨ã«ä¼´ã„,実際ã®å†å®šç¾©ã¯
+% \texttt{mingoth}, \texttt{ptexjis}ã®ã¨ãã—ã‹å¿…è¦ãªããªã‚Šã¾ã—ãŸï¼Ž
+%
+% \begin{macrocode}
+\expandafter\let\csname JY3/mc/m/n/10\endcsname\relax
+\ifmingoth
+ \DeclareFontShape{JY3}{mc}{m}{n}{<-> s * [\Cjascale] \ltj@stdmcfont:jfm=min}{}
+ \DeclareFontShape{JY3}{gt}{m}{n}{<-> s * [\Cjascale] \ltj@stdgtfont:jfm=min}{}
+\else
+ \ifptexjis
+ \DeclareFontShape{JY3}{mc}{m}{n}{<-> s * [\Cjascale] \ltj@stdmcfont:jfm=jis}{}
+ \DeclareFontShape{JY3}{gt}{m}{n}{<-> s * [\Cjascale] \ltj@stdgtfont:jfm=jis}{}
+ \fi
+\fi
+% \end{macrocode}
+%
+% 和文ã§ã‚¤ã‚¿ãƒªãƒƒã‚¯ä½“,斜体,サンセリフ体,
+% タイプライタ体ã®ä»£ã‚ã‚Šã«ã‚´ã‚·ãƒƒã‚¯ä½“を使ã†ã“ã¨ã«ã—ã¾ã™ã€‚
+%
+% [2014-03-25 LTJ] タイプライタ体ã«åˆã‚ã›ã‚‹ãƒ•ã‚¡ãƒŸãƒªã‚’ |\jttdefault| ã¨ã—,
+% 通常ã®ã‚´ã‚·ãƒƒã‚¯ä½“ã¨åˆ¥ã«ã§ãるよã†ã«ã—ã¾ã—ãŸã€‚|\jttdefault| ã¯ï¼Œæ¨™æº–ã§
+% |\gtdefault| ã¨å®šç¾©ã—ã¦ã„ã¾ã™ã€‚
+%
+% [2003-03-16] イタリック体,斜体ã«ã¤ã„ã¦ï¼Œå’Œæ–‡ã§ã‚´ã‚·ãƒƒã‚¯ã‚’当ã¦ã¦ã„ã¾ã—ãŸãŒï¼Œ
+% æ•°å­¦ã®å®šç†ç’°å¢ƒãªã©ã§å¤šé‡ã®ã‚¤ã‚¿ãƒªãƒƒã‚¯ä½“を使ã†ã“ã¨ãŒã‚り,ゴシックã«
+% ã™ã‚‹ã¨é»’々ã¨ãªã£ã¦ã—ã¾ã†ã¨ã„ã†å¼Šå®³ãŒã‚ã‚Šã¾ã—ãŸã€‚
+% |amsthm| を使ã‚ãªã„å ´åˆã¯å®šç†ã®æœ¬æ–‡ãŒæ˜Žæœã«ãªã‚‹ã‚ˆã†ã« |\newtheorem|
+% 環境を手直ã—ã—ã¦ã—ã®ã„ã§ã„ã¾ã—ãŸãŒï¼Œ
+% \TeX ãŒæ•°å­¦ã§å¤šç”¨ã•ã‚Œã‚‹ã“ã¨ã‚’考ãˆã‚‹ã¨ï¼Œã‚¤ã‚¿ãƒªãƒƒã‚¯ä½“ã«æ˜Žæœä½“ã‚’
+% 当ã¦ãŸã»ã†ãŒã„ã„よã†ã«æ€ãˆã¦ãã¾ã—ãŸã®ã§ï¼Œ
+% イタリック体・斜体ã«å¯¾å¿œã™ã‚‹å’Œæ–‡ã‚’明æœä½“ã«å¤‰ãˆã‚‹ã“ã¨ã«ã—ã¾ã—ãŸã€‚
+%
+% [2004-11-03] |\rmfamily| も和文対応ã«ã—ã¾ã—ãŸã€‚
+%
+% [2016-01-30 LTJ] |\rmfamily|, |\sffamily|, |\ttfamily| ã®å†å®šç¾©ã‚’Lua\TeX-ja
+% カーãƒãƒ«ã«ç§»å‹•ã•ã›ãŸã®ã§ï¼Œã“ã“ã§ã¯å’Œæ–‡å¯¾å¿œã«ã™ã‚‹ãƒ•ãƒ©ã‚° |\@ltj@match@family|\
+% を有効ã«ã•ã›ã‚‹ã ã‘ã§ã‚ˆã„ã§ã™ã€‚
+%
+% [2018-06-09 LTJ] シリーズ|b|ã¯åŒã˜æ›¸ä½“ã®|bx|ã¨ç­‰ä¾¡ã«ãªã‚‹ã‚ˆã†ã«å®£è¨€ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\DeclareFontShape{JY3}{mc}{bx}{n}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JY3}{gt}{bx}{n}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JY3}{mc}{b}{n}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JY3}{mc}{b}{n}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JY3}{mc}{m}{it}{<->ssub*mc/m/n}{}
+\DeclareFontShape{JY3}{mc}{m}{sl}{<->ssub*mc/m/n}{}
+\DeclareFontShape{JY3}{mc}{m}{sc}{<->ssub*mc/m/n}{}
+\DeclareFontShape{JY3}{gt}{m}{it}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JY3}{gt}{m}{sl}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JY3}{mc}{bx}{it}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JY3}{mc}{bx}{sl}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JY3}{mc}{b}{it}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JY3}{mc}{b}{sl}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JT3}{mc}{bx}{n}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JT3}{gt}{bx}{n}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JT3}{mc}{b}{n}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JT3}{mc}{b}{n}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JT3}{mc}{m}{it}{<->ssub*mc/m/n}{}
+\DeclareFontShape{JT3}{mc}{m}{sl}{<->ssub*mc/m/n}{}
+\DeclareFontShape{JT3}{mc}{m}{sc}{<->ssub*mc/m/n}{}
+\DeclareFontShape{JT3}{gt}{m}{it}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JT3}{gt}{m}{sl}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JT3}{mc}{bx}{it}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JT3}{mc}{bx}{sl}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JT3}{mc}{b}{it}{<->ssub*gt/m/n}{}
+\DeclareFontShape{JT3}{mc}{b}{sl}{<->ssub*gt/m/n}{}
+\renewcommand\jttdefault{\gtdefault}\@ltj@match@familytrue
+% \end{macrocode}
+%%
+% Lua\TeX-jaã§ã¯å’Œæ–‡çµ„版ã«ä¼´ã†ã‚°ãƒ«ãƒ¼ã¯ãƒŽãƒ¼ãƒ‰ãƒ™ãƒ¼ã‚¹ã§æŒ¿å…¥ã™ã‚‹ã‚ˆã†ã«ãªã‚Šï¼Œã¾ãŸ
+% 欧文・和文間ã®ã‚°ãƒ«ãƒ¼ã¨ã‚¤ã‚¿ãƒªãƒƒã‚¯è£œæ­£ã¯å¹²æ¸‰ã—ãªã„よã†ã«ãªã‚Šã¾ã—ãŸã€‚
+% ã¾ã ã€Œå’Œæ–‡ã®æ–œä½“ã€ã«ã¤ã„ã¦ã¯Lua\LaTeX カーãƒãƒ«å´ã§ã¾ã¨ã‚‚ãªå¯¾å¿œãŒã•ã‚Œã¦ã„ã¾ã›ã‚“ãŒï¼Œ
+% \texttt{jsclasses}ã§è¡Œã‚ã‚Œã¦ã„㟠|\textmc|, |\textgt| ã®å†å®šç¾©ã¯ä¸è¦ã®ã‚ˆã†ã«æ€ã‚ã‚Œã¾ã™ã€‚
+%
+% \texttt{jsclasses.dtx}中ã§è¡Œã‚ã‚Œã¦ã„㟠|\reDeclareMathAlphabet| ã®å†å®šç¾©ã¯å‰Šé™¤ã€‚
+% ã¾ãŸï¼ŒYue ZHANGã•ã‚“作ã®\texttt{fixjfm}パッケージ対応ã®ã‚³ãƒ¼ãƒ‰ã‚‚Lua\TeX-jaã§ã¯å‰Šé™¤ã—ã¦ã„ã¾ã™ï¼Ž
+%
+% \begin{macrocode}
+\AtBeginDocument{%
+ \unless\ifltj@disablejfam
+ \reDeclareMathAlphabet{\mathrm}{\mathrm}{\mathmc}
+ \reDeclareMathAlphabet{\mathbf}{\mathbf}{\mathgt}
+ \fi
+}%
+% \end{macrocode}
+%
+% \begin{macro}{\textsterling}
+%
+% ã“れ㯠|\pounds| 命令ã§å®Ÿéš›ã«å‘¼ã³å‡ºã•ã‚Œã‚‹æ–‡å­—ã§ã™ã€‚
+% 従æ¥ã‹ã‚‰ã®OT1エンコーディングã§ã¯ |\$| ã®ã‚¤ã‚¿ãƒªãƒƒã‚¯ä½“㌠|\pounds|
+% ãªã®ã§ \texttt{cmti} ãŒä½¿ã‚ã‚Œã¦ã„ã¾ã—ãŸãŒï¼Œ
+% 1994年春ã‹ã‚‰ã¯ \texttt{cmu}(upright italic,直立イタリック体)
+% ã«å¤‰ã‚ã‚Šã¾ã—ãŸã€‚
+% ã—ã‹ã— \texttt{cmu} ã¯ãã®æ€§æ ¼ã‹ã‚‰ã—ã¦å®Ÿé¨“çš„ãªã‚‚ã®ã§ã‚り,
+% |\pounds| 以外ã§ä½¿ã‚れるã¨ã¯æ€ãˆãªã„ã®ã§ï¼Œ
+% ã“ã“ã§ã¯ \texttt{cmti} ã«æˆ»ã—ã¦ã—ã¾ã„ã¾ã™ã€‚
+%
+% [2003-08-20] Computer Modernフォントを使ã†æ©Ÿä¼šã‚‚減り,T1エンコーディング
+% ãŒä¸€èˆ¬çš„ã«ãªã£ã¦ãã¾ã—ãŸã€‚ã“ã®å®šç¾©ã¯ã‚‚ã†ã‚ã¾ã‚Šæ„味ãŒãªã„ã®ã§æ¶ˆã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+% \DeclareTextCommand{\textsterling}{OT1}{{\itshape\char`\$}}
+% \end{macrocode}
+% \end{macro}
+%
+% アスキー㮠\texttt{kinsoku.dtx} ã§ã¯ã€Œâ€™ã€ã€Œâ€œã€ã€Œâ€ã€å‰å¾Œã®ãƒšãƒŠãƒ«ãƒ†ã‚£ãŒ5000ã«
+% ãªã£ã¦ã„ãŸã®ã§ï¼Œ\texttt{jsclasses.dtx} ã§ã¯ãれを 10000 ã«è£œæ­£ã—ã¦ã„ã¾ã—ãŸã€‚
+% ã—ã‹ã—,Lua\TeX-jaã§ã¯æœ€åˆã‹ã‚‰ã“れらã®ãƒ‘ラメータ㯠10000 ãªã®ã§ï¼Œ
+% ã‚‚ã¯ã‚„補正ã™ã‚‹å¿…è¦ã¯ã‚ã‚Šã¾ã›ã‚“。
+%
+% 「\TeXï¼ã€ã€Œã€’515ã€ã®è¨˜å·ã¨æ•°å­—ã®é–“ã«å››åˆ†ã‚¢ã‚­ãŒå…¥ã‚‰ãªã„よã†ã«ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\ltjsetparameter{jaxspmode={`ï¼,2}}
+\ltjsetparameter{jaxspmode={`〒,1}}
+% \end{macrocode}
+%
+% 「Cã‚„C++ã§ã¯â€¦â€¦ã€ã¨æ›¸ãã¨ï¼ŒC++ã®ç›´å¾Œã«å››åˆ†ã‚¢ã‚­ãŒå…¥ã‚‰ãªã„ã®ã§ãƒãƒ©ãƒ³ã‚¹ãŒæ‚ªããªã‚Šã¾ã™ã€‚
+% 四分アキãŒå…¥ã‚‹ã‚ˆã†ã«ã—ã¾ã—ãŸã€‚\% ã®ä¸¡å´ã‚‚åŒã˜ã§ã™ã€‚
+%
+% \begin{macrocode}
+\ltjsetparameter{alxspmode={`+,3}}
+\ltjsetparameter{alxspmode={`\%,3}}
+% \end{macrocode}
+%
+% \texttt{jsclasses.dtx} ã§ã¯80〜ffã®æ–‡å­—ã® |\xspcode| ã‚’å…¨ã¦3ã«ã—ã¦ã„ã¾ã—ãŸãŒï¼Œ
+% Lua\TeX-jaã§ã¯åŒæ§˜ã®å†…容ãŒæœ€åˆã‹ã‚‰è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã®ã§ï¼Œå¯¾å¿œã™ã‚‹éƒ¨åˆ†ã¯å‰Šé™¤ã€‚
+%
+% \begin{macro}{\@}
+%
+% 欧文ã¨ã„ãˆã°ï¼Œ\LaTeX ã® |\def\@{\spacefactor\@m}| ã¨ã„ã†å®šç¾©ï¼ˆ|\@m| ã¯1000)
+% ã§ã¯ |I watch TV\@.| ã¨æ›¸ã㨠V ã¨ãƒ”リオドã®ãƒšã‚¢ã‚«ãƒ¼ãƒ‹ãƒ³ã‚°ãŒåŠ¹ã‹ãªããªã‚Šã¾ã™ã€‚
+% ãã“ã§ï¼Œæ¬¡ã®ã‚ˆã†ãªå®šç¾©ã«ç›´ã—,|I watch TV.\@| ã¨æ›¸ãã“ã¨ã«ã—ã¾ã™ã€‚
+%
+% [2016-07-14] 2015-01-01ã®\LaTeX ã§ï¼Œauxiliary filesã«æ›¸ã出ã•ã‚ŒãŸã¨ãã«
+% スペースãŒé£Ÿã‚ã‚Œãªã„よã†ã«ã™ã‚‹ä¿®æ­£ãŒå…¥ã‚Šã¾ã—ãŸã€‚ã“ã‚Œã«åˆã‚ã›ã¦ |{}| を補ã„ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\def\@{\spacefactor3000{}}
+% \end{macrocode}
+% \end{macro}
+%
+% \section{フォントサイズ}
+%
+% フォントサイズを変ãˆã‚‹å‘½ä»¤ï¼ˆ|\normalsize|,|\small| ãªã©ï¼‰
+% ã®å®Ÿéš›ã®æŒ™å‹•ã®è¨­å®šã¯ï¼Œä¸‰ã¤ã®å¼•æ•°ã‚’ã¨ã‚‹å‘½ä»¤ |\@setfontsize| を使ã£ã¦ï¼Œ
+% ãŸã¨ãˆã°
+% \begin{quote}
+% |\@setfontsize{\normalsize}{10}{16}|
+% \end{quote}
+% ã®ã‚ˆã†ã«ã—ã¦è¡Œã„ã¾ã™ã€‚ã“ã‚Œã¯
+% \begin{quote}
+% |\normalsize| ã¯10ãƒã‚¤ãƒ³ãƒˆã®ãƒ•ã‚©ãƒ³ãƒˆã‚’使ã„,行é€ã‚Šã¯16ãƒã‚¤ãƒ³ãƒˆã§ã‚ã‚‹
+% \end{quote}
+% ã¨ã„ã†æ„味ã§ã™ã€‚
+% ãŸã ã—,処ç†ã‚’速ãã™ã‚‹ãŸã‚,
+% 以下ã§ã¯10ã¨åŒç¾©ã®\LaTeX ã®å†…部命令 |\@xpt| を使ã£ã¦ã„ã¾ã™ã€‚
+% ã“ã® |\@xpt| ã®é¡žã¯æ¬¡ã®ã‚‚ã®ãŒã‚り,\LaTeX 本体ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+%\begin{verbatim}
+% \@vpt 5 \@vipt 6 \@viipt 7
+% \@viiipt 8 \@ixpt 9 \@xpt 10
+% \@xipt 10.95 \@xiipt 12 \@xivpt 14.4
+%\end{verbatim}
+%
+% \begin{macro}{\@setfontsize}
+%
+% ã“ã“ã§ã¯ |\@setfontsize| ã®å®šç¾©ã‚’少々変更ã—ã¦ï¼Œ
+% 段è½ã®å­—下㒠|\parindent|,
+% 和文文字間ã®ã‚¹ãƒšãƒ¼ã‚¹ |kanjiskip|,
+% 和文・欧文間ã®ã‚¹ãƒšãƒ¼ã‚¹ |xkanjiskip| を変更ã—ã¦ã„ã¾ã™ã€‚
+%
+% |kanjiskip| 㯠|ltj-latex.sty| 㧠|0pt plus 0.4pt minus 0.5pt| ã«
+% 設定ã—ã¦ã„ã¾ã™ãŒï¼Œ
+% ã“ã‚Œã¯ãã‚‚ãも文字サイズã®å¤‰æ›´ã«å¿œã˜ã¦å¤‰ã‚ã‚‹ã¹ãã‚‚ã®ã§ã™ã€‚
+% ãã‚Œã«ï¼Œãƒ—ラスã«ãªã£ãŸã‚Šãƒžã‚¤ãƒŠã‚¹ã«ãªã£ãŸã‚Šã™ã‚‹ã®ã¯ï¼Œ
+% 追ã„出ã—ã¨è¿½ã„è¾¼ã¿ã®æ··åœ¨ãŒç”Ÿã˜ï¼Œçµ±ä¸€æ€§ã‚’欠ãã¾ã™ã€‚
+% ãªã‚‹ã¹ã追ã„出ã—ã«ãªã‚‹ã‚ˆã†ã«ãƒ—ラスã®å€¤ã ã‘ã«ã—ãŸã„ã¨ã“ã‚ã§ã™ãŒï¼Œ
+% ã”ãã‚ãšã‹ãªãƒžã‚¤ãƒŠã‚¹ã¯è¨±ã™ã“ã¨ã«ã—ã¾ã—ãŸã€‚
+%
+% |xkanjiskip| ã«ã¤ã„ã¦ã¯ï¼Œå››åˆ†ã¤ã¾ã‚Šå…¨è§’ã®1/4を標準ã¨ã—ã¦ï¼Œ
+% 追ã„出ã™ãŸã‚ã«ä¸‰åˆ†ã‚ã‚‹ã„ã¯äºŒåˆ†ã¾ã§å»¶ã°ã™ã®ãŒä¸€èˆ¬çš„ã§ã™ãŒï¼Œ
+% ã“ã“ã§ã¯Timesã‚„Palatinoã®ã‚¹ãƒšãƒ¼ã‚¹ãŒã»ã¼å››åˆ†ã§ã‚ã‚‹ã“ã¨ã«ç€ç›®ã—ã¦ï¼Œ
+% ã“ã‚Œã«ä¸€è‡´ã•ã›ã¦ã„ã¾ã™ã€‚ã“ã‚Œãªã‚‰æ›¸ãã¨ãã«ã‚¹ãƒšãƒ¼ã‚¹ã‚’空ã‘ã¦ã‚‚
+% 空ã‘ãªãã¦ã‚‚åŒã˜å‡ºåŠ›ã«ãªã‚Šã¾ã™ã€‚
+%
+% |\parindent| ã«ã¤ã„ã¦ã¯ï¼Œ0(以下)ã§ãªã‘ã‚Œã°å…¨è§’幅(|1\zw|)ã«ç›´ã—ã¾ã™ã€‚
+%
+% [2008-02-18] |english| オプション㧠|\parindent| ã‚’ 1em ã«ã—ã¾ã—ãŸã€‚
+%
+% [2014-05-14 LTJ] |\ltjsetparameter|ã®å®Ÿè¡Œã¯æ™‚é–“ãŒã‹ã‹ã‚‹ã®ã§ï¼Œ
+% |\ltjsetkanjiskip| 㨠|\ltjsetxkanjiskip|(両者ã¨ã‚‚,
+% 実行å‰ã«ã¯ |\ltj@setpar@global| ã®å®Ÿè¡ŒãŒå¿…è¦ï¼‰ã«ã—ã¾ã—ãŸã€‚
+%
+% [2014-12-24 LTJ] |jsclasses| ã§ã¯ï¼Œ|\@setfontsize| 中㧠|xkanjiskip| ã‚’
+% 設定ã™ã‚‹ã®ã¯ç¾åœ¨ã®å’Œæ¬§æ–‡é–“空白ã®è‡ªç„¶é•·ãŒæ­£ã®å ´åˆã ã‘ã§ã—ãŸã€‚
+% |ltjsclasses| ã§ã¯æœ€åˆã‹ã‚‰ã“ã®åˆ¤å®šãŒæŠœã‘ã¦ã—ã¾ã£ã¦ã„ãŸã®ã§ï¼Œå¾©æ´»ã•ã›ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\def\@setfontsize#1#2#3{%
+% \@nomath#1%
+ \ifx\protect\@typeset@protect
+ \let\@currsize#1%
+ \fi
+ \fontsize{#2}{#3}\selectfont
+ \ifdim\parindent>\z@
+ \if@english
+ \parindent=1em
+ \else
+ \parindent=1\zw
+ \fi
+ \fi
+ \ltj@setpar@global
+ \ltjsetkanjiskip\z@ plus .1\zw minus .01\zw
+ \@tempskipa=\ltjgetparameter{xkanjiskip}
+ \ifdim\@tempskipa>\z@
+ \if@slide
+ \ltjsetxkanjiskip .1em
+ \else
+ \ltjsetxkanjiskip .25em plus .15em minus .06em
+ \fi
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\jsc@setfontsize}
+% クラスファイルã®å†…部ã§ã¯ï¼Œæ‹¡å¤§çŽ‡ã‚‚考慮ã—㟠|\jsc@setfontsize| ã‚’
+% |\@setfontsize| ã®å¤‰ã‚ã‚Šã«ç”¨ã„ã‚‹ã“ã¨ã«ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\def\jsc@setfontsize#1#2#3{%
+ \@setfontsize#1{#2\jsc@mpt}{#3\jsc@mpt}}
+% \end{macrocode}
+% \end{macro}
+%
+% ã“れらã®ã‚°ãƒ«ãƒ¼ã‚’ã‚‚ã£ã¦ã—ã¦ã‚‚行分割ãŒã§ããªã„å ´åˆã¯ï¼Œ
+% |\emergencystretch| ã«è¨´ãˆã¾ã™ã€‚
+%
+% \begin{macrocode}
+\emergencystretch 3\zw
+% \end{macrocode}
+%
+% \begin{macro}{\ifnarrowbaselines}
+% \begin{macro}{\narrowbaselines}
+% \begin{macro}{\widebaselines}
+%
+% 欧文用ã«è¡Œé–“ã‚’ç‹­ãã™ã‚‹è«–ç†å¤‰æ•°ã¨ï¼Œãれを真・å½ã«ã™ã‚‹ãŸã‚ã®ã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚
+%
+% [2003-06-30] æ•°å¼ã«å…¥ã‚‹ã¨ã“ã‚㧠|\narrowbaselines|
+% を実行ã—ã¦ã„ã‚‹ã®ã§ |\abovedisplayskip| ç­‰ãŒåˆæœŸåŒ–
+% ã•ã‚Œã¦ã—ã¾ã†ã¨ã„ã†shintokã•ã‚“ã®ã”指摘ã«å¯¾ã—ã¦ï¼Œ
+% ã—ã£ã½æ„›å¥½å®¶ã•ã‚“ãŒæ¬¡ã®ä¿®æ­£ã‚’æ•™ãˆã¦ãã ã•ã„ã¾ã—ãŸã€‚
+%
+% [2008-02-18] |english| オプションã§æœ€åˆã®æ®µè½ã®ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã‚’ã—ãªã„よã†ã«ã—ã¾ã—ãŸã€‚
+%
+% TODO: Hasumiã•ã‚“ [qa:54539] ã®ã”指摘ã¯è€ƒæ…®ä¸­ã§ã™ã€‚
+%
+% [2015-01-07 LTJ] é…ããªã‚Šã¾ã—ãŸãŒï¼Œ
+% \url{http://oku.edu.mie-u.ac.jp/tex/mod/forum/discuss.php?d=1005} ã«ã‚ã£ãŸZRã•ã‚“ã®ãƒ‘ッãƒã‚’å–ã‚Šè¾¼ã¿ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\newif\ifnarrowbaselines
+\if@english
+ \narrowbaselinestrue
+\fi
+\def\narrowbaselines{%
+ \narrowbaselinestrue
+ \skip0=\abovedisplayskip
+ \skip2=\abovedisplayshortskip
+ \skip4=\belowdisplayskip
+ \skip6=\belowdisplayshortskip
+ \@currsize\selectfont
+ \abovedisplayskip=\skip0
+ \abovedisplayshortskip=\skip2
+ \belowdisplayskip=\skip4
+ \belowdisplayshortskip=\skip6\relax}
+\def\widebaselines{\narrowbaselinesfalse\@currsize\selectfont}
+\def\ltj@@ifnarrowbaselines{%
+ \ifnarrowbaselines\expandafter\@firstoftwo
+ \else \expandafter\@secondoftwo
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\normalsize}
+%
+% 標準ã®ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã¨è¡Œé€ã‚Šã‚’é¸ã¶ã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚
+%
+% 本文10ãƒã‚¤ãƒ³ãƒˆã®ã¨ãã®è¡Œé€ã‚Šã¯ï¼Œ
+% 欧文ã®æ¨™æº–クラスファイルã§ã¯12ãƒã‚¤ãƒ³ãƒˆï¼Œ
+% アスキーã®å’Œæ–‡ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã§ã¯15ãƒã‚¤ãƒ³ãƒˆã«ãªã£ã¦ã„ã¾ã™ãŒï¼Œ
+% ã“ã“ã§ã¯16ãƒã‚¤ãƒ³ãƒˆã«ã—ã¾ã—ãŸã€‚
+% ãŸã ã— |\narrowbaselines| ã§æ¬§æ–‡ç”¨ã®12ãƒã‚¤ãƒ³ãƒˆã«ãªã‚Šã¾ã™ã€‚
+%
+% 公称10ãƒã‚¤ãƒ³ãƒˆã®å’Œæ–‡ãƒ•ã‚©ãƒ³ãƒˆãŒç´„9.25ãƒã‚¤ãƒ³ãƒˆ
+% (アスキーã®ã‚‚ã®ã®0.961å€ï¼‰ã§ã‚ã‚‹ã“ã¨ã‚‚ã‚り,
+% è¡Œé€ã‚ŠãŒã‹ãªã‚Šã‚†ã£ãŸã‚Šã¨ã—ãŸã¨æ€ã„ã¾ã™ã€‚
+% 実際,$16/9.25 \approx 1.73$ ã§ã‚り,
+% 和文ã®æŽ¨å¥¨å€¤ã®ä¸€ã¤ã€ŒäºŒåˆ†å››åˆ†ã€ï¼ˆ1.75)
+% ã«è¿‘ã¥ãã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\renewcommand{\normalsize}{%
+ \ltj@@ifnarrowbaselines
+ {\jsc@setfontsize\normalsize\@xpt\@xiipt}%
+ {\jsc@setfontsize\normalsize\@xpt{\n@baseline}}%
+% \end{macrocode}
+%
+% æ•°å¼ã®ä¸Šã®ã‚¢ã‚­ï¼ˆ|\abovedisplayskip|),
+% 短ã„æ•°å¼ã®ä¸Šã®ã‚¢ã‚­ï¼ˆ|\abovedisplayshortskip|),
+% æ•°å¼ã®ä¸‹ã®ã‚¢ã‚­ï¼ˆ|\belowdisplayshortskip|)ã®è¨­å®šã§ã™ã€‚
+%
+% [2003-02-16] ã¡ã‚‡ã£ã¨å¤‰ãˆã¾ã—ãŸã€‚
+%
+% [2009-08-26] \TeX\ Q\,\&\,A 52569ã‹ã‚‰å§‹ã¾ã‚‹è­°è«–ã«ã¤ã„ã¦é€¡å·¡ã—ã¦
+% ã„ã¾ã—ãŸãŒï¼Œçµå±€ï¼Œå¾®èª¿ç¯€ã—ã¦ã¿ã‚‹ã“ã¨ã«ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+ \abovedisplayskip 11\jsc@mpt \@plus3\jsc@mpt \@minus4\jsc@mpt
+ \abovedisplayshortskip \z@ \@plus3\jsc@mpt
+ \belowdisplayskip 9\jsc@mpt \@plus3\jsc@mpt \@minus4\jsc@mpt
+ \belowdisplayshortskip \belowdisplayskip
+% \end{macrocode}
+%
+% 最後ã«ï¼Œãƒªã‚¹ãƒˆç’°å¢ƒã®ãƒˆãƒƒãƒ—レベルã®ãƒ‘ラメータ |\@listI| を,
+% |\@listi| ã«ã‚³ãƒ”ーã—ã¦ãŠãã¾ã™ã€‚|\@listI| ã®è¨­å®šã¯å¾Œã§å‡ºã¦ãã¾ã™ã€‚
+%
+% \begin{macrocode}
+ \let\@listi\@listI}
+% \end{macrocode}
+%
+% ã“ã“ã§å®Ÿéš›ã«æ¨™æº–フォントサイズã§åˆæœŸåŒ–ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\mcfamily\selectfont\normalsize
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\Cht}
+% \begin{macro}{\Cdp}
+% \begin{macro}{\Cwd}
+% \begin{macro}{\Cvs}
+% \begin{macro}{\Chs}
+%
+% 基準ã¨ãªã‚‹é•·ã•ã®è¨­å®šã‚’ã—ã¾ã™ã€‚
+% \texttt{lltjfont.sty}ã§å®£è¨€ã•ã‚Œã¦ã„ã‚‹
+% パラメータã«å®Ÿéš›ã®å€¤ã‚’設定ã—ã¾ã™ã€‚
+% ãŸã¨ãˆã° |\Cwd| 㯠|\normalfont| ã®å…¨è§’幅(|1\zw|)ã§ã™ã€‚
+%
+% [2017-08-31] 基準ã¨ã™ã‚‹æ–‡å­—を「全角空白ã€ï¼ˆEUCコード\texttt{0xA1A1})ã‹ã‚‰
+% 「漢ã€ï¼ˆJISコード\texttt{0x3441})ã¸å¤‰æ›´ã—ã¾ã—ãŸã€‚
+%
+% [2017-09-19] 内部的ã«ä½¿ã£ãŸ |\box0| を空ã«ã—ã¾ã™ã€‚
+% \begin{macrocode}
+\setbox0\hbox{æ¼¢}
+\setlength\Cht{\ht0}
+\setlength\Cdp{\dp0}
+\setlength\Cwd{\wd0}
+\setlength\Cvs{\baselineskip}
+\setlength\Chs{\wd0}
+\setbox0=\box\voidb@x
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\small}
+%
+% |\small| ã‚‚ |\normalsize| ã¨åŒæ§˜ã«è¨­å®šã—ã¾ã™ã€‚
+% è¡Œé€ã‚Šã¯ï¼Œ|\normalsize| ãŒ16ãƒã‚¤ãƒ³ãƒˆãªã‚‰ï¼Œ
+% 割åˆã‹ã‚‰ã™ã‚Œã°$16 \times 0.9 = 14.4$ãƒã‚¤ãƒ³ãƒˆã«ãªã‚Šã¾ã™ãŒï¼Œ
+% |\small| ã®ä½¿ã‚れ方を考ãˆã¦ï¼Œã“ã“ã§ã¯å’Œæ–‡13ãƒã‚¤ãƒ³ãƒˆï¼Œ
+% 欧文11ãƒã‚¤ãƒ³ãƒˆã¨ã—ã¾ã™ã€‚
+% ã¾ãŸï¼Œ|\topsep| 㨠|\parsep| ã¯ï¼Œå…ƒã¯ãã‚Œãžã‚Œ$4 \pm 2$,$2 \pm 1$
+% ãƒã‚¤ãƒ³ãƒˆã§ã—ãŸãŒï¼Œã“ã“ã§ã¯ã‚¼ãƒ­ï¼ˆ|\z@|)ã«ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\newcommand{\small}{%
+ \ltj@@ifnarrowbaselines
+%<!kiyou> {\jsc@setfontsize\small\@ixpt{11}}%
+%<kiyou> {\jsc@setfontsize\small{8.8888}{11}}%
+%<!kiyou> {\jsc@setfontsize\small\@ixpt{13}}%
+%<kiyou> {\jsc@setfontsize\small{8.8888}{13.2418}}%
+ \abovedisplayskip 9\jsc@mpt \@plus3\jsc@mpt \@minus4\jsc@mpt
+ \abovedisplayshortskip \z@ \@plus3\jsc@mpt
+ \belowdisplayskip \abovedisplayskip
+ \belowdisplayshortskip \belowdisplayskip
+ \def\@listi{\leftmargin\leftmargini
+ \topsep \z@
+ \parsep \z@
+ \itemsep \parsep}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\footnotesize}
+%
+% |\footnotesize| ã‚‚åŒæ§˜ã§ã™ã€‚
+% |\topsep| 㨠|\parsep| ã¯ï¼Œå…ƒã¯ãã‚Œãžã‚Œ$3 \pm 1$,$2 \pm 1$
+% ãƒã‚¤ãƒ³ãƒˆã§ã—ãŸãŒï¼Œã“ã“ã§ã¯ã‚¼ãƒ­ï¼ˆ|\z@|)ã«ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\newcommand{\footnotesize}{%
+ \ltj@@ifnarrowbaselines
+%<!kiyou> {\jsc@setfontsize\footnotesize\@viiipt{9.5}}%
+%<kiyou> {\jsc@setfontsize\footnotesize{8.8888}{11}}%
+%<!kiyou> {\jsc@setfontsize\footnotesize\@viiipt{11}}%
+%<kiyou> {\jsc@setfontsize\footnotesize{8.8888}{13.2418}}%
+ \abovedisplayskip 6\jsc@mpt \@plus2\jsc@mpt \@minus3\jsc@mpt
+ \abovedisplayshortskip \z@ \@plus2\jsc@mpt
+ \belowdisplayskip \abovedisplayskip
+ \belowdisplayshortskip \belowdisplayskip
+ \def\@listi{\leftmargin\leftmargini
+ \topsep \z@
+ \parsep \z@
+ \itemsep \parsep}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\scriptsize}
+% \begin{macro}{\tiny}
+% \begin{macro}{\large}
+% \begin{macro}{\Large}
+% \begin{macro}{\LARGE}
+% \begin{macro}{\huge}
+% \begin{macro}{\Huge}
+% \begin{macro}{\HUGE}
+%
+% ãれ以外ã®ã‚µã‚¤ã‚ºã¯ï¼Œæœ¬æ–‡ã«ä½¿ã†ã“ã¨ãŒãªã„ã®ã§ï¼Œ
+% å˜ã«ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã¨è¡Œé€ã‚Šã ã‘変更ã—ã¾ã™ã€‚
+% 特ã«æ³¨æ„ã™ã¹ã㯠|\large| ã§ï¼Œ
+% ã“ã‚Œã¯äºŒæ®µçµ„ã®ã¨ãã«ç¯€è¦‹å‡ºã—ã®ãƒ•ã‚©ãƒ³ãƒˆã¨ã—ã¦ä½¿ã„,
+% è¡Œé€ã‚Šã‚’ |\normalsize| ã¨åŒã˜ã«ã™ã‚‹ã“ã¨ã«ã‚ˆã£ã¦ï¼Œ
+% 節見出ã—ãŒè¤‡æ•°è¡Œã«ã‚ãŸã£ã¦ã‚‚段間ã§è¡ŒãŒæƒã†ã‚ˆã†ã«ã—ã¾ã™ã€‚
+%
+% [2004-11-03] |\HUGE| を追加。
+%
+% \begin{macrocode}
+\newcommand{\scriptsize}{\jsc@setfontsize\scriptsize\@viipt\@viiipt}
+\newcommand{\tiny}{\jsc@setfontsize\tiny\@vpt\@vipt}
+\if@twocolumn
+%<!kiyou> \newcommand{\large}{\jsc@setfontsize\large\@xiipt{\n@baseline}}
+%<kiyou> \newcommand{\large}{\jsc@setfontsize\large{11.111}{\n@baseline}}
+\else
+%<!kiyou> \newcommand{\large}{\jsc@setfontsize\large\@xiipt{17}}
+%<kiyou> \newcommand{\large}{\jsc@setfontsize\large{11.111}{17}}
+\fi
+%<!kiyou>\newcommand{\Large}{\jsc@setfontsize\Large\@xivpt{21}}
+%<kiyou>\newcommand{\Large}{\jsc@setfontsize\Large{12.222}{21}}
+\newcommand{\LARGE}{\jsc@setfontsize\LARGE\@xviipt{25}}
+\newcommand{\huge}{\jsc@setfontsize\huge\@xxpt{28}}
+\newcommand{\Huge}{\jsc@setfontsize\Huge\@xxvpt{33}}
+\newcommand{\HUGE}{\jsc@setfontsize\HUGE{30}{40}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% 別行立ã¦æ•°å¼ã®ä¸­ã§ã¯ |\narrowbaselines| ã«ã—ã¾ã™ã€‚
+% 和文ã®è¡Œé€ã‚Šã®ã¾ã¾ã§ã¯ï¼Œè¡Œåˆ—ã‚„å ´åˆåˆ†ã‘ã®è¡Œé€ã‚Šï¼Œ
+% 連分数ã®é«˜ã•ãªã©ãŒä¸é‡£åˆã„ã«å¤§ãããªã‚‹ãŸã‚ã§ã™ã€‚
+%
+% 本文中ã®æ•°å¼ã®ä¸­ã§ã¯ |\narrowbaselines| ã«ã—ã¦ã„ã¾ã›ã‚“。
+% 本文中ã§ã¯ãªã‚‹ã¹ãè¡Œé€ã‚ŠãŒå¤‰ã‚るよã†ãªå¤§ãã„ã‚‚ã®ã‚’使ã‚ãšï¼Œ
+% 行列㯠|amsmath| ã® |smallmatrix| 環境を使ã†ã®ãŒã„ã„ã§ã—ょã†ã€‚
+%
+% \begin{macrocode}
+\everydisplay=\expandafter{\the\everydisplay \narrowbaselines}
+% \end{macrocode}
+%
+% ã—ã‹ã—,ã“ã®ãŠã‹ã’ã§åˆ¥è¡Œæ•°å¼ã®ä¸Šä¸‹ã®ã‚¹ãƒšãƒ¼ã‚¹ãŒå°‘ã—é•ã£ã¦ã—ã¾ã„ã¾ã—ãŸã€‚
+% ã¨ã‚Šã‚ãˆãš |amsmath| ã® |equation| 関係㯠|okumacro| ã®ã»ã†ã§é€ƒã’ã¦ã„ã¾ã™ãŒï¼Œ
+% ã‚‚ã£ã¨ã†ã¾ã„逃ã’é“ãŒã‚ã‚Œã°ãŠæ•™ãˆãã ã•ã„。
+%
+% 見出ã—用ã®ãƒ•ã‚©ãƒ³ãƒˆã¯ |\bfseries| 固定ã§ã¯ãªã,|\headfont|
+% ã¨ã„ã†å‘½ä»¤ã§å®šã‚ã‚‹ã“ã¨ã«ã—ã¾ã™ã€‚
+% ã“ã‚Œã¯å¤ªã‚´ã‚·ãƒƒã‚¯ãŒä½¿ãˆã‚‹ã¨ã㯠|\sffamily| |\bfseries|
+% ã§ã„ã„ã¨æ€ã„ã¾ã™ãŒï¼Œé€šå¸¸ã®ä¸­ã‚´ã‚·ãƒƒã‚¯ã§ã¯å˜ã« |\sffamily|
+% ã ã‘ã®ã»ã†ãŒã‚ˆã•ãã†ã§ã™ã€‚
+% 『p\LaTeXe 美文書作æˆå…¥é–€ã€ï¼ˆ1997年)ã§ã¯ |\sffamily|
+% |\fontseries{sbc}| ã¨ã—ã¦æ–°ã‚´Mã¨åˆã‚ã›ã¾ã—ãŸãŒï¼Œ
+% |\fontseries{sbc}| ã¯ã¡ã‚‡ã£ã¨å¹…ãŒç‹­ã„よã†ã«æ„Ÿã˜ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+% \newcommand{\headfont}{\bfseries}
+\newcommand{\headfont}{\gtfamily\sffamily}
+% \newcommand{\headfont}{\sffamily\fontseries{sbc}\selectfont}
+% \end{macrocode}
+%
+% \section{レイアウト}
+%
+% \paragraph{二段組}
+%
+% \begin{macro}{\columnsep}
+% \begin{macro}{\columnseprule}
+%
+% |\columnsep| ã¯äºŒæ®µçµ„ã®ã¨ãã®å·¦å³ã®æ®µé–“ã®å¹…ã§ã™ã€‚
+% å…ƒã¯10ptã§ã—ãŸãŒï¼Œ|2\zw|ã«ã—ã¾ã—ãŸã€‚
+% ã“ã®ã‚¹ãƒšãƒ¼ã‚¹ã®ä¸­å¤®ã« |\columnseprule| ã®å¹…ã®ç½«ç·šãŒå¼•ã‹ã‚Œã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<!kiyou>\setlength\columnsep{2\zw}
+%<kiyou>\setlength\columnsep{28truebp}
+\setlength\columnseprule{\z@}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \paragraph{段è½}
+%
+% \begin{macro}{\lineskip}
+% \begin{macro}{\normallineskip}
+% \begin{macro}{\lineskiplimit}
+% \begin{macro}{\normallineskiplimit}
+%
+% 上下ã®è¡Œã®æ–‡å­—㌠|\lineskiplimit| より接近ã—ãŸã‚‰ï¼Œ
+% |\lineskip| より近ã¥ã‹ãªã„よã†ã«ã—ã¾ã™ã€‚
+% å…ƒã¯0ptã§ã—ãŸãŒ1ptã«å¤‰æ›´ã—ã¾ã—ãŸã€‚
+% \texttt{normal...} ã®ä»˜ã„ãŸæ–¹ã¯ä¿å­˜ç”¨ã§ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\lineskip{1\jsc@mpt}
+\setlength\normallineskip{1\jsc@mpt}
+\setlength\lineskiplimit{1\jsc@mpt}
+\setlength\normallineskiplimit{1\jsc@mpt}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\baselinestretch}
+%
+% 実際ã®è¡Œé€ã‚ŠãŒ |\baselineskip| ã®ä½•å€ã‹ã‚’表ã™ãƒžã‚¯ãƒ­ã§ã™ã€‚ãŸã¨ãˆã°
+% \begin{quote}
+% |\renewcommand{\baselinestretch}{2}|
+% \end{quote}
+% ã¨ã™ã‚‹ã¨ï¼Œè¡Œé€ã‚ŠãŒé€šå¸¸ã®2å€ã«ãªã‚Šã¾ã™ã€‚ãŸã ã—,
+% ã“れを設定ã™ã‚‹ã¨ï¼ŒãŸã¨ãˆ |\baselineskip| ãŒä¼¸ç¸®ã™ã‚‹ã‚ˆã†ã«
+% 設定ã—ã¦ã‚‚,行é€ã‚Šã®ä¼¸ç¸®ãŒã§ããªããªã‚Šã¾ã™ã€‚
+% è¡Œé€ã‚Šã®ä¼¸ç¸®ã¯ã—ãªã„ã®ãŒä¸€èˆ¬çš„ã§ã™ã€‚
+%
+% \begin{macrocode}
+\renewcommand{\baselinestretch}{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\parskip}
+% \begin{macro}{\parindent}
+%
+% |\parskip| ã¯æ®µè½é–“ã®è¿½åŠ ã‚¹ãƒšãƒ¼ã‚¹ã§ã™ã€‚
+% 元㯠0pt plus 1pt ã«ãªã£ã¦ã„ã¾ã—ãŸãŒï¼Œã“ã“ã§ã¯ã‚¼ãƒ­ã«ã—ã¾ã—ãŸã€‚
+% |\parindent| ã¯æ®µè½ã®å…ˆé ­ã®å­—下ã’å¹…ã§ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\parskip{\z@}
+\if@slide
+ \setlength\parindent{0\zw}
+\else
+ \setlength\parindent{1\zw}
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@lowpenalty}
+% \begin{macro}{\@medpenalty}
+% \begin{macro}{\@highpenalty}
+%
+% |\nopagebreak|,|\nolinebreak| ã¯å¼•æ•°ã«å¿œã˜ã¦æ¬¡ã®ãƒšãƒŠãƒ«ãƒ†ã‚£å€¤
+% ã®ã†ã¡ã©ã‚Œã‹ã‚’é¸ã¶ã‚ˆã†ã«ãªã£ã¦ã„ã¾ã™ã€‚
+% ã“ã“ã¯ã‚ªãƒªã‚¸ãƒŠãƒ«é€šã‚Šã§ã™ã€‚
+%
+% \begin{macrocode}
+\@lowpenalty 51
+\@medpenalty 151
+\@highpenalty 301
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\interlinepenalty}
+%
+% 段è½ä¸­ã®æ”¹ãƒšãƒ¼ã‚¸ã®ãƒšãƒŠãƒ«ãƒ†ã‚£ã§ã™ã€‚デフォルト㯠0 ã§ã™ã€‚
+%
+% \begin{macrocode}
+% \interlinepenalty 0
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\brokenpenalty}
+%
+% ページã®æœ€å¾Œã®è¡ŒãŒãƒã‚¤ãƒ•ãƒ³ã§çµ‚ã‚ã‚‹éš›ã®ãƒšãƒŠãƒ«ãƒ†ã‚£ã§ã™ã€‚
+% デフォルトã¯100ã§ã™ã€‚
+%
+% \begin{macrocode}
+% \brokenpenalty 100
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{ページレイアウト}
+%
+% \paragraph{縦方å‘ã®ã‚¹ãƒšãƒ¼ã‚¹}
+%
+% \begin{macro}{\headheight}
+% \begin{macro}{\topskip}
+%
+% |\topskip| ã¯æœ¬æ–‡é ˜åŸŸä¸Šç«¯ã¨æœ¬æ–‡1行目ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã¨ã®è·é›¢ã§ã™ã€‚
+% ã‚ã¾ã‚ŠãŽã‚ŠãŽã‚Šã®å€¤ã«ã™ã‚‹ã¨ï¼Œæœ¬æ–‡ä¸­ã« $\int$ ã®ã‚ˆã†ãªé«˜ã„文字ãŒ
+% å…¥ã£ãŸã¨ãã«1行目ã®ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ãŒä»–ã®ãƒšãƒ¼ã‚¸ã‚ˆã‚Šä¸‹ãŒã£ã¦ã—ã¾ã„ã¾ã™ã€‚
+% ã“ã“ã§ã¯æœ¬æ–‡ã®å…¬ç§°ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºï¼ˆ10pt)ã«ã—ã¾ã™ã€‚
+%
+% [2003-06-26] |\headheight| ã¯ãƒ˜ãƒƒãƒ€ã®é«˜ã•ã§ï¼Œ
+% å…ƒã¯12ptã§ã—ãŸãŒï¼Œæ–°ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚¯ãƒ©ã‚¹ã§ã¯ |\topskip|
+% ã¨ç­‰ã—ãã—ã¦ã„ã¾ã—ãŸã€‚ã¨ã“ã‚ãŒï¼Œ|fancyhdr| パッケージ
+% 㧠|\headheight| ãŒå°ã•ã„ã¨ãŠã‹ã—ã„ã“ã¨ã«ãªã‚‹ã‚ˆã†ã§ã™
+% ã®ã§ï¼Œ2å€ã«å¢—ã‚„ã—ã¾ã—ãŸã€‚代ã‚ã‚Šã«ï¼Œç‰ˆé¢ã®ä¸Šä¸‹æƒãˆã®
+% 計算ã§ã¯ |\headheight| ã§ã¯ãªã |\topskip| を使ã†
+% ã“ã¨ã«ã—ã¾ã—ãŸã€‚
+%
+% [2016-08-17] åœç‚¹ã‚„ルビãŒä¸€è¡Œç›®ã«æ¥ãŸå ´åˆã«ä¸‹ãŒã‚‹ã®ã‚’防ããŸ
+% ã‚,|\topskip| ã‚’10ptã‹ã‚‰1.38zwã«å¢—ã‚„ã—ã¾ã—ãŸã€‚
+% |\headheight| ã¯å¾“æ¥ã¨åŒã˜20ptã®ã¾ã¾ã¨ã—ã¾ã™ã€‚
+%
+% [2016-08-17 LTJ] 1.38zwã®ä»£ã‚ã‚Šã«1.38|\zh|ã«ã—ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\topskip{1.38\zh}%% from 10\jsc@mpt (2016-08-17)
+\if@slide
+ \setlength\headheight{0\jsc@mpt}
+\else
+ \setlength\headheight{20\jsc@mpt}%% from 2\topskip (2016-08-17); from \topskip (2003-06-26)
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\footskip}
+%
+% |\footskip| ã¯æœ¬æ–‡é ˜åŸŸä¸‹ç«¯ã¨ãƒ•ãƒƒã‚¿ä¸‹ç«¯ã¨ã®è·é›¢ã§ã™ã€‚
+% 標準クラスファイルã§ã¯ï¼Œbook ã§0.35in(約8.89mm),
+% book 以外ã§30pt(約10.54mm)ã¨ãªã£ã¦ã„ã¾ã—ãŸãŒï¼Œ
+% ã“ã“ã§ã¯A4判ã®ã¨ãã¡ã‚‡ã†ã©1cmã¨ãªã‚‹ã‚ˆã†ã«ï¼Œ
+% |\paperheight| ã®0.03367å€ï¼ˆæœ€å° |\baselineskip|)ã¨ã—ã¾ã—ãŸã€‚
+% 書ç±ã«ã¤ã„ã¦ã¯ï¼Œãƒ•ãƒƒã‚¿ã¯ä½¿ã‚ãªã„ã“ã¨ã«ã—ã¦ï¼Œã‚¼ãƒ­ã«ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+%<*article|kiyou>
+\if@slide
+ \setlength\footskip{\z@}
+\else
+ \setlength\footskip{0.03367\paperheight}
+ \ifdim\footskip<\baselineskip
+ \setlength\footskip{\baselineskip}
+ \fi
+\fi
+%</article|kiyou>
+%<jspf>\setlength\footskip{9\jsc@mmm}
+%<*book>
+\if@report
+ \setlength\footskip{0.03367\paperheight}
+ \ifdim\footskip<\baselineskip
+ \setlength\footskip{\baselineskip}
+ \fi
+\else
+ \setlength\footskip{\z@}
+\fi
+%</book>
+%<*report>
+\setlength\footskip{0.03367\paperheight}
+\ifdim\footskip<\baselineskip
+ \setlength\footskip{\baselineskip}
+\fi
+%</report>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\headsep}
+%
+% |\headsep| ã¯ãƒ˜ãƒƒãƒ€ä¸‹ç«¯ã¨æœ¬æ–‡é ˜åŸŸä¸Šç«¯ã¨ã®è·é›¢ã§ã™ã€‚
+% 元㯠book ã§18pt(約6.33mm),
+% ãれ以外ã§25pt(約8.79mm)ã«ãªã£ã¦ã„ã¾ã—ãŸã€‚
+% ã“ã“ã§ã¯ article 㯠|\footskip| $-$ |\topskip| ã¨ã—ã¾ã—ãŸã€‚
+%
+% [2016-10-08] article ã® \texttt{slide} ã®ã¨ã,
+% ãŠã‚ˆã³ book ã®éž \texttt{report} 㨠kiyou ã®ã¨ãã« |\headsep| ã‚’
+% 減らã—ãã“ã­ã¦ã„ãŸã®ã‚’修正ã—ã¾ã—ãŸï¼ˆ2016-08-17ã§ã®ä¿®æ­£æ¼ã‚Œï¼‰ã€‚
+%
+% \begin{macrocode}
+%<*article>
+\if@slide
+ \setlength\headsep{0\jsc@mpt}
+ \addtolength\headsep{-\topskip}%% added (2016-10-08)
+ \addtolength\headsep{10\jsc@mpt}%% added (2016-10-08)
+\else
+ \setlength\headsep{\footskip}
+ \addtolength\headsep{-\topskip}
+\fi
+%</article>
+%<*book>
+\if@report
+ \setlength\headsep{\footskip}
+ \addtolength\headsep{-\topskip}
+\else
+ \setlength\headsep{6\jsc@mmm}
+ \addtolength\headsep{-\topskip}%% added (2016-10-08)
+ \addtolength\headsep{10\jsc@mpt}%% added (2016-10-08)
+\fi
+%</book>
+%<*report>
+\setlength\headsep{\footskip}
+\addtolength\headsep{-\topskip}
+%</report>
+%<*jspf>
+\setlength\headsep{9\jsc@mmm}
+\addtolength\headsep{-\topskip}
+%</jspf>
+%<*kiyou>
+\setlength\headheight{0\jsc@mpt}
+\setlength\headsep{0\jsc@mpt}
+\addtolength\headsep{-\topskip}%% added (2016-10-08)
+\addtolength\headsep{10\jsc@mpt}%% added (2016-10-08)
+%</kiyou>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\maxdepth}
+%
+% |\maxdepth| ã¯æœ¬æ–‡æœ€ä¸‹è¡Œã®æœ€å¤§ã®æ·±ã•ã§ï¼Œ
+% plain \TeX ã‚„\LaTeX~2.09ã§ã¯4ptã«å›ºå®šã§ã—ãŸã€‚
+% \LaTeX2e ã§ã¯ |\maxdepth| $+$ |\topskip| を本文フォントサイズ
+% ã®1.5å€ã«ã—ãŸã„ã®ã§ã™ãŒï¼Œ|\topskip| ã¯æœ¬æ–‡ãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚º
+% (ã“ã“ã§ã¯10pt)ã«ç­‰ã—ã„ã®ã§ï¼Œçµå±€ |\maxdepth| 㯠|\topskip|
+% ã®åŠåˆ†ã®å€¤ï¼ˆå…·ä½“çš„ã«ã¯5pt)ã«ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\maxdepth{.5\topskip}
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{本文ã®å¹…ã¨é«˜ã•}
+%
+% \begin{macro}{\fullwidth}
+%
+% 本文ã®å¹…ãŒå…¨è§’40文字を超ãˆã‚‹ã¨èª­ã¿ã«ãããªã‚Šã¾ã™ã€‚
+% ãã“ã§ï¼Œæ›¸ç±ã®å ´åˆã«é™ã£ã¦ï¼Œ
+% ç´™ã®å¹…ãŒåºƒã„ã¨ãã¯å¤–å´ã®ãƒžãƒ¼ã‚¸ãƒ³ã‚’余分ã«ã¨ã£ã¦å…¨è§’40文字ã«æŠ¼ãˆï¼Œ
+% ヘッダやフッタã¯æœ¬æ–‡é ˜åŸŸã‚ˆã‚Šåºƒãå–ã‚‹ã“ã¨ã«ã—ã¾ã™ã€‚
+% ã“ã®ã¨ãヘッダやフッタã®å¹…を表㙠|\fullwidth| ã¨ã„ã†é•·ã•ã‚’定義ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\newdimen\fullwidth
+% \end{macrocode}
+%
+% ã“ã® |\fullwidth| 㯠article ã§ã¯ç´™å¹… |\paperwidth|ã®0.76å€ã‚’超ãˆãªã„
+% 全角幅ã®æ•´æ•°å€ï¼ˆäºŒæ®µçµ„ã§ã¯å…¨è§’å¹…ã®å¶æ•°å€ï¼‰ã«ã—ã¾ã™ã€‚0.76å€ã¨ã„ã†æ•°å€¤ã¯
+% A4縦置ãã®å ´åˆã«ç´™å¹…ã‹ã‚‰ç´„2インãƒã‚’引ã„ãŸå€¤ã«ãªã‚‹ã‚ˆã†ã«é¸ã³ã¾ã—ãŸã€‚
+% book ã§ã¯ç´™å¹…ã‹ã‚‰36ミリを引ã„ãŸå€¤ã«ã—ã¾ã—ãŸã€‚
+%
+% \begin{macro}{\textwidth}
+%
+% 書ç±ä»¥å¤–ã§ã¯æœ¬æ–‡é ˜åŸŸã®å¹… |\textwidth| 㯠|\fullwidth| ã¨ç­‰ã—ãã—ã¾ã™ã€‚
+% |article| ã§ã¯A4縦置ãã§49文字ã¨ãªã‚Šã¾ã™ã€‚
+% æŸå­¦ä¼šèªŒã‚¹ã‚¿ã‚¤ãƒ«ã§ã¯ |50\zw|(25文字×2段)+段間8\,mmã¨ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<*article>
+\if@slide
+ \setlength\fullwidth{0.9\paperwidth}
+\else
+ \setlength\fullwidth{0.76\paperwidth}
+\fi
+\if@twocolumn \@tempdima=2\zw \else \@tempdima=1\zw \fi
+\divide\fullwidth\@tempdima \multiply\fullwidth\@tempdima
+\setlength\textwidth{\fullwidth}
+%</article>
+%<*book>
+\if@report
+ \setlength\fullwidth{0.76\paperwidth}
+\else
+ \setlength\fullwidth{\paperwidth}
+ \addtolength\fullwidth{-36\jsc@mmm}
+\fi
+\if@twocolumn \@tempdima=2\zw \else \@tempdima=1\zw \fi
+\divide\fullwidth\@tempdima \multiply\fullwidth\@tempdima
+\setlength\textwidth{\fullwidth}
+\if@report \else
+ \if@twocolumn \else
+ \ifdim \fullwidth>40\zw
+ \setlength\textwidth{40\zw}
+ \fi
+ \fi
+\fi
+%</book>
+%<*report>
+\setlength\fullwidth{0.76\paperwidth}
+\if@twocolumn \@tempdima=2\zw \else \@tempdima=1\zw \fi
+\divide\fullwidth\@tempdima \multiply\fullwidth\@tempdima
+\setlength\textwidth{\fullwidth}
+%</report>
+%<*jspf>
+\setlength\fullwidth{50\zw}
+\addtolength\fullwidth{8\jsc@mmm}
+\setlength\textwidth{\fullwidth}
+%</jspf>
+%<*kiyou>
+\setlength\fullwidth{48\zw}
+\addtolength\fullwidth{\columnsep}
+\setlength\textwidth{\fullwidth}
+%</kiyou>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\textheight}
+%
+% ç´™ã®é«˜ã• |\paperheight| ã¯ï¼Œ1インãƒã¨ |\topmargin|
+% 㨠|\headheight| 㨠|\headsep| 㨠|\textheight|
+% 㨠|\footskip| ã¨ãƒšãƒ¼ã‚¸ä¸‹éƒ¨ã®ä½™ç™½ã‚’加ãˆãŸã‚‚ã®ã§ã™ã€‚
+%
+% 本文部分ã®é«˜ã• |\textheight| ã¯ï¼Œ
+% ç´™ã®é«˜ã• |\paperheight| ã®0.83å€ã‹ã‚‰ï¼Œ
+% ヘッダã®é«˜ã•ï¼Œãƒ˜ãƒƒãƒ€ã¨æœ¬æ–‡ã®è·é›¢ï¼Œæœ¬æ–‡ã¨ãƒ•ãƒƒã‚¿ä¸‹ç«¯ã®è·é›¢ï¼Œ
+% |\topskip| を引ã,
+% ãれを |\baselineskip| ã®å€æ•°ã«åˆ‡ã‚Šæ¨ã¦ï¼Œ
+% 最後㫠|\topskip| を加ãˆã¾ã™ã€‚
+% 念ã®ãŸã‚0.1ãƒã‚¤ãƒ³ãƒˆä½™åˆ†ã«åŠ ãˆã¦ãŠãã¾ã™ã€‚
+% 0.83å€ã¨ã„ã†æ•°å€¤ã¯ï¼ŒA4縦置ãã®å ´åˆã«ç´™ã®é«˜ã•ã‹ã‚‰
+% 上下マージンå„ç´„1インãƒã‚’引ã„ãŸå€¤ã«ãªã‚‹ã‚ˆã†ã«é¸ã³ã¾ã—ãŸã€‚
+%
+% æŸå­¦ä¼šèªŒã‚¹ã‚¿ã‚¤ãƒ«ã§ã¯44è¡Œã«ã—ã¾ã™ã€‚
+%
+% [2003-06-26] |\headheight| ã‚’ |\topskip| ã«ç›´ã—ã¾ã—ãŸã€‚
+% 以å‰ã¯ã“ã®äºŒã¤ã¯å€¤ãŒåŒã˜ã§ã‚ã£ãŸã®ã§ï¼Œå¤‰åŒ–ã¯ãªã„ã¯ãšã§ã™ã€‚
+%
+% [2016-08-26] |\topskip| ã‚’10ptã‹ã‚‰1.38zwã«å¢—ã‚„ã—ã¾ã—ãŸã®ã§ï¼Œ
+% ãã®åˆ† |\textheight| を増やã—ã¾ã™ï¼ˆ2016-08-17ã§ã®ä¿®æ­£æ¼ã‚Œï¼‰ã€‚
+%
+% [2016-10-08] article ã® slide ã®ã¨ãã« |\headheight| ã¯ã‚¼ãƒ­
+% ãªã®ã§ï¼Œã•ã‚‰ã«ä¿®æ­£ã—ã¾ã—ãŸï¼ˆ2016-08-17ã§ã®ä¿®æ­£æ¼ã‚Œï¼‰ã€‚
+%
+% \begin{macrocode}
+%<*article|book|report>
+\if@slide
+ \setlength{\textheight}{0.95\paperheight}
+\else
+ \setlength{\textheight}{0.83\paperheight}
+\fi
+\addtolength{\textheight}{-10\jsc@mpt}%% from -\topskip (2016-10-08); from -\headheight (2003-06-26)
+\addtolength{\textheight}{-\headsep}
+\addtolength{\textheight}{-\footskip}
+\addtolength{\textheight}{-\topskip}
+\divide\textheight\baselineskip
+\multiply\textheight\baselineskip
+%</article|book|report>
+%<jspf>\setlength{\textheight}{51\baselineskip}
+%<kiyou>\setlength{\textheight}{47\baselineskip}
+\addtolength{\textheight}{\topskip}
+\addtolength{\textheight}{0.1\jsc@mpt}
+%<jspf>\setlength{\mathindent}{10\jsc@mmm}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\flushbottom}
+%
+% [2016-07-18] |\textheight| ã«å¿µã®ãŸã‚0.1ãƒã‚¤ãƒ³ãƒˆä½™è£•ã‚’æŒãŸã›ã¦
+% ã„ã‚‹ã®ã¨åŒæ§˜ã«ï¼Œ|\flushbottom| ã«ã‚‚余裕をæŒãŸã›ã¾ã™ã€‚
+% å…ƒã®\LaTeXe ã§ã®å®Œå…¨ãª |\flushbottom| ã®å®šç¾©ã¯
+%\begin{verbatim}
+% \def\flushbottom{%
+% \let\@textbottom\relax \let\@texttop\relax}
+%\end{verbatim}
+% ã§ã™ãŒï¼Œæ¬¡ã®ã‚ˆã†ã«ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\def\flushbottom{%
+ \def\@textbottom{\vskip \z@ \@plus.1\jsc@mpt}%
+ \let\@texttop\relax}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\marginparsep}
+% \begin{macro}{\marginparpush}
+%
+% |\marginparsep| ã¯æ¬„外ã®æ›¸ãè¾¼ã¿ã¨æœ¬æ–‡ã¨ã®é–“éš”ã§ã™ã€‚
+% |\marginparpush| ã¯æ¬„外ã®æ›¸ãè¾¼ã¿ã©ã†ã—ã®æœ€å°ã®é–“éš”ã§ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\marginparsep{\columnsep}
+\setlength\marginparpush{\baselineskip}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\oddsidemargin}
+% \begin{macro}{\evensidemargin}
+%
+% ãã‚Œãžã‚Œå¥‡æ•°ãƒšãƒ¼ã‚¸ï¼Œå¶æ•°ãƒšãƒ¼ã‚¸ã®å·¦ãƒžãƒ¼ã‚¸ãƒ³ã‹ã‚‰1インãƒå¼•ã„ãŸå€¤ã§ã™ã€‚
+% 片é¢å°åˆ·ã§ã¯ |\oddsidemargin| ãŒä½¿ã‚ã‚Œã¾ã™ã€‚
+% \TeX ã¯ä¸Šãƒ»å·¦ãƒžãƒ¼ã‚¸ãƒ³ã« |1truein| を挿入ã—ã¾ã™ãŒï¼Œ
+% トンボ関係ã®ã‚ªãƒ—ションãŒæŒ‡å®šã•ã‚Œã‚‹ã¨ |lltjcore.sty|
+% ã¯ãƒˆãƒ³ãƒœã®å†…å´ã« |1in| ã®ã‚¹ãƒšãƒ¼ã‚¹ï¼ˆ|1truein| ã§ã¯ãªã)を挿入ã™ã‚‹ã®ã§ï¼Œ
+% å ´åˆåˆ†ã‘ã—ã¦ã„ã¾ã™ã€‚
+%
+% [2011-10-03 LTJ] Lua\TeX{} (pdf\TeX?) ã§ã¯ |1truein| ã§ã¯ãªã
+% |1in| ã«ãªã‚‹ã‚ˆã†ã§ã™ã€‚
+%
+% \begin{macrocode}
+\setlength{\oddsidemargin}{\paperwidth}
+\addtolength{\oddsidemargin}{-\fullwidth}
+\setlength{\oddsidemargin}{.5\oddsidemargin}
+\addtolength{\oddsidemargin}{-1in}
+\setlength{\evensidemargin}{\oddsidemargin}
+\if@mparswitch
+ \addtolength{\evensidemargin}{\fullwidth}
+ \addtolength{\evensidemargin}{-\textwidth}
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\marginparwidth}
+%
+% |\marginparwidth| ã¯æ¬„外ã®æ›¸ãè¾¼ã¿ã®æ¨ªå¹…ã§ã™ã€‚
+% 外å´ãƒžãƒ¼ã‚¸ãƒ³ã®å¹…(|\evensidemargin| $+$ 1インãƒï¼‰ã‹ã‚‰1センãƒã‚’引ã,
+% ã•ã‚‰ã« |\marginparsep|(欄外ã®æ›¸ãè¾¼ã¿ã¨æœ¬æ–‡ã®ã‚¢ã‚­ï¼‰ã‚’引ã„ãŸå€¤ã«
+% ã—ã¾ã—ãŸã€‚最後㫠|1\zw| ã®æ•´æ•°å€ã«åˆ‡ã‚Šæ¨ã¦ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\marginparwidth{\paperwidth}
+\addtolength\marginparwidth{-\oddsidemargin}
+\addtolength\marginparwidth{-1in}
+\addtolength\marginparwidth{-\textwidth}
+\addtolength\marginparwidth{-10\jsc@mmm}
+\addtolength\marginparwidth{-\marginparsep}
+\@tempdima=1\zw
+\divide\marginparwidth\@tempdima
+\multiply\marginparwidth\@tempdima
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\topmargin}
+%
+% 上マージン(紙ã®ä¸Šç«¯ã¨ãƒ˜ãƒƒãƒ€ä¸Šç«¯ã®è·é›¢ï¼‰
+% ã‹ã‚‰1インãƒå¼•ã„ãŸå€¤ã§ã™ã€‚
+%
+% [2003-06-26] |\headheight| ã‚’ |\topskip| ã«ç›´ã—ã¾ã—ãŸã€‚
+% 以å‰ã¯ã“ã®äºŒã¤ã¯å€¤ãŒåŒã˜ã§ã‚ã£ãŸã®ã§ï¼Œå¤‰åŒ–ã¯ãªã„ã¯ãšã§ã™ã€‚
+%
+% [2011-10-03 LTJ] ã“ã“ã‚‚ |\oddsidemargin| ã®ã¨ãã¨åŒæ§˜ã« |-\inv@mag in| ã§ã¯ãªã
+% |-1in| ã«ã—ã¾ã™ã€‚
+%
+% [2016-08-17] |\topskip| ã‚’10ptã‹ã‚‰1.38zwã«ç›´ã—ã¾ã—ãŸãŒï¼Œ
+% |\topmargin| ã¯å¾“æ¥ã®å€¤ã‹ã‚‰å¤‰ã‚らãªã„よã†ã«èª¿ç¯€ã—ã¾ã—ãŸã€‚
+% …ã®ã¤ã‚‚ã‚Šã§ã—ãŸãŒï¼Œ|\textheight| を増やã—忘れã¦ã„ãŸã®ã§
+% 変ã‚ã£ã¦ã—ã¾ã£ã¦ã„ã¾ã—ãŸï¼ˆ2016-08-26修正済ã¿ï¼‰ã€‚
+%
+% \begin{macrocode}
+\setlength\topmargin{\paperheight}
+\addtolength\topmargin{-\textheight}
+\if@slide
+ \addtolength\topmargin{-\headheight}
+\else
+ \addtolength\topmargin{-10\jsc@mpt}%% from -\topskip (2016-10-08); from -\headheight (2003-06-26)
+\fi
+\addtolength\topmargin{-\headsep}
+\addtolength\topmargin{-\footskip}
+\setlength\topmargin{0.5\topmargin}
+%<kiyou>\setlength\topmargin{81truebp}
+\addtolength\topmargin{-1in}
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{脚注}
+%
+% \begin{macro}{\footnotesep}
+%
+% å„脚注ã®é ­ã«å…¥ã‚‹æ”¯æŸ±ï¼ˆstrut)ã®é«˜ã•ã§ã™ã€‚
+% 脚注間ã«ä½™åˆ†ã®ã‚¢ã‚­ãŒå…¥ã‚‰ãªã„よã†ã«ï¼Œ
+% |\footnotesize| ã®æ”¯æŸ±ã®é«˜ã•ï¼ˆè¡Œé€ã‚Šã®0.7å€ï¼‰ã«ç­‰ã—ãã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+{\footnotesize\global\setlength\footnotesep{\baselineskip}}
+\setlength\footnotesep{0.7\footnotesep}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\footins}
+%
+% |\skip\footins| ã¯æœ¬æ–‡ã®æœ€çµ‚è¡Œã¨æœ€åˆã®è„šæ³¨ã¨ã®é–“ã®è·é›¢ã§ã™ã€‚
+% 標準ã®10ãƒã‚¤ãƒ³ãƒˆã‚¯ãƒ©ã‚¹ã§ã¯ 9 plus 4 minus 2 ãƒã‚¤ãƒ³ãƒˆã«ãªã£ã¦ã„ã¾ã™ãŒï¼Œ
+% 和文ã®è¡Œé€ã‚Šã‚’考ãˆã¦ã‚‚ã†ã¡ã‚‡ã£ã¨å¤§ããã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\setlength{\skip\footins}{16\jsc@mpt \@plus 5\jsc@mpt \@minus 2\jsc@mpt}
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{フロート関連}
+%
+% フロート(図,表)関連ã®ãƒ‘ラメータã¯\LaTeXe 本体ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ãŒï¼Œ
+% ã“ã“ã§è¨­å®šå¤‰æ›´ã—ã¾ã™ã€‚本文ページ(本文ã¨ãƒ•ãƒ­ãƒ¼ãƒˆãŒå…±å­˜ã™ã‚‹ãƒšãƒ¼ã‚¸ï¼‰
+% ã¨ãƒ•ãƒ­ãƒ¼ãƒˆã ã‘ã®ãƒšãƒ¼ã‚¸ã§è¨­å®šãŒç•°ãªã‚Šã¾ã™ã€‚
+% ã¡ãªã¿ã«ï¼Œã‚«ã‚¦ãƒ³ã‚¿ã¯å†…部ã§ã¯ |\c@| ã‚’åå‰ã«å† ã—ãŸãƒžã‚¯ãƒ­ã«ãªã£ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macro}{\c@topnumber}
+%
+% |topnumber| カウンタã¯æœ¬æ–‡ãƒšãƒ¼ã‚¸ä¸Šéƒ¨ã®ãƒ•ãƒ­ãƒ¼ãƒˆã®æœ€å¤§æ•°ã§ã™ã€‚
+%
+% [2003-08-23] ã¡ã‚‡ã£ã¨å¢—ã‚„ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\setcounter{topnumber}{9}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\topfraction}
+%
+% 本文ページ上部ã®ãƒ•ãƒ­ãƒ¼ãƒˆãŒå æœ‰ã§ãる最大ã®å‰²åˆã§ã™ã€‚
+% フロートãŒå…¥ã‚Šã‚„ã™ã„よã†ã«ï¼Œå…ƒã®å€¤ 0.7 ã‚’ 0.8 [2003-08-23: 0.85] ã«å¤‰ãˆã¦ã‚ã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+\renewcommand{\topfraction}{.85}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c@bottomnumber}
+%
+% |bottomnumber| カウンタã¯æœ¬æ–‡ãƒšãƒ¼ã‚¸ä¸‹éƒ¨ã®ãƒ•ãƒ­ãƒ¼ãƒˆã®æœ€å¤§æ•°ã§ã™ã€‚
+%
+% [2003-08-23] ã¡ã‚‡ã£ã¨å¢—ã‚„ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\setcounter{bottomnumber}{9}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\bottomfraction}
+%
+% 本文ページ下部ã®ãƒ•ãƒ­ãƒ¼ãƒˆãŒå æœ‰ã§ãる最大ã®å‰²åˆã§ã™ã€‚元㯠0.3 ã§ã—ãŸã€‚
+%
+% \begin{macrocode}
+\renewcommand{\bottomfraction}{.8}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c@totalnumber}
+%
+% |totalnumber| カウンタã¯æœ¬æ–‡ãƒšãƒ¼ã‚¸ã«å…¥ã‚Šã†ã‚‹ãƒ•ãƒ­ãƒ¼ãƒˆã®æœ€å¤§æ•°ã§ã™ã€‚
+%
+% [2003-08-23] ã¡ã‚‡ã£ã¨å¢—ã‚„ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\setcounter{totalnumber}{20}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\textfraction}
+%
+% 本文ページã«æœ€ä½Žé™å…¥ã‚‰ãªã‘ã‚Œã°ãªã‚‰ãªã„本文ã®å‰²åˆã§ã™ã€‚
+% フロートãŒå…¥ã‚Šã‚„ã™ã„よã†ã«å…ƒã® 0.2 ã‚’ 0.1 ã«å¤‰ãˆã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\renewcommand{\textfraction}{.1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\floatpagefraction}
+%
+% フロートã ã‘ã®ãƒšãƒ¼ã‚¸ã§ã®ãƒ•ãƒ­ãƒ¼ãƒˆã®æœ€å°å‰²åˆã§ã™ã€‚
+% ã“れも 0.5 ã‚’ 0.8 ã«å¤‰ãˆã¦ã‚ã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+\renewcommand{\floatpagefraction}{.8}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c@dbltopnumber}
+%
+% 二段組ã®ã¨ã本文ページ上部ã«å‡ºåŠ›ã§ãã‚‹
+% 段抜ãフロートã®æœ€å¤§æ•°ã§ã™ã€‚
+%
+% [2003-08-23] ã¡ã‚‡ã£ã¨å¢—ã‚„ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\setcounter{dbltopnumber}{9}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dbltopfraction}
+%
+% 二段組ã®ã¨ã本文ページ上部ã«å‡ºåŠ›ã§ãã‚‹
+% 段抜ãフロートãŒå ã‚ã†ã‚‹æœ€å¤§ã®å‰²åˆã§ã™ã€‚
+% 0.7 ã‚’ 0.8 ã«å¤‰ãˆã¦ã‚ã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+\renewcommand{\dbltopfraction}{.8}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dblfloatpagefraction}
+%
+% 二段組ã®ã¨ãフロートã ã‘ã®ãƒšãƒ¼ã‚¸ã«å…¥ã‚‹ã¹ã
+% 段抜ãフロートã®æœ€å°å‰²åˆã§ã™ã€‚
+% 0.5 ã‚’ 0.8 ã«å¤‰ãˆã¦ã‚ã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+\renewcommand{\dblfloatpagefraction}{.8}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\floatsep}
+% \begin{macro}{\textfloatsep}
+% \begin{macro}{\intextsep}
+%
+% |\floatsep| ã¯ãƒšãƒ¼ã‚¸ä¸Šéƒ¨ãƒ»ä¸‹éƒ¨ã®ãƒ•ãƒ­ãƒ¼ãƒˆé–“ã®è·é›¢ã§ã™ã€‚
+% |\textfloatsep| ã¯ãƒšãƒ¼ã‚¸ä¸Šéƒ¨ãƒ»ä¸‹éƒ¨ã®ãƒ•ãƒ­ãƒ¼ãƒˆã¨æœ¬æ–‡ã¨ã®è·é›¢ã§ã™ã€‚
+% |\intextsep| ã¯æœ¬æ–‡ã®é€”中ã«å‡ºåŠ›ã•ã‚Œã‚‹ãƒ•ãƒ­ãƒ¼ãƒˆã¨æœ¬æ–‡ã¨ã®è·é›¢ã§ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\floatsep {12\jsc@mpt \@plus 2\jsc@mpt \@minus 2\jsc@mpt}
+\setlength\textfloatsep{20\jsc@mpt \@plus 2\jsc@mpt \@minus 4\jsc@mpt}
+\setlength\intextsep {12\jsc@mpt \@plus 2\jsc@mpt \@minus 2\jsc@mpt}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dblfloatsep}
+% \begin{macro}{\dbltextfloatsep}
+%
+% 二段組ã®ã¨ãã®æ®µæŠœãã®ãƒ•ãƒ­ãƒ¼ãƒˆã«ã¤ã„ã¦ã®å€¤ã§ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\dblfloatsep {12\jsc@mpt \@plus 2\jsc@mpt \@minus 2\jsc@mpt}
+\setlength\dbltextfloatsep{20\jsc@mpt \@plus 2\jsc@mpt \@minus 4\jsc@mpt}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@fptop}
+% \begin{macro}{\@fpsep}
+% \begin{macro}{\@fpbot}
+%
+% フロートã ã‘ã®ãƒšãƒ¼ã‚¸ã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼ã§ã™ã€‚
+% |\@fptop| ã¯ãƒšãƒ¼ã‚¸ä¸Šéƒ¨ï¼Œ
+% |\@fpbot| ã¯ãƒšãƒ¼ã‚¸ä¸‹éƒ¨ï¼Œ
+% |\@fpsep| ã¯ãƒ•ãƒ­ãƒ¼ãƒˆé–“ã«å…¥ã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\@fptop{0\jsc@mpt \@plus 1fil}
+\setlength\@fpsep{8\jsc@mpt \@plus 2fil}
+\setlength\@fpbot{0\jsc@mpt \@plus 1fil}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@dblfptop}
+% \begin{macro}{\@dblfpsep}
+% \begin{macro}{\@dblfpbot}
+%
+% 段抜ãフロートã«ã¤ã„ã¦ã®å€¤ã§ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\@dblfptop{0\jsc@mpt \@plus 1fil}
+\setlength\@dblfpsep{8\jsc@mpt \@plus 2fil}
+\setlength\@dblfpbot{0\jsc@mpt \@plus 1fil}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \section{改ページ(日本語\TeX{}開発コミュニティ版ã®ã¿ï¼‰}\label{sec:cleardoublepage}
+%
+% \begin{macro}{\pltx@cleartorightpage}
+% \begin{macro}{\pltx@cleartoleftpage}
+% \begin{macro}{\pltx@cleartooddpage}
+% \begin{macro}{\pltx@cleartoevenpage}
+% [2017-02-24] コミュニティ版\pLaTeX ã®æ¨™æº–クラス2017/02/15ã«åˆã‚ã›ã¦ï¼Œ
+% åŒã˜å‘½ä»¤ã‚’追加ã—ã¾ã—ãŸã€‚
+% \begin{enumerate}
+% \item|\pltx@cleartorightpage|:å³ãƒšãƒ¼ã‚¸ã«ãªã‚‹ã¾ã§ãƒšãƒ¼ã‚¸ã‚’繰る命令
+% \item|\pltx@cleartoleftpage|:左ページã«ãªã‚‹ã¾ã§ãƒšãƒ¼ã‚¸ã‚’繰る命令
+% \item|\pltx@cleartooddpage|:奇数ページã«ãªã‚‹ã¾ã§ãƒšãƒ¼ã‚¸ã‚’繰る命令
+% \item|\pltx@cleartoevenpage|:å¶æ•°ãƒšãƒ¼ã‚¸ã«ãªã‚‹ã¾ã§ãƒšãƒ¼ã‚¸ã‚’繰る命令
+% \end{enumerate}
+% ã¨ãªã£ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<*article|book|report>
+\def\pltx@cleartorightpage{\clearpage\if@twoside
+ \unless\ifodd\numexpr\c@page+\ltjgetparameter{direction}\relax
+ \hbox{}\thispagestyle{empty}\newpage
+ \if@twocolumn\hbox{}\newpage\fi
+ \fi\fi}
+\def\pltx@cleartoleftpage{\clearpage\if@twoside
+ \ifodd\numexpr\c@page+\ltjgetparameter{direction}\relax
+ \hbox{}\thispagestyle{empty}\newpage
+ \if@twocolumn\hbox{}\newpage\fi
+ \fi\fi}
+\def\pltx@cleartooddpage{\clearpage\if@twoside
+ \ifodd\c@page\else
+ \hbox{}\thispagestyle{empty}\newpage
+ \if@twocolumn\hbox{}\newpage\fi
+ \fi\fi}
+\def\pltx@cleartoevenpage{\clearpage\if@twoside
+ \ifodd\c@page
+ \hbox{}\thispagestyle{empty}\newpage
+ \if@twocolumn\hbox{}\newpage\fi
+ \fi\fi}
+%</article|book|report>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cleardoublepage}
+% [2017-02-24] コミュニティ版\pLaTeX ã®æ¨™æº–クラス2017/02/15ã«åˆã‚ã›ã¦ï¼Œ
+% reportã¨bookクラスã®å ´åˆã«|\cleardoublepage|ã‚’å†å®šç¾©ã—ã¾ã™ã€‚
+% \begin{macrocode}
+%<*book|report>
+\if@openleft
+ \let\cleardoublepage\pltx@cleartoleftpage
+\else\if@openright
+ \let\cleardoublepage\pltx@cleartorightpage
+\fi\fi
+%</book|report>
+% \end{macrocode}
+% \end{macro}
+%
+% \section{ページスタイル}\label{sec:pagestyle}
+%
+% ページスタイルã¨ã—ã¦ï¼Œ\LaTeXe (欧文版)ã®æ¨™æº–クラス
+% ã§ã¯ |empty|,|plain|,|headings|,|myheadings| ãŒã‚ã‚Šã¾ã™ã€‚
+% ã“ã®ã†ã¡ |empty|,|plain| スタイルã¯\LaTeXe 本体
+% ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+%
+% アスキーã®ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã§ã¯ |headnombre|,|footnombre|,
+% |bothstyle|,|jpl@in| ãŒè¿½åŠ ã•ã‚Œã¦ã„ã¾ã™ãŒï¼Œ
+% ã“ã“ã§ã¯æ¬§æ–‡æ¨™æº–ã®ã‚‚ã®ã ã‘ã«ã—ã¾ã—ãŸã€‚
+%
+% ページスタイル㯠|\ps@...| ã®å½¢ã®ãƒžã‚¯ãƒ­ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+%
+% \begin{macro}{\@evenhead}
+% \begin{macro}{\@oddhead}
+% \begin{macro}{\@evenfoot}
+% \begin{macro}{\@oddfoot}
+%
+% |\@oddhead|,|\@oddfoot|,|\@evenhead|,|\@evenfoot| ã¯
+% å¶æ•°ãƒ»å¥‡æ•°ãƒšãƒ¼ã‚¸ã®æŸ±ï¼ˆãƒ˜ãƒƒãƒ€ï¼Œãƒ•ãƒƒã‚¿ï¼‰ã‚’出力ã™ã‚‹å‘½ä»¤ã§ã™ã€‚
+% ã“れら㯠|\fullwidth| å¹…ã® |\hbox| ã®ä¸­ã§å‘¼ã³å‡ºã•ã‚Œã¾ã™ã€‚
+% |\ps@...| ã®ä¸­ã§å®šç¾©ã—ã¦ãŠãã¾ã™ã€‚
+%
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% 柱ã®å†…容ã¯ï¼Œ|\chapter| ãŒå‘¼ã³å‡ºã™ |\chaptermark{何々}|,
+% |\section| ãŒå‘¼ã³å‡ºã™ |\sectionmark{何々}| ã§è¨­å®šã—ã¾ã™ã€‚
+% 柱を扱ã†å‘½ä»¤ã«ã¯æ¬¡ã®ã‚‚ã®ãŒã‚ã‚Šã¾ã™ã€‚
+%
+% \begin{quote}
+% \begin{tabbing}
+% |\markboth{å·¦}{å³} | \= 両方ã®æŸ±ã‚’設定ã—ã¾ã™ã€‚\\
+% |\markright{å³}| \> å³ã®æŸ±ã‚’設定ã—ã¾ã™ã€‚\\
+% |\leftmark| \> å·¦ã®æŸ±ã‚’出力ã—ã¾ã™ã€‚\\
+% |\rightmark| \> å³ã®æŸ±ã‚’出力ã—ã¾ã™ã€‚
+% \end{tabbing}
+% \end{quote}
+%
+% 柱を設定ã™ã‚‹å‘½ä»¤ã¯ï¼Œå³ã®æŸ±ãŒå·¦ã®æŸ±ã®ä¸‹ä½ã«ã‚ã‚‹å ´åˆã¯å分ã¾ã¨ã‚‚ã«
+% 動作ã—ã¾ã™ã€‚ãŸã¨ãˆã°å·¦ãƒžãƒ¼ã‚¯ã‚’ |\chapter|,å³ãƒžãƒ¼ã‚¯ã‚’ |\section|
+% ã§å¤‰æ›´ã™ã‚‹å ´åˆãŒã“ã‚Œã«ã‚ãŸã‚Šã¾ã™ã€‚
+% ã—ã‹ã—,åŒä¸€ãƒšãƒ¼ã‚¸ã«è¤‡æ•°ã® |\markboth| ãŒã‚ã‚‹ã¨ï¼Œ
+% ãŠã‹ã—ãªçµæžœã«ãªã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚
+%
+% |\tableofcontents| ã®ã‚ˆã†ãªå‘½ä»¤ã§ä½¿ã‚れる |\@mkboth| ã¯ï¼Œ
+% |\ps@...| コマンド中㧠|\markboth| ã‹ |\@gobbletwo|(何もã—ãªã„)
+% ã« |\let| ã•ã‚Œã¾ã™ã€‚
+%
+% \begin{macro}{\ps@empty}
+%
+% |empty| ページスタイルã®å®šç¾©ã§ã™ã€‚
+% \LaTeX 本体ã§å®šç¾©ã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã‚’コメントアウトã—ãŸå½¢ã§
+% 載ã›ã¦ãŠãã¾ã™ã€‚
+%
+% \begin{macrocode}
+% \def\ps@empty{%
+% \let\@mkboth\@gobbletwo
+% \let\@oddhead\@empty
+% \let\@oddfoot\@empty
+% \let\@evenhead\@empty
+% \let\@evenfoot\@empty}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ps@plainhead}
+% \begin{macro}{\ps@plainfoot}
+% \begin{macro}{\ps@plain}
+%
+% |plainhead| ã¯ã‚·ãƒ³ãƒ—ルãªãƒ˜ãƒƒãƒ€ã ã‘ã®ãƒšãƒ¼ã‚¸ã‚¹ã‚¿ã‚¤ãƒ«ã§ã™ã€‚
+%
+% |plainfoot| ã¯ã‚·ãƒ³ãƒ—ルãªãƒ•ãƒƒã‚¿ã ã‘ã®ãƒšãƒ¼ã‚¸ã‚¹ã‚¿ã‚¤ãƒ«ã§ã™ã€‚
+%
+% |plain| 㯠|book| ã§ã¯ |plainhead|,ãれ以外ã§ã¯ |plainfoot| ã«ãªã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+\def\ps@plainfoot{%
+ \let\@mkboth\@gobbletwo
+ \let\@oddhead\@empty
+ \def\@oddfoot{\normalfont\hfil\thepage\hfil}%
+ \let\@evenhead\@empty
+ \let\@evenfoot\@oddfoot}
+\def\ps@plainhead{%
+ \let\@mkboth\@gobbletwo
+ \let\@oddfoot\@empty
+ \let\@evenfoot\@empty
+ \def\@evenhead{%
+ \if@mparswitch \hss \fi
+ \hbox to \fullwidth{\textbf{\thepage}\hfil}%
+ \if@mparswitch\else \hss \fi}%
+ \def\@oddhead{%
+ \hbox to \fullwidth{\hfil\textbf{\thepage}}\hss}}
+%<book>\if@report \let\ps@plain\ps@plainfoot \else \let\ps@plain\ps@plainhead \fi
+%<!book>\let\ps@plain\ps@plainfoot
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ps@headings}
+%
+% |headings| スタイルã¯ãƒ˜ãƒƒãƒ€ã«è¦‹å‡ºã—ã¨ãƒšãƒ¼ã‚¸ç•ªå·ã‚’出力ã—ã¾ã™ã€‚
+% ã“ã“ã§ã¯ãƒ˜ãƒƒãƒ€ã«ã‚¢ãƒ³ãƒ€ãƒ¼ãƒ©ã‚¤ãƒ³ã‚’引ãよã†ã«ã—ã¦ã¿ã¾ã—ãŸã€‚
+%
+% ã¾ãš article ã®å ´åˆã§ã™ã€‚
+%
+% \begin{macrocode}
+%<*article|kiyou>
+\if@twoside
+ \def\ps@headings{%
+ \let\@oddfoot\@empty
+ \let\@evenfoot\@empty
+ \def\@evenhead{\if@mparswitch \hss \fi
+ \underline{\hbox to \fullwidth{\textbf{\thepage}\hfil\leftmark}}%
+ \if@mparswitch\else \hss \fi}%
+ \def\@oddhead{%
+ \underline{%
+ \hbox to \fullwidth{{\rightmark}\hfil\textbf{\thepage}}}\hss}%
+ \let\@mkboth\markboth
+ \def\sectionmark##1{\markboth{%
+ \ifnum \c@secnumdepth >\z@ \thesection \hskip1\zw\fi
+ ##1}{}}%
+ \def\subsectionmark##1{\markright{%
+ \ifnum \c@secnumdepth >\@ne \thesubsection \hskip1\zw\fi
+ ##1}}%
+ }
+\else % if not twoside
+ \def\ps@headings{%
+ \let\@oddfoot\@empty
+ \def\@oddhead{%
+ \underline{%
+ \hbox to \fullwidth{{\rightmark}\hfil\textbf{\thepage}}}\hss}%
+ \let\@mkboth\markboth
+ \def\sectionmark##1{\markright{%
+ \ifnum \c@secnumdepth >\z@ \thesection \hskip1\zw\fi
+ ##1}}}
+\fi
+%</article|kiyou>
+% \end{macrocode}
+%
+% 次㯠book ãŠã‚ˆã³ report ã®å ´åˆã§ã™ã€‚
+% [2011-05-10] ã—ã£ã½æ„›å¥½å®¶ã•ã‚“ [qa:6370] ã®ãƒ‘ッãƒã‚’å–ã‚Šè¾¼ã¾ã›ã¦ã„ãŸã ãã¾ã—ãŸ
+% (北見ã•ã‚“ [qa:55896] ã®ã”指摘ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ï¼‰ã€‚
+%
+% \begin{macrocode}
+%<*book|report>
+\newif\if@omit@number
+\def\ps@headings{%
+ \let\@oddfoot\@empty
+ \let\@evenfoot\@empty
+ \def\@evenhead{%
+ \if@mparswitch \hss \fi
+ \underline{\hbox to \fullwidth{\ltjsetparameter{autoxspacing={true}}
+ \textbf{\thepage}\hfil\leftmark}}%
+ \if@mparswitch\else \hss \fi}%
+ \def\@oddhead{\underline{\hbox to \fullwidth{\ltjsetparameter{autoxspacing={true}}
+ {\if@twoside\rightmark\else\leftmark\fi}\hfil\textbf{\thepage}}}\hss}%
+ \let\@mkboth\markboth
+ \def\chaptermark##1{\markboth{%
+ \ifnum \c@secnumdepth >\m@ne
+%<book> \if@mainmatter
+ \if@omit@number\else
+ \@chapapp\thechapter\@chappos\hskip1\zw
+ \fi
+%<book> \fi
+ \fi
+ ##1}{}}%
+ \def\sectionmark##1{\markright{%
+ \ifnum \c@secnumdepth >\z@ \thesection \hskip1\zw\fi
+ ##1}}}%
+%</book|report>
+% \end{macrocode}
+%
+% 最後ã¯å­¦ä¼šèªŒã®å ´åˆã§ã™ã€‚
+%
+% \begin{macrocode}
+%<*jspf>
+\def\ps@headings{%
+ \def\@oddfoot{\normalfont\hfil\thepage\hfil}
+ \def\@evenfoot{\normalfont\hfil\thepage\hfil}
+ \def\@oddhead{\normalfont\hfil \@title \hfil}
+ \def\@evenhead{\normalfont\hfil プラズマ・核èžåˆå­¦ä¼šèªŒ\hfil}}
+%</jspf>
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\ps@myheadings}
+%
+% |myheadings| ページスタイルã§ã¯ãƒ¦ãƒ¼ã‚¶ãŒ |\markboth| ã‚„ |\markright| ã§
+% 柱を設定ã™ã‚‹ãŸã‚,ã“ã“ã§ã®å®šç¾©ã¯éžå¸¸ã«ç°¡å˜ã§ã™ã€‚
+%
+% [2004-01-17] 渡辺徹ã•ã‚“ã®ãƒ‘ッãƒã‚’é©ç”¨ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\def\ps@myheadings{%
+ \let\@oddfoot\@empty\let\@evenfoot\@empty
+ \def\@evenhead{%
+ \if@mparswitch \hss \fi%
+ \hbox to \fullwidth{\thepage\hfil\leftmark}%
+ \if@mparswitch\else \hss \fi}%
+ \def\@oddhead{%
+ \hbox to \fullwidth{\rightmark\hfil\thepage}\hss}%
+ \let\@mkboth\@gobbletwo
+%<book|report> \let\chaptermark\@gobble
+ \let\sectionmark\@gobble
+%<!book&!report> \let\subsectionmark\@gobble
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \section{文書ã®ãƒžãƒ¼ã‚¯ã‚¢ãƒƒãƒ—}
+%
+% \subsection{表題}
+%
+% \begin{macro}{\title}
+% \begin{macro}{\author}
+% \begin{macro}{\date}
+%
+% ã“れらã¯\LaTeX 本体ã§æ¬¡ã®ã‚ˆã†ã«å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+% ã“ã“ã§ã¯ã‚³ãƒ¡ãƒ³ãƒˆã‚¢ã‚¦ãƒˆã—ãŸå½¢ã§ç¤ºã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+% \newcommand*{\title}[1]{\gdef\@title{#1}}
+% \newcommand*{\author}[1]{\gdef\@author{#1}}
+% \newcommand*{\date}[1]{\gdef\@date{#1}}
+% \date{\today}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\etitle}
+% \begin{macro}{\eauthor}
+% \begin{macro}{\keywords}
+%
+% æŸå­¦ä¼šèªŒã‚¹ã‚¿ã‚¤ãƒ«ã§ä½¿ã†è‹±èªžã®ã‚¿ã‚¤ãƒˆãƒ«ï¼Œè‹±èªžã®è‘—者å,キーワード,メールアドレスã§ã™ã€‚
+%
+% \begin{macrocode}
+%<*jspf>
+\newcommand*{\etitle}[1]{\gdef\@etitle{#1}}
+\newcommand*{\eauthor}[1]{\gdef\@eauthor{#1}}
+\newcommand*{\keywords}[1]{\gdef\@keywords{#1}}
+\newcommand*{\email}[1]{\gdef\authors@mail{#1}}
+\newcommand*{\AuthorsEmail}[1]{\gdef\authors@mail{author's e-mail:\ #1}}
+%</jspf>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\plainifnotempty}
+%
+% 従æ¥ã®æ¨™æº–クラスã§ã¯ï¼Œæ–‡æ›¸å…¨ä½“ã®ãƒšãƒ¼ã‚¸ã‚¹ã‚¿ã‚¤ãƒ«ã‚’ |empty| ã«
+% ã—ã¦ã‚‚表題ã®ã‚るページã ã‘ |plain| ã«ãªã£ã¦ã—ã¾ã†ã“ã¨ãŒ
+% ã‚ã‚Šã¾ã—ãŸã€‚ã“れ㯠|\maketitle| ã®å®šç¾©ä¸­
+% ã« |\thispagestyle|\hspace{0pt}|{plain}| ãŒå…¥ã£ã¦ã„ã‚‹
+% ãŸã‚ã§ã™ã€‚ã“ã®å•é¡Œã‚’解決ã™ã‚‹ãŸã‚ã«ï¼Œ
+% 「全体ã®ãƒšãƒ¼ã‚¸ã‚¹ã‚¿ã‚¤ãƒ«ãŒ |empty| ã§ãªã„ãªã‚‰
+% ã“ã®ãƒšãƒ¼ã‚¸ã®ã‚¹ã‚¿ã‚¤ãƒ«ã‚’ |plain| ã«ã™ã‚‹ã€ã¨ã„ã†æ¬¡ã®
+% 命令を作るã“ã¨ã«ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\def\plainifnotempty{%
+ \ifx \@oddhead \@empty
+ \ifx \@oddfoot \@empty
+ \else
+ \thispagestyle{plainfoot}%
+ \fi
+ \else
+ \thispagestyle{plainhead}%
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\maketitle}
+%
+% 表題を出力ã—ã¾ã™ã€‚
+% 著者åを出力ã™ã‚‹éƒ¨åˆ†ã¯ï¼Œæ¬§æ–‡ã®æ¨™æº–クラスファイルã§ã¯ |\large|,
+% 和文ã®ã‚‚ã®ã§ã¯ |\Large| ã«ãªã£ã¦ã„ã¾ã—ãŸãŒï¼Œã“ã“ã§ã¯ |\large|
+% ã«ã—ã¾ã—ãŸã€‚
+%
+% [2016-11-16] スペーシングを元㮠|jsclasses| ã«åˆã‚ã›ã‚‹ãŸã‚,|\smallskip| ã‚’
+% |\jsc@smallskip| ã«ç½®ãæ›ãˆã¾ã—ãŸã€‚|\smallskip| ã®ã¾ã¾ã§ã¯
+% \texttt{nomag(*)} ã®å ´åˆã«ã‚¹ã‚±ãƒ¼ãƒ«ã—ãªããªã‚Šï¼Œãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆãŒå¤‰ã‚ã£ã¦ã—ã¾ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<*article|book|report|kiyou>
+\if@titlepage
+ \newcommand{\maketitle}{%
+ \begin{titlepage}%
+ \let\footnotesize\small
+ \let\footnoterule\relax
+ \let\footnote\thanks
+ \null\vfil
+ \if@slide
+ {\footnotesize \@date}%
+ \begin{center}
+ \mbox{} \\[1\zw]
+ \large
+ {\maybeblue\hrule height0\jsc@mpt depth2\jsc@mpt\relax}\par
+ \jsc@smallskip
+ \@title
+ \jsc@smallskip
+ {\maybeblue\hrule height0\jsc@mpt depth2\jsc@mpt\relax}\par
+ \vfill
+ {\small \@author}%
+ \end{center}
+ \else
+ \vskip 60\jsc@mpt
+ \begin{center}%
+ {\LARGE \@title \par}%
+ \vskip 3em%
+ {\large
+ \lineskip .75em
+ \begin{tabular}[t]{c}%
+ \@author
+ \end{tabular}\par}%
+ \vskip 1.5em
+ {\large \@date \par}%
+ \end{center}%
+ \fi
+ \par
+ \@thanks\vfil\null
+ \end{titlepage}%
+ \setcounter{footnote}{0}%
+ \global\let\thanks\relax
+ \global\let\maketitle\relax
+ \global\let\@thanks\@empty
+ \global\let\@author\@empty
+ \global\let\@date\@empty
+ \global\let\@title\@empty
+ \global\let\title\relax
+ \global\let\author\relax
+ \global\let\date\relax
+ \global\let\and\relax
+ }%
+\else
+ \newcommand{\maketitle}{\par
+ \begingroup
+ \renewcommand\thefootnote{\@fnsymbol\c@footnote}%
+ \def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}%
+ \long\def\@makefntext##1{\advance\leftskip 3\zw
+ \parindent 1\zw\noindent
+ \llap{\@textsuperscript{\normalfont\@thefnmark}\hskip0.3\zw}##1}%
+ \if@twocolumn
+ \ifnum \col@number=\@ne
+ \@maketitle
+ \else
+ \twocolumn[\@maketitle]%
+ \fi
+ \else
+ \newpage
+ \global\@topnum\z@ % Prevents figures from going at top of page.
+ \@maketitle
+ \fi
+ \plainifnotempty
+ \@thanks
+ \endgroup
+ \setcounter{footnote}{0}%
+ \global\let\thanks\relax
+ \global\let\maketitle\relax
+ \global\let\@thanks\@empty
+ \global\let\@author\@empty
+ \global\let\@date\@empty
+ \global\let\@title\@empty
+ \global\let\title\relax
+ \global\let\author\relax
+ \global\let\date\relax
+ \global\let\and\relax
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@maketitle}
+%
+% 独立ã—ãŸè¡¨é¡Œãƒšãƒ¼ã‚¸ã‚’作らãªã„å ´åˆã®è¡¨é¡Œã®å‡ºåŠ›å½¢å¼ã§ã™ã€‚
+%
+% \begin{macrocode}
+ \def\@maketitle{%
+ \newpage\null
+ \vskip 2em
+ \begin{center}%
+ \let\footnote\thanks
+ {\LARGE \@title \par}%
+ \vskip 1.5em
+ {\large
+ \lineskip .5em
+ \begin{tabular}[t]{c}%
+ \@author
+ \end{tabular}\par}%
+ \vskip 1em
+ {\large \@date}%
+ \end{center}%
+ \par\vskip 1.5em
+%<article|report|kiyou> \ifvoid\@abstractbox\else\centerline{\box\@abstractbox}\vskip1.5em\fi
+ }
+\fi
+%</article|book|report|kiyou>
+%<*jspf>
+\newcommand{\maketitle}{\par
+ \begingroup
+ \renewcommand\thefootnote{\@fnsymbol\c@footnote}%
+ \def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}%
+ \long\def\@makefntext##1{\advance\leftskip 3\zw
+ \parindent 1\zw\noindent
+ \llap{\@textsuperscript{\normalfont\@thefnmark}\hskip0.3\zw}##1}%
+ \twocolumn[\@maketitle]%
+ \plainifnotempty
+ \@thanks
+ \endgroup
+ \setcounter{footnote}{0}%
+ \global\let\thanks\relax
+ \global\let\maketitle\relax
+ \global\let\@thanks\@empty
+ \global\let\@author\@empty
+ \global\let\@date\@empty
+% \global\let\@title\@empty % \@title ã¯æŸ±ã«ä½¿ã†
+ \global\let\title\relax
+ \global\let\author\relax
+ \global\let\date\relax
+ \global\let\and\relax
+ \ifx\authors@mail\@undefined\else{%
+ \def\@makefntext{\advance\leftskip 3\zw \parindent -3\zw}%
+ \footnotetext[0]{\itshape\authors@mail}%
+ }\fi
+ \global\let\authors@mail\@undefined}
+\def\@maketitle{%
+ \newpage\null
+ \vskip 6em % used to be 2em
+ \begin{center}
+ \let\footnote\thanks
+ \ifx\@title\@undefined\else{\LARGE\headfont\@title\par}\fi
+ \lineskip .5em
+ \ifx\@author\@undefined\else
+ \vskip 1em
+ \begin{tabular}[t]{c}%
+ \@author
+ \end{tabular}\par
+ \fi
+ \ifx\@etitle\@undefined\else
+ \vskip 1em
+ {\large \@etitle \par}%
+ \fi
+ \ifx\@eauthor\@undefined\else
+ \vskip 1em
+ \begin{tabular}[t]{c}%
+ \@eauthor
+ \end{tabular}\par
+ \fi
+ \vskip 1em
+ \@date
+ \end{center}
+ \vskip 1.5em
+ \centerline{\box\@abstractbox}
+ \ifx\@keywords\@undefined\else
+ \vskip 1.5em
+ \centerline{\parbox{157\jsc@mmm}{\textsf{Keywords:}\\ \small\@keywords}}
+ \fi
+ \vskip 1.5em}
+%</jspf>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{章・節}
+%
+% \paragraph{構æˆè¦ç´ }
+%
+% |\@startsection| マクロã¯6個ã®å¿…須引数ã¨ï¼Œã‚ªãƒ—ションã¨ã—㦠|*| ã¨
+% 1個ã®ã‚ªãƒ—ション引数ã¨1個ã®å¿…須引数をã¨ã‚Šã¾ã™ã€‚
+%
+% \begin{quote}
+% |\@startsection{å}{レベル}{字下ã’}{å‰ã‚¢ã‚­}{後アキ}{スタイル}| \\
+% | *[別見出ã—]{見出ã—}|
+% \end{quote}
+%
+% ãã‚Œãžã‚Œã®å¼•æ•°ã®æ„味ã¯æ¬¡ã®é€šã‚Šã§ã™ã€‚
+%
+% \begin{description}
+% \item[å] ユーザレベルコマンドã®åå‰ã§ã™ï¼ˆä¾‹: section)。
+% \item[レベル] 見出ã—ã®æ·±ã•ã‚’示ã™æ•°å€¤ã§ã™
+% (chapter=1, section=2, \ldots )。
+% ã“ã®æ•°å€¤ãŒ |secnumdepth| 以下ã®ã¨ã見出ã—番å·ã‚’出力ã—ã¾ã™ã€‚
+% \item[字下ã’] 見出ã—ã®å­—下ã’é‡ã§ã™ã€‚
+% \item[å‰ã‚¢ã‚­] ã“ã®å€¤ã®çµ¶å¯¾å€¤ãŒè¦‹å‡ºã—上å´ã®ç©ºãã§ã™ã€‚
+% è² ã®å ´åˆã¯ï¼Œè¦‹å‡ºã—直後ã®æ®µè½ã‚’インデントã—ã¾ã›ã‚“。
+% \item[後アキ] æ­£ã®å ´åˆã¯ï¼Œè¦‹å‡ºã—ã®ä¸‹ã®ç©ºãã§ã™ã€‚
+% è² ã®å ´åˆã¯ï¼Œçµ¶å¯¾å€¤ãŒè¦‹å‡ºã—ã®å³ã®ç©ºãã§ã™
+% (見出ã—ã¨åŒã˜è¡Œã‹ã‚‰æœ¬æ–‡ã‚’始ã‚ã¾ã™ï¼‰ã€‚
+% \item[スタイル] 見出ã—ã®æ–‡å­—スタイルã®è¨­å®šã§ã™ã€‚
+% \item[\texttt{*}] ã“ã® \texttt{*} å°ãŒãªã„ã¨ï¼Œè¦‹å‡ºã—番å·ã‚’付ã‘,
+% 見出ã—番å·ã®ã‚«ã‚¦ãƒ³ã‚¿ã«1を加算ã—ã¾ã™ã€‚
+% \item[別見出ã—] 目次や柱ã«å‡ºåŠ›ã™ã‚‹è¦‹å‡ºã—ã§ã™ã€‚
+% \item[見出ã—] 見出ã—ã§ã™ã€‚
+% \end{description}
+%
+% 見出ã—ã®å‘½ä»¤ã¯é€šå¸¸ |\@startsection| ã¨ãã®æœ€åˆã®6個ã®å¼•æ•°ã¨ã—ã¦
+% 定義ã•ã‚Œã¾ã™ã€‚
+%
+% 次㯠|\@startsection| ã®å®šç¾©ã§ã™ã€‚
+% 情報処ç†å­¦ä¼šè«–文誌スタイルファイル(\texttt{ipsjcommon.sty})
+% ã‚’å‚考ã«ã•ã›ã¦ã„ãŸã ãã¾ã—ãŸãŒï¼Œå®Œå…¨ã«è¡Œé€ã‚ŠãŒ |\baselineskip|
+% ã®æ•´æ•°å€ã«ãªã‚‰ãªãã¦ã‚‚ã„ã„ã‹ã‚‰å‰ã®è¡Œã¨é‡ãªã‚‰ãªã„よã†ã«ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\def\@startsection#1#2#3#4#5#6{%
+ \if@noskipsec \leavevmode \fi
+ \par
+% 見出ã—上ã®ç©ºãã‚’ \@tempskipa ã«ã‚»ãƒƒãƒˆã™ã‚‹
+ \@tempskipa #4\relax
+% \@afterindent ã¯è¦‹å‡ºã—直後ã®æ®µè½ã‚’字下ã’ã™ã‚‹ã‹ã©ã†ã‹ã‚’表ã™ã‚¹ã‚¤ãƒƒãƒ
+ \if@english \@afterindentfalse \else \@afterindenttrue \fi
+% 見出ã—上ã®ç©ºããŒè² ãªã‚‰è¦‹å‡ºã—直後ã®æ®µè½ã‚’字下ã’ã—ãªã„
+ \ifdim \@tempskipa <\z@
+ \@tempskipa -\@tempskipa \@afterindentfalse
+ \fi
+ \if@nobreak
+ \everypar{}%
+ \else
+ \addpenalty\@secpenalty
+% 次ã®è¡Œã¯å‰Šé™¤
+% \addvspace\@tempskipa
+% 次㮠\noindent ã¾ã§è¿½åŠ 
+ \ifdim \@tempskipa >\z@
+ \if@slide\else
+ \null
+ \vspace*{-\baselineskip}%
+ \fi
+ \vskip\@tempskipa
+ \fi
+ \fi
+ \noindent
+% 追加終ã‚ã‚Š
+ \@ifstar
+ {\@ssect{#3}{#4}{#5}{#6}}%
+ {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}}
+% \end{macrocode}
+%
+% |\@sect| 㨠|\@xsect| ã¯ï¼Œ
+% å‰ã®ã‚¢ã‚­ãŒã¡ã‚‡ã†ã©ã‚¼ãƒ­ã®å ´åˆã«ã‚‚ã†ã¾ãã„ãよã†ã«ï¼Œå¤šå°‘変ãˆã¦ã‚ã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+\def\@sect#1#2#3#4#5#6[#7]#8{%
+ \ifnum #2>\c@secnumdepth
+ \let\@svsec\@empty
+ \else
+ \refstepcounter{#1}%
+ \protected@edef\@svsec{\@seccntformat{#1}\relax}%
+ \fi
+% 見出ã—後ã®ç©ºãã‚’ \@tempskipa ã«ã‚»ãƒƒãƒˆ
+ \@tempskipa #5\relax
+% æ¡ä»¶åˆ¤æ–­ã®é †åºã‚’入れæ›ãˆã¾ã—ãŸ
+ \ifdim \@tempskipa<\z@
+ \def\@svsechd{%
+ #6{\hskip #3\relax
+ \@svsec #8}%
+ \csname #1mark\endcsname{#7}%
+ \addcontentsline{toc}{#1}{%
+ \ifnum #2>\c@secnumdepth \else
+ \protect\numberline{\csname the#1\endcsname}%
+ \fi
+ #7}}% 目次ã«ãƒ•ãƒ«ãƒãƒ¼ãƒ ã‚’載ã›ã‚‹ãªã‚‰ #8
+ \else
+ \begingroup
+ \interlinepenalty \@M % 下ã‹ã‚‰ç§»å‹•
+ #6{%
+ \@hangfrom{\hskip #3\relax\@svsec}%
+% \interlinepenalty \@M % 上ã«ç§»å‹•
+ #8\@@par}%
+ \endgroup
+ \csname #1mark\endcsname{#7}%
+ \addcontentsline{toc}{#1}{%
+ \ifnum #2>\c@secnumdepth \else
+ \protect\numberline{\csname the#1\endcsname}%
+ \fi
+ #7}% 目次ã«ãƒ•ãƒ«ãƒãƒ¼ãƒ ã‚’載ã›ã‚‹ãªã‚‰ã“ã“㯠#8
+ \fi
+ \@xsect{#5}}
+% \end{macrocode}
+%
+% 二ã¤æŒ¿å…¥ã—㟠|\everyparhook| ã®ã†ã¡å¾Œè€…㌠|\paragraph| é¡žã®å¾Œã§2回実行ã•ã‚Œï¼Œ
+% ãれ以é™ã¯å‰è€…ãŒå®Ÿè¡Œã•ã‚Œã¾ã™ã€‚
+%
+% [2011-10-05 LTJ] Lua\TeX-jaã§ã¯ |\everyparhook| ã¯ä¸è¦ãªã®ã§å‰Šé™¤ã€‚
+%
+% [2016-07-28] \texttt{slide}オプションã¨\texttt{twocolumn}オプションを
+% åŒæ™‚ã«æŒ‡å®šã—ãŸå ´åˆã®ç½«ç·šã®ä½ç½®ã‚’微調整ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\def\@xsect#1{%
+% 見出ã—ã®å¾Œã‚ã®ç©ºãã‚’ \@tempskipa ã«ã‚»ãƒƒãƒˆ
+ \@tempskipa #1\relax
+% æ¡ä»¶åˆ¤æ–­ã®é †åºã‚’変ãˆã¾ã—ãŸ
+ \ifdim \@tempskipa<\z@
+ \@nobreakfalse
+ \global\@noskipsectrue
+ \everypar{%
+ \if@noskipsec
+ \global\@noskipsecfalse
+ {\setbox\z@\lastbox}%
+ \clubpenalty\@M
+ \begingroup \@svsechd \endgroup
+ \unskip
+ \@tempskipa #1\relax
+ \hskip -\@tempskipa\ltjfakeparbegin
+ \else
+ \clubpenalty \@clubpenalty
+ \everypar{}%
+ \fi}%
+ \else
+ \par \nobreak
+ \vskip \@tempskipa
+ \@afterheading
+ \fi
+ \if@slide
+ {\vskip\if@twocolumn-5\jsc@mpt\else-6\jsc@mpt\fi
+ \maybeblue\hrule height0\jsc@mpt depth1\jsc@mpt
+ \vskip\if@twocolumn 4\jsc@mpt\else 7\jsc@mpt\fi\relax}%
+ \fi
+ \par % 2000-12-18
+ \ignorespaces}
+\def\@ssect#1#2#3#4#5{%
+ \@tempskipa #3\relax
+ \ifdim \@tempskipa<\z@
+ \def\@svsechd{#4{\hskip #1\relax #5}}%
+ \else
+ \begingroup
+ #4{%
+ \@hangfrom{\hskip #1}%
+ \interlinepenalty \@M #5\@@par}%
+ \endgroup
+ \fi
+ \@xsect{#3}}
+% \end{macrocode}
+%
+% \paragraph{柱関係ã®å‘½ä»¤}
+%
+% \begin{macro}{\chaptermark}
+% \begin{macro}{\sectionmark}
+% \begin{macro}{\subsectionmark}
+% \begin{macro}{\subsubsectionmark}
+% \begin{macro}{\paragraphmark}
+% \begin{macro}{\subparagraphmark}
+%
+% |\...mark| ã®å½¢ã®å‘½ä»¤ã‚’åˆæœŸåŒ–ã—ã¾ã™ï¼ˆç¬¬\ref{sec:pagestyle}節å‚照)。
+% |\chaptermark| 以外ã¯\LaTeX 本体ã§å®šç¾©æ¸ˆã¿ã§ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand*\chaptermark[1]{}
+% \newcommand*{\sectionmark}[1]{}
+% \newcommand*{\subsectionmark}[1]{}
+% \newcommand*{\subsubsectionmark}[1]{}
+% \newcommand*{\paragraphmark}[1]{}
+% \newcommand*{\subparagraphmark}[1]{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \paragraph{カウンタã®å®šç¾©}
+%
+% \begin{macro}{\c@secnumdepth}
+%
+% |secnumdepth| ã¯ç¬¬ä½•ãƒ¬ãƒ™ãƒ«ã®è¦‹å‡ºã—ã¾ã§
+% 番å·ã‚’付ã‘ã‚‹ã‹ã‚’決ã‚るカウンタã§ã™ã€‚
+%
+% \begin{macrocode}
+%<!book&!report>\setcounter{secnumdepth}{3}
+%<book|report>\setcounter{secnumdepth}{2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c@chapter}
+% \begin{macro}{\c@section}
+% \begin{macro}{\c@subsection}
+% \begin{macro}{\c@subsubsection}
+% \begin{macro}{\c@paragraph}
+% \begin{macro}{\c@subparagraph}
+%
+% 見出ã—番å·ã®ã‚«ã‚¦ãƒ³ã‚¿ã§ã™ã€‚
+% |\newcounter| ã®ç¬¬1引数ãŒæ–°ãŸã«ä½œã‚‹ã‚«ã‚¦ãƒ³ã‚¿ã§ã™ã€‚
+% ã“ã‚Œã¯ç¬¬2引数ãŒå¢—加ã™ã‚‹ãŸã³ã« 0 ã«æˆ»ã•ã‚Œã¾ã™ã€‚
+% 第2引数ã¯å®šç¾©æ¸ˆã¿ã®ã‚«ã‚¦ãƒ³ã‚¿ã§ã™ã€‚
+%
+% \begin{macrocode}
+\newcounter{part}
+%<book|report>\newcounter{chapter}
+%<book|report>\newcounter{section}[chapter]
+%<!book&!report>\newcounter{section}
+\newcounter{subsection}[section]
+\newcounter{subsubsection}[subsection]
+\newcounter{paragraph}[subsubsection]
+\newcounter{subparagraph}[paragraph]
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\thepart}
+% \begin{macro}{\thechapter}
+% \begin{macro}{\thesection}
+% \begin{macro}{\thesubsection}
+% \begin{macro}{\thesubsubsection}
+% \begin{macro}{\theparagraph}
+% \begin{macro}{\thesubparagraph}
+%
+% カウンタã®å€¤ã‚’出力ã™ã‚‹å‘½ä»¤ |\the何々| を定義ã—ã¾ã™ã€‚
+%
+% カウンタを出力ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã«ã¯æ¬¡ã®ã‚‚ã®ãŒã‚ã‚Šã¾ã™ã€‚
+%
+% \begin{quote}
+% |\arabic{COUNTER} | 1, 2, 3, \ldots \\
+% |\roman{COUNTER} | i, ii, iii, \ldots \\
+% |\Roman{COUNTER} | I, II, III, \ldots \\
+% |\alph{COUNTER} | a, b, c, \ldots \\
+% |\Alph{COUNTER} | A, B, C, \ldots \\
+% |\kansuji{COUNTER} | 一, 二, 三, \ldots
+% \end{quote}
+%
+% 以下ã§ã¯ã‚¹ãƒšãƒ¼ã‚¹ç¯€ç´„ã®ãŸã‚ |@| ã®ä»˜ã„ãŸå†…部表ç¾ã‚’多用ã—ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\renewcommand{\thepart}{\@Roman\c@part}
+%<!book&!report>% \renewcommand{\thesection}{\@arabic\c@section}
+%<!book&!report>\renewcommand{\thesection}{\presectionname\@arabic\c@section\postsectionname}
+%<!book&!report>\renewcommand{\thesubsection}{\@arabic\c@section.\@arabic\c@subsection}
+%<*book|report>
+\renewcommand{\thechapter}{\@arabic\c@chapter}
+\renewcommand{\thesection}{\thechapter.\@arabic\c@section}
+\renewcommand{\thesubsection}{\thesection.\@arabic\c@subsection}
+%</book|report>
+\renewcommand{\thesubsubsection}{%
+ \thesubsection.\@arabic\c@subsubsection}
+\renewcommand{\theparagraph}{%
+ \thesubsubsection.\@arabic\c@paragraph}
+\renewcommand{\thesubparagraph}{%
+ \theparagraph.\@arabic\c@subparagraph}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@chapapp}
+% \begin{macro}{\@chappos}
+%
+% |\@chapapp| ã®åˆæœŸå€¤ã¯ |\prechaptername|(第)ã§ã™ã€‚
+%
+% |\@chappos| ã®åˆæœŸå€¤ã¯ |\postchaptername|(章)ã§ã™ã€‚
+%
+% |\appendix| 㯠|\@chapapp| ã‚’ |\appendixname| ã«ï¼Œ
+% |\@chappos| を空ã«å†å®šç¾©ã—ã¾ã™ã€‚
+%
+% [2003-03-02] |\@secapp| ã¯å¤–ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+%<book|report>\newcommand{\@chapapp}{\prechaptername}
+%<book|report>\newcommand{\@chappos}{\postchaptername}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \paragraph{å‰ä»˜ï¼Œæœ¬æ–‡ï¼Œå¾Œä»˜}
+%
+% 本ã®ã†ã¡ç« ç•ªå·ãŒã‚ã‚‹ã®ãŒã€Œæœ¬æ–‡ã€ï¼Œ
+% ãれ以外ãŒã€Œå‰ä»˜ã€ã€Œå¾Œä»˜ã€ã§ã™ã€‚
+%
+% \begin{macro}{\frontmatter}
+%
+% ページ番å·ã‚’ローマ数字ã«ã—,章番å·ã‚’付ã‘ãªã„よã†ã«ã—ã¾ã™ã€‚
+%
+% [2017-03-05] |\frontmatter| 㨠|\mainmatter| ã®2ã¤ã®å‘½ä»¤ã¯ï¼Œ
+% 改ä¸ã¾ãŸã¯æ”¹ãƒšãƒ¼ã‚¸ã—ãŸå¾Œã§ |\pagenumbering{...}| ã§ãƒŽãƒ³ãƒ–ルを1ã«
+% リセットã—ã¾ã™ã€‚é•·ã„é–“ |\frontmatter| 㯠\texttt{openany} ã®ã¨ãã«
+% å˜ãªã‚‹æ”¹ãƒšãƒ¼ã‚¸ã¨ã—ã¦ã„ã¾ã—ãŸãŒï¼Œã“ã‚Œã§ã¯ãƒŽãƒ³ãƒ–ルをリセットã™ã‚‹éš›ã«
+% å¶å¥‡é€†è»¢ãŒèµ·ã“ã‚‹å ´åˆãŒã‚ã‚Šã¾ã—ãŸã€‚\texttt{openany} ã‹ã©ã†ã‹ã«ä¾ã‚‰ãš
+% 奇数ページã¾ã§ç¹°ã‚‹ã‚ˆã†ã«ä¿®æ­£ã™ã‚‹ã“ã¨ã§ï¼Œå•é¡Œã‚’解消ã—ã¾ã—ãŸã€‚
+% 実ã¯ï¼Œ\LaTeX ã®æ¨™æº–クラスã§ã¯1998å¹´ã«ä¿®æ­£ã•ã‚Œã¦ã„ãŸå•é¡Œã§ã™
+% (コミュニティ版\pLaTeX ã®æ¨™æº–クラス2017/03/05ã‚‚å‚照)。
+%
+% \begin{macrocode}
+%<*book>
+\newcommand\frontmatter{%
+ \pltx@cleartooddpage
+ \@mainmatterfalse
+ \pagenumbering{roman}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mainmatter}
+%
+% ページ番å·ã‚’算用数字ã«ã—,章番å·ã‚’付ã‘るよã†ã«ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand\mainmatter{%
+ \pltx@cleartooddpage
+ \@mainmattertrue
+ \pagenumbering{arabic}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\backmatter}
+%
+% 章番å·ã‚’付ã‘ãªã„よã†ã«ã—ã¾ã™ã€‚ページ番å·ã®ä»˜ã‘æ–¹ã¯å¤‰ã‚ã‚Šã¾ã›ã‚“。
+%
+% \begin{macrocode}
+\newcommand\backmatter{%
+ \if@openleft
+ \cleardoublepage
+ \else\if@openright
+ \cleardoublepage
+ \else
+ \clearpage
+ \fi\fi
+ \@mainmatterfalse}
+%</book>
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{部}
+%
+% \begin{macro}{\part}
+%
+% æ–°ã—ã„部を始ã‚ã¾ã™ã€‚
+%
+% |\secdef| を使ã£ã¦è¦‹å‡ºã—を定義ã—ã¦ã„ã¾ã™ã€‚
+% ã“ã®ãƒžã‚¯ãƒ­ã¯äºŒã¤ã®å¼•æ•°ã‚’ã¨ã‚Šã¾ã™ã€‚
+%
+% \begin{quote}
+% |\secdef{星ãªã—}{星ã‚ã‚Š}|
+% \end{quote}
+%
+% \begin{description}
+% \item[星ãªã—] \texttt{*} ã®ãªã„å½¢ã®å®šç¾©ã§ã™ã€‚
+% \item[星ã‚ã‚Š] \texttt{*} ã®ã‚ã‚‹å½¢ã®å®šç¾©ã§ã™ã€‚
+% \end{description}
+%
+% |\secdef| ã¯æ¬¡ã®ã‚ˆã†ã«ã—ã¦ä½¿ã„ã¾ã™ã€‚
+%
+%\begin{verbatim}
+% \def\chapter { ... \secdef \CMDA \CMDB }
+% \def\CMDA [#1]#2{....} % \chapter[...]{...} ã®å®šç¾©
+% \def\CMDB #1{....} % \chapter*{...} ã®å®šç¾©
+%\end{verbatim}
+%
+% ã¾ãš |book| 㨠|report| ã®ã‚¯ãƒ©ã‚¹ä»¥å¤–ã§ã™ã€‚
+%
+% \begin{macrocode}
+%<*!book&!report>
+\newcommand\part{%
+ \if@noskipsec \leavevmode \fi
+ \par
+ \addvspace{4ex}%
+ \if@english \@afterindentfalse \else \@afterindenttrue \fi
+ \secdef\@part\@spart}
+%</!book&!report>
+% \end{macrocode}
+%
+% |book| ãŠã‚ˆã³ |report| クラスã®å ´åˆã¯ï¼Œå°‘ã—複雑ã§ã™ã€‚
+%
+% \begin{macrocode}
+%<*book|report>
+\newcommand\part{%
+ \if@openleft
+ \cleardoublepage
+ \else\if@openright
+ \cleardoublepage
+ \else
+ \clearpage
+ \fi\fi
+ \thispagestyle{empty}% 欧文用標準スタイルã§ã¯ plain
+ \if@twocolumn
+ \onecolumn
+ \@restonecoltrue
+ \else
+ \@restonecolfalse
+ \fi
+ \null\vfil
+ \secdef\@part\@spart}
+%</book|report>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@part}
+%
+% 部ã®è¦‹å‡ºã—を出力ã—ã¾ã™ã€‚
+% |\bfseries| ã‚’ |\headfont| ã«å¤‰ãˆã¾ã—ãŸã€‚
+%
+% |book| ãŠã‚ˆã³ |report| クラス以外ã§ã¯ |secnumdepth| ㌠$-1$ より大ãã„ã¨ã
+% 部番å·ã‚’付ã‘ã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<*!book&!report>
+\def\@part[#1]#2{%
+ \ifnum \c@secnumdepth >\m@ne
+ \refstepcounter{part}%
+ \addcontentsline{toc}{part}{%
+ \prepartname\thepart\postpartname\hspace{1\zw}#1}%
+ \else
+ \addcontentsline{toc}{part}{#1}%
+ \fi
+ \markboth{}{}%
+ {\parindent\z@
+ \raggedright
+ \interlinepenalty \@M
+ \normalfont
+ \ifnum \c@secnumdepth >\m@ne
+ \Large\headfont\prepartname\thepart\postpartname
+ \par\nobreak
+ \fi
+ \huge \headfont #2%
+ \markboth{}{}\par}%
+ \nobreak
+ \vskip 3ex
+ \@afterheading}
+%</!book&!report>
+% \end{macrocode}
+%
+% |book| ãŠã‚ˆã³ |report| クラスã§ã¯ |secnumdepth| ㌠$-2$ より大ãã„ã¨ã部番å·ã‚’付ã‘ã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<*book|report>
+\def\@part[#1]#2{%
+ \ifnum \c@secnumdepth >-2\relax
+ \refstepcounter{part}%
+ \addcontentsline{toc}{part}{%
+ \prepartname\thepart\postpartname\hspace{1\zw}#1}%
+ \else
+ \addcontentsline{toc}{part}{#1}%
+ \fi
+ \markboth{}{}%
+ {\centering
+ \interlinepenalty \@M
+ \normalfont
+ \ifnum \c@secnumdepth >-2\relax
+ \huge\headfont \prepartname\thepart\postpartname
+ \par\vskip20\jsc@mpt
+ \fi
+ \Huge \headfont #2\par}%
+ \@endpart}
+%</book|report>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@spart}
+%
+% 番å·ã‚’付ã‘ãªã„部ã§ã™ã€‚
+%
+% \begin{macrocode}
+%<*!book&!report>
+\def\@spart#1{{%
+ \parindent \z@ \raggedright
+ \interlinepenalty \@M
+ \normalfont
+ \huge \headfont #1\par}%
+ \nobreak
+ \vskip 3ex
+ \@afterheading}
+%</!book&!report>
+%<*book|report>
+\def\@spart#1{{%
+ \centering
+ \interlinepenalty \@M
+ \normalfont
+ \Huge \headfont #1\par}%
+ \@endpart}
+%</book|report>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@endpart}
+%
+% |\@part| 㨠|\@spart| ã®æœ€å¾Œã§å®Ÿè¡Œã•ã‚Œã‚‹ãƒžã‚¯ãƒ­ã§ã™ã€‚
+% 両é¢å°åˆ·ã®ã¨ãã¯ç™½ãƒšãƒ¼ã‚¸ã‚’追加ã—ã¾ã™ã€‚
+% 二段組ã®ã¨ãã«ã¯ï¼ŒäºŒæ®µçµ„ã«æˆ»ã—ã¾ã™ã€‚
+%
+% [2016-12-13] \texttt{openany} ã®ã¨ãã«ã¯ç™½ãƒšãƒ¼ã‚¸ãŒè¿½åŠ ã•ã‚Œã‚‹ã®ã¯å¤‰ãªã®ã§ï¼Œ
+% ãã®å ´åˆã¯è¿½åŠ ã—ãªã„よã†ã«ã—ã¾ã—ãŸã€‚ã“ã®ãƒã‚°ã¯\LaTeX ã§ã¯
+% classes.dtx v1.4b (2000/05/19)
+% ã§ä¿®æ­£ã•ã‚Œã¦ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<*book|report>
+\def\@endpart{\vfil\newpage
+ \if@twoside
+ \if@openleft %% added (2017/02/24)
+ \null\thispagestyle{empty}\newpage
+ \else\if@openright %% added (2016/12/13)
+ \null\thispagestyle{empty}\newpage
+ \fi\fi %% added (2016/12/13, 2017/02/24)
+ \fi
+ \if@restonecol
+ \twocolumn
+ \fi}
+%</book|report>
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{ç« }
+%
+% \begin{macro}{\chapter}
+%
+% ç« ã®æœ€åˆã®ãƒšãƒ¼ã‚¸ã‚¹ã‚¿ã‚¤ãƒ«ã¯ï¼Œå…¨ä½“㌠|empty| ã§ãªã‘れ㰠|plain| ã«
+% ã—ã¾ã™ã€‚
+% ã¾ãŸï¼Œ|\@topnum| ã‚’ 0 ã«ã—ã¦ï¼Œ
+% 章見出ã—ã®ä¸Šã«å›³ã‚„表ãŒæ¥ãªã„よã†ã«ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<*book|report>
+\newcommand{\chapter}{%
+ \if@openleft\cleardoublepage\else
+ \if@openright\cleardoublepage\else\clearpage\fi\fi
+ \plainifnotempty % å…ƒ: \thispagestyle{plain}
+ \global\@topnum\z@
+ \if@english \@afterindentfalse \else \@afterindenttrue \fi
+ \secdef
+ {\@omit@numberfalse\@chapter}%
+ {\@omit@numbertrue\@schapter}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@chapter}
+%
+% 章見出ã—を出力ã—ã¾ã™ã€‚
+% |secnumdepth| ãŒ0以上ã‹ã¤ |\@mainmatter| ãŒçœŸã®ã¨ã章番å·ã‚’出力ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\def\@chapter[#1]#2{%
+ \ifnum \c@secnumdepth >\m@ne
+%<book> \if@mainmatter
+ \refstepcounter{chapter}%
+ \typeout{\@chapapp\thechapter\@chappos}%
+ \addcontentsline{toc}{chapter}%
+ {\protect\numberline
+ % {\if@english\thechapter\else\@chapapp\thechapter\@chappos\fi}%
+ {\@chapapp\thechapter\@chappos}%
+ #1}%
+%<book> \else\addcontentsline{toc}{chapter}{#1}\fi
+ \else
+ \addcontentsline{toc}{chapter}{#1}%
+ \fi
+ \chaptermark{#1}%
+ \addtocontents{lof}{\protect\addvspace{10\jsc@mpt}}%
+ \addtocontents{lot}{\protect\addvspace{10\jsc@mpt}}%
+ \if@twocolumn
+ \@topnewpage[\@makechapterhead{#2}]%
+ \else
+ \@makechapterhead{#2}%
+ \@afterheading
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@makechapterhead}
+%
+% 実際ã«ç« è¦‹å‡ºã—を組ã¿ç«‹ã¦ã¾ã™ã€‚
+% |\bfseries| ã‚’ |\headfont| ã«å¤‰ãˆã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\def\@makechapterhead#1{%
+ \vspace*{2\Cvs}% 欧文ã¯50pt
+ {\parindent \z@ \raggedright \normalfont
+ \ifnum \c@secnumdepth >\m@ne
+%<book> \if@mainmatter
+ \huge\headfont \@chapapp\thechapter\@chappos
+ \par\nobreak
+ \vskip \Cvs % 欧文ã¯20pt
+%<book> \fi
+ \fi
+ \interlinepenalty\@M
+ \Huge \headfont #1\par\nobreak
+ \vskip 3\Cvs}} % 欧文ã¯40pt
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@schapter}
+%
+% |\chapter*{...}| コマンドã®æœ¬ä½“ã§ã™ã€‚
+% |\chaptermark| を補ã„ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\def\@schapter#1{%
+ \chaptermark{#1}%
+ \if@twocolumn
+ \@topnewpage[\@makeschapterhead{#1}]%
+ \else
+ \@makeschapterhead{#1}\@afterheading
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@makeschapterhead}
+%
+% 番å·ãªã—ã®ç« è¦‹å‡ºã—ã§ã™ã€‚
+%
+% \begin{macrocode}
+\def\@makeschapterhead#1{%
+ \vspace*{2\Cvs}% 欧文ã¯50pt
+ {\parindent \z@ \raggedright
+ \normalfont
+ \interlinepenalty\@M
+ \Huge \headfont #1\par\nobreak
+ \vskip 3\Cvs}} % 欧文ã¯40pt
+%</book|report>
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{下ä½ãƒ¬ãƒ™ãƒ«ã®è¦‹å‡ºã—}
+%
+% \begin{macro}{\section}
+%
+% 欧文版ã§ã¯ |\@startsection| ã®ç¬¬4引数を負ã«ã—ã¦æœ€åˆã®æ®µè½ã®
+% 字下ã’ã‚’ç¦æ­¢ã—ã¦ã„ã¾ã™ãŒï¼Œ
+% 和文版ã§ã¯æ­£ã«ã—ã¦å­—下ã’ã™ã‚‹ã‚ˆã†ã«ã—ã¦ã„ã¾ã™ã€‚
+%
+% 段組ã®ã¨ãã¯ãªã‚‹ã¹ãå·¦å³ã®æ®µãŒç‹‚ã‚ãªã„よã†ã«å·¥å¤«ã—ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\if@twocolumn
+ \newcommand{\section}{%
+%<jspf>\ifx\maketitle\relax\else\maketitle\fi
+ \@startsection{section}{1}{\z@}%
+%<!kiyou> {0.6\Cvs}{0.4\Cvs}%
+%<kiyou> {\Cvs}{0.5\Cvs}%
+% {\normalfont\large\headfont\@secapp}}
+ {\normalfont\large\headfont\raggedright}}
+\else
+ \newcommand{\section}{%
+ \if@slide\clearpage\fi
+ \@startsection{section}{1}{\z@}%
+ {\Cvs \@plus.5\Cdp \@minus.2\Cdp}% å‰ã‚¢ã‚­
+ {.5\Cvs \@plus.3\Cdp}% 後アキ
+% {\normalfont\Large\headfont\@secapp}}
+ {\normalfont\Large\headfont\raggedright}}
+\fi
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\subsection}
+%
+% åŒä¸Šã§ã™ã€‚
+%
+% \begin{macrocode}
+\if@twocolumn
+ \newcommand{\subsection}{\@startsection{subsection}{2}{\z@}%
+ {\z@}{\if@slide .4\Cvs \else \z@ \fi}%
+ {\normalfont\normalsize\headfont}}
+\else
+ \newcommand{\subsection}{\@startsection{subsection}{2}{\z@}%
+ {\Cvs \@plus.5\Cdp \@minus.2\Cdp}% å‰ã‚¢ã‚­
+ {.5\Cvs \@plus.3\Cdp}% 後アキ
+ {\normalfont\large\headfont}}
+\fi
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\subsubsection}
+%
+% [2016-07-22] \texttt{slide}オプション指定時㫠|\subsubsection| ã®æ–‡å­—列
+% ã¨ç½«ç·šãŒé‡ãªã‚‹å•é¡Œã«å¯¾å‡¦ã—ã¾ã—ãŸ(forum:1982)。
+%
+% \begin{macrocode}
+\if@twocolumn
+ \newcommand{\subsubsection}{\@startsection{subsubsection}{3}{\z@}%
+ {\z@}{\if@slide .4\Cvs \else \z@ \fi}%
+ {\normalfont\normalsize\headfont}}
+\else
+ \newcommand{\subsubsection}{\@startsection{subsubsection}{3}{\z@}%
+ {\Cvs \@plus.5\Cdp \@minus.2\Cdp}%
+ {\if@slide .5\Cvs \@plus.3\Cdp \else \z@ \fi}%
+ {\normalfont\normalsize\headfont}}
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\paragraph}
+% \begin{macro}{\jsParagraphMark}
+%
+% 見出ã—ã®å¾Œã‚ã§æ”¹è¡Œã•ã‚Œã¾ã›ã‚“。
+%
+% [2016-11-16] 従æ¥ã¯ |\paragraph| ã®æœ€åˆã«å‡ºã‚‹ãƒžãƒ¼ã‚¯ã‚’「■ã€ã«å›ºå®šã—ã¦
+% ã„ã¾ã—ãŸãŒï¼Œã“ã®ãƒžãƒ¼ã‚¯ã‚’変更å¯èƒ½ã«ã™ã‚‹ãŸã‚ |\jsParagraphMark| ã¨ã„ã†ãƒžã‚¯ãƒ­
+% ã«åˆ‡ã‚Šå‡ºã—ã¾ã—ãŸã€‚ã“ã‚Œã§ï¼ŒãŸã¨ãˆã°
+%\begin{verbatim}
+% \renewcommand{\jsParagraphMark}{★}
+%\end{verbatim}
+% ã¨ã™ã‚Œã°ã€Œâ˜…ã€ã«å¤‰æ›´ã§ãã¾ã™ã—,マークを空ã«ã™ã‚‹ã“ã¨ã‚‚容易ã§ã™ã€‚
+% ãªãŠï¼ŒæŸå­¦ä¼šã‚¯ãƒ©ã‚¹ã§ã¯å¾“æ¥ã©ãŠã‚Šãƒžãƒ¼ã‚¯ã¯ä»˜ãã¾ã›ã‚“。
+%
+% \begin{macrocode}
+%<!jspf>\newcommand{\jsParagraphMark}{â– }
+\if@twocolumn
+ \newcommand{\paragraph}{\@startsection{paragraph}{4}{\z@}%
+ {\z@}{\if@slide .4\Cvs \else -1\zw\fi}% 改行ã›ãš 1\zw ã®ã‚¢ã‚­
+%<jspf> {\normalfont\normalsize\headfont}}
+%<!jspf> {\normalfont\normalsize\headfont\jsParagraphMark}}
+\else
+ \newcommand{\paragraph}{\@startsection{paragraph}{4}{\z@}%
+ {0.5\Cvs \@plus.5\Cdp \@minus.2\Cdp}%
+ {\if@slide .5\Cvs \@plus.3\Cdp \else -1\zw\fi}% 改行ã›ãš 1\zw ã®ã‚¢ã‚­
+%<jspf> {\normalfont\normalsize\headfont}}
+%<!jspf> {\normalfont\normalsize\headfont\jsParagraphMark}}
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\subparagraph}
+%
+% 見出ã—ã®å¾Œã‚ã§æ”¹è¡Œã•ã‚Œã¾ã›ã‚“。
+%
+% \begin{macrocode}
+\if@twocolumn
+ \newcommand{\subparagraph}{\@startsection{subparagraph}{5}{\z@}%
+ {\z@}{\if@slide .4\Cvs \@plus.3\Cdp \else -1\zw\fi}%
+ {\normalfont\normalsize\headfont}}
+\else
+ \newcommand{\subparagraph}{\@startsection{subparagraph}{5}{\z@}%
+ {\z@}{\if@slide .5\Cvs \@plus.3\Cdp \else -1\zw\fi}%
+ {\normalfont\normalsize\headfont}}
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{リスト環境}
+%
+% 第 $k$ レベルã®ãƒªã‚¹ãƒˆã®åˆæœŸåŒ–ã‚’ã™ã‚‹ã®ãŒ |\@list|$k$ ã§ã™
+% ($k = \mathtt{i}, \mathtt{ii}, \mathtt{iii}, \mathtt{iv}$)。
+% |\@list|$k$ 㯠|\leftmargin| ã‚’ |\leftmargin|$k$ ã«è¨­å®šã—ã¾ã™ã€‚
+%
+% \begin{macro}{\leftmargini}
+%
+% 二段組ã§ã‚ã‚‹ã‹ãªã„ã‹ã«å¿œã˜ã¦ãã‚Œãžã‚Œ 2em,2.5em ã§ã—ãŸãŒï¼Œ
+% ã“ã“ã§ã¯å…¨è§’å¹…ã®2å€ã«ã—ã¾ã—ãŸã€‚
+%
+% [2002-05-11] |3\zw| ã«å¤‰æ›´ã—ã¾ã—ãŸã€‚
+%
+% [2005-03-19] 二段組㯠|2\zw| ã«æˆ»ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\if@slide
+ \setlength\leftmargini{1\zw}
+\else
+ \if@twocolumn
+ \setlength\leftmargini{2\zw}
+ \else
+ \setlength\leftmargini{3\zw}
+ \fi
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\leftmarginii}
+% \begin{macro}{\leftmarginiii}
+% \begin{macro}{\leftmarginiv}
+% \begin{macro}{\leftmarginv}
+% \begin{macro}{\leftmarginvi}
+%
+% |ii|,|iii|,|iv| 㯠|\labelsep| ã¨
+% ãã‚Œãžã‚Œ `(m)',`vii.',`M.' ã®å¹…ã¨ã®å’Œã‚ˆã‚Šå¤§ããã™ã‚‹
+% ã“ã¨ã«ãªã£ã¦ã„ã¾ã™ã€‚ã“ã“ã§ã¯å…¨è§’å¹…ã®æ•´æ•°å€ã«ä¸¸ã‚ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\if@slide
+ \setlength\leftmarginii {1\zw}
+ \setlength\leftmarginiii{1\zw}
+ \setlength\leftmarginiv {1\zw}
+ \setlength\leftmarginv {1\zw}
+ \setlength\leftmarginvi {1\zw}
+\else
+ \setlength\leftmarginii {2\zw}
+ \setlength\leftmarginiii{2\zw}
+ \setlength\leftmarginiv {2\zw}
+ \setlength\leftmarginv {1\zw}
+ \setlength\leftmarginvi {1\zw}
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\labelsep}
+% \begin{macro}{\labelwidth}
+%
+% |\labelsep| ã¯ãƒ©ãƒ™ãƒ«ã¨æœ¬æ–‡ã®é–“ã®è·é›¢ã§ã™ã€‚
+% |\labelwidth| ã¯ãƒ©ãƒ™ãƒ«ã®å¹…ã§ã™ã€‚
+% ã“ã‚Œã¯äºŒåˆ†ã«å¤‰ãˆã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\setlength \labelsep {0.5\zw} % .5em
+\setlength \labelwidth{\leftmargini}
+\addtolength\labelwidth{-\labelsep}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\partopsep}
+%
+% リスト環境ã®å‰ã«ç©ºè¡ŒãŒã‚ã‚‹å ´åˆï¼Œ
+% |\parskip| 㨠|\topsep| 㫠|\partopsep| を
+% 加ãˆãŸå€¤ã ã‘縦方å‘ã®ç©ºç™½ãŒã§ãã¾ã™ã€‚
+% 0 ã«æ”¹å¤‰ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\setlength\partopsep{\z@} % {2\p@ \@plus 1\p@ \@minus 1\p@}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@beginparpenalty}
+% \begin{macro}{\@endparpenalty}
+% \begin{macro}{\@itempenalty}
+%
+% リストや段è½ç’°å¢ƒã®å‰å¾Œï¼Œãƒªã‚¹ãƒˆé …目間ã«æŒ¿å…¥ã•ã‚Œã‚‹ãƒšãƒŠãƒ«ãƒ†ã‚£ã§ã™ã€‚
+%
+% \begin{macrocode}
+\@beginparpenalty -\@lowpenalty
+\@endparpenalty -\@lowpenalty
+\@itempenalty -\@lowpenalty
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@listi}
+% \begin{macro}{\@listI}
+%
+% |\@listi| 㯠|\leftmargin|,|\parsep|,|\topsep|,|\itemsep| ãªã©ã®
+% トップレベルã®å®šç¾©ã‚’ã—ã¾ã™ã€‚
+% ã“ã®å®šç¾©ã¯ï¼Œãƒ•ã‚©ãƒ³ãƒˆã‚µã‚¤ã‚ºã‚³ãƒžãƒ³ãƒ‰ã«ã‚ˆã£ã¦å¤‰æ›´ã•ã‚Œã¾ã™
+% (ãŸã¨ãˆã° |\small| ã®ä¸­ã§ã¯å°ã•ã„値ã«è¨­å®šã•ã‚Œã¾ã™ï¼‰ã€‚
+% ã“ã®ãŸã‚,|\normalsize| ãŒã™ã¹ã¦ã®ãƒ‘ラメータを戻ã›ã‚‹ã‚ˆã†ã«ï¼Œ
+% |\@listI| 㧠|\@listi| ã®ã‚³ãƒ”ーをä¿å­˜ã—ã¾ã™ã€‚
+% å…ƒã®å€¤ã¯ã‹ãªã‚Šè¤‡é›‘ã§ã™ãŒï¼Œã“ã“ã§ã¯ç°¡ç´ åŒ–ã—ã¦ã—ã¾ã„ã¾ã—ãŸã€‚
+% 特ã«æœ€åˆã¨æœ€å¾Œã«è¡Œé€ã‚Šã®åŠåˆ†ã®ç©ºããŒå…¥ã‚‹ã‚ˆã†ã«ã—ã¦ã‚ã‚Šã¾ã™ã€‚
+% アスキーã®æ¨™æº–スタイルã§ã¯
+% トップレベル㮠|itemize|,|enumerate| 環境ã§ã ã‘
+% 最åˆã¨æœ€å¾Œã«è¡Œé€ã‚Šã®åŠåˆ†ã®ç©ºããŒå…¥ã‚‹ã‚ˆã†ã«ãªã£ã¦ã„ã¾ã—ãŸã€‚
+%
+% [2004-09-27] |\topsep| ã®ã‚°ãƒ«ãƒ¼ $_{-0.1}^{+0.2}$ |\baselineskip|
+% ã‚’æ€ã„切ã£ã¦å¤–ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\def\@listi{\leftmargin\leftmargini
+ \parsep \z@
+ \topsep 0.5\baselineskip
+ \itemsep \z@ \relax}
+\let\@listI\@listi
+% \end{macrocode}
+%
+% 念ã®ãŸã‚パラメータをåˆæœŸåŒ–ã—ã¾ã™ï¼ˆå®Ÿéš›ã«ã¯ä¸è¦ã®ã‚ˆã†ã§ã™ï¼‰ã€‚
+%
+% \begin{macrocode}
+\@listi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@listii}
+% \begin{macro}{\@listiii}
+% \begin{macro}{\@listiv}
+% \begin{macro}{\@listv}
+% \begin{macro}{\@listvi}
+%
+% 第2〜6レベルã®ãƒªã‚¹ãƒˆç’°å¢ƒã®ãƒ‘ラメータã®è¨­å®šã§ã™ã€‚
+%
+% \begin{macrocode}
+\def\@listii{\leftmargin\leftmarginii
+ \labelwidth\leftmarginii \advance\labelwidth-\labelsep
+ \topsep \z@
+ \parsep \z@
+ \itemsep\parsep}
+\def\@listiii{\leftmargin\leftmarginiii
+ \labelwidth\leftmarginiii \advance\labelwidth-\labelsep
+ \topsep \z@
+ \parsep \z@
+ \itemsep\parsep}
+\def\@listiv {\leftmargin\leftmarginiv
+ \labelwidth\leftmarginiv
+ \advance\labelwidth-\labelsep}
+\def\@listv {\leftmargin\leftmarginv
+ \labelwidth\leftmarginv
+ \advance\labelwidth-\labelsep}
+\def\@listvi {\leftmargin\leftmarginvi
+ \labelwidth\leftmarginvi
+ \advance\labelwidth-\labelsep}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \paragraph{enumerate環境}
+%
+% |enumerate| 環境ã¯ã‚«ã‚¦ãƒ³ã‚¿ |enumi|,|enumii|,|enumiii|,
+% |enumiv| を使ã„ã¾ã™ã€‚|enum|$n$ ã¯ç¬¬ $n$ レベルã®ç•ªå·ã§ã™ã€‚
+%
+% \begin{macro}{\theenumi}
+% \begin{macro}{\theenumii}
+% \begin{macro}{\theenumiii}
+% \begin{macro}{\theenumiv}
+%
+% 出力ã™ã‚‹ç•ªå·ã®æ›¸å¼ã‚’設定ã—ã¾ã™ã€‚
+% ã“れらã¯\LaTeX 本体(\texttt{ltlists.dtx} å‚照)ã§å®šç¾©æ¸ˆã¿ã§ã™ãŒï¼Œ
+% ã“ã“ã§ã¯è¡¨ã—方を変ãˆã¦ã„ã¾ã™ã€‚
+% |\@arabic|,|\@alph|,|\@roman|,|\@Alph| ã¯ãã‚Œãžã‚Œ
+% 算用数字,å°æ–‡å­—アルファベット,å°æ–‡å­—ローマ数字,大文字アルファベット
+% ã§ç•ªå·ã‚’出力ã™ã‚‹å‘½ä»¤ã§ã™ã€‚
+%
+% \begin{macrocode}
+\renewcommand{\theenumi}{\@arabic\c@enumi}
+\renewcommand{\theenumii}{\@alph\c@enumii}
+\renewcommand{\theenumiii}{\@roman\c@enumiii}
+\renewcommand{\theenumiv}{\@Alph\c@enumiv}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\labelenumi}
+% \begin{macro}{\labelenumii}
+% \begin{macro}{\labelenumiii}
+% \begin{macro}{\labelenumiv}
+%
+% |enumerate| 環境ã®ç•ªå·ã‚’出力ã™ã‚‹å‘½ä»¤ã§ã™ã€‚
+% 第2レベル以外ã¯æœ€å¾Œã«æ¬§æ–‡ã®ãƒ”リオドãŒä»˜ãã¾ã™ãŒï¼Œ
+% ã“ã‚Œã¯å¥½ã¿ã«å¿œã˜ã¦å–り払ã£ã¦ãã ã•ã„。
+% 第2レベルã®ç•ªå·ã®ã‹ã£ã“ã¯å’Œæ–‡ç”¨ã«æ›ãˆï¼Œ
+% ãã®ä¸¡å´ã«å…¥ã‚‹ä½™åˆ†ãªã‚°ãƒ«ãƒ¼ã‚’ |\inhibitglue| ã§
+% å–り除ã„ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand{\labelenumi}{\theenumi.}
+\newcommand{\labelenumii}{\inhibitglue(\theenumii)\inhibitglue}
+\newcommand{\labelenumiii}{\theenumiii.}
+\newcommand{\labelenumiv}{\theenumiv.}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\p@enumii}
+% \begin{macro}{\p@enumiii}
+% \begin{macro}{\p@enumiv}
+%
+% |\p@enum|$n$ 㯠|\ref| コマンド㧠|enumerate| 環境ã®ç¬¬ $n$ レベルã®
+% é …ç›®ãŒå‚ç…§ã•ã‚Œã‚‹ã¨ãã®æ›¸å¼ã§ã™ã€‚
+% ã“れも第2レベルã¯å’Œæ–‡ç”¨ã‹ã£ã“ã«ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\renewcommand{\p@enumii}{\theenumi}
+\renewcommand{\p@enumiii}{\theenumi\inhibitglue(\theenumii)}
+\renewcommand{\p@enumiv}{\p@enumiii\theenumiii}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \paragraph{itemize環境}
+%
+% \begin{macro}{\labelitemi}
+% \begin{macro}{\labelitemii}
+% \begin{macro}{\labelitemiii}
+% \begin{macro}{\labelitemiv}
+% |itemize| 環境ã®ç¬¬ $n$ レベルã®ãƒ©ãƒ™ãƒ«ã‚’作るコマンドã§ã™ã€‚
+% \begin{macrocode}
+\newcommand\labelitemi{\textbullet}
+\newcommand\labelitemii{\normalfont\bfseries \textendash}
+\newcommand\labelitemiii{\textasteriskcentered}
+\newcommand\labelitemiv{\textperiodcentered}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \paragraph{description環境}
+%
+% \begin{environment}{description}
+%
+% 本æ¥ã® |description| 環境ã§ã¯ï¼Œé …ç›®åãŒçŸ­ã„ã¨ï¼Œèª¬æ˜Žéƒ¨åˆ†ã®é ­ãŒ
+% ãã‚Œã«å¼•ããšã‚‰ã‚Œã¦å·¦ã«å‡ºã¦ã—ã¾ã„ã¾ã™ã€‚
+% ã“れを解決ã—ãŸæ–°ã—ã„ |description| ã®å®Ÿè£…ã§ã™ã€‚
+%
+% \begin{macrocode}
+\newenvironment{description}{%
+ \list{}{%
+ \labelwidth=\leftmargin
+ \labelsep=1\zw
+ \advance \labelwidth by -\labelsep
+ \let \makelabel=\descriptionlabel}}{\endlist}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\descriptionlabel}
+%
+% |description| 環境ã®ãƒ©ãƒ™ãƒ«ã‚’出力ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚
+% 好ã¿ã«å¿œã˜ã¦ |#1| ã®å‰ã«é©å½“ãªç©ºã
+% (ãŸã¨ãˆã° |\hspace{1\zw}|)を入れるã®ã‚‚ã„ã„ã¨æ€ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand*\descriptionlabel[1]{\normalfont\headfont #1\hfil}
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{概è¦}
+%
+% \begin{environment}{abstract}
+%
+% 概è¦ï¼ˆè¦æ—¨ï¼Œæ¢—概)を出力ã™ã‚‹ç’°å¢ƒã§ã™ã€‚
+% |book| クラスã§ã¯å„ç« ã®åˆã‚ã«ã¡ã‚‡ã£ã¨ã—ãŸã“ã¨ã‚’書ãã®ã«ä½¿ã„ã¾ã™ã€‚
+% |titlepage| オプション付ãã® |article| クラスã§ã¯ï¼Œ
+% 独立ã—ãŸãƒšãƒ¼ã‚¸ã«å‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+% |abstract| 環境ã¯å…ƒã¯ |quotation| 環境ã§ä½œã‚‰ã‚Œã¦ã„ã¾ã—ãŸãŒï¼Œ
+% |quotation| 環境ã®å³ãƒžãƒ¼ã‚¸ãƒ³ã‚’ゼロã«ã—ãŸã®ã§ï¼Œ
+% |list| 環境ã§ä½œã‚Šç›´ã—ã¾ã—ãŸã€‚
+%
+% JSPFスタイルã§ã¯å®Ÿéš›ã®å‡ºåŠ›ã¯ |\maketitle| ã§è¡Œã‚ã‚Œã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<*book>
+\newenvironment{abstract}{%
+ \begin{list}{}{%
+ \listparindent=1\zw
+ \itemindent=\listparindent
+ \rightmargin=0pt
+ \leftmargin=5\zw}\item[]}{\end{list}\vspace{\baselineskip}}
+%</book>
+%<*article|report|kiyou>
+\newbox\@abstractbox
+\if@titlepage
+ \newenvironment{abstract}{%
+ \titlepage
+ \null\vfil
+ \@beginparpenalty\@lowpenalty
+ \begin{center}%
+ \headfont \abstractname
+ \@endparpenalty\@M
+ \end{center}}%
+ {\par\vfil\null\endtitlepage}
+\else
+ \newenvironment{abstract}{%
+ \if@twocolumn
+ \ifx\maketitle\relax
+ \section*{\abstractname}%
+ \else
+ \global\setbox\@abstractbox\hbox\bgroup
+ \begin{minipage}[b]{\textwidth}
+ \small\parindent1\zw
+ \begin{center}%
+ {\headfont \abstractname\vspace{-.5em}\vspace{\z@}}%
+ \end{center}%
+ \list{}{%
+ \listparindent\parindent
+ \itemindent \listparindent
+ \rightmargin \leftmargin}%
+ \item\relax
+ \fi
+ \else
+ \small
+ \begin{center}%
+ {\headfont \abstractname\vspace{-.5em}\vspace{\z@}}%
+ \end{center}%
+ \list{}{%
+ \listparindent\parindent
+ \itemindent \listparindent
+ \rightmargin \leftmargin}%
+ \item\relax
+ \fi}{\if@twocolumn
+ \ifx\maketitle\relax
+ \else
+ \endlist\end{minipage}\egroup
+ \fi
+ \else
+ \endlist
+ \fi}
+\fi
+%</article|report|kiyou>
+%<*jspf>
+\newbox\@abstractbox
+\newenvironment{abstract}{%
+ \global\setbox\@abstractbox\hbox\bgroup
+ \begin{minipage}[b]{157\jsc@mmm}{\sffamily Abstract}\par
+ \small
+ \if@english \parindent6\jsc@mmm \else \parindent1\zw \fi}%
+ {\end{minipage}\egroup}
+%</jspf>
+% \end{macrocode}
+% \end{environment}
+%
+% \paragraph{キーワード}
+%
+% \begin{environment}{keywords}
+%
+% キーワードを準備ã™ã‚‹ç’°å¢ƒã§ã™ã€‚
+% 実際ã®å‡ºåŠ›ã¯ |\maketitle| ã§è¡Œã‚ã‚Œã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<*jspf>
+%\newbox\@keywordsbox
+%\newenvironment{keywords}{%
+% \global\setbox\@keywordsbox\hbox\bgroup
+% \begin{minipage}[b]{157\jsc@mmm}{\sffamily Keywords:}\par
+% \small\parindent0\zw}%
+% {\end{minipage}\egroup}
+%</jspf>
+% \end{macrocode}
+% \end{environment}
+%
+% \paragraph{verse環境}
+%
+% \begin{environment}{verse}
+%
+% è©©ã®ãŸã‚ã® |verse| 環境ã§ã™ã€‚
+%
+% \begin{macrocode}
+\newenvironment{verse}{%
+ \let \\=\@centercr
+ \list{}{%
+ \itemsep \z@
+ \itemindent -2\zw % å…ƒ: -1.5em
+ \listparindent\itemindent
+ \rightmargin \z@
+ \advance\leftmargin 2\zw}% å…ƒ: 1.5em
+ \item\relax}{\endlist}
+% \end{macrocode}
+% \end{environment}
+%
+% \paragraph{quotation環境}
+%
+% \begin{environment}{quotation}
+%
+% 段è½ã®é ­ã®å­—下ã’é‡ã‚’1.5emã‹ã‚‰ |\parindent| ã«å¤‰ãˆã¾ã—ãŸã€‚
+% ã¾ãŸï¼Œå³ãƒžãƒ¼ã‚¸ãƒ³ã‚’ 0 ã«ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\newenvironment{quotation}{%
+ \list{}{%
+ \listparindent\parindent
+ \itemindent\listparindent
+ \rightmargin \z@}%
+ \item\relax}{\endlist}
+% \end{macrocode}
+% \end{environment}
+%
+% \paragraph{quote環境}
+%
+% \begin{environment}{quote}
+%
+% |quote| 環境ã¯ï¼Œæ®µè½ãŒã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã•ã‚Œãªã„ã“ã¨ã‚’除ã,
+% |quotation| 環境ã¨åŒã˜ã§ã™ã€‚
+%
+% \begin{macrocode}
+\newenvironment{quote}%
+ {\list{}{\rightmargin\z@}\item\relax}{\endlist}
+% \end{macrocode}
+% \end{environment}
+%
+% \paragraph{定ç†ãªã©}
+%
+% |ltthm.dtx| å‚照。ãŸã¨ãˆã°æ¬¡ã®ã‚ˆã†ã«å®šç¾©ã—ã¾ã™ã€‚
+%\begin{verbatim}
+% \newtheorem{definition}{定義}
+% \newtheorem{axiom}{å…¬ç†}
+% \newtheorem{theorem}{定ç†}
+%\end{verbatim}
+%
+% [2001-04-26] 定ç†ã®ä¸­ã¯ã‚¤ã‚¿ãƒªãƒƒã‚¯ä½“ã«ãªã‚Šã¾ã—ãŸãŒï¼Œ
+% ã“ã‚Œã§ã¯å’Œæ–‡ãŒã‚´ã‚·ãƒƒã‚¯ä½“ã«ãªã£ã¦ã—ã¾ã†ã®ã§ï¼Œ
+% |\itshape| を削除ã—ã¾ã—ãŸã€‚
+%
+% [2009-08-23] |\bfseries| ã‚’ |\headfont| ã«ç›´ã—,
+% |\labelsep| ã‚’ |1\zw| ã«ã—,括弧を全角ã«ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\def\@begintheorem#1#2{\trivlist\labelsep=1\zw
+ \item[\hskip \labelsep{\headfont #1\ #2}]}
+\def\@opargbegintheorem#1#2#3{\trivlist\labelsep=1\zw
+ \item[\hskip \labelsep{\headfont #1\ #2(#3)}]}
+% \end{macrocode}
+%
+% \begin{environment}{titlepage}
+%
+% タイトルを独立ã®ãƒšãƒ¼ã‚¸ã«å‡ºåŠ›ã™ã‚‹ã®ã«ä½¿ã‚ã‚Œã¾ã™ã€‚
+%
+% [2017-02-24] コミュニティ版\pLaTeX ã®æ¨™æº–クラス2017/02/15ã«åˆã‚ã›ã¦ï¼Œ
+% bookクラスã§ã‚¿ã‚¤ãƒˆãƒ«ã‚’å¿…ãšå¥‡æ•°ãƒšãƒ¼ã‚¸ã«é€ã‚‹ã‚ˆã†ã«ã—ã¾ã—ãŸã€‚ã¨ã„ã£ã¦ã‚‚,
+% 横組クラスã—ã‹ã‚ã‚Šã¾ã›ã‚“ã§ã—ãŸã®ã§ï¼Œå¾“æ¥ã®æŒ™å‹•ã¯ä½•ã‚‚変ã‚ã£ã¦ã„ã¾ã›ã‚“。
+% ã¾ãŸï¼Œbook以外ã®å ´åˆã®ãƒšãƒ¼ã‚¸ç•ªå·ã®ãƒªã‚»ãƒƒãƒˆã‚‚コミュニティ版\pLaTeX ã®
+% 標準クラス2017/02/15ã«åˆã‚ã›ã¾ã—ãŸãŒï¼Œã“ã¡ã‚‰ã‚‚片é¢å°åˆ·ã‚ã‚‹ã„ã¯
+% 独立ã®ã‚¿ã‚¤ãƒˆãƒ«ãƒšãƒ¼ã‚¸ã‚’作らãªã„クラスã°ã‹ã‚Šã§ã—ãŸã®ã§ï¼Œå¾“æ¥ã®æŒ™å‹•ã¯
+% 何も変ã‚らãšã«æ¸ˆã¿ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\newenvironment{titlepage}{%
+%<book> \pltx@cleartooddpage %% 2017-02-24
+ \if@twocolumn
+ \@restonecoltrue\onecolumn
+ \else
+ \@restonecolfalse\newpage
+ \fi
+ \thispagestyle{empty}%
+ \ifodd\c@page\setcounter{page}\@ne\else\setcounter{page}\z@\fi
+ }%
+ {\if@restonecol\twocolumn \else \newpage \fi
+ \if@twoside\else
+ \setcounter{page}\@ne
+ \fi}
+% \end{macrocode}
+% \end{environment}
+%
+% \paragraph{付録}
+%
+% \begin{macro}{\appendix}
+%
+% 本文ã¨ä»˜éŒ²ã‚’分離ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚
+%
+% \begin{macrocode}
+%<*!book&!report>
+\newcommand{\appendix}{\par
+ \setcounter{section}{0}%
+ \setcounter{subsection}{0}%
+ \gdef\presectionname{\appendixname}%
+ \gdef\postsectionname{}%
+% \gdef\thesection{\@Alph\c@section}% [2003-03-02]
+ \gdef\thesection{\presectionname\@Alph\c@section\postsectionname}%
+ \gdef\thesubsection{\@Alph\c@section.\@arabic\c@subsection}}
+%</!book&!report>
+%<*book|report>
+\newcommand{\appendix}{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\@chappos{}%
+ \gdef\thechapter{\@Alph\c@chapter}}
+%</book|report>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{パラメータã®è¨­å®š}
+%
+% \paragraph{arrayã¨tabular環境}
+%
+% \begin{macro}{\arraycolsep}
+%
+% |array| 環境ã®åˆ—é–“ã«ã¯ |\arraycolsep| ã®2å€ã®å¹…ã®ç©ºããŒå…¥ã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\arraycolsep{5\jsc@mpt}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tabcolsep}
+%
+% |tabular| 環境ã®åˆ—é–“ã«ã¯ |\tabcolsep| ã®2å€ã®å¹…ã®ç©ºããŒå…¥ã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\tabcolsep{6\jsc@mpt}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\arrayrulewidth}
+%
+% |array|,|tabular| 環境内ã®ç½«ç·šã®å¹…ã§ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\arrayrulewidth{.4\jsc@mpt}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\doublerulesep}
+%
+% |array|,|tabular| 環境ã§ã®äºŒé‡ç½«ç·šé–“ã®ã‚¢ã‚­ã§ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\doublerulesep{2\jsc@mpt}
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{tabbing環境}
+%
+% \begin{macro}{\tabbingsep}
+%
+% |\'| コマンドã§å…¥ã‚‹ã‚¢ã‚­ã§ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\tabbingsep{\labelsep}
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{minipage環境}
+%
+% \begin{macro}{\@mpfootins}
+%
+% |minipage| 環境ã®è„šæ³¨ã® |\skip|\hspace{0pt}|\@mpfootins|
+% ã¯é€šå¸¸ã®ãƒšãƒ¼ã‚¸ã® |\skip|\hspace{0pt}|\footins|
+% ã¨åŒã˜åƒãã‚’ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\skip\@mpfootins = \skip\footins
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{framebox環境}
+%
+% \begin{macro}{\fboxsep}
+%
+% |\fbox|,|\framebox| ã§å†…å´ã®ãƒ†ã‚­ã‚¹ãƒˆã¨æž ã¨ã®é–“ã®ç©ºãã§ã™ã€‚
+%
+% \begin{macro}{\fboxrule}
+%
+% |\fbox|,|\framebox| ã®ç½«ç·šã®å¹…ã§ã™ã€‚
+%
+% \begin{macrocode}
+\setlength\fboxsep{3\jsc@mpt}
+\setlength\fboxrule{.4\jsc@mpt}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \paragraph{equationã¨eqnarray環境}
+%
+% \begin{macro}{\theequation}
+%
+% æ•°å¼ç•ªå·ã‚’出力ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚
+%
+% \begin{macrocode}
+%<!book&!report>\renewcommand \theequation {\@arabic\c@equation}
+%<*book|report>
+\@addtoreset{equation}{chapter}
+\renewcommand\theequation
+ {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@equation}
+%</book|report>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\jot}
+%
+% |eqnarray| ã®è¡Œé–“ã«ä½™åˆ†ã«å…¥ã‚‹ã‚¢ã‚­ã§ã™ã€‚
+% デフォルトã®å€¤ã‚’コメントアウトã—ã¦ç¤ºã—ã¦ãŠãã¾ã™ã€‚
+%
+% \begin{macrocode}
+% \setlength\jot{3pt}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@eqnnum}
+%
+% æ•°å¼ç•ªå·ã®å½¢å¼ã§ã™ã€‚
+% デフォルトã®å€¤ã‚’コメントアウトã—ã¦ç¤ºã—ã¦ãŠãã¾ã™ã€‚
+%
+% |\inhibitglue(\theequation)\inhibitglue| ã®ã‚ˆã†ã«å’Œæ–‡ã‹ã£ã“
+% を使ã†ã“ã¨ã‚‚å¯èƒ½ã§ã™ã€‚
+%
+% \begin{macrocode}
+% \def\@eqnnum{(\theequation)}
+% \end{macrocode}
+% \end{macro}
+%
+% |amsmath| パッケージを使ã†å ´åˆã¯ |\tagform@| を次ã®ã‚ˆã†ã«ä¿®æ­£ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+% \def\tagform@#1{\maketag@@@{(\ignorespaces#1\unskip\@@italiccorr)}}
+% \end{macrocode}
+%
+% \subsection{フロート}
+%
+% タイプ \texttt{TYPE} ã®ãƒ•ãƒ­ãƒ¼ãƒˆã‚ªãƒ–ジェクトを
+% 扱ã†ã«ã¯ï¼Œæ¬¡ã®ãƒžã‚¯ãƒ­ã‚’定義ã—ã¾ã™ã€‚
+% \begin{description}
+% \item[\texttt{\bslash fps@TYPE}]
+% フロートを置ãä½ç½®ï¼ˆfloat placement specifier)ã§ã™ã€‚
+% \item[\texttt{\bslash ftype@TYPE}]
+% フロートã®ç•ªå·ã§ã™ã€‚2ã®ç´¯ä¹—(1,2,4,\ldots )ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。
+% \item[\texttt{\bslash ext@TYPE}]
+% フロートã®ç›®æ¬¡ã‚’出力ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã®æ‹¡å¼µå­ã§ã™ã€‚
+% \item[\texttt{\bslash fnum@TYPE}]
+% キャプション用ã®ç•ªå·ã‚’生æˆã™ã‚‹ãƒžã‚¯ãƒ­ã§ã™ã€‚
+% \item[\texttt{\bslash @makecaption}{\meta{num}}{\meta{text}}]
+% キャプションを出力ã™ã‚‹ãƒžã‚¯ãƒ­ã§ã™ã€‚
+% \meta{num} 㯠|\fnum@...| ã®ç”Ÿæˆã™ã‚‹ç•ªå·ï¼Œ
+% \meta{text} ã¯ã‚­ãƒ£ãƒ—ションã®ãƒ†ã‚­ã‚¹ãƒˆã§ã™ã€‚
+% テキストã¯é©å½“ãªå¹…ã® |\parbox| ã«å…¥ã‚Šã¾ã™ã€‚
+% \end{description}
+%
+% \paragraph{figure環境}
+%
+% \begin{macro}{\c@figure}
+%
+% 図番å·ã®ã‚«ã‚¦ãƒ³ã‚¿ã§ã™ã€‚
+%
+% \begin{macro}{\thefigure}
+%
+% 図番å·ã‚’出力ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚
+%
+% \begin{macrocode}
+%<*!book&!report>
+\newcounter{figure}
+\renewcommand \thefigure {\@arabic\c@figure}
+%</!book&!report>
+%<*book|report>
+\newcounter{figure}[chapter]
+\renewcommand \thefigure
+ {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@figure}
+%</book|report>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fps@figure}
+% \begin{macro}{\ftype@figure}
+% \begin{macro}{\ext@figure}
+% \begin{macro}{\fnum@figure}
+%
+% |figure| ã®ãƒ‘ラメータã§ã™ã€‚
+% |\figurename| ã®ç›´å¾Œã« |~| ãŒå…¥ã£ã¦ã„ã¾ã—ãŸãŒï¼Œ
+% ã“ã“ã§ã¯å¤–ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\def\fps@figure{tbp}
+\def\ftype@figure{1}
+\def\ext@figure{lof}
+\def\fnum@figure{\figurename\nobreak\thefigure}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{environment}{figure}
+% \begin{environment}{figure*}
+%
+% |*| å½¢å¼ã¯æ®µæŠœãã®ãƒ•ãƒ­ãƒ¼ãƒˆã§ã™ã€‚
+%
+% \begin{macrocode}
+\newenvironment{figure}%
+ {\@float{figure}}%
+ {\end@float}
+\newenvironment{figure*}%
+ {\@dblfloat{figure}}%
+ {\end@dblfloat}
+% \end{macrocode}
+% \end{environment}
+% \end{environment}
+%
+% \paragraph{table環境}
+%
+% \begin{macro}{\c@table}
+% \begin{macro}{\thetable}
+%
+% 表番å·ã‚«ã‚¦ãƒ³ã‚¿ã¨è¡¨ç•ªå·ã‚’出力ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚
+% アスキー版ã§ã¯ |\thechapter.| ㌠|\thechapter{}・| ã«ãªã£ã¦ã„ã¾ã™ãŒï¼Œ
+% ã“ã“ã§ã¯ã‚ªãƒªã‚¸ãƒŠãƒ«ã®ã¾ã¾ã«ã—ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+%<*!book&!report>
+\newcounter{table}
+\renewcommand\thetable{\@arabic\c@table}
+%</!book&!report>
+%<*book|report>
+\newcounter{table}[chapter]
+\renewcommand \thetable
+ {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@table}
+%</book|report>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fps@table}
+% \begin{macro}{\ftype@table}
+% \begin{macro}{\ext@table}
+% \begin{macro}{\fnum@table}
+%
+% |table| ã®ãƒ‘ラメータã§ã™ã€‚
+% |\tablename| ã®ç›´å¾Œã« |~| ãŒå…¥ã£ã¦ã„ã¾ã—ãŸãŒï¼Œ
+% ã“ã“ã§ã¯å¤–ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\def\fps@table{tbp}
+\def\ftype@table{2}
+\def\ext@table{lot}
+\def\fnum@table{\tablename\nobreak\thetable}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{environment}{table}
+% \begin{environment}{table*}
+%
+% |*| ã¯æ®µæŠœãã®ãƒ•ãƒ­ãƒ¼ãƒˆã§ã™ã€‚
+%
+% \begin{macrocode}
+\newenvironment{table}%
+ {\@float{table}}%
+ {\end@float}
+\newenvironment{table*}%
+ {\@dblfloat{table}}%
+ {\end@dblfloat}
+% \end{macrocode}
+% \end{environment}
+% \end{environment}
+%
+% \subsection{キャプション}
+%
+% \begin{macro}{\@makecaption}
+%
+% |\caption| コマンドã«ã‚ˆã‚Šå‘¼ã³å‡ºã•ã‚Œï¼Œ
+% 実際ã«ã‚­ãƒ£ãƒ—ションを出力ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚
+% 第1引数ã¯ãƒ•ãƒ­ãƒ¼ãƒˆã®ç•ªå·ï¼Œ
+% 第2引数ã¯ãƒ†ã‚­ã‚¹ãƒˆã§ã™ã€‚
+%
+% \begin{macro}{\abovecaptionskip}
+% \begin{macro}{\belowcaptionskip}
+%
+% ãã‚Œãžã‚Œã‚­ãƒ£ãƒ—ションã®å‰å¾Œã«æŒ¿å…¥ã•ã‚Œã‚‹ã‚¹ãƒšãƒ¼ã‚¹ã§ã™ã€‚
+% |\belowcaptionskip| ãŒ0ã«ãªã£ã¦ã„ã¾ã—ãŸã®ã§ï¼Œ
+% キャプションを表ã®ä¸Šã«ã¤ã‘ãŸå ´åˆã«ã‚­ãƒ£ãƒ—ションã¨è¡¨ãŒ
+% ãã£ã¤ã„ã¦ã—ã¾ã†ã®ã‚’ç›´ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\newlength\abovecaptionskip
+\newlength\belowcaptionskip
+\setlength\abovecaptionskip{5\jsc@mpt} % å…ƒ: 10\p@
+\setlength\belowcaptionskip{5\jsc@mpt} % å…ƒ: 0\p@
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% 実際ã®ã‚­ãƒ£ãƒ—ションを出力ã—ã¾ã™ã€‚
+% オリジナルã¨ç•°ãªã‚Šï¼Œæ–‡å­—サイズを |\small| ã«ã—,
+% キャプションã®å¹…ã‚’2cmç‹­ãã—ã¾ã—ãŸã€‚
+%
+% [2003-11-05] ロジックを少ã—変ãˆã¦ã¿ã¾ã—ãŸã€‚
+%
+% [2015-05-26] |listings| パッケージを使ã†ã¨ãã«|title| を指定ã™ã‚‹ã¨æ¬¡ã®ã‚¨ãƒ©ãƒ¼ãŒå‡ºã‚‹ã®ã‚’修正。
+% \begin{verbatim}
+% ! Missing number, treated as zero.
+% \end{verbatim}
+%
+%
+% \begin{macrocode}
+%<*!jspf>
+% \long\def\@makecaption#1#2{{\small
+% \advance\leftskip10\jsc@mmm
+% \advance\rightskip10\jsc@mmm
+% \vskip\abovecaptionskip
+% \sbox\@tempboxa{#1{\hskip1\zw}#2}%
+% \ifdim \wd\@tempboxa >\hsize
+% #1{\hskip1\zw}#2\par
+% \else
+% \global \@minipagefalse
+% \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
+% \fi
+% \vskip\belowcaptionskip}}
+\long\def\@makecaption#1#2{{\small
+ \advance\leftskip .0628\linewidth
+ \advance\rightskip .0628\linewidth
+ \vskip\abovecaptionskip
+ \sbox\@tempboxa{#1{\hskip1\zw}#2}%
+ \ifdim \wd\@tempboxa <\hsize \centering \fi
+ #1{\hskip1\zw}#2\par
+ \vskip\belowcaptionskip}}
+%</!jspf>
+%<*jspf>
+\long\def\@makecaption#1#2{%
+ \vskip\abovecaptionskip
+ \sbox\@tempboxa{\small\sffamily #1\quad #2}%
+ \ifdim \wd\@tempboxa >\hsize
+ {\small\sffamily
+ \list{#1}{%
+ \renewcommand{\makelabel}[1]{##1\hfil}
+ \itemsep \z@
+ \itemindent \z@
+ \labelsep \z@
+ \labelwidth 11\jsc@mmm
+ \listparindent\z@
+ \leftmargin 11\jsc@mmm}\item\relax #2\endlist}
+ \else
+ \global \@minipagefalse
+ \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
+ \fi
+ \vskip\belowcaptionskip}
+%</jspf>
+% \end{macrocode}
+% \end{macro}
+%
+% \section{フォントコマンド}
+%
+% ã“ã“ã§ã¯\LaTeX~2.09ã§ä½¿ã‚ã‚Œã¦ã„ãŸã‚³ãƒžãƒ³ãƒ‰ã‚’定義ã—ã¾ã™ã€‚
+% ã“れらã¯ãƒ†ã‚­ã‚¹ãƒˆãƒ¢ãƒ¼ãƒ‰ã¨æ•°å¼ãƒ¢ãƒ¼ãƒ‰ã®ã©ã¡ã‚‰ã§ã‚‚動作ã—ã¾ã™ã€‚
+% ã“れらã¯äº’æ›æ€§ã®ãŸã‚ã®ã‚‚ã®ã§ï¼Œ
+% ã§ãã‚‹ã ã‘ |\text...| 㨠|\math...| を使ã£ã¦ãã ã•ã„。
+%
+% [2016-07-15] KOMA-Script中㮠|\scr@DeclareOldFontCommand| ã«å€£ã„,
+% ã“れらã®å‘½ä»¤ã‚’使ã†ã¨ãã«ã¯è­¦å‘Šã‚’発ã™ã‚‹ã“ã¨ã«ã—ã¾ã—ãŸã€‚
+%
+% [2016-07-16] 警告を最åˆã®ä¸€å›žã ã‘発ã™ã‚‹ã“ã¨ã«ã—ã¾ã—ãŸã€‚ã¾ãŸï¼Œ
+% 例外的ã«è­¦å‘Šã‚’出ã•ãªã„よã†ã«ã™ã‚‹ã‚¹ã‚¤ãƒƒãƒã‚‚付ã‘ã¾ã™ã€‚
+%
+% \begin{macro}{\if@jsc@warnoldfontcmd}
+% \begin{macro}{\if@jsc@warnoldfontcmdexception}
+% \begin{macrocode}
+\newif\if@jsc@warnoldfontcmd
+\@jsc@warnoldfontcmdtrue
+\newif\if@jsc@warnoldfontcmdexception
+\@jsc@warnoldfontcmdexceptionfalse
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\jsc@DeclareOldFontCommand}
+% \begin{macrocode}
+\newcommand*{\jsc@DeclareOldFontCommand}[3]{%
+ \DeclareOldFontCommand{#1}{%
+ \jsc@warnoldfontcmd{#1}#2%
+ }{%
+ \jsc@warnoldfontcmd{#1}#3%
+ }%
+}
+\DeclareRobustCommand*{\jsc@warnoldfontcmd}[1]{%
+ \if@jsc@warnoldfontcmdexception\else\if@jsc@warnoldfontcmd
+ \ClassWarning{\jsc@clsname}{%
+ deprecated old font command `\string#1' used.\MessageBreak
+ You should note, that since 1994 LaTeX2e provides a\MessageBreak
+ new font selection scheme called NFSS2 with several\MessageBreak
+ new, combinable font commands. This \jsc@clsname\MessageBreak
+ class has defined the old font commands like\MessageBreak
+ `\string#1' only for compatibility%
+ }%
+ \global\@jsc@warnoldfontcmdfalse
+ \fi\fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mc}
+% \begin{macro}{\gt}
+% \begin{macro}{\rm}
+% \begin{macro}{\sf}
+% \begin{macro}{\tt}
+%
+% フォントファミリを変更ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\jsc@DeclareOldFontCommand{\mc}{\normalfont\mcfamily}{\mathmc}
+\jsc@DeclareOldFontCommand{\gt}{\normalfont\gtfamily}{\mathgt}
+\jsc@DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm}
+\jsc@DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}
+\jsc@DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\bf}
+%
+% ボールドシリーズã«ã—ã¾ã™ã€‚通常ã®ãƒŸãƒ¼ãƒ‡ã‚£ã‚¢ãƒ ã‚·ãƒªãƒ¼ã‚ºã«æˆ»ã™
+% コマンド㯠|\mdseries| ã§ã™ã€‚
+%
+% \begin{macrocode}
+\jsc@DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\it}
+% \begin{macro}{\sl}
+% \begin{macro}{\sc}
+%
+% フォントシェイプを変ãˆã‚‹ã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚
+% 斜体ã¨ã‚¹ãƒ¢ãƒ¼ãƒ«ã‚­ãƒ£ãƒƒãƒ—スã¯æ•°å¼ä¸­ã§ã¯ä½•ã‚‚ã—ã¾ã›ã‚“
+% (警告メッセージを出力ã—ã¾ã™ï¼‰ã€‚
+% 通常ã®ã‚¢ãƒƒãƒ—ライト体ã«æˆ»ã™ã‚³ãƒžãƒ³ãƒ‰ã¯ |\upshape| ã§ã™ã€‚
+%
+% \begin{macrocode}
+\jsc@DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit}
+\jsc@DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl}
+\jsc@DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cal}
+% \begin{macro}{\mit}
+%
+% æ•°å¼ãƒ¢ãƒ¼ãƒ‰ä»¥å¤–ã§ã¯ä½•ã‚‚ã—ã¾ã›ã‚“(警告を出ã—ã¾ã™ï¼‰ã€‚
+%
+% \begin{macrocode}
+\DeclareRobustCommand*{\cal}{\@fontswitch\relax\mathcal}
+\DeclareRobustCommand*{\mit}{\@fontswitch\relax\mathnormal}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \section{相互å‚ç…§}
+%
+% \subsection{目次ã®é¡ž}
+%
+% |\section| コマンド㯠|.toc| ファイルã«æ¬¡ã®ã‚ˆã†ãªè¡Œã‚’出力ã—ã¾ã™ã€‚
+% \begin{quote}
+% |\contentsline{section}{タイトル}{ページ}|
+% \end{quote}
+% ãŸã¨ãˆã° |\section| ã«è¦‹å‡ºã—番å·ãŒä»˜ãå ´åˆï¼Œä¸Šã®ã€Œã‚¿ã‚¤ãƒˆãƒ«ã€ã¯
+% \begin{quote}
+% |\numberline{番å·}{見出ã—}|
+% \end{quote}
+% ã¨ãªã‚Šã¾ã™ã€‚
+% ã“ã®ã€Œç•ªå·ã€ã¯ |\thesection| コマンドã§ç”Ÿæˆã•ã‚ŒãŸè¦‹å‡ºã—番å·ã§ã™ã€‚
+%
+% |figure| 環境㮠|\caption| コマンド㯠|.lof| ファイルã«
+% 次ã®ã‚ˆã†ãªè¡Œã‚’出力ã—ã¾ã™ã€‚
+% \begin{quote}
+% |\contentsline{figure}{\numberline{番å·}{キャプション}{ページ}|
+% \end{quote}
+% ã“ã®ã€Œç•ªå·ã€ã¯ |\thefigure| コマンドã§ç”Ÿæˆã•ã‚ŒãŸå›³ç•ªå·ã§ã™ã€‚
+%
+% |table| 環境もåŒæ§˜ã§ã™ã€‚
+%
+% |\contentsline{...}| 㯠|\l@...| ã¨ã„ã†ã‚³ãƒžãƒ³ãƒ‰ã‚’実行ã™ã‚‹ã®ã§ï¼Œ
+% ã‚らã‹ã˜ã‚ |\l@chapter|,|\l@section|,|\l@figure| ãªã©ã‚’
+% 定義ã—ã¦ãŠã‹ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。
+% ã“れらã®å¤šã㯠|\@dottedtocline| コマンドを使ã£ã¦å®šç¾©ã—ã¾ã™ã€‚
+% ã“ã‚Œã¯
+% \begin{quote}
+% |\@dottedtocline{レベル}{インデント}{幅}{タイトル}{ページ}|
+% \end{quote}
+% ã¨ã„ã†æ›¸å¼ã§ã™ã€‚
+% \begin{description}
+% \item[レベル] ã“ã®å€¤ãŒ |tocdepth| 以下ã®ã¨ãã ã‘出力ã•ã‚Œã¾ã™ã€‚
+% |\chapter| ã¯ãƒ¬ãƒ™ãƒ«0,|\section| ã¯ãƒ¬ãƒ™ãƒ«1,等々ã§ã™ã€‚
+% \item[インデント] å·¦å´ã®å­—下ã’é‡ã§ã™ã€‚
+% \item[å¹…] 「タイトルã€ã« |\numberline| コマンドãŒå«ã¾ã‚Œã‚‹å ´åˆï¼Œ
+% 節番å·ãŒå…¥ã‚‹ç®±ã®å¹…ã§ã™ã€‚
+% \end{description}
+%
+% \begin{macro}{\@pnumwidth}
+%
+% ページ番å·ã®å…¥ã‚‹ç®±ã®å¹…ã§ã™ã€‚
+%
+% \begin{macro}{\@tocrmarg}
+%
+% å³ãƒžãƒ¼ã‚¸ãƒ³ã§ã™ã€‚
+% |\@tocrmarg| $\ge$ |\@pnumwidth| ã¨ã—ã¾ã™ã€‚
+%
+% \begin{macro}{\@dotsep}
+%
+% 点ã®é–“éš”ã§ã™ï¼ˆå˜ä½ mu)。
+%
+% \begin{macro}{\c@tocdepth}
+%
+% 目次ページã«å‡ºåŠ›ã™ã‚‹è¦‹å‡ºã—レベルã§ã™ã€‚
+% 元㯠\texttt{article} ã§3,ãã®ä»–ã§2ã§ã—ãŸãŒï¼Œ
+% ã“ã“ã§ã¯ä¸€ã¤ãšã¤æ¸›ã‚‰ã—ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand\@pnumwidth{1.55em}
+\newcommand\@tocrmarg{2.55em}
+\newcommand\@dotsep{4.5}
+%<!book&!report>\setcounter{tocdepth}{2}
+%<book|report>\setcounter{tocdepth}{1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \paragraph{目次}
+%
+% \begin{macro}{\tableofcontents}
+%
+% 目次を生æˆã—ã¾ã™ã€‚
+%
+% \begin{macro}{\jsc@tocl@width}
+%
+% [2013-12-30] |\prechaptername| ãªã©ã‹ã‚‰è¦‹ç©ã‚‚ã£ãŸç›®æ¬¡ã®ãƒ©ãƒ™ãƒ«ã®é•·ã•ã§ã™ã€‚(by ts)
+%
+% \begin{macrocode}
+\newdimen\jsc@tocl@width
+\newcommand{\tableofcontents}{%
+%<*book|report>
+ \settowidth\jsc@tocl@width{\headfont\prechaptername\postchaptername}%
+ \settowidth\@tempdima{\headfont\appendixname}%
+ \ifdim\jsc@tocl@width<\@tempdima \setlength\jsc@tocl@width{\@tempdima}\fi
+ \ifdim\jsc@tocl@width<2\zw \divide\jsc@tocl@width by 2 \advance\jsc@tocl@width 1\zw\fi
+ \if@twocolumn
+ \@restonecoltrue\onecolumn
+ \else
+ \@restonecolfalse
+ \fi
+ \chapter*{\contentsname}%
+ \@mkboth{\contentsname}{}%
+%</book|report>
+%<*!book&!report>
+ \settowidth\jsc@tocl@width{\headfont\presectionname\postsectionname}%
+ \settowidth\@tempdima{\headfont\appendixname}%
+ \ifdim\jsc@tocl@width<\@tempdima\relax\setlength\jsc@tocl@width{\@tempdima}\fi
+ \ifdim\jsc@tocl@width<2\zw \divide\jsc@tocl@width by 2 \advance\jsc@tocl@width 1\zw\fi
+ \section*{\contentsname}%
+ \@mkboth{\contentsname}{\contentsname}%
+%</!book&!report>
+ \@starttoc{toc}%
+%<book|report> \if@restonecol\twocolumn\fi
+}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\l@part}
+%
+% 部ã®ç›®æ¬¡ã§ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand*{\l@part}[2]{%
+ \ifnum \c@tocdepth >-2\relax
+%<!book&!report> \addpenalty\@secpenalty
+%<book|report> \addpenalty{-\@highpenalty}%
+ \addvspace{2.25em \@plus\jsc@mpt}%
+ \begingroup
+ \parindent \z@
+% \@pnumwidth should be \@tocrmarg
+% \rightskip \@pnumwidth
+ \rightskip \@tocrmarg
+ \parfillskip -\rightskip
+ {\leavevmode
+ \large \headfont
+ \setlength\@lnumwidth{4\zw}%
+ #1\hfil \hb@xt@\@pnumwidth{\hss #2}}\par
+ \nobreak
+%<book|report> \global\@nobreaktrue
+%<book|report> \everypar{\global\@nobreakfalse\everypar{}}%
+ \endgroup
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l@chapter}
+%
+% ç« ã®ç›®æ¬¡ã§ã™ã€‚|\@lnumwidth| ã‚’ |4.683\zw| ã«å¢—ã‚„ã—ã¾ã—ãŸã€‚
+%
+% [2013-12-30] |\@lnumwidth| ã‚’ |\jsc@tocl@width| ã‹ã‚‰
+% 決ã‚るよã†ã«ã—ã¦ã¿ã¾ã—ãŸã€‚(by ts)
+%
+% \begin{macrocode}
+%<*book|report>
+\newcommand*{\l@chapter}[2]{%
+ \ifnum \c@tocdepth >\m@ne
+ \addpenalty{-\@highpenalty}%
+ \addvspace{1.0em \@plus\jsc@mpt}
+% \vskip 1.0em \@plus\p@ % book.clsã§ã¯â†‘ãŒã“ã†ãªã£ã¦ã„ã‚‹
+ \begingroup
+ \parindent\z@
+% \rightskip\@pnumwidth
+ \rightskip\@tocrmarg
+ \parfillskip-\rightskip
+ \leavevmode\headfont
+ % \if@english\setlength\@lnumwidth{5.5em}\else\setlength\@lnumwidth{4.683\zw}\fi
+ \setlength\@lnumwidth{\jsc@tocl@width}\advance\@lnumwidth 2.683\zw
+ \advance\leftskip\@lnumwidth \hskip-\leftskip
+ #1\nobreak\hfil\nobreak\hbox to\@pnumwidth{\hss#2}\par
+ \penalty\@highpenalty
+ \endgroup
+ \fi}
+%</book|report>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l@section}
+%
+% 節ã®ç›®æ¬¡ã§ã™ã€‚
+%
+% \begin{macrocode}
+%<*!book&!report>
+\newcommand*{\l@section}[2]{%
+ \ifnum \c@tocdepth >\z@
+ \addpenalty{\@secpenalty}%
+ \addvspace{1.0em \@plus\jsc@mpt}%
+ \begingroup
+ \parindent\z@
+% \rightskip\@pnumwidth
+ \rightskip\@tocrmarg
+ \parfillskip-\rightskip
+ \leavevmode\headfont
+ %\setlength\@lnumwidth{4\zw}% å…ƒ1.5em [2003-03-02]
+ \setlength\@lnumwidth{\jsc@tocl@width}\advance\@lnumwidth 2\zw
+ \advance\leftskip\@lnumwidth \hskip-\leftskip
+ #1\nobreak\hfil\nobreak\hbox to\@pnumwidth{\hss#2}\par
+ \endgroup
+ \fi}
+%</!book&!report>
+% \end{macrocode}
+%
+% インデントã¨å¹…ã¯ãã‚Œãžã‚Œ1.5em,2.3emã§ã—ãŸãŒï¼Œ
+% |1\zw|,|3.683\zw|ã«å¤‰ãˆã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+%<book|report> % \newcommand*{\l@section}{\@dottedtocline{1}{1\zw}{3.683\zw}}
+% \end{macrocode}
+%
+% [2013-12-30] 上ã®ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã¯ |\jsc@tocl@width| ã‹ã‚‰æ±ºã‚るよã†ã«
+% ã—ã¾ã—ãŸã€‚(by ts)
+%
+% \end{macro}
+%
+% \begin{macro}{\l@subsection}
+% \begin{macro}{\l@subsubsection}
+% \begin{macro}{\l@paragraph}
+% \begin{macro}{\l@subparagraph}
+%
+% ã•ã‚‰ã«ä¸‹ä½ãƒ¬ãƒ™ãƒ«ã®ç›®æ¬¡é …ç›®ã®ä½“è£ã§ã™ã€‚
+% ã‚ã¾ã‚Šä½¿ã£ãŸã“ã¨ãŒã‚ã‚Šã¾ã›ã‚“ã®ã§ï¼Œè¦ä¿®æ­£ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“。
+%
+% [2013-12-30] ã“ã“ã‚‚ |\jsc@tocl@width| ã‹ã‚‰æ±ºã‚るよã†ã«
+% ã—ã¦ã¿ã¾ã—ãŸã€‚(by ts)
+%
+% \begin{macrocode}
+%<*!book&!report>
+% \newcommand*{\l@subsection} {\@dottedtocline{2}{1.5em}{2.3em}}
+% \newcommand*{\l@subsubsection}{\@dottedtocline{3}{3.8em}{3.2em}}
+% \newcommand*{\l@paragraph} {\@dottedtocline{4}{7.0em}{4.1em}}
+% \newcommand*{\l@subparagraph} {\@dottedtocline{5}{10em}{5em}}
+%
+% \newcommand*{\l@subsection} {\@dottedtocline{2}{1\zw}{3\zw}}
+% \newcommand*{\l@subsubsection}{\@dottedtocline{3}{2\zw}{3\zw}}
+% \newcommand*{\l@paragraph} {\@dottedtocline{4}{3\zw}{3\zw}}
+% \newcommand*{\l@subparagraph} {\@dottedtocline{5}{4\zw}{3\zw}}
+%
+\newcommand*{\l@subsection}{%
+ \@tempdima\jsc@tocl@width \advance\@tempdima -1\zw
+ \@dottedtocline{2}{\@tempdima}{3\zw}}
+\newcommand*{\l@subsubsection}{%
+ \@tempdima\jsc@tocl@width \advance\@tempdima 0\zw
+ \@dottedtocline{3}{\@tempdima}{4\zw}}
+\newcommand*{\l@paragraph}{%
+ \@tempdima\jsc@tocl@width \advance\@tempdima 1\zw
+ \@dottedtocline{4}{\@tempdima}{5\zw}}
+\newcommand*{\l@subparagraph}{%
+ \@tempdima\jsc@tocl@width \advance\@tempdima 2\zw
+ \@dottedtocline{5}{\@tempdima}{6\zw}}
+%</!book&!report>
+%<*book|report>
+% \newcommand*{\l@subsection} {\@dottedtocline{2}{3.8em}{3.2em}}
+% \newcommand*{\l@subsubsection}{\@dottedtocline{3}{7.0em}{4.1em}}
+% \newcommand*{\l@paragraph} {\@dottedtocline{4}{10em}{5em}}
+% \newcommand*{\l@subparagraph} {\@dottedtocline{5}{12em}{6em}}
+\newcommand*{\l@section}{%
+ \@tempdima\jsc@tocl@width \advance\@tempdima -1\zw
+ \@dottedtocline{1}{\@tempdima}{3.683\zw}}
+\newcommand*{\l@subsection}{%
+ \@tempdima\jsc@tocl@width \advance\@tempdima 2.683\zw
+ \@dottedtocline{2}{\@tempdima}{3.5\zw}}
+\newcommand*{\l@subsubsection}{%
+ \@tempdima\jsc@tocl@width \advance\@tempdima 6.183\zw
+ \@dottedtocline{3}{\@tempdima}{4.5\zw}}
+\newcommand*{\l@paragraph}{%
+ \@tempdima\jsc@tocl@width \advance\@tempdima 10.683\zw
+ \@dottedtocline{4}{\@tempdima}{5.5\zw}}
+\newcommand*{\l@subparagraph}{%
+ \@tempdima\jsc@tocl@width \advance\@tempdima 16.183\zw
+ \@dottedtocline{5}{\@tempdima}{6.5\zw}}
+%</book|report>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\numberline}
+% \begin{macro}{\@lnumwidth}
+%
+% 欧文版\LaTeX ã§ã¯ |\numberline{...}| ã¯å¹… |\@tempdima| ã®ç®±ã«å·¦è©°ã‚
+% ã§å‡ºåŠ›ã™ã‚‹å‘½ä»¤ã§ã™ãŒï¼Œ
+% アスキー版ã§ã¯ |\@tempdima| ã®ä»£ã‚ã‚Šã« |\@lnumwidth| ã¨ã„ã†å¤‰æ•°
+% ã§å¹…を決ã‚るよã†ã«å†å®šç¾©ã—ã¦ã„ã¾ã™ã€‚
+% 後続文字ãŒå…¨è§’ã‹åŠè§’ã‹ã§ã‚¹ãƒšãƒ¼ã‚¹ãŒå¤‰ã‚らãªã„よã†ã« |\hspace|
+% を入れã¦ãŠãã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\newdimen\@lnumwidth
+\def\numberline#1{\hb@xt@\@lnumwidth{#1\hfil}\hspace{0pt}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@dottedtocline}
+% \begin{macro}{\jsTocLine}
+%
+% \LaTeX 本体(\texttt{ltsect.dtx} å‚照)ã§ã®å®šç¾©ã¨åŒã˜ã§ã™ãŒï¼Œ
+% |\@tempdima| ã‚’ |\@lnumwidth| ã«å¤‰ãˆã¦ã„ã¾ã™ã€‚
+%
+% [2018-06-23] デフォルトã§ã¯\jsTocLine ã®ã‚ˆã†ã«ãƒ™ãƒ¼ã‚¹ãƒ©ã‚¤ãƒ³ã«ãªã‚Šã¾ã™ã€‚\par
+% ã“れを変更å¯èƒ½ã«ã™ã‚‹ãŸã‚,|\jsTocLine| ã¨ã„ã†ãƒžã‚¯ãƒ­ã«åˆ‡ã‚Šå‡ºã—ã¾ã—ãŸã€‚
+% 例ãˆã°ï¼Œä»®æƒ³ãƒœãƒ‡ã‚£ã®ä¸­å¤®
+% {\renewcommand{\jsTocLine}{\leaders \hbox {\hss ・\hss}\hfill}\jsTocLine}
+% ã«å¤‰æ›´ã—ãŸã„å ´åˆã¯
+%\begin{verbatim}
+% \renewcommand{\jsTocLine}{\leaders \hbox {\hss ・\hss}\hfill}
+%\end{verbatim}
+% ã¨ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\def\jsTocLine{\leaders\hbox{%
+ $\m@th \mkern \@dotsep mu\hbox{.}\mkern \@dotsep mu$}\hfill}
+\def\@dottedtocline#1#2#3#4#5{\ifnum #1>\c@tocdepth \else
+ \vskip \z@ \@plus.2\jsc@mpt
+ {\leftskip #2\relax \rightskip \@tocrmarg \parfillskip -\rightskip
+ \parindent #2\relax\@afterindenttrue
+ \interlinepenalty\@M
+ \leavevmode
+ \@lnumwidth #3\relax
+ \advance\leftskip \@lnumwidth \null\nobreak\hskip -\leftskip
+ {#4}\nobreak
+ \jsTocLine \nobreak\hb@xt@\@pnumwidth{%
+ \hfil\normalfont \normalcolor #5}\par}\fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \paragraph{図目次ã¨è¡¨ç›®æ¬¡}
+%
+% \begin{macro}{\listoffigures}
+%
+% 図目次を出力ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand{\listoffigures}{%
+%<*book|report>
+ \if@twocolumn\@restonecoltrue\onecolumn
+ \else\@restonecolfalse\fi
+ \chapter*{\listfigurename}%
+ \@mkboth{\listfigurename}{}%
+%</book|report>
+%<*!book&!report>
+ \section*{\listfigurename}%
+ \@mkboth{\listfigurename}{\listfigurename}%
+%</!book&!report>
+ \@starttoc{lof}%
+%<book|report> \if@restonecol\twocolumn\fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l@figure}
+%
+% 図目次ã®é …目を出力ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand*{\l@figure}{\@dottedtocline{1}{1\zw}{3.683\zw}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\listoftables}
+%
+% 表目次を出力ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand{\listoftables}{%
+%<*book|report>
+ \if@twocolumn\@restonecoltrue\onecolumn
+ \else\@restonecolfalse\fi
+ \chapter*{\listtablename}%
+ \@mkboth{\listtablename}{}%
+%</book|report>
+%<*!book&!report>
+ \section*{\listtablename}%
+ \@mkboth{\listtablename}{\listtablename}%
+%</!book&!report>
+ \@starttoc{lot}%
+%<book|report> \if@restonecol\twocolumn\fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l@table}
+%
+% 表目次ã¯å›³ç›®æ¬¡ã¨åŒã˜ã§ã™ã€‚
+%
+% \begin{macrocode}
+\let\l@table\l@figure
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{å‚考文献}
+%
+% \begin{macro}{\bibindent}
+%
+% オープンスタイルã®å‚考文献ã§ä½¿ã†ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆå¹…ã§ã™ã€‚
+% 元㯠1.5em ã§ã—ãŸã€‚
+%
+% \begin{macrocode}
+\newdimen\bibindent
+\setlength\bibindent{2\zw}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{thebibliography}
+%
+% å‚考文献リストを出力ã—ã¾ã™ã€‚
+%
+% [2016-07-16] \LaTeX~2.09ã§ä½¿ã‚ã‚Œã¦ã„ãŸãƒ•ã‚©ãƒ³ãƒˆã‚³ãƒžãƒ³ãƒ‰ã®è­¦å‘Šã‚’,
+% 文献スタイル(.bst)ã§ã¯ã‚ˆã |\bf| ãŒã„ã¾ã ã«ç”¨ã„られるã“ã¨ãŒå¤šã„ãŸã‚,
+% |thebibliography| 環境内ã§ã¯ä¾‹å¤–çš„ã«å‡ºã•ãªã„よã†ã«ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\newenvironment{thebibliography}[1]{%
+ \global\@jsc@warnoldfontcmdexceptiontrue
+ \global\let\presectionname\relax
+ \global\let\postsectionname\relax
+%<article|jspf> \section*{\refname}\@mkboth{\refname}{\refname}%
+%<*kiyou>
+ \vspace{1.5\baselineskip}
+ \subsubsection*{\refname}\@mkboth{\refname}{\refname}%
+ \vspace{0.5\baselineskip}
+%</kiyou>
+%<book|report> \chapter*{\bibname}\@mkboth{\bibname}{}%
+%<book|report> \addcontentsline{toc}{chapter}{\bibname}%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand\theenumiv{\@arabic\c@enumiv}}%
+%<kiyou> \small
+ \sloppy
+ \clubpenalty4000
+ \@clubpenalty\clubpenalty
+ \widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist
+ \global\@jsc@warnoldfontcmdexceptionfalse}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\newblock}
+%
+% |\newblock| ã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯å°ã•ãªã‚¹ãƒšãƒ¼ã‚¹ã‚’生æˆã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand{\newblock}{\hskip .11em\@plus.33em\@minus.07em}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@openbib@code}
+%
+% |\@openbib@code| ã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯ä½•ã‚‚ã—ã¾ã›ã‚“。
+% ã“ã®å®šç¾©ã¯ |openbib| オプションã«ã‚ˆã£ã¦å¤‰æ›´ã•ã‚Œã¾ã™ã€‚
+%
+% \begin{macrocode}
+\let\@openbib@code\@empty
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@biblabel}
+%
+% |\bibitem[...]| ã®ãƒ©ãƒ™ãƒ«ã‚’作りã¾ã™ã€‚
+% \texttt{ltbibl.dtx} ã®å®šç¾©ã®åŠè§’ [] を全角[]ã«å¤‰ãˆï¼Œ
+% 余分ãªã‚¹ãƒšãƒ¼ã‚¹ãŒå…¥ã‚‰ãªã„よã†ã« |\inhibitglue| ã§ã¯ã•ã¿ã¾ã—ãŸã€‚
+% ã¨ã‚Šã‚ãˆãšã‚³ãƒ¡ãƒ³ãƒˆã‚¢ã‚¦ãƒˆã—ã¦ãŠãã¾ã™ã®ã§ï¼Œå¿…è¦ã«å¿œã˜ã¦ç”Ÿã‹ã—ã¦ãã ã•ã„。
+%
+% \begin{macrocode}
+% \def\@biblabel#1{\inhibitglueï¼»#1ï¼½\inhibitglue}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cite}
+% \begin{macro}{\@cite}
+% \begin{macro}{\@citex}
+%
+% 文献ã®ç•ªå·ã‚’出力ã™ã‚‹éƒ¨åˆ†ã¯ \texttt{ltbibl.dtx} ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ãŒï¼Œ
+% コンマã¨ã‹ã£ã“を和文フォントã«ã™ã‚‹ã«ã¯æ¬¡ã®ã‚ˆã†ã«ã—ã¾ã™ã€‚
+% ã¨ã‚Šã‚ãˆãšã‚³ãƒ¡ãƒ³ãƒˆã‚¢ã‚¦ãƒˆã—ã¦ãŠãã¾ã—ãŸã®ã§ï¼Œå¿…è¦ã«å¿œã˜ã¦ç”Ÿã‹ã—ã¦ãã ã•ã„。
+% ã‹ã£ã“ã®å‰å¾Œã«å…¥ã‚‹ã‚°ãƒ«ãƒ¼ã‚’ |\inhibitglue| ã§å–ã£ã¦ã„ã¾ã™ã®ã§ï¼Œ
+% オリジナルåŒæ§˜ï¼Œ\verb*+Knuth~\cite{knu} + ã®ã‚ˆã†ã«åŠè§’空白
+% ã§å›²ã‚“ã§ãã ã•ã„。
+%
+% \begin{macrocode}
+% \def\@citex[#1]#2{\leavevmode
+% \let\@citea\@empty
+% \@cite{\@for\@citeb:=#2\do
+% {\@citea\def\@citea{,\inhibitglue\penalty\@m\ }%
+% \edef\@citeb{\expandafter\@firstofone\@citeb\@empty}%
+% \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi
+% \@ifundefined{b@\@citeb}{\mbox{\normalfont\bfseries ?}%
+% \G@refundefinedtrue
+% \@latex@warning
+% {Citation `\@citeb' on page \thepage \space undefined}}%
+% {\@cite@ofmt{\csname b@\@citeb\endcsname}}}}{#1}}
+% \def\@cite#1#2{\inhibitglue[{#1\if@tempswa ,#2\fi}]\inhibitglue}
+% \end{macrocode}
+%
+% 引用番å·ã‚’上ツキ㮠1)ã®ã‚ˆã†ãªã‚¹ã‚¿ã‚¤ãƒ«ã«ã™ã‚‹ã«ã¯æ¬¡ã®ã‚ˆã†ã«ã—ã¾ã™ã€‚
+% |\cite| ã®å…ˆé ­ã« |\unskip| を付ã‘ã¦å…ˆè¡Œã®ã‚¹ãƒšãƒ¼ã‚¹ï¼ˆ\verb|~| も)
+% を帳消ã—ã«ã—ã¦ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+% \DeclareRobustCommand\cite{\unskip
+% \@ifnextchar [{\@tempswatrue\@citex}{\@tempswafalse\@citex[]}}
+% \def\@cite#1#2{$^{\hbox{\scriptsize{#1\if@tempswa
+% ,\inhibitglue\ #2\fi})}}$}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{索引}
+%
+% \begin{environment}{theindex}
+%
+% 2〜3段組ã®ç´¢å¼•ã‚’作æˆã—ã¾ã™ã€‚
+% 最後ãŒå¶æ•°ãƒšãƒ¼ã‚¸ã®ã¨ãã«ãƒžãƒ¼ã‚¸ãƒ³ãŒãšã‚Œã‚‹ç¾è±¡ã‚’ç›´ã—ã¾ã—ãŸï¼ˆThanks: è—¤æ‘ã•ã‚“)。
+%
+% \begin{macrocode}
+\newenvironment{theindex}{% 索引を3段組ã§å‡ºåŠ›ã™ã‚‹ç’°å¢ƒ
+ \if@twocolumn
+ \onecolumn\@restonecolfalse
+ \else
+ \clearpage\@restonecoltrue
+ \fi
+ \columnseprule.4pt \columnsep 2\zw
+ \ifx\multicols\@undefined
+%<book|report> \twocolumn[\@makeschapterhead{\indexname}%
+%<book|report> \addcontentsline{toc}{chapter}{\indexname}]%
+%<!book&!report> \def\presectionname{}\def\postsectionname{}%
+%<!book&!report> \twocolumn[\section*{\indexname}]%
+ \else
+ \ifdim\textwidth<\fullwidth
+ \setlength{\evensidemargin}{\oddsidemargin}
+ \setlength{\textwidth}{\fullwidth}
+ \setlength{\linewidth}{\fullwidth}
+%<book|report> \begin{multicols}{3}[\chapter*{\indexname}%
+%<book|report> \addcontentsline{toc}{chapter}{\indexname}]%
+%<!book&!report> \def\presectionname{}\def\postsectionname{}%
+%<!book&!report> \begin{multicols}{3}[\section*{\indexname}]%
+ \else
+%<book|report> \begin{multicols}{2}[\chapter*{\indexname}%
+%<book|report> \addcontentsline{toc}{chapter}{\indexname}]%
+%<!book&!report> \def\presectionname{}\def\postsectionname{}%
+%<!book&!report> \begin{multicols}{2}[\section*{\indexname}]%
+ \fi
+ \fi
+%<book|report> \@mkboth{\indexname}{}%
+%<!book&!report> \@mkboth{\indexname}{\indexname}%
+ \plainifnotempty % \thispagestyle{plain}
+ \parindent\z@
+ \parskip\z@ \@plus .3\jsc@mpt\relax
+ \let\item\@idxitem
+ \raggedright
+ \footnotesize\narrowbaselines
+ }{
+ \ifx\multicols\@undefined
+ \if@restonecol\onecolumn\fi
+ \else
+ \end{multicols}
+ \fi
+ \clearpage
+ }
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\@idxitem}
+% \begin{macro}{\subitem}
+% \begin{macro}{\subsubitem}
+%
+% 索引項目ã®å­—下ã’å¹…ã§ã™ã€‚|\@idxitem| 㯠|\item| ã®é …ç›®ã®å­—下ã’å¹…ã§ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand{\@idxitem}{\par\hangindent 4\zw} % å…ƒ 40pt
+\newcommand{\subitem}{\@idxitem \hspace*{2\zw}} % å…ƒ 20pt
+\newcommand{\subsubitem}{\@idxitem \hspace*{3\zw}} % å…ƒ 30pt
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\indexspace}
+%
+% 索引ã§å…ˆé ­æ–‡å­—ã”ã¨ã®ãƒ–ロックã®é–“ã«å…¥ã‚‹ã‚¹ãƒšãƒ¼ã‚¹ã§ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand{\indexspace}{\par \vskip 10\jsc@mpt \@plus5\jsc@mpt \@minus3\jsc@mpt\relax}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seename}
+% \begin{macro}{\alsoname}
+%
+% 索引㮠|\see|,|\seealso| コマンドã§å‡ºåŠ›ã•ã‚Œã‚‹ã‚‚ã®ã§ã™ã€‚
+% デフォルトã¯ãã‚Œãžã‚Œ \emph{see},\emph{see also} ã¨ã„ã†è‹±èªžã§ã™ãŒï¼Œ
+% ã“ã“ã§ã¯ã¨ã‚Šã‚ãˆãšä¸¡æ–¹ã¨ã‚‚「→ã€ã«å¤‰ãˆã¾ã—ãŸã€‚
+% $\Rightarrow$(|$\Rightarrow$|)ãªã©ã§ã‚‚ã„ã„ã§ã—ょã†ã€‚
+%
+% \begin{macrocode}
+\newcommand\seename{\if@english see\else →\fi}
+\newcommand\alsoname{\if@english see also\else →\fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{脚注}
+%
+% \begin{macro}{\footnote}
+% \begin{macro}{\footnotemark}
+%
+% 和文ã®å¥èª­ç‚¹ãƒ»é–‰ã˜ã‹ã£ã“é¡žã®ç›´å¾Œã§ç”¨ã„ãŸéš›ã«
+% 余分ãªã‚¢ã‚­ãŒå…¥ã‚‹ã®ã‚’防ããŸã‚,
+% |\inhibitglue| を入れるã“ã¨ã«ã—ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\let\footnotes@ve=\footnote
+\def\footnote{\inhibitglue\footnotes@ve}
+\let\footnotemarks@ve=\footnotemark
+\def\footnotemark{\inhibitglue\footnotemarks@ve}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@makefnmark}
+%
+% 脚注番å·ã‚’付ã‘る命令ã§ã™ã€‚
+% ã“ã“ã§ã¯è„šæ³¨ç•ªå·ã®å‰ã«è¨˜å· $*$ を付ã‘ã¦ã„ã¾ã™ã€‚
+% 「注1ã€ã®å½¢å¼ã«ã™ã‚‹ã«ã¯ |\textasteriskcentered|
+% ã‚’ |注\kern0.1em| ã«ã—ã¦ãã ã•ã„。
+% |\@xfootnotenext| ã¨åˆã‚ã›ã¦ï¼Œ
+% ã‚‚ã—脚注番å·ãŒç©ºãªã‚‰è¨˜å·ã‚‚出力ã—ãªã„よã†ã«ã—ã¦ã‚ã‚Šã¾ã™ã€‚
+%
+% [2002-04-09] インプリメントã®ä»•æ–¹ã‚’変ãˆãŸãŸã‚消ã—ã¾ã—ãŸã€‚
+%
+% [2013-04-23] æ–°ã—ã„\pTeX ã§ã¯è„šæ³¨ç•ªå·ã®ã¾ã‚ã‚Šã«ã‚¹ãƒšãƒ¼ã‚¹ãŒå…¥ã‚Šã™ãŽã‚‹ã“ã¨ã‚’防ããŸã‚,
+% 北å·ã•ã‚“ã®ãƒ‘ッム[qa:57090] ã‚’å–ã‚Šè¾¼ã¿ã¾ã—ãŸã€‚
+%
+% [2013-05-14] plcore.ltx ã«å€£ã£ãŸå½¢ã«æ›¸ãç›´ã—ã¾ã—ãŸï¼ˆThanks: 北å·ã•ã‚“)。
+%
+% [2014-07-02 LTJ] |\ifydir| を使ã‚ãªã„å½¢ã«æ›¸æ›ãˆã¾ã—ãŸã€‚
+%
+% [2016-07-11] コミュニティ版p\LaTeX ã®å¤‰æ›´ã«è¿½éšã—ã¾ã—ãŸï¼ˆThanks: 角藤ã•ã‚“)。
+%
+% [2016-08-27 LTJ] çµæžœçš„ã« |\@makefnmark| ã®å®šç¾©ãŒ
+% Lua\TeX-ja本体(lltjcore.sty)中ã®ã‚‚ã®ã¨å…¨ãåŒã˜ã«ãªã£ã¦ã„ãŸã®ã§ï¼Œå‰Šé™¤ã—ã¾ã™ï¼Œ
+% \end{macro}
+%
+% \begin{macro}{\thefootnote}
+%
+% 脚注番å·ã« * å°ãŒä»˜ãよã†ã«ã—ã¾ã—ãŸã€‚
+% ãŸã ã—,番å·ãŒã‚¼ãƒ­ã®ã¨ã㯠* å°ã‚‚脚注番å·ã‚‚付ãã¾ã›ã‚“。
+%
+% [2003-08-15] |\textasteriskcentered| ã§ã¯ãƒ•ã‚©ãƒ³ãƒˆã«ã‚ˆã£ã¦
+% 下ãŒã‚Šã™ãŽã‚‹ã®ã§å¤‰æ›´ã—ã¾ã—ãŸã€‚
+%
+% [2016-10-08] TODO: 脚注番å·ãŒ |newtxtext| ã‚„ |newpxtext| ã®ä½¿ç”¨æ™‚ã«
+% ãŠã‹ã—ããªã£ã¦ã—ã¾ã„ã¾ã™ã€‚ã“れらã®ãƒ‘ッケージã¯å†…部㧠|\thefootnote| ã‚’
+% å†å®šç¾©ã—ã¦ã„ã¾ã™ã®ã§ï¼Œæ°—ã«ãªã‚‹å ´åˆã¯ãƒ‘ッケージを読ã¿è¾¼ã‚€ã¨ãã«
+% \texttt{defaultsups} オプションを付ã‘ã¦ãã ã•ã„(qa:57284, qa:57287)。
+%
+% \begin{macrocode}
+\def\thefootnote{\ifnum\c@footnote>\z@\leavevmode\lower.5ex\hbox{*}\@arabic\c@footnote\fi}
+% \end{macrocode}
+%
+% 「注1ã€ã®å½¢å¼ã«ã™ã‚‹ã«ã¯æ¬¡ã®ã‚ˆã†ã«ã—ã¦ãã ã•ã„。
+%
+% \begin{macrocode}
+% \def\thefootnote{\ifnum\c@footnote>\z@ 注\kern0.1\zw\@arabic\c@footnote\fi}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\footnoterule}
+%
+% 本文ã¨è„šæ³¨ã®é–“ã®ç½«ç·šã§ã™ã€‚
+%
+% \begin{macrocode}
+\renewcommand{\footnoterule}{%
+ \kern-3\jsc@mpt
+ \hrule width .4\columnwidth height 0.4\jsc@mpt
+ \kern 2.6\jsc@mpt}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c@footnote}
+%
+% 脚注番å·ã¯ç« ã”ã¨ã«ãƒªã‚»ãƒƒãƒˆã•ã‚Œã¾ã™ã€‚
+%
+% [2018-03-11] |\next|ãªã©ã„ãã¤ã‹ã®å†…部命令を |\jsc@...| 付ãã®
+% ユニークãªåå‰ã«ã—ã¾ã—ãŸã€‚
+% \begin{macrocode}
+%<book|report>\@addtoreset{footnote}{chapter}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@footnotetext}
+%
+% 脚注㧠|\verb| ãŒä½¿ãˆã‚‹ã‚ˆã†ã«æ”¹å¤‰ã—ã¦ã‚ã‚Šã¾ã™ã€‚
+% Jeremy Gibbons, \textit{\TeX\ and TUG NEWS},
+% Vol.~2, No.~4 (1993), p.~9)
+%
+% [2018-03-11] |\next|ãªã©ã„ãã¤ã‹ã®å†…部命令を |\jsc@...| 付ãã®
+% ユニークãªåå‰ã«ã—ã¾ã—ãŸã€‚
+% \begin{macrocode}
+\long\def\@footnotetext{%
+ \insert\footins\bgroup
+ \normalfont\footnotesize
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\footnotesep
+ \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
+ \hsize\columnwidth \@parboxrestore
+ \protected@edef\@currentlabel{%
+ \csname p@footnote\endcsname\@thefnmark
+ }%
+ \color@begingroup
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces}%
+ \futurelet\jsc@next\jsc@fo@t}
+\def\jsc@fo@t{\ifcat\bgroup\noexpand\jsc@next \let\jsc@next\jsc@f@@t
+ \else \let\jsc@next\jsc@f@t\fi \jsc@next}
+\def\jsc@f@@t{\bgroup\aftergroup\jsc@@foot\let\jsc@next}
+\def\jsc@f@t#1{#1\jsc@@foot}
+\def\jsc@@foot{\@finalstrut\strutbox\color@endgroup\egroup}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@makefntext}
+%
+% 実際ã«è„šæ³¨ã‚’出力ã™ã‚‹å‘½ä»¤ã§ã™ã€‚
+% |\@makefnmark| ã¯è„šæ³¨ã®ç•ªå·ã‚’出力ã™ã‚‹å‘½ä»¤ã§ã™ã€‚
+% ã“ã“ã§ã¯è„šæ³¨ãŒå·¦ç«¯ã‹ã‚‰ä¸€å®šè·é›¢ã«æ¥ã‚‹ã‚ˆã†ã«ã—ã¦ã‚ã‚Šã¾ã™ã€‚
+%
+% \begin{macrocode}
+\newcommand\@makefntext[1]{%
+ \advance\leftskip 3\zw
+ \parindent 1\zw
+ \noindent
+ \llap{\@makefnmark\hskip0.3\zw}#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@xfootnotenext}
+%
+% 最åˆã® |\footnotetext{...}| ã¯ç•ªå·ãŒä»˜ãã¾ã›ã‚“。
+% 著者ã®æ‰€å±žãªã©ã‚’脚注ã®æ¬„ã«æ›¸ãã¨ãã«ä¾¿åˆ©ã§ã™ã€‚
+%
+% ã™ã§ã« |\footnote| を使ã£ãŸå¾Œãªã‚‰ |\footnotetext[0]{...}|
+% ã¨ã™ã‚Œã°ç•ªå·ã‚’付ã‘ãªã„脚注ã«ãªã‚Šã¾ã™ã€‚
+% ãŸã ã—,ã“ã®å ´åˆã¯è„šæ³¨ç•ªå·ãŒãƒªã‚»ãƒƒãƒˆã•ã‚Œã¦ã—ã¾ã†ã®ã§ï¼Œ
+% 工夫ãŒå¿…è¦ã§ã™ã€‚
+%
+% [2002-04-09] インプリメントã®ä»•æ–¹ã‚’変ãˆãŸãŸã‚消ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+% \def\@xfootnotenext[#1]{%
+% \begingroup
+% \ifnum#1>\z@
+% \csname c@\@mpfn\endcsname #1\relax
+% \unrestored@protected@xdef\@thefnmark{\thempfn}%
+% \else
+% \unrestored@protected@xdef\@thefnmark{}%
+% \fi
+% \endgroup
+% \@footnotetext}
+% \end{macrocode}
+% \end{macro}
+%
+% \section{段è½ã®é ­ã¸ã®ã‚°ãƒ«ãƒ¼æŒ¿å…¥ç¦æ­¢}
+%
+% 段è½é ­ã®ã‹ãŽã‹ã£ã“ãªã©ã‚’見ã‹ã‘1å­—åŠä¸‹ã’ã‹ã‚‰å…¨è§’1字下ã’ã«ç›´ã—ã¾ã™ã€‚
+%
+% [2012-04-24 LTJ] Lua\TeX-jaã§ã¯JFMã«æ®µè½é–‹å§‹æ™‚ã®æ‹¬å¼§é¡žã®å­—下ã’幅をコントロール
+% ã™ã‚‹æ©Ÿèƒ½ãŒã‚ã‚Šã¾ã™ãŒï¼Œ|\item| 直後ã§ã¯ãƒ©ãƒ™ãƒ«ç”¨ã®ãƒœãƒƒã‚¯ã‚¹ãŒæ®µè½å…ˆé ­ã«ãªã‚‹
+% ãŸã‚,ã†ã¾ãåƒãã¾ã›ã‚“ã§ã—ãŸã€‚形を変ãˆã¦å¾©æ´»ã•ã›ã¾ã™ã€‚
+%
+% [2017-04-03 LTJ] 従æ¥ã‚¯ãƒ©ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã§å®šç¾©ã—ã¦ã„㟠|\@inhibitglue| ã¯ï¼Œ
+% Lua\TeX-jaã®ã‚³ã‚¢ã« |\ltjfakeparbegin| ã¨ã—ã¦æ­£å¼ã«è¿½åŠ ã•ã‚ŒãŸã®ã§ãƒªãƒãƒ¼ãƒ ã—ã¾ã™ï¼Ž
+%
+% |\item| 命令ã®ç›´å¾Œã§ã™ã€‚
+%
+% \begin{macrocode}
+\let\@inhibitglue=\ltjfakeparbegin
+\def\@item[#1]{%
+ \if@noparitem
+ \@donoparitem
+ \else
+ \if@inlabel
+ \indent \par
+ \fi
+ \ifhmode
+ \unskip\unskip \par
+ \fi
+ \if@newlist
+ \if@nobreak
+ \@nbitem
+ \else
+ \addpenalty\@beginparpenalty
+ \addvspace\@topsep
+ \addvspace{-\parskip}%
+ \fi
+ \else
+ \addpenalty\@itempenalty
+ \addvspace\itemsep
+ \fi
+ \global\@inlabeltrue
+ \fi
+ \everypar{%
+ \@minipagefalse
+ \global\@newlistfalse
+ \if@inlabel
+ \global\@inlabelfalse
+ {\setbox\z@\lastbox
+ \ifvoid\z@
+ \kern-\itemindent
+ \fi}%
+ \box\@labels
+ \penalty\z@
+ \fi
+ \if@nobreak
+ \@nobreakfalse
+ \clubpenalty \@M
+ \else
+ \clubpenalty \@clubpenalty
+ \everypar{}%
+ \fi\ltjfakeparbegin}%
+ \if@noitemarg
+ \@noitemargfalse
+ \if@nmbrlist
+ \refstepcounter\@listctr
+ \fi
+ \fi
+ \sbox\@tempboxa{\makelabel{#1}}%
+ \global\setbox\@labels\hbox{%
+ \unhbox\@labels
+ \hskip \itemindent
+ \hskip -\labelwidth
+ \hskip -\labelsep
+ \ifdim \wd\@tempboxa >\labelwidth
+ \box\@tempboxa
+ \else
+ \hbox to\labelwidth {\unhbox\@tempboxa}%
+ \fi
+ \hskip \labelsep}%
+ \ignorespaces}
+% \end{macrocode}
+%
+% |\@gnewline| ã«ã¤ã„ã¦ã¯ã¡ã‚‡ã£ã¨è¤‡é›‘ãªå¿ƒå¢ƒã§ã™ã€‚
+% ã‚‚ã¨ã‚‚ã¨ã®p\LaTeXe ã¯æ®µè½ã®é ­ã«ã‚°ãƒ«ãƒ¼ãŒå…¥ã‚‹æ–¹ã§çµ±ä¸€ã•ã‚Œã¦ã„ã¾ã—ãŸã€‚
+% ã—ã‹ã— |\\| ã®ç›´å¾Œã«ã¯ã‚°ãƒ«ãƒ¼ãŒå…¥ã‚‰ãšï¼Œä¸çµ±ä¸€ã§ã—ãŸã€‚
+% ãã“㧠|\\| ã®ç›´å¾Œã«ã‚‚グルーを入れるよã†ã«ç›´ã—ã¦ã„ãŸã ã„ãŸçµŒç·¯ãŒã‚ã‚Šã¾ã™ã€‚
+% ã—ã‹ã—,ã“ã“ã§ã¯é€†ã«ã‚°ãƒ«ãƒ¼ã‚’入れãªã„æ–¹ã§çµ±ä¸€ã—ãŸã„ã®ã§ï¼Œ
+% ã¾ãŸå…ƒã«æˆ»ã—ã¦ã—ã¾ã„ã¾ã—ãŸã€‚
+%
+% ã—ã‹ã—å˜ã«æˆ»ã™ã ã‘ã§ã‚‚駄目ã¿ãŸã„ãªã®ã§ï¼Œã“ã“ã§ã‚‚最後ã«ã‚°ãƒ«ãƒ¼ã‚’消ã—ã¦ãŠãã¾ã™ã€‚
+%
+% [2016-12-05 LTJ] 本家[2016-11-29],lltjcore.styã§ã®å¤‰æ›´ã«è¿½å¾“ã•ã›ã¾ã™ï¼Ž
+%
+% [2017-02-18 LTJ] lltjcore.styå´ã§æˆ»ã—ãŸã®ã‚’忘れã¦ã„ã¾ã—ãŸï¼Ž
+% \begin{macrocode}
+\def\@gnewline #1{%
+ \ifvmode
+ \@nolnerr
+ \else
+ \unskip \reserved@e {\reserved@f#1}\nobreak \hfil \break \null
+ \inhibitglue \ignorespaces
+ \fi}
+% \end{macrocode}
+%
+% \section{ã„ã‚ã„ã‚ãªãƒ­ã‚´}
+%
+% \LaTeX 関連ã®ãƒ­ã‚´ã‚’作り直ã—ã¾ã™ã€‚
+%
+% [2016-07-14] ロゴã®å®šç¾©ã¯\texttt{jslogo}パッケージã«ç§»è»¢ã—ã¾ã—ãŸã€‚
+% 後方互æ›ã®ãŸã‚,\texttt{jsclasses}ã§ã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã“れを読ã¿è¾¼ã¿ã¾ã™ã€‚
+% \texttt{nojslogo}オプションãŒæŒ‡å®šã•ã‚Œã¦ã„ã‚‹å ´åˆã¯èª­ã¿è¾¼ã¿ã¾ã›ã‚“。
+%
+% [2016-07-21 LTJ] \texttt{jsclasses} ã¨Lua\TeX-jaã®æ›´æ–°ã‚¿ã‚¤ãƒŸãƒ³ã‚°ãŒä¸€è‡´ã—ãªã„å¯èƒ½æ€§ã‚’考慮ã—,
+% \texttt{jslogo}パッケージãŒå­˜åœ¨ã—ãªã„å ´åˆã¯æ—§æ¥ã®å®šç¾©ã‚’ãã®ã¾ã¾ä½¿ã†ã“ã¨ã«ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\IfFileExists{jslogo.sty}{}{\@jslogofalse}%
+\if@jslogo
+ \RequirePackage{jslogo}
+ \def\å°{\jslg@small}
+ \def\上å°{\jslg@uppersmall}
+\else
+% \end{macrocode}
+%
+% 以下ã¯\texttt{jslogo}パッケージãŒãªã„å ´åˆã®å®šç¾©ã§ã™ã€‚
+%
+% \begin{macro}{\å°}
+% \begin{macro}{\上å°}
+%
+% 文字をå°ã•ã‚ã«å‡ºã—ãŸã‚Šä¸Šå¯„ã‚Šã«å°ã•ã‚ã«å‡ºã—ãŸã‚Šã™ã‚‹å‘½ä»¤ã§ã™ã€‚
+%
+% \begin{macrocode}
+\def\å°#1{\hbox{$\m@th$%
+ \csname S@\f@size\endcsname
+ \fontsize\sf@size\z@
+ \math@fontsfalse\selectfont
+ #1}}
+\def\上å°#1{{\sbox\z@ T\vbox to\ht0{\å°{#1}\vss}}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\TeX}
+% \begin{macro}{\LaTeX}
+%
+% ã“れら㯠\texttt{ltlogos.dtx} ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ãŒï¼Œ
+% Timesã‚„Helveticaã§ã‚‚見栄ãˆãŒã™ã‚‹ã‚ˆã†ã«è‹¥å¹²å¤‰æ›´ã—ã¾ã—ãŸã€‚
+%
+% [2003-06-12] Palatinoも加ãˆã¾ã—ãŸï¼ˆè¦èª¿æ•´ï¼‰ã€‚
+%
+% \begin{macrocode}
+\def\cmrTeX{%
+ \ifdim \fontdimen\@ne\font >\z@
+ T\kern-.25em\lower.5ex\hbox{E}\kern-.125emX\@
+ \else
+ T\kern-.1667em\lower.5ex\hbox{E}\kern-.125emX\@
+ \fi}
+\def\cmrLaTeX{%
+ \ifdim \fontdimen\@ne\font >\z@
+ L\kern-.32em\上å°{A}\kern-.22em\cmrTeX
+ \else
+ L\kern-.36em\上å°{A}\kern-.15em\cmrTeX
+ \fi}
+\def\sfTeX{T\kern-.1em\lower.4ex\hbox{E}\kern-.07emX\@}
+\def\sfLaTeX{L\kern-.25em\上å°{A}\kern-.08em\sfTeX}
+\def\ptmTeX{%
+ \ifdim \fontdimen\@ne\font >\z@
+ T\kern-.12em\lower.37ex\hbox{E}\kern-.02emX\@
+ \else
+ T\kern-.07em\lower.37ex\hbox{E}\kern-.05emX\@
+ \fi}
+\def\ptmLaTeX{%
+ \ifdim \fontdimen\@ne\font >\z@
+ L\kern-.2em\上å°{A}\kern-.1em\ptmTeX
+ \else
+ L\kern-.3em\上å°{A}\kern-.1em\ptmTeX
+ \fi}
+\def\pncTeX{%
+ \ifdim \fontdimen\@ne\font >\z@
+ T\kern-.2em\lower.5ex\hbox{E}\kern-.08emX\@
+ \else
+ T\kern-.13em\lower.5ex\hbox{E}\kern-.13emX\@
+ \fi}
+\def\pncLaTeX{%
+ \ifdim \fontdimen\@ne\font >\z@
+ L\kern-.3em\上å°{A}\kern-.1em\pncTeX
+ \else
+ L\kern-.3em\上å°{A}\kern-.1em\pncTeX
+ \fi}
+\def\pplTeX{%
+ \ifdim \fontdimen\@ne\font >\z@
+ T\kern-.17em\lower.32ex\hbox{E}\kern-.15emX\@
+ \else
+ T\kern-.12em\lower.34ex\hbox{E}\kern-.1emX\@
+ \fi}
+\def\pplLaTeX{%
+ \ifdim \fontdimen\@ne\font >\z@
+ L\kern-.27em\上å°{A}\kern-.12em\pplTeX
+ \else
+ L\kern-.3em\上å°{A}\kern-.15em\pplTeX
+ \fi}
+\def\ugmTeX{%
+ \ifdim \fontdimen\@ne\font >\z@
+ T\kern-.1em\lower.32ex\hbox{E}\kern-.06emX\@
+ \else
+ T\kern-.12em\lower.34ex\hbox{E}\kern-.1emX\@
+ \fi}
+\def\ugmLaTeX{%
+ \ifdim \fontdimen\@ne\font >\z@
+ L\kern-.2em\上å°{A}\kern-.13em\ugmTeX
+ \else
+ L\kern-.3em\上å°{A}\kern-.13em\ugmTeX
+ \fi}
+\DeclareRobustCommand{\TeX}{%
+ \def\@tempa{cmr}%
+ \ifx\f@family\@tempa\cmrTeX
+ \else
+ \def\@tempa{ptm}%
+ \ifx\f@family\@tempa\ptmTeX
+ \else
+ \def\@tempa{txr}%
+ \ifx\f@family\@tempa\ptmTeX
+ \else
+ \def\@tempa{pnc}%
+ \ifx\f@family\@tempa\pncTeX
+ \else
+ \def\@tempa{ppl}%
+ \ifx\f@family\@tempa\pplTeX
+ \else
+ \def\@tempa{ugm}%
+ \ifx\f@family\@tempa\ugmTeX
+ \else\sfTeX
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi}
+
+\DeclareRobustCommand{\LaTeX}{%
+ \def\@tempa{cmr}%
+ \ifx\f@family\@tempa\cmrLaTeX
+ \else
+ \def\@tempa{ptm}%
+ \ifx\f@family\@tempa\ptmLaTeX
+ \else
+ \def\@tempa{txr}%
+ \ifx\f@family\@tempa\ptmLaTeX
+ \else
+ \def\@tempa{pnc}%
+ \ifx\f@family\@tempa\pncLaTeX
+ \else
+ \def\@tempa{ppl}%
+ \ifx\f@family\@tempa\pplLaTeX
+ \else
+ \def\@tempa{ugm}%
+ \ifx\f@family\@tempa\ugmLaTeX
+ \else\sfLaTeX
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi}
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\LaTeXe}
+%
+% |\LaTeXe| コマンド㮠|\mbox{\m@th ...| ã§å§‹ã¾ã‚‹æ–°ã—ã„定義ã§ã¯
+% 直後ã®å’Œæ–‡ã¨ã®é–“ã« |xkanjiskip| ãŒå…¥ã‚Šã¾ã›ã‚“。ã¾ãŸï¼Œ
+% |mathptmx| パッケージãªã©ã¨ä½µç”¨ã™ã‚‹ã¨ï¼Œæœ€å¾Œã® $\varepsilon$ ãŒ
+% 下ãŒã‚Šã™ãŽã¦ã—ã¾ã„ã¾ã™ã€‚ãã®ãŸã‚,ã¡ã‚‡ã£ã¨æ‰‹ã‚’加ãˆã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+\DeclareRobustCommand{\LaTeXe}{$\mbox{%
+ \if b\expandafter\@car\f@series\@nil\boldmath\fi
+ \LaTeX\kern.15em2\raisebox{-.37ex}{$\textstyle\varepsilon$}}$}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pTeX}
+% \begin{macro}{\pLaTeX}
+% \begin{macro}{\pLaTeXe}
+%
+% \pTeX ,\pLaTeXe ã®ãƒ­ã‚´ã‚’出ã™å‘½ä»¤ã§ã™ã€‚
+%
+% \begin{macrocode}
+\def\pTeX{p\kern-.05em\TeX}
+\def\pLaTeX{p\LaTeX}
+\def\pLaTeXe{p\LaTeXe}
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\AmSTeX}
+%
+% \texttt{amstex.sty} ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚
+%
+% \begin{macrocode}
+\def\AmSTeX{\protect\AmS-\protect\TeX{}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\BibTeX}
+% \begin{macro}{\SliTeX}
+%
+% ã“れら㯠\texttt{doc.dtx} ã‹ã‚‰å–ã£ãŸã‚‚ã®ã§ã™ã€‚
+% ãŸã ã—,|\BibTeX| ã ã‘ã¯ã¡ã‚‡ã£ã¨ä¿®æ­£ã—ã¾ã—ãŸã€‚
+%
+% \begin{macrocode}
+% \@ifundefined{BibTeX}
+% {\def\BibTeX{{\rmfamily B\kern-.05em%
+% \textsc{i\kern-.025em b}\kern-.08em%
+% T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}}}{}
+\DeclareRobustCommand{\BibTeX}{B\kern-.05em\å°{I\kern-.025em B}%
+ \ifx\f@family\cmr\kern-.08em\else\kern-.15em\fi\TeX}
+\DeclareRobustCommand{\SliTeX}{%
+ S\kern-.06emL\kern-.18em\上å°{I}\kern -.03em\TeX}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \texttt{jslogo}パッケージãŒãªã„å ´åˆã®å®šç¾©ã¯ã“ã“ã§çµ‚ã‚ã‚Šã§ã™ã€‚
+% \begin{macrocode}
+\fi
+% \end{macrocode}
+%
+% \section{åˆæœŸè¨­å®š}
+%
+% \paragraph{ã„ã‚ã„ã‚ãªèªž}
+%
+% \begin{macro}{\prepartname}
+% \begin{macro}{\postpartname}
+% \begin{macro}{\prechaptername}
+% \begin{macro}{\postchaptername}
+% \begin{macro}{\presectionname}
+% \begin{macro}{\postsectionname}
+% \begin{macrocode}
+\newcommand{\prepartname}{\if@english Part~\else 第\fi}
+\newcommand{\postpartname}{\if@english\else 部\fi}
+%<book|report>\newcommand{\prechaptername}{\if@english Chapter~\else 第\fi}
+%<book|report>\newcommand{\postchaptername}{\if@english\else ç« \fi}
+\newcommand{\presectionname}{}% 第
+\newcommand{\postsectionname}{}% 節
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\contentsname}
+% \begin{macro}{\listfigurename}
+% \begin{macro}{\listtablename}
+% \begin{macrocode}
+\newcommand{\contentsname}{\if@english Contents\else 目次\fi}
+\newcommand{\listfigurename}{\if@english List of Figures\else 図目次\fi}
+\newcommand{\listtablename}{\if@english List of Tables\else 表目次\fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\refname}
+% \begin{macro}{\bibname}
+% \begin{macro}{\indexname}
+% \begin{macrocode}
+\newcommand{\refname}{\if@english References\else å‚考文献\fi}
+\newcommand{\bibname}{\if@english Bibliography\else å‚考文献\fi}
+\newcommand{\indexname}{\if@english Index\else 索引\fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\figurename}
+% \begin{macro}{\tablename}
+% \begin{macrocode}
+%<!jspf>\newcommand{\figurename}{\if@english Fig.~\else 図\fi}
+%<jspf>\newcommand{\figurename}{Fig.~}
+%<!jspf>\newcommand{\tablename}{\if@english Table~\else 表\fi}
+%<jspf>\newcommand{\tablename}{Table~}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\appendixname}
+% \begin{macro}{\abstractname}
+% \begin{macrocode}
+% \newcommand{\appendixname}{\if@english Appendix~\else 付録\fi}
+\newcommand{\appendixname}{\if@english \else 付録\fi}
+%<!book>\newcommand{\abstractname}{\if@english Abstract\else 概è¦\fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \paragraph{今日ã®æ—¥ä»˜}
+%
+% \LaTeX ã§å‡¦ç†ã—ãŸæ—¥ä»˜ã‚’出力ã—ã¾ã™ã€‚
+% ^^A |jarticle| ãªã©ã¨é•ã£ã¦ï¼Œæ¨™æº–を西暦ã«ã—,
+% ^^A 余分ãªç©ºç™½ãŒå…¥ã‚‰ãªã„よã†ã«æ”¹è‰¯ã—ã¾ã—ãŸã€‚
+% ^^A -- 2018å¹´7月以é™ã¯ |jarticle| ãªã©ã‚‚標準ãŒè¥¿æš¦ï¼Œ
+% ^^A -- 2019å¹´4月以é™ã¯ä½™åˆ†ãªç©ºç™½ãŒå…¥ã‚‰ãªããªã£ã¦ã„ã¾ã™ã€‚
+% 和暦ã«ã™ã‚‹ã«ã¯ |\和暦| ã¨æ›¸ã„ã¦ãã ã•ã„。
+% ã¡ãªã¿ã«ã“ã®æ–‡ç« ã®ä½œæˆæ—¥ã¯è¥¿æš¦ã§ã¯{\西暦\today}ã§ï¼Œ
+% 和暦ã§ã¯{\和暦\today}ã§ã™ã€‚
+%
+% \begin{macro}{\today}
+% \begin{macrocode}
+\newif\if西暦 \西暦true
+\def\西暦{\西暦true}
+\def\和暦{\西暦false}
+\newcount\heisei \heisei\year \advance\heisei-1988\relax
+\def\pltx@today@year@#1{%
+ \ifnum\numexpr\year-#1=1 å…ƒ\else
+ \ifnum\ltjgetparameter{direction}=3
+ \kansuji\numexpr\year-#1\relax
+ \else
+ \number\numexpr\year-#1\relax\nobreak
+ \fi
+ \fi å¹´
+}
+\def\pltx@today@year{%
+ \ifnum\numexpr\year*10000+\month*100+\day<19890108
+ 昭和\pltx@today@year@{1925}%
+ \else\ifnum\numexpr\year*10000+\month*100+\day<20190501
+ å¹³æˆ\pltx@today@year@{1988}%
+ \else
+ 令和\pltx@today@year@{2018}%
+ \fi\fi}
+\def\today{%
+ \if@english
+ \ifcase\month\or
+ January\or February\or March\or April\or May\or June\or
+ July\or August\or September\or October\or November\or December\fi
+ \space\number\day, \number\year
+ \else\if西暦
+ \ifnum\ltjgetparameter{direction}=3 \kansuji\year
+ \else\number\year\nobreak\fi å¹´
+ \else
+ \pltx@today@year
+ \fi
+ \ifnum\ltjgetparameter{direction}=3
+ \kansuji\month 月
+ \kansuji\day æ—¥
+ \else
+ \number\month\nobreak 月
+ \number\day\nobreak æ—¥
+ \fi\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{ãƒã‚¤ãƒ•ãƒãƒ¼ã‚·ãƒ§ãƒ³ä¾‹å¤–}
+%
+% \TeX ã®ãƒã‚¤ãƒ•ãƒãƒ¼ã‚·ãƒ§ãƒ³ãƒ«ãƒ¼ãƒ«ã®è£œè¶³ã§ã™ï¼ˆãƒšãƒ³ãƒ‡ã‚£ãƒ³ã‚°ï¼šeng-lish)
+%
+% \begin{macrocode}
+\hyphenation{ado-be post-script ghost-script phe-nom-e-no-log-i-cal man-u-script}
+% \end{macrocode}
+%
+% \paragraph{ページ設定}
+%
+% ページ設定ã®åˆæœŸåŒ–ã§ã™ã€‚
+% |stfloats|パッケージãŒã‚·ã‚¹ãƒ†ãƒ ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã‚‹å ´åˆã¯ã€ã“ã®ãƒ‘ッケージを使ã£ã¦
+% \pLaTeX ã®æ¨™æº–時ã¨åŒã˜ã‚ˆã†ã«ãƒœãƒˆãƒ ãƒ•ãƒ­ãƒ¼ãƒˆã®ä¸‹ã«è„šæ³¨ãŒçµ„ã¾ã‚Œã‚‹ã‚ˆã†ã«ã—ã¾ã™ã€‚
+%
+% [2017-02-19] \pLaTeX ã¨Lua\TeX-jaã®|\@makecol|ãŒé•ã†ã“ã¨ã‚’
+% 考慮ã—ã¦ã„ã¾ã›ã‚“ã§ã—ãŸã€‚
+% \begin{macrocode}
+%<article>\if@slide \pagestyle{empty} \else \pagestyle{plain} \fi
+%<book>\if@report \pagestyle{plain} \else \pagestyle{headings} \fi
+%<report|kiyou>\pagestyle{plain}
+%<jspf>\pagestyle{headings}
+\pagenumbering{arabic}
+\fnfixbottomtrue % 2017-02-19
+\IfFileExists{stfloats.sty}{\RequirePackage{stfloats}\fnbelowfloat}{}
+\if@twocolumn
+ \twocolumn
+ \sloppy
+ \flushbottom
+\else
+ \onecolumn
+ \raggedbottom
+\fi
+\if@slide
+ \renewcommand\kanjifamilydefault{\gtdefault}
+ \renewcommand\familydefault{\sfdefault}
+ \raggedright
+ \ltj@setpar@global
+ \ltjsetxkanjiskip0.1em\relax
+\fi
+% \end{macrocode}
+%
+% 以上ã§ã™ã€‚
+%
+% \Finale
+%
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/ltjsclasses.ins b/macros/luatex/generic/luatexja/src/ltjsclasses.ins
new file mode 100644
index 0000000000..957178678c
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/ltjsclasses.ins
@@ -0,0 +1,13 @@
+%
+% ltjsclasses.ins
+%
+
+\input docstrip.tex
+\keepsilent
+\generateFile{ltjsarticle.cls}{f}{\from{ltjsclasses.dtx}{article}}
+\generateFile{ltjsbook.cls}{f}{\from{ltjsclasses.dtx}{book}}
+\generateFile{ltjsreport.cls}{f}{\from{ltjsclasses.dtx}{report}}
+\generateFile{ltjspf.cls}{f}{\from{ltjsclasses.dtx}{jspf}}
+\generateFile{ltjskiyou.cls}{f}{\from{ltjsclasses.dtx}{kiyou}}
+
+\endbatchfile
diff --git a/macros/luatex/generic/luatexja/src/luatexja-compat.sty b/macros/luatex/generic/luatexja/src/luatexja-compat.sty
new file mode 100644
index 0000000000..f55bf51114
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/luatexja-compat.sty
@@ -0,0 +1,140 @@
+%
+% luatexja-compat.sty
+%
+
+%! 外ã‹ã‚‰èª­ã¾ã‚Œã‚‹ã®ã§ä»°ã€…ã—ããªã£ã¦ã¾ã™
+%% Avoid multiple loading.
+\csname\if11luatexjacompatLoaded\fi\endcsname
+\edef\x{%
+\catcode32=\the\catcode32%
+\catcode33=\the\catcode33%
+\catcode35=\the\catcode35%
+\catcode40=\the\catcode40%
+\catcode41=\the\catcode41%
+\catcode42=\the\catcode42%
+\catcode43=\the\catcode43%
+\catcode44=\the\catcode44%
+\catcode45=\the\catcode45%
+\catcode46=\the\catcode46%
+\catcode58=\the\catcode58%
+\catcode59=\the\catcode59%
+\catcode60=\the\catcode60%
+\catcode61=\the\catcode61%
+\catcode62=\the\catcode62%
+\catcode64=\the\catcode64%
+\catcode91=\the\catcode91%
+\catcode93=\the\catcode93%
+\catcode94=\the\catcode94%
+\catcode95=\the\catcode95%
+\catcode126=\the\catcode126%
+\endlinechar=\the\endlinechar
+\relax}
+\catcode32=10 %< >
+\catcode33=12 %<">
+\catcode35=6 %<#>
+\catcode40=12 %<(>
+\catcode41=12 %<)>
+\catcode42=12 %<*>
+\catcode43=12 %<+>
+\catcode44=12 %<,>
+\catcode45=12 %<->
+\catcode46=12 %<.>
+\catcode58=12 %<:>
+\catcode59=12 %<;>
+\catcode60=12 %<<>
+\catcode61=12 %<=>
+\catcode62=12 %<>>
+\catcode64=11 %<@>
+\catcode91=12 %<[>
+\catcode93=12 %<]>
+\catcode94=7 %<^>
+\catcode95=8 %<_>
+\catcode126=13 %<~>
+\endlinechar=-1 %
+%! ãªãŠ, 上ã®catcode設定ã¯coreã¨compatã§åŒä¸€ã«ã—ã¦ãŠã.
+\edef\ltj@compat@AtEnd{\x
+ \noexpand\let\noexpand\ltj@compat@AtEnd\relax}
+\def\luatexjacompatLoaded{\endinput}
+
+%% Check if LaTeX is used.
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax %<*!LaTeX>
+ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname
+ \csname iffalse\endcsname
+\else %<*LaTeX>
+ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname
+ \csname iftrue\endcsname
+ \NeedsTeXFormat{LaTeX2e}
+ \ProvidesPackage{luatexja-compat}[2018/03/29 Compatibility with pTeX]
+\fi %</LaTeX>
+
+% Load core module if not yet.
+\ifx\luatexjacoreLoaded\@undefined
+ \ifltj@in@latex %<*LaTeX>
+ \RequirePackage{luatexja-core}
+ \else %<*!LaTeX>
+ \input luatexja-core.sty %
+ \fi %</LaTeX>
+\fi
+
+%% When environment check fails, exit now.
+\ifx\LuaTeXjaAvailable\@undefined
+ \ltj@compat@AtEnd
+\expandafter\endinput\fi\relax
+
+%% Load Lua modules.
+%\RequireLuaModule{luatexja.infomute}
+% not yet implemented.
+
+%% Silence info messages of luatexbase-mcb
+%\directlua{ luatexja.infomute.add_mute("luatexbase-mcb") }
+% not yet implemented.
+
+%%------------------
+\RequireLuaTeXjaSubmodule{compat}
+
+\def\euc{\ltj@code@conv{euc}}
+\def\kuten{\ltj@code@conv{kuten}}
+\def\jis{\ltj@code@conv{jis}}
+\def\sjis{\ltj@code@conv{sjis}}
+\def\ucs{\ltj@code@conv{ucs}}
+
+\def\ltj@code@conv#1{%
+ \directlua{luatexja.compat.from_#1(token.scan_int())}%
+}
+
+\def\kansuji{%
+ \directlua{luatexja.compat.to_kansuji(token.scan_int())}%
+}
+
+\define@key[ltj]{japaram}{kansujichar}{\ltj@@set@stack{KSJ}{0}{0x7FFFFFFF}#1 }
+
+\ltjsetparameter{kansujichar={0,`〇}}
+\ltjsetparameter{kansujichar={1,`一}}
+\ltjsetparameter{kansujichar={2,`二}}
+\ltjsetparameter{kansujichar={3,`三}}
+\ltjsetparameter{kansujichar={4,`å››}}
+\ltjsetparameter{kansujichar={5,`五}}
+\ltjsetparameter{kansujichar={6,`å…­}}
+\ltjsetparameter{kansujichar={7,`七}}
+\ltjsetparameter{kansujichar={8,`å…«}}
+\ltjsetparameter{kansujichar={9,`ä¹}}
+\ltj@@decl@array@param{kansujichar}
+
+\ifltj@in@latex
+% \pltx@next@inhibitglue (pLaTeX 2018-03-09)
+\protected\def\pltx@next@inhibitglue{%
+ \ifhmode\inhibitglue\else
+ \edef\@tempa{\everypar{%
+ \everypar{\unexpanded\expandafter{\the\everypar}}%
+ \unexpanded\expandafter{\the\everypar}\inhibitglue}}%
+\@tempa\fi}
+ \newcommand\printglossary{\@input@{\jobname.gls}}
+\csname newcount\endcsname\hour
+\csname newcount\endcsname\minute
+\fi
+
+%%------------------ all done
+\ltj@compat@AtEnd
+\endinput
+%% EOF
diff --git a/macros/luatex/generic/luatexja/src/luatexja-core.sty b/macros/luatex/generic/luatexja/src/luatexja-core.sty
new file mode 100644
index 0000000000..ba13695352
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/luatexja-core.sty
@@ -0,0 +1,742 @@
+%
+% luatexja-core.sty
+%
+
+%! 外ã‹ã‚‰èª­ã¾ã‚Œã‚‹ã®ã§ä»°ã€…ã—ããªã£ã¦ã¾ã™
+%% Avoid multiple loading.
+\csname\if11luatexjacoreLoaded\fi\endcsname
+\edef\x{%
+\catcode32=\the\catcode32%
+\catcode33=\the\catcode33%
+\catcode35=\the\catcode35%
+\catcode40=\the\catcode40%
+\catcode41=\the\catcode41%
+\catcode42=\the\catcode42%
+\catcode43=\the\catcode43%
+\catcode44=\the\catcode44%
+\catcode45=\the\catcode45%
+\catcode46=\the\catcode46%
+\catcode58=\the\catcode58%
+\catcode59=\the\catcode59%
+\catcode60=\the\catcode60%
+\catcode61=\the\catcode61%
+\catcode62=\the\catcode62%
+\catcode64=\the\catcode64%
+\catcode91=\the\catcode91%
+\catcode93=\the\catcode93%
+\catcode94=\the\catcode94%
+\catcode95=\the\catcode95%
+\catcode126=\the\catcode126%
+\endlinechar=\the\endlinechar
+\relax}
+\catcode32=10 %< >
+\catcode33=12 %<">
+\catcode35=6 %<#>
+\catcode40=12 %<(>
+\catcode41=12 %<)>
+\catcode42=12 %<*>
+\catcode43=12 %<+>
+\catcode44=12 %<,>
+\catcode45=12 %<->
+\catcode46=12 %<.>
+\catcode58=12 %<:>
+\catcode59=12 %<;>
+\catcode60=12 %<<>
+\catcode61=12 %<=>
+\catcode62=12 %<>>
+\catcode64=11 %<@>
+\catcode91=12 %<[>
+\catcode93=12 %<]>
+\catcode94=7 %<^>
+\catcode95=8 %<_>
+\catcode126=13 %<~>
+\endlinechar=-1 %
+%! ãªãŠ, 上ã®catcode設定ã¯coreã¨compatã§åŒä¸€ã«ã—ã¦ãŠã.
+\edef\ltj@core@AtEnd{\x
+ \noexpand\let\noexpand\ltj@core@AtEnd\relax}
+\def\luatexjacoreLoaded{\endinput}
+
+%% Check if LaTeX is used.
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax %<*!LaTeX>
+ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname
+ \csname iffalse\endcsname
+\else %<*LaTeX>
+ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname
+ \csname iftrue\endcsname
+ \NeedsTeXFormat{LaTeX2e}
+ \ProvidesPackage{luatexja-core}[2017/11/12 Core of LuaTeX-ja]
+\fi %</LaTeX>
+
+%% Load prerequisite packages.
+\endlinechar=13 %
+\newif\ifltj@everyhook@avail\ltj@everyhook@availfalse
+%! 外部パッケージã¯æ™®é€šã® \endlinechar ã§èª­ã¾ãªã„ã¨å±é™º.
+\ifltj@in@latex %<*LaTeX>
+ \RequirePackage{luatexbase}
+ \RequirePackage{luaotfload}
+ \RequirePackage{ltxcmds} [2011/11/09] % v1.22
+ \RequirePackage{pdftexcmds} [2011/11/29] % v0.20
+ \RequirePackage{xkeyval} [2012/10/14] % v2.6b
+ \RequirePackage{atbegshi}
+ \RequirePackage{etoolbox}
+ \AtBeginShipoutInit
+ \IfFileExists{everyhook.sty}{\RequirePackage{everyhook}\ltj@everyhook@availtrue}{}
+\else %<*!LaTeX>
+ \input luatexbase.sty
+ \input luaotfload.sty
+ \input ltxcmds.sty
+ \input pdftexcmds.sty
+ \input xkeyval
+ \input atbegshi.sty
+ \AtBeginShipoutInit
+\fi %</LaTeX>
+\endlinechar=-1 %
+
+%% Check if LuaTeX is used
+\ltx@LocalExpandAfter\ifx\csname directlua\endcsname\relax
+ % Loading is silently aborted, since the notice of the wrong
+ % engine is already shown in luaotfload.
+ \ltj@core@AtEnd
+\expandafter\endinput\fi\relax
+
+%% Check LuaTeX version.
+\ifnum\luatexversion<100
+ \@PackageError{luatexja-core}
+ {This LuaTeX engine is too old for this package;\MessageBreak
+ at least 1.0.0 is needed}
+ {Package loading is aborted now.\MessageBreak}
+\expandafter\endinput\fi\relax
+
+%% \LuaTeXjaAvailable
+%! 環境検査ã«ãƒ‘スã—ãŸæ™‚ã«å®šç¾©ã•ã‚Œã‚‹.
+\let\LuaTeXjaAvailable=t %
+
+%%------------------
+\endlinechar=13
+
+%! ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
+% LuaTeX-ja core TeX source
+
+\newcount\ltjlineendcomment
+\ltjlineendcomment="FFFFF
+\catcode\ltjlineendcomment=14 %"
+
+\def\ltj@loaded{hoge}
+
+\newdimen\ltj@zw
+\newdimen\ltj@zh
+\newdimen\jQ \jQ=0.25mm
+\let\jH=\jQ
+
+%%%%%%%% error message
+\def\ltj@defnum{0}
+\def\ltj@defdimen{0}
+
+%%%%%%%% Attributes for Japanese typesetting.
+\newattribute\ltj@icflag % attribute for italic correction
+\newattribute\ltj@curjfnt % index for ``current horizontal Japanese font''
+\newattribute\ltj@curtfnt % index for ``current vertical Japanese font''
+\newattribute\ltj@charclass %
+\newattribute\ltj@charcode %
+\newattribute\ltj@autospc % attribute for autospacing
+\newattribute\ltj@autoxspc % attribute for autoxspacing
+\newattribute\ltj@yablshift % attribute for yalbaselineshift
+\newattribute\ltj@ykblshift % attribute for yjabaselineshift
+\newattribute\ltj@tablshift % attribute for talbaselineshift
+\newattribute\ltj@tkblshift % attribute for tjabaselineshift
+\newattribute\jfam % index for current jfam
+\newattribute\ltj@vert@ori % <=0: UAX#50, >0: always upright
+
+\newattribute\ltj@dir
+\newlanguage\ltj@@japanese
+\ltj@dir\z@
+\ltj@icflag\z@
+\ltj@charclass\z@
+\ltj@curjfnt\m@ne
+\ltj@curtfnt\m@ne
+
+%%%%%%%% Attributes for character ranges
+\newcount\ltj@tempcnta
+\ltj@tempcnta\z@
+\loop\ifnum\ltj@tempcnta<7
+ \expandafter\newattribute%
+ \csname ltj@kcat\the\ltj@tempcnta\endcsname
+ \csname ltj@kcat\the\ltj@tempcnta\endcsname=0
+ \advance\ltj@tempcnta\@ne
+\repeat
+
+
+%%%%%%%% Loading luatexja.lua
+%% Quark tokens needed in ltj-base
+\protected\def\ltj@@q@escape{\ltj@@q@escape@}
+\protected\def\ltj@@q@escapenum{\ltj@@q@escapenum@}
+
+\directlua{%
+ luatexja = {};
+ luatexja.lang_ja = \the\ltj@@japanese;
+ dofile(assert(kpse.find_file('luatexja.lua', 'tex'),
+ "File `luatexja.lua' not found"))
+}
+
+%% \RequireLuaTeXjaSubmodule{name}[date]
+% A TeX version of luatexja.load_module(name)
+% The second optional argument [date] is simply ignored.
+\def\RequireLuaTeXjaSubmodule#1{%
+ \@ifnextchar[{\ltj@requirelua@submod{#1}}{\ltj@requirelua@submod{#1}[]}}
+\def\ltj@requirelua@submod#1[#2]{%
+ \directlua{luatexja.load_module("\luatexluaescapestring{#1}")}}
+
+
+%%%%%%%% Load all sub-packages.
+\ifltj@in@latex %<*LaTeX>
+ \RequirePackage{ltj-base}
+\else %<*!LaTeX>
+ \input ltj-base.sty %
+\fi %</LaTeX>
+
+%%%%%%%% \asluastring
+\def\asluastring#1{'\luatexluaescapestring{\detokenize{#1}}'}
+
+%%%%%%%% Redefine \/
+\newluafunction\ltj@@italic@inner
+\directlua{
+ local t = lua.get_functions_table()
+ t[\the\ltj@@italic@inner] = luatexja.jfont.append_italic
+}
+\protected\def\/{\relax\luafunction\ltj@@italic@inner}
+
+%%%%%%%% \jfont\CS={...:...;jfm=metric;...}, \globaljfont
+\protected\def\jfont#1{%
+ \afterassignment\ltj@@jfont\directlua{luatexja.jfont.jfontdefX(false, 'yoko','\luatexluaescapestring{\noexpand#1}')}}
+\protected\def\globaljfont#1{%
+ \afterassignment\ltj@@jfont\directlua{luatexja.jfont.jfontdefX(true, 'yoko','\luatexluaescapestring{\noexpand#1}')}}
+\newluafunction\ltj@@jfont@inner
+\directlua{
+ local t = lua.get_functions_table()
+ t[\the\ltj@@jfont@inner] = luatexja.jfont.jfontdefY
+}
+\def\ltj@@jfont{\luafunction\ltj@@jfont@inner}
+
+%%%%%%%% \tfont\CS={...:...;jfm=metric;...}, \globaltfont
+\protected\def\tfont#1{%
+ \afterassignment\ltj@@jfont\directlua{luatexja.jfont.jfontdefX(false, 'tate','\luatexluaescapestring{\noexpand#1}')}}
+\protected\def\globaltfont#1{%
+ \afterassignment\ltj@@jfont\directlua{luatexja.jfont.jfontdefX(true, 'tate','\luatexluaescapestring{\noexpand#1}')}}
+
+%%%%%%%% \zw, \zh
+\newluafunction\ltj@zw@inner
+\newluafunction\ltj@zh@inner
+\directlua{
+ local t, setdimen, ltjf = lua.get_functions_table(), tex.setdimen, luatexja.jfont
+ t[\the\ltj@zw@inner] = function() setdimen('ltj@zw', ltjf.get_zw()) end
+ t[\the\ltj@zh@inner] = function() setdimen('ltj@zh', ltjf.get_zh()) end
+}
+\protected\def\zw{\luafunction\ltj@zw@inner\ltj@zw}
+\protected\def\zh{\luafunction\ltj@zh@inner\ltj@zh}
+
+%%%%%%%% \inhibitglue
+\newluafunction\ltj@reset@globaldefs@inner
+\newluafunction\ltj@restore@globaldefs@inner
+\newluafunction\ltj@@ihb@inner
+\newluafunction\ltj@@fakeparbegin@inner
+\newluafunction\ltj@@fakeboxbdd@inner
+\directlua{
+ local t = lua.get_functions_table()
+ t[\the\ltj@reset@globaldefs@inner]
+ = function() luatexja.global_temp = tex.globaldefs; tex.globaldefs = 0 end
+ t[\the\ltj@restore@globaldefs@inner]
+ = function() tex.globaldefs = luatexja.global_temp end
+ t[\the\ltj@@ihb@inner] = luatexja.jfmglue.create_inhibitglue_node
+ t[\the\ltj@@fakeparbegin@inner] = luatexja.jfmglue.create_beginpar_node
+ t[\the\ltj@@fakeboxbdd@inner] = luatexja.jfmglue.create_boxbdd_node
+}
+\protected\def\ltj@reset@globaldefs{\luafunction\ltj@reset@globaldefs@inner}
+\protected\def\ltj@restore@globaldefs{\luafunction\ltj@restore@globaldefs@inner}
+\protected\def\inhibitglue{\ifhmode\relax\luafunction\ltj@@ihb@inner\fi}
+\protected\def\ltjfakeparbegin{\ifhmode\relax\luafunction\ltj@@fakeparbegin@inner\fi}
+\protected\def\ltjfakeboxbdd{\ifhmode\relax\luafunction\ltj@@fakeboxbdd@inner\fi}
+
+
+%%%%%%%% \ltjdefcharrange<name>{100-200,3000-,5000,...}
+\protected\def\ltjdefcharrange#1#2{%
+ {\ltj@tempcntc=#1 \expandafter\ltj@@dcrange#2,,}\ignorespaces}
+\def\ltj@@dcrange#1,{\def\ltj@temp{#1}%
+ \ifx\ltj@temp\empty\let\@next=\relax\else
+ \ltj@@dcrangeA{#1}\let\@next=\ltj@@dcrange\fi\@next}
+\def\ltj@@dcrangeA#1{\ltj@@dcrangeB#1--\@nil}
+\def\ltj@@dcrangeB#1-#2-#3\@nil{\def\ltj@temp{#3}%
+ \ifx\ltj@temp\empty
+ \ltj@tempcnta=#1 \ltj@tempcntb=\ltj@tempcnta
+ \else
+ \def\ltj@temp{#1}%
+ \ifx\ltj@temp\empty\ltj@tempcnta='200\else\ltj@tempcnta=#1\fi\relax
+ \def\ltj@temp{#2}%
+ \ifx\ltj@temp\empty\ltj@tempcntb="10FFFF\else\ltj@tempcntb=#2\fi\relax%"
+ \fi
+ \directlua{luatexja.charrange.add_char_range(\the\ltj@tempcnta,\the\ltj@tempcntb,
+ \the\ltj@tempcntc)}%
+ }
+
+%%%%%%%% \ltjsetparameter
+\newcount\ltj@@stack \newcount\ltj@@group@level
+\ltj@@group@level\z@\ltj@@stack\z@
+
+\setbox\z@\hbox{%
+ \directlua{% This value depends on the version of LuaTeX.
+ luatexja.stack.hmode = -tex.nest[tex.nest.ptr].mode
+ }%
+}
+\setbox\z@\vbox{%
+ \directlua{% This value depends on the version of LuaTeX.
+ luatexja.stack.vmode = -tex.nest[tex.nest.ptr].mode
+ }%
+}
+\setbox\z@\box\voidb@x
+
+% prebreakpenalty = {<char_code>, <penalty>}
+\define@key[ltj]{japaram}{kcatcode}{\ltj@@set@stack{KCAT}{0}{0x7FFFFFFF}#1\relax}
+\define@key[ltj]{japaram}{prebreakpenalty}{\ltj@@set@stack{PRE}{-10000}{10000}#1\relax}
+\define@key[ltj]{japaram}{postbreakpenalty}{\ltj@@set@stack{POST}{-10000}{10000}#1\relax}
+\def\ltj@@set@stack#1#2#3{%
+ \directlua{luatexja.stack.set_stack_perchar(luatexja.stack_table_index.#1,#2,#3)}}
+%\def\ltj@@set@stack#1,#2:#3#4#5{%
+% \directlua{luatexja.stack.set_stack_perchar(luatexja.stack_table_index.#3,
+% \ltj@safe@num@or{nil}{#1},\ltj@safe@num@or{nil}{#2},#4,#5)}}
+
+% jatextfont = {<char_code>, <font_cs>}
+% only horizontal font is supported
+\define@key[ltj]{japaram}{jatextfont}{%
+ \expandafter\ltj@@set@stackfont#1:{MJT}}
+\define@key[ltj]{japaram}{jascriptfont}{%
+ \expandafter\ltj@@set@stackfont#1:{MJS}}
+\define@key[ltj]{japaram}{jascriptscriptfont}{%
+ \expandafter\ltj@@set@stackfont#1:{MJSS}}
+\protected\def\ltj@@set@stackfont#1,#2:#3{%
+ \ltj@reset@globaldefs
+ \ltj@tempcnta=\ltj@curjfnt\ltj@curjfnt\m@ne#2%
+ \ifnum\ltj@curjfnt=\m@ne
+ \@PackageError{luatexja-core}%
+ {\string#2 is not a control sequence that represents \MessageBreak
+ a Japanese font}{}%
+ \else
+ \directlua{luatexja.stack.set_stack_font(luatexja.stack_table_index.#3,
+ \ltj@safe@num@or{nil}{#1}, \the\ltj@curjfnt)}%
+ \fi
+ \ltj@curjfnt=\ltj@tempcnta
+ \ltj@restore@globaldefs
+ }
+
+% {y,t}{ja,al}baselineshift = <dimen>
+% yjabaselineshift = <dimen>
+\define@key[ltj]{japaram}{yalbaselineshift}{%
+ \directlua{tex.setattribute(luatexja.isglobal,
+ luatexbase.attributes['ltj@yablshift'], token.scan_dimen())}#1\relax}
+\define@key[ltj]{japaram}{yjabaselineshift}{%
+ \directlua{tex.setattribute(luatexja.isglobal,
+ luatexbase.attributes['ltj@ykblshift'], token.scan_dimen())}#1\relax}
+\define@key[ltj]{japaram}{talbaselineshift}{%
+ \directlua{tex.setattribute(luatexja.isglobal,
+ luatexbase.attributes['ltj@tablshift'], token.scan_dimen())}#1\relax}
+\define@key[ltj]{japaram}{tjabaselineshift}{%
+ \directlua{tex.setattribute(luatexja.isglobal,
+ luatexbase.attributes['ltj@tkblshift'], token.scan_dimen())}#1\relax}
+
+% jaxspmode = {<char_code>, <mode>}
+% mode: inhibit, preonly, postonly, allow
+% or 0 1 2 3
+\define@key[ltj]{japaram}{jaxspmode}{% \inhibitxspcode
+ \expandafter\ltj@set@jaxspmode#1:\relax}
+\def\ltj@set@jaxspmode#1,#2:{%
+ \lowercase{\edef\ltj@temp{#2}}%
+ \def\ltj@tempa{inhibit}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{0}\fi
+ \def\ltj@tempa{preonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{1}\fi
+ \def\ltj@tempa{postonly}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{2}\fi
+ \def\ltj@tempa{allow}\ifx\ltj@temp\ltj@tempa\def\ltj@temp{3}\fi
+ \ltj@@set@stack{XSP}03#1 \ltj@temp}
+
+% alxspmode = {<char_code>, <mode>}
+% mode: inhibit, preonly, postonly, allow
+% or 0 1 2 3
+\define@key[ltj]{japaram}{alxspmode}{% \inhibitxspcode
+ \expandafter\ltj@set@jaxspmode#1:\relax}% same code as jaxspmode
+
+% autospacing = <bool> (default: true)
+\define@boolkey[ltj]{japaram}{autospacing}[true]{%
+ \ifltj@japaram@autospacing
+ \directlua{luatexja.ext_print_global()}\ltj@autospc\@ne
+ \else
+ \directlua{luatexja.ext_print_global()}\ltj@autospc\z@
+ \fi}
+
+% autoxspacing = <bool> (default: true)
+\define@boolkey[ltj]{japaram}{autoxspacing}[true]{%
+ \ifltj@japaram@autoxspacing
+ \directlua{luatexja.ext_print_global()}\ltj@autoxspc\@ne
+ \else
+ \directlua{luatexja.ext_print_global()}\ltj@autoxspc\z@
+ \fi}
+
+% [x]]kanjiskip = <skip>
+\define@key[ltj]{japaram}{kanjiskip}{\ltjsetkanjiskip#1}
+\define@key[ltj]{japaram}{xkanjiskip}{\ltjsetxkanjiskip#1}
+\newluafunction\ltjsetkanjiskip@inner
+\newluafunction\ltjsetxkanjiskip@inner
+\directlua{
+ local t, scan_glue = lua.get_functions_table(), token.scan_glue
+ local sss, sti = luatexja.stack.set_stack_skip, luatexja.stack_table_index
+ t[\the\ltjsetkanjiskip@inner] = function()
+ local d = scan_glue(); sss(sti.KSK, d); node.free(d)
+ end
+ t[\the\ltjsetxkanjiskip@inner] = function()
+ local d = scan_glue(); sss(sti.XSK, d); node.free(d)
+ end
+}
+\protected\def\ltjsetkanjiskip{\luafunction\ltjsetkanjiskip@inner}
+\protected\def\ltjsetxkanjiskip{\luafunction\ltjsetxkanjiskip@inner}
+
+% jcharwidowpenalty = <count>
+\define@key[ltj]{japaram}{jcharwidowpenalty}{% %COUNT
+ \ltj@@set@stack{JWP}{-10000}{10000}\z@#1 }
+
+% differentjfm = { large | small | average | pleft | pright | paverage | both}
+\define@choicekey*+[ltj]{japaram}{differentjfm}[\ltj@temp\ltj@tempr]%
+ {large,small,average,pleft,pright,paverage,both}{%
+ \ifcase\ltj@tempr
+ \directlua{luatexja.jfmglue.diffmet_rule = math.max}\or
+ \directlua{luatexja.jfmglue.diffmet_rule = math.min}\or
+ \directlua{luatexja.jfmglue.diffmet_rule = math.two_average}\or
+ \directlua{luatexja.jfmglue.diffmet_rule = math.two_pleft}\or
+ \directlua{luatexja.jfmglue.diffmet_rule = math.two_pright}\or
+ \directlua{luatexja.jfmglue.diffmet_rule = math.two_paverage}\or
+ \directlua{luatexja.jfmglue.diffmet_rule = math.two_add}
+ \fi
+}{\ltj@PackageError{luatexja}{invalid argument `#1' for `differentjfm'}{%
+ Argument for `differentjfm' must be one of `large', `small', `average',^^J%
+ `pleft', `pright', 'paverage' or `both'. }}
+ % large, small, average, pleft, pright, paverage, both
+
+
+% jacharrange = { +-<range_number> }
+\define@key[ltj]{japaram}{jacharrange}{\expandafter\ltj@@scrange#1,,}
+\def\ltj@@scrange#1,{%
+ \edef\ltj@temp{#1}%
+ \ifx\ltj@temp\empty\let\ltj@@next=\relax\else\let\ltj@@next=\ltj@@scrange
+ \directlua{luatexja.charrange.toggle_char_range(%
+ luatexja.is_global,\ltj@safe@num@or{nil}{#1})}%
+ \fi\ltj@@next
+}
+
+\protected\def\ltj@setpar@global{%
+ \relax\ifnum\globaldefs>0\directlua{luatexja.isglobal='global'}%
+ \else\directlua{luatexja.isglobal=''}\fi
+}
+\protected\def\ltjsetparameter#1{%
+ \directlua{luatexja.base.start_time_measure('set_par')}%
+ \ltj@setpar@global\setkeys[ltj]{japaram}{#1}%
+ \directlua{luatexja.base.stop_time_measure('set_par')}%
+ \ignorespaces}
+\protected\def\ltjglobalsetparameter#1{%
+ \relax\ifnum\globaldefs<0\directlua{luatexja.isglobal=''}%
+ \else\directlua{luatexja.isglobal='global'}\fi%
+ \directlua{luatexja.base.start_time_measure('set_par')}%
+ \setkeys[ltj]{japaram}{#1}%
+ \directlua{luatexja.base.stop_time_measure('set_par')}%
+ \ignorespaces}
+
+%%%%%%%% \ltjgetparameter
+\def\ltj@@decl@array@param#1{%
+ \expandafter\let\csname ltj@@array@param/#1\endcsname=t%
+}
+\ltj@@decl@array@param{prebreakpenalty}
+\ltj@@decl@array@param{postbreakpenalty}
+\ltj@@decl@array@param{jaxspmode}
+\ltj@@decl@array@param{alxspmode}
+\ltj@@decl@array@param{kcatcode}
+\ltj@@decl@array@param{jacharrange}
+\ltj@@decl@array@param{chartorange}
+\ltj@@decl@array@param{boxdir}
+\def\ltjgetparameter#1{%
+ \directlua{luatexja.base.start_time_measure('get_par')}%
+ % stop call is moved in luatexja.lua
+ \ifcsname ltj@@array@param/#1\endcsname
+ \expandafter\ltx@firstoftwo
+ \else
+ \expandafter\ltx@secondoftwo
+ \fi
+ {\ltj@@getparam@two{#1}}%
+ {\ltj@@getparam@one{#1}}%
+}
+\def\ltj@@getparam@one#1{%
+ \directlua{luatexja.ext_get_parameter_unary('#1')}%
+}%
+\def\ltj@@getparam@two#1#2{%
+ \directlua{luatexja.ext_get_parameter_binary('#1', \ltj@safe@num@or{nil}{#2})}%
+}
+
+%%%%%%%% \ltjalchar<number>, \ltjjachar<number>
+\let\ltj@@origchar=\char
+\newluafunction\ltj@alljachar@inner
+\directlua{
+ local t, set_attr = lua.get_functions_table(), tex.setattribute
+ local get_attr, floor = tex.getattribute, math.floor
+ local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
+ local lang_ja = luatexja.lang_ja
+ t[\the\ltj@alljachar@inner] = function()
+ font.current(get_attr(attr_curjfnt)); tex.language=lang_ja;
+ for i=0,6 do
+ set_attr(luatexbase.attributes['ltj@kcat' .. floor(i)],0)
+ end
+ end
+}
+\protected\def\ltj@alljachar{\luafunction\ltj@alljachar@inner}
+\protected\def\ltj@allalchar{\relax
+ \csname ltj@kcat0\endcsname="7FFFFFFF %"
+ \csname ltj@kcat1\endcsname="7FFFFFFF %"
+ \csname ltj@kcat2\endcsname="7FFFFFFF %"
+ \csname ltj@kcat3\endcsname="7FFFFFFF %"
+ \csname ltj@kcat4\endcsname="7FFFFFFF %"
+ \csname ltj@kcat5\endcsname="7FFFFFFF %"
+ \csname ltj@kcat6\endcsname="7FFFFFFF }%"
+
+\protected\def\ltjjachar{\afterassignment\ltj@@jachar\ltj@tempcnta}
+\def\ltj@@jachar{{\directlua{tex.globaldefs=0}\ltj@alljachar\ltj@@origchar\ltj@tempcnta}}
+\protected\def\ltjalchar{\afterassignment\ltj@@alchar\ltj@tempcnta}
+\def\ltj@@alchar{{\directlua{tex.globaldefs=0}\ltj@allalchar\ltj@@origchar\ltj@tempcnta}}
+
+%%%%%%%% \ltjsetmathletter<number>, \ltjunsetmathletter<number>
+\protected\def\ltjsetmathletter#1{%
+ \directlua{luatexja.math.is_math_letters[token.scan_int()]=true}#1\relax
+}
+\protected\def\ltjunsetmathletter#1{%
+ \directlua{luatexja.math.is_math_letters[token.scan_int()]=false}#1\relax
+}
+
+%%%%%%%% \ltjdeclarealtfont<base_font_cs><alt_font_cs>{100-200,3000-,5000,...}
+% <base_font_cs> 㮠第 3 引数ã®æ–‡å­—é”㯠<alt_font_cs> ã§çµ„ã‚€
+% ã„ã¤ã‚‚ global
+\def\ltj@@getjfontnumber#1{% result in \ltj@tempcntc
+ \ltj@reset@globaldefs
+ \begingroup\ltj@curjfnt\m@ne\ltj@curtfnt\m@ne\relax
+ #1\directlua{luatexja.__temp = -(\the\ltj@curjfnt)*(\the\ltj@curtfnt)}\endgroup
+ \ltj@tempcntc=\directlua{tex.sprint(luatexja.__temp)}\relax
+ \ifnum\ltj@tempcntc=\m@ne
+ \@PackageError{luatexja-core}%
+ {\string#1 is not a control sequence that represents \MessageBreak
+ a Japanese font}{I'll use the current horizontal Japanese font instead.^^J}%
+ \ltj@tempcntc=\ltj@curjfnt
+ \fi\ltj@restore@globaldefs}
+
+\protected\def\ltjdeclarealtfont#1#2#3{%
+ {\ltj@@getjfontnumber#1\@tempcnta=\ltj@tempcntc% \@tempcnta: 基底フォント
+ \ltj@@getjfontnumber#2%
+ \expandafter\ltj@@altfont#3,,}\ignorespaces}
+\def\ltj@@altfont#1,{\def\ltj@temp{#1}%
+ \ifx\ltj@temp\empty\let\@next=\relax\else
+ \ltj@@altfontA{#1}\let\@next=\ltj@@altfont\fi\@next}
+\def\ltj@@altfontA#1{\ltj@@altfontB#1--\@nil}
+\def\ltj@@altfontB#1-#2-#3\@nil{\def\ltj@temp{#3}%
+ \ifx\ltj@temp\empty
+ \ltj@tempcnta=#1 \ltj@tempcntb=\ltj@tempcnta
+ \else
+ \def\ltj@temp{#1}%
+ \ifx\ltj@temp\empty\ltj@tempcnta='200\else\ltj@tempcnta=#1\fi\relax
+ \def\ltj@temp{#2}%
+ \ifx\ltj@temp\empty\ltj@tempcntb="10FFFF\else\ltj@tempcntb=#2\fi\relax%"
+ \fi
+ \directlua{luatexja.jfont.set_alt_font(
+ \the\ltj@tempcnta,\the\ltj@tempcntb,
+ \the\ltj@tempcntc, \the\@tempcnta)}%
+ }
+
+%%%%%%%% \ltjclearaltfont<font_cs>
+% <font_cs> ã®æ–‡å­—ã¯å…¨éƒ¨ <font_cs> 本æ¥ã®æ–‡å­—ã§çµ„ã‚€
+\protected\def\ltjclearaltfont#1{%
+ {\ltj@@getjfontnumber#1%
+ \directlua{luatexja.jfont.clear_alt_font(\the\ltj@tempcntc)}}\ignorespaces}
+
+
+%%%%%%%% \yoko, \tate,\dtou
+\protected\def\tate{%
+ \directlua{luatexja.direction.set_list_direction(3, 'tate')}%
+}
+\protected\def\yoko{%
+ \directlua{luatexja.direction.set_list_direction(4, 'yoko')}%
+}
+\protected\def\dtou{%
+ \directlua{luatexja.direction.set_list_direction(1, 'dtou')}%
+}
+\protected\def\utod{% 「縦数å¼ãƒ‡ã‚£ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã€
+ \directlua{luatexja.direction.set_list_direction(11, 'utod')}%
+}
+\define@key[ltj]{japaram}{direction}{%% always local
+ \directlua{luatexja.direction.set_list_direction(1, 'ltjsetparameter')}%
+}
+
+\yoko
+
+%%%% insert
+\let\orig@insert=\insert
+\protected\def\insert{\begingroup\afterassignment\ltj@@insert@A\ltj@tempcnta}
+\protected\def\ltj@@insert@A{\orig@insert\ltj@tempcnta\bgroup
+ \aftergroup\ltj@@insert@B\let\ltj@@next}
+\protected\def\ltj@@insert@B{\directlua{luatexja.direction.populate_insertion_dir_whatsit()}\endgroup}
+
+%%%% vadjust
+\let\ltj@@orig@vadjust=\vadjust
+\protected\def\vadjust{%
+ \ltj@@orig@vadjust\bgroup
+ \directlua{luatexja.direction.set_list_direction_hook('adj')}%
+ \aftergroup\ltj@@vadjust@check@dir\let\ltj@@next}
+\protected\def\ltj@@vadjust@check@dir{%
+ \directlua{luatexja.direction.check_adjust_direction()}%
+}
+
+%%%% \hbox, \vbox, \vtop
+\setbox\z@\hbox{%
+ \primitive\everymath{}
+ $\directlua{% This value depends on the version of LuaTeX.
+ luatexja.stack.mmode = -tex.nest[tex.nest.ptr].mode
+ }$%
+}
+\setbox\z@\box\voidb@x
+\ifltj@everyhook@avail% using everyhook package
+ \newluafunction\ltj@@box@dirhook
+ \directlua{
+ local t, ltjd = lua.get_functions_table(), luatexja.direction
+ t[\the\ltj@@box@dirhook]
+ = function() ltjd.set_list_direction_hook() end
+ }
+ \PushPreHook{hbox}{\luafunction\ltj@@box@dirhook\aftergroup\ltj@@reset@badness}
+ \PushPreHook{vbox}{\luafunction\ltj@@box@dirhook\aftergroup\ltj@@reset@badness}
+\else
+ \let\ltj@@everyhbox=\everyhbox\let\ltj@@everyvbox=\everyvbox
+ \newtoks\ltj@@i@everyhbox\newtoks\ltj@@i@everyvbox
+ \let\everyhbox=\ltj@@i@everyhbox\let\everyvbox=\ltj@@i@everyvbox
+ \newluafunction\ltj@@box@dirhook
+ \directlua{
+ local t, ltjd = lua.get_functions_table(), luatexja.direction
+ t[\the\ltj@@box@dirhook]
+ = function() ltjd.set_list_direction_hook() end
+ }
+ \ltj@@everyhbox{\luafunction\ltj@@box@dirhook
+ \aftergroup\ltj@@reset@badness\the\ltj@@i@everyhbox}
+ \ltj@@everyvbox{\luafunction\ltj@@box@dirhook
+ \aftergroup\ltj@@reset@badness\the\ltj@@i@everyvbox}
+\fi
+
+\newluafunction\ltj@@reset@badness@inner
+\directlua{
+ local t = lua.get_functions_table()
+ t[\the\ltj@@reset@badness@inner] = function()
+ if luatexja.global_temp then
+ tex.hbadness= tex.hbadness or luatexja.hbadness_temp
+ tex.vbadness= tex.vbadness or luatexja.vbadness_temp
+ tex.globaldefs= luatexja.global_temp or tex.globaldefs
+ end
+ end}
+\protected\def\ltj@@reset@badness{\luafunction\ltj@@reset@badness@inner}
+
+\AtBeginShipout{\directlua{luatexja.direction.finalize()}}
+
+%%%% \raise, \lower, \moveleft, \moveright
+\let\ltj@@orig@raise=\raise
+\let\ltj@@orig@lower=\lower
+\protected\def\raise{\ltj@reset@globaldefs\afterassignment\ltj@@raise\ltj@tempdima}
+\protected\def\lower{\ltj@reset@globaldefs\afterassignment\ltj@@raise\ltj@tempdima-}
+\protected\def\ltj@@raise{%
+ \ltj@restore@globaldefs
+ \edef\ltj@@raise@a{%
+ \noexpand\directlua{luatexja.direction.raise_box()}%
+ \ltj@@orig@raise\the\ltj@tempdima\noexpand\box\ltj@afbox
+ }\ltj@afterbox\ltj@@raise@a}
+\let\ltj@@orig@moveleft=\moveleft
+\let\ltj@@orig@moveright=\moveright
+\protected\def\moveleft{\ltj@reset@globaldefs\afterassignment\ltj@@moveleft\ltj@tempdima}
+\protected\def\moveright{\ltj@reset@globaldefs\afterassignment\ltj@@moveleft\ltj@tempdima-}
+\protected\def\ltj@@moveleft{%
+ \ltj@restore@globaldefs
+ \edef\ltj@@moveleft@a{%
+ \noexpand\directlua{luatexja.direction.raise_box()}%
+ \ltj@@orig@moveleft\the\ltj@tempdima\noexpand\box\ltj@afbox
+ }\ltj@afterbox\ltj@@moveleft@a}
+
+%%%%\vsplit
+\let\ltj@@orig@vsplit=\vsplit
+\protected\def\vsplit{\directlua{luatexja.direction.vsplit()}}
+%%%% \vcenter
+\let\ltj@@orig@vcenter=\vcenter
+\protected\def\vcenter{\ltj@afterbox\ltj@@vcenter\vbox}
+\protected\def\ltj@@vcenter{%
+ \directlua{luatexja.direction.raise_box()}%
+ \ltj@@orig@vcenter{\box\ltj@afbox}%
+}
+
+%%%% \unhbox and \unvbox
+\long\def \@gobbletwo #1#2{}
+\let\ltj@@orig@unhbox=\unhbox
+\let\ltj@@orig@unvbox=\unvbox
+\protected\def\unhbox{\ltj@reset@globaldefs\afterassignment\ltj@@unhbox\ltj@tempcnta}
+\protected\def\unvbox{\ltj@reset@globaldefs\afterassignment\ltj@@unvbox\ltj@tempcnta}
+\protected\def\ltj@@unhbox{%
+ \directlua{luatexja.direction.unbox_check_dir()}%
+ \ltj@@orig@unhbox\ltj@tempcnta}
+\protected\def\ltj@@unvbox{%
+ \directlua{luatexja.direction.unbox_check_dir()}%
+ \ltj@@orig@unvbox\ltj@tempcnta}
+\let\ltj@@orig@unhcopy=\unhcopy
+\let\ltj@@orig@unvcopy=\unvcopy
+\protected\def\unhcopy{\ltj@reset@globaldefs\afterassignment\ltj@@unhcopy\ltj@tempcnta}
+\protected\def\unvcopy{\ltj@reset@globaldefs\afterassignment\ltj@@unvcopy\ltj@tempcnta}
+\protected\def\ltj@@unhcopy{%
+ \directlua{luatexja.direction.unbox_check_dir(true)}%
+ \ltj@@orig@unhcopy\ltj@tempcnta
+ \directlua{luatexja.direction.uncopy_restore_whatsit()}}
+\protected\def\ltj@@unvcopy{%
+ \directlua{luatexja.direction.unbox_check_dir(true)}%
+ \ltj@@orig@unvcopy\ltj@tempcnta
+ \directlua{luatexja.direction.uncopy_restore_whatsit()}}
+
+%%%% lastbox
+\let\ltj@@orig@lastbox=\lastbox
+\protected\def\lastbox{%
+ \directlua{luatexja.direction.lastbox_hook()}\ltj@@orig@lastbox
+}
+
+%%%%%%%% \ltjgetwd<box_num> etc.
+\def\ltj@@getwd{%
+ \directlua{luatexja.direction.get_box_dim('width', token.scan_int())}}
+\def\ltj@@getht{%
+ \directlua{luatexja.direction.get_box_dim('height', token.scan_int())}}
+\def\ltj@@getdp{%
+ \directlua{luatexja.direction.get_box_dim('depth', token.scan_int())}}
+\let\ltjgetwd=\ltj@@getwd\let\ltjgetht=\ltj@@getht\let\ltjgetdp=\ltj@@getdp
+
+%%%%%%%% \ltjsetwd<box_num>=<dimen> etc.
+\protected\def\ltjsetwd{\directlua{luatexja.direction.set_box_dim('width')}}
+\protected\def\ltjsetht{\directlua{luatexja.direction.set_box_dim('height')}}
+\protected\def\ltjsetdp{\directlua{luatexja.direction.set_box_dim('depth')}}
+
+
+%%------------------ Load module for the format
+
+\ifltj@in@latex %<*LaTeX>
+ \RequirePackage{ltj-latex}
+\else\ifltj@in@plain %<*plain>
+ \input ltj-plain.sty %
+\fi\fi %</LaTeX|plain>
+
+\newcatcodetable\ltj@temp@cctb
+\def\ltj@overwrite@catcodetable#1{%
+ \setluatexcatcodetable\ltj@temp@cctb{\luatexcatcodetable#1}%
+ \setluatexcatcodetable#1{\luatexcatcodetable\ltj@temp@cctb\catcode\ltjlineendcomment=14}%"
+}
+\ltj@overwrite@catcodetable\CatcodeTableLaTeX
+\ltj@overwrite@catcodetable\CatcodeTableLaTeXAtLetter
+\ltj@overwrite@catcodetable\CatcodeTableExpl
+
+
+%%------------------ all done
+\ltj@core@AtEnd
+\endinput
+%% EOF
diff --git a/macros/luatex/generic/luatexja/src/luatexja.lua b/macros/luatex/generic/luatexja/src/luatexja.lua
new file mode 100644
index 0000000000..4a4de62b0d
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/luatexja.lua
@@ -0,0 +1,601 @@
+
+require('lualibs')
+tableunpack = table.unpack
+
+------------------------------------------------------------------------
+local function load_lua(fn)
+ local found = kpse.find_file(fn, 'tex')
+ if not found then
+ tex.error("LuaTeX-ja error: File `" .. fn .. "' not found")
+ else
+ texio.write_nl('(' .. found .. ')')
+ dofile(found)
+ end
+end
+luatexja.load_lua = load_lua
+function luatexja.load_module(name)
+ require('ltj-' .. name.. '.lua')
+end
+
+do
+ local setfield = node.direct.setfield
+ luatexja.setglue = node.direct.setglue or
+ function(g,w,st,sh,sto,sho)
+ setfield(g,'width', w or 0)
+ setfield(g,'stretch',st or 0)
+ setfield(g,'shrink', sh or 0)
+ setfield(g,'stretch_order',sto or 0)
+ setfield(g,'shrink_order', sho or 0)
+ end
+ local getfield = node.direct.getfield
+ luatexja.getglue = node.direct.getglue or
+ function(g)
+ return getfield(g,'width'),
+ getfield(g,'stretch'),
+ getfield(g,'shrink'),
+ getfield(g,'stretch_order'),
+ getfield(g,'shrink_order')
+ end
+end
+
+--- 以下ã¯å…¨ãƒ•ã‚¡ã‚¤ãƒ«ã§å…±æœ‰ã•ã‚Œã‚‹å®šæ•°
+local icflag_table = {}
+luatexja.icflag_table = icflag_table
+icflag_table.ITALIC = 1
+icflag_table.PACKED = 2
+icflag_table.KINSOKU = 3
+icflag_table.FROM_JFM = 4
+-- FROM_JFM: 4, 5, 6, 7, 8 →優先度高(伸ã³ã‚„ã™ã,縮ã¿ã‚„ã™ã„)
+-- 6 ãŒæ¨™æº–
+icflag_table.KANJI_SKIP = 68 -- = 4+64
+icflag_table.KANJI_SKIP_JFM = 69
+icflag_table.XKANJI_SKIP = 70
+icflag_table.XKANJI_SKIP_JFM = 71
+icflag_table.LINEEND = 72
+icflag_table.PROCESSED = 73
+icflag_table.IC_PROCESSED = 74
+icflag_table.BOXBDD = 75
+icflag_table.PROCESSED_BEGIN_FLAG = 4096 -- sufficiently large power of 2
+
+local stack_table_index = {}
+luatexja.stack_table_index = stack_table_index
+stack_table_index.PRE = 0x200000 -- characterã”ã¨
+stack_table_index.POST = 0x400000 -- characterã”ã¨
+stack_table_index.KCAT = 0x600000 -- characterã”ã¨
+stack_table_index.XSP = 0x800000 -- characterã”ã¨
+stack_table_index.RIPRE = 0xA00000 -- characterã”ã¨ï¼Œruby pre
+stack_table_index.RIPOST = 0xC00000 -- characterã”ã¨ï¼Œruby post
+stack_table_index.JWP = 0 -- ã“ã‚Œã ã‘
+stack_table_index.KSK = 1 -- ã“ã‚Œã ã‘
+stack_table_index.XSK = 2 -- ã“ã‚Œã ã‘
+stack_table_index.MJT = 0x100 -- 0--255
+stack_table_index.MJS = 0x200 -- 0--255
+stack_table_index.MJSS = 0x300 -- 0--255
+stack_table_index.KSJ = 0x400 -- 0--9
+
+local userid_table = {}
+luatexja.userid_table = userid_table
+userid_table.IHB = luatexbase.newuserwhatsitid('inhibitglue', 'luatexja') -- \inhibitglue
+userid_table.STCK = luatexbase.newuserwhatsitid('stack_marker', 'luatexja') -- スタック管ç†
+userid_table.BPAR = luatexbase.newuserwhatsitid('begin_par', 'luatexja') -- 「段è½å§‹ã‚ã€
+userid_table.DIR = luatexbase.newuserwhatsitid('direction', 'luatexja') -- 組方å‘
+userid_table.BOXB = luatexbase.newuserwhatsitid('box_boundary', 'luatexja') -- 「ボックス始ã‚・終ã‚ã‚Šã€
+userid_table.JA_AL_BDD = luatexbase.newuserwhatsitid('ja_al_boundary', 'luatexja')
+
+local dir_table = {}
+luatexja.dir_table = dir_table
+dir_table.dir_dtou = 1
+dir_table.dir_tate = 3
+dir_table.dir_yoko = 4
+dir_table.dir_math_mod = 8
+dir_table.dir_node_auto = 128 -- 組方å‘ã‚’åˆã‚ã›ã‚‹ãŸã‚ã«è‡ªå‹•ã§ä½œã‚‰ã‚ŒãŸã‚‚ã®
+dir_table.dir_node_manual = 256 -- 寸法代入ã«ã‚ˆã£ã¦ä½œã‚‰ã‚ŒãŸã‚‚ã®
+dir_table.dir_utod = dir_table.dir_tate + dir_table.dir_math_mod
+ -- 「縦数å¼ãƒ‡ã‚£ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã€ in pTeX
+--- 定義終ã‚ã‚Š
+
+local load_module = luatexja.load_module
+load_module('base'); local ltjb = luatexja.base
+load_module('rmlgbm'); local ltjr = luatexja.rmlgbm -- must be 1st
+
+if luatexja_debug then load_module('debug') end
+
+load_module('charrange'); local ltjc = luatexja.charrange
+load_module('stack'); local ltjs = luatexja.stack
+load_module('direction'); local ltjd = luatexja.direction -- +1 hlist +1 attr_list
+load_module('lineskip'); local ltjl = luatexja.lineskip -- +1 hlist +1 attr_list
+load_module('jfont'); local ltjf = luatexja.jfont
+load_module('inputbuf'); local ltji = luatexja.inputbuf
+load_module('pretreat'); local ltjp = luatexja.pretreat
+load_module('setwidth'); local ltjw = luatexja.setwidth
+load_module('jfmglue'); local ltjj = luatexja.jfmglue -- +1 glue +1 gs +1 attr_list
+load_module('math'); local ltjm = luatexja.math
+load_module('base'); local ltjb = luatexja.base
+
+
+local attr_jchar_class = luatexbase.attributes['ltj@charclass']
+local attr_jchar_code = luatexbase.attributes['ltj@charcode']
+local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
+local attr_yablshift = luatexbase.attributes['ltj@yablshift']
+local attr_icflag = luatexbase.attributes['ltj@icflag']
+local attr_uniqid = luatexbase.attributes['ltj@uniqid']
+local attr_dir = luatexbase.attributes['ltj@dir']
+local cat_lp = luatexbase.catcodetables['latex-package']
+
+-- Three aux. functions, bollowed from tex.web
+
+local unity=65536
+local floor = math.floor
+
+local function print_scaled(s)
+ local out=''
+ local delta=10
+ if s<0 then
+ out=out..'-'; s=-s
+ end
+ out=out..tostring(floor(s/unity)) .. '.'
+ s=10*(s%unity)+5
+ repeat
+ if delta>unity then s=s+32768-50000 end
+ out=out .. tostring(floor(s/unity))
+ s=10*(s%unity)
+ delta=delta*10
+ until s<=delta
+ return out
+end
+luatexja.print_scaled = print_scaled
+
+local function print_glue(d,order)
+ local out=print_scaled(d)
+ if order>0 then
+ out=out..'fi'
+ while order>1 do
+ out=out..'l'; order=order-1
+ end
+ else
+ out=out..'pt'
+ end
+ return out
+end
+
+local function print_spec(p)
+ local out=print_scaled(p.width)..'pt'
+ if p.stretch~=0 then
+ out=out..' plus '..print_glue(p.stretch,p.stretch_order)
+ end
+ if p.shrink~=0 then
+ out=out..' minus '..print_glue(p.shrink,p.shrink_order)
+ end
+return out
+end
+
+
+------------------------------------------------------------------------
+-- CODE FOR GETTING/SETTING PARAMETERS
+------------------------------------------------------------------------
+
+-- EXT: print parameters that don't need arguments
+do
+ local tex_getattr = tex.getattribute
+ local function getattr(a)
+ local r = tex.getattribute(a)
+ return (r==-0x7FFFFFFF) and 0 or r
+ end
+ luatexja.unary_pars = {
+ yalbaselineshift = function(t)
+ return print_scaled(getattr('ltj@yablshift'))..'pt'
+ end,
+ yjabaselineshift = function(t)
+ return print_scaled(getattr('ltj@ykblshift'))..'pt'
+ end,
+ talbaselineshift = function(t)
+ return print_scaled(getattr('ltj@tablshift'))..'pt'
+ end,
+ tjabaselineshift = function(t)
+ return print_scaled(getattr('ltj@tkblshift'))..'pt'
+ end,
+ kanjiskip = function(t)
+ return print_spec(ltjs.get_stack_skip(stack_table_index.KSK, t))
+ end,
+ xkanjiskip = function(t)
+ return print_spec(ltjs.get_stack_skip(stack_table_index.XSK, t))
+ end,
+ jcharwidowpenalty = function(t)
+ return ltjs.get_stack_table(stack_table_index.JWP, 0, t)
+ end,
+ autospacing = function(t)
+ return getattr('ltj@autospc')
+ end,
+ autoxspacing = function(t)
+ return getattr('ltj@autoxspc')
+ end,
+ differentjfm = function(t)
+ local f, r = luatexja.jfmglue.diffmet_rule, '???'
+ if f == math.max then r = 'large'
+ elseif f == math.min then r = 'small'
+ elseif f == math.two_average then r = 'average'
+ elseif f == math.two_paverage then r = 'paverage'
+ elseif f == math.two_pleft then r = 'pleft'
+ elseif f == math.two_pright then r = 'pright'
+ elseif f == math.two_add then r = 'both'
+ end
+ return r
+ end,
+ direction = function()
+ local v = ltjd.get_dir_count()
+ if math.abs(tex.nest[tex.nest.ptr].mode) == ltjs.mmode and v == dir_table.dir_tate then
+ v = dir_table.dir_utod
+ end
+ return v
+ end,
+ adjustdir = ltjd.get_adjust_dir_count,
+ }
+
+ local unary_pars = luatexja.unary_pars
+ function luatexja.ext_get_parameter_unary(k)
+ if unary_pars[k] then
+ tex.write(tostring(unary_pars[k](tex.getcount('ltj@@stack'))))
+ end
+ ltjb.stop_time_measure('get_par')
+ end
+end
+
+
+-- EXT: print parameters that need arguments
+do
+ luatexja.binary_pars = {
+ jacharrange = function(c, t)
+ if type(c)~='number' or c<-1 or c>31*ltjc.ATTR_RANGE then
+ -- 0, -1 ã¯ã‚¨ãƒ©ãƒ¼ã«ã—ãªã„(隠ã—)
+ ltjb.package_error('luatexja',
+ 'invalid character range number (' .. tostring(c) .. ')',
+ 'A character range number should be in the range 1..'
+ .. 31*ltjc.ATTR_RANGE .. ",\n"..
+ 'So I changed this one to ' .. 31*ltjc.ATTR_RANGE .. ".")
+ c=0 -- external range 217 == internal range 0
+ elseif c==31*ltjc.ATTR_RANGE then c=0
+ end
+ -- è² ã®å€¤ã¯ <U+0080 ã®æ–‡å­—ã®æ–‡å­—範囲,ã¨ã—ã¦å‡ºã¦ãる.ã“ã®æ™‚ã¯ã„ã¤ã‚‚欧文文字ãªã®ã§ 1 ã‚’è¿”ã™
+ return (c<0) and 1 or ltjc.get_range_setting(c)
+ end,
+ prebreakpenalty = function(c, t)
+ return ltjs.get_stack_table(stack_table_index.PRE
+ + ltjb.in_unicode(c, true), 0, t)
+ end,
+ postbreakpenalty = function(c, t)
+ return ltjs.get_stack_table(stack_table_index.POST
+ + ltjb.in_unicode(c, true), 0, t)
+ end,
+ kcatcode = function(c, t)
+ return ltjs.get_stack_table(stack_table_index.KCAT
+ + ltjb.in_unicode(c, false), 0, t)
+ end,
+ chartorange = function(c, t)
+ return ltjc.char_to_range(ltjb.in_unicode(c, false))
+ end,
+ jaxspmode = function(c, t)
+ return ltjs.get_stack_table(stack_table_index.XSP
+ + ltjb.in_unicode(c, true), 3, t)
+ end,
+ boxdir = function(c, t)
+ if type(c)~='number' or c<0 or c>65535 then
+ ltjb.package_error('luatexja',
+ 'Bad register code (' .. tostring(c) .. ')',
+ 'A register must be between 0 and 65535.\n'..
+ 'I changed this one to zero.')
+ c=0
+ end
+ return ltjd.get_register_dir(c)
+ end,
+ }
+ local binary_pars = luatexja.binary_pars
+
+ binary_pars.alxspmode = binary_pars.jaxspmode
+ function luatexja.ext_get_parameter_binary(k,c)
+ if binary_pars[k] then
+ tex.write(tostring(binary_pars[k](c,tex.getcount('ltj@@stack'))))
+ end
+ ltjb.stop_time_measure('get_par')
+ end
+end
+
+-- EXT: print \global if necessary
+function luatexja.ext_print_global()
+ if luatexja.isglobal=='global' then tex.sprint(cat_lp, '\\global') end
+end
+
+
+-- main process
+do
+ local start_time_measure, stop_time_measure
+ = ltjb.start_time_measure, ltjb.stop_time_measure
+ local nullfunc = function (n) return n end
+ local to_node = node.direct.tonode
+ local to_direct = node.direct.todirect
+ local ensure_tex_attr = ltjb.ensure_tex_attr
+
+ -- mode = true iff main_process is called from pre_linebreak_filter
+ local function main_process(head, mode, dir, gc)
+ ensure_tex_attr(attr_icflag, 0)
+ if gc == 'fin_row' then return head
+ else
+ --luatexja.ext_show_node_list(head, 'T> ', print)
+ start_time_measure('jfmglue')
+ local p = ltjj.main(to_direct(head),mode, dir)
+ stop_time_measure('jfmglue')
+ return to_node(p)
+ end
+ end
+
+ local function adjust_icflag(h)
+ -- kern from luaotfload will have icflag = 1
+ -- (same as italic correction)
+ ensure_tex_attr(attr_icflag, 1)
+ return h
+ end
+
+ -- callbacks
+ ltjb.add_to_callback(
+ 'pre_linebreak_filter',
+ function (head,groupcode)
+ return main_process(head, true, tex.textdir, groupcode)
+ end,'ltj.main',
+ luatexbase.priority_in_callback('pre_linebreak_filter', 'luaotfload.node_processor')+1)
+ ltjb.add_to_callback(
+ 'hpack_filter',
+ function (head,groupcode,size,packtype, dir)
+ return main_process(head, false, dir, groupcode)
+ end,'ltj.main',
+ luatexbase.priority_in_callback('hpack_filter', 'luaotfload.node_processor')+1)
+ ltjb.add_to_callback('pre_linebreak_filter', adjust_icflag, 'ltj.adjust_icflag', 1)
+ ltjb.add_to_callback('hpack_filter', adjust_icflag, 'ltj.adjust_icflag', 1)
+
+end
+
+-- cleanup process
+function luatexja.ext_cleanup()
+ ltjf.cleanup_size_cache()
+ ltjd.remove_end_whatsit()
+end
+
+
+-- lastnodechar
+do
+ local id_glyph = node.id('glyph')
+ function luatexja.pltx_composite_last_node_char()
+ local n = tex.nest[tex.nest.ptr].tail
+ local r = '-1'
+ if n then
+ if n.id==id_glyph then
+ while n.componetns and n.subtype and n.subtype%4 >= 2 do
+ n = node.tail(n)
+ end
+ r = tostring(n.char)
+ end
+ end
+ tex.sprint(r)
+ end
+end
+
+-- debug
+
+do
+
+local node_type = node.type
+local node_next = node.next
+local has_attr = node.has_attribute
+
+local id_penalty = node.id('penalty')
+local id_glyph = node.id('glyph')
+local id_glue = node.id('glue')
+local id_kern = node.id('kern')
+local id_hlist = node.id('hlist')
+local id_vlist = node.id('vlist')
+local id_rule = node.id('rule')
+local id_math = node.id('math')
+local id_whatsit = node.id('whatsit')
+local sid_user = node.subtype('user_defined')
+
+local function get_attr_icflag(p)
+ return (has_attr(p, attr_icflag) or 0) % icflag_table.PROCESSED_BEGIN_FLAG
+end
+
+local prefix, inner_depth
+local utfchar = utf.char
+local function debug_show_node_X(p,print_fn, limit)
+ local k = prefix
+ local s
+ local pt=node_type(p.id)
+ local base = prefix .. string.format('%X', get_attr_icflag(p))
+ .. ' ' .. pt .. ' ' .. tostring(p.subtype) .. ' '
+ if pt == 'glyph' then
+ s = base .. ' ' ..
+ (p.char>=0xF0000 and string.format('(U+%X)', p.char) or utfchar(p.char)) .. ' '
+ .. tostring(p.font) .. ' (' .. print_scaled(p.height) .. '+'
+ .. print_scaled(p.depth) .. ')x' .. print_scaled(p.width)
+ if p.xoffset~=0 or p.yoffset~=0 then
+ s = s .. ' off: (' .. print_scaled(p.xoffset)
+ .. ',' .. print_scaled(p.yoffset) .. ')'
+ end
+ print_fn(s)
+ elseif pt=='hlist' or pt=='vlist' or pt=='unset'or pt=='ins' then
+ if pt=='ins' then
+ s = base .. '(' .. print_scaled(p.height) .. '+'
+ .. print_scaled(p.depth) .. ')'
+ .. ', dir=' .. tostring(node.has_attribute(p, attr_dir))
+ else
+ s = base .. '(' .. print_scaled(p.height) .. '+'
+ .. print_scaled(p.depth) .. ')x' .. print_scaled(p.width)
+ .. ', dir=' .. tostring(node.has_attribute(p, attr_dir))
+ end
+ if (p.shift or 0)~=0 then
+ s = s .. ', shifted ' .. print_scaled(p.shift)
+ end
+ if p.glue_set and p.glue_sign ==2 or ( p.glue_sign==1 and p.glue_set>0) then
+ s = s .. ' glue set '
+ if p.glue_sign == 2 then s = s .. '-' end
+ s = s .. tostring(floor(p.glue_set*10000)/10000)
+ if p.glue_order == 0 then
+ s = s .. 'pt'
+ else
+ s = s .. 'fi'
+ for i = 2, p.glue_order do s = s .. 'l' end
+ end
+ end
+ if get_attr_icflag(p) == icflag_table.PACKED then
+ s = s .. ' (packed)'
+ end
+ print_fn(s);
+ local bid = inner_depth
+ prefix, inner_depth = prefix.. '.', inner_depth + 1
+ if inner_depth < limit then
+ for q in node.traverse(p.head) do
+ debug_show_node_X(q, print_fn, limit)
+ end
+ end
+ prefix=k
+ elseif pt=='rule' then
+ s = base .. '(' .. print_scaled(p.height) .. '+'
+ .. print_scaled(p.depth) .. ')x' .. print_scaled(p.width)
+ .. ', dir=' .. tostring(node.has_attribute(p, attr_dir))
+ print_fn(s)
+ elseif pt=='disc' then
+ print_fn(s)
+ local bid = inner_depth
+ if inner_depth < limit then
+ prefix, inner_depth = k.. 'p.', inner_depth + 1
+ for q in node.traverse(p.pre) do
+ debug_show_node_X(q, print_fn, limit)
+ end
+ prefix = k.. 'P.'
+ for q in node.traverse(p.post) do
+ debug_show_node_X(q, print_fn, limit)
+ end
+ prefix = k.. 'R.'
+ for q in node.traverse(p.replace) do
+ debug_show_node_X(q, print_fn, limit)
+ end
+ end
+ prefix=k
+ elseif pt == 'glue' then
+ s = base .. ' ' .. print_spec(p)
+ if get_attr_icflag(p)>icflag_table.KINSOKU
+ and get_attr_icflag(p)<icflag_table.KANJI_SKIP then
+ s = s .. ' (from JFM: priority ' .. get_attr_icflag(p)-icflag_table.FROM_JFM .. ')'
+ elseif get_attr_icflag(p)==icflag_table.KANJI_SKIP then
+ s = s .. ' (kanjiskip)'
+ elseif get_attr_icflag(p)==icflag_table.KANJI_SKIP_JFM then
+ s = s .. ' (kanjiskip, JFM specified)'
+ elseif get_attr_icflag(p)==icflag_table.XKANJI_SKIP then
+ s = s .. ' (xkanjiskip)'
+ elseif get_attr_icflag(p)==icflag_table.XKANJI_SKIP_JFM then
+ s = s .. ' (xkanjiskip, JFM specified)'
+ end
+ print_fn(s)
+ elseif pt == 'kern' then
+ s = base .. ' ' .. print_scaled(p.kern) .. 'pt'
+ if p.subtype==2 then
+ s = s .. ' (for accent)'
+ elseif get_attr_icflag(p)==icflag_table.IC_PROCESSED then
+ s = s .. ' (italic correction)'
+ elseif get_attr_icflag(p)==icflag_table.LINEEND then
+ s = s .. ' (end-of-line)'
+ -- elseif get_attr_icflag(p)==ITALIC then
+ -- s = s .. ' (italic correction)'
+ elseif get_attr_icflag(p)>icflag_table.KINSOKU
+ and get_attr_icflag(p)<icflag_table.KANJI_SKIP then
+ s = s .. ' (from JFM: priority ' .. get_attr_icflag(p)-icflag_table.FROM_JFM .. ')'
+ end
+ print_fn(s)
+ elseif pt == 'penalty' then
+ s = base .. ' ' .. tostring(p.penalty)
+ if get_attr_icflag(p)==icflag_table.KINSOKU then
+ s = s .. ' (for kinsoku)'
+ end
+ print_fn(s)
+ elseif pt == 'whatsit' then
+ s = base
+ if p.subtype==sid_user then
+ local t = tostring(p.user_id) .. ' (' ..
+ luatexbase.get_user_whatsit_name(p.user_id) .. ') '
+ if p.type ~= 110 then
+ s = s .. ' userid:' .. t .. p.value
+ print_fn(s)
+ else
+ s = s .. ' userid:' .. t .. '(node list)'
+ if p.user_id==userid_table.DIR then
+ s = s .. ' dir: ' .. tostring(node.has_attribute(p, attr_dir))
+ end
+ print_fn(s)
+ local bid = inner_depth
+ prefix, inner_depth =prefix.. '.', inner_depth + 1
+ if inner_depth < limit then
+ for q in node.traverse(p.value) do
+ debug_show_node_X(q, print_fn, limit)
+ end
+ end
+ prefix, inner_depth = k, bid
+ end
+ else
+ s = s .. (node.subtype(p.subtype) or '')
+ if p.subtype==1 then
+ s = s .. ' stream=' .. p.stream
+ print_fn(s)
+ for i=1,#p.data do
+ print_fn(s .. ' [' .. i .. '] = ' .. tostring(p.data[i].csname))
+ end
+ else
+ print_fn(s)
+ end
+ end
+ -------- math node --------
+ elseif pt=='noad' then
+ s = base ; print_fn(s)
+ if p.nucleus then
+ prefix = k .. 'N'; debug_show_node_X(p.nucleus, print_fn, limit);
+ end
+ if p.sup then
+ prefix = k .. '^'; debug_show_node_X(p.sup, print_fn, limit);
+ end
+ if p.sub then
+ prefix = k .. '_'; debug_show_node_X(p.sub, print_fn, limit);
+ end
+ prefix = k;
+ elseif pt=='math_char' then
+ s = base .. ' fam: ' .. p.fam .. ' , char = ' .. utfchar(p.char)
+ print_fn(s)
+ elseif pt=='sub_box' or pt=='sub_mlist' then
+ print_fn(base)
+ if p.head then
+ prefix = k .. '.';
+ for q in node.traverse(p.head) do
+ debug_show_node_X(q, print_fn)
+ end
+ end
+ else
+ print_fn(base)
+ end
+ p=node_next(p)
+end
+function luatexja.ext_show_node_list(head,depth,print_fn, lim)
+ prefix = depth
+ inner_depth = 0
+ if head then
+ while head do
+ debug_show_node_X(head, print_fn, lim or 1/0); head = node_next(head)
+ end
+ else
+ print_fn(prefix .. ' (null list)')
+ end
+end
+function luatexja.ext_show_node(head,depth,print_fn, lim)
+ prefix = depth
+ inner_depth = 0
+ if head then
+ debug_show_node_X(head, print_fn, lim or 1/0)
+ else
+ print_fn(prefix .. ' (null list)')
+ end
+end
+
+end
diff --git a/macros/luatex/generic/luatexja/src/luatexja.sty b/macros/luatex/generic/luatexja/src/luatexja.sty
new file mode 100644
index 0000000000..71f90ca327
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/luatexja.sty
@@ -0,0 +1,61 @@
+%
+% luatexja.sty
+%
+%! 外ã‹ã‚‰èª­ã¾ã‚Œã‚‹ã®ã§å¤šå°‘仰々ã—ããªã£ã¦ã¾ã™
+%% Avoid multiple loading.
+\csname\if11luatexjaLoaded\fi\endcsname
+\edef\x{%
+\catcode32=\the\catcode32%
+\catcode45=\the\catcode45%
+\catcode46=\the\catcode46%
+\catcode64=\the\catcode64%
+\catcode91=\the\catcode91%
+\catcode93=\the\catcode93%
+\endlinechar=\the\endlinechar
+\relax}
+\catcode32=10 %< >
+\catcode45=12 %<->
+\catcode46=12 %<.>
+\catcode64=11 %<@>
+\catcode91=12 %<[>
+\catcode93=12 %<]>
+\endlinechar=13 %
+%! ã‚ã¾ã‚Šæ©æµãŒãªã„ã®ã§ \endlinechar=-1 ã¯ãªã—
+\edef\ltj@AtEnd{\x
+ \noexpand\let\noexpand\ltj@AtEnd\relax}
+\def\luatexjaLoaded{\endinput}
+\newif\ifltj@disablejfam
+
+%% Check if LaTeX is used.
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax %<*!LaTeX>
+ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname
+ \csname iffalse\endcsname
+\else %<*LaTeX>
+ \expandafter\let\csname ifltj@in@latex\expandafter\endcsname
+ \csname iftrue\endcsname
+ \NeedsTeXFormat{LaTeX2e}
+ \ProvidesPackage{luatexja}[2019/04/08 Japanese Typesetting with Lua(La)TeX]
+ \DeclareOption{disablejfam}{\ltj@disablejfamtrue}
+ \DeclareOption*{}
+ \ProcessOptions\relax
+\fi %</LaTeX>
+%%%% VERSION
+\def\LuaTeXjaversion{20190827.0}
+
+\directlua{require('ltj-unicode-ccfix.lua')}% catcode of ideographs
+
+%% Load all sub-packages.
+\ifltj@in@latex %<*LaTeX>
+ %% \RequirePackage{expl3} needed if the version of l3kernel is v6111
+ \RequirePackage{luatexja-core,luatexja-compat}
+\else %<*!LaTeX>
+ \input luatexja-core.sty %
+ \input luatexja-compat.sty %
+\fi %</LaTeX>
+
+\directlua{luatexja.base.start_time_measure('RUN')}
+%% all done
+\ltj@AtEnd
+\endinput
+%% EOF
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjcore.sty b/macros/luatex/generic/luatexja/src/patches/lltjcore.sty
new file mode 100644
index 0000000000..100a1c2b7e
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjcore.sty
@@ -0,0 +1,339 @@
+%
+% lltjcore.sty: derived from plcore.dtx in pLaTeX.
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lltjcore}[2018/06/15 Patch to LaTeX2e Kernel for LuaTeX-ja]
+\RequirePackage{etoolbox}
+
+\def\cleardoublepage{\clearpage\if@twoside
+ \ifodd\c@page
+ \ifnum\ltjgetparameter{direction}=3
+ \hbox{}\thispagestyle{empty}\newpage
+ \if@twocolumn\hbox{}\newpage\fi
+ \fi
+ \else
+ \ifnum\ltjgetparameter{direction}=4
+ \hbox{}\thispagestyle{empty}\newpage
+ \if@twocolumn\hbox{}\newpage\fi
+ \fi
+ \fi\fi}
+\newif\iftombow \tombowfalse
+\newif\iftombowdate \tombowdatetrue
+\newdimen\@tombowwidth
+\setlength{\@tombowwidth}{.1\p@}
+\newbox\@TL\newbox\@Tl
+\newbox\@TC
+\newbox\@TR\newbox\@Tr
+\newbox\@BL\newbox\@Bl
+\newbox\@BC
+\newbox\@BR\newbox\@Br
+\newbox\@CL
+\newbox\@CR
+\font\@bannerfont=cmtt9
+\newtoks\@bannertoken
+\@bannertoken{}
+\def\maketombowbox{%
+ \setbox\@TL\hbox to\z@{\yoko\hss
+ \vrule width\dimexpr 10mm+\@tombowbleed\relax height\@tombowwidth depth\z@
+ \vrule height10mm width\@tombowwidth depth\z@
+ \iftombowdate
+ \raise4pt\hbox to\z@{\hskip5mm\@bannerfont\the\@bannertoken\hss}%
+ \fi}%
+ \setbox\@Tl\hbox to\z@{\yoko\hss
+ \vrule width10mm height\@tombowwidth depth\z@
+ \vrule height\dimexpr 10mm+\@tombowbleed\relax width\@tombowwidth depth\z@}%
+ \setbox\@TC\hbox{\yoko
+ \vrule width10mm height\@tombowwidth depth\z@
+ \vrule height10mm width\@tombowwidth depth\z@
+ \vrule width10mm height\@tombowwidth depth\z@}%
+ \setbox\@TR\hbox to\z@{\yoko
+ \vrule height10mm width\@tombowwidth depth\z@
+ \vrule width\dimexpr 10mm+\@tombowbleed\relax height\@tombowwidth depth\z@\hss}%
+ \setbox\@Tr\hbox to\z@{\yoko
+ \vrule height\dimexpr 10mm+\@tombowbleed\relax width\@tombowwidth depth\z@
+ \vrule width10mm height\@tombowwidth depth\z@\hss}%
+ \setbox\@BL\hbox to\z@{\yoko\hss
+ \vrule width\dimexpr 10mm+\@tombowbleed\relax depth\@tombowwidth height\z@
+ \vrule depth10mm width\@tombowwidth height\z@}%
+ \setbox\@Bl\hbox to\z@{\yoko\hss
+ \vrule width10mm depth\@tombowwidth height\z@
+ \vrule depth\dimexpr 10mm+\@tombowbleed\relax width\@tombowwidth height\z@}%
+ \setbox\@BC\hbox{\yoko
+ \vrule width10mm depth\@tombowwidth height\z@
+ \vrule depth10mm width\@tombowwidth height\z@
+ \vrule width10mm depth\@tombowwidth height\z@}%
+ \setbox\@BR\hbox to\z@{\yoko
+ \vrule depth10mm width\@tombowwidth height\z@
+ \vrule width\dimexpr 10mm+\@tombowbleed\relax depth\@tombowwidth height\z@\hss}%
+ \setbox\@Br\hbox to\z@{\yoko
+ \vrule depth\dimexpr 10mm+\@tombowbleed\relax width\@tombowwidth height\z@
+ \vrule width10mm depth\@tombowwidth height\z@\hss}%
+ \setbox\@CL\hbox to\z@{\yoko\hss
+ \vrule width10mm height.5\@tombowwidth depth.5\@tombowwidth
+ \vrule height10mm depth10mm width\@tombowwidth}%
+ \setbox\@CR\hbox to\z@{\yoko
+ \vrule height10mm depth10mm width\@tombowwidth
+ \vrule height.5\@tombowwidth depth.5\@tombowwidth width10mm\hss}%
+}
+\def\@outputtombow{%
+ \iftombow
+ \vbox to\z@{\kern-\dimexpr 10mm+\@tombowbleed\relax
+ \boxmaxdepth\maxdimen
+ \moveleft\@tombowbleed\vbox to\@@paperheight{%
+ \color@begingroup
+ \@tombowcolor
+ \hbox to\@@paperwidth{\hskip\@tombowbleed\relax
+ \copy\@TL\hfill\copy\@TC\hfill\copy\@TR\hskip\@tombowbleed}%
+ \kern-10mm
+ \hbox to\@@paperwidth{\copy\@Tl\hfill\copy\@Tr}%
+ \vfill
+ \hbox to\@@paperwidth{\copy\@CL\hfill\copy\@CR}%
+ \vfill
+ \hbox to\@@paperwidth{\copy\@Bl\hfill\copy\@Br}%
+ \kern-10mm
+ \hbox to\@@paperwidth{\hskip\@tombowbleed\relax
+ \copy\@BL\hfill\copy\@BC\hfill\copy\@BR\hskip\@tombowbleed}%
+ \color@endgroup
+ }\vss
+ }%
+ \fi
+}
+\def\@tombowcolor{\normalcolor}
+\def\@tombowbleed{3mm}
+\def\@tombowreset@@paper{%
+ \@@topmargin\topmargin
+ \iftombow
+ \@@paperwidth\paperwidth
+ \advance\@@paperwidth 2\dimexpr\@tombowbleed\relax
+ \@@paperheight\paperheight\advance\@@paperheight 10mm\relax
+ \advance\@@paperheight 2\dimexpr\@tombowbleed\relax
+ \advance\@@topmargin 1in\relax \advance\@themargin 1in\relax
+ \fi
+}
+\newdimen\@@paperheight
+\newdimen\@@paperwidth
+\newdimen\@@topmargin
+\def\@outputpage{%
+\begingroup % the \endgroup is put in by \aftergroup
+ \ifnum\ltjgetparameter{direction}=4\else
+ \dimen\z@\textwidth \textwidth\textheight \textheight\dimen\z@
+ \fi
+ \let \protect \noexpand
+ \language\document@default@language %LaTeX2e 2017/05/01
+ \@resetactivechars
+ \global\let\@@if@newlist\if@newlist
+ \global\@newlistfalse
+ \@parboxrestore
+ \shipout\vbox{\yoko
+ \set@typeset@protect
+ \aftergroup\endgroup
+ \aftergroup\set@typeset@protect
+ \if@specialpage
+ \global\@specialpagefalse\@nameuse{ps@\@specialstyle}%
+ \fi
+ \if@twoside
+ \ifodd\count\z@ \let\@thehead\@oddhead \let\@thefoot\@oddfoot
+ \ifnum\ltjgetparameter{direction}=3 \let\@themargin\evensidemargin
+ \else\let\@themargin\oddsidemargin\fi
+ \else \let\@thehead\@evenhead
+ \let\@thefoot\@evenfoot
+ \ifnum\ltjgetparameter{direction}=3 \let\@themargin\oddsidemargin
+ \else\let\@themargin\evensidemargin\fi
+ \fi\fi
+ \@tombowreset@@paper
+ \reset@font
+ \normalsize
+ \normalsfcodes
+ \let\label\@gobble
+ \let\index\@gobble
+ \let\glossary\@gobble
+ \baselineskip\z@skip \lineskip\z@skip \lineskiplimit\z@
+ \@begindvi
+ \@outputtombow
+ \vskip \@@topmargin
+ \moveright\@themargin\vbox{%
+ \setbox\@tempboxa \vbox to\headheight{%
+ \vfil
+ \color@hbox
+ \normalcolor
+ \hb@xt@\textwidth{\@thehead}%
+ \color@endbox
+ }% %% 22 Feb 87
+ \dp\@tempboxa \z@
+ \box\@tempboxa
+ \vskip \headsep
+ \box\@outputbox
+ \baselineskip \footskip
+ \color@hbox
+ \normalcolor
+ \hb@xt@\textwidth{\@thefoot}%
+ \color@endbox
+ }%
+ }%
+ \global\let\if@newlist\@@if@newlist
+ \global \@colht \textheight
+ \stepcounter{page}%
+ \let\firstmark\botmark
+}
+
+%%% Remove extra xkanjiskip
+\renewcommand\@makefnmark{%
+ \unless\ifnum\ltjgetparameter{direction}=3
+ \hbox{}\hbox{\@textsuperscript{\normalfont\@thefnmark}}\hbox{}%
+ \else\hbox{\yoko \@textsuperscript{\normalfont\@thefnmark}}\fi}
+\begingroup
+\@ifpackageloaded{hyperref}
+ {\def\ltj@setrefprefix{real}}
+ {\def\ltj@setrefprefix{}}
+\expandafter\gdef\csname \ltj@setrefprefix @setref\endcsname#1#2#3{%
+ \ifx#1\relax
+ \protect\G@refundefinedtrue
+ \nfss@text{\reset@font\bfseries ??}%
+ \@latex@warning{Reference `#3' on page \thepage \space
+ undefined}%
+ \else
+ \expandafter#2#1\protect\@setref@{}% change \null to \protect\@setref@{}
+ \fi}
+\gdef\@setref@{\ifhmode\spacefactor\@m\fi}
+\endgroup
+\if@compatibility\else
+\def\verb{\relax\ifmmode\hbox\else\leavevmode\vadjust{}\fi
+ \bgroup
+ \verb@eol@error \let\do\@makeother \dospecials
+ \verbatim@font\@noligs
+ \language\l@nohyphenation
+ \@ifstar\@sverb\@verb}
+\fi
+\gdef\@stopfield{%
+ \inhibitglue\@tempskipa\lastskip\unskip
+ \hskip\@tempskipa\color@endgroup\egroup}
+\pretocmd{\footnote}{\inhibitglue}{}{}
+\pretocmd{\footnotemark}{\inhibitglue}{}{}
+\patchcmd{\@footnotemark}{\@makefnmark}{%
+ \unless\ifnum\ltjgetparameter{direction}=3 \@makefnmark%
+ \else\hbox to\z@{\hskip-.25\zw\raise.9\zh\@makefnmark\hss}\fi%
+}{}{}
+\let\@parboxto\@empty
+\long\def\@iiiparbox#1#2[#3]#4#5{%
+ \leavevmode
+ \@pboxswfalse
+ \setlength\@tempdima{#4}%
+ \@begin@tempboxa\vbox{\hsize\@tempdima\@parboxrestore#5\@@par}%
+ \ifx\relax#2\else
+ \setlength\@tempdimb{#2}%
+ \edef\@parboxto{to\the\@tempdimb}%
+ \fi
+ \if#1b\vbox
+ \else\if #1t\vtop
+ \else\ifmmode\vcenter
+ \else\@pboxswtrue\null$\vcenter% !!!
+ \fi\fi\fi
+ \@parboxto{\let\hss\vss\let\unhbox\unvbox
+ \csname bm@#3\endcsname}%
+ \if@pboxsw \m@th$\null\fi% !!!
+ \@end@tempboxa}
+\def\underline#1{%
+ \relax
+ \ifmmode\@@underline{#1}%
+ \else \leavevmode\null$\@@underline{\hbox{#1}}\m@th$\null\relax\fi}
+
+%%% AtBeginDvi
+\def \AtBeginDvi #1{%
+ \global \setbox \@begindvibox
+ \vbox{\yoko\unvbox \@begindvibox #1}%
+}
+
+\newif\iffnfixbottom
+\newif\ifltj@ftn@unvboxed
+%%% @makecol
+\gdef \@makecol {%
+ \ifvoid\footins
+ \ltj@ftn@unvboxedfalse
+ \setbox\@outputbox \box\@cclv
+ \else
+ \ltj@ftn@unvboxedtrue
+ \setbox\@outputbox \vbox {%
+ \boxmaxdepth \@maxdepth
+ \unvbox \@cclv
+ \iffnfixbottom\vskip\z@ \@plus.0001fil\fi
+ \vskip \skip\footins
+ \color@begingroup
+ \normalcolor
+ \footnoterule
+ \unvbox \footins
+ \color@endgroup
+ }%
+ \fi
+ \let\@elt\relax
+ \xdef\@freelist{\@freelist\@midlist}%
+ \global \let \@midlist \@empty
+ \@combinefloats
+ \ifvbox\@kludgeins
+ \@makespecialcolbox
+ \else
+ \setbox\@outputbox \vbox to\@colht {%
+ \@texttop
+ \dimen@ \dp\@outputbox
+ \unvbox \@outputbox
+ \ifnum\ltjgetparameter{direction}=4\else\vbox{\hskip\z@}\fi %%% LuaTeX-ja
+ \vskip -\dimen@
+ \ifltj@ftn@unvboxed\iffnfixbottom\else\@textbottom\fi\else\@textbottom\fi
+ }%
+ \fi
+ \global \maxdepth \@maxdepth
+}
+\let\ltj@orig@makecol=\@makecol
+
+\patchcmd\@makespecialcolbox{\@textbottom}{\ifltj@ftn@unvboxed\iffnfixbottom\else\@textbottom\fi\else\@textbottom\fi}{}{}
+
+\def\@gnewline #1{%
+ \ifvmode
+ \@nolnerr
+ \else
+ \unskip \reserved@e {\reserved@f#1}\nobreak \hfil \break \null
+ % \null 㯠\break ã®åŠ¹æžœãŒè¡Œé ­ç¦å‰‡æ–‡å­—ã§æ‰“ã¡æ¶ˆã•ã‚Œãªã„ãŸã‚ã«å¿…è¦
+ \ignorespaces
+\fi}
+
+
+%%%%%% tabular (platex/#43) \@tabclassz
+\def\ltj@sharp{\relax\pltx@next@inhibitglue\ltjfakeboxbdd\ignorespaces\@sharp\unskip\ltjfakeboxbdd}
+\def\@tabclassz{%
+ \ifcase\@lastchclass
+ \@acolampacol
+ \or
+ \@ampacol
+ \or
+ \or
+ \or
+ \@addamp
+ \or
+ \@acolampacol
+ \or
+ \@firstampfalse\@acol
+ \fi
+ \edef\@preamble{%
+ \@preamble{%
+ \ifcase\@chnum
+ \hfil\hskip1sp\ltj@sharp\hfil
+ \or
+ \hskip1sp\ltj@sharp\hfil
+ \or
+ \hfil\hskip1sp\ltj@sharp
+ \fi}}}
+\patchcmd\@classv{%
+ \ignorespaces\@sharp
+}{%
+ \everypar\expandafter{\the\everypar\ltjfakeboxbdd}\ignorespaces\@sharp\unskip
+}{}{}
+\patchcmd{\@tabular}{\leavevmode}{\leavevmode\null}{}{}
+\apptocmd{\endtabular}{\null}{}{}
+\expandafter \let \csname endtabular*\endcsname = \endtabular
+
+%%%%%% tabbing (platex/#53)
+\patchcmd\@startline{\strut}{\strut\inhibitglue}{}{}
+\def\ltj@unhbox@curfield{\ltjfakeboxbdd\unhbox\@curfield\ltjfakeboxbdd}
+%\patchcmd\@contfield{\unhbox\@curfield}{\ltj@unhbox@curfield}{}{}
+\patchcmd\@addfield{\unhbox\@curfield}{\ltj@unhbox@curfield}{}{}
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjdefs.sty b/macros/luatex/generic/luatexja/src/patches/lltjdefs.sty
new file mode 100644
index 0000000000..52649e8426
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjdefs.sty
@@ -0,0 +1,230 @@
+%
+% lltjdefs.sty
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lltjdefs}[2019/08/21 Default font settings of LuaTeX-ja]
+
+\ifdefined\ltj@stdmcfont\else\def\ltj@stdmcfont{IPAExMincho}\fi
+\ifdefined\ltj@stdgtfont\else\def\ltj@stdgtfont{IPAExGothic}\fi
+\ifdefined\ltj@stdyokojfm\else\def\ltj@stdyokojfm{ujis}\fi
+\ifdefined\ltj@stdtatejfm\else\def\ltj@stdtatejfm{ujisv}\fi
+\InputIfFileExists{luatexja.cfg}{%
+ \typeout{*************************^^J%
+ * Loading luatexja.cfg.^^J%
+ *************************}%
+}{}
+
+\DeclareKanjiEncodingDefaults{}{}
+\DeclareErrorKanjiFont{JY3}{mc}{m}{n}{10}
+\kanjifamily{mc}
+\kanjiseries{m}
+\kanjishape{n}
+\fontsize{10}{10}
+\DeclareYokoKanjiEncoding{JY3}{}{}
+\DeclareKanjiSubstitution{JY3}{mc}{m}{n}
+\DeclareTateKanjiEncoding{JT3}{}{}
+\DeclareKanjiSubstitution{JT3}{mc}{m}{n}
+
+\newcommand\mcdefault{mc}
+\newcommand\gtdefault{gt}
+\newcommand\jttdefault{\mcdefault}
+\newcommand\kanjiencodingdefault{JY3}
+\newcommand\kanjifamilydefault{\mcdefault}
+\newcommand\kanjiseriesdefault{\mddefault}
+\newcommand\kanjishapedefault{\updefault}
+
+\DeclareKanjiFamily{JY3}{mc}{}
+\DeclareFontShape{JY3}{mc}{m}{n}{<-> s*[\ifdefined\Cjascale\Cjascale\else 0.962216\fi] \ltj@stdmcfont:jfm=\ltj@stdyokojfm}{}
+\DeclareKanjiFamily{JY3}{gt}{}
+\DeclareFontShape{JY3}{gt}{m}{n}{<-> s*[\ifdefined\Cjascale\Cjascale\else 0.962216\fi] \ltj@stdgtfont:jfm=\ltj@stdyokojfm}{}
+\DeclareFontShape{JY3}{mc}{bx}{n}{<-> ssub*gt/m/n}{}
+\DeclareFontShape{JY3}{gt}{bx}{n}{<-> ssub*gt/m/n}{}
+\DeclareFontShape{JY3}{mc}{b}{n}{<-> ssub*mc/bx/n}{}
+\DeclareFontShape{JY3}{gt}{b}{n}{<-> ssub*gt/bx/n}{}
+
+\DeclareKanjiFamily{JT3}{mc}{}
+\DeclareFontShape{JT3}{mc}{m}{n}{<-> s*[\ifdefined\Cjascale\Cjascale\else 0.962216\fi] \ltj@stdmcfont:jfm=\ltj@stdtatejfm}{}
+\DeclareKanjiFamily{JT3}{gt}{}
+\DeclareFontShape{JT3}{gt}{m}{n}{<-> s*[\ifdefined\Cjascale\Cjascale\else 0.962216\fi] \ltj@stdgtfont:jfm=\ltj@stdtatejfm}{}
+\DeclareFontShape{JT3}{mc}{bx}{n}{<-> ssub*gt/m/n}{}
+\DeclareFontShape{JT3}{gt}{bx}{n}{<-> ssub*gt/m/n}{}
+\DeclareFontShape{JT3}{mc}{b}{n}{<-> ssub*mc/bx/n}{}
+\DeclareFontShape{JT3}{gt}{b}{n}{<-> ssub*gt/bx/n}{}
+\KanjiEncodingPair{JY3}{JT3}
+
+\DeclareRelationFont{JY3}{gt}{m}{}{TU}{lmr}{bx}{}
+\DeclareRelationFont{JY3}{mc}{m}{}{TU}{lmr}{m}{}
+\DeclareRelationFont{JY3}{mc}{bx}{}{TU}{lmr}{bx}{}
+\DeclareRelationFont{JY3}{mc}{b}{}{TU}{lmr}{b}{}
+\DeclareRelationFont{JT3}{gt}{m}{}{TU}{lmr}{bx}{}
+\DeclareRelationFont{JT3}{mc}{m}{}{TU}{lmr}{m}{}
+\DeclareRelationFont{JT3}{mc}{bx}{}{TU}{lmr}{bx}{}
+\DeclareRelationFont{JT3}{mc}{b}{}{TU}{lmr}{b}{}
+
+\kanjiencoding{JY3}\selectfont\adjustbaseline
+
+\DeclareTextFontCommand{\textmc}{\mcfamily}
+\DeclareTextFontCommand{\textgt}{\gtfamily}
+\DeclareOldFontCommand{\mc}{\normalfont\mcfamily}{}
+\DeclareOldFontCommand{\gt}{\normalfont\gtfamily}{}
+
+\unless\ifltj@disablejfam
+ \DeclareSymbolFont{mincho}{JY3}{mc}{m}{n}
+ \jfam\symmincho
+ \SetSymbolFont{mincho}{bold}{JY3}{gt}{m}{n}
+ \DeclareSymbolFontAlphabet{\mathmc}{mincho}
+ \DeclareMathAlphabet{\mathgt}{JY3}{gt}{m}{n}
+\fi
+
+\newif\if@ltj@match@family
+\@ltj@match@familyfalse
+\def\verbatim@font{\normalfont\ttfamily\kanjifamily\jttdefault\selectfont}
+\DeclareRobustCommand\rmfamily
+ {\not@math@alphabet\rmfamily\mathrm
+ \romanfamily\rmdefault
+ \if@ltj@match@family\kanjifamily\mcdefault\fi\selectfont}
+\DeclareRobustCommand\sffamily
+ {\not@math@alphabet\sffamily\mathsf
+ \romanfamily\sfdefault
+ \if@ltj@match@family\kanjifamily\gtdefault\fi\selectfont}
+\DeclareRobustCommand\ttfamily
+ {\not@math@alphabet\ttfamily\mathtt
+ \romanfamily\ttdefault
+ \if@ltj@match@family\kanjifamily\jttdefault\fi\selectfont}
+%%% \eminnershape
+\DeclareRobustCommand\em
+ {\@nomath\em \ifdim \fontdimen\@ne\font >\z@
+ \eminnershape \else \gtfamily \itshape \fi}
+\def\eminnershape{\mcfamily \upshape}
+
+\ltjdefcharrange{1}{"80-"36F, "1E00-"1EFF}
+\ltjdefcharrange{2}{"370-"4FF, "1F00-"1FFF}
+\ltjdefcharrange{3}{%
+ "2000-"243F, "2500-"27BF, "2900-"29FF, "2B00-"2BFF}
+\ltjdefcharrange{4}{%
+ "500-"10FF, "1200-"1DFF, "2440-"245F, "27C0-"28FF, "2A00-"2AFF,
+ "2C00-"2E7F, "4DC0-"4DFF, "A4D0-"A95F, "A980-"ABFF, "E000-"F8FF,
+ "FB00-"FE0F, "FE20-"FE2F, "FE70-"FEFF, "10000-"1AFFF, "1B170-"1F0FF,
+ "1F300-"1FFFF
+} % non-Japanese
+\ltjdefcharrange{5}{"D800-"DFFF, "E0000-"E00FF, "E01F0-"10FFFF}
+\ltjdefcharrange{6}{%
+ "2460-"24FF, "2E80-"2EFF, "3000-"30FF, "3190-"319F, "31F0-"4DBF,
+ "4E00-"9FFF, "F900-"FAFF, "FE10-"FE1F, "FE30-"FE6F, "FF00-"FFEF,
+ "1B000-"1B16F, "1F100-"1F2FF, "20000-"2FFFF, "E0100-"E01EF
+}
+\ltjdefcharrange{7}{%
+ "1100-"11FF, "2F00-"2FFF, "3100-"318F, "31A0-"31EF, "A000-"A4CF,
+ "A960-"A97F, "AC00-"D7FF
+}
+\ltjdefcharrange{8}{"A7, "A8, "B0, "B1, "B4, "B6, "D7, "F7}
+\ltjsetparameter{jacharrange={-1, +2, +3, -4, -5, +6, +7, -8}}
+
+\directlua{for x=128,255 do luatexja.math.is_math_letters[x] = true end}
+\protected\def\<{\ifvmode\leavevmode\fi\inhibitglue}
+
+\directlua{luatexja.jfont.register_vert_replace{
+ [',']='ã€', ['.']='。', ['“']=0x301D, ['â€']=0x301F,
+}}
+
+% END OF FILE
+\endinput
+
+======== comment ========
+
+MIDDLE
+
+\ltjdefcharrange{1}{"80-"36F, "1E00-"1EFF}
+ % 2 "80-"FF num = 471/128 name = Latin-1 Supplement
+ % 3 "100-"17F num = 484/128 name = Latin Extended-A
+ % 4 "180-"24F num = 87/208 name = Latin Extended-B
+ % 5 "250-"2AF num = 154/96 name = IPA Extensions
+ % 6 "2B0-"2FF num = 42/80 name = Spacing Modifier Letters
+ % 7 "300-"36F num = 98/112 name = Combining Diacritical Marks
+ % 64 "1E00-"1EFF num = 16/256 name = Latin Extended Additional
+
+\ltjdefcharrange{2}{"370-"4FF, "1F00-"1FFF}
+ % Greek and Coptic, Cyrillic, Greek Extended
+
+\ltjdefcharrange{3}{%
+ "2000-"243F, "2500-"27BF, "2900-"29FF, "2B00-"2BFF}
+ % 66 "2000-"206F num = 140/112 name = General Punctuation
+ % 67 "2070-"209F num = 68/48 name = Superscripts and Subscripts
+ % 68 "20A0-"20CF num = 5/48 name = Currency Symbols
+ % 69 "20D0-"20FF num = 2/48 name = Combining Diacritical Marks for Symbols
+ % 70 "2100-"214F num = 46/80 name = Letterlike Symbols
+ % 71 "2150-"218F num = 90/64 name = Number Forms
+ % 72 "2190-"21FF num = 39/112 name = Arrows
+ % 73 "2200-"22FF num = 210/256 name = Mathematical Operators
+ % 74 "2300-"23FF num = 69/256 name = Miscellaneous Technical
+ % 75 "2400-"243F num = 1/64 name = Control Pictures
+ % 78 "2500-"257F num = 241 name = Box Drawing
+ % 79 "2580-"259F num = 17 name = Block Elements
+ % 80 "25A0-"25FF num = 70 name = Geometric Shapes
+ % 81 "2600-"26FF num = 49 name = Miscellaneous Symbols
+ % 82 "2700-"27BF num = 23 name = Dingbats
+ % 86 "2900-"297F num = 2 name = Supplemental Arrows-B
+ % 87 "2980-"29FF num = 4 name = Miscellaneous Mathematical Symbols-B
+ % 89 "2B00-"2BFF num = 3 name = Miscellaneous Symbols and Arrows
+
+\ltjdefcharrange{4}{%
+ "500-"10FF, "1200-"1DFF, "2440-"245F, "27C0-"28FF, "2A00-"2AFF,
+ "2C00-"2E7F, "4DC0-"4DFF, "A4D0-"A95F, "A980-"ABFF, "E000-"F8FF,
+ "FB00-"FE0F, "FE20-"FE2F, "FE70-"FEFF, "10000-"1AFFF, "1B170-"1F0FF,
+ "1F300-"1FFFF
+} % non-Japanese
+
+\ltjdefcharrange{5}{"D800-"DFFF, "E0000-"E00FF, "E01F0-"10FFFF}
+ % Surrogates, Tags
+ % 208 "F0000-"FFFFF num = 0/65536 name = Supplementary Private Use Area-A
+ % 209 "100000-"10FFFF num = 0/65536 name = Supplementary Private Use Area-B
+
+POSITIVE
+
+% Japanese
+\ltjdefcharrange{6}{%
+ "2460-"24FF, "2E80-"2EFF, "3000-"30FF, "3190-"319F, "31F0-"4DBF,
+ "4E00-"9FFF, "F900-"FAFF, "FE10-"FE1F, "FE30-"FE6F, "FF00-"FFEF,
+ "1B000-"1B16F, "1F100-"1F2FF, "20000-"2FFFF, "E0100-"E01EF
+}
+% 77 "2460-"24FF num = 150/160 name = Enclosed Alphanumerics
+% 98 "2E80-"2EFF num = 21 name = CJK Radicals Supplement
+% 101 "3000-"303F num = 144 name = CJK Symbols and Punctuation
+% 102 "3040-"309F num = 1074 name = Hiragana
+% 103 "30A0-"30FF num = 985 name = Katakana
+% 106 "3190-"319F num = 16/16 name = Kanbun
+% 109 "31F0-"31FF num = 128 name = Katakana Phonetic Extensions
+% 110 "3200-"32FF num = 143 name = Enclosed CJK Letters and Months
+% 111 "3300-"33FF num = 255 name = CJK Compatibility
+% 112 "3400-"4DBF num = 203 name = CJK Unified Ideographs Extension A
+% 114 "4E00-"9FFF num = 14087 name = CJK Unified Ideographs
+% 143 "F900-"FAFF num = 110/512 name = CJK Compatibility Ideographs
+% 147 "FE10-"FE1F num = 0/16 name = Vertical Forms
+% 149 "FE30-"FE4F num = 8/32 name = CJK Compatibility Forms
+% 150 "FE50-"FE6F num = 0/32 name = Small Form Variants
+% "FF00-"FFEF name = Halfwidth and Fullwidth Forms
+% "1B000-"1B0FF name = Kana Supplement
+% "1B100-"1B12F name = Kana Extended-A
+% "1B130-"1B16F name = Small Kana Extension
+% "1F100-"1F1FF name = Enclosed Alphanumeric Supplement
+% "1F200-"1F2FF name = Enclosed Ideographic Supplement
+% SIP
+% "E0000-"E01EF name = Variation Selectors Supplement
+
+\ltjdefcharrange{7}{%
+ "1100-"11FF, "2F00-"2FFF, "3100-"318F, "31A0-"31EF, "A000-"A4CF,
+ "A960-"A97F, "AC00-"D7FF
+}
+ % 35 "1100-"11FF num = 1 name = Hangul Jamo
+ % 99 "2F00-"2FDF num = 0/224 name = Kangxi Radicals
+ % 100 "2FF0-"2FFF num = 0/16 name = Ideographic Description Characters
+ % 104 "3100-"312F num = 0/48 name = Bopomofo
+ % 105 "3130-"318F num = 0/96 name = Hangul Compatibility Jamo
+ % 107 "31A0-"31BF num = 0/32 name = Bopomofo Extended
+ % 108 "31C0-"31EF num = 0/48 name = CJK Strokes
+ % 115 "A000-"A48F num = 0/1168 name = Yi Syllables
+ % 116 "A490-"A4CF num = 0/64 name = Yi Radicals
+ % "A960-"A97F name = Hangul Jamo Extended-A
+ % 137 "AC00-"D7AF num = 0/11184 name = Hangul Syllables
+ % 138 "D7B0-"D7FF num = 0/80 name = Hangul Jamo Extended-B
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjfont.sty b/macros/luatex/generic/luatexja/src/patches/lltjfont.sty
new file mode 100644
index 0000000000..8068d3326b
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjfont.sty
@@ -0,0 +1,874 @@
+%
+% lltjfont.sty: derived from plfonts.dtx in pLaTeX.
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lltjfont}[2019/08/21 Patch to NFSS2 for LuaTeX-ja]
+
+\def\ltj@chardef@text@cmd#1{%
+ \let\@ifdefinable\@@ifdefinable%
+ \edef\ltj@chardef@text@cmd@name{\expandafter\@gobble\string#1}%
+ \afterassignment\ltj@chardef@text@cmd@\ltj@tempcnta
+}
+\def\ltj@chardef@text@cmd@{%
+ \ifnum\ltj@tempcnta>"7F
+ \expandafter\edef\csname \ltj@chardef@text@cmd@name\endcsname{%
+ \noexpand\ltjalchar\the\ltj@tempcnta\space
+ }%
+ \else
+ \expandafter\chardef\csname \ltj@chardef@text@cmd@name\endcsname\ltj@tempcnta
+ \fi
+}
+\def\DeclareTextSymbol#1#2#3{%
+ \@dec@text@cmd\ltj@chardef@text@cmd#1{#2}#3\relax
+}
+
+\ifdefined\UnicodeEncodingName
+ \let\ltj@temp@DeclareTextComposite=\DeclareTextComposite
+ \def\DeclareTextComposite#1#2#3#4{}%
+ \input{tuenc.def}
+ \let\DeclareTextComposite=\ltj@temp@DeclareTextComposite
+ \expandafter\patchcmd\csname TU\string\textasteriskcentered\endcsname{\char}{\ltjalchar}{}{}
+\fi
+
+
+\let\k@encoding\@empty
+\let\ck@encoding\@empty
+% LuaTeX-ja uses JY3 and JT3 encodings.
+\def\cy@encoding{JY3}\def\ct@encoding{JT3}
+
+\let\k@family\@empty
+\let\k@series\@empty
+\let\k@shape\@empty
+\def\curr@kfontshape{\k@encoding/\k@family/\k@series/\k@shape}
+\def\rel@fontshape{\f@encoding/\f@family/\f@series/\f@shape}
+\ifdefined\Cht\else\newdimen\Cht\fi
+\ifdefined\cht\else\newdimen\cht\fi
+\ifdefined\Cdp\else\newdimen\Cdp\fi
+\ifdefined\cdp\else\newdimen\cdp\fi
+\ifdefined\Cwd\else\newdimen\Cwd\fi
+\ifdefined\cwd\else\newdimen\cwd\fi
+\ifdefined\Cvs\else\newdimen\Cvs\fi
+\ifdefined\cvs\else\newdimen\cvs\fi
+\ifdefined\Chs\else\newdimen\Chs\fi
+\ifdefined\chs\else\newdimen\chs\fi
+\ifdefined\cHT\else\newdimen\cHT\fi
+%\let\afont\font
+
+\let\ystrutbox\strutbox
+\newbox\dstrutbox
+\newbox\tstrutbox
+\newbox\zstrutbox
+\def\strutbox{%
+ \ifnum\ltjgetparameter{direction}=1 \dstrutbox % dtou
+ \else\ifnum\ltjgetparameter{direction}=4 \ystrutbox % yoko
+ \else\tstrutbox % tate and utod
+ \fi\fi
+}
+\def\strut{\relax
+ \ifnum\ltjgetparameter{direction}=1 % dtou
+ \ifmmode\copy\dstrutbox\else\unhcopy\dstrutbox\fi
+ \else\ifnum\ltjgetparameter{direction}=4 % yoko
+ \ifmmode\copy\ystrutbox\else\unhcopy\ystrutbox\fi
+ \else % tate and utod
+ \ifmmode\copy\tstrutbox\else\unhcopy\tstrutbox\fi
+ \fi\fi
+}
+
+\def\ystrut{\relax\hbox{\ltj@@orig@yoko
+ \ifmmode\copy\ystrutbox\else\unhcopy\ystrutbox\fi}}
+\def\tstrut{\relax\hbox{\ltj@@orig@tate
+ \ifmmode\copy\tstrutbox\else\unhcopy\tstrutbox\fi}}
+\def\dstrut{\relax\hbox{\ltj@@orig@dtou
+ \ifmmode\copy\dstrutbox\else\unhcopy\dstrutbox\fi}}
+\def\zstrut{\relax\hbox{\ltj@@orig@utod
+ \ifmmode\copy\zstrutbox\else\unhcopy\zstrutbox\fi}}
+
+{%
+ \def\cdp@elt#1#2#3#4{%
+ \directlua{luatexja.jfont.add_fenc_list('\luatexluaescapestring{#1}')}}%
+ \cdp@list%
+}
+
+\def\DeclareFontEncoding{%
+ \begingroup
+ \nfss@catcodes
+ \expandafter\endgroup
+ \DeclareFontEncoding@}
+\def\DeclareFontEncoding@#1#2#3{%
+ \expandafter
+ \ifx\csname T@#1\endcsname\relax
+ \def\cdp@elt{\noexpand\cdp@elt}%
+ \xdef\cdp@list{\cdp@list\cdp@elt{#1}%
+ {\default@family}{\default@series}%
+ {\default@shape}}%
+ \expandafter\let\csname#1-cmd\endcsname\@changed@cmd
+ \directlua{luatexja.jfont.add_fenc_list('\luatexluaescapestring{#1}')}%
+ \else
+ \@font@info{Redeclaring font encoding #1}%
+ \fi
+ \global\@namedef{T@#1}{#2}%
+ \global\@namedef{M@#1}{\default@M#3}%
+ \xdef\LastDeclaredEncoding{#1}%
+ }
+\def\DeclareKanjiEncoding#1{%
+ \@latex@warning{%
+ The \string\DeclareKanjiEncoding\space is obsoleted command. Please use
+ \MessageBreak
+ the \string\DeclareTateKanjiEncoding\space for `Tate-kumi' encoding, and
+ \MessageBreak
+ the \string\DeclareYokoKanjiEncoding\space for `Yoko-kumi' encoding.
+ \MessageBreak
+ I treat the `#1' encoding as `Yoko-kumi'.}
+ \DeclareYokoKanjiEncoding{#1}%
+}
+\def\DeclareYokoKanjiEncoding{%
+ \begingroup
+ \nfss@catcodes
+ \expandafter\endgroup
+ \DeclareYokoKanjiEncoding@}
+\def\DeclareYokoKanjiEncoding@#1#2#3{%
+ \expandafter\ifx\csname T@#1\endcsname\relax
+ \def\cdp@elt{\noexpand\cdp@elt}%
+ \xdef\cdp@list{\cdp@list\cdp@elt{#1}%
+ {\default@k@family}{\default@k@series}%
+ {\default@k@shape}}%
+ \expandafter\let\csname#1-cmd\endcsname\@changed@kcmd
+ \directlua{luatexja.jfont.add_kyenc_list('\luatexluaescapestring{#1}')}%
+ \else
+ \@font@info{Redeclaring KANJI (yoko) font encoding #1}%
+ \fi
+ \global\@namedef{T@#1}{#2}%
+ \global\@namedef{M@#1}{\default@KM#3}%
+ }
+\def\DeclareTateKanjiEncoding{%
+ \begingroup
+ \nfss@catcodes
+ \expandafter\endgroup
+ \DeclareTateKanjiEncoding@}
+\def\DeclareTateKanjiEncoding@#1#2#3{%
+ \expandafter\ifx\csname T@#1\endcsname\relax
+ \def\cdp@elt{\noexpand\cdp@elt}%
+ \xdef\cdp@list{\cdp@list\cdp@elt{#1}%
+ {\default@k@family}{\default@k@series}%
+ {\default@k@shape}}%
+ \expandafter\let\csname#1-cmd\endcsname\@changed@kcmd
+ \directlua{luatexja.jfont.add_ktenc_list('\luatexluaescapestring{#1}')}%
+ \else
+ \@font@info{Redeclaring KANJI (tate) font encoding #1}%
+ \fi
+ \global\@namedef{T@#1}{#2}%
+ \global\@namedef{M@#1}{\default@KM#3}%
+ }
+\@onlypreamble\DeclareKanjiEncoding
+\@onlypreamble\DeclareYokoKanjiEncoding
+\@onlypreamble\DeclareYokoKanjiEncoding@
+\@onlypreamble\DeclareTateKanjiEncoding
+\@onlypreamble\DeclareTateKanjiEncoding@
+\def\DeclareKanjiEncodingDefaults#1#2{%
+ \ifx\relax#1\else
+ \ifx\default@KT\@empty\else
+ \@font@info{Overwriting KANJI encoding scheme text defaults}%
+ \fi
+ \gdef\default@KT{#1}%
+ \fi
+ \ifx\relax#2\else
+ \ifx\default@KM\@empty\else
+ \@font@info{Overwriting KANJI encoding scheme math defaults}%
+ \fi
+ \gdef\default@KM{#2}%
+ \fi}
+\let\default@KT\@empty
+\let\default@KM\@empty
+\@onlypreamble\DeclareKanjiEncodingDefaults
+\def\DeclareFontFamily#1#2#3{%
+ \@ifundefined{T@#1}%
+ {\@latex@error{Encoding scheme `#1' unknown}\@eha}%
+ {\def\reserved@a{#3}%
+ \global
+ \expandafter\let\csname #1+#2\expandafter\endcsname
+ \ifx \reserved@a\@empty
+ \@empty
+ \else \reserved@a
+ \fi
+ \directlua{luatexja.jfont.add_ffam('\luatexluaescapestring{#2}')}%
+ }%
+}
+\def\DeclareKanjiFamily#1#2#3{%
+ \@ifundefined{T@#1}%
+ {\@latex@error{KANJI Encoding scheme `#1' unknown}\@eha}%
+ {\def\reserved@a{#3}%
+ \global
+ \expandafter\let\csname #1+#2\expandafter\endcsname
+ \ifx \reserved@a\@empty
+ \@empty
+ \else \reserved@a
+ \fi
+ \directlua{luatexja.jfont.add_kfam('\luatexluaescapestring{#2}')}%
+ }%
+}
+\def\DeclareKanjiSubstitution#1#2#3#4{%
+ \expandafter\ifx\csname T@#1\endcsname\relax
+ \@latex@error{KANJI Encoding scheme `#1' unknown}\@eha
+ \else
+ \begingroup
+ \def\reserved@a{#1}%
+ \toks@{}%
+ \def\cdp@elt##1##2##3##4{%
+ \def\reserved@b{##1}%
+ \ifx\reserved@a\reserved@b
+ \addto@hook\toks@{\cdp@elt{#1}{#2}{#3}{#4}}%
+ \else
+ \addto@hook\toks@{\cdp@elt{##1}{##2}{##3}{##4}}%
+ \fi}%
+ \cdp@list
+ \xdef\cdp@list{\the\toks@}%
+ \endgroup
+ \global\@namedef{D@#1}{\def\default@family{#2}%
+ \def\default@series{#3}%
+ \def\default@shape{#4}}%
+ \fi}
+\@onlypreamble\DeclareKanjiSubstitution
+\def\DeclareErrorKanjiFont#1#2#3#4#5{%
+ \xdef\error@kfontshape{%
+ \noexpand\expandafter\noexpand\split@name\noexpand\string
+ \expandafter\noexpand\csname#1/#2/#3/#4/#5\endcsname
+ \noexpand\@nil}%
+ \gdef\default@k@family{#2}%
+ \gdef\default@k@series{#3}%
+ \gdef\default@k@shape{#4}%
+ }
+\@onlypreamble\DeclareErrorKanjiFont
+
+\newif\ifltjselectfont@force@define
+\def\DeclareFixedFont#1#2#3#4#5#6{%
+ \begingroup
+ \math@fontsfalse
+ \every@math@size{}%
+ \fontsize{#6}\z@
+ \directlua{luatexja.jfont.is_kyenc('\luatexluaescapestring{#2}')}\ifin@%
+ \ltjselectfont@force@definetrue
+ \usekanji{#2}{#3}{#4}{#5}%
+ \global\let#1\getjfont
+ \ltjselectfont@force@definefalse
+ \else
+ \directlua{luatexja.jfont.is_ktenc('\luatexluaescapestring{#2}')}\ifin@%
+ \ltjselectfont@force@definetrue
+ \usekanji{#2}{#3}{#4}{#5}%
+ \global\let#1\gettfont
+ \ltjselectfont@force@definefalse
+ \else
+ \useroman{#2}{#3}{#4}{#5}%
+ \global\expandafter\let\expandafter#1\the\font
+ \fi
+ \fi
+ \endgroup
+ }
+\def\DLMfontsw@standard#1#2#3{#1{#2{#3}}}
+\def\reDeclareMathAlphabet#1#2#3{%
+ \ifdefined#2
+ \@temptokena\expandafter{#2}%
+ \else
+ \@temptokena{#2}%
+ \fi
+ \ifdefined#3
+ \toks0\expandafter{#3}%
+ \else
+ \toks0{#3}%
+ \fi
+ \long\protected\edef#1{%
+ \noexpand\DLMfontsw@standard{\the\@temptokena}{\the\toks0}}%
+}
+\@onlypreamble\reDeclareMathAlphabet
+\def\all@shape{all}%
+\def\DeclareRelationFont#1#2#3#4#5#6#7#8{%
+ \def\rel@shape{#4}%
+ \ifx\rel@shape\@empty
+ \global
+ \expandafter\def\csname rel@#1/#2/#3/all\endcsname{%
+ \romanencoding{#5}\romanfamily{#6}%
+ \romanseries{#7}}%
+ \else
+ \global
+ \expandafter\def\csname rel@#1/#2/#3/#4\endcsname{%
+ \romanencoding{#5}\romanfamily{#6}%
+ \romanseries{#7}\romanshape{#8}}%
+ \fi
+}
+\def\SetRelationFont#1#2#3#4#5#6#7#8{%
+ \def\rel@shape{#4}%
+ \ifx\rel@shape\@empty
+ \expandafter\def\csname rel@#1/#2/#3/all\endcsname{%
+ \romanencoding{#5}\romanfamily{#6}%
+ \romanseries{#7}}%
+ \else
+ \expandafter\def\csname rel@#1/#2/#3/#4\endcsname{%
+ \romanencoding{#5}\romanfamily{#6}%
+ \romanseries{#7}\romanshape{#8}}%
+ \fi
+}
+\newif\if@knjcmd
+\def\userelfont{\@knjcmdtrue}
+
+
+\RequirePackage{everysel}
+\let\ltj@@EverySelectfont@Init=\@EverySelectfont@Init
+\expandafter\expandafter\expandafter\let
+\expandafter\expandafter\csname ltj@@orig@selectfont\endcsname\csname selectfont\space\endcsname
+\@EverySelectfont@Init
+%\let\ltj@@font@info\@font@info
+%\let\ltj@@font@warning\@font@warning
+\def\@EverySelectfont@Init{%
+ \expandafter\let\csname selectfont\space \endcsname \ltj@@orig@selectfont
+ \ltj@@EverySelectfont@Init
+}
+\def\ltj@selectfont@tate{%
+ \let\k@encoding\ct@encoding
+ \xdef\font@name{\csname\curr@kfontshape/\f@size\endcsname}%
+ \pickup@tfont
+ \ifnum\ltjgetparameter{direction}=3 \font@name
+ \ltj@@does@alt@set{\curr@kfontshape}{%
+ % alt fonts ã®å®šç¾©
+ \directlua{luatexja.jfont.output_alt_font_cmd('t', '\luatexluaescapestring{\curr@kfontshape}')}%
+ % 定義ã—㟠alt fonts ã®ãƒ‡ãƒ¼ã‚¿ã‚’ \ltjdeclarealtfont ã«æ¸¡ã™ã®ã¨åŒç­‰ã®å‡¦ç†ã‚’ã™ã‚‹
+ \directlua{luatexja.jfont.pickup_alt_font_a('\f@size')}%
+ }%
+ \fi}
+\def\ltj@selectfont@yoko{%
+ \let\k@encoding\cy@encoding
+ \xdef\font@name{\csname\curr@kfontshape/\f@size\endcsname}%
+ \pickup@jfont
+ \unless\ifnum\ltjgetparameter{direction}=3 \font@name
+ \ltj@@does@alt@set{\curr@kfontshape}{%
+ % alt fonts ã®å®šç¾©
+ \directlua{luatexja.jfont.output_alt_font_cmd('y', '\luatexluaescapestring{\curr@kfontshape}')}%
+ % 定義ã—㟠alt fonts ã®ãƒ‡ãƒ¼ã‚¿ã‚’ \ltjdeclarealtfont ã«æ¸¡ã™ã®ã¨åŒç­‰ã®å‡¦ç†ã‚’ã™ã‚‹
+ \directlua{luatexja.jfont.pickup_alt_font_a('\f@size')}%
+ }%
+ \fi}
+\def\ltj@selectfont@patch{%
+ \directlua{luatexja.base.start_time_measure('selectfont')}%
+ \let\tmp@error@fontshape\error@fontshape
+ \let\error@fontshape\error@kfontshape
+ \directlua{luatexja.jfont.is_kyenc('\luatexluaescapestring{\k@encoding}')}\ifin@%
+ \let\cy@encoding\k@encoding
+ \edef\ct@encoding{\csname t@enc@\k@encoding\endcsname}%
+ \else
+ \directlua{luatexja.jfont.is_ktenc('\luatexluaescapestring{\k@encoding}')}\ifin@%
+ \let\ct@encoding\k@encoding
+ \edef\cy@encoding{\csname y@enc@\k@encoding\endcsname}%
+ \else
+ \@latex@error{KANJI Encoding scheme `\k@encoding' unknown}\@eha
+ \fi
+ \fi
+ \global\let\ltj@afont@name=\font@name
+ \ltj@selectfont@tate\ltj@selectfont@yoko
+%
+ \edef\tmp@item{{\k@encoding}}\expandafter\def\expandafter\k@encoding\tmp@item
+ \kenc@update
+ \global\let\font@name=\ltj@afont@name
+ \let\error@fontshape\tmp@error@fontshape
+ \if@knjcmd \@knjcmdfalse
+ \expandafter\ifx
+ \csname rel@\k@encoding/\k@family/\k@series/\k@shape\endcsname\relax
+ \expandafter\ifx
+ \csname rel@\k@encoding/\k@family/\k@series/all\endcsname\relax
+ \else
+ \csname rel@\k@encoding/\k@family/\k@series/all\endcsname\selectfont
+ % 警告: å†ã³ \selectfont を呼んã§ã„る.無é™ãƒ«ãƒ¼ãƒ—ã®å¯èƒ½æ€§ã‚ã‚Š
+ \fi
+ \else
+ \csname rel@\k@encoding/\k@family/\k@series/\k@shape\endcsname\selectfont
+ % 警告: å†ã³ \selectfont を呼んã§ã„る.無é™ãƒ«ãƒ¼ãƒ—ã®å¯èƒ½æ€§ã‚ã‚Š
+ \fi
+ \fi
+ \global\let\font@name=\ltj@afont@name
+ \directlua{luatexja.base.stop_time_measure('selectfont')}%
+}
+\EverySelectfont{\ltj@selectfont@patch}
+
+\bgroup
+ \def\ltj@@dir@patch#1#2#3{%
+ \global\csletcs{ltj@@orig@#1}{#1}%
+ \protected\expandafter\xdef\csname #1\endcsname{%
+ \csname ltj@@orig@#1\endcsname
+ \unexpanded{\ifnum#3<\z@\let\ltj@@protect\protect\set@typeset@protect}%
+ \unexpanded{\global\let\ltj@afont@name=\font@name}%
+ \expandonce{\csname ltj@selectfont@#2\endcsname}%
+ \unexpanded{\global\let\font@name=\ltj@afont@name}%
+ \unexpanded{\let\protect\ltj@@protect\fi}%
+ }%
+ }
+ \ltj@@dir@patch{yoko}{yoko}{\ltj@curjfnt}
+ \ltj@@dir@patch{tate}{tate}{\ltj@curtfnt}
+ \ltj@@dir@patch{utod}{yoko}{\ltj@curjfnt}
+ \ltj@@dir@patch{dtou}{yoko}{\ltj@curjfnt}
+\egroup
+
+\def\KanjiEncodingPair#1#2{\@namedef{t@enc@#1}{#2}\@namedef{y@enc@#2}{#1}}
+\def\set@fontsize#1#2#3{%
+ \@defaultunits\@tempdimb#2pt\relax\@nnil
+ \edef\f@size{\strip@pt\@tempdimb}%
+ \@defaultunits\@tempskipa#3pt\relax\@nnil
+ \edef\f@baselineskip{\the\@tempskipa}%
+ \edef\f@linespread{#1}%
+ \let\baselinestretch\f@linespread
+ \def\size@update{%
+ \baselineskip\f@baselineskip\relax
+ \baselineskip\f@linespread\baselineskip
+ \normalbaselineskip\baselineskip
+ \adjustbaseline
+ \setbox\ystrutbox\hbox{\ltj@@orig@yoko
+ \vrule\@width\z@
+ \@height.7\baselineskip \@depth.3\baselineskip}%
+ \setbox\dstrutbox\hbox{\ltj@@orig@dtou
+ \vrule\@width\z@
+ \@height.7\baselineskip \@depth.3\baselineskip}%
+ \setbox\tstrutbox\hbox{\ltj@@orig@tate
+ \vrule\@width\z@
+ \@height.5\baselineskip \@depth.5\baselineskip}%
+ \setbox\zstrutbox\hbox{\ltj@@orig@utod
+ \vrule\@width\z@
+ \@height.7\baselineskip \@depth.3\baselineskip}%
+ \let\size@update\relax}}
+
+\newluafunction\ltj@@adjust@baseline@inner
+\begingroup\catcode`\~=12
+\directlua{%
+ local nulltable = {}
+ local t = lua.get_functions_table()
+ local getfont, dir_tate = font.getfont, luatexja.dir_table.dir_tate
+ local fmt, get_attr = luatexja.jfont.font_metric_table, tex.getattribute
+ local getcount=tex.getcount
+ local setdimen, set_attr = tex.setdimen, tex.setattribute
+ local dir = luatexja.unary_pars.direction
+ t[\the\ltj@@adjust@baseline@inner] = function()
+ local ft = fmt[get_attr('ltj@curtfnt')] or nulltable
+ ft = ft.char_type or nulltable
+ local fk = ft[0] or nulltable
+ local ht, dp, wd = fk.height or 0, fk.depth or 0,
+ fk.width or ft.zw or 0
+ local fm
+ = ((getfont(font.current()) or nulltable)
+ .characters or nulltable)[77] or nulltable %% 'M'
+ set_attr('ltj@tablshift',
+ tex.round(0.5*((fm.height or 0)- (fm.depth or 0) - ht+ dp)))
+ if dir() ~= dir_tate then
+ ft = fmt[get_attr('ltj@curjfnt')] or nulltable
+ ft = ft.char_type or nulltable
+ fk = ft[0] or nulltable
+ ht, dp, wd = fk.height or 0, fk.depth or 0,
+ fk.width or ft.zw or 0
+ end
+ setdimen('cht', ht); setdimen('cdp', dp)
+ setdimen('cwd', wd); setdimen('chs', wd)
+ setdimen('cHT', ht+dp)
+ end
+}\endgroup
+\def\adjustbaseline{\luafunction\ltj@@adjust@baseline@inner
+ \cvs\normalbaselineskip}
+\DeclareRobustCommand\romanencoding[1]{%
+ \expandafter\ifx\csname T@#1\endcsname\relax
+ \@latex@error{Encoding scheme `#1' unknown}\@eha
+ \else
+ \edef\f@encoding{#1}%
+ \ifx\cf@encoding\f@encoding
+ \let\enc@update\relax
+ \else
+ \let\enc@update\@@enc@update
+ \fi
+ \fi
+}
+\DeclareRobustCommand\kanjiencoding[1]{%
+ \expandafter\ifx\csname T@#1\endcsname\relax
+ \@latex@error{KANJI Encoding scheme `#1' unknown}\@eha
+ \else
+ \edef\k@encoding{#1}%
+ \ifx\ck@encoding\k@encoding
+ \let\kenc@update\relax
+ \else
+ \let\kenc@update\@@kenc@update
+ \fi
+ \fi
+}
+\DeclareRobustCommand\fontencoding[1]{%
+ \directlua{luatexja.jfont.is_kyenc('\luatexluaescapestring{#1}')}\ifin@%
+ \kanjiencoding{#1}\else\romanencoding{#1}\fi}
+\def\@@kenc@update{%
+ \default@KT
+ \csname T@\k@encoding\endcsname
+ \csname D@\k@encoding\endcsname
+ \let\kenc@update\relax
+ \let\ck@encoding\k@encoding
+ \edef\tmp@enc{'\luatexluaescapestring{\k@encoding}'}%
+ \directlua{luatexja.jfont.is_kyenc(\tmp@enc)}\ifin@%
+ \let\cy@encoding\k@encoding
+ \else
+ \directlua{luatexja.jfont.is_ktenc(\tmp@enc)}\ifin@%
+ \let\ct@encoding\k@encoding
+ \else
+ \@latex@error{KANJI Encoding scheme `\k@encoding' unknown}\@eha
+ \fi
+ \fi
+}
+\let\kenc@update\relax
+\def\@changed@kcmd#1#2{%
+ \ifx\protect\@typeset@protect
+ \@inmathwarn#1%
+ \expandafter\ifx\csname\ck@encoding\string#1\endcsname\relax
+ \expandafter\ifx\csname ?\string#1\endcsname\relax
+ \expandafter\def\csname ?\string#1\endcsname{%
+ \TextSymbolUnavailable#1%
+ }%
+ \fi
+ \global\expandafter\let
+ \csname\cf@encoding \string#1\expandafter\endcsname
+ \csname ?\string#1\endcsname
+ \fi
+ \csname\ck@encoding\string#1%
+ \expandafter\endcsname
+ \else
+ \noexpand#1%
+ \fi}
+\newif\if@notkfam
+\newif\if@notffam
+\newif\if@tempswz
+\def\@ltj@use@fd{true}
+\DeclareRobustCommand\romanfamily[1]{\edef\f@family{#1}}
+\DeclareRobustCommand\kanjifamily[1]{\edef\k@family{#1}}
+\DeclareRobustCommand\fontfamily[1]{%
+ \@notkfamfalse\@notffamfalse
+ \edef\tmp@item{'\luatexluaescapestring{#1}'}%
+ %
+ \directlua{luatexja.jfont.search_kfam(\tmp@item, \@ltj@use@fd)}%
+ \ifin@\edef\k@family{#1}\else\@notkfamtrue\fi
+ %
+ % alphabetic fonts part
+ \directlua{luatexja.jfont.is_ffam(\tmp@item)}%
+ \ifin@\edef\f@family{#1}\else
+ % checking is_stored_ffam is not sufficient,
+ % since LuaTeX-ja doesn't know whats fonts are defined before LuaTeX-ja is loaded.
+ \ifcsname \f@encoding+#1\endcsname % easy case
+ \directlua{luatexja.jfont.add_ffam(\tmp@item)}\edef\f@family{#1}%
+ \else
+ \@tempswafalse
+ \def\cdp@elt##1{\ifcsname ##1+#1\endcsname\@tempswatrue\fi}%
+ \directlua{luatexja.jfont.search_ffam_declared()}%
+ \if@tempswz
+ \directlua{luatexja.jfont.add_ffam(\tmp@item)}\edef\f@family{#1}%
+ \else
+ % now we search Nffam_list and font definition files.
+ \directlua{luatexja.jfont.search_ffam_fd(\tmp@item)}%
+ \ifin@\edef\f@family{#1}\else\@notffamtrue\fi
+ \fi
+ \fi
+ \fi
+ %
+ \if@notkfam\if@notffam
+ \edef\k@family{#1}\edef\f@family{#1}%
+ \fi\fi
+}
+\DeclareRobustCommand\romanseries[1]{\edef\f@series{#1}}
+\DeclareRobustCommand\kanjiseries[1]{\edef\k@series{#1}}
+\DeclareRobustCommand\fontseries[1]{\kanjiseries{#1}\romanseries{#1}}
+\DeclareRobustCommand\romanshape[1]{\edef\f@shape{#1}}
+\DeclareRobustCommand\kanjishape[1]{\edef\k@shape{#1}}
+\DeclareRobustCommand\fontshape[1]{\kanjishape{#1}\romanshape{#1}}
+\def\usekanji#1#2#3#4{%
+ \kanjiencoding{#1}\kanjifamily{#2}\kanjiseries{#3}\kanjishape{#4}%
+ \selectfont\ignorespaces}
+\def\useroman#1#2#3#4{%
+ \romanencoding{#1}\romanfamily{#2}\romanseries{#3}\romanshape{#4}%
+ \selectfont\ignorespaces}
+\protected\def\usefont#1#2#3#4{%
+ \directlua{luatexja.jfont.is_kenc('\luatexluaescapestring{#1}')}\ifin@%
+ \usekanji{#1}{#2}{#3}{#4}%
+ \else\useroman{#1}{#2}{#3}{#4}%
+ \fi}
+\DeclareRobustCommand\normalfont{%
+ \kanjiencoding{\kanjiencodingdefault}%
+ \kanjifamily{\kanjifamilydefault}%
+ \kanjiseries{\kanjiseriesdefault}%
+ \kanjishape{\kanjishapedefault}%
+ \romanencoding{\encodingdefault}%
+ \romanfamily{\familydefault}%
+ \romanseries{\seriesdefault}%
+ \romanshape{\shapedefault}%
+ \selectfont\ignorespaces}
+\let\reset@font\normalfont
+\DeclareRobustCommand\mcfamily{%
+ \unless\ifltj@disablejfam\not@math@alphabet\mcfamily\mathmc\fi
+ \kanjifamily\mcdefault\selectfont}
+\DeclareRobustCommand\gtfamily{%
+ \unless\ifltj@disablejfam\not@math@alphabet\gtfamily\mathgt\fi
+ \kanjifamily\gtdefault\selectfont}
+\let\romanprocess@table\process@table
+\def\kanjiprocess@table{%
+ \kanjiencoding{\kanjiencodingdefault}%
+ \kanjifamily{\kanjifamilydefault}%
+ \kanjiseries{\kanjiseriesdefault}%
+ \kanjishape{\kanjishapedefault}%
+}
+\def\process@table{%
+ \romanprocess@table
+ \kanjiprocess@table
+}
+\@onlypreamble\romanprocess@table
+\@onlypreamble\kanjiprocess@table
+
+%%%%%% LuaTeX-ja specific
+
+% #1 ã®å±•é–‹çµæžœã‹ã‚‰ encoding 部分をã¨ã‚Šã ã—,ãã‚ŒãŒå’Œæ–‡ç”¨ã‹ã©ã†ã‹ã®çµæžœã‚’ \ifin@ ã«ä»£å…¥
+\def\ltj@@IsFontJapanese#1{%
+ \directlua{luatexja.jfont.is_kenc(string.match(
+ '\luatexluaescapestring{#1}', '[^/]+'))}}
+
+
+\let\extract@afont\extract@font
+\def\pickup@jfont{%
+ \ifnum
+ \unless\ifnum\ltjgetparameter{direction}=3 1\else
+ \ifltjselectfont@force@define 1\else 0\fi\fi =1 %
+ \expandafter \ifx \font@name \relax
+ \let\extract@font\extract@jfont
+ \define@newfont
+ \let\extract@font\extract@afont
+ \fi
+ \let\getjfont\font@name
+ \else
+ \begingroup\escapechar\m@ne
+ \ifcsname ltj@@fontjfm/\expandafter\string\font@name\endcsname\else
+ \let\extract@font\extract@jfont@onlyjfm
+ \define@newfont
+ \let\extract@font\extract@afont
+ \fi
+ \endgroup
+ \csname ltj@@fontjfm/\expandafter\expandafter\expandafter\@gobble\expandafter\string\font@name\endcsname
+ \fi
+}
+\def\pickup@tfont{%
+ \ifnum
+ \ifnum\ltjgetparameter{direction}=3 1\else
+ \ifltjselectfont@force@define 1\else 0\fi\fi =1 %
+ \expandafter \ifx \font@name \relax
+ \let\extract@font\extract@tfont
+ \define@newfont
+ \let\extract@font\extract@afont
+ \fi
+ \let\gettfont\font@name
+ \else
+ \begingroup\escapechar\m@ne
+ \ifcsname ltj@@fontjfm/\expandafter\string\font@name\endcsname\else
+ \let\extract@font\extract@tfont@onlyjfm
+ \define@newfont
+ \let\extract@font\extract@afont
+ \fi
+ \endgroup
+ \csname ltj@@fontjfm/\expandafter\expandafter\expandafter\@gobble\expandafter\string\font@name\endcsname
+ \fi
+}
+
+% ç•°ãªã‚‹å’Œæ–‡ enc/fam/ser/shape ã‹ã‚‰ã¯ç•°ãªã‚‹ãƒ•ã‚©ãƒ³ãƒˆç•ªå·ãŒæŒ¯ã‚‰ã‚Œã‚‹ã‚ˆã†ã«
+% ã‚ã–ã¨ã€Œã‚´ãƒŸã‚’ã¤ã‘ã‚‹ã€
+\def\ltj@@patch@external@font#1 at{%
+ \directlua{
+ local s = '\luatexluaescapestring{#1}'
+ local is_braced, is_quoted
+ if s:sub(1,1)=='{' and s:sub(-1)=='}' then is_braced=true; s=s:sub(2,-2) end
+ if s:sub(1,1)=='"' and s:sub(-1)=='"' then is_quoted=true; s=s:sub(2,-2) end
+ s=s..luatexja.jfont.print_aftl_address()
+ if is_braced then s='{'..s..'}' elseif is_quoted then s='"'..s..'"' end
+ %print(s, is_quoted, is_braced)
+ tex.sprint(-2, s)}%
+ \space at%
+}
+\def\extract@jfont{%
+ \get@external@font
+ \ltj@@does@alt@set{\f@encoding/\f@family/\f@series/\f@shape}{%
+ \edef\external@font{\expandafter\ltj@@patch@external@font\external@font}%
+ }%
+ \expandafter\globaljfont\font@name\external@font\relax\font@name% ã“ã“ã§æ™‚é–“ãŒã‹ã‹ã‚‹
+ \csname \f@encoding+\f@family\endcsname
+ \csname\curr@fontshape\endcsname}
+\def\extract@tfont{%
+ \get@external@font
+ \ltj@@does@alt@set{\f@encoding/\f@family/\f@series/\f@shape}{%
+ \edef\external@font{\expandafter\ltj@@patch@external@font\external@font}%
+ }%
+ \expandafter\globaltfont\font@name\external@font\relax\font@name
+ \csname \f@encoding+\f@family\endcsname
+ \csname\curr@fontshape\endcsname}
+\def\extract@jfont@onlyjfm{%
+ \get@external@font
+ \csxdef{ltj@@fontjfm/\expandafter\string\font@name}{%
+ \directlua{%
+ luatexja.jfont.load_jfmonly('\luatexluaescapestring{\external@font}', 'yoko')
+ }%
+ }}
+\def\extract@tfont@onlyjfm{%
+ \get@external@font
+ \csxdef{ltj@@fontjfm/\expandafter\string\font@name}{%
+ \directlua{%
+ luatexja.jfont.load_jfmonly('\luatexluaescapestring{\external@font}', 'tate')
+ }%
+ }}
+
+\let\ltj@@al@do@subst@correction=\do@subst@correction
+\def\ltj@@ja@do@subst@correction{%
+ \xdef\subst@correction{%
+ \font@name
+ \global\expandafter\let\csname \curr@fontshape/\f@size\endcsname\font@name%
+ \relax}%
+ \aftergroup\subst@correction
+}
+\def\do@subst@correction{%
+ \ltj@@IsFontJapanese{\curr@fontshape}\ifin@%
+ \ltj@@ja@do@subst@correction
+ \else
+ \ltj@@al@do@subst@correction
+ \fi
+}
+\let\@@italiccorr=\/
+
+%%%%%% Japanese font for math mode
+\unless\ifltj@disablejfam
+
+% \M@<enc> ã‹ã‚‰ ãã® <enc> ãŒå’Œæ–‡ç”¨ã‹èª¿ã¹ã‚‹
+{\catcode`M=12%
+\gdef\ltj@@mathJapaneseFonts#1M#2#3\relax{\ltj@@IsFontJapanese{#3}}}
+
+\let\ltj@@al@getanddefine@fonts=\getanddefine@fonts
+\def\ltj@@ja@getanddefine@fonts#1#2{%
+ \csletcs{if@ltj@tempif}{ifltjselectfont@force@define}%
+ \ltjselectfont@force@definetrue
+ \xdef\font@name{\csname \string#2/\tf@size\endcsname}%
+ \pickup@jfont\let\textfont@name\font@name
+ \xdef\font@name{\csname \string#2/\sf@size\endcsname}%
+ \pickup@jfont\let\scriptfont@name\font@name
+ \xdef\font@name{\csname \string#2/\ssf@size\endcsname}%
+ \pickup@jfont
+ \csletcs{ifltjselectfont@force@define}{if@ltj@tempif}%
+ \edef\math@fonts{\math@fonts\ltj@setpar@global%
+ \ltj@@set@stackfont#1,\textfont@name:{MJT}%
+ \ltj@@set@stackfont#1,\scriptfont@name:{MJS}%
+ \ltj@@set@stackfont#1,\font@name:{MJSS}%
+ }%
+}
+
+\def\getanddefine@fonts#1#2{%
+ \ltj@tempcnta=#1\ltj@@IsFontJapanese{\string#2}%
+ \ifin@\let\ltj@temp=\ltj@@ja@getanddefine@fonts%
+ \else \let\ltj@temp=\ltj@@al@getanddefine@fonts\fi
+ \ltj@temp{#1}{#2}%
+}
+\def\use@mathgroup#1#2{\relax\ifmmode
+ \math@bgroup
+ \expandafter\ifx\csname M@\f@encoding\endcsname#1\else
+ #1\fi\ltj@tempcnta=#2 \expandafter\ltj@@mathJapaneseFonts\string#1\relax%
+ \ifin@\jfam#2\relax\else\mathgroup#2\relax\fi
+ \expandafter\math@egroup\fi}%
+
+\fi
+
+%%%%%% Alternate Japanese Fonts
+%%%% \DeclareAlternateKanjiFont<Benc><Bfam><Bser><Bshape><Aenc><Afam><Aser><Ashape><range>
+% ã„ã¤ã‚‚ global
+\def\DeclareAlternateKanjiFont#1#2#3#4#5#6#7#8#9{%
+ \edef\@temp{#9}%
+ \ifx\@temp\@empty\else
+ {\def\ltj@temp@bfont{#1/#2/#3/#4}\def\ltj@temp@afont{#5/#6/#7/#8}%
+ \expandafter\ltj@@altfont@latex#9,,}\ignorespaces
+ \fi}
+\def\ltj@@altfont@latex#1,{\def\ltj@temp{#1}%
+ \ifx\ltj@temp\empty\let\@next=\relax\else
+ \ltj@@altfont@latexA{#1}\let\@next=\ltj@@altfont@latex\fi\@next}
+\def\ltj@@altfont@latexA#1{\ltj@@altfont@latexB#1--\@nil}
+\def\ltj@@altfont@latexB#1-#2-#3\@nil{\def\ltj@temp{#3}%
+ \ifx\ltj@temp\empty
+ \ltj@tempcnta=#1\relax\ltj@tempcntb=\ltj@tempcnta
+ \else
+ \def\ltj@temp{#1}%
+ \ifx\ltj@temp\empty\ltj@tempcnta='200\else\ltj@tempcnta=#1\fi\relax
+ \def\ltj@temp{#2}%
+ \ifx\ltj@temp\empty\ltj@tempcntb="10FFFF\else\ltj@tempcntb=#2\fi\relax%"
+ \fi
+ \directlua{luatexja.jfont.set_alt_font_latex(
+ \the\ltj@tempcnta,\the\ltj@tempcntb,
+ '\luatexluaescapestring{\ltj@temp@afont}',
+ '\luatexluaescapestring{\ltj@temp@bfont}')}%
+ }
+
+%%%% \ClearAlternateKanjiFont<Benc><Bfam><Bser><Bshape>
+% ã„ã¤ã‚‚ global
+\def\ClearAlternateKanjiFont#1#2#3#4{%
+ \directlua{luatexja.jfont.clear_alt_font_latex('\luatexluaescapestring{#1/#2/#3/#4}')}}
+
+\def\ltj@pickup@altfont@auxy#1{%
+ \begingroup\edef\font@name{\csname #1/\f@size\endcsname}\pickup@jfont\endgroup%
+}
+\def\ltj@pickup@altfont@auxt#1{%
+ \begingroup\edef\font@name{\csname #1/\f@size\endcsname}\pickup@tfont\endgroup%
+}
+\def\ltj@pickup@altfont@copy#1#2{%
+ \ltj@@getjfontnumber#1%
+ \directlua{luatexja.jfont.pickup_alt_font_b(\the\ltj@tempcntc,'\luatexluaescapestring{#2}')}%
+}
+
+\def\ltj@@does@alt@set#1#2{%
+ \directlua{luatexja.jfont.does_alt_set'\luatexluaescapestring{#1}'}{#2}}
+
+%%%% patch \@text@composite because of {y,t}albaselineshift
+
+% %% \pltx@isletter from plfonts.dtx
+% \def\pltx@mark{\pltx@mark@}
+% \let\pltx@scanstop\relax
+% \long\def\pltx@cond#1\fi{%
+% #1\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
+% \long\def\pltx@isletter#1{%
+% \expandafter\pltx@isletter@i#1\pltx@scanstop}
+% \long\def\pltx@isletter@i#1\pltx@scanstop{%
+% \pltx@cond\ifx\pltx@mark#1\pltx@mark\fi{\@firstoftwo}%
+% {\pltx@isletter@ii\pltx@scanstop#1\pltx@scanstop{}#1\pltx@mark}}
+% \long\def\pltx@isletter@ii#1\pltx@scanstop#{%
+% \pltx@cond\ifx\pltx@mark#1\pltx@mark\fi%
+% {\pltx@isletter@iii}{\pltx@isletter@iv}}
+% \long\def\pltx@isletter@iii#1\pltx@mark{\@secondoftwo}
+% \long\def\pltx@isletter@iv#1#2#3\pltx@mark{%
+% \pltx@cond\ifx\pltx@mark#3\pltx@mark\fi{%
+% \pltx@cond{\ifnum0\ifcat A\noexpand#21\fi\ifcat=\noexpand#21\fi>\z@}\fi
+% {\@firstoftwo}{\@secondoftwo}%
+% }{\@secondoftwo}}
+%
+% \def\@text@composite@x#1#2{%
+% \ifx#1\relax
+% #2%
+% \else\pltx@isletter{#1}{#1}{%
+% \begingroup
+% \setbox\z@\hbox\bgroup%
+% \ltj@yablshift\z@ \ltj@tablshift\z@
+% #1%
+% \@tempcntb\directlua{luatexja.pltx_composite_last_node_char()}%)
+% \xdef\pltx@composite@temp{\noexpand\@tempcntb=\the\@tempcntb\relax}%
+% \aftergroup\pltx@composite@temp
+% \egroup
+% \ifnum\ltjgetparameter{direction}=3 %
+% \@tempdima=\ltj@tablshift sp\else\@tempdima=\ltj@yablshift sp\fi
+% \ifnum\@tempcntb<\z@\@tempcnta\z@\else
+% \@tempcnta=\ltjgetparameter{jacharrange}{\ltjgetparameter{chartorange}{\@tempcntb}}\relax
+% \ifnum\@tempcnta=\z@\@tempdima\z@\fi
+% \fi
+% \ifnum\@tempcnta>\z@
+% \ifodd\ltjgetparameter{alxspmode}{\@tempcntb}\else\leavevmode\hbox{}\fi
+% \begingroup\mathsurround\z@$%
+% \hbox{\lower\@tempdima\box\z@}
+% $\endgroup%
+% \ifnum\ltjgetparameter{alxspmode}{\@tempcntb}<2\hbox{}\fi
+% \else
+% \ifdim\@tempdima=\z@{\ltj@yablshift\z@ \ltj@tablshift\z@#1}%
+% \else\lower\@tempdima\box\z@\fi
+% \fi
+% \endgroup}%
+% \fi
+% }
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-array.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-array.sty
new file mode 100644
index 0000000000..989fd8ce9d
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-array.sty
@@ -0,0 +1,26 @@
+%
+% lltjp-array.sty
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lltjp-array}[2018/03/29 Patch to array for LuaTeX-ja]
+
+\RequirePackage{etoolbox,array}
+
+\patchcmd\insert@column{%
+ \ignorespaces\@sharp\unskip
+}{%
+ \ltj@sharp
+}{}{}
+
+\@ifpackageloaded{lltjext}{}{%
+%% remove extra \xkanjiskip (pLaTeX2e 2016/04/17)
+\def\@tabular{%
+ \leavevmode \null
+ \hbox \bgroup $\col@sep\tabcolsep \let\d@llarbegin\begingroup
+ \let\d@llarend\endgroup
+ \@tabarray}
+\def\endtabular{\endarray $\egroup\null}
+\expandafter \let \csname endtabular*\endcsname = \endtabular
+}
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-fontspec.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-fontspec.sty
new file mode 100644
index 0000000000..6f469fc08f
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-fontspec.sty
@@ -0,0 +1,155 @@
+%
+% lltjp-fontspec.sty 2018-08-24
+%
+
+\NeedsTeXFormat{LaTeX2e}
+
+\RequirePackage{fontspec}
+\ExplSyntaxOn
+
+% <= v2.6g uses \l__fontspec_nfss_enc_tl instead of \g__fontspec_nfss_enc_tl
+\ifdefined \g__fontspec_nfss_enc_tl \else
+ \def \g__fontspec_nfss_enc_tl { \l__fontspec_nfss_enc_tl }
+\fi
+
+%%%%%%%% fontspec v2.5c overwrites \rmfamily etc. in \setmainfont
+\@ifpackagelater{fontspec}{2018/07/29}{ %% 2.6h or later
+\cs_set:Nn \__fontspec_main_setmainfont:nn
+ {
+ \fontspec_set_family:Nnn \l__fontspec_rmfamily_family_tl {#1} {#2}
+ \tl_set_eq:NN \rmdefault \l__fontspec_rmfamily_family_tl
+ \use:x
+ {
+ \exp_not:n { \DeclareRobustCommand \rmfamily }
+ {
+ \exp_not:N \fontencoding { \g__fontspec_nfss_enc_tl }
+ \exp_not:N \fontfamily { \l__fontspec_rmfamily_family_tl }
+ \exp_not:N\if@ltj@match@family\exp_not:N\kanjifamily\exp_not:N\mcdefault\exp_not:N\fi%%%
+ \exp_not:N \selectfont
+ }
+ }
+ \str_if_eq_x:nnT {\familydefault} {\rmdefault}
+ { \tl_set_eq:NN \encodingdefault \g__fontspec_nfss_enc_tl }
+ \__fontspec_setmainfont_hook:nn {#1} {#2}
+ \normalfont
+ }
+\cs_set:Nn \__fontspec_main_setsansfont:nn
+ {
+ \fontspec_set_family:Nnn \l__fontspec_sffamily_family_tl {#1} {#2}
+ \tl_set_eq:NN \sfdefault \l__fontspec_sffamily_family_tl
+ \use:x
+ {
+ \exp_not:n { \DeclareRobustCommand \sffamily }
+ {
+ \exp_not:N \fontencoding { \g__fontspec_nfss_enc_tl }
+ \exp_not:N \fontfamily { \l__fontspec_sffamily_family_tl }
+ \exp_not:N\if@ltj@match@family\exp_not:N\kanjifamily\exp_not:N\gtdefault\exp_not:N\fi%%%
+ \exp_not:N \selectfont
+ }
+ }
+ \str_if_eq_x:nnT {\familydefault} {\sfdefault}
+ { \tl_set_eq:NN \encodingdefault \g__fontspec_nfss_enc_tl }
+ \__fontspec_setsansfont_hook:nn {#1} {#2}
+ \normalfont
+ }
+\cs_set:Nn \__fontspec_main_setmonofont:nn
+ {
+ \fontspec_set_family:Nnn \l__fontspec_ttfamily_family_tl {#1} {#2}
+ \tl_set_eq:NN \ttdefault \l__fontspec_ttfamily_family_tl
+ \use:x
+ {
+ \exp_not:n { \DeclareRobustCommand \ttfamily }
+ {
+ \exp_not:N \fontencoding { \g__fontspec_nfss_enc_tl }
+ \exp_not:N \fontfamily { \l__fontspec_ttfamily_family_tl }
+ \exp_not:N\if@ltj@match@family\exp_not:N\kanjifamily\exp_not:N\jttdefault\exp_not:N\fi%%%
+ \exp_not:N \selectfont
+ }
+ }
+ \str_if_eq_x:nnT {\familydefault} {\ttdefault}
+ { \tl_set_eq:NN \encodingdefault \g__fontspec_nfss_enc_tl }
+ \__fontspec_setmonofont_hook:nn {#1} {#2}
+ \normalfont
+ }
+}{ %% <= 2.6g
+\DeclareDocumentCommand \setmainfont { O{} m O{} }
+ {
+ \fontspec_set_family:Nnn \g__fontspec_rmfamily_family {#1,#3} {#2}
+ \tl_set_eq:NN \rmdefault \g__fontspec_rmfamily_family
+ \use:x { \exp_not:n { \DeclareRobustCommand \rmfamily }
+ {
+ \exp_not:N \fontencoding { \g__fontspec_nfss_enc_tl }
+ \exp_not:N \fontfamily { \g__fontspec_rmfamily_family }
+ \exp_not:N\if@ltj@match@family\exp_not:N\kanjifamily\exp_not:N\mcdefault\exp_not:N\fi%%%
+ \exp_not:N \selectfont
+ }
+ }
+ \str_if_eq_x:nnT {\familydefault} {\rmdefault}
+ { \tl_set_eq:NN \encodingdefault \g__fontspec_nfss_enc_tl }
+ \normalfont
+ \ignorespaces
+ }
+\DeclareDocumentCommand \setsansfont { O{} m O{} }
+ {
+ \fontspec_set_family:Nnn \g__fontspec_sffamily_family {#1,#3} {#2}
+ \tl_set_eq:NN \sfdefault \g__fontspec_sffamily_family
+ \use:x { \exp_not:n { \DeclareRobustCommand \sffamily }
+ {
+ \exp_not:N \fontencoding { \g__fontspec_nfss_enc_tl }
+ \exp_not:N \fontfamily { \g__fontspec_sffamily_family }
+ \exp_not:N\if@ltj@match@family\exp_not:N\kanjifamily\exp_not:N\gtdefault\exp_not:N\fi%%%
+ \exp_not:N \selectfont
+ }
+ }
+ \str_if_eq_x:nnT {\familydefault} {\sfdefault}
+ { \tl_set_eq:NN \encodingdefault \g__fontspec_nfss_enc_tl }
+ \normalfont
+ \ignorespaces
+ }
+\DeclareDocumentCommand \setmonofont { O{} m O{} }
+ {
+ \fontspec_set_family:Nnn \g__fontspec_ttfamily_family {#1,#3} {#2}
+ \tl_set_eq:NN \ttdefault \g__fontspec_ttfamily_family
+ \use:x { \exp_not:n { \DeclareRobustCommand \ttfamily }
+ {
+ \exp_not:N \fontencoding { \g__fontspec_nfss_enc_tl }
+ \exp_not:N \fontfamily { \g__fontspec_ttfamily_family }
+ \exp_not:N\if@ltj@match@family\exp_not:N\kanjifamily\exp_not:N\jttdefault\exp_not:N\fi%%%
+ \exp_not:N \selectfont
+ }
+ }
+ \str_if_eq_x:nnT {\familydefault} {\ttdefault}
+ { \tl_set_eq:NN \encodingdefault \g__fontspec_nfss_enc_tl }
+ \normalfont
+ \ignorespaces
+ }
+}
+
+\cs_set:Nn \fontspec_visible_space:
+ {
+ \__fontspec_primitive_font_glyph_if_exist:NnTF \font {"2423}
+ { \ltjalchar"2423\scan_stop: }
+ { \fontspec_visible_space_fallback: }
+ }
+
+\AtBeginDocument{
+ \cs_if_exist:NF \verbvisiblespace {
+ % >= LaTeX2e <2018-12-01> does not need the following patch
+ \def\verb
+ {
+ \relax\ifmmode\hbox\else\leavevmode\fi % same as lltjcore
+ \bgroup
+ \verb@eol@error \let\do\@makeother \dospecials
+ \verbatim@font\@noligs
+ \@ifstar\__fontspecsverb\@verb
+ }
+ }
+}
+\cs_set:Npn \emshape { \gtfamily \itshape }
+\cs_set:Npn \eminnershape { \mcfamily \upshape }
+
+\ExplSyntaxOff
+\expandafter\patchcmd\csname TU\string\textasteriskcentered\endcsname{\char}{\ltjalchar}{}{}
+
+\endinput
+
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-footmisc.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-footmisc.sty
new file mode 100644
index 0000000000..f74c496308
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-footmisc.sty
@@ -0,0 +1,58 @@
+%
+% lltjp-footmiscs.sty
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lltjp-footmisc}[2017/05/05 Patch to footmisc for LuaTeX-ja]
+\RequirePackage{footmisc}
+
+\let \if@tempswa \ifFN@bottom
+\ifFN@para \@tempswatrue \fi
+\if@tempswa
+ \ifFN@bottom
+ \toks@{\setbox\@outputbox \box\@cclv
+ \xdef\@freelist{\@freelist\@midlist}%
+ \global\let\@midlist\@empty
+ \@combinefloats
+ \ifvoid\footins
+ \else
+ \setbox\@outputbox \vbox\bgroup
+ \boxmaxdepth\@maxdepth
+ \unvbox\@outputbox
+ \vfill\relax
+ }
+ \the\FN@temptoken
+ \toks@\expandafter{\the\toks@\egroup\fi}
+ \else
+ \toks@{\ifvoid\footins
+ \setbox\@outputbox\box\@cclv
+ \else
+ \setbox\@outputbox \vbox\bgroup
+ \boxmaxdepth\@maxdepth
+ \unvbox\@cclv
+ }
+ \the\FN@temptoken
+ \toks@\expandafter{\the\toks@
+ \egroup
+ \fi
+ \xdef\@freelist{\@freelist\@midlist}%
+ \global\let\@midlist\@empty
+ \@combinefloats
+ }%
+ \fi
+ \toks@\expandafter{\the\toks@
+ \ifvbox\@kludgeins
+ \@makespecialcolbox
+ \else
+ \setbox\@outputbox \vbox to\@colht{%
+ \@texttop \dimen@\dp\@outputbox
+ \unvbox\@outputbox
+ \ifnum\ltjgetparameter{direction}=3 \vbox{\hskip\z@}\fi %%% LuaTeX-ja
+ \vskip -\dimen@\@textbottom
+ }%
+ \fi
+ \global\maxdepth\@maxdepth
+ }
+ \edef\@makecol{\the\toks@}
+\fi
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty
new file mode 100644
index 0000000000..678556e55e
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty
@@ -0,0 +1,513 @@
+%
+% lltjp-geometry.sty
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lltjp-geometry}[2018/01/19 Patch to geometry for LuaTeX-ja with vertical writing mode]
+\ifdefined\if@ltj@@geometry@tate\expandafter\endinput\fi
+\newif\if@ltj@@geometry@tate
+\newif\if@ltj@@geometry@forceoff
+\@ltj@@geometry@tatefalse
+\@ltj@@geometry@forceofffalse
+\DeclareOption{force}{\@ltj@@geometry@tatetrue}
+\DeclareOption{disable}{\@ltj@@geometry@forceofftrue}
+
+\ProcessOptions\relax
+
+\RequirePackage{ifluatex}
+\ifluatex
+ \ifdefined\luatexjaLoaded\else
+ \PackageError{lltjp-geometry}{%
+ lltjp-geometry does not work without luatexja.
+ }{}
+\fi
+\else % pTeX
+\def \AtBeginDvi #1{%
+ \global \setbox \@begindvibox
+ \vbox{\yoko\unvbox \@begindvibox #1}%
+}
+\fi
+
+\RequirePackage{filehook}
+\RequirePackage{etoolbox}
+\newif\ifGm@ltj@layoutswitch
+\let\orig@PackageWarningNoLine=\PackageWarningNoLine
+% define ifGm@swap@papersize if it is undefined
+\expandafter\newif\csname ifGm@swap@papersize\endcsname
+
+\AtBeginOfPackageFile{geometry}{%
+ \edef\Gm@ltj@topskip{\the\topskip}
+ \edef\Gm@ltj@headsep{\the\headsep}
+ \edef\Gm@ltj@footskip{\the\footskip}
+\ifluatex
+ \ifnum\ltjgetparameter{direction}=3 \@ltj@@geometry@tatetrue\fi
+\else
+ \@gobble\iftrue\csname iftdir\endcsname\@ltj@@geometry@tatetrue\fi
+\fi
+\patchcmd\@begindocumenthook{\tate}{\tate}{\@ltj@@geometry@tatetrue}{}%
+\if@ltj@@geometry@tate
+ \if@ltj@@geometry@forceoff
+ \@ltj@@geometry@tatefalse
+ \else
+ \let\PackageWarningNoLine\@gobbletwo% 警告抑止
+ \fi
+\fi
+}
+\AtEndOfPackageFile{geometry}{%
+\let\PackageWarningNoLine=\orig@PackageWarningNoLine
+\if@ltj@@geometry@tate
+ \let\PackageWarningNoLine=\orig@PackageWarningNoLine
+%%% ã“ã“ã‹ã‚‰ãƒ‘ッãƒé–‹å§‹
+
+% TODO:
+% * pTeX, LuaTeX ã¨ã‚‚ã« truedimen ãŒæ­£ã—ã動作ã—ãªã„
+% * pTeX resetpaper ãŒæ­£ã—ã動作ã—ãªã„
+%
+% `h', `v' ã¯ã€Œæ°´å¹³ã€ã€Œåž‚ç›´ã€ã‚’æ„味ã™ã‚‹ãŒï¼š
+% ユーザーå´ã§ã¯ã€Œç´™ã®ç‰©ç†çš„ãªæ°´å¹³æ–¹å‘ã€ã€Œç‰©ç†çš„ãªåž‚ç›´æ–¹å‘ã€ã‚’,
+% ã—ã‹ã—パッケージ内部処ç†ã§ã¯ã€Œå­—é€ã‚Šæ–¹å‘ã€ã€Œè¡Œé€ã‚Šæ–¹å‘ã€ã‚’表ã™ï¼Ž
+% ãã®ãŸã‚,key-value interface 内㧠h, v ã®äº¤æ›ã‚’è¡Œã†å¿…è¦ãŒã‚る.
+
+% twoside 指定時ã¯ï¼Œlmargin ã¯å°å£å´ï¼Œrmargin ã¯ãƒŽãƒ‰å´ã®ä½™ç™½ã‚’指ã™ï¼Ž
+% ã¾ãŸï¼Œbindingoffset å¶æ•°ãƒšãƒ¼ã‚¸ã‚’å³ã«ï¼Œå¥‡æ•°ãƒšãƒ¼ã‚¸ã‚’å·¦ã«ãšã‚‰ã™ï¼Ž
+\define@key{Gm}{hdivide}{\Gm@parse@divide{#1}{lmargin}{height}{rmargin}}%
+
+\define@key{Gm}{vscale}{\Gm@hbodytrue\edef\Gm@hscale{#1}}%
+\define@key{Gm}{hscale}{\Gm@vbodytrue\edef\Gm@vscale{#1}}%
+\define@key{Gm}{vdivide}{\Gm@parse@divide{#1}{tmargin}{width}{bmargin}}%
+\define@key{Gm}{divide}{\Gm@parse@divide{#1}{tmargin}{width}{bmargin}%
+ \Gm@parse@divide{#1}{lmargin}{height}{rmargin}}%
+\define@key{Gm}{vmargin}{\Gm@branch{#1}{tmargin}{bmargin}}%
+\define@key{Gm}{hmargin}{\Gm@branch{#1}{lmargin}{rmargin}}%
+\define@key{Gm}{margin}{\Gm@branch{#1}{tmargin}{lmargin}%
+ \Gm@branch{#1}{bmargin}{rmargin}}%
+\define@key{Gm}{headsep}{\Gm@defbylen{ltj@headsep}{#1}}%
+\define@key{Gm}{footskip}{\Gm@defbylen{ltj@footskip}{#1}}%
+\let\KV@Gm@foot\KV@Gm@footskip
+\define@key{Gm}{vmarginratio}{\edef\Gm@hmarginratio{#1}}%
+\define@key{Gm}{hmarginratio}{\edef\Gm@vmarginratio{#1}}%
+\define@key{Gm}{nohead}[true]{\Gm@doifelse{nohead}{#1}%
+ {\Gm@setlength\headheight\z@\Gm@defbylen{ltj@headsep}\z@}{}}%
+\define@key{Gm}{nofoot}[true]{\Gm@doifelse{nofoot}{#1}%
+ {\Gm@defbylen{ltj@footskip}\z@}{}}%
+\define@key{Gm}{noheadfoot}[true]{\Gm@doifelse{noheadfoot}{#1}%
+ {\Gm@setlength\headheight\z@\Gm@defbylen{ltj@headsep}\z@
+ \Gm@defbylen{ltj@footskip}\z@}{}}%
+\define@key{Gm}{layoutwidth}{\Gm@layouttrue\Gm@setlength\Gm@layoutheight{#1}}%
+\define@key{Gm}{layoutheight}{\Gm@layouttrue\Gm@setlength\Gm@layoutwidth{#1}}%
+\define@key{Gm}{layoutsize}{\Gm@branch{#1}{layoutwidth}{layoutheight}}%
+\define@key{Gm}{layout}{\Gm@layouttrue\@nameuse{Gm@#1}{Gm@layout}%
+ \Gm@setlength\@tempdima{\Gm@layoutheight}%
+ \Gm@setlength\Gm@layoutheight{\Gm@layoutwidth}%
+ \Gm@setlength\Gm@layoutwidth{\@tempdima}%
+}%
+
+% \@mparswitch ã¯å‚注ã®å‡ºåŠ›ä½ç½®ã‚’å·¦å³ãƒšãƒ¼ã‚¸ã§å¤‰ãˆã‚‹ã‚¹ã‚¤ãƒƒãƒã ãŒï¼Œ
+% geometry.sty ã¯ã“れを左å³ãƒšãƒ¼ã‚¸ã®ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã‚’変ãˆã‚‹ã‹å¦ã‹ã®åˆ¤å®šã«ã‚‚使ã£ã¦ã„る.
+% 縦組クラスã®å ´åˆã¯ \@mparswitch ã¯å¸¸ã«å½ã§ãªã„ã¨ãŠã‹ã—ãªã“ã¨ã«ãªã‚‹ã®ã§
+% \@mparswitch -> \Gm@ltj@layoutswitch ã¨å称変更ã™ã‚‹ï¼Ž
+
+\let\Gm@ltj@layoutswitch\@mparswitch
+\@mparswitchfalse
+\define@key{Gm}{twoside}[true]{\Gm@doifelse{twoside}{#1}%
+ {\@twosidetrue\Gm@ltj@layoutswitchtrue}{\@twosidefalse\Gm@ltj@layoutswitchfalse}}%
+\define@key{Gm}{asymmetric}[true]{\Gm@doifelse{asymmetric}{#1}%
+ {\@twosidetrue\Gm@ltj@layoutswitchfalse}{}}%
+
+% includemp 指定時ã¯ï¼Œ\headsep (if reversemp || twocolumn) や,
+% \footskip (if !reversemp || twocolumn) ã‚’å‚注幅ã ã‘増加ã•ã›ã‚‹ï¼Ž
+
+% h <-> v
+\def\Gm@Dhratio{2:3}% = top:bottom default
+\def\Gm@Dvratio{1:1}% = left:right default for oneside
+\def\Gm@Dvratiotwo{3:2}% = inner:outer default for twoside.
+\ifGm@swap@papersize
+ % geometry.sty ロード時㫠landscape オプションãŒæŒ‡å®šã•ã‚Œã¦ã„ãŸå ´åˆï¼Œ
+ % ãã‚Œã«ã‚ˆã£ã¦ç”¨ç´™ã‚µã‚¤ã‚ºã®ç¸¦æ¨ªãŒå…¥ã‚Œæ›¿ã‚ã£ã¦ã—ã¾ã£ã¦ã„ã‚‹ã®ã§è£œæ­£ã™ã‚‹ï¼Ž
+ \setlength\@tempdima{\paperwidth}%
+ \setlength\paperwidth{\paperheight}%
+ \setlength\paperheight{\@tempdima}%
+\fi
+
+% save length
+\def\Gm@save{%
+ \Gm@savelength{paperwidth}%
+ \Gm@savelength{paperheight}%
+ \Gm@savelength{textwidth}%
+ \Gm@savelength{textheight}%
+ \Gm@savelength{evensidemargin}%
+ \Gm@savelength{oddsidemargin}%
+ \Gm@savelength{topmargin}%
+ \Gm@savelength{headheight}%
+ %\Gm@savelength{headsep}%
+ \Gm@savelength{topskip}%
+ %\Gm@savelength{footskip}%
+ \Gm@savelength{baselineskip}%
+ \Gm@savelength{marginparwidth}%
+ \Gm@savelength{marginparsep}%
+ \Gm@savelength{columnsep}%
+ \Gm@savelength{hoffset}%
+ \Gm@savelength{voffset}
+ \Gm@savelength{Gm@layoutwidth}%
+ \Gm@savelength{Gm@layoutheight}%
+ \Gm@savelength{Gm@layouthoffset}%
+ \Gm@savelength{Gm@layoutvoffset}%
+ \Gm@saveboolean{@twocolumn}%
+ \Gm@saveboolean{@twoside}%
+ \Gm@saveboolean{Gm@ltj@layoutswitch}%
+ \Gm@saveboolean{@reversemargin}}%
+
+% frame
+\ifluatex
+ \def\Gm@pageframe@cmd{\vb@xt@\z@}
+\else
+ \def\Gm@pageframe@cmd{\vb@xt@\z@\bgroup\yoko\aftergroup\egroup}
+\fi
+\renewcommand*{\Gm@pageframes}{%
+ \Gm@pageframe@cmd{%
+ \ifGm@showcrop
+ \vb@xt@\z@{\vskip-1\Gm@truedimen in\vskip\Gm@layoutvoffset%
+ \hb@xt@\z@{\hskip-1\Gm@truedimen in\hskip\Gm@layouthoffset%
+ \vb@xt@\Gm@layoutwidth{%
+ \let\protect\relax
+ \hb@xt@\Gm@layoutheight{\Gm@cropmark(-1,1,-3,3)\hfil\Gm@cropmark(1,1,3,3)}%
+ \vfil
+ \hb@xt@\Gm@layoutheight{\Gm@cropmark(-1,-1,-3,-3)\hfil\Gm@cropmark(1,-1,3,-3)}}%
+ \hss}%
+ \vss}%
+ \fi%
+ \ifGm@showframe
+ \if@twoside
+ \ifodd\count\z@
+ \let\@themargin\oddsidemargin
+ \else
+ \let\@themargin\evensidemargin
+ \fi
+ \fi
+ \moveright\@themargin%
+ \vb@xt@\z@{%
+ \vskip\topmargin\vb@xt@\z@{\vss\Gm@hrule}%
+ \vskip\headheight\vb@xt@\z@{\vss\Gm@hruled}%
+ \vskip\headsep\vb@xt@\z@{\vss\Gm@hrule}%
+ \if@reversemargin\vb@xt@\z@{%
+ \vss\vb@xt@\z@{\vss\Gm@hrule}%
+ \vskip\marginparwidth\vb@xt@\z@{\vss\Gm@hrule}%
+ \vskip\marginparsep
+ }\fi
+ \hb@xt@\textwidth{\llap{\Gm@vrule}\hfil\Gm@vrule}%
+ \vb@xt@\z@{\vss\Gm@hruled}%
+ \unless\if@reversemargin\vb@xt@\z@{%
+ \vskip\marginparsep\vb@xt@\z@{\vss\Gm@hrule}%
+ \vskip\marginparwidth\vb@xt@\z@{\vss\Gm@hruled}\vss%
+ }\fi%
+ \vskip\footskip\vb@xt@\z@{\vss\Gm@hruled}%
+ \vss}%
+ \fi%
+ }}
+\def\Gm@detall#1#2#3#4{%
+ \@tempcnta\z@
+ \if#1h
+ \let\Gm@mratio\Gm@hmarginratio
+ \edef\Gm@Dmratio{\Gm@Dhratio}%
+ \else
+ \let\Gm@mratio\Gm@vmarginratio
+ \edef\Gm@Dmratio{\if@twoside\Gm@Dvratiotwo\else\Gm@Dvratio\fi}%
+ \fi
+ \if#1h
+ \ifx\Gm@tmargin\@undefined\else\advance\@tempcnta4\relax\fi
+ \ifGm@hbody\advance\@tempcnta2\relax\fi
+ \ifx\Gm@bmargin\@undefined\else\advance\@tempcnta1\relax\fi
+ \Gm@cnth\@tempcnta
+ \else
+ \ifx\Gm@lmargin\@undefined\else\advance\@tempcnta4\relax\fi
+ \ifGm@vbody\advance\@tempcnta2\relax\fi
+ \ifx\Gm@rmargin\@undefined\else\advance\@tempcnta1\relax\fi
+ \Gm@cntv\@tempcnta
+ \fi
+ \ifcase\@tempcnta
+ \if#1h
+ \Gm@defbylen{width}{\Gm@Dhscale\Gm@layoutwidth}%
+ \else
+ \Gm@defbylen{height}{\Gm@Dvscale\Gm@layoutheight}%
+ \fi
+ \Gm@detiiandiii{#2}{#3}{#4}%
+ \or
+ \ifx\Gm@mratio\@undefined
+ \if#1h
+ \Gm@defbylen{width}{\Gm@Dhscale\Gm@layoutwidth}%
+ \else
+ \Gm@defbylen{height}{\Gm@Dvscale\Gm@layoutheight}%
+ \fi
+ \setlength\@tempdimc{\@nameuse{Gm@#4}}%
+ \Gm@detiiandiii{#2}{#3}{#4}%
+ \expandafter\let\csname Gm@#2\endcsname\@undefined
+ \Gm@defbylen{#4}{\@tempdimc}%
+ \else
+ \Gm@setbyratio[f]{#1}{#4}{#3}%
+ \fi
+ \Gm@detiv{#2}{#3}{#4}{#2}%
+ \or\Gm@detiiandiii{#2}{#3}{#4}%
+ \or\Gm@detiv{#2}{#2}{#4}{#3}%
+ \or
+ \ifx\Gm@mratio\@undefined
+ \if#1h
+ \Gm@defbylen{width}{\Gm@Dhscale\Gm@layoutwidth}%
+ \else
+ \Gm@defbylen{height}{\Gm@Dvscale\Gm@layoutheight}%
+ \fi
+ \setlength\@tempdimc{\@nameuse{Gm@#3}}%
+ \Gm@detiiandiii{#2}{#4}{#3}%
+ \expandafter\let\csname Gm@#2\endcsname\@undefined
+ \Gm@defbylen{#3}{\@tempdimc}%
+ \else
+ \Gm@setbyratio[b]{#1}{#3}{#4}%
+ \fi
+ \Gm@detiv{#2}{#3}{#4}{#2}%
+ \or\Gm@detiv{#2}{#3}{#4}{#2}%
+ \or\Gm@detiv{#2}{#2}{#3}{#4}%
+ \or\Gm@warning{Over-specification in `#1'-direction.%
+ ^^J\@spaces `#2' (\@nameuse{Gm@#2}) is ignored}%
+ \Gm@detiv{#2}{#3}{#4}{#2}%
+ \else\fi}%
+\def\Gm@clean{%
+ \ifnum\Gm@cnth<4\let\Gm@tmargin\@undefined\fi
+ \ifodd\Gm@cnth\else\let\Gm@bmargin\@undefined\fi
+ \ifnum\Gm@cntv<4\let\Gm@lmargin\@undefined\fi
+ \ifodd\Gm@cntv\else\let\Gm@rmargin\@undefined\fi
+ \ifGm@hbody\else
+ \let\Gm@hscale\@undefined
+ \let\Gm@width\@undefined
+ \let\Gm@textwidth\@undefined
+ \fi
+ \ifGm@vbody\else
+ \let\Gm@vscale\@undefined
+ \let\Gm@height\@undefined
+ \let\Gm@textheight\@undefined
+ \fi
+ }%
+\def\Gm@adjustpaper{%
+ \ifdim\paperwidth>\p@\else
+ \PackageError{geometry}{%
+ \string\paperwidth\space(\the\paperwidth) too short}{%
+ Set a paper type (e.g., `a4paper').}%
+ \fi
+ \ifdim\paperheight>\p@\else
+ \PackageError{geometry}{%
+ \string\paperheight\space(\the\paperheight) too short}{%
+ Set a paper type (e.g., `a4paper').}%
+ \fi
+ \ifGm@swap@papersize
+ \setlength\@tempdima{\paperwidth}%
+ \setlength\paperwidth{\paperheight}%
+ \setlength\paperheight{\@tempdima}%
+ \fi
+ \ifGm@layout\else
+ \setlength\Gm@layoutwidth{\paperheight}%
+ \setlength\Gm@layoutheight{\paperwidth}%
+ \fi}%
+\def\Gm@adjustbody{
+ \ifGm@hbody
+ \ifx\Gm@width\@undefined
+ \ifx\Gm@hscale\@undefined
+ \Gm@defbylen{width}{\Gm@Dhscale\Gm@layoutwidth}%
+ \else
+ \Gm@defbylen{width}{\Gm@hscale\Gm@layoutwidth}%
+ \fi
+ \fi
+ \ifx\Gm@textwidth\@undefined\else
+ \setlength\@tempdima{\Gm@textwidth}%
+ \ifGm@includemp
+ \advance\@tempdima\Gm@wd@mp
+ \fi
+ \ifGm@includehead
+ \addtolength\@tempdima{\headheight}%
+ \addtolength\@tempdima{\headsep}%
+ \fi
+ \ifGm@includefoot
+ \addtolength\@tempdima{\footskip}%
+ \fi
+ \edef\Gm@width{\the\@tempdima}%
+ \fi
+ \fi
+ \ifGm@vbody
+ \ifx\Gm@height\@undefined
+ \ifx\Gm@vscale\@undefined
+ \Gm@defbylen{height}{\Gm@Dvscale\Gm@layoutheight}%
+ \else
+ \Gm@defbylen{height}{\Gm@vscale\Gm@layoutheight}%
+ \fi
+ \fi
+ \setlength\topskip\Gm@ltj@topskip
+ \ifx\Gm@lines\@undefined\else
+ \@tempdima=\f@size\p@ \@tempdima=.5\@tempdima
+ \ifluatex
+ \advance\@tempdima\ltjgetparameter{talbaselineshift}%
+ \else
+ \advance\@tempdima\tbaselineshift
+ \fi
+ \ifdim\maxdepth<\@tempdima
+ \PackageWarningNoLine{lltjp-geometry}%
+ {\noexpand\maxdepth was changed from \the\maxdepth\space
+ to \the\@tempdima}
+ \maxdepth\@tempdima
+ \fi
+ \setbox\z@=\hbox{\tate% next \ifdim must be executed in tate dir.
+ \ifdim\topskip<\ht\tstrutbox
+ \@tempdima\topskip
+ \global\topskip\ht\tstrutbox
+ \PackageWarningNoLine{lltjp-geometry}%
+ {\noexpand\topskip was changed from \the\@tempdima\space
+ to \the\topskip}
+ \fi}%
+ \setlength\@tempdima{\baselineskip}%
+ \multiply\@tempdima\Gm@lines
+ \addtolength\@tempdima{\topskip}%
+ \addtolength\@tempdima{-\baselineskip}%
+ \edef\Gm@textheight{\the\@tempdima}%
+ \fi
+ \ifx\Gm@textheight\@undefined\else
+ \edef\Gm@height{\Gm@textheight}%
+ \fi
+ \fi}%
+
+\def\Gm@adjustmp{%
+ \ifGm@includemp
+ \@tempdimb\marginparwidth
+ \advance\@tempdimb\marginparsep
+ \Gm@wd@mp\@tempdimb
+ \if@twocolumn
+ \Gm@wd@mp2\@tempdimb
+ \fi
+ \fi}%
+\def\Gm@@process{%
+ \Gm@expandlengths
+ \Gm@adjustpaper
+ \addtolength\Gm@layoutheight{-\Gm@bindingoffset}%
+ \Gm@adjustmp
+ \Gm@adjustbody
+ \Gm@detall{h}{width}{tmargin}{bmargin}%
+ \Gm@detall{v}{height}{lmargin}{rmargin}%
+ \setlength\textwidth{\Gm@width}%
+ \setlength\textheight{\Gm@height}%
+ \setlength\headsep{\Gm@ltj@headsep}%
+ \setlength\footskip{\Gm@ltj@footskip}%
+ \setlength\topmargin{\Gm@tmargin}%
+ \setlength\oddsidemargin{\Gm@lmargin}%
+ \addtolength\oddsidemargin{-1\Gm@truedimen in}%
+ \ifGm@ltj@layoutswitch
+ \setlength\evensidemargin{\Gm@rmargin}%
+ \addtolength\evensidemargin{-1\Gm@truedimen in}%
+ \else
+ \evensidemargin\oddsidemargin
+ \fi
+ \advance\evensidemargin\Gm@bindingoffset
+ \addtolength\topmargin{-1\Gm@truedimen in}%
+ \ifGm@includehead
+ \addtolength\textwidth{-\headheight}%
+ \addtolength\textwidth{-\headsep}%
+ \else
+ \addtolength\topmargin{-\headheight}%
+ \addtolength\topmargin{-\headsep}%
+ \fi
+ \ifGm@includefoot
+ \addtolength\textwidth{-\footskip}%
+ \fi
+ \ifGm@includemp
+ \advance\textwidth-\Gm@wd@mp
+ \if@twocolumn
+ \advance\headsep.5\Gm@wd@mp
+ \advance\footskip.5\Gm@wd@mp
+ \else\if@reversemargin
+ \advance\headsep\Gm@wd@mp
+ \else
+ \advance\footskip\Gm@wd@mp
+ \fi\fi
+ \fi
+ \ifGm@heightrounded
+ \setlength\@tempdima{\textheight}%
+ \addtolength\@tempdima{-\topskip}%
+ \@tempcnta\@tempdima
+ \@tempcntb\baselineskip
+ \divide\@tempcnta\@tempcntb
+ \setlength\@tempdimb{\baselineskip}%
+ \multiply\@tempdimb\@tempcnta
+ \advance\@tempdima-\@tempdimb
+ \multiply\@tempdima\tw@
+ \ifdim\@tempdima>\baselineskip
+ \addtolength\@tempdimb{\baselineskip}%
+ \fi
+ \addtolength\@tempdimb{\topskip}%
+ \textheight\@tempdimb
+ \fi
+ \advance\oddsidemargin\Gm@layouthoffset%
+ \advance\evensidemargin\Gm@layouthoffset%
+ \advance\topmargin\Gm@layoutvoffset%
+ \addtolength\Gm@layoutheight{\Gm@bindingoffset}%
+}% end of \Gm@@process
+% log
+\def\Gm@logcontent#1{%
+ *geometry* verbose mode - [ #1 ] result:^^J%
+ \ifGm@pass * pass: disregarded the geometry package!^^J%
+ \else
+ * driver: \if\Gm@driver<none>\else\Gm@driver\fi^^J%
+ * paper: \ifx\Gm@paper\@undefined<default>\else\Gm@paper\fi^^J%
+ * layout: \ifGm@layout<custom>\else<same size as paper>\fi^^J%
+ \ifGm@layout
+ * layout(width,height): (\the\Gm@layoutwidth,\the\Gm@layoutheight)^^J%
+ \fi
+ * layoutoffset:(h,v)=(\the\Gm@layouthoffset,\the\Gm@layoutvoffset)^^J%
+ \@ifundefined{Gm@lines}{}{* lines: \Gm@lines^^J}%
+ \@ifundefined{Gm@hmarginratio}{}{* hratio: \Gm@hmarginratio^^J}%
+ \@ifundefined{Gm@vmarginratio}{}{* vratio: \Gm@vmarginratio^^J}%
+ \ifdim\Gm@bindingoffset=\z@\else
+ * bindingoffset: \the\Gm@bindingoffset^^J\fi
+ * modes: %
+ \Gm@showbool{landscape}%
+ \Gm@showbool{includehead}%
+ \Gm@showbool{includefoot}%
+ \Gm@showbool{includemp}%
+ \if@twoside twoside\space\fi%
+ \ifGm@ltj@layoutswitch\else\if@twoside asymmetric\space\fi\fi%
+ \Gm@showbool{heightrounded}%
+ \ifx\Gm@truedimen\@empty\else truedimen\space\fi%
+ \Gm@showbool{showframe}%
+ \Gm@showbool{showcrop}%
+ ^^J%
+ * h-part:(L,W,R)=(\Gm@lmargin, \Gm@height, \Gm@rmargin)^^J%
+ * v-part:(T,H,B)=(\Gm@tmargin, \Gm@width, \Gm@bmargin)^^J%
+ \fi
+ \Gm@showdim{\paperwidth}%
+ \Gm@showdim{\paperheight}%
+ \Gm@showdim{\textwidth}%
+ \Gm@showdim{\textheight}%
+ \Gm@showdim{\oddsidemargin}%
+ \Gm@showdim{\evensidemargin}%
+ \Gm@showdim{\topmargin}%
+ \Gm@showdim{\headheight}%
+ \Gm@showdim{\headsep}%
+ \Gm@showdim{\topskip}%
+ \Gm@showdim{\footskip}%
+ \Gm@showdim{\marginparwidth}%
+ \Gm@showdim{\marginparsep}%
+ \Gm@showdim{\columnsep}%
+ * \string\skip\string\footins=\the\skip\footins^^J%
+ \Gm@showdim{\hoffset}%
+ \Gm@showdim{\voffset}%
+ \Gm@showdim{\mag}%
+ * \string\@twocolumn\if@twocolumn true\else false\fi^^J%
+ * \string\@twoside\if@twoside true\else false\fi^^J%
+ * \string\@mparswitch\if@mparswitch true\else false\fi^^J%
+ * \string\@reversemargin\if@reversemargin true\else false\fi^^J%
+ * (1in=72.27pt=25.4mm, 1cm=28.453pt)^^J}%
+
+
+\Gm@initall
+\Gm@processconfig
+\ProcessOptionsKV[c]{Gm}%
+\Gm@setdefaultpaper
+\ProcessOptionsKV[p]{Gm}%
+\Gm@process
+
+%%% 終了
+\fi}
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-listings.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-listings.sty
new file mode 100644
index 0000000000..13f75e302e
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-listings.sty
@@ -0,0 +1,440 @@
+%
+% lltjp-listings.sty 2018-09-17
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\RequirePackage{listings,luatexbase-cctb}
+
+%%%%%%%%%%%%%%%% Japanese support
+%% whether letter-space in a fixed mode box is doubled or not
+\newif\if@ltj@lst@double
+\lst@Key{doubleletterspace}f[t]{\lstKV@SetIf{#1}\if@ltj@lst@double}
+
+%% IVS support
+\newif\if@ltj@lst@vsraw
+\def\ltj@lst@vscmd{}
+\lst@Key{vsraw}f[t]{\lstKV@SetIf{#1}\if@ltj@lst@vsraw}
+\lst@Key{vscmd}\relax{\def\ltj@lst@vscmd{#1}}
+
+% 既定㮠IVS 出力コマンド
+\def\ltjlistingsvsstdcmd#1{\@tempdima=\f@size pt%
+ \smash{\raisebox{.35\@tempdima}{\tt%
+ \fboxsep=.1\@tempdima\fbox{\fontsize{.5\@tempdima}{\z@}\selectfont
+ \oalign{\hss VS\hss\crcr\hss#1\hss\crcr}}}}}
+\def\ltj@lst@vscmd{\ltjlistingsvsstdcmd}
+
+% override \lst@FillFixed@
+% \ltj@hst@hss is \ltj@lst@hss@ivs or \ltj@lst@hss@normal,
+% according to vsraw = true or not.
+\def\lst@FillFixed@#1{%
+ \ifx\@empty#1\else\ltj@lst@hss#1\expandafter\lst@FillFixed@\fi}
+
+\directlua{
+ local cat_str = luatexbase.catcodetables['string']
+ local cat_lp = luatexbase.catcodetables['latex-package']
+ local ubyte = unicode.utf8.byte
+ local spccmd = string.char(0x5C) .. 'ltj@lst@hss@normal'
+ luatexja.listings = {}
+ function luatexja.listings.althss(t)
+ t = ubyte(t)
+ if not (t>=0xE0100 and t<0xE01F0) then
+ tex.sprint(cat_lp, spccmd)
+ end
+ end
+}
+\def\ltj@lst@hss@ivs#1{%
+ \directlua{luatexja.listings.althss('\luatexluaescapestring{#1}')}#1%
+}
+\def\ltj@lst@hss@double{\lst@hss\lst@hss}
+
+% lowest level
+\newif\if@ltj@lst@kanji
+\lst@AddToHook{InitVars}{\@ltj@lst@kanjifalse}
+
+\def\lst@AppendLetter{%
+ \ltj@lst@setletterflag\lst@Append}
+\def\lst@AppendOther{%
+ \lst@ifletter\lst@Output\lst@letterfalse\fi\@ltj@lst@kanjifalse
+ \futurelet\lst@lastother\lst@Append}
+
+\def\ltj@lst@setletterflag{%
+ \lst@ifletter
+ \if@ltj@lst@kanji\lst@Output\@ltj@lst@kanjifalse\fi
+ \else
+ \lst@lettertrue\if@ltj@lst@kanji\@ltj@lst@kanjifalse\else\lst@OutputOther\fi
+ \fi}
+
+\def\ltj@lst@setkanjiflag{%
+ \lst@ifletter
+ \lst@Output
+ \else
+ \if@ltj@lst@kanji\else\lst@OutputOther\fi\lst@lettertrue
+ \fi\@ltj@lst@kanjitrue}
+
+\def\ltj@lst@setopenflag{%
+ \lst@ifletter
+ \lst@letterfalse\lst@Output
+ \else
+ \if@ltj@lst@kanji\else\lst@OutputOther\fi
+ \fi\@ltj@lst@kanjitrue}
+
+\def\ltj@lst@setcloseflag{%
+ \lst@ifletter\else\lst@lettertrue\fi\@ltj@lst@kanjitrue}
+
+% Processing Japanese characters
+\def\ltj@lst@ProcessJALetter#1{%
+ \lst@whitespacefalse
+ \ifnum\ltjgetparameter{jacharrange}{\ltjgetparameter{chartorange}{`#1}}=0
+ \ifnum\ltjgetparameter{postbreakpenalty}{`#1}>0
+ \ltj@lst@setopenflag % é–‹ã括弧類
+ \else
+ \ifnum\ltjgetparameter{prebreakpenalty}{`#1}>0
+ \ltj@lst@setcloseflag % é–‰ã˜æ‹¬å¼§é¡žï¼Œå¥èª­ç‚¹
+ \else
+ \ltj@lst@setkanjiflag % 通常ã®å’Œæ–‡æ–‡å­—
+ \fi\fi
+ \advance\lst@length\@ne % 和文文字ã¯é€šå¸¸ã®2å€ã®å¹…
+ \else
+ \ltj@lst@setletterflag
+ \fi
+ \lst@Append#1}
+
+% åŠè§’カナ処ç†å‘½ä»¤
+\def\ltj@lst@ProcessJALetterHalf#1{%
+ \lst@whitespacefalse
+ \ifnum\ltjgetparameter{jacharrange}{\ltjgetparameter{chartorange}{`#1}}=0
+ \ifnum\ltjgetparameter{postbreakpenalty}{`#1}>0
+ \ltj@lst@setopenflag % é–‹ã括弧類
+ \else
+ \ifnum\ltjgetparameter{prebreakpenalty}{`#1}>0
+ \ltj@lst@setcloseflag % é–‰ã˜æ‹¬å¼§é¡ž
+ \else
+ \ltj@lst@setkanjiflag % 通常ã®å’Œæ–‡æ–‡å­—
+ \fi\fi
+ % åŠè§’カナã¯æ¬§æ–‡æ–‡å­—ã¨åŒã˜å¹…
+ \else
+ \ltj@lst@setletterflag
+ \fi
+ \lst@Append#1}
+
+% 漢字用異体字セレクタ命令
+\def\ltj@lst@ProcessIVS#1{%
+ \lst@whitespacefalse
+ \if@ltj@lst@vsraw
+ \lst@Append#1\advance\lst@length\m@ne
+ \else
+ \lst@TrackNewLines\lst@OutputLostSpace \lst@PrintToken
+ \setbox\@tempboxa\hbox to 2\lst@width{\hss
+ \expandafter\expandafter\expandafter\ltj@lst@vscmd
+ \expandafter{\the\numexpr`#1-"E00EF\relax}%"
+ \hss}%
+ \lst@CalcLostSpaceAndOutput\lst@whitespacefalse
+ \fi
+}
+
+% Variation Selector
+\def\ltj@lst@ProcessVS#1{%
+ \lst@whitespacefalse
+ \if@ltj@lst@vsraw
+ \lst@Append#1\advance\lst@length\m@ne
+ \else
+ \lst@TrackNewLines\lst@OutputLostSpace \lst@PrintToken
+ \setbox\@tempboxa\hbox to 2\lst@width{\hss
+ \expandafter\expandafter\expandafter\ltj@lst@vscmd
+ \expandafter{\the\numexpr`#1-"FDFF\relax}%"
+ \hss}%
+ \lst@CalcLostSpaceAndOutput\lst@whitespacefalse
+ \fi
+}
+
+
+% åŠè§’カナ,異体字セレクタã¯ã‚¢ã‚¯ãƒ†ã‚£ãƒ–化
+\def\ltj@@listing@jpsetN#1#2#3{% for (not large) range
+ \@tempcnta=\numexpr#1-1\relax\@tempcntb=\numexpr 1+#2\relax
+ \loop \global\advance\@tempcnta\@ne\ifnum\@tempcnta<\@tempcntb\relax
+ \ltj@@listing@jpsetN@{\@tempcnta}{#3}\repeat
+}
+
+\def\ltj@@listing@jpsetN@#1#2{{%
+ \@tempcnta=#1 \lccode`\~=\@tempcnta \lccode`\/=\@tempcnta
+ \lowercase{\gdef\@temp{\gdef~{#2/}}}}%
+ \@temptokena\expandafter\expandafter\expandafter\expandafter%
+ \expandafter\expandafter\expandafter{\expandafter\expandafter%
+ \expandafter\the\expandafter\@temptokena\@temp}%
+}
+\@temptokena{}
+\ltj@@listing@jpsetN{65377}{65439}{\ltj@lst@ProcessJALetterHalf}
+\ltj@@listing@jpsetN{65024}{65039}{\ltj@lst@ProcessVS}
+\ltj@@listing@jpsetN{917760}{917999}{\ltj@lst@ProcessIVS}
+\xdef\ltj@@listing@jpcmd{\the\@temptokena}\@temptokena{}
+
+% catcode 対策
+\newluatexcatcodetable\CatcodeTableLTJlistings
+\setluatexcatcodetable\CatcodeTableLTJlistings{%
+ \luatexcatcodetable\CatcodeTableLaTeXAtLetter
+ \catcode\ltjlineendcomment=13%"
+ \SetCatcodeRange{"FF61}{"FF9F}{13}% åŠè§’カナ
+ \SetCatcodeRange{"E0100}{"E01EF}{13}% 漢字用異体字セレクタ
+ \SetCatcodeRange{"FE00}{"FE0F}{13}% Variation Selector
+}
+
+% redefine \lstinline and its inner commands to support Japanese characters
+\renewcommand\lstinline[1][]{%
+ \leavevmode\bgroup % \hbox\bgroup --> \bgroup
+ \def\lst@boxpos{b}%
+ \lsthk@PreSet\lstset{flexiblecolumns,#1}%
+ \lsthk@TextStyle
+ \@ifnextchar\bgroup \ltj@lst@InlineG \ltj@lstinline@}
+\def\ltj@lstinline@#1{%
+ \edef\ltj@lst@temp{\the\catcode`#1}\lst@Init\relax\catcode`#1\ltj@lst@temp
+ \lst@InlineJ#1}
+\def\ltj@lst@InlineG{%
+ \lst@Init\relax\edef\ltj@lst@temp{\the\catcode`\}}\catcode`\}=2 \catcode`\ =12\relax
+ \let\lst@arg\@empty\afterassignment\ltj@lst@InlineG@@\@temptokena}
+\def\ltj@lst@InlineG@@{%
+ \catcode`\}=\ltj@lst@temp%
+ \expandafter\expandafter\expandafter\lst@InsideConvert%
+ \expandafter{\the\@temptokena}\lst@arg\lst@DeInit\egroup}
+
+%%%%%%%%%%%%%%%% \lstMakeShortInline
+\patchcmd\lstMakeShortInline@{\lst@shortinlinedef#1}{\lst@shortinlinedef~}{}{}
+
+% We redefine \lst@BeginDropInput, since now we have
+% two additional `process macros'.
+\def\lst@BeginDropInput#1{%
+ \lst@EnterMode{#1}%
+ {\lst@modetrue
+ \let\lst@OutputBox\@gobble
+ \let\lst@ifdropinput\iftrue
+ \let\lst@ProcessLetter\@gobble
+ \let\lst@ProcessDigit\@gobble
+ \let\lst@ProcessOther\@gobble
+ \let\lst@ProcessSpace\@empty
+ \let\lst@ProcessTabulator\@empty
+ \let\lst@ProcessFormFeed\@empty
+ \let\ltj@lst@ProcessJALetter\@gobble % added
+ \let\ltj@lst@ProcessJALetterHalf\@gobble % added
+}}
+
+\directlua{
+ local utfchar, getcount = unicode.utf8.char, tex.getcount
+ luatexja.listings.insert_cb = function()
+ if not luatexja.listings.patched then
+ luatexja.listings.patched = 1
+ luatexbase.add_to_callback('process_input_buffer',
+ function(buf)
+ local ret = ''
+ for i = 1, utf.len(buf) do
+ local c = utf.sub(buf, i, i)
+ local cu = utf.byte(c)
+ if cu >= 0x80 and tex.getcatcode(cu) \string~= 13 then
+ ret = ret .. utfchar(getcount('ltjlineendcomment'))
+ end
+ ret = ret .. c
+ end
+ return ret
+ end, 'ltj.listings_unicode', 1)
+ end
+ end
+ luatexja.listings.remove_cb = function()
+ if luatexja.listings.patched then
+ luatexja.listings.patched = nil
+ luatexbase.remove_from_callback('process_input_buffer',
+ 'ltj.listings_unicode')%
+ end
+ end}
+
+% hook!
+\lst@AddToHook{Init}{%
+ \luatexcatcodetable\CatcodeTableLTJlistings\ltj@@listing@jpcmd
+ \lccode`\~=\ltjlineendcomment\lowercase{\def~{\ltj@lst@ProcessJALetter}}%"
+ \directlua{luatexja.listings.insert_cb()}%
+ \if@ltj@lst@double
+ \let\ltj@lst@hss@normal=\ltj@lst@hss@double
+ \else
+ \let\ltj@lst@hss@normal=\lst@hss
+ \fi
+ \if@ltj@lst@vsraw
+ \let\ltj@lst@hss=\ltj@lst@hss@ivs
+ \else
+ \let\ltj@lst@hss=\ltj@lst@hss@normal
+ \fi
+}
+
+\def\ltj@lst@MakeActive#1{%
+ \let\lst@temp\@empty \ltj@lst@MakeActive@#1\relax}
+\begingroup
+\catcode`\^^A=12
+\catcode`\^^@=\active
+\lccode`\$=\ltjlineendcomment \catcode`\$=13 %"
+\lowercase{%
+\gdef\ltj@lst@MakeActive@#1{\let\lst@next\relax%
+ \ifx#1\relax
+ \else\let\lst@next\ltj@lst@MakeActive@
+ \ifnum`#1>127
+ \lccode`\^^A=`#1
+ \lowercase{\lst@lAddTo\lst@temp{$^^A}}%$
+ \else
+ \lccode`\^^@=`#1
+ \lowercase{\lst@lAddTo\lst@temp{^^@}}%
+ \fi\fi\lst@next}}
+\endgroup
+
+
+\begingroup \lccode`\~=`\ \relax \lowercase{%
+\gdef\lst@InsideConvert@#1 #2{%
+ \ltj@lst@MakeActive{#1}%
+ \ifx\@empty#2%
+ \lst@lExtend\lst@arg{\lst@temp}%
+ \else
+ \lst@lExtend\lst@arg{\lst@temp~}%
+ \expandafter\lst@InsideConvert@
+ \fi#2}
+}\endgroup
+
+\lst@AddToHook{ExitVars}{%
+ \directlua{luatexja.listings.remove_cb()}%
+}
+
+% 白線対策
+\newif\ifltj@lst@frame@top
+\newdimen\ltj@lst@frame@lslimit
+\gdef\lst@frameInit{%
+ \ltj@lst@frame@toptrue
+ \ifx\lst@framelshape\@empty \let\lst@frameL\@empty \fi
+ \ifx\lst@framershape\@empty \let\lst@frameR\@empty \fi
+ \def\lst@framevrule{\vrule\@width\lst@framerulewidth\relax}%
+ \lst@ifframeround
+ \lst@frameCalcDimA\z@ \@getcirc\@tempdima
+ \@tempdimb\@tempdima \divide\@tempdimb\tw@
+ \advance\@tempdimb -\@wholewidth
+ \edef\lst@frametextsep{\the\@tempdimb}%
+ \edef\lst@framerulewidth{\the\@wholewidth}%
+ \lst@frameCalcDimA\@ne \@getcirc\@tempdima
+ \@tempdimb\@tempdima \divide\@tempdimb\tw@
+ \advance\@tempdimb -\tw@\@wholewidth
+ \advance\@tempdimb -\lst@frametextsep
+ \edef\lst@rulesep{\the\@tempdimb}%
+ \fi
+ \lst@frameMakeBoxV\lst@framebox{\ht\strutbox}{\dp\strutbox}%
+ %%%% ã“ã“ã‹ã‚‰
+ \@tempdima\z@
+ \ifdim\ht\strutbox<\cht\@tempdima=\dimexpr\cht-\ht\strutbox\relax\fi
+ \ifdim\dp\strutbox<\cdp\@tempdima=\dimexpr\cdp-\dp\strutbox\relax\fi
+ \ltj@lst@frame@lslimit=-\@tempdima
+ \def\lst@framelr{%
+ \ifltj@lst@frame@top\ltj@lst@frame@topfalse\else\lineskiplimit\ltj@lst@frame@lslimit\fi
+ \copy\lst@framebox}%
+ %%%% ã“ã“ã¾ã§
+ \ifx\lst@frametshape\@empty\else
+ \lst@frameH T\lst@frametshape
+ \ifvoid\z@\else
+ \par\lst@parshape
+ \@tempdima-\baselineskip \advance\@tempdima\ht\z@
+ \ifdim\prevdepth<\@cclvi\p@\else
+ \advance\@tempdima\prevdepth
+ \fi
+ \ifdim\@tempdima<\z@
+ \vskip\@tempdima\vskip\lineskip
+ \fi
+ \noindent\box\z@\par
+ \lineskiplimit\maxdimen \lineskip\z@
+ \fi
+ \lst@frameSpreadV\lst@framextopmargin
+ \fi}
+
+
+
+%%%%%%%%%%%%%%%% escape to \LaTeX
+\lstloadaspects{escape}
+\gdef\lst@Escape#1#2#3#4{%
+ \lst@CArgX #1\relax\lst@CDefX
+ {}%
+ {\lst@ifdropinput\else
+ \lst@TrackNewLines\lst@OutputLostSpace \lst@XPrintToken
+ \lst@InterruptModes
+ \lst@EnterMode{\lst@TeXmode}{\lst@modetrue}%
+ \ifx\^^M#2%
+ \lst@CArg #2\relax\lst@ActiveCDefX
+ {}%
+ {\lst@escapeend #4\lst@LeaveAllModes\lst@ReenterModes}%
+ {\lst@MProcessListing}%
+ \else
+ \lst@CArg #2\relax\lst@ActiveCDefX
+ {}%
+ {\lst@escapeend #4\lst@LeaveAllModes\lst@ReenterModes
+ \lst@newlines\z@ \lst@whitespacefalse}%
+ {}%
+ \fi%
+ \ltj@lst@escape@setup#2%
+ #3\catcode\ltjlineendcomment=9\lst@escapebegin\expandafter\lst@next%"
+ \fi}%
+ {}}
+\def\ltj@lst@emptygrp{{}}
+\def\ltj@lst@escape@setup#1{%
+ \begingroup\lccode`\~=`#1\lowercase{%
+ \gdef\lst@next##1~{%
+ \let\lst@arg\@empty\ltj@lst@remove@jacmd{##1}%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
+ \scantokens\expandafter\expandafter\expandafter{\expandafter\ltj@lst@emptygrp\lst@arg\empty}%
+ ~}%
+ }\endgroup
+}
+\begingroup
+ \lccode`\|=\ltjlineendcomment \lowercase{%"
+ \gdef\ltj@lst@remove@jacmd#1{%
+ \expandafter\ltj@lst@remove@jacmd@\detokenize{#1}|\@nil|}
+ \gdef\ltj@lst@remove@jacmd@#1|{%
+ \ifx#1\@nil\else
+ \lst@lAddTo\lst@arg{#1}%
+ \expandafter\ltj@lst@remove@jacmd@
+ \fi}}
+\endgroup
+
+%%%%%%%%%%%%%%%% texcl
+\lst@AddToHook{AfterBeginComment}
+ {\ifnum\lst@mode=\lst@TeXLmode
+ \catcode`\^^M=13\relax
+ \catcode\ltjlineendcomment=9\relax
+ \fi}
+
+%%%%%%%%%%%%%%%%
+\lstloadaspects{writefile}
+\begingroup \catcode`\^^I=11
+\gdef\lst@WFBegin#1#2{%
+ \begingroup
+ \let\lst@OutputBox#1%
+ \def\lst@Append##1{%
+ \advance\lst@length\@ne
+ \expandafter\lst@token\expandafter{\the\lst@token##1}%
+ \ifx ##1\lst@outputspace \else
+ \lst@WFAppend##1%
+ \fi}%
+ \lst@lAddTo\lst@PreGotoTabStop{\lst@WFAppend{^^I}}%
+ \lst@lAddTo\lst@ProcessSpace{\lst@WFAppend{ }}%
+ \def\ltj@lst@ProcessIVS##1{\lst@whitespacefalse\lst@Append##1}%
+ \def\ltj@lst@ProcessVS##1{\lst@whitespacefalse\lst@Append##1}%
+ \let\lst@DeInit\lst@WFDeInit
+ \let\lst@MProcessListing\lst@WFMProcessListing
+ \lst@WFifopen\else
+ \immediate\openout\lst@WF=#2\relax
+ \global\let\lst@WFifopen\iftrue
+ \@gobbletwo\fi\fi
+ \fi}
+\endgroup
+
+
+% \begin{修正事項}{1.3} from jlisting.sty
+% ã¡ã‚‡ã£ã¨ã—ãŸä¿®æ­£
+\gdef\lst@breakProcessOther#1{\lst@ProcessOther#1}
+% ソースコード目次ã«ãŠã‘る文字ã¨ç•ªå·ã®ç©ºã
+\let \l@lstlisting = \l@figure
+
+%%%%
+% キャプションã¨ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ç›®æ¬¡ã«å¯¾ã™ã‚‹æ—¥æœ¬èªžå¯¾å¿œ
+%\def\lstlistingname{ソースコード}
+%\def\lstlistlistingname{ソースコード目次}
+% \end{修正事項}
+%%%%
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-microtype.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-microtype.sty
new file mode 100644
index 0000000000..db2fac8481
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-microtype.sty
@@ -0,0 +1,67 @@
+%
+% lltjp-microtype.sty 2019-08-12
+%
+% (Work in Progress)
+%
+\NeedsTeXFormat{LaTeX2e}
+
+\RequirePackage{etoolbox}
+\makeatletter
+
+\def\MT@register@font{%
+ \xdef\MT@font@list{\expandonce{\MT@font@list\MT@font},}% !!!
+}
+\def\MT@register@subst@font{\MT@exp@one@n\MT@in@clist\font@name\MT@font@list
+ \ifMT@inlist@\else
+ \xdef\MT@font@list{\expandonce{\MT@font@list\font@name},}% !!!
+ \fi}
+\let\ltj@MT@tracking@\MT@tracking@
+\def\MT@tracking@{%
+ \MT@exp@one@n\MT@in@clist\MT@font\MT@tr@font@list
+ \ifMT@inlist@\else
+ \MT@maybe@do{tr}%
+ \ifMT@do\else
+ \xdef\MT@tr@font@list{\expandonce{\MT@tr@font@list\MT@font,}}% !!!
+ \fi
+ \fi
+}
+\ifx\MT@tracking\ltj@MT@tracking@\let\MT@tracking\MT@tracking@\fi
+
+
+%\endinput
+\begingroup
+ \catcode`\/=\z@
+ /MT@map@tlist@n{/\LÏ„JCHAREX}/@makeother /lccode`/Ï„=`/t
+ /lowercase{%
+ /def/x{/endgroup
+ /def/MT@charstring{\CHAR"}%
+ /def/MT@is@char##1\CHAR"##2##3##4/relax{%
+ %/message{MIC <##1><##2><##3><##4>}%
+ /ifx/relax##4/relax
+ /expandafter/MT@is@char@ltja/MT@strip@prefix##1>/relax\LÏ„JALCHAR\LÏ„JALCHAR/relax
+ /else
+ /ifx/relax##1/relax
+ /if##3\/relax
+ /edef/MT@char@{/number"##2}%
+ /MT@ifstreq/MT@charstring{##3##4}/relax/MT@norestfalse
+ /else
+ /edef/MT@char@{/number"##2##3}%
+ /MT@ifstreq/MT@charstring{##4}/relax
+ {/MT@is@xchar##2##3|##4\CHAR"/relax}%
+ /fi
+ /fi
+ /fi
+ }%
+ /def/MT@ltjs@drop@##1>##2/relax{##1}%
+ /def/MT@is@char@ltja##1\LÏ„JALCHAR##2\LÏ„JALCHAR##3/relax{%
+ %/typeout{MICLTJA <##1><##2><##3>}%
+ /ifx/relax##1/relax
+ /ifx/relax##2/relax/else
+ /edef/MT@char@{/expandafter/number/MT@ltjs@drop@##2>/relax}%
+ /fi
+ /fi
+ }%
+ }%
+ }
+/x
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-preview.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-preview.sty
new file mode 100644
index 0000000000..00602884ea
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-preview.sty
@@ -0,0 +1,22 @@
+%
+% lltjp-preview.sty
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lltjp-preview}[2018/01/20 Patch to preview for LuaTeX-ja]
+
+\RequirePackage{etoolbox,preview}
+\newbox\ltj@preview@box
+
+\patchcmd\pr@endbox{%
+ \pr@ship@end
+}{%
+ \setbox\ltj@preview@box=\box\AtBeginShipoutBox
+ \setbox\AtBeginShipoutBox=\vbox{\yoko\box\pr@box}%
+ \directlua{luatexja.direction.finalize()}%
+ \setbox\pr@box=\box\AtBeginShipoutBox
+ \setbox\AtBeginShipoutBox=\box\ltj@preview@box
+ \pr@ship@end
+}{}{}
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-siunitx.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-siunitx.sty
new file mode 100644
index 0000000000..c6bebc36cd
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-siunitx.sty
@@ -0,0 +1,96 @@
+%
+% lltjp-siunitx.sty 2019-06-06
+%
+
+\NeedsTeXFormat{LaTeX2e}
+
+\RequirePackage{siunitx}
+\makeatletter
+\ExplSyntaxOn
+\cs_generate_variant:Nn \tl_if_in:NnT { coT }
+\cs_new:Nn \__ltj_siunix_patch_inner:n {
+ \cs_if_exist:cT { #1_tl } {
+ \tl_if_in:coT { #1_tl } { \tex_char:D } {
+ \tl_replace_all:cnn { #1_tl } { \tex_char:D } { \ltjalchar }
+ }
+ }
+}
+\cs_new:Nn \__ltj_siunix_patch_inner_math:n {
+ \__ltj_siunix_patch_inner:n { l__siunitx_#1_math }
+ \__ltj_siunix_patch_inner:n { l__siunitx_#1_text }
+}
+\AtBeginDocument {
+ \__ltj_siunix_patch_inner:n { c__siunitx_minus }
+ \__ltj_siunix_patch_inner:n { c__siunitx_mu }
+ \__ltj_siunix_patch_inner_math:n { angstrom }
+ \__ltj_siunix_patch_inner_math:n { arcminute }
+ \__ltj_siunix_patch_inner_math:n { arcsecond }
+ \__ltj_siunix_patch_inner_math:n { ohm }
+}
+
+%%%% new table column: S and s
+\bool_new:N \l__ltj_siunitx_table_collect_relax_bool
+\cs_set_protected:Npn \__siunitx_table_collect_begin_s: {
+ \bool_set_false:N \l__ltj_siunitx_table_collect_relax_bool
+ \cs_set_eq:NN \__siunitx_table_collect_token:N
+ \__siunitx_table_collect_token_s:N
+ \cs_set_eq:NN \__siunitx_table_print: \__siunitx_table_print_s:
+ \__siunitx_table_collect_init_s:
+ \__siunitx_table_collect_get:
+}
+
+\cs_set_protected:Npn \__siunitx_table_collect_not_braced:N #1
+ {
+ \token_if_eq_meaning:NNTF #1 \tex_relax:D {
+ \bool_if:NTF \l__ltj_siunitx_table_collect_relax_bool {
+ \__siunitx_table_collect_not_braced_aux_i:N #1
+ } {
+ \bool_set_true:N \l__ltj_siunitx_table_collect_relax_bool
+ }
+ } {
+ \token_if_eq_meaning:NNF #1 \ltjfakeboxbdd {
+ \token_if_eq_meaning:NNF #1 \pltx@next@inhibitglue {
+ \token_if_eq_meaning:NNF #1 \tex_ignorespaces:D
+ {
+ \token_if_eq_meaning:NNF #1 \tex_unskip:D
+ { \__siunitx_table_collect_not_braced_aux_i:N #1 }
+ }
+ }}}
+ \__siunitx_table_collect_next:
+ }
+
+\AtBeginDocument
+ {
+ \@ifpackageloaded { mdwtab }
+ {
+ \cs_set_protected:Npn \__siunitx_table_collect_not_braced:N #1
+ {
+ \token_if_eq_meaning:NNTF #1 \tex_relax:D {
+ \bool_if:NTF \l__ltj_siunitx_table_collect_relax_bool {
+ \__siunitx_table_collect_not_braced_aux_i:N #1
+ } {
+ \bool_set_true:N \l__ltj_siunitx_table_collect_relax_bool
+ }
+ } {
+ \token_if_eq_meaning:NNF #1 \ltjfakeboxbdd {
+ \token_if_eq_meaning:NNF #1 \pltx@next@inhibitglue {
+ \token_if_eq_meaning:NNF #1 \tex_ignorespaces:D
+ {
+ \token_if_eq_meaning:NNF #1 \tex_unskip:D
+ {
+ \token_if_eq_meaning:NNF #1 \tab@setcr
+ {
+ \token_if_eq_meaning:NNF #1 \@maybe@unskip
+ { \__siunitx_table_collect_not_braced_aux_i:N #1 }
+ }
+ }
+ }
+ }}}
+ \__siunitx_table_collect_next:
+ }
+ }
+ { }
+ }
+
+\ExplSyntaxOff
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-stfloats.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-stfloats.sty
new file mode 100644
index 0000000000..e7535bd7e1
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-stfloats.sty
@@ -0,0 +1,27 @@
+%
+% lltjp-stfloats.sty 2017-05-05
+%
+
+\NeedsTeXFormat{LaTeX2e}
+
+\RequirePackage{stfloats}
+\RequirePackage{etoolbox}
+
+\newif\ifltj@stfloats@fnbelowfloat
+\let\ltj@fn@makecol=\fn@makecol
+\ifx\@makecol\ltj@fn@makecol\ltj@stfloats@fnbelowfloattrue\fi % \fnbelowfloat 発行済
+\let\ltj@fn@makecol=\relax
+\global\let\org@makecol\ltj@orig@makecol
+
+\patchcmd\fn@makecol{\vskip -\dimen@\@textbottom}%
+ {\ifnum\ltjgetparameter{direction}=4\else\vbox{\hskip\z@}\fi %%% LuaTeX-ja
+ \vskip -\dimen@
+ \ifltj@ftn@unvboxed\iffnfixbottom\else\@textbottom\fi\else\@textbottom\fi}{}{}
+\patchcmd\fn@makecol{\vskip\skip\footins}{\iffnfixbottom\vskip\z@\@plus.0001fil\fi\vskip\skip\footins}{}{}
+\patchcmd\fn@makecol{\ifvoid\footins}{\ifvoid\footins\ltj@ftn@unvboxedfalse}{}{}
+\patchcmd\fn@makecol{\setbox\@outputbox \vbox}{\ltj@ftn@unvboxedtrue\setbox\@outputbox \vbox}{}{}
+
+\ifltj@stfloats@fnbelowfloat
+ \global\let\@makecol\fn@makecol
+\fi
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-tascmac.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-tascmac.sty
new file mode 100644
index 0000000000..d0ac424701
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-tascmac.sty
@@ -0,0 +1,142 @@
+%
+% lltjp-tascmac.sty
+% based on tascmac.sty [2016/04/15 v2.0b (community edition)]
+% \tbaselineshift=\z@ ==> \ltj@tablshift=\z@
+% \ybaselineshift=\z@ ==> \ltj@yablshift=\z@
+% \dimen...=\tbaselineshift ==> \dimen...=\ltj@tablshift sp
+% \dimen...=\ybaselineshift ==> \dimen...=\ltj@yablshift sp
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lltjp-tascmac}[2017/12/23 Patch to (t)ascmac for LuaTeX-ja]
+
+\RequirePackage{tascmac}
+
+%% use Type1 font for ascgrp
+\pdfextension mapline{+ascgrp <ascgrp.pfb}
+
+%% oval command
+\def\ascmac@parse@ovarg#1{%
+ \ifnum\ltjgetparameter{direction}=3\relax
+ \def\ascmac@ovarg{}%
+ \@tfor\reserved@a:=#1\do{%
+ \if l\reserved@a \edef\ascmac@ovarg{\ascmac@ovarg t}%
+ \else\if t\reserved@a \edef\ascmac@ovarg{\ascmac@ovarg r}%
+ \else\if r\reserved@a \edef\ascmac@ovarg{\ascmac@ovarg b}%
+ \else\if b\reserved@a \edef\ascmac@ovarg{\ascmac@ovarg l}%
+ \fi\fi\fi\fi}%
+ \else
+ \def\ascmac@ovarg{#1}%
+ \fi
+}
+
+%% boxnote environment
+\def\boxnote{\par\vspace{.3\baselineskip}%
+ \@saveybaselineshift\ltj@yablshift sp\ltj@yablshift\z@
+ \@savetbaselineshift\ltj@tablshift sp\ltj@tablshift\z@
+ \setbox\@nbox=\hbox{\@ascgrp\vrule width1.08pt depth35pt b\hss a\hss b}
+ \@whiledim \wd\@nbox<\hsize \do{
+ \setbox\@nbox=\hbox{\@ascgrp\unhbox\@nbox \hss a\hss b}}
+ \setbox\@nbox=\hbox to\hsize{\@ascgrp\unhbox\@nbox \hss a\hss b%
+ \vrule width1.08pt depth35pt}
+ \@bw=\wd\@nbox\advance\@bw -40pt
+ \begin{lrbox}{\@nbody}\begin{minipage}{\@bw}% (KN:1998/02/27)
+ \ltj@yablshift\@saveybaselineshift \ltj@tablshift\@savetbaselineshift}%
+
+%% screen environment
+\def\screen{%
+ \@saveybaselineshift\ltj@yablshift sp\ltj@yablshift\z@
+ \@savetbaselineshift\ltj@tablshift sp\ltj@tablshift\z@
+ \@ifnextchar[{\@screen}{\@screen[0]}}
+\def\@screen[#1]{\ifcase#1\def\@r{20}\def\@s{9.8pt}\def\@sx{10pt}\or
+ \def\@r{18}\def\@s{8.8pt}\def\@sx{9pt}\or
+ \def\@r{16}\def\@s{7.8pt}\def\@sx{8pt}\or
+ \def\@r{14}\def\@s{6.8pt}\def\@sx{7pt}\or
+ \def\@r{12}\def\@s{5.8pt}\def\@sx{6pt}\or
+ \def\@r{10}\def\@s{4.8pt}\def\@sx{5pt}\or
+ \def\@r{8}\def\@s{3.8pt}\def\@sx{4pt}\or
+ \def\@r{6}\def\@s{2.8pt}\def\@sx{3pt}\else
+ \def\@r{4}\def\@s{1.8pt}\def\@sx{2pt}\fi
+ \par\vspace{.3\baselineskip}\@scw\linewidth \advance\@scw -\@r pt
+ \setbox\scb@x=\hbox to\@scw\bgroup\begin{minipage}{\@scw}% (KN:1998/02/27)
+ \ltj@yablshift\@saveybaselineshift \ltj@tablshift\@savetbaselineshift}%
+
+%% itembox environment
+\def\@itembox[#1]#2{%
+ \@saveybaselineshift\ltj@yablshift sp\ltj@yablshift\z@
+ \@savetbaselineshift\ltj@tablshift sp\ltj@tablshift\z@
+ \par\vspace{.3\baselineskip}%
+ \setbox\@iboxstr=\hbox{%
+ \ltj@yablshift\@saveybaselineshift \ltj@tablshift\@savetbaselineshift #2}%
+ \@itemh\ht\@iboxstr\advance\@itemh\dp\@iboxstr
+ \vspace{.5\@itemh}\bgroup\@scw\linewidth
+ \advance\@scw-20pt\@iboxpos={#1}%
+ \setbox\scb@x=\hbox to\@scw\bgroup\begin{minipage}{\@scw}%
+ \ltj@yablshift\@saveybaselineshift
+ \ltj@tablshift\@savetbaselineshift
+ \vspace*{.5\@itemh}}%
+
+%% \keytop
+\def\@keytop[#1]#2{%
+ {\setbox0=\hbox{\shortstack{#2}}\ltj@yablshift\z@\ltj@tablshift\z@%
+ \dimen0=\wd0\advance\dimen0 5pt\dimen1=\dp0\advance\dimen1 2.5pt%
+ \setbox\scscb@x=\hbox to\dimen0{%
+ \@scw\wd0\hfil\vtop{\offinterlineskip
+ \thinlines\setlength{\unitlength}{1pt}\hrule\kern2.3pt\@hobox{tl}{tr}5%
+ \kern-2.4pt\box0\@hobox{bl}{br}5\kern-.4pt\hrule}\hfil}%
+ \dimen0=\dp\scscb@x\advance\dimen0 -.4pt
+ \setbox0=\vbox{\hbox{\hbox to.2pt{\vtop to\dimen0{\@vrf@{2.3pt}{.4pt}}\hss}%
+ \box\scscb@x\hbox to.2pt{\hss\vtop to\dimen0{\@vrf@{2.3pt}{.4pt}}}}}%
+ \if #1c\mbox{}$\vcenter{\box0}$\mbox{}\else
+ \if #1t\else\if #1b\boxmaxdepth=0pt\else
+ \boxmaxdepth=\dimen1\fi\fi \mbox{}\vbox{\box0}\fi}}
+
+%% \mask
+\def\mask#1#2{{\setbox\@bwsp=\hbox{#1}%
+ \setbox0=\hbox{\ltj@yablshift\z@\ltj@tablshift\z@ \@ascgrp#2}%
+ \dimen0=\wd\@bwsp\dimen1=\ht\@bwsp\advance\dimen1\dp\@bwsp\dimen2=-\dimen1
+ \setdim@{\dimen0}{\wd0}\setdim@{\dimen1}{\ht0}%
+ \setbox\@@bwsp=\hbox to\dimen0{\leaders
+ \vtop to\dimen1{\leaders\box0\vfil}\hfil}%
+ \advance\dimen2\dp\@@bwsp\divide\dimen2 2
+ \advance\dimen2\dp\@bwsp\boxmaxdepth=\dimen2
+ \setbox\@@bwsp=\vbox{\box\@@bwsp}%
+ \mbox{}\hbox to\wd\@@bwsp{\hbox to0pt{\box\@@bwsp\hss}\hss\unhbox\@bwsp\hss}}}
+
+%% \maskbox
+\def\Maskbox#1#2#3#4#5#6{{%
+ \setbox0=\hbox{\ltj@yablshift\z@\ltj@tablshift\z@ \@ascgrp#3}%
+ \dimen0=#1\@setdim{\dimen0}{\wd0}\dimen1=#2\@setdim{\dimen1}{\ht0}%
+ \ifx#4c\skip0=0pt plus1fil\skip1=\skip0\fi
+ \ifx#4r\skip0=0pt plus1fil\skip1=0pt\fi
+ \ifx#4l\skip1=0pt plus1fil\skip0=0pt\fi
+ \leavevmode
+ \hbox{\hbox to0pt{\hbox to\dimen0{\leaders\vbox to\dimen1{\leaders
+ \box0\vfil}\hfil}\hss}%
+ \vrule width#5\vbox to\dimen1{\hrule height#5\vfil
+ \dimen3=#5\advance\dimen0-2\dimen3\advance\dimen0 .15pt
+ \hbox to\dimen0{\hskip\skip0\relax#6\hskip\skip1}%
+ \vfil\hrule height#5}\vrule width#5}}}
+
+%% shadebox environment
+\def\shadebox{\par\vspace{.3\baselineskip}%
+ \@saveybaselineshift\ltj@yablshift sp\ltj@yablshift\z@
+ \@savetbaselineshift\ltj@tablshift sp\ltj@tablshift\z@
+ \dimen0\linewidth \advance\dimen0-20pt
+ \advance\dimen0-2\fboxrule \advance\dimen0-\shaderule
+ \setbox\@tempboxa=\hbox\bgroup\minipage{\dimen0}%
+ \ltj@yablshift\@saveybaselineshift \ltj@tablshift\@savetbaselineshift}
+
+%% \yen
+%
+% \changes{1996/03/13}{v1.1}{Append \cs{leavevmode} in
+% \cs{yen}, \cs{return}, \cs{Return} command.}
+%
+\def\yen{\leavevmode\hbox{\yoko%
+\setbox0=\hbox{Y}Y\kern-.97\wd0\vbox{\hrule height.1ex width.98\wd0
+\kern.33ex\hrule height.1ex width.98\wd0\kern.45ex}}}
+%
+%% return-key
+\def\return{\leavevmode\hbox{\yoko\@ascgrp\char"20}}
+\def\Return{\leavevmode\hbox{\yoko\@ascgrp @}}
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-unicode-math.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-unicode-math.sty
new file mode 100644
index 0000000000..d8c4055d14
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-unicode-math.sty
@@ -0,0 +1,87 @@
+%
+% lltjp-unicode-math.sty 2018-10-09
+%
+
+\NeedsTeXFormat{LaTeX2e}
+
+\RequirePackage{unicode-math,etoolbox}
+
+\ExplSyntaxOn
+
+\cs_set:Nn \__um_define_math_chars: {
+ \group_begin:
+ \cs_set:Npn \__um_sym:nnn ##1##2##3
+ {
+ \ltjsetmathletter{ ##1 }
+ \tl_if_in:nnT
+ { \mathord \mathalpha \mathbin \mathrel \mathpunct \mathop \mathfence }
+ {##3}
+ {
+ \exp_last_unbraced:NNx \cs_gset_eq:NN ##2 { \char_generate:nn {##1} {12} }
+ }
+ }
+ \__um_input_math_symbol_table:
+ \group_end:
+}
+\unless\ifltj@disablejfam
+\cs_set:Npn \use@mathgroup #1 #2
+{
+ %\typeout{UM <#1><#2>}
+ \mode_if_math:T % <- not sure
+ {
+ \math@bgroup
+ \cs_if_eq:cNF {M@\f@encoding} #1 {#1}
+ \__um_switchto_literal:
+ \ltj@tempcnta=#2 \expandafter\ltj@@mathJapaneseFonts\string#1\relax%
+ \ifin@ \jfam #2 \relax \else \mathgroup #2 \relax \fi
+ \math@egroup
+ }
+}
+\fi
+
+\ifcsname jsc@mag@xrealtrue \endcsname \else
+ \expandafter\expandafter\expandafter \ExplSyntaxOff \expandafter \endinput
+\fi
+\ifjsc@mag@xreal
+ \cs_if_exist:cTF { ltjs@orig@get@external@font } {
+ % ltjsclasses: use lua
+ \cs_new:Nn \lltjp_um_unmag_fsize:
+ {
+ \cs_gset:Nx \lltjp_um_f@size: {\directlua{luatexja.ltjs_unmagnify_fsize(\f@size)}}
+ \cs_gset:Nx \lltjp_um_sf@size: {\directlua{luatexja.ltjs_unmagnify_fsize(\sf@size)}}
+ \cs_gset:Nx \lltjp_um_ssf@size: {\directlua{luatexja.ltjs_unmagnify_fsize(\ssf@size)}}
+ }
+ }{
+ % bxjscls: use \jsc@preadjust@extract@font
+ \cs_new:Nn \lltjp_um_unmag_fsize:
+ {
+ \group_begin:
+ \jsc@preadjust@extract@font
+ \cs_gset_eq:NN \lltjp_um_f@size: \f@size
+ \group_end:
+ \group_begin:
+ \cs_set_eq:NN \f@size \sf@size \jsc@preadjust@extract@font
+ \cs_gset_eq:NN \lltjp_um_sf@size: \f@size
+ \group_end:
+ \group_begin:
+ \cs_set_eq:NN \f@size \ssf@size \jsc@preadjust@extract@font
+ \cs_gset_eq:NN \lltjp_um_ssf@size: \f@size
+ \group_end:
+ }
+ }
+ \pretocmd { \__um_fontspec_select_font: } {
+ \cs_set_eq:NN \lltjp_um_orig_fsize: \f@size
+ \lltjp_um_unmag_fsize:
+ \cs_set_eq:NN \f@size \lltjp_um_f@size:
+ \cs_set_eq:NN \tf@size \lltjp_um_f@size:
+ \cs_set_eq:NN \sf@size \lltjp_um_sf@size:
+ \cs_set_eq:NN \ssf@size \lltjp_um_ssf@size:
+ } {} {}
+ \apptocmd { \__um_fontspec_select_font: } {
+ \cs_set_eq:NN \f@size \lltjp_um_orig_fsize:
+ } {} {}
+\fi
+
+\ExplSyntaxOff
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-xunicode.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-xunicode.sty
new file mode 100644
index 0000000000..3d6e49fbaa
--- /dev/null
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-xunicode.sty
@@ -0,0 +1,99 @@
+%
+% lltjp-xunicode.sty
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lltjp-xunicode}[2017/05/05 Patch to xunicode for LuaTeX-ja]
+
+\def\XeTeXpicfile{}
+\RequirePackage{xunicode}
+{\catcode`\"=12
+\gdef\check@hexcom@digits@#1#2#3#4#5@!@#6#7#8{%
+ \ifx @#4\relax
+ \UTFacc@warning@{insufficient hex digits #7 for #6-\string#8}%
+ \else
+ \ifcat \active\noexpand#8%
+ \ifx\add@flag\@ne %
+ \expandafter\def\csname\UTFencname\string#8\endcsname{\ltjalchar"#1#2#3#4\relax}%
+ \ifx\unDeFiNed@#8%
+ \ifx\cf@encoding\UTFencname
+ \DeclareTextCommand{#8}{OT1}{\undefined}%
+ \else
+ \DeclareTextCommand{#8}{\cf@encoding}{\undefined}%
+ \fi
+ \else {% macro #8 exists already ...
+ \let\protect\noexpand
+ \edef\UTF@testi{#8}\def\UTF@testii{#8}%
+ \ifx\UTF@testi\UTF@testii\aftergroup\UTF@ignore
+ \else\aftergroup\UTF@doit\fi
+ }%
+ \iffalse
+ % ... but when it isn't robust, make it so
+ \expandafter\let\csname?-\string#8\endcsname#8\relax
+ \edef\next@UTF@{{\cf@encoding}%
+ {\expandafter\noexpand\csname?-\string#8\endcsname}}%
+ \expandafter\DeclareTextCommand\expandafter
+ {\expandafter#8\expandafter}\next@UTF@
+ \fi
+ \fi %
+ \else % \add@flag \z@
+ \expandafter\global\expandafter
+ \let\csname\UTFencname\string#8\endcsname\relax
+ \fi % end of \add@flag switch
+ \else % not active catcode --- shouldn't happen
+ % \typeout{*** did you really mean #8 ? ***}%
+ \ifx\add@flag\@ne %
+ \edef\tmp@name{\expandafter\string\csname\UTFencname\endcsname
+ \expandafter\string\csname#8\endcsname}%
+ \expandafter\def\csname\tmp@name\endcsname{\ltjalchar"#1#2#3#4\relax}%
+ \ifx\cf@encoding\UTFencname
+ \expandafter\DeclareTextCommand\expandafter
+ {\csname#8\endcsname}{OT1}{\undefined}%
+ \else
+ \expandafter\DeclareTextCommand\expandafter
+ {\csname#8\endcsname}{\cf@encoding}{\undefined}%
+ \fi
+ \else % \add@flag \z@
+ \expandafter\global\expandafter\let\csname#8\endcsname\relax
+ \fi % end of \add@flag switch
+ \fi % end of \ifcat
+ \fi}
+\gdef\check@hex@digits@#1#2#3#4#5@!@#6#7#8#9{%
+ \ifx @#4\relax
+ \UTFacc@warning@{insufficient hex digits #7 for #6-\string#8#9}%
+ \else
+ \def\UTFchar{\ltjalchar"#1#2#3#4\relax}%
+ \expandafter\expandafter\expandafter\declare@utf@composite
+ \expandafter\expandafter\expandafter
+ {\expandafter\csname#6\endcsname}{\UTFchar}{#8}{#9}\relax
+ \fi}
+\gdef\add@UTF@accent#1#2#3{\ifx\relax#2\relax\ltjalchar"#3\else
+ \ifx\ #2\relax\ltjalchar"#3\else
+ \expandafter\ifx\UTF@space#2\relax\ltjalchar"#3\else
+ \ifx~#2\ltjalchar"#3\else#2\ltjalchar"#1\fi\fi\fi\fi\relax}
+\gdef\add@UTF@accents#1#2#3{#2\ltjalchar"#1\ltjalchar"#3\relax}
+}
+% If unicode-math is already loaded, the following error occurs:
+% ! Undefined control sequence.
+% \hbar ->\hslash
+% Therefore temporarily set \hbar=\relax.
+\let\ltj@tmpa\hbar
+\let\hbar\relax
+
+\let\ltj@tmpb\iftipaonetoken
+\let\iftipaonetoken\relax
+%\typeout{UTFencname: \UTFencname}
+\let\ltj@temp=\@temp
+\edef\@temp{\noexpand\ReloadXunicode{\UTFencname}}\@temp
+\makeatletter
+\let\@temp=\ltj@temp\let\ltj@temp\relax
+\let\hbar\ltj@tmpa
+\let\iftipaonetoken\ltj@tmpb
+\let\ltj@tmpb\relax % no more an if-token
+
+%% ticket 30501
+{\catcode`\!0\catcode`\\11!catcode`!2 11!catcode`!?11!catcode`!-11
+ !expandafter!gdef!csname!UTFencname \nobreakspace!endcsname{!?-\nobreakspace}%
+}
+
+\endinput
diff --git a/macros/luatex/generic/luatexja/tool/blocks2defcharrange.rb b/macros/luatex/generic/luatexja/tool/blocks2defcharrange.rb
new file mode 100644
index 0000000000..186d0ba94d
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/blocks2defcharrange.rb
@@ -0,0 +1,25 @@
+#! /usr/bin/ruby
+
+# The following script converts Blocks.txt
+# (http://unicode.org/Public/UNIDATA/Blocks.txt)
+# to the character range definitions of LuaTeX-ja.
+
+# USAGE: ruby blocks2defcharrange.rb > unicodeBlocks.tex
+
+count = 1
+open("Blocks.txt", "r").each_line {|line|
+ if line =~ /#/
+ line = $`
+ end
+ if line =~ /^\s*$/
+ next
+ end
+ if line =~ /([0-9a-f]+)\.\.([0-9a-f]+); (.*)/i
+ bcharcode = $1
+ echarcode = $2
+ blockname = $3
+ print "\\defcharrange{", count
+ print "}{\"", bcharcode, "-\"", echarcode, "} % ", blockname, "\n"
+ count += 1
+ end
+}
diff --git a/macros/luatex/generic/luatexja/tool/chars2defcharrange.rb b/macros/luatex/generic/luatexja/tool/chars2defcharrange.rb
new file mode 100644
index 0000000000..21f6e7728c
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/chars2defcharrange.rb
@@ -0,0 +1,51 @@
+#! /usr/bin/ruby
+# -*- coding: utf-8 -*-
+
+# The following script converts a set of chars except "\s", as Ruby defines,
+# to the character range definition of LuaTeX-ja.
+
+# USAGE: ruby __FILE__ ifile rangeNo [> ofile]
+
+# Example (in Japanese)
+# 教育漢字リスト (http://www.aozora.gr.jp/kanji_table/kyouiku_list.zip)
+# ã«å¯¾ã—ã¦é©ç”¨ã—ãŸã„ã¨ã.
+# 1. kyoikukanji.txt ã«å¯¾ã—ã¦ï¼Œã‚³ãƒ¡ãƒ³ãƒˆéƒ¨åˆ†ã®å…ˆé ­ã« # ã‚’ã¤ã‘る編集を加ãˆã‚‹;
+# 2. ruby chars2defcharrange.rb kyoikukanji.txt 210 > kyoikukanjiChars.tex
+# を実行ã™ã‚‹ï¼Ž
+
+def print_usage()
+ print "USAGE: ruby ", __FILE__, "ifile rangeNo [> ofile]\n"
+end
+
+if __FILE__ == $0
+ # コマンドライン引数ã®å‡¦ç†
+ if ARGV.length < 2
+ print_usage()
+ exit
+ end
+ ifile = ARGV[0]
+ rangeNo = ARGV[1]
+
+ # 対象文字列ã®ä½œæˆ
+ string = ""
+ open(ifile, "r").each_line{|line|
+ if line =~ /#/
+ line = $`
+ end
+ line.gsub!(/\s/){}
+ string += line
+ }
+
+ # 10 進 unicode code point é…列ã«å¤‰æ›
+ decs = string.unpack("U*")
+
+ # print
+ print "\defcharrange{", rangeNo, "}{"
+ decs.each_with_index{|code, index|
+ if index != 0
+ print ","
+ end
+ print "\"", code.to_s(16)
+ }
+ print "}\n"
+end
diff --git a/macros/luatex/generic/luatexja/tool/function_uax50.lua b/macros/luatex/generic/luatexja/tool/function_uax50.lua
new file mode 100644
index 0000000000..d345284535
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/function_uax50.lua
@@ -0,0 +1,50 @@
+kpse.set_program_name('luatex')
+dofile(kpse.find_file('lualibs.lua'))
+
+local function toX(a) return string.format('0x%X',a) end
+
+local uax_revision = '12.1.0'
+print(' -- UAX#50 for Unicode ' .. uax_revision)
+local fh = io.open('VerticalOrientation-' .. uax_revision .. '.txt')
+local t = {}
+
+for c in fh:lines() do
+ if c:match('(%x+)%.%.(%x+)%s+;%sT-[rR]') then
+ local b, e = c:match('(%x+)%.%.(%x+)%s+;')
+ b, e = tonumber(b,16), tonumber(e,16)
+ for i=b,e do t[i]=true end
+ elseif c:match('(%x+)%s+;%sT-[rR]') then
+ local b = c:match('(%x+)%s+;')
+ t[tonumber(b,16)]=true
+ end
+end
+
+fh:close()
+local t2={}
+local b, v = 0, t[0]
+for i=0,0x10ffff do
+ if t[i]~=v then
+ table.insert(t2,b); b, v=i, t[i]
+ end
+end
+table.insert(t2,b)
+
+print(' -- t[0] = ' .. tostring(t[0]))
+print(table.serialize(t2,' local t'))
+
+--[[
+for i,v in ipairs(t2) do
+ print(i, toX(v[1]) .. ' ≦x< ' .. toX(v[2]), v[3])
+end
+]]
+
+print([[ local function rotate_in_uax50(i)
+ local lo, hi = 1, #t
+ while lo < hi do
+ local mi = math.ceil((lo+hi)/2)
+ if t[mi]<=i then lo=mi else hi=mi-1 end
+ end
+ return lo%2==1
+ end
+]])
+
diff --git a/macros/luatex/generic/luatexja/tool/ivslist.tex b/macros/luatex/generic/luatexja/tool/ivslist.tex
new file mode 100644
index 0000000000..0e0a712461
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/ivslist.tex
@@ -0,0 +1,58 @@
+%#!lualatex
+\documentclass{article}
+\batchmode
+\usepackage{luaotfload,booktabs,array,luacode,longtable}
+\usepackage[scale=0.8]{geometry}
+\errorstopmode
+
+\ifdefined\myfontname\else
+{\newlinechar=`@
+\message{@Name of the font to test = }
+\read-1 to\myfontname \global\let\myfontname\myfontname
+\message{@}}
+\fi
+\font\test=\myfontname\space at 12pt
+{\test\begin{luacode}
+ ident = fonts.hashes.identifiers[font.current()]
+\end{luacode}
+}
+
+
+\def\FMT#1#2{{\oalign{\test\char#1\crcr\rm\tiny\hss#2\hss\crcr}}}
+\def\OUT#1{\leavevmode\hbox to 7em{{\test\char"#1}\ ({\tt U+#1})\hss}}%"
+\begin{document}
+{\noindent\Large\bf \myfontname\\\null\hfill (%
+ \directlua{tex.sprint(ident.fullname)}%
+)}
+
+\bigskip
+\baselineskip18pt
+
+\begin{luacode}
+local t = ident.shared.rawdata
+t = t and t.resources
+t = t and t.variants
+local ivs, ivsi = {}, {}
+for i,v in pairs(t) do
+ if i>=0xE0100 then
+ for j,w in pairs(v) do
+ if not ivs[j] then table.insert(ivsi,j); ivs[j]=ivs[j] or {}; end
+ table.insert(ivs[j],{i-0xE0100,w})
+ end
+ end
+end
+local sort = table.sort
+local sortfn = function (a,b) return a[1]<b[1] end
+sort(ivsi)
+for _,v in pairs(ivsi) do
+ sort(ivs[v], sortfn)
+ tex.sprint('\\OUT{' .. string.format('%X', v) .. '}\\ ')
+ for _, cn in pairs(ivs[v]) do
+ tex.sprint('\\FMT{' .. tostring(cn[2]) .. '}{' .. cn[1] .. '}' )
+ end
+ tex.sprint('\\par')
+end
+\end{luacode}
+
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/generic/luatexja/tool/jfm-convert.lua b/macros/luatex/generic/luatexja/tool/jfm-convert.lua
new file mode 100755
index 0000000000..66b73a02cd
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/jfm-convert.lua
@@ -0,0 +1,281 @@
+#!/usr/bin/env texlua
+
+local stderr = io.stderr
+local function show_usage(s)
+ stderr:write('Error: ' .. s .. '\n');
+ stderr:write('Usage: jfm-convert [-J|-U] <ptex_jfm>\n');
+ stderr:write('-J: JIS mode, -U: UCS mode \n');
+ stderr:write(' * The output will be written to stdout.\n');
+ stderr:write(' * I do not read virtual fonts which corresponded to <ptex_jfm>.\n');
+ stderr:write(" You will need to adjust 'align', 'left', 'down' entries by hand.\n");
+ stderr:write(" * In JIS mode, characters which are not included in JIS X 0208\n");
+ stderr:write(" (e.g., 0x2257) are written as 0x202577.\n");
+ os.exit(1)
+end
+
+require('unicode'); local uchar = unicode.utf8.char
+kpse.set_program_name('luatex')
+jisx0208 = require('ltj-jisx0208.lua').table_jisx0208_uptex
+local function pass_ucs(s)
+ return "'" .. uchar(s) .. "'"
+end
+local function jis_to_ucs(s)
+ local a = jisx0208[s-0x2020]
+ return a and pass_ucs(a) or string.format('0x%X',s+0x200000)
+end
+
+-------- 引数解釈 --------
+
+require('unicode')
+local filename
+local mode
+
+for i=1,#arg do
+ if arg[i]=='-u' or arg[i]=='-U' then
+ mode = pass_ucs
+ elseif arg[i]=='-j' or arg[i]=='-J' then
+ mode = jis_to_ucs
+ elseif filename then
+ show_usage('Multiple JFM files.')
+ else
+ filename = arg[i]
+ end
+end
+
+if not filename then show_usage('Missing JFM file argument.') end
+kpse.set_program_name('ptex')
+local nf = kpse.find_file(filename, 'tfm')
+if not nf then show_usage("JFM file can't be opened: " .. filename) end
+
+-------- OPEN --------
+
+local jfm_ptex = io.open(nf, 'rb')
+local function get_word()
+ local d = table.pack(string.byte(jfm_ptex:read(4),1,4))
+ return d[1]*16777216+d[2]*65536+d[3]*256+d[4]
+end
+local function get_signed_word()
+ local d = get_word()
+ return (d>=2147483648) and -(4294967296-d) or d
+end
+local extract = bit32.extract
+local function get_two()
+ local d = get_word()
+ return extract(d,16,16), extract(d,0,16)
+end
+local function get_four()
+ local d = get_word()
+ return extract(d,24,8), extract(d,16,8), extract(d,8,8), extract(d,0,8)
+end
+
+local id, nt = get_two()
+local lf, lh = get_two()
+local bc, ec = get_two()
+local nw, nh = get_two()
+local nd, ni = get_two()
+local nl, nk = get_two()
+local ng, np = get_two()
+
+if bc~=0 or
+ lf~= 7 + lh + nt + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ng + np or
+ (id~=11 and id~=9) then
+ stderr:write('Bad JFM "' .. filename .. '".\n'); jfm_ptex:close(); os.exit(1)
+end
+
+local result = {}
+result.dir = (id==11) and 'yoko' or 'tate'
+
+-------- HEADER --------
+
+_ = get_word() -- checksum, unused
+local designsize = get_word()/1048576 -- ignored
+
+local encoding
+if lh>=3 then
+ encoding = ''
+ for i=1,math.min(10,lh-2) do encoding = encoding .. jfm_ptex:read(4) end
+ encoding = encoding:sub(2, 1+string.byte(encoding))
+end
+if not encoding then encoding = 'UNSPECIFIED' end
+
+local family = ''
+if lh>=13 then
+ for i=1,math.min(5,lh-12) do family = family .. jfm_ptex:read(4) end
+ family = family:sub(2, 1+string.byte(family))
+end
+
+local face = 0
+if lh>=18 then
+ _, _, _, face = get_four()
+ for i=1,lh-19 do jfm_ptex:read(4) end -- ignored
+end
+
+-------- CHAR_TYPE --------
+result[0] = {}
+local all_ctype = {}
+for i=1,nt do
+ local ccode, ctype = get_two()
+ if ccode~=0 then
+ all_ctype[#all_ctype+1] = ccode
+ end
+ if ctype~=0 then
+ if not result[ctype] then result[ctype] = {} end
+ if not result[ctype].chars then result[ctype].chars = {} end
+ local t = result[ctype].chars
+ t[#t+1] = ccode
+ end
+end
+
+-------- CHAR_INFO --------
+for i=0,ec do
+ if not result[i] then result[i] = {} end
+ local t, info = result[i], get_word()
+ t.align, t.left, t.down = 'left', 0, 0
+ t.width = extract(info, 24, 8)
+ t.height = extract(info, 20, 4)
+ t.depth = extract(info, 16, 4)
+ t.italic = extract(info, 10, 6)
+ t.tag = extract(info, 8, 2)
+ t.rem = extract(info, 0, 8)
+end
+
+local wi, hi, di, ii = {}, {}, {}, {}
+for i=0,nw-1 do wi[i] = get_signed_word() end
+for i=0,nh-1 do hi[i] = get_signed_word() end
+for i=0,nd-1 do di[i] = get_signed_word() end
+for i=0,ni-1 do ii[i] = get_signed_word() end
+
+
+-------- GLUE/KERN --------
+
+local gk_table = {}
+for i=0,nl-1 do gk_table[i] = table.pack(get_four()) end
+
+local kerns = {}
+for i=0,nk-1 do kerns[i] = get_signed_word() end
+
+local glues = {}
+for i=0,ng/3-1 do glues[i] = { get_signed_word(), get_signed_word(), get_signed_word() } end
+
+
+-------- PARAM --------
+local param = {}
+for i=1,math.min(9, np) do param[i] = get_word() end
+local zw = param[6]
+result.kanjiskip = {
+ param[2]/zw, param[3]/zw, param[4]/zw
+}
+result.xkanjiskip = {
+ param[7]/zw, param[8]/zw, param[9]/zw
+}
+result.zw, result.zh = 1.0, param[5]/zw
+
+
+
+-------- å„種 index ã®è§£æ±º --------
+for i=0,ec do
+ local t = result[i]
+ t.width = wi[t.width]/zw
+ t.height = hi[t.height]/zw
+ t.depth = di[t.depth]/zw
+ t.italic = ii[t.italic]/zw
+ if t.tag==1 then
+ local j = t.rem
+ while j do
+ local gkp = gk_table[j]
+ j = (gkp[1]<128) and j+gkp[1]+1 or nil
+ if gkp[3]<128 then
+ if not t.glue then t.glue = {} end
+ t.glue[gkp[2]] = {
+ glues[gkp[4]][1]/zw,
+ glues[gkp[4]][2]/zw,
+ glues[gkp[4]][3]/zw,
+ }
+ else
+ if not t.kern then t.kern = {} end
+ t.kern[gkp[2]] = kerns[gkp[4]]/zw
+ end
+ end
+ end
+ t.tag, t.rem = nil, nil
+end
+
+jfm_ptex:close()
+
+
+-------- モード判定 --------
+if not mode then
+ mode = jis_to_ucs
+ for i=1, #all_ctype do
+ if not jisx0208[all_ctype[i]-0x2020] then
+ mode = pass_ucs; break
+ end
+ end
+end
+
+-------- 出力 --------
+local function S(a)
+ if type(a)=='number' then
+ return tostring(math.floor(a*1000000+0.5)/1000000)
+ elseif type(a)=='table' then -- glue
+ return '{ ' .. S(a[1]) .. ', ' .. S(a[2]) .. ', ' .. S(a[3]) .. '},'
+ elseif type(a)=='string' then
+ return "'" .. a .. "'"
+ else
+ tostring(a)
+ end
+end
+
+print('-- -*- coding: utf-8 -*-')
+print('-- converted from ' .. filename .. ' by jfm_convert.lua')
+print('-- assumed encoding: ' .. (mode==jis_to_ucs and 'JIS' or 'UCS') .. '\n')
+print('luatexja.jfont.define_jfm {')
+print(' -- original design size = ' .. S(designsize))
+print(' -- original encoding = (' .. encoding .. ')')
+print(' -- original family = (' .. family .. ')')
+print(" dir = " .. S(result.dir) .. ",")
+print(' zw = ' .. S(result.zw) .. ', zh = ' .. S(result.zh) .. ', ')
+print(' kanjiskip = ' .. S(result.kanjiskip))
+print(' xkanjiskip = ' .. S(result.xkanjiskip))
+for i=0, ec do
+ local t = result[i]
+ print(' [' .. tostring(i) .. '] = {')
+ if t.chars then
+ print(' chars = {')
+ local d = ' '
+ for j=1,#(t.chars) do
+ d = d .. mode(t.chars[j]) .. ', '
+ if j%8==0 and j<#(t.chars) then
+ d = d .. '\n '
+ end
+ end
+ print(d)
+ print(' },')
+ end
+ print(' align = ' .. S(t.align) .. ', left = ' .. S(0.0)
+ .. ', down = ' .. S(0.0) .. ', ')
+ print(' width = ' .. S(t.width) .. ', height = ' .. S(t.height)
+ .. ', depth = ' .. S(t.depth) .. ', italic = ' .. S(t.italic) .. ',')
+ if t.glue then
+ print(' glue = {')
+ local gi = {}
+ for m,_ in pairs(t.glue) do gi[#gi+1]=m end
+ table.sort(gi)
+ for _,m in ipairs(gi) do
+ print(' [' .. tostring(m) .. '] = ' .. S(t.glue[m]))
+ end
+ print(' },')
+ end
+ if t.kern then
+ print(' kern = {')
+ local gi = {}
+ for m,_ in pairs(t.kern) do gi[#gi+1]=m end
+ table.sort(gi)
+ for _,m in ipairs(gi) do
+ print(' [' .. tostring(m) .. '] = ' .. S(t.kern[m]) .. ',')
+ end
+ print(' },')
+ end
+ print(' },')
+end
+print('}')
diff --git a/macros/luatex/generic/luatexja/tool/jfm-readable.rb b/macros/luatex/generic/luatexja/tool/jfm-readable.rb
new file mode 100644
index 0000000000..d60ad2efa5
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/jfm-readable.rb
@@ -0,0 +1,25 @@
+#! /usr/bin/ruby
+# -*- coding: utf-8 -*-
+
+# The following script converts Unicode codepoints as 0x???? to real characters.
+
+# USAGE: ruby __FILE__ ifile [> ofile]
+
+def print_usage()
+ print "USAGE: ruby ", __FILE__, "ifile [> ofile]\n"
+end
+
+if __FILE__ == $0
+ # コマンドライン引数ã®å‡¦ç†
+ if ARGV.length < 1
+ print_usage()
+ exit
+ end
+ ifile = ARGV[0]
+
+ print "-- -*- coding: utf-8 -*-\n"
+ open(ifile, "r").each_line{|line|
+ line.gsub!(/0x[0-9a-fA-F]*/){|s| s.to_s + "(" + [s.to_i(0)].pack("U*") + ")"}
+ print line
+ }
+end
diff --git a/macros/luatex/generic/luatexja/tool/kyoikukanji.txt b/macros/luatex/generic/luatexja/tool/kyoikukanji.txt
new file mode 100644
index 0000000000..76c48a6fd7
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/kyoikukanji.txt
@@ -0,0 +1,19 @@
+#教育漢字・学年別漢字é…当表
+
+#★第一学年★(80字)
+一 å³ é›¨ 円 王 音 下 ç« èŠ± è² å­¦ æ°— ä¹ ä¼‘ 玉 金 空 月 犬 見 五 å£ æ ¡ å·¦ 三 å±± å­ å›› 糸 å­— 耳 七 車 手 å 出 女 å° ä¸Š 森 人 æ°´ æ­£ 生 é’ å¤• 石 赤 åƒ å· å…ˆ æ—© è‰ è¶³ æ‘ å¤§ ç”· 竹 中 虫 町 天 ç”° 土 二 æ—¥ å…¥ å¹´ 白 å…« 百 æ–‡ 木 本 å ç›® ç«‹ 力 æž— å…­
+
+#★第二学年★(160字)
+引 ç¾½ 雲 園 é  ä½• 科 å¤ å®¶ æ­Œ ç”» 回 会 æµ· çµµ 外 角 楽 æ´» é–“ 丸 岩 é¡” æ±½ 記 帰 弓 牛 é­š 京 å¼· æ•™ è¿‘ å…„ å½¢ 計 å…ƒ 言 原 戸 å¤ åˆ å¾Œ 語 å·¥ å…¬ 広 交 å…‰ 考 è¡Œ 高 黄 åˆ è°· 国 é»’ 今 æ‰ ç´° 作 ç®— æ­¢ 市 矢 姉 æ€ ç´™ 寺 自 時 室 社 å¼± 首 秋 週 春 書 å°‘ å ´ 色 食 心 æ–° 親 図 æ•° 西 声 星 æ™´ 切 雪 船 ç·š å‰ çµ„ èµ° 多 太 体 å° åœ° æ±  知 茶 昼 é•· é³¥ æœ ç›´ 通 弟 店 点 é›» 刀 冬 当 æ± ç­” é ­ åŒ é“ èª­ 内 å— è‚‰ 馬 売 è²· 麦 åŠ ç•ª 父 風 分 èž ç±³ æ­© æ¯ æ–¹ 北 毎 妹 万 明 é³´ 毛 é–€ 夜 野 å‹ ç”¨ 曜 æ¥ é‡Œ ç† è©±
+
+#★第三学年★(200字)
+悪 安 æš— 医 委 æ„ è‚² å“¡ 院 飲 é‹ æ³³ 駅 央 横 屋 温 化 è· ç•Œ é–‹ 階 寒 æ„Ÿ æ¼¢ 館 岸 èµ· 期 客 究 急 ç´š å®® çƒ åŽ» æ©‹ 業 曲 å±€ 銀 区 苦 å…· å› ä¿‚ 軽 è¡€ 決 ç ” 県 庫 æ¹– å‘ å¹¸ 港 å· æ ¹ 祭 çš¿ 仕 æ­» 使 始 指 æ­¯ è©© 次 事 æŒ å¼ å®Ÿ 写 者 主 守 å– é…’ å— å·ž 拾 終 ç¿’ 集 ä½ é‡ å®¿ 所 æš‘ 助 昭 消 商 ç«  å‹ ä¹— æ¤ ç”³ 身 神 真 æ·± 進 世 æ•´ 昔 å…¨ 相 é€ æƒ³ æ¯ é€Ÿ æ— ä»– 打 対 å¾… 代 第 é¡Œ ç‚­ 短 談 ç€ æ³¨ 柱 ä¸ å¸³ 調 追 定 庭 笛 鉄 転 都 度 投 豆 島 湯 ç™» ç­‰ å‹• ç«¥ è¾² æ³¢ é… å€ ç®± ç•‘ 発 å å‚ æ¿ çš® 悲 美 é¼» ç­† æ°· 表 秒 ç—… å“ è²  部 æœ ç¦ ç‰© å¹³ è¿” 勉 放 味 命 é¢ å• å½¹ è–¬ ç”± æ²¹ 有 éŠ äºˆ 羊 æ´‹ 葉 陽 様 è½ æµ æ—… 両 ç·‘ 礼 列 ç·´ è·¯ å’Œ
+
+#★第四学年★(200字)
+æ„› 案 以 è¡£ ä½ å›² 胃 å° è‹± æ „ å¡© å„„ 加 æžœ 貨 課 芽 改 械 害 è¡— å„ è¦š 完 官 管 é–¢ 観 願 希 å­£ ç´€ å–œ æ—— 器 æ©Ÿ è­° 求 æ³£ æ•‘ 給 挙 æ¼ å…± å” é¡ ç«¶ 極 訓 è» éƒ¡ 径 åž‹ 景 芸 欠 çµ å»º å¥ é¨“ 固 功 好 候 航 康 å‘Š å·® èœ æœ€ æ 昨 札 刷 殺 察 å‚ ç”£ æ•£ 残 士 æ° å² å¸ è©¦ å… æ²» 辞 失 借 種 周 ç¥ é † åˆ æ¾ ç¬‘ å”± 焼 象 ç…§ 賞 臣 ä¿¡ æˆ çœ æ¸… é™ å¸­ ç© æŠ˜ 節 説 æµ… 戦 é¸ ç„¶ 争 倉 å·£ æŸ å´ ç¶š å’ å­« 帯 隊 é” å˜ ç½® 仲 貯 å…† è…¸ 低 底 åœ çš„ å…¸ ä¼ å¾’ 努 ç¯ å ‚ åƒ ç‰¹ å¾— 毒 熱 念 æ•— 梅 åš é£¯ 飛 è²» å¿… 票 標 ä¸ å¤« 付 府 副 粉 å…µ 別 辺 変 便 包 法 望 牧 末 満 未 脈 æ°‘ ç„¡ ç´„ 勇 è¦ é¤Š æµ´ 利 陸 良 æ–™ é‡ è¼ª é¡ž 令 冷 例 æ­´ 連 è€ åŠ´ 録
+
+#★第五学年★(185字)
+圧 移 å›  æ°¸ å–¶ è¡› 易 益 液 æ¼” å¿œ å¾€ æ¡œ æ© å¯ ä»® 価 æ²³ éŽ è³€ å¿« 解 æ ¼ 確 é¡ åˆŠ å¹¹ æ…£ 眼 基 寄 è¦ æŠ€ 義 逆 ä¹… æ—§ å±… 許 境 å‡ ç¦ å¥ ç¾¤ 経 æ½” 件 券 険 検 é™ ç¾ æ¸› æ•… 個 è­· 効 厚 耕 鉱 構 興 講 æ·· 査 å† ç½ å¦» 採 éš› 在 財 罪 雑 é…¸ è³› 支 å¿— æž å¸« 資 飼 示 ä¼¼ è­˜ 質 舎 è¬ æŽˆ ä¿® è¿° è¡“ 準 åº æ‹› 承 証 æ¡ çŠ¶ 常 情 ç¹” è· åˆ¶ 性 政 å‹¢ ç²¾ 製 税 責 績 接 設 舌 絶 銭 祖 ç´  ç· é€  åƒ å¢— 則 測 属 率 æ 退 貸 æ…‹ 団 æ–­ 築 å¼µ æ 程 é© æ•µ çµ± 銅 å°Ž å¾³ 独 ä»» 燃 能 ç ´ 犯 判 版 比 è‚¥ éž å‚™ 俵 è©• 貧 布 婦 富 æ­¦ 復 複 ä» ç·¨ å¼ ä¿ å¢“ å ± 豊 防 貿 æš´ å‹™ 夢 è¿· 綿 輸 ä½™ é  å®¹ ç•¥ ç•™ é ˜
+
+#★第六学年★(181字)
+ç•° éº åŸŸ 宇 映 延 沿 我 ç° æ‹¡ é© é–£ 割 æ ª å¹² å·» 看 ç°¡ å± æœº æ® è²´ ç–‘ å¸ ä¾› 胸 郷 勤 ç­‹ ç³» 敬 è­¦ 劇 æ¿€ ç©´ çµ¹ 権 憲 æº åŽ³ å·± 呼 誤 åŽ å­ çš‡ ç´… é™ é‹¼ 刻 ç©€ 骨 å›° ç ‚ 座 済 è£ ç­– 冊 èš• 至 ç§ å§¿ 視 è©ž 誌 ç£ å°„ æ¨ å°º è‹¥ 樹 åŽ å®— å°± 衆 従 縦 縮 熟 ç´” 処 ç½² 諸 除 å°† å‚· éšœ 城 è’¸ é‡ ä» åž‚ 推 寸 ç›› è– èª  宣 å°‚ 泉 æ´— 染 å–„ å¥ çª“ 創 装 層 æ“ è”µ 臓 å­˜ å°Š å®… æ‹… 探 誕 段 æš– 値 å®™ å¿  è‘— åº é ‚ æ½® 賃 ç—› 展 討 å…š ç³– 届 難 ä¹³ èª ç´ è„³ æ´¾ æ‹ èƒŒ 肺 俳 ç­ æ™© å¦ æ‰¹ 秘 è…¹ 奮 並 é™› é–‰ 片 補 æš® å® è¨ª 亡 忘 棒 æžš 幕 密 盟 模 訳 郵 優 å¹¼ 欲 ç¿Œ ä¹± åµ è¦§ è£ å¾‹ 臨 朗 è«–
diff --git a/macros/luatex/generic/luatexja/tool/kyoikukanjiChars.tex b/macros/luatex/generic/luatexja/tool/kyoikukanjiChars.tex
new file mode 100644
index 0000000000..623d4fb8e7
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/kyoikukanjiChars.tex
@@ -0,0 +1 @@
+\ltjdefcharrange{210}{"4E00,"53F3,"96E8,"5186,"738B,"97F3,"4E0B,"706B,"82B1,"8C9D,"5B66,"6C17,"4E5D,"4F11,"7389,"91D1,"7A7A,"6708,"72AC,"898B,"4E94,"53E3,"6821,"5DE6,"4E09,"5C71,"5B50,"56DB,"7CF8,"5B57,"8033,"4E03,"8ECA,"624B,"5341,"51FA,"5973,"5C0F,"4E0A,"68EE,"4EBA,"6C34,"6B63,"751F,"9752,"5915,"77F3,"8D64,"5343,"5DDD,"5148,"65E9,"8349,"8DB3,"6751,"5927,"7537,"7AF9,"4E2D,"866B,"753A,"5929,"7530,"571F,"4E8C,"65E5,"5165,"5E74,"767D,"516B,"767E,"6587,"6728,"672C,"540D,"76EE,"7ACB,"529B,"6797,"516D,"5F15,"7FBD,"96F2,"5712,"9060,"4F55,"79D1,"590F,"5BB6,"6B4C,"753B,"56DE,"4F1A,"6D77,"7D75,"5916,"89D2,"697D,"6D3B,"9593,"4E38,"5CA9,"9854,"6C7D,"8A18,"5E30,"5F13,"725B,"9B5A,"4EAC,"5F37,"6559,"8FD1,"5144,"5F62,"8A08,"5143,"8A00,"539F,"6238,"53E4,"5348,"5F8C,"8A9E,"5DE5,"516C,"5E83,"4EA4,"5149,"8003,"884C,"9AD8,"9EC4,"5408,"8C37,"56FD,"9ED2,"4ECA,"624D,"7D30,"4F5C,"7B97,"6B62,"5E02,"77E2,"59C9,"601D,"7D19,"5BFA,"81EA,"6642,"5BA4,"793E,"5F31,"9996,"79CB,"9031,"6625,"66F8,"5C11,"5834,"8272,"98DF,"5FC3,"65B0,"89AA,"56F3,"6570,"897F,"58F0,"661F,"6674,"5207,"96EA,"8239,"7DDA,"524D,"7D44,"8D70,"591A,"592A,"4F53,"53F0,"5730,"6C60,"77E5,"8336,"663C,"9577,"9CE5,"671D,"76F4,"901A,"5F1F,"5E97,"70B9,"96FB,"5200,"51AC,"5F53,"6771,"7B54,"982D,"540C,"9053,"8AAD,"5185,"5357,"8089,"99AC,"58F2,"8CB7,"9EA6,"534A,"756A,"7236,"98A8,"5206,"805E,"7C73,"6B69,"6BCD,"65B9,"5317,"6BCE,"59B9,"4E07,"660E,"9CF4,"6BDB,"9580,"591C,"91CE,"53CB,"7528,"66DC,"6765,"91CC,"7406,"8A71,"60AA,"5B89,"6697,"533B,"59D4,"610F,"80B2,"54E1,"9662,"98F2,"904B,"6CF3,"99C5,"592E,"6A2A,"5C4B,"6E29,"5316,"8377,"754C,"958B,"968E,"5BD2,"611F,"6F22,"9928,"5CB8,"8D77,"671F,"5BA2,"7A76,"6025,"7D1A,"5BAE,"7403,"53BB,"6A4B,"696D,"66F2,"5C40,"9280,"533A,"82E6,"5177,"541B,"4FC2,"8EFD,"8840,"6C7A,"7814,"770C,"5EAB,"6E56,"5411,"5E78,"6E2F,"53F7,"6839,"796D,"76BF,"4ED5,"6B7B,"4F7F,"59CB,"6307,"6B6F,"8A69,"6B21,"4E8B,"6301,"5F0F,"5B9F,"5199,"8005,"4E3B,"5B88,"53D6,"9152,"53D7,"5DDE,"62FE,"7D42,"7FD2,"96C6,"4F4F,"91CD,"5BBF,"6240,"6691,"52A9,"662D,"6D88,"5546,"7AE0,"52DD,"4E57,"690D,"7533,"8EAB,"795E,"771F,"6DF1,"9032,"4E16,"6574,"6614,"5168,"76F8,"9001,"60F3,"606F,"901F,"65CF,"4ED6,"6253,"5BFE,"5F85,"4EE3,"7B2C,"984C,"70AD,"77ED,"8AC7,"7740,"6CE8,"67F1,"4E01,"5E33,"8ABF,"8FFD,"5B9A,"5EAD,"7B1B,"9244,"8EE2,"90FD,"5EA6,"6295,"8C46,"5CF6,"6E6F,"767B,"7B49,"52D5,"7AE5,"8FB2,"6CE2,"914D,"500D,"7BB1,"7551,"767A,"53CD,"5742,"677F,"76AE,"60B2,"7F8E,"9F3B,"7B46,"6C37,"8868,"79D2,"75C5,"54C1,"8CA0,"90E8,"670D,"798F,"7269,"5E73,"8FD4,"52C9,"653E,"5473,"547D,"9762,"554F,"5F79,"85AC,"7531,"6CB9,"6709,"904A,"4E88,"7F8A,"6D0B,"8449,"967D,"69D8,"843D,"6D41,"65C5,"4E21,"7DD1,"793C,"5217,"7DF4,"8DEF,"548C,"611B,"6848,"4EE5,"8863,"4F4D,"56F2,"80C3,"5370,"82F1,"6804,"5869,"5104,"52A0,"679C,"8CA8,"8AB2,"82BD,"6539,"68B0,"5BB3,"8857,"5404,"899A,"5B8C,"5B98,"7BA1,"95A2,"89B3,"9858,"5E0C,"5B63,"7D00,"559C,"65D7,"5668,"6A5F,"8B70,"6C42,"6CE3,"6551,"7D66,"6319,"6F01,"5171,"5354,"93E1,"7AF6,"6975,"8A13,"8ECD,"90E1,"5F84,"578B,"666F,"82B8,"6B20,"7D50,"5EFA,"5065,"9A13,"56FA,"529F,"597D,"5019,"822A,"5EB7,"544A,"5DEE,"83DC,"6700,"6750,"6628,"672D,"5237,"6BBA,"5BDF,"53C2,"7523,"6563,"6B8B,"58EB,"6C0F,"53F2,"53F8,"8A66,"5150,"6CBB,"8F9E,"5931,"501F,"7A2E,"5468,"795D,"9806,"521D,"677E,"7B11,"5531,"713C,"8C61,"7167,"8CDE,"81E3,"4FE1,"6210,"7701,"6E05,"9759,"5E2D,"7A4D,"6298,"7BC0,"8AAC,"6D45,"6226,"9078,"7136,"4E89,"5009,"5DE3,"675F,"5074,"7D9A,"5352,"5B6B,"5E2F,"968A,"9054,"5358,"7F6E,"4EF2,"8CAF,"5146,"8178,"4F4E,"5E95,"505C,"7684,"5178,"4F1D,"5F92,"52AA,"706F,"5802,"50CD,"7279,"5F97,"6BD2,"71B1,"5FF5,"6557,"6885,"535A,"98EF,"98DB,"8CBB,"5FC5,"7968,"6A19,"4E0D,"592B,"4ED8,"5E9C,"526F,"7C89,"5175,"5225,"8FBA,"5909,"4FBF,"5305,"6CD5,"671B,"7267,"672B,"6E80,"672A,"8108,"6C11,"7121,"7D04,"52C7,"8981,"990A,"6D74,"5229,"9678,"826F,"6599,"91CF,"8F2A,"985E,"4EE4,"51B7,"4F8B,"6B74,"9023,"8001,"52B4,"9332,"5727,"79FB,"56E0,"6C38,"55B6,"885B,"6613,"76CA,"6DB2,"6F14,"5FDC,"5F80,"685C,"6069,"53EF,"4EEE,"4FA1,"6CB3,"904E,"8CC0,"5FEB,"89E3,"683C,"78BA,"984D,"520A,"5E79,"6163,"773C,"57FA,"5BC4,"898F,"6280,"7FA9,"9006,"4E45,"65E7,"5C45,"8A31,"5883,"5747,"7981,"53E5,"7FA4,"7D4C,"6F54,"4EF6,"5238,"967A,"691C,"9650,"73FE,"6E1B,"6545,"500B,"8B77,"52B9,"539A,"8015,"9271,"69CB,"8208,"8B1B,"6DF7,"67FB,"518D,"707D,"59BB,"63A1,"969B,"5728,"8CA1,"7F6A,"96D1,"9178,"8CDB,"652F,"5FD7,"679D,"5E2B,"8CC7,"98FC,"793A,"4F3C,"8B58,"8CEA,"820E,"8B1D,"6388,"4FEE,"8FF0,"8853,"6E96,"5E8F,"62DB,"627F,"8A3C,"6761,"72B6,"5E38,"60C5,"7E54,"8077,"5236,"6027,"653F,"52E2,"7CBE,"88FD,"7A0E,"8CAC,"7E3E,"63A5,"8A2D,"820C,"7D76,"92AD,"7956,"7D20,"7DCF,"9020,"50CF,"5897,"5247,"6E2C,"5C5E,"7387,"640D,"9000,"8CB8,"614B,"56E3,"65AD,"7BC9,"5F35,"63D0,"7A0B,"9069,"6575,"7D71,"9285,"5C0E,"5FB3,"72EC,"4EFB,"71C3,"80FD,"7834,"72AF,"5224,"7248,"6BD4,"80A5,"975E,"5099,"4FF5,"8A55,"8CA7,"5E03,"5A66,"5BCC,"6B66,"5FA9,"8907,"4ECF,"7DE8,"5F01,"4FDD,"5893,"5831,"8C4A,"9632,"8CBF,"66B4,"52D9,"5922,"8FF7,"7DBF,"8F38,"4F59,"9810,"5BB9,"7565,"7559,"9818,"7570,"907A,"57DF,"5B87,"6620,"5EF6,"6CBF,"6211,"7070,"62E1,"9769,"95A3,"5272,"682A,"5E72,"5DFB,"770B,"7C21,"5371,"673A,"63EE,"8CB4,"7591,"5438,"4F9B,"80F8,"90F7,"52E4,"7B4B,"7CFB,"656C,"8B66,"5287,"6FC0,"7A74,"7D79,"6A29,"61B2,"6E90,"53B3,"5DF1,"547C,"8AA4,"540E,"5B5D,"7687,"7D05,"964D,"92FC,"523B,"7A40,"9AA8,"56F0,"7802,"5EA7,"6E08,"88C1,"7B56,"518A,"8695,"81F3,"79C1,"59FF,"8996,"8A5E,"8A8C,"78C1,"5C04,"6368,"5C3A,"82E5,"6A39,"53CE,"5B97,"5C31,"8846,"5F93,"7E26,"7E2E,"719F,"7D14,"51E6,"7F72,"8AF8,"9664,"5C06,"50B7,"969C,"57CE,"84B8,"91DD,"4EC1,"5782,"63A8,"5BF8,"76DB,"8056,"8AA0,"5BA3,"5C02,"6CC9,"6D17,"67D3,"5584,"594F,"7A93,"5275,"88C5,"5C64,"64CD,"8535,"81D3,"5B58,"5C0A,"5B85,"62C5,"63A2,"8A95,"6BB5,"6696,"5024,"5B99,"5FE0,"8457,"5E81,"9802,"6F6E,"8CC3,"75DB,"5C55,"8A0E,"515A,"7CD6,"5C4A,"96E3,"4E73,"8A8D,"7D0D,"8133,"6D3E,"62DD,"80CC,"80BA,"4FF3,"73ED,"6669,"5426,"6279,"79D8,"8179,"596E,"4E26,"965B,"9589,"7247,"88DC,"66AE,"5B9D,"8A2A,"4EA1,"5FD8,"68D2,"679A,"5E55,"5BC6,"76DF,"6A21,"8A33,"90F5,"512A,"5E7C,"6B32,"7FCC,"4E71,"5375,"89A7,"88CF,"5F8B,"81E8,"6717,"8AD6,}
diff --git a/macros/luatex/generic/luatexja/tool/ltj-unicode-ccfix_make2.pl b/macros/luatex/generic/luatexja/tool/ltj-unicode-ccfix_make2.pl
new file mode 100755
index 0000000000..f55962956d
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/ltj-unicode-ccfix_make2.pl
@@ -0,0 +1,107 @@
+#!/usr/bin/env perl
+
+# create ltj-unicode-ccfix.tex by processing Unicode data file
+# LineBreak.txt
+
+# modified from unicode-char-prep.pl (part of the XeTeX typesetting system).
+# original copyright is as follows:
+#
+# /****************************************************************************\
+# Part of the XeTeX typesetting system
+# Copyright (c) 1994-2008 by SIL International
+# Copyright (c) 2009 by Jonathan Kew
+#
+# SIL Author(s): Jonathan Kew
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the copyright holders
+# shall not be used in advertising or otherwise to promote the sale,
+# use or other dealings in this Software without prior written
+# authorization from the copyright holders.
+# \****************************************************************************/
+
+die "usage: perl $0 LineBreak.txt > unicode-letters.tex\n"
+ unless $#ARGV == 0;
+
+sub parse_unidata {
+ my (@u) = @_;
+ $lccode{$u[0]} = $u[13] if $u[13] ne '';
+ $lccode{$u[0]} = $u[0] if $u[13] eq '' and ($u[2] =~ /^L/ or $u[12] ne '');
+ $uccode{$u[0]} = $u[12] if $u[12] ne '';
+ $uccode{$u[0]} = $u[0] if $u[12] eq '' and ($u[2] =~ /^L/ or $u[13] ne '');
+ if ($u[2] =~ /^L/) {
+ push(@letters, $u[0]);
+ }
+ elsif ($u[2] =~ /^M/) {
+ push(@marks, $u[0]);
+ }
+ elsif (exists $lccode{$u[0]} or exists $uccode{$u[0]}) {
+ push(@casesym, $u[0]);
+ }
+}
+
+
+my ($start, $end);
+$date = `date`;
+chomp $date;
+print << "__EOT__";
+-- Do not edit this file!
+-- Created from LineBreak.txt by ltj-unicode-ccfix_make.pl on $date.
+-- In case of errors, fix the Perl script instead.
+__EOT__
+
+%lineBreakClass = (
+ 'ID' => 1, # ideograph
+);
+
+
+print << '__EOT__';
+local tex_catcode = tex.setcatcode
+local tex_getcc = tex.getcatcode
+local function set_letter(b,e)
+ if tex_getcc(b)~=11 then
+ for i=b,e do tex_catcode('global', i, 11) end
+ end
+end
+__EOT__
+
+open LineBreak, $ARGV[0] or die "can't read $ARGV[0]";
+while (<LineBreak>) {
+ chomp;
+ s/ *#.*//;
+ s/ +$//;
+ if (m/([0-9A-F]{4,6})(?:\.\.([0-9A-F]{4,6}))?;(..)/) {
+ $s = $1;
+ $e = $2;
+ $lb = $3;
+ $e = $s if $e eq '';
+ if (exists $lineBreakClass{$lb}) {
+ if ($lineBreakClass{$lb} == 1) {
+ # ideographs: set whole range to class 1
+ print "set_letter(0x$s,0x$e)\n";
+ }
+ }
+ }
+}
+close LineBreak;
+
+print << '__EOT__';
+__EOT__
diff --git a/macros/luatex/generic/luatexja/tool/otf-AdobeMingStd-Light.txt b/macros/luatex/generic/luatexja/tool/otf-AdobeMingStd-Light.txt
new file mode 100644
index 0000000000..21ef023c47
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/otf-AdobeMingStd-Light.txt
@@ -0,0 +1,13 @@
+aalt Access All Alternates
+ccmp Glyph Composition/Decomposition
+cpct <unknown feature>
+dlig Discretionary Ligatures
+fwid Full Widths
+halt Alternate Half Widths
+hwid Half Widths
+liga Standard Ligatures
+nalt Alternate Annotation Forms
+pwid Proportional Widths
+vert Vertical Writing
+vhal Alternate Vertical Half Metrics
+vrt2 Vertical Alternates and Rotation
diff --git a/macros/luatex/generic/luatexja/tool/otf-AdobeMyungjoStd-Medium.txt b/macros/luatex/generic/luatexja/tool/otf-AdobeMyungjoStd-Medium.txt
new file mode 100644
index 0000000000..d2c7a22d15
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/otf-AdobeMyungjoStd-Medium.txt
@@ -0,0 +1,13 @@
+aalt Access All Alternates
+dlig Discretionary Ligatures
+fwid Full Widths
+halt Alternate Half Widths
+hngl Hangul
+hwid Half Widths
+nalt Alternate Annotation Forms
+pwid Proportional Widths
+sinf Scientific Inferiors
+sups Superscript
+vert Vertical Writing
+vhal Alternate Vertical Half Metrics
+vrt2 Vertical Alternates and Rotation
diff --git a/macros/luatex/generic/luatexja/tool/otf-AdobeSongStd-Light.txt b/macros/luatex/generic/luatexja/tool/otf-AdobeSongStd-Light.txt
new file mode 100644
index 0000000000..7bbdc3666d
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/otf-AdobeSongStd-Light.txt
@@ -0,0 +1,12 @@
+aalt Access All Alternates
+cpct <unknown feature>
+dlig Discretionary Ligatures
+fwid Full Widths
+halt Alternate Half Widths
+hwid Half Widths
+nalt Alternate Annotation Forms
+pwid Proportional Widths
+trad Traditional Forms
+vert Vertical Writing
+vhal Alternate Vertical Half Metrics
+vrt2 Vertical Alternates and Rotation
diff --git a/macros/luatex/generic/luatexja/tool/otf-KozMinPr6N-Regular.txt b/macros/luatex/generic/luatexja/tool/otf-KozMinPr6N-Regular.txt
new file mode 100644
index 0000000000..04b027baa2
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/otf-KozMinPr6N-Regular.txt
@@ -0,0 +1,38 @@
+aalt Access All Alternates
+afrc Alternative Fractions
+ccmp Glyph Composition/Decomposition
+dlig Discretionary Ligatures
+dnom Denominators
+expt Expert Forms
+frac Fractions
+fwid Full Widths
+halt Alternate Half Widths
+hkna Horizontal Kana Alternates
+hojo <unknown feature>
+hwid Half Widths
+ital Italics
+jp78 JIS78 Forms
+jp83 JIS83 Forms
+jp90 JIS90 Forms
+kern Kerning
+liga Standard Ligatures
+nalt Alternate Annotation Forms
+nlck NLC Kanji Forms
+numr Numerators
+palt Proportional Alternate Widths
+pkna <unknown feature>
+pwid Proportional Widths
+qwid Quarter Widths
+ruby Ruby Notation Forms
+sinf Scientific Inferiors
+subs Subscript
+sups Superscript
+trad Traditional Forms
+twid Third Widths
+vert Vertical Writing
+vhal Alternate Vertical Half Metrics
+vkna Vertical Kana Alternates
+vkrn Vertical Kerning
+vpal Proportional Alternate Vertical Metrics
+vrt2 Vertical Alternates and Rotation
+zero Slashed Zero
diff --git a/macros/luatex/generic/luatexja/tool/table_ivd_aj1.lua b/macros/luatex/generic/luatexja/tool/table_ivd_aj1.lua
new file mode 100644
index 0000000000..cf898a47b2
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/table_ivd_aj1.lua
@@ -0,0 +1,32 @@
+print([[
+return {
+version = 2,
+table_ivd_aj1 = {]])
+
+local f = io.open('IVD_Sequences.txt')
+local t, maxcid = {}, 0
+local s = f:read()
+while s do
+ if s:match('#') then
+ print('-- ' .. s)
+ elseif s:match('Adobe.Japan.') then
+ local c1,c2,c3 = s:match('(%x+)%s+(%x+);%s+Adobe.Japan.;%s+CID%+(%d+)')
+ c1, c2, c3 = tonumber(c1, 16), tonumber(c2, 16), tonumber(c3)
+ if c2 and c2>=0xE0100 then
+ c2 = c2 - 0xE00FF
+ if maxcid<c3 then maxcid = c3 end
+ t[c3] = c2*0x200000+c1
+ end
+ end
+ s = f:read()
+end
+f:close()
+
+for i=1,maxcid do
+ print(' ' .. tostring(t[i] or false) .. ',')
+end
+
+
+-- ( echo 'luatexja.otf.ivd_aj1 = {' ; grep 'Adobe-Japan1' IVD_Sequences.txt|sed 's/\([0-9A-F][0-9A-F]*\) \([0-9A-F][0-9A-F]*\)\;.*CID.\([0-9][0-9]*\)$/[\3]=\{0x\1,0x\2\},/' ; echo '}' )
+print([[}}]])
+
diff --git a/macros/luatex/generic/luatexja/tool/table_jisx0208.lua b/macros/luatex/generic/luatexja/tool/table_jisx0208.lua
new file mode 100644
index 0000000000..f3de6b982e
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/table_jisx0208.lua
@@ -0,0 +1,112 @@
+%#! euptex
+% cat jisx0208table.log | tr -s '\n' > ../src/luatexja/jisx0208.lua
+% ã®å¾Œï¼Œå°‘々修正
+\catcode`\!=1
+\catcode`\?=2
+
+\catcode`@11
+\def\@firstoftwo#1#2{#1}
+\def\@secondoftwo#1#2{#2}
+\def\ifnumcomp#1#2#3{%
+ \ifnum\numexpr#1\relax#2\numexpr#3\relax
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+}
+\def\truncdiv#1#2{%
+ \ifnumcomp{#1}<{(#1)/(#2)*(#2)}{%
+ \numexpr(#1)/(#2)-1%
+ }{%
+ \numexpr(#1)/(#2)%
+ }%
+}
+\def\hex#1{%
+ \ifnumcomp{#1}<0{}{\hn@i{#1}{}}%
+}
+\def\hn@i#1#2{%
+ \ifnumcomp{#1}<{16}
+ {%
+ \hn@digit{#1}#2%
+ }{%
+ \expandafter\hn@ii\expandafter{%
+ \the\numexpr\truncdiv{#1}{16}%
+ }{#1}{#2}%
+ }%
+}
+\def\hn@ii#1#2#3{%
+ \expandafter\hn@i\expandafter{%
+ \number\numexpr#1\expandafter\expandafter\expandafter
+ \expandafter\expandafter\expandafter\expandafter}%
+ \expandafter\expandafter\expandafter\expandafter
+ \expandafter\expandafter\expandafter{%
+ \hn@digit{(#2)-16*(#1)}#3}%
+}
+\begingroup
+\catcode`012\catcode`112\catcode`212\catcode`312\catcode`412
+\catcode`512\catcode`612\catcode`712\catcode`812\catcode`912
+\catcode`A12\catcode`B12\catcode`C12\catcode`D12\catcode`E12
+\catcode`F12
+\gdef\hn@digit#1{%
+ \ifcase\numexpr#1\relax 0%
+ \or \expandafter 1%
+ \or \expandafter 2%
+ \or \expandafter 3%
+ \or \expandafter 4%
+ \or \expandafter 5%
+ \or \expandafter 6%
+ \or \expandafter 7%
+ \or \expandafter 8%
+ \or \expandafter 9%
+ \or \expandafter A%
+ \or \expandafter B%
+ \or \expandafter C%
+ \or \expandafter D%
+ \or \expandafter E%
+ \or \expandafter F%
+ \fi
+}
+\endgroup
+
+
+\catcode`\{=12
+\catcode`\}=12
+\def\folio!?
+
+\newcount\ku
+\newcount\ten
+\newcount\tmp
+\newcount\tmpa
+\newcount\tmpb
+\font\tt=cmtt10 at 10pt\tt\baselineskip=12pt\parindent=0pt\parskip=0pt
+
+\catcode`\_=12
+\message!^^Jluatexbase.provides_module({?
+\message!^^J name = 'luatexja.jisx0208'})?
+\message!^^Jmodule('luatexja.jisx0208', package.seeall)?
+\message!^^Jtable_jisx0208_uptex = {?
+
+\ku=1
+\loop
+ \tmp=\ku \multiply\tmp"100 \advance\tmp"2020 %"
+ ! \ten=1
+ \loop
+ \advance\tmp1
+ \tmpa=\jis\tmp \tmpb=\tmp\advance\tmpb-"2020%"
+ \ifnum\tmpa=0\else
+ \ifnum\tmpa>256
+ \kansujichar1=\tmpa
+ \message!^^J [0x\hex\tmpb] = 0x\hex\tmpa, --(\kansuji1)?
+ \else
+ \message!^^J [0x\hex\tmpb] = 0x\hex\tmpa, ?
+ \fi
+ \fi
+ \advance\ten 1
+ \ifnum\ten<95\relax\repeat
+ ?
+ \advance\ku 1
+\ifnum\ku<95\relax\repeat
+
+\message!^^J}?
+
+\end
diff --git a/macros/luatex/generic/luatexja/tool/unicodeBlocks.tex b/macros/luatex/generic/luatexja/tool/unicodeBlocks.tex
new file mode 100644
index 0000000000..afdd0620da
--- /dev/null
+++ b/macros/luatex/generic/luatexja/tool/unicodeBlocks.tex
@@ -0,0 +1,210 @@
+% based on Unicode blocks Blocks-6.0.0.txt
+\ltjdefcharrange{1}{"0000-"007F} % Basic Latin
+\ltjdefcharrange{2}{"0080-"00FF} % Latin-1 Supplement
+\ltjdefcharrange{3}{"0100-"017F} % Latin Extended-A
+\ltjdefcharrange{4}{"0180-"024F} % Latin Extended-B
+\ltjdefcharrange{5}{"0250-"02AF} % IPA Extensions
+\ltjdefcharrange{6}{"02B0-"02FF} % Spacing Modifier Letters
+\ltjdefcharrange{7}{"0300-"036F} % Combining Diacritical Marks
+\ltjdefcharrange{8}{"0370-"03FF} % Greek and Coptic
+\ltjdefcharrange{9}{"0400-"04FF} % Cyrillic
+\ltjdefcharrange{10}{"0500-"052F} % Cyrillic Supplement
+\ltjdefcharrange{11}{"0530-"058F} % Armenian
+\ltjdefcharrange{12}{"0590-"05FF} % Hebrew
+\ltjdefcharrange{13}{"0600-"06FF} % Arabic
+\ltjdefcharrange{14}{"0700-"074F} % Syriac
+\ltjdefcharrange{15}{"0750-"077F} % Arabic Supplement
+\ltjdefcharrange{16}{"0780-"07BF} % Thaana
+\ltjdefcharrange{17}{"07C0-"07FF} % NKo
+\ltjdefcharrange{18}{"0800-"083F} % Samaritan
+\ltjdefcharrange{19}{"0840-"085F} % Mandaic
+\ltjdefcharrange{20}{"0900-"097F} % Devanagari
+\ltjdefcharrange{21}{"0980-"09FF} % Bengali
+\ltjdefcharrange{22}{"0A00-"0A7F} % Gurmukhi
+\ltjdefcharrange{23}{"0A80-"0AFF} % Gujarati
+\ltjdefcharrange{24}{"0B00-"0B7F} % Oriya
+\ltjdefcharrange{25}{"0B80-"0BFF} % Tamil
+\ltjdefcharrange{26}{"0C00-"0C7F} % Telugu
+\ltjdefcharrange{27}{"0C80-"0CFF} % Kannada
+\ltjdefcharrange{28}{"0D00-"0D7F} % Malayalam
+\ltjdefcharrange{29}{"0D80-"0DFF} % Sinhala
+\ltjdefcharrange{30}{"0E00-"0E7F} % Thai
+\ltjdefcharrange{31}{"0E80-"0EFF} % Lao
+\ltjdefcharrange{32}{"0F00-"0FFF} % Tibetan
+\ltjdefcharrange{33}{"1000-"109F} % Myanmar
+\ltjdefcharrange{34}{"10A0-"10FF} % Georgian
+\ltjdefcharrange{35}{"1100-"11FF} % Hangul Jamo
+\ltjdefcharrange{36}{"1200-"137F} % Ethiopic
+\ltjdefcharrange{37}{"1380-"139F} % Ethiopic Supplement
+\ltjdefcharrange{38}{"13A0-"13FF} % Cherokee
+\ltjdefcharrange{39}{"1400-"167F} % Unified Canadian Aboriginal Syllabics
+\ltjdefcharrange{40}{"1680-"169F} % Ogham
+\ltjdefcharrange{41}{"16A0-"16FF} % Runic
+\ltjdefcharrange{42}{"1700-"171F} % Tagalog
+\ltjdefcharrange{43}{"1720-"173F} % Hanunoo
+\ltjdefcharrange{44}{"1740-"175F} % Buhid
+\ltjdefcharrange{45}{"1760-"177F} % Tagbanwa
+\ltjdefcharrange{46}{"1780-"17FF} % Khmer
+\ltjdefcharrange{47}{"1800-"18AF} % Mongolian
+\ltjdefcharrange{48}{"18B0-"18FF} % Unified Canadian Aboriginal Syllabics Extended
+\ltjdefcharrange{49}{"1900-"194F} % Limbu
+\ltjdefcharrange{50}{"1950-"197F} % Tai Le
+\ltjdefcharrange{51}{"1980-"19DF} % New Tai Lue
+\ltjdefcharrange{52}{"19E0-"19FF} % Khmer Symbols
+\ltjdefcharrange{53}{"1A00-"1A1F} % Buginese
+\ltjdefcharrange{54}{"1A20-"1AAF} % Tai Tham
+\ltjdefcharrange{55}{"1B00-"1B7F} % Balinese
+\ltjdefcharrange{56}{"1B80-"1BBF} % Sundanese
+\ltjdefcharrange{57}{"1BC0-"1BFF} % Batak
+\ltjdefcharrange{58}{"1C00-"1C4F} % Lepcha
+\ltjdefcharrange{59}{"1C50-"1C7F} % Ol Chiki
+\ltjdefcharrange{60}{"1CD0-"1CFF} % Vedic Extensions
+\ltjdefcharrange{61}{"1D00-"1D7F} % Phonetic Extensions
+\ltjdefcharrange{62}{"1D80-"1DBF} % Phonetic Extensions Supplement
+\ltjdefcharrange{63}{"1DC0-"1DFF} % Combining Diacritical Marks Supplement
+\ltjdefcharrange{64}{"1E00-"1EFF} % Latin Extended Additional
+\ltjdefcharrange{65}{"1F00-"1FFF} % Greek Extended
+\ltjdefcharrange{66}{"2000-"206F} % General Punctuation
+\ltjdefcharrange{67}{"2070-"209F} % Superscripts and Subscripts
+\ltjdefcharrange{68}{"20A0-"20CF} % Currency Symbols
+\ltjdefcharrange{69}{"20D0-"20FF} % Combining Diacritical Marks for Symbols
+\ltjdefcharrange{70}{"2100-"214F} % Letterlike Symbols
+\ltjdefcharrange{71}{"2150-"218F} % Number Forms
+\ltjdefcharrange{72}{"2190-"21FF} % Arrows
+\ltjdefcharrange{73}{"2200-"22FF} % Mathematical Operators
+\ltjdefcharrange{74}{"2300-"23FF} % Miscellaneous Technical
+\ltjdefcharrange{75}{"2400-"243F} % Control Pictures
+\ltjdefcharrange{76}{"2440-"245F} % Optical Character Recognition
+\ltjdefcharrange{77}{"2460-"24FF} % Enclosed Alphanumerics
+\ltjdefcharrange{78}{"2500-"257F} % Box Drawing
+\ltjdefcharrange{79}{"2580-"259F} % Block Elements
+\ltjdefcharrange{80}{"25A0-"25FF} % Geometric Shapes
+\ltjdefcharrange{81}{"2600-"26FF} % Miscellaneous Symbols
+\ltjdefcharrange{82}{"2700-"27BF} % Dingbats
+\ltjdefcharrange{83}{"27C0-"27EF} % Miscellaneous Mathematical Symbols-A
+\ltjdefcharrange{84}{"27F0-"27FF} % Supplemental Arrows-A
+\ltjdefcharrange{85}{"2800-"28FF} % Braille Patterns
+\ltjdefcharrange{86}{"2900-"297F} % Supplemental Arrows-B
+\ltjdefcharrange{87}{"2980-"29FF} % Miscellaneous Mathematical Symbols-B
+\ltjdefcharrange{88}{"2A00-"2AFF} % Supplemental Mathematical Operators
+\ltjdefcharrange{89}{"2B00-"2BFF} % Miscellaneous Symbols and Arrows
+\ltjdefcharrange{90}{"2C00-"2C5F} % Glagolitic
+\ltjdefcharrange{91}{"2C60-"2C7F} % Latin Extended-C
+\ltjdefcharrange{92}{"2C80-"2CFF} % Coptic
+\ltjdefcharrange{93}{"2D00-"2D2F} % Georgian Supplement
+\ltjdefcharrange{94}{"2D30-"2D7F} % Tifinagh
+\ltjdefcharrange{95}{"2D80-"2DDF} % Ethiopic Extended
+\ltjdefcharrange{96}{"2DE0-"2DFF} % Cyrillic Extended-A
+\ltjdefcharrange{97}{"2E00-"2E7F} % Supplemental Punctuation
+\ltjdefcharrange{98}{"2E80-"2EFF} % CJK Radicals Supplement
+\ltjdefcharrange{99}{"2F00-"2FDF} % Kangxi Radicals
+\ltjdefcharrange{100}{"2FF0-"2FFF} % Ideographic Description Characters
+\ltjdefcharrange{101}{"3000-"303F} % CJK Symbols and Punctuation
+\ltjdefcharrange{102}{"3040-"309F} % Hiragana
+\ltjdefcharrange{103}{"30A0-"30FF} % Katakana
+\ltjdefcharrange{104}{"3100-"312F} % Bopomofo
+\ltjdefcharrange{105}{"3130-"318F} % Hangul Compatibility Jamo
+\ltjdefcharrange{106}{"3190-"319F} % Kanbun
+\ltjdefcharrange{107}{"31A0-"31BF} % Bopomofo Extended
+\ltjdefcharrange{108}{"31C0-"31EF} % CJK Strokes
+\ltjdefcharrange{109}{"31F0-"31FF} % Katakana Phonetic Extensions
+\ltjdefcharrange{110}{"3200-"32FF} % Enclosed CJK Letters and Months
+\ltjdefcharrange{111}{"3300-"33FF} % CJK Compatibility
+\ltjdefcharrange{112}{"3400-"4DBF} % CJK Unified Ideographs Extension A
+\ltjdefcharrange{113}{"4DC0-"4DFF} % Yijing Hexagram Symbols
+\ltjdefcharrange{114}{"4E00-"9FFF} % CJK Unified Ideographs
+\ltjdefcharrange{115}{"A000-"A48F} % Yi Syllables
+\ltjdefcharrange{116}{"A490-"A4CF} % Yi Radicals
+\ltjdefcharrange{117}{"A4D0-"A4FF} % Lisu
+\ltjdefcharrange{118}{"A500-"A63F} % Vai
+\ltjdefcharrange{119}{"A640-"A69F} % Cyrillic Extended-B
+\ltjdefcharrange{120}{"A6A0-"A6FF} % Bamum
+\ltjdefcharrange{121}{"A700-"A71F} % Modifier Tone Letters
+\ltjdefcharrange{122}{"A720-"A7FF} % Latin Extended-D
+\ltjdefcharrange{123}{"A800-"A82F} % Syloti Nagri
+\ltjdefcharrange{124}{"A830-"A83F} % Common Indic Number Forms
+\ltjdefcharrange{125}{"A840-"A87F} % Phags-pa
+\ltjdefcharrange{126}{"A880-"A8DF} % Saurashtra
+\ltjdefcharrange{127}{"A8E0-"A8FF} % Devanagari Extended
+\ltjdefcharrange{128}{"A900-"A92F} % Kayah Li
+\ltjdefcharrange{129}{"A930-"A95F} % Rejang
+\ltjdefcharrange{130}{"A960-"A97F} % Hangul Jamo Extended-A
+\ltjdefcharrange{131}{"A980-"A9DF} % Javanese
+\ltjdefcharrange{132}{"AA00-"AA5F} % Cham
+\ltjdefcharrange{133}{"AA60-"AA7F} % Myanmar Extended-A
+\ltjdefcharrange{134}{"AA80-"AADF} % Tai Viet
+\ltjdefcharrange{135}{"AB00-"AB2F} % Ethiopic Extended-A
+\ltjdefcharrange{136}{"ABC0-"ABFF} % Meetei Mayek
+\ltjdefcharrange{137}{"AC00-"D7AF} % Hangul Syllables
+\ltjdefcharrange{138}{"D7B0-"D7FF} % Hangul Jamo Extended-B
+\ltjdefcharrange{139}{"D800-"DB7F} % High Surrogates
+\ltjdefcharrange{140}{"DB80-"DBFF} % High Private Use Surrogates
+\ltjdefcharrange{141}{"DC00-"DFFF} % Low Surrogates
+\ltjdefcharrange{142}{"E000-"F8FF} % Private Use Area
+\ltjdefcharrange{143}{"F900-"FAFF} % CJK Compatibility Ideographs
+\ltjdefcharrange{144}{"FB00-"FB4F} % Alphabetic Presentation Forms
+\ltjdefcharrange{145}{"FB50-"FDFF} % Arabic Presentation Forms-A
+\ltjdefcharrange{146}{"FE00-"FE0F} % Variation Selectors
+\ltjdefcharrange{147}{"FE10-"FE1F} % Vertical Forms
+\ltjdefcharrange{148}{"FE20-"FE2F} % Combining Half Marks
+\ltjdefcharrange{149}{"FE30-"FE4F} % CJK Compatibility Forms
+\ltjdefcharrange{150}{"FE50-"FE6F} % Small Form Variants
+\ltjdefcharrange{151}{"FE70-"FEFF} % Arabic Presentation Forms-B
+\ltjdefcharrange{152}{"FF00-"FFEF} % Halfwidth and Fullwidth Forms
+\ltjdefcharrange{153}{"FFF0-"FFFF} % Specials
+\ltjdefcharrange{154}{"10000-"1007F} % Linear B Syllabary
+\ltjdefcharrange{155}{"10080-"100FF} % Linear B Ideograms
+\ltjdefcharrange{156}{"10100-"1013F} % Aegean Numbers
+\ltjdefcharrange{157}{"10140-"1018F} % Ancient Greek Numbers
+\ltjdefcharrange{158}{"10190-"101CF} % Ancient Symbols
+\ltjdefcharrange{159}{"101D0-"101FF} % Phaistos Disc
+\ltjdefcharrange{160}{"10280-"1029F} % Lycian
+\ltjdefcharrange{161}{"102A0-"102DF} % Carian
+\ltjdefcharrange{162}{"10300-"1032F} % Old Italic
+\ltjdefcharrange{163}{"10330-"1034F} % Gothic
+\ltjdefcharrange{164}{"10380-"1039F} % Ugaritic
+\ltjdefcharrange{165}{"103A0-"103DF} % Old Persian
+\ltjdefcharrange{166}{"10400-"1044F} % Deseret
+\ltjdefcharrange{167}{"10450-"1047F} % Shavian
+\ltjdefcharrange{168}{"10480-"104AF} % Osmanya
+\ltjdefcharrange{169}{"10800-"1083F} % Cypriot Syllabary
+\ltjdefcharrange{170}{"10840-"1085F} % Imperial Aramaic
+\ltjdefcharrange{171}{"10900-"1091F} % Phoenician
+\ltjdefcharrange{172}{"10920-"1093F} % Lydian
+\ltjdefcharrange{173}{"10A00-"10A5F} % Kharoshthi
+\ltjdefcharrange{174}{"10A60-"10A7F} % Old South Arabian
+\ltjdefcharrange{175}{"10B00-"10B3F} % Avestan
+\ltjdefcharrange{176}{"10B40-"10B5F} % Inscriptional Parthian
+\ltjdefcharrange{177}{"10B60-"10B7F} % Inscriptional Pahlavi
+\ltjdefcharrange{178}{"10C00-"10C4F} % Old Turkic
+\ltjdefcharrange{179}{"10E60-"10E7F} % Rumi Numeral Symbols
+\ltjdefcharrange{180}{"11000-"1107F} % Brahmi
+\ltjdefcharrange{181}{"11080-"110CF} % Kaithi
+\ltjdefcharrange{182}{"12000-"123FF} % Cuneiform
+\ltjdefcharrange{183}{"12400-"1247F} % Cuneiform Numbers and Punctuation
+\ltjdefcharrange{184}{"13000-"1342F} % Egyptian Hieroglyphs
+\ltjdefcharrange{185}{"16800-"16A3F} % Bamum Supplement
+\ltjdefcharrange{186}{"1B000-"1B0FF} % Kana Supplement
+\ltjdefcharrange{187}{"1D000-"1D0FF} % Byzantine Musical Symbols
+\ltjdefcharrange{188}{"1D100-"1D1FF} % Musical Symbols
+\ltjdefcharrange{189}{"1D200-"1D24F} % Ancient Greek Musical Notation
+\ltjdefcharrange{190}{"1D300-"1D35F} % Tai Xuan Jing Symbols
+\ltjdefcharrange{191}{"1D360-"1D37F} % Counting Rod Numerals
+\ltjdefcharrange{192}{"1D400-"1D7FF} % Mathematical Alphanumeric Symbols
+\ltjdefcharrange{193}{"1F000-"1F02F} % Mahjong Tiles
+\ltjdefcharrange{194}{"1F030-"1F09F} % Domino Tiles
+\ltjdefcharrange{195}{"1F0A0-"1F0FF} % Playing Cards
+\ltjdefcharrange{196}{"1F100-"1F1FF} % Enclosed Alphanumeric Supplement
+\ltjdefcharrange{197}{"1F200-"1F2FF} % Enclosed Ideographic Supplement
+\ltjdefcharrange{198}{"1F300-"1F5FF} % Miscellaneous Symbols And Pictographs
+\ltjdefcharrange{199}{"1F600-"1F64F} % Emoticons
+\ltjdefcharrange{200}{"1F680-"1F6FF} % Transport And Map Symbols
+\ltjdefcharrange{201}{"1F700-"1F77F} % Alchemical Symbols
+\ltjdefcharrange{202}{"20000-"2A6DF} % CJK Unified Ideographs Extension B
+\ltjdefcharrange{203}{"2A700-"2B73F} % CJK Unified Ideographs Extension C
+\ltjdefcharrange{204}{"2B740-"2B81F} % CJK Unified Ideographs Extension D
+\ltjdefcharrange{205}{"2F800-"2FA1F} % CJK Compatibility Ideographs Supplement
+\ltjdefcharrange{206}{"E0000-"E007F} % Tags
+\ltjdefcharrange{207}{"E0100-"E01EF} % Variation Selectors Supplement
+\ltjdefcharrange{208}{"F0000-"FFFFF} % Supplementary Private Use Area-A
+\ltjdefcharrange{209}{"100000-"10FFFF} % Supplementary Private Use Area-B
diff --git a/macros/luatex/generic/luatexko/ChangeLog b/macros/luatex/generic/luatexko/ChangeLog
new file mode 100644
index 0000000000..38e815ea96
--- /dev/null
+++ b/macros/luatex/generic/luatexko/ChangeLog
@@ -0,0 +1,235 @@
+2019-08-01 Dohyun Kim <nomos at ktug org>
+
+ Version 2.4
+
+ * luatexko.lua: allow linebreak before/after a normal hbox
+ * luatexko.{sty,lua}: moveleft horizontal box inside vertical writing
+
+2019-06-21 Dohyun Kim <nomos at ktug org>
+
+ Version 2.3
+
+ * luatexko.lua: prevent discretionary node after Kana;
+ provide lua functions deactivateall() and reactivateall().
+
+2019-06-07 Dohyun Kim <nomos at ktug org>
+
+ Version 2.2
+
+ * luatexko.sty, luatexko.lua: provide font option `InterCharStretch'
+
+2019-05-25 Dohyun Kim <nomos at ktug org>
+
+ Version 2.1
+
+ * luatexko.sty: give smallest stretch to quite short ruby;
+ allow star option to markoverwith.
+
+
+2019-05-01 Dohyun Kim <nomos at ktug org>
+
+ Version 2.0
+
+ * luatexko-core.sty: removed.
+ * luatexko.lua: totally rewritten.
+ * luatexko.sty: Package option `nofontspec' removed.
+ Font options `CompressPunctuations' `RemoveClassicSpaces'
+ and `InterCharacter' added.
+ `\registerbreakablebefore' and `\registerbreakableafter' added.
+
+2019-04-06 Dohyun Kim <nomos at ktug org>
+
+ Version 1.24
+
+ * luatexko.lua: fix a bug regarding vertical typesetting
+
+2019-03-24 Dohyun Kim <nomos at ktug org>
+
+ Version 1.23
+
+ * luatexko.lua: change post-linebreak callback from
+ 'post_linebreak_filter' to 'hpack_filter' with groupcode restriction.
+ * luatex-core.sty: remove '\pdffontsize' and replace it with a
+ more suitable equivalent.
+
+2018-11-09 Dohyun Kim <nomos at ktug org>
+
+ Version 1.22
+
+ * luatexko-core.sty, luatexko.lua: new command \hangulbyhangulfont.
+ This being declared, Hangul characters will be forcibly typeset
+ with Hangul font even when Latin font has Hangul glyphs.
+
+2018-08-02 Dohyun Kim <nomos at ktug org>
+
+ Version 1.21
+
+ * luatexko.sty: adapt to the fontspec v2.6h
+ * luatexko.lua: font substitution for disc node as well
+
+2018-04-19 Dohyun Kim <nomos at ktug org>
+
+ Version 1.20
+
+ * luatexko.lua: node.tail -> node.slide: see the bug reported at
+ http://www.ktug.org/xe/index.php?document_srl=229431
+
+2018-04-06 Dohyun Kim <nomos at ktug org>
+
+ Version 1.19
+
+ * luatexko.sty: use glueexpr
+
+2017-09-29 Dohyun Kim <nomos at ktug org>
+
+ Version 1.18
+
+ * luatexko.sty: zf@enc -> f@encoding
+
+2017-05-01 Dohyun Kim <nomos at ktug org>
+
+ Version 1.17
+
+ * luatexko.lua: rewrite reorderTM (reorder-tone-marks) function
+
+
+2017-02-06 Dohyun Kim <nomos at ktug org>
+
+ Version 1.16
+
+ * luatexko.sty: patch {rm|sf|tt}family of fontspec 2017
+
+2016-05-14 Dohyun Kim <nomos at ktug org>
+
+ Version 1.15
+
+ * luatexko-core.sty: allow nested underline emphasis
+
+2016-05-08 Dohyun Kim <nomos at ktug org>
+
+ Version 1.14
+
+ * luatexko.lua, luatexko-core.sty: more updates for luatex 0.95,
+ user_defined whatsit intead of special whatsit
+
+2016-04-25 Dohyun Kim <nomos at ktug org>
+
+ Version 1.13
+
+ * luatexko.lua: direct access to vmtx table; drop caching
+
+2016-04-22 Dohyun Kim <nomos at ktug org>
+
+ Version 1.12
+
+ * *.sty, *.lua: drop loading luatexbase.sty; updates for luatex 0.95
+ * luatexko.lua: avoid nested underline emphasis
+
+2015-12-10 Dohyun Kim <nomos at ktug org>
+
+ Version 1.11
+
+ * luatexko-core.sty: adapt to luaotfload v2.6
+ * luatexko-normalize.lua: a small fix for windows os
+
+2015-10-02 Dohyun Kim <nomos at ktug org>
+
+ Version 1.10
+
+ * luatexko.lua: adapt to latex 2015/10/01 and luatexbase v1.0
+ * luatexko.lua: assing pre/post penalty to U+FF62, U+FF63
+ * luatexko.lua: fix an infinite loop in reorderTM
+
+2015-07-02 Dohyun Kim <nomos at ktug org>
+
+ Version 1.9
+
+ * luatexko.lua: some more compatibility with synctex
+ * luatexko-core.sty: new environment `horizontal'
+ * luatexko.lua: remove support for ideographic variations (fontloader
+ supports them)
+
+2015-05-10 Dohyun Kim <nomos at ktug org>
+
+ Version 1.8
+
+ * luatexko.lua: internal changes using `node.direct'
+ * luatexko-core.sty: \xxruby is a convenient variant of \ruby
+
+2015-01-16 Dohyun Kim <nomos at ktug org>
+
+ Version 1.7
+
+ * luatexko.sty: package option [unfonts] is removed
+ * *.lua, *.sty: minor fixes and updated copyright year
+
+2014-06-17 Dohyun Kim <nomos at ktug org>
+
+ Version 1.6
+
+ * luatexko.sty, luatexko.lua: new font option [NoEmbedding] prevents
+ inclusion of fonts into PDF file.
+ * luatexko-uhc2utf8.lua: fix a bug in utf-8 detection routine,
+ reported by Karnes Kim
+ * luatexko.lua: put underline leader node before text, so that text
+ should not be overprinted by a color box. Requested by Karnes Kim
+ * luatexko.sty: [Ligatures=TeX] is now default option for main/sans
+ hangul/hanja/fallback fonts. Requires fontspec v2.4
+
+2014-05-11 Dohyun Kim <nomos at ktug org>
+
+ Version 1.5
+
+ * luatexko.sty: new package option [nofontspec] which prevents loading
+ of fontspec.sty
+ * luatexko.lua, luatexko.sty: use Nanum Type1 fonts as final fallback
+ fonts
+ * luatexko.sty: font option YetHangul=Off has gone now, only YetHangul
+ is still there.
+ * luatexko.lua: implemented experimental support for vertical
+ typesetting. LuaTeX version 0.79 or later is required.
+ * luatexko.lua, luatexko-core.sty: new macro \actualtext inspired by
+ accsupp.sty authored by Heiko Oberdiek.
+ * luatexko.lua: italic correction for replacing cjk fonts as well
+
+2014-01-16 Dohyun Kim <nomos at ktug org>
+
+ Version 1.4
+
+ * luatexko.lua: italic correction of fakeslant font
+ * luatexko.sty: use everysel.sty to redefine selectfont. This fixes
+ a bug reported by Hoze Yi & Juho Lee.
+
+2013-12-06 Dohyun Kim <nomos at ktug org>
+
+ Version 1.3
+
+ * luatexko.lua: if \josaignoreparens=1, then characters inside
+ parentheses are ignored during automatic josa selection routine.
+ * luatexko.sty, luatexko-core.sty, luatexko.lua: new macros
+ \hangulpunctuations \registerpunctuations etc; removed [QuoteRaise]
+ font option.
+ * luatexko.sty, luatexko-core.sty, luatexko.lua: new macros
+ \setmainfallbackfont \setsansfallbackfont etc.
+
+2013-07-03 Dohyun Kim <nomos at ktug org>
+
+ Version 1.2
+
+ * luatexko.sty: move Hangul caption setting to AtBeginDocument
+ * luatexko.lua: implemented reordering of hangul tone marks;
+ fix a bug wrt. \dotemph of old hangul.
+ * luatexko-core.sty: adapt to \fontname fix by luaotfload
+
+2013-05-19 Dohyun Kim <nomos at ktug org>
+
+ Version 1.1
+
+ * luatexko.sty: fix a bug regarding hyperref pdf string
+ * luatexko.lua, luatexko-core.sty: remove redundant code wrt.
+ font switching
+
+2013-05-10 Dohyun Kim <nomos at ktug org>
+
+ Initial release. Version 1.0
+
diff --git a/macros/luatex/generic/luatexko/README b/macros/luatex/generic/luatexko/README
new file mode 100644
index 0000000000..1284ed2271
--- /dev/null
+++ b/macros/luatex/generic/luatexko/README
@@ -0,0 +1,151 @@
+LuaTeX-ko Package version 2.4 (2019/08/01)
+===========================================
+
+This is a Lua(La)TeX macro package that supports typesetting Korean
+documents including Old Hangul texts. As LuaTeX has opened up access to
+almost all the hidden routines of TeX engine, users can obtain more
+beautiful outcome using this package rather than other Hangul packages
+operating on other engines.
+
+LuaTeX version 1.10+ and luaotfload package version 2.96+ are required for
+this package to run.
+
+This package also requires cjk-ko package for its full functionality.
+
+
+License
+-------
+
+This package is licensed under [LPPL](http://latex-project.org/lppl/)
+(LaTeX Project Public License) version 1.3c or later.
+
+See each file for details.
+
+
+Author
+------
+
+ Dohyun Kim <nomos at ktug org>
+ Soojin Nam <jsunam at gmail com>
+
+Please report any errors or suggestions to
+or leave messages in the issue tracker at:
+ <http://github.com/dohyunkim/luatexko>
+
+
+Files
+-----
+
+TeXinputs
+
+ luatexko.sty -> tex/luatex/luatexko/
+ luatexko.lua -> tex/luatex/luatexko/
+ luatexko-normalize.lua -> tex/luatex/luatexko/
+ luatexko-uhc2utf8.lua -> tex/luatex/luatexko/
+
+Documents
+
+ luatexko-doc.pdf -> doc/luatex/luatexko/
+ luatexko-doc.tex -> doc/luatex/luatexko/
+ README (this file) -> doc/luatex/luatexko/
+ ChangeLog -> doc/luatex/luatexko/
+
+
+Loading
+-------
+
+For a LaTeX user, declaring
+
+ \usepackage{luatexko}
+or
+
+ \usepackage{kotex}
+is sufficient to load the package, which will load fontspec as well.
+Notice that kotex.sty is a file provided by cjk-ko package.
+
+Under plain TeX:
+
+ \input luatexko.sty
+
+
+Package Options
+---------------
+
+ [hangul]
+Load Hangul captions. Besides, this option adjusts interword and
+interline spacing. Declares \hangulpunctuations=1 as well.
+
+ [hanja]
+Load Hanja captions. Also apply other settings as [hangul] option does.
+
+
+Hangul Font Commands
+--------------------
+
+ \setmainhangulfont
+ \setsanshangulfont
+ \setmonohangulfont
+Equivalent to \setmainfont et. al. of fontspec package. These fonts are
+used when the font loaded by \setmainfont et. al. does not have Hangul
+glyphs.
+
+ \setmainhanjafont
+ \setsanshanjafont
+ \setmonohanjafont
+These fonts are used when the font loaded by \setmainfont or
+\setmainhangulfont et. al. does not have Hanja glyphs.
+
+ \setmainfallbackfont
+ \setsansfallbackfont
+ \setmonofallbackfont
+These fonts are used when the font loaded by \setmainfont,
+\setmainhangulfont, or \setmainhanjafont et. al. does not have Hanja
+glyphs.
+
+In like manner, these commands are available as well:
+
+ \hangulfontspec \newhangulfontfamily \addhangulfontfeature
+ \hanjafontspec \newhanjafontfamily \addhanjafontfeature
+ \fallbackfontspec \newfallbackfontfamily \addfallbackfontfeature
+
+If any of these CJK fonts are not specified, UnBatang/UnDotum TrueType
+fonts will be used for typesetting CJK characters.
+
+
+Hangul Font Options
+-------------------
+
+ [InterHangul=<dimen>]
+Set spacing between Hangul characters.
+
+ [InterLatinCJK=<dimen>]
+Set spacing between CJK and Latin characters.
+
+ [CharRaise=<dimen>]
+Raise CJK characters by <dimen>.
+
+
+Other User Commands
+-------------------
+
+ \hangulpunctuations=<number>
+When <number> is 1 or greater (being default value), latin punctuations
+will be typeset with hangul fonts.
+
+ \dotemph{...}
+Emphasise Hangul or Hanja by putting dot above.
+
+ \ruby{<base text>}{<ruby text>}
+Typeset ruby annotations.
+
+ \uline{...}
+ \sout{...}
+ \uuline{...}
+ \xout{...}
+ \uwave{...}
+ \dashuline{...}
+ \dotuline{...}
+Same functionality as those ulem package provides.
+
+
+*END of README*
diff --git a/macros/luatex/generic/luatexko/luatexko-doc.pdf b/macros/luatex/generic/luatexko/luatexko-doc.pdf
new file mode 100644
index 0000000000..0eb5a5078f
--- /dev/null
+++ b/macros/luatex/generic/luatexko/luatexko-doc.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexko/luatexko-doc.tex b/macros/luatex/generic/luatexko/luatexko-doc.tex
new file mode 100644
index 0000000000..517fe4d2ed
--- /dev/null
+++ b/macros/luatex/generic/luatexko/luatexko-doc.tex
@@ -0,0 +1,664 @@
+%% !TEX program = lualatex
+%% !TEX encoding = UTF-8
+%%
+%% luatexko-doc.tex
+%%
+%% written by Dohyun Kim <nomos at ktug org>
+%% Soojin Nam <jsunam at gmail com>
+%%
+%% public domain
+
+\documentclass[a4paper]{article}
+\usepackage[hmargin=3.8cm]{geometry}
+\usepackage[svgnames]{xcolor}
+\usepackage[hangul]{luatexko}
+\directlua{
+ fonts.protrusions.setups.notoserifcjk = {
+ [171] = { 0.5, 0 },
+ [187] = { 0, 0.5 },
+ [1002965] = { 0, 0.5 },
+ [1002968] = { 0.5, 0 },
+ [1002969] = { 0, 0.5 },
+ [1002970] = { 0, 1 },
+ [1002971] = { 0, 0.5 },
+ [1002972] = { 0, 1 },
+ [1002974] = { 0, 0.5 },
+ [1002975] = { 0, 0.5 },
+ [1002976] = { 0, 0.5 },
+ [1002985] = { 1, 0 },
+ [1002986] = { 0, 1 },
+ [1002988] = { 0.5, 0 },
+ [1002989] = { 0, 0.5 },
+ }
+}
+\setmainhangulfont{Noto Serif CJK KR}[
+ Scale=0.98,
+ AutoFakeSlant,
+ Script=Hangul,
+ Language=Korean,
+ LocalForms=On,
+ UprightFont=* Light,
+ BoldFont=* Bold,
+ InterLatinCJK=.125em,
+ Expansion, Protrusion=notoserifcjk,
+]
+\setsanshangulfont{Noto Sans CJK KR}[
+ Scale=0.98,
+ Script=Hangul,
+ Language=Korean,
+ UprightFont=* DemiLight,
+ BoldFont=* Bold,
+ InterLatinCJK=.125em,
+]
+\setmonofont{Inconsolatazi4}[
+ Scale=0.98,
+ CharRaise=0.125ex,
+ Color=MidnightBlue,
+]
+\setmonohangulfont{Noto Sans CJK KR}[
+ Scale=0.98,
+ UprightFont=* DemiLight,
+ BoldFont=* Bold,
+ CharRaise=-.125ex,
+ Color=MidnightBlue,
+]
+\setmathhangulfont{Noto Sans CJK KR}[
+ Script=Hangul,
+ Language=Korean,
+ SizeFeatures={
+ {Size=-6, Font=* Medium},
+ {Size=6-9, Font=* Regular},
+ {Size=9-, Font=* DemiLight},
+ },
+]
+\newhangulfontface\rubyfont{Noto Serif CJK KR Medium}[
+ Script=Hangul,
+ Language=Korean,
+]
+\usepackage{hologo}
+\def\luatex{\hologo{LuaTeX}}
+\def\XeTeX{\hologo{XeTeX}}
+\usepackage[pdfencoding=auto,bookmarksnumbered,hidelinks]{hyperref}
+
+\edef\verbatim{\unexpanded\expandafter{\verbatim\linespread{1.1}\selectfont}}
+\edef\itemize{\unexpanded\expandafter{\itemize\small}}
+\catcode`|=13 \protected\def|{\verb|\let\\=\textbackslash}
+\protected\def\cs#1{\texttt{\language=1 \textbackslash\detokenize{#1}}}
+\def\logoko{\textsf{k}\kern-.0625em\textit{o}}
+\def\luatexko{\luatex-\logoko}
+\def\texlive{\TeX\ Live}
+\def\kotex{\logoko\kern-.1ex .\kern-.1667em \TeX}
+\def\hemph#1{\textsf{\bfseries #1}}
+\def\ldots{$\dots$}
+
+\begin{document}
+\title{\luatexko\ 간단 매뉴얼}
+\author{Dohyun Kim \normalsize |<nomos at ktug org>| \and
+ Soojin Nam \normalsize |<jsunam at gmail com>| \and
+ \normalsize <\url{http://github.com/dohyunkim/luatexko}>}
+\date{Version 2.4\quad 2019/08/01}
+\maketitle
+
+\begin{quote}\small
+ For a summary introduction in English, please see |README| file.
+
+ \begin{itemize}\linespread{1.1}\selectfont
+ \item[v2.2] ------
+ \item \hyperref[sec:fontoption]{글꼴옵션 |InterCharStretch| 제공}
+ \item[v2.0] ------
+ \item \hyperref[sec:fontoption]{글꼴옵션 |PunctRaise|, |NoEmbeding| 제거}
+ \item \hyperref[sec:mathhangul]{ìˆ˜ì‹ í•œê¸€ ê¸€ê¼´ì„ ìžë™ìœ¼ë¡œ 잡아주지 ì•ŠìŒ}
+ \item \cs{actualtext} 명령 ìž‘ë™ ì•ŠìŒ. 대신, 옛한글 í…스트 추출 ìžë™ 지ì›%
+ \footnote{%
+ PDF ë¦¬ë” ì–´í”Œë¦¬ì¼€ì´ì…˜ì´ ActualText ê¸°ëŠ¥ì„ ì§€ì›í•´ì•¼ 가능하다.
+ ì–´ë„비 리ë”는 확실히 가능할 것ì´ë‹¤. }
+ \item \hyperref[sec:fontoption]{글꼴옵션 |CompressPunctuations|,
+ |RemoveClassicSpaces|, |InterCharacter| 추가}
+ \item \hyperref[sec:break]{\cs{registerbreakableafter},
+ \cs{registerbreakablebefore} 명령 추가}
+ \end{itemize}
+\end{quote}
+
+\smallskip
+
+\section{부르기}\label{sec:loading}
+
+\hemph{\texlive\ 2019 ì´ìƒ}{ \small (\luatex\ v1.10 ì´ìƒ)}ì„ ì‚¬ìš©í•´ì•¼ 한다.
+
+\luatexko\ 부르기: \cs{usepackage{luatexko}} í˜¹ì€ \cs{usepackage{kotex}}.%
+\footnote{%
+ 플레ì¸í…ì—서는 \cs{input luatexko.sty} í˜¹ì€ \cs{input kotex.sty}. }
+
+ìž…ë ¥ì€ ì›ì¹™ì ìœ¼ë¡œ UTF-8으로 한다.
+BOM (Byte Order Mark)ì€ ìžˆì–´ë„ ì¢‹ê³  ì—†ì–´ë„ ì¢‹ë‹¤.
+CP949 ì¸ì½”ë”©ì— ê´€í•´ì„œëŠ” ì œ\ref{sec:uhcencoding}ì ˆ 참조.
+
+\section{패키지 옵션}\label{sec:packageopt}
+
+패키지 옵션으로 |[hangul]|ê³¼ |[hanja]|ê°€ 제공ëœë‹¤.%
+\footnote{%
+ |[nofontspec]| ì˜µì…˜ì€ v2.0부터 ë”는 제공ë˜ì§€ 않는다. }
+행간격 ì¡°ì •ì´ í–‰í•´ì§€ë©°
+장 제목ì´ë‚˜ 표·그림 캡션 따위가 한글 ë˜ëŠ” í•œìž ë°©ì‹ìœ¼ë¡œ 표시ëœë‹¤.
+장(chapter) 제목과 편(part) 제목ì—만 ``ì œ(第)''ê°€ 붙어 ``ì œ~1 편''
+``ì œ~3 장''ê³¼ ê°™ì€ ë°©ì‹ìœ¼ë¡œ 표시ë˜ë©° ì ˆ 제목 ì´í•˜ì—는 붙지 않는다.
+
+\section{글꼴명령}\label{sec:fontcmds}
+
+\luatexko를 로드하면 fontspec 패키지를 ìžë™ìœ¼ë¡œ 불러온다. 글꼴 설정ì—
+대해서는 fontspec 문서를 참조.
+
+한국어 ê¸€ê¼´ì„ ìœ„í•´ 새로 마련한 ëª…ë ¹ì€ ë‹¤ìŒê³¼ 같다.
+첫 ë‘ ì¤„, 즉 main/sans 글꼴들ì—는 |Ligatures=TeX| ì˜µì…˜ì´ ìžë™ìœ¼ë¡œ 주어진다.%
+\footnote{%
+ \cs{adhochangulfont} \cs{adhochanjafont} \cs{addhocfallbackfont}는
+ 마지막 줄 ëª…ë ¹ë“¤ì˜ ë‹¤ë¥¸ ì´ë¦„들ì´ë‹¤. }\,%
+\footnote{%
+ 플레ì¸í…ì—ì„œ 한글 글꼴 ì„¤ì •ì€ ë‹¤ìŒê³¼ ê°™ì´ í•œë‹¤:\par
+ \leftskip=3em\noindent
+ \cs{hangulfont=UnDotum\relax}\\
+ \cs{hanjafont=UnDotum at 14pt}\\
+ \cs{fallbackfont=HanaMinB at 12pt} }
+\begin{verbatim}
+ \setmainhangulfont \setmainhanjafont \setmainfallbackfont
+ \setsanshangulfont \setsanshanjafont \setsansfallbackfont
+ \setmonohangulfont \setmonohanjafont \setmonofallbackfont
+ \newhangulfontfamily \newhanjafontfamily \newfallbackfontfamily
+ \newhangulfontface \newhanjafontface \newfallbackfontface
+ \addhangulfontfeature \addhanjafontfeature \addfallbackfontfeature
+ \hangulfontspec \hanjafontspec \fallbackfontspec
+\end{verbatim}
+
+\section{글꼴 대체}\label{sec:fontswitch}
+
+ì›ì¹™ì ìœ¼ë¡œ \luatexko는 ì§€ì‹œëœ ê¸€ìžê°€ ì˜ë¬¸í°íŠ¸ì— 없으면 한글í°íŠ¸ì—ì„œ,
+한글í°íŠ¸ì—ë„ ì—†ìœ¼ë©´ í•œìží°íŠ¸ì—ì„œ, í•œìží°íŠ¸ì—ë„ ì—†ìœ¼ë©´ fallback
+í°íŠ¸ì—ì„œ 글ìžë¥¼ 찾아 ì°ëŠ”다.
+한글í°íŠ¸ê°€ 지정ë˜ì§€ 않았고 기본í°íŠ¸ì— 한글 글리프가 없다면
+\hemph{ì€ë°”탕, ì€ë‹ì›€ 트루타입}ì„ ìžë™ìœ¼ë¡œ 불러온다.%
+\footnote{%
+ ì€ê¸€ê¼´ íŠ¸ë£¨íƒ€ìž…ì€ \texliveì— í¬í•¨ë˜ì–´ 있다. }
+
+하지만 \cs{hangulbyhangulfont=1}ì„ ì„ ì–¸í•˜ë©´ í•œê¸€ì€ ìš°ì„  한글í°íŠ¸ë¡œ
+ì‹ìží•œë‹¤. ë˜í•œ \cs{hanjabyhanjafont=1}ì„ ì„ ì–¸í•˜ë©´ í•œìžëŠ” ìš°ì„  í•œìží°íŠ¸ë¡œ
+ì‹ìží•œë‹¤. ë‘ ê²½ìš° ëª¨ë‘ |0|ì„ ì„ ì–¸í•˜ë©´ ì›ëž˜ ë°©ì‹ìœ¼ë¡œ ë˜ëŒì•„간다.
+문단 중간ì—ì„œ ì‚¬ìš©í•´ë„ ë™ìž‘한다. 그러나 루아코드가 실행ë˜ë¯€ë¡œ
+í…ì˜ ê·¸ë£¹ì— ì˜í•´ ì˜í–¥ë°›ì§€ 않는 ì „ì—­ì  íš¨ê³¼ë¥¼ 가진다.
+
+ì¼ì •í•œ ì˜ë¬¸ ë¬¸ìž¥ë¶€í˜¸ë“¤ì€ í•œê¸€ í°íŠ¸ë¡œ ì‹ìžëœë‹¤.
+즉, \cs{hangulpunctuations=1}ì´ ê¸°ë³¸ìœ¼ë¡œ ìž‘ë™í•˜ê³ ,
+|0|ì„ ì§€ì‹œí•´ì•¼ ì´ ê¸°ëŠ¥ì´ ë¹„ë¡œì†Œ 꺼진다.
+verbatim 코드를 ì‹ìží•  때는 ì´ ê¸°ëŠ¥ì´ ìž‘ë™í•˜ì§€ 않는다.%
+\footnote{%
+ 좀 ë” ì •í™•ížˆ ë§í•˜ë©´ \cs{language=1} ìƒí™©ì—서는 ìž‘ë™í•˜ì§€ 않는다.
+ 부연하건대, \cs{language=1}ì¸ ìƒí™©ì—ì„œ ìž‘ë™í•˜ì§€ 않는 ê·¸ë°–ì˜ ê¸°ëŠ¥ë“¤ì€
+ 다ìŒê³¼ 같다: 줄바꿈 허용, InterCharacter, InterHangul, InterLatinCJK,
+ CompressPunctuations, RemoveClassicSpaces,
+ 한글^^b7í•œìž í°íŠ¸ ë¬¸ìž ë‹¤ìŒì— 오는 ê³µë°±ì˜ í¬ê¸° ì¡°ì • 등. }\,%
+\footnote{%
+ ë˜í•œ 플레ì¸í…ì—서는 ì˜ë¬¸ê¸€ê¼´ì„ 트루타입/오픈타입으로 지정해야만 ìž‘ë™í•œë‹¤. }
+ì˜í–¥ 받는 ë¬¸ìž¥ë¶€í˜¸ë“¤ì˜ ê¸°ë³¸ê°’ì€ ë‹¤ìŒê³¼ 같다:
+\begin{verbatim}
+ [0x21] ! [0x27] ' [0x28] ( [0x29] )
+ [0x2C] , [0x2E] . [0x3A] : [0x3B] ;
+ [0x3F] ? [0x60] ` [0xB7] · [0x2014] —
+ [0x2015] ― [0x2018] ‘ [0x2019] ’ [0x201C] “
+ [0x201D] †[0x2026] … [0x203B] ※
+\end{verbatim}
+
+다ìŒê³¼ ê°™ì€ ëª…ë ¹ìœ¼ë¡œ ì´ ëª©ë¡ì— 문ìžë¥¼ 추가하거나 제거할 수 있다.
+ì¸ìžëŠ” 콤마로 ë¶„ë¦¬ëœ ìˆ«ìž í˜•ì‹ìœ¼ë¡œì„œ 유니코드 코드í¬ì¸íŠ¸ë¥¼ 뜻한다.
+ì´ë“¤ ëª…ë ¹ì€ ë¬¸ë‹¨ 중간ì—ì„œë„ ì“¸ 수 있지만, ì „ì—­ì  íš¨ê³¼ë¥¼ 가진다.
+\begin{verbatim}
+ \registerpunctuations{45, "2D, `-}
+ \unregisterpunctuations{"2D, "2015}
+\end{verbatim}
+
+\section{줄바꿈 허용}\label{sec:break}
+
+ì–´ë–¤ ê¸€ìž ì•žì´ë‚˜ ë’¤ì—ì„œ ì¤„ë°”ê¿ˆì„ í—ˆìš©í•˜ê³  ì‹¶ì„ ë•Œ 아래와 ê°™ì´ ëª…ë ¹ì„ ì¤€ë‹¤.
+\begin{verbatim}
+\registerbreakableafter{"2460, "2461}
+\registerbreakablebefore{"2460, "2461}
+\end{verbatim}
+\luatexko는 다분히 보수ì ìœ¼ë¡œ ì¤„ë°”ê¿ˆì„ í—ˆìš©í•˜ê³  있다.
+예시한 유니코드는 `â‘ 'ê³¼ `â‘¡'ì¸ë° 기본ì ìœ¼ë¡œ
+ì´ë“¤ ë¬¸ìž ì•žë’¤ 모ë‘ì—ì„œ ì¤„ë°”ê¿ˆì´ ë˜ì§€ 않는다.
+
+\section{글꼴 옵션}\label{sec:fontoption}
+
+fontspecì˜ ê¸€ê¼´ 옵션 ì™¸ì— \luatexkoê°€ ë”°ë¡œ 제공하는 ê²ƒë“¤ì´ ìžˆë‹¤.%
+\footnote{%
+ 옛한글 ì‹ìžë¥¼ 위해서는 ì ì–´ë„ |Script=Hangul|
+ (플레ì¸í…ì´ë¼ë©´ |script=hang|)ì„ ì£¼ì–´ì•¼ 한다.
+ ì˜›í•œê¸€ì´ ì•„ë‹ˆë”ë¼ë„ í•œê¸€ì„ ì“´ë‹¤ë©´ ì´ ì˜µì…˜ì€ ì£¼ëŠ” ê²ƒì´ ì¢‹ë‹¤.
+ ë˜í•œ í°íŠ¸ê°€ 지ì›í•œë‹¤ë©´ |LocalForms=On| (플레ì¸í…ì´ë¼ë©´ |+locl|)ê³¼
+ 함께 쓰는 ê²ƒì´ ê¶Œìž¥ëœë‹¤. }\,%
+\footnote{%
+ |PunctRaise|, |NoEmbedding| ì˜µì…˜ì€ v2.0부터 ë”는 제공하지 않는다. }
+
+\def\hunmintxt{%
+ \noindent\textbf{%
+ 世솅〮宗조ᇰ御ᅌᅥᆼ〮製졩〮訓훈〮民민正져ᇰ〮音ᅙᅳᆷ
+ }\par
+ 製졩〮ᄂᆞᆫ〮글〮지ᅀᅳᆯ〮씨〮니〮御ᅌᅥᆼ〮製졩〮ᄂᆞᆫ〮님〯금〮지〯ᅀᅳ샨〮그〮리ë¼ã€®è¨“훈〮ì€ã€®á„€á†žá„…ᆞ칠〮씨〮오〮民%
+ 민ᄋᆞᆫ〮百ᄇᆡᆨ〮姓셔ᇰ〮ì´ã€®ì˜¤ã€®éŸ³á…™á…³á†·ì€ã€®ì†Œë¦¬ã€®ë‹ˆã€®è¨“훈〮民%
+ 민正져ᇰ〮音ᅙᅳᆷì€ã€®ç™¾á„‡á†¡á†¨ã€®å§“셔ᇰ〮ᄀᆞᄅᆞ치〮시논〮正져ᇰ〮ᄒᆞᆫ소리〮ë¼ã€®
+ \par\medskip
+ \noindent\textbf{%
+ 國ê·ã€®ä¹‹ì§•èªžá…Œá…¥á†¼ã€¯éŸ³á…™á…³á†·ì´ã€®
+ }\par
+ 國ê·ã€®á„‹á†žá†«ã€®ë‚˜ë¼ã€®ížˆë¼ã€®ä¹‹ì§•á„‚ᆞᆫ〮입〮겨〮지ë¼ã€®èªžá…Œá…¥á†¼ã€¯ëŠ”ë§ã€¯á„Šá†žë¯¸ë¼ã€®
+ \par
+ 나ëžã€®ë§ã€¯á„Šá†žë¯¸ã€®
+ \par\medskip
+ \noindent\textbf{%
+ 異잉〮乎ᅘᅩᆼ中듀ᇰ國ê·ã€®á„’ᆞ〮야〮
+ }\par
+ 異잉〮ᄂᆞᆫ〮다ᄅᆞᆯ씨ë¼ä¹Žá…˜á…©á†¼á„‚ᆞᆫ〮아〯모〮그ᅌᅦᄒᆞ〮논겨〮체ᄡᅳ〮는字á„ᆞᆼ〮ㅣë¼ã€®ä¸­á„ƒá…²á‡°åœ‹ê·ã€®á„‹á†žá†«ã€®%
+ 皇ᅘᅪᇰå¸ëŽ½ã€®ê²¨ã€¯ì‹ ë‚˜ë¼ã€®ížˆë‹ˆã€®ìš°ã€®ë¦¬ã€®ë‚˜ëžã€®å¸¸á„Šá…£á‡°è«‡ë•€ì• ã€®æ±Ÿá„€á…¡á‡°å—남ì´ã€®ë¼ã€®á„’ᆞ〮ᄂᆞ〮니ë¼ã€®
+ \par
+ 中듀ᇰ國ê·ã€®ì—〮달아〮
+}
+
+\begin{figure}
+ \fboxsep=1em
+ \fbox{\parbox{\dimexpr\linewidth-2.1em\relax}{\sffamily
+ \parindent1em
+ \hunmintxt
+}}
+\caption{옛한글 ì¡°íŒ ë³´ê¸°}\label{fig:yethangul}
+\end{figure}
+
+\begin{description}
+ \item[InterHangul] {\addhangulfontfeature{InterHangul=.5ex}한글 글ìž
+ 사ì´ì˜ ìžê°„}. 아래는 $-0.04$em ë§Œí¼ í•œê¸€ ìžê°„ì„ ì§€ì‹œí•œë‹¤.%
+ \footnote{%
+ 플레ì¸í…ì—서는 |interhangul=<dimen>|. }
+\begin{verbatim}
+ [InterHangul=-0.04em]
+\end{verbatim}
+
+\item[InterLatinCJK] 한글 ë˜ëŠ” í•œìžì™€ Latinë¬¸ìž ì‚¬ì´ì˜ ìžê°„ì„ ì„¤ì •í•œë‹¤.%
+ \footnote{%
+ 플레ì¸í…ì—서는 |interlatincjk=<dimen>|. }
+ 한글^^b7í•œìž ë‹¤ìŒì— ë¼í‹´ 문ìžê°€ 오는 경우 ì›ëž˜ëŠ” ì¤„ë°”ê¿ˆì´ ë˜ì§€ 않지만
+ ì´ ì˜µì…˜ì„ ì£¼ë©´ ì¤„ë°”ê¿ˆì´ ê°€ëŠ¥í•´ì§„ë‹¤.
+\begin{verbatim}
+ [InterLatinCJK=0.25em]
+\end{verbatim}
+
+\item[InterCharacter] CJK 글ìžë“¤ 사ì´ì˜ ìžê°„ì„ ì§€ì‹œí•œë‹¤.%
+ \footnote{%
+ 플레ì¸í…ì—서는 |intercharacter=<dimen>|. }
+ fontspecì˜ |LetterSpace| 옵션과 ê¸°ëŠ¥ì´ ìœ ì‚¬í•˜ì§€ë§Œ, ì˜›í•œê¸€ì„ ê¹¨ëœ¨ë¦¬ëŠ” 등ì˜
+ 오작ë™ì„ 하지 않는다. 전술한 ìžê°„ 옵션들보다 후순위로 ë™ìž‘한다.
+\begin{verbatim}
+ [InterCharacter=.125em]
+\end{verbatim}
+
+\item[InterCharStretch] CJK 글ìžê°„ 가변공백{\small(글루)}ì˜
+ stretch ê°’ì„ ì§€ì‹œí•œë‹¤.%
+ \footnote{%
+ 플레ì¸í…ì—서는 |intercharstretch=<dimen>|. }
+\begin{verbatim}
+ [InterCharStretch=0.5pt]
+\end{verbatim}
+
+\item[CharRaise] 글ìžì˜ 세로 위치를
+ {\addhangulfontfeature{CharRaise=.3em} ì¡°ì ˆ}í•  수 있는 기능ì´ë‹¤.
+ ì´ë¡œì¨ ì£¼ë³€ì— ì‹ìžë˜ëŠ” 다른 글꼴과 조화를 ì´ë£¨ê²Œ 한다.%
+ \footnote{%
+ 플레ì¸í…ì—서는 |charraise=<dimen>|. }
+\begin{verbatim}
+ [CharRaise=2pt]
+\end{verbatim}
+ 세로쓰기ì—서는 모든 글ìžë“¤ì„ 지정한 ê°’ë§Œí¼ ì˜¤ë¥¸ìª½ìœ¼ë¡œ ì´ë™ì‹œí‚¨ë‹¤.
+ 세로쓰기ì—ì„œ ì´ ì˜µì…˜ ê°’ì„ ê³ ì •ê¸¸ì´{\small(가령 |pt| 단위)}ë¡œ 주면
+ í¬ê¸°ê°€ 다른 í°íŠ¸ë“¤ê°„ì— ì¤‘ì•™ì •ë ¬ì´ ì´ë£¨ì–´ì§„다.
+ 세로쓰기ì—ì„œ ì´ ì˜µì…˜ì„ ì£¼ì§€ 않으면 |0.5ex|ê°€ 기본값으로 ë™ìž‘한다.
+
+\item[RemoveClassicSpaces] 고문헌 ì¡°íŒì‹œì— CJK 글ìžë“¤ 사ì´ì˜ ê³µë°±ì„ ì—†ì• ì¤€ë‹¤.%
+ \footnote{%
+ 플레ì¸í…ì—서는 |+removeclassicspaces|. }
+
+\item[CompressPunctuations] CJK 구ë‘ì  {\small (ë‚«í‘œ 따위)}ì˜ ê¸€ìží­ì„
+ ë°˜ê°ìœ¼ë¡œ 만든다. v2.0부터는 사용ìžê°€ 지시하지 않는 í•œ ìžë™ìœ¼ë¡œ 글ìží­ì„
+ 줄여주지 않는다.%
+ \footnote{%
+ 플레ì¸í…ì—서는 |+compresspunctuations|. }
+ ì´ ì˜µì…˜ì€ |CharacterWidth=AlternateHalf| 내지 {\small (ì„¸ë¡œì“°ê¸°ì˜ ê²½ìš°)}
+ |Vertical=HalfMetrics|와 ê±°ì˜ ê°™ì€ ê¸°ëŠ¥ì„ í•œë‹¤.%
+ \footnote{%
+ 플레ì¸í…ì—서는 ê°ê° |+halt| ë° |+vhal|ì´ë‹¤. ì´ë“¤ê³¼ 완전 ë™ì¼í•˜ì§„
+ 않다. 가령 U+3002 (\char"3002) ì²˜ë¦¬ì˜ ê²½ìš°.}
+
+\item[Protrusion] 특정 글ìžê°€ í–‰ ëŒì— ì™”ì„ ë•Œ íŒë©´ 바깥으로 ëŒì–´ë‚´ëŠ”
+ 기능ì´ë‹¤. Lua\TeXì€ ê¸°ë³¸ê°’ìœ¼ë¡œ ì˜¨ì  ë°˜ì  ë“±ì„ ì™„ì „ 글ìžë‚´ë°€ê¸° 한다.
+ |Protrusion|ì€ |Protrusion=default|와 ê°™ì€ ëœ»ì´ë‹¤.%
+ \footnote{%
+ 플레ì¸í…ì—서는 |protrusion=default|. }
+ ìžì‹ ë§Œì˜ ì„¤ì •ì„ ë§Œë“¤ì–´ 지정할 수 있다.%
+ \footnote{%
+ default ì„¤ì •ì„ ê³ ì¹˜ëŠ” ë°©ë²•ì€ ì´ë¥¼í…Œë©´ 다ìŒê³¼ 같다:\par
+ \leftskip=3em\noindent
+ \cs{directlua{ fonts.protrusions.setups.default[0x201C] = { 1, 0 } }} }
+
+\item[Expansion] íŒë©´ì˜ ê· ì¼í•œ ì¡°íŒì„ 위해 글ìžë“¤ì„ 미세하게 늘ì´ê±°ë‚˜
+ 줄ì´ëŠ” 기능ì´ë‹¤. |Expansion|ì€ |Expansion=default|와 마찬가지 뜻ì´ë‹¤.%
+ \footnote{%
+ 플레ì¸í…ì—서는 |expansion=default|. }
+
+\end{description}
+
+\section{고문헌}\label{sec:classic}
+
+\def\analectstext{%
+å­æ›°ï¼šã€Œå­¸è€Œæ™‚習之,ä¸äº¦èªªä¹Žï¼Ÿæœ‰æœ‹è‡ªé æ–¹ä¾†ï¼Œä¸äº¦æ¨‚乎?人ä¸çŸ¥è€Œä¸æ…,
+ä¸äº¦å›å­ä¹Žï¼Ÿã€\par
+有å­æ›°ï¼šã€Œå…¶çˆ²äººä¹Ÿå­å¼Ÿï¼Œè€Œå¥½çŠ¯ä¸Šè€…,鮮矣ï¼ä¸å¥½çŠ¯ä¸Šï¼Œè€Œå¥½ä½œäº‚者,未之有也ï¼
+å›å­å‹™æœ¬ï¼Œæœ¬ç«‹è€Œé“生;å­å¼Ÿä¹Ÿè€…,其爲ä»ä¹‹æœ¬èˆ‡ï¼Ÿã€\par
+å­æ›°ï¼šã€Œå·§è¨€ä»¤è‰²ï¼Œé®®çŸ£ä»ï¼ã€\par
+曾å­æ›°ï¼šã€Œå¾æ—¥ä¸‰çœå¾èº«ï¼šçˆ²äººè¬€ï¼Œè€Œä¸å¿ ä¹Žï¼Ÿèˆ‡æœ‹å‹äº¤ï¼Œè€Œä¸ä¿¡ä¹Žï¼Ÿå‚³ï¼Œ
+ä¸ç¿’乎?ã€\par
+å­æ›°ï¼šã€Œé“åƒä¹˜ä¹‹åœ‹ï¼Œæ•¬äº‹è€Œä¿¡ï¼Œç¯€ç”¨è€Œæ„›äººï¼Œä½¿æ°‘以時。ã€\par
+å­æ›°ï¼šã€Œå¼Ÿå­å…¥å‰‡å­ï¼Œå‡ºå‰‡å¼Ÿï¼›è¬¹è€Œä¿¡ï¼Œæ±Žæ„›è¡†ï¼›è€Œè¦ªä»ï¼Œè¡Œæœ‰é¤˜åŠ›ï¼Œå‰‡ä»¥å­¸æ–‡ã€‚ã€
+}
+\begin{figure}
+ \centering
+ \fbox{\parbox{37em}{\typesetclassic\sffamily
+ \addhangulfontfeature{CompressPunctuations}
+ \analectstext
+ }}
+\caption{고문헌 ì¡°íŒ ë³´ê¸°. typesetclassic í™˜ê²½ì„ ì´ìš©í–ˆë‹¤.}\label{fig:gomun}
+\end{figure}
+
+고문헌 ì¡°íŒì„ 위해 |typesetclassic| í™˜ê²½ì„ ì œê³µí•œë‹¤.%
+\footnote{%
+ 플레ì¸í…ì—서는 (문서 ì „ì²´ì— ì ìš©í•˜ì§€ 않는다면 그룹 안ì—ì„œ)
+ \cs{typesetclassic}ì„ ì‚¬ìš©í•œë‹¤.
+ |japanese|, |chinese|, |Schinese|, |Tchinese|, |korean| ë”°ìœ„ì˜ í™˜ê²½ì€
+ 지난 ë²„ì „ê³¼ì˜ í˜¸í™˜ì„±ì„ ìœ„í•´ 당분간 제공ë˜ê³  ìžˆì„ ë¿ì´ë‹¤. }
+그림~\ref{fig:gomun} 참조.
+
+v2.0부터는 고문헌 ì¡°íŒì—ì„œ 한글^^b7í•œìžì™€ ì˜ë¬¸ìžê°€ 붙어 나오ë”ë¼ë„ ìžë™ìœ¼ë¡œ
+ê°„ê²©ì„ ìž¡ì•„ì£¼ì§€ 않으므로 ì´ëŸ° 경우 사용ìžê°€ |InterLatinCJK| 옵션ì„
+지정해야 한다.
+ë˜í•œ 불필요한 ê³µë°±ì´ ì˜¤ë”ë¼ë„ ìžë™ìœ¼ë¡œ 제거해주지 않으므로 ì´ëŸ° 경우
+사용ìžê°€ |RemoveClassicSpaces| ì˜µì…˜ì„ ì£¼ì–´ì•¼ 한다.
+
+|typesetmodern|ì€ ê³ ë¬¸í—Œ ì¡°íŒ ì¤‘ì— ìž ê¹ í˜„ëŒ€ 한국어를 ì¡°íŒí•˜ëŠ” ë° ì‚¬ìš©í•œë‹¤.%
+\footnote{%
+ 플레ì¸í…ì—서는 (문서 ì „ì²´ì— ì ìš©í•˜ì§€ 않는다면 그룹 안ì—ì„œ)
+ \cs{typesetmodern}ì„ ì‚¬ìš©í•œë‹¤. }
+
+고문헌 ì¡°íŒ ì¤‘ \luatexkoê°€ ê¸€ìž ì‚¬ì´ì— 삽입하는 미세간격ì„
+사용ìžê°€ ì˜{\small(zero)}으로 강제하기 위해선 \cs{inhibitglue} ëª…ë ¹ì„ ì´ìš©í•œë‹¤.
+
+\section{세로쓰기}\label{sec:verttype}
+
+세로쓰기는 í°íŠ¸ì˜ 고급 오픈타입 ì†ì„±ì„ ì´ìš©í•˜ë¯€ë¡œ í°íŠ¸ê°€ ì´ë¥¼ 지ì›í•´ì•¼
+가능한 ì¼ì´ë‹¤. í°íŠ¸ì— |Vertical=Alternates|와 |RawFeature=vertical| 옵션ì„
+준다.%
+\footnote{%
+ ì´ëŠ” 플레ì¸í…ì—ì„œ |vertical;+vert| ì˜µì…˜ì„ ì£¼ëŠ” 것과 같다.
+ 사실 |vertical|ì„ ì„ ì–¸í•˜ë©´ |vert|는 ìžë™ìœ¼ë¡œ 켜지ë„ë¡ í•´ ë‘었다. }\,%
+\footnote{%
+ |vmtx| 정보를 가지고 있지 ì•Šì€ ê¸€ê¼´ì€ ì„¸ë¡œì“°ê¸°ì— ì í•©ì¹˜ ì•Šì€ ê¸€ê¼´ì´ë‹¤.
+ |otfinfo -t <파ì¼>| 명령으로 ê¸€ê¼´ì— ë“¤ì–´ìžˆëŠ” í…Œì´ë¸” 정보를 ì•Œ 수 있다. }
+세로쓰기ì—ì„œ |CharRaise| ì˜µì…˜ì˜ íš¨ê³¼ì— ëŒ€í•´ì„œëŠ” ì œ\ref{sec:fontoption}ì ˆì„
+참조할 것.
+
+세로쓰기ì—서는 \cs{typesetclassic}ì˜ ì•„ì¢…ì¸ \cs{typesetvertical}ì´
+기본으로 셋팅ë˜ì–´ 있다. ì¼ì¢…ì˜ ê³ ë¬¸í—Œ ì¡°íŒìœ¼ë¡œ 보는 것ì´ë‹¤.
+
+\begin{figure}
+\framebox[\linewidth]{\begin{vertical}{19.6em}\sffamily
+ \addhangulfontfeature{Vertical=Alternates, RawFeature=vertical}
+ \linespread{1.5}\selectfont
+ \hunmintxt
+\end{vertical}}
+\caption{ì„¸ë¡œì“°ê¸°ì˜ ì˜ˆ. 박스 ë†’ì´ |20em|ì„ ì§€ì‹œí–ˆë‹¤.}\label{fig:vertical}
+\end{figure}
+
+\begin{figure}
+\framebox[\linewidth]{\begin{vertical}{18.62em}\sffamily
+ \addhangulfontfeature{Vertical=Alternates, RemoveClassicSpaces,
+ InterCharStretch=1pt, CompressPunctuations, RawFeature=vertical}
+ \linespread{1.5}\selectfont
+ \analectstext
+\end{vertical}}
+\caption{ì„¸ë¡œì“°ê¸°ì˜ ë‹¤ë¥¸ 예. 박스 ë†’ì´ |19em|ì„ ì§€ì‹œí–ˆë‹¤.
+ 글꼴옵션으로 |RemoveClassicSpaces|, |CompressPunctuations|와 ë”불어
+ |InterCharStretch=1pt|를 추가했다. ê³µë°±ì´ ì—†ëŠ” 문서는 ìžê°„늘ì´ê¸° ê°’ì„
+ 넉넉하게 주는 ê²ƒì´ ì¢‹ë‹¤.}\label{fig:vertical3}
+\end{figure}
+
+ë¬¸ì„œì˜ ì¼ë¶€ë¥¼ 세로쓰기하려면 \cs{begin{vertical}{<dimen>}} \ldots\ \cs{end{vertical}}
+í™˜ê²½ì„ ì´ìš©í•œë‹¤. |<dimen>|으로 세로쓰기 ë°•ìŠ¤ì˜ ë†’ì´ë¥¼ 지시한다.%
+\footnote{%
+ 플레ì¸í…ì—서는 \cs{vertical{<dimen>}} \ldots\ \cs{endvertical}. }
+그림~\ref{fig:vertical},~\ref{fig:vertical3} ë° \ref{fig:vertical2} 참조.
+
+문서 전체를 세로쓰기한다면 ì´ í™˜ê²½ì„ ì“°ëŠ” 대신
+\cs{verticaltypesetting} ëª…ë ¹ì„ ì „ì²˜ë¦¬ë¶€ì— ì„ ì–¸í•œë‹¤.
+ì´ë•Œ 면주는 가로로 ì‹ìžë˜ë©° 면주 í°íŠ¸ì˜ ì„¤ì •ì€ ì‚¬ìš©ìžì˜ 몫ì´ë‹¤.
+
+세로쓰기 ë„ì¤‘ì— ë¬¸ì„œì˜ ì¼ë¶€ë¥¼ 가로쓰기하려면
+\cs{begin{horizontal}{<dimen>}} \ldots\ \cs{end{horizontal}}
+í™˜ê²½ì„ ì´ìš©í•œë‹¤. |<dimen>|ì€ ê°€ë¡œì“°ê¸° ë°•ìŠ¤ì˜ ë„ˆë¹„ë¥¼ 지시한다.%
+\footnote{%
+ 플레ì¸í…ì—서는 \cs{horizontal{<dimen>}} \ldots\ \cs{endhorizontal}. }
+가로쓰기 ì˜ì—­ì˜ í°íŠ¸ ì„¤ì •ì€ ì‚¬ìš©ìžì˜ 몫ì´ë‹¤.%
+\footnote{í°íŠ¸ 지시는 |horizontal| 환경 안ì—ì„œ 행하는 ê²ƒì„ ê¶Œìž¥í•œë‹¤.}
+
+\begin{figure}
+\framebox[\linewidth]{\begin{vertical}{16.66em}\sffamily
+ \addhangulfontfeature{Vertical=Alternates, CharRaise=3.2pt,
+ CompressPunctuations, CharacterWidth=Full, RawFeature=vertical}
+ \parindent-1em\leftskip1em \linespread{1.5}\selectfont
+ \spaceskip=.5em plus.25em minus.125em
+ \noindent ë‹˜ì˜ ì¹¨ë¬µ(The Silent Beloved)
+ \smallbreak
+ \hfil\hfil 한 용 운\hfil
+ \bigbreak
+ ë‹˜ì€ ê°“ìŠ´ë‹ˆë‹¤ ì•„ì•„ 사랑하는나ì˜ë‹˜ì€ 갓슴니다\par
+ 푸른산빗ì„깨치고 단í’나무숩ì„향하야난 ì ì€ê¸¸ì„ 거러서 참어떨치고
+ 갓슴니다\par
+ 黃金ì˜ê½ƒê°€í‹° 굿고빗나든 옛盟誓는 차듸찬ë ëŒì´ë˜ì•¼ì„œ í•œìˆ¨ì˜ å¾®é¢¨ì—
+ 나러갓슴니다\par
+ ë‚ ì¹´ë¡œì€ ì²«ã€ˆí‚¤ì“°ã€‰ì˜è¿½æ†¶ì€ 나ì˜é‹å‘½ì˜æŒ‡é‡ì„ ëŒë„ˆë…¸ì½” 뒷거름처서 사러젓슴니다\par
+ \hellipsis\par
+ ì•„ì•„ 님ì€ê°“지마는 나는 님ì„보내지 아니하ì–슴니다\par
+ 제곡조를못ì´ê¸°ëŠ” 사랑ì˜ë…¸ëž˜ëŠ” 님ì˜æ²ˆé»˜ì„ 휩싸고ë”니다\par
+\end{vertical}}
+\caption{ì„¸ë¡œì“°ê¸°ì˜ ë˜ ë‹¤ë¥¸ 예. 박스 ë†’ì´ |17em|ì„ ì§€ì‹œí–ˆë‹¤.
+ Noto Sans CJK ê¸€ê¼´ì˜ ì„¸ë¡œì“°ê¸° ê³µë°±ì€ ì›ëž˜ |1em|,
+ 즉 ì „ê°í¬ê¸°ë¡œ 매우 í¬ê¸° 때문ì—, 여기서는 \cs{spaceskip} ëª…ë ¹ì„ ì´ìš©í•˜ì—¬
+ ë°˜ê° í¬ê¸°ë¡œ 강제했다.}\label{fig:vertical2}
+\end{figure}
+
+\section{드러냄표}\label{sec:dotemph}
+
+\cs{dotemph} 명령으로 \dotemph{드러냄표}%
+를 ì´ìš©í•œ 강조를 í•  수 있다. ê¸°ë³¸ì€ ê¸€ìž ìœ„ì— ì ì„ ì°ëŠ” 형태ì´ë‚˜
+다ìŒê³¼ ê°™ì´ ëª…ë ¹ì„ ì£¼ì–´ ê°œì¸ì ìœ¼ë¡œ 선호하는 기호를 드러냄표로 쓸 수
+있다.
+
+\medskip
+â‘ ~|\def\dotemphraise{0.4em }|: 드러냄표를 피강조 ê¸€ìž ìœ„ë¡œ ëŒì–´ì˜¬ë¦¬ëŠ” 길ì´
+
+â‘¡~|\def\dotemphchar{\bfseries ^^^^02d9}|: 드러냄표 기호 ìžì²´ë¥¼ ì •ì˜.
+
+\section{루비}\label{sec:ruby}
+
+루비를 달 수 있다. ruby 패키지가 ì´ë¯¸ 존재하지만 \luatexko와 ê¶í•©ì´ 잘
+맞지 ì•Šì•„ 새로 매í¬ë¡œë¥¼ 제공한다.
+\begin{quote}
+ \cs{ruby{漢字}{í•œìž}}\quad$\Rightarrow$\quad\ruby{漢字}{í•œìž}
+\end{quote}
+ì´ì²˜ëŸ¼ 글ìžë³„ë¡œ ë”°ë¡œ 루비를 달 필요가 없다. 관련 ì„¤ì •ì€ ë‹¤ìŒì²˜ëŸ¼
+한다.
+
+\medskip
+â‘ ~\cs{rubyfont}: 루비를 ì‹ìží•  í°íŠ¸ë¥¼ 지시해 둔다. ê¸°ë³¸ê°’ì€ í˜„ìž¬ í°íŠ¸%
+\footnote{%
+ 루비는 ê¸€ìž í¬ê¸°ê°€ 작기 ë•Œë¬¸ì— ë³¸ë¬¸ í°íŠ¸ë³´ë‹¤ 약간 êµµì€ í°íŠ¸ë¡œ
+ 지정하는 ê²ƒì´ ì¢‹ë‹¤. }
+
+â‘¡~|\def\rubysize{0.6}|: 루비 ê¸€ìž í¬ê¸°ë¥¼ 본문 ê¸€ìž í¬ê¸°ì— 대한 비율로
+지정%
+\footnote{%
+ 플레ì¸í…ì—서는 ë£¨ë¹„ì˜ ê¸€ê¼´í¬ê¸°ë¥¼ ë”°ë¡œ 조정해주지 않는다.
+ 사용ìžê°€ \cs{rubyfont}를 설정할 ë•Œ í¬ê¸°ë„ 함께 지시하ë„ë¡ í•œë‹¤.
+ 가령:\par
+ \leftskip=3em\noindent
+ |\\font\\rubyfont=UnBatang at \\rubysize em| }
+
+â‘¢~|\def\rubysep{0.1ex}|: 루비와 본문 ê¸€ìž ì‚¬ì´ì˜ ê°„ê²©ì„ ì§€ì •
+
+â‘£~\cs{rubynooverlap}: ë£¨ë¹„ì˜ í­ì´ 본문 글ìžì˜ í­ë³´ë‹¤ í´ ë•Œ 루비가 ì´ì›ƒ
+글ìžë“¤ 위로 ì‚져나가지 못하게 한다. 본문 글ìžì˜ íë¦„ì„ ì¤‘ì‹œí•˜ì—¬
+\cs{rubyoverlap}ì„ ê¸°ë³¸ê°’ìœ¼ë¡œ 하였으므로 ì´ëŠ” ë”°ë¡œ 선언할 필요가 없다.
+
+\medskip
+한편, ì—°ì†ëœ 본문 글ìžë“¤ì— ê°ê° í•œ 글ìžì”© 루비를 ë‹¬ê³ ìž í•œë‹¤ë©´
+\cs{xxruby{...}{...}} ëª…ë ¹ì„ ì‚¬ìš©í•œë‹¤. 글ìžë“¤ 사ì´ì— ì¤„ë°”ê¿ˆì´ í—ˆìš©ëœë‹¤.
+ë‘ ì¸ìžì˜ ê¸€ìž ìˆ˜ê°€ ë™ì¼í•´ì•¼ 한다.
+
+\section{밑줄긋기}\label{sec:uline}
+
+ulem 패키지가 \luatexko와 ê¶í•©ì´ 잘 맞지 ì•Šì•„{\small (ì¤„ë°”ê¿ˆì— ë¬¸ì œê°€ 있ìŒ)}
+ëª…ë ¹ì„ ë”°ë¡œ 제공한다.
+
+\def\RA{\>$\Rightarrow$\>}
+\begin{tabbing}
+ \cs{dotuline{ë°‘ì¤„ì„ ì ì„ ìœ¼ë¡œ 긋는다}}\quad\=$\Rightarrow$\quad\= \kill
+ \cs{uline{ë°‘ì¤„ì„ ê·¸ì„ ìˆ˜ 있다}}\RA\uline{ë°‘ì¤„ì„ ê·¸ì„ ìˆ˜ 있다}\\
+ \cs{sout{ì·¨ì†Œì„ ì„ ê·¸ì„ ìˆ˜ 있다}}\RA\sout{ì·¨ì†Œì„ ì„ ê·¸ì„ ìˆ˜ 있다}\\
+ \cs{uuline{ë°‘ì¤„ì„ ë‘ ì¤„ 긋는다}}\RA\uuline{ë°‘ì¤„ì„ ë‘ ì¤„ 긋는다}\\
+ \cs{xout{빗금으로 취소할 수 있다}}\RA\xout{빗금으로 취소할 수 있다}\\
+ \cs{uwave{물결표로 ë°‘ì¤„ì„ ì‚¼ëŠ”ë‹¤}}\RA\uwave{물결표로 ë°‘ì¤„ì„ ì‚¼ëŠ”ë‹¤}\\
+ \cs{dashuline{대시로 ë°‘ì¤„ì„ ì‚¼ëŠ”ë‹¤}}\RA\dashuline{대시로 ë°‘ì¤„ì„ ì‚¼ëŠ”ë‹¤}\\
+ \cs{dotuline{ë°‘ì¤„ì„ ì ì„ ìœ¼ë¡œ 긋는다}}\RA\dotuline{ë°‘ì¤„ì„ ì ì„ ìœ¼ë¡œ 긋는다}
+\end{tabbing}
+
+관련하여 ë‹¤ìŒ ì„¤ì •ì„ í•  수 있다.
+
+\medskip
+â‘ ~|\def\ulinedown{0.5ex}|: ë°‘ì¤„ì„ ë² ì´ìŠ¤ë¼ì¸ 아래로 ëŒì–´ë‚´ë¦¬ëŠ” ì •ë„
+
+â‘¡~|\def\ulinewidth{0.04em}|: ë°‘ì¤„ì˜ êµµê¸°
+
+\medskip
+사실 위 밑줄 ì–‘ì‹ë“¤ì„ 만드는 ë°ëŠ” ì˜ˆì™¸ì—†ì´ \cs{markoverwith} ëª…ë ¹ì´ ì‚¬ìš©ë˜ì—ˆë‹¤.
+ë”°ë¼ì„œ 사용ìžëŠ” ì´ë¥¼ ì´ìš©í•´ ì›í•˜ëŠ” ì–‘ì‹ì„ 만들 수 있다.
+가령 노란색 ë§ˆì»¤íŽœì„ í‰ë‚´ë‚´ë ¤ë©´,%
+\footnote{%
+ ì´ ëª…ë ¹ì˜ ì¸ìžë¡œ 들어갈 수 있는 ê²ƒì€ box와 ruleì— êµ­í•œëœë‹¤.
+ 예시ì—서는 박스를 넣었다.}\,%
+\footnote{%
+ 별표 ë¶™ì€ ëª…ë ¹ \cs{markoverwith*}는 \cs{xleaders}를 실행하고,
+ 예시처럼 별표가 없으면 \cs{cleaders}를 실행한다. }
+\begin{verbatim}
+ \def\ymarker{%
+ \markoverwith{%
+ \hbox{{\color{yellow!50}\vrule width 1pt height 9pt depth 2pt}}%
+ }}
+\end{verbatim}
+
+\def\ymarker{\markoverwith{%
+ \hbox{{\color{yellow!50}\vrule width 1pt height 9pt depth 2pt}}}}
+
+\cs{ymarker{ë…¸ëž€ìƒ‰ì„ ì¹ í•´ì„œ 강조한다}}\quad$\Rightarrow$\quad
+\ymarker{ë…¸ëž€ìƒ‰ì„ ì¹ í•´ì„œ 강조한다}.
+
+\section{ìžë™ì¡°ì‚¬}\label{sec:autojosa}
+
+ìžë™ì¡°ì‚¬ëŠ” \kotex ê³¼ ë™ì¼í•˜ê²Œ \cs{ì€} \cs{는} \cs{ì´} \cs{ê°€} \cs{ì„} \cs{를}
+\cs{와} \cs{ê³¼} \cs{ë¡œ} \cs{으로} \cs{ë¼} \cs{ì´ë¼} 따위를 사용한다.
+버전 1.3부터는 \cs{josaignoreparens=1}ì´ ì„ ì–¸ë˜ì–´ 있으면 ìžë™ì¡°ì‚¬ëŠ”
+\hemph{괄호 ë¶€ë¶„ì„ ê±´ë„ˆë›°ê³ } ê·¸ ì•ž 글ìžì— 매칭한다.
+|0|ì´ ì„ ì–¸ë˜ë©´ ì›ëž˜ ë°©ì‹ìœ¼ë¡œ ëŒì•„간다.
+\begin{quote}
+ \cs{josaignoreparens=1} \josaignoreparens=1 \\
+ |í™ê¸¸ë™(1992)\는|\quad$\Rightarrow$\quad í™ê¸¸ë™(1992)\는\\
+ |í™ê¸¸ë™(2001)\ë¡œ|\quad$\Rightarrow$\quad í™ê¸¸ë™(2001)\ë¡œ\par
+ \cs{josaignoreparens=0} \josaignoreparens=0 \\
+ |í™ê¸¸ë™(1992)\는|\quad$\Rightarrow$\quad í™ê¸¸ë™(1992)\는\\
+ |í™ê¸¸ë™(2001)\ë¡œ|\quad$\Rightarrow$\quad í™ê¸¸ë™(2001)\ë¡œ
+\end{quote}
+
+\section{루아 ëª¨ë“ˆì˜ ì œê±° ë° ë³µì›}\label{sec:luamodule}
+
+루아 코드 |luatexko.deactivateall()|ì€ ì´ìƒ 언급한 \luatexko ì˜ ê±°ì˜ ëª¨ë“ 
+ê¸°ëŠ¥ì„ ë¬´ë ¥í™”í•œë‹¤. |luatexko.reactivateall()|ì€ ì´ë¥¼ ë³µì›í•œë‹¤.%
+\footnote{ìˆ˜ì§ ëª¨ë“œ (문단과 문단 사ì´)ì—ì„œ 사용할 것.
+ ìˆ˜í‰ ëª¨ë“œì—서는 ì •ìƒìž‘ë™ì„ 보장하지 못한다.}
+다른 패키지와 충ëŒí•  ë•Œ ì‹œë„í•´ ë³¼ 수 있다.
+ì „ìžì˜ 함수ì—는 문ìžì—´ì„ ì¸ìžë¡œ 줄 ìˆ˜ë„ ìžˆëŠ”ë°, 해당하는 다른 패키지ì˜
+ëª¨ë“ˆë“¤ì„ ìž ì‹œ 제거할 수 있다.
+
+\section{ìˆ˜ì‹ í•œê¸€}\label{sec:mathhangul}
+
+\begin{quote}
+ |$가^{나^다}$|\quad$\Rightarrow\quad가^{나^다}$
+\end{quote}
+ìˆ˜ì‹ í•œê¸€ í°íŠ¸ë¥¼ 설정하면 ìˆ˜ì‹ ëª¨ë“œì—ì„œë„ í•œê¸€ì„ {\small(hboxë¡œ ê°ì‹¸ì§€ ì•Šê³ )}
+ì§ì ‘ 입력할 수 있다.%
+\footnote{%
+ 플레ì¸í…ì—서는 \cs{mathhangulfont=UnBatang}ê³¼ ê°™ì´ ì„¤ì •í•œë‹¤.
+ ë˜ëŠ” 좀 ë” ê·¸ëŸ´ë“¯í•˜ê²Œ 하려면:\par
+ \leftskip=3em\noindent
+ |\\font\\texthangul="Noto Sans CJK KR DemiLight" at 10pt|\\
+ |\\font\\scripthangul="Noto Sans CJK KR Regular" at 7pt|\\
+ |\\font\\scriptscripthangul="Noto Sans CJK KR Medium" at 5pt|\\
+ |\\setmathhangulfonts\\texthangul\\scripthangul\\scriptscripthangul| }
+v2.0부터는 ìžë™ìœ¼ë¡œ ìˆ˜ì‹ í•œê¸€ì„ ìž¡ì•„ì£¼ì§€ 않는다.
+\begin{verbatim}
+ \setmathhangulfont{Noto Sans CJK KR}[
+ SizeFeatures={
+ {Size=-6, Font=* Medium},
+ {Size=6-9, Font=* Regular},
+ {Size=9-, Font=* DemiLight},
+ } ]
+\end{verbatim}
+현재 한글만 쓸 수 있게 설정ë˜ì–´ 있다.
+í•œìžë„ 수ì‹ì— ì§ì ‘ 입력하려면 사용ìžëŠ”
+ë‹¤ìŒ ëª…ë ¹ìœ¼ë¡œ 유니코드 ë¸”ëŸ­ì„ ì¶”ê°€ 지정해야 한다.
+\begin{verbatim}
+ \setmathhangulblock{4E00}{9FC3}
+\end{verbatim}
+
+\section{한국어 항목 번호}\label{sec:hangulnums}
+
+\kotexê³¼ ë™ì¼í•˜ê²Œ 항목 번호를 한국어 기호로 ë¶™ì¼ ìˆ˜ 있다.%
+\footnote{%
+ \cs{jaso} \cs{gana} \cs{ojaso} \cs{ogana} \cs{pjaso} \cs{pgana}
+ \cs{onum} \cs{pnum} \cs{oeng} \cs{peng} \cs{hnum} \cs{Hnum}
+ \cs{hroman} \cs{hRoman} \cs{hNum} \cs{hanjanum} 따위를 사용한다. }
+
+\section{입력 변환}\label{sec:noramlize}
+
+\cs{luatexhangulnormalize=1}ì´ë¼ 지시하면 첫가ë ìžëª¨ë¥¼ 완성형 ìŒì ˆë¡œ,
+|2|ë¼ë©´ 완성형 ìŒì ˆì„ 첫가ë ìžëª¨ë¡œ ì¸ì½”딩 변환한다. |0|ì´ í• ë‹¹ë˜ë©´
+ì¸ì½”딩 변환 ê¸°ëŠ¥ì´ êº¼ì§„ë‹¤. \XeTeXì˜ \cs{XeTeXinputnormalization} 명령과
+유사하나, ì˜¤ì§ í•œê¸€ê³¼ ì¼ë¶€ í•œìžì— 대해서만 정규화가 ìž‘ë™í•  ë¿ì´ë‹¤.
+
+\section{UHC ìž…ë ¥ ì¸ì½”딩}\label{sec:uhcencoding}
+
+권장하지 않지만 불가피하게 ìž…ë ¥ ì¸ì½”ë”©ì´ UHC (Unified Hangul Code)%
+\footnote{%
+ CP949ë¼ê³ ë„ 하며 EUC-KRì„ í¬í•¨í•œë‹¤. }%
+ë¡œ ë˜ì–´ 있는 파ì¼ì„ 처리할 때는
+\cs{luatexuhcinputencoding=1}ì„ ì„ ì–¸í•œë‹¤.
+|0|ì„ í• ë‹¹í•˜ë©´ 다시 UTF-8 입력으로 간주한다.
+\XeTeXì˜ \cs{XeTeXinputencoding} 명령과 유사하나, ì˜¤ì§ í•œêµ­ì–´ 문ìžë§Œ 처리할 수
+있다.%
+\footnote{%
+ ìœˆë„ ìš´ì˜ì²´ì œì—ì„œì˜ í•œê¸€ 파ì¼ì´ë¦„ 불러오기 ê¸°ëŠ¥ì€ v2.0부터는 제공하지 않는다.
+ 대신 |luatex -cmdx ...|, |lualatex -cmdx ...|와 ê°™ì´ ì»´íŒŒì¼ì‹œ 명령행ì—
+ |-cmdx| ì˜µì…˜ì„ ì£¼ë©´ ëœë‹¤ê³  하니 테스트해 보시기 바란다. }
+\hfill \fboxsep=-\fboxrule \fbox{\vbox to 1em{\hbox to 1em{\hss}\vss}}
+
+\end{document}
diff --git a/macros/luatex/generic/luatexko/luatexko-normalize.lua b/macros/luatex/generic/luatexko/luatexko-normalize.lua
new file mode 100644
index 0000000000..97c2b0ccf8
--- /dev/null
+++ b/macros/luatex/generic/luatexko/luatexko-normalize.lua
@@ -0,0 +1,620 @@
+-- luatexko-normalize.lua
+--
+-- Copyright (c) 2013-2019 Dohyun Kim <nomos at ktug org>
+-- Soojin Nam <jsunam at gmail com>
+--
+-- This work may be distributed and/or modified under the
+-- conditions of the LaTeX Project Public License, either version 1.3c
+-- of this license or (at your option) any later version.
+-- The latest version of this license is in
+-- http://www.latex-project.org/lppl.txt
+-- and version 1.3c or later is part of all distributions of LaTeX
+-- version 2006/05/20 or later.
+
+luatexbase.provides_module({
+ name = "luatexko-normalize",
+ version = "2.4",
+ date = "2019/08/01",
+ author = "Dohyun Kim, Soojin Nam",
+ description = "Hangul normalization",
+ license = "LPPL v1.3+",
+})
+
+luatexko = luatexko or {}
+luatexko.normalize = luatexko.normalize or {}
+local luatexkonormalize = luatexko.normalize
+
+local utf8codes = utf8.codes
+local utf8char = utf8.char
+local tableinsert = table.insert
+local tableappend = table.append
+local tableunpack = table.unpack
+
+local chanjatohanja = {
+ [0xF900] = {0x8C48, 0xFE00},
+ [0xF901] = {0x66F4, 0xFE00},
+ [0xF902] = {0x8ECA, 0xFE00},
+ [0xF903] = {0x8CC8, 0xFE00},
+ [0xF904] = {0x6ED1, 0xFE00},
+ [0xF905] = {0x4E32, 0xFE00},
+ [0xF906] = {0x53E5, 0xFE00},
+ [0xF907] = {0x9F9C, 0xFE00},
+ [0xF908] = {0x9F9C, 0xFE01},
+ [0xF909] = {0x5951, 0xFE00},
+ [0xF90A] = {0x91D1, 0xFE00},
+ [0xF90B] = {0x5587, 0xFE00},
+ [0xF90C] = {0x5948, 0xFE00},
+ [0xF90D] = {0x61F6, 0xFE00},
+ [0xF90E] = {0x7669, 0xFE00},
+ [0xF90F] = {0x7F85, 0xFE00},
+ [0xF910] = {0x863F, 0xFE00},
+ [0xF911] = {0x87BA, 0xFE00},
+ [0xF912] = {0x88F8, 0xFE00},
+ [0xF913] = {0x908F, 0xFE00},
+ [0xF914] = {0x6A02, 0xFE00},
+ [0xF915] = {0x6D1B, 0xFE00},
+ [0xF916] = {0x70D9, 0xFE00},
+ [0xF917] = {0x73DE, 0xFE00},
+ [0xF918] = {0x843D, 0xFE00},
+ [0xF919] = {0x916A, 0xFE00},
+ [0xF91A] = {0x99F1, 0xFE00},
+ [0xF91B] = {0x4E82, 0xFE00},
+ [0xF91C] = {0x5375, 0xFE00},
+ [0xF91D] = {0x6B04, 0xFE00},
+ [0xF91E] = {0x721B, 0xFE00},
+ [0xF91F] = {0x862D, 0xFE00},
+ [0xF920] = {0x9E1E, 0xFE00},
+ [0xF921] = {0x5D50, 0xFE00},
+ [0xF922] = {0x6FEB, 0xFE00},
+ [0xF923] = {0x85CD, 0xFE00},
+ [0xF924] = {0x8964, 0xFE00},
+ [0xF925] = {0x62C9, 0xFE00},
+ [0xF926] = {0x81D8, 0xFE00},
+ [0xF927] = {0x881F, 0xFE00},
+ [0xF928] = {0x5ECA, 0xFE00},
+ [0xF929] = {0x6717, 0xFE00},
+ [0xF92A] = {0x6D6A, 0xFE00},
+ [0xF92B] = {0x72FC, 0xFE00},
+ [0xF92C] = {0x90CE, 0xFE00},
+ [0xF92D] = {0x4F86, 0xFE00},
+ [0xF92E] = {0x51B7, 0xFE00},
+ [0xF92F] = {0x52DE, 0xFE00},
+ [0xF930] = {0x64C4, 0xFE00},
+ [0xF931] = {0x6AD3, 0xFE00},
+ [0xF932] = {0x7210, 0xFE00},
+ [0xF933] = {0x76E7, 0xFE00},
+ [0xF934] = {0x8001, 0xFE00},
+ [0xF935] = {0x8606, 0xFE00},
+ [0xF936] = {0x865C, 0xFE00},
+ [0xF937] = {0x8DEF, 0xFE00},
+ [0xF938] = {0x9732, 0xFE00},
+ [0xF939] = {0x9B6F, 0xFE00},
+ [0xF93A] = {0x9DFA, 0xFE00},
+ [0xF93B] = {0x788C, 0xFE00},
+ [0xF93C] = {0x797F, 0xFE00},
+ [0xF93D] = {0x7DA0, 0xFE00},
+ [0xF93E] = {0x83C9, 0xFE00},
+ [0xF93F] = {0x9304, 0xFE00},
+ [0xF940] = {0x9E7F, 0xFE00},
+ [0xF941] = {0x8AD6, 0xFE00},
+ [0xF942] = {0x58DF, 0xFE00},
+ [0xF943] = {0x5F04, 0xFE00},
+ [0xF944] = {0x7C60, 0xFE00},
+ [0xF945] = {0x807E, 0xFE00},
+ [0xF946] = {0x7262, 0xFE00},
+ [0xF947] = {0x78CA, 0xFE00},
+ [0xF948] = {0x8CC2, 0xFE00},
+ [0xF949] = {0x96F7, 0xFE00},
+ [0xF94A] = {0x58D8, 0xFE00},
+ [0xF94B] = {0x5C62, 0xFE00},
+ [0xF94C] = {0x6A13, 0xFE00},
+ [0xF94D] = {0x6DDA, 0xFE00},
+ [0xF94E] = {0x6F0F, 0xFE00},
+ [0xF94F] = {0x7D2F, 0xFE00},
+ [0xF950] = {0x7E37, 0xFE00},
+ [0xF951] = {0x964B, 0xFE00},
+ [0xF952] = {0x52D2, 0xFE00},
+ [0xF953] = {0x808B, 0xFE00},
+ [0xF954] = {0x51DC, 0xFE00},
+ [0xF955] = {0x51CC, 0xFE00},
+ [0xF956] = {0x7A1C, 0xFE00},
+ [0xF957] = {0x7DBE, 0xFE00},
+ [0xF958] = {0x83F1, 0xFE00},
+ [0xF959] = {0x9675, 0xFE00},
+ [0xF95A] = {0x8B80, 0xFE00},
+ [0xF95B] = {0x62CF, 0xFE00},
+ [0xF95C] = {0x6A02, 0xFE01},
+ [0xF95D] = {0x8AFE, 0xFE00},
+ [0xF95E] = {0x4E39, 0xFE00},
+ [0xF95F] = {0x5BE7, 0xFE00},
+ [0xF960] = {0x6012, 0xFE00},
+ [0xF961] = {0x7387, 0xFE00},
+ [0xF962] = {0x7570, 0xFE00},
+ [0xF963] = {0x5317, 0xFE00},
+ [0xF964] = {0x78FB, 0xFE00},
+ [0xF965] = {0x4FBF, 0xFE00},
+ [0xF966] = {0x5FA9, 0xFE00},
+ [0xF967] = {0x4E0D, 0xFE00},
+ [0xF968] = {0x6CCC, 0xFE00},
+ [0xF969] = {0x6578, 0xFE00},
+ [0xF96A] = {0x7D22, 0xFE00},
+ [0xF96B] = {0x53C3, 0xFE00},
+ [0xF96C] = {0x585E, 0xFE00},
+ [0xF96D] = {0x7701, 0xFE00},
+ [0xF96E] = {0x8449, 0xFE00},
+ [0xF96F] = {0x8AAA, 0xFE00},
+ [0xF970] = {0x6BBA, 0xFE00},
+ [0xF971] = {0x8FB0, 0xFE00},
+ [0xF972] = {0x6C88, 0xFE00},
+ [0xF973] = {0x62FE, 0xFE00},
+ [0xF974] = {0x82E5, 0xFE00},
+ [0xF975] = {0x63A0, 0xFE00},
+ [0xF976] = {0x7565, 0xFE00},
+ [0xF977] = {0x4EAE, 0xFE00},
+ [0xF978] = {0x5169, 0xFE00},
+ [0xF979] = {0x51C9, 0xFE00},
+ [0xF97A] = {0x6881, 0xFE00},
+ [0xF97B] = {0x7CE7, 0xFE00},
+ [0xF97C] = {0x826F, 0xFE00},
+ [0xF97D] = {0x8AD2, 0xFE00},
+ [0xF97E] = {0x91CF, 0xFE00},
+ [0xF97F] = {0x52F5, 0xFE00},
+ [0xF980] = {0x5442, 0xFE00},
+ [0xF981] = {0x5973, 0xFE00},
+ [0xF982] = {0x5EEC, 0xFE00},
+ [0xF983] = {0x65C5, 0xFE00},
+ [0xF984] = {0x6FFE, 0xFE00},
+ [0xF985] = {0x792A, 0xFE00},
+ [0xF986] = {0x95AD, 0xFE00},
+ [0xF987] = {0x9A6A, 0xFE00},
+ [0xF988] = {0x9E97, 0xFE00},
+ [0xF989] = {0x9ECE, 0xFE00},
+ [0xF98A] = {0x529B, 0xFE00},
+ [0xF98B] = {0x66C6, 0xFE00},
+ [0xF98C] = {0x6B77, 0xFE00},
+ [0xF98D] = {0x8F62, 0xFE00},
+ [0xF98E] = {0x5E74, 0xFE00},
+ [0xF98F] = {0x6190, 0xFE00},
+ [0xF990] = {0x6200, 0xFE00},
+ [0xF991] = {0x649A, 0xFE00},
+ [0xF992] = {0x6F23, 0xFE00},
+ [0xF993] = {0x7149, 0xFE00},
+ [0xF994] = {0x7489, 0xFE00},
+ [0xF995] = {0x79CA, 0xFE00},
+ [0xF996] = {0x7DF4, 0xFE00},
+ [0xF997] = {0x806F, 0xFE00},
+ [0xF998] = {0x8F26, 0xFE00},
+ [0xF999] = {0x84EE, 0xFE00},
+ [0xF99A] = {0x9023, 0xFE00},
+ [0xF99B] = {0x934A, 0xFE00},
+ [0xF99C] = {0x5217, 0xFE00},
+ [0xF99D] = {0x52A3, 0xFE00},
+ [0xF99E] = {0x54BD, 0xFE00},
+ [0xF99F] = {0x70C8, 0xFE00},
+ [0xF9A0] = {0x88C2, 0xFE00},
+ [0xF9A1] = {0x8AAA, 0xFE01},
+ [0xF9A2] = {0x5EC9, 0xFE00},
+ [0xF9A3] = {0x5FF5, 0xFE00},
+ [0xF9A4] = {0x637B, 0xFE00},
+ [0xF9A5] = {0x6BAE, 0xFE00},
+ [0xF9A6] = {0x7C3E, 0xFE00},
+ [0xF9A7] = {0x7375, 0xFE00},
+ [0xF9A8] = {0x4EE4, 0xFE00},
+ [0xF9A9] = {0x56F9, 0xFE00},
+ [0xF9AA] = {0x5BE7, 0xFE01},
+ [0xF9AB] = {0x5DBA, 0xFE00},
+ [0xF9AC] = {0x601C, 0xFE00},
+ [0xF9AD] = {0x73B2, 0xFE00},
+ [0xF9AE] = {0x7469, 0xFE00},
+ [0xF9AF] = {0x7F9A, 0xFE00},
+ [0xF9B0] = {0x8046, 0xFE00},
+ [0xF9B1] = {0x9234, 0xFE00},
+ [0xF9B2] = {0x96F6, 0xFE00},
+ [0xF9B3] = {0x9748, 0xFE00},
+ [0xF9B4] = {0x9818, 0xFE00},
+ [0xF9B5] = {0x4F8B, 0xFE00},
+ [0xF9B6] = {0x79AE, 0xFE00},
+ [0xF9B7] = {0x91B4, 0xFE00},
+ [0xF9B8] = {0x96B8, 0xFE00},
+ [0xF9B9] = {0x60E1, 0xFE00},
+ [0xF9BA] = {0x4E86, 0xFE00},
+ [0xF9BB] = {0x50DA, 0xFE00},
+ [0xF9BC] = {0x5BEE, 0xFE00},
+ [0xF9BD] = {0x5C3F, 0xFE00},
+ [0xF9BE] = {0x6599, 0xFE00},
+ [0xF9BF] = {0x6A02, 0xFE02},
+ [0xF9C0] = {0x71CE, 0xFE00},
+ [0xF9C1] = {0x7642, 0xFE00},
+ [0xF9C2] = {0x84FC, 0xFE00},
+ [0xF9C3] = {0x907C, 0xFE00},
+ [0xF9C4] = {0x9F8D, 0xFE00},
+ [0xF9C5] = {0x6688, 0xFE00},
+ [0xF9C6] = {0x962E, 0xFE00},
+ [0xF9C7] = {0x5289, 0xFE00},
+ [0xF9C8] = {0x677B, 0xFE00},
+ [0xF9C9] = {0x67F3, 0xFE00},
+ [0xF9CA] = {0x6D41, 0xFE00},
+ [0xF9CB] = {0x6E9C, 0xFE00},
+ [0xF9CC] = {0x7409, 0xFE00},
+ [0xF9CD] = {0x7559, 0xFE00},
+ [0xF9CE] = {0x786B, 0xFE00},
+ [0xF9CF] = {0x7D10, 0xFE00},
+ [0xF9D0] = {0x985E, 0xFE00},
+ [0xF9D1] = {0x516D, 0xFE00},
+ [0xF9D2] = {0x622E, 0xFE00},
+ [0xF9D3] = {0x9678, 0xFE00},
+ [0xF9D4] = {0x502B, 0xFE00},
+ [0xF9D5] = {0x5D19, 0xFE00},
+ [0xF9D6] = {0x6DEA, 0xFE00},
+ [0xF9D7] = {0x8F2A, 0xFE00},
+ [0xF9D8] = {0x5F8B, 0xFE00},
+ [0xF9D9] = {0x6144, 0xFE00},
+ [0xF9DA] = {0x6817, 0xFE00},
+ [0xF9DB] = {0x7387, 0xFE01},
+ [0xF9DC] = {0x9686, 0xFE00},
+ [0xF9DD] = {0x5229, 0xFE00},
+ [0xF9DE] = {0x540F, 0xFE00},
+ [0xF9DF] = {0x5C65, 0xFE00},
+ [0xF9E0] = {0x6613, 0xFE00},
+ [0xF9E1] = {0x674E, 0xFE00},
+ [0xF9E2] = {0x68A8, 0xFE00},
+ [0xF9E3] = {0x6CE5, 0xFE00},
+ [0xF9E4] = {0x7406, 0xFE00},
+ [0xF9E5] = {0x75E2, 0xFE00},
+ [0xF9E6] = {0x7F79, 0xFE00},
+ [0xF9E7] = {0x88CF, 0xFE00},
+ [0xF9E8] = {0x88E1, 0xFE00},
+ [0xF9E9] = {0x91CC, 0xFE00},
+ [0xF9EA] = {0x96E2, 0xFE00},
+ [0xF9EB] = {0x533F, 0xFE00},
+ [0xF9EC] = {0x6EBA, 0xFE00},
+ [0xF9ED] = {0x541D, 0xFE00},
+ [0xF9EE] = {0x71D0, 0xFE00},
+ [0xF9EF] = {0x7498, 0xFE00},
+ [0xF9F0] = {0x85FA, 0xFE00},
+ [0xF9F1] = {0x96A3, 0xFE00},
+ [0xF9F2] = {0x9C57, 0xFE00},
+ [0xF9F3] = {0x9E9F, 0xFE00},
+ [0xF9F4] = {0x6797, 0xFE00},
+ [0xF9F5] = {0x6DCB, 0xFE00},
+ [0xF9F6] = {0x81E8, 0xFE00},
+ [0xF9F7] = {0x7ACB, 0xFE00},
+ [0xF9F8] = {0x7B20, 0xFE00},
+ [0xF9F9] = {0x7C92, 0xFE00},
+ [0xF9FA] = {0x72C0, 0xFE00},
+ [0xF9FB] = {0x7099, 0xFE00},
+ [0xF9FC] = {0x8B58, 0xFE00},
+ [0xF9FD] = {0x4EC0, 0xFE00},
+ [0xF9FE] = {0x8336, 0xFE00},
+ [0xF9FF] = {0x523A, 0xFE00},
+ [0xFA00] = {0x5207, 0xFE00},
+ [0xFA01] = {0x5EA6, 0xFE00},
+ [0xFA02] = {0x62D3, 0xFE00},
+ [0xFA03] = {0x7CD6, 0xFE00},
+ [0xFA04] = {0x5B85, 0xFE00},
+ [0xFA05] = {0x6D1E, 0xFE00},
+ [0xFA06] = {0x66B4, 0xFE00},
+ [0xFA07] = {0x8F3B, 0xFE00},
+ [0xFA08] = {0x884C, 0xFE00},
+ [0xFA09] = {0x964D, 0xFE00},
+ [0xFA0A] = {0x898B, 0xFE00},
+ [0xFA0B] = {0x5ED3, 0xFE00},
+ [0xFA2E] = {0x90DE, 0xFE00},
+ [0xFA2F] = {0x96B7, 0xFE00},
+}
+local jamotocjamo = {
+ ccho = {
+ [0x1100] = 0x3131,
+ [0x1101] = 0x3132,
+ -- [0x11AA] = 0x3133,
+ [0x1102] = 0x3134,
+ -- [0x11AC] = 0x3135,
+ -- [0x11AD] = 0x3136,
+ [0x1103] = 0x3137,
+ [0x1104] = 0x3138,
+ [0x1105] = 0x3139,
+ -- [0x11B0] = 0x313A,
+ -- [0x11B1] = 0x313B,
+ -- [0x11B2] = 0x313C,
+ -- [0x11B3] = 0x313D,
+ -- [0x11B4] = 0x313E,
+ -- [0x11B5] = 0x313F,
+ [0x111A] = 0x3140,
+ [0x1106] = 0x3141,
+ [0x1107] = 0x3142,
+ [0x1108] = 0x3143,
+ [0x1121] = 0x3144,
+ [0x1109] = 0x3145,
+ [0x110A] = 0x3146,
+ [0x110B] = 0x3147,
+ [0x110C] = 0x3148,
+ [0x110D] = 0x3149,
+ [0x110E] = 0x314A,
+ [0x110F] = 0x314B,
+ [0x1110] = 0x314C,
+ [0x1111] = 0x314D,
+ [0x1112] = 0x314E,
+ [0x1114] = 0x3165,
+ [0x1115] = 0x3166,
+ -- [0x11C7] = 0x3167,
+ -- [0x11C8] = 0x3168,
+ -- [0x11CC] = 0x3169,
+ -- [0x11CE] = 0x316A,
+ -- [0x11D3] = 0x316B,
+ -- [0x11D7] = 0x316C,
+ -- [0x11D9] = 0x316D,
+ [0x111C] = 0x316E,
+ -- [0x11DD] = 0x316F,
+ -- [0x11DF] = 0x3170,
+ [0x111D] = 0x3171,
+ [0x111E] = 0x3172,
+ [0x1120] = 0x3173,
+ [0x1122] = 0x3174,
+ [0x1123] = 0x3175,
+ [0x1127] = 0x3176,
+ [0x1129] = 0x3177,
+ [0x112B] = 0x3178,
+ [0x112C] = 0x3179,
+ [0x112D] = 0x317A,
+ [0x112E] = 0x317B,
+ [0x112F] = 0x317C,
+ [0x1132] = 0x317D,
+ [0x1136] = 0x317E,
+ [0x1140] = 0x317F,
+ [0x1147] = 0x3180,
+ [0x114C] = 0x3181,
+ -- [0x11F1] = 0x3182,
+ -- [0x11F2] = 0x3183,
+ [0x1157] = 0x3184,
+ [0x1158] = 0x3185,
+ [0x1159] = 0x3186,
+ },
+ cjung = {
+ [0x1161] = 0x314F,
+ [0x1162] = 0x3150,
+ [0x1163] = 0x3151,
+ [0x1164] = 0x3152,
+ [0x1165] = 0x3153,
+ [0x1166] = 0x3154,
+ [0x1167] = 0x3155,
+ [0x1168] = 0x3156,
+ [0x1169] = 0x3157,
+ [0x116A] = 0x3158,
+ [0x116B] = 0x3159,
+ [0x116C] = 0x315A,
+ [0x116D] = 0x315B,
+ [0x116E] = 0x315C,
+ [0x116F] = 0x315D,
+ [0x1170] = 0x315E,
+ [0x1171] = 0x315F,
+ [0x1172] = 0x3160,
+ [0x1173] = 0x3161,
+ [0x1174] = 0x3162,
+ [0x1175] = 0x3163,
+ -- [0x1160] = 0x3164,
+ [0x1184] = 0x3187,
+ [0x1185] = 0x3188,
+ [0x1188] = 0x3189,
+ [0x1191] = 0x318A,
+ [0x1192] = 0x318B,
+ [0x1194] = 0x318C,
+ [0x119E] = 0x318D,
+ [0x11A1] = 0x318E,
+ }
+}
+
+local function is_hangul (c)
+ return c >= 0xAC00 and c <= 0xD7A3
+end
+
+local function is_modern_cho (c)
+ return c >= 0x1100 and c <= 0x1112
+end
+
+local function is_modern_jung (c)
+ return c >= 0x1161 and c <= 0x1175
+end
+
+local function is_modern_jong (c)
+ return c >= 0x11A8 and c <= 0x11C2
+end
+
+local function is_old_jong (c)
+ return c >= 0x11C3 and c <= 0x11FF
+ or c >= 0xD7CB and c <= 0xD7FB
+end
+
+local function is_jongsong (c)
+ return is_modern_jong(c) or is_old_jong(c)
+end
+
+local function jamo2syllable (t) -- table -> integer
+ local cho, jung, jong = tableunpack(t)
+ local s = (cho - 0x1100) * 21
+ s = (s + jung - 0x1161) * 28
+ if jong then
+ s = s + jong - 0x11A7
+ end
+ return s + 0xAC00
+end
+
+local function syllable2jamo (s) -- integer -> table
+ local t = {}
+ s = s - 0xAC00
+ t[1] = s // 588 + 0x1100
+ t[2] = s % 588 // 28 + 0x1161
+ local jong = s % 28
+ if jong ~= 0 then
+ t[3] = jong + 0x11A7
+ end
+ return t
+end
+
+local function hanguldecompose (buffer)
+ local t = {}
+ for _, c in utf8codes(buffer) do
+ if is_hangul(c) then
+ tableappend(t, syllable2jamo(c))
+ else
+ tableinsert(t, c)
+ end
+ end
+ return utf8char(tableunpack(t))
+end
+
+-- LV | LVT, T -> L, V, T+
+local function flush_syllable_jong (t, s)
+ if #s == 2 then
+ tableappend(t, syllable2jamo( s[1] ))
+ tableinsert(t, s[2])
+ else
+ tableappend(t, s)
+ end
+ return t, {}
+end
+
+local function compose_hanguldecompose (buffer) -- string -> table
+ local t, s = {}, {}
+ for _, c in utf8codes(buffer) do
+ if #s == 1 and is_jongsong(c) then
+ tableinsert(s, c)
+ else
+ t, s = flush_syllable_jong(t, s)
+ tableinsert(is_hangul(c) and s or t, c)
+ end
+ end
+ t = flush_syllable_jong(t, s)
+ return t
+end
+
+-- L, V, [T & ^OT]? -> LV | LVT
+local function flush_syllable (t, s)
+ if #s == 2 or #s == 3 and is_modern_jong( s[3] ) then
+ tableinsert(t, jamo2syllable(s))
+ else
+ tableappend(t, s)
+ end
+ return t, {}
+end
+
+local function compose_modern_hangul (ot)
+ local t, s = {}, {}
+ for _, c in ipairs(ot) do
+ if #s == 1 and is_modern_jung(c) or #s >= 2 and is_jongsong(c) then
+ tableinsert(s, c)
+ else
+ t, s = flush_syllable(t, s)
+ tableinsert(is_modern_cho(c) and s or t, c)
+ end
+ end
+ t = flush_syllable(t, s)
+ return t
+end
+
+-- L, VF -> CL
+local function flush_cjamocho (t, s)
+ if #s == 2 then
+ tableinsert(t, jamotocjamo.ccho[ s[1] ])
+ else
+ tableappend(t, s)
+ end
+ return t, {}
+end
+
+local function compose_jamo_chosong (ot)
+ local t, s = {}, {}
+ for _, c in ipairs(ot) do
+ if #s == 1 and c == 0x1160 then
+ tableinsert(s, c)
+ else
+ t, s = flush_cjamocho(t, s)
+ tableinsert(jamotocjamo.ccho[c] and s or t, c)
+ end
+ end
+ t = flush_cjamocho(t, s)
+ return t
+end
+
+-- LF, V, ^T -> CV, ^T
+local function flush_cjamojung (t, s)
+ if #s == 2 then
+ tableinsert(t, jamotocjamo.cjung[ s[2] ])
+ else
+ tableappend(t, s)
+ end
+ return t, {}
+end
+
+local function compose_jamo_jungsong (ot)
+ local t, s = {}, {}
+ for _, c in ipairs(ot) do
+ if #s == 1 and jamotocjamo.cjung[c] or #s == 2 and is_jongsong(c) then
+ tableinsert(s, c)
+ else
+ t, s = flush_cjamojung(t, s)
+ tableinsert(c == 0x115F and s or t, c)
+ end
+ end
+ t = flush_cjamojung(t, s)
+ return t
+end
+
+-- CHJ -> HJ, VS
+local function flush_compat_hanja (t, s)
+ if #s == 1 then
+ tableappend(t, chanjatohanja[ s[1] ])
+ else
+ tableappend(t, s)
+ end
+ return t, {}
+end
+
+local function compose_compat_hanja (ot)
+ local t, s = {}, {}
+ for _, c in ipairs(ot) do
+ if #s == 1 and c >= 0xFE00 and c <= 0xFE02 then
+ tableinsert(s, c)
+ else
+ t, s = flush_compat_hanja(t, s)
+ tableinsert(chanjatohanja[c] and s or t, c)
+ end
+ end
+ t = flush_compat_hanja(t, s)
+ return t
+end
+
+local function hangulcompose (buffer)
+ local t = compose_hanguldecompose(buffer)
+ t = compose_modern_hangul(t)
+ t = compose_jamo_chosong (t)
+ t = compose_jamo_jungsong(t)
+ t = compose_compat_hanja (t)
+
+ return utf8char(tableunpack(t))
+end
+
+local loaded = false
+local add_to_callback = luatexbase.add_to_callback
+local remove_from_callback = luatexbase.remove_from_callback
+
+local function unload()
+ if loaded then
+ remove_from_callback('process_input_buffer', 'luatexko.hangul_normalize')
+ loaded = false
+ end
+end
+luatexkonormalize.unload = unload
+
+local function compose()
+ unload()
+ add_to_callback('process_input_buffer', hangulcompose, 'luatexko.hangul_normalize')
+ loaded = true
+end
+luatexkonormalize.compose = compose
+
+local function decompose()
+ unload()
+ add_to_callback('process_input_buffer', hanguldecompose, 'luatexko.hangul_normalize')
+ loaded = true
+end
+luatexkonormalize.decompose = decompose
diff --git a/macros/luatex/generic/luatexko/luatexko-uhc2utf8.lua b/macros/luatex/generic/luatexko/luatexko-uhc2utf8.lua
new file mode 100644
index 0000000000..82d11379cb
--- /dev/null
+++ b/macros/luatex/generic/luatexko/luatexko-uhc2utf8.lua
@@ -0,0 +1,128 @@
+-- luatexko-uhc2utf8.lua
+--
+-- Copyright (c) 2013-2019 Dohyun Kim <nomos at ktug org>
+-- Soojin Nam <jsunam at gmail com>
+--
+-- This work may be distributed and/or modified under the
+-- conditions of the LaTeX Project Public License, either version 1.3c
+-- of this license or (at your option) any later version.
+-- The latest version of this license is in
+-- http://www.latex-project.org/lppl.txt
+-- and version 1.3c or later is part of all distributions of LaTeX
+-- version 2006/05/20 or later.
+
+luatexbase.provides_module({
+ name = "luatexko-uhc2utf8",
+ version = "2.4",
+ date = "2019/08/01",
+ author = "Dohyun Kim, Soojin Nam",
+ description = "UHC (CP949) input encoding",
+ license = "LPPL v1.3+",
+})
+
+luatexko = luatexko or {}
+luatexko.uhc2utf8 = luatexko.uhc2utf8 or {}
+local luatexkouhc2utf8 = luatexko.uhc2utf8
+
+local kpse_find_file = kpse.find_file
+local add_to_callback = luatexbase.add_to_callback
+local remove_from_callback = luatexbase.remove_from_callback
+
+local function get_uhc_uni_table()
+ local t_uhc2ucs = {}
+ local file = kpse_find_file("KSCms-UHC-UCS2","cmap files")
+ if file then
+ file = io.open(file, "r")
+ while true do
+ local line = file:read"*line"
+ if not line then break end
+ local ea,eb,uni = line:match"<(%x+)>%s+<(%x+)>%s+<(%x+)>"
+ if ea and eb and uni then
+ ea, eb, uni = tonumber(ea,16),tonumber(eb,16),tonumber(uni,16)
+ for i=ea,eb do
+ t_uhc2ucs[i] = uni
+ uni = uni + 1
+ end
+ end
+ end
+ file:close()
+ end
+ return t_uhc2ucs
+end
+
+local t_uhc2ucs = t_uhc2ucs or get_uhc_uni_table()
+
+local function uhc_to_utf8 (buffer)
+ if not buffer then return end
+ if utf8.len(buffer) then return end -- check if buffer is already utf-8
+ buffer = buffer:gsub("([\129-\253])([\65-\254])", function(a, b)
+ local u = t_uhc2ucs[a:byte() * 256 + b:byte()]
+ if u then
+ return utf8.char(u)
+ end
+ end)
+ return buffer
+end
+
+local function startconvert ()
+ add_to_callback('process_input_buffer', uhc_to_utf8, 'luatexko.uhctoutf8', 1)
+end
+luatexkouhc2utf8.startconvert = startconvert
+
+local function stopconvert ()
+ remove_from_callback('process_input_buffer', 'luatexko.uhctoutf8')
+end
+luatexkouhc2utf8.stopconvert = stopconvert
+
+-----------------------------------------
+-- Hangul Windows OS uses CP949 filenames
+-----------------------------------------
+local function get_uni_uhc_table()
+ local t_ucs2uhc = {}
+ for i,v in pairs(t_uhc2ucs) do
+ t_ucs2uhc[v] = i
+ end
+ return t_ucs2uhc
+end
+
+local t_ucs2uhc = t_ucs2uhc or get_uni_uhc_table()
+
+local function utf8_to_uhc (name)
+ if not name then return end
+ local t = {}
+ for _, u in utf8.codes(name) do
+ if u >= 0xA1 and u <= 0xFFE6 then
+ local c = t_ucs2uhc[u]
+ if c then
+ t[#t + 1] = c // 256
+ t[#t + 1] = c % 256
+ else
+ t[#t + 1] = u
+ end
+ else
+ t[#t + 1] = u
+ end
+ end
+ return string.char(table.unpack(t))
+end
+
+local function uhc_find_file (file, ...)
+ local f = kpse_find_file(file, ...)
+ if f then return f end
+ f = utf8_to_uhc(file)
+ return f and kpse_find_file(f, ...)
+end
+
+local function start_uhc_filename ()
+ add_to_callback('find_read_file', function(id, name) return uhc_find_file(name) end, 'luatexko.touhc_findreadfile')
+ add_to_callback('find_image_file', uhc_find_file, 'luatexko.touhc_findimagefile')
+ kpse.find_file = uhc_find_file
+end
+luatexkouhc2utf8.start_uhc_filename = start_uhc_filename
+
+local function stop_uhc_filename ()
+ remove_from_callback('find_read_file', 'luatexko.touhc_findreadfile')
+ remove_from_callback('find_image_file', 'luatexko.touhc_findimagefile')
+ kpse.find_file = kpse_find_file
+end
+luatexkouhc2utf8.stop_uhc_filename = stop_uhc_filename
diff --git a/macros/luatex/generic/luatexko/luatexko.lua b/macros/luatex/generic/luatexko/luatexko.lua
new file mode 100644
index 0000000000..3ab4f18961
--- /dev/null
+++ b/macros/luatex/generic/luatexko/luatexko.lua
@@ -0,0 +1,1969 @@
+-- luatexko.lua
+--
+-- Copyright (c) 2013-2019 Dohyun Kim <nomos at ktug org>
+-- Soojin Nam <jsunam at gmail com>
+--
+-- This work may be distributed and/or modified under the
+-- conditions of the LaTeX Project Public License, either version 1.3c
+-- of this license or (at your option) any later version.
+-- The latest version of this license is in
+-- http://www.latex-project.org/lppl.txt
+-- and version 1.3c or later is part of all distributions of LaTeX
+-- version 2006/05/20 or later.
+
+luatexbase.provides_module {
+ name = 'luatexko',
+ date = '2019/08/01',
+ version = '2.4',
+ description = 'typesetting Korean with LuaTeX',
+ author = 'Dohyun Kim, Soojin Nam',
+ license = 'LPPL v1.3+',
+}
+
+luatexko = luatexko or {}
+local luatexko = luatexko
+
+local dimensions = node.dimensions
+local end_of_math = node.end_of_math
+local getglue = node.getglue
+local getnext = node.getnext
+local getprev = node.getprev
+local getproperty = node.getproperty
+local has_attribute = node.has_attribute
+local has_glyph = node.has_glyph
+local insert_after = node.insert_after
+local insert_before = node.insert_before
+local nodecopy = node.copy
+local nodecount = node.count
+local nodefree = node.free
+local nodeid = node.id
+local nodenew = node.new
+local noderemove = node.remove
+local nodeslide = node.slide
+local nodesubtype = node.subtype
+local nodewrite = node.write
+local rangedimensions = node.rangedimensions
+local setglue = node.setglue
+local setproperty = node.setproperty
+local unset_attribute = node.unset_attribute
+
+local fontcurrent = font.current
+local fontfonts = font.fonts
+local fontgetfont = font.getfont
+local getparameters = font.getparameters
+
+local texattribute = tex.attribute
+local texcount = tex.count
+local texset = tex.set
+local texsp = tex.sp
+
+local set_macro = token.set_macro
+
+local stringformat = string.format
+
+local tableconcat = table.concat
+local tableunpack = table.unpack
+
+local add_to_callback = luatexbase.add_to_callback
+local attributes = luatexbase.attributes
+local call_callback = luatexbase.call_callback
+local callback_descriptions = luatexbase.callback_descriptions
+local create_callback = luatexbase.create_callback
+local module_warning = luatexbase.module_warning
+local new_user_whatsit = luatexbase.new_user_whatsit
+local new_user_whatsit_id = luatexbase.new_user_whatsit_id
+local registernumber = luatexbase.registernumber
+local remove_from_callback = luatexbase.remove_from_callback
+
+local function warning (...)
+ return module_warning("luatexko", stringformat(...))
+end
+
+local dirid = nodeid"dir"
+local discid = nodeid"disc"
+local glueid = nodeid"glue"
+local glyphid = nodeid"glyph"
+local hlistid = nodeid"hlist"
+local kernid = nodeid"kern"
+local mathid = nodeid"math"
+local penaltyid = nodeid"penalty"
+local ruleid = nodeid"rule"
+local vlistid = nodeid"vlist"
+local whatsitid = nodeid"whatsit"
+local literal_whatsit = nodesubtype"pdf_literal"
+local user_whatsit = nodesubtype"user_defined"
+local directmode = 2
+local fontkern = 0
+local userkern = 1
+local italcorr = 3
+local lua_number = 100
+local lua_value = 108
+local spaceskip = 13
+local nohyphen = registernumber"l@nohyphenation" or -1 -- verbatim
+local langkor = registernumber"koreanlanguage" or 16383
+
+local hangulfontattr = attributes.luatexkohangulfontattr
+local hanjafontattr = attributes.luatexkohanjafontattr
+local fallbackfontattr = attributes.luatexkofallbackfontattr
+local autojosaattr = attributes.luatexkoautojosaattr
+local classicattr = attributes.luatexkoclassicattr
+local dotemphattr = attributes.luatexkodotemphattr
+local rubyattr = attributes.luatexkorubyattr
+
+local vert_classic = 1
+local SC_classic = 2
+
+local function is_hanja (c)
+ return c >= 0x3400 and c <= 0xA4C6
+ or c >= 0xF900 and c <= 0xFAD9
+ or c >= 0x20000 and c <= 0x2FFFD
+ or c >= 0x2E81 and c <= 0x2FD5
+end
+
+local function is_hangul (c)
+ return c >= 0xAC00 and c <= 0xD7A3
+end
+
+local function is_chosong (c)
+ return c >= 0x1100 and c <= 0x115F
+ or c >= 0xA960 and c <= 0xA97C
+end
+
+local function is_jungsong (c)
+ return c >= 0x1160 and c <= 0x11A7
+ or c >= 0xD7B0 and c <= 0xD7C6
+end
+
+local function is_jongsong (c)
+ return c >= 0x11A8 and c <= 0x11FF
+ or c >= 0xD7CB and c <= 0xD7FB
+end
+
+local hangul_tonemark = {
+ [0x302E] = true, [0x302F] = true,
+}
+
+local function is_compat_jamo (c)
+ return c >= 0x3131 and c <= 0x318E
+end
+
+local function is_unicode_var_sel (c)
+ return c >= 0xFE00 and c <= 0xFE0F
+ or c >= 0xE0100 and c <= 0xE01EF
+end
+
+local function is_cjk_combining (c)
+ return c >= 0x302A and c <= 0x302F
+ or c >= 0x3099 and c <= 0x309C
+ or c >= 0xFF9E and c <= 0xFF9F
+ or is_unicode_var_sel(c)
+end
+
+local function is_noncjk_char (c)
+ return c >= 0x30 and c <= 0x39
+ or c >= 0x41 and c <= 0x5A
+ or c >= 0x61 and c <= 0x7A
+ or c >= 0xC0 and c <= 0xD6
+ or c >= 0xD8 and c <= 0xF6
+ or c >= 0xF8 and c <= 0x10FC
+ or c >= 0x1200 and c <= 0x1FFE
+ or c >= 0xA4D0 and c <= 0xA877
+ or c >= 0xAB01 and c <= 0xABBF
+ or c >= 0xFB00 and c <= 0xFDFD
+ or c >= 0xFE70 and c <= 0xFEFC
+end
+
+local function is_kana (c)
+ return c >= 0x3041 and c <= 0x3096
+ or c >= 0x30A1 and c <= 0x30FA
+ or c >= 0x31F0 and c <= 0x31FF
+ or c >= 0xFF66 and c <= 0xFF6F
+ or c >= 0xFF71 and c <= 0xFF9D
+ or c == 0x309F or c == 0x30FF
+ or c >= 0x1B000 and c <= 0x1B16F
+end
+
+local function is_hangul_jamo (c)
+ return is_hangul(c)
+ or is_compat_jamo(c)
+ or is_chosong(c)
+ or is_jungsong(c)
+ or is_jongsong(c)
+end
+
+local stretch_f = 5/100 -- should be consistent for ruby
+
+local function get_font_data (fontid)
+ return fontgetfont(fontid) or fontfonts[fontid] or {}
+end
+
+local function get_font_param (f, key)
+ local t
+ if type(f) == "number" then
+ t = getparameters(f)
+ if t and t[key] then
+ return t[key]
+ end
+ f = get_font_data(f)
+ end
+ if type(f) == "table" then
+ t = f.parameters
+ return t and t[key]
+ end
+end
+
+local function get_en_size (f)
+ local quad = get_font_param(f, "quad")
+ return quad and quad/2 or 327680
+end
+
+local function char_in_font(fontdata, char)
+ if type(fontdata) == "number" then
+ fontdata = get_font_data(fontdata)
+ end
+ if fontdata.characters then
+ return fontdata.characters[char]
+ end
+end
+
+local function option_in_font (fontdata, optionname)
+ if type(fontdata) == "number" then
+ fontdata = get_font_data(fontdata)
+ end
+ if fontdata.shared then
+ return fontdata.shared.features[optionname]
+ end
+end
+
+local function my_node_props (n)
+ local t = getproperty(n)
+ if not t then
+ t = {}
+ setproperty(n, t)
+ end
+ t.luatexko = t.luatexko or {}
+ return t.luatexko
+end
+
+-- font fallback
+
+local force_hangul = {
+ [0x21] = true, -- !
+ [0x27] = true, -- '
+ [0x28] = true, -- (
+ [0x29] = true, -- )
+ [0x2C] = true, -- ,
+ [0x2E] = true, -- .
+ [0x3A] = true, -- :
+ [0x3B] = true, -- ;
+ [0x3F] = true, -- ?
+ [0x60] = true, -- `
+ [0xB7] = true, -- ·
+ [0x2014] = true, -- —
+ [0x2015] = true, -- ―
+ [0x2018] = true, -- ‘
+ [0x2019] = true, -- ’
+ [0x201C] = true, -- “
+ [0x201D] = true, -- â€
+ [0x2026] = true, -- …
+ [0x203B] = true, -- ※
+}
+luatexko.forcehangulchars = force_hangul
+
+local forcehf_f, forcehf_id = new_user_whatsit("forcehf","luatexko")
+
+local function update_force_hangul (value)
+ local what = forcehf_f()
+ what.type = lua_value -- function
+ what.value = value
+ nodewrite(what)
+end
+luatexko.updateforcehangul = update_force_hangul
+
+local active_processes = {}
+
+local char_font_options = {
+ hangulspaceskip = {},
+ intercharacter = {},
+ intercharstretch = {},
+ interhangul = {},
+ interlatincjk = {},
+ tonemarkwidth = {},
+}
+
+local function hangul_space_skip (curr, newfont)
+ if curr.lang ~= nohyphen then
+ local n = getnext(curr)
+ if n and n.id == glueid and n.subtype == spaceskip then
+ local params = getparameters(curr.font)
+ local oldwd, oldst, oldsh, oldsto, oldsho = getglue(n)
+ if params
+ and oldwd == params.space
+ and oldst == params.space_stretch
+ and oldsh == params.space_shrink
+ and oldsto == 0
+ and oldsho == 0 then -- not user's spaceskip
+
+ local newwd = char_font_options.hangulspaceskip[newfont]
+ if newwd == nil then
+ local newsp = nodecopy(curr)
+ newsp.char, newsp.font = 32, newfont
+ newsp = nodes.simple_font_handler(newsp)
+ newwd = newsp and newsp.width or false
+ if newwd then
+ newwd = { texsp(newwd), texsp(newwd/2), texsp(newwd/3) }
+ end
+ char_font_options.hangulspaceskip[newfont] = newwd
+ if newsp then
+ nodefree(newsp)
+ end
+ end
+ if newwd then
+ setglue(n, newwd[1], newwd[2], newwd[3])
+ end
+ end
+ end
+ end
+end
+
+local function process_fonts (head)
+ local curr = head
+ while curr do
+ local id = curr.id
+ if id == glyphid then
+ local props = my_node_props(curr)
+ if not props.unicode then
+
+ local c = curr.char
+
+ if is_cjk_combining(c) then
+ local p = getprev(curr)
+ if p.id == glyphid and curr.font ~= p.font then
+ hangul_space_skip(curr, p.font)
+ curr.font = p.font
+ end
+
+ if not active_processes.reorderTM and
+ hangul_tonemark[c] and
+ option_in_font(curr.font, "script") == "hang" then
+ luatexko.activate("reorderTM") -- activate reorderTM here
+ active_processes.reorderTM = true
+ end
+
+ else
+ local hf = has_attribute(curr, hangulfontattr) or false
+ local hjf = has_attribute(curr, hanjafontattr) or false
+ local fontdata = get_font_data(curr.font)
+ local format = fontdata.format
+ local encode = fontdata.encodingbytes
+ local widefont = encode == 2 or format == "opentype" or format == "truetype"
+ if hf and widefont and force_hangul[c] and curr.lang ~= nohyphen then
+ curr.font = hf
+ elseif hf and luatexko.hangulbyhangulfont and is_hangul_jamo(c) then
+ hangul_space_skip(curr, hf)
+ curr.font = hf
+ elseif hjf and luatexko.hanjabyhanjafont and is_hanja(c) then
+ hangul_space_skip(curr, hjf)
+ curr.font = hjf
+ elseif not char_in_font(fontdata, c) then
+ local fbf = has_attribute(curr, fallbackfontattr) or false
+ for _,f in ipairs{ hf, hjf, fbf } do
+ if f and char_in_font(f, c) then
+ hangul_space_skip(curr, f)
+ curr.font = f
+ break
+ end
+ end
+ end
+ end
+
+ props.unicode = c
+ end
+ elseif id == discid then
+ curr.pre = process_fonts(curr.pre)
+ curr.post = process_fonts(curr.post)
+ curr.replace = process_fonts(curr.replace)
+ elseif id == mathid then
+ curr = end_of_math(curr)
+ elseif id == whatsitid
+ and curr.subtype == user_whatsit
+ and curr.user_id == forcehf_id
+ and curr.type == lua_value then
+
+ local value = curr.value
+ if type(value) == "function" then
+ value()
+ end
+ end
+ curr = getnext(curr)
+ end
+ return head
+end
+
+-- linebreak
+
+local intercharclass = { [0] =
+ { [0] = nil, {1,1}, nil, {.5,.5} },
+ { [0] = nil, nil, nil, {.5,.5} },
+ { [0] = {1,1}, {1,1}, nil, {.5,.5}, nil, {1,1}, {1,1} },
+ { [0] = {.5,.5},{.5,.5},{.5,.5},{1,.5}, {.5,.5},{.5,.5},{.5,.5} },
+ { [0] = {1,0}, {1,0}, nil, {1.5,.5},nil, {1,0}, {1,0} },
+ { [0] = nil, {1,1}, nil, {.5,.5} },
+ { [0] = {1,1}, {1,1}, nil, {.5,.5} },
+}
+
+local charclass = setmetatable({
+ [0x2018] = 1, [0x201C] = 1, [0x2329] = 1, [0x3008] = 1,
+ [0x300A] = 1, [0x300C] = 1, [0x300E] = 1, [0x3010] = 1,
+ [0x3014] = 1, [0x3016] = 1, [0x3018] = 1, [0x301A] = 1,
+ [0x301D] = 1, [0xFE17] = 1, [0xFE35] = 1, [0xFE37] = 1,
+ [0xFE39] = 1, [0xFE3B] = 1, [0xFE3D] = 1, [0xFE3F] = 1,
+ [0xFE41] = 1, [0xFE43] = 1, [0xFE47] = 1, [0xFF08] = 1,
+ [0xFF3B] = 1, [0xFF5B] = 1, [0xFF5F] = 1, [0xFF62] = 1,
+ --
+ [0x2019] = 2, [0x201D] = 2, [0x232A] = 2, [0x3001] = 2,
+ [0x3009] = 2, [0x300B] = 2, [0x300D] = 2, [0x300F] = 2,
+ [0x3011] = 2, [0x3015] = 2, [0x3017] = 2, [0x3019] = 2,
+ [0x301B] = 2, [0x301E] = 2, [0x301F] = 2, [0xFE10] = 2,
+ [0xFE11] = 2, [0xFE18] = 2, [0xFE36] = 2, [0xFE38] = 2,
+ [0xFE3A] = 2, [0xFE3C] = 2, [0xFE3E] = 2, [0xFE40] = 2,
+ [0xFE42] = 2, [0xFE44] = 2, [0xFE48] = 2, [0xFF09] = 2,
+ [0xFF0C] = 2, [0xFF3D] = 2, [0xFF5D] = 2, [0xFF60] = 2,
+ [0xFF63] = 2, [0xFF64] = 2,
+ --
+ [0x00B7] = 3, [0x30FB] = 3, [0xFF1A] = 3, [0xFF1B] = 3,
+ [0xFF65] = 3,
+ --
+ [0x3002] = 4, [0xFE12] = 4, [0xFF0E] = 4, [0xFF61] = 4,
+ --
+ [0x2015] = 5, [0x2025] = 5, [0x2026] = 5, [0xFE19] = 5,
+ [0xFE30] = 5, [0xFE31] = 5,
+ --
+ [0xFE15] = 6, [0xFE16] = 6, [0xFF01] = 6, [0xFF1F] = 6,
+}, { __index = function() return 0 end })
+
+local SC_charclass = setmetatable({
+ [0xFF01] = 4, [0xFF1A] = 4, [0xFF1B] = 4, [0xFF1F] = 4,
+}, { __index = charclass })
+
+local vert_charclass = setmetatable({
+ [0xFF1A] = 5, -- 0xFE13
+ [0xFF1B] = 5, -- 0xFE14
+}, { __index = charclass })
+
+local function get_char_class (c, classic)
+ if classic == vert_classic then
+ return vert_charclass[c]
+ elseif classic == SC_classic then
+ return SC_charclass[c]
+ end
+ return charclass[c]
+end
+
+local breakable_after = setmetatable({
+ [0x21] = true, [0x22] = true, [0x25] = true, [0x27] = true,
+ [0x29] = true, [0x2C] = true, [0x2D] = true, [0x2E] = true,
+ [0x3A] = true, [0x3B] = true, [0x3E] = true, [0x3F] = true,
+ [0x5D] = true, [0x7D] = true, [0x7E] = true, [0xBB] = true,
+ [0x2013] = true, [0x2014] = true, [0x25A1] = true, [0x25CB] = true,
+ [0x2E80] = true, [0x3003] = true, [0x3005] = true, [0x3007] = true,
+ [0x301C] = true, [0x3035] = true, [0x303B] = true, [0x303C] = true,
+ [0x309D] = true, [0x309E] = true, [0x30A0] = true, [0x30FC] = true,
+ [0x30FD] = true, [0x30FE] = true, [0xFE13] = true, [0xFE14] = true,
+ [0xFE32] = true, [0xFE50] = true, [0xFE51] = true, [0xFE52] = true,
+ [0xFE54] = true, [0xFE55] = true, [0xFE57] = true, [0xFE57] = true,
+ [0xFE58] = true, [0xFE5A] = true, [0xFE5C] = true, [0xFE5E] = true,
+ [0xFF1E] = true, [0xFF5E] = true, [0xFF70] = true,
+},{ __index = function (_,c)
+ return is_hangul_jamo(c) and not is_chosong(c)
+ or is_noncjk_char(c)
+ or is_hanja(c)
+ or is_cjk_combining(c)
+ or is_kana(c)
+ or charclass[c] >= 2
+end })
+luatexko.breakableafter = breakable_after
+
+local breakable_before = setmetatable({
+ [0x28] = true, [0x3C] = true, [0x5B] = true, [0x60] = true,
+ [0x7B] = true, [0xAB] = true, [0x25A1] = true, [0x25CB] = true,
+ [0x3007] = true, [0xFE59] = true, [0xFE5B] = true, [0xFE5D] = true,
+ [0xFF1C] = true,
+ -- small kana
+ [0x3041] = 1000, [0x3043] = 1000, [0x3045] = 1000, [0x3047] = 1000,
+ [0x3049] = 1000, [0x3063] = 1000, [0x3083] = 1000, [0x3085] = 1000,
+ [0x3087] = 1000, [0x308E] = 1000, [0x3095] = 1000, [0x3096] = 1000,
+ [0x30A1] = 1000, [0x30A3] = 1000, [0x30A5] = 1000, [0x30A7] = 1000,
+ [0x30A9] = 1000, [0x30C3] = 1000, [0x30E3] = 1000, [0x30E5] = 1000,
+ [0x30E7] = 1000, [0x30EE] = 1000, [0x30F5] = 1000, [0x30F6] = 1000,
+ [0x31F0] = 1000, [0x31F1] = 1000, [0x31F2] = 1000, [0x31F3] = 1000,
+ [0x31F4] = 1000, [0x31F5] = 1000, [0x31F6] = 1000, [0x31F7] = 1000,
+ [0x31F8] = 1000, [0x31F9] = 1000, [0x31FA] = 1000, [0x31FB] = 1000,
+ [0x31FC] = 1000, [0x31FD] = 1000, [0x31FE] = 1000, [0x31FF] = 1000,
+ [0xFF67] = 1000, [0xFF68] = 1000, [0xFF69] = 1000, [0xFF6A] = 1000,
+ [0xFF6B] = 1000, [0xFF6C] = 1000, [0xFF6D] = 1000, [0xFF6E] = 1000,
+ [0xFF6F] = 1000, [0x1B150] = 1000, [0x1B151] = 1000, [0x1B152] = 1000,
+ [0x1B164] = 1000, [0x1B165] = 1000, [0x1B166] = 1000, [0x1B167] = 1000,
+},{ __index = function(_,c)
+ return is_hangul(c)
+ or is_compat_jamo(c)
+ or is_chosong(c)
+ or is_hanja(c)
+ or is_kana(c)
+ or charclass[c] == 1
+end
+})
+luatexko.breakablebefore = breakable_before
+
+local allowbreak_false_nodes = {
+ [hlistid] = true,
+ [vlistid] = true,
+ [ruleid] = true,
+ [discid] = true,
+ [glueid] = true,
+ [penaltyid] = true,
+}
+
+local function is_blocking_node (curr)
+ local id, subtype = curr.id, curr.subtype
+ return allowbreak_false_nodes[id] or id == kernid and subtype == userkern
+end
+
+local function ruby_char_font (rb)
+ local n = has_glyph(rb.list)
+ if n then
+ local c, f = my_node_props(n).unicode or n.char, n.font
+ if is_chosong(c) or hangul_tonemark[c] then
+ c = 0xAC00
+ end
+ return c, f
+ end
+end
+
+local function hbox_ini_char_font (box)
+ local curr = box.list
+ while curr do
+ local id = curr.id
+ if id == glyphid then
+ local c = my_node_props(curr).unicode or curr.char
+ if c and not is_cjk_combining(c) then
+ return c, curr.font
+ end
+ elseif id == hlistid and curr.list then
+ return hbox_ini_char_font(curr)
+ elseif is_blocking_node(curr) then
+ return
+ end
+ curr = getnext(curr)
+ end
+end
+
+local function hbox_fin_char_font (box)
+ local curr = nodeslide(box.list)
+ while curr do
+ local id = curr.id
+ if id == glyphid then
+ local c = my_node_props(curr).unicode or curr.char
+ if c and not is_cjk_combining(c) then
+ return c, curr.font
+ end
+ elseif id == hlistid and curr.list then
+ return hbox_fin_char_font(curr)
+ elseif is_blocking_node(curr) then
+ return
+ end
+ curr = getprev(curr)
+ end
+end
+
+local function get_actualtext (curr)
+ local actual = my_node_props(curr).startactualtext
+ if type(actual) == "table" then
+ return actual[0], actual[1], actual[#actual]
+ end
+end
+
+local function goto_end_actualtext (curr)
+ local n = getnext(curr)
+ while n do
+ if n.id == whatsitid
+ and n.mode == directmode
+ and my_node_props(n).endactualtext then
+ curr = n
+ break
+ end
+ n = getnext(n)
+ end
+ return curr
+end
+
+local function fontdata_opt_dim (fd, optname)
+ local dim = option_in_font(fd, optname)
+ if dim then
+ local m, u = dim:match"^(.+)(e[mx])%s*$"
+ if m and u then
+ if u == "em" then
+ dim = m * fd.parameters.quad
+ else
+ dim = m * fd.parameters.x_height
+ end
+ else
+ dim = texsp(dim)
+ end
+ return dim
+ end
+end
+
+local function get_font_opt_dimen (fontid, optionname)
+ local t = char_font_options[optionname]
+ local dim = t and t[fontid]
+ if dim == nil then
+ local fd = get_font_data(fontid)
+ dim = fontdata_opt_dim(fd, optionname)
+ t[fontid] = dim or false -- cache
+ end
+ return dim
+end
+
+local function insert_glue_before (head, curr, par, br, brb, classic, ict, dim, fid)
+ local pn = nodenew(penaltyid)
+ if not br then
+ pn.penalty = 10000
+ elseif type(brb) == "number" then
+ pn.penalty = brb
+ elseif par and nodecount(glyphid, curr) <= 2 then
+ pn.penalty = 1000 -- supress orphan
+ else
+ pn.penalty = 50
+ end
+
+ dim = dim or 0
+ local gl = nodenew(glueid)
+ local en = get_en_size(fid)
+ if ict then
+ en = classic and en or en/4
+ setglue(gl, en * ict[1] + dim, nil, en * ict[2])
+ else
+ local str = get_font_opt_dimen(fid, "intercharstretch") or stretch_f*en
+ setglue(gl, dim, str, str*0.6)
+ end
+
+ head = insert_before(head, curr, pn)
+ return insert_before(head, curr, gl)
+end
+
+local function maybe_linebreak (head, curr, pc, pcl, cc, old, fid, par)
+ local ccl = get_char_class(cc, old)
+ if pc and cc and curr.lang ~= nohyphen then
+ local ict = intercharclass[pcl][ccl]
+ local brb = breakable_before[cc]
+ local br = brb and breakable_after[pc]
+ local dim = get_font_opt_dimen(fid, "intercharacter")
+ if ict or br or dim and (pcl >= 1 or ccl >= 1) then
+ head = insert_glue_before(head, curr, par, br, brb, old, ict, dim, fid)
+ end
+ end
+ return head, cc, ccl
+end
+
+local function process_linebreak (head, par)
+ local curr, pc, pcl = head, false, 0
+ while curr do
+ local id = curr.id
+ if id == glyphid then
+ local c = my_node_props(curr).unicode or curr.char
+ if c and not is_unicode_var_sel(c) then
+ local old = has_attribute(curr, classicattr)
+ head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, c, old, curr.font, par)
+ end
+
+ elseif id == hlistid and curr.list then
+ local old = has_attribute(curr, classicattr)
+ if has_attribute(curr, rubyattr) then
+ local c, f = ruby_char_font(curr) -- rubybase
+ if c and f then
+ head, pc, pcl = maybe_linebreak(head, curr, pc, pcl, c, old, f, par)
+ else
+ pc, pcl = false, 0
+ end
+ else
+ local c, f = hbox_ini_char_font(curr)
+ if c and f then
+ head = maybe_linebreak(head, curr, pc, pcl, c, old, f, par)
+ end
+ pc = hbox_fin_char_font(curr)
+ pcl = pc and get_char_class(pc, old) or 0
+ end
+
+ elseif id == whatsitid and curr.mode == directmode then
+ local glyf, c, fin = get_actualtext(curr)
+ if c and fin and glyf then
+ local old = has_attribute(glyf, classicattr)
+ head = maybe_linebreak(head, curr, pc, pcl, c, old, glyf.font, par)
+ pc, pcl, curr = fin, 0, goto_end_actualtext(curr)
+ end
+
+ elseif id == mathid then
+ pc, pcl, curr = 0x30, 0, end_of_math(curr)
+ elseif id == dirid then
+ pc, pcl = curr.dir:sub(1,1) == "-" and 0x30, 0 -- pop dir
+ elseif is_blocking_node(curr) then
+ pc, pcl = false, 0
+ end
+ curr = getnext(curr)
+ end
+ return head
+end
+
+-- compress punctuations
+
+local function process_glyph_width (head)
+ local curr = head
+ while curr do
+ local id = curr.id
+ if id == glyphid then
+ if curr.lang ~= nohyphen
+ and option_in_font(curr.font, "compresspunctuations") then
+
+ local cc = my_node_props(curr).unicode or curr.char
+ local old = has_attribute(curr, classicattr)
+ local class = get_char_class(cc, old)
+ if class >= 1 and class <= 4 and
+ (old or cc < 0x2000 or cc > 0x202F) then -- exclude general puncts
+
+ local gpos = class == 1 and getprev(curr) or getnext(curr)
+ gpos = gpos and gpos.id == kernid and gpos.subtype == fontkern
+
+ if not gpos then
+ local wd = get_en_size(curr.font) - curr.width
+ if wd ~= 0 then
+ local k = nodenew(kernid) -- fontkern (subtype 0) is default
+ k.kern = class == 3 and wd/2 or wd
+ if class == 1 then
+ head = insert_before(head, curr, k)
+ elseif class == 2 or class == 4 then
+ head, curr = insert_after(head, curr, k)
+ else
+ local k2 = nodecopy(k)
+ head = insert_before(head, curr, k)
+ head, curr = insert_after(head, curr, k2)
+ end
+ end
+ end
+ end
+ end
+ elseif id == mathid then
+ curr = end_of_math(curr)
+ end
+ curr = getnext(curr)
+ end
+ return head
+end
+
+-- interhangul & interlatincjk
+
+local function is_cjk_char (c)
+ return is_hangul_jamo(c)
+ or is_hanja(c)
+ or is_cjk_combining(c)
+ or is_kana(c)
+ or charclass[c] >= 1
+ or rawget(breakable_before, c) and c >= 0x2000
+ or rawget(breakable_after, c) and c >= 0x2000
+end
+
+local function do_interhangul_option (head, curr, pc, c, fontid, par)
+ local cc = (is_hangul(c) or is_compat_jamo(c) or is_chosong(c)) and 1 or 0
+
+ if cc*pc == 1 and curr.lang ~= nohyphen then
+ local dim = get_font_opt_dimen(fontid, "interhangul")
+ if dim then
+ head = insert_glue_before(head, curr, par, true, true, false, false, dim, fontid)
+ end
+ end
+
+ return head, cc
+end
+
+local function process_interhangul (head, par)
+ local curr, pc = head, 0
+ while curr do
+ local id = curr.id
+ if id == glyphid then
+ local c = my_node_props(curr).unicode or curr.char
+ if c and not is_unicode_var_sel(c) then
+ head, pc = do_interhangul_option(head, curr, pc, c, curr.font, par)
+
+ if is_chosong(c) then
+ pc = 0
+ elseif is_jungsong(c) or is_jongsong(c) or hangul_tonemark[c] then
+ pc = 1
+ end
+ end
+
+ elseif id == hlistid and curr.list then
+ if has_attribute(curr, rubyattr) then
+ local c, f = ruby_char_font(curr)
+ if c and f then
+ head, pc = do_interhangul_option(head, curr, pc, c, f, par)
+ else
+ pc = 0
+ end
+ else
+ local c, f = hbox_ini_char_font(curr)
+ if c and f then
+ head = do_interhangul_option(head, curr, pc, c, f, par)
+ end
+ c = hbox_fin_char_font(curr)
+ pc = c and is_hangul_jamo(c) and 1 or 0
+ end
+
+ elseif id == whatsitid and curr.mode == directmode then
+ local glyf, c = get_actualtext(curr)
+ if c and glyf then
+ head = do_interhangul_option(head, curr, pc, c, glyf.font, par)
+ pc, curr = 1, goto_end_actualtext(curr)
+ end
+
+ elseif id == mathid then
+ pc, curr = 0, end_of_math(curr)
+ elseif is_blocking_node(curr) or id == dirid then
+ pc = 0
+ end
+ curr = getnext(curr)
+ end
+ return head
+end
+
+local function do_interlatincjk_option (head, curr, pc, pf, pcl, c, cf, par)
+ local cc = is_cjk_char(c) and 1 or is_noncjk_char(c) and 2 or 0
+ local old = has_attribute(curr, classicattr)
+ local ccl = get_char_class(c, old)
+
+ if cc*pc == 2 and curr.lang ~= nohyphen then
+ local brb = cc == 2 or breakable_before[c] -- numletter != br_before
+ if brb then
+ local f = cc == 1 and cf or pf
+ local dim = get_font_opt_dimen(f, "interlatincjk")
+ if dim then
+ local ict = old and intercharclass[pcl][ccl] -- under classic env. only
+ if ict then
+ dim = get_font_opt_dimen(f, "intercharacter") or 0
+ end
+ head = insert_glue_before(head, curr, par, true, brb, old, ict, dim, f)
+ end
+ end
+ end
+
+ return head, cc, cf, ccl
+end
+
+local function process_interlatincjk (head, par)
+ local curr, pc, pf, pcl = head, 0, 0, 0
+ while curr do
+ local id = curr.id
+ if id == glyphid then
+ local c = my_node_props(curr).unicode or curr.char
+ if c and not is_unicode_var_sel(c) then
+ head, pc, pf, pcl = do_interlatincjk_option(head, curr, pc, pf, pcl, c, curr.font, par)
+ pc = breakable_after[c] and pc or 0
+ end
+
+ elseif id == hlistid and curr.list then
+ if has_attribute(curr, rubyattr) then
+ local c, f = ruby_char_font(curr)
+ if c and f then
+ head, pc, pf, pcl = do_interlatincjk_option(head, curr, pc, pf, pcl, c, f, par)
+ else
+ pc, pf, pcl = 0, 0, 0
+ end
+ else
+ local c, f = hbox_ini_char_font(curr)
+ if c and f then
+ head = do_interlatincjk_option(head, curr, pc, pf, pcl, c, f, par)
+ end
+ c, f = hbox_fin_char_font(curr)
+ if c and breakable_after[c] then
+ pc = is_cjk_char(c) and 1 or is_noncjk_char(c) and 2 or 0
+ else
+ pc = 0
+ end
+ pcl = c and get_char_class(c, has_attribute(curr, classicattr)) or 0
+ pf = f or 0
+ end
+
+ elseif id == whatsitid and curr.mode == directmode then
+ local glyf, c = get_actualtext(curr)
+ if c and glyf then
+ head, pc, pf, pcl = do_interlatincjk_option(head, curr, pc, pf, pcl, c, glyf.font, par)
+ curr = goto_end_actualtext(curr)
+ end
+
+ elseif id == mathid then
+ if pc == 1 then
+ head = do_interlatincjk_option(head, curr, pc, pf, pcl, 0x30, pf, par)
+ end
+ pc, pf, pcl = 2, 0, 0
+ curr = end_of_math(curr)
+
+ elseif id == dirid then
+ if pc == 1 and curr.dir:sub(1,1) == "+" then
+ head = do_interlatincjk_option(head, curr, pc, pf, pcl, 0x30, pf, par)
+ pc, pf, pcl = 0, 0, 0
+ end
+
+ elseif is_blocking_node(curr) then
+ pc, pf, pcl = 0, 0, 0
+ end
+ curr = getnext(curr)
+ end
+ return head
+end
+
+-- remove classic spaces
+
+local function process_remove_spaces (head)
+ local curr, opt_name, to_free = head, "removeclassicspaces", {}
+ while curr do
+ local id = curr.id
+ if id == glueid then
+ if curr.subtype == spaceskip and has_attribute(curr, classicattr) then
+
+ for k, v in pairs{ p = getprev(curr), n = getnext(curr) } do
+ local ok
+ while v do
+ local id = v.id
+ if id ~= whatsitid -- skip whatsit or kern except userkern
+ and ( id ~= kernid or v.subtype == userkern ) then
+
+ local vchar, vfont
+ if id == glyphid and v.lang ~= nohyphen then
+ local c = my_node_props(v).unicode or v.char or 0
+ if is_unicode_var_sel(c) then
+ v = getprev(v) or v
+ end
+ vchar, vfont = my_node_props(v).unicode or v.char, v.font
+ elseif id == hlistid and v.list then
+ if has_attribute(v, rubyattr) then
+ vchar, vfont = ruby_char_font(v)
+ elseif k == "p" then
+ vchar, vfont = hbox_fin_char_font(v)
+ else
+ vchar, vfont = hbox_ini_char_font(v)
+ end
+ end
+ if vchar and vfont and option_in_font(vfont, opt_name) then
+ ok = is_cjk_char(vchar)
+ end
+
+ break
+ end
+ v = k == "p" and getprev(v) or getnext(v)
+ end
+ if ok then
+ head = noderemove(head, curr)
+ to_free[#to_free + 1] = curr
+ break
+ end
+ end
+ end
+ elseif id == mathid then
+ curr = end_of_math(curr)
+ end
+ curr = getnext(curr)
+ end
+ for _,v in ipairs(to_free) do nodefree(v) end
+ return head
+end
+
+-- josa
+
+local josa_table = {
+ -- 리ì„, 중성, 종성
+ [0xAC00] = {0xC774, 0xAC00, 0xC774}, -- ê°€ = ì´, ê°€, ì´
+ [0xC740] = {0xC740, 0xB294, 0xC740}, -- ì€ = ì€, 는, ì€
+ [0xC744] = {0xC744, 0xB97C, 0xC744}, -- ì„ = ì„, 를, ì„
+ [0xC640] = {0xACFC, 0xC640, 0xACFC}, -- 와 = 과, 와, 과
+ [0xC73C] = {nil, nil, 0xC73C}, -- 으(로) = , , 으
+ [0xC774] = {0xC774, nil, 0xC774}, -- ì´(ë¼) = ì´, , ì´
+}
+
+local josa_code = setmetatable({
+ [0x30] = 3, [0x31] = 1, [0x33] = 3, [0x36] = 3,
+ [0x37] = 1, [0x38] = 1, [0x4C] = 1, [0x4D] = 3,
+ [0x4E] = 3, [0x6C] = 1, [0x6D] = 3, [0x6E] = 3,
+ [0x2160] = 1, [0x2162] = 3, [0x2165] = 3, [0x2166] = 1,
+ [0x2167] = 1, [0x2169] = 3, [0x216A] = 1, [0x216C] = 3,
+ [0x216D] = 3, [0x216E] = 3, [0x216F] = 3, [0x2170] = 1,
+ [0x2172] = 3, [0x2175] = 3, [0x2176] = 1, [0x2177] = 1,
+ [0x2179] = 3, [0x217A] = 1, [0x217C] = 3, [0x217D] = 3,
+ [0x217E] = 3, [0x217F] = 3, [0x2460] = 1, [0x2462] = 3,
+ [0x2465] = 3, [0x2466] = 1, [0x2467] = 1, [0x2469] = 3,
+ [0x246A] = 1, [0x246C] = 3, [0x246F] = 3, [0x2470] = 1,
+ [0x2471] = 1, [0x2473] = 3, [0x2474] = 1, [0x2476] = 3,
+ [0x2479] = 3, [0x247A] = 1, [0x247B] = 1, [0x247D] = 3,
+ [0x247E] = 1, [0x2480] = 3, [0x2483] = 3, [0x2484] = 1,
+ [0x2485] = 1, [0x2487] = 3, [0x2488] = 1, [0x248A] = 3,
+ [0x248D] = 3, [0x248E] = 1, [0x248F] = 1, [0x2491] = 3,
+ [0x2492] = 1, [0x2494] = 3, [0x2497] = 3, [0x2498] = 1,
+ [0x2499] = 1, [0x249B] = 3, [0x24A7] = 1, [0x24A8] = 3,
+ [0x24A9] = 3, [0x24C1] = 1, [0x24C2] = 3, [0x24C3] = 3,
+ [0x24DB] = 1, [0x24DC] = 3, [0x24DD] = 3, [0x3139] = 1,
+ [0x3203] = 1, [0x3263] = 1, [0xFF10] = 3, [0xFF11] = 1,
+ [0xFF13] = 3, [0xFF16] = 3, [0xFF17] = 1, [0xFF18] = 1,
+ [0xFF2C] = 1, [0xFF2D] = 3, [0xFF2E] = 3, [0xFF4C] = 1,
+ [0xFF4D] = 3, [0xFF4E] = 3,
+},{ __index = function(_,c)
+ if is_hangul(c) then
+ c = (c - 0xAC00) % 28 + 0x11A7
+ end
+ if is_chosong(c) then
+ return c == 0x1105 and 1 or 3
+ elseif is_jungsong(c) then
+ return c ~= 0x1160 and 2
+ elseif is_jongsong(c) then
+ return c == 0x11AF and 1 or 3
+ elseif is_noncjk_char(c) and c <= 0x7A
+ or c >= 0x2160 and c <= 0x217F -- roman
+ or c >= 0x2460 and c <= 0x24E9 -- â‘ 
+ or c >= 0x314F and c <= 0x3163 or c >= 0x3187 and c <= 0x318E -- ã…
+ or c >= 0x320E and c <= 0x321E -- ㈎
+ or c >= 0x326E and c <= 0x327F -- ㉮
+ or c >= 0xFF10 and c <= 0xFF19 -- ï¼
+ or c >= 0xFF21 and c <= 0xFF3A -- A
+ or c >= 0xFF41 and c <= 0xFF5A -- ï½
+ then return 2
+ elseif c >= 0x3131 and c <= 0x314E or c >= 0x3165 and c <= 0x3186 -- ㄱ
+ or c >= 0x3200 and c <= 0x320D -- ㈀
+ or c >= 0x3260 and c <= 0x326D -- ㉠
+ then return 3
+ end
+end })
+
+local ignore_parens = false
+
+local function prevjosacode (n, parenlevel)
+ local parenlevel, josacode = parenlevel or 0
+ while n do
+ local id = n.id
+ if id == glyphid then
+ local c = my_node_props(n).unicode or n.char -- beware hlist/vlist
+ if ignore_parens and c == 0x29 then
+ parenlevel = parenlevel + 1
+ elseif ignore_parens and c == 0x28 then
+ parenlevel = parenlevel - 1
+ elseif parenlevel <= 0 then
+ josacode = josa_code[c]
+ if josacode then break end
+ end
+ elseif id == hlistid or id == vlistid then
+ local list = n.list
+ if list then
+ josacode, parenlevel = prevjosacode(nodeslide(list), parenlevel)
+ if josacode then break end
+ end
+ end
+ n = getprev(n)
+ end
+ return josacode, parenlevel
+end
+
+local function process_josa (head)
+ local curr, tofree = head, {}
+ while curr do
+ local id = curr.id
+ if id == glyphid then
+ local autojosaattr = has_attribute(curr, autojosaattr)
+ if autojosaattr then
+ local cc = curr.char
+ if cc == 0xC774 then
+ local n = getnext(curr)
+ if n and n.char and is_hangul(n.char) then
+ else
+ cc = 0xAC00
+ end
+ end
+ local t = josa_table[cc]
+ if t then
+ ignore_parens = autojosaattr > 0
+ cc = t[prevjosacode(getprev(curr)) or 3]
+ if cc then
+ curr.char = cc
+ else
+ head = noderemove(head, curr)
+ tofree[#tofree + 1] = curr
+ end
+ end
+ unset_attribute(curr, autojosaattr)
+ end
+ elseif id == mathid then
+ curr = end_of_math(curr)
+ end
+ curr = getnext(curr)
+ end
+ for _,v in ipairs(tofree) do nodefree(v) end
+ return head
+end
+
+-- dotemph
+
+local dotemphbox = {}
+luatexko.dotemphbox = dotemphbox
+
+local function process_dotemph (head, tofree)
+ local curr, outer, tofree = head, not tofree, tofree or {}
+ while curr do
+ local id = curr.id
+ if id == glyphid then
+ local dotattr = has_attribute(curr, dotemphattr)
+ if dotattr then
+ local c = my_node_props(curr).unicode or curr.char
+ if is_hangul(c) or
+ is_compat_jamo(c) or
+ is_chosong(c) or
+ is_hanja(c) or
+ is_kana(c) then
+ local currwd = curr.width
+ if currwd >= get_en_size(curr.font) then
+ local box = nodecopy(dotemphbox[dotattr])
+ local shift = (currwd - box.width)/2
+ if shift ~= 0 then
+ local list = box.list
+ local k = nodenew(kernid)
+ k.kern = shift
+ box.list = insert_before(list, list, k)
+ end
+ box.width = 0
+ head = insert_before(head, curr, box)
+ tofree[dotattr] = true
+ end
+ end
+ unset_attribute(curr, dotemphattr)
+ end
+ elseif id == hlistid then
+ local list = curr.list
+ if list then
+ curr.list, tofree = process_dotemph(list, tofree)
+ end
+ end
+ curr = getnext(curr)
+ end
+ if outer then
+ for k in pairs(tofree) do nodefree(dotemphbox[k]) end
+ end
+ return head, tofree
+end
+
+-- uline
+
+local uline_f, uline_id = new_user_whatsit("uline","luatexko")
+local no_uline_id = new_user_whatsit_id("no_uline","luatexko")
+
+local function ulboundary (i, n, subtype)
+ local what = uline_f()
+ if n then
+ what.type = lua_value -- table
+ what.value = { i, nodecopy(n), subtype }
+ else
+ what.type = lua_number
+ what.value = i
+ end
+ nodewrite(what)
+end
+luatexko.ulboundary = ulboundary
+
+local white_nodes = {
+ [glueid] = true,
+ [penaltyid] = true,
+ [kernid] = true,
+ [whatsitid] = true,
+}
+
+function skip_white_nodes (n, ltr)
+ local nextnode = ltr and getnext or getprev
+ while n do
+ if not white_nodes[n.id] then break end
+ n = nextnode(n)
+ end
+ return n
+end
+
+local function draw_uline (head, curr, parent, t, final)
+ local start, list, subtype = t.start or head, t.list, t.subtype
+ start = skip_white_nodes(start, true)
+ if final then
+ nodeslide(start) -- to get correct getprev.
+ end
+ curr = skip_white_nodes(curr)
+ curr = getnext(curr) or curr
+ local len = parent and rangedimensions(parent, start, curr)
+ or dimensions(start, curr) -- it works?!
+ if len and len ~= 0 then
+ local g = nodenew(glueid)
+ setglue(g, len)
+ g.subtype = subtype
+ g.leader = final and list or nodecopy(list)
+ local k = nodenew(kernid)
+ k.kern = -len
+ head = insert_before(head, start, g)
+ head = insert_before(head, start, k)
+ end
+ return head
+end
+
+local function process_uline (head, parent, items, level)
+ local curr, items, level = head, items or {}, level or 0
+ while curr do
+ local id = curr.id
+ if id == whatsitid
+ and curr.subtype == user_whatsit
+ and curr.user_id == uline_id then
+
+ local value = curr.value
+ if curr.type == lua_value then
+ local count, list, subtype = tableunpack(value)
+ items[count] = {
+ start = curr,
+ list = list,
+ subtype = subtype,
+ level = level,
+ }
+ elseif items[value] then
+ head = draw_uline(head, curr, parent, items[value], true)
+ items[value] = nil
+ end
+
+ curr.user_id = no_uline_id -- avoid multiple run
+ elseif id == hlistid then
+ local list = curr.list
+ if list then
+ curr.list, items = process_uline(list, curr, items, level+1)
+ end
+ end
+ curr = getnext(curr)
+ end
+
+ curr = nodeslide(head)
+ for i, t in pairs(items) do
+ if level == t.level then
+ head = draw_uline(head, curr, parent, t)
+ t.start = nil
+ end
+ end
+ return head, items
+end
+
+-- ruby
+
+local rubybox = {}
+luatexko.rubybox = rubybox
+
+local function getrubystretchfactor (box)
+ local _, fid = ruby_char_font(box)
+ local str = get_font_opt_dimen(fid, "intercharstretch")
+ if str then
+ local em = get_en_size(fid) * 2
+ set_macro("luatexkostretchfactor", stringformat("%.4f", str/em/2))
+ end
+end
+luatexko.getrubystretchfactor = getrubystretchfactor
+
+local function process_ruby_pre_linebreak (head)
+ local curr = head
+ while curr do
+ local id = curr.id
+ if id == hlistid then
+ local rubyid = has_attribute(curr, rubyattr)
+ if rubyid then
+ local ruby_t = rubybox[rubyid]
+ if ruby_t[3] then -- rubyoverlap
+ local side = (ruby_t[1].width - curr.width)/2
+ if side > 0 then -- ruby is wide
+ local k, r = nodenew(kernid), nodenew(ruleid)
+ k.subtype, k.kern = userkern, -side
+ r.width, r.height, r.depth = side, 0, 0
+ local k2, r2 = nodecopy(k), nodecopy(r)
+ head = insert_before(head, curr, k)
+ head = insert_before(head, curr, r)
+ head, curr = insert_after(head, curr, r2)
+ head, curr = insert_after(head, curr, k2)
+ end
+ ruby_t[3] = false
+ end
+ end
+ elseif id == mathid then
+ curr = end_of_math(curr)
+ end
+ curr = getnext(curr)
+ end
+ return head
+end
+
+local function process_ruby_post_linebreak (head)
+ local curr = head
+ while curr do
+ if curr.id == hlistid then
+ local rubyid = has_attribute(curr, rubyattr)
+ if rubyid then
+ local ruby_t = rubybox[rubyid]
+ local ruby = ruby_t and ruby_t[1]
+ if ruby then
+ local side = (curr.width - ruby.width)/2
+ if side ~= 0 then
+ local list = ruby.list
+ local k = nodenew(kernid)
+ k.kern = side
+ ruby.list = insert_before(list, list, k)
+ end
+ ruby.width = 0
+ local _, f = ruby_char_font(curr)
+ local ascender = get_font_param(f, "ascender") or curr.height
+ ruby.shift = -ascender - ruby.depth - ruby_t[2] -- rubysep
+ head = insert_before(head, curr, ruby)
+ end
+ ruby_t = nil
+ unset_attribute(curr, rubyattr)
+ else
+ local list = curr.list
+ if list then
+ curr.list = process_ruby_post_linebreak(list)
+ end
+ end
+ end
+ curr = getnext(curr)
+ end
+ return head
+end
+
+-- reorder tone marks
+
+local function conv_tounicode (uni)
+ if uni < 0x10000 then
+ return stringformat("%04X", uni)
+ else -- surrogate
+ uni = uni - 0x10000
+ local high = uni // 0x400 + 0xD800
+ local low = uni % 0x400 + 0xDC00
+ return stringformat("%04X%04X", high, low)
+ end
+end
+
+local function pdfliteral_direct_actual (syllable)
+ local data
+ if syllable then
+ local t = {}
+ for _,v in ipairs(syllable) do
+ t[#t + 1] = conv_tounicode(v)
+ end
+ data = stringformat("/Span<</ActualText<FEFF%s>>>BDC", tableconcat(t))
+ else
+ data = "EMC"
+ end
+ local what = nodenew(whatsitid, literal_whatsit)
+ what.mode = directmode
+ what.data = data
+ if syllable then
+ my_node_props(what).startactualtext = syllable
+ else
+ my_node_props(what).endactualtext = true
+ end
+ return what
+end
+
+local function get_tonemark_width (curr, uni)
+ local fontid = curr.font
+ local hwidth = char_font_options.tonemarkwidth[fontid]
+ if not hwidth then
+ -- check horizontal width; vertical width is mostly non-zero
+ local fontdata = get_font_data(fontid)
+ local shared = fontdata.shared or {}
+ local rawdata = shared.rawdata or {}
+ local descriptions = rawdata.descriptions or {}
+ local description = descriptions[uni] or {}
+ hwidth = description.width or 0
+ char_font_options.tonemarkwidth[fontid] = hwidth
+ end
+ return hwidth
+end
+
+local function process_reorder_tonemarks (head)
+ local curr = head
+ while curr do
+ local id = curr.id
+ if id == glyphid and option_in_font(curr.font, "script") == "hang" then
+ local fontdata = get_font_data(curr.font)
+ local uni = my_node_props(curr).unicode or curr.char
+ if is_hangul(uni) or is_chosong(uni) or uni == 0x25CC then
+
+ local syllable = { [0]=curr, uni }
+
+ local n = getnext(curr)
+ while n do
+ local nid = n.id
+ if nid == glyphid then
+ local u = my_node_props(n).unicode or n.char
+ if is_jungsong(u)
+ or is_jongsong(u)
+ or hangul_tonemark[u] then
+ syllable[#syllable + 1] = u
+ curr, uni = n, u
+ else
+ break
+ end
+ elseif nid ~= kernid or n.subtype == userkern then
+ break
+ end
+ n = getnext(n)
+ end
+
+ if #syllable > 1
+ and hangul_tonemark[uni]
+ and get_tonemark_width(curr, uni) ~= 0 then
+
+ local ini, fin = syllable[0], curr
+ local actual = pdfliteral_direct_actual(syllable)
+ local endactual = pdfliteral_direct_actual()
+ head = insert_before(head, ini, actual)
+ head, curr = insert_after(head, curr, endactual)
+
+ head = noderemove(head, fin)
+ head = insert_before(head, ini, fin)
+ end
+
+ elseif hangul_tonemark[uni] -- isolated tone mark
+ and char_in_font(fontdata, 0x25CC) then
+
+ local dotcircle = nodecopy(curr)
+ dotcircle.char = 0x25CC
+ if get_tonemark_width(curr, uni) ~= 0 then
+ local actual = pdfliteral_direct_actual{ [0]=curr, uni }
+ local endactual = pdfliteral_direct_actual()
+ head = insert_before(head, curr, actual)
+ head, curr = insert_after(head, curr, dotcircle)
+ head, curr = insert_after(head, curr, endactual)
+ else
+ head = insert_before(head, curr, dotcircle)
+ end
+ end
+ elseif id == whatsitid
+ and curr.mode == directmode
+ and my_node_props(curr).startactualtext then
+
+ curr = goto_end_actualtext(curr)
+
+ elseif id == mathid then
+ curr = end_of_math(curr)
+ end
+ curr = getnext(curr)
+ end
+ return head
+end
+
+-- vertical font
+
+local streamreader = utilities.files
+local openfile = streamreader.open
+local closefile = streamreader.close
+local readstring = streamreader.readstring
+local readulong = streamreader.readcardinal4
+local readushort = streamreader.readcardinal2
+local readfixed = streamreader.readfixed4
+local readshort = streamreader.readinteger2
+local setpos = streamreader.setposition
+
+local function get_otf_tables (f, subfont)
+ if f then
+ local sfntversion = readstring(f,4)
+ if sfntversion == "ttcf" then
+ local ttcversion = readfixed(f)
+ local numfonts = readulong(f)
+ if subfont >= 1 and subfont <= numfonts then
+ local offsets = {}
+ for i = 1, numfonts do
+ offsets[i] = readulong(f)
+ end
+ setpos(f, offsets[subfont])
+ sfntversion = readstring(f,4)
+ end
+ end
+ if sfntversion == "OTTO" or sfntversion == "true" or sfntversion == "\0\1\0\0" then
+ local numtables = readushort(f)
+ local searchrange = readushort(f)
+ local entryselector = readushort(f)
+ local rangeshift = readushort(f)
+ local tables = {}
+ for i= 1, numtables do
+ local tag = readstring(f,4)
+ tables[tag] = {
+ checksum = readulong(f),
+ offset = readulong(f),
+ length = readulong(f),
+ }
+ end
+ return tables
+ end
+ end
+end
+
+local function read_maxp (f, t)
+ if f and t then
+ setpos(f, t.offset)
+ return {
+ version = readfixed(f),
+ numglyphs = readushort(f),
+ }
+ end
+end
+
+local function read_vhea (f, t)
+ if f and t then
+ setpos(f, t.offset)
+ return {
+ version = readfixed(f),
+ ascent = readshort(f),
+ descent = readshort(f),
+ lineGap = readshort(f),
+ advanceheightmax = readshort(f),
+ mintopsidebearing = readshort(f),
+ minbottomsidebrearing = readshort(f),
+ ymaxextent = readshort(f),
+ caretsloperise = readshort(f),
+ caretsloperun = readshort(f),
+ caretoffset = readshort(f),
+ reserved1 = readshort(f),
+ reserved2 = readshort(f),
+ reserved3 = readshort(f),
+ reserved4 = readshort(f),
+ metricdataformat = readshort(f),
+ numheights = readushort(f),
+ }
+ end
+end
+
+local function read_vmtx (f, t, numofheights, numofglyphs)
+ if f and t and numofheights and numofglyphs then
+ setpos(f, t.offset)
+ local vmtx = {}
+ local height = 0
+ for i = 0, numofheights-1 do
+ height = readushort(f)
+ vmtx[i] = {
+ ht = height,
+ tsb = readshort(f),
+ }
+ end
+ for i = numofheights, numofglyphs-1 do
+ vmtx[i] = {
+ ht = height,
+ tsb = readshort(f),
+ }
+ end
+ return vmtx
+ end
+end
+
+local tsb_font_data = {}
+
+local function get_tsb_table (filename, subfont)
+ subfont = tonumber(subfont) or 1
+ local key = stringformat("%s::%s", filename, subfont)
+ if tsb_font_data[key] then
+ return tsb_font_data[key]
+ end
+ local f = openfile(filename, true) -- true: zero-based
+ if f then
+ local vmtx
+ local tables = get_otf_tables(f, subfont)
+ if tables then
+ local vhea = read_vhea(f, tables.vhea)
+ local numofheights = vhea and vhea.numheights
+ local maxp = read_maxp(f, tables.maxp)
+ local numofglyphs = maxp and maxp.numglyphs
+ vmtx = read_vmtx(f, tables.vmtx, numofheights, numofglyphs)
+ end
+ closefile(f)
+ tsb_font_data[key] = vmtx
+ return vmtx
+ end
+end
+
+local function process_vertical_font (fontdata)
+ local subfont = fontdata.specification and fontdata.specification.sub
+ local tsb_tab = get_tsb_table(fontdata.filename, subfont)
+ if not tsb_tab then
+ warning("Vertical metrics table (vmtx) not found in the font\n"..
+ "`%s'", fontdata.fullname)
+ return
+ end
+
+ local shared = fontdata.shared or {}
+ local descriptions = shared.rawdata and shared.rawdata.descriptions or {}
+ local parameters = fontdata.parameters or {}
+ local scale = parameters.factor or 655.36
+ local quad = parameters.quad or 655360
+ local ascender = parameters.ascender or quad*0.8
+
+ local goffset = fontdata_opt_dim(fontdata, "charraise") or
+ (parameters.x_height or quad/2)/2
+ -- declare shift amount of horizontal box inside vertical env.
+ fontdata.horizboxmoveleftamount = quad/2-goffset
+
+ for i,v in pairs(fontdata.characters) do
+ local voff = goffset - (v.width or 0)/2
+ local bbox = descriptions[i] and descriptions[i].boundingbox or {0,0,0,0}
+ local gid = v.index
+ local tsb = tsb_tab[gid].tsb
+ local hoff = tsb and (bbox[4] + tsb) * scale or ascender
+ v.commands = {
+ { "down", -voff },
+ { "right", hoff },
+ { "pdf", "q 0 1 -1 0 0 0 cm" },
+ { "push" },
+ { "char", i },
+ { "pop" },
+ { "pdf", "Q" },
+ }
+ local vw = tsb_tab[gid].ht
+ v.width = vw and vw * scale or quad
+ local ht = bbox[3] * scale + voff
+ local dp = bbox[1] * scale + voff
+ v.height = ht > 0 and ht or nil
+ v.depth = dp < 0 and -dp or nil
+ end
+ local spacechar = char_in_font(fontdata, 32)
+ if spacechar then
+ parameters.space = spacechar.width
+ parameters.space_stretch = spacechar.width/2
+ parameters.space_shrink = spacechar.width/2
+ end
+
+ local res = fontdata.resources or {}
+ local fea = shared.features or {}
+ fea.kern = nil -- only for horizontal writing
+ fea.vert = true -- should be activated by default
+ local seq = res.sequences or {}
+ for _,v in ipairs(seq) do
+ local fea = v.features or {}
+ if fea.vhal or fea.vkrn or fea.valt or fea.vpal or fea.vert then
+ if v.type == "gpos_single" then
+ for _,vv in pairs(v.steps or {}) do
+ for _,vvv in pairs(vv.coverage or {}) do
+ if type(vvv) == "table" and #vvv == 4 then
+ vvv[1], vvv[2], vvv[3], vvv[4], vvv[5] =
+ -vvv[2], vvv[1], vvv[4], vvv[3], 0 -- last 0 to avoid multiple run
+ end
+ end
+ end
+ elseif v.type == "gpos_pair" then
+ for _,vv in pairs(v.steps or {}) do
+ for _,vvv in pairs(vv.coverage or {}) do
+ for _,vvvv in pairs(vvv) do
+ for _,vvvvv in pairs(vvvv) do
+ if type(vvvvv) == "table" and #vvvvv == 4 then
+ vvvvv[1], vvvvv[2], vvvvv[3], vvvvv[4], vvvvv[5] =
+ -vvvvv[2], vvvvv[1], vvvvv[4], vvvvv[3], 0
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+local function get_horizbox_moveleft ()
+ for _, v in ipairs{ fontcurrent(),
+ texattribute.luatexkohangulfontattr,
+ texattribute.luatexkohanjafontattr,
+ texattribute.luatexkofallbackfontattr } do
+ if v and v > 0 then
+ local amount = get_font_data(v).horizboxmoveleftamount
+ if amount then
+ set_macro("luatexkohorizboxmoveleft", texsp(amount).."sp")
+ break
+ end
+ end
+ end
+end
+luatexko.gethorizboxmoveleft = get_horizbox_moveleft
+
+-- charraise
+
+local function process_charriase_font (fontdata)
+ local raise = fontdata_opt_dim(fontdata, "charraise")
+ if raise then
+ local shared = fontdata.shared or {}
+ local descriptions = shared.rawdata and shared.rawdata.descriptions or {}
+ local scale = fontdata.parameters.factor or 655.36
+ for i, v in pairs( fontdata.characters ) do
+ v.commands = {
+ {"down", -raise },
+ {"char", i},
+ }
+ local bbox = descriptions[i] and descriptions[i].boundingbox or {0,0,0,0}
+ local ht = bbox[4] * scale + raise
+ local dp = bbox[2] * scale + raise
+ v.height = ht > 0 and ht or nil
+ v.depth = dp < 0 and -dp or nil
+ end
+ end
+end
+
+-- fake italic correctioin
+
+local function process_fake_slant_corr (head) -- for font fallback
+ local curr = head
+ while curr do
+ local id = curr.id
+ if id == kernid then
+ if curr.subtype == italcorr and curr.kern == 0 then
+ local p = getprev(curr)
+ while p do -- skip jungsong/jongsong
+ if p.id == glyphid and p.width < get_en_size(p.font) then
+ local c = my_node_props(p).unicode or p.char
+ if not is_jungsong(c) and not is_jongsong(c) then
+ break
+ end
+ elseif p.id == whatsitid
+ and p.mode == directmode
+ and my_node_props(p).endactualtext then -- skip
+ else
+ break
+ end
+ p = getprev(p)
+ end
+ if p.id == glyphid then
+ local fontdata = get_font_data(p.font)
+ if fontdata.slant and fontdata.slant > 0 then
+ local italic = char_in_font(fontdata, p.char).italic
+ if italic then
+ curr.kern = italic
+ end
+ end
+ end
+ end
+ elseif id == mathid then
+ curr = end_of_math(curr)
+ end
+ curr = getnext(curr)
+ end
+ return head
+end
+
+local function process_fake_slant_font (fontdata)
+ local fsl = fontdata.slant
+ if fsl and fsl > 0 then
+ fsl = fsl/1000
+ local params = fontdata.parameters or {}
+ params.slant = (params.slant or 0) + fsl*65536 -- slant per point
+ local scale = params.factor or 655.36
+ local shared = fontdata.shared or {}
+ local descriptions = shared.rawdata and shared.rawdata.descriptions or {}
+ for i, v in pairs(fontdata.characters) do
+ local bbox = descriptions[i] and descriptions[i].boundingbox or {0,0,0,0}
+ local italic = (v.height or 0) * fsl - (v.width or 0) + bbox[3]*scale
+ if italic > 0 then
+ v.italic = italic
+ end
+ end
+ end
+end
+
+-- wrap up
+
+local pass_fun = function(...) return ... end
+create_callback("luatexko_pre_hpack", "data", pass_fun)
+create_callback("luatexko_pre_prelinebreak", "data", pass_fun)
+create_callback("luatexko_post_hpack", "data", pass_fun)
+create_callback("luatexko_post_prelinebreak", "data", pass_fun)
+
+add_to_callback("hpack_filter", function(h)
+ h = process_fonts(h)
+ h = call_callback("luatexko_pre_hpack", h)
+ h = call_callback("luatexko_post_hpack", h)
+ return process_linebreak(h)
+end, "luatexko.hpack_filter.pre_rendering", 1)
+
+add_to_callback("pre_linebreak_filter", function(h)
+ h = process_fonts(h)
+ h = call_callback("luatexko_pre_prelinebreak", h, true)
+ h = call_callback("luatexko_post_prelinebreak", h, true)
+ return process_linebreak(h, true)
+end, "luatexko.pre_linebreak_filter.pre_rendering", 1)
+
+local font_opt_procs = {
+ removeclassicspaces = {
+ luatexko_pre_hpack = process_remove_spaces,
+ luatexko_pre_prelinebreak = process_remove_spaces,
+ },
+ interhangul = {
+ luatexko_post_hpack = process_interhangul,
+ luatexko_post_prelinebreak = process_interhangul,
+ },
+ interlatincjk = {
+ luatexko_post_hpack = process_interlatincjk,
+ luatexko_post_prelinebreak = process_interlatincjk,
+ },
+ compresspunctuations = {
+ hpack_filter = process_glyph_width,
+ pre_linebreak_filter = process_glyph_width,
+ },
+ slant = {
+ hpack_filter = process_fake_slant_corr,
+ pre_linebreak_filter = process_fake_slant_corr,
+ },
+}
+
+local function process_patch_font (fontdata)
+ for name, procs in pairs( font_opt_procs ) do
+ if not active_processes[name] and option_in_font(fontdata, name) then
+ for cbnam, cbfun in pairs( procs ) do
+ add_to_callback(cbnam, cbfun, "luatexko."..cbnam.."."..name)
+ end
+ active_processes[name] = true
+ end
+ end
+
+ if not active_processes.expansion
+ and option_in_font(fontdata, "expansion") then
+ texset("global", "adjustspacing", 2)
+ active_processes.expansion = true
+ end
+
+ if option_in_font(fontdata, "protrusion") then
+ if not active_processes.protrusion then
+ texset("global", "protrudechars", 2)
+ active_processes.protrusion = true
+ end
+ if not active_processes[fontdata.fullname] and
+ option_in_font(fontdata, "compresspunctuations") then
+ warning("Both `compresspunctuations' and `protrusion' are\n"..
+ "enabled for the font `%s'.\n"..
+ "Beware that this could result in bad justifications.\n",
+ fontdata.fullname)
+ active_processes[fontdata.fullname] = true
+ end
+ end
+
+ if option_in_font(fontdata, "vertical") then
+ process_vertical_font(fontdata)
+ elseif option_in_font(fontdata, "charraise") then
+ process_charriase_font(fontdata)
+ end
+
+ if option_in_font(fontdata, "slant") then
+ process_fake_slant_font(fontdata)
+ end
+end
+
+add_to_callback("luaotfload.patch_font", process_patch_font,
+"luatexko.patch_font")
+
+local auxiliary_procs = {
+ dotemph = {
+ hpack_filter = process_dotemph,
+ vpack_filter = process_dotemph,
+ },
+ uline = {
+ hpack_filter = process_uline,
+ vpack_filter = process_uline,
+ },
+ ruby = {
+ pre_linebreak_filter = process_ruby_pre_linebreak,
+ hpack_filter = process_ruby_post_linebreak,
+ vpack_filter = process_ruby_post_linebreak,
+ },
+ autojosa = {
+ luatexko_pre_hpack = process_josa,
+ luatexko_pre_prelinebreak = process_josa,
+ },
+ reorderTM = {
+ luatexko_pre_hpack = process_reorder_tonemarks,
+ luatexko_pre_prelinebreak = process_reorder_tonemarks,
+ },
+}
+
+local function activate (name)
+ for cbnam, cbfun in pairs( auxiliary_procs[name] ) do
+ local fun
+ if cbnam == "hpack_filter" then
+ fun = function(h, gc)
+ if gc == "align_set" then
+ h = cbfun(h)
+ end
+ return h
+ end
+ else
+ fun = function(h)
+ h = cbfun(h)
+ return h
+ end
+ end
+ add_to_callback(cbnam, fun, "luatexko."..cbnam.."."..name)
+ end
+end
+luatexko.activate = activate
+
+add_to_callback ("hyphenate",
+function(head)
+ local curr = head
+ while curr do
+ local id = curr.id
+ if id == glyphid and curr.subtype == 1 and curr.lang ~= nohyphen then
+ local c = curr.char
+ if c then
+ if is_unicode_var_sel(c) then
+ local p = getprev(curr)
+ if p.id == glyphid then
+ curr.lang = p.lang
+ end
+ elseif is_cjk_char(c) then
+ curr.lang = langkor
+ end
+ end
+ elseif id == mathid then
+ curr = end_of_math(curr)
+ end
+ curr = getnext(curr)
+ end
+ lang.hyphenate(head)
+end,
+"luatexko.hyphenate.prevent_disc_nodes")
+
+-- aux functions
+
+local function deactivate_all (str)
+ luatexko.deactivated = {}
+ for _, name in ipairs{ "hpack_filter",
+ "pre_linebreak_filter",
+ "vpack_filter",
+ "hyphenate",
+ "luaotfload.patch_font" } do
+ local t = {}
+ for i, v in ipairs( callback_descriptions(name) ) do
+ if v:find(str or "^luatexko%.") then
+ local ff, dd = remove_from_callback(name, v)
+ t[#t + 1] = { ff, dd, i }
+ end
+ end
+ luatexko.deactivated[name] = t
+ end
+end
+luatexko.deactivateall = deactivate_all
+
+local function reactivate_all ()
+ for name, v in pairs(luatexko.deactivated or {}) do
+ for _, vv in ipairs(v) do
+ add_to_callback(name, tableunpack(vv))
+ end
+ end
+ luatexko.deactivated = nil
+end
+luatexko.reactivateall = reactivate_all
+
+local function current_has_hangul_chars (cnt)
+ texcount[cnt] = char_in_font(fontcurrent(), 0xAC00) and 1 or 0
+end
+luatexko.currenthashangulchars = current_has_hangul_chars
+
diff --git a/macros/luatex/generic/luatexko/luatexko.sty b/macros/luatex/generic/luatexko/luatexko.sty
new file mode 100644
index 0000000000..7599a0977b
--- /dev/null
+++ b/macros/luatex/generic/luatexko/luatexko.sty
@@ -0,0 +1,728 @@
+% luatexko.sty
+%
+% Copyright (c) 2013-2019 Dohyun Kim <nomos at ktug org>
+% Soojin Nam <jsunam at gmail com>
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2006/05/20 or later.
+
+\ifdefined\luatexkohangulfontattr \endinput\fi
+\ifdefined\selectfont
+ \ProvidesPackage{luatexko}[2019/08/01 v2.4 typesetting Korean with LuaTeX]
+ \RequirePackage{luatexbase}
+ \RequirePackage{fontspec}
+\else
+ \input luatexbase.sty
+ \input luaotfload.sty
+ \chardef\luatexkoatcatcode=\catcode`\@
+ \catcode`\@=11
+\fi
+\newlanguage\koreanlanguage
+\protected\def\pdfliteral{\pdfextension literal}
+\newattribute\luatexkohangulfontattr
+\newattribute\luatexkohanjafontattr
+\newattribute\luatexkofallbackfontattr
+\newattribute\luatexkoautojosaattr
+\newattribute\luatexkoclassicattr
+\newattribute\luatexkodotemphattr
+\newattribute\luatexkorubyattr \chardef\luatexkorubyalloc\allocationnumber
+\directlua{ require"luatexko" }
+% classic
+\protected\def\typesetclassic{\luatexkoclassicattr\z@\parindent1em }
+\protected\def\typesetvertical{\luatexkoclassicattr\@ne\parindent1em }
+\protected\def\typesetmodern{\unsetattribute\luatexkoclassicattr}
+\protected\def\inhibitglue{\hskip\z@skip}
+\protected\def\Schinese{\luatexkoclassicattr\tw@\parindent2em }
+\protected\def\Tchinese{\luatexkoclassicattr\thr@@\parindent2em } % +halt
+\let\korean\typesetmodern \let\japanese\typesetclassic \let\chinese\Schinese
+% josa
+\count@"AC00
+\loop
+ \catcode\count@ 12
+ \ifnum\count@<"D7A3 \advance\count@\@ne \repeat
+\newcount\josaignoreparens
+\def\luatexkojosaactivate{%
+ \ifx\luatexkojosaactive\relax
+ \else
+ \directlua{ luatexko.activate("autojosa") }%
+ \global\let\luatexkojosaactive\relax
+ \fi
+ \luatexkoautojosaattr\josaignoreparens }
+\protected\def\ì€{\begingroup\luatexkojosaactivate ì€\endgroup}
+\let\는\ì€
+\protected\def\ì„{\begingroup\luatexkojosaactivate ì„\endgroup}
+\let\를\ì„
+\protected\def\와{\begingroup\luatexkojosaactivate 와\endgroup}
+\let\과\와
+\protected\def\ê°€{\begingroup\luatexkojosaactivate ê°€\endgroup}
+\protected\def\ì´{\begingroup\luatexkojosaactivate ì´\endgroup}
+\protected\def\ë¼{\ì´ë¼}
+\protected\def\으{\begingroup\luatexkojosaactivate 으\endgroup}
+\protected\def\로{\으로}
+% force hangul font
+\def\luatexkotoks@appendchars#1,{%
+ \ifx\empty#1\empty
+ \expandafter\luatexkotoks@appendchars
+ \else
+ \ifx*#1\else
+ \expandafter\ifx\expandafter\empty\the\toks@\empty
+ \etoksapp0{\number#1}%
+ \else
+ \etoksapp0{,\number#1}%
+ \fi
+ \expandafter\expandafter\expandafter\luatexkotoks@appendchars
+ \fi
+ \fi }
+\def\luatexkodoluacode#1{\directlua{
+ \ifhmode luatexko.updateforcehangul(function() \fi
+ #1
+ \ifhmode end) \fi }}
+\protected\def\registerpunctuations#1{%
+ \toks@{}\luatexkotoks@appendchars#1,*,\luatexkodoluacode{
+ local t = luatexko.forcehangulchars
+ for _,v in ipairs{\the\toks@} do t[v]=true end }}
+\let\registerhangulpunctuations\registerpunctuations
+\protected\def\unregisterpunctuations#1{%
+ \toks@{}\luatexkotoks@appendchars#1,*,\luatexkodoluacode{
+ local t = luatexko.forcehangulchars
+ for _,v in ipairs{\the\toks@} do t[v]=nil end }}
+\let\unregisterhangulpunctuations\unregisterpunctuations
+\protected\def\hangulpunctuations{%
+ \afterassignment\luatexkohangulpunctuations\count@ }
+\def\luatexkohangulpunctuations{\luatexkodoluacode{
+ local t = luatexko.forcehangulchars
+ for i in pairs(t) do t[i]=\ifcase\count@ false \else true \fi end }}
+\protected\def\registerbreakableafter#1{%
+ \toks@{}\luatexkotoks@appendchars#1,*,\luatexkodoluacode{
+ local t = luatexko.breakableafter
+ for _,v in ipairs{\the\toks@} do t[v]=true end }}
+\protected\def\registerbreakablebefore#1{%
+ \toks@{}\luatexkotoks@appendchars#1,*,\luatexkodoluacode{
+ local t = luatexko.breakablebefore
+ for _,v in ipairs{\the\toks@} do t[v]=true end }}
+\protected\def\hangulbyhangulfont{%
+ \afterassignment\luatexkohangulbyhangulfont\count@ }
+\def\luatexkohangulbyhangulfont{\luatexkodoluacode{
+ luatexko.hangulbyhangulfont=\ifcase\count@ false \else true \fi }}
+\protected\def\hanjabyhanjafont{%
+ \afterassignment\luatexkohanjabyhanjafont\count@ }
+\def\luatexkohanjabyhanjafont{\luatexkodoluacode{
+ luatexko.hanjabyhanjafont=\ifcase\count@ false \else true \fi }}
+% dotemph
+\newcount\luatexkodotemphcount
+\def\dotemphraise{1ex }
+\unless\ifdefined\bfseries\let\bfseries\bf\fi
+\def\dotemphchar{\bfseries\char"02D9 }
+\protected\def\dotemph#1{%
+ \global\advance\luatexkodotemphcount\@ne
+ \begingroup
+ \setbox\z@\hbox{\raise\dotemphraise\hbox{\dotemphchar}}%
+ \directlua{
+ if \the\luatexkodotemphcount == 1 then luatexko.activate("dotemph") end
+ luatexko.dotemphbox[\the\luatexkodotemphcount] = node.copy(tex.box[0].list)
+ }\luatexkodotemphattr\luatexkodotemphcount #1%
+ \endgroup }
+% uline
+\newcount\luatexkoulinecount
+\def\ulinedown{0.5ex }\def\ulinewidth{0.04em }
+\protected\def\markoverwith#1#{%
+ \ifx\empty#1\empty
+ \def\luatexkoleaderstype{101}% cleaders
+ \else
+ \def\luatexkoleaderstype{102}% xleaders
+ \fi
+ \luatexkomarkoverwith }
+\def\luatexkomarkoverwith#1#2{%
+ \global\advance\luatexkoulinecount\@ne
+ \begingroup
+ \count@\luatexkoulinecount
+ \ifx\luatexkoulinerunning\relax
+ \edef\ulinedown{\the\dimexpr\ulinedown+\ulinewidth+.15ex\relax}\fi
+ \let\luatexkoulinerunning\relax
+ \leavevmode
+ \setbox\z@\hbox{#1}%
+ \directlua{
+ if \the\luatexkoulinecount == 1 then luatexko.activate("uline") end
+ luatexko.ulboundary(\the\count@, tex.box[0].list, \luatexkoleaderstype)
+ }#2\directlua{
+ luatexko.ulboundary(\the\count@)
+ }\endgroup }
+\protected\def\uline{\markoverwith{%
+ \vrule width\z@ height-\ulinedown depth\dimexpr\ulinedown+\ulinewidth\relax }}
+\protected\def\dashuline{\markoverwith*{%
+ \hbox{\kern.125em
+ \vrule width.3em height-\ulinedown depth\dimexpr\ulinedown+\ulinewidth\relax
+ \kern.125em }}}
+\protected\def\dotuline{\markoverwith*{%
+ \lower\dimexpr\ulinedown+.1ex\relax\hbox{\kern.07em .\kern.07em }}}
+\protected\def\uuline#1{\uline{\uline{#1}}}
+\protected\def\sout#1{\begingroup
+ \def\ulinedown{-.5\dimexpr\ulinewidth+1ex\relax}%
+ \uline{#1}\endgroup}
+\protected\def\xout{\markoverwith{\hbox to.4em{\hss/\hss}}}
+\protected\def\uwave{\font\luatexkofontsixly=lasy6\relax
+ \markoverwith{\lower4\p@\hbox{\luatexkofontsixly\char58}}}
+% ruby
+\def\rubysize{0.6} % size of ruby compared to base chars
+\def\rubysep{0.1ex} % distance between base chars and ruby
+\def\luatexkostretchfactor{.0125} % .5em/20/2 is hard coded.
+\newif\ifruby@overlap
+\let\rubyoverlap\ruby@overlaptrue
+\let\rubynooverlap\ruby@overlapfalse
+\rubyoverlap % ruby may hangover neighboring chars
+\newcount\luatexkorubycount
+\def\luatexkorubybasehbox{\hbox attr\luatexkorubyalloc=\luatexkorubycount}
+\protected\def\ruby#1#2{%
+ \global\advance\luatexkorubycount\@ne
+ \begingroup
+ \leavevmode
+ \setbox\z@\luatexkorubybasehbox{#1}% base
+ \setbox\tw@\hbox{% ruby
+ \ifdefined\rubyfont \rubyfont \fi
+ \ifdefined\selectfont % <- latex
+ \dimen@\dimexpr\rubysize em\relax
+ \fontsize\dimen@\dimen@\selectfont
+ \fi
+ #2}%
+ \hbadness\@M % supress underfull warning
+ \dimen@ii\dimexpr\rubysize em\relax % ruby font size
+ \directlua{ luatexko.getrubystretchfactor(tex.box[2]) }% for intercharstretch
+ \ifdim\wd\z@ < \wd\tw@ % ruby is wider
+ \ifruby@overlap
+ \dimen@\dimexpr\wd\tw@-\wd\z@-\dimen@ii\relax % overhang .5 rubysize
+ \ifdim\dimen@ > \z@
+ \setbox\z@\luatexkorubybasehbox spread\dimen@{%
+ \hskip\z@ plus \luatexkostretchfactor em\relax
+ \unhbox\z@
+ \hskip\z@ plus \luatexkostretchfactor em\relax }%
+ \fi
+ \else
+ \setbox\z@\luatexkorubybasehbox to\wd\tw@{%
+ \hskip\z@ plus \luatexkostretchfactor em\relax
+ \unhbox\z@
+ \hskip\z@ plus \luatexkostretchfactor em\relax }%
+ \fi
+ \else
+ \ifdim\rubysize\wd\z@ > 2\wd\tw@ % ruby is far shorter
+ \setbox\tw@\hbox to\wd\z@{%
+ \hskip\dimen@ii plus 1sp\relax
+ \unhbox\tw@
+ \hskip\dimen@ii plus 1sp\relax }%
+ \else
+ \setbox\tw@\hbox to\wd\z@{%
+ \hskip\z@ plus \luatexkostretchfactor \dimen@ii\relax
+ \unhbox\tw@
+ \hskip\z@ plus \luatexkostretchfactor \dimen@ii\relax }%
+ \fi
+ \fi
+ \directlua{
+ if \the\luatexkorubycount == 1 then luatexko.activate("ruby") end
+ luatexko.rubybox[\the\luatexkorubycount] = {
+ node.copy(tex.box[2]),
+ \number\numexpr\dimexpr\rubysep\relax\relax,
+ \ifruby@overlap true\else false\fi, }}%
+ \box\z@
+ \endgroup }
+\protected\def\xxruby#1#2{%
+ \begingroup\def\basestr{#1}\def\rubystr{#2}\luatexkoxxruby\endgroup }
+\def\luatexkoxxruby{%
+ \ifx\empty\basestr\else
+ \expandafter\luatexkogetrubybasechar\basestr\end
+ \expandafter\luatexkogetrubyrubychar\rubystr\end
+ \ruby\basechar\rubychar
+ \expandafter\luatexkoxxruby
+ \fi }
+\def\luatexkogetrubybasechar#1#2\end{\def\basechar{#1}\def\basestr{#2}}
+\def\luatexkogetrubyrubychar#1#2\end{\def\rubychar{#1}\def\rubystr{#2}}
+% vertical writing
+\protected\def\vertical#1{%
+ \leavevmode
+ \setbox\z@\vbox\bgroup
+ \hsize#1\relax
+ \typesetvertical }
+\protected\def\endvertical{%
+ \egroup
+ \luatexkorotatebox\z@
+ \box\z@ }
+\protected\def\luatexkorotatebox#1{%
+ \setbox#1\hbox to\dimexpr\ht#1+\dp#1{%
+ \hfil
+ \vbox to\wd#1{%
+ \wd#1\z@ \ht#1\z@ \dp#1\z@
+ \pdfliteral{q 0 -1 1 0 0 0 cm}\box#1\pdfliteral{Q}%
+ \vfil }}}
+% horizontal box inside vertical writing
+\def\luatexkohorizboxmoveleft{0.5ex}
+\protected\def\horizontal#1{%
+ \directlua{ luatexko.gethorizboxmoveleft() }%
+ \leavevmode
+ \setbox\z@\vbox\bgroup
+ \hsize#1\relax
+ \typesetmodern }
+\protected\def\endhorizontal{%
+ \egroup
+ \luatexkounrotatebox\z@
+ \lower\luatexkohorizboxmoveleft\box\z@ }
+\protected\def\luatexkounrotatebox#1{%
+ \setbox#1\hbox to\dimexpr\ht#1+\dp#1{%
+ \vbox to\wd#1{%
+ \vfil
+ \wd#1\z@ \ht#1\z@ \dp#1\z@
+ \pdfliteral{q 0 1 -1 0 0 0 cm}\box#1\pdfliteral{Q}}%
+ \hfil }}
+% do not veticalize headline/footline
+\ifdefined\selectfont
+ \def\verticaltypesetting{%
+ \maxdepth\z@ \typesetvertical
+ \dimen@\textwidth \textwidth\textheight \textheight\dimen@
+ \edef\@outputpage{\unexpanded{\luatexkorotatebox\@outputbox
+ \textwidth\textheight}\unexpanded\expandafter{\@outputpage}}}
+\else
+ \def\verticaltypesetting{%
+ \dimen@\hsize \hsize\vsize \vsize\dimen@
+ \edef\plainoutput{\unexpanded{\dimen@\hsize \hsize\vsize \vsize\dimen@}%
+ \unexpanded\expandafter{\plainoutput}}%
+ \def\pagebody{\setbox\z@\vbox to\hsize{\boxmaxdepth=\maxdepth
+ \pagecontents}\luatexkorotatebox\z@\box\z@}%
+ \maxdepth\z@ \typesetvertical }
+\fi
+% hangul normalize
+\def\luatexhangulnormalize{%
+ \directlua{require"luatexko-normalize"}%
+ \afterassignment\luatexkohangulnormalize\count@}
+\def\luatexkohangulnormalize{%
+ \ifcase\count@ \directlua{ luatexko.normalize.unload() }% 0: none
+ \or \directlua{ luatexko.normalize.compose() }% 1: nfc
+ \else \directlua{ luatexko.normalize.decompose() }% 2: nfd
+ \fi }
+% convert uhc to utf8
+\def\luatexuhcinputencoding{%
+ \directlua{require"luatexko-uhc2utf8"}%
+ \afterassignment\luatexkouhcinputencoding\count@}
+\def\luatexkouhcinputencoding{%
+ \ifcase\count@ \directlua{ luatexko.uhc2utf8.stopconvert() }%
+ \else \directlua{ luatexko.uhc2utf8.startconvert() }%
+ \fi}
+% actualtext not provided
+\protected\def\actualtext#1#{\luatexkoactualtext}
+\def\luatexkoactualtext#1{#1}
+% math hangul
+\def\setmathhangulblock#1#2{%
+ \count@="#1
+ \loop
+ \Umathcode\count@ = 7 \symmathhangul\count@
+ \ifnum\count@<"#2 \advance\count@\@ne \repeat}
+% font fallback
+\newif\ifluatexkoselectfontrunning
+\def\luatexkohangulselectfont{%
+ \ifluatexkoselectfontrunning \else
+ \ifdefined\luatexkohangulfont
+ \begingroup
+ \luatexkoselectfontrunningtrue
+ \luatexkohangulfont
+ \expandafter\expandafter\expandafter\endgroup
+ \expandafter\luatexkohangulfontattr\fontid\font\relax
+ \fi
+ \fi }
+\def\luatexkohanjaselectfont{%
+ \ifluatexkoselectfontrunning \else
+ \ifdefined\luatexkohanjafont
+ \begingroup
+ \luatexkoselectfontrunningtrue
+ \luatexkohanjafont
+ \expandafter\expandafter\expandafter\endgroup
+ \expandafter\luatexkohanjafontattr\fontid\font\relax
+ \fi
+ \fi }
+\def\luatexkofallbackselectfont{%
+ \ifluatexkoselectfontrunning \else
+ \ifdefined\luatexkofallbackfont
+ \begingroup
+ \luatexkoselectfontrunningtrue
+ \luatexkofallbackfont
+ \expandafter\expandafter\expandafter\endgroup
+ \expandafter\luatexkofallbackfontattr\fontid\font\relax
+ \fi
+ \fi }
+% plain
+\ifdefined\selectfont\else
+ \protected\def\hangulfont{%
+ \afterassignment\luatexkohangulselectfont\font\luatexkohangulfont}
+ \protected\def\hanjafont{%
+ \afterassignment\luatexkohanjaselectfont\font\luatexkohanjafont}
+ \protected\def\fallbackfont{%
+ \afterassignment\luatexkofallbackselectfont\font\luatexkofallbackfont}
+ \newfam\symmathhangul
+ \protected\def\setmathhangulfonts#1#2#3{% font identifiers
+ \ifnum\Umathcharfam"AC00=\symmathhangul\else
+ \setmathhangulblock{AC00}{D7A3}%
+ \fi
+ \textfont\symmathhangul=#1\relax
+ \scriptfont\symmathhangul=#2\relax
+ \scriptscriptfont\symmathhangul=#3\relax }
+ \protected\def\mathhangulfont{%
+ \afterassignment\luatexkosetmathhangulfonts\font\textmathhangul}
+ \def\luatexkosetmathhangulfonts{%
+ \toks@\expandafter{\directlua{
+ local n = string.gsub("\fontname\textmathhangul", " at .+", "")
+ tex.sprint(n) }}%
+ \dimen@\fontdimen 6 \textmathhangul
+ \font\scriptmathhangul= {\the\toks@} at .7\dimen@
+ \font\scriptscriptmathhangul = {\the\toks@} at .5\dimen@
+ \setmathhangulfonts\textmathhangul\scriptmathhangul\scriptscriptmathhangul}
+ \catcode`\@=\luatexkoatcatcode
+\endinput\fi
+% latex
+\RequirePackage{everysel}
+\EverySelectfont{%
+ \ifx\f@encoding\UTFencname
+ \luatexkohangulselectfont
+ \luatexkohanjaselectfont
+ \luatexkofallbackselectfont
+ \fi }
+\protected\def\fontfamily#1{\edef\f@family{#1}% redefine \fontfamily
+ \ifx\f@encoding\UTFencname
+ \ifluatexkoselectfontrunning \else
+ \ifx\f@family\rmdefault
+ \let\luatexkohangulfont\luatexkomainhangulfont
+ \let\luatexkohanjafont\luatexkomainhanjafont
+ \let\luatexkofallbackfont\luatexkomainfallbackfont
+ \else\ifx\f@family\sfdefault
+ \let\luatexkohangulfont\luatexkosanshangulfont
+ \let\luatexkohanjafont\luatexkosanshanjafont
+ \let\luatexkofallbackfont\luatexkosansfallbackfont
+ \else\ifx\f@family\ttdefault
+ \let\luatexkohangulfont\luatexkomonohangulfont
+ \let\luatexkohanjafont\luatexkomonohanjafont
+ \let\luatexkofallbackfont\luatexkomonofallbackfont
+ \fi\fi\fi
+ \fi\fi }
+% fontspec-like
+\ExplSyntaxOn
+\DeclareDocumentCommand \setmainhangulfont { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkomainhangulfamily { Ligatures=TeX, #1, #3 } { #2 }
+ \DeclareRobustCommand \luatexkomainhangulfont
+ {
+ \fontfamily \luatexkomainhangulfamily \selectfont
+ }
+ \str_if_eq_x:nnT \familydefault \rmdefault
+ {
+ \cs_set_eq:NN \luatexkohangulfont \luatexkomainhangulfont
+ \luatexkohangulselectfont
+ }
+ \ignorespaces
+}
+\DeclareDocumentCommand \setsanshangulfont { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkosanshangulfamily { Ligatures=TeX, #1, #3 } { #2 }
+ \DeclareRobustCommand \luatexkosanshangulfont
+ {
+ \fontfamily \luatexkosanshangulfamily \selectfont
+ }
+ \str_if_eq_x:nnT \familydefault \sfdefault
+ {
+ \cs_set_eq:NN \luatexkohangulfont \luatexkosanshangulfont
+ \luatexkohangulselectfont
+ }
+ \ignorespaces
+}
+\DeclareDocumentCommand \setmonohangulfont { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkomonohangulfamily { #1, #3 } { #2 }
+ \DeclareRobustCommand \luatexkomonohangulfont
+ {
+ \fontfamily \luatexkomonohangulfamily \selectfont
+ }
+ \str_if_eq_x:nnT \familydefault \ttdefault
+ {
+ \cs_set_eq:NN \luatexkohangulfont \luatexkomonohangulfont
+ \luatexkohangulselectfont
+ }
+ \ignorespaces
+}
+\DeclareDocumentCommand \newhangulfontfamily { m O{} m O{} }
+{
+ \fontspec_set_family:cnn { luatexko_user_family_ \cs_to_str:N #1 } { #2, #4 } { #3 }
+ \DeclareRobustCommand #1
+ {
+ \tl_set:Nn \luatexkohangulfont
+ {
+ \exp_args:Nc \fontfamily { luatexko_user_family_ \cs_to_str:N #1 } \selectfont
+ }
+ \luatexkohangulselectfont
+ }
+ \ignorespaces
+}
+\DeclareDocumentCommand \newhangulfontface { m O{} m O{} }
+{
+ \newhangulfontfamily #1 { #3 } [ BoldFont={}, ItalicFont={}, SmallCapsFont={}, #2, #4 ]
+}
+\DeclareDocumentCommand \hangulfontspec { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkohangulfontfamily { #1, #3 } { #2 }
+ \tl_set:Nn \luatexkohangulfont
+ {
+ \fontfamily \luatexkohangulfontfamily \selectfont
+ }
+ \luatexkohangulselectfont
+ \ignorespaces
+}
+\DeclareDocumentCommand \setmainhanjafont { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkomainhanjafamily { Ligatures=TeX, #1, #3 } { #2 }
+ \DeclareRobustCommand \luatexkomainhanjafont
+ {
+ \fontfamily \luatexkomainhanjafamily \selectfont
+ }
+ \str_if_eq_x:nnT \familydefault \rmdefault
+ {
+ \cs_set_eq:NN \luatexkohanjafont \luatexkomainhanjafont
+ \luatexkohanjaselectfont
+ }
+ \ignorespaces
+}
+\DeclareDocumentCommand \setsanshanjafont { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkosanshanjafamily { Ligatures=TeX, #1, #3 } { #2 }
+ \DeclareRobustCommand \luatexkosanshanjafont
+ {
+ \fontfamily \luatexkosanshanjafamily \selectfont
+ }
+ \str_if_eq_x:nnT \familydefault \sfdefault
+ {
+ \cs_set_eq:NN \luatexkohanjafont \luatexkosanshanjafont
+ \luatexkohanjaselectfont
+ }
+ \ignorespaces
+}
+\DeclareDocumentCommand \setmonohanjafont { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkomonohanjafamily { #1, #3 } { #2 }
+ \DeclareRobustCommand \luatexkomonohanjafont
+ {
+ \fontfamily \luatexkomonohanjafamily \selectfont
+ }
+ \str_if_eq_x:nnT \familydefault \ttdefault
+ {
+ \cs_set_eq:NN \luatexkohanjafont \luatexkomonohanjafont
+ \luatexkohanjaselectfont
+ }
+ \ignorespaces
+}
+\DeclareDocumentCommand \newhanjafontfamily { m O{} m O{} }
+{
+ \fontspec_set_family:cnn { luatexko_user_family_ \cs_to_str:N #1 } { #2, #4 } { #3 }
+ \DeclareRobustCommand #1
+ {
+ \tl_set:Nn \luatexkohanjafont
+ {
+ \exp_args:Nc \fontfamily { luatexko_user_family_ \cs_to_str:N #1 } \selectfont
+ }
+ \luatexkohanjaselectfont
+ }
+ \ignorespaces
+}
+\DeclareDocumentCommand \newhanjafontface { m O{} m O{} }
+{
+ \newhanjafontfamily #1 { #3 } [ BoldFont={}, ItalicFont={}, SmallCapsFont={}, #2, #4 ]
+}
+\DeclareDocumentCommand \hanjafontspec { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkohanjafontfamily { #1, #3 } { #2 }
+ \tl_set:Nn \luatexkohanjafont
+ {
+ \fontfamily \luatexkohanjafontfamily \selectfont
+ }
+ \luatexkohanjaselectfont
+ \ignorespaces
+}
+
+\DeclareDocumentCommand \setmainfallbackfont { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkomainfallbackfamily { Ligatures=TeX, #1, #3 } { #2 }
+ \DeclareRobustCommand \luatexkomainfallbackfont
+ {
+ \fontfamily \luatexkomainfallbackfamily \selectfont
+ }
+ \str_if_eq_x:nnT \familydefault \rmdefault
+ {
+ \cs_set_eq:NN \luatexkofallbackfont \luatexkomainfallbackfont
+ \luatexkofallbackselectfont
+ }
+ \ignorespaces
+}
+\DeclareDocumentCommand \setsansfallbackfont { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkosansfallbackfamily { Ligatures=TeX, #1, #3 } { #2 }
+ \DeclareRobustCommand \luatexkosansfallbackfont
+ {
+ \fontfamily \luatexkosansfallbackfamily \selectfont
+ }
+ \str_if_eq_x:nnT \familydefault \sfdefault
+ {
+ \cs_set_eq:NN \luatexkofallbackfont \luatexkosansfallbackfont
+ \luatexkofallbackselectfont
+ }
+ \ignorespaces
+}
+\DeclareDocumentCommand \setmonofallbackfont { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkomonofallbackfamily { #1, #3 } { #2 }
+ \DeclareRobustCommand \luatexkomonofallbackfont
+ {
+ \fontfamily \luatexkomonofallbackfamily \selectfont
+ }
+ \str_if_eq_x:nnT \familydefault \ttdefault
+ {
+ \cs_set_eq:NN \luatexkofallbackfont \luatexkomonofallbackfont
+ \luatexkofallbackselectfont
+ }
+ \ignorespaces
+}
+\DeclareDocumentCommand \newfallbackfontfamily { m O{} m O{} }
+{
+ \fontspec_set_family:cnn { luatexko_user_family_ \cs_to_str:N #1 } { #2, #4 } { #3 }
+ \DeclareRobustCommand #1
+ {
+ \tl_set:Nn \luatexkofallbackfont
+ {
+ \exp_args:Nc \fontfamily { luatexko_user_family_ \cs_to_str:N #1 } \selectfont
+ }
+ \luatexkofallbackselectfont
+ }
+ \ignorespaces
+}
+\DeclareDocumentCommand \newfallbackfontface { m O{} m O{} }
+{
+ \newfallbackfontfamily #1 { #3 } [ BoldFont={}, ItalicFont={}, SmallCapsFont={}, #2, #4 ]
+}
+\DeclareDocumentCommand \fallbackfontspec { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkofallbackfontfamily { #1, #3 } { #2 }
+ \tl_set:Nn \luatexkofallbackfont
+ {
+ \fontfamily \luatexkofallbackfontfamily \selectfont
+ }
+ \luatexkofallbackselectfont
+ \ignorespaces
+}
+\DeclareDocumentCommand \setmathhangulfont { O{} m O{} }
+{
+ \fontspec_set_family:Nnn \luatexkomathhangulfamily { #1, #3 } { #2 }
+ \DeclareSymbolFont { mathhangul }
+ \g_fontspec_encoding_tl \luatexkomathhangulfamily \mddefault \updefault
+ \int_compare:nNnF { \Umathcharfam"AC00 } = { \symmathhangul }
+ {
+ \setmathhangulblock{AC00}{D7A3}
+ }
+ \ignorespaces
+}
+\ExplSyntaxOff
+\let\adhochangulfont\hangulfontspec
+\let\adhochanjafont\hanjafontspec
+\let\adhocfallbackfont\fallbackfontspec
+% interhangul, interlatincjk, charraise
+\protected\def\addhangulfontfeature#1{%
+ \begingroup
+ \ifdefined\luatexkohangulfont \luatexkohangulfont \fi
+ \addfontfeature{#1}%
+ \edef\x{\endgroup
+ \def\noexpand\luatexkohangulfont{%
+ \noexpand\fontfamily{\f@family}\noexpand\selectfont}}\x
+ \luatexkohangulselectfont
+ \ignorespaces}
+\let\addhangulfontfeatures\addhangulfontfeature
+\protected\def\addhanjafontfeature#1{%
+ \begingroup
+ \ifdefined\luatexkohanjafont \luatexkohanjafont \fi
+ \addfontfeature{#1}%
+ \edef\x{\endgroup
+ \def\noexpand\luatexkohanjafont{%
+ \noexpand\fontfamily{\f@family}\noexpand\selectfont}}\x
+ \luatexkohanjaselectfont
+ \ignorespaces}
+\let\addhanjafontfeatures\addhanjafontfeature
+\protected\def\addfallbackfontfeature#1{%
+ \begingroup
+ \ifdefined\luatexkofallbackfont \luatexkofallbackfont \fi
+ \addfontfeature{#1}%
+ \edef\x{\endgroup
+ \def\noexpand\luatexkofallbackfont{%
+ \noexpand\fontfamily{\f@family}\noexpand\selectfont}}\x
+ \luatexkofallbackselectfont
+ \ignorespaces}
+\let\addfallbackfontfeatures\addfallbackfontfeature
+\newfontfeature{InterHangul}{interhangul=#1}
+\newfontfeature{InterLatinCJK}{interlatincjk=#1}
+\newfontfeature{CharRaise}{charraise=#1}
+\newfontfeature{RemoveClassicSpaces}{+removeclassicspaces}
+\newfontfeature{CompressPunctuations}{+compresspunctuations}
+\newfontfeature{Expansion}{expansion=\ifx\empty#1\empty default\else #1\fi }
+\newfontfeature{Protrusion}{protrusion=\ifx\empty#1\empty default\else #1\fi }
+\newfontfeature{InterCharacter}{intercharacter=#1}
+\newfontfeature{InterCharStretch}{intercharstretch=#1}
+% italic correction
+\def\nocorrlist{,.^^^^3001^^^^3002^^^^ff0c^^^^ff0e^^^^ff61^^^^ff64}
+% package options
+\newif\if@hangul
+\newif\if@hanja
+\DeclareOption{hangul}{\@hangultrue}
+\DeclareOption{hanja}{\@hangultrue\@hanjatrue}
+\ProcessOptions\relax
+% default hangul font
+\AtBeginDocument{
+ \ifdefined\luatexkomainhangulfont\else
+ \begingroup\rmfamily
+ \directlua{ luatexko.currenthashangulchars(255) }\expandafter\endgroup
+ \ifnum\count@=\z@
+ \setmainhangulfont{UnBatang}[Script=Hangul,Language=Korean]\fi\fi
+ \ifdefined\luatexkosanshangulfont\else
+ \begingroup\sffamily
+ \directlua{ luatexko.currenthashangulchars(255) }\expandafter\endgroup
+ \ifnum\count@=\z@
+ \setsanshangulfont{UnDotum}\fi\fi
+ \ifdefined\luatexkomonohangulfont\else
+ \begingroup\ttfamily
+ \directlua{ luatexko.currenthashangulchars(255) }\expandafter\endgroup
+ \ifnum\count@=\z@
+ \let\luatexkomonohangulfont\luatexkosanshangulfont\fi\fi
+ \@ifpackageloaded{hyperref}{\pdfstringdefDisableCommands{%
+ \let\ruby\@firstoftwo \let\xxruby\@firstoftwo
+ \let\dotemph\@firstofone
+ \let\markoverwith\@secondoftwo
+ \let\uline\@firstofone \let\sout\@firstofone
+ \let\uuline\@firstofone \let\xout\@firstofone
+ \let\uwave\@firstofone \let\dashuline\@firstofone
+ \let\dotuline\@firstofone
+ \let\typesetclassic\empty \let\typesetmodern\empty
+ \let\inhibitglue\empty
+ \let\hangulpunctuations\count@
+ \let\registerpunctuations\@gobble \let\unregisterpunctuations\@gobble
+ \let\registerhangulpunctuations\@gobble
+ \let\unregisterhangulpunctuations\@gobble
+ \let\registerbreakableafter\@gobble \let\registerbreakablebefore\@gobble
+ \let\hangulbyhangulfont\count@ \let\hanjabyhanjafont\count@
+ \let\addhangulfontfeature\@gobble \let\addhangulfontfeatures\@gobble
+ \let\addhanjafontfeature\@gobble \let\addhanjafontfeatures\@gobble
+ \let\addfallbackfontfeature\@gobble \let\addfallbackfontfeatures\@gobble
+ \def\는{는}\def\ì€{ì€}\def\ì„{ì„}\def\를{를}\def\와{와}\def\ê³¼{ê³¼}%
+ \def\ê°€{ê°€}\def\ì´{ì´}\def\ë¼{ë¼}\def\으{으}\def\ë¡œ{ë¡œ}%
+ \def\hellipsis{...}}}{}
+ \if@hangul \RequirePackage{konames-utf}\fi
+}
+% misc
+\RequirePackage{kolabels-utf}
+\protected\def\hellipsis{\char"2026\char"2026 }
+\if@hangul
+ \linespread{1.3888}
+ \footnotesep=1.3888\footnotesep
+ \skip\footins=\glueexpr\skip\footins/72*100\relax
+ \frenchspacing
+\fi
+\endinput
diff --git a/macros/luatex/generic/luatextra b/macros/luatex/generic/luatextra
new file mode 120000
index 0000000000..146a6052b7
--- /dev/null
+++ b/macros/luatex/generic/luatextra
@@ -0,0 +1 @@
+../latex/luatextra \ No newline at end of file
diff --git a/macros/luatex/generic/luavlna/README.md b/macros/luatex/generic/luavlna/README.md
new file mode 100644
index 0000000000..366cd21700
--- /dev/null
+++ b/macros/luatex/generic/luavlna/README.md
@@ -0,0 +1,119 @@
+# Luavlna, version v0.1c, 2019-04-16
+
+# Introduction
+
+`Luavlna` is a small package for plain LuaTeX and LuaLaTeX. In some languages,
+like Czech or Polish, there should be no single letter words at the
+line end, according to the typographical norms. There exists some
+external commands (like `vlna`) or packages (`encxvlna` for encTeX,
+`xevlna` for XeTeX, `impnattypo` for LuaLaTeX).
+
+Other feature of this package is including of non-breakable space after initials,
+like in personal names, after or before academic degrees
+and between numbers and units (SI and others).
+
+The code is modified version of Patrick Gundlach’s answer on
+TeX.sx[^1]. The difference is that it is possible to specify which
+single letters should be taken into account for different
+languages.
+The support for degrees and units was added as well.
+
+# Usage
+
+The usage is simple:
+
+ \input ucode
+ \uselanguage{czech}
+ %% in the case of luacsplain, use instead:
+ %% \chyph
+ %% but language code for Czech is different than in LaTeX or normal
+ %% LuaTeX, so you will need to set single letters with somethinh like:
+ %% \singlechars{5}{AIiVvOoUuSsZzKk}
+ \input luavlna
+ \preventsingledebugon
+ \input luaotfload.sty
+ \font\hello={name:Linux Libertine O:+rlig;+clig;+liga;+tlig} at 12pt
+ \hsize=3in
+ \hello
+ PříliÅ¡ žluÅ¥ouÄký kůň úpÄ›l Äábelské ódy.
+ Text s krátkými souhláskami a samohláskami i dalšími jevy
+ z nabídky možností (v textu možnými).
+
+ I zaÄátek odstavce je tÅ™eba Å™eÅ¡it, i když výskyt zalomení není pravdÄ›podobný.
+
+ Co třeba í znaky š diakritikou?
+
+ Různé možnosti [v závorkách <i jiných znacích
+
+ Podpora iniciál a titulů: M. J. Hegel, Ing. Běháková, Ph.D., Ž. Zíbrt.
+
+ Podpora jednotek: 100,5 MN\cdot{}s, 100.5 kJ, 200 µA, $-1$ dag, 12 MiB, 1 m$^3$/s.
+
+ \preventsingledebugoff
+ \bye
+
+
+It is also possible to use the package with lua, just use
+
+ \usepackage{luavlna}
+
+in the preamble.
+
+# Commands
+
+ \singlechars{language name}{letters}
+
+Enable this feature for certain letters in given language.
+
+Default values:
+
+ %% only Czech and Slovak are supported out of the box
+ \singlechars{czech}{AIiVvOoUuSsZzKk}
+ \singlechars{slovak}{AIiVvOoUuSsZzKk}
+
+ \compoundinitials{language name}{compounds}
+
+Declare compound letters for given language. Second argument should be comma
+separated list of compound letters, in exact form in which they can appear.
+
+Default values:
+
+ \compoundinitials{czech}{Ch}
+
+##Turning off language switching
+
+By default, language of the nodes is taken into account. If you want to use
+settings for one language for a whole document, you can use following command:
+
+ \preventsinglelang{language name}
+
+##Turning off processing
+
+If you want to stop processing of the spaces in the document you can use
+command
+
+ \preventsingleoff
+
+To resume processing, use
+
+ \preventsingleon
+
+## Debugging commands
+
+ \preventsingledebugon
+ \preventsingledebugoff
+
+Insert debugging marks on/off. Default off.
+
+# Authors
+
+Michal Hoftich
+Miro HronÄok
+
+# License
+
+Permission is granted to copy, distribute and/or modify this software
+under the terms of the LaTeX Project Public License, version 1.3.
+
+[^1]:
+ <http://tex.stackexchange.com/a/28128/2891>
diff --git a/macros/luatex/generic/luavlna/luavlna-csplain-langs.lua b/macros/luatex/generic/luavlna/luavlna-csplain-langs.lua
new file mode 100644
index 0000000000..f4e1ccea16
--- /dev/null
+++ b/macros/luatex/generic/luavlna/luavlna-csplain-langs.lua
@@ -0,0 +1,21 @@
+local languages = {}
+local function parse_language_lan(content)
+ for name, id in content:gmatch("preplang%s+.-%s+(.-)%s+.-%s(.-)%s+") do
+ -- skip invalid languages
+ if not name:match("%#") then
+ languages[name] = id
+ end
+ end
+end
+
+local langfile = kpse.find_file("lua-hyphen.lan")
+if langfile then
+ local f = io.open(langfile, "r")
+ local content = f:read("*all")
+ parse_language_lan(content)
+ f:close()
+end
+
+
+return languages
+
diff --git a/macros/luatex/generic/luavlna/luavlna-doc.pdf b/macros/luatex/generic/luavlna/luavlna-doc.pdf
new file mode 100644
index 0000000000..c929578013
--- /dev/null
+++ b/macros/luatex/generic/luavlna/luavlna-doc.pdf
Binary files differ
diff --git a/macros/luatex/generic/luavlna/luavlna-doc.tex b/macros/luatex/generic/luavlna/luavlna-doc.tex
new file mode 100644
index 0000000000..1519d7fe9f
--- /dev/null
+++ b/macros/luatex/generic/luavlna/luavlna-doc.tex
@@ -0,0 +1,266 @@
+\documentclass[12pt]{ltxdoc}
+%\documentclass{article}
+%\usepackage[utf8]{luainputenc}
+\usepackage{fontspec}
+\setmainfont[Ligatures=TeX]{Linux Libertine O}
+\usepackage[czech,english]{babel}
+\usepackage{luacode}
+\usepackage{amsfonts}
+%\usepackage[]{polyglossia}
+%\setmainlanguage{english}
+%\setotherlanguage{czech}
+%\usepackage{url}
+\usepackage{hyperref}
+%\input prevent-single
+%\usepackage[]{prevent-single}
+\usepackage[]{luavlna}
+%\input prevent-single
+%\def\preventsingledebugon{}
+\newenvironment{mycode}{
+ %\leavevmode%
+ \medskip%
+ \parindent=0pt%
+}{\medskip}
+
+\ifdefined\version\else
+ \def\version{{{VERSION}}}
+ \let\gitdate\date
+\fi
+
+\begin{document}
+\title{The \verb|luavlna| package}
+\author{Michal Hoftich (\url{michal.h21@gmail.com})\\Miro HronÄok (\url{miro@hroncok.cz})}
+\date{Version \version\\\gitdate}
+\maketitle
+\tableofcontents
+\section{Introduction}
+
+
+This is a small package for plain Lua\TeX and Lua\LaTeX. In some languages, like
+Czech or Polish, there should be no single letter words at the line
+end, according to the typographical norms. There exists some
+external commands (like \verb!vlna!) or packages (\verb!encxvlna!
+for enc\TeX, \verb!xevlna! for Xe\TeX,
+\verb!impnattypo! for Lua\LaTeX). %This package is for plain
+%lua\TeX and for lua\LaTeX.
+
+Other feature of this package is including of non-breakable space after
+initials, like in personal names, after or before academic degrees
+and between numbers and units (SI and others).
+
+The code is modified version of Patrick Gundlach's answer on
+TeX.sx\footnote{\url{http://tex.stackexchange.com/a/28128/2891}}.
+The difference is that it is possible to specify which single letters
+should be taken into account for different languages.
+The support for degrees and units was added as well.
+% The code works also for single letters at the beginning of the brackets.
+
+
+\section{Usage}
+
+The usage is simple:
+
+\begin{verbatim}
+\input ucode
+\uselanguage{czech}
+%% in the case of luacsplain, use instead:
+%% \chyph
+\input luavlna
+\preventsingledebugon
+\input luaotfload.sty
+\font\hello={name:Linux Libertine O:+rlig;+clig;+liga;+tlig} at 12pt
+\hsize=3in
+\hello
+PříliÅ¡ žluÅ¥ouÄký kůň úpÄ›l Äábelské ódy.
+Text s krátkými souhláskami a samohláskami i dalšími jevy
+z nabídky možností (v textu možnými).
+
+I zaÄátek odstavce je tÅ™eba Å™eÅ¡it, i když výskyt zalomení
+není pravděpodobný.
+
+Co třeba í znaky š diakritikou?
+
+Různé možnosti [v závorkách <i jiných znacích
+
+Podpora iniciál a titulů: M. J. Hegel, Ing. Běháková, Ph.D., Ž. Zíbrt.
+
+Podpora jednotek: 100,5 MN\cdot{}s, 100.5 kJ, 200 µA, $-1$ dag,
+12 MiB, 1 m$^3$/s.
+
+Uvnitř matematiky by mělo být zpracování vypnuté: $k \in \mathbb N$.
+PokraÄujeme v příkladu.
+
+\preventsingledebugoff
+\bye
+\end{verbatim}
+
+%\noindent\parbox{3in}{%
+
+\noindent
+\begin{minipage}{3in}
+\preventsingledebugon
+\selectlanguage{czech}
+PříliÅ¡ \textit{žluÅ¥ouÄký kůň} úpÄ›l Äábelské ódy.
+Text s krátkými souhláskami a samohláskami i dalšími jevy z nabídky možností (v textu možnými).
+
+I zaÄátek odstavce je tÅ™eba Å™eÅ¡it, i když výskyt zalomení není pravdÄ›podobný.
+
+Co třeba í znaky š diakritikou?
+
+Různé možnosti [v závorkách \textless i jiných znacích
+
+Podpora iniciál a titulů: M. J. Hegel, Ing. Běháková, Ph.D., Ž. Zíbrt.
+
+Podpora jednotek: 100,5 MN\cdot{}s, 100.5 kJ, 200 µA, $-1$ dag, 12 MiB, 1 m$^3$/s.
+
+UvnitÅ™ matematiky by mÄ›lo být zpracování vypnuté: $k \in \mathbb N$. PokraÄujeme v příkladu.
+
+\preventsingledebugoff
+%}
+\end{minipage}
+
+\selectlanguage{english}
+\bigskip
+It is also possible to use the package with Lua\LaTeX, just use
+
+\begin{verbatim}
+ \usepackage{luavlna}
+\end{verbatim}
+
+in the preamble.
+
+\section{Commands}
+
+\begin{mycode}
+\cmd{\singlechars}\marg{language name}\marg{letters}
+\end{mycode}
+
+Enable this feature for certain letters in given language.
+%Language code is internall \TeX\ code for the language, it is $0$ for English,
+%$16$ for Czech. Please note that in \verb|csplain|, language code for Czech
+%is $5$ and you will have to set it yourself.
+
+Default values:
+
+\begin{mycode}
+\begin{verbatim}
+%% only Czech and Slovak are supported out of the box
+\singlechars{czech}{AIiVvOoUuSsZzKk}
+\singlechars{slovak}{AIiVvOoUuSsZzKk}
+\end{verbatim}
+\end{mycode}
+
+%By default, all
+%single letters are processed, this command can be used to pass a
+%string of characters, which should be processed only.
+
+\begin{mycode}
+\cmd{\compoundinitials}\marg{language name}\marg{compounds}
+\end{mycode}
+
+Declare compound letters for given language. Second argument should be comma
+separated list of compound letters, in exact form in which they can appear.
+
+Default values:
+
+\begin{mycode}
+\begin{verbatim}
+\compoundinitials{czech}{Ch,CH}
+\end{verbatim}
+\end{mycode}
+
+\subsection{Turning off language switching}
+
+By default, language of the nodes is taken into account. If you want to use
+settings for one language for a whole document, you can use following command:
+
+\begin{mycode}
+\cmd{\preventsinglelang}\marg{language name}
+\end{mycode}
+
+\subsection{Turning off processing}
+
+If you want to stop processing of the spaces in the document you can use command
+
+\begin{mycode}
+\cmd{\preventsingleoff}
+\end{mycode}
+
+To resume processing, use
+
+\begin{mycode}
+\cmd{\preventsingleon}
+\end{mycode}
+
+You can also disable units and degrees processing:
+
+\begin{mycode}
+ \cmd{\nounits}\\
+ \cmd{\nopredegrees}\\
+ \cmd{\nosufdegrees}
+\end{mycode}
+
+\subsection{Debugging commands}
+\begin{mycode}
+\cmd{\preventsingledebugon}\par
+\cmd{\preventsingledebugoff}
+\end{mycode}
+
+Insert debugging marks on/off. Default off.
+
+\section{Lua module \texttt{luavlna-langno.lua}}
+
+When we process glyph nodes with Lua\TeX\ callbacks, there are \verb|lang|
+fields available. These are numerical codes of languages, but no information
+about language names easily accesible from Lua side is available.\footnote{%
+ Language names are stored in \TeX macros like \verb|\string\l@langname|, but
+ different formats use different naming of these macros}
+These numbers are format dependent, majority of formats like
+Lua\LaTeX use \verb|language.dat| file provided by \verb|babel|
+for assign numbers to languages, but for example \verb|csplain|
+use its own system.
+
+To allow easy setting of language dependent parameters, \verb|langno| module
+was created. It's purpose is to translate language code to language name and
+the other way. Lua\LaTeX, Lua\TeX\ and CSplain formats are supported at the moment.
+
+\subsection{Recognized languages}
+\subsubsection{Lua\TeX\ and Lua\LaTeX}
+
+File \verb|language.dat| is processed to load language names, aliases and assigned numbers. These language names are the same as names supported by the \verb|babel| package.
+
+\begin{quotation}
+ \small\noindent
+\begin{luacode*}
+ langno = require "luavlna-langno"
+ function print_format_lang(fmt)
+ local luatex = langno.load_languages(fmt)
+ local t = {}
+ for k, v in pairs(luatex.names) do
+ t[#t+1]=k
+ end
+ table.sort(t)
+ tex.print(table.concat(t,", "))
+ end
+ print_format_lang("luatex")
+\end{luacode*}
+\end{quotation}
+
+\subsubsection{CSplain}
+
+Different method is used with the CSplain format. The \verb|lua-hyphen.lan| file is parsed for the language codes.
+
+\begin{quotation}
+ \small\noindent
+ \begin{luacode*}
+ print_format_lang("csplain")
+ \end{luacode*}
+\end{quotation}
+
+
+\section{License}
+
+Permission is granted to copy, distribute and/or modify this software
+under the terms of the LaTeX Project Public License, version 1.3.
+
+\end{document}
diff --git a/macros/luatex/generic/luavlna/luavlna-langno.lua b/macros/luatex/generic/luavlna/luavlna-langno.lua
new file mode 100644
index 0000000000..f703e4328a
--- /dev/null
+++ b/macros/luatex/generic/luavlna/luavlna-langno.lua
@@ -0,0 +1,119 @@
+-- langno.lua
+-- library for working with luatex's language numbers
+-- glyph nodes have numerical lang field, but the language names for
+-- these numbers aren't saved.
+--
+-- this library tries to find language names by parsing `language.dat` file
+--
+
+local M = {}
+
+local tex = tex or {}
+
+local format = tex.formatname -- or "luatex"
+
+-- languages object
+local lang_obj = function(names, numbers)
+ local obj = {}
+ obj.__index = obj
+ local self = setmetatable({},obj)
+ self.names = names
+ self.numbers = numbers
+ -- get language name by number
+ self.get_name = function(self, number)
+ return self.numbers[number]
+ end
+ -- get language number by name
+ self.get_number = function(self, name)
+ return self.names[name]
+ end
+ return self
+end
+
+
+-- default language loader, language.dat file is parsed
+local load_lang_dat = function(start)
+ -- languages are saved in the file language.dat
+ local lang_dat = kpse.find_file("language.dat")
+ if not lang_dat then
+ return nil, "Cannot load file language.dat"
+ end
+ local f = io.open(lang_dat, "r")
+ local i = start or 0
+ local numlang = {} -- return language name
+ local langnum = {} -- return language number
+ for line in f:lines() do
+ -- match comment, equal sign and first word on a line
+ local first, language = line:match("%s*([%%%=]?)([%a]*)")
+ if first ~="%" then -- ignore comments
+ langnum[language] = i
+ if first ~="=" then -- on lines starting with eq are language synonyms
+ --print(i, language)
+ numlang[i] = language
+ i = i + 1
+ end
+ end
+ end
+ return lang_obj(langnum, numlang)--{numbers = numlang, names = langnum}
+end
+
+local load_lang_dat_lualatex = function()
+ return load_lang_dat(1)
+end
+
+local load_csplain= function()
+ local l = require "luavlna-csplain-langs"
+ local langnum = {}
+ local numlang = {}
+ for k, v in pairs(l) do
+ local first = k:gsub(" *;.*","")
+ langnum[first] = v
+ for _,i in ipairs(v) do
+ numlang[i] = first
+ end
+ end
+ return lang_obj(langnum, numlang)
+end
+
+
+-- because different formats may use different ways to load languages
+-- driver mechanism is provided.
+local drivers = {}
+drivers["lualatex"] = load_lang_dat_lualatex
+drivers["luatex"] = load_lang_dat
+drivers["default"] = load_lang_dat
+drivers["csplain"] = load_csplain
+drivers["pdfcsplain"] = load_csplain
+drivers["luacsplain"] = load_csplain
+
+local load_languages = function(name)
+ local name = name or format
+ print ("Load driver: "..name)
+ local func = drivers[name] or drivers["default"]
+ if not func then return nil, "Cannot find driver function "..name end
+ return func()
+end
+
+-- only load_languages function is provided to the outside world
+M.load_languages = load_languages
+
+return M
+--[[
+
+-- sample usage:
+local j = load_languages()
+print(j:get_name(16))
+print(j:get_number("slovak"))
+for k, v in pairs(j.numbers) do
+ print(k,v)
+end
+--]]
+
+-- this may be used in future, if I find a way how does local language.dat
+-- affect language loading
+-- load local language.dat
+--[[
+local loc = kpse.var_value('TEXMFLOCAL') .. "tex/generic/config/language.dat"
+local f, msg = io.open(loc, "r")
+f:read("*all")
+--]]
diff --git a/macros/luatex/generic/luavlna/luavlna-predegrees.lua b/macros/luatex/generic/luavlna/luavlna-predegrees.lua
new file mode 100644
index 0000000000..995b00558f
--- /dev/null
+++ b/macros/luatex/generic/luavlna/luavlna-predegrees.lua
@@ -0,0 +1,65 @@
+return {
+ "ak.",
+ "akad.",
+ "arch.",
+ "arm.",
+ "art.",
+ "Bc.",
+ "BcA.",
+ "brig.",
+ "Äet.",
+ "des.",
+ "Dipl.-Ing.",
+ "doc.",
+ "dr.",
+ "Dr.",
+ "Dr.-Ing.",
+ "gen.",
+ "genmjr.",
+ "genplk.",
+ "genpor.",
+ "ICDr.",
+ "ing.",
+ "Ing.",
+ "JUDr.",
+ "kpt.",
+ "mal.",
+ "MDDr.",
+ "MgA.",
+ "Mgr.",
+ "mjr.",
+ "MSDr.",
+ "MUDr.",
+ "MVDr.",
+ "npor.",
+ "nprap.",
+ "nrtm.",
+ "nstržm.",
+ "PaedDr.",
+ "PharmDr.",
+ "PhDr.",
+ "PhMr.",
+ "plk.",
+ "por.",
+ "pplk.",
+ "ppor.",
+ "pprap.",
+ "prap.",
+ "prof.",
+ "RCDr.",
+ "RNDr.",
+ "RSDr.",
+ "RTDr.",
+ "rtm.",
+ "rtn.",
+ "soch.",
+ "stržm.",
+ "sv.",
+ "svob.",
+ "Å¡prap.",
+ "Å¡t.",
+ "ThDr.",
+ "ThLic.",
+ "ThMgr.",
+ "voj.",
+}
diff --git a/macros/luatex/generic/luavlna/luavlna-presi.lua b/macros/luatex/generic/luavlna/luavlna-presi.lua
new file mode 100644
index 0000000000..99ff5285b6
--- /dev/null
+++ b/macros/luatex/generic/luavlna/luavlna-presi.lua
@@ -0,0 +1,30 @@
+return {
+ "Y",
+ "Yi",
+ "Z",
+ "Zi",
+ "E",
+ "Ei",
+ "P",
+ "Pi",
+ "T",
+ "Ti",
+ "G",
+ "Gi",
+ "M",
+ "Mi",
+ "k",
+ "Ki",
+ "h",
+ "da",
+ "d",
+ "c",
+ "m",
+ "µ",
+ "n",
+ "p",
+ "f",
+ "a",
+ "z",
+ "y",
+}
diff --git a/macros/luatex/generic/luavlna/luavlna-si.lua b/macros/luatex/generic/luavlna/luavlna-si.lua
new file mode 100644
index 0000000000..166eb7a1d2
--- /dev/null
+++ b/macros/luatex/generic/luavlna/luavlna-si.lua
@@ -0,0 +1,38 @@
+return {
+ "A",
+ "b",
+ "B",
+ "Bq",
+ "C",
+ "°C",
+ "cd",
+ "dag",
+ "eV",
+ "F",
+ "°F",
+ "g",
+ "Gy",
+ "H",
+ "Hz",
+ "J",
+ "K",
+ "kat",
+ "kg",
+ "lm",
+ "lx",
+ "m",
+ "mg",
+ "mol",
+ "N",
+ "Pa",
+ "rad",
+ "s",
+ "S",
+ "sr",
+ "Sv",
+ "T",
+ "V",
+ "W",
+ "Wb",
+ "Ω",
+}
diff --git a/macros/luatex/generic/luavlna/luavlna-sufdegrees.lua b/macros/luatex/generic/luavlna/luavlna-sufdegrees.lua
new file mode 100644
index 0000000000..0c326cc180
--- /dev/null
+++ b/macros/luatex/generic/luavlna/luavlna-sufdegrees.lua
@@ -0,0 +1,21 @@
+return {
+ "BBA",
+ "BLaw",
+ "BPA",
+ "BSc.",
+ "B.Th.",
+ "CSc.",
+ "DiS.",
+ "DSc.",
+ "LL.B.",
+ "LL.M.",
+ "MBA",
+ "MLaw",
+ "MMed.",
+ "MPA",
+ "MSc.",
+ "M.Th.",
+ "PhD.",
+ "Ph.D.",
+ "Th.D.",
+}
diff --git a/macros/luatex/generic/luavlna/luavlna.4ht b/macros/luatex/generic/luavlna/luavlna.4ht
new file mode 100644
index 0000000000..960e9e4de8
--- /dev/null
+++ b/macros/luatex/generic/luavlna/luavlna.4ht
@@ -0,0 +1,5 @@
+\directlua{
+luavlna.set_tex4ht()
+}
+
+\endinput
diff --git a/macros/luatex/generic/luavlna/luavlna.lua b/macros/luatex/generic/luavlna/luavlna.lua
new file mode 100644
index 0000000000..84d4c3f82c
--- /dev/null
+++ b/macros/luatex/generic/luavlna/luavlna.lua
@@ -0,0 +1,314 @@
+-- Module luavlna
+-- code originally created by Patrick Gundlach
+-- http://tex.stackexchange.com/q/27780/2891
+-- The code was adapted for plain TeX and added some more features
+-- 1. It is possible to turn this functionality only for some letters
+-- 2. Code now works even for single letters after brackets etc.
+--
+local M = {}
+local utf_match = unicode.utf8.match
+local utf_char = unicode.utf8.char
+local utf_len = unicode.utf8.len
+
+local glue_id = node.id "glue"
+local glyph_id = node.id "glyph"
+local hlist_id = node.id "hlist"
+local vlist_id = node.id "vlist"
+local math_id = node.id "math"
+local period_char = string.byte(".")
+
+local alpha = string.char(37).."a" -- alpha class, entering
+-- percent char directly caused error
+local alphas = {}
+local match_char = function(x) return utf_match(x,alpha) end
+local match_table = function(x, chars)
+ local chars=chars or {}
+ return chars[x]
+end
+local singlechars = {} -- {a=true,i=true,z=true, v=true, u=true, o = true}
+
+local initials = {}
+
+local main_language = nil
+
+-- when main_language is set, we will not use lang info in the nodes, but
+-- main language instead
+local get_language = function(lang)
+ return main_language or lang
+end
+
+local set_main_language = function(lang)
+ main_language = lang
+end
+
+local debug = false
+local tex4ht = false
+-- Enable processing only for certain letters
+-- must be table in the {char = true, char2=true} form
+local set_singlechars= function(lang,c)
+ --print("Set single chars lua")
+ if type(lang) == "table" then
+ for _,l in pairs(lang) do
+ singlechars[l] = c
+ end
+ else
+ local lang = tonumber(lang)
+ -- for k,_ in pairs(c) do print(k) end
+ singlechars[lang] = c
+ end
+end
+
+local set_initials = function(lang,c)
+ if type(lang) == "table" then
+ for _,l in pairs(lang) do
+ initials[l] = c
+ end
+ else
+ local lang = tonumber(lang)
+ initials[lang]=c
+ end
+end
+
+
+local debug_tex4ht = function(head,p)
+ --[[ local w = node.new("glyph")
+ w.lang = tex.lang
+ w.font = font.current()
+ w.char = 64
+ ]]
+ --node.remove(head,node.prev(p))
+ local w = node.new("whatsit", "special")
+ w.data = "t4ht=<span style='background-color:red;width:2pt;'> </span>"
+ return w, head
+end
+
+local debug_node = function(head,p)
+ local w
+ if tex4ht then
+ w, head = debug_tex4ht(head,p)
+ else
+ w = node.new("whatsit","pdf_literal")
+ w.data = "q 1 0 1 RG 1 0 1 rg 0 0 m 0 5 l 2 5 l 2 0 l b Q"
+ end
+ node.insert_after(head,head,w)
+ node.insert_after(head,w,p)
+ -- return w
+end
+
+
+local set_debug= function(x)
+ debug = x
+end
+
+local set_tex4ht = function()
+ tex4ht = true
+end
+
+local insert_penalty = function(head)
+ local p = node.new("penalty")
+ p.penalty = 10000
+ local debug = debug or false
+ if debug then
+ local w = debug_node(head,p)
+ else
+ node.insert_after(head,head,p)
+ end
+ return head
+end
+
+local replace_with_thin_space = function(head)
+ local gluenode = node.new(node.id("glue"))
+ local gluespec = node.new(node.id("glue_spec"))
+ gluenode.width = tex.sp("0.2em")
+ -- gluenode.spec = gluespec
+ gluenode.next = head.next
+ gluenode.prev = head.prev
+ gluenode.next.prev = gluenode
+ gluenode.prev.next = gluenode
+ return gluenode
+end
+
+local is_alpha = function(c)
+ local status = alphas[c]
+ if not status then
+ status = utf_match(c, alpha)
+ alphas[c] = status
+ end
+ return status
+end
+
+-- find whether letter is uppercase
+local up_table = {}
+local is_uppercase= function(c)
+ if not is_alpha(c) then return false end
+ local status = up_table[c]
+ if status ~= nil then
+ return status
+ end
+ status = unicode.utf8.upper(c) == c
+ up_table[c] = status
+ return status
+end
+
+local is_number = function(word)
+ return tonumber(string.sub(word, -1)) ~= nil
+end
+
+local init_buffer = ""
+local is_initial = function(c, lang)
+ return is_uppercase(c)
+end
+
+local cut_off_end_chars = function(word, dot)
+ local last = string.sub(word, -1)
+ while word ~= "" and (not dot or last ~= ".") and not is_alpha(last) do
+ word = string.sub(word, 1, -2) -- remove last char
+ last = string.sub(word, -1)
+ end
+ return word
+end
+
+local part_until_non_alpha = function(word)
+ for i = 1, #word do
+ local c = word:sub(i,i)
+ if not is_alpha(c) then
+ word = string.sub(word, 1, i-1)
+ break
+ end
+ end
+ return word
+end
+
+
+function Set (list)
+ local set = {}
+ for _, l in ipairs(list) do set[l] = true end
+ return set
+end
+
+
+local presi = (require "luavlna-presi")
+local si = Set(require "luavlna-si")
+
+local is_unit = function(word)
+ if M.no_unit==true then return false end
+ word = part_until_non_alpha(word)
+ if si[word] then
+ return true
+ end
+ for _, prefix in pairs(presi) do
+ s, e = string.find(word, prefix)
+ if s == 1 then
+ local unit = string.sub(word, e+1)
+ if si[unit] then
+ return true
+ end
+ end
+ end
+ return false
+end
+
+local predegrees = Set (require "luavlna-predegrees")
+local sufdegrees = Set (require "luavlna-sufdegrees")
+
+local function prevent_single_letter (head)
+ local singlechars = singlechars -- or {}
+ -- match_char matches all single letters, but this method is abbandoned
+ -- in favor of using table with enabled letters. With this method, multiple
+ -- languages are supported
+ local test_fn = match_table -- singlechars and match_table or match_char
+ local space = true
+ local init = false
+ local anchor = head
+ local wasnumber = false
+ local word = ""
+ local no_predegrees = M.no_predegrees
+ local no_sufdegrees = M.no_sufdegrees
+ local in_math = false
+ while head do
+ local id = head.id
+ local nextn = head.next
+ -- local skip = node.has_attribute(head, luatexbase.attributes.preventsinglestatus)
+ local skip = node.has_attribute(head, M.preventsingleid)
+ if id == math_id then
+ if head.subtype == 0 then
+ word = ""
+ in_math = true
+ else
+ in_math = false
+ if is_number(word) then wasnumber = true end
+ word = ""
+ end
+ end
+ if skip ~= 1 and not in_math then
+ if id == glue_id then
+ if wasnumber then
+ if word ~= "" then
+ wasnumber = false
+ word = cut_off_end_chars(word, false)
+ if is_unit(word) then
+ anchor = replace_with_thin_space(anchor)
+ insert_penalty(anchor.prev)
+ end
+ end
+ elseif is_number(word) then
+ wasnumber = true
+ else
+ word = cut_off_end_chars(word, true)
+ if no_predegrees ~= true and predegrees[word] then
+ insert_penalty(head.prev)
+ elseif no_sufdegrees ~= true and sufdegrees[word] then
+ insert_penalty(anchor.prev)
+ end
+ end
+ space=true
+ anchor = head
+ word = ""
+ init = is_initial " " -- reset initials
+ elseif space==true and id == glyph_id and is_alpha(utf_char(head.char)) then -- a letter
+ local lang = get_language(head.lang)
+ local char = utf_char(head.char)
+ word = char
+ init = is_initial(char,lang)
+ local s = singlechars[lang] or {} -- load singlechars for node's lang
+ --[[
+ for k, n in pairs(singlechars) do
+ for c,_ in pairs(n) do
+ --print(type(k), c)
+ end
+ end
+ --]]
+ if test_fn(char, s) and nextn ~= nil and nextn.id == glue_id then -- only if we are at a one letter word
+ head = insert_penalty(head)
+ end
+ space = false
+ -- handle initials
+ -- uppercase letter followed by period (code 46)
+ elseif init and head.id == glyph_id and head.char == period_char and nextn.id == glue_id and utf_len(word) == 1 then
+ head = insert_penalty(head)
+ elseif head.id == glyph_id then
+ local char = utf_char(head.char)
+ word = word .. char
+ init = is_initial(char, head.lang)
+ -- hlist support
+ elseif head.id == hlist_id then
+ prevent_single_letter(head.head)
+ -- vlist support
+ elseif head.id == vlist_id then
+ prevent_single_letter(head.head)
+ end
+ elseif id == glyph_id and in_math then
+ word = word .. utf_char(head.char)
+ end
+ head = head.next
+ end
+ return true
+end
+
+M.preventsingle = prevent_single_letter
+M.singlechars = set_singlechars
+M.initials = set_initials
+M.set_tex4ht = set_tex4ht
+M.debug = set_debug
+M.set_main_language = set_main_language
+return M
diff --git a/macros/luatex/generic/luavlna/luavlna.sty b/macros/luatex/generic/luavlna/luavlna.sty
new file mode 100644
index 0000000000..059c260ea1
--- /dev/null
+++ b/macros/luatex/generic/luavlna/luavlna.sty
@@ -0,0 +1,24 @@
+\ProvidesPackage{luavlna}[2017/09/30 luavlna]
+
+\def\nosingledefaults{\relax}
+\input luavlna
+
+\def\singlechars#1#2{%
+ \ifcsname l@#1\endcsname%
+ \expandafter\directlua\expandafter{set_singlechars("\the\csname l@#1\endcsname","#2")}%
+ \fi%
+}
+
+% Define compound initials
+\def\compoundinitials#1#2{%
+ \ifcsname l@#1\endcsname%
+ \expandafter\directlua\expandafter{set_compounds("\the\csname l@#1\endcsname","#2")}%
+ \fi%
+}
+
+\AtBeginDocument{%
+ \singlechars{czech}{AIiVvOoUuSsZzKk}
+ \singlechars{slovak}{AIiVvOoUuSsZzKk}
+ \compoundinitials{czech}{Ch,CH}
+}
+\endinput
diff --git a/macros/luatex/generic/luavlna/luavlna.tex b/macros/luatex/generic/luavlna/luavlna.tex
new file mode 100644
index 0000000000..f3c44f1b69
--- /dev/null
+++ b/macros/luatex/generic/luavlna/luavlna.tex
@@ -0,0 +1,103 @@
+% Modify pre_linebreak_filter callback so the spaces can be inserted
+\directlua{%
+luavlna = require "luavlna"
+langno = require "luavlna-langno"
+
+require "ltluatex"
+luatexbase.add_to_callback("pre_linebreak_filter", luavlna.preventsingle,"LuaVlna")
+% -- define the attribute number
+luavlna.preventsingleid = math.random(2^16)
+
+local languages = langno.load_languages()
+local get_lang_id = function(lang)
+ local langid = lang
+ if not tonumber(lang) then
+ langid = languages:get_number(lang)
+ end
+ return langid
+end
+
+% Process string and make table of enabled single letters
+% By default, spaces for all single letters are inserted
+% This can be modified with \singlechars macro
+set_singlechars = function(lang,chars)
+ local utf_gmatch = unicode.utf8.gmatch
+ % local langnumbers = languages.names
+ local langid = get_lang_id(lang)
+ if not langid then return nil, "Cannot find language number for: "..lang end
+ local chars = chars or ""
+ local singlechars = {}
+ local percent = string.char(37)
+ local alpha = percent .. "a"
+ for char in utf_gmatch(chars,"("..alpha..")") do
+ singlechars[char] = true
+ end
+ luavlna.singlechars(langid,singlechars)
+end
+
+% set compound characters for initials handling
+% useful for Czech "Ch" etc.
+% comma separated list of compounds
+set_compounds = function(lang, compounds)
+ local langid = get_lang_id(lang)
+ if not langid then return nil, "Cannot find language number for: "..lang end
+ local c = compounds:explode(",+") % match multiple colons as one
+ local compoundstable = {}
+ for _, compound in pairs(c) do
+ compoundstable[compound] = true
+ end
+ luavlna.initials(langid, compoundstable)
+end
+
+set_main_language = function(lang)
+ local langid = languages:get_number(lang)
+ if not langid then return nil, "Cannot find language number for: "..lang end
+ luavlna.set_main_language(langid)
+end
+}
+
+% Set letters which are prevented from breaking
+\def\singlechars#1#2{%
+\directlua{set_singlechars("#1","#2")}
+}
+
+% Define compound initials
+\def\compoundinitials#1#2{%
+\directlua{set_compounds("#1","#2")}
+}
+% Enable inserting of visual marks for debugging
+\def\preventsingledebugon{%
+\directlua{luavlna.debug(true)}
+}
+
+\def\preventsinglelang#1{%
+ \directlua{set_main_language("#1")}
+}
+
+%\newluatexattribute\preventsinglestatus
+\attributedef\preventsinglestatus=\directlua{tex.print(luavlna.preventsingleid)} % just a random number
+
+\def\preventsingleon{%
+ \preventsinglestatus=2
+}
+
+\def\preventsingleoff{
+ \preventsinglestatus=1
+}
+% Disable inserting of visual marks for dewbugging
+\def\preventsingledebugoff{%
+\directlua{luavlna.debug(false)}
+}
+
+% disable processing of units or degrees
+
+\def\nopredegrees{\directlua{luavlna.no_predegrees = true}}
+\def\nosufdegrees{\directlua{luavlna.no_sufdegrees = true}}
+\def\nounits{\directlua{luavlna.no_unit = true}}
+
+\ifdefined\nosingledefaults\else
+ \singlechars{czech}{AIiVvOoUuSsZzKk}
+ \singlechars{slovak}{AIiVvOoUuSsZzKk}
+ \compoundinitials{czech}{Ch,CH}
+\fi
+
diff --git a/macros/luatex/generic/luaxml/README b/macros/luatex/generic/luaxml/README
new file mode 100644
index 0000000000..317a60671f
--- /dev/null
+++ b/macros/luatex/generic/luaxml/README
@@ -0,0 +1,37 @@
+Introduction
+============
+
+LuaXML is pure lua library for reading and serializing of the XML files. Current release is aimed mainly as support
+for the odsfile package. The documentation was created by automatic conversion of original documentation in the source code.
+In this version, some files not useful for luaTeX were droped.
+
+
+Install
+=======
+
+LuaXML is installed in TeX distributions, so you don't need to install it yourself. If you want to try the development version,
+then clone this repository and run
+
+ make install
+
+Please note that you will need [LDoc](http://stevedonovan.github.io/ldoc/manual/doc.md.html#Processing_Single_Modules) and
+[dkjson](http://dkolf.de/src/dkjson-lua.fsl/home) Lua modules installed on your system.
+
+License:
+========
+
+This code is freely distributable under the terms of the Lua license
+ (http://www.lua.org/copyright.html)
+
+
+Author
+------
+Michal Hoftich
+Email: michal.h21@gmail.com
+Version: v0.1h, 2018-12-18
+
+Original authors: Paul Chakravarti and Manoel Campos (http://manoelcampos.com)
+
+If you are interested in the process of development you may observe
+
+ https://github.com/michal-h21/LuaXML
diff --git a/macros/luatex/generic/luaxml/luaxml-cssquery.lua b/macros/luatex/generic/luaxml/luaxml-cssquery.lua
new file mode 100644
index 0000000000..d353a310c4
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml-cssquery.lua
@@ -0,0 +1,276 @@
+--- CSS query module for LuaXML
+-- @module luaxml-cssquery
+-- @author Michal Hoftich <michal.h21@gmail.com
+local parse_query = require("luaxml-parse-query")
+
+-- the string.explode function is provided by LuaTeX
+-- this is alternative for stock Lua
+-- source: http://lua-users.org/wiki/SplitJoin
+local function string_split(str, sep)
+ local sep, fields = sep or ":", {}
+ local pattern = string.format("([^%s]+)", sep)
+ str:gsub(pattern, function(c) fields[#fields+1] = c end)
+ return fields
+end
+
+string.explode = string.explode or string_split
+
+--- CssQuery constructor
+-- @function cssquery
+-- @return CssQuery object
+local function cssquery()
+ --- @type CssQuery
+ local CssQuery = {}
+ CssQuery.__index = CssQuery
+ CssQuery.__debug = false
+ CssQuery.querylist = {}
+
+ function CssQuery.debug(self)
+ self.__debug = true
+ end
+
+ function CssQuery:debug_print(text)
+ if self.__debug then
+ print("[CSS Object]: " .. text)
+ end
+ end
+ --- Calculate CSS specificity of the query
+ -- @param query table created by CssQuery:prepare_selector() function
+ -- @return integer speficity value
+ function CssQuery:calculate_specificity(query)
+ local query = query or {}
+ local specificity = 0
+ for _, item in ipairs(query.query or {}) do
+ for key, value in pairs(item) do
+ if key == "id" then
+ specificity = specificity + 100
+ elseif key == "tag" then
+ specificity = specificity + 1
+ else
+ specificity = specificity + 10
+ end
+ end
+ end
+ return specificity
+ end
+
+ -- save element position in the current siblings list
+ local function make_nth(curr_el)
+ local pos = 0
+ local el_pos = 0
+ -- get current node list
+ local siblings = curr_el:get_siblings()
+ if siblings then
+ for _, other_el in ipairs(siblings) do
+ -- number the elements
+ if other_el:is_element() then
+ pos = pos + 1
+ other_el.nth = pos
+ -- save the current element position
+ if other_el == curr_el then
+ el_pos = pos
+ end
+ end
+ end
+ else
+ return false
+ end
+ return el_pos
+ end
+
+ local function test_first_child(el, nth)
+ local el_pos = el.nth or make_nth(el)
+ return el_pos == 1
+ end
+
+ -- test element for nth-child selector
+ local function test_nth_child(el, nth)
+ local el_pos = el.nth or make_nth(el)
+ -- we support only the nth-child(number) form
+ return el_pos == tonumber(nth)
+ end
+
+ --- Test prepared querylist
+ -- @param domobj DOM element to test
+ -- @param querylist [optional] List of queries to test
+ -- @return table with CSS queries, which match the selected DOM element
+ function CssQuery:match_querylist(domobj, querylist)
+ local matches = {}
+ -- querylist can be explicit, saved queries can be used otherwise
+ local querylist = querylist or self.querylist
+
+ local function test_part(key, value, el)
+ -- print("testing", key, value, el:get_element_name())
+ if key == "tag" then
+ return el:get_element_name() == value
+ elseif key == "id" then
+ local id = el:get_attribute "id"
+ return id and id == value
+ elseif key == "class" then
+ local class = el:get_attribute "class"
+ if not class then return false end
+ local c = {}
+ for part in class:gmatch "([^%s]+)" do
+ c[part] = true
+ end
+ return c[value] == true
+ elseif key == "nth-child" then
+ return test_nth_child(el, value)
+ elseif key == "first-child" then
+ return test_first_child(el, value)
+ end
+ -- TODO: Add more cases
+ -- just return true for not supported selectors
+ return true
+ end
+
+ local function test_object(query, el)
+ -- test one object in CSS selector
+ local matched = {}
+ for key, value in pairs(query) do
+ matched[#matched+1] = test_part(key, value, el)
+ end
+ if #matched == 0 then return false end
+ for k, v in ipairs(matched) do
+ if v ~= true then return false end
+ end
+ return true
+ end
+
+ local function match_query(query, el)
+ local query = query or {}
+ local object = table.remove(query) -- get current object from the query stack
+ if not object then return true end -- if the query stack is empty, then we can be sure that it matched previous items
+ if not el:is_element() then return false end -- if there is object to test, but current node isn't element, test failed
+ local result = test_object(object, el)
+ if result then
+ return match_query(query, el:get_parent())
+ end
+ return false
+ end
+ for _,element in ipairs(querylist) do
+ local query = {}
+ for k,v in ipairs(element.query) do query[k] = v end
+ if #query > 0 then -- don't try to match empty query
+ local result = match_query(query, domobj)
+ if result then matches[#matches+1] = element end
+ end
+ end
+ return matches
+ end
+
+ --- Get elements that match the selector
+ -- @return table with DOM_Object elements
+ function CssQuery:get_selector_path(
+ domobj, -- DOM_Object
+ selectorlist -- querylist table created using CssQuery:prepare_selector
+ )
+ local nodelist = {}
+ domobj:traverse_elements(function(el)
+ local matches = self:match_querylist(el, selectorlist)
+ self:debug_print("Matching " .. el:get_element_name() .." "..#matches)
+ if #matches > 0 then nodelist[#nodelist+1] = el
+ end
+ end)
+ return nodelist
+ end
+
+ --- Parse CSS selector to a query table.
+ -- XML namespaces can be supported using
+ -- namespace|element syntax
+ -- @return table querylist
+ function CssQuery:prepare_selector(
+ selector -- string CSS selector query
+ )
+ local querylist = {}
+ local function parse_selector(item)
+ local query = {}
+ -- for i = #item, 1, -1 do
+ -- local part = item[i]
+ for _, part in ipairs(item) do
+ local t = {}
+ for _, atom in ipairs(part) do
+ local key = atom[1]
+ local value = atom[2]
+ -- support for XML namespaces in selectors
+ -- the namespace should be added using "|"
+ -- like namespace|element
+ if key=="tag" then
+ -- LuaXML doesn't support namespaces, so it is necessary
+ -- to match namespace:element
+ value=value:gsub("|", ":")
+ end
+ t[key] = value
+ end
+ query[#query + 1] = t
+ end
+ return query
+ end
+ -- for item in selector:gmatch("([^%s]+)") do
+ -- elements[#elements+1] = parse_selector(item)
+ -- end
+ local parts = parse_query.parse_query(selector) or {}
+ -- several selectors may be separated using ",", we must process them separately
+ local sources = selector:explode(",")
+ for i, part in ipairs(parts) do
+ querylist[#querylist+1] = {query = parse_selector(part), source = sources[i]}
+ end
+ return querylist
+ end
+
+ --- Add selector to CSS object list of selectors,
+ -- func is called when the selector matches a DOM object
+ -- params is table which will be passed to the func
+ -- @return integer number of elements in the prepared selector
+ function CssQuery:add_selector(
+ selector, -- CSS selector string
+ func, -- function which will be executed on matched elements
+ params -- table with parameters for the function
+ )
+ local selector_list = self:prepare_selector(selector)
+ for k, query in ipairs(selector_list) do
+ query.specificity = self:calculate_specificity(query)
+ query.func = func
+ query.params = params
+ table.insert(self.querylist, query)
+ end
+ self:sort_querylist()
+ return #selector_list
+ end
+
+ --- Sort selectors according to their specificity
+ -- It is called automatically when the selector is added
+ -- @return querylist table
+ function CssQuery:sort_querylist(
+ querylist -- [optional] querylist table
+ )
+ local querylist = querylist or self.querylist
+ table.sort(self.querylist, function(a,b)
+ return a.specificity > b.specificity
+ end)
+ return querylist
+ end
+
+ --- It tests list of queries agaings a DOM element and executes the
+ --- coresponding function that is saved for the matched query.
+ -- @return nothing
+ function CssQuery:apply_querylist(
+ domobj, -- DOM element
+ querylist -- querylist table
+ )
+ for _, query in ipairs(querylist) do
+ -- use default empty function which will pass to another match
+ local func = query.func or function() return true end
+ local params = query.params or {}
+ local status = func(domobj, params)
+ -- break the execution when the function return false
+ if status == false then
+ break
+ end
+ end
+ end
+
+ return setmetatable({}, CssQuery)
+end
+
+return cssquery
diff --git a/macros/luatex/generic/luaxml/luaxml-domobject.lua b/macros/luatex/generic/luaxml/luaxml-domobject.lua
new file mode 100644
index 0000000000..a410885e04
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml-domobject.lua
@@ -0,0 +1,529 @@
+--- DOM module for LuaXML
+-- @module luaxml-domobject
+-- @author Michal Hoftich <michal.h21@gmail.com
+local dom = {}
+local xml = require("luaxml-mod-xml")
+local handler = require("luaxml-mod-handler")
+local css_query = require("luaxml-cssquery")
+
+
+local void = {area = true, base = true, br = true, col = true, hr = true, img = true, input = true, link = true, meta = true, param = true}
+
+local escapes = {
+ [">"] = "&gt;",
+ ["<"] = "&lt;",
+ ["&"] = "&amp;",
+ ['"'] = "&quot;",
+ ["'"] = "&#39;",
+ ["`"] = "&#x60;"
+}
+
+local function escape(search, text)
+ return text:gsub(search, function(ch)
+ return escapes[ch] or ""
+ end)
+end
+
+local function escape_element(text)
+ return escape("([<>&])", text)
+end
+
+local function escape_attr(text)
+ return escape("([<>&\"'`])", text)
+end
+
+local actions = {
+ TEXT = {text = "%s"},
+ COMMENT = {start = "<!-- ", text = "%s", stop = " -->"},
+ ELEMENT = {start = "<%s%s>", stop = "</%s>", void = "<%s%s />"},
+ DECL = {start = "<?%s %s?>"},
+ PI = {start = "<?%s %s?>"},
+ DTD = {start = "<!DOCTYPE ", text = "%s" , stop=">"},
+ CDATA = {start = "<![CDATA[", text = "%s", stop ="]]>"}
+
+}
+
+--- It serializes the DOM object back to the XML.
+-- This function is mainly used for internal purposes, it is better to
+-- use the `DOM_Object:serialize()`.
+-- @param parser DOM object
+-- @param current Element which should be serialized
+-- @param level
+-- @param output
+-- @return table Table with XML strings. It can be concenated using table.concat() function to get XML string corresponding to the DOM_Object.
+local function serialize_dom(parser, current,level, output)
+ local output = output or {}
+ local function get_action(typ, action)
+ local ac = actions[typ] or {}
+ local format = ac[action] or ""
+ return format
+ end
+ local function insert(format, ...)
+ table.insert(output, string.format(format, ...))
+ end
+ local function prepare_attributes(attr)
+ local t = {}
+ local attr = attr or {}
+ for k, v in pairs(attr) do
+ t[#t+1] = string.format("%s='%s'", k, escape_attr(v))
+ end
+ if #t == 0 then return "" end
+ -- add space before attributes
+ return " " .. table.concat(t, " ")
+ end
+ local function start(typ, el, attr)
+ local format = get_action(typ, "start")
+ insert(format, el, prepare_attributes(attr))
+ end
+ local function text(typ, text)
+ local format = get_action(typ, "text")
+ insert(format, escape_element(text))
+ end
+ local function stop(typ, el)
+ local format = get_action(typ, "stop")
+ insert(format,el)
+ end
+ local level = level or 0
+ local spaces = string.rep(" ",level)
+ local root= current or parser._handler.root
+ local name = root._name or "unnamed"
+ local xtype = root._type or "untyped"
+ local text_content = root._text or ""
+ local attributes = root._attr or {}
+ -- if xtype == "TEXT" then
+ -- print(spaces .."TEXT : " .. root._text)
+ -- elseif xtype == "COMMENT" then
+ -- print(spaces .. "Comment : ".. root._text)
+ -- else
+ -- print(spaces .. xtype .. " : " .. name)
+ -- end
+ -- for k, v in pairs(attributes) do
+ -- print(spaces .. " ".. k.."="..v)
+ -- end
+ if xtype == "DTD" then
+ text_content = string.format('%s %s "%s" "%s"', name, attributes["_type"] or "", attributes._name, attributes._uri )
+ -- remove unused fields
+ text_content = text_content:gsub('"nil"','')
+ text_content = text_content:gsub('%s*$','')
+ attributes = {}
+ elseif xtype == "ELEMENT" and void[name] and #current._children < 1 then
+ local format = get_action(xtype, "void")
+ insert(format, name, prepare_attributes(attributes))
+ return output
+ elseif xtype == "PI" then
+ -- it contains spurious _text attribute
+ attributes["_text"] = nil
+ elseif xtype == "DECL" and name =="xml" then
+ -- the xml declaration attributes must be in a correct order
+ insert("<?xml version='%s' encoding='%s' ?>", attributes.version, attributes.encoding)
+ return output
+ end
+
+ start(xtype, name, attributes)
+ text(xtype,text_content)
+ local children = root._children or {}
+ for _, child in ipairs(children) do
+ output = serialize_dom(parser,child, level + 1, output)
+ end
+ stop(xtype, name)
+ return output
+end
+
+--- XML parsing function
+-- Parse the XML text and create the DOM object.
+-- @return DOM_Object
+local parse = function(
+ xmltext --- String to be parsed
+ )
+ local domHandler = handler.domHandler()
+ --- @type DOM_Object
+ local DOM_Object = xml.xmlParser(domHandler)
+ -- preserve whitespace
+ DOM_Object.options.stripWS = nil
+ DOM_Object:parse(xmltext)
+ DOM_Object.current = DOM_Object._handler.root
+ DOM_Object.__index = DOM_Object
+ DOM_Object.css_query = css_query()
+
+ local function save_methods(element)
+ setmetatable(element,DOM_Object)
+ local children = element._children or {}
+ for _, x in ipairs(children) do
+ save_methods(x)
+ end
+ end
+ local parser = setmetatable({}, DOM_Object)
+
+ --- Returns root element of the DOM_Object
+ -- @return DOM_Object
+ function DOM_Object:root_node()
+ return self._handler.root
+ end
+
+
+ --- Get current node type
+ -- @param el [optional] node to get the type of
+ function DOM_Object:get_node_type(
+ el --- [optional] element to test
+ )
+ local el = el or self
+ return el._type
+ end
+
+ --- Test if the current node is an element.
+ -- You can pass different element as parameter
+ -- @return boolean
+ function DOM_Object:is_element(
+ el --- [optional] element to test
+ )
+ local el = el or self
+ return self:get_node_type(el) == "ELEMENT" -- @bool
+ end
+
+
+ --- Test if current node is text
+ -- @return boolean
+ function DOM_Object:is_text(
+ el --- [optional] element to test
+ )
+ local el = el or self
+ return self:get_node_type(el) == "TEXT"
+ end
+
+ local lower = string.lower
+
+ --- Return name of the current element
+ -- @return string
+ function DOM_Object:get_element_name(
+ el --- [optional] element to test
+ )
+ local el = el or self
+ return el._name or "unnamed"
+ end
+
+ --- Get value of an attribute
+ -- @return string
+ function DOM_Object:get_attribute(
+ name --- Attribute name
+ )
+ local el = self
+ if self:is_element(el) then
+ local attr = el._attr or {}
+ return attr[name]
+ end
+ end
+
+ --- Set value of an attribute
+ -- @return boolean
+ function DOM_Object:set_attribute(
+ name --- Attribute name
+ , value --- Value to be set
+ )
+ local el = self
+ if self:is_element(el) then
+ el._attr[name] = value
+ return true
+ end
+ end
+
+
+ --- Serialize the current node back to XML
+ -- @return string
+ function DOM_Object:serialize(
+ current --- [optional] element to be serialized
+ )
+ local current = current
+ -- if no current element is added and self is not plain parser object
+ -- (_type is then nil), use the current object as serialized root
+ if not current and self._type then
+ current = self
+ end
+ return table.concat(serialize_dom(self, current))
+ end
+
+ --- Get text content from the node and all of it's children
+ -- @return string
+ function DOM_Object:get_text(
+ current --- [optional] element which should be converted to text
+ )
+ local current = current or self
+ local text = {}
+ if current:is_text() then return current._text or "" end
+ for _, el in ipairs(current:get_children()) do
+ if el:is_text() then
+ text[#text+1] = el._text or ""
+ elseif el:is_element() then
+ text[#text+1] = el:get_text()
+ end
+ end
+ return table.concat(text)
+ end
+
+
+
+ --- Retrieve elements from the given path.
+ -- The path is list of elements separated by space,
+ -- starting from the top element of the current element
+ -- @return table of elements which match the path
+ function DOM_Object:get_path(
+ path --- path to be traversed
+ , current --- [optional] element which should be traversed. Default element is the root element of the DOM_Object
+ )
+ local function traverse_path(path_elements, current, t)
+ local t = t or {}
+ if #path_elements == 0 then
+ -- for _, x in ipairs(current._children or {}) do
+ -- table.insert(t,x)
+ -- end
+ table.insert(t,current)
+ return t
+ end
+ local current_path = table.remove(path_elements, 1)
+ for _, x in ipairs(self:get_children(current)) do
+ if self:is_element(x) then
+ local name = string.lower(self:get_element_name(x))
+ if name == current_path then
+ t = traverse_path(path_elements, x, t)
+ end
+ end
+ end
+ return t
+ end
+ local current = current or self:root_node() -- self._handler.root
+ local path_elements = {}
+ local path = string.lower(path)
+ for el in path:gmatch("([^%s]+)") do table.insert(path_elements, el) end
+ return traverse_path(path_elements, current)
+ end
+
+ --- Select elements chidlren using CSS selector syntax
+ -- @return table with elements matching the selector.
+ function DOM_Object:query_selector(
+ selector --- String using the CSS selector syntax
+ )
+ local css_query = self.css_query
+ local css_parts = css_query:prepare_selector(selector)
+ return css_query:get_selector_path(self, css_parts)
+ end
+
+ --- Get table with children of the current element
+ -- @return table with children of the selected element
+ function DOM_Object:get_children(
+ el --- [optional] element to be selected
+ )
+ local el = el or self
+ local children = el._children or {}
+ return children
+ end
+
+ --- Get the parent element
+ -- @return DOM_Object parent element
+ function DOM_Object:get_parent(
+ el --- [optional] element to be selected
+ )
+ local el = el or self
+ return el._parent
+ end
+
+ --- Execute function on the current element and all it's children elements.
+ -- The traversing of child elements of a given node can be disabled when the executed
+ -- function returns false.
+ -- @return nothing
+ function DOM_Object:traverse_elements(
+ fn, --- function which will be executed on the current element and all it's children
+ current --- [optional] element to be selected
+ )
+ local current = current or self --
+ -- Following situation may happen when this method is called directly on the parsed object
+ if not current:get_node_type() then
+ current = self:root_node()
+ end
+ local status = true
+ if self:is_element(current) or self:get_node_type(current) == "ROOT"then
+ local status = fn(current)
+ -- don't traverse child nodes when the user function return false
+ if status ~= false then
+ for _, child in ipairs(self:get_children(current)) do
+ self:traverse_elements(fn, child)
+ end
+ end
+ end
+ end
+
+ --- Execute function on list of elements returned by DOM_Object:get_path()
+ function DOM_Object:traverse_node_list(
+ nodelist --- table with nodes selected by DOM_Object:get_path()
+ , fn --- function to be executed
+ )
+ local nodelist = nodelist or {}
+ for _, node in ipairs(nodelist) do
+ for _, element in ipairs(node._children) do
+ fn(element)
+ end
+ end
+ end
+
+ --- Replace the current node with new one
+ -- @return boolean, message
+ function DOM_Object:replace_node(
+ new --- element which should replace the current element
+ )
+ local old = self
+ local parent = self:get_parent(old)
+ local id,msg = self:find_element_pos( old)
+ if id then
+ parent._children[id] = new
+ return true
+ end
+ return false, msg
+ end
+
+ --- Add child node to the current node
+ function DOM_Object:add_child_node(
+ child, --- element to be inserted as a current node child
+ position --- [optional] position at which should the node be inserted
+ )
+ local parent = self
+ child._parent = parent
+ if position then
+ table.insert(parent._children, position, child)
+ else
+ table.insert(parent._children, child)
+ end
+ end
+
+
+ --- Create copy of the current node
+ -- @return DOM_Object element
+ function DOM_Object:copy_node(
+ element --- [optional] element to be copied
+ )
+ local element = element or self
+ local t = {}
+ for k, v in pairs(element) do
+ if type(v) == "table" and k~="_parent" then
+ t[k] = self:copy_node(v)
+ else
+ t[k] = v
+ end
+ end
+ save_methods(t)
+ return t
+ end
+
+
+ --- Create a new element
+ -- @return DOM_Object element
+ function DOM_Object:create_element(
+ name, -- New tag name
+ attributes, -- Table with attributes
+ parent -- [optional] element which should be saved as the element's parent
+ )
+ local parent = parent or self
+ local new = {}
+ new._type = "ELEMENT"
+ new._name = name
+ new._attr = attributes or {}
+ new._children = {}
+ new._parent = parent
+ save_methods(new)
+ return new
+ end
+
+ --- Create new text node
+ -- @return DOM_Object text object
+ function DOM_Object:create_text_node(
+ text, -- string
+ parent -- [optional] element which should be saved as the element's parent
+ )
+ local parent = parent or self
+ local new = {}
+ new._type = "TEXT"
+ new._parent = parent
+ new._text = text
+ save_methods(new)
+ return new
+ end
+
+ --- Delete current node
+ function DOM_Object:remove_node(
+ element -- [optional] element to be removed
+ )
+ local element = element or self
+ local parent = self:get_parent(element)
+ local pos = self:find_element_pos(element)
+ -- if pos then table.remove(parent._children, pos) end
+ if pos then
+ -- table.remove(parent._children, pos)
+ parent._children[pos] = setmetatable({_type = "removed"}, DOM_Object)
+ end
+ end
+
+ --- Find the element position in the current node list
+ -- @return integer position of the current element in the element table
+ function DOM_Object:find_element_pos(
+ el -- [optional] element which should be looked up
+ )
+ local el = el or self
+ local parent = self:get_parent(el)
+ if not self:is_element(parent) and self:get_node_type(parent) ~= "ROOT" then return nil, "The parent isn't element" end
+ for i, x in ipairs(parent._children) do
+ if x == el then return i end
+ end
+ return false, "Cannot find element"
+ end
+
+ --- Get node list which current node is part of
+ -- @return table with elements
+ function DOM_Object:get_siblings(
+ el -- [optional] element for which the sibling element list should be retrieved
+ )
+ local el = el or self
+ local parent = el:get_parent()
+ if parent:is_element() then
+ return parent:get_children()
+ end
+ end
+
+ --- Get sibling node of the current node
+ -- @param change Distance from the current node
+ -- @return DOM_Object node
+ function DOM_Object:get_sibling_node( change)
+ local el = self
+ local pos = el:find_element_pos()
+ local siblings = el:get_siblings()
+ if pos and siblings then
+ return siblings[pos + change]
+ end
+ end
+
+ --- Get next node
+ -- @return DOM_Object node
+ function DOM_Object:get_next_node(
+ el --- [optional] node to be used
+ )
+ local el = el or self
+ return el:get_sibling_node(1)
+ end
+
+ --- Get previous node
+ -- @return DOM_Object node
+ function DOM_Object:get_prev_node(
+ el -- [optional] node to be used
+ )
+ local el = el or self
+ return el:get_sibling_node(-1)
+ end
+
+
+ -- include the methods to all xml nodes
+ save_methods(parser._handler.root)
+ -- parser:
+ return parser
+end
+
+--- @export
+return {
+ parse = parse,
+ serialize_dom= serialize_dom
+}
diff --git a/macros/luatex/generic/luaxml/luaxml-entities.lua b/macros/luatex/generic/luaxml/luaxml-entities.lua
new file mode 100644
index 0000000000..dd7e6f7156
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml-entities.lua
@@ -0,0 +1,37 @@
+local M = {}
+local char = unicode and unicode.utf8.char or utf8.char
+local named_entities = require "luaxml-namedentities"
+local hexchartable = {}
+local decchartable = {}
+
+
+local function get_named_entity(name)
+ return named_entities[name]
+end
+
+function M.decode(s)
+ return s:gsub("&([#a-zA-Z0-9]+);?", function(m)
+ -- check if this is named entity first
+ local named = get_named_entity(m)
+ if named then return named end
+ -- check if it is numeric entity
+ local hex, charcode = m:match("#([xX]?)([a-fA-F0-9]+)")
+ -- if the entity is not numeric
+ if not charcode then return
+ "&" .. m .. ";"
+ end
+ local character
+ if hex~="" then
+ character = hexchartable[charcode] or char(tonumber(charcode,16))
+ hexchartable[charcode] = character
+ else
+ character = decchartable[charcode] or char(tonumber(charcode))
+ decchartable[charcode] = character
+ end
+ return character
+ end)
+end
+
+return M
+
+
diff --git a/macros/luatex/generic/luaxml/luaxml-mod-handler.lua b/macros/luatex/generic/luaxml/luaxml-mod-handler.lua
new file mode 100644
index 0000000000..5f12a92f71
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml-mod-handler.lua
@@ -0,0 +1,359 @@
+--..module(...,package.seeall)
+--
+-- Overview:
+-- =========
+-- Standard XML event handler(s) for XML parser module (xml.lua)
+--
+-- Features:
+-- =========
+-- printHandler - Generate XML event trace
+-- domHandler - Generate DOM-like node tree
+-- simpleTreeHandler - Generate 'simple' node tree
+-- simpleTeXhandler - SAX like handler with support for CSS selectros
+--
+-- API:
+-- ====
+-- Must be called as handler function from xmlParser
+-- and implement XML event callbacks (see xmlParser.lua
+-- for callback API definition)
+--
+-- printHandler:
+-- -------------
+--
+-- printHandler prints event trace for debugging
+--
+-- domHandler:
+-- -----------
+--
+-- domHandler generates a DOM-like node tree structure with
+-- a single ROOT node parent - each node is a table comprising
+-- fields below.
+--
+-- node = { _name = <Element Name>,
+-- _type = ROOT|ELEMENT|TEXT|COMMENT|PI|DECL|DTD,
+-- _attr = { Node attributes - see callback API },
+-- _parent = <Parent Node>
+-- _children = { List of child nodes - ROOT/NODE only }
+-- }
+--
+-- The dom structure is capable of representing any valid XML document
+--
+-- simpleTreeHandler
+-- -----------------
+--
+-- simpleTreeHandler is a simplified handler which attempts
+-- to generate a more 'natural' table based structure which
+-- supports many common XML formats.
+--
+-- The XML tree structure is mapped directly into a recursive
+-- table structure with node names as keys and child elements
+-- as either a table of values or directly as a string value
+-- for text. Where there is only a single child element this
+-- is inserted as a named key - if there are multiple
+-- elements these are inserted as a vector (in some cases it
+-- may be preferable to always insert elements as a vector
+-- which can be specified on a per element basis in the
+-- options). Attributes are inserted as a child element with
+-- a key of '_attr'.
+--
+-- Only Tag/Text & CDATA elements are processed - all others
+-- are ignored.
+--
+-- This format has some limitations - primarily
+--
+-- * Mixed-Content behaves unpredictably - the relationship
+-- between text elements and embedded tags is lost and
+-- multiple levels of mixed content does not work
+-- * If a leaf element has both a text element and attributes
+-- then the text must be accessed through a vector (to
+-- provide a container for the attribute)
+--
+-- In general however this format is relatively useful.
+--
+-- It is much easier to understand by running some test
+-- data through 'textxml.lua -simpletree' than to read this)
+--
+-- Options
+-- =======
+-- simpleTreeHandler.options.noReduce = { <tag> = bool,.. }
+--
+-- - Nodes not to reduce children vector even if only
+-- one child
+--
+-- domHandler.options.(comment|pi|dtd|decl)Node = bool
+--
+-- - Include/exclude given node types
+--
+-- Usage
+-- =====
+-- Pased as delegate in xmlParser constructor and called
+-- as callback by xmlParser:parse(xml) method.
+--
+-- See textxml.lua for examples
+-- License:
+-- ========
+--
+-- This code is freely distributable under the terms of the Lua license
+-- (<a href="http://www.lua.org/copyright.html">http://www.lua.org/copyright.html</a>)
+--
+-- History
+-- =======
+-- $Id: handler.lua,v 1.1.1.1 2001/11/28 06:11:33 paulc Exp $
+--
+-- $Log: handler.lua,v $
+-- Revision 1.1.1.1 2001/11/28 06:11:33 paulc
+-- Initial Import
+--@author Paul Chakravarti (paulc@passtheaardvark.com)<p/>
+
+
+---Handler to generate a string prepresentation of a table
+--Convenience function for printHandler (Does not support recursive tables).
+--@param t Table to be parsed
+--@returns Returns a string representation of table
+
+local M = {}
+local stack = require("luaxml-stack")
+local entities = require("luaxml-entities")
+
+local function showTable(t)
+ local sep = ''
+ local res = ''
+ if type(t) ~= 'table' then
+ return t
+ end
+ for k,v in pairs(t) do
+ if type(v) == 'table' then
+ v = showTable(v)
+ end
+ res = res .. sep .. string.format("%s=%s",k,v)
+ sep = ','
+ end
+ res = '{'..res..'}'
+ return res
+end
+
+
+M.showTable = showTable
+
+---Handler to generate a simple event trace
+local printHandler = function()
+ local obj = {}
+ obj.starttag = function(self,t,a,s,e)
+ io.write("Start : "..t.."\n")
+ if a then
+ for k,v in pairs(a) do
+ io.write(string.format(" + %s='%s'\n",k,v))
+ end
+ end
+ end
+ obj.endtag = function(self,t,s,e)
+ io.write("End : "..t.."\n")
+ end
+ obj.text = function(self,t,s,e)
+ io.write("Text : "..t.."\n")
+ end
+ obj.cdata = function(self,t,s,e)
+ io.write("CDATA : "..t.."\n")
+ end
+ obj.comment = function(self,t,s,e)
+ io.write("Comment : "..t.."\n")
+ end
+ obj.dtd = function(self,t,a,s,e)
+ io.write("DTD : "..t.."\n")
+ if a then
+ for k,v in pairs(a) do
+ io.write(string.format(" + %s='%s'\n",k,v))
+ end
+ end
+ end
+ obj.pi = function(self,t,a,s,e)
+ io.write("PI : "..t.."\n")
+ if a then
+ for k,v in pairs(a) do
+ io. write(string.format(" + %s='%s'\n",k,v))
+ end
+ end
+ end
+ obj.decl = function(self,t,a,s,e)
+ io.write("XML Decl : "..t.."\n")
+ if a then
+ for k,v in pairs(a) do
+ io.write(string.format(" + %s='%s'\n",k,v))
+ end
+ end
+ end
+ return obj
+end
+M.printHandler = printHandler
+---Handler to generate a lua table from a XML content string
+local function simpleTreeHandler()
+ local obj = {}
+
+ obj.root = {}
+ obj.stack = {obj.root;n=1}
+ obj.options = {noreduce = {}}
+
+ obj.reduce = function(self,node,key,parent)
+ -- Recursively remove redundant vectors for nodes
+ -- with single child elements
+ for k,v in pairs(node) do
+ if type(v) == 'table' then
+ self:reduce(v,k,node)
+ end
+ end
+ if #node == 1 and not self.options.noreduce[key] and
+ node._attr == nil then
+ parent[key] = node[1]
+ else
+ node.n = nil
+ end
+ end
+
+ obj.starttag = function(self,t,a)
+ local node = {}
+ if self.parseAttributes == true then
+ node._attr=a
+ end
+
+ local current = self.stack[#self.stack]
+ if current[t] then
+ table.insert(current[t],node)
+ else
+ current[t] = {node;n=1}
+ end
+ table.insert(self.stack,node)
+ end
+
+ obj.endtag = function(self,t,s)
+ local current = self.stack[#self.stack]
+ local prev = self.stack[#self.stack-1]
+ if not prev[t] then
+ error("XML Error - Unmatched Tag ["..s..":"..t.."]\n")
+ end
+ if prev == self.root then
+ -- Once parsing complete recursively reduce tree
+ self:reduce(prev,nil,nil)
+ end
+ table.remove(self.stack)
+ end
+
+ obj.text = function(self,t)
+ local current = self.stack[#self.stack]
+ table.insert(current,t)
+ end
+
+ obj.cdata = obj.text
+
+ return obj
+end
+
+M.simpleTreeHandler = simpleTreeHandler
+
+--- domHandler
+local function domHandler()
+ local obj = {}
+ local decode = entities.decode
+ obj.options = {commentNode=1,piNode=1,dtdNode=1,declNode=1}
+ obj.root = { _children = {n=0}, _type = "ROOT" }
+ obj.current = obj.root
+ obj.starttag = function(self,t,a)
+ local newattr
+ if a then
+ newattr = {}
+ for k,v in pairs(a) do
+ newattr[k] = decode(v)
+ end
+ end
+ local node = { _type = 'ELEMENT',
+ _name = t,
+ _attr = newattr,
+ _parent = self.current,
+ _children = {n=0} }
+ table.insert(self.current._children,node)
+ self.current = node
+ end
+ obj.endtag = function(self,t,s)
+ if t ~= self.current._name then
+ error("XML Error - Unmatched Tag ["..s..":"..t.."]\n")
+ end
+ self.current = self.current._parent
+ end
+ obj.text = function(self,t)
+ local node = { _type = "TEXT",
+ _parent = self.current,
+ _text = decode(t) }
+ table.insert(self.current._children,node)
+ end
+ obj.comment = function(self,t)
+ if self.options.commentNode then
+ local node = { _type = "COMMENT",
+ _parent = self.current,
+ _text = t }
+ table.insert(self.current._children,node)
+ end
+ end
+ obj.pi = function(self,t,a)
+ if self.options.piNode then
+ local node = { _type = "PI",
+ _name = t,
+ _attr = a,
+ _parent = self.current }
+ table.insert(self.current._children,node)
+ end
+ end
+ obj.decl = function(self,t,a)
+ if self.options.declNode then
+ local node = { _type = "DECL",
+ _name = t,
+ _attr = a,
+ _parent = self.current }
+ table.insert(self.current._children,node)
+ end
+ end
+ obj.dtd = function(self,t,a)
+ if self.options.dtdNode then
+ local node = { _type = "DTD",
+ _name = t,
+ _attr = a,
+ _parent = self.current }
+ table.insert(self.current._children,node)
+ end
+ end
+ obj.cdata = function(self,t)
+ local node = { _type = "CDATA",
+ _parent = self.current,
+ _text = decode(t) }
+ table.insert(self.current._children,node)
+ end
+ return obj
+end
+M.domHandler = domHandler
+
+--
+local simpleTeXhandler=function()
+ local obj={}
+ local _stack=stack.Stack:Create()
+ obj.starttag = function(self,t,a,s,e)
+ local tag = {t}
+ local getAtt = function(att)
+ if a[att] then
+ return att.."="..a[att]
+ end
+ return nil
+ end
+ if type(a) == "table" then
+ table.insert(tag,getAtt("id"))
+ table.insert(tag,getAtt("class"))
+ end
+ _stack:push("<"..table.concat(tag," ")..">")
+ io.write(_stack:join("").."\n")
+-- io.write("Start "..t.."\n" )
+ end
+ obj.endtag = function(self,t,s,e)
+ _stack:pop()
+ -- io.write("End : "..t.."\n")
+ end
+ return obj
+end
+M.simpleTeXhandler = simpleTeXhandler
+return M
diff --git a/macros/luatex/generic/luaxml/luaxml-mod-xml.lua b/macros/luatex/generic/luaxml/luaxml-mod-xml.lua
new file mode 100644
index 0000000000..2d99590105
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml-mod-xml.lua
@@ -0,0 +1,565 @@
+-- module(...,package.seeall)
+---
+-- Overview:
+-- =========
+--
+-- This module provides a non-validating XML stream parser in Lua.
+--
+-- Features:
+-- =========
+--
+-- * Tokenises well-formed XML (relatively robustly)
+-- * Flexible handler based event api (see below)
+-- * Parses all XML Infoset elements - ie.
+-- - Tags
+-- - Text
+-- - Comments
+-- - CDATA
+-- - XML Decl
+-- - Processing Instructions
+-- - DOCTYPE declarations
+-- * Provides limited well-formedness checking
+-- (checks for basic syntax & balanced tags only)
+-- * Flexible whitespace handling (selectable)
+-- * Entity Handling (selectable)
+--
+-- Limitations:
+-- ============
+--
+-- * Non-validating
+-- * No charset handling
+-- * No namespace support
+-- * Shallow well-formedness checking only (fails
+-- to detect most semantic errors)
+--
+-- API:
+-- ====
+--
+-- The parser provides a partially object-oriented API with
+-- functionality split into tokeniser and hanlder components.
+--
+-- The handler instance is passed to the tokeniser and receives
+-- callbacks for each XML element processed (if a suitable handler
+-- function is defined). The API is conceptually similar to the
+-- SAX API but implemented differently.
+--
+-- The following events are generated by the tokeniser
+--
+-- handler:start - Start Tag
+-- handler:end - End Tag
+-- handler:text - Text
+-- handler:decl - XML Declaration
+-- handler:pi - Processing Instruction
+-- handler:comment - Comment
+-- handler:dtd - DOCTYPE definition
+-- handler:cdata - CDATA
+--
+-- The function prototype for all the callback functions is
+--
+-- callback(val,attrs,start,end)
+--
+-- where attrs is a table and val/attrs are overloaded for
+-- specific callbacks - ie.
+--
+-- Callback val attrs (table)
+-- -------- --- -------------
+-- start name { attributes (name=val).. }
+-- end name nil
+-- text <text> nil
+-- cdata <text> nil
+-- decl "xml" { attributes (name=val).. }
+-- pi pi name { attributes (if present)..
+-- _text = <PI Text>
+-- }
+-- comment <text> nil
+-- dtd root element { _root = <Root Element>,
+-- _type = SYSTEM|PUBLIC,
+-- _name = <name>,
+-- _uri = <uri>,
+-- _internal = <internal dtd>
+-- }
+--
+-- (start & end provide the character positions of the start/end
+-- of the element)
+--
+-- XML data is passed to the parser instance through the 'parse'
+-- method (Nore: must be passed a single string currently)
+--
+-- Options
+-- =======
+--
+-- Parser options are controlled through the 'self.options' table.
+-- Available options are -
+--
+-- * stripWS
+--
+-- Strip non-significant whitespace (leading/trailing)
+-- and do not generate events for empty text elements
+--
+-- * expandEntities
+--
+-- Expand entities (standard entities + single char
+-- numeric entities only currently - could be extended
+-- at runtime if suitable DTD parser added elements
+-- to table (see obj._ENTITIES). May also be possible
+-- to expand multibyre entities for UTF-8 only
+--
+-- * errorHandler
+--
+-- Custom error handler function
+--
+-- NOTE: Boolean options must be set to 'nil' not '0'
+--
+-- Usage
+-- =====
+--
+-- Create a handler instance -
+--
+-- h = { start = function(t,a,s,e) .... end,
+-- end = function(t,a,s,e) .... end,
+-- text = function(t,a,s,e) .... end,
+-- cdata = text }
+--
+-- (or use predefined handler - see handler.lua)
+--
+-- Create parser instance -
+--
+-- p = xmlParser(h)
+--
+-- Set options -
+--
+-- p.options.xxxx = nil
+--
+-- Parse XML data -
+--
+-- xmlParser:parse("<?xml... ")
+-- License:
+-- ========
+--
+-- This code is freely distributable under the terms of the Lua license
+-- (http://www.lua.org/copyright.html)
+--
+-- History
+-- =======
+-- Fixed some errors in DTD matching
+-- Added functions serialize and xmlEscape
+-- by Michal Hoftich
+-- 2012/07/26
+--
+-- Added parameter parseAttributes (boolean) in xmlParser.parse method
+-- If true, tag attributtes are parsed. The default value is true.
+-- by Manoel Campos (http://manoelcampos.com)
+--
+-- $Id: xml.lua,v 1.1.1.1 2001/11/28 06:11:33 paulc Exp $
+--
+-- $Log: xml.lua,v $
+-- Revision 1.1.1.1 2001/11/28 06:11:33 paulc
+-- Initial Import
+--
+--@author Paul Chakravarti (paulc@passtheaardvark.com)<p/>
+
+local format= string.format
+---Parses a XML string
+--@param handler Handler object to be used to convert the XML string
+--to another formats. @see handler.lua
+local M={}
+local xmlParser = function(handler)
+ local obj = {}
+ -- Public attributes
+
+ obj.options = {
+ stripWS = 1,
+ expandEntities = 1,
+ errorHandler = function(err,pos)
+ error(format("%s [char=%d]\n",
+ err or "Parse Error",pos))
+ end,
+ }
+
+ -- Public methods
+
+ obj.parse = function(self, str, parseAttributes)
+ if parseAttributes == nil then
+ parseAttributes = true
+ end
+ self._handler.parseAttributes = parseAttributes
+
+ local match,endmatch,pos = 0,0,1
+ local text,endt1,endt2,tagstr,tagname,attrs,starttext,endtext
+ local errstart,errend,extstart,extend
+ while match do
+ -- Get next tag (first pass - fix exceptions below)
+ match,endmatch,text,endt1,tagstr,endt2 = string.find(str,self._XML,pos)
+ if not match then
+ if string.find(str,self._WS,pos) then
+ -- No more text - check document complete
+ if #self._stack ~= 0 then
+ self:_err(self._errstr.incompleteXmlErr,pos)
+ else
+ break
+ end
+ else
+ -- Unparsable text
+ self:_err(self._errstr.xmlErr,pos)
+ end
+ end
+ -- Handle leading text
+ starttext = match
+ endtext = match + string.len(text) - 1
+ match = match + string.len(text)
+ text = self:_parseEntities(self:_stripWS(text))
+ if text ~= "" and self._handler.text then
+ self._handler:text(text,nil,match,endtext)
+ end
+ -- Test for tag type
+ if string.find(string.sub(tagstr,1,5),"?xml%s") then
+ -- XML Declaration
+ match,endmatch,text = string.find(str,self._PI,pos)
+ if not match then
+ self:_err(self._errstr.declErr,pos)
+ end
+ if match ~= 1 then
+ -- Must be at start of doc if present
+ self:_err(self._errstr.declStartErr,pos)
+ end
+ tagname,attrs = self:_parseTag(text)
+ -- TODO: Check attributes are valid
+ -- Check for version (mandatory)
+ if attrs.version == nil then
+ self:_err(self._errstr.declAttrErr,pos)
+ end
+ if self._handler.decl then
+ self._handler:decl(tagname,attrs,match,endmatch)
+ end
+ elseif string.sub(tagstr,1,1) == "?" then
+ -- Processing Instruction
+ match,endmatch,text = string.find(str,self._PI,pos)
+ if not match then
+ self:_err(self._errstr.piErr,pos)
+ end
+ if self._handler.pi then
+ -- Parse PI attributes & text
+ tagname,attrs = self:_parseTag(text)
+ local pi = string.sub(text,string.len(tagname)+1)
+ if pi ~= "" then
+ if attrs then
+ attrs._text = pi
+ else
+ attrs = { _text = pi }
+ end
+ end
+ self._handler:pi(tagname,attrs,match,endmatch)
+ end
+ elseif string.sub(tagstr,1,3) == "!--" then
+ -- Comment
+ match,endmatch,text = string.find(str,self._COMMENT,pos)
+ if not match then
+ self:_err(self._errstr.commentErr,pos)
+ end
+ if self._handler.comment then
+ text = self:_parseEntities(self:_stripWS(text))
+ self._handler:comment(text,next,match,endmatch)
+ end
+ elseif string.sub(tagstr,1,8) == "!DOCTYPE" then
+ -- DTD
+ --match,endmatch,attrs = self:_parseDTD(string,pos)
+ match,endmatch,attrs = self:_parseDTD(str,pos)
+ if not match then
+ self:_err(self._errstr.dtdErr,pos)
+ end
+ if self._handler.dtd then
+ self._handler:dtd(attrs._root,attrs,match,endmatch)
+ end
+ elseif string.sub(tagstr,1,8) == "![CDATA[" then
+ -- CDATA
+ match,endmatch,text = string.find(str,self._CDATA,pos)
+ if not match then
+ self:_err(self._errstr.cdataErr,pos)
+ end
+ if self._handler.cdata then
+ self._handler:cdata(text,nil,match,endmatch)
+ end
+ else
+ -- Normal tag
+
+ -- Need theck for embedded '>' in attribute value and extend
+ -- match recursively if necessary eg. <tag attr="123>456">
+
+ while 1 do
+ errstart,errend = string.find(tagstr,self._ATTRERR1)
+ if errend == nil then
+ errstart,errend = string.find(tagstr,self._ATTRERR2)
+ if errend == nil then
+ break
+ end
+ end
+ local errorstring = tagstr:sub(errstart, errend)
+ -- it seems that it causes error if an attribute starts with `=`
+ if errorstring:match("^=") then break end
+
+ extstart,extend,endt2 = string.find(str,self._TAGEXT,endmatch+1)
+ if not extstart then break end
+
+ tagstr = tagstr .. string.sub(str,endmatch,extend-1)
+ if not match then
+ self:_err(self._errstr.xmlErr,pos)
+ end
+ endmatch = extend
+ end
+
+ -- Extract tagname/attrs
+
+ tagname,attrs = self:_parseTag(tagstr)
+
+ if (endt1=="/") then
+ -- End tag
+ if self._handler.endtag then
+ if attrs then
+ -- Shouldnt have any attributes in endtag
+ self:_err(format("%s (/%s)",
+ self._errstr.endTagErr,
+ tagname)
+ ,pos)
+ end
+ if table.remove(self._stack) ~= tagname then
+ self:_err(format("%s (/%s)",
+ self._errstr.unmatchedTagErr,
+ tagname)
+ ,pos)
+ end
+ self._handler:endtag(tagname,nil,match,endmatch)
+ end
+ else
+ -- Start Tag
+ table.insert(self._stack,tagname)
+ if self._handler.starttag then
+ self._handler:starttag(tagname,attrs,match,endmatch)
+ end
+ -- Self-Closing Tag
+ if (endt2=="/") then
+ table.remove(self._stack)
+ if self._handler.endtag then
+ self._handler:endtag(tagname,nil,match,endmatch)
+ end
+ end
+ end
+ end
+ pos = endmatch + 1
+ end
+ end
+
+ -- Private attrobures/functions
+
+ obj._handler = handler
+ obj._stack = {}
+
+ obj._XML = '^([^<]*)<(%/?)([^>]-)(%/?)>'
+ obj._ATTR1 = '([%w-:_]+)%s*=%s*"(.-)"'
+ obj._ATTR2 = '([%w-:_]+)%s*=%s*\'(.-)\''
+ obj._CDATA = '<%!%[CDATA%[(.-)%]%]>'
+ obj._PI = '<%?(.-)%?>'
+ obj._COMMENT = '<!%-%-(.-)%-%->'
+ obj._TAG = '^(.-)%s.*'
+ obj._LEADINGWS = '^%s+'
+ obj._TRAILINGWS = '%s+$'
+ obj._WS = '^%s*$'
+ local allowed_element_name_pattern = "[%w_%.%-]+"
+ obj._DTD1 = '<!DOCTYPE%s+(' .. allowed_element_name_pattern .. ')%s+(SYSTEM)%s+["\'](.-)["\']%s*(%b[])%s*>'
+ obj._DTD2 = '<!DOCTYPE%s+(' .. allowed_element_name_pattern .. ')%s+(PUBLIC)%s+["\'](.-)["\']%s+["\'](.-)["\']%s*(%b[])%s*>'
+ obj._DTD3 = '<!DOCTYPE%s+(' .. allowed_element_name_pattern .. ')%s*(%b[])%s*>'
+ obj._DTD4 = '<!DOCTYPE%s+(' .. allowed_element_name_pattern .. ')%s+(SYSTEM)%s+["\'](.-)["\']%s*>'
+ obj._DTD5 = '<!DOCTYPE%s+(' .. allowed_element_name_pattern .. ')%s+(PUBLIC)%s+["\'](.-)["\']%s+["\'](.-)["\']%s*>'
+ obj._DTD6 = '<!DOCTYPE%s+(' .. allowed_element_name_pattern .. ')%s*>'
+ --obj._DTD6 = "<!DOCTYPE%s+(.-)%s+(PUBLIC)%s+[\"'](.-)[\"']%s+[\"'](.-)[\"']%s*>"
+
+ obj._ATTRERR1 = '=%s*"[^"]*$'
+ obj._ATTRERR2 = '=%s*\'[^\']*$'
+ obj._TAGEXT = '(%/?)>'
+
+ obj._ENTITIES = { ["&lt;"] = "<",
+ ["&gt;"] = ">",
+ ["&amp;"] = "&",
+ ["&quot;"] = '"',
+ ["&apos;"] = "'",
+ ["&#(%d+);"] = function (x)
+ local d = tonumber(x)
+ if d >= 0 and d < 256 then
+ return string.char(d)
+ else
+ return "&#"..d..";"
+ end
+ end,
+ ["&#x(%x+);"] = function (x)
+ local d = tonumber(x,16)
+ if d >= 0 and d < 256 then
+ return string.char(d)
+ else
+ return "&#x"..x..";"
+ end
+ end,
+ }
+
+ obj._err = function(self,err,pos)
+ if self.options.errorHandler then
+ self.options.errorHandler(err,pos)
+ end
+ end
+
+ obj._errstr = { xmlErr = "Error Parsing XML",
+ declErr = "Error Parsing XMLDecl",
+ declStartErr = "XMLDecl not at start of document",
+ declAttrErr = "Invalid XMLDecl attributes",
+ piErr = "Error Parsing Processing Instruction",
+ commentErr = "Error Parsing Comment",
+ cdataErr = "Error Parsing CDATA",
+ dtdErr = "Error Parsing DTD",
+ endTagErr = "End Tag Attributes Invalid",
+ unmatchedTagErr = "Unbalanced Tag",
+ incompleteXmlErr = "Incomplete XML Document",
+ }
+
+ obj._stripWS = function(self,s)
+ if self.options.stripWS then
+ s = string.gsub(s,'^%s+','')
+ s = string.gsub(s,'%s+$','')
+ end
+ return s
+ end
+
+ obj._parseEntities = function(self,s)
+ if self.options.expandEntities then
+ --for k,v in self._ENTITIES do
+ for k,v in pairs(self._ENTITIES) do
+ --print (k, v)
+ s = string.gsub(s,k,v)
+ end
+ end
+ return s
+ end
+
+ obj._parseDTD = function(self,s,pos)
+ -- match,endmatch,root,type,name,uri,internal
+ --print(s.." : "..pos)
+ local m,e,r,t,n,u,i
+ m,e,r,t,n,u = string.find(s,self._DTD5,pos)
+ if m then
+ return m,e,{_root=r,_type=t,_name=n,_uri=u}
+ end
+ m,e,r,t,u,i = string.find(s,self._DTD1,pos)
+ if m then
+ return m,e,{_root=r,_type=t,_uri=u,_internal=i}
+ end
+ m,e,r,t,n,u,i = string.find(s,self._DTD2,pos)
+ if m then
+ return m,e,{_root=r,_type=t,_name=n,_uri=u,_internal=i}
+ end
+ m,e,r,i = string.find(s,self._DTD3,pos)
+ if m then
+ return m,e,{_root=r,_internal=i}
+ end
+ m,e,r,t,u = string.find(s,self._DTD4,pos)
+ if m then
+ return m,e,{_root=r,_type=t,_uri=u}
+ end
+ m,e,r = string.find(s, self._DTD6, pos)
+ if m then
+ return m,e, {_root=r }
+ end
+ return nil
+ end
+
+ obj._parseTag = function(self,s)
+ local attrs = {}
+ local tagname = string.gsub(s,self._TAG,'%1')
+ string.gsub(s,self._ATTR1,function (k,v)
+ attrs[string.lower(k)]=self:_parseEntities(v)
+ attrs._ = 1
+ end)
+ string.gsub(s,self._ATTR2,function (k,v)
+ attrs[string.lower(k)]=self:_parseEntities(v)
+ attrs._ = 1
+ end)
+ if attrs._ then
+ attrs._ = nil
+ else
+ attrs = nil
+ end
+ return tagname,attrs
+ end
+
+ return obj
+
+end
+M.xmlParser = xmlParser
+
+local function xmlEscape(s)
+ local t = {['"']="&quot;",["'"]="&apos;",["&"]="&amp;",["<"]="&lt;",[">"]="&gt;"}
+ return string.gsub(s,"([\"'<>&])",t)
+end
+
+M.xmlEscape = xmlEscape
+
+
+local function serialize(tb)
+local function getAttributes(k,v)
+ local i = ""
+ if(type(v["_attr"])=="table") then
+ -- texio.write_nl("attr")
+ for p,n in pairs(v["_attr"]) do
+ i = i ..' '.. p .. '="'..xmlEscape(n)..'"'
+ end
+ --table.remove(v,"_attr")
+ end
+ return i
+ end
+
+ local function printable(tb, level,currTag)
+ local r ={}
+ local currTag = currTag or ""
+ level = level or 0
+ local spaces = string.rep(' ', level*2)
+ for k,v in pairs(tb) do
+ if type(v) ~= "table" then
+ local ct = k
+ if type(k)=="number" then
+ ct = currTag
+ end
+ if ct == "" then
+ table.insert(r,spaces .. xmlEscape(v).."\n")
+ else
+ local i = getAttributes(k,v)
+ table.insert(r,spaces .. '<'..ct..i..'>'..xmlEscape(v)..'</'..ct..'>'.."\n")
+ end
+ else
+ if k == "_attr" then
+ --table.insert(r,printable(v, level))
+ else
+ if type(k)=="string" then
+ --currTag = k
+ if type(k)=="numeric" then
+ k = currTag
+ end
+ if #v > 1 then
+ table.insert(r,printable(v, level+1,k))
+ else
+ local i = getAttributes(k,v)
+ table.insert(r,spaces.."<"..k..i..">\n")
+ table.insert(r,printable(v, level+1,k))
+ table.insert(r,spaces.."</"..k..">\n")
+ end
+ else
+ local i = getAttributes(k,v)
+ table.insert(r,spaces .. "<"..currTag..i..">\n")
+ --level = level + 1
+ table.insert(r,printable(v, level+1))
+ table.insert(r,spaces .. "</"..currTag..">\n")
+ end
+ end
+ end
+ end
+ return table.concat(r,"")
+ end
+ return table.concat({'<?xml version="1.0" encoding="UTF-8"?>',printable(tb)},"\n")
+end
+M.serialize = serialize
+return M
diff --git a/macros/luatex/generic/luaxml/luaxml-namedentities.lua b/macros/luatex/generic/luaxml/luaxml-namedentities.lua
new file mode 100644
index 0000000000..5d68692914
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml-namedentities.lua
@@ -0,0 +1,2233 @@
+return {
+["HARDcy"]="Ъ",
+["capdot"]="â©€",
+["pound"]="£",
+["upuparrows"]="⇈",
+["RightFloor"]="⌋",
+["LeftUpTeeVector"]="⥠",
+["shcy"]="ш",
+["ac"]="∾",
+["Iacute"]="Ã",
+["boxVl"]="â•¢",
+["prap"]="⪷",
+["ocirc"]="ô",
+["Rsh"]="↱",
+["Ncy"]="Ð",
+["mdash"]="—",
+["lozf"]="⧫",
+["ETH"]="Ã",
+["rhov"]="ϱ",
+["dtri"]="â–¿",
+["shortparallel"]="∥",
+["DiacriticalDoubleAcute"]="Ë",
+["Uring"]="Å®",
+["gap"]="⪆",
+["notinvb"]="â‹·",
+["nsc"]="âŠ",
+["zeta"]="ζ",
+["Ouml"]="Ö",
+["Sub"]="â‹",
+["Zdot"]="Å»",
+["ograve"]="ò",
+["block"]="â–ˆ",
+["toea"]="⤨",
+["odash"]="âŠ",
+["DownRightVector"]="â‡",
+["siml"]="âª",
+["sharp"]="♯",
+["oline"]="‾",
+["Proportional"]="âˆ",
+["Lacute"]="Ĺ",
+["gtreqqless"]="⪌",
+["Im"]="â„‘",
+["blacktriangledown"]="â–¾",
+["ndash"]="–",
+["straightepsilon"]="ϵ",
+["bigodot"]="⨀",
+["npr"]="⊀",
+["iocy"]="Ñ‘",
+["lltri"]="â—º",
+["Uuml"]="Ü",
+["srarr"]="→",
+["nvap"]="â‰âƒ’",
+["nprec"]="⊀",
+["Rcy"]="Р",
+["DownArrowBar"]="⤓",
+["Ll"]="⋘",
+["forkv"]="â«™",
+["LongLeftArrow"]="⟵",
+["LeftUpVectorBar"]="⥘",
+["jsercy"]="ј",
+["thkap"]="≈",
+["gsime"]="⪎",
+["realine"]="â„›",
+["nsupset"]="⊃⃒",
+["inodot"]="ı",
+["CircleDot"]="⊙",
+["qint"]="⨌",
+["nLeftarrow"]="â‡",
+["prnap"]="⪹",
+["caron"]="ˇ",
+["LessFullEqual"]="≦",
+["RightVectorBar"]="⥓",
+["kappa"]="κ",
+["Ascr"]="ð’œ",
+["Emacr"]="Ä’",
+["nsup"]="⊅",
+["simlE"]="⪟",
+["gamma"]="γ",
+["CircleTimes"]="⊗",
+["Aogon"]="Ä„",
+["sstarf"]="⋆",
+["drbkarow"]="â¤",
+["ruluhar"]="⥨",
+["icirc"]="î",
+["Esim"]="⩳",
+["Longleftrightarrow"]="⟺",
+["SquareUnion"]="⊔",
+["Iacute"]="Ã",
+["oplus"]="⊕",
+["VerticalSeparator"]="â˜",
+["coprod"]="âˆ",
+["eDot"]="≑",
+["TScy"]="Ц",
+["Leftrightarrow"]="⇔",
+["Lcy"]="Л",
+["NotSucceedsSlantEqual"]="â‹¡",
+["Tstrok"]="Ŧ",
+["QUOT"]="\"",
+["curlyeqsucc"]="â‹Ÿ",
+["lozenge"]="â—Š",
+["ltcir"]="⩹",
+["Lsh"]="↰",
+["ldsh"]="↲",
+["dcaron"]="Ä",
+["scaron"]="Å¡",
+["Racute"]="Å”",
+["nvgt"]=">⃒",
+["Cscr"]="ð’ž",
+["rmoustache"]="⎱",
+["Ucy"]="У",
+["LessEqualGreater"]="â‹š",
+["lsime"]="âª",
+["Iuml"]="Ã",
+["zfr"]="ð”·",
+["LowerLeftArrow"]="↙",
+["ccaps"]="â©",
+["smeparsl"]="⧤",
+["hellip"]="…",
+["rcaron"]="Å™",
+["Dscr"]="ð’Ÿ",
+["clubs"]="♣",
+["Poincareplane"]="ℌ",
+["Vcy"]="Ð’",
+["nles"]="⩽̸",
+["blank"]="â£",
+["order"]="â„´",
+["ccups"]="⩌",
+["rbrkslu"]="â¦",
+["easter"]="â©®",
+["ltimes"]="⋉",
+["rBarr"]="â¤",
+["nlArr"]="â‡",
+["minusdu"]="⨪",
+["nhArr"]="⇎",
+["lg"]="≶",
+["LessGreater"]="≶",
+["lne"]="⪇",
+["NegativeThickSpace"]="​",
+["LessLess"]="⪡",
+["nsime"]="≄",
+["nltri"]="⋪",
+["boxvL"]="â•¡",
+["isin"]="∈",
+["UnderBrace"]="âŸ",
+["el"]="⪙",
+["ntriangleleft"]="⋪",
+["lnsim"]="⋦",
+["Sacute"]="Åš",
+["Fscr"]="ℱ",
+["gbreve"]="ÄŸ",
+["ohbar"]="⦵",
+["alefsym"]="ℵ",
+["nap"]="≉",
+["eqvparsl"]="⧥",
+["NegativeVeryThinSpace"]="​",
+["prod"]="âˆ",
+["ohm"]="Ω",
+["NotNestedGreaterGreater"]="⪢̸",
+["rtimes"]="â‹Š",
+["sigmav"]="Ï‚",
+["check"]="✓",
+["reg"]="®",
+["Gscr"]="ð’¢",
+["nLeftrightarrow"]="⇎",
+["triminus"]="⨺",
+["topfork"]="â«š",
+["Ugrave"]="Ù",
+["nleqslant"]="⩽̸",
+["Oacute"]="Ó",
+["NonBreakingSpace"]=" ",
+["eqcolon"]="≕",
+["lrcorner"]="⌟",
+["Ycy"]="Ы",
+["rarrtl"]="↣",
+["Udblac"]="Å°",
+["gl"]="≷",
+["rightarrow"]="→",
+["nprcue"]="â‹ ",
+["Hscr"]="â„‹",
+["rlhar"]="⇌",
+["trianglerighteq"]="⊵",
+["Uacute"]="Ú",
+["nexist"]="∄",
+["plusmn"]="±",
+["hardcy"]="ÑŠ",
+["Zcy"]="З",
+["lbarr"]="⤌",
+["macr"]="¯",
+["prnsim"]="⋨",
+["NotTildeEqual"]="≄",
+["Iscr"]="â„",
+["Element"]="∈",
+["Subset"]="â‹",
+["supsetneq"]="⊋",
+["raemptyv"]="⦳",
+["Scy"]="С",
+["xmap"]="⟼",
+["ugrave"]="ù",
+["notnivc"]="⋽",
+["LessTilde"]="≲",
+["RightUpVectorBar"]="⥔",
+["epar"]="â‹•",
+["otimes"]="⊗",
+["boxH"]="â•",
+["angmsdae"]="⦬",
+["topcir"]="⫱",
+["shy"]="­",
+["Lstrok"]="Å",
+["latail"]="⤙",
+["Tcy"]="Т",
+["sqcup"]="⊔",
+["sqsub"]="âŠ",
+["sqcap"]="⊓",
+["angmsd"]="∡",
+["parallel"]="∥",
+["minus"]="−",
+["circ"]="ˆ",
+["alpha"]="α",
+["chcy"]="ч",
+["SucceedsEqual"]="⪰",
+["opar"]="⦷",
+["Cayleys"]="â„­",
+["agrave"]="à",
+["imagpart"]="â„‘",
+["varsubsetneqq"]="⫋︀",
+["epsi"]="ε",
+["nVdash"]="⊮",
+["orarr"]="↻",
+["rfr"]="ð”¯",
+["xuplus"]="⨄",
+["checkmark"]="✓",
+["rpargt"]="⦔",
+["ncup"]="â©‚",
+["trisb"]="â§",
+["npar"]="∦",
+["times"]="×",
+["nrightarrow"]="↛",
+["commat"]="@",
+["bigtriangleup"]="â–³",
+["Zcaron"]="Ž",
+["fpartint"]="â¨",
+["lnapprox"]="⪉",
+["utri"]="â–µ",
+["Hat"]="^",
+["rsquo"]="’",
+["wfr"]="ð”´",
+["LeftDoubleBracket"]="⟦",
+["Sc"]="⪼",
+["midast"]="*",
+["utdot"]="â‹°",
+["lbrkslu"]="â¦",
+["Sqrt"]="√",
+["TripleDot"]="⃛",
+["oslash"]="ø",
+["rarrpl"]="⥅",
+["csupe"]="â«’",
+["gcy"]="г",
+["gtrdot"]="â‹—",
+["xfr"]="ð”µ",
+["cudarrl"]="⤸",
+["rarrb"]="⇥",
+["nRightarrow"]="â‡",
+["phi"]="φ",
+["fallingdotseq"]="≒",
+["rarrbfs"]="⤠",
+["rangle"]="⟩",
+["HorizontalLine"]="─",
+["propto"]="âˆ",
+["subsub"]="â«•",
+["flat"]="â™­",
+["ograve"]="ò",
+["bne"]="=⃥",
+["Cedilla"]="¸",
+["DownLeftTeeVector"]="⥞",
+["sup"]="⊃",
+["profalar"]="⌮",
+["sime"]="≃",
+["And"]="â©“",
+["bsim"]="∽",
+["vfr"]="ð”³",
+["edot"]="Ä—",
+["scE"]="⪴",
+["ffllig"]="ffl",
+["spadesuit"]="â™ ",
+["gt"]=">",
+["Lt"]="≪",
+["angmsdad"]="⦫",
+["rightsquigarrow"]="â†",
+["larrbfs"]="⤟",
+["NJcy"]="Њ",
+["thicksim"]="∼",
+["gnsim"]="⋧",
+["bottom"]="⊥",
+["lmoustache"]="⎰",
+["NotPrecedesEqual"]="⪯̸",
+["bumpe"]="â‰",
+["heartsuit"]="♥",
+["lt"]="<",
+["prop"]="âˆ",
+["DiacriticalAcute"]="´",
+["boxHu"]="╧",
+["RightUpDownVector"]="â¥",
+["ReverseElement"]="∋",
+["Dot"]="¨",
+["sqcups"]="⊔︀",
+["lvnE"]="≨︀",
+["subsetneq"]="⊊",
+["gdot"]="Ä¡",
+["lpar"]="(",
+["NotEqual"]="≠",
+["awint"]="⨑",
+["iiint"]="∭",
+["imath"]="ı",
+["gne"]="⪈",
+["operp"]="⦹",
+["nbumpe"]="â‰Ì¸",
+["doublebarwedge"]="⌆",
+["LJcy"]="Љ",
+["bbrk"]="⎵",
+["RightAngleBracket"]="⟩",
+["reg"]="®",
+["nvlArr"]="⤂",
+["xcup"]="⋃",
+["mapstoup"]="↥",
+["nlt"]="≮",
+["nsim"]="â‰",
+["nsubE"]="⫅̸",
+["plus"]="+",
+["bigotimes"]="⨂",
+["jmath"]="È·",
+["equals"]="=",
+["khcy"]="Ñ…",
+["Upsilon"]="Î¥",
+["rightrightarrows"]="⇉",
+["supe"]="⊇",
+["Egrave"]="È",
+["lbrksld"]="â¦",
+["sce"]="⪰",
+["HilbertSpace"]="â„‹",
+["ic"]="â£",
+["niv"]="∋",
+["ccaron"]="Ä",
+["bigwedge"]="â‹€",
+["olt"]="⧀",
+["ultri"]="â—¸",
+["ofr"]="ð”¬",
+["exponentiale"]="â…‡",
+["LeftCeiling"]="⌈",
+["UpEquilibrium"]="⥮",
+["vartriangleleft"]="⊲",
+["Supset"]="â‹‘",
+["aacute"]="á",
+["langle"]="⟨",
+["cuwed"]="â‹",
+["Ubreve"]="Ŭ",
+["fcy"]="Ñ„",
+["lsim"]="≲",
+["vltri"]="⊲",
+["jfr"]="ð”§",
+["digamma"]="Ï",
+["Eogon"]="Ę",
+["gnapprox"]="⪊",
+["Amacr"]="Ä€",
+["ecirc"]="ê",
+["scnE"]="⪶",
+["thickapprox"]="≈",
+["ltdot"]="â‹–",
+["malt"]="✠",
+["drcrop"]="⌌",
+["ifr"]="ð”¦",
+["NotGreaterTilde"]="≵",
+["upharpoonright"]="↾",
+["wedge"]="∧",
+["notin"]="∉",
+["nrarr"]="↛",
+["LeftTeeArrow"]="↤",
+["cacute"]="ć",
+["dwangle"]="⦦",
+["frasl"]="â„",
+["dzigrarr"]="⟿",
+["para"]="¶",
+["vnsup"]="⊃⃒",
+["spar"]="∥",
+["DotDot"]="⃜",
+["vnsub"]="⊂⃒",
+["suplarr"]="⥻",
+["preceq"]="⪯",
+["ffilig"]="ffi",
+["quot"]="\"",
+["nabla"]="∇",
+["weierp"]="℘",
+["searhk"]="⤥",
+["icy"]="и",
+["downdownarrows"]="⇊",
+["lang"]="⟨",
+["nleftrightarrow"]="↮",
+["hamilt"]="â„‹",
+["rpar"]=")",
+["iquest"]="¿",
+["bigstar"]="★",
+["biguplus"]="⨄",
+["dagger"]="†",
+["lrarr"]="⇆",
+["eacute"]="é",
+["gtdot"]="â‹—",
+["jcy"]="й",
+["supdsub"]="⫘",
+["Prime"]="″",
+["intercal"]="⊺",
+["Aacute"]="Ã",
+["prsim"]="≾",
+["nfr"]="ð”«",
+["ngeq"]="≱",
+["angmsdac"]="⦪",
+["DoubleLeftRightArrow"]="⇔",
+["Iogon"]="Ä®",
+["kappav"]="Ï°",
+["lsh"]="↰",
+["tfr"]="ð”±",
+["sect"]="§",
+["omega"]="ω",
+["gesles"]="⪔",
+["boxplus"]="⊞",
+["mfr"]="ð”ª",
+["GreaterFullEqual"]="≧",
+["Exists"]="∃",
+["Acirc"]="Â",
+["nesim"]="≂̸",
+["gacute"]="ǵ",
+["dotplus"]="∔",
+["rrarr"]="⇉",
+["prnE"]="⪵",
+["qfr"]="ð”®",
+["triangleq"]="≜",
+["boxvH"]="╪",
+["dcy"]="д",
+["sup1"]="¹",
+["nequiv"]="≢",
+["longleftrightarrow"]="⟷",
+["Icirc"]="ÃŽ",
+["shchcy"]="щ",
+["raquo"]="»",
+["quest"]="?",
+["Euml"]="Ë",
+["leftthreetimes"]="â‹‹",
+["part"]="∂",
+["VeryThinSpace"]=" ",
+["Upsi"]="Ï’",
+["bprime"]="‵",
+["CenterDot"]="·",
+["Agrave"]="À",
+["NotHumpEqual"]="â‰Ì¸",
+["theta"]="θ",
+["Jcirc"]="Ä´",
+["Ocirc"]="Ô",
+["rightharpoondown"]="â‡",
+["caps"]="∩︀",
+["DownLeftRightVector"]="â¥",
+["doteqdot"]="≑",
+["boxbox"]="⧉",
+["nvHarr"]="⤄",
+["timesd"]="⨰",
+["uharl"]="↿",
+["ouml"]="ö",
+["TSHcy"]="Ћ",
+["TRADE"]="â„¢",
+["iecy"]="е",
+["Zeta"]="Ζ",
+["Scirc"]="Ŝ",
+["Lleftarrow"]="⇚",
+["bigoplus"]="â¨",
+["DoubleDownArrow"]="⇓",
+["nexists"]="∄",
+["lesdoto"]="âª",
+["geq"]="≥",
+["nwnear"]="⤧",
+["Updownarrow"]="⇕",
+["andand"]="â©•",
+["nge"]="≱",
+["curvearrowleft"]="↶",
+["bkarow"]="â¤",
+["Ccaron"]="Č",
+["NegativeThinSpace"]="​",
+["nbump"]="≎̸",
+["ecir"]="≖",
+["imacr"]="Ä«",
+["Succeeds"]="≻",
+["supnE"]="⫌",
+["Auml"]="Ä",
+["rsh"]="↱",
+["approx"]="≈",
+["sdote"]="⩦",
+["SuchThat"]="∋",
+["Jsercy"]="Ј",
+["odsold"]="⦼",
+["Dcaron"]="ÄŽ",
+["dfisht"]="⥿",
+["harrcir"]="⥈",
+["hArr"]="⇔",
+["leftrightarrow"]="↔",
+["geqslant"]="⩾",
+["boxDL"]="â•—",
+["nsucceq"]="⪰̸",
+["leg"]="â‹š",
+["parsl"]="⫽",
+["dd"]="â…†",
+["bump"]="≎",
+["GT"]=">",
+["DiacriticalGrave"]="`",
+["Ecaron"]="Äš",
+["cap"]="∩",
+["sext"]="✶",
+["LongRightArrow"]="⟶",
+["LeftDownVectorBar"]="⥙",
+["gg"]="≫",
+["dlcorn"]="⌞",
+["LeftVector"]="↼",
+["Gcirc"]="Ĝ",
+["LT"]="<",
+["ldquor"]="„",
+["subset"]="⊂",
+["tstrok"]="ŧ",
+["iacute"]="í",
+["Hcirc"]="Ĥ",
+["gtrapprox"]="⪆",
+["demptyv"]="⦱",
+["HumpDownHump"]="≎",
+["image"]="â„‘",
+["Icirc"]="ÃŽ",
+["boxHD"]="╦",
+["aogon"]="Ä…",
+["smid"]="∣",
+["uuml"]="ü",
+["lneq"]="⪇",
+["star"]="☆",
+["UpperRightArrow"]="↗",
+["larrpl"]="⤹",
+["backsimeq"]="â‹",
+["Itilde"]="Ĩ",
+["supne"]="⊋",
+["LeftDownTeeVector"]="⥡",
+["yicy"]="Ñ—",
+["NotSucceeds"]="âŠ",
+["KJcy"]="Ќ",
+["GreaterEqualLess"]="â‹›",
+["nLt"]="≪⃒",
+["LeftRightArrow"]="↔",
+["Ubrcy"]="ÐŽ",
+["LeftArrowRightArrow"]="⇆",
+["dArr"]="⇓",
+["epsilon"]="ε",
+["wr"]="≀",
+["percnt"]="%",
+["lesdot"]="â©¿",
+["iiota"]="â„©",
+["boxul"]="┘",
+["iquest"]="¿",
+["tbrk"]="⎴",
+["blacktriangle"]="â–´",
+["real"]="ℜ",
+["origof"]="⊶",
+["yen"]="Â¥",
+["Intersection"]="â‹‚",
+["els"]="⪕",
+["cuesc"]="â‹Ÿ",
+["mldr"]="…",
+["RightTee"]="⊢",
+["Gbreve"]="Äž",
+["gimel"]="â„·",
+["models"]="⊧",
+["uring"]="ů",
+["gtrsim"]="≳",
+["hairsp"]=" ",
+["iota"]="ι",
+["eacute"]="é",
+["diamond"]="â‹„",
+["iuml"]="ï",
+["hybull"]="âƒ",
+["Uarrocir"]="⥉",
+["lesdotor"]="⪃",
+["lceil"]="⌈",
+["lsquo"]="‘",
+["Uogon"]="Ų",
+["beta"]="β",
+["permil"]="‰",
+["measuredangle"]="∡",
+["eg"]="⪚",
+["CHcy"]="Ч",
+["bepsi"]="϶",
+["GreaterLess"]="≷",
+["Ucirc"]="Û",
+["ange"]="⦤",
+["Otimes"]="⨷",
+["simgE"]="⪠",
+["boxdl"]="â”",
+["vDash"]="⊨",
+["supedot"]="â«„",
+["xvee"]="â‹",
+["nisd"]="⋺",
+["oacute"]="ó",
+["llhard"]="⥫",
+["Rarrtl"]="⤖",
+["equest"]="≟",
+["abreve"]="ă",
+["rceil"]="⌉",
+["nle"]="≰",
+["frown"]="⌢",
+["Ocirc"]="Ô",
+["boxminus"]="⊟",
+["nvrArr"]="⤃",
+["TildeTilde"]="≈",
+["Congruent"]="≡",
+["Alpha"]="Α",
+["glE"]="⪒",
+["compfn"]="∘",
+["cularr"]="↶",
+["llcorner"]="⌞",
+["plusacir"]="⨣",
+["RightTeeArrow"]="↦",
+["supsub"]="â«”",
+["aring"]="Ã¥",
+["boxhd"]="┬",
+["boxvh"]="┼",
+["VerticalBar"]="∣",
+["AElig"]="Æ",
+["DiacriticalDot"]="Ë™",
+["pscr"]="ð“…",
+["triangleleft"]="â—ƒ",
+["supsetneqq"]="⫌",
+["trie"]="≜",
+["NotDoubleVerticalBar"]="∦",
+["RightUpTeeVector"]="⥜",
+["NotLessGreater"]="≸",
+["gopf"]="ð•˜",
+["amalg"]="⨿",
+["nrtrie"]="â‹­",
+["harrw"]="↭",
+["FilledVerySmallSquare"]="â–ª",
+["gtrarr"]="⥸",
+["DDotrahd"]="⤑",
+["UpArrowBar"]="⤒",
+["angle"]="∠",
+["gtquest"]="⩼",
+["Equilibrium"]="⇌",
+["qscr"]="ð“†",
+["RightArrow"]="→",
+["LongLeftRightArrow"]="⟷",
+["NotCongruent"]="≢",
+["target"]="⌖",
+["iexcl"]="¡",
+["vsupne"]="⊋︀",
+["dopf"]="ð••",
+["RightTeeVector"]="⥛",
+["AElig"]="Æ",
+["lrm"]="‎",
+["boxUr"]="â•™",
+["nscr"]="ð“ƒ",
+["Phi"]="Φ",
+["erarr"]="⥱",
+["gesdot"]="⪀",
+["acE"]="∾̳",
+["iopf"]="ð•š",
+["NotSucceedsTilde"]="≿̸",
+["geqq"]="≧",
+["timesb"]="⊠",
+["nvdash"]="⊬",
+["fflig"]="ff",
+["Tilde"]="∼",
+["Ccirc"]="Ĉ",
+["boxDR"]="â•”",
+["AMP"]="&",
+["Idot"]="Ä°",
+["Gcy"]="Г",
+["pluscir"]="⨢",
+["Longrightarrow"]="⟹",
+["UnderParenthesis"]="â",
+["sqsubseteq"]="⊑",
+["profsurf"]="⌓",
+["fopf"]="ð•—",
+["and"]="∧",
+["middot"]="·",
+["ltquest"]="â©»",
+["scpolint"]="⨓",
+["Rcaron"]="Ř",
+["DoubleLeftTee"]="⫤",
+["rangd"]="⦒",
+["crarr"]="↵",
+["Bcy"]="Б",
+["lscr"]="ð“",
+["kopf"]="ð•œ",
+["rharu"]="⇀",
+["map"]="↦",
+["LT"]="<",
+["Scaron"]="Å ",
+["dscy"]="Ñ•",
+["NegativeMediumSpace"]="​",
+["amp"]="&",
+["sfrown"]="⌢",
+["EmptySmallSquare"]="â—»",
+["Acy"]="Ð",
+["cupcup"]="â©Š",
+["Gdot"]="Ä ",
+["hopf"]="ð•™",
+["smtes"]="⪬︀",
+["lap"]="⪅",
+["boxV"]="â•‘",
+["ltrie"]="⊴",
+["divide"]="÷",
+["larrb"]="⇤",
+["ijlig"]="ij",
+["Superset"]="⊃",
+["gtreqless"]="â‹›",
+["Tcaron"]="Ť",
+["jscr"]="ð’¿",
+["risingdotseq"]="≓",
+["DScy"]="Ð…",
+["rdca"]="⤷",
+["emptyset"]="∅",
+["curvearrowright"]="↷",
+["nrarrw"]="â†Ì¸",
+["angzarr"]="â¼",
+["frac35"]="â…—",
+["centerdot"]="·",
+["vsupnE"]="⫌︀",
+["Bumpeq"]="≎",
+["lnap"]="⪉",
+["gvertneqq"]="≩︀",
+["tcaron"]="Å¥",
+["Edot"]="Ä–",
+["Union"]="⋃",
+["cupdot"]="âŠ",
+["napE"]="⩰̸",
+["jopf"]="ð•›",
+["iff"]="⇔",
+["Aacute"]="Ã",
+["NotTildeFullEqual"]="≇",
+["plussim"]="⨦",
+["Yacute"]="Ã",
+["Sup"]="â‹‘",
+["multimap"]="⊸",
+["nlE"]="≦̸",
+["aelig"]="æ",
+["ntgl"]="≹",
+["Dstrok"]="Ä",
+["frac14"]="¼",
+["minusd"]="∸",
+["Wedge"]="â‹€",
+["Fcy"]="Ф",
+["xscr"]="ð“",
+["igrave"]="ì",
+["ulcorn"]="⌜",
+["CapitalDifferentialD"]="â……",
+["Star"]="⋆",
+["ExponentialE"]="â…‡",
+["NotNestedLessLess"]="⪡̸",
+["Acirc"]="Â",
+["DoubleRightArrow"]="⇒",
+["radic"]="√",
+["twoheadleftarrow"]="↞",
+["Ecy"]="Э",
+["SquareSuperset"]="âŠ",
+["leftleftarrows"]="⇇",
+["OElig"]="Å’",
+["Cacute"]="Ć",
+["bullet"]="•",
+["ngeqslant"]="⩾̸",
+["circlearrowright"]="↻",
+["CounterClockwiseContourIntegral"]="∳",
+["gnap"]="⪊",
+["Vdashl"]="⫦",
+["curlyeqprec"]="â‹ž",
+["gtlPar"]="⦕",
+["upsilon"]="Ï…",
+["aopf"]="ð•’",
+["prec"]="≺",
+["vscr"]="ð“‹",
+["fjlig"]="fj",
+["colone"]="≔",
+["copy"]="©",
+["ordf"]="ª",
+["laquo"]="«",
+["bemptyv"]="⦰",
+["NotReverseElement"]="∌",
+["eogon"]="Ä™",
+["DoubleUpArrow"]="⇑",
+["Ecirc"]="Ê",
+["Rrightarrow"]="⇛",
+["Fouriertrf"]="ℱ",
+["wscr"]="ð“Œ",
+["lBarr"]="⤎",
+["plankv"]="â„",
+["Uacute"]="Ú",
+["cemptyv"]="⦲",
+["squarf"]="â–ª",
+["diamondsuit"]="♦",
+["rightharpoonup"]="⇀",
+["rtri"]="â–¹",
+["Jcy"]="Й",
+["copf"]="ð•”",
+["langd"]="⦑",
+["xlArr"]="⟸",
+["egrave"]="è",
+["Lcaron"]="Ľ",
+["range"]="⦥",
+["solbar"]="⌿",
+["veeeq"]="≚",
+["suphsol"]="⟉",
+["brvbar"]="¦",
+["Ecirc"]="Ê",
+["nmid"]="∤",
+["shortmid"]="∣",
+["hookleftarrow"]="↩",
+["GreaterEqual"]="≥",
+["Icy"]="И",
+["uscr"]="ð“Š",
+["gel"]="â‹›",
+["ocir"]="⊚",
+["dzcy"]="ÑŸ",
+["GT"]=">",
+["ordm"]="º",
+["chi"]="χ",
+["Implies"]="⇒",
+["Verbar"]="‖",
+["nsupseteqq"]="⫆̸",
+["Dcy"]="Д",
+["it"]="â¢",
+["Ncaron"]="Ň",
+["eopf"]="ð•–",
+["gtcir"]="⩺",
+["emsp13"]=" ",
+["nGt"]="≫⃒",
+["ges"]="⩾",
+["Dashv"]="⫤",
+["andslope"]="⩘",
+["bsolb"]="⧅",
+["sup1"]="¹",
+["bopf"]="ð•“",
+["iogon"]="į",
+["puncsp"]=" ",
+["sscr"]="ð“ˆ",
+["SquareSupersetEqual"]="⊒",
+["neArr"]="⇗",
+["Ccedil"]="Ç",
+["mapstodown"]="↧",
+["aacute"]="á",
+["ForAll"]="∀",
+["lbbrk"]="â²",
+["leftrightarrows"]="⇆",
+["mDDot"]="∺",
+["sccue"]="≽",
+["otilde"]="õ",
+["NotSquareSuperset"]="âŠÌ¸",
+["succapprox"]="⪸",
+["nrarrc"]="⤳̸",
+["wopf"]="ð•¨",
+["nu"]="ν",
+["jcirc"]="ĵ",
+["rHar"]="⥤",
+["rdquo"]="â€",
+["conint"]="∮",
+["ensp"]=" ",
+["les"]="⩽",
+["supseteq"]="⊇",
+["uparrow"]="↑",
+["Larr"]="↞",
+["breve"]="˘",
+["questeq"]="≟",
+["topf"]="ð•¥",
+["Hfr"]="ℌ",
+["icirc"]="î",
+["sigmaf"]="Ï‚",
+["nbsp"]=" ",
+["mho"]="℧",
+["dotsquare"]="⊡",
+["rarrsim"]="⥴",
+["strns"]="¯",
+["swArr"]="⇙",
+["leftrightharpoons"]="⇋",
+["THORN"]="Þ",
+["lsaquo"]="‹",
+["varnothing"]="∅",
+["Afr"]="ð”„",
+["Or"]="â©”",
+["subedot"]="⫃",
+["agrave"]="à",
+["fltns"]="â–±",
+["apos"]="'",
+["Imacr"]="Ī",
+["Cap"]="â‹’",
+["lbrace"]="{",
+["lrhar"]="⇋",
+["euml"]="ë",
+["scirc"]="Å",
+["NotPrecedes"]="⊀",
+["leftrightsquigarrow"]="↭",
+["female"]="♀",
+["urcrop"]="⌎",
+["Pr"]="⪻",
+["NotLessSlantEqual"]="⩽̸",
+["subsup"]="â«“",
+["GreaterTilde"]="≳",
+["timesbar"]="⨱",
+["Gg"]="â‹™",
+["NotSquareSupersetEqual"]="â‹£",
+["starf"]="★",
+["sdotb"]="⊡",
+["xlarr"]="⟵",
+["xharr"]="⟷",
+["NotHumpDownHump"]="≎̸",
+["andd"]="⩜",
+["nis"]="⋼",
+["esdot"]="â‰",
+["ApplyFunction"]="â¡",
+["scnap"]="⪺",
+["Cup"]="â‹“",
+["dollar"]="$",
+["ShortUpArrow"]="↑",
+["nsupseteq"]="⊉",
+["solb"]="⧄",
+["Lcedil"]="Ä»",
+["rharul"]="⥬",
+["xopf"]="ð•©",
+["mu"]="μ",
+["Ntilde"]="Ñ",
+["QUOT"]="\"",
+["varrho"]="ϱ",
+["zwj"]="â€",
+["trpezium"]="â¢",
+["dbkarow"]="â¤",
+["zscr"]="ð“",
+["boxhU"]="╨",
+["circledcirc"]="⊚",
+["Efr"]="ð”ˆ",
+["hcirc"]="Ä¥",
+["Otilde"]="Õ",
+["subseteq"]="⊆",
+["swarhk"]="⤦",
+["nGtv"]="≫̸",
+["ddotseq"]="â©·",
+["cularrp"]="⤽",
+["RightArrowLeftArrow"]="⇄",
+["rx"]="â„ž",
+["mnplus"]="∓",
+["auml"]="ä",
+["uogon"]="ų",
+["notinvc"]="⋶",
+["Ffr"]="ð”‰",
+["apid"]="≋",
+["lharul"]="⥪",
+["gcirc"]="Ä",
+["ljcy"]="Ñ™",
+["dharr"]="⇂",
+["phiv"]="Ï•",
+["Beta"]="Î’",
+["kgreen"]="ĸ",
+["ne"]="≠",
+["oopf"]="ð• ",
+["top"]="⊤",
+["orslope"]="â©—",
+["succnsim"]="â‹©",
+["erDot"]="≓",
+["OverBracket"]="⎴",
+["lesg"]="⋚︀",
+["eDDot"]="â©·",
+["nbsp"]=" ",
+["plusdo"]="∔",
+["Omacr"]="Ō",
+["ape"]="≊",
+["lbrke"]="⦋",
+["zwnj"]="‌",
+["straightphi"]="Ï•",
+["NotGreaterGreater"]="≫̸",
+["cong"]="≅",
+["lopf"]="ð•",
+["ntlg"]="≸",
+["iiiint"]="⨌",
+["nshortmid"]="∤",
+["Darr"]="↡",
+["LeftAngleBracket"]="⟨",
+["itilde"]="Ä©",
+["triangleright"]="â–¹",
+["mcomma"]="⨩",
+["ETH"]="Ã",
+["roang"]="⟭",
+["apE"]="â©°",
+["reals"]="â„",
+["qopf"]="ð•¢",
+["nsub"]="⊄",
+["mid"]="∣",
+["NotSucceedsEqual"]="⪰̸",
+["szlig"]="ß",
+["uwangle"]="⦧",
+["Kappa"]="Κ",
+["rotimes"]="⨵",
+["notniva"]="∌",
+["xutri"]="â–³",
+["Iota"]="Ι",
+["UnderBar"]="_",
+["leqq"]="≦",
+["notinva"]="∉",
+["nopf"]="ð•Ÿ",
+["ubrcy"]="Ñž",
+["urcorn"]="âŒ",
+["luruhar"]="⥦",
+["nLtv"]="≪̸",
+["angsph"]="∢",
+["minusb"]="⊟",
+["nesear"]="⤨",
+["bot"]="⊥",
+["Abreve"]="Ä‚",
+["equiv"]="≡",
+["EmptyVerySmallSquare"]="â–«",
+["bigtriangledown"]="â–½",
+["nvlt"]="<⃒",
+["cylcty"]="⌭",
+["PartialD"]="∂",
+["ni"]="∋",
+["leftarrowtail"]="↢",
+["ClockwiseContourIntegral"]="∲",
+["divonx"]="⋇",
+["rsaquo"]="›",
+["bsime"]="â‹",
+["popf"]="ð•¡",
+["quaternions"]="â„",
+["boxhu"]="â”´",
+["disin"]="⋲",
+["Tcedil"]="Å¢",
+["angmsdaa"]="⦨",
+["npre"]="⪯̸",
+["gesl"]="⋛︀",
+["ldquo"]="“",
+["between"]="≬",
+["wedgeq"]="≙",
+["in"]="∈",
+["pi"]="Ï€",
+["acute"]="´",
+["uopf"]="ð•¦",
+["succnapprox"]="⪺",
+["nleqq"]="≦̸",
+["ENG"]="ÅŠ",
+["NotEqualTilde"]="≂̸",
+["circlearrowleft"]="↺",
+["rtrie"]="⊵",
+["integers"]="ℤ",
+["frac13"]="â…“",
+["gEl"]="⪌",
+["ropf"]="ð•£",
+["Sigma"]="Σ",
+["ocirc"]="ô",
+["DownRightTeeVector"]="⥟",
+["rfloor"]="⌋",
+["SHCHcy"]="Щ",
+["Uuml"]="Ü",
+["llarr"]="⇇",
+["efDot"]="≒",
+["NestedLessLess"]="≪",
+["SHcy"]="Ш",
+["NotCupCap"]="≭",
+["xdtri"]="â–½",
+["curlyvee"]="â‹Ž",
+["downharpoonleft"]="⇃",
+["Dopf"]="ð”»",
+["napos"]="ʼn",
+["Auml"]="Ä",
+["profline"]="⌒",
+["Ycirc"]="Ŷ",
+["RightDownTeeVector"]="â¥",
+["rAtail"]="⤜",
+["osol"]="⊘",
+["atilde"]="ã",
+["Kscr"]="ð’¦",
+["ang"]="∠",
+["natur"]="â™®",
+["Gopf"]="ð”¾",
+["AMP"]="&",
+["DoubleDot"]="¨",
+["Ouml"]="Ö",
+["dlcrop"]="âŒ",
+["bsolhsub"]="⟈",
+["NestedGreaterGreater"]="≫",
+["prcue"]="≼",
+["Uarr"]="↟",
+["dHar"]="⥥",
+["ssmile"]="⌣",
+["eqslantgtr"]="⪖",
+["glj"]="⪤",
+["hstrok"]="ħ",
+["lesssim"]="≲",
+["lowast"]="∗",
+["cirmid"]="⫯",
+["lates"]="⪭︀",
+["fnof"]="Æ’",
+["ord"]="â©",
+["rthree"]="⋌",
+["rcub"]="}",
+["Coproduct"]="âˆ",
+["curren"]="¤",
+["Mscr"]="ℳ",
+["Iopf"]="ð•€",
+["vprop"]="âˆ",
+["andv"]="â©š",
+["vrtri"]="⊳",
+["yacute"]="ý",
+["tilde"]="˜",
+["numsp"]=" ",
+["acd"]="∿",
+["blk34"]="â–“",
+["Pscr"]="ð’«",
+["ReverseEquilibrium"]="⇋",
+["diams"]="♦",
+["Hopf"]="â„",
+["veebar"]="⊻",
+["Euml"]="Ë",
+["intprod"]="⨼",
+["macr"]="¯",
+["Oscr"]="ð’ª",
+["nvle"]="≤⃒",
+["odblac"]="Å‘",
+["eqcirc"]="≖",
+["Kopf"]="ð•‚",
+["bumpeq"]="â‰",
+["twoheadrightarrow"]="↠",
+["apacir"]="⩯",
+["elinters"]="â§",
+["forall"]="∀",
+["ofcir"]="⦿",
+["dstrok"]="Ä‘",
+["simne"]="≆",
+["mopf"]="ð•ž",
+["RightTriangleBar"]="â§",
+["Jopf"]="ð•",
+["parsim"]="⫳",
+["pm"]="±",
+["boxh"]="─",
+["sqsupseteq"]="⊒",
+["eplus"]="⩱",
+["xi"]="ξ",
+["Diamond"]="â‹„",
+["Wcirc"]="Å´",
+["ReverseUpEquilibrium"]="⥯",
+["ovbar"]="⌽",
+["rho"]="Ï",
+["Map"]="⤅",
+["Qscr"]="ð’¬",
+["lhblk"]="â–„",
+["Igrave"]="Ì",
+["LeftTriangle"]="⊲",
+["LeftVectorBar"]="⥒",
+["late"]="⪭",
+["cups"]="∪︀",
+["lAtail"]="⤛",
+["RightTriangle"]="⊳",
+["Tscr"]="ð’¯",
+["capbrcup"]="⩉",
+["verbar"]="|",
+["leqslant"]="⩽",
+["DownBreve"]="Ì‘",
+["Laplacetrf"]="â„’",
+["nlsim"]="≴",
+["dblac"]="Ë",
+["empty"]="∅",
+["bowtie"]="⋈",
+["subdot"]="⪽",
+["oror"]="â©–",
+["LeftUpDownVector"]="⥑",
+["varkappa"]="Ï°",
+["kjcy"]="ќ",
+["iukcy"]="Ñ–",
+["angmsdag"]="⦮",
+["Sscr"]="ð’®",
+["frac34"]="¾",
+["acirc"]="â",
+["eqslantless"]="⪕",
+["YUcy"]="Ю",
+["swarr"]="↙",
+["DownArrow"]="↓",
+["Cdot"]="ÄŠ",
+["RuleDelayed"]="⧴",
+["UnderBracket"]="⎵",
+["sqcaps"]="⊓︀",
+["bbrktbrk"]="⎶",
+["barvee"]="⊽",
+["jukcy"]="Ñ”",
+["middot"]="·",
+["Psi"]="Ψ",
+["DifferentialD"]="â…†",
+["ordf"]="ª",
+["yucy"]="ÑŽ",
+["int"]="∫",
+["maltese"]="✠",
+["lHar"]="⥢",
+["NotLessLess"]="≪̸",
+["filig"]="ï¬",
+["af"]="â¡",
+["duarr"]="⇵",
+["boxVR"]="â• ",
+["elsdot"]="⪗",
+["Egrave"]="È",
+["RightDownVector"]="⇂",
+["bernou"]="ℬ",
+["szlig"]="ß",
+["Ncedil"]="Å…",
+["Aopf"]="ð”¸",
+["Ccedil"]="Ç",
+["DoubleLongLeftArrow"]="⟸",
+["Xscr"]="ð’³",
+["Mellintrf"]="ℳ",
+["ccedil"]="ç",
+["NotRightTriangleEqual"]="â‹­",
+["lotimes"]="⨴",
+["gjcy"]="Ñ“",
+["boxVr"]="â•Ÿ",
+["cuepr"]="â‹ž",
+["DiacriticalTilde"]="˜",
+["nwarr"]="↖",
+["plusb"]="⊞",
+["Iuml"]="Ã",
+["Gt"]="≫",
+["boxuL"]="â•›",
+["gsiml"]="âª",
+["vee"]="∨",
+["NotGreaterEqual"]="≱",
+["isinv"]="∈",
+["eng"]="Å‹",
+["lessdot"]="â‹–",
+["olcross"]="⦻",
+["pound"]="£",
+["RightUpVector"]="↾",
+["Chi"]="Χ",
+["num"]="#",
+["Because"]="∵",
+["udarr"]="⇅",
+["Copf"]="â„‚",
+["precnsim"]="⋨",
+["Bernoullis"]="ℬ",
+["angmsdah"]="⦯",
+["LeftFloor"]="⌊",
+["boxvR"]="â•ž",
+["plusmn"]="±",
+["ContourIntegral"]="∮",
+["notinE"]="⋹̸",
+["nwarhk"]="⤣",
+["gtrless"]="≷",
+["complexes"]="â„‚",
+["dashv"]="⊣",
+["SubsetEqual"]="⊆",
+["NotVerticalBar"]="∤",
+["Yscr"]="ð’´",
+["RightCeiling"]="⌉",
+["Rarr"]="↠",
+["vartheta"]="Ï‘",
+["PrecedesSlantEqual"]="≼",
+["boxUR"]="â•š",
+["ntilde"]="ñ",
+["boxVL"]="â•£",
+["bigvee"]="â‹",
+["aelig"]="æ",
+["angrtvbd"]="â¦",
+["scap"]="⪸",
+["Topf"]="ð•‹",
+["hfr"]="ð”¥",
+["Nu"]="Î",
+["Downarrow"]="⇓",
+["rsquor"]="’",
+["circledS"]="Ⓢ",
+["ntilde"]="ñ",
+["circledast"]="⊛",
+["eqsim"]="≂",
+["kcy"]="к",
+["ldrdhar"]="⥧",
+["nLl"]="⋘̸",
+["hyphen"]="â€",
+["Conint"]="∯",
+["xsqcup"]="⨆",
+["asympeq"]="â‰",
+["Wopf"]="ð•Ž",
+["gfr"]="ð”¤",
+["larr"]="â†",
+["ncy"]="н",
+["iacute"]="í",
+["gE"]="≧",
+["gesdoto"]="⪂",
+["tshcy"]="Ñ›",
+["IEcy"]="Е",
+["NotGreater"]="≯",
+["Vbar"]="â««",
+["Vopf"]="ð•",
+["UpArrowDownArrow"]="⇅",
+["mp"]="∓",
+["RightDownVectorBar"]="⥕",
+["exist"]="∃",
+["frac38"]="⅜",
+["zdot"]="ż",
+["eparsl"]="⧣",
+["lacute"]="ĺ",
+["zopf"]="ð•«",
+["zigrarr"]="â‡",
+["zhcy"]="ж",
+["zeetrf"]="ℨ",
+["vangrt"]="⦜",
+["Breve"]="˘",
+["odot"]="⊙",
+["blacklozenge"]="⧫",
+["NotRightTriangle"]="â‹«",
+["yuml"]="ÿ",
+["homtht"]="∻",
+["yscr"]="ð“Ž",
+["yopf"]="ð•ª",
+["afr"]="ð”ž",
+["Yopf"]="ð•",
+["ThinSpace"]=" ",
+["yfr"]="ð”¶",
+["larrlp"]="↫",
+["yen"]="Â¥",
+["nwarrow"]="↖",
+["supmult"]="â«‚",
+["nearrow"]="↗",
+["bigsqcup"]="⨆",
+["yacy"]="Ñ",
+["lcy"]="л",
+["ii"]="â…ˆ",
+["seswar"]="⤩",
+["yacute"]="ý",
+["lArr"]="â‡",
+["Uparrow"]="⇑",
+["xwedge"]="â‹€",
+["xrarr"]="⟶",
+["xrArr"]="⟹",
+["oast"]="⊛",
+["xoplus"]="â¨",
+["ImaginaryI"]="â…ˆ",
+["xnis"]="â‹»",
+["xhArr"]="⟺",
+["xcirc"]="â—¯",
+["xcap"]="â‹‚",
+["wreath"]="≀",
+["wp"]="℘",
+["lfr"]="ð”©",
+["wedbar"]="â©Ÿ",
+["psi"]="ψ",
+["Xopf"]="ð•",
+["vzigzag"]="⦚",
+["realpart"]="ℜ",
+["vsubne"]="⊊︀",
+["DoubleLongLeftRightArrow"]="⟺",
+["nsqsube"]="â‹¢",
+["varpropto"]="âˆ",
+["npreceq"]="⪯̸",
+["vopf"]="ð•§",
+["vert"]="|",
+["vellip"]="â‹®",
+["vdash"]="⊢",
+["hkswarow"]="⤦",
+["sqsube"]="⊑",
+["tdot"]="⃛",
+["leq"]="≤",
+["nacute"]="Å„",
+["succcurlyeq"]="≽",
+["vartriangleright"]="⊳",
+["Re"]="ℜ",
+["varsupsetneqq"]="⫌︀",
+["dsol"]="⧶",
+["Tau"]="Τ",
+["rsqb"]="]",
+["varsupsetneq"]="⊋︀",
+["varsubsetneq"]="⊊︀",
+["varsigma"]="Ï‚",
+["expectation"]="â„°",
+["kfr"]="ð”¨",
+["varr"]="↕",
+["varpi"]="Ï–",
+["varphi"]="Ï•",
+["CloseCurlyDoubleQuote"]="â€",
+["varepsilon"]="ϵ",
+["zcy"]="з",
+["lt"]="<",
+["vBarv"]="â«©",
+["vBar"]="⫨",
+["larrfs"]="â¤",
+["lthree"]="â‹‹",
+["nsimeq"]="≄",
+["div"]="÷",
+["Fopf"]="ð”½",
+["rbrack"]="]",
+["searrow"]="↘",
+["lcedil"]="ļ",
+["uuarr"]="⇈",
+["utrif"]="â–´",
+["utilde"]="Å©",
+["urtri"]="â—¹",
+["mapstoleft"]="↤",
+["olcir"]="⦾",
+["upsih"]="Ï’",
+["upsi"]="Ï…",
+["curlywedge"]="â‹",
+["uplus"]="⊎",
+["upharpoonleft"]="↿",
+["updownarrow"]="↕",
+["uml"]="¨",
+["cirscir"]="⧂",
+["ffr"]="ð”£",
+["uml"]="¨",
+["epsiv"]="ϵ",
+["umacr"]="Å«",
+["ulcrop"]="âŒ",
+["ulcorner"]="⌜",
+["dtrif"]="â–¾",
+["uhblk"]="â–€",
+["uharr"]="↾",
+["ugrave"]="ù",
+["ufr"]="ð”²",
+["ufisht"]="⥾",
+["mcy"]="м",
+["ngE"]="≧̸",
+["udhar"]="⥮",
+["iinfin"]="⧜",
+["kcedil"]="Ä·",
+["natural"]="â™®",
+["udblac"]="ű",
+["Gamma"]="Γ",
+["sol"]="/",
+["ucirc"]="û",
+["dtdot"]="⋱",
+["lsimg"]="âª",
+["Gfr"]="ð”Š",
+["nearhk"]="⤤",
+["NotTildeTilde"]="≉",
+["frac15"]="â…•",
+["uarr"]="↑",
+["succeq"]="⪰",
+["COPY"]="©",
+["uacute"]="ú",
+["uHar"]="⥣",
+["efr"]="ð”¢",
+["NotGreaterSlantEqual"]="⩾̸",
+["backsim"]="∽",
+["mlcp"]="â«›",
+["Mu"]="Μ",
+["tscy"]="ц",
+["NotExists"]="∄",
+["tscr"]="ð“‰",
+["ssetmn"]="∖",
+["triplus"]="⨹",
+["tridot"]="â—¬",
+["trianglelefteq"]="⊴",
+["orderof"]="â„´",
+["thetasym"]="Ï‘",
+["emptyv"]="∅",
+["emacr"]="Ä“",
+["trade"]="â„¢",
+["spades"]="â™ ",
+["ncedil"]="ņ",
+["tprime"]="‴",
+["NotGreaterFullEqual"]="≧̸",
+["topbot"]="⌶",
+["ctdot"]="⋯",
+["sqsubset"]="âŠ",
+["comma"]=",",
+["Mcy"]="М",
+["notni"]="∌",
+["OpenCurlyDoubleQuote"]="“",
+["sup2"]="²",
+["ascr"]="ð’¶",
+["UnionPlus"]="⊎",
+["scy"]="Ñ",
+["gesdotol"]="⪄",
+["KHcy"]="Ð¥",
+["frac45"]="â…˜",
+["larrsim"]="⥳",
+["COPY"]="©",
+["comp"]="âˆ",
+["Lopf"]="ð•ƒ",
+["thorn"]="þ",
+["prE"]="⪳",
+["Eta"]="Η",
+["thksim"]="∼",
+["dscr"]="ð’¹",
+["thinsp"]=" ",
+["ucirc"]="û",
+["clubsuit"]="♣",
+["LeftDownVector"]="⇃",
+["oscr"]="â„´",
+["thetav"]="Ï‘",
+["TildeFullEqual"]="≅",
+["triangle"]="â–µ",
+["smashp"]="⨳",
+["subsetneqq"]="â«‹",
+["ecirc"]="ê",
+["therefore"]="∴",
+["Theta"]="Θ",
+["plusdu"]="⨥",
+["Assign"]="≔",
+["telrec"]="⌕",
+["UpperLeftArrow"]="↖",
+["boxUL"]="â•",
+["planck"]="â„",
+["rarrc"]="⤳",
+["UpDownArrow"]="↕",
+["incare"]="â„…",
+["vcy"]="в",
+["Oopf"]="ð•†",
+["cwint"]="∱",
+["Kcy"]="К",
+["PrecedesEqual"]="⪯",
+["coloneq"]="≔",
+["duhar"]="⥯",
+["NewLine"]="\n",
+["tau"]="Ï„",
+["supE"]="⫆",
+["downarrow"]="↓",
+["half"]="½",
+["cscr"]="ð’¸",
+["omacr"]="Å",
+["SquareSubset"]="âŠ",
+["downharpoonright"]="⇂",
+["Uopf"]="ð•Œ",
+["swnwar"]="⤪",
+["swarrow"]="↙",
+["nGg"]="⋙̸",
+["imped"]="Ƶ",
+["diam"]="â‹„",
+["gla"]="⪥",
+["horbar"]="―",
+["eth"]="ð",
+["supsup"]="â«–",
+["hslash"]="â„",
+["circeq"]="≗",
+["darr"]="↓",
+["supsim"]="⫈",
+["supset"]="⊃",
+["supplus"]="â«€",
+["ecolon"]="≕",
+["csube"]="â«‘",
+["Nopf"]="â„•",
+["RoundImplies"]="⥰",
+["ycy"]="Ñ‹",
+["suphsub"]="â«—",
+["SucceedsSlantEqual"]="≽",
+["capand"]="â©„",
+["fscr"]="ð’»",
+["supdot"]="⪾",
+["Bfr"]="ð”…",
+["NotLeftTriangle"]="⋪",
+["RightArrowBar"]="⇥",
+["boxVH"]="╬",
+["raquo"]="»",
+["rightleftarrows"]="⇄",
+["Cross"]="⨯",
+["egsdot"]="⪘",
+["nvDash"]="⊭",
+["RBarr"]="â¤",
+["sup3"]="³",
+["cuvee"]="â‹Ž",
+["sup2"]="²",
+["angst"]="Ã…",
+["backcong"]="≌",
+["oelig"]="Å“",
+["Kfr"]="ð”Ž",
+["boxVh"]="â•«",
+["Zfr"]="ℨ",
+["sung"]="♪",
+["tcy"]="Ñ‚",
+["nshortparallel"]="∦",
+["Qopf"]="â„š",
+["sum"]="∑",
+["succsim"]="≿",
+["rmoust"]="⎱",
+["nleftarrow"]="↚",
+["cup"]="∪",
+["vsubnE"]="⫋︀",
+["copy"]="©",
+["Vdash"]="⊩",
+["Kcedil"]="Ķ",
+["escr"]="ℯ",
+["gnE"]="≩",
+["uacute"]="ú",
+["napid"]="≋̸",
+["le"]="≤",
+["DD"]="â……",
+["rarrlp"]="↬",
+["Lfr"]="ð”",
+["subsim"]="⫇",
+["ZHcy"]="Ж",
+["subseteqq"]="â«…",
+["rcedil"]="Å—",
+["napprox"]="≉",
+["laquo"]="«",
+["njcy"]="Ñš",
+["Colone"]="â©´",
+["Nacute"]="Ń",
+["Yfr"]="ð”œ",
+["aring"]="Ã¥",
+["mapsto"]="↦",
+["brvbar"]="¦",
+["Popf"]="â„™",
+["sigma"]="σ",
+["subrarr"]="⥹",
+["cire"]="≗",
+["subplus"]="⪿",
+["dfr"]="ð”¡",
+["subne"]="⊊",
+["hscr"]="ð’½",
+["lgE"]="⪑",
+["racute"]="Å•",
+["LeftRightVector"]="⥎",
+["subnE"]="â«‹",
+["isinE"]="⋹",
+["boxdR"]="â•’",
+["CupCap"]="â‰",
+["ncongdot"]="⩭̸",
+["bigcap"]="â‹‚",
+["nsce"]="⪰̸",
+["submult"]="â«",
+["NotLessEqual"]="≰",
+["piv"]="Ï–",
+["mstpos"]="∾",
+["sub"]="⊂",
+["cent"]="¢",
+["capcup"]="⩇",
+["blacksquare"]="â–ª",
+["Oacute"]="Ó",
+["circledR"]="®",
+["Atilde"]="Ã",
+["tritime"]="⨻",
+["notnivb"]="⋾",
+["Sopf"]="ð•Š",
+["Sum"]="∑",
+["hoarr"]="⇿",
+["Scedil"]="Åž",
+["square"]="â–¡",
+["cfr"]="ð” ",
+["divide"]="÷",
+["sacute"]="Å›",
+["NotLessTilde"]="≴",
+["gscr"]="â„Š",
+["ll"]="≪",
+["isins"]="â‹´",
+["PrecedesTilde"]="≾",
+["sqsupset"]="âŠ",
+["OverBrace"]="âž",
+["Epsilon"]="Ε",
+["sqsupe"]="⊒",
+["iprod"]="⨼",
+["dash"]="â€",
+["sqsup"]="âŠ",
+["nsccue"]="â‹¡",
+["infin"]="∞",
+["frac25"]="â…–",
+["backepsilon"]="϶",
+["robrk"]="⟧",
+["harr"]="↔",
+["ogt"]="â§",
+["sopf"]="ð•¤",
+["larrhk"]="↩",
+["boxvl"]="┤",
+["tcedil"]="Å£",
+["cwconint"]="∲",
+["lfloor"]="⌊",
+["ucy"]="у",
+["CloseCurlyQuote"]="’",
+["lsquor"]="‚",
+["softcy"]="ь",
+["smte"]="⪬",
+["smt"]="⪪",
+["isindot"]="⋵",
+["Pi"]="Π",
+["lnE"]="≨",
+["caret"]="â",
+["TildeEqual"]="≃",
+["delta"]="δ",
+["euro"]="€",
+["angrtvb"]="⊾",
+["Escr"]="â„°",
+["Ucirc"]="Û",
+["rarrap"]="⥵",
+["smile"]="⌣",
+["ccupssm"]="â©",
+["LeftArrow"]="â†",
+["frac12"]="½",
+["smallsetminus"]="∖",
+["Zscr"]="ð’µ",
+["angrt"]="∟",
+["lurdshar"]="⥊",
+["simrarr"]="⥲",
+["boxUl"]="╜",
+["simplus"]="⨤",
+["scedil"]="ÅŸ",
+["Eacute"]="É",
+["ast"]="*",
+["simg"]="⪞",
+["Aring"]="Ã…",
+["yuml"]="ÿ",
+["bsemi"]="â",
+["Omicron"]="Ο",
+["simdot"]="⩪",
+["sim"]="∼",
+["OverBar"]="‾",
+["intlarhk"]="⨗",
+["sfr"]="ð”°",
+["boxDl"]="â•–",
+["Cconint"]="∰",
+["ncaron"]="ň",
+["Lmidot"]="Ä¿",
+["shy"]="­",
+["LeftTriangleEqual"]="⊴",
+["esim"]="≂",
+["THORN"]="Þ",
+["REG"]="®",
+["xodot"]="⨀",
+["ddarr"]="⇊",
+["setmn"]="∖",
+["Ugrave"]="Ù",
+["setminus"]="∖",
+["dotminus"]="∸",
+["semi"]=";",
+["sect"]="§",
+["ncong"]="≇",
+["bNot"]="â«­",
+["Rho"]="Ρ",
+["GJcy"]="Ѓ",
+["boxhD"]="â•¥",
+["searr"]="↘",
+["Del"]="∇",
+["auml"]="ä",
+["Cfr"]="â„­",
+["VDash"]="⊫",
+["seArr"]="⇘",
+["ncap"]="⩃",
+["Product"]="âˆ",
+["sdot"]="â‹…",
+["frac58"]="â…",
+["zcaron"]="ž",
+["DZcy"]="Ð",
+["ltlarr"]="⥶",
+["scsim"]="≿",
+["VerticalTilde"]="≀",
+["squf"]="â–ª",
+["dharl"]="⇃",
+["iexcl"]="¡",
+["bumpE"]="⪮",
+["scnsim"]="â‹©",
+["drcorn"]="⌟",
+["Xfr"]="ð”›",
+["nsube"]="⊈",
+["Dfr"]="ð”‡",
+["nsmid"]="∤",
+["not"]="¬",
+["ShortRightArrow"]="→",
+["hookrightarrow"]="↪",
+["par"]="∥",
+["sc"]="≻",
+["rtrif"]="â–¸",
+["tosa"]="⤩",
+["acirc"]="â",
+["gtcc"]="⪧",
+["DJcy"]="Ђ",
+["NotLeftTriangleEqual"]="⋬",
+["bigcirc"]="â—¯",
+["rbrksld"]="⦎",
+["angmsdab"]="⦩",
+["Aring"]="Ã…",
+["rlm"]="â€",
+["Therefore"]="∴",
+["lambda"]="λ",
+["LowerRightArrow"]="↘",
+["asymp"]="≈",
+["rscr"]="ð“‡",
+["ouml"]="ö",
+["boxDr"]="â•“",
+["divideontimes"]="⋇",
+["rppolint"]="⨒",
+["oacute"]="ó",
+["Rcedil"]="Å–",
+["roplus"]="⨮",
+["DownLeftVectorBar"]="⥖",
+["Wfr"]="ð”š",
+["lesseqgtr"]="â‹š",
+["ropar"]="⦆",
+["bnot"]="âŒ",
+["Integral"]="∫",
+["boxdr"]="┌",
+["LeftTee"]="⊣",
+["hercon"]="⊹",
+["rnmid"]="â«®",
+["gvnE"]="≩︀",
+["bdquo"]="„",
+["Zacute"]="Ź",
+["Lscr"]="â„’",
+["ring"]="Ëš",
+["supseteqq"]="⫆",
+["kscr"]="ð“€",
+["approxeq"]="≊",
+["ntriangleright"]="â‹«",
+["lessgtr"]="≶",
+["prurel"]="⊰",
+["rightleftharpoons"]="⇌",
+["pitchfork"]="â‹”",
+["ltrPar"]="⦖",
+["NotSubset"]="⊂⃒",
+["Yacute"]="Ã",
+["eta"]="η",
+["Rfr"]="ℜ",
+["UpTee"]="⊥",
+["rfisht"]="⥽",
+["HumpEqual"]="â‰",
+["NotLess"]="≮",
+["sbquo"]="‚",
+["pointint"]="⨕",
+["ycirc"]="Å·",
+["lescc"]="⪨",
+["looparrowright"]="↬",
+["cross"]="✗",
+["grave"]="`",
+["rdquor"]="â€",
+["blacktriangleleft"]="â—‚",
+["rdldhar"]="⥩",
+["Nscr"]="ð’©",
+["atilde"]="ã",
+["lsqb"]="[",
+["lbrack"]="[",
+["Lambda"]="Λ",
+["rbrace"]="}",
+["times"]="×",
+["deg"]="°",
+["uuml"]="ü",
+["MediumSpace"]="âŸ",
+["lAarr"]="⇚",
+["bull"]="•",
+["daleth"]="ℸ",
+["ccirc"]="ĉ",
+["capcap"]="â©‹",
+["fllig"]="fl",
+["Qfr"]="ð””",
+["lopar"]="⦅",
+["nspar"]="∦",
+["RightTriangleEqual"]="⊵",
+["rbrke"]="⦌",
+["NotPrecedesSlantEqual"]="â‹ ",
+["rbbrk"]="â³",
+["hbar"]="â„",
+["rbarr"]="â¤",
+["rationals"]="â„š",
+["Oslash"]="Ø",
+["frac14"]="¼",
+["ratio"]="∶",
+["ratail"]="⤚",
+["rarrw"]="â†",
+["Gammad"]="Ϝ",
+["rarrhk"]="↪",
+["rarrfs"]="⤞",
+["lparlt"]="⦓",
+["rarr"]="→",
+["Backslash"]="∖",
+["zacute"]="ź",
+["euml"]="ë",
+["GreaterGreater"]="⪢",
+["NotTilde"]="â‰",
+["rang"]="⟩",
+["deg"]="°",
+["rArr"]="⇒",
+["congdot"]="â©­",
+["rAarr"]="⇛",
+["roarr"]="⇾",
+["emsp14"]=" ",
+["quot"]="\"",
+["isinsv"]="⋳",
+["quatint"]="⨖",
+["bcy"]="б",
+["qprime"]="â—",
+["race"]="∽̱",
+["tint"]="∭",
+["egs"]="⪖",
+["Proportion"]="∷",
+["aleph"]="ℵ",
+["wcirc"]="ŵ",
+["prime"]="′",
+["barwedge"]="⌅",
+["precsim"]="≾",
+["frac18"]="â…›",
+["nsubseteqq"]="⫅̸",
+["primes"]="â„™",
+["csup"]="â«",
+["boxuR"]="╘",
+["lmidot"]="Å€",
+["squ"]="â–¡",
+["Oslash"]="Ø",
+["SOFTcy"]="Ь",
+["nvinfin"]="⧞",
+["precneqq"]="⪵",
+["precnapprox"]="⪹",
+["SupersetEqual"]="⊇",
+["angmsdaf"]="⦭",
+["preccurlyeq"]="≼",
+["precapprox"]="⪷",
+["amp"]="&",
+["cudarrr"]="⤵",
+["Bscr"]="ℬ",
+["circleddash"]="âŠ",
+["pr"]="≺",
+["emsp"]=" ",
+["DoubleLongRightArrow"]="⟹",
+["cupcap"]="⩆",
+["plustwo"]="⨧",
+["numero"]="â„–",
+["ddagger"]="‡",
+["die"]="¨",
+["vArr"]="⇕",
+["Ograve"]="Ã’",
+["LeftArrowBar"]="⇤",
+["period"]=".",
+["InvisibleTimes"]="â¢",
+["NoBreak"]="â ",
+["ap"]="≈",
+["rtriltri"]="⧎",
+["curarrm"]="⤼",
+["planckh"]="â„Ž",
+["Leftarrow"]="â‡",
+["Not"]="⫬",
+["RightDoubleBracket"]="⟧",
+["Xi"]="Ξ",
+["phone"]="☎",
+["blk12"]="â–’",
+["boxvr"]="├",
+["intcal"]="⊺",
+["gneqq"]="≩",
+["Hacek"]="ˇ",
+["bscr"]="ð’·",
+["pfr"]="ð”­",
+["pertenk"]="‱",
+["perp"]="⊥",
+["npart"]="∂̸",
+["Odblac"]="Å",
+["Vfr"]="ð”™",
+["Ocy"]="О",
+["rhard"]="â‡",
+["Vscr"]="ð’±",
+["Square"]="â–¡",
+["hearts"]="♥",
+["NotSubsetEqual"]="⊈",
+["uArr"]="⇑",
+["nrArr"]="â‡",
+["otimesas"]="⨶",
+["ggg"]="â‹™",
+["otilde"]="õ",
+["ee"]="â…‡",
+["NotElement"]="∉",
+["VerticalLine"]="|",
+["orv"]="â©›",
+["Umacr"]="Ū",
+["boxHU"]="â•©",
+["Mopf"]="ð•„",
+["Uscr"]="ð’°",
+["EqualTilde"]="≂",
+["Pcy"]="П",
+["ordm"]="º",
+["DoubleContourIntegral"]="∯",
+["triangledown"]="â–¿",
+["or"]="∨",
+["DownTee"]="⊤",
+["frac56"]="â…š",
+["ominus"]="⊖",
+["oslash"]="ø",
+["omid"]="⦶",
+["para"]="¶",
+["gescc"]="⪩",
+["Ufr"]="ð”˜",
+["omicron"]="ο",
+["doteq"]="â‰",
+["mumap"]="⊸",
+["urcorner"]="âŒ",
+["olarr"]="↺",
+["DotEqual"]="â‰",
+["ogon"]="Ë›",
+["odiv"]="⨸",
+["ltcc"]="⪦",
+["nparsl"]="⫽⃥",
+["Colon"]="∷",
+["REG"]="®",
+["cirE"]="⧃",
+["laemptyv"]="⦴",
+["Igrave"]="Ì",
+["rdsh"]="↳",
+["nsucc"]="âŠ",
+["xotime"]="⨂",
+["Wscr"]="ð’²",
+["ShortDownArrow"]="↓",
+["copysr"]="â„—",
+["Longleftarrow"]="⟸",
+["oS"]="Ⓢ",
+["Yuml"]="Ÿ",
+["becaus"]="∵",
+["Rightarrow"]="⇒",
+["nwArr"]="⇖",
+["nvsim"]="∼⃒",
+["SquareIntersection"]="⊓",
+["Barv"]="⫧",
+["nvrtrie"]="⊵⃒",
+["nvltrie"]="⊴⃒",
+["sube"]="⊆",
+["boxHd"]="╤",
+["Iukcy"]="І",
+["NotSquareSubsetEqual"]="â‹¢",
+["DownRightVectorBar"]="⥗",
+["Jscr"]="ð’¥",
+["LeftTriangleBar"]="â§",
+["blacktriangleright"]="â–¸",
+["ntrianglerighteq"]="â‹­",
+["ntrianglelefteq"]="⋬",
+["Bopf"]="ð”¹",
+["LeftUpVector"]="↿",
+["OpenCurlyQuote"]="‘",
+["NotSupersetEqual"]="⊉",
+["Barwed"]="⌆",
+["nsupe"]="⊉",
+["nsupE"]="⫆̸",
+["lrtri"]="⊿",
+["pluse"]="⩲",
+["blk14"]="â–‘",
+["Eopf"]="ð”¼",
+["boxv"]="│",
+["Pfr"]="ð”“",
+["DownTeeArrow"]="↧",
+["DownLeftVector"]="↽",
+["YIcy"]="Ї",
+["phmmat"]="ℳ",
+["NotRightTriangleBar"]="â§Ì¸",
+["bigcup"]="⋃",
+["ubreve"]="Å­",
+["lEg"]="⪋",
+["IJlig"]="IJ",
+["nrtri"]="â‹«",
+["npolint"]="⨔",
+["micro"]="µ",
+["cir"]="â—‹",
+["ge"]="≥",
+["NotGreaterLess"]="≹",
+["YAcy"]="Я",
+["nparallel"]="∦",
+["thorn"]="þ",
+["Vert"]="‖",
+["DoubleRightTee"]="⊨",
+["sup3"]="³",
+["notindot"]="⋵̸",
+["not"]="¬",
+["Delta"]="Δ",
+["simeq"]="≃",
+["nltrie"]="⋬",
+["beth"]="ℶ",
+["bfr"]="ð”Ÿ",
+["loarr"]="⇽",
+["Ifr"]="â„‘",
+["nleq"]="≰",
+["FilledSmallSquare"]="â—¼",
+["nldr"]="‥",
+["CirclePlus"]="⊕",
+["nless"]="≮",
+["Atilde"]="Ã",
+["Ograve"]="Ã’",
+["nhpar"]="⫲",
+["rlarr"]="⇄",
+["bsol"]="\\",
+["nharr"]="↮",
+["pre"]="⪯",
+["ngtr"]="≯",
+["acy"]="а",
+["ngsim"]="≵",
+["nges"]="⩾̸",
+["ngeqq"]="≧̸",
+["Otilde"]="Õ",
+["nedot"]="â‰Ì¸",
+["nearr"]="↗",
+["frac23"]="â…”",
+["frac16"]="â…™",
+["lcaron"]="ľ",
+["naturals"]="â„•",
+["nang"]="∠⃒",
+["nVDash"]="⊯",
+["longrightarrow"]="⟶",
+["igrave"]="ì",
+["DownArrowUpArrow"]="⇵",
+["Omega"]="Ω",
+["ZeroWidthSpace"]="​",
+["curren"]="¤",
+["Jfr"]="ð”",
+["DoubleLeftArrow"]="â‡",
+["bcong"]="≌",
+["mscr"]="ð“‚",
+["Rscr"]="â„›",
+["twixt"]="≬",
+["frac12"]="½",
+["slarr"]="â†",
+["LessSlantEqual"]="⩽",
+["oint"]="∮",
+["amacr"]="Ä",
+["ell"]="â„“",
+["midcir"]="â«°",
+["Lang"]="⟪",
+["micro"]="µ",
+["ldca"]="⤶",
+["marker"]="â–®",
+["succ"]="≻",
+["Int"]="∬",
+["Jukcy"]="Є",
+["succneqq"]="⪶",
+["because"]="∵",
+["male"]="♂",
+["lrhard"]="⥭",
+["complement"]="âˆ",
+["lvertneqq"]="≨︀",
+["DoubleUpDownArrow"]="⇕",
+["ltrif"]="â—‚",
+["ltri"]="â—ƒ",
+["dot"]="Ë™",
+["bnequiv"]="≡⃥",
+["Ntilde"]="Ñ",
+["ocy"]="о",
+["lstrok"]="Å‚",
+["RightVector"]="⇀",
+["backprime"]="‵",
+["loz"]="â—Š",
+["lowbar"]="_",
+["infintie"]="â§",
+["nsqsupe"]="â‹£",
+["Tfr"]="ð”—",
+["loplus"]="⨭",
+["nsubset"]="⊂⃒",
+["looparrowleft"]="↫",
+["longmapsto"]="⟼",
+["longleftarrow"]="⟵",
+["PlusMinus"]="±",
+["NotSquareSubset"]="âŠÌ¸",
+["lobrk"]="⟦",
+["DoubleVerticalBar"]="∥",
+["NotLeftTriangleBar"]="â§Ì¸",
+["equivDD"]="⩸",
+["loang"]="⟬",
+["lneqq"]="≨",
+["iuml"]="ï",
+["lmoust"]="⎰",
+["csub"]="â«",
+["lharu"]="↼",
+["lhard"]="↽",
+["lfisht"]="⥼",
+["lesseqqgtr"]="⪋",
+["rcy"]="Ñ€",
+["cent"]="¢",
+["lessapprox"]="⪅",
+["lesges"]="⪓",
+["Utilde"]="Ũ",
+["leftharpoonup"]="↼",
+["leftarrow"]="â†",
+["awconint"]="∳",
+["lcub"]="{",
+["excl"]="!",
+["Sfr"]="ð”–",
+["leftharpoondown"]="↽",
+["Vvdash"]="⊪",
+["there4"]="∴",
+["lat"]="⪫",
+["larrtl"]="↢",
+["Precedes"]="≺",
+["Gcedil"]="Ä¢",
+["boxtimes"]="⊠",
+["colon"]=":",
+["InvisibleComma"]="â£",
+["OverParenthesis"]="âœ",
+["lagran"]="â„’",
+["Rang"]="⟫",
+["djcy"]="Ñ’",
+["curarr"]="↷",
+["gsim"]="≳",
+["cedil"]="¸",
+["boxur"]="â””",
+["rightthreetimes"]="⋌",
+["eth"]="ð",
+["Ropf"]="â„",
+["Agrave"]="À",
+["iscr"]="ð’¾",
+["ccedil"]="ç",
+["imof"]="⊷",
+["imagline"]="â„",
+["UpArrow"]="↑",
+["boxdL"]="â••",
+["Mfr"]="ð”",
+["SucceedsTilde"]="≿",
+["barwed"]="⌅",
+["NotSuperset"]="⊃⃒",
+["gneq"]="⪈",
+["hksearow"]="⤥",
+["lE"]="≦",
+["nlarr"]="↚",
+["gt"]=">",
+["Zopf"]="ℤ",
+["gammad"]="Ï",
+["rect"]="â–­",
+["Hstrok"]="Ħ",
+["frac34"]="¾",
+["acute"]="´",
+["fork"]="â‹”",
+["Vee"]="â‹",
+["ldrushar"]="⥋",
+["ThickSpace"]="âŸâ€Š",
+["LeftTeeVector"]="⥚",
+["egrave"]="è",
+["ngt"]="≯",
+["nsubseteq"]="⊈",
+["frac78"]="â…ž",
+["SquareSubsetEqual"]="⊑",
+["ecy"]="Ñ",
+["UpTeeArrow"]="↥",
+["pcy"]="п",
+["GreaterSlantEqual"]="⩾",
+["ecaron"]="Ä›",
+["cupor"]="â©…",
+["Nfr"]="ð”‘",
+["rightarrowtail"]="↣",
+["Ofr"]="ð”’",
+["subE"]="â«…",
+["IOcy"]="Ð",
+["cedil"]="¸",
+["cdot"]="Ä‹",
+["ShortLeftArrow"]="â†",
+["CircleMinus"]="⊖",
+["Dagger"]="‡",
+["cupbrcap"]="⩈",
+["SmallCircle"]="∘",
+["cirfnint"]="â¨",
+["nvge"]="≥⃒",
+["Eacute"]="É",
+["Equal"]="⩵",
+["MinusPlus"]="∓",
+["Tab"]=" ",
+}
diff --git a/macros/luatex/generic/luaxml/luaxml-parse-query.lua b/macros/luatex/generic/luaxml/luaxml-parse-query.lua
new file mode 100644
index 0000000000..7931fa193f
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml-parse-query.lua
@@ -0,0 +1,46 @@
+-- Source: https://github.com/leafo/web_sanitize
+-- Author: Leaf Corcoran
+local R, S, V, P
+do
+ local _obj_0 = require("lpeg")
+ R, S, V, P = _obj_0.R, _obj_0.S, _obj_0.V, _obj_0.P
+end
+local C, Cs, Ct, Cmt, Cg, Cb, Cc, Cp
+do
+ local _obj_0 = require("lpeg")
+ C, Cs, Ct, Cmt, Cg, Cb, Cc, Cp = _obj_0.C, _obj_0.Cs, _obj_0.Ct, _obj_0.Cmt, _obj_0.Cg, _obj_0.Cb, _obj_0.Cc, _obj_0.Cp
+end
+local alphanum = R("az", "AZ", "09")
+local num = R("09")
+local white = S(" \t\n") ^ 0
+-- this is a deviation from the upstream, we allow ":" in the tag name, because
+-- luaxml doesn't support XML namespaces and elements must be queried using
+-- dom:query_selector("namespace:element")
+local word = (alphanum + S("_-") + S("|")) ^ 1
+local mark
+mark = function(name)
+ return function(...)
+ return {
+ name,
+ ...
+ }
+ end
+end
+local parse_query
+parse_query = function(query)
+ local tag = word / mark("tag")
+ local cls = P(".") * (word / mark("class"))
+ local id = P("#") * (word / mark("id"))
+ local any = P("*") / mark("any")
+ local nth = P(":nth-child(") * C(num ^ 1) * ")" / mark("nth-child")
+ local first = P(":first-child") / mark("first-child")
+ local attr = P("[") * C(word) * P("]") / mark("attr")
+ local selector = Ct((any + nth + first + tag + cls + id + attr) ^ 1)
+ local pq = Ct(selector * (white * selector) ^ 0)
+ local pqs = Ct(pq * (white * P(",") * white * pq) ^ 0)
+ pqs = pqs * (white * -1)
+ return pqs:match(query)
+end
+return {
+ parse_query = parse_query
+}
diff --git a/macros/luatex/generic/luaxml/luaxml-pretty.lua b/macros/luatex/generic/luaxml/luaxml-pretty.lua
new file mode 100644
index 0000000000..44f3183949
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml-pretty.lua
@@ -0,0 +1,89 @@
+--module(...,package.seeall)
+
+--- Lua pretty printer from <a href="http://mini.net/cgi-bin/lua/44.html">http://mini.net/cgi-bin/lua/44.html</a><br/>
+-- This was extracted from utility code in "util.lua".<br/>
+-- 23/02/2001 jcw@equi4.com<br/>
+-- Pretty displays a value, properly dealing with tables and cycles
+
+local displayvalue=
+ function (s)
+ if not s or type(s)=='function' or type(s)=='userdata' then
+ s=tostring(s)
+ elseif type(s)~='number' then
+ s=string.gsub(string.format('%q',s),'^"([^"\']*)"$',"'%1'")
+ end
+ return s
+ end
+
+local askeystr=
+ function (u,s)
+ if type(u)=='string' and string.find(u,'^[%w_]+$') then return s..u end
+ return '['..displayvalue(u)..']'
+ end
+
+local horizvec=
+ function (x,n)
+ local o,e='',''
+ for i=1,#x do
+ if type(x[i])=='table' then return end
+ o=o..e..displayvalue(x[i])
+ if string.len(o)>n then return end
+ e=','
+ end
+ return '('..o..')'
+ end
+
+local horizmap=
+ function (x,n)
+ local o,e='',''
+ for k,v in pairs(x) do
+ if type(v)=='table' then return end
+ o=o..e..askeystr(k,'')..'='..displayvalue(v)
+ if string.len(o)>n then return end
+ e=','
+ end
+ return '{'..o..'}'
+ end
+local M = {}
+local function pretty(p,x,h,q)
+ if not p then p,x='globals',globals() end
+ if type(x)=='table' then
+ if not h then h={} end
+ if h[x] then
+ x=h[x]
+ else
+ if not q then q=p end
+ h[x]=q
+ local s={}
+ for k,v in pairs(x) do table.insert(s,k) end
+ if #s>0 then
+ local n=75-string.len(p)
+ local f=#s==#x and horizvec(x,n)
+ if not f then f=horizmap(x,n) end
+ if not f then
+ table.sort(s,function (a,b)
+ --if tag(a)~=tag(b) then a,b=tag(b),tag(a) end
+ if type(a)~=type(b) then a,b=type(b),type(a) end
+ return a<b
+ end)
+ for i=1,#s do
+ if s[i] then
+ local u=askeystr(s[i],'.')
+ pretty(p..u,x[s[i]],h,q..u)
+ p=string.rep(' ',string.len(p))
+ end
+ end
+ return
+ end
+ x=f
+ else
+ x='{}'
+ end
+ end
+ else
+ x=displayvalue(x)
+ end
+ print(p..' = '..x)
+end
+M.pretty = pretty
+return M
diff --git a/macros/luatex/generic/luaxml/luaxml-stack.lua b/macros/luatex/generic/luaxml/luaxml-stack.lua
new file mode 100644
index 0000000000..6c2d83610f
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml-stack.lua
@@ -0,0 +1,67 @@
+-- Code from http://lua-users.org/wiki/SimpleStack
+--module(...,package.seeall)
+local M={}
+local Stack = {}
+M.Stack = Stack
+local unpack = table.unpack
+-- Create a Table with stack functions
+function Stack:Create()
+
+ -- stack table
+ local t = {}
+ -- entry table
+ t._et = {}
+
+ -- push a value on to the stack
+ function t:push(...)
+ if ... then
+ local targs = {...}
+ -- add values
+ for _,v in pairs(targs) do
+ table.insert(self._et, v)
+ end
+ end
+ end
+
+ -- pop a value from the stack
+ function t:pop(num)
+
+ -- get num values from stack
+ local num = num or 1
+
+ -- return table
+ local entries = {}
+
+ -- get values into entries
+ for i = 1, num do
+ -- get last entry
+ if #self._et ~= 0 then
+ table.insert(entries, self._et[#self._et])
+ -- remove last value
+ table.remove(self._et)
+ else
+ break
+ end
+ end
+ -- return unpacked entries
+ return unpack(entries)
+ end
+
+ -- get entries
+ function t:getn()
+ return #self._et
+ end
+
+ -- list values
+ function t:list()
+ for i,v in pairs(self._et) do
+ print(i, v)
+ end
+ end
+ function t:join(s)
+ return table.concat(self._et,s)
+ end
+ return t
+end
+
+return M
diff --git a/macros/luatex/generic/luaxml/luaxml-testxml.lua b/macros/luatex/generic/luaxml/luaxml-testxml.lua
new file mode 100644
index 0000000000..8231642116
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml-testxml.lua
@@ -0,0 +1,147 @@
+#!/usr/bin/lua
+---Simple command line test parser - applies handler[s] specified
+-- to XML file (or STDIN) and dumps results<br/>
+--
+-- $Id: testxml.lua,v 1.1.1.1 2001/11/28 06:11:33 paulc Exp $<br/>
+--
+-- $Log: testxml.lua,v $<br/>
+-- Revision 1.1.1.1 2001/11/28 06:11:33 paulc<br/>
+-- Initial Import
+--
+
+modxml = require('luaxml-mod-xml')
+handler = require('luaxml-mod-handler')
+pretty = require('luaxml-pretty')
+
+
+-- Defaults
+_print = nil
+_simpletree = nil
+_dom = nil
+_file = nil
+_xmlrpc = nil
+_debug = nil
+_ws = nil
+_noentity = nil
+
+_usage = [[
+textxml.lua [-print] [-simpletree] [-dom] [-xmlrpc] [-debug]
+ [-ws] [-noentity] [-help] [file]
+]]
+
+_help = [[
+testxml.lua - Simple command line XML processor
+
+Options:
+
+ -print : Generate event dump (default)
+ -simpletree : Generate simple tree
+ -dom : Generate DOM-like tree
+ -debug : Print debug info (filename/text)
+ -ws : Do not strip whitespace
+ -noentity : Do not expand entities
+ -help : Print help
+ file : XML File (parse stdin in nil)
+]]
+
+index = 1
+local exit = os.exit
+
+function setOptions(x)
+ if _ws then
+ x.options.stripWS = nil
+ end
+ if _noentity then
+ x.options.expandEntities = nil
+ end
+end
+
+while arg[index] do
+ --print (arg[index])
+ if (string.sub(arg[index],1,1)=='-') then
+ if arg[index] == "-print" then
+ _print = 1
+ elseif arg[index] == "-simpletree" then
+ _simpletree= 1
+ elseif arg[index] == "-dom" then
+ _dom= 1
+ elseif arg[index] == "-xmlrpc" then
+ _xmlrpc= 1
+ elseif arg[index] == "-debug" then
+ _debug = 1
+ elseif arg[index] == "-ws" then
+ _ws = 1
+ elseif arg[index] == "-noentity" then
+ _noentity = 1
+ elseif arg[index] == "-help" then
+ print(_usage)
+ exit()
+ else
+ print(_usage)
+ exit()
+ end
+ else
+ -- Filename is last argument if present
+ if arg[index+1] then
+ print(_usage)
+ exit()
+ else
+ _file = arg[index]
+ end
+ end
+ index = index + 1
+end
+
+if _file then
+ print("File",_file)
+ if (_debug) then
+ io.write ( "File: ".._file.."\n" )
+ end
+ --xml = read(openfile(_file,"r"),"*a")
+
+ local f, e = io.open(_file, "r")
+ if f then
+ xml = f:read("*a")
+ else
+ error(e)
+ end
+
+else
+ xml = io.read("*a")
+end
+
+if _debug then
+ io.write ( "----------- XML\n" )
+ io.write (xml.."\n")
+end
+
+if _print or not (_print or _dom or _simpletree or _print or _xmlrpc) then
+ io.write ( "----------- Print\n" )
+ h = handler.printHandler()
+ x = modxml.xmlParser(h)
+ setOptions(x)
+ x:parse(xml)
+end
+
+if _simpletree then
+ io.write ( "----------- SimpleTree\n" )
+ h = handler.simpleTreeHandler()
+ x = modxml.xmlParser(h)
+ setOptions(x)
+ x:parse(xml)
+ pretty.pretty('root',h.root)
+end
+
+if _dom then
+ io.write ( "----------- Dom\n" )
+ h = handler.domHandler()
+ x = modxml.xmlParser(h)
+ setOptions(x)
+ x:parse(xml)
+ pretty.pretty('root',h.root)
+ io.write ( "-----------\n" )
+end
+
+
+
+
diff --git a/macros/luatex/generic/luaxml/luaxml.pdf b/macros/luatex/generic/luaxml/luaxml.pdf
new file mode 100644
index 0000000000..0f5b986026
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaxml/luaxml.tex b/macros/luatex/generic/luaxml/luaxml.tex
new file mode 100644
index 0000000000..ebaba5b4d7
--- /dev/null
+++ b/macros/luatex/generic/luaxml/luaxml.tex
@@ -0,0 +1,749 @@
+\documentclass{ltxdoc}
+% \usepackage{tgschola,url}
+\usepackage{url}
+\usepackage[english]{babel}
+\usepackage{hyperref}
+\usepackage{luacode}
+\usepackage{framed}
+% Version is defined in the makefile, use default values when compiled directly
+\ifdefined\version\else
+\def\version{v0.1h}
+\let\gitdate\date
+\fi
+\newcommand\modulename[1]{\subsection{#1}\label{sec:#1}}
+\newcommand\modulesummary[1]{#1\\}
+\newcommand\moduleclass[1]{\subsubsection{Class: #1}}
+\newcommand\functionname[2]{\par\noindent\textbf{#1(#2)}\\}
+\newcommand\functionsummary[1]{#1\\\textbf{Parameters:}\\}
+\newcommand\functionparam[2]{\texttt{#1}: #2\\}
+\newcommand\functionreturn[1]{\textbf{Return: }\\#1\\}
+
+\begin{document}
+ \title{The \textsc{LuaXML} library}
+ \author{Paul Chakravarti \and Michal Hoftich}
+ \date{Version \version\\\gitdate}
+ \maketitle
+\tableofcontents
+
+\section{Introduction}
+
+|LuaXML| is pure lua library for processing and serializing of the |xml| files.
+The base code code has been written by Paul Chakravarti, with minor changes
+which brings Lua 5.3 or HTML 5 support. On top of that, new modules for
+accessing the |xml| files using |DOM| like methods or |CSS|
+selectors\footnote{Thanks to Leaf Corcoran for |CSS selector| parsing code.}
+have been added.
+
+The documentation is divided to three parts -- first part deals with the |DOM|
+library, second part describes the low-level libraries and the third part is
+original documentation by Paul Chakravarti.
+% Current release is aimed mainly as support for the odsfile package.
+% In first release it was included with the odsfile package,
+% but as it is general library which can be used also with other packages,
+% I decided to distribute it as separate library.
+
+\section{The \texttt{DOM\_Object} library}
+
+This library can process a |xml| sources using |DOM| like functions. To load
+it, you need to require |luaxml-domobject.lua| file. The |parse| function
+provided by the library creates \texttt{DOM\_Object} object, which provides several
+methods for processing the |xml| tree.
+
+\begin{verbatim}
+local dom = require "luaxml-domobject"
+local document = [[
+<html>
+<head><title>sample</title></head>
+<body>
+<h1>test</h1>
+<p>hello</p>
+</body>
+</html>
+ ]]
+
+-- dom.parse returns the DOM_Object
+local obj = dom.parse(document)
+-- it is possible to call methods on the object
+local root_node = obj:root_node()
+for _, x in ipairs(root_node:get_children()) do
+ print(x:get_element_name())
+end
+\end{verbatim}
+
+The details about available methods can be found in the API docs, section
+\ref{sec:luaxml-domobject}. The above code will load a |xml| document, it will
+get the ROOT element and print all it's children element names. The
+\verb|DOM_Object:get_children| function returns Lua table, so it is possible to
+loop over it using standard table functions.
+
+\begin{framed}
+\begin{luacode*}
+dom = require "luaxml-domobject"
+local document = [[
+<html>
+<head><title>sample</title></head>
+<body>
+<h1>test</h1>
+<p>hello</p>
+</body>
+</html>
+ ]]
+
+-- dom.parse returns the DOM_Object
+obj = dom.parse(document)
+-- it is possible to call methods on the object
+local root_node = obj:root_node()
+for _, x in ipairs(root_node:get_children()) do
+ tex.print(x:get_element_name().. "\\par")
+end
+\end{luacode*}
+\end{framed}
+
+\subsection{Node selection methods}
+There are some other methods for element retrieving.
+
+\subsubsection{The \texttt{DOM\_Object:get\_path} method}
+If you want to print text content of all child elements of the body element, you can use \verb|DOM_Object:get_path|:
+
+\begin{verbatim}
+local path = obj:get_path("html body")
+for _, el in ipairs(path[1]:get_children()) do
+ print(el:get_text())
+end
+\end{verbatim}
+
+The \verb|DOM_Object:get_path| function always return array with all elements
+which match the requested path, even it there is only one such element. In this
+case, it is possible to use standard Lua table indexing to get the first and
+only one matched element and get it's children using
+\verb|DOM_Object:get_children| method. It the children node is an element, it's
+text content is printed using \verb|DOM_Object:get_text|.
+
+
+
+\begin{framed}
+ \begin{luacode*}
+local path = obj:get_path("html body")
+
+for _, el in ipairs(path[1]:get_children()) do
+ if el:is_element() then
+ tex.print(el:get_text().."\\par")
+ end
+end
+ \end{luacode*}
+\end{framed}
+
+\subsubsection{The \texttt{DOM\_Object:query\_selector} method}
+
+This method uses |CSS selector| syntax to select elements, similarly to JavaScript \textit{jQuery} library.
+
+\begin{verbatim}
+for _, el in ipairs(obj:query_selector("h1,p")) do
+ print(el:get_text())
+end
+\end{verbatim}
+
+
+\begin{framed}
+ \begin{luacode*}
+for _, el in ipairs(obj:query_selector("h1,p")) do
+ tex.print(el:get_text().."\\par")
+end
+ \end{luacode*}
+\end{framed}
+
+It supports also |XML| namespaces, using \verb_namespace|element_ syntax.
+
+\subsection{Element traversing}
+
+\subsubsection{The \texttt{DOM\_Object:traverse\_elements} method}
+
+It may be useful to traverse over all elements and apply a function on all of them.
+
+\begin{verbatim}
+obj:traverse_elements(function(node)
+ print(node:get_text())
+end)
+\end{verbatim}
+
+\begin{framed}
+ \begin{luacode*}
+obj:traverse_elements(function(node)
+ tex.print(node:get_text().."\\par")
+end)
+ \end{luacode*}
+\end{framed}
+
+The \verb|get_text| method gets text from all children elements, so the first
+line shows all text contained in the \verb|<html>| element, the second one in
+\verb|<head>| element and so on.
+
+\subsection{DOM modifications}
+
+It is possible to add new elements, text nodes, or to remove them.
+
+\begin{verbatim}
+local headers = obj:query_selector("h1")
+for _, header in ipairs(headers) do
+ header:remove_node()
+end
+-- query selector returns array, we must retrieve the first element
+-- to get the actual body element
+local body = obj:query_selector("body")[1]
+local paragraph = body:create_element("p", {})
+body:add_child_node(paragraph)
+paragraph:add_child_node(paragraph:create_text_node("This is a second paragraph"))
+
+for _, el in ipairs(body:get_children()) do
+ if el:is_element() then
+ print(el:get_element_name().. ": ".. el:get_text())
+ end
+end
+\end{verbatim}
+
+In this example, \verb|<h1>| element is being removed from the sample document, and new
+paragraph is added. Two paragraphs should be shown in the output:
+
+\begin{framed}
+ \begin{luacode*}
+local headers = obj:query_selector("h1")
+-- query selector returns array, we must retrieve the first element
+-- to get the actual body element
+local body = obj:query_selector("body")[1]
+local oldbody = body:copy_node()
+for _, header in ipairs(headers) do
+ header:remove_node()
+end
+local paragraph = body:create_element("p", {})
+body:add_child_node(paragraph)
+paragraph:add_child_node(paragraph:create_text_node("This is a second paragraph"))
+
+for _, el in ipairs(body:get_children()) do
+if el:is_element() then
+ tex.print(el:get_element_name().. ": ".. el:get_text() .. "\\par")
+end
+end
+
+body:replace_node(oldbody)
+ \end{luacode*}
+\end{framed}
+
+
+\section{The \texttt{CssQuery} library}
+
+This library serves mainly as a support for the
+\texttt{DOM\_Object:query\_selector} function. It also supports adding
+information to the DOM tree.
+
+\subsection{Example usage}
+
+\begin{verbatim}
+local cssobj = require "luaxml-cssquery"
+local domobj = require "luaxml-domobject"
+
+local xmltext = [[
+<html>
+<body>
+<h1>Header</h1>
+<p>Some text, <i>italics</i></p>
+</body>
+</html>
+]]
+
+local dom = domobj.parse(xmltext)
+local css = cssobj()
+
+css:add_selector("h1", function(obj)
+ print("header found: " .. obj:get_text())
+end)
+
+css:add_selector("p", function(obj)
+ print("paragraph found: " .. obj:get_text())
+end)
+
+css:add_selector("i", function(obj)
+ print("found italics: " .. obj:get_text())
+end)
+
+dom:traverse_elements(function(el)
+ -- find selectors that match the current element
+ local querylist = css:match_querylist(el)
+ -- add templates to the element
+ css:apply_querylist(el,querylist)
+end)
+\end{verbatim}
+
+\begin{framed}
+ \begin{luacode*}
+local cssobj = require "luaxml-cssquery"
+local domobj = require "luaxml-domobject"
+local print = function(s) tex.print(s .. "\\par") end
+
+local xmltext = [[
+<html>
+<body>
+<h1>Header</h1>
+<p>Some text, <i>italics</i></p>
+</body>
+</html>
+]]
+
+local dom = domobj.parse(xmltext)
+local css = cssobj()
+
+css:add_selector("h1", function(obj)
+ print("header found: " .. obj:get_text())
+end)
+
+css:add_selector("p", function(obj)
+ print("paragraph found: " .. obj:get_text())
+end)
+
+css:add_selector("i", function(obj)
+ print("found italics: " .. obj:get_text())
+end)
+
+dom:traverse_elements(function(el)
+ -- find selectors that match the current element
+ local querylist = css:match_querylist(el)
+ -- add templates to the element
+ css:apply_querylist(el,querylist)
+end)
+ \end{luacode*}
+\end{framed}
+
+More complete example may be found in the \texttt{examples} directory in the
+\texttt{LuaXML} source code
+repository\footnote{\url{https://github.com/michal-h21/LuaXML/blob/master/examples/xmltotex.lua}}.
+
+\section{The API documentation}
+
+\input{doc/api.tex}
+
+\section{Low-level functions usage}
+
+% The processing is done with several handlers, their usage will be shown in the
+% following section. Full description of handlers is given in the original
+% documentation in section \ref{sec:handlers}.
+
+% \subsection{Usage examples}
+
+The original |LuaXML| library provides some low-level functions for |XML| handling.
+First of all, we need to load the libraries:
+
+\begin{verbatim}
+xml = require('luaxml-mod-xml')
+handler = require('luaxml-mod-handler')
+\end{verbatim}
+
+
+The |luaxml-mod-xml| file contains the xml parser and also the serializer. In
+|luaxml-mod-handler|, various handlers for dealing with xml data are defined.
+Handlers transforms the |xml| file to data structures which can be handled from
+the Lua code. More information about handlers can be found in the original
+documentation, section \ref{sec:handlers}.
+
+\subsection{The simpleTreeHandler}
+\begin{verbatim}
+sample = [[
+<a>
+ <d>hello</d>
+ <b>world.</b>
+ <b at="Hi">another</b>
+</a>]]
+treehandler = handler.simpleTreeHandler()
+x = xml.xmlParser(treehandler)
+x:parse(sample)
+\end{verbatim}
+
+You have to create handler object, using |handler.simpleTreeHandler()| and xml
+parser object using |xml.xmlParser(handler object)|. |simpleTreehandler|
+creates simple table hierarchy, with top root node in |treehandler.root|
+
+\begin{verbatim}
+-- pretty printing function
+function printable(tb, level)
+ level = level or 1
+ local spaces = string.rep(' ', level*2)
+ for k,v in pairs(tb) do
+ if type(v) ~= "table" then
+ print(spaces .. k..'='..v)
+ else
+ print(spaces .. k)
+ level = level + 1
+ printable(v, level)
+ end
+ end
+end
+
+-- print table
+printable(treehandler.root)
+-- print xml serialization of table
+print(xml.serialize(treehandler.root))
+-- direct access to the element
+print(treehandler.root["a"]["b"][1])
+\end{verbatim}
+
+This code produces the following output:
+
+\begin{verbatim}
+ output:
+ a
+ d=hello
+ b
+ 1=world.
+ 2
+ 1=another
+ _attr
+ at=Hi
+ <?xml version="1.0" encoding="UTF-8"?>
+ <a>
+ <d>hello</d>
+ <b>world.</b>
+ <b at="Hi">
+ another
+ </b>
+ </a>
+
+ world.
+\end{verbatim}
+
+First part is pretty-printed dump of Lua table structure contained in the handler, the second
+part is |xml| serialized from that table and the last part demonstrates direct access to particular
+elements.
+
+Note that |simpleTreeHandler| creates tables that can be easily accessed using
+standard lua functions, but if the xml document is of mixed-content type\footnote{%
+This means that element may contain both children elements and text.}:
+
+\begin{verbatim}
+<a>hello
+ <b>world</b>
+</a>
+\end{verbatim}
+
+\noindent then it produces wrong results. It is useful mostly for data |xml| files, not for
+text formats like |xhtml|.
+
+\subsection{The domHandler}
+
+% For complex xml documents with mixed content, |domHandler| is capable of representing any valid XML document:
+For complex xml documents, it is best to use the |domHandler|, which creates object which contains all information
+from the |xml| document.
+
+\begin{verbatim}
+-- file dom-sample.lua
+-- next line enables scripts called with texlua to use luatex libraries
+--kpse.set_program_name("luatex")
+function traverseDom(current,level)
+ local level = level or 0
+ local spaces = string.rep(" ",level)
+ local root= current or current.root
+ local name = root._name or "unnamed"
+ local xtype = root._type or "untyped"
+ local attributes = root._attr or {}
+ if xtype == "TEXT" then
+ print(spaces .."TEXT : " .. root._text)
+ else
+ print(spaces .. xtype .. " : " .. name)
+ end
+ for k, v in pairs(attributes) do
+ print(spaces .. " ".. k.."="..v)
+ end
+ local children = root._children or {}
+ for _, child in ipairs(children) do
+ traverseDom(child, level + 1)
+ end
+end
+
+local xml = require('luaxml-mod-xml')
+local handler = require('luaxml-mod-handler')
+local x = '<p>hello <a href="http://world.com/">world</a>, how are you?</p>'
+local domHandler = handler.domHandler()
+local parser = xml.xmlParser(domHandler)
+parser:parse(x)
+traverseDom(domHandler.root)
+\end{verbatim}
+
+The ROOT element is stored in |domHandler.root| table, it's child nodes are stored in |_children|
+tables. Node type is saved in |_type| field, if the node type is |ELEMENT|, then |_name| field contains
+element name, |_attr| table contains element attributes. |TEXT| node contains text content in |_text|
+field.
+
+The previous code produces following output in the terminal: % after command
+% |texlua dom-sample.lua| running:
+
+\begin{verbatim}
+ROOT : unnamed
+ ELEMENT : p
+ TEXT : hello
+ ELEMENT : a
+ href=http://world.com/
+ TEXT : world
+ TEXT : , how are you?
+\end{verbatim}
+
+% With \verb|domHandler|, you can process documents with mixed content, like
+% \verb|xhtml|, so it is a most powerful handler.
+
+
+\clearpage
+\part{Original \texttt{LuaXML} documentation by Paul Chakravarti}
+\medskip
+
+\noindent This document was created automatically from the original source code comments using Pandoc\footnote{\url{http://johnmacfarlane.net/pandoc/}}
+
+\section{Overview}
+
+
+This module provides a non-validating XML stream parser in Lua.
+\section{Features}
+
+\begin{itemize}
+\item
+ Tokenises well-formed XML (relatively robustly)
+\item
+ Flexible handler based event api (see below)
+\item
+ Parses all XML Infoset elements - ie.
+ \begin{itemize}
+ \item
+ Tags
+ \item
+ Text
+ \item
+ Comments
+ \item
+ CDATA
+ \item
+ XML Decl
+ \item
+ Processing Instructions
+ \item
+ DOCTYPE declarations
+ \end{itemize}
+\item
+ Provides limited well-formedness checking (checks for basic syntax \&
+ balanced tags only)
+\item
+ Flexible whitespace handling (selectable)
+\item
+ Entity Handling (selectable)
+\end{itemize}
+\section{Limitations}
+
+\begin{itemize}
+\item
+ Non-validating
+\item
+ No charset handling
+\item
+ No namespace support
+\item
+ Shallow well-formedness checking only (fails to detect most semantic
+ errors)
+\end{itemize}
+\section{API}
+
+The parser provides a partially object-oriented API with functionality
+split into tokeniser and hanlder components.
+
+The handler instance is passed to the tokeniser and receives callbacks
+for each XML element processed (if a suitable handler function is
+defined). The API is conceptually similar to the SAX API but implemented
+differently.
+
+The following events are generated by the tokeniser
+
+\begin{verbatim}
+handler:starttag - Start Tag
+handler:endtag - End Tag
+handler:text - Text
+handler:decl - XML Declaration
+handler:pi - Processing Instruction
+handler:comment - Comment
+handler:dtd - DOCTYPE definition
+handler:cdata - CDATA
+\end{verbatim}
+The function prototype for all the callback functions is
+
+\begin{verbatim}
+callback(val,attrs,start,end)
+\end{verbatim}
+where attrs is a table and val/attrs are overloaded for specific
+callbacks - ie.
+
+\begin{tabular}{llp{5cm}}
+Callback & val & attrs (table)\\
+\hline
+starttag & name & |{ attributes (name=val).. }|\\
+endtag & name & nil\\
+text & |<text>| & nil\\
+cdata & |<text> | & nil\\
+decl & "xml" & |{ attributes (name=val).. }|\\
+pi & pi name & \begin{verbatim}{ attributes (if present)..
+ _text = <PI Text>
+}\end{verbatim}\\
+comment & |<text>| & nil\\
+dtd & root element & \begin{verbatim}{ _root = <Root Element>,
+ _type = SYSTEM|PUBLIC,
+ _name = <name>,
+ _uri = <uri>,
+ _internal = <internal dtd>
+}\end{verbatim}\\
+\end{tabular}
+
+(starttag \& endtag provide the character positions of the start/end of the
+element)
+
+XML data is passed to the parser instance through the `parse' method
+(Note: must be passed as single string currently)
+
+\section{Options}
+
+Parser options are controlled through the `self.options' table.
+Available options are -
+
+\begin{itemize}
+\item
+ stripWS
+
+ Strip non-significant whitespace (leading/trailing) and do not
+ generate events for empty text elements
+\item
+ expandEntities
+
+ Expand entities (standard entities + single char numeric entities only
+ currently - could be extended at runtime if suitable DTD parser added
+ elements to table (see obj.\_ENTITIES). May also be possible to expand
+ multibyre entities for UTF--8 only
+\item
+ errorHandler
+
+ Custom error handler function
+\end{itemize}
+NOTE: Boolean options must be set to `nil' not `0'
+
+\section{Usage}
+
+Create a handler instance -
+
+\begin{verbatim}
+h = { starttag = function(t,a,s,e) .... end,
+ endtag = function(t,a,s,e) .... end,
+ text = function(t,a,s,e) .... end,
+ cdata = text }
+\end{verbatim}
+(or use predefined handler - see luaxml-mod-handler.lua)
+
+Create parser instance -
+
+\begin{verbatim}
+p = xmlParser(h)
+\end{verbatim}
+Set options -
+
+\begin{verbatim}
+p.options.xxxx = nil
+\end{verbatim}
+Parse XML data -
+
+\begin{verbatim}
+xmlParser:parse("<?xml... ")
+\end{verbatim}
+\section{Handlers}\label{sec:handlers}
+
+\subsection{Overview}
+
+Standard XML event handler(s) for XML parser module (luaxml-mod-xml.lua)
+
+\subsection{Features}
+
+\begin{verbatim}
+printHandler - Generate XML event trace
+domHandler - Generate DOM-like node tree
+simpleTreeHandler - Generate 'simple' node tree
+simpleTeXhandler - SAX like handler with support for CSS selectros
+\end{verbatim}
+\subsection{API}
+
+Must be called as handler function from xmlParser and implement XML
+event callbacks (see xmlParser.lua for callback API definition)
+
+\subsubsection{printHandler}
+
+printHandler prints event trace for debugging
+
+\subsubsection{domHandler}
+
+domHandler generates a DOM-like node tree structure with
+a single ROOT node parent - each node is a table comprising
+fields below.
+
+\begin{verbatim}
+node = { _name = <Element Name>,
+ _type = ROOT|ELEMENT|TEXT|COMMENT|PI|DECL|DTD,
+ _attr = { Node attributes - see callback API },
+ _parent = <Parent Node>
+ _children = { List of child nodes - ROOT/NODE only }
+ }
+
+\end{verbatim}
+\subsubsection{simpleTreeHandler}
+
+simpleTreeHandler is a simplified handler which attempts to generate a
+more `natural' table based structure which supports many common XML
+formats.
+
+The XML tree structure is mapped directly into a recursive table
+structure with node names as keys and child elements as either a table
+of values or directly as a string value for text. Where there is only a
+single child element this is inserted as a named key - if there are
+multiple elements these are inserted as a vector (in some cases it may
+be preferable to always insert elements as a vector which can be
+specified on a per element basis in the options). Attributes are
+inserted as a child element with a key of `\_attr'.
+
+Only Tag/Text \& CDATA elements are processed - all others are ignored.
+
+This format has some limitations - primarily
+
+\begin{itemize}
+\item Mixed-Content behaves unpredictably - the relationship between text
+ elements and embedded tags is lost and multiple levels of mixed
+ content does not work
+\item If a leaf element has both a text element and attributes then the text
+ must be accessed through a vector (to provide a container for the
+ attribute)
+\end{itemize}
+In general however this format is relatively useful.
+
+
+\subsection{Options}
+
+\begin{verbatim}
+simpleTreeHandler.options.noReduce = { <tag> = bool,.. }
+
+ - Nodes not to reduce children vector even if only
+ one child
+
+domHandler.options.(comment|pi|dtd|decl)Node = bool
+
+ - Include/exclude given node types
+\end{verbatim}
+\subsection{Usage}
+
+Pased as delegate in xmlParser constructor and called as callback by
+xmlParser:parse(xml) method.
+
+\section{History}
+
+This library is fork of LuaXML library originaly created by Paul
+Chakravarti. Some files not needed for use with luatex were droped from the distribution.
+Documentation was converted from original comments in the source code.
+
+\section{License}
+
+This code is freely distributable under the terms of the Lua license
+(\url{http://www.lua.org/copyright.html})
+\end{document}
diff --git a/macros/luatex/generic/nodetree/README.md b/macros/luatex/generic/nodetree/README.md
new file mode 100644
index 0000000000..2b92a67fa2
--- /dev/null
+++ b/macros/luatex/generic/nodetree/README.md
@@ -0,0 +1,104 @@
+
+![nodetree](https://raw.githubusercontent.com/Josef-Friedrich/nodetree/master/graphics/packagename.png)
+
+# Abstract
+
+`nodetree` is a development package that visualizes the structure of
+node lists. `nodetree` shows its debug informations in the consoles’
+output when you compile a LuaTeX file. It uses a similar visual
+representation for node lists as the UNIX `tree` command uses for a
+folder structure.
+
+Node lists are the main building blocks of each document generated by
+the TeX engine LuaTeX. The package `nodetree` doesn‘t change
+the rendered document. The tree view can only be seen when using a
+terminal to generate the document.
+
+`nodetree` is inspired by a
+[gist from Patrick Gundlach](https://gist.github.com/pgundlach/556247).
+
+# License
+
+Copyright (C) 2016 by Josef Friedrich <josef@friedrich.rocks>
+------------------------------------------------------------------------
+This work may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3 of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+# CTAN
+
+Since July 2016 the cloze package is included in the Comprehensive TeX
+Archive Network (CTAN).
+
+* TeX archive: http://mirror.ctan.org/tex-archive/macros/luatex/generic/nodetree
+* Package page: http://www.ctan.org/pkg/nodetree
+
+# Repository
+
+https://github.com/Josef-Friedrich/nodetree
+
+# Installation
+
+Get source:
+
+ git clone git@github.com:Josef-Friedrich/nodetree.git
+ cd nodetree
+
+Compile:
+
+ make
+
+or manually:
+
+ luatex nodetree.ins
+ lualatex nodetree.dtx
+ makeindex -s gglo.ist -o nodetree.gls nodetree.glo
+ makeindex -s gind.ist -o nodetree.ind nodetree.idx
+ lualatex nodetree.dtx
+
+# Examples
+
+## The node list of the package name
+
+```latex
+\documentclass{article}
+\usepackage{nodetree}
+\begin{document}
+nodetree
+\end{document}
+```
+
+![nodetree](graphics/packagename.png)
+
+## The node list of a mathematical formula
+
+```latex
+\documentclass{article}
+\usepackage[callback={mhlist}]{nodetree}
+\begin{document}
+\[\left(a\right)\left[\frac{b}{a}\right]=a\,\]
+\end{document}
+```
+
+![nodetree](https://raw.githubusercontent.com/Josef-Friedrich/nodetree/master/graphics/math.png)
+
+## The node list of the word 'Office'
+
+The characters 'ffi' are deeply nested in a discretionary node.
+
+```latex
+\documentclass{article}
+\usepackage{nodetree}
+\begin{document}
+Office
+\end{document}
+```
+
+![nodetree](https://raw.githubusercontent.com/Josef-Friedrich/nodetree/master/graphics/ligatures.png)
+
diff --git a/macros/luatex/generic/nodetree/nodetree.dtx b/macros/luatex/generic/nodetree/nodetree.dtx
new file mode 100644
index 0000000000..24416e17ce
--- /dev/null
+++ b/macros/luatex/generic/nodetree/nodetree.dtx
@@ -0,0 +1,2010 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2016 by Josef Friedrich <josef@friedrich.rocks>
+% ----------------------------------------------------------------------
+% This work may be distributed and/or modified under the conditions of
+% the LaTeX Project Public License, either version 1.3 of this license
+% or (at your option) any later version. The latest version of this
+% license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Josef Friedrich.
+%
+% This work consists of the files nodetree.dtx and nodetree.ins
+% and the derived filebase nodetree.sty and nodetree.lua.
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{nodetree.dtx}
+%</driver>
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{nodetree}
+%<*package>
+ [2016/07/18 v1.2 Visualize node lists in a tree view]
+%</package>
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{paralist,fontspec,graphicx,fancyvrb}
+\usepackage[
+ colorlinks=true,
+ linkcolor=red,
+ filecolor=red,
+ urlcolor=red,
+]{hyperref}
+%\usepackage{nodetree}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+
+\setmonofont{DejaVu Sans Mono}
+
+\def\nodetreelua#1{\texttt{\scantokens{\catcode`\_=12\relax#1}}}
+
+\def\secref#1{(\rightarrow\ \ref{#1})}
+
+\newcommand{\tmpgraphics}[1]{
+ \noindent
+ \includegraphics[scale=0.4]{graphics/#1}
+}
+
+\DefineVerbatimEnvironment{code}{Verbatim}
+{
+ frame=single,
+ fontsize=\footnotesize,
+}
+
+\begin{document}
+
+\providecommand*{\url}{\texttt}
+\GetFileInfo{nodetree.dtx}
+\title{The \textsf{nodetree} package}
+\author{%
+ Josef Friedrich\\%
+ \url{josef@friedrich.rocks}\\%
+ \href{https://github.com/Josef-Friedrich/nodetree}{github.com/Josef-Friedrich/nodetree}%
+}
+\date{\fileversion~from \filedate}
+
+\maketitle
+
+\noindent
+\includegraphics[width=\linewidth]{graphics/packagename}
+
+\newpage
+
+\tableofcontents
+
+\newpage
+
+%-----------------------------------------------------------------------
+% Abstract
+%-----------------------------------------------------------------------
+
+\section{Abstract}
+
+|nodetree| is a development package that visualizes the structure of
+node lists. |nodetree| shows its debug informations in the consoles’
+output when you compile a Lua\TeX{} file. It uses a similar visual
+representation for node lists as the UNIX |tree| command uses for a
+folder structure.
+
+Node lists are the main building blocks of each document generated by
+the \TeX{} engine \emph{Lua\TeX}. The package |nodetree| doesn‘t change
+the rendered document. The tree view can only be seen when using a
+terminal to generate the document.
+
+|nodetree| is inspired by a
+\href{https://gist.github.com/pgundlach/556247}
+{gist from Patrick Gundlach}.
+
+%-----------------------------------------------------------------------
+% Usage
+%-----------------------------------------------------------------------
+
+\section{Usage}
+
+The package |nodetree| can be used both with Lua\TeX{} and Lua\LaTeX{}.
+You have to use both engines in a text console. Run for example
+|luatex luatex-test.tex| to list the nodes using Lua\TeX{}.
+
+\begin{code}
+\input{nodetree.tex}
+\nodetreeregister{postline}
+
+Lorem ipsum dolor.
+\bye
+\end{code}
+
+Or run |lualatex lualatex-test.tex| to show a node tree using
+Lua\LaTeX{}. In Lua\LaTeX{} you can omit |\nodetreeregister{postline}|.
+|\usepackage{nodetree}| registers automatically the
+|post_linebreak_filter|. If you don’t want debug the
+|post_linebreak_filter| use |\nodetreeunregister{postline}|.
+
+\begin{code}
+\documentclass{article}
+\usepackage{nodetree}
+
+\begin{document}
+Lorem ipsum dolor.
+\end{document}
+\end{code}
+
+%%
+% inside Lua code
+%%
+
+\subsection{Debug nodes inside Lua code}
+
+Use the Lua function |nodetree.analyze(head)| to debug nodes inside your
+Lua code. The following code snippet demonstrates the usage in Lua\TeX{}.
+|head| is the current node.
+
+\begin{code}
+\input{nodetree.tex}
+
+\directlua{
+ local test = function (head)
+ nodetree.analyze(head)
+ end
+ callback.register('post_linebreak_filter', test)
+}
+
+Lorem ipsum dolor.
+\bye
+\end{code}
+
+This example illustrates how the function has to be applied in
+Lua\LaTeX{}.
+
+\begin{code}
+\documentclass{article}
+\usepackage{nodetree}
+
+\begin{document}
+
+\directlua{
+ local test = function (head)
+ nodetree.analyze(head)
+ end
+ luatexbase.add_to_callback('post_linebreak_filter', test, 'test')
+}
+
+Lorem ipsum dolor.
+\end{document}
+\end{code}
+
+%-----------------------------------------------------------------------
+% Macros
+%-----------------------------------------------------------------------
+
+\section{Macros}
+
+%%
+% \nodetreeregister
+%%
+
+\subsection{\cmd{\nodetreeregister}}
+
+\DescribeMacro{\nodetreeregister}
+\cmd{\nodetreeregister}\marg{callbacks}: The argument \marg{callbacks}
+takes a comma separated list of callback aliases as described in
+\secref{sec:option-callback}.
+
+%%
+% \nodetreeunregister
+%%
+
+\subsection{\cmd{\nodetreeunregister}}
+
+\DescribeMacro{\nodetreeunregister}
+\cmd{\nodetreeunregister}\marg{callbacks}: The argument \marg{callbacks}
+takes a comma separated list of callback aliases as described in
+\secref{sec:option-callback}.
+
+%%
+% \nodetreeoption
+%%
+
+\subsection{\cmd{\nodetreeoption}}
+
+\DescribeMacro{\nodetreeoption}
+\cmd{\nodetreeoption}\oarg{option}\marg{value}: \secref{sec:options}
+This macro sets the option \oarg{option} to the value \marg{value}.
+
+%%
+% \nodetreeset
+%%
+
+\subsection{\cmd{\nodetreeset}}
+
+\DescribeMacro{\nodetreeset}
+\cmd{\nodetreeset}\marg{kv-options}:
+This macro can only be used in Lua\LaTeX{}. \marg{kv-options} are key
+value pairs.
+
+\begin{code}
+\nodetreeset{color=no,callbacks={hpack,vpack},verbosity=2}
+\end{code}
+
+%-----------------------------------------------------------------------
+% Options
+%-----------------------------------------------------------------------
+
+\section{Options}
+\label{sec:options}
+
+%%
+% callback
+%%
+
+\subsection{Option \texttt{callback}}
+\label{sec:option-callback}
+
+The option |callback| is the most important setting of the package. You
+have to specify one alias to select the |callback|. Because of the
+underscores the callback name contains it can not set by its technical
+name (\rightarrow{} Figure \ref{fig:callback}).
+
+This macros process callback options:
+\cmd{\nodetreeregister}\marg{callbacks},
+\cmd{\nodetreeunregister}\marg{callbacks},
+\cmd{\nodetreeset}\marg{callback=<callbacks>} and
+\cmd{\usepackage}\oarg{callback=<callbacks>}\marg{nodetree}.
+
+Use commas to specify mulitple callbacks. Avoid using whitespaces:
+
+\begin{code}
+\nodetreeregister{preline,line,postline}
+\end{code}
+
+Wrap your callback aliases in curly braces for the macro |\nodetreeset|:
+
+\begin{code}
+\nodetreeset{callback={preline,line,postline}}
+\end{code}
+
+The same applies for the macro |\usepackage|:
+
+\begin{code}
+\usepackage{callback={preline,line,postline}}
+\end{code}
+
+%%
+% Tabular callbacks
+%%
+
+\newcommand{\nodetreecallback}[3]{
+ \nodetreelua{#1} & \nodetreelua{#2} & \nodetreelua{#3} \\
+}
+
+\begin{figure}
+
+\noindent
+\begin{tabular}{lll}
+\textbf{Alias (short)} & \textbf{Alias (longer)} & \textbf{Callback} \\
+\nodetreecallback{contribute}{contributefilter}{contribute_filter}
+\nodetreecallback{buildpage}{buildpagefilter}{buildpage_filter}
+\nodetreecallback{preline}{prelinebreakfilter}{pre_linebreak_filter}
+\nodetreecallback{line}{linebreakfilter}{linebreak_filter}
+\nodetreecallback{append}{appendtovlistfilter}{append_to_vlist_filter}
+\nodetreecallback{postline}{postlinebreakfilter}{post_linebreak_filter}
+\nodetreecallback{hpack}{hpackfilter}{hpack_filter}
+\nodetreecallback{vpack}{vpackfilter}{vpack_filter}
+\nodetreecallback{hpackq}{hpackquality}{hpack_quality}
+\nodetreecallback{vpackq}{vpackquality}{vpack_quality}
+\nodetreecallback{process}{processrule}{process_rule}
+\nodetreecallback{preout}{preoutputfilter}{pre_output_filter}
+\nodetreecallback{hyph}{hyphenate}{hyphenate}
+\nodetreecallback{liga}{ligaturing}{ligaturing}
+\nodetreecallback{kern}{kerning}{kerning}
+\nodetreecallback{insert}{insertlocalpar}{insert_local_par}
+\nodetreecallback{mhlist}{mlisttohlist}{mlist_to_hlist}
+\end{tabular}
+
+\caption{The callback aliases}
+\label{fig:callback}
+\end{figure}
+
+%%
+% verbosity
+%%
+
+\subsection{Option \texttt{verbosity}}
+
+Higher integer values result in a more verbose output. The default value
+for this options is |1|. At the moment only verbosity level |2| is
+implemented.
+
+%%
+% color
+%%
+
+\subsection{Option \texttt{color}}
+
+The default option for |color| is |colored|. Use any other string (for
+example |none| or |no|) to disable the colored terminal output of the
+package.
+
+\begin{code}
+\usepackage[color=no]{nodetree}
+\end{code}
+
+%%
+% unit
+%%
+
+\subsection{Option \texttt{unit}}
+
+The option |unit| sets the length unit to display all length values of
+the nodes. The default option for |unit| is |pt|. See figure
+\ref{fig:fixed-units} and \ref{fig:relative-units} for possible values.
+
+\begin{figure}
+\begin{tabular}{lp{10cm}}
+\textbf{Unit} &
+\textbf{Description} \\
+
+pt &
+Point 1/72.27 inch. The conversion to metric units, to two decimal
+places, is 1 point = 2.85 mm = 28.45 cm. \\
+
+pc &
+Pica, 12 pt \\
+
+in &
+Inch, 72.27 pt \\
+
+bp &
+Big point, 1/72 inch. This length is the definition of a point in
+PostScript and many desktop publishing systems. \\
+
+cm &
+Centimeter \\
+
+mm &
+Millimeter \\
+
+dd &
+Didot point, 1.07 pt \\
+
+cc &
+Cicero, 12 dd \\
+
+sp &
+Scaled point, 1/65536 pt \\
+\end{tabular}
+\caption{Fixed units}
+\label{fig:fixed-units}
+\end{figure}
+
+\begin{figure}
+\begin{tabular}{lp{10cm}}
+\textbf{Unit} &
+\textbf{Description} \\
+
+ex &
+x-height of the current font \\
+
+em &
+Width of the capital letter M \\
+\end{tabular}
+\caption{Relative units}
+\label{fig:relative-units}
+\end{figure}
+
+%%
+% decimalplaces
+%%
+
+\subsection{Option \texttt{decimalplaces}}
+
+The options |decimalplaces| sets the number of decimal places for some
+node fields.
+
+\begin{code}
+\nodetreeoption[decimalplaces]{4}
+\end{code}
+
+gets
+
+\begin{code}
+├─GLYPH char: "a"; width: 5pt; height: 4.3055pt;
+\end{code}
+
+If |decimalplaces| is set to |0| only integer values are shown.
+
+\begin{code}
+├─GLYPH char: "a"; width: 5pt; height: 4pt;
+\end{code}
+
+%-----------------------------------------------------------------------
+% Visual tree structure
+%-----------------------------------------------------------------------
+
+\section{Visual tree structure}
+
+%%
+% Two different connections
+%%
+
+\subsection{Two different connections}
+
+Nodes in Lua\TeX{} are connected. The |nodetree| package distinguishs
+between the |list| and |field| connections.
+
+\begin{itemize}
+ \item |list|: Nodes, which are double connected by |next| and
+ |previous| fields.
+ \item |field|: Connections to nodes by other fields than |next| and
+ |previous| fields, e. g. |head|, |pre|.
+\end{itemize}
+
+%%
+% Unicode characters
+%%
+
+\subsection{Unicode characters to show the tree view}
+
+\renewcommand{\arraystretch}{1.5}
+
+The package |nodetree| uses the unicode box drawing symbols. Your
+default terminal font should contain this characters to obtain the tree
+view. Eight box drawing characters are necessary.
+
+\noindent
+\begin{tabular}{lcl}
+\textbf{Code} & \textbf{Character} & \textbf{Name} \\
+U+2500 & |─| & BOX DRAWINGS LIGHT HORIZONTAL \\
+U+2502 & |│| & BOX DRAWINGS LIGHT VERTICAL \\
+U+2514 & |â””| & BOX DRAWINGS LIGHT UP AND RIGHT \\
+U+251C & |├| & BOX DRAWINGS LIGHT VERTICAL AND RIGHT \\
+U+2550 & |â•| & BOX DRAWINGS DOUBLE HORIZONTAL \\
+U+2551 & |â•‘| & BOX DRAWINGS DOUBLE VERTICAL \\
+U+255A & |â•š| & BOX DRAWINGS DOUBLE UP AND RIGHT \\
+U+2560 & |â• | & BOX DRAWINGS DOUBLE VERTICAL AND RIGHT \\
+\end{tabular}
+
+For |list| connections \emph{light} characters are shown.
+
+\begin{code}
+│ │
+│ ├─list1
+│ └─list2
+└─list3
+\end{code}
+
+|field| connections are visialized by \emph{Double} characters.
+
+\begin{code}
+â•‘ â•‘
+â•‘ â• â•field1
+â•‘ â•šâ•field2
+â•šâ•field3
+\end{code}
+
+%-----------------------------------------------------------------------
+% Examples
+%-----------------------------------------------------------------------
+
+\newpage
+
+\section{Examples}
+
+%%
+% packagename
+%%
+
+\subsection{The node list of the package name}
+
+\begin{code}
+\documentclass{article}
+\usepackage{nodetree}
+\begin{document}
+nodetree
+\end{document}
+\end{code}
+
+\tmpgraphics{packagename}
+
+%%
+% math
+%%
+
+\newpage
+
+\subsection{The node list of a mathematical formula}
+
+\begin{code}
+\documentclass{article}
+\usepackage[callback={mhlist}]{nodetree}
+\begin{document}
+\[\left(a\right)\left[\frac{b}{a}\right]=a\,\]
+\end{document}
+\end{code}
+
+\tmpgraphics{math}
+
+%%
+% ligatures
+%%
+
+\newpage
+
+\subsection{The node list of the word \emph{Office}}
+
+The characters \emph{ffi} are deeply nested in a discretionary node.
+
+\begin{code}
+\documentclass{article}
+\usepackage{nodetree}
+\begin{document}
+Office
+\end{document}
+\end{code}
+
+\tmpgraphics{ligatures}
+
+%-----------------------------------------------------------------------
+% Index
+%-----------------------------------------------------------------------
+
+ \DocInput{nodetree.dtx}
+ \pagebreak
+ \PrintChanges
+ \pagebreak
+ \PrintIndex
+\end{document}
+%</driver>
+%<*readme>
+
+![nodetree](https://raw.githubusercontent.com/Josef-Friedrich/nodetree/master/graphics/packagename.png)
+
+# Abstract
+
+`nodetree` is a development package that visualizes the structure of
+node lists. `nodetree` shows its debug informations in the consoles’
+output when you compile a LuaTeX file. It uses a similar visual
+representation for node lists as the UNIX `tree` command uses for a
+folder structure.
+
+Node lists are the main building blocks of each document generated by
+the TeX engine LuaTeX. The package `nodetree` doesn‘t change
+the rendered document. The tree view can only be seen when using a
+terminal to generate the document.
+
+`nodetree` is inspired by a
+[gist from Patrick Gundlach](https://gist.github.com/pgundlach/556247).
+
+# License
+
+Copyright (C) 2016 by Josef Friedrich <josef@friedrich.rocks>
+------------------------------------------------------------------------
+This work may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3 of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+# CTAN
+
+Since July 2016 the cloze package is included in the Comprehensive TeX
+Archive Network (CTAN).
+
+* TeX archive: http://mirror.ctan.org/tex-archive/macros/luatex/generic/nodetree
+* Package page: http://www.ctan.org/pkg/nodetree
+
+# Repository
+
+https://github.com/Josef-Friedrich/nodetree
+
+# Installation
+
+Get source:
+
+ git clone git@github.com:Josef-Friedrich/nodetree.git
+ cd nodetree
+
+Compile:
+
+ make
+
+or manually:
+
+ luatex nodetree.ins
+ lualatex nodetree.dtx
+ makeindex -s gglo.ist -o nodetree.gls nodetree.glo
+ makeindex -s gind.ist -o nodetree.ind nodetree.idx
+ lualatex nodetree.dtx
+
+# Examples
+
+## The node list of the package name
+
+```latex
+\documentclass{article}
+\usepackage{nodetree}
+\begin{document}
+nodetree
+\end{document}
+```
+
+![nodetree](graphics/packagename.png)
+
+## The node list of a mathematical formula
+
+```latex
+\documentclass{article}
+\usepackage[callback={mhlist}]{nodetree}
+\begin{document}
+\[\left(a\right)\left[\frac{b}{a}\right]=a\,\]
+\end{document}
+```
+
+![nodetree](https://raw.githubusercontent.com/Josef-Friedrich/nodetree/master/graphics/math.png)
+
+## The node list of the word 'Office'
+
+The characters 'ffi' are deeply nested in a discretionary node.
+
+```latex
+\documentclass{article}
+\usepackage{nodetree}
+\begin{document}
+Office
+\end{document}
+```
+
+![nodetree](https://raw.githubusercontent.com/Josef-Friedrich/nodetree/master/graphics/ligatures.png)
+
+%</readme>
+% \fi
+%
+% \CheckSum{0}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \changes{v0.1}{2015/06/16}{Converted to DTX file}
+% \changes{v1.0}{2016/07/07}{Inital release}
+% \changes{v1.1}{2016/07/13}{Fix the registration of same callbacks}
+% \changes{v1.2}{2016/07/18}{Fix difference between README.md in the upload and that from nodetree.dtx}
+%
+% \DoNotIndex{\newcommand,\newenvironment,\def,\directlua}
+%
+% \StopEventually{}
+% \pagebreak
+% \section{Implementation}
+%
+% \iffalse
+%<*tex>
+% \fi
+% \MacroTopsep = 10pt plus 2pt minus 2pt
+% \MacrocodeTopsep = 10pt plus 1.2pt minus 1pt
+% \makeatletter
+% \c@CodelineNo 25 \relax
+% \makeatother
+%
+% \subsection{The file \tt{nodetree.tex}}
+%
+% \begin{macrocode}
+\directlua{
+ nodetree = require('nodetree')
+ nodetree.set_option('engine', 'luatex')
+ nodetree.set_default_options()
+}
+% \end{macrocode}
+%
+% \begin{macro}{\nodetreeoption}
+% \begin{macrocode}
+\def\nodetreeoption[#1]#2{
+ \directlua{
+ nodetree.set_option('#1', '#2')
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\nodetreeregister}
+% \begin{macrocode}
+\def\nodetreeregister#1{
+ \directlua{
+ nodetree.set_option('callback', '#1')
+ nodetree.register_callbacks()
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\nodetreeunregister}
+% \begin{macrocode}
+\def\nodetreeunregister#1{
+ \directlua{
+ nodetree.set_option('callback', '#1')
+ nodetree.unregister_callbacks()
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \iffalse
+%</tex>
+%<*package>
+% \fi
+% \makeatletter
+% \c@CodelineNo 25 \relax
+% \makeatother
+%
+% \subsection{The file \tt{nodetree.sty}}
+%
+% \begin{macrocode}
+\input{nodetree}
+\directlua{
+ nodetree.set_option('engine', 'lualatex')
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\RequirePackage{kvoptions}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\SetupKeyvalOptions{
+ family=NT,
+ prefix=NT@
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareStringOption[term]{channel}
+\define@key{NT}{channel}[]{\nodetreeoption[channel]{#1}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareStringOption[postlinebreak]{callback}
+\define@key{NT}{callback}[]{\nodetreeoption[callback]{#1}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareStringOption[1]{verbosity}
+\define@key{NT}{verbosity}[]{\nodetreeoption[verbosity]{#1}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareStringOption[colored]{color}
+\define@key{NT}{color}[]{\nodetreeoption[color]{#1}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareStringOption[1]{unit}
+\define@key{NT}{unit}[]{\nodetreeoption[unit]{#1}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareStringOption[1]{decimalplaces}
+\define@key{NT}{decimalplaces}[]{\nodetreeoption[decimalplaces]{#1}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ProcessKeyvalOptions*
+\directlua{
+ nodetree.set_default_options()
+ nodetree.register_callbacks()
+}
+% \end{macrocode}
+%
+% \begin{macro}{\nodetreeset}
+% \begin{macrocode}
+\newcommand{\nodetreeset}[1]{\setkeys{nodetree}{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \iffalse
+%</package>
+%<*luamain>
+% \fi
+%
+% \makeatletter
+% \c@CodelineNo 0 \relax
+% \makeatother
+%
+% \subsection{The file \tt{nodetree.lua}}
+%
+% \begin{macrocode}
+local nodex = {}
+% \end{macrocode}
+%
+% \begin{macrocode}
+local tpl = {}
+% \end{macrocode}
+%
+% \begin{macrocode}
+local tree = {}
+% \end{macrocode}
+%
+% Nodes in Lua\TeX{} are connected. The nodetree view distinguishs
+% between the |list| and |field| connections.
+%
+% \begin{itemize}
+% \item |list|: Nodes, which are double connected by |next| and
+% |previous| fields.
+% \item |field|: Connections to nodes by other fields than |next| and
+% |previous| fields, e. g. |head|, |pre|.
+% \end{itemize}
+%
+% The lua table named |tree.state| holds state values for the current
+% tree item.
+%
+% \begin{code}
+% tree.state:
+% - 1:
+% - list: continue
+% - field: stop
+% - 2:
+% - list: continue
+% - field: stop
+% \end{code}
+% \begin{macrocode}
+tree.state = {}
+% \end{macrocode}
+%
+% \begin{macrocode}
+local callbacks = {}
+% \end{macrocode}
+%
+% \begin{macrocode}
+local base = {}
+% \end{macrocode}
+%
+% \begin{macrocode}
+local options = {}
+% \end{macrocode}
+%
+% \subsubsection{nodex --- Extend the node library}
+%
+% Get the node id form, e. g.:
+% \begin{code}
+% <node nil < 172 > nil : hlist 2>
+% \end{code}
+% \begin{macrocode}
+function nodex.node_id(n)
+ return string.gsub(tostring(n), '^<node%s+%S+%s+<%s+(%d+).*', '%1')
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function nodex.subtype(n)
+ local typ = node.type(n.id)
+ local subtypes = {
+% \end{macrocode}
+% \paragraph{hlist (0)}
+% \begin{macrocode}
+ hlist = {
+ [0] = 'unknown',
+ [1] = 'line',
+ [2] = 'box',
+ [3] = 'indent',
+ [4] = 'alignment',
+ [5] = 'cell',
+ [6] = 'equation',
+ [7] = 'equationnumber',
+ },
+% \end{macrocode}
+% \paragraph{vlist (1)}
+% \begin{macrocode}
+ vlist = {
+ [0] = 'unknown',
+ [4] = 'alignment',
+ [5] = 'cell',
+ },
+% \end{macrocode}
+% \paragraph{rule (2)}
+% \begin{macrocode}
+ rule = {
+ [0] = 'unknown',
+ [1] = 'box',
+ [2] = 'image',
+ [3] = 'empty',
+ [4] = 'user',
+ },
+% \end{macrocode}
+%
+% \noindent
+% Nodes without subtypes:
+% \begin{compactitem}
+% \item ins (3)
+% \item mark (4)
+% \end{compactitem}
+% \begin{macrocode}
+% \end{macrocode}
+% \paragraph{adjust (5)}
+% \begin{macrocode}
+ adjust = {
+ [0] = 'normal',
+ [1] = 'pre',
+ },
+% \end{macrocode}
+% \paragraph{boundary (6)}
+% \begin{macrocode}
+ boundary = {
+ [0] = 'cancel',
+ [1] = 'user',
+ [2] = 'protrusion',
+ [3] = 'word',
+ },
+% \end{macrocode}
+% \paragraph{disc (7)}
+% \begin{macrocode}
+ disc = {
+ [0] = 'discretionary',
+ [1] = 'explicit',
+ [2] = 'automatic',
+ [3] = 'regular',
+ [4] = 'first',
+ [5] = 'second',
+ },
+% \end{macrocode}
+%
+% \noindent
+% Nodes without subtypes:
+% \begin{compactitem}
+% \item whatsit (8)
+% \item local\_par (9)
+% \item dir (10)
+% \end{compactitem}
+%
+% \paragraph{math (11)}
+% \begin{macrocode}
+ math = {
+ [0] = 'beginmath',
+ [1] = 'endmath',
+ },
+% \end{macrocode}
+% \paragraph{glue (12)}
+% \begin{macrocode}
+ glue = {
+ [0] = 'userskip',
+ [1] = 'lineskip',
+ [2] = 'baselineskip',
+ [3] = 'parskip',
+ [4] = 'abovedisplayskip',
+ [5] = 'belowdisplayskip',
+ [6] = 'abovedisplayshortskip',
+ [7] = 'belowdisplayshortskip',
+ [8] = 'leftskip',
+ [9] = 'rightskip',
+ [10] = 'topskip',
+ [11] = 'splittopskip',
+ [12] = 'tabskip',
+ [13] = 'spaceskip',
+ [14] = 'xspaceskip',
+ [15] = 'parfillskip',
+ [16] = 'mathskip',
+ [17] = 'thinmuskip',
+ [18] = 'medmuskip',
+ [19] = 'thickmuskip',
+ [98] = 'conditionalmathskip',
+ [99] = 'muglue',
+ [100] = 'leaders',
+ [101] = 'cleaders',
+ [102] = 'xleaders',
+ [103] = 'gleaders',
+ },
+% \end{macrocode}
+% \paragraph{kern (13)}
+% \begin{macrocode}
+ kern = {
+ [0] = 'fontkern',
+ [1] = 'userkern',
+ [2] = 'accentkern',
+ [3] = 'italiccorrection',
+ },
+% \end{macrocode}
+%
+% \noindent
+% Nodes without subtypes:
+% \begin{compactitem}
+% \item penalty (14)
+% \item unset (15)
+% \item style (16)
+% \item choice (17)
+% \end{compactitem}
+%
+% \paragraph{noad (18)}
+% \begin{macrocode}
+ noad = {
+ [0] = 'ord',
+ [1] = 'opdisplaylimits',
+ [2] = 'oplimits',
+ [3] = 'opnolimits',
+ [4] = 'bin',
+ [5] = 'rel',
+ [6] = 'open',
+ [7] = 'close',
+ [8] = 'punct',
+ [9] = 'inner',
+ [10] = 'under',
+ [11] = 'over',
+ [12] = 'vcenter',
+ },
+% \end{macrocode}
+% \paragraph{radical (19)}
+% \begin{macrocode}
+ radical = {
+ [0] = 'radical',
+ [1] = 'uradical',
+ [2] = 'uroot',
+ [3] = 'uunderdelimiter',
+ [4] = 'uoverdelimiter',
+ [5] = 'udelimiterunder',
+ [6] = 'udelimiterover',
+ },
+% \end{macrocode}
+%
+% \noindent
+% Nodes without subtypes:
+% \begin{compactitem}
+% \item fraction (20)
+% \end{compactitem}
+%
+% \paragraph{accent (21)}
+% \begin{macrocode}
+ accent = {
+ [0] = 'bothflexible',
+ [1] = 'fixedtop',
+ [2] = 'fixedbottom',
+ [3] = 'fixedboth',
+ },
+% \end{macrocode}
+% \paragraph{fence (22)}
+% \begin{macrocode}
+ fence = {
+ [0] = 'unset',
+ [1] = 'left',
+ [2] = 'middle',
+ [3] = 'right',
+ },
+% \end{macrocode}
+%
+% \noindent
+% Nodes without subtypes:
+% \begin{compactitem}
+% \item math\_char (23)
+% \item sub\_box (24)
+% \item sub\_mlist (25)
+% \item math\_text\_char (26)
+% \item delim (27)
+% \item margin\_kern (28)
+% \end{compactitem}
+%
+% \paragraph{glyph (29)}
+% \begin{macrocode}
+ glyph = {
+ [0] = 'character',
+ [1] = 'ligature',
+ [2] = 'ghost',
+ [3] = 'left',
+ [4] = 'right',
+ },
+% \end{macrocode}
+%
+% \noindent
+% Nodes without subtypes:
+% \begin{compactitem}
+% \item align\_record (30)
+% \item pseudo\_file (31)
+% \item pseudo\_line (32)
+% \item page\_insert (33)
+% \item split\_insert (34)
+% \item expr\_stack (35)
+% \item nested\_list (36)
+% \item span (37)
+% \item attribute (38)
+% \item glue\_spec (39)
+% \item attribute\_list (40)
+% \item temp (41)
+% \item align\_stack (42)
+% \item movement\_stack (43)
+% \item if\_stack (44)
+% \item unhyphenated (45)
+% \item hyphenated (46)
+% \item delta (47)
+% \item passive (48)
+% \item shape (49)
+% \end{compactitem}
+% \begin{macrocode}
+ }
+ subtypes.whatsit = node.whatsits()
+ local out = ''
+ if subtypes[typ] and subtypes[typ][n.subtype] then
+ out = subtypes[typ][n.subtype]
+ if options.verbosity > 1 then
+ out = out .. tpl.type_id(n.subtype)
+ end
+ return out
+ else
+ return tostring(n.subtype)
+ end
+ assert(false)
+end
+% \end{macrocode}
+%
+% \subsubsection{tpl --- Template function}
+%
+% \begin{macrocode}
+function tpl.round(number)
+ local mult = 10^(options.decimalplaces or 0)
+ return math.floor(number * mult + 0.5) / mult
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.length(input)
+ input = tonumber(input)
+ input = input / tex.sp('1' .. options.unit)
+ return string.format('%g%s', tpl.round(input), options.unit)
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.fill(number, order, field)
+ if order ~= nil and order ~= 0 then
+ if field == 'stretch' then
+ out = '+'
+ else
+ out = '-'
+ end
+ return out .. string.format(
+ '%gfi%s', number / 2^16,
+ string.rep('l', order - 1)
+ )
+ else
+ return tpl.length(number)
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+tpl.node_colors = {
+ hlist = {'red', 'bright'},
+ vlist = {'green', 'bright'},
+ rule = {'blue', 'bright'},
+ ins = {'blue'},
+ mark = {'magenta'},
+ adjust = {'cyan'},
+ boundary = {'red', 'bright'},
+ disc = {'green', 'bright'},
+ whatsit = {'yellow', 'bright'},
+ local_par = {'blue', 'bright'},
+ dir = {'magenta', 'bright'},
+ math = {'cyan', 'bright'},
+ glue = {'magenta', 'bright'},
+ kern = {'green', 'bright'},
+ penalty = {'yellow', 'bright'},
+ unset = {'blue'},
+ style = {'magenta'},
+ choice = {'cyan'},
+ noad = {'red'},
+ radical = {'green'},
+ fraction = {'yellow'},
+ accent = {'blue'},
+ fence = {'magenta'},
+ math_char = {'cyan'},
+ sub_box = {'red', 'bright'},
+ sub_mlist = {'green', 'bright'},
+ math_text_char = {'yellow', 'bright'},
+ delim = {'blue', 'bright'},
+ margin_kern = {'magenta', 'bright'},
+ glyph = {'cyan', 'bright'},
+ align_record = {'red'},
+ pseudo_file = {'green'},
+ pseudo_line = {'yellow'},
+ page_insert = {'blue'},
+ split_insert = {'magenta'},
+ expr_stack = {'cyan'},
+ nested_list = {'red'},
+ span = {'green'},
+ attribute = {'yellow'},
+ glue_spec = {'magenta'},
+ attribute_list = {'cyan'},
+ temp = {'magenta'},
+ align_stack = {'red', 'bright'},
+ movement_stack = {'green', 'bright'},
+ if_stack = {'yellow', 'bright'},
+ unhyphenated = {'magenta', 'bright'},
+ hyphenated = {'cyan', 'bright'},
+ delta = {'red'},
+ passive = {'green'},
+ shape = {'yellow'},
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.color_code(code)
+ return string.char(27) .. '[' .. tostring(code) .. 'm'
+end
+% \end{macrocode}
+%
+% \begin{code}
+% local colors = {
+% -- attributes
+% reset = 0,
+% clear = 0,
+% bright = 1,
+% dim = 2,
+% underscore = 4,
+% blink = 5,
+% reverse = 7,
+% hidden = 8,
+%
+% -- foreground
+% black = 30,
+% red = 31,
+% green = 32,
+% yellow = 33,
+% blue = 34,
+% magenta = 35,
+% cyan = 36,
+% white = 37,
+%
+% -- background
+% onblack = 40,
+% onred = 41,
+% ongreen = 42,
+% onyellow = 43,
+% onblue = 44,
+% onmagenta = 45,
+% oncyan = 46,
+% onwhite = 47,
+% }
+% \end{code}
+% \begin{macrocode}
+function tpl.color(color, mode, background)
+ if options.color ~= 'colored' then
+ return ''
+ end
+% \end{macrocode}
+%
+% \begin{macrocode}
+ local out = ''
+ local code = ''
+% \end{macrocode}
+%
+% \begin{macrocode}
+ if mode == 'bright' then
+ out = tpl.color_code(1)
+ elseif mode == 'dim' then
+ out = tpl.color_code(2)
+ end
+% \end{macrocode}
+%
+% \begin{macrocode}
+ if not background then
+ if color == 'reset' then code = 0
+ elseif color == 'red' then code = 31
+ elseif color == 'green' then code = 32
+ elseif color == 'yellow' then code = 33
+ elseif color == 'blue' then code = 34
+ elseif color == 'magenta' then code = 35
+ elseif color == 'cyan' then code = 36
+ else code = 37 end
+ else
+ if color == 'black' then code = 40
+ elseif color == 'red' then code = 41
+ elseif color == 'green' then code = 42
+ elseif color == 'yellow' then code = 43
+ elseif color == 'blue' then code = 44
+ elseif color == 'magenta' then code = 45
+ elseif color == 'cyan' then code = 46
+ elseif color == 'white' then code = 47
+ else code = 40 end
+ end
+ return out .. tpl.color_code(code)
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.key_value(key, value)
+ local out = tpl.color('yellow') .. key .. ': '
+ if value then
+ out = out .. tpl.color('white') .. value .. '; '
+ end
+ return out .. tpl.color('reset')
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.char(input)
+ return string.format('%q', unicode.utf8.char(input))
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.type(type, id)
+ local out = tpl.color(
+ tpl.node_colors[type][1],
+ tpl.node_colors[type][2]
+ )
+ .. string.upper(type)
+ if options.verbosity > 1 then
+ out = out .. tpl.type_id(id)
+ end
+ return out .. tpl.color('reset') .. ' '
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.callback_variable(variable_name, variable)
+ if variable ~= nil and variable ~= '' then
+ tpl.print(variable_name .. ': ' .. tostring(variable))
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.line(length)
+ if length == 'long' then
+ return '------------------------------------------'
+ else
+ return '-----------------------'
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.callback(callback_name, variables)
+ tpl.print('\n\n')
+ tpl.print('Callback: ' .. tpl.color('red', '', true) ..
+ callback_name .. tpl.color('reset')
+ )
+ if variables then
+ for name, value in pairs(variables) do
+ if value ~= nil and value ~= '' then
+ tpl.print(' - ' .. name .. ': ' .. tostring(value))
+ end
+ end
+ end
+ tpl.print(tpl.line('long'))
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.type_id(id)
+ return '[' .. tostring(id) .. ']'
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.branch(connection_type, connection_state, last)
+ local c = connection_type
+ local s = connection_state
+ local l = last
+ if c == 'list' and s == 'stop' and l == false then
+ return ' '
+ elseif c == 'field' and s == 'stop' and l == false then
+ return ' '
+ elseif c == 'list' and s == 'continue' and l == false then
+ return '│ '
+ elseif c == 'field' and s == 'continue' and l == false then
+ return 'â•‘ '
+ elseif c == 'list' and s == 'continue' and l == true then
+ return '├─'
+ elseif c == 'field' and s == 'continue' and l == true then
+ return 'â• â•'
+ elseif c == 'list' and s == 'stop' and l == true then
+ return '└─'
+ elseif c == 'field' and s == 'stop' and l == true then
+ return 'â•šâ•'
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.branches(level, connection_type)
+ local out = ''
+ for i = 1, level - 1 do
+ out = out .. tpl.branch('list', tree.state[i]['list'], false)
+ out = out .. tpl.branch('field', tree.state[i]['field'], false)
+ end
+% \end{macrocode}
+% Format the last branches
+% \begin{macrocode}
+ if connection_type == 'list' then
+ out = out .. tpl.branch('list', tree.state[level]['list'], true)
+ else
+ out = out .. tpl.branch('list', tree.state[level]['list'], false)
+ out = out .. tpl.branch('field', tree.state[level]['field'], true)
+ end
+ return out
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tpl.print(text)
+
+ if options.channel == 'log' then
+ if not log then
+ log = io.open(tex.jobname .. '_nodetree.log', 'a')
+ end
+ log:write(text, '\n')
+ else
+ print(' ' .. text)
+ end
+end
+% \end{macrocode}
+%
+% \subsubsection{tree --- Build the node tree}
+%
+% \begin{macrocode}
+function tree.format_field(head, field)
+ local out = ''
+% \end{macrocode}
+%
+% \begin{macrocode}
+ if not head[field] or head[field] == 0 then
+ return ''
+ end
+% \end{macrocode}
+%
+% \begin{macrocode}
+ if options.verbosity < 2 and
+ -- glyph
+ field == 'font' or
+ field == 'left' or
+ field == 'right' or
+ field == 'uchyph' or
+ -- hlist
+ field == 'dir' or
+ field == 'glue_order' or
+ field == 'glue_sign' or
+ field == 'glue_set' or
+ -- glue
+ field == 'stretch_order' then
+ return ''
+ elseif options.verbosity < 3 and
+ field == 'prev' or
+ field == 'next' or
+ field == 'id'
+ then
+ return ''
+ end
+% \end{macrocode}
+%
+% \begin{macrocode}
+ if field == 'prev' or field == 'next' then
+ out = nodex.node_id(head[field])
+ elseif field == 'subtype' then
+ out = nodex.subtype(head)
+ elseif
+ field == 'width' or
+ field == 'height' or
+ field == 'depth' or
+ field == 'kern' or
+ field == 'shift' then
+ out = tpl.length(head[field])
+ elseif field == 'char' then
+ out = tpl.char(head[field])
+ elseif field == 'glue_set' then
+ out = tpl.round(head[field])
+ elseif field == 'stretch' or field == 'shrink' then
+ out = tpl.fill(head[field], head[field .. '_order'], field)
+ else
+ out = tostring(head[field])
+ end
+% \end{macrocode}
+%
+% \begin{macrocode}
+ return tpl.key_value(field, out)
+end
+% \end{macrocode}
+%
+% |level| is a integer beginning with 1. The variable |connection_type|
+% is a string, which can be either |list| or |field|. The variable
+% |connection_state| is a string, which can be either |continue| or
+% |stop|.
+% \begin{macrocode}
+function tree.set_state(level, connection_type, connection_state)
+ if not tree.state[level] then
+ tree.state[level] = {}
+ end
+ tree.state[level][connection_type] = connection_state
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tree.analyze_fields(fields, level)
+ local max = 0
+ local connection_state = ''
+ for _ in pairs(fields) do
+ max = max + 1
+ end
+ local count = 0
+ for field_name, recursion_node in pairs(fields) do
+ count = count + 1
+ if count == max then
+ connection_state = 'stop'
+ else
+ connection_state = 'continue'
+ end
+ tree.set_state(level, 'field', connection_state)
+ tpl.print(tpl.branches(level, 'field') .. tpl.key_value(field_name))
+ tree.analyze_list(recursion_node, level + 1)
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tree.analyze_node(head, level)
+ local connection_state
+ local out = ''
+ if head.next then
+ connection_state = 'continue'
+ else
+ connection_state = 'stop'
+ end
+ tree.set_state(level, 'list', connection_state)
+ out = tpl.branches(level, 'list')
+ .. tpl.type(node.type(head.id), head.id)
+ if options.verbosity > 1 then
+ out = out .. tpl.key_value('no', nodex.node_id(head))
+ end
+% \end{macrocode}
+%
+% \begin{macrocode}
+ local fields = {}
+ for field_id, field_name in pairs(node.fields(head.id, head.subtype)) do
+ if field_name ~= 'next' and
+ field_name ~= 'prev' and
+ node.is_node(head[field_name]) then
+ fields[field_name] = head[field_name]
+ else
+ out = out .. tree.format_field(head, field_name)
+ end
+ end
+% \end{macrocode}
+%
+% \begin{macrocode}
+ tpl.print(out)
+ tree.analyze_fields(fields, level)
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tree.analyze_list(head, level)
+ while head do
+ tree.analyze_node(head, level)
+ head = head.next
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function tree.analyze_callback(head)
+ tree.analyze_list(head, 1)
+ tpl.print(tpl.line('short') .. '\n')
+end
+% \end{macrocode}
+%
+% \subsubsection{callbacks --- Callback wrapper}
+%
+% \begin{macrocode}
+function callbacks.contribute_filter(extrainfo)
+ tpl.callback('contribute_filter', {extrainfo = extrainfo})
+ return true
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.buildpage_filter(extrainfo)
+ tpl.callback('buildpage_filter', {extrainfo = extrainfo})
+ return true
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.pre_linebreak_filter(head, groupcode)
+ tpl.callback('pre_linebreak_filter', {groupcode = groupcode})
+ tree.analyze_callback(head)
+ return true
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.linebreak_filter(head, is_display)
+ tpl.callback('linebreak_filter', {is_display = is_display})
+ tree.analyze_callback(head)
+ return true
+end
+% \end{macrocode}
+%
+% TODO: Fix return values, page output
+% \begin{macrocode}
+function callbacks.append_to_vlist_filter(head, locationcode, prevdepth, mirrored)
+ local variables = {
+ locationcode = locationcode,
+ prevdepth = prevdepth,
+ mirrored = mirrored,
+ }
+ tpl.callback('append_to_vlist_filter', variables)
+ tree.analyze_callback(head)
+ return true
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.post_linebreak_filter(head, groupcode)
+ tpl.callback('post_linebreak_filter', {groupcode = groupcode})
+ tree.analyze_callback(head)
+ return true
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.hpack_filter(head, groupcode, size, packtype, direction, attributelist)
+ local variables = {
+ groupcode = groupcode,
+ size = size,
+ packtype = packtype,
+ direction = direction,
+ attributelist = attributelist,
+ }
+ tpl.callback('hpack_filter', variables)
+ tree.analyze_callback(head)
+ return true
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.vpack_filter(head, groupcode, size, packtype, maxdepth, direction, attributelist)
+ local variables = {
+ groupcode = groupcode,
+ size = size,
+ packtype = packtype,
+ maxdepth = tpl.length(maxdepth),
+ direction = direction,
+ attributelist = attributelist,
+ }
+ tpl.callback('vpack_filter', variables)
+ tree.analyze_callback(head)
+ return true
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.hpack_quality(incident, detail, head, first, last)
+ local variables = {
+ incident = incident,
+ detail = detail,
+ first = first,
+ last = last,
+ }
+ tpl.callback('hpack_quality', variables)
+ tree.analyze_callback(head)
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.vpack_quality(incident, detail, head, first, last)
+ local variables = {
+ incident = incident,
+ detail = detail,
+ first = first,
+ last = last,
+ }
+ tpl.callback('vpack_quality', variables)
+ tree.analyze_callback(head)
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.process_rule(head, width, height)
+ local variables = {
+ width = width,
+ height = height,
+ }
+ tpl.callback('process_rule', variables)
+ tree.analyze_callback(head)
+ return true
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.pre_output_filter(head, groupcode, size, packtype, maxdepth, direction)
+ local variables = {
+ groupcode = groupcode,
+ size = size,
+ packtype = packtype,
+ maxdepth = maxdepth,
+ direction = direction,
+ }
+ tpl.callback('pre_output_filter', variables)
+ tree.analyze_callback(head)
+ return true
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.hyphenate(head, tail)
+ tpl.callback('hyphenate')
+ tpl.print('head:')
+ tree.analyze_callback(head)
+ tpl.print('tail:')
+ tree.analyze_callback(tail)
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.ligaturing(head, tail)
+ tpl.callback('ligaturing')
+ tpl.print('head:')
+ tree.analyze_callback(head)
+ tpl.print('tail:')
+ tree.analyze_callback(tail)
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.kerning(head, tail)
+ tpl.callback('kerning')
+ tpl.print('head:')
+ tree.analyze_callback(head)
+ tpl.print('tail:')
+ tree.analyze_callback(tail)
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.insert_local_par(local_par, location)
+ tpl.callback('insert_local_par', {location = location})
+ tree.analyze_callback(local_par)
+ return true
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function callbacks.mlist_to_hlist(head, display_type, need_penalties)
+ local variables = {
+ display_type = display_type,
+ need_penalties = need_penalties,
+ }
+ tpl.callback('mlist_to_hlist', variables)
+ tree.analyze_callback(head)
+ return node.mlist_to_hlist(head, display_type, need_penalties)
+end
+% \end{macrocode}
+%
+% \subsubsection{base --- Exported base functions}
+%
+% \begin{macrocode}
+function base.normalize_options()
+ options.verbosity = tonumber(options.verbosity)
+ options.decimalplaces = tonumber(options.decimalplaces)
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function base.set_default_options()
+ local defaults = {
+ verbosity = 1,
+ callback = 'postlinebreak',
+ engine = 'luatex',
+ color = 'colored',
+ decimalplaces = 2,
+ unit = 'pt',
+ channel = 'term',
+ }
+ if not options then
+ options = {}
+ end
+ for key, value in pairs(defaults) do
+ if not options[key] then
+ options[key] = value
+ end
+ end
+ base.normalize_options()
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function base.set_option(key, value)
+ if not options then
+ options = {}
+ end
+ options[key] = value
+ base.normalize_options()
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function base.get_option(key)
+ if not options then
+ options = {}
+ end
+ if options[key] then
+ return options[key]
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function base.get_callback_name(alias)
+ if alias == 'contribute' or alias == 'contributefilter' then
+ return 'contribute_filter'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'buildpage' or alias == 'buildpagefilter' then
+ return 'buildpage_filter'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'preline' or alias == 'prelinebreakfilter' then
+ return 'pre_linebreak_filter'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'line' or alias == 'linebreakfilter' then
+ return 'linebreak_filter'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'append' or alias == 'appendtovlistfilter' then
+ return 'append_to_vlist_filter'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'postline' or alias == 'postlinebreakfilter' then
+ return 'post_linebreak_filter'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'hpack' or alias == 'hpackfilter' then
+ return 'hpack_filter'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'vpack' or alias == 'vpackfilter' then
+ return 'vpack_filter'
+% \end{macrocode}
+% TODO: Fix: Unable to register callback
+% \begin{macrocode}
+ elseif alias == 'hpackq' or alias == 'hpackquality' then
+ return 'hpack_quality'
+% \end{macrocode}
+% TODO: Fix: Unable to register callback
+% \begin{macrocode}
+ elseif alias == 'vpackq' or alias == 'vpackquality' then
+ return 'vpack_quality'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'process' or alias == 'processrule' then
+ return 'process_rule'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'preout' or alias == 'preoutputfilter' then
+ return 'pre_output_filter'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'hyph' or alias == 'hyphenate' then
+ return 'hyphenate'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'liga' or alias == 'ligaturing' then
+ return 'ligaturing'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'kern' or alias == 'kerning' then
+ return 'kerning'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'insert' or alias == 'insertlocalpar' then
+ return 'insert_local_par'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ elseif alias == 'mhlist' or alias == 'mlisttohlist' then
+ return 'mlist_to_hlist'
+% \end{macrocode}
+%
+% \begin{macrocode}
+ else
+ return 'post_linebreak_filter'
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function base.register(cb)
+ if options.engine == 'lualatex' then
+ luatexbase.add_to_callback(cb, callbacks[cb], 'nodetree')
+ else
+ id, error = callback.register(cb, callbacks[cb])
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function base.register_callbacks()
+ for alias in string.gmatch(options.callback, '([^,]+)') do
+ base.register(base.get_callback_name(alias))
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function base.unregister(cb)
+ if options.engine == 'lualatex' then
+ luatexbase.remove_from_callback(cb, 'nodetree')
+ else
+ id, error = callback.register(cb, nil)
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function base.unregister_callbacks()
+ for alias in string.gmatch(options.callback, '([^,]+)') do
+ base.unregister(base.get_callback_name(alias))
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function base.execute()
+ local c = base.get_callback()
+ if options.engine == 'lualatex' then
+ luatexbase.add_to_callback(c, callbacks.post_linebreak_filter, 'nodetree')
+ else
+ id, error = callback.register(c, callbacks.post_linebreak_filter)
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+function base.analyze(head)
+ tpl.print('\n')
+ tree.analyze_list(head, 1)
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+return base
+% \end{macrocode}
+% \iffalse
+%</luamain>
+% \fi
+%
+% \Finale
+\endinput
diff --git a/macros/luatex/generic/nodetree/nodetree.ins b/macros/luatex/generic/nodetree/nodetree.ins
new file mode 100644
index 0000000000..85d250818e
--- /dev/null
+++ b/macros/luatex/generic/nodetree/nodetree.ins
@@ -0,0 +1,61 @@
+% Copyright (C) 2016 by Josef Friedrich <josef@friedrich.rocks>
+% ----------------------------------------------------------------------
+% This work may be distributed and/or modified under the conditions of
+% the LaTeX Project Public License, either version 1.3c of this license
+% or (at your option) any later version. The latest version of this
+% license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008/05/05 or later.
+
+\input docstrip.tex
+\keepsilent
+
+\usedir{tex/lualatex/nodetree}
+
+\askforoverwritefalse
+
+\preamble
+
+This is a generated file.
+
+Copyright (C) 2016 by Josef Friedrich <josef@friedrich.rocks>
+----------------------------------------------------------------------
+This work may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3c of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of LaTeX
+version 2008/05/05 or later.
+
+\endpreamble
+
+\generate{\file{nodetree.tex}{\from{nodetree.dtx}{tex}}}
+\generate{\file{nodetree.sty}{\from{nodetree.dtx}{package}}}
+
+\nopreamble
+\nopostamble
+\generate{\file{nodetree.lua}{\from{nodetree.dtx}{luamain}}}
+\generate{\file{README.md}{\from{nodetree.dtx}{readme}}}
+
+\obeyspaces
+\Msg{*************************************************************}
+\Msg{* *}
+\Msg{* To finish the installation you have to move the following *}
+\Msg{* file into a directory searched by TeX: *}
+\Msg{* *}
+\Msg{* nodetree.sty *}
+\Msg{* *}
+\Msg{* To produce the documentation run the file nodetree.dtx *}
+\Msg{* through LaTeX. *}
+\Msg{* *}
+\Msg{* Happy TeXing! *}
+\Msg{* *}
+\Msg{*************************************************************}
+
+\endbatchfile
diff --git a/macros/luatex/generic/nodetree/nodetree.pdf b/macros/luatex/generic/nodetree/nodetree.pdf
new file mode 100644
index 0000000000..0ea7228abe
--- /dev/null
+++ b/macros/luatex/generic/nodetree/nodetree.pdf
Binary files differ
diff --git a/macros/luatex/generic/spelling/CHANGES b/macros/luatex/generic/spelling/CHANGES
new file mode 100644
index 0000000000..b96745410f
--- /dev/null
+++ b/macros/luatex/generic/spelling/CHANGES
@@ -0,0 +1,90 @@
+This material is subject to the LaTeX Project Public License. See
+<http://www.latex-project.org/lppl/> for the details of that license.
+
+
+### v0.41 (2013-05-25)
+
+Fixes:
+
+* Fixed compatibility issue with LuaTeX 0.70.2 that caused text output
+ file written to be emtpy.
+
+
+### v0.4 (2013-05-23)
+
+New features:
+
+* In addition to lists of bad and good spellings, words can be checked
+ against user-defined match rules to determine highlighting status.
+
+Changes:
+
+* Removed means to configure EOL character of text output file.
+ Standard Lua EOL character is always used, which is platform
+ dependent.
+
+* Improved compatibility with recent LuaTeX versions (v0.74 and newer).
+
+* File `<jobname>.spell.xml` is loaded before file `<jobname>.spell.bad`
+ (if both files exist).
+
+Fixes:
+
+* Bad words with surrounding punctuation haven't been highlighted.
+ Determining whether a word needs to be highlighted is now done by
+ checking against the lists of bad and good spellings words as they
+ appear in the document with possible punctuation as well as with all
+ surrounding punctuation stripped ([GitHub issue 8][ghi#8]).
+
+* Macro `\spellingoutputlinelength` was broken.
+
+* Raising an error when a file cannot be opened for reading causes
+ problems when compiling a document for the first time. Now, only a
+ warning is written to the console and log file in that case.
+
+[ghi#8]: https://github.com/sh2d/spelling/issues/8
+
+
+### v0.3 (2013-02-12)
+
+New:
+
+* [LanguageTool][lt] support: LanguageTool error reports in the XML
+ format can be parsed for spelling errors (with the help of the
+ [LuaXML][luaxml] package). LanguageTool is a cross-platform style and
+ grammar checker.
+
+[lt]: http://www.languagetool.org/
+[luaxml]: http://www.ctan.org/pkg/luaxml
+
+Changes:
+
+* Default file names used by the package have been changed:
+
+ <jobname>.spb => <jobname>.spell.bad
+ <jobname>.spg => <jobname>.spell.good
+ <jobname>.txt => <jobname>.spell.txt
+
+
+### v0.2 (2012-12-04)
+
+Fixes:
+
+* File `spelling.lua` could not be found by LaTeX style file
+ ([GitHub issue 14][ghi#14]).
+
+[ghi#14]: https://github.com/sh2d/spelling/issues/14
+
+
+### v0.1 (2012-11-30)
+
+First upload to CTAN.
+
+
+
+<!--
+%%% Local Variables:
+%%% coding: utf-8
+%%% mode: markdown
+%%% End:
+-->
diff --git a/macros/luatex/generic/spelling/LICENSE b/macros/luatex/generic/spelling/LICENSE
new file mode 100644
index 0000000000..2244313901
--- /dev/null
+++ b/macros/luatex/generic/spelling/LICENSE
@@ -0,0 +1,416 @@
+The LaTeX Project Public License
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+LPPL Version 1.3c 2008-05-04
+
+Copyright 1999 2002-2008 LaTeX3 Project
+ Everyone is allowed to distribute verbatim copies of this
+ license document, but modification of it is not allowed.
+
+
+PREAMBLE
+========
+
+The LaTeX Project Public License (LPPL) is the primary license under
+which the LaTeX kernel and the base LaTeX packages are distributed.
+
+You may use this license for any work of which you hold the copyright
+and which you wish to distribute. This license may be particularly
+suitable if your work is TeX-related (such as a LaTeX package), but
+it is written in such a way that you can use it even if your work is
+unrelated to TeX.
+
+The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE',
+below, gives instructions, examples, and recommendations for authors
+who are considering distributing their works under this license.
+
+This license gives conditions under which a work may be distributed
+and modified, as well as conditions under which modified versions of
+that work may be distributed.
+
+We, the LaTeX3 Project, believe that the conditions below give you
+the freedom to make and distribute modified versions of your work
+that conform with whatever technical specifications you wish while
+maintaining the availability, integrity, and reliability of
+that work. If you do not see how to achieve your goal while
+meeting these conditions, then read the document `cfgguide.tex'
+and `modguide.tex' in the base LaTeX distribution for suggestions.
+
+
+DEFINITIONS
+===========
+
+In this license document the following terms are used:
+
+ `Work'
+ Any work being distributed under this License.
+
+ `Derived Work'
+ Any work that under any applicable law is derived from the Work.
+
+ `Modification'
+ Any procedure that produces a Derived Work under any applicable
+ law -- for example, the production of a file containing an
+ original file associated with the Work or a significant portion of
+ such a file, either verbatim or with modifications and/or
+ translated into another language.
+
+ `Modify'
+ To apply any procedure that produces a Derived Work under any
+ applicable law.
+
+ `Distribution'
+ Making copies of the Work available from one person to another, in
+ whole or in part. Distribution includes (but is not limited to)
+ making any electronic components of the Work accessible by
+ file transfer protocols such as FTP or HTTP or by shared file
+ systems such as Sun's Network File System (NFS).
+
+ `Compiled Work'
+ A version of the Work that has been processed into a form where it
+ is directly usable on a computer system. This processing may
+ include using installation facilities provided by the Work,
+ transformations of the Work, copying of components of the Work, or
+ other activities. Note that modification of any installation
+ facilities provided by the Work constitutes modification of the Work.
+
+ `Current Maintainer'
+ A person or persons nominated as such within the Work. If there is
+ no such explicit nomination then it is the `Copyright Holder' under
+ any applicable law.
+
+ `Base Interpreter'
+ A program or process that is normally needed for running or
+ interpreting a part or the whole of the Work.
+
+ A Base Interpreter may depend on external components but these
+ are not considered part of the Base Interpreter provided that each
+ external component clearly identifies itself whenever it is used
+ interactively. Unless explicitly specified when applying the
+ license to the Work, the only applicable Base Interpreter is a
+ `LaTeX-Format' or in the case of files belonging to the
+ `LaTeX-format' a program implementing the `TeX language'.
+
+
+
+CONDITIONS ON DISTRIBUTION AND MODIFICATION
+===========================================
+
+1. Activities other than distribution and/or modification of the Work
+are not covered by this license; they are outside its scope. In
+particular, the act of running the Work is not restricted and no
+requirements are made concerning any offers of support for the Work.
+
+2. You may distribute a complete, unmodified copy of the Work as you
+received it. Distribution of only part of the Work is considered
+modification of the Work, and no right to distribute such a Derived
+Work may be assumed under the terms of this clause.
+
+3. You may distribute a Compiled Work that has been generated from a
+complete, unmodified copy of the Work as distributed under Clause 2
+above, as long as that Compiled Work is distributed in such a way that
+the recipients may install the Compiled Work on their system exactly
+as it would have been installed if they generated a Compiled Work
+directly from the Work.
+
+4. If you are the Current Maintainer of the Work, you may, without
+restriction, modify the Work, thus creating a Derived Work. You may
+also distribute the Derived Work without restriction, including
+Compiled Works generated from the Derived Work. Derived Works
+distributed in this manner by the Current Maintainer are considered to
+be updated versions of the Work.
+
+5. If you are not the Current Maintainer of the Work, you may modify
+your copy of the Work, thus creating a Derived Work based on the Work,
+and compile this Derived Work, thus creating a Compiled Work based on
+the Derived Work.
+
+6. If you are not the Current Maintainer of the Work, you may
+distribute a Derived Work provided the following conditions are met
+for every component of the Work unless that component clearly states
+in the copyright notice that it is exempt from that condition. Only
+the Current Maintainer is allowed to add such statements of exemption
+to a component of the Work.
+
+ a. If a component of this Derived Work can be a direct replacement
+ for a component of the Work when that component is used with the
+ Base Interpreter, then, wherever this component of the Work
+ identifies itself to the user when used interactively with that
+ Base Interpreter, the replacement component of this Derived Work
+ clearly and unambiguously identifies itself as a modified version
+ of this component to the user when used interactively with that
+ Base Interpreter.
+
+ b. Every component of the Derived Work contains prominent notices
+ detailing the nature of the changes to that component, or a
+ prominent reference to another file that is distributed as part
+ of the Derived Work and that contains a complete and accurate log
+ of the changes.
+
+ c. No information in the Derived Work implies that any persons,
+ including (but not limited to) the authors of the original version
+ of the Work, provide any support, including (but not limited to)
+ the reporting and handling of errors, to recipients of the
+ Derived Work unless those persons have stated explicitly that
+ they do provide such support for the Derived Work.
+
+ d. You distribute at least one of the following with the Derived Work:
+
+ 1. A complete, unmodified copy of the Work;
+ if your distribution of a modified component is made by
+ offering access to copy the modified component from a
+ designated place, then offering equivalent access to copy
+ the Work from the same or some similar place meets this
+ condition, even though third parties are not compelled to
+ copy the Work along with the modified component;
+
+ 2. Information that is sufficient to obtain a complete,
+ unmodified copy of the Work.
+
+7. If you are not the Current Maintainer of the Work, you may
+distribute a Compiled Work generated from a Derived Work, as long as
+the Derived Work is distributed to all recipients of the Compiled
+Work, and as long as the conditions of Clause 6, above, are met with
+regard to the Derived Work.
+
+8. The conditions above are not intended to prohibit, and hence do not
+apply to, the modification, by any method, of any component so that it
+becomes identical to an updated version of that component of the Work as
+it is distributed by the Current Maintainer under Clause 4, above.
+
+9. Distribution of the Work or any Derived Work in an alternative
+format, where the Work or that Derived Work (in whole or in part) is
+then produced by applying some process to that format, does not relax or
+nullify any sections of this license as they pertain to the results of
+applying that process.
+
+10. a. A Derived Work may be distributed under a different license
+ provided that license itself honors the conditions listed in
+ Clause 6 above, in regard to the Work, though it does not have
+ to honor the rest of the conditions in this license.
+
+ b. If a Derived Work is distributed under a different license, that
+ Derived Work must provide sufficient documentation as part of
+ itself to allow each recipient of that Derived Work to honor the
+ restrictions in Clause 6 above, concerning changes from the Work.
+
+11. This license places no restrictions on works that are unrelated to
+the Work, nor does this license place any restrictions on aggregating
+such works with the Work by any means.
+
+12. Nothing in this license is intended to, or may be used to, prevent
+complete compliance by all parties with all applicable laws.
+
+
+NO WARRANTY
+===========
+
+There is no warranty for the Work. Except when otherwise stated in
+writing, the Copyright Holder provides the Work `as is', without
+warranty of any kind, either expressed or implied, including, but not
+limited to, the implied warranties of merchantability and fitness for a
+particular purpose. The entire risk as to the quality and performance
+of the Work is with you. Should the Work prove defective, you assume
+the cost of all necessary servicing, repair, or correction.
+
+In no event unless required by applicable law or agreed to in writing
+will The Copyright Holder, or any author named in the components of the
+Work, or any other party who may distribute and/or modify the Work as
+permitted above, be liable to you for damages, including any general,
+special, incidental or consequential damages arising out of any use of
+the Work or out of inability to use the Work (including, but not limited
+to, loss of data, data being rendered inaccurate, or losses sustained by
+anyone as a result of any failure of the Work to operate with any other
+programs), even if the Copyright Holder or said author or said other
+party has been advised of the possibility of such damages.
+
+
+MAINTENANCE OF THE WORK
+=======================
+
+The Work has the status `author-maintained' if the Copyright Holder
+explicitly and prominently states near the primary copyright notice in
+the Work that the Work can only be maintained by the Copyright Holder
+or simply that it is `author-maintained'.
+
+The Work has the status `maintained' if there is a Current Maintainer
+who has indicated in the Work that they are willing to receive error
+reports for the Work (for example, by supplying a valid e-mail
+address). It is not required for the Current Maintainer to acknowledge
+or act upon these error reports.
+
+The Work changes from status `maintained' to `unmaintained' if there
+is no Current Maintainer, or the person stated to be Current
+Maintainer of the work cannot be reached through the indicated means
+of communication for a period of six months, and there are no other
+significant signs of active maintenance.
+
+You can become the Current Maintainer of the Work by agreement with
+any existing Current Maintainer to take over this role.
+
+If the Work is unmaintained, you can become the Current Maintainer of
+the Work through the following steps:
+
+ 1. Make a reasonable attempt to trace the Current Maintainer (and
+ the Copyright Holder, if the two differ) through the means of
+ an Internet or similar search.
+
+ 2. If this search is successful, then enquire whether the Work
+ is still maintained.
+
+ a. If it is being maintained, then ask the Current Maintainer
+ to update their communication data within one month.
+
+ b. If the search is unsuccessful or no action to resume active
+ maintenance is taken by the Current Maintainer, then announce
+ within the pertinent community your intention to take over
+ maintenance. (If the Work is a LaTeX work, this could be
+ done, for example, by posting to comp.text.tex.)
+
+ 3a. If the Current Maintainer is reachable and agrees to pass
+ maintenance of the Work to you, then this takes effect
+ immediately upon announcement.
+
+ b. If the Current Maintainer is not reachable and the Copyright
+ Holder agrees that maintenance of the Work be passed to you,
+ then this takes effect immediately upon announcement.
+
+ 4. If you make an `intention announcement' as described in 2b. above
+ and after three months your intention is challenged neither by
+ the Current Maintainer nor by the Copyright Holder nor by other
+ people, then you may arrange for the Work to be changed so as
+ to name you as the (new) Current Maintainer.
+
+ 5. If the previously unreachable Current Maintainer becomes
+ reachable once more within three months of a change completed
+ under the terms of 3b) or 4), then that Current Maintainer must
+ become or remain the Current Maintainer upon request provided
+ they then update their communication data within one month.
+
+A change in the Current Maintainer does not, of itself, alter the fact
+that the Work is distributed under the LPPL license.
+
+If you become the Current Maintainer of the Work, you should
+immediately provide, within the Work, a prominent and unambiguous
+statement of your status as Current Maintainer. You should also
+announce your new status to the same pertinent community as
+in 2b) above.
+
+
+WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE
+======================================================
+
+This section contains important instructions, examples, and
+recommendations for authors who are considering distributing their
+works under this license. These authors are addressed as `you' in
+this section.
+
+Choosing This License or Another License
+----------------------------------------
+
+If for any part of your work you want or need to use *distribution*
+conditions that differ significantly from those in this license, then
+do not refer to this license anywhere in your work but, instead,
+distribute your work under a different license. You may use the text
+of this license as a model for your own license, but your license
+should not refer to the LPPL or otherwise give the impression that
+your work is distributed under the LPPL.
+
+The document `modguide.tex' in the base LaTeX distribution explains
+the motivation behind the conditions of this license. It explains,
+for example, why distributing LaTeX under the GNU General Public
+License (GPL) was considered inappropriate. Even if your work is
+unrelated to LaTeX, the discussion in `modguide.tex' may still be
+relevant, and authors intending to distribute their works under any
+license are encouraged to read it.
+
+A Recommendation on Modification Without Distribution
+-----------------------------------------------------
+
+It is wise never to modify a component of the Work, even for your own
+personal use, without also meeting the above conditions for
+distributing the modified component. While you might intend that such
+modifications will never be distributed, often this will happen by
+accident -- you may forget that you have modified that component; or
+it may not occur to you when allowing others to access the modified
+version that you are thus distributing it and violating the conditions
+of this license in ways that could have legal implications and, worse,
+cause problems for the community. It is therefore usually in your
+best interest to keep your copy of the Work identical with the public
+one. Many works provide ways to control the behavior of that work
+without altering any of its licensed components.
+
+How to Use This License
+-----------------------
+
+To use this license, place in each of the components of your work both
+an explicit copyright notice including your name and the year the work
+was authored and/or last substantially modified. Include also a
+statement that the distribution and/or modification of that
+component is constrained by the conditions in this license.
+
+Here is an example of such a notice and statement:
+
+ %% pig.dtx
+ %% Copyright 2005 M. Y. Name
+ %
+ % This work may be distributed and/or modified under the
+ % conditions of the LaTeX Project Public License, either version 1.3
+ % of this license or (at your option) any later version.
+ % The latest version of this license is in
+ % http://www.latex-project.org/lppl.txt
+ % and version 1.3 or later is part of all distributions of LaTeX
+ % version 2005/12/01 or later.
+ %
+ % This work has the LPPL maintenance status `maintained'.
+ %
+ % The Current Maintainer of this work is M. Y. Name.
+ %
+ % This work consists of the files pig.dtx and pig.ins
+ % and the derived file pig.sty.
+
+Given such a notice and statement in a file, the conditions
+given in this license document would apply, with the `Work' referring
+to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being
+generated from `pig.dtx' using `pig.ins'), the `Base Interpreter'
+referring to any `LaTeX-Format', and both `Copyright Holder' and
+`Current Maintainer' referring to the person `M. Y. Name'.
+
+If you do not want the Maintenance section of LPPL to apply to your
+Work, change `maintained' above into `author-maintained'.
+However, we recommend that you use `maintained', as the Maintenance
+section was added in order to ensure that your Work remains useful to
+the community even when you can no longer maintain and support it
+yourself.
+
+Derived Works That Are Not Replacements
+---------------------------------------
+
+Several clauses of the LPPL specify means to provide reliability and
+stability for the user community. They therefore concern themselves
+with the case that a Derived Work is intended to be used as a
+(compatible or incompatible) replacement of the original Work. If
+this is not the case (e.g., if a few lines of code are reused for a
+completely different task), then clauses 6b and 6d shall not apply.
+
+
+Important Recommendations
+-------------------------
+
+ Defining What Constitutes the Work
+
+ The LPPL requires that distributions of the Work contain all the
+ files of the Work. It is therefore important that you provide a
+ way for the licensee to determine which files constitute the Work.
+ This could, for example, be achieved by explicitly listing all the
+ files of the Work near the copyright notice of each file or by
+ using a line such as:
+
+ % This work consists of all files listed in manifest.txt.
+
+ in that place. In the absence of an unequivocal list it might be
+ impossible for the licensee to determine what is considered by you
+ to comprise the Work and, in such a case, the licensee would be
+ entitled to make reasonable conjectures as to which files comprise
+ the Work.
+
diff --git a/macros/luatex/generic/spelling/README b/macros/luatex/generic/spelling/README
new file mode 100644
index 0000000000..a5f2ee4158
--- /dev/null
+++ b/macros/luatex/generic/spelling/README
@@ -0,0 +1,70 @@
+This material is subject to the LaTeX Project Public License. See
+<http://www.latex-project.org/lppl/> for the details of that license.
+
+
+
+### Package information
+
+Package name: spelling
+Summary description: support for spell-checking of LuaTeX documents
+Version: v0.41
+Date: 2013-05-25
+License: [LPPL v1.3c](http://www.latex-project.org/lppl/lppl-1-3c.html)
+Maintenance status: maintained
+Current maintainer: Stephan Hennig, <sh2d@arcor.de>
+
+
+
+### Description
+
+This package supports spell-checking of TeX documents compiled with the
+LuaTeX engine. It can give visual feedback in PDF output similar to
+WYSIWYG word processors. The package relies on an external
+spell-checker application that can check a plain text file and output a
+list of bad spellings. The package should work with most
+spell-checkers, even dumb, TeX-unaware ones.
+
+
+
+### Development
+
+The development repository is currently hosted at
+[GitHub](https://github.com/sh2d/spelling/). Code documentation is in
+[LuaDoc](http://keplerproject.github.com/luadoc/) format and can be
+generated via
+
+ luadoc -d API *.lua
+
+Bugs and a wish list can be found in the
+[issue tracker](https://github.com/sh2d/spelling/issues/). Patches
+welcome!
+
+
+_Happy TeXing!_
+
+
+
+### File list
+
+ CHANGES
+ LICENSE
+ README
+ spelling.sty
+ spelling-doc.bad
+ spelling-doc.tex
+ spelling-doc-lst-lua.tex
+ spelling-main.lua
+ spelling-recurse.lua
+ spelling-stage-1.lua
+ spelling-stage-2.lua
+ spelling-stage-3.lua
+ spelling-stage-4.lua
+
+
+
+<!--
+%%% Local Variables:
+%%% coding: utf-8
+%%% mode: markdown
+%%% End:
+-->
diff --git a/macros/luatex/generic/spelling/spelling-doc-lst-lua.tex b/macros/luatex/generic/spelling/spelling-doc-lst-lua.tex
new file mode 100644
index 0000000000..4fee01d300
--- /dev/null
+++ b/macros/luatex/generic/spelling/spelling-doc-lst-lua.tex
@@ -0,0 +1,84 @@
+%%% spelling-doc-lst-lua.tex
+%%% Copyright 2013 Stephan Hennig
+%%
+%% This work may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.3 of this license
+%% or (at your option) any later version. The latest version of this
+%% license is in http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+\lstdefinelanguage[5.2]{Lua}{%
+ alsoletter={.},%
+ % language keywords
+ morekeywords=[1]{%
+ and,break,do,else,elseif,end,%
+ false,for,function,goto,if,in,%
+ local,nil,not,or,repeat,return,%
+ then,true,until,while,%
+ },%
+ % standard library identifiers
+ morekeywords=[2]{%
+ % basic library
+ assert,collectgarbage,dofile,error,_G,getmetatable,ipairs,%
+ load,loadfile,next,pairs,pcall,print,rawequal,rawget,rawlen,rawset,%
+ select,setmetatable,tonumber,tostring,type,_VERSION,xpcall,%
+ % coroutine library
+ coroutine.create,coroutine.resume,coroutine.running,%
+ coroutine.status,coroutine.wrap,coroutine.yield,%
+ % package library
+ require,package.config,package.cpath,package.loaded,%
+ package.loadlib,package.path,package.preload,package.searchers,%
+ package.searchpath,%
+ % string library
+ string.byte,string.char,string.dump,string.find,string.format,%
+ string.gmatch,string.gsub,string.len,string.lower,string.match,%
+ string.rep,string.reverse,string.sub,string.upper,%
+ % table library
+ table.concat,table.insert,table.pack,table.remove,table.sort,%
+ table.unpack,%
+ % mathematical library
+ math.abs,math.acos,math.asin,math.atan,math.atan2,math.ceil,%
+ math.cos,math.cosh,math.deg,math.exp,math.floor,math.fmod,%
+ math.frexp,math.huge,math.ldexp,math.log,math.max,math.min,%
+ math.modf,math.pi,math.pow,math.rad,math.random,math.randomseed,%
+ math.sin,math.sinh,math.sqrt,math.tan,math.tanh,%
+ % bit library
+ bit32.arshift,bit32.band,bit32.bnot,bit32.bor,bit32.btest,%
+ bit32.bxor,bit32.extract,bit32.replace,bit32.lrotate,bit32.lshift,%
+ bit32.rrotate,bit32.rshift,%
+ % io library
+ io.close,io.flush,io.input,io.lines,io.open,io.output,io.popen,%
+ io.read,io.stderr,io.stdin,io.stdout,io.tmpfile,io.type,io.write,%
+ % os library
+ os.clock,os.date,os.difftime,os.execute,os.exit,os.getenv,%
+ os.remove,os.rename,os.setlocale,os.time,os.tmpname,%
+ % debug library
+ debug.debug,debug.gethook,debug.getinfo,debug.getlocal,%
+ debug.getmetatable,debug.getregistry,debug.getupvalue,%
+ debug.getuservalue,debug.sethook,debug.setlocal,debug.setmetatable,%
+ debug.setupvalue,debug.setuservalue,debug.traceback,%
+ debug.upvalueid,debug.upvaluejoin,%
+ },%
+ % add environment
+ morekeywords=[2]{_ENV},%
+ %
+ sensitive=true,%
+ % single line comments
+ morecomment=[l]{--},%
+ % multi line comments
+ morecomment=[s]{--[[}{]]},%
+ morecomment=[s]{--[=[}{]=]},%
+ morecomment=[s]{--[==[}{]==]},%
+ morecomment=[s]{--[===[}{]===]},%
+ % backslash escaped strings
+ morestring=[b]",%
+ morestring=[b]',%
+ % multi line strings
+ morestring=[s]{[[}{]]},%
+ morestring=[s]{[=[}{]=]},%
+ morestring=[s]{[==[}{]==]},%
+ morestring=[s]{[===[}{]===]},%
+ % labels
+ moredelim=[s][keywordstyle3]{::}{::},%
+}[keywords,comments,strings]%
diff --git a/macros/luatex/generic/spelling/spelling-doc.bad b/macros/luatex/generic/spelling/spelling-doc.bad
new file mode 100644
index 0000000000..9e34486307
--- /dev/null
+++ b/macros/luatex/generic/spelling/spelling-doc.bad
@@ -0,0 +1,4 @@
+Ther
+mispellings
+spellling
+foo’s
diff --git a/macros/luatex/generic/spelling/spelling-doc.pdf b/macros/luatex/generic/spelling/spelling-doc.pdf
new file mode 100644
index 0000000000..527d70d6ac
--- /dev/null
+++ b/macros/luatex/generic/spelling/spelling-doc.pdf
Binary files differ
diff --git a/macros/luatex/generic/spelling/spelling-doc.tex b/macros/luatex/generic/spelling/spelling-doc.tex
new file mode 100644
index 0000000000..79e59b2aec
--- /dev/null
+++ b/macros/luatex/generic/spelling/spelling-doc.tex
@@ -0,0 +1,830 @@
+%%% spelling-doc.tex
+%%% Copyright 2012, 2013 Stephan Hennig
+%%
+%% This work may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.3 of this license
+%% or (at your option) any later version. The latest version of this
+%% license is in http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% See file README for more information.
+%%
+\documentclass[11pt]{article}
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures=TeX}
+\usepackage{multicol}
+\usepackage[rgb, x11names]{xcolor}
+\usepackage{listings}
+\input{\jobname-lst-lua.tex}
+\lstset{
+ basicstyle=\ttfamily,
+ columns=spaceflexible,
+}
+% Short-cut for non-language code snippets.
+\lstMakeShortInline\|
+% Short-cut for LaTeX code snippets.
+\lstMakeShortInline[
+language={[LaTeX]TeX},
+basicstyle=\ttfamily,
+]°
+\lstdefinestyle{Lua}{
+ language=[5.2]Lua,
+ keywordstyle=\bfseries\color{Blue4},
+ keywordstyle=[2]\bfseries\color{RoyalBlue3},
+ keywordstyle=[3]\bfseries\color{Purple3},
+ stringstyle=\bfseries\color{Coral4},
+ commentstyle=\itshape\color{Green4},
+}
+\usepackage{xspace}
+\usepackage{array}
+\usepackage{booktabs}
+\usepackage[latin, UKenglish]{babel}
+\usepackage{hyperref}
+\hypersetup{
+ pdftitle={spelling},
+ pdfauthor={Stephan Hennig},
+ pdfkeywords={spell-checking, spelling, TeX, LuaTeX}
+}
+\hypersetup{
+ english,% For \autoref.
+ pdfstartview={XYZ null null null},% Zoom factor is determined by viewer.
+ colorlinks,
+ linkcolor=RoyalBlue3,
+ urlcolor=Chocolate4,
+ citecolor=DeepPink2
+}
+\usepackage{spelling}
+\spellingreadbad{\jobname.bad}
+\newcommand*{\pkg}{\textsf{spelling}}
+\newcommand*{\acr}[1]{\mbox{\scshape#1}}
+\newcommand*{\descr}[1]{〈\emph{#1}〉}
+\newcommand*{\cmd}[1]{\mbox{\ttfamily\textbackslash#1}}
+\newcommand*{\macro}[1]{\cmd{#1}\marginpar{\cmd{#1}}}
+\newcommand*{\latinphrase}[1]{\foreignlanguage{latin}{\emph{#1}}}
+\newcommand*{\lpcf}{\latinphrase{cf.}\xspace}
+\newcommand*{\lpeg}{\latinphrase{e.\,g.}\xspace}
+\newcommand*{\lpetc}{\latinphrase{etc.}\xspace}
+\newcommand*{\lpie}{\latinphrase{i.\,e.}\xspace}
+\begin{document}
+\author{Stephan Hennig\thanks{sh2d@arcor.de}}
+\title{\pkg\thanks{This document describes the \pkg\ package v0.41.}}
+\maketitle
+
+
+\begin{abstract}
+ This package supports spell-checking of \TeX\ documents compiled with
+ the Lua\TeX\ engine. It can give visual feedback in \acr{pdf} output
+ similar to \acr{wysiwyg} word processors. The package relies on an
+ external spell-checker application that can check a plain text file
+ and output a list of bad spellings. The package should work with most
+ spell-checkers, even dumb, \TeX-unaware ones.
+
+ \emph{Warning! This package is in a very early state. Everything may
+ change!}
+\end{abstract}
+
+\begin{multicols}{2}
+\small
+% Set toc entries ragged right. Trick taken from tocloft.pdf.
+\makeatletter
+\renewcommand{\@tocrmarg}{2.55em plus1fil}
+\makeatother
+\tableofcontents
+\end{multicols}
+
+
+\section{Introduction}
+\label{sec:intro}
+
+Ther%
+\footnote{A footnote containing mispellings.}
+%
+are three main approaches to spell-checking \TeX\ documents:
+
+\begin{enumerate}
+
+\item checking spelling in the |.tex| source file,
+
+\item converting a |.tex| file to another format, for which a proved
+ spell-checking solution exists,
+
+\item checking spelling after a |.tex| file has been processed by \TeX.
+
+\end{enumerate}
+
+All of these approaches have their strengths and weaknesses. This
+package follows the third approach, providing some unique features:
+
+\begin{itemize}
+
+\item In traditional solutions, text is extracted from typeset
+ \acr{dvi}, \acr{ps} or \acr{pdf} files, including hyphenated words.
+ To avoid (lots of) false positives being reported by the
+ spell-checker, hyphenation needs to be switched off during the \TeX\
+ run. That is, one doesn't work on the original document any more.
+
+ In contrast to that, the \pkg\ package works transparently on the
+ original |.tex| source file. Text is extracted \emph{during}
+ typesetting, after Lua\TeX\ has applied its catcode and macro
+ machinery, but before hyphenation takes place.
+
+\item The \pkg\ package can highlight words with known incorrect
+ spelling in \acr{pdf} output, giving visual feedback similar to
+ \acr{wysiwyg} word processors.%
+ \footnote{Currently, only colouring words is implemented.}
+
+\end{itemize}
+
+
+\section{Usage}
+\label{sec:usage}
+
+The \pkg\ package requires the Lua\TeX\ engine. All functionality of
+the package is implemented in Lua. The \LaTeX\ interface, which is
+described below, is effectively a wrapper around the Lua interface.
+
+\emph{Implementing such wrappers for other formats shouldn't be too
+ difficult. The author is a \LaTeX-only user, though, and therefore
+ grateful for contributions. By the way, the \LaTeX\ package needs
+ some polishing, too, \lpeg, a key-value interface is desirable.
+ Patches welcome!}
+
+
+\subsection{Work-flow}
+\label{sec:work-flow}
+
+Here's a short outline of how using the \pkg\ package fits into the
+general process of compiling a document with Lua\TeX:
+
+\begin{enumerate}
+
+\item After loading the package in the preamble of a |.tex| source file,
+ a list of bad spellings is read from a file (if that file exists).
+
+\item During the Lua\TeX\ run, text is extracted from pages and all
+ words are checked against the list of bad spellings. Words with a
+ known incorrect spelling are highlighted in \acr{pdf} output.
+
+\item At the end of the Lua\TeX\ run, in addition to the \acr{pdf} file,
+ a text file is written, containing most of the text of the typeset
+ document.
+
+\item The text file is then checked by your favourite external
+ spell-checker application, \lpeg, Aspell or Hunspell. The
+ spell-checker should be able to write a list of bad spellings to a
+ file. Otherwise, visual feedback in \acr{pdf} output won't work.
+
+\item Visually minded people may now compile their document a second
+ time. This time, the new list of bad spellings is read-in and words
+ with incorrect spelling found by the spell-checker should now be
+ highlighted in \acr{pdf} output. Users can then apply the necessary
+ corrections to the |.tex| source file.
+
+\end{enumerate}
+
+Whatever way spell-checker output is employed, users not interested in
+visual feedback (because their spell-checker has an interactive mode
+only or because they prefer grabbing bad spellings from a file directly)
+can also benefit from this package. Using it, Lua\TeX\ writes a pure
+text file that is particularly well suited as spell-checker input,
+because it contains no hyphenated words (and neither macros, nor active
+characters). That way, any spell-checker application, even \TeX-unaware
+ones, can be used to check spelling of \TeX\ documents.
+
+
+\subsection{Word lists}
+\label{sec:wordlists}
+
+As described above, after loading the \pkg\ package, a list of bad
+spellings is read from a file \descr{jobname}.|spell.bad|, if that file
+exists. Words found in this file are stored in an internal list of bad
+spellings and are later used for highlighting spelling mistakes in
+\acr{pdf} output. Additionally, a list of good spellings is read from a
+file \descr{jobname}|.spell.good|, if that file exists. Words found in
+the latter file are stored in an internal list of good spellings. File
+format for both files is one word per line. Files must be in the
+\acr{utf-8} encoding. Letter case is significant.
+
+A word in the document is highlighted, if it occurs in the internal list
+of bad spellings, but not in the internal list of good spellings. That
+is, known good spellings take precedence over known bad spellings.
+
+Users can load additional files containing lists of bad or good
+spellings with macros \macro{spellingreadbad} and
+\macro{spellingreadgood}. Argument to both macros is a file name. If a
+file cannot be found, a warning is written to the console and |log| file
+and compilation continues. As an example, the command
+
+\begin{lstlisting}[language={[LaTeX]TeX}]
+\spellingreadgood{myproject.whitelist}
+\end{lstlisting}
+%
+reads words from a file |myproject.whitelist| and adds them to the list
+of good spellings.
+
+Known good spellings can be used to deal with words wrongly reported as
+bad spellings by the spell-checker (false positives). But note, most
+spell-checkers also provide means to deal with unknown words via
+additional dictionaries. It is recommended to configure your
+spell-checker to report as few false positives as possible.
+
+
+\subsection{Match rules}
+\label{sec:matchrules}
+
+\emph{This section describes an advanced feature. You may safely skip
+ this section upon first reading.}
+
+The \pkg\ package provides an additional way to deal with bad and good
+spellings, match rules. Match rules can be used to employ regular
+patterns within certain ‘words’. A typical example are bibliographic
+references like \emph{Lin86}, which are often flagged by spell-checkers,
+but need not be highlighted as they are generated by \TeX.
+
+There are two kinds of rules, bad and good rules. A rule is a Lua
+function whose boolean return value indicates whether a word
+\emph{matches} the rule. A bad rule should return a true value for all
+strings identified as bad spellings, otherwise a false value. A good
+rule should return a true value for all strings identified as good
+spellings, otherwise a false value. A word in the document is
+highlighted if it matches any bad rule, but no good rule.
+
+Function arguments are a \emph{raw} string and a \emph{stripped} string.
+The raw string is a string representing a word as it is found in the
+document possibly surrounded by punctuation characters. The stripped
+string is the same string with surrounding punctuation already stripped.
+
+As an example, the rule in \autoref{lst:mr-three-letter-words} matches
+all words consisting of exactly three letters. The function matches the
+stripped string against the Lua string pattern |^%a%a%a$| via function
+|unicode.utf8.find| from the Selene Unicode library. The latter
+function is a \acr{utf-8} capable version of Lua's built-in function
+|string.find|. It returns |nil| (a false value) if there has been no
+match and a number (a true value) if there has been a match. The
+pattern |%a| represents a character class matching a single letter.
+Characters |^| and |$| are anchors for the beginning and the end of the
+string in question. Note, pattern |%a%a%a| without anchors would match
+any string containing three letters in a row. More information about
+Lua string patterns can be found in the Lua reference manual%
+\footnote{\url{http://www.lua.org/manual/5.2/manual.html\#6.4}}%
+%
+, the Selene Unicode library documentation%
+\footnote{\url{https://github.com/LuaDist/slnunicode/blob/master/unitest}}
+%
+and in the Unicode standard%
+\footnote{\url{http://www.unicode.org/Public/4.0-Update1/UCD-4.0.1.html\#General_Category_Values}}%
+.
+
+\suppressfloats[b]
+
+\begin{lstlisting}[style=Lua, float, label=lst:mr-three-letter-words, caption={Matching three-letter words.}]
+function three_letter_words(raw, stripped)
+ return unicode.utf8.find(stripped, '^%a%a%a$')
+end
+\end{lstlisting}
+
+\autoref{lst:mr-double-punctuation} shows a rule matching all ‘words’
+containing double punctuation. Note, how the raw string is examined
+instead of the stripped one.
+
+\begin{lstlisting}[style=Lua, float, label=lst:mr-double-punctuation, caption={Matching double punctuation.}]
+function double_punctuation(raw, stripped)
+ return unicode.utf8.find(raw, '%p%p')
+end
+\end{lstlisting}
+
+The rule in \autoref{lst:mr-bibtex-alpha} combines the results of three
+string searches to match bibliographic references as generated by the
+Bib\TeX\ style \emph{alpha}.
+
+\begin{lstlisting}[style=Lua, float, label=lst:mr-bibtex-alpha, caption={Matching references generated by the Bib\TeX\ style \emph{alpha}.}]
+function bibtex_alpha(raw, stripped)
+ return unicode.utf8.find(stripped, '^%u%l%l?%d%d$')
+ or unicode.utf8.find(stripped, '^%u%u%u?%u?%d%d$')
+ or unicode.utf8.find(stripped, '^%u%u%u%+%d%d$')
+end
+\end{lstlisting}
+
+Match rules have to be provided by means of a Lua module. Such modules
+can be loaded with the \macro{spellingmatchrules} command. Argument is
+a module name. To tell bad rules from good rules, the table returned by
+the module must follow this convention: Function identifiers
+representing bad and good match rules are prefixed |bad_rule_| and
+|good_rule_|, resp. The rest of an identifier is actually irrelevant.
+Other and non-function identifiers are ignored.
+
+\autoref{lst:mr-module} shows an example module declaring the rules from
+\autoref{lst:mr-three-letter-words} and
+\autoref{lst:mr-double-punctuation} as \emph{bad} match rules and the
+rule from \autoref{lst:mr-bibtex-alpha} as a \emph{good} match rule.
+Note, how function identifiers are made local and how exported function
+identifiers are prefixed |bad_rule_| and |good_rule_|, while local
+function identifiers have no prefixes. When the module resides in a
+file named |myproject.rules.lua|, it can be loaded in the preamble of a
+document via
+\begin{lstlisting}[language={[LaTeX]TeX}]
+\spellingmatchrules{myproject.rules}
+\end{lstlisting}
+
+\begin{lstlisting}[style=Lua, float=p, label=lst:mr-module, caption={A Lua module containing two bad and one good match rule.}]
+-- Module table.
+local M = {}
+
+-- Import Selene Unicode library.
+local unicode = require('unicode')
+-- Add short-cut.
+local Ufind = unicode.utf8.find
+
+-- Local function matching three letter words.
+local function three_letter_words(raw, stripped)
+ return Ufind(stripped, '^%a%a%a$')
+end
+-- Make this a bad rule.
+M.bad_rule_three_letter_words = three_letter_words
+
+local function double_punctuation(raw, stripped)
+ return Ufind(raw, '%p%p')
+end
+M.bad_rule_double_punctuation = double_punctuation
+
+local function bibtex_alpha(raw, stripped)
+ return Ufind(stripped, '^%u%l%l?%d%d$')
+ or Ufind(stripped, '^%u%u%u?%u?%d%d$')
+ or Ufind(stripped, '^%u%u%u%+%d%d$')
+end
+M.good_rule_bibtex_alpha = bibtex_alpha
+
+-- Export module table.
+return M
+\end{lstlisting}
+
+How are match rules and lists of bad and good spellings related?
+Internally, the lists of bad and good spellings are referred to by two
+special default match rules, that look-up raw and stripped strings and
+return a true value if either argument has been found in the
+corresponding list. Since good rules take precedence over bad rules, an
+entry in the list of good spellings takes precedence over any
+user-supplied bad rule. Likewise, any user-supplied good rule takes
+precedence over an entry in the list of bad spellings.
+
+\paragraph{Some final remarks on match rules} It must be stressed that
+the boolean return value of a match rule \emph{does not} indicate
+whether a spelling is bad or good, but whether a word matches a certain
+rule or not. Whether it's a bad or a good spelling, depends on the name
+of the match rule in the module table.
+
+Match rules are only called upon the first occurrence of a spelling in a
+document. The information, whether a spelling needs to be highlighted,
+is stored in a cache table. Subsequent occurrences of a spelling just
+need a table look-up to determine highlighting status. For that reason,
+it is safe to do relatively expensive operations within a match rule
+without affecting compilation time too much. Nevertheless, match rules
+should be stated as efficient as possible.%
+\footnote{Some Lua performance tips can be found in the book \emph{Lua
+ Programming Gems} by Figueiredo, Celes and Ierusalimschy
+ \emph{(eds.)}, 2008, ch.~2. That chapter is also available online at
+ \url{http://www.lua.org/gems/}.}
+
+When written without care, match rules can easily produce false
+positives as well as false negatives. While false positives in bad
+rules and false negatives in good rules can easily be spotted due to the
+unexpected highlighting of words, the other cases are more problematic.
+To avoid all kinds of false results, match rules should be stated as
+specific as possible.
+
+
+\subsection{Highlighting spellling mistakes}
+\label{sec:highlight}
+
+\paragraph{Enabling/disabling} Highlighting spelling mistakes (words
+with known incorrect spelling) in \acr{pdf} output can be toggled on and
+off with command \macro{spellinghighlight}. If the argument is |on|,
+highlighting is enabled. For other arguments, highlighting is disabled.
+Highlighting is enabled, by default.
+
+\paragraph{Colour} The colour used for highlighting bad spellings can be
+determined by command \cmd{spellinghighlightcolor}. Argument is a
+colour statement in the \acr{pdf} language. As an example, the colour
+red in the \acr{rgb} colour space is represented by the statement %
+|1 0 0 rg|. In the \acr{cmyk} colour space, a reddish colour is
+represented by |0 1 1 0 k|. Default colour used for highlighting is %
+|1 0 0 rg|, \lpie, red in the \acr{rgb} colour space.
+
+
+\subsection{Text output}
+\label{sec:textoutput}
+
+\paragraph{Text file} After loading the \pkg\ package, at the end of the
+Lua\TeX\ run, a text file is written that contains most of the document
+text. The text file is no close text rendering of the typeset document,
+but serves as input for your favourite spell-checker application. It
+contains the document text in a simple format: paragraphs separated by
+blank lines. A paragraph is anything that, during typesetting, starts
+with a |local_par| whatsit node in the node list representing a typeset
+page of the original document, \lpeg, paragraphs in running text,
+footnotes, marginal notes, (in-lined) °\parbox° commands or cells from
+°p°-like table columns \lpetc
+
+Paragraphs consist of words separated by spaces. A word is the textual
+representation of a chain of consecutive nodes of type |glyph|, |disc|
+or |kern|. Boxes are processed transparently. That is, the \pkg\
+package (highly imperfectly) tries to recognise as a single word what in
+typeset output looks like a single word. As an example, the \LaTeX\
+code
+
+\begin{center}
+ \begin{tabular}{c}
+\begin{lstlisting}[language={[LaTeX]TeX}]
+foo\mbox{'s bar}s
+\end{lstlisting}
+ \end{tabular}
+\end{center}
+which is typeset as
+
+\begin{center}
+ foo\mbox{'s bar}s
+\end{center}
+is considered two words \textit{foo's} and \textit{bars}, instead of the
+four words \textit{foo}, \textit{'s}, \textit{bar} and~\textit{s}.%
+\footnote{This document has been compiled with a custom list of bad
+ spellings, which is why the word \emph{foo's} should be highlighted.}
+
+\paragraph{Enabling/disabling} Text output can be toggled on and off
+with command \macro{spellingoutput}. If the argument is |on|, text
+output is enabled. For other arguments, text output is disabled. Text
+output is enabled, by default.
+
+\paragraph{File name} \hspace{0pt plus 5em} Text output file name can be
+configured via command \macro{spellingoutputname}. Argument is the new
+file name. Default text output file name is
+\descr{jobname}|.spell.txt|.
+
+\paragraph{Line length} In text output, paragraphs can either be put on
+a single line or broken into lines of a fixed length. The behaviour can
+be controlled via command \macro{spellingoutputlinelength}. Argument is
+a number. If the number is less than~1, paragraphs are put on a single
+line. For larger arguments, the number specifies maximum line length.
+Note, lines are broken at spaces only. Words longer than maximum line
+length are put on a single line exceeding maximum line length. Default
+line length is~72.
+
+
+\subsection{Text extraction}
+\label{sec:textextraction}
+
+\paragraph{Enabling/disabling} Text extraction can be enabled and
+disabled in the document via command \macro{spellingextract}. If the
+argument is |on|, text extraction is enabled. For other arguments, text
+extraction is disabled. The command should be used in vertical mode,
+\lpie, outside paragraphs. If text extraction is disabled in the
+document preamble, an empty text file is written at the end of the
+Lua\TeX\ run. Text extraction is enabled, by default.
+
+Note, text extraction and visual feedback are orthogonal features. That
+is, if text extraction is disabled for part of a document, \lpeg, a long
+table, words with a known incorrect spelling are still highlighted in
+that part.
+
+
+\subsection{Code point mapping}
+\label{sec:cp-mapping}
+
+As explained in \autoref{sec:textoutput}, the text file written at the
+end of the Lua\TeX\ run is in the \acr{utf-8} encoding. Unicode
+contains a wealth of code points with a special meaning, such as
+ligatures, alternative letters, symbols \lpetc Unfortunately, not all
+spell-checker applications are smart enough to correctly interpret all
+Unicode code points that may occur in a document. For that reason, a
+code point mapping feature has been implemented that allows for mapping
+certain Unicode code points that may appear in a node list to arbitrary
+strings in text output. A typical example is to map ligatures to the
+characters corresponding to their constituting letters. The default
+mappings applied can be found in \autoref{tab:cp-mapping}.
+
+\begin{table}
+ \begin{minipage}{1.0\linewidth}
+ \centering
+
+ \newcommand*{\coltitle}[2]{%
+ \normalfont%
+ \vbox{
+ \hbox{\strut#1}
+ \hbox{\strut#2}
+ }%
+ }
+
+ \begin{tabular}{>{\ttfamily}l>{\fontspec{Linux Libertine
+ O}}l>{\ttfamily}l>{\ttfamily}l}
+ \normalfont Unicode name & \coltitle{sample}{glyph\footnote{Sample
+ glyphs are taken from font \emph{Linux Libertine~O}.}} &
+ \coltitle{code}{point} & \coltitle{target}{characters}\\
+ \addlinespace
+ \toprule
+ \addlinespace
+
+ LATIN CAPITAL LIGATURE IJ & ^^^^0132 & 0x0132 & IJ \\
+ LATIN SMALL LIGATURE IJ & ^^^^0133 & 0x0133 & ij \\
+ LATIN CAPITAL LIGATURE OE & ^^^^0152 & 0x0152 & OE \\
+ LATIN SMALL LIGATURE OE & ^^^^0153 & 0x0153 & oe \\
+ LATIN SMALL LETTER LONG S & ^^^^017f & 0x017f & s \\
+ \addlinespace
+ LATIN SMALL LIGATURE FF & ^^^^fb00 & 0xfb00 & ff \\
+ LATIN SMALL LIGATURE FI & ^^^^fb01 & 0xfb01 & fi \\
+ LATIN SMALL LIGATURE FL & ^^^^fb02 & 0xfb02 & fl \\
+ LATIN SMALL LIGATURE FFI & ^^^^fb03 & 0xfb03 & ffi \\
+ LATIN SMALL LIGATURE FFL & ^^^^fb04 & 0xfb04 & ffl \\
+ LATIN SMALL LIGATURE LONG S T & ^^^^fb05 & 0xfb05 & st \\
+ LATIN SMALL LIGATURE ST & ^^^^fb06 & 0xfb06 & st \\
+ \end{tabular}
+
+ \caption{Default code point mappings.}
+ \label{tab:cp-mapping}
+
+ \end{minipage}
+\end{table}
+
+Additional mappings can be declared by command \macro{spellingmapping}.
+This command takes two arguments, a number that refers to the Unicode
+code point, and a sequence of arbitrary characters that is the mapping
+target. The code point number must be in a format that can be parsed by
+Lua. The characters must be in the \acr{utf-8} encoding.
+
+New mappings only have effect on the following document text. The
+command should therefore be used in the document preamble. As an
+example, the character |A| can be mapped to |Z| and \latinphrase{vice
+ versa} with the following code:
+
+\begin{lstlisting}[language={[LaTeX]TeX}]
+\spellingmapping{65}{Z}% A => Z
+\spellingmapping{90}{A}% Z => A
+\end{lstlisting}
+
+Another command \macro{spellingclearallmappings} can be used to remove
+all existing code point mappings.
+
+
+\subsection{Tables}
+\label{sec:tables}
+
+How do tables fit into the simple text file format that has only
+paragraphs and blank lines as described in \autoref{sec:textoutput}?
+What is a paragraph with regards to tables? A whole table? A row? A
+single cell?
+
+By default, only text from cells in °p°(aragraph)-like columns is put on
+their own paragraph, because the corresponding node list branches
+contain a |local_par| whatsit node (\lpcf \autoref{sec:textoutput}).
+The behaviour can be changed with the \macro{spellingtablepar} command.
+This command takes as argument a number. If the argument is~0, the
+behaviour is described as above. If the argument is~1, a blank line is
+inserted before and after every table row (but at most once between
+table rows). If the argument is~2, a blank line is inserted before and
+after every table cell. By default, no blank lines are inserted.
+
+
+\section{LanguageTool support}
+\label{sec:languagetool}
+
+Installing spell-checkers and dictionaries can be a difficult task if
+there are no pre-built packages available for an architecture. That's
+one reason the \pkg\ package is rather spell-checker agnostic and the
+manual doesn't recommend a particular spell-checker application.
+Another reason is, there is no best spell-checker. The only
+recommendation the author makes is not to trust in one spell-checker,
+but to use multiple spell-checkers at the same time, with different
+dictionaries or, better yet, different checking engines under the hood.
+
+Among the set of options available, LanguageTool%
+\footnote{\url{http://www.languagetool.org/}}%
+%
+, a style and grammar checker that can also check spelling since
+version~1.8, deserves some notice for its portability, ease of
+installation and active development. For these reasons, the \pkg\
+package provides explicit LanguageTool support. LanguageTool uses
+Hunspell as the spell-checking engine, augmenting results with a rule
+based engine and a morphological analyser (depending on the language).
+The \pkg\ package can parse LanguageTool's error reports in the
+\acr{xml} format, pick those errors that are spelling related and use
+them to highlight bad spellings.%
+\footnote{Highlighting style and grammar errors found by LanguageTool
+ should be possible, but requires major restructuring of the \pkg\
+ package.}
+
+
+\subsection{Installation}
+\label{sec:lt-installation}
+
+Here are some brief installation instructions for the stand-alone
+version of LanguageTool (tested with LanguageTool~2.1). The stand-alone
+version contains a \acr{gui} as well as a command-line interface. For
+the \pkg\ package, the latter is needed.
+
+\begin{enumerate}
+
+\item LanguageTool is primarily written in Java. Make sure a recent
+ Java Runtime Environment (\acr{jre}) is installed.
+
+\item\label{enum:run-java} Open a command-line and type
+
+\begin{lstlisting}
+java -version
+\end{lstlisting}
+%
+ If you get an error message, find out the full path to the Java
+ executable (called |java.exe| on Windows) for later reference.
+
+\item Download the stand-alone version of LanguageTool (should be a
+ \acr{zip} archive).
+
+\item Uncompress the downloaded archive to a location of your choice.
+
+\item Open a command-line in the directory containing file
+ |languagetool-commandline.jar| and type
+
+\begin{lstlisting}[escapeinside=°°]
+°\descr{path to}°/java -jar languagetool-commandline.jar --help
+\end{lstlisting}
+%
+ Prepending the path to the Java executable is optional, depending on
+ the result in step~\ref{enum:run-java}. If you now see a list of
+ LanguageTool's command-line options rush by, all is well.
+
+\item For easier access to LanguageTool, create a small batch script and
+ put that somewhere into the |PATH|.
+
+ \begin{itemize}
+
+ \item For users of unixoide systems, the script might look like
+
+\begin{lstlisting}[escapeinside=°°]
+#!/bin/sh
+°\descr{path to}°/java -jar °\descr{path to}°/languagetool-commandline.jar $*
+\end{lstlisting}
+%
+ where \texttt{\descr{path to}} should point to the Java executable
+ (optional) and file |languagetool-commandline.jar| (mandatory). If
+ the script is named |lt.sh|, you should be able to run LanguageTool
+ on the command shell by typing, \lpeg,
+
+\begin{lstlisting}
+sh lt.sh --version
+\end{lstlisting}
+%
+ Don't forget to put the script into the |PATH|! For other ways of
+ making scripts executable, please consult the operating system
+ documentation.
+
+ \item For Windows users, the script might look like
+
+\begin{lstlisting}[escapeinside=°°]
+@echo off
+°\descr{path to}°\java -jar °\descr{path to}°\languagetool-commandline.jar %*
+\end{lstlisting}
+%
+ where \texttt{\descr{path to}} should point to the Java executable
+ (optional) and file |languagetool-commandline.jar| (mandatory). If
+ the script is named |lt.bat|, you should be able to run LanguageTool
+ on the command-line by typing, \lpeg,
+
+\begin{lstlisting}
+lt --version
+\end{lstlisting}
+%
+ Don't forget to put the script into the |PATH|!
+
+ \end{itemize}
+
+\end{enumerate}
+
+
+\subsection{Usage}
+\label{sec:lt-usage}
+
+The results of checking a text file with LanguageTool are written to an
+error report, either in a human readable format or in a machine friendly
+\acr{xml} format. The \pkg\ package can only parse the latter format.
+When it was said in \autoref{sec:wordlists} that the \pkg\ package reads
+files \descr{jobname}|.spell.bad| and \descr{jobname}|.spell.good|, if
+they exist, that was not the whole truth. Additionally, a file
+\descr{jobname}|.spell.xml| is read, if it exists. This file should
+contain a LanguageTool error report in the \acr{xml} format. Additional
+LanguageTool \acr{xml} error reports can be loaded via the
+\macro{spellingreadLT} command. Argument is a file name. Macros
+|\spellingreadLT|, |\spellingreadbad| and |\spellingreadgood| can be
+used in combination in a \TeX\ file.
+
+To check a text file and create an error report in the \acr{xml} format,
+LanguageTool can be called on the command-line like this
+\begin{lstlisting}[escapeinside=°°]
+lt °\descr{options}° °\descr{input file}° > °\descr{error report}°
+\end{lstlisting}
+where \texttt{\descr{options}} is a list of options described below,
+\texttt{\descr{input file}} is the text file written by the \pkg\
+package in the first Lua\TeX\ run and \texttt{\descr{error report}} is
+the file containing the error report. Note, how standard output is
+redirected to a file via the |>| operator. By default, LanguageTool
+writes error reports to standard output, that is, the command-line.
+Redirection is a feature most operating systems provide.
+
+\begin{itemize}
+
+\item Option |-l| determines the language (variant) of the file to
+ check. As an example, language variant US English can be selected via
+ |-l en-US|. The full list of languages supported by LanguageTool can
+ be requested via option |--list|.
+
+\item Option |-c| determines the encoding of the input file. Since the
+ text file written by the \pkg\ package is in the \acr{utf-8} encoding,
+ this part should be |-c utf-8|.
+
+\item By default, LanguageTool outputs error reports in a human readable
+ format. The \pkg\ package can only parse error reports in the
+ \acr{xml} format. If the |--api| option is present, LanguageTool
+ outputs \acr{xml} data.
+
+\item Users that don't want to highlight bad spellings, but prefer to
+ study the list of bad spellings themselves, should refer to the |-u|
+ option. But note, that with the latter option present, LanguageTool
+ doesn't output pure \acr{xml} any more, even if the |--api| option is
+ present. Make sure such error reports aren't read by the \pkg\
+ package.
+
+\item If the |--help| option is present, LanguageTool shows more
+ information about command-line options.
+
+\end{itemize}
+
+As an example, to compile a \LaTeX\ file |myletter.tex| written in
+French that uses the \pkg\ package with standard settings to highlight
+bad spellings and to use LanguageTool as a spell-checker, the following
+commands should be typed on the command-line:
+
+\begin{lstlisting}
+lualatex myletter
+lt --api -c utf-8 -l fr myletter.spell.txt > myletter.spell.xml
+lualatex myletter
+\end{lstlisting}
+
+
+\section{Bugs}
+\label{sec:bugs}
+
+Note, this package is in a very early state. Expect bugs! Package
+development is hosted at
+\href{http://github.com/sh2d/spelling/}{\bfseries GitHub}. The full
+list of known bugs and feature requests can be found in the
+\href{http://github.com/sh2d/spelling/issues/}{\bfseries issue tracker}.
+New bugs should be reported there.
+
+The most user-visible issues are listed below:
+
+\begin{itemize}
+
+\item There's no support for the Plain \TeX\ or Con\TeX\ formats other
+ than the \acr{API} of the package's Lua modules, yet
+ (\href{https://github.com/sh2d/spelling/issues/1}{issue~1}).
+
+\item Macros provided by the \LaTeX\ package have very long names. A
+ \emph{key-value} package option interface would be much more
+ user-friendly
+ (\href{https://github.com/sh2d/spelling/issues/2}{issue~2}).
+
+\item There are a couple of issues with text extraction and highlighting
+ incorrect spellings:
+
+ \begin{itemize}
+
+ \item Text in head and foot lines is neither extracted nor highlighted
+ (\href{https://github.com/sh2d/spelling/issues/7}{issue~7}).
+
+ \item The first word starting right after an |hlist|, \lpeg, the first
+ word within an |\mbox|, is never highlighted. It is extracted and
+ written to the text file, though. This might affect acronyms, names
+ \lpetc (\href{https://github.com/sh2d/spelling/issues/6}{issue~6}).
+
+ \item Bad spellings that are hyphenated at a page break are not
+ highlighted
+ (\href{https://github.com/sh2d/spelling/issues/10}{issue~10}).
+
+ \end{itemize}
+
+
+\end{itemize}
+
+Patches welcome!
+
+\bigskip
+\emph{Happy \TeX ing!}
+
+
+\end{document}
+
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-PDF-mode: t
+%%% TeX-master: t
+%%% coding: utf-8
+%%% End:
diff --git a/macros/luatex/generic/spelling/spelling-main.lua b/macros/luatex/generic/spelling/spelling-main.lua
new file mode 100644
index 0000000000..8aaecbda0c
--- /dev/null
+++ b/macros/luatex/generic/spelling/spelling-main.lua
@@ -0,0 +1,220 @@
+--- spelling-main.lua
+--- Copyright 2012, 2013 Stephan Hennig
+--
+-- This work may be distributed and/or modified under the conditions of
+-- the LaTeX Project Public License, either version 1.3 of this license
+-- or (at your option) any later version. The latest version of this
+-- license is in http://www.latex-project.org/lppl.txt
+-- and version 1.3 or later is part of all distributions of LaTeX
+-- version 2005/12/01 or later.
+--
+-- See file README for more information.
+--
+
+
+--- Main Lua file.
+--
+-- @author Stephan Hennig
+-- @copyright 2012, 2013 Stephan Hennig
+-- @release version 0.41
+--
+
+
+-- Module identification.
+if luatexbase.provides_module then
+ luatexbase.provides_module(
+ {
+ name = 'spelling',
+ date = '2013/05/25',
+ version = '0.41',
+ description = 'support for spell-checking of LuaTeX documents',
+ author = 'Stephan Hennig',
+ licence = 'LPPL ver. 1.3c',
+ }
+ )
+end
+
+
+--- Global table of modules.
+-- The work of the spelling package can be separated into four
+-- stages:<br />
+--
+-- <dl>
+--
+-- <dt>Stage 1</dt>
+-- <dd><ul>
+-- <li>Load bad strings.</li>
+-- <li>Load good strings.</li>
+-- <li>Handle match rules.</li>
+-- </ul></dd>
+--
+-- <dt>Stage 2 (call-back <code>pre_linebreak_filter</code>)</dt>
+-- <dd><ul>
+-- <li>Tag word strings in node lists before paragraph breaking
+-- takes place.</li>
+-- <li>Check spelling of strings.</li>
+-- <li>Highlight strings with known incorrect spelling in PDF
+-- output.</li>
+-- </ul></dd>
+--
+-- <dt>Stage 3 (<code>\AtBeginShipout</code>)</dt>
+-- <dd><ul>
+-- <li>Store all strings found on built page via tag nodes in text
+-- document data structure.</li>
+-- </ul></dd>
+--
+-- <dt>Stage 4 (call-back <code>stop_run</code>)</dt>
+-- <dd><ul>
+-- <li>Output text stored in text document data structure to a
+-- file.</li>
+-- </ul></dd>
+--
+-- </dl>
+--
+-- The code of the spelling package is organized in modules reflecting
+-- these stages. References to modules are stored in a table. Table
+-- indices correspond to the stages as shown above. The table of module
+-- references is shared in a global table (`PKG_spelling`) so that
+-- public module functions are accessible from within external code.<br
+-- />
+--
+-- <ul>
+-- <li><code>spelling-stage-1.lua : stage[1]</code></li>
+-- <li><code>spelling-stage-2.lua : stage[2]</code></li>
+-- <li><code>spelling-stage-3.lua : stage[3]</code></li>
+-- <li><code>spelling-stage-4.lua : stage[4]</code></li>
+-- </ul>
+--
+-- @class table
+-- @name stage
+stage = {}
+
+
+--- Table of package-wide resources that are shared among several
+--- modules.
+--
+-- @class table
+-- @name res
+--
+-- @field rules_bad Table.<br />
+--
+-- This table contains all bad rules. Spellings can be matched against
+-- these rules.
+--
+-- @field rules_good Table.<br />
+--
+-- This table contains all good match rules. Spellings can be matched
+-- against these rules.
+--
+-- @field text_document Table.<br />
+--
+-- Data structure that stores the text of a document. The text document
+-- data structure stores the text of a document. The data structure is
+-- quite simple. A text document is an ordered list (an array) of
+-- paragraphs. A paragraph is an ordered list (an array) of words. A
+-- word is a single UTF-8 encoded string.<br />
+--
+-- During the LuTeX run, node lists are scanned for strings before
+-- hyphenation takes place. The strings found in a node list are stored
+-- in the current paragraph. After finishing scanning a node list, the
+-- current paragraph is inserted into the text document. At the end of
+-- the LuaTeX run, all paragraphs of the text document are broken into
+-- lines of a fixed length and the lines are written to a file.<br />
+--
+-- Here's the rationale of this approach:
+--
+-- <ul>
+--
+-- <li> It reduces file access <i>during</i> the LuaTeX run by delaying
+-- write operations until the end.
+--
+-- <li> It saves space. In Lua, strings are internalized. Since in a
+-- document, the same words are used over and over again, relatively
+-- few strings are actually stored in memory.
+--
+-- <li> It allows for pre-processing the text document before writing it
+-- to a file.
+--
+-- </ul>
+--
+-- @field whatsit_uid Number.<br />
+--
+-- Unique ID for marking user-defined whatsit nodes created by this
+-- package. The ID is generated at run-time. See this <a
+-- href="https://github.com/mpg/luatexbase/issues/8">GitHub issue</a>.
+--
+local res = {
+
+ rules_bad,
+ rules_good,
+ text_document,
+ whatsit_ids,
+
+}
+
+
+--- Global package table.
+-- This global table provides access to package-wide variables from
+-- within other chunks.
+--
+-- @class table
+-- @name PKG_spelling
+PKG_spelling = {}
+
+
+--- Determine unique IDs for user-defined whatsit nodes used by this
+-- package. Package luatexbase provides user-defined whatsit node ID
+-- allocation since version v0.6 (TL 2013). For older package versions,
+-- we start allocating at an arbitrary hard-coded value of 13**8
+-- (ca. 2**30). Note, for compatibility with LuaTeX 0.70.2, the value
+-- must be less than 2^31.
+--
+-- @return Table mapping names to IDs.
+local function __allocate_whatsit_ids()
+ local ids = {}
+ -- Allocation support present?
+ if luatexbase.new_user_whatsit_id then
+ ids.start_tag = luatexbase.new_user_whatsit_id('start_tag', 'spelling')
+ ids.end_tag = luatexbase.new_user_whatsit_id('end_tag', 'spelling')
+ else
+ local uid = 13^8
+ ids.start_tag = uid + 1
+ ids.end_tag = uid + 2
+ end
+ return ids
+end
+
+
+--- Package initialisation.
+--
+local function __init()
+ -- Create resources.
+ res.rules_bad = {}
+ res.rules_good = {}
+ res.text_document = {}
+ res.whatsit_ids = __allocate_whatsit_ids()
+ -- Provide global access to package ressources during module loading.
+ PKG_spelling.res = res
+ -- Load sub-modules:
+ -- * bad and good string loading
+ -- * match rule handling
+ stage[1] = require 'spelling-stage-1'
+ -- * node list tagging
+ -- * spell-checking
+ -- * bad string highlighting
+ stage[2] = require 'spelling-stage-2'
+ -- * text storage
+ stage[3] = require 'spelling-stage-3'
+ -- * text output
+ stage[4] = require 'spelling-stage-4'
+ -- Remove global reference to package ressources.
+ PKG_spelling.res = nil
+ -- Provide global access to module references.
+ PKG_spelling.stage = stage
+ -- Enable text storage.
+ stage[3].enable_text_storage()
+end
+
+
+-- Initialize package.
+__init()
diff --git a/macros/luatex/generic/spelling/spelling-recurse.lua b/macros/luatex/generic/spelling/spelling-recurse.lua
new file mode 100644
index 0000000000..70b48eea2b
--- /dev/null
+++ b/macros/luatex/generic/spelling/spelling-recurse.lua
@@ -0,0 +1,110 @@
+--- spelling-recurse.lua
+--- Copyright 2012, 2013 Stephan Hennig
+--
+-- This work may be distributed and/or modified under the conditions of
+-- the LaTeX Project Public License, either version 1.3 of this license
+-- or (at your option) any later version. The latest version of this
+-- license is in http://www.latex-project.org/lppl.txt
+-- and version 1.3 or later is part of all distributions of LaTeX
+-- version 2005/12/01 or later.
+--
+-- See file README for more information.
+--
+
+
+--- Helper module for recursing into a node list.
+-- This module provides means to recurse into a node list, calling
+-- user-provided call-back functions upon certain events.
+--
+-- @author Stephan Hennig
+-- @copyright 2012, 2013 Stephan Hennig
+-- @release version 0.41
+--
+-- @trick Prevent LuaDoc from looking past here for module description.
+--[[ Trick LuaDoc into entering 'module' mode without using that command.
+module(...)
+--]]
+
+
+-- Module table.
+local M = {}
+
+
+-- Function short-cuts.
+local traverse = node.traverse
+
+
+-- Short-cuts for constants.
+local HLIST = node.id('hlist')
+local VLIST = node.id('vlist')
+
+
+--- Scan a node list and call call-back functions upon certain events.
+-- This function scans a node list. Upon certain events, user-defined
+-- call-back functions are called. Call-back functions have to be
+-- provided in a table. Call-back functions and corresponding events
+-- are:
+--
+-- <dl>
+--
+-- <dt>`vlist_pre_recurse`</dt> <dd>A vlist is about to be recursed
+-- into. Argument is the vlist node.</dd>
+--
+-- <dt>`vlist_post_recurse`</dt> <dd>Recursing into a vlist has been
+-- finished. Argument is the vlist node.</dd>
+--
+-- <dt>`hlist_pre_recurse`</dt> <dd>An hlist is about to be recursed
+-- into. Argument is the hlist node.</dd>
+--
+-- <dt>`hlist_post_recurse`</dt> <dd>Recursing into a hlist has been
+-- finished. Argument is the hlist node.</dd>
+--
+-- <dt>`visit`</dt> <dd>A node of type other that `vlist` and `hlist`
+-- has been found. Arguments are the head node of the current node
+-- (head node of the current branch) and the current node.</dd>
+--
+-- </dl>
+--
+-- If a call-back entry in the table is `nil`, the corresponding event
+-- is ignored.
+--
+-- @param head Node list.
+-- @param cb Table of call-back functions.
+local function recurse_node_list(head, cb)
+ -- Make call-back functions local identifiers.
+ local cb_vlist_pre_recurse = cb.vlist_pre_recurse
+ local cb_vlist_post_recurse = cb.vlist_post_recurse
+ local cb_hlist_pre_recurse = cb.hlist_pre_recurse
+ local cb_hlist_post_recurse = cb.hlist_post_recurse
+ local cb_visit_node = cb.visit_node
+ -- Iterate over nodes in current branch.
+ for n in traverse(head) do
+ local nid = n.id
+ -- Test for vlist node.
+ if nid == VLIST then
+ -- Announce vlist pre-traversal.
+ if cb_vlist_pre_recurse then cb_vlist_pre_recurse(n) end
+ -- Recurse into 'vlist'.
+ recurse_node_list(n.head, cb)
+ -- Announce vlist post-traversal.
+ if cb_vlist_post_recurse then cb_vlist_post_recurse(n) end
+ -- Test for hlist node.
+ elseif nid == HLIST then
+ -- Announce hlist pre-traversal.
+ if cb_hlist_pre_recurse then cb_hlist_pre_recurse(n) end
+ -- Recurse into 'hlist'.
+ recurse_node_list(n.head, cb)
+ -- Announce hlist post-traversal.
+ if cb_hlist_post_recurse then cb_hlist_post_recurse(n) end
+ -- Other nodes.
+ else
+ -- Visit node.
+ if cb_visit_node then cb_visit_node(head, n) end
+ end
+ end
+end
+M.recurse_node_list = recurse_node_list
+
+
+-- Return module table.
+return M
diff --git a/macros/luatex/generic/spelling/spelling-stage-1.lua b/macros/luatex/generic/spelling/spelling-stage-1.lua
new file mode 100644
index 0000000000..c54bac98eb
--- /dev/null
+++ b/macros/luatex/generic/spelling/spelling-stage-1.lua
@@ -0,0 +1,370 @@
+--- spelling-stage-1.lua
+--- Copyright 2012, 2013 Stephan Hennig
+--
+-- This work may be distributed and/or modified under the conditions of
+-- the LaTeX Project Public License, either version 1.3 of this license
+-- or (at your option) any later version. The latest version of this
+-- license is in http://www.latex-project.org/lppl.txt
+-- and version 1.3 or later is part of all distributions of LaTeX
+-- version 2005/12/01 or later.
+--
+-- See file README for more information.
+--
+
+
+--- Handle lists of bad and good strings and match rules.
+--
+-- @author Stephan Hennig
+-- @copyright 2012, 2013 Stephan Hennig
+-- @release version 0.41
+--
+-- @trick Prevent LuaDoc from looking past here for module description.
+--[[ Trick LuaDoc into entering 'module' mode without using that command.
+module(...)
+--]]
+
+
+-- Module table.
+local M = {}
+
+
+-- Import external modules.
+local unicode = require('unicode')
+local xml = require('luaxml-mod-xml')
+
+
+-- Function short-cuts.
+local Sfind = string.find
+
+local tabinsert = table.insert
+
+local Ufind = unicode.utf8.find
+local Ugmatch = unicode.utf8.gmatch
+local Usub = unicode.utf8.sub
+
+
+-- Declare local variables to store references to resources that are
+-- provided by external code.
+--
+-- Table of known bad strings.
+local __is_bad
+--
+-- Table of known good strings.
+local __is_good
+--
+-- Table of bad rules.
+local __rules_bad
+--
+-- Table of good rules.
+local __rules_good
+
+
+--- Generic function for reading bad or good spellings from a file.
+-- All data from the file is read into a string, which is then parsed by
+-- the given parse function.
+--
+-- @param fname File name.
+-- @param parse_string Custom parse function.
+-- @param t Mapping table bad or good spellings should be added to.
+-- @param hint String for info message. Either `bad` or `good`.
+local function __parse_file(fname, parse_string, t, hint)
+ local total_c = 0
+ local new_c = 0
+ local f, err = io.open(fname, 'r')
+ if f then
+ local s = f:read('*all')
+ f:close()
+ total_c, new_c = parse_string(s, t)
+ else
+ texio.write_nl('package spelling: Warning! ' .. err)
+ end
+ texio.write_nl('package spelling: Info! ' .. total_c .. '/' .. new_c .. ' total/new ' .. hint .. ' strings read from file \'' .. fname .. '\'.')
+end
+
+
+--- Generic function for parsing a string containing a plain list of
+-- strings. Input format are strings separated by new line or carriage
+-- return, i.e., one string per line. All lines found in the list are
+-- mapped to the boolean value `true` in the given table.
+--
+-- @param s Input string (a list of strings).
+-- @param t Table that maps strings to the value `true`.
+-- @return Number of total and new strings found.
+local function __parse_plain_list(s, t)
+ local total_c = 0
+ local new_c = 0
+ -- Iterate line-wise through input string.
+ for l in Ugmatch(s, '[^\r\n]+') do
+ -- Map string to boolean value `true`.
+ if not t[l] then
+ t[l] = true
+ new_c = new_c + 1
+ end
+ total_c = total_c + 1
+ end
+ return total_c, new_c
+end
+
+
+--- Parse a plain list of bad strings read from a file.
+-- All strings found (words with known incorrect spelling) are mapped to
+-- the boolean value `true` in table `__is_bad`. The format of the
+-- input file is one string per line.
+--
+-- @param fname File name.
+local function parse_bad_plain_list_file(fname)
+ __parse_file(fname, __parse_plain_list, __is_bad, 'bad')
+end
+M.parse_bad_plain_list_file = parse_bad_plain_list_file
+
+
+--- Parse a plain list of good strings read from a file.
+-- All strings found (words with known correct spelling) are mapped to
+-- the boolean value `true` in table `__is_good`. The format of the
+-- input file is one string per line.
+--
+-- @param fname File name.
+local function parse_good_plain_list_file(fname)
+ __parse_file(fname, __parse_plain_list, __is_good, 'good')
+end
+M.parse_good_plain_list_file = parse_good_plain_list_file
+
+
+--- Get a custom LanguageTool XML handler.
+-- The returned XML handler scans LanguageTool XML data for incorrect
+-- spellings. For every incorrect spelling found, the given call-back
+-- function is called with the incorrect spelling string as argument.<br
+-- />
+--
+-- XML data is checked for being created by LanguageTool (via attribute
+-- <code>software</code> in tag <code>matches</code>).
+--
+-- @param cb Call-back function handling incorrect spellings found in
+-- XML data.
+-- @return XML handler.
+local function __get_XML_handler_LanguageTool(cb)
+
+ -- Some flags for checking validity of XML data. LanguageTool XML
+ -- data must declare as being UTF-8 encoded and advertise as being
+ -- created by LanguageTool.
+ local is_XML_encoding_UTF_8 = false
+ local is_XML_creator_LanguageTool = false
+ local is_XML_valid = false
+
+ --- Handler object for parsing LanguageTool XML data.
+ -- This table contains call-backs used by LuaXML when parsing XML
+ -- data.
+ --
+ -- @class table
+ -- @name XML_handler
+ -- @field decl Handle XML declaration.
+ -- @field starttag Handle all relevant tags.
+ -- @field endtag Not used, but mandatory.
+ local XML_handler = {
+
+ decl = function(self, text, attr)
+ -- Check XML encoding declaration.
+ if attr.encoding == 'UTF-8' then
+ is_XML_encoding_UTF_8 = true
+ is_XML_valid = is_XML_encoding_UTF_8 and is_XML_creator_LanguageTool
+ else
+ error('package spelling: Error! XML data not in the UTF-8 encoding.')
+ end
+ end,
+
+ starttag = function(self, text, attr)
+ -- Process <matches> tag.
+ if text == 'matches' then
+ -- Check XML creator is LanguageTool.
+ if attr and attr.software == 'LanguageTool' then
+ is_XML_creator_LanguageTool = true
+ is_XML_valid = is_XML_encoding_UTF_8 and is_XML_creator_LanguageTool
+ end
+ -- Check XML data is valid.
+ elseif not is_XML_valid then
+ error('package spelling: Error! No valid LanguageTool XML data.')
+ -- Process <error> tags.
+ elseif text == 'error' then
+ local ruleid = attr.ruleid
+ if ruleid == 'HUNSPELL_RULE'
+ or ruleid == 'HUNSPELL_NO_SUGGEST_RULE'
+ or ruleid == 'GERMAN_SPELLER_RULE'
+ or Ufind(ruleid, '^MORFOLOGIK_RULE_')
+ then
+ -- Extract misspelled word from context attribute.
+ local word = Usub(attr.context, attr.contextoffset + 1, attr.contextoffset + attr.errorlength)
+ cb(word)
+ end
+ end
+ end,
+
+ endtag = function(self, text)
+ end,
+
+ }
+
+ return XML_handler
+end
+
+
+--- Parse a string containing LanguageTool XML data.
+-- All incorrect spellings found in the given XML data are mapped to the
+-- boolean value `true` in the given table.
+--
+-- @param s String containing XML data.
+-- @param t Table mapping incorrect spellings to a boolean.
+-- @return Number of total and new incorrect spellings found.
+local function __parse_XML_LanguageTool(s, t)
+ local total_c = 0
+ local new_c = 0
+
+ -- Create call-back for custom LanguageTool XML handler that stores a
+ -- bad word in the given table and does some statistics.
+ local cb_incorrect_spelling = function(word)
+ if not t[word] then
+ t[word] = true
+ new_c = new_c + 1
+ end
+ total_c = total_c + 1
+ end
+
+ -- Create custom XML handler.
+ local XML_handler_LT = __get_XML_handler_LanguageTool(cb_incorrect_spelling)
+ -- Create custom XML parser.
+ local x = xml.xmlParser(XML_handler_LT)
+ -- Parse XML data.
+ x:parse(s)
+ return total_c, new_c
+end
+
+
+--- Parse LanguageTool XML data read from a file.
+-- All strings found in the file (words with known incorrect spelling)
+-- are mapped to the boolean value `true` in table `__is_bad`.
+--
+-- @param fname File name.
+local function parse_XML_LanguageTool_file(fname)
+ __parse_file(fname, __parse_XML_LanguageTool, __is_bad, 'bad')
+end
+M.parse_XML_LanguageTool_file = parse_XML_LanguageTool_file
+
+
+--- Parse default sources for bad and good strings.
+-- All strings found in default sources for words with known incorrect
+-- spelling are mapped to the boolean value `true` in table `__is_bad`.
+-- All strings found in default sources for words with known correct
+-- spelling are mapped to the boolean value `true` in table `__is_good`.
+-- Default sources for bad spellings are files `<jobname>.spell.xml` (a
+-- LanguageTool XML file) and `<jobname>.spell.bad` (a plain list file).
+-- Default sources for good spellings are file `<jobname>.spell.good` (a
+-- plain list file).
+local function parse_default_bad_and_good()
+ local fname, f
+ -- Try to read bad spellings from LanguageTool XML file
+ -- '<jobname>.spell.xml'.
+ fname = tex.jobname .. '.spell.xml'
+ f = io.open(fname, 'r')
+ if f then
+ f:close()
+ parse_XML_LanguageTool_file(fname)
+ end
+ -- Try to read bad spellings from plain list file
+ -- '<jobname>.spell.bad'.
+ fname = tex.jobname .. '.spell.bad'
+ f = io.open(fname, 'r')
+ if f then
+ f:close()
+ parse_bad_plain_list_file(fname)
+ end
+ -- Try to read good spellings from plain list file
+ -- '<jobname>.spell.good'.
+ fname = tex.jobname .. '.spell.good'
+ f = io.open(fname, 'r')
+ if f then
+ f:close()
+ parse_good_plain_list_file(fname)
+ end
+end
+M.parse_default_bad_and_good = parse_default_bad_and_good
+
+
+--- Default bad dictionary look-up match rule.
+-- This function looks-up both arguments in the list of bad spellings.
+-- It returns `true` if either of the arguments is found in the list of
+-- bad spellings, otherwise `false`.
+--
+-- @param raw Raw string to check.
+-- @param stripped Same as `raw`, but with stripped surrounding
+-- punctuation.
+-- @return A boolean value indicating a match.
+local function __bad_rule_bad_dictionary_lookup(raw, stripped)
+ return __is_bad[stripped] or __is_bad[raw]
+end
+
+
+--- Default good dictionary look-up match rule.
+-- This function looks-up both arguments in the list of good spellings.
+-- It returns `true` if either of the arguments is found in the list of
+-- good spellings, otherwise `false`.
+--
+-- @param raw Raw string to check.
+-- @param stripped Same as `raw`, but with stripped surrounding
+-- punctuation.
+-- @return A boolean value indicating a match.
+local function __good_rule_good_dictionary_lookup(raw, stripped)
+ return __is_good[stripped] or __is_good[raw]
+end
+
+
+--- Load match rule module.
+-- Match rule modules are loaded using `require`. The module table must
+-- follow the following convention: Indentifiers of bad match rules
+-- start `bad_rule_`. Indentifiers of good match rules start
+-- `good_rule_`. Other and non-function identifiers are ignore.
+--
+-- All match rules found in a module are added to the table of bad and
+-- good match rules. Arguments of a match rule function are a raw
+-- string and the same string with stripped surrounding punctuation.
+--
+-- @param fname Module file name.
+local function read_match_rules(fname)
+ local bad_c = 0
+ local good_c = 0
+ local rules = require(fname)
+ for k,v in pairs(rules) do
+ if type(v) == 'function' then
+ if Sfind(k, '^bad_rule_') then
+ tabinsert(__rules_bad, v)
+ bad_c = bad_c + 1
+ elseif Sfind(k, '^good_rule_') then
+ tabinsert(__rules_good, v)
+ good_c = good_c + 1
+ end
+ end
+ end
+ texio.write_nl('package spelling: Info! ' .. bad_c .. '/' .. good_c .. ' bad/good match rules read from module \'' .. fname .. '\'.')
+end
+M.read_match_rules = read_match_rules
+
+
+--- Module initialisation.
+--
+local function __init()
+ -- Get local references to package ressources.
+ __rules_bad = PKG_spelling.res.rules_bad
+ __rules_good = PKG_spelling.res.rules_good
+ -- Add default dictionary look-up match rules.
+ tabinsert(__rules_bad, __bad_rule_bad_dictionary_lookup)
+ tabinsert(__rules_good, __good_rule_good_dictionary_lookup)
+ -- Create emtpy lists of known spellings.
+ __is_bad = {}
+ __is_good = {}
+end
+
+
+-- Initialize module.
+__init()
+
+
+-- Return module table.
+return M
diff --git a/macros/luatex/generic/spelling/spelling-stage-2.lua b/macros/luatex/generic/spelling/spelling-stage-2.lua
new file mode 100644
index 0000000000..c7cb98f1f2
--- /dev/null
+++ b/macros/luatex/generic/spelling/spelling-stage-2.lua
@@ -0,0 +1,675 @@
+--- spelling-stage-2.lua
+--- Copyright 2012, 2013 Stephan Hennig
+--
+-- This work may be distributed and/or modified under the conditions of
+-- the LaTeX Project Public License, either version 1.3 of this license
+-- or (at your option) any later version. The latest version of this
+-- license is in http://www.latex-project.org/lppl.txt
+-- and version 1.3 or later is part of all distributions of LaTeX
+-- version 2005/12/01 or later.
+--
+-- See file README for more information.
+--
+
+
+--- Tag node lists with word strings before hyphenation takes place.
+-- This module provides means to tag node lists by inserting
+-- user-defined whatsit nodes before and after first and last node
+-- belonging to a chain representing a string in the node list. The
+-- final tag node contains a reference to a string containing the word
+-- string. Tagging is applied before hyphenation takes place.
+--
+-- @author Stephan Hennig
+-- @copyright 2012, 2013 Stephan Hennig
+-- @release version 0.41
+--
+-- @trick Prevent LuaDoc from looking past here for module description.
+--[[ Trick LuaDoc into entering 'module' mode without using that command.
+module(...)
+--]]
+
+
+-- Module table.
+local M = {}
+
+
+-- Import external modules.
+local recurse = require('spelling-recurse')
+local unicode = require('unicode')
+
+
+-- Function short-cuts.
+local tabconcat = table.concat
+local tabinsert = table.insert
+local tabremove = table.remove
+
+local node_new = node.new
+local node_insert_after = node.insert_after
+local node_insert_before = node.insert_before
+
+local recurse_node_list = recurse.recurse_node_list
+
+local Sfind = string.find
+local Sgmatch = string.gmatch
+local Smatch = string.match
+
+local Uchar = unicode.utf8.char
+local Umatch = unicode.utf8.match
+
+
+-- Short-cuts for constants.
+local DISC = node.id('disc')
+local GLYPH = node.id('glyph')
+local KERN = node.id('kern')
+local WHATSIT = node.id('whatsit')
+local LOCAL_PAR = node.subtype('local_par')
+local USER_DEFINED = node.subtype('user_defined')
+local PDF_COLORSTACK = node.subtype('pdf_colorstack')
+
+
+-- Declare local variables to store references to resources that are
+-- provided by external code.
+--
+-- Table of bad rules.
+local __rules_bad
+--
+-- Table of good rules.
+local __rules_good
+--
+-- ID of user-defined whatsit nodes marking the start of a word.
+local __uid_start_tag
+--
+-- ID of user-defined whatsit nodes marking the end of a word.
+local __uid_end_tag
+
+
+--- Module options.
+-- This table contains all module options. User functions to set
+-- options are provided.
+--
+-- @class table
+-- @name __opts
+-- @field hl_color Colour used for highlighting bad spellings in PDF
+-- output.
+local __opts = {
+ hl_color,
+}
+
+
+--- Set colour used for highlighting.
+-- Set colour used for highlighting bad spellings in PDF output. The
+-- argument is checked for a valid PDF colour statement. As an example,
+-- the string `1 0 0 rg` represents a red colour in the RGB colour
+-- space. A similar colour in the CMYK colour space would be
+-- represented by the string '0 1 1 0 k'.
+--
+-- @param col New colour.
+local function set_highlight_color(col)
+ -- Extract all colour components.
+ local components = Smatch(col, '^(%S+ %S+ %S+) rg$') or Smatch(col, '^(%S+ %S+ %S+ %S+) k$')
+ local is_valid_arg = components
+ if is_valid_arg then
+ -- Validate colour components.
+ for comp in Sgmatch(components, '%S+') do
+ -- Check number syntax.
+ local is_valid_comp = Sfind(comp, '^%d+%.?%d*$') or Sfind(comp, '^%d*%.?%d+$')
+ if is_valid_comp then
+ -- Check number range.
+ comp = tonumber(comp)
+ is_valid_comp = comp >= 0 and comp <= 1
+ end
+ is_valid_arg = is_valid_arg and is_valid_comp
+ end
+ end
+ if is_valid_arg then
+ __opts.hl_color = col
+ else
+ error('package spelling: Error! Invalid PDF colour statement: ' .. tostring(col))
+ end
+end
+M.set_highlight_color = set_highlight_color
+
+
+--- Highlighting status cache table.
+-- Determining the highlighting status of a string can be an expensive
+-- operation. To reduce average run-time penalty per string,
+-- highlighting status of all strings found in a document is cached in
+-- this table, so that determining the highlighting status of a known
+-- string requires only one table look-up.<br />
+--
+-- This table needs an `__index` meta method calculating the
+-- highlighting status of unknown keys (strings).
+--
+-- @class table
+-- @name __is_highlighting_needed
+local __is_highlighting_needed = {}
+
+
+--- Calculate and cache the highlighting status of a string.
+-- First, surrounding punctuation is stripped from the string argument.
+-- Then, the given raw as well as the stripped string are checked
+-- against all rules. Highlighting of the string is required, if any
+-- bad rule matches, but no good rule matches. That is, good rules take
+-- precedence over bad rules.
+--
+-- @param t Original table.
+-- @param raw Raw string to check.
+-- @return True, if highlighting is required. False, otherwise.
+local function __calc_is_highlighting_needed(t, raw)
+ -- Strip surrounding punctuation from string.
+ local stripped = Umatch(raw, '^%p*(.-)%p*$')
+ -- Check for a bad match.
+ local is_bad = false
+ for _,matches_bad in ipairs(__rules_bad) do
+ is_bad = is_bad or matches_bad(raw, stripped)
+ if is_bad then break end
+ end
+ -- Check for a good match.
+ local is_good = false
+ for _,matches_good in ipairs(__rules_good) do
+ is_good = is_good or matches_good(raw, stripped)
+ if is_good then break end
+ end
+ -- Calculate highlighting status.
+ local status = (is_bad and not is_good) or false
+ -- Store status in cache table.
+ rawset(t, raw, status)
+ -- Return status.
+ return status
+end
+
+
+-- Set-up meta table for highlighting status cache table.
+setmetatable(__is_highlighting_needed, {
+ __index = __calc_is_highlighting_needed,
+})
+
+
+--- Convert a Unicode code point to a regular UTF-8 encoded string.
+-- This function can be used as an `__index` meta method.
+--
+-- @param t original table
+-- @param cp originl key, a Unicode code point
+-- @return UTF-8 encoded string corresponding to the Unicode code point.
+local function __meta_cp2utf8(t, cp)
+ return Uchar(cp)
+end
+
+
+--- Table of Unicode code point mappings.
+-- This table maps Unicode code point to strings. The mappings are used
+-- during text extraction to translate certain Unicode code points to an
+-- arbitrary string instead of the corresponding UTF-8 encoded
+-- character.<br />
+--
+-- As an example, by adding an appropriate entry to this table, the
+-- single Unicode code point U-fb00 (LATIN SMALL LIGATURE FF) can be
+-- resolved into the multi character string 'ff' instead of being
+-- converted to the single character string 'ff' ('&#xfb00;').<br />
+--
+-- Keys are Unicode code points. Values must be strings in the UTF-8
+-- encoding. If a key is not present in this table, the regular UTF-8
+-- character is returned by means of a meta table.<br />
+--
+-- @class table
+-- @name __codepoint_map
+local __codepoint_map = {
+
+ [0x0132] = 'IJ',-- LATIN CAPITAL LIGATURE IJ
+ [0x0133] = 'ij',-- LATIN SMALL LIGATURE IJ
+ [0x0152] = 'OE',-- LATIN CAPITAL LIGATURE OE
+ [0x0153] = 'oe',-- LATIN SMALL LIGATURE OE
+ [0x017f] = 's',-- LATIN SMALL LETTER LONG S
+
+ [0xfb00] = 'ff',-- LATIN SMALL LIGATURE FF
+ [0xfb01] = 'fi',-- LATIN SMALL LIGATURE FI
+ [0xfb02] = 'fl',-- LATIN SMALL LIGATURE FL
+ [0xfb03] = 'ffi',-- LATIN SMALL LIGATURE FFI
+ [0xfb04] = 'ffl',-- LATIN SMALL LIGATURE FFL
+ [0xfb05] = 'st',-- LATIN SMALL LIGATURE LONG S T
+ [0xfb06] = 'st',-- LATIN SMALL LIGATURE ST
+
+}
+
+
+--- Meta table for code point mapping table.
+--
+-- @class table
+-- @name __meta_codepoint_map
+-- @field __index Index operator.
+local __meta_codepoint_map = {
+ __index = __meta_cp2utf8,
+}
+
+
+-- Set meta table for code point mapping table.
+setmetatable(__codepoint_map, __meta_codepoint_map)
+
+
+--- Clear all code point mappings.
+-- After calling this function, there are no known code point mappings
+-- and no code point mapping takes place during text extraction.
+local function clear_all_mappings()
+ __codepoint_map = {}
+ setmetatable(__codepoint_map, __meta_codepoint_map)
+end
+M.clear_all_mappings = clear_all_mappings
+
+
+--- Manage Unicode code point mappings.
+-- This function can be used to set-up code point mappings. First
+-- argument must be a number, second argument must be a string in the
+-- UTF-8 encoding or `nil`.<br />
+--
+-- If the second argument is a string, after calling this function, the
+-- Unicode code point given as first argument, when found in a node list
+-- during text extraction, is mapped to the string given as second
+-- argument instead of being converted to a UTF-8 encoded character
+-- corresponding to the code point.<br />
+--
+-- If the second argument is `nil`, a mapping for the given code point,
+-- if existing, is deleted.
+--
+-- @param cp A Unicode code point, e.g., 0xfb00 for the code point LATIN
+-- SMALL LIGATURE FF.
+-- @param newt New target string to map the code point to or `nil`.
+-- @return Old target string the code point was mapped to before
+-- (possibly `nil`). If any arguments are invalid, return value is
+-- `false`. Arguments are invalid if code point is not of type `number`
+-- or not in the range 0 to 0x10ffff or if new target string is neither
+-- of type `string` nor `nil`).
+local function set_mapping(cp, newt)
+ -- Prevent from invalid entries in mapping table.
+ if (type(cp) ~= 'number') or
+ (cp < 0) or
+ (cp > 0x10ffff) or
+ ((type(newt) ~= 'string') and (type(newt) ~= 'nil')) then
+ return false
+ end
+ -- Retrieve old mapping.
+ local oldt = rawget(__codepoint_map, cp)
+ -- Set new mapping.
+ __codepoint_map[cp] = newt
+ -- Return old mapping.
+ return oldt
+end
+M.set_mapping = set_mapping
+
+
+-- First and last nodes known to belong to the current word and their
+-- head nodes. These nodes are logged, so that after recognizing the
+-- end of a word, they can be tagged by inserting new user-defined
+-- whatsit nodes before and after them.
+local __curr_word_start_head
+local __curr_word_start
+local __curr_word_end_head
+local __curr_word_end
+
+
+--- Tag the current word in the node list.
+-- Insert tag nodes (user-defined whatsit nodes) into the node list
+-- before and after the first and last nodes belonging to the current
+-- word. The tag marking the start of a word contains as value an empty
+-- string. The tag marking the end of a word contains as value a
+-- reference to the word string.
+--
+-- @param word Word string.
+local function __tag_word(word)
+ -- Check, if start node of current word is a head node. Inserting
+ -- before head nodes needs special attention. This is not yet
+ -- implemented.
+ if (__curr_word_start ~= __curr_word_start_head) then
+ -- Create new start tag node.
+ local start_tag = node_new(WHATSIT, USER_DEFINED)
+ -- Mark whatsit node with module ID, so that we can recognize it
+ -- later.
+ start_tag.user_id = __uid_start_tag
+ -- Value is an empty string.
+ start_tag.type = 115
+ start_tag.value = ''
+ -- Insert start tag before first node belonging to current word.
+ node_insert_before(__curr_word_start_head, __curr_word_start, start_tag)
+ end
+ -- Create new end tag node.
+ local end_tag = node_new(WHATSIT, USER_DEFINED)
+ -- Mark whatsit node with module ID, so that we can recognize it
+ -- later.
+ end_tag.user_id = __uid_end_tag
+ -- Value of end tag is an index (a number).
+ end_tag.type = 115
+ end_tag.value = word
+ -- Insert end tag after last node belonging to current word.
+ node_insert_after(__curr_word_end_head, __curr_word_end, end_tag)
+end
+
+
+--- Highlight bad spelling by colour.
+-- Insert colour whatsits before and after the first and last nodes
+-- known to belong to the current word.
+local function __highlight_by_color()
+ -- Check, if start node of current word is a head node. Inserting
+ -- before head nodes needs special attention. This is not yet
+ -- implemented.
+ if (__curr_word_start ~= __curr_word_start_head) then
+ -- Create pdf_colorstack whatsit nodes.
+ local push = node_new(WHATSIT, PDF_COLORSTACK)
+ local pop = node_new(WHATSIT, PDF_COLORSTACK)
+ push.stack = 0
+ pop.stack = 0
+ push.command = 1
+ pop.command = 2
+ push.data = __opts.hl_color
+ node_insert_before(__curr_word_start_head, __curr_word_start, push)
+ node_insert_after(__curr_word_end_head, __curr_word_end, pop)
+ end
+end
+
+
+--- Highlight bad spelling by colour (using node field `cmd`).
+-- Insert colour whatsits before and after the first and last nodes
+-- known to belong to the current word.
+-- @see function __highlight_by_color
+local function __highlight_by_color_cmd()
+ -- Check, if start node of current word is a head node. Inserting
+ -- before head nodes needs special attention. This is not yet
+ -- implemented.
+ if (__curr_word_start ~= __curr_word_start_head) then
+ -- Create pdf_colorstack whatsit nodes.
+ local push = node_new(WHATSIT, PDF_COLORSTACK)
+ local pop = node_new(WHATSIT, PDF_COLORSTACK)
+ push.stack = 0
+ pop.stack = 0
+ push.cmd = 1
+ pop.cmd = 2
+ push.data = __opts.hl_color
+ node_insert_before(__curr_word_start_head, __curr_word_start, push)
+ node_insert_after(__curr_word_end_head, __curr_word_end, pop)
+ end
+end
+
+
+--- Generic function for highlighting bad spellings.
+local function __highlight_bad_word()
+ __highlight_by_color()
+end
+
+
+-- Tagging status.
+local __is_active_tagging
+
+
+-- Highlighting status.
+local __is_active_highlighting
+
+
+--- Data structure that stores the characters of a word string.
+-- The current word data structure is an ordered list (an array) of the
+-- characters of the word. The characters are collected while scanning
+-- a node list. They are concatenated to a single string only after the
+-- end of a word is detected, before inserting the current word into the
+-- current paragraph data structure.
+--
+-- @class table
+-- @name __curr_word
+local __curr_word
+
+
+--- Act upon detection of end of current word string.
+-- If the current word contains visible characters, store the current
+-- word in the current tag.
+local function __finish_current_word()
+ -- Finish a word?
+ if __curr_word then
+ local word = tabconcat(__curr_word)
+ -- Check, if the current word has already been tagged. This is only
+ -- a quick hack.
+ local start_prev = __curr_word_start.prev
+ local end_next = __curr_word_end.next
+ if start_prev and end_next
+ and (start_prev.id == WHATSIT)
+ and (start_prev.subtype == USER_DEFINED)
+ and (start_prev.user_id == __uid_start_tag)
+ and (end_next.id == WHATSIT)
+ and (end_next.subtype == USER_DEFINED)
+ and (end_next.user_id == __uid_end_tag)
+ and (end_next.value == word) then
+ __curr_word = nil
+ __curr_word_start_head = nil
+ __curr_word_start = nil
+ __curr_word_end_head = nil
+ __curr_word_end = nil
+ return
+ end
+ -- Tag node list with word string.
+ if __is_active_tagging then
+ __tag_word(word)
+ end
+ -- Highlighting needed?
+ if __is_highlighting_needed[word] and __is_active_highlighting then
+ __highlight_bad_word()
+ end
+ __curr_word = nil
+ end
+ __curr_word_start_head = nil
+ __curr_word_start = nil
+ __curr_word_end_head = nil
+ __curr_word_end = nil
+end
+
+
+--- Act upon detection of end of current paragraph.
+-- If the current paragraph contains words, store the current paragraph
+-- in the text document.
+local function __finish_current_paragraph()
+ -- Finish current word.
+ __finish_current_word()
+end
+
+
+--- Paragraph management stack.
+-- Stack of boolean flags, that are used for logging the occurence of a
+-- new paragraph within nested vlists.
+local __is_vlist_paragraph
+
+
+--- Paragraph management.
+-- This function puts a new boolean flag onto a stack that is used to
+-- log the occurence of a new paragraph, while recursing into the coming
+-- vlist. After finishing recursing into the vlist, the flag needs to
+-- be removed from the stack. Depending on the flag, the then current
+-- paragraph can be finished.
+local function __vlist_pre_recurse()
+ tabinsert(__is_vlist_paragraph, false)
+end
+
+
+--- Paragraph management.
+-- Remove flag from stack after recursing into a vlist. If necessary,
+-- finish the current paragraph.
+local function __vlist_post_recurse()
+ local p = tabremove(__is_vlist_paragraph)
+ if p then
+ __finish_current_paragraph()
+ end
+end
+
+
+--- Find paragraphs and strings.
+-- While scanning a node list, this call-back function finds nodes
+-- representing the start of a paragraph (local_par whatsit nodes) and
+-- strings (chains of nodes of type glyph, kern, disc).
+--
+-- @param head Head node of current branch.
+-- @param n The current node.
+local function __visit_node(head, n)
+ local nid = n.id
+ -- Test for word string component node.
+ if nid == GLYPH then
+ -- Save first node belonging to current word and its head for later
+ -- reference.
+ if not __curr_word_start then
+ __curr_word_start_head = head
+ __curr_word_start = n
+ end
+ -- Save latest node belonging to current word and its head for later
+ -- reference.
+ __curr_word_end_head = head
+ __curr_word_end = n
+ -- Provide new empty word, if necessary.
+ if not __curr_word then
+ __curr_word = {}
+ end
+ -- Append character to current word string.
+ tabinsert(__curr_word, __codepoint_map[n.char])
+ -- Test for other word string component nodes.
+ elseif (nid == DISC) or (nid == KERN) then
+ -- We're still within the current word string. Do nothing.
+ -- Test for paragraph start.
+ elseif (nid == WHATSIT) and (n.subtype == LOCAL_PAR) then
+ __finish_current_paragraph()
+ __is_vlist_paragraph[#__is_vlist_paragraph] = true
+ else
+ -- End of current word string detected.
+ __finish_current_word()
+ end
+end
+
+
+--- Table of call-back functions for node list recursion: store the
+--- word strings found in a node list.
+-- The call-back functions in this table identify chains of nodes
+-- representing word strings in a node list and stores the strings in
+-- the text document. Local_par whatsit nodes are word boundaries.
+-- Nodes of type `hlist` are recursed into as if they were non-existent.
+-- As an example, the LaTeX input `a\mbox{a b}b` is recognized as two
+-- strings `aa` and `bb`.
+--
+-- @class table
+-- @name __cb_tag_words
+-- @field vlist_pre_recurse Paragraph management.
+-- @field vlist_post_recurse Paragraph management.
+-- @field visit_node Find nodes representing paragraphs and words.
+local __cb_tag_words = {
+
+ vlist_pre_recurse = __vlist_pre_recurse,
+ vlist_post_recurse = __vlist_post_recurse,
+ visit_node = __visit_node,
+
+}
+
+
+--- Process node list according to this stage.
+-- This function recurses into the given node list, extracts all text
+-- and stores it in the text document.
+--
+-- @param head Node list.
+local function __process_node_list(head)
+ __curr_word_start_head = nil
+ __curr_word_start = nil
+ __curr_word_end_head = nil
+ __curr_word_end = nil
+ recurse_node_list(head, __cb_tag_words)
+ -- Clean-up left-over word and/or paragraph.
+ __finish_current_paragraph()
+end
+
+
+--- Call-back function that processes the node list.
+--
+-- @param head Node list.
+local function __cb_pre_linebreak_filter_pkg_spelling(head)
+ __process_node_list(head)
+ return head
+end
+
+
+--- Start tagging text.
+-- After calling this function, words are tagged in node lists before
+-- hyphenation takes place.
+local function enable_text_tagging()
+ __is_active_tagging = true
+end
+M.enable_text_tagging = enable_text_tagging
+
+
+--- Stop tagging text.
+-- After calling this function, no more word tagging in node lists takes
+-- place.
+local function disable_text_tagging()
+ __is_active_tagging = false
+end
+M.disable_text_tagging = disable_text_tagging
+
+
+--- Start highlighting bad spellings.
+-- After calling this function, bad spellings are highlighted in PDF
+-- output.
+local function enable_word_highlighting()
+ __is_active_highlighting = true
+end
+M.enable_word_highlighting = enable_word_highlighting
+
+
+--- Stop highlighting bad spellings.
+-- After calling this function, no more bad spellings are highlighted in
+-- PDF output.
+local function disable_word_highlighting()
+ __is_active_highlighting = false
+end
+M.disable_word_highlighting = disable_word_highlighting
+
+
+--- Try to maintain compatibility with older LuaTeX versions.
+-- Between LuaTeX 0.70.2 and 0.76.0 node field `cmd` of `whatsits` nodes
+-- of subtype `pdf_colorstack` has been renamed to `command`. This
+-- function checks which node field is the correct one and activates a
+-- fall-back function in case. Due to a bug in LuaTeX 0.76.0 (shipped
+-- with TL2013) function `node.has_field()` doesn't return correct
+-- results. It is therefore tested if an assignment to field `command`
+-- raises an error or not.
+local function __maintain_compatibility()
+ -- Create pdf_colorstack whatsit node.
+ local n = node.new(WHATSIT, PDF_COLORSTACK)
+ -- Function that assigns a value to node field 'command'.
+ local f = function()
+ n.command = 1
+ end
+ -- If the assignment is not successful, fall-back to node field 'cmd'.
+ if not pcall(f) then
+ __highlight_by_color = __highlight_by_color_cmd
+ end
+ -- Delete test node.
+ node.free(n)
+end
+
+
+--- Module initialisation.
+--
+local function __init()
+ -- Try to maintain compatibility with older LuaTeX versions.
+ __maintain_compatibility()
+ -- Get local references to package ressources.
+ __rules_bad = PKG_spelling.res.rules_bad
+ __rules_good = PKG_spelling.res.rules_good
+ __uid_start_tag = PKG_spelling.res.whatsit_ids.start_tag
+ __uid_end_tag = PKG_spelling.res.whatsit_ids.end_tag
+ -- Create empty paragraph management stack.
+ __is_vlist_paragraph = {}
+ -- Remember tagging status.
+ __is_active_tagging = false
+ -- Remember highlighting status.
+ __is_active_highlighting = false
+ -- Set default highlighting colour.
+ set_highlight_color('1 0 0 rg')
+ -- Register call-back: Before TeX breaks a paragraph into lines, tag
+ -- and highlight strings.
+ luatexbase.add_to_callback('pre_linebreak_filter', __cb_pre_linebreak_filter_pkg_spelling, '__cb_pre_linebreak_filter_pkg_spelling')
+end
+
+
+-- Initialize module.
+__init()
+
+
+-- Return module table.
+return M
diff --git a/macros/luatex/generic/spelling/spelling-stage-3.lua b/macros/luatex/generic/spelling/spelling-stage-3.lua
new file mode 100644
index 0000000000..613e6af995
--- /dev/null
+++ b/macros/luatex/generic/spelling/spelling-stage-3.lua
@@ -0,0 +1,301 @@
+--- spelling-stage-3.lua
+--- Copyright 2012, 2013 Stephan Hennig
+--
+-- This work may be distributed and/or modified under the conditions of
+-- the LaTeX Project Public License, either version 1.3 of this license
+-- or (at your option) any later version. The latest version of this
+-- license is in http://www.latex-project.org/lppl.txt
+-- and version 1.3 or later is part of all distributions of LaTeX
+-- version 2005/12/01 or later.
+--
+-- See file README for more information.
+--
+
+
+--- Store the text of a LuaTeX document in a text document data
+--- structure.
+-- This module provides means to extract text from a LuaTeX document and
+-- to store it in a text document data structure.
+--
+-- In the text document, words are stored as UTF-8 encoded strings. A
+-- mapping mechanism is provided by which, during word string
+-- recognition, individual code-points, e.g., of glyph nodes, can be
+-- translated to arbitrary UTF-8 strings, e.g., ligatures to single
+-- letters.
+--
+-- @author Stephan Hennig
+-- @copyright 2012, 2013 Stephan Hennig
+-- @release version 0.41
+--
+-- @trick Prevent LuaDoc from looking past here for module description.
+--[[ Trick LuaDoc into entering 'module' mode without using that command.
+module(...)
+--]]
+
+
+-- Module table.
+local M = {}
+
+
+-- Import external modules.
+local recurse = require('spelling-recurse')
+
+
+-- Function short-cuts.
+local recurse_node_list = recurse.recurse_node_list
+
+local tabinsert = table.insert
+local tabremove = table.remove
+
+
+-- Short-cuts for constants.
+local WHATSIT = node.id('whatsit')
+local LOCAL_PAR = node.subtype('local_par')
+local USER_DEFINED = node.subtype('user_defined')
+
+
+-- Declare local variables to store references to resources that are
+-- provided by external code.
+--
+-- Text document data structure.
+local __text_document
+--
+-- ID of user-defined whatsit nodes marking the start of a word.
+local __uid_start_tag
+--
+-- ID of user-defined whatsit nodes marking the end of a word.
+local __uid_end_tag
+
+
+--- Module options.
+-- This table contains all module options. User functions to set
+-- options are provided.
+--
+-- @class table
+-- @name __opts
+-- @field table_par When processing a table, when should paragraphs be
+-- inserted into the text document?<br />
+--
+-- <ul>
+-- <li> 0 - Don't touch tables in any way.</li>
+-- <li> 1 - Insert paragraphs before and after hlists of type
+-- <i>alignment column or row</i>, i.e., before and after
+-- every table row.</li>
+-- <li> 2 - Insert paragraphs before and after hlists of type
+-- <i>alignment cell</i>, i.e., before and after every table
+-- cell.</li>
+-- </ul>
+local __opts = {
+ table_par,
+}
+
+
+--- Set table behaviour.
+-- Determine when paragraphs are inserted within tables.
+--
+-- @param value New value.
+local function set_table_paragraphs(value)
+ __opts.table_par = value
+end
+M.set_table_paragraphs = set_table_paragraphs
+
+
+--- Data structure that stores the word strings found in a node list.
+--
+-- @class table
+-- @name __curr_paragraph
+local __curr_paragraph
+
+
+--- Act upon detection of end of current word string.
+-- If the current word contains visible characters, store the current
+-- word in the current paragraph.
+--
+-- @param n String tag node.
+local function __finish_current_word(n)
+ -- Provide new empty paragraph, if necessary.
+ if not __curr_paragraph then
+ __curr_paragraph = {}
+ end
+ -- Append current string to current paragraph.
+ tabinsert(__curr_paragraph, n.value)
+end
+
+
+--- Act upon detection of end of current paragraph.
+-- If the current paragraph contains words, store the current paragraph
+-- in the text document.
+local function __finish_current_paragraph()
+ -- Finish a paragraph?
+ if __curr_paragraph then
+ -- Append current paragraph to document structure.
+ tabinsert(__text_document, __curr_paragraph)
+ __curr_paragraph = nil
+ end
+end
+
+
+--- Paragraph management stack.
+-- Stack of boolean flags, that are used for logging the occurence of a
+-- new paragraph within nested vlists.
+local __is_vlist_paragraph
+
+
+--- Paragraph management.
+-- This function puts a new boolean flag onto a stack that is used to
+-- log the occurence of a new paragraph, while recursing into the coming
+-- vlist. After finishing recursing into the vlist, the flag needs to
+-- be removed from the stack. Depending on the flag, the then current
+-- paragraph can be finished.
+local function __vlist_pre_recurse()
+ tabinsert(__is_vlist_paragraph, false)
+end
+
+
+--- Paragraph management.
+-- Remove flag from stack after recursing into a vlist. If necessary,
+-- finish the current paragraph.
+local function __vlist_post_recurse()
+ local p = tabremove(__is_vlist_paragraph)
+ if p then
+ __finish_current_paragraph()
+ end
+end
+
+
+--- Handle tables lines and cells.
+-- Start a new paragraph before and after an hlist of subtype `alignment
+-- column or row` or `alignment cell`, depending on option `table_par`.
+--
+-- @param n hlist node.
+local function __handle_table(n)
+ local subtype = n.subtype
+ local table_par = __opts.table_par
+ if (subtype == 4) and (table_par == 1) then
+ __finish_current_paragraph()
+ elseif (subtype == 5) and (table_par == 2) then
+ __finish_current_paragraph()
+ end
+end
+
+
+--- Find paragraphs and strings.
+-- While scanning a node list, this call-back function finds nodes
+-- representing the start of a paragraph (local_par whatsit nodes) and
+-- string tags (user_defined whatsit nodes).
+--
+-- @param head Head node of current branch.
+-- @param n The current node.
+local function __visit_node(head, n)
+ local nid = n.id
+ -- Test for node containing a word string.
+ if nid == WHATSIT then
+ -- Test for word string tag.
+ if (n.subtype == USER_DEFINED) and (n.user_id == __uid_end_tag) then
+ __finish_current_word(n)
+ -- Test for paragraph start.
+ elseif n.subtype == LOCAL_PAR then
+ __finish_current_paragraph()
+ __is_vlist_paragraph[#__is_vlist_paragraph] = true
+ end
+ end
+end
+
+
+--- Table of call-back functions for node list recursion: store the
+--- word strings found in a node list.
+-- The call-back functions in this table identify chains of nodes
+-- representing word strings in a node list and stores the strings in
+-- the text document. A new paragraph is started at local_par whatsit
+-- nodes and after finishing a vlist containing a local_par whatsit
+-- node. Nodes of type `hlist` are recursed into as if they were
+-- non-existent. As an example, the LaTeX input `a\mbox{a b}b` is
+-- recognized as two strings `aa` and `bb`.
+--
+-- @class table
+-- @name __cb_store_words
+-- @field vlist_pre_recurse Paragraph management.
+-- @field vlist_post_recurse Paragraph management.
+-- @field hlist_pre_recurse Table management.
+-- @field hlist_post_recurse Table management.
+-- @field visit_node Find nodes representing paragraphs and words.
+local __cb_store_words = {
+
+ vlist_pre_recurse = __vlist_pre_recurse,
+ vlist_post_recurse = __vlist_post_recurse,
+ hlist_pre_recurse = __handle_table,
+ hlist_post_recurse = __handle_table,
+ visit_node = __visit_node,
+
+}
+
+
+--- Process node list according to this stage.
+-- This function recurses into the given node list, finds strings in
+-- tags and stores them in the text document.
+--
+-- @param head Node list.
+local function __process_node_list(head)
+ recurse_node_list(head, __cb_store_words)
+ -- Clean-up left-over word and/or paragraph.
+ __finish_current_paragraph()
+end
+
+
+-- Call-back status.
+local __is_active_storage
+
+
+--- Call-back function that processes the node list.
+-- <i>This function is not made available in the module table, but in
+-- the global package table!</i>
+--
+-- @param head Node list.
+local function cb_AtBeginShipout(box)
+ if __is_active_storage then
+ __process_node_list(tex.box[box])
+ end
+end
+
+
+--- Start storing text.
+-- After calling this function, text is stored in the text document.
+local function enable_text_storage()
+ __is_active_storage = true
+end
+M.enable_text_storage = enable_text_storage
+
+
+--- Stop storing text.
+-- After calling this function, no more text is stored in the text
+-- document.
+local function disable_text_storage()
+ __is_active_storage = false
+end
+M.disable_text_storage = disable_text_storage
+
+
+--- Module initialisation.
+--
+local function __init()
+ -- Get local references to package ressources.
+ __text_document = PKG_spelling.res.text_document
+ __uid_start_tag = PKG_spelling.res.whatsit_ids.start_tag
+ __uid_end_tag = PKG_spelling.res.whatsit_ids.end_tag
+ -- Make \AtBeginShipout function available in package table.
+ PKG_spelling.cb_AtBeginShipout = cb_AtBeginShipout
+ -- Create empty paragraph management stack.
+ __is_vlist_paragraph = {}
+ -- Remember call-back status.
+ __is_active_storage = false
+ -- Set default table paragraph behaviour.
+ set_table_paragraphs(0)
+end
+
+
+-- Initialize module.
+__init()
+
+
+-- Return module table.
+return M
diff --git a/macros/luatex/generic/spelling/spelling-stage-4.lua b/macros/luatex/generic/spelling/spelling-stage-4.lua
new file mode 100644
index 0000000000..ce027c8c50
--- /dev/null
+++ b/macros/luatex/generic/spelling/spelling-stage-4.lua
@@ -0,0 +1,202 @@
+--- spelling-stage-4.lua
+--- Copyright 2012, 2013 Stephan Hennig
+--
+-- This work may be distributed and/or modified under the conditions of
+-- the LaTeX Project Public License, either version 1.3 of this license
+-- or (at your option) any later version. The latest version of this
+-- license is in http://www.latex-project.org/lppl.txt
+-- and version 1.3 or later is part of all distributions of LaTeX
+-- version 2005/12/01 or later.
+--
+-- See file README for more information.
+--
+
+
+--- At the end of a LuaTeX run, write the text stored in a text document
+--- data structure to a file.
+-- This module provides means to write the text stored in a text
+-- document data structure to a file at the end of a LuaTeX run.
+--
+-- @author Stephan Hennig
+-- @copyright 2012, 2013 Stephan Hennig
+-- @release version 0.41
+--
+-- @trick Prevent LuaDoc from looking past here for module description.
+--[[ Trick LuaDoc into entering 'module' mode without using that command.
+module(...)
+--]]
+
+
+-- Module table.
+local M = {}
+
+
+-- Import external modules.
+local unicode = require('unicode')
+
+
+-- Function short-cuts.
+local tabconcat = table.concat
+local tabinsert = table.insert
+
+local Ulen = unicode.utf8.len
+
+
+-- Declare local variables to store references to resources that are
+-- provided by external code.
+--
+-- Text document data structure.
+local __text_document
+
+
+--- Module options.
+-- This table contains all module options. User functions to set
+-- options are provided.
+--
+-- @class table
+-- @name __opts
+-- @field output_file_name Output file name.
+-- @field output_line_length Line length in output.
+local __opts = {
+ output_file_name,
+ output_line_lenght,
+}
+
+
+--- Set output file name.
+-- Text output will be written to a file with the given name.
+--
+-- @param name New output file name.
+local function set_output_file_name(name)
+ __opts.output_file_name = name
+end
+M.set_output_file_name = set_output_file_name
+
+
+--- Set output line length.
+-- Set the number of columns in text output. Text output will be
+-- wrapped at spaces so that lines don't contain more than the specified
+-- number of characters per line. There's one exception: if a word is
+-- longer than the specified number of characters, the word is put on
+-- its own line and that line will be overfull.
+--
+-- @param cols New line length in output. If the argument is smaller
+-- than 1, lines aren't wrapped, i.e., all text of a paragraph is put on
+-- a single line.
+local function set_output_line_length(cols)
+ __opts.output_line_length = cols
+end
+M.set_output_line_length = set_output_line_length
+
+
+--- Break a text paragraph into lines.
+-- Lines are broken at spaces only. Lines containing only one word may
+-- exceed maximum line length.
+--
+-- @param par A text paragraph (an array of words).
+-- @param max_line_len Maximum length of lines in wrapped paragraph. If
+-- the argument is less then 1, paragraph isn't wrapped at all.
+-- @return Table containing the lines of the paragraph.
+local function __wrap_text_paragraph(par, max_line_len)
+ local wrapped_par = {}
+ -- Index of first word on current line. Initialize current line with
+ -- first word of paragraph.
+ local line_start = 1
+ -- Track current line length.
+ local line_len = Ulen(par[line_start])
+ -- Iterate over remaining words in paragraph.
+ for i = 2,#par do
+ local word_len = Ulen(par[i])
+ local new_line_len = line_len + 1 + word_len
+ -- Maximum line length exceeded?
+ if new_line_len > max_line_len and max_line_len >= 1 then
+ -- Insert current line into wrapped paragraph.
+ tabinsert(wrapped_par, tabconcat(par, ' ', line_start, i-1))
+ -- Initialize new current line.
+ line_start = i
+ new_line_len = word_len
+ end
+ -- Append word to current line.
+ line_len = new_line_len
+ end
+ -- Insert last line of paragraph.
+ tabinsert(wrapped_par, tabconcat(par, ' ', line_start))
+ return wrapped_par
+end
+
+
+--- Write all text stored in the text document to a file.
+--
+local function __write_text_document()
+ -- Open output file.
+ local fname = __opts.output_file_name or (tex.jobname .. '.spell.txt')
+ local f = assert(io.open(fname, 'w'))
+ local max_line_len = __opts.output_line_length
+ -- Iterate through document paragraphs.
+ for _,par in ipairs(__text_document) do
+ -- Write wrapped paragraph to file with a leading empty line.
+ f:write('\n', tabconcat(__wrap_text_paragraph(par, max_line_len), '\n'), '\n')
+ -- Delete paragraph from memory.
+ __text_document[_] = nil
+ end
+ -- Close output file.
+ f:close()
+end
+
+
+--- Callback function that writes all document text into a file.
+local function __cb_stopr_pkg_spelling()
+ __write_text_document()
+end
+
+
+-- Call-back status.
+local __is_active_output
+
+
+--- Enable text document output.
+-- Registers call-back `stop_run` to output the text stored in the text
+-- document at the end of the LuaTeX run.
+local function enable_text_output()
+ if not __is_active_output then
+ -- Register call-back: At the end of the LuaTeX run, output all text
+ -- stored in the text document.
+ luatexbase.add_to_callback('stop_run', __write_text_document, '__cb_stop_run_pkg_spelling')
+ __is_active_output = true
+ end
+end
+M.enable_text_output = enable_text_output
+
+
+--- Disable text document output.
+-- De-registers call-back `stop_run`.
+local function disable_text_output()
+ if __is_active_output then
+ -- De-register call-back.
+ luatexbase.remove_from_callback('stop_run', '__cb_stop_run_pkg_spelling')
+ __is_active_output = false
+ end
+end
+M.disable_text_output = disable_text_output
+
+
+--- Module initialisation.
+--
+local function __init()
+ -- Get local references to package ressources.
+ __text_document = PKG_spelling.res.text_document
+ -- Set default output file name.
+ set_output_file_name(nil)
+ -- Set default output line length.
+ set_output_line_length(72)
+ -- Remember call-back status.
+ __is_active_output = false
+end
+
+
+-- Initialize module.
+__init()
+
+
+-- Return module table.
+return M
diff --git a/macros/luatex/generic/spelling/spelling.sty b/macros/luatex/generic/spelling/spelling.sty
new file mode 100644
index 0000000000..8e780b432f
--- /dev/null
+++ b/macros/luatex/generic/spelling/spelling.sty
@@ -0,0 +1,150 @@
+%%% spelling.sty
+%%% Copyright 2012, 2013 Stephan Hennig
+%%
+%% This work may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.3 of this license
+%% or (at your option) any later version. The latest version of this
+%% license is in http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% See file README for more information.
+%%
+\ProvidesPackage{spelling}
+ [2013/05/25 v0.41 Support for spell-checking of LuaTeX documents (SH)]
+\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+% Test for the LuaTeX engine.
+\RequirePackage{ifluatex}
+\ifluatex
+\else
+\PackageError{spelling}{LuaTeX engine required}{You could try with the
+ `lualatex' command.}
+\fi
+% Lua module version management.
+\RequirePackage{luatexbase-modutils}
+% LuaTeX call-back management.
+\RequirePackage{luatexbase-mcb}
+% User-defined whatsit node ID allocation.
+\RequirePackage{luatexbase-attr}
+% Load main Lua file.
+\directlua name {spelling}{
+ % The main Lua file is not a module, so we must pass a full path to
+ % `dofile`.
+ local f = kpse.find_file('spelling-main.lua', 'lua')
+ dofile(f)
+}
+% Words are extracted after pages have been built. In lack of a proper
+% Lua call-back, we're hooking into shipout from the LaTeX side.
+\RequirePackage{atbegshi}
+\AtBeginShipout{%
+ \directlua name {spelling-atbeginshipout}{
+ PKG_spelling.cb_AtBeginShipout(\the\AtBeginShipoutBox)
+ }%
+}
+% Provide command for reading-in a list of bad spellings.
+\newcommand*{\spellingreadbad}[1]{%
+ \directlua{
+ PKG_spelling.stage[1].parse_bad_plain_list_file('\luaescapestring{#1}')
+ }%
+}
+% Provide command for reading-in a list of good spellings.
+\newcommand*{\spellingreadgood}[1]{%
+ \directlua{
+ PKG_spelling.stage[1].parse_good_plain_list_file('\luaescapestring{#1}')
+ }%
+}
+% Provide command for reading bad spellings from a LanguageTool XML
+% file.
+\newcommand*{\spellingreadLT}[1]{%
+ \directlua{
+ PKG_spelling.stage[1].parse_XML_LanguageTool_file('\luaescapestring{#1}')
+ }%
+}
+% Provide command for reading match rules from a file. Argument must be
+% a file name.
+\newcommand*{\spellingmatchrules}[1]{%
+ \directlua{
+ PKG_spelling.stage[1].read_match_rules('\luaescapestring{#1}')
+ }%
+}
+% Provide command for enabling/disabling visual feedback.
+\newcommand*{\spellinghighlight}[1]{%
+ \directlua{
+ if '\luaescapestring{#1}' == 'on' then
+ PKG_spelling.stage[2].enable_word_highlighting()
+ else
+ PKG_spelling.stage[2].disable_word_highlighting()
+ end
+ }%
+}
+% Provide command for setting visual feedback colour.
+\newcommand*{\spellinghighlightcolor}[1]{%
+ \directlua{
+ PKG_spelling.stage[2].set_highlight_color('\luaescapestring{#1}')
+ }%
+}
+% Provide command for enabling/disabling text ouput.
+\newcommand*{\spellingoutput}[1]{%
+ \directlua{
+ if '\luaescapestring{#1}' == 'on' then
+ PKG_spelling.stage[4].enable_text_output()
+ else
+ PKG_spelling.stage[4].disable_text_output()
+ end
+ }%
+}
+% Provide command for setting text output file name.
+\newcommand*{\spellingoutputname}[1]{%
+ \directlua{
+ PKG_spelling.stage[4].set_output_file_name('\luaescapestring{#1}')
+ }%
+}
+% Provide command for setting text output file line length.
+\newcommand*{\spellingoutputlinelength}[1]{%
+ \directlua{
+ PKG_spelling.stage[4].set_output_line_length(\luaescapestring{#1})
+ }%
+}
+% Provide command for enabling/disabling text extraction.
+\newcommand*{\spellingextract}[1]{%
+ \directlua{
+ if '\luaescapestring{#1}' == 'on' then
+ PKG_spelling.stage[2].enable_text_tagging()
+ else
+ PKG_spelling.stage[2].disable_text_tagging()
+ end
+ }%
+}
+% Provide command to declare code point mappings.
+\newcommand*{\spellingmapping}[2]{%
+ \directlua{
+ local r = PKG_spelling.stage[2].set_mapping(\luaescapestring{#1}, '\luaescapestring{#2}')
+ if r == false then
+ texio.write_nl('package spelling: invalid mapping: \luaescapestring{#1} => \luaescapestring{#2}')
+ end
+ }%
+}
+% Provide command to clear all existing code point mappings.
+\newcommand*{\spellingclearallmappings}{%
+ \directlua{
+ PKG_spelling.stage[2].clear_all_mappings()
+ }%
+}
+% Provide command to specify table paragraph behaviour.
+\newcommand*{\spellingtablepar}[1]{%
+ \directlua{
+ PKG_spelling.stage[3].set_table_paragraphs(\luaescapestring{#1})
+ }%
+}
+%
+% Read bad and good spellings from default sources.
+\directlua{
+ PKG_spelling.stage[1].parse_default_bad_and_good()
+}%
+%
+% Enable visual feedback.
+\spellinghighlight{on}
+% Enable text ouput at the end of the LuaTeX run.
+\spellingoutput{on}
+% Enable text extraction.
+\spellingextract{on}
diff --git a/macros/luatex/latex/addliga/README b/macros/luatex/latex/addliga/README
new file mode 100644
index 0000000000..cab7bd12a6
--- /dev/null
+++ b/macros/luatex/latex/addliga/README
@@ -0,0 +1,6 @@
+The addliga package allows LuaLaTeX users to access basic ligatures (ff, fi, ffi, fl, ffl) in legacy TrueType fonts accessed via fontspec.
+
+This package was written by Daniel Benjamin Miller, 2019, and is contributed to the public domain.
+
+Version History:
+April 30, 2019: 1.0
diff --git a/macros/luatex/latex/addliga/addliga.pdf b/macros/luatex/latex/addliga/addliga.pdf
new file mode 100644
index 0000000000..31b2d9e1d8
--- /dev/null
+++ b/macros/luatex/latex/addliga/addliga.pdf
Binary files differ
diff --git a/macros/luatex/latex/addliga/addliga.sty b/macros/luatex/latex/addliga/addliga.sty
new file mode 100644
index 0000000000..e9a3d0892d
--- /dev/null
+++ b/macros/luatex/latex/addliga/addliga.sty
@@ -0,0 +1,22 @@
+% !TEX TS-program = lualatex
+% addliga.sty
+% Version 1.0
+% Adds ligatures to TrueType fonts in LuaLaTeX
+% Written 2019 by Daniel Benjamin Miller <dbmiller@dbmiller.org>
+% Contributed to the Public Domain
+% No Rights Reserved
+\ProvidesPackage{addliga}[2019/04/30 addliga 1.0]
+\directlua{
+ fonts.handlers.otf.addfeature{
+ name = "liga",
+ type = "ligature",
+ data = {
+ ['ff']={"f","f"},
+ ['fi']={"f","i"},
+ ['ffi']={"f","f","i"},
+ ['fl']={"f","l"},
+ ['ffl']={"f","f","l"},
+ },
+ }
+}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/addliga/addliga.tex b/macros/luatex/latex/addliga/addliga.tex
new file mode 100644
index 0000000000..0468127223
--- /dev/null
+++ b/macros/luatex/latex/addliga/addliga.tex
@@ -0,0 +1,33 @@
+% !TEX TS-program = lualatex
+\documentclass{scrartcl}
+\setkomafont{disposition}{\bfseries}
+\KOMAoptions{fontsize=12pt}
+\usepackage[letterpaper]{geometry}
+\usepackage{addliga}
+\usepackage{fontspec}
+\setmainfont[Numbers={OldStyle}]{Domitian}
+\setmonofont[Scale=1.05]{CMU Typewriter Text Variable Width}
+\usepackage[protrusion=true,expansion=true]{microtype}
+\usepackage{realscripts}
+\usepackage[main=english,,latin.classical,nil]{babel}
+\newcommand{\laterm}[1]{\foreignlanguage{latin}{\textit{#1}}}
+\deffootnote[1.5em]{1.5em}{1em}{\makebox[1.5em][l]{\thefootnotemark.}}
+\usepackage[pdfusetitle,pdfa,hidelinks]{hyperref}\hypersetup{pdfencoding=unicode}
+\usepackage{hologo}
+\title{\normalfont\texttt{addliga}\\\large (version 1.0)}
+%\date{}
+\author{Daniel~Benjamin Miller\\\large(\texttt{dbmiller@dbmiller.org})}
+\begin{document}
+\maketitle
+The \texttt{fontspec}\footnote{\url{https://ctan.org/pkg/fontspec}} package enables use of OpenType and TrueType fonts in \hologo{LuaLaTeX} and \hologo{XeLaTeX}. Though legacy TrueType fonts often include at least a partial set of ligatures, these, unlike those of OpenType fonts, are not accessible through \texttt{fontspec}'s usual mechanisms. The \texttt{addliga} package is designed to allow easy use of basic TrueType font ligatures in \hologo{LuaLaTeX} by adding an OpenType \texttt{liga} lookup table to the loaded font. (\laterm{Nota bene}: not all fonts will contain ligature support; \texttt{addliga} only adds support for existing ligatures.) The ligatures supported are ff, fi, ffi, fl and ffl. This package has been contributed to the public domain.
+\section*{Basic Usage}
+\begin{verbatim}
+\documentclass{…}
+\usepackage{addliga}
+\usepackage{fontspec}
+\setmainfont{…}
+\begin{document}
+…
+\end{document}
+\end{verbatim}
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/arabluatex/README.md b/macros/luatex/latex/arabluatex/README.md
new file mode 100644
index 0000000000..c9dec25920
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/README.md
@@ -0,0 +1,146 @@
+---
+author:
+- Robert Alessi
+title: 'The arabluatex package – README file'
+---
+
+Overview
+========
+
+This package provides for [LuaLaTeX](http://luatex.org) an
+[ArabTeX](http://ctan.org/pkg/arabtex)-like interface to generate Arabic
+writing from an <span style="font-variant:small-caps;">ascii</span>
+transliteration. It is particularly well-suited for complex documents
+such as technical documents or critical editions where a lot of
+left-to-right commands intertwine with Arabic writing. arabluatex is
+able to process any ArabTeX input notation. Its output can be set in the
+same modes of vocalization as ArabTeX, or in different roman
+transliterations. It further allows many typographical refinements. It
+will eventually interact with some other packages yet to come to produce
+from `.tex` source files, in addition to printed books, `TEI xml`
+compliant critical editions and/or lexicons that can be searched,
+analyzed and correlated in various ways.
+
+License and disclamer
+=====================
+
+ArabLuaTeX – Processing ArabTeX notation under LuaLaTeX
+
+Copyright ⓒ 2016–2019 Robert Alessi
+
+Please send error reports and suggestions for improvements to Robert
+Alessi:
+
+- email: <alessi@robertalessi.net>
+
+- website: <http://www.robertalessi.net/arabluatex>
+
+- comments, feature requests, bug reports:
+ <https://gitlab.com/ralessi/arabluatex/issues>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.
+
+This release of arabluatex consists of the following source files:
+
+- `arabluatex.ins`
+
+- `arabluatex.dtx`
+
+- `arabluatex.lua`
+
+- `arabluatex_voc.lua`
+
+- `arabluatex_fullvoc.lua`
+
+- `arabluatex_novoc.lua`
+
+- `arabluatex_trans.lua`
+
+License applicable to the documentation
+---------------------------------------
+
+Copyright ⓒ 2016–2019 Robert Alessi
+
+The documentation file `arabluatex.pdf` that is generated from the
+`arabluatex.dtx` source is licensed under the Creative Commons
+Attribution-ShareAlike 4.0 International License. To view a copy of this
+license, visit <http://creativecommons.org/licenses/by-sa/4.0/> or send
+a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
+
+Installation
+============
+
+1. Run `'lualatex arabluatex.ins'` to produce the `arabluatex.sty`
+ file;
+
+2. To finish the installation you have to move the following files into
+ a directory where LaTeX can find them. See the FAQ on `texfaq.org`
+ at <https://texfaq.org/FAQ-inst-wlcf> for more on this:
+
+ - `arabluatex.sty`
+
+ - `arabluatex-patch.sty`
+
+ - `arabluatex.lua`
+
+ - `arabluatex_voc.lua`
+
+ - `arabluatex_fullvoc.lua`
+
+ - `arabluatex_novoc.lua`
+
+ - `arabluatex_trans.lua`
+
+3. Additionally, those who use emacs with AUCTeX may copy
+ `arabluatex.el` to their `~/.emacs.d/auctex/auto` local directory.
+ This will enable the appropriate hooks for ArabLuaTeX in AUCTeX.
+
+Development, Git Repository
+===========================
+
+Browse the code
+---------------
+
+You can browse ArabLuaTeX repository on the web:
+<http://git.robertalessi.net/arabluatex>
+
+From this page, you can download all the releases of ArabLuaTeX. For
+instructions on how to install ArabLuaTeX, please see above.
+
+Comments, Feature requests, Bug Reports
+---------------------------------------
+
+<https://gitlab.com/ralessi/arabluatex/issues>
+
+Download the repository
+-----------------------
+
+ArabLuaTeX development is facilitated by git, a distributed version
+control system. You will need to install git (most GNU/Linux
+distributions package it in their repositories).
+
+Use this command to download the repository
+
+ git clone http://git.robertalessi.net/arabluatex
+
+A new directory named arabluatex will have been created, containing
+ArabLuaTeX.
+
+Git hosting
+-----------
+
+Make an account on <https://gitlab.com> and navigate (while logged in)
+to <https://gitlab.com/ralessi/arabluatex>. Click *Fork* and you will
+have in your account your own repository of `arabluatex` where you will
+be able to make whatever changes you like to.
diff --git a/macros/luatex/latex/arabluatex/arabluatex.dtx b/macros/luatex/latex/arabluatex/arabluatex.dtx
new file mode 100644
index 0000000000..001f962c70
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/arabluatex.dtx
@@ -0,0 +1,5181 @@
+% \iffalse meta-comment
+% ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX
+% Copyright (C) 2016--2019 Robert Alesssi
+%
+% Please send error reports and suggestions for improvements to Robert
+% Alessi <alessi@robertalessi.net>
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful, but
+% WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see
+% <http://www.gnu.org/licenses/>.
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{arabluatex.dtx}
+%</driver>
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{arabluatex}
+%<*package>
+ [2019/03/24 v1.17 An ArabTeX-like interface for LuaLaTeX]
+%</package>
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{filecontents}
+\begin{filecontents}{\jobname.bib}
+% This file is part of the `arabluatex' package
+%
+% ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX
+% Copyright (C) 2016--2019 Robert Alessi
+%
+% Please send error reports and suggestions for improvements to Robert
+% Alessi <alessi@robertalessi.net>
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful, but
+% WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see
+% <http://www.gnu.org/licenses/>.
+
+@software{pkg:arabtex,
+ author = {Lagally, Klaus},
+ maintainer = {Lagally, Klaus},
+ title = {Arab\TeX},
+ indextitle = {Arab\TeX},
+ date = {2004-11-03},
+ version = {4.00},
+ url =
+ {http://mirrors.ctan.org/language/arabic/arabtex/doc/html/arabtex.htm},
+ subtitle = {Typesetting Arabic and Hebrew},
+ titleaddon = {User Manual Version 4.00}
+}
+
+@software{pkg:amiri,
+ author = {Hosny, Khaled},
+ maintainer = {Hosny, Khaled},
+ title = {Amiri},
+ indextitle = {Amiri},
+ date = {2017-12-13},
+ url = {http://www.amirifont.org/}
+}
+
+@Book{Habash,
+ author = {Habash, Nizar Y.},
+ title = {Introduction to Arabic Natural Language Processing},
+ year = 2010,
+ series = {Synthesis Lectures on Human Language Technologies},
+ number = 10,
+ publisher = {Morgan \& Claypool Publishers},
+ location = {Toronto}
+}
+
+@MVBook{Wright,
+ author = {Wright, W. LL.D},
+ title = {A Grammar of the Arabic Language},
+ indextitle = {Grammar of the Arabic Language, A},
+ year = 1896,
+ editor = {Robertson Smith, W. and de Goeje, M. J.},
+ editortype = {reviser},
+ foreword = {Cachia, Pierre},
+ edition = 3,
+ volumes = 2,
+ pagination = {none},
+ publisher = {Librairie du Liban},
+ location = {Beirut},
+ annote = {New impression, 1996}
+}
+
+@Manual{din31635,
+ label = {{DIN 31~635}},
+ title = {Information and Documentation - Romanization of the
+ Arabic Alphabet for Arabic, Ottoman-Turkish,
+ Persian, Kurdish, Urdu and Pushto},
+ date = {2011-07},
+ url = {http://www.din.de}
+}
+
+@InProceedings{dmg,
+ author = {Brockelmann, Carl and Fischer, August and Heffening,
+ W. and Taeschner, Franz},
+ shorttitle = {Die Transliteration der arabischen Schrift},
+ title = {Die Transliteration der arabischen Schrift in ihrer
+ Anwendung auf die Hauptliteratursprachen der
+ islamischen Welt},
+ indextitle = {Transliteration der arabischen Schrift, Die},
+ year = 1935,
+ booktitle = {Denkschrift dem 19. internationalen
+ Orientalistenkongreß in Rom vorgelegt von der
+ Transkriptionkommission der Deutschen
+ Morgenländischen Gesellschaft},
+ editor = {van Ronkel, Ph. S. and Spies, Otto},
+ editortype = {collaborator},
+ publisher = {Deutsche Morgenländische Gesellschaft, in Kommission
+ bei F. A. Brockaus},
+ url =
+ {http://www.naher-osten.uni-muenchen.de/studium_lehre/werkzeugkasten/dmgtransliteration.pdf},
+ location = {Leipzig}
+}
+
+@MVBook{Lane,
+ author = {Lane, Edward William},
+ title = {An Arabic-English lexicon},
+ date = {1863/1893},
+ indextitle = {Arabic-English Lexicon, An},
+ volumes = 8,
+ shorthand = {Lane, \emph{Lexicon}},
+ pagination = {none},
+ publisher = {Williams and Norgate},
+ location = {London -- Edinburgh}
+}
+\end{filecontents}
+\usepackage[english]{babel}
+\usepackage{dox}
+\doxitem{Option}{option}{options}
+\usepackage{fontspec}
+\usepackage{microtype}
+\defaultfontfeatures{RawFeature={+liga}}
+\setmainfont{Old Standard}[SmallCapsFont={Latin Modern Roman Caps},
+ RawFeature={+mark;+ccmp;+ss05;+ss06}]
+\usepackage{newunicodechar}
+\newunicodechar{ǧ}{ǧ} % Old Standard does not include ǧ/Ǧ
+\newunicodechar{Ǧ}{Ǧ} %
+\usepackage{metalogox}
+\usepackage{arabluatex}[2019/03/24]
+\SetArbUp{\textsuperscript{\thinspace#1}} % Old Standard needs this
+\usepackage[nopar]{quran}
+\usepackage[noindex]{nameauth}
+\usepackage{varioref}
+\usepackage{hyperxmp}
+\PassOptionsToPackage{pdfa}{hyperref}
+\usepackage{hypdoc}
+\usepackage{uri}
+\usepackage{bookmark}
+\usepackage{authblk}
+\hypersetup{unicode=true, colorlinks, allcolors=blue,
+ linktocpage=true, pdfauthor={Robert Alessi}, pdftitle={The
+ arabluatex package}, pdfcontactemail={alessi@robertalessi.net},
+ pdfcontacturl={http://www.robertalessi.net/arabluatex},
+ pdfcopyright={Copyright (C) 2016--2019 Robert Alessi
+ <alessi@robertalessi.net>. This document is licensed under the
+ Creative Commons Attribution-ShareAlike 4.0 International
+ License. To view a copy of this license, visit
+ http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to
+ Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.},
+ pdflicenseurl={https://creativecommons.org/licenses/by-sa/4.0/legalcode},
+ pdfmetalang={en-US}, pdftype={Text}, pdfkeywords={Arabic language,
+ arabtex, luatex}}
+\usepackage[scale=1.5]{ccicons}
+\usepackage[lot]{multitoc}
+\usepackage{enumitem}
+\setlist{nosep}
+\setlist[itemize]{label=\textendash}
+\setlist[enumerate,1]{label=(\alph*)}
+\setlist[enumerate,2]{label=\roman*.}
+\newlist{enumabjad}{enumerate}{10}
+\setlist[enumabjad]{label={\abjad{\arabic*}}}
+\usepackage{multicol}
+\usepackage{cleveref}
+\crefname{footnote}{note}{notes}
+\usepackage{quoting}
+\quotingsetup{noorphans, rightmargin=0pt}
+\renewcommand*{\quotingfont}{\footnotesize}
+\usepackage[position=below]{caption}
+\usepackage{lineno}
+\usepackage{longtable}
+\usepackage{booktabs}
+\usepackage[defaultlines=3,all]{nowidow}
+\usepackage{needspace}
+\usepackage{addlines}
+\usepackage{relsize}
+\usepackage{tikz}
+\usepackage[breakable, skins, xparse, minted]{tcolorbox}
+\tcbset{colback=white, boxrule=.15mm, colframe=red!50!white,
+ breakable}
+\newtcbox{\arabluabox}{boxrule=.3mm, left=0mm, right=0mm, top=0mm,
+ bottom=0mm}
+\newtcblisting{example}{minted options={linenos, numbersep=0mm,
+ fontsize=\smaller}}
+\newtcblisting{code}{minted options={linenos, numbersep=0mm,
+ fontsize=\smaller}, listing
+ only}
+\newcommand{\package}[1]{\textsf{#1}\index{#1=#1 (package)}}
+\usepackage[contents]{colordoc}
+\usepackage{csquotes}
+\DeclareQuoteStyle{arabic}
+{\rmfamily\textquotedblright}{\rmfamily\textquotedblleft}
+{\rmfamily\textquoteright}{\rmfamily\textquoteleft}
+\usepackage[style=authoryear, indexing=cite]{biblatex}
+\DeclareIndexFieldFormat{indextitle}{\index{#1=\emph{#1}}}
+\addbibresource{arabluatex.bib}
+\usepackage{etoc}
+\etocsettocdepth{paragraph}
+\newcommand{\altableofcontents}{%
+ \begingroup
+ \etocsetstyle{section}{}{}
+ {\etocsavedsectiontocline{%
+ \numberline{\etocnumber}\etocname}{\etocpage}}{}
+ \etocsetstyle{subsection}{}{}
+ {\etocsavedsubsectiontocline{%
+ \numberline{\etocnumber}\etocname}{\etocpage}}{}%
+ \etocsetstyle{subsubsection}{}{}
+ {\etocsavedsubsubsectiontocline{%
+ \numberline{\etocnumber}\etocname}{\etocpage}}{}%
+ \etocsetstyle{paragraph}{}{\leftskip2cm\rightskip 2.2em \parfillskip
+ 0pt plus 1fil\relax \nobreak}
+ {\noindent\etocname{} \etocpage{} }{\par}%
+ \etocmulticolstyle[2]{\section*{Contents}}
+ \pdfbookmark[1]{Contents}{toc}
+ \tableofcontents
+ \endgroup}
+\EnableCrossrefs
+\RecordChanges
+\CodelineIndex
+\begin{document}
+ \DocInput{arabluatex.dtx}
+ \printbibliography[heading=bibintoc]
+ \phantomsection
+ \addcontentsline{toc}{section}{Change History}
+ \PrintChanges
+ \phantomsection
+ \addcontentsline{toc}{section}{Index}
+ \PrintIndex
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{919}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+% \makeatletter
+% \let\org@changes@\changes@
+% \def\my@changes v#1.#2.#3\@nil{%
+% \org@changes@{v#1.\six@digits{#2}.#3=v#1.#2.#3}%
+% }%
+% \newcommand*{\six@digits}[1]{%
+% \ifnum#1<100000 0\fi
+% \ifnum#1<10000 0\fi
+% \ifnum#1<1000 0\fi
+% \ifnum#1<100 0\fi
+% \two@digits{#1}%
+% }%
+% \renewcommand*{\changes@}[1]{%
+% \my@changes#1.\@nil
+% }%
+% \makeatother
+%
+% \changes{v1.0}{2016/03/29}{Initial release}
+% \changes{v1.0.1}{2016/03/31}{Minor update of the documentation}
+%
+% \DoNotIndex{\newcommand,\newenvironment,\renewcommand}
+% \DoNotIndex{\~,\AtBeginDocument,\bgroup,\csname}
+% \DoNotIndex{\DeclareDocumentCommand,\def,\edef,\egroup}
+% \DoNotIndex{\else,\endcsname,\endinput,\expandafter,\fi}
+% \DoNotIndex{\ifdef,\ifdefined,\ifx,\MessageBreak,\NeedsTeXFormat}
+% \DoNotIndex{\NewDocumentCommand,\newif,\PackageError,\PackageWarning}
+% \DoNotIndex{\relax,\RenewDocumentCommand,\string,\verb,\let}
+% \DoNotIndex{\enskip}
+%
+% \providecommand*{\url}{\texttt}
+% \GetFileInfo{arabluatex.dtx}
+%
+% \newcommand*{\NEWfeature}[1]{%
+% \hskip 1sp \marginpar{\small\sffamily\raggedright
+% New feature\\#1}}
+%
+% \title{\tcbox[colframe=black, enhanced, tikznode, drop lifted
+% shadow, colback=white, boxrule=.25mm]%
+% {The \textsf{arabluatex} package\\
+% \fileversion\ -- \filedate}}
+%
+% \author{Robert Alessi \\
+% \href{mailto:alessi@robertalessi.net?Subject=arabluatex package}%
+% {\texttt{alessi@robertalessi.net}}}
+% \date{}
+%
+% \maketitle
+% \footnotesize
+% \altableofcontents
+% \listoftables
+% \normalsize
+%
+% \begin{abstract}
+% This package provides for {\LuaLaTeX} an Arab{\TeX}-like interface
+% to generate Arabic writing from an \textsc{ascii}
+% transliteration. It is particularly well-suited for complex
+% documents such as technical documents or critical editions where a
+% lot of left-to-right commands intertwine with Arabic
+% writing. \package{arabluatex} is able to process any Arab\TeX\
+% input notation. Its output can be set in the same modes of
+% vocalization as Arab\TeX, or in different roman
+% transliterations. It further allows many typographical
+% refinements. It will eventually interact with some other packages
+% yet to come to produce from \verb|.tex| source files, in addition
+% to printed books, \texttt{TEI xml} compliant critical editions
+% and/or lexicons that can be searched, analyzed and correlated in
+% various ways.
+% \end{abstract}
+%
+% \section*{License and disclamer}
+% \addcontentsline{toc}{section}{License and disclamer}
+% \subsection*{License applicable to the software}
+% \label{sec:license-software}
+%
+% \package{arabluatex} --- Processing Arab\TeX\ notation under Lua\LaTeX.\\
+% Copyright \textcopyright\ 2016--2019 Robert Alessi
+%
+% Please send error reports and suggestions for improvements to Robert
+% Alessi:
+% \begin{itemize}
+% \item email: \mailto[arabluatex package]{alessi@roberalessi.net}
+% \item website: \url{http://www.robertalessi.net/arabluatex}
+% \item development: \url{http://git.robertalessi.net/arabluatex}
+% \item comments, feature requests, bug reports:
+% \url{https://gitlab.com/ralessi/arabluatex/issues}
+% \end{itemize}
+%
+% \marginpar{\texttt{gpl3+}}
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful, but
+% WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see
+% <http://www.gnu.org/licenses/>.
+%
+% This release of \package{arabluatex} consists of the following
+% source files:
+% \begin{itemize}
+% \item |arabluatex.ins|
+% \item |arabluatex.dtx|
+% \item |arabluatex.lua|
+% \item |arabluatex_voc.lua|
+% \item |arabluatex_fullvoc.lua|
+% \item |arabluatex_novoc.lua|
+% \item |arabluatex_trans.lua|
+% \item |arabluatex.el|
+% \end{itemize}
+%
+% \subsection*{License applicable to this document}
+% \label{sec:documentation-license}
+% Copyright \textcopyright\ 2016--2019 Robert Alessi
+%
+% \ccbysa\marginpar{\texttt{CC BY-SA 4.0}}
+% This document is licensed under the Creative Commons
+% Attribution-ShareAlike 4.0 International License. To view a copy of
+% this license, visit
+% \url{http://creativecommons.org/licenses/by-sa/4.0/} or send a
+% letter to Creative Commons, PO Box 1866, Mountain View, CA 94042,
+% USA.
+%
+% \section{Introduction}
+% In comparison to Prof. Lagally's outstanding Arab\TeX,\footnote{See
+% \url{http://ctan.org/pkg/arabtex}} Arab{\LuaTeX} is at present
+% nothing more than a modest piece of software. Hopefully---if I may
+% say so---it will eventually provide all of its valuable qualities to
+% the {\LuaLaTeX} users.
+%
+% \package{arabtex} dates back to 1992. As far as I know, it was then
+% the first and only way to typeset Arabic texts with \TeX\ and
+% \LaTeX. To achieve that, \package{arabtex} provided---and still
+% does---an Arabic font in \arb[trans]{\uc{nasxI}} style and a macro
+% package that defined its own input notation which was, as the author
+% stated, \enquote{both machine, and human, readable, and suited for
+% electronic transmission and e-mail
+% communication}.\footnote{\textcite[2]{pkg:arabtex}.} Even if the
+% same can be said about Unicode, Arab\TeX\ \textsc{ASCII} input
+% notation still surpasses Unicode input, in my opinion, when it comes
+% to typesetting complex documents, such as scientific documents or
+% critical editions where footnotes and other kind of annotations can
+% be particulary abundant. It must also be said that most text editors
+% have trouble in displaying Arabic script connected with preceding or
+% following \LaTeX\ commands: it often happens that commands seem
+% misplaced, not to mention punctuation marks, or opening or closing
+% braces, brackets or parentheses that are unexpectedly displayed in
+% the wrong direction. Of course, some text editors provide ways to
+% get around such difficulties by inserting invisible Unicode
+% characters, such as LEFT-TO-RIGHT or RIGHT-TO-LEFT MARKS
+% (\texttt{U+200E}, \texttt{U+200F}), RTL/LTR \enquote{embed}
+% characters (\texttt{U+202B}, \texttt{U+202A}) and RLO/LRO
+% \enquote{bidi-override} characters (\texttt{U+202E},
+% \texttt{U+202D}).\footnote{Gáspár Sinai's Yudit probably has the
+% best Unicode support. See \url{http://www.yudit.org}.} Nonetheless,
+% it remains that inserting all the time these invisible characters in
+% complex documents rapidly becomes confusing and cumbersome.
+%
+% The great advantage of Arab\TeX\ notation is that it is immune from
+% all these difficulties, let alone its being clear and
+% straightforward. One also must remember that computers are designed
+% to process code. Arab\TeX\ notation is a way of encoding Arabic
+% language, just as \TeX\ \enquote{mathematics mode} is a way of
+% processing code to display mathematics. As such, not only does it
+% allow greater control over typographical features, but it also can
+% be processed in several different ways: so without going into
+% details, depending on one's wishes, Arab\TeX\ input can be full
+% vocalized Arabic (\emph{scriptio plena}), vocalized Arabic or
+% non-vocalized Arabic (\emph{scriptio defectiva}); it further can be
+% transliterated into whichever romanization standard the user may
+% choose.
+%
+% \label{ref:tei-to-come}
+% But there may be more to be said on that point, as encoding Arabic
+% also naturally encourages the coder to vocalize the texts---without
+% compelling him to do so, of course. Accurate coding may even have
+% other virtuous effects. For instance, hyphens may be used for tying
+% particles or prefixes to words, or to mark inflectional endings, and
+% so forth. In other words, accurate coding produces accurate texts
+% that can stand to close grammatical scrutiny and to complex textual
+% searches as well.
+%
+% Having that in mind, I started \package{arabluatex}. With the help
+% of Lua, it will eventually interact with some other packages yet to
+% come to produce from \verb|.tex| source files, in addition to
+% printed books, \texttt{TEI xml} compliant critical editions and/or
+% lexicons that can be searched, analyzed and correlated in various
+% ways.
+%
+%\subsection{\package{arabluatex} is for {\LuaLaTeX}}
+% It goes without saying that \package{arabluatex} requires
+% {\LuaLaTeX}. \TeX\ and \LaTeX\ have \package{arabtex}, and
+% {\XeLaTeX} has \package{arabxetex}. Both of them are much more
+% advanced than \package{arabluatex}, as they can process a number of
+% different languages,\footnote{\label{fn:arabtex-languages}To date,
+% both packages support Arabic, Maghribi, Urdu, Pashto, Sindhi,
+% Kashmiri, Uighuric and Old Malay; in addition to these,
+% \package{arabtex} also has a Hebrew mode, including Judeo-Arabic and
+% Yiddish.} whereas \package{arabluatex} can process only Arabic for
+% the time being. More languages will be included in future releases
+% of \package{arabluatex}.
+%
+% In comparison to \package{arabxetex}, \package{arabluatex} works in
+% a very different way. The former relies on the
+% \href{http://scripts.sil.org/TECkitIntro}{\texttt{TECkit}} engine
+% which converts Arab\TeX\ input on the fly into Unicode Arabic
+% script, whereas the latter passes Arab\TeX\ input on to a set of Lua
+% functions. At first, \LaTeX\ commands are taken care of in different
+% ways: some, as \cs{emph}, \cs{textbf} and the like are expected to
+% have Arabic text as arguments, while others, as \cs{LR}, for
+% \enquote{left-to-right text}, are not. Then, once what is Arabic is
+% carefully separated form what is not, it is processed by other Lua
+% functions which rely on different sets of correpondence tables to do
+% the actual conversion in accordance with one's wishes. Finally, Lua
+% returns to \TeX\ the converted strings---which may in turn contain
+% some other Arab\TeX\ input yet to be processed---for further
+% processing.
+%
+% \section{The basics of \package{arabluatex}}
+% \subsection{Activating \package{arabluatex}}
+% \package{arabluatex} is loaded the usual way:\\
+% \tcboxverb{\usepackage{arabluatex}}\\
+% The only requirement of \package{arabluatex} is {\LuaLaTeX};
+% it will complain if the document is compiled with another
+% engine. That aside, \package{arabluatex} does not load packages such
+% as \package{polyglossia}. Although it can work with
+% \package{polyglossia}, it does not require it.
+%
+% \paragraph{Font setup}
+% Any Arabic font can be defined to be used with
+% \package{arabluatex}. For example, assuming that \package{fontspec}
+% is loaded, this line may be inserted in the preamble, just above the
+% line that loads \package{arabluatex}:
+% \arabluabox{\cs{newfontfamily}\cs{arabicfont}\marg{fontname}[Script=Arabic]}
+% \noindent where \meta{fontname} is the standard name of the Arabic
+% font to be used.
+%
+% By default, if no Arabic font is selected, \package{arabluatex} will
+% issue a warning message and attempt to load the Amiri
+% font\footnote{\textcite{pkg:amiri}.} like so:---\\
+% \tcboxverb{\newfontfamily\arabicfont{Amiri}[Script=Arabic]}
+% \begin{quoting}
+% \textsc{Rem.} By default Amiri places the \arb[trans]{kasraT} in
+% combination with the \arb[trans]{ta^sdId} below the consonant,
+% like so: \arb{BBi}\,. That is correct, as at least in the oldest
+% manuscripts {\renewfontfamily\arabicfont{Amiri}[Script=Arabic,
+% RawFeature={+ss05}]\arb{BBi}} may stand for \arb{BBa} as
+% well as \arb{BBi}\,. See \textcite[i. 14 C--D]{Wright}. The placement
+% of the \arb[trans]{kasraT} above the consonant may be obtained by
+% selecting the |ss05| feature of the Amiri font, like
+% so:---\footnote{See the documentation of \package{amiri},
+% \textcite[6]{pkg:amiri}.}\\
+% \tcboxverb{\newfontfamily\arabicfont{Amiri}[Script=Arabic,RawFeature={+ss05}]}
+%
+% Other Arabic fonts may behave differently.
+% \end{quoting}
+%
+% \subsection{Options}
+% \label{sec:options}
+% \package{arabluatex} may be loaded with five global options, the
+% first four of which are mutually exclusive and may be overriden at
+% any point of the document (see below \vref{sec:local-options}):
+%
+% \DescribeOption{voc}\hfill\tcboxverb{Default}\\ In this mode,
+% which is the one selected by default, every short vowel written
+% generates its corresponding diacritical mark: \arb[trans]{.dammaT}
+% (\arb{Bu}), \arb[trans]{fat.haT} (\arb{Ba}) and \arb[trans]{kasraT}
+% (\arb{Bi}). If a vowel is followed by |N|, viz. \meta{uN, aN, iN},
+% then the corresponding \arb[trans]{tanwIn} (\arb{BuN}, \arb{B|aN}\,,
+% \arb{TaN}, \arb{BaN_A} or \arb{BiN}) is generated. Finally, \meta{u,
+% a, i} at the commencement of a word indicate a \enquote{connective
+% \arb[trans]{'alif}\,} (\arb[trans]{'alifu 'l-wa.sli}), but |voc|
+% mode does not show the \arb[trans]{wa.slaT} above the
+% \arb[trans]{'alif}; instead, the accompanying vowel may be expressed
+% at the beginning of a sentence (\arb{u} \arb{a} \arb{i}).
+%
+% \DescribeOption{fullvoc}\\ \label{fullvoc-mode}In addition to what
+% the |voc| mode does, |fullvoc| expresses the \arb[trans]{sukUn} and
+% the \arb[trans]{wa.slaT}.
+%
+% \DescribeOption{novoc}\\ None of the diacritics is showed in |novoc|
+% mode, unless otherwise specified (see \enquote{quoting} technique
+% below \vref{sec:quoting}).
+%
+% \DescribeOption{trans} \\ \label{ref:describe-trans}This mode
+% transliterates the Arab\TeX\ input into one of the accepted
+% standards. At present, three standards are supported (see below
+% \vref{sec:transliteration} for more details):
+% \begin{description}
+% \item[dmg] \emph{Deutsche Morgenländische Gesellschaft}, which is
+% selected by default;
+% \item[loc] \emph{Library of Congress};
+% \item[arabica] \emph{Arabica}.
+% \end{description}
+% More standards will be included in future releases of
+% \package{arabluatex}.
+%
+% \label{ref:export-global-opt}
+% \DescribeOption{export} |export|$=$|true|\verb+|+|false|
+% \hfill\tcboxverb{Default: false}\\ \label{export-mode}
+% \NEWfeature{v.1.13} This option acts as a named argument and does
+% not need a value as it defaults to |true| if it is used. It enables
+% \package{arabluatex} to produce a duplicate of the original |.tex|
+% source file in which all \textsc{ascii} strings are replaced with
+% Unicode equivalents. See below \vref{sec:arabtex2utf} for more
+% information.
+%
+% \subsubsection{Classic contrasted with modern typesetting of Arabic}
+% \label{sec:classic-modern-typesetting}
+% \NEWfeature{v.1.2} By default, \package{arabluatex} typesets Arabic
+% in a classic, traditional style the most prominent features of which
+% are the following:
+% \begin{itemize}
+% \item \enquote*{Classic} \arb[trans]{maddaT}: when
+% \arb[trans]{'alif} and \arb[trans]{hamzaT} accompanied by a simple
+% vowel or \arb[trans]{tanwIn} is preceded by an \arb[trans]{'alif} of
+% prolongation (\arb[voc]{BA}), then a mere \arb[trans]{hamzaT} is
+% written on the line, and a \arb[trans]{maddaT} is placed over the
+% \arb[trans]{'alif}, like so:---
+% \begin{quote}
+% |samA'uN| \arb[voc]{samA'uN} \arb[trans]{samA'uN}, |jA'a|
+% \arb[voc]{jA'a} \arb[trans]{jA'a}, |yatasA'alUna|
+% \arb[voc]{yatasA'alUna} \arb[trans]{yatasA'alUna}\footnote{Note
+% that in old mss. such forms as \arb[voc]{samA"'a"'a},
+% \arb[voc]{jA"'a"'a} are also found; see \textcite[i. 24
+% D]{Wright}.} (see \vpageref{ref:madda} for further details).
+% \end{quote}
+% \item The euphonic \arb[trans]{ta^sdId} is generated (see
+% \vpageref{ref:euphonic-tashdid}).
+% \item In |fullvoc| mode, the \arb[trans]{sukUn} is expressed.
+% \item In such words as \arb{^say'aN}, \arb{.zim'aN} and the like,
+% the \arb[trans]{hamzaT} alone is not written over the letter
+% \arb[trans]{yA'} with no diacritical points below as in
+% \arb{^sayy"'aN}, \arb{.zimy"'aN}, but over a horizontal stroke
+% placed in the continuation of the preceding letter. %
+% \iffalse
+%<*example>
+% \fi
+\begin{tcblisting}{text only}
+ Please note that only few Arabic fonts provide such contrivances. In
+ case this feature is not supported by some Arabic font, it is
+ advisable to use \cs{SetArbEasy}.
+\end{tcblisting}
+% \iffalse
+%</example>
+% \fi
+% \end{itemize}
+%
+% \DescribeMacro{\SetArbEasy} \NEWfeature{v1.4.4} Such refinements as
+% \enquote*{classic} \arb[trans]{maddaT} may be discarded by the
+% \cs{SetArbEasy} command, either globally in the preamble or locally
+% at any point of the document. The difference between \cs{SetArbEasy}
+% and its \enquote*{starred} version
+% \DescribeMacro{\SetArbEasy*}\cs{SetArbEasy*} is that the former
+% keeps the \arb[trans]{sukUn} that is generated by the |fullvoc|
+% mode, while the latter further takes it away. Default
+% \enquote*{classic} rules may be set back at any point of the
+% document with the \DescribeMacro{\SetArbDflt}\cs{SetArbDflt}
+% command. \NEWfeature{v1.6} \DescribeMacro{\SetArbDflt*}Assimilation
+% rules laid on \vref{ref:assimilation} may also be applied by the
+% \enquote*{starred} version of this command \cs{SetArbDflt*} either
+% in the preamble or at any point of the document.\footnote{For an
+% example, see \vref{sec:poetry-example}.} Examples follow:---
+% \begin{enumerate}
+% \item \cs{SetArbDflt}:
+% \begin{enumerate}
+% \item |voc| \arb[voc]{wa-mAta istisqA'aN qabla 'an yutimma
+% kitAba-hu fI nujUm-i 'l-samA'-i}
+% \item |fullvoc| \arb[fullvoc]{wa-mAta istisqA'aN qabla 'an yutimma
+% kitAba-hu fI nujUm-i 'l-samA'-i}
+% \item |trans| \arb[trans]{wa-mAta istisqA'aN qabla 'an yutimma
+% kitAba-hu fI nujUm-i 'l-samA'-i}
+% \end{enumerate}
+% \item \cs{SetArbDflt*}:
+% \begin{enumerate}\SetArbDflt*
+% \item |voc| \arb[voc]{wa-mAta istisqA'aN qabla 'an yutimma
+% kitAba-hu fI nujUm-i 'l-samA'-i}
+% \item |fullvoc| \arb[fullvoc]{wa-mAta istisqA'aN qabla 'an yutimma
+% kitAba-hu fI nujUm-i 'l-samA'-i}
+% \item |trans| \arb[trans]{wa-mAta istisqA'aN qabla 'an yutimma
+% kitAba-hu fI nujUm-i 'l-samA'-i}\SetArbDflt
+% \end{enumerate}
+% \item \cs{SetArbEasy}:
+% \begin{enumerate}\SetArbEasy
+% \item |voc| \arb[voc]{wa-mAta istisqA'aN qabla 'an yutimma
+% kitAba-hu fI nujUm-i 'l-samA'-i}
+% \item |fullvoc| \arb[fullvoc]{wa-mAta istisqA'aN qabla 'an yutimma
+% kitAba-hu fI nujUm-i 'l-samA'-i}
+% \item |trans| \arb[trans]{wa-mAta istisqA'aN qabla 'an yutimma
+% kitAba-hu fI nujUm-i 'l-samA'-i}\SetArbDflt
+% \end{enumerate}
+% \item \cs{SetArbEasy*}:
+% \begin{enumerate}\SetArbEasy*
+% \item |voc| \arb[voc]{wa-mAta istisqA'aN qabla 'an yutimma
+% kitAba-hu fI nujUm-i 'l-samA'-i}
+% \item |fullvoc| \arb[fullvoc]{wa-mAta istisqA'aN qabla 'an yutimma
+% kitAba-hu fI nujUm-i 'l-samA'-i}
+% \item |trans| \arb[trans]{wa-mAta istisqA'aN qabla 'an yutimma
+% kitAba-hu fI nujUm-i 'l-samA'-i}\SetArbDflt
+% \end{enumerate}
+% \end{enumerate}
+%
+% \iffalse
+%<*example>
+% \fi
+\begin{tcblisting}{text only}
+ Please note that this document is typeset with \cs{SetArbDflt}
+ throughout.
+\end{tcblisting}
+% \iffalse
+%</example>
+% \fi
+%
+%\subsection{Typing Arabic}
+% \DescribeMacro{\arb} Once \package{arabluatex} is loaded, a
+% \cs{arb}\marg{Arabic text} command is available for inserting Arabic
+% text in paragraphs, like so:---%
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ From \textcite[i. 1 A]{Wright}:--- Arabic, like Hebrew and
+ Syriac, is written and read from right to left. The letters
+ of the alphabet (\arb{.hurUf-u 'l-hijA'-i}, \arb{.hurUf-u
+ 'l-tahajjI}, \arb{al-.hurUf-u 'l-hijA'iyyaT-u}, or
+ \arb{.hurUf-u 'l-mu`jam-i}) are twenty-eight in number and
+ are all consonants, though three of them are also used as
+ vowels (see §~3).
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% \paragraph{Caveat}
+% For some reason, left-to-right paragraphs that start with Arabic
+% words lose their indentation. For the time being, this can be
+% circumvented by appending the \cs{indent} command at the
+% commencement of such paragraphs.
+%
+% \label{ref:ltr-lists}%
+% The same remark applies to left-to-right list environments: when
+% items start with Arabic words, the \cs{arb} command must be prefixed
+% with \cs{indent}. The following example comes from \textcite[i. 213
+% C]{Wright}:--- %
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \begin{enumerate}[label=\Roman*., start=16]
+ \item \indent\arb{fawA`ilu}*.
+ \begin{enumerate}[label=\arabic*.]
+ \item \indent\arb{fA`aluN}; as \arb{_hAtamuN} \emph{a
+ signet-ring}, ...
+ \end{enumerate}
+ \end{enumerate}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% \DescribeEnv{arab} Running paragraphs of Arabic text should rather
+% be placed inside an \emph{Arabic environment}
+%
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \begin{arab}
+ [...]
+ \end{arab}
+\end{code}
+% \iffalse
+%</example>
+% \fi
+% like so:---\label{ref:juha-code}
+% \setquotestyle{arabic}
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \begin{arab}
+ 'at_A .sadIquN 'il_A ju.hA ya.tlubu min-hu .himAra-hu
+ li-yarkaba-hu fI safraTiN qa.sIraTiN fa-qAla la-hu:
+ \enquote{sawfa 'u`Idu-hu 'ilay-ka fI 'l-masA'-i
+ wa-'adfa`u la-ka 'ujraTaN.} fa-qAla ju.hA:
+ \enquote{'anA 'AsifuN jiddaN 'annI lA 'asta.tI`u 'an
+ 'u.haqqiqa la-ka ra.gbata-ka fa-'l-.himAr-u laysa hunA
+ 'l-yawm-a.} wa-qabla 'an yutimma ju.hA kalAma-hu bada'a
+ 'l-.himAr-u yanhaqu fI 'i.s.tabli-hi. fa-qAla la-hu
+ .sadIqu-hu: \enquote{'innI 'asma`u .himAra-ka yA ju.hA
+ yanhaqu.} fa-qAla la-hu ju.hA: \enquote{.garIbuN
+ 'amru-ka yA .sadIqI 'a-tu.saddiqu 'l-.himAr-a
+ wa-tuka_d_diba-nI?}
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+% \setquotestyle{english}
+%
+% \subsubsection{Local options}
+% \label{sec:local-options}
+% As seen above in \vref{sec:options}, \package{arabluatex} may be
+% loaded with four mutually exclusive global options: |voc| (which is
+% the default option), |fullvoc|, |novoc| and |trans|. Whatever choice
+% has been made globally, it may be overriden at any point of the
+% document, as the \cs{arb} command may take any of the |voc|,
+% |fullvoc|, |novoc| or |trans| modes as optional argument, like
+% so:---
+% \begin{itemize}
+% \item \DescribeOption{voc} \cs{arb}|[voc]|\marg{Arabic text};
+% \item \DescribeOption{fullvoc} \cs{arb}|[fullvoc]|\marg{Arabic text};
+% \item \DescribeOption{novoc} \cs{arb}|[novoc]|\marg{Arabic text};
+% \item \DescribeOption{trans} \cs{arb}|[trans]|\marg{Arabic text}.
+% \end{itemize}
+%
+% The same optional arguments may be passed to the environment |arab|:
+% one may have \cs{begin}|{arab}|\oarg{mode}|...|\cs{end}|{arab}|,
+% where \meta{mode} may be any of |voc|, |fullvoc|, |novoc| or
+% |trans|.
+%
+%\section{Standard Arab\TeX\ input}
+%\subsection{Consonants}
+% \Cref{tab:arabtex-consonants} gives the Arab\TeX\ equivalents for
+% all of the Arabic consonants.
+%
+% \addlines[2]
+% \newcommand{\dmg}[1]{%
+% \SetTranslitConvention{dmg}%
+% \arb[trans]{#1}}
+% \newcommand{\loc}[1]{%
+% \SetTranslitConvention{loc}%
+% \arb[trans]{#1}\SetTranslitConvention{dmg}}
+% \newcommand{\brill}[1]{%
+% \SetTranslitConvention{arabica}%
+% \arb[trans]{#1}\SetTranslitConvention{dmg}}
+% \begin{longtable}{lllll}
+% \bottomrule
+% \caption*{\Cref*{tab:arabtex-consonants}: Standard Arab\TeX\
+% (consonants)}
+% \endfoot
+% \captionlistentry{Arab\TeX\ consonants}\\[-1em]
+% \toprule
+% Letter & \multicolumn{3}{l}{Transliteration\footnotemark}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & \\ \midrule
+% \endfirsthead
+% \toprule
+% Letter & \multicolumn{3}{l}{Transliteration}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & \\ \midrule
+% \endhead \footnotetext{See below \vref{sec:transliteration}.}
+% \label{tab:arabtex-consonants}
+% \arb[voc]{'i 'a 'u}\footnote{See below, \emph{Rem{.} a.} For
+% \arb[trans]{'alif} as a consonant, see \textcite[i. 16
+% D]{Wright}. The \arb[trans]{hamzaT} itself is encoded \texttt{<'>}
+% and may be followed by either \meta{u, a} or \meta{i}. See below
+% \vref{ref:hamza}.} & \dmg{'u 'a 'i} &
+% \loc{|'u, |'a, |'i} & \brill{|'u, |'a, |'i} & |'u| or |'a| or |'i| \\
+% \arb[novoc]{b} & \dmg{b} & \loc{b} & \brill{b} & |b| \\
+% \arb[novoc]{t} & \dmg{t} & \loc{t} & \brill{t} & |t| \\
+% \arb[novoc]{_t} & \dmg{_t} & \loc{_t} & \brill{_t} & |_t| \\
+% \arb[novoc]{j} & \dmg{j} & \loc{j} & \brill{j} & |^g| or |j| \\
+% \arb[novoc]{.h} & \dmg{.h} & \loc{.h} & \brill{.h} & |.h| \\
+% \arb[novoc]{x} & \dmg{x} & \loc{x} & \brill{x} & |_h| or |x|\\
+% \arb[novoc]{d} & \dmg{d} & \loc{d} & \brill{d} & |d| \\
+% \arb[novoc]{_d} & \dmg{_d} & \loc{_d} & \brill{_d} & |_d| \\
+% \arb[novoc]{r} & \dmg{r} & \loc{r} & \brill{r} & |r| \\
+% \arb[novoc]{z} & \dmg{z} & \loc{z} & \brill{z} & |z| \\
+% \arb[novoc]{s} & \dmg{s} & \loc{s} & \brill{s} & |s| \\
+% \arb[novoc]{^s} & \dmg{^s} & \loc{^s} & \brill{^s} & |^s| \\
+% \arb[novoc]{.s} & \dmg{.s} & \loc{.s} & \brill{.s} & |.s| \\
+% \arb[novoc]{.d} & \dmg{.d} & \loc{.d} & \brill{.d} & |.d| \\
+% \arb[novoc]{.t} & \dmg{.t} & \loc{.t} & \brill{.t} & |.t| \\
+% \arb[novoc]{.z} & \dmg{.z} & \loc{.z} & \brill{.z} & |.z| \\
+% \arb[novoc]{`} & \dmg{`} & \loc{`} & \brill{`} & |`| \\
+% \arb[novoc]{.g} & \dmg{.g} & \loc{.g} & \brill{.g} & |.g| \\
+% \arb[novoc]{f} & \dmg{f} & \loc{f} & \brill{f} & |f| \\
+% \arb[novoc]{q} & \dmg{q} & \loc{q} & \brill{q} & |q| \\
+% \arb[novoc]{k} & \dmg{k} & \loc{k} & \brill{k} & |k| \\
+% \arb[novoc]{l} & \dmg{l} & \loc{l} & \brill{l} & |l| \\
+% \arb[novoc]{m} & \dmg{m} & \loc{m} & \brill{m} & |m| \\
+% \arb[novoc]{n} & \dmg{n} & \loc{n} & \brill{n} & |n| \\
+% \arb[novoc]{h} & \dmg{h} & \loc{h} & \brill{h} & |h| \\
+% \arb[novoc]{w} & \dmg{w} & \loc{w} & \brill{w} & |w| \\
+% \arb[novoc]{y} & \dmg{y} & \loc{y} & \brill{y} & |y|\footnote{For
+% the letter \arb[novoc]{.y} with no diacritical points below, see
+% \emph{Rem{.} b.} below.} \\
+% \arb[novoc]{T} & \dmg{aT} & \loc{aT} & \brill{aT} & |T| \\
+% \end{longtable}
+% \begin{quoting}
+% \textsc{Rem.}~\emph{a.} Please note that in all cases of elision,
+% the \arb[trans]{'alifu 'l-wa.sli} is expressed only by the vowel
+% that accompanies the omitted \arb[trans]{hamzaT}: \meta{u, a, i}
+% as in |wa-inhazama| \arb[fullvoc]{wa-inhazama}
+% \arb[trans]{wa-inhazama}. For more details on the definite article
+% and the \arb[trans]{'alifu 'l-wa.sli} see
+% \vref{ref:definite-article}.
+%
+% That said, \arb{.A} as a consonant is actually the \emph{spiritus
+% lenis} of the Greeks and is distinguished by the
+% \arb[trans]{hamzaT} \arb[novoc]{(|"')} as it is shown in the above
+% table. However, the bare \arb[trans]{'alif} may also be encoded as
+% |.A| whether it be followed by a vowel or not, like so: |wa-.An|
+% \arb{wa-.An} \arb[trans]{wa-.An} (where the dot symbolizes the
+% absence of vowel), |wa-.Aan| \arb{wa-.Aan} \arb[trans]{wa-.Aan},
+% |wa-.Ain| \arb{wa-.Ain} \arb[trans]{wa-.Ain}.
+%
+% \textsc{Rem.}~\emph{b.} The letter \arb[novoc]{y} with two points
+% below, \arb{al-yA'u 'l-mu_tannATu min ta.hti-hA}, may also be
+% written without diacritical points as \arb[novoc]{Y}. When it is
+% used as a consonant, it is encoded |aY|, where |a| recalls the
+% \arb[trans]{fat.haT} placed above the preceding letter in
+% vocalized Arabic, like so: |qaY'uN| \arb{qaY'uN}
+% \arb[trans]{qaY'uN}, |^saY'uN| \arb{^saY'uN} \arb[trans]{^saY'uN},
+% |^saY'aN| \arb[trans]{^saY'aN} \arb{^saY'aN}.
+%
+% The same result may be achieved by encoding this letter as |.y|,
+% like so: |qa.y'uN| \arb{qa.y'uN} \arb[trans]{qa.y'uN}, |^sa.y'uN|
+% \arb{^sa.y'uN} \arb[trans]{^sa.y'uN}, |^sa.y'aN|
+% \arb[trans]{^sa.y'aN} \arb{^sa.y'aN}.
+% \end{quoting}
+%
+% \subsection{Additional characters}
+% \changes{v1.8.5}{2017/06/20}{Six additional Persian characters are
+% now available}
+% \NEWfeature{v1.8.5}\Cref{tab:arabtex-additional-characters} gives
+% the Arab\TeX\ equivalents for some additional Persian characters.
+%
+% \begin{longtable}{lllll}
+% \bottomrule
+% \caption*{\Cref*{tab:arabtex-additional-characters}: Standard
+% Arab\TeX\ (additional characters)}
+% \endfoot
+% \captionlistentry{Arab\TeX\ additional characters}\\[-1em]
+% \toprule
+% Letter & \multicolumn{3}{l}{Transliteration\footnotemark}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica}\footnotemark
+% & \\ \midrule
+% \endfirsthead
+% \toprule
+% Letter & \multicolumn{3}{l}{Transliteration}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & \\ \midrule
+% \endhead
+% \addtocounter{footnote}{-1}
+% \footnotetext{See below \vref{sec:transliteration}.}
+% \stepcounter{footnote}
+% \footnotetext{The characters that are listed in this table are not
+% included in this standard. However, as \texttt{arabica} is based on
+% \texttt{dmg}, the \texttt{dmg} equivalents have been used here.}
+% \label{tab:arabtex-additional-characters}
+% \hskip-1em\arb[novoc]{p} & \dmg{p} & \loc{p} & \brill{p} & \verb|p| \\
+% \arb[novoc]{^c} & \dmg{^c} & \loc{^c} & \brill{^c} & \verb|^c| \\
+% \arb[novoc]{^z} & \dmg{^z} & \loc{^z} & \brill{^z} & \verb|^z| \\
+% \arb[novoc]{v}\footnote{\label{fn:not-in-dmg}This character is not found in
+% \textcite[2]{dmg}. It is taken from the \textcite{din31635} standard.} &
+% \dmg{v} & \loc{v} & \brill{v} & \verb|v| \\
+% \arb[novoc]{g} & \dmg{g} & \loc{g} & \brill{g} & \verb|g| \\
+% \arb[novoc]{^n}\footnote{See \cref{fn:not-in-dmg}.} & \dmg{^n} &
+% \loc{^n} & \brill{^n} & \verb|^n| \\
+% \end{longtable}
+% \begin{quoting}
+% \textsc{Rem.} The alveolar consonants \arb[novoc]{^c} and
+% \arb[novoc]{^z} are processed as solar letters by
+% \package{arabluatex}.
+% \end{quoting}
+%
+% \subsection{Vowels}
+% \subsubsection{Long vowels}
+% \Cref{tab:arabtex-long-vowels} gives the Arab\TeX\ equivalents for
+% the Arabic long vowels.
+%
+% \begin{longtable}{lllll}
+% \bottomrule
+% \caption*{\Cref*{tab:arabtex-long-vowels}: Standard Arab\TeX\ (long
+% vowels)}
+% \endfoot
+% \captionlistentry{Arab\TeX\ long vowels}\\[-1em]
+% \toprule
+% Letter & \multicolumn{3}{l}{Transliteration\footnotemark}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & \\ \midrule
+% \endfirsthead
+% \toprule
+% Letter & \multicolumn{3}{l}{Transliteration}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & \\ \midrule
+% \endhead \footnotetext{See below \vref{sec:transliteration}.}
+% \label{tab:arabtex-long-vowels}
+% \arb[novoc]{A} & \dmg{A} & \loc{A} & \brill{A} & \verb|A| \\
+% \arb[novoc]{U} & \dmg{U} & \loc{U} & \brill{U} & \verb|U| \\
+% \arb[novoc]{I} & \dmg{I} & \loc{I} & \brill{I} &
+% \verb|I|\footnote{For the letter \arb[novoc]{I} with no diacritical
+% points, see \emph{Rem{.} c.} below.} \\
+% \arb[novoc]{_A}\footnote{$=$ \arb[trans]{al-'alif-u 'l-maq.sUraT-u}.}
+% & \dmg{_A} & \loc{_A} & \brill{_A} & \verb|_A| or \verb|Y| \\
+% \arb[novoc]{B_a} & \dmg{B_a} & \loc{B_a} & \brill{B_a} & \verb|_a| \\
+% \arb[novoc]{B_u} & \dmg{B_u} & \loc{B_u} & \brill{B_u} & \verb|_u| \\
+% \arb[novoc]{B_i} & \dmg{B_i} & \loc{B_i} & \brill{B_i} & \verb|_i| \\
+% \end{longtable}
+%
+% \begin{quoting}
+% \textsc{Rem.}~\emph{a.} The long vowels \arb[trans]{A, U, I},
+% otherwise called \arb[trans]{.hurUf-u 'l-madd-i}, \emph{the
+% letters of prolongation}, involve the placing of the short vowels
+% \arb[trans]{Ba, Bu, Bi} before the letters \arb[novoc]{A},
+% \arb[novoc]{U}, \arb[novoc]{I} respectively. \package{arabluatex}
+% does that automatically in case any from |voc|, |fullvoc| or
+% |trans| modes is selected e.g. \arb[voc]{qAla} \arb[trans]{qAla},
+% \arb[voc]{qIla} \arb[trans]{qIla}, \arb[voc]{yaqUlu}
+% \arb[trans]{yaqUlu}.
+%
+% \textsc{Rem.}~\emph{b.} Defective writings, such as
+% \arb[novoc]{B_a}, \arb[trans]{al-'alif-u 'l-ma.h_dUfaT-u}, or
+% defective writings of \arb[trans]{B_u} and \arb[trans]{B_i} are
+% encoded |_a| |_u| and |_i| respectively, e.g. |_d_alika|
+% \arb[voc]{_d_alika}, |al-mal_a'ikaT-u| |'l-ra.hm_an-u|
+% \arb[voc]{al-mal_a'ikaT-u 'l-ra.hm_an-u}, |.hu_dayfaT-u| |bn-u|
+% |'l-yamAn_i| \arb[fullvoc]{.hu_dayfaT-u bn-u 'l-yamAn_i} for
+% \arb[trans]{\uc{.hu_dayfaT-u} bn-u 'l-\uc{yamAn_i}}, etc.
+%
+% \textsc{Rem.}~\emph{c.} The letter \arb[novoc]{y} with two points
+% below, \arb{al-yA'u 'l-mu_tannATu min ta.hti-hA}, may also be
+% written without diacritical points as \arb[novoc]{Y}. When it is
+% used as a long vowel, it is encoded |iY|, where |i| recalls the
+% \arb[trans]{kasraT} placed below the preceding letter in vocalized
+% Arabic, like so: |liY| \arb{liY} \arb[trans]{liY}, |yam^siY|
+% \arb{yam^siY} \arb[trans]{yam^siY}.
+% \end{quoting}
+%
+% \subsubsection{Short vowels}
+% \Cref{tab:arabtex-short-vowels} gives the Arab\TeX\ equivalents for
+% the Arabic short vowels.
+%
+% \begin{longtable}{lllll}
+% \bottomrule
+% \caption*{\Cref*{tab:arabtex-short-vowels}: Standard Arab\TeX\
+% (short vowels)}
+% \endfoot
+% \captionlistentry{Arab\TeX\ short vowels}\\[-1em]
+% \toprule
+% Letter & \multicolumn{3}{l}{Transliteration\footnotemark}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & \\ \midrule
+% \endfirsthead
+% \toprule
+% Letter & \multicolumn{3}{l}{Transliteration}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & \\ \midrule
+% \endhead \footnotetext{See below \vref{sec:transliteration}.}
+% \label{tab:arabtex-short-vowels}
+% \arb[voc]{Ba} & \dmg{Ba} & \loc{Ba} & \brill{Ba} & \verb|a| \\
+% \arb[voc]{Bu} & \dmg{Bu} & \loc{Bu} & \brill{Bu} & \verb|u| \\
+% \arb[voc]{Bi} & \dmg{Bi} & \loc{Bi} & \brill{Bi} & \verb|i| \\
+% \arb[voc]{BaN} & \dmg{BaN} & \loc{BaN} & \brill{BaN} & \verb|aN| \\
+% \arb[voc]{BuN} & \dmg{BuN} & \loc{BuN} & \brill{BuN} & \verb|uN| \\
+% \arb[voc]{BiN} & \dmg{BiN} & \loc{BiN} & \brill{BiN} & \verb|iN| \\
+% \end{longtable}
+%
+% Whether Arabic texts be vocalized or not is essentially a matter of
+% personal choice. So one may use |voc| mode and decide not to write
+% vowels except at some particular places for disambiguation purposes,
+% or use |novoc| mode, not write vowels---as |novoc| normally does not
+% show them---except, again, where disambiguation is needed.\footnote{See
+% below \vref{sec:quoting}.}
+%
+% \iffalse
+%<*example>
+% \fi
+\begin{tcblisting}{text only}
+ However, it may be wise to always write the vowels, leaving to the
+ various modes provided by \package{arabluatex} to take care of
+ showing or not showing the vowels.
+\end{tcblisting}
+% \iffalse
+%</example>
+% \fi
+%
+% That said, there is no need to write the short vowels
+% \arb[trans]{fat.haT}, \arb[trans]{.dammaT} or \arb[trans]{kasraT}
+% except in the following cases:---
+% \begin{itemize}
+% \item at the commencement of a word, to indicate that a connective
+% \arb[trans]{'alif} is needed, with the exception of the article (see
+% below \vref{sec:quoting});
+% \item when \package{arabluatex} needs to perform a contextual
+% analysis to determine the carrier of the \arb[trans]{hamzaT};
+% \item in the various transliteration modes, as vowels are always
+% expressed in romanized Arabic.
+% \end{itemize}
+%
+%\section{\package{arabluatex} in action}
+%\subsection{The vowels and diphthongs}
+% \paragraph{Short vowels} As said above, they are written \meta{a, u,
+% i}:
+% \begin{quote}
+% |_halaqa| (or |xalaqa|) \arb[voc]{xalaqa} \arb[trans]{xalaqa},
+% |^samsuN| \arb[voc]{^samsuN} \arb[trans]{^samsuN}, |karImuN|
+% \arb[voc]{karImuN} \arb[trans]{\uc{karImuN}}.
+%
+% |bi-hi| \arb[voc]{bi-hi} \arb[trans]{bi-hi}, |'aqi.tuN|
+% \arb[voc]{'aqi.tuN} \arb[trans]{'aqi.tuN}.
+%
+% |la-hu| \arb[voc]{la-hu} \arb[trans]{la-hu}, |.hujjaTuN|
+% \arb[voc]{.hujjaTuN} \arb[trans]{.hujjaTuN}.
+% \end{quote}
+%
+%\paragraph{Long vowels} They are written \meta{U, A, I}:
+% \begin{quote}
+% |qAla| \arb[voc]{qAla} \arb[trans]{qAla}, |bI`a| \arb[voc]{bI`a}
+% \arb[trans]{bI`a}, |.tUruN| \arb[voc]{.tUruN} \arb[trans]{.tUruN},
+% |.tInuN| \arb[voc]{.tInuN} \arb[trans]{.tInuN}, |murU'aTuN|
+% \arb[voc]{murU'aTuN} \arb[trans]{murU'aTuN}.
+% \end{quote}
+%
+% \paragraph{\texorpdfstring{\arb[trans]{'alif maq.sUraT}}{ʾalif
+% maqṣūrah}} It is written \meta{\_A} or \meta{Y}:
+% \begin{quote}
+% |al-fat_A| \arb[voc]{al-fat_A} \arb[trans]{al-fat_A}, |al-maqh_A|
+% \arb[voc]{al-maqh_A} \arb[trans]{al-maqh_A}, |'il_A|
+% \arb[voc]{'il_A} \arb[trans]{'il_A}.
+% \end{quote}
+%
+% \paragraph{\texorpdfstring{\arb[trans]{'alif} \emph{otiosum}}{ʾalif
+% otiosum}} Said \arb[trans]{'alif-u 'l-wiqAyaT-i}, \enquote{the
+% guarding \arb[trans]{'alif}}\,, after \arb[novoc]{U} at the end of a
+% word, both when preceded by \arb[trans]{.dammaT} and by
+% \arb[trans]{fat.haT} is written \meta{UA} or \meta{aW, aWA}:
+% \begin{quote}
+% |na.sarUA| \arb[voc]{na.sarUA} \arb[trans]{na.sarUA}, |katabUA|
+% \arb[voc]{katabUA} \arb[trans]{katabUA}, |ya.gzUA|
+% \arb[voc]{ya.gzUA} \arb[trans]{ya.gzUA}, |ramaW|
+% \arb[fullvoc]{ramaW} \arb[trans]{ramaW}, |banaWA|
+% \arb[fullvoc]{banaWA}, \arb[trans]{banaWA}.
+% \end{quote}
+%
+% \paragraph{\texorpdfstring{\arb[trans]{'alif ma.h_dUfaT} and
+% defective \arb[trans]{U, I}}{ʾalif maḥá¸Å«fah and defective Å«, Ä«}}
+% They are written \meta{\_a, \_i \_u}:
+% \begin{quote}
+% |al-l_ah-u| \arb[voc]{al-l_ah-u} \arb[trans]{al-l_ah-u},
+% |'il_ahuN| \arb[voc]{'il_ahuN} \arb[trans]{'il_ahuN}.
+%
+% |al-ra.hm_an-u| \arb[voc]{al-ra.hm_an-u}
+% \arb[trans]{al-ra.hm_an-u}, |l_akin| \arb[voc]{l_akin}
+% \arb[trans]{l_akin}, |h_ahunA| \arb[voc]{h_ahunA}
+% \arb[trans]{h_ahunA}, |.hunayn-u| |bn-u| |'is.h_aq-a|
+% \arb[voc]{.hunayn-u bn-u 'is.h_aq-a} \arb[trans]{\uc{.hunayn}-u
+% bn-u \uc{'is.h_aq-a}}, |rabb_i| \arb[voc]{rabb_i}
+% \arb[trans]{rabb_i}, |al-`A.s_i| \arb[voc]{al-`A.s_i}
+% \arb[trans]{al-\uc{`A.s_i}}.
+% \end{quote}
+%
+% \paragraph{\texorpdfstring{Silent
+% \arb[novoc]{U}/\arb[novoc]{I}}{Silent ÙŠ/Ùˆ}}
+% Some words ending with \arb[voc]{BAT} are usually written
+% \arb[voc]{BawT} or \arb[voc]{B_aUT} instead of \arb[voc]{BAT}: see
+% \textcite[i. 12 A]{Wright}. \package{arabluatex} preserves that
+% particular writing; the same applies to words ending in
+% \arb[voc]{BayT} for \arb[voc]{BAT}\,. Long vowels \meta{U, I} shall
+% receive no \arb[trans]{sukUn} after a \arb[trans]{'alif ma.h_dUfaT}
+% and are discarded in |trans| mode:
+% \begin{quote}
+% |.hay_aUTuN| \arb[voc]{.hay_aUTuN} \arb[trans]{.hay_aUTuN},
+% |.sal_aUTuN| \arb[voc]{.sal_aUTuN} \arb[trans]{.sal_aUTuN},
+% |mi^sk_aUTuN| \arb[voc]{mi^sk_aUTuN} \arb[trans]{mi^s\-k_aUTuN},
+% |tawr_aITuN| \arb[voc]{tawr_aITuN} \arb[trans]{tawr_aITuN}.
+%
+% And so also: |al-rib_aIT-u| \arb[voc]{al-rib_aIT-u}
+% \arb[trans]{al-rib_aIT-u}.
+% \end{quote}
+%
+% \paragraph{\texorpdfstring{\arb[trans]{\uc{`amruNU}}, and the silent
+% \arb[novoc]{U}}{Ê¿Amrun, and the silent Ùˆ}} To that name a silent
+% \arb[novoc]{U} is added to distinguish it from
+% \arb[trans]{\uc{`umar-u}}: see \textcite[i. 12 C]{Wright}. In no way
+% this affects the sound of the \arb[trans]{tanwIn}, so it has to be
+% discarded in |trans| mode:
+% \begin{quote}
+% |`amruNU| \arb[voc]{`amruNU} \arb[trans]{`amruNU}, |`amraNU|
+% \arb[voc]{`amraNU} \arb[trans]{`amraNU}, |`amriNU|
+% \arb[voc]{`amriNU} \arb[trans]{`amriNU}.
+%
+% When the \arb[trans]{tanwIn} falls away \parencite[i. 249
+% B]{Wright}: |`amr-uU| |bn-u| |mu.hammadiN| \arb[fullvoc]{`amr-uU
+% bnu mu.hammadiN} \arb[trans]{\uc{`amr-uU} bn-u
+% \uc{mu.hammadiN}}, |mu.hammad-u| |bn-u| |`amr-iU| |bn-i|
+% |_hAlidiN| \arb[fullvoc]{mu.hammad-u bn-u `amr-iU bn-i _hAlidiN}
+% \arb[trans]{\uc{mu.hammad-u} bn-u \uc{`amr-iU} bn-i
+% \uc{_hAlidiN}}.
+%
+% And so also: |al-rib_aUA| \arb[voc]{al-rib_aUA}
+% \arb[trans]{al-rib_aUA}, |ribaNU| \arb[voc]{ribaNU}
+% \arb[trans]{ribaNU}.
+% \end{quote}
+%
+% \paragraph{\texorpdfstring{\arb[trans]{tanwIn}}{tanwīn}}
+% The marks of doubled short vowels, \arb{BuN}, \arb{BaN}, \arb{BiN},
+% are written \meta{uN, aN, iN} respectively. \package{arabluatex}
+% deals with special cases, such as \arb{BaN} taking an \arb[novoc]{A}
+% after all consonants except \arb[novoc]{T}, and \arb[trans]{tanwIn}
+% preceding \arb[novoc]{Y} as in \arb[voc]{hudaN_A}, which is written
+% \meta{aN\_A} or \meta{aNY}:
+% \begin{quote}
+% |mAluN| \arb[voc]{mAluN} \arb[trans]{mAluN}, |bAbaN|
+% \arb[voc]{bAbaN} \arb[trans]{bAbaN}, |madInaTaN|
+% \arb[voc]{madInaTaN} \arb[trans]{madInaTaN}, |bintiN|
+% \arb[voc]{bintiN} \arb[trans]{bintiN} |maqhaN_A|
+% \arb[voc]{maqhaN_A} \arb[trans]{maqhaN_A}, |fataNY|
+% \arb[voc]{fataNY} \arb[trans]{fataNY}.
+%
+% \package{arabluatex} is aware of special orthographies: |^say'uN|
+% \arb[voc]{^say'uN} \arb[trans]{^say'uN}, |^say'aN|
+% \arb[voc]{^say'aN} \arb[trans]{^say'aN}, |^say'iN|
+% \arb[voc]{^say'iN} \arb[trans]{^say'iN}.
+% \end{quote}
+%
+% In some cases, it may be useful to mark the root form of defective
+% words so as to produce a more accurate transliteration of ending
+% \arb[trans]{tanwIn}. As seen above, \arb[trans]{tanwIn} preceding
+% \arb[novoc]{_A} is written \meta{aN\_A} or \meta{aNY}. Such forms as
+% \arb[voc]{qA.diNI} may likewise be written \meta{iNI}:---
+% \begin{quote}
+% |al-qA.dI| \arb[voc]{al-qA.dI} \arb[trans]{al-qA.dI}, |qA.diyaN|
+% \arb[voc]{qA.diyaN} \arb[trans]{qA.diyaN}, |qA.diNI|
+% \arb[voc]{qA.diNI} \arb[trans]{qA.diNI}.
+% \end{quote}
+%
+% \subsection{Other orthographic signs}
+% \paragraph{\texorpdfstring{\arb[trans]{tA' marbU.taT}}{tÄʾ marbÅ«á¹­ah}}
+% It is written \meta{T}:
+% \begin{quote}
+% |madInaTuN| \arb[voc]{madInaTuN} \arb[trans]{madInaTuN},
+% |madInaTaN| \arb[voc]{madInaTaN} \arb[trans]{madInaTaN},
+% |madInaTiN| \arb[voc]{madInaTiN} \arb[trans]{madInaTiN}.
+% \end{quote}
+%
+% \paragraph{\texorpdfstring{\arb[trans]{hamzaT}}{hamzah}}
+% \label{ref:hamza}It is written \meta{\texttt{'}}, its carrier being
+% determined by contextual analysis. In case one wishes to bypass this
+% mechanism, he can use the \enquote{quoting} feature that is
+% described below in \vref{sec:quoting}.
+% \begin{quote}
+% \textbf{Initial \arb[trans]{hamzaT}}: |'asaduN| \arb[voc]{'asaduN}
+% \arb[trans]{'asaduN}, |'u_htuN| \arb[voc]{'u_htuN}
+% \arb[trans]{'u_htuN}, |'iqlIduN| \arb[voc]{'iqlIduN}
+% \arb[trans]{'iqlIduN}, |'anna| \arb[voc]{'anna}
+% \arb[trans]{'anna}, |'inna| \arb[voc]{'inna} \arb[trans]{'inna}.
+%
+% \label{ref:initial-hamza}
+% \arb[trans]{hamzaT} followed by the long vowel \arb[novoc]{U} is
+% encoded |'_U|: |'_Ul_A| \arb[voc]{'_Ul_A} \arb[trans]{'_Ul_A}, |'_UlU|
+% \arb[voc]{'_UlU} \arb[trans]{'_UlU}, |'_UlA'ika|
+% \arb[voc]{'_UlA'ika} \arb[trans]{'_UlA'ika}.
+%
+% \arb[trans]{hamzaT} followed by the long vowel \arb[novoc]{I} is
+% encoded |'_I|: |'_ImAnuN| \arb[voc]{'_ImAnuN}
+% \arb[trans]{'_ImA\-nuN}\footnote{For another way of encoding the
+% initial \arb[trans]{hamzaT} followed by a long vowel, see the
+% \arb[trans]{ta_hfIf-u 'l-hamzaT-i}\vpageref{ref:taxfif-hamzah}.}.
+%
+% \textbf{Middle \arb[trans]{hamzaT}}: |xA.ti'-Ina|
+% \arb[voc]{xA.ti'-Ina} \arb[trans]{xA.ti'-Ina}, |ru'UsuN|
+% \arb[voc]{ru'UsuN}, \arb[trans]{ru'UsuN}, |xa.tI'aTuN|
+% \arb[voc]{xa.tI'aTuN} \arb[trans]{xa.tI'aTuN}, |su'ila|
+% \arb[voc]{su'ila} \arb[trans]{su'ila}, |'as'ilaTuN|
+% \arb[voc]{'as'i\-laTuN} \arb[trans]{'as'ilaTuN}, |mas'alaTuN|
+% \arb[voc]{mas'alaTuN} \arb[trans]{mas'alaTuN}, |'as'alu|
+% \arb[voc]{'as'alu} \arb[trans]{'as'alu}, |yatasA'alUna|
+% \arb[voc]{yatasA'alUna}\linebreak \arb[trans]{yatasA'alUna},
+% |murU'aTuN| \arb[voc]{murU'aTuN}, |taw'amuN|
+% \arb[fullvoc]{taw'amuN} \arb[trans]{taw'amuN},
+% \arb[trans]{murU'aTuN}, |ta'xIruN| \arb[fullvoc]{ta'xIruN}
+% \arb[trans]{ta'xIruN}, |ta'ax|\allowbreak|xara|
+% \arb[voc]{ta'axxara} \arb[trans]{ta'axxara}, |ji'tu-ka|
+% \arb[voc]{ji'tu-ka} \arb[trans]{ji'tu-ka}, |qA'iluN|
+% \arb[voc]{qA'iluN} \arb[trans]{qA'iluN}, |.hIna'i_diN|
+% \arb[trans]{.hIna'i_diN} \arb[voc]{.hIna'i_diN}, |hay'aTuN|
+% \arb[voc]{hay'aTuN} \arb[trans]{hay\-'aTuN}, |hay'AtuN|
+% \arb[voc]{hay'AtuN} \arb[trans]{hay'AtuN}.
+%
+% From \textcite[i. 14 B]{Wright}:--- All consonants, whatsoever,
+% not even \arb[trans]{'alif} \emph{hèmzatum} excepted, admit of
+% being doubled and take \arb[trans]{ta^sdId}. Hence we speak and
+% write |ra''AsuN| \arb[voc]{ra''AsuN} \arb[trans]{ra''AsuN},
+% |sa''AluN| \arb[voc]{sa''AluN} \arb[trans]{sa''AluN}, |na''AjuN|
+% \arb[voc]{na''AjuN} \arb[trans]{na''AjuN}.
+%
+% \textbf{Final \arb[trans]{hamzaT}}: |xa.ta'uN| \arb[voc]{xa.ta'uN}
+% \arb[trans]{xa.ta'uN}, |xa.ta'aN| \arb[voc]{xa.ta'aN}
+% \arb[trans]{xa.ta'aN}, |xa.ta'iN| \arb[voc]{xa.ta'iN}
+% \arb[trans]{xa.ta'iN}, |'aqra'u| \arb[voc]{'aqra'u}
+% \arb[trans]{'aqra'u}, |taqra'Ina| \arb[voc]{taqra'Ina}
+% \arb[trans]{taqra'Ina}, |taqra'Una| \arb[voc]{taqra'Una}
+% \arb[trans]{taqra'Una}, |yaqra'na| \arb[fullvoc]{yaqra'na}
+% \arb[trans]{yaqra'na}, |yaxba'Ani| \arb[voc]{yaxba'Ani}
+% \arb[trans]{yaxba'Ani}, |xaba'A| \arb[voc]{xaba'A}
+% \arb[trans]{xaba'A}, |xubi'a| \arb[voc]{xubi'a}
+% \arb[trans]{xubi'a}, |xubi'UA| \arb[voc]{xubi'UA}
+% \arb[trans]{xubi'UA}, |jA'a| \arb[voc]{jA'a} \arb[trans]{jA'a},
+% |ridA'uN| \arb[voc]{ridA'uN} \arb[trans]{ridA'uN}, |ridA'aN|
+% \arb[voc]{ridA'aN} \arb[trans]{ridA'aN}, |jI'a| \arb[voc]{jI'a}
+% \arb[trans]{jI'a}, |radI'iN| \arb[voc]{radI'iN}
+% \arb[trans]{radI'iN}, |sU'uN| \arb[voc]{sU'uN} \arb[trans]{sU'uN},
+% |.daw'uN| \arb[voc]{.daw'uN} \arb[trans]{.daw'uN}, |qay'iN|
+% \arb[voc]{qay'iN} \arb[trans]{qay'iN}, |^sifA'I|
+% \arb[voc]{^sifA'I} \arb[trans]{^sifA'I}, |man^sa'I|
+% \arb[trans]{man^sa'I} \arb[voc]{man^sa'I}, |nisA'uN|
+% \arb[voc]{nisA'uN} \arb[trans]{ni\-sA'uN}, |nisA'u-hu|
+% \arb[voc]{nisA'u-hu} \arb[trans]{nisA'u-hu}, |nisA'i-hi|
+% \arb[voc]{nisA'i-hi} \arb[trans]{nisA'i-hi}, |nisA'I|
+% \arb[voc]{nisA'I} \arb[trans]{nisA'I}.
+%
+% |^say'uN| \arb[voc]{^say'uN} \arb[trans]{^say'uN}, |^say'aN|
+% \arb[voc]{^say'aN} \arb[trans]{^say'aN}, |^say'iN|
+% \arb[voc]{^say'iN} \arb[trans]{^say'iN}, |al-^say'-u|
+% \arb[voc]{al-^say'-u} \arb[trans]{al-^say'-u}, |'a^syA'-u|
+% \arb[voc]{'a^syA'-u} \arb[trans]{'a^syA'-u}, |'a^syA'-a|
+% \arb[voc]{'a^syA'-a} \arb[trans]{'a^syA'-a}, |.zim'aN|
+% \arb[voc]{.zim'aN} \arb[trans]{.zim'aN}, |radI'aN|
+% \arb[voc]{radI'aN} \arb[trans]{radI'aN}.
+%
+% \label{ref:taxfif-hamzah}
+% \textbf{\arb[trans]{ta_hfIf-u 'l-hamzaT-i}}: if the
+% \arb[trans]{hamzaT} has \arb[trans]{jazmaT} and is preceded by
+% \emph{\arb[trans]{'alif} hamzatum}, it must be changed into the
+% letter of prolongation that is homogeneous with the preceding
+% vowel; hence: |'a'mana| \arb[voc]{'a'mana} \arb[trans]{'a'mana},
+% |'u'minu| \arb[voc]{'u'minu} \arb[trans]{'u'minu}, |'i'mAnuN|
+% \arb[voc]{'i'mAnuN} \arb[trans]{'i'mAnuN}. For other possible ways
+% of encoding such sequences, see \vpageref{ref:initial-hamza}
+% (\arb[trans]{hamzaT} followed by \arb[novoc]{U} and \arb[novoc]{I})
+% and the \arb[trans]{maddaT} \vpageref{ref:madda}.
+%
+% Imperatives of verbs that have the \arb[trans]{hamzaT} as the
+% first radical are other cases of \arb[trans]{ta_hfIf-u
+% 'l-hamzaT-i}: |i'sir| \arb[fullvoc]{i'sir} \arb[trans]{i'sir},
+% |i'_dan| \arb[fullvoc]{i'_dan} \arb[trans]{i'_dan}, |u'mul|
+% \arb[fullvoc]{u'mul} \arb[trans]{u'mul}. \package{arabluatex}
+% also provides ways of encoding those words when the initial
+% \arb[trans]{'alif} comes into \arb[trans]{wa.sl}, so as to make
+% the \arb[trans]{'alif wa.sl} fall away when preceded by
+% \arb[voc]{wa} or \arb[voc]{fa}: |wa-'sir| \arb[fullvoc]{wa-'sir}
+% \arb[trans]{wa-'sir}, |fa-'_dan| \arb[fullvoc]{fa-'_dan}
+% \arb[trans]{fa-'_dan}, |fa-'ti| \arb[fullvoc]{fa-'ti}
+% \arb[trans]{fa-'ti}, |wa-'tamirUA| \arb[fullvoc]{wa-'tamirUA}
+% \arb[trans]{wa-'tamirUA}; or be retained outside the imperative,
+% as in |fa-i'tazarat| \arb[fullvoc]{fa-i'tazarat}
+% \arb[trans]{fa-i'tazarat}, |ba`da| |i'tilAfiN| \arb[fullvoc]{ba`da
+% i'tilAfiN} \arb[trans]{ba`da i'tilAfiN}.
+%
+% \textbf{The strange spelling of \arb[trans]{mi'aTuN}}: |mi'aTuN|
+% \arb[voc]{mi'aTuN} \arb[trans]{mi'aTuN}, \linebreak |mi'atAni|
+% \arb[voc]{mi'atAni} \arb[trans]{mi'atAni}, |mi'atayni|
+% \arb[voc]{mi'atayni} \arb[trans]{mi'atayni}, |mi'Una|
+% \arb[voc]{mi'Una} \arb[trans]{mi'Una}, |mi'AtuN|
+% \arb[voc]{mi'AtuN} \arb[trans]{mi'AtuN}, |mi'aN_A|
+% \arb[voc]{mi'aN_A} \arb[trans]{mi'aN_A}. Of course, the
+% \enquote*{pipe} character can be used to prevent this rule from
+% being applied (see \vref{sec:pipe}): \verb+mi'a|TuN+
+% \arb[voc]{mi'a|TuN} \arb[trans]{mi'a|TuN}.
+% \end{quote}
+%
+% \paragraph{\texorpdfstring{\arb[trans]{maddaT}}{maddah}}
+% \label{ref:madda}At the beginning of a syllabe, \arb[trans]{'alif}
+% with \arb[trans]{hamzaT} and \arb[trans]{fat.haT} (\arb[voc]{'a})
+% followed by \arb[trans]{'alifu 'l-maddi} (\arb[trans]{'alif} of
+% prolongation) or \arb[trans]{'alif} with \arb[trans]{hamzaT} and
+% \arb[trans]{jazmaT} (\arb[voc]{a"'"}) are both represented in
+% writing \arb[trans]{'alif} with \arb[trans]{maddaT}: \arb[voc]{A"'}
+% \parencite[see][i. 25 A--B]{Wright}.
+%
+% \iffalse
+%<*example>
+% \fi
+\begin{tcblisting}{text only}
+ Hence one should keep to this distinction and encode |'a'kulu|
+ \arb[voc]{'a'kulu} \arb[trans]{'a'kulu} and |'AkiluN|
+ \arb[voc]{'AkiluN} \arb[trans]{'AkiluN} respectively.
+\end{tcblisting}
+% \iffalse
+%</example>
+% \fi
+%
+% \package{arabluatex} otherwise determines \arb[trans]{al-'alif-u
+% 'l-mamdUdaT-u} by context analysis.
+%
+% \begin{quote}
+% |'is'AduN| \arb[voc]{'is'AduN} \arb[trans]{'is'AduN}, |'AkilUna|
+% \arb[voc]{'AkilUna} \arb[trans]{'AkilUna}, |'a'mannA|
+% \arb[voc]{'a'mannA} \arb[trans]{'a'mannA}, |al-qur'An-u|
+% \arb[voc]{al-qur'An-u} \arb[trans]{al-qur'An-u}.
+%
+% |jA'a| \arb[voc]{jA'a} \arb[trans]{jA'a}, |yatasA'alUna|
+% \arb[voc]{yatasA'alUna} \arb[trans]{yatasA'alUna}, |ridA'uN|
+% \arb[voc]{ridA'uN} \arb[trans]{ridA'uN}, |xaba'A|
+% \arb[voc]{xaba'A} \arb[trans]{xaba'A}, |yaxba'Ani|
+% \arb[voc]{yaxba'Ani} \arb[trans]{yaxba'Ani}.
+% \end{quote}
+%
+% \paragraph{\texorpdfstring{\arb[trans]{^saddaT}}{Å¡addah}}
+% \arb[trans]{ta^sdId} is either \emph{necessary} or \emph{euphonic}.
+%
+% \subparagraph{The necessary \arb[trans]{ta^sdId}}
+% \label{ref:necessary-tashdid}always follows a vowel, whether short
+% or long \parencite[see][i. 15 A--B]{Wright}. It is encoded in
+% writing the consonant that carries it twice:
+% \begin{quote}
+% |`allaqa| \arb[voc]{`allaqa} \arb[trans]{`allaqa}, |mAdduN|
+% \arb[voc]{mAdduN} \arb[trans]{mAdduN}, |'ammara|
+% \arb[voc]{'ammara} \arb[trans]{ammara}, |murruN| \arb[voc]{murruN}
+% \arb[trans]{murruN}.
+% \end{quote}
+%
+% \subparagraph{The euphonic \arb[trans]{ta^sdId}}
+% \label{ref:euphonic-tashdid} always follows a vowelless consonant
+% which is passed over in pronunciation and assimilated to a following
+% consonant. It may be found \parencite[i. 15 B--16 C]{Wright}:---
+% \begin{enumerate}
+% \item With the \emph{solar} letters \arb[novoc]{t}, \arb[novoc]{_t},
+% \arb[novoc]{d}, \arb[novoc]{_d}, \arb[novoc]{r}, \arb[novoc]{z},
+% \arb[novoc]{s}, \arb[novoc]{^s}, \arb[novoc]{.s}, \arb[novoc]{.d},
+% \arb[novoc]{.t}, \arb[novoc]{.z}, \arb[novoc]{l}, \arb[novoc]{n},
+% after the article \arb[fullvoc]{al-}:---
+% \iffalse
+%<*example>
+% \fi
+\begin{tcblisting}{text only}
+ Unlike \package{arabtex} and \package{arabxetex},
+ \package{arabluatex} \emph{never requires the solar letter to be
+ written twice}, as it automatically generates the euphonic
+ \arb[trans]{ta^sdId} above the letter that carries it, whether the
+ article be written in the assimilated form or not, e.g. |al-^sams-u|
+ \arb[voc]{al-^sams-u} \arb[trans]{al-^sams-u}, or |a^s-^sams-u|
+ \arb[voc]{a^s-^sams-u} \arb[trans]{a^s-^sams-u}.
+\end{tcblisting}
+% \iffalse
+%</example>
+% \fi
+% \begin{quote}
+% |al-tamr-u| \arb[voc]{al-tamr-u} \arb[trans]{al-tamr-u},
+% |al-ra.hm_an-u| \arb[voc]{al-ra.hm_an-u}
+% \arb[trans]{al-ra.hm_an-u}, |al-.zulm-u| \arb[voc]{al-.zulm-u}
+% \arb[trans]{al-.zulm-u}, |al-lu.gaT-u| \arb[voc]{al-lu.gaT-u}
+% \arb[trans]{al-lu.gaT-u}.
+% \end{quote}
+% \item \label{ref:assimilation} With the letters \arb[novoc]{r},
+% \arb[novoc]{l}, \arb[novoc]{m}, \arb[novoc]{w}, \arb[novoc]{y}
+% after \arb[voc]{n} with \arb[trans]{jazmaT}, and also after the
+% \arb[trans]{tanwIn}:---
+% \begin{quote}\SetArbDflt*
+% Note the absence of \arb[trans]{sukUn} above the passed over
+% \arb[novoc]{n} in the following examples, each of which is
+% accompanied by a consistent transliteration: |min rabbi-hi|
+% \arb[fullvoc]{min rabbi-hi}, \arb[trans]{min rabbi-hi},
+% |min| |layliN| \arb[fullvoc]{min layliN} \arb[trans]{min layliN},
+% |'an| |yaqtula| \arb[fullvoc]{'an yaqtula} \arb[trans]{'an yaqtula}.
+%
+% With \arb[trans]{tanwIn}: |kitAbuN| |mubInuN| \arb[voc]{kitAbuN
+% mubInuN} \arb[trans]{kitAbuN mubInuN}.\SetArbDflt
+% \end{quote}
+% \iffalse
+%<*example>
+% \fi
+\begin{tcblisting}{text only}
+ \textsc{Rem.} This particular feature must be put into operation by
+ the \cs{SetArbDflt*} command explicitly. See above
+ \vref{sec:classic-modern-typesetting} for further details. Other
+ kinds of assimilations, including the various cases of
+ \arb[trans]{'id.gAm}, will be included in \package{arabluatex}
+ gradually.
+\end{tcblisting}
+% \iffalse
+%</example>
+% \fi
+% \item With the letter \arb[voc]{t} after the dentals
+% \arb[novoc]{_t}, \arb[novoc]{d}, \arb[novoc]{_d}, \arb[novoc]{.d},
+% \arb[novoc]{.t}, \arb[novoc]{.z} in certain parts of the verb:
+% this kind of assimilation, e.g. \arb[voc]{labi_tttu} for
+% \arb[voc]{labi_ttu} \arb[trans]{labi_ttu}, will be discarded here,
+% as it is largely condemned by the
+% grammarians \parencite[see][i. 16 B--C]{Wright}.
+% \end{enumerate}
+%
+% \paragraph{\texorpdfstring{The definite article and the
+% \arb[trans]{'alif-u 'l-wa.sl-i}}{The definite article and the ʾalifu
+% 'l-waá¹£li}}
+% \label{ref:definite-article}
+% At the beginning of a sentence, \arb[fullvoc]{"a} is never written,
+% as \arb[fullvoc]{'l-.hamd-u li-ll_ah-i}; instead, to indicate that
+% the \arb[trans]{'alif} is a connective \arb[trans]{'alif}
+% (\arb[trans]{'alif-u 'l-wa.sl-i}), the \arb[trans]{hamzaT} is
+% omitted and only its accompanying vowel is expressed:
+% \begin{quote}
+% |al-.hamd-u| |li-l-l_ah-i| \arb[fullvoc]{al-.hamd-u li-l-l_ah-i}
+% \arb[trans]{al-.hamd-u li-l-l_ah-i}.
+% \end{quote}
+% As said above on \cpageref{fullvoc-mode}, |fullvoc| is the mode
+% in which \package{arabluatex} expresses the \arb[trans]{sukUn} and
+% the \arb[trans]{wa.slaT}. \package{arabluatex} will take care of
+% doing that automatically provided that the vowel which is to be
+% absorbed by the final vowel of the preceding word be properly
+% encoded, like so:---
+% \begin{enumerate}
+% \item Definite article at the beginning of a sentence is encoded\\
+% \tcboxverb{al-}, or \tcboxverb{a<solar letter>-}\\ if one
+% wishes to mark the assimilation---which is in no way required, as
+% \package{arabulatex} will detect all cases of assimilation.
+% \item Definite article inside sentences is encoded\\ \tcboxverb{'l-}
+% or \tcboxverb{'<solar letter>-}.
+% \item In all remaining cases of elision, the \arb[trans]{'alifu
+% 'l-wa.sli} is expressed by the vowel that accompanies the omitted
+% \arb[trans]{hamzaT}: \meta{u, a, i}.
+% \end{enumerate}
+% \begin{quote}
+% \textbf{Article}: |bAb-u| |'l-madrasaT-i| \arb[fullvoc]{bAb-u
+% 'l-madrasaT-i} \arb[trans]{bAb-u 'l-madrasaT-i},
+% |al-maqA|\allowbreak|laT-u| |'l-'_Ul_A| \arb[fullvoc]{al-maqAlaT-u
+% 'l-'_Ul_A} \arb[trans]{al-maqAlaT-u 'l-'_Ul_A}, |al-lu.gaT-u|
+% |'l-`ara|\allowbreak|biyyaT-u| \arb[fullvoc]{al-lu.gaT-u
+% 'l-`arabiyyaT-u} \arb[trans]{al-lu.gaT-u 'l-`arabiyyaT-u}, |fI|
+% |.sinA`aT-i| |'l-.tibb-i| \arb[fullvoc]{fI .sinA`aT-i 'l-.tibb-i}
+% \arb[trans]{fI .sinA`aT-i 'l-.tibb-i}, |'il_A| |'l-intiqA.d-i|
+% \arb[fullvoc]{'il_A 'l-intiqA.d-i} \arb[trans]{'il_A
+% 'l-intiqA.d-i}, |fI| |'l-ibtidA'-i| \arb[fullvoc]{fI 'l-ibtidA'-i}
+% \arb[trans]{fI 'l-ibtidA'-i}, |'abU| |'l-wazIr-i|
+% \arb[fullvoc]{'abU 'l-wazIr-i} \arb[trans]{'abU 'l-wazIr-i},
+% |fa-lammA| |ra'aW| |'l-najm-a| \arb[fullvoc]{fa-lammA ra'aW
+% 'l-najm-a} \arb[trans]{fa-lammA ra'aW 'l-najm-a}.
+%
+% \textbf{Particles}:---
+% \begin{enumerate}
+% \item \arb[trans]{li-}: \arb[trans]{'alif-u 'l-wa.sl-i} is omitted
+% in the article \arb[fullvoc]{al} when it is preceded by the
+% preposition \arb[fullvoc]{li}: |li-l-rajul-i|
+% \arb[fullvoc]{li-l-rajul-i}
+% \arb[trans]{li-l-rajul-i}.\\
+% If the first letter of the noun be \arb[novoc]{l}, then the
+% \arb[novoc]{l} of the article also falls away, but
+% \package{arabluatex} is aware of that: |li-l-laylaT-i|
+% \arb[fullvoc]{li-l-laylaT-i} \arb[trans]{li-l-laylaT-i}.
+% \item \arb[trans]{la-}: the same applies to the affirmative
+% particle \arb[fullvoc]{la}: |la-l-.haqq-u|
+% \arb[fullvoc]{la-l-.haqq-u} \arb[trans]{la-l-.haqq-u}.
+% \item With the other particles, \arb[trans]{'alif-u 'l-wa.sl-i} is
+% expressed: |fI| |'l-madIna|\allowbreak|T-i| \arb[fullvoc]{fI
+% 'l-madInaT-i} \arb[trans]{fI 'l-madInaT-i}, |wa-'l-rajul-u|
+% \arb[fullvoc]{wa-'l-rajul-u} \arb[trans]{wa-'l-rajul-u},
+% |bi-'l-|\allowbreak|qalam-i| \arb[fullvoc]{bi-'l-qalam-i}
+% \arb[trans]{bi-'l-qalam-i}, |bi-'l-ru`b-i|
+% \arb[fullvoc]{bi-'l-ru`b-i} \arb[trans]{bi-'l-ru`b-i}.
+% \end{enumerate}
+%
+% \textbf{Perfect active, imperative, nomen actionis}: |qAla|
+% |isma`| \arb[fullvoc]{qAla isma`} \arb[trans]{qAla isma`}, |qAla|
+% |uqtul| \arb[fullvoc]{qAla uqtul} \arb[trans]{qAla uqtul}, |huwa|
+% |inhazama| \arb[fullvoc]{huwa inhazama} \arb[trans]{huwa
+% inhazama}, |wa-ustu`mila| \arb[fullvoc]{wa-ustu`mila}
+% \arb[trans]{wa-ustu`mila}, |qad-i| |in.sarafa| \arb[fullvoc]{qadi
+% in.sarafa} \arb[trans]{qadi in.sarafa}, |al-iqtidAr-u|
+% \arb[fullvoc]{al-iqtidAr-u} \arb[trans]{al-iqtidAr-u}, |'il_A|
+% |'l-inti|\allowbreak|qA.d-i| \arb[fullvoc]{'il_A 'l-intiqA.d-i}
+% \arb[trans]{'il_A 'l-intiqA.d-i}, |law| |istaqbala|
+% \arb[fullvoc]{law istaqbala} \arb[trans]{law istaqbala}.
+%
+% \textbf{Other cases}: |'awi| |ismu-hu| \arb[fullvoc]{'awi ismu-hu}
+% \arb[trans]{'awi ismu-hu}, |zayduN| |ibn-u| |`amriNU|
+% \arb[fullvoc]{\uc{z}ayduN ibn-u \uc{`amriNU}}
+% \arb[trans]{\uc{z}ayduN ibn-u
+% \uc{`amriNU}},\footnote{\label{fn:zayd-is-son}%
+% \enquote{\arb[trans]{\uc{z}ayd} is the son of
+% \arb[trans]{\uc{`a}mr}}: the second noun is not in apposition to
+% the first, but forms part of the predicate. Hence \arb[voc]{zayduN
+% ibn-u `amriNU} and not \arb[voc]{zayd-u bn-u `amriNU},
+% \enquote{Zayd, son of Ê¿Amr}.} |`umar-u| |ibn-u| |'l-_ha.t.tAb-i|
+% \arb[fullvoc]{\uc{`umar}-u ibn-u \uc{'l-_ha.t.tAb-i}}
+% \arb[trans]{\uc{`umar}-u ibn-u
+% \uc{'l-_ha.t.tAb-i}},\footnote{\enquote{\arb[trans]{\uc{`umar}}
+% is the son of \arb[trans]{\uc{al-_ha.t.tAb}}} (see
+% \vref{fn:zayd-is-son}).} |imru'-u| |'l-qays-i|
+% \arb[fullvoc]{imru'-u 'l-qays-i} \arb[trans]{\uc{i}mru'-u
+% \uc{'l-qays-i}}, |la-aymun-u| |'l-l_ah-i|
+% \arb[fullvoc]{la-aymun-u 'l-l_ah-i} \arb[trans]{la-aymun-u
+% 'l-l_ah-i}.
+% \end{quote}
+%
+% \subparagraph{\arb[trans]{'alif-u 'l-wa.sl-i} preceded by a long
+% vowel} The long vowel preceding the connective \arb[trans]{'alif} is
+% shortened in pronunciation \parencite[i. 21 B--D]{Wright}. This does
+% not appear in the Arabic script, but \package{arabluatex} takes it
+% into account in some transliteration standards:---
+% \begin{quote}
+% |fI| |'l-nAs-i| \arb[fullvoc]{fI 'l-nAs-i} \arb[trans]{fI
+% 'l-nAs-i}, |'abU| |'l-wazIr-i| \arb[fullvoc]{'abU 'l-wazIr-i}
+% \arb[trans]{'abU 'l-wazIr-i}, |fI| |'l-ibtidA'-i| \arb[fullvoc]{fI
+% 'l-ibtidA'-i} \arb[trans]{fI 'l-ibtidA'-i}, |_dU 'l-i`lAl-i|
+% \arb[fullvoc]{_dU 'l-i`lAl-i} \arb[trans]{_dU 'l-i`lAl-i},
+% |maqh_A| |'l-'amIr-i| \arb[voc]{maqh_A 'l-'amIr-i}
+% \arb[trans]{maqh_A 'l-'amIr-i}.
+% \end{quote}
+%
+% \subparagraph{\arb[trans]{'alif-u 'l-wa.sl-i} preceded by a diphthong}
+% \label{sec:diphthong-alif}
+% The diphthong is resolved into two simple vowels \parencite[i. 21
+% D--22 A]{Wright} viz. \emph{ay}~→ \emph{\u{a}\u{i}} and \emph{aw}~→
+% \emph{\u{a}\u{u}}. \package{arabluatex} detects the cases in which
+% this rule applies:---
+% \begin{quote}
+% |fI| |`aynay| |'l-malik-i| \arb[fullvoc]{fI `aynay 'l-malik-i}
+% \arb[trans]{fI `aynay 'l-malik-i}, |ix^say|
+% |'l-qaw|\allowbreak|m-a| \arb[fullvoc]{ix^say 'l-qawm-a}
+% \arb[trans]{ix^say 'l-qawm-a}, |mu.s.tafaw| |'l-l_ah-i|
+% \arb[fullvoc]{mu.s.tafaw 'l-l_ah-i} \arb[trans]{mu.s.ta\-faw
+% 'l-l_ah-i}.
+%
+% |ramaW| |'l-.hijAraT-a| \arb[fullvoc]{ramaW 'l-.hijAraT-a}
+% \arb[trans]{ramaW 'l-.hijAraT-a}, |fa-lammA| |ra'aW |\allowbreak{}
+% |'l-najm-a| \arb[fullvoc]{fa-lammA ra'aW 'l-najm-a}
+% \arb[trans]{fa-lammA ra'aW 'l-najm-a}.
+% \end{quote}
+%
+% \subparagraph{\arb[trans]{'alif-u 'l-wa.sl-i} preceded by a consonant
+% with \arb[trans]{sukUn}} The vowel which the consonant takes is
+% either its original vowel, or that which belongs to the connective
+% \arb[trans]{'alif} or the \arb[trans]{kasraT}; in most of the
+% cases \parencite[i. 22 A--C]{Wright}, it is encoded explicitly, like
+% so:---
+% \begin{quote}
+% |'antumu| |'l-kA_dib-Una| \arb[fullvoc]{'antumu 'l-kA_dib-Una}
+% \arb[trans]{'antumu 'l-kA_dib-Una}, |ra'aytumu| |'l-rajul-a|
+% \arb[fullvoc]{ra'aytumu 'l-rajul-a} \arb[trans]{ra'aytumu
+% 'l-rajul-a}, |mani| |'l-ka_d_dAb-u| \arb[fullvoc]{mani
+% 'l-ka_d_dAb-u} \arb[trans]{mani 'l-ka_d_dAb-u}, |qatalati|
+% |'l-rUm-u| \arb[fullvoc]{qatalati 'l-rUm-u} \arb[trans]{qatalati
+% \uc{'l-rUm-u}}.
+% \end{quote}
+% \label{ref:muhammaduni}
+% However, the Arabic script does not show the \arb[trans]{kasraT} or
+% the \arb[trans]{.dammaT} which may be taken by the nouns having
+% \arb[trans]{tanwIn} although it is explicit in pronunciation and
+% must appear in some transliteration standards. \package{arabluatex}
+% takes care of that automatically:---
+% \begin{quote}
+% |mu.hammaduN| |'l-nabI| \arb[fullvoc]{mu.hammaduN 'l-nabI}
+% \arb[trans]{\uc{m}u.hammaduN 'l-nabI}, |salAmuN| |ud_hulUA|
+% \arb[fullvoc]{salAmuN ud_hulUA} \arb[trans]{salAmuN ud_hulUA},
+% |qa.sIdata-hu| |fI| |qatl-i| |\uc{'a}bI|
+% |\uc{m}|\allowbreak|uslimiN| |'llatI| |yaqUlu| |fI-hA|
+% \arb[fullvoc]{qa.sIdata-hu fI qatl-i \uc{'a}bI \uc{m}uslimiN
+% 'llatI yaqUlu fI-hA} \arb[trans]{qa.sIdata-hu fI qatl-i \uc{'a}bI
+% \uc{m}uslimiN 'llatI yaqUlu fI-hA}.
+% \end{quote}
+%
+% \subsection{Special orthographies}
+% \paragraph{The name of God}
+% The name of God, \arb[voc]{al-l_ahu}, is compounded of the article
+% \arb[fullvoc]{al-}, and \arb[fullvoc]{'ilAh-u} (noted
+% \arb[fullvoc]{'il_ah-u} with the defective \arb[trans]{'alif}) so
+% that it becomes \arb[fullvoc]{al-'ilAh-u}; then the
+% \arb[trans]{hamzaT} is suppressed, its vowel being transferred to
+% the \arb[novoc]{l} before it, so that there remains
+% \arb[voc]{alil_ah-u} \parencite[I refer to][I. 83
+% col. 1]{Lane}. Finally, the first \arb[novoc]{l} is made quiescent
+% and incorporated into the other, hence the \arb[trans]{ta^sdId}
+% above it. As \package{arabluatex} never requires a solar letter to
+% be written twice (see above, \vpageref{ref:euphonic-tashdid}), the
+% name of God is therefore encoded |al-l_ah-u| or |'l-l_ah-u|:---
+% \begin{quote}
+% |al-l_ah-u| \arb[fullvoc]{al-l_ah-u} \arb[trans]{al-l_ah-u},
+% \verb+yA|+\footnote{\label{fn:pipe-allah-01}Note the
+% \enquote{pipe} character \enquote*{\textbar} here after |yA| and
+% below after |fa| before footnote mark \ref{fn:pipe-allah-02}: it
+% is needed by the |dmg| transliteration mode as in this mode any
+% vowel at the commencement of a word preceded by a word that ends
+% with a vowel, either short or long, is absorbed by this vowel
+% viz. \arb[trans]{`al_A 'l-.tarIq-i}. See \vref{sec:pipe} on the
+% \enquote{pipe} and \vref{sec:transliteration} on |dmg| mode.}
+% |al-l_ah-u| \arb[fullvoc]{yA| al-l_ah-u} \arb[trans]{yA|
+% al-l_ah-u}, \verb+'a-fa|+\footnote{\label{fn:pipe-allah-02}See
+% \cref{fn:pipe-allah-01}.}|-al-|\allowbreak|l_ah-i|
+% |la-ta.g`alanna| \arb[fullvoc]{'a-fa|-al-l_ah-i la-ta.g`alanna}
+% \arb[trans]{'a-fa|-al-l_ah-i la-ta.g`alanna},
+% |bi-'l-|\allowbreak|l_ah-i| \arb[fullvoc]{bi-'l-l_ah-i}
+% \arb[trans]{bi-'l-l_ah-i}, |wa-'l-l_ah-i|
+% \arb[fullvoc]{wa-'l-l_ah-i} \arb[trans]{wa-'l-l_ah-i}, |bi-sm-i|
+% |'l-l_ah-i| \arb[fullvoc]{bi-sm-i 'l-l_ah-i} \arb[trans]{bi-sm-i
+% 'l-l_ah-i}, |al-.hamd-u| |li-l-l_ah-i| \arb[fullvoc]{al-.hamd-u
+% li-l-l_ah-i} \arb[trans]{al-.hamd-u li-l-l_ah-i}, |li-l-l_ah-i|
+% |'l-qA'il-u| \arb[fullvoc]{li-l-l_ah-i 'l-qA'il-u}
+% \arb[trans]{li-l-l_ah-i 'l-qA'il-u}.
+% \end{quote}
+%
+% \paragraph{\texorpdfstring{The conjunctive \arb[voc]{alla_dI}}{The
+% conjunctive اَلَّذÙÙŠ}}
+% Although it is compounded of the article \arb[fullvoc]{al}, the
+% demonstrative letter \arb[novoc]{l} and the demonstrative pronoun
+% \arb[voc]{_dA}, both masculine and feminine forms that are written
+% defectively are encoded |alla_dI| and |allatI| respectively. Forms
+% starting with the connective \arb[trans]{'alif} are encoded
+% |'lla_dI| and |'llatI|:---
+% \begin{quote}
+% |'a_hAfu| |mina| |'l-malik-i| |'lla_dI| |ya.zlimu| |'l-nAs-a|
+% \arb[fullvoc]{'a_hAfu mina 'l-malik-i 'lla_dI ya.zlimu 'l-nAs-a}
+% \arb[trans]{'a_hAfu mina 'l-malik-i 'lla_dI ya.zlimu 'l-nAs-a},
+% |`udtu| |'l-^say_h-a| |'lla_dI| |huwa| |marI.duN|
+% \arb[fullvoc]{`udtu 'l-^say_h-a 'lla_dI huwa marI.duN}
+% \arb[trans]{`udtu 'l-^say_h-a 'lla_dI huwa marI.duN}, |mA| |'anA|
+% |bi-'lla_dI| |qA'iluN| |la-ka| |^say'aN| \arb[fullvoc]{mA 'anA
+% bi-'lla_dI qA'iluN la-ka ^say'aN} \arb[trans]{mA 'anA bi-'lla_dI
+% qA'iluN la-ka ^say'aN}.
+%
+% |'ari-nA| |'lla_dayni| |'a.dallA-nA| |mina| |'l-jinn-i|
+% |wa-'l-'ins-i| \arb[fullvoc]{'ari-nA 'lla_dayni 'a.dallA-nA mina
+% 'l-jinn-i wa-'l-'ins-i} \arb[trans]{'ari-nA 'lla_dayni 'a.dallA-nA
+% mina 'l-jinn-i wa-'l-'ins-i}.
+% \end{quote}
+% The other forms are encoded regularly as |al-l| or |'l-l|:---
+% \begin{quote}
+% |fa-'innA| |na_dkuru| |'l-.sawt-ayni| |'l-la_dayni| |rawaynA-humA|
+% |`an| |ja.h.zaT-a| \arb[fullvoc]{fa-'innA na_dkuru 'l-.sawt-ayni
+% 'l-la_dayni rawaynA-humA `an \uc{ja.h.zaT-a}}
+% \arb[trans]{fa-'innA na_dkuru 'l-.sawt-ayni 'l-la_dayni
+% rawaynA-humA `an \uc{ja.h.zaT-a}}.
+%
+% And also: |al-la_dAni| \arb[fullvoc]{al-la_dAni}
+% \arb[trans]{al-la_dAni}, |al-la_dayni| \arb[fullvoc]{al-la_dayni}
+% \arb[trans]{al-la_dayni}, |al-latAni| \arb[fullvoc]{al-latAni}
+% \arb[trans]{al-latAni}, |al-latayni| \arb[fullvoc]{al-latayni}
+% \arb[trans]{al-latayni}, |al-lAtI| \arb[fullvoc]{al-lAtI}
+% \arb[trans]{al-lAtI},
+% \verb+al-lA'|Ati+\footnote{\label{fn:pipe-madda}Note here the
+% \enquote{pipe} character \enquote*{\textbar}: as already stated
+% \vpageref{ref:madda}, the sequence |'A| usually encodes
+% \arb[trans]{'alif} with \arb[trans]{hamzaT} followed by
+% \arb[trans]{'alif} of prolongation, which is represented in writing
+% \arb[trans]{'alif} with \arb[trans]{maddaT}: \arb[voc]{A"'}. The
+% \enquote{pipe} character prevents this rule from being
+% applied. See \vref{sec:pipe}.} \arb[fullvoc]{al-lA'|Ati}
+% \arb[trans]{al-lA'|Ati}, |al-lA'I| \arb[fullvoc]{al-lA'I}
+% \arb[trans]{al-lA'I}, and so forth.
+% \end{quote}
+%
+% \subsection{Quoting}
+% \label{sec:quoting}
+% It is here referred to \enquote{quoting} after the \package{arabtex}
+% package.\footnote{See \textcite[22]{pkg:arabtex}} The
+% \enquote{quoting} mechanism of \package{arabluatex} is designed to
+% be very similar in effect to the one of \package{arabtex}.
+%
+% To start with an example, suppose one types the following in |novoc|
+% mode: \arb[novoc]{`ullima `ilm-a 'l-hay'aT-i}; is it
+% \arb[fullvoc]{`ullima}, \emph{he was taught the science of
+% astronomy}, or \arb[fullvoc]{`allama}, \emph{he taught the science
+% of astronomy}? In order to disambiguate this clause, it may be
+% sensible to put a \arb[trans]{.dammaT} above the first \arb[voc]{`}:
+% \arb[novoc]{`"ullima `ilm-a 'l-hay'aT-i}, which is achieved by
+% \enquote{quoting} the vowel |u|, like so: |`"ullima|, or, with no
+% other vowel than the required |u|: |`"ullm|.
+%
+% This is how the \enquote{quoting} mechanism works: metaphorically
+% speaking, it acts as a \emph{toggle switch}. If something, in a
+% given mode, is supposed to be visible, \enquote{quoting} hides it;
+% conversely, if it is supposed not to, it makes it visible.
+%
+% As shown above, \enquote{quoting} means inserting one straight
+% double quote (|"|) \emph{before} the letter that is to be acted
+% upon. Its effects depend on the mode which is currently selected,
+% either |novoc|, |voc| or |fullvoc|:---
+%
+% \paragraph{\texttt{novoc}} In this mode, \enquote{quoting}
+% essentially means make visible something that ought not to be so.
+% \begin{enumerate}
+% \item Quoting a vowel, either short or long, makes the
+% \arb[trans]{.dammaT}, \arb[trans]{fat.haT} or \arb[trans]{kasraT}
+% appear above the appropriate consonant:---
+% \begin{quote}
+% |`"ullima| |`ilm-a| |'l-hay'aT-i| \arb[novoc]{`"ullima `ilm-a
+% 'l-hay'aT-i} \arb[trans]{`"ullima `ilm-a 'l-hay'aT-i}, |ya.gz"UA|
+% \arb[novoc]{ya.gz"UA} \arb[trans]{ya.gz"UA}.
+% \end{quote}
+% \item The same applies when \enquote{quoting} the
+% \arb[trans]{tanwIn}:---
+% \begin{quote}
+% |wa-'innA| |sawfa| |tudriku-nA| |'l-manAyA| |muqadd"araT"aN|
+% \arb[novoc]{wa-'innA sawfa tudriku-nA 'l-manAyA muqadd"araT"aN},
+% \arb[trans]{wa-'innA sawfa tudriku-nA 'l-manAyA muqadd"araT"aN}.
+% \end{quote}
+% \item \label{ref:quoted-sukun-b}If no vowel follows the straight
+% double quote, then a \arb[trans]{sukUn} is put above the preceding
+% consonant:---
+% \begin{quote}
+% |qAla isma`"| \arb[novoc]{qAla isma`"} \arb[trans]{qAla isma`"},
+% |jA'at"| |hinduN| \arb[voc]{jA'at" \uc{hinduN}}
+% \arb[trans]{jA'at" \uc{hinduN}}, |^sabIhuN| |bi-man| |q"u.ti`at"|
+% |qadamA-hu| \arb[novoc]{^sabIhuN bi-man q"u.ti`at" qadamA-hu}
+% \arb[trans]{^sabIhuN bi-man q"u.ti`at" qadamA-hu}.
+% \end{quote}
+% \item At the commencement of a word, the straight double quote is
+% interpreted as \arb[trans]{'alif-u 'l-wa.sl-i}:---
+% \begin{quote}
+% |wa-"ust"u`mila| \arb[novoc]{wa-"ust"u`mila}
+% \arb[trans]{wa-"ust"u`mila}, |huwa| |"inhazama| \arb[novoc]{huwa
+% "inhazama} \arb[trans]{huwa "inhazama}, |al-"intiqA.d-u|
+% \arb[novoc]{al-"intiqA.d-u} \arb[trans]{al-"intiqA.d-u}.
+% \end{quote}
+% \end{enumerate}
+%
+% \paragraph{\texttt{voc}}
+% In accordance with the general rule, in this mode, \enquote{quoting}
+% makes the vowels and the \arb[trans]{tanwIn} disappear, should this
+% feature be required for some reason:---
+% \begin{enumerate}
+% \item Short and long vowels:---
+% \begin{quote}
+% |q"Ala q"A'iluN| \arb[voc]{q"Ala q"A'iluN} \arb[trans]{q"Ala
+% q"A'iluN}, |ibn-u 'abI 'u.saybi`aT-"a| \arb[voc]{ibn-u 'abI
+% 'u.saybi`aT-"a} \arb[trans]{\uc{ibn-u} \uc{'abI}
+% \uc{'u.saybi`aT-"a}}.
+% \end{quote}
+% \item \arb[trans]{tanwIn}:---
+% \begin{quote}
+% |madInaT"aN| \arb[voc]{madInaT"aN} \arb[trans]{madInaT"aN},
+% |bAb"aN| \arb[voc]{bAb"aN} \arb[trans]{bAb"aN}, |hud"aN_A|
+% \arb[voc]{hud"aN_A} \arb[trans]{hud"aN_A}, |^say'"iN|
+% \arb[voc]{^say'"iN} \arb[trans]{^say'"iN}.
+% \end{quote}
+% \end{enumerate}
+% One may more usefully \enquote{quote} the initial vowels to write
+% the \arb[trans]{wa.slaT} above the \arb[trans]{'alif} or insert a
+% straight double quote after a consonant not followed by a vowel to
+% make the \arb[trans]{sukUn} appear:---
+% \begin{enumerate}
+% \item \arb[trans]{'alif-u 'l-wa.sl-i}:---
+% \begin{quote}
+% |fI "istiq.sA'-iN| \arb[voc]{fI "istiq.sA'-iN} \arb[trans]{fI
+% "istiq.sA'-iN}, |wa-"istiq.sA'-uN| \arb[voc]{wa-"istiq.sA'-uN}
+% \allowbreak\arb[trans]{wa-"istiq.sA'-uN}, |qAla| |"uhrub|
+% |fa-lan| |tuqtala| \arb[voc]{qAla "uhrub fa-lan tuqtala}
+% \arb[trans]{qAla "uhrub fa-lan tuqtala}.
+% \end{quote}
+% \item \arb[trans]{sukUn}:---
+% \begin{quote}
+% |qAla| |"uqtul"| |fa-lan| |tuqtala| \arb[voc]{qAla "uqtul"
+% fa-lan tuqtala} \arb[trans]{qAla "uqtul" fa-lan tuqtala}, |mA|
+% |jA'at"| |mini| |imra'aTiN| \arb[voc]{mA jA'at" mini imra'aTiN}
+% \arb[trans]{mA jA'at" mini imra'aTiN}, |kam"| |qad"| |ma.dat"|
+% |min"| |laylaTiN| \arb[voc]{kam" qad" ma.dat" min" laylaTiN}
+% \arb[trans]{kam" qad" ma.dat" min"
+% laylaTiN}.\label{ref:quoted-sukun-e}
+% \end{quote}
+% \end{enumerate}
+%
+% \paragraph{\texttt{fullvoc}}
+% In this mode, \enquote{quoting} can be used to take away any short
+% vowel (or \arb[trans]{tanwIn}, as seen above) or any
+% \arb[trans]{sukUn}:---
+% \begin{quote}\label{ref:qrannun-full}
+% |al-jamr-u| |'l-.sayfiyy-u| |'lla_dI| |kAna|
+% \verb+bi-q"rAn"|nUn-a+ \arb[fullvoc]{al-jamr-u 'l-.sayfiyy-u
+% 'lla_dI kAna \uc{bi-q"rAn"|nUn-a}} \arb[trans]{al-jamr-u
+% 'l-.sayfiyy-u 'lla_dI kAna \uc{bi-q"rAn"|nUn-a}}.
+% \end{quote}
+%
+% \subsubsection{\texorpdfstring{Quoting the
+% \arb[trans]{hamzaT}}{Quoting the hamzah}}
+% \label{sec:quoting-hamza}
+% As said above in \vref{ref:hamza}, the \arb[trans]{hamzaT} is always
+% written \meta{\texttt{'}}, its carrier being determined by contextual
+% analysis. \enquote{Quoting} that straight single quote character
+% like so: \meta{\texttt{"'}} allows to determine the carrier of the
+% \arb[trans]{hamzaT} freely, without any consideration for the
+% context. \Cref{tab:quoted-hamza} gives the equivalents for all the
+% possible carriers the \arb[trans]{hamzaT} may take.
+%
+% \begin{longtable}{lllll}
+% \bottomrule
+% \caption*{\Cref*{tab:quoted-hamza}: \enquote{Quoted}
+% \arb[trans]{hamzaT}}
+% \endfoot
+% \captionlistentry{\enquote{Quoted} \arb[trans]{hamzaT}}\\[-1em]
+% \toprule Letter & \multicolumn{3}{l}{Transliteration\footnotemark}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & \\ \midrule
+% \endfirsthead
+% \toprule Letter & \multicolumn{3}{l}{Transliteration}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & \\ \midrule
+% \endhead
+% \footnotetext{See below \vref{sec:transliteration}.}
+% \label{tab:quoted-hamza}
+% \arb[novoc]{|"'} & \dmg{|"'} & \loc{|"'} & \brill{|"'} & \verb+|"'+ \\
+% \pagebreak[1]
+% \arb[novoc]{A"'} & \dmg{A"'} & \loc{A"'} & \brill{A"'} & \verb|A"'| \\
+% \arb[novoc]{a"'} & \dmg{a"'} & \loc{a"'} & \brill{a"'} & \verb|a"'| \\
+% \arb[novoc]{u"'} & \dmg{u"'} & \loc{u"'} & \brill{u"'} & \verb|u"'| \\
+% \arb[novoc]{w"'} & \dmg{w"'} & \loc{w"'} & \brill{w"'} & \verb|w"'| \\
+% \arb[novoc]{i"'} & \dmg{i"'} & \loc{i"'} & \brill{i"'} & \verb|i"'| \\
+% \arb[novoc]{y"'} & \dmg{y"'} & \loc{y"'} & \brill{y"'} & \verb|y"'| \\
+% \end{longtable}
+%
+% As one can see from \vref{tab:quoted-hamza}, the carrier of the
+% \arb[trans]{hamzaT} is inferred from the letter that precedes the
+% straight double quote \meta{\texttt{"}}. Of course, any
+% \enquote{quoted} \arb[trans]{hamzaT} may take a short vowel, which
+% is to be written \emph{after} the Arab\TeX\ equivalent for the
+% \arb[trans]{hamzaT} itself, namely \meta{\texttt{'}}. For example,
+% \arb[voc]{w"'a} is encoded \meta{\texttt{w"'a}}, while
+% \arb[voc]{w"'"} is encoded \meta{\texttt{w"'"}}. In the latter
+% example, the second straight double quote encodes the
+% \arb[trans]{sukUn} in |voc| mode in accordance with the rule laid
+% above \vpagerefrange{ref:quoted-sukun-b}{ref:quoted-sukun-e}.
+% \begin{quote}
+% |'a`dA'ukum| \arb[fullvoc]{'a`dA'ukum} \arb[trans]{'a`dA'ukum},
+% \verb+'a`dA|"'ukum+ \arb[fullvoc]{'a`daA"'|"'ukum}
+% \arb[trans]{'a`dA|"'ukum}, |'a`dA'ikum| \arb[fullvoc]{'a`dA'ikum}
+% \arb[trans]{'a`dA'ikum}, \verb+'a`dA|"'ikum+
+% \arb[fullvoc]{'a`daA"'|"'ikum} \arb[trans]{'a`dA|"'ikum}.
+% \end{quote}
+%
+% \subsection{The \enquote{pipe} character (\textbar)}
+% \label{sec:pipe}
+% In the terminology of Arab\TeX, the \enquote{pipe} character
+% \enquote*{\textbar} is referred to as the \enquote{invisible
+% consonant}. Hence, as already seen above in
+% \vref{sec:quoting-hamza}, its usage to encode the
+% \arb[trans]{hamzaT} alone, with no carrier: \verb+|"'+
+% \arb[novoc]{|"'}.
+%
+% Aside from that usage, the \enquote{pipe} character is used to
+% prevent almost any of the contextual analysis rules that are
+% described above from being applied. Two examples have already been
+% given to demonstrate how that particular mechanism works in
+% \vref{fn:pipe-allah-01} and in \vref{fn:pipe-madda}. One more example
+% follows:---
+% \begin{quote}
+% \verb+bi-qrAn|nUn-a+ \arb[voc]{\uc{bi-qrAn|nUn-a}}
+% \arb[trans]{\uc{bi-qrAn|nUn-a}}, \enquote{in Crannon} (Thessaly,
+% Greece).\footnote{See more context \vpageref{ref:qrannun-full}.}
+% \end{quote}
+% As one can see, the \enquote{pipe} character between the two
+% \meta{n} prevents the necessary \arb[trans]{ta^sdId} rule
+% (\cpageref{ref:necessary-tashdid}) from being applied.
+%
+% \subsection{Putting back on broken contextual analysis rules}
+% \label{sec:arbnull}
+% \NEWfeature{v1.7} In complex documents such as critical editions
+% where footnotes and other kind of annotations can be particularly
+% abundant, the contextual analysis rules that are described above may
+% be broken by \LaTeX\ commands. To take an example, consider the
+% following:---%
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ This is wrong:
+ \begin{arab}[fullvoc]
+ fa-lammA ra'aW\LRfootnote{A footnote which interferes with
+ the contextual analysis.} 'l-na^gma...
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi%
+% According to the rule stated \vpageref{sec:diphthong-alif}, the
+% diphthong in \arb[trans]{ra'aW} must be resolved into two simple
+% vowels before the \arb[trans]{'alif-u 'l-wa.sl-i}, as
+% \arb[fullvoc]{ra'aW 'l-na^gma}.
+%
+% \DescribeMacro{\arbnull} The \cs{arbnull} command is provided so as
+% to put back on contextual analysis rules in such situations. It
+% takes as argument the word that must be brought back for any given
+% rule to be applied as it ought to. Depending on the contexts that
+% have to be restored, \cs{arbnull} may be found just after or before
+% Arabic words.%
+% \iffalse
+%<*example>
+% \fi
+\begin{tcblisting}{text only}
+ In any case, \emph{no space must be left} after or before the Arabic
+ word that \cs{arbnull} is applied to.
+\end{tcblisting}
+% \iffalse
+%</example>
+% \fi%
+% The following shows how the Arabic should have been written in the
+% preceding example and gives further illustrations of the same
+% technique:---%
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \begin{arab}[fullvoc]
+ fa-lammA ra'aW\arbnull{'l-na^gma}\LRfootnote{A footnote
+ which interferes with the contextual analysis.}
+ 'l-na^gma...
+
+ qAla\LRfootnote{A footnote which interferes with the
+ contextual analysis.} \arbnull{qAla}uhrub fa-lan tuqtala.
+
+ \uc{z}ayduN\arbnull{ibnu}\LRfootnote{A footnote which
+ interferes with the contextual analysis.}
+ \arbnull{zayduN}ibn-u \uc{`a}mriNU.\LRfootnote{See
+ \vref{fn:zayd-is-son}.}
+ \end{arab}
+
+ \begin{arab}[trans]
+ \uc{z}ayduN\arbnull{ibnu}\LRfootnote{A footnote which
+ interferes with the contextual analysis.}
+ \arbnull{zayduN}ibn-u \uc{`a}mriNU.\LRfootnote{See
+ \vref{fn:zayd-is-son}.}
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi%
+%
+% \subsection{\texorpdfstring{Stretching characters: the
+% \arb[trans]{ta.twIl}}{Stretching characters: the taṭwīl}}
+% \label{sec:tatwil}
+% A double hyphen \meta{-\,-} stretches the ligature in which one
+% letter is bound to another. Although it is always better to rely on
+% automatic stretching, this technique can be used to a modest extent,
+% especially to increase legibility of letters and diacritics which
+% stand one above the other:--
+% \begin{quote}
+% |.hunayn-u| |bn-u| |'is.h--_aq-a| \arb[voc]{.hunayn-u bn-u
+% 'is.h--_aq-a} \arb[trans]{\uc{.hunayn-u} bn-u \uc{'is.h--_aq-a}}
+% \end{quote}
+%
+% \subsection{Digits}
+% \label{sec:digits}
+% \subsubsection{Numerical figures}
+% \label{sec:numerical-figures}
+% The \emph{Indian numbers}, \arb[trans]{al-raqam-u 'l-hindiyy-u}, are
+% ten in number, and they are compounded in exactly the same way as
+% our numerals:---
+% \begin{quote}
+% |1874| \arb[voc]{1874}, |123-456,789| \arb[voc]{123-456,789}, |fI|
+% |sanaT-i| |1024| \arb[voc]{fI sanaT-i 1024}
+% \end{quote}
+%
+% \subsubsection{The \emph{abjad}}
+% \label{sec:abjad}
+% The numbers may also be expressed with letters from right to left
+% arranged in accordance with the order of the Hebrew and Aramaic
+% alphabets \parencite[see][i. 28 B--C]{Wright}. The
+% \arb[trans]{'abjad} numbers are usually distinguished from the
+% surrounding words by a stroke placed over them.
+%
+% \DescribeMacro{\abjad} \NEWfeature{v.1.1} \arb[trans]{'abjad}
+% numbers are inserted with the \cs{abjad}\marg{number} command in any
+% of the |voc|, |fullvoc| and |novoc| modes, where \meta{number} may
+% be any number between 1 and 1999, like so:---
+% \begin{quote}
+% |\abjad{45}| |kitAbu-hu| |fI| |'l-`AdAt-i| \arb[voc]{\abjad{45}
+% kitAbu-hu fI 'l-`AdAt-i} \arb[trans]{\abjad{45} kitAbu-hu fI
+% 'l-`AdAt-i}.
+% \end{quote}
+% \begin{quoting}
+% \textsc{Rem.}~\emph{a.} As can be seen in the above given example,
+% \package{arabluatex} expresses the \arb[trans]{'abjad} numbers in
+% Roman numerals if it finds the \cs{abjad} command in any of the
+% transliteration modes.
+%
+% \textsc{Rem.}~\emph{b.} \cs{abjad} may also be found outside
+% Arabic environments. In that case, \package{arabluatex} does not
+% print the stroke as a distinctive mark over the number for it is
+% not surrounded by other Arabic words. In case one nonetheless
+% wishes to print the stroke, he can either use the \cs{aemph}
+% command that is described below in \vref{sec:emphasis} or insert
+% the \arb[trans]{'ab^gad} number in |\arb[novoc]{}|:---
+% \begin{quote}
+% |The| |\arb[trans]{'abjad}| |number| |for| |1874| |is|
+% |\abjad{1874}| The \arb[trans]{'abjad} number for 1874 is
+% \abjad{1874}.
+%
+% |The| |\arb[trans]{'abjad}| |number| |for| |1874| |is|
+% |\aemph*{\abjad{1874}}| The \arb[trans]{'abjad} number for 1874
+% is \aemph*{\abjad{1874}}.
+%
+% |The| |\arb[trans]{'abjad}| |number| |for| |1874| |is|
+% |\arb[novoc]{\abjad{1874}}| The \arb[trans]{'abjad} number for
+% 1874 is \arb[novoc]{\abjad{1874}}.
+% \end{quote}
+% \end{quoting}
+%
+% \NEWfeature{v1.12}\cs{abjad} may also be used to convert values of
+% counters into \arb[trans]{'ab^gad} numbers, like so:--- %
+% \changes{v1.12}{2018/06/24}{\cs{abjad} can now process \LaTeX\
+% counters}%
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ The \arb[trans]{'ab^gad} number for the current page (\thepage) is
+ \abjad{\thepage}.
+\end{example}
+% \iffalse
+%</example>
+% \fi%
+%
+% This technique can be used to produce abjad-numbered lists as will
+% be demonstrated \vpageref{ref:abjad-list}.
+%
+% \subsection{Additional characters}
+% \label{sec:additional-characters}
+% In the manuscripts, the unpointed letters, \arb[trans]{al-.hurUf-u
+% 'l-muhmalaT-u}, are sometimes further distinguished from the pointed
+% by various contrivances, as explained in \textcite[i. 4
+% B--C]{Wright}. One may find these letters written in a smaller size
+% below the line, or with a dot or another mark below. As representing
+% all the possible contrivances leads to much complexity and also
+% needs to be agreed among scholars, new ways of encoding them will be
+% proposed and gradually included as \package{arabluatex} will mature.
+%
+% For the time being, the following is included:---
+% \begin{longtable}{lllll}
+% \bottomrule
+% \caption*{\Cref*{tab:additional-arabic-codings}: Additional Arabic
+% codings}
+% \endfoot
+% \captionlistentry{Additional Arabic codings}\\[-1em]
+% \toprule
+% Letter & \multicolumn{3}{l}{Transliteration\footnotemark}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & \\ \midrule
+% \endfirsthead
+% \toprule
+% Letter & \multicolumn{3}{l}{Transliteration}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} \\ \midrule
+% \endhead \footnotetext{See below \vref{sec:transliteration}.}
+% \label{tab:additional-arabic-codings}
+% \arb[novoc]{.b} & \dmg{.b} & \loc{.b} & \brill{.b} & |.b| \\
+% \arb[novoc]{^d} & \dmg{^d} & \loc{^d} & \brill{^d} & |^d| \\
+% \arb[novoc]{.f} & \dmg{.f} & \loc{.f} & \brill{.f} & |.f| \\
+% \arb[novoc]{.q} & \dmg{.q} & \loc{.q} & \brill{.q} & |.q| \\
+% \arb[novoc]{.k} & \dmg{.k} & \loc{.k} & \brill{.k} & |.k| \\
+% \pagebreak[1]
+% \arb[novoc]{.n} & \dmg{.n} & \loc{.n} & \brill{.n} & |.n| \\
+% \arb[novoc]{((} & \dmg{((} & \loc{((} & \brill{((} & |((| \\
+% \arb[novoc]{))} & \dmg{))} & \loc{))} & \brill{))} & |))| \\
+% \end{longtable}
+%
+% \begin{quote}
+% |'afAman.tUs| Gal.(M) |.fmn.n.ts| (sic) Gal.(E1),
+% \arb[novoc]{'afAman.tUs} Gal.(M) \arb[novoc]{.fmn.n.ts} (sic)
+% Gal.(E1), \arb[trans]{'afAman.tUs} Gal.(M) \arb[trans]{.fmn.n.ts}
+% (sic) Gal.(E1).
+% \end{quote}
+%
+% \subsection{Arabic emphasis}
+% \label{sec:emphasis}
+% As already seen in \vref{sec:abjad}, the \arb[trans]{'abjad} numbers
+% are distinguished from the surrounding words by a stroke placed
+% over them. This technique is used to distinguish further words that
+% are proper names or book titles.
+%
+% \DescribeMacro{\aemph} One may use the \cs{aemph}\marg{Arabic
+% text} command to use the same technique to emphasize words, like so:---
+% \begin{quote}
+% |\abjad{45}:| |kitAbu-hu| |\aemph{fI| |'l-`AdAt-i}|
+% \arb[voc]{\abjad{45}: kitAbu-hu \aemph{fI 'l-`AdAt-i}}
+% \arb[trans]{\abjad{45}: kitAbu-hu \aemph{fI 'l-\uc{`AdAt-i}}}.
+% \end{quote}
+%
+% \begin{quoting}
+% \textsc{Rem.}~\emph{a.} As the above example shows,
+% \package{arabluatex} places the horizontal stroke \emph{under} the
+% emphasized words in any of the transliteration modes.
+%
+% \textsc{Rem.}~\emph{b.} \NEWfeature{v1.9.2}\DescribeMacro{\aemph*}
+% \cs{aemph*} is also provided should one wish to always have the
+% horizontal stroke printed over the emphasized words, like so:
+% |\abjad{45}:| |kitAbu-hu| |\aemph*{fI| |'l-`AdAt-i}|
+% \arb[voc]{\abjad{45}: kitAbu-hu \aemph*{fI 'l-`AdAt-i}}
+% \arb[trans]{\abjad{45}: kitAbu-hu \aemph*{fI 'l-\uc{`AdAt-i}}}.
+% \end{quoting}
+%
+% \section{Arabic poetry}
+% \label{sec:poetry}
+% \NEWfeature{v1.6} \package{arabluatex} provides a special
+% environment for typesetting Arabic poetry. Every line in this
+% environment must end with |\\|.
+%
+% \DescribeEnv{arabverse} The |arabverse| environment may take up to
+% six optional \enquote*{named arguments} each of which is set using
+% the syntax \meta{key}$=$\meta{value}, like so:---%
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \begin{arabverse}[key1=value1, key2=value2, ...]
+ <verses>
+ \end{arabverse}
+\end{code}
+% \iffalse
+%</example>
+% \fi
+%
+% The description of the optional arguments follows:---
+%
+% \DescribeOption{mode} |mode|$=$\meta{mode}, either |voc|, |fullvoc|,
+% |novoc| or |trans|. The default mode is the one that is set at load
+% time as already seen \vref{sec:options}.
+%
+% \DescribeOption{width} |width|$=$\meta{length}
+% \hfill\tcboxverb{Default: 0.3\linewidth}\\ The default width of
+% each hemistich that the verse consists of. It may be expressed in
+% any accepted unit of measurement, such as |4cm| or |2in|. However,
+% one must keep in mind that the total length of the two hemistichs
+% added to the one of the gutter that separates them must not exceed
+% the length of the base line, unless one wishes to have the
+% hemistichs distributed on subsequent lines.
+%
+% \DescribeOption{gutter} |gutter|$=$\meta{width}
+% \hfill\tcboxverb{Default: 0.15 x (hemistich width)}\\ The gutter
+% consists of the blank space that is between the two hemistichs. By
+% default, it is commensurate with the width of the hemistich, but it
+% may be expressed in any accepted unit of measurement as well.
+%
+% \DescribeOption{metre} |metre|$=$\meta{name}
+% \hfill\tcboxverb{Default: none}\\ If the name of the metre is
+% expressed, it is printed after the lines and set flush left in
+% |voc|, |fullvoc| and |novoc| modes or flush right in |trans| mode.
+%
+% \DescribeOption{delim} |delim|$=$|true|\verb+|+|false|
+% \hfill\tcboxverb{Default: false}\\ This named argument does not
+% need a value as it defaults to |true| if it is used. If so, a
+% delimiter is printed between each of the hemistichs. By default, it
+% is set to the \enquote*{star} character \enquote*{*}. The
+% \DescribeMacro{\SetHemistichDelim}\cs{SetHemistichDelim}\marg{delimiter}
+% command may be used at any point of the document to change this
+% default setting.
+%
+% \DescribeOption{utf} |utf|$=$|true|\verb+|+|false|
+% \hfill\tcboxverb{Default: false}\\ As the preceding one, this
+% named argument does not need a value as it defaults to |true| if it
+% is used. If so, Unicode Arabic input is expected in the |arabverse|
+% environment instead of \textsc{ascii} Arab\TeX\ or Buckwalter input
+% schemes. See \vref{sec:unicode-input} for more details.
+%
+% \DescribeOption{color} |color|$=$\meta{color name}
+% \hfill\tcboxverb{Default: not set}\\
+% \NEWfeature{v1.13} The color in which lines of poetry are to be
+% rendered.
+%
+% \label{ref:poetry-export}
+% \DescribeOption{export} |export|$=$|true|\verb+|+|false|
+% \hfill\tcboxverb{Default: false}\\
+% \NEWfeature{v.1.13} This named argument does not need a value as it
+% defaults to |true| if it is used. If |export| is set as a global
+% option as well (see above \vpageref{export-mode}), all the lines
+% will be converted to Unicode and exported to the external selected
+% file. See below \vref{sec:arabtex2utf} for more details.
+%
+% \DescribeMacro{\bayt} Inside the |arabverse| environment, each line
+% is typeset by the \cs{bayt} command which takes two mandatory
+% arguments and may accept one optional
+% argument.\footnote{\label{ref:bayt-star}A \enquote*{starred} version
+% \cs{bayt*} is also defined. \package{arabluatex} uses it internally
+% when \texttt{export} is set to \texttt{true} to instruct some Lua
+% functions that lines of poetry have already been processed. That
+% aside, \cs{bayt} and \cs{bayt*} do the same, and only \cs{bayt}
+% should be used.} Additionally, every \cs{bayt} command \emph{must}
+% be followed with |\\| like so:---%
+% \iffalse
+%<*example>
+% \fi
+\begin{tcblisting}{text only}
+ \cs{bayt}\marg{\arb[trans]{.sadr}}\oarg{\arb[trans]{tadwIr}}%
+ \marg{\arb[trans]{`ajuz}}|\\|
+\end{tcblisting}
+% \iffalse
+%</example>
+% \fi
+%
+% That two subsequent hemistichs should be connected with one another
+% is technically named \arb[trans]{tadwIr}. Should that happen, either
+% the \arb[trans]{.sadr} or the \arb[trans]{`ajuz} or both of them,
+% may be connected to one another by letters that are naturally bound
+% to the following or the preceding ones over the
+% \arb[trans]{tadwIr}. The optional argument of the \cs{bayt} command
+% is designed to deal with the various situations that may arise:---
+% \begin{enumerate}
+% \item If the two hemistichs be connected with one another by a
+% prominent horizontal flexible stroke, the \arb[trans]{ta.twIl} should
+% be used, like so: |[--]| (see \vref{sec:tatwil}). Of course, the
+% ending word of the \arb[trans]{.sadr} and the word at the
+% commencement of the \arb[trans]{`a^guz} must have the
+% \arb[trans]{ta.twIl} too so that the proper shapes of the letters be
+% selected. Consider for example the following:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \begin{arabverse}[mode=fullvoc, width=.3\linewidth]
+ \bayt{lA 'ar_A man `ahidtu fI-hA fa-'abkI 'l---}[--]{---yawma
+ dalhaN wa-mA yaruddu 'l-bukA'u}\\
+ \end{arabverse}
+\end{example}
+% \iffalse
+%</example>
+% \fi%
+% As one can see, \emph{triple hyphens} have been used. In the
+% \arb[trans]{.sadr}, the first hyphen triggers the rules that are
+% related to the definite article and the \arb[trans]{'alif-u
+% 'l-wa.sl-i},\footnote{See \vref{ref:definite-article}} while the
+% following two select the figure of the letter \arb[trans]{lAm}
+% connected with a following letter. In the \arb[trans]{`a^guz}, the
+% last two hyphens select the letter \arb[trans]{yA'} connected with a
+% preceding letter, while the first one is simply discarded in this
+% mode, but still may appear as it should, if the |trans| mode be
+% selected:---%
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \begin{arabverse}[mode=trans, width=.4\linewidth]
+ \bayt{lA 'ar_A man `ahidtu fI-hA fa-'abkI 'l---}[--]{---yawma
+ dalhaN wa-mA yaruddu 'l-bukA'u}\\
+ \end{arabverse}
+\end{example}
+% \iffalse
+%</example>
+% \fi%
+% \item In some other cases, it may seem difficult, if not fairly
+% impossible, to split a given word into two parts. This happens
+% mostly because of the \arb[trans]{^saddaT}. Consider for example
+% the following:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \begin{arabverse}[mode=fullvoc, width=.25\linewidth,
+ gutter=1cm]
+ \bayt{.gayra 'annI qad 'asta`Inu `al_A 'l-ha--}[--mmi ]{'i_dA
+ _haffa bi-'l-_tawiyyi 'l-na^gA'u}\\
+ \bayt{bi-zaf--UfiN ka-'anna-hA hiq--laTuN}[ 'ummu ]{ri'AliN
+ dawwiyyaTuN saqfA'u}\\
+ \end{arabverse}
+\end{example}
+% \iffalse
+%</example>
+% \fi%
+% In the first line, the word \arb{al-hammi} should be split into
+% \arb{al-ham"-- --mi} as the first part of it belongs to the
+% \arb[trans]{.sadr} and the second to the \arb[trans]{`a^guz}. One
+% solution to avoid splitting this word in such a way is to write
+% inside the \arb[trans]{tadwIr} the part of it that belongs to either
+% hemistich, without omitting to add a space after it. In the second
+% line, the word \arb{'ummu} should be split into \arb{'um"-- --mu},
+% so that the only way to avoid splitting it into two parts is to
+% write it all inside the \arb[trans]{tadwIr}. In that case, as the
+% word is to be placed in the middle, it has been surrounded by
+% spaces.
+% \end{enumerate}
+%
+% \paragraph{Scaling and distortion of characters}
+% The |arabverse| environment and the \cs{bayt} command are designed
+% to typeset the verses in a two-column, fixed width layout. This may
+% result in a somewhat distorted text. Should that happen, one may
+% adapt the layout by modifying the values of the above described
+% |width| and |gutter| named arguments until the visual aspect of the
+% layout be satisfactory. It has to be noted that distortion and
+% warping may be even more perceptible in Roman than in Arabic
+% characters.
+%
+% \paragraph{Footnotes}
+% Footnotes are not set by default inside the \cs{bayt} command, but
+% there are two easy ways to have them printed.
+%
+% If they are little in number, each footnote may be split into pairs
+% of \cs{footnote\allowbreak{}mark}|{}| (please mind the braces or
+% \enquote{declare} |footnotemark| using \cs{MkArbBreak} to take it
+% out of the Arabic environment\footnote{See
+% \vref{sec:declare-new-commands}.}) in the argument of the \cs{bayt}
+% command and \cs{footnotetext} outside the \cs{bayt} command.
+%
+% If the footnotes are abundant in number, it is advised to load the
+% \package{footnotehyper} package which \package{arabluatex} will then
+% use to typeset any kind of footnote that is called from the
+% arguments of the \cs{bayt} command.\footnote{The \package{footnote}
+% package can also be used for the same effect. However, it must be
+% loaded \emph{after} \package{arabluatex}.}
+%
+% \paragraph{Line numbering}
+% Inside the |arabverse| environment, the |linenumbers| environment of
+% the \package{lineno} package can be used to have the lines of
+% succeeding verses numbered. Please refer to the documentation of
+% this package for more information or to the example below for a
+% basic implementation of this technique.
+%
+% \subsection{Example}
+% \label{sec:poetry-example}
+% Here follow the first lines of \prname{imru'u 'l-qaysi}'s
+% \arb[trans]{\uc{m}u`allaqaT}. In this example, \cs{SetArbDflt*} has
+% been selected so as to mark the \arb[trans]{'id.gAm} that is fit to
+% this declamatory poetry:---\footnote{Please note that for the time
+% being only the assimilation rules that are laid on
+% \vref{ref:assimilation} are applied. See
+% \vref{sec:classic-modern-typesetting} for more information. None of
+% the editions of the \arb[trans]{\uc{M}u`allaqAt} that I know of
+% feature the \arb[trans]{'id.gAm} in the Arabic text, although it is
+% often strongly marked in declamation.}%
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \begin{arab}[fullvoc]
+ qAla imru'u 'l-\uc{q}aysi fI mu`allaqati-hi:
+ \end{arab}
+
+ \begin{arabverse}[mode=fullvoc, metre={(al-.darbu 'l-_tAnI mina
+ 'l-`arU.di 'l-'_Ul_A mina 'l-.tawIli)}]
+ \SetArbDflt*
+ \begin{linenumbers*}
+ \bayt{qifA nabki min _dikr_A .habIbiN wa-manzili}{bi-saq.ti
+ 'l-liw_A bayna \uc{'l-d}a_hUli fa-\uc{.h}awmali}\\
+ \bayt{fa-\uc{t}U.di.ha fa-'l-\uc{m}iqrATi lam ya`fu
+ rasmu-hA}{limA nasa^gat-hA min ^ganUbiN wa-^sam'ali}\\
+ \bayt{tar_A ba`ara 'l-'ar'Ami fI `ara.sAti-hA}{wa-qI`Ani-hA
+ ka-'anna-hu .habbu fulfuli}\\
+ \bayt{ka-'annI .gadATa 'l-bayni yawma ta.hammalUA}{lad_A
+ samurAti 'l-.hayyi nAqifu .han.zali}\\
+ \bayt{wuqUfaN bi-hA .sa.hbI `alayya ma.tiyya-hum}{yaqUlUna
+ lA tahlik 'asaN_A wa-ta^gammali}\\
+ \bayt{wa-'inna ^sifA'I `abraTuN muharAqaTuN}{fa-hal `inda
+ rasmiN dAsiriN min mu`awwali}\\
+ \end{linenumbers*}
+ \end{arabverse}
+\end{code}
+% \iffalse
+%</example>
+% \fi%
+% \begin{arab}[fullvoc]
+% qAla imru'u 'l-\uc{q}aysi fI mu`allaqati-hi:
+% \end{arab}
+%
+% \begin{arabverse}[mode=fullvoc, metre={(al-.darbu 'l-_tAnI mina
+% 'l-`arU.di 'l-'_Ul_A mina 'l-.tawIli)}, width=.25\linewidth]
+% \SetArbDflt*
+% \begin{linenumbers*}
+% \bayt{qifA nabki min _dikr_A .habIbiN wa-manzili}{bi-saq.ti
+% 'l-liw_A bayna \uc{'l-d}a_hUli fa-\uc{.h}awmali}\\
+% \bayt{fa-\uc{t}U.di.ha fa-'l-\uc{m}iqrATi lam ya`fu
+% rasmu-hA}{limA nasa^gat-hA min ^ganUbiN wa-^sam'ali}\\
+% \bayt{tar_A ba`ara 'l-'ar'Ami fI `ara.sAti-hA}{wa-qI`Ani-hA
+% ka-'anna-hu .habbu fulfuli}\\
+% \bayt{ka-'annI .gadATa 'l-bayni yawma ta.hammalUA}{lad_A
+% samurAti
+% 'l-.hayyi nAqifu .han.zali}\\
+% \bayt{wuqUfaN bi-hA .sa.hbI `alayya ma.tiyya-hum}{yaqUlUna lA
+% tahlik 'asaN_A wa-ta^gammali}\\
+% \bayt{wa-'inna ^sifA'I `abraTuN muharAqaTuN}{fa-hal `inda rasmiN
+% dAsiriN min mu`awwali}\\
+% \end{linenumbers*}
+% \end{arabverse}
+%
+% \medskip
+%
+% \begin{arab}[trans]
+% qAla imru'u 'l-\uc{q}aysi fI mu`allaqati-hi:
+% \end{arab}
+%
+% \begin{arabverse}[mode=trans, metre={(al-.darbu 'l-_tAnI mina
+% 'l-`arU.di 'l-'_Ul_A mina 'l-.tawIli)}, width=.4\linewidth]
+% \SetArbDflt*
+% \begin{linenumbers*}
+% \bayt{qifA nabki min _dikr_A .habIbiN wa-manzili}{bi-saq.ti
+% 'l-liw_A bayna \uc{'l-d}a_hUli fa-\uc{.h}awmali}\\
+% \bayt{fa-\uc{t}U.di.ha fa-'l-\uc{m}iqrATi lam ya`fu
+% rasmu-hA}{limA nasa^gat-hA min ^ganUbiN wa-^sam'ali}\\
+% \bayt{tar_A ba`ara 'l-'ar'Ami fI `ara.sAti-hA}{wa-qI`Ani-hA
+% ka-'anna-hu .habbu fulfuli}\\
+% \bayt{ka-'annI .gadATa 'l-bayni yawma ta.hammalUA}{lad_A
+% samurAti
+% 'l-.hayyi nAqifu .han.zali}\\
+% \bayt{wuqUfaN bi-hA .sa.hbI `alayya ma.tiyya-hum}{yaqUlUna lA
+% tahlik 'asaN_A wa-ta^gammali}\\
+% \bayt{wa-'inna ^sifA'I `abraTuN muharAqaTuN}{fa-hal `inda rasmiN
+% dAsiriN min mu`awwali}\\
+% \end{linenumbers*}
+% \end{arabverse}
+%
+% \section{Special applications}
+% \label{sec:special-applications}
+% \phantomsection
+% \paragraph{Linguistics}
+% The same horizontal stroke as the \arb[trans]{ta.twIl} (see
+% \vref{sec:tatwil}) may be encoded \meta{B}; \meta{BB} will receive
+% the \arb[trans]{ta^sdId}. This is useful to make linguistic
+% annotations and comments on vowels:---
+% \begin{quote}
+% |Bu| |Ba| |Bi| |BuN| |BaN| |BiN| \arb[voc]{Bu Ba Bi BuN BaN BiN}
+% \arb[trans]{Bu Ba Bi BuN BaN BiN}, |BBu| |BBa| |BBi| \arb[voc]{BBu
+% BBa BBi} \arb[trans]{BBu BBa BBi}, |B--aN| \arb[voc]{B--aN}
+% \arb[trans]{B--aN}, |B"| \arb[voc]{B"}\,.
+% \end{quote}
+%
+% \paragraph{Brackets}
+% \phantomsection
+% \NEWfeature{v1.4.3} The various bracket symbols are useful in
+% technical documents such as critical editions for indicating that
+% some words or some letters must be added or
+% removed. \package{arabluatex} will automatically fit those symbols
+% to the direction of the text. For the time being, the following
+% symbols are supported:
+% \begin{itemize}
+% \item parentheses: |()|
+% \item square brackets: |[]|
+% \item angle brackets: |<>|
+% \item braces: |{}|
+% \end{itemize}
+%
+% \DescribeMacro{\abraces} Parentheses, square and angle brackets may
+% be input directly at the keyboard; however, words or letters that
+% are to be read between braces must be passed as arguments to the
+% \cs{abraces} command:---%
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \begin{arab}
+ \abraces{wa-qAla} 'inna 'abI kAna mina 'l-muqAtilaTi
+ wa-kAna--<--t> 'ummI min `u.zamA'i buyUti 'l-zamAzimaTi.
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% \paragraph{Additional Arabic marks}
+% \label{sec:arabic-marks}
+% In addition to common letters, many symbols and ligatures are
+% encoded in Arabic Unicode standard, such as honorifics consisting of
+% complex ligatures, and annotation signs used in the
+% \arb[trans]{\uc{qur'An}} or in classical poetry.
+%
+% \DescribeMacro{\arbmark}
+% \NEWfeature{v1.11}\cs{arbmark}\oarg{rl\textbar{}lr}\marg{shorthand}
+% can be used to insert such characters either in Unicode or in
+% romanized Arabic environments. It takes as argument a shorthand
+% defined beforehand in a default list which consists of the following
+% at the time of writing:---\\
+% \begin{longtable}{llp{.3\linewidth}p{.3\linewidth}}
+% \bottomrule
+% \caption*{\Cref*{tab:arabtex-additional-marks}: Additional Arabic
+% marks}
+% \endfoot
+% \captionlistentry{Additional Arabic marks}\\[-1em]
+% \toprule
+% Codepoint & Shorthand & Glyph & Transliteration \\ \midrule
+% \endfirsthead
+% \toprule
+% Codepoint & Shorthand & Glyph & Transliteration \\ \midrule
+% \endhead\label{tab:arabtex-additional-marks}%
+% |FDFD| & |bismillah| & \arb{\arbmark{bismillah}} &
+% \arbmark{bismillah} \\
+% |FDF5| & |salam| & \arb{\arbmark{salam}} & \arbmark{salam} \\
+% |FDFA| & |slm| & \arb{\arbmark{slm}} & \arbmark{slm} \\
+% |FDFB| & |jalla| & \arb{\arbmark{jalla}} & \arbmark{jalla} \\
+% \end{longtable}
+%
+% \NEWfeature{v1.13}
+% The mark to be inserted is determined by contextual analysis, or by
+% an optional argument, either |rl| to have the Arabic glyph printed,
+% or |lr| to print the tranliterated equivalent.
+%
+% \DescribeMacro{\newarbmark} \NEWfeature{v1.11} \cs{newarbmark} is
+% also provided should one wish to define new marks in addition to the
+% marks defined above. This command takes three arguments, like so:---
+% \arabluabox{\cs{newarbmark}\marg{shorthand}\marg{RTL
+% codepoint}\marg{LTR rendition}}
+%
+% As regards the right-to-left codepoint, it may be either typed in
+% Unicode or selected as Unicode codepoint. To that end, the \LaTeX\
+% command \tcboxverb{\symbol{"XYZT}} or its plain \TeX\ variant
+% \tcboxverb{\char"XYZT\relax} may be used, where |XYZT| are
+% uppercase hex digits (|0| to |9| or |A| to |F|).
+%
+% It is also possible to use the so-called `|^^^^| notation' like so:
+% \tcboxverb{^^^^xyzt}, where |xyzt| are lowercase hex digits (|0|
+% to |9| or |a| to |f|).
+%
+% As regards the third argument (left-to-right rendition), it may be
+% either left empty or typed by means of
+% \cs{arb}|[trans]|\marg{arabtex code} so as to have it printed in
+% romanized Arabic.%
+% \iffalse
+%<*example>
+% \fi
+\begin{tcblisting}{text only}
+ It must be noted that \cs{newarbmark} expects Arab\TeX\ input scheme
+ inside \cs{arb}|[trans]{}| to the exclusion of \textsf{buckwalter}
+ input scheme.
+\end{tcblisting}
+% \iffalse
+%</example>
+% \fi%
+%
+% The example below provides an implementation of this technique. It
+% may be observed that \cs{arbcolor} is used so as to have the marks
+% printed in red:---%
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \SetArbDflt*
+ \newarbmark{sly}{\arbcolor[red]{^^^^06d6}}{}
+ \newarbmark{jim}{\arbcolor[red]{^^^^06da}}{}
+ \begin{arab}
+ sUraTu 'l-nisA'i, 19:
+ \end{arab}
+ \begin{center}
+ \begin{arab}
+ \arbmark{bismillah}
+ \end{arab}
+ \end{center}
+ \begin{arab}[fullvoc]
+ y_a'ayyuhA 'lla_dIna 'a'manUA lA ya.hillu la-kum 'an tari_tUA
+ 'l-nisA'a karhaN\arbmark{sly} wa-lA ta`.dulU-hunna li-ta_dhabUA
+ bi-ba`.di mA 'a'taytumU-hunna 'illA 'an ya'tIna bi-fA.hi^saTiN
+ mubayyinaTiN\arbmark{jim} wa-`A^sirU-hunna
+ bi-'l-ma`rUfi\arbmark{jim} fa-'in karihtumU-hunna fa-`as_A_a
+ 'an takrahUA ^say'aN wa-ya^g`ala 'l-l_ahu fI-hi _hayraN
+ ka_tIraN ((19))
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% \subsection{\texorpdfstring{The \prname{qur'An}}{The QurʾÄn}}
+% \label{sec:the-quran}
+% This sub-part is destined to become a part of its own, as fine
+% typesetting of \prname{qur'An}ic text is planned in the versions of
+% \package{arabluatex} to come in the medium-term. New functions and
+% new Arabic modes will be available as \package{arabluatex} will
+% mature.
+%
+% \DescribeMacro{\ayah}\NEWfeature{v1.15}For the time being,
+% \cs{ayah}\marg{3-digit number} is provided so as to typeset the
+% number of the \arb[trans]{'AyaT} that it is referred to inside the
+% dedicated mark---Unicode |U+06DD|: \txarb{^^^^06dd}---in Arabic
+% script or inside parentheses in romanized Arabic:---
+% \begin{quote}
+% |\ayah{123}| \arb{\ayah{123}} \arb[trans]{\ayah{123}}.
+% \end{quote}
+%
+% An example follows:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \SetArbDflt*
+ \newarbmark{alifsp}{^^^^0627}{\arb[trans]{'alif} }
+ \newarbmark{lamsp}{^^^^0644^^^^0653}{\arb[trans]{lAm} }
+ \newarbmark{mim}{^^^^0645^^^^0653}{\arb[trans]{mIm}}
+ \begin{arab}[fullvoc]
+ min ((sUraTi \uc{'l-b}aqaraTi)):
+ \end{arab}
+ \begin{arab}[fullvoc]
+ \arbmark{alifsp}\arbmark{lamsp}\arbmark{mim}~\ayah{1}
+ _d_alika 'l-kit_abu lA rayba fI-hi hudaN_A
+ li-l-muttaqIna~\ayah{2} 'lla_dIna yu'minUna bi-'l-.gaybi
+ wa-yuqImUna 'l-.sal_aUTa wa-mimmA razaqn_a-hum
+ yunfiqUna~\ayah{3}
+ \end{arab}
+\end{example}
+\begin{tcblisting}{text only}
+ \SetArbDflt*
+ \begin{arab}[trans]
+ min ((sUraTi \uc{'l-b}aqaraTi)):
+ \end{arab}
+ \begin{arab}[trans]
+ \arbmark{alifsp}\arbmark{lamsp}\arbmark{mim}~\ayah{1}
+ _d_alika 'l-kit_abu lA rayba fI-hi hudaN_A
+ li-l-muttaqIna~\ayah{2} 'lla_dIna yu'minUna bi-'l-.gaybi
+ wa-yuqImUna 'l-.sal_aUTa wa-mimmA razaqn_a-hum
+ yunfiqUna~\ayah{3}
+ \end{arab}
+\end{tcblisting}
+% \iffalse
+%</example>
+% \fi
+%
+% \paragraph{Caveat}
+% For some reason, most of the Arabic fonts do not show the number
+% properly: some are only able to display at most two digits, while
+% others display the digits outside the \enquote*{end of
+% \arb[trans]{'AyaT}} sign, let alone those that print the digits
+% stacked. To the knowledge of the writer, this should be reported to
+% the developers of those fonts.
+%
+% \section{Color}
+% \label{sec:color}
+% \NEWfeature{v1.12}\package{arabluatex} is able to render in color
+% either words, parts of words or diacritics. As the techniques
+% implemented in this section may lead to some complexity, the reader
+% should first become well acquainted with the following
+% points:\footnote{Regarding the colors themselves and the way new
+% colors can be defined in addition to those that are already
+% available, please refer to the \package{xcolor} package.}---
+% \begin{enumerate}
+% \item The \enquote{pipe} character (\textbar, \vref{sec:pipe});
+% \item \enquote*{Quoting} technique (\vref{sec:quoting}), and more
+% specifically \enquote*{quoting the \arb[trans]{hamzaT}}
+% (\vpageref{sec:quoting-hamza});
+% \item Putting back on broken contextual analysis rules
+% (\vref{sec:arbnull});
+% \item Arabic marks (\vref{sec:arabic-marks}).
+% \end{enumerate}
+%
+% \DescribeMacro{\arbcolor} \cs{arbcolor} takes the text to be colored
+% into \meta{color} as an argument:---
+% \arabluabox{\cs{arbcolor}\oarg{color}\marg{Arabic text}}
+%
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \begin{arab}
+ \arbcolor[red]{al-bAbu 'l-_hAmisu} fI .tabaqAti 'l-'a.tibbA'i
+ 'lla_dIna kAnUA mun_du zamAni \uc{^gAlInUsa} wa-qarIbaN
+ min-hu. \arbcolor[red]{\uc{^gAlInUsu}}: wa-li-na.da` 'awwalaN
+ kalAmaN kulliyyaN fI 'a_hbAri \uc{^gAlInUsa} wa-mA kAna
+ `alay-hi...
+ \end{arab}
+ \begin{arab}[trans]
+ \arbcolor[red]{al-bAbu 'l-_hAmisu} fI .tabaqAti 'l-'a.tibbA'i
+ 'lla_dIna kAnUA mun_du zamAni \uc{^gAlInUsa} wa-qarIbaN
+ min-hu. \arbcolor[red]{\uc{^gAlInUsu}}: wa-li-na.da` 'awwalaN
+ kalAmaN kulliyyaN fI 'a_hbAri \uc{^gAlInUsa} wa-mA kAna
+ `alay-hi...
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% As this example shows, \cs{arbcolor} has been used to render
+% headings in red with the same encoding both in vocalized and in
+% romanized Arabic. The same technique also applies to syllabes inside
+% words. \package{arabluatex} takes care of selecting the appropriate
+% shape of the letters while coloring them:---
+% \begin{quote}\textbf{\enquote*{voc} mode}:\\
+% |i^stara\arbcolor[brown]{y}tu-hu| |bi-_tama\arbcolor[red]{niN}|
+% |'a`\arbcolor[blue]{^ga}ba-ka|
+% \arb{i^stara\arbcolor[brown]{y}tu-hu bi-_tama\arbcolor[red]{niN}
+% 'a`\arbcolor[blue]{^ga}ba-ka}
+% \arb[trans]{i^stara\arbcolor[brown]{y}tu-hu
+% bi-_tama\-\arbcolor[red]{niN} 'a`\arbcolor[blue]{^ga}ba-ka}.
+% \end{quote}
+% \begin{quote}\textbf{\enquote*{fullvoc} mode}:\\
+% |i^stara\arbcolor[brown]{y}tu-hu| |bi-_tama\arbcolor[red]{niN}|
+% |'a`\arbcolor[blue]{^ga}ba-ka|
+% \arb[fullvoc]{i^stara\arbcolor[brown]{y}tu-hu
+% bi-_tama\arbcolor[red]{niN} 'a`\arbcolor[blue]{^ga}ba-ka}
+% \arb[trans]{i^stara\arbcolor[brown]{y}tu-hu
+% bi-_tama\-\arbcolor[red]{niN} 'a`\arbcolor[blue]{^ga}ba-ka}.
+% \end{quote}
+%
+% \subsection{Tricks of the trade}
+% \label{sec:color-tricks}
+% \paragraph{Diacritics}
+% Depending on the mode selected, either |voc|, |novoc| or |fullvoc|,
+% coloring the diacritics requires more attention for the insertion of
+% \cs{arbcolor} may prevent contextual analysis from being applied.
+%
+% Furthermore, depending on the surrounding letters, the standard
+% encoding of short vowels \meta{u, a, i} may result either in
+% diacritics or in a connective \arb[trans]{'alif} with the
+% \arb[trans]{wa.slaT} or its accompanying vowel. As for the
+% \arb[trans]{sukUn}, it is generated by contextual analysis. Thus
+% applying colors to bare diacritics requires them to have specific
+% encodings.
+%
+% \Cref{tab:arbcolor-diacritics} gives the Arab\TeX\ equivalents for
+% the diacritics to be printed inside or just after \cs{arbcolor}.
+%
+% \needspace{7\baselineskip}
+% \begin{longtable}{lllll}
+% \bottomrule
+% \caption*{\Cref*{tab:arbcolor-diacritics}: Arab\TeX\ diacritics
+% for \cs{arbcolor}}
+% \endfoot
+% \captionlistentry{Arab\TeX\ diacritics for \cs{arbcolor}}\\[-1em]
+% \toprule
+% Diacritic & \multicolumn{3}{l}{Transliteration\footnotemark}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & \\ \midrule
+% \endfirsthead
+% \toprule
+% Diacritic & \multicolumn{3}{l}{Transliteration}
+% & Arab\TeX\ notation \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & \\ \midrule
+% \endhead \footnotetext{See below \vref{sec:transliteration}.}
+% \label{tab:arbcolor-diacritics}
+% \arb{B.a} & \dmg{.a} & \loc{.a} & \brill{.a} & \verb|.a| \\
+% \pagebreak[1]
+% \arb{B.u} & \dmg{.u} & \loc{.u} & \brill{.u} & \verb|.u| \\
+% \arb{B.i} & \dmg{.i} & \loc{.i} & \brill{.i} & \verb|.i| \\ \midrule
+% \arb{Bo} & \dmg{o} & \loc{o} & \brill{o} & \verb|o| \\
+% \end{longtable}
+%
+% The following examples show how the letters, or the diacritics above
+% or under them or both the letters and the diacritics can be rendered
+% in different colors:---
+% \begin{quote}\textbf{\enquote*{voc} mode}:\\
+% |i^staraytu-hu| |bi-_taman\arbcolor[red]{iN}|
+% |'a`^g\arbcolor[red]|\allowbreak|{.a}ba-ka|
+% \arb{i^staraytu-hu bi-_taman\arbcolor[red]{iN}
+% 'a`^g\arbcolor[red]{.a}ba-ka}
+% \arb[trans]{i^staraytu-hu bi-_taman\arbcolor[red]{iN}
+% 'a`^g\arbcolor[red]{.a}ba-ka}.
+%
+% |i^staraytu-hu| |bi-_tama\arbcolor[red]{n}iN|
+% |'a`\arbcolor[red]|\allowbreak|{^g}.aba-ka|
+% \arb{i^staraytu-hu bi-_tama\arbcolor[red]{n}iN
+% 'a`\arbcolor[red]{^g}.aba-ka}
+% \arb[trans]{i^staraytu-hu bi-_tama\arbcolor[red]{n}iN
+% 'a`\arbcolor[red]{^g}.aba-ka}.
+%
+% |i^staraytu-hu| |bi-_tama\arbcolor[red]{n}\arbcolor[blue]{iN}|
+% \allowbreak
+% |'a`\arbcolor[red]|\allowbreak|{^g}\arbcolor[blue]{.a}ba-ka|
+% \arb{i^staraytu-hu bi-_tama\arbcolor[red]{n}\arbcolor[blue]{iN}
+% 'a`\arbcolor[red]{^g}\arbcolor[blue]{.a}ba-ka} \linebreak
+% \arb[trans]{i^staraytu-hu
+% bi-_tama\arbcolor[red]{n}\arbcolor[blue]{iN}
+% 'a`\arbcolor[red]{^g}\arbcolor[blue]{.a}ba-ka}.
+% \end{quote}
+%
+% \begin{quote}\textbf{\enquote*{fullvoc} mode}:\\
+% |i^staray"\arbcolor[red]{o}tu-hu| |bi-_taman"\arbcolor[red]{iN}|
+% |'a`^g"\arbcolor[red]{.a}ba-ka|
+% \arb[fullvoc]{i^staray"\arbcolor[red]{o}tu-hu
+% bi-_taman"\arbcolor[red]{iN} 'a`^g"\arbcolor[red]{.a}ba-ka}
+% \arb[trans]{i^staray"\arbcolor[red]{o}tu-hu
+% bi-_taman"\arbcolor[red]{iN}
+% \linebreak 'a`^g"\arbcolor[red]{.a}ba-ka}.
+%
+% |i^stara\arbcolor[red]{y"}otu-hu| |bi-_tama\arbcolor[red]{n"}iN|
+% |'a`\arbcolor[red]|\allowbreak|{^g"}.aba-ka|
+% \arb[fullvoc]{i^stara\arbcolor[red]{y"}otu-hu
+% bi-_tama\arbcolor[red]{n"}iN 'a`\arbcolor[red]{^g"}.aba-ka}
+% \arb[trans]{i^stara\arbcolor[red]{y"}otu-hu
+% bi-_tama\arbcolor[red]{n"}iN 'a`\arbcolor[red]{^g"}.aba-ka}.
+%
+% |i^stara\arbcolor[red]{y"}\arbcolor[blue]{o}tu-hu|
+% |bi-_tama\arb|\allowbreak|color[red]{n"}\arbcolor[blue]{iN}|
+% |'a`\arbcolor[red]|\allowbreak|{^g"}\arb|\allowbreak%
+% |color[blue]{.a}ba-ka|
+% \arb[fullvoc]{i^stara\arbcolor[red]{y"}\arbcolor[blue]{o}tu-hu
+% bi-_tama\arbcolor[red]{n"}\arbcolor[blue]{iN}
+% 'a`\arbcolor[red]{^g"}\arbcolor[blue]{.a}ba-ka}
+% \arb[trans]{i^stara\arbcolor[red]{y"}\arbcolor[blue]{o}tu-hu
+% bi-_tama\arbcolor[red]{n"}\arbcolor[blue]{iN}
+% 'a`\arbcolor[red]{^g"}\arbcolor[blue]{.a}ba-ka}.
+% \end{quote}
+%
+% As can be seen, |fullvoc| required the letters |y|, |n| and |^g|
+% before \cs{arbcolor} to be \enquote*{quoted}. Otherwise, unwanted
+% \arb[trans]{sukUn}\txtrans{s} would have been generated because of
+% the absence of a vowel after those consonants.
+%
+% \paragraph{\texorpdfstring{\arb[trans]{tanwIn}}{tanwīn}}
+% \cs{arbnull} must be used with \arb[trans]{fat.haTAn} (\arb{BaN}) so
+% as to put back on contextual analysis rules:---
+% \begin{quote}
+% |mu`allim\arbcolor[red]{\arbnull{m}aN}|
+% \arb{mu`allim\arbcolor[red]{\arbnull{m}aN}}
+% \arb[trans]{mu`allim\arbcolor[red]{\arbnull{m}aN}},\\
+% |istisqA'\arbcolor[red]{\arbnull{A'}aN}|
+% \arb{istisqA'\arbcolor[red]{\arbnull{A'}aN}}
+% \arb[trans]{istisqA'\arbcolor[red]{\arbnull{A'}aN}},\\
+% |^say'\arbcolor[red]{\arbnull{ay'}aN}|
+% \arb{^say'\arbcolor[red]{\arbnull{ay'}aN}}
+% \arb[trans]{^say'\arbcolor[red]{\arbnull{ay'}aN}},\\
+% \verb+^gAmi`aT|\arbcolor[red]{\arbnull{T}aN}+
+% \arb{^gAmi`aT|\arbcolor[red]{\arbnull{T}aN}}
+% \arb[trans]{^gAmi`aT|\arbcolor[red]{\arbnull{T}aN}}.
+% \end{quote}
+% \begin{quoting}
+% \textsc{Rem.} Note that in the last example
+% (\arb[trans]{^gAmi`aT|\arbcolor[red]{\arbnull{T}aN}}), the
+% \enquote*{pipe} character has been inserted before
+% \cs{arbcolor}. Otherwise, the |dmg| mode of the transliteration
+% rules would have interpreted the \arb[trans]{tA' marbU.taT} as
+% \emph{final} (e.g. \txtrans{h} instead of the expected
+% \txtrans{t}).\footnote{See also \vpageref{ref:ta-marbutah-pipe}
+% \enquote{Discarding the \arb[trans]{'i`rAb}} for more
+% information.}
+% \end{quoting}
+%
+% The \arb[trans]{tanwIn} preceding a \arb[novoc]{_A} conveys even
+% more intricate business to the rendering with the utmost accuracy in
+% both romanized and non-romanized modes. First, a new Arabic mark
+% needs to be defined. It should print \arb[novoc]{_A} in Arabic
+% script and not a thing in transliteration. It is to be appended after
+% \cs{arbcolor}, like so:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \newarbmark{Y}{^^^^0649}{}
+ \arb{hud\arbcolor[red]{aN\arbnull{_A}}\arbmark{Y}}
+ \arb[trans]{hud\arbcolor[red]{aN\arbnull{_A}}\arbmark{Y}}
+\end{example}
+% \iffalse
+%</example>
+% \fi%
+%
+% \paragraph{\texorpdfstring{\arb[trans]{wa.slaT} and
+% \arb[trans]{maddaT}}{waá¹£lah and maddah}}
+% Both can be generated with the help of \cs{arbnull}:---
+% \begin{quote}
+% |wa-\arbcolor[red]{\arbnull{wa}i}stisqA'uN|
+% \arb[fullvoc]{wa-\arbcolor[red]{\arbnull{wa}i}stisqA'uN}
+% \arb[trans]{wa-\arbcolor[red]{\arbnull{wa}i}stisqA'uN}\footnote{To
+% the knowledge of the writer, the \arb[trans]{wa.slaT} alone is not
+% part of the Arabic Unicode block.}.
+%
+% |fI| |"al".i-\arbcolor[red]{\arbnull{'l-}i}btidA'i|
+% \arb[fullvoc]{fI "al".i-\arbcolor[red]{\arbnull{'l-}i}btidA'i}
+% \linebreak
+% \arb[trans]{fI "al".i-\arbcolor[red]{\arbnull{'l-}i}btidA'i}.
+%
+% |\arbcolor[red]{'a'\arbnull{k}}kulu|
+% \arb{\arbcolor[red]{'a'\arbnull{k}}kulu}
+% \arb[trans]{\arbcolor[red]{'a'\arbnull{k}}kulu},\\
+% |\arbcolor[red]{'A\arbnull{k}}kiluN|
+% \arb{\arbcolor[red]{'A\arbnull{k}}kiluN}
+% \arb[trans]{\arbcolor[red]{'A\arbnull{k}}kiluN}.
+% \end{quote}
+%
+% The Unicode codepoint of the \arb[trans]{maddaT} is 0653, while bare
+% \arb[trans]{'alif} is 0627. So:--- %
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \newarbmark{alifmaddahred}{^^^^0627\arbcolor[red]{^^^^0653}}%
+ {\arb[trans]{\arbcolor[red]{'a'\arbnull{k}}}}
+ \arb{\arbmark{alifmaddahred}kulu}
+ \arb[trans]{\arbmark{alifmaddahred}kulu}.
+\end{example}
+% \iffalse
+%</example>
+% \fi%
+%
+% \begin{quoting}
+% \textsc{Rem.} In the preceding example, any consonant could have
+% been passed as argument to the \cs{arbnull} command.
+% \end{quoting}
+%
+% \paragraph{\texorpdfstring{\arb[trans]{^sad\-daT}}{Å¡addah}}
+% In the following example, it is assumed that the
+% \arb[trans]{^saddaT} above the letter \arb[novoc]{l} in
+% \arb[fullvoc]{al-mu`allimUna}, \arb[trans]{al-mu`allimUna}, is to be
+% rendered in red. Thus the Arabic mark must generate the
+% \arb[trans]{^saddaT} alone---of which the Unicode codepoint is
+% 0651---in Arabic script and the letter \enquote*{l} in
+% transliteration:--- %
+%\iffalse
+%<*example>
+% \fi
+\begin{example}
+ \newarbmark{lamshaddah}{^^^^0651}{l}
+ \arb[fullvoc]{al-mu`al"\arbcolor[red]{\arbmark{lamshaddah}}.imUna}
+ \arb[trans]{al-mu`al"\arbcolor[red]{\arbmark{lamshaddah}}.imUna}.
+\end{example}
+% \iffalse
+%</example>
+% \fi%
+%
+% \paragraph{\texorpdfstring{The definite article and the euphonic
+% \arb[trans]{ta^sdId}}{The definite article and the euphonic tašdīd}}
+% The intricate business of rendering in color the initial
+% \arb[trans]{'alif al-wa.sl} of the definite article followed by a
+% solar consonant must be unraveled.
+%
+% From the examples provided above, in |fI 'l-nAsi| \arb[fullvoc]{fI
+% 'l-nAsi} \arb[trans]{fI 'l-nAsi}, the initial \arb[trans]{'alif-u
+% 'l-wa.sl-i} can be rendered in red like so:
+% |\arbcolor[red]{\arbnull{al-}a}|
+% \arb[fullvoc]{\arbcolor[red]{\arbnull{al-}a}}. Then, the following
+% two letters, namely |l-n|, must print the string \arb[trans]{lAm}
+% $+$ \arb[trans]{nUn} $+$ \arb[trans]{^saddaT} in Arabic, and exactly
+% \txtrans{n-n} in transliteration. Thus an Arabic mark is
+% needed:--- %
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \newarbmark{lnn}{^^^^0644^^^^0646^^^^0651}{n-n}
+ \arb[fullvoc]{fI\arbnull{al-}
+ \arbcolor[red]{\arbnull{al-}a}\arbmark{lnn}Asi}
+ \arb[trans]{fI\arbnull{al-}
+ \arbcolor[red]{\arbnull{al-}a}\arbmark{lnn}Asi}.
+\end{example}
+% \iffalse
+%</example>
+% \fi%
+%
+% \paragraph{\texorpdfstring{\arb[trans]{hamzaT}}{hamzah}}
+% The \enquote*{quoting} technique provides an easy way to determine
+% the carrier of the \arb[trans]{hamzaT}, as shown in
+% \vref{tab:quoted-hamza}---:
+% \begin{quote}
+% \verb+yatasA\arbnull{'a}\arbcolor[red]{|"'}.alUna+
+% \arb{yatasA\arbnull{'a}\arbcolor[red]{|"'}.alUna}
+% \arb[trans]{yatasA\arbnull{'a}\-\arbcolor[red]{|"'}.a\-lUna},
+% \verb+^say\arbcolor[red]{|"'}\arbnull{'}aN+
+% \arb{^say\arbcolor[red]{|"'}\arbnull{'}aN}
+% \arb[trans]{^say\arbcolor[red]{|"'}\arbnull{'}aN},
+% \verb+^say\ar+\allowbreak\verb+bcolor[red]{|"'}iN+
+% \arb{^say\arbcolor[red]{|"'}iN}
+% \arb[trans]{^say\arbcolor[red]{|"'}iN},
+% |\arbcolor[red]{a"'}.as\arbcolor|\allowbreak|[red]{y"'}.ilaTuN|
+% \arb{\arbcolor[red]{a"'}.as\arbcolor[red]{y"'}.ilaTuN}
+% \arb[trans]{\arbcolor[red]{a"'}.as\arbcolor[red]{y"'}.ilaTuN}.
+% \end{quote}
+%
+%
+% \section{Transliteration}
+% \label{sec:transliteration}
+% It may be more appropriate to speak of \enquote{romanization} than
+% \enquote{transliteration} of Arabic. As seen above in
+% \cref{sec:options} \vpagerefrange{sec:options}{sec:local-options},
+% the \enquote{transliteration mode} may be selected globally or locally.
+%
+% This mode transliterates the Arab\TeX\ input into one of the
+% accepted standards. As said above \vpageref{ref:describe-trans},
+% three standards are supported at present:
+% \begin{description}
+% \item[dmg] \emph{Deutsche Morgenländische Gesellschaft}, which was
+% adopted by the International Convention of Orientalist Scholars in
+% Rome in 1935.\footnote{See \textcite{dmg}.} |dmg| transliteration
+% convention is selected by default;
+% \item[loc] \emph{Library of Congress}: this standard is part of a
+% large set of standards for romanization of non-roman scripts
+% adopted by the American Library Association and the Library of
+% Congress;\footnote{See
+% \url{http://www.loc.gov/catdir/cpso/roman.html} for the
+% \href{http://www.loc.gov/catdir/cpso/romanization/arabic.pdf}{source
+% document concerning Arabic language}.}
+% \item[arabica] \NEWfeature{v1.8}
+% \changes{v1.8}{2017/03/30}{\texttt{arabica} transliteration
+% standard is now supported} \emph{Journal of Arabic and Islamic
+% Studies}/\emph{Revue d'études arabes et islamiques}: this standard
+% is most widely used by scholars in the field of Arabic
+% studies.\footnote{See
+% \url{http://www.brill.nl/files/brill.nl/specific/authors_instructions/ARAB.pdf}.}
+% \end{description}
+% More standards will be included in future releases of
+% \package{arabluatex}.
+%
+% \paragraph{Convention} \DescribeMacro{\SetTranslitConvention} The
+% transliteration mode, which is set to |dmg| by default, may be
+% changed at any point of the document by the
+% \cs{SetTranslitConvention}\marg{mode} command , where \meta{mode}
+% may be either |dmg|, |loc| or |arabica|. This command is also
+% accepted in the preamble should one wish to set the transliteration
+% mode globally, e.g.:---%
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \usepackage{arabluatex}
+ \SetTranslitConvention{loc}
+\end{code}
+% \iffalse
+%</example>
+% \fi
+%
+% \paragraph{Style} \DescribeMacro{\SetTranslitStyle} Any
+% transliterated Arabic text is printed in italics by default. This
+% also can be changed either globally in the preamble or locally at
+% any point of the document by the \cs{SetTranslitStyle}\marg{style}
+% command, where \meta{style} may be any font shape selection
+% command, e.g. \cs{upshape}, \cs{itshape}, \cs{slshape}, and so forth.
+%
+% \paragraph{Font} \NEWfeature{v1.4} \DescribeMacro{\SetTranslitFont}
+% \cs{SetTranslitFont}\marg{font selection command} allows any
+% specific font to be selected for rendering transliterated text with
+% the font-selecting commands of the \package{fontspec} or
+% \package{luaotfload} package. Of course, this font must have been
+% defined properly. To take one example, here is how the \emph{Gentium
+% Plus} font can be used for rendering transliterated text:---
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \newfontfamily\translitfont{Gentium Plus}[Ligatures=TeX]
+ \SetTranslitFont{\translitfont}
+\end{code}
+% \iffalse
+%</example>
+% \fi
+%
+% \paragraph{Proper names} \DescribeMacro{\uc} Proper names or book
+% titles that must have their first letters uppercased may be passed
+% as arguments to the \cs{uc}\marg{word} command. \cs{uc} is a
+% clever command, for it will give the definite article
+% \arb[trans]{al-} in lower case in all positions. Moreover, if the
+% inital letter, apart from the article, cannot be uppercased,
+% viz. \arb[trans]{|"'} or \arb[trans]{`}, the letter next to it will be
+% uppercased:---
+% \begin{quote}
+% |\uc{.hunayn-u}| |bn-u| |\uc{'is.h_aq-a}|
+% \arb[voc]{\uc{.hunayn-u} bn-u \uc{'is.h_aq-a}}
+% \arb[trans]{\uc{.hunayn-u} bn-u \uc{'is.h_aq-a}},
+% |\uc{`u_tm_an-u}| \arb[voc]{\uc{`u_tm_an-u}}
+% \arb[trans]{\uc{`u_tm_an-u}}, |.daraba| |\uc{zayd-u}| |bn-u|
+% |\uc{_h_alidiN}| |\uc{sa`d-a}| |bn-a| |\uc{`awf-i}| |bn-i|
+% |\uc{|\allowbreak|`abd-i}| |\uc{'l-l_ah-i}|
+% \arb[fullvoc]{.daraba \uc{zayd-u} bn-u \uc{_h_alidiN}
+% \uc{sa`d-a} bn-a \uc{`awf-i} bn-i \uc{`abd-i} \uc{'l-l_ah-i}}
+% \arb[trans]{.daraba \uc{zayd-u} bn-u \uc{_h_alidiN} \uc{sa`d-a}
+% bn-a \uc{`awf-i} bn-i \uc{`abd-i} \uc{'l-l_ah-i}}.
+% \end{quote}
+% However, \cs{uc} must be used cautiously in some very particular
+% cases, for the closing brace of its argument may prevent a rule from
+% being applied. To take an example, as seen above
+% \vpageref{ref:muhammaduni}, the transliteration of
+% \arb[fullvoc]{\uc{m}u.hammaduN 'l-nabI} must be
+% \arb[trans]{\uc{m}u.hammaduN 'l-nabI}, as nouns having the
+% \arb[trans]{tanwIn} take a \arb[trans]{kasraT} in pronunciation
+% before \arb[trans]{'alifu 'l-wa.sli}. In that case, encoding
+% \arb[fullvoc]{mu.hammaduN} like so: |\uc{mu.hammaduN}| is wrong,
+% because the closing brace would prevent \package{arabluatex} from
+% detecting the sequence \meta{-uN} immediately followed by
+% \meta{'l-}. Fortunately, this can be circumvented in a
+% straightforward way by inserting only part of the noun in the
+% argument of \cs{uc} vz. up to the first letter that is to be
+% uppercased, like so: |\uc{m}u.hammaduN|.
+%
+% \paragraph{Hyphenation}
+% In case transliterated Arabic words break the \TeX\ hyphenation
+% algorithm, one may use the |\-| command to insert discretionary
+% hyphens. This command will be discarded in all of the Arabic modes
+% of \package{arabluatex}, but will be processed by any of the
+% transliteration modes:---
+% \begin{quote}
+% |\uc{'abU}| |\uc{bakriN}| |\uc{mu\-.ham\-madu}| |bnu|
+% |\uc{za\-ka| |\-riy\-yA'a}| |\uc{'l-rAziyyu}| \arb{\uc{'abU}
+% \uc{bakriN} \uc{mu\-.ham\-mad-u} bnu \uc{za\-ka\-riy\-yA'a}
+% \uc{'l-rAziyyu}} \arb[trans]{\uc{'abU} \uc{bakriN}
+% \uc{mu\-.ham\-mad-u} bn-u \uc{za\-ka\-riy\-yA'-a}
+% \uc{'l-rAziyyu}}.
+% \end{quote}
+%
+% \paragraph{\enquote*{Long} pro\-per names}
+% \NEWfeature{v1.10} \cs{uc} is also able to process proper names
+% consisting of several subsequent words:---
+% \begin{quote}
+% |\arb[trans]{\uc{'abU| |zaydiN| |.hunaynu| |bnu| |'is.h_aqa|
+% |'l-`ibAdiyyu}}| \arb[trans]{\uc{'abU zaydiN .hunaynu bnu
+% 'is.h_aqa 'l-`ibAdiyyu}}.
+% \end{quote}
+%
+% \paragraph{Proper names outside Arabic environments}
+% \changes{v1.10}{2018/01/03}{\cs{uc} supersedes \cs{cap}}
+% \DescribeMacro{\prname}\NEWfeature{v1.10} Transliterated proper
+% names inserted in paragraphs of English text should be printed in
+% the same typeface as the surrounding text. \cs{prname}\marg{Arabic
+% proper name} is provided to that effect:\footnote{Just as \cs{uc},
+% \cs{prname} is also able to process proper names consisting of
+% several subsequent words.}---
+%\iffalse
+%<*example>
+% \fi
+\begin{example}
+ From \textcite[i. 23 C]{Wright}:--- If the name following
+ \arb[fullvoc]{ibnuN} be that of the mother or the grandfather, the
+ \arb[fullvoc]{"a} is retained; as \arb[fullvoc]{`Is_A ibnu maryama},
+ \enquote{Jesus the son of Mary}; \arb[fullvoc]{`ammAru ibnu
+ man.sUriN}, \enquote{\prname{`ammAr} the (grand)son of
+ \prname{man.sUr}}.
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% The following example shows how \cs{prname} can be used in
+% conjunction with the \package{nameauth} package to have Arabic
+% proper names printed first in full then in partial
+% forms:\footnote{See the documentation of \package{nameauth} for more
+% details: \url{https://ctan.org/pkg/nameauth}}--- %
+%\iffalse
+%<*example>
+% \fi
+\begin{example}
+ \begin{nameauth}
+ \< Hunayn & \prname{'abU zayd} & \prname{.hunayn}, \prname{{i}bn
+ 'is.h_aq al-`ibAdiyy} & > %
+ \< Razi & \prname{'abU bakr mu.hammad ibn zakariyyA'} &
+ \prname{al-rAziyy} & > %
+ \end{nameauth}
+
+ On first occurrence, proper names are printed as \Hunayn, \Razi.
+ Then as \Hunayn, \Razi.
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% \begin{quoting}\label{ref:prname-star}
+% \textsc{Rem.} \DescribeMacro{\prname*} \package{arabluatex} also
+% provides \cs{prname*} which only renders in upright roman style
+% already transliterated proper names without applying any further
+% processing. It is mostly used internally and applied to proper
+% names exported in Unicode to an external selected
+% file.\footnote{See below \vref{sec:arabtex2utf} for more details.}
+% \end{quoting}
+%
+% \subsection{Additional note on \texttt{dmg} convention}
+% \label{sec:additional-note-dmg}
+% \NEWfeature{v1.3} According to \textcite[6]{dmg}, Arabic
+% \arb[trans]{'i`rAb} may be rendered into |dmg| in three different
+% ways:
+% \begin{enumerate}
+% \item \label{ref:dmg-full-rend}In full:
+% \NoArbUp\arb[trans]{\uc{`amruNU}}\ArbUpDflt\,;
+% \item \label{ref:dmg-up-rend}As superscript text:
+% \arb[trans]{\uc{`amruNU}}\,;
+% \item \label{ref:irab-discarded}Discarded: \arb[trans]{\uc{`amr}}.
+% \end{enumerate}
+% \DescribeMacro{\arbup} By default, \package{arabluatex} applies rule
+% \ref{ref:dmg-up-rend}. Once delimited by a set of Lua functions,
+% \arb[trans]{'i`rAb} is passed as an argument on to a \cs{arbup}
+% command which is set to \cs{textsuperscript}.
+%
+% \DescribeMacro{\NoArbUp} \DescribeMacro{\ArbUpDflt} \cs{NoArbUp} may
+% be used either in the preamble or at any point of the document in
+% case one wishes to apply rule \ref{ref:dmg-full-rend}. The default
+% rule \ref{ref:dmg-up-rend} can be set back with \cs{ArbUpDflt} at
+% any point of the document.
+%
+% \DescribeMacro{\SetArbUp} Finally, \cs{SetArbUp}\marg{formatting
+% directives} can be used to customize the way \arb[trans]{'i`rAb} is
+% displayed. To take one example, here is how Arabic
+% \arb[trans]{'i`rAb} may be rendered as subscript text:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \SetArbUp{\textsubscript{#1}}
+ Arabic |dmg| transliteration for \arb{ra'aytu ^gAmi`aN
+ muhaddamaTaN mi'_danatu-hu}: \arb[trans]{ra'aytu
+ ^gAmi`aN muhaddamaTaN mi'_danatu-hu.}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% As shown in the above example, |#1| is the token that is replaced
+% with the actual \arb[trans]{tanwIn} in the formatting directives of
+% the \cs{SetArbUp} command.
+%
+% \paragraph{\texorpdfstring{\arb[trans]{'i`rAb} boundaries}{ʾiÊ¿rÄb
+% boundaries}}
+% Every declinable noun (\arb[trans]{mu`rab}) may be declined either
+% with or without \arb[trans]{tanwIn}, viz. \arb[trans]{mun.sarifuN}
+% or \arb[trans]{.gayr-u mun.sarifiN}. The former is automatically
+% parsed by \package{arabluatex}, whereas the latter has to be
+% delimited with an hyphen, like so:---
+% \begin{quote}
+% \arb[trans]{\textbf{mun.sarif}}: |mu`allimuN|
+% \arb[voc]{mu`allimuN} \arb[trans]{mu`allimuN}, |kA'inuN|
+% \arb[voc]{kA'inuN} \arb[trans]{kA'inuN}, |kA'inAtuN|
+% \arb[voc]{kA'inAtuN} \arb[trans]{kA'inAtuN}, |\uc{`amraNU}|
+% \arb[voc]{\uc{`amraNU}} \arb[trans]{\uc{`amraNU}}, |fataN_A|
+% \arb[voc]{fataN_A} \arb[trans]{fataN_A}, |qA.diNI| \arb{qA.diNI}
+% \arb[trans]{qA.diNI}.
+%
+% \arb[trans]{\textbf{.gayr mun.sarif}}: |al-mu`allim-u|
+% \arb[voc]{al-mu`allim-u} \arb[trans]{al-mu`allim-u}, |kitAb-Ani|
+% \arb[voc]{kitAb-Ani} \arb[trans]{kitAb-Ani}, |ra^sa'-Ani|
+% \arb[voc]{ra^sa'-Ani} \arb[trans]{ra^sa'-Ani}, |sAriq-Una|
+% \arb[voc]{sAriq-Una} \arb[trans]{sAriq-Una}, |qA.d-Una|
+% \arb[voc]{qA.d-Una} \arb[trans]{qA.d-Una}, |al-.zulm-Atu|
+% \arb[voc]{al-.zulm-Atu} \arb[trans]{al-.zulm-Atu}.
+% \end{quote}
+%
+% \begin{quoting}
+% \textsc{Rem.}~\emph{a.} As the \arb[trans]{tanwIn} is passed over
+% in pronunciation when it is followed by the letters
+% \arb[novoc]{r}, \arb[novoc]{l}, \arb[novoc]{m}, \arb[novoc]{w},
+% \arb[novoc]{y} (see \vref{ref:assimilation}), it may be desirable
+% to further distinguish it by putting it above the line, but not to
+% do the same for \arb[trans]{.gayr mun.sarif} terminations. This
+% can be achieved by simply omitting the hyphen before any
+% \arb[trans]{.gayr mun.sarif} termination:---\\
+% |kAna| |.ganiyyaN| |l_akinna-hu| |labisa| |^gubbaTaN| |mumazzaqaN|
+% |'aydu-hA| \arb[voc]{kAna .ganiyyaN l_akinna-hu labisa ^gubbaTaN
+% mumazzaqaN 'aydu-hA} \arb[trans]{kAna .ganiyyaN l_akinna-hu labisa
+% ^gubbaTaN mumazzaqaN 'aydu-hA}.
+%
+% \textsc{Rem.}~\emph{b.} Although the hyphen before the
+% \arb[trans]{tanwIn} is optional as \package{arabluatex} always
+% parses nouns with such termination, it may also be used to mark
+% better the inflectional endings:---\\
+% |mana`a| |'l-nAs-a| |kAffaT-aN| |min| |mu_hA.tabati-hi|
+% |'a.had-uN| |bi-sayyidi-nA| \arb[voc]{mana`a 'l-nAs-a kAffaT-aN
+% min mu_hA.tabati-hi 'a.had-uN bi-sayyidi-nA} \arb[trans]{mana`a
+% 'l-nAs-a kAffaT-aN min mu_hA.tabati-hi 'a.had-uN bi-sayyidi-nA}.
+% \end{quoting}
+%
+% \paragraph{\texorpdfstring{Discar\-ding the
+% \arb[trans]{'i`rAb}}{Discarding the ʾiÊ¿rÄb}}
+% \label{ref:ta-marbutah-pipe}
+% As said above (\vref{ref:irab-discarded}), the \arb[trans]{'i`rAb}
+% may be discarded in some cases, as in transliterated proper names or
+% book titles. \package{arabluatex} is able to render words ending
+% with \arb[trans]{tA' marbU.taT} in different ways, depending on
+% their function:---
+% \begin{enumerate}
+% \item Nouns followed by an adjective in apposition: |madInaT|
+% |kabIraT| \arb[trans]{madInaT kabIraT}, |al-madInaT| |al-kabIraT|
+% \arb[trans]{al-madInaT al-kabIraT}.
+% \item Nouns followed by another noun in the genitive (contruct
+% state): |.hikmaT| |al-l_ah| \arb[trans]{.hikmaT| \uc{al-l_ah}},
+% |fi.d.daT| |al-darAhim| \arb[trans]{fi.d.daT al-darAhim}.
+% \end{enumerate}
+% \begin{quoting}
+% \textsc{Rem.} It may so happen, as in the absence of the article
+% before the annexed word, that \package{arabluatex} be unable to
+% determine which of the above two cases the word ending with
+% \arb[trans]{tA' marbU.taT} falls into. The \enquote*{pipe}
+% character (see \vref{sec:pipe}) may be appended to that word to
+% indicate that what follows is in the construct state:
+% |\uc{r}isAlaT| |fI| |tartIb| \verb+qirA'aT|+ |kutub|
+% |\uc{^g}AlInUs| \arb[trans]{\uc{r}isAlaT fI tartIb qirA'aT|
+% kutub \uc{^g}AlInUs}.
+% \end{quoting}
+%
+%
+% \paragraph{Uncertain short vowels}
+% In some printed books, it may happen that more than one short vowel
+% be placed on a consonant in cases where the vocalization is
+% uncertain or ambiguous, like so: \arb[voc]{fa`uaila}. In
+% transliteration, the uncertain vowels go between slashes and are
+% separated by commas: |fa`uaila| \arb[voc]{fa`uaila}
+% \arb[trans]{fa`uaila}.
+%
+% \subsection{Examples}
+% \label{sec:examples-translit}
+% Here follows in transliteration the story of
+% \arb[trans]{\uc{ju.hA}} and his donkey (\arb[voc]{\uc{ju.hA
+% wa-.himAru-hu}}). See the code \vpageref{ref:juha-code}:---
+%
+% \SetTranslitConvention{dmg}
+% \begin{arab}[trans]
+% \LR{\textbf{\emph{\enquote*{dmg}} standard:}} 'at_A .sadIquN 'il_A
+% \uc{ju.hA} ya.tlubu min-hu .himAra-hu li-yarkaba-hu fI safraTiN
+% qa.sIraTiN fa-qAla la-hu: \enquote{sawfa 'u`Idu-hu 'ilay-ka fI
+% 'l-masA'-i wa-'adfa`u la-ka 'ujraTaN.} fa-qAla \uc{ju.hA}:
+% \enquote{'anA 'AsifuN jiddaN 'annI lA 'asta.tI`u 'an 'u.haqqiqa
+% la-ka ra.gbata-ka fa-'l-.himAr-u laysa hunA 'l-yawm-a.} wa-qabla
+% 'an yutimma \uc{ju.hA} kalAma-hu bada'a 'l-.himAr-u yanhaqu fI
+% 'i.s.tabli-hi. fa-qAla la-hu .sadIqu-hu: \enquote{'innI 'asma`u
+% .himAra-ka yA \uc{ju.hA} yanhaqu.} fa-qAla la-hu \uc{ju.hA}:
+% \enquote{.garIbuN 'amru-ka yA .sadIqI 'a-tu.saddiqu 'l-.himAr-a
+% wa-tuka_d_diba-nI?}
+% \end{arab}
+%
+% \SetTranslitConvention{loc}
+% \begin{arab}[trans]
+% \LR{\textbf{\emph{\enquote*{loc}} standard:}} 'at_A .sadIquN 'il_A
+% \uc{ju.hA} ya.tlubu min-hu .himAra-hu li-yarkaba-hu fI safraTiN
+% qa.sIraTiN fa-qAla la-hu: \enquote{sawfa 'u`Idu-hu 'ilay-ka fI
+% 'l-masA'-i wa-'adfa`u la-ka 'ujraTaN.} fa-qAla \uc{ju.hA}:
+% \enquote{'anA 'AsifuN jiddaN 'annI lA 'asta.tI`u 'an 'u.haqqiqa
+% la-ka ra.gbata-ka fa-'l-.himAr-u laysa hunA 'l-yawm-a.} wa-qabla
+% 'an yutimma \uc{ju.hA} kalAma-hu bada'a 'l-.himAr-u yanhaqu fI
+% 'i.s.tabli-hi. fa-qAla la-hu .sadIqu-hu: \enquote{'innI 'asma`u
+% .himAra-ka yA \uc{ju.hA} yanhaqu.} fa-qAla la-hu \uc{ju.hA}:
+% \enquote{.garIbuN 'amru-ka yA .sadIqI 'a-tu.saddiqu 'l-.himAr-a
+% wa-tuka_d_diba-nI?}
+% \end{arab}
+% \SetTranslitConvention{dmg}
+%
+% \SetTranslitConvention{arabica}
+% \begin{arab}[trans]
+% \LR{\textbf{\emph{\enquote*{arabica}} standard:}} 'at_A .sadIquN
+% 'il_A \uc{ju.hA} ya.tlubu min-hu .himAra-hu li-yarkaba-hu fI
+% safraTiN qa.sIraTiN fa-qAla la-hu: \enquote{sawfa 'u`Idu-hu
+% 'ilay-ka fI 'l-masA'-i wa-'adfa`u la-ka 'ujraTaN.} fa-qAla
+% \uc{ju.hA}: \enquote{'anA 'AsifuN jiddaN 'annI lA 'asta.tI`u 'an
+% 'u.haqqiqa la-ka ra.gbata-ka fa-'l-.himAr-u laysa hunA 'l-yawm-a.}
+% wa-qabla 'an yutimma \uc{ju.hA} kalAma-hu bada'a 'l-.himAr-u
+% yanhaqu fI 'i.s.tabli-hi. fa-qAla la-hu .sadIqu-hu: \enquote{'innI
+% 'asma`u .himAra-ka yA \uc{ju.hA} yanhaqu.} fa-qAla la-hu
+% \uc{ju.hA}: \enquote{.garIbuN 'amru-ka yA .sadIqI 'a-tu.saddiqu
+% 'l-.himAr-a wa-tuka_d_diba-nI?}
+% \end{arab}
+% \SetTranslitConvention{dmg}
+%
+% \section{Buckwalter input scheme}
+% \label{sec:buckwalter-scheme}
+% \NEWfeature{v1.4} Even though \package{arabluatex} is primarily
+% designed to process the Arab\TeX\ notation, it can also process the
+% Buckwalter input scheme to a large extent.\footnote{See
+% \url{http://www.qamus.org/transliteration.htm}} The Buckwalter
+% scheme is actually processed in two steps, as it is first converted
+% into Arab\TeX. Then, once this is accomplished, the Arab\TeX\ scheme
+% is processed through the above described functions. In this way, the
+% Buckwalter input scheme can make the most of the
+% \package{arabluatex} special features that are presented in
+% \vref{sec:options}.
+%
+% \DescribeMacro{\SetInputScheme} The input scheme, which is set to
+% |arabtex| by default, may be changed at any point of the document by
+% the \cs{SetInputScheme}\marg{scheme} command, where \meta{scheme}
+% may be either |arabtex| or |buckwalter|. This command is also
+% accepted in the preamble should one wish to set the input scheme
+% globally, like so:---
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \usepackage{arabluatex}
+ \SetInputScheme{buckwalter}
+\end{code}
+% \iffalse
+%</example>
+% \fi
+%
+% \paragraph{\enquote*{base}, \enquote*{\texttt{xml}} and
+% \enquote*{safe} schemes}
+% \package{arabluatex} can use any of the so-called Buckwalter
+% \enquote*{base}, \enquote*{\texttt{xml}} or \enquote*{safe} schemes
+% as they are described in \textcite[25--26]{Habash}.\footnote{I am
+% grateful to Graeme Andrews who suggested that the \enquote*{safe}
+% scheme be included in \package{arabluatex}.} However, the following
+% limitation apply to the \enquote*{base} and \enquote*{\texttt{xml}}
+% schemes: the braces |{| and |}|, which are used to encode
+% \arb[novoc]{"a} and \arb[novoc]{y"'}, must be replaced with square
+% brackets viz. |[| and |]| respectively.
+%
+% It is therefore recommended to use the Buckwalter \enquote*{safe}
+% scheme.
+%
+% \Cref{tab:buckwalter-scheme} gives the Buckwalter equivalents that
+% are currently used by \package{arabluatex}. The additional
+% characters that are defined in \vref{tab:additional-arabic-codings}
+% are also available.
+%
+% \enlargethispage{\baselineskip}
+% \begin{longtable}{llllll}
+% \bottomrule
+% \caption*{\Cref*{tab:buckwalter-scheme}: Buckwalter scheme}
+% \endfoot
+% \captionlistentry{Buckwalter scheme}\\[-1em]
+% \toprule
+% Letter & \multicolumn{3}{l}{Transliteration\footnotemark}
+% & \multicolumn{2}{l}{Buckwalter notation} \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & |base/xml| &
+% |safe| \\ \midrule
+% \endfirsthead
+% \toprule
+% Letter & \multicolumn{3}{l}{Transliteration}
+% & \multicolumn{2}{l}{Buckwalter notation} \\
+% & \texttt{dmg} & \texttt{loc} & \texttt{arabica} & |base/xml| &
+% |safe| \\ \midrule
+% \endhead \footnotetext{See \vref{sec:transliteration}.}
+% \label{tab:buckwalter-scheme}
+% \arb[novoc]{a} & \dmg{a} & \loc{a} & \brill{a} & |A| & |A| \\
+% \pagebreak[1]
+% \arb[novoc]{b} & \dmg{b} & \loc{b} & \brill{b} & |b| & |b| \\
+% \arb[novoc]{t} & \dmg{t} & \loc{t} & \brill{t} & |t| & |t| \\
+% \arb[novoc]{_t} & \dmg{_t} & \loc{_t} & \brill{_t} & |v| & |v| \\
+% \arb[novoc]{j} & \dmg{j} & \loc{j} & \brill{j} & |j| & |j| \\
+% \arb[novoc]{.h} & \dmg{.h} & \loc{.h} & \brill{.h} & |H| & |H| \\
+% \arb[novoc]{x} & \dmg{x} & \loc{x} & \brill{x} & |x| & |x| \\
+% \arb[novoc]{d} & \dmg{d} & \loc{d} & \brill{d} & |d| & |d| \\
+% \arb[novoc]{_d} & \dmg{_d} & \loc{_d} & \brill{_d} & |*| & |V| \\
+% \arb[novoc]{r} & \dmg{r} & \loc{r} & \brill{r} & |r| & |r| \\
+% \arb[novoc]{z} & \dmg{z} & \loc{z} & \brill{z} & |z| & |z| \\
+% \arb[novoc]{s} & \dmg{s} & \loc{s} & \brill{s} & |s| & |s| \\
+% \arb[novoc]{^s} & \dmg{^s} & \loc{^s} & \brill{^s} & |$| & |c| \\
+% \arb[novoc]{.s} & \dmg{.s} & \loc{.s} & \brill{.s} & |S| & |S| \\
+% \arb[novoc]{.d} & \dmg{.d} & \loc{.d} & \brill{.d} & |D| & |D| \\
+% \arb[novoc]{.t} & \dmg{.t} & \loc{.t} & \brill{.t} & |T| & |T| \\
+% \arb[novoc]{.z} & \dmg{.z} & \loc{.z} & \brill{.z} & |Z| & |Z| \\
+% \arb[novoc]{`} & \dmg{`} & \loc{`} & \brill{`} & |E| & |E| \\
+% \arb[novoc]{.g} & \dmg{.g} & \loc{.g} & \brill{.g} & |g| & |g| \\
+% \arb[novoc]{f} & \dmg{f} & \loc{f} & \brill{f} & |f| & |f| \\
+% \arb[novoc]{q} & \dmg{q} & \loc{q} & \brill{q} & |q| & |q| \\
+% \arb[novoc]{k} & \dmg{k} & \loc{k} & \brill{k} & |k| & |k| \\
+% \arb[novoc]{l} & \dmg{l} & \loc{l} & \brill{l} & |l| & |l| \\
+% \arb[novoc]{m} & \dmg{m} & \loc{m} & \brill{m} & |m| & |m| \\
+% \arb[novoc]{n} & \dmg{n} & \loc{n} & \brill{n} & |n| & |n| \\
+% \arb[novoc]{h} & \dmg{h} & \loc{h} & \brill{h} & |h| & |h| \\
+% \arb[novoc]{w} & \dmg{w} & \loc{w} & \brill{w} & |w| & |w| \\
+% \arb[novoc]{y} & \dmg{y} & \loc{y} & \brill{y} & |y| & |y| \\
+% \arb[novoc]{Y} & \dmg{Y} & \loc{Y} & \brill{Y} & |Y| & |Y| \\
+% \arb[novoc]{T} & \dmg{aT} & \loc{aT} & \brill{aT} & |p| & |p| \\
+% \midrule
+% \arb[novoc]{|"'} & \dmg{|"'} & \loc{|"'} & \brill{|"'} & \verb|'| & |C| \\
+% \arb[novoc]{A"'} & \dmg{A"'} & \loc{A"'} & \brill{A"'} & \verb+|+ & |M| \\
+% \arb[novoc]{a"'} & \dmg{a"'} & \loc{a"'} & \brill{a"'} & \verb|>| & |O| \\
+% \arb[novoc]{w"'} & \dmg{w"'} & \loc{w"'} & \brill{w"'} & \verb|&| & |W| \\
+% \arb[novoc]{i"'} & \dmg{i"'} & \loc{i"'} & \brill{i"'} & \verb|<| & |I| \\
+% \arb[novoc]{y"'} & \dmg{y"'} & \loc{y"'} & \brill{y"'} & \verb|]| & |Q| \\
+% \midrule
+% \arb[novoc]{BB} & --- & --- & --- & \verb|~| & |~| \\
+% \arb[novoc]{"a} & ' & ' & --- & |[| & |L| \\
+% \midrule
+% \arb[voc]{Ba} & \dmg{Ba} & \loc{Ba} & \brill{Ba} & \verb|a| & |a| \\
+% \arb[voc]{Bu} & \dmg{Bu} & \loc{Bu} & \brill{Bu} & \verb|u| & |u| \\
+% \arb[voc]{Bi} & \dmg{Bi} & \loc{Bi} & \brill{Bi} & \verb|i| & |i| \\
+% \arb[voc]{BaN} & \dmg{BaN} & \loc{BaN} & \brill{BaN} & \verb|F| & |F| \\
+% \arb[voc]{BuN} & \dmg{BuN} & \loc{BuN} & \brill{BuN} & \verb|N| & |N| \\
+% \arb[voc]{BiN} & \dmg{BiN} & \loc{BiN} & \brill{BiN} & \verb|K| & |K| \\
+% \arb[voc]{B"} & --- & --- & --- & \verb|o| & |o| \\
+% \midrule
+% \arb[novoc]{B_a} & \dmg{B_a} & \loc{B_a} & \brill{B_a} & |`| & |e| \\
+% \midrule
+% \arb[novoc]{--} (\arb[trans]{ta.twIl}) & --- & --- & --- & |_| & |_| \\
+% \end{longtable}
+%
+% \paragraph{Transliteration}
+% The Buckwalter notation can also be transliterated into any accepted
+% romanization standard of Arabic. See above
+% \vref{sec:transliteration} for more information. However, it should
+% be pointed out again that only accurate coding produces accurate
+% transliteration. It is therefore at the very least highly advisable
+% to use the hyphen for tying the definite article and the inseparable
+% particles (viz. prepositions, adverbs and conjunctions) to words,
+% like so:--- \SetInputScheme{buckwalter}
+% \begin{quote}
+% |Al-EaAlamu| \arb{Al-EaAlam-u} \arb[trans]{Al-EaAlam-u},
+% |Al-camsu| \arb{Al-cams-u} \arb[trans]{Al-cams-u},
+% |bi-SinaAEapi| |Al-T~ib~i|, \arb{bi-SinaAEap-i Al-T~ib~-i}
+% \arb[trans]{bi-SinaAEap-i Al-T~ib~-i}.
+%
+% |wa-Al-l~ehi| \arb{wa-Al-l~eh-i} \arb[trans]{wa-Al-l~eh-i},
+% |Al-Hamdu| |li-l~ehi| \arb{Al-Hamd-u li-l~eh-i}
+% \arb[trans]{Al-Hamd-u li-l~eh-i}.
+% \end{quote}
+% \SetInputScheme{arabtex}
+%
+% Similary, it is not advisable to use \verb+|+ and |[|
+% (\enquote*{base} and \enquote*{\texttt{xml}} schemes) or |M| and |L|
+% (\enquote*{safe} scheme) to encode the \arb[trans]{'alif-u
+% 'l-mamdUdaT-i} and the \arb[trans]{'alif-u 'l-wa.sl-i} for such
+% signs are supposed to be generated by \package{arabluatex} internal
+% functions. Besides, as they do not \emph{per se} convey any
+% morphological information on what they are derived from, they cannot
+% be transliterated accurately. To take one example, %
+% \SetInputScheme{buckwalter}%
+% |<ilY Al-LntiqaADi| gives \arb{>ilY Al-LntiqaADi} as expected, but
+% only |<ilY Al-intiqADi| can be transliterated as \arb[trans]{<ilY
+% Al-intiqaADi} with the correct vowel \meta{i} in place of the %
+% \SetInputScheme{arabtex}%
+% \arb[trans]{'alif-u 'l-wa.sl-i}.
+%
+% \section{Unicode Arabic input}
+% \label{sec:unicode-input}
+% \NEWfeature{v1.5} As said above in \vref{sec:buckwalter-scheme}
+% about the Buckwalter input scheme, even though \package{arabluatex}
+% is primarily designed to process the Arab\TeX\ notation, it also
+% accepts Unicode Arabic input. It should be noted that
+% \package{arabluatex} does in no way interfere with Unicode Arabic
+% input: none of the |voc|, |fullvoc|, |novoc| or |trans| options will
+% have any effect on plain Unicode Arabic for the time being.
+%
+% That said, there are two ways of inserting Unicode
+% Arabic:
+% \begin{enumerate}
+% \item \DescribeMacro{\txarb} The \cs{txarb}\marg{Unicode Arabic}
+% command for inserting Unicode Arabic text in paragraphs;
+% \item The \DescribeEnv{txarab} |txarab| environment for inserting
+% running paragraphs of Arabic text, like so:---\\%
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \begin{txarab}
+ <Unicode Arabic text>
+ \end{txarab}
+\end{code}
+% \iffalse
+%</example>
+% \fi
+% \end{enumerate}
+%
+% \needspace{4\baselineskip}
+% \section{\LaTeX\ Commands in Arabic environments}
+% \label{sec:commands-in-arb}
+% \paragraph{General principle} \label{ref:cmd-inside-arabic}\LaTeX\
+% commands are accepted in Arabic environments. The general principle
+% which applies is that any single-argument command with up to
+% \emph{two optional arguments}---that is:
+% \cs{command}\oarg{opt1}\oarg{opt2}\marg{arg}---such as
+% \cs{emph}\marg{text}, \cs{textbf}\marg{text} and the like, is
+% assumed to have Arabic text in its mandatory argument:---
+% \begin{quote}
+% |\abjad{45}| |kitAbu-hu| |\emph{fI| |'l-\uc{`AdAt-i}}|
+% \arb[voc]{\abjad{45} kitAbu-hu \emph{fI 'l-\uc{`AdAt-i}}}
+% \arb[trans]{\abjad{45} kitAbu-hu \emph{fI
+% 'l-\uc{`AdAt-i}}}.\footnote{This is odd in Arabic script, but
+% using such features as \cs{emph} or \cs{textbf} is a matter of
+% personal taste.}
+% \NewDocumentCommand{\rlframebox}{o o m}{
+% \IfNoValueTF{#2}{\IfNoValueTF{#1}{
+% \framebox{\setRL#3}}{\framebox[#1]{\setRL#3}}
+% }{\framebox[#1][#2]{\setRL#3}}}
+%
+% |\arb{\abjad{45} \rlframebox[1in][s]{kitAbu-hu fI 'l-`AdAti}}|\\
+% \arb{\abjad{45} \rlframebox[1in][s]{kitAbu-hu fI
+% 'l-`AdAti}}\,\footnote{\cs{rlframefox} has been adapted from
+% \cs{framebox} for insertions of right-to-left text.}
+% \end{quote}
+%
+% The same applies to footnotes:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \renewcommand{\footnoterule}%
+ {\hfill\noindent\rule[1mm]{.4\textwidth}{.15mm}}
+ \begin{arab}
+ 'inna 'abI kAna mina 'l-muqAtilaT-i\footnote{al-muqAtilaT-i:
+ al-muqAtil-Ina.}, wa-kAnat 'ummI min `u.zamA'-i buyUt-i
+ 'l-zamAzimaT-i\footnote{al-zamAzimaT-u: .tA'ifaT-u mina
+ 'l-furs-i.}.
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% Some commands, however, do not expect running text in their
+% arguments, or one may wish to insert English text e.g. in footnotes
+% or in marginal notes. \package{arabluatex} provides a set of
+% commands to handle such cases.
+%
+% \DescribeMacro{\LR} \cs{LR}\marg{arg} is designed to typeset its
+% argument from left to right. It may be used in an Arabic
+% environment, either \cs{arb}\marg{Arabic text} or \cs{begin}|{arab}|
+% \meta{Arabic text} \cs{end}|{arab}|, for short insertions of
+% left-to-right text, or to insert any \LaTeX\ command that would
+% otherwise be rejected by \package{arabluatex}, such as commands the
+% argument of which is expected to be a dimension or a unit of
+% measurement.
+%
+% \DescribeMacro{\RL} \cs{RL}\marg{arg} does the same as
+% \cs{LR}\marg{arg}, but typesets its argument from right to left. Even
+% in an Arabic environment, this command may be useful.
+%
+% \DescribeMacro{\LRfootnote} \DescribeMacro{\RLfootnote}
+% \cs{LRfootnote}\marg{text} and \cs{RLfootnote}\marg{text} typeset
+% left-to-right and right-to-left footnotes respectively in Arabic
+% environments. Unlike \cs{footnote}\marg{text}, the arguments of both
+% \cs{LRfootnote} and \cs{RLfootnote} are not expected to be Arabic
+% text. For example, \cs{LRfootnote} can be used to insert English
+% footnotes in running Arabic text:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \begin{arab}[fullvoc]
+ \uc{z}ayd-uN\arbnull{ibnu}\LRfootnote{%
+ \enquote{\arb[trans]{\uc{z}ayd} is the son of
+ \arb[trans]{\uc{`a}mr}}: the second noun is not in
+ apposition to the first, but forms part of the
+ predicate\ldots} \arbnull{zayduN}ibn-u \uc{`a}mr-iNU
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% When footnotes are typeset from right to left, it may happen that
+% the numbers of the footnotes that are at the bottom of the page be
+% typeset in the wrong direction. For example, instead of an expected
+% number 18, one may get 81. \package{arabluatex} is not responsible
+% for that, but should it happen, it may be necessary to redefine in
+% the preamble the \LaTeX\ macro \cs{thefootnote} like so:---\\
+% \tcboxverb{\renewcommand*{\thefootnote}{\textsuperscript{\LR{\arabic{footnote}}}}}
+% \DescribeMacro{\FixArbFtnmk} Another solution is to put in the
+% preamble, below the line that loads \package{arabluatex}, the
+% \cs{FixArbFtnmk} command. However, for more control over the layout
+% of footnotes marks, it is advisable to use the \package{scrextend}
+% package.\footnote{See \url{http://ctan.org/pkg/koma-script}; read
+% the documentation of \package{KOMA-script} for details about the
+% \cs{deffootnotemark} and \cs{deffootnote} commands.}
+%
+% \DescribeMacro{\LRmarginpar} The
+% \cs{LRmarginpar}\oarg{left}\marg{right} command does for marginal
+% notes the same as \cs{LRfootnote} does for footnotes. Of course, it
+% is supposed to be used in Arabic environments. Note that
+% \cs{marginpar} also works in Arabic environments, but it acts as any
+% other single-argument command inserted in Arabic environments. The
+% general principle laid \vpageref{ref:cmd-inside-arabic} applies.
+%
+% \label{ref:setrl-setlr}
+% \DescribeMacro{\setRL} \DescribeMacro{\setLR} \cs{setRL} and
+% \cs{setLR} can be used to change the direction of paragraphs, either
+% form left to right or from right to left. As an example, an
+% easy way to typeset a right-to-left sectional title follows:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \setRL
+ \section*{\arb{barzawayhi li-buzurjumihra bn-i 'l-buxtikAni}}
+ \setLR
+ \begin{arab}
+ qAla barzawayhi bn-u 'azhar-a, ra's-u 'a.tibbA'-i fAris-a...
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% \subsection{New commands}
+% \label{sec:declare-new-commands}
+% \NEWfeature{v1.9}%
+% In some particular cases, it may be useful to define new commands to
+% be inserted in Arabic environments. From the general principle laid
+% \vpageref{ref:cmd-inside-arabic}, it follows that any command that
+% is found inside an Arabic environment is assumed to have Arabic text
+% in its argument which \package{arabluatex} will process as such
+% before passing it on to the command itself for any further
+% processing. As a result of this feature, such a command as:\\
+% \tcboxverb{\newcommand{\fvarabic}[1]{\arb[fullvoc]{#1}}}\\
+% will work as expected, but will always output non-vocalized Arabic
+% if it is inserted in a |novoc| Arabic environment because its
+% argument will have been processed by the |novoc| rules before the
+% command |\fvarabic| itself can see it.
+%
+% \DescribeMacro{\MkArbBreak} The \cs{MkArbBreak}\marg{csv list of
+% commands} command can be used in the preamble to give any
+% command---either new or already existing---the precedence over
+% \package{arabluatex} inside Arabic environments. It takes as
+% argument a comma-separated list of commands each of which must be
+% stripped of its leading character
+% |\|, like so:---\\
+% \tcboxverb{\MkArbBreak{onecmd, anothercmd, yetanothercmd, ...}}
+%
+% For example, here follows a way to define a new command |\fvred| to
+% distinguish words with a different color and always print them in
+% fully vocalized Arabic:--- %
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \MkArbBreak{fvred}
+ \newcommand{\fvred}[1]{\arbcolor[red]{\arb[fullvoc]{#1}}}
+ \begin{arab}[voc]
+ _tumma "intalaqa _dU 'l-qarn-ayni 'il_A 'ummaT-iN 'u_hr_A fI
+ \fvred{((ma.tli`-i 'l-^sams-i))} wa-lA binA'-a la-hum
+ yu'amminu-hum mina 'l-^sams-i.
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% It must be noted that the arguments, either optional or mandatory,
+% of commands declared with \cs{MkArbBreak} are not to be processed by
+% \package{arabluatex}. Therefore, as in the previous example, any of
+% their argument to be rendered in Arabic must be inserted again in
+% \cs{arb}. \NEWfeature{v1.12}These commands themselves may have up to
+% two optional and/or mandatory arguments followed by one optional
+% argument, like so:---
+% \begin{enumerate}
+% \item \cs{command} (no argument, lowermost combination)
+% \item \cs{command}\oarg{opt1} (one optional argument)
+% \item \cs{command}\marg{arg1} (one mandatory argument)
+% \item \cs{command}\oarg{opt1}\marg{arg1} (one optional and one
+% mandatory argument)
+% \item{} [\ldots]
+% \item \cs{command}\oarg{opt1}\oarg{opt2}\marg{arg1}\marg{arg2}
+% \item
+% \cs{command}\oarg{opt1}\oarg{opt2}\marg{arg1}\marg{arg2}\oarg{opt3}
+% (uppermost combination)
+% \end{enumerate}
+%
+% \DescribeMacro{\MkArbBreak*}\NEWfeature{v1.12} As said above,
+% \cs{MkArbBreak} prevents \package{arabluatex} from processing the
+% arguments of \enquote*{declared} commands as Arabic text. This
+% technique proves sufficient in most cases. However, a
+% \enquote*{starred} version of this
+% command---\cs{MkArbBreak*}\marg{csv list of commands}---is also
+% provided. It goes a step further, as it directs \package{arabluatex}
+% to \emph{close} the current Arabic environment before any of the
+% \enquote*{declared} commands, then \emph{resume} it just after.
+%
+% \iffalse
+%<*example>
+% \fi
+\begin{tcblisting}{text only}
+ It must be noted that \cs{MkArbBreak*} must be used with the utmost
+ care and \emph{should never be used} if \cs{MkArbBreak} gives
+ satisfaction. At any rate, the latter must always be tested before
+ the former.
+\end{tcblisting}
+% \iffalse
+%</example>
+% \fi%
+%
+% \subsection{Environments}
+% \label{sec:environments}
+% \changes{v1.5}{2016/11/14}{Environments may be nested inside the
+% \texttt{arab} environment}
+% \NEWfeature{v1.5} Environments such as
+% \tcboxverb{\begin{quote} ... \end{quote}} may be nested inside the
+% |arab| environment. Up to one optional argument may be passed to
+% each nested environment, like so:---
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \begin{arab}
+ \begin{<environment>}[<options>]
+ <Arabic text>
+ \end{<environment>}
+ \end{arab}
+\end{code}
+% \iffalse
+%</example>
+% \fi
+%
+% In the following example, the \package{quoting} package is used:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \setquotestyle{arabic}
+ \begin{arab}[fullvoc]
+ kAna \uc{'abU} \uc{'l-hu_dayli} 'ahd_A 'il_A \uc{muwaysiN}
+ dajAjaTaN. wa-kAnat dajAjatu-hu 'llatI 'ahdA-hA dUna mA kAna
+ yuttaxa_du li-\uc{muwaysiN}. wa-l_akinna-hu bi-karami-hi
+ wa-bi-.husni xuluqi-hi 'a.zhara 'l-ta`ajjuba min simani-hA
+ wa-.tIbi la.hmi-hA. wa-kAna <\uc{'abU} \uc{'l-hu_dayli}>
+ yu`rafu bi-'l-'imsAki 'l-^sadIdi. fa-qAla: \enquote{wa-kayfa
+ ra'ayta yA \uc{'abA} \uc{`imrAna} tilka 'l-dajAjaTa?} qAla:
+ \enquote{kAnat `ajabaN mina 'l-`ajabi!} fa-yaqUlu:
+ \begin{quoting}[begintext=\textquotedblright,
+ endtext=\textquotedblleft]
+ wa-tadrI mA jinsu-hA? wa-tadrI mA sinnu-hA? fa-'inna
+ 'l-dajAjaTa 'inna-mA ta.tIbu bi-'l-jinsi wa-'l-sinni.
+ wa-tadrI bi-'ayyi ^say'iN kunnA nusamminu-hA? wa-fI 'ayyi
+ makAniN kunnA na`lifu-hA?
+ \end{quoting}
+ fa-lA yazAlu fI h_a_dA wa-'l-'A_haru ya.d.haku .da.hkaN
+ na`rifu-hu na.hnu wa-lA ya`rifu-hu \uc{'abU} \uc{'l-hu_dayli}.
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% \subsubsection{Lists}
+% \label{sec:lists}
+% Lists environments are also accepted inside the |arab|
+% environment. One may either use any of the three standard list
+% environments, viz. |itemize|, |enumerate| and |description| or use
+% packages that provide additional refinements such as
+% \package{paralist} or \package{enumitem}.
+%
+% To take a first example, should one wish to typeset a list of
+% manuscripts, the |description| environment can be used like so:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \setRL\paragraph{\arb[novoc]{rumUzi 'l-kitAbi}}\setLR
+ \begin{arab}[novoc]
+ \begin{description}
+ \item[b] max.tU.tu 'l-maktabaTi 'l-'ahliyyaTi bi-\uc{bArIs} 2860
+ `arabiyyuN.
+ \item[s] max.tU.tu 'l-maktabaTi 'l-'ahliyyaTi bi-\uc{bArIs} 2859
+ `arabiyyuN.
+ \item[m] max.tU.tu majlisi \arb[novoc]{^sUrAY malY} .tahrAna 521.
+ \end{description}
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% As a second example, the contents of a treatise may be typeset with
+% the standard list environments, like so:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \setRL\centerline{\arb{\textbf{al-qAnUnu fI 'l-.tibbi}}}\setLR
+ \begin{arab}
+ \begin{itemize}
+ \item \textbf{al-fannu 'l-'awwalu} fI .haddi 'l-.tibbi
+ wa-maw.dU`Ati-hi mina 'l-'umUri 'l-.tabI`iyyaTi wa-ya^stamilu
+ `al_A sittaTi ta`AlImiN
+ \begin{itemize}
+ \item \textbf{al-ta`lImu 'l-'awwalu} [wa-huwa fa.slAni]
+ \begin{itemize}
+ \item \textbf{al-fa.slu 'l-'awwalu}
+ \end{itemize}
+ \end{itemize}
+ \end{itemize}
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% \label{ref:abjad-list}
+% As a third example, abjad-numbered lists can be typeset in
+% conjunction with the \package{enumitem} package,\footnote{See the
+% documentation of \package{enumitem} for more details:
+% \url{https://ctan.org/pkg/enumitem}} like so:---
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ % preamble:---
+ \usepackage{enumitem}
+ \newlist{enumabjad}{enumerate}{10}
+ \setlist[enumabjad]{nosep, label={\abjad{\arabic*}}}
+ \usepackage{multicol}
+\end{code}
+\begin{example}
+ From \textcite[i. 29 B--C]{Wright}:--- The derived forms of the
+ triliteral verb are usually reckoned fifteen in number, but the
+ learner may pass over the last four, because (with the exception
+ of the twelfth) they are of very rare occurrence.
+ \RLmulticolcolumns
+ \begin{multicols}{3}
+ \begin{arab}[fullvoc]
+ \begin{enumabjad}
+ \item fa`ala
+ \item fa``ala
+ \item fA`ala
+ \item 'af`ala
+ \item tafa``ala
+ \item tafA`ala
+ \item infa`ala
+ \item ifta`ala
+ \item if`alla
+ \item istaf`ala
+ \item if`Alla
+ \item if`aw`ala
+ \item if`awwala
+ \item if`anlala
+ \item if`anl_A
+ \end{enumabjad}
+ \end{arab}
+ \end{multicols}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% \paragraph{Caveat}
+% The various French definition files of the \package{babel} package
+% viz. |acadian|, |canadien|, |francais|, |frenchb| or |french| all
+% redefine the list environments, which breaks the standard definition
+% file that is used by \package{arabluatex}. Therefore,
+% \package{babel-french} must be loaded with the |StandardLists=true|
+% option, like so:---%
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \usepackage[french]{babel}
+ \frenchsetup{StandardLists=true}
+\end{code}
+% \iffalse
+%</example>
+% \fi%
+% This option will prevent \package{babel-french} from interfering
+% with the layout of the document. Then the \package{paralist} or
+% \package{enumitem} packages can be used to make the lists
+% \enquote*{compact} as \package{babel-french} do.
+%
+% \subsection{\package{csquotes}}
+% \label{sec:csquotes}
+% The recommended way of inserting quotation marks in running Arabic
+% text is to use \package{csquotes}. With the help of the
+% \cs{DeclareQuoteStyle} command, one can define an Arabic style, like
+% so:---
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \usepackage{csquotes}
+ \DeclareQuoteStyle{arabic}
+ {\textquotedblright}{\textquotedblleft}
+ {\textquoteright}{\textquoteleft}
+\end{code}
+% \iffalse
+%</example>
+% \fi
+% Then, use this newly defined style with \cs{setquotestyle}, like so:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \setquotestyle{arabic}
+ \begin{arab}
+ fa-qAla la-hu ju.hA: \enquote{.garIb-uN 'amru-ka yA .sadIqI
+ 'a-tu.saddiqu 'l-.himAr-a wa-tuka_d_diba-nI?}
+ \end{arab}
+ \setquotestyle{english}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+% \begin{quoting}
+% \textsc{Rem.} Do not forget to set back the quoting style to its
+% initial state once the Arabic environment is closed. See the last
+% line in the code above.
+% \end{quoting}
+%
+% \subsection{Two-argument special commands}
+% \label{sec:two-arg-cmds}
+%
+% \paragraph{textcolor}
+% \label{sec:textcolor}
+% The two-argument command \cs{textcolor}\marg{color}\marg{Ara\-bic
+% text} is supported inside \cs{begin}|{arab}| \ldots\
+% \cs{end}|{arab}|. One simple example
+% follows:\footnote{\package{arabluatex} provides its own
+% \cs{arbcolor} command which is able to render syllabes or diacritics
+% in colors. See \vref{sec:color}.}--- %
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \begin{arab}
+ \textcolor{red}{\uc{m}uha_d_dabu \uc{'l-d}Ini \uc{`a}bdu
+ \uc{'l-r}a.hImi bnu \uc{`a}liyyiN} huwa ^say_hu-nA 'l-'imAmu
+ 'l-.sadru 'l-kabIru 'l-`Alimu 'l-fA.dilu \uc{m}uha_d_dabu
+ \uc{'l-d}Ini \uc{'a}bU \uc{m}u.hammadiN \uc{`a}bdu
+ \uc{'l-r}a.hImi bnu \uc{`a}liyyi bni \uc{.h}AmidiN wa-yu`rafu
+ bi-\uc{'l-d}a_hwari.
+ \end{arab}
+ \begin{arab}[trans]
+ \textcolor{red}{\uc{m}uha_d_dabu \uc{'l-d}Ini \uc{`a}bdu
+ \uc{'l-r}a.hImi bnu \uc{`a}liyyiN} huwa ^say_hu-nA 'l-'imAmu
+ 'l-.sadru 'l-kabIru 'l-`Alimu 'l-fA.dilu \uc{m}uha_d_dabu
+ \uc{'l-d}Ini \uc{'a}bU \uc{m}u.hammadiN \uc{`a}bdu
+ \uc{'l-r}a.hImi bnu \uc{`a}liyyi bni \uc{.h}AmidiN wa-yu`rafu
+ bi-\uc{'l-d}a_hwari.
+ \end{arab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% \paragraph{\package{reledmac}}
+% \label{sec:reledmac}
+% The two-argument command \cs{edtext}\marg{lemma}\marg{commands} is
+% supported inside \cs{begin}|{arab}| \ldots\
+% \cs{end}|{arab}|.\footnote{\cs{pstart} and \cs{pend} are also
+% supported inside the |arab| environment.} As an example, one may get
+% \package{arabluatex} and \package{reledmac} to work together like
+% so:--- %
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \beginnumbering
+ \pstart
+ \begin{arab}
+ wa-ya.sIru ta.hta 'l-jild-i
+ \edtext{\arb{.sadId-uN}}{\Afootnote{M: \arb{.sadId-aN} E1}}
+ \end{arab}
+ \pend
+ \endnumbering
+\end{code}
+% \iffalse
+%</example>
+% \fi
+%
+% \subsection{\package{quran}}
+% \label{sec:pkg-quran}
+% \changes{v1.5}{2016/11/14}{Compatibility with the \textsf{quran}
+% package} \package{arabluatex} is compatible with the \package{quran}
+% package so that both can be used in conjunction with one another for
+% typesetting the \arb[trans]{\uc{qur'An}}. As \package{quran} draws
+% the text of the \arb[trans]{\uc{qur'An}} from a Unicode encoded
+% database, its commands have to be passed as arguments to the
+% \cs{txarb} command for short insertions in left-to-right paragraphs,
+% or inserted inside the \index{txarab=txarab (environment)}|txarab|
+% environment for typesetting running paragraphs of
+% \arb[trans]{\uc{qur'An}}\emph{ic} text (see above
+% \vref{sec:unicode-input} for more details). Please note that
+% \package{arabluatex} takes care of formatting the Arabic: therefore,
+% it is recommended to load the \package{quran} package with the
+% |nopar| option, after \package{arabluatex} itself has been loaded,
+% like so:--- %
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \usepackage{arabluatex}
+ \usepackage[nopar]{quran}
+\end{code}
+% \iffalse
+%</example>
+% \fi
+%
+% As an example, the following code will typeset the \arb[trans]{sUraT
+% al-\uc{fAti.haT}}:---
+% \iffalse
+%<*example>
+% \fi
+\begin{example}
+ \begin{txarab}
+ \quransurah[1]
+ \end{txarab}
+\end{example}
+% \iffalse
+%</example>
+% \fi
+%
+% \section{Exporting Unicode Arabic to an external file}
+% \label{sec:arabtex2utf}
+% \NEWfeature{v.1.13}\package{arabluatex} is able to produce a
+% duplicate of the original |.tex| source file in which all |arabtex|
+% or |buckwalter| strings will have been replaced with Unicode
+% equivalents, either in Arabic script or in any accepted standard of
+% transliteration. Exporting \textsc{ascii} strings to Unicode while
+% preserving the exact selected global or local options is a fairly
+% complex operation which may require {\LuaLaTeX} to be run several
+% times as will be explained below.
+%
+% \subsection{Commands and environments}
+% \paragraph{\texttt{export} global option}
+% \DescribeOption{export} First, \package{arabluatex} must be loaded
+% with the |export| global option enabled,\footnote{See above
+% \vpageref{ref:export-global-opt} for more information.} like
+% so:--- %
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ % preamble
+ \usepackage[export]{arabluatex}
+ % or:
+ \usepackage[export=true]{arabluatex}
+\end{code}
+% \iffalse
+%</example>
+% \fi
+%
+% Once that is done, compiling the current file will produce a new
+% empty external |.tex| file with the same preamble as the original
+% file.
+%
+% \DescribeMacro{\SetArbOutSuffix} By default, |_out| is appended as a
+% suffix to the external file name. Any other suffix may be set with
+% the command \cs{SetArbOutSuffix}\marg{suffix}.
+%
+% \paragraph{Exporting running paragraphs}
+% \DescribeEnv{arabexport} Then, the |arabexport| environment is
+% provided to actually exporting running paragraphs with or without
+% Arabic environments to the external selected file, like so:--- %
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ \begin{arabexport}
+ <Running paragraphs of either Arabic or non-Arabic text>
+ \end{arabexport}
+\end{code}
+% \iffalse
+%</example>
+% \fi
+%
+% \package{arabluatex} converts to Unicode and writes to the external
+% file what is found inside Arabic environments. As to non-Arabic
+% text, it is appended untouched to this file, which is formatted as
+% follows:---
+% \begin{enumerate}
+% \item Unicode Arabic text, either in Arabic script or in
+% transliteration, is inserted as argument of
+% \cs{txarb}\footnote{See above \vref{sec:unicode-input}.} or
+% \cs{txtrans}\footnote{\cs{txtrans} is used internally by several
+% Lua functions to format transliterated Arabic. Therefore, it is
+% not documented.} accordingly.
+% \item \DescribeMacro{\arbpardir}Additionally, Arabic paragraphs may
+% receive \cs{arbpardir}, which \package{arabluatex} uses to
+% determine the direction of Arabic paragraphs to be set by default,
+% or either \cs{setRL} or \cs{setLR} depending on what may have been
+% set locally.\footnote{See above \vpageref{ref:setrl-setlr}.}
+% \item \DescribeMacro{\prname*}Proper names are inserted as arguments
+% of \cs{prname*}.\footnote{See above \vpageref{ref:prname-star}.}
+% \end{enumerate}
+%
+% \paragraph{Appending words or commands to the external file only}
+% \DescribeMacro{\ArbOutFile}\DescribeMacro{\ArbOutFile*}
+% \cs{ArbOutFile}\oarg{newline}\allowbreak\marg{argument} silently
+% exports its argument to the external file. It may take the string
+% |newline| as an optional argument, in which case a carriage return
+% is appended to the contents of the
+% argument. \cs{ArbOutFile*}\oarg{newline}\marg{argument} does the
+% same as \cs{ArbOutFile}, but also inserts its argument into the
+% current |.tex| source file.
+%
+% \paragraph{Exporting Arabic poetry}
+% Lines of Arabic poetry are exported as described above
+% \vpageref{ref:poetry-export} when the |export| option that is
+% specific to the |arabverse| environment is set to |true|. As a
+% result of this particular feature, |arabverse| environments must be
+% left outside |\begin{arabexport}| \ldots\ |\end{arabexport}|.
+%
+% Please note that inside |arabverse| environments \cs{bayt} is
+% replaced with \cs{bayt*}.\footnote{See above \vref{ref:bayt-star} for
+% more information.}
+%
+% \subsection{Nested Arabic environments}
+% The exporting mechanism described above converts only the outermost
+% level of nested Arabic environments. This may be sufficient in some
+% cases, but if nested Arabic environments be found in the original
+% |.tex| source file, then the Unicode converted file must be opened
+% and compiled in turn, and so on until the innermost Arabic
+% environment be converted and exported. In such cases,
+% \package{arabluatex} issues a warning, so that authors do not have
+% to check the entire file that just has been exported:--- %
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ Package arabluatex Warning: There are still 'arabtex' strings
+ to be converted. Please open <jobname><suffix>.tex and compile
+ it one more time.
+\end{code}
+% \iffalse
+%</example>
+% \fi
+% Where \meta{jobname} is the name of the original |.tex| source file,
+% and \meta{suffix} the suffix appended to the file that is to be
+% opened and compiled again.
+%
+% \subsection{Further processing of Unicode converted files}
+% \label{sec:further-processing-utf-files}
+% Unicode files can be further processed by document converters such
+% as John McFarlane's |pandoc|\footnote{See
+% \url{http://pandoc.org/}}. To take here one simple example, here is
+% how |file_out.tex| can be converted from {\LuaLaTeX} into Open
+% Document format (|.odt|):---%
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ pandoc file_out.tex -s -o file_out.odt
+\end{code}
+% \iffalse
+%</example>
+% \fi
+%
+% However, specific commands such as \cs{txarb}, \cs{txtrans} or
+% \cs{prname*}, which are not known to |pandoc|, must be redefined
+% explicitly in the preamble to prevent the converter from gobbling
+% their arguments, like so:---%
+% \iffalse
+%<*example>
+% \fi
+\begin{code}
+ % preamble:
+ \usepackage{arabluatex} % note that 'export' has been removed
+ \renewcommand{\txarb}[1]{#1}
+ \renewcommand{\txtrans}[1]{\emph{#1}}
+ \renewcommand{\arbup}[1]{\textsuperscript{#1}}
+ % now that \prname{} has been replaced with \prname*{} it should
+ % be safe to say:
+ \renewcommand{\prname}[2]{#2}
+ % &c
+\end{code}
+% \iffalse
+%</example>
+% \fi
+%
+% \section{Future work}
+% \label{sec:future-work}
+% A short, uncommented, list of what is planned in the versions of
+% \package{arabluatex} to come follows:
+% \begin{enumerate}
+% \item Short-term:
+% \begin{enumerate}
+% \item \texttt{TEI xml} support: \package{arabluatex} will
+% interoperate with \texttt{TEI xml} through new global and local
+% options that will output Arabic in a \texttt{TEI xml} compliant
+% file in addition to the usual PDF output: see
+% \vpageref{ref:tei-to-come}.
+% \end{enumerate}
+% \item Medium-term:
+% \begin{enumerate}
+% \item More languages: the list of supported languages will
+% eventually be the same as \package{arabtex}: see
+% \vref{fn:arabtex-languages}.
+% \item Formulate propositions for extending the Arab\TeX\ notation
+% and the transliteration tables. Include them in
+% \package{arabluatex}. See \vref{sec:additional-characters}.
+% \end{enumerate}
+% \end{enumerate}
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \iffalse
+%<*package>
+% \fi
+%
+% The most important part of \package{arabluatex} relies on Lua
+% functions and tables. Read the |.lua| files that accompany
+% \package{arabluatex} for more information.
+% \begin{macrocode}
+\RequirePackage{ifluatex}
+% \end{macrocode}
+% \package{arabluatex} requires {\LuaLaTeX} of course. Issue a warning
+% if the document is processed with another engine.
+% \begin{macrocode}
+\ifluatex\else
+ \PackageError{arabluatex}{lualatex needed}{%
+ Package `arabluatex' needs LuaTeX.\MessageBreak
+ So you should use `lualatex' to process your document.\MessageBreak
+ See documentation of `arabluatex' for further information.}%
+ \expandafter\expandafter\expandafter\csname endinput\endcsname
+\fi
+% \end{macrocode}
+% Declare the global options, and define them:
+% \begin{macrocode}
+\RequirePackage{xkeyval}
+\DeclareOptionX{voc}{\def\al@mode{voc}}
+\DeclareOptionX{fullvoc}{\def\al@mode{fullvoc}}
+\DeclareOptionX{novoc}{\def\al@mode{novoc}}
+\DeclareOptionX{trans}{\def\al@mode{trans}}
+\define@boolkey{arabluatex.sty}[@pkg@]{export}[true]{%
+ \if@pkg@export%
+ \AtBeginDocument{\luadirect{arabluatex.openstream()}%
+ \MkArbBreak{@al@ob,@al@cb,@al@cb@sp}}
+ \AtEndDocument{\luadirect{arabluatex.closestream()}}
+ \else\fi}
+\ExecuteOptionsX{voc}
+\ProcessOptionsX\relax
+\def\al@mode@voc{voc}
+\def\al@mode@fullvoc{fullvoc}
+\def\al@mode@novoc{novoc}
+\def\al@mode@trans{trans}
+% \end{macrocode}
+% Packages that are required by \package{arabluatex}:
+% \begin{macrocode}
+\RequirePackage{xcolor}
+\RequirePackage{luacolor}
+\RequirePackage{etoolbox}
+\RequirePackage{arabluatex-patch}
+\RequirePackage{fontspec}
+\RequirePackage{luacode}
+\RequirePackage{xparse}
+\RequirePackage{adjustbox}
+\RequirePackage{xstring}
+\PassOptionsToPackage{normalem}{ulem}
+\RequirePackage{ulem}
+% \end{macrocode}
+% The following boolean will be set to |true| in |RL| mode:
+% \begin{macrocode}
+\providebool{al@rlmode}
+% \end{macrocode}
+% Here begins the real work: load |arabluatex.lua|:
+% \begin{macrocode}
+\luadirect{dofile(kpse.find_file("arabluatex.lua"))}
+% \end{macrocode}
+% Font setup. If no Arabic font is selected, issue a warning message
+% and attempt to load the Amiri font which is included in \TeX{}live:
+% \begin{macrocode}
+\AtBeginDocument{\ifdefined\arabicfont\relax\else
+\PackageWarning{arabluatex}{\string\arabicfont\ is not defined.^^J
+ I will try to load Amiri}%
+\newfontfamily\arabicfont[Script=Arabic]{Amiri}\fi}%
+% \end{macrocode}
+% \begin{macro}{\setRL}
+% This neutralizes what may be defined by other packages:
+% \begin{macrocode}
+\AtBeginDocument{\def\setRL{\booltrue{al@rlmode}\pardir TRT%
+ \textdir TRT}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\setLR}
+% The same applies to \cs{setLR}:
+% \begin{macrocode}
+\AtBeginDocument{\def\setLR{\boolfalse{al@rlmode}\pardir TLT%
+ \textdir TLT}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\LR} This command typesets its argument from left to
+% right. As \cs{LR} may be already defined, we need to redefine for
+% it to suit our purpose:
+% \begin{macrocode}
+\AtBeginDocument{\ifdef{\LR}%
+ {\RenewDocumentCommand{\LR}{m}{\bgroup\textdir TLT\rmfamily#1\egroup}}
+ {\NewDocumentCommand{\LR}{m}{\bgroup\textdir TLT\rmfamily#1\egroup}}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\RL} This one typesets its argument from right to
+% left. Same remark as above regarding the need of redefinition.
+% \begin{macrocode}
+\AtBeginDocument{\ifdef{\RL}%
+ {\RenewDocumentCommand{\RL}{m}{\bgroup\textdir TRT\rmfamily#1\egroup}}
+ {\NewDocumentCommand{\RL}{m}{\bgroup\textdir TRT#1\rmfamily\egroup}}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\MkArbBreak}
+% \changes{v1.9}{2017/07/05}{New \cs{MkArbBreak} command for
+% inserting user-defined macros in Arabic environments} The
+% \cs{MkArbBreak}\marg{csv list of commands} command can be used to
+% give any command---either new or already existing---the precedence
+% over \package{arabluatex} inside Arabic environments. It is
+% actually coded in Lua.
+% \begin{macro}{\MkArbBreak*}
+% \changes{v1.12}{2018/06/24}{\enquote*{starred} version which
+% closes Arabic environments before processing declared commands.}
+% \cs{MkArbBreak*} goes a step further as it directs
+% \package{arabluatex} to close the current Arabic environment before
+% processing any \enquote*{declared} command then resume it just
+% after.
+% \begin{macrocode}
+\NewDocumentCommand{\MkArbBreak}{s m}{%
+ \IfBooleanTF{#1}
+ {\luadirect{arabluatex.mkarbbreak(\luastringN{#2}, "out")}}
+ {\luadirect{arabluatex.mkarbbreak(\luastringN{#2}, "dflt")}}
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\aemph} Arabic emphasis. Needs to be redefined as
+% well. The function is actually coded in Lua.
+% \changes{v1.16}{2018/11/06}{Now uses \textsf{ulem}}
+% \begin{macro}{\aemph*} The \enquote*{starred} version of this
+% command alway puts the stroke over its argument.
+% \changes{v1.9.2}{2017/10/24}{Starred version which always puts the
+% stroke over its argument}As of v1.16 \package{arabluatex} uses
+% \package{ulem} to render the strokes, thus allowing line breaks
+% and manual hyphenation for transliterated Arabic.
+% \begin{macrocode}
+\def\oline{\@ifstar\@oline\@@oline}
+\def\@oline#1{\ensuremath{\overline{\mbox{#1}}}}
+\def\@@oline{\bgroup \ULdepth=-3ex \ULset}
+\AtBeginDocument{\ifdef{\aemph}%
+ {\RenewDocumentCommand{\aemph}{s m}{%
+ \IfBooleanTF{#1}{%
+ \luadirect{tex.sprint(arabluatex.aemph(\luastringN{#2},
+ "over"))}}
+ {\luadirect{tex.sprint(arabluatex.aemph(\luastringN{#2},
+ "dflt"))}}}}
+ {\NewDocumentCommand{\aemph}{s m}{%
+ \IfBooleanTF{#1}{%
+ \luadirect{tex.sprint(arabluatex.aemph(\luastringN{#2},
+ "over"))}}
+ {\luadirect{tex.sprint(arabluatex.aemph(\luastringN{#2},
+ "dflt"))}}}}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\arbcolor}\changes{v1.12}{2018/06/24}{Standard color
+% command for Arabic environments}
+% \cs{arbcolor}\oarg{color}\marg{Arabic text} takes the Arabic text to
+% be colored as argument.
+% \begin{macrocode}
+\NewDocumentCommand{\arbcolor}{o m}{%
+ \IfNoValueTF{#1}{#2}{\textcolor{#1}{#2}}}
+% \end{macrocode}
+%
+% \end{macro}
+% \begin{macro}{\SetInputScheme}
+% \changes{v1.4}{2016/07/05}{\cs{SetInputScheme} can be used to
+% process other input schemes such as \enquote*{Buckwalter}}
+% \package{arabluatex} is designed for processing Arab\TeX\ input
+% notation. \cs{SetInputScheme} may be used in the preamble or at
+% any point of the document should the user wish to use a different
+% notation such as the \enquote*{Buckwalter scheme}.
+% \begin{macrocode}
+\def\al@input@scheme{arabtex}
+\NewDocumentCommand{\SetInputScheme}{m}{\def\al@input@scheme{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\SetArbEasy}
+% \changes{v1.2}{2016/05/09}{New \cs{SetArbEasy}/\cs{SetArbDflt} for
+% \enquote*{modern} or \enquote*{classic} Arabic styles.}
+% \begin{macro}{\SetArbEasy*}
+% \changes{v1.4.4}{2016/09/28}{this starred version discards the
+% \arb[trans]{sukUn} in addition to what is already discarded by
+% \cs{SetArbEasy}.}
+% \begin{macro}{\SetArbDflt}
+% By default, \package{arabluatex} applies complex rules to generate
+% euphonic \arb[trans]{ta^sdId}, \arb[trans]{'alif mamdUdaT} and
+% \arb[trans]{sukUn} depending on the modes which are selected,
+% either |voc|, |fullvoc| or |trans|. Such refinements can be
+% discarded with \cs{SetArbEasy}, either globally in the preamble or
+% at any point of the document. Note that \cs{SetArbEasy} keeps the
+% \arb[trans]{sukUn} that is generated, while the starred version
+% \cs{SetArbEasy*} takes it away. Default complex rules can be set
+% back at any point of the document with \cs{SetArbDflt}.
+% \begin{macro}{\SetArbDflt*}
+% \changes{v1.6}{2016/12/17}{This starred version applies the
+% assimilation rules in addition to what \cs{SetArbDflt} already
+% does.} As of v1.6, \package{arabluatex} does not applies any more
+% the assimilation rules that are laid on \vref{ref:assimilation}; a
+% new starred version \cs{SetArbDflt*} is now available to the user
+% should he wish to apply them.
+% \begin{macrocode}
+\def\al@arb@rules{dflt}
+\NewDocumentCommand{\SetArbEasy}{s}{%
+ \IfBooleanTF{#1}
+ {\def\al@arb@rules{easynosukun}}
+ {\def\al@arb@rules{easy}}}
+\NewDocumentCommand{\SetArbDflt}{s}{%
+ \IfBooleanTF{#1}
+ {\def\al@arb@rules{idgham}}
+ {\def\al@arb@rules{dflt}}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\SetTranslitFont}
+% \changes{v1.4}{2016/07/05}{For selecting a specific font for
+% transliterated texts} By default, the font that is used for
+% transliterated text is the main font of the document. Any other
+% font may also be selected with the font-selecting commands of the
+% \package{fontspec} package.
+% \begin{macrocode}
+\def\al@trans@font{\rmfamily}%
+\NewDocumentCommand{\SetTranslitFont}{m}{\def\al@trans@font{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\SetTranslitStyle} By default any transliterated
+% Arabic text is printed in italics. This can be changed either
+% globally in the preamble or at any point of the document:
+% \begin{macrocode}
+\def\al@trans@style{\itshape}%
+\NewDocumentCommand{\SetTranslitStyle}{m}{\def\al@trans@style{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\SetTranslitConvention}
+% \cs{SetTranslitConvention}\marg{convention} can be used to change
+% the transliteration convention, which is |dmg| by default:
+% \begin{macrocode}
+\def\al@trans@convention{dmg}
+\NewDocumentCommand{\SetTranslitConvention}{m}{%
+ \def\al@trans@convention{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\arbup}
+% \changes{v1.3}{2016/05/28}{\arb[trans]{'i`rAb} is now written as
+% superscript text in \texttt{dmg} mode by default.}
+% \begin{macro}{\NoArbUp}
+% \begin{macro}{\ArbUpDflt}
+% \begin{macro}{\SetArbUp}
+% By default, \cs{arbup} is set to \cs{textsuperscript}. This is how
+% the \arb[trans]{tanwIn} that takes place at the end of a word
+% should be displayed in |dmg| mode. \cs{NoArbUp} may be used
+% either in the preamble or at any point of the document in case one
+% wishes to have the \arb[trans]{tanwIn} on the line. The default
+% rule can be set back with \cs{ArbUpDflt} at any point of the
+% document. Finally \cs{SetArbUp} can be used to customize the way
+% \arb[trans]{tanwIn} is displayed: this command takes the
+% formatting directives as argument, like so:
+% \cs{SetArbUp}\marg{code}.
+% \begin{macrocode}
+\NewDocumentCommand{\al@arbup@dflt}{m}{\textsuperscript{#1}}%
+\NewDocumentCommand{\al@arbup}{m}{\al@arbup@dflt{#1}}
+\NewDocumentCommand{\arbup}{m}{\al@arbup{#1}}
+\NewDocumentCommand{\ArbUpDflt}{}{\let\al@arbup=\al@arbup@dflt}
+\NewDocumentCommand{\NoArbUp}{}{\RenewDocumentCommand{\al@arbup}{m}{##1}}
+\NewDocumentCommand{\SetArbUp}{m}{%
+ \RenewDocumentCommand{\al@arbup}{m}{#1}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\uc} Proper Arabic names or book titles should be
+% passed to the \cs{uc} command so that they have their first letters
+% uppercased. \cs{uc} is actually coded in Lua.
+% \begin{macrocode}
+\NewDocumentCommand{\uc}{m}%
+ {\luadirect{tex.sprint(arabluatex.uc(\luastringN{#1}))}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\Uc} \cs{uc} can be used safely in all of the modes
+% that are provided by \package{arabluatex} as any of the |voc|,
+% |fullvoc| and |novoc| modes discard it on top of any other
+% functions to be run. \cs{Uc} does the same as \cs{uc} except
+% that \emph{it is never discarded}. For that reason, \cs{Uc}
+% \emph{should never be used outside the} |trans|
+% \emph{mode}. \package{arabluatex} uses \cs{Uc} internally so as
+% to prevent \cs{uc} from being discarded in case words that are to
+% be transliterated are inserted into Arabic commands or
+% environments where transliteration is not required. Therefore, it
+% is not documented.
+% \begin{macrocode}
+\let\Uc\uc
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\prname}\changes{v1.10}{2018/01/03}{New command for
+% typesetting Arabic proper names in transliteration} \cs{prname} is
+% to be used outside Arabic environments for proper names. It takes as
+% argument one or more Arabic words, each of which will be rendered in
+% upright roman style with its first letter uppercased.
+% \begin{macro}{\prname*}\changes{v1.13}{2018/08/27}{Renders proper
+% names already converted to Unicode in upright roman style}
+% Unlike \cs{prname}, \cs{prname*} does not take |arabtex| or
+% |buckwalter| input as argument, but already Unicode converted
+% names and renders them in upright roman style.
+% \begin{macrocode}
+\NewDocumentCommand{\prname}{s m}{%
+ \bgroup\SetTranslitStyle{\relax}%
+ \IfBooleanTF{#1}{\txtrans{#2}}{\arb[trans]{\uc{#2}}}\egroup}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\txarb} \cs{txarb} sets the direction to right-to-left
+% and selects the Arabic font. It is used internally by several Lua
+% functions, but available to the user should he wish to insert
+% |utf8| Arabic text in his document.
+% \begin{macro}{\txtrans} \cs{txtrans} is used internally by several
+% Lua functions to insert transliterated Arabic text. Therefore, it is
+% not documented.
+% \begin{macrocode}
+\NewDocumentCommand{\txarb}{+m}{%
+ \bgroup\textdir TRT\arabicfont#1\egroup}
+\NewDocumentCommand{\txtrans}{+m}{%
+ \bgroup\textdir TLT\al@trans@font\al@trans@style#1\egroup}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{environment}{txarab}
+% \changes{v1.5}{2016/11/14}{New \texttt{txarab} environment for
+% typesetting running paragraphs in Unicode Arabic} The |txarab|
+% environment does for paragraphs the same as \cs{txarb} does for
+% short insertions of |utf8| Arabic text.
+% \begin{macrocode}
+\NewDocumentEnvironment{txarab}{}{%
+ \par%
+ \booltrue{al@rlmode}%
+ \pardir TRT\textdir TRT\arabicfont}{\par}
+% \end{macrocode}
+% \end{environment}
+% \begin{macro}{\arb}
+% The \cs{arb} command detects which Arabic mode is to be used,
+% either globally if no option is set, or locally, then passes its
+% argument to the appropriate Lua function.
+% \begin{macrocode}
+\NewDocumentCommand{\arb}{O{\al@mode} +m}%
+{\edef\@tempa{#1}%
+ \ifx\@tempa\al@mode@voc%
+ \bgroup\booltrue{al@rlmode}\textdir TRT\arabicfont%
+ \luadirect{tex.sprint(arabluatex.processvoc(\luastringN{#2},
+ \luastringO{\al@arb@rules}, \luastringO{\al@input@scheme}))}\egroup%
+ \else%
+ \ifx\@tempa\al@mode@fullvoc%
+ \bgroup\booltrue{al@rlmode}\textdir TRT\arabicfont%
+ \luadirect{tex.sprint(arabluatex.processfullvoc(\luastringN{#2},
+ \luastringO{\al@arb@rules}, \luastringO{\al@input@scheme}))}\egroup%
+ \else%
+ \ifx\@tempa\al@mode@novoc%
+ \bgroup\booltrue{al@rlmode}\textdir TRT\arabicfont%
+ \luadirect{tex.sprint(arabluatex.processnovoc(\luastringN{#2},
+ \luastringO{\al@arb@rules}, \luastringO{\al@input@scheme}))}\egroup%
+ \else%
+ \ifx\@tempa\al@mode@trans%
+ \bgroup\textdir TLT\al@trans@font\al@trans@style%
+ \luadirect{tex.sprint(arabluatex.processtrans(\luastringN{#2},
+ \luastringO{\al@trans@convention},
+ \luastringO{\al@arb@rules},
+ \luastringO{\al@input@scheme}))}\egroup%
+ \else%
+ \fi\fi\fi\fi}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\arbmark}
+% \changes{v1.11}{2018/03/31}{New command for inserting additional
+% marks in Arabic environments}
+% \cs{arbmark}\oarg{rl\textbar{}lr}\marg{shorthand} takes one
+% argument from a list of defined elements.
+% \changes{v1.13}{2018/08/27}{New optional argument: either
+% \texttt{rl} or \texttt{lr}} The mark to be inserted is determined
+% by contextual analysis or by an optional argument, either |rl| or
+% |lr|. This command is coded in Lua.
+% \begin{macrocode}
+\NewDocumentCommand{\arbmark}{O{} m}{%
+ \bgroup%
+ \SetInputScheme{arabtex}%
+ \luadirect{tex.sprint(arabluatex.processarbmarks(\luastringN{#2},
+ \luastringN{#1}))}%
+ \egroup}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\newarbmark}
+% \changes{v1.11}{2018/03/31}{Allows defining additional sets of Arabic
+% marks} \cs{newarbmark} lets the user define additional Arabic
+% marks. As \cs{arbmark}, this command is coded in Lua. It takes
+% three arguments: the abbreviated form to be used as argument of
+% \cs{arbmark}, the rendition in Arabic script and the rendition in
+% romanized Arabic.
+% \begin{macrocode}
+\NewDocumentCommand{\newarbmark}{m m m}{%
+ \luadirect{arabluatex.newarbmark(\luastringN{#1}, \luastringN{#2},
+ \luastringN{#3})}}
+% \end{macrocode}
+% \end{macro}
+% \begin{environment}{arab}
+% The |arab| environment does for paragraphs the same as \cs{arb} does
+% for short insertions of Arabic text.
+% \begin{macrocode}
+\NewDocumentEnvironment{arab}{O{\al@mode} +b}%
+{\par\edef\@tempa{#1}%
+ \ifx\@tempa\al@mode@voc%
+ \booltrue{al@rlmode}%
+ \bgroup\pardir TRT\textdir TRT\arabicfont%
+ \luadirect{tex.sprint(arabluatex.processvoc(\luastringN{#2},
+ \luastringO{\al@arb@rules}, \luastringO{\al@input@scheme}))}\egroup%
+ \else%
+ \ifx\@tempa\al@mode@fullvoc%
+ \booltrue{al@rlmode}%
+ \bgroup\pardir TRT\textdir TRT\arabicfont%
+ \luadirect{tex.sprint(arabluatex.processfullvoc(\luastringN{#2},
+ \luastringO{\al@arb@rules}, \luastringO{\al@input@scheme}))}\egroup%
+ \else%
+ \ifx\@tempa\al@mode@novoc%
+ \booltrue{al@rlmode}%
+ \bgroup\pardir TRT\textdir TRT\arabicfont%
+ \luadirect{tex.sprint(arabluatex.processnovoc(\luastringN{#2},
+ \luastringO{\al@arb@rules}, \luastringO{\al@input@scheme}))}\egroup%
+ \else%
+ \ifx\@tempa\al@mode@trans%
+ \bgroup\pardir TLT\textdir TLT\al@trans@font\al@trans@style%
+ \luadirect{tex.sprint(arabluatex.processtrans(\luastringN{#2},
+ \luastringO{\al@trans@convention},
+ \luastringO{\al@arb@rules},
+ \luastringO{\al@input@scheme}))}\egroup%
+ \else \fi\fi\fi\fi}{\par}
+% \end{macrocode}
+% \end{environment}
+% \begin{environment}{arabverse}
+% \changes{v1.6}{2016/12/17}{New environment \texttt{arabverse} for
+% typesetting Arabic poetry} The |arabverse| environment may receive
+% different options: |mode|, |width|, |gutter|, |metre|, |color|,
+% |utf|, |delim| and |export|; all of them are defined here just
+% before the |arabverse|
+% environment. \changes{v1.13}{2018/08/27}{New options
+% \texttt{color} and \texttt{export} to \texttt{arabverse}
+% environment.}
+% \begin{macrocode}
+\newlength{\al@bayt@width}
+\newlength{\al@gutter@width}
+\setlength{\al@bayt@width}{.3\textwidth}
+\setlength{\al@gutter@width}{.15\al@bayt@width}
+\define@key[al]{verse}{width}{\setlength{\al@bayt@width}{#1}}
+\define@key[al]{verse}{gutter}{\setlength{\al@gutter@width}{#1}}
+\define@key[al]{verse}{metre}{\arb{#1}}
+\define@key[al]{verse}{color}[]{\color{#1}}
+\define@boolkey[al]{verse}{utf}[true]{}
+\define@boolkey[al]{verse}{delim}[true]{}
+\define@boolkey[al]{verse}{export}[true]{}
+\define@choicekey[al]{verse}{mode}{fullvoc, voc, novoc,
+ trans}{\def\al@mode{#1}}
+\presetkeys[al]{verse}{metre={}, utf=false,
+ delim=false}{}
+% \end{macrocode}
+% Then follows the environment itself:
+% \begin{macrocode}
+\NewDocumentEnvironment{arabverse}{O{}}%
+{\bgroup\setkeys[al]{verse}[width, gutter, color, utf, delim,
+ metre]{#1}%
+ \if@pkg@export\ifal@verse@export%
+ \ArbOutFile{\begin{arabverse}}%
+ % \ifx\al@mode\al@mode@trans%
+ % \luadirect{arabluatex.tooutfile(\luastringN{[#1]})}%
+ % \else%
+ \IfSubStr[1]{#1}{utf}%
+ {\luadirect{arabluatex.tooutfile(\luastringN{[#1]})}}%
+ {\luadirect{arabluatex.tooutfile(\luastringN{[#1, utf]})}}%
+ % \fi
+ \else\fi\else\fi\egroup%
+ \par\centering\noindent\bgroup\setkeys[al]{verse}[metre]{#1}%
+ % \ifx\al@mode\al@mode@trans%
+ % \ifal@verse@utf\setRL\else\setLR\fi%
+ % \else\setRL\fi%
+ \ifal@verse@utf%
+ \ifx\al@mode\al@mode@trans\setLR\else\setRL\fi%
+ \else%
+ \ifx\al@mode\al@mode@trans\setLR\else\setRL\fi%
+ \fi%
+ \arab@v@export[#1]
+ }%
+ {\endarab@v@export
+ \hfill\setkeys[al]{verse}[width, gutter, color, utf, delim, mode,
+ export]{#1}%
+ \egroup\par%
+ \bgroup\setkeys[al]{verse}[width, gutter, color, utf, delim, mode,
+ metre]{#1}%
+ \if@pkg@export\ifal@verse@export%
+ \ArbOutFile{\end{arabverse}}
+ \else\fi\else\fi\egroup}
+% \end{macrocode}
+% \begin{macro}{\bayt}
+% \changes{v1.6}{2016/12/17}{New macro \cs{bayt} for typesetting
+% each verse inside the \texttt{arabverse} environment} Each verse
+% consists of two hemistichs; therefore the \cs{bayt} command takes
+% two arguments, the first receives the \arb[trans]{.sadr} and the
+% second the \arb[trans]{`ajuz}. That two subsequent hemistichs
+% should be connected with one another is technically named
+% \arb[trans]{tadwIr}. In some of these cases, the hemistichs may be
+% connected by a prominent horizontal flexible stroke which is drawn
+% by the \cs{al@verse@stroke} command.
+% \begin{macro}{\SetHemistichDelim}
+% \changes{v1.6}{2016/12/17}{New \cs{SetHemistichDelim} command for
+% changing the default delimiter between hemistichs} A hemistich
+% delimiter also may be defined. By default, it is set to the
+% \enquote*{star} character: |*|. The
+% \cs{SetHemistichDelim}\marg{delimiter} command can be used at any
+% point of the document to change this default setting.
+% \end{macro}
+% \begin{macrocode}
+\NewDocumentCommand{\arb@utf}{m}{%
+ \ifal@verse@utf\txarb{#1}\else\arb{#1}\fi}
+\def\al@hemistich@delim{*}
+\NewDocumentCommand{\SetHemistichDelim}{m}{\def\al@hemistich@delim{#1}}
+\def\al@verse@stroke{\leavevmode\xleaders\hbox{\arb{--}}\hfill\kern0pt}
+\NewDocumentCommand{\bayt}{s m o m}{%
+ \IfBooleanTF{#1}{\relax}{\relax}%
+ \ifdefined\savenotes\savenotes\else\fi%
+ \edef\al@tatweel{--}%
+ \adjustbox{width=\al@bayt@width, height=\Height}{\arb@utf{#2}}%
+ \IfNoValueTF{#3}{%
+ \ifal@verse@delim\makebox[\al@gutter@width][c]{\al@hemistich@delim}%
+ \else%
+ \hspace{\al@gutter@width}%
+ \fi
+ }{%
+ \edef\@tempa{#3}%
+ \ifx\@tempa\al@tatweel%
+ \ifx\al@mode\al@mode@trans%
+ \hspace{\al@gutter@width}%
+ \else%
+ \makebox[\al@gutter@width][s]{\al@verse@stroke}%
+ \fi%
+ \else%
+ \ifx\al@mode\al@mode@trans%
+ \adjustbox{width=\al@gutter@width, height=\Height}{\arb@utf{#3}}%
+ \else%
+ \makebox[\al@gutter@width][s]{\arb@utf{#3}}%
+ \fi\fi}%
+ \adjustbox{width=\al@bayt@width, height=\Height}{\arb@utf{#4}}%
+ \ifdefined\spewnotes\spewnotes\else\fi%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{environment}
+% \begin{macro}{\abjad} \cs{abjad}\marg{number} expresses its argument
+% in Arabic letters in accordance with the \arb[trans]{'abjad}
+% arrangement of the alphabet. \meta{number} must be between 1 and
+% 1999. It is now coded in Lua so that \package{polyglossia} is no
+% longer needed. See |arabluatex.lua| for more information.
+% \changes{v1.1}{2016/04/26}{New and more flexible \protect\cs{abjad}
+% command.}
+% \begin{macrocode}
+\AtBeginDocument{%
+ \ifdefined\abjad%
+ \RenewDocumentCommand{\abjad}{m}%
+ {\ifbool{al@rlmode}%
+ {\oline*{%
+ \luadirect{tex.sprint(arabluatex.abjadify(\luastring{#1}))}}}
+ {\luadirect{tex.sprint(arabluatex.abjadify(\luastring{#1}))}}}
+ \else%
+ \NewDocumentCommand{\abjad}{m}%
+ {\ifbool{al@rlmode}%
+ {\oline*{%
+ \luadirect{tex.sprint(arabluatex.abjadify(\luastring{#1}))}}}
+ {\luadirect{tex.sprint(arabluatex.abjadify(\luastring{#1}))}}}
+ \fi}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\ayah}\changes{v1.15}{2018/10/09}{Prints End of Ayah
+% sign}\cs{ayah}\marg{number} prints up to 3-digit numbers inside
+% \enquote*{end of Ayah} sign (|U+06DD|) or inside parentheses
+% depending on the mode which is selected.
+% \begin{macrocode}
+\NewDocumentCommand{\ayah}{m}{%
+ \luadirect{tex.sprint(arabluatex.ayah(\luastringN{#1}))}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\arbnull}
+% \changes{v1.7}{2016/12/24}{New \cs{arbnull} command for putting
+% back on any contextual analysis rule broken by other commands.}
+% The \cs{arbnull} command does nothing by itself. It is processed
+% only if it is found in Arabic context so as to put back on
+% contextual analysis in case it has been broken by other commands.
+% \begin{macrocode}
+\NewDocumentCommand{\arbnull}{m}{\relax}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\abraces}
+% \cs{abraces}\marg{Arabic text} puts its argument between
+% braces. This macro is written in Lua and is dependent on the
+% current value of |tex.textdir|.
+% \changes{v1.4.3}{2016/09/14}{New \cs{abraces} command which
+% expresses its argument between braces.}
+% \begin{macrocode}
+\NewDocumentCommand{\abraces}{+m}{%
+ \luadirect{tex.sprint(arabluatex.abraces(\luastringN{#1}))}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\LRmarginpar} \cs{LRmarginpar} is supposed to be
+% inserted in an Arabic environment. It typsets his argument in a
+% marginal note from left to right.
+% \begin{macrocode}
+\DeclareDocumentCommand{\LRmarginpar}{o m}{%
+ \IfNoValueTF{#1}
+ {\marginpar{\textdir TLT #2}}
+ {\marginpar[\textdir TLT #1]{\textdir TLT #2}}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\LRfootnote} \cs{LRfootnote} and \cs{RLfootnote} are
+% supposed to be used in Arabic environments for insertions of non
+% Arabic text. \cs{LRfootnote} typesets its argument left-to-right\ldots
+% \begin{macro}{\RLfootnote} while \cs{RLfootnote} typesets its
+% argument left-to-right.
+% \begin{macrocode}
+\DeclareDocumentCommand{\LRfootnote}{m}{\bgroup\pardir
+ TLT\textdir TLT\footnote{#1}\egroup}
+\DeclareDocumentCommand{\RLfootnote}{m}{\bgroup\pardir
+ TRT\textdir TRT\footnote{#1}\egroup}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\FixArbFtnmk} In the preamble, just below
+% \cs{usepackage}|{arabluatex}|, \cs{FixArbFtnmk} may be of some
+% help in case the footnote numbers at the bottom of the page are
+% printed in the wrong direction. This quick fix uses and loads
+% \package{scrextend} if it is not already loaded.
+% \begin{macrocode}
+\NewDocumentCommand{\FixArbFtnmk}{}{%
+ \@ifpackageloaded{scrextend}%
+ {\AtBeginDocument{%
+ \deffootnote{2em}{1.6em}{\LR{\thefootnotemark}.\enskip}}}%
+ {\RequirePackage{scrextend}
+ \AtBeginDocument{%
+ \deffootnote{2em}{1.6em}{\LR{\thefootnotemark}.\enskip}}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph*{Exporting Unicode Arabic to external file}
+% \begin{macro}{\SetArbOutSuffix}
+% \changes{v1.13}{2018/08/27}{Sets a suffix to be appended to the
+% filename of the external Unicode file.}By default, |_out| is the
+% suffix to be appended to the external file in which
+% \package{arabluatex} exports Unicode in place of
+% |arabtex| or |buckwalter| strings. Any other suffix may be
+% set with \cs{SetArbOutSuffix}\marg{suffix}.
+% \begin{macrocode}
+\NewDocumentCommand{\SetArbOutSuffix}{m}{
+ \luadirect{arabluatex.utffilesuffix(\luastringN{#1})}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\ArbOutFile}
+% \changes{v1.13}{2018/08/27}{Silently exports its argument in the
+% selected external file.}
+% \cs{ArbOutFile}\oarg{newline}\marg{string} silently exports
+% \meta{string} to the external selected file. It may take |newline|
+% as an optional argument in which case a carriage return is
+% appended to |string|.
+% \begin{macro}{\ArbOutFile*}
+% \cs{ArbOutFile*}\oarg{newline}\marg{string} does the same as
+% \cs{ArbOutFile} but also inserts \meta{string} in the current
+% |.tex| source file.
+% \begin{macrocode}
+\NewDocumentCommand{\ArbOutFile}{s O{no} +m}{%
+ \if@pkg@export%
+ \IfBooleanTF{#1}{%
+ #3\luadirect{arabluatex.tooutfile(\luastringN{#3}, "#2")}}{%
+ \luadirect{arabluatex.tooutfile(\luastringN{#3}, "#2")}}%
+ \else\IfBooleanTF{#1}{#3}{}\fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{environment}{arabexport}
+% \changes{v1.13}{2018/08/27}{Processes and print its argument in
+% the current file and exports it in full Unicode in the external
+% selected \texttt{.tex} file.} The |arabexport| environment
+% processes and prints its argument unchanged to the current |.pdf|
+% file. Additionally, if \package{arabluatex} is loaded with the
+% |export| option, this argument is exported to the external
+% selected |.tex| file with Unicode in place of the original
+% |arabtex| or |buckwalter| strings.
+% \begin{macrocode}
+\NewDocumentEnvironment{arabexport}{+b}{%
+ \if@pkg@export%
+ \par
+ #1
+ \luadirect{arabluatex.doexport("yes")}
+ \luadirect{tex.sprint(arabluatex.arbtoutf(\luastringN{#1}))}
+ \luadirect{arabluatex.doexport("no")}
+ \else\par#1\fi
+ }{\par}
+% \end{macrocode}
+% \end{environment}
+% \begin{environment}{arab@v@export} The |arab@v@export| environment
+% does for |arabverse| the same as |arabexport|. It is used
+% internally by |arabverse|.
+% \begin{macrocode}
+\NewDocumentEnvironment{arab@v@export}{O{} +b}{%
+ \setkeys[al]{verse}[width, gutter, color, utf, delim, mode,
+ metre]{#1}
+ \if@pkg@export\ifal@verse@export%
+ \par
+ #2
+ \luadirect{arabluatex.doexport("arabverse")}
+ \luadirect{tex.sprint(arabluatex.arbtoutf(\luastringN{#2}))}
+ \luadirect{arabluatex.doexport("no")}
+ \else\par#2\fi\else\par#2\fi
+}{\par}
+% \end{macrocode}
+% \end{environment}
+% \begin{macro}{\arbpardir}
+% \changes{v1.13}{2018/08/27}{Sets the direction of Arabic paragraphs
+% once they are converted to Unicode.} \cs{arbpardir} is automatically
+% inserted by \package{arabluatex} at the beginning of Arabic
+% paragraphs converted to Unicode so that they are printed in the
+% right direction.
+% \begin{macrocode}
+\NewDocumentCommand{\arbpardir}{}{%
+ \ifx\al@mode\al@mode@trans\setLR\else\setRL\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection*{Errors and Warnings}
+% \begin{macrocode}
+\newcommand{\al@warning}[1]{\PackageWarning{arabluatex}{#1}}
+\newcommand{\al@error}[2]{\PackageError{arabluatex}{#1}{#2}}
+\newcommand{\al@wrong@nesting}{\al@error{%
+ (RL/LR)\string\footnote\space is not allowed\MessageBreak inside
+ \string\RL{} and \string\RL{} commands}{%
+ Get rid of the surrounding \string\RL{} or \string\LR{} command.}}
+\newcommand{\al@wrong@mark}{\al@warning{%
+ Unknown Arabic mark in \string\arbmark{}. Replaced
+ with\MessageBreak <??>. Please check your code}}
+% \end{macrocode}
+%
+% That is it. Say goodbye before leaving.
+%
+% \iffalse
+%</package>
+% \fi
+%
+% \subsection*{Patches}
+% \label{sec:patches}
+%
+% \iffalse
+%<*patch>
+% \fi
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{arabluatex-patch}%
+[2016/11/14 v1.0 patches for arabluatex]
+% \end{macrocode}
+% I have put in a separate |.sty| file external lines of code that
+% I had to patch for a good reason. I hate doing this, and hopefully,
+% most of these lines will disappear as soon as they are not required
+% anymore.
+%
+% The following is taken from |latex.ltx|. I had to make this patch
+% for I could not find a way to process the list environments in
+% right-to-left mode. The {\LuaTeX} primitives \cs{bodydir} and
+% \cs{pagedir} will eventually allow us to get rid of this:
+% \begin{macrocode}
+\def\list#1#2{%
+ \ifnum \@listdepth >5\relax
+ \@toodeep
+ \else
+ \global\advance\@listdepth\@ne
+ \fi
+ \rightmargin\z@
+ \listparindent\z@
+ \itemindent\z@
+ \csname @list\romannumeral\the\@listdepth\endcsname
+ \def\@itemlabel{#1}%
+ \let\makelabel\@mklab
+ \@nmbrlistfalse
+ #2\relax
+ \@trivlist
+ \parskip\parsep
+ \parindent\listparindent
+ \advance\linewidth -\rightmargin
+ \advance\linewidth -\leftmargin
+% \end{macrocode}
+% patch begins:
+% \begin{macrocode}
+ \ifbool{al@rlmode}{\advance\@totalleftmargin \rightmargin}%
+ {\advance\@totalleftmargin \leftmargin}
+% \end{macrocode}
+% patch ends.
+% \begin{macrocode}
+ \parshape \@ne \@totalleftmargin \linewidth
+ \ignorespaces}
+\def\@item[#1]{%
+ \if@noparitem
+ \@donoparitem
+ \else
+ \if@inlabel
+ \indent \par
+ \fi
+ \ifhmode
+ \unskip\unskip \par
+ \fi
+ \if@newlist
+ \if@nobreak
+ \@nbitem
+ \else
+ \addpenalty\@beginparpenalty
+ \addvspace\@topsep
+ \addvspace{-\parskip}%
+ \fi
+ \else
+ \addpenalty\@itempenalty
+ \addvspace\itemsep
+ \fi
+ \global\@inlabeltrue
+ \fi
+ \everypar{%
+ \@minipagefalse
+ \global\@newlistfalse
+ \if@inlabel
+ \global\@inlabelfalse
+ {\setbox\z@\lastbox
+ \ifvoid\z@
+ \kern-\itemindent
+ \fi}%
+ \box\@labels
+ \penalty\z@
+ \fi
+ \if@nobreak
+ \@nobreakfalse
+ \clubpenalty \@M
+ \else
+ \clubpenalty \@clubpenalty
+ \everypar{}%
+ \fi}%
+ \if@noitemarg
+ \@noitemargfalse
+ \if@nmbrlist
+ \refstepcounter\@listctr
+ \fi
+ \fi
+% \end{macrocode}
+% patch begins:
+% \begin{macrocode}
+ \ifbool{al@rlmode}{\sRLbox\@tempboxa{\makelabel{#1}}}{%
+ \sbox\@tempboxa{\makelabel{#1}}}%
+ \ifbool{al@rlmode}{\global\setbox\@labels\hbox dir TRT}%
+ {\global\setbox\@labels\hbox}{%
+% \end{macrocode}
+% patch ends.
+% \begin{macrocode}
+ \unhbox\@labels
+ \hskip \itemindent
+ \hskip -\labelwidth
+ \hskip -\labelsep
+ \ifdim \wd\@tempboxa >\labelwidth
+ \box\@tempboxa
+ \else
+ \hbox to\labelwidth {\unhbox\@tempboxa}%
+ \fi
+ \hskip \labelsep}%
+ \ignorespaces}
+% \end{macrocode}
+% This is adapted from Vafa Khalighi's \package{bidi} package. Thanks
+% to him.
+% \begin{macrocode}
+\long\def\sRLbox#1#2{\setbox#1\hbox dir TRT{%
+ \color@setgroup#2\color@endgroup}}
+% \end{macrocode}
+%
+% \iffalse
+%</patch>
+% \fi
+%
+% \Finale
+\endinput
diff --git a/macros/luatex/latex/arabluatex/arabluatex.ins b/macros/luatex/latex/arabluatex/arabluatex.ins
new file mode 100644
index 0000000000..ea5a73ebcf
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/arabluatex.ins
@@ -0,0 +1,109 @@
+%% This file is part of the `arabluatex' package
+%%
+%% ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX
+%% Copyright (C) 2016--2019 Robert Alessi
+%%
+%% Please send error reports and suggestions for improvements to
+%% Robert Alessi <alessi@robertalessi.net>
+%%
+%% This program is free software: you can redistribute it and/or
+%% modify it under the terms of the GNU General Public License
+%% as published by the Free Software Foundation, either version 3
+%% of the License, or (at your option) any later version.
+%%
+%% This program is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%% GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with this program. If not, see
+%% <http://www.gnu.org/licenses/>.
+%%
+%% This release of 'arabluatex' consists of the following source files:
+%% - arabluatex.ins
+%% - arabluatex.dtx
+%% - arabluatex.lua
+%% - arabluatex_voc.lua
+%% - arabluatex_fullvoc.lua
+%% - arabluatex_novoc.lua
+%% - arabluatex_trans.lua
+%%
+
+
+\input docstrip.tex
+\keepsilent
+
+\usedir{tex/lualatex/arabluatex}
+
+\preamble
+
+This is a generated file.
+
+This file is part of the `arabluatex' package
+
+ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX
+Copyright (C) 2016--2019 Robert Alessi
+
+Please send error reports and suggestions for improvements to Robert
+Alessi <alessi@robertalessi.net>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see
+<http://www.gnu.org/licenses/>.
+
+This release of 'arabluatex' consists of the following source files:
+- arabluatex.ins
+- arabluatex.dtx
+- arabluatex.lua
+- arabluatex_voc.lua
+- arabluatex_fullvoc.lua
+- arabluatex_novoc.lua
+- arabluatex_trans.lua
+
+\endpreamble
+
+\generate{%
+ \file{arabluatex.sty}{\from{arabluatex.dtx}{package}}
+ \file{arabluatex-patch.sty}{\from{arabluatex.dtx}{patch}}
+ }
+
+\Msg{***********************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* files into a directory where LaTeX canfind them. See the}
+\Msg{* FAQ at https://texfaq.org/FAQ-inst-wlcf for}
+\Msg{* more on this}
+\Msg{*}
+\Msg{* \space\space arabluatex.sty}
+\Msg{* \space\space arabluatex-patch.sty}
+\Msg{* \space\space arabluatex.lua}
+\Msg{* \space\space arabluatex_voc.lua}
+\Msg{* \space\space arabluatex_fullvoc.lua}
+\Msg{* \space\space arabluatex_novoc.lua}
+\Msg{* \space\space arabluatex_trans.lua}
+\Msg{*}
+\Msg{* To produce the documentation run the files ending with}
+\Msg{* `.dtx' through LuaLaTeX.}
+\Msg{*}
+\Msg{* For an index, do:}
+\Msg{* \space makeindex -s gind.ist -o arabluatex.ind arabluatex.idx}
+\Msg{* For a list of changes, do:}
+\Msg{* \space makeindex -s gglo.ist -o arabluatex.gls arabluatex.glo}
+\Msg{* For a bibliography, do:}
+\Msg{* \space biber arabluatex}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{***********************************************************}
+
+\endbatchfile
diff --git a/macros/luatex/latex/arabluatex/arabluatex.lua b/macros/luatex/latex/arabluatex/arabluatex.lua
new file mode 100644
index 0000000000..df031569c0
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/arabluatex.lua
@@ -0,0 +1,1187 @@
+--[[
+This file is part of the `arabluatex' package
+
+ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX
+Copyright (C) 2016--2019 Robert Alessi
+
+Please send error reports and suggestions for improvements to Robert
+Alessi <alessi@robertalessi.net>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see
+<http://www.gnu.org/licenses/>.
+--]]
+
+arabluatex = {}
+
+require("arabluatex_voc")
+require("arabluatex_fullvoc")
+require("arabluatex_novoc")
+require("arabluatex_trans")
+
+-- lpeg equivalent for string.gsub()
+local function gsub(s, patt, repl)
+ patt = lpeg.P(patt)
+ patt = lpeg.Cs((patt / repl + 1)^0)
+ return lpeg.match(patt, s)
+end
+
+-- makeatletter, makeatother
+local atletter = "\\makeatletter{}"
+local atother = "\\makeatother{}"
+
+-- some basic patterns:
+local ascii = lpeg.R("az", "AZ", "@@")
+local dblbkslash = lpeg.Cs("\\")
+local bsqbrackets = lpeg.Cs{ "[" * ((1 - lpeg.S"[]") + lpeg.V(1))^0 * "]" }
+local bcbraces = lpeg.Cs{ "{" * ((1 - lpeg.S"{}") + lpeg.V(1))^0 * "}" }
+local spce = lpeg.Cs(" ")
+local spcenc = lpeg.P(" ")
+local cmdstar = lpeg.Cs(spce * lpeg.P("*"))
+local bsqbracketsii = lpeg.Cs(bsqbrackets^-2)
+local bcbracesii = lpeg.Cs(bcbraces^-2)
+local cmd = lpeg.Cs(dblbkslash * ascii^1 * cmdstar^-1)
+local rawcmd = lpeg.Cs(dblbkslash * ascii^1)
+local aftercmd = lpeg.Cs(lpeg.S("*[{,.?;:'`\"") + dblbkslash)
+local cmdargs = lpeg.Cs(spce^-1 * bsqbracketsii * bcbracesii * bsqbrackets^-1)
+local arbargs = lpeg.Cs(spce^-1 * bsqbrackets^-1 * bcbraces)
+local baytargs = lpeg.Cs(spce * bcbraces * bsqbrackets^-1 * bcbraces)
+
+local function protectarb(str)
+ str = string.gsub(str, "(\\arb%s?)(%[.-%])(%b{})", "\\al@brk{\\arb%2%3}")
+ str = string.gsub(str, "(\\LR%s?)(%b{})", "\\@LR%2")
+ str = string.gsub(str, "(\\RL%s?)(%b{})", "\\@RL%2")
+ return str
+end
+
+local function unprotectarb(str)
+ str = string.gsub(str, "(\\@arb)(%[.-%])(%b{})", "\\arb%2%3")
+ str = string.gsub(str, "(\\@LR)(%b{})", "\\LR%2")
+ str = string.gsub(str, "(\\@RL)(%b{})", "\\RL%2")
+ str = gsub(str, lpeg.Cs("\\al@brk") * bcbraces, function(tag, body)
+ body = string.sub(body, 2, -2)
+ return string.format("%s", body)
+ end)
+ return str
+end
+
+-- the following is to be taken out of \arb{}
+local outofarb = {
+ "LRfootnote",
+ "RLfootnote",
+ "edtext",
+ "pstart",
+ "pend"
+}
+-- commands the arguments of which must not be processed by arabluatex
+-- inside \arb{}. 'albrkcmds' is what is set by default. 'brkcmds'
+-- collects the commands set in the preamble with \MkArbBreak{}
+local albrkcmds = {
+ "begin",
+ "end",
+ "par",
+ "LRmarginpar",
+ "arbmark",
+ "abjad",
+ "ayah"
+}
+local brkcmds = {}
+
+function arabluatex.mkarbbreak(str, opt)
+ str = str ..","
+ str = string.gsub(str, "%s+", "")
+ local fieldstart = 1
+ if opt == "dflt" then
+ repeat
+ local nexti = string.find(str, "%,", fieldstart)
+ table.insert(brkcmds, string.sub(str, fieldstart, nexti-1))
+ fieldstart = nexti +1
+ until fieldstart > string.len(str)
+ return brkcmds
+ elseif opt == "out" then
+ repeat
+ local nexti = string.find(str, "%,", fieldstart)
+ table.insert(outofarb, string.sub(str, fieldstart, nexti-1))
+ fieldstart = nexti +1
+ until fieldstart > string.len(str)
+ return outofarb
+ end
+end
+
+local function breakcmd(str)
+ -- process \item[], then \item[]
+ str = string.gsub(str, "\\(item.?)(%b[])",
+ function(tag, body)
+ body = string.sub(body, 2, -2)
+ return string.format("\\al@brk{\\item[\\arb{%s}] }", body)
+ end)
+ str = string.gsub(str, "(\\item)(%s+)", "%1{}%2")
+ -- \textcolor
+ str = string.gsub(str, "\\(textcolor%s?)(%b{})(%b{})",
+ function(tag, bodycolor, bodytext)
+ bodycolor = string.sub(bodycolor, 2, -2)
+ bodytext = string.sub(bodytext, 2, -2)
+ return string.format("\\al@brk{\\%s{%s}{\\arb{%s}}}", tag, bodycolor, bodytext)
+ end)
+ -- commands set by default in outofarb
+ for i = 1,#outofarb do
+ str = gsub(str, dblbkslash * lpeg.Cs(outofarb[i]) * cmdargs, "}%1%2%3\\arb{")
+ end
+ -- commands set by default in albrkcmds
+ for i = 1,#albrkcmds do
+ str = gsub(str, dblbkslash * lpeg.Cs(albrkcmds[i]) * cmdargs, "\\al@brk{%1%2%3}")
+ end
+ -- user commands (brkcmds)
+ if next(brkcmds) == nil then
+ -- nothing to do
+ else
+ for i = 1,#brkcmds do
+ str = gsub(str, dblbkslash * lpeg.Cs(brkcmds[i]) * cmdargs, "\\al@brk{%1%2%3}")
+ end
+ end
+ return str
+end
+
+local function holdcmd(str)
+ str = gsub(str, lpeg.Cs("\\arb") * bcbraces, function(tag, body)
+ body = string.sub(body, 2, -2)
+ body = gsub(body, cmd * spcenc^-1 * bsqbracketsii * spcenc^-1 * bcbraces, function(btag, bopt, bbody)
+ bbody = string.sub(bbody, 2, -2)
+ if string.find(btag, "@") then
+ return holdcmd(string.format("}%s%s{%s}\\arb{", btag, bopt, bbody))
+ else
+ return holdcmd(string.format("}%s%s{\\arb{%s}}\\arb{", btag, bopt, bbody))
+ end
+ end)
+ return string.format("%s{%s}", tag, body)
+ end)
+ str = string.gsub(str, "\\arb{}", "")
+ return str
+end
+
+local function arbnum(str)
+ str = string.gsub(str, "([0-9%,%-%/]+)", function(num)
+ return string.reverse(num)
+ end)
+ return str
+end
+
+local function indnum(str)
+ str = string.gsub(str, "([0-9%,%-%/]+)", function(num)
+ return string.reverse(num)
+ end)
+ for i = 1,#numbers do
+ str = string.gsub(str, numbers[i].a, numbers[i].b)
+ end
+ return str
+end
+
+local function processdiscretionary(str)
+ str = string.gsub(str, "\\%-", "\\-{}")
+ return str
+end
+
+local function processarbnull(str, scheme)
+ if scheme == "buckwalter" then
+ str = string.gsub(str, "(\\arbnull.?)(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ return string.format("P%sP", body)
+ end)
+ else
+ str = string.gsub(str, "(\\arbnull.?)(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ return string.format("O%sO", body)
+ end)
+ end
+ return str
+end
+
+local function takeout_abjad_ayah(str)
+ str = string.gsub(str, "(\\abjad.?)(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ return string.format("%s", body)
+ end)
+ str = string.gsub(str, "(\\ayah.?)(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ if tonumber(body) ~= nil and str.len(body) < 4 then
+ return string.format("(%s)", body)
+ else
+ return "<??>"
+ end
+ end)
+ return str
+end
+
+local function takeoutcapetc(str)
+ str = string.gsub(str, "(\\arb.?%[trans%])(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ body = string.gsub(body, "(\\uc%s?)(%b{})", "\\Uc%2")
+ return string.format("%s{%s}", tag, body)
+ end)
+ str = string.gsub(str, "(\\arbup.?)(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ return string.format("%s", body)
+ end)
+ str = string.gsub(str, "(\\uc%s?)(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ return string.format("%s", body)
+ end)
+ str = string.gsub(str, "\\uc%s", "")
+ str = string.gsub(str, "\\linebreak", "")
+ str = string.gsub(str, "\\%-", "")
+ return str
+end
+
+local function checkwrnested(str)
+ for i = 1,#outofarb do
+ str = gsub(str, dblbkslash * lpeg.Cs(lpeg.P("LR") + lpeg.P("RL")) * cmdargs,
+ function(prefix, tag, body)
+ body = string.sub(body, 2, -2)
+ if string.find(body, "\\"..outofarb[i]) then
+ return atletter.."\\al@wrong@nesting{}"..atother
+ else
+ -- nothing to do, so proceed.
+ end
+ end)
+ end
+ return str
+end
+
+local function takeoutarb(str)
+ str = checkwrnested(str)
+ for i = 1,#outofarb do
+ str = gsub(str, dblbkslash * lpeg.Cs(outofarb[i]) * cmdargs,
+ function(prefix, tag, body)
+ body = gsub(body, lpeg.P("\\arb"), "\\@rb")
+ return string.format("%s%s%s", prefix, tag, body)
+ end)
+ end
+ str = string.gsub(str, "(\\arb%s?)(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ return string.format("%s", body)
+ end)
+ str = string.gsub(str, "\\@rb", "\\arb")
+ str = "\\arb{"..str.."}"
+ return str
+end
+
+local function voc(str, rules)
+ str = string.gsub(str, "\\arb(%b{})", function(inside)
+ inside = string.sub(inside, 2, -2)
+ for i = 1,#hamza do
+ inside = string.gsub(inside, hamza[i].a, hamza[i].b)
+ end
+ if rules == "idgham" then
+ for i = 1,#tanwin do
+ inside = string.gsub(inside, tanwin[i].a, tanwin[i].b)
+ end
+ else
+ for i = 1,#tanwineasy do
+ inside = string.gsub(inside, tanwineasy[i].a, tanwineasy[i].b)
+ end
+ end
+ for i = 1,#trigraphs do
+ inside = string.gsub(inside, trigraphs[i].a, trigraphs[i].b)
+ end
+ if rules == "idgham" then
+ for i = 1,#idgham do
+ inside = string.gsub(inside, idgham[i].a, idgham[i].b)
+ end
+ end
+ for i = 1,#digraphs do
+ inside = string.gsub(inside, digraphs[i].a, digraphs[i].b)
+ end
+ for i = 1,#single do
+ inside = string.gsub(inside, single[i].a, single[i].b)
+ end
+ for i = 1,#longv do
+ inside = string.gsub(inside, longv[i].a, longv[i].b)
+ end
+ for i = 1,#shortv do
+ inside = string.gsub(inside, shortv[i].a, shortv[i].b)
+ end
+ for i = 1,#punctuation do
+ inside = string.gsub(inside, punctuation[i].a, punctuation[i].b)
+ end
+ for i = 1,#null do
+ inside = string.gsub(inside, null[i].a, null[i].b)
+ end
+ inside = indnum(inside)
+ return string.format("\\arabicfont{}%s", inside)
+ end)
+return str
+end
+
+local function voceasy(str)
+ str = string.gsub(str, "\\arb(%b{})", function(inside)
+ inside = string.sub(inside, 2, -2)
+ for i = 1,#hamzaeasy do
+ inside = string.gsub(inside, hamzaeasy[i].a, hamzaeasy[i].b)
+ end
+ for i = 1,#tanwineasy do
+ inside = string.gsub(inside, tanwineasy[i].a, tanwineasy[i].b)
+ end
+ for i = 1,#trigraphseasy do
+ inside = string.gsub(inside, trigraphseasy[i].a, trigraphseasy[i].b)
+ end
+ for i = 1,#digraphs do
+ inside = string.gsub(inside, digraphs[i].a, digraphs[i].b)
+ end
+ for i = 1,#single do
+ inside = string.gsub(inside, single[i].a, single[i].b)
+ end
+ for i = 1,#longv do
+ inside = string.gsub(inside, longv[i].a, longv[i].b)
+ end
+ for i = 1,#shortv do
+ inside = string.gsub(inside, shortv[i].a, shortv[i].b)
+ end
+ for i = 1,#punctuation do
+ inside = string.gsub(inside, punctuation[i].a, punctuation[i].b)
+ end
+ for i = 1,#null do
+ inside = string.gsub(inside, null[i].a, null[i].b)
+ end
+ inside = indnum(inside)
+ return string.format("\\arabicfont{}%s", inside)
+ end)
+return str
+end
+
+local function fullvoc(str, rules)
+ str = string.gsub(str, "\\arb(%b{})", function(inside)
+ inside = string.sub(inside, 2, -2)
+ for i = 1,#hamzafv do
+ inside = string.gsub(inside, hamzafv[i].a, hamzafv[i].b)
+ end
+ if rules == "idgham" then
+ for i = 1,#tanwinfv do
+ inside = string.gsub(inside, tanwinfv[i].a, tanwinfv[i].b)
+ end
+ else
+ for i = 1,#tanwinfveasy do
+ inside = string.gsub(inside, tanwinfveasy[i].a, tanwinfveasy[i].b)
+ end
+ end
+ for i = 1,#trigraphsfv do
+ inside = string.gsub(inside, trigraphsfv[i].a, trigraphsfv[i].b)
+ end
+ if rules == "idgham" then
+ for i = 1,#idgham do
+ inside = string.gsub(inside, idgham[i].a, idgham[i].b)
+ end
+ end
+ if rules == "idgham" then
+ for i = 1,#digraphsfvidgham do
+ inside = string.gsub(inside, digraphsfvidgham[i].a, digraphsfvidgham[i].b)
+ end
+ else
+ for i = 1,#digraphsfv do
+ inside = string.gsub(inside, digraphsfv[i].a, digraphsfv[i].b)
+ end
+ end
+ for i = 1,#singlefv do
+ inside = string.gsub(inside, singlefv[i].a, singlefv[i].b)
+ end
+ for i = 1,#longv do
+ inside = string.gsub(inside, longv[i].a, longv[i].b)
+ end
+ for i = 1,#shortv do
+ inside = string.gsub(inside, shortv[i].a, shortv[i].b)
+ end
+ for i = 1,#punctuation do
+ inside = string.gsub(inside, punctuation[i].a, punctuation[i].b)
+ end
+ for i = 1,#null do
+ inside = string.gsub(inside, null[i].a, null[i].b)
+ end
+ inside = indnum(inside)
+ return string.format("\\arabicfont{}%s", inside)
+ end)
+return str
+end
+
+local function fullvoceasy(str, rules)
+ str = string.gsub(str, "\\arb(%b{})", function(inside)
+ inside = string.sub(inside, 2, -2)
+ for i = 1,#hamzafveasy do
+ inside = string.gsub(inside, hamzafveasy[i].a, hamzafveasy[i].b)
+ end
+ for i = 1,#tanwinfveasy do
+ inside = string.gsub(inside, tanwinfveasy[i].a, tanwinfveasy[i].b)
+ end
+ for i = 1,#trigraphsfveasy do
+ inside = string.gsub(inside, trigraphsfveasy[i].a, trigraphsfveasy[i].b)
+ end
+ if rules == "nosukun" then
+ for i = 1,#digraphsfveasy do
+ inside = string.gsub(inside, digraphsfveasy[i].a, digraphsfveasy[i].b)
+ end
+ else
+ for i = 1,#digraphsfv do
+ inside = string.gsub(inside, digraphsfv[i].a, digraphsfv[i].b)
+ end
+ end
+ if rules == "nosukun" then
+ for i = 1,#singlefveasy do
+ inside = string.gsub(inside, singlefveasy[i].a, singlefveasy[i].b)
+ end
+ else
+ for i = 1,#singlefv do
+ inside = string.gsub(inside, singlefv[i].a, singlefv[i].b)
+ end
+ end
+ for i = 1,#longv do
+ inside = string.gsub(inside, longv[i].a, longv[i].b)
+ end
+ for i = 1,#shortv do
+ inside = string.gsub(inside, shortv[i].a, shortv[i].b)
+ end
+ for i = 1,#punctuation do
+ inside = string.gsub(inside, punctuation[i].a, punctuation[i].b)
+ end
+ for i = 1,#null do
+ inside = string.gsub(inside, null[i].a, null[i].b)
+ end
+ inside = indnum(inside)
+ return string.format("\\arabicfont{}%s", inside)
+ end)
+return str
+end
+
+local function novoc(str)
+ str = string.gsub(str, "\\arb(%b{})", function(inside)
+ inside = string.sub(inside, 2, -2)
+ for i = 1,#hamza do
+ inside = string.gsub(inside, hamza[i].a, hamza[i].b)
+ end
+ for i = 1,#tanwinnv do
+ inside = string.gsub(inside, tanwinnv[i].a, tanwinnv[i].b)
+ end
+ for i = 1,#trigraphsnv do
+ inside = string.gsub(inside, trigraphsnv[i].a, trigraphsnv[i].b)
+ end
+ for i = 1,#digraphs do
+ inside = string.gsub(inside, digraphs[i].a, digraphs[i].b)
+ end
+ for i = 1,#single do
+ inside = string.gsub(inside, single[i].a, single[i].b)
+ end
+ for i = 1,#longvnv do
+ inside = string.gsub(inside, longvnv[i].a, longvnv[i].b)
+ end
+ for i = 1,#shortvnv do
+ inside = string.gsub(inside, shortvnv[i].a, shortvnv[i].b)
+ end
+ for i = 1,#punctuation do
+ inside = string.gsub(inside, punctuation[i].a, punctuation[i].b)
+ end
+ for i = 1,#null do
+ inside = string.gsub(inside, null[i].a, null[i].b)
+ end
+ inside = indnum(inside)
+ return string.format("\\arabicfont{}%s", inside)
+ end)
+ return str
+end
+
+local function novoceasy(str)
+ str = string.gsub(str, "\\arb(%b{})", function(inside)
+ inside = string.sub(inside, 2, -2)
+ for i = 1,#hamzaeasy do
+ inside = string.gsub(inside, hamzaeasy[i].a, hamzaeasy[i].b)
+ end
+ for i = 1,#tanwinnv do
+ inside = string.gsub(inside, tanwinnv[i].a, tanwinnv[i].b)
+ end
+ for i = 1,#trigraphsnv do
+ inside = string.gsub(inside, trigraphsnv[i].a, trigraphsnv[i].b)
+ end
+ for i = 1,#digraphs do
+ inside = string.gsub(inside, digraphs[i].a, digraphs[i].b)
+ end
+ for i = 1,#single do
+ inside = string.gsub(inside, single[i].a, single[i].b)
+ end
+ for i = 1,#longvnv do
+ inside = string.gsub(inside, longvnv[i].a, longvnv[i].b)
+ end
+ for i = 1,#shortvnv do
+ inside = string.gsub(inside, shortvnv[i].a, shortvnv[i].b)
+ end
+ for i = 1,#punctuation do
+ inside = string.gsub(inside, punctuation[i].a, punctuation[i].b)
+ end
+ for i = 1,#null do
+ inside = string.gsub(inside, null[i].a, null[i].b)
+ end
+ inside = indnum(inside)
+ return string.format("\\arabicfont{}%s", inside)
+ end)
+ return str
+end
+
+local function transdmg(str, rules)
+ str = string.gsub(str, "\\arb(%b{})", function(inside)
+ inside = string.sub(inside, 2, -2)
+ for i = 1,#hamzatrdmg do
+ inside = string.gsub(inside, hamzatrdmg[i].a, hamzatrdmg[i].b)
+ end
+ for i = 1,#tanwintrdmg do
+ inside = string.gsub(inside, tanwintrdmg[i].a, tanwintrdmg[i].b)
+ end
+ for i = 1,#trigraphstrdmg do
+ inside = string.gsub(inside, trigraphstrdmg[i].a, trigraphstrdmg[i].b)
+ end
+ if rules == "idgham" then
+ for i = 1,#idghamtrdmg do
+ inside = string.gsub(inside, idghamtrdmg[i].a, idghamtrdmg[i].b)
+ end
+ end
+ for i = 1,#digraphstrdmg do
+ inside = string.gsub(inside, digraphstrdmg[i].a, digraphstrdmg[i].b)
+ end
+ for i = 1,#singletrdmg do
+ inside = string.gsub(inside, singletrdmg[i].a, singletrdmg[i].b)
+ end
+ for i = 1,#longvtrdmg do
+ inside = string.gsub(inside, longvtrdmg[i].a, longvtrdmg[i].b)
+ end
+ for i = 1,#shortvtrdmg do
+ inside = string.gsub(inside, shortvtrdmg[i].a, shortvtrdmg[i].b)
+ end
+ for i = 1,#punctuationtr do
+ inside = string.gsub(inside, punctuationtr[i].a, punctuationtr[i].b)
+ end
+ for i = 1,#nulltr do
+ inside = string.gsub(inside, nulltr[i].a, nulltr[i].b)
+ end
+ return string.format("%s", inside)
+ end)
+ return str
+end
+
+local function transloc(str)
+ str = string.gsub(str, "\\arb(%b{})", function(inside)
+ inside = string.sub(inside, 2, -2)
+ for i = 1,#hamzatrloc do
+ inside = string.gsub(inside, hamzatrloc[i].a, hamzatrloc[i].b)
+ end
+ for i = 1,#tanwintrloc do
+ inside = string.gsub(inside, tanwintrloc[i].a, tanwintrloc[i].b)
+ end
+ for i = 1,#trigraphstrloc do
+ inside = string.gsub(inside, trigraphstrloc[i].a, trigraphstrloc[i].b)
+ end
+ for i = 1,#digraphstrloc do
+ inside = string.gsub(inside, digraphstrloc[i].a, digraphstrloc[i].b)
+ end
+ for i = 1,#singletrloc do
+ inside = string.gsub(inside, singletrloc[i].a, singletrloc[i].b)
+ end
+ for i = 1,#longvtrloc do
+ inside = string.gsub(inside, longvtrloc[i].a, longvtrloc[i].b)
+ end
+ for i = 1,#shortvtrloc do
+ inside = string.gsub(inside, shortvtrloc[i].a, shortvtrloc[i].b)
+ end
+ for i = 1,#finaltrloc do
+ inside = string.gsub(inside, finaltrloc[i].a, finaltrloc[i].b)
+ end
+ for i = 1,#punctuationtr do
+ inside = string.gsub(inside, punctuationtr[i].a, punctuationtr[i].b)
+ end
+ for i = 1,#nulltr do
+ inside = string.gsub(inside, nulltr[i].a, nulltr[i].b)
+ end
+ return string.format("%s", inside)
+ end)
+ return str
+end
+
+local function transarabica(str)
+ str = string.gsub(str, "\\arb(%b{})", function(inside)
+ inside = string.sub(inside, 2, -2)
+ for i = 1,#hamzatrarabica do
+ inside = string.gsub(inside, hamzatrarabica[i].a, hamzatrarabica[i].b)
+ end
+ for i = 1,#tanwintrloc do
+ inside = string.gsub(inside, tanwintrloc[i].a, tanwintrloc[i].b)
+ end
+ for i = 1,#trigraphstrarabica do
+ inside = string.gsub(inside, trigraphstrarabica[i].a, trigraphstrarabica[i].b)
+ end
+ for i = 1,#digraphstrarabica do
+ inside = string.gsub(inside, digraphstrarabica[i].a, digraphstrarabica[i].b)
+ end
+ for i = 1,#singletrarabica do
+ inside = string.gsub(inside, singletrarabica[i].a, singletrarabica[i].b)
+ end
+ for i = 1,#longvtrarabica do
+ inside = string.gsub(inside, longvtrarabica[i].a, longvtrarabica[i].b)
+ end
+ for i = 1,#shortvtrloc do
+ inside = string.gsub(inside, shortvtrloc[i].a, shortvtrloc[i].b)
+ end
+ for i = 1,#punctuationtr do
+ inside = string.gsub(inside, punctuationtr[i].a, punctuationtr[i].b)
+ end
+ for i = 1,#nulltr do
+ inside = string.gsub(inside, nulltr[i].a, nulltr[i].b)
+ end
+ return string.format("%s", inside)
+ end)
+ return str
+end
+
+local function processbuckw(str)
+ str = string.gsub(str, "\\arb(%b{})", function(inside)
+ inside = string.sub(inside, 2, -2)
+ for i = 1,#buckwalter do
+ inside = string.gsub(inside, buckwalter[i].a, buckwalter[i].b)
+ end
+ return string.format("\\arb{%s}", inside)
+ end)
+ return str
+end
+
+-- The following functions produce a copy of the original .tex source
+-- file in which all arabtex strings are replaced with Unicode
+-- equivalents
+local utffilesuffix = "_out"
+local export_utf = "no"
+
+function arabluatex.utffilesuffix(str)
+ utffilesuffix = str
+ return true
+end
+
+function arabluatex.doexport(str)
+ export_utf = str
+ return true
+end
+
+function arabluatex.openstream()
+ local f = io.open(tex.jobname..utffilesuffix.."_tmp.tex", "a+")
+ local preamble = io.open(tex.jobname..".tex", "r")
+ for line in preamble:lines() do
+ f:write(line, "\n")
+ if string.find(line, "^%s-\\begin%s?{document}") then
+ break
+ end
+ end
+ preamble:close()
+ f:close()
+ return true
+end
+
+local function processarbtoutf(str)
+ if export_utf ~= "arabverse" then
+ str = "\\begin{arabexport}"..str
+ else end
+ --[[ -- of no use, see above takeout_abjad_ayah()
+ str = string.gsub(str, "(\\txtrans%s?)(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ body = string.gsub(body, "(\\abjad%s?)(%b{})", function(btag, bbody)
+ bbody = string.sub(bbody, 2, -2)
+ return string.format("%s", bbody)
+ end)
+ body = string.gsub(body, "(\\ayah%s?)(%b{})", function(btag, bbody)
+ bbody = string.sub(bbody, 2, -2)
+ return string.format("(%s)", bbody)
+ end)
+ return string.format("%s{%s}", tag, body)
+ end)
+ --]]
+ str = string.gsub(str, "(\\txarb%s?)(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ body = string.gsub(body, "(\\abjad%s?)(%b{})", function(btag, bbody)
+ bbody = string.sub(bbody, 2, -2)
+ if tonumber(bbody) ~= nil then
+ bbody = arabluatex.abjadify(bbody)
+ return string.format("\\oline*{\\arb[novoc]{%s}}", bbody)
+ else
+ return string.format("%s{%s}", btag, bbody)
+ end
+ end)
+ body = string.gsub(body, "(\\arbmark%s?)(%b{})", function(btag, bbody)
+ bbody = string.sub(bbody, 2, -2)
+ return string.format("%s[rl]{%s}", btag, bbody)
+ end)
+ body = string.gsub(body, "(\\ayah%s?)(%b{})", function(btag, bbody)
+ bbody = string.sub(bbody, 2, -2)
+ return string.format("\\arb[novoc]{%s^^^^06dd}", bbody)
+ end)
+ return string.format("%s{%s}", tag, body)
+ end)
+ str = string.gsub(str, "(\\bayt)%s?(%b{})(%b[])(%b{})", function(tag, argi, argii, argiii)
+ argi = string.sub(argi, 2, -2)
+ argii = string.sub(argii, 2, -2)
+ argiii = string.sub(argiii, 2, -2)
+ return string.format("%s*{\\arb{%s}}[\\arb{%s}]{\\arb{%s}}", tag, argi, argii, argiii)
+ end)
+ str = string.gsub(str, "(\\bayt)%s?(%b{})(%b{})", function(tag, argi, argii)
+ argi = string.sub(argi, 2, -2)
+ argii = string.sub(argii, 2, -2)
+ return string.format("%s*{\\arb{%s}}{\\arb{%s}}", tag, argi, argii)
+ end)
+ str = string.gsub(str, "(\\prname)%s?(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ if string.find(body, "\\uc%s?%b{}") then
+ return string.format("%s*{%s}", tag, body)
+ else
+ return string.format("%s{\\arb[trans]{\\uc{%s}}}", tag, body)
+ end
+ end)
+ str = string.gsub(str, "(\\begin%s?{arab})(%b[])", function(tag, body)
+ if string.find(body, "trans") then
+ return string.format("\\par\\bgroup\\setLR\\arb%s{", body)
+ else
+ return string.format("\\par\\bgroup\\setRL\\arb%s{", body)
+ end
+ end)
+ str = string.gsub(str, "(\\begin%s?{arab})", "\\par\\bgroup\\arbpardir\\arb{")
+ str = string.gsub(str, "\\end%s?{arab}", "}\\egroup\\par")
+ -- This does not work, while the following two do. Look into this later.
+ -- str = gsub(str, lpeg.Cs("\\arb") * spcenc * bsqbrackets^-1 * bcbraces, function(tag, opt, body)
+ -- body = string.sub(body, 2, -2)
+ -- return string.format("%s%s\\@al@pr@ob%s\\@al@pr@cb", tag, opt, body)
+ -- end)
+ str = string.gsub(str, "(\\arb%s?)(%b[])(%b{})", function(tag, opt, body)
+ body = string.sub(body, 2, -2)
+ return string.format("%s%s\\@al@pr@ob%s\\@al@pr@cb", tag, opt, body)
+ end)
+ str = string.gsub(str, "(\\arb)%s?(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ return string.format("%s\\@al@pr@ob%s\\@al@pr@cb", tag, body)
+ end)
+ str = string.gsub(str, "(\\arbmark)%s?(%b[])(%b{})", function(tag, opt, body)
+ body = string.sub(body, 2, -2)
+ return string.format("%s%s\\@al@pr@ob%s\\@al@pr@cb", tag, opt, body)
+ end)
+ str = string.gsub(str, "(\\arbmark)%s?(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ return string.format("%s\\@al@pr@ob%s\\@al@pr@cb", tag, body)
+ end)
+ str = string.gsub(str, "(\\[Uu]c)%s?(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ return string.format("%s\\@al@pr@ob%s\\@al@pr@cb", tag, body)
+ end)
+ str = string.gsub(str, "{", "\\@al@ob")
+ str = string.gsub(str, "} ", "\\@al@cb@sp")
+ str = string.gsub(str, "}", "\\@al@cb")
+ str = string.gsub(str, "\\@al@pr@ob", "{")
+ str = string.gsub(str, "\\@al@pr@cb", "}")
+ str = string.gsub(str, "(%b{})", function(body)
+ body = string.sub(body, 2, -2)
+ body = string.gsub(body, "(%s?)(\\@al@ob)", "%1{")
+ body = string.gsub(body, "(\\@al@cb@sp)", "} ")
+ body = string.gsub(body, "(\\@al@cb)(%s?)", "}%2")
+ return string.format("{%s}", body)
+ end)
+ if export_utf ~= "arabverse" then
+ str = str.."\\end{arabexport}"
+ else end
+ return str
+end
+
+function arabluatex.arbtoutf(str)
+ str = processarbtoutf(str)
+ str = "\\ArbOutFile{"..str.."}"
+ str = string.gsub(str, "(\\ArbOutFile)%s?(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ body = gsub(body, lpeg.Cs("\\arb") * arbargs, "}%1%2\\ArbOutFile{")
+ return string.format("%s{%s}", tag, body)
+ end)
+ str = string.gsub(str, "(\\ArbOutFile)%s?(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ body = string.gsub(body, "(\\[Uu]c)%s?(%b{})", "}%1%2\\ArbOutFile{")
+ return string.format("%s{%s}", tag, body)
+ end)
+ str = string.gsub(str, "(\\ArbOutFile)%s?(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ body = gsub(body, lpeg.Cs("\\arbmark") * arbargs, "}%1%2\\ArbOutFile{")
+ return string.format("%s{%s}", tag, body)
+ end)
+ return str
+end
+
+function arabluatex.tooutfile(str, nl)
+ local f = io.open(tex.jobname..utffilesuffix.."_tmp.tex", "a+")
+ if nl == "newline" then
+ f:write(str, "\n\n")
+ else
+ f:write(str)
+ end
+ f:close()
+ return str
+end
+
+function arabluatex.closestream()
+ local f = io.open(tex.jobname..utffilesuffix.."_tmp.tex", "r")
+ local o = io.open(tex.jobname..utffilesuffix..".tex", "w")
+ local t = f:read("*a")
+ t = string.gsub(t, "\\arabicfont{}", "")
+ t = string.gsub(t, "\\par ", "\n\n")
+ t = string.gsub(t, "(\\@al@ob)", "{")
+ t = string.gsub(t, "(\\@al@cb@sp)", "} ")
+ t = string.gsub(t, "(\\@al@cb)(%s?)", "}")
+ t = gsub(t, lpeg.Cs("\\begin") * spcenc^-1 * bcbraces * cmdargs,
+ "\n%1%2%3\n")
+ t = string.gsub(t, "(\\\\)(%s?)", "%1\n")
+ t = string.gsub(t, "(\\\\)(\n)(\\end%s?)(%b{})", "%1%3%4")
+ t = string.gsub(t, "%s-\n(\\begin%s?)(%b{})", "\n%1%2")
+ t = string.gsub(t, "(\\item)", "\n%1")
+ t = string.gsub(t, "\n\n(\\item)", "\n%1")
+ t = string.gsub(t, "(\\end%s?)(%b{})", "%1%2\n")
+ t = string.gsub(t, "([^\n]%s-)(\\end)%s?(%b{})", "%1\n%2%3")
+ t = string.gsub(t, "\n\n\n", "\n\n")
+ t = string.gsub(t, "(\\txarb%s?%{)(\\txarb%s?)(%b{})(%})",
+ function(tagio, tagii, body, tagic)
+ body = string.sub(body, 2, -2)
+ return
+ string.format("%s%s%s", tagio, body, tagic)
+ end)
+ t = string.gsub(t, "(\\prname%s?%*%{)(\\txtrans%s?)(%b{})(%})",
+ function(tagio, tagii, body, tagic)
+ body = string.sub(body, 2, -2)
+ return string.format("%s%s%s", tagio, body, tagic)
+ end)
+ if string.find(t, "\\begin%s?{document}.-\\arb%s?[%[%{]")
+ or
+ string.find(t, "\\begin%s?{document}.-\\[Uu]c%s?%b{}")
+ or
+ string.find(t, "\\begin%s?{document}.-\\abjad%s?%b{}")
+ or
+ string.find(t, "\\begin%s?{document}.-\\ayah%s?%b{}")
+ then
+ -- issue a warning:
+ tex.print([[\unexpanded{\PackageWarningNoLine{arabluatex}{]]
+ ..
+ [[There are still 'arabtex' strings to be converted. ]]
+ ..
+ [[Please open ]] .. tex.jobname .. utffilesuffix .. ".tex" ..
+ [[ and compile it one more time}}]])
+ --
+ else end
+ t = gsub(t, rawcmd * spce^1 * aftercmd, "%1%3")
+ t = t.."\n\\end{document}"
+ io.write(t)
+ o:write(t)
+ f:close()
+ o:close()
+ os.remove(tex.jobname..utffilesuffix.."_tmp.tex")
+ return true
+end
+
+-- Process standard arabluatex modes:
+function arabluatex.processvoc(str, rules, scheme)
+ str = takeoutarb(str)
+ str = processarbnull(str, scheme)
+ str = takeoutcapetc(str)
+ str = protectarb(str)
+ str = breakcmd(str)
+ str = holdcmd(str)
+ if scheme == "buckwalter" then
+ str = processbuckw(str)
+ else end
+ if rules == "easy" or rules == "easynosukun" then
+ str = voceasy(str)
+ elseif rules == "dflt" or rules == "idgham" then
+ str = voc(str, rules)
+ else end
+ str = unprotectarb(str)
+ if export_utf == "yes" then
+ tofile = "\\txarb{"..str.."}"
+ arabluatex.tooutfile(tofile)
+ elseif export_utf == "arabverse" then
+ tofile = "\\txarb{"..str.."}"
+ arabluatex.tooutfile(tofile)
+ else
+ return str
+ end
+ return ""
+end
+
+function arabluatex.processfullvoc(str, rules, scheme)
+ str = takeoutarb(str)
+ str = processarbnull(str, scheme)
+ str = takeoutcapetc(str)
+ str = protectarb(str)
+ str = breakcmd(str)
+ str = holdcmd(str)
+ if scheme == "buckwalter" then
+ str = processbuckw(str)
+ else end
+ if rules == "easy" then
+ str = fullvoceasy(str, "sukun")
+ elseif rules == "easynosukun" then
+ str = fullvoceasy(str, "nosukun")
+ elseif rules == "dflt" or rules == "idgham" then
+ str = fullvoc(str, rules)
+ else end
+ str = unprotectarb(str)
+ if export_utf == "yes" then
+ tofile = "\\txarb{"..str.."}"
+ arabluatex.tooutfile(tofile)
+ elseif export_utf == "arabverse" then
+ tofile = "\\txarb{"..str.."}"
+ arabluatex.tooutfile(tofile)
+ else
+ return str
+ end
+ return ""
+end
+
+function arabluatex.processnovoc(str, rules, scheme)
+ str = takeoutarb(str)
+ str = processarbnull(str, scheme)
+ str = takeoutcapetc(str)
+ str = protectarb(str)
+ str = breakcmd(str)
+ str = holdcmd(str)
+ if scheme == "buckwalter" then
+ str = processbuckw(str)
+ else end
+ if rules == "easy" or rules == "easynosukun" then
+ str = novoceasy(str)
+ elseif rules == "dflt" or rules == "idgham" then
+ str = novoc(str)
+ else end
+ str = unprotectarb(str)
+ if export_utf == "yes" then
+ tofile = "\\txarb{"..str.."}"
+ arabluatex.tooutfile(tofile)
+ elseif export_utf == "arabverse" then
+ tofile = "\\txarb{"..str.."}"
+ arabluatex.tooutfile(tofile)
+ else
+ return str
+ end
+ return ""
+end
+
+function arabluatex.processtrans(str, mode, rules, scheme)
+ str = takeoutarb(str)
+ str = processdiscretionary(str)
+ str = processarbnull(str, scheme)
+ str = takeout_abjad_ayah(str)
+ str = protectarb(str)
+ str = breakcmd(str)
+ str = holdcmd(str)
+ if scheme == "buckwalter" then
+ str = processbuckw(str)
+ end
+ if mode == "dmg" then
+ str = transdmg(str, rules)
+ elseif mode == "loc" then
+ str = transloc(str)
+ elseif mode == "arabica" then
+ str = transarabica(str)
+ end
+ str = unprotectarb(str)
+ if export_utf == "yes" then
+ tofile = "\\txtrans{"..str.."}"
+ arabluatex.tooutfile(tofile)
+ elseif export_utf == "arabverse" then
+ tofile = "\\txtrans{"..str.."}"
+ arabluatex.tooutfile(tofile)
+ else
+ return str
+ end
+ return ""
+end
+
+function arabluatex.newarbmark(abbr, rtlmk, ltrmk)
+ abbr = "@"..abbr
+ rtlmk = "\\arabicfont{}"..rtlmk
+ table.insert(arbmarks, {a = abbr, b = rtlmk, c = ltrmk})
+ table.sort(arbmarks, function(a ,b) return(#a.a > #b.a) end)
+ return true
+end
+
+local function isintable(table, element)
+ for i = 1,#table do
+ if table[i].a == element then
+ return true
+ end
+ end
+ return false
+end
+
+function arabluatex.processarbmarks(str, dir)
+ str = "@"..str
+ if not isintable(arbmarks, str) then
+ str = "\\LR{<??>}"..atletter.."\\al@wrong@mark{}"..atother
+ else
+ if dir == "lr" then
+ for i = 1,#arbmarks do
+ str = string.gsub(str, arbmarks[i].a, arbmarks[i].c)
+ end
+ elseif dir == "rl" then
+ for i = 1,#arbmarks do
+ str = string.gsub(str, arbmarks[i].a, arbmarks[i].b)
+ end
+ elseif tex.textdir == "TLT" then
+ for i = 1,#arbmarks do
+ str = string.gsub(str, arbmarks[i].a, arbmarks[i].c)
+ end
+ else
+ for i = 1,#arbmarks do
+ str = string.gsub(str, arbmarks[i].a, arbmarks[i].b)
+ end
+ end
+ end
+ if export_utf == "yes" then
+ tofile = str
+ arabluatex.tooutfile(tofile)
+ elseif export_utf == "arabverse" then
+ tofile = str
+ arabluatex.tooutfile(tofile)
+ else
+ return str
+ end
+ return ""
+end
+
+function arabluatex.uc(str)
+ str = string.gsub(str, "(\\txtrans.?)(%b{})", function(tag, body)
+ body = string.sub(body, 2, -2)
+ return string.format("%s", body)
+ end)
+ str = string.gsub(str, "{", "\\@al@ob")
+ str = string.gsub(str, "} ", "\\@al@cb@sp ")
+ str = string.gsub(str, "}", "\\@al@cb")
+ -- Allah and ibn
+ str = string.gsub(str, "(al%-lÄh)([uai]?)", "{AllÄh%2}")
+ str = string.gsub(str, "([%'%-]?)(l%-lÄh)([uai]?)", "%1{LlÄh%3}")
+ str = string.gsub(str, "(%s[%(%<%[]?)([i%']?b[n%.])", "%1{%2}")
+ for i = 1,#lcuc do
+ str = string.gsub(str, "^([%S]-%-[`']?)"..lcuc[i].a, "{%1"..lcuc[i].b.."}")
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "(%s[%(%<%[]?)([%S]-%-[`']?)"..lcuc[i].a, "%1{%2"..lcuc[i].b.."}")
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "^([%S]-%-Ê¿)"..lcuc[i].a, "{%1"..lcuc[i].b.."}")
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "(%s[%(%<%[]?)([%S]-%-Ê¿)"..lcuc[i].a, "%1{%2"..lcuc[i].b.."}")
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "^([%S]-%-ʾ)"..lcuc[i].a, "{%1"..lcuc[i].b.."}")
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "(%s[%(%<%[]?)([%S]-%-ʾ)"..lcuc[i].a, "%1{%2"..lcuc[i].b.."}")
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "^([`'])"..lcuc[i].a, "{%1"..lcuc[i].b.."}")
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "(%s[%(%<%[]?)([`'])"..lcuc[i].a, "%1{%2"..lcuc[i].b.."}")
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "^(ʾ)"..lcuc[i].a, "{%1"..lcuc[i].b.."}")
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "(%s[%(%<%[]?)(ʾ)"..lcuc[i].a, "%1{%2"..lcuc[i].b.."}")
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "^(Ê¿)"..lcuc[i].a, "{%1"..lcuc[i].b.."}")
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "(%s[%(%<%[]?)(Ê¿)"..lcuc[i].a, "%1{%2"..lcuc[i].b.."}")
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "^"..lcuc[i].a, lcuc[i].b)
+ end
+ for i = 1,#lcuc do
+ str = string.gsub(str, "(%s[%(%<%[]?)"..lcuc[i].a, "%1"..lcuc[i].b)
+ end
+ str = string.gsub(str, "{", "")
+ str = string.gsub(str, "}", "")
+ str = string.gsub(str, "\\@al@ob", "{")
+ str = string.gsub(str, "\\@al@cb@sp ", "} ")
+ str = string.gsub(str, "\\@al@cb", "}")
+ if export_utf == "yes" then
+ tofile = str
+ arabluatex.tooutfile(tofile)
+ elseif export_utf == "arabverse" then
+ tofile = str
+ arabluatex.tooutfile(tofile)
+ else
+ return str
+ end
+ return ""
+end
+
+-- this function is adapted from an 'obsolete project' of Khaled
+-- Hosny's that dates back to 2010. Thanks to him.
+-- See https://github.com/khaledhosny/lualatex-arabic
+function arabluatex.abjadify(n)
+ local abjadnum = ""
+ n = tonumber(n)
+ if n >= 1000 then
+ for i=1,math.floor(n/1000) do
+ abjadnum = abjadnum .. abjad[4][1]
+ end
+ n = math.fmod(n,1000)
+ end
+ if n >= 100 then
+ abjadnum = abjadnum .. abjad[3][math.floor(n/100)]
+ n = math.fmod(n, 100)
+ end
+ if n >= 10 then
+ abjadnum = abjadnum .. abjad[2][math.floor(n/10)]
+ n = math.fmod(n, 10)
+ end
+ if n >= 1 then
+ abjadnum = abjadnum .. abjad[1][math.floor(n/1)]
+ end
+ return "\\arb[novoc]{"..abjadnum.."}"
+end
+
+function arabluatex.abraces(str)
+ if tex.textdir == "TRT" then
+ str = "\\}"..str.."\\{"
+ elseif tex.textdir == "TLT" then
+ str = "\\{"..str.."\\}"
+ end
+ return str
+end
+
+function arabluatex.aemph(str, opt)
+ if tex.textdir == "TRT" then
+ str = "\\oline{\\textdir TRT{}"..str.."}"
+ elseif tex.textdir == "TLT" then
+ if opt == "over" then
+ str = "\\oline{"..str.."}"
+ else
+ str = "\\uline{"..str.."}"
+ end
+ end
+ return str
+end
+
+function arabluatex.ayah(str)
+ if tonumber(str) ~= nil and str.len(str) < 4 then
+ if tex.textdir == "TRT" then
+ str = indnum(str).."^^^^06dd"
+ elseif tex.textdir == "TLT" then
+ str = "\\arb[trans]{("..str..")}"
+ end
+ return str
+ else
+ return "\\LR{<??>}"
+ end
+end
diff --git a/macros/luatex/latex/arabluatex/arabluatex.pdf b/macros/luatex/latex/arabluatex/arabluatex.pdf
new file mode 100644
index 0000000000..5374b0aef2
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/arabluatex.pdf
Binary files differ
diff --git a/macros/luatex/latex/arabluatex/arabluatex_fullvoc.lua b/macros/luatex/latex/arabluatex/arabluatex_fullvoc.lua
new file mode 100644
index 0000000000..f524c3b6d9
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/arabluatex_fullvoc.lua
@@ -0,0 +1,1015 @@
+--[[
+This file is part of the `arabluatex' package
+
+ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX
+Copyright (C) 2016--2019 Robert Alessi
+
+Please send error reports and suggestions for improvements to Robert
+Alessi <alessi@robertalessi.net>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see
+<http://www.gnu.org/licenses/>.
+--]]
+
+hamzafv = {
+ -- next line for ʾiÊ¿rÄb hyphen
+ {a="(')(%-)([uaiUAI])", b="%1%3"},
+ -- next lines for ʾalif alone
+ {a="(%.A)([uai]?)l%-(%^n)", b="ا%2ل%3"}, --additional (^n is lunar)
+ {a="([%(%[%|%<%s%-O])(%.A)([uai]?)l%-(%^n)", b="%1ا%3%4"}, --additional (^n is lunar) --p
+ {a="(%.A)([uai]?)l%-([%_%^%.]?[tdrzsnc])", b="ا%2ل%3%3"},
+ {a="([%(%[%|%<%s%-O])(%.A)([uai]?)l%-([%_%^%.]?[tdrzsnc])", b="%1ا%3ل%4%4"}, --p
+ {a="%.A", b="ا"},
+ -- hard coded hamza
+ {a="|\"'", b="Ø¡"},
+ {a="A\"'", b="Ø¢"},
+ {a="[au]\"'", b="Ø£"},
+ {a="w\"'", b="ؤ"},
+ {a="i\"'", b="Ø¥"},
+ {a="y\"'", b="ئ"},
+ {a="ؤ([^uaiUAI])", b="ؤْ%1"},
+ {a="ؤ(%p*)$", b="ؤْ%1"},
+ {a="ؤ(%p*%s)", b="ؤْ%1"},
+ {a="أ([^uaiUAI])", b="أْ%1"},
+ {a="أ(%p*)$", b="أْ%1"},
+ {a="أ(%p*%s)", b="أْ%1"},
+ {a="ئ([^uaiUAI])", b="ئْ%1"},
+ {a="ئ(%p*)$", b="ئْ%1"},
+ {a="ئ(%p*%s)", b="ئْ%1"},
+ -- hamza takes tašdīd too
+ {a="''([Uu])", b="ؤؤ%1"},
+ {a="''([Aa])", b="أأ%1"},
+ {a="''([Ii])", b="ئئ%1"},
+ -- inseparable adverbial particle 'a- + 'a
+ {a="\'(a)%-\'(a)", b="أ%1اأ%2"},
+ -- initial long u and i (for a, see below)
+ {a="%'%_U", b="Ø£U"},
+ {a="%'%_I", b="Ø¥I"},
+ -- taḫfīfu 'l-hamza
+ {a="'u'([^uaiUAI])", b="Ø£U%1"},
+ {a="'i'([^uaiUAI])", b="Ø¥I%1"},
+ {a="([wf]a)%-\'([^uaiUAIl][^%-])", b="%1أْ%2"},
+ {a="^u'([^uaiUAI])", b="اU%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])u'([^uaiUAI])", b="%1اU%2"},
+ {a="^i'([^uaiUAI])", b="اI%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])i'([^uaiUAI])", b="%1اI%2"},
+ -- madda (historic writing below)
+ {a="'a'([^uaiUAI])", b="Ø¢%1"},
+ {a="([^uiyUI])\'a?A([%_%^%.]?[%`%'btjghxdrzsfqklmnywAY])", b="%1Ø¢%2"},
+ {a="^\'a?A([%_%^%.]?[%`%'btjghxdrzsfqklmnywAY])", b="Ø¢%1"},
+ {a="\'a?A(O[%_%^%.]?[%`%'btjghxdrzsfqklmnywAY]-O)", b="Ø¢"},
+ {a="(%W)\'a?A([%_%^%.]?[%`%'btjghxdrzsfqklmnywAY])", b="%1Ø¢%2"},
+ {a="(A)(O%'[%S]-O)", b="Ø¢"},
+ {a="(A)(')(uN?%p*)$", b="aآء%3"},
+ {a="(A)(')(uN?)(%p*%s)", b="aآء%3%4"},
+ {a="(A)(')(iN?%p*)$", b="aآء%3"},
+ {a="(A)(')(iN?)(%p*%s)", b="aآء%3%4"},
+ {a="(A)(')([iI])", b="aآئ%3"}, -- historic madda
+ {a="(A)(')(u)", b="aآؤ%3"}, -- historic madda
+ {a="(A)(')", b="aآء"}, -- historic madda
+ -- initial (needs both ^ and %W patterns)
+ -- 'aw: the diphthong is to be resolved into 'awi' (next 8 lines)
+ {a="^('aw)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(%W)('aw)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1%2i"},
+ {a="^('aw)(O)([%(%[%|%<]?\"?[uai])([%S]-O)", b="%1i"},
+ {a="(%W)('aw)(O)([%(%[%|%<]?\"?[uai])([%S]-O)", b="%1%2i"},
+ {a="^('aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ {a="(%W)('aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1%2i%3%4"},
+ {a="^('aw)(%s)([%(%[%|%<]?\"?[uai])", b="%1i%2%3"},
+ {a="(%W)('aw)(%s)([%(%[%|%<]?\"?[uai])", b="%1%2i%3%4"},
+ -- then the 'initial' rules for the remaining cases
+ {a="^(')([ua])", b="Ø£%2"},
+ {a="^(')(i)", b="Ø¥%2"},
+ -- consider replacing initial %W with [%s%(%[%<%-]:
+ -- {a="(%W)(')([ua])", b="%1Ø£%3"},
+ -- {a="(%W)(')(i)", b="%1Ø¥%3"},
+ {a="([%s%(%[%<%-])(')([ua])", b="%1Ø£%3"},
+ {a="([%s%(%[%<%-])(')(i)", b="%1Ø¥%3"},
+ -- final
+ -- mi'aT is special orthography (unlike ^say'aN and .zim'aN):
+ -- {a="(%^sa%.?[yY])(\"?%|?)(%')(aN)", b="%1%2ئ%4"}, --new
+ -- {a="(.zi?m)(%')(aN)", b="%1ئ%3"}, --new
+ {a="(mi)(%')(a[Tt])", b="%1ائ%3"},
+ {a="(mi)(%')(aN%_?[AY])", b="%1Ø£%3"},
+ -- final hamzah is on the line after a letter of prolongation or a
+ -- consonant with sukūn
+ {a="([^Auai])(')(\"?[uai]N?)(%p*)$", b="%1Ø¡%3%4"}, --new
+ {a="([^Auai])(')(\"?[uai]N?)(%p*%s)", b="%1Ø¡%3%4"},
+-- u
+ {a="(u)(')([uai]N?%p*)$", b="%1ؤ%3"},
+ {a="(u)(')([uai]N?)(%p*%s)", b="%1ؤ%3%4"},
+ {a="(u)(')(%p*)$", b="%1ؤْ%3"},
+ {a="(u)(')(%p*%s)", b="%1ؤْ%3"},
+-- a
+ {a="(a)(')(A%p*)$", b="%1Ø¢"},
+ {a="(a)(')(A)(%p*%s)", b="%1Ø¢%4"},
+ {a="(a)(')([u]N?%p*)$", b="%1Ø£%3"},
+ {a="(a)(')([u]N?)(%p*%s)", b="%1Ø£%3%4"},
+ {a="(a)(')(a%p*)$", b="%1Ø£%3"},
+ {a="(a)(')(a)(%p*%s)", b="%1Ø£%3%4"},
+ {a="(a)(')(aN%p*)$", b="%1أً"},
+ {a="(a)(')(aN)(%p*%s)", b="%1أً%4"},
+ {a="(a)(')([i]N?%p*)$", b="%1Ø¥%3"},
+ {a="(a)(')([i]N?)(%p*%s)", b="%1Ø¥%3%4"},
+ {a="(a)(')(%p*)$", b="%1أْ%3"},
+ {a="(a)(')(%p*%s)", b="%1أْ%3"},
+-- i
+ {a="(i)(')([uai]N?%p*)$", b="%1ئ%3"},
+ {a="(i)(')([uai]N?)(%p*%s)", b="%1ئ%3%4"},
+ {a="(i)(')(%p*)$", b="%1ئْ%3"},
+ {a="(i)(')(%p*%s)", b="%1ئْ%3"},
+--
+ -- middle
+ {a="([UIwy])(')", b="%1Ø¡"}, --new
+ -- {a="([Iy])(')", b="%1ئ"}, --included in the above line
+ {a="([^uai])(')([uU])", b="%1ؤ%3"},
+ {a="([^uai])(')(%_?[aAY])", b="%1Ø£%3"},
+ {a="([^uai])(')([iI])", b="%1ئ%3"},
+ {a="(u)(')([uU])", b="%1ؤ%3"},
+ {a="(u)(')(%_?[aAY])", b="%1ؤ%3"},
+ {a="(u)(')([iI])", b="%1ئ%3"},
+ {a="(a)(')(%_?[aAY])", b="%1Ø£%3"},
+ {a="(a)(')([uU])", b="%1ؤ%3"},
+ {a="(a)(')([iI])", b="%1ئ%3"},
+ {a="(i)(')(%_?[aAY])", b="%1ئ%3"},
+ {a="(i)(')([uU])", b="%1ئ%3"},
+ {a="(i)(')([iI])", b="%1ئ%3"},
+ {a="(a)(')([^uaiUAI])", b="%1أْ%3"},
+ {a="(u)(')([^uaiUAI])", b="%1ؤْ%3"},
+ {a="(i)(')([^uaiUAI])", b="%1ئْ%3"}
+}
+
+hamzafveasy = { -- differences marked below with 'easy'
+ -- next line for ʾiÊ¿rÄb hyphen
+ {a="(')(%-)([uaiUAI])", b="%1%3"},
+ -- next lines for ʾalif alone
+ {a="(%.A)([uai]?)l%-(%^n)", b="ا%2ل%3"}, --additional (^n is lunar)
+ {a="([%(%[%|%<%s%-O])(%.A)([uai]?)l%-(%^n)", b="%1ا%3%4"}, --additional (^n is lunar) --p
+ {a="(%.A)([uai]?)l%-([%_%^%.]?[tdrzsnc])", b="ا%2ل%3%3"},
+ {a="([%(%[%|%<%s%-O])(%.A)([uai]?)l%-([%_%^%.]?[tdrzsnc])", b="%1ا%3ل%4%4"}, --p
+ {a="%.A", b="ا"},
+ -- hard coded hamza
+ {a="|\"'", b="Ø¡"},
+ {a="A\"'", b="Ø¢"},
+ {a="[au]\"'", b="Ø£"},
+ {a="w\"'", b="ؤ"},
+ {a="i\"'", b="Ø¥"},
+ {a="y\"'", b="ئ"},
+ {a="ؤ([^uaiUAI])", b="ؤْ%1"},
+ {a="ؤ(%p*)$", b="ؤْ%1"},
+ {a="ؤ(%p*%s)", b="ؤْ%1"},
+ {a="أ([^uaiUAI])", b="أْ%1"},
+ {a="أ(%p*)$", b="أْ%1"},
+ {a="أ(%p*%s)", b="أْ%1"},
+ {a="ئ([^uaiUAI])", b="ئْ%1"},
+ {a="ئ(%p*)$", b="ئْ%1"},
+ {a="ئ(%p*%s)", b="ئْ%1"},
+ -- hamza takes tašdīd too
+ {a="''([Uu])", b="ؤؤ%1"},
+ {a="''([Aa])", b="أأ%1"},
+ {a="''([Ii])", b="ئئ%1"},
+ -- inseparable adverbial particle 'a- + 'a
+ {a="\'(a)%-\'(a)", b="أ%1اأ%2"},
+ -- initial long u and i (for a, see below)
+ {a="%'%_U", b="Ø£U"},
+ {a="%'%_I", b="Ø¥I"},
+ -- taḫfīfu 'l-hamza
+ {a="'u'([^uaiUAI])", b="Ø£U%1"},
+ {a="'i'([^uaiUAI])", b="Ø¥I%1"},
+ {a="([wf]a)%-\'([^uaiUAIl][^%-])", b="%1أْ%2"},
+ {a="^u'([^uaiUAI])", b="اU%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])u'([^uaiUAI])", b="%1اU%2"},
+ {a="^i'([^uaiUAI])", b="اI%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])i'([^uaiUAI])", b="%1اI%2"},
+ -- madda (historic writing below)
+ {a="'a'([^uaiUAI])", b="Ø¢%1"},
+ {a="([^uiyUI])\'a?A([%_%^%.]?[%`%'btjghxdrzsfqklmnywAY])", b="%1Ø¢%2"},
+ {a="^\'a?A([%_%^%.]?[%`%'btjghxdrzsfqklmnywAY])", b="Ø¢%1"},
+ {a="\'a?A(O[%_%^%.]?[%`%'btjghxdrzsfqklmnywAY]-O)", b="Ø¢"},
+ {a="(%W)\'a?A([%_%^%.]?[%`%'btjghxdrzsfqklmnywAY])", b="%1Ø¢%2"},
+ --easy (begin)
+ {a="(A)(O%'[%S]-O)", b="ا"},
+ {a="(A)(')(uN?%p*)$", b="aاء%3"},
+ {a="(A)(')(uN?)(%p*%s)", b="aاء%3%4"},
+ {a="(A)(')(iN?%p*)$", b="aاء%3"},
+ {a="(A)(')(iN?)(%p*%s)", b="aاء%3%4"},
+ {a="(A)(')([iI])", b="aائ%3"}, -- historic madda
+ {a="(A)(')(u)", b="aاؤ%3"}, -- historic madda
+ {a="(A)(')", b="aاء"}, -- historic madda
+ --easy (end)
+ -- initial (needs both ^ and %W patterns)
+ -- 'aw: the diphthong is to be resolved into 'awi' (next 8 lines)
+ {a="^('aw)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(%W)('aw)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1%2i"},
+ {a="^('aw)(O)([%(%[%|%<]?\"?[uai])([%S]-O)", b="%1i"},
+ {a="(%W)('aw)(O)([%(%[%|%<]?\"?[uai])([%S]-O)", b="%1%2i"},
+ {a="^('aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ {a="(%W)('aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1%2i%3%4"},
+ {a="^('aw)(%s)([%(%[%|%<]?\"?[uai])", b="%1i%2%3"},
+ {a="(%W)('aw)(%s)([%(%[%|%<]?\"?[uai])", b="%1%2i%3%4"},
+ -- then the 'initial' rules for the remaining cases
+ {a="^(')([ua])", b="Ø£%2"},
+ {a="^(')(i)", b="Ø¥%2"},
+ -- consider replacing initial %W with [%s%(%[%<%-]:
+ -- {a="(%W)(')([ua])", b="%1Ø£%3"},
+ -- {a="(%W)(')(i)", b="%1Ø¥%3"},
+ {a="([%s%(%[%<%-])(')([ua])", b="%1Ø£%3"},
+ {a="([%s%(%[%<%-])(')(i)", b="%1Ø¥%3"},
+ -- final
+ -- mi'aT is special orthography (unlike ^say'aN and .zim'aN)
+ -- {a="(%^sa%.?[yY])(\"?%|?)(%')(aN)", b="%1%2ئ%4"}, --new
+ -- {a="(.zi?m)(%')(aN)", b="%1ئ%3"}, --new
+ {a="(mi)(%')(a[Tt])", b="%1ائ%3"},
+ {a="(mi)(%')(aN%_?[AY])", b="%1Ø£%3"},
+ -- easy (begin)
+ -- The Munjid says that such words as radI'aN do not have the
+ -- hamzah alone on the line, so take out the following two lines
+ -- (final hamzah is on the line after a letter of prolongation or a
+ -- consonant with sukūn)
+ -- {a="([^Auai])(')(\"?[uai]N?)(%p*)$", b="%1Ø¡%3%4"}, --new
+ -- {a="([^Auai])(')(\"?[uai]N?)(%p*%s)", b="%1Ø¡%3%4"},
+ {a="([^Auai])(')(\"?aN)(%p*)$", b="%1ئ%3%4"}, --new
+ {a="([^Auai])(')(\"?aN)(%p*%s)", b="%1ئ%3%4"}, --new
+ {a="([^uai])(')(\"?a)(%p*)$", b="%1Ø¡%3%4"}, --new
+ {a="([^uai])(')(\"?a)(%p*%s)", b="%1Ø¡%3%4"}, --new
+ {a="([^uai])(')(\"?[ui]N?)(%p*)$", b="%1Ø¡%3%4"}, --new
+ {a="([^uai])(')(\"?[ui]N?)(%p*%s)", b="%1Ø¡%3%4"}, --new
+ --easy (end)
+-- u
+ {a="(u)(')([uai]N?%p*)$", b="%1ؤ%3"},
+ {a="(u)(')([uai]N?)(%p*%s)", b="%1ؤ%3%4"},
+ {a="(u)(')(%p*)$", b="%1ؤْ%3"},
+ {a="(u)(')(%p*%s)", b="%1ؤْ%3"},
+-- a
+ {a="(a)(')(A%p*)$", b="%1Ø¢"},
+ {a="(a)(')(A)(%p*%s)", b="%1Ø¢%4"},
+ {a="(a)(')([u]N?%p*)$", b="%1Ø£%3"},
+ {a="(a)(')([u]N?)(%p*%s)", b="%1Ø£%3%4"},
+ {a="(a)(')(a%p*)$", b="%1Ø£%3"},
+ {a="(a)(')(a)(%p*%s)", b="%1Ø£%3%4"},
+ {a="(a)(')(aN%p*)$", b="%1أً"},
+ {a="(a)(')(aN)(%p*%s)", b="%1أً%4"},
+ {a="(a)(')([i]N?%p*)$", b="%1Ø¥%3"},
+ {a="(a)(')([i]N?)(%p*%s)", b="%1Ø¥%3%4"},
+ {a="(a)(')(%p*)$", b="%1أْ%3"},
+ {a="(a)(')(%p*%s)", b="%1أْ%3"},
+-- i
+ {a="(i)(')([uai]N?%p*)$", b="%1ئ%3"},
+ {a="(i)(')([uai]N?)(%p*%s)", b="%1ئ%3%4"},
+ {a="(i)(')(%p*)$", b="%1ئْ%3"},
+ {a="(i)(')(%p*%s)", b="%1ئْ%3"},
+--
+ -- middle
+ {a="([Uw])(')", b="%1Ø¡"}, --new
+ {a="([Iy])(')", b="%1ئ"}, --easy
+ {a="([^uai])(')([uU])", b="%1ؤ%3"},
+ {a="([^uai])(')(%_?[aAY])", b="%1Ø£%3"},
+ {a="([^uai])(')([iI])", b="%1ئ%3"},
+ {a="(u)(')([uU])", b="%1ؤ%3"},
+ {a="(u)(')(%_?[aAY])", b="%1ؤ%3"},
+ {a="(u)(')([iI])", b="%1ئ%3"},
+ {a="(a)(')(%_?[aAY])", b="%1Ø£%3"},
+ {a="(a)(')([uU])", b="%1ؤ%3"},
+ {a="(a)(')([iI])", b="%1ئ%3"},
+ {a="(i)(')(%_?[aAY])", b="%1ئ%3"},
+ {a="(i)(')([uU])", b="%1ئ%3"},
+ {a="(i)(')([iI])", b="%1ئ%3"},
+ {a="(a)(')([^uaiUAI])", b="%1أْ%3"},
+ {a="(u)(')([^uaiUAI])", b="%1ؤْ%3"},
+ {a="(i)(')([^uaiUAI])", b="%1ئْ%3"}
+}
+
+tanwinfv = { -- with assimilations (\SetArbDflt*)
+ -- assimilations (begin)
+ {a="(O[%S]-)(%-?[uai]N[UI]?)(O)([rlmnwy])", b="%4%4"},
+ {a="(%-?[uai]NU)(%s)([rlmnwy])", b="%1%2%3%3"},
+ -- assimilations (end)
+ {a="(O[%S]-)(%-?[uai]N[UI]?)(O)([uai])", b="Ù±"},
+ {a="%-?(uNU)(%s)([uai])", b="%1%2Ù±"},
+ {a="%-?(aNU)(%s)([uai])", b="%1%2Ù±"},
+ {a="%-?(iNU)(%s)([uai])", b="%1%2Ù±"},
+ {a="%-?uNU", b="ٌو"},
+ {a="%-?aNU", b="ًوا"},
+ {a="%-?iNU", b="ÙÙˆ"},
+ {a="%-?([uai]N)(%s)([uai])", b="%1%2Ù±"},
+ {a="%-?(aN[%_]?[AY])(%s)([uai])", b="%1%2Ù±"},
+ -- assimilations (begin)
+ {a="%-?(uN)(%s)([rlmnwy])", b="ٌ%2%3%3"},
+ {a="(O[%S]-)(%-?aN)(_A)(O)([rlmnwy])", b="%5%5"},
+ {a="(O[%S]-)(%-?aN)(Y)(O)([rlmnwy])", b="%5%5"},
+ {a="%-?(aN)(_A)(%s)([rlmnwy])", b="ًى%3%4%4"},
+ {a="%-?(aN)(Y)(%s)([rlmnwy])", b="ًى%3%4%4"},
+ {a="(T)%-?(aN)(%s)([rlmnwy])", b="%1Ù‹%3%4%4"},
+-- {a="(Ø¡)%-?(aN)(%s)([rlmnwy])", b="%1%2%3%4%4"}, --new
+ {a="([^TA])%-?(aN)(%s)([rlmnwy])", b="%1ًا%3%4%4"},
+ {a="%-?(iNI?)(%s)([rlmnwy])", b="Ù%2%3%3"},
+ -- assimilations (end)
+ {a="(O[%S]-)(%-?aN)(_A)(O)([uai])", b="Ù±"},
+ {a="(O[%S]-)(%-?aN)(Y)(O)([uai])", b="Ù±"},
+ -- quoted tanwīn (begin)
+ {a="%-?(\"uN)", b=""},
+ {a="(B)%-?(\"aN)", b="%1"},
+ {a="%-?(\"aN)(_A)", b="Ù‰"},
+ {a="%-?(\"aN)(Y)", b="Ù‰"},
+ {a="(T)%-?(\"aN)", b="%1"},
+ {a="([اآ])(ء)%-?(\"aN)", b="%1%2"}, --new
+ {a="([^TA])%-?(\"aN)", b="%1ا"},
+ {a="%-?(\"iNI?)", b=""},
+ -- quoted tanwīn (end)
+ {a="%-?(uN)", b="ٌ"},
+ {a="(B)%-?(aN)", b="%1Ù‹"},
+ -- needed by \arbcolor:
+ {a="%-?(aN)(O[%S]-%_AO)", b="Ù‹"},
+ {a="%-?(aN)(O[%S]-YO)", b="Ù‹"},
+ {a="(O[%S]-TO)%-?(aN)", b="Ù‹"},
+ {a="(O[%S]-)([اآ])(ء)(O)%-?(aN)", b="ً"}, --new
+ {a="(O[%S]-[^TA]O)%-?(aN)", b="ًا"},
+ --
+ {a="%-?(aN)(_A)", b="ًى"},
+ {a="%-?(aN)(Y)", b="ًى"},
+ {a="(T)%-?(aN)", b="%1Ù‹"},
+ {a="([اآ])(ء)%-?(aN)", b="%1%2ً"}, --new
+ {a="([^TA])%-?(aN)", b="%1ًا"},
+ {a="%-?(iNI?)", b="Ù"}
+}
+
+tanwinfveasy = { -- no assimilations (see below)
+ -- assimilations (begin)
+--easy {a="(O[%S]-)(%-?[uai]N[UI]?)(O)([rlmnwy])", b="%4%4"},
+--easy {a="(%-?[uai]NU)(%s)([rlmnwy])", b="%1%2%3%3"},
+ -- assimilations (end)
+ {a="(O[%S]-)(%-?[uai]N[UI]?)(O)([uai])", b="Ù±"},
+ {a="%-?(uNU)(%s)([uai])", b="%1%2Ù±"},
+ {a="%-?(aNU)(%s)([uai])", b="%1%2Ù±"},
+ {a="%-?(iNU)(%s)([uai])", b="%1%2Ù±"},
+ {a="%-?uNU", b="ٌو"},
+ {a="%-?aNU", b="ًوا"},
+ {a="%-?iNU", b="ÙÙˆ"},
+ {a="%-?([uai]N)(%s)([uai])", b="%1%2Ù±"},
+ {a="%-?(aN[%_]?[AY])(%s)([uai])", b="%1%2Ù±"},
+ -- assimilations (begin)
+--easy {a="%-?(uN)(%s)([rlmnwy])", b="ٌ%2%3%3"},
+--easy {a="(O[%S]-)(%-?aN)(_A)(O)([rlmnwy])", b="%5%5"},
+--easy {a="(O[%S]-)(%-?aN)(Y)(O)([rlmnwy])", b="%5%5"},
+--easy {a="%-?(aN)(_A)(%s)([rlmnwy])", b="ًى%3%4%4"},
+--easy {a="%-?(aN)(Y)(%s)([rlmnwy])", b="ًى%3%4%4"},
+--easy {a="(T)%-?(aN)(%s)([rlmnwy])", b="%1Ù‹%3%4%4"},
+--easy {a="(Ø¡)%-?(aN)(%s)([rlmnwy])", b="%1%2%3%4%4"}, --new
+--easy {a="([^TA])%-?(aN)(%s)([rlmnwy])", b="%1ًا%3%4%4"},
+--easy {a="%-?(iNI?)(%s)([rlmnwy])", b="Ù%2%3%3"},
+ -- assimilations (end)
+ {a="(O[%S]-)(%-?aN)(_A)(O)([uai])", b="Ù±"},
+ {a="(O[%S]-)(%-?aN)(Y)(O)([uai])", b="Ù±"},
+ -- quoted tanwīn (begin)
+ {a="%-?(\"uN)", b=""},
+ {a="(B)%-?(\"aN)", b="%1"},
+ {a="%-?(\"aN)(_A)", b="Ù‰"},
+ {a="%-?(\"aN)(Y)", b="Ù‰"},
+ {a="(T)%-?(\"aN)", b="%1"},
+ {a="([اآ])(ء)%-?(\"aN)", b="%1%2"}, --new
+ {a="([^TA])%-?(\"aN)", b="%1ا"},
+ {a="%-?(\"iNI?)", b=""},
+ -- quoted tanwīn (end)
+ {a="%-?(uN)", b="ٌ"},
+ {a="(B)%-?(aN)", b="%1Ù‹"},
+ -- needed by \arbcolor:
+ {a="%-?(aN)(O[%S]-%_AO)", b="Ù‹"},
+ {a="%-?(aN)(O[%S]-YO)", b="Ù‹"},
+ {a="(O[%S]-TO)%-?(aN)", b="Ù‹"},
+ {a="(O[%S]-)([اآ])(ء)(O)%-?(aN)", b="ً"}, --new
+ {a="(O[%S]-[^TA]O)%-?(aN)", b="ًا"},
+ --
+ {a="%-?(aN)(_A)", b="ًى"},
+ {a="%-?(aN)(Y)", b="ًى"},
+ {a="(T)%-?(aN)", b="%1Ù‹"},
+ {a="([اآ])(ء)%-?(aN)", b="%1%2ً"}, --new
+ {a="([^TA])%-?(aN)", b="%1ًا"},
+ {a="%-?(iNI?)", b="Ù"}
+}
+
+trigraphsfv = { -- trigraphs or more
+ -- ʾalif al-waṣl: put it back on with \arbnull
+ {a="(O[%S]-)([%'a]l%-)(O)(\"?[uai])", b="Ù±"},
+ -- 'llatI / 'llad_I
+ {a="^'ll(a)([%_]?[dt])", b="ٱلّ%1%2"},
+ {a="([%(%[%|%<%s%-])'ll(a)([%_]?[dt])", b="%1ٱلّ%2%3"}, --p
+ -- law: the diphthong is to be resolved into 'awi' (next 8 lines)
+ {a="^(law)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(%W)(law)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1%2i"},
+ {a="^(law)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(%W)(law)(O)(\"?[uai])([%S]-O)", b="%1%2i"},
+ {a="^(law)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ {a="(%W)(law)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1%2i%3%4"},
+ {a="^(law)(%s)([%(%[%|%<]?\"?[uai])", b="%1i%2%3"},
+ {a="(%W)(law)(%s)([%(%[%|%<]?\"?[uai])", b="%1%2i%3%4"},
+ -- al- + lÄm
+ {a="^(a)l%-(l)", b="ا%1ل%2%2"},
+ {a="([%(%[%|%<%s%-O])(a)l%-(l)", b="%1ا%2ل%3%3"}, --p
+ -- al- + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)l%-(%^n)", b="ا%1ل%2"}, -- ^n is lunar
+ {a="([%(%[%|%<%s%-O])(a)l%-(%^n)", b="%1ا%2ل%3"}, -- ^n is lunar --p
+ {a="^(a)l%-([%_%^%.]?[tdrzsnc])", b="ا%1ل%2%2"},
+ {a="([%(%[%|%<%s%-O])(a)l%-([%_%^%.]?[tdrzsnc])", b="%1ا%2ل%3%3"}, --p
+ -- assim. art. + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)(%^n)%-", b="ا%1ل"}, -- ^n is lunar
+ {a="([%(%[%|%<%s%-O])(a)(%^n)%-", b="%1ا%2ل"}, -- ^n is lunar --p
+ {a="^(a)([%_%^%.]?[tdrzsnc])%-", b="ا%1ل%2"},
+ {a="([%(%[%|%<%s%-O])(a)([%_%^%.]?[tdrzsnc])%-", b="%1ا%2ل%3"}, --p
+ -- al- + initial unstable hamza
+ {a="^(a)l%-(\"?[uai])", b="ا%1ل%2ٱ"},
+ {a="([%(%[%|%<%s%-O])(a)l%-(\"?[uai])", b="%1ا%2ل%3ٱ"}, --p
+ -- li-/la + art. + initial unstable hamza is a special orthography
+ {a="l([ai])%-l%-(\"?[uai])", b="Ù„%1Ù„%2Ù±"},
+ -- al- + lunar consonant (i.e. what remains)
+ {a="^(a)l%-", b="ا%1لْ"},
+ {a="([%(%[%|%<%s%-O])(a)l%-", b="%1ا%2لْ"}, --p
+ -- diphthongs to be resolved before ʾalif conjunctionis
+ {a="(aW)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="awuا"},
+ {a="(aw)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1u"},
+ {a="(ay)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(aW)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="awuا%2%3"},
+ {a="(aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1u%2%3"},
+ {a="(ay)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ -- art. with waá¹£la + lÄm
+ {a="'l%-(l)", b="ٱل%1%1"},
+ -- art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are additional characters)
+ {a="'l%-(%^n)", b="ٱل%1"}, -- ^n is lunar
+ {a="'l%-([%_%^%.]?[tdrzsnc])", b="ٱل%1%1"},
+ -- li-/la- + art. + lÄm
+ {a="l([ai])%-l%-(l)", b="Ù„%1%2%2"},
+ -- assim. art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are additional characters)
+ {a="'(%^n)%-", b="ٱل"}, -- ^n is lunar
+ {a="'([%_%^%.]?[tdrzsnc])%-", b="ٱل%1"},
+ -- li-/la- + art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-l%-(%^n)", b="Ù„%1Ù„%2"}, -- ^n is lunar
+ {a="l([ai])%-l%-([%_%^%.]?[tdrzsnc])", b="Ù„%1Ù„%2%2"},
+ -- li-/la- + assim. art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-(%^n)%-(%^n)", b="Ù„%1Ù„%3"}, -- ^n is lunar
+ {a="l([ai])%-([%_%^%.]?[tdrzsnc])%-([%_%^%.]?[tdrzsnc])", b="Ù„%1Ù„%3%3"},
+ -- art. with waá¹£la + initial unstable hamza
+ {a="'l%-(\"?[uai])", b="ٱل%1ٱ"},
+ -- art. with waá¹£la + lunar consonant (i.e. what remains)
+ {a="'l%-", b="ٱلْ"},
+ -- the silent wÄw
+ {a="uU(%p*)$", b="uÙˆ%1"},
+ {a="uU(%p*%s)", b="uÙˆ%1"},
+ {a="aU(%p*)$", b="aÙˆ%1"},
+ {a="aU(%p*%s)", b="aÙˆ%1"},
+ {a="iU(%p*)$", b="iÙˆ%1"},
+ {a="iU(%p*%s)", b="iÙˆ%1"},
+ -- words ending in -ÄT with silent wÄw/yÄʾ
+ {a="(_a)UA", b="%1وا"},
+ {a="(_a)U", b="%1Ùˆ"},
+ {a="(_a)I", b="%1ÙŠ"}
+}
+
+-- idgham/assimilation rules for trigraphs apply here : see voc lua
+-- file.
+
+trigraphsfveasy = { -- trigraphs or more (see 'easy' tag below for the diffs)
+ -- ʾalif al-waṣl: put it back on with \arbnull
+ {a="(O[%S]-)([%'a]l%-)(O)(\"?[uai])", b="Ù±"},
+ -- 'llatI / 'llad_I
+ {a="^'ll(a)([%_]?[dt])", b="ٱلّ%1%2"},
+ {a="([%(%[%|%<%s%-])'ll(a)([%_]?[dt])", b="%1ٱلّ%2%3"}, --p
+ -- law: the diphthong is to be resolved into 'awi' (next 8 lines)
+ {a="^(law)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(%W)(law)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1%2i"},
+ {a="^(law)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(%W)(law)(O)(\"?[uai])([%S]-O)", b="%1%2i"},
+ {a="^(law)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ {a="(%W)(law)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1%2i%3%4"},
+ {a="^(law)(%s)([%(%[%|%<]?\"?[uai])", b="%1i%2%3"},
+ {a="(%W)(law)(%s)([%(%[%|%<]?\"?[uai])", b="%1%2i%3%4"},
+ -- al- + lÄm
+ {a="^(a)l%-(l)", b="ا%1ل%2%2"},
+ {a="([%(%[%|%<%s%-O])(a)l%-(l)", b="%1ا%2ل%3%3"}, --p
+ -- al- + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)l%-(%^n)", b="ا%1ل%2"}, -- ^n is lunar
+ {a="([%(%[%|%<%s%-O])(a)l%-(%^n)", b="%1ا%2ل%3"}, -- ^n is lunar --p
+ {a="^(a)l%-([%_%^%.]?[tdrzsnc])", b="ا%1ل%2%2"},
+ {a="([%(%[%|%<%s%-O])(a)l%-([%_%^%.]?[tdrzsnc])", b="%1ا%2ل%3%3"}, --p
+ -- assim. art. + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)(%^n)%-", b="ا%1ل"}, -- ^n is lunar
+ {a="([%(%[%|%<%s%-O])(a)(%^n)%-", b="%1ا%2ل"}, -- ^n is lunar --p
+ {a="^(a)([%_%^%.]?[tdrzsnc])%-", b="ا%1ل%2"},
+ {a="([%(%[%|%<%s%-O])(a)([%_%^%.]?[tdrzsnc])%-", b="%1ا%2ل%3"}, --p
+ -- al- + initial unstable hamza
+ {a="^(a)l%-(\"?[uai])", b="ا%1ل%2ٱ"},
+ {a="([%(%[%|%<%s%-O])(a)l%-(\"?[uai])", b="%1ا%2ل%3ٱ"}, --p
+ -- li-/la + art. + initial unstable hamza is a special orthography
+ {a="l([ai])%-l%-(\"?[uai])", b="Ù„%1Ù„%2Ù±"},
+ -- al- + lunar consonant (i.e. what remains)
+ {a="^(a)l%-", b="ا%1لْ"},
+ {a="([%(%[%|%<%s%-O])(a)l%-", b="%1ا%2لْ"}, --p
+ -- diphthongs to be resolved before ʾalif conjunctionis
+ {a="(aW)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="awuا"},
+ {a="(aw)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1u"},
+ {a="(ay)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(aW)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="awuا%2%3"},
+ {a="(aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1u%2%3"},
+ {a="(ay)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ -- art. with waá¹£la + lÄm
+ {a="'l%-(l)", b="ٱل%1%1"},
+ -- art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are additional characters)
+ {a="'l%-(%^n)", b="ٱل%1"}, -- ^n is lunar
+ {a="'l%-([%_%^%.]?[tdrzsnc])", b="ٱل%1%1"},
+ -- li-/la- + art. + lÄm
+ {a="l([ai])%-l%-(l)", b="Ù„%1%2%2"},
+ -- assim. art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are is an additional characters)
+ {a="'(%^n)%-", b="ٱل"}, -- ^n is lunar
+ {a="'([%_%^%.]?[tdrzsnc])%-", b="ٱل%1"},
+ -- li-/la- + art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-l%-(%^n)", b="Ù„%1Ù„%2"}, -- ^n is lunar
+ {a="l([ai])%-l%-([%_%^%.]?[tdrzsnc])", b="Ù„%1Ù„%2%2"},
+ -- li-/la- + assim. art. + solar consonant is a special orthography
+ -- ('c and '^n' are additional characters)
+ {a="l([ai])%-(%^n)%-(%^n)", b="Ù„%1Ù„%3"}, -- ^n is lunar
+ {a="l([ai])%-([%_%^%.]?[tdrzsnc])%-([%_%^%.]?[tdrzsnc])", b="Ù„%1Ù„%3%3"},
+ -- art. with waá¹£la + initial unstable hamza
+ {a="'l%-(\"?[uai])", b="ٱل%1ٱ"},
+ -- art. with waá¹£la + lunar consonant (i.e. what remains)
+ {a="'l%-", b="ٱلْ"},
+ -- the silent wÄw
+ {a="uU(%p*)$", b="uÙˆ%1"},
+ {a="uU(%p*%s)", b="uÙˆ%1"},
+ {a="aU(%p*)$", b="aÙˆ%1"},
+ {a="aU(%p*%s)", b="aÙˆ%1"},
+ {a="iU(%p*)$", b="iÙˆ%1"},
+ {a="iU(%p*%s)", b="iÙˆ%1"},
+ -- words ending in -ÄT with silent wÄw/yÄʾ
+ {a="(_a)UA", b="%1وا"},
+ {a="(_a)U", b="%1Ùˆ"},
+ {a="(_a)I", b="%1ÙŠ"}
+}
+
+digraphsfvidgham = {
+ -- ʾiÊ¿rÄb: straight double quote must be discarded
+ {a="(%-)(\"?[UI]na)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?[UI]na)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?At[ui])(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?At[ui])(%p*)$", b="%2%3"},
+ {a="(%-)(\"?Ani)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?Ani)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?ayni)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?ayni)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?[uai])(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?[uai])(%p*)$", b="%2%3"},
+ -- ʾiÊ¿rÄb (end)
+ -- initial straight double quote gives a connective ʾalif
+ {a="^\"[uai]", b="Ù±"},
+ {a="([%(%[%|%<%s%-])\"[uai]", b="%1Ù±"}, --p
+ -- diphthongs to be resolved before ʾalif conjunctionis
+ {a="(aW)(O)(\"?[uai])([%S]-O)", b="awuا"},
+ {a="(aW)(%s)([%(%[%|%<]?)(\"?[uai])", b="awuا%2%3ٱ"}, --p
+ {a="(aw)(O)(\"?[uai])([%S]-O)", b="%1u"},
+ {a="(aw)(%s)([%(%[%|%<]?)(\"?[uai])", b="%1u%2%3Ù±"}, --p
+ {a="(ay)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(ay)(%s)([%(%[%|%<]?)(\"?[uai])", b="%1i%2%3Ù±"}, --p
+ -- hyphen + initial alif without hamza
+ -- {a="([uai]%-)(\"?[uai])", b="%1Ù±"},
+ {a="([uai]%-)(\"?[uai])([%^%_%.%`]?)([%aأإؤئ])", b="%1ٱ%3%4"},
+ -- initial alif without hamza (next 4 lines)
+ {a="(O[%S]-)([uaiUAIY])(O)(\"?[uai])", b="Ù±"},
+ {a="([%_]?[uaiUAIY])(%s[%(%[%|%<]?)(\"?[uai])", b="%1%2Ù±"}, --p
+ {a="^([%(%[%|%<]?)(\"?[uai])", b="%1ا%2"}, --p
+ {a="(%s)([%(%[%|%<]?)(\"?[uai])", b="%1%2ا%3"}, --p
+ {a="%-%-", b="Ù€"},
+ {a="ؤؤ", b="ؤّ"},
+ {a="أأ", b="أّ"},
+ {a="ئئ", b="ئّ"},
+ {a="bb", b="بّ"},
+ {a="BB", b="ـّ"},
+ {a="([%_%^%.])([tghdsz])([tghdsz])", b="%1%2|%3"},
+ -- same as above for additional characters:
+ {a="([%_%^%.])([cn])([cn])", b="%1%2|%3"},
+ {a="tt", b="تّ"},
+ {a="%_t%_t", b="ثّ"},
+ {a="jj", b="جّ"},
+ {a="%^g%^g", b="جّ"},
+ {a="%.h%.h", b="حّ"},
+ {a="xx", b="خّ"},
+ {a="%_h%_h", b="خّ"},
+ {a="dd", b="دّ"},
+ {a="%_d%_d", b="ذّ"},
+ {a="rr", b="رّ"},
+ {a="zz", b="زّ"},
+ {a="ss", b="سّ"},
+ {a="%^s%^s", b="شّ"},
+ {a="%.s%.s", b="صّ"},
+ {a="%.d%.d", b="ضّ"},
+ {a="%.t%.t", b="طّ"},
+ {a="%.z%.z", b="ظّ"},
+ {a="%`%`", b="عّ"},
+ {a="%.g%.g", b="غّ"},
+ {a="ff", b="ÙÙ‘"},
+ {a="qq", b="قّ"},
+ {a="kk", b="كّ"},
+ {a="ll", b="لّ"},
+ {a="mm", b="مّ"},
+ {a="nn", b="نّ"},
+ {a="hh", b="هّ"},
+ {a="ww", b="وّ"},
+ {a="yy", b="يّ"},
+ {a="%.y%.y", b="ىّ"},
+ -- additional characters + Å¡addah (begin)
+ {a="pp", b="پّ"},
+ {a="vv", b="Ú¤Ù‘"},
+ {a="gg", b="Ú¯Ù‘"},
+ {a="%^c%^c", b="Ú†Ù‘"},
+ {a="%^z%^z", b="Ú˜Ù‘"},
+ {a="%^n%^n", b="Ú­Ù‘"},
+ -- additional characters + Å¡addah (end)
+ -- sukūn begin
+ -- first, take out hyphen if any (next two lines):
+ {a="([ai]Y)%-([uaiUAI])", b="%1%2"},
+ {a="([%_%^%.]?[Bbtjghxdrzs%`fqklmnwy])%-([uaiUAI])", b="%1%2"},
+ {a="([%_%^%.]?[Bbtjghxdrzs%`fqklmnwy])(%p*)$", b="%1Ù’%2"},
+ {a="([%_%^%.]?[Bbtjghxdrzs%`fqklmnwy])(%p*%s)", b="%1Ù’%2"},
+ {a="([ai]Y)([%_]?[^%_uaiUAIYًٌÙ])", b="%1Ù’%2"},
+ {a="([%_%^%.]?[Bbtjghxdrzs%`fqklmnwy])([%_]?[^%_uaiUAIYًٌÙ])", b="%1Ù’%2"},
+ -- take out sukūn in cases of assimilation
+ {a="(n)(ْ)(%s)(ر)", b="%1%3%4"},
+ {a="(n)(Ù’)(%s)(Ùˆ)", b="%1%3%4"},
+ {a="(n)(Ù’)(%s)(ÙŠ)", b="%1%3%4"},
+ {a="(n)(Ù’)(%s)(Ù„)", b="%1%3%4"},
+ {a="(n)(Ù’)(%s)(Ù…)", b="%1%3%4"},
+ {a="(n)(Ù’)(%s)(Ù†)", b="%1%3%4"},
+ {a="Ù’\"", b="\""},
+ -- sukūn end
+ {a="_t", b="Ø«"},
+ {a="%^g", b="ج"},
+ {a="%.h", b="Ø­"},
+ {a="_h", b="Ø®"},
+ {a="_d", b="Ø°"},
+ {a="%^s", b="Ø´"},
+ {a="%.s", b="ص"},
+ {a="%.d", b="ض"},
+ {a="%.t", b="Ø·"},
+ {a="%.z", b="ظ"},
+ {a="%.g", b="غ"},
+ {a="%.y", b="Ù‰"},
+ -- additional characters (begin)
+ {a="%^c", b="Ú†"},
+ {a="%^z", b="Ú˜"},
+ {a="%^n", b="Ú­"},
+ -- additional characters (end)
+ {a="(U)(A)", b="%1ا"},
+ {a="WA", b="وْا"},
+ {a="(a)W\"", b="%1وا"},
+ {a="(a)W", b="%1وْا"},
+ {a="_A", b="aÙ‰"},
+ {a="_u", b="Ù—"},
+ {a="_a", b="Ù°"},
+ {a="_i", b="Ù–"},
+ {a="%.b", b="Ù®"},
+ {a="%.f", b="Ú¡"},
+ {a="%.q", b="Ù¯"},
+ {a="%.k", b="Ú©"},
+ {a="%.n", b="Úº"},
+ {a="%^d", b="ÚŠ"}
+}
+
+digraphsfv = {
+ -- iÊ¿rÄb: straight double quote must be discarded
+ {a="(%-)(\"?[UI]na)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?[UI]na)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?At[ui])(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?At[ui])(%p*)$", b="%2%3"},
+ {a="(%-)(\"?Ani)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?Ani)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?ayni)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?ayni)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?[uai])(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?[uai])(%p*)$", b="%2%3"},
+ -- ʾiÊ¿rÄb (end)
+ -- initial straight double quote gives a connective ʾalif
+ {a="^\"[uai]", b="Ù±"},
+ {a="([%(%[%|%<%s%-])\"[uai]", b="%1Ù±"}, --p
+ -- diphthongs to be resolved before ʾalif conjunctionis
+ {a="(aW)(O)(\"?[uai])([%S]-O)", b="awuا"},
+ {a="(aW)(%s)([%(%[%|%<]?)(\"?[uai])", b="awuا%2%3ٱ"}, --p
+ {a="(aw)(O)(\"?[uai])([%S]-O)", b="%1u"},
+ {a="(aw)(%s)([%(%[%|%<]?)(\"?[uai])", b="%1u%2%3Ù±"}, --p
+ {a="(ay)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(ay)(%s)([%(%[%|%<]?)(\"?[uai])", b="%1i%2%3Ù±"}, --p
+ -- hyphen + initial alif without hamza
+ -- {a="([uai]%-)(\"?[uai])", b="%1Ù±"},
+ {a="([uai]%-)(\"?[uai])([%^%_%.%`]?)([%aأإؤئ])", b="%1ٱ%3%4"},
+ -- initial alif without hamza (next 4 lines)
+ {a="(O[%S]-)([uaiUAIY])(O)(\"?[uai])", b="Ù±"},
+ {a="([%_]?[uaiUAIY])(%s[%(%[%|%<]?)(\"?[uai])", b="%1%2Ù±"}, --p
+ {a="^([%(%[%|%<]?)(\"?[uai])", b="%1ا%2"}, --p
+ {a="(%s)([%(%[%|%<]?)(\"?[uai])", b="%1%2ا%3"}, --p
+ {a="%-%-", b="Ù€"},
+ {a="ؤؤ", b="ؤّ"},
+ {a="أأ", b="أّ"},
+ {a="ئئ", b="ئّ"},
+ {a="bb", b="بّ"},
+ {a="BB", b="ـّ"},
+ {a="([%_%^%.])([tghdsz])([tghdsz])", b="%1%2|%3"},
+ -- same as above for additional characters:
+ {a="([%_%^%.])([cn])([cn])", b="%1%2|%3"},
+ {a="tt", b="تّ"},
+ {a="%_t%_t", b="ثّ"},
+ {a="jj", b="جّ"},
+ {a="%^g%^g", b="جّ"},
+ {a="%.h%.h", b="حّ"},
+ {a="xx", b="خّ"},
+ {a="%_h%_h", b="خّ"},
+ {a="dd", b="دّ"},
+ {a="%_d%_d", b="ذّ"},
+ {a="rr", b="رّ"},
+ {a="zz", b="زّ"},
+ {a="ss", b="سّ"},
+ {a="%^s%^s", b="شّ"},
+ {a="%.s%.s", b="صّ"},
+ {a="%.d%.d", b="ضّ"},
+ {a="%.t%.t", b="طّ"},
+ {a="%.z%.z", b="ظّ"},
+ {a="%`%`", b="عّ"},
+ {a="%.g%.g", b="غّ"},
+ {a="ff", b="ÙÙ‘"},
+ {a="qq", b="قّ"},
+ {a="kk", b="كّ"},
+ {a="ll", b="لّ"},
+ {a="mm", b="مّ"},
+ {a="nn", b="نّ"},
+ {a="hh", b="هّ"},
+ {a="ww", b="وّ"},
+ {a="yy", b="يّ"},
+ {a="%.y%.y", b="ىّ"},
+ -- additional characters + Å¡addah (begin)
+ {a="pp", b="پّ"},
+ {a="vv", b="Ú¤Ù‘"},
+ {a="gg", b="Ú¯Ù‘"},
+ {a="%^c%^c", b="Ú†Ù‘"},
+ {a="%^z%^z", b="Ú˜Ù‘"},
+ {a="%^n%^n", b="Ú­Ù‘"},
+ -- additional characters + Å¡addah (end)
+ -- sukūn begin
+ -- first, take out hyphen if any (next two lines):
+ {a="([ai]Y)%-([uaiUAI])", b="%1%2"},
+ {a="([%_%^%.]?[Bbtjghxdrzs%`fqklmnwy])%-([uaiUAI])", b="%1%2"},
+ {a="([%_%^%.]?[Bbtjghxdrzs%`fqklmnwy])(%p*)$", b="%1Ù’%2"},
+ {a="([%_%^%.]?[Bbtjghxdrzs%`fqklmnwy])(%p*%s)", b="%1Ù’%2"},
+ {a="([ai]Y)([%_]?[^%_uaiUAIYًٌÙ])", b="%1Ù’%2"},
+ {a="([%_%^%.]?[Bbtjghxdrzs%`fqklmnwy])([%_]?[^%_uaiUAIYًٌÙ])", b="%1Ù’%2"},
+ -- take out sukūn in cases of assimilation
+-- {a="(n)(ْ)(%s)(ر)", b="%1%3%4"},
+-- {a="(n)(Ù’)(%s)(Ùˆ)", b="%1%3%4"},
+-- {a="(n)(Ù’)(%s)(ÙŠ)", b="%1%3%4"},
+-- {a="(n)(Ù’)(%s)(Ù„)", b="%1%3%4"},
+-- {a="(n)(Ù’)(%s)(Ù…)", b="%1%3%4"},
+-- {a="(n)(Ù’)(%s)(Ù†)", b="%1%3%4"},
+ {a="Ù’\"", b="\""},
+ -- sukūn end
+ {a="_t", b="Ø«"},
+ {a="%^g", b="ج"},
+ {a="%.h", b="Ø­"},
+ {a="_h", b="Ø®"},
+ {a="_d", b="Ø°"},
+ {a="%^s", b="Ø´"},
+ {a="%.s", b="ص"},
+ {a="%.d", b="ض"},
+ {a="%.t", b="Ø·"},
+ {a="%.z", b="ظ"},
+ {a="%.g", b="غ"},
+ {a="%.y", b="Ù‰"},
+ -- additional characters (begin)
+ {a="%^c", b="Ú†"},
+ {a="%^z", b="Ú˜"},
+ {a="%^n", b="Ú­"},
+ -- additional characters (end)
+ {a="(U)(A)", b="%1ا"},
+ {a="WA", b="وْا"},
+ {a="(a)W\"", b="%1وا"},
+ {a="(a)W", b="%1وْا"},
+ {a="_A", b="aÙ‰"},
+ {a="_u", b="Ù—"},
+ {a="_a", b="Ù°"},
+ {a="_i", b="Ù–"},
+ {a="%.b", b="Ù®"},
+ {a="%.f", b="Ú¡"},
+ {a="%.q", b="Ù¯"},
+ {a="%.k", b="Ú©"},
+ {a="%.n", b="Úº"},
+ {a="%^d", b="ÚŠ"}
+}
+
+digraphsfveasy = { -- see the differences under 'easy' marker below
+ -- ʾiÊ¿rÄb: straight double quote must be discarded
+ {a="(%-)(\"?[UI]na)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?[UI]na)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?At[ui])(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?At[ui])(%p*)$", b="%2%3"},
+ {a="(%-)(\"?Ani)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?Ani)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?ayni)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?ayni)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?[uai])(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?[uai])(%p*)$", b="%2%3"},
+ -- ʾiÊ¿rÄb (end)
+ -- initial straight double quote gives a connective ʾalif
+ {a="^\"[uai]", b="Ù±"},
+ {a="([%(%[%|%<%s%-])\"[uai]", b="%1Ù±"}, --p
+ -- diphthongs to be resolved before ʾalif conjunctionis
+ {a="(aW)(O)(\"?[uai])([%S]-O)", b="awuا"},
+ {a="(aW)(%s)([%(%[%|%<]?)(\"?[uai])", b="awuا%2%3ٱ"}, --p
+ {a="(aw)(O)(\"?[uai])([%S]-O)", b="%1u"},
+ {a="(aw)(%s)([%(%[%|%<]?)(\"?[uai])", b="%1u%2%3Ù±"}, --p
+ {a="(ay)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(ay)(%s)([%(%[%|%<]?)(\"?[uai])", b="%1i%2%3Ù±"}, --p
+ -- hyphen + initial alif without hamza
+ -- {a="([uai]%-)(\"?[uai])", b="%1Ù±"},
+ {a="([uai]%-)(\"?[uai])([%^%_%.%`]?)([%aأإؤئ])", b="%1ٱ%3%4"},
+ -- initial alif without hamza (next 4 lines)
+ {a="(O[%S]-)([uaiUAIY])(O)(\"?[uai])", b="Ù±"},
+ {a="([%_]?[uaiUAIY])(%s[%(%[%|%<]?)(\"?[uai])", b="%1%2Ù±"}, --p
+ {a="^([%(%[%|%<]?)(\"?[uai])", b="%1ا%2"}, --p
+ {a="(%s)([%(%[%|%<]?)(\"?[uai])", b="%1%2ا%3"}, --p
+ {a="%-%-", b="Ù€"},
+ {a="ؤؤ", b="ؤّ"},
+ {a="أأ", b="أّ"},
+ {a="ئئ", b="ئّ"},
+ {a="bb", b="بّ"},
+ {a="BB", b="ـّ"},
+ {a="([%_%^%.])([tghdsz])([tghdsz])", b="%1%2|%3"},
+ -- same as above for additional characters:
+ {a="([%_%^%.])([cn])([cn])", b="%1%2|%3"},
+ {a="tt", b="تّ"},
+ {a="%_t%_t", b="ثّ"},
+ {a="jj", b="جّ"},
+ {a="%^g%^g", b="جّ"},
+ {a="%.h%.h", b="حّ"},
+ {a="xx", b="خّ"},
+ {a="%_h%_h", b="خّ"},
+ {a="dd", b="دّ"},
+ {a="%_d%_d", b="ذّ"},
+ {a="rr", b="رّ"},
+ {a="zz", b="زّ"},
+ {a="ss", b="سّ"},
+ {a="%^s%^s", b="شّ"},
+ {a="%.s%.s", b="صّ"},
+ {a="%.d%.d", b="ضّ"},
+ {a="%.t%.t", b="طّ"},
+ {a="%.z%.z", b="ظّ"},
+ {a="%`%`", b="عّ"},
+ {a="%.g%.g", b="غّ"},
+ {a="ff", b="ÙÙ‘"},
+ {a="qq", b="قّ"},
+ {a="kk", b="كّ"},
+ {a="ll", b="لّ"},
+ {a="mm", b="مّ"},
+ {a="nn", b="نّ"},
+ {a="hh", b="هّ"},
+ {a="ww", b="وّ"},
+ {a="yy", b="يّ"},
+ {a="%.y%.y", b="ىّ"},
+ -- additional characters + Å¡addah (begin)
+ {a="pp", b="پّ"},
+ {a="vv", b="Ú¤Ù‘"},
+ {a="gg", b="Ú¯Ù‘"},
+ {a="%^c%^c", b="Ú†Ù‘"},
+ {a="%^z%^z", b="Ú˜Ù‘"},
+ {a="%^n%^n", b="Ú­Ù‘"},
+ -- additional characters + Å¡addah (end)
+ -- sukūn begin ('easy' needs these rules to be taken out); but
+ -- first take out every previously generated sukūn by hamza rules,
+ -- so there be no need to edit them:
+ {a="Ù’", b=""},
+ -- first, take out hyphen if any (next two lines):
+-- {a="([ai]Y)%-([uaiUAI])", b="%1%2"},
+-- {a="([%_%^%.]?[Bbtjghxdrzs%`fqklmnwy])%-([uaiUAI])", b="%1%2"},
+-- {a="([%_%^%.]?[Bbtjghxdrzs%`fqklmnwy])(%p*)$", b="%1Ù’%2"},
+-- {a="([%_%^%.]?[Bbtjghxdrzs%`fqklmnwy])(%p*%s)", b="%1Ù’%2"},
+-- {a="([ai]Y)([%_]?[^%_uaiUAIYًٌÙ])", b="%1Ù’%2"},
+-- {a="([%_%^%.]?[Bbtjghxdrzs%`fqklmnwy])([%_]?[^%_uaiUAIYًٌÙ])", b="%1Ù’%2"},
+ -- take out sukūn in cases of assimilation
+-- {a="(n)(ْ)(%s)(ر)", b="%1%3%4"},
+-- {a="(n)(Ù’)(%s)(Ùˆ)", b="%1%3%4"},
+-- {a="(n)(Ù’)(%s)(ÙŠ)", b="%1%3%4"},
+-- {a="(n)(Ù’)(%s)([Ù„])", b="%1%3%4"},
+-- {a="(n)(Ù’)(%s)([Ù…])", b="%1%3%4"},
+-- {a="(n)(Ù’)(%s)([Ù†])", b="%1%3%4"},
+-- {a="Ù’\"", b="\""},
+ -- sukūn end
+ {a="_t", b="Ø«"},
+ {a="%^g", b="ج"},
+ {a="%.h", b="Ø­"},
+ {a="_h", b="Ø®"},
+ {a="_d", b="Ø°"},
+ {a="%^s", b="Ø´"},
+ {a="%.s", b="ص"},
+ {a="%.d", b="ض"},
+ {a="%.t", b="Ø·"},
+ {a="%.z", b="ظ"},
+ {a="%.g", b="غ"},
+ {a="%.y", b="Ù‰"},
+ -- additional characters (begin)
+ {a="%^c", b="Ú†"},
+ {a="%^z", b="Ú˜"},
+ {a="%^n", b="Ú­"},
+ -- additional characters (end)
+ {a="(U)(A)", b="%1ا"},
+ {a="WA", b="وْا"},
+ {a="(a)W\"", b="%1وا"},
+ {a="(a)W", b="%1وْا"},
+ {a="_A", b="aÙ‰"},
+ {a="_u", b="Ù—"},
+ {a="_a", b="Ù°"},
+ {a="_i", b="Ù–"},
+ {a="%.b", b="Ù®"},
+ {a="%.f", b="Ú¡"},
+ {a="%.q", b="Ù¯"},
+ {a="%.k", b="Ú©"},
+ {a="%.n", b="Úº"},
+ {a="%^d", b="ÚŠ"}
+}
+
+singlefv = {
+ {a="b", b="ب"},
+ {a="t", b="ت"},
+ {a="j", b="ج"},
+ {a="x", b="Ø®"},
+ {a="d", b="د"},
+ {a="r", b="ر"},
+ {a="z", b="ز"},
+ {a="s", b="س"},
+ {a="f", b="Ù"},
+ {a="`", b="ع"},
+ {a="f", b="Ù"},
+ {a="q", b="Ù‚"},
+ {a="k", b="Ùƒ"},
+ {a="l", b="Ù„"},
+ {a="m", b="Ù…"},
+ {a="n", b="Ù†"},
+ {a="h", b="Ù‡"},
+ {a="w", b="Ùˆ"},
+ {a="y", b="ÙŠ"},
+ {a="T", b="Ø©"},
+ -- additional characters (begin)
+ {a="p", b="Ù¾"},
+ {a="v", b="Ú¤"},
+ {a="g", b="Ú¯"},
+ -- additional characters (end)
+ {a="\"$", b=""},
+ {a="\"(%W)", b="%1"},
+ {a="\"([^uaiUAI])", b="%1"},
+ {a="o", b="ْ"}, -- hard-coded sukūn
+ {a="([^0-9])%-([^0-9])", b="%1%2"},
+ {a="B", b="Ù€"},
+}
+
+singlefveasy = { -- see the differences under 'easy' tag below
+ {a="b", b="ب"},
+ {a="t", b="ت"},
+ {a="j", b="ج"},
+ {a="x", b="Ø®"},
+ {a="d", b="د"},
+ {a="r", b="ر"},
+ {a="z", b="ز"},
+ {a="s", b="س"},
+ {a="f", b="Ù"},
+ {a="`", b="ع"},
+ {a="f", b="Ù"},
+ {a="q", b="Ù‚"},
+ {a="k", b="Ùƒ"},
+ {a="l", b="Ù„"},
+ {a="m", b="Ù…"},
+ {a="n", b="Ù†"},
+ {a="h", b="Ù‡"},
+ {a="w", b="Ùˆ"},
+ {a="y", b="ÙŠ"},
+ {a="T", b="Ø©"},
+ -- additional characters (begin)
+ {a="p", b="Ù¾"},
+ {a="v", b="Ú¤"},
+ {a="g", b="Ú¯"},
+ -- additional characters (end)
+ -- easy (begin): \" needs to put back the sukūn
+ {a="\"$", b="Ù’"},
+ {a="\"(%W)", b="Ù’%1"},
+ {a="\"([^uaiUAI])", b="Ù’%1"},
+ -- easy (end)
+ {a="([^0-9])%-([^0-9])", b="%1%2"},
+ {a="B", b="Ù€"},
+}
diff --git a/macros/luatex/latex/arabluatex/arabluatex_novoc.lua b/macros/luatex/latex/arabluatex/arabluatex_novoc.lua
new file mode 100644
index 0000000000..51418617b7
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/arabluatex_novoc.lua
@@ -0,0 +1,166 @@
+--[[
+This file is part of the `arabluatex' package
+
+ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX
+Copyright (C) 2016--2019 Robert Alessi
+
+Please send error reports and suggestions for improvements to Robert
+Alessi <alessi@robertalessi.net>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see
+<http://www.gnu.org/licenses/>.
+--]]
+
+tanwinnv = {
+ -- assimilations (begin). These are good but may not apply here.
+-- {a="(O[%S]-)(%-?[uai]N[UI]?)(O)([rlmnwy])", b="%4%4"},
+-- {a="(%-?[uai]NU)(%s)([rlmnwy])", b="%1%2%3%3"},
+ -- assimilations (end)
+ {a="%-?uNU", b="Ùˆ"},
+ {a="%-?aNU", b="وا"},
+ {a="%-?iNU", b="Ùˆ"},
+ -- assimilations (begin). These are good but may not apply here.
+-- {a="%-?(uN)(%s)([rlmnwy])", b="|%2%3%3"},
+-- {a="(O[%S]-)(%-?aN)(_A)(O)([rlmnwy])", b="%5%5"},
+-- {a="(O[%S]-)(%-?aN)(Y)(O)([rlmnwy])", b="%5%5"},
+-- {a="%-?(aN)(_A)(%s)([rlmnwy])", b="Ù‰%3%4%4"},
+-- {a="%-?(aN)(Y)(%s)([rlmnwy])", b="Ù‰%3%4%4"},
+-- {a="(T)%-?(aN)(%s)([rlmnwy])", b="%1%3%4%4"},
+-- {a="(Ø¡)%-?(aN)(%s)([rlmnwy])", b="%1%3%4%4"},
+-- {a="([^TA])%-?(aN)(%s)([rlmnwy])", b="%1ا%3%4%4"},
+-- {a="%-?(iNI?)(%s)([rlmnwy])", b="|%2%3%3"},
+ -- assimilations (end)
+ -- "quoted" tanwīn (begin)
+ {a="%-?(\"uN)", b="ٌ"},
+ {a="(B)%-?(\"aN)", b="%1Ù‹"},
+ {a="%-?(\"aN)(_A)", b="ًى"},
+ {a="%-?(\"aN)(Y)", b="ًى"},
+ {a="(T)%-?(\"aN)", b="%1Ù‹"},
+ {a="([اآ])(ء)%-?(\"aN)", b="%1%2ً"}, --new
+ {a="([^TA])%-?(\"aN)", b="%1ًا"},
+ {a="%-?(\"iNI?)", b="Ù"},
+ -- "quoted" tanwīn (end)
+ {a="%-?(uN)", b=""},
+ {a="(B)%-?(aN)", b="%1"},
+ -- needed by \arbcolor:
+ {a="%-?(aN)(O[%S]-%_AO)", b=""},
+ {a="%-?(aN)(O[%S]-YO)", b=""},
+ {a="(O[%S]-TO)%-?(aN)", b=""},
+ {a="(O[%S]-)([اآ])(ء)(O)%-?(aN)", b=""}, --new
+ {a="(O[%S]-[^TA]O)%-?(aN)", b=""},
+ --
+ {a="%-?(aN)(_A)", b="Ù‰"},
+ {a="%-?(aN)(Y)", b="Ù‰"},
+ {a="(T)%-?(aN)", b="%1"},
+ {a="([اآ])(ء)%-?(aN)", b="%1%2"}, --new
+ {a="([^TA])%-?(aN)", b="%1ا"},
+ {a="%-?(iNI?)", b=""},
+ -- ʾalif al-waṣl: put it back on with \arbnull
+ {a="(O[%S]-)([%'a]l%-)(O)(\"?[uai])", b="%4"},
+ -- initial straight double quote gives a connective ʾalif. This has
+ -- nothing to do with the tanwīn, but I put it here for time being.
+ {a="^\"", b="Ù±"},
+ {a="([%s%-])\"", b="%1Ù±"}
+}
+
+trigraphsnv = { -- trigraphs or more
+ -- Allah
+ {a="l%-l_ah", b="l-ll_ah"},
+ -- 'llatI / 'llad_I
+ {a="^'ll(a)([%_]?[dt])", b="ال%1%2"},
+ {a="([%(%[%|%<%s%-])'ll(a)([%_]?[dt])", b="%1ال%2%3"}, --p
+ -- al- + lÄm
+ {a="^(a)l%-(l)", b="ا%1ل%2"},
+ {a="([%(%[%|%<%s%-])(a)l%-(l)", b="%1ا%2ل%3"}, --p
+ -- al- + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)l%-(%^n)", b="ا%1ل%2"}, -- ^n is lunar
+ {a="([%(%[%|%<%s%-])(a)l%-(%^n)", b="%1ا%2ل%3"}, -- ^n is lunar --p
+ {a="^(a)l%-([%_%^%.]?[tdrzsnc])", b="ا%1ل%2"},
+ {a="([%(%[%|%<%s%-])(a)l%-([%_%^%.]?[tdrzsnc])", b="%1ا%2ل%3"}, --p
+ -- assim. art. + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)(%^n)%-", b="ا%1ل"}, -- ^n is lunar
+ {a="([%(%[%|%<%s%-])(a)(%^n)%-", b="%1ا%2ل"}, -- ^n is lunar --p
+ {a="^(a)([%_%^%.]?[tdrzsnc])%-", b="ا%1ل"},
+ {a="([%(%[%|%<%s%-])(a)([%_%^%.]?[tdrzsnc])%-", b="%1ا%2ل"}, --p
+ -- al- + initial unstable hamza
+ {a="^(a)l%-(\")([uai])", b="ا%1لٱ%3"},
+ {a="([%(%[%|%<%s%-])(a)l%-(\")([uai])", b="%1ا%2لٱ%4"}, --p
+ {a="^(a)l%-([uai])", b="ا%1لا%2"},
+ {a="([%(%[%|%<%s%-])(a)l%-([uai])", b="%1ا%2لا%3"}, --p
+ -- li-/la- + art. + initial unstable hamza is a special orthography
+ {a="l([ai])%-l%-(\")([uai])", b="ل%1لٱ%3"},
+ {a="l([ai])%-l%-([uai])", b="ل%1لا%2"},
+ -- al- + lunar consonant (i.e. what remains)
+ {a="^(a)l%-", b="ا%1ل"},
+ {a="([%(%[%|%<%s%-])(a)l%-", b="%1ا%2ل"}, --p
+ -- art. with waá¹£la + lÄm
+ {a="'l%-(l)", b="ال%1"},
+ -- art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are additional characters)
+ {a="'l%-(%^n)", b="ال%1"}, -- ^n is lunar
+ {a="'l%-([%_%^%.]?[tdrzsnc])", b="ال%1"},
+ -- li-/la- + art. + lÄm
+ {a="l([ai])%-l%-(l)", b="Ù„%1%2"},
+ -- assim. art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are additional characters)
+ {a="'(%^n)%-", b="ال"}, -- ^n is lunar
+ {a="'([%_%^%.]?[tdrzsnc])%-", b="ال"},
+ -- li-/la- + art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-l%-(%^n)", b="Ù„%1Ù„%2"}, -- ^n is lunar
+ {a="l([ai])%-l%-([%_%^%.]?[tdrzsnc])", b="Ù„%1Ù„%2"},
+ -- li-/la + assim. art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-(%^n)%-(%^n)", b="Ù„%1Ù„%3"}, -- ^n is lunar
+ {a="l([ai])%-([%_%^%.]?[tdrzsnc])%-([%_%^%.]?[tdrzsnc])", b="Ù„%1Ù„%3"},
+ -- art. with waá¹£la + initial unstable hamza
+ {a="'l%-(\")([uai])", b="الٱ%2"},
+ {a="'l%-([uai])", b="الا%1"},
+ -- art. with waá¹£la + lunar consonant (i.e. what remains)
+ {a="'l%-", b="ال"},
+ -- the silent wÄw
+ {a="uU(%p*)$", b="uÙˆ%1"},
+ {a="uU(%p*%s)", b="uÙˆ%1"},
+ {a="aU(%p*)$", b="aÙˆ%1"},
+ {a="aU(%p*%s)", b="aÙˆ%1"},
+ {a="iU(%p*)$", b="iÙˆ%1"},
+ {a="iU(%p*%s)", b="iÙˆ%1"},
+ -- words ending in -ÄT with silent wÄw/yÄʾ
+ {a="(_a)UA", b="%1وا"},
+ {a="(_a)U", b="%1Ùˆ"},
+ {a="(_a)I", b="%1ÙŠ"}
+}
+
+longvnv = {
+ {a="\"A", b="َا"},
+ {a="\"U", b="ÙÙˆ"},
+ {a="\"I", b="ÙÙŠ"},
+ {a="\"Y", b="aÙ‰"},
+ {a="A", b="ا"},
+ {a="U", b="Ùˆ"},
+ {a="I", b="ÙŠ"},
+ {a="Y", b="Ù‰"},
+}
+
+shortvnv = {
+ {a="\"u", b="Ù"},
+ {a="\"a", b="ÙŽ"},
+ {a="\"i", b="Ù"},
+ {a="%-?%.u", b="Ù"},
+ {a="%-?%.a", b="ÙŽ"},
+ {a="%-?%.i", b="Ù"},
+ {a="u", b=""},
+ {a="a", b=""},
+ {a="i", b=""}
+}
diff --git a/macros/luatex/latex/arabluatex/arabluatex_trans.lua b/macros/luatex/latex/arabluatex/arabluatex_trans.lua
new file mode 100644
index 0000000000..63a1956345
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/arabluatex_trans.lua
@@ -0,0 +1,1018 @@
+--[[
+This file is part of the `arabluatex' package
+
+ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX
+Copyright (C) 2016--2019 Robert Alessi
+
+Please send error reports and suggestions for improvements to Robert
+Alessi <alessi@robertalessi.net>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see
+<http://www.gnu.org/licenses/>.
+--]]
+
+-- common
+
+punctuationtr = {
+ {a="%(%(", b="("},
+ {a="%)%)", b=")"}
+}
+
+nulltr = {
+ {a="%|", b=""},
+ {a="o", b=""},
+ {a="O[%S]-O", b=""},
+ {a="[%^%_](.)", b="<??>%1"}
+}
+
+-- cap (legacy)
+captr = {
+ -- dmg (defaut); loc as well
+ {a="Ä", b="Ä€"},
+ {a="b", b="B"},
+ {a="t", b="T"},
+ {a="ṯ", b="Ṯ"},
+ {a="ǧ", b="Ǧ"},
+ {a="ḥ", b="Ḥ"},
+ {a="ḫ", b="Ḫ"},
+ {a="d", b="D"},
+ {a="á¸", b="Ḏ"},
+ {a="r", b="R"},
+ {a="z", b="Z"},
+ {a="s", b="S"},
+ {a="Å¡", b="Å "},
+ {a="á¹£", b="á¹¢"},
+ {a="á¸", b="Ḍ"},
+ {a="ṭ", b="Ṭ"},
+ {a="ẓ", b="Ẓ"},
+ {a="Ä¡", b="Ä "},
+ {a="f", b="F"},
+ {a="q", b="Q"},
+ {a="k", b="K"},
+ {a="l", b="L"},
+ {a="m", b="M"},
+ {a="n", b="N"},
+ {a="h", b="H"},
+ {a="w", b="W"},
+ {a="ū", b="Ū"},
+ {a="y", b="Y"},
+ {a="ī", b="Ī"}
+}
+
+-- uc
+lcuc = {
+ {a="b", b="B"},
+ {a="t", b="T"},
+ {a="ṯ", b="Ṯ"},
+ {a="ǧ", b="Ǧ"},
+ {a="j", b="J"},
+ {a="ḥ", b="Ḥ"},
+ {a="ḫ", b="Ḫ"},
+ {a="d", b="D"},
+ {a="á¸", b="Ḏ"},
+ {a="r", b="R"},
+ {a="z", b="Z"},
+ {a="s", b="S"},
+ {a="Å¡", b="Å "},
+ {a="á¹£", b="á¹¢"},
+ {a="á¸", b="Ḍ"},
+ {a="ṭ", b="Ṭ"},
+ {a="ẓ", b="Ẓ"},
+ {a="Ä¡", b="Ä "},
+ {a="f", b="F"},
+ {a="q", b="Q"},
+ {a="k", b="K"},
+ {a="l", b="L"},
+ {a="m", b="M"},
+ {a="n", b="N"},
+ {a="h", b="H"},
+ {a="w", b="W"},
+ {a="y", b="Y"},
+ {a="u", b="U"},
+ {a="a", b="A"},
+ {a="i", b="I"},
+ {a="ū", b="Ū"},
+ {a="Ä", b="Ä€"},
+ {a="ī", b="Ī"},
+ -- additional characters
+ {a="p", b="P"},
+ {a="Ä", b="ÄŒ"},
+ {a="ž", b="Ž"},
+ {a="v", b="V"},
+ {a="g", b="G"},
+ {a="ñ", b="Ñ"},
+ {a="ch", b="Ch"}, -- loc
+}
+
+-- dmg
+
+hamzatrdmg = {
+ -- next lines for ʾalif alone
+ {a="(%.A)l%-(%^n)", b=".|l-%2"}, --additional (^n is lunar)
+ {a="([%(%[%|%<%s%-O])(%.A)l%-(%^n)", b="%1.|l-%3"}, --additional (^n is lunar) --p
+ {a="(%.A)l%-([%_%^%.]?[tdrzsnc])", b=".|%2-%2"},
+ {a="([%(%[%|%<%s%-O])(%.A)l%-([%_%^%.]?[tdrzsnc])", b="%1.|%3-%3"}, --p
+ {a="(%.A)([uai])l%-(%^n)", b="||%2l-%3"}, --additional (^n is lunar)
+ {a="([%(%[%|%<%s%-O])(%.A)([uai])l%-(%^n)", b="%1||%3l-%4"}, --additional (^n is lunar) --p
+ {a="(%.A)([uai])l%-([%_%^%.]?[tdrzsnc])", b="||%2%3-%3"},
+ {a="([%(%[%|%<%s%-O])(%.A)([uai])l%-([%_%^%.]?[tdrzsnc])", b="%1||%3%4-%4"}, --p
+ {a="(%.A)([^uai])", b=".|%2"},
+ {a="(%.A)([uai])", b="||%2"},
+ -- hard coded hamza
+ {a="|\"'", b="ʾ"},
+ {a="A\"'", b="ʾA"},
+ {a="[au]\"'", b="ʾ"},
+ {a="w\"'", b="ʾ"},
+ {a="i\"'", b="ʾ"},
+ {a="y\"'", b="ʾ"},
+ -- hamza takes tašdīd too
+ {a="''([Uu])", b="ʾʾ%1"},
+ {a="''([Aa])", b="ʾʾ%1"},
+ {a="''([Ii])", b="ʾʾ%1"},
+ -- initial long u and i (for a, see below)
+ {a="%'%_U", b="ʾU"},
+ {a="%'%_I", b="ʾI"},
+ -- taḫfīfu 'l-hamza
+ {a="'u'([^uaiUAI])", b="ʾU%1"},
+ {a="'i'([^uaiUAI])", b="ʾI%1"},
+ {a="^u'([^uaiUAI])", b="U%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])u'([^uaiUAI])", b="%1U%2"},
+ {a="^i'([^uaiUAI])", b="I%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])i'([^uaiUAI])", b="%1I%2"},
+ -- madda (historic writing below)
+ {a="'a'([^uaiUAI])", b="ʾA%1"},
+ {a="'a?A", b="ʾA"},
+ {a="(A)(')(i)$", b="%1ʾ%3"},
+ {a="(A)(')(i)(%W)", b="%1ʾ%3%4"},
+ {a="(A)(')(i)", b="%1ʾ%3"}, -- historic madda
+ {a="(A)(')", b="%1ʾ"}, -- historic madda
+ -- initial (needs both ^ and %W patterns)
+ -- 'aw: the diphthong is to be resolved into 'awi' (next 8 lines)
+ {a="^('aw)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(%W)('aw)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1%2i"},
+ {a="^('aw)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(%W)('aw)(O)(\"?[uai])([%S]-O)", b="%1%2i"},
+ {a="^('aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ {a="(%W)('aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1%2i%3%4"},
+ {a="^('aw)(%s)([%(%[%|%<]?\"?[uai])", b="%1i%2%3"}, --p
+ {a="(%W)('aw)(%s)([%(%[%|%<]?\"?[uai])", b="%1%2i%3%4"}, --p
+ -- then the 'initial' rules for the remaining cases
+ {a="^(')([ua])", b="ʾ%2"},
+ {a="^(')(i)", b="ʾ%2"},
+ -- consider replacing initial %W with [%s%(%[%<%-]:
+ -- {a="(%W)(')([ua])", b="%1ʾ%3"},
+ -- {a="(%W)(')(i)", b="%1ʾ%3"},
+ {a="([%s%(%[%<%-])(')([ua])", b="%1ʾ%3"},
+ {a="([%s%(%[%<%-])(')(i)", b="%1ʾ%3"},
+ -- final
+ {a="([Iy])(')(aN)$", b="%1ʾ%3"},
+ {a="([Iy])(')(aN)(%W)", b="%1ʾ%3%4"},
+ {a="([^uai])(')([uai]N?)$", b="%1ʾ%3"},
+ {a="([^uai])(')([uai]N?)(%W)", b="%1ʾ%3%4"},
+ {a="([UI])(')([uai])$", b="%1ʾ%3"},
+ {a="([UI])(')([uai])(%W)", b="%1ʾ%3%4"},
+ -- middle
+ {a="(U)(')", b="%1ʾ"},
+ {a="([Iy])(')", b="%1ʾ"},
+ {a="([^uai])(')([uU])", b="%1ʾ%3"},
+ {a="([^uai])(')(%_?[aAY])", b="%1ʾ%3"},
+ {a="([^uai])(')([iI])", b="%1ʾ%3"},
+ {a="(u)(')([uU])", b="%1ʾ%3"},
+ {a="(u)(')(%_?[aAY])", b="%1ʾ%3"},
+ {a="(u)(')([iI])", b="%1ʾ%3"},
+ {a="(a)(')(%_?[aAY])", b="%1ʾ%3"},
+ {a="(a)(')([uU])", b="%1ʾ%3"},
+ {a="(a)(')([iI])", b="%1ʾ%3"},
+ {a="(i)(')(%_?[aAY])", b="%1ʾ%3"},
+ {a="(i)(')([uU])", b="%1ʾ%3"},
+ {a="(i)(')([iI])", b="%1ʾ%3"},
+ {a="(a)(')([^uaiUAI])", b="%1ʾ%3"},
+ {a="(u)(')([^uaiUAI])", b="%1ʾ%3"},
+ {a="(i)(')([^uaiUAI])", b="%1ʾ%3"}
+}
+
+tanwintrdmg = {
+ {a="%-?([uai]NU)(O)([ui])([%S]-O)", b="\\arbup{un%3}"},
+ {a="%-?([uai]NU)(%s)([ui])", b="\\arbup{un%3}%2'"},
+ {a="%-?(iNI)(O)([ui])([%S]-O)", b="i\\arbup{n%3}"},
+ {a="%-?(iNI)(%s)([ui])", b="i\\arbup{n%3}%2'"},
+ {a="(O[%S]-)([uai]N[UI])(O)(\"?[ui])", b="'"},
+ {a="%-?uNU", b="\\arbup{un}"},
+ {a="%-?aNU", b="\\arbup{an}"},
+ {a="%-?iNU", b="\\arbup{in}"},
+ {a="%-?iNI", b="i\\arbup{n}"},
+ -- tanwīn preceding ʾalif conjunctionis
+ {a="%-?(uN)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="\\arbup{uni}"},
+ {a="%-?(aN)(_A)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="ạ\\arbup{ni}"},
+ {a="%-?(aN)(Y)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="ạ\\arbup{ni}"},
+ {a="(T)%-?(aN)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="t\\arbup{ani}"},
+ {a="([^TA])%-?(aN)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1\\arbup{ani}"},
+ {a="%-?(iN)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="\\arbup{ini}"},
+ {a="%-?(uN)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="\\arbup{uni}%2%3"},
+ {a="%-?(aN)(_A)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="ạ\\arbup{ni}%3%4"},
+ {a="%-?(aN)(Y)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="ạ\\arbup{ni}%3%4"},
+ {a="(T)%-?(aN)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="t\\arbup{ani}%3%4"},
+ {a="([^TA])%-?(aN)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1\\arbup{ani}%3%4"},
+ {a="%-?(iN)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="\\arbup{ini}%2%3"},
+ -- tanwīn preceding 'lla_dI/'llatI
+ {a="%-?(uN)(O)('lla[%_]?[dt])([%S]-O)", b="\\arbup{uni}"},
+ {a="%-?(aN)(_A)(O)('lla[%_]?[dt])([%S]-O)", b="ạ\\arbup{ni}"},
+ {a="%-?(aN)(Y)(O)('lla[%_]?[dt])([%S]-O)", b="ạ\\arbup{ni}"},
+ {a="(T)%-?(aN)(O)('lla[%_]?[dt])([%S]-O)", b="t\\arbup{ani}"},
+ {a="([^TA])%-?(aN)(O)('lla[%_]?[dt])([%S]-O)", b="%1\\arbup{ani}"},
+ {a="%-?(iN)(O)('lla[%_]?[dt])([%S]-O)", b="\\arbup{ini}"},
+ {a="%-?(uN)(%s)('lla[%_]?[dt])", b="\\arbup{uni}%2%3"},
+ {a="%-?(aN)(_A)(%s)('lla[%_]?[dt])", b="ạ\\arbup{ni}%3%4"},
+ {a="%-?(aN)(Y)(%s)('lla[%_]?[dt])", b="ạ\\arbup{ni}%3%4"},
+ {a="(T)%-?(aN)(%s)('lla[%_]?[dt])", b="t\\arbup{ani}%3%4"},
+ {a="([^TA])%-?(aN)(%s)('lla[%_]?[dt])", b="%1\\arbup{ani}%3%4"},
+ {a="%-?(iN)(%s)('lla[%_]?[dt])", b="\\arbup{ini}%2%3"},
+ -- tanwīn + alif without hamza and kasra (ibn) or dhamma (uhrub)
+ {a="%-?(uN)(O)([ui])([%S]-O)", b="\\arbup{un%3}"},
+ {a="%-?(aN)(_A)(O)([ui])([%S]-O)", b="ạ\\arbup{n%4}"},
+ {a="%-?(aN)(Y)(O)([ui])([%S]-O)", b="ạ\\arbup{n%4}"},
+ {a="(T)%-?(aN)(O)([ui])([%S]-O)", b="t\\arbup{an%4}"},
+ {a="([^TA])%-?(aN)(O)([ui])([%S]-O)", b="%1\\arbup{an%4}"},
+ {a="%-?(iN)(O)([ui])([%S]-O)", b="\\arbup{in%3}"},
+ {a="(O[%S]-)([uai]N)(O)(\"?[ui])", b="'"},
+ {a="%-?(uN)(%s)([ui])", b="\\arbup{un%3}%2'"},
+ {a="%-?(aN)(_A)(%s)([ui])", b="ạ\\arbup{n%4}%3'"},
+ {a="%-?(aN)(Y)(%s)([ui])", b="ạ\\arbup{n%4}%3'"},
+ {a="(T)%-?(aN)(%s)([ui])", b="t\\arbup{an%4}%3'"},
+ {a="([^TA])%-?(aN)(%s)([ui])", b="%1\\arbup{an%4}%3'"},
+ {a="%-?(iN)(%s)([ui])", b="\\arbup{in%3}%2'"},
+ --
+-- {a="uN", b="\\arbup{un}"}, (now included in the last line of this table)
+ {a="%-?(\"?At)%-?([ui])N", b="\\arbup{%1%2n}"},
+ -- needed by \arbcolor:
+ {a="%-?(aN)(O[%S]-%_AO)", b="ạ\\arbup{n}"},
+ {a="%-?(aN)(O[%S]-YO)", b="ạ\\arbup{n}"},
+ {a="(O[%S]-TO)%-?(\"?aN)", b="\\arbup{an}"},
+ {a="(O[%S]-[^TA]O)%-?(\"?aN)", b="\\arbup{an}"},
+ --
+ {a="%-?(aN)(_A)", b="ạ\\arbup{n}"},
+ {a="%-?(aN)(Y)", b="ạ\\arbup{n}"},
+ {a="(T)%-?(\"?aN)", b="t\\arbup{an}"},
+ {a="([^TA])%-?(\"?aN)", b="%1\\arbup{an}"},
+ {a="%-?([ui])N", b="\\arbup{%1n}"}
+}
+
+trigraphstrdmg = { -- trigraphs or more
+ -- 'llatI / 'llad_I
+ {a="^'ll(a)([%_]?[dt])", b="'ll%1%2"},
+ {a="([%(%[%|%<%s])'ll(a)([%_]?[dt])", b="%1'll%2%3"}, --p
+ -- law: the diphthong is to be resolved into 'awi' (next 8 lines)
+ {a="^(law)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(%W)(law)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1%2i"},
+ {a="^(law)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(%W)(law)(O)(\"?[uai])([%S]-O)", b="%1%2i"},
+ {a="^(law)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ {a="(%W)(law)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1%2i%3%4"},
+ {a="^(law)(%s)([%(%[%|%<]?\"?[uai])", b="%1i%2%3"}, --p
+ {a="(%W)(law)(%s)([%(%[%|%<]?\"?[uai])", b="%1%2i%3%4"}, --p
+ -- al- + lÄm
+ {a="^(a)l%-(l)", b="%1l-%2"},
+ {a="([%(%[%|%<%s%-O])(a)l%-(l)", b="%1%2l-%3"}, --p
+ -- al- + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)l%-(%^n)", b="%1l-%2"}, -- ^n is lunar
+ {a="([%(%[%|%<%s%-O])(a)l%-(%^n)", b="%1%2l-%3"}, --^n is lunar --p
+ {a="^(a)l%-([%_%^%.]?[tdrzsnc])", b="%1%2-%2"},
+ {a="([%(%[%|%<%s%-O])(a)l%-([%_%^%.]?[tdrzsnc])", b="%1%2%3-%3"}, --p
+ -- assim. art. + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)(%^n)%-", b="%1l-"}, -- ^n is lunar
+ {a="([%(%[%|%<%s%-O])(a)(%^n)%-", b="%1%2l-"}, --^n is lunar --p
+ {a="^(a)([%_%^%.]?[tdrzsnc])%-", b="%1%2-"},
+ {a="([%(%[%|%<%s%-O])(a)([%_%^%.]?[tdrzsnc])%-", b="%1%2%3-"}, --p
+ -- al- + initial unstable hamza
+ {a="^(a)l%-(\"?[uai])", b="%1l-%2"},
+ {a="([%(%[%|%<%s%-O])(a)l%-(\"?[uai])", b="%1%2l-%3"}, --p
+ -- li-/la- + art. + initial unstable hamza is a special orthography
+ {a="l([ai])%-l%-([uai])", b="l%1-l-%2"},
+ -- al- + lunar consonant (i.e. what remains)
+ {a="^(a)l%-", b="%1l-"},
+ {a="([%(%[%|%<%s%-O])(a)l%-", b="%1%2l-"}, --p
+ -- diphthongs to be resolved before ʾalif conjunctionis
+ {a="(aw)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1u"},
+ {a="(ay)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1u%2%3"},
+ {a="(ay)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ -- art. with waá¹£la + lÄm
+ {a="'l%-(l)", b="'l-%1"},
+ -- art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are additional characters)
+ {a="'l%-(%^n)", b="'l-%1"}, -- ^n is lunar
+ {a="'l%-([%_%^%.]?[tdrzsnc])", b="'%1-%1"},
+ -- li-/la- + art. + lÄm
+ {a="l([ai])%-l%-(l)", b="l%1-%2-%2"},
+ -- assim. art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are additional characters)
+ {a="'(%^n)%-", b="'l-"}, -- ^n is lunar
+ {a="'([%_%^%.]?[tdrzsnc])%-", b="'%1-"},
+ -- li-/la- + art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-l%-(%^n)", b="l%1-l-%2"}, -- ^n is lunar
+ {a="l([ai])%-l%-([%_%^%.]?[tdrzsnc])", b="l%1-%2-%2"},
+ -- li-/la- + assim. art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-(%^n)%-(%^n)", b="l%1-l-%3"}, -- ^n is lunar
+ {a="l([ai])%-([%_%^%.]?[tdrzsnc])%-([%_%^%.]?[tdrzsnc])", b="l%1-%2-%3"},
+ -- art. with waá¹£la + initial unstable hamza
+ {a="'l%-(\"?[uai])", b="'l-%1"},
+ -- art. with waá¹£la + lunar consonant (i.e. what remains)
+ {a="'l%-", b="'l-"},
+ -- the silent wÄw
+ {a="uU$", b="u"},
+ {a="uU(%W)", b="u%1"},
+ {a="aU$", b="a"},
+ {a="aU(%W)", b="a%1"},
+ {a="iU$", b="i"},
+ {a="iU(%W)", b="i%1"},
+ -- words ending in -ÄT with silent wÄw/yÄʾ
+ {a="(_a)UA", b="A"},
+ {a="(_a)U", b="A"},
+ {a="(_a)I", b="A"}
+}
+
+idghamtrdmg = {
+ -- assimilations
+ {a="(n)(}?)(%s)([rlmnwy])", b="%4%2%3%4"},
+ {a="(n)(}?)(O)([rlmnwy])([%S]-O)", b="%4%2"}
+}
+
+digraphstrdmg = {
+ {a="([uai]%-)(\"?[uai])", b="%1'"}, -- hyphen + initial alif without hamza
+ -- the following two are replaced with the 4 lines next for now
+-- {a="^(\"?[uai])", b="%1"}, -- initial alif without hamza
+-- {a="(%W)(\"?[uai])", b="%1%2"}, -- initial alif without hamza
+-- {a="^(\"[uai])", b="'"}, -- initial alif without hamza
+-- {a="(%W)(\"[uai])", b="%1'"}, -- initial alif without hamza
+ {a="^(\"?[uai])", b="%1"}, -- initial alif without hamza
+ {a="(%W)(\"?[uai])", b="%1%2"}, -- initial alif without hamza
+ -- this is not necessary, take out for now:
+-- {a="([%_]?[uaiUAIY])(%s)([uai])", b="%1%2'"}, -- initial alif without hamza
+ {a="(aw)(O)(\"?[uai])([%S]-O)", b="%1u"},
+ {a="(aw)(%s)([%(%[%|%<]?)(\"?[uai])", b="%1u%2%3'"}, --p
+ {a="(ay)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(ay)(%s)([%(%[%|%<]?)(\"?[uai])", b="%1i%2%3'"}, --p
+ {a="(aW)(O)(\"?[uai])([%S]-O)", b="awu"},
+ {a="(UA)(O)(\"?[uai])([%S]-O)", b="u"},
+ {a="(%_A)(O)(\"?[uai])([%S]-O)", b="ạ"},
+ {a="(Y)(O)(\"?[uai])([%S]-O)", b="ạ"},
+ {a="(%_a)(O)(\"?[uai])([%S]-O)", b="a"},
+ {a="(A)(O)(\"?[uai])([%S]-O)", b="a"},
+ {a="([%_]?[Uu])(O)(\"?[uai])([%S]-O)", b="u"},
+ {a="([%_]?[Ii])(O)(\"?[uai])([%S]-O)", b="i"},
+ {a="(O[%S]-)([%'a]l%-)(O)(\"?[uai])", b="'"},
+ {a="(O[%S]-)([UAIYWuaiyw])(O)(\"?[uai])", b="'"},
+ {a="(aW)(%s)([%(%[%|%<]?)(\"?[uai])", b="awu%2%3%4"}, --p
+ {a="(UA)(%s)([%(%[%|%<]?)(\"?[uai])", b="u%2%3'"}, --p
+ {a="([^%_][uai])(%s)([%(%[%|%<]?)(\"?[uai])", b="%1%2%3'"}, --p
+ {a="(%_A)(%s)([%(%[%|%<]?)(\"?[uai])", b="ạ%2%3'"}, --p
+ {a="(Y)(%s)([%(%[%|%<]?)(\"?[uai])", b="ạ%2%3'"}, --p
+ {a="(%_a)(%s)([%(%[%|%<]?)(\"?[uai])", b="a%2%3'"}, --p
+ {a="(A)(%s)([%(%[%|%<]?)(\"?[uai])", b="a%2%3'"}, --p
+ {a="([%_]?[Uu])(%s)([%(%[%|%<]?)(\"?[uai])", b="u%2%3'"}, --p
+ {a="([%_]?[Ii])(%s)([%(%[%|%<]?)(\"?[uai])", b="i%2%3'"}, --p
+ -- ʾiÊ¿rÄb hyphen (begin)
+ {a="(%-)(\"?[UI]na)(%p*%s)", b="\\arbup{%2}%3"},
+ {a="(%-)(\"?[UI]na)(%p*)$", b="\\arbup{%2}%3"},
+ {a="(%-)(\"?At%.?[ui])(%p*%s)", b="\\arbup{%2}%3"},
+ {a="(%-)(\"?At%.?[ui])(%p*)$", b="\\arbup{%2}%3"},
+ {a="(%-)(\"?Ani)(%p*%s)", b="\\arbup{%2}%3"},
+ {a="(%-)(\"?Ani)(%p*)$", b="\\arbup{%2}%3"},
+ {a="(%-)(\"?%.?ayni)(%p*%s)", b="\\arbup{%2}%3"},
+ {a="(%-)(\"?%.?ayni)(%p*)$", b="\\arbup{%2}%3"},
+ {a="(%-)(\"?%.?[uai])(%p*%s)", b="\\arbup{%2}%3"},
+ {a="(%-)(\"?%.?[uai])(%p*)$", b="\\arbup{%2}%3"},
+ -- ʾiÊ¿rÄb hyphen (end) shorten long vowels preceding ʾalif
+ -- conjunctionis—without forgetting 'lla_dI
+ {a="(U)(A)", b="U"},
+ {a="(aW)(O)('[%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])([%S]-O)", b="awu"},
+ {a="(%_a)(O)('[%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])([%S]-O)", b="a"},
+ {a="(%_A)(O)('[%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])([%S]-O)", b="ạ"},
+ {a="(A)(O)('[%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])([%S]-O)", b="a"},
+ {a="(Y)(O)('[%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])([%S]-O)", b="ạ"},
+ {a="([%_]?[Uu])(O)('[%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])([%S]-O)", b="u"},
+ {a="([%_]?[Ii])(O)('[%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])([%S]-O)", b="i"},
+ --p (next 7 lines, just after %s)
+ {a="(aW)(%s)([%(%[%|%<]?['][%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])", b="awu%2%3"},
+ {a="(%_a)(%s)([%(%[%|%<]?['][%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])", b="a%2%3"},
+ {a="(%_A)(%s)([%(%[%|%<]?['][%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])", b="ạ%2%3"},
+ {a="(A)(%s)([%(%[%|%<]?['][%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])", b="a%2%3"},
+ {a="(Y)(%s)([%(%[%|%<]?['][%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])", b="ạ%2%3"},
+ {a="([%_]?[Uu])(%s)([%(%[%|%<]?['][%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])", b="u%2%3"},
+ {a="([%_]?[Ii])(%s)([%(%[%|%<]?['][%_%^%.]?[l'btjghxdrzs`fqkmnwy][%-l])", b="i%2%3"},
+ {a="%-%-", b=""},
+ {a="iyyaT(%p*)$", b="Ä«yaT%1"},
+ {a="iyyaT(%p*%s)", b="Ä«yaT%1"},
+ {a="iyy(%p*)$", b="Ä«%1"},
+ {a="iyy(%p*%s)", b="Ä«%1"},
+ -- {a="T([^uai])", b="%1"},
+ {a="T(\\arbup)", b="t%1"},
+ {a="([a%'][%_%^%.]?[tdrzsln]%-)(%S-)T([%(%[%|%<%s])(a[%_%^%.]?[tdrzsln]%-)", b="%1%2h%3%4"}, --p
+ {a="T([%(%[%|%<%s])(a[%_%^%.]?[tdrzsln]%-)", b="t%1%2"}, --p
+ {a="T([%|\"])", b="t%1"},
+ {a="T(%p*%s)", b="h%1"},
+ {a="T(%p*)$", b="h%1"},
+ {a="T(%p*)(%W)", b="h%1%2"},
+ {a="_t", b="ṯ"},
+ {a="%^g", b="ǧ"},
+ {a="%.h", b="ḥ"},
+ {a="_h", b="ḫ"},
+ {a="_d", b="á¸"},
+ {a="%^s", b="Å¡"},
+ {a="%.s", b="á¹£"},
+ {a="%.d", b="á¸"},
+ {a="%.t", b="á¹­"},
+ {a="%.z", b="ẓ"},
+ {a="%.g", b="Ä¡"},
+ {a="%.y", b="y"},
+ -- additional characters (begin)
+ {a="%^c", b="Ä"},
+ {a="%^z", b="ž"},
+ {a="%^n", b="ñ"},
+ -- additional characters (end)
+ -- the following needs to be moved above shortening rules
+-- {a="(U)(A)", b="Å«"},
+ {a="WA", b="w"},
+ {a="(a)W", b="%1w"},
+ {a="_A", b="ÄÌ£"},
+ {a="_u", b="Å«"},
+ {a="_a", b="Ä"},
+ {a="_i", b="Ä«"},
+ {a="%.b", b="ḅ"},
+ {a="%.f", b="f̣"},
+ {a="%.q", b="q̣"},
+ {a="%.k", b="k"},
+ {a="%.n", b="ṇ"},
+ {a="%^d", b="dÌ"}
+}
+
+singletrdmg = {
+ {a="b", b="b"},
+ {a="t", b="t"},
+ {a="j", b="ǧ"},
+ {a="x", b="ḫ"},
+ {a="d", b="d"},
+ {a="r", b="r"},
+ {a="z", b="z"},
+ {a="s", b="s"},
+ {a="`", b="Ê¿"},
+ {a="f", b="f"},
+ {a="q", b="q"},
+ {a="k", b="k"},
+ {a="l", b="l"},
+ {a="m", b="m"},
+ {a="n", b="n"},
+ {a="h", b="h"},
+ {a="w", b="w"},
+ {a="y", b="y"},
+ {a="T", b="t"},
+ -- additional characters (begin)
+ {a="p", b="p"},
+ {a="v", b="v"},
+ {a="g", b="g"},
+ -- additional characters (end)
+ {a="\"", b=""},
+ {a="B", b=""}
+}
+
+longvtrdmg = {
+ {a="A", b="Ä"},
+ {a="U", b="Å«"},
+ {a="I", b="Ä«"},
+ {a="aY", b="ay"},
+ {a="iY", b="Ä«"},
+ {a="Y", b="ÄÌ£"}
+}
+
+shortvtrdmg = {
+ {a="([uai])([uai])([uai])", b="/%1,%2,%3/"},
+ {a="([uai])([uai])", b="/%1,%2/"},
+ {a="%.u", b="u"},
+ {a="%.a", b="a"},
+ {a="%.i", b="i"},
+ {a="u", b="u"},
+ {a="a", b="a"},
+ {a="i", b="i"}
+}
+
+-- loc
+
+hamzatrloc = {
+ -- next lines for ʾalif alone
+ {a="(%.A)([^uai])", b=".|%2"},
+ {a="(%.A)([uai])", b="||%2"},
+ -- hard coded hamza
+ {a="|\"'", b="ʾ"},
+ {a="A\"'", b="ʾA"},
+ {a="[au]\"'", b="ʾ"},
+ {a="w\"'", b="ʾ"},
+ {a="i\"'", b="ʾ"},
+ {a="y\"'", b="ʾ"},
+ -- hamza takes tašdīd too
+ {a="''([Uu])", b="ʾʾ%1"},
+ {a="''([Aa])", b="ʾʾ%1"},
+ {a="''([Ii])", b="ʾʾ%1"},
+ -- initial long u and i (for a, see below)
+ {a="%'%_U", b="U"},
+ {a="%'%_I", b="I"},
+ -- taḫfīfu 'l-hamza
+ {a="^'u'([^uaiUAI])", b="U%1"},
+ {a="([%s%(%[%<%-])'u'([^uaiUAI])", b="%1U%2"},
+ {a="^'i'([^uaiUAI])", b="I%1"},
+ {a="([%s%(%[%<%-])'i'([^uaiUAI])", b="%1I%2"},
+ {a="^u'([^uaiUAI])", b="U%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])u'([^uaiUAI])", b="%1U%2"},
+ {a="^i'([^uaiUAI])", b="I%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])i'([^uaiUAI])", b="%1I%2"},
+ -- madda (historic writing below)
+ {a="^(')(A)", b="%2"},
+ {a="(%W)(')(A)", b="%1%3"},
+ {a="^'a'([^uaiUAI])", b="A%1"},
+ {a="(%W)'a'([^uaiUAI])", b="%1A%2"},
+ {a="'a'([^uaiUAI])", b="A%1"},
+ {a="^'a?A", b="A"},
+ {a="(%W)'a?A", b="%1A"},
+ {a="'a?A", b="ʾA"},
+ {a="(A)(')(i)$", b="%1ʾ%3"},
+ {a="(A)(')(i)(%W)", b="%1ʾ%3%4"},
+ {a="(A)(')(i)", b="%1ʾ%3"}, -- historic madda
+ {a="(A)(')", b="%1ʾ"}, -- historic madda
+ -- initial (needs both ^ and %W patterns)
+ {a="^(')([ua])", b="%2"},
+ {a="^(')(i)", b="%2"},
+ -- consider replacing initial %W with [%s%(%[%<%-]:
+ -- {a="(%W)(')([ua])", b="%1%3"},
+ -- {a="(%W)(')(i)", b="%1%3"},
+ {a="([%s%(%[%<%-])(')([ua])", b="%1%3"},
+ {a="([%s%(%[%<%-])(')(i)", b="%1%3"},
+ -- final
+ {a="([Iy])(')(aN)$", b="%1ʾ%3"},
+ {a="([Iy])(')(aN)(%W)", b="%1ʾ%3%4"},
+ {a="([^uai])(')([uai]N?)$", b="%1ʾ%3"},
+ {a="([^uai])(')([uai]N?)(%W)", b="%1ʾ%3%4"},
+ {a="([UI])(')([uai])$", b="%1ʾ%3"},
+ {a="([UI])(')([uai])(%W)", b="%1ʾ%3%4"},
+ -- middle
+ {a="(U)(')", b="%1ʾ"},
+ {a="([Iy])(')", b="%1ʾ"},
+ {a="([^uai])(')([uU])", b="%1ʾ%3"},
+ {a="([^uai])(')(%_?[aAY])", b="%1ʾ%3"},
+ {a="([^uai])(')([iI])", b="%1ʾ%3"},
+ {a="(u)(')([uU])", b="%1ʾ%3"},
+ {a="(u)(')(%_?[aAY])", b="%1ʾ%3"},
+ {a="(u)(')([iI])", b="%1ʾ%3"},
+ {a="(a)(')(%_?[aAY])", b="%1ʾ%3"},
+ {a="(a)(')([uU])", b="%1ʾ%3"},
+ {a="(a)(')([iI])", b="%1ʾ%3"},
+ {a="(i)(')(%_?[aAY])", b="%1ʾ%3"},
+ {a="(i)(')([uU])", b="%1ʾ%3"},
+ {a="(i)(')([iI])", b="%1ʾ%3"},
+ {a="(a)(')([^uaiUAI])", b="%1ʾ%3"},
+ {a="(u)(')([^uaiUAI])", b="%1ʾ%3"},
+ {a="(i)(')([^uaiUAI])", b="%1ʾ%3"}
+}
+
+tanwintrloc = {
+ {a="%-?uNU", b="un"},
+ {a="%-?aNU", b="an"},
+ {a="%-?iNU", b="in"},
+ {a="%-?iNI", b="in"},
+ {a="%-?(\"?At)%-?([ui])N", b="%1%2n"},
+ {a="%-?([ui])N", b="%1n"},
+ -- needed by \arbcolor:
+ {a="%-?(aN)(O[%S]-%_AO)", b="an"},
+ {a="%-?(aN)(O[%S]-YO)", b="an"},
+ {a="(O[%S]-TO)%-?(\"?aN)", b="an"},
+ {a="(O[%S]-[^TA]O)%-?(\"?aN)", b="an"},
+ --
+ {a="%-?(aN)(_A)", b="an"},
+ {a="%-?(aN)(Y)", b="an"},
+ {a="(T)%-?(\"?aN)", b="tan"},
+ {a="([^TA])%-?(\"?aN)", b="%1an"}
+}
+
+trigraphstrloc = { -- trigraphs or more
+ -- 'llatI / 'llad_I
+ {a="^'ll(a)([%_]?[dt])", b="all%1%2"},
+ {a="([%(%[%|%<%s])'ll(a)([%_]?[dt])", b="%1all%2%3"}, --p
+ -- al- + lÄm
+ {a="^(a)l%-(l)", b="%1l-%2"},
+ {a="(%s)(a)l%-(l)", b="%1%2l-%3"},
+ -- al- + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)l%-(%^n)", b="%1l-%2"}, -- ^n is lunar
+ {a="(%s)(a)l%-(%^n)", b="%1%2l-%3"}, -- ^n is lunar
+ {a="^(a)l%-([%_%^%.]?[tdrzsnc])", b="%1l-%2"},
+ {a="(%s)(a)l%-([%_%^%.]?[tdrzsnc])", b="%1%2l-%3"},
+ -- assim. art. + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)(%^n)%-", b="%1l-"}, -- ^n is lunar
+ {a="(%s)(a)(%^n)%-", b="%1%2l-"}, -- ^n is lunar
+ {a="^(a)([%_%^%.]?[tdrzsnc])%-", b="%1l-"},
+ {a="(%s)(a)([%_%^%.]?[tdrzsnc])%-", b="%1%2l-"},
+ -- al- + initial unstable hamza
+ {a="^(a)l%-([uai])", b="%1l-%2"},
+ {a="(%s)(a)l%-([uai])", b="%1%2l-%3"},
+ -- li-/la- + art. + initial unstable hamza is a special orthography
+ {a="l([ai])%-l%-([uai])", b="l%1-l-%2"},
+ -- al- + lunar consonant (i.e. what remains)
+ {a="^(a)l%-", b="%1l-"},
+ {a="(%s)(a)l%-", b="%1%2l-"},
+ -- art. with waá¹£la + lÄm
+ {a="'l%-(l)", b="al-%1"},
+ -- art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are additional characters)
+ {a="'l%-(%^n)", b="al-%1"}, -- ^n is lunar
+ {a="'l%-([%_%^%.]?[tdrzsnc])", b="al-%1"},
+ -- li-/la- + art. + lÄm
+ {a="l([ai])%-l%-(l)", b="l%1-l-%2"},
+ -- assim. art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are additional characters)
+ {a="'(%^n)%-", b="al-"}, -- ^n is lunar
+ {a="'([%_%^%.]?[tdrzsnc])%-", b="al-"},
+ -- li-/la- + art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-l%-(%^n)", b="l%1-l-%2"}, -- ^n is lunar
+ {a="l([ai])%-l%-([%_%^%.]?[tdrzsnc])", b="l%1-l-%2"},
+ -- li-/la- + assim. art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-(%^n)%-(%^n)", b="l%1-l-%3"}, -- ^n is lunar
+ {a="l([ai])%-([%_%^%.]?[tdrzsnc])%-([%_%^%.]?[tdrzsnc])", b="l%1-l-%3"},
+ -- art. with waá¹£la + initial unstable hamza
+ {a="'l%-([uai])", b="al-%1"},
+ -- art. with waá¹£la + lunar consonant (i.e. what remains)
+ {a="'l%-", b="al-"},
+ -- the silent wÄw
+ {a="uU$", b="u"},
+ {a="uU(%W)", b="u%1"},
+ {a="aU$", b="a"},
+ {a="aU(%W)", b="a%1"},
+ {a="iU$", b="i"},
+ {a="iU(%W)", b="i%1"},
+ -- words ending in -ÄT with silent wÄw/yÄʾ
+ {a="(_a)UA", b="A"},
+ {a="(_a)U", b="A"},
+ {a="(_a)I", b="A"}
+}
+
+digraphstrloc = {
+ -- discard the ʾiÊ¿rÄb hyphen (begin)
+ {a="(%-)(\"?[UI]na)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?[UI]na)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?At[ui])(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?At[ui])(%p*)$", b="%2%3"},
+ {a="(%-)(\"?Ani)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?Ani)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?ayni)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?ayni)(%p*)$", b="%2%3"},
+ {a="(%-)([uai])(%p*%s)", b="%2%3"},
+ {a="(%-)([uai])(%p*)$", b="%2%3"},
+ -- discard the ʾiÊ¿rÄb hyphen (end)
+ {a="(%-)(\"?[uai])", b="%1%2"}, -- hyphen + initial alif without hamza
+ {a="^(\"?[uai])", b="%1"}, -- initial alif without hamza
+ {a="(%s)([uai])", b="%1%2"}, -- initial alif without hamza
+ {a="%-%-", b=""},
+ {a="uww", b="Å«w"},
+ {a="iyy(%p*)$", b="Ä«%1"},
+ {a="iyy(%p*%s)", b="Ä«%1"},
+ {a="iyy", b="Ä«y"},
+ {a="([tkdsg])(h)", b="%1'%2"},
+ -- {a="T([^uai])", b="h%1"},
+ {a="([a%']l%-)(%S-)T([%(%[%|%<%s])(al%-)", b="%1%2h%3%4"}, --p
+ {a="T([%(%[%|%<%s])(al%-)", b="t%1%2"}, --p
+ {a="T([%|\"])", b="t%1"},
+ {a="T(%p*)$", b="h%1"},
+ {a="T(%p*%s)", b="h%1"},
+ {a="_t", b="th"},
+ {a="%^g", b="j"},
+ {a="%.h", b="ḥ"},
+ {a="_h", b="kh"},
+ {a="_d", b="dh"},
+ {a="%^s", b="sh"},
+ {a="%.s", b="á¹£"},
+ {a="%.d", b="á¸"},
+ {a="%.t", b="á¹­"},
+ {a="%.z", b="ẓ"},
+ {a="%.g", b="gh"},
+ {a="%.y", b="y"},
+ -- additional characters (begin)
+ {a="%^c", b="ch"},
+ {a="%^z", b="zh"},
+ {a="%^n", b="ñ"},
+ -- additional characters (end)
+ {a="(U)(A)", b="Å«"},
+ {a="WA", b="w"},
+ {a="(a)W", b="%1w"},
+ {a="_A", b="á"},
+ {a="_u", b="Å«"},
+ {a="_a", b="Ä"},
+ {a="_i", b="Ä«"},
+ {a="%.b", b="b"},
+ {a="%.f", b="f"},
+ {a="%.q", b="q"},
+ {a="%.k", b="k"},
+ {a="%.n", b="n"},
+ {a="%^d", b="d"}
+}
+
+singletrloc = {
+ {a="b", b="b"},
+ {a="t", b="t"},
+ {a="j", b="j"},
+ {a="x", b="kh"},
+ {a="d", b="d"},
+ {a="r", b="r"},
+ {a="z", b="z"},
+ {a="s", b="s"},
+ {a="`", b="`"},
+ {a="f", b="f"},
+ {a="q", b="q"},
+ {a="k", b="k"},
+ {a="l", b="l"},
+ {a="m", b="m"},
+ {a="n", b="n"},
+ {a="h", b="h"},
+ {a="w", b="w"},
+ {a="y", b="y"},
+ {a="T", b="t"},
+ -- additional characters (begin)
+ {a="p", b="p"},
+ {a="v", b="v"},
+ {a="g", b="g"},
+ -- additional characters (end)
+ {a="\"", b=""},
+ {a="B", b=""}
+}
+
+longvtrloc = {
+ {a="A", b="Ä"},
+ {a="U", b="Å«"},
+ {a="I", b="Ä«"},
+ {a="aY", b="ay"},
+ {a="iY", b="Ä«"},
+ {a="Y", b="á"},
+}
+
+shortvtrloc = {
+ {a="([uai])([uai])([uai])", b="/%1,%2,%3/"},
+ {a="([uai])([uai])", b="/%1,%2/"},
+ {a="%.u", b="u"},
+ {a="%.a", b="a"},
+ {a="%.i", b="i"},
+ {a="u", b="u"},
+ {a="a", b="a"},
+ {a="i", b="i"}
+}
+
+finaltrloc = {
+ {a="ʾ", b="'"},
+}
+
+-- arabica
+
+hamzatrarabica = { -- ≠ from hamzatrloc: initial hamza has to be held
+ -- next lines for ʾalif alone
+ {a="(%.A)([^uai])", b=".|%2"},
+ {a="(%.A)([uai])", b="||%2"},
+ -- hard coded hamza
+ {a="|\"'", b="ʾ"},
+ {a="A\"'", b="ʾA"},
+ {a="[au]\"'", b="ʾ"},
+ {a="w\"'", b="ʾ"},
+ {a="i\"'", b="ʾ"},
+ {a="y\"'", b="ʾ"},
+ -- hamza takes tašdīd too
+ {a="''([Uu])", b="ʾʾ%1"},
+ {a="''([Aa])", b="ʾʾ%1"},
+ {a="''([Ii])", b="ʾʾ%1"},
+ -- initial long u and i (for a, see below)
+ {a="%'%_U", b="U"},
+ {a="%'%_I", b="I"},
+ -- taḫfīfu 'l-hamza
+ {a="^'u'([^uaiUAI])", b="U%1"},
+ {a="([%s%(%[%<%-])'u'([^uaiUAI])", b="%1U%2"},
+ {a="^'i'([^uaiUAI])", b="I%1"},
+ {a="([%s%(%[%<%-])'i'([^uaiUAI])", b="%1I%2"},
+ {a="^u'([^uaiUAI])", b="U%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])u'([^uaiUAI])", b="%1U%2"},
+ {a="^i'([^uaiUAI])", b="I%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])i'([^uaiUAI])", b="%1I%2"},
+ -- madda (historic writing below)
+ {a="^(')(A)", b="%2"},
+ {a="(%W)(')(A)", b="%1%3"},
+ {a="^'a'([^uaiUAI])", b="A%1"},
+ {a="(%W)'a'([^uaiUAI])", b="%1A%2"},
+ {a="'a'([^uaiUAI])", b="A%1"},
+ {a="^'a?A", b="A"},
+ {a="(%W)'a?A", b="%1A"},
+ {a="'a?A", b="ʾA"},
+ {a="(A)(')(i)$", b="%1ʾ%3"},
+ {a="(A)(')(i)(%W)", b="%1ʾ%3%4"},
+ {a="(A)(')(i)", b="%1ʾ%3"}, -- historic madda
+ {a="(A)(')", b="%1ʾ"}, -- historic madda
+ -- initial (needs both ^ and %W patterns):
+ -- hold it for now (see below, beginning of digraphs table)
+ {a="^(')([ua])", b="@%2"},
+ {a="^(')(i)", b="@%2"},
+ -- consider replacing initial %W with [%s%(%[%<%-]:
+ -- {a="(%W)(')([ua])", b="%1@%3"},
+ -- {a="(%W)(')(i)", b="%1@%3"},
+ {a="([%s%(%[%<%-])(')([ua])", b="%1@%3"},
+ {a="([%s%(%[%<%-])(')(i)", b="%1@%3"},
+ -- final
+ {a="([Iy])(')(aN)$", b="%1ʾ%3"},
+ {a="([Iy])(')(aN)(%W)", b="%1ʾ%3%4"},
+ {a="([^uai])(')([uai]N?)$", b="%1ʾ%3"},
+ {a="([^uai])(')([uai]N?)(%W)", b="%1ʾ%3%4"},
+ {a="([UI])(')([uai])$", b="%1ʾ%3"},
+ {a="([UI])(')([uai])(%W)", b="%1ʾ%3%4"},
+ -- middle
+ {a="(U)(')", b="%1ʾ"},
+ {a="([Iy])(')", b="%1ʾ"},
+ {a="([^uai])(')([uU])", b="%1ʾ%3"},
+ {a="([^uai])(')(%_?[aAY])", b="%1ʾ%3"},
+ {a="([^uai])(')([iI])", b="%1ʾ%3"},
+ {a="(u)(')([uU])", b="%1ʾ%3"},
+ {a="(u)(')(%_?[aAY])", b="%1ʾ%3"},
+ {a="(u)(')([iI])", b="%1ʾ%3"},
+ {a="(a)(')(%_?[aAY])", b="%1ʾ%3"},
+ {a="(a)(')([uU])", b="%1ʾ%3"},
+ {a="(a)(')([iI])", b="%1ʾ%3"},
+ {a="(i)(')(%_?[aAY])", b="%1ʾ%3"},
+ {a="(i)(')([uU])", b="%1ʾ%3"},
+ {a="(i)(')([iI])", b="%1ʾ%3"},
+ {a="(a)(')([^uaiUAI])", b="%1ʾ%3"},
+ {a="(u)(')([^uaiUAI])", b="%1ʾ%3"},
+ {a="(i)(')([^uaiUAI])", b="%1ʾ%3"}
+}
+
+trigraphstrarabica = { -- trigraphs or more
+ -- 'llatI / 'llad_I
+ {a="^'ll(a)([%_]?[dt])", b="ll%1%2"},
+ {a="([%-%(%[%|%<%s])'ll(a)([%_]?[dt])", b="%1ll%2%3"}, --p
+ -- al- + lÄm
+ {a="^(a)l%-(l)", b="%1l-%2"},
+ {a="(%s)(a)l%-(l)", b="%1%2l-%3"},
+ -- al- + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)l%-(%^n)", b="%1l-%2"}, -- ^n is lunar
+ {a="(%s)(a)l%-(%^n)", b="%1%2l-%3"}, -- ^n is lunar
+ {a="^(a)l%-([%_%^%.]?[tdrzsnc])", b="%1l-%2"},
+ {a="(%s)(a)l%-([%_%^%.]?[tdrzsnc])", b="%1%2l-%3"},
+ -- assim. art. + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)(%^n)%-", b="%1l-"}, -- ^n is lunar
+ {a="(%s)(a)(%^n)%-", b="%1%2l-"}, -- ^n is lunar
+ {a="^(a)([%_%^%.]?[tdrzsnc])%-", b="%1l-"},
+ {a="(%s)(a)([%_%^%.]?[tdrzsnc])%-", b="%1%2l-"},
+ -- al- + initial unstable hamza
+ {a="^(a)l%-([uai])", b="%1l-%2"},
+ {a="(%s)(a)l%-([uai])", b="%1%2l-%3"},
+ -- li-/la- + art. + initial unstable hamza is a special orthography
+ {a="l([ai])%-l%-([uai])", b="l%1-l-%2"},
+ -- al- + lunar consonant (i.e. what remains)
+ {a="^(a)l%-", b="%1l-"},
+ {a="(%s)(a)l%-", b="%1%2l-"},
+ -- art. with waá¹£la + lÄm
+ {a="'l%-(l)", b="l-%1"},
+ -- art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are additional characters)
+ {a="'l%-(%^n)", b="l-%1"}, -- ^n is lunar
+ {a="'l%-([%_%^%.]?[tdrzsnc])", b="l-%1"},
+ -- li-/la- + art. + lÄm
+ {a="l([ai])%-l%-(l)", b="l%1-l-%2"},
+ -- assim. art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are additional characters)
+ {a="'(%^n)%-", b="l-"}, -- ^n is lunar
+ {a="'([%_%^%.]?[tdrzsnc])%-", b="l-"},
+ -- li-/la- + art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-l%-(%^n)", b="l%1-l-%2"}, -- ^n is lunar
+ {a="l([ai])%-l%-([%_%^%.]?[tdrzsnc])", b="l%1-l-%2"},
+ -- li-/la- + assim. art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-(%^n)%-(%^n)", b="l%1-l-%3"}, -- ^n is lunar
+ {a="l([ai])%-([%_%^%.]?[tdrzsnc])%-([%_%^%.]?[tdrzsnc])", b="l%1-l-%3"},
+ -- art. with waá¹£la + initial unstable hamza
+ {a="'l%-([uai])", b="l-%1"},
+ -- art. with waá¹£la + lunar consonant (i.e. what remains)
+ {a="'l%-", b="l-"},
+ -- the silent wÄw
+ {a="uU$", b="u"},
+ {a="uU(%W)", b="u%1"},
+ {a="aU$", b="a"},
+ {a="aU(%W)", b="a%1"},
+ {a="iU$", b="i"},
+ {a="iU(%W)", b="i%1"},
+ -- words ending in -ÄT with silent wÄw/yÄʾ
+ {a="(_a)UA", b="A"},
+ {a="(_a)U", b="A"},
+ {a="(_a)I", b="A"}
+}
+
+digraphstrarabica = {
+ {a="([uai]%-)(\"?[uai])", b="%1"}, -- hyphen + initial alif without hamza
+ {a="([UAIYuai])(%s)([%(%[%|%<]?)(\"?[uai])", b="%1%2%3"}, --p
+ {a="(O[%S]-)([UAIuai])(O)(\"?[uai])", b=""},
+ {a="@", b=""}, -- remove the tag before the former hamza
+ -- discard the ʾiÊ¿rÄb hyphen (begin)
+ {a="(%-)(\"?[UI]na)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?[UI]na)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?At[ui])(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?At[ui])(%p*)$", b="%2%3"},
+ {a="(%-)(\"?Ani)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?Ani)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?ayni)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?ayni)(%p*)$", b="%2%3"},
+ {a="(%-)([uai])(%p*%s)", b="%2%3"},
+ {a="(%-)([uai])(%p*)$", b="%2%3"},
+ -- discard the ʾiÊ¿rÄb hyphen (end)
+ {a="(%-)(\"?[uai])", b="%1%2"}, -- hyphen + initial alif without hamza
+ {a="^(\"?[uai])", b="%1"}, -- initial alif without hamza
+ {a="(%s)([uai])", b="%1%2"}, -- initial alif without hamza
+ {a="%-%-", b=""},
+ {a="iyy(%p*)$", b="Ä«%1"},
+ {a="iyy(%p*%s)", b="Ä«%1"},
+ -- {a="T([^uai])", b="h%1"},
+ {a="([a%']l%-)(%S-)aT([%(%[%|%<%s])(al%-)", b="%1%2a%3%4"}, --p
+ {a="aT([%(%[%|%<%s])(al%-)", b="at%1%2"}, --p
+ {a="T([%|\"])", b="t%1"},
+ {a="aT(%p*)$", b="a%1"},
+ {a="aT(%p*%s)", b="a%1"},
+ {a="_t", b="ṯ"},
+ {a="%^g", b="ǧ"},
+ {a="%.h", b="ḥ"},
+ {a="_h", b="ḫ"},
+ {a="_d", b="á¸"},
+ {a="%^s", b="Å¡"},
+ {a="%.s", b="á¹£"},
+ {a="%.d", b="á¸"},
+ {a="%.t", b="á¹­"},
+ {a="%.z", b="ẓ"},
+ {a="%.g", b="Ä¡"},
+ {a="%.y", b="y"},
+ -- additional characters (begin)
+ {a="%^c", b="Ä"},
+ {a="%^z", b="ž"},
+ {a="%^n", b="ñ"},
+ -- additional characters (end)
+ {a="(U)(A)", b="Å«"},
+ {a="WA", b="w"},
+ {a="(a)W", b="%1w"},
+ {a="_A", b="Ä"},
+ {a="_u", b="Å«"},
+ {a="_a", b="Ä"},
+ {a="_i", b="Ä«"},
+ {a="%.b", b="b"},
+ {a="%.f", b="f"},
+ {a="%.q", b="q"},
+ {a="%.k", b="k"},
+ {a="%.n", b="n"},
+ {a="%^d", b="d"}
+}
+
+singletrarabica = {
+ {a="b", b="b"},
+ {a="t", b="t"},
+ {a="j", b="ǧ"},
+ {a="x", b="ḫ"},
+ {a="d", b="d"},
+ {a="r", b="r"},
+ {a="z", b="z"},
+ {a="s", b="s"},
+ {a="`", b="Ê¿"},
+ {a="f", b="f"},
+ {a="q", b="q"},
+ {a="k", b="k"},
+ {a="l", b="l"},
+ {a="m", b="m"},
+ {a="n", b="n"},
+ {a="h", b="h"},
+ {a="w", b="w"},
+ {a="y", b="y"},
+ {a="T", b="t"},
+ -- additional characters (begin)
+ {a="p", b="p"},
+ {a="v", b="v"},
+ {a="g", b="g"},
+ -- additional characters (end)
+ {a="\"", b=""},
+ {a="B", b=""}
+}
+
+longvtrarabica = {
+ {a="aY", b="ay"},
+ {a="iY", b="Ä«"},
+ {a="[AY]", b="Ä"},
+ {a="U", b="Å«"},
+ {a="I", b="Ä«"}
+}
diff --git a/macros/luatex/latex/arabluatex/arabluatex_voc.lua b/macros/luatex/latex/arabluatex/arabluatex_voc.lua
new file mode 100644
index 0000000000..54c324c428
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/arabluatex_voc.lua
@@ -0,0 +1,903 @@
+--[[
+This file is part of the `arabluatex' package
+
+ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX
+Copyright (C) 2016--2019 Robert Alessi
+
+Please send error reports and suggestions for improvements to Robert
+Alessi <alessi@robertalessi.net>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see
+<http://www.gnu.org/licenses/>.
+--]]
+
+arbmarks = {
+ {a="@bismillah", b="\\arabicfont{}^^^^fdfd", c="\\arb[trans]{bi-ismi \\uc{'l-l_ahi} 'l-ra.hm_ani 'l-ra.hImi}"},
+ {a="@salam", b="\\arabicfont{}^^^^fdf5", c="\\arb[trans]{.sall_A\\arbnull{'l-l_ahu} \\uc{'l-l_ahu} `alay-hi wa-sallama}"},
+ {a="@jalla", b="\\arabicfont{}^^^^fdfb", c="\\arb[trans]{^galla ^galAla-hu}"},
+ {a="@slm", b="\\arabicfont{}^^^^fdfa", c="\\arb[trans]{.sall_A\\arbnull{'l-l_ahu} \\uc{'l-l_ahu} `alay-hi wa-sallama}"}
+}
+
+abjad = {
+{"a\"'", "b", "j", "d", "h", "w", "z", ".h", ".t"},
+{"y", "k", "l", "m", "n", "s", "`", "f", ".s", },
+{"q", "r", "^s", "t", "_t", "x", "_d", ".d", ".z", },
+{".g"}
+}
+
+numbers = {
+ {a="0", b="Ù "},
+ {a="1", b="Ù¡"},
+ {a="2", b="Ù¢"},
+ {a="3", b="Ù£"},
+ {a="4", b="Ù¤"},
+ {a="5", b="Ù¥"},
+ {a="6", b="Ù¦"},
+ {a="7", b="Ù§"},
+ {a="8", b="Ù¨"},
+ {a="9", b="Ù©"}
+}
+
+raw = {
+ {a="A", b="َا"},
+ {a="U", b="ÙÙˆ"},
+ {a="I", b="ÙÙŠ"},
+ {a="b", b="ب"},
+ {a="t", b="ت"},
+ {a="j", b="ج"},
+ {a="x", b="Ø®"},
+ {a="d", b="د"},
+ {a="r", b="ر"},
+ {a="z", b="ز"},
+ {a="s", b="س"},
+ {a="f", b="Ù"},
+ {a="`", b="ع"},
+ {a="f", b="Ù"},
+ {a="q", b="Ù‚"},
+ {a="k", b="Ùƒ"},
+ {a="l", b="Ù„"},
+ {a="m", b="Ù…"},
+ {a="n", b="Ù†"},
+ {a="h", b="Ù‡"},
+ {a="w", b="Ùˆ"},
+ {a="y", b="ÙŠ"},
+ {a="T", b="Ø©"},
+ {a="u", b="Ù"},
+ {a="a", b="ÙŽ"},
+ {a="i", b="Ù"}
+}
+
+buckwalter = {
+ --- hard coded madda: hold it for now
+ {a="%|", b="@"},
+ {a="M", b="@"}, -- BW safe
+ {a="%_", b="--"}, -- taṭwīl
+ -- prevent any unwanted Å¡adda from being generated
+ {a="bb", b="b|b"},
+ {a="tt", b="t|t"},
+ {a="vv", b="v|v"},
+ {a="jj", b="j|j"},
+ {a="HH", b="H|H"},
+ {a="xx", b="x|x"},
+ {a="dd", b="d|d"},
+ {a="%*%*", b="*|*"},
+ {a="VV", b="V|V"}, -- BW safe
+ {a="rr", b="r|r"},
+ {a="ss", b="s|s"},
+ {a="%$%$", b="$|$"},
+ {a="cc", b="c|c"}, -- BW safe
+ {a="SS", b="S|S"},
+ {a="DD", b="D|D"},
+ {a="TT", b="T|T"},
+ {a="ZZ", b="Z|Z"},
+ {a="EE", b="E|E"},
+ {a="gg", b="g|g"},
+ {a="ff", b="f|f"},
+ {a="qq", b="q|q"},
+ {a="kk", b="k|k"},
+ {a="ll", b="l|l"},
+ {a="mm", b="m|m"},
+ {a="nn", b="n|n"},
+ {a="hh", b="h|h"},
+ {a="ww", b="w|w"},
+ {a="yy", b="y|y"},
+ -- hamza begin
+ -- look into this later on:
+-- {a="%>a?A", b="@@@"}, -- hold this (madda)
+-- {a="%>a\'([^uai])", b="@@@%1"}, -- hold this (madda)
+ {a="a?A\'", b="@@"}, -- hold this (classic madda)
+ {a="\'", b="|\"\'"},
+ {a="C", b="|\"\'"}, -- BW safe
+ {a="%>", b="a\"\'"},
+ {a="O", b="a\"\'"}, -- BW safe
+ {a="%&", b="w\"\'"},
+ {a="W", b="w\"\'"}, -- BW safe
+ {a="%<", b="i\"\'"},
+ {a="I", b="i\"\'"}, -- BW safe
+ {a="%]", b="y\"\'"},
+ {a="Q", b="y\"\'"},
+ -- hamza end
+ -- trigraphs
+ {a="^Aal%-?", b="al-"},
+ {a="(%W)Aal%-?", b="%1al-"},
+ {a="(%s)Aal%-?", b="%1al-"},
+ {a="([%-%s])Al%-?", b="%1\'l-"},
+ {a="^A", b="a"},
+ {a="(%W)A", b="%1a"},
+ {a="(%s)A", b="%1a"},
+ {a="(al%-[%g])(%~)", b="%1"},
+ {a="(\'l%-[%g])(%~)", b="%1"},
+ -- digraphs begin
+ {a="aA", b="A"},
+ {a="uw([^%~])", b="U%1"},
+ {a="iy([^%~])", b="I%1"},
+ -- digraphs end
+ -- madda: get it back now
+-- {a="%@%@%@", b="\'A"},
+ {a="%@%@", b="A\'"}, -- give back classic madda
+ {a="%@", b="A\"\'"}, -- hard coded madda
+ -- Å¡adda:
+ {a="([%g])(%~)", b="%1%1"},
+ {a="%`", b="_a"},
+ {a="e", b="_a"}, -- BW safe
+ {a="v", b="_t"},
+ {a="H", b=".h"},
+ {a="%*", b="_d"},
+ {a="V", b="_d"}, -- BW safe
+ {a="%$", b="^s"},
+ {a="c", b="^s"}, -- BW safe
+ {a="S", b=".s"},
+ {a="D", b=".d"},
+ {a="T", b=".t"},
+ {a="Z", b=".z"},
+ {a="E", b="`"},
+ {a="g", b=".g"},
+ {a="p", b="T"},
+ {a="N", b="uN"},
+ {a="F", b="aN"},
+ {a="K", b="iN"},
+ {a="o", b="\""},
+ {a="P", b="O"}, -- pass on to \arbnull
+ -- hard-coded connective alif
+ {a="%[", b="Ù±"},
+ {a="L", b="Ù±"} -- BW safe
+}
+
+hamza = {
+ -- next line for ʾiÊ¿rÄb hyphen
+ {a="(')(%-)([uaiUAI])", b="%1%3"},
+ -- next lines for ʾalif alone
+ {a="(%.A)([uai]?)l%-(%^n)", b="ا%2ل%3"}, --additional (^n is lunar)
+ {a="([%(%[%|%<%s%-O])(%.A)([uai]?)l%-(%^n)", b="%1ا%3%4"}, --additional (^n is lunar) --p
+ {a="(%.A)([uai]?)l%-([%_%^%.]?[tdrzsnc])", b="ا%2ل%3%3"},
+ {a="([%(%[%|%<%s%-O])(%.A)([uai]?)l%-([%_%^%.]?[tdrzsnc])", b="%1ا%3ل%4%4"}, --p
+ {a="%.A", b="ا"},
+ -- hard coded hamza
+ {a="|\"'", b="Ø¡"},
+ {a="A\"'", b="Ø¢"},
+ {a="[au]\"'", b="Ø£"},
+ {a="w\"'", b="ؤ"},
+ {a="i\"'", b="Ø¥"},
+ {a="y\"'", b="ئ"},
+ -- hamza takes tašdīd too
+ {a="''([Uu])", b="ؤؤ%1"},
+ {a="''([Aa])", b="أأ%1"},
+ {a="''([Ii])", b="ئئ%1"},
+ -- inseparable adverbial particle 'a- + 'a
+ {a="\'(a)%-\'(a)", b="أ%1اأ%2"},
+ -- initial long u and i (for a, see below)
+ {a="%'%_U", b="Ø£U"},
+ {a="%'%_I", b="Ø¥I"},
+ -- taḫfīfu 'l-hamza
+ {a="'u'([^uaiUAI])", b="Ø£U%1"},
+ {a="'i'([^uaiUAI])", b="Ø¥I%1"},
+ {a="([wf]a)%-\'([^uaiUAIl][^%-])", b="%1أْ%2"},
+ {a="^u'([^uaiUAI])", b="اU%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])u'([^uaiUAI])", b="%1اU%2"},
+ {a="^i'([^uaiUAI])", b="اI%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])i'([^uaiUAI])", b="%1اI%2"},
+ -- madda (historic writing below)
+ {a="'a'([^uaiUAI])", b="Ø¢%1"},
+ {a="([^uiyUI])\'a?A([%_%^%.]?[%`%'btjghxdrzsfqklmnywAY])", b="%1Ø¢%2"},
+ {a="^\'a?A([%_%^%.]?[%`%'btjghxdrzsfqklmnywAY])", b="Ø¢%1"},
+ {a="\'a?A(O[%_%^%.]?[%`%'btjghxdrzsfqklmnywAY]-O)", b="Ø¢"},
+ {a="(%W)\'a?A([%_%^%.]?[%`%'btjghxdrzsfqklmnywAY])", b="%1Ø¢%2"},
+ {a="(A)(O%'[%S]-O)", b="Ø¢"},
+ {a="(A)(')(uN?%p*)$", b="aآء%3"},
+ {a="(A)(')(uN?)(%p*%s)", b="aآء%3%4"},
+ {a="(A)(')(iN?%p*)$", b="aآء%3"},
+ {a="(A)(')(iN?)(%p*%s)", b="aآء%3%4"},
+ {a="(A)(')([iI])", b="aآئ%3"}, -- historic madda
+ {a="(A)(')(u)", b="aآؤ%3"}, -- historic madda
+ {a="(A)(')", b="aآء"}, -- historic madda
+ -- initial (needs both ^ and %W patterns)
+ -- 'aw: the diphthong is to be resolved into 'awi' (next 8 lines)
+ {a="^('aw)(O)('[%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(%W)('aw)(O)('[%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1%2i"},
+ {a="^('aw)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(%W)('aw)(O)(\"?[uai])([%S]-O)", b="%1%2i"},
+ {a="^('aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ {a="(%W)('aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1%2i%3%4"},
+ {a="^('aw)(%s)([%(%[%|%<]?\"?[uai])", b="%1i%2%3"}, --p
+ {a="(%W)('aw)(%s)([%(%[%|%<]?\"?[uai])", b="%1%2i%3%4"}, --p
+ -- then the 'initial' rules for the remaining cases
+ {a="^(')([ua])", b="Ø£%2"},
+ {a="^(')(i)", b="Ø¥%2"},
+ -- consider replacing initial %W with [%s%(%[%<%-]:
+ -- {a="(%W)(')([ua])", b="%1Ø£%3"},
+ -- {a="(%W)(')(i)", b="%1Ø¥%3"},
+ {a="([%s%(%[%<%-])(')([ua])", b="%1Ø£%3"},
+ {a="([%s%(%[%<%-])(')(i)", b="%1Ø¥%3"},
+ -- final
+ -- mi'aT is special orthography (unlike ^say'aN and .zim'aN):
+ -- {a="(%^sa%.?[yY])(\"?%|?)(%')(aN)", b="%1%2ئ%4"}, --new
+ -- {a="(.zi?m)(%')(aN)", b="%1ئ%3"}, --new
+ {a="(mi)(%')(a[Tt])", b="%1ائ%3"},
+ {a="(mi)(%')(aN%_?[AY])", b="%1Ø£%3"},
+ -- final hamzah is on the line after a letter of prolongation or a
+ -- consonant with sukūn
+ {a="([^Auai])(')(\"?[uai]N?)(%p*)$", b="%1Ø¡%3%4"}, --new
+ {a="([^Auai])(')(\"?[uai]N?)(%p*%s)", b="%1Ø¡%3%4"},
+-- u
+ {a="(u)(')([uai]N?%p*)$", b="%1ؤ%3"},
+ {a="(u)(')([uai]N?)(%p*%s)", b="%1ؤ%3%4"},
+ {a="(u)(')(%p*)$", b="%1ؤ%3"},
+ {a="(u)(')(%p*%s)", b="%1ؤ%3"},
+-- a
+ {a="(a)(')(A%p*)$", b="%1Ø¢"},
+ {a="(a)(')(A)(%p*%s)", b="%1Ø¢%4"},
+ {a="(a)(')([u]N?%p*)$", b="%1Ø£%3"},
+ {a="(a)(')([u]N?)(%p*%s)", b="%1Ø£%3%4"},
+ {a="(a)(')(a%p*)$", b="%1Ø£%3"},
+ {a="(a)(')(a)(%p*%s)", b="%1Ø£%3%4"},
+ {a="(a)(')(aN%p*)$", b="%1أً"},
+ {a="(a)(')(aN)(%p*%s)", b="%1أً%4"},
+ {a="(a)(')([i]N?%p*)$", b="%1Ø¥%3"},
+ {a="(a)(')([i]N?)(%p*%s)", b="%1Ø¥%3%4"},
+ {a="(a)(')(%p*)$", b="%1Ø£%3"},
+ {a="(a)(')(%p*%s)", b="%1Ø£%3"},
+-- i
+ {a="(i)(')([uai]N?%p*)$", b="%1ئ%3"},
+ {a="(i)(')([uai]N?)(%p*%s)", b="%1ئ%3%4"},
+ {a="(i)(')(%p*)$", b="%1ئ%3"},
+ {a="(i)(')(%p*%s)", b="%1ئ%3"},
+--
+ -- middle
+ {a="([UIwy])(')", b="%1Ø¡"}, --new
+ -- {a="([Iy])(')", b="%1ئ"}, -- included in the above line
+ {a="([^uai])(')([uU])", b="%1ؤ%3"},
+ {a="([^uai])(')(%_?[aAY])", b="%1Ø£%3"},
+ {a="([^uai])(')([iI])", b="%1ئ%3"},
+ {a="(u)(')([uU])", b="%1ؤ%3"},
+ {a="(u)(')(%_?[aAY])", b="%1ؤ%3"},
+ {a="(u)(')([iI])", b="%1ئ%3"},
+ {a="(a)(')(%_?[aAY])", b="%1Ø£%3"},
+ {a="(a)(')([uU])", b="%1ؤ%3"},
+ {a="(a)(')([iI])", b="%1ئ%3"},
+ {a="(i)(')(%_?[aAY])", b="%1ئ%3"},
+ {a="(i)(')([uU])", b="%1ئ%3"},
+ {a="(i)(')([iI])", b="%1ئ%3"},
+ {a="(a)(')([^uaiUAI])", b="%1Ø£%3"},
+ {a="(u)(')([^uaiUAI])", b="%1ؤ%3"},
+ {a="(i)(')([^uaiUAI])", b="%1ئ%3"}
+}
+
+hamzaeasy = { -- differences marked below with 'easy'
+ -- next line for ʾiÊ¿rÄb hyphen
+ {a="(')(%-)([uaiUAI])", b="%1%3"},
+ -- next lines for ʾalif alone (easy)
+ {a="(%.A)([uai]?)l%-(%^n)", b="ا%2ل%3"}, --additional (^n is lunar)
+ {a="([%(%[%|%<%s%-O])(%.A)([uai]?)l%-(%^n)", b="%1ا%3%4"}, --additional (^n is lunar) --p
+ {a="(%.A)([uai]?)l%-([%_%^%.]?[tdrzsnc])", b="ا%2ل%3"},
+ {a="([%(%[%|%<%s%-O])(%.A)([uai]?)l%-([%_%^%.]?[tdrzsnc])", b="%1ا%3ل%4"}, --p
+ {a="%.A", b="ا"},
+ -- hard coded hamza
+ {a="|\"'", b="Ø¡"},
+ {a="A\"'", b="Ø¢"},
+ {a="[au]\"'", b="Ø£"},
+ {a="w\"'", b="ؤ"},
+ {a="i\"'", b="Ø¥"},
+ {a="y\"'", b="ئ"},
+ -- hamza takes tašdīd too
+ {a="''([Uu])", b="ؤؤ%1"},
+ {a="''([Aa])", b="أأ%1"},
+ {a="''([Ii])", b="ئئ%1"},
+ -- inseparable adverbial particle 'a- + 'a
+ {a="\'(a)%-\'(a)", b="أ%1اأ%2"},
+ -- initial long u and i (for a, see below)
+ {a="%'%_U", b="Ø£U"},
+ {a="%'%_I", b="Ø¥I"},
+ -- taḫfīfu 'l-hamza
+ {a="'u'([^uaiUAI])", b="Ø£U%1"},
+ {a="'i'([^uaiUAI])", b="Ø¥I%1"},
+ {a="([wf]a)%-\'([^uaiUAIl][^%-])", b="%1أْ%2"},
+ {a="^u'([^uaiUAI])", b="اU%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])u'([^uaiUAI])", b="%1اU%2"},
+ {a="^i'([^uaiUAI])", b="اI%1"},
+ {a="([^uaiUAIYN][%s%(%[%<])i'([^uaiUAI])", b="%1اI%2"},
+ -- madda (historic writing below)
+ {a="'a'([^uaiUAI])", b="Ø¢%1"},
+ {a="([^uiyUI])\'a?A([%_%^%.]?[%`%'btjghxdrzsfqklmnywAY])", b="%1Ø¢%2"},
+ {a="^\'a?A([%_%^%.]?[%`%'btjghxdrzsfqklmnywAY])", b="Ø¢%1"},
+ {a="\'a?A(O[%_%^%.]?[%`%'btjghxdrzsfqklmnywAY]-O)", b="Ø¢"},
+ {a="(%W)\'a?A([%_%^%.]?[%`%'btjghxdrzsfqklmnywAY])", b="%1Ø¢%2"},
+ --easy (begin)
+ {a="(A)(O%'[%S]-O)", b="ا"},
+ {a="(A)(')(uN?%p*)$", b="aاء%3"},
+ {a="(A)(')(uN?)(%p*%s)", b="aاء%3%4"},
+ {a="(A)(')(iN?%p*)$", b="aاء%3"},
+ {a="(A)(')(iN?)(%p*%s)", b="aاء%3%4"},
+ {a="(A)(')([iI])", b="aائ%3"}, -- historic madda
+ {a="(A)(')(u)", b="aاؤ%3"}, -- historic madda
+ {a="(A)(')", b="aاء"}, -- historic madda
+ --easy (end)
+ -- initial (needs both ^ and %W patterns)
+ -- 'aw: the diphthong is to be resolved into 'awi' (next 8 lines)
+ {a="^('aw)(O)('[%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(%W)('aw)(O)('[%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1%2i"},
+ {a="^('aw)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(%W)('aw)(O)(\"?[uai])([%S]-O)", b="%1%2i"},
+ {a="^('aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ {a="(%W)('aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1%2i%3%4"},
+ {a="^('aw)(%s)([%(%[%|%<]?\"?[uai])", b="%1i%2%3"},
+ {a="(%W)('aw)(%s)([%(%[%|%<]?\"?[uai])", b="%1%2i%3%4"},
+ -- then the 'initial' rules for the remaining cases
+ {a="^(')([ua])", b="Ø£%2"},
+ {a="^(')(i)", b="Ø¥%2"},
+ -- consider replacing initial %W with [%s%(%[%<%-]:
+ -- {a="(%W)(')([ua])", b="%1Ø£%3"},
+ -- {a="(%W)(')(i)", b="%1Ø¥%3"},
+ {a="([%s%(%[%<%-])(')([ua])", b="%1Ø£%3"},
+ {a="([%s%(%[%<%-])(')(i)", b="%1Ø¥%3"},
+ -- final
+ -- mi'aT is special orthography (unlike ^say'aN and .zim'aN)
+ -- {a="(%^sa%.?[yY])(\"?%|?)(%')(aN)", b="%1%2ئ%4"}, --new
+ -- {a="(.zi?m)(%')(aN)", b="%1ئ%3"}, --new
+ {a="(mi)(%')(a[Tt])", b="%1ائ%3"},
+ {a="(mi)(%')(aN%_?[AY])", b="%1Ø£%3"},
+ -- easy (begin)
+ -- The Munjid says that such words as radI'aN do not have the
+ -- hamzah alone on the line, so take out the following two lines
+ -- (final hamzah is on the line after a letter of prolongation or a
+ -- consonant with sukūn)
+ -- {a="([^Auai])(')(\"?[uai]N?)(%p*)$", b="%1Ø¡%3%4"}, --new
+ -- {a="([^Auai])(')(\"?[uai]N?)(%p*%s)", b="%1Ø¡%3%4"},
+ {a="([^Auai])(')(\"?aN)(%p*)$", b="%1ئ%3%4"}, --new
+ {a="([^Auai])(')(\"?aN)(%p*%s)", b="%1ئ%3%4"}, --new
+ {a="([^uai])(')(\"?a)(%p*)$", b="%1Ø¡%3%4"}, --new
+ {a="([^uai])(')(\"?a)(%p*%s)", b="%1Ø¡%3%4"}, --new
+ {a="([^uai])(')(\"?[ui]N?)(%p*)$", b="%1Ø¡%3%4"}, --new
+ {a="([^uai])(')(\"?[ui]N?)(%p*%s)", b="%1Ø¡%3%4"}, --new
+ --easy (end)
+-- u
+ {a="(u)(')([uai]N?%p*)$", b="%1ؤ%3"},
+ {a="(u)(')([uai]N?)(%p*%s)", b="%1ؤ%3%4"},
+ {a="(u)(')(%p*)$", b="%1ؤ%3"},
+ {a="(u)(')(%p*%s)", b="%1ؤ%3"},
+-- a
+ {a="(a)(')(A%p*)$", b="%1Ø¢"},
+ {a="(a)(')(A)(%p*%s)", b="%1Ø¢%4"},
+ {a="(a)(')([u]N?%p*)$", b="%1Ø£%3"},
+ {a="(a)(')([u]N?)(%p*%s)", b="%1Ø£%3%4"},
+ {a="(a)(')(a%p*)$", b="%1Ø£%3"},
+ {a="(a)(')(a)(%p*%s)", b="%1Ø£%3%4"},
+ {a="(a)(')(aN%p*)$", b="%1أً"},
+ {a="(a)(')(aN)(%p*%s)", b="%1أً%4"},
+ {a="(a)(')([i]N?%p*)$", b="%1Ø¥%3"},
+ {a="(a)(')([i]N?)(%p*%s)", b="%1Ø¥%3%4"},
+ {a="(a)(')(%p*)$", b="%1Ø£%3"},
+ {a="(a)(')(%p*%s)", b="%1Ø£%3"},
+-- i
+ {a="(i)(')([uai]N?%p*)$", b="%1ئ%3"},
+ {a="(i)(')([uai]N?)(%p*%s)", b="%1ئ%3%4"},
+ {a="(i)(')(%p*)$", b="%1ئ%3"},
+ {a="(i)(')(%p*%s)", b="%1ئ%3"},
+--
+ -- middle
+ {a="([Uw])(')", b="%1Ø¡"}, --new
+ {a="([Iy])(')", b="%1ئ"}, --easy
+ {a="([^uai])(')([uU])", b="%1ؤ%3"},
+ {a="([^uai])(')(%_?[aAY])", b="%1Ø£%3"},
+ {a="([^uai])(')([iI])", b="%1ئ%3"},
+ {a="(u)(')([uU])", b="%1ؤ%3"},
+ {a="(u)(')(%_?[aAY])", b="%1ؤ%3"},
+ {a="(u)(')([iI])", b="%1ئ%3"},
+ {a="(a)(')(%_?[aAY])", b="%1Ø£%3"},
+ {a="(a)(')([uU])", b="%1ؤ%3"},
+ {a="(a)(')([iI])", b="%1ئ%3"},
+ {a="(i)(')(%_?[aAY])", b="%1ئ%3"},
+ {a="(i)(')([uU])", b="%1ئ%3"},
+ {a="(i)(')([iI])", b="%1ئ%3"},
+ {a="(a)(')([^uaiUAI])", b="%1Ø£%3"},
+ {a="(u)(')([^uaiUAI])", b="%1ؤ%3"},
+ {a="(i)(')([^uaiUAI])", b="%1ئ%3"}
+}
+
+tanwin = {
+ -- assimilations (begin)
+ {a="(O[%S]-)(%-?[uai]N[UI]?)(O)([rlmnwy])", b="%4%4"},
+ {a="(%-?[uai]NU)(%s)([rlmnwy])", b="%1%2%3%3"},
+ -- assimilations (end)
+ {a="(O[%S]-)(%-?[uai]N[UI]?)(O)([uai])", b="%4"},
+ {a="%-?uNU", b="ٌو"},
+ {a="%-?aNU", b="ًوا"},
+ {a="%-?iNU", b="ÙÙˆ"},
+ -- assimilations (begin)
+ {a="%-?(uN)(%s)([rlmnwy])", b="ٌ%2%3%3"},
+ {a="(O[%S]-)(%-?aN)(_A)(O)([rlmnwy])", b="%5%5"},
+ {a="(O[%S]-)(%-?aN)(Y)(O)([rlmnwy])", b="%5%5"},
+ {a="%-?(aN)(_A)(%s)([rlmnwy])", b="ًى%3%4%4"},
+ {a="%-?(aN)(Y)(%s)([rlmnwy])", b="ًى%3%4%4"},
+ {a="(T)%-?(aN)(%s)([rlmnwy])", b="%1Ù‹%3%4%4"},
+ {a="(Ø¡)%-?(aN)(%s)([rlmnwy])", b="%1%2%3%4%4"}, --new
+ {a="([^TA])%-?(aN)(%s)([rlmnwy])", b="%1ًا%3%4%4"},
+ {a="%-?(iNI?)(%s)([rlmnwy])", b="Ù%2%3%3"},
+ -- assimilations (end)
+ {a="(O[%S]-)(%-?aN)(_A)(O)([uai])", b="%5"},
+ {a="(O[%S]-)(%-?aN)(Y)(O)([uai])", b="%5"},
+ -- quoted tanwīn (begin)
+ {a="%-?(\"uN)", b=""},
+ {a="(B)%-?(\"aN)", b="%1"},
+ {a="%-?(\"aN)(_A)", b="Ù‰"},
+ {a="%-?(\"aN)(Y)", b="Ù‰"},
+ {a="(T)%-?(\"aN)", b="%1"},
+ {a="([اآ])(ء)%-?(\"aN)", b="%1%2"}, --new
+ {a="([^TA])%-?(\"aN)", b="%1ا"},
+ {a="%-?(\"iNI?)", b=""},
+ -- quoted tanwīn (end)
+ {a="%-?(uN)", b="ٌ"},
+ {a="(B)%-?(aN)", b="%1Ù‹"},
+ -- needed by \arbcolor:
+ {a="%-?(aN)(O[%S]-%_AO)", b="Ù‹"},
+ {a="%-?(aN)(O[%S]-YO)", b="Ù‹"},
+ {a="(O[%S]-TO)%-?(aN)", b="Ù‹"},
+ {a="(O[%S]-)([اآ])(ء)(O)%-?(aN)", b="ً"}, --new
+ {a="(O[%S]-[^TA]O)%-?(aN)", b="ًا"},
+ --
+ {a="%-?(aN)(_A)", b="ًى"},
+ {a="%-?(aN)(Y)", b="ًى"},
+ {a="(T)%-?(aN)", b="%1Ù‹"},
+ {a="([اآ])(ء)%-?(aN)", b="%1%2ً"}, --new
+ {a="([^TA])%-?(aN)", b="%1ًا"},
+ {a="%-?(iNI?)", b="Ù"}
+}
+
+tanwineasy = { -- 'easy' requires some lines to be taken out:
+ -- assimilations (begin)
+-- {a="(O[%S]-)(%-?[uai]N[UI]?)(O)([rlmnwy])", b="%4%4"},
+-- {a="(%-?[uai]NU)(%s)([rlmnwy])", b="%1%2%3%3"},
+ -- assimilations (end)
+ {a="(O[%S]-)(%-?[uai]N[UI]?)(O)([uai])", b="%4"},
+ {a="%-?uNU", b="ٌو"},
+ {a="%-?aNU", b="ًوا"},
+ {a="%-?iNU", b="ÙÙˆ"},
+ -- assimilations (begin)
+-- {a="%-?(uN)(%s)([rlmnwy])", b="ٌ%2%3%3"},
+-- {a="(O[%S]-)(%-?aN)(_A)(O)([rlmnwy])", b="%5%5"},
+-- {a="(O[%S]-)(%-?aN)(Y)(O)([rlmnwy])", b="%5%5"},
+-- {a="%-?(aN)(_A)(%s)([rlmnwy])", b="ًى%3%4%4"},
+-- {a="%-?(aN)(Y)(%s)([rlmnwy])", b="ًى%3%4%4"},
+-- {a="(T)%-?(aN)(%s)([rlmnwy])", b="%1Ù‹%3%4%4"},
+-- {a="(Ø¡)%-?(aN)(%s)([rlmnwy])", b="%1%2%3%4%4"}, --new
+-- {a="([^TA])%-?(aN)(%s)([rlmnwy])", b="%1ًا%3%4%4"},
+-- {a="%-?(iNI?)(%s)([rlmnwy])", b="Ù%2%3%3"},
+ -- assimilations (end)
+ {a="(O[%S]-)(%-?aN)(_A)(O)([uai])", b="%5"},
+ {a="(O[%S]-)(%-?aN)(Y)(O)([uai])", b="%5"},
+ -- quoted tanwīn (begin)
+ {a="%-?(\"uN)", b=""},
+ {a="(B)%-?(\"aN)", b="%1"},
+ {a="%-?(\"aN)(_A)", b="Ù‰"},
+ {a="%-?(\"aN)(Y)", b="Ù‰"},
+ {a="(T)%-?(\"aN)", b="%1"},
+ {a="([اآ])(ء)%-?(\"aN)", b="%1%2"}, --new
+ {a="([^TA])%-?(\"aN)", b="%1ا"},
+ {a="%-?(\"iNI?)", b=""},
+ -- quoted tanwīn (end)
+ {a="%-?(uN)", b="ٌ"},
+ {a="(B)%-?(aN)", b="%1Ù‹"},
+ -- needed by \arbcolor:
+ {a="%-?(aN)(O[%S]-%_AO)", b="Ù‹"},
+ {a="%-?(aN)(O[%S]-YO)", b="Ù‹"},
+ {a="(O[%S]-TO)%-?(aN)", b="Ù‹"},
+ {a="(O[%S]-)([اآ])(ء)(O)%-?(aN)", b="ً"}, --new
+ {a="(O[%S]-[^TA]O)%-?(aN)", b="ًا"},
+ --
+ {a="%-?(aN)(_A)", b="ًى"},
+ {a="%-?(aN)(Y)", b="ًى"},
+ {a="(T)%-?(aN)", b="%1Ù‹"},
+ {a="([اآ])(ء)%-?(aN)", b="%1%2ً"}, --new
+ {a="([^TA])%-?(aN)", b="%1ًا"},
+ {a="%-?(iNI?)", b="Ù"}
+}
+
+trigraphs = { -- trigraphs or more
+ -- ʾalif al-waṣl: put it back on with \arbnull
+ {a="(O[%S]-)([%'a]l%-)(O)(\"[uai])", b="Ù±"},
+ {a="(O[%S]-)([%'a]l%-)(O)([uai])", b="ا"},
+ -- 'llatI / 'llad_I
+ {a="^'ll(a)([%_]?[dt])", b="الّ%1%2"},
+ {a="([%(%[%|%<%s%-])'ll(a)([%_]?[dt])", b="%1الّ%2%3"}, --p
+ -- law: the diphthong is to be resolved into 'awi' (next 8 lines)
+ {a="^(law)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(%W)(law)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1%2i"},
+ {a="^(law)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(%W)(law)(O)(\"?[uai])([%S]-O)", b="%1%2i"},
+ {a="^(law)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ {a="(%W)(law)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1%2i%3%4"},
+ {a="^(law)(%s)([%(%[%|%<]?\"?[uai])", b="%1i%2%3"}, --p
+ {a="(%W)(law)(%s)([%(%[%|%<]?\"?[uai])", b="%1%2i%3%4"}, --p
+ -- al- + lÄm
+ {a="^(a)l%-(l)", b="ا%1ل%2%2"},
+ {a="([%(%[%|%<%s%-O])(a)l%-(l)", b="%1ا%2ل%3%3"}, --p
+ -- al- + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)l%-(%^n)", b="ا%1ل%2"}, -- ^n is lunar
+ {a="([%(%[%|%<%s%-O])(a)l%-(%^n)", b="%1ا%2ل%3"},-- ^n is lunar --p
+ {a="^(a)l%-([%_%^%.]?[tdrzsnc])", b="ا%1ل%2%2"},
+ {a="([%(%[%|%<%s%-O])(a)l%-([%_%^%.]?[tdrzsnc])", b="%1ا%2ل%3%3"}, --p
+ -- assim. art. + solar consonant ('c' and '^n' are additional characters)
+ {a="^(a)(%^n)%-", b="ا%1ل"}, -- ^n is lunar
+ {a="([%(%[%|%<%s%-O])(a)(%^n)%-", b="%1ا%2ل"},-- ^n is lunar --p
+ {a="^(a)([%_%^%.]?[tdrzsnc])%-", b="ا%1ل%2"},
+ {a="([%(%[%|%<%s%-O])(a)([%_%^%.]?[tdrzsnc])%-", b="%1ا%2ل%3"}, --p
+ -- al- + initial unstable hamza
+ {a="^(a)l%-(\")([uai])", b="ا%1ل%3ٱ"},
+ {a="([%(%[%|%<%s%-O])(a)l%-(\")([uai])", b="%1ا%2ل%4ٱ"}, --p
+ {a="^(a)l%-([uai])", b="ا%1ل%2ا"},
+ {a="([%(%[%|%<%s%-O])(a)l%-([uai])", b="%1ا%2ل%3ا"}, --p
+ -- li-/la- + art. + initial unstable hamza is a special orthography
+ {a="l([ai])%-l%-(\")([uai])", b="Ù„%1Ù„%3Ù±"},
+ {a="l([ai])%-l%-([uai])", b="ل%1ل%2ا"},
+ -- al- + lunar consonant (i.e. what remains)
+ {a="^(a)l%-", b="ا%1ل"},
+ {a="([%(%[%|%<%s%-O])(a)l%-", b="%1ا%2ل"}, --p
+ -- diphthongs to be resolved before ʾalif conjunctionis
+ {a="(aW)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="awuا"},
+ {a="(aw)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1u"},
+ {a="(ay)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(aW)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="awuا%2%3"},
+ {a="(aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1u%2%3"},
+ {a="(ay)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ -- art. with waá¹£la + lÄm
+ {a="'l%-(l)", b="ال%1%1"},
+ -- art. with waá¹£la + solar consonant
+ -- ('c' and '^n' are additional characters)
+ {a="'l%-(%^n)", b="ال%1"}, -- ^n is lunar
+ {a="'l%-([%_%^%.]?[tdrzsnc])", b="ال%1%1"},
+ -- li-/la- + art. + lÄm
+ {a="l([ai])%-l%-(l)", b="Ù„%1%2%2"},
+ -- assim. art. with waá¹£la + solar consonant ('c' and '^n' are
+ -- additional characters)
+ {a="'(%^n)%-", b="ال"}, -- ^n is lunar
+ {a="'([%_%^%.]?[tdrzsnc])%-", b="ال%1"},
+ -- li-/la- + art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-l%-(%^n)", b="Ù„%1Ù„%2"}, -- '^n' is lunar
+ {a="l([ai])%-l%-([%_%^%.]?[tdrzsnc])", b="Ù„%1Ù„%2%2"},
+ -- li-/la + assim. art. + solar consonant is a special orthography
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-(%^n)%-(%^n)", b="Ù„%1Ù„%3"}, -- ^n is lunar
+ {a="l([ai])%-([%_%^%.]?[tdrzsnc])%-([%_%^%.]?[tdrzsnc])", b="Ù„%1Ù„%3%3"},
+ -- art. with waá¹£la + initial unstable hamza
+ {a="'l%-(\")([uai])", b="ال%2ٱ"},
+ {a="'l%-([uai])", b="ال%1ا"},
+ -- art. with waá¹£la + lunar consonant (i.e. what remains)
+ {a="'l%-", b="ال"},
+ -- the silent wÄw
+ {a="uU(%p*)$", b="uÙˆ%1"},
+ {a="uU(%p*%s)", b="uÙˆ%1"},
+ {a="aU(%p*)$", b="aÙˆ%1"},
+ {a="aU(%p*%s)", b="aÙˆ%1"},
+ {a="iU(%p*)$", b="iÙˆ%1"},
+ {a="iU(%p*%s)", b="iÙˆ%1"},
+ -- words ending in -ÄT with silent wÄw/yÄʾ
+ {a="(_a)UA", b="%1وا"},
+ {a="(_a)U", b="%1Ùˆ"},
+ {a="(_a)I", b="%1ÙŠ"}
+}
+
+idgham = {
+ -- assimilations
+ {a="(n)(%s)([rlmnwy])", b="%1%2%3%3"},
+ {a="(n)(O)([rlmnwy])([%S]-O)", b="%3"}
+}
+
+trigraphseasy = { -- differences marked below with 'easy'
+ -- ʾalif al-waṣl: put it back on with \arbnull
+ {a="(O[%S]-)([%'a]l%-)(O)(\"[uai])", b="Ù±"},
+ {a="(O[%S]-)([%'a]l%-)(O)([uai])", b="ا"},
+ -- Allah (easy)
+ {a="l%-l_ah", b="l-ll_ah"},
+ -- 'llatI / 'llad_I
+ {a="^'ll(a)([%_]?[dt])", b="الّ%1%2"},
+ {a="([%(%[%|%<%s%-])'ll(a)([%_]?[dt])", b="%1الّ%2%3"}, --p
+ -- law: the diphthong is to be resloved into 'awi' (next 8 lines)
+ {a="^(law)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(%W)(law)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1%2i"},
+ {a="^(law)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(%W)(law)(O)(\"?[uai])([%S]-O)", b="%1%2i"},
+ {a="^(law)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ {a="(%W)(law)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1%2i%3%4"},
+ {a="^(law)(%s)([%(%[%|%<]?\"?[uai])", b="%1i%2%3"}, --p
+ {a="(%W)(law)(%s)([%(%[%|%<]?\"?[uai])", b="%1%2i%3%4"}, --p
+ -- al- + lÄm (easy)
+ {a="^(a)l%-(l)", b="ا%1ل%2"},
+ {a="([%(%[%|%<%s%-O])(a)l%-(l)", b="%1ا%2ل%3"}, --p
+ -- al- + solar consonant (easy) ('c' and '^n' are additional characters)
+ {a="^(a)l%-(%^n)", b="ا%1ل%2"}, -- ^n is lunar
+ {a="([%(%[%|%<%s%-O])(a)l%-(%^n)", b="%1ا%2ل%3"}, -- ^n is lunar --p
+ {a="^(a)l%-([%_%^%.]?[tdrzsnc])", b="ا%1ل%2"},
+ {a="([%(%[%|%<%s%-O])(a)l%-([%_%^%.]?[tdrzsnc])", b="%1ا%2ل%3"}, --p
+ -- assim. art. + solar consonant (easy) ('c' and '^n' are
+ -- additional characters)
+ {a="^(a)(%^n)%-", b="ا%1ل"}, -- ^n is lunar
+ {a="([%(%[%|%<%s%-O])(a)(%^n)%-", b="%1ا%2ل"}, -- ^n is lunar --p
+ {a="^(a)([%_%^%.]?[tdrzsnc])%-", b="ا%1ل"},
+ {a="([%(%[%|%<%s%-O])(a)([%_%^%.]?[tdrzsnc])%-", b="%1ا%2ل"}, --p
+ -- al- + initial unstable hamza
+ {a="^(a)l%-(\")([uai])", b="ا%1ل%3ٱ"},
+ {a="([%(%[%|%<%s%-O])(a)l%-(\")([uai])", b="%1ا%2ل%4ٱ"}, --p
+ {a="^(a)l%-([uai])", b="ا%1ل%2ا"},
+ {a="([%(%[%|%<%s%-O])(a)l%-([uai])", b="%1ا%2ل%3ا"}, --p
+ -- li-/la- + art. + initial unstable hamza is a special orthography
+ {a="l([ai])%-l%-(\")([uai])", b="Ù„%1Ù„%3Ù±"},
+ {a="l([ai])%-l%-([uai])", b="ل%1ل%2ا"},
+ -- al- + lunar consonant (i.e. what remains)
+ {a="^(a)l%-", b="ا%1ل"},
+ {a="([%(%[%|%<%s%-O])(a)l%-", b="%1ا%2ل"}, --p
+ -- diphthongs to be resolved before ʾalif conjunctionis
+ {a="(aW)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="awuا"},
+ {a="(aw)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1u"},
+ {a="(ay)(O)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)([%S]-O)", b="%1i"},
+ {a="(aW)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="awuا%2%3"},
+ {a="(aw)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1u%2%3"},
+ {a="(ay)(%s)(['][%_%^%.]?[l'btjghxdrzs`fqkmnwy]%-)", b="%1i%2%3"},
+ -- art. with waá¹£la + lÄm (easy)
+ {a="'l%-(l)", b="ال%1"},
+ -- art. with waá¹£la + solar consonant (easy)
+ -- ('c' and '^n' are additional characters)
+ {a="'l%-(%^n)", b="ال%1"}, -- ^n is lunar
+ {a="'l%-([%_%^%.]?[tdrzsnc])", b="ال%1"},
+ -- li-/la- + art. + lÄm (easy)
+ {a="l([ai])%-l%-(l)", b="Ù„%1%2"},
+ -- assim. art. with waá¹£la + solar consonant (easy)
+ -- ('c' and '^n' are additional characters)
+ {a="'(%^n)%-", b="ال"}, -- ^n is lunar
+ {a="'([%_%^%.]?[tdrzsnc])%-", b="ال"},
+ -- li-/la- + art. + solar consonant is a special orthography (easy)
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-l%-(%^n)", b="Ù„%1Ù„%2"}, -- ^n is lunar
+ {a="l([ai])%-l%-([%_%^%.]?[tdrzsnc])", b="Ù„%1Ù„%2"},
+ -- li-/la + assim. art. + solar consonant is a special orthography (easy)
+ -- ('c' and '^n' are additional characters)
+ {a="l([ai])%-(%^n)%-(%^n)", b="Ù„%1Ù„%3"}, -- ^n is lunar
+ {a="l([ai])%-([%_%^%.]?[tdrzsnc])%-([%_%^%.]?[tdrzsnc])", b="Ù„%1Ù„%3"},
+ -- art. with waá¹£la + initial unstable hamza
+ {a="'l%-(\")([uai])", b="ال%2ٱ"},
+ {a="'l%-([uai])", b="ال%1ا"},
+ -- art. with waá¹£la + lunar consonant (i.e. what remains)
+ {a="'l%-", b="ال"},
+ -- the silent wÄw
+ {a="uU(%p*)$", b="uÙˆ%1"},
+ {a="uU(%p*%s)", b="uÙˆ%1"},
+ {a="aU(%p*)$", b="aÙˆ%1"},
+ {a="aU(%p*%s)", b="aÙˆ%1"},
+ {a="iU(%p*)$", b="iÙˆ%1"},
+ {a="iU(%p*%s)", b="iÙˆ%1"},
+ -- words ending in -ÄT with silent wÄw/yÄʾ
+ {a="(_a)UA", b="%1وا"},
+ {a="(_a)U", b="%1Ùˆ"},
+ {a="(_a)I", b="%1ÙŠ"}
+}
+
+digraphs = {
+ -- ʾiÊ¿rÄb: straight double quote must be discarded
+ {a="(%-)(\"?[UI]na)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?[UI]na)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?At[ui])(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?At[ui])(%p*)$", b="%2%3"},
+ {a="(%-)(\"?Ani)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?Ani)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?ayni)(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?ayni)(%p*)$", b="%2%3"},
+ {a="(%-)(\"?[uai])(%p*%s)", b="%2%3"},
+ {a="(%-)(\"?[uai])(%p*)$", b="%2%3"},
+ -- ʾiÊ¿rÄb (end)
+ -- initial straight double quote gives a connective ʾalif
+ {a="^\"[uai]", b="Ù±"},
+ {a="([%(%[%|%<%s%-])\"[uai]", b="%1Ù±"}, --p
+ -- diphthongs to be resolved before ʾalif conjunctionis
+ {a="(aW)(O)(\"?[uai])([%S]-O)", b="awuا"},
+ {a="(aW)(%s)([%(%[%|%<]?)([uai])", b="awuا%2%3%4"}, --p
+ {a="(aw)(O)(\"?[uai])([%S]-O)", b="%1u"},
+ {a="(aw)(%s)([%(%[%|%<]?)(\"?[uai])", b="%1u%2%3ا"}, --p
+ {a="(ay)(O)(\"?[uai])([%S]-O)", b="%1i"},
+ {a="(ay)(%s)([%(%[%|%<]?)(\"?[uai])", b="%1i%2%3ا"}, --p
+ -- hyphen + initial alif without hamza:
+ {a="([uai]%-)(\"?[uai])([%^%_%.%`]?)([%aإأؤئ])", b="%1ا%3%4"},
+ -- initial alif without hamza
+ {a="^([%(%[%|%<]?)(\"?[uai])", b="%1ا%2"}, --p
+ -- initial alif without hamza
+ {a="(O[%S]-)([uaiUAIY])(O)(\"?[uai])", b="ا"},
+ {a="(%s)([%(%[%|%<]?)(\"?[uai])", b="%1%2ا"}, --p
+ {a="%-%-", b="Ù€"},
+ {a="ؤؤ", b="ؤّ"},
+ {a="أأ", b="أّ"},
+ {a="ئئ", b="ئّ"},
+ {a="bb", b="بّ"},
+ {a="BB", b="ـّ"},
+ {a="([%_%^%.])([tghdsz])([tghdsz])", b="%1%2|%3"},
+ -- same as above for additional characters:
+ {a="([%_%^%.])([cn])([cn])", b="%1%2|%3"},
+ {a="tt", b="تّ"},
+ {a="%_t%_t", b="ثّ"},
+ {a="jj", b="جّ"},
+ {a="%^g%^g", b="جّ"},
+ {a="%.h%.h", b="حّ"},
+ {a="xx", b="خّ"},
+ {a="%_h%_h", b="خّ"},
+ {a="dd", b="دّ"},
+ {a="%_d%_d", b="ذّ"},
+ {a="rr", b="رّ"},
+ {a="zz", b="زّ"},
+ {a="ss", b="سّ"},
+ {a="%^s%^s", b="شّ"},
+ {a="%.s%.s", b="صّ"},
+ {a="%.d%.d", b="ضّ"},
+ {a="%.t%.t", b="طّ"},
+ {a="%.z%.z", b="ظّ"},
+ {a="%`%`", b="عّ"},
+ {a="%.g%.g", b="غّ"},
+ {a="ff", b="ÙÙ‘"},
+ {a="qq", b="قّ"},
+ {a="kk", b="كّ"},
+ {a="ll", b="لّ"},
+ {a="mm", b="مّ"},
+ {a="nn", b="نّ"},
+ {a="hh", b="هّ"},
+ {a="ww", b="وّ"},
+ {a="yy", b="يّ"},
+ {a="%.y%.y", b="ىّ"},
+ -- additional characters + Å¡addah (begin)
+ {a="pp", b="پّ"},
+ {a="vv", b="Ú¤Ù‘"},
+ {a="gg", b="Ú¯Ù‘"},
+ {a="%^c%^c", b="Ú†Ù‘"},
+ {a="%^z%^z", b="Ú˜Ù‘"},
+ {a="%^n%^n", b="Ú­Ù‘"},
+ -- additional characters + Å¡addah (end)
+ {a="_t", b="Ø«"},
+ {a="%^g", b="ج"},
+ {a="%.h", b="Ø­"},
+ {a="_h", b="Ø®"},
+ {a="_d", b="Ø°"},
+ {a="%^s", b="Ø´"},
+ {a="%.s", b="ص"},
+ {a="%.d", b="ض"},
+ {a="%.t", b="Ø·"},
+ {a="%.z", b="ظ"},
+ {a="%.g", b="غ"},
+ {a="%.y", b="Ù‰"},
+ -- additional characters (begin)
+ {a="%^c", b="Ú†"},
+ {a="%^z", b="Ú˜"},
+ {a="%^n", b="Ú­"},
+ -- additional characters (end)
+ {a="(U)(A)", b="%1ا"},
+ {a="WA", b="وا"},
+ {a="(a)W\"", b="%1وْا"},
+ {a="(a)W", b="%1وا"},
+ {a="_A", b="aÙ‰"},
+ {a="_u", b="Ù—"},
+ {a="_a", b="Ù°"},
+ {a="_i", b="Ù–"},
+ {a="%.b", b="Ù®"},
+ {a="%.f", b="Ú¡"},
+ {a="%.q", b="Ù¯"},
+ {a="%.k", b="Ú©"},
+ {a="%.n", b="Úº"},
+ {a="%^d", b="ÚŠ"}
+}
+
+single = {
+ {a="b", b="ب"},
+ {a="t", b="ت"},
+ {a="j", b="ج"},
+ {a="x", b="Ø®"},
+ {a="d", b="د"},
+ {a="r", b="ر"},
+ {a="z", b="ز"},
+ {a="s", b="س"},
+ {a="f", b="Ù"},
+ {a="`", b="ع"},
+ {a="f", b="Ù"},
+ {a="q", b="Ù‚"},
+ {a="k", b="Ùƒ"},
+ {a="l", b="Ù„"},
+ {a="m", b="Ù…"},
+ {a="n", b="Ù†"},
+ {a="h", b="Ù‡"},
+ {a="w", b="Ùˆ"},
+ {a="y", b="ÙŠ"},
+ {a="T", b="Ø©"},
+ -- additional characters (begin)
+ {a="p", b="Ù¾"},
+ {a="v", b="Ú¤"},
+ {a="g", b="Ú¯"},
+ -- additional characters (end)
+ {a="\"$", b="Ù’"},
+ {a="\"(%W)", b="Ù’%1"},
+ {a="\"([^uaiUAI])", b="Ù’%1"},
+ {a="o", b="ْ"}, -- hard-coded sukūn
+ {a="([^0-9])%-([^0-9])", b="%1%2"},
+ {a="B", b="Ù€"}
+}
+
+longv = {
+ {a="\"A", b="ا"},
+ {a="\"U", b="Ùˆ"},
+ {a="\"I", b="ÙŠ"},
+ {a="\"Y", b="Ù‰"},
+ {a="A", b="َا"},
+ {a="U", b="ÙÙˆ"},
+ {a="I", b="ÙÙŠ"},
+ {a="aY", b="aÙ‰"},
+ {a="iY", b="iÙ‰"},
+ {a="Y", b="aÙ‰"}
+}
+
+shortv = {
+ {a="\"u", b=""},
+ {a="\"a", b=""},
+ {a="\"i", b=""},
+ {a="%-?%.u", b="Ù"},
+ {a="%-?%.a", b="ÙŽ"},
+ {a="%-?%.i", b="Ù"},
+ {a="u", b="Ù"},
+ {a="a", b="ÙŽ"},
+ {a="i", b="Ù"}
+}
+
+punctuation = {
+ {a="%(%(", b="ï´¿"},
+ {a="%)%)", b="ï´¾"},
+ {a="%(", b="+@("},
+ {a="%)", b="-@("},
+ {a="%+%@%(", b=")"},
+ {a="%-%@%(", b="("},
+ {a="%<", b="+@<"},
+ {a="%>", b="-@<"},
+ {a="%+%@%<", b=">"},
+ {a="%-%@%<", b="<"},
+ {a="%[", b="+@["},
+ {a="%]", b="-@["},
+ {a="%+%@%[", b="]"},
+ {a="%-%@%[", b="["},
+ {a="%.", b="."},
+ -- replaced with the next two rules to make the Arabic comma work
+ -- after \abraces{}
+-- {a="([^0-9])%,", b="%1،"},
+ {a="%,", b="،"},
+ {a="([%d])%،", b="%1,"},
+ {a="%?", b="ØŸ"},
+ {a="%;", b="Ø›"},
+}
+
+null = {
+ {a="%|", b=""},
+ {a="^%-", b=""},
+ {a="([^0-9])(%-)", b="%1"},
+ {a="O[%S]-O", b=""},
+ {a="[%^%_](.)", b=">??<%1"}
+}
diff --git a/macros/luatex/latex/arabluatex/samples/al-Jahiz.pdf b/macros/luatex/latex/arabluatex/samples/al-Jahiz.pdf
new file mode 100644
index 0000000000..b12a86dd1c
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/samples/al-Jahiz.pdf
Binary files differ
diff --git a/macros/luatex/latex/arabluatex/samples/al-Jahiz.tex b/macros/luatex/latex/arabluatex/samples/al-Jahiz.tex
new file mode 100644
index 0000000000..e83b795cbd
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/samples/al-Jahiz.tex
@@ -0,0 +1,178 @@
+%
+% This file is public domain
+% To compile this document, do:
+% 'lualatex --shell-escape al-Jahiz'
+%
+\documentclass[fontsize=12pt, paper=letter, DIV=classic]{scrartcl}
+\usepackage{fontspec}
+\setmainfont{Old Standard}
+\usepackage{newunicodechar}
+\newunicodechar{ǧ}{ǧ} % Old Standard does include ǧ/Ǧ
+\newunicodechar{Ǧ}{Ǧ} %
+\usepackage{filecontents}
+
+\usepackage{xcolor}
+\usepackage[outputdir=TMP]{minted}
+\definecolor{bg}{rgb}{0.95,0.95,0.95}
+\usepackage{ccicons}
+
+\usepackage{lineno}
+\usepackage{setspace}
+\onehalfspacing
+
+\usepackage{csquotes}
+\DeclareQuoteStyle{arabic}
+{\rmfamily\textquotedblright}{\rmfamily\textquotedblleft}
+{\rmfamily\textquoteright}{\rmfamily\textquoteleft}
+
+\usepackage[fullvoc]{arabluatex}
+\SetArbEasy
+
+\PassOptionsToPackage{pdfa}{hyperref}
+\usepackage{hyperxmp}
+\usepackage{hyperref}
+\hypersetup{colorlinks, linkcolor=blue, pdfauthor={Robert Alessi}}
+
+\begin{document}
+\begin{filecontents*}{dajaja.tex}
+\begin{linenumbers*}
+ \begin{arab}
+ kAna \uc{'a}bU 'l-\uc{h}u_dayli 'ahd_A 'il_A \uc{m}uwaysiN
+ dajAjaTaN. wa-kAnat dajAjatu-hu 'llatI 'ahdA-hA dUna mA kAna
+ yuttaxa_du li-\uc{m}uwaysiN. wa-l_akinna-hu bi-karami-hi
+ wa-bi-.husni _hu\-luqi-hi 'a.zhara 'l-ta`ajjuba min simani-hA
+ wa-.tIbi la.hmi-hA. wa-kAna <\uc{'a}bU 'l-\uc{h}u_dayli>
+ yu`rafu bi-'l-'imsAki 'l-^sadIdi. fa-qAla: \enquote{wa-kayfa
+ ra'ayta yA \uc{'a}bA \uc{`i}mrAna tilka 'l-dajA\-jaTa?}
+ qAla: \enquote{kAnat `ajabaN mina 'l-`ajabi!} fa-yaqUlu:
+ \enquote{wa-tadrI mA jinsu-hA? wa-tadrI mA sinnu-hA? fa-'inna
+ 'l-dajAjaTa 'inna-mA ta.tIbu bi-'l-jinsi wa-'l-sinni. wa-tadrI
+ bi-'ayyi ^say'iN kunnA nusamminu-hA? wa-fI 'ayyi makAniN kunnA
+ na`lifu-hA?} fa-lA yazAlu fI h_a_dA wa-'l-'A_haru ya.d.haku
+ .da.hkaN na`rifu-hu na.hnu wa-lA ya`rifu-hu \uc{'a}bU
+ 'l-\uc{h}u_dayli.
+ \end{arab}
+
+\begin{arab}
+ wa-kAna \uc{'a}bU 'l-\uc{h}u_dayli 'aslama 'l-nAsi .sadraN
+ wa-'awsa`a-hum _huluqaN wa-'ashala-hum suhUlaTaN. fa-'in _dakarUA
+ dajAjaTaN, qAla: \enquote{'ayna kAnat yA \uc{'a}bA \uc{`i}mrAna
+ min tilka 'l-dajA\-jaTi?} fa-'in _dakarUA ba.t.taTaN 'aw `anAqaN
+ 'aw jazUraN 'aw baqaraTaN, qAla: \enquote{fa-'ayna kAnat h_a_dihi
+ 'l-jazUru fI 'l-juzuri min tilka 'l-dajAjaTi fI 'l-dajAji!}
+ wa-'ini istasmana \uc{'a}bU 'l-\uc{h}u_dayli ^say'aN mina
+ 'l-.tayri wa-'l-bahA'imi, qAla: \enquote{lA wa-'l-l_ahi wa-lA tilka
+ 'l-dajAjaTu!} wa-'in _dakarUA `u_dUbaTa 'l-^sa.hmi, qAla:
+ \enquote{`u_dUbaTu 'l-^sa.hmi fI 'l-baqari wa-'l-ba.t.ti wa-bu.tUni
+ 'l-samaki wa-'l-dajAji, wa-lA siyyamA _d_alika 'l-jinsu mina
+ 'l-dajAji.} wa-'in _dakarUA mIlAda ^say'iN 'aw qudUma
+ 'insAniN, qAla: \enquote{kAna _d_alika ba`da 'an 'ahdaytu-hA la-ka
+ bi-sanaTiN, wa-mA kAna bayna qudUmi fulAniN wa-bayna 'l-ba`_taTi
+ bi-tilka 'l-dajAjaTi 'illA yawmuN.} wa-kAnat ma_ta\-laN fI
+ kulli ^say'iN wa-tArI_haN fI kulli ^say'iN.
+\end{arab}
+\end{linenumbers*}
+
+\bigskip
+
+\begin{arab}
+ \uc{al-jA.hi.zu}, \aemph{\uc{k}itAbu 'l-\uc{b}u_halA'i}
+\end{arab}
+\end{filecontents*}
+
+\title{\large\arb{dajAjaTu \uc{'a}bI 'l-\uc{h}u_dayli
+ 'l-\uc{`a}llAfi}}
+\author{}
+\date{}
+
+\titlehead{\textbf{\textsf{arabluatex sample file}} --- \cczero\ This
+ file is public domain.\\
+ \textsf{arabluatex} mode: \texttt{fullvoc} with
+ \texttt{\textbackslash SetArbEasy}\\
+ Full vocalization, the \arb[trans]{sukUn} and the
+ \arb[trans]{wa.slaT} are expressed, the \arb[trans]{ta^sdId} is
+ generated, but the \enquote*{classic} \arb[trans]{maddaT} is
+ discarded (see source code on p.~\pageref{source}).}
+\maketitle
+\vspace{-1in}
+\doublespacing
+\setquotestyle{arabic}
+\input{dajaja}
+
+\makeatletter
+\def\al@mode{trans}
+\makeatother
+\SetTranslitConvention{dmg}
+\titlehead{\textsf{arabluatex} mode: \texttt{trans} with
+ \texttt{\textbackslash SetTranslitConvention\{dmg\}} and
+ \texttt{\textbackslash SetArbEasy}\\
+\emph{Deutsche Morgenländische Gesellschaft} (see source code on
+p.~\pageref{source})}
+\onehalfspacing
+\maketitle
+\vspace{-1in}
+\setquotestyle{english}
+\input{dajaja}
+
+\makeatletter
+\def\al@mode{trans}
+\makeatother
+\SetTranslitConvention{loc}
+\titlehead{\textsf{arabluatex} mode: \texttt{trans} with
+ \texttt{\textbackslash SetTranslitConvention\{loc\}}\\
+\emph{Library of Congress} (see source code on p.~\pageref{source})}
+\maketitle
+\vspace{-1in}
+\setquotestyle{english}
+\input{dajaja}
+
+\makeatletter
+\def\al@mode{trans}
+\makeatother
+\SetTranslitConvention{arabica}
+\titlehead{\textsf{arabluatex} mode: \texttt{trans} with
+ \texttt{\textbackslash SetTranslitConvention\{arabica\}}\\
+\emph{Journal of Arabic and Islamic Studies} (Arabica, see source code
+on p.~\pageref{source})}
+\maketitle
+\vspace{-1in}
+\setquotestyle{english}
+\input{dajaja}
+
+\makeatletter
+\def\al@mode{voc}
+\makeatother
+\singlespacing
+\SetTranslitConvention{dmg}
+\titlehead{}
+\title{\large Source code}
+\subtitle{}
+\maketitle
+\vspace{-1in}
+
+\phantomsection\label{source}
+Here follows the exact source code that has been used to produce the
+above presented outputs. Discretionary hyphens
+(\mintinline{latex}|\-|) may have been inserted at some points to
+prevent lines from overflowing into the right margin.
+
+\medskip
+
+\noindent\textbf{\texttt{preamble:}}
+\begin{minted}[linenos, bgcolor=bg]{latex}
+\usepackage{csquotes} % recommended for inline quotations
+\DeclareQuoteStyle{arabic} % then \setquotestyle{arabic} or
+ % \setquotestyle{english} may be used
+ {\rmfamily\textquotedblright}{\rmfamily\textquotedblleft}
+ {\rmfamily\textquoteright}{\rmfamily\textquoteleft}
+
+\usepackage[fullvoc]{arabluatex} % 'voc', 'fullvoc', 'novoc' or 'trans'
+\SetTranslitConvention{dmg} % 'dmg', 'loc' or 'arabica'
+\SetArbEasy % ie. discard 'classic' maddah
+
+\title{\arb{dajAjaTu \uc{'a}bI 'l-\uc{h}u_dayli 'l-\uc{`a}llAfi}}
+\end{minted}
+\textbf{\texttt{document:}}
+\inputminted[linenos, firstnumber=last, bgcolor=bg]{latex}{TMP/dajaja.tex}
+
+\end{document}
diff --git a/macros/luatex/latex/arabluatex/samples/exporting.pdf b/macros/luatex/latex/arabluatex/samples/exporting.pdf
new file mode 100644
index 0000000000..aff9bb76e2
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/samples/exporting.pdf
Binary files differ
diff --git a/macros/luatex/latex/arabluatex/samples/exporting.tex b/macros/luatex/latex/arabluatex/samples/exporting.tex
new file mode 100644
index 0000000000..7f22c2c098
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/samples/exporting.tex
@@ -0,0 +1,206 @@
+\RequirePackage{filecontents}
+%
+% This file is public domain
+%
+\begin{filecontents*}{exporting-preamble.tex}
+\documentclass[12pt]{article}
+
+\usepackage[fullvoc,export=false]{arabluatex}
+\SetArbEasy
+
+\usepackage{csquotes}
+\DeclareQuoteStyle{arabic}
+{\textquotedblright}{\textquotedblleft}
+{\textquoteright}{\textquoteleft}
+
+% \renewcommand{\txarb}[1]{#1}
+% \renewcommand{\txtrans}[1]{\emph{#1}}
+% \newcommand{\aemph}[1]{#1}
+% \renewcommand{\arbup}[1]{\textsuperscript{#1}}
+\end{filecontents*}
+\begin{filecontents*}{exporting-dajaja.tex}
+\begin{arabexport}
+\section*{Unicode Arabic}
+\setquotestyle{arabic}
+\begin{arab}
+ kAna \uc{'a}bU 'l-\uc{h}u_dayli 'ahd_A 'il_A
+ \uc{m}uwaysiN dajAjaTaN. wa-kAnat dajAjatu-hu 'llatI
+ 'ahdA-hA dUna mA kAna yuttaxa_du
+ li-\uc{m}uwaysiN. wa-l_akinna-hu bi-karami-hi
+ wa-bi-.husni _hu\-luqi-hi 'a.zhara 'l-ta`ajjuba min
+ simani-hA wa-.tIbi la.hmi-hA. wa-kAna <\uc{'a}bU
+ 'l-\uc{h}u_dayli> yu`rafu bi-'l-'imsAki
+ 'l-^sadIdi. fa-qAla: \enquote{wa-kayfa ra'ayta yA
+ \uc{'a}bA \uc{`i}mrAna tilka 'l-dajA\-jaTa?} qAla:
+ \enquote{kAnat `ajabaN mina 'l-`ajabi!} fa-yaqUlu:
+ \enquote{wa-tadrI mA jinsu-hA? wa-tadrI mA sinnu-hA?
+ fa-'inna 'l-dajAjaTa 'inna-mA ta.tIbu bi-'l-jinsi
+ wa-'l-sinni. wa-tadrI bi-'ayyi ^say'iN kunnA
+ nusamminu-hA? wa-fI 'ayyi makAniN kunnA na`lifu-hA?}
+ fa-lA yazAlu fI h_a_dA wa-'l-'A_haru ya.d.haku .da.hkaN
+ na`rifu-hu na.hnu wa-lA ya`rifu-hu \uc{'a}bU
+ 'l-\uc{h}u_dayli.
+\end{arab}
+
+\begin{arab}
+ wa-kAna \uc{'a}bU 'l-\uc{h}u_dayli 'aslama 'l-nAsi
+ .sadraN wa-'awsa`a-hum _huluqaN wa-'ashala-hum
+ suhUlaTaN. fa-'in _dakarUA dajAjaTaN, qAla:
+ \enquote{'ayna kAnat yA \uc{'a}bA \uc{`i}mrAna min
+ tilka 'l-dajA\-jaTi?} fa-'in _dakarUA ba.t.taTaN 'aw
+ `anAqaN 'aw jazUraN 'aw baqaraTaN, qAla:
+ \enquote{fa-'ayna kAnat h_a_dihi 'l-jazUru fI 'l-juzuri
+ min tilka 'l-dajAjaTi fI 'l-dajAji!} wa-'ini
+ istasmana \uc{'a}bU 'l-\uc{h}u_dayli ^say'aN mina
+ 'l-.tayri wa-'l-bahA'imi, qAla: \enquote{lA wa-'l-l_ahi
+ wa-lA tilka 'l-dajAjaTu!} wa-'in _dakarUA `u_dUbaTa
+ 'l-^sa.hmi, qAla: \enquote{`u_dUbaTu 'l-^sa.hmi fI
+ 'l-baqari wa-'l-ba.t.ti wa-bu.tUni 'l-samaki
+ wa-'l-dajAji, wa-lA siyyamA _d_alika 'l-jinsu mina
+ 'l-dajAji.} wa-'in _dakarUA mIlAda ^say'iN 'aw
+ qudUma 'insAniN, qAla: \enquote{kAna _d_alika ba`da 'an
+ 'ahdaytu-hA la-ka bi-sanaTiN, wa-mA kAna bayna qudUmi
+ fulAniN wa-bayna 'l-ba`_taTi bi-tilka 'l-dajAjaTi
+ 'illA yawmuN.} wa-kAnat ma_ta\-laN fI kulli ^say'iN
+ wa-tArI_haN fI kulli ^say'iN.
+\end{arab}
+
+\bigskip
+
+\begin{arab}
+ \uc{al-jA.hi.zu}, \aemph{\uc{k}itAbu 'l-\uc{b}u_halA'i}
+\end{arab}
+
+\section*{Romanized Arabic}
+\setquotestyle{english}
+\begin{arab}[trans]
+ kAna \uc{'a}bU 'l-\uc{h}u_dayli 'ahd_A 'il_A
+ \uc{m}uwaysiN dajAjaTaN. wa-kAnat dajAjatu-hu 'llatI
+ 'ahdA-hA dUna mA kAna yuttaxa_du
+ li-\uc{m}uwaysiN. wa-l_akinna-hu bi-karami-hi
+ wa-bi-.husni _hu\-luqi-hi 'a.zhara 'l-ta`ajjuba min
+ simani-hA wa-.tIbi la.hmi-hA. wa-kAna <\uc{'a}bU
+ 'l-\uc{h}u_dayli> yu`rafu bi-'l-'imsAki
+ 'l-^sadIdi. fa-qAla: \enquote{wa-kayfa ra'ayta yA
+ \uc{'a}bA \uc{`i}mrAna tilka 'l-dajA\-jaTa?} qAla:
+ \enquote{kAnat `ajabaN mina 'l-`ajabi!} fa-yaqUlu:
+ \enquote{wa-tadrI mA jinsu-hA? wa-tadrI mA sinnu-hA?
+ fa-'inna 'l-dajAjaTa 'inna-mA ta.tIbu bi-'l-jinsi
+ wa-'l-sinni. wa-tadrI bi-'ayyi ^say'iN kunnA
+ nusamminu-hA? wa-fI 'ayyi makAniN kunnA na`lifu-hA?}
+ fa-lA yazAlu fI h_a_dA wa-'l-'A_haru ya.d.haku .da.hkaN
+ na`rifu-hu na.hnu wa-lA ya`rifu-hu \uc{'a}bU
+ 'l-\uc{h}u_dayli.
+\end{arab}
+
+\begin{arab}[trans]
+ wa-kAna \uc{'a}bU 'l-\uc{h}u_dayli 'aslama 'l-nAsi
+ .sadraN wa-'awsa`a-hum _huluqaN wa-'ashala-hum
+ suhUlaTaN. fa-'in _dakarUA dajAjaTaN, qAla:
+ \enquote{'ayna kAnat yA \uc{'a}bA \uc{`i}mrAna min
+ tilka 'l-dajA\-jaTi?} fa-'in _dakarUA ba.t.taTaN 'aw
+ `anAqaN 'aw jazUraN 'aw baqaraTaN, qAla:
+ \enquote{fa-'ayna kAnat h_a_dihi 'l-jazUru fI 'l-juzuri
+ min tilka 'l-dajAjaTi fI 'l-dajAji!} wa-'ini
+ istasmana \uc{'a}bU 'l-\uc{h}u_dayli ^say'aN mina
+ 'l-.tayri wa-'l-bahA'imi, qAla: \enquote{lA wa-'l-l_ahi
+ wa-lA tilka 'l-dajAjaTu!} wa-'in _dakarUA `u_dUbaTa
+ 'l-^sa.hmi, qAla: \enquote{`u_dUbaTu 'l-^sa.hmi fI
+ 'l-baqari wa-'l-ba.t.ti wa-bu.tUni 'l-samaki
+ wa-'l-dajAji, wa-lA siyyamA _d_alika 'l-jinsu mina
+ 'l-dajAji.} wa-'in _dakarUA mIlAda ^say'iN 'aw qudUma
+ 'insAniN, qAla: \enquote{kAna _d_alika ba`da 'an
+ 'ahdaytu-hA la-ka bi-sanaTiN, wa-mA kAna bayna qudUmi
+ fulAniN wa-bayna 'l-ba`_taTi bi-tilka 'l-dajAjaTi
+ 'illA yawmuN.} wa-kAnat ma_ta\-laN fI kulli ^say'iN
+ wa-tArI_haN fI kulli ^say'iN.
+\end{arab}
+
+\bigskip
+
+\begin{arab}[trans]
+ \uc{al-jA.hi.zu}, \aemph{\uc{k}itAbu 'l-\uc{b}u_halA'i}
+\end{arab}
+\end{arabexport}
+\end{filecontents*}
+\documentclass[12pt]{article}
+
+\usepackage[fullvoc,export=false]{arabluatex}
+\SetArbEasy
+
+\usepackage{csquotes}
+\DeclareQuoteStyle{arabic}
+{\textquotedblright}{\textquotedblleft}
+{\textquoteright}{\textquoteleft}
+
+\PassOptionsToPackage{pdfa}{hyperref}
+\usepackage{hyperxmp}
+\usepackage{hyperref}
+\hypersetup{colorlinks, linkcolor=blue, pdfauthor={Robert
+ Alessi}}
+
+\title{\large Exporting Unicode Arabic to an external
+ .tex source file}
+\author{}
+\date{}
+
+\usepackage{xcolor}
+\usepackage[outputdir=TMP]{minted}
+\definecolor{bg}{rgb}{0.95,0.95,0.95}
+
+\usepackage{ccicons}
+\usepackage{paralist}
+
+% \renewcommand{\txarb}[1]{#1}
+% \renewcommand{\txtrans}[1]{\emph{#1}}
+% \renewcommand{\aemph}[1]{#1}
+% \renewcommand{\arbup}[1]{\textsuperscript{#1}}
+
+\begin{document}
+\vspace*{-.5in}
+\noindent
+\textbf{\textsf{arabluatex sample file}} --- \cczero\ This
+file is public domain
+
+\begin{compactenum}
+\item Copy the source code below, paste it into your
+ favorite tex editor and save it as
+ \verb|exporting.tex|.
+\item In the preamble, set \verb|export=true| in
+ \textsf{arabluatex} global options (line 3).
+\item Compile this file with Lua\LaTeX.
+\item Open \verb|exporting_out.tex| and compile it again
+ with Lua\LaTeX.
+\item Open \verb|exporting_out_out.tex|, then:
+ \begin{compactenum}
+ \item In the preamble, set \verb|export=false| in
+ \textsf{arabluatex} global options (line 3).
+ \item Compile this file and see the resulting
+ \verb|exporting_out_out.pdf|.
+ \end{compactenum}
+\item Finally, uncomment in the preamble the four lines
+ that are just above \verb|\begin{document}|.
+\item Open a terminal, then do:
+\begin{verbatim}
+pandoc exporting_out_out.tex -s -o exporting.odt
+\end{verbatim}
+ and open the resulting \verb|exporting.odt| file with LibreOffice.
+\end{compactenum}
+
+\phantomsection
+\section*{Source code}
+\label{ref:source-begin}
+\inputminted[firstnumber=last, bgcolor=bg]{latex}%
+ {TMP/exporting-preamble.tex}
+
+\begin{minted}[bgcolor=bg]{latex}
+\begin{document}
+\end{minted}
+\inputminted[firstnumber=last, bgcolor=bg]{latex}%
+ {TMP/exporting-dajaja.tex}
+\begin{minted}[bgcolor=bg]{latex}
+\end{document}
+\end{minted}
+\label{ref:source-end}
+
+\end{document}
diff --git a/macros/luatex/latex/arabluatex/samples/template-01.pdf b/macros/luatex/latex/arabluatex/samples/template-01.pdf
new file mode 100644
index 0000000000..b72fa71008
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/samples/template-01.pdf
Binary files differ
diff --git a/macros/luatex/latex/arabluatex/samples/template-01.tex b/macros/luatex/latex/arabluatex/samples/template-01.tex
new file mode 100644
index 0000000000..1a5ea4f8af
--- /dev/null
+++ b/macros/luatex/latex/arabluatex/samples/template-01.tex
@@ -0,0 +1,109 @@
+\documentclass[paper=letter, DIV=classic, headings=small]{scrartcl}
+
+\usepackage{ccicons}
+\usepackage{paralist}
+
+\usepackage{arabluatex}
+
+\usepackage{hyperref}
+\hypersetup{colorlinks, linkcolor=blue, breaklinks}
+
+\subject{\textsf{arabluatex} sample files}
+\title{The Basics}
+\author{Robert Alessi\thanks{\cczero\ This file is public domain.}}
+
+\begin{document}
+\maketitle
+
+\begin{abstract}
+ This file demonstrates the basic features of \texttt{arabluatex}.
+\end{abstract}
+
+\section{The less, the better}
+\label{sec:less-better}
+\textsf{arabluatex} is loaded by one single line in the preamble:
+\begin{verbatim}
+\usepackage{arabluatex}
+\end{verbatim}
+That said, there are two subsequent requirements:
+\begin{compactenum}
+\item An Arabic font: \textsf{arabluatex} tries to load the
+ \textsf{Amiri} Arabic font which is already part of
+ \textsf{texlive}.
+\item A Roman font that has all the characters that are needed for
+ the transliteration of the Arabic.
+\end{compactenum}
+
+Once these requirements are met, one may insert Arabic words in
+left-to-right paragraphs like so: \verb|\arb{da_hala mubtasimaN}|,
+\arb{da_hala mubtasimaN}. Or insert running paragraphs of Arabic text
+inside the \verb|arab| environment, like so:---
+\begin{verbatim}
+\begin{arab}
+ 'at_A .sadIquN 'il_A ju.hA ya.tlubu min-hu .himAra-hu li-yarkaba-hu
+ fI safraTiN qa.sIraTiN fa-qAla la-hu: sawfa 'u`Idu-hu 'ilay-ka fI
+ 'l-masA'-i wa-'adfa`u la-ka 'ujraTaN. fa-qAla ju.hA: 'anA 'AsifuN
+ jiddaN 'annI lA 'asta.tI`u 'an 'u.haqqiqa la-ka ra.gbata-ka
+ fa-'l-.himAr-u laysa hunA 'l-yawm-a. wa-qabla 'an yutimma ju.hA
+ kalAma-hu bada'a 'l-.himAr-u yanhaqu fI 'i.s.tabli-hi. fa-qAla la-hu
+ .sadIqu-hu: 'innI 'asma`u .himAra-ka yA ju.hA yanhaqu. fa-qAla la-hu
+ ju.hA: .garIbuN 'amru-ka yA .sadIqI 'a-tu.saddiqu 'l-.himAr-a
+ wa-tuka_d_diba-nI?
+\end{arab}
+\end{verbatim}
+\begin{arab}
+ 'at_A .sadIquN 'il_A ju.hA ya.tlubu min-hu .himAra-hu li-yarkaba-hu
+ fI safraTiN qa.sIraTiN fa-qAla la-hu: sawfa 'u`Idu-hu 'ilay-ka fI
+ 'l-masA'-i wa-'adfa`u la-ka 'ujraTaN. fa-qAla ju.hA: 'anA 'AsifuN
+ jiddaN 'annI lA 'asta.tI`u 'an 'u.haqqiqa la-ka ra.gbata-ka
+ fa-'l-.himAr-u laysa hunA 'l-yawm-a. wa-qabla 'an yutimma ju.hA
+ kalAma-hu bada'a 'l-.himAr-u yanhaqu fI 'i.s.tabli-hi. fa-qAla la-hu
+ .sadIqu-hu: 'innI 'asma`u .himAra-ka yA ju.hA yanhaqu. fa-qAla la-hu
+ ju.hA: .garIbuN 'amru-ka yA .sadIqI 'a-tu.saddiqu 'l-.himAr-a
+ wa-tuka_d_diba-nI?
+\end{arab}
+
+\section{Options}
+\label{sec:options}
+\textsf{arabluatex} may be loaded with four mutually exclusive options:---
+\begin{compactdesc}
+\item[voc] To have every short vowel written. This option is loaded by
+ default.
+\item[fullvoc] To have the \arb[trans]{sukUn} and the
+ \arb[trans]{wa.slaT} expressed in addition to what \verb|voc|
+ already does.
+\item[novoc] To have all the diacritics discarded.
+\item[trans] To have the Arabic transliterated into one of the
+ accepted standards.
+\end{compactdesc}
+\begin{verbatim}
+% <preamble>
+\usepackage{arabluatex} % this loads 'voc' by default
+\usepackage[voc]{arabluatex}
+\usepackage[fullvoc]{arabluatex}
+\usepackage[novoc]{arabluatex}
+\usepackage[trans]{arabluatex}
+\end{verbatim}
+
+At any point of the document, any mode can be set locally, like so:---
+\begin{verbatim}
+English paragraph: To have the \arb[trans]{sukUn} and the
+ \arb[trans]{wa.slaT} expressed...
+
+\begin{arab}[trans] % Arabic paragraph
+ 'at_A .sadIquN 'il_A \uc{j}u.hA ya.tlubu min-hu .himAra-hu
+ li-yarkaba-hu fI safraTiN qa.sIraTiN fa-qAla la-hu: sawfa 'u`Idu-hu
+ 'ilay-ka fI 'l-masA'-i wa-'adfa`u la-ka 'ujraTaN.
+\end{arab}
+\end{verbatim}
+
+English paragraph: To have the \arb[trans]{sukUn} and the
+ \arb[trans]{wa.slaT} expressed...
+
+\begin{arab}[trans] % Arabic paragraph
+ 'at_A .sadIquN 'il_A \uc{j}u.hA ya.tlubu min-hu .himAra-hu
+ li-yarkaba-hu fI safraTiN qa.sIraTiN fa-qAla la-hu: sawfa 'u`Idu-hu
+ 'ilay-ka fI 'l-masA'-i wa-'adfa`u la-ka 'ujraTaN.
+\end{arab}
+
+\end{document}
diff --git a/macros/luatex/latex/beamer-rl/Example-of-use-ar.pdf b/macros/luatex/latex/beamer-rl/Example-of-use-ar.pdf
new file mode 100644
index 0000000000..31b4ff520f
--- /dev/null
+++ b/macros/luatex/latex/beamer-rl/Example-of-use-ar.pdf
Binary files differ
diff --git a/macros/luatex/latex/beamer-rl/Example-of-use-ar.tex b/macros/luatex/latex/beamer-rl/Example-of-use-ar.tex
new file mode 100644
index 0000000000..367358a7b3
--- /dev/null
+++ b/macros/luatex/latex/beamer-rl/Example-of-use-ar.tex
@@ -0,0 +1,277 @@
+\documentclass{beamer}
+\usepackage{hologo} % pdflatex, xelatex, lualatex logos
+
+\usepackage{beamer-rl}
+\babelprovide[import=ar-DZ, main]{arabic}
+\babelfont{sf}{Amiri}
+
+% Themes without Navigation Bars
+%\mode<presentation>{\usetheme{default}}
+%\mode<presentation>{\usetheme{boxes}}
+%\mode<presentation>{\usetheme{Bergen}}
+%\mode<presentation>{\usetheme{Boadilla}}
+%\mode<presentation>{\usetheme{Madrid}}
+%\mode<presentation>{\usetheme{AnnArbor}}
+\mode<presentation>{\usetheme{CambridgeUS}}
+%\mode<presentation>{\usetheme{EastLansing}}
+%\mode<presentation>{\usetheme{Pittsburgh}}
+%\mode<presentation>{\usetheme{Rochester}}
+
+% Themes with a Tree-Like Navigation Bar
+%\mode<presentation>{\usetheme{Antibes}}
+%\mode<presentation>{\usetheme{JuanLesPins}}
+%\mode<presentation>{\usetheme{Montpellier}}
+
+% Themes with a Table of Contents Sidebar
+%\mode<presentation>{\usetheme{Berkeley}}
+%\mode<presentation>{\usetheme{PaloAlto}}
+%\mode<presentation>{\usetheme{Goettingen}}
+%\mode<presentation>{\usetheme{Hannover}}
+
+% Themes with a Mini Frame Navigation
+%\mode<presentation>{\usetheme{Berlin}}
+%\mode<presentation>{\usetheme{Ilmenau}}
+%\mode<presentation>{\usetheme{Dresden}}
+%\mode<presentation>{\usetheme{Darmstadt}}
+%\mode<presentation>{\usetheme{Frankfurt}}
+%\mode<presentation>{\usetheme{Singapore}}
+%\mode<presentation>{\usetheme{Szeged}}
+
+% Themes with Section and Subsection Tables
+%\mode<presentation>{\usetheme{Copenhagen}}
+%\mode<presentation>{\usetheme{Luebeck}}
+%\mode<presentation>{\usetheme{Malmoe}}
+%\mode<presentation>{\usetheme{Warsaw}}
+
+\usecolortheme{spruce}
+
+\title{حزمة beamer-rl}
+
+\author{Salim Bou}
+
+\institute[]{%
+{\color{blue} Repository: } https://github.com/seloumi/beamer-rl \par
+{\color{blue} Bug tracker: } https://github.com/seloumi/beamer-rl/issues
+}
+
+\date{\today}
+
+\setbeamercovered{transparent=10}
+\newtheorem*{thm}{نظرية.}
+
+\def\cs#1{\babelsublr{\texttt{\textbackslash#1}}}
+
+\begin{document}
+
+\parskip=6pt
+
+\begin{frame}
+\titlepage
+\end{frame}
+
+\begin{frame}
+\frametitle{\contentsname}
+\tableofcontents
+\end{frame}
+
+\section{مدخل}
+
+\begin{frame}[fragile]
+\frametitle{مدخل}
+انشاء عرض بيمر عربي (اتجاه النص من اليمين لليسار) اعتمادا على
+ \hologo{pdfLaTeX} أو \hologo{XeLaTeX} مازال يعترضه الكثير من المشاكل والمعوقات خاصة ما يتعلق بالألوان والروابط والتي لم يوجد لها حلولا~بعد.
+
+Ùريق \hologo{LuaTeX}
+أوجد حلولا لهذه المشاكل، الشكر لهم ولـ
+\textit{Javier~Bezos}
+لأعماله بالحزمة
+\verb|babel| وخصوصا الكتابة بالاتجاهين (\verb|bidi| writing)
+
+هذه الحزمة تعدل ÙÙŠ بعض اوامر وتعليمات beamer لغرض انشاء عروض من اليمين إلى اليسار (العربية على سبيل المثال)ØŒ الحزمة تستدعي \verb|babel| مع الخيار
+\verb|bidi=basic-r|
+ والمعالجة تتطلب استخدام
+\hologo{LuaLaTeX}
+
+\end{frame}
+
+\section{كيÙية استعمال الحزمة}
+
+\begin{frame}[fragile]
+\frametitle{كيÙية استعمال الحزمة}
+
+\selectlanguage{nil}
+
+\begin{verbatim}
+\documentclass{beamer}
+\usepackage{beamer-rl}
+\babelprovide[import=ar-DZ, main]{arabic}
+\babelfont{sf}{Amiri}
+
+\mode<presentation>{\usetheme{Warsaw}}
+\begin{document}
+...
+\end{document}
+
+\end{verbatim}
+
+\end{frame}
+
+\section{أمثلة}
+\subsection{الإطارات}
+
+\begin{frame}[fragile]
+\frametitle{الإطارات}
+
+{\selectlanguage{nil}
+\verb:\setbeamertemplate{blocks}[default]:
+}
+
+\setbeamertemplate{blocks}[default]
+
+
+\begin{block}{أورستد}
+ لاحظ هانز أورستد ÙÙŠ 21 أبريل 1820 وهو ÙŠÙعد أحد التجارب أن إبرة
+ البوصلة تنحر٠عن اتجاهها نحو الشمال عندما كان يغلق ويÙتح التيار ÙÙŠ
+ دائرة كهربائية ÙŠÙعدها.
+\end{block}
+
+{\selectlanguage{nil}
+\verb:\setbeamertemplate{blocks}[rounded][shadow=true]:
+}
+
+\setbeamertemplate{blocks}[rounded][shadow=true]
+
+\begin{block}{أورستد}
+ لاحظ هانز أورستد ÙÙŠ 21 أبريل 1820 وهو ÙŠÙعد أحد التجارب أن إبرة
+ البوصلة تنحر٠عن اتجاهها نحو الشمال عندما كان يغلق ويÙتح التيار ÙÙŠ
+ دائرة كهربائية ÙŠÙعدها.
+\end{block}
+
+\end{frame}
+
+\subsection{القوائم}
+
+\begin{frame}[fragile]
+\frametitle{enumerate, itemize}
+
+\begin{enumerate}
+\item Ùيزياء تطبيقية
+\item Ùيزياء تجريبية
+\item Ùيزياء نظرية
+\end{enumerate}
+
+\setbeamertemplate{itemize item}[triangle]
+
+{\selectlanguage{nil}
+\verb|\setbeamertemplate{itemize item}[triangle]|
+}
+
+\begin{itemize}
+\item Ùيزياء تطبيقية
+\item Ùيزياء تجريبية
+\item Ùيزياء نظرية
+\end{itemize}
+
+\selectlanguage{nil}
+
+\begin{itemize}
+\item first item
+\item second item
+\item third item
+\end{itemize}
+
+\end{frame}
+
+\subsection{الروابط}
+
+\begin{frame}
+\frametitle{الروابط}
+\begin{itemize}
+\item<1-> العنصر الأول.
+\item<2-> العنصر الثاني.
+\item<3-> العنصر الثالث.
+\end{itemize}
+\hyperlink{jumptosecond}{\beamerreturnbutton{الرجوع إلى الشريحة الثانية}}
+\hypertarget<2>{jumptosecond}{}
+
+\end{frame}
+
+
+\subsection{النظريات}
+
+\begin{frame}
+\frametitle{النظريات}
+
+\framesubtitle{The proof uses \textit{reductio ad absurdum}.}
+\begin{thm}
+There is no largest prime number.
+\end{thm}
+\begin{proof}
+\begin{enumerate}[<+-| alert@+>]
+\item Suppose $p$ were the largest prime number.
+\item Let $q$ be the product of the first $p$ numbers.
+\item Then $q+1$ is not divisible by any of them.
+\item But $q + 1$ is greater than $1$, thus divisible by some prime
+number not in the first $p$ numbers.\qedhere
+\end{enumerate}
+\end{proof}
+
+\end{frame}
+
+\subsection{التكبير}
+
+\begin{frame}[fragile]
+\frametitle{التكبير}
+
+\framezoom<1><2>[border=2](2cm,2cm)(2cm,2cm)
+\pgfimage[height=5cm]{example-image}
+
+\selectlanguage{nil}
+
+\begin{verbatim}
+\framezoom<1><2>[border=2](2cm,2cm)(2cm,2cm)
+\pgfimage[height=5cm]{example-image}
+\end{verbatim}
+\end{frame}
+
+\section{بعض الملاحظات}
+
+\begin{frame}[fragile]
+\frametitle{بعض الملاحظات}
+
+\begin{itemize}
+\item
+الحزمة
+ \verb:beamer-rl: تقوم بتبادل لكل من التعليمتين \cs{blacktriangleright} Ùˆ \cs{blacktriangleleft} ÙÙŠ حالة نص من اليمين لليسار
+
+\bigskip
+
+{\selectlanguage{nil}
+\centering
+\begin{tabular}{c|cc}
+\hline
+ & \verb:\blacktriangleright: & \verb:\blacktriangleleft: \\
+\hline
+LTR context & \blacktriangleright & \blacktriangleleft \\
+\hline
+RTL context & {\selectlanguage{arabic}\blacktriangleright} & {\selectlanguage{arabic}\blacktriangleleft} \\
+\hline
+\end{tabular}
+\par
+}
+
+\bigskip
+
+
+\item
+ÙÙŠ بعض الحالات يمكن استعمال التعليمة
+ \cs{babelsublr} التي توÙرها الحزمة \verb:bebel:
+لادراج نص من اليسار لليمين (لاتيني) ÙÙŠ وسط نص من اليمين لليسار،
+ على سبيل المثال ÙÙŠ حال اردنا ادراج رسم
+ \verb:pspicture: ضمن نص من اليمين لليسار.
+\end{itemize}
+
+
+\end{frame}
+
+\end{document}
diff --git a/macros/luatex/latex/beamer-rl/Example-of-use-en.pdf b/macros/luatex/latex/beamer-rl/Example-of-use-en.pdf
new file mode 100644
index 0000000000..4629290c75
--- /dev/null
+++ b/macros/luatex/latex/beamer-rl/Example-of-use-en.pdf
Binary files differ
diff --git a/macros/luatex/latex/beamer-rl/Example-of-use-en.tex b/macros/luatex/latex/beamer-rl/Example-of-use-en.tex
new file mode 100644
index 0000000000..3593e93759
--- /dev/null
+++ b/macros/luatex/latex/beamer-rl/Example-of-use-en.tex
@@ -0,0 +1,266 @@
+\documentclass{beamer}
+\usepackage{hologo} % pdflatex, xelatex, lualatex logos
+
+\usepackage{beamer-rl}
+\babelprovide[import=ar-DZ, main]{arabic}
+\babelprovide[import,language=Default]{english}
+\babelfont{sf}{Amiri}
+
+% Themes without Navigation Bars
+%\mode<presentation>{\usetheme{default}}
+%\mode<presentation>{\usetheme{boxes}}
+%\mode<presentation>{\usetheme{Bergen}}
+%\mode<presentation>{\usetheme{Boadilla}}
+\mode<presentation>{\usetheme{Madrid}}
+%\mode<presentation>{\usetheme{AnnArbor}}
+%\mode<presentation>{\usetheme{CambridgeUS}}
+%\mode<presentation>{\usetheme{EastLansing}}
+%\mode<presentation>{\usetheme{Pittsburgh}}
+%\mode<presentation>{\usetheme{Rochester}}
+
+% Themes with a Tree-Like Navigation Bar
+%\mode<presentation>{\usetheme{Antibes}}
+%\mode<presentation>{\usetheme{JuanLesPins}}
+%\mode<presentation>{\usetheme{Montpellier}}
+
+% Themes with a Table of Contents Sidebar
+%\mode<presentation>{\usetheme{Berkeley}}
+%\mode<presentation>{\usetheme{PaloAlto}}
+%\mode<presentation>{\usetheme{Goettingen}}
+%\mode<presentation>{\usetheme{Hannover}}
+
+% Themes with a Mini Frame Navigation
+%\mode<presentation>{\usetheme{Berlin}}
+%\mode<presentation>{\usetheme{Ilmenau}}
+%\mode<presentation>{\usetheme{Dresden}}
+%\mode<presentation>{\usetheme{Darmstadt}}
+%\mode<presentation>{\usetheme{Frankfurt}}
+%\mode<presentation>{\usetheme{Singapore}}
+%\mode<presentation>{\usetheme{Szeged}}
+
+% Themes with Section and Subsection Tables
+%\mode<presentation>{\usetheme{Copenhagen}}
+%\mode<presentation>{\usetheme{Luebeck}}
+%\mode<presentation>{\usetheme{Malmoe}}
+%\mode<presentation>{\usetheme{Warsaw}}
+
+\title{The beamer-rl package}
+
+\author{Salim Bou}
+
+\institute[]{%
+{\color{blue} Repository: } https://github.com/seloumi/beamer-rl \par
+{\color{blue} Bug tracker: } https://github.com/seloumi/beamer-rl/issues
+}
+
+
+\date{{\selectlanguage{english} \today}}
+
+\setbeamercovered{transparent=10}
+\newtheorem*{prf}{Proof}
+
+
+\begin{document}
+
+\parskip=6pt
+
+\begin{frame}
+\titlepage
+\end{frame}
+
+\begin{frame}
+\frametitle{\selectlanguage{english}\contentsname}
+\tableofcontents
+\end{frame}
+
+\section{Introduction}
+
+\begin{frame}[fragile]
+\frametitle{Introduction}
+Creating beamer presentation for right to left language (like arabic) using \hologo{pdfLaTeX} or \hologo{XeLaTeX} still poses many problems due to bugs not currently resolved especially for colors and hyperlinks
+
+The \hologo{LuaTeX} team set solutions for these issues thanks to them and to \textit{Javier~Bezos} for his works on the package \verb|babel| and \verb|bidi| writing
+
+This package provides patchs of some beamer templates and commands
+for right to left presentation, this package call babel with \verb|bidi=basic-r| option and require lualatex engine
+
+\end{frame}
+
+\section{How to use beamer-rl}
+
+\begin{frame}[fragile]
+\frametitle{How to use beamer-rl}
+
+\selectlanguage{nil}
+
+\begin{verbatim}
+\documentclass{beamer}
+\usepackage{beamer-rl}
+\babelprovide[import=ar-DZ, main]{arabic}
+\babelfont{sf}{Amiri}
+
+\mode<presentation>{\usetheme{Warsaw}}
+\begin{document}
+...
+\end{document}
+
+\end{verbatim}
+
+\end{frame}
+
+\section{Examples}
+\subsection{Blocks}
+
+\begin{frame}[fragile]
+\frametitle{Blocks}
+
+{\selectlanguage{nil}
+\verb:\setbeamertemplate{blocks}[default]:
+}
+
+\setbeamertemplate{blocks}[default]
+
+
+\begin{block}{Lorem}
+ \selectlanguage{nil}
+ On 21 April 1820, during a lecture, Ørsted
+ noticed a compass needle deflected from magnetic north when an
+ electric current from a battery was switched on and off.
+\end{block}
+
+{\selectlanguage{nil}
+\verb:\setbeamertemplate{blocks}[rounded][shadow=true]:
+}
+
+\setbeamertemplate{blocks}[rounded][shadow=true]
+
+\begin{block}{Lorem}
+ \selectlanguage{nil}
+ On 21 April 1820, during a lecture, Ørsted
+ noticed a compass needle deflected from magnetic north when an
+ electric current from a battery was switched on and off.
+\end{block}
+
+\end{frame}
+
+\subsection{Lists}
+
+\begin{frame}[fragile]
+\frametitle{enumerate, itemize}
+
+\begin{enumerate}
+\item first item
+\item second item
+\item third item
+\end{enumerate}
+
+\setbeamertemplate{itemize item}[triangle]
+
+{\selectlanguage{nil}
+\verb|\setbeamertemplate{itemize item}[triangle]|
+}
+
+
+\begin{itemize}
+\item first item
+\item second item
+\item third item
+\end{itemize}
+
+\selectlanguage{nil}
+
+\begin{itemize}
+\item first item
+\item second item
+\item third item
+\end{itemize}
+
+
+\end{frame}
+
+\subsection{Hyperlinks}
+
+\begin{frame}
+\frametitle{Hyperlinks}
+\begin{itemize}
+\item<1-> First item.
+\item<2-> Second item.
+\item<3-> Third item.
+\end{itemize}
+\hyperlink{jumptosecond}{\beamergotobutton{return to second slide}}
+\hypertarget<2>{jumptosecond}{}
+\end{frame}
+
+
+\subsection{Theorems}
+
+\begin{frame}
+\frametitle{Theorems}
+
+\framesubtitle{The proof uses \textit{reductio ad absurdum}.}
+\begin{theorem}
+There is no largest prime number.
+\end{theorem}
+\begin{prf}
+\begin{enumerate}[<+-| alert@+>]
+\item Suppose $p$ were the largest prime number.
+\item Let $q$ be the product of the first $p$ numbers.
+\item Then $q+1$ is not divisible by any of them.
+\item But $q + 1$ is greater than $1$, thus divisible by some prime
+number not in the first $p$ numbers.\qedhere
+\end{enumerate}
+\end{prf}
+
+\end{frame}
+
+\subsection{Zooming}
+
+\begin{frame}[fragile]
+\frametitle{Zooming}
+
+\framezoom<1><2>[border=2](2cm,2cm)(2cm,2cm)
+\pgfimage[height=5cm]{example-image}
+
+\selectlanguage{nil}
+
+\begin{verbatim}
+\framezoom<1><2>[border=2](2cm,2cm)(2cm,2cm)
+\pgfimage[height=5cm]{example-image}
+\end{verbatim}
+\end{frame}
+
+\section{Some notes}
+
+\begin{frame}[fragile]
+\frametitle{Some notes}
+
+\begin{itemize}
+\item
+The \verb:beamer-rl: package swap the definition of \verb:\blacktriangleright: with \verb:\blacktriangleleft: in RTL context.
+
+\bigskip
+
+{\selectlanguage{nil}
+\centering
+\begin{tabular}{c|cc}
+\hline
+ & \verb:\blacktriangleright: & \verb:\blacktriangleleft: \\
+\hline
+LTR context & \blacktriangleright & \blacktriangleleft \\
+\hline
+RTL context & {\selectlanguage{arabic}\blacktriangleright} & {\selectlanguage{arabic}\blacktriangleleft} \\
+\hline
+\end{tabular}
+\par
+}
+
+\bigskip
+
+\item
+In some cases you need to use \verb:\babelsublr: command from \verb:bebel:
+package to insert a left to right text within your right to left text, e.g if you need to insert a \verb:pspicture: drawing in RTL context
+\end{itemize}
+
+\end{frame}
+
+\end{document}
diff --git a/macros/luatex/latex/beamer-rl/README.txt b/macros/luatex/latex/beamer-rl/README.txt
new file mode 100644
index 0000000000..a262ea9250
--- /dev/null
+++ b/macros/luatex/latex/beamer-rl/README.txt
@@ -0,0 +1,23 @@
+The beamer-rl package
+v1.2
+
+This package provides patchs of some beamer templates and commands
+for right to left presentation, this package require babel with lualatex engine
+If you want to report any bugs or typos and corrections in the
+documentation then
+please use the issue tracker:
+
+ <https://github.com/seloumi/beamer-rl/issues>
+
+Current version release date: 2019/04/03
+
+___________________
+Salim Bou
+
+Copyright (c) 2019
+It may be distributed and/or modified under the LaTeX Project Public License,
+version 1.3c or higher (your choice). The latest version of
+this license is at: http://www.latex-project.org/lppl.txt
+
+This work is author-maintained (as per LPPL maintenance status)
+by Salim Bou. \ No newline at end of file
diff --git a/macros/luatex/latex/beamer-rl/beamer-rl.sty b/macros/luatex/latex/beamer-rl/beamer-rl.sty
new file mode 100644
index 0000000000..b476c58fb0
--- /dev/null
+++ b/macros/luatex/latex/beamer-rl/beamer-rl.sty
@@ -0,0 +1,467 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{beamer-rl}
+[2019/04/03 v1.2 LaTeX package to patch beamer for right to left presentation]
+
+\RequirePackage[nil,bidi=basic-r,layout=counters.lists.tabular]{babel}
+
+\def\reset@temp#1#2{\expandafter\let\csname beamer@@tmpop@#1@#2\endcsname\relax}
+\def\@@defbeamertemplate#1#2{\reset@temp{#1}{#2}\defbeamertemplate{#1}{#2}}
+\def\@defbeamertemplate#1#2{\reset@temp{#1}{#2}\defbeamertemplate*{#1}{#2}}
+
+\def\redefbeamertemplate{%
+ \@ifstar{\@defbeamertemplate}{\@@defbeamertemplate}%
+}
+
+\let\old@blacktriangleright\blacktriangleright
+\let\old@blacktriangleleft\blacktriangleleft
+
+\def\blacktriangleright{%
+ \ifcase\bbl@thepardir \old@blacktriangleright\else\old@blacktriangleleft\fi}
+\def\blacktriangleleft{%
+ \ifcase\bbl@thepardir \old@blacktriangleleft\else\old@blacktriangleright\fi}
+
+
+\let\oldpgfpicture\pgfpicture
+\let\oldendpgfpicture\endpgfpicture
+
+\def\pgfpicture{\babelsublr\bgroup\oldpgfpicture}
+\def\endpgfpicture{\oldendpgfpicture\egroup}
+
+\let\oldpgfuseshading\pgfuseshading
+\def\pgfuseshading#1{\babelsublr{\oldpgfuseshading{#1}}}
+
+\hypersetup{unicode}
+
+
+%% beamerbasebox
+
+\newdimen\bmb@dimc
+
+\renewcommand\beamerboxesrounded[2][]{%
+ \global\let\beamer@firstlineitemizeunskip=\relax%
+ \vbox\bgroup%
+ \setkeys{beamerboxes}{upper=block title,lower=block body,width=\textwidth,shadow=false}%
+ \setkeys{beamerboxes}{#1}%
+ {%
+ \usebeamercolor{\bmb@lower}%
+ \globalcolorstrue%
+ \colorlet{lower.bg}{bg}%
+ }%
+ {%
+ \usebeamercolor{\bmb@upper}%
+ \globalcolorstrue%
+ \colorlet{upper.bg}{bg}%
+ }%
+ %
+ % Typeset head
+ %
+ \vskip4bp
+ \setbox\bmb@box=\hbox{%
+ \begin{minipage}[b]{\bmb@width}%
+ \usebeamercolor[fg]{\bmb@upper}%
+ #2%
+ \end{minipage}}%
+ \ifdim\wd\bmb@box=0pt%
+ \setbox\bmb@box=\hbox{}%
+ \ht\bmb@box=1.5pt%
+ \bmb@prevheight=-4.5pt%
+ \else%
+ \wd\bmb@box=\bmb@width%
+ \bmb@temp=\dp\bmb@box%
+ \ifdim\bmb@temp<1.5pt%
+ \bmb@temp=1.5pt%
+ \fi%
+ \setbox\bmb@box=\hbox{\raise\bmb@temp\hbox{\box\bmb@box}}%
+ \dp\bmb@box=0pt%
+ \bmb@prevheight=\ht\bmb@box%
+ \fi%
+ \bmb@temp=\bmb@width%
+ \bmb@dima=\bmb@temp\advance\bmb@dima by2.2bp%
+ \bmb@dimb=\bmb@temp\advance\bmb@dimb by4bp%
+ \ifdim\wd\bmb@box=0pt
+ \bmb@dimc=\bmb@width%
+ \else
+ \bmb@dimc=0pt%
+ \fi
+ \hbox{%
+ \textdir TLT\begin{pgfpicture}{0bp}{+-\ht\bmb@box}{\bmb@dimc}{+-\ht\bmb@box}
+ \ifdim\wd\bmb@box=0pt%
+ \color{lower.bg}%
+ \else%
+ \color{upper.bg}%
+ \fi%
+ \pgfpathqmoveto{-4bp}{-1bp}
+ \pgfpathqcurveto{-4bp}{1.2bp}{-2.2bp}{3bp}{0bp}{3bp}
+ \pgfpathlineto{\pgfpoint{\bmb@temp}{3bp}}
+ \pgfpathcurveto%
+ {\pgfpoint{\bmb@dima}{3bp}}%
+ {\pgfpoint{\bmb@dimb}{1.2bp}}%
+ {\pgfpoint{\bmb@dimb}{-1bp}}%
+ \bmb@dima=-\ht\bmb@box%
+ \advance\bmb@dima by-2pt%
+ \pgfpathlineto{\pgfpoint{\bmb@dimb}{\bmb@dima}}
+ \pgfpathlineto{\pgfpoint{-4bp}{\bmb@dima}}
+ \pgfusepath{fill}
+ \end{pgfpicture}%
+ \copy\bmb@box%
+ }%
+ \nointerlineskip%
+ \vskip-1pt%
+ \ifdim\wd\bmb@box=0pt%
+ \else%
+ \hbox{%
+ \begin{pgfpicture}{0pt}{0pt}{\bmb@width}{6pt}
+ \bmb@dima=\bmb@width%
+ \advance\bmb@dima by8bp%
+ \pgfpathrectangle{\pgfpoint{-4bp}{-1bp}}{\pgfpoint{\bmb@dima}{8bp}}
+ \pgfusepath{clip}
+ {\pgftransformshift{\pgfpoint{-4bp}{0bp}}\pgftext[left,base]{\pgfuseshading{bmb@transition}}}%
+ \end{pgfpicture}%
+ }%
+ \nointerlineskip%
+ \vskip-0.5pt%
+ \fi%
+ \ifbmb@shadow%
+ \setbox\bmb@boxshadow=\hbox{\pgfuseshading{bmb@shadow}}%
+ \setbox\bmb@boxshadowball=\hbox{\pgfuseshading{bmb@shadowball}}%
+ \setbox\bmb@boxshadowballlarge=\hbox{\pgfuseshading{bmb@shadowballlarge}}%
+ \fi%
+ \setbox\bmb@colorbox=\hbox{{\pgfpicturetrue\pgfsetcolor{lower.bg}}}%
+ \setbox\bmb@box=\hbox\bgroup\begin{minipage}[b]{\bmb@width}%
+ \vskip2pt%
+ \usebeamercolor[fg]{\bmb@lower}%
+ \colorlet{beamerstructure}{upper.bg}%
+ \colorlet{structure}{upper.bg}%
+ %\color{.}%
+ }
+
+ \def\endbeamerboxesrounded{%
+ \end{minipage}\egroup%
+ \wd\bmb@box=\bmb@width%
+ \bmb@temp=\dp\bmb@box%
+ \advance\bmb@temp by.5pt%
+ \setbox\bmb@box=\hbox{\raise\bmb@temp\hbox{\box\bmb@box}}%
+ \dp\bmb@box=0pt%
+ \bmb@temp=\wd\bmb@box%
+ \bmb@dima=\bmb@temp\advance\bmb@dima by2.2bp%
+ \bmb@dimb=\bmb@temp\advance\bmb@dimb by4bp%
+ \hbox{%
+ \textdir TLT\begin{pgfpicture}{0bp}{0bp}{0bp}{0bp}
+ \ifbmb@shadow%
+ {\pgftransformshift{\pgfpoint{4bp}{-3bp}}\pgftext{\copy\bmb@boxshadowball}}
+ \begin{pgfscope}
+ {%
+ \advance\bmb@temp by-1bp%
+ \pgfpathrectangle{\pgfpoint{\bmb@temp}{-7bp}}{\pgfpoint{9bp}{9bp}}%
+ \pgfusepath{clip}
+ }%
+ {\pgftransformshift{\pgfpoint{\bmb@temp}{1bp}}\pgftext{\box\bmb@boxshadowballlarge}}
+ \end{pgfscope}
+ \begin{pgfscope}
+ \advance\bmb@temp by-4bp%
+ \pgfpathrectangle{\pgfpoint{4bp}{-7bp}}{\pgfpoint{\bmb@temp}{5bp}}
+ \pgfusepath{clip}
+ {\pgftransformshift{\pgfpoint{4bp}{-7bp}}\pgftext[left,base]{\copy\bmb@boxshadow}}%
+ \end{pgfscope}
+ \begin{pgfscope}
+ \advance\bmb@temp by 4bp%
+ \bmb@dima=\ht\bmb@box%
+ \advance\bmb@dima by\bmb@prevheight%
+ \advance\bmb@dima by 4bp%
+ \pgfpathrectangle{\pgfpoint{\bmb@temp}{1bp}}{\pgfpoint{4bp}{\bmb@dima}}
+ \pgfusepath{clip}
+ \advance\bmb@dima by-4bp%
+ {\pgftransformshift{\pgfpoint{\bmb@temp}{\bmb@dima}}\pgftext{\box\bmb@boxshadowball}}
+ \advance\bmb@dima by-1bp%
+ \pgfpathrectangle{\pgfpoint{\bmb@temp}{1bp}}{\pgfpoint{4bp}{\bmb@dima}}
+ \pgfusepath{clip}
+ \advance\bmb@temp by4bp%
+ {\pgftransformshift{\pgfpoint{\bmb@temp}{-3bp}}%
+ \pgftransformrotate{90}%
+ \pgftext[left,base]{\box\bmb@boxshadow}}%
+ \end{pgfscope}
+ \fi%
+ \unhbox\bmb@colorbox%
+ \pgfpathqmoveto{-4bp}{1bp}
+ \pgfpathqcurveto{-4bp}{-1.2bp}{-2.2bp}{-3bp}{0bp}{-3bp}
+ \pgfpathlineto{\pgfpoint{\the\bmb@temp}{-3bp}}
+ \pgfpathcurveto%
+ {\pgfpoint{\the\bmb@dima}{-3bp}}%
+ {\pgfpoint{\the\bmb@dimb}{-1.2bp}}%
+ {\pgfpoint{\the\bmb@dimb}{1bp}}%
+ {
+ \bmb@dima=\ht\bmb@box%
+ \pgfpathlineto{\pgfpoint{\bmb@dimb}{\bmb@dima}}
+ \pgfpathlineto{\pgfpoint{-4bp}{\bmb@dima}}
+ \pgfusepath{fill}
+ }
+ \ifbmb@shadow%
+ {
+ \color{black!50!bg}
+ \pgfsetlinewidth{0pt}
+ \pgfpathmoveto{\pgfpoint{\bmb@dimb}{-.5bp}}
+ \bmb@dima=\ht\bmb@box%
+ \advance\bmb@dima by\bmb@prevheight%
+ \advance\bmb@dima by 1bp%
+ \pgfpathlineto{\pgfpoint{\bmb@dimb}{\bmb@dima}}
+ \pgfusepath{stroke}
+ \bmb@temp=\bmb@dima
+ \advance\bmb@dima by 1bp%
+ \color{black!31!bg}
+ \pgfpathmoveto{\pgfpoint{\bmb@dimb}{\bmb@temp}}
+ \pgfpathlineto{\pgfpoint{\bmb@dimb}{\bmb@dima}}
+ \pgfusepath{stroke}
+ \advance\bmb@dima by 1bp%
+ \advance\bmb@temp by 1bp%
+ \color{black!19!bg}
+ \pgfpathmoveto{\pgfpoint{\bmb@dimb}{\bmb@temp}}
+ \pgfpathlineto{\pgfpoint{\bmb@dimb}{\bmb@dima}}
+ \pgfusepath{stroke}
+ \advance\bmb@dima by 1bp%
+ \advance\bmb@temp by 1bp%
+ \color{black!6!bg}
+ \pgfpathmoveto{\pgfpoint{\bmb@dimb}{\bmb@temp}}
+ \pgfpathlineto{\pgfpoint{\bmb@dimb}{\bmb@dima}}
+ \pgfusepath{stroke}
+ \advance\bmb@dima by 1.5bp%
+ \advance\bmb@temp by 1bp%
+ \color{bg}
+ \pgfpathmoveto{\pgfpoint{\bmb@dimb}{\bmb@temp}}
+ \pgfpathlineto{\pgfpoint{\bmb@dimb}{\bmb@dima}}
+ \pgfusepath{stroke}
+ }
+ \fi
+ \end{pgfpicture}%
+ \box\bmb@box%
+ }%
+ \ifbmb@shadow%
+ \vskip4bp minus 2bp%
+ \else%
+ \vskip2bp%
+ \fi%
+ \egroup% of \vbox\bgroup
+}
+
+
+%% beamerbaseauxtemplates
+
+
+% (sub-)section in toc: subsections numbered
+
+\redefbeamertemplate{subsection in toc}{subsections numbered}
+{\leavevmode\leftskip=2em\rlap{\hskip-2em \inserttocsectionnumber\hbox{.}\inserttocsubsectionnumber}\inserttocsubsection\par}
+
+
+%% beamerinnerthemedefault
+
+\redefbeamertemplate*{button}{default}
+{%
+ \setbox\beamer@tempbox=\hbox{{\insertbuttontext}}%
+ \ht\beamer@tempbox=6pt%
+ \dp\beamer@tempbox=0pt%
+ \setbox\beamer@tempbox=\vbox{\box\beamer@tempbox\vskip2pt}%
+ \beamer@tempdim=\wd\beamer@tempbox%
+ \beamer@dima=\beamer@tempdim\advance\beamer@dima by2.2pt
+ \beamer@dimb=\beamer@tempdim\advance\beamer@dimb by4pt
+ \textdir TLT\begin{pgfpicture}{-4pt}{0pt}{\the\beamer@tempdim}{8pt}
+ \color{bg}
+ \pgfsetlinewidth{0.8pt}
+ \pgfpathqmoveto{0pt}{0pt}
+ \pgfpathqcurveto{-2.2pt}{0pt}{-4pt}{1.8pt}{-4pt}{4pt}
+ \pgfpathqcurveto{-4pt}{6.2pt}{-2.2pt}{8pt}{0pt}{8pt}
+ \pgfpathlineto{\pgfpoint{\the\beamer@tempdim}{8pt}}
+ \pgfpathcurveto%
+ {\pgfpoint{\the\beamer@dima}{8pt}}%
+ {\pgfpoint{\the\beamer@dimb}{6.2pt}}%
+ {\pgfpoint{\the\beamer@dimb}{4pt}}
+ \pgfpathcurveto%
+ {\pgfpoint{\the\beamer@dimb}{1.8pt}}%
+ {\pgfpoint{\the\beamer@dima}{0pt}}%
+ {\pgfpoint{\the\beamer@tempdim}{0pt}}
+ \pgfpathclose
+ \pgfusepathqfill
+ \colorlet{bg}{parent.bg}
+ \usebeamercolor[fg]{button border}
+ \pgfpathqmoveto{0pt}{0pt}
+ \pgfpathqcurveto{-2.2pt}{0pt}{-4pt}{1.8pt}{-4pt}{4pt}
+ \pgfpathqcurveto{-4pt}{6.2pt}{-2.2pt}{8pt}{0pt}{8pt}
+ \pgfpathlineto{\pgfpoint{\the\beamer@tempdim}{8pt}}
+ \pgfpathcurveto%
+ {\pgfpoint{\the\beamer@dima}{8pt}}%
+ {\pgfpoint{\the\beamer@dimb}{6.2pt}}%
+ {\pgfpoint{\the\beamer@dimb}{4pt}}
+ \pgfpathcurveto%
+ {\pgfpoint{\the\beamer@dimb}{1.8pt}}%
+ {\pgfpoint{\the\beamer@dima}{0pt}}%
+ {\pgfpoint{\the\beamer@tempdim}{0pt}}
+ \pgfpathclose
+ \pgfusepathqstroke
+ \end{pgfpicture}%
+ \hskip-\beamer@tempdim%
+ \box\beamer@tempbox%
+ \kern4pt%
+}
+
+%% beamerbasenavigation
+
+% User Buttons
+
+\pgfdefobject{beamergotosymbol}{\pgfpoint{0pt}{-1pt}}{\pgfpoint{5pt}{5pt}}
+{
+ \pgfpathqmoveto{1.5bp}{0.5bp}
+ \pgfpathqlineto{3.5bp}{2bp}
+ \pgfpathqlineto{1.5bp}{3.5bp}
+ \pgfusepathqfill
+}
+
+\def\insertgotosymbol{%
+ \begin{pgfpicture}{1pt}{0pt}{6pt}{5pt}
+ \pgfuseobject{\ifcase\bbl@thepardir beamergotosymbol\else beamerreturnsymbol\fi}%
+\end{pgfpicture}}
+
+\pgfdefobject{beamerreturnsymbol}{\pgfpoint{0pt}{-1pt}}{\pgfpoint{5pt}{5pt}}
+{
+ \pgfpathqmoveto{3.5bp}{0.5bp}
+ \pgfpathqlineto{1.5bp}{2bp}
+ \pgfpathqlineto{3.5bp}{3.5bp}
+ \pgfusepathqfill
+}
+
+\def\insertreturnsymbol{%
+ \begin{pgfpicture}{1pt}{0pt}{6pt}{5pt}
+ \pgfuseobject{\ifcase\bbl@thepardir beamerreturnsymbol\else beamergotosymbol\fi}%
+\end{pgfpicture}}
+
+
+\pgfdefobject{beamerskipsymbolrl}{\pgfpoint{0pt}{-1pt}}{\pgfpoint{7pt}{5pt}}
+{
+ \pgfpathqmoveto{3.5bp}{0.5bp}
+ \pgfpathqlineto{1.5bp}{2bp}
+ \pgfpathqlineto{3.5bp}{3.5bp}
+ \pgfpathqmoveto{5.5bp}{0.5bp}
+ \pgfpathqlineto{3.5bp}{2bp}
+ \pgfpathqlineto{5.5bp}{3.5bp}
+ \pgfusepathqfill
+}
+
+\pgfdefobject{beamerskipsymbol}{\pgfpoint{0pt}{-1pt}}{\pgfpoint{7pt}{5pt}}
+{
+ \pgfpathqmoveto{1.5bp}{0.5bp}
+ \pgfpathqlineto{3.5bp}{2bp}
+ \pgfpathqlineto{1.5bp}{3.5bp}
+ \pgfpathqmoveto{3.5bp}{0.5bp}
+ \pgfpathqlineto{5.5bp}{2bp}
+ \pgfpathqlineto{3.5bp}{3.5bp}
+ \pgfusepathqfill
+}
+
+\def\insertskipsymbol{%
+ \begin{pgfpicture}{-1pt}{0pt}{6pt}{5pt}
+ \pgfuseobject{\ifcase\bbl@thepardir beamerskipsymbol\else beamerskipsymbolrl\fi}%
+\end{pgfpicture}}
+
+\def\beamergotobutton#1{\beamerbutton{\insertgotosymbol\ #1}}
+\def\beamerreturnbutton#1{\beamerbutton{\insertreturnsymbol\ #1}}
+\def\beamerskipbutton#1{\beamerbutton{\insertskipsymbol\ #1}}
+
+%% beamerbaseframesize
+
+%
+% Zoom stuff
+%
+
+\def\beamer@framezoom<#1><#2>[#3](#4,#5)(#6,#7){%
+ \par\nointerlineskip%
+ \global\beamer@slidehaszoomtrue%
+ \advance\beamer@zoomcount by1\relax%
+ \def\beamer@zoomborderwidth{0}%
+ \edef\beamer@labelzoomed{beamer@labelzoomed@\the\beamer@zoomframecount @\the\beamer@zoomcount}%
+ \setkeys{beamerzoom}{#3}%
+ \only<#1>{%
+ {\hypersetup{pdfhighlight={/P},pdfborder={0 0 \beamer@zoomborderwidth}}%
+ \global\setbox\@tempboxa=\vbox{\hyperlink{\beamer@labelzoomed}{\vbox to #7{\hbox
+ to#6{\hfil}\vfil}}}}%
+ \ht\@tempboxa=0pt%
+ \wd\@tempboxa=0pt%
+ \dp\@tempboxa=0pt%
+ \setbox\@tempboxa=\vbox{\moveright#4\hbox{\lower#5\vbox{\box\@tempboxa}}}%
+ \ht\@tempboxa=0pt%
+ \wd\@tempboxa=0pt%
+ \dp\@tempboxa=0pt%
+ \global\setbox\beamer@zoombox=\vbox to0pt{\unvbox\beamer@zoombox\box\@tempboxa}%
+ }%
+ \only<#2>{%
+ \pardir TLT%
+ \@ifundefined{\beamer@labelzoomed}%
+ {%
+ \hypertarget{\beamer@labelzoomed}{}%
+ \expandafter\gdef\csname\beamer@labelzoomed\endcsname{}%
+ }{}%
+ \gdef\beamer@zoomer{%
+ % compute zoom factor
+ \@tempdima=\beamer@frametextheight%
+ \@tempdimb=#7\relax%
+ \@tempcnta=\@tempdimb%
+ \divide\@tempcnta by4096\relax%
+ \multiply\@tempdima by16\relax%
+ \divide\@tempdima by\@tempcnta%
+ \@tempdimb=\paperwidth%
+ \ifbeamer@plainframe%
+ \else%
+ \advance\@tempdimb by-\beamer@leftsidebar%
+ \advance\@tempdimb by-\beamer@rightsidebar\relax%
+ \fi%
+ \@tempdimc=#6\relax%
+ \@tempcntb=\@tempdimc%
+ \divide\@tempcntb by4096\relax%
+ \multiply\@tempdimb by16\relax%
+ \divide\@tempdimb by\@tempcntb%
+ \ifdim\@tempdimb<\@tempdima%
+ \@tempdima=\@tempdimb%
+ \fi%
+ \edef\beamer@temp{\strip@pt\@tempdima}%
+ \@tempdimc=\beamer@frametextheight%
+ \advance\@tempdimc by4pt%
+ \@tempdimb=\paperwidth%
+ \ifbeamer@plainframe%
+ \else%
+ \advance\@tempdimb by-\beamer@leftsidebar%
+ \advance\@tempdimb by-\beamer@rightsidebar\relax%
+ \fi%
+ \setbox\@tempboxa=\vbox{\hsize=\@tempdimb\Acrobatmenu{GoBack}{\vbox to
+ \beamer@frametextheight{\hbox to\@tempdimb{\hfil}\vfil}}}%
+ \ht\@tempboxa=0pt%
+ \wd\@tempboxa=0pt%
+ \dp\@tempboxa=0pt%
+ \setbox\beamer@framebox=\vbox to\beamer@frametextheight{{%
+ \ifbeamer@plainframe\beamer@leftmargin=\Gm@lmargin\fi%
+ \pardir TLT%
+ \begin{pgfpicture}{\beamer@leftmargin}{-\beamer@frametextheight}{\beamer@leftmargin}{0pt}
+ \pgftext[left,top]{\box\@tempboxa}
+ \pgfpathrectangle{\pgfpoint{0pt}{-\@tempdimc}}{\pgfpoint{\@tempdimb}{\@tempdimc}}%
+ \pgfusepath{clip}
+ \begingroup
+ \pgftransformscale{\beamer@temp}
+ \@tempdima=#4\relax%
+ \@tempdimb=#5\relax%
+ {\pgftransformshift{\pgfpoint{-\@tempdima}{\@tempdimb}}%
+ \pgftext[left,top]{\vbox{\vbox{}\nointerlineskip\unvbox\beamer@framebox}}}
+ \endgroup
+ \end{pgfpicture}%
+ }}%
+
+ \setbox\beamer@framebox=\vbox{%
+ \nobreak\vbox{}\nobreak\par\nobreak\beamer@entrycode\nobreak%
+ \nointerlineskip\unvbox\beamer@frametitlebox%
+ \nobreak%
+ \box\beamer@framebox %
+ \nobreak%
+ \vss%
+ \beamer@exitcode%
+ }%
+ \global\setbox\beamer@footins=\box\voidb@x% no footnotes in zoomed slides
+ }%
+ }%
+}
+
+\endinput
diff --git a/macros/luatex/latex/bezierplot/README b/macros/luatex/latex/bezierplot/README
new file mode 100644
index 0000000000..493bfe5c65
--- /dev/null
+++ b/macros/luatex/latex/bezierplot/README
@@ -0,0 +1,21 @@
+DESCRIPTION:
+bezierplot is a Lua program as well as a (Lua)LaTeX package.
+Given a smooth function, bezierplot returns a smooth bezier path written
+in TikZ notation (which also matches METAPOST) that approximates the
+graph of the function. For polynomial functions of degree <= 3 and
+inverses of them, the approximation is exact. bezierplot finds special
+points such as extreme points and inflection points and reduces the
+number of used points.
+
+VERSION:
+1.4 2019-06-18
+
+LICENSE:
+The package and the program are distributed on CTAN under the terms of
+the LaTeX Project Public License (LPPL) version 1.3c.
+
+Copyright (c) 2018 Linus Romer
+
+Please write to
+linus dot romer at gmx dot ch
+to submit bug reports, request new features, etc.
diff --git a/macros/luatex/latex/bezierplot/bezierplot-doc.pdf b/macros/luatex/latex/bezierplot/bezierplot-doc.pdf
new file mode 100644
index 0000000000..c93fd5f102
--- /dev/null
+++ b/macros/luatex/latex/bezierplot/bezierplot-doc.pdf
Binary files differ
diff --git a/macros/luatex/latex/bezierplot/bezierplot-doc.tex b/macros/luatex/latex/bezierplot/bezierplot-doc.tex
new file mode 100644
index 0000000000..a1239b6e57
--- /dev/null
+++ b/macros/luatex/latex/bezierplot/bezierplot-doc.tex
@@ -0,0 +1,200 @@
+% !TEX program = pdfLaTeX --shell-escape
+\documentclass[a4paper]{article}
+\usepackage{tikz,multicol,bezierplot,amsmath,cancel}
+\usepackage[margin=3.5cm,top=1.75cm]{geometry}
+\usepackage{fetamont}
+\title{bezierplot}\author{Linus Romer}
+\DeclareDocumentCommand{\graphcomparison}{ m m }{
+ \begin{center}
+ \begin{tikzpicture}[scale=.4]
+ \draw (0,-5) node[below]{\tiny\texttt{\detokenize{#1}\quad | \detokenize{#2}}};
+ \draw[step=1,thin] (-5,-5) grid (5,5);
+ \draw[thick,->] (-5,0) -- (5.5,0) node[below]{$x$};
+ \draw[thick,->] (0,-5) -- (0,5.5) node[left]{$y$};
+ \foreach \x in {-4,-3,-2,-1,1,2,3,4} {\draw (\x,1pt) -- (\x,-1pt) node[below]{\tiny \x};}
+ \foreach \y in {-4,-3,-2,-1,1,2,3,4} {\draw (1pt,\y) -- (-1pt,\y) node[left]{\tiny \y};}
+ \draw[color=red,domain=-5:5,range=-5:5,samples=1000] plot function{#2};
+ \draw \bezierplot{#1};
+ \end{tikzpicture}
+ \end{center}
+}
+\begin{document}
+\maketitle\noindent
+\section{Introduction}
+\texttt{bezierplot} is a Lua program as well as a (Lua)\LaTeX{} package. This document describes both.
+
+Given a smooth function, \texttt{bezierplot} returns a smooth bezier path written in Ti\emph{k}Z notation (which also matches \MP{}) that approximates the graph of the function. For polynomial functions of degree $\leq 3$ and inverses of them, the approximation is exact (up to numeric precision). \texttt{bezierplot} finds special graph points such as extreme points and inflection points and reduces the number of used points.
+
+The following example will show a comparison of \textsc{gnuplot} with \verb|bezierplot| for the function $y=\sqrt{x}$ for $0\leq x \leq 5$:
+\begin{center}
+ \begin{tikzpicture}[scale=1.4]
+ \draw (0,0) .. controls (0,0.7454) and (1.6667,1.4907) .. (5,2.2361);
+ \draw (0,0) circle(.02) -- (0,0.745) circle( .02);
+ \draw (1.6667,1.4907) circle(.02) -- (5,2.2361) circle( .02);
+ \draw (2.5,.5) node[above]{\verb|bezierplot|};
+ \begin{scope}[shift={(5.2,0)}]
+ \draw[domain=0:5,samples=51] plot function{x**0.5};
+ \foreach \x in {0,0.1,...,5.05} {\draw (\x,{\x^0.5}) circle (0.02);}
+ \draw (2.5,.5) node[above]{\textsc{gnuplot}};
+ \end{scope}
+ \end{tikzpicture}
+\end{center}
+\textsc{gnuplot} used 51 samples (no smoothing) and is still quite inexact at the beginning, whereas \verb|bezierplot| uses 4 points only and is exact (up to numeric precision)!
+\section{Installation}
+As \texttt{bezierplot} is written in Lua, the installation depends whether you are using Lua\LaTeX{} or another \LaTeX{} engine.
+\subsection{Installation For Lua\LaTeX{}}
+If you have installed \texttt{bezierplot} by a package manager, the installation is already complete. The manual installation of \texttt{bezierplot} is done in 2 steps:
+\begin{itemize}
+ \item copy the files \texttt{bezierplot.lua} and \texttt{bezierplot.sty} somewhere in your \texttt{texmf} tree (e.g. to \verb|~/texmf/tex/lualatex/bezierplot/bezierplot.sty| and\\
+ \verb|~/texmf/scripts/bezierplot/bezierplot.lua|)
+ \item update the ls-R databases by running \texttt{mktexlsr}
+\end{itemize}
+\subsection{Additional Installation Steps For Other \LaTeX{} Engines}
+You will have to call \texttt{bezierplot} as an external program via the option \texttt{--shell-escape} (\texttt{--write18} for MiK\TeX{}). Therefore, \texttt{bezierplot.lua} has to be copied with the name \texttt{bezierplot} to a place, where your OS can find it. Under Linux this usually means copying to the directory \texttt{/usr/local/bin/}, but for Windows this will probably include more steps (like adding to the \texttt{PATH}). Of course, Lua has to be installed as well. As soon as you can call \texttt{bezierplot} from a command line (e.g. by typing \verb|bezierplot "x^2"|), it should also work with other \LaTeX{} engines.
+\section{Loading}
+The \texttt{bezierplot} package is loaded with \verb|\usepackage{bezierplot}|. There are no loading options for the package.
+\section{Usage}
+\begin{multicols}{2}
+\noindent A minimal example of Lua\LaTeX{} document could be:
+\begin{verbatim}
+\documentclass{article}
+\usepackage{tikz,bezierplot}
+\begin{document}
+\tikz \draw \bezierplot{x^2};
+\end{document}
+\end{verbatim}
+\begin{center}
+ \tikz \draw[scale=.7] \bezierplot{x^2};
+\end{center}
+\end{multicols}
+\noindent
+The command \verb|\bezierplot| has 6 optional arguments in the sense of
+\begin{center}
+ \verb|\bezierplot[XMIN][XMAX][YMIN][YMAX][SAMPLES]{FUNCTION}|
+\end{center}
+The defaults are \verb|XMIN| = \verb|YMIN| $= -5$, \verb|XMAX| = \verb|YMAX| $= 5$ and \verb|SAMPLES| $= 0$ (this will set as few samples as possible).
+\begin{center}
+ \begin{tikzpicture}[scale=.7]
+ \draw \bezierplot[-1][2]{x^2};
+ \draw (0,0) node[below]{\verb|\bezierplot[-1][2]{x^2}|};
+ \begin{scope}[shift={(10,0)}]
+ \draw \bezierplot[-1][2][0.5][3]{x^2};
+ \draw (0,0) node[below]{\verb|\bezierplot[-1][2][0.5][3]{x^2}|};
+ \end{scope}
+ \end{tikzpicture}
+\end{center}
+You may reverse the graph by making \verb|XMIN| bigger than \verb|XMAX|. E.g.
+\begin{verbatim}
+ \bezierplot[-5][5]{0.5*x+1}
+\end{verbatim}
+returns \verb|(-5,-1.5) -- (5,3.5)|, whereas
+\begin{verbatim}
+ \bezierplot[5][-5]{0.5*x+1}
+\end{verbatim}
+returns the reversed path \verb|(5,3.5) -- (-5,-1.5)|. This is useful, if you want to cycle a path to a closed area:
+\begin{multicols}{2}
+\begin{verbatim}
+\begin{tikzpicture}
+ \fill[black!30] \bezierplot[-1][1]{2-x^2}
+ -- \bezierplot[1][-1]{x^3-x} -- cycle;
+ \draw \bezierplot[-1.1][1.1]{2-x^2};
+ \draw \bezierplot[-1.1][1.1]{x^3-x};
+\end{tikzpicture}
+\end{verbatim}
+\begin{center}
+ \begin{tikzpicture}
+ \fill[black!30] \bezierplot[-1][1]{2-x^2} -- \bezierplot[1][-1]{x^3-x} -- cycle;
+ \draw \bezierplot[-1.1][1.1]{2-x^2};
+ \draw \bezierplot[-1.1][1.1]{x^3-x};
+ \end{tikzpicture}
+\end{center}
+\end{multicols}
+\subsection{Running Raw \texttt{bezierplot}}
+Of course, you can run \verb|bezierplot.lua| in a terminal without using \LaTeX{}, e.g.
+\begin{verbatim}
+lua bezierplot.lua "3*x^0.8+2"
+\end{verbatim}
+will return
+\begin{verbatim}
+(0,2) .. controls (0.03,2.282) and (0.268,3.244) .. (1,5)
+\end{verbatim}
+You can set the window of the graph and the number of samples as follows:
+\begin{verbatim}
+lua bezierplot.lua "FUNCTION" XMIN XMAX YMIN YMAX SAMPLES
+\end{verbatim}
+e.g.
+\begin{verbatim}
+lua bezierplot.lua "FUNCTION" 0 1 -3 2.5 201
+\end{verbatim}
+will set $0\leq x\leq 1$ and $-3\leq y\leq 2.5$ and $201$ equidistant samples. You may also omit the $y$--range, hence
+\begin{verbatim}
+lua bezierplot.lua "FUNCTION" 0 1
+\end{verbatim}
+will set $0\leq x\leq 1$ and leave the default $-5\leq y\leq 5$. The variables \verb|XMIN|, \verb|XMAX|, \verb|YMIN| and \verb|YMAX| may also be computable expressions like \verb|2*pi+6|:
+\begin{verbatim}
+lua bezierplot.lua "sin(x)" -pi pi
+\end{verbatim}
+You may use \verb|huge| for $\infty$:
+\begin{verbatim}
+lua bezierplot "1/x" 0 1 0 huge
+\end{verbatim}
+As \verb|huge| is very huge and \verb|bezierplot| uses recursive calls for nontrivial functions and non--fixed samples, this can last very long:
+\begin{verbatim}
+lua bezierplot "1/x" -5 5 -huge huge
+\end{verbatim}
+But if you set fixed samples, it will be fast again (as this does not use recursive calls):
+\begin{verbatim}
+lua bezierplot "1/x" -5 5 -huge huge 100
+\end{verbatim}
+\subsection{Notation Of Functions}
+The function term given to \verb|bezierplot| must contain at most one variable: $x$. E.g. \verb|"2.3*(x-1)^2-3"|. You must not omit \verb|*| operators:
+\begin{center}
+ wrong:\quad $\cancel{\texttt{2x(x+1)}}$ \hfil correct:\quad \texttt{2*x*(x+1)}
+\end{center}
+You have two possibilities to write powers: \verb|"x^2"| and \verb|"x**2"| both mean $x^2$.
+
+\medskip
+
+The following functions and constants are possible:
+\begin{center}
+\begin{tabular}{ll}
+ \verb|abs| & absolute value (remember: your function should still be smooth)\\
+ \verb|acos| & $\cos^{-1}$ inverse function of cosine in radians\\
+ \verb|asin| & $\sin^{-1}$ inverse function of sine in radians\\
+ \verb|atan| & $\tan^{-1}$ inverse function of tangent in radians\\
+ \verb|cbrt| & cube root $\sqrt[3]{\quad}$ that works for negative numbers, too\\
+ \verb|cos| & cosine for angles in radians\\
+ \verb|exp| & the exponential function $e^{(\;)}$\\
+ \verb|huge| & the numerical $\infty$\\
+ \verb|e| & the euler constant $e=\mathrm{exp}(1)$\\
+ \verb|log| & the natural logarithm $\mathrm{log}_e(\;)$\\
+ \verb|pi| & Archimedes’ constant $\pi\approx 3.14$\\
+ \verb|sgn| & sign function\\
+ \verb|sin| & sine for angles in radians\\
+ \verb|sqrt| & square root $\sqrt{\quad}$\\
+ \verb|tan| & tangent for angles in radians
+\end{tabular}
+\end{center}
+%
+\newpage
+%
+\section{Examples of \texttt{bezierplot} in Comparison with \textsc{gnuplot}}
+The following graphs are drawn with \texttt{bezierplot} (black) and \textsc{gnuplot} (red). You may not recognize the red behind the black unless you zoom in. \textsc{gnuplot} used 1000 samples per example. The functions are given below the pictures (left: bezierplot, right: \textsc{gnuplot}).
+\begin{multicols}{3}
+\graphcomparison{0.32*x-0.7}{0.32*x-0.7}
+\graphcomparison{-x^2+4}{-x**2+4}
+\graphcomparison{(x+1)*x*(x-1)}{(x+1)*x*(x-1)}
+\graphcomparison{x^0.5}{x**0.5}
+%\graphcomparison{x^(1/3)}{x**(1/3.)}
+\graphcomparison{cbrt(x)}{sgn(x)*abs(x)**(1/3.)}
+\graphcomparison{x^3*(x-1)}{x**3*(x-1)}
+\graphcomparison{2*cos(3*x+4)+3}{2*cos(3*x+4)+3}
+\graphcomparison{tan(x)}{tan(x)}
+\graphcomparison{x+0.5*sin(x)}{x+0.5*sin(x)}
+%\graphcomparison{1/(x-2)+1}{1/(x-2)+1}
+\graphcomparison{2*x^2/(3*x-3)}{2*x**2/(3*x-3)}
+\graphcomparison{4-exp(x)}{4-exp(x)}
+\graphcomparison{log(x+4)}{log(x+4)}
+\end{multicols}
+
+\end{document}
diff --git a/macros/luatex/latex/bezierplot/bezierplot.lua b/macros/luatex/latex/bezierplot/bezierplot.lua
new file mode 100755
index 0000000000..382da2d74e
--- /dev/null
+++ b/macros/luatex/latex/bezierplot/bezierplot.lua
@@ -0,0 +1,940 @@
+#!/usr/bin/env lua
+-- Linus Romer, published 2018 under LPPL Version 1.3c
+-- version 1.4 2019-06-18
+abs = math.abs
+acos = math.acos
+asin = math.asin
+atan = math.atan
+cos = math.cos
+exp = math.exp
+e = math.exp(1)
+log = math.log
+pi = math.pi
+sin = math.sin
+sqrt = math.sqrt
+tan = math.tan
+huge = math.huge
+
+-- just a helper for debugging:
+local function printdifftable(t)
+ for i = 1,#t do
+ for j = 1, 6 do
+ if j < 5 then
+ io.write(t[i][j].." ")
+ else
+ if t[i][j] then
+ io.write("true ")
+ else
+ io.write("false ")
+ end
+ end
+ end
+ io.write("\n")
+ end
+end
+
+-- cube root defined for all real numbers x
+function cbrt(x)
+ if x < 0 then
+ return -(-x)^(1/3)
+ else
+ return x^(1/3)
+ end
+end
+
+function sgn(x)
+ if x<0 then
+ return -1
+ elseif x>0 then
+ return 1
+ else
+ return 0
+ end
+end
+
+local function round(num, decimals)
+ local result = tonumber(string.format("%." .. (decimals or 0) .. "f", num))
+ if abs(result) == 0 then
+ return 0
+ else
+ return result
+ end
+end
+
+-- check if a point (x,y) satisfies xmin <= x <= xmax and ymin <= < <= ymax
+local function is_in_window(x,y,xmin,xmax,ymin,ymax)
+ if x >= xmin and x <= xmax and y >= ymin and y <= ymax then
+ return true
+ else
+ return false
+ end
+end
+
+local function evaluate(s)
+ local tempfunc = assert(load("return " .. s))
+ return tempfunc()
+end
+
+
+-- 5-stencil method
+-- return from a graph from f in the form {{x,y},...}
+-- the derivatives in form {{x,y,dy/dx,ddy/ddx,extrema,inflection},...}
+local function diffgraph(func,graph,h)
+ local dgraph = {}
+ local l = #graph
+ if l < 4 then -- this is not worth the pain...
+ for i = 1, l do
+ table.insert(dgraph,{graph[i][1],graph[i][2],0,0,false,false})
+ end
+ else
+ local yh = func(graph[1][1]-h)
+ local yhh = func(graph[1][1]-2*h)
+ if yhh > -math.huge and yhh < math.huge -- if defined at all
+ and yh > -math.huge and yh < math.huge then
+ dgraph[1] = {graph[1][1],graph[1][2],
+ (yhh-8*yh+8*graph[2][2]-graph[3][2])/(12*h),
+ (-yhh+16*yh-30*graph[1][2]+16*graph[2][2]-graph[3][2])
+ /(12*h^2)}
+ dgraph[2] = {graph[2][1],graph[2][2],
+ (yh-8*graph[1][2]+8*graph[3][2]-graph[4][2])/(12*h),
+ (-yh+16*graph[1][2]-30*graph[2][2]+16*graph[3][2]-graph[4][2])
+ /(12*h^2)}
+ else -- take neighbour values
+ dgraph[1] = {graph[1][1],graph[1][2],
+ (graph[1][2]-8*graph[2][2]+8*graph[4][2]-graph[5][2])/(12*h),
+ (-graph[1][2]+16*graph[2][2]-30*graph[3][2]
+ +16*graph[4][2]-graph[5][2])/(12*h^2)}
+ dgraph[2] = {graph[2][1],graph[2][2],
+ (graph[1][2]-8*graph[2][2]+8*graph[4][2]-graph[5][2])/(12*h),
+ (-graph[1][2]+16*graph[2][2]-30*graph[3][2]
+ +16*graph[4][2]-graph[5][2])/(12*h^2)}
+ end
+ for i = 3, l-2 do
+ table.insert(dgraph,{graph[i][1],graph[i][2],
+ (graph[i-2][2]-8*graph[i-1][2]+8*graph[i+1][2]-graph[i+2][2])
+ /(12*h),
+ (-graph[i-2][2]+16*graph[i-1][2]-30*graph[i][2]
+ +16*graph[i+1][2]-graph[i+2][2])
+ /(12*h^2)})
+ end
+ yh = func(graph[l][1]+h)
+ yhh = func(graph[l][1]+2*h)
+ if yhh > -math.huge and yhh < math.huge -- if defined at all
+ and yh > -math.huge and yh < math.huge then
+ dgraph[l-1] = {graph[l-1][1],graph[l-1][2],
+ (graph[l-3][2]-8*graph[l-2][2]+8*graph[l][2]-yh)/(12*h),
+ (-graph[l-3][2]+16*graph[l-2][2]-30*graph[l-1][2]
+ +16*graph[l][2]-yh)/(12*h^2)}
+ dgraph[l] = {graph[l][1],graph[l][2],
+ (graph[l-2][2]-8*graph[l-1][2]+8*yh-yhh)/(12*h),
+ (-graph[l-2][2]+16*graph[l-1][2]-30*graph[l][2]
+ +16*yh-yhh)/(12*h^2)}
+ else
+ -- take neighbour values
+ dgraph[l] = {graph[l][1],graph[l][2],
+ (graph[l-4][2]-8*graph[l-3][2]+8*graph[l-1][2]-graph[l][2])
+ /(12*h),
+ (-graph[l-4][2]+16*graph[l-3][2]-30*graph[l-2][2]
+ +16*graph[l-1][2]-graph[l][2])/(12*h^2)}
+ dgraph[l-1] = {graph[l-1][1],graph[l-2][2],
+ (graph[l-4][2]-8*graph[l-3][2]+8*graph[l-1][2]-graph[l][2])
+ /(12*h),
+ (-graph[l-4][2]+16*graph[l-3][2]-30*graph[l-2][2]
+ +16*graph[l-1][2]-graph[l][2])/(12*h^2)}
+ end
+ -- add information about being extremum / inflection point (true/false)
+ for i = 1, l do
+ dgraph[i][5] = false -- dy/dx == 0 ? default, may change later
+ dgraph[i][6] = false -- ddy/ddx == 0 ? default, may change later
+ end
+ for i = 1, l-1 do
+ -- if no gap is inbetween
+ if not (dgraph[i+1][1] - dgraph[i][1] > 1.5*h) then
+ -- check for dy/dx == 0
+ -- if not already determined as near dy/dx=0
+ if dgraph[i][3] == 0 then
+ if dgraph[i+1][3] == 0 then --take the later
+ dgraph[i+1][5] = true
+ dgraph[i][5] = false
+ else
+ dgraph[i][5] = true
+ end
+ elseif abs(dgraph[i][3]*dgraph[i+1][3])
+ ~= dgraph[i][3]*dgraph[i+1][3] then -- this must be near
+ if abs(dgraph[i][4]) <= abs(dgraph[i+1][4]) then
+ dgraph[i][5] = true
+ else
+ dgraph[i+1][5] = true
+ end
+ end
+ -- check for ddy/ddx == 0
+ -- if not already determined as near ddy/ddx=0
+ if (not dgraph[i][6]) and (abs(dgraph[i][4]*dgraph[i+1][4])
+ ~= dgraph[i][4]*dgraph[i+1][4]) then -- this must be near
+ if abs(dgraph[i][4]) <= abs(dgraph[i+1][4]) then
+ dgraph[i][6] = true
+ else
+ dgraph[i+1][6] = true
+ end
+ end
+ end
+ end
+ end
+ return dgraph
+end
+
+-- simplified diffgraph function, the function is derived only once
+-- return from a graph from f in the form {{x,y},...}
+-- the derivatives in form {{x,y,dy/dx},...}
+-- we start with index 1 and then always jump indexjump to the next
+-- index
+local function diffgraphsimple(func,graph,h,indexjump)
+ local dgraph = {}
+ local l = math.floor((#graph-1)/indexjump)*indexjump+1
+ if l < 2 then -- this is not worth the pain...
+ dgraph = {graph[1][1],graph[1][2],0}
+ else
+ local yh = func(graph[1][1]-h)
+ local yhh = func(graph[1][1]-2*h)
+ if yhh > -math.huge and yhh < math.huge -- if defined at all
+ and yh > -math.huge and yh < math.huge then
+ dgraph[1] = {graph[1][1],graph[1][2],
+ (yhh-8*yh+8*graph[2][2]-graph[3][2])/(12*h)}
+ else -- take neighbour values
+ dgraph[1] = {graph[1][1],graph[1][2],
+ (graph[1][2]-8*graph[2][2]+8*graph[4][2]-graph[5][2])
+ /(12*h)}
+ end
+ for i = 1+indexjump, l-1, indexjump do
+ table.insert(dgraph,{graph[i][1],graph[i][2],
+ (graph[i-2][2]-8*graph[i-1][2]+8*graph[i+1][2]-graph[i+2][2])
+ /(12*h)})
+ end
+ yh = func(graph[l][1]+h)
+ yhh = func(graph[l][1]+2*h)
+ if yhh > -math.huge and yhh < math.huge -- if defined at all
+ and yh > -math.huge and yh < math.huge then
+
+ table.insert(dgraph,{graph[l][1],graph[l][2],
+ (graph[l-2][2]-8*graph[l-1][2]+8*yh-yhh)/(12*h)})
+ else
+ -- take neighbour values
+ table.insert(dgraph,{graph[l][1],graph[l][2],
+ (graph[l-4][2]-8*graph[l-3][2]+8*graph[l-1][2]-graph[l][2])
+ /(12*h)})
+ end
+ end
+ return dgraph
+end
+
+-- diffgraph for cubic function ax^3+bx^2+cx+d
+-- returns the derivatives in form {{x,y,dy/dx,ddy/ddx},...}
+-- if isinverse = true then the coordinates will be inversed
+local function diffgraphcubic(graph,a,b,c,d,isinverse)
+ local dgraph = {}
+ local l = #graph
+ for i = 1, l do
+ if isinverse then
+ dgraph[#dgraph+1] = {graph[i][2],graph[i][1],c
+ +graph[i][2]*(2*b+3*a*graph[i][2]),6*a*graph[i][2]+2*b}
+ else
+ dgraph[#dgraph+1] = {graph[i][1],graph[i][2],c
+ +graph[i][1]*(2*b+3*a*graph[i][1]),6*a*graph[i][1]+2*b}
+ end
+ end
+ return dgraph
+end
+
+-- checks for 100 x, if the function given by funcstring
+-- fits the graph g (up to maxerror) after filling in
+-- the parameters a, b, c, d
+-- if the graph is inverted, then isinverse has to be set true
+local function do_parameters_fit(a,b,c,d,funcstring,funcgraph,maxerror,isinverse)
+ if not (a > -math.huge and a < math.huge and b > -math.huge and b < math.huge and
+ c > -math.huge and c < math.huge and d > -math.huge and d < math.huge) then
+ return false
+ end
+ local funcx = string.gsub(funcstring, "a", a)
+ local funcx = string.gsub(funcx, "b", b)
+ local funcx = string.gsub(funcx, "c", c)
+ local funcx = string.gsub(funcx, "d", d)
+ local func = assert(load("local x = ...; return "..funcx))
+ for i = 1, #funcgraph, math.max(1,math.floor(0.01*#funcgraph)) do
+ if isinverse then
+ if abs(func(funcgraph[i][2])-funcgraph[i][1])
+ > maxerror then
+ return false
+ end
+ else
+ if abs(func(funcgraph[i][1])-funcgraph[i][2])
+ > maxerror then
+ return false
+ end
+ end
+ end
+ return true
+end
+
+-- f(x)=a*x^3+b*x+c
+local function parameters_cubic(xp,yp,xq,yq,xr,yr,xs,ys)
+ local a = (((xp^2 * xq) * yr) - ((xp^2 * xq) * ys)
+ - ((xp^2 * xr) * yq) + ((xp^2 * xr) * ys) + ((xp^2 * xs) * yq)
+ - ((xp^2 * xs) * yr) - ((xp * xq^2) * yr) + ((xp * xq^2) * ys)
+ + ((xp * xr^2) * yq) - ((xp * xr^2) * ys) - ((xp * xs^2) * yq)
+ + ((xp * xs^2) * yr) + ((xq^2 * xr) * yp) - ((xq^2 * xr) * ys)
+ - ((xq^2 * xs) * yp) + ((xq^2 * xs) * yr) - ((xq * xr^2) * yp)
+ + ((xq * xr^2) * ys) + ((xq * xs^2) * yp) - ((xq * xs^2) * yr)
+ + ((xr^2 * xs) * yp) - ((xr^2 * xs) * yq) - ((xr * xs^2) * yp)
+ + ((xr * xs^2) * yq)) /
+ (((xp^3 * xq^2) * xr) - ((xp^3 * xq^2) * xs)
+ - ((xp^3 * xq) * xr^2) + ((xp^3 * xq) * xs^2)
+ + ((xp^3 * xr^2) * xs) - ((xp^3 * xr) * xs^2)
+ - ((xp^2 * xq^3) * xr) + ((xp^2 * xq^3) * xs)
+ + ((xp^2 * xq) * xr^3) - ((xp^2 * xq) * xs^3)
+ - ((xp^2 * xr^3) * xs) + ((xp^2 * xr) * xs^3)
+ + ((xp * xq^3) * xr^2) - ((xp * xq^3) * xs^2)
+ - ((xp * xq^2) * xr^3) + ((xp * xq^2) * xs^3)
+ + ((xp * xr^3) * xs^2) - ((xp * xr^2) * xs^3)
+ - ((xq^3 * xr^2) * xs) + ((xq^3 * xr) * xs^2)
+ + ((xq^2 * xr^3) * xs) - ((xq^2 * xr) * xs^3)
+ - ((xq * xr^3) * xs^2) + ((xq * xr^2) * xs^3))
+ local b = ((((-xp^3) * xq) * yr) + ((xp^3 * xq) * ys)
+ + ((xp^3 * xr) * yq) - ((xp^3 * xr) * ys) - ((xp^3 * xs) * yq)
+ + ((xp^3 * xs) * yr) + ((xp * xq^3) * yr) - ((xp * xq^3) * ys)
+ - ((xp * xr^3) * yq) + ((xp * xr^3) * ys) + ((xp * xs^3) * yq)
+ - ((xp * xs^3) * yr) - ((xq^3 * xr) * yp) + ((xq^3 * xr) * ys)
+ + ((xq^3 * xs) * yp) - ((xq^3 * xs) * yr) + ((xq * xr^3) * yp)
+ - ((xq * xr^3) * ys) - ((xq * xs^3) * yp) + ((xq * xs^3) * yr)
+ - ((xr^3 * xs) * yp) + ((xr^3 * xs) * yq) + ((xr * xs^3) * yp)
+ - ((xr * xs^3) * yq)) /
+ (((xp^3 * xq^2) * xr) - ((xp^3 * xq^2) * xs)
+ - ((xp^3 * xq) * xr^2) + ((xp^3 * xq) * xs^2)
+ + ((xp^3 * xr^2) * xs) - ((xp^3 * xr) * xs^2)
+ - ((xp^2 * xq^3) * xr) + ((xp^2 * xq^3) * xs)
+ + ((xp^2 * xq) * xr^3) - ((xp^2 * xq) * xs^3)
+ - ((xp^2 * xr^3) * xs) + ((xp^2 * xr) * xs^3)
+ + ((xp * xq^3) * xr^2) - ((xp * xq^3) * xs^2)
+ - ((xp * xq^2) * xr^3) + ((xp * xq^2) * xs^3)
+ + ((xp * xr^3) * xs^2) - ((xp * xr^2) * xs^3)
+ - ((xq^3 * xr^2) * xs) + ((xq^3 * xr) * xs^2)
+ + ((xq^2 * xr^3) * xs) - ((xq^2 * xr) * xs^3)
+ - ((xq * xr^3) * xs^2) + ((xq * xr^2) * xs^3))
+ local c = (((xp^3 * xq^2) * yr) - ((xp^3 * xq^2) * ys)
+ - ((xp^3 * xr^2) * yq) + ((xp^3 * xr^2) * ys)
+ + ((xp^3 * xs^2) * yq) - ((xp^3 * xs^2) * yr)
+ - ((xp^2 * xq^3) * yr) + ((xp^2 * xq^3) * ys)
+ + ((xp^2 * xr^3) * yq) - ((xp^2 * xr^3) * ys)
+ - ((xp^2 * xs^3) * yq) + ((xp^2 * xs^3) * yr)
+ + ((xq^3 * xr^2) * yp) - ((xq^3 * xr^2) * ys)
+ - ((xq^3 * xs^2) * yp) + ((xq^3 * xs^2) * yr)
+ - ((xq^2 * xr^3) * yp) + ((xq^2 * xr^3) * ys)
+ + ((xq^2 * xs^3) * yp) - ((xq^2 * xs^3) * yr)
+ + ((xr^3 * xs^2) * yp) - ((xr^3 * xs^2) * yq)
+ - ((xr^2 * xs^3) * yp) + ((xr^2 * xs^3) * yq)) /
+ (((xp^3 * xq^2) * xr) - ((xp^3 * xq^2) * xs)
+ - ((xp^3 * xq) * xr^2) + ((xp^3 * xq) * xs^2)
+ + ((xp^3 * xr^2) * xs) - ((xp^3 * xr) * xs^2)
+ - ((xp^2 * xq^3) * xr) + ((xp^2 * xq^3) * xs)
+ + ((xp^2 * xq) * xr^3) - ((xp^2 * xq) * xs^3)
+ - ((xp^2 * xr^3) * xs) + ((xp^2 * xr) * xs^3)
+ + ((xp * xq^3) * xr^2) - ((xp * xq^3) * xs^2)
+ - ((xp * xq^2) * xr^3) + ((xp * xq^2) * xs^3)
+ + ((xp * xr^3) * xs^2) - ((xp * xr^2) * xs^3)
+ - ((xq^3 * xr^2) * xs) + ((xq^3 * xr) * xs^2)
+ + ((xq^2 * xr^3) * xs) - ((xq^2 * xr) * xs^3)
+ - ((xq * xr^3) * xs^2) + ((xq * xr^2) * xs^3))
+ local d = ((((xp^(3) * xq^(2)) * xr) * ys)
+ - (((xp^(3) * xq^(2)) * xs) * yr) - (((xp^(3) * xq) * xr^(2)) * ys)
+ + (((xp^(3) * xq) * xs^(2)) * yr) + (((xp^(3) * xr^(2)) * xs) * yq)
+ - (((xp^(3) * xr) * xs^(2)) * yq) - (((xp^(2) * xq^(3)) * xr) * ys)
+ + (((xp^(2) * xq^(3)) * xs) * yr) + (((xp^(2) * xq) * xr^(3)) * ys)
+ - (((xp^(2) * xq) * xs^(3)) * yr) - (((xp^(2) * xr^(3)) * xs) * yq)
+ + (((xp^(2) * xr) * xs^(3)) * yq) + (((xp * xq^(3)) * xr^(2)) * ys)
+ - (((xp * xq^(3)) * xs^(2)) * yr) - (((xp * xq^(2)) * xr^(3)) * ys)
+ + (((xp * xq^(2)) * xs^(3)) * yr) + (((xp * xr^(3)) * xs^(2)) * yq)
+ - (((xp * xr^(2)) * xs^(3)) * yq) - (((xq^(3) * xr^(2)) * xs) * yp)
+ + (((xq^(3) * xr) * xs^(2)) * yp) + (((xq^(2) * xr^(3)) * xs) * yp)
+ - (((xq^(2) * xr) * xs^(3)) * yp) - (((xq * xr^(3)) * xs^(2)) * yp)
+ + (((xq * xr^(2)) * xs^(3)) * yp)) /
+ (((xp^(3) * xq^(2)) * xr) -
+ ((xp^(3) * xq^(2)) * xs) - ((xp^(3) * xq) * xr^(2))
+ + ((xp^(3) * xq) * xs^(2)) + ((xp^(3) * xr^(2)) * xs)
+ - ((xp^(3) * xr) * xs^(2)) - ((xp^(2) * xq^(3)) * xr)
+ + ((xp^(2) * xq^(3)) * xs) + ((xp^(2) * xq) * xr^(3))
+ - ((xp^(2) * xq) * xs^(3)) - ((xp^(2) * xr^(3)) * xs)
+ + ((xp^(2) * xr) * xs^(3)) + ((xp * xq^(3)) * xr^(2))
+ - ((xp * xq^(3)) * xs^(2)) - ((xp * xq^(2)) * xr^(3))
+ + ((xp * xq^(2)) * xs^(3)) + ((xp * xr^(3)) * xs^(2))
+ - ((xp * xr^(2)) * xs^(3)) - ((xq^(3) * xr^(2)) * xs)
+ + ((xq^(3) * xr) * xs^(2)) + ((xq^(2) * xr^(3)) * xs)
+ - ((xq^(2) * xr) * xs^(3)) - ((xq * xr^(3)) * xs^(2))
+ + ((xq * xr^(2)) * xs^(3)))
+ return a, b, c, d
+end
+
+-- f(x)=a*x+b
+local function parameters_affine(xp,yp,xq,yq)
+ local a = (yp - yq) / (xp - xq)
+ local b = ((xp * yq) - (xq * yp)) / (xp - xq)
+ return a, b
+end
+
+-- what is the sum of the squared error
+-- when comparing the bezier path
+-- p.. control q and r .. s
+-- with the graph g from index starti to endi
+-- (looking at the points at roughly t=.33 and t=.67)
+local function squareerror(f,g,starti,endi,qx,qy,rx,ry)
+ local result = 0
+ for t = .1, .9, .1 do
+ x = (1-t)^3*g[starti][1]+3*t*(1-t)^2*qx+3*t^2*(1-t)*rx+t^3*g[endi][1]
+ y = (1-t)^3*g[starti][2]+3*t*(1-t)^2*qy+3*t^2*(1-t)*ry+t^3*g[endi][2]
+ result = result + (y-f(x))^2
+ end
+ return result
+end
+
+-- converts a table with bezier point information
+-- to a string with rounded values
+-- the path is reversed, if rev is true
+-- e.g. if bezierpoints = {{0,1},{2,3,4,5,6,7},{8,9,10,11,12,13}}
+-- then
+-- (0,1) .. controls (2,3) and (4,5) .. (6,7) .. controls
+-- (8,9) and (10,11) .. (12,13)
+-- will be returned
+-- the notation "pgfplots" will change the notation to
+-- YES: \addplot coordinates {(0,1) (6,7) (2,3) (4,5) (6,7) (12,13) (8,9) (10,11)}
+-- NO: 0 1 \\ 6 7 \\ 2 3 \\ 4 5 \\ \\ 6 7 \\ 12 13 \\ 8 9 \\ 10 11 \\
+-- As pgfplots does not connect the bezier segments
+-- reverse paths are not implemented
+local function beziertabletostring(bezierpoints,rndx,rndy,rev,notation)
+ local bezierstring = ""
+ local b = {{round(bezierpoints[1][1],rndx),round(bezierpoints[1][2],rndy)}} -- rounded and then
+ -- reduced points (if identical after rounding)
+ -- rounding
+ for i = 2, #bezierpoints do
+ -- check if x--coordinates are identical
+ if round(bezierpoints[i][#bezierpoints[i]-1],rndx) ~= b[#b][#b[#b]-1] then
+ b[#b+1] = {}
+ for j = 1, #bezierpoints[i] do
+ if j % 2 == 0 then -- x coordinate
+ b[#b][j] = round(bezierpoints[i][j],rndx)
+ else
+ b[#b][j] = round(bezierpoints[i][j],rndy)
+ end
+ end
+ end
+ end
+ if #b > 1 then -- if not empty or single point
+ -- check if bezierstring contains only straight lines
+ local onlystraightlines = true
+ for i = 1, #b do
+ if #b[i] > 2 then
+ onlystraightlines = false
+ break
+ end
+ end
+ if onlystraightlines then
+ if rev then
+ bezierstring = "(" .. b[#b][1] .. "," .. b[#b][2] ..")"
+ for i = #b-1, 1, -1 do
+ bezierstring = bezierstring ..
+ " -- (" .. b[i][1] .. "," .. b[i][2] ..")"
+ end
+ else
+ if notation == "pgfplots" then
+ bezierstring = "\\addplot coordinates {("
+ .. b[1][1] .. "," .. b[1][2] .. ") ("
+ .. b[2][1] .. "," .. b[2][2] .. ") ("
+ .. b[1][1] .. "," .. b[1][2] .. ") ("
+ .. b[2][1] .. "," .. b[2][2] .. ") }"
+ else -- notation = tikz
+ bezierstring = "(" .. b[1][1] .. "," .. b[1][2] ..")"
+ for i = 2, #b do
+ bezierstring = bezierstring ..
+ " -- (" .. b[i][1] .. "," .. b[i][2] ..")"
+ end
+ end
+ end
+ else
+ if rev then
+ bezierstring = "(" .. b[#b][#b[#b]-1] .. ","
+ .. b[#b][#b[#b]] ..")" -- initial point
+ for i = #b, 2, -1 do
+ if #b[i] >= 6 then -- cubic bezier spline
+ bezierstring = bezierstring .. " .. controls ("
+ .. b[i][3] .. "," .. b[i][4] ..") and ("
+ .. b[i][1] .. "," .. b[i][2] .. ") .. ("
+ .. b[i-1][#b[i-1]-1] .. "," .. b[i-1][#b[i-1]]..")"
+ else
+ bezierstring = bezierstring .. " ("
+ .. b[i-1][#b[i-1]-1] .. "," .. b[i-1][#b[i-1]] ..")"
+ end
+ end
+ else
+ if notation == "pgfplots" then
+ bezierstring = "\\addplot coordinates {"
+ for i = 1, #b-1 do
+ if #b[i+1] >= 6 then -- cubic bezier spline
+ bezierstring = bezierstring .. "("
+ .. b[i][#b[i]-1] .. "," .. b[i][#b[i]] .. ") ("
+ .. b[i+1][5] .. "," .. b[i+1][6] .. ") ("
+ .. b[i+1][1] .. "," .. b[i+1][2] .. ") ("
+ .. b[i+1][3] .. "," .. b[i+1][4] .. ") "
+ end
+ end
+ bezierstring = bezierstring .. "}"
+ else -- notation = tikz
+ bezierstring = "(" .. b[1][1] .. ","
+ .. b[1][2] ..")" -- initial point
+ for i = 2, #b do
+ if #b[i] >= 6 then -- cubic bezier spline
+ bezierstring = bezierstring .. " .. controls ("
+ .. b[i][1] .. "," .. b[i][2] ..") and ("
+ .. b[i][3] .. "," .. b[i][4] .. ") .. ("
+ .. b[i][5] .. "," .. b[i][6]..")"
+ else
+ bezierstring = bezierstring .. " ("
+ .. b[i][1] .. "," .. b[i][2] ..")"
+ end
+ end
+ end
+ end
+ end
+ end
+ return bezierstring
+end
+
+-- take end points of a graph g of the function f
+-- (from indices starti to endi)
+-- without extrema or inflection points inbetween
+-- and try to approximate it with a cubic bezier curve
+-- (round to rndx and rndy when printing)
+-- if maxerror <= 0, the function will not be recursive anymore
+local function graphtobezierapprox(f,g,starti,endi,maxerror)
+ local px = g[starti][1]
+ local py = g[starti][2]
+ local dp = g[starti][3]
+ local sx = g[endi][1]
+ local sy = g[endi][2]
+ local ds = g[endi][3]
+ -- we compute the corner point c, where the controls would meet
+ local cx = ((dp * px) - (ds * sx) - py + sy) / (dp - ds)
+ local cy = (dp * ((ds * px) - (ds * sx) - py + sy) / (dp - ds)) + py
+ -- now we slide q between p and c & r between s and c
+ -- and search for the best qx and best rx
+ local qx = px+.01*(cx-px)
+ local qy = py+.01*(cy-py)
+ local rx = sx+.01*(cx-sx)
+ local ry = sy+.01*(cy-sy)
+ local err = squareerror(f,g,starti,endi,qx,qy,rx,ry)
+ for i = 2, 99 do
+ for j = 2, 99 do
+ xa = px+i*.01*(cx-px)
+ ya = py+i*.01*(cy-py)
+ xb = sx+j*.01*(cx-sx)
+ yb = sy+j*.01*(cy-sy)
+ -- now check, if xa and xb fit better
+ -- than the last qx and rx did
+ -- (sum of squares must be smaller)
+ local newerror = squareerror(f,g,starti,endi,xa,ya,xb,yb)
+ if newerror < err then
+ qx = xa
+ qy = ya
+ rx = xb
+ ry = yb
+ err = newerror
+ end
+ end
+ end
+ if maxerror > 0 then
+ -- check if it is close enough: (recycling err, xa, ya)
+ err = 0
+ for t = .1, .9, .1 do
+ xa = (1-t)^3*g[starti][1]+3*t*(1-t)^2*qx+3*t^2*(1-t)*rx+t^3*g[endi][1]
+ ya = (1-t)^3*g[starti][2]+3*t*(1-t)^2*qy+3*t^2*(1-t)*ry+t^3*g[endi][2]
+ if abs(ya-f(xa)) > err then
+ err = abs(ya-f(xa))
+ err = abs(ya-f(xa))
+ end
+ end
+ if (err <= maxerror)
+ and qx > -math.huge and qx < math.huge
+ and qy > -math.huge and qy < math.huge
+ and rx > -math.huge and ry < math.huge
+ and sx > -math.huge and sy < math.huge
+ then
+ return {qx,qy,rx,ry,sx,sy}
+ else
+ -- search for an intermediate point where the graph has the same
+ -- slope as the line from the start point to the end point:
+ local interindex = math.floor(.5*starti+.5*endi) -- will change
+ for i = starti + 1, endi - 1 do
+ if abs(g[i][3]-(g[endi][2]-g[starti][2])
+ /(g[endi][1]-g[starti][1]))
+ < abs(g[interindex][3]-(g[endi][2]-g[starti][2])
+ /(g[endi][1]-g[starti][1])) then
+ interindex = i
+ end
+ end
+ local left = graphtobezierapprox(f,g,starti,interindex,maxerror)
+ local right = graphtobezierapprox(f,g,interindex,endi,maxerror)
+ for i=1, #right do --now append the right to the left:
+ left[#left+1] = right[i]
+ end
+ return left
+ end
+ elseif qx > -math.huge and qx < math.huge
+ and qy > -math.huge and qy < math.huge
+ and rx > -math.huge and ry < math.huge
+ and sx > -math.huge and sy < math.huge
+ then
+ return {qx,qy,rx,ry,sx,sy}
+ end
+end
+
+-- like above but exact for quadratic and cubic (if not inverse)
+-- resp. exact for squareroot and cuberoot (if inverse)
+local function graphtobezier(g,starti,endi,isinverse)
+ local px = g[starti][1]
+ local py = g[starti][2]
+ local dp = g[starti][3]
+ local sx = g[endi][1]
+ local sy = g[endi][2]
+ local ds = g[endi][3]
+ local qx = px+(sx-px)/3
+ local rx = px+2*(sx-px)/3
+ local qy = py+(qx-px)*dp
+ local ry = sy+(rx-sx)*ds
+ if isinverse then
+ return {qy,qx,ry,rx,sy,sx}
+ else
+ return {qx,qy,rx,ry,sx,sy}
+ end
+end
+
+-- main function
+function bezierplot(functionstring,xminstring,xmaxstring,yminstring,ymaxstring,samplesstring,notation)
+ local fstringreplaced = string.gsub(functionstring, "%*%*", "^")
+ local f = assert(load("local x = ...; return " .. fstringreplaced))
+ local xmin = evaluate(xminstring)
+ local xmax = evaluate(xmaxstring)
+ local ymin = evaluate(yminstring)
+ local ymax = evaluate(ymaxstring)
+ local samples = evaluate(samplesstring)
+ local isreverse = false
+ if xmin > xmax then
+ isreverse = true
+ elseif xmin == xmax then
+ xmax = xmin + 10
+ end
+ xmin, xmax = math.min(xmin,xmax), math.max(xmin,xmax)
+ if ymin == ymax then
+ ymax = ymin + 10
+ end
+ ymin, ymax = math.min(ymin,ymax), math.max(ymin,ymax)
+ local xsteps = 50000
+ -- if samples < 2 the samples will be chosen as wisely as possible
+ local arbitrary_samples = true
+ if samples >= 2 then
+ arbitrary_samples = false
+ xsteps = (samples-1)*math.max(2,math.floor(xsteps/(samples-1)))
+ end
+ local xstep = (xmax-xmin)/xsteps
+ -- the output of the x coordinates will be rounded to rndx digits
+ local rndx = math.max(0,math.floor(5.5-log(xmax-xmin)/log(10)))
+ local xerror = abs(xmax-xmin)/(10^rndx)
+ -- the output of the y coordinates will be rounded to rndy digits
+ local rndy = math.max(0,math.floor(5.5-log(ymax-ymin)/log(10)))
+ local yerror = (ymax-ymin)/(10^rndy)
+ -- determine parts of the graph that are inside window
+ local graphs = {} -- graph split to the connected parts
+ local graph = {} -- graphs concatenated (needed for function type)
+ local outside = true -- value is outside window
+ local i = 0
+ local j = 0
+ local yminreal -- determine the real minimimum of the y coord.
+ local ymaxreal -- just decring
+ local yminrealfound = false
+ local ymaxrealfound = false
+ for n = 0, xsteps do
+ local x = xmin + n/xsteps*(xmax-xmin)
+ if n == xsteps then
+ x = xmax
+ end
+ local y = f(x)
+ if (y >= ymin-.1*yerror and ymin ~= -huge or y > ymin and ymin == -huge)
+ and (y <= ymax+.1*yerror and ymax ~= huge or y < ymax and ymax == huge)
+ then -- inside
+ if outside then -- if it was outside before
+ outside = false
+ j = 0
+ i = i + 1
+ graphs[i] = {}
+ end
+ j = j + 1
+ graphs[i][j] = {x,y}
+ graph[#graph+1] = {x,y}
+ if not yminrealfound or yminrealfound and y < yminreal then
+ yminreal = y
+ yminrealfound = true
+ end
+ if not ymaxrealfound or ymaxrealfound and y > ymaxreal then
+ ymaxreal = y
+ ymaxrealfound = true
+ end
+ else
+ outside = true
+ end
+ end
+
+ -- some redefinitions
+ if #graph ~= 0 and yminreal ~= ymaxreal then
+ ymin = yminreal
+ ymax = ymaxreal
+ rndy = math.max(0,math.floor(5.5-log(ymax-ymin)/log(10)))
+ yerror = (ymax-ymin)/(10^rndy)
+ end
+
+ -- check for the function type (for this, we need the concatenated
+ -- parts of the graph)
+ -- go through the connected parts
+ local functiontype = "unknown"
+ local a, b, c, d -- possible function parameter
+ -- check for affine functions:
+ local l = #graph
+ a, b = parameters_affine(graph[1][1],graph[1][2],
+ graph[l][1],graph[l][2])
+ if do_parameters_fit(a,b,0,0,"a*x+b",graph,yerror,false) then
+ functiontype = "affine"
+ else -- check for cubic functions (includes quadratic functions)
+ a, b, c, d = parameters_cubic(graph[1][1],graph[1][2],
+ graph[math.floor(l/3)][1],graph[math.floor(l/3)][2],
+ graph[math.floor(2*l/3)][1],graph[math.floor(2*l/3)][2],
+ graph[l][1],graph[l][2])
+ if do_parameters_fit(a,b,c,d,"a*x^3+b*x^2+c*x+d",graph,
+ yerror,false) then
+ functiontype = "cubic"
+ else -- check for cuberoot functions (includes squareroots)
+ a, b, c, d = parameters_cubic(graph[1][2],graph[1][1],
+ graph[math.floor(l/3)][2],graph[math.floor(l/3)][1],
+ graph[math.floor(2*l/3)][2],graph[math.floor(2*l/3)][1],
+ graph[l][2],graph[l][1])
+ if do_parameters_fit(a,b,c,d,"a*x^3+b*x^2+c*x+d",graph,
+ xerror,true) then
+ functiontype = "cuberoot"
+ end
+ end
+ end
+
+ local bezierpoints = {}
+ -- the bezier path (0,1) .. controls
+ -- (2,3) and (4,5) .. (6,7) .. controls
+ -- (8,9) and (10,11) .. (12,13)
+ -- will be stored as
+ -- bezierpoints={{0,1},{2,3,4,5,6,7},{8,9,10,11,12,13}}
+
+ if functiontype == "affine" then
+ if arbitrary_samples then
+ bezierpoints = {{graph[1][1],graph[1][2]},{graph[#graph][1],
+ graph[#graph][2]}}
+ else -- we can here savely assume that graphs has only one part,
+ -- therefore graphs[1]=graph
+ for i = 1, #graph, math.floor(xsteps/(samples-1)) do
+ bezierpoints[#bezierpoints+1] = {graph[i][1],graph[i][2]}
+ end
+ end
+ elseif functiontype == "cubic" then
+ local extrema_inflections = {} -- store the extrema and
+ -- inflection points for arbitrary samples
+ if arbitrary_samples then
+ if math.abs(a) < yerror*1e-10 then -- quadratic case (one extremum)
+ if is_in_window(-c/(2*b),(-c^2+4*b*d)/(4*b),xmin,xmax,
+ ymin,ymax) then
+ extrema_inflections = {{-c/(2*b),(-c^2+4*b*d)/(4*b)}}
+ end
+ else -- cubic case (two extrema and one inflection point)
+ -- we order the points with the help of sgn
+ -- check for first extrema
+ if is_in_window((-sgn(a)*sqrt(-3*a*c+b^2)-b)/(3*a),
+ (2*b^3+27*a^2*d-9*a*b*c+sqrt(b^2-3*a*c)*sgn(a)*
+ (2*b^2-6*a*c))/(27*a^2),xmin,xmax,ymin,ymax) then
+ extrema_inflections[#extrema_inflections+1] =
+ {(-sgn(a)*sqrt(-3*a*c+b^2)-b)/(3*a),(2*b^3+27*a^2*d-
+ 9*a*b*c+sqrt(b^2-3*a*c)*sgn(a)*(2*b^2-6*a*c))/(27*a^2)}
+ end
+ -- check for inflection point (has to be inbetween)
+ if is_in_window(-b/(3*a),(2*b^3+27*a^2*d-9*a*b*c)
+ /(27*a^2),xmin,xmax,ymin,ymax) then
+ extrema_inflections[#extrema_inflections+1]={-b/(3*a),
+ (2*b^3+27*a^2*d-9*a*b*c)/(27*a^2)}
+ end
+ -- check for second extrema
+ if is_in_window((sgn(a)*sqrt(-3*a*c+b^2)-b)/(3*a),
+ (2*b^3+27*a^2*d-9*a*b*c+sqrt(b^2-3*a*c)*sgn(a)*
+ (-2*b^2+6*a*c))/(27*a^2),xmin,xmax,ymin,ymax) then
+ extrema_inflections[#extrema_inflections+1] =
+ {(sgn(a)*sqrt(-3*a*c+b^2)-b)/(3*a),(2*b^3+27*a^2*d-
+ 9*a*b*c+sqrt(b^2-3*a*c)*sgn(a)*(-2*b^2+6*a*c))/(27*a^2)}
+ end
+ end
+ end
+ for part = 1, #graphs do
+ bezierpoints[#bezierpoints+1] = {graphs[part][1][1],
+ graphs[part][1][2]} -- initial points
+ local graphsamples = {}-- will be the graph reduced to the
+ -- samples (or the most important points)
+ local dg -- will be the differentiated graph
+ if arbitrary_samples then -- add extrema and inflection
+ -- points to the border points
+ graphsamples = {{graphs[part][1][1],
+ graphs[part][1][2]}}
+ for j = 1, #extrema_inflections do
+ if extrema_inflections[j][1] > math.min(
+ graphs[part][1][1] ,graphs[part][#graphs[part]][1])
+ and extrema_inflections[j][1] < math.max(
+ graphs[part][1][1] ,graphs[part][#graphs[part]][1])
+ then
+ graphsamples[#graphsamples+1] =
+ {extrema_inflections[j][1],
+ extrema_inflections[j][2]}
+ end
+ end
+ graphsamples[#graphsamples+1] =
+ {graphs[part][#graphs[part]][1],
+ graphs[part][#graphs[part]][2]}
+ else
+ for i = 1, #graphs[part], xsteps/(samples-1) do
+ graphsamples[#graphsamples+1] =
+ {graphs[part][i][1],graphs[part][i][2]}
+ end
+ end
+ dg = diffgraphcubic(graphsamples,a,b,c,d,false)
+ for i = 2, #dg do
+ bezierpoints[#bezierpoints+1] = graphtobezier(dg,i-1,i,false)
+ end
+ end
+ elseif functiontype == "cuberoot" then
+ local inflection = {} -- store the inflection point
+ if arbitrary_samples and math.abs(a) ~= 0
+ and is_in_window((2*b^3+27*a^2*d-9*a*b*c)/(27*a^2),-b/(3*a),
+ xmin,xmax,ymin,ymax) then
+ inflection = {(2*b^3+27*a^2*d-9*a*b*c)/(27*a^2),-b/(3*a)}
+ end
+ -- (there cannot be more than one part)
+ bezierpoints[#bezierpoints+1] = {graphs[1][1][1],
+ graphs[1][1][2]} -- initial points
+ local graphsamples = {}-- will be the graph reduced to the
+ -- samples (or the most important points)
+ local dg -- will be the differentiated graph
+ if arbitrary_samples then -- add inflection point (if exis.)
+ graphsamples = {{graphs[1][1][1],
+ graphs[1][1][2]}}
+ if #inflection > 0 and inflection[1] > math.min(
+ graphs[1][1][1],graphs[1][#graphs[1]][1])
+ and inflection[1] < math.max(
+ graphs[1][1][1],graphs[1][#graphs[1]][1])
+ then
+ graphsamples[#graphsamples+1] =
+ {inflection[1],inflection[2]}
+ end
+ graphsamples[#graphsamples+1] =
+ {graphs[1][#graphs[1]][1],
+ graphs[1][#graphs[1]][2]}
+ else
+ for i = 1, #graphs[1], xsteps/(samples-1) do
+ graphsamples[#graphsamples+1] =
+ {graphs[1][i][1],graphs[1][i][2]}
+ end
+ end
+ dg = diffgraphcubic(graphsamples,a,b,c,d,true)
+ for i = 2, #dg do
+ bezierpoints[#bezierpoints+1] = graphtobezier(dg,i-1,i,true)
+ end
+ else
+ ---------- generic case (no special function) ----------------
+ if arbitrary_samples then
+ -- go through the connected parts
+ for part = 1, #graphs do
+ local dg = diffgraph(f,graphs[part],xstep)
+ --printdifftable(dg) -- for debugging
+ bezierpoints[#bezierpoints+1] = {dg[1][1],dg[1][2]}
+ local startindex = 1
+ for k = 2, #dg do
+ if dg[k][5] or dg[k][6] then -- extrema and inflection points
+ local tobeadded = graphtobezierapprox(
+ f,dg,startindex,k,10*yerror)
+ -- tobeadded may contain a multiple of 6 entries
+ -- e.g. {1,2,3,4,5,6,7,8,9,10,11,12}
+ for i = 1, math.floor(#tobeadded/6) do
+ bezierpoints[#bezierpoints+1] = {}
+ for j = 1, 6 do
+ bezierpoints[#bezierpoints][j] = tobeadded[(i-1)*6+j]
+ end
+ end
+ startindex = k
+ end
+ end
+ if startindex ~= #dg then -- if no special points inbetween
+ local tobeadded = graphtobezierapprox(f,dg,
+ startindex,#dg,10*yerror)
+ -- tobeadded may contain a multiple of 6 entries
+ -- e.g. {1,2,3,4,5,6,7,8,9,10,11,12}
+ for i = 1, math.floor(#tobeadded/6) do
+ bezierpoints[#bezierpoints+1] = {}
+ for j = 1, 6 do
+ bezierpoints[#bezierpoints][j] = tobeadded[(i-1)*6+j]
+ end
+ end
+ end
+ end
+ else -- fixed samples in the generic case
+ -- go through the connected parts
+ for part = 1, #graphs do
+ local dg = diffgraphsimple(f,graphs[part],xstep,
+ math.floor(0.5+xsteps/(samples-1)))
+ bezierpoints[#bezierpoints+1] = {dg[1][1],dg[1][2]} -- initial points
+ for i = 2, #dg do
+ bezierpoints[#bezierpoints+1] = graphtobezier(dg,i-1,i,false)
+ end
+ end
+ end
+ end
+ return beziertabletostring(bezierpoints,rndx,rndy,isreverse,notation)
+end
+
+-- main program --
+
+if not pcall(debug.getlocal, 4, 1) then
+--if debug.getinfo(3) == nil then
+ if #arg >= 1 then
+ local xmin = -5
+ local xmax = 5
+ if #arg >= 2 then
+ xmin = arg[2]
+ end
+ if #arg >= 3 then
+ xmax = arg[3]
+ end
+ local ymin = -5
+ local ymax = 5
+ if #arg >= 4 then
+ ymin = arg[4]
+ end
+ if #arg >= 5 then
+ ymax = arg[5]
+ end
+ local samples = 0
+ if #arg >= 6 then
+ samples = arg[6]
+ end
+ local notation = "tikz"
+ if #arg >= 7 then
+ notation = arg[7]
+ end
+ print(bezierplot(arg[1],xmin,xmax,ymin,ymax,samples,notation))
+ end
+end
+
+
+
diff --git a/macros/luatex/latex/bezierplot/bezierplot.sty b/macros/luatex/latex/bezierplot/bezierplot.sty
new file mode 100644
index 0000000000..94be30b4dc
--- /dev/null
+++ b/macros/luatex/latex/bezierplot/bezierplot.sty
@@ -0,0 +1,17 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{bezierplot}[2019/06/18 bezierplot]
+\RequirePackage{xparse}
+\RequirePackage{iftex}
+\ifLuaTeX
+ \directlua{require("bezierplot")}
+ \DeclareExpandableDocumentCommand{\xbezierplot}{O{-5} O{5} O{-5} O{5} O{0} O{tikz} m}{%
+ \directlua{tex.sprint(bezierplot("#7","#1","#2","#3","#4","#5","#6"))}
+ }
+\else
+ \let\xpandblinpt\@@input
+ \DeclareExpandableDocumentCommand{\xbezierplot}{O{-5} O{5} O{-5} O{5} O{0} O{tikz} m}{%
+ \xpandblinpt|"bezierplot '#7' '#1' '#2' '#3' '#4' '#5' '#6'"
+ }
+\fi
+\providecommand\bezierplot{\romannumeral`\^^@\xbezierplot}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/cloze/README b/macros/luatex/latex/cloze/README
new file mode 100644
index 0000000000..1369553b81
--- /dev/null
+++ b/macros/luatex/latex/cloze/README
@@ -0,0 +1,53 @@
+# Description
+
+EN: `cloze` is a LuaLaTeX/LaTeX package to generate cloze. It uses the
+capabilities of the modern TeX engine LuaTex.
+
+DE: `cloze` ist a LuaLaTeX/LaTeX-Paket zum Erstellen von Lückentexten.
+Es nutzt die Möglichkeiten der modernen TeX-Engine LuaTeX.
+
+# License
+
+Copyright (C) 2015 by Josef Friedrich <josef@friedrich.rocks>
+------------------------------------------------------------------------
+This work may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3 of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+# CTAN
+
+Since July 2015 the cloze package is included in the Comprehensive TeX
+Archive Network (CTAN).
+
+* TeX archive: http://mirror.ctan.org/tex-archive/macros/luatex/latex/cloze
+* Package page: https://www.ctan.org/pkg/cloze
+
+# Repository
+
+https://github.com/Josef-Friedrich/cloze
+
+# Installation
+
+Get source:
+
+ git clone git@github.com:Josef-Friedrich/cloze.git
+ cd cloze
+
+Compile:
+
+ make
+
+or manually:
+
+ luatex cloze.ins
+ lualatex cloze.dtx
+ makeindex -s gglo.ist -o cloze.gls cloze.glo
+ makeindex -s gind.ist -o cloze.ind cloze.idx
+ lualatex cloze.dtx
+
diff --git a/macros/luatex/latex/cloze/cloze.dtx b/macros/luatex/latex/cloze/cloze.dtx
new file mode 100644
index 0000000000..18780780f2
--- /dev/null
+++ b/macros/luatex/latex/cloze/cloze.dtx
@@ -0,0 +1,2379 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2015-2016 by Josef Friedrich <josef@friedrich.rocks>
+% ----------------------------------------------------------------------
+% This work may be distributed and/or modified under the conditions of
+% the LaTeX Project Public License, either version 1.3 of this license
+% or (at your option) any later version. The latest version of this
+% license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Josef Friedrich.
+%
+% This work consists of the files cloze.dtx and cloze.ins
+% and the derived filebase cloze.sty and cloze.lua.
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{cloze.dtx}
+%</driver>
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{cloze}
+%<*package>
+ [2016/06/23 v1.2 Package to typeset cloze worksheets or cloze tests]
+%</package>
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[show]{cloze}
+\usepackage{paralist}
+\usepackage{titlesec}
+\titleformat{\paragraph}[hang]{%
+ \normalfont\normalsize\bfseries%
+ }{\theparagraph}{1em}{}
+\titleformat{\subparagraph}[hang]{%
+ \normalfont\small\bfseries%
+ }{\thesubparagraph}{1em}{}
+ \titlespacing*{\subparagraph}{0pt}{*1}{0pt}
+
+\usepackage[
+ colorlinks=true,
+ linkcolor=red,
+ filecolor=red,
+ urlcolor=red,
+]{hyperref}
+
+\MakeShortVerb{\|}
+
+\setlength{\fboxrule}{0.2pt}
+\setlength{\fboxsep}{4pt}
+
+\makeatletter
+\newcommand{\@minipagerestore}{\setlength{\parindent}{10pt}}
+\makeatother
+
+\newsavebox{\examplebox}
+\newenvironment{clozeexample}{%
+ \noindent%
+ \begin{lrbox}{\examplebox}%
+ \begin{minipage}{0.9\textwidth}%
+ \footnotesize%
+}{%
+ \end{minipage}%
+ \end{lrbox}%
+ \begin{center}%
+ \fbox{\usebox{\examplebox}}%
+ \end{center}%
+}
+
+% Colors for the codebox
+\definecolor{grayline}{gray}{0.9}
+\definecolor{graybackground}{gray}{0.97}
+
+\newsavebox{\codebox}
+\newenvironment{code}{%
+ \noindent%
+ \begin{lrbox}{\codebox}%
+ \begin{minipage}{0.9\textwidth}%
+}{%
+ \end{minipage}%
+ \end{lrbox}%
+ \begin{center}%
+ \fcolorbox{grayline}{graybackground}{\usebox{\codebox}}%
+ \end{center}%
+}
+
+\newcommand{\tighten}{\vspace{-6pt}}
+
+\newcommand{\getdefaults}[1]{%
+ \directlua{tex.print(cloze.get_defaults('#1'))}%
+}
+
+\newcommand{\expdesc}[1]{(|#1|)}
+
+\newcommand{\desc}[1]{%
+ \hfill%
+ \expdesc{#1}%
+ \par%
+}
+
+\def\tt#1{\texttt{#1}}
+
+\def\secref#1{(\rightarrow\ \ref{#1})}
+
+\newcommand{\option}[2]{\tt{[#1=}\meta{#2}\tt{]}}
+\newcommand{\clozeluafunction}[1]{
+ \marginpar{%
+ \raggedleft%
+ \MacroFont%
+ \tt{%
+ #1%
+ }%
+ }%
+}
+
+\newcommand{\nodelisthfont}{\bfseries\sffamily}
+
+\newcommand{\nodelistheader}{
+ \hline
+ \nodelisthfont Variable name &
+ \nodelisthfont Node type &
+ \nodelisthfont Node subtype &
+ \nodelisthfont Parameter \\
+ \hline
+}
+
+\newenvironment{nodelist}{
+ \noindent
+ \begingroup
+ \footnotesize
+ \begin{tabular}{llll}
+ \nodelistheader
+}{
+ \hline
+ \end{tabular}
+ \endgroup
+}
+
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\begin{document}
+
+\providecommand*{\url}{\texttt}
+\GetFileInfo{cloze.dtx}
+\title{The \cloze{cloze} package%
+ \thanks{Many thanks to Robert-Michael Huber for his advice
+and to Paul Isambert for his article \emph{"Three things you can do with
+Lua\TeX{} that would be extremely painful otherwise"} in TUGboat, Volume
+31 (2010), No. 3. This article helped a lot to write this package.}%
+}
+\author{%
+ Josef Friedrich\\%
+ \url{josef@friedrich.rocks}\\%
+ \href{https://github.com/Josef-Friedrich/cloze}{github.com/Josef-Friedrich/cloze}%
+}
+\date{\fileversion~from \filedate}
+
+\maketitle\vfill
+
+\pagebreak
+
+\setcounter{secnumdepth}{5}
+\setcounter{tocdepth}{5}
+\tableofcontents
+
+%-----------------------------------------------------------------------
+% Introduction
+%-----------------------------------------------------------------------
+
+\pagebreak
+\section{Introduction}
+
+\emph{cloze} is a \LaTeX{} package to generate cloze texts. It uses
+the capabilities of the modern \TeX{} engine \emph{Lua\TeX}. Therefore,
+you must use Lua\LaTeX{} to create documents containing gaps.
+
+\begin{code}
+\begin{verbatim}
+lualatex cloze-text.tex
+\end{verbatim}
+\end{code}
+
+The main feature of the package is that the formatting doesn't change
+when using the |hide| and |show| \secref{sec:option-hide} options.
+
+\newcommand{\clozelorem}{%
+Lorem ipsum \cloze{dolor sit} amet, consectetur \cloze{adipisicing}
+elit, sed do eiusmod tempor incididunt ut labore et \cloze{dolore magna}
+aliqua. Ut enim ad minim veniam, quis nostrud \cloze{exercitation}
+ullamco laboris nisi ut \cloze{aliquip} ex ea commodo consequat.%
+}
+
+\begin{clozeexample}
+\clozelorem
+\end{clozeexample}
+
+\clozeset{hide}
+
+The command |\clozeset{hide}| only shows gaps. When you put both texts
+on top of each other you will see that they perfectly match.
+
+\begin{clozeexample}
+\clozelorem
+\end{clozeexample}
+
+\clozeset{show}
+
+%-----------------------------------------------------------------------
+% Usage
+%-----------------------------------------------------------------------
+
+\section{Usage}
+
+There are three commands and one environment to generate
+cloze texts: \cmd{\cloze}, \cmd{\clozefix}, \cmd{\clozefil} and
+|clozepar|.
+
+%%
+% \cloze
+%%
+
+\subsection{The commands and environments}
+
+\subsubsection{\cmd{\cloze}}
+\label{sec:command-cloze}
+
+\DescribeMacro{\cloze} \cmd{\cloze}\oarg{options}\marg{some text}: The
+command \cmd{\cloze} is similar to a command that offers the possibility
+to underline the texts. \cmd{\cloze} does not prevent line breaks. The
+width of a gap depends on the number of letters and the font used.
+The only option which affects the widths of a gap is the option
+|margin| \secref{sec:option-margin}.
+
+\begin{clozeexample}
+Lorem ipsum \cloze{dolor} sit amet, \cloze{consectetur} adipisicing
+elit, sed do eiusmod tempor incididunt ut labore et dolore
+\cloze{magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
+ullamco laboris nisi} ut aliquip ex ea commodo consequat.
+\end{clozeexample}
+
+\noindent It is possible to convert a complete paragraph into a `gap'.
+But don't forget: There is a special environment for this: \tt{clozepar}
+\secref{sec:command-clozepar}.
+
+\begin{clozeexample}
+\cloze{Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
+eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
+minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
+ex ea commodo consequat.}
+\end{clozeexample}
+
+\noindent The command \cmd{\cloze} doesn't change the behavior of the
+hyphenation. Let's try some long German words:
+
+\begin{clozeexample}
+es
+\cloze{Te\-le\-kom\-mu\-ni\-ka\-tions\-ü\-ber\-wach\-ung}
+geht
+\cloze{Un\-ter\-neh\-mens\-steu\-er\-fort\-ent\-wick\-lungs\-ge\-setz}
+\cloze{Ab\-teil\-ungs\-lei\-ter\-in}
+\cloze{Ober\-kom\-mi\-sar\-in}
+auch
+\cloze{Fil\-lial\-lei\-ter\-in}
+kurz
+\cloze{Ober\-kom\-mi\-sar\-in}
+\cloze{Un\-ter\-neh\-mens\-steu\-er\-fort\-ent\-wick\-lungs\-ge\-setz}
+\cloze{Fil\-lial\-lei\-ter\-in}
+\cloze{Metz\-ger\-mei\-ster\-in}
+in
+\cloze{Ab\-teil\-ungs\-lei\-ter\-in}
+der
+\cloze{Ober\-kom\-mi\-sar\-in}
+\cloze{Hoch\-lei\-stungs\-flüs\-sig\-keits\-chro\-ma\-to\-gra\-phie}
+\cloze{Fil\-lial\-lei\-ter\-in}
+Kürze
+\cloze{Un\-ter\-neh\-mens\-steu\-er\-fort\-ent\-wick\-lungs\-ge\-setz}
+\cloze{Metz\-ger\-mei\-ster\-in}
+liegt
+\cloze{Ab\-teil\-ungs\-lei\-ter\-in}
+die
+\cloze{Metz\-ger\-mei\-ster\-in}
+\cloze{Ab\-teil\-ungs\-lei\-ter\-in}
+Würze
+\cloze{Ober\-kom\-mi\-sar\-in}
+\end{clozeexample}
+
+%%
+% \clozesetfont
+%%
+
+\subsubsection{\cmd{\clozesetfont}}
+\label{sec:command-clozesetfont}
+\label{sec:command-clozefont}
+
+\DescribeMacro{\clozesetfont}
+The gap font can be changed by using the command
+\cmd{\clozesetfont}. \tt{\string\cloze\-set\-font} redefines the command
+\cmd{\clozefont} which contains the font definition.
+Thus, the command \tt{\string\clozesetfont\string{\string\Large\string}}
+has the same effect as
+\tt{\string\re\-new\-com\-mand\string{\string\cloze\-font\string}%
+\string{\string\Large\string}}.
+
+\clozesetfont{\Large}
+
+\begin{clozeexample}
+Excepteur \cloze{sint} occaecat \cloze{cupidatat} non proident.
+\end{clozeexample}
+
+\noindent Please do not put any color definitions in
+\cmd{\clozesetfont}, as it won't work. Use the option
+|textcolor| instead \secref{sec:option-textcolor}.
+
+|\clozesetfont{\ttfamily\normalsize}| changes the gap text for example
+into a normal sized typewriter font.
+
+\clozesetfont{\ttfamily\normalsize}
+
+\begin{clozeexample}
+Excepteur \cloze{sint} occaecat \cloze{cupidatat} non proident.
+\end{clozeexample}
+
+\clozesetfont{\itshape}
+
+%%
+% \clozefix
+%%
+
+\subsubsection{\cmd{\clozefix}}
+\label{sec:command-clozefix}
+
+\DescribeMacro{\clozefix} \cmd{\clozefix}\oarg{options}\marg{some text}:
+The command \cmd{\clozefix} creates gaps with a fixed width. The
+clozes are default concering the width \tt{\getdefaults{width}}.
+
+\begin{clozeexample}
+\noindent Lorem ipsum dolor sit amet:
+\begin{compactenum}
+\item \clozefix[width=5cm]{consectetur}
+\item \clozefix[width=5cm]{adipisicing}
+\item \clozefix[width=5cm]{elit}
+\end{compactenum}
+sed do eiusmod.
+\end{clozeexample}
+
+Gaps with a fixed width are much harder to solve.
+
+\begin{clozeexample}
+Lorem ipsum dolor \clozefix[align=center,width=3cm]{sit} amet,
+\clozefix[align=center,width=3cm]{consectetur} adipisicing elit, sed do
+eiusmod tempor incididunt \clozefix[align=center,width=3cm]{ut} labore
+et dolore magna aliqua.
+\end{clozeexample}
+
+Using the option |align| you can make nice tabulars like this:
+
+\begin{clozeexample}
+\begin{tabular}{p{5cm}p{4cm}}
+\raggedleft Composer & Life span \\
+\clozefix[width=5cm,align=right]{Joseph Haydn} & \clozefix{1723-1809} \\
+\clozefix[width=5cm,align=right]{Wolfgang Amadeus Mozart} & \clozefix{1756-1791} \\
+\clozefix[width=5cm,align=right]{Ludwig van Beethoven} & \clozefix{1770-1827} \\
+\end{tabular}
+\end{clozeexample}
+
+%%
+% \clozefil
+%%
+
+\subsubsection{\cmd{\clozefil}}
+\label{sec:command-clozefil}
+
+\DescribeMacro{\clozefil} \cmd{\clozefil}\oarg{options}\marg{some text}:
+The name of the command is inspired by \cmd{\hfil}, \cmd{\hfill}, and
+\cmd{\hfilll}. Only \cmd{\clozefil} fills out all available horizontal
+spaces with a line.
+
+\begin{clozeexample}
+Lorem ipsum dolor sit amet, \clozefil{consectetur adipisicing elit, sed
+do eiusmod.}
+
+Ut enim \clozefil{ad minim veniam} exercitation.
+\end{clozeexample}
+
+%%
+% clozepar
+%%
+
+\subsubsection{\tt{clozepar}}
+\label{sec:command-clozepar}
+
+\DescribeEnv{clozepar} |\begin{clozepar}|\oarg{options} \dots
+\textit{some text} \dots |\end{clozepar}|: The environment \tt{clozepar}
+transforms a complete paragraph into a cloze text. The options |align|,
+|margin| and |width| have no effect on this environment.
+
+\begin{clozeexample}
+Lorem ipsum dolor sit amet, consectetur adipisicing elit ullamco laboris
+nisi.
+
+\begin{clozepar}
+Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
+ut aliquip ex ea commodo consequat. Duis aute irure dolor in
+reprehenderit in voluptate velit esse cillum.
+\end{clozepar}
+
+Excepteur sint occaecat cupidatat non proident.
+\end{clozeexample}
+
+%%
+% \clozeline
+%%
+
+\subsubsection{\cmd{\clozeline}}
+\label{sec:command-clozeline}
+
+\DescribeMacro{\clozeline}
+\cmd{\clozeline}\oarg{options}:
+To create a cloze line of a certain width, use the command
+\cmd{\clozeline}. The default width of the line is
+\tt{\getdefaults{width}}. In combination with the other cloze commands
+you can create for example an irregular alignment of the cloze text.
+
+\begin{code}
+\begin{verbatim}
+Ut enim ad
+\clozeline[width=1cm]\cloze{minim}\clozeline[width=3cm]
+minim veniam
+\end{verbatim}
+\end{code}
+
+\tighten
+
+\begin{clozeexample}
+Ut enim ad \clozeline[width=1cm]\cloze{minim}\clozeline[width=3cm] minim
+veniam,
+\end{clozeexample}
+
+%%
+% \clozelinefil
+%%
+
+\subsubsection{\cmd{\clozelinefil}}
+\label{sec:command-clozelinefil}
+
+\DescribeMacro{\clozelinefil}
+\cmd{\clozelinefil}\oarg{options}:
+This command \cmd{\clozelinefil} fills the
+complete available horizontal space with a line. Moreover,
+\cmd{\clozelinefil} was used to create \cmd{\clozefil}.
+
+\begin{clozeexample}
+Lorem\clozelinefil
+\end{clozeexample}
+
+%-----------------------------------------------------------------------
+% Options
+%-----------------------------------------------------------------------
+
+\subsection{The options}
+
+%%
+% Local and global options
+%%
+
+\subsubsection{Local and global options}
+
+The \emph{cloze} package distinguishs between \emph{local} and
+\emph{global} options. Besides the possiblity to set \emph{global}
+options in the \cmd{\usepackage}\oarg{global options}\marg{cloze}
+declaration, the cloze package offers a special command to set
+\emph{global} options:
+\cmd{\clozeset}\marg{global options}
+
+%%
+% \clozeset
+%%
+
+\subsubsection{\cmd{\clozeset}}
+\label{sec:command-clozeset}
+
+\DescribeMacro{\clozeset}
+\cmd{\clozeset}\marg{global options}: The command can set \emph{global}
+options for each paragraph.
+
+\begin{code}
+\begin{verbatim}
+\clozeset{textcolor=red} Lorem \cloze{ipsum} dolor \par
+\clozeset{textcolor=green} Lorem \cloze{ipsum} dolor
+\end{verbatim}
+\end{code}
+
+\tighten
+
+\begin{clozeexample}
+\clozeset{textcolor=red} Lorem \cloze{ipsum} dolor \par
+\clozeset{textcolor=green} Lorem \cloze{ipsum} dolor
+\end{clozeexample}
+
+\noindent \cmd{\clozeset} does not change the options within a
+paragraph. As you can see in the example below the last \cmd{\clozeset}
+applies the color green for both gaps.
+
+\begin{code}
+\begin{verbatim}
+\clozeset{textcolor=red} Lorem \cloze{ipsum} dolor
+\clozeset{textcolor=green} Lorem \cloze{ipsum} dolor
+\end{verbatim}
+\end{code}
+
+\tighten
+
+\begin{clozeexample}
+\clozeset{textcolor=red} Lorem \cloze{ipsum} dolor
+\clozeset{textcolor=green} Lorem \cloze{ipsum} dolor
+\end{clozeexample}
+
+\clozereset
+
+%%
+% \clozereset
+%%
+
+\subsubsection{\cmd{\clozereset}}
+\label{sec:command-clozereset}
+
+\DescribeMacro{\clozereset}
+\cmd{\clozereset}: The command resets all \emph{global} options to the
+default values. It has no effect on the \emph{local} options.
+
+\begin{code}
+\begin{verbatim}
+\clozeset{
+ thickness=3mm,
+ linecolor=yellow,
+ textcolor=magenta,
+ margin=-2pt
+}
+\end{verbatim}
+\end{code}
+
+\tighten
+
+\clozeset{thickness=3mm,linecolor=yellow,textcolor=magenta,margin=-2pt}
+
+\begin{clozeexample}
+Very \cloze{silly} global \cloze{options}.
+\end{clozeexample}
+
+\begin{code}
+|\clozereset|
+\end{code}
+\clozereset
+
+\tighten
+
+\begin{clozeexample}
+\cloze{Relax!} We can reset \cloze{those} options.
+\end{clozeexample}
+
+%%
+% \clozereset
+%%
+
+\subsubsection{\cmd{\clozeshow} and \cmd{\clozehide}}
+\label{sec:command-clozeshow}
+\label{sec:command-clozehide}
+
+\DescribeMacro{\clozeshow} \DescribeMacro{\clozehide}
+\cmd{\clozeshow} and \cmd{\clozehide}: This commands are shortcuts for
+\cmd{\clozeset}\marg{show} and \cmd{\clozeset}\marg{hide}.
+
+\begin{code}
+|\clozehide|
+\end{code}
+\clozehide
+
+\tighten
+
+\begin{clozeexample}
+Lorem \cloze{ipsum dolor sit} amet, consectetur \cloze{adipisicing}
+elit.
+\end{clozeexample}
+
+\begin{code}
+|\clozeshow|
+\end{code}
+\clozeshow
+
+\tighten
+
+\begin{clozeexample}
+Lorem \cloze{ipsum dolor sit} amet, consectetur \cloze{adipisicing}
+elit.
+\end{clozeexample}
+
+%%
+% align
+%%
+
+\subsubsection{\tt{align}}
+\label{sec:option-align}
+
+\option{align}{left/center/right}:
+Only the macro \cmd{\clozefix} \secref{sec:command-clozefix} takes the
+option \tt{align} into account. Possible values are \tt{left},
+\tt{center} and \tt{right}. This option only makes sense, if the width
+of the line is larger than the width of the text.
+
+\newcommand{\optionsalign}[1]{%
+ \noindent%
+ \clozefix[align=#1,width=8cm]{Lorem ipsum}%
+ \desc{#1}%
+}
+
+\begin{clozeexample}
+\optionsalign{left}
+\optionsalign{center}
+\optionsalign{right}
+\end{clozeexample}
+
+%%
+% distance
+%%
+
+\subsubsection{\tt{distance}}
+\label{sec:option-distance}
+
+\option{distance}{dimen}:
+The option |distance| specifies the spacing between the baseline of the
+text and the gap line. The larger the dimension of the option
+|distance|, the more moves the line down. Negative values cause the line
+to appear above the baseline. The default value is
+\tt{\getdefaults{distance}}.
+
+\newcommand{\optiondistance}[1]{%
+ \noindent%
+ \clozefil[distance=#1]{Lorem ipsum dolor sit amet.}
+ \expdesc{#1}
+ \par%
+}
+
+\begin{clozeexample}
+\optiondistance{\getdefaults{distance}}
+\optiondistance{3pt}
+\optiondistance{-3pt}
+\end{clozeexample}
+
+%%
+% hide and show
+%%
+
+\subsubsection{\tt{hide} and \tt{show}}
+\label{sec:option-hide}
+\label{sec:option-show}
+
+\tt{[hide]} and \tt{[show]}:
+By default the cloze text is displayed. Use the option |hide| to remove
+the cloze text from the output. If you accidentally specify both
+options -- |hide| and |show| -- the last option "wins".
+
+\newcommand{\optionshow}[1]{%
+ \noindent%
+ Lorem ipsum \cloze[#1]{dolor sit amet}, consectetur
+ \cloze[#1]{adipisicing} elit.%
+ \desc{#1}%
+}
+
+\begin{clozeexample}
+\optionshow{hide}
+\optionshow{show}
+\optionshow{show,hide}
+\optionshow{hide,show}
+\end{clozeexample}
+
+%%
+% linecolor and textcolor
+%%
+
+\subsubsection{\tt{linecolor} and \tt{textcolor}}
+\label{sec:option-linecolor}
+\label{sec:option-textcolor}
+
+\option{linecolor}{color name} and
+\option{textcolor}{color name}:
+Values for both color options are color names used by the xcolor
+package. To define your own color use the following command:
+
+\begin{code}
+\begin{verbatim}
+\definecolor{myclozecolor}{rgb}{0.1,0.4,0.6}
+\cloze[textcolor=myclozecolor]{Lorem ipsum}
+\end{verbatim}
+\end{code}
+\definecolor{myclozecolor}{rgb}{0.1,0.4,0.6}
+
+\newcommand{\optioncolor}[2]{%
+ \noindent%
+ \clozefil[#1=#2]{Lorem ipsum dolor sit amet, consectetur} %
+ \expdesc{#2}%
+ \par%
+}
+
+\tighten
+
+\begin{clozeexample}
+\optioncolor{textcolor}{myclozecolor}
+\optioncolor{textcolor}{red}
+\optioncolor{textcolor}{green}
+\end{clozeexample}
+
+\noindent You can use the same color names to colorize the cloze lines.
+
+\begin{clozeexample}
+\optioncolor{linecolor}{myclozecolor}
+\optioncolor{linecolor}{red}
+\optioncolor{linecolor}{green}
+\end{clozeexample}
+
+%%
+% margin
+%%
+
+\subsubsection{\tt{margin}}
+\label{sec:option-margin}
+
+\option{margin}{dimen}:
+The option |margin| indicates how far the line sticks up from the text.
+The option can be used with the commands \cmd{\cloze}, \cmd{\clozefix}
+and \cmd{\clozefil}. The default value of the option is
+\tt{\getdefaults{margin}}.
+
+\newcommand{\optionmargin}[1]{%
+ \noindent%
+ Lorem ipsum \cloze[margin=#1]{dolor} sit amet.%
+ \desc{#1}%
+}
+
+\begin{clozeexample}
+\optionmargin{0pt}
+\optionmargin{5mm}
+\optionmargin{1cm}
+\optionmargin{6em}
+\optionmargin{-4pt}
+\end{clozeexample}
+
+% Folgt ein Satzzeichen direkt auf eine Lücke, so findet der
+% Zeilenumbruch erst nach dem Satzzeichen statt. Auch ein noch so großer
+% Wert für |margin| beeinflusst dieses Verhalten nicht.
+\noindent Is a punctation mark placed directly after a gap, then the
+line breaks after this punctation mark. Even the most large value of
+|margin| does not affect this behavior.
+
+\begin{clozeexample}
+\clozeset{margin=3mm}
+\cloze{Lorem}, \cloze{ipsum}. \cloze{dolor}; \cloze{sit}: \cloze{amet},
+\cloze{consectetur}. \cloze{adipisicing}; \cloze{elit}: \cloze{sed},
+\cloze{do}. \cloze{eiusmod}; \cloze{tempor}.
+\end{clozeexample}
+
+\clozereset
+
+%%
+% thickness
+%%
+
+\subsubsection{\tt{thickness}}
+\label{sec:option-thickness}
+
+\option{thickness}{dimen}:
+The option |thickness| indicates how thick the line is. The option
+|distance| \secref{sec:option-distance} is not affected by this option,
+because the bottom of the line moves down. The default value of this
+option is \tt{\getdefaults{thickness}}.
+
+\newcommand{\optionthickness}[1]{%
+ \noindent%
+ Lorem \cloze[thickness=#1]{ipsum dolor sit} amet.%
+ \desc{#1}%
+}
+
+\begin{clozeexample}
+\optionthickness{0.01pt}
+\optionthickness{1pt}
+\optionthickness{2pt}
+\end{clozeexample}
+
+%%
+% width
+%%
+
+\subsubsection{\tt{width}}\label{sec:option-width}
+
+\option{width}{dimen}:
+The only command which can be changed by the option |width| is
+\cmd{\clozefix} \secref{sec:command-clozefix}. The default value of the
+option is \tt{\getdefaults{width}}.
+
+\newcommand{\optionwidth}[1]{%
+ \noindent%
+ Lorem \clozefix[width=#1]{dolor} amet.%
+ \desc{#1}%
+}
+
+\begin{clozeexample}
+\optionwidth{3cm}
+\optionwidth{5cm}
+\optionwidth{7cm}
+\end{clozeexample}
+
+%-----------------------------------------------------------------------
+% Special application areas
+%-----------------------------------------------------------------------
+
+\subsection{Special application areas}
+
+%%
+% tabbing
+%%
+
+\subsubsection{The \tt{tabbing} environment}
+
+\begin{code}
+\begin{verbatim}
+\begin{tabbing}
+col1 \hspace{1cm} \= col2 \hspace{1cm} \= col3 \hspace{1cm} \= col4 \\
+\cloze{col1} \> \> \clozefix{col3} \\
+\end{tabbing}
+\end{verbatim}
+\end{code}
+
+\begin{clozeexample}
+\begin{tabbing}
+col1 \hspace{1cm} \= col2 \hspace{1cm} \= col3 \hspace{1cm} \= col4 \\
+\cloze{col1} \> \> \clozefix{col3} \\
+\end{tabbing}
+\end{clozeexample}
+
+%%
+% picture
+%%
+
+\subsubsection{The \tt{picture} environment}
+
+\begin{code}
+\begin{verbatim}
+\begin{picture}(320,100)
+\put(80,25){\cloze{Lorem}}
+\put(160,50){\clozefix{ipsum}}
+\put(240,75){\clozefil{dolor}}
+\end{picture}
+\end{verbatim}
+\end{code}
+
+\begin{clozeexample}
+\begin{picture}(320,100)
+\put(80,25){\cloze{Lorem}}
+\put(160,50){\clozefix{ipsum}}
+\put(240,75){\clozefil{dolor}}
+\end{picture}
+\end{clozeexample}
+
+%%
+% tabular
+%%
+
+\subsubsection{The \tt{tabular} environment}
+
+\begin{code}
+\begin{verbatim}
+\begin{tabular}{l c}
+\cloze{Lorem} & \cloze{ipsum} \\
+\clozefix{amet} & \clozefix{consectetur} \\
+\cloze{sed} & \cloze{do} \\
+\end{tabular}
+\end{verbatim}
+\end{code}
+
+% No |c| inside because of short verbatim.
+
+\begin{clozeexample}
+\clozeset{width=1cm}
+\begin{tabular}{l c}
+\cloze{Lorem} & \cloze{ipsum} \\
+\clozefix{amet} & \clozefix{consectetur} \\
+\cloze{sed} & \cloze{do} \\
+\end{tabular}
+\end{clozeexample}
+
+ \DocInput{cloze.dtx}
+ \pagebreak
+ \PrintChanges
+ \pagebreak
+ \PrintIndex
+\end{document}
+%</driver>
+%<*readme>
+# Description
+
+EN: `cloze` is a LuaLaTeX/LaTeX package to generate cloze. It uses the
+capabilities of the modern TeX engine LuaTex.
+
+DE: `cloze` ist a LuaLaTeX/LaTeX-Paket zum Erstellen von Lückentexten.
+Es nutzt die Möglichkeiten der modernen TeX-Engine LuaTeX.
+
+# License
+
+Copyright (C) 2015 by Josef Friedrich <josef@friedrich.rocks>
+------------------------------------------------------------------------
+This work may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3 of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+# CTAN
+
+Since July 2015 the cloze package is included in the Comprehensive TeX
+Archive Network (CTAN).
+
+* TeX archive: http://mirror.ctan.org/tex-archive/macros/luatex/latex/cloze
+* Package page: https://www.ctan.org/pkg/cloze
+
+# Repository
+
+https://github.com/Josef-Friedrich/cloze
+
+# Installation
+
+Get source:
+
+ git clone git@github.com:Josef-Friedrich/cloze.git
+ cd cloze
+
+Compile:
+
+ make
+
+or manually:
+
+ luatex cloze.ins
+ lualatex cloze.dtx
+ makeindex -s gglo.ist -o cloze.gls cloze.glo
+ makeindex -s gind.ist -o cloze.ind cloze.idx
+ lualatex cloze.dtx
+
+%</readme>
+% \fi
+%
+% \CheckSum{128}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \changes{v0.1}{2015/06/16}{Converted to DTX file}
+% \changes{v1.0}{2015/07/08}{Inital release}
+% \changes{v1.1}{2016/06/13}{Make cloze compatible to LuaTeX version 0.95}
+% \changes{v1.2}{2016/06/23}{The cloze makros are now working in
+% tabular, tabbing and picture environments}
+%
+% \DoNotIndex{\newcommand,\newenvironment,\def,\directlua}
+%
+% \StopEventually{}
+% \pagebreak
+% \section{Implementation}
+%
+% \iffalse
+%<*package>
+% \fi
+% \MacroTopsep = 10pt plus 2pt minus 2pt
+% \MacrocodeTopsep = 10pt plus 1.2pt minus 1pt
+%
+% \makeatletter
+% \c@CodelineNo 25 \relax
+% \makeatother
+%
+% \subsection{The file \tt{cloze.sty}}
+%
+% This four packages are used to build \emph{cloze}:
+%
+% \begin{itemize}
+% \item \href{https://www.ctan.org/pkg/fontspec}{fontspec} is not
+% necessarily required. When using Lua\LaTeX{} it is good form to load
+% it. Apart from this the package supplies helpful messages, when you
+% compile a Lua\LaTeX{} document with pdf\LaTeX{}.
+%
+% \item \href{https://www.ctan.org/pkg/luatexbase}{luatexbase} allows to
+% register multiple Lua callbacks.
+%
+% \item \href{https://www.ctan.org/pkg/kvoptions}{kvoptions} takes the
+% handling of the options.
+%
+% \item \href{https://www.ctan.org/pkg/xcolor}{xcolor} is required to
+% colorize the text and the line of a gap.
+% \end{itemize}
+%
+% \begin{macrocode}
+\RequirePackage{fontspec,luatexbase-mcb,kvoptions,xcolor}
+% \end{macrocode}
+%
+% Load the cloze lua module and put all return values in the variable
+% |cloze|.
+%
+% \begin{macrocode}
+\directlua{
+ cloze = require('cloze')
+}
+% \end{macrocode}
+%
+% \subsubsection{Internal macros}
+%
+% \begin{macro}{\cloze@set@to@global}
+% Set the Lua variable |registry.is_global| to |true|. All options
+% are then stored in the variable |registry.global_options|.
+% \begin{macrocode}
+\def\cloze@set@to@global{%
+ \directlua{cloze.set_is_global(true)}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cloze@set@to@local}
+% First unset the variable |registry.local_options|. Now set the Lua
+% variable |registry.is_global| to |false|. All options are then stored
+% in the variable |registry.local_options|.
+% \begin{macrocode}
+\def\cloze@set@to@local{%
+ \directlua{
+ cloze.unset_local_options()
+ cloze.set_is_global(false)
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cloze@set@option}
+% \cmd{\cloze@set@option} is a wrapper for the Lua function
+% |registry.set_option|. \cmd{\cloze@set@option}\oarg{key}\marg{value}
+% sets a key \meta{key} to the value \meta{value}.
+% \begin{macrocode}
+\def\cloze@set@option[#1]#2{%
+ \directlua{cloze.set_option('#1', '#2')}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cloze@color}
+% Convert a color definiton name to a PDF colorstack string, for example
+% convert the color name |blue| to the colorstack string
+% |0 0 1 rg 0 0 1 RG|. The macro definition |\cloze@color{blue}|
+% builds itself the macro |\color@blue|, which expands to the PDF
+% colorstack string. The colorstack string is necessary to generate a
+% PDF colorstack whatsit.
+% \begin{macrocode}
+\def\cloze@color#1{\csname\string\color@#1\endcsname}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cloze@set@local@options}
+% This macro is used in all cloze commands to handle the optional
+% arguments. First it sets the option storage to local and then it
+% commits the options to the package \emph{kvoptions} via the macro
+% |\kvsetkeys{CLZ}{}|.
+% \begin{macrocode}
+\def\cloze@set@local@options#1{%
+ \cloze@set@to@local%
+ \kvsetkeys{CLZ}{#1}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cloze@start@marker}
+% At the begining |\cloze@start@marker| registers the required Lua
+% callbacks. Then it inserts a whatsit marker which marks the begin of a
+% gap.
+% \begin{macrocode}
+\def\cloze@start@marker#1{%
+ \strut\directlua{
+ cloze.register('#1')
+ cloze.marker('#1', 'start')
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cloze@stop@marker}
+% \cmd{\cloze@stop@marker} inserts a whatsit marker that marks the end
+% of gap.
+% \begin{macrocode}
+\def\cloze@stop@marker#1{%
+ \strut\directlua{
+ cloze.marker('#1', 'stop')
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cloze@margin}
+% \cmd{\cloze@margin} surrounds a text in a gap with two |kerns|.
+% \begin{macrocode}
+\def\cloze@margin#1{%
+ \directlua{cloze.margin()}%
+ #1%
+ \directlua{cloze.margin()}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Options}
+%
+% \emph{cloze} offers key-value pairs to use as options. For processing
+% the key-value pairs we use the package
+% \href{https://www.ctan.org/pkg/kvoptions}{kvoptions}.
+% To make all key-value pairs accessibly to Lua code, we use the
+% declaration
+% \cmd{\define@key}\marg{CLZ}\marg{option}\oarg[]\marg{\dots}. This
+% declaration comes from the package
+% \href{https://www.ctan.org/pkg/keyval}{keyval}.
+%
+% At start all values are declared as global options. At the Lua side
+% all values are now stored in the |registry.global_options| table.
+%
+% \begin{macrocode}
+\cloze@set@to@global
+% \end{macrocode}
+%
+% We use the abbreviation |CLZ| for \emph{cloze} as family name and
+% prefix.
+%
+% \begin{macrocode}
+\SetupKeyvalOptions{
+ family=CLZ,
+ prefix=CLZ@
+}
+% \end{macrocode}
+%
+% \paragraph{\tt{align}}
+%
+% \noindent Please read the section \secref{sec:option-align} how to use
+% the option |align|. |align| affects only the command \cmd{\clozefix}
+% \secref{sec:command-clozefix}.
+%
+% \begin{macrocode}
+\DeclareStringOption{align}
+\define@key{CLZ}{align}[]{\cloze@set@option[align]{#1}}
+% \end{macrocode}
+%
+% \paragraph{\tt{distance}}
+%
+% \noindent Please read the section \secref{sec:option-distance} how to
+% use the option |distance|.
+%
+% \begin{macrocode}
+\DeclareStringOption{distance}
+\define@key{CLZ}{distance}[]{\cloze@set@option[distance]{#1}}
+% \end{macrocode}
+%
+% \paragraph{\tt{hide}}
+%
+% \noindent If the option |hide| appears in the commands, |hide| will be
+% set to \emph{true} and |show| to \emph{false} on the Lua side. Please
+% read the section \secref{sec:option-hide} how to use the option
+% |hide|.
+%
+% \begin{macrocode}
+\DeclareVoidOption{hide}{%
+ \cloze@set@option[hide]{true}%
+ \cloze@set@option[show]{false}%
+}
+% \end{macrocode}
+%
+% \paragraph{\tt{linecolor}}
+%
+% \noindent Please read the section \secref{sec:option-linecolor} how to
+% use the option |linecolor|.
+%
+% \begin{macrocode}
+\DeclareStringOption{linecolor}
+\define@key{CLZ}{linecolor}[]{%
+ \cloze@set@option[linecolor]{\cloze@color{#1}}%
+}
+% \end{macrocode}
+%
+% \paragraph{\tt{margin}}
+%
+% \noindent Please read the section \secref{sec:option-margin} how to
+% use the option |margin|.
+%
+% \begin{macrocode}
+\DeclareStringOption{margin}
+\define@key{CLZ}{margin}[]{\cloze@set@option[margin]{#1}}
+% \end{macrocode}
+%
+% \paragraph{\tt{show}}
+%
+% \noindent If the option |show| appears in the commands, |show| will be
+% set to \emph{true} and |true| to \emph{false} on the Lua side. Please
+% read the section \secref{sec:option-show} how to use the option
+% |show|.
+%
+% \begin{macrocode}
+\DeclareVoidOption{show}{%
+ \cloze@set@option[show]{true}%
+ \cloze@set@option[hide]{false}%
+}
+% \end{macrocode}
+%
+% \paragraph{\tt{textcolor}}
+%
+% \noindent Please read the section \secref{sec:option-textcolor} how to
+% use the option |textcolor|.
+%
+% \begin{macrocode}
+\DeclareStringOption{textcolor}
+\define@key{CLZ}{textcolor}[]{%
+ \cloze@set@option[textcolor]{\cloze@color{#1}}%
+}
+% \end{macrocode}
+%
+% \paragraph{\tt{thickness}}
+%
+% \noindent Please read the section \secref{sec:option-thickness} how to
+% use the option |thickness|.
+%
+% \begin{macrocode}
+\DeclareStringOption{thickness}
+\define@key{CLZ}{thickness}[]{\cloze@set@option[thickness]{#1}}
+% \end{macrocode}
+%
+% \paragraph{\tt{width}}
+%
+% \noindent Please read the section \secref{sec:option-width} how to use
+% the option |width|. |width| affects only the command \cmd{\clozefix}
+% \secref{sec:command-clozefix}.
+%
+% \begin{macrocode}
+\DeclareStringOption{width}
+\define@key{CLZ}{width}[]{\cloze@set@option[width]{#1}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ProcessKeyvalOptions{CLZ}
+% \end{macrocode}
+%
+% \subsubsection{Public macros}
+%
+% All public macros are prefixed with |\cloze|.
+%
+% \begin{macro}{\clozeset}
+% The usage of the command \cmd{\clozeset} is described in detail in
+% section \secref{sec:command-clozeset}.
+% \begin{macrocode}
+\newcommand{\clozeset}[1]{%
+ \cloze@set@to@global%
+ \kvsetkeys{CLZ}{#1}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clozereset}
+% The usage of the command \cmd{\clozereset} is described in detail in
+% section \secref{sec:command-clozereset}.
+% \begin{macrocode}
+\newcommand{\clozereset}{%
+ \directlua{cloze.reset()}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clozeshow}
+% The usage of the command \cmd{\clozeshow} is described in detail in
+% section \secref{sec:command-clozeshow}.
+% \begin{macrocode}
+\newcommand{\clozeshow}{%
+ \clozeset{show}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clozehide}
+% The usage of the command \cmd{\clozehide} is described in detail in
+% section \secref{sec:command-clozehide}.
+% \begin{macrocode}
+\newcommand{\clozehide}{%
+ \clozeset{hide}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clozefont}
+% The usage of the command \cmd{\clozefont} is described in detail in
+% section \secref{sec:command-clozefont}.
+% \begin{macrocode}
+\newcommand{\clozefont}{\itshape}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clozesetfont}
+% The usage of the command \cmd{\clozesetfont} is described in detail in
+% section \secref{sec:command-clozesetfont}.
+% \begin{macrocode}
+\newcommand{\clozesetfont}[1]{%
+ \renewcommand{\clozefont}[1]{%
+ #1%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cloze}
+% The usage of the command \cmd{\cloze} is described in detail in
+% section \secref{sec:command-cloze}.
+% \begin{macrocode}
+\newcommand{\cloze}[2][]{%
+ \cloze@set@local@options{#1}%
+ \cloze@start@marker{basic}%
+ {%
+ \clozefont\relax%
+ \cloze@margin{#2}%
+ }%
+ \cloze@stop@marker{basic}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clozefix}
+% The usage of the command \cmd{\clozefix} is described in detail in
+% section \secref{sec:command-clozefix}.
+% \begin{macrocode}
+\newcommand{\clozefix}[2][]{%
+ \cloze@set@local@options{#1}%
+ \cloze@start@marker{fix}%
+ {%
+ \clozefont\relax%
+ \cloze@margin{#2}%
+ }%
+ \cloze@stop@marker{fix}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{clozepar}
+% The usage of the environment |clozepar| is described in detail in
+% section \secref{sec:command-clozepar}.
+% \begin{macrocode}
+\newenvironment{clozepar}[1][]%
+{%
+ \par%
+ \cloze@set@local@options{#1}%
+ \cloze@start@marker{par}%
+ \clozefont\relax%
+}%
+{%
+ \cloze@stop@marker{par}%
+ \par%
+ \directlua{cloze.unregister('par')}%
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\clozefil}
+% The usage of the command \cmd{\clozefil} is described in detail in
+% section \secref{sec:command-clozefil}.
+% \begin{macrocode}
+\newcommand{\clozefil}[2][]{%
+ \cloze[#1]{#2}\clozelinefil[#1]%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clozeline}
+% The usage of the command \cmd{\clozeline} is described in detail in
+% section \secref{sec:command-clozeline}.
+% \begin{macrocode}
+\newcommand{\clozeline}[1][]{%
+ \cloze@set@local@options{#1}%
+ \directlua{cloze.line()}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clozelinefil}
+% The usage of the command \cmd{\clozelinefil} is described in detail in
+% section \secref{sec:command-clozelinefil}.
+% \begin{macrocode}
+\newcommand{\clozelinefil}[1][]{%
+ \cloze@set@local@options{#1}%
+ \strut%
+ \directlua{cloze.linefil()}%
+ \strut%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \iffalse
+%</package>
+%<*lua>
+% \fi
+%
+% \makeatletter
+% \c@CodelineNo 0 \relax
+% \makeatother
+%
+% \subsection{The file \tt{cloze.lua}}
+%
+% \setlength{\parindent}{0pt}
+%
+% \paragraph{Initialisation of the function tables}
+%
+% It is good form to provide some background informations about this Lua
+% module.
+% \begin{macrocode}
+if not modules then modules = { } end modules ['cloze'] = {
+ version = '0.1',
+ comment = 'cloze',
+ author = 'Josef Friedrich, R.-M. Huber',
+ copyright = 'Josef Friedrich, R.-M. Huber',
+ license = 'The LaTeX Project Public License Version 1.3c 2008-05-04'
+}
+% \end{macrocode}
+%
+% |nodex| is a abbreviation for \emph{node eXtended}.
+% \begin{macrocode}
+local nodex = {}
+% \end{macrocode}
+%
+% All values and functions, which are related to the option management,
+% are stored in a table called |registry|.
+%
+% \begin{macrocode}
+local registry = {}
+% \end{macrocode}
+%
+% I didn't know what value I should take as |user_id|. Therefore I took
+% my birthday and transformed it to a large number.
+% \begin{macrocode}
+registry.user_id = 3121978
+registry.storage = {}
+registry.defaults = {
+ ['align'] = 'l',
+ ['distance'] = '1.5pt',
+ ['hide'] = false,
+ ['linecolor'] = '0 0 0 rg 0 0 0 RG', -- black
+ ['margin'] = '3pt',
+ ['resetcolor'] = '0 0 0 rg 0 0 0 RG', -- black
+ ['show_text'] = true,
+ ['show'] = true,
+ ['textcolor'] = '0 0 1 rg 0 0 1 RG', -- blue
+ ['thickness'] = '0.4pt',
+ ['width'] = '2cm',
+}
+registry.global_options = {}
+registry.local_options = {}
+% \end{macrocode}
+%
+% All those functions are stored in the table |cloze| that are
+% registered as callbacks to the pre and post linebreak filters.
+% \begin{macrocode}
+local cloze = {}
+% \end{macrocode}
+% In the status table are stored state information, which are necessary
+% for the recursive cloze generation.
+% \begin{macrocode}
+cloze.status = {}
+% \end{macrocode}
+%
+% The |base| table contains some basic functions. |base| is the only
+% table of this Lua module that will be exported.
+% \begin{macrocode}
+local base = {}
+base.is_registered = {}
+% \end{macrocode}
+%
+% \subsubsection{Node precessing (nodex)}
+%
+% All functions in this section are stored in a table called |nodex|.
+% |nodex| is a abbreviation for \emph{node eXtended}. The |nodex| table
+% bundles all functions, which extend the built-in |node| library.
+%
+% \paragraph{Color handling (color)}
+%
+% \clozeluafunction{create\_colorstack}
+% Create a whatsit node of the subtype |pdf_colorstack|. |data| is a PDF
+% colorstack string like |0 0 0 rg 0 0 0 RG|.
+% \begin{macrocode}
+function nodex.create_colorstack(data)
+ if not data then
+ data = '0 0 0 rg 0 0 0 RG' -- black
+ end
+ local whatsit = node.new('whatsit', 'pdf_colorstack')
+ whatsit.stack = 0
+ whatsit.data = data
+ return whatsit
+end
+% \end{macrocode}
+%
+% \clozeluafunction{create\_color}
+% |nodex.create_color()| is a wrapper for the function
+% |nodex.create_colorstack()|. It queries the current values of the
+% options |linecolor| and |textcolor|. The argument |option| accepts the
+% strings |line|, |text| and |reset|.
+% \begin{macrocode}
+function nodex.create_color(option)
+ local data
+ if option == 'line' then
+ data = registry.get_value('linecolor')
+ elseif option == 'text' then
+ data = registry.get_value('textcolor')
+ elseif option == 'reset' then
+ data = nil
+ else
+ data = nil
+ end
+ return nodex.create_colorstack(data)
+end
+% \end{macrocode}
+%
+% \paragraph{Line handling (line)}
+%
+% \clozeluafunction{create\_line}
+% Create a rule node, which is used as a line for the cloze texts. The
+% |depth| and the |height| of the rule are calculated form the options
+% |thickness| and |distance|. The argument |width| must have the length
+% unit \emph{scaled points}.
+% \begin{macrocode}
+function nodex.create_line(width)
+ local rule = node.new(node.id('rule'))
+ local thickness = tex.sp(registry.get_value('thickness'))
+ local distance = tex.sp(registry.get_value('distance'))
+ rule.depth = distance + thickness
+ rule.height = - distance
+ rule.width = width
+ return rule
+end
+% \end{macrocode}
+%
+% \clozeluafunction{insert\_list}
+% Insert a |list| of nodes after or before the |current|. The |head|
+% argument is optional. In some edge cases it is unfortately necessary.
+% if |head| is omitted the |current| node is used. The argument
+% |position| can take the values |'after'| or |'before'|.
+% \begin{macrocode}
+function nodex.insert_list(position, current, list, head)
+ if not head then
+ head = current
+ end
+ for i, insert in ipairs(list) do
+ if position == 'after' then
+ head, current = node.insert_after(head, current, insert)
+ elseif position == 'before' then
+ head, current = node.insert_before(head, current, insert)
+ end
+ end
+ return current
+end
+% \end{macrocode}
+%
+% \clozeluafunction{insert\_line}
+% Enclose a rule node (cloze line) with two PDF colorstack whatsits. The
+% first colorstack node dyes the line, the seccond resets the color.
+%
+% \subparagraph*{Node list:}
+%
+% \begin{nodelist}
+% |n.color_line| & |whatsit| & |pdf_colorstack| & Line color \\
+% |n.line| & |rule| & & |width| \\
+% |n.color_reset| & |whatsit| & |pdf_colorstack| & Reset color \\
+% \end{nodelist}
+%
+% \begin{macrocode}
+function nodex.insert_line(current, width)
+ return nodex.insert_list(
+ 'after',
+ current,
+ {
+ nodex.create_color('line'),
+ nodex.create_line(width),
+ nodex.create_color('reset')
+ }
+ )
+end
+% \end{macrocode}
+%
+% \clozeluafunction{write\_line}
+% This function enclozes a rule node with color nodes as it the function
+% |nodex.insert_line| does. In contrast to |nodex.insert_line| the three
+% nodes are appended to \TeX’s ‘current list’. They are not inserted in
+% a node list, which is accessed by a Lua callback.
+%
+% \subparagraph*{Node list:}
+%
+% \begin{nodelist}
+% - & |whatsit| & |pdf_colorstack| & Line color \\
+% - & |rule| & & |width| \\
+% - & |whatsit| & |pdf_colorstack| & Reset color \\
+% \end{nodelist}
+%
+% \begin{macrocode}
+function nodex.write_line()
+ node.write(nodex.create_color('line'))
+ node.write(nodex.create_line(tex.sp(registry.get_value('width'))))
+ node.write(nodex.create_color('reset'))
+end
+% \end{macrocode}
+%
+% \paragraph{Handling of extendable lines (linefil)}
+%
+% \clozeluafunction{create\_linefil}
+% This function creates a line which stretchs indefinitely in the
+% horizontal direction.
+% \begin{macrocode}
+function nodex.create_linefil()
+ local glue = node.new('glue')
+ glue.subtype = 100
+ glue.stretch = 65536
+ glue.stretch_order = 3
+ local rule = nodex.create_line(0)
+ rule.dir = 'TLT'
+ glue.leader = rule
+ return glue
+end
+% \end{macrocode}
+%
+% \clozeluafunction{write\_linefil}
+% The function |nodex.write_linefil| surrounds a indefinitely strechable
+% line with color whatsits and puts it to \TeX’s ‘current (node) list’.
+% \begin{macrocode}
+function nodex.write_linefil()
+ node.write(nodex.create_color('line'))
+ node.write(nodex.create_linefil())
+ node.write(nodex.create_color('reset'))
+end
+% \end{macrocode}
+%
+% \paragraph{Kern handling (kern)}
+%
+% \clozeluafunction{create\_kern}
+% This function creates a kern node with a given width. The argument
+% |width| had to be specified in scaled points.
+% \begin{macrocode}
+function nodex.create_kern(width)
+ local kern = node.new(node.id('kern'))
+ kern.kern = width
+ return kern
+end
+% \end{macrocode}
+%
+% \clozeluafunction{strut\_to\_hlist}
+% To make life easier: We add at the beginning of each hlist a strut.
+% Now we can add line, color etc. nodes after the first node of a hlist
+% not before - after is much more easier.
+% \begin{macrocode}
+function nodex.strut_to_hlist(hlist)
+ local n = {} -- node
+ n.head = hlist.head
+ n.kern = nodex.create_kern(0)
+ n.strut = node.insert_before(n.head, n.head, n.kern)
+ hlist.head = n.head.prev
+ return hlist, n.strut, n.head
+end
+% \end{macrocode}
+%
+% \clozeluafunction{write\_margin}
+% Write kern nodes to the current node list. This kern nodes can be used
+% to build a margin.
+% \begin{macrocode}
+function nodex.write_margin()
+ local kern = nodex.create_kern(tex.sp(registry.get_value('margin')))
+ node.write(kern)
+end
+% \end{macrocode}
+%
+% \clozeluafunction{search\_hlist}
+% Search for a |hlist| (subtype |line|). Return false, if no |hlist| can
+% be found.
+% \begin{macrocode}
+function nodex.search_hlist(head)
+ while head do
+ if head.id == node.id('hlist') and head.subtype == 1 then
+ return nodex.strut_to_hlist(head)
+ end
+ head = head.next
+ end
+ return false
+end
+% \end{macrocode}
+%
+% \subsubsection{Option handling (registry)}
+%
+% The table |registry| bundels functions that deal with option handling.
+%
+% \paragraph{Marker processing (marker)}
+%
+% A marker is a whatsit node of the subtype |user_defined|. A marker has
+% two purposes:
+%
+% \begin{enumerate}
+% \item Mark the begin and the end of a gap.
+% \item Store a index number, that points to a Lua table, which holds
+% some additional data like the local options.
+% \end{enumerate}
+%
+% \clozeluafunction{create\_marker}
+% We create a user defined whatsit node that can store a number (type =
+% 100). In order to distinguish this node from other user defined
+% whatsit nodes we set the |user_id| to a large number. We call this
+% whatsit node a marker. The argument |index| is a number, which is
+% associated to values in the |registry.storage| table.
+% \begin{macrocode}
+function registry.create_marker(index)
+ local marker = node.new('whatsit','user_defined')
+ marker.type = 100 -- number
+ marker.user_id = registry.user_id
+ marker.value = index
+ return marker
+end
+% \end{macrocode}
+%
+% \clozeluafunction{write\_marker}
+% Write a marker node to \TeX's current node list. The argument |mode|
+% accepts the string values |basic|, |fix| and |par|. The argument
+% |position|. The argument |position| is either set to |start| or to
+% |stop|.
+% \begin{macrocode}
+function registry.write_marker(mode, position)
+ local index = registry.set_storage(mode, position)
+ local marker = registry.create_marker(index)
+ node.write(marker)
+end
+% \end{macrocode}
+%
+% \clozeluafunction{is\_marker}
+% This functions checks if the given node |item| is a marker.
+% \begin{macrocode}
+function registry.is_marker(item)
+ if item.id == node.id('whatsit')
+ and item.subtype == node.subtype('user_defined')
+ and item.user_id == registry.user_id then
+ return true
+ else
+ return false
+ end
+end
+% \end{macrocode}
+%
+% \clozeluafunction{check\_marker}
+% This functions tests, whether the given node |item| is a marker. The
+% argument |item| is a node. The argument |mode| accepts the string
+% values |basic|, |fix| and |par|. The argument |position| is either set
+% to |start| or to |stop|.
+% \begin{macrocode}
+function registry.check_marker(item, mode, position)
+ local data = registry.get_marker_data(item)
+ if data and data.mode == mode and data.position == position then
+ return true
+ else
+ return false
+ end
+end
+% \end{macrocode}
+%
+% \clozeluafunction{get\_marker}
+% |registry.get_marker| returns the given marker. The argument |item| is
+% a node. The argument |mode| accepts the string values |basic|, |fix|
+% and |par|. The argument |position| is either set to |start| or to
+% |stop|.
+% \begin{macrocode}
+function registry.get_marker(item, mode, position)
+ local out
+ if registry.check_marker(item, mode, position) then
+ out = item
+ else
+ out = false
+ end
+ if out and position == 'start' then
+ registry.get_marker_values(item)
+ end
+ return out
+end
+% \end{macrocode}
+%
+% \clozeluafunction{get\_marker\_data}
+% |registry.get_marker_data| tests whether the node |item| is a marker.
+% The argument |item| is a node of unspecified type.
+% \begin{macrocode}
+function registry.get_marker_data(item)
+ if item.id == node.id('whatsit')
+ and item.subtype == node.subtype('user_defined')
+ and item.user_id == registry.user_id then
+ return registry.get_storage(item.value)
+ else
+ return false
+ end
+end
+% \end{macrocode}
+%
+% \clozeluafunction{get\_marker\_values}
+% First this function saves the associatied values of a marker to the
+% local options table. Second it returns this values. The argument
+% |marker| is a whatsit node.
+% \begin{macrocode}
+function registry.get_marker_values(marker)
+ local data = registry.get_marker_data(marker)
+ registry.local_options = data.values
+ return data.values
+end
+% \end{macrocode}
+%
+% \clozeluafunction{remove\_marker}
+% This function removes a given whatsit marker. It only deletes a node,
+% if a marker is given.
+% \begin{macrocode}
+function registry.remove_marker(marker)
+ if registry.is_marker(marker) then node.remove(marker, marker) end
+end
+% \end{macrocode}
+%
+% \paragraph{Storage functions (storage)}
+%
+% \clozeluafunction{get\_index}
+% |registry.index| is a counter. The functions |registry.get_index()|
+% increases the counter by one and then returns it.
+% \begin{macrocode}
+function registry.get_index()
+ if not registry.index then
+ registry.index = 0
+ end
+ registry.index = registry.index + 1
+ return registry.index
+end
+% \end{macrocode}
+%
+% \clozeluafunction{set\_storage}
+% |registry.set_storage()| stores the local options in the Lua table
+% |registry.storage|. It returns a numeric index number. This index
+% number is the key, where the local options in the Lua table are
+% stored. The argument |mode| accepts the string values |basic|, |fix|
+% and |par|.
+% \begin{macrocode}
+function registry.set_storage(mode, position)
+ local index = registry.get_index()
+ local data = {
+ ['mode'] = mode,
+ ['position'] = position
+ }
+ data.values = registry.local_options
+ registry.storage[index] = data
+ return index
+end
+% \end{macrocode}
+%
+% \clozeluafunction{get\_storage}
+% The function |registry.get_storage()| retrieves values which belong to
+% a whatsit marker. The argument |index| is a numeric value.
+% \begin{macrocode}
+function registry.get_storage(index)
+ return registry.storage[index]
+end
+% \end{macrocode}
+%
+% \paragraph{Option processing (option)}
+%
+% \clozeluafunction{set\_option}
+% This function stores a value |value| and his associated key |key|
+% either to the global (|registry.global_options|) or to the local
+% (|registry.local_options|) option table. The global boolean variable
+% |registry.local_options| controls in which table the values are
+% stored.
+% \begin{macrocode}
+function registry.set_option(key, value)
+ if value == '' or value == '\\color@ ' then
+ return false
+ end
+ if registry.is_global == true then
+ registry.global_options[key] = value
+ else
+ registry.local_options[key] = value
+ end
+end
+% \end{macrocode}
+%
+% \clozeluafunction{set\_is\_global}
+% |registry.set_is_global()| sets the variable |registry.is_global| to
+% the value |value|. It is intended, that the variable takes boolean
+% values.
+% \begin{macrocode}
+function registry.set_is_global(value)
+ registry.is_global = value
+end
+% \end{macrocode}
+%
+% \clozeluafunction{unset\_local\_options}
+% This function unsets the local options.
+% \begin{macrocode}
+function registry.unset_local_options()
+ registry.local_options = {}
+end
+% \end{macrocode}
+%
+% \clozeluafunction{unset\_global\_options}
+% |registry.unset_global_options| empties the global options storage.
+% \begin{macrocode}
+function registry.unset_global_options()
+ registry.global_options = {}
+end
+% \end{macrocode}
+%
+% \clozeluafunction{get\_value}
+% Retrieve a value from a given key. First search for the value in the
+% local options, then in the global options. If both option storages are
+% empty, the default value will be returned.
+% \begin{macrocode}
+function registry.get_value(key)
+ if registry.has_value(registry.local_options[key]) then
+ return registry.local_options[key]
+ end
+ if registry.has_value(registry.global_options[key]) then
+ return registry.global_options[key]
+ end
+ return registry.defaults[key]
+end
+% \end{macrocode}
+%
+% \clozeluafunction{get\_value\_show}
+% The function |registry.get_value_show()| returns the boolean value
+% |true| if the option |show| is true. In contrast to the function
+% |registry.get_value()| it converts the string value `true' to a
+% boolean value.
+% \begin{macrocode}
+function registry.get_value_show()
+ if
+ registry.get_value('show') == true
+ or
+ registry.get_value('show') == 'true'
+ then
+ return true
+ else
+ return false
+ end
+end
+% \end{macrocode}
+%
+% \clozeluafunction{has\_value}
+% This function tests whether the value |value| is not empty and has a
+% value.
+% \begin{macrocode}
+function registry.has_value(value)
+ if value == nil or value == '' or value == '\\color@ ' then
+ return false
+ else
+ return true
+ end
+end
+% \end{macrocode}
+%
+% \clozeluafunction{get\_defaults}
+% |registry.get_defaults(option)| returns a the default value of the
+% given option.
+% \begin{macrocode}
+function registry.get_defaults(option)
+ return registry.defaults[option]
+end
+% \end{macrocode}
+%
+% \subsubsection{Assembly to cloze texts (cloze)}
+%
+% Some graphics for better understanding of the node tree:
+%
+% \paragraph{Paragraph}
+%
+% \noindent\includegraphics[width=\linewidth]{graphics/par}
+%
+% \paragraph{Tabular environment}
+%
+% \noindent\includegraphics[width=\linewidth]{graphics/tabular}
+%
+% \paragraph{Picture environment}
+%
+% \noindent\includegraphics[width=\linewidth]{graphics/picture}
+%
+% \clozeluafunction{basic\_make}
+% The function |cloze.basic_make()| makes one gap. The argument |start|
+% is the node, where the gap begins. The argument |stop| is the node,
+% where the gap ends.
+% \begin{macrocode}
+function cloze.basic_make(start, stop)
+ local n = {}
+ local l = {}
+ n.head = start
+ if not start or not stop then
+ return
+ end
+ n.start = start
+ n.stop = stop
+ l.width = node.dimensions(
+ cloze.status.hlist.glue_set,
+ cloze.status.hlist.glue_sign,
+ cloze.status.hlist.glue_order,
+ n.start,
+ n.stop
+ )
+ n.line = nodex.insert_line(n.start, l.width)
+ n.color_text = nodex.insert_list('after', n.line, {nodex.create_color('text')})
+ if registry.get_value_show() then
+ nodex.insert_list('after', n.color_text, {nodex.create_kern(-l.width)})
+ nodex.insert_list('before', n.stop, {nodex.create_color('reset')}, n.head)
+ else
+ n.line.next = n.stop.next
+ n.stop.prev = n.line.prev
+ end
+% \end{macrocode}
+% I some edge cases the lua callbacks get fired up twice. After the
+% cloze has been created, the start and stop whatsit markers can be
+% deleted.
+% \begin{macrocode}
+ registry.remove_marker(n.start)
+ registry.remove_marker(n.stop)
+end
+% \end{macrocode}
+%
+% \clozeluafunction{basic\_search\_stop}
+% Search for a stop marker.
+% \begin{macrocode}
+function cloze.basic_search_stop(head)
+ local stop
+ while head do
+ cloze.status.continue = true
+ stop = head
+ if registry.check_marker(stop, 'basic', 'stop') then
+ cloze.status.continue = false
+ break
+ end
+ head = head.next
+ end
+ return stop
+end
+% \end{macrocode}
+%
+% \clozeluafunction{basic\_search\_start}
+% Search for a start marker. Also begin a new cloze, if the boolean
+% value |cloze.status.continue| is true. The knowledge of the last
+% hlist node is a requirement to begin a cloze.
+% \begin{macrocode}
+function cloze.basic_search_start(head)
+ local start
+ local stop
+ local n = {}
+ if cloze.status.continue then
+ n.hlist = nodex.search_hlist(head)
+ if n.hlist then
+ cloze.status.hlist = n.hlist
+ start = cloze.status.hlist.head
+ end
+ elseif registry.check_marker(head, 'basic', 'start') then
+ start = head
+ end
+ if start then
+ stop = cloze.basic_search_stop(start)
+ cloze.basic_make(start, stop)
+ end
+end
+% \end{macrocode}
+%
+% \clozeluafunction{basic\_recursion}
+% Parse recursivley the node tree. Start and stop markers can be nested
+% deeply into the node tree.
+% \begin{macrocode}
+function cloze.basic_recursion(head)
+ while head do
+ if head.head then
+ cloze.status.hlist = head
+ cloze.basic_recursion(head.head)
+ else
+ cloze.basic_search_start(head)
+ end
+ head = head.next
+ end
+end
+% \end{macrocode}
+%
+% \clozeluafunction{basic}
+% The corresponding \LaTeX{} command to this lua function is \cmd{\cloze}
+% \secref{sec:command-cloze}. The argument |head| is the head node of a
+% node list.
+% \begin{macrocode}
+function cloze.basic(head)
+ cloze.status.continue = false
+ cloze.basic_recursion(head)
+ return head
+end
+% \end{macrocode}
+%
+% \clozeluafunction{fix\_length}
+% Calculate the length of the whitespace before (|l.kern_start|) and
+% after (|l.kern_stopt|) the text.
+% \begin{macrocode}
+function cloze.fix_length(start, stop)
+ local l = {}
+ l.width = tex.sp(registry.get_value('width'))
+ l.text_width = node.dimensions(start, stop)
+ l.align = registry.get_value('align')
+ if l.align == 'right' then
+ l.kern_start = - l.text_width
+ l.kern_stop = 0
+ elseif l.align == 'center' then
+ l.half = (l.width - l.text_width) / 2
+ l.kern_start = - l.half - l.text_width
+ l.kern_stop = l.half
+ else
+ l.kern_start = - l.width
+ l.kern_stop = l.width - l.text_width
+ end
+ return l.width, l.kern_start, l.kern_stop
+end
+% \end{macrocode}
+%
+% \clozeluafunction{fix\_make}
+% The function |cloze.fix_make| generates a gap of fixed width.
+%
+% \subparagraph*{Node lists}
+%
+% \subparagraph*{Show text:}
+%
+% \begin{nodelist}
+% |n.start| & |whatsit| & |user_definded| & |index| \\
+% |n.line| & |rule| & & |l.width| \\
+% |n.kern_start| & |kern| & & Depends on |align| \\
+% |n.color_text| & |whatsit| & |pdf_colorstack| & Text color \\
+% & |glyphs| & & Text to show \\
+% |n.color_reset| & |whatsit| & |pdf_colorstack| & Reset color \\
+% |n.kern_stop| & |kern| & & Depends on |align| \\
+% |n.stop| & |whatsit| & |user_definded| & |index| \\
+% \end{nodelist}
+%
+% \subparagraph*{Hide text:}
+%
+% \begin{nodelist}
+% |n.start| & |whatsit| & |user_definded| & |index| \\
+% |n.line| & |rule| & & |l.width| \\
+% |n.stop| & |whatsit| & |user_definded| & |index| \\
+% \end{nodelist}
+%
+% The argument |start| is the node, where the gap begins. The argument
+% |stop| is the node, where the gap ends.
+% \begin{macrocode}
+function cloze.fix_make(start, stop)
+ local l = {} -- length
+ local n = {} -- node
+ l.width, l.kern_start, l.kern_stop = cloze.fix_length(start, stop)
+ n.line = nodex.insert_line(start, l.width)
+ if registry.get_value_show() then
+ nodex.insert_list(
+ 'after',
+ n.line,
+ {
+ nodex.create_kern(l.kern_start),
+ nodex.create_color('text')
+ }
+ )
+ nodex.insert_list(
+ 'before',
+ stop,
+ {
+ nodex.create_color('reset'),
+ nodex.create_kern(l.kern_stop)
+ },
+ start
+ )
+ else
+ n.line.next = stop.next
+ end
+ registry.remove_marker(start)
+ registry.remove_marker(stop)
+end
+% \end{macrocode}
+%
+% \clozeluafunction{fix\_recursion}
+% Function to recurse the node list and search after marker. |head| is
+% the head node of a node list.
+% \begin{macrocode}
+function cloze.fix_recursion(head)
+ local n = {} -- node
+ n.start, n.stop = false
+ while head do
+ if head.head then
+ cloze.fix_recursion(head.head)
+ else
+ if not n.start then
+ n.start = registry.get_marker(head, 'fix', 'start')
+ end
+ if not n.stop then
+ n.stop = registry.get_marker(head, 'fix', 'stop')
+ end
+ if n.start and n.stop then
+ cloze.fix_make(n.start, n.stop)
+ n.start, n.stop = false
+ end
+ end
+ head = head.next
+ end
+end
+% \end{macrocode}
+%
+% \clozeluafunction{fix}
+% The corresponding \LaTeX{} command to this Lua function is
+% \cmd{\clozefix} \secref{sec:command-clozefix}. The argument |head| is
+% the head node of a node list.
+% \begin{macrocode}
+function cloze.fix(head)
+ cloze.fix_recursion(head)
+ return head
+end
+% \end{macrocode}
+%
+% \clozeluafunction{par}
+% The corresponding \LaTeX{} environment to this lua function is
+% |clozepar| \secref{sec:command-clozepar}.
+%
+% \subparagraph*{Node lists}
+%
+% \subparagraph*{Show text:}
+%
+% \begin{nodelist}
+% |n.strut| & |kern| & & width = 0 \\
+% |n.line| & |rule| & & |l.width| (Width from hlist) \\
+% |n.kern| & |kern| & & |-l.width| \\
+% |n.color_text| & |whatsit| & |pdf_colorstack| & Text color \\
+% & |glyphs| & & Text to show \\
+% |n.tail| & |glyph| & & Last glyph in hlist \\
+% |n.color_reset| & |whatsit| & |pdf_colorstack| & Reset color \\
+% \end{nodelist}
+%
+% \subparagraph*{Hide text:}
+%
+% \begin{nodelist}
+% |n.strut| & |kern| & & width = 0 \\
+% |n.line| & |rule| & & |l.width| (Width from hlist) \\
+% \end{nodelist}
+%
+% The argument |head| is the head node of a node list.
+% \begin{macrocode}
+function cloze.par(head)
+ local l = {} -- length
+ local n = {} -- node
+ for hlist in node.traverse_id(node.id('hlist'), head) do
+ for whatsit in node.traverse_id(node.id('whatsit'), hlist.head) do
+ registry.get_marker(whatsit, 'par', 'start')
+ end
+ l.width = hlist.width
+ hlist, n.strut, n.head = nodex.strut_to_hlist(hlist)
+ n.line = nodex.insert_line(n.strut, l.width)
+ if registry.get_value_show() then
+ nodex.insert_list(
+ 'after',
+ n.line,
+ {
+ nodex.create_kern(-l.width),
+ nodex.create_color('text')
+ }
+ )
+ nodex.insert_list(
+ 'after',
+ node.tail(head),
+ {nodex.create_color('reset')}
+ )
+ else
+ n.line.next = nil
+ end
+ end
+ return head
+end
+% \end{macrocode}
+%
+% \subsubsection{Basic module functions (base)}
+%
+% The |base| table contains functions which are published to the
+% |cloze.sty| file.
+%
+% \clozeluafunction{register}
+% This function registers the functions |cloze.par|, |cloze.basic| and
+% |cloze.fix| the Lua callbacks. |cloze.par| and |cloze.basic| are
+% registered to the callback |post_linebreak_filter| and |cloze.fix| to
+% the callback |pre_linebreak_filter|. The argument |mode| accepts the
+% string values |basic|, |fix| and |par|.
+% \begin{macrocode}
+function base.register(mode)
+ local basic
+ if mode == 'par' then
+ luatexbase.add_to_callback(
+ 'post_linebreak_filter',
+ cloze.par,
+ mode
+ )
+ return true
+ end
+ if not base.is_registered[mode] then
+ if mode == 'basic' then
+ luatexbase.add_to_callback(
+ 'post_linebreak_filter',
+ cloze.basic,
+ mode
+ )
+ elseif mode == 'fix' then
+ luatexbase.add_to_callback(
+ 'pre_linebreak_filter',
+ cloze.fix,
+ mode
+ )
+ else
+ return false
+ end
+ base.is_registered[mode] = true
+ end
+end
+% \end{macrocode}
+%
+% \clozeluafunction{unregister}
+% |base.unregister(mode)| deletes the registered functions from the Lua
+% callbacks. The argument |mode| accepts the string values |basic|,
+% |fix| and |par|.
+% \begin{macrocode}
+function base.unregister(mode)
+ if mode == 'basic' then
+ luatexbase.remove_from_callback('post_linebreak_filter', mode)
+ elseif mode == 'fix' then
+ luatexbase.remove_from_callback('pre_linebreak_filter', mode)
+ else
+ luatexbase.remove_from_callback('post_linebreak_filter', mode)
+ end
+end
+% \end{macrocode}
+%
+% Publish some functions to the |cloze.sty| file.
+% \begin{macrocode}
+base.linefil = nodex.write_linefil
+base.line = nodex.write_line
+base.margin = nodex.write_margin
+base.set_option = registry.set_option
+base.set_is_global = registry.set_is_global
+base.unset_local_options = registry.unset_local_options
+base.reset = registry.unset_global_options
+base.get_defaults = registry.get_defaults
+base.marker = registry.write_marker
+% \end{macrocode}
+%
+% \begin{macrocode}
+return base
+% \end{macrocode}
+% \iffalse
+%</lua>
+% \fi
+%
+% \Finale
+\endinput
diff --git a/macros/luatex/latex/cloze/cloze.ins b/macros/luatex/latex/cloze/cloze.ins
new file mode 100644
index 0000000000..87a4e09d25
--- /dev/null
+++ b/macros/luatex/latex/cloze/cloze.ins
@@ -0,0 +1,61 @@
+% Copyright (C) 2015-2016 by Josef Friedrich <josef@friedrich.rocks>
+% ----------------------------------------------------------------------
+% This work may be distributed and/or modified under the conditions of
+% the LaTeX Project Public License, either version 1.3c of this license
+% or (at your option) any later version. The latest version of this
+% license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008/05/05 or later.
+
+
+\input docstrip.tex
+\keepsilent
+
+\usedir{tex/lualatex/cloze}
+
+\askforoverwritefalse
+
+\preamble
+
+This is a generated file.
+
+Copyright (C) 2015-2016 by Josef Friedrich <josef@friedrich.rocks>
+----------------------------------------------------------------------
+This work may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3c of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of LaTeX
+version 2008/05/05 or later.
+
+\endpreamble
+
+\generate{\file{cloze.sty}{\from{cloze.dtx}{package}}}
+
+\nopreamble
+\nopostamble
+\generate{\file{cloze.lua}{\from{cloze.dtx}{lua}}}
+\generate{\file{README.md}{\from{cloze.dtx}{readme}}}
+
+\obeyspaces
+\Msg{*************************************************************}
+\Msg{* *}
+\Msg{* To finish the installation you have to move the following *}
+\Msg{* file into a directory searched by TeX: *}
+\Msg{* *}
+\Msg{* cloze.sty *}
+\Msg{* *}
+\Msg{* To produce the documentation run the file cloze.dtx *}
+\Msg{* through LaTeX. *}
+\Msg{* *}
+\Msg{* Happy TeXing! *}
+\Msg{* *}
+\Msg{*************************************************************}
+
+\endbatchfile
diff --git a/macros/luatex/latex/cloze/cloze.pdf b/macros/luatex/latex/cloze/cloze.pdf
new file mode 100644
index 0000000000..a3af3efb6d
--- /dev/null
+++ b/macros/luatex/latex/cloze/cloze.pdf
Binary files differ
diff --git a/macros/luatex/latex/combofont/README.md b/macros/luatex/latex/combofont/README.md
new file mode 100644
index 0000000000..10a189f3da
--- /dev/null
+++ b/macros/luatex/latex/combofont/README.md
@@ -0,0 +1,24 @@
+# The combofont package
+
+An EXPERIMENTAL package to add nfss-declaration of combo fonts to a luaLaTeX document
+
+Version 0.3 2019/06/08
+copyright Ulrike Fischer
+
+
+## License
+
+LATEX Project Public License 1.3c.
+
+## Contents
+
+- Readme.md (this file)
+- combofont.sty (the sty)
+- combofont.tex, combofont.pdf (the docu and example)
+- combofont-test-fira-math.tex and pdf (and example for math)
+
+
+## Installation
+
+Put the sty where it can be found.
+
diff --git a/macros/luatex/latex/combofont/combofont-test-fira-math.pdf b/macros/luatex/latex/combofont/combofont-test-fira-math.pdf
new file mode 100644
index 0000000000..c5a83a5c1f
--- /dev/null
+++ b/macros/luatex/latex/combofont/combofont-test-fira-math.pdf
Binary files differ
diff --git a/macros/luatex/latex/combofont/combofont-test-fira-math.tex b/macros/luatex/latex/combofont/combofont-test-fira-math.tex
new file mode 100644
index 0000000000..75d2f39c16
--- /dev/null
+++ b/macros/luatex/latex/combofont/combofont-test-fira-math.tex
@@ -0,0 +1,125 @@
+% !Mode:: "TeX:DE:UTF-8:Main"
+%% Date 2017/07/03 Version 0.2 combofont example
+\documentclass[parskip=full]{scrartcl}
+
+\usepackage{luacode}
+
+%As a test I patch the FraktionNumeratorShift by a large value
+% and add it to the luaotfload patch_font callback:
+\begin{luacode}
+
+local patch_texgyrepagellamath = function (fontdata)
+ local mathconstants = fontdata.MathConstants
+ if mathconstants and fontdata.psname == "TeXGyrePagellaMath-Regular"
+ then
+ mathconstants.FractionNumeratorDisplayStyleShiftUp=5.5*mathconstants.FractionNumeratorDisplayStyleShiftUp
+ mathconstants.FractionNumeratorShiftUp=5.5*mathconstants.FractionNumeratorShiftUp
+ end
+end
+
+
+luatexbase.add_to_callback
+ (
+ "luaotfload.patch_font",
+ patch_texgyrepagellamath,
+ "change_texgyrepagellamath"
+ )
+\end{luacode}
+
+\usepackage[math-style=upright]{unicode-math}
+\usepackage{combofont}
+
+\setmainfont{Fira Sans}
+
+
+\setupcombofont{FiraMath}
+ {%
+ file:texgyrepagella-math.otf:mode=base;script=math;language=DFLT; at #1pt,
+ file:firasans-light.otf at #1pt,
+ file:firasans-lightitalic.otf at #1pt
+ }
+ {%
+ {},
+ 0x30-0x39,
+ 0x61-0x7A*0x03B1-0x03C9
+ }
+
+\setupcombofont{FiraMathScript}
+ {%
+ file:texgyrepagella-math.otf:mode=base;script=math;language=DFLT;+ssty=0 at #1pt,
+ file:firasans-regular.otf at #1pt,
+ file:firasans-italic.otf at #1pt
+ }
+ {%
+ {},
+ 0x30-0x39,
+ 0x61-0x7A*0x03B1-0x03C9
+ }
+
+\setupcombofont{FiraMathScriptScript}
+ {%
+ file:texgyrepagella-math.otf:mode=base;script=math;language=DFLT;+ssty=1 at #1pt,
+ file:firasans-semibold.otf at #1pt,
+ file:firasans-semibolditalic.otf at #1pt
+ }
+ {%
+ {},
+ 0x30-0x39,
+ 0x61-0x7A*0x03B1-0x03C9
+ }
+
+% Mathversion bold need Script and ScriptScript declarations too!
+\setupcombofont{FiraMathBold}
+ {%
+ file:texgyrepagella-math.otf:mode=base;script=math;language=DFLT; at #1pt,
+ file:firasans-regular.otf at #1pt,
+ file:firasans-italic.otf at #1pt
+ }
+ {%
+ {},
+ 0x30-0x39,
+ 0x61-0x7A*0x03B1-0x03C9
+ }
+
+
+\DeclareFontFamily{TU}{FiraMath}{}
+\DeclareFontShape {TU}{FiraMath}{m}{n}
+ {
+ <-7> combo*FiraMathScriptScript
+ <7-10>combo*FiraMathScript
+ <10-> combo*FiraMath
+ }{}
+
+\DeclareFontShape {TU}{FiraMath}{bx}{n} {<->combo*FiraMathBold}{}
+
+% better start with a real math font, so that
+% unicode sets everything up
+\setmathfont{TeX Gyre Pagella Math}%
+
+% Perhaps some other symbol fonts will need setup too
+\SetSymbolFont{operators}{normal}{TU}{FiraMath}{m}{n}
+\SetSymbolFont{operators}{bold}{TU}{FiraMath}{bx}{n}
+
+
+% Map "a" etc to the ascii range. Original values can be found with
+%[\Umathcharclass `\a] [\Umathcharfam `\a] [\Umathcharslot `\a]
+% not needed because of math-style=upright
+%\Umathcode `\a = "7 "0 "61
+
+
+\begin{document}
+
+\minisec{Test some symbols}
+
+$123 - a^{a^a} + 1^{1^1} abc = \sqrt{hhhhhhhhhhh}$
+
+\minisec{Test patching}
+
+$\frac{1}{9}$
+
+\minisec{Test math version}
+
+\mathversion{bold}
+$123 - a^{a^a} + 1^{1^1} abc = \frac{1}{9} $
+
+\end{document}
diff --git a/macros/luatex/latex/combofont/combofont.pdf b/macros/luatex/latex/combofont/combofont.pdf
new file mode 100644
index 0000000000..54b9763a34
--- /dev/null
+++ b/macros/luatex/latex/combofont/combofont.pdf
Binary files differ
diff --git a/macros/luatex/latex/combofont/combofont.sty b/macros/luatex/latex/combofont/combofont.sty
new file mode 100644
index 0000000000..24572b1f77
--- /dev/null
+++ b/macros/luatex/latex/combofont/combofont.sty
@@ -0,0 +1,106 @@
+% !Mode:: "TeX:DE:UTF-8:Main"
+%28.05.2018
+\def\UlrikeFischer@package@ufcombofont@date{2019/06/08}\def\UlrikeFischer@package@ufcombofont@version{0.3}
+
+\RequirePackage{xparse}
+\ProvidesExplPackage {combofont} {\UlrikeFischer@package@ufcombofont@date}{\UlrikeFischer@package@ufcombofont@version}
+ {An EXPERIMENTAL package to add nfss-declaration of combo fonts to a luaLaTeX document}
+% highly experimental! Comments to Ulrike Fischer. fischer@troubleshooting-tex.de
+\prop_if_exist:NT \g_msg_module_name_prop
+ {
+ \prop_gput:Nnn \g_msg_module_name_prop { ufcombo }{ combofont }
+ }
+
+\msg_new:nnn {ufcombo} {need-luatex}
+ {
+ The~ combofont~package~requires~LuaLaTeX.~Quitting.
+ }
+
+\msg_new:nnn {ufcombo} {combofont-already-exists}
+ {
+ The~combofont~#1~has~already~been~set~up.~I~won't~overwrite~it
+ }
+
+\sys_if_engine_luatex:F
+ {
+ \msg_fatal:nn {ufcombo} {need-luatex}
+ \endinput
+ }
+
+\RequirePackage{xfp}
+
+\cs_generate_variant:Nn \seq_set_split:Nnn {cnV}
+
+\NewDocumentCommand\setupcombofont { m m m } %name, basefonts, combofont declaration
+ {
+ \tl_set:Nn\l_tmpa_tl { #2 }
+ \regex_replace_all:nnN {\#1} {\c{f@size}} \l_tmpa_tl
+ % \tl_show:N\l_tmpa_tl
+ \seq_if_exist:cTF { l__ufcombo_#1_basefonts_seq }
+ {
+ \msg_warning:nnn { ufcombo} {combofont-already-exists} { #1 }
+ }
+ {
+ \seq_new:c { l__ufcombo_#1_basefonts_seq }
+ \seq_set_split:cnV { l__ufcombo_#1_basefonts_seq } { , }\l_tmpa_tl
+ %%\seq_show:c {l__ufcombo_#1_basefonts_seq }
+ \seq_new:c { l__ufcombo_#1_combodesc_seq }
+ \seq_set_from_clist:cn { l__ufcombo_#1_combodesc_seq } { #3 }
+ %%\seq_show:c { l__ufcombo_#1_combodesc_seq }
+ \__ufcombo_build_combodesc:n { #1 }
+ }
+ }
+
+
+\cs_new:Nn \__ufcombo_call_basefonts:n
+ {
+ \int_zero:N \l_tmpa_int
+ \seq_map_inline:cn {l__ufcombo_#1_basefonts_seq}
+ {
+ \int_incr:N \l_tmpa_int
+ \exp_args:Nc \font { l__ufcombo_tmpfont_\int_to_roman:n{\l_tmpa_int}_tl } = ##1
+ }
+ }
+
+
+
+
+
+
+\cs_new:Nn \__ufcombo_build_combodesc:n
+ {
+ \tl_new:c { l__ufcombo_#1_combodesc_tl }
+ \tl_set:cx { l__ufcombo_#1_combodesc_tl } { \tl_to_str:n { " } combo \tl_to_str:n { : }~ }
+ \int_step_inline:nnnn { 1 } { 1 } { \seq_count:c { l__ufcombo_#1_basefonts_seq } }
+ {
+ \tl_put_right:cn { l__ufcombo_#1_combodesc_tl } { ##1~->~\fontid }
+ \exp_args:Nnc \tl_put_right:cn { l__ufcombo_#1_combodesc_tl }
+ {
+ l__ufcombo_tmpfont_\int_to_roman:n{##1}_tl
+ }
+ \tl_set:Nx\l_tmpa_tl { \seq_item:cn {l__ufcombo_#1_combodesc_seq } {##1} }
+ \tl_if_empty:NF \l_tmpa_tl
+ {
+ \tl_put_right:cx { l__ufcombo_#1_combodesc_tl}
+ {
+ ,~ \seq_item:cn {l__ufcombo_#1_combodesc_seq } {##1}
+ }
+ }
+ \tl_put_right:cx { l__ufcombo_#1_combodesc_tl} {\tl_to_str:n{;}}
+ }
+ \tl_put_right:cx { l__ufcombo_#1_combodesc_tl } { \tl_to_str:n { " } }
+ %% \tl_show:c { l__ufcombo_#1_combodesc_tl }
+ }
+
+\DeclareSizeFunction{combo}{\__ufcombo_sfcnt:}
+
+\cs_new:Nn\__ufcombo_sfcnt:
+ {
+ % \tl_show:c {l__ufcombo_\use:c{mandatory@arg}_combodesc_tl}
+ \__ufcombo_call_basefonts:n { \mandatory@arg }
+ \tl_set_eq:Nc \external@font { l__ufcombo_\use:c{mandatory@arg}_combodesc_tl}
+ }%
+
+\tl_new:N\combodefaultfeat
+\tl_set:Nn\combodefaultfeat{mode=node;script=latn;language=DFLT;+tlig;}
+\endinput
diff --git a/macros/luatex/latex/combofont/combofont.tex b/macros/luatex/latex/combofont/combofont.tex
new file mode 100644
index 0000000000..88ceecdf78
--- /dev/null
+++ b/macros/luatex/latex/combofont/combofont.tex
@@ -0,0 +1,217 @@
+% !Mode:: "TeX:DE:UTF-8:Main"
+\documentclass[parskip=half-,egregdoesnotlikesansseriftitles]{scrartcl}
+\usepackage{combofont}
+\usepackage{ydoc-code,ydoc-desc}
+\usepackage[english]{babel}
+\usepackage[autostyle]{csquotes}
+\usepackage{fontspec}
+
+\usepackage{xcolor}
+
+
+\setupcombofont{combotest-regular}
+ {
+ {file:lmroman10-regular.otf:\combodefaultfeat} at #1pt,
+ {file:lmsans10-regular.otf} at \fpeval{#1/10*15}pt,
+ {file:cmunrm.otf} at #1pt
+ }
+ {
+ {} ,
+ 0x41-0x5A*0x21*0x3F,
+ fallback
+ }
+
+\setupcombofont{combotest-bold}
+ {
+ {file:lmroman10-bold.otf:\combodefaultfeat} at #1pt,
+ {file:lmsans10-bold.otf} at \fpeval{#1/10*15}pt,
+ {file:cmunbbx.otf} at #1pt
+ }
+ {
+ {} ,
+ 0x41-0x5A*0x21*0x3F,
+ fallback
+ }
+
+
+
+\DeclareFontFamily{TU}{combotest}{}
+\DeclareFontShape{TU} {combotest}{m}{n}{<->combo*combotest-regular}{}
+\DeclareFontShape{TU} {combotest}{bx}{n}{<->combo*combotest-bold}{}
+
+\title{The \texttt{combofont} package \\
+{\normalsize Version \csname UlrikeFischer@package@ufcombofont@version\endcsname\
+from \csname UlrikeFischer@package@ufcombofont@date\endcsname}}
+\author{Ulrike Fischer\thanks{fischer@troubleshooting-tex.de}}
+\newcommand\package[1]{\texttt{#1}}
+\begin{document}
+\maketitle
+
+\section{Status: EXPERIMENTAL}
+
+This is an EXPERIMENTAL package.
+
+It can disappear without notice e.\,g. if the \package{luaotfload} changes so that it no longer works, or if luatex changes, or if \package{fontspec} includes the code.
+
+It is also possible that syntax and commands change in an incompatible way. So if you use it in a production environment: \textbf{You have been warned}.
+
+\section{Introduction}
+In version 2.7 \package{luaotfload} supports combining characters from multiple fonts into a single virtualized one.
+
+That means that one can build a font that takes e.g. the capital letters from a sans serif font and the lowercase letters from a serif font. Or a font that pulls in missing greek or cyrillic glyphs from another font.
+
+The method pulls in \emph{only} glyphs. It is not suitable for every imaginable font combination -- some drawbacks are described below -- and one should use it with care. Nevertheless it is a quite neat extension of the tools to manipulate fonts.
+
+The main problem with the examples in the \package{luaotfload} manual is that they create fonts of a fix size. This means that they don't respond to command like \verb+\large+ or \verb+\footnotesize+.
+
+After trying around a bit and then asking a question (https://tex.stackexchange.com/questions/371647/call-a-luatex-combo-font-through-nfss) I got from David Carlisle the idea to use a \texttt{size}-Funktion which one defines with \verb+\DeclareSizeFunction+ to inject the needed code to size the combo-font in a nfss-\verb+\DeclareFontShape+-command.
+
+\package{combofont.sty} is the result.
+
+It is not meant as a production package but as package that helps to exploit the use of combo fonts.
+
+\section{Requirements}
+You need at least an up-to-date TeXLive 2016. TeXLive 2017 with luatex 1.0.4 or a current miktex is better.
+
+\textbf{Change Version 0.2, 3.7.2017}: The style no longer loads the now obsolete \texttt{l3regex}, it assumes that it is loaded by \texttt{expl3}. In older \TeX-systems you will have to load the package.
+
+
+\section{Using combo fonts}
+
+To be able to use a combo font with standard \LaTeX\ font commands you have to do two things (the source code of this documentation is a complete example):
+
+\begin{enumerate}
+\item Setup and describe the building of the combo font with \verb+\setupcombofont+
+
+\item Write \texttt{nfss}-declarations
+\end{enumerate}
+
+\subsection{Setup the combo font}
+
+\DescribeMacro\setupcombofont{<name>}{<comma list of basefonts>}{<comma list of ranges and code-points>}
+
+\begin{description}
+ \item[\marg{name}] is the name of the font. It should be some unique ascii-string without spaces. If you intend to define lots of fonts it would be a good idea to think about a sensible naming sheme. In the example here I simply used \texttt{combotest-regular} and \texttt{combotest-bold}.
+
+ \item[\marg{comma list of basefonts}] This should be a list of font declarations you want to use to build your combo font. The syntax used is described in the \package{luaotfload} manual. Example:
+
+\begin{verbatim}
+{
+ {file:lmroman10-regular.otf:\combodefaultfeat} at #1pt,
+ {file:lmsans10-regular.otf} at \fpeval{#1/10*15}pt,
+ {file:cmunrm.otf} at #1pt
+}
+\end{verbatim}
+
+\minisec{Important points are:}
+\begin{description}
+\item[Order of the fonts] The first font is the main font which will receive the glyphs. So think carefully which font is should be and setup its font features correctly. \package{combofont} defines as a helper command \verb+\combodefaultfeat+ which sets \texttt{mode=node;script=latn;language=DFLT;+tlig;}.
+
+\item[Size declaration] The font description should end with a size declaration line \verb+at #1pt+. When processing the font \verb+#1+ will be replaced by the current font size. As you can see in the second font you can do calculations. \emph{Don't forget the size declaration!}
+
+\item Be careful with the commas: there shouldn't be one after the last font.
+\end{description}
+
+\item[\marg{comma list of ranges and code-points}] This is a comma list of settings which describe which glyphs are taken from the respective font. Example:
+
+\begin{verbatim}
+{
+ {} ,
+ 0x41-0x5A*0x21*0x3F,
+ fallback
+}
+\end{verbatim}
+
+\minisec{Important points:}
+\begin{enumerate}
+\item There should be as many settings as there are fonts.
+\item Empty entries should be marked with a pair of braces (normally the first entry is empty).
+\item You can add ranges of code points and single code points. Blocks are separated by an asterix \verb+*+. The example set the uppercase letters and the exclamation and the question mark.
+\item The keyword \texttt{fallback} means that this font is used for \enquote{missing glyphs} (in the example for the cyrillic glyphs).
+\end{enumerate}
+\end{description}
+
+\subsection{Write \texttt{nfss}-declarations}
+
+After all the fonts you need have been setup, you can write suitable \texttt{nfss}-declarations which make it possible to call the font by family and other font commands. Example:
+
+\begin{verbatim}
+\DeclareFontFamily{TU}{combotest}{}
+\DeclareFontShape {TU}{combotest}{m}{n} {<->combo*combotest-regular}{}
+\DeclareFontShape {TU}{combotest}{bx}{n}{<->combo*combotest-bold}{}
+\end{verbatim}
+
+The important point is the size-function \verb+combo*+ which does all the work.
+
+
+\section{Demonstration}
+
+
+\verb+\fontfamily{combotest}\selectfont+:
+\fontfamily{combotest}\selectfont
+Some Text with Capital Words!
+Eh bien, mon prince. Gênes et Lueques ne sont plus que des
+apanages, des помеÑÑ‚ÑŒÑ, de la famille Buonaparte?
+%
+
+\verb+\large+\large:
+Some Text with Capital Words!
+Eh bien, mon prince. Gênes et Lueques ne sont plus que des
+apanages, des помеÑÑ‚ÑŒÑ, de la famille Buonaparte?
+
+\verb+\tiny+\tiny:
+Some Text with Capital Words!
+Eh bien, mon prince. Gênes et Lueques ne sont plus que des
+apanages, des помеÑÑ‚ÑŒÑ, de la famille Buonaparte?
+
+\verb+\bfseries\normalsize+\bfseries
+\normalsize:
+Some Text with Capital Words!
+Eh bien, mon prince. Gênes et Lueques ne sont plus que des
+apanages, des помеÑÑ‚ÑŒÑ, de la famille Buonaparte?
+
+
+\verb+\tiny+\tiny:
+Some Text with Capital Words!
+Eh bien, mon prince. Gênes et Lueques ne sont plus que des
+apanages, des помеÑÑ‚ÑŒÑ, de la famille Buonaparte?
+%
+
+\normalfont\normalsize
+
+\section{About Math (new in version 0.2)}\enlargethispage{2\baselineskip}
+
+Combofonts can also be used in math. There is a test file called \texttt{combofont-test-fira-math.tex} which shows how one can combine \textsf{TeX Gyre Pagella Math} with the \textsf{Fira Sans} textfont. It also shows how one can patch the font to adjust values of the math table.
+
+\minisec{Important points:}
+\begin{enumerate}
+\item This a first try to get something working in math. It is in no way finished or complete, I'm rather certain that something will be missing or even faulty.
+\item Start with a real math font with a math constants table.
+\item Don't expect to get a perfect sans serif math font this way without work. It can take quite some time to adjust everything. Also a text font is not really meant to be used as math font.
+\item The lua-code for the font patch compares \texttt{fontdata.psname} with the string \\\texttt{TeXGyrePagellaMath-Regular} to restrict the patch to the specific font.
+
+ The font name database of luaotfload-names.lua contains for \textsf{TeX Gyre Pagella Math} these entries:
+
+ \begin{verbatim}
+ ["plainname"]="TeXGyrePagellaMath-Regular",
+ ["psname"]="texgyrepagellamathregular",
+ \end{verbatim}
+
+ As you can see the correct string for the comparision with \texttt{fontdata.psname} is in \verb+["plainname"]+ and not in \verb+["psname"]+. Don't ask me why. \texttt{luaotfload} seems to copy the infos around quite a lot. So when adapting the code to other fonts, test with various font names if it seems not to work.
+\end{enumerate}
+
+
+\section{Remarks and open questions}
+
+As mentioned in the introduction a combo font only pulls in glyphs. This has a lot of (not all yet understood or seen) side effects. Here a few things that should be considered when building a combo font:
+
+\begin{description}
+ \item[Kerning] Obviously some kerning works (see e.g. the large W before the o in the demonstration). But it is quite unclear which values are used, how bad it can get and if one can correct it.
+ \item[Font features] Only font features of the first font are taken into account. E.g. adding a color setting has an effect only if applied to the first font and then colors all glyphs. \verb!+smcp! (the open type small caps feature) only has an effect if the first font knows it. Mixing scripts and languages is probably not possible (but I didn't try yet).
+ \item[Speed] I didn't try to optimize the loading of the fonts.
+ \item[Pulling glyphs in other positions] One interesting question would if it is possible to switch glyph positions before or after the pull. E.g. if one could move the chars a-z from a sans serif text font to the math sans serif positions.
+ \item[Side effects] I naturally directly found a side-effect of such a combo font declaration: https://github.com/lualatex/luaotfload/issues/414. So the question is if there are more.
+\end{description}
+\end{document}
+
+
diff --git a/macros/luatex/latex/gurps/README.md b/macros/luatex/latex/gurps/README.md
new file mode 100644
index 0000000000..e3d5897922
--- /dev/null
+++ b/macros/luatex/latex/gurps/README.md
@@ -0,0 +1,19 @@
+| | |
+|-------:|------------------------------------------------------------------
+| gurps:| A LaTeX package for GURPS typesetting |
+| Author:| Nathanael Farley |
+| E-mail:| nasfarley88@gmail.com |
+|License:| Released under the LaTeX Project Public License v1.3c or later |
+| See:| http://www.latex-project.org/lppl.txt |
+
+This package supports typesetting Generic Universal Role Playing System (GURPS) materials. It provides many convenience commands (e.g. `\gurps`, `\SJGamesOnlinePolicy`) as well as limited NPC building capabilities with a character environment.
+
+The package requires the use of LuaLaTeX as several of the internal calculations are in Lua.
+
+----
+
+Disclaimer:
+The material presented here is the original creation of Nathanael Farley, intended for use with the <a href="http://www.sjgames.com/gurps/"><b><i>GURPS</i></b></a> system from <a href="http://www.sjgames.com/">Steve Jackson Games</a>. This material is not official and is not endorsed by Steve Jackson Games.
+
+Notice:
+<a href="http://www.sjgames.com/gurps/"><b><i>GURPS</i></b></a> is a registered trademark of Steve Jackson Games, and is copyrighted by Steve Jackson Games. All rights are reserved by SJ Games. This material is used here in accordance with the SJ Games <a href="http://www.sjgames.com/general/online_policy.html">online policy</a>.
diff --git a/macros/luatex/latex/gurps/gurps.dtx b/macros/luatex/latex/gurps/gurps.dtx
new file mode 100644
index 0000000000..83a77e10c7
--- /dev/null
+++ b/macros/luatex/latex/gurps/gurps.dtx
@@ -0,0 +1,416 @@
+% \iffalse meta-comment
+% vim: textwidth=75
+%<*internal>
+\iffalse
+%</internal>
+%<*readme>
+| | |
+|-------:|------------------------------------------------------------------
+| gurps:| A LaTeX package for GURPS typesetting |
+| Author:| Nathanael Farley |
+| E-mail:| nasfarley88@gmail.com |
+|License:| Released under the LaTeX Project Public License v1.3c or later |
+| See:| http://www.latex-project.org/lppl.txt |
+
+This package supports typesetting Generic Universal Role Playing System (GURPS) materials. It provides many convenience commands (e.g. `\gurps`, `\SJGamesOnlinePolicy`) as well as limited NPC building capabilities with a character environment.
+
+The package requires the use of LuaLaTeX as several of the internal calculations are in Lua.
+
+----
+
+Disclaimer:
+The material presented here is the original creation of Nathanael Farley, intended for use with the <a href="http://www.sjgames.com/gurps/"><b><i>GURPS</i></b></a> system from <a href="http://www.sjgames.com/">Steve Jackson Games</a>. This material is not official and is not endorsed by Steve Jackson Games.
+
+Notice:
+<a href="http://www.sjgames.com/gurps/"><b><i>GURPS</i></b></a> is a registered trademark of Steve Jackson Games, and is copyrighted by Steve Jackson Games. All rights are reserved by SJ Games. This material is used here in accordance with the SJ Games <a href="http://www.sjgames.com/general/online_policy.html">online policy</a>.
+%</readme>
+%<*internal>
+\fi
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+%</internal>
+%<*install>
+\input docstrip.tex
+\keepsilent
+\askforoverwritefalse
+\preamble
+-------:| -----------------------------------------------------------------
+ gurps:| A LaTeX package for GURPS typesetting
+ Author:| Nathanael Farley
+ E-mail:| nasfarley88@gmail.com
+License:| Released under the LaTeX Project Public License v1.3c or later
+ See:| http://www.latex-project.org/lppl.txt
+
+\endpreamble
+\postamble
+
+Copyright (C) 2017 by Nathanael Farley <nasfarley88@gmail.com>
+
+This work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License (LPPL), either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in the file:
+
+http://www.latex-project.org/lppl.txt
+
+This work is "maintained" (as per LPPL maintenance status) by
+Nathanael Farley.
+
+This work consists of the file gurps.dtx and a Makefile.
+Running "make" generates the derived files README, gurps.pdf and gurps.sty.
+Running "make inst" installs the files in the user's TeX tree.
+Running "make install" installs the files in the local TeX tree.
+
+\endpostamble
+
+\usedir{tex/latex/gurps}
+\generate{
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+%</install>
+%<install>\endbatchfile
+%<*internal>
+\usedir{source/latex/gurps}
+\generate{
+ \file{\jobname.ins}{\from{\jobname.dtx}{install}}
+}
+\nopreamble\nopostamble
+\usedir{doc/latex/gurps}
+\generate{
+ \file{README.md}{\from{\jobname.dtx}{readme}}
+}
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+%</internal>
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{gurps.dtx}
+%</driver>
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{gurps}
+%<*package>
+ [2018/02/14 v0.1.1 A LaTeX package for GURPS typesetting]
+%</package>
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[a4paper,margin=25mm,left=50mm,nohead]{geometry}
+\usepackage[numbered]{hypdoc}
+\usepackage{\jobname}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \GetFileInfo{\jobname.dtx}
+% \DoNotIndex{\newcommand,\newenvironment}
+%
+% \title{\textsf{gurps} --- A LaTeX package for GURPS typesetting\thanks{This file
+% describes version \fileversion, last revised \filedate.}
+%}
+%\author{Nathanael Farley\thanks{E-mail: nasfarley88@gmail.com}}
+%\date{Released \filedate}
+%
+%\maketitle
+%
+%\changes{v0.1}{2018/02/13}{First public release}
+%\changes{v0.1.1}{2018/02/14}{Minor changes to CTAN upload}
+%
+% \begin{abstract}
+% \textit{\textbf{GURPS}} is an excellent RPG system. \LaTeX{} is an excellent
+% typesetting system. Together, they make excellent game aids. At least, they
+% can with this package!
+% \end{abstract}
+%
+% \section{Usage}
+%
+% ==== Put descriptive text here. ====
+%
+% \DescribeMacro{\gurps}
+% The SJGames online policy asks that \textbf{\textit{GURPS}} is always bold and
+% italicised, so this command provides the correct
+% formatting.
+%
+% \DescribeEnv{character}
+% Yep. Makes a character
+%
+%\StopEventually{^^A
+% \PrintChanges
+% \PrintIndex
+%}
+%
+% \section{Implementation}
+% Loading required libraries and the lua logic for this class.
+% \begin{macrocode}
+%<*package>
+\RequirePackage{xparse}
+\RequirePackage{xspace}
+\RequirePackage{etex}
+\RequirePackage{luacode}
+
+\RequirePackage{hyperref}
+
+\luadirect{require("gurps.lua")}
+% \end{macrocode}
+% \begin{macro}{\gurps}
+% Steve Jackson Games asks that the name \textbf{\textit{GURPS}} is always in
+% bold and italicised. This macro provides that.
+% \begin{macrocode}
+\NewDocumentCommand{\gurps}{s}{%
+ \IfBooleanTF#1
+ % With star
+ {\href{http://www.sjgames.com/gurps/}{\textbf{\textit{GURPS}}\xspace}}
+ % Without star
+ {\textbf{\textit{GURPS}}\xspace}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\dice}
+% Notates dice in the \gurps way (e.g. drops the |6| from |d6|) and puts it in %
+% an |\mbox|. First argument number of dice. Second argument is a modifier and
+% optional. E.g.~|\dice{3}[1]|
+% creates \mbox{3d+1}.
+% \begin{macrocode}
+\NewDocumentCommand{\dice}{mO{0}}{%
+ \luadirect{print_dice([[#1]], [[#2]])}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\SteveJacksonGames}
+% \begin{macrocode}
+\NewDocumentCommand{\SteveJacksonGames}{s}{%
+ \IfBooleanTF#1%
+ % With star
+ {\href{http://www.sjgames.com/}{Steve~Jackson~Games\xspace}}%
+ % Without star
+ {Steve~Jackson~Games\xspace}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\SJGamesOnlinePolicyDisclaimer}
+% \begin{macrocode}
+\NewDocumentCommand{\SJGamesOnlinePolicyDisclaimer}{}{%
+ The material presented here is my original creation, intended for use with the
+ \gurps* system from \SteveJacksonGames*. This material is not official and is
+ not endorsed by \SteveJacksonGames.
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SJGamesOnlinePolicyDisclaimer}
+% The disclaimer \emph{almost} as it appears on the online policy. The words
+% `the art' have been removed since by default no art (including logos) are
+% included in \LaTeX{} documents.
+% \begin{macrocode}
+\NewDocumentCommand{\SJGamesOnlinePolicyNotice}{}{%
+ \gurps* is a registered trademark of \SteveJacksonGames, and is copyrighted by
+ \SteveJacksonGames. All rights are reserved by SJ Games. This material is used
+ here in accordance with the SJ Games
+ \href{http://www.sjgames.com/general/online_policy.html}{online policy}.
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\SJGamesOnlinePolicyGameAid}
+% This text is required for all game aid's produced for \textbf{\textit{GURPS}} but without an
+% official license. It takes one argument: author name.
+% \begin{macrocode}
+\NewDocumentCommand{\SJGamesOnlinePolicyGameAid}{m}{%
+ \gurps is a trademark of \SteveJacksonGames, and its rules and art are
+ copyrighted by \SteveJacksonGames. All rights are reserved by
+ \SteveJacksonGames. This game aid is the original creation of #1 and
+ is released for free distribution, and not for resale, under the
+ permissions granted in the
+ \href{http://www.sjgames.com/general/online_policy.html}%
+ {\SteveJacksonGames Online Policy}.
+}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\ST}
+% Sets the strength of the current character
+% \begin{macrocode}
+\NewDocumentCommand{\ST}{m}{\luadirect{_ARGS.ST = #1}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\DX}
+% Sets the dexterity of the current character
+% \begin{macrocode}
+\NewDocumentCommand{\DX}{m}{\luadirect{_ARGS.DX = #1}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\IQ}
+% Sets the IQ of the current character
+% \begin{macrocode}
+\NewDocumentCommand{\IQ}{m}{\luadirect{_ARGS.IQ = #1}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\HT}
+% Sets the health of the current character
+% \begin{macrocode}
+\NewDocumentCommand{\HT}{m}{\luadirect{_ARGS.HT = #1}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\HP}
+% Sets the HP of the current character
+% \begin{macrocode}
+\NewDocumentCommand{\HP}{m}{\luadirect{_ARGS.HP = #1}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\Per}
+% Sets the perception of the current character
+% \begin{macrocode}
+\NewDocumentCommand{\Per}{m}{\luadirect{_ARGS.Per = #1}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\Will}
+% Sets the will of the current character
+% \begin{macrocode}
+\NewDocumentCommand{\Will}{m}{\luadirect{_ARGS.Will = #1}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\FP}
+% Sets the FP of the current character
+% \begin{macrocode}
+\NewDocumentCommand{\FP}{m}{\luadirect{_ARGS.FP = #1}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\SM}
+% Sets the SM of the current character
+% \begin{macrocode}
+\NewDocumentCommand{\SM}{m}{\luadirect{_ARGS.SM = #1}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\DR}
+% Sets the DR of the current character
+% \begin{macrocode}
+\NewDocumentCommand{\DR}{m}{\luadirect{_ARGS.DR = #1}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{environment}{character}
+% This environment defines a `character' i.e.~anything with full stats.
+% \begin{macrocode}
+\NewDocumentEnvironment{character}{}{%
+% \end{macrocode}
+% \changes{v1.00a}{2017/12/04}{Added a spurious change log entry to show what a
+% change \emph{within} an environment definition looks like.}
+%
+% The global lua variable |_ARGS| is created and then populated by commands
+% inside the environment.
+% \begin{macrocode}
+\luadirect{_ARGS = {
+ advantages={},
+ disadvantages={},
+ skills={},
+ spells={}
+ }}
+}{%
+% \end{macrocode}
+% At the end of the environment, the character is initialised printed (via lua's
+% |tex.print|).
+% \begin{macrocode}
+ \luadirect{character = create_character(_ARGS)}
+ \luadirect{print_character()}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{lens}
+% Like |character|, but it's a lens.
+% \begin{macrocode}
+\newenvironment{lens}[1]{%
+ \luadirect{character = create_character({#1})}%
+}{%
+ \luadirect{print_character_as_lens()}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\advantage}
+% Adds an advantage to a character. NOTE: this only works in a |character| or
+% |lens| environment.
+% \begin{macrocode}
+\NewDocumentCommand{\advantage}{mO{}}{%
+ \luadirect{_ARGS.advantages[ [[\unexpanded{#1}]] ] = trait(#2)}
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\disadvantage}
+% Adds a disadvantage to a character. NOTE: this only works in a |character| or
+% |lens| environment.
+% \begin{macrocode}
+\NewDocumentCommand{\disadvantage}{mO{}}{%
+ \luadirect{_ARGS.disadvantages[ [[\unexpanded{#1}]] ] = trait(#2)}
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\levelledadvantage}
+% Adds an advantage to a character. NOTE: this only works in a |character| or
+% |lens| environment.
+% \begin{macrocode}
+% TODO finish this!
+\NewDocumentCommand{\levelledadvantage}{mmO{nil}}{%
+ \luadirect{_ARGS.advantages[ [[\unexpanded{#1}]] ] = valued_trait(#2, #3)}
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\levelleddisadvantage}
+% Adds a disadvantage to a character. NOTE: this only works in a |character| or
+% |lens| environment.
+% \begin{macrocode}
+\NewDocumentCommand{\levelleddisadvantage}{mmO{nil}}{%
+ \luadirect{_ARGS.disadvantages[ [[\unexpanded{#1}]] ] = valued_trait(#2, #3)}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\skill}
+% \begin{macrocode}
+\NewDocumentCommand\skill{mom}{%
+ \IfNoValueTF{#2}
+ {\luadirect{_ARGS.skills[ [[\unexpanded{#1}]] ] = {value=#3}}}
+ {%
+ \luadirect{
+ _ARGS.skills[ [[\unexpanded{#1}]] ] = {value=#3, difficulty=[[#2]]}
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spell}
+% \begin{macrocode}
+\NewDocumentCommand\spell{mom}{%
+ \IfNoValueTF{#2}
+ {\luadirect{_ARGS.spells[ [[\unexpanded{#1}]] ] = {value=#3}}}
+ {%
+ \luadirect{
+ _ARGS.spells[ [[\unexpanded{#1}]] ] = {value=#3, difficulty=[[#2]]}
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+\endinput
+%</package>
+% \end{macrocode}
+%\Finale
diff --git a/macros/luatex/latex/gurps/gurps.lua b/macros/luatex/latex/gurps/gurps.lua
new file mode 100644
index 0000000000..22273aeb30
--- /dev/null
+++ b/macros/luatex/latex/gurps/gurps.lua
@@ -0,0 +1,312 @@
+require "gurps_tables"
+
+function thrust_or_swing(typ, st)
+ if st < 1 then
+ return "0"
+ end
+
+ if _GTHRUSTSWINGTABLE[typ][st] then
+ return _GTHRUSTSWINGTABLE[typ][st]
+ else
+ return thrust_or_swing(typ, st - 1)
+ end
+end
+
+function thrust(st)
+ return thrust_or_swing("thrust", st)
+end
+
+function swing(st)
+ return thrust_or_swing("swing", st)
+end
+
+function print_dice(dice_no, modifier)
+ tex.sprint([[\mbox{]])
+ tex.sprint(dice_no .. "d")
+
+ -- If `modifier` is a valid number
+
+ local modifier_number = tonumber(modifier)
+ if modifier_number then
+ if modifier_number > 0 then
+ tex.sprint("+" .. modifier_number)
+ elseif modifier_number < 0 then
+ tex.sprint("-" .. modifier_number)
+ -- else, don't print anything
+ end
+ -- elseif `modifier` is non-nil
+ elseif modifier then
+ tex.sprint("+" .. modifier)
+ end
+ tex.sprint("}")
+end
+
+function valued_trait(value, points)
+ return {
+ value=value,
+ points=points or "?"
+ }
+end
+
+function value(value)
+ return {
+ value=value
+ }
+end
+
+function trait(points)
+ return {
+ points=points or "?"
+ }
+end
+
+function base_stat(stat, multiplier, default)
+ default = default or 10
+ stat = stat or default
+ multiplier = multiplier or 10
+ return valued_trait(stat, (stat - default)*multiplier)
+end
+
+-- Creates an attack table.
+function attack(stat, damage, based_on)
+ rettable = {
+ stat=stat or "?",
+ damage=damage or "?",
+ based_on=based_on or "?"
+ }
+
+ -- i.e. if it's based on a real stat and that stat is a skill
+ if based_on ~= "?" and character.skills[based_on] then
+ rettable.adjustment = character.skills[based_on] - stat
+ elseif based_on ~= "?" and character.spells[based_on] then
+ rettable.adjustment = character.spells[based_on] - stat
+ end
+
+ return rettable
+end
+
+function create_character(args)
+ -- Creates a character
+ local args = args or {}
+ local c = {}
+
+ c.pointless_stats = {}
+ c.pointless_stats.DR = value(args.DR or 0)
+ c.pointless_stats.SM = value(args.SM or 0)
+
+ c.base_stats = {
+ ST=base_stat(args.ST, 10 - c.pointless_stats.SM.value),
+ DX=base_stat(args.DX, 20),
+ IQ=base_stat(args.IQ, 20),
+ HT=base_stat(args.HT),
+ }
+
+ -- Gets the value for a base stat
+ function gv(c, key)
+ return c.base_stats[key].value
+ end
+
+ c.pointless_stats.thr = value(thrust(gv(c, "ST")))
+ c.pointless_stats.sw = value(swing(gv(c, "ST")))
+
+ c.base_stats.HP = base_stat(args.HP or gv(c, "ST"), 5, gv(c, "ST"))
+ c.base_stats.Per = base_stat(args.Per or gv(c, "IQ"), 5, gv(c, "IQ"))
+ c.base_stats.Will = base_stat(args.Will or gv(c, "IQ"), 5, gv(c, "IQ"))
+ c.base_stats.FP = base_stat(args.FP or gv(c, "HT"), 5, gv(c, "HT"))
+
+ -- c.advantages = {}
+ -- c.disadvantages = {}
+ c.advantages = args.advantages
+ c.disadvantages = args.disadvantages
+ -- TODO abstract the logic for spells into general skills
+ c.skills = {}
+ for name,obj in pairs(args.skills) do
+ if obj.difficulty then
+ x = split(obj.difficulty)
+ -- TODO fix this to be spell points vv
+ points = calculate_skill_points(c, x[1], x[2], obj.value)
+ c.skills[name] = valued_trait(obj.value, points)
+ else
+ c.skills[name] = valued_trait(obj.value)
+ end
+ end
+ c.spells = {}
+ for name,obj in pairs(args.spells) do
+ if obj.difficulty then
+ x = split(obj.difficulty)
+ -- TODO fix this to be spell points vv
+ points = calculate_skill_points(c, x[1], x[2], obj.value)
+ c.spells[name] = valued_trait(obj.value, points)
+ else
+ c.spells[name] = valued_trait(obj.value)
+ end
+ end
+ c.attacks = {}
+
+ return c
+end
+
+-- character = create_character()
+
+
+function count_points()
+ running_total = 0
+ for i,traits in pairs({"base_stats",
+ "advantages",
+ "disadvantages",
+ "skills",
+ "spells"}) do
+ if character[traits] then
+ for j,v in pairs(character[traits]) do
+ if v.points ~= "?" then
+ running_total = running_total + v.points
+ end
+ end
+ end
+ end
+ return running_total
+end
+
+
+function print_little_section(title, tbl)
+ tex.print([[\paragraph{]] .. title .. [[}]])
+
+ local x = {}
+ for k,v in pairs(tbl) do
+ if v.value == nil then
+ table.insert(x, k .. "[" .. v.points .. "]")
+ elseif v.points == nil then
+ table.insert(x, k .. "~" .. v.value)
+ else
+ table.insert(x, k .. "~" .. v.value .. "[" .. v.points .. "]")
+ end
+ end
+
+ if next(tbl) == nil then
+ table.insert(x, [[\ldots{}]])
+ end
+ tex.print(table.concat(x, ", ") .. ".")
+end
+
+
+base_stats = {
+ "ST", "DX", "IQ", "HT", "HP", "Per", "Will", "FP"
+}
+
+
+function print_character()
+ tex.print([[\subsubsection{Stats (]] .. count_points() .. [[~pt)}]])
+ tex.print([[\paragraph{Base stats}]])
+ local x = {}
+ for i, base_stat in ipairs(base_stats) do
+ local obj = character.base_stats[base_stat]
+ table.insert(
+ x,
+ base_stat .. [[~]] .. obj.value
+ .. "[" .. obj.points .. "]")
+ end
+ tex.print(table.concat(x, ", ") .. ".")
+
+ print_little_section("Other", character.pointless_stats)
+
+ print_little_section("Advantages", character.advantages)
+ print_little_section("Disadvantages", character.disadvantages)
+ print_little_section("Skills", character.skills)
+ if next(character.spells) then
+ print_little_section("Spells", character.spells)
+ end
+end
+
+function print_character_as_lens()
+ tex.print([[\subsubsection{Lens (+]] .. count_points() .. [[~pt)}]])
+ tex.print([[\paragraph{Base stats}]])
+ local x = {}
+ for i, base_stat in ipairs(base_stats) do
+ local obj = character.base_stats[base_stat]
+ if obj.value ~= 10 then
+ table.insert(
+ x,
+ base_stat .. [[~+]] .. obj.value - 10
+ .. "[" .. obj.points .. "]")
+ end
+ end
+ tex.print(table.concat(x, ", ") .. ".")
+
+ if next(character.advantages) ~= nil then
+ print_little_section("Advantages", character.advantages)
+ end
+ if next(character.disadvantages) ~= nil then
+ print_little_section("Disadvantages", character.disadvantages)
+ end
+ if next(character.skills) ~= nil then
+ print_little_section("Skills", character.skills)
+ end
+ if next(character.spells) ~= nil then
+ print_little_section("Spells", character.spells)
+ end
+end
+
+
+-- Creates a new LaTeX command
+--
+-- TODO move this to the dtx file because that's where documentation for LaTeX
+-- files lives
+function print_set_cmd(name, extra_args)
+ extra_args = extra_args or {"nil"}
+ tex.print(
+ string.format(
+ [[\NewDocumentCommand\set%s{m}]]
+ .. [[{\luadirect{character.%s = base_stat(#1, %s)}}]],
+ name,
+ name,
+ table.concat(extra_args, ", ")
+ )
+ )
+end
+
+print_set_cmd("ST")
+print_set_cmd("DX", {"20"})
+print_set_cmd("IQ", {"20"})
+print_set_cmd("HT")
+print_set_cmd("HP", {"5", "character.base_stats.ST.value"})
+print_set_cmd("Per", {"5", "character.base_stats.IQ.value"})
+print_set_cmd("Will", {"5", "character.base_stats.IQ.value"})
+print_set_cmd("FP", {"5", "character.base_stats.HT.value"})
+
+--- Splits string (on / by default)
+function split(s, split_on)
+ local split_on = split_on or [[/]]
+ local rettable = {}
+ for i in string.gmatch(s, "[^" .. split_on .. "]+") do
+ table.insert(rettable, i)
+ end
+ return rettable
+end
+
+
+function calculate_skill_points(character, based_on, difficulty, skill_level)
+ -- TODO rename this variable
+ if difficulty == "Easy" then
+ difficulty_modifier = 0
+ elseif difficulty == "Average" then
+ difficulty_modifier = 1
+ elseif difficulty == "Hard" then
+ difficulty_modifier = 2
+ elseif difficulty == "Very Hard" then
+ difficulty_modifier = 3
+ elseif difficulty == "Wildcard" then
+ return 3*calculate_skill_points(based_on, "Very Hard", skill_level)
+ end
+
+ -- TODO make support for non-base stat based_on values
+ local relative_level = skill_level - character.base_stats[based_on].value
+ if relative_level == (0 - difficulty_modifier) then
+ return 1
+ elseif relative_level == (1 - difficulty_modifier) then
+ return 2
+ elseif relative_level == (2 - difficulty_modifier) then
+ return 4
+ elseif relative_level > (2 - difficulty_modifier) then
+ return (relative_level - 1 + difficulty_modifier) * 4
+ end
+end
diff --git a/macros/luatex/latex/gurps/gurps.pdf b/macros/luatex/latex/gurps/gurps.pdf
new file mode 100644
index 0000000000..0e6159b69f
--- /dev/null
+++ b/macros/luatex/latex/gurps/gurps.pdf
Binary files differ
diff --git a/macros/luatex/latex/gurps/gurps_tables.lua b/macros/luatex/latex/gurps/gurps_tables.lua
new file mode 100644
index 0000000000..56c79b79b0
--- /dev/null
+++ b/macros/luatex/latex/gurps/gurps_tables.lua
@@ -0,0 +1,112 @@
+_GSWINGTABLE = {}
+_GSWINGTABLE[1] = "1d-5"
+_GSWINGTABLE[2] = "1d-5"
+_GSWINGTABLE[3] = "1d-4"
+_GSWINGTABLE[4] = "1d-4"
+_GSWINGTABLE[5] = "1d-3"
+_GSWINGTABLE[6] = "1d-3"
+_GSWINGTABLE[7] = "1d-2"
+_GSWINGTABLE[8] = "1d-2"
+_GSWINGTABLE[9] = "1d-1"
+_GSWINGTABLE[10] = "1d"
+_GSWINGTABLE[11] = "1d+1"
+_GSWINGTABLE[12] = "1d+2"
+_GSWINGTABLE[13] = "2d-1"
+_GSWINGTABLE[14] = "2d"
+_GSWINGTABLE[15] = "2d+1"
+_GSWINGTABLE[16] = "2d+2"
+_GSWINGTABLE[17] = "3d-1"
+_GSWINGTABLE[18] = "3d"
+_GSWINGTABLE[19] = "3d+1"
+_GSWINGTABLE[20] = "3d+2"
+_GSWINGTABLE[21] = "4d-1"
+_GSWINGTABLE[22] = "4d"
+_GSWINGTABLE[23] = "4d+1"
+_GSWINGTABLE[24] = "4d+2"
+_GSWINGTABLE[25] = "5d-1"
+_GSWINGTABLE[26] = "5d"
+_GSWINGTABLE[27] = "5d+1"
+_GSWINGTABLE[28] = "5d+1"
+_GSWINGTABLE[29] = "5d+2"
+_GSWINGTABLE[30] = "5d+2"
+_GSWINGTABLE[31] = "6d-1"
+_GSWINGTABLE[32] = "6d-1"
+_GSWINGTABLE[33] = "6d"
+_GSWINGTABLE[34] = "6d"
+_GSWINGTABLE[35] = "6d+1"
+_GSWINGTABLE[36] = "6d+1"
+_GSWINGTABLE[37] = "6d+2"
+_GSWINGTABLE[38] = "6d+2"
+_GSWINGTABLE[39] = "7d-1"
+_GSWINGTABLE[40] = "7d-1"
+_GSWINGTABLE[45] = "7d+1"
+_GSWINGTABLE[50] = "8d-1"
+_GSWINGTABLE[55] = "8d+1"
+_GSWINGTABLE[60] = "9d"
+_GSWINGTABLE[65] = "9d+2"
+_GSWINGTABLE[70] = "10d"
+_GSWINGTABLE[75] = "10d+2"
+_GSWINGTABLE[80] = "11d"
+_GSWINGTABLE[85] = "11d+2"
+_GSWINGTABLE[90] = "12d"
+_GSWINGTABLE[95] = "12d+2"
+_GSWINGTABLE[100] = "13d"
+
+_GTHRUSTTABLE = {}
+_GTHRUSTTABLE[1] = "1d-6"
+_GTHRUSTTABLE[2] = "1d-6"
+_GTHRUSTTABLE[3] = "1d-5"
+_GTHRUSTTABLE[4] = "1d-5"
+_GTHRUSTTABLE[5] = "1d-4"
+_GTHRUSTTABLE[6] = "1d-4"
+_GTHRUSTTABLE[7] = "1d-3"
+_GTHRUSTTABLE[8] = "1d-3"
+_GTHRUSTTABLE[9] = "1d-2"
+_GTHRUSTTABLE[10] = "1d-2"
+_GTHRUSTTABLE[11] = "1d-1"
+_GTHRUSTTABLE[12] = "1d-1"
+_GTHRUSTTABLE[13] = "1d"
+_GTHRUSTTABLE[14] = "1d"
+_GTHRUSTTABLE[15] = "1d+1"
+_GTHRUSTTABLE[16] = "1d+1"
+_GTHRUSTTABLE[17] = "1d+2"
+_GTHRUSTTABLE[18] = "1d+2"
+_GTHRUSTTABLE[19] = "2d-1"
+_GTHRUSTTABLE[20] = "2d-1"
+_GTHRUSTTABLE[21] = "2d"
+_GTHRUSTTABLE[22] = "2d"
+_GTHRUSTTABLE[23] = "2d+1"
+_GTHRUSTTABLE[24] = "2d+1"
+_GTHRUSTTABLE[25] = "2d+2"
+_GTHRUSTTABLE[26] = "2d+2"
+_GTHRUSTTABLE[27] = "3d-1"
+_GTHRUSTTABLE[28] = "3d-1"
+_GTHRUSTTABLE[29] = "3d"
+_GTHRUSTTABLE[30] = "3d"
+_GTHRUSTTABLE[31] = "3d+1"
+_GTHRUSTTABLE[32] = "3d+1"
+_GTHRUSTTABLE[33] = "3d+2"
+_GTHRUSTTABLE[34] = "3d+2"
+_GTHRUSTTABLE[35] = "4d-1"
+_GTHRUSTTABLE[36] = "4d-1"
+_GTHRUSTTABLE[37] = "4d"
+_GTHRUSTTABLE[38] = "4d"
+_GTHRUSTTABLE[39] = "4d+1"
+_GTHRUSTTABLE[40] = "4d+1"
+_GTHRUSTTABLE[45] = "5d"
+_GTHRUSTTABLE[50] = "5d+2"
+_GTHRUSTTABLE[55] = "6d"
+_GTHRUSTTABLE[60] = "7d-1"
+_GTHRUSTTABLE[65] = "7d+1"
+_GTHRUSTTABLE[70] = "8d"
+_GTHRUSTTABLE[75] = "8d+2"
+_GTHRUSTTABLE[80] = "9d"
+_GTHRUSTTABLE[85] = "9d+2"
+_GTHRUSTTABLE[90] = "10d"
+_GTHRUSTTABLE[95] = "10d+2"
+_GTHRUSTTABLE[100] = "11d"
+
+_GTHRUSTSWINGTABLE = {
+ thrust=_GTHRUSTTABLE,
+ swing=_GSWINGTABLE,
+}
diff --git a/macros/luatex/latex/hmtrump/README.md b/macros/luatex/latex/hmtrump/README.md
new file mode 100644
index 0000000000..5f0c656816
--- /dev/null
+++ b/macros/luatex/latex/hmtrump/README.md
@@ -0,0 +1,63 @@
+# hmtrump Package
+
+## What is this?
+
+You will be able to describe playing cards using *hmtrump* package.
+**This package needs LuaLaTeX**.
+
+sample.tex is sample file.
+
+## How to use?
+
+1. Install NKD04 Playing Card's Index font
+1. \usepackage{hmtrump} in preamble
+1. To describe cards, use \trump{*rank*}{*suit*}
+
++ *rank*: 1 to 9, T (meaning 10), J, Q, K
++ *suit*: S (Spade), H (Hard), D (Diamond), C (Club), x (no suits)
+
+## Manual
+
+[hmtrump.pdf](hmtrump.pdf) is manual, written in Japanese.
+
+## 日本語ã§ok
+
+トランプã®ãƒ«ãƒ¼ãƒ«ã‚’ TeX ã§åŸ·ç­†ã™ã‚‹äººã«å‘ã‘ã¦ä½œã£ãŸãƒ‘ッケージã§ã™ã€‚
+トランプã®ã‚«ãƒ¼ãƒ‰ã®è¨˜å·ã‚’手軽ã«å‡ºåŠ›ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+[hmtrump-sample.tex](hmtrump-sample.tex) ãŒã‚µãƒ³ãƒ—ルファイルã«ãªã£ã¦ã„ã¾ã™ã€‚
+
+[hmtrump.pdf](hmtrump.pdf) ãŒãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ã§ã™ã€‚ã”一読ãã ã•ã„。
+
+### 使ã„æ–¹
+
+**LuaLaTeX** ã‚’å¿…è¦ã¨ã—ã¾ã™ï¼ˆfontspec パッケージを内部ã§èª­ã¿è¾¼ã¿ã¾ã™ï¼‰ã€‚
+
+ã¾ãšã¯ã˜ã‚ã«ã€åŒæ¢±ã® NKD04 Playing Card's Index フォントをインストールã—ã¦ãã ã•ã„。
+
+プリアンブル㫠\usepackage{hmtrump} ã¨æ›¸ã‘ã°ä½¿ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+
+トランプã®ã‚«ãƒ¼ãƒ‰ã‚’出力ã™ã‚‹ã«ã¯ \trump{*rank*}{*suit*} ã¨ã—ã¾ã™ã€‚
+*rank* 㯠1〜9 ã®æ•°å­—ã¾ãŸã¯ T(10), K, Q, J を指定ã—ã€*suit* ã«ã¯ S, H, D, C, x
+(スペードã€ãƒãƒ¼ãƒˆã€ãƒ€ã‚¤ãƒ¤ã€ã‚¯ãƒ©ãƒ–ã€ã‚¹ãƒ¼ãƒˆãªã—)を指定ã—ã¾ã™ã€‚
+
+ãã®ä»–æä¾›ã•ã‚Œã‚‹å‘½ä»¤ã¯ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+
+## License
+
+ã“ã®ãƒ‘ッケージã«å«ã¾ã‚Œã‚‹æˆæžœç‰©ã¯ã€ã‚¯ãƒªã‚¨ã‚¤ãƒ†ã‚£ãƒ–・コモンズ 表示--継承
+ライセンスã®å…ƒã§é…布を行ã†ã€‚
+
+This package is licensed under a Creative Commons Attribution-ShareAlike
+4.0 International License.
+
+NKD04 Playing Card's Index フォントã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã¯ã€é…布元ã§ç¤ºã•ã‚Œã¦ã„る通りã®
+æ¡ä»¶ã«å¾“ã†ã€‚ã™ãªã‚ã¡ã€å•†ç”¨ç§ç”¨å•ã‚ãšè‡ªç”±ã«ä½¿ç”¨ã§ãã€é…布元
+[http://hwm3.gyao.ne.jp/shiroi-niwatori/nishiki-teki.htm](http://hwm3.gyao.ne.jp/shiroi-niwatori/nishiki-teki.htm)
+を示ã›ã°å†é…布もå¯èƒ½ã§ã‚る。原文ã¯[ã“ã“](./nkd04_playing_cards_index/LICENSE)ã‚’å‚照。
+
+NKD04 Playing Card's Index is licensed under following;
+There is no restriction on using NKD04 Playing Card's Index regardless
+of private or commercial, and it is possible to redistribute this.
+In the case of redistribution, please specify this distribution source
+([http://hwm3.gyao.ne.jp/shiroi-niwatori/nishiki-teki.htm](http://hwm3.gyao.ne.jp/shiroi-niwatori/nishiki-teki.htm)).
+For further information, pleas see [here](./nkd04_playing_cards_index/LICENSE).
diff --git a/macros/luatex/latex/hmtrump/by-sa.png b/macros/luatex/latex/hmtrump/by-sa.png
new file mode 100644
index 0000000000..182227ce65
--- /dev/null
+++ b/macros/luatex/latex/hmtrump/by-sa.png
Binary files differ
diff --git a/macros/luatex/latex/hmtrump/hmtrump-sample.pdf b/macros/luatex/latex/hmtrump/hmtrump-sample.pdf
new file mode 100644
index 0000000000..e6ea0535c8
--- /dev/null
+++ b/macros/luatex/latex/hmtrump/hmtrump-sample.pdf
Binary files differ
diff --git a/macros/luatex/latex/hmtrump/hmtrump-sample.tex b/macros/luatex/latex/hmtrump/hmtrump-sample.tex
new file mode 100644
index 0000000000..42c6522807
--- /dev/null
+++ b/macros/luatex/latex/hmtrump/hmtrump-sample.tex
@@ -0,0 +1,189 @@
+\documentclass[jafontsize=8pt]{jlreq}
+
+\usepackage{luatexja}
+\ltjdefcharrange{11}{`→,`↑,`↓,`â†}
+\ltjsetparameter{jacharrange={-2,-8,+11}}
+\usepackage[jfm_yoko=jlreq,jfm_tate=jlreqv]{luatexja-preset}
+\usepackage{luatexja-otf,luatexja-adjust}
+\newopentypefeature{PKana}{On}{pkna}
+
+\usepackage{yhmath,amssymb,mathtools,mathabx,mathrsfs,mathbbol}
+
+\usepackage[math]{iwona}
+\usepackage[euler-digits]{eulervm}
+\usepackage{tgheros,newpxtext,yhmath}
+\usepackage[scaled]{beramono}
+\DeclareMathAlphabet{\mathtt}{T1}{fvm}{m}{n}
+\DeclareMathAlphabet{\mathsf}{T1}{uop}{m}{n}
+
+\usepackage{scalefnt}
+\usepackage{multirow}
+\usepackage{multicol}
+\ltjenableadjust[lineend=extended,priority=true,profile=true,linestep=true]
+\allowdisplaybreaks[4]
+
+\usepackage{hmtrump}
+
+\usepackage[a4paper,margin=15mm]{geometry}
+
+\newcommand{\hmG}{%
+ \tikz[baseline=(T.base)]
+ \node[fill=black,text=white,outer sep=0pt,inner sep=0.1ex]
+ (T)at(0,0){\textsf{G}};%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\begin{document}
+
+\pagestyle{empty}
+
+\vspace{-1cm}
+\title{Skat ルールサマリー}
+\author{ã²ã¨ã¿ã•ã‚“}
+
+\begin{center}
+{\LARGE Skat ルール早見}---ã²ã¨ã¿ã•ã‚“ \today
+\end{center}
+
+\setlength{\parindent}{0pt}
+
+\section{ゲームã®æµã‚Œ}
+\textbf{\mbox{カードをé…ã‚‹}\hfill →\hfill \mbox{ビッドをã™ã‚‹}\hfill →\hfill
+\mbox{スカート交æ›ã€ã‚²ãƒ¼ãƒ ã®ç¨®é¡žã‚’決ã‚ã‚‹}\hfill →\hfill \mbox{トリックテイキング}\hfill
+→\hfill \mbox{得点計算}\hfill}\\
+é…ã‚Šæ–¹: 3→スカート2→4→3
+\hspace*{1\zw}(4人以上)ディーラーã¨ï¼ˆ5人)ディーラーã®3ã¤å·¦éš£ã¯ä¸å‚加ã€ãƒ‡ã‚£ãƒ¼ãƒ©ãƒ¼ã®æ¬¡ãŒã‚ªãƒ¼ãƒ—ニングリード\\
+ビッドã¯å‹ã¡æŠœãæ–¹å¼ï¼ˆå…ˆã®ãƒ“ッドã«å„ªå…ˆæ¨©ï¼‰
+
+\section{カード}
+基本ã®ç›®çš„: 61カード点以上ç²å¾—/ヌルゲーム: 1トリックもå–らãªã„\par
+\unitrump{JC}\unitrump{JS}\unitrump{JH}\unitrump{JD}ã¯ãƒŒãƒ«ä»¥å¤–ã§å¸¸ã«åˆ‡æœ­
+\begin{table}[h]
+\begin{minipage}{.2\textwidth}
+\centering
+\caption{カード点}
+\begin{tabular}{c|c}
+\hline
+\trump Ax&11\\
+\trump Tx&10\\
+\trump Kx&4\\
+\trump Qx&3\\
+\trump Jx&2\\
+\hline\hline
+ç·è¨ˆ&120\\
+\hline
+\end{tabular}
+\end{minipage}
+\begin{minipage}{.75\textwidth}
+\centering
+\caption{ランクã®é †}
+\begin{tabular}{c|c|l}
+\hline
+\multirow{2}{*}{スートゲーム}&
+切札&$\trump JC>\trump JS>\trump JH>\trump JD
+ >\trump Ax>\trump Tx>\trump Kx>\trump Qx>\trump 9x>\trump 8x>\trump 7x$\\
+&切札以外&$\trump Ax>\trump Tx>\trump Kx>\trump Qx>\trump 9x>\trump 8x>\trump 7x$\\
+\hline
+\multirow{2}{*}{グランド}&
+切札&$\trump JC>\trump JS>\trump JH>\trump JD$\\
+&切札以外&$\trump Ax>\trump Tx>\trump Kx>\trump Qx>\trump 9x>\trump 8x>\trump 7x$\\
+\hline\hline
+\multicolumn{2}{c|}{ヌルゲーム}&
+$\trump Ax>\trump Kx>\trump Qx>\trump Jx>\trump Tx>\trump 9x>\trump 8x>\trump 7x$\\
+\hline
+\end{tabular}
+\end{minipage}
+\end{table}
+
+\section{ゲーム点}
+$\text{Gp}=\text{基本点}\times\text{é”æˆç‚¹}$ã€å¤±æ•—ãªã‚‰ã°2å€\\
+ビッドã®ç‚¹æ•°ã«è¶³ã‚Šãšå¤±æ•—→é”æˆç‚¹ã‚’増やã—ã€ãƒ“ッドã®ç‚¹æ•°ã‚’超ãˆãŸã¨ã“ã‚㧠Gp ã¨ã—ã€ãã‚Œã®2å€ã®å¤±ç‚¹\\
+\textbf{シュワルツ}→全トリックå–ã‚‹/\textbf{シュナイダー}→90点以上/\textbf{ウベア}→手札を公開ã—ã¦å…¨ãƒˆãƒªãƒƒã‚¯\\
+\hspace{1\zw}ã„ãšã‚Œã‚‚ãƒãƒ³ãƒ‰ã‚²ãƒ¼ãƒ ã®ã¨ãã«ã®ã¿å®£è¨€å¯èƒ½ï¼ˆå®£è¨€ã›ãšã¨ã‚‚ã€æˆã‚Šè¡Œãã§é”æˆã¯å¯èƒ½ï¼‰\\
+\textbf{ウィズ/ウィズアウト}→上ã‹ã‚‰ä½•æžšã®é€£ç¶šã—ãŸåˆ‡æœ­ã‚’æŒã£ã¦ã„ã‚‹/ã„ãªã„ã‹
+\begin{table}[h]
+\begin{minipage}{.2\textwidth}
+\centering
+\caption{基本点}
+\begin{tabular}{cc|c}
+\hline
+\multirow{2}{*}{\mbox{\tate \hspace{0.3\zw}スートゲーム}}
+&\hmD&9\\
+&\hmH&10\\
+&\hmS&11\\
+&\hmC&12\\
+\hline
+\multicolumn{2}{c|}{グランド}&24\\
+\hline
+\end{tabular}
+\end{minipage}
+\begin{minipage}{.75\textwidth}
+\centering
+\caption{é”æˆç‚¹}
+\begin{tabular}{cc||cccccc}
+\hline
+&&シュワルツ&シュナイダー&89--31&逆シュナイダー&逆シュワルツ\\
+\hline\hline
+\multicolumn{2}{c||}{スカートゲーム}
+&3&2&1&2&3\\
+\multirow{4}{*}{\mbox{\tate \hspace{0.3\zw}ãƒãƒ³ãƒ‰ã‚²ãƒ¼ãƒ }}
+&宣言無ã—
+&4&3&2&3&4\\
+&シュナイダー宣言
+&5&4&4&5&6\\
+&シュワルツ宣言
+&6&6&6&7&8\\
+&ウベア宣言
+&7&7&7&8&9\\
+\hline
+\multicolumn{7}{r}{+ウィズ/ウィズアウト}
+\end{tabular}
+\end{minipage}
+\end{table}
+\begin{table}[h]
+\caption{基本点(ヌルゲーム)→é”æˆç‚¹ã¯1固定}
+\centering
+\begin{tabular}{cccc}
+\hline
+ヌル(ãƒãƒ³ãƒ‰ï¼‰&ヌル(スカート)&ヌル・ウベア(ãƒãƒ³ãƒ‰ï¼‰&ヌル・ウベア(スカート)\\
+\hline
+23&35&46&59\\
+\hline
+\end{tabular}
+\end{table}
+
+\section{ビッドå¯èƒ½ãªç‚¹æ•°}
+18 \hmD2→\hmD ã®ã‚¹ãƒ¼ãƒˆã‚²ãƒ¼ãƒ ã€é”æˆç‚¹2㧠18 Gp\hspace{1\zw}\hmG →グランド\\
+\begin{multicols}{4}
+\renewcommand{~}{\hspace{1\zw}}
+18~\hmD2\\
+20~\hmH2\\
+22~\hmS2\\
+23~ヌル(スカート)\\
+24~\hmC2\\
+27~\hmD3\\
+30~\hmH3\\
+33~\hmS3\\
+35~ヌル(ãƒãƒ³ãƒ‰ï¼‰\\
+36~\hmD4, \hmC3\\
+40~\hmH4\\
+44~\hmS4\\
+45~\hmD5\\
+46~ヌル・ウベア(ãƒãƒ³ãƒ‰ï¼‰\\
+48~\hmC4, \hmG2\\
+50~\hmH5\\
+54~\hmD6\\
+55~\hmS5\\
+59~ヌル・ウベア(ãƒãƒ³ãƒ‰ï¼‰\\
+60~\hmH6, \hmC5\\
+63~\hmD7\\
+66~\hmS6\\
+70~\hmH7\\
+72~\hmD8, \hmC6, \hmG3\\
+\begin{center}$\vdots$\end{center}
+\end{multicols}
+
+
+\end{document}
diff --git a/macros/luatex/latex/hmtrump/hmtrump.pdf b/macros/luatex/latex/hmtrump/hmtrump.pdf
new file mode 100644
index 0000000000..5487dbe7d8
--- /dev/null
+++ b/macros/luatex/latex/hmtrump/hmtrump.pdf
Binary files differ
diff --git a/macros/luatex/latex/hmtrump/hmtrump.sty b/macros/luatex/latex/hmtrump/hmtrump.sty
new file mode 100644
index 0000000000..4702292bc9
--- /dev/null
+++ b/macros/luatex/latex/hmtrump/hmtrump.sty
@@ -0,0 +1,258 @@
+%
+% This is `hmtrump.sty'
+%
+% Author: Hitomi-san (a.k.a. Carele Smith)
+%
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{hmtrump}[2019-08-06 v1.2a]
+\RequirePackage{tikz,xcolor,fontspec}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 定義本体
+
+%: 色ã®å®£è¨€
+\definecolor{hartsuit}{cmyk}{.14,.94,.22,.27}
+\definecolor{diasuit}{cmyk}{.11,.57,.97,.31}
+\definecolor{clubsuit}{cmyk}{.70,.5,.99,.18}
+\definecolor{spadesuit}{cmyk}{.98,.80,.5,.15}
+
+\definecolor{cardback}{gray}{.95}
+\definecolor{cardborder}{gray}{.2}
+\definecolor{cardtext}{gray}{0}
+
+% \hmtc@strut => 支柱\rule[-0.65em]{0pt}{1.85em}
+% \newcommand{\hmtc@strut}{\rule[-0.65em]{0pt}{1.85em}}
+\newcommand{\hmtc@strut}{\relax}
+
+%: 日本語ã—ã¦ã„る時対策
+\ifx\ltjdefcharrange\@undefined\relax\else
+ \ltjdefcharrange{24}{
+ "2660-"2667,%å„スート
+ "E000-"E005,%ブランクã€ï¼ˆåˆæˆç”¨ãƒ–ランク→ä¸ä½¿ç”¨ï¼‰ã€æ•°å­—10-13
+ "EDDB-"EDE3,%ジョーカーマーク
+ "2160-"216B,%ローマ数字1-12
+ "E5BC-"E5BE,%ローマ数字12-21
+ "1F0A0-"1F0FF%Unicodeトランプ
+ }
+ \ltjsetparameter{jacharrange={-24}}
+\fi
+
+%: \hmtcfont => フォント変更
+\newcommand{\hmtc@trump@font}{NKD04_Playing_Cards_Index}
+\newfontfamily\hmtcfont{\hmtc@trump@font}
+
+%%: \trump{ランク}{スート}
+\tikzset{hmtcscale/.style={scale=0.9}} % å€çŽ‡
+\tikzset{hmtrump/.style={hmtcscale,draw=cardborder,fill=cardback,outer sep=0pt,rounded corners}}
+ % hmtrump スタイルを定義ã—ç›´ã™ï¼ˆ\tikzset を使ã£ã¦ä¸Šæ›¸ãã™ã‚‹ï¼‰ã“ã¨ã§ã€ã‚«ãƒ¼ãƒ‰ã®ã‚¹ã‚¿ã‚¤ãƒ«ã‚’変更å¯èƒ½ã€‚
+
+\newcommand{\trump}[2]{\hmtc@strut\hmtc@trump@{\hmtc@rank@{#1}}{#2}}
+
+\newcommand{\hmtc@rank@}[1]{\ifx#1T{\char"E002}\else#1\fi} % 10
+
+\newcommand{\hmtc@trump@}[2]{%
+ \ifx#2H{%
+ \tikz[baseline=(T.base)]
+ \node[hmtrump,text=hartsuit]
+ (T)at(0,0){\hmtcfont{#1\char"2665}};%
+ }%
+ \else\ifx#2D{%
+ \tikz[baseline=(T.base)]
+ \node[hmtrump,text=diasuit]
+ (T)at(0,0){\hmtcfont{#1\char"2666}};%
+ }%
+ \else\ifx#2C{%
+ \tikz[baseline=(T.base)]
+ \node[hmtrump,text=clubsuit]
+ (T)at(0,0){\hmtcfont{#1\char"2663}};%
+ }%
+ \else\ifx#2S{%
+ \tikz[baseline=(T.base)]
+ \node[hmtrump,text=spadesuit]
+ (T)at(0,0){\hmtcfont{#1\char"2660}};%
+ }%
+ \else{%
+ \tikz[baseline=(T.base)]
+ \node[hmtrump]
+ (T)at(0,0){\hmtcfont{#1}};%
+ }%
+ \fi\fi\fi\fi%
+}
+
+%%: \trumpx{ランク}
+\newcommand{\trumpx}[1]{\hmtc@strut\hmtc@trump@{\hmtc@rank@{#1}}{x}}
+
+
+%: \hm[S,H,D,C] => ãã‚Œãžã‚Œã®ã‚¹ãƒ¼ãƒˆã‚’出力
+\newcommand{\hmH}{\textcolor{hartsuit}{\hmtcfont\char"2665}}
+\newcommand{\hmD}{\textcolor{diasuit}{\hmtcfont\char"2666}}
+\newcommand{\hmC}{\textcolor{clubsuit}{\hmtcfont\char"2663}}
+\newcommand{\hmS}{\textcolor{spadesuit}{\hmtcfont\char"2660}}
+
+%: \joker ãªã©=> ジョーカー
+\newcommand{\BLACKJOKER}{\trumpx{\char"F5BC}}
+\newcommand{\WHITEJOKER}{\trumpx{\char"F5BD}}
+\newcommand{\REDJOKER}{\trumpx{\char"F5BE}}
+\newcommand{\JOKER}{\BLACKJOKER}
+
+\newcommand{\blackjoker}{\hmtc@joker@base{\char"F5BC}}
+\newcommand{\whitejoker}{\hmtc@joker@base{\char"F5BD}}
+\newcommand{\redjoker}{\hmtc@joker@base{\char"F5BE}}
+\newcommand{\joker}{\blackjoker}
+
+\newcommand{\hmtc@joker@base}[1]{\hmtc@strut{\hmtcfont%
+ \tikz[baseline=(T.base)]\node[hmtrump](T)at(0,0){
+ \parbox{1em}{
+ \fontsize{0.3em}{0}\rule{0pt}{0pt}\hfil\selectfont JOKER\hfil\rule{0pt}{0pt}\\
+ \fontsize{2.33em}{0}\selectfont\rule{0pt}{0pt}\hfil#1\hfil\rule{0pt}{0pt}%
+ }
+ };%
+}}
+
+
+%: \trumpblank => æž 
+\newcommand{\trumpblank}[1]{%
+ \rule[-0.65em]{0pt}{1.85em}\tikz[baseline=(T.base)]\node[hmtrump](T)at(0,0){#1};%
+}
+
+%: \romanindex => ローマ数字
+\newcounter{hmtc@roman}
+\newcommand{\romanindex}[1]{%
+ \ifnum#1=0\relax%
+ O%
+ \else\ifnum#1<13\relax%
+ \setcounter{hmtc@roman}{"215F}%
+ \addtocounter{hmtc@roman}{#1}%
+ {\hmtcfont\char\value{hmtc@roman}}%
+ \else\ifnum#1>12\relax%
+ \setcounter{hmtc@roman}{"EDCE}%
+ \addtocounter{hmtc@roman}{#1}%
+ {\hmtcfont\char\value{hmtc@roman}}%
+ \fi\fi\fi%
+}
+
+%: \tarottrump => タロットã®åˆ‡æœ­
+\newcommand{\tarottrump}[1]{\trumpx{\romanindex{#1}}}
+
+%: \unitrump => ユニコードã®ãƒˆãƒ©ãƒ³ãƒ—領域
+%%: カードã®åå‰ã‚’マクロã«è¢«è¦†
+% 通常ã®ãƒˆãƒ©ãƒ³ãƒ—
+\def\hmtc@uni@s@ace{AS} \def\hmtc@uni@h@ace{AH} \def\hmtc@uni@d@ace{AD} \def\hmtc@uni@c@ace{AC}
+\def\hmtc@uni@s@two{2S} \def\hmtc@uni@h@two{2H} \def\hmtc@uni@d@two{2D} \def\hmtc@uni@c@two{2C}
+\def\hmtc@uni@s@three{3S} \def\hmtc@uni@h@three{3H} \def\hmtc@uni@d@three{3D} \def\hmtc@uni@c@three{3C}
+\def\hmtc@uni@s@four{4S} \def\hmtc@uni@h@four{4H} \def\hmtc@uni@d@four{4D} \def\hmtc@uni@c@four{4C}
+\def\hmtc@uni@s@five{5S} \def\hmtc@uni@h@five{5H} \def\hmtc@uni@d@five{5D} \def\hmtc@uni@c@five{5C}
+\def\hmtc@uni@s@six{6S} \def\hmtc@uni@h@six{6H} \def\hmtc@uni@d@six{6D} \def\hmtc@uni@c@six{6C}
+\def\hmtc@uni@s@seven{7S} \def\hmtc@uni@h@seven{7H} \def\hmtc@uni@d@seven{7D} \def\hmtc@uni@c@seven{7C}
+\def\hmtc@uni@s@eight{8S} \def\hmtc@uni@h@eight{8H} \def\hmtc@uni@d@eight{8D} \def\hmtc@uni@c@eight{8C}
+\def\hmtc@uni@s@nine{9S} \def\hmtc@uni@h@nine{9H} \def\hmtc@uni@d@nine{9D} \def\hmtc@uni@c@nine{9C}
+\def\hmtc@uni@s@ten{TS} \def\hmtc@uni@h@ten{TH} \def\hmtc@uni@d@ten{TD} \def\hmtc@uni@c@ten{TC}
+\def\hmtc@uni@s@jack{JS} \def\hmtc@uni@h@jack{JH} \def\hmtc@uni@d@jack{JD} \def\hmtc@uni@c@jack{JC}
+\def\hmtc@uni@s@cavallo{CS} \def\hmtc@uni@h@cavallo{CH} \def\hmtc@uni@d@cavallo{CD} \def\hmtc@uni@c@cavallo{CC}
+\def\hmtc@uni@s@queen{QS} \def\hmtc@uni@h@queen{QH} \def\hmtc@uni@d@queen{QD} \def\hmtc@uni@c@queen{QC}
+\def\hmtc@uni@s@king{KS} \def\hmtc@uni@h@king{KH} \def\hmtc@uni@d@king{KD} \def\hmtc@uni@c@king{KC}
+% ジョーカー
+\def\hmtc@uni@joker@a{joker} \def\hmtc@joker@b{joker1} \def\hmtc@joker@c{joker2}
+% è£
+\def\hmtc@uni@back{back}
+% タロット
+\def\hmtc@uni@tarot@zero{0} \def\hmtc@uni@tarot@one{1} \def\hmtc@uni@tarot@two{2}
+\def\hmtc@uni@tarot@three{3} \def\hmtc@uni@tarot@four{4} \def\hmtc@uni@tarot@five{5}
+\def\hmtc@uni@tarot@six{6} \def\hmtc@uni@tarot@seven{7} \def\hmtc@uni@tarot@eight{8}
+\def\hmtc@uni@tarot@nine{9} \def\hmtc@uni@tarot@ten{10} \def\hmtc@uni@tarot@eleven{11}
+\def\hmtc@uni@tarot@twelve{12} \def\hmtc@uni@tarot@thirteen{13} \def\hmtc@uni@tarot@fourteen{14}
+\def\hmtc@uni@tarot@fifteen{15} \def\hmtc@uni@tarot@sixteen{16} \def\hmtc@uni@tarot@seventeen{17}
+\def\hmtc@uni@tarot@eighteen{18} \def\hmtc@uni@tarot@nineteen{19} \def\hmtc@uni@tarot@twenty{20}
+\def\hmtc@uni@tarot@twentyone{21}
+%%: 定義本体
+\newcommand{\unitrump}[1]{{\hmtcfont%
+ \def\hmtc@unitrump@arg{#1}%
+ % スペード
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@ace\relax\char"1F0A1\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@two\relax\char"1F0A2\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@three\relax\char"1F0A3\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@four\relax\char"1F0A4\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@five\relax\char"1F0A5\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@six\relax\char"1F0A6\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@seven\relax\char"1F0A7\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@eight\relax\char"1F0A8\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@nine\relax\char"1F0A9\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@ten\relax\char"1F0AA\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@jack\relax\char"1F0AB\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@cavallo\relax\char"1F0AC\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@queen\relax\char"1F0AD\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@s@king\relax\char"1F0AE\fi%
+ % ãƒãƒ¼ãƒˆ
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@ace\relax\char"1F0B1\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@two\relax\char"1F0B2\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@three\relax\char"1F0B3\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@four\relax\char"1F0B4\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@five\relax\char"1F0B5\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@six\relax\char"1F0B6\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@seven\relax\char"1F0B7\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@eight\relax\char"1F0B8\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@nine\relax\char"1F0B9\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@ten\relax\char"1F0BA\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@jack\relax\char"1F0BB\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@cavallo\relax\char"1F0BC\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@queen\relax\char"1F0BD\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@h@king\relax\char"1F0BE\fi%
+ % ダイヤ
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@ace\relax\char"1F0C1\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@two\relax\char"1F0C2\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@three\relax\char"1F0C3\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@four\relax\char"1F0C4\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@five\relax\char"1F0C5\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@six\relax\char"1F0C6\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@seven\relax\char"1F0C7\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@eight\relax\char"1F0C8\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@nine\relax\char"1F0C9\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@ten\relax\char"1F0CA\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@jack\relax\char"1F0CB\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@cavallo\relax\char"1F0CC\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@queen\relax\char"1F0CD\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@d@king\relax\char"1F0CE\fi%
+ % クラブ
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@ace\relax\char"1F0D1\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@two\relax\char"1F0D2\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@three\relax\char"1F0D3\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@four\relax\char"1F0D4\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@five\relax\char"1F0D5\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@six\relax\char"1F0D6\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@seven\relax\char"1F0D7\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@eight\relax\char"1F0D8\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@nine\relax\char"1F0D9\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@ten\relax\char"1F0DA\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@jack\relax\char"1F0DB\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@cavallo\relax\char"1F0DC\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@queen\relax\char"1F0DD\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@c@king\relax\char"1F0DE\fi%
+ % ジョーカー
+ \ifx\hmtc@unitrump@arg\hmtc@uni@joker@a\relax\char"1F0BF\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@joker@b\relax\char"1F0CF\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@joker@c\relax\char"1F0DF\fi%
+ % è£
+ \ifx\hmtc@unitrump@arg\hmtc@uni@back\relax\char"1F0A0\fi%
+ % タロット
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@zero\relax\char"1F0E0\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@one\relax\char"1F0E1\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@two\relax\char"1F0E2\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@three\relax\char"1F0E3\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@four\relax\char"1F0E4\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@five\relax\char"1F0E5\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@six\relax\char"1F0E6\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@seven\relax\char"1F0E7\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@eight\relax\char"1F0E8\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@nine\relax\char"1F0E9\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@ten\relax\char"1F0EA\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@eleven\relax\char"1F0EB\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@twelve\relax\char"1F0EC\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@thirteen\relax\char"1F0ED\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@fourteen\relax\char"1F0EE\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@fifteen\relax\char"1F0EF\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@sixteen\relax\char"1F0F0\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@seventeen\relax\char"1F0F1\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@eighteen\relax\char"1F0F2\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@nineteen\relax\char"1F0F3\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@twenty\relax\char"1F0F4\fi%
+ \ifx\hmtc@unitrump@arg\hmtc@uni@tarot@twentyone\relax\char"1F0F5\fi%
+}}
diff --git a/macros/luatex/latex/hmtrump/hmtrump.tex b/macros/luatex/latex/hmtrump/hmtrump.tex
new file mode 100644
index 0000000000..af607ee1e4
--- /dev/null
+++ b/macros/luatex/latex/hmtrump/hmtrump.tex
@@ -0,0 +1,372 @@
+%! LuaLaTeX
+\documentclass{jlreq}
+\usepackage{hmtrump}
+\usepackage{shortvrb,bxtexlogo}
+\usepackage[colorlinks,unicode=true]{hyperref}
+\hypersetup{linkcolor=blue,urlcolor=teal}
+\usepackage{tgheros,newpxtext,newpxmath}
+\usepackage[scaled]{beramono}
+\MakeShortVerb{\|}
+\usepackage[jfm_yoko=jlreq,jfm_tate=jlreqv]{luatexja-preset}
+\renewcommand{\thefootnote}{\textasteriskcentered\arabic{footnote}}
+\title{|hmtrump| Package}
+\author{ã²ã¨ã¿ã•ã‚“}
+\date{v1.2a [2019-08-06]}
+
+\begin{document}
+\maketitle
+
+\begin{center}
+Repository: \url{https://github.com/Hitomi-San/hmtrump}\\
+Font: \url{http://hwm3.gyao.ne.jp/shiroi-niwatori/nishiki-teki.htm}
+\end{center}
+
+\hrulefill
+\tableofcontents
+\pagebreak
+
+\section{What is this}
+You will be able to describe playing cards using |hmtrump| package.
+\emph{This package needs LuaLaTeX.}
+
+
+\section{How to use?}
+\begin{enumerate}
+\item Install NKD04 Playing Card's Index font
+\item |\usepackage{hmtrump}| in preamble
+\item To describe cards, use |\trump{<rank>}{<suit>}|
+\end{enumerate}
+
+\begin{description}
+\item[<rank>] 1 to 9, T (meaning 10), J, Q, K
+\item[<suit>] S (Spade), H (Hard), D (Diamond), C (Club), x (no suits)
+\end{description}
+
+\vspace*{5pt}
+\rule{0pt}{0pt}\hfil
+\begin{minipage}[t]{.45\textwidth}
+\centerline{output}\hrule\vspace*{1pt}\hrule
+\footnotesize
+When you play skat, you might remember all \trumpx J
+cards---\trump JC, \trump JS, \trump JH and \trump JD
+belong trump suit. If trump suit is \hmD{} and
+\trump TD is led, then you can follow with \trump JC.
+
+The rank of \trumpx{J} is below:
+\[\trump JC>\trump JS>\trump JH>\trump JD\]
+
+All joker---\joker, \blackjoker, \redjoker{} will not
+be used in skat.
+
+\hspace{1ex}\hrule\hspace{1ex}
+
+タロットカードã«ã¯ã€åˆ‡æœ­å°‚用ã®ã‚«ãƒ¼ãƒ‰\tarottrump{1}〜
+\tarottrump{21}ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚å ã„用ã®ã‚¿ãƒ­ãƒƒãƒˆã‚«ãƒ¼ãƒ‰
+ã«ã¯\trumpblank{愚者}ã®ã‚«ãƒ¼ãƒ‰ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€
+ã“ã‚Œã¯åˆ‡æœ­ã§ã¯ã‚ã‚Šã¾ã›ã‚“。
+\end{minipage}
+\hfil
+\begin{minipage}[t]{.45\textwidth}
+\centerline{input}\hrule\vspace*{1pt}\hrule
+\scriptsize\ttfamily
+When you play skat, you might remember all |\trumpx| J
+cards---|\trump| JC, |\trump| JS, |\trump| JH and |\trump| JD
+belong trump suit. If trump suit is |\hmD{}| and |\trump| TD
+is led, then you can follow with |\trump| JC.\\
+
+The rank of trumps are below:\\
+|\[|
+|\trump| JC > |\trump| JS > |\trump| JH > |\trump| JD
+|\]|\\
+All joker---|\joker|, |\blackjoker|, |\redjoker{}| will not
+be used in skat.\\
+
+|\hspace{1ex}\hrule\hspace{1ex}|\\
+
+タロットカードã«ã¯ã€åˆ‡æœ­å°‚用ã®ã‚«ãƒ¼ãƒ‰ |\tarottrump{1}|〜
+|\tarottrump{21}| ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚å ã„用ã®ã‚¿ãƒ­ãƒƒãƒˆã‚«ãƒ¼ãƒ‰ã«ã¯
+|\trumpblank{愚者}| ã®ã‚«ãƒ¼ãƒ‰ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ã“ã‚Œã¯åˆ‡æœ­ã§ã¯
+ã‚ã‚Šã¾ã›ã‚“。
+\end{minipage}
+\hfil\rule{0pt}{0pt}
+\vspace*{5pt}
+
+\section{ã“ã‚Œã¯ä½•}
+\TeX 文書中ã§ã€ãƒˆãƒ©ãƒ³ãƒ—ã®ã‚«ãƒ¼ãƒ‰ã‚’表ç¾ã™ã‚‹ãŸã‚ã®ãƒ‘ッケージã§ã™ã€‚
+|hmtrump| パッケージを利用ã™ã‚‹ã“ã¨ã§ã€æ¬¡ã®ã‚ˆã†ãªå‡ºåŠ›ã‚’å¾—ã‚‹
+ã“ã¨ãŒã§ãã¾ã™ã€‚内部㧠|fontspec| パッケージを読ã¿è¾¼ã‚“ã§ã„ã‚‹ã®ã§ã€
+\LuaLaTeX 専用ã®ãƒ‘ッケージã¨ãªã‚Šã¾ã™ï¼ˆ\XeLaTeX ã§ã‚‚å‹•ãã‹ã‚‚
+ã—ã‚Œãªã„ã‘ã©ã€å‹•ä½œç¢ºèªã—ã¦ãªã„ã®ã§éžå¯¾å¿œã§ã™ï¼‰ã€‚日本語文書中
+ã§ã‚‚使用ã§ãã¾ã™ã€‚
+
+\section{使ã„æ–¹}
+ã“ã®ãƒ‘ッケージã§ç”¨ã„ã¦ã„るトランプã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ç”¨ã®ãƒ•ã‚©ãƒ³ãƒˆã¯ã€
+åŒæ¢±ã®ãƒˆãƒ©ãƒ³ãƒ—ã®éš…å°çš„書体『NKD04 Playing Card's Indexã€Version 0.80
+\footnote{\url{http://hwm3.gyao.ne.jp/shiroi-niwatori/nishiki-teki.htm}}
+を用ã„ã¦ã„ã¾ã™ã€‚|hmtrump| パッケージを利用ã™ã‚‹å‰ã«ã€ã“ã®ãƒ•ã‚©ãƒ³ãƒˆã‚’
+\LuaTeX ã‹ã‚‰åˆ©ç”¨å¯èƒ½ãªå ´æ‰€ã«ä¿å­˜ã—ã¦ãã ã•ã„。通常ã¯ã“ã®ãƒ•ã‚©ãƒ³ãƒˆã‚’
+インストールã™ã‚Œã°ã‚ˆã„ã§ã™ã€‚フォントã®ä½œæˆè€…ã¯ã†ã¿ã»ãŸã‚‹æ§˜ã§ã™ã€‚
+パッケージ作æˆè€…ã§ã¯ã‚ã‚Šã¾ã›ã‚“。
+
+パッケージを読ã¿è¾¼ã‚€ã«ã¯|\usepackage{hmtrump}|をプリアンブルã«
+書ã„ã¦ãã ã•ã„。オプションã¯ã‚ã‚Šã¾ã›ã‚“。
+
+\section{ä¾å­˜ãƒ‘ッケージ}
+|hmtrump| パッケージã¯å†…部㧠|tikz|ã€|xcolor|ã€|fontspec| パッケージ
+を読ã¿è¾¼ã¿ã¾ã™ã€‚
+
+\section{æä¾›ã•ã‚Œã‚‹å‘½ä»¤}
+\begin{table}[tb]
+\centering
+\caption{例\label{ie}}
+\begin{tabular}{lc}
+\hline
+\multicolumn{1}{c}{入力/input}&出力/output\\
+\hline\hline
+|\trump{A}{S} \trump{J}{C}|&\trump {A}{S} \trump{J}{C}\\
+|\trump 7D \trump QH|&\trump 7D \trump QH\\
+|\trump 3x \trump Tx|&\trump 3x \trump Tx\\
+|\trumpx 6 \trumpx Q|&\trumpx 6 \trumpx Q\\
+\hline
+|\hmS \hmH \hmD \hmC|&\hmS \hmH \hmD \hmC\\
+\hline
+|\JOKER \joker|&\JOKER \joker\\
+|\BLACKJOKER \blackjoker|&\BLACKJOKER \blackjoker\\
+|\WHITEJOKER \whitejoker|&\WHITEJOKER \whitejoker\\
+|\REDJOKER \redjoker|&\REDJOKER \redjoker\\
+\hline
+|\unitrump{7H} \unitrump{KS}|&\unitrump{7H} \unitrump{KS}\\
+\hline
+|\trumpblank{愚者}|&\trumpblank{愚者}\\
+|\trumpblank{\hmtcfont PAGE}|&\trumpblank{\hmtcfont PAGE}\\
+\hline
+|\tarottrump{0}|&\tarottrump{0}\\
+|\tarottrump{14}|&\tarottrump{14}\\
+|\tarottrump{21}|&\tarottrump{21}\\
+\hline
+\end{tabular}
+\end{table}
+
+\subsection{\textbackslash trump 命令}
+|\trump{<ランク>}{<スート>}| ã®æ›¸å¼ã§ã€ãƒˆãƒ©ãƒ³ãƒ—ã®ã‚«ãƒ¼ãƒ‰ã‚’出力ã—ã¾ã™ã€‚
+|<ランク>| ã«ã¯é€šå¸¸ |A|ã€|1| ã‹ã‚‰ |9| ã®æ•´æ•°ã€|T|ã€|J|ã€|C|ã€|Q|ã€|K| ã®
+ã„ãšã‚Œã‹ãŒå…¥åŠ›ã•ã‚Œã‚‹ã“ã¨ã‚’想定ã—ã¦ã„ã¾ã™ã€‚|T| ã¨ã™ã‚‹ã¨
+{\fontspec{NKD04_Playing_Cards_Index}{\char"E002}}ãŒå‡ºåŠ›
+ã•ã‚Œã¾ã™ã€‚|<スート>| ã«ã¯ |S|(\hmS)ã€|H|(\hmH)ã€|D|(\hmD)ã€
+|C|(\hmC)|x|(スートã®æŒ‡å®šãªã—)ã®ã„ãšã‚Œã‹ã‚’指定ã—ã¾ã™ã€‚
+
+|\trump{<ランク>}{x}|ã¯|\trumpx{<ランク>}|ã¨æ›¸ãã“ã¨ã‚‚ã§ãã¾ã™ã€‚
+
+\subsection{スート出力命令}
+|\hmS|ã€|\hmH|ã€|\hmD|ã€|\hmC| ã¯ãã‚Œãžã‚Œ \hmSã€\hmHã€
+\hmDã€\hmC を出力ã—ã¾ã™ã€‚
+
+\subsection{ジョーカー出力命令}
+|\JOKER| ã‚„ |\joker| ã§\JOKER ã‚„\joker を出力ã—ã¾ã™ã€‚
+ジョーカー出力命令ã¯8種類ã‚ã‚Šã¾ã™ã€‚表\ref{ie}ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+デフォルトã§ã¯ã€|\JOKER| 㯠|\BLACKJOKER|ã«ãªã‚Šã€
+|\joker| 㯠|\blackjoker| ã¨ãªã£ã¦ã„ã¾ã™ã€‚å¿…è¦ã«
+å¿œã˜ã¦ã€|\renewcommand{\joker}{\whitejoker}| ãªã©ã¨ã™ã‚‹ã“ã¨ãŒ
+ã§ãã¾ã™ã€‚
+
+\subsection{\textbackslash unitrump 命令}
+|\unitrump{<ランク><スート>}| ã®æ›¸å¼ã§ã€Unicodeã®ãƒˆãƒ©ãƒ³ãƒ—領域ã®
+文字を出力ã—ã¾ã™ã€‚例ãˆã°ã€|\unitrump{QC}| ã‚„ |\unitrump{TD}| ã§ã€
+\unitrump{QC} ã‚„ \unitrump{TD} ãŒå‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+\footnote{\texttt{\textbackslash unitrump} 命令ã§å‡ºåŠ›ã•ã‚Œã‚‹æ–‡å­—ã¯ã€
+\LuaLaTeX-ja を用ã„ã¦ã„ã‚‹å ´åˆã¯ã€\textbf{AJchar} ã¨ã—ã¦å‡ºåŠ›ã•ã‚Œã¾ã™ã€‚}
+
+ãã®ä»–ã€Unicode ã®ãƒˆãƒ©ãƒ³ãƒ—領域ã«ã‚る文字ãªã‚‰ã°ã€ã™ã¹ã¦å‡ºåŠ›ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+|\unitrump|を用ã„ã¦å‡ºåŠ›ã§ãる文字ã¯ã€è¡¨\ref{unitrump}ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+
+\begin{table}[tb]
+\caption{\textbackslash unitrump 命令ã§å‡ºåŠ›ã§ãる文字\label{unitrump}}
+\centering
+\begin{tabular}{cc}
+\hline
+引数/argument&出力/output\\
+\hline\hline
+|AS AH AD AC|&\unitrump{AS} \unitrump{AH} \unitrump{AD} \unitrump{AC}\\
+|2S 2H 2D 2C|&\unitrump{2S} \unitrump{2H} \unitrump{2D} \unitrump{2C}\\
+|3S 3H 3D 3C|&\unitrump{3S} \unitrump{3H} \unitrump{3D} \unitrump{3C}\\
+|4S 4H 4D 4C|&\unitrump{4S} \unitrump{4H} \unitrump{4D} \unitrump{4C}\\
+|5S 5H 5D 5C|&\unitrump{5S} \unitrump{5H} \unitrump{5D} \unitrump{5C}\\
+|6S 6H 6D 6C|&\unitrump{6S} \unitrump{6H} \unitrump{6D} \unitrump{6C}\\
+|7S 7H 7D 7C|&\unitrump{7S} \unitrump{7H} \unitrump{7D} \unitrump{7C}\\
+|8S 8H 8D 8C|&\unitrump{8S} \unitrump{8H} \unitrump{8D} \unitrump{8C}\\
+|9S 9H 9D 9C|&\unitrump{9S} \unitrump{9H} \unitrump{9D} \unitrump{9C}\\
+|TS TH TD TC|&\unitrump{TS} \unitrump{TH} \unitrump{TD} \unitrump{TC}\\
+|JS JH JD JC|&\unitrump{JS} \unitrump{JH} \unitrump{JD} \unitrump{JC}\\
+|CS CH CD CC|&\unitrump{CS} \unitrump{CH} \unitrump{CD} \unitrump{CC}\\
+|QS QH QD QC|&\unitrump{QS} \unitrump{QH} \unitrump{QD} \unitrump{QC}\\
+|KS KH KD KC|&\unitrump{KS} \unitrump{KH} \unitrump{KD} \unitrump{KC}\\
+\hline
+|back|&\unitrump{back}\\
+\hline
+|joker joker1 joker2|&\unitrump{joker} \unitrump{joker1} \unitrump{joker2}\\
+\hline
+|0|&\unitrump{0}\\
+|1 2 3 4 5 6 7|&
+ \unitrump{1} \unitrump{2} \unitrump{3} \unitrump{4} \unitrump{5} \unitrump{6} \unitrump{7}\\
+|8 9 10 11 12 13 14|&
+ \unitrump{8} \unitrump{9} \unitrump{10} \unitrump{11} \unitrump{12} \unitrump{13} \unitrump{14}\\
+|15 16 17 18 19 20 21|&
+ \unitrump{15} \unitrump{16} \unitrump{17} \unitrump{18} \unitrump{19} \unitrump{20} \unitrump{21}\\
+\hline
+\end{tabular}
+\end{table}
+
+\subsection{汎用カード命令}
+|\trumpblank{<内容>}| ã§ä¸€èˆ¬ã®ã‚«ãƒ¼ãƒ‰ã‚’出力ã—ã¾ã™ã€‚カードã®ä¸­èº«
+ã¯æœ¬æ–‡æ›¸ä½“ã§è¡¨ç¤ºã•ã‚Œã‚‹ã®ã§ã€å¿…è¦ãŒã‚ã‚Œã°é©å½“ã« |\textsf| ã‚„ |\textbf|
+ãªã©ã‚’補ã£ã¦ãã ã•ã„。|\hmtcfont| 命令
+㧠NKD04 Playing Card's Index を利用ã§ãã¾ã™ï¼ˆ|\hmtcfont|
+ã¯å®£è¨€åž‹ã®å‘½ä»¤ã§ã™ï¼‰ã€‚例ãˆã°ã€|\trumpblank{\hmtcfont JOKER}|
+ã§\trumpblank{\hmtcfont JOKER}を出力ã—ã¾ã™ã€‚
+
+\subsection{タロットカードã®åˆ‡æœ­ç”¨å‘½ä»¤}
+|\tarottrump{<æ•°å­—>}| ã§ã€ã‚¿ãƒ­ãƒƒãƒˆã®åˆ‡æœ­ã‚’出力ã§ãã¾ã™ã€‚|<æ•°å­—>| ã«ã¯
+0ã‹ã‚‰21ã®æ•´æ•°ãŒå…¥ã‚Šã¾ã™ã€‚例ãˆã°ã€|\tarottrump{8}| ã§\tarottrump{8}ãŒ
+出力ã•ã‚Œã¾ã™ã€‚|\tarottrump{0}| ã¯æ„šè€…ã®ã‚«ãƒ¼ãƒ‰ã‚’出力ã™ã‚‹ç›®çš„ã§ç”¨ã„ã€
+\tarottrump{0}ãŒå‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+
+\section{カスタマイズ}
+|\renewcommand| ãªã©ã‚’ã™ã‚‹ã“ã¨ã«ã‚ˆã£ã¦ã€å‡ºåŠ›çµæžœã‚’カスタマイズ
+ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+
+\subsection{フォントå}
+NKD04\_Playing\_Cards\_Index ã‚’é•ã†ãƒ•ã‚©ãƒ³ãƒˆåã§ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ãŸå ´åˆã€
+|\hmtc@trump@font| をインストールã—ãŸãƒ•ã‚©ãƒ³ãƒˆåã« |\renewcommand| ã§
+定義ã—ç›´ã—ã¦ãã ã•ã„。
+
+\textbf{注æ„}: NKD04 Playing Card's Index Version 0.80 ã®ç§ç”¨é ˜åŸŸã‚’
+å‰æã¨ã—ã¦ã„ã‚‹ã®ã§ã€ä»–ã®ãƒ•ã‚©ãƒ³ãƒˆã‚’指定ã—ãŸå ´åˆã¯ã†ã¾ãå‹•ãã¾ã›ã‚“。
+
+\subsection{色}
+\begin{table}[tb]
+\centering
+\caption{変更å¯èƒ½ãªè‰²\label{color}}
+\begin{tabular}{lll}
+\hline
+色ã®åå‰&デフォルトã®å®šç¾©&色ã®ç®‡æ‰€\\
+\hline\hline
+|hartsuit|&|{cmyk}{.14,.94,.22,.27}|&ãƒãƒ¼ãƒˆã®ã‚¹ãƒ¼ãƒˆåŠã³ã‚«ãƒ¼ãƒ‰ã®æ–‡å­—\\
+|diasuit|&|{cmyk}{.11,.57,.97,.31}|&ダイヤã®ã‚¹ãƒ¼ãƒˆåŠã³ã‚«ãƒ¼ãƒ‰ã®æ–‡å­—\\
+|clubsuit|&|{cmyk}{.70,.5,.99,.18}|&クラブã®ã‚¹ãƒ¼ãƒˆåŠã³ã‚«ãƒ¼ãƒ‰ã®æ–‡å­—\\
+|spadesuit|&|{cmyk}{.98,.80,.5,.15}|&スペードã®ã‚¹ãƒ¼ãƒˆåŠã³ã‚«ãƒ¼ãƒ‰ã®æ–‡å­—\\
+\hline
+|cardback|&|{gray}{.95}|&カードã®èƒŒæ™¯\\
+|cardborder|&|{gray}{.2}|&カードã®æž ç·š\\
+|cardtext|&|{gray}{0}|&スート指定ã®ãªã„カードã®æ–‡å­—\\
+\hline
+\end{tabular}
+\end{table}
+
+視èªã—ã‚„ã™ã„よã†ã€|hmtrump| パッケージã§ã¯ã‚¹ãƒ¼ãƒˆã®ãƒžãƒ¼ã‚¯ã¨ã€
+スートã®ãƒžãƒ¼ã‚¯ã‚’ä¼´ã†ã‚«ãƒ¼ãƒ‰ã‚’出力ã™ã‚‹æ™‚ã«ã€è‰²ã‚’使ã£ã¦å‡ºåŠ›ã—ã¾ã™ã€‚
+デフォルトã§ã¯ã€ç™½é»’å°åˆ·ã«ã‚‚è€ãˆã‚Œã‚‹ã‚ˆã†ã€ãã‚Œãžã‚Œå½©åº¦ã‚’è½ã¨ã—ãŸ
+色ã«ãªã£ã¦ã„ã¾ã™ã€‚
+
+色を変更ã—ãŸã„å ´åˆã¯ã€|xcolor| パッケージãŒæä¾›ã—ã¦ã„る〠|\definecolor|
+命令を使ã£ã¦ã€è‰²ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚変更ã§ãる色ã®å®šç¾©ã¯ã€è¡¨\ref{color}ã«
+示ã—ã¦ã‚ã‚‹ã¨ãŠã‚Šã§ã™ã€‚
+
+例ãˆã°ã€|\definecolor{hartsuit}{cmyk}{0,.84,.94,.01}| ã¨æ›¸ã„ã¦ãŠã‘ã°ã€
+|\hmH| ã§{\definecolor{hartsuit}{cmyk}{0,.84,.94,.01}\hmH}ãŒå‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+|\definecolor| 命令ã¯ã€å±€æ‰€åŒ–ã®å½±éŸ¿ã‚’å—ã‘ã‚‹ã®ã§ã€|{}| ã§æ‹¬ã‚Œã°
+一部ã ã‘ã®è‰²ã‚’変ãˆã‚‹ã“ã¨ã‚‚å¯èƒ½ã§ã™ã€‚
+
+\subsection{サイズ}
+|\tikzset|命令を使ã£ã¦ã€å‡ºåŠ›ã•ã‚Œã‚‹ã‚«ãƒ¼ãƒ‰ã®ã‚µã‚¤ã‚ºã‚’変更ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+
+|\tikzset{hmtcscale/.style={scale=<å€çŽ‡>}}| ã¨æ›¸ãã“ã¨ã§æŒ‡å®šã—ãŸå€çŽ‡ã®
+カードãŒå‡ºåŠ›ã•ã‚Œã¾ã™ã€‚デフォルトã§ã¯ 0.9 å€ã«ãªã£ã¦ã„ã¾ã™ã€‚ã“ã¡ã‚‰ã‚‚局所化ã®å½±éŸ¿ã‚’
+ã†ã‘ã¾ã™ã€‚ベースラインã®ä½ç½®ã¯å›ºå®šã§ã™ã€‚
+
+例ãˆã° |{\tikzset{hmtcscale/.style={scale=0.6}}\trump 3H}\trump JD| ã¨
+書ã㨠{\tikzset{hmtcscale/.style={scale=0.6}}\trump 3H}\trump JD ãŒå‡ºåŠ›ã•ã‚Œã¾ã™ã€‚
+
+\section{ãã®ä»–}
+\begin{itemize}
+\item \LuaLaTeX-ja を利用ã—ã¦ã„ã‚‹å ´åˆã€|\ltjdefcharrange| 命令を用ã„ã¦ã€24番ã®
+ 文字範囲ã«ã„ãã¤ã‹ã®æ–‡å­—を追加ã—ã€ãれらを\textbf{ALchar}ã¨ã—ã¦è¨­å®šã—ã¾ã™ã€‚
+ 文字範囲を変更ã—ã¦ã„ã‚‹å ´åˆã€24番ã®æ–‡å­—範囲ã«ã¯æ–°ã—ã文字を追加ã—ãŸã‚Šã€\textbf{JAchar}
+ ã¨ã—ã¦è¨­å®šã—ãªã„よã†ã«æ³¨æ„ã—ã¦ãã ã•ã„。
+\end{itemize}
+
+\section{TO DO}
+以下実装ã—ãŸã„ã¨æ€ã£ã¦ã„ã‚‹ã“ã¨:
+\begin{itemize}
+\item |\trump| 命令ã«ä¸æ­£ãªã‚¹ãƒ¼ãƒˆã®æŒ‡å®šå­ãŒæŒ‡å®šã•ã‚ŒãŸæ™‚ã«ã‚¨ãƒ©ãƒ¼ã‚’åãよã†ã«ã™ã‚‹ã€‚
+\item ã‚‚ã—ã‹ã—ãªãã¦ã‚‚ |\joker| 命令ã§å‡ºåŠ›ã•ã‚Œã‚‹ã‚«ãƒ¼ãƒ‰ã€è‹¥å¹²ä½ç½®ãŒä¸‹ãŒã£ã¦ã¾ã™ã­â€¦â€¦ã€‚
+\end{itemize}
+
+\section{License}
+
+\rule{0pt}{0pt}\hfill\includegraphics[height=2\zh]{by-sa.png}\hfill\rule{0pt}{0pt}
+
+ã“ã®ãƒ‘ッケージã«å«ã¾ã‚Œã‚‹æˆæžœç‰©ã¯ã€ã‚¯ãƒªã‚¨ã‚¤ãƒ†ã‚£ãƒ–・コモンズ 表示--継承
+ライセンスã®å…ƒã§é…布を行ã†ã€‚
+
+NKD04 Playing Card's Index フォントã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã¯ã€é…布元ã§ç¤ºã•ã‚Œã¦ã„る通りã®
+æ¡ä»¶ã«å¾“ã†ã€‚ã™ãªã‚ã¡ã€å•†ç”¨ç§ç”¨å•ã‚ãšè‡ªç”±ã«ä½¿ç”¨ã§ãã€é…布元
+\url{http://hwm3.gyao.ne.jp/shiroi-niwatori/nishiki-teki.htm}
+を示ã›ã°å†é…布もå¯èƒ½ã§ã‚る。原文ã¯ä¸‹ã«ç¤ºã™ã€‚
+
+This package is licensed under a Creative Commons Attribution-ShareAlike
+4.0 International License.
+
+NKD04 Playing Card's Index is licensed under following;
+There is no restriction on using NKD04 Playing Card's Index regardless
+of private or commercial, and it is possible to redistribute this.
+In the case of redistribution, please specify this distribution source
+\url{http://hwm3.gyao.ne.jp/shiroi-niwatori/nishiki-teki.htm}.
+The original text is shown below.
+
+以下ãŒã€\url{http://hwm3.gyao.ne.jp/shiroi-niwatori/faq.txt}ã«ã¦è¨˜ã•ã‚Œã¦ã„ã‚‹ã€
+フォントã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®å…¨æ–‡ã§ã‚る(「以下å„フォントã€ã«
+nkd04\_playing\_cards\_index.ttf ã‚‚å«ã¾ã‚Œã¦ã„る)。
+
+\noindent\hspace{1cm}\dotfill\hspace{1cm}
+
+\bgroup\small
+\url{http://hwm3.gyao.ne.jp/shiroi-niwatori/nishiki-teki.htm}
+ã«ã¦é…布ã—ã¦ã„る「ã«ã—ã的フォントã€ä»¥ä¸‹å„フォントã§ã®æ–‡æ›¸ã‚„ç”»åƒã®ä½œæˆã€
+装飾ã¨ã—ã¦ã®åˆ©ç”¨ç­‰ã€ä¸€èˆ¬çš„ãªç›®çš„ã§ã®ä½¿ç”¨ã«ã¤ã„ã¦ã¯ä½•ã®åˆ¶é™ã‚‚ã‚ã‚Šã¾ã›ã‚“。
+ç§ç”¨å•†ç”¨ã‚’å•ã‚ãšå­˜åˆ†ã«ã”自由ã«ãŠã“ãªã£ã¦ãã ã•ã„。
+
+ゲームãªã©ã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ´ã¸ã®åŒæ¢±ã‚„ã€ãã®ä»–ãªã‚“らã‹ã®å½¢ã®å†é…布ã«ã¤ã„ã¦ã‚‚ã€å¿…è¦ã§ã‚ã‚Œã°ã‹ã¾ã„ã¾ã›ã‚“。
+å†é…布ã®å ´åˆã¯å½“é…布元ã¯æ˜Žç¤ºã—ã¦ãŠã„ã¦ã„ãŸã ã‘ã‚Œã°ã¨æ€ã„ã¾ã™ (当é…布元ãŒæ¶ˆæ»…ã—ãŸå ´åˆã¯ä¸è¦ã§ã™)。
+
+フォントã¯ã¨ãã©ãæ›´æ–°ã—ã¦ã„ãŸã‚Šã™ã‚‹ã®ã§ã€ãªã‚‹ã¹ã最新版をãŠä½¿ã„ã„ãŸã ã‘ã‚‹ã¨å¬‰ã—ã„ã§ã™ã€‚
+特ã«ã€Œã«ã—ã的フォントã€(Nishiki-teki) ã¯æ–‡å­—ã®è¿½åŠ ã‚„修正等をã‹ãªã‚Šé »ç¹ã«ãŠã“ãªã£ã¦ãŠã‚Šã¾ã™ã€‚
+
+フォントã®ä½¿ç”¨ã«éš›ã—ã¦å½“æ–¹ã¸ã®å ±å‘Šãªã©ã¯ç‰¹ã«å¿…è¦ã‚ã‚Šã¾ã›ã‚“。
+ãŒã€ã”一報ãªã©ã„ãŸã ã‘ã¾ã—ãŸå ´åˆã«ã¯ä½¿ã£ã¦ãã ã•ã£ã¦ã‚ã‚ŠãŒãŸã„ãªã‚ã¨å–œã³ã¤ã¤ä»Šå¾Œã®å‚考ã«ã•ã›ã¦
+ã„ãŸã ã„ãŸã‚Šå¿ƒã®ç³§ã¨ã—ã¦åŠ±ã¿ã«ã™ã‚‹ãªã©ã„ãŸã—ã¾ã™ã€‚
+
+ãªã«ã‹ç–‘å•ç‚¹ã‚„至らã¬ç‚¹ãªã©ã”ã–ã„ã¾ã—ãŸã‚‰å¿Œæ†šãªããŠå•ã„åˆã‚ã›ãã ã•ã„。\\
+\url{http://hwm3.gyao.ne.jp/shiroi-niwatori/quispiam_est.htm}\\
+ã“ã®ãƒšãƒ¼ã‚¸ä¸‹éƒ¨ã®Webæ‹æ‰‹ã‚ãŸã‚Šã‚’ã”利用ã„ãŸã ã‘ã‚Œã°ã¨å­˜ã˜ã¾ã™ã€‚
+当方ã‹ã‚‰ã®è¿”答㯠\url{http://d.hatena.ne.jp/Umihotaru/} ã“ã¡ã‚‰ã‚’ã”覧ã«ãªã£ã¦ãã ã•ã„。
+
+
+\hspace{3\zw}2016-03-18\hspace{1\zw}ã†ã¿ã»ãŸã‚‹æ‹
+\egroup
+
+\section{Change log}
+\begin{description}
+\item[{[2019-08-06 ver.~1.2a]}] |\newfontfamily| を覚ãˆãŸã€‚
+\item[{[2019-06-13 ver.~1.1b]}] マニュアルã®èª¤æ¤ã‚’修正。
+\item[{[2019-06-12 ver.~1.1a]}] |\unitrump| 命令を追加。
+\item[{[2019-06-12 ver.~1.1a]}] マニュアルã®èª¤æ¤ã‚’修正。
+\item[{[2019-05-21 ver.~1.0d]}] フォントã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã‚’明記。
+\item[{[2019-05-15 ver.~1.0c]}] ライセンスを明記。
+\item[{[2019-05-14 ver.~1.0b]}] |\@undefined| を使ã†ã“ã¨ã‚’覚ãˆãŸã€‚
+\item[{[2019-05-14 ver.~1.0b]}] 英文ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’作æˆã€‚
+\item[{[2019-04-14 ver.~1.0]}] |hmtrump.sty| ã«ä½œè€…を明記。
+\item[{[2019-04-14 ver.~1.0]}] ドキュメントã®ã‚µãƒ³ã‚»ãƒªãƒ•ãƒ•ã‚©ãƒ³ãƒˆã‚’変更。
+\item[{[2019-04-14 ver.~1.0]}] TO DO を追加。
+\end{description}
+
+\end{document}
diff --git a/macros/luatex/latex/hmtrump/nkd04_playing_cards_index/LICENSE b/macros/luatex/latex/hmtrump/nkd04_playing_cards_index/LICENSE
new file mode 100644
index 0000000000..dad2dab2f5
--- /dev/null
+++ b/macros/luatex/latex/hmtrump/nkd04_playing_cards_index/LICENSE
@@ -0,0 +1,62 @@
+以下ã¯ã€http://hwm3.gyao.ne.jp/shiroi-niwatori/faq.txt ã«ã¦è¨˜ã•ã‚Œã¦ã„ã‚‹ã€
+フォントã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã®å…¨æ–‡ã§ã‚る。
+(「以下å„フォントã€ã« nkd04_playing_cards_index.ttf ã‚‚å«ã¾ã‚Œã¦ã„る)
+
+-------------------------
+
+http://hwm3.gyao.ne.jp/shiroi-niwatori/nishiki-teki.htm
+ã«ã¦é…布ã—ã¦ã„る「ã«ã—ã的フォントã€ä»¥ä¸‹å„フォントã§ã®æ–‡æ›¸ã‚„ç”»åƒã®ä½œæˆã€
+装飾ã¨ã—ã¦ã®åˆ©ç”¨ç­‰ã€ä¸€èˆ¬çš„ãªç›®çš„ã§ã®ä½¿ç”¨ã«ã¤ã„ã¦ã¯ä½•ã®åˆ¶é™ã‚‚ã‚ã‚Šã¾ã›ã‚“。
+ç§ç”¨å•†ç”¨ã‚’å•ã‚ãšå­˜åˆ†ã«ã”自由ã«ãŠã“ãªã£ã¦ãã ã•ã„。
+
+ゲームãªã©ã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ´ã¸ã®åŒæ¢±ã‚„ã€ãã®ä»–ãªã‚“らã‹ã®å½¢ã®å†é…布ã«ã¤ã„ã¦ã‚‚ã€å¿…è¦ã§ã‚ã‚Œã°ã‹ã¾ã„ã¾ã›ã‚“。
+å†é…布ã®å ´åˆã¯å½“é…布元ã¯æ˜Žç¤ºã—ã¦ãŠã„ã¦ã„ãŸã ã‘ã‚Œã°ã¨æ€ã„ã¾ã™ (当é…布元ãŒæ¶ˆæ»…ã—ãŸå ´åˆã¯ä¸è¦ã§ã™)。
+
+フォントã¯ã¨ãã©ãæ›´æ–°ã—ã¦ã„ãŸã‚Šã™ã‚‹ã®ã§ã€ãªã‚‹ã¹ã最新版をãŠä½¿ã„ã„ãŸã ã‘ã‚‹ã¨å¬‰ã—ã„ã§ã™ã€‚
+特ã«ã€Œã«ã—ã的フォントã€(Nishiki-teki) ã¯æ–‡å­—ã®è¿½åŠ ã‚„修正等をã‹ãªã‚Šé »ç¹ã«ãŠã“ãªã£ã¦ãŠã‚Šã¾ã™ã€‚
+
+フォントã®ä½¿ç”¨ã«éš›ã—ã¦å½“æ–¹ã¸ã®å ±å‘Šãªã©ã¯ç‰¹ã«å¿…è¦ã‚ã‚Šã¾ã›ã‚“。
+ãŒã€ã”一報ãªã©ã„ãŸã ã‘ã¾ã—ãŸå ´åˆã«ã¯ä½¿ã£ã¦ãã ã•ã£ã¦ã‚ã‚ŠãŒãŸã„ãªã‚ã¨å–œã³ã¤ã¤ä»Šå¾Œã®å‚考ã«ã•ã›ã¦
+ã„ãŸã ã„ãŸã‚Šå¿ƒã®ç³§ã¨ã—ã¦åŠ±ã¿ã«ã™ã‚‹ãªã©ã„ãŸã—ã¾ã™ã€‚
+
+ãªã«ã‹ç–‘å•ç‚¹ã‚„至らã¬ç‚¹ãªã©ã”ã–ã„ã¾ã—ãŸã‚‰å¿Œæ†šãªããŠå•ã„åˆã‚ã›ãã ã•ã„。
+http://hwm3.gyao.ne.jp/shiroi-niwatori/quispiam_est.htm
+ã“ã®ãƒšãƒ¼ã‚¸ä¸‹éƒ¨ã®Webæ‹æ‰‹ã‚ãŸã‚Šã‚’ã”利用ã„ãŸã ã‘ã‚Œã°ã¨å­˜ã˜ã¾ã™ã€‚
+当方ã‹ã‚‰ã®è¿”答㯠http://d.hatena.ne.jp/Umihotaru/ ã“ã¡ã‚‰ã‚’ã”覧ã«ãªã£ã¦ãã ã•ã„。
+
+
+   2016-03-18 ã†ã¿ã»ãŸã‚‹æ‹
+
+======================
+
+This is license written of ``Nishiki-teki font,'' including NKD04 Playing Card’s Index,
+in http://hwm3.gyao.ne.jp/shiroi-niwatori/faq.txt
+
+-------------------------
+
+There is no restriction on using each font distributed on
+http://hwm3.gyao.ne.jp/shiroi-niwatori/nishiki-teki.htm, such as ``Nishiki-teki,''
+for general purpose such as creation of documents and images, use as decoration, etc.
+Please do it freely regardless of private or commercial.
+
+It is possible, if necessary, to bundle the fonts into an archive, such as a game,
+or to redistribute them in some other way. In the case of redistribution, please
+specify this distribution source (it is not necessary if this distribution source
+has disappeared).
+
+The fonts are updated from time to time, so I hope you will use the latest version
+as much as possible. In particular, "Nishiki-teki" frequently adds characters and
+makes corrections.
+
+There is no need to report to us when using fonts. However, if you do so, I would
+like to thank you for using it, and I will use it as a reference for the future, or
+as a source of encouragement.
+
+Please feel free to contact us if you have any questions or concerns.
+http://hwm3.gyao.ne.jp/shiroi-niwatori/quispiam_est.htm
+
+We hope you can use Web Clap at the bottom of this page.
+The response from me http://d.hatena.ne.jp/Umihotaru/ Please see here.
+
+2016-03-18 Umihotaru
+(translated by Shoma Hitomi 2019-05-21)
diff --git a/macros/luatex/latex/hmtrump/nkd04_playing_cards_index/nkd04_playing_cards_index.ttf b/macros/luatex/latex/hmtrump/nkd04_playing_cards_index/nkd04_playing_cards_index.ttf
new file mode 100644
index 0000000000..e11169e7fc
--- /dev/null
+++ b/macros/luatex/latex/hmtrump/nkd04_playing_cards_index/nkd04_playing_cards_index.ttf
Binary files differ
diff --git a/macros/luatex/latex/hmtrump/nkd04_playing_cards_index/readme.txt b/macros/luatex/latex/hmtrump/nkd04_playing_cards_index/readme.txt
new file mode 100644
index 0000000000..56288cc074
--- /dev/null
+++ b/macros/luatex/latex/hmtrump/nkd04_playing_cards_index/readme.txt
@@ -0,0 +1,55 @@
+
+ _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
+
+
+ TrueTypeフォント トランプã®éš…å°çš„書体
+ 『NKD04 Playing Card's Indexã€
+ Version 0.80
+
+
+ _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
+
+
+
+ * トランプã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã«ã‚ˆã使ã‚れるよã†ãªæ•°å­—や文字ã®æ›¸ä½“を摸ã—ãŸã‚¹ãƒ©ãƒ–セリフ体ã®ãƒ•ã‚©ãƒ³ãƒˆã§ã™ã€‚
+
+ * インデックス index ã¨ã¯ã€ãƒˆãƒ©ãƒ³ãƒ—ã®ã‚«ãƒ¼ãƒ‰ã®éš…ã«æŒ¯ã‚‰ã‚Œã¦ã„ã‚‹æ•°å­—ã¨ã‚¹ãƒ¼ãƒˆ (♠♥♦♣) ã®è¡¨ç¤ºã®ã“ã¨ã§ã™ã€‚
+ * å°å­¦é¤¨ã€Žãƒ©ãƒ³ãƒ€ãƒ ãƒã‚¦ã‚¹è‹±å’Œå¤§è¾žå…¸ã€ã§ã¯ã“ã® index ã«å¯¾ã—ã¦
+ * 「隅å°(ã™ã¿ã˜ã‚‹ã—)ã€ã¨ã„ã†å’Œè¨³èªžã‚’示ã—ã¦ã„ã¾ã™ãŒã€ã‚ã¾ã‚Šä¸€èˆ¬ã«çŸ¥ã‚‰ã‚ŒãŸç”¨èªžã§ã¯ãªã•ãã†ã§ã™ã€‚
+
+
+ * 当フォントã¯ASCII文字ã®ã»ã‹ã«ã€ä»Šã®ã¨ã“ã‚以下ã®æ–‡å­—や記å·ã‚’å«ã‚“ã§ã„ã¾ã™:
+
+¼½¾ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯ○â—★☆♠♡♢♣♤♥♦♧â¤
+
+ * ã¾ãŸã€Unicodeã®ã€ŒPlaying Cardsã€ãƒ–ロック (U+1F0A0..1F0FF) ã«ã€æ•°å­—ã¨ã‚¹ãƒ¼ãƒˆã‚’ç°¡ç´„ã«ç¤ºã—ãŸå›³æŸ„ã‚’
+ * åŽéŒ²ã—ã¦ã„ã¾ã™ã€‚
+
+ * ãã®ã»ã‹ã€ç§ç”¨é ˜åŸŸã«ä»¥ä¸‹ã®ã‚‚ã®ã‚’åŽã‚ã¦ã„ã¾ã™ã€‚
+
+U+E000  ブランクカード
+U+E001 î€ åˆæˆç”¨ã‚«ãƒ¼ãƒ‰æž 
+U+E002  数字10
+U+E003  数字11
+U+E004  数字12
+U+E005  数字13
+U+EDDB  ローマ数字XIII
+U+EDDC  ローマ数字XIV
+U+EDDD î· ãƒ­ãƒ¼ãƒžæ•°å­—XV
+U+EDDE  ローマ数字XVI
+U+EDDF  ローマ数字XVII
+U+EDE0  ローマ数字XVIII
+U+EDE1  ローマ数字XIX
+U+EDE2  ローマ数字XX
+U+EDE3  ローマ数字XXI
+U+F5BC ï–¼ ジョーカーã®ã‚·ãƒ³ãƒœãƒ«é»’
+U+F5BD ï–½ ジョーカーã®ã‚·ãƒ³ãƒœãƒ«ç™½
+U+F5BE ï–¾ ジョーカーã®ã‚·ãƒ³ãƒœãƒ«èµ¤(縦縞)
+
+
+
+
+ 制作: ã†ã¿ã»ãŸã‚‹
+ ni.wa.torigairu@gmail.com
+ http://hwm3.gyao.ne.jp/shiroi-niwatori/nishiki-teki.htm
+
diff --git a/macros/luatex/latex/lilyglyphs/CHANGES.md b/macros/luatex/latex/lilyglyphs/CHANGES.md
new file mode 100644
index 0000000000..f99c28209e
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/CHANGES.md
@@ -0,0 +1,142 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+*lilyglyphs* - Release Notes
+============================
+This document lists all changes in the development of *lilyglyphs*.
+All changes should be present in the manual, but only the finished versions printed bold are available as pdf downloads. (Latest changes are only found in the master branch of the git repository. They should be documentd in the lilyglyphs.tex file there too.)
+So the lines above the topmost bold version line represent the changes not available in the downloadable pdf documentation.
+
+0.2.3
+---
+(2014-03-13)
+Some enhancements and additions, new version of the font files
+
+- Update Emmentaler fonts to 2.18.0
+- Provide consistent BE and AE versions of singlenote commands
+- Add set of articulation symbols
+- Add a set of \threeBeamedQuavers commands
+- Add \demisemiquaver commands (up/down, dotted)
+- Fix trailing space of \quaver and \semiquaver
+ (may affect spacing of existing documents)
+
+0.2.2
+-----
+(2013-09-27)
+Mainly resolving some issues that have become visible *due to* the intial release
+
+- Fix upright quotes in code examples
+- Fix path bug with Python scripts in OS X
+- Fix bug with library lookup in Python scripts,
+ revert some settings unnecessarily made for TeXLive distribution
+- Add German version of example document
+- Add predefined commands:
+ `\wholeNote`, `\wholeNoteDotted`
+ Accordion notation (available Emmentaler glyphs)
+- Rename `\fancyExample` to `\lilyFancyExample` to avoid confusion
+- lilyglyphs is now available through CTAN and TeXLive
+
+0.2.1
+-----
+(2013-09-15)
+
+- lilyglyphs now also works with LuaLaTeX!
+ (Thanks to Dave Bellows)
+- considerable revision of the manual
+- Provide 'private' directory to add personal commands
+- pdf files for image based commands are now tracked in the Git repository
+- some modifications to the use of the Python scripts
+- Drop support/necessity for starred commands
+ All commands by default now don't print a space after them.
+ To achieve that effect one has to write a pair of curly braces.
+ This is in line with default behaviour of e.g \LaTeX{} and similar commands
+- The command generation scripts accept scale= and raise= entries
+ that set default values for subsequent commands
+- Fix \lilyTimeSignature
+ Now scales correctly and doesn't have a fraction line anymore.
+ 'raise' still doesn't work.
+
+0.2.0
+-----
+(2012-11-10)
+
+- Add some commands with images, mainly single notes.
+- graphical \lilyglyphs command with corresponding .pdf and .png files
+- Python script rebuild-pdfs.py
+ Re-creates pdf files for use in image driven commands that are missing
+ because they are not tracked in Git
+ Python script deploy.py
+ Gathers the relevant files and puts them in an archive
+- Python script genGlyphCommands.py
+ Very easy way to create new commands with arbitrary sources.
+- Python script buildglyphimages.py
+ Very easy way to create new image glyphs and their respective commands
+ at the same time. You can edit the objects in LilyPond, then
+ let the script do the rest: write LilyPond source files, compile the image files,
+ create LaTeX commands, a documentation table and test code for fine-tuning the commands.
+- New generic commands \lilyPrintImage and \lilyImage
+ (loading 'glyphs' from PDF images created with LilyPond)
+
+0.1.0
+-----
+(2012-10-19)
+
+- Add dotted symbols and the logic behind it
+- Add some rest glyphs
+- Add fermata
+- Add all 'sharp' accidentals
+
+0.0.5
+-----
+(2012-09-25)
+
+- Exchange meaning of starred and unstarred command versions:
+ Unstarred now means: with trailing space (continuous text),
+ starred means: without trailing space
+- Implement numerical time signatures
+ (scaling and vertical placement don't work properly yet)
+- Plus: Major rewrite of the manual
+
+0.0.2
+-----
+(2012-09-23)
+
+- New syntax accepting key=value options for generic and predefined commands.
+- Options can be set at global, design time and command invocation level.
+- Optical sizes of the Emmentaler font can be selected
+
+0.0.1
+-----
+(2012-09-06)
+
+- All glyphs from Emmentaler can be printed using generic access commands
+- Some predefined commands are already available.
diff --git a/macros/luatex/latex/lilyglyphs/INSTALL b/macros/luatex/latex/lilyglyphs/INSTALL
new file mode 100644
index 0000000000..fcc757b722
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/INSTALL
@@ -0,0 +1,44 @@
+INSTALL for 'lilyglyphs'
+
+'lilyglyphs' is a package to make musical symbols and
+notational elements of the LilyPond engraving software
+(http://www.lilypond.org) available to LaTeX documents.
+
+There are several ways to obtain the package, with different
+installation procedures.
+
+If you have obtained the package through a TeX distribution
+you should be able to use the package without further action.
+For advanced options and usage please refer to the manual.
+
+If you have downloaded lilyglyphs.zip from CTAN please extract the
+archive to a location in your TEXMFHOME tree,
+e.g. ~/texmf/tex/latex/lilyglyphs on Linux.
+
+If you want to use the Github repository you should clone it
+(or your fork) to a directory in your local texmf tree, e.g.
+~/texmf/tex/latex/lilyglyphs on Linux.
+It is advisable to first create a fork and additionally add
+the official repository as an 'upstream' remote.
+
+With both options you should make sure the package directory is
+actually called 'lilyglyphs'.
+
+With both downloaded options you have to make the enclosed 'Emmentaler'
+OpenType font visible to LaTeX.
+For this you can copy the fonts/ directory to your TEXMFHOME/fonts/opentype
+directory and rename it to lilyglyphs or emmentaler. Even better, create a
+link there to the original folder in the package. This way you won't be
+affected by updates of the font files in the package.
+It is important to note that you should not have the Emmentaler fonts
+installed as system fonts in parallel because this might irritate
+XeLaTeX.
+
+Please note that the Github repository doesn't contain a precompiled
+manual. If you want to compile the manual with LuaLaTeX or XeLaTeX
+
+you need the (free) fonts 'Linux Libertine O', 'Linux Biolinum O' and
+'DejaVu Sans Mono'. If you don't want or can't install them you can modify
+'documentation/lilyglyphsManualFonts.sty' to use different fonts
+or remove the reference to it from 'documentation/lilyglyphs.tex'
+to use default fonts.
diff --git a/macros/luatex/latex/lilyglyphs/README b/macros/luatex/latex/lilyglyphs/README
new file mode 100644
index 0000000000..ce1bc35768
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/README
@@ -0,0 +1,44 @@
+README for 'lilyglyphs'
+
+'lilyglyphs' is a package to make musical symbols and
+notational elements of the LilyPond engraving software
+(http://www.lilypond.org) available to LaTeX documents.
+
+(C) Urs Liska and others 2012-2013
+
+Symbols can be inserted like characters in the continuous text,
+either through a growing number of predefined commands or through
+generic access commands that can insert and print virtually anything
+that can be achieved with LilyPond.
+Different from any other solution I have found so far 'lilyglyphs'
+items scale perfectly with any text font size and provide
+detailed control over their placement and scaling.
+
+'lilyglyphs' uses 'fontspec' to access LilyPond's 'Emmentaler'
+OpenType fonts, so it can only be used with LuaLaTeX and XeLaTeX,
+which are both supported.
+The manual uses the (free) fonts 'Linux Libertine O', 'Linux
+Biolinum O' and 'DejaVu Sans Mono', so in order to compile the manual
+you need these fonts installed or have to manually modify/replace
+the file 'documentation/lilyglyphsManualFonts.sty'.
+
+Symbols that aren't covered by the 'Emmentaler' fonts are provided
+with the help of small pdf image files that have been generated with
+LilyPond itself. If you want to extend the package with your own
+commands based on images you have to use LilyPond, i.e. you need a
+working installation. This isn't necessary to _use_ 'lilyglyphs', however.
+The package contains helper scripts that streamline the creation
+of new commands. If you want to make use of them you will also
+need a working installation of Python 2. Of course this too isn't
+a requirement for using the package.
+
+'lilyglyphs' is distributed under the LaTeX Project Public License
+Version 1.3c (license/COPYING.LPPL),
+the included Emmentaler OpenType fonts are distributed under the
+SIL Open Font License, Version 1.1 (otf/LICENSE.OFL)
+
+The project homepage is http://www.openlilylib.org/lilyglyphs
+The development platform is at https://github.com/openlilylib/lilyglyphs
+There you can report and discuss bugs, problems, suggestions etc.
+You may also check out the openlilylib-user mailing list at
+https://lists.sourceforge.net/lists/listinfo/openlilylib-user
diff --git a/macros/luatex/latex/lilyglyphs/VERSION b/macros/luatex/latex/lilyglyphs/VERSION
new file mode 100644
index 0000000000..c202238f1b
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/VERSION
@@ -0,0 +1,2 @@
+This is lilyglyphs 0.2.3
+Generated on 2014-03-12
diff --git a/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-400.png b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-400.png
new file mode 100644
index 0000000000..6c0228629d
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-400.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-600.png b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-600.png
new file mode 100644
index 0000000000..d524ca3b0f
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-600.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-de.pdf b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-de.pdf
new file mode 100644
index 0000000000..a50d91876f
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-de.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-de.tex b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-de.tex
new file mode 100644
index 0000000000..07f63a33bf
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example-de.tex
@@ -0,0 +1,91 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\documentclass[oneside,11pt]{article}
+\usepackage{lilyglyphsStyle}
+\usepackage{lilyglyphsManualFonts}
+
+\usepackage{polyglossia}
+\setmainlanguage{german}
+
+\pagestyle{empty}
+
+
+% make the glyphs lighter
+\lilyOpticalSize{26}
+
+\begin{document}
+\begin{center}
+{ \Huge \lilyglyphs }
+
+\bigskip
+{ \Large Urs Liska }
+
+\emph{September 2013}
+
+\end{center}
+
+\bigskip
+
+Sie schreiben Texte über Musik, vielleicht als Musikwissenschaftler, Lehrer oder Komponist?
+Sie bereiten solche Dokumente zum Druck vor und haben schon immer die Möglichkeit vermisst, Dinge wie das Folgende zu setzen?
+
+\begin{quote}
+„In T.\,24 gilt das \decrescHairpin{} von der 2.\,\halfNote{} bis zum \lilyDynamics{sf} auf dem 11.\,\semiquaverDown[raise=-.5].“
+\end{quote}
+
+Das neue Paket \lilyglyphs{}%
+\footnote{\url{http://www.openlilylib.org/lilyglyphs} -- \href{mailto:info@openlilylib.org}{info@openlilylib.org}}
+erlaubt es auf komfortable Weise, Notationselemente aus LilyPond%
+\footnote{\url{http://www.lilypond.org}}
+in Textdokumenten zu verwenden.
+Vorzeichen wie \flat{} oder \sharp, aber auch Zeichen wie \hspace{.5ex}\fermata{} und Taktangaben wie \lilyTimeCHalf{} oder \lilyTimeSignature{5\,+\,7}{8} sind unmittelbar zugänglich.
+Aber Sie können auch beliebige Notationskonstrukte wie \lilyFancyExample{} dieses sinnfreie Beispiel in den Fließtext einfügen oder gar eingescannte Bilddateien als „Zeichen“ verfügbar machen.
+Dieses Paket kann Ihre typographischen Optionen für das Schreiben oder Setzen von kritischen Berichten, analytischen Texten oder Unterrichtsmaterial erheblich erweitern.
+
+Ein Aspekt, der \lilyglyphs{} von allen mir bekannten Lösungen unterscheidet, ist, dass es nicht auf einen Satz vorgefertigter Symbole beschränkt ist, sondern \emph{jegliche} Notation setzen kann, die mit LilyPond realisierbar ist.
+
+\footnotesize
+Die andere Besonderheit ist die \halfNoteRest{} automatische Größenanpassung an die umgebende Schriftgröße,
+\large was es leicht macht, die \halfNoteRest{} Zeichen im Fließtext zu verwenden.
+\normalsize
+Sie passen sich grundsätzlich von selbst an, können aber auch \clefF[scale=.4] manuell skaliert werden, einzeln oder pauschal \clefG[scale=1.3,raise=-2.9].
+
+\medskip
+Zu schön um wahr zu sein?
+Zugegeben, die Sache hat einen Haken: \lilyglyphs{} ist ein \LaTeX{}%
+\footnote{\url{http://www.latex-project.org}}-Paket und erfordert daher möglicherweise ein Umdenken.
+Sollten die obigen Beispiele aber Ihr Interesse geweckt haben oder Ihren professionellen Bedürfnissen entgegenkommen, dann machen Sie doch einfach einmal einen Versuch -- es ist ohnehin alles Freie Software.
+(Vielleicht ist auch mein Aufsatz über textbasiertes Arbeiten eine hilfreiche Lektüre%
+\footnote{\url{http://lilypondblog.org/2013/07/plain-text-files-in-music/}}).
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example.pdf b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example.pdf
new file mode 100644
index 0000000000..6a36397d37
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example.png b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example.png
new file mode 100644
index 0000000000..bf668e9a8d
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example.tex b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example.tex
new file mode 100644
index 0000000000..4761593809
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs-example.tex
@@ -0,0 +1,89 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\documentclass[oneside,11pt]{article}
+\usepackage{lilyglyphsStyle}
+\usepackage{lilyglyphsManualFonts}
+
+\pagestyle{empty}
+
+\newcommand{\superscript}[1]{{\addfontfeatures{VerticalPosition=Superior}#1}}
+\linespread{1.1}
+
+% make the glyphs lighter
+\lilyOpticalSize{26}
+
+\begin{document}
+\begin{center}
+{ \Huge \lilyglyphs }
+
+\bigskip
+{ \Large Urs Liska }
+
+\emph{September 2013}
+
+\end{center}
+
+\bigskip
+
+You are authoring text documents about music, maybe you're a musicologist, teacher, or composer?
+You are preparing such documents for publication and have always missed the ability to print sentences like this one?
+
+\begin{quote}
+In m.\,24 the \decrescHairpin{} lasts from the 2\superscript{nd} \halfNote{} to the \lilyDynamics{sf} on the 11\superscript{th} \semiquaverDown[raise=-.5].
+\end{quote}
+
+With the new package \lilyglyphs{} you can easily insert the notational elements of the LilyPond%
+\footnote{\url{http://www.lilypond.org}}
+engraving software in your text documents.
+Accidentals like \flat{} or \sharp, but also articulation scripts (\hspace{.65ex}\fermata{}) and time signatures such as \lilyTimeCHalf{} or \lilyTimeSignature{5\,+\,7}{8} are readily available.
+But you can also insert arbitrary notational constructs like this mockup example \lilyFancyExample{} into your text or even make scanned images available as “charactersâ€.
+This package may greatly extend your typographical options when authoring or typesetting critical reports, analytical texts or teaching/exam material.
+
+One thing that sets \lilyglyphs{} apart from other solutions I had investigated is that one isn't restricted to a set of predefined symbols but is able to print \emph{any notation} that can be realized with LilyPond.
+
+\footnotesize
+The other nice thing is that the glyphs \halfNoteRest{} scale well with the surrounding font size,
+\large making it easy \halfNoteRest{} to incorporate them into continuous text.
+\normalsize By default the glyphs scale automatically but they can also be scaled \clefF[scale=.4] manually, either individually or document-wise \clefG[scale=1.5,raise=-3.1].
+
+\medskip
+Sounds too good to be true? Well, there’s one catch to it: \lilyglyphs{} is a \LaTeX{}%
+\footnote{\url{http://www.latex-project.org}}
+package, so you may have to consider a change in mind-set.
+But if the above examples whet your appetite and match your professional needs you should really consider giving it a serious try -- it's all Free Software anyway.
+You may find reading my essay on the advantages of plain text toolchains helpful too%
+\footnote{\url{http://lilypondblog.org/2013/07/plain-text-files-in-music/}}.
+
+For more information you may visit \lilyglyphs' project homepage \url{http://openlilylib.org/lilyglyphs} or contact us through \href{mailto:info@openlilylib.org}{info@openlilylib.org}.
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs.pdf b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs.pdf
new file mode 100644
index 0000000000..c73d2be2e3
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs.tex b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs.tex
new file mode 100644
index 0000000000..078aae2a88
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs.tex
@@ -0,0 +1,1429 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\documentclass[oneside]{scrreprt}
+\usepackage{lilyglyphsStyle}
+\usepackage{lilyglyphsManualFonts}
+\usepackage{paralist}
+\begin{document}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Title page
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\title{\lilyglyphs[scale=1.5]\\~\\
+ \normalsize Version 0.2.3}
+\author{Urs Liska}
+
+\maketitle
+
+\pagebreak
+
+\section*{Quick Start}
+\lilyglyphs{} enables \LaTeX{} to include arbitrary notational elements from the LilyPond%
+\footnote{\url{http://www.lilypond.org}}
+notation software like characters in continuous text.
+As it uses \package{fontspec} to access glyphs from an OpenType font \lilyglyphs{} works with \hologo{XeLaTeX} or \hologo{LuaLaTeX} exclusively.
+
+If you have obtained the package as part of a \TeX{} distribution the following Minimal Working Example should get you going in a minute and show if everything works correctly.
+If you have downloaded the package please refer to \fref{sec:installation} for a few more preliminary installation steps.
+
+\medskip
+
+\begin{lstlisting}[language={[LaTeX]TeX}]
+\documentclass{article} % Should work with any documentclass
+\usepackage{fontspec} % Is necessary to access OpenType fonts
+\usepackage{lilyglyphs} % Currently there are no package options available
+\begin{document}
+\flatflat{} or \clefGInline. % Predefined commands,
+ % Use {} to allow trailing whitespace
+\lilyGlyph[scale=1.2, raise=.5]{timesig.neomensural64}
+ % Access "Emmentaler" glyphs by their name
+ % Generic commands have one mandatory
+ % and one optional (placement) argument.
+\twoBeamedQuavers % Commands that include images instead of font glyphs.
+\end{document}
+\end{lstlisting}
+
+\medskip
+In the text you can use predefined commands like \flatflat{} or \clefGInline.
+Commands without the pair of curly braces swallow any trailing whitespace -- use these before punctuations or to combine symbols.
+For the available predefined commands consult the reference in \fref{chap:list_predefined_commands}.
+
+Glyphs that are part of LilyPond's \emmentaler{} font but not covered by a predefined command yet can be accessed through the generic command \cmd{lilyGlyph\{GLYPHNAME\}}, the glyph names being listed in \url{http://www.lilypond.org/doc/v2.16/Documentation/notation/the-feta-font.html}
+or in the file \dir{the-feta-font-2-16-2.html} located in the the \dir{documentation} directory of the package.
+As an example take this neomensural time signature \lilyGlyph[scale=1.2, raise=.5]{timesig.neomensural64}.
+Other symbols can be included as image files \twoBeamedQuavers[scale=.95], but from the author's perspective this doesn't make a difference.
+
+All commands accept an optional argument containing \texttt{key=value} pairs.
+Currently two keys are supported:
+\texttt{scale} multiplies the size of the glyph by the given factor while \texttt{raise} shifts it vertically by the given amount interpreted as \emph{ex}.
+Glyphs accessed individually generally need these options, see the neomensural time signature in the example.
+
+Apart from the Emmentaler glyphs \lilyglyphs{} can include any notational construct that LilyPond can produce.
+Please refer to \fref{sec:generic_access_commands} to learn about the \emph{generic access commands} and to \fref{sec:generating_commands_image} for detailed instructions how to create custom commands.
+
+\lilyglyphs{} elements \tiny automatically \halfNoteRest{} \normalsize or manually \huge \halfNoteRest{} \normalsize scale with the \halfNoteRest{} text size commands.
+
+\tableofcontents
+\vfill
+
+\pagebreak
+
+\vfill
+%\input{copyright-notice.inp}
+
+\chapter{Introduction}
+\label{chap:introduction}
+
+\lilyglyphs{} came into existence when I looked for a way to include arbitrary notational elements in the continuous text of \LaTeX{} documents.
+Unfortunately all packages I could find were quite restricted in the number of available symbols and/or their flexibility in scaling with the text size.
+Moreover no solution came near the beauty of the engraving of LilyPond%
+\footnote{\url{http://www.lilypond.org}}.
+Therefore I decided to “roll my own†package and make the notation font and notational elements of LilyPond available to \LaTeX{} documents.
+
+LilyPond is a promising competitor in producing the most beautiful musical engraving on the market, and one of the foundations of this beauty is its \emmentaler{} font.
+\lilyglyphs{} accesses the Emmentaler font through the \package{fontspec} package and inserts its glyphs in the continuous text applying sophisticated control over scaling and spacing.
+Therefore it relies on a \LaTeX{} engine supporting \package{fontspec}.
+It was written using \hologo{XeLaTeX}, but thanks to the contribution of Dave Bellows%
+\footnote{\url{http://www.davebellows.com}}
+it now also works with \hologo{LuaLaTeX}%
+\footnote{Principally it is possible to extend the functionality so it would also work with plain \LaTeX{} by accessing non-OpenType variants of the font, but as the package maintainer has neither experience nor active interest in this area this will only be implemented if there are volunteers who join us.}.
+
+The Emmentaler font only provides a subset of LilyPond's notational capabilities, as LilyPond draws many symbols itself.
+After some experiments with drawing such elements in \LaTeX{} it became clear that this approach isn't really maintainable -- and especially wouldn't provide a sufficient output quality.
+Therefore this kind of elements is included through small \textsc{pdf} image files that have explicitely been created with LilyPond.
+
+Great care has been taken to make the notational elements scale well with the surrounding text font size.
+Each single element can be scaled and vertically shifted, but the settings can also be done per document to accomodate for unusual body fonts that might not match too well with \lilyglyphs.
+
+\medskip
+The coverage of glyphs is far from being comprehensive, but the package is already very usable for real-world documents.
+Any Emmentaler glyph that isn't covered yet by a predefined command can be accessed by its name.
+Other -- image based -- commands (for example arbitrarily complex musical expressions) can be added through a process that has been made as simple as possible (although it involves using external software such as LilyPond and possibly Python).
+Details about extending \lilyglyphs{} with additional commands can be found in \fref{chap:python_scripts}.
+
+
+As the number of possible commands seems endless we would be extremely happy about any contribution of new material.
+But there are also technical details with regard to \LaTeX{} programming where additional competence would be highly welcome.
+You may have a look at the issue tracker%
+\footnote{\url{https://github.com/openlilylib/lilyglyphs/issues}}
+to get an idea where you could help.
+
+\bigskip
+
+Originally \lilyglyphs{} was a project on its own but by now it is part of a rather large family of projects around engraving musical scores with LilyPond and typesetting texts with \LaTeX: openLilyLib%
+\footnote{\url{http://www.openlilylib.org}}.
+If you have come here mainly as a \LaTeX{} document author you should also have a look at the \package{musicexamples} package%
+\footnote{\url{http://www.openlilylib.org/musicexamples}}.
+If you are also interested in LilyPond itself you might find the tutorials section, \package{lilylib} and \package{lilypond-doc} interesting too.
+A few more projects are still in the planning phase, and you can always see the current state of affairs at our Github starting page%
+\footnote{\url{https://github.com/openlilylib}}.
+\lilyglyphs{} is developed in the \dir{lilyglyphs} directory of this project site, there you can inspect the source, clone or fork the repository, and submit issue reports.
+If you are interested in participating in the development of \lilyglyphs, don't hesitate to contact us directly\footnote{\url{mailto:ul@openlilylib.org}}.
+
+\section{Installation}
+\label{sec:installation}
+
+\paragraph{Installation Options}
+There are several ways to get \lilyglyphs{} up and running: As part of a \TeX{} distribution, as a download from CTAN%
+\footnote{http://www.ctan.org/pkg/lilyglyphs}
+or through its development repository on GitHub%
+\footnote{\url{https://github.com/openlilylib/lilyglyphs}},
+which is the recommended way if you're familiar with Git.
+If it's contained in your distribution you should be able to simply \emph{use} the package and start typing, e.\,g. with the example given in the “Quick Start†at the beginning of this manual.
+Otherwise there are a few steps of manual installation.
+
+\lilyglyphs{} is known to need fairly recent versions of \package{fontspec} and \hologo{LuaLaTeX}.
+So if you haven't got \lilyglyphs{} through your \LaTeX{} distribution you may have to take care that you use a sufficiently current distribution.
+
+\textbf{\textsf{Note:}} If you have installed the package through a distribution you can still use one of the following installation methods because both will actually \emph{hide} the distribution installation.
+One advantage of this approach is that you can access this manual conveniently using \texttt{texdoc lilylgyphs}.
+But if you want to use the included Python scripts you should be careful to run the correct versions of them.
+
+\paragraph{CTAN Download}
+If you've downloaded the package from CTAN you should extract the archive to a location in the \dir{tex/latex/} directory of your \textsc{texmfhome} (e.\.g. \dir{\textasciitilde/texmf/} on Linux or \dir{\textasciitilde/Library/texmf/} on Mac OS X).
+
+\paragraph{GitHub Download}
+If you're familiar with Git the recommended way to use \lilyglyphs{} is to create a fork of the GitHub repository (assuming you already have a Github account).
+Inside the same \dir{tex/latex/} dir run \texttt{git clone git@github.com:YOURUSERNAME/lilyglyphs.git} -- please don't provide an alternative destination name because the package should actually reside in a directory called \dir{lilyglyphs/}.
+Then \texttt{cd} into that directory and add the original repository with \texttt{git remote add upstream git@github.com:openlilylib/lilyglyphs.git}.
+From now on you will refer to your fork as \texttt{origin} and to the official repository as \texttt{upstream}.
+
+The most immediate advantage of using \lilyglyphs{} through the Git repository is that it is the easiest way to keep the package up to date.
+Each time someone adds new commands to the package they will be instantly available through the repository while regular releases will happen much less frequently.
+And if updates should somehow break syntax in existing documents you can easily (and temporarily) check out the earlier version of the package you had used when originally writing your documents.
+Another advantage of the repository version is that you have “direct access†to extending the package with predefined commands in a way that makes it easy for us to incorporate your contribution in the official package.
+
+\paragraph{Font Considerations}
+If you install \lilyglyphs{} manually you will have to make the included \emmentaler{} OpenType font available for \LaTeX.
+Copy the complete \dir{fonts/} folder from the package directory to \dir{TEXMFHOME/fonts/opentype} (creating these subdirectories if they aren't already present on your system) and rename it to a more explicit name such as ‘emmentaler’ or ‘lilyglyphs’.
+An even better way would be not to copy the files but rather create a symlink to it with \texttt{cd TEXMFHOME/fonts/opentype} and \texttt{ln -s /path/to/lilyglyphs/fonts emmentaler} \todo{check on Windows}.
+That way no manual adjustments have to be made when \lilyglyphs{} is updated and might bring new versions of the font files with it.\\
+\textbf{\textsf{Note:}} the package probably won't work with \hologo{XeLaTeX} if you also have installed \emmentaler{} as a system font.\\
+\textbf{\textsf{Note:}} If you create a link instead of a copy you have to make sure that there is at least one regular file or subdirectory in the directory beside the link.
+Otherwise \hologo{LuaLaTeX} won't find the font, which is a limitation in the \texttt{kpathsea} library.
+The easiest way is to simply add an empty \dir{dummy/} subdir.
+
+\medskip
+If you experience any issues with this or other topics during installation please give us feedback so we can improve documentation .
+
+\section{License}
+\label{sec:license}
+
+\lilyglyphs{} is distributed under the \LaTeX{} Project Public License version 1.3 or (at your option) any later version of this license.
+You may find the latest version of this license at \url{http://www.latex-project.org/lppl.txt}, and version 1.3 or later is part of all distributions of LaTeX version 2005/12/01 or later.
+A full copy of the license is enclosed in the file \dir{/license/COPYING.LPPL} of the package.
+The file \dir{/license/MANIFEST} contains a list of all files affected by this licensing.
+
+The package is currently maintained by its original author Urs Liska, but its \textsc{lppl} status is simply ‘maintained’.
+
+\medskip
+\lilyglyphs{} contains the \emmentaler{} OpenType font developed provided by the LilyPond project (\url{http://www.lilypond.org}).
+It is redistributed unmodified under the SIL Open Font License, Version 1.1.
+For details see \dir{/otf/LICENSE.OFL} and \dir{/otf/FONTLOG}.
+
+\chapter{Usage}
+\label{chap:usage}
+
+As mentioned in the Quick Start at the beginning of this document you have to activate \lilyglyphs{} with \cmd{usepackage\{fontspec\}} \cmd{usepackage\{lilyglyphs\}}.
+This will give you access to the predefined commands and some generic access commands.
+
+\section{Usage of Predefined Commands}
+\label{sec:usage_predefined_commands}
+A number of predefined commands is available for immediate use.
+To use them you just have to enter the command to print the corresponding musical element, e.\,g. \cmd{lilyTimeC} for a \lilyTimeC.
+A complete reference of these commands is available in \fref{chap:list_predefined_commands}, along with any specific comments that might be necessary.
+
+As you will see later there are some commands that take arguments and many that don't.
+Commands without mandatory arguments behave like e.\,g. the well-known \cmd{LaTeX} command in that they swallow any whitespace entered after them.
+So in order to allow a space to be printed afterwards you have to supply a pair of curly braces, like \cmd{flat\{\} and more} to print “\,\flat{}\ and moreâ€.
+Commands with arguments don't need this special treatment, so you can simply write a space character after them or not like \cmd{lilyDynamics\{mf\} or \textbackslash lilyDynamics\{pp\}.} to achieve \lilyDynamics{mf} or \lilyDynamics{pp}.
+
+\section{Generic Access Commands}
+\label{sec:generic_access_commands}
+
+There is a wealth of conceivable musical symbols and only a limited number of predefined commands.
+Even when this package will become more and more comprehensive there will always be cases that haven't been covered yet.
+For these cases \lilyglyphs{} provides four generic access commands:
+\begin{itemize*}
+\item \cmd{lilyGlyph}
+\item \cmd{lilyGlyphByNumber}
+\item \cmd{lilyText}
+\item \cmd{lilyImage}.
+\end{itemize*}
+
+They all accept one mandatory and one optional argument, the mandatory one being the content to be printed.
+This content has to be given in a form specific to the respective command.
+
+\paragraph*{\cmd{lilyGlyph}} expects the OpenType glyph name.
+You can look up the glyph names in the Appendix of LilyPond's \emph{Notation Reference}\footnote{\url{http://www.lilypond.org/doc/v2.16/Documentation/notation/the-feta-font}} or in the somewhat reduced html page provided in the \dir{/documentation} directory of the package download.\\
+Please note that many Emmentaler glyphs, especially articulations, are aligned to their center because that's what they are used like in a score.
+So don't be surprise if you need considerable extra space before such glyphs.
+This isn't a bug but rather a characteristic of using the glyphs in a different context than they were designed for.
+
+\paragraph*{\cmd{lilyGlyphByNumber}} expects the Unicode code number of the glyph.
+You will generally not want to use this as the code positions aren't guaranteed to stay the same with new versions of the fonts.
+There may be some uses for numerical access however, e.\,g. if you want to iterate over a range of glyphs.
+
+\paragraph*{\cmd{lilyText}} expects ordinary text as its argument.
+In fact it just switches the font to Emmentaler and then writes the string given as the argument.
+This only works for Dynamics letters, numbers and the glyphs \lilyText[scale=2]{+ - , .} -- as these glyphs are located at their ordinary \textsc{ascii} character position in the font.
+But you can also enter any spacing commands (like \cmd{hspace} or plain spaces) to control the spacing between glyphs.
+But keep in mind that this may result in line breaking inside your expression.
+If you need to prevent this you can surround your expression by an \cmd{mbox}.\\
+(There is a special command provided -- \cmd{lilyDynamics} -- which is essentially a wrapper around \cmd{lilyText} and presets the character size to a suitable default.)
+
+\paragraph*{\cmd{lilyImage}} expects the basename of an image file your \TeX{} system can process.
+It then includes this file using the same optional argument mechanism as the other commands.
+What sets this command apart from simply including an image is that it automatically scales the image relative to the current text font size, with being printed at its original size at \cmd{normalsize}.
+You have to take care yourself that \LaTeX{} finds and can handle the image file.
+While this command has originally been created to print images generated by LilyPond you can actually print \emph{any} image, e.\,g. scanned images from autographs, taking advantage of \lilyglyphs' infrastructure, for example the optional arguments described in the following section.
+
+\section{The Optional Argument: Layout Adjustment}
+\label{sec:optional_argument}
+The generic access commands as well as the predefined commands allow an optional argument to be passed.
+This can contain a list of comma-separated options in \texttt{<key=value>} form that influence the appearance of the glyphs. Currently there are the \texttt{scale} and \texttt{raise} options.
+
+\paragraph*{\texttt{scale}}
+changes the size of the glyph.
+As the Emmentaler glyphs are designed for a totally different purpose they often don't fit very well in the context of continuous text.
+\texttt{scale} is given as a factor by which the default size is multiplied.
+With Emmentaler glyphs this has to be a positive number, otherwise you will get an error.
+But glyphs printed by \cmd{lilyImage} (or predefined commands based on it) can also be scaled negatively.
+This results in an image that is rotated around the center of the bottom line of the original.
+You will therefore have to add an appropriate \texttt{raise} value (try e.\,g. 2 as a starting point).
+You will have to take some care about the horizontal spacing, as such a flipped image seems to use it with inverted direction.
+But you can safely put extra horizontal space after the image, and it is a valid and practical way to create two symbols from one image file.
+
+\paragraph*{\texttt{raise}}
+changes the vertical placement of the glyph.
+The majority of glyphs is placed too low by default, so they need a positive \texttt{raise} value.
+\texttt{raise} is given as a decimal value without units, which is interpreted as \emph{ex}, or x-height.
+As there is no \emph{x} in a musical font, this is somewhat arbitrary, but it is a natural unit to scale with the surrounding font size.
+Usually you may start trying \texttt{raise} values between 0 and 0.5.
+
+\bigskip
+These layout adjustments can be made at three different stages: at design time (of predefined commands), globally (per document), and at command invocation.
+
+\paragraph*{At design time}
+a designer of a predefined command has already selected the optimal default values so the command will work out-of-the-box in most cases.
+
+\paragraph*{Globally}
+the layout adjustments default to values that leave the glyphs unaltered (i.\,e. \texttt{scale=1} and \texttt{raise=0}).
+A document author can override these defaults at any time with \cmd{lilyGlobalOptions\{<options>\}}.
+This may for example be necessary if you use a text font which doesn't harmonize well with \lilyglyphs' default settings, for example because of its unusual x-height.
+You can use this command at the beginning of the document to modify the appearance for the whole document, or you can change its settings multiple times throughout the document.
+This is what you generally have to do when using \cmd{lilyGlyph} for printing individual glyphs from Emmentaler.
+
+\paragraph*{At command invocation}
+you can pass the layout adjustment options for the specific instance of the glyph.
+
+\bigskip
+The values that finally affect the layout of any given glyphs take all three stages into account.
+By passing an option at command invocation you don't set absolute values, but modify the values already present.
+The effective \texttt{scale} value is \mbox{\texttt{designtime * global * invocation}}, the effective \texttt{raise} is \mbox{\texttt{designtime + global + invocation}}.
+So passing a \texttt{scale=1.1} will always slightly increase the glyph's size, no matter what settings are already in effect.
+
+\textit{Technically speaking \lilyglyphs{} applies a fourth layer of scaling with image files.
+It calculates a last scaling factor by multiplying the result of the above considerations with the ratio of the current font size versus the size of the \cmd{normalsize} font.}
+
+
+\section{Example: Define a Custom Command}
+\label{sec:example}
+Now it's time for an example that actually uses the generic access commands to print symbols provided by the Emmentaler font.
+It will walk you through the process up to defining a ‘local’ predefined command.
+
+We want to print the \emph{fermata} sign which isn't implemented yet as a predefined command.
+In the documentation we have looked up the name of the glyph: \texttt{scripts.ufermata}, so you can print it with \cmd{lilyGlyph\{scripts.ufermata\}}: \lilyGlyph{scripts.ufermata}.
+While this gives us the right glyph its appearance isn't really what we're after yet and we want to adjust its size and placement.
+This is done with the optional argument described in the previous subsection.
+
+First we increase the size of the glyph with the \texttt{scale} argument. We find that a scaling factor of 1.4 seems suitable:
+\cmd{lilyGlyph[scale=1.4]\{scripts.ufermata\}} -- \lilyGlyph[scale=1.4]{scripts.ufermata}
+
+As you can see the glyph is -- as most Emmentaler glyphs are -- placed too low, so you have to add the \texttt{raise} argument. A value of 0.3 seems fine -- remember, the raise argument is interpreted as \emph{ex}, but you don't write down the unit.\\
+ \cmd{lilyGlyph[scale=1.4,raise=0.3]\{scripts.ufermta\}} -- \lilyGlyph[scale=1.4,raise=0.6]{scripts.ufermata}
+
+You can now further see that the glyph is placed too far to the left -- which is a good example of the behaviour described earlier with the \cmd{lilyGlyph} command.
+In fact it seems the point in the middle of the fermata is placed where we would expect the glyph to start.
+So you have to add some leading space, which might be practical to be entered in \emph{ex}:\\
+\cmd{hspace\{1ex\}}\cmd{lilyGlyph[scale=1.4,raise=0.3]\{scripts.ufermta\}} -- \hspace{1ex}\lilyGlyph[scale=1.4,raise=0.3]{scripts.ufermata}
+
+\medskip
+If you want you can now simply enclose this definition in a \cmd{newcommand} to be able to reuse it.
+\cmd{newcommand\{\textbackslash fermata\}\{hspace\{1ex\}}\cmd{lilyGlyph[scale=1.4,raise=0.3]\{scripts.ufermta\}}.
+After this you can enter your tweaked symbol by simply writing \cmd{fermata}.
+However you are encouraged to create such a command the way we define predefined commands in \lilyglyphs{} itself.
+This way it will gain the flexibility of the predefined commands, and it will be easier to be incorporated in the package itself.
+See our instructions on how to create predefined commands the \lilyglyphs{} way in \fref{sec:howto_predefined_commands}.
+If you manage to write a command that you find useful for others also please submit it to us -- or even better: if you figured out how to create commands in general, please join us.
+As mentioned earlier the number of possible commands is huge, and the value of the package will increase with each step towards a comprehensive coverage.
+
+\section{Dotted symbols}
+\label{sec:dotted_symbols}
+There are commands that are accompanied by \cmd{...Dotted} versions.
+While they can be used like any other commands there are some caveats because they are technically different from normal commands, actually appending a dot to normal commands.
+
+If you use significant scaling factors for the commands you have to check carefully whether the gap and the position of the dot scale and move well.
+Unfortunately one can't influence the parameters of the dot independently.
+We have worked hard to enable the designer of a command to create rules how to scale the gap, but you still may run into problems here.
+In such a case you will have to either change the predefined command in the library or just create the dotted symbol from scratch.
+
+Immediately after having used a dotted symbol you can arbitrarily add more dots with the \cmd{lilyPrintMoreDots} command.
+This command uses the existing dot settings (scale and raise) and prints another dot.
+By default it has a gap of 0.25\,ex, but you can override this by passing a number as an optional argument, which is interpreted as \emph{ex}.
+
+For example if you take the command \cmd{halfNoteRestDotted}, which prints a dotted half note rest: \halfNoteRestDotted{} you can easily add more dots through \cmd{halfNoteRestDotted\textbackslash lilyPrintMoreDots}: \halfNoteRestDotted\lilyPrintMoreDots.
+
+Please note that you should only call \cmd{lilyPrintMoreDots} immediately after calling a \cmd{...Dotted} command. Otherwise you may get surprising results or even errors because the underlying key-value variables are inititialized wrongly or not at all.
+
+\section{Optical size}
+\label{sec:optical_size}
+The \emmentaler{} fonts come in a set of eight “optical sizesâ€.
+These are variations of the font originally designed to be used at different point sizes.
+Generally you can assume that fonts for larger sizes offer more detail and give a somewhat lighter appearance, while fonts for smaller point sizes give more weight on the paper but less detail to be readable at small sizes.
+
+\lilyglyphs{} gives you the option to access the available font versions, but it may make more sense to appreciate them as “weights†-- although this is technically speaking or even conceptionally incorrect.
+The eight optical sizes of the Emmentaler font are: 11, 13, 14, 16, 18, 20, 23, 26.
+If you conceive these as weights you would somehow order them from black (11) to light (26).
+You can switch the used optical size at any time in a document using the command \cmd{lilyOpticalSize}, giving the number as an option.
+You could for example use this feature to adapt the LilyPond glyphs to a darker or lighter default text font.
+Be sure to supply a number corresponding to a font actually available on your system.
+Maybe this will someday also be available as an option to select for a single glyph, but for now you have to switch twice: before and after the glyph.
+
+The optical size used by \lilyglyphs{} defaults to 16.
+
+\paragraph*{Known issues and warnings:}
+Optical sizes don't work with glyphs printed as images.
+If you \emph{have} to use these glyphs in different weights, you will have to take care for it yourself.
+The general plan would be to create different versions of the glyph by creating different glyphs in LilyPond (presumably by using different staff sizes).
+
+\chapter{Reference of Predefined Commands}
+\label{chap:list_predefined_commands}
+The following sections document the predefined commands that already have been implemented.
+They generally contain explanations on the specific use of the commands (if necessary) and a table listing the implemented commands.
+Remember that any glyph of the Emmentaler font which is not covered by a predefined command yet can be accessed by its name through the \cmd{lilyGlyph} command.
+A full list of available glyphs is available in the documentation folder of the \lilyglyphs{} package or in LilyPond's original documentation at \url{http://www.lilypond.org/doc/v2.16/Documentation/notation/the-feta-font.html}.
+
+The documentation explicitely mentions if the commands are based on image files.
+
+\section{Single Notes}
+\label{sec:singlenotes}
+Single notes may well be the most frequently used glyphs.
+Unfortunately they aren't present in \emmentaler{} because LilyPond draws them by itself, so \lilyglyphs{} realizes them using included pdf image files.
+The commands are available identically in British and American form.
+See \fref{tab:singlenotes} for the available predefined commands.
+
+\begin{reftable}{Single Notes}{singlenotes}
+\wholeNote & \cmd{semibreve} -- \cmd{wholeNote}\\
+\wholeNoteDotted & \cmd{semibreveDotted} -- \cmd{wholeNoteDotted}\\
+\halfNote & \cmd{minim} -- \cmd{halfNote}\\
+\halfNoteDown & \cmd{minimDown} -- \cmd{halfNoteDown}\\
+\halfNoteDotted & \cmd{minimDotted} -- \cmd{halfNoteDotted}\\
+\halfNoteDottedDown & \cmd{minimDottedDown} -- \cmd{halfNoteDottedDown}\\
+\halfNoteDottedDouble & \cmd{minimDottedDouble} -- \cmd{halfNoteDottedDouble}\\
+\halfNoteDottedDoubleDown & \cmd{minimDottedDoubleDown} -- \cmd{halfNoteDottedDoubleDown}\\
+\crotchet & \cmd{crotchet} -- \cmd{quarterNote}\\
+\crotchetDown & \cmd{crotchetDown} -- \cmd{quarterNoteDown}\\
+\crotchetDotted & \cmd{crotchetDotted} -- \cmd{quarterNoteDotted}\\
+\crotchetDottedDown & \cmd{crotchetDottedDown} -- \cmd{quarterNoteDottedDown}\\
+\crotchetDottedDouble & \cmd{crotchetDottedDouble} -- \cmd{quarterNoteDottedDouble}\\
+\crotchetDottedDoubleDown & \cmd{crotchetDottedDoubleDown} -- \cmd{quarterNoteDottedDoubleDown}\\
+\quaver & \cmd{quaver} -- \cmd{eighthNote}\\
+\quaverDown & \cmd{quaverDown} -- \cmd{eighthNoteDown}\\
+\quaverDotted & \cmd{quaverDotted} -- \cmd{eighthNoteDotted}\\
+\quaverDottedDown & \cmd{quaverDottedDown} -- \cmd{eighthNoteDottedDown}\\
+\quaverDottedDouble & \cmd{quaverDottedDouble} -- \cmd{eighthNoteDottedDouble}\\
+\quaverDottedDoubleDown & \cmd{quaverDottedDoubleDown} -- \cmd{eighthNoteDottedDoubleDown}\\
+\semiquaver & \cmd{semiquaver} -- \cmd{sixteenthNote}\\
+\semiquaverDown & \cmd{semiquaverDown} -- \cmd{sixteenthNoteDown}\\
+\semiquaverDotted & \cmd{semiquaverDotted} -- \cmd{sixteenthNoteDotted}\\
+\semiquaverDottedDown & \cmd{semiquaverDottedDown} -- \cmd{sixteenthNoteDottedDown}\\
+\semiquaverDottedDouble & \cmd{semiquaverDottedDouble} -- \cmd{sixteenthNoteDottedDouble}\\
+\semiquaverDottedDoubleDown & \cmd{semiquaverDottedDoubleDown} -- \cmd{sixteenthNoteDottedDoubleDown}\\
+\demisemiquaver & \cmd{demisemiquaver} -- \cmd{thirtysecondNote}\\
+\demisemiquaverDown & \cmd{demisemiquaverDown} -- \cmd{thirtysecondNoteDown}\\
+\demisemiquaverDotted & \cmd{demisemiquaverDotted} -- \cmd{thirtysecondNoteDotted}\\
+\demisemiquaverDottedDown & \cmd{demisemiquaverDottedDown} -- \cmd{thirtysecondNoteDottedDown}\\
+\demisemiquaverDottedDouble & \cmd{demisemiquaverDottedDouble} -- \cmd{thirtysecondNoteDottedDouble}\\
+\demisemiquaverDottedDoubleDown & \cmd{demisemiquaverDottedDoubleDown} -- \cmd{thirtysecondNoteDottedDoubleDown}\\
+\end{reftable}
+
+
+\section{Beamed notes}
+\label{sec:beamed_notes}
+
+We will only provide a few complex symbols like beamed notes for default use.
+Of course one could have the wish for indefinite variations like notes with variable beam slope.
+But as long as it isn't possible to make this parametrical%
+\footnote{See \ghIssue{64}}
+it is probably a good idea to stick with a few basic commands.
+For now see \fref{tab:beamedNotes} for the implemented commands.
+
+Beamed notes are implemented using \textsc{pdf} files.
+
+\begin{reftable}{Two Beamed Notes}{beamedNotes}
+\twoBeamedQuavers & \cmd{twoBeamedQuavers}\\
+\end{reftable}
+
+\begin{reftable}{Three Beamed Notes}{threeBeamedNotes}
+\threeBeamedQuavers & \cmd{threeBeamedQuavers} & Three beamed quavers\\
+\threeBeamedQuaversI & \cmd{threeBeamedQuaversI} & Second dotted\\
+\threeBeamedQuaversII & \cmd{threeBeamedQuaversII} & First dotted\\
+\threeBeamedQuaversIII & \cmd{threeBeamedQuaversIII} & Second dotted, first short\\
+\end{reftable}
+
+
+\section{Clefs}
+\label{sec:clefs}
+Some of the clef glyphs are among the few that are too large by default.
+You couldn't use a G clef at default size within continuous text without severely \clefG{} damaging line spacing.
+But if you scale them to a size that doesn't disturb line spacing, they look quite disproportionate, especially when combined with other elements: \mbox{ \clefCInline{} \natural.}
+To ease the handling of that issue we provide the clefs in two forms, at ordinary size which can be problematic in continuous text, and as an -Inline version which looks somewhat funny but can be used within the line.
+
+See \fref{tab:clefs} for the available predefined commands.
+
+\begin{reftable}{Clefs}{clefs}
+\clefGInline & \cmd{clefG}, \cmd{clefGInline} & clefs.G\\
+\clefFInline & \cmd{clefF}, \cmd{clefFInline} & clefs.F\\
+\clefCInline & \cmd{clefC}, \cmd{clefCInline} & clefs.C\\
+\end{reftable}
+
+\section{Time Signatures}
+\label{sec:timesignatures}
+
+The Emmentaler font provides two “real†glyphs for time signatures, the \lilyTimeC{} and the \lilyTimeCHalf.
+
+The numerical (single and compound) time signatures can be printed using \cmd{lilyTimeSignature\{numerator\}\{denominator\}}: \lilyTimeSignature{4}{4}.
+\texttt{numerator} and \texttt{denominator} are treated as \cmd{lilyText}, so you can enter anything this command can use (see \fref{sec:generic_access_commands}).
+This way you can easily write compound time signatures like \cmd{lilyTimeSignature\{4 + 7\}\{8\}}: \lilyTimeSignature{4 + 7}{8}.
+But be aware that the command does \emph{not} have a notion of columns, so you have to take care about the horizontal alignment yourself if there are more than one item in both rows, for example by adding explicit space.
+
+\cmd{lilyTimeSignature} respects any whitespace after the closing bracket so you don't have to supply the pair of curly braces.
+
+\begin{reftable}{Time Signatures}{timesignatures}
+\lilyTimeC & \cmd{lilyTimeC} & timesig.C44\\
+\lilyTimeCHalf & \cmd{lilyTimeCHalf} & timesig.C22\\
+\lilyTimeSignature{7}{8} & \cmd{lilyTimeSignature\{7\}\{8\}}\\
+\lilyTimeSignature{3 + 4}{4 + 8} & \cmd{lilyTimeSignature\{3 + 4\}\{4 + 8\}}\\
+\end{reftable}
+
+\paragraph*{Known issues and warnings:} \cmd{lilyTimeSignature} also expects the optional argument as the other commands, but it doesn't understand the \texttt{raise} option correctly.
+The box with the time signature is vertically centered so it should generally be OK, but if you for some reason have to change its vertical position you should manually surround the whole command by a \cmd{raisebox}.
+
+\section{Numbers}
+\label{sec:numbers}
+Numbers can be entered with the already known \cmd{lilyText} command.
+Access through the glyph names is possible but not necessary.
+Therefore we don't provide predefined commands for them.
+With the default scaling of 1.0 they generally fit as lowercase letters like \lilyText{0 1 2 3 4 5 6 7 8 9} \cmd{lilyText\{0 1 2 3 4 5 6 7 8 9\}}.
+For Uppercase letters you can start trying a scaling of 1.3. A future version of the package may provide convenience commands with default scalings for upper/lowercase letters, fingerings, figured bass numbers, time signature numbers etc.
+
+A special case are four glyphs that are related to numbers: \lilyText[scale=1.5]{+~-~.~,} (plus, hyphen, fullstop and comma).
+These are also accessible through \cmd{lilyText} and their respective characters, the example in the previous sentence being written as \cmd{lilyText[scale=1.5]\{+~-~.~,\}}.
+
+\section{Accidentals}
+\label{sec:accidentals}
+
+The \cmd{natural} \natural, the \cmd{flat} \flat{} and the \cmd{sharp} \sharp{} replace the respective commands from standard \LaTeX.
+Please note that all the accidentals are designed at the same scaling in order to allow a uniform appearance. You will however have to check if they don't affect an even line spacing.
+
+See \fref{tab:accidentals} for the list of implemented commands.
+
+\begin{reftable}{Accidentals}{accidentals}
+\natural & \cmd{natural} & accidentals.natural\\
+\midrule
+\sharp & \cmd{sharp} & accidentals.sharp\\
+\sharpArrowup & \cmd{sharpArrowup} & accidentals.sharp.arrowup\\
+\sharpArrowdown & \cmd{sharpArrowdown} & accidentals.sharp.arrowdown\\
+\sharpArrowboth & \cmd{sharpArrowboth} & accidentals.sharp.arrowboth\\
+\sharpSlashslashStem & \cmd{sharpSlashslashStem} & accidentals.sharp.slashslash.stem\\
+\sharpSlashslashslashStemstem & \cmd{sharpSlashslashslashStemstem} & accidentals.sharp.slashslashslash.stemstem\\
+\sharpSlashslashslashStem & \cmd{sharpSlashslashslashStem} & accidentals.sharp.slashslashslash.stem\\
+\sharpSlashslashStemstemstem & \cmd{sharpSlashslashStemstemstem} & accidentals.sharp.slashslash.stemstemstem\\
+\doublesharp & \cmd{doublesharp} & accidentals.doublesharp\\
+\midrule
+\flat & \cmd{flat} & accidentals.flat\\
+\flatflat & \cmd{flatflat} & accidentals.flatflat\\
+\end{reftable}
+
+\section{Rests}
+\label{sec:rests}
+
+See \fref{tab:rests} for the implemented rest commands.
+
+For more information on how to use \cmd{lilyPrintMoreDots} to produce multiply dotted rests please see \fref{sec:dotted_symbols}.
+
+\begin{reftable}{Rests}{rests}
+\wholeNoteRest & \cmd{wholeNoteRest} & Whole Note Rest\\
+\wholeNoteRestDotted & \cmd{wholeNoteRestDotted} & DottedWhole Note Rest\\
+\midrule
+\halfNoteRest & \cmd{halfNoteRest} & Half Note Rest\\
+\halfNoteRestDotted & \cmd{halfNoteRestDotted} & Dotted Half Note Rest\\
+ \halfNoteRestDotted\lilyPrintMoreDots &
+ \cmd{halfNoteRestDotted}\cmd{lilyPrintMoreDots} &
+ Example of Double Dotted Rest\\
+\midrule
+\crotchetRest & \cmd{crotchetRest} & Crotchet Rest\\
+\crotchetRestDotted & \cmd{crotchetRestDotted} & Dotted Crotchet Rest\\
+\midrule
+\quaverRest & \cmd{quaverRest} & Quaver Rest\\
+\quaverRestDotted & \cmd{quaverRestDotted} & Dotted Quaver Rest\\
+\midrule
+\semiquaverRest & \cmd{semiquaverRest} & Semiquaver Rest\\
+\semiquaverRestDotted & \cmd{semiquaverRestDotted} & Dotted Semiquaver Rest\\
+\end{reftable}
+
+\section{Dynamic Text}
+\label{sec:dynamic_text}
+As explained earlier the Dynamic Letters can be accessed through \cmd{lilyText} without providing glyph names or numbers as argument.
+For the available letters see \ref{tab:singleDynLetters}.
+As a convenience there is a predefined command \cmd{lilyDynamics}, which is just a wrapper around \cmd{lilyText} that sets the \texttt{Scale} argument to a default value of 1.5.
+
+\begin{reftable}{Single Dynamics Letters}{singleDynLetters}
+\lilyDynamics{f} & \cmd{lilyDynamics\{f\}} & forte\\
+\lilyDynamics{p} & \cmd{lilyDynamics\{p\}} & piano\\
+\lilyDynamics{m} & \cmd{lilyDynamics\{m\}} & mezzo-\\
+\lilyDynamics{r} & \cmd{lilyDynamics\{r\}} & rin-\\
+\lilyDynamics{s} & \cmd{lilyDynamics\{s\}} & s-\\
+\lilyDynamics{z} & \cmd{lilyDynamics\{z\}} & -z\\
+\end{reftable}
+
+These Letters can be combined to make complex Dynamics.
+\lilyglyphs{} doesn't provide predefined commands as they can easily be entered as single strings to \cmd{lilyDynamics}, like \cmd{lilyDynamics\{sffzrmp\}}, resulting in \lilyDynamics{sffzrmp}.
+In this specific situation you could enter a small horizontal space between the \lilyDynamics{z} and the \lilyDynamics{r} -- but as this combination wouldn't occur in real life we don't need to demonstrate it here.
+There are a few predefined commands (see \fref{tab:combinedDynLetters}) handling the “kerning†of some special combination of letters.
+Internally these commands internally use \cmd{lilyDynamics} with its default scaling.
+
+\begin{reftable}{Combined Dynamics Expressions}{combinedDynLetters}
+\lilyRF & \cmd{lilyRF} & rinforzando\\
+\lilyRFZ & \cmd{lilyRFZ} & rinforzando (alternative)\\
+
+\end{reftable}
+
+
+\section{Graphical Dynamic Symbols}
+\label{sec:graphical_dynamic_symbols}
+
+Graphical dynamic symbols like hairpins are realized by including image files.
+See \fref{tab:dynamicSigns} for the implemented commands.
+
+\begin{reftable}{Dynamics Signs}{dynamicSigns}
+\crescHairpin & \cmd{crescHairpin}\\
+\decrescHairpin & \cmd{decrescHairpin}\\
+\end{reftable}
+
+\section{Articulations}
+\label{sec:articulations}
+
+\begin{reftable}{Articulations}{articulations}
+\lilyAccent & \cmd{lilyAccent}\\
+\lilyEspressivo & \cmd{lilyEspressivo}\\
+\lilyStaccato & \cmd{lilyStaccato}\\
+\lilyThumb & \cmd{lilyThumb} & Thumb pizzicato\\
+\marcato & \cmd{marcato}\\
+\marcatoDown & \cmd{marcatoDown}\\
+\portato & \cmd{portato}\\
+\portatoDown & \cmd{portatoDown}\\
+\staccatissimo & \cmd{staccatissimo}\\
+\tenuto & \cmd{tenuto}\\
+\end{reftable}
+
+\section{Scripts}
+\label{sec:scripts}
+
+Script implementation has just begun. For the implemented glyphs see \fref{tab:scripts}.
+
+If you manually enter scripts through \cmd{lilyGlyph} you will notice that they usually seem to print too far to the left, clashing with the preceding text.
+This is due to the fact that in musical engraving scripts are centered relative to the note they belong to.
+Therefore you often have to add extra space before the glyph if you access them directly.
+The predefined commands should of course have this already built in.
+
+\begin{reftable}{Scripts}{scripts}
+\fermata & \cmd{fermata} & Fermata\\
+\end{reftable}
+
+\section{Accordion Notation}
+\label{sec:accordion-notation}
+
+\begin{reftable}{Accordion notation}{accordion-notation}
+\accordionBayanBass & \cmd{accordionBayanBass} & Bayan bass register\\
+\accordionDiscant & \cmd{accordionDiscant} & Discant register\\
+\accordionFreeBass & \cmd{accordionFreeBass} & Free bass register\\
+\accordionOldEE & \cmd{accordionOldEE} & Unknown accordion notation\\
+\accordionPull & \cmd{accordionPull} & Directon of bellows\\
+\accordionPush & \cmd{accordionPush} & Directon of bellows\\
+\accordionStdBass & \cmd{accordionStdBass} & Standard bass register\\
+\end{reftable}
+
+These are the symbols present in the Emmentaler font.
+More symbols that are created through combination of the discant symbol with one or more accordion dot(s) have yet to be created.
+
+\section{Fancy (Example) Commands}
+\label{sec:fancy-examples}
+This is just an example of a fancy notation generated with the assistance of our scripts (see \fref{sec:generating_commands_image}).
+
+\begin{reftable}{Fancy (Example) Commands}{fancyexamples}
+\lilyFancyExample & \cmd{lilyFancyExample} & a fancy command using a LilyPond file\\
+\end{reftable}
+
+
+\chapter{Internals}
+\label{chap:internals}
+
+\section{Documentation of the generic access commands}
+\label{sec:internals_generic_access}
+This section is essential for readers who want to understand how this package works internally, for example if they want to actively participate in its development.
+It is structured from the perspective of the package's behaviour instead of from a user's POV.
+If you simply want to add your own predefined commands “the \lilyglyphs{} way†it is a good idea to read this section too, but you may also skip it and directly go to \ref{sec:directory_structure}.
+
+\medskip
+In order to make the package's \texttt{.sty} file easier to understand, its content is split into multiple input files which are located in the \dir{/commands} and \dir{/core} subfolders.
+The most fundamental definitions are in the \dir{core/keyval.inp} and \dir{core/genericAccess.inp} files.
+
+\subsection{Accessing \emmentaler{} Glyphs}
+\label{subsec:accessing_emmentaler_glyphs}
+The command that actually prints glyphs from the Emmentaler font is \cmd{lilyPrint}, defined in \texttt{core/genericAccess.inp}.
+It isn't intended to be called directly within a document, but only from the predefined commands.
+It takes two arguments, the first -- optional -- being the comma-separated list of \texttt{<key=value>} pairs, the second the actual content to be printed.
+
+\begin{lstlisting}[language={[LaTeX]TeX}]
+\newcommand*{\lilyPrint}[2][]{%
+ \interpretLilyOptions{#1}%
+ \raisebox{{\lilyEffectiveRaise}ex}{%
+ {\fontspec[Scale=\lilyEffectiveScale]
+ {emmentaler-\lilyOpticalSuffix.otf}#2}%
+ }%
+}
+\end{lstlisting}
+
+At first the command \cmd{interpretLilyOptions} is called, where the options of the different levels are evaluated and calculated to their effective values.
+Then the content of \#2 is printed, within a \cmd{raisebox} and with the currently selected opticals version of the \emmentaler{} font.
+
+\begin{lstlisting}[language={[LaTeX]TeX}]
+\newcommand*{\interpretLilyOptions}[1]{%
+ \setkeys{lilyCmdOptions}{scale=1,raise=0}%
+ \setkeys{lilyCmdOptions}{#1}%
+ \pgfmathsetmacro{\lilyEffectiveScale}{%
+ \lilyGlobalOptions@scale *
+ \lilyCmdOptions@scale * \lilyDesignOptions@scale}%
+ \pgfmathsetmacro{\lilyEffectiveRaise}{%
+ \lilyGlobalOptions@raise +
+ \lilyCmdOptions@raise + \lilyDesignOptions@raise}%
+}
+\end{lstlisting}
+\cmd{interpretLilyOptions} is defined in \dir{core/keyval.inp}.\\
+The \texttt{<key=value>} mechanism is achieved using the \texttt{keyval} package as the most basic solution available.
+{\color{red} If this can be implemented in a more elegant, extensible and/or powerful way using other packages, e.\,g.\ \package{pgfkeys}, we'd appreciate any input.}
+It uses three families of keys, corresponding to the three levels of options:
+\texttt{lilyGlobalOptions}, \texttt{lilyDesignOptions} and \texttt{lilyCmdOptions}.
+
+In a first step the keys for the actual command options are initialized to a neutral state.
+This is necessary because otherwise options not present in the command invocation would be in an uninitialized or unknown state.
+After this the options provided by the command invocation (i.\,e. the ones in the end user's document) are applied.
+Finally the effective values of the options are calculated from the global, the design and the command invocation options.
+The scaling values are multiplied, the raise values added.
+While the command options have just been determined, the global options are valid globally (and can be changed globally) and the design options have been set by the command that actually called \cmd{lilyPrint}.
+This is the reason why \cmd{lilyPrint} should never be invoked directly -- the design options would be in the unknown state of the previous invocation of\cmd{lilyPrint}.
+
+\medskip
+At the next higher level there are the three generic access functions \cmd{lilyGlyph}, \cmd{lilyGlyphByNumber} and \cmd{lilyText}, defined in \dir{core/genericAccess.inp}.
+They are very similar and differ only in the way they determine the actual content to be printed.
+As stated in the end user part of this documentation they expect two arguments, the optional \texttt{<key=value>} pair list and the contents.
+As a first step the commands initialize the design options to a neutral state, because the “design†of the generic glyphs has to be neutral by design.
+In the second step they invoke \cmd{lilyPrint}, passing the optional argument along and determine the printed content individually:
+\cmd{lilyGlyph} calls the helper function \cmd{lilyGetGlyph}, \cmd{lilyGlyphByNumber} calls \cmd{lilyGetGlyphByNumber}, while \cmd{lilyText} just passes its contents argument unchanged to \cmd{lilyPrint}.
+
+These helper functions are important because most predefined commands call one of them to select glyphs from the Emmentaler fonts.\\
+\cmd{lilyGetGlyph} takes the glyph name as found in the LilyPond documentation.\\
+\cmd{lilyGetGlyphByNumber} takes the Unicode character index of the intended glyph.
+But be aware that the Unicode index may change at any time with new versions of the Emmentaler font, so it usually isn't a good idea to access glyphs through their index.
+There may be some uses for numerical access, however, e.\,g.\ to iterate over a range of glyphs.
+
+\subsection{Printing image files}
+\label{subsec:printing_image_files}
+\cmd{lilyPrintImage}, defined in \dir{core/genericAccess.inp}, is the command that prints glyphs from a supplied image file.
+It actually is quite similar to \cmd{lilyPrint}, with only the extra consideration of scaling the image to the text font size.
+
+\begin{lstlisting}[language={[LaTeX]TeX}]
+\newcommand*{\lilyPrintImage}[2][]{%
+ % interpret optional argument
+ \interpretLilyOptions{#1}%
+ % determine scaling factor to accomodate the current font size
+ % (as images don't scale automatically with the font)
+ \lilyScaleImage%
+ % Print the image in a raisebox
+ \raisebox{{\lilyEffectiveRaise}ex}{%
+ \includegraphics[scale=\lilyImageEffectiveScale]{#2}%
+ }%
+}
+\end{lstlisting}
+First the command calls \cmd{interpretLilyOptions}, which is the same as with \cmd{lilyPrint}.
+But as an additional step \cmd{lilyScaleImage} is called, and finally it uses \cmd{lilyImageEffectiveScale} as the scaling factor instead of \cmd{lilyEffectiveScale}.
+I won't explain this in detail, but in effect it multiplies the \cmd{lilyEffectiveScale} calculated before with the ratio of the current font size to the \cmd{normalsize} size.
+
+What is finally given as the content to be printed is the basename of an image file.
+This can be any file format understood by the used \TeX engine but we highly recommend using \textsc{pdf} files for sake of printing quality.
+
+As with printing Emmentaler glyphs there is no handling of design time options here, and for that reason you should never call this command directly from a document.
+Please use \cmd{lilyImage} instead which does the same as \cmd{lilyPrintImage} but additionally defaults the design time options to neutral values.
+
+\section{The Package's Directory Structure}
+\label{sec:directory_structure}
+This section describes the directory structure as found in the development repository on GitHub%
+\footnote{\url{https://github.com/openlilylib/lilyglyphs}}.
+If you have obtained \lilyglyphs{} from there and want to write new commands on a regular basis, especially if you want to contribute your results back to the package, you will need to have a fair understanding of it.
+The same is true if you want to use the Python scripts as described in \fref{chap:python_scripts}.
+If you intend to contribute or just start doing so it is highly recommended to go that way.
+
+If you have downloaded \lilyglyphs{} from \textsc{ctan} there will be significant differences in the directory structure which are mentioned below, so you should read the section anyway.
+
+If you are using \lilyglyphs{} from a \TeX{} distribution you can't really consider the contents of this section because the files will be scattered over a number of system and distribution specific places which are out of our control.
+There is a way around this problem which is described in \fref{chap:python_scripts}, but we still recommend using the GitHub version for serious extending work.
+Getting an idea about the package content is a good idea nevertheless.
+
+\paragraph*{The root directory}
+contains the usual number of files such as \textsc{readme}, installation hints and licensing information as well as the main package file \texttt{lilyglyphs.sty}.
+
+\paragraph*{\dir{/core}
+\footnote{For this section a leading “/†in directory names refer to the package root directory.}}
+consists of include files for \texttt{lilyglyphs.sty} that contain the fundamental program logic of the package.
+
+\paragraph*{The \dir{/commands} directory}
+contains files defining the predefined commands available to the end user of \lilyglyphs.
+If you are going to write new commands you will include them in these files or add new files here.
+
+\paragraph*{\dir{/documentation}}
+contains this manual and an example document, boxth as \texttt{.tex} and \textsc{pdf} files as well as an \textsc{html} document listing all glyphs of the \emmentaler{} font.
+
+The subdirectory \dir{resources} contains included files for the \textsc{html} document as well as helper packages for the \LaTeX{} documents.
+The subdirectory \dir{lilyglyphs\_logo} contains the logo of the package in \textsc{pdf} and \textsc{png} format along with its \texttt{.tex} source.
+
+\paragraph*{\dir{/fonts}}
+contains the \emmentaler{} font files, copied from LilyPond 2.16.2 as the latest stable version.
+This is the directory you will have copied or linked to during a manual installation of the package.
+
+\paragraph*{\dir{/glyphimages}}
+contains all material for the image based commands: original input files, generated LilyPond source files and the resulting \textsc{pdf} images.
+If you are going to create new commands using LilyPond generated images you will work in this directory.
+This is explained in more detail in \fref{sec:generating_commands_image}.
+
+\paragraph*{\dir{/license}}
+contains the full \textsc{lppl} license for the package and the \textsc{ofl} license for the included Emmentaler fonts.
+
+\paragraph*{\dir{/scripts}}
+contains Python scripts that simplify the generation and management of new commands.
+In the \textsc{ctan} archive the contents of this directory is distributed over two directories, \dir{/bin} and \dir{/lib}.
+
+\paragraph*{\dir{source}}
+contains the \textsc{metafont} sources for the Emmentaler fonts.
+They are checked out from the LilyPond development repository at exactly the same state as the binary font files used.
+
+\subsection{“Private†Directory Structure}
+\label{subsec:private_directory_structure}
+If you have obtained \lilyglyphs{} any other way than through its Git repository you probably can't or don't want to modify the package files directly.
+Instead we recommend you set up a private “shadow†search path where you can safely place your own additions.
+Apart from potential issues with write access to files in the \TeX{} installation this procedure will avoid your changes being overwritten by package updates.
+
+We have provided a skeleton directory structure in the file \dir{lilyglyphs\_private.zip} which is located in the \dir{documentation/} directory of the package%
+\footnote{Please consult the documentation of your \TeX{} distribution where to find these.
+A good chance would be to run \texttt{kpsewhich lilyglyphs.sty} which should find the location of the main package file}.
+Extract this archive somehwere in your \LaTeX{} search path, e.\,g. to \dir{TEXMFHOME/tex/latex/lilyglyphs\_private}.
+
+In the first level of this directory you'll find two nearly empty stubs: \texttt{lilyglyphsPrivate.sty} and \texttt{lilyglyphsPrivate.tex}.
+The first file is a \LaTeX{} package where you can store and organize your own predefined commands%
+\footnote{Of course you will have to “use†this package to make the commands available to other documents},
+the second a file where you can (and are strongly advised to) document your additions.
+If you make use of these files in a structured way (following the hints in the comments in these files) it will be very easy for us to incorporate any additions you send to us by email (if you don't want to go the Git way).
+
+The rest is a copy of the directory structure below \dir{/glyphimages}.
+There you can store sources and results of commands generated with LilyPond.
+Please adhere to the model of the directories in the package for this.
+And please also see the chapter \fref{chap:contributing} on contributing.
+
+\section{How to write predefined commands}
+\label{sec:howto_predefined_commands}
+Writing your own predefined commands is actually quite straightforward -- and identical if you want to write a command for your document or for inclusion in the package.
+So if you find yourself creating predefined commands that you think are useful for general use, don't hesitate to submit them to us.
+
+\subsubsection{Commands that print single glyphs}
+\label{subsubsec:commands_single-glyphs}
+Let's review an example of a predefined command, the \cmd{doublesharp}.
+
+\begin{lstlisting}[language={[LaTeX]TeX}]
+% "accidentals.doublesharp"
+\newcommand*{\doublesharp}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.35}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.doublesharp}}%
+}
+\end{lstlisting}
+
+We use the starred version of \cmd{newcommand}, because a glyph command naturally doesn't span paragraphs.
+We declare to accept one optional argument, which defaults to empty.
+This argument can take the list of \texttt{<key=value>} options.
+When writing the commands, please take care not to omit the \texttt{\%} characters at the line endings, as they prevent unwanted whitespace to be introduced in the output.
+
+In the second line we define the design options for the command.
+In the example the designer has decided that a doublesharp glyph should be scaled to 1.5 and raised 0.35\,ex compared to its default appearance.
+
+The third line calls the internal \cmd{lilyPrint} command.
+It passes the optional argument, with which the end user can override (i.\,e.\ modify) the designed values.
+As the \doublesharp{} is a glyph that has to be selected by its glyph name, we call \cmd{lilyGetGlyph}, supplying the glyph name found in the documentation.
+The result of this command is passed as the \texttt{\#2} to \cmd{lilyPrint}.
+
+To summarize: Writing a predefined command for printing an Emmentaler glyph involves just two steps, setting the design time options and calling \cmd{lilyPrint} with the appropriate \#2 argument.
+
+\medskip
+If you know the Unicode number of the desired glyph you can call \cmd{lilyGetGlyphByNumber} instead of \cmd{lilyGetGlyph}, but you can't be sure this number will stay the same forever.
+
+\medskip
+Creating commands using image files is practically the same and even simpler.
+If you look at the definition of a \cmd{crotchet},
+\begin{lstlisting}[language={[LaTeX]TeX}]
+\newcommand*{\crotchet}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.9,raise=-0.2}%
+ \lilyPrintImage[#1]{crotchet}%
+}
+\end{lstlisting}
+you will notice that the only differences are that the actual printing is done with \cmd{lilyPrintImage} instead of \cmd{lilyPrint} and that therefore the basename of the image file can be passed directly.
+In \fref{sec:generating_commands_image} you will see a tool that allows to create numerous image commands quite easily.
+
+\bigskip
+As a last example we will look at the definition of \cmd{lilyRFZ} \lilyRFZ.
+
+\begin{lstlisting}[language={[LaTeX]TeX}]
+\newcommand{\lilyRFZ}[1][]{%
+ \mbox{%
+ \lilyDynamics[#1]{r\hspace{0.035ex}fz}%
+ }%
+}
+\end{lstlisting}
+You may notice that we use \cmd{lilyDynamics} here, one of the Generic Access Commands (see \fref{sec:generic_access_commands}) instead of the low-level printing command.
+We can do this and also use the other ones: \cmd{lilyText}, \cmd{lilyGlyph}, \cmd{lilyGlyphByNumber} or \cmd{lilyImage}.
+This is actually simpler because we don't have to set the design time options -- but that's also the main disadvantage: this way we \emph{can't} set them and have to use the given default parameters.
+As mentioned in \fref{sec:dynamic_text}, \cmd{lilyDynamics} is just a wrapper around \cmd{lilyText}, setting the \texttt{scale} factor to 1.5.
+While the other generic commands only print single glyphs, \cmd{lilyText} can print ‘plain text’, so usually there is no need to write predefined commands only to combine letters to a single command.
+In some cases this may however be necessary.
+In the given example of \cmd{lilyRFZ} we need to apply a little bit of extra space between the \lilyDynamics{r} and the \lilyDynamics{f}.
+We see that we can insert a \cmd{hspace} command between the letters without any problems.
+But as it turns out \LaTeX{} may now decide to insert a line break at its discretion, so we have to additionally enclose this call to \cmd{lilyDynamics} in a \cmd{mbox}.
+The command just passes the optional argument to \cmd{lilyDynamics}, so you can use these arguments in your document as usual.
+
+This example is meant to encourage you to experiment with the definition of new commands.
+All you have to deal with is setting the design time options and the optional argument, and chosing the appropriate input method for the second argument.
+Apart from this you can design commands as you aanre used to.
+
+\bigskip
+Once you have defined your new command you of course have to make it av ailable to \LaTeX.
+If it is a “local†command that you just use for a specific document you can simply put it in the document's preamble or a dedicated helper \texttt{.sty} file.
+If it is an image driven command you will have created the image file before and will have to place this in a location where \LaTeX{} can find it.
+But the best place you can permanently store your new commands is the \package{lilyglyphsPrivate} package described in \fref{subsec:private_directory_structure}.
+Please don't forget to document your command in \texttt{lilyglyphsPrivate.tex}.
+For more information on how to contribute your new commands to the package see \fref{chap:contributing}.
+
+\subsubsection{Create Dotted Symbols}
+\label{subsubsec:dotted_symbols}
+
+It is not exactly trivial to create dotted symbols as predefined commands.
+Of course you can always use \cmd{lilyDot} to print LilyPond's dot glyph, but if you want to create commands that combine a glyph and one ore more dots you encounter two difficulties:
+You can't apply the optional arguments independently on the two items, and there may be issues with the scaling and the gap between the two glyphs.
+
+There is some infrastructure in \lilyglyphs{} (defined in the file dotted.inp) to faciliate dealing with dotted symbols, but this implementation isn't completely satisfactory so far.
+Great care has been taken to hide as much complexity as possible in the mentioned file, in order to make the definition of actual commands as clean and concise as possible.
+
+Let's analyze the implementation of a dotted half note rest:
+\begin{lstlisting}[language={[LaTeX]TeX}]
+% Dotted half note rest
+\newcommand*{\halfNoteRestDotted}[1][]{%
+ % define the optional arguments for the dot
+ \setkeys{lilyDesignOptions}{scale=0.8,raise=0.2}%
+ % Calculate effective scale/raise and the hspace for the dot
+ \lilySetDotOptions[#1]{0.05}{0.5}{0}%
+ % Print the rest and then the dot
+ \halfNoteRest[#1]\lilyDotSpace\lilyPrintDot
+}
+\end{lstlisting}
+
+The command takes the usual optional argument that can contain \texttt{<key=value>} pairs.
+This applies to the dotted symbol as a whole.
+Please note that in the last line the predefined command \cmd{halfNoteRest[\#1]} is called and passed the optional argument.
+You can only use this technique of creating dotted symbols on top of correctly implemented predefined commands.
+
+The first thing you have to do is to define the DesignTimeOptions for the dot. They are relative to the original design of \cmd{lilyDot}, and you have to adjust them so the dot suits the main glyph in its size and vertical position (you can ignore the horizontal spacing for now):
+\begin{lstlisting}[language={[LaTeX]TeX}]
+ % define the optional arguments for the dot
+ \setkeys{lilyDesignOptions}{scale=0.8,raise=0.2}%
+\end{lstlisting}
+You should always set these options because otherwise you might get strange results or error messages.
+
+The next step is to call a quite complex command \cmd{lilySetDotOptions} that sets several options for the dot:
+\begin{lstlisting}[language={[LaTeX]TeX}]
+ % Calculate effective scale/raise and the hspace for the dot
+ \lilySetDotOptions[#1]{0}{0.5}{0.4}%
+\end{lstlisting}
+This command takes one optional and three mandatory arguments.
+The optional argument is just the one that is written in the \LaTeX{} document and that is passed into the function. The remaining three arguments control the horizontal spacing between the main glyph and the dot.
+As we now have two individual elements we have to control the gap between them explicitely as it doesn't scale relative to the \texttt{scale} argument by itself.
+The relation between the \texttt{scale} factor and the horizontal gap can be understood as a curve (mathematically spoken: a 2nd order function).
+
+The first (mandatory) argument sets the intensity of the curve.
+A value of 0 will result in a linear relation (no curve at all), that is when doubling \texttt{scale} the gap will be exactly twice as wide.
+Positive values will result in larger gaps for larger \textbf{scale}s.
+As this is a quadratic function you will want to start with very small values or 0.
+
+The second argument sets the general (linear) steepness of the curve.
+A value of 1 means that by increasing \texttt{scale} by 1 the gap will be wider by 1\emph{ex}.
+0.5 seems a good starting point for this argument.
+
+The last argument is an offset in \emph{ex} for the whole curve which is independent from the scaling.
+You can use it to accomodate specifically wide or narrow glyphs.
+
+\cmd{lilySetDotOptions} takes all these informations, calculates some settings for the dot and stores them in internal variables that can be used by subsequent commands.
+Please understand that they may be partially or totally overwritten by the next use of \emph{any} predefined command.
+So you have to call this command immediately before actually printing the dot, otherwise it may or may not provide satisfying results.
+
+The final line actually calls three commands:\\
+\cmd{halfNoteRest[\#1]} prints the already defined main glyph.
+\cmd{lilyDotSpace} prints a horizontal space that is determined by the previous call to \cmd{lilySetDotOptions}, and \cmd{lilyPrintDot} finally prints the dot with the settings just defined.
+
+\begin{lstlisting}[language={[LaTeX]TeX}]
+ % Print the rest and then the dot
+ \halfNoteRest*[#1]\lilyDotSpace\lilyPrintDot
+\end{lstlisting}
+
+This was an explanation from the perspective of designing new predefined commands.
+If you want to know how this is implemented internally, please look at the generously commented file \texttt{core/dotted.inp}.
+
+\paragraph*{Known issues and warning:}
+One issue that hasn't been addressed yet is the vertical placement of the dot when scaled.
+The dot is positioned relatively to the baseline of the text, and the main glyph may have a different center point.
+So when scaling the main glyph may seem to behave differently from the dot.\\~\\
+If you want to create a dotted version of a glyph that is printed from an image file it will generally be easier and more reliable to create a command using a new image file.
+
+
+\subsubsection{Create Multiply Dotted Symbols}
+\label{subsubsec:multiply_dotted_symbols}
+
+There is no need to define additional versions of glyphs with more than one dot.
+For this purpose we have implemented the command \cmd{lilyPrintMoreDots}.
+This prints a dot with the same characteristics as the preceding one from a dotted command (but remember that there shouldn't be any calls to other predefined commands in betwen).
+The horizontal gap between the dots scales linearly with a default of 0.25\emph{ex} per unit of \texttt{scale}.
+But if you pass an number as an optional argument this is interpreted as a different gap in \emph{ex}.
+
+\chapter{Generating Commands with Python}
+\label{chap:python_scripts}
+As we just have seen in \fref{subsubsec:commands_single-glyphs} it is quite easy to create predefined commands.
+At least with regard to the Emmentaler glyphs it is really straightforward to simply create a command based on existing models and the documentation.
+Nothing prevents you from simply adding new commands to your document or helper package.
+Image driven commands are slightly more complex.
+The \LaTeX{} part is equally straightforward, but you also have to provide the \textsc{pdf} image by creating a score with LilyPond and produce the right output file, which involves a few steps.
+
+Therefore we have developed a set of tools and templates to streamline the process of creating new commands even further.
+These tools are Python 2 scripts, so in order to use them you will need a working Python installation.
+They are located in the \dir{/scripts} (GitHub version) or \dir{/bin} (\textsc{ctan} version) directory of the package.
+If you want to create image driven commands you will of course have to have LilyPond installed too.
+In both cases the process basically consists of writing a definitions file (something like a template), calling a script and then putting the results to a useful place.
+
+To summarize your options for extending the symbols coverage:
+\begin{itemize*}
+\item If you only have the plain \lilyglyphs{} package you can create new commands using Emmentaler glyphs.\\
+You can also create image driven commands using any preexisting images (e.\,g. scans or output from any software).
+\item If you also have LilyPond installed you can additionally create image driven commands that match the ones already present in the package.
+\item If you have Python working you can make use of our tools to generate Emmentaler and LilyPond commands (LilyPond presence provided).
+\end{itemize*}
+
+The Python scripts expect to work inside either the package directory itself or in the private “shadow†directory described in \fref{subsec:private_directory_structure}.
+They perform the check based on the “lilygpyhs†part of the directory name, so for the scripts to work correctly it is crucial that you didn't change their names during a manual installation.
+
+\medskip
+All Python scripts handle \texttt{-h/--help} and \texttt{-v/--version} arguments, printing a short usage help or the current \lilyglyphs{} version.
+
+\paragraph{Licensing Note}
+All files generated by the Python scripts contain the \lilyglyphs{} license preamble stating them to be licensed with the GPL.
+But this is only relevant if you contribute them back to the package itself.
+Initially these generated files are the result of \emph{your} work and you can do with them whatever you want.
+So if you use the Python scripts to create commands for your own needs you can simply remove the license preamble from them.
+
+\section{Generating Commands for \emmentaler{} Glyphs}
+\label{sec:generating_commands_emmentaler}
+
+Generating commands that print Emmentaler glyphs with our tools is a straightforward process.
+The steps involved are few:
+\begin{inparaenum}[1)]
+\item create an input definitions file,
+\item run a Python script on it,
+\item fine-tune the commands in the generated \LaTeX{} file, and
+\item move the resulting code to an appropriate place.
+\end{inparaenum}
+We'll go through these steps in the following subsections.
+Be assured that although these instructions span several pages the actual process of creating new commands is very fast once you have got used to it.
+
+In addition to the following documentation you can also refer to a more casual post on the \emph{Scores of Beauty} blog%
+\footnote{\url{http://lilypondblog.org/2013/09/extending-lilyglyphs-part-1/}}
+which shows an example of creating a complete group of glyphs.
+
+\subsection{Preparing the Input File}
+\label{subsec:GGC_preparing_input_file}
+
+The first step is to create a text file with entries for any number of new commands to be created.
+You can save it to any convenient location, and it is up to you to keep this file for reference or drop it after use.
+
+The input file consists of one ore more command definitions.
+Each command definition is composed of a set of lines with \texttt{key=value} pairs (please note that you shouldn't use whitespace around the equals sign).
+The end of the definition is indicated by an empty line, therefore it is important that your file ends with an empty line, otherwise the last entry will be discarded.
+Lines beginning with Python and \LaTeX{} style comments (\% and \#) are ignored, so you can use them to document your file if you want.
+
+
+\medskip
+A command entry consists of several mandatory or optional lines.
+The order doesn't matter, but it is considered good practice to stick to one style.
+The following items are possible/necessary:
+\begin{itemize}
+ \item \textsf{\textbf{cmd} (mandatory)}: Specifies the command name.
+ You have to make sure that it is a valid \LaTeX{} name and that it isn't in use already.
+ \lilyglyphs{} prefixes commands that seem prone to ambiguity with “lily†followed by an uppercase letter: instead of \cmd{dynamics} we used \cmd{lilyDynamics}.
+ You are encouraged to adhere to that convention.
+ \item \textsf{\textbf{comment} (optional)}: You can pass a single line comment that will be used before the command definition.
+ (If you want to have a multiline comment instead you can insert line breaks with \cmd{n}.)
+ \item \textsf{\textbf{element} (mandatory)}: The actual element to be passed to the internal printing functions.
+ The possible type of its value depends on the \texttt{type} of the command, as described below.
+ \item \textsf{\textbf{type} (mandatory, but defaulted)}: The type determines the internal printing command to be used with the command.
+ Please refer to \fref{sec:generic_access_commands} for more information.
+ The option is mandatory but defaults to “glyphnameâ€, so you can skip it for the most common case that the glyph is called by name.
+
+ \begin{itemize}
+ \item \textbf{\texttt{glyphname:}} The glyph is selected by its glyphname, which is what you have to specify as “element†(e.\,g. “accidentals.sharp“ (without the quotes)).
+ You can look up the glyph names in LilyPond's documentation or in the glyph list contained in the package.
+
+ \item \textbf{\texttt{number:}} The Unicode number is used to determine the glyph.
+
+ \item \textbf{\texttt{text:}} The content is passed as plain text (works only for Dynamic letters, numbers and \texttt{+ - , .})
+
+ \item \textbf{\texttt{dynamics:}} The content is also passed as plain text, but the \cmd{lilyDynamics} function is used to print it (applying the suitable default scaling).
+
+ \item \textbf{\texttt{image:}} The command prints an image file.\\
+ If you already have an image file created with LilyPond or obtained from any other source than LilyPond (e.\,g. a scanned image from a printed edition or an autograph) this is the recommended way to create image driven commands.
+ []You can even use this to create non-musical commands that print images and profit from \lilyglyphs' infrastructure (like the automatic scaling with text size).]
+ For this purpose you can use .pdf files (preferred) or any image files your \LaTeX{} installation can process.
+
+ The “element†for an image driven command is the plain file name without extension or path.
+ The file has to be stored in a location that is visible to \LaTeX, and you are responsible for avoiding name clashes.
+ If you have set up a private directory structure as recommended in \fref{subsec:private_directory_structure}, its \dir{custom\_images} subdirectory is a good choice.
+ \end{itemize}
+ \item \textsf{\textbf{scale / raise} (optional):}
+ If a line contains one of the keys \verb|scale=| or \verb|raise=| the value after the equals sign is used for the design time options of the new command.
+ These values are also kept for subsequent command entries until the file is finished or the script finds a new entry -- which would replace its value.
+ The idea behind this option is to simplify the (likely) process of defining a set of related commands within an input file with its high probability of sharing default values.
+\end{itemize}
+
+\noindent Here you can see two examples of command entries:
+\begin{lstlisting}
+cmd=fermataDown
+element=scripts.dfermata
+comment=downward fermata
+# type glyphname is implicitely used
+
+cmd=rinforzando
+type=dynamics
+element=rfz
+comment=Rinforzando (kerned)
+\end{lstlisting}
+
+In the following subsection you can see what these commands are processed to.
+
+\subsection{Generating the \LaTeX{} code}
+\label{subsec:GGC_processing}
+
+The Python script that processes your input file is \texttt{lily-glyph-commands.py}.
+It expects the (absolute or relative) filename of the input file as its first and single parameter (apart from the mentioned standard arguments).
+The program parses the input file and creates a new file with the same basename but a \texttt{.tex} extension, in the same folder where the input file is.
+Please note that the script in its current implementation will silently overwrite any earlier file with that name.
+So if you need to keep such a generated file for reference you'll have to copy/move it to a safe location.
+
+The resulting file is a working \LaTeX{} document that uses the \lilyglyphs{} package.
+It contains \LaTeX{} \cmd{newcommand} definitions for each command definition in the input file.
+The visible part of the document contains a reference table (as used throughout this manual) with all generated commands and additionally example text for each generated command.
+
+The examples above would be processed to the following two \LaTeX{} commands:
+\begin{lstlisting}[language={[LaTeX]TeX}]
+% downward fermata
+\newcommand*{\fermataDown}[1][0]{%
+ \setkeys{lilyDesignOptions}{scale=1,raise=0}%
+ \lilyPrint[#1]{\lilyGetGlyphs{scripts.dfermata}}%
+}
+
+% Rinforzando (kerned)
+\newcommand*{\rinforzando}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1,raise=0}%
+ \lilyDynamics{rfz}}%
+}
+\end{lstlisting}
+
+\subsection{Fine-tuning the \LaTeX{} Commands}
+\label{subsec:GGC_fine-tuning}
+So what are we going to do with the contents of this file?
+Well, it depends on how/where you want to eventually use it, but the first step will be to fine-tune the commands.
+
+The first thing the generated example text does is showing that the command actually works.
+But its more important purpose is to print the new glyph in different contexts: in continuous text, before punctuations, at the beginning of a line etc.
+You should use these blocks of example text to adjust the arguments in the \verb|\setkeys{lilyDesignOptions}| clause.
+The script generates default values for the design time values of the optional argument, and it would of course be purely random if they would be perfect right away.
+Even if you supplied \texttt{scale} and/or \texttt{raise} values in the input file you're likely to have to tune the results.
+You should specifically keep an eye on spacing issues: Does the glyph affect line spacing, is the “kerning†of the glyph correct?
+On the other hand you should probably try to keep corresponding glyphs at an equal scaling.
+Besides tweaking the optional argument values you can add space before or after the glyph -- keep in mind that you may as well use negative \cmd{hspace}.
+And of course you can adjust the commands any way you like, but if you are going to make experimental commands you will probably rather write them manually as described in \fref{sec:howto_predefined_commands}.
+
+\subsection{Finishing Off (and Contributing)}
+\label{subsec:GGC_finishing_off}
+If you are satisfied with the new command(s) you will have to move them to a useful place.
+If you are just creating the commands for your personal or one-time use you can either copy the command definitions to the preamble of your current \LaTeX{} document or to any style file you might maintain.
+A good choice would be the \package{lilyglyphsPrivate.sty} as described in \fref{subsec:private_directory_structure}.
+In this case it is recommended to supply documentation in the \texttt{lilyglyphsPrivate.tex} file on the same directory for your own reference.
+
+But of course we would be happy if you decided to contribute your commands as additions to the package -- we consider increasing coverage of glyphs through user contribution a natural way of evolution for \lilyglyphs.
+Be prepared for compilation errors when your contribution returns to you as package updates.
+Once this happens your own command definitions will try to re-define the commands, and \LaTeX{} will throw out error messages.
+In that case you will have to remove your definitions from your private packages (wherever you have put them) -- they are obsolete now anyway.
+
+Probably the simplest way to contribute is sending the processed \texttt{.tex} file as an email to the package maintainer (currently \href{mailto:ul@openlilylib.org}{\nolinkurl{ul@openlilylib.org}}).
+He would then incorporate them into the package.
+\emph{Please} keep the generated reference table in the file as we will need it to update the command reference in the manual.
+And please also add some information about your additions in the file: where it belongs, where it should be documented etc.
+If your commands need any special considerations (e.\,g. specific arguments) please also add some material suitable for the manual.
+
+If you are working on a fork of the GitHub repository (as is recommended for potential contributors) you can incoporate the new commands directly and send us a pull request (preferably as soon as possible to minimize risk of conflicts with others' changes).
+This works by completing the following steps:
+\begin{itemize}
+\item Create a new branch with a suitable name.
+\item Move/copy the command definitions (with all comments) to appropriate .inp files in the package's \dir{/commands} subdirectory.
+If you find you should create a new .inp file because your commands belong to a new category please take the existing files as a model and add an appropriate \cmd{input} statement to \texttt{lilyglyphs.sty}.
+For any newly created files copy\,\&\,paste the usual copyright comment at the beginning from another file.
+\item \emph{Please} add documentation for your commands in the manual (\texttt{/documentation/lilyglyphs.tex}).
+Find the appropriate subsection in the “Predefined commands†section (or create a new one) and add information to it.
+At least we need the entries in the reference table, but if there is anything special to note about the commands please explain this too.
+If you add to an existing subsection you may copy the rows from the table in the file generated by the script, otherwise you should copy the whole table (but update the caption and label fields appropriately).
+\item If you are happy with the result you can push to your fork of the repository and send a pull request through the GitHub web site.
+\end{itemize}
+
+If you have any questions on these procedures it is certainly a good idea to get in contact with us \emph{before} starting any substantial work.
+
+
+\section{Generating Commands with Glyph Images}
+\label{sec:generating_commands_image}
+Creating commands with images generated by LilyPond is a significantly more complex task than simply inserting Emmentaler glyphs, and therefore the Python script \texttt{lily-image-commands.py} is a more complex one.
+But from the end user's perspective the process is surprisingly similar:
+\begin{inparaenum}[1)]
+\item create an input definitions file,
+\item run a Python script on it,
+\item fine-tune the commands in the generated \LaTeX{} file, and
+\item move the resulting code to an appropriate place.
+\end{inparaenum}
+The main differences to consider are the different structure of the input files and some considerations about file locations.
+
+But let us start with looking at the form of the input files.
+
+
+\subsection{Preparing the Input Files}
+\label{subsec:BGI_preparing_input}
+\texttt{lily-image-commands.py} doesn't expect regular LilyPond source files as its input, but rather a file with one or multiple ‘snippets’ in it, similar to those for \texttt{lily-glyph-commands.py}.
+We will later see that it is possible and makes sense to provide compilable Lilypond files, though.
+
+Depending on the type of your \lilyglyphs{} installation you may work either in the \dir{/glyphimages} directory of the package or in the \dir{lilyglyphs\_private} directory you set up according to \fref{subsec:private_directory_structure}.
+So in the context of the following instructions \dir{/} or \texttt{ROOT} refer to the appropriate one of these two directories.
+
+Input definition files are to be stored in the \dir{/definitions} subdirectory .
+Other than the files used for the generation of Emmentaler commands these files are considered persistent and should remain in place to be able to recreate the images at a later time.
+Therefore it is recommended to define related commands in one file and give it an appropriate name.
+A filename extension isn't mandatory but you may use \texttt{.ly} as you will see later.
+The file name will also be reflected in the resulting file with the generated \LaTeX{} commands.
+
+As with the Emmentaler commands the definitions file can contain any number of command entries, although they are structured differently.
+
+A command entry starts with the special key \verb|%%lilyglyphs| on a single line.
+
+After this there may be any number of lines starting with a single \% as a LilyPond comment.
+These comment lines are used for commenting the command in the resulting \LaTeX{} file.
+
+If a line consists of the special key \verb|%%protected| the script skips the entire command.
+You should use this key whenever you consider a command finished because it will prevent LilyPond from recompiling that command%
+\footnote{This is especially important when working inside a Git repository.
+With any new or different LilyPond installation the generated \texttt{pdf} files are likely to be different and would therefore be considered as ‘modified’ by Git}
+and the script from re-generating the \LaTeX{} command.
+
+If a line contains one of the keys \verb|scale=| or \verb|raise=| the value after the equals sign is used for the design time options of the new command.
+These values are also kept for subsequent command entries until the file is finished or the script finds a new entry -- which would replace its value.
+The idea behind this option is to simplify the (likely) process of defining a set of related commands within an input file with its high probability of sharing default values.
+The setting of option defaults also works if a command is marked as “protectedâ€.
+Generally this is an advantage since you don't have to take care to correctly update the file when you mark something as protected.
+But there may be cases where you will want to remove the defaults setting from a \texttt{\%\%protected} clause.
+
+Afterwards you provide the actual LilyPond command in the form of a variable holding a musical expression.
+The first line should contain exactly the name, the '=' and the opening curly brace.
+The name of the variable is very important because it will also be used as the file name of the image file and the \LaTeX{} command name.
+The following lines are interpreted as LilyPond code until the parser finds a line starting with the closing curly brace.
+This will also end the command entry, but for readability's sake it is a good idea to enter at least one empty line after the entry.
+
+One important thing to know is that by default the generated image will \emph{not} print staff lines, a time signature and the clef.
+
+This is a minimal working example of a \lilyglyphs{} entry section:
+
+\begin{lstlisting}
+%%lilyglyphs
+% crotchet with upward stem
+crotchet = {
+ g'4
+}
+\end{lstlisting}
+
+\paragraph*{Warnings:}
+So far the parser isn't very smart.
+It just \emph{assumes} that the input file it parses is correct.
+If you provide code with deviations from this explanation, the script will probably produce erroneous results or just stop working.
+Probably it won't do any harm, but we can't make any promises on that.
+Please consider the script as being in a \textbf{very experimental} state.
+
+In the current implementation you can't create commands that \emph{do} print staff lines, time signatures or clefs.
+To achieve this you'd have to write the LilyPond input file(s) on your own.
+This issue is on the \textsc{todo} list for one of the next releases of \lilyglyphs.
+
+\bigskip
+You can define as many entries in one file as you like -- they will all be processed at once.
+Of course it is recommended to combine a coherent set of commands.
+
+Everything that is outside of the lilyglyph entries is ignored by the script, so you can make use of these places to make a usable LilyPond file out of it.
+You can start off with the file \texttt{/definitions/\_template.ly} to see how it works.
+
+Basically you have to copy your definition to a new variable named \texttt{symbol} and then include a special include file \texttt{score.ily} (which is provided in that \dir{/definitions} directory).
+This will print your command definition as the only element in a new score block that is prepared not to print staff, time signature and clef.
+You can repeat this several times, inserting top-level \cmd{markup}s and have LilyPond produce a sheet with all defined symbols.
+This way you can finish your design in “pure LilyPond†before actually going on to the \LaTeX{} part -- and at the same time prepare a reference sheet of your work.
+
+\begin{lstlisting}
+\version "2.16.2"
+
+%%lilyglyphs
+% crotchet with upward stem
+crotchet = {
+ g'4
+}
+\markup "Crotchet with upward stem"
+symbol = \crotchet
+\include "score.ily"
+
+% %lilyglyphs
+% crotchet with downward stem
+crotchetDown = {
+ \stemDown
+ c'4
+}
+\markup "Crotchet with downward stem"
+symbol = \crotchetDown
+\include "score.ily"
+
+% and so on ...
+\end{lstlisting}
+
+\subsection{Running the Script}
+\label{subsec:BGI_running}
+
+If you have prepared your input file you can run the \texttt{lily-image-commands.py} script, passing it the complete file name (as a relative or absolute path) of your definitions file.
+The script tries to check if the input file is in the correct location -- which is considered true if it is in a \dir{defintions} folder and has a \dir{lilyglyphs*} directory in its path.
+This is valid both within the package directory and the private directory structure.
+
+Now the script will do several things:
+
+\paragraph*{Generate LilyPond source files:}
+In a first step the program parses the input file and extracts information about the command definitions that haven't been marked as protected.
+For each command definition it generates one compilable LilyPond source file in the \dir{/generated\_src} directory, named with the command name.
+If there is such a file already (i.\,e. the command had already been processed before) you will be asked if you want to overwrite this file.
+If you are currently working on a command you will probably want the file to be overwritten, but if you \emph{accidentally} used a name that already exists you should of course keep the existing files and rename your new command.
+
+\paragraph*{Compile images with LilyPond:}
+Now these generated source files are compiled using LilyPond with the command line option \verb|-dpreview|.
+The directory is then cleaned up, and the resulting small PDF files are moved to the \dir{/pdfs} directory.
+
+\paragraph*{Generate \LaTeX{} commands:}
+Finally the script generates a \LaTeX{} file that is comparable to the one generated by the Emmentaler command generation script.
+It will be stored in the \dir{/generated\_cmd} directory as a \texttt{.tex} file with the same basename as your original input file.
+Please note that these generated files aren't considered persistent and will be overwritten if you repeatedly process the same input file.
+
+\subsection{Utilizing the results}
+\label{subsec:BGI_utilizing_results}
+
+If you have successfully run the script you have the following results:
+\begin{itemize}
+\item LilyPond source files in the \dir{/generated\_src} folder (one for each command),
+\item corresponding PDF files in the \dir{/pdfs} folder and
+\item the file \dir{/generated\_cmd/INPUTFILENAME.tex}.
+\end{itemize}
+
+You shouldn't touch the first two items but go on and open the \texttt{.tex} file.
+This file is structured identically as the files generated by \texttt{lily-glyph-commands.py}, and also the way to finish off and possibly contribute your commands is essentially the same as described in \fref{subsec:GGC_fine-tuning} and \fref{subsec:GGC_finishing_off}.
+
+There are a few differences however:
+
+\begin{itemize}
+\item You should always keep the original definitions file so you can later re-generate the image from it.
+This can happen when you need to modify it -- or when you want to upgrade the package to a new version of \emmentaler{} or LilyPond.
+\item Don't forget to mark finished command definitions as ‘protected’.
+\item Keep in mind that the generated \texttt{.tex} file will be overwritten next time the same input file is processed by the script, so if you need to make any changes to the \LaTeX{} command definitions you should immediately copy them to a safe place.
+\item Sometimes you will find that a rather tall glyph is difficult to accomodate because the necessary scaling will make it look unnaturally small.
+In such a case you might consider going back to the LilyPond side to review the design of your glyph (for example the glyphs for the single note commands have shortened stems).
+Please make sure that you understand the implications of the following section about partial processing.
+\item If you want to submit new commands by email we need
+\begin{inparaenum}[1)]
+\item the original definition,
+\item the generated LilyPond source, and
+\item the final \LaTeX{} command.
+\end{inparaenum}
+\end{itemize}
+
+\subsection{Partial processing of the input file}
+\label{subsec:BGI_partial_processing}
+
+You are encouraged to put a coherent set of multiple command definitions in one definitions file and keep this file, as it is the source from that everything can be rebuilt at any time.
+But there will be occasions when you don't want the Python script to do all the work over and over again.
+If you add a new command to the input file (and you \emph{should} add it to an existing file if it belongs to the same category) you only want the new command to be processed.
+Or if you are working on the fine-tuning of the commands (as described in the previous section) and decide that you have to change the LilyPond definition of a single glyph you also only want to reprocess this one.
+For this purpose you can mark entries in the input definitions file as “protectedâ€, in order to prevent them to be newly processed by the script.
+To do this you enter a line containing \verb|%%protected| in your entry definition (note the double percent sign and the absence of a \texttt{space} after them).
+You can see an example for this in the \texttt{\_template.ly} file -- because the example entry shouldn't be processed at all.
+From now on the marked command won't be processed anymore.
+This means that the LilyPond source file won't be generated again, LilyPond isn't run again for the script (which would be the most annoying thing), and the \LaTeX{} commands won't be generated again.
+The output file will of course be overwritten (you have renamed it before re-running the script, didn't you?) but it won't be cluttered with commands that you have already dealt with earlier.
+
+
+\subsection{Recreating Image Files}
+\label{subsec:BGI_recreating_images}
+
+There also are occasions when you might have to (re)create the \textsc{pdf} files that serve as the glyph images without having to regenerate the \LaTeX{} commands or the LilyPond source files.
+One example would be the upgrade to a new an \emmentaler{} version.
+In that case you can run the script \texttt{rebuild-pdfs.py}.
+In order to work the script expects the current working directory to be either the \dir{glyphimages} subdirectory of the package or the root of the \dir{lilyglyphs\_private} directory.
+This script essentially compares the directories with the generated LilyPond sources and with the created pdf files, and if it finds a source without a corresponding pdf it will call LilyPond to recreate it.
+If you don't want to regenerate \emph{missing} \textsc{pdf}s but rather replace \emph{existing} files you first have to delete the \emph{pdf} files on disk so the script can detect them as missing.
+Of course this script will only work with a working LilyPond installation.
+
+\medskip
+Maybe in the future there will be functionality to detect changes in the glyphs' definitions, or remove \textsc{pdf} files that don't have a corresponding source file anymore.
+
+\chapter{Contributing to \lilyglyphs}
+\label{chap:contributing}
+
+The original motivation to create \lilyglyphs{} was the need to include musical symbols in a critical report of a scholarly edition.
+Looking around on the internet and \textsc{ctan} I didn't find a solution that was even near the flexibility and output quality I wanted for this edition (and my work in general), so I came up with the idea of accessing the glyphs of LilyPond's \emmentaler{} font.
+Fortunately I realized very early that I should make all this more generic and create a public \LaTeX{} package.
+When I found the solution to incorporate non-Emmentaler glyphs through LilyPond-generated \textsc{pdf} images I saw that it worked out quite well.
+By now I have a solution that completely works for my personal needs and presumably is a useful package for any \LaTeX{} authors interested in incorporating musical symbols in their documents.
+
+But \lilyglyphs{} definitely is a package that lives on community contribution.
+Why? Because one of the main goals for continuing development is a growing coverage of glyphs.
+This task is very “scalable“ and prone to “crowd-development†because any number of contributors can add commands from the fields they are working on and need glyphs from.
+I personally will probably only add new commands as I need them for my work, maybe sometimes getting the hang and complete a group.
+So anybody who uses the package to a more than casual degree is highly encouraged to share his additions with me and the community.
+
+There are also existing issues with the \LaTeX{} implementation that can be seen in the project's issue tracker on GitHub (\url{https://github.com/openlilylib/lilyglyphs}).
+Furthermore I'm sure there are quite a few things that could be implemented more elegantly, more efficiently, or with less package dependencies -- this package is actually my first serious work with \LaTeX{} \dots
+
+And finally I have some ideas how \lilyglyphs' functionality could be enhanced, and others could come up with more ideas.
+For example I would be interested in having parametrized commands that can print a number of related glyphs, there could be more layout options, I would like to be able to use global layout options for specific glyph groups (e.g. raise all accidentals by a certain amount) etc.
+And one day I would like to make the package compliant to the currently emerging SMuFL standard%
+\footnote{\url{http://www.smufl.org}}
+in order to allow using glyphs from different music fonts.
+
+So if you think this package is interesting, please contact me so it can evolve over time!
+If you're just using it, please submit any additions you make for your own use (or start submitting arbitrary commands to enhance the package's coverage).
+And if you're a \LaTeX{} expert please don't hesitate to go right to the core and help me with the evolution of its code base \dots
+
+\end{document}
diff --git a/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs_logo/lilyglyphs_logo.pdf b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs_logo/lilyglyphs_logo.pdf
new file mode 100644
index 0000000000..00f399ac2e
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs_logo/lilyglyphs_logo.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs_logo/lilyglyphs_logo.png b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs_logo/lilyglyphs_logo.png
new file mode 100644
index 0000000000..84fb0770be
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs_logo/lilyglyphs_logo.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs_logo/lilyglyphs_logo.tex b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs_logo/lilyglyphs_logo.tex
new file mode 100644
index 0000000000..8186f7c9d3
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/lilyglyphs_logo/lilyglyphs_logo.tex
@@ -0,0 +1,57 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\documentclass{scrartcl}
+\usepackage{fontspec}
+\usepackage{lilyglyphs}
+\usepackage[%
+ top=0cm,
+ bottom=0cm,
+ left=0cm,
+ paperheight=5.2mm,
+ paperwidth=14.2mm]{geometry}
+
+\begin{document}
+
+\pagestyle{empty}
+\setmainfont{Gentium}
+\noindent
+\textit{lily}%
+ \hspace*{0.05ex}\clefGInline[scale=0.8,raise=0.2]%
+ \lilyOpticalSize{26}%
+ ly\lilyDynamics{p}%
+ \lilyOpticalSize{13}%
+ \hspace*{0.2ex}\flat[scale=0.9,raise=0.2]%
+ \lilyOpticalSize{11}%
+ \lilyDynamics{s}
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-088c978c.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-088c978c.png
new file mode 100644
index 0000000000..6e4a5e68e4
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-088c978c.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-1981c3c7.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-1981c3c7.png
new file mode 100644
index 0000000000..6ff4d13129
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-1981c3c7.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-20e8632d.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-20e8632d.png
new file mode 100644
index 0000000000..9d8a0acab1
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-20e8632d.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-2abb8a04.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-2abb8a04.png
new file mode 100644
index 0000000000..3ce8d17b35
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-2abb8a04.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-2be182be.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-2be182be.png
new file mode 100644
index 0000000000..ef5b6e07c7
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-2be182be.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-3b47d3fe.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-3b47d3fe.png
new file mode 100644
index 0000000000..130d1b161b
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-3b47d3fe.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-3f4afecc.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-3f4afecc.png
new file mode 100644
index 0000000000..be58e46305
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-3f4afecc.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-40869867.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-40869867.png
new file mode 100644
index 0000000000..2f149b1d89
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-40869867.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-5b13ce04.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-5b13ce04.png
new file mode 100644
index 0000000000..7feeee464a
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-5b13ce04.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-5c91a201.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-5c91a201.png
new file mode 100644
index 0000000000..bd3d3b8664
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-5c91a201.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-707477b7.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-707477b7.png
new file mode 100644
index 0000000000..b55caf19d7
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-707477b7.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-76dbcd67.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-76dbcd67.png
new file mode 100644
index 0000000000..3c90e65b86
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-76dbcd67.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-7fd84ff8.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-7fd84ff8.png
new file mode 100644
index 0000000000..dff2d3596e
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-7fd84ff8.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-8155deab.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-8155deab.png
new file mode 100644
index 0000000000..b8d8775d60
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-8155deab.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-8b332c94.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-8b332c94.png
new file mode 100644
index 0000000000..969abdd8f3
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-8b332c94.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-8d82df0c.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-8d82df0c.png
new file mode 100644
index 0000000000..67a96d63ad
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-8d82df0c.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-8d8bb8a3.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-8d8bb8a3.png
new file mode 100644
index 0000000000..2fbbaab19b
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-8d8bb8a3.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-907bc72d.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-907bc72d.png
new file mode 100644
index 0000000000..8b75a51946
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-907bc72d.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-a2bf82dd.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-a2bf82dd.png
new file mode 100644
index 0000000000..b26e80a272
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-a2bf82dd.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-ae3fd948.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-ae3fd948.png
new file mode 100644
index 0000000000..3f802d4363
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-ae3fd948.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-b3dc0958.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-b3dc0958.png
new file mode 100644
index 0000000000..d21b581033
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-b3dc0958.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-b69af986.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-b69af986.png
new file mode 100644
index 0000000000..631f9de6f2
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-b69af986.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-d9988a2c.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-d9988a2c.png
new file mode 100644
index 0000000000..03e03c0acc
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-d9988a2c.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-dffaecd2.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-dffaecd2.png
new file mode 100644
index 0000000000..4d70851eb0
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-dffaecd2.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lily-f4d0afc9.png b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-f4d0afc9.png
new file mode 100644
index 0000000000..8ba90ae872
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lily-f4d0afc9.png
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lilyglyphsManualFonts.sty b/macros/luatex/latex/lilyglyphs/documentation/resources/lilyglyphsManualFonts.sty
new file mode 100644
index 0000000000..f91ca70a0d
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lilyglyphsManualFonts.sty
@@ -0,0 +1,51 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lilyglyphsManualFonts}
+
+\RequirePackage{fontspec}
+
+% Of course we need lilyglyphs itself :-)
+\RequirePackage{lilyglyphs}
+
+% fontspec base settings
+\setmainfont[%
+ Ligatures=TeX,
+ Numbers=OldStyle]{Linux Libertine O}
+\setsansfont[Scale=MatchLowercase,
+ ItalicFont=LinBiolinumOI,
+ BoldFont=LinBiolinumOB,
+ Ligatures=TeX]{LinBiolinumO}
+\setmonofont[Scale=MatchLowercase]{DejaVu Sans Mono}
+
+\linespread{1.05}
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lilyglyphsStyle.sty b/macros/luatex/latex/lilyglyphs/documentation/resources/lilyglyphsStyle.sty
new file mode 100644
index 0000000000..bff6ad1c84
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lilyglyphsStyle.sty
@@ -0,0 +1,186 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lilyglyphsStyle}
+
+\RequirePackage{fontspec}
+
+% Of course we need lilyglyphs itself :-)
+\RequirePackage{lilyglyphs}
+
+% Improve typography and paragraph layout
+\RequirePackage{microtype}
+
+% Suppress superfluous ligature
+\RequirePackage[english]{selnolig}
+
+% Typeset XeLaTeX and LuaTeX logos regardless of engine used
+\RequirePackage{hologo}
+
+\frenchspacing
+
+% Enhanced table commands
+\RequirePackage{booktabs}
+\RequirePackage{longtable}
+
+% Tightly spaced lists
+\RequirePackage{mdwlist}
+
+% Typeset listings
+% (Special styles defined in OLLstyles.sty)
+\RequirePackage{listings}
+% Format listings with typewriter font by default
+\lstset{
+ frame=single,
+ basicstyle=\fontspec{Liberation Mono}\footnotesize}
+
+% Common table format for reference tables
+\newenvironment{reftable}[2]
+ {%
+ \begin{center}
+ \begin{longtable}[H]{lll}
+ \caption{#1}\\
+ \label{tab:#2}\\
+ \toprule
+ &\\
+ }
+ {%
+ &\\
+ \bottomrule
+ \end{longtable}
+ \end{center}
+ }
+
+% Insert a picture with a glyph list from LilyPond's glyph list
+% #1 is the caption of the figure
+% #2 the label name
+% #5 the file name of the image
+\newcommand{\glyphlist}[3]{%
+ \begin{figure}[htbp]
+ \centering
+ \includegraphics[width=.75\textwidth]{glyphlist/resources/#3}
+ \caption{#1}
+ \label{fig:#2}
+ \end{figure}
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Character styles
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Format LaTeX or LilyPond commands like \env with a prepended backslash
+\newcommand*{\cmd}[1]{\env{\textbackslash #1}}
+
+% Format directory names
+\newcommand*{\dir}[1]{\texttt{#1}}
+
+% Format environment names
+\newcommand*{\env}[1]{\texttt{#1}}
+
+% Format package names
+\newcommand*{\package}[1]{\texttt{#1}}
+
+% Add a TODO item that is easily spotted
+\newcommand{\todo}[1]{{\color{red}{\textbf{\textsf{[TODO: #1]}}}}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Other commands
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Reference an Issue on openLilyLib's Github account
+\newcommand*{\ghIssue}[1]{\href{https://github.com/openlilylib/lilyglyphs/issues/#1}{(GitHub-Issue \##1)}}
+
+% print "LilyPond" (may be formatted later)
+\newcommand*{\lilypond}{\texttt{LilyPond}}
+
+\newcommand*{\emmentaler}{\textsc{Emmentaler}}
+
+% print "openLilyLib" (may be formatted later)
+\newcommand*{\openlilylib}{\texttt{openLilyLib}}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Add fancyref for smart cross-references
+\RequirePackage{fancyref}
+
+% categories for subsection and subsubsection:
+
+% subsection - subsec:
+
+\newcommand*{\fancyrefsubseclabelprefix}{subsec}
+
+\fancyrefaddcaptions{english}{%
+ \providecommand*{\frefsubsecname}{subsection}%
+ \providecommand*{\Frefsubsecname}{Subsection}%
+}
+
+\frefformat{plain}{\fancyrefsubseclabelprefix}{\frefsubsecname\fancyrefdefaultspacing#1}
+\Frefformat{plain}{\fancyrefsubseclabelprefix}{\Frefsubsecname\fancyrefdefaultspacing#1}
+
+\frefformat{vario}{\fancyrefsubseclabelprefix}{%
+ \frefsubsecname\fancyrefdefaultspacing#1#3%
+}
+\Frefformat{vario}{\fancyrefsubseclabelprefix}{%
+ \Frefsubsecname\fancyrefdefaultspacing#1#3%
+}
+
+% subsubsection - subsubsec:
+
+\newcommand*{\fancyrefsubsubseclabelprefix}{subsubsec}
+
+\fancyrefaddcaptions{english}{%
+ \providecommand*{\frefsubsubsecname}{subsection}% the same as for subsection
+ \providecommand*{\Frefsubsubsecname}{Subsection}%
+}
+
+\frefformat{plain}{\fancyrefsubsubseclabelprefix}{\frefsubsubsecname\fancyrefdefaultspacing#1}
+\Frefformat{plain}{\fancyrefsubsubseclabelprefix}{\Frefsubsubsecname\fancyrefdefaultspacing#1}
+
+\frefformat{vario}{\fancyrefsubsubseclabelprefix}{%
+ \frefsubsubsecname\fancyrefdefaultspacing#1#3%
+}
+\Frefformat{vario}{\fancyrefsubsubseclabelprefix}{%
+ \Frefsubsubsecname\fancyrefdefaultspacing#1#3%
+}
+
+% End fancyref
+%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Options for use of hyperlinks
+% (make sure this is included last)
+\RequirePackage[%
+ colorlinks,
+ urlcolor=blue,
+ bookmarks=true,
+ bookmarksnumbered=true]{hyperref}
diff --git a/macros/luatex/latex/lilyglyphs/documentation/resources/lilypond-manuals.css b/macros/luatex/latex/lilyglyphs/documentation/resources/lilypond-manuals.css
new file mode 100644
index 0000000000..0da009ed24
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/resources/lilypond-manuals.css
@@ -0,0 +1,469 @@
+/**********************************************************/
+/* PAGE-WIDE SETTINGS */
+/**********************************************************/
+
+html {
+ height: 100%;
+}
+
+body {
+ margin: 0 auto;
+ padding: 0;
+ height: 100%;
+ font-size: 100%;
+ line-height: 1.125;
+ color: #000;
+ background-color: #fff;
+}
+
+/***********************************************************/
+/* HEADERS */
+/***********************************************************/
+
+.chapter, .section, .subsection, .subsubsection,
+.appendix, .appendixsec, .appendixsubsec,
+.unnumbered, .unnumberedsec, .unnumberedsubsec, .unnumberedsubsubsec,
+.subheading, .subsubheading {
+ color: #204a87;
+ border-bottom: 1px dashed black;
+ padding-bottom: 0.15em;
+ margin-top: 0.6em;
+ margin-bottom: 1em;
+}
+
+.settitle {
+ background: #b1d281;
+ font-size: 2em;
+ text-align: center;
+ padding: 0.4em 0.5em;
+ border: solid #7b925a;
+ border-width: 1px 0;
+ margin: 0;
+}
+
+.chapter, .appendix, .unnumbered {
+ font-size: 1.8em;
+}
+
+.section, .appendixsec, .unnumberedsec {
+ font-size: 1.6em;
+}
+
+.subsection, .appendixsubsec, .unnumberedsubsec {
+ font-size: 1.4em;
+}
+
+.subheading, .subsubsection, .unnumberedsubsubsec {
+ font-size: 1.25em;
+}
+
+.subsubheading {
+ font-size: 1em;
+ font-weight: bold;
+}
+
+.chapheading {
+ position: absolute;
+ height: 0;
+ overflow: hidden;
+ text-indent: -999em;
+}
+
+/***********************************************************/
+/* LINKS */
+/***********************************************************/
+
+a:link {
+ color: #0c51ab;
+}
+
+a:visited {
+ color: #804f01;
+}
+
+a:active {
+ color: #278800;
+}
+
+a:hover {
+ color: #0105ad;
+}
+
+/***********************************************************/
+/* BLOCK FORMATTING */
+/***********************************************************/
+
+blockquote, .smallexample {
+ width: 96%;
+ padding: 0;
+ border: solid #b1d281;
+ border-width: 1px 1px 1px 5px;
+ margin: 1em auto;
+}
+
+blockquote p, pre.smallexample {
+ padding: 1em;
+ margin: 0;
+}
+
+blockquote blockquote {
+ border: none;
+}
+
+.verbatim, .example, .lisp {
+ font-size: 1em;
+ padding: 1em;
+ margin: 0;
+}
+
+#main hr {
+ height: 0;
+ padding: 0;
+ border: 0;
+ margin: 0;
+ text-indent: -999em;
+}
+
+table.cartouche {
+ background: #f5f5dc;
+ width: 85%;
+ border-collapse: collapse;
+ padding: 0 0.5em;
+ border: 2px solid #8f5902;
+ margin: 0 auto 1em;
+}
+
+table.cartouche p {
+ padding: 1em;
+ margin: 0;
+}
+
+table.cartouche td {
+ border: none;
+}
+
+/***********************************************************/
+/* MAIN CONTENT */
+/***********************************************************/
+
+div#main {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ padding: 0;
+ margin: 0;
+ overflow: auto;
+}
+
+div#main li {
+ padding: 0 1em 0.5em 0;
+}
+
+div#main ul {
+ margin: 0;
+ padding-left: 3em;
+}
+
+h1, h2, h3, h4, p, table, address, dt {
+ padding-left: 1em;
+ padding-right: 1em;
+}
+
+p {
+ margin: 1em 0;
+}
+
+#languages {
+ padding: 0.5em 1em;
+ margin: 0;
+}
+
+pre.menu-comment {
+ font-size: 1em;
+ padding-top: 1em;
+ padding-bottom: 0;
+ margin: 0;
+}
+
+#main .contents li {
+ padding-bottom: 0;
+}
+
+#main .contents > ul {
+ margin-bottom: 1em;
+}
+
+/***********************************************************/
+/* TOC SIDEBAR */
+/***********************************************************/
+
+div#tocframe {
+ display: none;
+ position: absolute;
+ top: 0;
+ right: 73%;
+ bottom: 0;
+ left: 0;
+ padding: 0;
+ margin: 0;
+ overflow: auto;
+ background: #f5f5dc;
+ z-index: 100;
+ list-style-type: none;
+ font-size: 0.83em;
+ line-height: 1.3;
+}
+
+@media screen {
+ body > div#tocframe {
+ position: fixed
+ }
+}
+
+div#tocframe a:link, div#tocframe a:visited {
+ color: #454532;
+ text-decoration: none;
+}
+
+div#tocframe a:hover {
+ color: #232b16;
+ text-decoration: underline;
+}
+
+div#tocframe p.toc_uplink {
+ font-size: 1em;
+ line-height: 1.125;
+ background: #c9ccc4;
+ padding: 0.25em 1em 0.25em 0.5em;
+ border-bottom: 1px solid #a0a087;
+ margin: 0;
+}
+
+div#tocframe p.toc_uplink a:link,
+div#tocframe p.toc_uplink a:visited {
+ color: #1c1c1b;
+}
+
+div#tocframe p.toc_uplink a:hover {
+ color: #000;
+}
+
+div#tocframe h4 {
+ font-size: 1em;
+ line-height: 1.125;
+ font-weight: bold;
+ font-style: italic;
+ padding: 0.75em 0.5em 0 0.5em;
+ margin: 0;
+}
+
+#tocframe .contents {
+ background-color: transparent;
+ list-style-type: none;
+ padding: 0;
+ border: 0;
+ margin: 0;
+}
+
+#tocframe ul.toc {
+ padding: 0.25em 0.5em 1em 0.5em;
+ list-style-type: none;
+ margin: 0;
+}
+
+#tocframe ul.toc ul.toc {
+ padding: 0;
+ margin: 0;
+}
+
+#tocframe ul.toc li {
+ padding: 0;
+ margin: 0;
+}
+
+#tocframe ul.toc > li {
+ font-size: 1em;
+}
+
+#tocframe ul.toc li li {
+ padding-left: 1em;
+}
+
+li.toc_current {
+ font-weight: bold;
+ font-style: italic;
+}
+
+li.toc_current ul {
+ font-weight: normal;
+ font-style: normal;
+ background: transparent;
+}
+
+/***********************************************************/
+/* NAVIGATION */
+/***********************************************************/
+
+.nav_table {
+ width: 100%;
+ background: #c9ccc4;
+ font-size: 0.83em;
+ border-collapse: collapse;
+ padding: 0;
+ border: none;
+ margin: 0;
+}
+
+.nav_table a:link, .nav_table a:visited {
+ color: #1c1c1b;
+ text-decoration: none;
+}
+
+.nav_table a:hover {
+ color: #000;
+ text-decoration: underline;
+}
+
+.nav_table tr, .nav_table a {
+ padding: 0;
+ margin: 0;
+}
+
+.nav_table td {
+ padding: 0.25em;
+ margin: 0;
+}
+
+div.header {
+ background: #b1d281;
+ text-align: center;
+ padding: 0.5em;
+ border-bottom: 1px solid #7b925a;
+ margin: 0;
+ height: auto;
+}
+
+div.header h1 {
+ font-size: 2em;
+ padding: 0.25em;
+ margin: 0;
+}
+
+div.subheader {
+ background: #ddd;
+ padding: 0;
+ margin: 0;
+ text-align: center;
+}
+
+div.subheader p {
+ padding: 0.5em;
+ margin: 0;
+}
+
+table#navigation {
+ line-height: 1.5;
+ padding: 0;
+ margin: 1em auto;
+}
+
+table#navigation td {
+ padding: 0.5em 0.75em;
+}
+
+table#navigation ul {
+ padding-left: 0.5em;
+ margin: 0;
+}
+
+table .title {
+ font-weight: bold;
+}
+
+.footer {
+ background: #e5f5ce;
+ font-size: 0.8em;
+ padding: 0.2em 0;
+ border: solid #b1d281;
+ border-width: 0 0 5px 0;
+ margin: 0;
+}
+
+.footer a:link {
+ color: #0308fc;
+}
+
+.footer p {
+ padding: 0 1.25em;
+ margin: 0.4em 0;
+}
+
+table.menu {
+ margin: 0 0 1em;
+}
+
+/***********************************************************/
+/* OVERRIDES FOR PRINTING */
+/***********************************************************/
+
+@media print {
+ /* Hide the sidebar and make the main contents take up the full width */
+ div#main { position: static; overflow: visible; left: 0; }
+ div#tocframe { display: none; }
+ /* Also don't show the navigation toolbars between all sections */
+ .nav_table { display: none; }
+}
+
+/***********************************************************/
+/* FORMATTING of AJAX SEARCH BOX */
+/***********************************************************/
+
+div#search {
+ border: none;
+ border-bottom: 1pt solid #C5972C;
+ background: #E8E3AC;
+ padding-left: 3px;
+ padding-top: 2px;
+ padding-bottom: 1px;
+}
+div#search p, div#search form {
+ padding: 0;
+ margin: 0;
+}
+#search_results {
+ font-size: 0.75em;
+ padding: 0;
+ margin: 0;
+ display: none;
+}
+#search_results table {
+ width: 100%;
+}
+
+/***********************************************************/
+/* OTHER */
+/***********************************************************/
+
+.warning {
+ background: #eef;
+ text-align: left;
+ padding: 0;
+ border: 1px solid green;
+ /* Experimental rounded corners */
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ margin: 1em;
+}
+
+.advanced {
+ background: #eeffcc;
+ text-align: left;
+ padding: 0;
+ border: 1px solid green;
+ /* Experimental rounded corners */
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ margin: 0.5em 0.5em 2em 3em;
+}
diff --git a/macros/luatex/latex/lilyglyphs/documentation/the-feta-font-2-18-0.html b/macros/luatex/latex/lilyglyphs/documentation/the-feta-font-2-18-0.html
new file mode 100644
index 0000000000..4d3fbe2f4b
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/documentation/the-feta-font-2-18-0.html
@@ -0,0 +1,571 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- saved from url=(0075)http://www.lilypond.org/doc/v2.18/Documentation/notation/the-feta-font.html -->
+<html><!-- Copyright C 1999-2012 by the authors.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1
+or any later version published by the Free Software Foundation;
+with no Invariant Sections.
+A copy of the license is included in the section entitled "GNU
+Free Documentation License".
+
+ --><!-- Created on December 29, 2013 by texi2html 1.82
+texi2html was written by:
+ Lionel Cons <Lionel.Cons@cern.ch> (original author)
+ Karl Berry <karl@freefriends.org>
+ Olaf Bachmann <obachman@mathematik.uni-kl.de>
+ and many others.
+Maintained by: Many creative people.
+Send bugs and suggestions to <texi2html-bug@nongnu.org>
+--><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>LilyPond Notation Reference: A.8 The Feta font</title>
+
+<meta name="description" content="LilyPond Notation Reference: A.8 The Feta font">
+<meta name="keywords" content="LilyPond Notation Reference: A.8 The Feta font">
+<meta name="resource-type" content="document">
+<meta name="distribution" content="global">
+<meta name="generator" content="Bluefish 2.2.3" >
+
+<link href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index#index" rel="start" title="LilyPond — Notation Reference">
+<link href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index#lilypond-command-index" rel="index" title="D. LilyPond command index">
+<link href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" rel="contents" title="Table of Contents">
+<link href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" rel="help" title="About This Document">
+<link href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables#notation-manual-tables" rel="up" title="A. Notation manual tables">
+<link href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-index#lilypond-index" rel="next" title="E. LilyPond index">
+<link href="http://www.lilypond.org/doc/v2.18/Documentation/notation/list-of-colors#list-of-colors" rel="previous" title="A.7 List of colors">
+<link rel="stylesheet" type="text/css" title="Default style" href="./resources/lilypond-manuals.css">
+<!--[if lte IE 7]>
+<link href="../../Documentation/css/lilypond-ie-fixes.css" rel="stylesheet" type="text/css">
+<![endif]-->
+
+
+<link type="text/css" rel="stylesheet" href="chrome-extension://cpngackimfmofbokmjmljamhdncknpmg/style.css"><script type="text/javascript" charset="utf-8" src="chrome-extension://cpngackimfmofbokmjmljamhdncknpmg/js/page_context.js"></script><style type="text/css"></style></head>
+
+<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000" screen_capture_injected="true">
+
+
+<div id="main">
+<a name="The-Feta-font"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/list-of-colors" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; List of colors&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;Notation manual tables&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#clef-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Clef glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="the-feta-font"></a>
+<h2 class="appendixsec">A.8 The Feta font</h2>
+
+<a name="index-Feta-font"></a>
+<a name="index-Font_002c-Feta"></a>
+
+<p>The following symbols are available in the Emmentaler font and may be
+accessed directly using text markup with the name of the glyph
+as shown in the tables below,
+such as <code>g^\markup {\musicglyph #"scripts.segno" }</code> or
+<code>\markup {\musicglyph #"five"}</code>. For more information,
+see <a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/formatting-text">Formatting text</a>.
+</p>
+
+<table class="menu" border="0" cellspacing="0">
+<tbody><tr><td align="left" valign="top"><a href="#clef-glyphs" accesskey="1">Clef glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#time-signature-glyphs" accesskey="2">Time Signature glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#number-glyphs" accesskey="3">Number glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#accidental-glyphs" accesskey="4">Accidental glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#default-notehead-glyphs" accesskey="5">Default Notehead glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#special-notehead-glyphs" accesskey="6">Special Notehead glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#shape_002dnote-notehead-glyphs" accesskey="7">Shape-note Notehead glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#rest-glyphs" accesskey="8">Rest glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#flag-glyphs" accesskey="9">Flag glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#dot-glyphs">Dot glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#dynamic-glyphs">Dynamic glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#script-glyphs">Script glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#arrowhead-glyphs">Arrowhead glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#bracket_002dtip-glyphs">Bracket-tip glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#pedal-glyphs">Pedal glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#accordion-glyphs">Accordion glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#tie-glyphs">Tie glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#vaticana-glyphs">Vaticana glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#medicaea-glyphs">Medicaea glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#hufnagel-glyphs">Hufnagel glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#mensural-glyphs">Mensural glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#neomensural-glyphs">Neomensural glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#petrucci-glyphs">Petrucci glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#solesmes-glyphs">Solesmes glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+<tr><td align="left" valign="top"><a href="#kievan-notation-glyphs">Kievan Notation glyphs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
+</td></tr>
+</tbody></table>
+
+
+<hr size="6">
+<a name="Clef-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#the-feta-font" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; The Feta font&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#time-signature-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Time Signature glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="clef-glyphs"></a>
+<h3 class="unnumberedsubsec">Clef glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/0b/lily-76dbcd67.ly">
+ <img align="middle" border="0" src="./resources/lily-76dbcd67.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Time-Signature-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#clef-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Clef glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#number-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Number glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="time-signature-glyphs"></a>
+<h3 class="unnumberedsubsec">Time Signature glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/c6/lily-8b332c94.ly">
+ <img align="middle" border="0" src="./resources/lily-8b332c94.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Number-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#time-signature-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Time Signature glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#accidental-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Accidental glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="number-glyphs"></a>
+<h3 class="unnumberedsubsec">Number glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/80/lily-8d8bb8a3.ly">
+ <img align="middle" border="0" src="./resources/lily-8d8bb8a3.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Accidental-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#number-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Number glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#default-notehead-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Default Notehead glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="accidental-glyphs"></a>
+<h3 class="unnumberedsubsec">Accidental glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/1b/lily-5b13ce04.ly">
+ <img align="middle" border="0" src="./resources/lily-5b13ce04.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Default-Notehead-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#accidental-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Accidental glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#special-notehead-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Special Notehead glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="default-notehead-glyphs"></a>
+<h3 class="unnumberedsubsec">Default Notehead glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/38/lily-f4d0afc9.ly">
+ <img align="middle" border="0" src="./resources/lily-f4d0afc9.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Special-Notehead-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#default-notehead-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Default Notehead glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#shape_002dnote-notehead-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Shape-note Notehead glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="special-notehead-glyphs"></a>
+<h3 class="unnumberedsubsec">Special Notehead glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/9d/lily-088c978c.ly">
+ <img align="middle" border="0" src="./resources/lily-088c978c.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Shape_002dnote-Notehead-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#special-notehead-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Special Notehead glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#rest-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Rest glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="shape_002dnote-notehead-glyphs"></a>
+<h3 class="unnumberedsubsec">Shape-note Notehead glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/71/lily-5c91a201.ly">
+ <img align="middle" border="0" src="./resources/lily-5c91a201.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Rest-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#shape_002dnote-notehead-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Shape-note Notehead glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#flag-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Flag glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="rest-glyphs"></a>
+<h3 class="unnumberedsubsec">Rest glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/fa/lily-40869867.ly">
+ <img align="middle" border="0" src="./resources/lily-40869867.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Flag-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#rest-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Rest glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#dot-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Dot glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="flag-glyphs"></a>
+<h3 class="unnumberedsubsec">Flag glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/09/lily-2be182be.ly">
+ <img align="middle" border="0" src="./resources/lily-2be182be.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Dot-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#flag-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Flag glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#dynamic-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Dynamic glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="dot-glyphs"></a>
+<h3 class="unnumberedsubsec">Dot glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/81/lily-8155deab.ly">
+ <img align="middle" border="0" src="./resources/lily-8155deab.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Dynamic-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#dot-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Dot glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#script-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Script glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="dynamic-glyphs"></a>
+<h3 class="unnumberedsubsec">Dynamic glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/fb/lily-ae3fd948.ly">
+ <img align="middle" border="0" src="./resources/lily-ae3fd948.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Script-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#dynamic-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Dynamic glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#arrowhead-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Arrowhead glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="script-glyphs"></a>
+<h3 class="unnumberedsubsec">Script glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/e5/lily-20e8632d.ly">
+ <img align="middle" border="0" src="./resources/lily-20e8632d.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Arrowhead-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#script-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Script glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#bracket_002dtip-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Bracket-tip glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="arrowhead-glyphs"></a>
+<h3 class="unnumberedsubsec">Arrowhead glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/92/lily-8d82df0c.ly">
+ <img align="middle" border="0" src="./resources/lily-8d82df0c.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Bracket_002dtip-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#arrowhead-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Arrowhead glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#pedal-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Pedal glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="bracket_002dtip-glyphs"></a>
+<h3 class="unnumberedsubsec">Bracket-tip glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/a4/lily-7fd84ff8.ly">
+ <img align="middle" border="0" src="./resources/lily-7fd84ff8.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Pedal-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#bracket_002dtip-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Bracket-tip glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#accordion-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Accordion glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="pedal-glyphs"></a>
+<h3 class="unnumberedsubsec">Pedal glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/62/lily-a2bf82dd.ly">
+ <img align="middle" border="0" src="./resources/lily-a2bf82dd.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Accordion-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#pedal-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Pedal glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#tie-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Tie glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="accordion-glyphs"></a>
+<h3 class="unnumberedsubsec">Accordion glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/63/lily-3b47d3fe.ly">
+ <img align="middle" border="0" src="./resources/lily-3b47d3fe.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Tie-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#accordion-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Accordion glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#vaticana-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Vaticana glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="tie-glyphs"></a>
+<h3 class="unnumberedsubsec">Tie glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/f5/lily-dffaecd2.ly">
+ <img align="middle" border="0" src="./resources/lily-dffaecd2.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Vaticana-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#tie-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Tie glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#medicaea-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Medicaea glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="vaticana-glyphs"></a>
+<h3 class="unnumberedsubsec">Vaticana glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/08/lily-b69af986.ly">
+ <img align="middle" border="0" src="./resources/lily-b69af986.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Medicaea-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#vaticana-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Vaticana glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#hufnagel-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Hufnagel glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="medicaea-glyphs"></a>
+<h3 class="unnumberedsubsec">Medicaea glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/fd/lily-1981c3c7.ly">
+ <img align="middle" border="0" src="./resources/lily-1981c3c7.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Hufnagel-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#medicaea-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Medicaea glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#mensural-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Mensural glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="hufnagel-glyphs"></a>
+<h3 class="unnumberedsubsec">Hufnagel glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/4a/lily-d9988a2c.ly">
+ <img align="middle" border="0" src="./resources/lily-d9988a2c.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Mensural-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#hufnagel-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Hufnagel glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#neomensural-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Neomensural glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="mensural-glyphs"></a>
+<h3 class="unnumberedsubsec">Mensural glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/f4/lily-907bc72d.ly">
+ <img align="middle" border="0" src="./resources/lily-907bc72d.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Neomensural-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#mensural-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Mensural glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#petrucci-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Petrucci glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="neomensural-glyphs"></a>
+<h3 class="unnumberedsubsec">Neomensural glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/2d/lily-707477b7.ly">
+ <img align="middle" border="0" src="./resources/lily-707477b7.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Petrucci-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#neomensural-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Neomensural glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#solesmes-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Solesmes glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="petrucci-glyphs"></a>
+<h3 class="unnumberedsubsec">Petrucci glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/07/lily-3f4afecc.ly">
+ <img align="middle" border="0" src="./resources/lily-3f4afecc.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+
+<hr size="6">
+<a name="Solesmes-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#petrucci-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Petrucci glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="#kievan-notation-glyphs" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Kievan Notation glyphs &gt; </a>]</td></tr></tbody></table>
+<a name="solesmes-glyphs"></a>
+<h3 class="unnumberedsubsec">Solesmes glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/5a/lily-b3dc0958.ly">
+ <img align="middle" border="0" src="./resources/lily-b3dc0958.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+<hr size="6">
+<a name="Kievan-Notation-glyphs"></a>
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#solesmes-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Solesmes glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/note-head-styles" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Note head styles &gt; </a>]</td></tr></tbody></table>
+<a name="kievan-notation-glyphs"></a>
+<h3 class="unnumberedsubsec">Kievan Notation glyphs</h3>
+
+<blockquote><p>
+ <a href="http://www.lilypond.org/doc/v2.18/Documentation/4d/lily-2abb8a04.ly">
+ <img align="middle" border="0" src="./resources/lily-2abb8a04.png" alt="[image of music]">
+ </a>
+</p>
+</blockquote>
+
+
+
+<hr size="6">
+<table class="nav_table">
+<tbody><tr><td valign="middle" align="left" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/notation-manual-tables" title="Beginning of this chapter or previous chapter"> &lt;&lt; Notation manual tables&nbsp;</a>]</td><td valign="middle" align="center" colspan="3">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index" title="Cover (top) of document" rel="start">Top</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_toc#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/lilypond-command-index" title="Index" rel="index">Index</a>][<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/index_abt#SEC_About" title="About (help)" rel="help"> ? </a>]</td><td valign="middle" align="right" colspan="1">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/cheat-sheet" title="Next chapter">&nbsp;Cheat sheet &gt;&gt; </a>]</td></tr><tr><td valign="middle" align="left" colspan="2">[<a href="#solesmes-glyphs" title="Previous section in reading order" accesskey="p" rel="previous"> &lt; Solesmes glyphs&nbsp;</a>]</td><td valign="middle" align="center" colspan="1">[<a href="#the-feta-font" title="Up section" accesskey="u" rel="up">&nbsp; Up :&nbsp;The Feta font&nbsp;</a>]</td><td valign="middle" align="right" colspan="2">[<a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/note-head-styles" title="Next section in reading order" accesskey="n" rel="next">&nbsp;Note head styles &gt; </a>]</td></tr></tbody></table>
+<!-- footer_tag -->
+<div class="footer">
+<!-- This footer was autogenerated by /home/gub/gub/target/linux-x86/build/lilypond-git.sv.gnu.org--lilypond.git-stable-2.18/scripts/build/out/www_post -->
+<p class="footer_version">
+This page is for LilyPond-2.18.0 (stable-branch).
+</p>
+<p class="footer_report">
+We welcome your aid; please <a href="http://lilypond.org/help-us.html">help us</a> by reporting errors to our <a href="http://post.gmane.org/post.php?group=gmane.comp.gnu.lilypond.bugs">bug list</a>.
+</p>
+</div>
+
+
+<p id="languages">
+<!-- These links were autogenerated by /home/gub/gub/target/linux-x86/build/lilypond-git.sv.gnu.org--lilypond.git-stable-2.18/scripts/build/out/www_post -->
+ Other languages: <a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/the-feta-font.de.html">deutsch</a>, <a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/the-feta-font.es.html">español</a>, <a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/the-feta-font.fr.html">français</a>, <a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/the-feta-font.it.html">italiano</a>, <a href="http://www.lilypond.org/doc/v2.18/Documentation/notation/the-feta-font.ja.html">日本語</a>.
+ <br>
+ About <a href="http://www.lilypond.org/website/misc/browser-language">automatic language selection</a>.
+</p>
+
+<!-- FOOTER -->
+
+<!-- end div#main here -->
+</div>
+
+
+
+</body></html> \ No newline at end of file
diff --git a/macros/luatex/latex/lilyglyphs/fonts/FONTLOG b/macros/luatex/latex/lilyglyphs/fonts/FONTLOG
new file mode 100644
index 0000000000..1c423c35df
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/fonts/FONTLOG
@@ -0,0 +1,23 @@
+This is the FONTLOG for the Emmentaler OpenType fonts
+distributed together with the lilyglyphs LaTeX package.
+lilyglyphs is maintained by Urs Liska (ul@openlilylib.org).
+
+Emmentaler is the music font of the LilyPond engraving software
+(http://www.lilypond.org) and contains all musical symbols that
+LilyPond doesn't draw itself.
+lilyglyphs is a package that makes LilyPond's notational elements
+available as character commands in LuaLaTeX/XeLaTeX documents.
+
+The font files distributed with lilyglyphs are the ones shipped with
+LilyPond 2.18.0 without any modifications.
+
+The fonts have been created by "The LilyPond authors" and are licensed
+under the SIL Open Font License, Version 1.1. See the file
+LICENSE.OFL in the same directory for details.
+More information on LilyPond and the Emmentaler fonts can be obtained
+at http://www.lilypond.org.
+
+The Metafont sources for the fonts can be obtained at LilyPond's
+Git repository at http://savannah.gnu.org/git/?group=lilypond,
+in particular they are in the 'mf' directory of the source tree at
+http://git.savannah.gnu.org/cgit/lilypond.git/tree/
diff --git a/macros/luatex/latex/lilyglyphs/fonts/LICENSE.OFL b/macros/luatex/latex/lilyglyphs/fonts/LICENSE.OFL
new file mode 100644
index 0000000000..41e80d6039
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/fonts/LICENSE.OFL
@@ -0,0 +1,95 @@
+
+Copyright (c) 1996--2013, The LilyPond authors (lilypond.org)
+with Reserved Font Name "Emmentaler" and "Feta".
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+SIL OPEN FONT LICENSE
+
+Version 1.1 - 26 February 2007
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/macros/luatex/latex/lilyglyphs/fonts/emmentaler-11.otf b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-11.otf
new file mode 100644
index 0000000000..b749fe4b68
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-11.otf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/fonts/emmentaler-13.otf b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-13.otf
new file mode 100644
index 0000000000..da5a686cbf
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-13.otf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/fonts/emmentaler-14.otf b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-14.otf
new file mode 100644
index 0000000000..c8bf9e71d8
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-14.otf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/fonts/emmentaler-16.otf b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-16.otf
new file mode 100644
index 0000000000..1ed1212fa0
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-16.otf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/fonts/emmentaler-18.otf b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-18.otf
new file mode 100644
index 0000000000..bad36f2f5c
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-18.otf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/fonts/emmentaler-20.otf b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-20.otf
new file mode 100644
index 0000000000..07ce75c902
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-20.otf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/fonts/emmentaler-23.otf b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-23.otf
new file mode 100644
index 0000000000..d7597ddb13
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-23.otf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/fonts/emmentaler-26.otf b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-26.otf
new file mode 100644
index 0000000000..df5c42ea81
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-26.otf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/fonts/emmentaler-brace.otf b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-brace.otf
new file mode 100644
index 0000000000..c850072863
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/fonts/emmentaler-brace.otf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/license/COPYING.LPPL b/macros/luatex/latex/lilyglyphs/license/COPYING.LPPL
new file mode 100644
index 0000000000..f24b18cd79
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/license/COPYING.LPPL
@@ -0,0 +1,419 @@
+'lilyglyphs' is free software and can be distributed and modified
+under the LaTeX Project Public License Version 1.3c or (at your option)
+any later version.
+
+The LaTeX Project Public License
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+LPPL Version 1.3c 2008-05-04
+
+Copyright 1999 2002-2008 LaTeX3 Project
+ Everyone is allowed to distribute verbatim copies of this
+ license document, but modification of it is not allowed.
+
+
+PREAMBLE
+========
+
+The LaTeX Project Public License (LPPL) is the primary license under
+which the LaTeX kernel and the base LaTeX packages are distributed.
+
+You may use this license for any work of which you hold the copyright
+and which you wish to distribute. This license may be particularly
+suitable if your work is TeX-related (such as a LaTeX package), but
+it is written in such a way that you can use it even if your work is
+unrelated to TeX.
+
+The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE',
+below, gives instructions, examples, and recommendations for authors
+who are considering distributing their works under this license.
+
+This license gives conditions under which a work may be distributed
+and modified, as well as conditions under which modified versions of
+that work may be distributed.
+
+We, the LaTeX3 Project, believe that the conditions below give you
+the freedom to make and distribute modified versions of your work
+that conform with whatever technical specifications you wish while
+maintaining the availability, integrity, and reliability of
+that work. If you do not see how to achieve your goal while
+meeting these conditions, then read the document `cfgguide.tex'
+and `modguide.tex' in the base LaTeX distribution for suggestions.
+
+
+DEFINITIONS
+===========
+
+In this license document the following terms are used:
+
+ `Work'
+ Any work being distributed under this License.
+
+ `Derived Work'
+ Any work that under any applicable law is derived from the Work.
+
+ `Modification'
+ Any procedure that produces a Derived Work under any applicable
+ law -- for example, the production of a file containing an
+ original file associated with the Work or a significant portion of
+ such a file, either verbatim or with modifications and/or
+ translated into another language.
+
+ `Modify'
+ To apply any procedure that produces a Derived Work under any
+ applicable law.
+
+ `Distribution'
+ Making copies of the Work available from one person to another, in
+ whole or in part. Distribution includes (but is not limited to)
+ making any electronic components of the Work accessible by
+ file transfer protocols such as FTP or HTTP or by shared file
+ systems such as Sun's Network File System (NFS).
+
+ `Compiled Work'
+ A version of the Work that has been processed into a form where it
+ is directly usable on a computer system. This processing may
+ include using installation facilities provided by the Work,
+ transformations of the Work, copying of components of the Work, or
+ other activities. Note that modification of any installation
+ facilities provided by the Work constitutes modification of the Work.
+
+ `Current Maintainer'
+ A person or persons nominated as such within the Work. If there is
+ no such explicit nomination then it is the `Copyright Holder' under
+ any applicable law.
+
+ `Base Interpreter'
+ A program or process that is normally needed for running or
+ interpreting a part or the whole of the Work.
+
+ A Base Interpreter may depend on external components but these
+ are not considered part of the Base Interpreter provided that each
+ external component clearly identifies itself whenever it is used
+ interactively. Unless explicitly specified when applying the
+ license to the Work, the only applicable Base Interpreter is a
+ `LaTeX-Format' or in the case of files belonging to the
+ `LaTeX-format' a program implementing the `TeX language'.
+
+
+
+CONDITIONS ON DISTRIBUTION AND MODIFICATION
+===========================================
+
+1. Activities other than distribution and/or modification of the Work
+are not covered by this license; they are outside its scope. In
+particular, the act of running the Work is not restricted and no
+requirements are made concerning any offers of support for the Work.
+
+2. You may distribute a complete, unmodified copy of the Work as you
+received it. Distribution of only part of the Work is considered
+modification of the Work, and no right to distribute such a Derived
+Work may be assumed under the terms of this clause.
+
+3. You may distribute a Compiled Work that has been generated from a
+complete, unmodified copy of the Work as distributed under Clause 2
+above, as long as that Compiled Work is distributed in such a way that
+the recipients may install the Compiled Work on their system exactly
+as it would have been installed if they generated a Compiled Work
+directly from the Work.
+
+4. If you are the Current Maintainer of the Work, you may, without
+restriction, modify the Work, thus creating a Derived Work. You may
+also distribute the Derived Work without restriction, including
+Compiled Works generated from the Derived Work. Derived Works
+distributed in this manner by the Current Maintainer are considered to
+be updated versions of the Work.
+
+5. If you are not the Current Maintainer of the Work, you may modify
+your copy of the Work, thus creating a Derived Work based on the Work,
+and compile this Derived Work, thus creating a Compiled Work based on
+the Derived Work.
+
+6. If you are not the Current Maintainer of the Work, you may
+distribute a Derived Work provided the following conditions are met
+for every component of the Work unless that component clearly states
+in the copyright notice that it is exempt from that condition. Only
+the Current Maintainer is allowed to add such statements of exemption
+to a component of the Work.
+
+ a. If a component of this Derived Work can be a direct replacement
+ for a component of the Work when that component is used with the
+ Base Interpreter, then, wherever this component of the Work
+ identifies itself to the user when used interactively with that
+ Base Interpreter, the replacement component of this Derived Work
+ clearly and unambiguously identifies itself as a modified version
+ of this component to the user when used interactively with that
+ Base Interpreter.
+
+ b. Every component of the Derived Work contains prominent notices
+ detailing the nature of the changes to that component, or a
+ prominent reference to another file that is distributed as part
+ of the Derived Work and that contains a complete and accurate log
+ of the changes.
+
+ c. No information in the Derived Work implies that any persons,
+ including (but not limited to) the authors of the original version
+ of the Work, provide any support, including (but not limited to)
+ the reporting and handling of errors, to recipients of the
+ Derived Work unless those persons have stated explicitly that
+ they do provide such support for the Derived Work.
+
+ d. You distribute at least one of the following with the Derived Work:
+
+ 1. A complete, unmodified copy of the Work;
+ if your distribution of a modified component is made by
+ offering access to copy the modified component from a
+ designated place, then offering equivalent access to copy
+ the Work from the same or some similar place meets this
+ condition, even though third parties are not compelled to
+ copy the Work along with the modified component;
+
+ 2. Information that is sufficient to obtain a complete,
+ unmodified copy of the Work.
+
+7. If you are not the Current Maintainer of the Work, you may
+distribute a Compiled Work generated from a Derived Work, as long as
+the Derived Work is distributed to all recipients of the Compiled
+Work, and as long as the conditions of Clause 6, above, are met with
+regard to the Derived Work.
+
+8. The conditions above are not intended to prohibit, and hence do not
+apply to, the modification, by any method, of any component so that it
+becomes identical to an updated version of that component of the Work as
+it is distributed by the Current Maintainer under Clause 4, above.
+
+9. Distribution of the Work or any Derived Work in an alternative
+format, where the Work or that Derived Work (in whole or in part) is
+then produced by applying some process to that format, does not relax or
+nullify any sections of this license as they pertain to the results of
+applying that process.
+
+10. a. A Derived Work may be distributed under a different license
+ provided that license itself honors the conditions listed in
+ Clause 6 above, in regard to the Work, though it does not have
+ to honor the rest of the conditions in this license.
+
+ b. If a Derived Work is distributed under a different license, that
+ Derived Work must provide sufficient documentation as part of
+ itself to allow each recipient of that Derived Work to honor the
+ restrictions in Clause 6 above, concerning changes from the Work.
+
+11. This license places no restrictions on works that are unrelated to
+the Work, nor does this license place any restrictions on aggregating
+such works with the Work by any means.
+
+12. Nothing in this license is intended to, or may be used to, prevent
+complete compliance by all parties with all applicable laws.
+
+
+NO WARRANTY
+===========
+
+There is no warranty for the Work. Except when otherwise stated in
+writing, the Copyright Holder provides the Work `as is', without
+warranty of any kind, either expressed or implied, including, but not
+limited to, the implied warranties of merchantability and fitness for a
+particular purpose. The entire risk as to the quality and performance
+of the Work is with you. Should the Work prove defective, you assume
+the cost of all necessary servicing, repair, or correction.
+
+In no event unless required by applicable law or agreed to in writing
+will The Copyright Holder, or any author named in the components of the
+Work, or any other party who may distribute and/or modify the Work as
+permitted above, be liable to you for damages, including any general,
+special, incidental or consequential damages arising out of any use of
+the Work or out of inability to use the Work (including, but not limited
+to, loss of data, data being rendered inaccurate, or losses sustained by
+anyone as a result of any failure of the Work to operate with any other
+programs), even if the Copyright Holder or said author or said other
+party has been advised of the possibility of such damages.
+
+
+MAINTENANCE OF THE WORK
+=======================
+
+The Work has the status `author-maintained' if the Copyright Holder
+explicitly and prominently states near the primary copyright notice in
+the Work that the Work can only be maintained by the Copyright Holder
+or simply that it is `author-maintained'.
+
+The Work has the status `maintained' if there is a Current Maintainer
+who has indicated in the Work that they are willing to receive error
+reports for the Work (for example, by supplying a valid e-mail
+address). It is not required for the Current Maintainer to acknowledge
+or act upon these error reports.
+
+The Work changes from status `maintained' to `unmaintained' if there
+is no Current Maintainer, or the person stated to be Current
+Maintainer of the work cannot be reached through the indicated means
+of communication for a period of six months, and there are no other
+significant signs of active maintenance.
+
+You can become the Current Maintainer of the Work by agreement with
+any existing Current Maintainer to take over this role.
+
+If the Work is unmaintained, you can become the Current Maintainer of
+the Work through the following steps:
+
+ 1. Make a reasonable attempt to trace the Current Maintainer (and
+ the Copyright Holder, if the two differ) through the means of
+ an Internet or similar search.
+
+ 2. If this search is successful, then enquire whether the Work
+ is still maintained.
+
+ a. If it is being maintained, then ask the Current Maintainer
+ to update their communication data within one month.
+
+ b. If the search is unsuccessful or no action to resume active
+ maintenance is taken by the Current Maintainer, then announce
+ within the pertinent community your intention to take over
+ maintenance. (If the Work is a LaTeX work, this could be
+ done, for example, by posting to comp.text.tex.)
+
+ 3a. If the Current Maintainer is reachable and agrees to pass
+ maintenance of the Work to you, then this takes effect
+ immediately upon announcement.
+
+ b. If the Current Maintainer is not reachable and the Copyright
+ Holder agrees that maintenance of the Work be passed to you,
+ then this takes effect immediately upon announcement.
+
+ 4. If you make an `intention announcement' as described in 2b. above
+ and after three months your intention is challenged neither by
+ the Current Maintainer nor by the Copyright Holder nor by other
+ people, then you may arrange for the Work to be changed so as
+ to name you as the (new) Current Maintainer.
+
+ 5. If the previously unreachable Current Maintainer becomes
+ reachable once more within three months of a change completed
+ under the terms of 3b) or 4), then that Current Maintainer must
+ become or remain the Current Maintainer upon request provided
+ they then update their communication data within one month.
+
+A change in the Current Maintainer does not, of itself, alter the fact
+that the Work is distributed under the LPPL license.
+
+If you become the Current Maintainer of the Work, you should
+immediately provide, within the Work, a prominent and unambiguous
+statement of your status as Current Maintainer. You should also
+announce your new status to the same pertinent community as
+in 2b) above.
+
+
+WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE
+======================================================
+
+This section contains important instructions, examples, and
+recommendations for authors who are considering distributing their
+works under this license. These authors are addressed as `you' in
+this section.
+
+Choosing This License or Another License
+----------------------------------------
+
+If for any part of your work you want or need to use *distribution*
+conditions that differ significantly from those in this license, then
+do not refer to this license anywhere in your work but, instead,
+distribute your work under a different license. You may use the text
+of this license as a model for your own license, but your license
+should not refer to the LPPL or otherwise give the impression that
+your work is distributed under the LPPL.
+
+The document `modguide.tex' in the base LaTeX distribution explains
+the motivation behind the conditions of this license. It explains,
+for example, why distributing LaTeX under the GNU General Public
+License (GPL) was considered inappropriate. Even if your work is
+unrelated to LaTeX, the discussion in `modguide.tex' may still be
+relevant, and authors intending to distribute their works under any
+license are encouraged to read it.
+
+A Recommendation on Modification Without Distribution
+-----------------------------------------------------
+
+It is wise never to modify a component of the Work, even for your own
+personal use, without also meeting the above conditions for
+distributing the modified component. While you might intend that such
+modifications will never be distributed, often this will happen by
+accident -- you may forget that you have modified that component; or
+it may not occur to you when allowing others to access the modified
+version that you are thus distributing it and violating the conditions
+of this license in ways that could have legal implications and, worse,
+cause problems for the community. It is therefore usually in your
+best interest to keep your copy of the Work identical with the public
+one. Many works provide ways to control the behavior of that work
+without altering any of its licensed components.
+
+How to Use This License
+-----------------------
+
+To use this license, place in each of the components of your work both
+an explicit copyright notice including your name and the year the work
+was authored and/or last substantially modified. Include also a
+statement that the distribution and/or modification of that
+component is constrained by the conditions in this license.
+
+Here is an example of such a notice and statement:
+
+ %% pig.dtx
+ %% Copyright 2005 M. Y. Name
+ %
+ % This work may be distributed and/or modified under the
+ % conditions of the LaTeX Project Public License, either version 1.3
+ % of this license or (at your option) any later version.
+ % The latest version of this license is in
+ % http://www.latex-project.org/lppl.txt
+ % and version 1.3 or later is part of all distributions of LaTeX
+ % version 2005/12/01 or later.
+ %
+ % This work has the LPPL maintenance status `maintained'.
+ %
+ % The Current Maintainer of this work is M. Y. Name.
+ %
+ % This work consists of the files pig.dtx and pig.ins
+ % and the derived file pig.sty.
+
+Given such a notice and statement in a file, the conditions
+given in this license document would apply, with the `Work' referring
+to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being
+generated from `pig.dtx' using `pig.ins'), the `Base Interpreter'
+referring to any `LaTeX-Format', and both `Copyright Holder' and
+`Current Maintainer' referring to the person `M. Y. Name'.
+
+If you do not want the Maintenance section of LPPL to apply to your
+Work, change `maintained' above into `author-maintained'.
+However, we recommend that you use `maintained', as the Maintenance
+section was added in order to ensure that your Work remains useful to
+the community even when you can no longer maintain and support it
+yourself.
+
+Derived Works That Are Not Replacements
+---------------------------------------
+
+Several clauses of the LPPL specify means to provide reliability and
+stability for the user community. They therefore concern themselves
+with the case that a Derived Work is intended to be used as a
+(compatible or incompatible) replacement of the original Work. If
+this is not the case (e.g., if a few lines of code are reused for a
+completely different task), then clauses 6b and 6d shall not apply.
+
+
+Important Recommendations
+-------------------------
+
+ Defining What Constitutes the Work
+
+ The LPPL requires that distributions of the Work contain all the
+ files of the Work. It is therefore important that you provide a
+ way for the licensee to determine which files constitute the Work.
+ This could, for example, be achieved by explicitly listing all the
+ files of the Work near the copyright notice of each file or by
+ using a line such as:
+
+ % This work consists of all files listed in manifest.txt.
+
+ in that place. In the absence of an unequivocal list it might be
+ impossible for the licensee to determine what is considered by you
+ to comprise the Work and, in such a case, the licensee would be
+ entitled to make reasonable conjectures as to which files comprise
+ the Work.
diff --git a/macros/luatex/latex/lilyglyphs/license/MANIFEST b/macros/luatex/latex/lilyglyphs/license/MANIFEST
new file mode 100644
index 0000000000..8b9030f086
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/license/MANIFEST
@@ -0,0 +1,180 @@
+MANIFEST for lilyglpyhs 0.2.3
+Generated on 2014-03-12
+
+The following files are part of this work:
+
+/CHANGES.md
+/INSTALL
+/README
+/deploy/documentation/lilyglyphs-example-400.png
+/deploy/documentation/lilyglyphs-example-600.png
+/deploy/documentation/lilyglyphs-example-de.pdf
+/deploy/documentation/lilyglyphs-example-de.tex
+/deploy/documentation/lilyglyphs-example.pdf
+/deploy/documentation/lilyglyphs-example.png
+/deploy/documentation/lilyglyphs-example.tex
+/deploy/documentation/lilyglyphs.pdf
+/deploy/documentation/lilyglyphs.tex
+/deploy/documentation/lilyglyphs_logo/lilyglyphs_logo.pdf
+/deploy/documentation/lilyglyphs_logo/lilyglyphs_logo.png
+/deploy/documentation/lilyglyphs_logo/lilyglyphs_logo.tex
+/deploy/documentation/the-feta-font-2-18-0.html
+/documentation/resources/lily-088c978c.png
+/documentation/resources/lily-1981c3c7.png
+/documentation/resources/lily-20e8632d.png
+/documentation/resources/lily-2abb8a04.png
+/documentation/resources/lily-2be182be.png
+/documentation/resources/lily-3b47d3fe.png
+/documentation/resources/lily-3f4afecc.png
+/documentation/resources/lily-40869867.png
+/documentation/resources/lily-5b13ce04.png
+/documentation/resources/lily-5c91a201.png
+/documentation/resources/lily-707477b7.png
+/documentation/resources/lily-76dbcd67.png
+/documentation/resources/lily-7fd84ff8.png
+/documentation/resources/lily-8155deab.png
+/documentation/resources/lily-8b332c94.png
+/documentation/resources/lily-8d82df0c.png
+/documentation/resources/lily-8d8bb8a3.png
+/documentation/resources/lily-907bc72d.png
+/documentation/resources/lily-a2bf82dd.png
+/documentation/resources/lily-ae3fd948.png
+/documentation/resources/lily-b3dc0958.png
+/documentation/resources/lily-b69af986.png
+/documentation/resources/lily-d9988a2c.png
+/documentation/resources/lily-dffaecd2.png
+/documentation/resources/lily-f4d0afc9.png
+/documentation/resources/lilyglyphsManualFonts.sty
+/documentation/resources/lilyglyphsStyle.sty
+/documentation/resources/lilypond-manuals.css
+/documentation/resources/lilypond-manuals.css~
+/fonts/FONTLOG
+/fonts/FONTLOG~
+/fonts/LICENSE.OFL
+/fonts/emmentaler-11.otf
+/fonts/emmentaler-13.otf
+/fonts/emmentaler-14.otf
+/fonts/emmentaler-16.otf
+/fonts/emmentaler-18.otf
+/fonts/emmentaler-20.otf
+/fonts/emmentaler-23.otf
+/fonts/emmentaler-26.otf
+/fonts/emmentaler-brace.otf
+/license/COPYING.LPPL
+/license/license-preamble.inp
+/scripts/README-scripts
+/scripts/deploy.py
+/scripts/lily-glyph-commands.py
+/scripts/lily-image-commands.py
+/scripts/lily-rebuild-pdfs.py
+/scripts/lilyglyphs_common.py
+/scripts/lilyglyphs_common.pyc
+/source/fonts
+/source/fonts/README-emmentaler
+/source/fonts/README-emmentaler~
+/source/fonts/emmentaler-2-18-0.zip
+/source/glyphimages/definitions/_template.ly
+/source/glyphimages/definitions/beamednotes.ly
+/source/glyphimages/definitions/dynamicsigns.ly
+/source/glyphimages/definitions/fancyexamples.ly
+/source/glyphimages/definitions/score.ily
+/source/glyphimages/definitions/singlenotes.ly
+/source/glyphimages/definitions/singlenotes.pdf
+/source/glyphimages/generated_src/lily-crescHairpin.ly
+/source/glyphimages/generated_src/lily-crotchet.ly
+/source/glyphimages/generated_src/lily-crotchetDotted.ly
+/source/glyphimages/generated_src/lily-crotchetDottedDouble.ly
+/source/glyphimages/generated_src/lily-crotchetDottedDoubleDown.ly
+/source/glyphimages/generated_src/lily-crotchetDottedDown.ly
+/source/glyphimages/generated_src/lily-crotchetDown.ly
+/source/glyphimages/generated_src/lily-decrescHairpin.ly
+/source/glyphimages/generated_src/lily-demisemiquaver.ly
+/source/glyphimages/generated_src/lily-demisemiquaverDotted.ly
+/source/glyphimages/generated_src/lily-demisemiquaverDottedDouble.ly
+/source/glyphimages/generated_src/lily-demisemiquaverDottedDoubleDown.ly
+/source/glyphimages/generated_src/lily-demisemiquaverDottedDown.ly
+/source/glyphimages/generated_src/lily-demisemiquaverDown.ly
+/source/glyphimages/generated_src/lily-fancyExample.ly
+/source/glyphimages/generated_src/lily-halfNote.ly
+/source/glyphimages/generated_src/lily-halfNoteDotted.ly
+/source/glyphimages/generated_src/lily-halfNoteDottedDouble.ly
+/source/glyphimages/generated_src/lily-halfNoteDottedDoubleDown.ly
+/source/glyphimages/generated_src/lily-halfNoteDottedDown.ly
+/source/glyphimages/generated_src/lily-halfNoteDown.ly
+/source/glyphimages/generated_src/lily-quaver.ly
+/source/glyphimages/generated_src/lily-quaverDotted.ly
+/source/glyphimages/generated_src/lily-quaverDottedDouble.ly
+/source/glyphimages/generated_src/lily-quaverDottedDoubleDdown.ly
+/source/glyphimages/generated_src/lily-quaverDottedDoubleDown.ly
+/source/glyphimages/generated_src/lily-quaverDottedDown.ly
+/source/glyphimages/generated_src/lily-quaverDown.ly
+/source/glyphimages/generated_src/lily-semiquaver.ly
+/source/glyphimages/generated_src/lily-semiquaverDotted.ly
+/source/glyphimages/generated_src/lily-semiquaverDottedDouble.ly
+/source/glyphimages/generated_src/lily-semiquaverDottedDoubleDown.ly
+/source/glyphimages/generated_src/lily-semiquaverDottedDown.ly
+/source/glyphimages/generated_src/lily-semiquaverDown.ly
+/source/glyphimages/generated_src/lily-threeBeamedQuavers.ly
+/source/glyphimages/generated_src/lily-threeBeamedQuaversI.ly
+/source/glyphimages/generated_src/lily-threeBeamedQuaversII.ly
+/source/glyphimages/generated_src/lily-threeBeamedQuaversIII.ly
+/source/glyphimages/generated_src/lily-twoBeamedQuavers.ly
+/tex/commands/README-commands
+/tex/commands/accidentals.inp
+/tex/commands/accordion.inp
+/tex/commands/beamednotes.inp
+/tex/commands/clefs.inp
+/tex/commands/dynamics.inp
+/tex/commands/fancyexamples.inp
+/tex/commands/noteheads.inp
+/tex/commands/numbers.inp
+/tex/commands/rests.inp
+/tex/commands/scripts.inp
+/tex/commands/singlenotes.inp
+/tex/commands/timesignatures.inp
+/tex/core/README-core
+/tex/core/dotted.inp
+/tex/core/genericAccess.inp
+/tex/core/keyval.inp
+/tex/core/opticals.inp
+/tex/lilyglyphs.sty
+/tex/pdfs/.gitignore
+/tex/pdfs/lily-crescHairpin.pdf
+/tex/pdfs/lily-crotchet.pdf
+/tex/pdfs/lily-crotchetDotted.pdf
+/tex/pdfs/lily-crotchetDottedDouble.pdf
+/tex/pdfs/lily-crotchetDottedDoubleDown.pdf
+/tex/pdfs/lily-crotchetDottedDown.pdf
+/tex/pdfs/lily-crotchetDown.pdf
+/tex/pdfs/lily-decrescHairpin.pdf
+/tex/pdfs/lily-demisemiquaver.pdf
+/tex/pdfs/lily-demisemiquaverDotted.pdf
+/tex/pdfs/lily-demisemiquaverDottedDouble.pdf
+/tex/pdfs/lily-demisemiquaverDottedDoubleDown.pdf
+/tex/pdfs/lily-demisemiquaverDottedDown.pdf
+/tex/pdfs/lily-demisemiquaverDown.pdf
+/tex/pdfs/lily-fancyExample.pdf
+/tex/pdfs/lily-halfNote.pdf
+/tex/pdfs/lily-halfNoteDotted.pdf
+/tex/pdfs/lily-halfNoteDottedDouble.pdf
+/tex/pdfs/lily-halfNoteDottedDoubleDown.pdf
+/tex/pdfs/lily-halfNoteDottedDown.pdf
+/tex/pdfs/lily-halfNoteDown.pdf
+/tex/pdfs/lily-quaver.pdf
+/tex/pdfs/lily-quaverDotted.pdf
+/tex/pdfs/lily-quaverDottedDouble.pdf
+/tex/pdfs/lily-quaverDottedDoubleDdown.pdf
+/tex/pdfs/lily-quaverDottedDoubleDown.pdf
+/tex/pdfs/lily-quaverDottedDown.pdf
+/tex/pdfs/lily-quaverDown.pdf
+/tex/pdfs/lily-semiquaver.pdf
+/tex/pdfs/lily-semiquaverDotted.pdf
+/tex/pdfs/lily-semiquaverDottedDouble.pdf
+/tex/pdfs/lily-semiquaverDottedDoubleDown.pdf
+/tex/pdfs/lily-semiquaverDottedDown.pdf
+/tex/pdfs/lily-semiquaverDown.pdf
+/tex/pdfs/lily-threeBeamedQuavers.pdf
+/tex/pdfs/lily-threeBeamedQuaversI.pdf
+/tex/pdfs/lily-threeBeamedQuaversII.pdf
+/tex/pdfs/lily-threeBeamedQuaversIII.pdf
+/tex/pdfs/lily-twoBeamedQuavers.pdf
diff --git a/macros/luatex/latex/lilyglyphs/license/license-preamble.inp b/macros/luatex/latex/lilyglyphs/license/license-preamble.inp
new file mode 100644
index 0000000000..9e3b129dba
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/license/license-preamble.inp
@@ -0,0 +1,31 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/macros/luatex/latex/lilyglyphs/scripts/README-scripts b/macros/luatex/latex/lilyglyphs/scripts/README-scripts
new file mode 100644
index 0000000000..a05dd12651
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/scripts/README-scripts
@@ -0,0 +1,3 @@
+This folder contains utility scripts to extend
+and maintain the lilyglyphs package.
+For usage information refer to the manual.
diff --git a/macros/luatex/latex/lilyglyphs/scripts/lily-glyph-commands.py b/macros/luatex/latex/lilyglyphs/scripts/lily-glyph-commands.py
new file mode 100755
index 0000000000..691652ece6
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/scripts/lily-glyph-commands.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+
+# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+# %
+# This file is part of the 'lilyglyphs' LaTeX package. %
+# ========== %
+# %
+# https://github.com/openlilylib/lilyglyphs %
+# http://www.openlilylib.org/lilyglyphs %
+# %
+# Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+# %
+# 'lilyglyphs' is free software: you can redistribute it and/or modify %
+# it under the terms of the LaTeX Project Public License, either %
+# version 1.3 of this license or (at your option) any later version. %
+# You may find the latest version of this license at %
+# http://www.latex-project.org/lppl.txt %
+# more information on %
+# http://latex-project.org/lppl/ %
+# and version 1.3 or later is part of all distributions of LaTeX %
+# version 2005/12/01 or later. %
+# %
+# This work has the LPPL maintenance status 'maintained'. %
+# The Current Maintainer of this work is Urs Liska (see above). %
+# %
+# This work consists of the files listed in the file 'manifest.txt' %
+# which can be found in the 'license' directory. %
+# %
+# This program is distributed in the hope that it will be useful, %
+# but WITHOUT ANY WARRANTY; without even the implied warranty of %
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+# %
+# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+# ########################################################################
+# #
+# genGlyphCommands.py #
+# #
+# generate commands based on Emmentaler glyphs #
+# #
+# ########################################################################
+
+import os, sys, argparse, lilyglyphs_common as lg
+
+def main(input_file):
+ """Do the main work of the script"""
+
+ in_dir, in_file = os.path.split(input_file)
+ os.chdir(in_dir)
+
+ # load and parse input file
+ lg.read_input_file(in_file)
+ read_entries()
+
+ # generate LaTeX commands and save them to output file
+ # (will be a .tex sibling of the input file)
+ lg.generate_latex_commands()
+ out_file, out_ext = os.path.splitext(input_file)
+ lg.write_latex_file(os.path.join(os.getcwd(), out_file + '.tex'))
+
+def read_entries():
+ """Parse the input file and fill a dictionary"""
+ entry = {}
+ def reset_entry():
+ """Set all members of the dict empty,
+ because not all are present in each entry."""
+ entry['cmd'] = ''
+ entry['element'] = ''
+ entry['type'] = 'glyphname'
+ entry['comment'] = []
+ entry['raise'] = ''
+ entry['scale'] = ''
+
+ reset_entry()
+ scale = ''
+ rais = ''
+ for line in lg.definitions_file:
+ line = line.strip()
+ # empty line = end of entry
+ if not len(line):
+ # skip if cmd and glyph haven't been filled both
+ if not (entry['cmd'] and entry['element']):
+ print 'Skip malformed entry \'' + entry['cmd'] + '\'. Please check input file'
+ reset_entry()
+ else:
+ print 'Read entry \'' + entry['cmd'] + '\''
+ lg.in_cmds[entry['cmd']] = {}
+ lg.in_cmds[entry['cmd']]['element'] = entry['element']
+ lg.in_cmds[entry['cmd']]['type'] = entry['type']
+ lg.in_cmds[entry['cmd']]['comment'] = entry['comment']
+ if scale:
+ lg.in_cmds[entry['cmd']]['scale'] = scale
+ if rais:
+ lg.in_cmds[entry['cmd']]['raise'] = rais
+ reset_entry()
+ # ignore Python or LaTeX style comments
+ elif line[0] in '#%':
+ continue
+ else:
+ # add element to the entry
+ keyval = line.split('=')
+ if keyval[0] == 'scale':
+ scale = keyval[1]
+ elif keyval[0] == 'raise':
+ rais = keyval[1]
+ if keyval[0] == 'comment':
+ entry['comment'] = [keyval[1]]
+ else:
+ entry[keyval[0].strip()] = keyval[1].strip()
+
+
+def usage():
+ print 'genGlyphCommands.py'
+ print 'is part of the lilyglyphs package'
+ print ''
+ print 'Usage:'
+ print 'Pass the name (without path) of an input definitions file'
+ print '(this has to be located in the /stash_new_commands directory.'
+ print 'Please refer to the manual (documentation/lilyglyphs.pdf).'
+
+# ####################################
+# Finally launch the program
+if __name__ == "__main__":
+ # parse command line arguments
+ parser = argparse.ArgumentParser(
+ description='Generate LaTeX commands using Emmentaler glyphs',
+ parents=[lg.common_arguments])
+ parser.add_argument('i',
+ type=lg.is_file,
+ metavar='INPUT',
+ help='File with command templates.')
+ args = parser.parse_args()
+
+ # if we have exactly one existing file
+ # join its components and run the program
+ main(os.path.join(os.getcwd(), vars(args)['i']))
diff --git a/macros/luatex/latex/lilyglyphs/scripts/lily-image-commands.py b/macros/luatex/latex/lilyglyphs/scripts/lily-image-commands.py
new file mode 100755
index 0000000000..fce67ad53c
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/scripts/lily-image-commands.py
@@ -0,0 +1,321 @@
+#!/usr/bin/env python
+
+# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+# %
+# This file is part of the 'lilyglyphs' LaTeX package. %
+# ========== %
+# %
+# https://github.com/openlilylib/lilyglyphs %
+# http://www.openlilylib.org/lilyglyphs %
+# %
+# Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+# %
+# 'lilyglyphs' is free software: you can redistribute it and/or modify %
+# it under the terms of the LaTeX Project Public License, either %
+# version 1.3 of this license or (at your option) any later version. %
+# You may find the latest version of this license at %
+# http://www.latex-project.org/lppl.txt %
+# more information on %
+# http://latex-project.org/lppl/ %
+# and version 1.3 or later is part of all distributions of LaTeX %
+# version 2005/12/01 or later. %
+# %
+# This work has the LPPL maintenance status 'maintained'. %
+# The Current Maintainer of this work is Urs Liska (see above). %
+# %
+# This work consists of the files listed in the file 'manifest.txt' %
+# which can be found in the 'license' directory. %
+# %
+# This program is distributed in the hope that it will be useful, %
+# but WITHOUT ANY WARRANTY; without even the implied warranty of %
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+# %
+# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+import os, sys, getopt, datetime, subprocess, argparse, lilyglyphs_common as lg
+
+
+
+# ###############
+# string to be printed before the actual command
+lily_src_prefix = """\\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+"""
+
+# string to be printed after the actual command definition
+lily_src_score = """
+ \\score {
+ \\new Staff \\with {
+ \\remove "Staff_symbol_engraver"
+ \\remove "Clef_engraver"
+ \\remove "Time_signature_engraver"
+ }
+"""
+
+def main():
+ """Do the actual work of the script"""
+ print ''
+ print 'buildglyphimages.py,'
+ print 'Part of lilyglyphs.'
+ print ''
+
+ # set CWD and ensure the necessary subdirs are present
+ check_paths()
+ print ''
+
+ # load and parse input file
+ lg.read_input_file(in_file)
+ read_entries()
+ print ''
+
+ # generate LilyPond source files for each command
+ # and compile them
+ write_lily_src_files()
+ print ''
+ lg.compile_lily_files()
+ print ''
+
+ # remove intermediate files and move pdfs to pdf directory
+ lg.cleanup_lily_files()
+ print ''
+
+ # generate latex commands and example code
+ # and write them to the output file
+ lg.generate_latex_commands()
+ print ''
+ write_latex_file()
+
+
+def check_paths():
+ """Sets CWD to 'glyphimages' subdir or root of lilyglyphs_private
+ and makes sure that the necessary subdirectories are present"""
+
+ # one level above 'definitions' is 'glyphimages'
+ os.chdir(os.path.join(in_path, '..'))
+
+ # check the presence of the necessary subdirectories
+ # and create them if necessary
+ # (otherwise we'll get errors when trying to write in them)
+ ls = os.listdir('.')
+ if not lg.dir_lysrc in ls:
+ os.mkdir(lg.dir_lysrc)
+ if not lg.dir_pdfs in ls:
+ os.mkdir(lg.dir_pdfs)
+ if not lg.dir_cmd in ls:
+ os.mkdir(lg.dir_cmd)
+
+def cmd_filename(cmd_name):
+ if cmd_name.startswith('lily'):
+ return cmd_name[:4] + '-' + cmd_name[4:]
+ elif cmd_name.startswith('lily-'):
+ return cmd_name
+ else:
+ return 'lily-' + cmd_name
+
+# set default scale and raise arguments to empty
+scale = ''
+rais = ''
+
+def read_entries():
+ """Parses the input source file and extracts glyph entries"""
+ print 'Read entries of LilyPond commands:'
+ for i in range(len(lg.definitions_file)):
+ if '%%lilyglyphs' in lg.definitions_file[i]:
+ i = read_entry(i)
+ print lg.lily_files
+
+def read_entry(i):
+ """Reads a single glyph entry from the input file and stores it
+ in the global dictionary lg.in_cmds"""
+ global scale, rais
+ # read comment line(s)
+ i += 1
+ is_protected = False
+ comment = []
+ # loop over the comment line(s)
+ while i < len(lg.definitions_file):
+ line = lg.definitions_file[i].strip()
+ # check for 'protected' entries that shouldn't be processed newly
+ if not line[0] == '%':
+ break
+ elif '%%protected' in line:
+ is_protected = True
+ elif 'scale=' in line:
+ dummy, scale = line.split('=')
+ elif 'raise=' in line:
+ dummy, rais = line.split('=')
+ else:
+ line = line[1:].strip()
+ comment.append(line)
+ i += 1
+
+ # remove any empty lines
+ while len(lg.definitions_file[i].strip()) == 0:
+ i += 1
+
+ # read command name
+ line = lg.definitions_file[i].strip()
+ cmd_name = line[: line.find('=') - 1]
+ print '- ' + cmd_name,
+ if is_protected:
+ print '(protected and skipped)'
+ else:
+ print '' #(for line break only)
+
+ # read actual command until we find a line the begins with a closing curly bracket
+ i += 1
+ lilySrc = []
+ while lg.definitions_file[i][0] != '}':
+ lilySrc.append(lg.definitions_file[i])
+ i += 1
+ if not is_protected:
+ lg.in_cmds[cmd_name] = {}
+ lg.in_cmds[cmd_name]['comment'] = comment
+ lg.in_cmds[cmd_name]['lilySrc'] = lilySrc
+ lg.in_cmds[cmd_name]['element'] = cmd_filename(cmd_name)
+ lg.in_cmds[cmd_name]['type'] = 'image'
+ if scale:
+ lg.in_cmds[cmd_name]['scale'] = scale
+ if rais:
+ lg.in_cmds[cmd_name]['raise'] = rais
+
+ lg.lily_files.append(cmd_filename(cmd_name))
+ return i
+
+
+def usage():
+ print """buildglyphimages. Part of the lilyglyphs package.
+ Parses a template file, creates
+ single .ly files from it, uses LilyPond to create single glyph
+ pdf files and set up template files to be used in LaTeX.
+ The input file has to be located in the glyphimages folder
+ of either the lilyglyph package itself or of a copy of
+ the lilyglyphs_private directory structure contained in the
+ distribution.
+ For detailed instructions refer to the manual.
+ Usage:
+ buildglyphimages.py in-file-name.
+ """
+
+def write_file_info(name, fout):
+ """Formats file specific information for the lilyPond source file"""
+ long_line = '% This file defines a single glyph to be created with LilyPond: %\n'
+ width = len(long_line) - 1
+ header = '%' * width + '\n'
+ spacer = '%' + ' ' * (width - 2) + '%\n'
+ padding = width - len(name) - 8
+ fout.write(header)
+ fout.write(spacer)
+ fout.write(long_line)
+ fout.write(spacer)
+ fout.write('% ' + name + '.ly' + ' ' * padding + '%\n')
+ fout.write(spacer)
+ fout.write(header)
+ fout.write(lg.signature())
+ fout.write('\n\n')
+
+def write_latex_file():
+ """Composes LaTeX file and writes it to disk"""
+ print 'Generate LaTeX file'
+ print lg.dir_cmd, in_basename
+ lg.write_latex_file(os.path.join(os.getcwd(), lg.dir_cmd, in_basename + '.tex'))
+
+def write_lily_src_files():
+ """Generates one .ly file for each found new command"""
+ skip_cmds = []
+ print 'Write .ly files for each entry:'
+ for cmd_name in lg.in_cmds:
+ print '- ' + cmd_name
+ gen_src_name = os.path.join(lg.dir_lysrc, cmd_filename(cmd_name) + '.ly')
+ # handle existing commands
+ if os.path.exists(gen_src_name):
+ action = ''
+ while not (action == 'Y' or action == 'N'):
+ action = raw_input('already present. Overwrite (y/n)? ')
+ action = action.upper()
+ if action == 'N':
+ skip_cmds.append(cmd_name)
+ continue
+
+ # open a single lily src file for write access
+ fout = open(gen_src_name, 'w')
+
+ #output the license information
+ fout.write(lg.lilyglyphs_copyright_string)
+ fout.write('\n')
+
+ #output information on the actual file
+ write_file_info(cmd_name, fout)
+
+ #write the default LilyPond stuff
+ fout.write(lily_src_prefix)
+
+ # write the comment for the command
+ fout.write('%{\n')
+ for line in lg.in_cmds[cmd_name]['comment']:
+ fout.write(line + '\n')
+ fout.write('%}\n\n')
+
+ # write the actual command
+ fout.write(cmd_name + ' = {\n')
+ for line in lg.in_cmds[cmd_name]['lilySrc']:
+ fout.write(line + '\n')
+ fout.write('}\n')
+
+ # write the score definition
+ fout.write(lily_src_score)
+
+ # finish the LilyPond file
+ fout.write(' \\' + cmd_name + '\n')
+ fout.write('}\n\n')
+
+ fout.close()
+
+ # remove skipped commands from in_cmds
+ print skip_cmds
+ for cmd_name in skip_cmds:
+ del lg.in_cmds[cmd_name]
+ lg.lily_files.remove(cmd_filename(cmd_name))
+
+# ####################################
+# Finally launch the program
+if __name__ == "__main__":
+
+ # parse command line arguments
+ parser = argparse.ArgumentParser(
+ description='Process templates to LilyPond input files,' +
+ 'compile these and generate LaTeX commands.',
+ parents=[lg.common_arguments])
+ parser.add_argument('i',
+ type=lg.is_file,
+ metavar='INPUT',
+ help='File with command templates.')
+ args = parser.parse_args()
+
+ # if we have exactly one existing file
+ # join its components and run the program
+
+ # process filename argument, providing absolute path
+ script_path, script_name = os.path.split(sys.argv[0])
+
+ in_file = os.path.join(os.getcwd(), vars(args)['i'])
+ # check if the input file is in the right place
+ # this has to be the definitions subdir of
+ # the package directory or the lilyglyphs_private dir
+ in_path, in_filename = os.path.split(in_file)
+ in_path = os.path.normpath(in_path)
+ if not (('lilyglyphs' in in_path) and (in_path.endswith('definitions'))):
+ print 'File in the wrong location: ' + in_path
+ usage()
+ sys.exit(2)
+ in_basename, in_ext = os.path.splitext(in_filename)
+ main()
diff --git a/macros/luatex/latex/lilyglyphs/scripts/lily-rebuild-pdfs.py b/macros/luatex/latex/lilyglyphs/scripts/lily-rebuild-pdfs.py
new file mode 100755
index 0000000000..b74ab26c6b
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/scripts/lily-rebuild-pdfs.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+
+# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+# %
+# This file is part of the 'lilyglyphs' LaTeX package. %
+# ========== %
+# %
+# https://github.com/openlilylib/lilyglyphs %
+# http://www.openlilylib.org/lilyglyphs %
+# %
+# Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+# %
+# 'lilyglyphs' is free software: you can redistribute it and/or modify %
+# it under the terms of the LaTeX Project Public License, either %
+# version 1.3 of this license or (at your option) any later version. %
+# You may find the latest version of this license at %
+# http://www.latex-project.org/lppl.txt %
+# more information on %
+# http://latex-project.org/lppl/ %
+# and version 1.3 or later is part of all distributions of LaTeX %
+# version 2005/12/01 or later. %
+# %
+# This work has the LPPL maintenance status 'maintained'. %
+# The Current Maintainer of this work is Urs Liska (see above). %
+# %
+# This work consists of the files listed in the file 'manifest.txt' %
+# which can be found in the 'license' directory. %
+# %
+# This program is distributed in the hope that it will be useful, %
+# but WITHOUT ANY WARRANTY; without even the implied warranty of %
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+# %
+# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+# ########################################################################
+# #
+# rebuild-pdfs.py #
+# #
+# This program looks in the directories where the generated .ly files #
+# and the generated pdf images are stored. #
+# If it finds that there are missing pdfs it will recompile them #
+# using LilyPond. #
+# #
+# The main purpose is to allow the creation of pdf images of glyphs #
+# that already have been processed to LaTeX commands but whose PDF #
+# files have been lost. #
+# The other purpose is to update the set of PDF files to a new version #
+# of Emmentaler or LilyPond without touching the definitions. #
+# #
+# ########################################################################
+
+import os, sys, subprocess, argparse, lilyglyphs_common as lg
+
+
+def main():
+ """Main walk through the program"""
+ print 'rebuild-pdfs.py'
+ print 'regenerate all pdf images that are not present (anymore)'
+ print ''
+
+ # Check if we are in a legal CWD and ensure a PDF subdir is present
+ check_paths()
+
+ # build a list of commands with missing PDF files
+ src_files = check_missing_pdfs()
+
+ # is there anything to be done at all?
+ if len(src_files) == 0:
+ print ''
+ print 'No image files missing, nothing to be done.'
+ print 'If you want to re-create pdfs, then delete them first'
+ sys.exit(0)
+ print ''
+ print 'Found ' + str(len(src_files)) + ' missing file(s).'
+ for cmd in src_files:
+ print '- ' + cmd
+
+ # compile all LilyPond files without matching pdf
+ lg.lily_files = src_files
+ lg.compile_lily_files()
+
+ # clean up directories
+ lg.cleanup_lily_files()
+
+def check_missing_pdfs():
+ """Compares the list of LilyPond source and resulting PDF files.
+ Returns a list of LilyPond source file basenames
+ which don't have a corresponding PDF file"""
+ print 'Reading file lists, counting missing pdf files'
+
+ # read existing .pdf files in lg.dir_pdfs
+ img_files = []
+ for entry in os.listdir(lg.dir_pdfs):
+ entry = os.path.join(lg.dir_pdfs, entry)
+ if os.path.isfile(entry):
+ path, name = os.path.split(entry)
+ basename, ext = os.path.splitext(name)
+ if ext == '.pdf':
+ img_files.append(basename)
+
+ # read existing .ly source files in in_dir
+ # and add them to the sources list if the image is missing
+ src_files = []
+ for entry in os.listdir(lg.dir_lysrc):
+ entry = os.path.join(lg.dir_lysrc, entry)
+ if os.path.isfile(entry):
+ path, name = os.path.split(entry)
+ basename, ext = os.path.splitext(name)
+ if ext == '.ly' and basename not in img_files:
+ src_files.append(basename)
+ return src_files
+
+def check_paths():
+ """Checks if we're in the right CWD
+ and makes sure that there is a pdf output directory available"""
+
+ print 'Checking directories ...'
+
+ # check the presence of the necessary subdirectories
+ ls = os.listdir('.')
+ if not 'generated_src' in ls:
+ print 'No LilyPond source files directory found.'
+ print 'Sorry, there is something wrong :-('
+ print 'Current working directory is: ' + os.getcwd()
+ print 'Please consult the manual.'
+ sys.exit(2)
+ if not 'pdfs' in ls:
+ os.mkdir('pdfs')
+
+ print '... done'
+ print ''
+
+
+# ####################################
+# Finally launch the program
+if __name__ == "__main__":
+ # parse command line arguments
+ parser = argparse.ArgumentParser(
+ description='Rebuild all pdfs missing in the \'pdfs\' subdiredtory',
+ parents=[lg.common_arguments])
+ args = parser.parse_args()
+ main()
diff --git a/macros/luatex/latex/lilyglyphs/scripts/lilyglyphs_common.py b/macros/luatex/latex/lilyglyphs/scripts/lilyglyphs_common.py
new file mode 100644
index 0000000000..92a2c023c9
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/scripts/lilyglyphs_common.py
@@ -0,0 +1,360 @@
+#!/usr/bin/env python
+
+# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+# %
+# This file is part of the 'lilyglyphs' LaTeX package. %
+# ========== %
+# %
+# https://github.com/openlilylib/lilyglyphs %
+# http://www.openlilylib.org/lilyglyphs %
+# %
+# Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+# %
+# 'lilyglyphs' is free software: you can redistribute it and/or modify %
+# it under the terms of the LaTeX Project Public License, either %
+# version 1.3 of this license or (at your option) any later version. %
+# You may find the latest version of this license at %
+# http://www.latex-project.org/lppl.txt %
+# more information on %
+# http://latex-project.org/lppl/ %
+# and version 1.3 or later is part of all distributions of LaTeX %
+# version 2005/12/01 or later. %
+# %
+# This work has the LPPL maintenance status 'maintained'. %
+# The Current Maintainer of this work is Urs Liska (see above). %
+# %
+# This work consists of the files listed in the file 'manifest.txt' %
+# which can be found in the 'license' directory. %
+# %
+# This program is distributed in the hope that it will be useful, %
+# but WITHOUT ANY WARRANTY; without even the implied warranty of %
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+# %
+# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+# ########################################################################
+# #
+# lilyglyphs_common.py #
+# #
+# Common functionality for the Python scripts in lilyglyphs #
+# #
+# ########################################################################
+
+import os, sys, datetime, subprocess, argparse
+
+# ################
+# Global variables
+
+definitions_file = []
+version_string = '0.2.2'
+
+# ######################
+# Common CL arguments
+common_arguments = argparse.ArgumentParser(add_help=False)
+common_arguments.add_argument('-v', '--version',
+ action='version',
+ version='%(prog)s ' + version_string)
+
+def is_file(filename):
+ if os.path.exists(filename):
+ return filename
+ else:
+ msg = "file %s not found" % filename
+ raise argparse.ArgumentTypeError(msg)
+
+
+# ###########
+# Directories
+dir_defs = 'definitions'
+dir_lysrc = 'generated_src'
+dir_pdfs = 'pdfs'
+dir_cmd = 'generated_cmd'
+
+# LilyPond commands
+in_cmds = {}
+# LilyPond source files (corresponds to in_cmds)
+# stores basenames without path and extension
+lily_files = []
+# LaTeX commands
+latex_cmds = {}
+
+# #######
+# Strings
+
+lilyglyphs_copyright_string = """
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+"""
+
+latexfile_start_comment = """
+% This file contains definitions for the new commands
+% along with test code for them.
+% You can test the commands in the context of continuous text
+% and adjust their design time options.
+% Afterwards you should manually move the commands to
+% the appropriate .inp files,
+% because this file will be overwritten by the next run
+% of SCRIPT_NAME!
+% If you want to keep this file for reference
+% you should save it with a new name.
+%
+% There also is a table containing entries for use in the lilyglyph manual.
+% You can either copy the whole table to the appropriate
+% place in lilyglyphs.tex or just copy individual table rows.
+
+\\documentclass{scrartcl}
+\\usepackage{lilyglyphsStyle}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%
+% new command definitions
+
+"""
+
+latexfile_begin_document = """
+
+\\begin{document}
+
+%%%%%%%%%%%%%
+% Text output
+
+\\section*{New \\lilyglyphs{} commands}
+"""
+
+latexfile_reftable = """
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Reference table to be used in the manual
+% (use complete or single lines)
+
+\\begin{reftable}{New commands}{newcommands}
+"""
+
+latexfile_testcode = """\\end{reftable}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Test code for fine-tuning the new commands
+"""
+
+# ##############
+# Code templates
+
+# template string to build the test code for the commands
+# 'CMD' will be replaced by the actual command_name
+testcode_template = """
+
+\\noindent\\textbf{\\textsf{Continuous text for} \\cmd{CMD}:}\\\\
+Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+sed \\CMD{} do eiusmod tempor incididunt ut labore et dolore magna aliqua \\CMD.\\\\
+\\CMD{} Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
+ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur \\CMD.
+\\CMD{} Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+\\bigskip
+"""
+
+# Default values for optional argument in generated commands
+DEF_SCALE = '1'
+DEF_RAISE = '0'
+
+# template strings to build the command from
+# 'CMD' will be replaced by the actual command_name
+# 'ELEM' will be replaced by the actual content element to be rendered
+
+cmd_templates = {}
+cmd_templates['image'] = """\\newcommand*{\\CMD}[1][]{%
+ \\setkeys{lilyDesignOptions}{scale=SCALE,raise=RAISE}%
+ \\lilyPrintImage[#1]{ELEM}%
+}
+
+"""
+
+cmd_templates['glyphname'] = """\\newcommand*{\\CMD}[1][]{%
+ \\setkeys{lilyDesignOptions}{scale=SCALE,raise=RAISE}%
+ \\lilyPrint[#1]{\\lilyGetGlyph{ELEM}}%
+}
+
+"""
+
+cmd_templates['number'] = """\\newcommand*{\\CMD}[1][]{%
+ \\setkeys{lilyDesignOptions}{scale=SCALE,raise=RAISE}%
+ \\lilyPrint[#1]{\\lilyGetGlyphByNumber{ELEM}}%
+}
+
+"""
+
+cmd_templates['dynamics'] = """\\newcommand{\\CMD}[1][]{%
+ \\mbox{%
+ \\lilyDynamics[#1]{ELEM}%
+ }%
+}
+
+"""
+
+cmd_templates['text'] = """\\newcommand{\\CMD}[1][]{%
+ \\setkeys{lilyDesignOptions}{scale=SCALE,raise=RAISE}%
+ \\mbox{%
+ \\lilyText[#1]{ELEM}%
+ }%
+}
+
+"""
+
+def cleanup_lily_files():
+ """Removes unneccessary files from LilyPond compilation,
+ rename and remove the preview PDF files to the right directory."""
+
+ print 'Clean up directories'
+
+ # iterate through dir_lysrc
+ os.chdir(dir_lysrc)
+ for entry in os.listdir('.'):
+ if os.path.isfile(entry):
+ name, extension = os.path.splitext(entry)
+ #remove unnecessary files
+ if not extension in ['.pdf', '.ly']:
+ os.remove(entry)
+ if extension == '.pdf':
+ # remove full-page pdf
+ if '.preview' in name:
+ newfile = entry.replace('.preview.', '.')
+ newfile = os.path.join('..', dir_pdfs, newfile)
+ # rename/move small 'preview' pdf
+ os.rename(entry, newfile)
+ else:
+ os.remove(entry)
+ os.chdir('..')
+
+def compile_lily_files():
+ """Compiles LilyPond files to """
+ print 'Compile with LilyPond:'
+ for file in lily_files:
+ args = []
+ args.append("lilypond")
+ args.append("-o")
+ args.append(dir_lysrc)
+ args.append("-dpreview")
+ args.append("-dno-point-and-click")
+ args.append(os.path.join(dir_lysrc, file + ".ly"))
+ subprocess.call(args)
+ print ''
+
+def generate_latex_commands():
+ """Generates the templates for the commands in a new LaTeX file.
+ These should manually be moved to the appropriate .inp files
+ in lilyglyphs"""
+
+ # iterate over the list of commands
+ for cmd_name in in_cmds:
+ latex_cmds[cmd_name] = {}
+
+ # create LaTeX command
+ cmd = []
+ for line in in_cmds[cmd_name]['comment']:
+ cmd.append('% ' + line + '\n')
+ cmd.append(signature() + '\n')
+ template = cmd_templates[in_cmds[cmd_name]['type']]
+ template = template.replace('CMD', cmd_name)
+ if 'scale' in in_cmds[cmd_name]:
+ scale = in_cmds[cmd_name]['scale']
+ else:
+ scale = DEF_SCALE
+ template = template.replace('SCALE', scale)
+ if 'raise' in in_cmds[cmd_name]:
+ rais = in_cmds[cmd_name]['raise']
+ else:
+ rais = DEF_RAISE
+ template = template.replace('RAISE', rais)
+ cmd.append(template.replace('ELEM', in_cmds[cmd_name]['element']))
+ latex_cmds[cmd_name]['cmd'] = cmd
+
+ # create LaTeX test code
+ tc = []
+ tc.append(testcode_template.replace('CMD', cmd_name))
+ latex_cmds[cmd_name]['testcode'] = tc
+
+def read_input_file(in_file):
+ """Reads the input source file and stores it
+ in the global variable definitions_file"""
+ global definitions_file
+
+ in_file = os.path.normpath(in_file)
+
+ print 'Read input file ' + in_file
+
+ # check for existence of input file
+ if not os.path.exists(in_file):
+ print 'File ' + in_file + ' not found.'
+ print 'Please specify an input file'
+ sys.exit(2)
+
+ fin = open(in_file, 'r')
+ for line in fin:
+ definitions_file.append(line.rstrip(' \n'))
+ fin.close()
+
+def script_name():
+ dummy, result = os.path.split(sys.argv[0])
+ return result
+
+def signature():
+ """Returns a signature to be inserted in an output file"""
+ return '% created by ' + script_name() + ' on ' + str(datetime.date.today())
+
+def write_latex_file(file_name):
+ fout = open(file_name, 'w')
+ fout.write('% New Glyphs for the lilyglyphs package\n')
+ fout.write(signature() + '\n')
+ fout.write(latexfile_start_comment.replace('SCRIPT_NAME', script_name()))
+
+ # write out command definitions
+ sorted_cmds = sorted(latex_cmds.iterkeys())
+ for cmd_name in sorted_cmds:
+ for line in latex_cmds[cmd_name]['cmd']:
+ fout.write(line)
+
+ fout.write(latexfile_begin_document)
+ fout.write(signature()[2:]+ '\n')
+ fout.write(latexfile_reftable)
+
+ # write out the reference table
+ row_template = '\\CMD & \\cmd{CMD} & description\\\\'
+ for cmd_name in sorted_cmds:
+ fout.write(row_template.replace('CMD', cmd_name) + '\n')
+ fout.write(latexfile_testcode)
+
+ # write out the test code
+ for cmd_name in sorted_cmds:
+ for line in latex_cmds[cmd_name]['testcode']:
+ fout.write(line)
+
+ fout.write('\\end{document}\n')
+ fout.close()
diff --git a/macros/luatex/latex/lilyglyphs/source/fonts/README-emmentaler b/macros/luatex/latex/lilyglyphs/source/fonts/README-emmentaler
new file mode 100644
index 0000000000..4208f11aa0
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/fonts/README-emmentaler
@@ -0,0 +1,8 @@
+The archive emmentaler-2-18-0 contains
+the Metafont sources used to create the
+Emmentaler OpenType fonts in the /fonts
+directory.
+They were taken from LilyPond's original
+Git repository at
+http://savannah.gnu.org/git/?group=lilypond
+with the 2.18.0 release checked out.
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/_template.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/_template.ly
new file mode 100644
index 0000000000..2854b4ed7d
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/_template.ly
@@ -0,0 +1,54 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file defines a set of glyphs to be compiled in LilyPond %
+% %
+% EXAMPLE %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\version "2.17.5"
+
+%%lilyglyphs
+% example comment
+exampleCommand = {
+ g'4
+}
+
+\markup { exampleCommand}
+symbol = \exampleCommand
+\include "score.ily"
+
+% Example ends here
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/beamednotes.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/beamednotes.ly
new file mode 100644
index 0000000000..1175c8c203
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/beamednotes.ly
@@ -0,0 +1,111 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file defines a set of glyphs to be compiled in LilyPond %
+% %
+% Beamed notes %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\version "2.17.5"
+
+%%%%%%%%%%%%%%%%%%%%%%%
+% Groups with two beams
+
+%%lilyglyphs
+% two beamed quavers with diagonal beam
+%%protected
+twoBeamedQuavers = {
+ \override Beam#'damping = 0
+ d'8[ e']
+}
+
+\markup { twoBeamedQuavers }
+symbol = \twoBeamedQuavers
+\include "score.ily"
+
+%%%%%%%%%%%%%%%%%%%%%%%%%
+% Groups with three beams
+
+%%lilyglyphs
+% raise=-0.6
+% scale=0.9
+% three beamed quavers
+%%protected
+threeBeamedQuavers = {
+ \override Beam #'positions = #'(1 . 1)
+ e'8[ e' e']
+}
+
+\markup { threeBeamedQuavers }
+symbol = \threeBeamedQuavers
+\include "score.ily"
+
+%%lilyglyphs
+% three beamed quavers, second dotted
+%%protected
+threeBeamedQuaversI = {
+ \override Beam #'positions = #'(1 . 1)
+ \override Score.SpacingSpanner #'common-shortest-duration = #(ly:make-moment 1/8)
+ e'8[ e'8. e'16]
+}
+
+\markup { threeBeamedQuaversI }
+symbol = \threeBeamedQuaversI
+\include "score.ily"
+
+%%lilyglyphs
+% three beamed quavers, first dotted
+%%protected
+threeBeamedQuaversII = {
+ \override Beam #'positions = #'(1 . 1)
+ \override Score.SpacingSpanner #'common-shortest-duration = #(ly:make-moment 1/12)
+ e'8.[ e'16 e'8]
+}
+
+\markup { threeBeamedQuaversII }
+symbol = \threeBeamedQuaversII
+\include "score.ily"
+
+%%lilyglyphs
+% three beamed quavers, last dotted
+%%protected
+threeBeamedQuaversIII = {
+ \override Beam #'positions = #'(1 . 1)
+ \override Score.SpacingSpanner #'common-shortest-duration = #(ly:make-moment 1/12)
+ e'16[ e'8. e'8]
+}
+
+\markup { threeBeamedQuaversIII }
+symbol = \threeBeamedQuaversIII
+\include "score.ily"
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/dynamicsigns.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/dynamicsigns.ly
new file mode 100644
index 0000000000..f9a8e66d0f
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/dynamicsigns.ly
@@ -0,0 +1,62 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file defines a set of glyphs to be compiled in LilyPond %
+% %
+% Beamed notes %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\version "2.17.5"
+
+
+%%lilyglyphs
+% crescendo hairpin
+crescHairpin = {
+ s1\< s4\!
+}
+
+\markup { crescHairpin }
+symbol = \crescHairpin
+\include "score.ily"
+
+
+%%lilyglyphs
+% decrescendo hairpin
+decrescHairpin = {
+ s1\> s4\!
+}
+
+\markup { decrescHairpin }
+symbol = \decrescHairpin
+\include "score.ily"
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/fancyexamples.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/fancyexamples.ly
new file mode 100644
index 0000000000..2479478563
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/fancyexamples.ly
@@ -0,0 +1,61 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file defines a set of glyphs to be compiled in LilyPond %
+% %
+% EXAMPLE %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\version "2.17.5"
+
+%{ template for a single entry
+ replace 'EXAMPLE_...' by actual content %}
+
+%%lilyglyphs
+% example of a fancy notation
+lilyFancyExample = \relative e' {
+ \override NoteHead.transparent = ##t
+ \override Stem #'length = #4
+ \override Stem #'thickness = #1.6
+ e4-.( e-. e-. e-.) \glissando
+ s4 \stemDown a4 \laissezVibrer
+}
+
+\markup { lilyFancyExample }
+symbol = \fancyExample
+\include "score.ily"
+
+% Example ends here
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/score.ily b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/score.ily
new file mode 100644
index 0000000000..a61c465e68
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/score.ily
@@ -0,0 +1,49 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is to be included in the definitions .ly files %
+% %
+% Use it to have a LilyPond-compilable .ly file if you want %
+% to visually check your new glyphs before creating the %
+% LaTeX commands %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \symbol
+} \ No newline at end of file
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/singlenotes.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/singlenotes.ly
new file mode 100644
index 0000000000..dc239da35d
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/singlenotes.ly
@@ -0,0 +1,377 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file defines a set of glyphs to be compiled in LilyPond %
+% %
+% Single notes %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\version "2.17.5"
+
+%{ template for a single entry
+ replace 'EXAMPLE_...' by actual content %}
+%%lilyglyphs
+%%protected (use this line if you don't want the command to be generated)
+% EXAMPLE_comment
+EXAMPLE_command_name = {
+ g'4
+}
+
+\markup { EXAMPLE_command_name }
+symbol = \EXAMPLE_command_name
+\include "score.ily"
+
+% Example ends here
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%lilyglyphs
+% half note with upward stem
+%%protected
+halfNote = {
+ \override Stem#'length = 5
+ g'2
+}
+
+\markup { halfNote }
+symbol = \halfNote
+\include "score.ily"
+
+%%lilyglyphs
+% half note with downward stem
+% scale=0.75
+% raise=-0.4
+%%protected
+halfNoteDown = {
+ \stemDown
+ \override Stem#'length = 5
+ g'2
+}
+
+%%lilyglyphs
+% dotted half note with upward stem
+%%protected
+halfNoteDotted = {
+ \override Stem#'length = 5
+ g'2.
+}
+
+\markup { halfNoteDotted }
+symbol = \halfNoteDotted
+\include "score.ily"
+
+%%lilyglyphs
+% dotted half note with downward stem
+%%protected
+halfNoteDottedDown = {
+ \stemDown
+ \override Stem#'length = 5
+ g'2.
+}
+
+%%lilyglyphs
+% doubledotted half note with upward stem
+%%protected
+halfNoteDottedDouble = {
+ \override Stem#'length = 5
+ g'2..
+}
+
+\markup { halfNoteDottedDouble }
+symbol = \halfNoteDottedDouble
+\include "score.ily"
+
+%%lilyglyphs
+% doubledotted half note with downward stem
+%%protected
+halfNoteDottedDoubleDown = {
+ \stemDown
+ \override Stem#'length = 5
+ g'2..
+}
+
+%%lilyglyphs
+% crotchet with upward stem
+%%protected
+crotchet = {
+ \override Stem#'length = 5
+ g'4
+}
+
+\markup { crotchet }
+symbol = \crotchet
+\include "score.ily"
+
+%%lilyglyphs
+% crotchet with downward stem
+%%protected
+crotchetDown = {
+ \stemDown
+ \override Stem#'length = 5
+ g'4
+}
+
+%%lilyglyphs
+% dotted crotchet with upward stem
+%%protected
+crotchetDotted = {
+ \override Stem#'length = 5
+ g'4.
+}
+
+\markup { crotchetDotted }
+symbol = \crotchetDotted
+\include "score.ily"
+
+%%lilyglyphs
+% dotted crotchet with downward stem
+%%protected
+crotchetDottedDown = {
+ \stemDown
+ \override Stem#'length = 5
+ g'4.
+}
+
+%%lilyglyphs
+% doubledotted crotchet with upward stem
+%%protected
+crotchetDottedDouble = {
+ \override Stem#'length = 5
+ g'4..
+}
+
+\markup { crotchetDottedDouble }
+symbol = \crotchetDottedDouble
+\include "score.ily"
+
+
+%%lilyglyphs
+% doubledotted crotchet with upward stem
+%%protected
+crotchetDottedDoubleDown = {
+ \stemDown
+ \override Stem#'length = 5
+ g'4..
+}
+
+%%lilyglyphs
+% quaver with upward stem
+%%protected
+quaver = {
+ \override Stem#'length = 6
+ g'8
+}
+
+%%lilyglyphs
+% quaver with downward stem
+%%protected
+quaverDown = {
+ \stemDown
+ \override Stem#'length = 6
+ g'8
+}
+
+\markup { quaver }
+symbol = \quaver
+\include "score.ily"
+
+%%lilyglyphs
+% dotted quaver with upward stem
+%%protected
+quaverDotted = {
+ \override Stem#'length = 6
+ g'8.
+}
+
+\markup { quaverDotted }
+symbol = \quaverDotted
+\include "score.ily"
+
+
+%%lilyglyphs
+% dotted quaver with downward stem
+%%protected
+quaverDottedDown = {
+ \stemDown
+ \override Stem#'length = 6
+ g'8.
+}
+
+%%lilyglyphs
+% doubledotted quaver with upward stem
+%%protected
+quaverDottedDouble = {
+ \override Stem#'length = 6
+ g'8..
+}
+
+\markup { quaverDottedDouble }
+symbol = \quaverDottedDouble
+\include "score.ily"
+
+%%lilyglyphs
+% doubledotted quaver with downward stem
+%%protected
+quaverDottedDoubleDown = {
+ \stemDown
+ \override Stem#'length = 6
+ g'8..
+}
+
+%%lilyglyphs
+% semiquaver with upward stem
+%%protected
+semiquaver = {
+ \override Stem#'length = #6.5
+ g'16
+}
+
+\markup { semiquaver }
+symbol = \semiquaver
+\include "score.ily"
+
+
+%%lilyglyphs
+% semiquaver with downward stem
+%%protected
+semiquaverDown = {
+ \stemDown
+ \override Stem#'length = #6.5
+ g'16
+}
+
+%%lilyglyphs
+% dotted semiquaver with upward stem
+%%protected
+semiquaverDotted = {
+ \override Stem#'length = #6.5
+ g'16.
+}
+
+\markup { semiquaverDotted }
+symbol = \semiquaverDotted
+\include "score.ily"
+
+%%lilyglyphs
+% dotted semiquaver with downward stem
+%%protected
+semiquaverDottedDown = {
+ \stemDown
+ \override Stem#'length = #6.5
+ g'16.
+}
+
+%%lilyglyphs
+% doubledotted semiquaver with upward stem
+%%protected
+semiquaverDottedDouble = {
+ \override Stem#'length = #6.5
+ g'16..
+}
+
+\markup { semiquaverDottedDouble }
+symbol = \semiquaverDottedDouble
+\include "score.ily"
+
+%%lilyglyphs
+% doubledotted semiquaver with downward stem
+%%protected
+semiquaverDottedDoubleDown = {
+ \stemDown
+ \override Stem#'length = #6.5
+ g'16..
+}
+
+%%lilyglyphs
+% demisemiquaver with upward stem
+%%protected
+demisemiquaver = {
+ \override Stem#'length = #7.5
+ g'32
+}
+
+\markup { demisemiquaver }
+symbol = \demisemiquaver
+\include "score.ily"
+
+
+%%lilyglyphs
+% demisemiquaver with downward stem
+%%protected
+demisemiquaverDown = {
+ \stemDown
+ \override Stem#'length = #7.5
+ g'32
+}
+
+%%lilyglyphs
+% dotted demisemiquaver with upward stem
+%%protected
+demisemiquaverDotted = {
+ \override Stem#'length = #7.5
+ g'32.
+}
+
+\markup { demisemiquaverDotted }
+symbol = \demisemiquaverDotted
+\include "score.ily"
+
+%%lilyglyphs
+% dotted demisemiquaver with downward stem
+%%protected
+demisemiquaverDottedDown = {
+ \stemDown
+ \override Stem#'length = #7.5
+ g'32.
+}
+
+%%lilyglyphs
+% doubledotted demisemiquaver with upward stem
+%%protected
+demisemiquaverDottedDouble = {
+ \override Stem#'length = #7.5
+ g'32..
+}
+
+\markup { demisemiquaverDottedDouble }
+symbol = \demisemiquaverDottedDouble
+\include "score.ily"
+
+%%lilyglyphs
+% doubledotted demisemiquaver with downward stem
+%%protected
+demisemiquaverDottedDoubleDown = {
+ \stemDown
+ \override Stem#'length = #7.5
+ g'32..
+}
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/singlenotes.pdf b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/singlenotes.pdf
new file mode 100644
index 0000000000..c44e140145
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/definitions/singlenotes.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crescHairpin.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crescHairpin.ly
new file mode 100644
index 0000000000..cecaf8f6ee
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crescHairpin.ly
@@ -0,0 +1,69 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% crescHairpin.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-09
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+crescendo hairpin
+%}
+
+crescHairpin = {
+ s1\< s4\!
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \crescHairpin
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchet.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchet.ly
new file mode 100644
index 0000000000..1ecec3a380
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchet.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% crotchet.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-09
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+crotchet with upward stem
+%}
+
+crotchet = {
+ \override Stem#'length = 5
+ g'4
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \crotchet
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDotted.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDotted.ly
new file mode 100644
index 0000000000..53412ee6db
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDotted.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% crotchetDotted.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-09
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+dotted crotchet with upward stem
+%}
+
+crotchetDotted = {
+ \override Stem#'length = 5
+ g'4.
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \crotchetDotted
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDottedDouble.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDottedDouble.ly
new file mode 100644
index 0000000000..e3ac2e02c9
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDottedDouble.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% crotchetDottedDouble.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-09
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+doubledotted crotchet with upward stem
+%}
+
+crotchetDottedDouble = {
+ \override Stem#'length = 5
+ g'4..
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \crotchetDottedDouble
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDottedDoubleDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDottedDoubleDown.ly
new file mode 100644
index 0000000000..eed0a26613
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDottedDoubleDown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% crotchetDottedDoubleDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+doubledotted crotchet with upward stem
+%}
+
+crotchetDottedDoubleDown = {
+ \stemDown
+ \override Stem#'length = 5
+ g'4..
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \crotchetDottedDoubleDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDottedDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDottedDown.ly
new file mode 100644
index 0000000000..41282b207a
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDottedDown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% crotchetDottedDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+dotted crotchet with downward stem
+%}
+
+crotchetDottedDown = {
+ \stemDown
+ \override Stem#'length = 5
+ g'4.
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \crotchetDottedDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDown.ly
new file mode 100644
index 0000000000..2538434dd7
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-crotchetDown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% crotchetDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+crotchet with downward stem
+%}
+
+crotchetDown = {
+ \stemDown
+ \override Stem#'length = 5
+ g'4
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \crotchetDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-decrescHairpin.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-decrescHairpin.ly
new file mode 100644
index 0000000000..65cfa7fc4c
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-decrescHairpin.ly
@@ -0,0 +1,69 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% decrescHairpin.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-09
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+decrescendo hairpin
+%}
+
+decrescHairpin = {
+ s1\> s4\!
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \decrescHairpin
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaver.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaver.ly
new file mode 100644
index 0000000000..209e4accdc
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaver.ly
@@ -0,0 +1,71 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% demisemiquaver.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by lily-image-commands.py on 2013-11-21
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+demisemiquaver with upward stem
+%}
+
+demisemiquaver = {
+ \override Stem#'length = #7.5
+ g'32
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \demisemiquaver
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDotted.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDotted.ly
new file mode 100644
index 0000000000..4eeddda1f2
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDotted.ly
@@ -0,0 +1,71 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% demisemiquaverDotted.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by lily-image-commands.py on 2013-11-21
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+dotted demisemiquaver with upward stem
+%}
+
+demisemiquaverDotted = {
+ \override Stem#'length = #7.5
+ g'32.
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \demisemiquaverDotted
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDottedDouble.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDottedDouble.ly
new file mode 100644
index 0000000000..58449d8ebf
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDottedDouble.ly
@@ -0,0 +1,71 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% demisemiquaverDottedDouble.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by lily-image-commands.py on 2013-11-21
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+doubledotted demisemiquaver with upward stem
+%}
+
+demisemiquaverDottedDouble = {
+ \override Stem#'length = #7.5
+ g'32..
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \demisemiquaverDottedDouble
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDottedDoubleDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDottedDoubleDown.ly
new file mode 100644
index 0000000000..4147746cef
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDottedDoubleDown.ly
@@ -0,0 +1,72 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% demisemiquaverDottedDoubleDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by lily-image-commands.py on 2013-11-21
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+doubledotted demisemiquaver with downward stem
+%}
+
+demisemiquaverDottedDoubleDown = {
+ \stemDown
+ \override Stem#'length = #7.5
+ g'32..
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \demisemiquaverDottedDoubleDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDottedDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDottedDown.ly
new file mode 100644
index 0000000000..5079edb323
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDottedDown.ly
@@ -0,0 +1,72 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% demisemiquaverDottedDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by lily-image-commands.py on 2013-11-21
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+dotted demisemiquaver with downward stem
+%}
+
+demisemiquaverDottedDown = {
+ \stemDown
+ \override Stem#'length = #7.5
+ g'32.
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \demisemiquaverDottedDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDown.ly
new file mode 100644
index 0000000000..772ab223b9
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-demisemiquaverDown.ly
@@ -0,0 +1,72 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% demisemiquaverDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by lily-image-commands.py on 2013-11-21
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+demisemiquaver with downward stem
+%}
+
+demisemiquaverDown = {
+ \stemDown
+ \override Stem#'length = #7.5
+ g'32
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \demisemiquaverDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-fancyExample.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-fancyExample.ly
new file mode 100644
index 0000000000..5ce138f776
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-fancyExample.ly
@@ -0,0 +1,74 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% fancyExample.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by genImageCommands.py on 2013-09-07
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+example of a fancy notation
+%}
+
+fancyExample = {
+ \override NoteHead.transparent = ##t
+ \override Stem #'length = #4
+ \override Stem #'thickness = #1.6
+ e4-.( e-. e-. e-.) \glissando
+ s4 \stemDown a4 \laissezVibrer
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \fancyExample
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNote.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNote.ly
new file mode 100644
index 0000000000..2f7065b2a9
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNote.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% halfNote.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-09
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+half note with upward stem
+%}
+
+halfNote = {
+ \override Stem#'length = 5
+ g'2
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \halfNote
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDotted.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDotted.ly
new file mode 100644
index 0000000000..c2d4f6d187
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDotted.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% halfNoteDotted.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-09
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+dotted half note with upward stem
+%}
+
+halfNoteDotted = {
+ \override Stem#'length = 5
+ g'2.
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \halfNoteDotted
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDottedDouble.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDottedDouble.ly
new file mode 100644
index 0000000000..46f8b4b606
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDottedDouble.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% halfNoteDottedDouble.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-09
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+doubledotted half note with upward stem
+%}
+
+halfNoteDottedDouble = {
+ \override Stem#'length = 5
+ g'2..
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \halfNoteDottedDouble
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDottedDoubleDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDottedDoubleDown.ly
new file mode 100644
index 0000000000..6c85b2f34c
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDottedDoubleDown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% halfNoteDottedDoubleDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+doubledotted half note with downward stem
+%}
+
+halfNoteDottedDoubleDown = {
+ \stemDown
+ \override Stem#'length = 5
+ g'2..
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \halfNoteDottedDoubleDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDottedDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDottedDown.ly
new file mode 100644
index 0000000000..1b8ca534f9
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDottedDown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% halfNoteDottedDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+dotted half note with downward stem
+%}
+
+halfNoteDottedDown = {
+ \stemDown
+ \override Stem#'length = 5
+ g'2.
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \halfNoteDottedDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDown.ly
new file mode 100644
index 0000000000..12891815cd
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-halfNoteDown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% halfNoteDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+half note with downward stem
+%}
+
+halfNoteDown = {
+ \stemDown
+ \override Stem#'length = 5
+ g'2
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \halfNoteDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaver.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaver.ly
new file mode 100644
index 0000000000..73789d53f4
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaver.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% quaver.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-09
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+quaver with upward stem
+%}
+
+quaver = {
+ \override Stem#'length = 6
+ g'8
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \quaver
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDotted.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDotted.ly
new file mode 100644
index 0000000000..d59ea8ba86
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDotted.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% quaverDotted.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+dotted quaver with upward stem
+%}
+
+quaverDotted = {
+ \override Stem#'length = 6
+ g'8.
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \quaverDotted
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDouble.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDouble.ly
new file mode 100644
index 0000000000..d3b20053b3
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDouble.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% quaverDottedDouble.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+doubledotted quaver with upward stem
+%}
+
+quaverDottedDouble = {
+ \override Stem#'length = 6
+ g'8..
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \quaverDottedDouble
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDoubleDdown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDoubleDdown.ly
new file mode 100644
index 0000000000..6cf3cd5e73
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDoubleDdown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% quaverDottedDoubleDdown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+doubledotted quaver with downward stem
+%}
+
+quaverDottedDoubleDdown = {
+ \stemDown
+ \override Stem#'length = 6
+ g'8..
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \quaverDottedDoubleDdown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDoubleDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDoubleDown.ly
new file mode 100644
index 0000000000..211cd4f6fd
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDoubleDown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% quaverDottedDoubleDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+doubledotted quaver with downward stem
+%}
+
+quaverDottedDoubleDown = {
+ \stemDown
+ \override Stem#'length = 6
+ g'8..
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \quaverDottedDoubleDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDown.ly
new file mode 100644
index 0000000000..93ae3005f5
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDottedDown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% quaverDottedDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+dotted quaver with downward stem
+%}
+
+quaverDottedDown = {
+ \stemDown
+ \override Stem#'length = 6
+ g'8.
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \quaverDottedDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDown.ly
new file mode 100644
index 0000000000..d181bdaf55
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-quaverDown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% quaverDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+quaver with downward stem
+%}
+
+quaverDown = {
+ \stemDown
+ \override Stem#'length = 6
+ g'8
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \quaverDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaver.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaver.ly
new file mode 100644
index 0000000000..ebac65b3ce
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaver.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% semiquaver.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-09
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+semiquaver with upward stem
+%}
+
+semiquaver = {
+ \override Stem#'length = #6.5
+ g'16
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \semiquaver
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDotted.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDotted.ly
new file mode 100644
index 0000000000..d516b7973e
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDotted.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% semiquaverDotted.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2013-08-30
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+dotted semiquaver with upward stem
+%}
+
+semiquaverDotted = {
+ \override Stem#'length = #6.5
+ g'16.
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \semiquaverDotted
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDottedDouble.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDottedDouble.ly
new file mode 100644
index 0000000000..0f757c89a3
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDottedDouble.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% semiquaverDottedDouble.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+doubledotted semiquaver with upward stem
+%}
+
+semiquaverDottedDouble = {
+ \override Stem#'length = #6.5
+ g'16..
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \semiquaverDottedDouble
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDottedDoubleDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDottedDoubleDown.ly
new file mode 100644
index 0000000000..72b641db9a
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDottedDoubleDown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% semiquaverDottedDoubleDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+doubledotted semiquaver with downward stem
+%}
+
+semiquaverDottedDoubleDown = {
+ \stemDown
+ \override Stem#'length = #6.5
+ g'16..
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \semiquaverDottedDoubleDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDottedDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDottedDown.ly
new file mode 100644
index 0000000000..f4b725cdb8
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDottedDown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% semiquaverDottedDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+dotted semiquaver with downward stem
+%}
+
+semiquaverDottedDown = {
+ \stemDown
+ \override Stem#'length = #6.5
+ g'16.
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \semiquaverDottedDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDown.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDown.ly
new file mode 100644
index 0000000000..09da96d378
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-semiquaverDown.ly
@@ -0,0 +1,71 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% semiquaverDown.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-13
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+semiquaver with downward stem
+%}
+
+semiquaverDown = {
+ \stemDown
+ \override Stem#'length = #6.5
+ g'16
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \semiquaverDown
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuavers.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuavers.ly
new file mode 100644
index 0000000000..1ea9294685
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuavers.ly
@@ -0,0 +1,71 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% threeBeamedQuavers.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by lily-image-commands.py on 2013-11-21
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+three beamed quavers
+%}
+
+threeBeamedQuavers = {
+ \override Beam #'positions = #'(1 . 1)
+ e'8[ e' e']
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \threeBeamedQuavers
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuaversI.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuaversI.ly
new file mode 100644
index 0000000000..5bdebca329
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuaversI.ly
@@ -0,0 +1,72 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% threeBeamedQuaversI.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by lily-image-commands.py on 2013-11-21
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+three beamed quavers, second dotted
+%}
+
+threeBeamedQuaversI = {
+ \override Beam #'positions = #'(1 . 1)
+ \override Score.SpacingSpanner #'common-shortest-duration = #(ly:make-moment 1/8)
+ e'8[ e'8. e'16]
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \threeBeamedQuaversI
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuaversII.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuaversII.ly
new file mode 100644
index 0000000000..1304da565a
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuaversII.ly
@@ -0,0 +1,72 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% threeBeamedQuaversII.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by lily-image-commands.py on 2013-11-21
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+three beamed quavers, first dotted
+%}
+
+threeBeamedQuaversII = {
+ \override Beam #'positions = #'(1 . 1)
+ \override Score.SpacingSpanner #'common-shortest-duration = #(ly:make-moment 1/12)
+ e'8.[ e'16 e'8]
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \threeBeamedQuaversII
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuaversIII.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuaversIII.ly
new file mode 100644
index 0000000000..846a687e0a
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-threeBeamedQuaversIII.ly
@@ -0,0 +1,72 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% threeBeamedQuaversIII.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by lily-image-commands.py on 2013-11-21
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+three beamed quavers, last dotted
+%}
+
+threeBeamedQuaversIII = {
+ \override Beam #'positions = #'(1 . 1)
+ \override Score.SpacingSpanner #'common-shortest-duration = #(ly:make-moment 1/12)
+ e'16[ e'8. e'8]
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \threeBeamedQuaversIII
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-twoBeamedQuavers.ly b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-twoBeamedQuavers.ly
new file mode 100644
index 0000000000..a14e064594
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/source/glyphimages/generated_src/lily-twoBeamedQuavers.ly
@@ -0,0 +1,70 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file defines a single glyph to be created with LilyPond: %
+% %
+% twoBeamedQuavers.ly %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% created by buildglyphimages.py on 2012-11-09
+
+\version "2.16.2"
+
+#(set-global-staff-size 14)
+
+\paper {
+ indent = 0
+}
+\header {
+ tagline = ""
+}
+
+%{
+two beamed quavers with diagonal beam
+%}
+
+twoBeamedQuavers = {
+ \override Beam#'damping = 0
+ d'8[ e']
+}
+
+ \score {
+ \new Staff \with {
+ \remove "Staff_symbol_engraver"
+ \remove "Clef_engraver"
+ \remove "Time_signature_engraver"
+ }
+ \twoBeamedQuavers
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/tex/README-tex b/macros/luatex/latex/lilyglyphs/tex/README-tex
new file mode 100644
index 0000000000..682ff49e92
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/README-tex
@@ -0,0 +1,7 @@
+This directory contains files to be found by LaTeX.
+
+The core/ and commands/ subdirectories
+_must_ remain beside the lilyglyphs.sty package!
+
+The pdfs/ subdirectory contains files
+that are _used_ by the package. \ No newline at end of file
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/README-commands b/macros/luatex/latex/lilyglyphs/tex/commands/README-commands
new file mode 100644
index 0000000000..4666f416f0
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/README-commands
@@ -0,0 +1,2 @@
+This folder contains command definitions
+used in the lilyglyphs LaTeX package. \ No newline at end of file
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/accidentals.inp b/macros/luatex/latex/lilyglyphs/tex/commands/accidentals.inp
new file mode 100644
index 0000000000..e8b90a6c17
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/accidentals.inp
@@ -0,0 +1,120 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%
+% Accidentals %
+%%%%%%%%%%%%%%%
+
+% "accidentals.natural"
+\renewcommand*{\natural}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.natural}}%
+}
+
+%%%%%%%%
+% flats
+%%%%%%%%
+
+% "accidentals.flat"
+\renewcommand*{\flat}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.2}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.flat}}%
+}
+
+% "accidentals.flatflat"
+\newcommand*{\flatflat}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.2}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.flatflat}}%
+}
+
+%%%%%%%%
+% sharps
+%%%%%%%%
+
+% "accidentals.sharp"
+\renewcommand*{\sharp}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.sharp}}%
+}
+
+% "accidentals.sharp.arrowup"
+\newcommand*{\sharpArrowup}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.sharp.arrowup}}%
+}
+
+% "accidentals.sharp.arrowdown"
+\newcommand*{\sharpArrowdown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.sharp.arrowdown}}%
+}
+
+% "accidentals.sharp.arrowboth"
+\newcommand*{\sharpArrowboth}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.sharp.arrowboth}}%
+}
+
+% "accidentals.sharp.slashslash.stem"
+\newcommand*{\sharpSlashslashStem}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.sharp.slashslash.stem}}%
+}
+
+% "accidentals.sharp.slashslashslash.stemstem"
+\newcommand*{\sharpSlashslashslashStemstem}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.sharp.slashslashslash.stemstem}}%
+}
+
+% "accidentals.sharp.slashslashslash.stem"
+\newcommand*{\sharpSlashslashslashStem}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.sharp.slashslashslash.stem}}%
+}
+
+% "accidentals.sharp.slashslash.stemstemstem"
+\newcommand*{\sharpSlashslashStemstemstem}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.sharp.slashslash.stemstemstem}}%
+}
+
+% "accidentals.doublesharp"
+\newcommand*{\doublesharp}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0.35}%
+ \lilyPrint[#1]{\lilyGetGlyph{accidentals.doublesharp}}%
+}
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/accordion.inp b/macros/luatex/latex/lilyglyphs/tex/commands/accordion.inp
new file mode 100644
index 0000000000..b20f97203e
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/accordion.inp
@@ -0,0 +1,116 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%
+% Accordion registers %
+%%%%%%%%%%%%%%%%%%%%%%%
+
+%------------------
+% Emmentaler glyphs
+
+% accordion bayan bass
+% created by lily-glyph-commands.py on 2013-09-23
+\newcommand*{\accordionBayanBass}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1,raise=-.2}%
+ \hspace*{.5ex}%
+ \lilyPrint[#1]{\lilyGetGlyph{accordion.bayanbass}%
+ \hspace*{-.3ex}}%
+}
+
+% accordion discant
+% created by lily-glyph-commands.py on 2013-09-23
+\newcommand*{\accordionDiscant}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1,raise=-.2}%
+ \hspace*{.6ex}%
+ \lilyPrint[#1]{\lilyGetGlyph{accordion.discant}%
+ \hspace*{-.3ex}}%
+}
+
+% accordion dot
+% created by lily-glyph-commands.py on 2013-09-23
+\newcommand*{\accordionDot}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1,raise=-.2}%
+ \hspace*{.7ex}%
+ \lilyPrint[#1]{\lilyGetGlyph{accordion.dot}}%
+}
+
+% accordion free bass
+% created by lily-glyph-commands.py on 2013-09-23
+\newcommand*{\accordionFreeBass}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1,raise=-.2}%
+ \hspace*{.5ex}%
+ \lilyPrint[#1]{\lilyGetGlyph{accordion.freebass}}%
+}
+
+% accordion old EE
+% created by lily-glyph-commands.py on 2013-09-23
+\newcommand*{\accordionOldEE}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1,raise=-.2}%
+ \hspace*{.5ex}%
+ \lilyPrint[#1]{\lilyGetGlyph{accordion.oldEE}}%
+}
+
+% accordion pull
+% created by lily-glyph-commands.py on 2013-09-23
+\newcommand*{\accordionPull}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1,raise=-.2}%
+ \hspace*{.2ex}%
+ \lilyPrint[#1]{\lilyGetGlyph{accordion.pull}}%
+}
+
+% accordion push
+% created by lily-glyph-commands.py on 2013-09-23
+\newcommand*{\accordionPush}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1,raise=-.2}%
+ \hspace*{.5ex}%
+ \lilyPrint[#1]{\lilyGetGlyph{accordion.push}}%
+}
+
+% accordion standard bass
+% created by lily-glyph-commands.py on 2013-09-23
+\newcommand*{\accordionStdBass}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1,raise=-.2}%
+ \hspace*{.9ex}%
+ \lilyPrint[#1]{\lilyGetGlyph{accordion.stdbass}%
+ \hspace*{-.4ex}}%
+}
+
+%------------------------------
+% Combined glyphs, image based
+
+%TODO
+
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/beamednotes.inp b/macros/luatex/latex/lilyglyphs/tex/commands/beamednotes.inp
new file mode 100644
index 0000000000..c18e3315ae
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/beamednotes.inp
@@ -0,0 +1,81 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%
+% Beamed notes %
+%%%%%%%%%%%%%%%%
+
+%------------------------------
+% Two notes connected by a beam
+
+% two beamed quavers with diagonal beam
+% created by buildglyphimages.py on 2012-11-08
+\newcommand*{\twoBeamedQuavers}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.7,raise=-0.4}%
+ \lilyPrintImage[#1]{lily-twoBeamedQuavers}%
+}
+
+%--------------------------------
+% Three notes connected by a beam
+
+% three beamed quavers
+% created by lily-image-commands.py on 2013-11-21
+\newcommand*{\threeBeamedQuavers}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.9,raise=-0.6}%
+ \lilyPrintImage[#1]{lily-threeBeamedQuavers}%
+}
+
+% three beamed quavers, second dotted
+% created by lily-image-commands.py on 2013-11-21
+\newcommand*{\threeBeamedQuaversI}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.9,raise=-0.6}%
+ \lilyPrintImage[#1]{lily-threeBeamedQuaversI}%
+}
+
+% three beamed quavers, first dotted
+% created by lily-image-commands.py on 2013-11-21
+\newcommand*{\threeBeamedQuaversII}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.9,raise=-0.6}%
+ \lilyPrintImage[#1]{lily-threeBeamedQuaversII}%
+}
+
+% three beamed quavers, last dotted
+% created by lily-image-commands.py on 2013-11-21
+\newcommand*{\threeBeamedQuaversIII}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.9,raise=-0.6}%
+ \lilyPrintImage[#1]{lily-threeBeamedQuaversIII}%
+}
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/clefs.inp b/macros/luatex/latex/lilyglyphs/tex/commands/clefs.inp
new file mode 100644
index 0000000000..4f688e7f3e
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/clefs.inp
@@ -0,0 +1,76 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%
+% Clef glyphs %
+%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%
+% \treble clef
+\newcommand*{\clefG}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.2,raise=0.25}%
+ \lilyPrint[#1]{\lilyGetGlyph{clefs.G}}%
+}
+
+\newcommand*{\clefGInline}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.8,raise=0.15}%
+ \lilyPrint[#1]{\lilyGetGlyph{clefs.G}}%
+}
+
+%%%%%%%%%%%%
+% \bass clef
+\newcommand*{\clefF}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.4,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{clefs.F}}%
+}
+
+\newcommand*{\clefFInline}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.1,raise=0.65}%
+ \lilyPrint[#1]{\lilyGetGlyph{clefs.F}}%
+}
+
+%%%%%%%%%%%%
+% \alto clef
+\newcommand*{\clefC}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.1,raise=0.6}%
+ \lilyPrint[#1]{\lilyGetGlyph{clefs.C}}%
+}
+
+\newcommand*{\clefCInline}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.9,raise=0.6}%
+ \lilyPrint[#1]{\lilyGetGlyph{clefs.C}}%
+}
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/dynamics.inp b/macros/luatex/latex/lilyglyphs/tex/commands/dynamics.inp
new file mode 100644
index 0000000000..1ecb8807d6
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/dynamics.inp
@@ -0,0 +1,97 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Dynamic Script letters %
+%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%--------------
+% Single Glyphs
+
+% The dynamics letters don't have to be accessed through special commands
+% but can be written through \lilyText.
+% A chain of glyphs can be printed at once,
+% normal space is possible between letters
+% Available glyphs are
+ % f for forte
+ % p for piano
+ % m for mezzo
+ % r for rin-
+ % s for s- (as in sf)
+ % z for -z (as in sfz)
+
+% \lilyDynamics is just a wrapper around \lilyText
+% specifying a default scaling factor
+\newcommand{\lilyDynamics}[2][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0}%
+ \lilyPrint[#1]{#2}%
+}
+
+%-------------------------
+% Combined Dynamic Scripts
+
+% Combined dynamics aren't generally necessary
+% as \lilyText takes any combination of characters as argument.
+% Some combinations seem to need additonal kerning,
+% so we provide predefined commands for them
+
+% rinforzando
+\newcommand{\lilyRF}[1][]{%
+ \mbox{\lilyDynamics[#1]{r\hspace{0.035ex}f}}%
+}
+
+% rinforzando with trailing z
+\newcommand{\lilyRFZ}[1][]{%
+ \mbox{\lilyDynamics[#1]{r\hspace{0.035ex}fz}}%
+}
+
+%------------------------
+% Graphical Dynamic Signs
+
+% decrescendo Hairpin
+% created by buildglyphimages.py on 2012-11-08
+\newcommand*{\decrescHairpin}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.9,raise=0}%
+ \lilyPrintImage[#1]{lily-decrescHairpin}%
+}
+
+% crescendo Hairpin
+% created by buildglyphimages.py on 2012-11-08
+\newcommand*{\crescHairpin}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.9,raise=0}%
+ \lilyPrintImage[#1]{lily-crescHairpin}%
+}
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/fancyexamples.inp b/macros/luatex/latex/lilyglyphs/tex/commands/fancyexamples.inp
new file mode 100644
index 0000000000..74c371cf31
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/fancyexamples.inp
@@ -0,0 +1,51 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% fancy example %
+% This isn't a command for any real-world usage %
+% but only an example for creating complex, %
+% i.e. composed notation that can be turned %
+% into a predefined command %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% example of a fancy notation
+% created by genImageCommands.py on 2013-09-07
+\newcommand*{\lilyFancyExample}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=.7,raise=-.7}%
+ \lilyPrintImage[#1]{lily-fancyExample}%
+}
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/noteheads.inp b/macros/luatex/latex/lilyglyphs/tex/commands/noteheads.inp
new file mode 100644
index 0000000000..7961971ca7
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/noteheads.inp
@@ -0,0 +1,48 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%
+% Notes and Noteheads %
+%%%%%%%%%%%%%%%%%%%%%%%
+
+%TODO This really is only a start
+%TODO There is esp. the question of Stems
+
+\newcommand*{\lilyHalfNotehead}{\lilyGlyph{1.5}{"noteheads.s1"} }
+
+\newcommand{\dottedHalf}{\lilyHalfNotehead \lilyDot}
+
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/numbers.inp b/macros/luatex/latex/lilyglyphs/tex/commands/numbers.inp
new file mode 100644
index 0000000000..b1bcfcd9fe
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/numbers.inp
@@ -0,0 +1,53 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%
+% Numbers %
+%%%%%%%%%%%
+
+%--------------
+% Basic numbers
+
+% Numbers don't have to be accessed through special commands
+% but can be written through \lilyText.
+% Available are all arabic numbers from 0 through 9
+
+%TODO: provide convenience commands with default scalings for
+ % fingering
+ % Time signatures
+ % figured bass
+ % etc? \ No newline at end of file
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/rests.inp b/macros/luatex/latex/lilyglyphs/tex/commands/rests.inp
new file mode 100644
index 0000000000..48538af3f7
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/rests.inp
@@ -0,0 +1,141 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%
+% Rests %
+%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%
+% Whole note rests
+
+% "rests.1o - whole note rest upwards"
+\newcommand*{\wholeNoteRest}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.3,raise=0.4}%
+ \lilyPrint[#1]{\hspace*{0.25ex}\lilyGetGlyph{rests.0o}}%
+}
+
+% Dotted whole note rest
+\newcommand*{\wholeNoteRestDotted}[1][]{%
+ % define the optional arguments for the dot
+ \setkeys{lilyDesignOptions}{scale=0.8,raise=0.2}%
+ % Calculate effective scale/raise and the hspace for the dot
+ \lilySetDotOptions[#1]{0}{0.5}{0.4}%
+ % Print the rest and then the dot
+ \wholeNoteRest[#1]\lilyDotSpace\lilyPrintDot
+}
+
+
+%%%%%%%%%%%%%%%%%
+% Half note rests
+%%%%%%%%%%%%%%%%%
+
+% "rests.1o - half note rest upwards"
+\newcommand*{\halfNoteRest}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.3,raise=0.4}%
+ \lilyPrint[#1]{\hspace*{0.25ex}\lilyGetGlyph{rests.1o}}%
+}
+
+% Dotted half note rest
+\newcommand*{\halfNoteRestDotted}[1][]{%
+ % define the optional arguments for the dot
+ \setkeys{lilyDesignOptions}{scale=0.8,raise=0.2}%
+ % Calculate effective scale/raise and the hspace for the dot
+ \lilySetDotOptions[#1]{0}{0.5}{0.4}%
+ % Print the rest and then the dot
+ \halfNoteRest[#1]\lilyDotSpace\lilyPrintDot
+}
+
+%%%%%%%%%%%%%%%%%
+% Crotchet Rests
+%%%%%%%%%%%%%%%%%
+
+% Crotchet Rest
+\newcommand*{\crotchetRest}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.3,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{rests.2}}%
+}
+
+% Dotted crotched rest
+\newcommand*{\crotchetRestDotted}[1][]{%
+ % define the optional arguments for the dot
+ \setkeys{lilyDesignOptions}{scale=0.8,raise=0.2}%
+ % Calculate effective scale/raise and the hspace for the dot
+ \lilySetDotOptions[#1]{0}{0}{-0.5}%
+ % Print the rest and then the dot
+ \crotchetRest[#1]\lilyPrintDot%
+}
+
+%%%%%%%%%%%%%%%
+% Quaver Rests
+%%%%%%%%%%%%%%%
+
+% Quaver Rest
+\newcommand*{\quaverRest}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.3,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{rests.3}}%
+}
+
+% Dotted crotched rest
+\newcommand*{\quaverRestDotted}[1][]{%
+ % define the optional arguments for the dot
+ \setkeys{lilyDesignOptions}{scale=0.8,raise=0.2}%
+ % Calculate effective scale/raise and the hspace for the dot
+ \lilySetDotOptions[#1]{0}{0}{-0.5}%
+ % Print the rest and then the dot
+ \quaverRest[#1]\lilyPrintDot%
+}
+
+
+%%%%%%%%%%%%%%%%%%
+% Semiquaver Rests
+%%%%%%%%%%%%%%%%%%
+
+% Semiquaver Rest
+\newcommand*{\semiquaverRest}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.3,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{rests.4}}%
+}
+
+% Dotted crotchet rest
+\newcommand*{\semiquaverRestDotted}[1][]{%
+ % define the optional arguments for the dot
+ \setkeys{lilyDesignOptions}{scale=0.8,raise=0.2}%
+ % Calculate effective scale/raise and the hspace for the dot
+ \lilySetDotOptions[#1]{0}{0}{-0.3}%
+ % Print the rest and then the dot
+ \semiquaverRest[#1]\lilyPrintDot%
+}
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/scripts.inp b/macros/luatex/latex/lilyglyphs/tex/commands/scripts.inp
new file mode 100644
index 0000000000..16120f05ed
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/scripts.inp
@@ -0,0 +1,121 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%
+% Scripts %
+%%%%%%%%%%%%%%%
+
+% "scripts.ufermata"
+\newcommand*{\fermata}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.2,raise=0.5}%
+ \lilyPrint[#1]{\hspace*{0.55ex}\lilyGetGlyph{scripts.ufermata}}%
+}
+
+%%%%%%%%%%%%%%%
+% Articulations
+%%%%%%%%%%%%%%%
+
+% Accent symbol
+% created by lily-glyph-commands.py on 2013-11-20
+\newcommand*{\lilyAccent}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.4,raise=0.5}%
+ \lilyPrint[#1]{\hspace{0.75ex}\lilyGetGlyph{scripts.sforzato}\hspace{-0.4ex}}%
+}
+
+% Espressivo
+% created by lily-glyph-commands.py on 2013-11-20
+\newcommand*{\lilyEspressivo}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.4,raise=0.5}%
+ \lilyPrint[#1]{\hspace{1.7ex}\lilyGetGlyph{scripts.espr}\hspace{-0.4ex}}%
+}
+
+% Staccato dot
+% created by lily-glyph-commands.py on 2013-11-20
+\newcommand*{\lilyStaccato}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.6,raise=0.5}%
+ \lilyPrint[#1]{\hspace{0.1ex}\lilyGetGlyph{scripts.staccato}\hspace{-0.2ex}}%
+}
+
+% Thumb pizzicato for string instruments
+% created by lily-glyph-commands.py on 2013-11-20
+\newcommand*{\lilyThumb}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.6,raise=0.65}%
+ \lilyPrint[#1]{\hspace{0.1ex}\lilyGetGlyph{scripts.thumb}\hspace{-0.3ex}}%
+}
+
+% marcato articulation
+% created by lily-glyph-commands.py on 2013-11-20
+\newcommand*{\marcato}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.4,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{scripts.umarcato}\hspace{-0.3ex}}%
+}
+
+% marcato articulation downwards
+% created by lily-glyph-commands.py on 2013-11-20
+\newcommand*{\marcatoDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.4,raise=1}%
+ \lilyPrint[#1]{\lilyGetGlyph{scripts.dmarcato}\hspace{-0.3ex}}%
+}
+
+% portato articulation
+% created by lily-glyph-commands.py on 2013-11-20
+\newcommand*{\portato}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.4,raise=0.5}%
+ \lilyPrint[#1]{\hspace{0.2ex}\lilyGetGlyph{scripts.uportato}\hspace{-0.4ex}}%
+}
+
+% portato articulation downwards
+% created by lily-glyph-commands.py on 2013-11-20
+\newcommand*{\portatoDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.4,raise=1}%
+ \lilyPrint[#1]{\hspace{0.2ex}\lilyGetGlyph{scripts.dportato}\hspace{-0.4ex}}%
+}
+
+% staccatissimo articulation
+% created by lily-glyph-commands.py on 2013-11-20
+\newcommand*{\staccatissimo}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.4,raise=0.5}%
+ \lilyPrint[#1]{\lilyGetGlyph{scripts.ustaccatissimo}}%
+}
+
+% tenuto articulation
+% created by lily-glyph-commands.py on 2013-11-20
+\newcommand*{\tenuto}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.4,raise=0.8}%
+ \lilyPrint[#1]{\lilyGetGlyph{scripts.tenuto}\hspace{-0.4ex}}%
+}
+
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/singlenotes.inp b/macros/luatex/latex/lilyglyphs/tex/commands/singlenotes.inp
new file mode 100644
index 0000000000..8c8f16f1cf
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/singlenotes.inp
@@ -0,0 +1,321 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%
+% Single notes %
+%%%%%%%%%%%%%%%%
+
+% The commands are defined in British English
+% and are followed by their American English synonyms
+
+%%%%%%%%%%%%%
+% whole notes
+
+% whole note
+\newcommand*{\semibreve}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1,raise=0.2}%
+ \lilyPrint[#1]{\lilyGetGlyph{noteheads.s0}}%
+}
+\newcommand{\wholeNote}[1][]{\semibreve[#1]}
+
+% dotted whole note
+\newcommand*{\semibreveDotted}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1,raise=0.2}%
+ % Calculate effective scale/raise and the hspace for the dot
+ \lilySetDotOptions[#1]{0}{0.5}{0.4}%
+ % Print the rest and then the dot
+ \wholeNote[#1]\lilyDotSpace\lilyPrintDot
+}
+\newcommand*{\wholeNoteDotted}[1][]{\semibreveDotted[#1]}
+
+%%%%%%%%%%%%
+% half notes
+
+% half note with upward stem
+% created by buildglyphimages.py on 2012-11-06
+\newcommand*{\minim}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.2}%
+ \lilyPrintImage[#1]{lily-halfNote}%
+}
+\newcommand*{\halfNote}[1][]{\minim[#1]}
+
+% half note with downward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\minimDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.6}%
+ \lilyPrintImage[#1]{lily-halfNoteDown}%
+}
+\newcommand*{\halfNoteDown}[1][]{\minimDown[#1]}
+
+% dotted half note with upward stem
+% created by buildglyphimages.py on 2012-11-07
+\newcommand*{\minimDotted}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.2}%
+ \lilyPrintImage[#1]{lily-halfNoteDotted}%
+}
+\newcommand*{\halfNoteDotted}[1][]{\minimDotted[#1]}
+
+% dotted half note with downward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\minimDottedDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.6}%
+ \lilyPrintImage[#1]{lily-halfNoteDottedDown}%
+}
+\newcommand*{\halfNoteDottedDown}[1][]{\minimDottedDown[#1]}
+
+% doubledotted half note with upward stem
+% created by buildglyphimages.py on 2012-11-08
+\newcommand*{\minimDottedDouble}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.2}%
+ \lilyPrintImage[#1]{lily-halfNoteDottedDouble}%
+}
+\newcommand*{\halfNoteDottedDouble}[1][]{\minimDottedDouble[#1]}
+
+% doubledotted half note with downward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\minimDottedDoubleDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.6}%
+ \lilyPrintImage[#1]{lily-halfNoteDottedDoubleDown}%
+}
+\newcommand*{\halfNoteDottedDoubleDown}[1][]{\minimDottedDoubleDown[#1]}
+
+
+%%%%%%%%%%%
+% crotchets
+
+% crotchet with upward stem
+% created by buildglyphimages.py on 2012-11-06
+\newcommand*{\crotchet}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.25}%
+ \lilyPrintImage[#1]{lily-crotchet}%
+}
+\newcommand*{\quarterNote}[1][]{\crotchet[#1]}
+
+% crotchet with downward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\crotchetDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.4}%
+ \lilyPrintImage[#1]{lily-crotchetDown}%
+}
+\newcommand*{\quarterNoteDown}[1][]{\crotchetDown[#1]}
+
+% dotted crotchet with upward stem
+% created by buildglyphimages.py on 2012-11-07
+\newcommand*{\crotchetDotted}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.25}%
+ \lilyPrintImage[#1]{lily-crotchetDotted}%
+}
+\newcommand*{\quarterNoteDotted}[1][]{\crotchetDotted[#1]}
+
+% dotted crotchet with downward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\crotchetDottedDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.4}%
+ \lilyPrintImage[#1]{lily-crotchetDottedDown}%
+}
+\newcommand*{\quarterNoteDottedDown}[1][]{\crotchetDottedDown[#1]}
+
+% doubledotted crotchet with upward stem
+% created by buildglyphimages.py on 2012-11-08
+\newcommand*{\crotchetDottedDouble}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.25}%
+ \lilyPrintImage[#1]{lily-crotchetDottedDouble}%
+}
+\newcommand*{\quarterNoteDottedDouble}[1][]{\crotchetDottedDouble[#1]}
+
+% doubledotted crotchet with downward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\crotchetDottedDoubleDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.4}%
+ \lilyPrintImage[#1]{lily-crotchetDottedDoubleDown}%
+}
+\newcommand*{\quarterNoteDottedDoubleDown}[1][]{\crotchetDottedDoubleDown[#1]}
+
+
+%%%%%%%%%
+% quavers
+
+% quaver with upward stem
+% created by buildglyphimages.py on 2012-11-06
+\newcommand*{\quaver}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.3}%
+ \lilyPrintImage[#1]{lily-quaver}%
+}
+\newcommand*{\eighthNote}[1][]{\quaver[#1]}
+
+% quaver with downward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\quaverDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.7}%
+ \lilyPrintImage[#1]{lily-quaverDown}%
+}
+\newcommand*{\eighthNoteDown}[1][]{\quaverDown[#1]}
+
+% dotted quaver with upward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\quaverDotted}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.3}%
+ \lilyPrintImage[#1]{lily-quaverDotted}%
+}
+\newcommand*{\eighthNoteDotted}[1][]{\quaverDotted[#1]}
+
+% dotted quaver with downward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\quaverDottedDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.7}%
+ \lilyPrintImage[#1]{lily-quaverDottedDown}%
+}
+\newcommand*{\eighthNoteDottedDown}[1][]{\quaverDottedDown[#1]}
+
+% doubledotted quaver with upward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\quaverDottedDouble}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.3}%
+ \lilyPrintImage[#1]{lily-quaverDottedDouble}%
+}
+\newcommand*{\eighthNoteDottedDouble}[1][]{\quaverDottedDouble[#1]}
+
+% doubledotted quaver with downward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\quaverDottedDoubleDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.7}%
+ \lilyPrintImage[#1]{lily-quaverDottedDoubleDown}%
+}
+\newcommand*{\eighthNoteDottedDoubleDown}[1][]{\quaverDottedDoubleDown[#1]}
+
+
+%%%%%%%%%%%%%
+% semiquavers
+
+% semiquaver with upward stem
+% created by buildglyphimages.py on 2012-11-06
+\newcommand*{\semiquaver}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.15}%
+ \lilyPrintImage[#1]{lily-semiquaver}%
+}
+\newcommand*{\sixteenthNote}[1][]{\semiquaver[#1]}
+
+% semiquaver with downward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\semiquaverDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.8}%
+ \lilyPrintImage[#1]{lily-semiquaverDown}%
+}
+\newcommand*{\sixteenthNoteDown}[1][]{\semiquaverDown[#1]}
+
+% dotted semiquaver with upward stem
+% created by buildglyphimages.py on 2012-11-07
+\newcommand*{\semiquaverDotted}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.15}%
+ \lilyPrintImage[#1]{lily-semiquaverDotted}%
+}
+\newcommand*{\sixteenthNoteDotted}[1][]{\semiquaverDotted[#1]}
+
+% dotted semiquaver with downward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\semiquaverDottedDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.8}%
+ \lilyPrintImage[#1]{lily-semiquaverDottedDown}%
+}
+\newcommand*{\sixteenthNoteDottedDown}[1][]{\semiquaverDottedDown[#1]}
+
+% doubledotted semiquaver with upward stem
+% created by buildglyphimages.py on 2012-11-08
+\newcommand*{\semiquaverDottedDouble}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.15}%
+ \lilyPrintImage[#1]{lily-semiquaverDottedDouble}%
+}
+\newcommand*{\sixteenthNoteDottedDouble}[1][]{\semiquaverDottedDouble[#1]}
+
+% doubledotted semiquaver with downward stem
+% created by buildglyphimages.py on 2012-11-13
+\newcommand*{\semiquaverDottedDoubleDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.8}%
+ \lilyPrintImage[#1]{lily-semiquaverDottedDoubleDown}%
+}
+\newcommand*{\sixteenthNoteDottedDoubleDown}[1][]{\semiquaverDottedDoubleDown[#1]}
+
+%%%%%%%%%%%%%%%%%
+% demisemiquavers
+
+% demisemiquaver with upward stem
+% created by lily-image-commands.py on 2013-11-18
+\newcommand*{\demisemiquaver}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.4}%
+ \lilyPrintImage[#1]{lily-demisemiquaver}%
+}
+\newcommand*{\thirtysecondNote}[1][]{\demisemiquaver[#1]}
+
+% dotted demisemiquaver with upward stem
+% created by lily-image-commands.py on 2013-11-18
+\newcommand*{\demisemiquaverDotted}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.4}%
+ \lilyPrintImage[#1]{lily-demisemiquaverDotted}%
+}
+\newcommand*{\thirtysecondNoteDotted}[1][]{\demisemiquaverDotted[#1]}
+
+% doubledotted demisemiquaver with upward stem
+% created by lily-image-commands.py on 2013-11-18
+\newcommand*{\demisemiquaverDottedDouble}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.4}%
+ \lilyPrintImage[#1]{lily-demisemiquaverDottedDouble}%
+}
+\newcommand*{\thirtysecondNoteDottedDouble}[1][]{\demisemiquaverDottedDouble[#1]}
+
+% doubledotted demisemiquaver with downward stem
+% created by lily-image-commands.py on 2013-11-18
+\newcommand*{\demisemiquaverDottedDoubleDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.4}%
+ \lilyPrintImage[#1]{lily-demisemiquaverDottedDoubleDown}%
+}
+\newcommand*{\thirtysecondNoteDottedDoubleDown}[1][]{\demisemiquaverDottedDoubleDown[#1]}
+
+% dotted demisemiquaver with downward stem
+% created by lily-image-commands.py on 2013-11-18
+\newcommand*{\demisemiquaverDottedDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.4}%
+ \lilyPrintImage[#1]{lily-demisemiquaverDottedDown}%
+}
+\newcommand*{\thirtysecondNoteDottedDown}[1][]{\demisemiquaverDottedDown[#1]}
+
+% demisemiquaver with downward stem
+% created by lily-image-commands.py on 2013-11-18
+\newcommand*{\demisemiquaverDown}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.75,raise=-0.4}%
+ \lilyPrintImage[#1]{lily-demisemiquaverDown}%
+}
+\newcommand*{\thirtysecondNoteDown}[1][]{\demisemiquaverDown[#1]}
diff --git a/macros/luatex/latex/lilyglyphs/tex/commands/timesignatures.inp b/macros/luatex/latex/lilyglyphs/tex/commands/timesignatures.inp
new file mode 100644
index 0000000000..e4b248bd9b
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/commands/timesignatures.inp
@@ -0,0 +1,63 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%
+% Time Signature glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% \time 4/4
+\newcommand*{\lilyTimeC}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.4,raise=0.7}%
+ \lilyPrint[#1]{\lilyGetGlyph{timesig.C44}}%
+}
+
+% \time 2/2
+\newcommand*{\lilyTimeCHalf}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.4,raise=0.7}%
+ \lilyPrint[#1]{\lilyGetGlyph{timesig.C22}}%
+}
+
+% general \time n/m command (prints time signature as a fraction in emmentaler font)
+% doesn't need curly braces after it
+\newcommand*{\lilyTimeSignature}[3][]{%
+ \setkeys{lilyDesignOptions}{scale=1.1,raise=0}%
+ \setkeys{lilyCmdOptions}{#1}%
+ \adjustbox{stack=cc}{%
+ \baselineskip=0pt%
+ \lilyPrint[#1]{#2}\\%
+ \lilyPrint[#1]{#3}\par}%
+} \ No newline at end of file
diff --git a/macros/luatex/latex/lilyglyphs/tex/core/README-core b/macros/luatex/latex/lilyglyphs/tex/core/README-core
new file mode 100644
index 0000000000..23286b05f8
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/core/README-core
@@ -0,0 +1,2 @@
+This folder contains the core functionality
+of the lilyglyphs LaTeX package. \ No newline at end of file
diff --git a/macros/luatex/latex/lilyglyphs/tex/core/dotted.inp b/macros/luatex/latex/lilyglyphs/tex/core/dotted.inp
new file mode 100644
index 0000000000..6b7b7f634b
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/core/dotted.inp
@@ -0,0 +1,114 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% logic for dotted glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Dot, e.g. necessary to create dotted notes
+\newcommand*{\lilyDot}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=1.5,raise=0}%
+ \lilyPrint[#1]{\lilyGetGlyph{dots.dot}}%
+}
+
+\makeatletter
+
+% Calculate the space between a glyph and a dot
+% based on the 2nd order function
+% f(x) = (1/n * x^2) - 1/n + (m * x) - m + o
+% where
+% #1: scaling factor x
+% #2: curve factor n
+% #4 line steepness m
+% #3 offset o (offset of 0 results in a dotSpace of 0 at scale=1).
+% The result is supposed to be taken as ex and stored in \lilyDotSpaceF
+% which is used by \lilyDotSpace
+\newcommand*{\lilyCalcDotSpace}[4]{%
+ \pgfmathsetmacro{\lilyDotSpaceF}{%
+ #1 * #1% x^2
+ * #2 - #2%
+ + #1 * #3 - #3 + #4}%
+}
+
+% Interpret the different options to be used for printing a dot
+% The optional arguments (passed as #1)given by the user are taken into account,
+% then the scaling and raise are calculated using the design options
+% from the calling predefined command.
+% Finally the space between the glyph and the dot is calculated using the
+% 2nd order function \lilyCalcDotSpace:
+% (1/n * scale^2) - 1/n + (1/m * scale) - 1/m + o
+% #2: curve factor n
+% #4 line steepness m
+% #3 offset o (offset of 0 results in a dotSpace of 0 at scale=1).
+
+\newcommand*{\lilySetDotOptions}[4][]{%
+ % Initialize the user's command option in case he didn't provide them
+ \setkeys{lilyCmdOptions}{scale=1,raise=0}%
+ % process the optional argument to access the values
+ \setkeys{lilyCmdOptions}{#1}%
+ % calculate optional arguments for the dot,
+ % based on "design options" and the given arguments
+ \pgfmathsetmacro{\lilyDotScale}{\lilyCmdOptions@scale * \lilyDesignOptions@scale}%
+ \pgfmathsetmacro{\lilyDotRaise}{\lilyCmdOptions@raise + \lilyDesignOptions@raise}%
+ % calculate the space between the rest and the dot
+ \lilyCalcDotSpace{\lilyCmdOptions@scale}{#2}{#3}{#4}%
+}
+\makeatother
+
+% Insert a space between a glyph and a dot
+% \lilyCalcDotSpace or better \lilySetDotOptions should have been called
+% immediately before \lilyDotSpace,
+% otherwise the result could be undefined
+\newcommand*{\lilyDotSpace}{\hspace*{\lilyDotSpaceF ex}}
+
+% Print the actual dot,
+% use the settings defined in \lilySetDotOptions
+\newcommand*{\lilyPrintDot}{\lilyDot[raise=\lilyDotRaise,scale=\lilyDotScale]}
+
+% Print another dot, for multiply dotted symbols.
+% It uses the dot settings from the previous command.
+% So if you encounter strange settings, make sure you have called
+% a predefined command of a dotted symbol immediately before.
+% If no predefined command has been called at all
+% you will see an error message because the key-value pairs
+% haven't been initialized yet.
+% It uses a different way to determine the space between dots.
+% It defaults to 0.25 ex, but you can optionally pass it
+% a number that is interpreted as ex.
+\newcommand*{\lilyPrintMoreDots}[1][0.25]{%
+ \hspace*{#1 ex}\lilyPrintDot%
+}
diff --git a/macros/luatex/latex/lilyglyphs/tex/core/genericAccess.inp b/macros/luatex/latex/lilyglyphs/tex/core/genericAccess.inp
new file mode 100644
index 0000000000..095dd2de64
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/core/genericAccess.inp
@@ -0,0 +1,189 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines the generic printing functionality %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This is the internal command that actually prints the glyph(s)%
+% Users aren't intended to use it directly %
+% #1 are key-value options
+% #2 the content to be printed
+\newcommand*{\lilyPrint}[2][]{%
+ % interpret optional argument
+ \interpretLilyOptions{#1}%
+ % print the glyph in a raisebox
+ \raisebox{\lilyEffectiveRaise ex}{%
+ {\fontspec[Scale=\lilyEffectiveScale]{emmentaler-\lilyOpticalSuffix.otf}#2}%
+ }%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Helper functions for \lilyPrintImage below
+
+% Calculate the (point) ratio between the current font size
+% and the size of \normalsize fonts.
+% This is used to scale the output of \lilyPrintImage
+% as images aren't scaled automatically with font size commands.
+\makeatletter
+\newcommand*{\currentFontRatio}{%
+ % store point size of current font
+ \xdef\currentFontSize{\f@size}%
+ {%
+ % Temporarily switch to normal size
+ \normalsize%
+ % and store normal point size
+ \xdef\normalFontSize{\f@size}%
+ }%
+ % Calculate ratio and store the value
+ \pgfmathsetmacro{\getCurrentFontRatio}{%
+ \currentFontSize / \normalFontSize}%
+}
+\makeatother
+
+% Apply the scaling factor that is necessary to
+% accomodate the current font size.
+% The accumulated scaling factor of the other sources
+% is taken into account through \lilyEffectiveScale.
+\newcommand*{\lilyScaleImage}{%
+ \currentFontRatio%
+ \pgfmathsetmacro{\lilyImageEffectiveScale}{%
+ \lilyEffectiveScale * \getCurrentFontRatio}%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Load 'glyph' from an image (preferrably PDF). %
+% Used for items that are created using LilyPond itself %
+% Users aren't intended to use it directly %
+% #1 are key-value options
+% #2 the content to be printed
+\newcommand*{\lilyPrintImage}[2][]{%
+ % interpret optional argument
+ \interpretLilyOptions{#1}%
+ % determine scaling factor to accomodate the current font size
+ % (as images don't scale automatically with the font)
+ \lilyScaleImage%
+ % Print the image in a raisebox
+ \raisebox{\lilyEffectiveRaise ex}{%
+ \includegraphics[scale=\lilyImageEffectiveScale]{#2.pdf}%
+ }%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Generic command(s) to select a LilyPond Glyph %
+% These shouldn't be used by end users but %
+% for designing predefined commands. %
+% They select a glyph by a specific method and %
+% return the #2 to be passed to \lilyPrint %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Determine the glyph by its OpenType glyphName
+
+\usepackage{ifluatex,ifxetex}
+
+\ifluatex
+\usepackage{luaotfload,luacode}
+\begin{luacode}
+documentdata = documentdata or { }
+
+local stringformat = string.format
+local texsprint = tex.sprint
+local slot_of_name = luaotfload.aux.slot_of_name
+
+documentdata.fontchar = function (chr)
+local chr = slot_of_name(font.current(), chr, false)
+if chr and type(chr) == "number" then
+texsprint
+(stringformat ([[\char"%X"]], chr))
+end
+end
+\end{luacode}
+
+\def\lilyGetGlyph#1{\directlua{documentdata.fontchar "#1"}}
+\fi
+
+\ifxetex
+\newcommand*{\lilyGetGlyph}[1]{\XeTeXglyph\XeTeXglyphindex"#1" }
+\fi
+
+% Determine the glyph by its OpenType character number
+% (these may change with new versions of the fonts!)
+\newcommand*{\lilyGetGlyphByNumber}[1]{\char"#1 }
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Generic commands to print glyphs that aren't %
+% covered by predefined commands yet. %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Print a glyph by its glyph name. %
+% Glyph names have to be looked up %
+% in the docs. %
+
+\newcommand*{\lilyGlyph}[2][]{%
+ % set defaults
+ \setkeys{lilyDesignOptions}{scale=1,raise=0}%
+ \lilyPrint[#1]{\lilyGetGlyph{#2}}%
+}
+
+% Determine the glyph by its Unicode number
+% (works for those glyphs that reside in 'standard' places)
+\newcommand*{\lilyGlyphByNumber}[2][]{%
+ % set defaults
+ \setkeys{lilyDesignOptions}{scale=1,raise=0}%
+ \lilyPrint[#1]{\lilyGetGlyphByNumber{#2}}%
+}
+
+% Don't 'determine' glyph positions but just use plain text.
+% This works for dynamics letters, numbers and + - . ,
+\newcommand*{\lilyText}[2][]{%
+ % set defaults
+ \setkeys{lilyDesignOptions}{scale=1,raise=0}%
+ \lilyPrint[#1]{#2}%
+}
+
+% Load 'glyph' from an image (preferrably PDF).
+% Used for items that are created using LilyPond itself.
+\newcommand*{\lilyImage}[2][]{%
+ % set defaults
+ \setkeys{lilyDesignOptions}{scale=1, raise=0}%
+ % interpret optional argument
+ \interpretLilyOptions{#1}%
+ \raisebox{\lilyEffectiveRaise ex}{%
+ \includegraphics[scale=\lilyEffectiveScale]{#2}%
+ }%
+}
diff --git a/macros/luatex/latex/lilyglyphs/tex/core/keyval.inp b/macros/luatex/latex/lilyglyphs/tex/core/keyval.inp
new file mode 100644
index 0000000000..840bbacc36
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/core/keyval.inp
@@ -0,0 +1,100 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines the key-value functionality %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Define keys for keyval options
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\makeatletter
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Family lilyDesignOptions
+%
+% This family is used for defining default values for the options at design time
+% i.e. when developping predefined commands.
+\define@key{lilyDesignOptions}{scale}{\def\lilyDesignOptions@scale{#1}}
+\define@key{lilyDesignOptions}{raise}{\def\lilyDesignOptions@raise{#1}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Family lilyGlobalOptions
+%
+% This family is used for globally adjusting the option values.
+% The user can globally override options at any time
+% using the command \lilyOptions.
+% This is originally intended for cases where the package defaults
+% are not very suitable for the font of the continuous text
+\define@key{lilyGlobalOptions}{scale}{\def\lilyGlobalOptions@scale{#1}}
+\define@key{lilyGlobalOptions}{raise}{\def\lilyGlobalOptions@raise{#1}}
+% Initialize these \defs to 'no adjustment' because the user doesn't have to do that
+\def\lilyGlobalOptions@scale{1}
+\def\lilyGlobalOptions@raise{0}
+
+% Change any of the global options at any place in the document
+% (only options that are present are affected)
+\newcommand*{\lilyGlobalOptions}[1]{\setkeys{lilyGlobalOptions}{#1}}
+
+%%%%%%%%%%%%%%%%%%%%%%%
+% Family lilyCmdOptions
+%
+% This family is used for options the end user can use to fine tune the output
+% (i.e. within the actual document)
+\define@key{lilyCmdOptions}{scale}{\def\lilyCmdOptions@scale{#1}}
+\define@key{lilyCmdOptions}{raise}{\def\lilyCmdOptions@raise{#1}}
+
+% Calculate the effective option values from
+% - global defaults,
+% - design time defaults and
+% - actual user options
+%
+% Scaling factors are multiplied.
+% Raise levels are summed.
+\newcommand*{\interpretLilyOptions}[1]{%
+ % initialize user arguments (no argument = no change)
+ % in order to avoid uninitialized arguments
+ \setkeys{lilyCmdOptions}{scale=1,raise=0}%
+ % Options that are present override the defaults
+ \setkeys{lilyCmdOptions}{#1}%
+ % calculate the scaling factor
+ \pgfmathsetmacro{\lilyEffectiveScale}{%
+ \lilyGlobalOptions@scale * \lilyCmdOptions@scale * \lilyDesignOptions@scale}%
+ % calculate the raise level from the design value and the optional user value
+ \pgfmathsetmacro{\lilyEffectiveRaise}{%
+ \lilyGlobalOptions@raise + \lilyCmdOptions@raise + \lilyDesignOptions@raise}%
+}
+
+\makeatother
+
diff --git a/macros/luatex/latex/lilyglyphs/tex/core/opticals.inp b/macros/luatex/latex/lilyglyphs/tex/core/opticals.inp
new file mode 100644
index 0000000000..83c39ede6e
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/core/opticals.inp
@@ -0,0 +1,55 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is part of the lilyglyphs package %
+% and defines one subset of glyphs %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Define the used optical size font
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The Emmentaler font comes in several optical sizes
+% While these are originally intendes for use at different point sizes
+% they are rather weights in the context of continuous text.
+%
+% Default to 16 (medium)
+\def\lilyOpticalSuffix{16}
+% The following command select from the available fonts
+% and can be used anywhere in the document
+% #1 is the suffix number of the font file
+% and has to be on of the following:
+% 11,13,14,16,18,20,23,26
+% Higher the number result in thinner glyphs
+\newcommand{\lilyOpticalSize}[1]{\def\lilyOpticalSuffix{#1}}
+
diff --git a/macros/luatex/latex/lilyglyphs/tex/lilyglyphs.sty b/macros/luatex/latex/lilyglyphs/tex/lilyglyphs.sty
new file mode 100644
index 0000000000..7788f40755
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/lilyglyphs.sty
@@ -0,0 +1,103 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% This file is part of the 'lilyglyphs' LaTeX package. %
+% ========== %
+% %
+% https://github.com/openlilylib/lilyglyphs %
+% http://www.openlilylib.org/lilyglyphs %
+% %
+% Copyright 2012-2013 Urs Liska and others, ul@openlilylib.org %
+% %
+% 'lilyglyphs' is free software: you can redistribute it and/or modify %
+% it under the terms of the LaTeX Project Public License, either %
+% version 1.3 of this license or (at your option) any later version. %
+% You may find the latest version of this license at %
+% http://www.latex-project.org/lppl.txt %
+% more information on %
+% http://latex-project.org/lppl/ %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% This work has the LPPL maintenance status 'maintained'. %
+% The Current Maintainer of this work is Urs Liska (see above). %
+% %
+% This work consists of the files listed in the file 'manifest.txt' %
+% which can be found in the 'license' directory. %
+% %
+% This program is distributed in the hope that it will be useful, %
+% but WITHOUT ANY WARRANTY; without even the implied warranty of %
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{lilyglyphs}
+
+% Introduce key=value options
+\RequirePackage{keyval}
+
+% Necessary for calculations.
+% TODO: Is that really necessary or can it be achieved much cheaper?
+\RequirePackage{pgf}
+
+% Create a vertically stacked box (time signatures)
+\RequirePackage[export]{adjustbox}
+
+%%%%%%%%%%%%%%%%%%%%%%
+% Core functionality %
+
+% select from the optical sizes fonts
+\input{core/opticals.inp}
+
+% include the functionality for the key=value options
+\input{core/keyval.inp}
+
+% include the basic functionality to select and print glyphs
+\input{core/genericAccess.inp}
+
+% include logic and functionality to create dotted symbols
+\input{core/dotted.inp}
+
+% Core functionality %
+%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Definitions of the glyphs in groups %
+% corresponding to the glyph list in the LilyPond docs %
+
+\input{commands/clefs.inp}
+
+\input{commands/numbers.inp}
+
+\input{commands/timesignatures.inp}
+
+\input{commands/dynamics.inp}
+
+\input{commands/accidentals.inp}
+
+%\input{commands/noteheads.inp}
+
+\input{commands/rests.inp}
+
+\input{commands/scripts.inp}
+
+\input{commands/accordion.inp}
+
+% Definitions of complex glyphs created with LilyPond
+% and included as image files
+
+\input{commands/singlenotes.inp}
+
+\input{commands/beamednotes.inp}
+
+\input{commands/fancyexamples.inp}
+
+% End of command definitions %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% lilyglyphs logo to be used in texts about lilyglyphs
+% created by genGlyphCommands.py on 2012-11-10
+\newcommand*{\lilyglyphs}[1][]{%
+ \setkeys{lilyDesignOptions}{scale=0.97,raise=-0.78}%
+ \lilyPrintImage[#1]{lilyglyphs_logo}%
+}
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crescHairpin.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crescHairpin.pdf
new file mode 100644
index 0000000000..cba460c570
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crescHairpin.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchet.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchet.pdf
new file mode 100644
index 0000000000..9ce5a793ab
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchet.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDotted.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDotted.pdf
new file mode 100644
index 0000000000..1c55a09877
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDotted.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDottedDouble.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDottedDouble.pdf
new file mode 100644
index 0000000000..0f39bd0606
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDottedDouble.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDottedDoubleDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDottedDoubleDown.pdf
new file mode 100644
index 0000000000..ccde99d755
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDottedDoubleDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDottedDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDottedDown.pdf
new file mode 100644
index 0000000000..963557dc53
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDottedDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDown.pdf
new file mode 100644
index 0000000000..75db5762fe
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-crotchetDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-decrescHairpin.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-decrescHairpin.pdf
new file mode 100644
index 0000000000..3d676e5bee
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-decrescHairpin.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaver.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaver.pdf
new file mode 100644
index 0000000000..edfe5bc1b4
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaver.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDotted.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDotted.pdf
new file mode 100644
index 0000000000..2ff802c1cf
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDotted.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDottedDouble.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDottedDouble.pdf
new file mode 100644
index 0000000000..899060302e
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDottedDouble.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDottedDoubleDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDottedDoubleDown.pdf
new file mode 100644
index 0000000000..09fb1be424
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDottedDoubleDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDottedDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDottedDown.pdf
new file mode 100644
index 0000000000..85e89b8ca0
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDottedDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDown.pdf
new file mode 100644
index 0000000000..ce361e340d
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-demisemiquaverDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-fancyExample.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-fancyExample.pdf
new file mode 100644
index 0000000000..48c9e4c06c
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-fancyExample.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNote.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNote.pdf
new file mode 100644
index 0000000000..639277692a
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNote.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDotted.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDotted.pdf
new file mode 100644
index 0000000000..67f68c534d
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDotted.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDottedDouble.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDottedDouble.pdf
new file mode 100644
index 0000000000..6d8dd52076
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDottedDouble.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDottedDoubleDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDottedDoubleDown.pdf
new file mode 100644
index 0000000000..f93e8c487f
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDottedDoubleDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDottedDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDottedDown.pdf
new file mode 100644
index 0000000000..1ca33ca079
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDottedDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDown.pdf
new file mode 100644
index 0000000000..699ba96fc5
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-halfNoteDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaver.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaver.pdf
new file mode 100644
index 0000000000..c9b6e0a8d1
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaver.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDotted.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDotted.pdf
new file mode 100644
index 0000000000..95d24f18fb
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDotted.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDouble.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDouble.pdf
new file mode 100644
index 0000000000..e448e06f15
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDouble.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDoubleDdown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDoubleDdown.pdf
new file mode 100644
index 0000000000..4e2f48e68f
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDoubleDdown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDoubleDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDoubleDown.pdf
new file mode 100644
index 0000000000..e59325eed5
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDoubleDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDown.pdf
new file mode 100644
index 0000000000..b68c341da6
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDottedDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDown.pdf
new file mode 100644
index 0000000000..52ce2437b1
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-quaverDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaver.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaver.pdf
new file mode 100644
index 0000000000..a72405f5b7
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaver.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDotted.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDotted.pdf
new file mode 100644
index 0000000000..d810ea9339
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDotted.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDottedDouble.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDottedDouble.pdf
new file mode 100644
index 0000000000..b2434a6c76
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDottedDouble.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDottedDoubleDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDottedDoubleDown.pdf
new file mode 100644
index 0000000000..e8b391aae0
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDottedDoubleDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDottedDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDottedDown.pdf
new file mode 100644
index 0000000000..c980d5b86d
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDottedDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDown.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDown.pdf
new file mode 100644
index 0000000000..3ea309c499
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-semiquaverDown.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuavers.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuavers.pdf
new file mode 100644
index 0000000000..c8503af46a
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuavers.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuaversI.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuaversI.pdf
new file mode 100644
index 0000000000..0743b08b5c
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuaversI.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuaversII.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuaversII.pdf
new file mode 100644
index 0000000000..3985befd88
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuaversII.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuaversIII.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuaversIII.pdf
new file mode 100644
index 0000000000..9b8cd50615
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-threeBeamedQuaversIII.pdf
Binary files differ
diff --git a/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-twoBeamedQuavers.pdf b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-twoBeamedQuavers.pdf
new file mode 100644
index 0000000000..45b88b27c5
--- /dev/null
+++ b/macros/luatex/latex/lilyglyphs/tex/pdfs/lily-twoBeamedQuavers.pdf
Binary files differ
diff --git a/macros/luatex/latex/lua-check-hyphen/README.md b/macros/luatex/latex/lua-check-hyphen/README.md
new file mode 120000
index 0000000000..fd42db32e3
--- /dev/null
+++ b/macros/luatex/latex/lua-check-hyphen/README.md
@@ -0,0 +1 @@
+doc/README.md \ No newline at end of file
diff --git a/macros/luatex/latex/lua-check-hyphen/doc/README.md b/macros/luatex/latex/lua-check-hyphen/doc/README.md
new file mode 100644
index 0000000000..24384114ef
--- /dev/null
+++ b/macros/luatex/latex/lua-check-hyphen/doc/README.md
@@ -0,0 +1,27 @@
+# lua-check-hyphen
+
+## Usage
+
+ \usepackage{lua-check-hyphen}
+ ...
+ \LuaCheckHyphen{mark,whitelist={filea.txt,fileb.txt}}
+
+## What it does
+
+It lists all hyphenated words in the log file as well as in the file with the extension `.uhy`
+
+## How to use
+
+A typical workflow is:
+
+* run final document
+* put the correctly hyphenated words into a text file (format: each word separated with space or on a single line, only whitespace matters as a separator)
+* add that file to the whitelist (as given above)
+* optionally use the option `mark` to make the unknown hyphenated words visible in the PDF file
+
+
+Copyright 2012–2018 Patrick Gundlach (patrick@gundla.ch) and other contributors (see github)<br>
+Package version: 0.7a
+Public repository: https://github.com/pgundlach/lua-check-hyphen<br>
+Licensed under the MIT license. See the file 'mit-license.txt' for exact terms.<br>
+Status: works fine, slightly unmaintained.<br>
diff --git a/macros/luatex/latex/lua-check-hyphen/doc/luacheckhyphenmanual.pdf b/macros/luatex/latex/lua-check-hyphen/doc/luacheckhyphenmanual.pdf
new file mode 100644
index 0000000000..a701120890
--- /dev/null
+++ b/macros/luatex/latex/lua-check-hyphen/doc/luacheckhyphenmanual.pdf
Binary files differ
diff --git a/macros/luatex/latex/lua-check-hyphen/doc/luacheckhyphenmanual.tex b/macros/luatex/latex/lua-check-hyphen/doc/luacheckhyphenmanual.tex
new file mode 100644
index 0000000000..5d043a7124
--- /dev/null
+++ b/macros/luatex/latex/lua-check-hyphen/doc/luacheckhyphenmanual.tex
@@ -0,0 +1,173 @@
+\documentclass{ltxdockit}
+\usepackage{csquotes,graphicx}
+\newcommand\pkgversion{0.7a}
+
+\titlepage{%
+ title={The lua-check-hyphen package},
+ subtitle={Checking your hyphenated words},
+ url={https://github.com/pgundlach/lua-check-hyphen},
+ author={Patrick Gundlach},
+ email={patrick@gundla.ch},
+ revision={\pkgversion},
+ date={\today}}
+
+\hypersetup{%
+ pdftitle={The lua-check-hyphen package},
+ pdfsubject={Checking your hyphenated words},
+ pdfauthor={Patrick Gundlach},
+ pdfkeywords={tex, latex, hyphenation}}
+
+
+
+
+\begin{document}
+\printtitlepage
+\tableofcontents
+
+\section{Introduction}
+
+\TeX\ is pretty good at hyphenating words. But a computer algorithm is not perfect, sometimes we wish to manually check all used hyphenations in a document. This package helps you on this task.
+
+\section{Usage}
+
+This package only works with Lua\TeX. To activate it a
+
+\begin{verbatim}
+ \usepackage{lua-check-hyphen}
+\end{verbatim}
+is enough.
+
+When you process your document with Lua\LaTeX, a file with the suffix \verb|.uhy| is created with that contains every hyphenated word. You can check that file for hyphenation errors. With the package option \texttt{nofile}, you can tell the package not to write the external file. In any case the list is written to the log file.
+
+\section{Advanced usage}
+\label{sec:advanced_usage}
+
+With longer documents it becomes tedious checking for the same hyphenated words over and over. Therefore this package allows you to create a whitelist of \emph{accepted hyphenation}. This whitelist is a simple textfile where the words are separated by whitespace and the allowed hyphenation is marked with a dash (-). You can use the output file \texttt{.uhy} as an input for the whitelist file. You load the file in your document with
+
+\begin{verbatim}
+ \LuaCheckHyphen{whitelist=myfile.txt}
+\end{verbatim}
+
+and a sample file looks like this:
+
+\begin{verbatim}
+seren-ity
+morn-ings
+posses-sion
+\end{verbatim}
+
+or
+
+\begin{verbatim}
+seren-ity morn-ings posses-sion
+\end{verbatim}
+
+The format is not important, the entries must be separated by whitespace.
+
+Words in this whitelist won't be reported. \sty{lua-check-hyphen} assumes that these are valid break points.
+
+You can have more than one whitelist file by giving the filenames separated by comma:
+
+\begin{verbatim}
+\LuaCheckHyphen{whitelist={file1.txt,file2.txt,file3.txt}}
+\end{verbatim}
+
+\section{Visual marker}
+
+You might want to use the PDF viewer to check for incorrectly hyphenated words. To enable visual feedback, just pass the \texttt{mark} option to the \cmd{usepackage} or to the \cmd{LuaCheckHyphen} command:
+
+\begin{verbatim}
+\usepackage[mark]{lua-check-hyphen}
+% or:
+\LuaCheckHyphen{mark}
+\end{verbatim}
+
+This marks all non-whitelisted used hyphenation points in the document with a black square (not to be confused with overfull boxes):
+
+\includegraphics{sample-crop}
+
+\section{Options to \cmd{LuaCheckHyphen}}
+
+For the true/false options you don't need to write the \texttt{=true} part. All options except for the \texttt{whitelist} can be passed directly to the package:
+
+\begin{verbatim}
+\usepackage[mark,nofile]{lua-check-hyphen}
+\end{verbatim}
+
+\noindent All options can be set in \cmd{LuaCheckHyphen}.
+
+\begin{verbatim}
+\LuaCheckHyphen{mark,nofile,whitelist=myfile.txt}
+\end{verbatim}
+
+
+\begin{optionlist}
+ \boolitem[true]{compact}{Words with different hyphenation occurrences are listed only once.}
+ \boolitem[false]{mark}{Create visual markers when an unknown hyphenation encountered.}
+ \boolitem[false]{nofile}{Don't write to an external file (\texttt{.uhy}).}
+ \boolitem[false]{file}{Don't do anything. This is for the last document run, no marks will be generated.}
+ \valitem{whitelist}{files}{List of files, separated by \enquote{\texttt{,}}. You need to wrap the filenames in braces \texttt{\textbraceleft...\textbraceright} so that the comma won't be seen as a option separator.}
+\end{optionlist}
+
+\section{Final document}
+
+When you pass the Option \opt{final} to the \cmd{documentclass}, the \cmd{usepackage} or the \cmd{LuaCheckHyphen} command, all processing is disabled.
+
+\section{Changes}
+\begin{changelog}
+\begin{release}{0.7a}{2018-04-19}
+ \item Bugfix for \texttt{--output-directory} with argument separated by = instead of whitespace.
+\end{release}
+\begin{release}{0.7}{2018-04-16}
+ \item Take \texttt{--output-directory} into account.
+\end{release}
+\begin{release}{0.6}{2018-02-07}
+ \item Remove dependencies and update package to a modern LuaTeX. Thanks to Christian Stadelmann.
+\end{release}
+\begin{release}{0.5}{2017-07-31}
+ \item Fix error where I can't find a whitelist file, but the io.open() call does not return an error message.
+\end{release}
+\begin{release}{0.4}{2016-04-01}
+ \item Compact representation of hyphenated words that occur more than once with different hyphenation positions (option copmact=true).
+ \item Sort uhy entries alphabetically and only use lowercase words in the file.
+\end{release}
+ \begin{release}{0.2}{2012-06-22}
+ \item Fix ligature counting error (github issue \#1)
+ \item Add nofile option
+ \item No hyphenation list in the terminal output (log only)
+ \item License details added
+ \end{release}
+\end{changelog}
+
+\section{Bugs}
+
+\begin{itemize}
+ \item Paragraphs that end with \verb+\end{document}+ are ignored. Inserting an empty line or
+ \cmd{par} helps.
+\end{itemize}
+
+\section{License}
+
+This file (documentation and the package) is released under the terms of the MIT License. See the file \texttt{mit-license.txt} in the distribution.
+
+% Copyright (c) 2012 Patrick Gundlach
+
+% Permission is hereby granted, free of charge, to any person obtaining a copy
+% of this software and associated documentation files (the \enquote{Software}), to deal
+% in the Software without restriction, including without limitation the rights
+% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+% copies of the Software, and to permit persons to whom the Software is
+% furnished to do so, subject to the following conditions:
+
+% The above copyright notice and this permission notice shall be included in all
+% copies or substantial portions of the Software.
+
+% THE SOFTWARE IS PROVIDED \enquote{AS IS}, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+% SOFTWARE.
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/lua-check-hyphen/doc/mit-license.txt b/macros/luatex/latex/lua-check-hyphen/doc/mit-license.txt
new file mode 100644
index 0000000000..1bc0d0e99e
--- /dev/null
+++ b/macros/luatex/latex/lua-check-hyphen/doc/mit-license.txt
@@ -0,0 +1,19 @@
+Copyright (c) 2012-2014 Patrick Gundlach
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/macros/luatex/latex/lua-check-hyphen/doc/sample.pdf b/macros/luatex/latex/lua-check-hyphen/doc/sample.pdf
new file mode 100644
index 0000000000..83d16992ee
--- /dev/null
+++ b/macros/luatex/latex/lua-check-hyphen/doc/sample.pdf
Binary files differ
diff --git a/macros/luatex/latex/lua-check-hyphen/doc/sample.tex b/macros/luatex/latex/lua-check-hyphen/doc/sample.tex
new file mode 100644
index 0000000000..618fbf7f17
--- /dev/null
+++ b/macros/luatex/latex/lua-check-hyphen/doc/sample.tex
@@ -0,0 +1,10 @@
+\documentclass{article}
+\usepackage{fontspec,nopageno}
+\usepackage[mark]{lua-check-hyphen}
+\begin{document}
+\parindent0.9em
+\hsize 1.3in
+A wonderful serenity has taken possession of my entire soul, like these sweet
+mornings of spring which I enjoy with my whole heart.
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/lua-check-hyphen/lua-check-hyphen.lua b/macros/luatex/latex/lua-check-hyphen/lua-check-hyphen.lua
new file mode 100644
index 0000000000..b21a39bcde
--- /dev/null
+++ b/macros/luatex/latex/lua-check-hyphen/lua-check-hyphen.lua
@@ -0,0 +1,284 @@
+-- Copyright 2012-2017 Patrick Gundlach (patrick@gundla.ch)
+-- Public repository: https://github.com/pgundlach/lua-check-hyphen
+-- Licensed under the MIT license. See the file 'mit-license.txt' for exact terms.
+
+-- Version: 0.7a
+
+
+-- for debugging purpuse:
+-- function w( ... )
+-- texio.write_nl("--->" .. string.format(...))
+-- end
+
+local explode = function(s,p)
+ local t = { }
+ for s in unicode.utf8.gmatch(s,p) do
+ if s ~= "" then
+ t[#t+1] = s
+ end
+ end
+ return t
+end
+
+luacheckhyphen = {}
+
+
+local hyphenattr = luatexbase.new_attribute("hyphenattr")
+
+luacheckhyphen.hyphenwords = {}
+luacheckhyphen.all_hyphenatedwords = {}
+luacheckhyphen.word_whitelist = {}
+luacheckhyphen.rectangle = node.new("whatsit","pdf_literal")
+luacheckhyphen.rectangle.data = string.format("q 0 0 10 10 re f S Q")
+
+local a_glyph_node = node.id("glyph")
+local a_disc_node = node.id("disc")
+local a_glue_node = node.id("glue")
+local a_whatsit_node = node.id("whatsit")
+local subtype_rightskip = 9
+
+
+local sln = unicode.utf8
+
+luacheckhyphen.deligature = function ( glyph_node )
+ local head = glyph_node.components
+ local str = ""
+ while head do
+ if head.id == a_glyph_node then
+ if head.components then
+ str = str .. luacheckhyphen.deligature(head)
+ else
+ str = str .. sln.char(head.char)
+ end
+ end
+ head = head.next
+ end
+ return str
+end
+
+
+-- This functions analyzes the list beginning at head. If it encounters a box,
+-- it recurses into the box. If it finds a disc node, it goes back until it finds the word
+-- start. Then it analyzes the word und finds all hyphenation points. For example the German
+-- word "Salpetersäure" has these disc nodes: , "Sal-petersäure", "Salpe-tersäure",
+-- "Salpeter-säure", and "Salpetersäu-re". Each of these "word with hyphen" gets stored in
+-- the hash hyphenwords
+luacheckhyphen.collect_discs = function(head)
+ local word_start
+ local word
+ -- this is where we store all the breakpoints
+ local thisbreakpoint
+ local word_with_hyphen
+ local c
+ local hyphencounter = #luacheckhyphen.hyphenwords + 1
+ local sln = unicode.utf8
+ local ligature_chars
+ while head do
+ if head.id == 0 then
+ elseif head.id == a_disc_node then
+ word_start = head
+ word_end = head
+ while word_start.prev and word_start.prev.id ~= a_glue_node do
+ word_start = word_start.prev
+ end
+ word = ""
+ c = 0
+ while word_start and word_start.id ~= a_glue_node do
+ if word_start == head then -- disc
+ -- there is a breakpoint after letter c
+ node.set_attribute(head,hyphenattr,hyphencounter)
+ thisbreakpoint = c
+ elseif word_start.id == a_glyph_node then
+ if word_start.components then
+ ligature_chars = luacheckhyphen.deligature(word_start)
+ word = word .. ligature_chars
+ c = c + string.len(ligature_chars)
+ elseif sln.match(sln.char(word_start.char),"%a") then
+ c = c + 1
+ word = word .. sln.char(word_start.char)
+ end
+ end
+ word_start = word_start.next
+ end
+ if thisbreakpoint then
+ word_with_hyphen = sln.sub(word,1,thisbreakpoint) .. "-" .. sln.sub(word,thisbreakpoint+1,-1)
+ -- word with hyphen has all possible hyphenation points
+ luacheckhyphen.hyphenwords[hyphencounter] = word_with_hyphen
+ hyphencounter = #luacheckhyphen.hyphenwords + 1
+ end
+ end
+ head = head.next
+ end
+ return true
+end
+
+-- Remove '-' from word
+local function removedash( word )
+ local ret = sln.gsub(word,"-","")
+ return ret
+end
+
+luacheckhyphen.check_discs = function (head,parent)
+ local c
+ local word
+ local tmp
+ while head do
+ if head.id < 2 then -- a box, recurse
+ luacheckhyphen.check_discs(head.list,head)
+ -- package luashowhyphens has disc-whatsit-rightskip, without luashowhyphens it is disc-rightskip
+ elseif head.id == a_disc_node and head.next and head.next.id == a_glue_node and head.next.subtype == subtype_rightskip or
+ head.id == a_disc_node and head.next and head.next.next and head.next.id == a_whatsit_node and head.next.next.id == a_glue_node and head.next.next.subtype == subtype_rightskip then
+ c = node.has_attribute(head,hyphenattr)
+ word = sln.lower(luacheckhyphen.hyphenwords[c])
+ if luacheckhyphen.word_whitelist[word] then
+ -- word found, but OK (whitelisted)
+ else
+ if luachekchyphen.compact == nil or luachekchyphen.compact == "true" then
+ local word_without_hyphen = removedash(word)
+ local tmp = luacheckhyphen.all_hyphenatedwords[word_without_hyphen] or {}
+ tmp[word] = true
+ luacheckhyphen.all_hyphenatedwords[word_without_hyphen] = tmp
+ else
+ luacheckhyphen.all_hyphenatedwords[word] = true
+ end
+ if luacheckhyphen.drawmarks then
+ tmp = node.copy(luacheckhyphen.rectangle)
+ node.insert_after(parent,head,tmp)
+ end
+ end
+ end
+ head = head.next
+ end
+ return true
+end
+
+-- http://www.lua.org/pil/19.3.html
+local function pairsByKeys (t)
+ local a = {}
+ for n in pairs(t) do table.insert(a, n) end
+ table.sort(a)
+ local i = 0 -- iterator variable
+ local iter = function () -- iterator function
+ i = i + 1
+ if a[i] == nil then return nil
+ else return a[i], t[a[i]]
+ end
+ end
+ return iter
+end
+
+local function getUhyFilename (tex_jobname)
+ local unknown_hyphenation_filename = tex_jobname .. ".uhy"
+ local i = 1
+ local FLAG = '-output-directory'
+ while (arg[i] ~= nil) do
+ local argument = arg[i]
+ if (string.sub(argument, 2, 2) == '-' ) then
+ argument = string.sub(argument, 2)
+ end
+ if (string.sub(argument, 1, string.len(FLAG)) == FLAG) then
+ local prefix = nil
+ if (string.sub(argument, string.len(FLAG)+1, string.len(FLAG)+1) == '=') then
+ prefix = string.sub(argument, string.len(FLAG)+2)
+ else
+ prefix = arg[i+1]
+ end
+ unknown_hyphenation_filename = prefix .. "/" .. unknown_hyphenation_filename
+ break
+ end
+ i = i + 1
+ end
+ return unknown_hyphenation_filename
+end
+
+luacheckhyphen.listhyphenatedwords = function()
+ if luacheckhyphen.final == "true" then
+ return
+ end
+ -- don't write if the use has turned that off!
+ if not luacheckhyphen.nofile then
+ local unknown_hyphenation_filename = getUhyFilename(tex.jobname)
+ local unknown_hyphenation_file = io.open(unknown_hyphenation_filename,"w")
+ for k,v in pairsByKeys(luacheckhyphen.all_hyphenatedwords) do
+ if luachekchyphen.compact == "true" or luachekchyphen.compact == nil then
+ local hyphenationlist = {}
+ local hyphenpos = {}
+ for l,_ in pairs(v) do
+ local tmp = string.find(l,"-")
+ if tmp then
+ hyphenpos[#hyphenpos + 1] = tmp
+ end
+ hyphenationlist[#hyphenationlist + 1] = l
+ end
+ table.sort(hyphenpos)
+ local word_with_all_hyphenationpoints = {}
+ local cur = 1
+ for i=1,string.len(k) do
+ if hyphenpos[cur] == i then
+ word_with_all_hyphenationpoints[#word_with_all_hyphenationpoints + 1] = "-"
+ cur = cur + 1
+ end
+ word_with_all_hyphenationpoints[#word_with_all_hyphenationpoints + 1] = string.sub(k,i, i)
+ end
+ unknown_hyphenation_file:write(table.concat(word_with_all_hyphenationpoints,"") .. "\n")
+ else
+ unknown_hyphenation_file:write(k .. "\n")
+ end
+ end
+ unknown_hyphenation_file:close()
+ end
+
+ texio.write_nl("log","All words with unknown hyphenation below")
+ for k,v in pairs(luacheckhyphen.all_hyphenatedwords) do
+ texio.write_nl("log",k)
+ end
+end
+
+luacheckhyphen.enable = function()
+ if luacheckhyphen.final == "true" then
+ return
+ end
+ local whitelistfile,err
+ local filecontents
+ if luacheckhyphen.whitelist then
+ for i,v in ipairs(string.explode(luacheckhyphen.whitelist,",")) do
+ whitelistfile,err = io.open(v)
+ if not whitelistfile then
+ if err then
+ texio.write_nl(err)
+ else
+ texio.write_nl(string.format("White list %q not found, ignored.",tostring(v)))
+ end
+ else
+ filecontents = whitelistfile:read("*a")
+ for _,entry in ipairs(explode(filecontents,"[^%s]+")) do
+ parts = string.explode(entry,"-")
+ if #parts > 2 then
+ local c = 1
+ for c=1,#parts - 1 do
+ local word = {}
+ for i=1,#parts do
+ word[#word + 1] = parts[i]
+ if i == c then
+ word[#word + 1] = "-"
+ end
+ end
+ luacheckhyphen.word_whitelist[table.concat(word,"")] = true
+ end
+ else
+ luacheckhyphen.word_whitelist[entry] = true
+ end
+ end
+ end
+ end
+ end
+ if luacheckhyphen.mark == "true" then
+ luacheckhyphen.drawmarks = true
+ end
+ luatexbase.add_to_callback("pre_linebreak_filter", luacheckhyphen.collect_discs,"collect_discs")
+ luatexbase.add_to_callback("post_linebreak_filter",luacheckhyphen.check_discs,"check_discs")
+end
+
+return luacheckhyphen
+
+-- end of file
diff --git a/macros/luatex/latex/lua-check-hyphen/lua-check-hyphen.sty b/macros/luatex/latex/lua-check-hyphen/lua-check-hyphen.sty
new file mode 100644
index 0000000000..933694871a
--- /dev/null
+++ b/macros/luatex/latex/lua-check-hyphen/lua-check-hyphen.sty
@@ -0,0 +1,44 @@
+% Copyright 2012–2017 Patrick Gundlach (patrick@gundla.ch)
+% Public repository: https://github.com/pgundlach/lua-check-hyphen
+% Licensed under the MIT license. See the file 'mit-license.txt' for exact terms.
+
+% Don't change these two lines, they are updated automatically
+\def\luachekchyphenpkgdate{2018/04/19}
+\def\luachekchyphenversion{0.7a}
+
+
+\RequirePackage{ifluatex}
+\RequirePackage{luatexbase}
+\RequirePackage{keyval}
+
+\DeclareOption{final}{\setkeys{luacheckhyphen}{final}}
+\DeclareOption{nofile}{\setkeys{luacheckhyphen}{nofile}}
+
+\DeclareOption*{\setkeys{luacheckhyphen}{\CurrentOption}}
+
+\ProvidesPackage{lua-check-hyphen}[\luachekchyphenpkgdate\space v\luachekchyphenversion\space Hyphenation checking for LuaTeX (PGU)]
+
+
+
+\def\luachekchyphendothings{\directlua{luachekchyphen.enable() }}
+
+\define@key{luacheckhyphen}{nofile}[true]{\directlua{luachekchyphen.nofile = "\luaescapestring{#1}"}}
+\define@key{luacheckhyphen}{compact}[true]{\directlua{luachekchyphen.compact = "\luaescapestring{#1}"}}
+\define@key{luacheckhyphen}{final}[true]{\directlua{luachekchyphen.final = "\luaescapestring{#1}"}}
+\define@key{luacheckhyphen}{mark}[true]{\directlua{luachekchyphen.mark = "\luaescapestring{#1}"}}
+\define@key{luacheckhyphen}{whitelist}{\directlua{luachekchyphen.whitelist = "\luaescapestring{#1}"}}
+
+
+\ifluatex
+ \AtBeginDocument{\luachekchyphendothings}
+ \directlua{luachekchyphen = require('lua-check-hyphen')}
+ \def\LuaCheckHyphen#1{\setkeys{luacheckhyphen}{#1}}
+ \AtEndDocument{\directlua{luachekchyphen.listhyphenatedwords()}}
+\else
+ \def\LuaCheckHyphen#1{}
+ \message{Warning: lua-check-hyphen only works with LuaTeX (LaTeX format for now)}
+\fi
+
+\ProcessOptions
+
+
diff --git a/macros/luatex/latex/luabibentry/Makefile b/macros/luatex/latex/luabibentry/Makefile
new file mode 100644
index 0000000000..6de822e698
--- /dev/null
+++ b/macros/luatex/latex/luabibentry/Makefile
@@ -0,0 +1,100 @@
+#This Makefile is a modified version of luacode's Makefile
+#
+#Changes
+# * "NAME" field: luacode -> luabibentry
+# * check target also calls BibTeX and re-runs lualatex
+# * use of pdflatex instead of latexmk to build documentation
+# * added LUA
+
+NAME = luabibentry
+FORMAT = lualatex
+
+DTX = $(NAME).dtx
+DOC = $(NAME).pdf
+STY = $(NAME).sty
+LUA = $(NAME).lua
+TEST = test-$(NAME).tex
+
+UNPACKED = $(STY) $(TEST)
+GENERATED = $(UNPACKED) $(DOC)
+SOURCES = $(DTX) README News Makefile
+
+SRCFILES = $(DTX) Makefile
+DOCFILES = $(DOC) README News
+RUNFILES = $(STY) $(LUA)
+ALL = $(SRCFILES) $(DOCFILES) $(RUNFILES)
+
+#TEXMFROOT = ./texmf
+RUNDIR = $(TEXMFROOT)/tex/$(FORMAT)/$(NAME)
+DOCDIR = $(TEXMFROOT)/doc/$(FORMAT)/$(NAME)
+SRCDIR = $(TEXMFROOT)/source/$(FORMAT)/$(NAME)
+
+CTAN_ZIP = $(NAME).zip
+TDS_ZIP = $(NAME).tds.zip
+ZIPS = $(CTAN_ZIP) $(TDS_ZIP)
+
+all: $(GENERATED)
+doc: $(DOC)
+unpack: $(UNPACKED)
+ctan: check $(CTAN_ZIP)
+tds: $(TDS_ZIP)
+world: ctan
+
+.PHONY: all doc unpack ctan tds check world
+
+%.pdf: %.dtx
+ pdflatex -interaction=batchmode $< >/dev/null
+ pdflatex -interaction=batchmode $< >/dev/null
+
+$(UNPACKED): $(DTX)
+ tex -interaction=batchmode $< >/dev/null
+
+check: $(UNPACKED)
+ lualatex -interaction=batchmode $(TEST) >/dev/null
+ bibtex $(TEST) >/dev/null
+ lualatex -interaction=batchmode $(TEST) >/dev/null
+
+$(CTAN_ZIP): $(DOC) $(SOURCES) $(TDS_ZIP)
+ @echo "Making $@ for CTAN upload."
+ @$(RM) -- $@
+ @zip -9 -q $@ $^
+
+define run-install
+@mkdir -p $(RUNDIR) && cp $(RUNFILES) $(RUNDIR)
+@mkdir -p $(DOCDIR) && cp $(DOCFILES) $(DOCDIR)
+@mkdir -p $(SRCDIR) && cp $(SRCFILES) $(SRCDIR)
+endef
+
+$(TDS_ZIP): TEXMFROOT=./tmp-texmf
+$(TDS_ZIP): $(ALL)
+ @echo "Making TDS-ready archive $@."
+ @$(RM) -- $@
+ @if test -e $(TEXMFROOT); then echo 'bad TEXMFROOT'; false; fi
+ $(run-install)
+ @cd $(TEXMFROOT) && zip -q -9 ../$@ -r .
+ @$(RM) -r -- $(TEXMFROOT)
+
+.PHONY: install clean mrproper help
+
+install: check $(ALL)
+ @echo "Installing in '$(TEXMFROOT)'."
+ $(run-install)
+
+clean:
+ @latexmk -silent -c $(DTX) >/dev/null
+ @rm -f -- test-*.log test-*.aux test-*.pdf
+
+mrproper: clean
+ @rm -f -- $(GENERATED) $(ZIPS)
+
+help:
+ @echo '$(NAME) makefile targets:'
+ @echo ' help - (this message)'
+ @echo ' all - (default target) all generated files'
+ @echo ' world - synonymous for ctan'
+ @echo ' unpack - extract all files'
+ @echo ' doc - compile documentation'
+ @echo ' ctan - run check & generate archive for CTAN'
+ @echo ' tds - generate a TDS compliant archive'
+ @echo ' check - run the test files'
+ @echo ' install TEXMFROOT=<path> - install in <path>'
diff --git a/macros/luatex/latex/luabibentry/News b/macros/luatex/latex/luabibentry/News
new file mode 100644
index 0000000000..dac29cbb37
--- /dev/null
+++ b/macros/luatex/latex/luabibentry/News
@@ -0,0 +1,6 @@
+2012/02/02 - v0.1a
+ * luabibentry.lua is now found in the lua search path.
+ * Replaced dofile by require as suggested by Ulrike Fischer.
+
+2011/06/27 - v0.1
+ * Initial version
diff --git a/macros/luatex/latex/luabibentry/README b/macros/luatex/latex/luabibentry/README
new file mode 100644
index 0000000000..b7f1c914fe
--- /dev/null
+++ b/macros/luatex/latex/luabibentry/README
@@ -0,0 +1,45 @@
+LuaLaTeX package luabibentry v0.1a, 2012-02-02.
+Copyright (c) Oliver Kopp, 2012
+
+Summary
+-------
+luabibentry is a reimplementation of bibentry.sty by Patrick W. Daly.
+It provides the command \bibentry{<BibTeXKey>} to print the
+bibliographic entry in the main document.
+
+
+Generating the package
+----------------------
+To produce the package and the manual from `luabibentry.dtx' you have to run
+
+ tex luaindex.dtx
+and pdflatex luaindex.dtx
+
+or make all
+
+
+Installation
+------------
+Distributors should save
+ luabibentry.lua as TDS:luatex/luabibentry/luabibentry.lua and
+ luabibentry.sty as TDS:luatex/luabibentry/luabibindex.sty.
+
+A TDS-friendly .zip can be obtained by "make tds"
+
+
+License
+-------
+This file is part of the LuaLaTex package `luabibentry'.
+
+This work may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, version 1.3c of the license.
+The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+and version 1.3c or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+This work has the LPPL maintenance status "maintained".
+
+The Current Maintainer and author of this work is Oliver Kopp.
+
+This work consists of the files `luabibentry.dtx' and `README'.
diff --git a/macros/luatex/latex/luabibentry/luabibentry.dtx b/macros/luatex/latex/luabibentry/luabibentry.dtx
new file mode 100644
index 0000000000..55db6496d7
--- /dev/null
+++ b/macros/luatex/latex/luabibentry/luabibentry.dtx
@@ -0,0 +1,401 @@
+% \iffalse meta-comment
+% ==========================================================================
+% luabibentry.dtx v0.1a, 2012/02/02
+% Copyright (c) Oliver Kopp, 2012
+%
+% This file is part of the LuaLaTex package `luabibentry'.
+%
+% This work may be distributed and/or modified under the conditions of
+% the LaTeX Project Public License, version 1.3c of the license.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status "maintained".
+%
+% The Current Maintainer and author of this work is Oliver Kopp.
+%
+% This work consists of the files `luabibentry.dtx' and `README'.
+%
+% Unpacking:
+% tex luabibentry.dtx
+% Documentation:
+% pdflatex luacode.dtx
+% ==========================================================================
+%
+%<*ignore>
+\begingroup
+ \def\x{LaTeX2e}%
+\expandafter\endgroup
+\ifcase 0\ifx\install y1\fi\expandafter
+ \ifx\csname processbatchFile\endcsname\relax\else1\fi
+ \ifx\fmtname\x\else 1\fi\relax
+\else\csname fi\endcsname
+%</ignore>
+%<*install>
+\input docstrip.tex
+\keepsilent
+\askforoverwritefalse
+{
+\obeyspaces\obeylines
+\global\def\preambletext{
+\space
+Copyright (c) 2012 by Oliver Kopp <oliver.kopp.googlemail.com>
+
+This file was generated from file(s) of luabibentry distribution.
+-----------------------------------------------------------------
+
+This work may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, version 1.3c of the license.
+The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+and version 1.3c or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+This work has the LPPL maintenance status "maintained".
+
+The Current Maintainer and author of this work is Oliver Kopp.
+
+This file may only be distributed together with the files listed in
+`luabibentry.dtx'. You may however distribute the files listed in
+`luabibentry.dtx' without this file.
+}
+\global\def\stypreambletext{
+\preambletext
+Usage:
+
+\string\setupbibentry{<bibliography>} before the usage of \string\bibentry.
+\string\setupbibentry{\string\jobname} may be used if the bibliography has the same name as the .tex file.
+
+\string\bibentry{<entry>} where you want to have placed an entry.
+In case an entry is not found "?" is output
+}
+}
+%
+\expandafter\preamble
+\preambletext
+\endpreamble
+%
+\declarepreamble\stypreamble
+\stypreambletext
+\endpreamble
+%
+\def\BibTeXComment{@Comment }
+\let\MetaPrefix\BibTeXComment
+\declarepreamble\bibpreamble
+\preambletext
+\endpreamble
+%
+\def\ThreeHyphens{---}
+\let\MetaPrefix\ThreeHyphens
+%
+\expandafter\declarepreamble\expandafter\luapreamble
+\preambletext
+\endpreamble
+
+\generate{%
+ \let\MetaPrefix\DoubleperCent
+ \usepreamble\defaultpreamble
+ \file{test-luabibentry.tex}{\from{luabibentry.dtx}{testlatex}}%
+%
+ \let\MetaPrefix\DoubleperCent
+ \usepreamble\stypreamble
+ \file{luabibentry.sty}{\from{luabibentry.dtx}{package}}%
+%
+ \let\MetaPrefix\BibTeXComment
+ \usepreamble\bibpreamble
+ \nopostamble
+ \file{test-luabibentry.bib}{\from{luabibentry.dtx}{testbibtex}}%
+%
+ \let\MetaPrefix\ThreeHyphens
+ \usepreamble\luapreamble
+ \nopostamble
+ \file{luabibentry.lua}{\from{luabibentry.dtx}{lua}}%
+}
+{
+\obeyspaces
+\Msg{************************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* files into a directory searched by TeX:}
+\Msg{*}
+\Msg{* luabibentry.sty and luabibentry.lua}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+}
+
+%\csname endinput\endcsname
+\endbatchfile
+%</install>
+%<package>\NeedsTeXFormat{LaTeX2e}[1995/06/01]
+%<package>\ProvidesPackage{luabibentry}
+%<driver>\ProvidesFile{luaindex.dtx}
+%<*driver|package>
+[2012/02/02 v0.1a LuaLaTeX Package to place bibliography entries in text]
+%</driver|package>
+%<lua>if (luatexbase and (luatexbase.provides_module)) then
+%<lua> luatexbase.provides_module({
+%<lua> name = "luabibentry",
+%<lua> date = "2012/02/02",
+%<lua> version = "0.1a",
+%<lua> description = "LuaLaTeX Package to Place Bibliography Entries in Text",
+%<lua> author = "Oliver Kopp",
+%<lua> licence = "LPPL v1.3c or later"
+%<lua> })
+%<lua>end
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\documentclass[oneside,DIV=16,BCOR=0cm,parskip=half]{scrdoc}
+\usepackage[english]{babel}
+\usepackage{hyperref}
+\providecommand*{\LuaLaTeX}{Lua\kern-.025em\LaTeX}
+\CodelineIndex
+\RecordChanges
+\GetFileInfo{luabibentry.ltx}
+\title{%
+ The \texttt{luabibentry} package
+}
+%\date{\fileversion} %currently doesn't work
+\date{Version 0.1a as of 2012/02/02}
+\author{Oliver Kopp\thanks{oliver.kopp%
+@%
+googlemail%
+.%
+com}}
+\begin{document}
+\maketitle
+\DocInput{luabibentry.dtx}
+\end{document}
+%</driver>
+%\fi^^A meta-comment
+%
+% \changes{v0.1}{2011/06/27}{start of new package}
+% \changes{v0.1a}{2012/02/02}{fixed lua code to use `require' instead of `dofile'.}
+%
+% \begin{abstract}
+% Typically, bibliographic entries are put at the end of a document. This
+% package allows for \emph{repeating} bibliographic entries in the document itself. The package
+% is inspired by bibentry, which provides similar functionality for \LaTeX{}.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Introduction}
+% This package allows one to place bibliographic entries anywhere
+% in the text. It is to be used to produce annotated bibliographies, such as
+% \begin{quote}
+% For an intoduction to the topic of workflow management, see
+% Frank Leymann and Dieter Roller. {\it Production Workflow -- Concepts and Techniques}.
+% Prentice Hall PTR, 2000.
+% \end{quote}
+%
+% The idea is that the full reference is used, not just the citation [1] or
+% Leymann and Roller [2000].
+%
+% This package is a variant of bibentry.sty by Patrick W.\ Daly. bibentry.sty is
+% distributed with the natbib
+% package\footnote{\url{http://mirror.ctan.org/macros/latex/contrib/natbib/}}. This
+% documentation of luabibentry is mostly adapted from Patrick's documentation of
+% bibentry. bibentry itself is part of the natbib package.
+%
+% The main reason for the reimplementation is the incompatibility of hyperref's
+% backref with bibenetry.sty. The \texttt{\textbackslash saved \makeatletter
+% @\makeatother bibitem} solution did not work here.
+%
+% The differences to bibentry.sty is:
+% The commands |\nobibliography| and |\nobibliography*|
+% are unsupported. luabibentry always uses the bibliography of the
+% document.
+%
+% \section{Usage}
+% |\setupbibentry{<bibliography>}| before the usage of |\bibentry|.\\
+% |\setupbibentry{\jobname}| may be used if the bibliography has the same name as the |.tex| file.
+%
+% |\bibentry{<entry>}| where you want to have placed an entry.
+% In case an entry is not found, ``?'' is output.
+%
+% \section{Caveats}
+% The caveats of the entry format are similar to the bibentry package. The only
+% difference is that luabibentry expects the key as last token in the bibitem entry.
+% Thus, the following text is a verbatim copy of bibentry's documentation with the
+% reference to the allowed space after the key being removed.
+%
+% The entries in the \texttt{.bbl} must be of the form
+% \begin{quote}
+% |\bibitem|\oarg{label}\marg{key}\\
+% \emph{Text of the reference entry.}\\[1ex]
+% |\bibitem|\dots
+% \end{quote}
+% That is, there must be a new line after the \marg{key}
+% and a blank line before the next |\bibitem|. The final period in the text
+% will be removed, if present, allowing one to place the |\bibentry| commands
+% in mid-sentence. Of course, there may be other periods within the text that
+% might look funny.
+%
+% \section{Test}
+% A simple test whether luabibentry runs is provided here:
+%
+% \iffalse meta-comment
+%<*testlatex>
+% \fi
+% \begin{macrocode}
+\documentclass{article}
+\usepackage{luabibentry}
+\setupbibentry{\jobname}
+
+\usepackage[backref=page]{hyperref}
+
+\begin{document}
+
+The entry for \cite{LR2000} is: \bibentry{LR2000}.
+
+\bibliographystyle{plain}
+\bibliography{test-luabibentry}
+
+\end{document}
+% \end{macrocode}
+% \iffalse meta-comment
+%</testlatex>
+% \fi
+%
+% \iffalse meta-comment
+%<*testbibtex>
+% \fi
+% \begin{macrocode}
+@BOOK{LR2000,
+ title = {{P}roduction {W}orkflow -- {C}oncepts and {T}echniques},
+ publisher = {Prentice Hall PTR},
+ year = {2000},
+ author = {Frank Leymann and Dieter Roller},
+ isbn = {0130217530}
+}
+% \end{macrocode}
+% \iffalse meta-comment
+%</testbibtex>
+% \fi
+%
+% \section{Implementation of Lua Module \texttt{luabibentry.lua}}
+% \iffalse meta-comment
+%<*lua>
+% \fi^^A meta-comment
+% \begin{macrocode}
+module("luabibentry", package.seeall)
+require("lualibs-file")
+
+-- stores all entries
+local entries = {}
+
+-- builds the data by reading the given filename
+function builddata(filename)
+ -- Parameters seem to be passed as arrays.
+ -- We access the first element of the parameter to get the filename
+ local file = io.open(filename[1], "r")
+ if file==nil then
+ texio.write_nl("luabibentry: could not open file " .. filename[1])
+ return
+ end
+ local line = file:read("*line")
+ while (line~=nil) do
+ -- \bibitem is our marker for new entries
+ local i = string.find(line, "\\bibitem")
+ if i~=nil then
+ -- we expect the key in brackets in the same line
+ i = string.find(line,"{")
+ local lasti = 0
+ -- we jump to the last bracket
+ while i~= nil do
+ lasti = i
+ i = string.find(line,"{",i+1)
+ end
+ local key = string.sub(line, lasti+1)
+ -- we use the text from the last opening bracket ("{") until
+ -- the end of the line minus one
+ -- we expect nothing more to follow in this line
+ key = string.sub(key, 1, string.len(key)-1)
+ -- the next lines are the entry
+ -- we expect an entry to be finished with a blank line
+ -- (or the end of the file)
+ line = file:read("*line")
+ local entry = ""
+ while (line~=nil) and (line~="") do
+ entry = entry .. line
+ line = file:read("*line")
+ end
+ -- remove the final dot (if present)
+ local entryLen = string.len(entry)
+ local lastChar = string.sub(entry, entryLen, entryLen)
+ if lastChar == "." then
+ entry = string.sub(entry, 1, entryLen-1)
+ end
+ entries[key]=entry
+ end
+ line = file:read("*line")
+ end
+ file:close()
+end
+
+-- looks up the given key in the entries
+-- in case an entry is not found, a bold question mark is printed
+function bibentry(key)
+ local res = entries[key[1]]
+ if res==nil then
+ res = "\\textbf{?}"
+ end
+ tex.print(res)
+end
+
+% \end{macrocode}
+%
+% \iffalse meta-comment
+%</lua>
+% \fi^^A meta-comment
+
+% \section{Implementation of \LaTeX{} Package \texttt{luabibentry.sty}}
+%
+% \iffalse meta-comment
+%<*package>
+% \fi^^A meta-comment
+% \LuaLaTeX{} must be used to use the package.
+% \begin{macrocode}
+\RequirePackage{ifluatex}
+\ifluatex\else
+ \PackageError{luabibentry}{lualatex needed}{%
+ Package `luabibentry' needs LuaTeX.\MessageBreak
+ So you should use `lualatex' to process you document!\MessageBreak
+ See documentation of `luabibentry' for further information.}%
+ \expandafter\expandafter\expandafter\csname endinput\endcsname
+\fi
+% \end{macrocode}
+%
+% Load the lua module:
+% \begin{macrocode}
+\directlua{require("luabibentry.lua")}
+% \end{macrocode}
+%
+% Interface to the lua module:
+% \begin{macrocode}
+\newcommand{\setupbibentry}[1]{\directlua{luabibentry.builddata{"#1.bbl"}}}
+\newcommand{\bibentry}[1]{\nocite{#1}\directlua{luabibentry.bibentry{"#1"}}}
+% \end{macrocode}
+%
+% \iffalse meta-comment
+%</package>
+% \fi^^A meta-comment
+%
+% \section{Acknowledgements}
+% This package is a variant of |bibentry.sty| by Patrick W.\ Daly. |bibentry.sty| is
+% distributed with the |natbib| package. This documentation of luabibentry is
+% mostly adapted from Patrick's documentation of |bibentry|.
+%
+% Thanks to Markus Kohm for the dtx and lua inspirements, Manuel
+% P\'egouri\'e-Gonnard for the Makefile, dtx, and lua inspirements, and
+% Heiko Oberdiek for his detailed feedback on a draft version of this package.
+%
+% \Finale
+%
+\endinput
diff --git a/macros/luatex/latex/luabibentry/luabibentry.pdf b/macros/luatex/latex/luabibentry/luabibentry.pdf
new file mode 100644
index 0000000000..f5084e107e
--- /dev/null
+++ b/macros/luatex/latex/luabibentry/luabibentry.pdf
Binary files differ
diff --git a/macros/luatex/latex/luabidi/LICENCE.md b/macros/luatex/latex/luabidi/LICENCE.md
new file mode 100644
index 0000000000..7de4faf488
--- /dev/null
+++ b/macros/luatex/latex/luabidi/LICENCE.md
@@ -0,0 +1,6 @@
+# MIT Licence
+
+Copyright (c) Vafa Khalighi 2009, Arthur Reutenauer 2013, 2019, Jürgen Spitzmüller 2019.
+
+The licence for all files within this package is (the MIT
+licence)[https://opensource.org/licenses/MIT] unless otherwise noted.
diff --git a/macros/luatex/latex/luabidi/README.md b/macros/luatex/latex/luabidi/README.md
new file mode 100644
index 0000000000..f889e844c6
--- /dev/null
+++ b/macros/luatex/latex/luabidi/README.md
@@ -0,0 +1,8 @@
+# luabidi
+Luabidi is an attempt to offer the same functionality for LuaTeX as bidi
+does for XeTeX.
+
+## CTAN Package
+https://www.ctan.org/pkg/luabidi
+
+Copyright (c) Vafa Khalighi 2009, Arthur Reutenauer 2013, 2019, Jürgen Spitzmüller 2019
diff --git a/macros/luatex/latex/luabidi/doc/test.tex b/macros/luatex/latex/luabidi/doc/test.tex
new file mode 100644
index 0000000000..1b51109ad4
--- /dev/null
+++ b/macros/luatex/latex/luabidi/doc/test.tex
@@ -0,0 +1,13 @@
+\documentclass[12pt]{article}
+\usepackage[arabmaths]{luabidi}
+\begin{document}
+\setRTLmain
+\section{ghesmate 1}
+
+in yek ghesmat ast ke an ra dar inja minevisam
+
+\begin{equation}
+1+2=3
+\end{equation}
+in ham dobare masalei ast ke man minevisam va shoma an ra mibinid.
+\end{document}
diff --git a/macros/luatex/latex/luabidi/tex/arabmaths.tex b/macros/luatex/latex/luabidi/tex/arabmaths.tex
new file mode 100644
index 0000000000..e125dce795
--- /dev/null
+++ b/macros/luatex/latex/luabidi/tex/arabmaths.tex
@@ -0,0 +1,2 @@
+\mathdir TRT
+\def\@eqnnum{{\normalfont \normalcolor \textdir TLT ({\textdir TRT\theequation})}}
diff --git a/macros/luatex/latex/luabidi/tex/autofootnoterule.tex b/macros/luatex/latex/luabidi/tex/autofootnoterule.tex
new file mode 100644
index 0000000000..f770694652
--- /dev/null
+++ b/macros/luatex/latex/luabidi/tex/autofootnoterule.tex
@@ -0,0 +1,116 @@
+\ifx \CatEscape\undefined
+ \chardef\CatEscape=0
+ \chardef\CatOpen=1
+ \chardef\CatClose=2
+ \chardef\CatIgnore=9
+ \chardef\CatLetter=11
+ \chardef\CatOther=12
+ \chardef\CatActive=13 % is defined in Plain already
+
+ \chardef\CatUsCode=\catcode`\_
+\fi
+
+\catcode`\_=\CatLetter % top level macro file
+
+
+\def\l@fn{%
+ \hbox to \columnwidth
+ {\pagedir TLT\vbox{\kern -3\p@
+ \hrule width .4\columnwidth \kern2.6\p@}\hfil}}
+\def\r@fn{%
+ \hrule width .4\columnwidth\kern 2.6\p@}
+
+
+\def\@makefnmark{\hbox{$^{\hbox{\scriptsize\@thefnmark}}\m@th$}}
+
+
+\def\leftfootnoterule{\global\def\footnoterule{\l@fn}}
+\def\rightfootnoterule{\global\def\footnoterule{\r@fn}}
+\leftfootnoterule
+
+%%% \beginprog
+\newread\old_foot_file
+\newwrite\foot_file
+\def\foot_file_name{\jobname.fot\relax}
+\def\init_footnote{%
+ \openin\old_foot_file\foot_file_name
+ \ifeof\old_foot_file \closein\old_foot_file
+ \else \closein\old_foot_file
+ \read_foot_file
+ \fi
+ \immediate\openout\foot_file\foot_file_name
+ \immediate\write\foot_file{\relax}%
+ \global\let\init_footnote\relax
+ }
+
+\newcount\foot_name_no % for generating footnote mark names
+
+
+
+
+
+\newcount\autofootnote
+\def\fnpp_next_footnote{%
+ \init_footnote
+ \global\advance\foot_name_no\@ne
+ \global\advance\c@footnote\@ne
+ \edef\do_write{%
+ \immediate\write\foot_file{%
+ \string\advance\autofootnote\@ne
+ \string\expandafter\xdef
+ \string\csname\space f@\number\foot_name_no \endcsname{%
+ \string\number\autofootnote
+ }%
+ }%
+ }%
+ \do_write
+ \global\autofootnote 0\csname f@\number\foot_name_no \endcsname \relax
+ }
+
+\def\read_foot_file{%
+ \begingroup
+ \catcode`\@\CatLetter \catcode`\^^M\CatIgnore
+ \input \foot_file_name
+ \endgroup
+ }
+
+\let\fnpp_orig_outputpage=\@outputpage
+\def\@outputpage{%
+ \ifx \init_footnote\relax
+ \immediate\write\foot_file{\autofootnote\z@}%
+ \fi
+ \fnpp_orig_outputpage
+ }
+
+\let\FnppOrigFootnote=\footnote % save original bindings
+\let\FnppOrigFootnotemark=\footnotemark
+
+\def\footnote{%
+ \@ifnextchar[% % ] (Emacs)
+ \@xfootnote
+ {\fnpp_next_footnote \ifnum\autofootnote=1\rightfootnoterule\fi \@xfootnote[\the\c@footnote] %
+}%
+ }
+\def\footnotemark{%
+ \@ifnextchar[% % ] (Emacs)
+ \@xfootnotemark
+ {\fnpp_next_footnote \ifnum\autofootnote=1\rightfootnoterule\fi \@xfootnotemark[\the\c@footnote]}%
+ }
+
+
+
+
+\def\footnotemarkLR{%
+ \@ifnextchar[% % ] (Emacs)
+ \@xfootnotemark
+ {\fnpp_next_footnote \ifnum\autofootnote=1\leftfootnoterule\fi\@xfootnotemark[\the\c@footnote]}%
+ }
+
+
+\def\Footnote#1{%
+\begingroup
+\footnotemarkLR%
+\renewcommand{\thefootnote}{\@arabic\c@footnote}%
+\pardir TLT \textdir TLT\footnotetext{#1}%
+\endgroup
+}
diff --git a/macros/luatex/latex/luabidi/tex/luabidi.sty b/macros/luatex/latex/luabidi/tex/luabidi.sty
new file mode 100644
index 0000000000..abc1d2a936
--- /dev/null
+++ b/macros/luatex/latex/luabidi/tex/luabidi.sty
@@ -0,0 +1,56 @@
+%% This file is luabidi.sty
+%%
+%% Copyright © 2009 Vafa Khalighi, 2013--2019 Arthur Reutenauer, 2019 Jürgen Spitzmüller
+%%
+%%%% It may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{luabidi}[2019/08/24 v0.4
+ Bidirectional typesetting in LuaTeX]
+\newif\if@RTL
+\newif\if@RTLmain
+\def\setRTLmain{\pagedir TRT \bodydir TRT \pardir TRT \textdir TRT}
+\def\setRTL{\@RTLtrue\pardir TRT \textdir TRT}
+\let\setRL=\setRTL
+\def\setLTR{\@RTLfalse\pardir TLT \textdir TLT}
+\let\setLR=\setLTR
+\let\unsetRTL=\setLTR
+\let\unsetLTR=\setRTL
+\def\RTL{\@RTLtrue\trivlist \pardir TRT \textdir TRT\item\relax}
+\def\endRTL{\@RTLfalse\endtrivlist}
+\def\LTR{\trivlist \pardir TLT \textdir TLT\item\relax}
+\def\endLTR{\endtrivlist}
+\def\@ensure@RTL#1{\if@RTL#1\else\RLE{#1}\fi}
+\def\@ensure@LTR#1{\if@RTL\LRE{#1}\else{#1}\fi}
+\def\@ensure@dir#1{\if@RTL\RLE{#1}\else{#1}\fi}
+\let\@ensure@maindir=\@ensuredir
+\@RTLmainfalse
+\DeclareOption{arabmaths}{\input{arabmaths}}
+\DeclareOption{textwidthfootnoterule}{\input{textwidthfootnoterule}}
+\let\n@xt=\
+\DeclareRobustCommand*\LRE{\protect\pLRE}
+\def\pLRE{\protect\afterassignment\moreLRE \let\n@xt= }
+\DeclareRobustCommand*\RLE{\protect\pRLE}
+\def\pRLE{\protect\afterassignment\moreRLE \let\n@xt= }
+\def\bracetext{\ifcat\n@xt{\else\ifcat\n@xt}\fi
+ \errmessage{Missing left brace has been substituted}\fi \bgroup}
+\def\moreLRE{\bracetext \aftergroup\unsetLTR \setLTR\@RTLfalse}
+\def\moreRLE{\bracetext \aftergroup\unsetRTL \setRTL\@RTLtrue}
+\let\LR=\LRE
+\let\RL=\RLE
+
+\def\Footnote#1{%
+\begingroup
+\footnotemark
+\renewcommand{\thefootnote}{\@arabic\c@footnote}%
+\pardir TLT \textdir TLT\footnotetext{#1}%
+\endgroup
+}
+
+\DeclareOption{autofootnoterule}{\input{autofootnoterule}}
+
+
+
+\ProcessOptions
+\endinput
diff --git a/macros/luatex/latex/luabidi/tex/textwidthfootnoterule.tex b/macros/luatex/latex/luabidi/tex/textwidthfootnoterule.tex
new file mode 100644
index 0000000000..7fc71e0cef
--- /dev/null
+++ b/macros/luatex/latex/luabidi/tex/textwidthfootnoterule.tex
@@ -0,0 +1,2 @@
+\def\footnoterule{\kern-3\p@
+ \hrule \@width \textwidth \kern 2.6\p@}
diff --git a/macros/luatex/latex/luacode/Makefile b/macros/luatex/latex/luacode/Makefile
new file mode 100644
index 0000000000..dcc90a75a9
--- /dev/null
+++ b/macros/luatex/latex/luacode/Makefile
@@ -0,0 +1,90 @@
+NAME = luacode
+FORMAT = lualatex
+
+DTX = $(NAME).dtx
+DOC = $(NAME).pdf
+STY = $(NAME).sty
+TEST = test-$(NAME).tex
+TESTLOG = test-$(NAME).log
+
+UNPACKED = $(STY) $(TEST)
+GENERATED = $(UNPACKED) $(DOC)
+SOURCES = $(DTX) README News Makefile
+
+SRCFILES = $(DTX) Makefile
+DOCFILES = $(DOC) README News
+RUNFILES = $(STY)
+ALL = $(SRCFILES) $(DOCFILES) $(RUNFILES)
+
+TEXMFROOT = ./texmf
+RUNDIR = $(TEXMFROOT)/tex/$(FORMAT)/$(NAME)
+DOCDIR = $(TEXMFROOT)/doc/$(FORMAT)/$(NAME)
+SRCDIR = $(TEXMFROOT)/source/$(FORMAT)/$(NAME)
+
+CTAN_ZIP = $(NAME).zip
+TDS_ZIP = $(NAME).tds.zip
+ZIPS = $(CTAN_ZIP) $(TDS_ZIP)
+
+all: $(GENERATED)
+doc: $(DOC)
+unpack: $(UNPACKED)
+ctan: check $(CTAN_ZIP)
+tds: $(TDS_ZIP)
+world: ctan
+
+.PHONY: all doc unpack ctan tds check world
+
+%.pdf: %.dtx
+ latexmk -pdf -silent $< >/dev/null
+
+$(UNPACKED): $(DTX)
+ tex -interaction=batchmode $< >/dev/null
+
+check: $(UNPACKED)
+ lualatex -interaction=batchmode $(TEST) >/dev/null
+ ! grep 'blank space' $(TESTLOG)
+
+$(CTAN_ZIP): $(DOC) $(SOURCES) $(TDS_ZIP)
+ @echo "Making $@ for CTAN upload."
+ @$(RM) -- $@
+ @zip -9 -q $@ $^
+
+define run-install
+@mkdir -p $(RUNDIR) && cp $(RUNFILES) $(RUNDIR)
+@mkdir -p $(DOCDIR) && cp $(DOCFILES) $(DOCDIR)
+@mkdir -p $(SRCDIR) && cp $(SRCFILES) $(SRCDIR)
+endef
+
+$(TDS_ZIP): TEXMFROOT=./tmp-texmf
+$(TDS_ZIP): $(ALL)
+ @echo "Making TDS-ready archive $@."
+ @$(RM) -- $@
+ @if test -e $(TEXMFROOT); then echo 'bad TEXMFROOT'; false; fi
+ $(run-install)
+ @cd $(TEXMFROOT) && zip -q -9 ../$@ -r .
+ @$(RM) -r -- $(TEXMFROOT)
+
+.PHONY: install clean mrproper help
+
+install: check $(ALL)
+ @echo "Installing in '$(TEXMFROOT)'."
+ $(run-install)
+
+clean:
+ @latexmk -silent -c $(DTX) >/dev/null
+ @rm -f -- test-*.log test-*.aux test-*.pdf
+
+mrproper: clean
+ @rm -f -- $(GENERATED) $(ZIPS)
+
+help:
+ @echo '$(NAME) makefile targets:'
+ @echo ' help - (this message)'
+ @echo ' all - (default target) all generated files'
+ @echo ' world - synonymous for ctan'
+ @echo ' unpack - extract all files'
+ @echo ' doc - compile documentation'
+ @echo ' ctan - run check & generate archive for CTAN'
+ @echo ' tds - generate a TDS compliant archive'
+ @echo ' check - run the test files'
+ @echo ' install TEXMFROOT=<path> - install in <path>'
diff --git a/macros/luatex/latex/luacode/News b/macros/luatex/latex/luacode/News
new file mode 100644
index 0000000000..74a12418f7
--- /dev/null
+++ b/macros/luatex/latex/luacode/News
@@ -0,0 +1,13 @@
+2012/01/23 v1.2a
+ * fix spurious space
+ * clarify doc about backslashes and Lua strings (sugg. by Herbert)
+
+2011/12/29 v1.2
+ * new helper macros \luastring, \luastringO, \luastringN
+ * new debug (logging) feature
+
+2011/05/24 v1.1
+ * compatibility with luatexbase 0.4
+
+2010/11/08 v1.0
+ * initial version
diff --git a/macros/luatex/latex/luacode/README b/macros/luatex/latex/luacode/README
new file mode 100644
index 0000000000..6b5ad9e94c
--- /dev/null
+++ b/macros/luatex/latex/luacode/README
@@ -0,0 +1,43 @@
+ The luacode package for LuaLaTeX
+
+
+Executing Lua code from within TeX with \directlua can sometimes be
+tricky: there is no easy way to use the percent character, counting
+backslashes may be hard, and Lua comments don't work the way you expect.
+This package provides the \luaexec command and the luacode(*)
+environments to help with these problems.
+
+For an introduction to the most important gotchas of \directlua, see
+lualatex-doc.pdf. Before you start using the tools in this package, let me
+insist that the most robust way to manage a non-trivial piece of Lua code is
+to use an external file and source it from Lua, as explained in the cited
+document.
+
+
+Installation
+------------
+
+Here are the recommended installation methods (preferred first).
+
+1. If you are using TeX Live 2008 or later, use 'tlmgr install luacode'.
+If your are using MiKTeX, use the MiKTeX Package Manager.
+Alternatively, try you Linux distribution's package management system.
+
+2. a. Grab luacode.tds.zip on the CTAN.
+ b. Unzip it at the root of one or your TDS trees.
+ c. You may need to update some filename database after this, see your TeX
+ distribution's manual for details. (Hint: with TeX Live, run 'mktexlsr';
+ with MikTeX, look for "Refresh FNDB" in the MikTeX menu.)
+
+3. a. Grab the sources from CTAN or github.
+ b. Run 'make install TEXMFROOT=/path/to/texmf'.
+ (Warning: 'make install' without giving a TEXMFROOT will
+ put files in './texmf', which is probably not what you want.)
+ c. See 2c.
+
+
+Licence
+-------
+
+This package is distributed under the terms of the LPPL v1.3c or later.
+See the source file luacode.dtx for details.
diff --git a/macros/luatex/latex/luacode/luacode.dtx b/macros/luatex/latex/luacode/luacode.dtx
new file mode 100644
index 0000000000..def0572f7c
--- /dev/null
+++ b/macros/luatex/latex/luacode/luacode.dtx
@@ -0,0 +1,723 @@
+% \iffalse meta-comment (by the way, this file is contains UTF-8)
+%
+% Written in 2010, 2011 by Manuel Pégourié-Gonnard <mpg@elzevir.fr>
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Manuel Pégourié-Gonnard
+%
+% This work consists of the main source file luacode.dtx
+% and the derived files
+% luacode.sty luacode.pdf
+%
+% Unpacking:
+% tex luacode.dtx
+% Documentation:
+% pdflatex luacode.dtx
+%
+%<*ignore>
+\begingroup
+ \def\x{LaTeX2e}%
+\expandafter\endgroup
+\ifcase 0\ifx\install y1\fi\expandafter
+ \ifx\csname processbatchFile\endcsname\relax\else1\fi
+ \ifx\fmtname\x\else 1\fi\relax
+\else\csname fi\endcsname
+%</ignore>
+%<*install>
+\input docstrip.tex
+
+\keepsilent
+\askforoverwritefalse
+
+\preamble
+
+See the source file for author and licensing information.
+
+\endpreamble
+
+\generate{%
+ \usedir{tex/lualatex/luacode}%
+ \file{luacode.sty}{\from{luacode.dtx}{texpackage}}%
+}
+
+\generate{%
+ \usedir{doc/lualatex/luacode}%
+ \file{test-luacode.tex}{\from{luacode.dtx}{testlatex}}%
+}
+
+\obeyspaces
+\Msg{************************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* files into a directory searched by TeX:}
+\Msg{*}
+\Msg{* luacode.sty}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{textcomp}
+\usepackage{lmodern}
+\usepackage{fixltx2e, mparhack}
+
+\usepackage{xcolor}
+\usepackage{booktabs}
+\usepackage{xspace}
+\usepackage[a4paper]{geometry}
+\usepackage[english]{babel}
+\usepackage[colorlinks]{hyperref}
+\usepackage{bookmark}
+
+\newcommand*\email [1] {<\href{mailto:#1}{#1}>}
+\newcommand \file {\nolinkurl}
+\newcommand \pk {\textsf}
+\newcommand \cmdname {\texttt}
+
+\pdfstringdefDisableCommands{%
+ \def\cs#1{\@backslashchar #1}}
+
+\MakeShortVerb\|
+\renewcommand\MacroFont{\ttfamily\small\color{blue}}
+
+\begin{document}
+ \DocInput{luacode.dtx}%
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{0}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+% \title{The \pk{luacode} package}
+% \author{Manuel P\'egouri\'e-Gonnard \email{mpg@elzevir.fr}}
+% \date{v1.2a 2012/01/23}
+%
+% \maketitle
+%
+% \begin{abstract}
+% Executing Lua code from within \TeX\ with |\directlua| can sometimes be
+% tricky: there is no easy way to use the percent character, counting
+% backslashes may be hard, and Lua comments don't work the way you expect.
+% This package provides the |\luaexec| command and the |luacode(*)|
+% environments to help with these problems, as well as helper macros and a
+% debugging mode.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Documentation}
+%
+% \subsection{Lua code in \LaTeX}
+%
+% For an introduction to the most important gotchas of |\directlua|, see
+% \file{lualatex-doc.pdf}. Before presenting the tools in this package, let me
+% insist that the best way to manage a non-trivial piece of Lua code is
+% probably to use an external file and source it from Lua, as explained in the
+% cited document.
+%
+% \medskip
+%
+% \DescribeMacro\luadirect
+% First, the exact syntax of |\directlua| has changed along version of
+% Lua\TeX, so this package provides a |\luadirect| command which is an exact
+% synonym of |\directlua| except that it doesn't have the funny, changing
+% parts of its syntax, and benefits from the debugging facilities described
+% below (\ref{dbg}).\footnote{And expands in two steps instead of one. If
+% you don't know what it means, then you hopefully don't need to.}
+%
+% The problems with |\directlua| (or |\luadirect|) are mainly with \TeX\
+% special characters. Actually, things are not that bad, since most special
+% characters do work, namely: |_|, |^|, |&|, \verb+$+, |{|, |}|. Three are a
+% bit tricky but they can be managed with |\string|: |\|, |#| and |~|. Only
+% |%| is really hard to obtain. Also, \TeX\ macros are expanded, which is good
+% since it allows to pass information from \TeX\ to Lua, but you must be
+% careful and use only purely expandable macros.
+%
+% \DescribeMacro\luaexec
+% The |\luaexec| command is similar to |\luadirect| but with a few additional
+% features:\footnote{And one major drawback: it is not purely expandable. See
+% previous note.} |\\| gives a double backslash (see note below)
+% |\%| a percent character, and |~| just works. For single backslashes,
+% |\string| is still needed. Also, \TeX\ macros are expanded.
+%
+% \DescribeEnv{luacode}
+% The |luacode| environment is similar to |\luaexec|, except that you can now
+% use |%| and |#| directly (but |\%| and |\#| also work) and the line breaks
+% are respected, so that you can use line-wise Lua comments in the normal way,
+% without mistakenly commenting the rest of the chunk.
+%
+% Only the backslash and the braces keep their special meaning, so that macros
+% still work as usual, and you still need to use |\string| to get a single
+% backslash.
+%
+% \DescribeEnv{luacode*}
+% The variant |luacode*| goes further and makes even backslash a normal
+% character, so that you don't need any trick to obtain a single backslash. On
+% the other end, macros don't work any more. So, the content of a |luacode*|
+% is interpreted exactly as if it were in a normal Lua file, directly fed to
+% the Lua interpreter without any \TeX\ intervention.
+%
+% \medskip
+%
+% The following table summarizes how to use special characters with the
+% various commands and environments.
+%
+% \begin{center}
+% \begin{tabular}{rcccc}
+% \toprule
+% & |\luadirect| & |\luaexec| & |luacode| & |luacode*| \\
+% \midrule
+% Macros & Yes & Yes & Yes & No \\
+% Single backslash & |\string\| & |\string\| & |\string\| & Just |\| \\
+% Double backslash & |\string\\| & |\\| & |\\| & |\\| \\
+% Tilde & |\string~| & |~| & |~| & |~| \\
+% Sharp & |\string#| & |\#| & |#| (or |\#|) & |#| \\
+% Percent & No easy way & |\%| & |%| (or |\%|) & |%| \\
+% \TeX\ comments & Yes & Yes & No & No \\
+% Lua line comments & No & No & Yes & Yes \\
+% \bottomrule
+% \end{tabular}
+% \end{center}
+%
+% \noindent\textbf{Backslashes and Lua strings.}
+% In the table and descriptions above, ``double backslash'' means that the Lua
+% interpreter will see a double backslash. It may then turn it into a single
+% backslash in the context of a Lua string delimited by single or double quotes
+% as opposed to a Lua string delimited by brackets, see
+% \href{http://www.lua.org/pil/2.4.html}{\emph{Programming in Lua} section
+% 2.4}. Similarly, a single backslash may or may not be interpreted as
+% starting an escape sequence. For example:
+% \begin{verbatim}
+% \begin{luacode}
+% a = "\\" -- a contains a single backslash
+% b = [[\\]] -- b contains two backslashes
+% c = "\\\\" -- c contains two backslashes too
+% d = "line one\nline two" -- d contains a newline character
+% e = [[single\nline]] -- e contains no newline character
+% \end{luacode}
+% \end{verbatim}
+% The alert reader may notice that in the case of |\luadirect| and |\luaexec|,
+% single backslashes are a bit weird. For example with
+% \begin{verbatim}
+% \luaexec{texio.write_nl("line one\string\nline two")}
+% \end{verbatim}
+% \TeX\ will see |\nline| as a control sequence which is the ``argument'' of
+% |\string| and the Lua interpreter will consider only |\n| as an escape
+% sequence, and |line| as independent characters. In practice, this should not
+% have any unwanted consequences (except perhaps on the sanity of the reader).
+%
+% \medskip
+%
+% \noindent\textbf{Technical notes on environments.}
+% \DescribeEnv{luacodestar}
+% The environments will not work inside the argument of a command (just as
+% with verbatim commands and environments). Also, you are supposed to leave a
+% space (or end-of-line) after the |\begin{luacode}| or |\begin{luacode*}|,
+% which is probably a natural thing to do anyway. Finally, if you wish to
+% define derived environments, you'll need to use |\luacode| \dots
+% |\endluacode| instead of the usual |\begin| |\end| pair in your
+% environment's definition. For the stared variant, use |\luacodestar| and
+% |\endluacodestar|.
+%
+% \medskip
+%
+% The test file (section~\ref{test}, or \file{test-luacode.tex} in the same
+% directory as this document) provides stupid but complete examples.
+%
+% \subsection{Helper macros}
+%
+% As mentioned in the previous section, except for trivial pieces of codes (or
+% examples) it is good practice to keep all your Lua code in separate |.lua|
+% files and then use |\luadirect| only to |require()| or |dofile()| it and
+% define \LaTeX\ wrappers for some functions, eg:
+% \begin{quote}
+% |\newcommand*\foo[2]{\luadirect{foo("#1", #2)}}|
+% \end{quote}
+% This way, problems with \TeX\ special characters are avoided, since most of
+% the Lua is never seen by \TeX. Unfortunately, there is still potential
+% for problems. For example |\foo{a"b}{2}| will cause the Lua interpreter to
+% complain since the |"| in |#1| will end the string; we want the Lua
+% interpreter to see |"a\"b"| as the first argument.
+%
+% \DescribeMacro\luastring
+% Fortunately, Lua\TeX\ offers a primitive that does exactly what we need:
+% escape characters that need to be escaped in a Lua string. Unfortunately, it
+% has a very long name (especially in the prefixed form available in \LaTeX):
+% |\luatexluaescapestring|. Also, you need to think to use quotes in addition
+% to this primitive. So this package provides a shorter version: |\luastring|
+% that also include the quotes, so a safer version of |\foo| might be defined
+% as
+% \begin{quote}
+% |\newcommand*\foo[2]{\luadirect{foo(\luastring{#1}, #2)}}|
+% \end{quote}
+%
+% \DescribeMacro\luastringN
+% \DescribeMacro\luastringO
+% It should be noted that the argument of |\luastring| is fully
+% expanded\footnote{If you don't know what this means, just skip this
+% paragraph.} before being turned into a Lua string. In case where such an
+% expansion is unwanted, two variants are provided: |\luastringN| for no
+% expansion, and |\luastringO| for one-level expansion (of the first token)
+% only.
+%
+% \subsection{Debugging} \label{dbg}
+%
+% \DescribeMacro\LuaCodeDebugOn
+% \DescribeMacro\LuaCodeDebugOff
+% The commands |\luadirect| and |\luaexec| as well as the environments
+% |luacode| and |luacode*| can optionally print the Lua code as it will be
+% seen by the Lua interpreter in the log file before executing it. The feature
+% is disabled by default and can be turned on and off using |\LuaCodeDebugOn|
+% and |\LuaCodeDebugOff| (which obey the usual \TeX\ scoping rules).
+%
+% \section{Implementation}
+%
+% \begin{macrocode}
+%<*texpackage>
+% \end{macrocode}
+%
+% \subsection{Preliminaries}
+%
+% Catcode defenses.
+%
+% \begin{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax% = and space
+ \catcode123 1 % {
+ \catcode125 2 % }
+ \catcode 35 6 % #
+ \toks0{\endlinechar\the\endlinechar}%
+ \edef\x{\endlinechar13}%
+ \def\y#1 #2 {%
+ \toks0\expandafter{\the\toks0 \catcode#1 \the\catcode#1}%
+ \edef\x{\x \catcode#1 #2}}%
+ \y 13 5 % carriage return
+ \y 61 12 % =
+ \y 32 10 % space
+ \y 123 1 % {
+ \y 125 2 % }
+ \y 35 6 % #
+ \y 64 11 % @ (letter)
+ \y 39 12 % '
+ \y 40 12 % (
+ \y 41 12 % )
+ \y 42 12 % *
+ \y 45 12 % -
+ \y 46 12 % .
+ \y 47 12 % /
+ \y 91 12 % [
+ \y 93 12 % ]
+ \y 94 7 % ^
+ \y 96 12 % `
+ \y 126 13 % ~
+ \toks0\expandafter{\the\toks0 \relax\noexpand\endinput}%
+ \edef\y#1{\noexpand\expandafter\endgroup%
+ \noexpand\ifx#1\relax \edef#1{\the\toks0}\x\relax%
+ \noexpand\else \noexpand\expandafter\noexpand\endinput%
+ \noexpand\fi}%
+\expandafter\y\csname luacode@sty@endinput\endcsname%
+% \end{macrocode}
+%
+% Package declaration.
+%
+% \begin{macrocode}
+\ProvidesPackage{luacode}[2012/01/23 v1.2a lua-in-tex helpers (mpg)]
+% \end{macrocode}
+%
+% Make sure Lua\TeX\ is used.
+%
+% \begin{macrocode}
+\RequirePackage{ifluatex}
+\ifluatex\else
+ \PackageError{luacode}{LuaTeX is required for this package. Aborting.}{%
+ This package can only be used with the LuaTeX engine\MessageBreak
+ (command `lualatex'). Package loading has been stopped\MessageBreak
+ to prevent additional errors.}
+ \expandafter\luacode@sty@endinput
+\fi
+% \end{macrocode}
+%
+% Use \pk{luatexbase} for catcode tables.
+%
+% \begin{macrocode}
+\RequirePackage{luatexbase}
+% \end{macrocode}
+%
+% \subsection{Internal code}
+%
+% Produce Lua code printing debug info for the given argument.
+%
+% \begin{macrocode}
+\newcommand \luacode@printdbg [1] {%
+ texio.write_nl('log',
+ '-- BEGIN luacode debug (on input line \the\inputlineno)')
+ texio.write_nl('log', "\luatexluaescapestring{#1}")
+ texio.write_nl('log',
+ '-- END luacode debug (on input line \the\inputlineno)')
+}
+% \end{macrocode}
+%
+% Execute a piece of Lua code, possibly printing debug info.
+% |maybe@printdbg| will be either |printdbg| or |gobble|, see user macros.
+%
+% \begin{macrocode}
+\newcommand \luacode@dbg@exec [1] {%
+ \directlua {
+ \luacode@maybe@printdbg{#1}
+ #1
+ }%
+}
+% \end{macrocode}
+% Execute a piece of code, with shortcuts for double-backslash, percent and
+% tilde, and trying to preserve newlines. This internal macro is long so
+% that we can use in the environment, while the corresponding user command
+% will be short. Make sure |~| is active.
+%
+% \begin{macrocode}
+\begingroup \catcode`\~\active \expandafter\endgroup
+\@firstofone{%
+ \newcommand \luacode@execute [1] {%
+ \begingroup
+ \escapechar92
+ \newlinechar10
+ \edef\\{\string\\}%
+ \edef~{\string~}%
+ \let\%=\luacode@percentchar
+ \let\#=\luacode@sharpchar
+ \expandafter\expandafter\expandafter\endgroup
+ \luacode@dbg@exec{#1}}
+}
+% \end{macrocode}
+%
+% Catcode 12 percent and sharp characters for use in the previous command.
+%
+% \begin{macrocode}
+\begingroup \escapechar\m@ne \edef\aux{\endgroup
+ \unexpanded{\newcommand\luacode@percentchar}{\string\%}%
+ \unexpanded{\newcommand\luacode@sharpchar }{\string\#}%
+}\aux
+% \end{macrocode}
+%
+% Generic code for environments; the argument is the name of a catcode
+% table. We're normally inside a group, but let's open a new one in case
+% we're called directly rather that using |\begin|. Define the end marker
+% to be |\end{<envname>}| with current catcodes.
+%
+% \begin{macrocode}
+\newcommand*\luacode@begin [1] {%
+ \begingroup
+ \escapechar92
+ \luatexcatcodetable#1\relax
+ \edef\luacode@endmark{\string\end{\@currenvir}}%
+ \expandafter\def \expandafter\luacode@endmark \expandafter{%
+ \luatexscantextokens \expandafter{\luacode@endmark}}%
+ \luacode@grab@body}
+% \end{macrocode}
+%
+% We'll define the body grabber in a moment, but let's see how the
+% environment ends now.
+%
+% \begin{macrocode}
+\newcommand\luacode@end{%
+ \edef\luacode@next{%
+ \noexpand\luacode@execute{\the\luacode@lines}%
+ \noexpand\end{\@currenvir}}%
+ \expandafter\endgroup
+ \luacode@next}
+% \end{macrocode}
+%
+% It is not possible to grab the body using a macro with delimited
+% argument, since the end marker may contains open-group characters,
+% depending on the current catcode regime. So we collect it linewise and
+% check each line against the end marker.
+%
+% Storage for lines.
+%
+% \begin{macrocode}
+\newtoks\luacode@lines
+\newcommand*\luacode@addline [1] {%
+ \luacode@lines\expandafter{\the\luacode@lines#1^^J}}
+% \end{macrocode}
+%
+% Loop initialisation. Set endlinechar explicitely so that we can use it
+% as a delimiter (and later when writing the code to Lua). Eat up the first
+% token which is supposed to be a (catcode 12) |\endlinechar| character
+% token.
+%
+% \begin{macrocode}
+\newcommand \luacode@grab@body [1] {%
+ \luacode@lines{}%
+ \endlinechar10
+ \luacode@grab@lines}
+% \end{macrocode}
+%
+% The actual line-grabbing loop.
+%
+% \begin{macrocode}
+\long\def\luacode@grab@lines#1^^J{%
+ \def\luacode@curr{#1}%
+ \luacode@strip@spaces
+ \ifx\luacode@curr\luacode@endmark
+ \expandafter\luacode@end
+ \else
+ \expandafter\luacode@addline\expandafter{\luacode@curr}%
+ \expandafter\luacode@grab@lines
+ \fi}
+% \end{macrocode}
+%
+% Strip catcode 12 spaces from the beginning of the token list inside
+% |\luacode@curr|. First we need catcode 12 space, then we procede in the
+% usual way.
+%
+% \begin{macrocode}
+\begingroup\catcode32 12 \expandafter\endgroup
+\@firstofone{\newcommand\luacode@spaceother{ }}
+\newcommand \luacode@strip@spaces {%
+ \expandafter\luacode@strip@sp@peek\luacode@curr\@nil}
+\newcommand \luacode@strip@sp@peek {%
+ \futurelet\@let@token\luacode@strip@sp@look}
+\newcommand \luacode@strip@sp@look {%
+ \expandafter\ifx\luacode@spaceother\@let@token
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi{%
+ \afterassignment\luacode@strip@sp@peek
+ \let\@let@token=
+ }{%
+ \luacode@strip@sp@def
+ }}
+\@ifdefinable \luacode@strip@sp@def \relax
+\def \luacode@strip@sp@def #1\@nil{%
+ \def\luacode@curr{#1}}
+% \end{macrocode}
+%
+% Finally, we need a custom catcode table for the default environment:
+% everything other, except backslash, braces and letters which retain their
+% natural catcodes.
+%
+% Be carefull about the name of the macro for setting catcode ranges which
+% is currently changing in luatexbase. The group here doesn't matter since
+% catcode table settings are always global.
+%
+% \begin{macrocode}
+\newluatexcatcodetable \luacode@table@soft
+\begingroup
+\ifdefined\SetCatcodeRange \else
+ \let\SetCatcodeRange\setcatcoderange
+\fi
+\setluatexcatcodetable \luacode@table@soft {%
+ \luatexcatcodetable\CatcodeTableOther
+ \catcode 92 0
+ \catcode 123 1
+ \catcode 125 2
+ \SetCatcodeRange {65}{90} {11}
+ \SetCatcodeRange {97}{122}{11}
+}
+\endgroup
+% \end{macrocode}
+%
+% \subsection{Public macros and environments}
+%
+% Debugging.
+%
+% \begin{macrocode}
+\newcommand \LuaCodeDebugOn {\let \luacode@maybe@printdbg \luacode@printdbg}
+\newcommand \LuaCodeDebugOff {\let \luacode@maybe@printdbg \@gobble}
+\LuaCodeDebugOff
+% \end{macrocode}
+%
+% The |\luadirect| and |\luaexec| macros.
+%
+% \begin{macrocode}
+\@ifdefinable\luadirect {\let\luadirect\luacode@dbg@exec}
+\newcommand*\luaexec [1] {\luacode@execute{#1}}
+% \end{macrocode}
+%
+% Environments using different catcode tables.
+%
+% \begin{macrocode}
+\newenvironment {luacode} {\luacode@begin\luacode@table@soft} {}
+\newenvironment {luacode*} {\luacode@begin\CatcodeTableOther} {}
+\newcommand \luacodestar {\@nameuse{luacode*}}
+\def \endluacodestar {\@nameuse{endluacode*}}
+% \end{macrocode}
+%
+% Helper macros
+%
+% \begin{macrocode}
+\newcommand \luastring [1] {"\luatexluaescapestring{#1}"}
+\newcommand \luastringO [1] {\luastring{\unexpanded\expandafter{#1}}}
+\newcommand \luastringN [1] {\luastring{\unexpanded{#1}}}
+% \end{macrocode}
+%
+% We're already done!
+%
+% \begin{macrocode}
+\luacode@sty@endinput
+%</texpackage>
+% \end{macrocode}
+%
+% \section{Test file} \label{test}
+%
+% TODO: this test files requires manual checking that the output (pdf and
+% log file) is correct; this should be fixed.
+%
+% \begin{macrocode}
+%<*testlatex>
+\documentclass{minimal}
+\usepackage{luacode}
+\begin{document}
+
+\newcommand\foo{3}
+
+\(
+ \luadirect{
+ texio.write_nl("Special chars: _ ^ & $ { } working.\string\n"
+ .. "Backslashes need a bit of care.\string\n"
+ .. "Sharps and tildes too: # doubled, but \string# and \string~")
+ % a tex comment: no easy way to get a %
+ tex.sprint("\string\\pi \string\\neq", tostring(math.pi))
+ % we can use TeX macros
+ tex.sprint("-", math.sqrt(\foo))
+ }
+\)
+
+
+\(
+ \luaexec{
+ texio.write_nl("Special chars: _ ^ & $ { } ~ working.\string\n"
+ .. "Backslashes still need a bit of care.\string\n"
+ .. "Single sharps are easier now: \#")
+ % a tex comment: we also get a % below
+ tex.sprint("\\pi \\neq ", tostring(math.pi):gsub('\%.', '+'))
+ % we can use TeX macros
+ tex.sprint("-", math.sqrt(\foo))
+ }
+\)
+
+\[
+ \begin{luacode}
+ texio.write_nl("Special chars: _ ^ & $ { } ~ # % working.\string\n"
+ .. "Only backslashes still need a bit of care.\string\n")
+ -- a lua comment: we could use \% below, too
+ tex.sprint("\\pi \\neq ", tostring(math.pi):gsub('%.', '+'))
+ -- we can use TeX macros
+ tex.sprint("-", math.sqrt(\foo))
+ \end{luacode}
+\]
+
+\[
+ \begin{luacode*}
+ texio.write_nl("Special chars: _ ^ & $ { } ~ # % \\ working.\n")
+ -- a lua comment: the backlash is doubled as in normal Lua code
+ tex.sprint("\\pi \\neq ", tostring(math.pi):gsub('%.', '+'))
+ -- no way to use a TeX variable here
+ \end{luacode*}
+\]
+
+\newenvironment{mathluacode} { \[ \luacode }{ \endluacode \] }
+\newenvironment{mathluacode*}{ \[ \luacodestar }{ \endluacodestar \] }
+
+\begin{mathluacode}
+ local foo = "A full line.\string\n"
+ tex.sprint("\\pi \\neq ", tostring(math.pi):gsub('%.', '+'))
+ -- a lua comment: we could have used \% above, too
+ tex.sprint("-", math.sqrt(\foo))
+\end{mathluacode}
+
+\begin{mathluacode*}
+ local foo_bar = "A full line.\n"
+ tex.sprint("\\pi \\neq ", tostring(math.pi):gsub('%.', '+'))
+ -- a lua comment: no way to use a TeX variable here
+\end{mathluacode*}
+
+\begin{luacode*}
+ function myfunc(str)
+ assert(type(str) == 'string')
+ tex.sprint(-2, str)
+ end
+\end{luacode*}
+
+\newcommand*\mymac [1] {\texttt{\luadirect{myfunc(\luastring{#1})}}\par}
+\mymac{abc}
+\mymac{123}
+\mymac{a"b\string\nc'd}
+
+\def\mac{\onelevel}
+\def\onelevel{fully expanded}
+string : \texttt{\luadirect{myfunc(\luastring \mac)}}\par
+stringO: \texttt{\luadirect{myfunc(\luastringO\mac)}}\par
+stringN: \texttt{\luadirect{myfunc(\luastringN\mac)}}\par
+
+\LuaCodeDebugOn
+\luadirect {local foo = 'bar' .. \luastring{a"b'c}}
+\luaexec {local foo = 'bar\%\#' .. \luastring{a"b'c}}
+\begin{luacode}
+ local foo = 'bar'
+ local baz = 12 % 2
+ assert(\luastring\mac == 'fully expanded')
+ -- assert(\luastringO\mac == '\\onelevel')
+ -- assert(\luastringN\mac == '\\mac')
+\end{luacode}
+
+\LuaCodeDebugOff
+\luadirect{local rem = 'dbg should be disabled here'}
+
+% \end{macrocode}
+%
+% Now track spurious spaces. This is the only part that is automatically
+% checked, using grep in the Makefile.
+%
+% \begin{macrocode}
+\tracingcommands1
+\luadirect{local foo}%
+\luaexec{local foo}%
+\begin{luacode}
+ local foo
+\end{luacode}
+\begin{luacode*}
+ local foo
+\end{luacode*}
+\tracingcommands0
+
+\end{document}
+%</testlatex>
+% \end{macrocode}
+%
+%
+% \Finale
+\endinput
diff --git a/macros/luatex/latex/luacode/luacode.pdf b/macros/luatex/latex/luacode/luacode.pdf
new file mode 100644
index 0000000000..7c3e7b7cec
--- /dev/null
+++ b/macros/luatex/latex/luacode/luacode.pdf
Binary files differ
diff --git a/macros/luatex/latex/luahyphenrules/README.md b/macros/luatex/latex/luahyphenrules/README.md
new file mode 100644
index 0000000000..a73222e514
--- /dev/null
+++ b/macros/luatex/latex/luahyphenrules/README.md
@@ -0,0 +1,15 @@
+luahyphenrules
+==============
+
+Preloading hyphenation patterns (or “hyphen rulesâ€) into the format is
+not required in LuaTeX and recent releases of `babel` don't do it.
+This package is addressed to those who just want to select the
+language and load their patterns by means of `language.dat` without
+loading `babel`.
+
+* Javier Bezos
+* 2016-12-07
+* Released under the LaTeX Project Public License v1.3c or later
+ See http://www.latex-project.org/lppl.txt
+* It requires LuaLaTeX
+
diff --git a/macros/luatex/latex/luahyphenrules/luahyphenrules.pdf b/macros/luatex/latex/luahyphenrules/luahyphenrules.pdf
new file mode 100644
index 0000000000..9f0c9c39ac
--- /dev/null
+++ b/macros/luatex/latex/luahyphenrules/luahyphenrules.pdf
Binary files differ
diff --git a/macros/luatex/latex/luahyphenrules/luahyphenrules.sty b/macros/luatex/latex/luahyphenrules/luahyphenrules.sty
new file mode 100644
index 0000000000..244bf903c8
--- /dev/null
+++ b/macros/luatex/latex/luahyphenrules/luahyphenrules.sty
@@ -0,0 +1,161 @@
+% +--------------------------------------------------------+
+% | Typeset luahyphenrules.tex to get the documentation. |
+% +--------------------------------------------------------+
+%
+%% Copyright (C) 2016 Javier Bezos
+%% All Rights Reserved
+%% http://www.texnia.com
+%%
+%% This work may be distributed and/or modified under the conditions
+%% of the LaTeX Project Public License, either version 1.3 of this
+%% license or (at your option) any later version. The latest version
+%% of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2003/12/01 or later.
+%%
+%% This work has the LPPL maintenance status "maintained".
+%%
+%% This Current Maintainer of this work is Javier Bezos.
+%%
+%% This work consists of the files luahyphenrules.tex and
+%% luahyphenrules.sty.
+\ProvidesPackage{luahyphenrules}
+ [2016/12/07 v1.0 language.dat reader lualatex]
+
+% The code below is essentially the same as in babel.dtx, with a few
+% minor changes. See the latter for further info.
+
+\begingroup
+ \toks@{}
+ \count@\z@ % 0=start, 1=0th, 2=normal
+ \def\bbl@process@line#1#2 #3 #4 {%
+ \ifx=#1%
+ \bbl@process@synonym{#2}%
+ \else
+ \bbl@process@language{#1#2}{#3}{#4}%
+ \fi
+ \ignorespaces}
+ \def\bbl@manylang{%
+ \ifnum\bbl@last>\@ne
+ \bbl@info{Non-standard hyphenation setup}%
+ \fi
+ \let\bbl@manylang\relax}
+ \def\bbl@process@language#1#2#3{%
+ \ifcase\count@
+ \@ifundefined{zth@#1}{\count@\tw@}{\count@\@ne}%
+ \or
+ \count@\tw@
+ \fi
+ \ifnum\count@=\tw@
+ \expandafter\addlanguage\csname l@#1\endcsname
+ \language\allocationnumber
+ \chardef\bbl@last\allocationnumber
+ \bbl@manylang
+ \let\bbl@elt\relax
+ \xdef\bbl@languages{%
+ \bbl@languages\bbl@elt{#1}{\the\language}{#2}{#3}}%
+ \fi
+ \the\toks@
+ \toks@{}}
+ \def\bbl@process@synonym@aux#1#2{%
+ \global\expandafter\chardef\csname l@#1\endcsname#2\relax
+ \let\bbl@elt\relax
+ \xdef\bbl@languages{%
+ \bbl@languages\bbl@elt{#1}{#2}{}{}}}%
+ \def\bbl@process@synonym#1{%
+ \ifcase\count@
+ \toks@\expandafter{\the\toks@\relax\bbl@process@synonym{#1}}%
+ \or
+ \@ifundefined{zth@#1}{\bbl@process@synonym@aux{#1}{0}}{}%
+ \else
+ \bbl@process@synonym@aux{#1}{\the\bbl@last}%
+ \fi}
+ \ifx\bbl@languages\@undefined % Just a (sensible?) guess
+ \chardef\l@english\z@
+ \chardef\l@USenglish\z@
+ \chardef\bbl@last\z@
+ \global\@namedef{bbl@hyphendata@0}{{hyphen.tex}{}}
+ \gdef\bbl@languages{%
+ \bbl@elt{english}{0}{hyphen.tex}{}%
+ \bbl@elt{USenglish}{0}{}{}}
+ \else
+ \def\bbl@elt#1#2#3#4{% Remove all except language 0
+ \ifnum#2>\z@\else
+ \noexpand\bbl@elt{#1}{#2}{#3}{#4}%
+ \fi}%
+ \xdef\bbl@languages{\bbl@languages}%
+ \fi
+ \def\bbl@elt#1#2#3#4{\@namedef{zth@#1}{}} % Define flags
+ \bbl@languages
+ \openin1=language.dat
+ \ifeof1
+ \PackageWarning{luahyphenrules}%
+ {I couldn't find language.dat. No additional\MessageBreak
+ patterns loaded. Reported}%
+ \else
+ \loop
+ \endlinechar\m@ne
+ \read1 to \bbl@line
+ \endlinechar`\^^M
+ \if T\ifeof1F\fi T\relax
+ \ifx\bbl@line\@empty\else
+ \edef\bbl@line{\bbl@line\space\space\space}%
+ \expandafter\bbl@process@line\bbl@line\relax
+ \fi
+ \repeat
+ \fi
+\endgroup
+
+\def\bbl@get@enc#1:#2:#3\@@@{\def\bbl@hyph@enc{#2}}
+
+\newcatcodetable\bbl@tempcattbl
+
+\def\bbl@luapatterns#1#2{%
+ \bbl@get@enc#1::\@@@
+ \setbox\z@\hbox\bgroup
+ \begingroup
+ \savecatcodetable\bbl@tempcattbl
+ \catcodetable\catcodetable@latex
+ \input #1\relax
+ \catcodetable\bbl@tempcattbl
+ \endgroup
+ \def\bbl@tempa{#2}%
+ \ifx\bbl@tempa\@empty\else
+ \input #2\relax
+ \fi
+ \egroup}%
+
+\newcommand\HyphenRules[1]{%
+ \language=\expandafter\ifx\csname l@#1:\f@encoding\endcsname\relax
+ \@ifundefined{l@#1}%
+ {\z@
+ \PackageError{luahyphenrules}%
+ {Unknown language `#1'. Either you have\MessageBreak
+ misspelled its name or language.dat doesn't define\MessageBreak
+ it. Words in this language won't be hyphenated.}%
+ {You may proceed, but expect wrong results}}%
+ {\csname l@#1\endcsname
+ \edef\bbl@tempa{#1}}%
+ \else
+ \csname l@#1:\f@encoding\endcsname
+ \edef\bbl@tempa{#1:\f@encoding}%
+ \fi\relax
+ \@ifundefined{bbl@hyphendata@\the\language}%
+ {\def\bbl@elt##1##2##3##4{% 1:name, 2:num, 3:pat-file, 4:exc-file
+ \ifnum##2=\csname l@\bbl@tempa\endcsname % tempa=spanish,dutch:OT1...
+ \def\bbl@tempb{##3}%
+ \ifx\bbl@tempb\@empty\else % if not a synonymous (if pat-file)
+ \def\bbl@tempc{{##3}{##4}}%
+ \fi
+ \expandafter\xdef\csname bbl@hyphendata@##2\endcsname{\bbl@tempc}%
+ \fi}%
+ \bbl@languages
+ \@ifundefined{bbl@hyphendata@\the\language}%
+ {\PackageInfo{luahyphenrules}%
+ {No hyphenation patterns were set for\MessageBreak
+ language ‘\bbl@tempa’. Reported}}%
+ {\expandafter\expandafter\expandafter\bbl@luapatterns
+ \csname bbl@hyphendata@\the\language\endcsname}}{}}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/luahyphenrules/luahyphenrules.tex b/macros/luatex/latex/luahyphenrules/luahyphenrules.tex
new file mode 100644
index 0000000000..d249d9d9ac
--- /dev/null
+++ b/macros/luatex/latex/luahyphenrules/luahyphenrules.tex
@@ -0,0 +1,114 @@
+% +--------------------------------------------------+
+% | Typeset this file to get the documentation. |
+% +--------------------------------------------------+
+%
+%% Copyright (C) 2016 Javier Bezos
+%% All Rights Reserved
+%% http://www.texnia.com
+%%
+%% This work may be distributed and/or modified under the conditions
+%% of the LaTeX Project Public License, either version 1.3 of this
+%% license or (at your option) any later version. The latest version
+%% of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2003/12/01 or later.
+%%
+%% This work has the LPPL maintenance status "maintained".
+%%
+%% This Current Maintainer of this work is Javier Bezos.
+%%
+%% This work consists of the files luahyphenrules.tex and
+%% luahyphenrules.sty.
+\documentclass[a4paper]{ltxguide}
+
+\title{\textsf{luahyphenrules}\\\large Version 1.0}
+
+\author{Javier Bezos\\\texttt{http://www.texnia.com}}
+
+\date{2016-12-07}
+
+\raggedright
+\parskip=.8ex
+\advance\oddsidemargin-.7cm
+\advance\textwidth2cm
+\addtolength{\textheight}{3.5cm}
+\addtolength{\topmargin}{-2cm}
+
+\usepackage{xcolor,bera}
+
+\definecolor{notes}{rgb}{.75, .3, .3}%
+
+\makeatletter
+\def\@begintheorem#1#2{%
+ \list{}{}%
+ \global\advance\@listdepth\m@ne
+ \item[{\sffamily\bfseries\color{notes}\MakeUppercase{#1}}]}%
+\makeatother
+\newtheorem{warning}{Warning}
+\newtheorem{note}{Note}
+\newtheorem{example}{Example}
+
+\begin{document}
+
+\vspace*{1cm}
+{\fontsize{48}{48}\selectfont \color{notes}{luahyphenrules}\par}
+{\LARGE Loading patterns in \textsf{lualatex} with
+\texttt{language.dat}\par}
+\vspace*{1ex}
+Version 1.0 (2016-12-07)\par
+Javier Bezos (\texttt{http://www.texnia.com})
+
+\vspace*{6ex}
+
+Preloading hyphenation patterns (or ``hyphen rules'') into the format
+is not required in Lua\TeX. On the contrary, it is even discouraged
+and accordingly recent releases of \textsf{babel} don't do it. This file is
+addressed to those who just want to select the language and load their
+patterns without loading at all the \textsf{babel} package with
+|\usepackage|.
+
+When \textsf{luahyphenrules} is loaded, it reads |language.dat| and
+stores its data. Then, you can use the following command to select the
+language.
+
+\begin{decl}
+|\HyphenRules{<language-name>}|
+\end{decl}
+
+Here |<language-name>| is the name in |language.dat|. It select the
+language, if exists, and loads its hyphenations patterns if not done
+before. If the language does not exist or there are no patterns, it
+raises and error.
+
+\begin{note}
+ If you are using \textsf{babel} you do not need this package.
+\end{note}
+
+\begin{note}
+ Actually, loading hypenations patterns in Lua\TeX{} is so simple as
+ inputting the corresponding file with the correct catcode regime
+ when the language is active (which in turn may be created with
+ |\newlanguage|). This package is mostly about reading and
+ parsing |language.dat| at runtime.
+\end{note}
+
+\begin{note}
+ The internal variable |\bbl@languages|, containing the list of
+ languages in |language.dat|, is also set by this package. See the
+ \textsf{babel} manual for further info.
+\end{note}
+
+\begin{warning}
+ This package only works with Lua\LaTeX.
+\end{warning}
+
+
+\end{document}
+
+
+
+
+
+
+
diff --git a/macros/luatex/latex/luaimageembed/LICENSE b/macros/luatex/latex/luaimageembed/LICENSE
new file mode 100644
index 0000000000..aa53876ce8
--- /dev/null
+++ b/macros/luatex/latex/luaimageembed/LICENSE
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2017 Christian C. Sachs
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/macros/luatex/latex/luaimageembed/README.md b/macros/luatex/latex/luaimageembed/README.md
new file mode 100644
index 0000000000..0ed617ea34
--- /dev/null
+++ b/macros/luatex/latex/luaimageembed/README.md
@@ -0,0 +1,41 @@
+# luaimageembed
+
+LuaTeX package to embed images directly as base64-encoded strings into the document. This can be useful, e.g. to package a document with images into a single TeX file, or with automatically generated graphics.
+
+The image files will be decoded, written to a temporary directory, and cleaned up afterwards.
+
+Use at your own risk.
+
+## Commands
+
+Three commands are wrapped to allow for use with base64-encoded images:
+
+- `\includegraphicsembedded` (`\includegraphics`)
+- `\pgfdeclareimageembedded` (`\pgfdeclareimage`)
+- `\pgfimageembedded` (`\pgfimage`)
+
+Each takes the base64-encoded image data instead of the filename; see the example below. Supported are `png`, `jpg`, `jb2` and `pdf` images.
+
+## Example
+
+```latex
+\documentclass{scrartcl}
+
+\usepackage{luaimageembed}
+\usepackage{graphicx}
+
+\begin{document}
+\includegraphicsembedded[width=4cm]{%
+iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAAAAABzQ+pjAAAAFElEQVQI12P4z/Cf4f9/BgYGBgYA
+IOsD/UqPmwUAAAAASUVORK5CYII=
+}
+\end{document}
+```
+
+## Version
+
+0.1 (alpha)
+
+## License
+
+MIT
diff --git a/macros/luatex/latex/luaimageembed/luaimageembed.sty b/macros/luatex/latex/luaimageembed/luaimageembed.sty
new file mode 100644
index 0000000000..184c5fbb0b
--- /dev/null
+++ b/macros/luatex/latex/luaimageembed/luaimageembed.sty
@@ -0,0 +1,85 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{luaimageembed}[2017/08/12 luaimageembed alpha version 0.1]
+
+% Copyright Christian C. Sachs, MIT licensed
+
+\RequirePackage{luacode}
+
+% no options so far
+
+\begin{luacode*}
+
+image_counter = 0
+image_list = {}
+image_tmpdir = nil
+
+function add_image(data)
+ if image_tmpdir == nil then
+ image_tmpdir = os.tmpdir()
+ end
+
+ local ltn12 = require("ltn12")
+ local mime = require("mime")
+
+ local file_name = image_tmpdir .. "/" .. "image" .. image_counter
+ image_counter = image_counter + 1
+
+ ltn12.pump.all(
+ ltn12.source.string(data),
+ ltn12.sink.chain(
+ mime.decode("base64"),
+ ltn12.sink.file(io.open(file_name, "a"))
+ )
+ )
+
+ local file = io.open(file_name, "rb")
+
+ local magic = file:read(2)
+ file:close()
+
+ local new_extension = "error"
+
+ if magic == "\x89\x50" then
+ new_extension = "png"
+ elseif magic == "\xff\xd8" then
+ new_extension = "jpg"
+ elseif magic == "\x97\x4a" then
+ new_extension = "jb2"
+ elseif magic == "\x25\x50" then
+ new_extension = "pdf"
+ else
+ error("Unsupported image data passed")
+ end
+
+ local old_file_name = file_name
+ local file_name = file_name .. "." .. new_extension
+ texio.write_nl('term', "magic=" .. magic)
+ texio.write_nl('term', "output_filename=" .. file_name)
+
+ os.rename(old_file_name, file_name)
+
+ table.insert(image_list, 1, file_name)
+
+ return file_name
+
+end
+
+function cleanup_images()
+ for i = 1, #image_list do
+ os.remove(image_list[i])
+ end
+
+ if image_tmpdir ~= nil then
+ lfs.rmdir(image_tmpdir)
+ end
+end
+
+luatexbase.add_to_callback("finish_pdffile", cleanup_images, "Removes temporary images and folder again")
+
+\end{luacode*}
+
+\newcommand{\includegraphicsembedded}[2][]{\includegraphics[#1]{\directlua{tex.print(add_image([[#2]]))}}}
+\newcommand{\pgfdeclareimageembedded}[3][]{\pgfdeclareimage[#1]{#2}{\directlua{tex.print(add_image([[#3]]))}}}
+\newcommand{\pgfimageembedded}[2][]{\pgfimage[#1]{\directlua{tex.print(add_image([[#2]]))}}}
+
+\endinput
diff --git a/macros/luatex/latex/luaindex/README b/macros/luatex/latex/luaindex/README
new file mode 100644
index 0000000000..aebd8bafe6
--- /dev/null
+++ b/macros/luatex/latex/luaindex/README
@@ -0,0 +1,55 @@
+LuaLaTeX package luaindex
+Copyright (c) Markus Kohm, 2011
+
+This file is part of the luaTeX package `luaindex'.
+
+This work may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, version 1.3c of the license.
+The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+and version 1.3c or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+This work has the LPPL maintenance status "maintained".
+
+The Current Maintainer and author of this work is Markus Kohm.
+
+This work consists of the files `luaindex.dtx' and `README'.
+
+============================================================================
+
+luaindex is another index processor written in Lua. Currently usage of
+LuaLaTeX is provided only, but plainLuaTeX, ConTeXt or other formats may
+follow.
+
+luaindex provides more than one index. Like SplitIndex it needs only one
+help file for all produced indexes.
+
+============================================================================
+
+Note: This is an alpha version!
+For additional version information see `lualatex.dtx.'
+
+============================================================================
+
+To produce the package, the examples, and the manual from `luaindex.dtx'
+you have to run
+
+ lualatex --shell-escape luaindex.dtx
+
+simply.
+
+============================================================================
+
+Distributors should save luaindex.lua as .../scripts/luaindex/luaindex.lua
+and luaindex.sty as .../tex/lualatex/luaindex/luaindex.sty at the TEXMF
+tree.
+
+============================================================================
+
+Important changes:
+
+0.1b: - module name is not longer `koma.luaindex' but `luaindex' due to
+ the usage of luatexbase-modutils
+
+============================================================================
diff --git a/macros/luatex/latex/luaindex/luaindex.dtx b/macros/luatex/latex/luaindex/luaindex.dtx
new file mode 100644
index 0000000000..a2bd7b0498
--- /dev/null
+++ b/macros/luatex/latex/luaindex/luaindex.dtx
@@ -0,0 +1,1602 @@
+% \CheckSum{421}
+% \iffalse meta-comment
+% ==========================================================================
+% luaindex.dtx
+% Copyright (c) Markus Kohm, 2011
+%
+% This file is part of the luaTeX package `luaindex'.
+%
+% This work may be distributed and/or modified under the conditions of
+% the LaTeX Project Public License, version 1.3c of the license.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status "maintained".
+%
+% The Current Maintainer and author of this work is Markus Kohm.
+%
+% This work consists of the files `luaindex.dtx' and `README'.
+% ==========================================================================
+% \fi^^A meta-comment
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+% \iffalse meta-comment
+%<*dtx|ins>
+\def\batchfile{luaindex.dtx}
+\input docstrip.tex
+\ifToplevel{%
+ \Msg{********************************************************************}
+ \Msg{*}
+ \Msg{* Steps of luaindex generation:}
+ \Msg{* =============================}
+ \Msg{*}
+ \Msg{* - Generation of all needed files:}
+ \keepsilent
+ \askforoverwritefalse
+}
+{
+\obeyspaces\obeylines
+\global\def\preambletext{
+\space
+Copyright (c) 2011 by Markus Kohm <komascript(at)gmx.info>
+
+This file was generated from file(s) of luaindex distribution.
+--------------------------------------------------------------
+
+This work may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, version 1.3c of the license.
+The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+and version 1.3c or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+This work has the LPPL maintenance status "maintained".
+
+The Current Maintainer and author of this work is Markus Kohm.
+
+This file may only be distributed together with the files listed in
+`luaindex.dtx'. You may however distribute the files listed in
+`luaindex.dtx' without this file.
+
+NOTE: THIS IS AN ALPHA-VERSION!
+}
+}
+\expandafter\preamble
+\preambletext
+\endpreamble
+\def\ThreeHyphens{---}
+\let\MetaPrefix\ThreeHyphens
+\expandafter\declarepreamble\expandafter\luapreamble
+\preambletext
+\endpreamble
+
+\generate{%
+ \let\MetaPrefix\DoubleperCent
+ \usepreamble\defaultpreamble
+ \file{luaindex.ltx}{\from{luaindex.dtx}{manual}}%
+ \file{luaindex.sty}{\from{luaindex.dtx}{package}}%
+ \file{luaindex-example.ltx}{\from{luaindex.dtx}{example}}%
+ \let\MetaPrefix\ThreeHyphens
+ \usepreamble\luapreamble
+ \nopostamble
+ \file{luaindex.lua}{\from{luaindex.dtx}{lua}}%
+}
+
+\ifToplevel{%
+ \Msg{* \space\space done.}
+ \Msg{* - Generation of examples:}
+ \directlua{%
+ local retval = os.execute( "lualatex --jobname=luaindex-example
+ --interaction=batchmode luaindex-example.ltx" );
+ if ( retval == nil ) then
+ tex.error( "Shell escape not enabled!",
+ { "You should try",
+ " `luatex --shell-escape --jobname=luaindex luaindex.dtx'",
+ "to enable shell escape.",
+ "Otherwise you will get no example." } )
+ elseif ( retval == 0 ) then
+ else
+ tex.error( "Failed to generate the example",
+ { "I've tried to call",
+ " `lualatex --jobname=luaindex luaindex-example.ltx'",
+ "but got unexpected return value:",
+ retval }
+ )
+ end
+ }%
+}
+
+\ifToplevel{%
+ \Msg{* \space\space implemented not yet.}
+ \Msg{* - Generation of manual:}
+ \directlua{%
+ local retval = os.execute( "lualatex --jobname=luaindex
+ --interaction=batchmode luaindex.ltx" );
+ if ( retval == 0 ) then
+ retval = os.execute( "lualatex --jobname=luaindex
+ --interaction=batchmode luaindex.ltx" );
+ end
+ if ( retval == 0 ) then
+ retval = os.execute( "makeindex -q -s gind.ist luaindex" );
+ end
+ if ( retval == 0 ) then
+ retval = os.execute( "makeindex -q -s gglo.ist
+ -o luaindex.gls luaindex.glo" );
+ end
+ if ( retval == 0 ) then
+ retval = os.execute( "lualatex --jobname=luaindex
+ --interaction=batchmode luaindex.ltx" );
+ end
+ if ( retval == nil ) then
+ tex.error( "Shell escape not enabled!",
+ { "You should try",
+ " `luatex --shell-escape --jobname=luaindex luaindex.dtx'",
+ "to enable shell escape.",
+ "Otherwise you will get no manual." } )
+ elseif ( retval == 0 ) then
+ else
+ tex.error( "Failed to generate the manual",
+ { "I've tried to call",
+ " `lualatex --jobname=luaindex luaindex.ltx'",
+ "but got unexpected return value:",
+ retval }
+ )
+ end
+ }%
+}
+
+\ifToplevel{%
+ \Msg{* \space\space done.}
+ \Msg{*}
+ \Msg{* Now you may install all the files.}
+ \Msg{*}
+ \Msg{********************************************************************}
+}
+
+\csname endinput\endcsname
+%</dtx|ins>
+%<*dtx>
+\ProvidesFile{luaindex.dtx}
+%</dtx>
+%<package|manuel|example>\NeedsTeXFormat{LaTeX2e}[1995/06/01]
+%<package>\ProvidesPackage{luaindex}
+%<manual>\ProvidesFile{luaindex.ltx}
+%<example>\ProvidesFile{luaindex-example.ltx}
+%<lua>if luatexbase.provides_module then
+%<lua> luatexbase.provides_module({
+%<lua> name = "luaindex",
+%<lua> date = "2011/02/18",
+%<lua> version = "0.1b",
+%<lua> description = "LuaTeX index processor",
+%<lua> author = "Markus Kohm",
+%<lua> licence = "LPPL v1.3c or later"
+%<lua> })
+%<lua>end
+%<*package|manual|dtx>
+ [2011/02/18 v0.1b LuaLaTeX Package
+%<*manual>
+ documentation:
+%</manual>
+ index processor]%
+%</package|manual|dtx>
+%<*manual>
+\documentclass{scrdoc}
+\usepackage{tabularx}
+\usepackage[english]{babel}
+\usepackage{xcolor}
+\colorlet{mcode}{teal}
+\usepackage{fontspec}
+\providecommand*{\LuaTeX}{Lua\kern-.125em\TeX}
+\providecommand*{\LuaLaTeX}{Lua\kern-.025em\LaTeX}
+\CodelineIndex
+\RecordChanges
+\GetFileInfo{luaindex.ltx}
+\title{%
+ Usage of\\
+ \LuaTeX{} module \texttt{luaindex}\\
+ and\\
+ \LuaLaTeX{} Package \texttt{luaindex}\\
+ for Generating Indexes\\
+}
+\date{\fileversion}
+\author{Markus Kohm\thanks{komascript%
+@%
+gmx%
+.%
+info}}
+\begin{document}
+\maketitle
+\DocInput{luaindex.dtx}
+\end{document}
+%</manual>
+%\fi^^A meta-comment
+%
+% \changes{v0.1}{2011/01/26}{start of new package}
+% \changes{v0.1b}{2011/02/18}{prefix `koma.' removed from Lua module}
+%
+% \begin{abstract}
+% With \LuaTeX{} it would not be a problem to call an index processor like
+% MakeIndex while running \LuaTeX{}. So the user would not longer require
+% to call the index processor on his own. But on the other side Lua hat
+% enough power to process the index itself. Package \texttt{luaindex} was
+% made to do this. It consists primary of a Lua module:
+% \texttt{luaindex.lua}. This provides functions to generate a new index
+% (or several new indexes), add entries to it and print the index. To make
+% the world easier there's an additional \LaTeX{} package:
+% \texttt{luaindex.sty}.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Idea}
+%
+% We will explain this in a future release.
+%
+% \section{General Options}
+%
+% See implementation documentation.
+%
+% \section{Generating Index Entries}
+%
+% See implementation documentation.
+%
+% \section{Print an Index}
+%
+% See implementation documentation.
+%
+% \section{Known Issues}
+%
+% Currently the user documentation is not existing. Please use the
+% implementation documentation and the example instead of. This will be
+% changed in a future release but maybe not at a near future.
+%
+% Currently there are no attributes to give the different indexes different
+% headings. You may redefine |\indexname| before printing an index to do
+% so. Future releases will do this simply by option.
+%
+% Currently repeated pre-sort-replaces are not supported. Maybe they will in a
+% future release.
+%
+% Currently page ranges are not supported. They will in a future release.
+%
+% Note: This is not even a beta version. It's only a proof of concept. Almost
+% everything my be designed and implemented in a better kind. The author
+% himself is just learning \LuaTeX{}.
+%
+% Nevertheless you may report bugs and patches to komascript^^A
+% @^^A
+% gmx^^A
+% .^^A
+% info.
+%
+%
+% \StopEventually{%
+% \PrintIndex
+% \PrintChanges
+% }
+%
+% \section{Implementation of Lua Module \texttt{luaindex.lua}}
+%
+% \iffalse meta-comment
+%<*lua>
+% \fi^^A meta-comment
+%
+% First of all wie define a new module named \texttt{luaindex}. All
+% variables and functions will be local to this module.
+% \begin{macrocode}
+module("luaindex", package.seeall)
+% \end{macrocode}
+%
+% To handle all indexes we have a variable named \texttt{indexes}. This is a
+% table of index tables \emph{assoziated by the name of the index
+% table}\marginpar{\makebox[0pt][l]{\color{mcode}^^A
+% \begin{tabular}[t]{@{}l@{}}
+% \texttt{indexes}=\{\\
+% \enskip\emph{name}=\{\\
+% \enskip\enskip\texttt{presortreplaces}=\{\\
+% \enskip\enskip\enskip\{[\emph{pattern}]=\emph{replace}, \dots\kern.1em\},
+% \dots\\
+% \enskip\enskip\},\\
+% \enskip\enskip\texttt{sortorderbychar}=\{\\
+% \enskip\enskip\enskip[\emph{char}]=\emph{position}, \dots\\
+% \enskip\enskip\},\\
+% \enskip\enskip\{\\
+% \enskip\enskip\enskip\texttt{sort}="\dots\kern.1em",\\
+% \enskip\enskip\enskip\texttt{value}="\dots\kern.1em",\\
+% \enskip\enskip\enskip\texttt{pages}=\{\dots\kern.1em\},\\
+% \enskip\enskip\enskip\texttt{subindex}=\{\dots\kern.1em\}\\
+% \enskip\enskip\}\\
+% \enskip\}\\
+% \}\\
+% \end{tabular}
+% }}
+% \begin{itemize}
+% \item Each index table has at least \emph{two elements} assoziated to
+% \texttt{presortreplaces} and
+% \texttt{sortorderbychar}.
+% \item There may be additional numericly assoziated elements, the \emph{index
+% entries}.
+% \begin{itemize}
+% \item Each index entry has a least \emph{two elements} assoziated to
+% \texttt{sort} und \texttt{value}. Element \texttt{sort} is the sort key
+% of the index entry. Element \texttt{value} is the print value of the
+% index entry.
+% \item Each index entry may have an element assoziated to
+% \texttt{pages}. This is a table of print values, that will be used as
+% page number of the entry. It need not to be numeric. This table hat
+% numeric assoziations. Later addeed pages will be appended to the end of
+% the table.
+% \item Each index entry may habe an element assoziated to
+% \texttt{subindex}. This is an index table too, but do not have elements
+% \texttt{presortreplaces} or \texttt{sortorderbychar}.
+% \end{itemize}
+% \end{itemize}
+% \begin{macrocode}
+local indexes = {}
+% \end{macrocode}
+%
+% Next we have a function\marginpar{\makebox[0pt][l]{\color{mcode}^^A
+% \texttt{newindex(\emph{index name})}}} to generate a new \emph{index table}
+% at \texttt{indexes}:
+% \begin{macrocode}
+function newindex( indexname )
+ indexes[indexname]={ presortreplaces = {},
+ sortorderbychar = {} }
+end
+% \end{macrocode}
+% The function parameter is the name of the index. This is not realy a print
+% name, but a simple assoziation name.
+%
+% Don't be impressed because of empty initialization of
+% \texttt{presortreplaces} and \texttt{sortorderbychar}. We will have
+% functions to change this.
+%
+% First of all, we have a function\marginpar{\makebox[0pt][l]{\color{mcode}^^A
+% \begin{tabular}[t]{@{}l@{}l@{}}
+% \texttt{sortorder(} & \texttt{\emph{index name},} \\
+% & \texttt{\emph{sort-order})}\\
+% \end{tabular}%
+% }} to add a new sort order.
+% \begin{macrocode}
+function sortorder( indexname, sortorder )
+ local i, value
+% \end{macrocode}
+% The first parameter of the function is the name if the index table. If an
+% index table with the given name does not exist, \TeX{} should release an
+% error message with some optional help.
+% \begin{macrocode}
+ local index = indexes[indexname]
+ if index == nil then
+ tex.error( "Unknown index `" .. indexname .. "'",
+ { "You've tried to add a new sortorder to an index, but there's no index with the",
+ "given name.",
+ "You should define the index using lua function ",
+ " `luaindex.newindex(\"" .. indexname .. "\")'",
+ "before."
+ }
+ )
+ else
+ if type(sortorder) == "string" then
+% \end{macrocode}
+% The second parameter of the function may be a string. The string simply is
+% an concatenation of the character in the order that should be used to sort
+% the index entries of this index. The index table assoziatione
+% \texttt{sortorderbychar} is a table. The characters are the assoziation and
+% the wanted sort position is the assoziated value.
+% \begin{macrocode}
+ local value
+ i = 1
+ repeat
+ value = unicode.utf8.sub( sortorder, i, i )
+%<debug> print( i, value )
+ if value then
+ index.sortorderbychar[value] = i
+ end
+ i = i + 1
+ until value == ""
+ else -- should be table
+% \end{macrocode}
+% The second parameter of the function may also be a table with numerical
+% assoziations.
+% \begin{macrocode}
+ for i, value in ipairs( sortorder ) do
+ index.sortorderbychar[value] = i
+ end
+ end
+ end
+end
+% \end{macrocode}
+%
+% Second manipulation function\marginpar{\makebox[0pt][l]{\color{mcode}^^A
+% \begin{tabular}[t]{@{}l@{}l@{}}
+% \texttt{presortreplace(} & \texttt{\emph{index name},} \\
+% & \texttt{\emph{pass},} \\
+% & \texttt{\emph{pattern},} \\
+% & \texttt{\emph{replace})}\\
+% \end{tabular}%
+% }} is to add presort entries to a presort pass of
+% an index. \texttt{\emph{pattern}} and \texttt{\emph{replace}} are
+% strings. See Lua function \texttt{unicode.utf8.sub} for more information
+% about these.
+% \begin{macrocode}
+function presortreplace( indexname, pass, pattern, replace )
+ local n
+% \end{macrocode}
+% The first parameter of the function is the name if the index table. If an
+% index table with the given name does not exist, \TeX{} should release an
+% error message with some optional help.
+% \begin{macrocode}
+ local index = indexes[indexname]
+ if index == nil then
+ tex.error( "Unknown index `" .. indexname .. "'",
+ { "You've tried to add a new presort-replace to an index, but there's no index",
+ "with the given name.",
+ "You should define the index using lua function ",
+ " `luaindex.newindex(\"" .. indexname .. "\")'",
+ "before."
+ }
+ )
+ else
+% \end{macrocode}
+% If the index exists, we have to create replace tables for every pass until
+% the given.
+% \begin{macrocode}
+ for n = table.maxn(index.presortreplaces), pass, 1 do
+ if ( index.presortreplaces[n] == nil ) then
+ index.presortreplaces[n] = {}
+ end
+ end
+% \end{macrocode}
+% Last but not least we have to add a new replace to the pass:
+% \begin{macrocode}
+ index.presortreplaces[pass][pattern]=replace
+ end
+end
+% \end{macrocode}
+%
+% Indexes are normally separated into single letters, all numbers and all
+% other symbols. To do so, we have a new
+% function\marginpar{\makebox[0pt][l]{\color{mcode}^^A
+% \begin{tabular}[b]{@{}l@{~}l@{}}
+% \texttt{local} & \texttt{getclass(} \\
+% & \enskip\texttt{\emph{utf8-char})}\\
+% \end{tabular}%
+% }} that returns 1 for all other symbols, 2 for all numbers and 3 for all
+% letters. Wether an UTF-8 character is a letter or not depends on the
+% locale type ``\texttt{collate}''. You may set it using
+% \texttt{os.setlocale("\emph{locale}", "collate")}.
+% \begin{macrocode}
+local function getclass( utfc )
+ local i
+ for i in unicode.utf8.gmatch( utfc, "%n" ) do
+%<debug> print( utfc .. " is a number" )
+ return 2
+ end
+ for i in unicode.utf8.gmatch( utfc, "%a" ) do
+%<debug> print( utfc .. " is a letter" )
+ return 3
+ end
+%<debug> print( utfc .. " is a symbol" )
+ return 1
+end
+% \end{macrocode}
+%
+% Before printing or sorting we may want to replace\marginpar{%^^A
+% \makebox[0pt][l]{\color{mcode}^^A
+% \begin{tabular}[t]{@{}l@{~}l@{}}
+% \texttt{local} & \texttt{do\_presortreplaces(} \\
+% & \enskip\texttt{\emph{utf8-string},}\\
+% & \enskip\texttt{\emph{replace table})}\\
+% \end{tabular}%
+% }} some strings. We have a table of those. At the string each occurence of
+% the assoziation should be replaced by the assoziated value.
+% \begin{macrocode}
+local function do_presortreplaces( srcstr, presortreplace )
+ if presortreplace then
+ local pat, rep
+ for pat, rep in pairs( presortreplace ) do
+ srcstr = unicode.utf8.gsub( srcstr, pat, rep )
+ end
+ end
+ return srcstr
+end
+% \end{macrocode}
+%
+% Now let's print the index.\marginpar{\makebox[0pt][l]{\color{mcode}^^A
+% \begin{tabular}[t]{@{}l@{~}l@{}}
+% \texttt{local} & \texttt{printsubindex(} \\
+% & \enskip\texttt{\emph{level},}\\
+% & \enskip\texttt{\emph{index},}\\
+% & \enskip\texttt{\emph{presortreplace\_zero})}\\
+% \end{tabular}%
+% }}
+% There aren't much differences in printing an index or a sub-index to an
+% index entry. We only need to know the level of the (sub-) index. level 0
+% is the main index.
+% \begin{macrocode}
+local function printsubindex( level, index, presortreplace_zero )
+ local i,t,n,p,l
+ local group=""
+ local class=-1
+% \end{macrocode}
+% We build the \TeX{} index item command: \verb|\item|, \verb|\subitem|,
+% \verb|\subsubitem| etc. depending on the level. So \texttt{level} is simply
+% the number of \verb|sub| at the index item command.
+% \begin{macrocode}
+ local item="\\"
+ for l = 1, level, 1 do
+ item = item .. "sub"
+ end
+ item = item .. "item "
+% \end{macrocode}
+% Walk through all index items.
+% \begin{macrocode}
+ for i,t in ipairs( index ) do
+% \end{macrocode}
+% If \texttt{level} is 0, we are at the root index. We want to group this
+% Index into numbers, symbols and single letters. To do so, we detect the
+% class of the first character at the sort string and add \verb|\indexgroup|
+% commands if neccessary.
+% \begin{macrocode}
+ if ( level == 0 ) then
+ local sort=do_presortreplaces( t["sort"], presortreplace_zero )
+ local firstchar=unicode.utf8.upper( unicode.utf8.sub( sort, 1, 1 ) )
+ if ( firstchar ~= group ) then
+ local newclass
+% \end{macrocode}
+% The character differ, but we have to print the group only if the groups of
+% the characters differ.
+% \begin{macrocode}
+ newclass=getclass( firstchar )
+ if ( newclass == 1 and class ~= newclass ) then
+ tex.print( "\\indexgroup{\\symbolsname}" )
+ elseif ( newclass == 3 ) then
+ tex.print( "\\indexgroup{" .. firstchar .. "}" )
+ elseif ( newclass == 2 and class ~= newclass ) then
+ tex.print( "\\indexgroup{\\numbersname}" )
+ end
+ group=firstchar
+ class=newclass
+ end
+ end
+% \end{macrocode}
+% Now we have to print the index item. We use the \texttt{value} to be
+% printed. If one or more pagenumbers are stored, we print them too. If the
+% index entry has a sub index, we call \texttt{printsubindex} for this one
+% with increased level.
+% \begin{macrocode}
+ tex.sprint( item, t["value"] )
+ if t["pages"] then
+ tex.sprint( "\\indexpagenumbers{" )
+ for n,p in ipairs( t["pages"] ) do
+ tex.sprint( "\\indexpagenumber{", p, "}" )
+ end
+ tex.print( "}" )
+ end
+ if t["subindex"] then
+ printsubindex( level+1, t["subindex"], presortreplaces_zero )
+ end
+ end
+end
+% \end{macrocode}
+% Printing\marginpar{\makebox[0pt][l]{\color{mcode}^^A
+% \begin{tabular}[t]{@{}l@{}}
+% \texttt{printindex(\emph{index name})}\\
+% \end{tabular}%
+% }} a whole index is simply the same like printing a sub index, but before
+% printing the index, we have to test, wether the named index exists or
+% not.
+% \begin{macrocode}
+function printindex( indexname )
+ local index=indexes[indexname]
+ if index == nil then
+ tex.error( "Unknown index `" .. indexname .. "'",
+ { "You've tried to print an index, but there's no index with the",
+ "given name.",
+ "You should define the index using lua function ",
+ " `luaindex.newindex(\"" .. indexname .. "\")'",
+ "before."
+ }
+ )
+ else
+ print( "Index: \"" .. indexname .. "\" with " .. table.maxn( index ) .. " level-0-entries" )
+ tex.print( "\\begin{theindex}" )
+ printsubindex(0,indexes[indexname],indexes[indexname].presortreplaces[0])
+ tex.print( "\\end{theindex}" )
+ end
+end
+% \end{macrocode}
+%
+% To sort the index character classes numbers, letters and other are not
+% enough. So we build sub-classes\marginpar{\makebox[0pt][l]{\color{mcode}^^A
+% \begin{tabular}[b]{@{}l@{~}l@{}}
+% \texttt{local} & \texttt{getsubclass(} \\
+% & \enskip\texttt{\emph{utf8-char})}\\
+% \end{tabular}%
+% }} inside these three classes.
+% \begin{macrocode}
+local function getsubclass( utfc )
+ local i
+% \end{macrocode}
+% Inside letters we want so sort upper case before lower case.
+% \begin{macrocode}
+ for i in unicode.utf8.gmatch( utfc, "%l" ) do
+ return 1
+ end
+ for i in unicode.utf8.gmatch( utfc, "%u" ) do
+ return 2
+ end
+% \end{macrocode}
+% Inside other symbols we want so sort controls before spaces before
+% punctuations before numbers before unknown.
+% \begin{macrocode}
+ for i in unicode.utf8.gmatch( utfc, "%c" ) do
+ return 1
+ end
+ for i in unicode.utf8.gmatch( utfc, "%s" ) do
+ return 2
+ end
+ for i in unicode.utf8.gmatch( utfc, "%p" ) do
+ return 3
+ end
+ for i in unicode.utf8.gmatch( utfc, "%n" ) do
+ return 4
+ end
+ return 10 -- unkown is the biggest sub class
+end
+% \end{macrocode}
+% To compare\marginpar{\makebox[0pt][l]{\color{mcode}^^A
+% \begin{tabular}[t]{@{}l@{~}l@{}}
+% \texttt{local} & \texttt{do\_strcmp(} \\
+% & \enskip\texttt{\emph{first string},} \\
+% & \enskip\texttt{\emph{second string},} \\
+% & \enskip\texttt{\emph{sort order table})}\\
+% \end{tabular}%
+% }} two UTF8-strings we could simply use the string compare of
+% Lua. But for our purpose this is not enough. So we've added a configurable
+% sort order and now have to compare character by character depeding on this
+% sort order.
+% \begin{macrocode}
+local function do_strcmp( first, second, sortorderbychar )
+ local secondtable = string.explode( second, "" )
+ local firstutf
+ local n = 1
+%<debug> print( first .. ", " .. second );
+ for firstutf in string.utfcharacters( first ) do
+ local secondutf = unicode.utf8.sub( second, n, n )
+ n = n + 1;
+ if firstutf then
+ if secondutf ~= "" then
+%<debug> print( " " .. firstutf .. ", " .. secondutf )
+ if firstutf ~= secondutf then
+ local firstn, secondn
+ if sortorderbychar then
+ firstn = sortorderbychar[firstutf]
+ secondn = sortorderbychar[secondutf]
+ end
+% \end{macrocode}
+% If both characters were in the sort order table with different index we may
+% return -1, if the index of first was lower than second, and 1, if the index
+% of first was higher than second.
+% \begin{macrocode}
+ if firstn and secondn then
+%<debug> print( " n: " .. firstn .. ", " .. secondn )
+ if firstn < secondn then
+ return -1
+ elseif firstn > secondn then
+ return 1
+ end
+ else
+% \end{macrocode}
+% If one character was not in the sort order table, we compare the classes and
+% if same the sub-classes.
+% \begin{macrocode}
+ local firstclass = getclass( firstutf )
+ local secondclass = getclass( secondutf )
+ if firstclass < secondclass then
+ return -1
+ elseif firstclass == secondclass then
+ local firstsubclass = getsubclass( firstutf)
+ local secondsubclass = getsubclass( secondutf )
+ if firstsubclass < secondsubclass then
+ return -1
+ elseif firstsubclass == secondsubclass then
+ if firstutf < secondutf then
+ return -1
+ else
+ return 1
+ end
+ else
+ return 1
+ end
+ else
+ return 1
+ end
+ end
+ end
+ else
+% \end{macrocode}
+% If the first string was longer than the second, it is greater.
+% \begin{macrocode}
+ return 1
+ end
+ else
+% \end{macrocode}
+% If the first string was shorter than the second, it is lower.
+% \begin{macrocode}
+ if secondutf ~= "" then
+ return -1
+ else
+ return 0 -- This should never happen!
+ end
+ end
+ end
+% \end{macrocode}
+% If the first string was shorter than the second, it is lower. If not they
+% are same.
+% \begin{macrocode}
+ if unicode.utf8.sub( second, n, n ) ~= "" then
+ return -1
+ else
+ return 0
+ end
+end
+% \end{macrocode}
+%
+% Now we are able to compare\marginpar{%^^A
+% \makebox[0pt][l]{\color{mcode}^^A
+% \begin{tabular}[t]{@{}l@{~}l@{}}
+% \texttt{local} & \texttt{do\_indexcmp(} \\
+% & \enskip\texttt{\emph{first string},}\\
+% & \enskip\texttt{\emph{second string},}\\
+% & \enskip\texttt{\emph{replace tables},}\\
+% & \enskip\texttt{\emph{sort order table})}\\
+% \end{tabular}%
+% }} the sort value of two index entries. Before the
+% first compare we do the first pre-sort replace. All other pre-sort replaces
+% will be done only, if the sort entries are not same!
+% \begin{macrocode}
+local function do_indexcmp( firstsort, secondsort,
+ presortreplaces, sortorderbychar )
+ local pass = 0
+ local ncmp = 0
+ repeat
+ if presortreplaces and presortreplaces[pass] then
+ firstsort = do_presortreplaces( firstsort, presortreplaces[pass] )
+ secondsort = do_presortreplaces( secondsort, presortreplaces[pass] )
+%<debug> print( "Replace-Pass " .. pass .. ": " .. firstsort .. ", " .. secondsort )
+ end
+ pass = pass + 1
+ ncmp = do_strcmp( firstsort, secondsort, sortorderbychar )
+ until ( ncmp ~= 0 ) or ( pass > table.maxn( presortreplaces ) )
+%<*debug>
+ if ncmp < 0 then
+ print( firstsort .. "<" .. secondsort )
+ elseif ncmp == 0 then
+ print ( firstsort .. "=" .. secondsort )
+ else
+ print( firstsort .. ">" .. secondsort )
+ end
+%</debug>
+ return ncmp
+end
+% \end{macrocode}
+%
+% Inserting\marginpar{%^^A
+% \makebox[0pt][l]{\color{mcode}^^A
+% \begin{tabular}[t]{@{}l@{~}l@{}}
+% \texttt{local} & \texttt{subinsert(} \\
+% & \enskip\texttt{\emph{index table},}\\
+% & \enskip\texttt{\emph{replace tables},}\\
+% & \enskip\texttt{\emph{sort order table},}\\
+% & \enskip\texttt{\emph{page string},}\\
+% & \enskip\texttt{\emph{sort value},}\\
+% & \enskip\texttt{\emph{print value},}\\
+% & \enskip\dots\kern.1em\texttt{)}\\
+% \end{tabular}%
+% }} a new entry to an index is same like inserting a new entry to a
+% sub-index of an already existing entry. So we have only one local function
+% for this. A new entry consists of a page string, that should be added to the
+% page list of the entry, a sort value, that should be used to find the
+% correct entry and a print value, that should be shown at the index. Entries
+% are only same, if the compare of the sort value is 0 and the print values
+% are same. A new entry may be not only a new entry to the top level but to
+% sub levels. Because of this, there may be several pairs of sort- and print
+% values. We use bisection search to find the insert position.
+% \begin{macrocode}
+local function subinsert( index, presortreplaces, sortorderbychar,
+ pagestring, sortvalue, outputvalue, ... )
+ local min = 1
+ local max = table.maxn(index)
+ local updown = 0
+
+ local n = math.ceil(( min + max ) / 2)
+ while min <= max do
+ updown = do_indexcmp( sortvalue, index[n].sort,
+ presortreplaces, sortorderbychar )
+ if updown == 0 then
+% \end{macrocode}
+% The sort values are compared to be same (after serveral replaces). But only
+% if the print values are (without any replaces) same, we have to use this
+% entry. In this case we add a new sub-entry to this entry and if no new sub
+% entry was given the page string to the page table.
+% \begin{macrocode}
+ if outputvalue == index[n].value then
+%<debug> print( "The entries are same." )
+ if ( ... ) then
+%<debug> print( " Adding subentry to already existing entry" )
+ if ( index[n].subindex == nil ) then
+ index[n].subindex = {}
+ end
+ subinsert( index[n].subindex, presortreplaces, sortorderbychar,
+ pagestring, ... )
+ else
+%<debug> print( " Is the pagestring already at the pages table?" )
+ local i, p
+ for i, p in ipairs( index[n].pages ) do
+ if pagestring == p then
+%<debug> print( "The pagestring is already at the pages table." )
+%<debug> print( " We have nothing to do." )
+ return
+ end
+%<debug> print( pagestring, "!=", p )
+ end
+%<debug> print( "The pagestring was not at the pages table.",
+%<debug> "Add the new pagestring to the pages table",
+%<debug> "and stop processing." )
+ table.insert( index[n].pages, pagestring )
+ end
+ return
+ else
+% \end{macrocode}
+% If the print values are not same, we use sequential search for the position
+% after the last entry with same sort value but different print value. This is
+% the position to use for the new entry.
+% \begin{macrocode}
+%<debug> print( "The entries are not same.",
+%<debug> "Search for the last entry, with same sort." )
+ repeat
+ n = n + 1
+ if n <= max then
+ updown = do_indexcmp( sortvalue, index[min].sort,
+ presortreplaces, sortorderbychar )
+ end
+ until n > max or updown ~= 0
+ min = n
+ max = n-1
+ end
+ elseif updown > 0 then
+ min = n+1
+ else
+ max = n-1
+ end
+ n = math.ceil(( min + max ) / 2)
+%<debug> print ( min, max, n )
+ end
+% \end{macrocode}
+% if we have a new sub entry we add this to the new position. If not we simply
+% add the new entry with the page table.
+% \begin{macrocode}
+ if ( ... ) then
+%<debug> print( "Generating new entry without page but subindex" )
+ table.insert( index, n,
+ { sort=sortvalue, value=outputvalue, subindex={} } )
+%<debug> print( "Add subindex to new generated entry" )
+ subinsert( index[n].subindex, presortreplaces, sortorderbychar,
+ pagestring, ... )
+ else
+%<debug> print( "Generating new entry with page" )
+ table.insert( index, n,
+ { sort=sortvalue, value=outputvalue, pages={pagestring} } )
+ end
+end
+% \end{macrocode}
+% We've explained before, that inserting\marginpar{%^^A
+% \makebox[0pt][l]{\color{mcode}^^A
+% \begin{tabular}[t]{@{}l@{}}
+% \texttt{insert(\emph{index name},}\\
+% \enskip\texttt{\emph{page string},}\\
+% \enskip\texttt{\emph{sort value},}\\
+% \enskip\texttt{\emph{print value},}\\
+% \enskip\dots\kern.1em\texttt{)}\\
+% \end{tabular}%
+% }} a new entry is same like inserting a entry to a sub entry. There's only
+% one tiny difference: the replace tables and sort order are members of the
+% index table.
+% \begin{macrocode}
+function insert( indexname, pagestring, sortvalue, outputvalue, ... )
+ local index=indexes[indexname]
+ subinsert( index, index.presortreplaces, index.sortorderbychar,
+ pagestring, sortvalue, outputvalue, ... )
+end
+% \end{macrocode}
+%
+% Last we will need a function,\marginpar{^^A
+% \makebox[0pt][l]{\color{mcode}^^A
+% \texttt{removeentries(\emph{index name})}}} that only removes all index
+% entries but not presortreplaces or sortorderbychar.
+% \begin{macrocode}
+function removeentries( indexname )
+ local p = indexes[indexname].presortreplaces
+ local s = indexes[indexname].sortorderbychar
+ indexes[indexname]={ presortreplaces = p,
+ sortorderbychar = s }
+end
+% \end{macrocode}
+%
+% \iffalse meta-comment
+%</lua>
+% \fi^^A meta-comment
+%
+% \section{Implementation of \LaTeX{} Package \texttt{luaindex.sty}}
+%
+% \iffalse meta-comment
+%<*package>
+% \fi^^A meta-comment
+%
+% The \LaTeX{} package is user's candy but not necessary. You may use
+% \texttt{luaindex.lua} directly, but \LaTeX{} users will expect a \LaTeX{}
+% interface.
+%
+% \subsection{Package Startup}
+%
+% \LuaLaTeX{} must be used to use the package.
+% \begin{macrocode}
+\RequirePackage{ifluatex}
+\ifluatex\else
+ \PackageError{luaindex}{lualatex needed}{%
+ Package `luaindex' needs LuaTeX.\MessageBreak
+ So you should use `lualatex' to process you document!\MessageBreak
+ See documentation of `luaindex' for further information.}%
+ \expandafter\expandafter\expandafter\csname endinput\endcsname
+\fi
+% \end{macrocode}
+% \changes{v0.1b}{2011/02/18}{Using package \texttt{luatexbase-compat}}
+% \begin{macrocode}
+\RequirePackage{luatexbase-compat}[2010/10/10]
+% \end{macrocode}
+% \changes{v0.1b}{2011/02/18}{Using package \texttt{luatexbase-modutils}}
+% \begin{macrocode}
+\RequirePackage{luatexbase-modutils}[2010/10/10]
+% \end{macrocode}
+%
+% We need some \LuaTeX{} primitives:
+% \begin{macrocode}
+\luatexbase@ensure@primitive{luaescapestring}
+% \end{macrocode}
+%
+% We need some Lua functions:
+% \begin{macrocode}
+\directlua{%
+ if not tex.error then
+ luatexbase.module_error('luaindex',
+ 'undefined function!\string\n%
+ LuaTeX function tex.error() needed but not defined.\string\n%
+ Maybe you are using the wrong version of LuaTeX.')
+ end
+ if not tex.print then
+ luatexbase.module_error('luaindex',
+ 'undefined function!\string\n%
+ LuaTeX function tex.print() needed but not defined.\string\n%
+ Maybe you are using the wrong version of LuaTeX.')
+ end
+ if not tex.sprint then
+ luatexbase.module_error('luaindex',
+ 'undefined function!\string\n%
+ LuaTeX function tex.sprint() needed but not defined.\string\n%
+ Maybe you are using the wrong version of LuaTeX.')
+ end
+}
+% \end{macrocode}
+%
+% Load an initialize lua module. We could do this much later, but it is very,
+% very important, so we do is as soon as possible.
+% \begin{macrocode}
+\RequireLuaModule{luaindex}
+% \end{macrocode}
+%
+% With \texttt{luaindex} we use a temporary index file, too. This is
+% necessary, because page numbers are only valid while output routine. So
+% usage of a temporary index file is a good solution to have correct page
+% numbers. If this file exists, we load it simply while |\begin{document}| and
+% then produce an new one. But loading the old one is not simply an
+% |\input|. Out temporary index file is a Lua file, so we use Lua function
+% \texttt{dofile} to load it.
+% \begin{macrocode}
+\newwrite\@indexfile
+\AtBeginDocument{%
+ \IfFileExists{\jobname.ldx}{\directlua{dofile('\jobname.ldx')}}{}%
+ \openout\@indexfile=\jobname.ldx
+}
+% \end{macrocode}
+%
+% \subsection{Options}
+%
+% We use a key-value interface even for options. Because of this we're using
+% \KOMAScript{} package scrbase.
+% \begin{macrocode}
+\RequirePackage{scrbase}
+\DefineFamily{luaindex}
+\DefineFamilyMember{luaindex}
+% \end{macrocode}
+%
+% \begin{option}{sortorder}
+% \begin{macro}{\luaindex@sortorder}
+% Support for individual sort order. Sort order is an attribute of the index
+% root Lua table. Because of this the option simply saves it and it will be
+% setup later while defining new indexes.
+% \begin{macrocode}
+\newcommand*{\luaindex@sortorder}{}
+\DefineFamilyKey{luaindex}{sortorder}{%
+ \edef\luaindex@sortorder{#1}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{option}
+%
+% \begin{option}{locale}
+% If no individual sort order is given, the \emph{collate} locale would cause
+% the sort order. So we add an option make this locale changable. Note, that
+% changing this locale may also affect to other Lua functions!
+% \begin{macrocode}
+\DefineFamilyKey{luaindex}{locale}{%
+ \if@atdocument
+ \expandafter\@firstofone
+ \else
+ \expandafter\AtBeginDocument
+ \fi
+ {%
+ \protected@write\@indexfile{}{%
+ os.setlocale('#1','collate')
+ }%
+ }%
+}
+% \end{macrocode}
+% \end{option}
+%
+% \begin{option}{pageformat}
+% \begin{macro}{\luaindex@pageformat}
+% The page format is an attribute of every index entry. But you may define a
+% primary page format to be used, if no individual page format will be given.
+% \begin{macrocode}
+\newcommand*{\luaindex@pageformat}{}
+\DefineFamilyKey{luaindex}{pageformat}{%
+ \def\luaindex@pageformat{#1}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{option}
+%
+% \begin{option}{singlepass}
+% This option changes the general behavior of |\printindex|. See definition of
+% |\printindex| for more information about.
+% \begin{macrocode}
+\FamilyBoolKey{luaindex}{singlepass}{@luaindexsinglepass}
+% \end{macrocode}
+% \end{option}
+%
+% Processing all the options while loading the package.
+% \begin{macrocode}
+\FamilyProcessOptions{luaindex}\relax
+% \end{macrocode}
+%
+% \begin{macro}{\setupluaindex}
+% This is only an convenience command for run time setup of \texttt{luadindex}
+% options.
+% \begin{macrocode}
+\newcommand*{\setupluaindex}{\FamilyOptions{luaindex}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Some Usual Index Commands}
+%
+% \begin{macro}{\see}
+% \begin{macro}{\seealso}
+% |\see| and |\seealso| are common commands used at the page number
+% format. They are defined for compatibility. ^^A Fixme: Is this a good idea?
+% \begin{macro}{\seename}
+% \begin{macro}{\alsoname}
+% The two terms |\seename| and |\alsoname| are used by |\see| and |\seealso|
+% and needed to be defined also.
+% \begin{macrocode}
+\newcommand*\see[2]{\emph{\seename} #1}
+\providecommand*\seealso[2]{\emph{\alsoname} #1}
+\providecommand\seename{see}
+\providecommand*\alsoname{see also}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Generation of Indexes and Index Entries}
+%
+% \begin{macro}{\newindex}
+% We can handle not only one index but several indexes. To do so, we have to
+% create a new lua index table for each index. Just use
+% \begin{quote}|\newindex|\marg{index name}\end{quote} to do so. Additional
+% features may be set up using: \begin{quote}|\newindex|\oarg{index
+% options}\marg{index name}\end{quote} Currently all global options are
+% supported for \meta{index options}, but some will be ignored.
+% \begin{macrocode}
+\newcommand*{\newindex}[2][]{%
+ \directlua{luaindex.newindex('\luatexluaescapestring{#2}')}%
+ \begingroup
+ \setupluaindex{#1}%
+ \ifx\luaindex@sortorder\@empty\else
+ \AtBeginDocument{%
+ \protected@write\@indexfile{}{%
+ luaindex.sortorder('\luatexluaescapestring{#2}',
+ '\luaindex@sortorder')
+ }}%
+ \fi
+ \endgroup
+}
+% \end{macrocode}
+% You may use |\newindex| at the document preamble only.
+% \begin{macrocode}
+\@onlypreamble\newindex
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\luaindex}
+% This command will be used to add a new root level entry to an index:
+% \begin{quote}|\luaindex|\marg{index
+% name}\oarg{options}\marg{entry}\end{quote}
+% \begin{description}
+% \item[\normalfont\meta{index name}] -- the name of the index to be
+% used. This has to be the same like you've used to create the new index
+% using |\newindex|.
+% \item[\normalfont\meta{options}] -- several options for the index
+% entry. Currently supported are:
+% \begin{description}
+% \item[\normalfont\texttt{locale=}\meta{locale specifier}] -- just calls
+% |\luaindexsetup|\marg{locale specifier}. Note, that this is a global
+% action!
+% \item[\normalfont\texttt{pageformat=}\meta{command}] -- is a command with
+% at most one argument to format the page number of the index entry. You
+% may, e.\,g., use |sort=\see|\marg{reference} or
+% |sort=\seealso|{\marg{reference}} to produce a ``see'' or ``see also''
+% cross reference to \meta{reference} instead of showing a real page
+% number.
+% \item[\normalfont\texttt{sort=}\meta{sort entry}] -- destines the sort
+% position of the index entry. If it is omitted \meta{entry} will be used
+% instead.
+% \end{description}
+% \item[\normalfont\meta{entry}] -- this will be shown in the index.
+% \end{description}
+% Note: An index entry is only same, if \meta{sort entry} is same (after
+% several presort replaces) and \meta{entry} is same. Index entries
+% with same \meta{sort entry} but different \meta{entry} will be placed
+% at the current end of the entries with same \meta{sort entry}.
+% \begin{macrocode}
+\newcommand*{\luaindex}[1]{%
+ \@bsphack
+ \begingroup
+ \edef\luaindex@name{#1}%
+ \lua@index
+}
+\newcommand*{\lua@index}[2][]{%
+ \set@display@protect
+ \edef\luaindex@sort{#2}%
+ \define@key{luaindex.setindex}{sort}{\edef\luaindex@sort{##1}}%
+ \define@key{luaindex.setindex}{pageformat}{\def\luaindex@pageformat{##1}}%
+ \define@key{luaindex.setindex}{locale}{\luaindexsetup{locale=#1}}%
+ \setkeys{luaindex.setindex}{#1}%
+ \protected@write\@indexfile{\let\luatexluaescapestring\relax}{%
+ luaindex.insert('\luatexluaescapestring{\luaindex@name}',
+ '{\luatexluaescapestring{\luaindex@pageformat{\thepage}}}',
+ '\luatexluaescapestring{\luaindex@sort}',
+ '\luatexluaescapestring{#2}')
+ }%
+ \endgroup
+ \@esphack
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\luasubindex}
+% \begin{macro}{\lua@subindex}
+% \begin{macro}{\lua@@subindex}
+% Same like |\luaindex| but to produce a sub entry:
+% \begin{quote}|\luasubindex|\marg{index name}\oarg{options}\marg{entry}^^A
+% \linebreak[2]\oarg{options}\marg{sub-entry}\end{quote} Note, that the
+% \meta{options} for the \meta{sub-entry} only allows a sub-set of the options
+% shown for |\luaindex|. Currently only \texttt{sort=}\meta{sort entry}.
+% \begin{macrocode}
+\newcommand*{\luasubindex}[1]{%
+ \@bsphack
+ \begingroup
+ \edef\luaindex@name{#1}%
+ \lua@subindex
+}
+\newcommand*{\lua@subindex}[2][]{%
+ \set@display@protect
+ \edef\luaindex@sort{#2}%
+ \define@key{luaindex.setindex}{sort}{\edef\luaindex@sort{##1}}%
+ \define@key{luaindex.setindex}{pageformat}{\def\luaindex@pageformat{##1}}%
+ \define@key{luaindex.setindex}{locale}{\luaindexsetup{locale=#1}}%
+ \setkeys{luaindex.setindex}{#1}%
+ \protected@write\@indexfile{\let\luatexluaescapestring\relax}{%
+ luaindex.insert('\luatexluaescapestring{\luaindex@name}',
+ '{\luatexluaescapestring{\luaindex@pageformat{\thepage}}}',
+ '\luatexluaescapestring{\luaindex@sort}',
+ '\luatexluaescapestring{#2}',
+ }%
+ \aftergroup\lua@@subindex
+ \endgroup
+}
+\newcommand*{\lua@@subindex}[2][]{%
+ \begingroup
+ \set@display@protect
+ \edef\luaindex@sort{#2}%
+ \define@key{luaindex.setindex}{sort}{\edef\luaindex@sort{##1}}%
+ \setkeys{luaindex.setindex}{#1}%
+ \protected@write\@indexfile{\let\luatexluaescapestring\relax}{%
+ \@spaces
+ '\luatexluaescapestring{\luaindex@sort}',
+ '\luatexluaescapestring{#2}')
+ }%
+ \endgroup
+ \@esphack
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\luasubsubindex}
+% \begin{macro}{\lua@subsubindex}
+% \begin{macro}{\lua@@@subindex}
+% Same like |\luaindex| but to produce a sub-sub-entry, that is a sub-entry to
+% a sub-entry:
+% \begin{quote}|\luasubindex|\marg{index
+% name}\oarg{options}\marg{entry}\linebreak[2]^^A
+% \oarg{options}\marg{sub-entry}\linebreak[2]^^A
+% \oarg{options}\linebreak[2]\marg{sub-sub-entry}\end{quote}
+% Note, that the \meta{options} for the \meta{sub-entry} and the
+% \meta{sub-sub-entry} only allows a sub-set of the options shown for
+% |\luaindex|. Currently only \texttt{sort=}\meta{sort entry}.
+% \begin{macrocode}
+\newcommand*{\luasubsubindex}[1]{%
+ \@bsphack
+ \begingroup
+ \edef\luaindex@name{#1}%
+ \lua@subsubindex
+}
+\newcommand*{\lua@subsubindex}[2][]{%
+ \set@display@protect
+ \edef\luaindex@sort{#2}%
+ \define@key{luaindex.setindex}{sort}{\edef\luaindex@sort{##1}}%
+ \define@key{luaindex.setindex}{pageformat}{\def\luaindex@pageformat{##1}}%
+ \define@key{luaindex.setindex}{locale}{%
+ \luaindexsetup{locale=#1}%
+ }
+ \setkeys{luaindex.setindex}{#1}%
+ \protected@write\@indexfile{\let\luatexluaescapestring\relax}{%
+ luaindex.insert('\luatexluaescapestring{\luaindex@name}',
+ '{\luatexluaescapestring{\luaindex@pageformat{\thepage}}}',
+ '\luatexluaescapestring{\luaindex@sort}',
+ '\luatexluaescapestring{#2}',
+ }%
+ \aftergroup\lua@@@subindex
+ \endgroup
+}
+\newcommand*{\lua@@@subindex}[2][]{%
+ \begingroup
+ \set@display@protect
+ \edef\luaindex@sort{#2}%
+ \define@key{luaindex.setindex}{sort}{\edef\luaindex@sort{##1}}%
+ \setkeys{luaindex.setindex}{#1}%
+ \protected@write\@indexfile{\let\luatexluaescapestring\relax}{%
+ \@spaces
+ '\luatexluaescapestring{\luaindex@sort}',
+ '\luatexluaescapestring{#2}',
+ }%
+ \aftergroup\lua@@subindex
+ \endgroup
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\makeindex}
+% \begin{macro}{\index}
+% \begin{macro}{\subindex}
+% \begin{macro}{\subsubindex}
+% These are defined to increase compatibility to old index packages
+% only. Command |\makeindex| simply generates the new index named
+% \texttt{general} and the other commands to add entries to that index. Note,
+% that adding a sub-entry or sub-sub-entry is not yet compatible to other
+% index packages. You need to use the command |\subindex| and |\subsubindex|
+% instead of something like
+% |\index{|\meta{entry}|!|\meta{sub-entry}|!|\meta{sub-sub-entry}|}|. Note
+% also, that changing the format of the page number is not compatible with
+% other index packages. You have to use |\index[pageformat=|\meta{page
+% format}|]{|\dots\kern.1em|}| instead of something like
+% |\index{|\meta{entry}\verb+|+\meta{page format}|}|.
+% \begin{macrocode}
+\renewcommand*{\makeindex}{%
+ \newindex{general}%
+ \renewcommand*\index{\luaindex{general}}%
+ \newcommand*\subindex{\luasubindex{general}}%
+ \newcommand*\subsubindex{\luasubsubindex{general}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Printing an Index}
+%
+% We do not only want to create an index, we also need to print it.
+%
+% \begin{macro}{\printindex}
+% With
+% \begin{quote}|\printindex|\oarg{options}\end{quote}
+% you can print an index. The known options are
+% \begin{description}
+% \item[\normalfont\texttt{index=}\meta{index name}] -- print the index with
+% the given name as declared at |\newindex|. If you omit this option, index
+% ``\texttt{general}'' will be printed.
+% \item[\normalfont\texttt{singlepass=}\meta{boolean value}] -- you may switch
+% on and of the single pass feature. For the differences of single pass
+% feature on and off, see table~\ref{tab:singlepass}
+% \begin{table}
+% \centering
+% \caption{Implications of option \texttt{singlepass} to
+% \texttt{\string\printindex}}
+% \label{tab:singlepass}
+% \begin{tabularx}{\linewidth}{@{}>{\raggedright}X>{\raggedright}X}
+% \firsthline
+% \texttt{singlepass=false} & \texttt{singlepass=true} \tabularnewline
+% \hline
+% index of previous \LuaLaTeX{} run will be printed
+% & index of current \LuaLaTeX{} run will be printed
+% \tabularnewline[1ex]
+% start of index depends on the class
+% & start of the index at next page earliest
+% \tabularnewline[1ex]
+% index entries may be added to an index even after it has been printed
+% & no more index entries may be added to the index after it has been
+% printed
+% \tabularnewline
+% \lasthline
+% \end{tabularx}
+% \end{table}
+% \end{description}
+% \begin{macrocode}
+\newcommand*{\printindex}[1][]{%
+ \begingroup
+ \edef\luaindex@name{general}%
+ \define@key{luaindex.setindex}{index}{\edef\luaindex@name{##1}}%
+ \define@key{luaindex.setindex}{singlepass}[true]{%
+ \setupluaindex{singlepass}{##1}%
+ }%
+ \setkeys{luaindex.setindex}{#1}%
+ \if@luaindexsinglepass
+ \closeout\@indexfile
+ \clearpage
+ \directlua{%
+ luaindex.removeentries('\luatexluaescapestring{\luaindex@name}')
+ dofile('\jobname.ldx')
+ }%
+ \fi
+ \directlua{%
+ luaindex.printindex('\luatexluaescapestring{\luaindex@name}')
+ }%
+ \endgroup
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \texttt{luaindex.lua} uses several macros while printing the index. First of
+% all it uses the environment \texttt{theindex}. But several additional macros
+% will be used:
+%
+% \begin{macro}{\indexgroup}
+% \begin{macro}{\indexspace}
+% \begin{macro}{\symbolsname}
+% \begin{macro}{\numbersname}
+% Each index is grouped. Index groups are symbols, numbers and each first
+% letter. Each group starts with |\indexgroup|\marg{group} with group is
+% either |\symbolsname|, |\numbersname| or a upper case letter. In difference
+% to other index processors no automatic |\indexspace| will be added before
+% each group. So we define |\indexgroup| to add it.
+% \begin{macrocode}
+\providecommand*{\indexgroup}[1]{%
+ \indexspace\textbf{#1}\nopagebreak
+}
+\providecommand*{\indexspace}{%
+ \def\indexspace{\vskip\baselineskip}
+}
+\providecommand*{\symbolsname}{Symbols}
+\providecommand*{\numbersname}{Numbers}
+\AtBeginDocument{%
+ \providecaptionname{english}\symbolsname{Symbols}%
+ \providecaptionname{english}\numbersname{Numbers}%
+ \providecaptionname{german}\symbolsname{Symbole}%
+ \providecaptionname{german}\numbersname{Zahlen}%
+ \providecaptionname{ngerman}\symbolsname{Symbole}%
+ \providecaptionname{ngerman}\numbersname{Zahlen}%
+ \providecaptionname{austrian}\symbolsname{Symbole}%
+ \providecaptionname{austrian}\numbersname{Zahlen}%
+ \providecaptionname{naustrian}\symbolsname{Symbole}%
+ \providecaptionname{naustrian}\numbersname{Zahlen}%
+ \providecaptionname{french}\symbolsname{Symbole}%
+ \providecaptionname{french}\numbersname{Chiffres}%
+ \providecaptionname{spanish}\symbolsname{Simbolos}%
+ \providecaptionname{spanish}\numbersname{N\'umeros}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\indexpagenumbers}
+% \begin{macro}{\indexpagenumber}
+% \begin{macro}{\indexpagenumbersep}
+% \begin{macro}{\index@pagenumbersep}
+% The page numbers of an entry are printed all together as argument of
+% |\indexpagenumbers|\marg{page number}. Each single page number is printed as
+% argument of |\indexpagenumber|\marg{page number}. So separate the single
+% page numbers |\indexpagenumber| is predefined to add internal macro
+% |\index@pagenumbersep| before the page number. This will add
+% |\indexpagenumbersep| before each page number but the first one.
+% \begin{macrocode}
+\providecommand*{\indexpagenumbers}[1]{%
+ \def\index@pagenumbersep{\let\index@pagenumbersep\indexpagenumbersep}%
+ \nobreakspace-- #1}
+\providecommand*{\indexpagenumber}[1]{\index@pagenumbersep #1}
+\providecommand*{\indexpagenumbersep}{, }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \iffalse meta-comment
+%</package>
+% \fi^^A meta-comment
+%
+% \section{Examples}
+%
+% \iffalse meta-comment
+%<*example>
+% \fi^^A meta-comment
+%
+% Currently only one example file will be produced:
+% \begin{description}
+% \item[\normalfont\texttt{luaindex-example}] -- This should show index
+% entries, index sub-entries, index sub-sub-entries.
+% \begin{macrocode}
+\documentclass{article}
+\usepackage[ngerman]{babel}
+\usepackage{blindtext}
+\usepackage{fontspec}
+% \end{macrocode}
+% We load package \texttt{luaindex} with option \texttt{locale=de\_DE}. At
+% least at Linux this will add \"A, \"O, \"U, \"a, \"o, \"u, and \ss{} to the
+% letters and even set a valid sort order for those.
+%
+% We load package \texttt{luaindex} with option \texttt{singlepass} to produce
+% a valid index with one \LuaLaTeX{} run instead of two or more. But with this
+% printing of the index will produce a new page.
+% \begin{macrocode}
+\usepackage[
+ locale=de_DE,
+ singlepass % Wenn der Index ohnehin eine neue Seite produziert,
+ % dann kann er direkt beim ersten Lauf ein korrektes
+ % Ergebnis liefern.
+]{luaindex}
+% \end{macrocode}
+%
+% We use the compatibility command |\makeindex| to generate the ``general''
+% index and the further compatibility commands, e.g., |\index|.
+% \begin{macrocode}
+\makeindex
+% \end{macrocode}
+%
+% We want |\textbf| to be ignored at the sort:
+% \begin{macrocode}
+\directlua{luaindex.presortreplace('general',0,
+ '\luatexluaescapestring{\string\textbf}\space*\string\{([\string^\string\}]*)\string\}','\%1')}
+% \end{macrocode}
+%
+% Now we can start our document. This consist of some text and several index
+% entries.
+% \begin{macrocode}
+\begin{document}
+
+\blindtext[10]
+A\index{B ist der zweite Buchstabe}
+aber\index{aber ist ein Wort}
+D\index{D ist der vierte Buchstabe}
+A\index{A ist der erste Buchstabe}
+A\index{A ist der erste Buchstabe}
+% \end{macrocode}
+% Now, let's do something different. Let's show that babel shorthands may be
+% used inside index entries:
+% \begin{macrocode}
+C\index{C ist "`der"' dritte Buchstabe}
+X\index{X ist der drittletzte Buchstabe}
+% \end{macrocode}
+% And macros may also be used but change the sort sequence of the index!
+% \begin{macrocode}
+D\index{\textbf{D} ist der Buchstabe nach C}
+Y\index{Y ist der \textbf{vorletzte} Buchstabe}
+Z\index{Z ist der letzte Buchstabe}
+A\index{Ä ist auch ein Buchstabe}
+% \end{macrocode}
+% We may change the sort sequence manually by adding the \texttt{sort}
+% option. The page number format may also be changed using the
+% \texttt{pageformat} option.
+% \begin{macrocode}
+Ä\index[sort={Ä ist aber auch ein Buchstabe},%
+ pageformat=\emph]{Ä ist wirklich auch
+ ein Buchstabe (und hier stimmt die Sortierung
+ nicht -- \emph{aber eigentlich doch})}
+% \end{macrocode}
+% Let's add one more page with some more index entries:
+% \begin{macrocode}
+\clearpage
+
+A\index{A ist der erste Buchstabe}
+Ae\index{Ae ist kein Buchstabe, sondern zwei}
+
+% \end{macrocode}
+% And now, let's have some sub-entries and even a sub-sub-entry. One of the
+% sub-entries will become a different sort position and will be marked with an
+% emphasized page number.
+% \begin{macrocode}
+Kompliziert\subindex{Diverses}{Untereintrag}
+Noch komplizierter\subindex{Diverses}{Obereintrag}
+Noch komplizierter\%
+subindex{Diverses}[sort=Obereintra,pageformat=\emph]{Untereintrag}
+Noch komplizierter%
+\subsubindex{Diverses}{Untereintrag}{Unteruntereintrag}
+
+% \end{macrocode}
+% That's enough. Time time to print the index. Remember, that this is already
+% a valid index, because we are using option \texttt{singlepass}.
+% \begin{macrocode}
+\printindex
+\end{document}
+% \end{macrocode}
+% \end{description}
+%
+% \iffalse meta-comment
+%</example>
+% \fi^^A meta-comment
+%
+% \Finale
+%
+\endinput
+%% Local Variables:
+%% TeX-master: t
+%% TeX-PDF-mode: t
+%% TeX-engine: luatex
+%% flyspell-mode: t
+%% End:
diff --git a/macros/luatex/latex/luaindex/luaindex.pdf b/macros/luatex/latex/luaindex/luaindex.pdf
new file mode 100644
index 0000000000..8f640304f3
--- /dev/null
+++ b/macros/luatex/latex/luaindex/luaindex.pdf
Binary files differ
diff --git a/macros/luatex/latex/luainputenc/Makefile b/macros/luatex/latex/luainputenc/Makefile
new file mode 100644
index 0000000000..1ad5023e36
--- /dev/null
+++ b/macros/luatex/latex/luainputenc/Makefile
@@ -0,0 +1,94 @@
+# Makefile for luainputenc.
+
+NAME = luainputenc
+DOC = $(NAME).pdf
+DTX = $(NAME).dtx
+
+# Files grouped by generation mode
+COMPILED = $(DOC)
+UNPACKED = lutf8.def lutf8x.def inputenc.sty.diff \
+ luainputenc.sty luainputenc.lua
+SOURCE = $(DTX) README Makefile NEWS
+GENERATED = $(COMPILED) $(UNPACKED)
+
+# Files grouped by installation location
+UNPACKED_DOC = inputenc.sty.diff
+RUNFILES = $(filter-out $(UNPACKED_DOC) test.tex, $(UNPACKED))
+DOCFILES = $(DOC) $(UNPACKED_DOC) test.tex README NEWS
+SRCFILES = $(DTX) Makefile
+
+# The following definitions should be equivalent
+# ALL_FILES = $(RUNFILES) $(DOCFILES) $(SRCFILES)
+ALL_FILES = $(GENERATED) $(SOURCE)
+
+# Installation locations
+FORMAT = lualatex
+RUNDIR = $(TEXMFROOT)/tex/$(FORMAT)/$(NAME)
+DOCDIR = $(TEXMFROOT)/doc/$(FORMAT)/$(NAME)
+SRCDIR = $(TEXMFROOT)/source/$(FORMAT)/$(NAME)
+TEXMFROOT = ./texmf
+
+CTAN_ZIP = $(NAME).zip
+TDS_ZIP = $(NAME).tds.zip
+ZIPS = $(CTAN_ZIP) $(TDS_ZIP)
+
+DO_TEX = tex --interaction=batchmode $< >/dev/null
+DO_LATEXMK = latexmk -pdf -silent $< >/dev/null
+
+all: $(GENERATED)
+doc: $(COMPILED)
+unpack: $(UNPACKED)
+ctan: check $(CTAN_ZIP)
+tds: $(TDS_ZIP)
+world: all ctan
+.PHONY: all doc unpack ctan tds world check
+
+%.pdf: %.dtx
+ $(DO_LATEXMK)
+
+$(UNPACKED): $(DTX)
+ $(DO_TEX)
+
+check: $(UNPACKED)
+ lualatex --interaction=batchmode test.tex >/dev/null
+
+$(CTAN_ZIP): $(SOURCE) $(COMPILED) $(TDS_ZIP)
+ @echo "Making $@ for CTAN upload."
+ @$(RM) -- $@
+ @zip -9 $@ $^ >/dev/null
+
+define run-install
+@mkdir -p $(RUNDIR) && cp $(RUNFILES) $(RUNDIR)
+@mkdir -p $(DOCDIR) && cp $(DOCFILES) $(DOCDIR)
+@mkdir -p $(SRCDIR) && cp $(SRCFILES) $(SRCDIR)
+endef
+
+$(TDS_ZIP): TEXMFROOT=./tmp-texmf
+$(TDS_ZIP): $(ALL_FILES)
+ @echo "Making TDS-ready archive $@."
+ @$(RM) -- $@
+ $(run-install)
+ @cd $(TEXMFROOT) && zip -9 ../$@ -r . >/dev/null
+ @$(RM) -r -- $(TEXMFROOT)
+
+.PHONY: install manifest clean mrproper
+
+install: $(ALL_FILES)
+ @echo "Installing in '$(TEXMFROOT)'."
+ $(run-install)
+
+manifest:
+ @echo "Source files:"
+ @for f in $(SOURCE); do echo $$f; done
+ @echo ""
+ @echo "Derived files:"
+ @for f in $(GENERATED); do echo $$f; done
+
+clean:
+ @latexmk -silent -c *.dtx >/dev/null
+ @# for tex-only runs:
+ @$(RM) -- *.log
+
+mrproper: clean
+ @$(RM) -- $(GENERATED) $(ZIPS) test.*
+
diff --git a/macros/luatex/latex/luainputenc/NEWS b/macros/luatex/latex/luainputenc/NEWS
new file mode 100644
index 0000000000..ab5603073b
--- /dev/null
+++ b/macros/luatex/latex/luainputenc/NEWS
@@ -0,0 +1,27 @@
+ History of the luainputenc package
+
+2010/11/19 v0.973
+ * fix stupid bug introduced in 0.971, spotted by Benoît Rivet
+
+2010/11/10 v0.972
+ * adapt to luatexbase 0.3
+
+2010/11/05 v0.971
+ * improved documentation
+ * no longer loading luatextra
+ * fix bug under pdftex/xetex, thanks to Ulrike
+
+2010/05/11 v0.97
+ * adapting to the new luatexbase system
+
+2010/02/07 v0.96
+ * removing the files eu2enc.def and eu2lmr.fd from luainputenc, they
+ can now be found in the euenc package.
+ * creating luainputenc.package_option and luainputenc.encoding
+
+2009/11/28 v0.95
+ * fixing a bug with \endlinechar introduced in LuaTeX 0.43
+
+2009/09/23 v0.95
+ * adapting to the new callback process_output_buffer introduced in
+ LuaTeX v0.43.
diff --git a/macros/luatex/latex/luainputenc/README b/macros/luatex/latex/luainputenc/README
new file mode 100644
index 0000000000..90f2439640
--- /dev/null
+++ b/macros/luatex/latex/luainputenc/README
@@ -0,0 +1,78 @@
+ The luainputenc LaTeX2e package
+
+
+luainputenc is an adaptation of inputenc for LuaTeX, as the old inputenc does
+not work (at all) with the LuaTeX engine. It is used only for compatibility
+with old documents. New documents should be encoded in UTF-8 and use Unicode
+fonts (eg with a recent verion of the fontspec package).
+
+This package automatically calls the old inputenc when running with pdfTeX, and
+xetex-inputenc when running XeTeX, so you can safely use it with all your
+documents.
+
+This package is developed on <http://github.com/mpg/luainputenc>, see the 'NEWS'
+file for version history.
+
+Installation
+------------
+
+Here are the recommended installation methods (preferred first).
+
+1. If you are using TeX Live 2008 or later, use 'tlmgr install luainputenc'.
+Alternatively, try your (TeX or Linux) distribution's package management system.
+
+2. a. Grab luainputenc.tds.zip on the CTAN.
+ b. Unzip it at the root of one or your TDS trees.
+ c. You may need to update some filename database after, see your TeX
+distribution's manual for details.
+
+3. a. Grab the sources from CTAN or github.
+ b. Run 'make install TEXMFROOT=/path/to/texmf'.
+ c. See 2c.
+
+
+Manifest
+--------
+
+Source files:
+ luainputenc.dtx the single file source & doc
+
+Derived files:
+ luainputenc.pdf the documentation
+ luainputenc.sty the LaTeX package
+ luainputenc.lua the lua functions for encoding translation
+ lutf8.def replacement for utf8.def
+ lutf8x.def idem, with new functionalities for Unicode fonts
+ inputenc.sty.diff: patch for inputenc.sty to load luainputenc
+ automatically if running LuaTeX
+
+License
+-------
+
+This work is under the CC0 license, with an additional restriction:
+the article 6 of the LaTeX Project Public License (lppl), that applies to code
+that has been taken from LaTeX files.
+
+You can find the text of the lppl at
+
+The lppl can be found at http://www.latex-project.org/lppl.txt
+
+You can find the CC0 full text at
+
+http://creativecommons.org/publicdomain/zero/1.0/legalcode
+
+The file luainputenc.dtx contains code with the lppl restriction as well as the
+derived files
+ luainputenc.sty
+ luainputenc.pdf
+ lutf8.def
+ lutf8x.def
+
+For further details about their license, please see the comments in these files.
+
+The other derived files are
+ luainputenc.lua
+ inputenc.sty.diff
+
+These files are under the CC0 license only.
+
diff --git a/macros/luatex/latex/luainputenc/luainputenc.dtx b/macros/luatex/latex/luainputenc/luainputenc.dtx
new file mode 100644
index 0000000000..807d7344b8
--- /dev/null
+++ b/macros/luatex/latex/luainputenc/luainputenc.dtx
@@ -0,0 +1,1464 @@
+% \iffalse meta-comment -- by the way, this file contains UTF-8
+%
+% Written in 2009, 2010 by Manuel Pégourié-Gonnard and Élie Roux.
+% <mpg@elzevir.fr>
+% <elie.roux@telecom-bretagne.eu>
+%
+% This work is under the CC0 license. As an exception, the files
+% luainputenc.sty, lutf8.def and lutf8x.def have more restrictions.
+% See these file for more details.
+%
+% People who helped on this package:
+% Javier Bezos
+% Will Robertson
+% Hans Hagen
+% Heiko Oberdiek
+% Javier Mugica
+%
+% This work consists of the main source file luainputenc.dtx
+% and the derived files
+% luainputenc.sty, luainputenc.lua, lutf8.def, lutf8x.def,
+% and luainputenc.pdf
+%
+% Unpacking:
+% tex luainputenc.dtx
+% Documentation:
+% pdflatex luainputenc.dtx
+%
+%<*ignore>
+\begingroup
+ \def\x{LaTeX2e}%
+\expandafter\endgroup
+\ifcase 0\ifx\install y1\fi\expandafter
+ \ifx\csname processbatchFile\endcsname\relax\else1\fi
+ \ifx\fmtname\x\else 1\fi\relax
+\else\csname fi\endcsname
+%</ignore>
+%<*install>
+\input docstrip.tex
+
+\keepsilent
+\askforoverwritefalse
+
+\let\MetaPrefix\relax
+
+\preamble
+This is a generated file.
+
+Written in 2009, 2010 by Manuel Pegourie-Gonnard and Elie Roux.
+
+This work is under the CC0 license. As an exception, the files
+luainputenc.sty, lutf8.def and lutf8x.def have more restrictions.
+See these file for more details.
+
+People who helped on this package:
+ Javier Bezos
+ Will Robertson
+ Hans Hagen
+ Heiko Oberdiek
+ Javier Mugica
+
+This work consists of the main source file luainputenc.dtx
+and the derived files
+ luainputenc.sty, luainputenc.lua, lutf8.def, lutf8x.def,
+ and luainputenc.pdf
+
+\endpreamble
+
+\let\MetaPrefix\DoubleperCent
+
+\generate{%
+ \usedir{tex/lualatex/luainputenc}%
+ \file{luainputenc.sty}{\from{luainputenc.dtx}{package}}%
+ \file{lutf8.def}{\from{luainputenc.dtx}{def}}%
+ \file{lutf8x.def}{\from{luainputenc.dtx}{defx}}%
+}
+
+\generate{%
+ \usedir{doc/luatex/luainputenc}%
+ \file{test.tex}{\from{luainputenc.dtx}{test}}%
+}
+
+\def\MetaPrefix{-- }
+
+\def\luapostamble{%
+ \MetaPrefix^^J%
+ \MetaPrefix\space End of File `\outFileName'.%
+}
+
+\def\currentpostamble{\luapostamble}%
+
+\generate{%
+ \usedir{tex/lualatex/luainputenc}%
+ \file{luainputenc.lua}{\from{luainputenc.dtx}{lua}}%
+}
+
+\nopreamble
+\nopostamble
+
+\generate{%
+ \file{inputenc.sty.diff}{\from{luainputenc.dtx}{patch}}%
+}
+
+\obeyspaces
+\Msg{************************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* files into a directory searched by TeX:}
+\Msg{*}
+\Msg{* luainputenc.sty luainputenc.lua lutf8.def lutf8x.def}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+% \iffalse
+%<package>
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{luainputenc}
+%<package> [2010/11/19 v0.973 inputenc package for LuaTeX]
+%<package>
+% \fi
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{textcomp}
+\usepackage{lmodern}
+\usepackage{metalogo}
+\usepackage[lmargin=5cm, textwidth=14cm]{geometry}
+\usepackage[bookmarks=true, colorlinks=true]{hyperref}
+\usepackage{bookmark}
+\usepackage[english]{babel}
+\providecommand\eTeX{e\TeX}
+\newcommand\pf{\textsf}
+\newcommand\file{\texorpdfstring{\nolinkurl}{}}
+\newcommand\code{\texttt}
+\newcommand*\email[1]{\href{mailto:#1}{#1}}
+\begin{document}
+ \DocInput{luainputenc.dtx}%
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{0}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+% \title{The \textsf{luainputenc} package}
+% \date{2010/11/19 v0.973}
+% \author{%
+% Manuel P\'egouri\'e-Gonnard \email{mpg@elzevir.fr} \\
+% \'Elie Roux \email{elie.roux@telecom-bretagne.eu}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% Input encoding management for Lua\TeX, needed only for compatibility with
+% old documents. For new documents, using UTF-8 encoding and Unicode fonts is
+% \emph{strongly} recommended. You've been warned!
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Overview: When (not) to use this package}
+%
+% This package is strictly meant for compatibility. It is usefull in the two
+% (overlapping) following cases:
+% \begin{enumerate}
+% \item Your source is not encoded in UTF-8 and you don't want to reencode it
+% for some reason.
+% \item Your document is using legacy 8-bit fonts (with \pf{fontenc}), as
+% opposed to modern Unicode fonts (most probably with \pf{fontspec} or
+% \pf{luaotfload} and \pf{fontenc} with option \code{EU2}).
+% \end{enumerate}
+% Surprisingly enough, in the second case \pf{luainputenc} is needed, due to
+% the way \LaTeX\ implements font encodings.
+%
+% From the user point of view, adapting an old document for \LuaTeX\ is really
+% easy: replacing \pf{inputenc} by \pf{luainputenc} in the preamble is
+% enough.
+%
+% Note that \pf{luainputenc} automatically loads \pf{inputenc} if called
+% with an old engine, so you will still be able to compile your documents with
+% pdf\TeX\ without changing them.
+%
+% \pf{luainputenc} has several modes of operation. By default, it basically
+% turns \LuaTeX\ into an 8-bit engine, which means you loose half of the
+% benefits from using \LuaTeX. If you are using only Unicode fonts, you can
+% activate a nicer mode of operation using the \code{unactivate} package
+% option. That way, \LuaTeX\ remains a true Unicode engine.
+%
+% Unicode fonts with \LuaTeX\ are handled using a new encoding: \code{EU2}. It
+% is used internally by the \pf{fontspec} package when loading Unicode fonts.
+% This encoding is special as it needs non-ASCII characters to be non-active
+% (unlike other font encodings), so you cannot mix old encodings and EU2. If
+% you're using only Unicode fonts, this isn't a problem: use the
+% \code{unactivate} package option mentioned in the previous paragraph.
+%
+% But if you
+% want to use both 8-bit fonts and Unicode fonts in your document, you need to
+% use another package option, \code{lutf8x}. This option
+% overrides \LaTeX's mechanism for font encoding switching, so that it
+% (un)activates non-ASCII characters on-the-fly. With this options, you'll be
+% able change the font encoding from/to \code{EU2}, for example:
+%
+% \begin{verbatim}
+% abc
+% {
+% \fontencoding{EU2}\usefont
+% \font\foo="MyOtfFont.otf"\foo
+% abc
+% }
+% abc
+% \end{verbatim}
+%
+% \section{Documentation}
+%
+% \subsection{Introduction}
+%
+% One the the most interesting new features of Lua\TeX\ is the fact that it is
+% (like Omega/Aleph) not limited to 256 characters, and can now understand
+% Unicode. The problem is that it does not read input the way older engines
+% (like pdf\TeX) do, and thus \textsf{inputenc} is totally broken with Lua\TeX
+% . This package aims at replacing \textsf{inputenc} for Lua\TeX , by adapting
+% the way Lua\TeX\ handles input, and the way \textsf{inputenc} handles UTF-8.
+% This package has two very distinct modes: 8-bit and UTF-8.
+%
+% \subsection{Overview of 8-bit mode}
+%
+% This package \textbf{does not} map 8-bit encodings to utf8. It allows
+% Lua\TeX\ to read 8-bit characters, by converting each byte into a unicode
+% character with the same character number. The resulting unicode characters
+% are not true UTF-8, they are what we will call ``fake UTF-8". For example
+% the byte 225 will be converted into the unicode character with number 225
+% (two bytes long). It will be true UTF-8 only if the encoding is latin1.
+%
+% Here is how it works: the 8-bit encodings are converted into fake UTF-8, so
+% that the corresponding tokens are chars with the good numbers. Then (like
+% \textsf{inputenc}) it reads the char numbers, and converts it into LICR
+% (\LaTeX\ Internal Character Representation), with the font encoding.
+%
+% In Lua\TeX\ version 0.43, a new callback called |process_output_buffer|,
+% this callbacks allows to make Lua\TeX\ write 8-bit instead of UTF-8, so the
+% behaviour is the same as pdfTeX as this level. For versions prior to 0.43
+% though, we need to do more tricky things, described in the next paragraph.
+% This machinery is disabled for Lua\TeX\ version 0.43 and superior, so you
+% can keep the default behaviour, which will be compatible with pdfTeX in
+% most cases, but you can consider the machinery obsolete.
+%
+% For these old versions, \textsf{luainputenc} only changes the input
+% behaviour, it does not change the ouput behaviour (when files are written
+% for example). The consequence is that files will still be written by
+% Lua\TeX\ in UTF-8 (fake UTF-8 in this case), even if the asked input
+% encoding is a 8-bit encoding. In most cases it's not a problem, as most
+% files will be written in LICR, meaning ASCII, which is both 8-bit and UTF-8.
+% The problem comes when characters with a number $>$ 128 are written in a
+% 8-bit encoding. This may happen if you use |\protect| in a section for
+% example. In these cases, Lua\TeX\ will write fake UTF-8, and try to read
+% 8-bit encoding, so it will get confused.
+%
+% The proposed solution is to unactivate the input conversion when we read
+% certain files or extentions. This package should work with no change for
+% most documents, but if you cook your own aux files with an unknown
+% extention, you may have to force the package to read some files in UTF-8
+% instead of 8-bit. See comments in the \texttt{.sty} file to know the useful
+% commands.
+%
+% \subsection{Overview of UTF-8 mode}
+%
+% The behaviour of \textsf{inputenc} in utf8 mode is to read the input byte by
+% byte, and decide if the character we are in is 1, 2, 3 or 4 bytes long, and
+% then read other bytes accordingly. This behaviour fails with Lua\TeX\
+% because it reads input character by character (characters do not have a
+% fixed number of bytes in unicode). The result is thus an error.
+%
+% All characters recognized by \TeX\ are active characters, that correspond to
+% a LICR macro. Then \textsf{inputenc} reads the \texttt{*.dfu} files that
+% contain the correspondance between these LICR macros and a character number
+% in the fonts for different font encodings (T1, OT1, etc.).
+%
+% \subsubsection{legacy mode}
+%
+% \textsf{luainputenc} can get this behaviour (we will call it \emph{legacy
+% mode}, but another difference implied by the fact that Lua\TeX\ can read
+% more than 256 characters is that fonts can also have more than 256
+% characters. Lua\TeX\ can thus read unicode fonts. If we want to use unicode
+% fonts (OTF for example), we can't use the \emph{legacy mode} anymore, as it
+% would mean that we would have to rewrite a specially long
+% \texttt{unicode.dfu} file, and it would be totally inefficient, as for
+% instance \texttt{\'e} (unicode character number 233) would be mapped to
+% \texttt{\string\'e}, and then mapped back to \texttt{\string\char\ 233}.
+%
+% \subsubsection{unicode font mode}
+%
+% To fix this, the most simple solution is to desactivate all activated
+% characters, thus typing \texttt{\'e} will directly call
+% \texttt{\string\char\ 233} in the unicode fonts, and produce a \texttt{\'e}.
+% We will call this behaviour the \emph{unicode font mode}. To enable this
+% mode, you can use the option \texttt{unactivate} in \textsf{luainputenc},
+% and you must use the font encoding \texttt{EU2} provided by the \textsf{euenc}
+% package. See documentation of \textsf{euenc} package for more details about
+% \texttt{EU2}. To use this mode with \texttt{EU2}, you must be able to open OTF
+% fonts. A simple way to do so it by using the package \textsf{luaotfload}.
+%
+% \subsubsection{mixed mode}
+%
+% But the \emph{unicode font mode} has a strong limitation (that will
+% certainly dissapear with time): it cannot use non-unicode fonts. If you want
+% to mix unicode fonts and old fonts, you'll have to use the \emph{mixed
+% mode}. In this mode you can type some parts of your document in \emph{legacy
+% mode} and some in \emph{unicode font mode}. The reason why we chose not to
+% integrate this choice in the \emph{legacy mode} is that we wanted to have a
+% mode that preserved most of the backward compatibility, to safely compile
+% old documents; the \emph{mixed mode} introduces new things that may break
+% old documents. To get the \emph{mixed mode}, you must pass the option
+% \texttt{lutf8x} to \textsf{luainputenc}. This mode is the most experimental.
+%
+% \section{Accessing the encoding in lua}
+%
+% In order to access the encoding and the package option in lua, two variables
+% are set: |luainputenc.package_option| contains the option passed to the
+% package, and |luainputenc.encoding| that contains the encoding (defaults to
+% utf8, and is utf8 even with the options |unactivate|, |utf8x|, etc.).
+%
+% \section{Files}
+%
+% This package contains a \texttt{.sty} file for both \LaTeX\ and Plain, a
+% patch for inputenc to use \textsf{luainputenc} so that you can process old
+% documents without changing anything, and the lua functions.
+%
+% \subsection{\texttt{inputenc.sty} patch}
+%
+% A good thing would be to patch \textsf{inputenc} to load
+% \textsf{luainputenc} instead, so that you don't have to change your
+% documents to load \textsf{luainputenc} especially. The \LaTeX\ team is
+% extremely conservative and does not want this patch applied (maybe we will
+% find a solution later). Here is a patch for inputenc.sty:
+%
+% \iffalse
+%<*patch>
+% \fi
+%
+% \begin{macrocode}
+
+ \ifnum\@tempcnta<`#2\relax
+ \advance\@tempcnta\@ne
+ \repeat}
++
++\begingroup\expandafter\expandafter\expandafter\endgroup
++\expandafter\ifx\csname XeTeXversion\endcsname\relax\else
++ \RequirePackage{xetex-inputenc}
++ \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{xetex-inputenc}}
++ \ProcessOptions*
++ \expandafter\endinput
++\fi
++\begingroup\expandafter\expandafter\expandafter\endgroup
++\expandafter\ifx\csname directlua\endcsname\relax\else
++ \RequirePackage{luainputenc}
++ \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{luainputenc}}
++ \ProcessOptions*
++ \expandafter\endinput
++\fi
++
+ \ProcessOptions
+ \endinput
+ %%
+
+% \end{macrocode}
+%
+% \iffalse
+%</patch>
+% \fi
+%
+% \subsection{\texttt{luainputenc.sty}}
+%
+% This file has some code from \texttt{inputenc.sty}, but also provides new
+% options, and new macros to convert from 8-bit to fake UTF-8.
+%
+% \iffalse
+%<*package>
+% \fi
+%
+% \begin{macrocode}
+%
+%% This file was adapted from inputenc.sty, which copyright is:
+%% Copyright 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004
+%% 2005 2006 The LaTeX3 Project.
+%%
+%% inputenc.sty is under the lppl version 1.3c or later, and can be
+%% found in the base LaTeX system.
+%%
+%% The lppl can be found at http://www.latex-project.org/lppl.txt
+%%
+%% The changes to inputenc.sty are Copyright 2009 Elie Roux, and are
+%% under the CC0 license.
+%%
+%% The changes are LuaTeX support.
+%%
+%% This file is distributed under the CC0 license, with clause 6 of the
+%% lppl as additional restrictions.
+
+% \end{macrocode}
+%
+% First we check if we are called with Lua\TeX , (pdf)\TeX or Xe\TeX . If
+% we are called with pdf\TeX , we default to \textsf{inputenc}, and to
+% \textsf{xetex-inputenc} if we are called with Xe\TeX . We also remap the
+% new options to \texttt{utf8} in these cases.
+%
+% \begin{macrocode}
+
+\RequirePackage{ifluatex}
+\RequirePackage{ifxetex}
+
+\ifxetex
+ \DeclareOption{unactivate}{\PassOptionsToPackage{utf8}{xetex-inputenc}}
+ \DeclareOption{lutf8}{\PassOptionsToPackage{utf8}{xetex-inputenc}}
+ \DeclareOption{lutf8x}{\PassOptionsToPackage{utf8}{xetex-inputenc}}
+ \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{xetex-inputenc}}
+ \ProcessOptions*
+ \RequirePackage{xetex-inputenc}
+ \expandafter\endinput
+\fi
+
+\ifluatex\else
+ \DeclareOption{unactivate}{\PassOptionsToPackage{utf8}{inputenc}}
+ \DeclareOption{lutf8}{\PassOptionsToPackage{utf8}{inputenc}}
+ \DeclareOption{lutf8x}{\PassOptionsToPackage{utf8}{inputenc}}
+ \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{inputenc}}
+ \ProcessOptions*
+ \RequirePackage{inputenc}
+ \expandafter\endinput
+\fi
+
+% \end{macrocode}
+%
+% Here we know we are called with Lua\TeX . We first require
+% \textsf{luatextra} and ensure a few primitives, then we load the
+% \texttt{lua} file.
+%
+% \begin{macrocode}
+
+\RequirePackage{luatexbase}
+\luatexbase@ensure@primitive{luaescapestring}
+
+\RequireLuaModule{luainputenc}
+
+% \end{macrocode}
+%
+% Here is some code from \textsf{inputenc}.
+%
+% \begin{macrocode}
+
+\def\DeclareInputMath#1{%
+ \@inpenc@test
+ \bgroup
+ \uccode`\~#1%
+ \uppercase{%
+ \egroup
+ \def~%
+ }%
+}
+\def\DeclareInputText#1#2{%
+ \def\reserved@a##1 ${}%
+ \def\reserved@b{#2}%
+ \ifcat_\expandafter\reserved@a\meaning\reserved@b$ $_%
+ \DeclareInputMath{#1}{#2}%
+ \else
+ \DeclareInputMath{#1}{\IeC{#2}}%
+ \fi
+}
+\def\IeC{%
+ \ifx\protect\@typeset@protect
+ \expandafter\@firstofone
+ \else
+ \noexpand\IeC
+ \fi
+}
+% \end{macrocode}
+%
+% We changed a little the behaviour of this macro: we removed
+% |\@inpenc@loop\^^?\^^ff|, because it made no sense in UTF-8 mode. We will
+% call this line for 8-bit encodings.
+%
+% Note that the code has been changed for |\endlinechar|, because in new
+% versions (from v0.43) of Lua\TeX{} the value cannot exceed 127.
+% Thus, with the old version of \textsf{luainputenc}, when trying
+% to add 10000, it fails silently, and when 10000 is substracted, the
+% new value is -1, resulting in no end of lines at all in the document.
+%
+% \begin{macrocode}
+
+\def\inputencoding#1{%
+ \the\inpenc@prehook
+ \gdef\@inpenc@test{\global\let\@inpenc@test\relax}%
+ \edef\@inpenc@undefined{\noexpand\@inpenc@undefined@{#1}}%
+ \edef\inputencodingname{#1}%
+ \@inpenc@loop\^^A\^^H%
+ \@inpenc@loop\^^K\^^K%
+ \@inpenc@loop\^^N\^^_%
+ \xdef\saved@endlinechar{\the\endlinechar }%
+ \endlinechar=-1
+ \xdef\saved@space@catcode{\the\catcode`\ }%
+ \catcode`\ 9\relax
+ \input{#1.def}%
+ \endlinechar=\saved@endlinechar{}%
+ \catcode`\ \saved@space@catcode\relax
+ \ifx\@inpenc@test\relax\else
+ \PackageWarning{inputenc}%
+ {No characters defined\MessageBreak
+ by input encoding change to `#1'\MessageBreak}%
+ \fi
+ \the\inpenc@posthook
+ \luatexbase@directlua{luainputenc.set_option("\luatexluaescapestring{#1}")}
+}
+\newtoks\inpenc@prehook
+\newtoks\inpenc@posthook
+\def\@inpenc@undefined@#1{\PackageError{inputenc}%
+ {Keyboard character used is undefined\MessageBreak
+ in inputencoding `#1'}%
+ {You need to provide a definition with
+ \noexpand\DeclareInputText\MessageBreak or
+ \noexpand\DeclareInputMath before using this key.}}%
+\def\@inpenc@loop#1#2{%
+ \@tempcnta`#1\relax
+ \loop
+ \catcode\@tempcnta\active
+ \bgroup
+ \uccode`\~\@tempcnta
+ \uppercase{%
+ \egroup
+ \let~\inpenc@undefined
+ }%
+ \ifnum\@tempcnta<`#2\relax
+ \advance\@tempcnta\@ne
+ \repeat}
+
+% \end{macrocode}
+%
+% Here we declare our options. Note that we remap \texttt{utf8} to
+% \texttt{lutf8}, because we use out \texttt{lutf8.def} instead of
+% \textsf{inputenc}'s \texttt{utf8.def}.
+%
+% \begin{macrocode}
+
+\DeclareOption{utf8}{%
+ \inputencoding{lutf8}%
+}
+
+\DeclareOption{lutf8}{%
+ \inputencoding{lutf8}%
+}
+
+\DeclareOption{utf8x}{%
+ \inputencoding{lutf8}%
+}
+
+\DeclareOption{lutf8x}{%
+ \inputencoding{lutf8x}%
+}
+
+% \end{macrocode}
+%
+% For the \texttt{unactivate} option, for \emph{unicode font mode}, we just
+% don't do anything.
+%
+% \begin{macrocode}
+
+\DeclareOption{unactivate}{%
+ \edef\inputencodingname{unactivate}%
+ \luatexbase@directlua{luainputenc.set_option([[unactivate]])}
+}
+
+% \end{macrocode}
+%
+% All other options are 8-bit encodings, so we activate the translation
+% into fake UTF-8, and we execute the loop we removes from
+% |\inputencoding|.
+%
+% \begin{macrocode}
+
+\DeclareOption*{%
+ \lIE@activate %
+ \@inpenc@loop\^^?\^^ff%
+ \inputencoding{\CurrentOption}%
+}
+
+% \end{macrocode}
+%
+% The rest of the file is only the machinery for LuaTeX versions without
+% the callback |process_output_buffer|, so it will be deprecated after
+% TeXLive 2009, you are not advised to use it.
+%
+% \begin{macrocode}
+
+\ifnum\luatexversion>42
+
+ \newcommand*{\lIE@activate}[0]{%
+ \luatexbase@directlua{luainputenc.register_callbacks()}%
+ }
+
+\else
+
+% \end{macrocode}
+%
+% |\lIE@setstarted| and |\lIE@setstopped| are called when the fake UTF-8
+% translation must be activated or desactivated. You can call them several
+% successive times. They are called very often, even if the package is not
+% activated (for example if it's loaded with the utf8 option), but they act
+% only if the package is activated.
+%
+% \begin{macrocode}
+
+\newcommand*\lIE@setstarted[0]{%
+ \ifnum\lIE@activated=1 %
+ \luatexbase@directlua{luainputenc.setstarted()}%
+ \fi %
+}
+
+\newcommand*\lIE@setstopped[0]{%
+ \ifnum\lIE@activated=1 %
+ \luatexbase@directlua{luainputenc.setstopped()}%
+ \fi %
+}
+
+% \end{macrocode}
+%
+% The following 5 macros are made to declare a file that will have to be
+% read in fake UTF-8 and not in 8-bit. These files are the ones that will
+% be generated by \TeX . In \textbf{no way} this means you can include true
+% UTF-8 files, it means that you can include files that have been written
+% by Lua\TeX\ with \textsf{luainputenc}, which means files in fake UTF-8.
+% The macros are very simple, when you call them with a file name (the same
+% as the one you will use with \string\input ), it will read it with or
+% without the fake UTF-8 translation. This package includes a whole bunch
+% of extentions that will be read in fake UTF-8, so the occasions to use
+% these macros will be rare, but if you use them, please report it to the
+% package maintainer.
+%
+% \begin{macro}{\lIE@SetUtfFile}
+%
+% If you call this macro with a file name, each time you will input this
+% file, it will be read in fake UTF-8. You can call it with a file that you
+% generate with Lua\TeX\ and that you want to include.
+%
+% \begin{macrocode}
+
+\newcommand*\lIE@SetUtfFile[1]{%
+ \luatexbase@directlua{luainputenc.set_unicode_file("\luatexluaescapestring{#1}")}%
+}
+
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\lIE@SetNonUtfFile}
+%
+% Same as the previous macro, except that the file will be read as 8-bit.
+% This macro is useful if there is an exception in an extention (see
+% further comments).
+%
+% \begin{macrocode}
+
+\newcommand*\lIE@SetNonUtfFile[1]{%
+ \luatexbase@directlua{luainputenc.set_non_unicode_file("\luatexluaescapestring{#1}")}%
+}
+
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\lIE@UnsetFile}
+%
+% This macro gives a file the default behaviour of its extention.
+%
+% \begin{macrocode}
+
+\newcommand*\lIE@UnsetFile[1]{%
+ \luatexbase@directlua{luainputenc.unset_file("\luatexluaescapestring{#1}")}%
+}
+
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\lIE@SetUtfExt}
+%
+% You can tell \textsf{luainputenc} to treat all files with a particular
+% extention in a certain way. The way the file extention is checked is to
+% compare the four last characters of the filename. So if your extention
+% has only three letters, you must include the preceding dot. This macro
+% tells \textsf{luainputenc} to read all files from an extention in fake
+% UTF-8.
+%
+% \begin{macrocode}
+
+\newcommand*\lIE@SetUtfExt[1]{%
+ \luatexbase@directlua{luainputenc.set_unicode_extention("\luatexluaescapestring{#1}")}%
+}
+
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\lIE@SetUtfExt}
+%
+% Same as before, but the files will be read in 8-bit.
+%
+% \begin{macrocode}
+
+\newcommand*\lIE@SetNonUtfExt[1]{
+ \luatexbase@directlua{luainputenc.set_non_unicode_extention("\luatexluaescapestring{#1}")}
+}
+
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\lIE@InputUtfFile}
+%
+% This macro inputs a file in fake UTF-8. It has the ``feature" to unset
+% the behaviour on the file you will call, so to be safe, you must call
+% them with files for which the behaviour has not been set.
+%
+% \begin{macrocode}
+
+
+\newcommand*\lIE@InputUtfFile[1]{%
+ \lIE@SetUtfFile{#1}%
+ \input #1%
+ \lIE@UnsetFile{#1}%
+}
+
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\lIE@InputNonUtfFile}
+%
+% Same as before, but to read a file as 8-bit.
+%
+% \begin{macrocode}
+
+\newcommand*\lIE@InputNonUtfFile[1]{%
+ \lIE@SetNonUtfFile{#1}%
+ \input #1%
+ \lIE@UnsetFile{#1}%
+}
+
+% \end{macrocode}
+%
+% \end{macro}
+%
+% Two definitions to put the previous two macros in the user space.
+%
+% \begin{macrocode}
+
+\newcommand*\InputUtfFile[1]{%
+ \lIE@InputUtfFile{#1}%
+}
+
+\newcommand*\InputNonUtfFile[1]{%
+ \lIE@InputNonUtfFile{#1}%
+}
+
+\newcount\lIE@activated
+
+\newcommand*{\lIE@activate}[0]{%
+ \lIE@activated=1 %
+ \lIE@setstarted %
+}
+
+\newcommand*{\lIE@FromInputenc}[1]{%
+ \ifnum\lIE@activated=0 %
+ \lIE@activate %
+ \fi%
+}
+
+\fi
+
+\ProcessOptions*
+
+% \end{macrocode}
+%
+% \iffalse
+%</package>
+% \fi
+%
+% \iffalse
+%<*def>
+% \fi
+%
+% \subsection{\texttt{lutf8.def}}
+%
+% \begin{macrocode}
+%% This file was adapted from utf8.def, which copyright is:
+%% Copyright 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003
+%% 2004 2005 2006 The LaTeX3 Project.
+%%
+%% utf8.def is under the lppl version 1.3c or later, and can be found
+%% in the base LaTeX system.
+%%
+%% The lppl can be found at http://www.latex-project.org/lppl.txt
+%%
+%% The changes to utf8.def are Copyright 2009 Elie Roux, and are under
+%% the CC0 license.
+%%
+%% The changes are LuaTeX support.
+%%
+%% This file is distributed under the CC0 license, with clause 6 of the
+%% lppl as additional restrictions.
+
+% \end{macrocode}
+%
+% Most of the file is taken from \texttt{utf8.def}, the main changes are
+% commented. A lot of code was removed, especially the codes that analysed
+% the unicode characters byte by byte.
+%
+% \begin{macrocode}
+
+
+\ProvidesFile{lutf8.def}
+ [2010/05/10 v0.97 UTF-8 support for luainputenc]
+
+\makeatletter
+\catcode`\ \saved@space@catcode
+
+\@inpenc@test
+
+\ifx\@begindocumenthook\@undefined
+ \makeatother
+ \endinput \fi
+
+% \end{macrocode}
+%
+% This function is changed a lot. Its aim is to map the character (first
+% argument) to a macro (second argument). In \texttt{utf8.def} it was
+% complicated as unicode was analyzed byte by byte. With Lua\TeX\ it is
+% extremely simple, we just have to activate the character, and call a
+% traditional |\DeclareInputTeXt|.
+%
+% \begin{macrocode}
+
+\gdef\DeclareUnicodeCharacter#1#2{%
+ \@tempcnta"#1%
+ \catcode\@tempcnta\active %
+ \DeclareInputText{\the\@tempcnta}{#2}%
+}
+
+\@onlypreamble\DeclareUnicodeCharacter
+
+\def\cdp@elt#1#2#3#4{%
+ \wlog{Now handling font encoding #1 ...}%
+ \lowercase{%
+ \InputIfFileExists{#1enc.dfu}}%
+ {\wlog{... processing UTF-8 mapping file for font encoding
+ #1}%
+ \catcode`\ 9\relax}%
+ {\wlog{... no UTF-8 mapping file for font encoding #1}}%
+}
+\cdp@list
+
+\def\DeclareFontEncoding@#1#2#3{%
+ \expandafter %
+ \ifx\csname T@#1\endcsname\relax %
+ \def\cdp@elt{\noexpand\cdp@elt}%
+ \xdef\cdp@list{\cdp@list\cdp@elt{#1}%
+ {\default@family}{\default@series}%
+ {\default@shape}}%
+ \expandafter\let\csname#1-cmd\endcsname\@changed@cmd %
+ \begingroup %
+ \wlog{Now handling font encoding #1 ...}%
+ \lowercase{%
+ \InputIfFileExists{#1enc.dfu}}%
+ {\wlog{... processing UTF-8 mapping file for font encoding #1}}%
+ {\wlog{... no UTF-8 mapping file for font encoding #1}}%
+ \endgroup
+ \else
+ \@font@info{Redeclaring font encoding #1}%
+ \fi
+ \global\@namedef{T@#1}{#2}%
+ \global\@namedef{M@#1}{\default@M#3}%
+ \xdef\LastDeclaredEncoding{#1}%
+}
+
+\DeclareUnicodeCharacter{00A9}{\textcopyright}
+\DeclareUnicodeCharacter{00AA}{\textordfeminine}
+\DeclareUnicodeCharacter{00AE}{\textregistered}
+\DeclareUnicodeCharacter{00BA}{\textordmasculine}
+\DeclareUnicodeCharacter{02C6}{\textasciicircum}
+\DeclareUnicodeCharacter{02DC}{\textasciitilde}
+\DeclareUnicodeCharacter{200C}{\textcompwordmark}
+\DeclareUnicodeCharacter{2026}{\textellipsis}
+\DeclareUnicodeCharacter{2122}{\texttrademark}
+\DeclareUnicodeCharacter{2423}{\textvisiblespace}
+
+% \end{macrocode}
+%
+% \iffalse
+%</def>
+% \fi
+%
+% \iffalse
+%<*defx>
+% \fi
+%
+% \subsection{\texttt{lutf8x.def}}
+%
+% \begin{macrocode}
+%% This file was adapted from utf8.def, which copyright is:
+%% Copyright 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003
+%% 2004 2005 2006 The LaTeX3 Project.
+%%
+%% utf8.def is under the lppl version 1.3c or later, and can be found
+%% in the base LaTeX system.
+%%
+%% The lppl can be found at http://www.latex-project.org/lppl.txt
+%%
+%% The changes to utf8.def are Copyright 2009 Elie Roux, and are under
+%% the CC0 license.
+%%
+%% The changes are LuaTeX support.
+%%
+%% This file is distributed under the CC0 license, with clause 6 of the
+%% lppl as additional restrictions.
+
+% \end{macrocode}
+%
+% This file is mostly the code from \texttt{lutf.def}, but it adds
+% mechanisms to pass from \emph{legacy mode} to \emph{unicode font mode}.
+% The trick is to put in a lua table all characters that are activated by
+% the \emph{legacy mode}, and to unactivate them when we switch to
+% \emph{unicode font mode}. This is made (almost) entirely in lua. The
+% difficult part is the changes in |\DeclareFontEncoding|.
+%
+% \begin{macrocode}
+
+\ProvidesFile{lutf8x.def}
+ [2010/05/10 v0.97 UTF-8 support for luainputenc]
+
+\makeatletter
+\catcode`\ \saved@space@catcode
+
+\@inpenc@test
+
+\ifx\@begindocumenthook\@undefined
+ \makeatother
+ \endinput \fi
+
+% \end{macrocode}
+%
+% We change it a little to add the activated character in the lua table.
+%
+% \begin{macrocode}
+
+\gdef\DeclareUnicodeCharacter#1#2{%
+ \@tempcnta"#1%
+ \luatexbase@directlua{luainputenc.declare_character('\the\@tempcnta')}%
+ \catcode\@tempcnta\active %
+ \DeclareInputText{\the\@tempcnta}{#2}%
+}
+
+\@onlypreamble\DeclareUnicodeCharacter
+
+\def\cdp@elt#1#2#3#4{%
+ \wlog{Now handling font encoding #1 ...}%
+ \lowercase{%
+ \InputIfFileExists{#1enc.dfu}}%
+ {\wlog{... processing UTF-8 mapping file for font encoding
+ #1}%
+ \catcode`\ 9\relax}%
+ {\wlog{... no UTF-8 mapping file for font encoding #1}}%
+}
+\cdp@list
+
+% \end{macrocode}
+%
+% The macros to change from/to \emph{legacy mode} to/from \emph{unicode
+% font mode}.
+%
+% \begin{macrocode}
+
+\def\lIE@ActivateUnicodeCatcodes{%
+\luatexbase@directlua{luainputenc.activate_characters()}%
+}
+
+\def\lIE@DesactivateUnicodeCatcodes{%
+\luatexbase@directlua{luainputenc.desactivate_characters()}%
+}
+
+\def\lIE@CharactersActivated{%
+\luatexbase@directlua{luainputenc.force_characters_activated()}
+}
+
+\edef\lIE@EU{EU2}
+
+% \end{macrocode}
+%
+% We add some code to automatically activate or unactivate characters
+% according to the encoding changes. Note that we override |\@@enc@update|,
+% which may pose some problems if a package of yours does it too.
+% Fortunately this package is the only one that does it in \TeX Live.
+%
+% \begin{macrocode}
+
+\def\DeclareFontEncoding@#1#2#3{%
+ \edef\lIE@test{#1}%
+ \ifx\lIE@test\lIE@EU %
+ \ifx\LastDeclaredEncoding\lIE@EU\else %
+ \lIE@CharactersActivated %
+ \lIE@DesactivateUnicodeCatcodes %
+ \fi
+ \gdef\@@enc@update{%
+ \edef\lIE@test{#1}%
+ \ifx\f@encoding\lIE@EU %
+ \lIE@DesactivateUnicodeCatcodes %
+ \else %
+ \lIE@ActivateUnicodeCatcodes %
+ \fi
+ \expandafter\let\csname\cf@encoding-cmd\endcsname\@changed@cmd
+ \expandafter\let\csname\f@encoding-cmd\endcsname\@current@cmd
+ \default@T
+ \csname T@\f@encoding\endcsname
+ \csname D@\f@encoding\endcsname
+ \let\enc@update\relax
+ \let\cf@encoding\f@encoding
+ }
+ \else %
+ \expandafter %
+ \ifx\csname T@#1\endcsname\relax %
+ \def\cdp@elt{\noexpand\cdp@elt}%
+ \xdef\cdp@list{\cdp@list\cdp@elt{#1}%
+ {\default@family}{\default@series}%
+ {\default@shape}}%
+ \expandafter\let\csname#1-cmd\endcsname\@changed@cmd %
+ \begingroup %
+ \wlog{Now handling font encoding #1 ...}%
+ \lowercase{%
+ \InputIfFileExists{#1enc.dfu}}%
+ {\wlog{... processing UTF-8 mapping file for font encoding #1}}%
+ {\wlog{... no UTF-8 mapping file for font encoding #1}}%
+ \endgroup
+ \else
+ \@font@info{Redeclaring font encoding #1}%
+ \fi
+ \fi %
+ \global\@namedef{T@#1}{#2}%
+ \global\@namedef{M@#1}{\default@M#3}%
+ \xdef\LastDeclaredEncoding{#1}%
+}
+
+\DeclareUnicodeCharacter{00A9}{\textcopyright}
+\DeclareUnicodeCharacter{00AA}{\textordfeminine}
+\DeclareUnicodeCharacter{00AE}{\textregistered}
+\DeclareUnicodeCharacter{00BA}{\textordmasculine}
+\DeclareUnicodeCharacter{02C6}{\textasciicircum}
+\DeclareUnicodeCharacter{02DC}{\textasciitilde}
+\DeclareUnicodeCharacter{200C}{\textcompwordmark}
+\DeclareUnicodeCharacter{2026}{\textellipsis}
+\DeclareUnicodeCharacter{2122}{\texttrademark}
+\DeclareUnicodeCharacter{2423}{\textvisiblespace}
+
+% \end{macrocode}
+%
+% \iffalse
+%</defx>
+% \fi
+%
+%
+% \subsection{\texttt{luainputenc.lua}}
+%
+% First the \texttt{inputenc} module is registered as a Lua\TeX\ module,
+% with some informations.
+%
+% \iffalse
+%<*lua>
+% \fi
+%
+% \begin{macrocode}
+
+module('luainputenc', package.seeall)
+
+luainputenc.module = {
+ name = "luainputenc",
+ version = 0.97,
+ date = "2010/05/10",
+ description = "Lua simple inputenc package.",
+ author = "Elie Roux",
+ copyright = "Elie Roux",
+ license = "CC0",
+}
+
+luatexbase.provides_module(luainputenc.module)
+
+local format = string.format
+
+luainputenc.log = luainputenc.log or function(...)
+ luatexbase.module_log('luainputenc', format(...))
+end
+
+% \end{macrocode}
+%
+% We keep the option and the true encoding in two variables.
+%
+% \begin{macrocode}
+
+luainputenc.encoding = "utf8"
+luainputenc.package_option = nil
+
+function luainputenc.set_option(option)
+ luainputenc.package_option = option
+ if option == "lutf8" or option == "lutf8x" or option == "utf8x" or option == "unactivate" then
+ luainputenc.encoding = "utf8"
+ else
+ luainputenc.encoding = option
+ end
+end
+
+% \end{macrocode}
+%
+% Some local declarations.
+%
+% \begin{macrocode}
+
+local char, utfchar, byte, format, gsub, utfbyte, utfgsub =
+string.char, unicode.utf8.char, string.byte, string.format, string.gsub, unicode.utf8.byte, unicode.utf8.gsub
+
+% \end{macrocode}
+%
+% The function to transform a 8-bit character in the corresponding fake
+% UTF-8 character.
+%
+% \begin{macrocode}
+
+function luainputenc.byte_to_utf(ch)
+ return utfchar(byte(ch))
+end
+
+% \end{macrocode}
+%
+% The function that will be registered in the
+% \texttt{process\_input\_buffer} callback when needed.
+%
+% \begin{macrocode}
+
+function luainputenc.fake_utf_read(buf)
+ return gsub(buf,"(.)", luainputenc.byte_to_utf)
+end
+
+% \end{macrocode}
+%
+% The function to transform a fake utf8 character in the corresponding
+% 8-bit character.
+%
+% \begin{macrocode}
+
+function luainputenc.utf_to_byte(ch)
+ return char(utfbyte(ch))
+end
+
+% \end{macrocode}
+%
+% The function that will be registered in the
+% \texttt{process\_output\_buffer} callback if it exists.
+%
+% \begin{macrocode}
+
+function luainputenc.fake_utf_write(buf)
+ return utfgsub(buf,"(.)", luainputenc.utf_to_byte)
+end
+
+% \end{macrocode}
+%
+% Here we register the two callbacks, and the behaviour is the same as in pdfTeX.
+% The next part of the file is only the machinery for LuaTeX versions without
+% the callback |process_output_buffer|, so it will be deprecated after
+% TeXLive 2009, you are not advised to use it.
+%
+% \begin{macrocode}
+
+if tex.luatexversion > 42 then
+
+ function luainputenc.register_callbacks()
+ luatexbase.add_to_callback('process_output_buffer', luainputenc.fake_utf_write, 'luainputenc.fake_utf_write')
+ luatexbase.add_to_callback('process_input_buffer', luainputenc.fake_utf_read, 'luainputenc.fake_utf_read')
+ end
+
+else
+
+% \end{macrocode}
+%
+% \texttt{start()} and \texttt{stop()} are the functions that register or
+% unregister the function in the callback. When the function is registered,
+% Lua\TeX\ reads the input in fake UTF-8.
+%
+% \begin{macrocode}
+
+ local started, stopped = 1, 0
+
+ luainputenc.state = stopped
+
+ function luainputenc.setstate(state)
+ if state == luainputenc.state then
+ return
+ elseif state == started then
+ luainputenc.start()
+ else
+ luainputenc.stop()
+ end
+ end
+
+ function luainputenc.setstarted()
+ luainputenc.setstate(started)
+ end
+
+ function luainputenc.setstopped()
+ luainputenc.setstate(stopped)
+ end
+
+ function luainputenc.start()
+ luatexbase.add_to_callback('process_input_buffer', luainputenc.fake_utf_read,
+ 'luainputenc.fake_utf_read')
+ luainputenc.state = started
+ if luainputenc.callback_registered == 0 then
+ luainputenc.register_callback()
+ end
+ end
+
+ function luainputenc.stop()
+ luatexbase.remove_from_callback('process_input_buffer', 'luainputenc.fake_utf_read')
+ luainputenc.state = stopped
+ return
+ end
+
+% \end{macrocode}
+%
+% Here is a list of all file extentions for which we consider that the
+% files have been written by Lua\TeX , and thus must be read in fake UTF-8.
+% I may have forgotten things in the list. If you find a new extention,
+% please report the maintainer.
+%
+% \begin{macrocode}
+
+ luainputenc.unicode_extentions = {
+ ['.aux'] = 1, -- basic files
+ ['.toc'] = 1,
+ ['.gls'] = 1,
+ ['.ind'] = 1,
+ ['.idx'] = 1,
+ ['.vrb'] = 1, -- beamer and powerdot
+ ['.nav'] = 1, -- other beamer extentions
+ ['.sol'] = 1,
+ ['.qsl'] = 1,
+ ['.snm'] = 1,
+ ['.pgn'] = 1, -- pagereference
+ ['.cpg'] = 1, -- AlProTeX
+ ['.pst'] = 1, -- pst-tree
+ ['.tmp'] = 1, -- sauerj/collect
+ ['.sym'] = 1, -- listofsymbols
+ ['.sub'] = 1, -- listofsymbols
+ ['.lof'] = 1, -- preprint
+ ['.lot'] = 1, -- preprint
+ ['mtc1'] = 1, -- minitoc
+ ['.ovr'] = 1, -- thumbss
+ ['.fff'] = 1, -- endplate
+ ['.sbb'] = 1, -- splitbib
+ ['.bbl'] = 1, -- latex
+ ['.ain'] = 1, -- authorindex
+ ['.abb'] = 1, -- juraabbrev
+ ['.ent'] = 1, -- endnotes
+ ['.end'] = 1, -- fn2end
+ ['.thm'] = 1, -- ntheorem
+ ['.xtr'] = 1, -- extract
+ ['.han'] = 1, -- linguho
+ ['.bnd'] = 1, -- bibref
+ ['.bbl'] = 1, -- bibref
+ ['.col'] = 1, -- mwrite
+ ['.ttt'] = 1, -- endfloat
+ ['.fax'] = 1, -- lettre
+ ['.tns'] = 1, -- lettre
+ ['.odt'] = 1, -- lettre
+ ['.etq'] = 1, -- lettre
+ ['.emd'] = 1, -- poemscol
+ ['.emx'] = 1, -- poemscol
+ ['.ctn'] = 1, -- poemscol
+ ['.hst'] = 1, -- vhistory
+ ['.acr'] = 1, -- crosswrd
+ ['.dwn'] = 1, -- crosswrd
+ ['.ttc'] = 1, -- talk
+ -- ['.txt'] = 1, -- coverpage, but not sure it's safe to include it...
+ ['.eve'] = 1, -- calend0
+ ['.scn'] = 1, -- cwebmac
+ }
+
+% \end{macrocode}
+%
+% The code to define a specific behaviour for certain files.
+%
+% \begin{macrocode}
+
+ luainputenc.unicode_files = {}
+
+ luainputenc.non_unicode_files = {}
+
+ function luainputenc.set_unicode_file(filename)
+ if luainputenc.non_unicode_files[filename] == 1 then
+ luainputenc.non_unicode_files[filename] = nil
+ end
+ luainputenc.unicode_files[filename] = 1
+ end
+
+ function luainputenc.set_non_unicode_file(filename)
+ if luainputenc.unicode_files[filename] == 1 then
+ luainputenc.unicode_files[filename] = nil
+ end
+ luainputenc.non_unicode_files[filename] = 1
+ end
+
+ function luainputenc.set_unicode_extention(ext)
+ luainputenc.unicode_extention[ext] = 1
+ end
+
+ function luainputenc.set_non_unicode_extention(ext)
+ if luainputenc.unicode_extentions[ext] == 1 then
+ luainputenc.unicode_extentions[ext] = nil
+ end
+ end
+
+ function luainputenc.unset_file(filename)
+ if luainputenc.unicode_files[filename] == 1 then
+ luainputenc.unicode_files[filename] = nil
+ elseif luainputenc.non_unicode_files[filename] == 1 then
+ luainputenc.non_unicode_files[filename] = nil
+ end
+ end
+
+ local unicode, non_unicode = stopped, started
+
+ function luainputenc.find_state(filename)
+ if luainputenc.unicode_files[filename] == 1 then
+ return unicode
+ elseif luainputenc.non_unicode_files[filename] == 1 then
+ return non_unicode
+ else
+ local ext = filename:sub(-4)
+ if luainputenc.unicode_extentions[ext] == 1 then
+ return unicode
+ else
+ return non_unicode
+ end
+ end
+ end
+
+% \end{macrocode}
+%
+% We register the functions to stop or start the fake UTF-8 translation in
+% the appropriate callbacks if necessary.
+%
+% \begin{macrocode}
+
+ function luainputenc.pre_read_file(env)
+ if not env.path then
+ return
+ end
+ local currentstate = luainputenc.state
+ luainputenc.setstate(luainputenc.find_state(env.filename))
+ env.previousstate = currentstate
+ end
+
+ function luainputenc.close(env)
+ luainputenc.setstate(env.previousstate)
+ end
+
+ luainputenc.callback_registered = 0
+
+ function luainputenc.register_callback()
+ if luainputenc.callback_registered == 0 then
+ luatexbase.add_to_callback('pre_read_file', luainputenc.pre_read_file,
+ 'luainputenc.pre_read_file')
+ luatexbase.add_to_callback('file_close', luainputenc.close, 'luainputenc.close')
+ luainputenc.callback_registered = 1
+ end
+ end
+
+end
+
+% \end{macrocode}
+%
+% Finally we provide some functions to activate or disactivate the catcodes
+% of the non-ASCII characters.
+%
+% \begin{macrocode}
+
+
+luainputenc.activated_characters = {}
+luainputenc.characters_are_activated = false
+
+function luainputenc.declare_character(c)
+ luainputenc.activated_characters[tonumber(c)] = true
+end
+
+function luainputenc.force_characters_activated ()
+ luainputenc.characters_are_activated = true
+end
+
+function luainputenc.activate_characters()
+ if not luainputenc.characters_are_activated then
+ for n, _ in pairs(luainputenc.activated_characters) do
+ tex.sprint(string.format('\\catcode %d\\active',n))
+ end
+ luainputenc.characters_are_activated = true
+ end
+end
+
+function luainputenc.desactivate_characters()
+ if luainputenc.characters_are_activated then
+ for n, _ in pairs(luainputenc.activated_characters) do
+ tex.sprint(string.format('\\catcode %d=11',n))
+ end
+ luainputenc.characters_are_activated = false
+ end
+end
+
+% \end{macrocode}
+%
+% \iffalse
+%</lua>
+% \fi
+%
+% \section{Test file}
+%
+% Very minimal, just check that the package correctly loads with an option
+% and doesn't crash on a one-line plain ASCII document body\dots
+%
+% \begin{macrocode}
+%<*test>
+\documentclass{article}
+\usepackage[utf8]{luainputenc}
+\begin{document}
+bla
+\end{document}
+%</test>
+% \end{macrocode}
+%
+% \Finale
+\endinput
diff --git a/macros/luatex/latex/luainputenc/luainputenc.pdf b/macros/luatex/latex/luainputenc/luainputenc.pdf
new file mode 100644
index 0000000000..d6db0888b3
--- /dev/null
+++ b/macros/luatex/latex/luainputenc/luainputenc.pdf
Binary files differ
diff --git a/macros/luatex/latex/lualatex-math/MANIFEST b/macros/luatex/latex/lualatex-math/MANIFEST
new file mode 100644
index 0000000000..c30851c215
--- /dev/null
+++ b/macros/luatex/latex/lualatex-math/MANIFEST
@@ -0,0 +1,14 @@
+This work consists of the non-derived files
+
+README
+README.rst
+MANIFEST
+lualatex-math.dtx
+lualatex-math.ins
+lualatex-math.el
+
+and the derived files
+
+lualatex-math.sty
+lualatex-math.lua
+lualatex-math.pdf
diff --git a/macros/luatex/latex/lualatex-math/README b/macros/luatex/latex/lualatex-math/README
new file mode 100644
index 0000000000..9224b9bcb3
--- /dev/null
+++ b/macros/luatex/latex/lualatex-math/README
@@ -0,0 +1,48 @@
+The ``lualatex-math`` package
+=============================
+
+This package patches a few commands of the LaTeX 2ε kernel and the ``amsmath``,
+``amsopn``, ``mathtools`` and ``icomma`` packages to be more compatible with
+the LuaTeX engine. It is only meaningful if you compile your documents with
+LuaLaTeX.
+
+
+License
+-------
+
+This material is subject to the LaTeX Project Public License, either
+version 1.3c of this license or (at your option) any later version. See
+http://www.latex-project.org/lppl/ for the details of that license.
+
+
+Installation
+------------
+
+Copy the files ``lualatex-math.sty`` and ``lualatex-math.lua`` to a place where
+TeX can find them. The documentation is contained in the file
+``lualatex-math.pdf``.
+
+To produce the runtime files from the Docstrip source, run ``make``. To
+produce the PDF manual, run ``make pdf``. To produce and compile a few test
+files, run ``make check``. To compile the manual you’ll need my `custom
+documentation class`_.
+
+To install the runtime files in your home TEXMF tree, run ``make install``. To
+install the PDF manual in your home TEXMF tree, run ``make install-pdf``. The
+package includes an AucTeX style file which will be installed in
+``~/.emacs.d``.
+
+.. _custom documentation class: https://github.com/phst/phst-doc
+
+
+Usage
+-----
+
+Include the package via ``\usepackage{lualatex-math}``. The package has no
+options and no public interface; it applies the appropriate fixes
+automatically. See ``lualatex-math.pdf`` for details.
+
+If you encounter any issues, please report them by means of the `issue
+tracker`_.
+
+.. _issue tracker: https://github.com/phst/lualatex-math/issues
diff --git a/macros/luatex/latex/lualatex-math/lualatex-math.dtx b/macros/luatex/latex/lualatex-math/lualatex-math.dtx
new file mode 100644
index 0000000000..2ac5af66a5
--- /dev/null
+++ b/macros/luatex/latex/lualatex-math/lualatex-math.dtx
@@ -0,0 +1,724 @@
+% \iffalse meta-comment
+%
+% Copyright 2011–2019 by Philipp Stephani, Joseph Wright, and Will Robertson
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either
+% version 1.3c of this license or (at your option) any later
+% version. The latest version of this license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3c or later is part of all distributions of
+% LaTeX version 2009/09/24 or later.
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\documentclass[a4paper, 10pt, ngerman, american]{phst-doc}
+
+\usepackage{lualatex-math}
+\newcommand*{\thispackage}{\textsf{lualatex-math}\xspace}
+
+\begin{document}
+
+\DocInput{lualatex-math.dtx}
+\PrintChanges
+\PrintIndex
+
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{280}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \changes{v0.1}{2011/04/22}{Initial version}
+% \changes{v0.3a}{2011/09/13}{Updated for changes in \pkg{l3kernel}}
+% \changes{v1.0}{2012/08/27}{Switched to \pkg{l3docstrip}}
+%
+% \GetFileInfo{lualatex-math.sty}
+%
+% \title{The \thispackage package\thanks{This document corresponds to
+% \thispackage{}~\fileversion, dated~\filedate.}}
+%
+% \author{Philipp Stephani \\ \texttt{p.stephani2@gmail.com}}
+% \date{\filedate}
+%
+%
+% \maketitle
+% \tableofcontents
+%
+%
+% \section{Introduction}
+%
+% \Hologo{LuaTeX} brings major improvements to all areas of \hologo{TeX}
+% typesetting and programming. They are made available through new primitives
+% or the embedded Lua interpreter, and combining them with existing
+% \hologo{LaTeX2e} packages is not a task the average \hologo{LaTeX} user
+% should have to care about. Therefore a multitude of \hologo{LaTeX2e}
+% packages have been written to bridge the gap between documents and the new
+% features. The \thispackage package focuses on the additional possibilities
+% for mathematical typesetting. The most eminent of the new features is the
+% ability to use Unicode and OpenType fonts, as provided by \Robertson’s
+% \pkg{unicode-math} package. However, there is a smaller group of changes
+% unrelated to Unicode: these are to be dealt with in this package. While in
+% principle most \hologo{TeX} documents written for traditional engines should
+% work just fine with \hologo{LuaTeX}, there is a small number of breaking
+% changes that require the attention of package authors. The \thispackage
+% package tries to fix some of the issues encountered while porting traditional
+% macro packages to \hologo{LuaLaTeX}.
+%
+% The decision to write patches for existing macro packages should not be
+% made lightly: monkey patching done by somebody different from the original
+% package author ties the patching package to the implementation details of
+% the patched functionality and breaks all rules of encapsulation. However,
+% due to the lack of alternatives, it has become an accepted way of providing
+% new functionality in \hologo{LaTeX}. To keep the negative impact as small
+% as possible, the \thispackage package patches only the \hologo{LaTeX2e}
+% kernel and a small number of popular packages. In general, this package
+% should be regarded as a temporary kludge that should be removed once the
+% math-related packages are updated to be usable with \hologo{LuaTeX}. By
+% its very nature, the package is likely to cause problems; in such cases,
+% please refer to the issue
+% tracker\footnote{\url{https://github.com/phst/lualatex-math/issues}}.
+%
+%
+% \section{Interface}
+%
+% The \thispackage package can be loaded with \cmd{\usepackage} or
+% \cmd{\RequirePackage}, as usual. It has no options and no public
+% interface; the patching is always done when the package is loaded and
+% cannot be controlled. As a matter of course, the \thispackage package
+% needs \hologo{LuaLaTeX} to function; it will produce error messages and
+% refuse to load under other engines and formats. The package depends on the
+% \pkg{expl3} bundle, the \pkg{etoolbox} package and the
+% \pkg{filehook} package. The \thispackage package is independent of
+% the \pkg{unicode-math} package; the fixes provided here are valid for both
+% Unicode and legacy math typesetting.
+%
+% Currently patches for the \hologo{LaTeX2e} kernel and the \pkg{amsmath},
+% \pkg{mathtools} and \pkg{icomma} packages are provided. It is not relevant
+% whether you load these packages before or after \thispackage. They should
+% work as expected (and ideally you shouldn’t notice anything), but if you load
+% other packages that by themselves overwrite commands patched by this package,
+% bad things may happen, as it is usual with \hologo{LaTeX}.
+%
+% One user-visible change is that the new
+% \DescribeMacros{\mathstyle}\cmd{\mathstyle} primitive
+% should work in
+% all cases after the \thispackage package has been loaded, provided you use
+% the high-level macros \DescribeMacros{\frac\binom\genfrac}\cmd{\frac},
+% \cmd{\binom}, and \cmd{\genfrac}. The fraction-like \hologo{TeX}
+% primitives like \cmd{\over} or \cmd{\atopwithdelims} and the
+% \hologo{plainTeX} leftovers like \cmd{\brack} or \cmd{\choose} cannot be
+% patched, and you shouldn’t use them.
+%
+% \StopEventually{}
+%
+%
+% \section{Implementation of the \hologo{LaTeX2e} package}
+%
+% \changes{v1.4a}{2015/08/24}{Use \pkg{expl3} versions of \hologo{LuaTeX}
+% math primitives}
+% \changes{v1.4a}{2015/08/24}{Avoid \cs{RequireLuaModule}}
+% \changes{v1.4a}{2015/09/16}{Load \pkg{luatexbase} only if required}
+%
+% \subsection{Requirements}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=lltxmath>
+\NeedsTeXFormat{LaTeX2e}[2009/09/24]
+\RequirePackage{expl3}[2018/06/18]
+\ProvidesExplPackage{lualatex-math}{2019/01/21}{1.8}%
+ {Patches for mathematics typesetting with LuaLaTeX}
+\RequirePackage { etoolbox } [ 2007/10/08 ]
+\cs_if_exist:NF \newluabytecode
+ { \RequirePackage { luatexbase } [ 2010/05/27 ] }
+\RequirePackage { filehook } [ 2011/03/09 ]
+\directlua{require("lualatex-math")}
+% \end{macrocode}
+%
+% \begin{macro}{\@@_restore_catcode:N}
+% Executing the exhaustive expansion of
+% \cmd{\@@_restore_catcode:N}\meta{character token} restores the category
+% code of the \meta{character token} to its current value.
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_restore_catcode:N #1 {
+ \char_set_catcode:nn { \int_eval:n { `#1 } }
+ { \char_value_catcode:n { `#1 } }
+}
+% \end{macrocode}
+% \end{macro}
+% We use the macro defined above to restore the category code of the dollar
+% sign. There are packages that make the dollar sign active; hopefully they
+% get loaded after the packages we are trying to patch.
+% \begin{macrocode}
+\exp_args:Nx \AtEndOfPackage {
+ \@@_restore_catcode:N \$
+}
+\char_set_catcode_math_toggle:N \$
+% \end{macrocode}
+%
+%
+% \subsection{Messages}
+%
+% \begin{l3message}{luatex-required}
+% Issued when not running under \hologo{LuaTeX}.
+% \begin{macrocode}
+\msg_new:nnn { lualatex-math } { luatex-required } {
+ The~ lualatex-math~ package~ requires~ LuaTeX. \\
+ I~ will~ stop~ loading~ now.
+}
+% \end{macrocode}
+% \end{l3message}
+%
+% \begin{l3message}{macro-expected}
+% Issued when trying to patch a non-macro. The first argument must be the
+% detokenized macro name.
+% \begin{macrocode}
+\msg_new:nnn { lualatex-math } { macro-expected } {
+ I've~ expected~ that~ #1~ is~ a~ macro,~ but~ it~ isn't.
+}
+% \end{macrocode}
+% \end{l3message}
+%
+% \begin{l3message}{wrong-meaning}
+% Issued when trying to patch a macro with an unexpected meaning. The first
+% argument must be the detokenized macro name; the second argument must be
+% the actual detokenized meaning; and the third argument must be the expected
+% detokenized meaning.
+% \begin{macrocode}
+\msg_new:nnn { lualatex-math } { wrong-meaning } {
+ I've~ expected~ #1~ to~ have~ the~ meaning \\
+ #3, \\
+ but~ it~ has~ the~ meaning \\
+ #2.
+}
+% \end{macrocode}
+% \end{l3message}
+%
+% \begin{l3message}{patch-macro}
+% Issued when a macro is patched. The first argument must be the detokenized
+% macro name.
+% \begin{macrocode}
+\msg_new:nnn { lualatex-math } { patch-macro } {
+ I'm~ going~ to~ patch~ macro~ #1.
+}
+% \end{macrocode}
+% \end{l3message}
+%
+%
+% \subsection{Initialization}
+%
+% Unless we are running under \hologo{LuaTeX}, we issue an error and quit
+% immediately.
+% \begin{macrocode}
+\sys_if_engine_luatex:F {
+ \msg_error:nn { lualatex-math } { luatex-required }
+ \endinput
+}
+% \end{macrocode}
+%
+% \subsection{Patching}
+%
+% \begin{macro}{\@@_temp:w}
+% A scratch macro.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_temp:w \prg_do_nothing:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_patch:NNnnn}
+% \begin{macro}{\@@_patch:cNnnn}
+% The auxiliary macro \cmd{\@@_patch:NNnnn}\meta{command}\meta{factory
+% command}\marg{parameter text}\marg{expected replacement text}\marg{new
+% replacement text} tries to patch \meta{command}. If \meta{command} is
+% undefined, do nothing. Otherwise it must be a macro with the given
+% \meta{parameter text} and \meta{expected replacement text}, created by the
+% given \meta{factory command} or equivalent. In this case it will be
+% overwritten using the \meta{parameter text} and the \meta{new replacement
+% text}. Otherwise issue a warning and don’t overwrite.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_patch:NNnnn #1 #2 #3 #4 #5 {
+ \cs_if_exist:NT #1 {
+ \token_if_macro:NTF #1 {
+ \group_begin:
+ #2 \@@_temp:w #3 { #4 }
+ \cs_if_eq:NNTF #1 \@@_temp:w {
+ \msg_info:nnx { lualatex-math } { patch-macro }
+ { \token_to_str:N #1 }
+ \group_end:
+ #2 #1 #3 { #5 }
+ } {
+ \msg_warning:nnxxx { lualatex-math } { wrong-meaning }
+ { \token_to_str:N #1 } { \token_to_meaning:N #1 }
+ { \token_to_meaning:N \@@_temp:w }
+ \group_end:
+ }
+ } {
+ \msg_warning:nnx { lualatex-math } { macro-expected }
+ { \token_to_str:N #1 }
+ }
+ }
+}
+\cs_generate_variant:Nn \@@_patch:NNnnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_mathchar:NN}
+% The macro \cmd{\@@_set_mathchar:NN}\meta{control sequence}\meta{token}
+% defines the \meta{control sequence} as an extended mathematical character
+% shorthand whose mathematical code is given by the mathematical code of the
+% character \texttt{\textasciigrave}\meta{token}. We cannot use the
+% |\Umathcharnumdef| primitive here since we would then rely on the
+% |\Umathcodenum| primitive which is currently
+% broken.\footnote{\url{http://tug.org/pipermail/luatex/2012-October/003794.html}}
+% \changes{v0.3c}{2012/08/23}{\pkg{l3kernel} renamed \cs{lua_now:x} to
+% \cs{lua_now_x:n}}
+% \changes{v1.1}{2012/10/13}{Update reasoning why \cs{Umathcharnumdef} is not
+% used here}
+% \changes{v1.3a}{2014/06/18}{\pkg{l3kernel} has (currently) dropped
+% \cs{lua_now_x:n}}
+% \changes{v1.4a}{2015/08/24}{\cs{lua_now_x:n} is back}
+% \changes{v1.8}{2019/01/21}{\cs{lua_now_x:n} is now called \cs{lua_now:e}}
+% \changes{v1.8}{2019/01/21}{Stop using \cs{…:D} control sequences}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_set_mathchar:NN #1 #2 {
+ \Umathchardef #1
+ \lua_now:e {
+ lualatex.math.print_class_fam_slot( \int_eval:n { `#2 } )
+ }
+ \scan_stop:
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{\Hologo{LaTeX2e} kernel}
+%
+% \changes{v0.3}{2011/08/07}{Patched math group allocation to gain access to
+% all families}
+% \changes{v1.4}{2015/04/04}{Removed patch for math group allocation; the
+% kernel itself now supports all available math families}
+% \Hologo{LuaTeX} enables access to the current mathematical style via the
+% \cmd{\mathstyle} primitive. For this to work, fraction-like constructs (\eg,
+% \meta{numerator} \cmd{\over} \meta{denominator}) have to be enclosed in a
+% \cmd{\Ustack} group. \cmd{\frac} can be patched to do this, but the
+% \hologo{plainTeX} remnants \cmd{\choose}, \cmd{\brack} and \cmd{\brace}
+% should be discouraged.
+%
+% \begin{macro}{\frac}
+% Here we assume that nobody except \pkg{amsmath} redefines \cmd{\frac}.
+% This is obviously not the case, but we ignore other packages (\eg,
+% \pkg{nath}) for the moment. We only patch the \hologo{LaTeX2e} kernel
+% definition if the \pkg{amsmath} package is not loaded; the corresponding
+% patch for \pkg{amsmath} follows below.
+% \begin{macrocode}
+\AtEndPreamble {
+ \@ifpackageloaded { amsmath } { } {
+ \@@_patch:NNnnn \frac \cs_set_nopar:Npn { #1 #2 } {
+ {
+ \begingroup #1 \endgroup \over #2
+ }
+ } {
+% \end{macrocode}
+% To do: do we need the additional set of braces around \cmd{\Ustack}?
+% \changes{v1.8}{2019/01/21}{Stop using \cs{…:D} control sequences}
+% \begin{macrocode}
+ {
+ \Ustack { \group_begin: #1 \group_end: \over #2 }
+ }
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{\pkg{amsmath}}
+%
+% The popular \pkg{amsmath} package is subject to three \hologo{LuaTeX}-related problems:
+% \begin{itemize}
+% \item The \cmd{\mathcode} primitive is used several times, which fails for
+% Unicode math characters. \cmd{\Umathcode} should be used instead.
+% \item Legacy font dimensions are used for constructing stacks in the
+% \cmd{\substack} command and the \env{subarray} environment. This doesn’t
+% work if a Unicode math font is selected.
+% \item The fraction commands \cmd{\frac} and \cmd{\genfrac} don’t use the
+% \cmd{\Ustack} primitive.
+% \end{itemize}
+%
+% \begin{macro}{\c_@@_std_minus_mathcode_int}
+% \begin{macro}{\c_@@_std_equal_mathcode_int}
+% These constants contain the standard \hologo{TeX} mathematical codes for
+% the minus and the equal signs. We temporarily set the math codes to these
+% constants before loading the \pkg{amsmath} package so that it can request
+% the legacy math code without error.
+% \begin{macrocode}
+\int_const:Nn \c_@@_std_minus_mathcode_int { "2200 }
+\int_const:Nn \c_@@_std_equal_mathcode_int { "303D }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \changes{v1.5}{2016/03/07}{Removed unused helper macro \cs{@@_char_dim:NN}}
+%
+% \begin{macro}{\l_@@_minus_mathchar}
+% \begin{macro}{\l_@@_equal_mathchar}
+% These mathematical characters are saved before \pkg{amsmath} is loaded so
+% that we can temporarily assign the \hologo{TeX} values to the mathematical
+% codes of the minus and equals signs. The \pkg{amsmath} package queries
+% these codes, and if they represent Unicode characters, the package loading
+% will fail. If \pkg{amsmath} has already been loaded, there is nothing we
+% can do, therefore we use the non-starred version of
+% \cmd{\AtBeginOfPackageFile}.
+% \changes{v1.2}{2013/01/13}{Replace removed macro \cs{chk_if_free_cs:N}}
+% \begin{macrocode}
+\tl_new:N \l_@@_minus_mathchar
+\tl_new:N \l_@@_equal_mathchar
+\AtBeginOfPackageFile { amsmath } {
+ \@@_set_mathchar:NN \l_@@_minus_mathchar \-
+ \@@_set_mathchar:NN \l_@@_equal_mathchar \=
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% Now we temporarily reset the mathematical codes.
+% \begin{macrocode}
+ \char_set_mathcode:nn { `\- } { \c_@@_std_minus_mathcode_int }
+ \char_set_mathcode:nn { `\= } { \c_@@_std_equal_mathcode_int }
+ \AtEndOfPackageFile { amsmath } {
+% \end{macrocode}
+% \begin{macro}{\std@minus}
+% \begin{macro}{\std@equals}
+% The \pkg{amsmath} package defines the control sequences \cmd{\std@minus}
+% and \cmd{\std@equal} as mathematical character shorthands while loading,
+% but uses our restored mathematical codes, which must be fixed.
+% \begin{macrocode}
+ \cs_set_eq:NN \std@minus \l_@@_minus_mathchar
+ \cs_set_eq:NN \std@equal \l_@@_equal_mathchar
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% Finally, we restore the original mathematical codes of the two signs.
+% \changes{v1.8}{2019/01/21}{Stop using \cs{…:D} control sequences}
+% \begin{macrocode}
+ \Umathcodenum `\- \l_@@_minus_mathchar
+ \Umathcodenum `\= \l_@@_equal_mathchar
+ }
+}
+% \end{macrocode}
+% All of the following fixes work even if \pkg{amsmath} is already loaded.
+% \begin{macro}{\@begindocumenthook}
+% \changes{v0.3b}{2011/09/18}{Another update for a change in \pkg{l3kernel}}
+% \pkg{amsmath} repeats the definiton of \cmd{\std@minus} and
+% \cmd{\std@equal} at the beginning of the document, so we also have to patch
+% the internal kernel macro \cmd{\@begindocumenthook} which contains the hook
+% code.
+% \begin{macrocode}
+\AtEndOfPackageFile * { amsmath } {
+ \tl_replace_once:Nnn \@begindocumenthook {
+ \mathchardef \std@minus \mathcode `\- \relax
+ \mathchardef \std@equal \mathcode `\= \relax
+ } {
+ \@@_set_mathchar:NN \std@minus \-
+ \@@_set_mathchar:NN \std@equal \=
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \changes{v1.5}{2016/03/07}{Removed patch for \cs{Mathstrutbox@};
+% \pkg{amsmath} now has a definition usable in \Hologo{LuaLaTeX}}
+%
+% \begin{environment}{subarray}
+% The \env{subarray} environment uses legacy font dimensions. We simply
+% patch it to use \hologo{LuaTeX} font parameters (and \hologo{LaTeX3}
+% expressions instead of \hologo{TeX} arithmetic). Since subscript arrays
+% are conceptually vertical stacks, we use the sum of top and bottom shift
+% for the default vertical baseline distance (\cmd{\baselineskip}) and the
+% minimum vertical gap for stack for the minimum baseline distance
+% (\cmd{\lineskip}).
+% \changes{v1.8}{2019/01/21}{Stop using \cs{…:D} control sequences}
+% \begin{macrocode}
+ \@@_patch:NNnnn \subarray \cs_set:Npn { #1 } {
+ \vcenter
+ \bgroup
+ \Let@
+ \restore@math@cr
+ \default@tag
+ \baselineskip \fontdimen 10~ \scriptfont \tw@
+ \advance \baselineskip \fontdimen 12~ \scriptfont \tw@
+%<@@=>
+ \lineskip \thr@@ \fontdimen 8~ \scriptfont \thr@@
+%<@@=lltxmath>
+ \lineskiplimit \lineskip
+ \ialign
+ \bgroup
+ \ifx c #1 \hfil \fi
+ $ \m@th \scriptstyle ## $
+ \hfil
+ \crcr
+ } {
+ \vcenter
+ \c_group_begin_token
+ \Let@
+ \restore@math@cr
+ \default@tag
+ \skip_set:Nn \baselineskip {
+ \Umathstacknumup \scriptstyle
+ + \Umathstackdenomdown \scriptstyle
+ }
+ \lineskip \Umathstackvgap \scriptstyle
+ \lineskiplimit \lineskip
+ \ialign
+ \c_group_begin_token
+ \token_if_eq_meaning:NNT c #1 { \hfil }
+ \Ustartmath
+ \m@th
+ \scriptstyle
+ \tex_alignmark:D \tex_alignmark:D
+ \Ustopmath
+ \hfil
+ \crcr
+ }
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\frac}
+% Since \cmd{\frac} is declared by \cmd{\DeclareRobustCommand}, we must patch
+% the macro \cmd{\frac\textvisiblespace}.
+% \changes{v1.8}{2019/01/21}{Stop using \cs{…:D} control sequences}
+% \begin{macrocode}
+ \@@_patch:cNnnn { frac~ } \cs_set:Npn { #1 #2 } {
+ {
+%<@@=>
+ \begingroup #1 \endgroup \@@over #2
+ }
+ } {
+ {
+ \Ustack { \group_begin: #1 \group_end: \@@over #2 }
+%<@@=lltxmath>
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\genfrac}
+% Generalized fractions are typeset by the \cmd{\genfrac} command.
+% Since \cmd{\genfrac} is declared by \cmd{\DeclareRobustCommand},
+% we have to patch the macro \cmd{\genfrac\textvisiblespace}.
+% \changes{v1.7}{2017/06/15}{Adapt patch to changes in \pkg{amsmath}}
+% \changes{v1.8}{2019/01/21}{Stop using \cs{…:D} control sequences}
+% \begin{macrocode}
+ \@@_patch:cNnnn { genfrac~ } \cs_set:Npn {
+ #1 #2 #3 #4 #5 #6
+ } {
+ {
+ \@mathstyle { #4 }
+ \genfrac@choice o { #1 }
+ {
+ \begingroup #5 \endgroup
+%<@@=>
+ \ifx @ #3 @ \@@over \else \@@above \fi #3 \relax
+ #6
+ }
+ \genfrac@choice c { #2 }
+ }
+ } {
+ {
+ \@mathstyle { #4 }
+ \genfrac@choice o { #1 }
+ {
+ \Ustack {
+ \group_begin: #5 \group_end:
+ \tl_if_empty:nTF { #3 } { \@@over } { \@@above #3 \scan_stop: }
+%<@@=lltxmath>
+ #6
+ }
+ }
+ \genfrac@choice c { #2 }
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \changes{v1.1}{2012/10/13}{Add fix and unit test for \pkg{amsopn}}
+% \changes{v1.6}{2016/04/16}{Removed patch for \cs{newmcodes@};
+% \pkg{amsmath} now has a definition usable in \Hologo{LuaLaTeX}}
+%
+%
+% \subsection{\pkg{mathtools}}
+%
+% \pkg{mathtools}’ \cmd{\cramped} command and others that make use of its
+% internal version use a hack involving a null radical. \Hologo{LuaTeX} has
+% primitives for setting material in cramped mode, so we make use of them.
+%
+% \begin{macro}{\MT_cramped_internal:Nn}
+% The macro \cmd{\MT_cramped_internal:Nn}\meta{style}\marg{expression}
+% typesets the \meta{expression} in the cramped style corresponding to the
+% given \meta{style} (\cmd{\displaystyle} etc.); all we have to do in
+% \hologo{LuaTeX} is to select the correct primitive. Rewriting the
+% user-level \cmd{\cramped} command and employing \cmd{\mathstyle} would be
+% possible as well, but we avoid this way since we want to patch only a
+% single command.
+% \begin{macrocode}
+\AtEndOfPackageFile * { mathtools } {
+ \@@_patch:NNnnn \MT_cramped_internal:Nn
+ \cs_set_nopar:Npn { #1 #2 } {
+ \sbox \z@ {
+ $
+ \m@th
+ #1
+ \nulldelimiterspace = \z@
+ \radical \z@ { #2 }
+ $
+ }
+ \ifx #1 \displaystyle
+ \dimen@ = \fontdimen 8 \textfont 3
+ \advance \dimen@ .25 \fontdimen 5 \textfont 2
+ \else
+ \dimen@ = 1.25 \fontdimen 8
+ \ifx #1 \textstyle
+ \textfont
+ \else
+ \ifx #1 \scriptstyle
+ \scriptfont
+ \else
+ \scriptscriptfont
+ \fi
+ \fi
+ 3
+ \fi
+ \advance \dimen@ -\ht\z@
+ \ht\z@ = -\dimen@
+ \box\z@
+ } {
+% \end{macrocode}
+% \changes{v1.4}{2014/08/18}{Added \cs{ensuremath} to work around
+% \href{https://github.com/phst/lualatex-math/issues/11}{issue~11}}
+% Here the additional set of braces is absolutely necessary, otherwise the
+% changed mathematical style would be applied to the material after the
+% \cmd{\mathchoice} construct. As the original command works in both text and
+% math mode, we use |\ensuremath| here.
+% \begin{macrocode}
+ {
+ \ensuremath {
+ \use:c { luatex_cramped \cs_to_str:N #1 :D } #2
+ }
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{\pkg{icomma}}
+%
+% \changes{v0.2}{2011/07/03}{Added patch for the \pkg{icomma} package}
+% The \pkg{icomma} package uses |\mathchardef| to save the mathematical code of
+% the comma character. This breaks for Unicode fonts. The incompatibility was
+% noticed by
+% \Breitfeld.\footnote{\url{https://groups.google.com/forum/\#!topic/de.comp.text.tex/Cputk-AJS5I/discussion}}
+%
+% \begin{macro}{\mathcomma}
+% \pkg{icomma} defines the mathemathical character shorthand \cmd{\icomma} at
+% the beginning of the document, therefore we again patch
+% \cmd{\@begindocumenthook}.
+% \begin{macrocode}
+\AtEndOfPackageFile * { icomma } {
+ \tl_replace_once:Nnn \@begindocumenthook {
+ \mathchardef \mathcomma \mathcode `\,
+ } {
+ \@@_set_mathchar:NN \mathcomma \,
+ }
+}
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \section{Implementation of the \hologo{LuaLaTeX} module}
+%
+% For the Lua module, we use the standard \pkg{luatexbase-modutils} template.
+% \changes{v1.3}{2013/08/03}{Stop using the deprecated \func{module} function}
+% \changes{v1.4a}{2015/08/24}{Load all of \pkg{luatexbase}}
+% \begin{macrocode}
+%<*lua>
+lualatex = lualatex or {}
+lualatex.math = lualatex.math or {}
+luatexbase.provides_module({
+ name = "lualatex-math",
+ date = "2013/08/03",
+ version = 1.3,
+ description = "Patches for mathematics typesetting with LuaLaTeX",
+ author = "Philipp Stephani",
+ licence = "LPPL v1.3+"
+})
+% \end{macrocode}
+% \begin{function}{unpack}
+% \changes{v1.3}{2013/08/03}{Integrate Philipp Gesang’s patch to make the
+% \func{unpack} function compatible with Lua~5.2}
+% The function \func{unpack} needs to be treated specially as it got moved
+% around in Lua~5.2.
+% \begin{macrocode}
+local unpack = unpack or table.unpack
+% \end{macrocode}
+% \end{function}
+% \changes{v1.4a}{2015/08/24}{Pick up new name for string catcode table
+% where available}
+% \begin{macrocode}
+local cctb = luatexbase.catcodetables or
+ {string = luatexbase.registernumber("catcodetable@string")}
+% \end{macrocode}
+%
+% \changes{v1.5}{2016/03/07}{Removed unused Lua function \func{print_fam_slot}}
+%
+% \begin{function}{print_class_fam_slot}
+% The function \func{print_class_fam_slot} takes one argument which must be a
+% number. It interprets the argument as a Unicode code point whose
+% mathematical code is printed in the form
+% \meta{class}\texttt{\textvisiblespace}\meta{family}\texttt{\textvisiblespace}\meta{slot},
+% suitable for the right-hand side of \cmd{\Umathchardef}.
+% \begin{macrocode}
+function lualatex.math.print_class_fam_slot(char)
+ local code = tex.getmathcode(char)
+ local class, family, slot = unpack(code)
+ local result = string.format("%i %i %i ", class, family, slot)
+ tex.sprint(cctb.string, result)
+end
+% \end{macrocode}
+% \end{function}
+% \begin{macrocode}
+return lualatex.math
+%</lua>
+% \end{macrocode}
+%
+% \Finale
+\endinput
+
+% Local Variables:
+% mode: doctex
+% coding: utf-8-unix
+% TeX-engine: luatex
+% End:
diff --git a/macros/luatex/latex/lualatex-math/lualatex-math.ins b/macros/luatex/latex/lualatex-math/lualatex-math.ins
new file mode 100644
index 0000000000..175173b1a6
--- /dev/null
+++ b/macros/luatex/latex/lualatex-math/lualatex-math.ins
@@ -0,0 +1,88 @@
+% lualatex-math.ins
+% Copyright 2011, 2012, 2013, 2017 Philipp Stephani
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either
+% version 1.3c of this license or (at your option) any later
+% version. The latest version of this license is in
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3c or later is part of all distributions of
+% LaTeX version 2009/09/24 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+% The Current Maintainer of this work is Philipp Stephani.
+% This work consists of all files listed in MANIFEST.
+
+\input l3docstrip.tex
+
+\keepsilent
+\askforoverwritefalse
+
+\usedir{tex/lualatex/lualatex-math}
+
+\preamble
+
+This is a generated file.
+
+Copyright 2011-2017 Philipp Stephani
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of
+LaTeX version 2009/09/24 or later.
+
+\endpreamble
+
+\generate{
+ \file{lualatex-math.sty}{\from{lualatex-math.dtx}{package}}
+ \file{lualatex-math.drv}{\from{lualatex-math.dtx}{driver}}
+}
+
+\def\MetaPrefix{--}
+\preamble
+
+This is a generated file.
+
+Copyright 2011-2017 Philipp Stephani
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of
+LaTeX version 2009/09/24 or later.
+
+\endpreamble
+\nopostamble
+
+\generate{
+ \file{lualatex-math.lua}{\from{lualatex-math.dtx}{lua}}
+}
+
+\obeyspaces
+\Msg{*****************************************************}
+\Msg{* *}
+\Msg{* To finish the installation you have to move the *}
+\Msg{* following files into a directory searched by TeX: *}
+\Msg{* *}
+\Msg{* lualatex-math.sty *}
+\Msg{* lualatex-math.lua *}
+\Msg{* *}
+\Msg{* To produce the documentation run the file *}
+\Msg{* lualatex-math.dtx through LaTeX. *}
+\Msg{* *}
+\Msg{* Happy TeXing! *}
+\Msg{* *}
+\Msg{*****************************************************}
+
+\endbatchfile
diff --git a/macros/luatex/latex/lualatex-math/lualatex-math.pdf b/macros/luatex/latex/lualatex-math/lualatex-math.pdf
new file mode 100644
index 0000000000..c1728ca518
--- /dev/null
+++ b/macros/luatex/latex/lualatex-math/lualatex-math.pdf
Binary files differ
diff --git a/macros/luatex/latex/lualatex-truncate/README.md b/macros/luatex/latex/lualatex-truncate/README.md
new file mode 100644
index 0000000000..53de8f0486
--- /dev/null
+++ b/macros/luatex/latex/lualatex-truncate/README.md
@@ -0,0 +1,36 @@
+# lualatex-truncate
+This package provides a wrapper for the [`truncate` package](https://ctan.org/pkg/truncate) package,
+which fixes issues related to LuaTeX's hyphenation algorithm.
+
+
+### Dependencies
+`lualatex-truncate` depends on these packages:
+`iftex`, `letltxmacro` and `truncate`
+
+
+### Installation
+Extract the *package* file first:
+
+ 1. Run LaTeX over the file `lualatex-truncate.ins`
+ 2. Move the resulting `.sty` file to `TEXMF/tex/lualatex/lualatex-truncate/`
+
+Then, you can compile the *documentation* yourself by executing
+
+ lualatex lualatex-truncate-doc.dtx
+ makeindex -s gind.ist lualatex-truncate-doc.idx
+ makeindex -s gglo.ist -o lualatex-truncate-doc.gls lualatex-truncate-doc.glo
+ lualatex lualatex-truncate-doc.dtx
+ lualatex lualatex-truncate-doc.dtx
+
+
+or just use the precompiled documentation shipped with the source files.
+In both cases, copy the files `lualatex-truncate-doc.pdf` and `README.md` to `TEXMF/doc/lualatex/lualatex-truncate/`.
+
+
+
+### License
+LPPL 1.3c or any later version (available at [http://www.latex-project.org/lppl.txt](http://www.latex-project.org/lppl.txt "Show the current version of the LPPL"))
+
+This package is *maintained*. Current maintainer is [Sebastian Friedl](mailto:sfr682k@t-online.de).
+
+
diff --git a/macros/luatex/latex/lualatex-truncate/lualatex-truncate-doc.dtx b/macros/luatex/latex/lualatex-truncate/lualatex-truncate-doc.dtx
new file mode 100644
index 0000000000..38fb37afa4
--- /dev/null
+++ b/macros/luatex/latex/lualatex-truncate/lualatex-truncate-doc.dtx
@@ -0,0 +1,262 @@
+%\iffalse
+%% Doc-Source file to use with LaTeX2e
+%% Copyright (C) 2018 Sebastian Friedl
+%%
+%% This work is subject to the LaTeX Project Public License, Version 1.3c or -- at
+%% your option -- any later version of this license.
+%% The work consists of the files lualatex-truncate.dtx, lualatex-truncate.ins,
+%% lualatex-truncate-doc.dtx and the derived file lualatex-truncate.sty
+%%
+%% This work has the LPPL maintenance status ‘maintained’.
+%% Current maintainer of the work is Sebastian Friedl.
+%%
+%% -------------------------------------------------------------------------------------------
+%%
+%% A LuaLaTeX wrapper for the truncate package
+%%
+%% -------------------------------------------------------------------------------------------
+%%
+%% Please report bugs and other problems as well as suggestions for improvements
+%% to my email address (sfr682k@t-online.de).
+%%
+%% -------------------------------------------------------------------------------------------
+%\fi
+
+% !TeX spellcheck=en_US
+
+\documentclass[11pt]{ltxdoc}
+
+\usepackage{iftex}
+\RequireLuaTeX
+
+\usepackage[no-math]{fontspec}
+\usepackage{polyglossia}
+\setdefaultlanguage{english}
+\usepackage[english]{selnolig}
+
+\usepackage{array}
+\usepackage{csquotes}
+\usepackage{hologo}
+\usepackage{multicol}
+\usepackage{xcolor}
+
+
+\parindent0pt
+
+\usepackage[erewhon]{newtxmath}
+\setmainfont{erewhon}
+\setsansfont[Scale=MatchLowercase]{Source Sans Pro}
+\setmonofont[Scale=MatchLowercase]{Hack}
+
+\usepackage[a4paper,left=4.50cm,right=2.75cm,top=3.25cm,bottom=2.75cm,nohead]{geometry}
+
+
+\hyphenation{mo-dify-ing}
+
+\def\Lua{\textsf{Lua}\ignorespaces}
+
+\usepackage[unicode, pdfborder={0 0 0}, linktoc=all, hyperindex=false]{hyperref}
+\usepackage{bookmark}% fix PDF bookmark issues caused by hyperref
+
+
+
+\MakeShortVerb{"}
+\CheckSum{55}
+
+\renewcommand*{\usage}[1]{\hyperpage{#1}}
+\renewcommand*{\main}[1]{\hyperpage{#1}}
+
+\newcommand*{\sty}[1]{\textsf{#1}}
+\newcommand*{\opt}[1]{\texttt{#1}\index{#1=\texttt{#1}~~option|main}}
+
+\def\param#1{\textit{\rmfamily\ensuremath{\langle}#1\ensuremath{\rangle}}}
+\def\DescribeOption#1{\marginpar{\raggedleft\PrintDescribeMacro{#1}}}
+
+
+\PageIndex
+\RecordChanges
+
+
+
+
+\title{The \sty{lualatex-truncate} package \\ {\large\url{https://gitlab.com/SFr682k/lualatex-truncate}}}
+\author{Sebastian Friedl \\ \href{mailto:sfr682k@t-online.de}{\ttfamily sfr682k@t-online.de}}
+\date{2018/08/22 (v1.1)}
+
+\hypersetup{pdftitle={The lualatex-truncate package},pdfauthor={Sebastian Friedl}}
+
+\begin{document}
+ \maketitle
+ \thispagestyle{empty}
+
+
+
+
+ \medskip
+ \begin{abstract}\centering
+ \hspace{-1.5em}%
+ This package provides a wrapper for using the \sty{truncate} package\footnote{available at \url{https://ctan.org/pkg/truncate}},
+ thus fixing issues related to \hologo{LuaTeX}'s hyphenation mechanism.
+ \end{abstract}
+
+
+
+ \tableofcontents
+
+
+
+
+ \clearpage
+
+
+ \subsection*{Dependencies and other requirements}
+ \addcontentsline{toc}{subsection}{Dependencies and other requirements}
+ \sty{lualatex-truncate} requires \LaTeXe\ and depends on the following packages:
+ \begin{multicols}{3}\sffamily\centering
+ if\kern0pt tex \\ letltxmacro \\ truncate
+ \end{multicols}
+
+
+ \subsection*{Installation}
+ \addcontentsline{toc}{subsection}{Installation}
+ Extract the \textit{package} file first:
+ \begin{enumerate}
+ \item Run \LaTeX\ over the file "lualatex-truncate.ins"
+ \item Move the resulting ".sty" file to "TEXMF/tex/lualatex/lualatex-truncate/"
+ \end{enumerate}
+
+ Then, you can compile the \textit{documentation} yourself by executing \\[\smallskipamount]
+ "lualatex lualatex-truncate-doc.dtx" \\
+ "makeindex -s gind.ist lualatex-truncate-doc.idx" \\
+ "makeindex -s gglo.ist -o lualatex-truncate-doc.gls lualatex-truncate-doc.glo" \\
+ "lualatex lualatex-truncate-doc.dtx" \\
+ "lualatex lualatex-truncate-doc.dtx"
+
+ \smallskip
+ or just use the precompiled documentation shipped with the source files. \\
+ In both cases, copy the files "lualatex-truncate-doc.pdf" and "README.md" to \\
+ "TEXMF/doc/lualatex/lualatex-truncate/"
+
+
+ \subsection*{License}
+ \addcontentsline{toc}{subsection}{License}
+ \textcopyright\ 2018 Sebastian Friedl
+
+ \smallskip
+ This work may be distributed and/or modified under the conditions of the \LaTeX\ Project Public License, either version 1.3c of this license or (at your option) any later version.
+
+ \smallskip
+ The latest version of this license is available at \url{http://www.latex-project.org/lppl.txt} and version 1.3c or later is part of all distributions of \LaTeX\ version 2008-05-04 or later.
+
+ \smallskip
+ This work has the LPPL maintenace status \enquote*{maintained}. \\
+ Current maintainer of this work is Sebastian Friedl.
+
+ \medskip
+ This work consists of the following files:
+ \begin{itemize} \itemsep 0pt
+ \item "lualatex-truncate.sty",
+ \item "lualatex-truncate.ins",
+ \item "lualatex-truncate-doc.dtx" and
+ \item the derived file "lualatex-truncate.sty"
+ \end{itemize}
+
+
+
+
+
+ % DOCUMENTATION PART ----------------------------------------------------------------------
+ \clearpage
+ \part{The documentation}
+ \begin{center}
+ \colorbox{red!75!black}{\colorbox{white}{\begin{minipage}{.95\textwidth}
+ \textbf{\color{red!75!black}\large Don't load the \sty{truncate} package in your preamble!!}
+
+ \medskip
+ This task is already done for you by \sty{lualatex-truncate}!
+
+ \smallskip
+ Also, all package options stated in this documentation are meant to be passed to \sty{lualatex-truncate}; otherwise they can't be processed by the wrapper mechanism.
+ \end{minipage}}}
+ \end{center}
+
+
+ \subsection*{Truncating text to a given width%
+ \footnote{This section has been adapted from \sty{truncate}'s documentation: \\
+ \indent\indent\url{http://mirrors.ctan.org/macros/latex/contrib/truncate/truncate.pdf}}}
+ \addcontentsline{toc}{subsection}{Truncating text to a given width}
+
+ \leavevmode%
+ \DescribeOption{\truncate}%
+ The package defines a command "\truncate["\param{marker}"]{"\param{width}"}{"\param{text}"}".
+
+ If the text is too wide to fit in the specified width, then it is truncated, and a continuation marker is shown at the end.
+ The default marker, used when the optional \texttt{[\param{marker}]} parameter is omitted, is "\,\dots". You can change this default by redefining \DescribeMacro{\TruncateMarker}"\TruncateMarker" (e.g.~"\renewcommand\TruncateMarker{\dots}").
+
+ \medskip
+ Normally, the text (no matter whether truncated or not) is printed flushed-left in a box with exactly the width specified. The package option \DescribeOption{fit}\opt{fit} causes the output text to have its natural width, up to a maximum of the specified width.
+
+ \medskip
+ Normally, the text won't be truncated in the middle of a word, nor at a space specified with a tie ("~"). For example:
+ \begin{quote}
+ "\truncate{122pt}{This text has been~truncated}"
+ \end{quote}
+ gives
+ \begin{quote}
+ \enquote{\hbox to 122pt {This text has\,\dots\hfill}}
+ \end{quote}
+
+ \medskip
+ You can use one of the package options \DescribeOption{hyphenate}\opt{hyphenate}, \DescribeOption{breakwords}\opt{breakwords} or \DescribeOption{breakall}\opt{breakall} to allow truncating in the middle of words. The first two only truncate at hyphenation points; with the only difference that \opt{breakwords} suppresses the hyphen character.
+ On the other hand, \opt{breakall} allows truncation at any character. For example:
+ \begin{quote}
+ "\truncate{122pt}{This text has been~truncated}"
+ \end{quote}
+ gives
+ \begin{quote}
+ \begin{tabular}{l@{\quad}l}
+ \enquote{\hbox to 122pt {This text has been trun-\,\dots\hfill}} & (package option \texttt{hyphenate}) \\
+ \enquote{\hbox to 122pt {This text has been trun\,\dots~\hfill}} & (package option \texttt{breakwords}) \\
+ \enquote{\hbox to 122pt {This text has been trunc\,\dots\hfill}} & (package option \texttt{breakall})
+ \end{tabular}
+ \end{quote}
+
+ [All of these options work through (Lua)\TeX's hyphenation mechanism.]
+
+
+ \subsection*{Known limitations}
+ \addcontentsline{toc}{subsection}{Known limitations}
+ \begin{itemize}
+ \item
+ \sty{lualatex-truncate} provides a \textit{wrapper} fixing \hologo{LuaTeX}-related \enquote{glitches} in the \sty{truncate} package.
+ It doesn't (and won't) fix any bugs or \enquote{undocumented features} introduced by the \sty{truncate} package itself.
+ \end{itemize}
+
+
+
+
+
+
+
+
+ % Start determining the checksum from here
+ \StopEventually{%
+ \clearpage
+ \phantomsection
+ \addcontentsline{toc}{part}{Index}%
+ \PrintChanges
+ \setcounter{IndexColumns}{2}
+ \IndexPrologue{\section*{Index}}
+ \PrintIndex}
+
+
+
+ \vspace{3\bigskipamount}
+ \part{The package code}
+ \CodelineNumbered
+ \DocInput{lualatex-truncate.dtx}
+
+
+ \Finale
+\end{document}
+
diff --git a/macros/luatex/latex/lualatex-truncate/lualatex-truncate-doc.pdf b/macros/luatex/latex/lualatex-truncate/lualatex-truncate-doc.pdf
new file mode 100644
index 0000000000..67dd999e19
--- /dev/null
+++ b/macros/luatex/latex/lualatex-truncate/lualatex-truncate-doc.pdf
Binary files differ
diff --git a/macros/luatex/latex/lualatex-truncate/lualatex-truncate.dtx b/macros/luatex/latex/lualatex-truncate/lualatex-truncate.dtx
new file mode 100644
index 0000000000..06d035702a
--- /dev/null
+++ b/macros/luatex/latex/lualatex-truncate/lualatex-truncate.dtx
@@ -0,0 +1,166 @@
+%\iffalse
+%<*package>
+%% \CharacterTable
+%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%% Digits \0\1\2\3\4\5\6\7\8\9
+%% Exclamation \! Double quote \" Hash (number) \#
+%% Dollar \$ Percent \% Ampersand \&
+%% Acute accent \' Left paren \( Right paren \)
+%% Asterisk \* Plus \+ Comma \,
+%% Minus \- Point \. Solidus \/
+%% Colon \: Semicolon \; Less than \<
+%% Equals \= Greater than \> Question mark \?
+%% Commercial at \@ Left bracket \[ Backslash \\
+%% Right bracket \] Circumflex \^ Underscore \_
+%% Grave accent \` Left brace \{ Vertical bar \|
+%% Right brace \} Tilde \~}
+%</package>
+%\fi
+%\iffalse
+% Doc-Source file to use with LaTeX2e
+% Copyright (C) 2018 Sebastian Friedl
+%
+% This work is subject to the LaTeX Project Public License, Version 1.3c or -- at
+% your option -- any later version of this license.
+% The work consists of the files lualatex-truncate.dtx, lualatex-truncate.ins,
+% lualatex-truncate-doc.dtx and the derived file lualatex-truncate.sty
+%
+% This work has the LPPL maintenance status 'maintained'.
+% Current maintainer of the work is Sebastian Friedl.
+%\fi
+%
+%
+%
+% \changes{1.0}{2018/06/03}{Initial release}
+% \changes{1.1}{2018/08/22}{\textsc{\bfseries Bugfix:} visible hyphen char with \texttt{breakall} option and non-english language}
+%
+% \subsubsection*{Initialization}
+% Identify the package and require \LaTeXe:
+% \begin{macrocode}
+\ProvidesPackage{lualatex-truncate}%
+ [2018/08/22 v1.1 LuaLaTeX wrapper for the truncate package]
+\NeedsTeXFormat{LaTeX2e}
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{Internal variables}
+% This variable is used to remember whether messing with the hyphen char is required:
+% \begin{macrocode}
+\newif\if@lualtxtruncate@hackhyphen
+\@lualtxtruncate@hackhyphenfalse
+% \end{macrocode}
+%
+% Also, enable remembering whether the \opt{breakall} option has been used:
+% \begin{macrocode}
+\newif\if@lualtxtruncate@breakall
+\@lualtxtruncate@breakallfalse
+% \end{macrocode}
+%
+%
+%
+%
+% \subsubsection*{Package options}
+% The \opt{breakwords} and \opt{breakall} options require the hyphanation character to be hidden.
+% Therefore, we remember to \enquote{hack} the hyphen character before passing these options
+% to the \enquote{original} \sty{truncate} package:
+% \begin{macrocode}
+\DeclareOption{breakwords}{%
+ \@lualtxtruncate@hackhyphentrue%
+ \PassOptionsToPackage{breakwords}{truncate}}
+% \end{macrocode}
+%
+% In case of the \opt{breakall} option, we also need to remember the option's usage:
+% \begin{macrocode}
+\DeclareOption{breakall}{%
+ \@lualtxtruncate@breakalltrue%
+ \@lualtxtruncate@hackhyphentrue%
+ \PassOptionsToPackage{breakall}{truncate}}
+% \end{macrocode}
+%
+% \smallskip
+% Pass all other options (i.e. \opt{hyphenate} and \opt{fit}) directly to the \sty{truncate} package:
+% \begin{macrocode}
+\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{truncate}}
+% \end{macrocode}
+%
+% \smallskip
+% Process all options passed to \sty{lualatex-truncate}:
+% \begin{macrocode}
+\ProcessOptions
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{Load the \sty{truncate} package}
+% Require the \sty{truncate} package. All package options have already been passed on. \\
+% If \sty{truncate} has been loaded already, a error message is printed to the log.
+% \begin{macrocode}
+\@ifpackageloaded{truncate}{%
+ \PackageError{lualatex-truncate}%
+ {Don't load the truncate package when using lualatex-truncate!}%
+ {Don't load the truncate package and pass all package options
+ to lualatex-truncate! Otherwise, the wrapper mechanism won't
+ be able to understand what you want.}%
+}{\RequirePackage{truncate}}
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{If the document is not compiled via \hologo{LuaLaTeX}\dots}
+% Don't wrap anything if the document isn't compiled by \hologo{LuaLaTeX}:
+% \begin{macrocode}
+\RequirePackage{iftex}
+\ifLuaTeX\else%
+ \PackageWarningNoLine{lualatex-truncate}%
+ {Whoops! You don't want to use LuaLaTeX?}%
+ \endinput%
+\fi%
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{Constructing the wrapper}
+% \begin{macro}{\lualtxtruncate@truncate}
+% Remember the original "\truncate" command's definition.
+% Since "\truncate" provides an optional argument, "\LetLtxMacro" has to be used
+% instead of the primitive "\let" command:
+% \begin{macrocode}
+\RequirePackage{letltxmacro}
+\LetLtxMacro\lualtxtruncate@truncate\truncate
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\truncate}
+% \changes{1.1}{2018/08/22}{Remember previous hyphenation character}
+% Construct the wrapper by redefining the "\truncate" command
+% and -- if necessary -- modifying "\prehyphenchar". \\
+% "\prehyphenchar"'s value is stored inside the counter
+% "\lualtxtruncate@tmp". Also, the current language must be set to US english,
+% if the \opt{breakall} option has been used.
+% \begin{macrocode}
+\renewcommand{\truncate}[3][\TruncateMarker]{{% two braces -> scope changes
+ \if@lualtxtruncate@breakall%
+ \language\z@% force US english
+ \fi%
+ \newcount\lualtxtruncate@tmp%
+ \lualtxtruncate@tmp=\the\prehyphenchar% remember current hyphen char
+ \if@lualtxtruncate@hackhyphen%
+ \prehyphenchar=0% invisible hyphen
+ \fi%
+ \lualtxtruncate@truncate[#1]{#2}{#3}% run the original \truncate macro
+ \if@lualtxtruncate@hackhyphen%
+ \prehyphenchar=\the\lualtxtruncate@tmp% restore hyphen
+ \fi%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsubsection*{Famous last words}
+% Enough code for this package. "\endinput".
+% \begin{macrocode}
+\endinput
+% \end{macrocode}
diff --git a/macros/luatex/latex/lualatex-truncate/lualatex-truncate.ins b/macros/luatex/latex/lualatex-truncate/lualatex-truncate.ins
new file mode 100644
index 0000000000..696eeca771
--- /dev/null
+++ b/macros/luatex/latex/lualatex-truncate/lualatex-truncate.ins
@@ -0,0 +1,41 @@
+\input docstrip
+
+\preamble
+ lualatex-truncate.dtx
+ Copyright 2018 Sebastian Friedl
+
+ This work may be distributed and/or modified under the
+ conditions of the LaTeX Project Public License, either version 1.3c
+ of this license of (at your option) any later version.
+ The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+ and version 1.3c or later is part of all distributions of LaTeX
+ version 2008/05/04 or later.
+
+ This work has the LPPL maintenance status 'maintained'.
+ Current maintainer of the work is Sebastian Friedl
+
+ This work consists of the files lualatex-truncate.dtx, lualatex-truncate.ins,
+ lualatex-truncate-doc.dtx and the derived file lualatex-truncate.sty
+
+\endpreamble
+
+\askforoverwritefalse
+
+
+
+
+\generate
+{%
+ \file
+ {lualatex-truncate.sty}%
+ {%
+ \usepreamble\defaultpreamble
+ \usepostamble\defaultpostamble
+ \from{lualatex-truncate.dtx}{lualatex-truncate.sty,package}%
+ }%
+}
+
+
+\endbatchfile
+
diff --git a/macros/luatex/latex/luamesh/README b/macros/luatex/latex/luamesh/README
new file mode 100644
index 0000000000..be387c79e6
--- /dev/null
+++ b/macros/luatex/latex/luamesh/README
@@ -0,0 +1,47 @@
+-*- coding: utf-8 -*-
+luamesh package by Maxime Chupin
+Version 0.51 dated 2017/04/15
+
+The LuaLaTeX package luamesh allows to compute and draw 2D Delaunay triangulation.
+The algorithm is written with lua, and depending on the choice of the “engineâ€,
+the drawing is done by MetaPost (with luamplib) or by tikz.
+The Delaunay triangulation algorithm is the Bowyer and Watson algorithm.
+Several macros are provided to draw the global mesh, the set of points, or
+a particular step of the algorithm.
+
+This work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3
+of this license or (at your option) any later version.
+The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+FILES :
+===== documentation =====
+README
+animation-crop.pdf
+biblio.bib
+dum.bbl
+dum.tex
+fond.mp
+fond.pdf
+lltxdoc.cls
+luamesh-doc.listing
+luamesh-doc.pdf
+luamesh-doc.tex
+luamesh-title.pdf
+maillage.geo
+maillage.msh
+meshgarde.txt
+
+===== Lua Script File =====
+luamesh.lua
+luamesh-polygon.lua
+luamesh-tex.lua
+
+===== Files for LuaLaTeX =====
+luamesh.sty
+==================
+
+The archive luamesh-v0-5.zip contains all the files to insert into your texmf.
diff --git a/macros/luatex/latex/luamesh/doc/animation-crop.pdf b/macros/luatex/latex/luamesh/doc/animation-crop.pdf
new file mode 100644
index 0000000000..2ea7b9b657
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/animation-crop.pdf
Binary files differ
diff --git a/macros/luatex/latex/luamesh/doc/biblio.bib b/macros/luatex/latex/luamesh/doc/biblio.bib
new file mode 100644
index 0000000000..4d7ab75ef2
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/biblio.bib
@@ -0,0 +1,92 @@
+% This file was created with JabRef 2.10.
+% Encoding: UTF-8
+
+
+@Article{Bowyer,
+ Title = {Computing {D}irichlet tessellations},
+ Author = {Bowyer, A.},
+ Journal = {Comput. J.},
+ Year = {1981},
+ Number = {2},
+ Pages = {162--166},
+ Volume = {24},
+
+ Coden = {CMPJA6},
+ Doi = {10.1093/comjnl/24.2.162},
+ Fjournal = {The Computer Journal},
+ ISSN = {0010-4620},
+ Mrclass = {52-04 (52A25)},
+ Mrnumber = {619576},
+ Url = {http://dx.doi.org/10.1093/comjnl/24.2.162}
+}
+
+@Book{Frey,
+ Title = {Mesh generation},
+ Author = {Frey, Pascal Jean and George, Paul-Louis},
+ Publisher = {ISTE, London; John Wiley \& Sons, Inc., Hoboken, NJ},
+ Year = {2008},
+ Edition = {Second},
+ Note = {Application to finite elements},
+
+ Doi = {10.1002/9780470611166},
+ ISBN = {978-1-84821-029-5},
+ Mrclass = {65N50 (65-02 65N30)},
+ Mrnumber = {2398720},
+ Pages = {848},
+ Url = {http://dx.doi.org/10.1002/9780470611166}
+}
+
+@Manual{luamplib,
+ Title = {luamplib – Use LuaTeX's built-in METAPOST interpreter},
+ Author = {Hagen, Hans and Hoekwater, Taco and Roux, Élie and Pégourié-Gonnard, Manuel and Gesang, Philipp and Kim, Dohyun},
+ Note = {v. 2.11.3},
+ Year = {2016},
+
+ Owner = {chupin},
+ Timestamp = {2016.11.28}
+}
+
+@Manual{animate,
+ Title = {The animate Package},
+ Author = {Grahn, Alexander},
+ Note = {},
+ Year = {2016},
+}
+
+@Manual{tikz,
+ Title = {pgf – Create PostScript and PDF graphics in TeX},
+ Author = {Tantau, Till and Feuersänger, Christian},
+ Note = {v. 3.0.1a},
+ Year = {2015},
+
+ Owner = {chupin},
+ Timestamp = {2016.11.28}
+}
+@Manual{gmsh,
+ Title = {Gmsh Reference Manual},
+ Author = {Geuzaine, Christophe and Remacle, Jean-Francois Tantau},
+ Note = {v. 2.14},
+ Year = {2016},
+
+ Owner = {chupin},
+ Timestamp = {2016.11.28}
+}
+
+@Article{Watson,
+ Title = {Computing the {$n$}-dimensional {D}elaunay tessellation with
+ application to {V}orono\u\i\ polytopes},
+ Author = {Watson, D. F.},
+ Journal = {Comput. J.},
+ Year = {1981},
+ Number = {2},
+ Pages = {167--172},
+ Volume = {24},
+
+ Coden = {CMPJA6},
+ Doi = {10.1093/comjnl/24.2.167},
+ Fjournal = {The Computer Journal},
+ ISSN = {0010-4620},
+ Mrclass = {52-04 (52A25)},
+ Mrnumber = {619577},
+ Url = {http://dx.doi.org/10.1093/comjnl/24.2.167}
+}
diff --git a/macros/luatex/latex/luamesh/doc/dum.tex b/macros/luatex/latex/luamesh/doc/dum.tex
new file mode 100644
index 0000000000..19753f3926
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/dum.tex
@@ -0,0 +1,6 @@
+\documentclass{article}
+\begin{document}
+\nocite{*}
+\bibliography{biblio}
+\bibliographystyle{plain}
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luamesh/doc/fond.mp b/macros/luatex/latex/luamesh/doc/fond.mp
new file mode 100644
index 0000000000..8f2ca64328
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/fond.mp
@@ -0,0 +1,21 @@
+input svgnames;
+
+l = 596;
+h = 842;
+
+pair A, B, C, D;
+
+A = (0,0);
+B = (l,0);
+C = (l,h);
+D = (0,h);
+
+beginfig(1);
+
+ fill (A--B--D--cycle) withcolor Moccasin;
+ fill (A--C--D--cycle) withcolor Gainsboro;
+
+
+endfig;
+
+end
diff --git a/macros/luatex/latex/luamesh/doc/fond.pdf b/macros/luatex/latex/luamesh/doc/fond.pdf
new file mode 100644
index 0000000000..22218152cc
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/fond.pdf
Binary files differ
diff --git a/macros/luatex/latex/luamesh/doc/lltxdoc.cls b/macros/luatex/latex/luamesh/doc/lltxdoc.cls
new file mode 100644
index 0000000000..d0b4d47fde
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/lltxdoc.cls
@@ -0,0 +1,105 @@
+% private class for lualatex-doc
+% see lualatex-doc.tex for copying conditions
+% Manuel Pégourié-Gonnard
+
+\ProvidesClass{lltxdoc}
+
+\LoadClass[a4paper]{scrartcl}
+\RequirePackage{luamesh}
+\RequirePackage{fontspec}
+\RequirePackage{metalogo, xspace, ifmtarg, xargs, fancyvrb}
+\RequirePackage[french,english]{babel}
+\RequirePackage[colorlinks=true]{hyperref}
+%\RequirePackage{bookmark}
+
+\defaultfontfeatures{Ligatures=TeX, Scale=MatchLowercase}
+% \setmainfont{Linux Libertine O}
+%\setmainfont{Slabo 27px}
+\usepackage{unicode-math}
+\setmainfont{Libertinus Serif}
+\setmathfont{Libertinus Math}
+\setsansfont{Kurier}
+\setmonofont{Monaco}
+
+\newcommand*\simplelogo [1] {%
+ \ifcsname #1\endcsname \else \badlogocommand \fi
+ \lowercase{\expandafter\simple@logo\expandafter{%
+ \csname #1\expandafter\endcsname\expandafter}}\expandafter{%
+ \csname #1\endcsname}{#1}}
+\newcommand*\simple@logo [3] {%
+ \newcommand #1 {#2\xspace}%
+ \pdfstringdefDisableCommands{\def#1{#3\space}}}
+
+\providecommand \ConTeXt {Con\TeX{}t}
+\providecommand \pdfTeX {pdf\TeX}
+\providecommand \TeXLive {\TeX\thinspace Live}
+\providecommand \MiKTeX {MiK\TeX}
+
+\simplelogo {TeX}
+\simplelogo {LaTeX}
+\simplelogo {LuaTeX}
+\simplelogo {LuaLaTeX}
+\simplelogo {XeTeX}
+\simplelogo {XeLaTeX}
+\simplelogo {ConTeXt}
+\simplelogo {pdfTeX}
+\simplelogo {MiKTeX}
+\simplelogo {TeXLive}
+
+\colorlet{code}{blue!80!black}
+\fvset{formatcom=\color{code}}
+\DefineShortVerb|
+\catcode`\ 10 % non-breakable space
+
+\newcommand*\email [1] {<\href{mailto:#1}{#1}>}
+\newcommand*\ctan [1]
+{\href{http://mirror.ctan.org/#1}{\nolinkurl{#1}}}
+\newcommand \file {\nolinkurl}
+\newcommand*\note [1] {\noindent\textsf{\bfseries #1.}\quad\ignorespaces}
+\newcommand \cmd {\texttt}
+\newcommand \code [1] {\texorpdfstring {\texttt{\color{code}#1}} {#1}}
+\newcommand*\cs [1] {\code{\textbackslash #1}}
+
+\newcommandx*\para [2][2] {%
+ \@ifmtarg{#2}{\para@{#1}{#1}}{\para@{#1}{#2}}}
+\newcommand \para@ [2] {%
+ \par \medskip
+ \hypertarget{para.#2}{}%
+ \belowpdfbookmark{#1}{para.#2}%
+ \noindent
+ \label{para.#2}%
+ \makebox [0pt][r] {%
+ \textsf{\bfseries #1\quad}}%
+ \ignorespaces
+}
+\newcommandx*\pararef [3][1, 3] {%
+ \@ifmtarg{#3}{\para@ref{#1}{#2}{#2}}{\para@ref{#1}{#2}{#3}}}
+\newcommand \para@ref [3] {%
+ \hyperlink{para.#3}{#1{#2}}}
+\newcommand*\parapageref [1] {%
+ \autopagref{para.#1}}
+
+\newcommand \pf {\textsf}
+\newcommand \pk {\pararef[\pf]}
+
+\newcommandx*\pkdesc [6][6] {%
+ \para {#1}
+ \pkditem {Engines} {#3}
+ \pkditem {Formats} {#4}
+ \pkditem {Authors} [\\]{#2}
+ \pkditem {CTAN location} [\\]{#5}[\ctan]
+ \pkditem {Development url} [\\]{#6}[\url]
+ \newline
+}
+\newcommandx*\pkditem [4][2,4] {\@ifnotmtarg{#3}{%
+ #2\textsf{\bfseries #1:} #4{#3}.%
+ }}
+
+
+\newenvironment{myquote}{%
+ \list{}{\leftmargin0pt \rightmargin1em}%
+\item\relax
+ \small
+}{%
+ \endlist
+} \ No newline at end of file
diff --git a/macros/luatex/latex/luamesh/doc/luamesh-doc.listing b/macros/luatex/latex/luamesh/doc/luamesh-doc.listing
new file mode 100644
index 0000000000..e2c890627d
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/luamesh-doc.listing
@@ -0,0 +1,84 @@
+ \documentclass{article}
+ %% lualatex compilation
+ \usepackage[margin=2.5cm]{geometry}
+ \usepackage{luamesh}
+ \usepackage{fontspec}
+ \usepackage{multido}
+ \pagestyle{empty}
+ \def\drawPath{draw (-2,-2)*u--(8,-2)*u--(8,6)*u--(-2,6)*u--cycle withcolor 0.99white;}
+ \def\clipPath{clip currentpicture to (-2,-2)*u--(8,-2)*u--(8,6)*u--(-2,6)*u--cycle;}
+ \begin{document}
+ \drawPointsMeshinc[mode=ext, bbox = show,colorBbox = blue!20,print=points]{mesh.txt}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ }
+ \newpage\buildMeshBWinc[mode=ext,bbox = show,colorBbox = blue!20,print=points]{meshInit.txt}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ }
+ \multido{\ii=5+1}{4}{%
+ \newpage\meshAddPointBWinc[mode=ext,step=badtriangles,colorNew
+ =green!20!red,colorBack=red!10,colorCircle = blue,bbox =
+ show,colorBbox = blue!20]{mesh.txt}{\ii}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ } \newpage
+ \meshAddPointBWinc[mode=ext,step=cavity,colorNew
+ =green!20!red,colorBack=red!10,colorCircle = blue,bbox =
+ show,colorBbox = blue!20]{mesh.txt}{\ii}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ } \newpage
+ \meshAddPointBWinc[mode=ext,step=newtriangles,colorNew
+ =green!20!red,colorBack=red!10,colorCircle = blue,bbox =
+ show,colorBbox = blue!20]{mesh.txt}{\ii}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ }
+ }
+ \newpage
+ \buildMeshBWinc[mode=ext,bbox = show,colorBbox = blue!20,print=points]{mesh.txt}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ }
+ \newpage
+ \buildMeshBWinc[mode=ext,print=points]{mesh.txt}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ }
+\end{document}
diff --git a/macros/luatex/latex/luamesh/doc/luamesh-doc.pdf b/macros/luatex/latex/luamesh/doc/luamesh-doc.pdf
new file mode 100644
index 0000000000..92a1162b9e
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/luamesh-doc.pdf
Binary files differ
diff --git a/macros/luatex/latex/luamesh/doc/luamesh-doc.tex b/macros/luatex/latex/luamesh/doc/luamesh-doc.tex
new file mode 100644
index 0000000000..e2e2bdfc43
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/luamesh-doc.tex
@@ -0,0 +1,1219 @@
+% luamesh: compute and draw meshes with lua, luamplib and tikz
+%
+% Originally written by Maxime Chupin <mc@melusine.eu.org>,
+% 2010.
+%
+% Distributed under the terms of the GNU free documentation licence:
+% http://www.gnu.org/licenses/fdl.html
+% without any invariant section or cover text.
+
+\documentclass{lltxdoc}
+\usepackage{tcolorbox}
+\usepackage{enumitem}
+\usepackage[tikz]{bclogo}
+\usepackage{wrapfig}
+\usepackage{animate}
+
+\title{\Verb+luamesh+: compute and draw meshes with \lualatex}
+\author{Maxime Chupin \email{mc@melusine.eu.org}}
+\date{\today}
+
+
+\definecolor{darkred}{rgb}{0.8,0.1,0.1}
+
+
+\newcommand*\commande{\noindent\hspace{-30pt}%
+ \SaveVerb[aftersave={%
+ \UseVerb{Vitem}
+ }%
+ ]{Vitem}}
+
+\newcommand*\textme[1]{\textcolor{black}{\rmfamily\textit{#1}}}
+\newcommand*\meta[1]{% % meta
+ \textme{\ensuremath{\langle}#1\ensuremath{\rangle}}}
+\newcommand*\optstar{% % optional star
+ \meta{\ensuremath{*}}\xspace}
+\DefineShortVerb{\|}
+\newcommand\R{\mathbf{R}}
+\setlength{\fboxsep}{2pt}
+\fvset{%
+ codes={\catcode`\«\active \catcode`\×\active },
+ defineactive={\makefancyog\makefancytimes},
+ formatcom=\color{darkred},
+ frame=single
+}
+% rendre «...» équivalent à \meta{...}
+{\catcode`\«\active
+ \newcommandx\makefancyog[0][addprefix=\global]{%
+ \def«##1»{\meta{##1}}}}
+% rendre × équivalent à \optstar
+{\catcode`\×\active
+ \newcommandx\makefancytimes[0][addprefix=\global]{%
+ \def×{\optstar{}}}}
+
+
+\tcbuselibrary{listings,breakable}
+
+\definecolor{vert}{rgb}{0.1,0.4,0.1}
+\definecolor{bleu}{rgb}{0.1,0.1,0.4}
+\lstset{
+ numberstyle=\footnotesize\color{vert},
+ keywordstyle=\ttfamily\bfseries\color{blue},
+ basicstyle=\ttfamily\footnotesize,
+ commentstyle=\itshape\color{vert},
+ stringstyle=\ttfamily,
+ showstringspaces=false,
+ language=[LaTeX]TeX,
+ breaklines=true,
+ breakindent=30pt,
+ defaultdialect=[LaTeX]TeX,
+ morekeywords={buildMeshBW,buildMeshBWinc,drawPointsMesh,buildVoronoiBW,buildVoronoiBWinc,
+ drawPointsMeshinc, meshAddPointBW,
+ meshAddPointBWinc,drawGmsh,drawGmshinc,gmshVoronoi,gmshVoronoiinc}% frame=tb
+}
+
+\lstdefinelanguage{lua}
+{morekeywords={for,end,function,do,if,else,elseif,then,
+ tex.print,tex.sprint,io.read,io.open,string.find,string.explode,require},
+ morecomment=[l]{--},
+ morecomment=[s]{--[[}{]]},
+ morestring=[b]''
+}
+
+\newtcblisting{Exemple}{%
+ arc=0pt,outer arc=0pt,
+ colback=red!2!white,
+ colframe=red!75!black,
+ breakable,
+ boxsep=0pt,left=5pt,right=5pt,top=5pt,bottom=5pt, bottomtitle =
+ 3pt, toptitle=3pt,
+ boxrule=0pt,bottomrule=0.5pt,toprule=0.5pt, toprule at break =
+ 0pt, bottomrule at break = 0pt,
+ listing options={breaklines},
+}
+
+\newtcblisting{commandshell}{colback=black,colupper=white,colframe=black,
+ arc=0pt,
+ listing only,boxsep=0pt,listing
+ options={style=tcblatex,language=sh},
+ every listing line={\textcolor{red}{\small\ttfamily\bfseries user \$> }}}
+
+\newtcblisting{latexcode}{
+ arc=0pt,outer arc=0pt,
+ colback=red!2!white,
+ colframe=red!75!black,
+ breakable,
+ boxsep=0pt,left=5pt,right=5pt,top=5pt,bottom=5pt, bottomtitle =
+ 3pt, toptitle=3pt,
+ boxrule=0pt,bottomrule=0.5pt,toprule=0.5pt, toprule at break =
+ 0pt, bottomrule at break = 0pt,
+ listing only,boxsep=0pt,listing
+ options={breaklines}
+}
+
+
+\newcommand\luamesh{\Verb+luamesh+\xspace}
+
+\newenvironment{optionsenum}[1][]
+{\begin{description}[font=\color{darkred}\ttfamily]}
+ {\end{description}}
+
+\newenvironment{warning}{%
+ \setlength{\logowidth}{24pt}
+ \tcbset{%
+ arc=0pt,outer arc=0pt,colback=gray!10!white,colframe=gray!60!white,
+ boxsep=0pt,left=5pt,right=5pt,top=5pt,bottom=5pt, bottomtitle = 3pt, toptitle=3pt,
+ boxrule=0pt,bottomrule=0.5pt,toprule=0.5pt}
+ \medskip
+ \begin{tcolorbox}%
+ \begin{wrapfigure}[2]{L}{17pt}%
+ % \raisebox{-5pt}{
+ \vspace*{-0.55cm}
+ \bcinfo
+ % }%
+ \end{wrapfigure}
+ }%
+ {\end{tcolorbox}\medskip}
+
+\lstset{moredelim=*[s][\color{red}\rmfamily\itshape]{<}{>}}
+\lstset{moredelim=*[s][\color{blue}\rmfamily\itshape]{<<}{>>}}
+\usepackage[colorlinks=true]{hyperref}
+\begin{document}
+%% === Page de garde ===================================================
+\thispagestyle{empty}
+\begin{tikzpicture}[remember picture, overlay]
+ \node[below right, shift={(-4pt,4pt)}] at (current page.north west) {%
+ \includegraphics{fond.pdf}%
+ };
+\end{tikzpicture}%
+
+\noindent
+\includegraphics{luamesh-title}\\
+{\large compute and draw meshes with \lualatex}\\[1cm]
+\parbox{0.6\textwidth}{
+ \meshAddPointBW[
+ mode=ext,step=badtriangles,
+ colorNew =green!20!red,
+ colorBack=red!10,
+ colorCircle = blue,
+ bbox = show,
+ colorBbox = black!30
+ ]
+ {meshgarde.txt}{7}
+}\hfill
+\parbox{0.4\textwidth}{\Large\raggedleft
+ \textbf{Contributor}\\
+ Maxime \textsc{Chupin}
+}
+\vfill
+\begin{center}
+ Version 0.5, 2017, February, 9th \\
+ \url{http://melusine.eu.org/syracuse/G/delaunay/}
+\end{center}
+%% == Page de garde ====================================================
+\newpage
+
+\maketitle
+
+\begin{abstract}
+ The package \Verb|luamesh| allows to compute and draw 2D Delaunay
+ triangulation. The algorithm is written with lua, and depending on the
+ choice of the ``engine'', the drawing is done by MetaPost (with
+ \Verb|luamplib|) or by \Verb|tikz|.
+
+ The Delaunay triangulation algorithm is the Bowyer and Watson
+ algorithm. Several macros are provided to draw the global mesh, the
+ set of points, or a particular step of the algorithm.
+\end{abstract}
+
+I would like to thank Jean-Michel Sarlat, who hosts the development
+with a git project on the \Verb+melusine+ machine:
+\begin{center}
+ \url{https://melusine.eu.org/syracuse/G/delaunay/}
+\end{center}
+I would also like to thank the first user, an intensive
+\emph{test} user, and a very kind English corrector: Nicole Spillane.
+
+\tableofcontents
+
+\section{Installation}
+
+
+Of course, you can just put the two files \Verb+luamesh.lua+ and
+\Verb+luamesh.sty+ in the working directory but this is not
+recommended.
+
+
+\subsection{With \TeX live and Linux or Mac OSX}
+
+To install \luamesh with \TeX live, you have to create the local
+\Verb+texmf+ directory in your \Verb+home+.
+
+\begin{commandshell}
+mkdir ~/texmf
+\end{commandshell}
+
+Then place the files in the correct directories. The
+\Verb+luamesh.sty+ file must be in directory:
+\begin{center}
+ \Verb+~/texmf/tex/latex/luamesh/+
+\end{center}
+and the \Verb+luamesh.lua+, the \Verb+luamesh-tex.lua+ and the
+\Verb-luamesh-polygon.lua+ files must be in directory:
+\begin{center}
+ \Verb+~/texmf/scripts/luamesh/+
+\end{center}
+
+Once you have done this, \luamesh can be included in your document
+with
+\begin{latexcode}
+\usepackage{luamesh}
+\end{latexcode}
+
+\subsection{With Mik\TeX{} and Windows}
+
+As these two systems are unknown to the contributor, we refer to the
+documentation for integrating local additions to Mik\TeX:
+\begin{center}
+ \url{http://docs.miktex.org/manual/localadditions.html}
+\end{center}
+
+
+\subsection{A \lualatex package}
+
+If you want to use this package, you must compile your document with
+\Verb+lualatex+:
+
+\begin{commandshell}
+ lualatex mylatexfile.tex
+\end{commandshell}
+
+
+\subsection{Dependencies}
+
+This package is built upon two main existing packages that one used to
+draw the
+triangulations :
+\begin{enumerate}
+\item \Verb+luamplib+ to use MetaPost via the \luatex library
+ \Verb+mplib+;
+\item \Verb+tikz+.
+\end{enumerate}
+We will see how to choose between these two \emph{drawing engines}.
+Moreover, the following packages are necessary:
+\begin{enumerate}
+\item \Verb+xkeyval+ to manage the optional arguments;
+\item \Verb+xcolor+ to use colors (required by \Verb+luamplib+);
+\item \Verb+ifthen+ to help programming with \TeX.
+\end{enumerate}
+
+
+\section{The Basic Macros}
+
+This package provides macros to draw two
+dimensional triangulations (or meshes).
+
+\subsection{Draw a Complete Mesh}\label{sec:buildMesh}
+
+\commande|\buildMeshBW[«options»]{«list of points» or «file name»}|\medskip
+
+This macro produces the Delaunay triangulation (using the Bowyer and
+Watson algorithm) of the given \meta{list of points}. The list of
+points must be given in the following way :
+\begin{center}
+ \verb+(x1,y1);(x2,y2);(x3,y3);...;(xn,yn)+
+\end{center}
+
+\begin{Exemple}
+ \buildMeshBW{(0.3,0.3);(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5);(2.8,1.5)}
+\end{Exemple}
+
+\subsubsection{The Options}
+
+There are several options to customize the drawing.
+\begin{optionsenum}
+\item[mode = int (default) \textme{or} ext:] this option allows to
+ use either the previously described set of points in the argument, or
+ a file containing the points line by line (in 2 columns). Such a
+ file looks like :
+\begin{verbatim}
+x1 y1
+x2 y2
+x3 y3
+...
+xn yn
+\end{verbatim}
+\item[bbox = none (default) \textme{or} show:] this option allows to draw the
+ points added to form the \emph{bounding box}\footnote{The bounding
+ box is defined by four points place at 15\% around the box
+ defined by $(x_{\min},y_{\min})$, $(x_{\min},y_{\max})$,
+ $(x_{\max},y_{\max})$, and $(x_{\min},y_{\max})$. It is used by
+ the algorithm and will be computed in any case.} and the
+ triangles attached. By default, these triangles are removed at the end of
+ the algorithm.
+\item[color = \meta{value} (default: black):] The color of the
+ drawing.
+\item[colorBbox = \meta{value} (default: black):] The color of the
+ drawing for the elements (points and triangles) belonging to the
+ bounding box.
+\item[print = none (default) \textme{or} points \textme{or}
+ dotpoints:] The \Verb+point+ value allows to label the vertices of the
+ triangulation. This also adds a \emph{dot} at each vertex. The
+ \Verb+dotpoints+ value only add a dot without the labeling.
+\item[meshpoint = \meta{value} (default: P):] The letter(s) used to
+ label the vertices of the triangulation. It is included in the math
+ mode delimiters \Verb+$...$+. The bounding box points are labeled
+ with numbers 1 to 4 and with a star exponent.
+\item[tikz (boolean, default:false):] By default, this boolean is set
+ to \Verb+false+, and MetaPost (with \Verb+luamplib+) is used to draw
+ the picture. With this option, \Verb+tikz+ becomes the \textit{drawing
+ engine}.
+\item[scale = \meta{value} (default: 1cm):] The scale option defines
+ the scale at which the picture is drawn (the same for both
+ axes). It must contain the unit of length (cm,
+ pt, etc.).
+\end{optionsenum}
+
+To illustrate the options, let us show you an example. We consider a
+file \Verb+mesh.txt+:
+\begin{verbatim}
+0.3 0.3
+1.5 1
+4 0
+4.5 2.5
+1.81 2.14
+2.5 0.5
+2.8 1.5
+\end{verbatim}
+\begin{Exemple}
+ \buildMeshBW[%
+ tikz,
+ mode = ext,
+ bbox = show,
+ color = red,
+ colorBbox = blue!30,
+ print = points,
+ meshpoint = x,
+ scale = 1.3cm,
+ ]{mesh.txt}
+\end{Exemple}
+
+\begin{warning}
+The drawing engine is not very relevant here, although it is useful to
+understand how the drawing is produced. However, the engine will be
+relevant to
+the so called \emph{inc} macros (section~\ref{sec:inc}) for adding
+code before and after the one generated by
+\luamesh.
+\end{warning}
+
+\subsection{Draw the Set of Points}
+
+\commande|\drawPointsMesh[«options»]{«list of points» or «file name»}|\medskip
+
+With the \Verb+\drawPointsMesh+, we plot the set of (user chosen) points from
+which the Bowyer and Watson algorithm computes the triangulation.
+
+The use of this macro is quite similar to
+\Verb+\buildMeshBW+. Here is an example of the basic uses.
+\begin{Exemple}
+ \drawPointsMesh{(0.3,0.3);(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5);(2.8,1.5)}
+\end{Exemple}
+
+
+\subsubsection{The Options}
+
+There are several options (exactly the same as for the
+\Verb+\buildMeshBW+) to customize the drawing.
+\begin{optionsenum}
+\item[mode = int (default) \textme{or} ext:] this option allows to
+ use either the previously described set of points as the argument, or
+ a file containing the points line by line (in 2 columns). Such a
+ file looks like :
+\begin{verbatim}
+x1 y1
+x2 y2
+x3 y3
+...
+xn yn
+\end{verbatim}
+\item[bbox = none (default) \textme{or} show:] this option allows to draw the
+ points added to form the \emph{bounding box}\footnote{The bounding
+ box is defined by four points place at 15\% around the box
+ defined by $(x_{\min},y_{\min})$, $(x_{\min},y_{\max})$,
+ $(x_{\max},y_{\max})$, and $(x_{\min},y_{\max})$. It is used by
+ the algorithm and will be computed in any case.} and the
+ triangles attached. By default, these triangles are removed at the end of
+ the algorithm. \emph{Here, because we plot only the vertices of the
+ mesh, there are no triangles, only dots.}
+\item[color = \meta{value} (default: black):] The color of the
+ drawing.
+\item[colorBbox = \meta{value} (default: black):] The color of the
+ drawing for the elements (points and triangles) belonging to the
+ bounding box.
+\item[print = none (default) \textme{or} points:] To label the vertices of the
+ triangulation. This also adds a \emph{dot} at each vertex. With no
+ label, the dot remains.
+\item[meshpoint = \meta{value} (default: P):] The letter(s) used to
+ label the vertices of the triangulation. This is included in the math
+ mode delimiters \Verb+$...$+. The bounding box points are labeled
+ with numbers 1 to 4 and with a star exponent.
+\item[tikz (boolean, default:false):] By default, this boolean is set
+ to \Verb+false+, and MetaPost (with \Verb+luamplib+) is used to draw
+ the picture. With this option, \Verb+tikz+ becomes the \textit{drawing
+ engine}.
+\item[scale = \meta{value} (default: 1cm):] The scale option defines
+ the scale at which the picture is drawn (the same for both
+ axes). It must contain the unit of length (cm,
+ pt, etc.).
+\end{optionsenum}
+With the same external mesh point file presented in
+section~\ref{sec:buildMesh}, we illustrate the different options.
+
+\begin{Exemple}
+ \drawPointsMesh[%
+ tikz,
+ mode = ext,
+ bbox = show,
+ color = blue,
+ colorBbox = red,
+ print = points,
+ meshpoint = y,
+ scale = 1.3cm,
+ ]{mesh.txt}
+\end{Exemple}
+
+
+\subsection{Draw a Step of the Bowyer and Watson Algorithm}
+
+\commande|\meshAddPointBW[«options»]{«list of points» or «file name»}{«point» or «number of line»}|\medskip
+
+This command allows to plot the steps within the addition of a
+point in a Delaunay triangulation by the Bowyer and Watson
+algorithm.
+
+This macro produces the Delaunay triangulation (using the Bowyer and
+Watson algorithm) of the given \meta{list of points} and shows a step
+of the algorithm when the \meta{point} is added. The list of
+points must be given in the following way:
+\begin{center}
+ \verb+(x1,y1);(x2,y2);(x3,y3);...;(xn,yn)+
+\end{center}
+and the point is of the form \verb+(x,y)+. The \meta{file name}
+and \meta{number of line} will be explained in the option
+description.
+
+One can use the macro as follows:
+\begin{Exemple}
+ \meshAddPointBW[step=badtriangles]{(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5);(2.8,1.5)}{(2.2,1.8)}
+ \meshAddPointBW[step=cavity]{(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5);(2.8,1.5)}{(2.2,1.8)}
+ \meshAddPointBW[step=newtriangles]{(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5);(2.8,1.5)}{(2.2,1.8)}
+\end{Exemple}
+The default value for \Verb+step+ is
+\Verb+badtriangles+. Consequently, the first
+line is equivalent to
+\begin{latexcode}
+\meshAddPointBW{(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5);(2.8,1.5)}{(2.2,1.8)}
+\end{latexcode}
+
+\subsubsection{The Options}
+
+There are several options (some of them are the same as for
+\Verb+\buildMeshBW+) to customize the drawing.
+\begin{optionsenum}
+\item[mode = int (default) \textme{or} ext:] this option allows to
+ use either the previously described set of points as the argument, or
+ a file containing the points line by line (in 2 columns). Such a
+ file looks like :
+\begin{verbatim}
+x1 y1
+x2 y2
+x3 y3
+...
+xn yn
+\end{verbatim}
+For the second argument of the macro, if we are in
+\Verb+mode = ext+, the argument must be the \emph{line number} of the file
+corresponding to the point we want to add. The algorithm will stop at the
+previous line to build the initial triangulation and proceed to add
+the point corresponding to the line requested. The subsequent lines in
+the file are
+ignored.
+\item[bbox = none (default) \textme{or} show:] this option allows to draw the
+ added points that form the \emph{bounding box} and the triangles
+ attached. Although they are always computed, by default, these
+ triangles are removed at the end of
+ the algorithm.
+\item[color = \meta{value} (default: black):] The color of the
+ drawing.
+\item[colorBbox = \meta{value} (default: black):] The color of the
+ drawing for the elements (points and triangles) belonging to the
+ bounding box.
+\item[colorNew = \meta{value} (default: red):] The color of the
+ drawing of the ``new'' elements which are the point to add, the
+ polygon delimiting the cavity, and the new triangles.
+\item[colorBack = \meta{value} (default: black!20):] The color for the
+ filling of the region concerned by the addition of the new point.
+\item[colorCircle = \meta{value} (default: green):] The color for
+ the circumcircle of the triangles containing the point to add.
+\item[meshpoint = \meta{value} (default: P):] The letter(s) used to
+ label the vertices of the triangulation. It is included in the math
+ mode delimiters \Verb+$...$+. The bounding box points are labeled
+ with numbers 1 to 4 and with a star exponent.
+\item[step = badtriangles (default) \textme{or} cavity \textme{or}
+ newtriangles:] To choose the step we want to draw, corresponding to
+ the steps of the Bowyer and Watson algorithm.
+\item[newpoint = \meta{value} (default: P):] The letter(s) used to
+ label the new point of the triangulation. It is include in the math
+ mode delimiters \Verb+$...$+.
+\item[tikz (boolean, default:false):] By default, this boolean is set
+ to \Verb+false+, and MetaPost (with \Verb+luamplib+) is used to draw
+ the picture. With this option, \Verb+tikz+ is the \textit{drawing
+ engine}.
+\item[scale = \meta{value} (default: 1cm):] The scale option defines
+ the scale at which the picture is drawn (the same for both
+ axis). It must contain the unit of length (cm,
+ pt, etc.).
+\end{optionsenum}
+
+Here is an example of customizing the drawing. First, recall that
+the external file \Verb+mesh.txt+ is:
+\begin{verbatim}
+0.3 0.3
+1.5 1
+4 0
+4.5 2.5
+1.81 2.14
+2.5 0.5
+2.8 1.5
+\end{verbatim}
+We draw the addition of the 6th point. The 7th line will be ignored.
+\begin{Exemple}
+ \meshAddPointBW[
+ tikz,
+ mode = ext,
+ color = blue!70,
+ meshpoint = \alpha,
+ newpoint = y,
+ colorBack=red!10,
+ colorNew = green!50!red,
+ colorCircle = blue,
+ colorBbox = black!20,
+ bbox = show,
+ scale=1.4cm,
+ step=badtriangles]
+ {mesh.txt}{6}
+\end{Exemple}
+
+\subsection{Mesh a Polygon}
+
+\commande|\meshPolygon[«options»]{«list of points» or «file name»}|\medskip
+
+
+With \luamesh, it is possible to mesh an object giving the
+\emph{border}, \emph{i.e.}, one closed polygon. The polygon is given
+as a list of points as above:
+\begin{center}
+ \verb+(x1,y1);(x2,y2);(x3,y3);...;(xn,yn)+
+\end{center}
+Once again we can also give a file of points using the \Verb+mode+
+option.
+
+This command allows to plot the steps within the building of a complete
+mesh. The followed method is, given a parameter $h$:
+\begin{itemize}
+\item to build a squared grid of points with a unit distance equal to
+ $h$;
+\item to keep the grid points inside the polygon;
+\item if necessary to add points along the polygon to respect the
+ distance parameter;
+\item to mesh the complete set of points (using the Bowyer and Watson
+ algorithm).
+\end{itemize}
+
+One can use the macro as follows:
+\begin{Exemple}
+ \meshPolygon[step=polygon,scale=2cm]{(0,0);(1,0);(1,0.5);(0,0.5);(-0.20,0.35);(-0.25,0.25);(-0.20,0.15)}
+ \meshPolygon[step=grid,scale=2cm]{(0,0);(1,0);(1,0.5);(0,0.5);(-0.20,0.35);(-0.25,0.25);(-0.20,0.15)}
+ \meshPolygon[step=points,scale=2cm]{(0,0);(1,0);(1,0.5);(0,0.5);(-0.20,0.35);(-0.25,0.25);(-0.20,0.15)}
+ \meshPolygon[step=mesh,scale=2cm]{(0,0);(1,0);(1,0.5);(0,0.5);(-0.20,0.35);(-0.25,0.25);(-0.20,0.15)}
+\end{Exemple}
+
+Note that if the points of the grid are too closed to the points of
+the refined boundary, they are ejected.
+
+\subsubsection{The Options}
+
+There are several options (some of them are the same as for
+\Verb+\buildMeshBW+) to customize the drawing.
+\begin{optionsenum}
+\item[mode = int (default) \textme{or} ext:] this option allows to
+ use either the previously described set of points as the argument, or
+ a file containing the points line by line (in 2 columns). Such a
+ file looks like :
+\begin{verbatim}
+x1 y1
+x2 y2
+x3 y3
+...
+xn yn
+\end{verbatim}
+\item[h = \meta{value} (default: 0.2):] The mesh parameter, it is the
+ unit distance for the grid. If necessary, the boundary is refined to
+ get points which respect the distance constrain.
+\item[color = \meta{value} (default: black):] The color of the
+ drawing (the grid point and the mesh).
+\item[colorPolygon = \meta{value} (default: red):] The color of the
+ drawing for the boundary polygon.
+\item[print = none (default) \textme{or} points \textme{or}
+ dotpoints:] The \Verb+point+ value allows to label the vertices of the
+ triangulation. This also adds a \emph{dot} at each vertex. The
+ \Verb+dotpoints+ value only add a dot without the labeling.
+\item[meshpoint = \meta{value} (default: P):] The letter(s) used to
+ label the vertices of the triangulation. It is included in the math
+ mode delimiters \Verb+$...$+.
+\item[step = polygon \textme{or} grid \textme{or}
+ points \textme{or} mesh (default):] To choose the step we want to draw,
+ see the description above.
+\item[tikz (boolean, default:false):] By default, this boolean is set
+ to \Verb+false+, and MetaPost (with \Verb+luamplib+) is used to draw
+ the picture. With this option, \Verb+tikz+ is the \textit{drawing
+ engine}.
+\item[scale = \meta{value} (default: 1cm):] The scale option defines
+ the scale at which the picture is drawn (the same for both
+ axis). It must contain the unit of length (cm,
+ pt, etc.).
+\item[gridpoints = rect (default) \textme{or} perturb:] This option
+ allows to specify the mode of generation of the grid points. The
+ value \Verb+rect+ produces a simple rectangular grid, and the value
+ \Verb+pertub+ randomly perturbs the rectangular grid.
+\end{optionsenum}
+
+Here is an example of customizing the drawing.
+\begin{Exemple}
+ \meshPolygon[
+ tikz,
+ color = blue!70,
+ meshpoint = \alpha,
+ colorPolygon=red!120,
+ scale=4cm,
+ step=mesh,
+ print=points,
+ gridpoints=perturb]
+ {(0,0);(1,0);(1,0.5);(0,0.5);(-0.20,0.35);(-0.25,0.25);(-0.20,0.15)}
+\end{Exemple}
+
+
+\section{The \emph{inc} Macros}\label{sec:inc}
+
+The three macros presented in the above sections have complementary
+macros, with the suffix \Verb+inc+ that allow the user to add code
+(MetaPost or \Verb+tikz+, depending of the drawing engine) before and
+after the code generated by \luamesh.
+
+The three macros are:\medskip
+
+
+\commande|\buildMeshBWinc[«options»]{«list of points» or «file name»}{«code before»}{«code after»}|\medskip
+
+\commande|\drawPointsMeshinc[«options»]{«list of points» or «file name»}{«code before»}{«code after»}|\medskip
+
+\commande|\meshAddPointBWinc[«options»]{«list of points» or «file name»}%|
+
+\commande| {«point» or «number of line»}{«code before»}{«code after»}|\medskip
+
+\subsection{With MetaPost}
+
+We consider the case where the drawing engine is MetaPost (through the
+\Verb+luamplib+ package).
+
+The feature is described for the \Verb+\buildMeshBWinc+ but the mechanism
+and possibilities are exactly the same for all three macros.
+
+When we use the MetaPost drawing engine, the macros previously
+described produce a code of the form
+\begin{latexcode}
+\begin{luamplib}
+ u:=<scale>;
+ beginfig(0);
+ <code for the drawing>
+ endfig;
+\end{luamplib}
+\end{latexcode}
+
+Then, the arguments \meta{code before} and \meta{code after} are
+inserted as follows:
+\begin{latexcode}
+\begin{luamplib}
+ u:=<scale>;
+ <<code before>>
+ <code for the drawing>
+ <<code after>>
+\end{luamplib}
+\end{latexcode}
+\begin{warning}
+With the \emph{inc} macros, the user has to add the \Verb+beginfig();+
+and \Verb+endfig;+ commands to produce a picture. Indeed, this allows
+to use the \Verb+\everymplib+ command from the \Verb+\luamplib+ package.
+\end{warning}
+
+\subsubsection{The \LaTeX{} Colors Inside the MetaPost Code}\label{sec:mpcolor}
+
+The configurable colors
+of the \LaTeX{} macro are accessible inside the MetaPost code. For
+\Verb+\buildMeshBWinc+ and \Verb+\drawPointsMeshinc+,
+\Verb+\luameshmpcolor+,
+and \Verb+\luameshmpcolorBbox+ have been defined.
+For the macro \Verb+\meshAddPointBWinc+ three additional
+colors are present: \Verb+\luameshmpcolorBack+,
+\Verb+\luameshmpcolorNew+, and
+\Verb+\luameshmpcolorCircle+. For the macro \Verb+\meshPolygon+, the
+color \Verb+\luameshmpcolorPoly+ is defined. Of course, MetaPost
+colors can be defined as well. Finally, the \Verb+luamplib+ mechanism
+\Verb+\mpcolor+ is also available.
+
+\subsubsection{The Mesh Points}
+
+At the beginning of the automatically generated code, a list of
+MetaPost \Verb+pair+s are defined corresponding to all the vertices in
+the mesh (when the option \Verb+bbox=show+, the last 4 points are the
+\emph{bounding box points}). The points are available with the
+\Verb+MeshPoints[]+ table of variables. The \Verb+pair+s ($\R^{2}$ points)
+\Verb+MeshPoints[i]+ are
+defined using the unit length \Verb+u+.
+
+With the \Verb+\meshPolygon+ macro, we have the points of the polygon
+(refined) that are available with the
+\Verb+polygon[]+ table of variables.
+
+\subsubsection{Examples}
+
+Here is three examples for the different macros.
+\begin{Exemple}
+\drawPointsMeshinc[
+color = blue!50,
+print = points,
+meshpoint = x,
+scale=0.8cm,
+]{(0.3,0.3);(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5);(2.8,1.5)}%
+{% code before
+ beginfig(0);
+}%
+{% code after
+ label(btex Mesh $\mathbb{T}$ etex, (0,2u)) withcolor \luameshmpcolor;
+ endfig;
+}
+\buildMeshBWinc[%
+bbox = show,
+color = red,
+colorBbox = blue!30,
+print = points,
+meshpoint = x,
+scale=0.8cm
+]{(0.3,0.3);(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5);(2.8,1.5)}%
+{% code before
+ beginfig(0);
+}
+{% code after
+ drawdblarrow MeshPoints[3] -- MeshPoints[9] withpen pencircle scaled 1pt
+ withcolor (0.3,0.7,0.2);
+ endfig;
+}
+\meshAddPointBWinc[
+meshpoint = \alpha,
+newpoint = y,
+colorBack=red!10,
+colorNew = green!50!red,
+colorCircle = blue,
+colorBbox = black!20,
+bbox = show,
+scale=0.8cm,
+step=badtriangles]
+{(0.3,0.3);(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5)}{(2.8,1.5)}%
+{%code before
+ picture drawing;
+ drawing := image(
+}{%code after
+ );
+ beginfig(0);
+ fill MeshPoints[7]--MeshPoints[8]--MeshPoints[9]--MeshPoints[10]--cycle
+ withcolor \mpcolor{blue!10};
+ draw drawing;
+ endfig;
+}
+\end{Exemple}
+\begin{warning}
+ The variables \Verb+MeshPoints[]+ are not defined for the argument
+ corresponding to the code placed \textbf{before} the code generated by
+ \luamesh. Hence, to use such variables, we have to define a
+ \Verb+picture+ as shown in the third example above.
+\end{warning}
+
+
+\subsection{With TikZ}
+
+If we have chosen \Verb+tikz+ as the drawing engine, the added code
+will be written in \Verb+tikz+. In that case, the two arguments
+\meta{code before} and \meta{code after} will be inserted as follows:
+\begin{latexcode}
+\noindent
+\begin{tikzpicture}[x=<scale>,y=<scale>]
+ <<code before>>
+ <generated code>
+ <<code after>>
+\end{tikzpicture}
+\end{latexcode}
+
+Because the engine is \Verb+tikz+ their is no issue with colors, the
+\LaTeX{} colors (e.g.: \Verb+xcolor+) can be used directly.
+
+\subsubsection{The Mesh Points}
+
+The mesh points are defined here as \Verb+tikz+
+\Verb+\coordinate+ and named as follows
+\begin{latexcode}
+\coordinate (MeshPoints1) at (...,...);
+\coordinate (MeshPoints2) at (...,...);
+\coordinate (MeshPoints3) at (...,...);
+%etc.
+\end{latexcode}
+
+With the \Verb+\meshPolygon+ we have also the polygon points coordinates:
+\begin{latexcode}
+\coordinate (polygon1) at (...,...);
+%etc.
+\end{latexcode}
+
+Once again these coordinates are not yet defined to be used in the
+code given by \meta{code
+ before} argument.
+
+\subsubsection{Examples}
+
+\begin{Exemple}
+ \drawPointsMeshinc[
+ tikz,
+ color = blue!50,
+ print = points,
+ meshpoint = x,
+ scale=0.8cm,
+ ]{(0.3,0.3);(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5);(2.8,1.5)}%
+ {% code before
+ }%
+ {% code after
+ \node[color = blue!50] at (0,2) {Mesh $\mathbb{T}$} ;
+ }
+ \buildMeshBWinc[%
+ tikz,
+ bbox = show,
+ color = red,
+ colorBbox = blue!30,
+ print = points,
+ meshpoint = x,
+ scale=0.8cm
+ ]{(0.3,0.3);(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5);(2.8,1.5)}%
+ {% code before
+ }
+ {% code after
+ \draw[<->,thick, color=green] (MeshPoints3) -- (MeshPoints9);
+ }
+\end{Exemple}
+
+\section{Voronoï Diagrams}
+
+Another interesting feature of b Delaunay triangulation is that its
+\emph{dual} is the so-called Voronoï diagram. More precisely, for a
+finite set of
+points $\{p_{1},\ldots, p_{n}\}$ in the Euclidean plane, the Voronoï
+cell $R_{k}$ corresponding to $p_{k}$ is the set of
+all points in the Euclidean plane $\R^{2}$ whose distance to $p_{k}$ is less
+than
+or equal to its distance to any other $p_{k'}$.\bigskip
+
+
+\commande|\buildVoronoiBW[«options»]{«list of points» or «file name»}|\medskip
+
+This macro produce the Voronoï diagram of the given \meta{list of
+ points}. Once again, the
+list of
+points must be given in the following way :
+\begin{center}
+ \verb+(x1,y1);(x2,y2);(x3,y3);...;(xn,yn)+
+\end{center}
+
+\begin{Exemple}
+ \buildVoronoiBW{(0.3,0.3);(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5);(2.8,1.5);(0.1,2);(1.5,-0.3)}
+\end{Exemple}
+
+\subsection{The Options}\label{sec:voronoiOptions}
+
+
+There are several options to customize the drawing.
+\begin{optionsenum}
+\item[mode = int (default) \textme{or} ext:] this option allows to
+ use either the previously described set of points in the argument, or
+ a file containing the points line by line (in 2 columns). Such a
+ file looks like :
+\begin{verbatim}
+x1 y1
+x2 y2
+x3 y3
+...
+xn yn
+\end{verbatim}
+\item[bbox = none (default) \textme{or} show:] this option allows to draw the
+ added points to form a \emph{bounding box}\footnote{The bounding
+ box is defined by four points place at 15\% around the box
+ defined by $(x_{\min},y_{\min})$, $(x_{\min},y_{\max})$,
+ $(x_{\max},y_{\max})$, and $(x_{\min},y_{\max})$. It is used by
+ the algorithm and will be computed in any case.} and the corresponding
+ triangulation. By default, these points are removed at the end of
+ the algorithm.
+\item[color = \meta{value} (default: black):] The color of the
+ drawing.
+\item[colorBbox = \meta{value} (default: black):] The color of the
+ drawing for the elements (points and triangles) belonging to the
+ bounding box.
+\item[colorVoronoi = \meta{value} (default: black):] The color of the
+ drawing for the elements (points and polygons) belonging to the
+ Voronoï diagram.
+\item[print = none (default) \textme{or} points:] To label the
+ vertices in the
+ triangulation. Contrary to the previous macros, where
+ \Verb+print=none+, a \emph{dot} is produced at each vertex of the
+ set of points and at the circumcircle centers which are the nodes of
+ the Voronoï diagram.
+\item[meshpoint = \meta{value} (default: P):] The letter(s) used to
+ label the vertices of the triangulation. This is included in the math
+ mode delimiters \Verb+$...$+. The bounding box points are labelled
+ with numbers 1 to 4 and with a star exponent.
+\item[circumpoint = \meta{value} (default: P):] The letter(s) used to
+ label the vertices of the Voronoï diagram. This is included in the math
+ mode delimiters \Verb+$...$+.
+\item[tikz (boolean, default:false):] By default, this boolean is set
+ to \Verb+false+, and MetaPost (with \Verb+luamplib+) is used to draw
+ the picture. With this option, \Verb+tikz+ becomes the \textit{drawing
+ engine}.
+\item[scale = \meta{value} (default: 1cm):] The scale option defines
+ the scale at which the picture is drawn (the same for both
+ axes). It must contain the unit of length (cm,
+ pt, etc.).
+\item[delaunay = none (default) \textme{or} show:] This option
+ allows to draw the Delaunay triangulation under the Voronoï diagram.
+\item[styleDelaunay = none (default) \textme{or} dashed:] This option
+ allows to draw the Delaunay triangulation in dashed lines.
+\item[styleVoronoi = none (default) \textme{or} dashed:] This option
+ allows to draw the Voronoï edges in dashed lines.
+\end{optionsenum}
+
+\begin{Exemple}
+ \buildVoronoiBW[tikz,delaunay=show,styleDelaunay=dashed]
+ {(0.3,0.3);(1.5,1);(4,0);(4.5,2.5);(1.81,2.14);(2.5,0.5);(2.8,1.5);(0.1,2);(1.5,-0.3)}
+\end{Exemple}
+
+\subsection{The \emph{inc} variant}
+
+Once again, a variant of the macros is available allowing the user to
+add code before and after the code produced by \luamesh. We refer to
+section~\ref{sec:inc} because it works the same way.
+
+Let us note that:
+\begin{itemize}
+\item with MetaPost, the circumcenters are defined using
+ \Verb+pair CircumPoints[];+ and so they are accessible.
+\item With \Verb+tikz+, there are new coordinates defined as follows
+ \begin{latexcode}
+ \coordinate (CircumPoints1) at (...,...);
+ \coordinate (CircumPoints2) at (...,...);
+ \coordinate (CircumPoints3) at (...,...);
+ % etc.
+ \end{latexcode}
+\end{itemize}
+
+Finally, when the MetaPost drawing engine is used another color is
+available (see~\ref{sec:mpcolor}): \Verb+\luameshmpcolorVoronoi+.
+
+\section{With Gmsh}
+
+Gmsh is an open source efficient software that produces meshes. The
+exporting format is the \emph{MSH ASCII file format} and can be easily
+read by a Lua program. \luamesh provides the user with dedicated
+macros to read and draw meshes coming from a Gmsh exportation.\bigskip
+
+\commande|\drawGmsh[«options»]{«file name»}|\medskip
+
+This macro draws the triangulation produced by Gmsh and exported in the
+\Verb+msh+ format. The argument is the name of the file to be read
+(e.g.: \Verb+maillage.msh+).
+
+\begin{Exemple}
+\drawGmsh{maillage.msh}
+\end{Exemple}
+
+There are several options to customize the drawing.
+\begin{optionsenum}
+\item[color = \meta{value} (default: black):] The color of the
+ drawing.
+\item[print = none (default) \textme{or} points:] To label the vertices of the
+ triangulation. Contrary to some previous macros, when
+ \Verb+print=none+ a \emph{dot} is produced at each vertex of the
+ set of points and at the circumcircle centers (these are the nodes of
+ the Voronoï diagram).
+\item[meshpoint = \meta{value} (default: P):] The letter(s) used to
+ label the vertices of the triangulation. This is included in the math
+ mode delimiters \Verb+$...$+. The bounding box points are labeled
+ with numbers 1 to 4 and with a star exponent.
+\item[tikz (boolean, default:false):] By default, this boolean is set
+ to \Verb+false+, and MetaPost (with \Verb+luamplib+) is used to draw
+ the picture. With this option, \Verb+tikz+ becomes the \textit{drawing
+ engine}.
+\item[scale = \meta{value} (default: 1cm):] The scale option defines
+ the scale at which the picture is drawn (the same for both
+ axes). It must contain the unit of length (cm,
+ pt, etc.).
+\end{optionsenum}
+Here is an example:
+\begin{Exemple}
+ \drawGmsh[scale=2cm,print=points, color=blue!30]{maillage.msh}
+\end{Exemple}
+
+\subsection{Gmsh and Voronoï Diagrams}
+
+Because Gmsh generates Delaunay triangulations, we can plot the associated
+Voronoï diagram. This is done by the following macro:\bigskip
+
+\commande|\gmshVoronoi[«options»]{«file name»}|\medskip
+
+\begin{Exemple}
+ \gmshVoronoi{maillage.msh}
+\end{Exemple}
+
+
+\subsection{The Options}\label{sec:voronoiOptions}
+
+
+There are several options to customize the drawing.
+\begin{optionsenum}
+\item[color = \meta{value} (default: black):] The color of the
+ drawing.
+\item[colorVoronoi = \meta{value} (default: black):] The color of the
+ drawing for the elements (points and polygons) belonging to the
+ Voronoï diagram.
+\item[print = none (default) \textme{or} points:] To label the vertices of the
+ triangulation. Contrary to some previous macros, when
+ \Verb+print=none+, a \emph{dot} is produced at each vertex of the
+ set of points and at the circumcircle centers (these are the nodes of
+ the Voronoï diagram).
+\item[meshpoint = \meta{value} (default: P):] The letter(s) used to
+ label the vertices of the triangulation. It is included in the math
+ mode delimiters \Verb+$...$+. The bounding box points are labeled
+ with numbers 1 to 4 and with a star exponent.
+\item[circumpoint = \meta{value} (default: P):] The letter(s) used to
+ label the vertices of the Voronoï diagram. This is included in the math
+ mode delimiters \Verb+$...$+.
+\item[tikz (boolean, default:false):] By default, this boolean is set
+ to \Verb+false+, and MetaPost (with \Verb+luamplib+) is used to draw
+ the picture. With this option, \Verb+tikz+ becomes the \textit{drawing
+ engine}.
+\item[scale = \meta{value} (default: 1cm):] The scale option defines
+ the scale at which the picture is drawn (the same for both
+ axes). It must contain the unit of length (cm,
+ pt, etc.).
+\item[delaunay = none (default) \textme{or} show] This option
+ allows to draw the Delaunay triangulation overlapped with the
+ Voronoï diagram.
+\item[styleDelaunay = none (default) \textme{or} dashed] This option
+ allows to draw the Delaunay triangulation in dashed lines.
+\item[styleVoronoi = none (default) \textme{or} dashed] This option
+ allows to draw the Voronoï edges in dashed lines.
+\end{optionsenum}
+
+\begin{Exemple}
+ \gmshVoronoi[tikz,scale=1.5cm, delaunay=show,styleVoronoi=dashed]{maillage.msh}
+\end{Exemple}
+
+
+\subsection{The \emph{inc} variants}
+
+Once again, there exist \emph{inc} variant macros:\bigskip
+
+\commande|\drawGmshinc[«options»]{«file name»}{«code before»}{«code after»}|\medskip
+
+\commande|\gmshVoronoiinc[«options»]{«file name»}{«code before»}{«code after»}|\medskip
+
+We refer to the previous sections for explanations.
+
+
+
+\section{Gallery}
+\subsection{With Animate}
+
+If you use \emph{Adobe Acrobat reader}, you can easily produce an
+animation of the Bowyer and Watson algorithm with the package
+\Verb+animate+.
+
+For example, the following code (in a file name \Verb+animation.tex+):
+\begin{latexcode}
+ \documentclass{article}
+ %% lualatex compilation
+ \usepackage[margin=2.5cm]{geometry}
+ \usepackage{luamesh}
+ \usepackage{fontspec}
+ \usepackage{multido}
+ \pagestyle{empty}
+ \def\drawPath{draw (-2,-2)*u--(8,-2)*u--(8,6)*u--(-2,6)*u--cycle withcolor 0.99white;}
+ \def\clipPath{clip currentpicture to (-2,-2)*u--(8,-2)*u--(8,6)*u--(-2,6)*u--cycle;}
+ \begin{document}
+ \drawPointsMeshinc[mode=ext, bbox = show,colorBbox = blue!20,print=points]{mesh.txt}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ }
+ \newpage\buildMeshBWinc[mode=ext,bbox = show,colorBbox = blue!20,print=points]{meshInit.txt}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ }
+ \multido{\ii=5+1}{4}{%
+ \newpage\meshAddPointBWinc[mode=ext,step=badtriangles,colorNew
+ =green!20!red,colorBack=red!10,colorCircle = blue,bbox =
+ show,colorBbox = blue!20]{mesh.txt}{\ii}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ } \newpage
+ \meshAddPointBWinc[mode=ext,step=cavity,colorNew
+ =green!20!red,colorBack=red!10,colorCircle = blue,bbox =
+ show,colorBbox = blue!20]{mesh.txt}{\ii}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ } \newpage
+ \meshAddPointBWinc[mode=ext,step=newtriangles,colorNew
+ =green!20!red,colorBack=red!10,colorCircle = blue,bbox =
+ show,colorBbox = blue!20]{mesh.txt}{\ii}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ }
+ }
+ \newpage
+ \buildMeshBWinc[mode=ext,bbox = show,colorBbox = blue!20,print=points]{mesh.txt}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ }
+ \newpage
+ \buildMeshBWinc[mode=ext,print=points]{mesh.txt}%
+ {%
+ beginfig(0);
+ \drawPath
+ }%
+ {%
+ \clipPath
+ endfig;
+ }
+\end{document}
+\end{latexcode}
+produces a PDF with multiple pages. Using the \Verb+pdfcrop+ program,
+we crop the pages to the material, and then we can animate the PDF
+using the \Verb+animate+ package.
+
+%\begin{Exemple}
+%\animategraphics[controls]{1}{animation-crop}{}{}
+%\end{Exemple}
+
+\input{dum.bbl}
+
+\end{document}
+
+
+
+%%% Local Variables:
+%%% flyspell-mode: 1
+%%% ispell-local-dictionary: "american"
+%%% End:
diff --git a/macros/luatex/latex/luamesh/doc/luamesh-title.pdf b/macros/luatex/latex/luamesh/doc/luamesh-title.pdf
new file mode 100644
index 0000000000..f352340ce2
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/luamesh-title.pdf
Binary files differ
diff --git a/macros/luatex/latex/luamesh/doc/maillage.geo b/macros/luatex/latex/luamesh/doc/maillage.geo
new file mode 100644
index 0000000000..ca0961535e
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/maillage.geo
@@ -0,0 +1,9 @@
+// Gmsh project created on Tue Nov 29 22:45:35 2016
+Point(1) = {0, 0, 0, .5};
+Point(2) = {3, 0, 0, .5};
+Point(3) = {0, 3, 0, .5};
+Circle(1) = {3, 1, 2};
+Line(2) = {1, 3};
+Line(3) = {2, 1};
+Line Loop (1) = {1,3,2};
+Plane Surface (6) = {1};
diff --git a/macros/luatex/latex/luamesh/doc/maillage.msh b/macros/luatex/latex/luamesh/doc/maillage.msh
new file mode 100644
index 0000000000..39a88023d0
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/maillage.msh
@@ -0,0 +1,160 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+50
+1 0 0 0
+2 3 0 0
+3 0 3 0
+4 0.4693033951192702 2.963065021785638 0
+5 0.9270509831224205 2.853169548886248 0
+6 1.361971499215402 2.673019572566753 0
+7 1.763355756873741 2.427050983127515 0
+8 2.121320343555531 2.121320343563755 0
+9 2.427050983122084 1.763355756881216 0
+10 2.673019572563731 1.361971499221335 0
+11 2.853169548884875 0.9270509831266447 0
+12 2.963065021785299 0.4693033951214145 0
+13 0 0.499999999997822 0
+14 0 0.9999999999960245 0
+15 0 1.499999999994285 0
+16 0 1.999999999996158 0
+17 0 2.499999999998079 0
+18 2.500000000003167 0 0
+19 2.000000000001941 0 0
+20 1.500000000004168 0 0
+21 1.00000000000281 0 0
+22 0.5000000000014051 0 0
+23 1.234141133439995 1.234706476168725 0
+24 2.019011585984451 0.8482511421012229 0
+25 0.7996467420535595 2.004579558507475 0
+26 0.7193791167395813 0.7231883013413306 0
+27 1.519111484662544 1.840362994240276 0
+28 1.444230772066577 0.6206006444007433 0
+29 0.6032715654033697 1.482446070099814 0
+30 1.967205997854255 1.422470442749536 0
+31 2.483520846404239 0.5934345676487791 0
+32 0.5639644981111984 2.469590570556198 0
+33 1.323592795170413 2.162102387974417 0
+34 2.468934320532775 1.014872883347498 0
+35 1.818185974210566 0.4238910154260575 0
+36 0.3947241723756524 1.821731472036314 0
+37 1.134164055943625 1.659777451599567 0
+38 1.613471831330844 1.104183945170989 0
+39 0.9806274474984064 2.435458768712165 0
+40 0.4081594929391452 1.008296761660148 0
+41 1.00688752284509 0.4118199261386256 0
+42 0.439071022087537 0.4405508315229876 0
+43 1.118714369352139 0.8621581647343061 0
+44 1.923763789491919 1.798468600466841 0
+45 2.313447213716825 1.312293020670456 0
+46 1.529398659496223 1.467534627005675 0
+47 0.8456544688053689 1.137388163063763 0
+48 1.73022883395083 2.069861061874561 0
+49 2.160830764549087 0.3569017273154402 0
+50 0.3343775807151865 2.155932068334013 0
+$EndNodes
+$Elements
+101
+1 15 2 0 1 1
+2 15 2 0 2 2
+3 15 2 0 3 3
+4 1 2 0 1 3 4
+5 1 2 0 1 4 5
+6 1 2 0 1 5 6
+7 1 2 0 1 6 7
+8 1 2 0 1 7 8
+9 1 2 0 1 8 9
+10 1 2 0 1 9 10
+11 1 2 0 1 10 11
+12 1 2 0 1 11 12
+13 1 2 0 1 12 2
+14 1 2 0 2 1 13
+15 1 2 0 2 13 14
+16 1 2 0 2 14 15
+17 1 2 0 2 15 16
+18 1 2 0 2 16 17
+19 1 2 0 2 17 3
+20 1 2 0 3 2 18
+21 1 2 0 3 18 19
+22 1 2 0 3 19 20
+23 1 2 0 3 20 21
+24 1 2 0 3 21 22
+25 1 2 0 3 22 1
+26 2 2 0 6 12 18 31
+27 2 2 0 6 4 32 17
+28 2 2 0 6 47 37 23
+29 2 2 0 6 29 37 47
+30 2 2 0 6 13 40 42
+31 2 2 0 6 22 42 41
+32 2 2 0 6 17 3 4
+33 2 2 0 6 18 12 2
+34 2 2 0 6 13 14 40
+35 2 2 0 6 21 22 41
+36 2 2 0 6 20 41 28
+37 2 2 0 6 15 29 40
+38 2 2 0 6 25 37 29
+39 2 2 0 6 24 28 38
+40 2 2 0 6 28 43 38
+41 2 2 0 6 23 38 43
+42 2 2 0 6 20 28 35
+43 2 2 0 6 15 36 29
+44 2 2 0 6 11 12 31
+45 2 2 0 6 4 5 32
+46 2 2 0 6 24 35 28
+47 2 2 0 6 25 29 36
+48 2 2 0 6 20 21 41
+49 2 2 0 6 14 15 40
+50 2 2 0 6 24 30 45
+51 2 2 0 6 26 42 40
+52 2 2 0 6 26 41 42
+53 2 2 0 6 11 31 34
+54 2 2 0 6 24 45 34
+55 2 2 0 6 9 30 44
+56 2 2 0 6 6 7 33
+57 2 2 0 6 5 39 32
+58 2 2 0 6 27 37 33
+59 2 2 0 6 9 45 30
+60 2 2 0 6 25 33 37
+61 2 2 0 6 24 38 30
+62 2 2 0 6 1 13 42
+63 2 2 0 6 1 42 22
+64 2 2 0 6 24 31 49
+65 2 2 0 6 25 50 32
+66 2 2 0 6 24 34 31
+67 2 2 0 6 15 16 36
+68 2 2 0 6 19 20 35
+69 2 2 0 6 25 32 39
+70 2 2 0 6 7 48 33
+71 2 2 0 6 24 49 35
+72 2 2 0 6 25 36 50
+73 2 2 0 6 30 46 44
+74 2 2 0 6 8 9 44
+75 2 2 0 6 27 44 46
+76 2 2 0 6 5 6 39
+77 2 2 0 6 6 33 39
+78 2 2 0 6 18 49 31
+79 2 2 0 6 17 32 50
+80 2 2 0 6 10 11 34
+81 2 2 0 6 25 39 33
+82 2 2 0 6 27 33 48
+83 2 2 0 6 18 19 49
+84 2 2 0 6 16 17 50
+85 2 2 0 6 9 10 45
+86 2 2 0 6 7 8 48
+87 2 2 0 6 30 38 46
+88 2 2 0 6 23 43 47
+89 2 2 0 6 27 46 37
+90 2 2 0 6 28 41 43
+91 2 2 0 6 26 43 41
+92 2 2 0 6 23 37 46
+93 2 2 0 6 10 34 45
+94 2 2 0 6 19 35 49
+95 2 2 0 6 16 50 36
+96 2 2 0 6 23 46 38
+97 2 2 0 6 26 40 47
+98 2 2 0 6 29 47 40
+99 2 2 0 6 8 44 48
+100 2 2 0 6 26 47 43
+101 2 2 0 6 27 48 44
+$EndElements
diff --git a/macros/luatex/latex/luamesh/doc/mesh.txt b/macros/luatex/latex/luamesh/doc/mesh.txt
new file mode 100644
index 0000000000..37b6920f88
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/mesh.txt
@@ -0,0 +1,7 @@
+0.3 0.3
+1.5 1
+4 0
+4.5 2.5
+1.81 2.14
+2.5 0.5
+2.8 1.5
diff --git a/macros/luatex/latex/luamesh/doc/meshgarde.txt b/macros/luatex/latex/luamesh/doc/meshgarde.txt
new file mode 100644
index 0000000000..89e58d4466
--- /dev/null
+++ b/macros/luatex/latex/luamesh/doc/meshgarde.txt
@@ -0,0 +1,9 @@
+0 0
+6 0
+2 4
+1.5 2
+2. 0.5
+3 2.6
+3.5 1
+5 3.
+0.3 3.2
diff --git a/macros/luatex/latex/luamesh/scripts/luamesh-polygon.lua b/macros/luatex/latex/luamesh/scripts/luamesh-polygon.lua
new file mode 100644
index 0000000000..fd8a228aa3
--- /dev/null
+++ b/macros/luatex/latex/luamesh/scripts/luamesh-polygon.lua
@@ -0,0 +1,87 @@
+-- Given three colinear points p, q, r, the function checks if
+-- point q lies on line segment 'pr'
+function onSegment(p,q,r)
+ if(q.x <= math.max(p.x,r.x) and q.x >= math.min(p.x,r.x) and
+ q.y <= math.max(p.y,r.y) and q.y>= math.min(p.y,r.y)) then
+ return true
+ else
+ return false
+ end
+end
+
+-- To find orientation of ordered triplet (p, q, r).
+-- The function returns following values
+-- 0 --> p, q and r are colinear
+-- 1 --> Clockwise
+-- 2 --> Counterclockwise
+function orientation(p,q,r)
+ val = (q.y-p.y)*(r.x-q.x)-(q.x-p.x)*(r.y-q.y)
+ if(val == 0) then
+ return 0
+ end
+ if(val > 0) then
+ return 1
+ else
+ return 2
+ end
+end
+
+
+-- The function that returns true if line segment 'p1q1'
+-- and 'p2q2' intersect.
+function doIntersect(p1,q1,p2,q2)
+ -- Find the four orientations needed for general and
+ -- special cases
+ o1 = orientation(p1, q1, p2)
+ o2 = orientation(p1, q1, q2)
+ o3 = orientation(p2, q2, p1)
+ o4 = orientation(p2, q2, q1)
+
+ -- gerenal case (without limite case)
+ if(o1 ~= o2 and o3 ~= o4) then
+ return true
+ end
+
+ -- Special case
+ -- p1, q1 and p2 are colinear and p2 lies on segment p1q1
+ if (o1 == 0 and onSegment(p1, p2, q1)) then return true end
+ -- p1, q1 and p2 are colinear and q2 lies on segment p1q1
+ if (o2 == 0 and onSegment(p1, q2, q1)) then return true end
+ -- p2, q2 and p1 are colinear and p1 lies on segment p2q2
+ if (o3 == 0 and onSegment(p2, p1, q2)) then return true end
+ -- p2, q2 and q1 are colinear and q1 lies on segment p2q2
+ if (o4 == 0 and onSegment(p2, q1, q2)) then return true end
+ return false; -- Doesn't fall in any of the above cases
+end
+
+-- Returns true if the point p lies inside the polygon[] with n vertices
+function isInside(listPoints,p,h)
+ -- if the point is to close to a point of the polygon
+ for i=1,#listPoints do
+ if(math.sqrt(math.pow(p.x-listPoints[i].x,2) + math.pow(p.y-listPoints[i].y,2))<0.4*h) then
+ return false
+ end
+ end
+ -- There must be at least 3 vertices in polygon[]
+ if (#listPoints <= 3) then return false end
+ -- Create a point for line segment from p to infinite
+ extreme = {x=1e05,y=p.y};
+ -- Count intersections of the above line with sides of polygon
+ count = 0
+ for i=1,#listPoints do
+ ip = (i)%(#listPoints)+1
+ -- Check if the line segment from 'p' to 'extreme' intersects
+ -- with the line segment from 'polygon[i]' to 'polygon[next]'
+ if (doIntersect(listPoints[i], listPoints[ip], p, extreme)) then
+ -- If the point 'p' is colinear with line segment 'i-ip',
+ -- then check if it lies on segment. If it lies, return true,
+ -- otherwise false
+ if (orientation(listPoints[i], p, listPoints[ip]) == 0) then
+ return onSegment(listPoints[i], p, listPoints[ip])
+ end
+ count = count+1
+ end
+ end
+ -- Return true if count is odd, false otherwise
+ return (count%2 == 1)
+end
diff --git a/macros/luatex/latex/luamesh/scripts/luamesh-tex.lua b/macros/luatex/latex/luamesh/scripts/luamesh-tex.lua
new file mode 100644
index 0000000000..11e31a4c77
--- /dev/null
+++ b/macros/luatex/latex/luamesh/scripts/luamesh-tex.lua
@@ -0,0 +1,998 @@
+-- trace Voronoi with MP
+function traceVoronoiMP(listPoints, triangulation,listVoronoi, points, tri,styleD,styleV)
+ if(styleD == "dashed") then
+ sDelaunay = "dashed evenly"
+ else
+ sDelaunay = ""
+ end
+ if(styleV == "dashed") then
+ sVoronoi = "dashed evenly"
+ else
+ sVoronoi = ""
+ end
+ listCircumC = listCircumCenter(listPoints,triangulation)
+ output = "";
+ output = output .. " pair MeshPoints[];"
+ for i=1,#listPoints do
+ output = output .. "MeshPoints[".. i .. "] = (" .. listPoints[i].x .. "," .. listPoints[i].y .. ")*u;"
+ end
+ output = output .. " pair CircumCenters[];"
+ for i=1,#listCircumC do
+ output = output .. "CircumCenters[".. i .. "] = (" .. listCircumC[i].x .. "," .. listCircumC[i].y .. ")*u;"
+ end
+ if(tri=="show") then
+ for i=1,#triangulation do
+ PointI = listPoints[triangulation[i][1]]
+ PointJ = listPoints[triangulation[i][2]]
+ PointK = listPoints[triangulation[i][3]]
+ if(triangulation[i].type == "bbox") then
+ output = output .. "draw (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u--("..PointK.x..",".. PointK.y ..")*u--cycle "..sDelaunay.." withcolor \\luameshmpcolorBbox;"
+ else
+ output = output .. "draw (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u--("..PointK.x..",".. PointK.y ..")*u--cycle "..sDelaunay.." withcolor \\luameshmpcolor;"
+ end
+ end
+ end
+ for i=1,#listVoronoi do
+ PointI = listCircumC[listVoronoi[i][1]]
+ PointJ = listCircumC[listVoronoi[i][2]]
+ output = output .. "draw (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u "..sVoronoi.." withcolor \\luameshmpcolorVoronoi;"
+ end
+ if(points=="points") then
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "dotlabel.llft (btex $\\MeshPoint^{*}_{"..j.."}$ etex, (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u ) withcolor \\luameshmpcolorBbox ;"
+ j=j+1
+ else
+ output = output .. "dotlabel.llft (btex $\\MeshPoint_{" .. i .. "}$ etex, (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u ) withcolor \\luameshmpcolor ;"
+ end
+ end
+ for i=1,#listCircumC do
+ output = output .. "dotlabel.llft (btex $\\CircumPoint_{" .. i .. "}$ etex, (" .. listCircumC[i].x ..",".. listCircumC[i].y .. ")*u ) withcolor \\luameshmpcolorVoronoi ;"
+ end
+ else
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "drawdot (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u withcolor \\luameshmpcolorBbox withpen pencircle scaled 3;"
+ j=j+1
+ else
+ output = output .. "drawdot (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u withcolor \\luameshmpcolor withpen pencircle scaled 3;"
+ end
+ end
+ for i=1,#listCircumC do
+ output = output .. "drawdot (" .. listCircumC[i].x ..",".. listCircumC[i].y .. ")*u withcolor \\luameshmpcolorVoronoi withpen pencircle scaled 3;"
+ end
+ end
+
+ return output
+end
+
+
+-- trace Voronoi with TikZ
+function traceVoronoiTikZ(listPoints, triangulation,listVoronoi, points, tri,color,colorBbox,colorVoronoi,styleD,styleV)
+ if(styleD == "dashed") then
+ sDelaunay = ",dashed"
+ else
+ sDelaunay = ""
+ end
+ if(styleV == "dashed") then
+ sVoronoi = ",dashed"
+ else
+ sVoronoi = ""
+ end
+ listCircumC = listCircumCenter(listPoints,triangulation)
+ output = ""
+ for i=1,#listPoints do
+ output = output .. "\\coordinate (MeshPoints".. i .. ") at (" .. listPoints[i].x .. "," .. listPoints[i].y .. ");"
+ end
+ for i=1,#listCircumC do
+ output = output .. "\\coordinate (CircumPoints".. i .. ") at (" .. listCircumC[i].x .. "," .. listCircumC[i].y .. ");"
+ end
+ if(tri=="show") then
+ for i=1,#triangulation do
+ PointI = listPoints[triangulation[i][1]]
+ PointJ = listPoints[triangulation[i][2]]
+ PointK = listPoints[triangulation[i][3]]
+ if(triangulation[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox..sDelaunay.."] (".. PointI.x ..",".. PointI.y ..")--("..PointJ.x..",".. PointJ.y ..")--("..PointK.x..",".. PointK.y ..")--cycle;"
+ else
+ output = output .. "\\draw[color="..color..sDelaunay.."] (".. PointI.x ..",".. PointI.y ..")--("..PointJ.x..",".. PointJ.y ..")--("..PointK.x..",".. PointK.y ..")--cycle;"
+ end
+ end
+ end
+ for i=1,#listVoronoi do
+ PointI = listCircumC[listVoronoi[i][1]]
+ PointJ = listCircumC[listVoronoi[i][2]]
+ output = output .. "\\draw[color="..colorVoronoi..sVoronoi.."] (".. PointI.x ..",".. PointI.y ..")--("..PointJ.x..",".. PointJ.y ..");"
+ end
+ if(points=="points") then
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint^*_{" .. j .. "}$};"
+ j=j+1
+ else
+ output = output .. "\\draw[color="..color.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint_{" .. i .. "}$};"
+ end
+ end
+ for i=1,#listCircumC do
+ output = output .. "\\draw[color="..colorVoronoi.."] (" .. listCircumC[i].x ..",".. listCircumC[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\CircumPoint_{" .. i .. "}$};"
+ end
+ else
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} ;"
+ j=j+1
+ else
+ output = output .. "\\draw[color="..color.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} ;"
+ end
+ end
+ for i=1,#listCircumC do
+ output = output .. "\\draw[color="..colorVoronoi.."] (" .. listCircumC[i].x ..",".. listCircumC[i].y .. ") node {$\\bullet$};"
+ end
+ end
+ return output
+end
+
+
+
+-- buildVoronoi with MP
+function buildVoronoiMPBW(chaine,mode,points,bbox,scale,tri,styleD,styleV)
+ local listPoints = buildList(chaine, mode)
+ local triangulation = BowyerWatson(listPoints,bbox)
+ local listVoronoi = buildVoronoi(listPoints, triangulation)
+ output = traceVoronoiMP(listPoints,triangulation,listVoronoi,points,tri,styleD,styleV)
+ output = "\\leavevmode\\begin{mplibcode}beginfig(0);u:="..scale.. ";" .. output .."endfig;\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+
+-- buildVoronoi with TikZ
+function buildVoronoiTikZBW(chaine,mode,points,bbox,scale,tri,color,colorBbox,colorVoronoi,styleD,styleV)
+ local listPoints = buildList(chaine, mode)
+ local triangulation = BowyerWatson(listPoints,bbox)
+ local listVoronoi = buildVoronoi(listPoints, triangulation)
+ output = traceVoronoiTikZ(listPoints,triangulation,listVoronoi,points,tri,color,colorBbox,colorVoronoi,styleD,styleV)
+ output = "\\noindent\\begin{tikzpicture}[x=" .. scale .. ",y=" .. scale .."]" .. output .."\\end{tikzpicture}" tex.sprint(output)
+end
+
+
+-- buildVoronoi with MP
+function buildVoronoiMPBWinc(chaine,beginning, ending,mode,points,bbox,scale,tri,styleD,styleV)
+ local listPoints = buildList(chaine, mode)
+ local triangulation = BowyerWatson(listPoints,bbox)
+ local listVoronoi = buildVoronoi(listPoints, triangulation)
+ output = traceVoronoiMP(listPoints,triangulation,listVoronoi,points,tri,styleD,styleV)
+ output = "\\leavevmode\\begin{mplibcode}u:="..scale..";"..beginning .. output .. ending .. "\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+
+-- buildVoronoi with TikZ
+function buildVoronoiTikZBWinc(chaine,beginning, ending,mode,points,bbox,scale,tri,color,colorBbox,colorVoronoi)
+ local listPoints = buildList(chaine, mode,styleD,styleV)
+ local triangulation = BowyerWatson(listPoints,bbox)
+ local listVoronoi = buildVoronoi(listPoints, triangulation)
+ output = traceVoronoiTikZ(listPoints,triangulation,listVoronoi,points,tri,color,colorBbox,colorVoronoi,styleD,styleV)
+ output = "\\noindent\\begin{tikzpicture}[x=" .. scale .. ",y=" .. scale .."]" ..beginning.. output..ending .."\\end{tikzpicture}"
+ tex.sprint(output)
+end
+
+
+
+-- trace a triangulation with TikZ
+function traceMeshTikZ(listPoints, triangulation,points,color,colorBbox)
+ output = ""
+ for i=1,#listPoints do
+ output = output .. "\\coordinate (MeshPoints".. i .. ") at (" .. listPoints[i].x .. "," .. listPoints[i].y .. ");"
+ end
+ for i=1,#triangulation do
+ PointI = listPoints[triangulation[i][1]]
+ PointJ = listPoints[triangulation[i][2]]
+ PointK = listPoints[triangulation[i][3]]
+ if(triangulation[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (".. PointI.x ..",".. PointI.y ..")--("..PointJ.x..",".. PointJ.y ..")--("..PointK.x..",".. PointK.y ..")--cycle;"
+ else
+ output = output .. "\\draw[color="..color.."] (".. PointI.x ..",".. PointI.y ..")--("..PointJ.x..",".. PointJ.y ..")--("..PointK.x..",".. PointK.y ..")--cycle;"
+ end
+ end
+ if(points=="points") then
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint^*_{" .. j .. "}$};"
+ j=j+1
+ else
+ output = output .. "\\draw[color="..color.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint_{" .. i .. "}$};"
+ end
+ end
+ end
+ if(points=="dotpoints") then
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$};"
+ j=j+1
+ else
+ output = output .. "\\draw[color="..color.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$};"
+ end
+ end
+ end
+ return output
+end
+
+
+-- trace a triangulation with MP
+function traceMeshMP(listPoints, triangulation,points)
+ output = "";
+ output = output .. " pair MeshPoints[];"
+ for i=1,#listPoints do
+ output = output .. "MeshPoints[".. i .. "] = (" .. listPoints[i].x .. "," .. listPoints[i].y .. ")*u;"
+ end
+ for i=1,#triangulation do
+ PointI = listPoints[triangulation[i][1]]
+ PointJ = listPoints[triangulation[i][2]]
+ PointK = listPoints[triangulation[i][3]]
+ if(triangulation[i].type == "bbox") then
+ output = output .. "draw (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u--("..PointK.x..",".. PointK.y ..")*u--cycle withcolor \\luameshmpcolorBbox;"
+ else
+ output = output .. "draw (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u--("..PointK.x..",".. PointK.y ..")*u--cycle withcolor \\luameshmpcolor;"
+ end
+ end
+ if(points=="points") then
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "dotlabel.llft (btex $\\MeshPoint^{*}_{"..j.."}$ etex, (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u ) withcolor \\luameshmpcolorBbox ;"
+ j=j+1
+ else
+ output = output .. "dotlabel.llft (btex $\\MeshPoint_{" .. i .. "}$ etex, (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u ) withcolor \\luameshmpcolor ;"
+ end
+ end
+ end
+ if(points=="dotpoints") then
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "drawdot (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u withcolor \\luameshmpcolorBbox withpen pencircle scaled 3;"
+ j=j+1
+ else
+ output = output .. "drawdot (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u withcolor \\luameshmpcolor withpen pencircle scaled 3;"
+ end
+ end
+ end
+ return output
+end
+
+
+-- buildMesh with MP
+function buildMeshMPBW(chaine,mode,points,bbox,scale)
+ local listPoints = buildList(chaine, mode)
+ local triangulation = BowyerWatson(listPoints,bbox)
+ output = traceMeshMP(listPoints, triangulation,points)
+ output = "\\leavevmode\\begin{mplibcode}beginfig(0);u:="..scale.. ";" .. output .."endfig;\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+-- buildMesh with MP include code
+function buildMeshMPBWinc(chaine,beginning, ending,mode,points,bbox,scale)
+ local listPoints = buildList(chaine, mode)
+ local triangulation = BowyerWatson(listPoints,bbox)
+ output = traceMeshMP(listPoints, triangulation,points)
+ output = "\\leavevmode\\begin{mplibcode}u:="..scale..";"..beginning .. output .. ending .. "\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+-- buildMesh with TikZ
+function buildMeshTikZBW(chaine,mode,points,bbox,scale,color,colorBbox)
+ local listPoints = buildList(chaine, mode)
+ local triangulation = BowyerWatson(listPoints,bbox)
+ output = traceMeshTikZ(listPoints, triangulation,points,color,colorBbox)
+ output = "\\noindent\\begin{tikzpicture}[x=" .. scale .. ",y=" .. scale .."]" .. output .."\\end{tikzpicture}"
+ tex.sprint(output)
+end
+
+-- buildMesh with TikZ
+function buildMeshTikZBWinc(chaine,beginning, ending,mode,points,bbox,scale,color,colorBbox)
+ local listPoints = buildList(chaine, mode)
+ local triangulation = BowyerWatson(listPoints,bbox)
+ output = traceMeshTikZ(listPoints, triangulation,points,color,colorBbox)
+ output = "\\noindent\\begin{tikzpicture}[x=" .. scale .. ",y=" .. scale .."]" ..beginning.. output..ending .."\\end{tikzpicture}"
+ tex.sprint(output)
+end
+
+
+-- print points of the mesh
+function tracePointsMP(listPoints,points)
+ output = "";
+ output = output .. " pair MeshPoints[];"
+ for i=1,#listPoints do
+ output = output .. "MeshPoints[".. i .. "] = (" .. listPoints[i].x .. "," .. listPoints[i].y .. ")*u;"
+ end
+ if(points=="points") then
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "dotlabel.llft (btex $\\MeshPoint^{*}_{" .. j .. "}$ etex, (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u ) withcolor \\luameshmpcolorBbox ;"
+ j=j+1
+ else
+ output = output .. "dotlabel.llft (btex $\\MeshPoint_{" .. i .. "}$ etex, (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u ) withcolor \\luameshmpcolor ;"
+ end
+ end
+ else
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "drawdot (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u withcolor \\luameshmpcolorBbox withpen pencircle scaled 3;"
+ else
+ output = output .. "drawdot (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u withcolor \\luameshmpcolor withpen pencircle scaled 3;"
+ end
+ end
+ end
+ return output
+end
+
+-- print points of the mesh
+function tracePointsTikZ(listPoints,points,color,colorBbox)
+ output = "";
+ for i=1,#listPoints do
+ output = output .. "\\coordinate (MeshPoints".. i .. ") at (" .. listPoints[i].x .. "," .. listPoints[i].y .. ");"
+ end
+ if(points=="points") then
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint^*_{" .. j .. "}$};"
+ j = j+1
+ else
+ output = output .. "\\draw[color="..color.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint_{" .. i .. "}$};"
+ end
+ end
+ else
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} ;"
+ else
+ output = output .. "\\draw[color="..color.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} ;"
+ end
+ end
+ end
+ return output
+end
+
+-- print points to mesh
+function printPointsMP(chaine,mode,points,bbox,scale)
+ local listPoints = buildList(chaine, mode)
+ if(bbox == "bbox" ) then
+ listPoints = buildBoundingBox(listPoints)
+ end
+ output = tracePointsMP(listPoints,points)
+ output = "\\leavevmode\\begin{mplibcode}beginfig(0);u:="..scale.. ";" .. output .."endfig;\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+
+-- print points to mesh
+function printPointsMPinc(chaine,beginning, ending, mode,points,bbox,scale)
+ local listPoints = buildList(chaine, mode)
+ if(bbox == "bbox" ) then
+ listPoints = buildBoundingBox(listPoints)
+ end
+ output = tracePointsMP(listPoints,points)
+ output = "\\leavevmode\\begin{mplibcode}u:="..scale..";"..beginning .. output .. ending .. "\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+-- print points to mesh
+function printPointsTikZ(chaine,mode,points,bbox,scale,color,colorBbox)
+ local listPoints = buildList(chaine, mode)
+ if(bbox == "bbox" ) then
+ listPoints = buildBoundingBox(listPoints)
+ end
+ output = tracePointsTikZ(listPoints,points,color,colorBbox)
+ output = "\\noindent\\begin{tikzpicture}[x=" .. scale .. ",y=" .. scale .."]" .. output .."\\end{tikzpicture}"
+ tex.sprint(output)
+end
+
+
+-- print points to mesh
+function printPointsTikZinc(chaine,beginning, ending, mode,points,bbox,scale,color,colorBbox)
+ local listPoints = buildList(chaine, mode)
+ if(bbox == "bbox" ) then
+ listPoints = buildBoundingBox(listPoints)
+ end
+ output = tracePointsTikZ(listPoints,points,color,colorBbox)
+ output = "\\noindent\\begin{tikzpicture}[x=" .. scale .. ",y=" .. scale .."]" ..beginning.. output..ending .."\\end{tikzpicture}"
+ tex.sprint(output)
+end
+
+
+-- buildMesh
+function buildRect(largeur,a,b,nbrA, nbrB)
+ local listPoints = rectangleList(a,b,nbrA,nbrB)
+ local triangulation = BowyerWatson(listPoints,"none")
+ traceTikZ(listPoints, triangulation,largeur,"none")
+end
+
+
+--
+function TeXaddOnePointTikZ(listPoints,P,step,bbox,color,colorBack, colorNew, colorCircle,colorBbox)
+ output = ""
+ -- build the triangulation
+ local triangulation = BowyerWatson(listPoints,bbox)
+ local badTriangles = buildBadTriangles(P,triangulation,listPoints)
+ for i=1,#listPoints do
+ output = output .. "\\coordinate (MeshPoints".. i .. ") at (" .. listPoints[i].x .. "," .. listPoints[i].y .. ");"
+ end
+ if(step == "badT") then
+ -- draw all triangle
+ for i=1,#triangulation do
+ PointI = listPoints[triangulation[i][1]]
+ PointJ = listPoints[triangulation[i][2]]
+ PointK = listPoints[triangulation[i][3]]
+ if(triangulation[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (".. PointI.x ..",".. PointI.y ..")--("..PointJ.x..",".. PointJ.y ..")--("..PointK.x..",".. PointK.y ..")--cycle;"
+ else
+ output = output .. "\\draw[color="..color.."] (".. PointI.x ..",".. PointI.y ..")--("..PointJ.x..",".. PointJ.y ..")--("..PointK.x..",".. PointK.y ..")--cycle;"
+ end
+ end
+ -- draw and fill the bad triangle
+ for i=1,#badTriangles do
+ PointI = listPoints[triangulation[badTriangles[i]][1]]
+ PointJ = listPoints[triangulation[badTriangles[i]][2]]
+ PointK = listPoints[triangulation[badTriangles[i]][3]]
+ output = output .. "\\draw[fill="..colorBack.."] (".. PointI.x ..",".. PointI.y ..")--("..PointJ.x..",".. PointJ.y ..")--("..PointK.x..",".. PointK.y ..")--cycle;"
+ end
+ -- draw the circoncircle
+ for i=1,#badTriangles do
+ PointI = listPoints[triangulation[badTriangles[i]][1]]
+ PointJ = listPoints[triangulation[badTriangles[i]][2]]
+ PointK = listPoints[triangulation[badTriangles[i]][3]]
+ center, radius = circoncircle(PointI, PointJ, PointK)
+ output = output .. "\\draw[dashed, color="..colorCircle.."] ("..center.x .. "," .. center.y .. ") circle ("..radius ..");"
+ end
+ -- mark the points
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint^*_{" .. j .. "}$};"
+ j = j+1
+ else
+ output = output .. "\\draw[color="..color.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint_{" .. i .. "}$};"
+ end
+ end
+ -- mark the point to add
+ output = output .. "\\draw[color="..colorNew.."] (" .. P.x ..",".. P.y .. ") node {$\\bullet$} node[anchor=north east] {$\\NewPoint$};"
+ elseif(step == "cavity") then
+ polygon = buildCavity(badTriangles, triangulation)
+ polyNew = cleanPoly(polygon)
+ -- remove the bad triangles
+ for j=1,#badTriangles do
+ table.remove(triangulation,badTriangles[j]-(j-1))
+ end
+ -- draw the triangles
+ for i=1,#triangulation do
+ PointI = listPoints[triangulation[i][1]]
+ PointJ = listPoints[triangulation[i][2]]
+ PointK = listPoints[triangulation[i][3]]
+ if(triangulation[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (".. PointI.x ..",".. PointI.y ..")--("..PointJ.x..",".. PointJ.y ..")--("..PointK.x..",".. PointK.y ..")--cycle;"
+ else
+ output = output .. "\\draw[color="..color.."] (".. PointI.x ..",".. PointI.y ..")--("..PointJ.x..",".. PointJ.y ..")--("..PointK.x..",".. PointK.y ..")--cycle;"
+ end
+ end
+ -- fill and draw the cavity
+ path = ""
+ for i=1,#polyNew do
+ PointI = listPoints[polyNew[i]]
+ path = path .. "(".. PointI.x ..",".. PointI.y ..")--"
+ end
+ output = output .. "\\draw[color="..colorNew..",fill ="..colorBack..", thick] " .. path .. "cycle;"
+ -- mark the points of the mesh
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint^*_{" .. j .. "}$};"
+ j=j+1
+ else
+ output = output .. "\\draw[color="..color.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint_{" .. i .. "}$};"
+ end
+ end
+ -- mark the adding point
+ output = output .. "\\draw[color="..colorNew.."] (" .. P.x ..",".. P.y .. ") node {$\\bullet$} node[anchor=north east] {$\\NewPoint$};"
+ elseif(step == "newT") then
+ polygon = buildCavity(badTriangles, triangulation)
+ polyNew = cleanPoly(polygon)
+ -- remove the bad triangles
+ for j=1,#badTriangles do
+ table.remove(triangulation,badTriangles[j]-(j-1))
+ end
+ -- draw the triangle of the triangulation
+ for i=1,#triangulation do
+ PointI = listPoints[triangulation[i][1]]
+ PointJ = listPoints[triangulation[i][2]]
+ PointK = listPoints[triangulation[i][3]]
+ if(triangulation[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (".. PointI.x ..",".. PointI.y ..")--("..PointJ.x..",".. PointJ.y ..")--("..PointK.x..",".. PointK.y ..")--cycle;"
+ else
+ output = output .. "\\draw[color="..color.."] (".. PointI.x ..",".. PointI.y ..")--("..PointJ.x..",".. PointJ.y ..")--("..PointK.x..",".. PointK.y ..")--cycle;"
+ end
+ end
+ -- fill and draw the cavity
+ path = ""
+ for i=1,#polyNew do
+ PointI = listPoints[polyNew[i]]
+ path = path .. "(".. PointI.x ..",".. PointI.y ..")--"
+ end
+ output = output .. "\\draw[color="..colorNew..",fill ="..colorBack..", thick] " .. path .. "cycle;"
+ -- draw the new triangles composed by the edges of the polygon and the added point
+ for i=1,#polygon do
+ output = output .. "\\draw[color=TeXCluaMeshNewTikZ, thick]".."(".. listPoints[polygon[i][1]].x .. "," .. listPoints[polygon[i][1]].y .. ") -- (" .. listPoints[polygon[i][2]].x .. "," .. listPoints[polygon[i][2]].y ..");"
+ output = output .. "\\draw[color="..colorNew..", thick]".."(".. listPoints[polygon[i][1]].x .. "," .. listPoints[polygon[i][1]].y .. ") -- (" .. P.x .. "," .. P.y ..");"
+ output = output .. "\\draw[color="..colorNew..", thick]".."(".. listPoints[polygon[i][2]].x .. "," .. listPoints[polygon[i][2]].y .. ") -- (" .. P.x .. "," .. P.y ..");"
+ end
+ -- mark points
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "\\draw[color="..colorBbox.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint^*_{" .. j .. "}$};"
+ j=j+1
+ else
+ output = output .. "\\draw[color="..color.."] (" .. listPoints[i].x ..",".. listPoints[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint_{" .. i .. "}$};"
+ end
+ end
+ -- mark the added point
+ output = output .. "\\draw[color="..colorNew.."] (" .. P.x ..",".. P.y .. ") node {$\\bullet$} node[anchor=north east] {$\\NewPoint$};"
+ end
+ return output
+end
+
+function TeXaddOnePointMPBW(listPoints,P,step,bbox)
+ output = "";
+ output = output .. "pair MeshPoints[];"
+ -- build the triangulation
+ local triangulation = {}
+ local badTriangles = {}
+ triangulation = BowyerWatson(listPoints,bbox)
+ badTriangles = buildBadTriangles(P,triangulation,listPoints)
+ for i=1,#listPoints do
+ output = output .. "MeshPoints[".. i .. "] = (" .. listPoints[i].x .. "," .. listPoints[i].y .. ")*u;"
+ end
+ if(step == "badT") then
+ -- draw all triangle
+ for i=1,#triangulation do
+ PointI = listPoints[triangulation[i][1]]
+ PointJ = listPoints[triangulation[i][2]]
+ PointK = listPoints[triangulation[i][3]]
+ if(triangulation[i].type == "bbox") then
+ output = output .. "draw (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u--("..PointK.x..",".. PointK.y ..")*u--cycle withcolor \\luameshmpcolorBbox;"
+ else
+ output = output .. "draw (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u--("..PointK.x..",".. PointK.y ..")*u--cycle withcolor \\luameshmpcolor;"
+ end
+ end
+ -- draw and fill the bad triangle
+ for i=1,#badTriangles do
+ PointI = listPoints[triangulation[badTriangles[i]][1]]
+ PointJ = listPoints[triangulation[badTriangles[i]][2]]
+ PointK = listPoints[triangulation[badTriangles[i]][3]]
+ output = output .. "draw (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u--("..PointK.x..",".. PointK.y ..")*u--cycle withcolor \\luameshmpcolor;"
+ output = output .. "fill (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u--("..PointK.x..",".. PointK.y ..")*u--cycle withcolor \\luameshmpcolorBack;"
+ end
+ -- draw the circoncircle
+ for i=1,#badTriangles do
+ PointI = listPoints[triangulation[badTriangles[i]][1]]
+ PointJ = listPoints[triangulation[badTriangles[i]][2]]
+ PointK = listPoints[triangulation[badTriangles[i]][3]]
+ center, radius = circoncircle(PointI, PointJ, PointK)
+ output = output .. "draw fullcircle scaled ("..radius .."*2u) shifted ("..center.x .. "*u," .. center.y .. "*u) dashed evenly withcolor \\luameshmpcolorCircle;"
+ end
+ -- mark the points
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "dotlabel.llft (btex $\\MeshPoint^{*}_{" .. j .. "}$ etex, (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u ) withcolor \\luameshmpcolorBbox ;"
+ j=j+1
+ else
+ output = output .. "dotlabel.llft (btex $\\MeshPoint_{" .. i .. "}$ etex, (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u ) withcolor \\luameshmpcolor ;"
+ end
+ end
+ -- mark the point to add
+ output = output .. "dotlabel.llft (btex $\\NewPoint$ etex,(" .. P.x ..",".. P.y .. ")*u) withcolor \\luameshmpcolorNew;"
+ elseif(step == "cavity") then
+ polygon = buildCavity(badTriangles, triangulation)
+ polyNew = cleanPoly(polygon)
+ -- remove the bad triangles
+ for j=1,#badTriangles do
+ table.remove(triangulation,badTriangles[j]-(j-1))
+ end
+ -- draw the triangles
+ for i=1,#triangulation do
+ PointI = listPoints[triangulation[i][1]]
+ PointJ = listPoints[triangulation[i][2]]
+ PointK = listPoints[triangulation[i][3]]
+ if(triangulation[i].type == "bbox") then
+ output = output .. "draw (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u--("..PointK.x..",".. PointK.y ..")*u--cycle withcolor \\luameshmpcolorBbox;"
+ else
+ output = output .. "draw (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u--("..PointK.x..",".. PointK.y ..")*u--cycle withcolor \\luameshmpcolor;"
+ end
+ end
+ -- fill and draw the cavity
+ path = ""
+ for i=1,#polyNew do
+ PointI = listPoints[polyNew[i]]
+ path = path .. "(".. PointI.x ..",".. PointI.y ..")*u--"
+ end
+ output = output .. "fill " .. path .. "cycle withcolor \\luameshmpcolorBack;"
+ output = output .. "draw " .. path .. "cycle withcolor \\luameshmpcolorNew withpen pencircle scaled 1pt;"
+ -- mark the points of the mesh
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "dotlabel.llft (btex $\\MeshPoint^{*}_{" .. j .. "}$ etex, (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u ) withcolor \\luameshmpcolorBbox ;"
+ j=j+1
+ else
+ output = output .. "dotlabel.llft (btex $\\MeshPoint_{" .. i .. "}$ etex, (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u ) withcolor \\luameshmpcolor ;"
+ end
+ end
+ -- mark the adding point
+ output = output .. "dotlabel.llft (btex $\\NewPoint$ etex,(" .. P.x ..",".. P.y .. ")*u) withcolor \\luameshmpcolorNew ;"
+ elseif(step == "newT") then
+ polygon = buildCavity(badTriangles, triangulation)
+ polyNew = cleanPoly(polygon)
+ -- remove the bad triangles
+ for j=1,#badTriangles do
+ table.remove(triangulation,badTriangles[j]-(j-1))
+ end
+ -- draw the triangle of the triangulation
+ for i=1,#triangulation do
+ PointI = listPoints[triangulation[i][1]]
+ PointJ = listPoints[triangulation[i][2]]
+ PointK = listPoints[triangulation[i][3]]
+ if(triangulation[i].type == "bbox") then
+ output = output .. "draw (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u--("..PointK.x..",".. PointK.y ..")*u--cycle withcolor \\luameshmpcolorBbox;"
+ else
+ output = output .. "draw (".. PointI.x ..",".. PointI.y ..")*u--("..PointJ.x..",".. PointJ.y ..")*u--("..PointK.x..",".. PointK.y ..")*u--cycle withcolor \\luameshmpcolor;"
+ end
+ end
+ -- fill the cavity
+ path = ""
+ for i=1,#polyNew do
+ PointI = listPoints[polyNew[i]]
+ path = path .. "(".. PointI.x ..",".. PointI.y ..")*u--"
+ end
+ output = output .. "fill " .. path .. "cycle withcolor \\luameshmpcolorBack;"
+ -- draw the new triangles composed by the edges of the polygon and the added point
+ for i=1,#polygon do
+ output = output .. "draw".."(".. listPoints[polygon[i][1]].x .. "," .. listPoints[polygon[i][1]].y .. ")*u -- (" .. listPoints[polygon[i][2]].x .. "," .. listPoints[polygon[i][2]].y ..")*u withcolor \\luameshmpcolorNew withpen pencircle scaled 1pt;"
+ output = output .. "draw".."(".. listPoints[polygon[i][1]].x .. "," .. listPoints[polygon[i][1]].y .. ")*u -- (" .. P.x .. "," .. P.y ..")*u withcolor \\luameshmpcolorNew withpen pencircle scaled 1pt;"
+ output = output .. "draw".."(".. listPoints[polygon[i][2]].x .. "," .. listPoints[polygon[i][2]].y .. ")*u -- (" .. P.x .. "," .. P.y ..")*u withcolor \\luameshmpcolorNew withpen pencircle scaled 1pt;"
+ end
+ -- mark points
+ j=1
+ for i=1,#listPoints do
+ if(listPoints[i].type == "bbox") then
+ output = output .. "dotlabel.llft (btex $\\MeshPoint^{*}_{" .. j .. "}$ etex, (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u ) withcolor \\luameshmpcolorBbox ;"
+ j=j+1
+ else
+ output = output .. "dotlabel.llft (btex $\\MeshPoint_{" .. i .. "}$ etex, (" .. listPoints[i].x ..",".. listPoints[i].y .. ")*u ) withcolor \\luameshmpcolor ;"
+ end
+ end
+ -- mark the added point
+ output = output .. "dotlabel.llft (btex $\\NewPoint$ etex,(" .. P.x ..",".. P.y .. ")*u) withcolor \\luameshmpcolorNew ;"
+ end
+ return output
+end
+
+
+function TeXOnePointTikZBW(chaine,point,step,scale,mode,bbox,color,colorBack,colorNew,colorCircle,colorBbox)
+ local listPoints = {}
+ if(mode=="int") then
+ Sx,Sy=string.match(point,"%((.+),(.+)%)")
+ P = {x=Sx, y=Sy}
+ listPoints = buildList(chaine, mode)
+ else
+ -- point is a number
+ P, listPoints = buildListExt(chaine,tonumber(point))
+ end
+ output = TeXaddOnePointTikZ(listPoints,P,step,bbox,color,colorBack,colorNew,colorCircle,colorBbox)
+ output = "\\noindent\\begin{tikzpicture}[x="..scale..",y="..scale.."]".. output .. "\\end{tikzpicture}"
+ tex.sprint(output)
+end
+
+function TeXOnePointTikZBWinc(chaine,point,beginning, ending,step,scale,mode,bbox,color,colorBack,colorNew,colorCircle,colorBbox)
+ local listPoints = {}
+ if(mode=="int") then
+ Sx,Sy=string.match(point,"%((.+),(.+)%)")
+ P = {x=Sx, y=Sy}
+ listPoints = buildList(chaine, mode)
+ else
+ -- point is a number
+ P, listPoints = buildListExt(chaine,tonumber(point))
+ end
+ output = TeXaddOnePointTikZ(listPoints,P,step,bbox,color,colorBack,colorNew,colorCircle,colorBbox)
+ output = "\\noindent\\begin{tikzpicture}[x="..scale..",y="..scale.."]".. beginning..output ..ending.. "\\end{tikzpicture}"
+ tex.sprint(output)
+end
+
+function TeXOnePointMPBW(chaine,point,step,scale,mode,bbox)
+ local listPoints = {}
+ if(mode=="int") then
+ Sx,Sy=string.match(point,"%((.+),(.+)%)")
+ P = {x=Sx, y=Sy}
+ listPoints = buildList(chaine, mode)
+ else
+ -- point is a number
+ P, listPoints = buildListExt(chaine,tonumber(point))
+ end
+ output = TeXaddOnePointMPBW(listPoints,P,step,bbox)
+ output = "\\leavevmode\\begin{mplibcode}beginfig(0);u:="..scale..";".. output .. "endfig;\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+function TeXOnePointMPBWinc(chaine,point,beginning,ending,step,scale,mode,bbox)
+ local listPoints = {}
+ if(mode=="int") then
+ Sx,Sy=string.match(point,"%((.+),(.+)%)")
+ P = {x=Sx, y=Sy}
+ listPoints = buildList(chaine, mode)
+ else
+ -- point is a number
+ P, listPoints = buildListExt(chaine,tonumber(point))
+ end
+ output = TeXaddOnePointMPBW(listPoints,P,step,bbox)
+ output = "\\begin{mplibcode}u:="..scale..";"..beginning .. output .. ending .. "\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+
+function drawGmshMP(file,points,scale)
+ local listPoints,triangulation = readGmsh(file)
+ output = traceMeshMP(listPoints,triangulation,points)
+ output = "\\leavevmode\\begin{mplibcode}beginfig(0);u:="..scale.. ";" .. output .."endfig;\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+function drawGmshMPinc(file,beginning,ending,points,scale)
+ local listPoints,triangulation = readGmsh(file)
+ output = traceMeshMP(listPoints,triangulation,points)
+ output = "\\leavevmode\\begin{mplibcode}u:="..scale..";"..beginning .. output .. ending .. "\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+
+
+--
+function drawGmshTikZ(file,points,scale,color)
+ local listPoints,triangulation = readGmsh(file)
+ output = traceMeshTikZ(listPoints, triangulation,points,color,colorBbox)
+ output = "\\noindent\\begin{tikzpicture}[x=" .. scale .. ",y=" .. scale .."]" .. output .."\\end{tikzpicture}"
+ tex.sprint(output)
+end
+
+--
+function drawGmshTikZinc(file,beginning, ending,points,scale,color)
+ local listPoints,triangulation = readGmsh(file)
+ output = traceMeshTikZ(listPoints, triangulation,points,color,colorBbox)
+ output = "\\noindent\\begin{tikzpicture}[x=" .. scale .. ",y=" .. scale .."]" ..beginning.. output..ending .."\\end{tikzpicture}"
+ tex.sprint(output)
+end
+
+
+-- buildVoronoi with MP
+function gmshVoronoiMP(file,points,scale,tri,styleD,styleV)
+ local listPoints,triangulation = readGmsh(file)
+ local listVoronoi = buildVoronoi(listPoints, triangulation)
+ output = traceVoronoiMP(listPoints,triangulation,listVoronoi,points,tri,styleD,styleV)
+ output = "\\leavevmode\\begin{mplibcode}beginfig(0);u:="..scale.. ";" .. output .."endfig;\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+
+-- buildVoronoi with TikZ
+function gmshVoronoiTikZ(file,points,scale,tri,color,colorVoronoi,styleD,styleV)
+ local listPoints,triangulation = readGmsh(file)
+ local listVoronoi = buildVoronoi(listPoints, triangulation)
+ output = traceVoronoiTikZ(listPoints,triangulation,listVoronoi,points,tri,color,colorBbox,colorVoronoi,styleD,styleV)
+ output = "\\noindent\\begin{tikzpicture}[x=" .. scale .. ",y=" .. scale .."]" .. output .."\\end{tikzpicture}" tex.sprint(output)
+end
+
+
+-- buildVoronoi with MP
+function gmshVoronoiMPinc(file,beginning, ending,points,scale,tri,styleD,styleV)
+ local listPoints,triangulation = readGmsh(file)
+ local listVoronoi = buildVoronoi(listPoints, triangulation)
+ output = traceVoronoiMP(listPoints,triangulation,listVoronoi,points,tri,styleD,styleV)
+ output = "\\leavevmode\\begin{mplibcode}u:="..scale..";"..beginning .. output .. ending .. "\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+
+-- buildVoronoi with TikZ
+function gmshVoronoiTikZinc(file,beginning, ending,points,scale,tri,color,colorVoronoi,styleD,styleV)
+ local listPoints,triangulation = readGmsh(file)
+ local listVoronoi = buildVoronoi(listPoints, triangulation)
+ output = traceVoronoiTikZ(listPoints,triangulation,listVoronoi,points,tri,color,colorBbox,colorVoronoi,styleD,styleV)
+ output = "\\noindent\\begin{tikzpicture}[x=" .. scale .. ",y=" .. scale .."]" ..beginning.. output..ending .."\\end{tikzpicture}"
+ tex.sprint(output)
+end
+
+
+--------------------------------------------------
+-- Meshing of a polygon --
+--------------------------------------------------
+
+function tracePolygonMP(polygon,points)
+ output = "";
+ output = output .. "pair polygon[];"
+ for i=1,#polygon do
+ output = output .. "polygon[".. i .. "] = (" .. polygon[i].x .. "," .. polygon[i].y .. ")*u;"
+ end
+ output = output .. "draw "
+ for i=1,#polygon do
+ output = output .. "(" .. polygon[i].x .. "," .. polygon[i].y .. ")*u -- "
+ end
+ output = output .. "cycle withcolor \\luameshmpcolorPoly withpen pencircle scaled 1pt;"
+ if(points=="points") then
+ for i=1,#polygon do
+ output = output .. "dotlabel.llft (btex $\\MeshPoint_{" .. i .. "}$ etex, (" .. polygon[i].x ..",".. polygon[i].y .. ")*u ) withcolor \\luameshmpcolorPoly ;"
+ end
+ end
+ if(points=="dotpoints") then
+ for i=1,#polygon do
+ output = output .. "drawdot (" .. polygon[i].x ..",".. polygon[i].y .. ")*u withcolor \\luameshmpcolorPoly withpen pencircle scaled 3;"
+ end
+ end
+ return output
+end
+
+
+function tracePolygonTikZ(polygon,points, colorPoly)
+ output = "";
+ for i=1,#polygon do
+ output = output .. "\\coordinate (polygon".. i .. ") at (" .. polygon[i].x .. "," .. polygon[i].y .. ");"
+ end
+ output = output .. "\\draw[color=".. colorPoly .. ", thick]"
+ for i=1,#polygon do
+ output = output .. "(" .. polygon[i].x .. "," .. polygon[i].y .. ") -- "
+ end
+ output = output .. "cycle;"
+ if(points=="points") then
+ for i=1,#polygon do
+ output = output .. "\\draw[color="..colorPoly.."] (" .. polygon[i].x ..",".. polygon[i].y .. ") node {$\\bullet$} node[anchor=north east] {$\\MeshPoint_{" .. i .. "}$};"
+ end
+ end
+ if(points=="dotpoints") then
+ for i=1,#polygon do
+ output = output .. "\\draw[color="..colorPoly.."] (" .. polygon[i].x ..",".. polygon[i].y .. ") node {$\\bullet$};"
+ end
+ end
+ return output
+end
+
+
+
+function drawMeshPolygonMP(chaine,mode,h,step,
+ points,scale,random)
+ local polygon = buildList(chaine, mode)
+ polygon = addPointsPolygon(polygon,h)
+ local grid = buildGrid(polygon,h,random)
+ local listPoints = addGridPoints(polygon,grid,h)
+ if(step=="polygon") then
+ -- the polygon
+ output = tracePolygonMP(polygon,points)
+ end
+ if(step=="grid") then
+ -- polygon + grid
+ output = tracePointsMP(grid,points)
+ output = output .. tracePolygonMP(polygon,points)
+ end
+ if(step=="points") then
+ -- polygon + only grid points inside the polygon
+ output = tracePointsMP(listPoints,points)
+ output = output .. tracePolygonMP(polygon,points)
+ end
+ if(step=="mesh") then
+ -- polygon + mesh
+ triangulation = BowyerWatson(listPoints,"none") -- no bbox
+ output = traceMeshMP(listPoints,triangulation,points)
+ output = output .. tracePolygonMP(polygon,points)
+ end
+
+ output = "\\leavevmode\\begin{mplibcode}beginfig(0);u:="..scale.. ";" .. output .."endfig;\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+
+
+function drawMeshPolygonTikZ(chaine,mode,h,step,
+ points,scale,color,colorPoly,random)
+ local polygon = buildList(chaine, mode)
+ polygon = addPointsPolygon(polygon,h)
+ local grid = buildGrid(polygon,h,random)
+ local listPoints = addGridPoints(polygon,grid,h)
+ if(step=="polygon") then
+ -- the polygon
+ output = tracePolygonTikZ(polygon,points,colorPoly)
+ end
+ if(step=="grid") then
+ -- polygon + grid
+ output = tracePointsTikZ(grid,points,color,"none") -- none for colorBbox
+ output = output .. tracePolygonTikZ(polygon,points,colorPoly)
+ end
+ if(step=="points") then
+ -- polygon + only grid points inside the polygon
+ output = tracePointsTikZ(listPoints,points,color,"none")
+ output = output .. tracePolygonTikZ(polygon,points,colorPoly)
+ end
+ if(step=="mesh") then
+ -- polygon + mesh
+ triangulation = BowyerWatson(listPoints,"none") -- no bbox
+ output = traceMeshTikZ(listPoints,triangulation,points,color,"none")
+ output = output .. tracePolygonTikZ(polygon,points,colorPoly)
+ end
+ output = "\\noindent\\begin{tikzpicture}[x=" .. scale .. ",y=" .. scale .."]" .. output .."\\end{tikzpicture}"
+ tex.sprint(output)
+end
+
+function drawMeshPolygonMPinc(chaine,beginning,ending,mode,h,step,
+ points,scale,random)
+ local polygon = buildList(chaine, mode)
+ polygon = addPointsPolygon(polygon,h)
+ local grid = buildGrid(polygon,h,random)
+ local listPoints = addGridPoints(polygon,grid,h)
+ if(step=="polygon") then
+ -- the polygon
+ output = tracePolygonMP(polygon,points)
+ end
+ if(step=="grid") then
+ -- polygon + grid
+ output = tracePointsMP(grid,points)
+ output = output .. tracePolygonMP(polygon,points)
+ end
+ if(step=="points") then
+ -- polygon + only grid points inside the polygon
+ output = tracePointsMP(listPoints,points)
+ output = output .. tracePolygonMP(polygon,points)
+ end
+ if(step=="mesh") then
+ -- polygon + mesh
+ triangulation = BowyerWatson(listPoints,"none") -- no bbox
+ output = traceMeshMP(listPoints,triangulation,points)
+ output = output .. tracePolygonMP(polygon,points)
+ end
+ output = "\\begin{mplibcode}u:="..scale..";"..beginning .. output .. ending .. "\\end{mplibcode}"
+ tex.sprint(output)
+end
+
+
+
+function drawMeshPolygonTikZinc(chaine,beginning,ending,mode,h,step,
+ points,scale,color,colorPoly,random)
+ local polygon = buildList(chaine, mode)
+ polygon = addPointsPolygon(polygon,h)
+ local grid = buildGrid(polygon,h,random)
+ local listPoints = addGridPoints(polygon,grid,h)
+ if(step=="polygon") then
+ -- the polygon
+ output = tracePolygonTikZ(polygon,points,colorPoly)
+ end
+ if(step=="grid") then
+ -- polygon + grid
+ output = tracePointsTikZ(grid,points,color,"none") -- none for colorBbox
+ output = output .. tracePolygonTikZ(polygon,points,colorPoly)
+ end
+ if(step=="points") then
+ -- polygon + only grid points inside the polygon
+ output = tracePointsTikZ(listPoints,points,color,"none")
+ output = output .. tracePolygonTikZ(polygon,points,colorPoly)
+ end
+ if(step=="mesh") then
+ -- polygon + mesh
+ triangulation = BowyerWatson(listPoints,"none") -- no bbox
+ output = traceMeshTikZ(listPoints,triangulation,points,color,"none")
+ output = output .. tracePolygonTikZ(polygon,points,colorPoly)
+ end
+ output = "\\noindent\\begin{tikzpicture}[x="..scale..",y="..scale.."]".. beginning..output ..ending.. "\\end{tikzpicture}"
+ tex.sprint(output)
+end
diff --git a/macros/luatex/latex/luamesh/scripts/luamesh.lua b/macros/luatex/latex/luamesh/scripts/luamesh.lua
new file mode 100644
index 0000000000..a1023aace9
--- /dev/null
+++ b/macros/luatex/latex/luamesh/scripts/luamesh.lua
@@ -0,0 +1,545 @@
+require "luamesh-polygon"
+require "luamesh-tex"
+
+local function shallowCopy(original)
+ local copy = {}
+ for key, value in pairs(original) do
+ copy[key] = value
+ end
+ return copy
+end
+
+-- Bowyer and Watson algorithm
+-- Delaunay meshing
+function BowyerWatson (listPoints,bbox)
+ local triangulation = {}
+ lgth = #listPoints
+ -- add four points to listPoints to have a bounding box
+ listPoints = buildBoundingBox(listPoints)
+ -- the first triangle
+ triangulation[1] = {lgth+1, lgth+2, lgth+3,type="bbox"}
+ -- the second triangle
+ triangulation[2] = {lgth+1, lgth+3, lgth+4,type="bbox"}
+ -- add points one by one
+ for i=1,lgth do
+ -- find the triangles which the circumcircle contained the point to add
+ badTriangles = buildBadTriangles(listPoints[i],triangulation,listPoints)
+ -- build the polygon of the cavity containing the point to add
+ polygon = buildCavity(badTriangles, triangulation)
+ -- remove the bad triangles
+ for j=1,#badTriangles do
+ table.remove(triangulation,badTriangles[j]-(j-1))
+ end
+ -- build the new triangles and add them to triangulation
+ for j=1,#polygon do
+ if((polygon[j][1]>lgth) or (polygon[j][2]>lgth) or (i>lgth)) then
+ table.insert(triangulation,{polygon[j][1],polygon[j][2],i,type="bbox"})
+ else
+ table.insert(triangulation,{polygon[j][1],polygon[j][2],i,type="in"})
+ end
+ end
+ end -- end adding points of the listPoints
+ -- remove bounding box
+ if(bbox ~= "bbox") then
+ triangulation = removeBoundingBox(triangulation,lgth)
+ table.remove(listPoints,lgth+1)
+ table.remove(listPoints,lgth+1)
+ table.remove(listPoints,lgth+1)
+ table.remove(listPoints,lgth+1)
+ end
+ return triangulation
+end
+
+
+function buildBoundingBox(listPoints)
+ -- listPoints : list of points
+ -- epsV : parameter for the distance of the bounding box
+ local xmin, xmax, ymin, ymax, eps
+ xmin = 1000
+ ymin = 1000
+ xmax = -1000
+ ymax = -1000
+ for i=1,#listPoints do
+ if (listPoints[i].x < xmin) then
+ xmin = listPoints[i].x
+ end
+ if (listPoints[i].x > xmax) then
+ xmax = listPoints[i].x
+ end
+ if (listPoints[i].y < ymin) then
+ ymin = listPoints[i].y
+ end
+ if (listPoints[i].y > ymax) then
+ ymax = listPoints[i].y
+ end
+ end
+ eps = math.max(math.abs(xmax-xmin),math.abs(ymax-ymin))*0.15
+ xmin = xmin - eps
+ xmax = xmax + eps
+ ymin = ymin - eps
+ ymax = ymax + eps
+ -- add points of the bounding box in last positions
+ table.insert(listPoints,{x=xmin,y=ymin,type="bbox"})
+ table.insert(listPoints,{x=xmin,y=ymax,type="bbox"})
+ table.insert(listPoints,{x=xmax,y=ymax,type="bbox"})
+ table.insert(listPoints,{x=xmax,y=ymin,type="bbox"})
+ return listPoints
+end
+
+function BoundingBox(listPoints)
+ -- listPoints : list of points
+ -- epsV : parameter for the distance of the bounding box
+ local xmin, xmax, ymin, ymax, eps
+ xmin = 1000
+ ymin = 1000
+ xmax = -1000
+ ymax = -1000
+ for i=1,#listPoints do
+ if (listPoints[i].x < xmin) then
+ xmin = listPoints[i].x
+ end
+ if (listPoints[i].x > xmax) then
+ xmax = listPoints[i].x
+ end
+ if (listPoints[i].y < ymin) then
+ ymin = listPoints[i].y
+ end
+ if (listPoints[i].y > ymax) then
+ ymax = listPoints[i].y
+ end
+ end
+ eps = math.max(math.abs(xmax-xmin),math.abs(ymax-ymin))*0.15
+ xmin = xmin - eps
+ xmax = xmax + eps
+ ymin = ymin - eps
+ ymax = ymax + eps
+ return xmin, xmax, ymin, ymax
+end
+
+function removeBoundingBox(triangulation,lgth)
+ -- build the four bounding box edge
+ point1 = lgth+1
+ point2 = lgth+2
+ point3 = lgth+3
+ point4 = lgth+4
+ -- for all triangle
+ local newTriangulation = {}
+ for i=1,#triangulation do
+ boolE1 = pointInTriangle(point1,triangulation[i])
+ boolE2 = pointInTriangle(point2,triangulation[i])
+ boolE3 = pointInTriangle(point3,triangulation[i])
+ boolE4 = pointInTriangle(point4,triangulation[i])
+ if((not boolE1) and (not boolE2) and (not boolE3) and (not boolE4)) then
+ table.insert(newTriangulation,triangulation[i])
+ end
+ end
+ return newTriangulation
+end
+
+
+function buildBadTriangles(point, triangulation,listPoints)
+ local badTriangles = {}
+ for j=1,#triangulation do -- for all triangles
+ A = listPoints[triangulation[j][1]]
+ B = listPoints[triangulation[j][2]]
+ C = listPoints[triangulation[j][3]]
+ center, radius = circoncircle(A,B,C)
+ CP = Vector(center,point)
+ if(VectorNorm(CP)<radius) then -- the point belongs to the circoncirle
+ table.insert(badTriangles,j)
+ end
+ end
+ return badTriangles
+end
+
+-- construction of the cavity composed by the bad triangles around the point to add
+function buildCavity(badTriangles, triangulation)
+ local polygon = {}
+ for j=1,#badTriangles do -- for all bad triangles
+ ind = badTriangles[j]
+ for k=1,3 do -- for all edges
+ edge = {triangulation[ind][k],triangulation[ind][k%3+1]}
+ edgeBord = false
+ for l = 1,#badTriangles do -- for all badtriangles
+ badInd = badTriangles[l]
+ if(badInd ~= ind) then -- if not the current one
+ edgeBord = edgeBord or edgeInTriangle(edge,triangulation[badInd])
+ end
+ end --
+ -- if the edge does not belong to another bad triangle
+ if(edgeBord == false) then
+ -- insert the edge to the cavity
+ table.insert(polygon,edge)
+ end
+ end --
+ end --
+ return polygon
+end
+
+function edgeInTriangle(e,t)
+ in1 = false
+ in2 = false
+ for i=1,3 do
+ if e[1] == t[i] then
+ in1 = true
+ end
+ if e[2] == t[i] then
+ in2 = true
+ end
+ end
+ out = (in1 and in2)
+ return out
+end
+
+function pointInTriangle(e,t)
+ in1 = false
+ for i=1,3 do
+ if e == t[i] then
+ in1 = true
+ end
+ end
+ return in1
+end
+
+
+function Vector(A,B)
+ local out = {x = B.x - A.x, y = B.y - A.y}
+ return out
+end
+
+function VectorNorm(NP)
+ return math.sqrt(NP.x*NP.x +NP.y*NP.y)
+end
+
+-- circoncircle
+function circoncircle(M, N, P)
+ -- Compute center and radius of the circoncircle of the triangle M N P
+
+ -- return : (center [Point],radius [float])
+
+ local MN = Vector(M,N)
+ local NP = Vector(N,P)
+ local PM = Vector(P,M)
+ m = VectorNorm(NP) -- |NP|
+ n = VectorNorm(PM) -- |PM|
+ p = VectorNorm(MN) -- |MN|
+
+ d = (m + n + p) * (-m + n + p) * (m - n + p) * (m + n - p)
+ if d > 0 then
+ rad = m * n * p / math.sqrt(d)
+ else
+ rad = 0
+ end
+ d = -2 * (M.x * NP.y + N.x * PM.y + P.x * MN.y)
+ O = {x=0, y=0}
+ OM = Vector(O, M)
+ ON = Vector(O, N)
+ OP = Vector(O, P)
+ om2 = math.pow(VectorNorm(OM),2) -- |OM|**2
+ on2 = math.pow(VectorNorm(ON),2) -- |ON|**2
+ op2 = math.pow(VectorNorm(OP),2) -- |OP|**2
+ x0 = -(om2 * NP.y + on2 * PM.y + op2 * MN.y) / d
+ y0 = (om2 * NP.x + on2 * PM.x + op2 * MN.x) / d
+ if d == 0 then
+ Out = {nil, nil}
+ else
+ Out = {x=x0, y=y0}
+ end
+ return Out, rad -- (center [Point], R [float])
+end
+
+-- compute the list of the circumcircle of a triangulation
+function listCircumCenter(listPoints,triangulation)
+ local list = {}
+ for j=1,#triangulation do
+ A = listPoints[triangulation[j][1]]
+ B = listPoints[triangulation[j][2]]
+ C = listPoints[triangulation[j][3]]
+ center, radius = circoncircle(A,B,C)
+ table.insert(list,{x=center.x,y=center.y,r=radius})
+ end
+ return list
+end
+
+-- find the three neighbour triangles of T
+function findNeighbour(T,i,triangulation)
+ -- T : triangle
+ -- i : index of T in triangualation
+ -- triangulation
+
+ list = {}
+ -- define the three edge
+ e1 = {T[1],T[2]}
+ e2 = {T[2],T[3]}
+ e3 = {T[3],T[1]}
+ for j=1,#triangulation do
+ if j~= i then
+ if(edgeInTriangle(e1,triangulation[j])) then
+ table.insert(list,j)
+ end
+ if(edgeInTriangle(e2,triangulation[j])) then
+ table.insert(list,j)
+ end
+ if(edgeInTriangle(e3,triangulation[j])) then
+ table.insert(list,j)
+ end
+ end
+ end
+ return list
+end
+
+-- test if edge are the same (reverse)
+function equalEdge(e1,e2)
+ if(((e1[1] == e2[1]) and (e1[2] == e2[2])) or ((e1[1] == e2[2]) and (e1[2] == e2[1]))) then
+ return true
+ else
+ return false
+ end
+end
+
+-- test if the edge belongs to the list
+function edgeInList(e,listE)
+ output = false
+ for i=1,#listE do
+ if(equalEdge(e,listE[i])) then
+ output = true
+ end
+ end
+ return output
+end
+
+-- build the edges of the Voronoi diagram with a given triangulation
+function buildVoronoi(listPoints, triangulation)
+ local listCircumCircle = listCircumCenter(listPoints, triangulation)
+ local listVoronoi = {}
+ for i=1,#listCircumCircle do
+ listN = findNeighbour(triangulation[i],i,triangulation)
+ for j=1,#listN do
+ edge = {i,listN[j]}
+ if( not edgeInList(edge, listVoronoi)) then
+ table.insert(listVoronoi, edge)
+ end
+ end
+ end
+ return listVoronoi
+end
+
+-- build the list of points
+function buildList(chaine, mode)
+ -- if mode = int : the list is given in the chaine string (x1,y1);(x2,y2);...;(xn,yn)
+ -- if mode = ext : the list is given in a file line by line with space separation
+ local listPoints = {}
+ if mode == "int" then
+ local points = string.explode(chaine, ";")
+ local lgth=#points
+ for i=1,lgth do
+ Sx,Sy=string.match(points[i],"%((.+),(.+)%)")
+ listPoints[i]={x=tonumber(Sx),y=tonumber(Sy)}
+ end
+ elseif mode == "ext" then
+ io.input(chaine) -- open the file
+ text=io.read("*all")
+ lines=string.explode(text,"\n+") -- all the lines
+ tablePoints={}
+ for i=1,#lines do
+ xy=string.explode(lines[i]," +")
+ listPoints[i]={x=tonumber(xy[1]),y=tonumber(xy[2])}
+ end
+ else
+ print("Non existing mode")
+ end
+ return listPoints
+end
+
+
+-- function to add points on a polygon to respect
+-- the size of unit mesh
+function addPointsPolygon(polygon,h)
+ local newPolygon = shallowCopy(polygon)
+ k=0 -- to follow in the newPolygon
+ for i=1,#polygon do
+ k = k+1
+ ip = (i)%(#polygon)+1
+ dist = math.sqrt(math.pow(polygon[i].x-polygon[ip].x,2) + math.pow(polygon[i].y-polygon[ip].y,2))
+ -- if the distance between two ponits of the polygon is greater than 1.5*h
+ if(dist>=2*h) then
+ n = math.floor(dist/h)
+ step = dist/(n+1)
+ for j=1,n do
+ a = {x=polygon[i].x+j*step*(polygon[ip].x-polygon[i].x)/dist,y=polygon[i].y+j*step*(polygon[ip].y-polygon[i].y)/dist}
+ table.insert(newPolygon,k+j,a)
+ end
+ k=k+n
+ end
+ end
+ return newPolygon
+end
+
+-- function to build a gridpoints from the bounding box
+-- with a prescribed
+function buildGrid(listPoints,h,random)
+ -- listPoints : list of the points of the polygon, ordered
+ -- h : parameter for the grid
+ xmin, xmax, ymin, ymax = BoundingBox(listPoints)
+
+ local grid = rectangleList(xmin,xmax,ymin,ymax,h,random)
+ return grid
+end
+
+-- function to build the list of points in the rectangle
+function rectangleList(xmin,xmax,ymin,ymax,h,random)
+ -- for the random
+ math.randomseed( os.time() )
+ nbrX = math.floor(math.abs(xmax-xmin)/h)
+ nbrY = math.floor(math.abs(ymax-ymin)/h)
+ local listPoints = {}
+ k=1
+ for i=1,(nbrX+1) do
+ for j=1,(nbrY+1) do
+ rd = math.random()
+ if(random=="perturb") then
+ fact = 0.3*h
+ --print(fact)
+ else
+ fact = 0.0
+ end
+ listPoints[k] = {x = xmin+(i-1)*h+rd*fact, y=ymin+(j-1)*h+rd*fact}
+ k=k+1
+ end
+ end
+ return listPoints
+end
+
+
+-- function to add points from a grid to the interior of a polygon
+function addGridPoints(polygon, grid,h)
+ local listPoints = shallowCopy(polygon)
+ k = #polygon
+ for i=1, #grid do
+ --print(grid[i].x,grid[i].y)
+ --print(isInside(polygon,grid[i]))
+ if(isInside(polygon,grid[i],h)) then
+ k=k+1
+ listPoints[k] = grid[i]
+ end
+ end
+ return listPoints
+end
+
+
+
+-- function give a real polygon without repeting points
+function cleanPoly(polygon)
+ local polyNew = {}
+ local polyCopy = shallowCopy(polygon)
+ e1 = polyCopy[1][1]
+ e2 = polyCopy[1][2]
+ table.insert(polyNew, e1)
+ table.insert(polyNew, e2)
+ table.remove(polyCopy,1)
+ j = 2
+ while #polyCopy>1 do
+ i=1
+ find = false
+ while (i<=#polyCopy and find==false) do
+ bool1 = (polyCopy[i][1] == polyNew[j])
+ bool2 = (polyCopy[i][2] == polyNew[j])
+ if(bool1 or bool2) then -- the edge has a common point with polyNew[j]
+ if(not bool1) then
+ table.insert(polyNew, polyCopy[i][1])
+ find = true
+ table.remove(polyCopy,i)
+ j = j+1
+ elseif(not bool2) then
+ table.insert(polyNew, polyCopy[i][2])
+ find = true
+ table.remove(polyCopy,i)
+ j = j+1
+ end
+ end
+ i=i+1
+ end
+ end
+ return polyNew
+end
+
+
+
+-- build the list of points extern and stop at nbr
+function buildListExt(chaine, stop)
+ local listPoints = {}
+ io.input(chaine) -- open the file
+ text=io.read("*all")
+ lines=string.explode(text,"\n+") -- all the lines
+ for i=1,tonumber(stop) do
+ xy=string.explode(lines[i]," +")
+ table.insert(listPoints,{x=tonumber(xy[1]),y=tonumber(xy[2])})
+ end
+ xy=string.explode(lines[stop+1]," +")
+ point={x=tonumber(xy[1]),y=tonumber(xy[2])}
+ return point, listPoints
+end
+
+function split(pString, pPattern)
+ local Table = {} -- NOTE: use {n = 0} in Lua-5.0
+ local fpat = "(.-)" .. pPattern
+ local last_end = 1
+ local s, e, cap = pString:find(fpat, 1)
+ while s do
+ if s ~= 1 or cap ~= "" then
+ table.insert(Table,cap)
+ end
+ last_end = e+1
+ s, e, cap = pString:find(fpat, last_end)
+ end
+ if last_end <= #pString then
+ cap = pString:sub(last_end)
+ table.insert(Table, cap)
+ end
+ return Table
+end
+
+function readGmsh(file)
+ io.input(file) -- open the file
+ text=io.read("*all")
+ local lines = split(text,"\n+") -- all the lines
+ local listPoints={}
+ local triangulation ={}
+ boolNodes = false
+ Jnodes = 0
+ boolElements = false
+ Jelements = 0
+ J=0
+ for i=1,#lines-J do
+ if(lines[i+J] == "$EndNodes") then
+ boolNodes = false
+ -- go to the next line
+ end
+ if(boolNodes) then -- we are in the Nodes environment
+ xy=split(lines[i+J]," +")
+ table.insert(listPoints,{x=tonumber(xy[2]),y=tonumber(xy[3])})
+ end
+ if(lines[i+J] == "$Nodes") then
+ boolNodes = true
+ -- go to the next line
+ J=J+1
+ end
+ if(lines[i+J] == "$EndElements") then
+ boolElements = false
+ -- go to the next line
+ end
+ if(boolElements) then -- we are in the Nodes environment
+ xy=split(lines[i+J]," +")
+ if(tonumber(xy[2]) == 2) then -- if the element is a triangle
+ nbrTags = xy[3]+1
+ table.insert(triangulation,{tonumber(xy[2+nbrTags+1]),tonumber(xy[2+nbrTags+2]),tonumber(xy[2+nbrTags+3])})
+ end
+ end
+ if(lines[i+J] == "$Elements") then
+ boolElements = true
+ -- go to the next line
+ J=J+1
+ end
+ end
+ return listPoints, triangulation
+end
diff --git a/macros/luatex/latex/luamesh/tex/luamesh.sty b/macros/luatex/latex/luamesh/tex/luamesh.sty
new file mode 100644
index 0000000000..86f66edf1f
--- /dev/null
+++ b/macros/luatex/latex/luamesh/tex/luamesh.sty
@@ -0,0 +1,984 @@
+\NeedsTeXFormat{LaTeX2e}%
+\def\PackageName{luamesh}%
+\def\fileversion{v0.51}%
+\def\filedate{2017/04/15}%
+\ProvidesPackage{luamesh}[\filedate\space\fileversion]%
+%
+% package to load
+\RequirePackage{xkeyval,xcolor,ifthen}%
+%% one global option: mp or tikz
+%\newif\ifluameshmp%
+%\define@key{luamesh.sty}{mp}[]{\luameshmptrue}%
+%\define@key{luamesh.sty}{tikz}[]{\luameshmpfalse}%
+%
+%\RequirePackage{etoolbox} % pour robustifier les commandes
+%
+%
+%\ifluameshmp%
+ \RequirePackage{luamplib}%
+%\else%
+ \RequirePackage{tikz}%
+%\fi%
+%
+% load the lua code
+\directlua{require("luamesh.lua")}%
+%
+%%
+% for tikz (default value)
+% default color for the plot of a global mesh
+\definecolor{TeXCluaMeshTikZ}{rgb}{0.,0.,0.}
+% default color for a new element
+\definecolor{TeXCluaMeshNewTikZ}{rgb}{0.5,0.1,0.1}
+% defaut color for the background of new element
+\definecolor{TeXCluaMeshBackTikZ}{rgb}{0.99,0.85,0.85}
+% default color for circoncircle
+\definecolor{TeXCluaMeshCircleTikZ}{rgb}{0.1,0.6,0.1}
+%%
+%
+%%%%%%%%%%%%%%%% the buildMesh command inc
+%% the user can write code (tikz or MP)
+%% before and after the generated code
+\define@boolkey{buildMeshInc}{tikz}[true]{}%
+%% show the bounding box for delaunay
+\define@choicekey*{buildMeshInc}{bbox}[\val\nr]{none, show}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bmi@bbox{none}%
+ \or%
+ \def\luameshval@bmi@bbox{bbox}%
+ \fi%
+}%
+%% the scale
+\define@key{buildMeshInc}{scale}[1cm]{\def\luameshval@bmi@scale{#1}}%
+%% print ponits ?
+\define@choicekey*{buildMeshInc}{print}[\val\nr]{none, points,dotpoints}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bmi@print{none}%
+ \or%
+ \def\luameshval@bmi@print{points}%
+ \or%
+ \def\luameshval@bmi@print{dotpoints}%
+ \fi%
+}%
+%% the name of the point
+\define@key{buildMeshInc}{meshpoint}[P]{\def\luameshval@bmi@meshpoint{#1}}%
+%% the mode for reading the points
+\define@choicekey*{buildMeshInc}{mode}[\val\nr]{int, ext}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bmi@mode{int}%
+ \or%
+ \def\luameshval@bmi@mode{ext}%
+ \fi%
+}%
+%% the name of the color of drawing
+\define@key{buildMeshInc}{color}[black]{\def\luameshval@bmi@color{#1}}%
+%% the name of the color of drawing the bbox
+\define@key{buildMeshInc}{colorBbox}[black]{\def\luameshval@bmi@colorbbox{#1}}%
+%
+\presetkeys{buildMeshInc}{tikz=false,bbox=none,scale, meshpoint,mode=int,print=none,color,colorBbox}{}%
+%
+\newcommand*{\buildMeshBWinc}[4][]{%
+ % #1 : optionnal arguments
+ % #2 : the string containing the list of points
+ % (x1,y1);(x2,y2);... or the name file containing the points
+ % #3 : the code to place before the generated one
+ % #4 : the code to place after the generated one
+ \setkeys{buildMeshInc}{#1} %
+ \def\MeshPoint{\luameshval@bmi@meshpoint}%
+ \ifKV@buildMeshInc@tikz% if we are using tikz
+ \directlua{%
+ buildMeshTikZBWinc("#2","\luaescapestring{\unexpanded{#3}}","\luaescapestring{\unexpanded{#4}}","\luameshval@bmi@mode","\luameshval@bmi@print","\luameshval@bmi@bbox","\luameshval@bmi@scale","\luameshval@bmi@color","\luameshval@bmi@colorbbox")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshval@bmi@color}%
+ \mplibcolor{\luameshmpcolorBbox}{\luameshval@bmi@colorbbox}%
+ \directlua{%
+ buildMeshMPBWinc("#2","\luaescapestring{\unexpanded{#3}}","\luaescapestring{\unexpanded{#4}}","\luameshval@bmi@mode","\luameshval@bmi@print","\luameshval@bmi@bbox","\luameshval@bmi@scale")%
+ }%
+ %
+ \fi%
+}%
+%
+%%%%%%%%%%%%%%%% the buildMeshBW command
+%% the code is complete and we don't have any callbacks
+\define@boolkey{buildMesh}{tikz}[true]{}%
+%% show the bounding box for delaunay
+\define@choicekey*{buildMesh}{bbox}[\val\nr]{none, show}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bm@bbox{none}%
+ \or%
+ \def\luameshval@bm@bbox{bbox}%
+ \fi%
+}%
+%% the scale
+\define@key{buildMesh}{scale}[1cm]{\def\luameshval@bm@scale{#1}}%
+%% print points
+\define@choicekey*{buildMesh}{print}[\val\nr]{none, points, dotpoints}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bm@print{none}%
+ \or%
+ \def\luameshval@bm@print{points}%
+ \or%
+ \def\luameshval@bm@print{dotpoints}%
+ \fi%
+}%
+%% the name of the point
+\define@key{buildMesh}{meshpoint}[P]{\def\luameshval@bm@meshpoint{#1}}%
+%% the mode for reading the points
+\define@choicekey*{buildMesh}{mode}[\val\nr]{int, ext}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bm@mode{int}%
+ \or%
+ \def\luameshval@bm@mode{ext}%
+ \fi%
+}%
+%% the name of the color of drawing
+\define@key{buildMesh}{color}[black]{\def\luameshval@bm@color{#1}}%
+%% the name of the color of drawing the bbox
+\define@key{buildMesh}{colorBbox}[black]{\def\luameshval@bm@colorbbox{#1}}%
+%
+\presetkeys{buildMesh}{tikz=false,bbox=none,scale, meshpoint,mode=int,print=none,color,colorBbox}{}%
+%
+\newcommand{\buildMeshBW}[2][]{%
+ % #1 : optionnal arguments
+ % #2 : the string containing the list of points
+ % (x1,y1);(x2,y2);... or the name file containing the points
+ \setkeys{buildMesh}{#1} %
+ \def\MeshPoint{\luameshval@bm@meshpoint}%
+ \ifKV@buildMesh@tikz% if we are using tikz
+ \directlua{%
+ buildMeshTikZBW("#2","\luameshval@bm@mode","\luameshval@bm@print","\luameshval@bm@bbox","\luameshval@bm@scale","\luameshval@bm@color","\luameshval@bm@colorbbox")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshval@bm@color}%
+ \mplibcolor{\luameshmpcolorBbox}{\luameshval@bm@colorbbox}%
+ \directlua{%
+ buildMeshMPBW("#2","\luameshval@bm@mode","\luameshval@bm@print","\luameshval@bm@bbox","\luameshval@bm@scale")%
+ }%
+ %
+ \fi%
+}%
+%%%%%%%%%%%%%%%% the buildVoronoi command
+%% the user can write code (tikz or MP)
+%% before and after the generated code
+\define@boolkey{buildVoronoiInc}{tikz}[true]{}%
+%% show the bounding box for delaunay
+\define@choicekey*{buildVoronoiInc}{bbox}[\val\nr]{none, show}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bvi@bbox{none}%
+ \or%
+ \def\luameshval@bvi@bbox{bbox}%
+ \fi%
+}%
+%% the scale
+\define@key{buildVoronoiInc}{scale}[1cm]{\def\luameshval@bvi@scale{#1}}%
+%% print ponits ?
+\define@choicekey*{buildVoronoiInc}{print}[\val\nr]{none, points}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bvi@print{none}%
+ \or%
+ \def\luameshval@bvi@print{points}%
+ \fi%
+}%
+%% style dashed Delaunay
+\define@choicekey*{buildVoronoiInc}{styleDelaunay}[\val\nr]{none, dashed}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bvi@styleDelaunay{none}%
+ \or%
+ \def\luameshval@bvi@styleDelaunay{dashed}%
+ \fi%
+}%
+%% style dashed Voronoi
+\define@choicekey*{buildVoronoiInc}{styleVoronoi}[\val\nr]{none, dashed}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bvi@styleVoronoi{none}%
+ \or%
+ \def\luameshval@bvi@styleVoronoi{dashed}%
+ \fi%
+}%
+%% the name of the point
+\define@key{buildVoronoiInc}{meshpoint}[P]{\def\luameshval@bvi@meshpoint{#1}}%
+%% the name of the circum point
+\define@key{buildVoronoiInc}{circumpoint}[P]{\def\luameshval@bvi@circumpoint{#1}}%
+%% the mode for reading the points
+\define@choicekey*{buildVoronoiInc}{mode}[\val\nr]{int, ext}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bvi@mode{int}%
+ \or%
+ \def\luameshval@bvi@mode{ext}%
+ \fi%
+}%
+%% the mode for reading the points
+\define@choicekey*{buildVoronoiInc}{delaunay}[\val\nr]{none, show}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bvi@delaunay{none}%
+ \or%
+ \def\luameshval@bvi@delaunay{show}%
+ \fi%
+}%
+%% the name of the color of drawing
+\define@key{buildVoronoiInc}{color}[black]{\def\luameshval@bvi@color{#1}}%
+%% the name of the color of drawing Voronoi
+\define@key{buildVoronoiInc}{colorVoronoi}[red]{\def\luameshval@bvi@colorvoronoi{#1}}%
+%% the name of the color of drawing the bbox
+\define@key{buildVoronoiInc}{colorBbox}[black]{\def\luameshval@bvi@colorbbox{#1}}%
+%
+\presetkeys{buildVoronoiInc}{tikz=false,bbox=none,scale, meshpoint,circumpoint,mode=int,print=none,color,colorVoronoi,colorBbox,delaunay=none,styleDelaunay=none,styleVoronoi=none}{}%
+%
+\newcommand*{\buildVoronoiBWinc}[4][]{%
+ % #1 : optionnal arguments
+ % #2 : the string containing the list of points
+ % (x1,y1);(x2,y2);... or the name file containing the points
+ % #3 : the code to place before the generated one
+ % #4 : the code to place after the generated one
+ \setkeys{buildVoronoiInc}{#1} %
+ \def\MeshPoint{\luameshval@bvi@meshpoint}%
+ \def\CircumPoint{\luameshval@bvi@circumpoint}%
+ \ifKV@buildVoronoiInc@tikz% if we are using tikz
+ \directlua{%
+ buildVoronoiTikZBWinc("#2","\luaescapestring{\unexpanded{#3}}","\luaescapestring{\unexpanded{#4}}","\luameshval@bvi@mode","\luameshval@bvi@print","\luameshval@bvi@bbox","\luameshval@bvi@scale","\luameshval@bvi@delaunay","\luameshval@bvi@color","\luameshval@bvi@colorbbox","\luameshval@bvi@colorvoronoi","\luameshval@bvi@styleDelaunay","\luameshval@bvi@styleVoronoi")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshval@bvi@color}%
+ \mplibcolor{\luameshmpcolorBbox}{\luameshval@bvi@colorbbox}%
+ \mplibcolor{\luameshmpcolorVoronoi}{\luameshval@bvi@colorvoronoi}%
+ \directlua{%
+ buildVoronoiMPBWinc("#2","\luaescapestring{\unexpanded{#3}}","\luaescapestring{\unexpanded{#4}}","\luameshval@bvi@mode","\luameshval@bvi@print","\luameshval@bvi@bbox","\luameshval@bvi@scale","\luameshval@bvi@delaunay","\luameshval@bvi@styleDelaunay","\luameshval@bvi@styleVoronoi")%
+ }%
+ %
+ \fi%
+}%
+%
+%%%%%%%%%%%%%%%% the buildVoronoiBW command
+%% the code is complete and we don't have any callbacks
+\define@boolkey{buildVoronoi}{tikz}[true]{}%
+%% show the bounding box for delaunay
+\define@choicekey*{buildVoronoi}{bbox}[\val\nr]{none, show}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bv@bbox{none}%
+ \or%
+ \def\luameshval@bv@bbox{bbox}%
+ \fi%
+}%
+%% the scale
+\define@key{buildVoronoi}{scale}[1cm]{\def\luameshval@bv@scale{#1}}%
+%% print points
+\define@choicekey*{buildVoronoi}{print}[\val\nr]{none, points}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bv@print{none}%
+ \or%
+ \def\luameshval@bv@print{points}%
+ \fi%
+}%
+%% the name of the point
+\define@key{buildVoronoi}{meshpoint}[P]{\def\luameshval@bv@meshpoint{#1}}%
+%% the name of the circum point
+\define@key{buildVoronoi}{circumpoint}[P]{\def\luameshval@bv@circumpoint{#1}}%
+%% the mode for reading the points
+\define@choicekey*{buildVoronoi}{mode}[\val\nr]{int, ext}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bv@mode{int}%
+ \or%
+ \def\luameshval@bv@mode{ext}%
+ \fi%
+}%
+%% style dashed Delaunay
+\define@choicekey*{buildVoronoi}{styleDelaunay}[\val\nr]{none, dashed}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bv@styleDelaunay{none}%
+ \or%
+ \def\luameshval@bv@styleDelaunay{dashed}%
+ \fi%
+}%
+%% style dashed Voronoi
+\define@choicekey*{buildVoronoi}{styleVoronoi}[\val\nr]{none, dashed}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bv@styleVoronoi{none}%
+ \or%
+ \def\luameshval@bv@styleVoronoi{dashed}%
+ \fi%
+}%
+%% the mode for reading the points
+\define@choicekey*{buildVoronoi}{delaunay}[\val\nr]{none, show}{%
+ \ifcase\nr\relax%
+ \def\luameshval@bv@delaunay{none}%
+ \or%
+ \def\luameshval@bv@delaunay{show}%
+ \fi%
+}%
+%% the name of the color of drawing
+\define@key{buildVoronoi}{color}[black]{\def\luameshval@bv@color{#1}}%
+%% the name of the color of drawing Voronoi
+\define@key{buildVoronoi}{colorVoronoi}[red]{\def\luameshval@bv@colorVoronoi{#1}}%
+%% the name of the color of drawing the bbox
+\define@key{buildVoronoi}{colorBbox}[black]{\def\luameshval@bv@colorbbox{#1}}%
+%
+\presetkeys{buildVoronoi}{tikz=false,bbox=none,scale,
+ meshpoint,circumpoint,mode=int,print=none,color,colorVoronoi,colorBbox,delaunay=none,styleDelaunay=none, styleVoronoi=none}{}%
+%
+\newcommand{\buildVoronoiBW}[2][]{%
+ % #1 : optionnal arguments
+ % #2 : the string containing the list of points
+ % (x1,y1);(x2,y2);... or the name file containing the points
+ \setkeys{buildVoronoi}{#1} %
+ \def\MeshPoint{\luameshval@bv@meshpoint}%
+ \def\CircumPoint{\luameshval@bv@circumpoint}%
+ \ifKV@buildVoronoi@tikz% if we are using tikz
+ \directlua{%
+ buildVoronoiTikZBW("#2","\luameshval@bv@mode","\luameshval@bv@print","\luameshval@bv@bbox","\luameshval@bv@scale","\luameshval@bv@delaunay","\luameshval@bv@color","\luameshval@bv@colorbbox","\luameshval@bv@colorVoronoi","\luameshval@bv@styleDelaunay","\luameshval@bv@styleVoronoi")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshval@bv@color}%
+ \mplibcolor{\luameshmpcolorBbox}{\luameshval@bv@colorbbox}%
+ \mplibcolor{\luameshmpcolorVoronoi}{\luameshval@bv@colorVoronoi}%
+ \directlua{%
+ buildVoronoiMPBW("#2","\luameshval@bv@mode","\luameshval@bv@print","\luameshval@bv@bbox","\luameshval@bv@scale","\luameshval@bv@delaunay","\luameshval@bv@styleDelaunay","\luameshval@bv@styleVoronoi")%
+ }%
+ %
+ \fi%
+}%
+%
+%
+%%%%%%%%%%%%%%%%% the draw Points macro
+%% plot the list of points given in argument
+% the engine
+\define@boolkey{drawPoints}{tikz}[true]{}%
+%% show the bounding box for delaunay
+\define@choicekey*{drawPoints}{bbox}[\val\nr]{none, show}{%
+ \ifcase\nr\relax%
+ \def\luameshval@tp@bbox{none}%
+ \or%
+ \def\luameshval@tp@bbox{bbox}%
+ \fi%
+}%
+%% the scale
+\define@key{drawPoints}{scale}[1cm]{\def\luameshval@tp@scale{#1}}%
+%% print points
+\define@choicekey*{drawPoints}{print}[\val\nr]{none, points}{%
+ \ifcase\nr\relax%
+ \def\luameshval@tp@print{none}%
+ \or%
+ \def\luameshval@tp@print{points}%
+ \fi%
+}%
+%% the name of the point
+\define@key{drawPoints}{meshpoint}[P]{\def\luameshval@tp@meshpoint{#1}}%
+%% the mode for reading the points
+\define@choicekey*{drawPoints}{mode}[\val\nr]{int, ext}{%
+ \ifcase\nr\relax%
+ \def\luameshval@tp@mode{int}%
+ \or%
+ \def\luameshval@tp@mode{ext}%
+ \fi%
+}%
+%% the name of the color of drawing
+\define@key{drawPoints}{color}[black]{\def\luameshval@tp@color{#1}}%
+%% the name of the color of drawing the bbox
+\define@key{drawPoints}{colorBbox}[black]{\def\luameshval@tp@colorbbox{#1}}%
+%
+\presetkeys{drawPoints}{tikz=false,bbox=none,scale, meshpoint,mode=int,print=none,color,colorBbox}{}%
+%
+\newcommand{\drawPointsMesh}[2][]{%
+ % #1 : optionnal arguments
+ % #2 : the string containing the list of points
+ % (x1,y1);(x2,y2);... or the name file containing the points
+ \setkeys{drawPoints}{#1} %
+ \def\MeshPoint{\luameshval@tp@meshpoint}%
+ \ifKV@drawPoints@tikz% if we are using tikz
+ \directlua{%
+ printPointsTikZ("#2","\luameshval@tp@mode","\luameshval@tp@print","\luameshval@tp@bbox","\luameshval@tp@scale","\luameshval@tp@color","\luameshval@tp@colorbbox")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshval@tp@color}%
+ \mplibcolor{\luameshmpcolorBbox}{\luameshval@tp@colorbbox}%
+ \directlua{%
+ printPointsMP("#2","\luameshval@tp@mode","\luameshval@tp@print","\luameshval@tp@bbox","\luameshval@tp@scale")%
+ }%
+ %
+ \fi%
+}%
+%
+
+%%%%%%%%%%%%%%%% the draw Points macro inc with callbacks
+%% engine of drawing
+\define@boolkey{drawPointsInc}{tikz}[true]{}%
+%% show the bounding box for delaunay
+\define@choicekey*{drawPointsInc}{bbox}[\val\nr]{none, show}{%
+ \ifcase\nr\relax%
+ \def\luameshval@tpi@bbox{none}%
+ \or%
+ \def\luameshval@tpi@bbox{bbox}%
+ \fi%
+}%
+%% the scale
+\define@key{drawPointsInc}{scale}[1cm]{\def\luameshval@tpi@scale{#1}}%
+%% print points
+\define@choicekey*{drawPointsInc}{print}[\val\nr]{none, points}{%
+ \ifcase\nr\relax%
+ \def\luameshval@tpi@print{none}%
+ \or%
+ \def\luameshval@tpi@print{points}%
+ \fi%
+}%
+%% the name of the point
+\define@key{drawPointsInc}{meshpoint}[P]{\def\luameshval@tpi@meshpoint{#1}}%
+%% the mode for reading the points
+\define@choicekey*{drawPointsInc}{mode}[\val\nr]{int, ext}{%
+ \ifcase\nr\relax%
+ \def\luameshval@tpi@mode{int}%
+ \or%
+ \def\luameshval@tpi@mode{ext}%
+ \fi%
+}%
+%
+% color
+%% the name of the color of drawing
+\define@key{drawPointsInc}{color}[black]{\def\luameshval@tpi@color{#1}}%
+%% the name of the color of drawing the bbox
+\define@key{drawPointsInc}{colorBbox}[black]{\def\luameshval@tpi@colorbbox{#1}}%
+%
+\presetkeys{drawPointsInc}{tikz=false,bbox=none,scale, meshpoint,mode=int,print=none,color,colorBbox}{}%
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\newcommand*{\drawPointsMeshinc}[4][]{%
+ % #1 : optionnal arguments
+ % #2 : the string containing the list of points
+ % (x1,y1);(x2,y2);... or the name file containing the points
+ % #3 : the code to place before the generated one
+ % #4 : the code to place after the generated one
+ \setkeys{drawPointsInc}{#1} %
+ \def\MeshPoint{\luameshval@tpi@meshpoint}%
+ \ifKV@drawPointsInc@tikz% if we are using tikz
+ \directlua{%
+ printPointsTikZinc("#2","\luaescapestring{\unexpanded{#3}}","\luaescapestring{\unexpanded{#4}}","\luameshval@tpi@mode","\luameshval@tpi@print","\luameshval@tpi@bbox","\luameshval@tpi@scale","\luameshval@tpi@color","\luameshval@tpi@colorbbox")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshval@tpi@color}%
+ \mplibcolor{\luameshmpcolorBbox}{\luameshval@tpi@colorbbox}%
+ \directlua{%
+ printPointsMPinc("#2","\luaescapestring{\unexpanded{#3}}","\luaescapestring{\unexpanded{#4}}","\luameshval@tpi@mode","\luameshval@tpi@print","\luameshval@tpi@bbox","\luameshval@tpi@scale")%
+ }%
+ \fi%
+}%
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% the meshAddOnePointBW commande
+%%engine of draiwng
+\define@boolkey{MeshAddOneBW}{tikz}[true]{}%
+%% the scale
+\define@key{MeshAddOneBW}{scale}[1cm]{\def\luameshval@ap@scale{#1}}%
+%% the name of the points
+\define@key{MeshAddOneBW}{meshpoint}[P]{\def\luameshval@ap@meshpoint{#1}}%
+%% the name of the new point
+\define@key{MeshAddOneBW}{newpoint}[P]{\def\luameshval@ap@newpoint{#1}}%
+%% a complete picture or some code of the engine
+\define@choicekey*{MeshAddOneBW}{step}[\val\nr]{badtriangles, cavity, newtriangles}{%
+ \ifcase\nr\relax%
+ \def\luameshval@ap@step{badT}%
+ \or%
+ \def\luameshval@ap@step{cavity}%
+ \or%
+ \def\luameshval@ap@step{newT}%
+ \fi%
+}%
+% color
+%% the color of drawing
+\define@key{MeshAddOneBW}{color}[black]{\def\luameshval@ap@color{#1}}%
+%% the color of background of new element
+\define@key{MeshAddOneBW}{colorBack}[black!20]{\def\luameshval@ap@colorback{#1}}%
+%% the color of new element
+\define@key{MeshAddOneBW}{colorNew}[red]{\def\luameshval@ap@colornew{#1}}%
+%% the color of circoncircle
+\define@key{MeshAddOneBW}{colorCircle}[green]{\def\luameshval@ap@colorcircle{#1}}%
+%% the name of the color of drawing the bbox
+\define@key{MeshAddOneBW}{colorBbox}[black]{\def\luameshval@ap@colorbbox{#1}}%
+%
+%% a complete picture or some code of the engine
+\define@choicekey*{MeshAddOneBW}{mode}[\val\nr]{int, ext}{%
+ \ifcase\nr\relax%
+ \def\luameshval@ap@mode{int}%
+ \or%
+ \def\luameshval@ap@mode{ext}%
+ \fi%
+}%
+\define@choicekey*{MeshAddOneBW}{bbox}[\val\nr]{none, show}{%
+ \ifcase\nr\relax%
+ \def\luameshval@ap@bbox{none}%
+ \or%
+ \def\luameshval@ap@bbox{bbox}%
+ \fi%
+}%
+\presetkeys{MeshAddOneBW}{tikz=false,scale, meshpoint,newpoint,color,colorBack,colorNew,colorCircle,step=badtriangles,mode=int,bbox=none,colorBbox}{}%
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\newcommand*{\meshAddPointBW}[3][]{%
+ % #1 : optionnal arguments
+ % #2 : the string containing the list of points
+ % (x1,y1);(x2,y2);... or the name file containing the points
+ \setkeys{MeshAddOneBW}{#1} %
+ \def\MeshPoint{\luameshval@ap@meshpoint}%
+ \def\NewPoint{\luameshval@ap@newpoint}%
+ \ifKV@MeshAddOneBW@tikz% if we are using tikz
+ \directlua{%
+ TeXOnePointTikZBW("#2","#3","\luameshval@ap@step","\luameshval@ap@scale","\luameshval@ap@mode","\luameshval@ap@bbox","\luameshval@ap@color","\luameshval@ap@colorback","\luameshval@ap@colornew","\luameshval@ap@colorcircle","\luameshval@ap@colorbbox")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshval@ap@color}
+ \mplibcolor{\luameshmpcolorBack}{\luameshval@ap@colorback}
+ \mplibcolor{\luameshmpcolorNew}{\luameshval@ap@colornew}
+ \mplibcolor{\luameshmpcolorCircle}{\luameshval@ap@colorcircle}
+ \mplibcolor{\luameshmpcolorBbox}{\luameshval@ap@colorbbox}
+ \directlua{%
+ TeXOnePointMPBW("#2","#3","\luameshval@ap@step","\luameshval@ap@scale","\luameshval@ap@mode","\luameshval@ap@bbox")%
+ }%
+ %
+ \fi%
+}%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% the meshAddPointBWinc commande with callbacks
+%% engine of drawing
+\define@boolkey{MeshAddOneBWinc}{tikz}[true]{}%
+%% the scale
+\define@key{MeshAddOneBWinc}{scale}[1cm]{\def\luameshval@api@scale{#1}}%
+%% the name of the points
+\define@key{MeshAddOneBWinc}{meshpoint}[P]{\def\luameshval@api@meshpoint{#1}}%
+%% the name of the new point
+\define@key{MeshAddOneBWinc}{newpoint}[P]{\def\luameshval@api@newpoint{#1}}%
+%% a complete picture or some code of the engine
+\define@choicekey*{MeshAddOneBWinc}{step}[\val\nr]{badtriangles, cavity, newtriangles}{%
+ \ifcase\nr\relax%
+ \def\luameshval@api@step{badT}%
+ \or%
+ \def\luameshval@api@step{cavity}%
+ \or%
+ \def\luameshval@api@step{newT}%
+ \fi%
+}%
+% color
+%% the color of drawing
+\define@key{MeshAddOneBWinc}{color}[black]{\def\luameshval@api@color{#1}}%
+%% the color of background of new element
+\define@key{MeshAddOneBWinc}{colorBack}[black!20]{\def\luameshval@api@colorback{#1}}%
+%% the color of new element
+\define@key{MeshAddOneBWinc}{colorNew}[red]{\def\luameshval@api@colornew{#1}}%
+%% the color of circoncircle
+\define@key{MeshAddOneBWinc}{colorCircle}[green]{\def\luameshval@api@colorcircle{#1}}%
+\define@key{MeshAddOneBWinc}{colorBbox}[black]{\def\luameshval@api@colorbbox{#1}}%
+%
+%% a complete picture or some code of the engine
+\define@choicekey*{MeshAddOneBWinc}{mode}[\val\nr]{int, ext}{%
+ \ifcase\nr\relax%
+ \def\luameshval@api@mode{int}%
+ \or%
+ \def\luameshval@api@mode{ext}%
+ \fi%
+}%
+\define@choicekey*{MeshAddOneBWinc}{bbox}[\val\nr]{none, show}{%
+ \ifcase\nr\relax%
+ \def\luameshval@api@bbox{none}%
+ \or%
+ \def\luameshval@api@bbox{bbox}%
+ \fi%
+}%
+\presetkeys{MeshAddOneBWinc}{tikz=false,scale, meshpoint,newpoint,color,colorBack,colorNew,colorCircle,step=badtriangles,mode=int,bbox=none,colorBbox}{}%
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\newcommand*{\meshAddPointBWinc}[5][]{%
+ % #1 : optionnal arguments
+ % #2 : the string containing the list of points
+ % (x1,y1);(x2,y2);... or the name file containing the points
+ % #3 : the code to place before the generated one
+ % #4 : the code to place after the generated one
+ \setkeys{MeshAddOneBWinc}{#1} %
+ \def\MeshPoint{\luameshval@api@meshpoint}%
+ \def\NewPoint{\luameshval@api@newpoint}%
+ \ifKV@MeshAddOneBWinc@tikz% if we are using tikz
+ \directlua{%
+ TeXOnePointTikZBWinc("#2","#3","\luaescapestring{\unexpanded{#4}}","\luaescapestring{\unexpanded{#5}}","\luameshval@ap@step","\luameshval@ap@scale","\luameshval@ap@mode","\luameshval@ap@bbox","\luameshval@ap@color","\luameshval@ap@colorback","\luameshval@ap@colornew","\luameshval@ap@colorcircle","\luameshval@ap@colorbbox")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshval@api@color}
+ \mplibcolor{\luameshmpcolorBack}{\luameshval@api@colorback}
+ \mplibcolor{\luameshmpcolorNew}{\luameshval@api@colornew}
+ \mplibcolor{\luameshmpcolorCircle}{\luameshval@api@colorcircle}
+ \mplibcolor{\luameshmpcolorBbox}{\luameshval@api@colorbbox}
+ \directlua{%
+ TeXOnePointMPBWinc("#2","#3","\luaescapestring{\unexpanded{#4}}","\luaescapestring{\unexpanded{#5}}","\luameshval@api@step","\luameshval@api@scale","\luameshval@api@mode","\luameshval@api@bbox")%
+ }%
+ %
+ \fi%
+}%
+%
+%%%%%%%%%%%%%%%% the drawGmsh command inc
+%% the user can write code (tikz or MP)
+%% before and after the generated code
+\define@boolkey{drawGmshInc}{tikz}[true]{}%
+%% the scale
+\define@key{drawGmshInc}{scale}[1cm]{\def\luameshvaldgi@scale{#1}}%
+%% print ponits ?
+\define@choicekey*{drawGmshInc}{print}[\val\nr]{none, points}{%
+ \ifcase\nr\relax%
+ \def\luameshvaldgi@print{none}%
+ \or%
+ \def\luameshvaldgi@print{points}%
+ \fi%
+}%
+%% the name of the point
+\define@key{drawGmshInc}{meshpoint}[P]{\def\luameshvaldgi@meshpoint{#1}}%
+%% the name of the color of drawing
+\define@key{drawGmshInc}{color}[black]{\def\luameshvaldgi@color{#1}}%
+%
+\presetkeys{drawGmshInc}{tikz=false,scale, meshpoint,print=none,color}{}%
+%
+\newcommand*{\drawGmshinc}[4][]{%
+ % #1 : optionnal arguments
+ % #2 : the string containing the gmsh file
+ % #3 : the code to place before the generated one
+ % #4 : the code to place after the generated one
+ \setkeys{drawGmshInc}{#1} %
+ \def\MeshPoint{\luameshvaldgi@meshpoint}%
+ \ifKV@drawGmshInc@tikz% if we are using tikz
+ \directlua{%
+ drawGmshTikZinc("#2","\luaescapestring{\unexpanded{#3}}","\luaescapestring{\unexpanded{#4}}","\luameshvaldgi@print","\luameshvaldgi@scale","\luameshvaldgi@color")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshvaldgi@color}%
+ \directlua{%
+ drawGmshMPinc("#2","\luaescapestring{\unexpanded{#3}}","\luaescapestring{\unexpanded{#4}}","\luameshvaldgi@print","\luameshvaldgi@scale")%
+ }%
+ %
+ \fi%
+}%
+%
+%%%%%%%%%%%%%%%% the drawGmshBW command
+%% the code is complete and we don't have any callbacks
+\define@boolkey{drawGmsh}{tikz}[true]{}%
+%% the scale
+\define@key{drawGmsh}{scale}[1cm]{\def\luameshvaldg@scale{#1}}%
+%% print points
+\define@choicekey*{drawGmsh}{print}[\val\nr]{none, points}{%
+ \ifcase\nr\relax%
+ \def\luameshvaldg@print{none}%
+ \or%
+ \def\luameshvaldg@print{points}%
+ \fi%
+}%
+%% the name of the point
+\define@key{drawGmsh}{meshpoint}[P]{\def\luameshvaldg@meshpoint{#1}}%
+%% the name of the color of drawing
+\define@key{drawGmsh}{color}[black]{\def\luameshvaldg@color{#1}}%
+%
+\presetkeys{drawGmsh}{tikz=false,scale, meshpoint,print=none,color}{}%
+%
+\newcommand{\drawGmsh}[2][]{%
+ % #1 : optionnal arguments
+ % #2 : the gmsh file
+ \setkeys{drawGmsh}{#1} %
+ \def\MeshPoint{\luameshvaldg@meshpoint}%
+ \ifKV@drawGmsh@tikz% if we are using tikz
+ \directlua{%
+ drawGmshTikZ("#2","\luameshvaldg@print","\luameshvaldg@scale","\luameshvaldg@color")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshvaldg@color}%
+ \directlua{%
+ drawGmshMP("#2","\luameshvaldg@print","\luameshvaldg@scale")%
+ }%
+ %
+ \fi%
+}%
+%%%%%%%%%%%%%%%% the gmshVoronoi command
+%% the user can write code (tikz or MP)
+%% before and after the generated code
+\define@boolkey{gmshVoronoiInc}{tikz}[true]{}%
+%% the scale
+\define@key{gmshVoronoiInc}{scale}[1cm]{\def\luameshval@gvi@scale{#1}}%
+%% print ponits ?
+\define@choicekey*{gmshVoronoiInc}{print}[\val\nr]{none, points}{%
+ \ifcase\nr\relax%
+ \def\luameshval@gvi@print{none}%
+ \or%
+ \def\luameshval@gvi@print{points}%
+ \fi%
+}%
+%% the name of the point
+\define@key{gmshVoronoiInc}{meshpoint}[P]{\def\luameshval@gvi@meshpoint{#1}}%
+%% the name of the circum point
+\define@key{gmshVoronoiInc}{circumpoint}[P]{\def\luameshval@gvi@circumpoint{#1}}%
+%% the mode for reading the points
+\define@choicekey*{gmshVoronoiInc}{delaunay}[\val\nr]{none, show}{%
+ \ifcase\nr\relax%
+ \def\luameshval@gvi@delaunay{none}%
+ \or%
+ \def\luameshval@gvi@delaunay{show}%
+ \fi%
+}%
+%% style dashed Delaunay
+\define@choicekey*{gmshVoronoiInc}{styleDelaunay}[\val\nr]{none, dashed}{%
+ \ifcase\nr\relax%
+ \def\luameshval@gvi@styleDelaunay{none}%
+ \or%
+ \def\luameshval@gvi@styleDelaunay{dashed}%
+ \fi%
+}%
+%% style dashed Voronoi
+\define@choicekey*{gmshVoronoiInc}{styleVoronoi}[\val\nr]{none, dashed}{%
+ \ifcase\nr\relax%
+ \def\luameshval@gvi@styleVoronoi{none}%
+ \or%
+ \def\luameshval@gvi@styleVoronoi{dashed}%
+ \fi%
+}%
+%% the name of the color of drawing
+\define@key{gmshVoronoiInc}{color}[black]{\def\luameshval@gvi@color{#1}}%
+%% the name of the color of drawing Voronoi
+\define@key{gmshVoronoiInc}{colorVoronoi}[red]{\def\luameshval@gvi@colorvoronoi{#1}}%
+%
+\presetkeys{gmshVoronoiInc}{tikz=false,scale,
+ meshpoint,circumpoint,print=none,color,colorVoronoi,delaunay=none,styleVoronoi=none, styleDelaunay=none}{}%
+%
+\newcommand*{\gmshVoronoiinc}[4][]{%
+ % #1 : optionnal arguments
+ % #2 : the gmsh file
+ % #3 : the code to place before the generated one
+ % #4 : the code to place after the generated one
+ \setkeys{gmshVoronoiInc}{#1} %
+ \def\MeshPoint{\luameshval@gvi@meshpoint}%
+ \def\CircumPoint{\luameshval@gvi@circumpoint}%
+ \ifKV@gmshVoronoiInc@tikz% if we are using tikz
+ \directlua{%
+ gmshVoronoiTikZinc("#2","\luaescapestring{\unexpanded{#3}}","\luaescapestring{\unexpanded{#4}}","\luameshval@gvi@print","\luameshval@gvi@scale","\luameshval@gvi@delaunay","\luameshval@gvi@color","\luameshval@gvi@colorvoronoi","\luameshval@gvi@styleDelaunay","\luameshval@gvi@styleVoronoi")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshval@gvi@color}%
+ \mplibcolor{\luameshmpcolorVoronoi}{\luameshval@gvi@colorvoronoi}%
+ \directlua{%
+ gmshVoronoiMPinc("#2","\luaescapestring{\unexpanded{#3}}","\luaescapestring{\unexpanded{#4}}","\luameshval@gvi@print","\luameshval@gvi@scale","\luameshval@gvi@delaunay","\luameshval@gvi@styleDelaunay","\luameshval@gvi@styleVoronoi")%
+ }%
+ %
+ \fi%
+}%
+%
+%%%%%%%%%%%%%%%% the gmshVoronoiBW command
+%% the code is complete and we don't have any callbacks
+\define@boolkey{gmshVoronoi}{tikz}[true]{}%
+%% the scale
+\define@key{gmshVoronoi}{scale}[1cm]{\def\luameshval@gv@scale{#1}}%
+%% print points
+\define@choicekey*{gmshVoronoi}{print}[\val\nr]{none, points}{%
+ \ifcase\nr\relax%
+ \def\luameshval@gv@print{none}%
+ \or%
+ \def\luameshval@gv@print{points}%
+ \fi%
+}%
+%% the name of the point
+\define@key{gmshVoronoi}{meshpoint}[P]{\def\luameshval@gv@meshpoint{#1}}%
+%% the name of the circum point
+\define@key{gmshVoronoi}{circumpoint}[P]{\def\luameshval@gv@circumpoint{#1}}%
+%% the mode for reading the points
+\define@choicekey*{gmshVoronoi}{delaunay}[\val\nr]{none, show}{%
+ \ifcase\nr\relax%
+ \def\luameshval@gv@delaunay{none}%
+ \or%
+ \def\luameshval@gv@delaunay{show}%
+ \fi%
+}%
+%% style dashed Delaunay
+\define@choicekey*{gmshVoronoi}{styleDelaunay}[\val\nr]{none, dashed}{%
+ \ifcase\nr\relax%
+ \def\luameshval@gv@styleDelaunay{none}%
+ \or%
+ \def\luameshval@gv@styleDelaunay{dashed}%
+ \fi%
+}%
+%% style dashed Voronoi
+\define@choicekey*{gmshVoronoi}{styleVoronoi}[\val\nr]{none, dashed}{%
+ \ifcase\nr\relax%
+ \def\luameshval@gv@styleVoronoi{none}%
+ \or%
+ \def\luameshval@gv@styleVoronoi{dashed}%
+ \fi%
+}%
+%% the name of the color of drawing
+\define@key{gmshVoronoi}{color}[black]{\def\luameshval@gv@color{#1}}%
+%% the name of the color of drawing Voronoi
+\define@key{gmshVoronoi}{colorVoronoi}[red]{\def\luameshval@gv@colorVoronoi{#1}}%
+%
+\presetkeys{gmshVoronoi}{tikz=false,scale, meshpoint,circumpoint,print=none,color,colorVoronoi,delaunay=none,styleVoronoi=none, styleDelaunay=none}{}%
+%
+\newcommand{\gmshVoronoi}[2][]{%
+ % #1 : optionnal arguments
+ % #2 : the gmsh file
+ \setkeys{gmshVoronoi}{#1} %
+ \def\MeshPoint{\luameshval@gv@meshpoint}%
+ \def\CircumPoint{\luameshval@gv@circumpoint}%
+ \ifKV@gmshVoronoi@tikz% if we are using tikz
+ \directlua{%
+ gmshVoronoiTikZ("#2","\luameshval@gv@print","\luameshval@gv@scale","\luameshval@gv@delaunay","\luameshval@gv@color","\luameshval@gv@colorVoronoi","\luameshval@gv@styleDelaunay","\luameshval@gv@styleVoronoi")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshval@gv@color}%
+ \mplibcolor{\luameshmpcolorVoronoi}{\luameshval@gv@colorVoronoi}%
+ \directlua{%
+ gmshVoronoiMP("#2","\luameshval@gv@print","\luameshval@gv@scale","\luameshval@gv@delaunay","\luameshval@gv@styleDelaunay","\luameshval@gv@styleVoronoi")%
+ }%
+ %
+ \fi%
+}%
+%
+%
+%
+%%%%%%%%%%%%%%%% the meshPolygon command
+%%
+\define@boolkey{meshPolygon}{tikz}[true]{}%
+
+%% the scale
+\define@key{meshPolygon}{scale}[1cm]{\def\luameshval@mp@scale{#1}}%
+%% print points
+\define@choicekey*{meshPolygon}{print}[\val\nr]{none, points,dotpoints}{%
+ \ifcase\nr\relax%
+ \def\luameshval@mp@print{none}%
+ \or%
+ \def\luameshval@mp@print{points}%
+ \or%
+ \def\luameshval@mp@print{dotpoints}%
+ \fi%
+}%
+%% the name of the point
+\define@key{meshPolygon}{meshpoint}[P]{\def\luameshval@mp@meshpoint{#1}}%
+%% the grid parameter
+\define@key{meshPolygon}{h}[0.2]{\def\luameshval@mp@h{#1}}%
+%% the mode for reading the points
+\define@choicekey*{meshPolygon}{mode}[\val\nr]{int, ext}{%
+ \ifcase\nr\relax%
+ \def\luameshval@mp@mode{int}%
+ \or%
+ \def\luameshval@mp@mode{ext}%
+ \fi%
+}%
+%% the mode for the generation of gridpoints
+\define@choicekey*{meshPolygon}{gridpoints}[\val\nr]{rect, perturb}{%
+ \ifcase\nr\relax%
+ \def\luameshval@mp@gridpoints{rect}%
+ \or%
+ \def\luameshval@mp@gridpoints{perturb}%
+ \fi%
+}%
+%% the different steps of the meshing
+\define@choicekey*{meshPolygon}{step}[\val\nr]{polygon, grid, points, mesh}{%
+ \ifcase\nr\relax%
+ \def\luameshval@mp@step{polygon}%
+ \or%
+ \def\luameshval@mp@step{grid}%
+ \or%
+ \def\luameshval@mp@step{points}%
+ \or%
+ \def\luameshval@mp@step{mesh}%
+ \fi%
+}%
+
+%% the name of the color of drawing
+\define@key{meshPolygon}{color}[black]{\def\luameshval@mp@color{#1}}%
+%% the name of the color of drawing Voronoi
+\define@key{meshPolygon}{colorPolygon}[red]{\def\luameshval@mp@colorPolygon{#1}}%
+%% the name of the color of drawing the bbox
+%
+\presetkeys{meshPolygon}{tikz=false,scale,mode=int,step=mesh,print=none,color,colorPolygon,h,meshpoint,gridpoints=rect}{}%
+%
+\newcommand{\meshPolygon}[2][]{%
+ % #1 : optionnal arguments
+ % #2 : the string containing the list of points
+ % (x1,y1);(x2,y2);... or the name file containing the points
+ \setkeys{meshPolygon}{#1} %
+ \def\MeshPoint{\luameshval@mp@meshpoint}%
+ \ifKV@meshPolygon@tikz% if we are using tikz
+ \directlua{%
+ drawMeshPolygonTikZ("#2","\luameshval@mp@mode","\luameshval@mp@h","\luameshval@mp@step","\luameshval@mp@print","\luameshval@mp@scale","\luameshval@mp@color","\luameshval@mp@colorPolygon","\luameshval@mp@gridpoints")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshval@mp@color}%
+ \mplibcolor{\luameshmpcolorPoly}{\luameshval@mp@colorPolygon}%
+ \directlua{%
+ drawMeshPolygonMP("#2","\luameshval@mp@mode","\luameshval@mp@h","\luameshval@mp@step","\luameshval@mp@print","\luameshval@mp@scale","\luameshval@mp@gridpoints")%
+ }%
+ %
+ \fi%
+}%
+%%%%%%%%%%%%%%%% the meshPolygonInc command
+%%
+\define@boolkey{meshPolygonInc}{tikz}[true]{}%
+
+%% the scale
+\define@key{meshPolygonInc}{scale}[1cm]{\def\luameshval@mpi@scale{#1}}%
+%% print points
+\define@choicekey*{meshPolygonInc}{print}[\val\nr]{none, points,dotpoints}{%
+ \ifcase\nr\relax%
+ \def\luameshval@mpi@print{none}%
+ \or%
+ \def\luameshval@mpi@print{points}%
+ \or%
+ \def\luameshval@mpi@print{dotpoints}%
+ \fi%
+}%
+%% the mode for the generation of gridpoints
+\define@choicekey*{meshPolygonInc}{gridpoints}[\val\nr]{rect, perturb}{%
+ \ifcase\nr\relax%
+ \def\luameshval@mpi@gridpoints{rect}%
+ \or%
+ \def\luameshval@mpi@gridpoints{perturb}%
+ \fi%
+}%
+%% the name of the point
+\define@key{meshPolygonInc}{meshpoint}[P]{\def\luameshval@mpi@meshpoint{#1}}%
+%% the grid parameter
+\define@key{meshPolygonInc}{h}[0.2]{\def\luameshval@mpi@h{#1}}%
+%% the mode for reading the points
+\define@choicekey*{meshPolygonInc}{mode}[\val\nr]{int, ext}{%
+ \ifcase\nr\relax%
+ \def\luameshval@mpi@mode{int}%
+ \or%
+ \def\luameshval@mpi@mode{ext}%
+ \fi%
+}%
+%% the different steps of the meshing
+\define@choicekey*{meshPolygonInc}{step}[\val\nr]{polygon, grid, points, mesh}{%
+ \ifcase\nr\relax%
+ \def\luameshval@mpi@step{polygon}%
+ \or%
+ \def\luameshval@mpi@step{grid}%
+ \or%
+ \def\luameshval@mpi@step{points}%
+ \or%
+ \def\luameshval@mpi@step{mesh}%
+ \fi%
+}%
+
+%% the name of the color of drawing
+\define@key{meshPolygonInc}{color}[black]{\def\luameshval@mpi@color{#1}}%
+%% the name of the color of drawing Voronoi
+\define@key{meshPolygonInc}{colorPolygon}[red]{\def\luameshval@mpi@colorPolygon{#1}}%
+%% the name of the color of drawing the bbox
+%
+\presetkeys{meshPolygonInc}{tikz=false,scale,mode=int,step=mesh,print=none,color,colorPolygon,h,meshpoint,gridpoints=rect}{}%
+%
+\newcommand{\meshPolygonInc}[4][]{%
+ % #1 : optionnal arguments
+ % #2 : the string containing the list of points
+ % (x1,y1);(x2,y2);... or the name file containing the points
+ % #3 : the code to place before the generated one
+ % #4 : the code to place after the generated one
+ \setkeys{meshPolygonInc}{#1} %
+ \def\MeshPoint{\luameshval@mpi@meshpoint}%
+ \ifKV@meshPolygonInc@tikz% if we are using tikz
+ \directlua{%
+ drawMeshPolygonTikZinc("#2","\luaescapestring{\unexpanded{#3}}","\luaescapestring{\unexpanded{#4}}","\luameshval@mpi@mode","\luameshval@mpi@h","\luameshval@mpi@step","\luameshval@mpi@print","\luameshval@mpi@scale","\luameshval@mpi@color","\luameshval@mpi@colorPolygon","\luameshval@mpi@gridpoints")%
+ }%
+ \else % we are using MP
+ \mplibcolor{\luameshmpcolor}{\luameshval@mpi@color}%
+ \mplibcolor{\luameshmpcolorPoly}{\luameshval@mpi@colorPolygon}%
+ \directlua{%
+ drawMeshPolygonMPinc("#2","\luaescapestring{\unexpanded{#3}}","\luaescapestring{\unexpanded{#4}}","\luameshval@mpi@mode","\luameshval@mpi@h","\luameshval@mpi@step","\luameshval@mpi@print","\luameshval@mpi@scale","\luameshval@mpi@gridpoints")%
+ }%
+ %
+ \fi%
+}%
diff --git a/macros/luatex/latex/luarandom/Changes b/macros/luatex/latex/luarandom/Changes
new file mode 100644
index 0000000000..29cf20e023
--- /dev/null
+++ b/macros/luatex/latex/luarandom/Changes
@@ -0,0 +1,4 @@
+..... luarandom.sty
+0.01 2018-12-15 first CTAN version (hv)
+
+
diff --git a/macros/luatex/latex/luarandom/README b/macros/luatex/latex/luarandom/README
new file mode 100644
index 0000000000..f51f725e01
--- /dev/null
+++ b/macros/luatex/latex/luarandom/README
@@ -0,0 +1,12 @@
+# luarandom.sty #
+
+This package provides some macros for creating random number
+lists between a nd b (Integers). This list can have multiple
+numbers or not.
+
+The macros for random numbers can only be used with LuaLaTeX!
+
+hvoss@tug.org
+
+
+%% $Id: README 862 2018-12-15 16:25:55Z herbert $
diff --git a/macros/luatex/latex/luarandom/doc/luarandom-doc.pdf b/macros/luatex/latex/luarandom/doc/luarandom-doc.pdf
new file mode 100644
index 0000000000..9f137411ad
--- /dev/null
+++ b/macros/luatex/latex/luarandom/doc/luarandom-doc.pdf
Binary files differ
diff --git a/macros/luatex/latex/luarandom/doc/luarandom-doc.tex b/macros/luatex/latex/luarandom/doc/luarandom-doc.tex
new file mode 100644
index 0000000000..6c17c1647d
--- /dev/null
+++ b/macros/luatex/latex/luarandom/doc/luarandom-doc.tex
@@ -0,0 +1,90 @@
+%% $Id: luarandom-doc.tex 862 2018-12-15 16:25:55Z herbert $
+\documentclass[fontsize=11pt,english,BCOR=10mm,DIV=12,bibliography=totoc,parskip=false,
+ headings=small, headinclude=false,footinclude=false,oneside,abstract=on]{pst-doc}
+
+\usepackage{xcolor,pstricks,multido}
+\usepackage{auto-pst-pdf-lua}
+
+\usepackage{luarandom}
+\let\pstMathFV\fileversion
+\lstset{pos=t,wide=true,language=[LaTeX]{TeX},basicstyle=\footnotesize\ttfamily}
+%
+\makeatletter
+\def\DefOfOperator{\@ifstar{\DefOfOperator@}{\DefOfOperator@@}}
+\def\DefOfOperator@#1#2#3#4{{\operator@font#1}:\left\{\begin{array}{ccc} #2&\to&#3\\
+x&\mapsto&#4\end{array}\right.}
+\def\DefOfOperator@@#1#2#3{{\operator@font#1}:\left\{\begin{array}{ccc} #2&\to&#3\\
+x&\mapsto&{\operator@font#1}(x)\end{array}\right.}
+\makeatother
+
+
+\begin{document}
+
+\title{\texttt{luarandom}}
+\subtitle{Create a list of random numbers with or without multiple values; v. 0.01}
+\author{Herbert Vo\ss}
+\docauthor{Herbert Vo\ss}
+\date{\today}
+\maketitle
+
+\tableofcontents
+
+
+\section{Random numbers}
+Package \LPack{luarandom} supports the creation of random number lists where a number will
+appear only once or multiple times. With Lua\TeX\ all random numbers are build with the help of Lua which
+has the advantage that there will be no problem with \TeX's limited parameter stack size.
+However, this package will \emph{not} run with other \TeX-engines than Lua\LaTeX.
+
+
+\section{The Macros}
+\begin{BDef}
+\Lcs{makeSimpleRandomNumberList}\Largb{Left}\Largb{Right}\Largb{N}\% multiple values possible\\
+\Lcs{makeRandomNumberList}\Largb{Left}\Largb{Right}\Largb{N} \% no multiple values!\\
+\Lcs{getNumberFromList}\Largb{number}
+\end{BDef}
+
+
+The list of the random numbers is saved in the Lua table \texttt{RandomNumbers}.
+
+
+\section{Examples}
+
+
+\begin{LTXexample}[pos=t]
+\small
+\makeSimpleRandomNumberList{1}{30}{30}% with multiple values (hopefully ;-)
+\multido{\iA=1+1}{30}{\getNumberFromList{\iA}, }
+
+\makeRandomNumberList{1}{30}{30}% without multiple values
+\multido{\iA=1+1}{30}{\getNumberFromList{\iA}, }
+\end{LTXexample}
+
+
+
+The following example uses PSTricks related packages which cannot be run directly
+with Lua\LaTeX. The package \LPack{auto-pst-pdf-lua} will convert the PSTricks stuff
+in the baclground into PDF images which will be included in a second run.
+
+
+\begin{LTXexample}[pos=t]
+\newcounter{RandNo}\setcounter{RandNo}{1}
+\def\n{10} \def\N{\the\numexpr\n*\n}
+\makeRandomNumberList{1}{\N}{\N}
+\begin{pspicture}(\n,\n)
+ \psgrid[subgriddiv=0,gridlabels=0pt]
+ \multido{\rRow=0.5+1.0}{\n}{\multido{\rCol=0.5+1.0}{\n}{%
+ \rput(\rCol,\rRow){\textcolor{randomhsb}{\getNumberFromList{\theRandNo}}}%
+ \stepcounter{RandNo}}}
+\end{pspicture}
+\end{LTXexample}
+
+
+\section{The code}
+
+\lstinputlisting{luarandom.sty}
+
+\printindex
+
+
+\end{document}
diff --git a/macros/luatex/latex/luarandom/latex/luarandom.sty b/macros/luatex/latex/luarandom/latex/luarandom.sty
new file mode 100644
index 0000000000..a0be7f3c49
--- /dev/null
+++ b/macros/luatex/latex/luarandom/latex/luarandom.sty
@@ -0,0 +1,76 @@
+% $Id: luarandom.sty 862 2018-12-15 16:25:55Z herbert $
+%%
+%% This is file `luarandom.sty'.
+%%
+%% IMPORTANT NOTICE:
+%%
+%% luarandom Copyright (C) 2019- Herbert Voss <hvoss@tug.org>
+%%
+%% This package may be distributed under the terms of the LaTeX Project
+%% Public License, as described in lppl.txt in the base LaTeX distribution.
+%% Either version 1.3 or, at your option, any later version.
+%%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{luarandom}[2018/12/16 v 0.01 package for random numbers]
+\RequirePackage{ifluatex}
+\def\lua@nl{^^J\space\space\space\space}
+\newcommand\lua@PackageError[2]{\PackageError{luarandom}{\lua@nl #1^^J}{#2}}
+\ifluatex\else
+ \lua@PackageError{%
+ "You are not using LuaTeX\app@nl
+ the lua definitions will not be available!}
+ {If you run the source from a GUI then set
+ the compiler "lualatex" in the
+ preferences.}%
+\fi
+
+\RequirePackage{luacode}
+\begin{luacode*}
+RandomNumbers = {}
+
+function allFound(R)
+ local r1 = R[1]
+ local i
+ for i=2,#R do
+ r1 = r1 and R[i]
+ if not r1 then return false end
+ end
+ return true
+end
+
+function makeRandomNumberList(l,r,n)
+ RandomNumbers = {}
+ math.randomseed(os.time())
+ local R = {}
+ local i,j
+ for i=1,n do R[i] = false end
+ repeat
+ local rand = math.random(l,r)
+ if not R[rand] then
+ R[rand] = true
+ RandomNumbers[#RandomNumbers+1] = rand
+ end
+ until allFound(R)
+end
+
+function makeSimpleRandomNumberList(l,r,n)
+ RandomNumbers = {}
+ math.randomseed(os.time()/3)
+ local i
+ for i=1,n do RandomNumbers[#RandomNumbers+1] = math.random(l,r) end
+end
+
+function getRand(i)
+ tex.print(RandomNumbers[i])
+end
+\end{luacode*}
+
+\def\makeRandomNumberList#1#2#3{%
+ \directlua{makeRandomNumberList(#1,#2,#3)}}
+\def\makeSimpleRandomNumberList#1#2#3{%
+ \directlua{makeSimpleRandomNumberList(#1,#2,#3)}}
+\def\getNumberFromList#1{\directlua{getRand(#1)}}
+
+
+\endinput
diff --git a/macros/luatex/latex/luasseq/README b/macros/luatex/latex/luasseq/README
new file mode 100644
index 0000000000..b6cb5d9204
--- /dev/null
+++ b/macros/luatex/latex/luasseq/README
@@ -0,0 +1,6 @@
+Version 2015-07-16 contains compatibility fixed for lualatex bundled with TeXLive 2014.
+
+Required for use: luasseq.lua and luasseq.sty
+
+To get luasseq.sty: lualatex luasseq.ins (requires luasseq.dtx)
+To get the documentation luasseq.pdf: lualatex luasseq.dtx
diff --git a/macros/luatex/latex/luasseq/luasseq.dtx b/macros/luatex/latex/luasseq/luasseq.dtx
new file mode 100644
index 0000000000..349ee9f9df
--- /dev/null
+++ b/macros/luatex/latex/luasseq/luasseq.dtx
@@ -0,0 +1,992 @@
+%
+% ^^A This is file luasseq.dtx. First LaTeX the accompanying file luasseq.ins
+% ^^A to produce the package file luasseq.sty.
+% ^^A Then LaTeX this file to produce the documentation of the luasseq package.
+% ^^A
+% ^^A (c) 2003-2010 Tilman Bauer. Freely distributable under the LaTeX Project Public License (LPPL)
+% ^^A
+% \ifthenelse{0=1}{
+%<*never>
+\documentclass{ltxdoc}
+\usepackage{luasseq}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\begin{document}
+\DocInput{luasseq.dtx} \PrintIndex \PrintChanges
+\end{document}
+%</never>
+% }{}
+
+%
+% \changes{v1.0}{November 12, 2003}{First release of code and documentation}
+% \changes{v1.01}{November 15, 2003}{Bug fix with clipping after a ssgoto}
+% \changes{v1.02}{November 18, 2003}{Bug fix that would mess up page numbering in some cases}
+% \changes{v1.03}{December 11, 2003}{Added examples to documentation, bug fix in grid drawing}
+% \changes{v1.04}{January 19, 2004}{Up to nine drops per square now possible, added customization of the grid}
+% \changes{v1.05}{December 9, 2004}{Added support for different packing strategies; support for dotted lines}
+% \changes{v1.06}{August 1, 2005}{sseqxstep=0 will now suppress printing of horizontal label; similarly sseqystep=0 and vertical labels}
+% \changes{v2.0a}{July 16, 2007}{Completely recoded the graphics for using pgf instead of xyPic. Many new features. Consult the manual.}
+% \changes{v2.0}{April 9, 2009}{bug fix with arrows leaving the chart}
+% \ifthenelse{0=1}{
+%<*package>
+\NeedsTeXFormat{LaTeX2e}
+
+\ProvidesPackage{luasseq}[2010/11/06 ver 2.1]
+
+\RequirePackage{ifthen,calc,pifont}
+\RequirePackage{pgf}[2006/01/01]
+\RequirePackage{xkeyval}
+\usepgflibrary{snakes}
+
+\newboolean{debug}
+\setboolean{debug}{false}
+
+\DeclareOption{ps}{\errmessage{sseq: ps/nops is deprecated}}
+\DeclareOption{nops}{\errmessage{sseq: ps/nops is deprecated}}
+\DeclareOption{dvips}{\errmessage{sseq: deprecated option dvips ignored}}
+\DeclareOption{xdvi}{\errmessage{sseq: deprecated option xdvi ignored}}
+\DeclareOption{color}{\errmessage{sseq: deprecated option color ignored}}
+\DeclareOption{nocolor}{\errmessage{sseq: deprecated option nocolor ignored}}
+\DeclareOption{debug}{\setboolean{debug}{true}}
+
+\ProcessOptions
+
+%</package>
+% }{}
+%
+% \title{Typesetting spectral sequences in \LaTeX\ with luasseq.sty}
+% \author{Tilman Bauer\footnote{tilman@alum.mit.edu}}
+% \date{November 6, 2010}
+%
+% \MakeShortVerb{\|}
+%
+% \maketitle
+%
+% \section{Introduction}
+%
+% The present package, \texttt{luasseq}, facilitates the typesetting of mathematical objects called \emph{spectral sequence charts} (henceforth simply called ``chart''). It is a re-coded and largely code-compatible version of the older package |sseq| with new functionality and much higher typesetting speed and lower memory requirements. It requires to be run with |luatex|, a \TeX extension by the Lua programming language nowadays included in many \TeX distributation.
+%
+% From a typographical point of view, a chart is a two-dimensional grid with integer coordinates; at every position (x,y), there may be any number of symbols (usually dots, little circles or boxes, digits etc.), possibly decorated with labels, and between any two such symbols may or may not be a connection---e.~g., a line, an arrow, or some curved line.
+%
+% The \texttt{luasseq} package is built on top of the pgf package by Till Tantau. Previous versions of |sseq| (pre-2.0) were based on the graphics package xy-Pic; the current version produces higher quality output and allows for more customization, at the cost of requiring a fairly recent \TeX distribution (or, at least, the packages |pgf| and |xkeyval| should be installed and the former should be no older than from 2006) as well as LuaTeX.
+%
+% This package automates the following functions:
+%
+% \begin{itemize}
+% \item Automatic drawing of the grid and the axis labels;
+% \item Clipping. Anything outside the displayed portion of the chart is clipped away. This has the advantage that a large chart, which does not fit on a page, can be cut into smaller pieces which contain exactly the same \texttt{sseq} code, but different clipping regions.
+% \item Arranging. Multiple symbols dropped at the same integer coordinates will be automatically arranged so that they usually do not overlap. The algorithm for doing this is rather primitive, but still powerful enough for most applications.
+% \item Simplified ``turtle graphics'' syntax. Every primitive element of a chart is typeset with a macro defined by \texttt{sseq}.
+% \item Control structures (loops, if/then, etc.) are allowed inside the \texttt{sseq} environment.
+% \end{itemize}
+%
+%
+% \section{Loading}
+%
+% The |luasseq| package is loaded with
+%
+% |\usepackage{luasseq}|.
+%
+% All options from previous versions of |sseq| are deprecated.
+%
+% \section{Basic usage}
+%
+% \DescribeEnv{sseq}
+% A spectral sequence is typeset by the code
+%
+% |\begin{sseq}[|\meta{options...}|]{|\meta{x-range}|}{|\meta{y-range}|}|
+%
+% \meta{sseq commands...}
+%
+% |\end{sseq}|
+%
+% In the simplest case, a range is of the form \meta{min}|...|\meta{max}, where \meta{min} and \meta{max} are two integers with \meta{min} $\leq$ \meta{max}.
+%
+% Thus |\begin{sseq}{2...5}{-3...-1}\end{sseq}| will typeset
+% \[\begin{sseq}{2...5}{-3...-1}\end{sseq}.\]
+%
+% It is also possible for ranges to be a comma-separated list of ranges of the above form, e.g. |0...3,8...10|. In this case, the chart is broken into several pieces. Here is an example:
+%
+% \noindent\begin{minipage}{\textwidth/2}
+% \begin{verbatim}\begin{sseq}{-1...3,5...8,20...24}
+% {0...2,4...4}
+%\end{sseq}\end{verbatim}\end{minipage}\begin{minipage}{\textwidth/2}\begin{sseq}{-1...3,5...8,20...24}{0...2,4...4}\end{sseq}\bigskip\end{minipage}
+%
+% The minimum value of one block always has to be at least two greater than the maximum of the previous block; |0...2,3...5| is illegal.
+%
+%
+% The following options are defined for the |sseq| environment. Options in bold face are the default setting.
+% \begin{description}
+% \item[|grid=|]\meta{none,\textbf{crossword},go,dots,chess} Select an option of drawing the background grid.
+%
+% \begin{tabular}{ccccc}
+% none & crossword & go & dots & chess\\
+% \begin{sseq}[entrysize=2mm,labels=none,grid=none]{4}{4}\end{sseq} &
+% \begin{sseq}[entrysize=2mm,labels=none,grid=crossword]{4}{4}\end{sseq} &
+% \begin{sseq}[entrysize=2mm,labels=none,grid=go]{4}{4}\end{sseq} &
+% \begin{sseq}[entrysize=2mm,labels=none,grid=dots]{4}{4}\end{sseq} &
+% \begin{sseq}[entrysize=2mm,labels=none,grid=chess]{4}{4}\end{sseq}
+% \end{tabular}
+%
+% With the |chess| option, all squares with coordinates (x,y) with x+y even are white.
+% \item[|gridstroke=|\meta{thickness}] For the grid types |crossword| and |go|, this sets the line width. The default is .1pt. A good option is to set it to the resolution of your output device.
+%
+% \item[|gapsize=|\meta{size},|xgapsize=|\meta{size},|ygapsize=|\meta{size}] This sets the size of the gap between two pieces in a range (i.e. in the above example, the distance between the $3$-column and the $5$-column). The |gapsize| option sets both |xgapsize| and |ygapsize| to the same given value. The default is 3mm.
+%
+% \item[|entrysize=|\meta{size}] Specify the size of each square of the grid. The default is 4mm.
+% \item[|labels=|\meta{labels},|xlabels=|\meta{labels},|ylabels=|\meta{labels}] Specify how labels on the x- and y-axis are drawn, respectively. The |labels| option sets both |xlabels| and |ylabels| to the same. Possible values are |none|, |numbers|, or an explicit list of semicolon-separated labels |{|\meta{$x_1$}|;|\meta{$x_2$}|;|\dots|}| which will be typeset in math mode. If the range consists of more than one block, the labels for the separate blocks are separated by a comma; see the example below. The default is |numbers|. Inside the label strings, one can use the following placeholder:
+% \begin{description}
+% \item[|\&n|] will be replaced by the coordinate
+% \item[|\&c|] will be replaced by the number of the piece in a multi-piece range (starting with 0)
+% \item[|\&i|] will be replaced by the index within the current piece (starting with 0)
+% \end{description}
+% \item[|labelstep=|\meta{step},|xlabelstep=|\meta{step},|ylabelstep=|\meta{step}] Frequently it is not desirable that every label is printed, but only every second or third label. This can be done by setting this option to a positive integer. The default is 2.
+%
+% The following example illustrates how labels can be customized:
+%
+% \noindent\begin{minipage}{\textwidth*2/3}
+% \begin{verbatim}\begin{sseq}[xlabelstep=1,ylabelstep=4,
+% xlabels={x_{&n},y_1;y_2;y_3}]
+% {1...3,10...11}{0...4}
+%\end{sseq}\end{verbatim}\end{minipage}\begin{minipage}{\textwidth/3}\begin{sseq}[xlabelstep=1,ylabelstep=4,xlabels={x_{&n},y_1;y_2;y_3}]{1...3,10...11}{0...4}\end{sseq}\end{minipage}
+% \item[|leak=|\meta{size},|xleak=|\meta{size},|yleak=|\meta{size}] When a line is drawn from within the visible range of the chart to a point outside, or vice versa, this line will protrude beyond the boundaries of the grid. These values define how far; the default is one third of |gapsize|. Do not set this to a value larger than half of |gapsize|.
+% \item[|arrows=|\meta{arrow type}] Sets the default arrow type to use in the spectral sequence. Here are some default arrow types:
+%
+%\begin{sseq}[grid=none,labels=none]{0...3}{-2...0}
+% \ssdrop{} \ssmove 3 0 \ssdrop{\;to} \ssstroke[arrowto=to] \ssmove {-3}{-1}
+% \ssdrop{} \ssmove 3 0 \ssdrop{\;stealth} \ssstroke[arrowto=stealth] \ssmove {-3}{-1}
+% \ssdrop{} \ssmove 3 0 \ssdrop{\;latex} \ssstroke[arrowto=latex]
+%\end{sseq}
+%
+% Other arrow types can be defined by the user or loaded from a library; see the pgf package documentation for details.
+%
+% \item[|packing=|] \meta{\textbf{auto},horizontal,vertical,diagonal} Specify which algorithm you want to use to arrange multiple objects in a grid square. The following charts illustrate the effect:
+%
+% \begin{sseq}[packing=auto,ylabels={\hbox to 1.8cm{auto}},xlabelstep=1,entrysize=.6cm]{1...5}{0...0}
+% \ssmove 1 0 \ssdropbull\ssmove 1 0 \ssdropbull\ssdropbull
+% \ssmove 1 0 \ssdropbull\ssdropbull\ssdropbull
+% \ssmove 1 0 \ssdropbull\ssdropbull\ssdropbull\ssdropbull
+% \ssmove 1 0 \ssdropbull\ssdropbull\ssdropbull\ssdropbull\ssdropbull
+% \end{sseq}
+% \hspace{1cm}
+% \begin{sseq}[packing=diagonal,ylabels={\hbox to 1.8cm{diagonal}},xlabelstep=1,entrysize=.6cm]{1...5}{0...0}
+% \ssmove 1 0 \ssdropbull\ssmove 1 0 \ssdropbull\ssdropbull
+% \ssmove 1 0 \ssdropbull\ssdropbull\ssdropbull
+% \ssmove 1 0 \ssdropbull\ssdropbull\ssdropbull\ssdropbull
+% \ssmove 1 0 \ssdropbull\ssdropbull\ssdropbull\ssdropbull\ssdropbull
+% \end{sseq}
+% \\[.5cm]
+% \begin{sseq}[packing=vertical,ylabels={\hbox to 1.8cm{vertical}},xlabelstep=1,entrysize=.6cm]{1...5}{0...0}
+% \ssmove 1 0 \ssdropbull\ssmove 1 0 \ssdropbull\ssdropbull
+% \ssmove 1 0 \ssdropbull\ssdropbull\ssdropbull
+% \ssmove 1 0 \ssdropbull\ssdropbull\ssdropbull\ssdropbull
+% \ssmove 1 0 \ssdropbull\ssdropbull\ssdropbull\ssdropbull\ssdropbull
+% \end{sseq}
+% \hspace{1cm}
+% \begin{sseq}[packing=horizontal,ylabels={\hbox to 1.8cm{horizontal}},xlabelstep=1,entrysize=.6cm]{1...5}{0...0}
+% \ssmove 1 0 \ssdropbull\ssmove 1 0 \ssdropbull\ssdropbull
+% \ssmove 1 0 \ssdropbull\ssdropbull\ssdropbull
+% \ssmove 1 0 \ssdropbull\ssdropbull\ssdropbull\ssdropbull
+% \ssmove 1 0 \ssdropbull\ssdropbull\ssdropbull\ssdropbull\ssdropbull
+% \end{sseq}
+%
+% \bigskip
+% \emph{Notice for advanced users:} you can define your own packing algorithm, say |mypack|, by defining a Lua function |sseq_packing_mypack(i,n)| which returns a pair of coordinates (in \TeX{} scaled points) indicating the offset of the center of object |i| out of a total of |n| dropped objects from the lower left corner of the square.
+% \end{description}
+%
+% \section{sseq commands}
+%
+% Inside an |sseq| environment there is defined a virtual cursor, which starts out at position $(0,0)$ (even if that position is not within the visible range!). Most drawing commands are relative to the current cursor position; this facilitates reusage of |sseq| code when a certain pattern has to be repeated, as is often the case in mathematical spectral sequences.
+%
+%
+% \ifthenelse{0=1}{
+%
+%
+
+\directlua0{dofile(kpse.find_file("luasseq.lua","lua"))}
+
+
+ \definecolor{sseqgr}{gray}{0.65}
+ \definecolor{sslightgr}{gray}{0.9}
+ \definecolor{ssred}{rgb}{1,0,0}
+ \definecolor{ssblack}{rgb}{0,0,0}
+\newcommand{\ssconncolor}{ssblack}
+\newcommand{\sslabelcolor}{ssblack}
+\newcommand{\ssplacecolor}{ssblack}
+
+%% ^^A Initialization
+\newcount\sseqxstart \sseqxstart=0
+\newcount\sseqystart \sseqystart=0
+\newdimen\sseq@dimen % ^^A To convert dimensions to scaled points (in TeX)
+\newbox\sseqbox % ^^A To compute the size of dropped objects (in TeX)
+
+
+
+
+
+\long\def\for #1=#2\to#3\do#4\od{#1=#2 \sseq@for #1\to #3\do #4\od}
+\long\def\sseq@for #1\to #2\do #3\od{%
+ \ifnum #1>#2 \else
+ #3\relax
+ \advance #1 by 1
+ \def\tempcmd{\sseq@for #1\to #2\do #3\od}%
+ \expandafter\tempcmd
+ \fi
+}
+
+\def\@eval#1#2{%
+ \edef\tempcmd{\noexpand#1#2}%
+ \tempcmd
+}
+
+%
+%
+%
+% ^^A This replaces \ssplacespecial in the xy version.
+% ^^A Arguments: 1,2 = x- and y-coordinates
+% ^^A 3 = pgf shape
+% ^^A 4 = pgf path usage
+% ^^A 5 = contents
+%
+\def\ss@placespecial#1#2#3#4#5{
+\directlua0{sseq_drop_object(#1,#2,[[#3]],[[#4]],[[#5]],[[\ssplacecolor]])}}
+
+\newcommand{\ssplace}[3]{
+ \ss@placespecial{#1}{#2}{rectangle}{discard}{#3}
+}
+
+\newcommand{\ssplaceboxed}[3]{
+ \ss@placespecial{#1}{#2}{rectangle}{stroke}{\ensuremath{#3}}
+}
+
+\newcommand{\ssplacecircled}[3]{
+ \ss@placespecial{#1}{#2}{circle}{stroke}{\ensuremath{#3}}
+}
+
+% }{}
+%
+% \DescribeMacro{\ssmoveto}
+% To move the cursor to the absolute position (x,y), use |\ssmoveto{x}{y}|.
+%
+% \ifthenelse{0=1}{
+\newcommand{\ssmoveto}[2]{\directlua0{sseq_moveto(#1,#2)}}
+% }{}
+% \DescribeMacro{\ssmove}
+% To move the cursor relative to the current position by (x,y), use |\ssmove{x}{y}|.
+%
+% \iffalse
+\newcommand{\ssmove}[2]{\directlua0{sseq_move(#1,#2)}}
+% \fi
+%
+%
+% \DescribeMacro{\ssdrop}
+% The command |\ssdrop[|\meta{options}|]{|\meta{mathcode}|}| will display \emph{mathcode} at the current cursor position. The argument is always interpreted in math mode.
+% The following options can be given:
+% \begin{description}
+% \item[|circled|] A circle is drawn around the object.
+% \item[|boxed|] A box is drawn around the object.
+% \item[|color=|\meta{color}] The object is drawn in the specified color. Any \LaTeX{} color can be used, e.g. predefined colors such as |black|, |blue|, |PineGreen|, etc., or user defined rgb colors.
+% \item[|name=|\meta{name}] This is equivalent to issuing |\ssname{|\meta{name}|}| after |\ssdrop|, see below.
+% \end{description}
+% If the argument is |\bullet|, |\circle|, or |\square|, the object is replaced by a better-spaced graphics primitive.
+%
+% \ifthenelse{0=1}{
+\define@key{sseqdrop}{circled}[true]{\newif\ifKV@sseqdrop@circled\csname KV@sseqdrop@circled#1\endcsname}
+\define@key{sseqdrop}{boxed}[true]{\newif\ifKV@sseqdrop@boxed\csname KV@sseqdrop@boxed#1\endcsname}
+\define@key{sseqdrop}{color}{\def\sseq@color{#1}}
+\define@key{sseqdrop}{name}{\def\sseq@name{#1}}
+%
+\def\ssdrop{\@ifnextchar[\sseq@drop{\sseq@drop[]}}
+\def\sseq@drop[#1]#2{
+ \presetkeys{sseqdrop}{circled=false,boxed=false,color=\ssplacecolor,name=\relax}{}
+ \setkeys{sseqdrop}{#1}
+ \ifKV@sseqdrop@circled
+ \directlua0{sseq_drop_object_here("circle","stroke",[[#2]],"\sseq@color")}
+ \else
+ \ifKV@sseqdrop@boxed
+ \directlua0{sseq_drop_object_here("rectangle","stroke",[[#2]],"\sseq@color")}
+ \else
+ \directlua0{sseq_drop_object_here("rectangle","discard",[[#2]],"\sseq@color")}
+ \fi
+ \fi
+ \def\temp{\relax}
+ \ifx\sseq@name\temp \else
+ \@eval\ssname{{\sseq@name}}
+ \fi
+}
+% }{}
+%
+% ^^A The following are commands purely kept for compatibility.
+%
+% \iffalse
+%
+\newcommand{\ssdropbull}{\ssdrop{\bullet}}
+\newcommand{\ssdropboxed}[1]{\ssdrop[boxed]{#1}}
+\newcommand{\ssdropcircled}[1]{\ssdrop[circled]{#1}}
+% \fi
+%
+% \DescribeMacro{\ssname}
+% |\ssname{|\meta{name}|}| gives the object most recently dropped the name \meta{name}. If the previous command is one of the drop commands, then it refers to that object; if it is not, then if there is one and only one object at the current cursor position, it refers to that object; if that is also not the case, an error message is generated. \emph{New in luasseq:} The argument |name| is a space-separated list of alphanumerical strings, such as |3 alpha beta2 beta2|; the order of the strings is irrelevant, thus this name is equal to |beta2 alpha 3 beta2|.
+%
+% \iffalse
+\def\ssname#1{\directlua0{sseq_name("#1")}}
+% \fi
+%
+% \DescribeMacro{\ssgoto}
+% After an object has been given a \meta{name} with |\ssname|, the cursor can be moved back to that object at any time by issuing |\ssgoto{|\meta{name}|}|. This becomes necessary when there is more than one object in one position.
+%
+% \iffalse
+\newcommand{\ssgoto}[1]{\directlua0{sseq_goto("#1")}}
+% \fi
+%
+% \DescribeMacro{\ssprefix}
+% Often the mechanism provided by |\ssname|/|\ssgoto| is not flexible enough to deal with repeated code. In that case, |\ssprefix{|\meta{prefix}|}| defines a ``multiplier'' for all names that follow; i.e. a |\ssname{|\meta{name}|}| after such a command will really define a name \meta{prefix} \meta{name} (with a space in between, so that the order is irrelevant). However, since |\ssgoto| also observes the prefix, |\ssgoto{|\meta{name}|}| will still work. |\ssprefix| commands can be iterated; the prefices are then concatenated.
+%
+% \iffalse
+\newcommand{\ssprefix}[1]{\directlua0{sseq_prefix("#1")}}
+% \fi
+%
+% \DescribeMacro{\ssresetprefix}
+% This command resets the prefix defined by (a sequence of) |\ssprefix| to the empty prefix.
+%
+% \iffalse
+\newcommand{\ssresetprefix}{\directlua0{sseq_reset_prefix()}}
+% \fi
+%
+% \DescribeMacro{\ssabsgoto}
+% This is a version of |\ssgoto| that ignores the current prefix.
+%
+% \ifthenelse{0=1}{
+\newcommand{\ssabsgoto}[1]{\directlua0{sseq_abs_goto("#1")}}
+% }{}
+%
+% \DescribeMacro{\ssdroplabel}
+% This command decorates the previously typeset object with a label. It is used in the form
+% |\ssdroplabel[|\meta{options...}|]{|\meta{label}|}|.
+%
+% The \meta{label} will then be typeset next to the most recently dropped object (for a definition for what that is, exactly, consult the description of |\ssname|). If you specify one of |U|,|LU|,|RU|,|L|,|R|,|LD|,|RD|,|D| as an option, the label is positioned relative to the object it labels (default: |U|=up).
+% As in |\ssdrop|, an option |color=|\meta{color} will typeset the label in the \LaTeX{} color \meta{color}.
+%
+% \ifthenelse{0=1}{
+\define@key{sseqlabel}{color}{\def\sseq@color{#1}}
+\define@key{sseqlabel}{pos}{\def\sseq@position{#1}}
+\define@key{sseqlabel}{U}[]{\def\sseq@position{U}}
+\define@key{sseqlabel}{LU}[]{\def\sseq@position{LU}}
+\define@key{sseqlabel}{L}[]{\def\sseq@position{L}}
+\define@key{sseqlabel}{LD}[]{\def\sseq@position{LD}}
+\define@key{sseqlabel}{D}[]{\def\sseq@position{D}}
+\define@key{sseqlabel}{RD}[]{\def\sseq@position{RD}}
+\define@key{sseqlabel}{R}[]{\def\sseq@position{R}}
+\define@key{sseqlabel}{RU}[]{\def\sseq@position{RU}}
+%
+\def\ssdroplabel{\@ifnextchar[\sseq@droplabel{\sseq@droplabel[]}}
+\def\sseq@droplabel[#1]#2{
+ \def\sseq@position{L}
+ \presetkeys{sseqlabel}{color=\ssplacecolor}{}
+ \setkeys{sseqlabel}{#1}
+ \directlua0{sseq_drop_label("\sseq@position","\sseq@color",[[#2]])}
+}
+% }{}
+%
+% \DescribeMacro{\ssdropextension}
+% The command |\ssdropextenstion[|\meta{options...}|]| has only optional arguments and is rather specialized. It refers to a previously dropped object (see |\ssname|), draws a circle or box around it (default: a circle, can be changed by giving the option |boxed|, and considers that circle a new object. Thus it produces a new object that is attached to the original object, and not subject to the packing algorithm that tries to make objects non-overlapping. Further options are |color| and |name| with the same usage as in |\ssdrop|.
+%
+% \ifthenelse{0=1}{
+\define@key{sseqdropext}{circled}[true]{\newif\ifKV@sseqdrop@circled\csname KV@sseqdrop@circled#1\endcsname}
+\define@key{sseqdropext}{boxed}[true]{\newif\ifKV@sseqdrop@boxed\csname KV@sseqdrop@boxed#1\endcsname}
+\define@key{sseqdropext}{color}{\def\ssplacecolor{#1}}
+\define@key{sseqdropext}{name}{\def\sseq@name{#1}}
+%
+\def\ssdropextension{\@ifnextchar[\sseq@dropextension{\sseq@dropextension[]}}
+\def\sseq@dropextension[#1]{
+ \edef\sseq@savecolor{\ssplacecolor}
+ \def\sseq@name{\relax}
+ \presetkeys{sseqdropext}{circled=false,boxed=false}{}
+ \setkeys{sseqdrop}{#1}
+ \ifKV@sseqdrop@boxed
+ \directlua0{sseq_drop_extension("rectangle","stroke","\sseq@color")}
+ \else
+ \directlua0{sseq_drop_extension("circle","stroke","\sseq@color")}
+ \fi
+
+ \def\temp{\relax}
+ \ifx\sseq@name\temp \else
+ \@eval\ssname{{\sseq@name}}
+ \fi
+}
+%
+% }{}
+%
+%
+% \DescribeMacro{\ssstroke}
+% There are two ways of typesetting connections between objects. One of them is the command |\ssstroke|, which
+% requires that the cursor recently moved from one object to another. It takes no non-optional arguments and typesets a
+% line between the two objects. Example: Suppose there are two objects, which have been given the names |a| and |b|
+% by |\ssname|. Drawing a line between them is achieved by the command |\ssgoto{a} \ssgoto{b} \ssstroke|.
+%
+% The following options can be given in the form |\ssstroke[options]|:
+% \begin{description}
+% \item[|color=|color] the connection is drawn in the given \LaTeX{} color
+% \item[|curve=|value] the connection is curved to the left by an amount proportional to the value given.
+% \item[{|dashed|[=dashing type]}] the connection is drawn in a dashed style. The optional \emph{dashing type} is an
+% expression of the form |{{a}{b}...}|, where each of a, b, \dots is a length (like 2pt or 3mm). The line then consists of
+% a stroke of length |a|, followed by a gap of length |b|, followed by a stroke of length ... etc.
+% \item[{|dotted|[=dashing type]}] the connection is drawn in a dotted style. If the optional dashing type is given,
+% this option behaves exactly like |dashed|.
+% \item[{|arrowfrom|[=arrow style]}] An arrow is drawn at the beginning of the line. The global arrow style can be overridden
+% by specifying an arrow style.
+% \item[{|arrowto|[=arrow style]}] An arrow is drawn at the end of the line.
+% \item[|void|] This option says that the target of the connection is not another object; instead, the connection should just point into the correct direction.
+% \end{description}
+%
+% \ifthenelse{0=1}{
+%
+\define@key{sseqstroke}{color}{\def\sseq@color{#1}}
+\define@key{sseqstroke}{curve}{\def\sseq@curve{#1}}
+\define@key{sseqstroke}{dashed}[{{2pt}{2pt}}]{\def\sseq@dashing{#1}}
+\define@key{sseqstroke}{dotted}[{{.5pt}{2pt}}]{\def\sseq@dashing{#1}}
+\define@key{sseqstroke}{arrowfrom}[\sseq@defaultarrowstyle]{\def\sseq@arrowfrom{\ssinversearrowhead[#1]}}
+\define@key{sseqstroke}{arrowto}[\sseq@defaultarrowstyle]{\def\sseq@arrowto{\ssarrowhead[#1]}}
+\define@key{sseqstroke}{void}[true]{\newif\ifKV@sseqstroke@void\csname KV@sseqstroke@void#1\endcsname}
+%
+\def\ssstroke{\@ifnextchar[\sseq@stroke{\sseq@stroke[]}}
+\def\sseq@stroke[#1]{
+ \def\sseq@dashing{}
+ \def\sseq@curve{}
+ \def\sseq@arrowfrom{}
+ \def\sseq@arrowto{}
+ \presetkeys{sseqstroke}{void=false,color=\ssconncolor}{}
+ \setkeys{sseqstroke}{#1}
+ \ifKV@sseqstroke@void % ^^A a void line
+ \directlua0{sseq_late_connection("\sseq@dashing","\sseq@curve","\sseq@color",false,true)}
+ \else
+ \directlua0{sseq_late_connection("\sseq@dashing","\sseq@curve","\sseq@color",false,false)}
+ \fi
+ \sseq@arrowfrom
+ \sseq@arrowto
+}
+% }{}
+%
+% ^^A Keep these for compatibility
+% \ifthenelse{0=1}{
+\newcommand{\sscurve}[1]{\sseq@stroke[curve=#1]}
+\newcommand{\ssdashedstroke}{\sseq@stroke[dashed]}
+\newcommand{\ssdashedcurve}[1]{\sseq@stroke[dashed,curve=#1]}
+\newcommand{\ssdottedstroke}{\sseq@stroke[dotted]}
+\newcommand{\ssdottedcurve}[1]{\sseq@stroke[dotted,curve=#1}
+% }{}
+%
+% \DescribeMacro{\ssarrowhead}
+% \DescribeMacro{\ssinversearrowhead}
+% Instead of specifying |arrowfrom| or |arrowto| in |ssstroke|, you can issue these commands afterwards to typeset an arrow head onto the beginning resp. end of the connection most recently typeset. There is one optional parameter |[|\meta{arrow style}|]| which selects the arrow tips of style \meta{arrow style}, cf. the documentation of |\ssstroke|.
+%
+% \ifthenelse{0=1}{
+\newcommand{\ssarrowhead}[1][\sseq@defaultarrowstyle]{\directlua0{sseq_add_arrow("arrowto","#1")}}
+\newcommand{\ssinversearrowhead}[1][\sseq@defaultarrowstyle]{\directlua0{sseq_add_arrow("arrowfrom","#1")}}
+% }{}
+%
+% \DescribeMacro{\ssline}
+% A second way of producing connections is |\ssline[|\meta{options...}|]{|\meta{x}|}{|\meta{y}|}|. This command draws a connection from the most recent object (cf. |\ssname|) to an object at relative position (\meta{x},\meta{y}), and it moves that cursor to that new position. If |\ssline| is followed by a drop command, then the line is attached to this newly dropped object (note the slightly out-of-order execution!), no matter how many other objects there are at the target position. However, if it is not followed by a drop command, then there has to be one and only one object at the target position, otherwise an error message is generated. The options are exactly the same as for |\ssstroke|.
+%
+% \ifthenelse{0=1}{
+%
+\define@key{sseqline}{color}{\def\sseq@color{#1}}
+\define@key{sseqline}{curve}{\def\sseq@curve{#1}}
+\define@key{sseqline}{dashed}[{{2pt}{2pt}}]{\def\sseq@dashing{#1}}
+\define@key{sseqline}{dotted}[{{.5pt}{2pt}}]{\def\sseq@dashing{#1}}
+\define@key{sseqline}{arrowfrom}[\sseq@defaultarrowstyle]{\def\sseq@arrowfrom{\ssinversearrowhead[#1]}}
+\define@key{sseqline}{arrowto}[\sseq@defaultarrowstyle]{\def\sseq@arrowto{\ssarrowhead[#1]}}
+\define@key{sseqline}{void}[true]{\newif\ifKV@sseqline@void\csname KV@sseqline@void#1\endcsname}
+%
+\def\ssline{\@ifnextchar[\sseq@line{\sseq@line[]}}
+\def\sseq@line[#1]#2#3{
+ \def\sseq@dashing{}
+ \def\sseq@curve{}
+ \edef\sseq@arrowfrom{}
+ \edef\sseq@arrowto{}
+ \presetkeys{sseqline}{void=false,color=\ssconncolor}{}
+ \setkeys{sseqline}{#1}
+ \ifKV@sseqline@void % ^^A a void line
+ \directlua0{sseq_assert_source(); sseq_finish_pos(); sseq_move(#2,#3); sseq_late_connection("\sseq@dashing","\sseq@curve","\sseq@color",false,true)}
+ \else
+ \directlua0{sseq_open_connection("\sseq@dashing","\sseq@curve","\sseq@color",false,false); sseqposx = sseqposx+#2; sseqposy = sseqposy+#3}
+ \fi
+ \sseq@arrowfrom
+ \sseq@arrowto
+}
+\newcommand{\sscurvedline}[3]{\ssline[curve=#3]{#1}{#2}}
+\newcommand{\ssdashedline}[2]{\ssline[dashed]{#1}{#2}}
+\newcommand{\sscurveddashedline}[3]{\ssline[curve=#3,dashed]{#1}{#2}}
+% }{}
+%
+% \DescribeMacro{\ssarrow}
+% |\ssarrow[|\meta{options...}|]{|\meta x|}{|\meta y|}| is an abbreviation for\\
+% |\ssline[|\meta{options...}|,arrowto]{|\meta x|}{|\meta y|}|
+%
+% \ifthenelse{0=1}{
+\newcommand{\ssarrow}[3][]{
+ \ssline[arrowto,#1]{#2}{#3}
+}
+\newcommand{\sscurvedarrow}[3]{\ssline[arrowto,curve=#3]{#1}{#2}}
+\newcommand{\ssdashedarrow}[2]{\ssline[arrowto,dashed]{#1}{#2}}
+\newcommand{\sscurveddashedarrow}[3]{\ssline[arrowto,dashed,curve=#3]{#1}{#2}}
+%
+%
+\def\ssvoidline{\@ifnextchar[\sseq@voidline{\sseq@voidline[]}}
+\def\sseq@voidline[#1]#2#3{
+ \def\sseq@dashing{}
+ \def\sseq@curve{}
+ \edef\sseq@arrowfrom{}
+ \edef\sseq@arrowto{}
+ \presetkeys{sseqline}{color=\ssconncolor}{}
+ \setkeys{sseqline}{#1}
+ \directlua0{sseq_void_line("\sseq@dashing","\sseq@curve","\sseq@color",#2,#3)}
+ \sseq@arrowfrom
+ \sseq@arrowto
+}
+
+\newcommand{\ssvoidarrow}[2]{\ssvoidline{#1}{#2}\ssarrowhead}
+\newcommand{\ssinversevoidarrow}[2]{\ssvoidline{#1}{#2}\ssinversearrowhead}
+
+% }{}
+%
+% \DescribeMacro{\ssbullstring}
+% |\ssbullstring{x}{y}{n}| is a shortcut for |\ssdrop{\bullet}| followed by $n-1$ copies of |\ssline{x}{y} \ssdrop{\bullet}|.
+% \iffalse
+\newcommand{\ssbullstring}[3]{
+\directlua0{sseq_bullstring(#1,#2,#3,[[\ssplacecolor]])}
+}
+% \fi
+%
+% \DescribeMacro{\ssinfbullstring}
+% |\ssinfbullstring{x}{y}{n}| is a shortcut for |\ssdrop{\bullet}| followed by $n-1$ copies of |\ssline{x}{y} \ssdrop{\bullet}|, followed by |\ssarrow[void]{x}{y}|. The cursor finishes on the last bullet.
+%
+% \iffalse
+\newcommand{\ssinfbullstring}[3]{
+\ssbullstring{#1}{#2}{#3}
+\ssvoidarrow{#1}{#2}
+}
+% \fi
+%
+% \DescribeMacro{\ssgrayout}
+% (new in |luasseq|) This command, which has as only optional argument a color, can be given at any point in the |sseq| code and changes the color of the most recent object (cf. |\ssname|) to the color given (gray by default), along with all lines connected to this object. Any line drawn to that object after issuing |ssgrayout| will not be affected. This is used for typesetting differentials in spectral sequences.
+%
+% \iffalse
+\newcommand{\ssgrayout}[1][gray]{\directlua0{sseq_grayout("#1")}}
+% \fi
+%
+% \section{Examples}
+%
+%
+% \newtheorem{ex}{Example}
+%
+%\begin{ex}
+%The following code generates a $5 \times 5$ grid with labels between $-2$ and $2$. The size of every square is $(.8cm)^2$, and labels are written on every square. The grid is chess-style. A bullet is drawn at coordinate (0,0).
+%
+%\noindent
+%\begin{minipage}{\textwidth/2}
+%\begin{verbatim}
+%\begin{sseq}[grid=chess,labelstep=1,
+% entrysize=.8cm]{-2...2}{-2...2}
+%\ssdrop{\bullet}
+%\end{sseq}
+%\end{verbatim}
+%\end{minipage}
+%\begin{minipage}{\textwidth/2}
+%\def\sseqgridstyle{\ssgridchess}
+%\begin{sseq}[grid=chess,labelstep=1,entrysize=.8cm]{-2...2}{-2...2}
+%\ssdropbull
+%\end{sseq}
+%\end{minipage}
+%\end{ex}
+%
+%
+%\begin{ex}
+%This example demonstrates how to move the cursor and drop objects and labels. Note how the last bullet, which is dropped at position (8,4), is outside the grid and thus clipped. The grid style is the default (|crossword|). \bigskip
+%
+%\noindent
+%\begin{minipage}{\textwidth/2}
+%\begin{verbatim}
+%\begin{sseq}{0...6}{0...6}
+%\ssdrop{\bullet}
+%\ssdroplabel[U]{(0,0)}
+%\ssmove 2 1
+%\ssdrop{\clubsuit}
+%\ssdropextension
+%\ssdropextension
+%\ssdropextension
+%\ssdroplabel[RU]{(2,1)}
+%\ssmove 0 4
+%\ssdropcircled{8}
+%\ssmoveto 5 4
+%\ssdropboxed{\spadesuit}
+%\ssdroplabel[R]{(5,4)}
+%\ssmove 3 0
+%\ssdrop{\bullet}
+%\end{sseq}
+%\end{verbatim}
+%\end{minipage}
+%\begin{minipage}{\textwidth/2}
+%\begin{sseq}{0...6}{0...6}
+%\ssdrop{\bullet}
+%\ssdroplabel[U]{(0,0)}
+%\ssmove 2 1
+%\ssdrop{\clubsuit}
+%\ssdropextension
+%\ssdropextension
+%\ssdropextension
+%\ssdroplabel[RU]{(2,1)}
+%\ssmove 0 4
+%\ssdropcircled{8}
+%\ssmoveto 5 4
+%\ssdropboxed{\spadesuit}
+%\ssdroplabel[R]{(5,4)}
+%\ssmove 3 0
+%\ssdrop{\bullet}
+%\end{sseq}
+%\end{minipage}
+%\end{ex}
+%
+%\begin{ex}
+%This example illustrates the different ways of drawing connections.
+%\bigskip
+%
+%\noindent
+%\begin{minipage}{.6\textwidth}
+%\begin{verbatim}
+%\begin{sseq}[grid=go]{0...9}{0...6}
+%\ssdrop{\bullet}
+%\ssmove 4 4
+%\ssdrop{\bullet} \ssstroke
+%\ssstroke[curve=-.5]
+%\ssstroke[curve=.1,dashed] \ssarrowhead
+%\ssmove 4 0 \ssdropcircled{T}
+%\ssstroke
+%\ssmoveto 0 6
+%\ssdrop{\bullet}
+%\ssline {1} {-1} \ssdrop{\bullet}
+%\ssline[curve=.2] 7 {-1}
+%\end{sseq}
+%\end{verbatim}
+%\end{minipage}
+%\begin{minipage}{.4\textwidth}
+%\begin{sseq}[grid=go]{0...9}{0...6}
+%\ssdrop{\bullet}
+%\ssmove 4 4
+%\ssdrop{\bullet} \ssstroke
+%\ssstroke[curve=-.5]
+%\ssstroke[curve=.1,dashed] \ssarrowhead
+%\ssmove 4 0 \ssdropcircled{T}
+%\ssstroke
+%\ssmoveto 0 6
+%\ssdrop{\bullet}
+%\ssline {1} {-1} \ssdrop{\bullet}
+%\ssline[curve=.2] 7 {-1}
+%\end{sseq}
+%\end{minipage}
+%\end{ex}
+%
+%\begin{ex}
+%This sample code shows how to use names for objects dropped in spectral sequence; this is particularly useful when more than one item is dropped at one position. It also demonstrates void arrows, which do not need a target.
+%\bigskip
+%
+%\noindent
+%\begin{minipage}{\textwidth*2/3}
+%\begin{verbatim}
+%\begin{sseq}[grid=dots]{0...4}{0...4}
+%\ssdrop{\bullet} \ssname{a} \ssvoidarrow 0 1
+%\ssdrop{\bullet} \ssname{b} \ssvoidarrow 0 1
+%\ssdrop{\bullet} \ssname{c} \ssvoidarrow 0 1
+%\ssdropextension \ssname{d}
+%\ssmove 4 4
+%\ssdrop{\bullet} \ssname{e}
+%\ssdrop{\bullet} \ssname{f}
+%\ssgoto a \ssgoto f \ssstroke
+%\ssgoto e \ssstroke
+%\ssgoto d \sscurve{.2}
+%\ssline 4 0 \ssdrop{\bullet}
+%\end{sseq}
+%\end{verbatim}
+%\end{minipage}
+%\begin{minipage}{\textwidth/3}
+%
+%\begin{sseq}[grid=dots]{0...4}{0...4}
+%\ssdrop{\bullet} \ssname{a}\ssvoidarrow 0 1
+%\ssdrop{\bullet} \ssname{b}\ssvoidarrow 0 1
+%\ssdrop{\bullet} \ssname{c}\ssvoidarrow 0 1
+%\ssdropextension \ssname{d}
+%\ssmove 4 4
+%\ssdrop{\bullet} \ssname{e}
+%\ssdrop{\bullet} \ssname{f}
+%\ssgoto a \ssgoto f \ssstroke
+%\ssgoto e \ssstroke
+%\ssgoto d \sscurve{.2}
+%\ssline 4 0 \ssdrop{\bullet}
+%\end{sseq}
+%\end{minipage}
+%\end{ex}
+%
+%\begin{ex}
+% This final example shows how to take advantage of loops, prefices, and |\ssgrayout|
+%
+%\noindent
+%\begin{minipage}[t]{\textwidth*1/3}
+%\begin{verbatim}
+%\newcount\cnti
+%\def\drawstring#1#2{
+% \ifnum#2=1
+% \ssdrop{\bullet}
+% \ssname{#1}
+% \else
+% \ssdrop{\bullet}
+% \ssname{#1}
+% \ssline 1 0
+% \ssprefix{i}
+% \cnti=#2
+% \advance \cnti by -1
+% \drawstring{#1}
+% {\the\cnti}
+% \fi
+%}
+%\end{verbatim}
+%\end{minipage}
+%\begin{minipage}[t]{\textwidth*1/3}
+%\begin{verbatim}
+%\def\drawlines#1#2#3{
+% \ifnum#3>0
+% \cnti=#3
+% \ssgoto{#1} \ssgoto{#2}
+% \ssstroke \ssarrowhead
+% \ssprefix{i}
+% \advance \cnti by -1
+% \drawlines{#1}{#2}
+% {\the\cnti}
+% \fi
+%}
+%\end{verbatim}
+%\end{minipage}
+%\begin{minipage}[t]{\textwidth*1/3}
+%\begin{verbatim}
+%\begin{sseq}[grid=none]
+% {0...8}{0...3}
+%\ssmoveto 0 3
+%\drawstring{a}{8}
+%\ssmoveto 0 3
+%\ssresetprefix
+%\drawstring{b}{8}
+%\ssmoveto 0 0
+%\ssresetprefix
+%\drawstring{c}{8}
+%\ssresetprefix
+%\drawlines{c}{a}{8}
+%\ssresetprefix
+%\drawlines{b}{i i c}{6}
+%\ssresetprefix
+%\ssgoto{c}
+%\ssgrayout[red]
+%\ssgoto{c i i i i}
+%\ssgrayout[green]
+%\end{sseq}
+%\end{verbatim}
+%\end{minipage}
+%
+% \bigskip
+%
+% The result is shown in the following chart:
+%\newcount\cnti
+%\def\drawstring#1#2{
+% \ifnum#2=1
+% \ssdrop{\bullet} \ssname{#1}
+% \else
+% \ssdrop{\bullet} \ssname{#1}
+% \ssline 1 0
+% \ssprefix{i}
+% \cnti=#2
+% \advance \cnti by -1
+% \drawstring{#1}
+% {\the\cnti}
+% \fi
+%}
+%\def\drawlines#1#2#3{
+% \ifnum#3>0
+% \cnti=#3
+% \ssgoto{#1} \ssgoto{#2}
+% \ssstroke \ssarrowhead
+% \ssprefix{i}
+% \advance \cnti by -1
+% \drawlines{#1}{#2}
+% {\the\cnti}
+% \fi
+%}
+%\begin{tabular}{l}
+%\begin{sseq}[grid=none]{0...8}{0...3}
+%\ssmoveto 0 3
+%\drawstring{a}{8}
+%\ssmoveto 0 3
+%\ssresetprefix
+%\drawstring{b}{8}
+%\ssmoveto 0 0
+%\ssresetprefix
+%\drawstring{c}{8}
+%\ssresetprefix
+%\drawlines{c}{a}{8}
+%\ssresetprefix
+%\drawlines{b}{i i c}{6}
+%\ssresetprefix
+%\ssgoto{c} \ssgrayout[red]
+%\ssgoto{c i i i i} \ssgrayout[green]
+%\end{sseq}
+%\end{tabular}
+%\end{ex}
+%
+%\section{Final remarks}
+%
+% This package has been extremely helpful for my own mathematical work, and it most likely carries the characteristics of a tool initially developed for my own purposes only. Before any published version, there was a version of |sseq| which was much less powerful; and what is worse, this version is not fully upward compatible with the previous one. (Every object that was dropped was forgotten right afterwards; thus connections could not properly connect objects but were always drawn from the center of the box corresponding to a coordinate to the center of the box corresponding to the target coordinate, resulting in fairly ugly pictures.) The published version 1.0 of |sseq| used xy-Pic and had most of the functionality of the current package, but was extremely slow and a memory hog. Version 2.0 of |sseq| was recoded using the graphics package pgf, improving the typesetting greatly. The current version 2.1 of luasseq migrated most of the \TeX code to Lua, which greatly improved typesetting speed and memory requirements, while enabling new features such as |\ssgrayout|, more flexible labelling and packing algorithms, and, again, type quality.
+%
+% Many things remain to be desired:
+%
+% \begin{itemize}
+% \item While objects are placed next to each other, no attempt is made not to make connections overlap
+% \item Labelling lines between objects is not supported.
+% \item Have some features that make repetitions of sseq code redundant (which occurs for example when an $E^r$ term of a spectral sequence has a polynomial generator).
+% \end{itemize}
+%
+% Given time and leisure, I might or might not implement one or more of these improvements and make them available; of course, I would be even more happy if somebody else did it. (Needless to say, I would request that I be informed of and sent the enhancements.) I do guarantee that all further versions of |luasseq| that might or might not be written by me will be compatible with the documented code written for this version.
+%
+% \endinput
+%
+%
+%
+% ^^A options that can be passed to sseq
+%
+\define@key{sseq}{grid}{
+ \directlua0{sseqgriddrawer = sseq_grid_#1}
+}
+%
+\define@key{sseq}{entrysize}{
+ \sseq@dimen=#1
+ \directlua0{sseqentrysize=\number\sseq@dimen} % In LUA, it's all in scaled points.
+}
+
+\define@key{sseq}{labels}{
+ \setkeys{sseq}{xlabels=#1,ylabels=#1}
+}
+\define@key{sseq}{xlabels}{
+ \def\temp{#1}
+ \def\temptwo{none}
+ \ifx\temp\temptwo
+ \directlua0{sseqxlabels = sseq_parse_label_list("")}
+ \else
+ \def\temptwo{numbers}
+ \ifx\temp\temptwo
+ \directlua0{sseqxlabels = sseq_parse_label_list("&n")}
+ \else
+ \directlua0{sseqxlabels = sseq_parse_label_list([[#1]])}
+ \fi
+ \fi
+}
+\define@key{sseq}{ylabels}{
+ \def\temp{#1}
+ \def\temptwo{none}
+ \ifx\temp\temptwo
+ \directlua0{sseqylabels = sseq_parse_label_list("")}
+ \else
+ \def\temptwo{numbers}
+ \ifx\temp\temptwo
+ \directlua0{sseqylabels = sseq_parse_label_list("&n")}
+ \else
+ \directlua0{sseqylabels = sseq_parse_label_list([[#1]])}
+ \fi
+ \fi
+}
+
+\define@key{sseq}{xlabelstep}{
+\directlua0{sseqxstep=#1}
+}
+\define@key{sseq}{ylabelstep}{
+\directlua0{sseqystep=#1}
+}
+
+\define@key{sseq}{labelstep}{\setkeys{sseq}{xlabelstep=#1}\setkeys{sseq}{ylabelstep=#1}}
+
+\define@key{sseq}{gapsize}{\setkeys{sseq}{xgapsize=#1}\setkeys{sseq}{ygapsize=#1}}
+\define@key{sseq}{xgapsize}{
+\sseq@dimen=#1
+\directlua0{sseqxgap=\number\sseq@dimen}
+}
+\define@key{sseq}{ygapsize}{
+\sseq@dimen=#1
+\directlua0{sseqygap=\number\sseq@dimen}
+}
+\define@key{sseq}{leak}{\setkeys{sseq}{xleak=#1}\setkeys{sseq}{yleak=#1}}
+\define@key{sseq}{xleak}{
+\sseq@dimen=#1
+\directlua0{sseqxleak=\number\sseq@dimen}
+}
+\define@key{sseq}{yleak}{
+\sseq@dimen=#1
+\directlua0{sseqyleak=\number\sseq@dimen}
+}
+
+\define@key{sseq}{gridstroke}{
+\sseq@dimen=#1
+\directlua0{sseqgridstrokethickness=\number\sseq@dimen}
+}
+
+\define@key{sseq}{arrows}{
+\def\sseq@defaultarrowstyle{#1}
+\directlua0{sseqdefaultarrowstyle="#1"}
+}
+
+\define@key{sseq}{packing}{
+\directlua0{sseqpacking = sseq_pack_#1}
+}
+%
+% ^^A Defaults
+%
+\def\sseq@defaultarrowstyle{to}
+
+\directlua0{sseq_set_defaults()}
+
+\newenvironment{sseq}[3][]{%
+\begingroup
+%
+\directlua0{sseq_init()}
+%
+% ^^A Start the PGF environment
+\begin{pgfpicture}
+%
+% ^^A Initialize some local counters and dimensions
+%
+%
+% ^^A Parse arguments
+%
+%
+\setkeys{sseq}{#1}
+%
+%
+%
+\directlua0{sseq_setup_ranges("#2","#3",\the\sseqxstart,\the\sseqystart)}
+%
+%
+\directlua0{sseq_drawgrid()}
+%
+\directlua0{sseq_drawlabels()}
+%
+% ^^A Move to turtle to (0,0)
+\directlua0{sseqboxno = \the\sseqbox} % ^^A Needed to measure the size of entries
+}
+%
+%
+% ^^A PART FOR \end{sseq}
+%
+{
+\relax
+\ssmoveto 0 0
+\directlua0{sseq_position_objects(); sseq_dump_code()}
+\end{pgfpicture}
+\endgroup
+}
+%
+% \Finale
diff --git a/macros/luatex/latex/luasseq/luasseq.ins b/macros/luatex/latex/luasseq/luasseq.ins
new file mode 100644
index 0000000000..1c1418e1a5
--- /dev/null
+++ b/macros/luatex/latex/luasseq/luasseq.ins
@@ -0,0 +1,4 @@
+\def\batchfile{luasseq.ins}
+\input docstrip.tex
+\generateFile{luasseq.sty}{t}{\from{luasseq.dtx}{package}}
+\endbatchfile
diff --git a/macros/luatex/latex/luasseq/luasseq.lua b/macros/luatex/latex/luasseq/luasseq.lua
new file mode 100644
index 0000000000..79082efce7
--- /dev/null
+++ b/macros/luatex/latex/luasseq/luasseq.lua
@@ -0,0 +1,894 @@
+-- to do: clean up dtx file of remnants of classical sseq code
+-- to do: documentation
+
+function sseq_init()
+-- sseqobject is a 2D-array containing arrays of all the nodes that are dropped at (x,y)
+-- Thus the first object dropped at (2,3) is sseqobject[2][3][1].
+-- The object itself is a dictionary, containing:
+-- name a given name
+-- code the TeX code (in math mode) to typeset
+-- extends if it's an extension, then what it extends
+-- color the color
+-- nodetype the pgf node type (circle etc)
+-- cmd pgf code for drawing it -- with one %s for the color
+-- posx,posy the absolute position on the picture (in sp) -- determined at the end
+ sseqobject = {}
+-- sseqname is a dictionary containing all the given names of dropped objects
+-- Its value is a dictionary, containing
+-- x, y, n the triple index in the sseqobject array
+ sseqname = {}
+-- sseqlabel is an array of labels of sseqobjects
+-- Its values are dictionaries, containing
+-- x,y,n the triple the label belongs to
+-- pos one of L,LU,U,RU,R,RD,D,LD
+-- code the TeX code (in math mode) to typeset
+-- color the color
+ sseqlabel = {}
+-- sseqconnection is an array containing all connection (lines)
+-- the connection itself is a dictionary, containing:
+-- from an array (x,y,n) if n=0 then source void
+-- to an array (x,y,n) if n=0 then target void
+-- color the color
+-- curving a number denoting the curving factor
+-- dashing the pgf dashing code
+-- arrowfrom the arrowstyle at from (or nil)
+-- arrowto the arrowstyle at to (or nil)
+ sseqconnection = {}
+--
+-- Initialize some global variables
+--
+ sseqcurrentindex = nil
+ sseqpreviousindex = nil
+ sseqopenconnection = nil
+
+ sseqxstart = 0 -- minimal x
+ sseqystart = 0 -- minimal y
+
+ sseqgriddrawer = sseq_grid_crossword
+ sseqgridstrokethickness = 6554 -- 0.1pt in sp
+
+ sseqxlabels = sseq_parse_label_list("&n")
+ sseqylabels = sseq_parse_label_list("&n")
+
+ sseqprefix = {}
+ sseqposx, sseqposy = 0,0
+ sseqcurrabsx, sseqcurrabsy = 0,0
+ sseq_set_defaults()
+end
+
+function sseq_set_defaults()
+ sseqentrysize = 745860 -- 0.4 cm in scaled points
+ sseqxgap = 559409 -- 0.3 cm in scaled points
+ sseqygap = 559409
+ sseqxstep = 2 -- every other label is drawn
+ sseqystep = 2
+ sseqdefaultarrowstyle = "to"
+ ssequsescolor = true
+ sseqpacking = sseq_pack_auto
+end
+
+
+-- parselabelrange: input = a string of the form a...b,c...d, etc.
+-- defstart: the default start index
+-- return = an array of dictionaries
+-- min a number
+-- max a number
+function parselabelrange(s,defstart)
+ local res = {}
+ local mini,maxi,found
+ for rng in string.gmatch(s.."," , "([^,]+)") do
+ found,_,mini,maxi = string.find(rng,"([+-]?[0-9]+)%.%.%.([+-]?[0-9]+)")
+ if not found then
+ mini = defstart
+ maxi = tonumber(rng)
+ if not maxi then error("invalid range : "..rng) end
+ maxi = maxi+defstart-1
+ else
+ mini = tonumber(mini)
+ maxi = tonumber(maxi)
+ end
+ table.insert(res,{min = mini, max = maxi})
+ end
+ return res
+end
+
+function sseq_setup_ranges(xr,yr,defxstart,defystart)
+ sseqxrange = parselabelrange(xr,defxstart)
+ sseqyrange = parselabelrange(yr,defystart)
+end
+
+function sseq_get_rangepart(range,x,gap)
+ local pos = 0
+ for j,rng in ipairs(range) do
+ if x >= rng.min and x <= rng.max then
+ return pos,pos+(rng.max+1-rng.min)*sseqentrysize
+ else
+ pos = pos+(rng.max+1-rng.min)*sseqentrysize+gap
+ end
+ end
+end
+
+function sseq_getabsoluteposition(range,x,gap)
+ local pos = 0
+ for j,rng in ipairs(range) do
+ if x >= rng.min and x <= rng.max then
+ return pos+sseqentrysize*(x-rng.min),false
+ end
+ pos = pos+(rng.max+1-rng.min)*sseqentrysize+gap
+ end
+end
+
+function sseq_getcoords(x,y)
+ local xpos,xout,ypos,yout
+ xpos = sseq_getabsoluteposition(sseqxrange,x,sseqxgap)
+ ypos = sseq_getabsoluteposition(sseqyrange,y,sseqygap)
+ return xpos, ypos
+end
+
+function sseq_grid_none()
+end
+
+function sseq_grid_crossword(x,y,width,height)
+ tex.print("\\pgfsetlinewidth{"..sseqgridstrokethickness.."sp}")
+ tex.print("\\pgfpathgrid[stepx="..sseqentrysize.."sp,stepy="..sseqentrysize.."sp]{\\pgfpointorigin}{\\pgfpoint{"..width*sseqentrysize.."sp}{"..height*sseqentrysize.."sp}}")
+ tex.print("\\pgfusepath{stroke}")
+end
+
+function sseq_grid_go(x,y,width,heigh)
+ tex.print("\\pgfsetlinewidth{"..sseqgridstrokethickness.."sp}")
+ tex.print("\\pgftransformxshift{"..(sseqentrysize/2).."sp}")
+ tex.print("\\pgftransformyshift{"..(sseqentrysize/2).."sp}")
+ tex.print("\\pgfpathgrid[stepx="..sseqentrysize.."sp,stepy="..sseqentrysize.."sp]{\\pgfpoint{"..(-sseqentrysize/2).."sp}{"..(-sseqentrysize/2).."sp}}{\\pgfpoint{"..(width*sseqentrysize-sseqentrysize/2).."sp}{"..(height*sseqentrysize-sseqentrysize/2).."sp}}")
+ tex.print("\\pgfusepath{stroke}")
+end
+
+function sseq_grid_dots(x,y,width,height)
+ tex.print("\\pgfsetlinewidth{1pt}")
+ tex.print("\\pgfsetdash{{1pt}{"..(sseqentrysize-65536).."sp}}{"..(sseqentrysize/2+32768).."sp}")
+ tex.print("\\pgftransformxshift{"..(sseqentrysize/2).."sp}")
+ tex.print("\\pgftransformyshift{"..(sseqentrysize/2).."sp}")
+ tex.print("\\pgfpathgrid[stepx="..sseqentrysize.."sp,stepy="..sseqentrysize.."sp]{\\pgfpoint{"..(-sseqentrysize/2).."sp}{"..(-sseqentrysize/2).."sp}}{\\pgfpoint{"..(width*sseqentrysize-sseqentrysize/2).."sp}{"..(height*sseqentrysize-sseqentrysize/2).."sp}}")
+ tex.print("\\pgfusepath{stroke}")
+end
+
+function sseq_grid_chess(x,y,width,height)
+ tex.print("\\pgfsetcolor{sslightgr}")
+ if ((x+y) % 2) == 1 then -- invert everything by first drawing a solid gray rectangle
+ -- and then draw the grid in white. This way, even bidegree
+ -- is always white.
+ tex.print("\\pgfpathrectangle{\\pgfpoint{0sp}{0sp}}{\\pgfpoint{"
+ ..(width*sseqentrysize).."sp}{"..(height*sseqentrysize).."sp}}")
+ tex.print("\\pgfusepath{fill}")
+ tex.print("\\pgfsetcolor{white}")
+ end
+
+ tex.print("\\pgfsetlinewidth{"..sseqentrysize.."sp}")
+
+ tex.print("\\pgfsetdash{{"..sseqentrysize.."sp}{"..sseqentrysize.."sp}}{"..sseqentrysize.."sp}")
+
+
+ tex.print("\\pgftransformxshift{"..(sseqentrysize/2).."sp}")
+ tex.print("\\pgftransformyshift{"..(sseqentrysize/2).."sp}")
+ tex.print("\\pgfpathgrid[stepx="..(sseqentrysize*2).."sp,stepy="..(sseqentrysize*2).."sp]{\\pgfpoint{"..(-sseqentrysize/2).."sp}{"..(-sseqentrysize/2).."sp}}{\\pgfpoint{"..(width*sseqentrysize-sseqentrysize/2).."sp}{"..(height*sseqentrysize-sseqentrysize/2).."sp}}")
+ tex.print("\\pgfusepath{stroke}")
+end
+
+function sseq_drawgrid() -- draws the background grid. This seems like pgf patterns are made
+ -- for this purpose, but you can't specify a phase for patterns,
+ -- so they are useless except for ornamental purposes.
+ local xmin,ymin,width,heigt
+ for x,xrng in ipairs(sseqxrange) do
+ for y,yrng in ipairs(sseqyrange) do
+ xmin, ymin = sseq_getcoords(xrng.min,yrng.min)
+ tex.print("\\begin{pgfscope}")
+ tex.print("\\pgftransformshift{\\pgfpoint{"..xmin.."sp}{"..ymin.."sp}}")
+ width = (xrng.max+1)-xrng.min
+ height = (yrng.max+1)-yrng.min
+ sseqgriddrawer(xrng.min,yrng.min,width,height)
+ tex.print("\\end{pgfscope}")
+ end
+ end
+end
+
+-- A label list has the form x1;x2;...;xn,y1;y2;...;yn,... where x1 etc are labels
+-- A label may contain the placeholders:
+-- &n = actual coordinate
+-- &c = number of chunk (begin with 0)
+-- &i = index within the chunk (begin with 0)
+
+function sseq_parse_label_list(s)
+ local res = {}
+ local chunk = 0
+ local index
+
+ for rng in string.gmatch(s.."," , "([^,]*),") do
+ res[chunk] = {}
+ index = 0
+ for label in string.gmatch(rng..";", "([^;]*);") do
+ res[chunk][index] = label
+ index = index+1
+ end
+ chunk = chunk+1
+ end
+ return res
+end
+
+function sseq_format_label(label, n,c,i)
+ local res
+ res = string.gsub(label,"&n",n)
+ res = string.gsub(res,"&c",c)
+ res = string.gsub(res,"&i",i)
+ res = string.gsub(res,"&&","&")
+ return res
+end
+
+function sseq_label_fromlist(n,c,i,list)
+-- will return list[c][i] unless this is out of range, then take the last one given
+ local chunks = #list
+ local chunklen
+ local chunk
+ if list[0] then chunks = chunks+1 else return "" end
+ chunk = list[math.min(chunks-1,c)]
+ chunklen = #chunk
+ if chunk[0] then chunklen = chunklen+1 end
+ return sseq_format_label(chunk[math.min(chunklen-1,i)],n,c,i)
+end
+
+
+function sseq_draw_horizontal_labels(range)
+ local k
+
+ if sseqxstep == 0 then return end -- old-fashioned way of disabling labels
+ for c,rng in ipairs(range) do
+ k=0
+ for i=rng.min,rng.max,sseqxstep do
+ x = sseq_getcoords(i,0)
+ label = sseq_label_fromlist(i,c-1,k,sseqxlabels)
+ -- bug fix with bounding box sizes in pgf
+-- tex.print("\\sbox\\sseq@labelbox{\\strut\\ensuremath{"..label.."}}")
+-- tex.print("\\dimen0=\\ht\\sseq@labelbox")
+-- tex.print("\\advance\\dimen0 by \\dp\\sseq@labelbox")
+-- tex.print("\\pgf@protocolsizes{0pt}{-\\dimen0}")
+ tex.print("\\pgftext[top,at=\\pgfpoint{"..(x+sseqentrysize/2).."sp}{0sp}]{\\ensuremath{\\strut "..label.."}}")
+ k=k+sseqxstep
+ end
+ end
+end
+
+function sseq_draw_vertical_labels(range)
+ local k
+
+ if sseqystep == 0 then return end -- old-fashioned way of disabling labels
+ for c,rng in ipairs(range) do
+ k=0
+ for i=rng.min,rng.max,sseqystep do
+ _,y = sseq_getcoords(0,i)
+ label = sseq_label_fromlist(i,c,k,sseqylabels)
+ tex.print("\\pgftext[right,at=\\pgfpoint{-2pt}{"..(y+sseqentrysize/2).."sp}]{\\ensuremath{"..label.."}}")
+ k=k+sseqystep
+ end
+ end
+end
+
+
+function sseq_drawlabels()
+ sseq_draw_horizontal_labels(sseqxrange)
+ sseq_draw_vertical_labels(sseqyrange)
+end
+
+function sseq_getdroplist(x,y)
+ return sseqobject[x] and sseqobject[x][y]
+end
+
+function sseq_openposition()
+ local l = sseq_getdroplist(sseqposx,sseqposy)
+ if not l then
+ error(string.format("sseq: cannot open position (%d,%d): nothing dropped yet",sseqposx,sseqposy))
+ elseif #l ~= 1 then
+ error(string.format("sseq: cannot open position (%d,%d): multiple drops",sseqposx,sseqposy))
+ else
+ sseqcurrentindex = {sseqposx,sseqposy,1}
+ end
+end
+
+function sseq_assert_source()
+ sseq_flush_connection()
+ if not sseqcurrentindex then
+ sseq_openposition()
+ end
+end
+
+function sseq_finish_pos()
+ sseq_flush_connection()
+ if sseqcurrentindex then
+ sseq_conclude_connection()
+ sseqpreviousindex, sseqcurrentindex = sseqcurrentindex,nil
+ end
+end
+
+function sseq_drop_and_open(x,y)
+ if not sseqobject[x] then sseqobject[x] = {} end
+ if not sseqobject[x][y] then sseqobject[x][y] = {} end
+ table.insert(sseqobject[x][y],{})
+ sseqcurrentindex = {x,y,#sseqobject[x][y]}
+end
+
+function sseq_drop_object(x,y,shape,pathusage,content,col)
+ local obj
+ sseq_finish_pos()
+ sseq_drop_and_open(x,y)
+ obj = sseqobject[x][y][sseqcurrentindex[3]]
+ obj.code = content
+ obj.color = col
+ obj.nodetype = shape
+
+
+ sseq_conclude_connection()
+ -- now do the optimizations such as \bullet -> drawn black circle etc
+ if (pathusage == "fill") or (obj.code == "\\bullet ") then
+ if (obj.nodetype == "circle") or (obj.code == "\\bullet ") then
+ obj.nodetype = "circle"
+ obj.cmd = "\\pgfsetfillcolor{%s}\\pgfpathqcircle{2pt}\\pgfusepathqfill"
+ obj.radius = 131072 -- 2pt in sp
+ obj.wd,obj.ht = 262144,262144 -- 4pt in sp
+ else
+ obj.cmd = "\\pgfsetfillcolor{%s}\\pgfsys@rect{-2pt}{-2pt}{4pt}{4pt}\\pgfsys@fill"
+ obj.wd,obj.ht = 262144,262144
+ obj.radius = 370727
+ end
+ elseif (obj.code == "\\circ ") then
+ obj.nodetype = "circle"
+ obj.cmd = "\\pgfsetstrokecolor{%s}\\pgfsetfillcolor{white}\\pgfsetdash{}{0pt}\\pgfpathqcircle{2pt}\\pgfusepathqfillstroke"
+ obj.radius = 131072 -- 2pt in sp
+ obj.wd,obj.ht = 262144,262144 -- 4pt in sp
+ elseif(obj.code == "\\square ") then
+ obj.nodetype="rectangle"
+ obj.cmd = "\\pgfsetstrokecolor{%s}\\pgfsetdash{}{0pt}\\pgfsys@rect{-2pt}{-2pt}{4pt}{4pt}\\pgfsys@stroke"
+ obj.wd,obj.ht = 262144,262144
+ obj.radius = 370727
+ else
+ obj.cmd = "\\pgfsetstrokecolor{%s}\\pgfsetfillcolor{white}"..string.format("\\pgfnode{%s}{center}{\\color{%%s}\\ensuremath{%s}}{}{\\pgfusepath{fill,%s}}",obj.nodetype,obj.code,pathusage)
+ tex.print (string.format("\\setbox%d=\\hbox{\\pgfinterruptpicture\\ensuremath{%s}\\endpgfinterruptpicture}",sseqboxno,obj.code))
+ tex.print("\\directlua0{sseq_register_size()}")
+ end
+end
+
+function sseq_drop_extension(shape,pathusage,col)
+ local obj,refobj
+ sseq_assert_source()
+ table.insert(sseqobject[sseqposx][sseqposy],{})
+ obj = sseqobject[sseqposx][sseqposy][#sseqobject[sseqposx][sseqposy]]
+ obj.code = "" -- no TeX code to typeset
+ obj.extends = sseqcurrentindex[3]
+ obj.color = col
+ obj.nodetype = shape
+ refobj = sseqobject[sseqcurrentindex[1]][sseqcurrentindex[2]][sseqcurrentindex[3]]
+
+ sseqcurrentindex[3] = #sseqobject[sseqposx][sseqposy]
+ sseq_conclude_connection()
+
+ if (shape=="circle") then
+ obj.radius = refobj.radius+65536 -- add 1pt in sp
+ obj.wd,obj.ht = 2*obj.radius,2*obj.radius
+ obj.cmd = "\\pgfsetstrokecolor{%s}\\pgfpathqcircle{"..obj.radius.."sp}\\pgfusepath{stroke,"..pathusage.."}"
+ else
+ obj.wd,obj.ht = refobj.wd+131072,refobj.ht +131072 -- add 1 pt at each side
+ obj.radius = 0.5*math.sqrt(obj.wd*obj.wd+obj.ht*obj.ht)
+ obj.cmd = "\\pgfsetstrokecolor{%s}\\pgfsetshapeinnerxsep{"..(.5*obj.wd).."sp}\\pgfsetshapeinnerysep{"..(.5*obj.ht).."sp}\\pgfnode{rectangle}{center}{}{}{\\pgfusepath{stroke,"..pathusage.."}}"
+ end
+end
+
+function sseq_register_size()
+ local currobj = sseqobject[sseqcurrentindex[1]][sseqcurrentindex[2]][sseqcurrentindex[3]]
+ currobj.wd = tex.box[sseqboxno].width
+ currobj.ht = (tex.box[sseqboxno].height+tex.box[sseqboxno].depth)
+ currobj.dp = tex.box[sseqboxno].depth
+ currobj.radius = 0.5*math.sqrt(currobj.wd*currobj.wd+currobj.ht*currobj.ht)
+end
+
+function sseq_drop_object_here(shape,pathusage,content,col)
+ sseq_drop_object(sseqposx,sseqposy,shape,pathusage,content,col)
+end
+
+function sseq_bullstring(x,y,n,col)
+ if n==0 then return end
+ sseq_drop_object_here("circle","fill","\\bullet",col)
+ for i=2,n do
+ sseq_move(x,y)
+ sseq_drop_object_here("circle","fill","\\bullet",col)
+ sseq_late_connection("","",col,false,false)
+ end
+end
+
+function sseq_moveto(x,y)
+ sseq_conclude_connection()
+ sseq_finish_pos()
+ sseqposx = x
+ sseqposy = y
+end
+
+function sseq_grayout(col)
+ sseq_assert_source()
+ sseqobject[sseqcurrentindex[1]][sseqcurrentindex[2]][sseqcurrentindex[3]].color = col
+ for _,conn in pairs(sseqconnection) do
+ if (conn.from[1] == sseqcurrentindex[1] and conn.from[2] == sseqcurrentindex[2] and conn.from[3] == sseqcurrentindex[3]) or (conn.to[1] == sseqcurrentindex[1] and conn.to[2] == sseqcurrentindex[2] and conn.to[3] == sseqcurrentindex[3]) then
+ conn.color = col
+ end
+ end
+end
+
+function sseq_move(x,y)
+ sseq_moveto(sseqposx+x,sseqposy+y)
+end
+
+-- New prefix model: sseqprefix is a stack of lists
+-- sseq_begin_prefix_context pushes an empty prefix onto that stack
+-- sseq_end_prefix_context pops the last prefix off the stack
+-- A prefix is an (unordered) list of names
+
+function uses_old_prefix_model(pref)
+ if #pref == 0 then return true end
+ if type(pref[1]) == "table" then return false end
+ return true
+end
+
+function stringtolist(pref,name)
+ local res = {}
+ -- check if we're using the old or the new model
+ if uses_old_prefix_model(pref) then
+ for i,p in ipairs(pref) do table.insert(res,p) end
+ else -- new prefix model
+ for i,l in ipairs(pref) do
+ for j,p in ipairs(l) do table.insert(res,p) end
+ end
+ end
+ for w in string.gmatch(name,"%w+") do
+ table.insert(res,w)
+ end
+ table.sort(res)
+ return res
+end
+
+function sseq_set_global_name(name)
+ local namestring = table.concat(name)
+ sseq_assert_source()
+ if sseqname[namestring] then
+ error("sseq: duplicate name "..namestring)
+ else
+ sseqname[namestring] = {sseqcurrentindex[1],sseqcurrentindex[2],sseqcurrentindex[3]}
+ end
+end
+
+function sseq_global_name(name)
+ return stringtolist(sseqprefix,name)
+end
+
+function sseq_name(name)
+ sseq_set_global_name(sseq_global_name(name))
+end
+
+function sseq_global_goto(name)
+ local namestring = table.concat(name)
+ sseq_conclude_connection()
+ sseq_finish_pos()
+ if not sseqname[namestring] then
+ error("sseq: goto name does not exist: '"..namestring.."'")
+ else
+ sseqcurrentindex = { sseqname[namestring][1],sseqname[namestring][2],sseqname[namestring][3] }
+ sseqposx,sseqposy = sseqname[namestring][1], sseqname[namestring][2]
+ end
+end
+
+function sseq_abs_goto(name)
+ sseq_global_goto(stringtolist({},name))
+end
+
+function sseq_prefix(pref)
+ if uses_old_prefix_model(sseqprefix) then
+ sseqprefix = stringtolist(sseqprefix,pref)
+ else
+ sseqprefix[#sseqprefix] = stringtolist(sseqprefix[#sseqprefix],pref)
+ end
+end
+
+function sseq_begin_prefix_context()
+ if (#sseqprefix > 0) and uses_old_prefix_model(sseqprefix) then
+ error("sseq: you cannot use stacked prefixes when there's a non-stacked active prefix")
+ else
+ table.insert(sseqprefix,{})
+ end
+end
+
+
+function sseq_end_prefix_context()
+ if uses_old_prefix_model(sseqprefix) then
+ error("sseq: no prefix context to end")
+ else
+ table.remove(sseqprefix,#sseqprefix)
+ end
+end
+
+-- sseq_reset_prefix is deprecated. It'll throw an error if we ever used
+-- sseq_begin_prefix_context (because that would be incompatible)
+function sseq_reset_prefix()
+ if uses_old_prefix_model(sseqprefix) then
+ sseqprefix = {}
+ else
+ error("sseq: you cannot use \\ssresetprefix if you use stacked prefixes.")
+ end
+end
+
+function sseq_goto(name)
+ sseq_global_goto(sseq_global_name(name))
+end
+
+function sseq_flush_connection()
+end
+
+function sseq_conclude_connection()
+ if not sseqopenconnection then return end
+ if not sseqcurrentindex then
+ sseq_openposition()
+ end
+ sseqopenconnection.to = { sseqcurrentindex[1],sseqcurrentindex[2],sseqcurrentindex[3] }
+ table.insert(sseqconnection,sseqopenconnection)
+ sseqopenconnection = nil
+end
+
+-- immediately register a connection between sseqpreviousindex and sseqcurrentindex
+function sseq_late_connection(dash,bending,col,sourcevoid,targetvoid)
+ local newconn
+
+ sseq_flush_connection() -- finish previous connection
+ if not targetvoid then sseq_assert_source() end
+ if (not sseqpreviousindex) or (not targetvoid and (sseqpreviousindex[3] == 0)) then
+ error("sseq: connection without well-defined source")
+ end
+ newconn = { color = col, dashing = dash }
+ if(bending ~= "") then newconn.curving = bending end
+ if sourcevoid then
+ newconn.from = {sseqpreviousindex[1],sseqpreviousindex[2],0}
+ else
+ newconn.from = {sseqpreviousindex[1],sseqpreviousindex[2],sseqpreviousindex[3]}
+ end
+ if targetvoid then
+ newconn.to = {sseqposx,sseqposy,0}
+ else
+ newconn.to = {sseqcurrentindex[1],sseqcurrentindex[2],sseqcurrentindex[3]}
+ end
+ table.insert(sseqconnection,newconn)
+end
+
+function sseq_void_line(dash,bending,col,x,y)
+ local newconn = { color = col, dashing = dash }
+
+ if(bending ~= "") then newconn.curving = bending end
+ sseq_assert_source();
+ newconn.from = {sseqcurrentindex[1],sseqcurrentindex[2],sseqcurrentindex[3]}
+ newconn.to = {sseqcurrentindex[1]+x,sseqcurrentindex[2]+y,0}
+ table.insert(sseqconnection,newconn)
+end
+
+function sseq_open_connection(dash,bending,col,x,y)
+ local newconn = { color = col, dashing = dash }
+
+ if(bending ~= "") then newconn.curving = bending end
+ sseq_assert_source(); sseq_finish_pos()
+ newconn.from = {sseqpreviousindex[1],sseqpreviousindex[2],sseqpreviousindex[3]}
+ sseqopenconnection = newconn
+end
+
+function sseq_add_arrow(fromto,type)
+ if sseqopenconnection then
+ sseqopenconnection[fromto] = type
+ else
+ sseqconnection[#sseqconnection][fromto] = type
+ end
+end
+
+function sseq_drop_label(p,col,label)
+ sseq_assert_source()
+ table.insert(sseqlabel,{x = sseqcurrentindex[1], y = sseqcurrentindex[2], n = sseqcurrentindex[3],
+ color = col, code = label, pos = p})
+end
+
+
+function sseq_pack_diagonal(i,n)
+ return sseqentrysize/2+sseqentrysize*(n-i)/4,
+ sseqentrysize/2-sseqentrysize*(n-i)/4
+end
+
+function sseq_pack_horizontal(i,n)
+ return sseqentrysize/2+sseqentrysize*(i-1)/4,
+ sseqentrysize/2
+end
+function sseq_pack_vertical(i,n)
+ return sseqentrysize/2,
+ sseqentrysize/2-sseqentrysize*(n-i)/4
+end
+
+sseqautopackdata = { {{.5,.5}}, -- one
+ {{.25,.75},{.75,.25}}, -- two
+ {{.167,.833},{.5,.5},{.833,.167}}, -- three
+ {{.167,.75},{.389,.25},{.611,.75},{.833,.25}} -- four
+ }
+
+function sseq_pack_auto(i,n) -- return offset of the ith square out of n.
+ if n > 4 then return sseq_pack_diagonal(i,n) end
+ dat = sseqautopackdata[n][i]
+ return dat[1]*sseqentrysize,dat[2]*sseqentrysize
+
+end
+
+function sseq_position_object_list(x,y,list)
+ local absx,absy = sseq_getcoords(x,y) -- the lower left corner of the square
+ local numobj = #list
+ local j = 1
+
+ if not absx or not absy then return end -- outside clipping area -- don't draw.
+
+ for i,obj in ipairs(list) do
+ if (obj.extends) then numobj = numobj-1 end
+ end
+
+ for i,obj in ipairs(list) do
+ if (obj.extends) then
+ obj.posx,obj.posy = list[obj.extends].posx,list[obj.extends].posy
+ else
+ obj.posx, obj.posy = sseqpacking(j,numobj)
+ obj.posx = obj.posx + absx
+ obj.posy = obj.posy + absy
+ j = j+1
+ end
+ if not obj.color then obj.color = "black" end
+ end
+end
+
+function sseq_position_objects()
+ for x,ylist in pairs(sseqobject) do
+ for y,olist in pairs(ylist) do
+ sseq_position_object_list(x,y,olist)
+ end
+ end
+end
+
+function sseq_dump_translation(x,y)
+ tex.print("\\pgfsys@transformshift{"..(x-sseqcurrabsx).."sp}{"..(y-sseqcurrabsy).."sp}")
+ sseqcurrabsx,sseqcurrabsy = x,y
+end
+
+function sseq_dump_object(x,y,obj)
+ if not obj.posx or not obj.posy then return end
+ sseq_dump_translation(obj.posx,obj.posy)
+ tex.print(string.format(obj.cmd,obj.color,obj.color))
+end
+
+--
+-- return the intersection of the vector to (fromx, fromy) with the boundary of obj
+--
+function sseq_correct_line_end(obj,fromx,fromy,curving)
+ local distsq,posx,posy,deltax,deltay,dirx,diry
+ posx,posy = obj.posx,obj.posy
+
+ dirx = posx-fromx
+ diry = posy-fromy
+
+ if(curving) then
+ dirx,diry = dirx/2-curving*diry,diry/2+curving*dirx
+ end
+
+ if obj.nodetype == "circle" then
+ dist = math.sqrt(dirx*dirx + diry*diry)
+ return posx - obj.radius*(dirx)/dist,
+ posy - obj.radius*(diry)/dist
+ else
+ deltax = dirx/diry*obj.ht/2 -- no problem with infinity in LUA
+ deltay = diry/dirx*obj.wd/2
+ if(math.abs(deltax) <= obj.wd/2) then -- boundary point on one of the horizontal lines
+ if fromy > posy then
+ return posx + deltax, posy + obj.ht/2
+ else
+ return posx - deltax, posy - obj.ht/2
+ end
+ else
+ if fromx > posx then
+ return posx + obj.wd/2, posy + deltay
+ else
+ return posx - obj.wd/2, posy - deltay
+ end
+ end
+ end
+end
+
+--
+-- return the intersection of the vector from (x,y) to the clipped object at
+-- coordinate (clipi,clipj) with the boundary of the grid segment containing (i,j)
+--
+function sseq_fix_clipped_connection(clipi,clipj,i,j,x,y)
+ local minx,maxx,miny,maxy,deltax,deltay
+
+ minx,maxx = sseq_get_rangepart(sseqxrange,i,sseqxgap)
+ miny,maxy = sseq_get_rangepart(sseqyrange,j,sseqygap)
+ minx = minx - sseqxleak
+ maxx = maxx + sseqxleak
+ miny = miny - sseqyleak
+ maxy = maxy + sseqyleak
+
+ deltax = 1e10*(clipi-i)
+ deltay = 1e10*(clipj-j)
+ -- compute intersection of the vector (deltax, deltay) based at (x,y)
+ -- with the rectangle minx,miny,maxx,maxy
+ if(x+deltax > maxx) then deltax,deltay = maxx-x, deltay * (maxx-x)/deltax end
+ if(x+deltax < minx) then deltax,deltay = minx-x, deltay*(minx-x)/deltax end
+ if(y+deltay > maxy) then deltax,deltay = deltax * (maxy-y)/deltay, maxy-y end
+ if(y+deltay < miny) then deltax,deltay = deltax * (miny-y)/deltay, miny-y end
+ return x+deltax,y+deltay
+end
+
+function sseq_dump_connection(conn)
+ local fromx, fromy, tox, toy, ctrlx,ctrly, helpx, helpy
+ local fromobj,toobj
+
+ -- possibilities: * from, to not in the displayed range
+ -- * from[3] = 0 or to[3] = 0 (void line)
+ -- or any combination.
+
+ -- if source or target is clipped, will make it a void line
+ --
+
+ -- TODO: locations outside displayed range are incorrect
+
+ fromx,fromy = sseq_getcoords(conn.from[1],conn.from[2])
+ tox,toy = sseq_getcoords(conn.to[1],conn.to[2])
+
+ if ((not fromx) or (not fromy) or (conn.from[3] == 0))
+ and ((not tox) or (not toy) or (conn.to[3] == 0)) then
+ -- forget it -- source and target are clipped and/or void
+ return
+ end
+
+ if ((not fromx) or (not fromy)) then -- source clipped: we can be sure the target is regular
+ toobj = sseqobject[conn.to[1]][conn.to[2]][conn.to[3]]
+ tox,toy = toobj.posx, toobj.posy
+ fromx,fromy = sseq_fix_clipped_connection(conn.from[1],conn.from[2],conn.to[1],conn.to[2],tox,toy)
+ elseif ((not tox) or (not toy)) then -- target clipped: we can be sure the source is regular
+ fromobj = sseqobject[conn.from[1]][conn.from[2]][conn.from[3]]
+ fromx,fromy = fromobj.posx, fromobj.posy
+ tox,toy = sseq_fix_clipped_connection(conn.to[1],conn.to[2],conn.from[1],conn.from[2],fromx,fromy)
+ elseif conn.from[3] == 0 then -- source not clipped but void
+ toobj = sseqobject[conn.to[1]][conn.to[2]][conn.to[3]]
+ fromx = fromx+(toobj.posx-tox)
+ fromy = fromy+(toobj.posy-toy)
+ tox,toy = toobj.posx, toobj.posy
+ elseif conn.to[3] == 0 then -- target not clipped but void
+ fromobj = sseqobject[conn.from[1]][conn.from[2]][conn.from[3]]
+ tox = tox+(fromobj.posx-fromx)
+ toy = toy+(fromobj.posy-fromy)
+ fromx,fromy = fromobj.posx, fromobj.posy
+ else -- both source and target regular
+ fromobj = sseqobject[conn.from[1]][conn.from[2]][conn.from[3]]
+ fromx,fromy = fromobj.posx, fromobj.posy
+ toobj = sseqobject[conn.to[1]][conn.to[2]][conn.to[3]]
+ tox,toy = toobj.posx, toobj.posy
+ end
+
+
+ if fromobj then -- we have to be more careful where it ends
+ fromx,fromy = sseq_correct_line_end(fromobj,tox,toy,conn.curving)
+ end
+ if toobj then
+ tox,toy = sseq_correct_line_end(toobj,fromx,fromy,conn.curving and -conn.curving)
+ end
+
+ if conn.curving then
+ ctrlx = tox/2+fromx/2-conn.curving*(toy-fromy)
+ ctrly = toy/2+fromy/2+conn.curving*(tox-fromx)
+ end
+
+ if conn.arrowfrom or conn.arrowto or conn.curving then -- got to use slow code
+ tex.print("\\pgfsetdash{"..conn.dashing.."}{0pt}")
+ tex.print("\\pgfsetstrokecolor{"..conn.color.."}")
+ if (fromx and fromy) then
+ if (tox and toy) then
+ tex.print(string.format("\\pgfpathmoveto{\\pgfpoint{%dsp}{%dsp}}",fromx,fromy))
+ if conn.curving then
+ tex.print(string.format("\\pgfpathquadraticcurveto{\\pgfpoint{%dsp}{%dsp}}{\\pgfpoint{%dsp}{%dsp}}",ctrlx,ctrly,tox,toy))
+ else
+ tex.print(string.format("\\pgfpathlineto{\\pgfpoint{%dsp}{%dsp}}",tox,toy))
+ end
+ if conn.arrowfrom then
+ tex.print("\\pgfsetarrowsstart{"..conn.arrowfrom.."}")
+ else
+ tex.print("\\pgfsetarrowsstart{}")
+ end
+ if conn.arrowto then
+ tex.print("\\pgfsetarrowsend{"..conn.arrowto.."}")
+ else
+ tex.print("\\pgfsetarrowsend{}")
+ end
+ tex.print("\\pgfusepath{stroke}")
+ end
+ end
+ else
+ tex.print("\\pgfsetdash{"..conn.dashing.."}{0pt}")
+ tex.print("\\pgfsetstrokecolor{"..conn.color.."}")
+ if (fromx and fromy) then
+ if (tox and toy) then
+ tex.print(string.format("\\pgfsys@moveto{%dsp}{%dsp}",fromx,fromy))
+ tex.print(string.format("\\pgfsys@lineto{%dsp}{%dsp}",tox,toy))
+ tex.print("\\pgfsys@stroke")
+ end
+ end
+ end
+end
+
+local labelpositioninrect = { U = {0,.5,"bottom"},
+ UL = {-.5,.5,"bottom,right"},
+ LU = {-.5,.5,"bottom,right"},
+ L = {-.5,0,"right"},
+ DL = {-.5,-.5,"top,right"},
+ LD = {-.5,-.5,"top,right"},
+ D = {0,-.5,"top"},
+ DR = {.5,-.5,"top,left"},
+ RD = {.5,-.5,"top,left"},
+ R = {.5,0,"left"},
+ UR = {.5,.5,"bottom,left"},
+ RU = {.5,.5,"bottom,left"} }
+local labelpositionincirc = { U = {0,1,"bottom"},
+ UL = {-.71,.71,"bottom,right"},
+ LU = {-.71,.71,"bottom,right"},
+ L = {-1,0,"right"},
+ DL = {-.71,-.71,"top,right"},
+ LD = {-.71,-.71,"top,right"},
+ D = {0,-1,"top"},
+ DR = {.71,-.71,"top,left"},
+ RD = {.71,-.71,"top,left"},
+ R = {1,0,"left"},
+ UR = {.71,.71,"bottom,left"},
+ RU = {.71,.71,"bottom,left"} }
+
+function sseq_dump_label(label)
+ local labelledobj = sseqobject[label.x][label.y][label.n]
+ local posx,posy
+
+ if (not labelledobj.posx) or (not labelledobj.posy) then return end
+ tex.print("\\color{"..label.color.."}")
+ if labelledobj.nodetype == "circle" then
+ posx = labelledobj.posx+labelpositionincirc[label.pos][1]*labelledobj.radius
+ posy = labelledobj.posy+labelpositionincirc[label.pos][2]*labelledobj.radius
+ sseq_dump_translation(posx,posy)
+ tex.print(string.format("\\pgftext[%s]{\\ensuremath{%s}}",labelpositioninrect[label.pos][3],label.code))
+ else
+ posx = labelledobj.posx+labelpositioninrect[label.pos][1]*labelledobj.wd
+ posy = labelledobj.posy+labelpositioninrect[label.pos][2]*labelledobj.ht
+ sseq_dump_translation(posx,posy)
+ tex.print(string.format("\\pgftext[%s]{\\ensuremath{%s}}",labelpositioninrect[label.pos][3],label.code))
+ end
+end
+
+-- Write out all the pgf code to produce the chart
+function sseq_dump_code()
+ if (not sseqxleak) then sseqxleak = 0.3*sseqxgap end
+ if (not sseqyleak) then sseqyleak = 0.3*sseqygap end
+ tex.print("\\makeatletter")
+ tex.print("\\pgfset{inner sep=0pt}")
+ -- connections
+ for _,conn in pairs(sseqconnection) do
+ sseq_dump_connection(conn)
+ end
+ -- objects
+ tex.print("\\color{white}") -- background fill color
+ for x,ylist in pairs(sseqobject) do
+ for y,olist in pairs(ylist) do
+ for z,obj in ipairs(olist) do
+ sseq_dump_object(x,y,obj)
+ end
+ end
+ end
+ -- labels
+ for _,label in pairs(sseqlabel) do
+ sseq_dump_label(label)
+ end
+ tex.print("\\makeatother")
+end
+
diff --git a/macros/luatex/latex/luasseq/luasseq.pdf b/macros/luatex/latex/luasseq/luasseq.pdf
new file mode 100644
index 0000000000..6e487fcde6
--- /dev/null
+++ b/macros/luatex/latex/luasseq/luasseq.pdf
Binary files differ
diff --git a/macros/luatex/latex/luatextra/Makefile b/macros/luatex/latex/luatextra/Makefile
new file mode 100644
index 0000000000..93d290d0ad
--- /dev/null
+++ b/macros/luatex/latex/luatextra/Makefile
@@ -0,0 +1,92 @@
+# Makefile for luatextra.
+
+NAME = luatextra
+DTX = $(wildcard *.dtx)
+DOC_DTX = $(patsubst %.dtx, %.pdf, $(DTX))
+
+# Files grouped by generation mode
+UNPACKED= luatextra.sty
+COMPILED = $(DOC_DTX)
+GENERATED = $(UNPACKED) $(COMPILED)
+SOURCE = $(DTX) README Makefile News
+
+# Files grouped by installation location
+RUNFILES = $(filter-out test.tex, $(UNPACKED))
+DOCFILES = $(DOC_DTX) test.tex README News
+SRCFILES = $(DTX) Makefile
+
+# The following definitions should be equivalent
+# ALL_FILES = $(RUNFILES) $(DOCFILES) $(SRCFILES)
+ALL_FILES = $(GENERATED) $(SOURCE)
+
+# Installation locations
+FORMAT = lualatex
+RUNDIR = $(TEXMFROOT)/tex/$(FORMAT)/$(NAME)
+DOCDIR = $(TEXMFROOT)/doc/$(FORMAT)/$(NAME)
+SRCDIR = $(TEXMFROOT)/source/$(FORMAT)/$(NAME)
+TEXMFROOT = ./texmf
+
+CTAN_ZIP = $(NAME).zip
+TDS_ZIP = $(NAME).tds.zip
+ZIPS = $(CTAN_ZIP) $(TDS_ZIP)
+
+DO_TEX = tex --interaction=batchmode $< >/dev/null
+DO_LATEXMK = latexmk -pdf -silent $< >/dev/null
+
+all: $(GENERATED)
+doc: $(COMPILED)
+unpack: $(UNPACKED)
+ctan: check $(CTAN_ZIP)
+tds: $(TDS_ZIP)
+world: all ctan
+.PHONY: all doc unpack ctan tds world check
+
+%.pdf: %.dtx
+ $(DO_LATEXMK)
+
+$(UNPACKED): luatextra.dtx
+ $(DO_TEX)
+
+check: $(UNPACKED)
+ lualatex --interaction=batchmode test.tex >/dev/null
+
+$(CTAN_ZIP): $(SOURCE) $(COMPILED) $(TDS_ZIP)
+ @echo "Making $@ for CTAN upload."
+ @$(RM) -- $@
+ @zip -9 $@ $^ >/dev/null
+
+define run-install
+@mkdir -p $(RUNDIR) && cp $(RUNFILES) $(RUNDIR)
+@mkdir -p $(DOCDIR) && cp $(DOCFILES) $(DOCDIR)
+@mkdir -p $(SRCDIR) && cp $(SRCFILES) $(SRCDIR)
+endef
+
+$(TDS_ZIP): TEXMFROOT=./tmp-texmf
+$(TDS_ZIP): $(ALL_FILES)
+ @echo "Making TDS-ready archive $@."
+ @$(RM) -- $@
+ $(run-install)
+ @cd $(TEXMFROOT) && zip -9 ../$@ -r . >/dev/null
+ @$(RM) -r -- $(TEXMFROOT)
+
+.PHONY: install manifest clean mrproper
+
+install: $(ALL_FILES)
+ @echo "Installing in '$(TEXMFROOT)'."
+ $(run-install)
+
+manifest:
+ @echo "Source files:"
+ @for f in $(SOURCE); do echo $$f; done
+ @echo ""
+ @echo "Derived files:"
+ @for f in $(GENERATED); do echo $$f; done
+
+clean:
+ @latexmk -silent -c *.dtx >/dev/null
+ @# for tex-only runs:
+ @rm -f -- *.log
+
+mrproper: clean
+ @$(RM) -- $(GENERATED) $(ZIPS) test.*
+
diff --git a/macros/luatex/latex/luatextra/News b/macros/luatex/latex/luatextra/News
new file mode 100644
index 0000000000..c841768bdb
--- /dev/null
+++ b/macros/luatex/latex/luatextra/News
@@ -0,0 +1,58 @@
+ History of the luatextra package
+
+
+2010-12-14 v1.0.1
+ * work around bug (loading order) reported by Damien Robert
+
+2010/10/10 v1.0
+ * move to latex only
+ * remove old callback code
+ * remove old macro/primitive aliases
+ * load fontspec
+
+2010/10/10 v0.99a
+ * adapt to luatexbase v3.0
+
+2010/10/08 v0.99
+ * delegate definition of {luacode} and \luadirect to package luacode
+ * raise an error rather than a warning when not running LuaTeX
+ * load fixltx2e under LaTeX
+
+2010/10/04 v0.98
+ * load metalogo under LaTeX; don't define logos under Plain TeX
+ * documentation overhaul; added a "planned changes" section
+ * rm luatextra-reference.pdf; will be back separatly as lualatex-doc.pdf
+
+2010/08/02 v0.971
+ * fix latex detection that used to break latex detection in other packages
+ (inc. TikZ).
+
+2010/05/10
+ * adaptation to the new luatexbase package
+
+2010/03/29 v0.97
+ * bump version to account for luaextra (now lualibs) separation
+
+2010/03/28
+ * move luaextra to a separate package
+
+2010/03/28, luatextra v0.96
+ * a lot of stuff moved to luatexbase. Now using luatexbase v0.1.
+
+2010/01/10, luaextra v0.92:
+ * making the file loadable without luatextra (useful for lua scripts)
+ * fixing typo in localize_sep
+
+2009/12/16, luatextra v0.95:
+ * package can now be loaded with a different engine, it then loads only
+ \LuaTeX and \LuaLaTeX
+ * \CatcodeTableLaTeXAtLetter and \CatcodeTableExpl have appeared
+ * short names have been added to the tex.catcodetablenumber table
+
+2009/09/22, luatextra v0.94:
+ * prefixing macros with \luatex instead of \lua, to be coherent with
+ TeX Live 2009.
+
+2009/09/18, luamcallbacks v0.93:
+ * adding the callback process_output_buffer, to use it with luainputenc
+
diff --git a/macros/luatex/latex/luatextra/README b/macros/luatex/latex/luatextra/README
new file mode 100644
index 0000000000..30ebacd7db
--- /dev/null
+++ b/macros/luatex/latex/luatextra/README
@@ -0,0 +1,37 @@
+ The luatextra package for LuaLaTeX
+
+
+The luatextra package loads essential and useful packages for LuaLaTeX. It is
+meant as convenience for users who don't want to load them individually.
+
+
+Installation
+------------
+
+Here are the recommended installation methods (preferred first).
+
+1. If you are using TeX Live 2008 or later, use 'tlmgr install luatextra'.
+Alternatively, try your (TeX or Linux) distribution's package management system.
+
+2. a. Grab luatextra.tds.zip on the CTAN.
+ b. Unzip it at the root of one or your TDS trees.
+ c. You may need to update some filename database after this, see your TeX
+distribution's manual for details.
+
+3. a. Grab the sources from CTAN or github.
+ b. Run 'make install TEXMFROOT=/path/to/texmf'.
+ c. See 2c.
+
+
+License
+-------
+
+This work and the derived files are under the Creative Commons CC0 license.
+
+See the full text at
+
+http://creativecommons.org/publicdomain/zero/1.0/legalcode
+
+and a FAQ at
+
+http://wiki.creativecommons.org/CC0
diff --git a/macros/luatex/latex/luatextra/luatextra.dtx b/macros/luatex/latex/luatextra/luatextra.dtx
new file mode 100644
index 0000000000..824c441fb3
--- /dev/null
+++ b/macros/luatex/latex/luatextra/luatextra.dtx
@@ -0,0 +1,200 @@
+% \iffalse meta-comment
+%
+% Written in 2009, 2010 by Manuel Pégourié-Gonnard and Élie Roux.
+% <mpg@elzevir.fr>
+% <elie.roux@telecom-bretagne.eu>
+%
+% This work is under the CC0 license.
+%
+% This work consists of the main source file luatextra.dtx
+% and the derived files
+% luatextra.sty, luatextra.lua, luatextra.pdf.
+%
+% Unpacking:
+% tex luatextra.dtx
+% Documentation:
+% pdflatex luatextra.dtx
+%
+%<*ignore>
+\begingroup
+ \def\x{LaTeX2e}%
+\expandafter\endgroup
+\ifcase 0\ifx\install y1\fi\expandafter
+ \ifx\csname processbatchFile\endcsname\relax\else1\fi
+ \ifx\fmtname\x\else 1\fi\relax
+\else\csname fi\endcsname
+%</ignore>
+%<*install>
+\input docstrip.tex
+
+\keepsilent
+\askforoverwritefalse
+
+\preamble
+
+Written in 2009, 2010 by Manuel Pegourie-Gonnard and Elie Roux.
+
+This work is under the CC0 license.
+See source file '\inFileName' for details.
+
+\endpreamble
+
+\generate{%
+ \usedir{tex/luatex/luatextra}%
+ \file{luatextra.sty}{\from{luatextra.dtx}{package}}%
+}
+
+\generate{%
+ \usedir{doc/luatex/luatextra}%
+ \file{test.tex}{\from{luatextra.dtx}{test}}%
+}
+
+\obeyspaces
+\Msg{************************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* files into a directory searched by TeX:}
+\Msg{*}
+\Msg{* luatextra.sty luatextra.lua}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{textcomp}
+\usepackage{lmodern}
+\usepackage{metalogo}
+\usepackage[bookmarks=true, colorlinks=true]{hyperref}
+\usepackage{bookmark}
+\usepackage[english]{babel}
+\providecommand\eTeX{e\TeX}
+\newcommand\pf{\textsf}
+\newcommand\file{\texorpdfstring{\nolinkurl}{}}
+\newcommand\code{\texttt}
+\newcommand*\email[1]{\href{mailto:#1}{#1}}
+\begin{document}
+ \DocInput{luatextra.dtx}%
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{0}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+% \title{The \textsf{luatextra} package}
+% \date{2010/10/10 v1.0}
+% \author{%
+% Manuel P\'egouri\'e-Gonnard \& \'Elie Roux \\
+% Support: \email{lualatex-dev@tug.org}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% The \pf{luatextra} package loads essential and useful packages for
+% \LuaLaTeX. It is meant as convenience for users who don't want to load them
+% individually.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Documentation}
+%
+% The following packages are loaded:
+% \begin{description}
+% \item[fontspec] --- advanced font management, integrated in the \LaTeX\ font
+% selection scheme, with access to system fonts and opentype features;
+% \item[luacode] --- tools for easier integration of Lua code in \LaTeX;
+% \item[metalogo] --- commands for logos, including |\LuaTeX| and
+% |\LuaLaTeX|;
+% \item[fixltx2e] --- various fixes and small enchancements for the \LaTeX\
+% core;
+% \item[luatexbase] --- low-level management of \LuaTeX's new and extended
+% resources;
+% \item[lualibs] --- additional general-purpose Lua functions.
+% \end{description}
+%
+% In case you are not yet familiar with the available \LuaLaTeX\ packages, you
+% might want to check the document \nolinkurl{lualatex-doc.pdf} from the
+% eponymous package.
+%
+% \section{Implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% Identify.
+%
+% \begin{macrocode}
+\ProvidesPackage{luatextra}[2010/10/10 v1.0 Loading usual LuaLaTeX packages]
+% \end{macrocode}
+%
+% Make sure Lua\TeX\ is being used.
+%
+% \begin{macrocode}
+\RequirePackage{ifluatex}
+\ifluatex\else
+ \PackageError{luatextra}{LuaTeX is required for this package. Aborting.}{%
+ This package can only be used with the LuaTeX engine^^J%
+ (command `lualatex' or `luatex').^^J%
+ Package loading has been stopped to prevent additional errors.}
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% Load packages; \pf{luatexbase} and \pf{lualibs} are loaded (indirectly)
+% by fontspec, but just to be sure (in case it changes in the future).
+%
+% \begin{macrocode}
+\RequirePackage{fontspec}
+\RequirePackage{luatexbase}
+\RequireLuaModule{lualibs}
+\RequirePackage{metalogo}
+\RequirePackage{luacode}
+\RequirePackage{fixltx2e}
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \section{Test file}
+%
+% Very minimal, just check that the package correctly loads. We have to use
+% |\documentclass| to make \pf{xkeyval} (loaded by \pf{fontspec}) happy.
+%
+% \begin{macrocode}
+%<*test>
+\documentclass{minimal}
+\usepackage{luatextra}
+\stop
+%</test>
+% \end{macrocode}
+%
+%
+% \Finale
+\endinput
diff --git a/macros/luatex/latex/luatextra/luatextra.pdf b/macros/luatex/latex/luatextra/luatextra.pdf
new file mode 100644
index 0000000000..d4f7ebb52f
--- /dev/null
+++ b/macros/luatex/latex/luatextra/luatextra.pdf
Binary files differ
diff --git a/macros/luatex/latex/luatodonotes/README.md b/macros/luatex/latex/luatodonotes/README.md
new file mode 100644
index 0000000000..6036b14d70
--- /dev/null
+++ b/macros/luatex/latex/luatodonotes/README.md
@@ -0,0 +1,35 @@
+# luatodonotes
+The package allows the user to insert comments into a document that
+suggest (for example) further editing that may be needed.
+
+The comments are shown in the margins alongside the text; different styles
+for the comments may be used; the styles are selected using package
+options.
+
+The package is based on the package todonotes by Henrik Skov Midtiby
+(http://www.ctan.org/pkg/todonotes), and depends heavily on Lua,
+so it can only be used with LuaLaTeX.
+
+
+## Installation
+Run `latex luatodonotes.ins` to generate the package files and copy the listed
+files into your TEXMF tree.
+
+
+## Development
+The latest source code is available on GitHub:
+https://github.com/fabianlipp/luatodonotes
+
+If you want to report bugs or you have suggestions for improvements, you can
+use the issue tracker on GitHub or contact me via email.
+
+
+## License
+The luatodonotes package is subject to the LATEX Project Public License.
+The following external lua libraries are used:
+
+* `path_line.lua` and `path_point.lua`:
+ taken from luapower.com (Public domain)
+
+* `inspect.lua`:
+ by Enrique García Cota (MIT License)
diff --git a/macros/luatex/latex/luatodonotes/inspect.lua b/macros/luatex/latex/luatodonotes/inspect.lua
new file mode 100644
index 0000000000..638a673a70
--- /dev/null
+++ b/macros/luatex/latex/luatodonotes/inspect.lua
@@ -0,0 +1,297 @@
+local inspect ={
+ _VERSION = 'inspect.lua 2.0.0',
+ _URL = 'http://github.com/kikito/inspect.lua',
+ _DESCRIPTION = 'human-readable representations of tables',
+ _LICENSE = [[
+ MIT LICENSE
+
+ Copyright (c) 2013 Enrique García Cota
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ ]]
+}
+
+-- Apostrophizes the string if it has quotes, but not aphostrophes
+-- Otherwise, it returns a regular quoted string
+local function smartQuote(str)
+ if str:match('"') and not str:match("'") then
+ return "'" .. str .. "'"
+ end
+ return '"' .. str:gsub('"', '\\"') .. '"'
+end
+
+local controlCharsTranslation = {
+ ["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n",
+ ["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v"
+}
+
+local function escapeChar(c) return controlCharsTranslation[c] end
+
+local function escape(str)
+ local result = str:gsub("\\", "\\\\"):gsub("(%c)", escapeChar)
+ return result
+end
+
+local function isIdentifier(str)
+ return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" )
+end
+
+local function isArrayKey(k, length)
+ return type(k) == 'number' and 1 <= k and k <= length
+end
+
+local function isDictionaryKey(k, length)
+ return not isArrayKey(k, length)
+end
+
+local defaultTypeOrders = {
+ ['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4,
+ ['function'] = 5, ['userdata'] = 6, ['thread'] = 7
+}
+
+local function sortKeys(a, b)
+ local ta, tb = type(a), type(b)
+
+ -- strings and numbers are sorted numerically/alphabetically
+ if ta == tb and (ta == 'string' or ta == 'number') then return a < b end
+
+ local dta, dtb = defaultTypeOrders[ta], defaultTypeOrders[tb]
+ -- Two default types are compared according to the defaultTypeOrders table
+ if dta and dtb then return defaultTypeOrders[ta] < defaultTypeOrders[tb]
+ elseif dta then return true -- default types before custom ones
+ elseif dtb then return false -- custom types after default ones
+ end
+
+ -- custom types are sorted out alphabetically
+ return ta < tb
+end
+
+local function getDictionaryKeys(t)
+ local keys, length = {}, #t
+ for k,_ in pairs(t) do
+ if isDictionaryKey(k, length) then table.insert(keys, k) end
+ end
+ table.sort(keys, sortKeys)
+ return keys
+end
+
+local function getToStringResultSafely(t, mt)
+ local __tostring = type(mt) == 'table' and rawget(mt, '__tostring')
+ local str, ok
+ if type(__tostring) == 'function' then
+ ok, str = pcall(__tostring, t)
+ str = ok and str or 'error: ' .. tostring(str)
+ end
+ if type(str) == 'string' and #str > 0 then return str end
+end
+
+local maxIdsMetaTable = {
+ __index = function(self, typeName)
+ rawset(self, typeName, 0)
+ return 0
+ end
+}
+
+local idsMetaTable = {
+ __index = function (self, typeName)
+ local col = setmetatable({}, {__mode = "kv"})
+ rawset(self, typeName, col)
+ return col
+ end
+}
+
+local function countTableAppearances(t, tableAppearances)
+ tableAppearances = tableAppearances or setmetatable({}, {__mode = "k"})
+
+ if type(t) == 'table' then
+ if not tableAppearances[t] then
+ tableAppearances[t] = 1
+ for k,v in pairs(t) do
+ countTableAppearances(k, tableAppearances)
+ countTableAppearances(v, tableAppearances)
+ end
+ countTableAppearances(getmetatable(t), tableAppearances)
+ else
+ tableAppearances[t] = tableAppearances[t] + 1
+ end
+ end
+
+ return tableAppearances
+end
+
+local function parse_filter(filter)
+ if type(filter) == 'function' then return filter end
+ -- not a function, so it must be a table or table-like
+ filter = type(filter) == 'table' and filter or {filter}
+ local dictionary = {}
+ for _,v in pairs(filter) do dictionary[v] = true end
+ return function(x) return dictionary[x] end
+end
+
+local function makePath(path, key)
+ local newPath, len = {}, #path
+ for i=1, len do newPath[i] = path[i] end
+ newPath[len+1] = key
+ return newPath
+end
+
+-------------------------------------------------------------------
+function inspect.inspect(rootObject, options)
+ options = options or {}
+ local depth = options.depth or math.huge
+ local filter = parse_filter(options.filter or {})
+
+ local tableAppearances = countTableAppearances(rootObject)
+
+ local buffer = {}
+ local maxIds = setmetatable({}, maxIdsMetaTable)
+ local ids = setmetatable({}, idsMetaTable)
+ local level = 0
+ local blen = 0 -- buffer length
+
+ local function puts(...)
+ local args = {...}
+ for i=1, #args do
+ blen = blen + 1
+ buffer[blen] = tostring(args[i])
+ end
+ end
+
+ local function down(f)
+ level = level + 1
+ f()
+ level = level - 1
+ end
+
+ local function tabify()
+ puts("\n", string.rep(" ", level))
+ end
+
+ local function commaControl(needsComma)
+ if needsComma then puts(',') end
+ return true
+ end
+
+ local function alreadyVisited(v)
+ return ids[type(v)][v] ~= nil
+ end
+
+ local function getId(v)
+ local tv = type(v)
+ local id = ids[tv][v]
+ if not id then
+ id = maxIds[tv] + 1
+ maxIds[tv] = id
+ ids[tv][v] = id
+ end
+ return id
+ end
+
+ local putValue -- forward declaration that needs to go before putTable & putKey
+
+ local function putKey(k)
+ if isIdentifier(k) then return puts(k) end
+ puts( "[" )
+ putValue(k, {})
+ puts("]")
+ end
+
+ local function putTable(t, path)
+ if alreadyVisited(t) then
+ puts('<table ', getId(t), '>')
+ elseif level >= depth then
+ puts('{...}')
+ else
+ if tableAppearances[t] > 1 then puts('<', getId(t), '>') end
+
+ local dictKeys = getDictionaryKeys(t)
+ local length = #t
+ local mt = getmetatable(t)
+ local to_string_result = getToStringResultSafely(t, mt)
+
+ puts('{')
+ down(function()
+ if to_string_result then
+ puts(' -- ', escape(to_string_result))
+ if length >= 1 then tabify() end -- tabify the array values
+ end
+
+ local needsComma = false
+ for i=1, length do
+ needsComma = commaControl(needsComma)
+ puts(' ')
+ putValue(t[i], makePath(path, i))
+ end
+
+ for _,k in ipairs(dictKeys) do
+ needsComma = commaControl(needsComma)
+ tabify()
+ putKey(k)
+ puts(' = ')
+ putValue(t[k], makePath(path, k))
+ end
+
+ if mt then
+ needsComma = commaControl(needsComma)
+ tabify()
+ puts('<metatable> = ')
+ putValue(mt, makePath(path, '<metatable>'))
+ end
+ end)
+
+ if #dictKeys > 0 or mt then -- dictionary table. Justify closing }
+ tabify()
+ elseif length > 0 then -- array tables have one extra space before closing }
+ puts(' ')
+ end
+
+ puts('}')
+ end
+
+ end
+
+ -- putvalue is forward-declared before putTable & putKey
+ putValue = function(v, path)
+ if filter(v, path) then
+ puts('<filtered>')
+ else
+ local tv = type(v)
+
+ if tv == 'string' then
+ puts(smartQuote(escape(v)))
+ elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then
+ puts(tostring(v))
+ elseif tv == 'table' then
+ putTable(v, path)
+ else
+ puts('<',tv,' ',getId(v),'>')
+ end
+ end
+ end
+
+ putValue(rootObject, {})
+
+ return table.concat(buffer)
+end
+
+setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end })
+
+return inspect
+
diff --git a/macros/luatex/latex/luatodonotes/luatodonotes.dtx b/macros/luatex/latex/luatodonotes/luatodonotes.dtx
new file mode 100644
index 0000000000..2351cfbf6c
--- /dev/null
+++ b/macros/luatex/latex/luatodonotes/luatodonotes.dtx
@@ -0,0 +1,2082 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2014-2017 by Fabian Lipp <fabian.lipp@gmx.de>
+% based on the todonotes package
+% by Henrik Skov Midtiby <henrikmidtiby@gmail.com>
+% ------------------------------------------------------------
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.2
+% of this license or (at your option) any later version.
+% The latest version of this license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.2 or later is part of all distributions of LaTeX
+% version 1999/12/01 or later.
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{luatodonotes.dtx}
+%</driver>
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{luatodonotes}
+%<*package>
+ [2017/09/30 v0.4 luatodonotes source and documentation.]
+%</package>
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{wrapfig}
+\PassOptionsToPackage{colorlinks, urlcolor=blue}{hyperref}
+\usepackage{hypdoc} % this package loads hyperref among others
+\usepackage[colorinlistoftodos, shadow]{luatodonotes}[2017/09/30]
+\usepackage{fontspec}
+\usepackage{amsmath}
+\usepackage{setspace}
+\usepackage{soul}
+\setcounter{tocdepth}{2}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\begin{document}
+ \DocInput{luatodonotes.dtx}
+%\iffalse
+% \PrintChanges
+% \PrintIndex
+%\fi
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{906}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \changes{0.1}{2014/08/07}{The first version of the package}
+% \changes{0.2}{2015/01/13}{Fix wrong linespacing when changing fontsize}
+% \changes{0.2}{2015/01/13}{Included suggestions from CTAN submission into
+% documentation}
+% \changes{0.2}{2015/03/12}{Added troubleshooting section to documentation}
+% \changes{0.3}{2015/12/03}{Incorporated some changes from todonotes (version
+% 1.0.4)}
+% \changes{0.4}{2017/10/01}{Incorporated some changes from todonotes (version
+% 1.0.5)}
+% \GetFileInfo{luatodonotes.dtx}
+%
+% \DoNotIndex{\newcommand,\newenvironment}
+%
+% \iffalse
+% A macro for marking things todo before the next relase
+% (typically update of documentation).
+% \fi
+% \newcommand{\donow}[1]{\todo[color=blue]{#1}}
+%
+%
+% \title{The \textsf{luatodonotes} package\thanks{This document
+% corresponds to \textsf{luatodonotes}~\fileversion, dated \filedate.}}
+% \author{Fabian Lipp\thanks{This documentation and the whole package is based
+% on version 1.0.2 of the todonotes package by Henrik Skov Midtiby.} \\
+% \texttt{fabian.lipp@gmx.de}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% The |luatodonotes| package allows you to insert to--do items in your
+% document. At any point in the document a list of all the inserted
+% to--do items can be listed with the |\listoftodos| command.
+%
+% It is an extended version of the |todonotes| package and uses more advanced
+% algorithms to place the to--do notes on the page.
+% For this algorithms it depends on Lua\TeX.
+% \end{abstract}
+%
+% \pdfbookmark[1]{Contents}{contents}
+% \tableofcontents
+%
+% \newpage
+% \section{Introduction}
+%
+% The |luatodonotes| package makes three commands available to the
+% user: |\todo[]{}|, |\missingfigure{}| and |\listoftodos|.
+% |\todo[]{}| and |\missingfigure{}| makes it possible to insert
+% notes in your document about things that has to be done later
+% (todonotes \ldots).
+% This package is based on version 1.0.2 of
+% |todonotes|\footnote{\url{http://www.ctan.org/pkg/todonotes}} by Henrik Skov
+% Midtiby.
+%
+% The positions of the notes on the page is determined using algorithms
+% implemented in Lua, so you have to process your documents using Lua\LaTeX.
+% The package can be used as a drop-in replacement for the original
+% |todonotes| package, you
+% only need to modify |\usepackage{todonotes}| to |\usepackage{luatodonotes}|.
+% Note that |todonotes| and |luatodonotes| must not be loaded inside the same
+% document.
+%
+% Some alternatives for the luatodonotes package are:
+% \begin{itemize}
+% \item \href{http://www.ctan.org/pkg/easy-todo}{easy-todo}\\
+% Depends on |color|, |tocloft| and |ifthen|, small feature set.
+% \item \href{http://www.ctan.org/pkg/fixmetodonotes}{fixmetodonotes}\\
+% Depends on |graphicx|, |color|, |transparent|, |watermark|, |fix-cm|, |ulem| and |tocloft|, small feature set.
+% \item \href{http://www.ctan.org/pkg/todo}{todo}\\
+% Depends on |amssymb|, medium feature set.
+% \item \href{http://www.ctan.org/pkg/fixme}{fixme}\\
+% Large package with a lot of features.
+% \item \href{http://www.ctan.org/pkg/todonotes}{todonotes}
+% \end{itemize}
+%
+% Compared to the classical todonotes this package has more advanced algorithms
+% and more configuration options to control the position of the notes on the
+% page.
+% Additionally, we are able to place notes at almost every position on the
+% page, e.\,g., in floating environments or in footnotes.
+% As a disadvantage luatodonotes requires Lua\LaTeX{} for document processing, so
+% a standard |pdflatex| won't work.
+% Depending on the chosen layout for the to--do notes the runtime can be much
+% higher than with todonotes.
+% Labels placed by luatodonotes can conflict with text placed with
+% |\marginpar|.
+%
+% The main reason for considering other packages is that the todonotes
+% package is quite large and relies heavily on tikz.
+% This can slow down compilation of large documents significantly.
+% The mentioned alternatives have a different feature set and do not
+% rely on tikz, which makes them require less ressoureces.
+%
+%
+%
+% \subsection{Using Lua\LaTeX}
+% It is quite easy to switch from |pdflatex| to |lualatex|.
+% You only have to load a few different packages.
+% A small guide can be found in the Lua\LaTeX{}
+% guide\footnote{\url{http://mirror.ctan.org/info/luatex/lualatex-doc/lualatex-doc.pdf}}.
+%
+% The Lua\TeX{} processor (the |lualatex| executable) should be included in all
+% modern \TeX{} distributions, so you do not need to install additional
+% software.
+% You simply have to run |lualatex| instead of |pdflatex| (or instead of
+% |latex|, |xelatex|).
+%
+%
+%
+% \subsection{Usage of luatodonotes}
+% The package is loaded with |\usepackage|\oarg{options}|{luatodonotes}|.
+% Valid options are described in Section~\ref{subsecPackageOptions}.
+% Note that |todonotes| must \emph{not} be loaded.
+% You have to use |lualatex| to process your document, |pdflatex| will not
+% work.
+% The package depends on positions written to the aux-file, so you have to run
+% |lualatex| twice or even three times to get the labels and leaders for the
+% notes right.
+%
+% \DescribeMacro{\todo}
+% My \index{\todo}most common usage of the todonotes package, is to
+% insert an todonotes somewhere in a latex document.
+% An example of this usage is the command
+%
+% |\todo{Make a cake \ldots}|,
+%
+% \noindent
+% which renders like\todo{Make a cake \ldots}.
+% The |\todo| command has this structure:
+% |\todo|\oarg{options}\marg{todo text}.
+% The |todo text| is the text that will be shown in the todonote and
+% in the list of todos. The optional argument |options|, allows the
+% user to customize the appearance of the inserted todonotes.
+% For a description of all the options see section
+% \ref{subsecTodoOptions}.
+%
+% \DescribeMacro{\todoarea}
+% The |\todoarea| is similiar to |\todo|, but is able to highlight a specified
+% area in the text, to which the note is connected.
+% The command has this structure:
+% |\todoarea|\oarg{options}\marg{note text}\marg{highlighted text}.
+% This command was not tested extensively until now, so it should be used with
+% caution.
+%
+% \DescribeMacro{\missingfigure}
+% The |\missingfigure| command inserts an image containing an
+% attention sign and the given text.
+% The command takes only one argument
+% |\missingfigure|\marg{text}, a text string that could
+% describe what the figure should consist of.
+% An example of its usage could be
+%
+% |\missingfigure{Make a sketch of the structure of a trebuchet.}|
+%
+% \noindent
+% which renders like.
+%
+% \missingfigure{Make a sketch of the structure of a trebuchet.}
+%
+%
+% \DescribeMacro{\listoftodos}
+% The |\listoftodos| command inserts a list of all the todos in the
+% current document. |\listoftodos| takes no arguments.
+% For this document the list of to--do's looks like.
+% \listoftodos
+% \vspace{0.5cm}
+%
+% \DescribeMacro{\todototoc}
+% The |\todototoc| command adds an entry to the table of contents for
+% list of todos. The command should be placed right before the
+% |\listoftodos| command.
+%
+% \subsection{Package options}
+% \label{subsecPackageOptions}
+% \DescribeMacro{disable}
+% If the option |disable| is passed to the package, the macros
+% usually defined by the package (|\todo|, |\todoarea|, |\listoftodos| and
+% |\missingfigure|) are defined as macros with no effect, and thus
+% all inserted notes are removed.
+%
+% \DescribeMacro{obeyDraft, obeyFinal}
+% When the option |obeyDraft| is given, the package checks
+% if the one of the options |draft|, |draftcls| or |draftclsnofoot|
+% is given (this option is usually given to
+% the documentclass). If the |draft| option is given, the
+% functionality of the package is enabled and otherwise the effect
+% of the package is disabled.
+% The option |obeyFinal| does something similar, except that the
+% todonotes package is only disabled if the |final| option given.
+%
+% \DescribeMacro{danish, german, ngerman, english, french, swedish}
+% \DescribeMacro{spanish, catalan, italian}
+% \DescribeMacro{portuguese, dutch, croatian}
+% Use translations of the text strings
+% ''List of todos'' and ''Missing figure''.
+% The default is to use none of these options, which results in
+% english text strings.
+% Currently the following languages are supported:
+% catalan,
+% croatian,
+% danish,
+% dutch,
+% english,
+% french,
+% german,
+% ngerman,
+% italian,
+% portuguese,
+% spanish and
+% swedish.
+%
+% \DescribeMacro{colorinlistoftodos}
+% Adds a small colored square in front of all items in the Todo
+% list. The color of the square is the same as the fill color of the
+% inserted todonote.
+% This can be useful if there are different types of todos
+% (insert reference, explain in detail, \ldots) where the color of
+% the inserted todonote marks the type of todo.
+%
+% \DescribeMacro{color}
+% \DescribeMacro{backgroundcolor}
+% \DescribeMacro{linecolor}
+% \DescribeMacro{bordercolor}
+% These options sets the default colors for the todo command.
+% There is three colors that can be specified. The border color
+% (default |bordercolor=black|) around the inserted text, the color
+% behind the inserted text (default |backgroundcolor=orange|) and
+% the color of the line connecting the inserted textbox with the
+% current location in the text (default |linecolor=black!30|).
+% Setting the |color| option to |val| passes this value on to the
+% background and line color options.
+% The specified colors must be valid according to the
+% |xcolor| package.
+%
+% \DescribeMacro{textsize}
+% |textsize=value| sets the default text size of the inserted
+% todonotes to the given value.
+% Value is the ''name'' of the used font size, eg. if the desired
+% fontsize is |\tiny| use |textsize=tiny|. The default value is
+% |textsize=normalsize|.
+%
+% \DescribeMacro{prependcaption}
+% The |prependcaption| option triggers a special behaviour of the
+% |caption=val| option for the todo command, where the given value
+% |val| is inserted in the inserted todonote.
+%
+% \DescribeMacro{shadow}
+% If the |shadow| option is given, the inserted todonotes will be
+% displayed with a gray shadow.
+% I expect that the option will trigger problems with tikz versions
+% prior to 2.0.
+%
+% \DescribeMacro{figwidth}
+% \DescribeMacro{figheight}
+% The |figwidth=length| option and |figheight=length| option set the default
+% width and height of the figure
+% inserted by the |\missingfigure| command.
+% The default value is |\linewidth| for the width and |4cm| for the height.
+%
+% \DescribeMacro{leaderwidth}
+% The |leaderwidth=length| option specifies the width of the leader lines.
+% The argument is passed to the |line width| option in TikZ.
+% The default value is |1.6pt|.
+%
+% \DescribeMacro{leadertype}
+% The |leadertype=type| option specifies the shape of the leaders, which are
+% drawn between the labels in the margin and the corresponding sites in text.
+% We use the characterization of the leader types known from boundary labeling:
+% $p$ denotes a segment parallel to the left/right side of the text area, while
+% $o$ denotes a orthogonal segment.
+% $s$ is a straight-line segment.
+% The following types are available (|opo| is the default value):
+% \begin{itemize}
+% \item |s|:
+% Straight-line connection between site and label.
+% \item |sBezier|:
+% Uses the straight-line leaders but transforms them into B\'ezier curves,
+% which are easier to follow for the reader.
+% The generated curves don't cross each other when the straight-line leaders
+% are crossing-free.
+% \item |opo|:
+% This is the style used in the original todonotes package.
+% The leaders start with a horizontal segment at the site in the text,
+% followed by a vertical segment in the margin beneath the text.
+% The last segment is a vertical segment, which connects to the label.
+% \item |os|:
+% This is the style used in common word processing applications like
+% LibreOffice.
+% The leader also starts with a horizontal segment that leads to the margin
+% and is connected to the label by a straight line.
+% \item |po|:
+% The leader starts with a vertical segment at the site in text and is then
+% connected to the label by a horizontal segment.
+% \end{itemize}
+%
+% \DescribeMacro{positioning}
+% The |positioning=algorithm| option specifies, which algorithm is used to
+% determine the positions of the notes on the page.
+% You should choose the algorithm depending on the leader type you want to use.
+% You can also use one of the options |s|, |po|, |bezier|, or |opo| to define
+% the positioning algorithm together with the leadertype.
+% The default value for this option is |inputOrderStacks|.
+% The following algorithms are available:
+% \begin{itemize}
+% \item |inputOrder|:
+% Place the labels in the order given by the
+% y-coordinates of the corresponding sites in text.
+% Intended for use with $opo$- or $os$-leaders.
+% \item |inputOrderStacks|:
+% Like the algorithm before, but the labels are
+% clustered before they are placed.
+% Thus the labels are placed nearer to their sites.
+% Intended for use with $opo$- or $os$-leaders.
+% \item |sLeaderNorthEast|:
+% Places labels in a way that they can be connected to their sites by
+% straight-line leaders without crossings.
+% The leaders are attached to the upper right or upper left corner of the
+% label (depending on which site of the text the label is placed).
+% Intended for use with $s$-leaders or B\'ezier leaders.
+% \item |sLeaderNorthEastBelow|:
+% Like the algorithm before, but the leader is attached to a point that is a
+% constant offset below the corner of the label.
+% Intended for use with $s$-leaders or B\'ezier leaders.
+% \item |sLeaderNorthEastBelowStacks|:
+% Like the algorithm before, but the labels are cluster before they are
+% placed.
+% Thus the labels are placed nearer to their sites.
+% Intended for use with $s$-leaders or B\'ezier leaders.
+% \item |sLeaderEast|:
+% Like the algorithms before, but the leader is attached to the center of the
+% right or left boundary of the label.
+% Intended for use with $s$-leaders or B\'ezier leaders.
+% \item |poLeaders|:
+% Calculates label positions that lead to $po$-leaders with minimum total
+% length.
+% This algorithm depends heavily on the number of notes, so the runtime and
+% memory consumption can get very high.
+% \item |poLeadersAvoidLines|:
+% Like the algorithm before, but tries to avoid overlapping of horizontal
+% leader segments with text.
+% This algorithm depends heavily on advanced Lua\TeX\ features to manipulate
+% the data structures of the page, so it possibly could give conflicts with
+% other packages.
+% \end{itemize}
+%
+% \DescribeMacro{s}
+% \DescribeMacro{bezier}
+% \DescribeMacro{opo}
+% \DescribeMacro{po}
+% Shorthand options for convenience, which represent common combinations of
+% leadertypes and postioning algorithms.
+% |leadertype| or |positioning| options following one of these options override
+% its settings.
+% They use the following positioning algorithms:
+% \begin{itemize}
+% \item |s|: |sLeaderNorthEastBelowStacks|
+% \item |bezier|: |sLeaderNorthEastBelowStacks|
+% \item |opo|: |inputOrderStacks|
+% \item |po|: |poLeadersAvoidLines|
+% \end{itemize}
+%
+% \DescribeMacro{splitting}
+% The |splitting=algorithm| option can be used to place the labels on both sides
+% of the text.
+% The notes are only separated when there is enough space on both sides (see
+% |minNoteWidth|.
+% The default value for this option is |none|.
+% Available algorithms for this option are:
+% \begin{itemize}
+% \item |none|:
+% Labels are placed in the wider margin only.
+% \item |middle|:
+% The text area is split in the middle in a left and a right half.
+% Labels, whose sites are in the left half of the text, are placed in the
+% left margin, the others in the right margin.
+% \item |median|:
+% The notes are seperated at the median of the sites (sorted by
+% x-coordinate).
+% That is, the number of notes in the left and the right margin is equal
+% (except for one note).
+% \item |weightedMedian|:
+% Considers the height of the labels for the median.
+% So the total height of the labels in the left margin is approximately equal
+% to that in the right margin.
+% \end{itemize}
+%
+% \DescribeMacro{interNoteSpace}
+% The |interNoteSpace=length| option specifies the minimum vertical distance
+% between two notes.
+% The default value is |5pt|.
+%
+% \DescribeMacro{noteInnerSep}
+% The |noteInnerSep=length| option specifies the |inner sep| used for the TikZ
+% nodes, i.\,e., the distance between the border of the note and the text inside
+% it.
+% The default value is |5pt|.
+%
+% \DescribeMacro{routingAreaWidth}
+% The |routingAreaWidth=length| option specifies the width of the so called
+% routing area.
+% This is the area, in which the vertical segment of $opo$-leaders are placed.
+% The area is also used for $os$-leaders.
+% The default value is |0.4cm|.
+%
+% \DescribeMacro{minNoteWidth}
+% The |minNoteWidth=length| option specifies the minimum width of the labels.
+% When there is fewer space in one of the margins, this margin is not considered
+% for label placement.
+% If both margins are narrower, no labels are placed and an error message is
+% printed to the console output.
+% The default value of this option is |2.0cm|.
+%
+% \DescribeMacro{distanceNotesPageBorder}
+% The |distanceNotesPageBorder=length| option specifies the horizontal distance
+% from the labels to the borders of the paper.
+% You can adjust this setting to your printer margins.
+% The default value of this option is |0.5cm|.
+%
+% \DescribeMacro{distanceNotesText}
+% The |distanceNotesPageBorder=length| option specifies the horizontal distance
+% between the labels and the text area.
+% With $opo$- or $os$-leaders the routing area is inserted additionally so the
+% distance between labels and text area increases.
+% The default value of this option is |0.2cm|.
+%
+% \DescribeMacro{rasterHeight}
+% The |rasterHeight=length| option is used only for the $po$-leader algorithm.
+% For this algorithm the page is rasterized and the labels are placed only on
+% the positions given by this raster.
+% Decreasing this value can yield better results (i.\,e., smaller total leader
+% length), but strongly increases the runtime and memory consumption.
+% The default value of this option is |1cm|.
+%
+% \DescribeMacro{additionalMargin}
+% The |additionalMargin=length| option extends the page margins horizontally.
+% To achieve this the page width is increased.
+% The page is extended by the given length on both sides.
+% The layout of the page stays the same but the paper format is changed: the
+% height is left unmodified, but the width is increased by the doubled value of
+% the given length.
+% This option is useful if you have to adhere to a given layout, whose margins
+% are not wide enough to accomodate the notes.
+% You can safely use this option as the final layout of your document does not
+% change when disabling the |luatodonotes| package.
+% The default width of |2cm| for the additional margin is used when the option
+% is given without a length.
+%
+% \DescribeMacro{debug}
+% When the |debug| option is activated the package is more verbose on
+% the commandline.
+% Additionally, some markers, which can be used to understand the algorithms,
+% are drawn on the page (depending on the chosen algorithm).
+%
+%
+%
+%
+% \subsection{Options for the \texttt{todo} command}
+% \label{subsecTodoOptions}
+% There are several options that can be given to the |\todo|
+% command. All the options are described here and often I have
+% included examples of the change in visual appearance.
+% Default values for these options can be set using the presetkeys
+% command.
+% \begin{verbatim}
+% \presetkeys{todonotes}{fancyline, color=blue!30}{}
+% \end{verbatim}
+%
+% \DescribeMacro{disable}
+% The |disable| option can be given directly to the todo command.
+% If given the command has no effect.
+%
+% \DescribeMacro{color}
+% \DescribeMacro{backgroundcolor}
+% \DescribeMacro{linecolor}
+% \DescribeMacro{bordercolor}
+% These options set the color that is used in the current todo
+% command.
+% The color classes is the same as used in the color package
+% options, see section \ref{subsecPackageOptions}.
+% Default values can be set by the color
+% options when the todonotes package is loaded.
+% \todo[color=green!40]{And a green note}
+% The todo notes inserted in this paragraph is created with the
+% command
+% |\todo[color=green!40]{And a green note}|.
+% The color of the inserted note could be used to mark different
+% types of tasks (insert references, explain something in detail,
+% \ldots), this could be streamlined by defining new commands like
+% below.
+% \begin{verbatim}
+% \newcommand{\insertref}[1]{\todo[color=green!40]{#1}}
+% \newcommand{\explainindetail}[1]{\todo[color=red!40]{#1}}
+% \end{verbatim}
+% An example that uses all of the color options is given below
+% \todo[linecolor=green!70!white, backgroundcolor=blue!20!white,
+% bordercolor=red]{Anything but default colors}.
+% \begin{verbatim}
+% \todo[linecolor=green!70!white, backgroundcolor=blue!20!white,
+% bordercolor=red]{Anything but default colors}.
+% \end{verbatim}
+%
+%
+% \DescribeMacro{line / noline}
+% If you want to get rid of the line connecting the inserted note
+% with the place in the text where the note occurs in the latex
+% code, the option |noline| can be used.
+% \todo[noline]{A note with no line connecting it to the placement
+% in the original text.}
+% |\todo[noline]{A note with no line ...}|
+% \vspace{1.0cm}
+%
+%
+% \DescribeMacro{inline / noinline}
+% It is possible to place a todonote inside the text instead of
+% placing it in the margin, this could be desirable if the text in
+% the note has a considerable length.
+% |\todo[inline]{A todonote placed in the text}|
+% \todo[inline]{A todonote placed in the text}
+
+% \begin{wrapfigure}[1]{r}[20mm]{40mm}
+% \begin{tikzpicture}
+% \draw[red] (0, 0) circle(0.45);
+% \draw[green] (1, 0) circle(0.45);
+% \draw[blue] (2, 0) circle(0.45);
+% \end{tikzpicture}
+% \caption{A text explaining the image.
+% \todo[inline]{Fill those circles \ldots}}
+% \end{wrapfigure}
+% Another usage for the inline option is when you want to add a
+% todonote to a figure caption.
+%
+% \begin{verbatim}
+% \begin{wrapfigure}{r}[20mm]{40mm}
+% \begin{tikzpicture}
+% \draw[red] (0, 0) circle(0.45);
+% \draw[green] (1, 0) circle(0.45);
+% \draw[blue] (2, 0) circle(0.45);
+% \end{tikzpicture}
+% \caption{A text explaining the image.
+% \todo[inline]{Fill those circles \ldots}}
+% \end{wrapfigure}
+% \end{verbatim}
+%
+% \DescribeMacro{size}
+% |size=val| changes the size of the text inside the todonote.
+% The commands used to create the notes below are \\ \noindent
+% |\todo[size=\Large]{A note with a large font size.}|
+% and \\ \noindent
+% |\todo[inline, size=\tiny]{Note with very small font size.}|.
+% \todo[size=\Large]{A note with a large font size.}
+% \todo[inline, size=\footnotesize]{Note with very small font size.}
+%
+% \DescribeMacro{list / nolist}
+% When the option |nolist| is given, the todo item will not appear in
+% the list of todos.
+%
+% \DescribeMacro{caption}
+% The |caption| option enables the user to specify a short
+% description of the todonote that are inserted in the list of
+% todos instead of the full todonote text.
+% \todo[caption={Short note}]{A very long and tedious note that
+% cannot be on one line in the list of todos.}
+% \begin{verbatim}
+% \todo[caption={Short note}]{A very long and tedious note that
+% cannot be on one line in the list of todos.}.
+% \end{verbatim}
+% The effect of this option is altered with the package option
+% |prependcaption| or the |prepend| / |noprepend| option for the
+% todo command.
+%
+% \DescribeMacro{prepend / noprepend}
+% The options |prepend| and |noprepend| can be used for setting
+% whether a given caption should be prepended to the todonote or
+% not.
+% Globally this can be set using the |prependcaption| option for the
+% package.~\todo[prepend, caption={Short note with prepend}]{A very
+% long and tedious note that cannot be on one line in the list of
+% todos.} Below is the effect of the option shown using the code:
+% \todo[noprepend, caption={Short note with noprepend}]{A very long
+% and tedious note that cannot be on one line in the list of
+% todos.}
+% \begin{verbatim}
+% \todo[prepend, caption={Short note with prepend}]{A very long and tedious
+% note that cannot be on one line in the list of todos.}.
+% \todo[noprepend, caption={Short note with noprepend}]{A very long and
+% tedious note that cannot be on one line in the list of todos.}.
+% \end{verbatim}
+%
+% \DescribeMacro{author}
+% The |author| option takes a parameter, the name of the author.
+% The given name is inserted in the todonote.
+% \todo[author=Xavier]{Testing author option.}
+% \todo[author=Xavier, inline]{Testing author option.}
+% \begin{verbatim}
+% \todo[author=Xavier]{Testing author option.}
+% \todo[author=Xavier, inline]{Testing author option.}
+% \end{verbatim}
+%
+% \subsection{Options for the \texttt{missingfigure} command}
+%
+% \DescribeMacro{figwidth}
+% The |figwidth=length| option sets the width of the figure inserted by the
+% |\missingfigure| command.
+% Length values below $6cm$ might trigger some problems with the
+% visual appearance.
+% Try to compare the default of the missing figure command, when the
+% option is given or not.
+% \begin{verbatim}
+% \missingfigure[figwidth=6cm]{Testing a long text string}
+% \end{verbatim}
+% \missingfigure[figwidth=6cm]{Testing a long text string}
+% \begin{verbatim}
+% \missingfigure{Testing a long text string}
+% \end{verbatim}
+% \missingfigure{Testing a long text string}
+% \begin{wrapfigure}{r}[2cm]{6cm}
+% \missingfigure[figwidth=6cm]{Add a test image \ldots}
+% \end{wrapfigure}
+% Another usage of the option is when |\missingfigure| is used in
+% the wrapfigure environment.
+% \begin{verbatim}
+% \begin{wrapfigure}{r}[2cm]{6cm}
+% \missingfigure[figwidth=6cm]{Add a test image \ldots}
+% \end{wrapfigure}
+% \end{verbatim}
+%
+% \DescribeMacro{figheight}
+% The |figheight=length| option changes the height of the inserted
+% missing figure.
+% The default height is 4cm and using values lower than this might
+% cause the warning sign to pop out of the gray area.
+% \begin{verbatim}
+% \missingfigure[figheight=6cm]{Testing a long text string}
+% \end{verbatim}
+% \missingfigure[figheight=6cm]{Testing}
+%
+%
+% \DescribeMacro{figcolor}
+% The |figcolor=color| options sets the background color of
+% inserted missing figures.
+% The default color is |black!40|.
+% \begin{verbatim}
+% \missingfigure[figcolor=white]{Testing figcolor}
+% \end{verbatim}
+% \missingfigure[figcolor=white]{Testing figcolor}
+%
+%
+%
+% \subsection{Options for the \texttt{listoftodos} command}
+% The |\listoftodos| command takes one optional argument, that
+% defines the name of the inserted list of todos.
+% \begin{verbatim}
+% \listoftodos[I can be called anything]
+% \end{verbatim}
+%
+%
+% \subsection{Troubleshooting}
+% \subsubsection{Missing Lua files}
+% A potential error message when Lua source files are not found, is the
+% following:
+% \begin{verbatim}
+% ! LuaTeX error [\directlua]:1: module 'luatodonotes' not found:
+% no field package.preload['luatodonotes']
+% [luatexbase.loader] Search failed
+% [kpse lua searcher] file not found: 'luatodonotes'
+% [kpse C searcher] file not found: 'luatodonotes'
+% [oberdiek.luatex.kpse_module_loader]-eroux Search failed
+% stack traceback:
+% [C]: in function 'require'
+% [\directlua]:1: in main chunk.
+% l.250 \directlua{require("luatodonotes")}
+% \end{verbatim}
+% This means that the file |luatodonotes.lua| cannot be found by Lua\TeX.
+% It depends on the version of your \TeX{} installation. in which directories
+% Lua\TeX{} is looking for Lua source files.
+% You can query these paths with the following command:
+% \begin{verbatim}
+% kpsewhich -show-path=lua\end{verbatim}
+% See the |kpathsea|
+% documentation\footnote{\url{http://tug.org/texinfohtml/kpathsea.html}} for
+% the interpretation of this path.
+% The Lua source files of the |luatodonotes| package should be in one of the
+% searched directories.
+% You can modify the path in your \TeX{} configuration or using environment
+% variables.
+% You can query kpathsea for a file using the default \TeX{} search path with:
+% \begin{verbatim}
+% kpsewhich luatodonotes.lua\end{verbatim}
+% Be sure to run |texhash| (as root if needed) after moving files into the
+% texmf tree.
+%
+% \subsubsection{The \texttt{debug} option}
+% You can load the package with the option |debug| (see
+% Section~\ref{subsecPackageOptions}).
+% It gives some additional information in the console while running Lua\TeX{}
+% and draws additional information into the output document.
+% For example, the size of the computed areas, in which the labels are placed,
+% is shown in the document.
+% Depending on the chosen layout algorithm some intermediate steps of the
+% algorithms are given.
+%
+%
+%
+%
+%
+% \subsection{Known issues}
+% \subsubsection{Package loading order}
+% The luatodonotes package requires the following packages:
+% \begin{multicols}{2}
+% \begin{itemize}
+% \item ifthen
+% \item xkeyval
+% \item xcolor
+% \item tikz
+% \item graphicx (is loaded via the tikz package)
+% \item luacode
+% \item luatex
+% \item atbegshi
+% \item xstring
+% \item zref-abspage
+% \item ifoddpage
+% \item soul
+% \item soulpos
+% \end{itemize}
+% \end{multicols}
+% \noindent
+% When luatodonotes are loaded in the preamble, the package checks
+% if these packages all are loaded. If that is not the case it loads
+% the missing packages with no options given.
+% If you want to give some specific options to some of these
+% packages, you have to load them \emph{before} the luatodonotes
+% package, otherwise you will get an ''Option clash'' error when
+% latex works on the document.
+%
+% If both the menukeys and the xcolor (with the option \verb!table!)
+% package should be loaded, the following order must be used.
+% \begin{verbatim}
+%\usepackage[table]{xcolor}
+%\usepackage{todonotes}
+%\usepackage{menukeys}
+% \end{verbatim}
+%
+% \subsubsection{Spacing around inserted notes}
+% Inserted todo commands will eat the white space after the command.
+% \begin{verbatim}
+%Testing\todo{Does this eat the space?} testing.\end{verbatim}
+% \noindent
+% Testing\todo{Does this eat the space?} testing.
+%
+% This can be prevented by adding curly parenthesis after the
+% todo command, like shown below.
+% \begin{verbatim}
+%Testing\todo{Does this eat the space?}{} testing.\end{verbatim}
+% \noindent
+% Testing\todo{Does this eat the space?}{} testing.
+%
+%
+%
+% \subsubsection{Conflicts with the amsart documentclass}
+% The |amsart| document class redefines some internal commands that
+% is used by the todonotes package, this will cause an malfunctioning
+% |\listoftodos| command.
+% The following code to circumvent the problem was given by Dan
+% Luecking on comp.text.tex
+% \begin{verbatim}
+% \makeatletter
+% \providecommand\@dotsep{5}
+% \makeatother
+% \listoftodos\relax
+% \end{verbatim}
+%
+% NOT TESTED
+% NOT TESTED
+% NOT TESTED
+%
+% Dominique suggests the following workaround.
+% \begin{verbatim}
+% \makeatletter
+% \providecommand\@dotsep{5}
+% \def\listtodoname{List of Todos}
+% \def\listoftodos{\@starttoc{tdo}\listtodoname}
+% \makeatother
+% \end{verbatim}
+%
+%
+%
+% \subsubsection{Unknown option ''remember picture''}
+% If latex throws the error
+% \begin{verbatim}
+% Package tikz Error: I do not know what to do with the option ``remember picture''.
+% \end{verbatim}
+% It probably means that your latex installation is outdated, as
+% only newer versions of latex driver for tikz supports the
+% |remember picture| option.
+% For additional info consult
+% ''Section 10.2.2 Producing PDF Output'' in the tikz manual.
+% \url{http://mirror.ctan.org/graphics/pgf/base/doc/pgfmanual.pdf}
+%
+%
+%
+% \subsubsection{List of todo heading is not correctly formatted}
+% If using natbib, the todonotes list title gets screwed up unless
+% you do something like this:
+% \begin{verbatim}
+% \makeatletter\let\chapter\@undefined\makeatother
+% \end{verbatim}
+% Suggestion by Richard Stanton.
+%
+%
+%
+% \subsubsection{Some commands not working inside notes}
+% Some commands will not work like expected, when used inside of a note.
+% They will cause errors when processing the document or have simply no effect.
+% This is caused by the mechanism used to layout the notes:
+% The content is written into a hbox when a |\todo| is encountered.
+% The contents of this box are then stored until the note is typeset.
+% By that time the contents are taken out of the hbox (by |\unhbox|) and put
+% into a |\parbox| with the width required for the note.
+% I don't have a solution for this problem yet.
+%
+%
+%
+%
+%
+% \iffalse
+% \StopEventually{\PrintChanges\PrintIndex}
+% \fi
+% \StopEventually{\clearpage\pdfbookmark{Changes}{changes}\PrintChanges}
+%
+% \newpage
+% \section{Implementation}
+% \begin{environment}{luatodonotes.lua}
+% In this section only the source code of the LaTeX package file
+% (|luatodonotes.sty|) is shown.
+% The Lua code is contained in |luatodonotes.lua| and documented by comments
+% inside this file.
+% These comments are primarily describing technical aspects.
+% Information about the implemented algorithms and some theoretical
+% considerations can be found in the following documents:
+% \begin{itemize}
+% \item Kindermann, P., Lipp, F., and Wolff, A.:
+% Luatodonotes: Boundary Labeling for Annotations in Texts.
+% In: Duncan, C. and Symvonis, A. (eds.) Proc. 22nd Int. Sympos. Graph Drawing GD'14.
+% LNCS, vol. 8871, pp. 76-88. Springer, Heidelberg (2014)
+% \url{http://dx.doi.org/10.1007/978-3-662-45803-7_7}
+% \item Lipp, F.:
+% Boundary Labeling for Annotations in Texts.
+% Master thesis, 2014.
+% \url{http://www1.pub.informatik.uni-wuerzburg.de/pub/theses/2014-lipp-master.pdf}
+% \end{itemize}
+% \changes{0.2}{2014/09/08}{Compatibility with csquotes package (notes were
+% displayed multiple times when used in \texttt{\textbackslash blockquote}
+% command)}
+% \changes{0.2}{2015/02/28}{Correct height calculation for notes with modified
+% fontsize}
+% \changes{0.2}{2015/02/28}{Make Lua variables and functions local or put them
+% into luatodonotes array (don't pollute global namespace)}
+% \changes{0.2}{2015/03/03}{Fix problems with recent versions of lualibs}
+% \changes{0.3}{2015/10/30}{Fix problems with doubled notes when code is read
+% multiple times (e.g., by tabularx)}
+% \changes{0.3}{2015/11/16}{Deal with notes without a page number (happens when
+% placed in \texttt{\textbackslash caption}, e.g.)}
+% \changes{0.3}{2015/11/30}{Remove two variables from Lua global namespace}
+% \changes{0.3}{2015/12/02}{Less console output unless debug option is set}
+% \end{environment}
+%
+% \subsection{Dependencies and definitions}
+% Make sure that the classical |todonotes| package is not loaded as we redefine
+% its commands.
+% Additionally we pretend that |todonotes| 1.0.2 is already loaded.
+% So later attempts to load package |todonotes| are simply ignored.
+% Loading both packages in the same document would produce errors (like
+% ``Command already defined'').
+% \changes{0.3}{2015/12/01}{Ensure that package \texttt{todonotes} is not
+% loaded}
+% \begin{macrocode}
+\@ifpackageloaded{todonotes}{
+ \PackageError{luatodonotes}{%
+ Conflicting packages todonotes and luatodonotes\MessageBreak
+ loaded. Aborting.}{%
+ The package luatodonotes was designed as a replacement for todonotes. So it
+ is not possible (and not reasonable) to include both of them in the same
+ document.%
+ If you want to use luatodonotes you should delete the todonotes
+ package from\MessageBreak
+ your preamble.\MessageBreak}
+}{}
+\expandafter\def\csname ver@todonotes.sty\endcsname{2014/07/14}
+% \end{macrocode}
+% Check if Lua\TeX{} is used.
+% \changes{0.2}{2015/02/23}{Check if LuaTeX is used at begin of package}
+% \begin{macrocode}
+\RequirePackage{ifluatex}
+\ifluatex\else
+ \PackageError{luatodonotes}{LuaTeX is required for this package. Aborting.}{%
+ This package can only be used with the LuaTeX engine\MessageBreak
+ (command `lualatex'). Package loading has been stopped\MessageBreak
+ to prevent additional errors.}
+\fi
+% \end{macrocode}
+% Loads the packages dependencies.
+% \begin{macrocode}
+\RequirePackage{ifthen}
+\RequirePackage{xkeyval}
+\RequirePackage{xcolor}
+\RequirePackage{tikz}
+\usetikzlibrary{positioning}
+\usetikzlibrary{intersections}
+\usetikzlibrary{decorations.pathmorphing}
+\RequirePackage{luacode}
+\RequirePackage{atbegshi}
+\RequirePackage{xstring}
+\RequirePackage{zref-abspage}
+\RequirePackage{ifoddpage}
+\RequirePackage{soul}
+\RequirePackage{soulpos}
+\RequirePackage{etoolbox}
+% \end{macrocode}
+% The package |luatex| must not be loaded in new TeX distributions as the
+% definition of |\newattribute| in it conflicts with newer versions of
+% Lua\LaTeX.
+% Older versions of |luatexbase| include the package |luatex| by themselves, for
+% newer versions the Lua\LaTeX kernel should include the commands that we need
+% (e.\,g., |\newattribute|).
+% \changes{0.3}{2015/11/12}{Remove package \texttt{luatex} for current
+% versions of Lua\LaTeX (as it caused problems)}
+% \begin{macrocode}
+\@ifpackagelater{luatexbase}{2013/05/04}{}{
+ \RequirePackage{luatex}
+}
+% \end{macrocode}
+% Some default values are set
+% \begin{macrocode}
+\newcommand{\@todonotes@text}{}%
+\newcommand{\@todonotes@backgroundcolor}{orange}
+\newcommand{\@todonotes@linecolor}{black!30}
+\newcommand{\@todonotes@bordercolor}{black}
+\newcommand{\@todonotes@leaderwidth}{1.6pt}
+\newcommand{\@todonotes@textsize}{\normalsize}
+\newcommand{\@todonotes@figwidth}{\linewidth}
+\newcommand{\@todonotes@figheight}{4cm}
+\newcommand{\@todonotes@figcolor}{black!40}
+% \end{macrocode}
+% Default values for variables added by luatodonotes
+% \begin{macrocode}
+\newcommand{\@todonotes@positioning}{inputOrderStacks}
+\newcommand{\@todonotes@splitting}{none}
+\newcommand{\@todonotes@leadertype}{opo}
+\newcommand{\@todonotes@interNoteSpace}{5pt}
+\newcommand{\@todonotes@noteInnerSep}{5pt}
+\newcommand{\@todonotes@routingAreaWidth}{0.4cm}
+\newcommand{\@todonotes@minNoteWidth}{2.0cm}
+\newcommand{\@todonotes@distanceNotesPageBorder}{0.5cm}
+\newcommand{\@todonotes@distanceNotesText}{0.2cm}
+\newcommand{\@todonotes@rasterHeight}{1cm}
+\newcommand{\@todonotes@additionalMargin}{2cm}
+% \end{macrocode}
+% \begin{macrocode}
+\AtBeginDocument{
+\ifx\undefined\phantomsection
+\newcommand{\phantomsection}{}
+\fi
+}
+% \end{macrocode}
+%
+% \subsection{Declaration of options for the package}
+% In this part the various options for
+% the package are defined.
+%
+% Define the default text strings and set localization options for
+% the danish and german languages.
+% \begin{macrocode}
+\newcommand{\@todonotes@todolistname}{Todo list}
+\newcommand{\@todonotes@MissingFigureText}{Figure}
+\newcommand{\@todonotes@MissingFigureUp}{Missing}
+\newcommand{\@todonotes@MissingFigureDown}{figure}
+\newcommand{\@todonotes@SetTodoListName}[1]
+ {\renewcommand{\@todonotes@todolistname}{#1}}
+\newcommand{\@todonotes@SetMissingFigureText}[1]
+ {\renewcommand{\@todonotes@MissingFigureText}{#1}}
+\newcommand{\@todonotes@SetMissingFigureUp}[1]
+ {\renewcommand{\@todonotes@MissingFigureUp}{#1}}
+\newcommand{\@todonotes@SetMissingFigureDown}[1]
+ {\renewcommand{\@todonotes@MissingFigureDown}{#1}}
+\newif{\if@todonotes@reverseMissingFigureTriangle}
+\DeclareOptionX{catalan}{
+ \@todonotes@SetTodoListName{Llista de feines pendents}%
+ \@todonotes@SetMissingFigureText{Figura}%
+ \@todonotes@SetMissingFigureUp{Figura}%
+ \@todonotes@SetMissingFigureDown{pendent}%
+}
+\DeclareOptionX{croatian}{%
+ \@todonotes@SetTodoListName{Popis obveza}%
+ \@todonotes@SetMissingFigureText{Slika}%
+ \@todonotes@SetMissingFigureUp{Nedostaje}%
+ \@todonotes@SetMissingFigureDown{slika}%
+}
+\DeclareOptionX{danish}{%
+ \@todonotes@SetTodoListName{G\o{}rem\aa{}lsliste}%
+ \@todonotes@SetMissingFigureText{Figur}%
+ \@todonotes@SetMissingFigureUp{Manglende}%
+ \@todonotes@SetMissingFigureDown{figur}%
+}
+\DeclareOptionX{dutch}{%
+ \@todonotes@SetTodoListName{Lijst van onafgewerkte taken}%
+ \@todonotes@SetMissingFigureText{Figuur}%
+ \@todonotes@SetMissingFigureUp{Ontbrekende}%
+ \@todonotes@SetMissingFigureDown{figuur}%
+}
+\DeclareOptionX{english}{%
+ \@todonotes@SetTodoListName{Todo list}%
+ \@todonotes@SetMissingFigureText{Figure}%
+ \@todonotes@SetMissingFigureUp{Missing}%
+ \@todonotes@SetMissingFigureDown{figure}%
+}
+\DeclareOptionX{french}{%
+ \@todonotes@SetTodoListName{Liste des points \`a traiter}%
+ \@todonotes@SetMissingFigureText{Figure}%
+ \@todonotes@SetMissingFigureUp{Figure}%
+ \@todonotes@SetMissingFigureDown{manquante}%
+ \@todonotes@reverseMissingFigureTrianglefalse
+}
+\DeclareOptionX{german}{%
+ \@todonotes@SetTodoListName{Liste der noch zu erledigenden Punkte}%
+ \@todonotes@SetMissingFigureText{Abbildung}%
+ \@todonotes@SetMissingFigureUp{Fehlende}%
+ \@todonotes@SetMissingFigureDown{Abbildung}%
+}
+\DeclareOptionX{italian}{
+ \@todonotes@SetTodoListName{Elenco delle cose da fare}%
+ \@todonotes@SetMissingFigureText{Figura}%
+ \@todonotes@SetMissingFigureUp{Figura}%
+ \@todonotes@SetMissingFigureDown{mancante}%
+}
+\DeclareOptionX{ngerman}{%
+ \@todonotes@SetTodoListName{Liste der noch zu erledigenden Punkte}%
+ \@todonotes@SetMissingFigureText{Abbildung}%
+ \@todonotes@SetMissingFigureUp{Fehlende}%
+ \@todonotes@SetMissingFigureDown{Abbildung}%
+}
+\DeclareOptionX{portuguese}{
+ \@todonotes@SetTodoListName{Lista de tarefas pendentes}%
+ \@todonotes@SetMissingFigureText{Figura}%
+ \@todonotes@SetMissingFigureUp{Figura}%
+ \@todonotes@SetMissingFigureDown{pendente}%
+}
+\DeclareOptionX{spanish}{
+ \@todonotes@SetTodoListName{Lista de tareas pendientes}%
+ \@todonotes@SetMissingFigureText{Figura}%
+ \@todonotes@SetMissingFigureUp{Figura}%
+ \@todonotes@SetMissingFigureDown{pendiente}%
+}
+\DeclareOptionX{swedish}{%
+ \@todonotes@SetTodoListName{Att g\"{o}ra-lista}%
+ \@todonotes@SetMissingFigureText{Figur}%
+ \@todonotes@SetMissingFigureUp{Figur}%
+ \@todonotes@SetMissingFigureDown{saknas}%
+}
+% \end{macrocode}
+% Create a counter, for storing the number of inserted todos.
+% \begin{macrocode}
+\newcounter{@todonotes@numberoftodonotes}
+% \end{macrocode}
+% Create a counter, for storing the number of lines in the current todoarea.
+% \begin{macrocode}
+\newcounter{@todonotes@numberofLinesInArea}
+% \end{macrocode}
+% Toggle whether the package should obey the global draft option.
+% \begin{macrocode}
+\newif{\if@todonotes@obeyDraft}
+\DeclareOptionX{obeyDraft}{\@todonotes@obeyDrafttrue}
+\newif{\if@todonotes@isDraft}
+\DeclareOptionX{draft}{\@todonotes@isDrafttrue}
+\DeclareOptionX{draftcls}{\@todonotes@isDrafttrue}
+\DeclareOptionX{draftclsnofoot}{\@todonotes@isDrafttrue}
+\newif{\if@todonotes@obeyFinal}
+\DeclareOptionX{obeyFinal}{\@todonotes@obeyFinaltrue}
+\newif{\if@todonotes@isFinal}
+\DeclareOptionX{final}{\@todonotes@isFinaltrue}
+% \end{macrocode}
+% Make it possible to disable the functionality
+% of the package. If this option is given, the
+% commands |\todo{}| and |\listoftodos| are defined
+% as commands with no effect. (But you can still
+% compile you document with these commands).
+% \begin{macrocode}
+\newif{\if@todonotes@disabled}
+\DeclareOptionX{disable}{\@todonotes@disabledtrue}
+% \end{macrocode}
+% Show small boxes in the list of todos with the color of the
+% inserted todonotes.
+% \begin{macrocode}
+\newif{\if@todonotes@colorinlistoftodos}
+\DeclareOptionX{colorinlistoftodos}{\@todonotes@colorinlistoftodostrue}
+% \end{macrocode}
+% We only define dvistyle for compatibility with todonotes.
+% The option was intented for use with \texttt{tex}, there should be no problems
+% using \texttt{luatex}.
+% So we ignore this option and issue a warning.
+% \begin{macrocode}
+\DeclareOptionX{dvistyle}{\PackageWarningNoLine{luatodonotes}
+ {Parameter dvistyle is not supported by luatodonotes.
+ Ignoring this option}}
+% \end{macrocode}
+% Create a color option.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {color}{
+ \renewcommand{\@todonotes@backgroundcolor}{#1}
+ \renewcommand{\@todonotes@linecolor}{#1}}
+% \end{macrocode}
+% Make the background color of the notes as
+% an option.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {backgroundcolor}{\renewcommand{\@todonotes@backgroundcolor}{#1}}
+% \end{macrocode}
+% Make the line color of the notes as
+% an option.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {linecolor}{\renewcommand{\@todonotes@linecolor}{#1}}
+% \end{macrocode}
+% Make the color of the notes box color as
+% an option.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {bordercolor}{\renewcommand{\@todonotes@bordercolor}{#1}}
+% \end{macrocode}
+% Make the width of the leader line as
+% an option.
+% It is later set as \texttt{line width} in TikZ.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {leaderwidth}{\renewcommand{\@todonotes@leaderwidth}{#1}}
+% \end{macrocode}
+% Set whether short captions given as arguments to the todo command
+% should be included in the inserted todonote.
+% \begin{macrocode}
+\newif{\if@todonotes@prependcaptionglobal}
+\@todonotes@prependcaptionglobalfalse
+\DeclareOptionX{prependcaption}{\@todonotes@prependcaptionglobaltrue}
+% \end{macrocode}
+% This option is only there for compatibility with todonotes.
+% We ignore it and issue a warning because the width of our labels is
+% determined dynamically based on the page layout.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {textwidth}{\PackageWarningNoLine{luatodonotes}
+ {Parameter textwidth is not supported by luatodonotes}}
+% \end{macrocode}
+% Make the text size as an option. It requires some magic with the
+% |\csname| and |\endcsname| macros, as commands cannot be taken as
+% options for a package.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {textsize}{\renewcommand{\@todonotes@textsize}{\csname #1\endcsname}}
+% \end{macrocode}
+% Add option for shadows behind the inserted notes
+% \begin{macrocode}
+\newif{\if@todonotes@shadowenabled}
+\@todonotes@shadowenabledfalse
+\DeclareOptionX{shadow}{\@todonotes@shadowenabledtrue
+\usetikzlibrary{shadows}}
+% \end{macrocode}
+% Add option for the default width of the figure inserted with
+% |\missingfigure|.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {figwidth}{\renewcommand{\@todonotes@figwidth}{#1}}
+\define@key{luatodonotes.sty}%
+ {figheight}{\renewcommand{\@todonotes@figheight}{#1}}
+\define@key{luatodonotes.sty}%
+ {figcolor}{\renewcommand{\@todonotes@figcolor}{#1}}
+% \end{macrocode}
+% \begin{macro}{s,bezier,opo,po}
+% Provide shorthand options for the most common leader styles.
+% \changes{0.3}{2015/12/03}{Provide shorthand commands for most common leader
+% styles}
+% \begin{macrocode}
+\DeclareOptionX{po}%
+ {\setkeys{luatodonotes.sty}{leadertype=po,positioning=poLeadersAvoidLines}}
+\DeclareOptionX{s}%
+ {\setkeys{luatodonotes.sty}{leadertype=s,positioning=sLeaderNorthEastBelowStacks}}
+\DeclareOptionX{bezier}%
+ {\setkeys{luatodonotes.sty}{leadertype=sBezier,positioning=sLeaderNorthEastBelowStacks}}
+\DeclareOptionX{opo}%
+ {\setkeys{luatodonotes.sty}{leadertype=opo,positioning=inputOrderStacks}}
+% \end{macrocode}
+% \end{macro}
+% Specify the name of the algorithm used to specify the position of the labels.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {positioning}{\renewcommand{\@todonotes@positioning}{#1}}
+% \end{macrocode}
+% Specify the name of the algorithm used to split the notes for left and right side.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {splitting}{\renewcommand{\@todonotes@splitting}{#1}}
+% \end{macrocode}
+% Specify the type of leaders that are drawn.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {leadertype}{\renewcommand{\@todonotes@leadertype}{#1}}
+% \end{macrocode}
+% Specify the vertical distance between the notes.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {interNoteSpace}{\renewcommand{\@todonotes@interNoteSpace}{#1}}
+% \end{macrocode}
+% Specify the distance from the text inside the notes to the border.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {noteInnerSep}{\renewcommand{\@todonotes@noteInnerSep}{#1}}
+% \end{macrocode}
+% Specify the width of the routing area used for $opo$- and $os$-leaders.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {routingAreaWidth}{\renewcommand{\@todonotes@routingAreaWidth}{#1}}
+% \end{macrocode}
+% Minimum width of notes in one margin beside the text to be considered for
+% label placement.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {minNoteWidth}{\renewcommand{\@todonotes@minNoteWidth}{#1}}
+% \end{macrocode}
+% Specify horizontal distance from the notes to the borders of the page.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {distanceNotesPageBorder}%
+ {\renewcommand{\@todonotes@distanceNotesPageBorder}{#1}}
+% \end{macrocode}
+% Specify the horizontal distance between the notes and the text area.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {distanceNotesText}{\renewcommand{\@todonotes@distanceNotesText}{#1}}
+% \end{macrocode}
+% Specify the height of the raster used for the $po$-leader algorithm.
+% \begin{macrocode}
+\define@key{luatodonotes.sty}%
+ {rasterHeight}{\renewcommand{\@todonotes@rasterHeight}{#1}}
+% \end{macrocode}
+% \begin{macro}{additionalMargin}
+% Control whether the margin should be enlarged for the notes and its width.
+% \changes{0.3}{2015/12/01}{Introduce package option \texttt{additionalMargin}}
+% \changes{0.4}{2016/04/01}{Fixed problems of the \texttt{additionalMargin}
+% option with certain documentclasses}
+% \begin{macrocode}
+\newif{\if@todonotes@additionalMarginEnabled}
+\@todonotes@additionalMarginEnabledfalse
+\define@key{luatodonotes.sty}%
+ {additionalMargin}[\@todonotes@additionalMargin]{%
+ \@todonotes@additionalMarginEnabledtrue
+ \renewcommand{\@todonotes@additionalMargin}{#1}}
+% \end{macrocode}
+% \end{macro}
+% This option is used to activate debug mode.
+% Luatex prints more verbose output to the commandline in this mode.
+% Furthermore, some of the algorithms also print debugging hints onto the
+% output page.
+% \begin{macrocode}
+\newif{\if@todonotes@debugenabled}
+\@todonotes@debugenabledfalse
+\DeclareOptionX{debug}{\@todonotes@debugenabledtrue}
+% \end{macrocode}
+% Finally process the given options.
+% \begin{macrocode}
+\ProcessOptionsX*
+% \end{macrocode}
+% If the |obeyDraft| is given, check whether one of the |draft|,
+% |draftcls| or |draftclsnofoot|
+% options are given and enable or disable the functionality of this
+% package.
+% If the |obeyFinal| option is given together with the |final| option
+% the todonotes are disabled.
+% The |disable| option will overrule the effect of |obeyDraft|.
+% \begin{macrocode}
+\if@todonotes@disabled
+\else
+ \if@todonotes@obeyDraft
+ \@todonotes@disabledtrue
+ \if@todonotes@isDraft
+ \@todonotes@disabledfalse
+ \fi
+ \fi
+ \if@todonotes@obeyFinal
+ \@todonotes@disabledfalse
+ \if@todonotes@isFinal
+ \@todonotes@disabledtrue
+ \fi
+ \fi
+\fi
+% \end{macrocode}
+% If the option |additionalMargin| is given, we enlarge the margins for the notes.
+% We simply increase the page size by the doubled value of |additionalMargin|
+% and move the contents to the right using |\hoffset|.
+% \begin{macrocode}
+\if@todonotes@additionalMarginEnabled
+ \newlength{\@todonotes@modpaperwidth}
+ \AfterEndPreamble{%
+ \setlength{\@todonotes@modpaperwidth}{\paperwidth}%
+ \addtolength{\@todonotes@modpaperwidth}{\@todonotes@additionalMargin}%
+ \addtolength{\@todonotes@modpaperwidth}{\@todonotes@additionalMargin}%
+ \pdfpagewidth=\@todonotes@modpaperwidth%
+ \addtolength{\hoffset}{\@todonotes@additionalMargin}%
+ }%
+\fi%
+% \end{macrocode}
+% \subsection{Initialisation of our Lua code}
+% In this part we define some of the variables used by Lua depending on the
+% package options and do some other initialisation tasks.
+%
+% We first need some temporary dimensions, which are written by \TeX\ and read
+% from Lua.
+% We use dimensions here because it is easier to access \TeX\ dimensions from
+% Lua than \LaTeX\ lengths.
+% We use |tex.dimen| in Lua to access dimensions.
+% The first dimensions are used when extracting the absolute coordinates of a
+% position on the page.
+% \begin{macrocode}
+\newdimen\@todonotes@extractx
+\newdimen\@todonotes@extracty
+% \end{macrocode}
+% The following savebox and dimensions are used to calculate the height of a
+% certain label.
+% The box and dimensions are filled by \TeX\ and then read from Lua.
+% \begin{macrocode}
+\newsavebox\@todonotes@heightcalcbox
+\newdimen\@todonotes@heightcalcboxdepth
+\newdimen\@todonotes@heightcalcboxheight
+% \end{macrocode}
+% The following savebox is used to store the contents of a note and is then
+% read from Lua.
+% \begin{macrocode}
+\newsavebox\@todonotes@notetextbox
+% \end{macrocode}
+% The following dimensions are used to read |\baselineskip|,
+% |\normalbaselineskip| and |\f@size| from Lua.
+% We need |\normalbaselineskip| as |\baselineskip| is set to 0 inside
+% tabular cells.
+% Dimension |\@todonotes@currentsidemargin| is set to the left margin,
+% i.\,e., to the value of length |\oddsidemargin| or
+% |\evensidemargin| depending on the type page.
+% \changes{0.3}{2015/10/30}{Fix position of marker in table cells
+% (\texttt{\textbackslash baselineskip} is empty inside tables)}
+% \begin{macrocode}
+\newdimen\@todonotes@baselineskip
+\newdimen\@todonotes@normalbaselineskip
+\newdimen\@todonotes@fontsize
+\newdimen\@todonotes@currentsidemargin
+% \end{macrocode}
+% Loading our main Lua file.
+% \begin{macrocode}
+\directlua{require("luatodonotes")}
+% \end{macrocode}
+% Setting variables to values given by package options.
+% \begin{macrocode}
+\directlua{luatodonotes.noteInnerSep =
+ string.todimen("\luatexluaescapestring{\@todonotes@noteInnerSep}")}
+\directlua{luatodonotes.noteInterSpace =
+ string.todimen("\luatexluaescapestring{\@todonotes@interNoteSpace}")}
+\directlua{luatodonotes.routingAreaWidth =
+ string.todimen("\luatexluaescapestring{\@todonotes@routingAreaWidth}")}
+\directlua{luatodonotes.minNoteWidth =
+ string.todimen("\luatexluaescapestring{\@todonotes@minNoteWidth}")}
+\directlua{luatodonotes.distanceNotesPageBorder =
+ string.todimen("\luatexluaescapestring{\@todonotes@distanceNotesPageBorder}")}
+\directlua{luatodonotes.distanceNotesText =
+ string.todimen("\luatexluaescapestring{\@todonotes@distanceNotesText}")}
+\directlua{luatodonotes.rasterHeight =
+ string.todimen("\luatexluaescapestring{\@todonotes@rasterHeight}")}
+% \end{macrocode}
+% Set the variables for the used algorithms and leader types depending on the
+% corresponding package options.
+% \begin{macrocode}
+\directlua{luatodonotes.setPositioningAlgo("\luatexluaescapestring{\@todonotes@positioning}")}
+\directlua{luatodonotes.setSplittingAlgo("\luatexluaescapestring{\@todonotes@splitting}")}
+\directlua{luatodonotes.setLeaderType("\luatexluaescapestring{\@todonotes@leadertype}")}
+% \end{macrocode}
+% The following commands are used to detect the absolute positions of lines on
+% the page.
+%
+% We first need to define a command to be able to insert the position from
+% |\pdflastypos| into a write-whatsit in Lua.
+% We need this workaround because we cannot insert |\pdflastypos| directly into
+% the tokenlist in the Lua callback \texttt{callbackOutputLinePositions()}.
+% \begin{macrocode}
+\def\@todonotes@pdflastypos{\the\pdflastypos}
+% \end{macrocode}
+% The following commands are written to the temporary \texttt{lpo}-file.
+% When reading this file we call a Lua function for each line in the file and
+% thus can collect the line positions in a Lua table.
+% \begin{macrocode}
+\newcommand{\@todonotes@lineposition}[3]{%
+ \directlua{luatodonotes.linePositionsAddLine(#1,#2,#3)}%
+}
+\newcommand{\@todonotes@nextpage}{%
+ \directlua{luatodonotes.linePositionsNextPage()}%
+}%
+% \end{macrocode}
+% The following macro is used in \texttt{AtBeginShipout} to signal in the
+% \texttt{lpo}-file that a new page is started.
+% \begin{macrocode}
+\newcommand{\@todonotes@writeNextpageToLpo}{%
+ \ifdefined\tf@lpo%
+ \immediate\write\tf@lpo{\@backslashchar @todonotes@nextpage}%
+ \fi
+}
+% \end{macrocode}
+% Depending on the debug-option of the package we set the corresponding Lua
+% variable here.
+% Additionally, we prepare to print our notes and leaders in foreground when in
+% debug mode.
+% \begin{macrocode}
+\if@todonotes@debugenabled
+ \directlua{luatodonotes.todonotesDebug = true}
+ \newcommand{\@todonotes@AtBeginShipoutUpperLeft}
+ {\AtBeginShipoutUpperLeftForeground}
+\else
+ \directlua{luatodonotes.todonotesDebug = false}
+ \newcommand{\@todonotes@AtBeginShipoutUpperLeft}
+ {\AtBeginShipoutUpperLeft}
+\fi
+% \end{macrocode}
+% Initialise the script when all Lua variables are set according to the package
+% options.
+% \begin{macrocode}
+\directlua{luatodonotes.initTodonotes()}
+% \end{macrocode}
+% Some definitions to highlight areas in text.
+% The first command is needed to accept control spaces (|\ |) in arguments for
+% soul commands.
+% After that we define the highlighting command used for todoareas.
+% \begin{macrocode}
+\soulregister{\ }{0}
+\newlength{\todonotes@textmark@width}
+\newlength{\todonotes@textmark@fontsize}
+\newlength{\todonotes@textmark@linebelow}
+\newlength{\todonotes@textmark@lineabove}
+\ulposdef{\todonotes@textmark@highlight}{%
+ \setlength\todonotes@textmark@width\ulwidth%
+ \setlength\todonotes@textmark@fontsize{\f@size pt}%
+ \stepcounter{@todonotes@numberofLinesInArea}%
+ \ifulstarttype{0}%
+ {% begin of area
+ \def\todonotes@textmark@decoLeft{}%
+ \def\todonotes@textmark@shift{-2pt}%
+ \addtolength\todonotes@textmark@width{2pt}%
+ \setcounter{@todonotes@numberofLinesInArea}{1}}%
+ {\def\todonotes@textmark@decoLeft{@todonotes@todoarea}%
+ \def\todonotes@textmark@shift{-4pt}%
+ \addtolength\todonotes@textmark@width{4pt}}%
+ \ifulendtype{0}%
+ {% last line of area
+ \def\todonotes@textmark@decoRight{}%
+ \addtolength\todonotes@textmark@width{2pt}%
+ \directlua{luatodonotes.processLastLineInTodoArea()}}%
+ {\def\todonotes@textmark@decoRight{@todonotes@todoarea}%
+ \addtolength\todonotes@textmark@width{4pt}}%
+ \newcommand{\@todonotes@nodeNamePrefix}%
+ {@todonotes@\arabic{@todonotes@numberoftodonotes}%
+ @\arabic{@todonotes@numberofLinesInArea} }%
+ \hspace*{\todonotes@textmark@shift}{\smash{%
+ \begin{tikzpicture}[overlay,remember picture,
+ deco/.style={}]%
+ \setlength\todonotes@textmark@linebelow%
+ {-0.95\dimexpr\baselineskip-\f@size pt\relax}%
+ \setlength\todonotes@textmark@lineabove%
+ {\dimexpr\f@size pt+\todonotes@textmark@linebelow\relax}%
+ \coordinate
+ (\@todonotes@nodeNamePrefix areaSW)
+ at (0,\todonotes@textmark@linebelow);
+ \coordinate
+ (\@todonotes@nodeNamePrefix areaSE)
+ at (\todonotes@textmark@width, \todonotes@textmark@linebelow);
+ \coordinate
+ (\@todonotes@nodeNamePrefix areaNE)
+ at (\todonotes@textmark@width,\todonotes@textmark@lineabove);
+ \coordinate
+ (\@todonotes@nodeNamePrefix areaNW)
+ at (0,\todonotes@textmark@lineabove);
+ \draw[draw=green!70,fill=green,fill opacity=.2]
+ (\@todonotes@nodeNamePrefix areaSW)
+ decorate[\todonotes@textmark@decoLeft] {
+ -- (\@todonotes@nodeNamePrefix areaNW)
+ }
+ -- (\@todonotes@nodeNamePrefix areaNE)
+ decorate[\todonotes@textmark@decoRight] {
+ -- (\@todonotes@nodeNamePrefix areaSE)
+ }
+ -- cycle;
+ \end{tikzpicture}%
+ }}%
+}%
+% \end{macrocode}
+% \subsection{Options for the todo command}
+%
+% In this part the various options for
+% commands in the package are defined.
+% Set an arbitrarily fill color
+% \begin{macrocode}
+\newcommand{\@todonotes@currentlinecolor}{}%
+\newcommand{\@todonotes@currentbackgroundcolor}{}%
+\newcommand{\@todonotes@currentbordercolor}{}%
+\define@key{todonotes}{color}{%
+ \renewcommand{\@todonotes@currentlinecolor}{#1}%
+ \renewcommand{\@todonotes@currentbackgroundcolor}{#1}}%
+\define@key{todonotes}{linecolor}{%
+ \renewcommand{\@todonotes@currentlinecolor}{#1}}%
+\define@key{todonotes}{backgroundcolor}{%
+ \renewcommand{\@todonotes@currentbackgroundcolor}{#1}}%
+\define@key{todonotes}{bordercolor}{%
+ \renewcommand{\@todonotes@currentbordercolor}{#1}}%
+\newcommand{\@todonotes@currentleaderwidth}{}%
+\define@key{todonotes}{leaderwidth}{%
+ \renewcommand{\@todonotes@currentleaderwidth}{#1}}%
+% \end{macrocode}
+% Set a relative font size
+% \begin{macrocode}
+\newcommand{\@todonotes@sizecommand}{}%
+\define@key{todonotes}{size}{\renewcommand{\@todonotes@sizecommand}{#1}}%
+% \end{macrocode}
+% Should the todo item be disabled?
+% \begin{macrocode}
+\newif\if@todonotes@localdisable%
+\define@key{todonotes}{disable}[]{\@todonotes@localdisabletrue}%
+\define@key{todonotes}{nodisable}[]{\@todonotes@localdisablefalse}%
+% \end{macrocode}
+% Should the todo item be included in the list of todos?
+% \begin{macrocode}
+\newif\if@todonotes@appendtolistoftodos%
+\define@key{todonotes}{list}[]{\@todonotes@appendtolistoftodostrue}%
+\define@key{todonotes}{nolist}[]{\@todonotes@appendtolistoftodosfalse}%
+% \end{macrocode}
+% Should the todo item be displayed inline?
+% \begin{macrocode}
+\newif\if@todonotes@inlinenote%
+\define@key{todonotes}{inline}[]{\@todonotes@inlinenotetrue}%
+\define@key{todonotes}{noinline}[]{\@todonotes@inlinenotefalse}%
+% \end{macrocode}
+% \begin{macrocode}
+\newif\if@todonotes@prependcaption%
+\define@key{todonotes}{prepend}[]{\@todonotes@prependcaptiontrue}%
+\define@key{todonotes}{noprepend}[]{\@todonotes@prependcaptionfalse}%
+% \end{macrocode}
+% Should the note in the margin be connected to the insertion point
+% in the text?
+% \begin{macrocode}
+\newif\if@todonotes@line%
+\define@key{todonotes}{line}[]{\@todonotes@linetrue}%
+\define@key{todonotes}{noline}[]{\@todonotes@linefalse}%
+% \end{macrocode}
+% Only here for compatibility with todonotes.
+% We don't need the fancy lines because we have more advanced drawing styles.
+% So we ignore this option and issue a warning.
+% \begin{macrocode}
+\define@key{todonotes}{fancyline}[]{\PackageWarningNoLine{luatodonotes}
+ {Parameter fancyline is not supported by luatodonotes}}%
+\define@key{todonotes}{nofancyline}[]{}%
+% \end{macrocode}
+% Author option.
+% \begin{macrocode}
+\newcommand{\@todonotes@author}{}%
+\newif\if@todonotes@authorgiven%
+\define@key{todonotes}{author}{%
+ \renewcommand{\@todonotes@author}{#1}%
+ \@todonotes@authorgiventrue}%
+\define@key{todonotes}{noauthor}[]{\@todonotes@authorgivenfalse}%
+% \end{macrocode}
+% Should the text in the list of todos be different from the text
+% in the todonote?
+% \begin{macrocode}
+\newcommand{\@todonotes@caption}{}%
+\newif\if@todonotes@captiongiven%
+\define@key{todonotes}{caption}%
+ {\renewcommand{\@todonotes@caption}{#1}%
+ \@todonotes@captiongiventrue}%
+\define@key{todonotes}{nocaption}[]{\@todonotes@captiongivenfalse}%
+% \end{macrocode}
+% Change the current figure width and height.
+% \begin{macrocode}
+\newcommand{\@todonotes@currentfigwidth}{\@todonotes@figwidth}
+\define@key{todonotes}%
+ {figwidth}{\renewcommand{\@todonotes@currentfigwidth}{#1-2pt}}
+\newcommand{\@todonotes@currentfigheight}{\@todonotes@figheight}
+\define@key{todonotes}%
+ {figheight}{\renewcommand{\@todonotes@currentfigheight}{#1-2pt}}
+\newcommand{\@todonotes@currentfigcolor}{\@todonotes@figcolor}
+\define@key{todonotes}%
+ {figcolor}{\renewcommand{\@todonotes@currentfigcolor}{#1}}
+% \end{macrocode}
+% Preset values of the options
+% \begin{macrocode}
+\presetkeys%
+ {todonotes}%
+ {linecolor=\@todonotes@linecolor,%
+ backgroundcolor=\@todonotes@backgroundcolor,%
+ bordercolor=\@todonotes@bordercolor,%
+ leaderwidth=\@todonotes@leaderwidth,%
+ nodisable,%
+ noinline,%
+ nocaption,%
+ noauthor,%
+ figwidth=\@todonotes@figwidth,%
+ figheight=\@todonotes@figheight,%
+ figcolor=\@todonotes@figcolor,%
+ line, list, size=\@todonotes@textsize}{}%
+% \end{macrocode}
+% \subsection{The main code part}
+% Here are the actual macros defined.
+% The following boolean is used to remember if |\todo| or |\todoarea|
+% was called.
+% \begin{macrocode}
+\newif\if@todonotes@areaselected%
+% \end{macrocode}
+% The following token registers are used to access the data for a note (which
+% is stored in macros) from Lua.
+% \begin{macrocode}
+\newtoks\@todonotes@toks@currentlinecolor%
+\newtoks\@todonotes@toks@currentbackgroundcolor%
+\newtoks\@todonotes@toks@currentbordercolor%
+\newtoks\@todonotes@toks@currentleaderwidth%
+\newtoks\@todonotes@toks@sizecommand%
+% \end{macrocode}
+% If the option "disable" was passed to the package
+% define empty commands.
+% \begin{macrocode}
+\if@todonotes@disabled%
+ \newcommand{\listoftodos}[1][]{}
+ \newcommand{\@todo}[2][]{}
+ \newcommand{\@todoarea}[3][]{}
+ \newcommand{\missingfigure}[2][]{}
+\else % \if@todonotes@disabled
+% \end{macrocode}
+% \begin{macro}{\listoftodos}
+% Define the |\listoftodos| command and define the
+% appearance of the list of todos.
+% \changes{0.3}{2015/11/16}{\texttt{\textbackslash listoftodos} didn't work
+% with documentclass \texttt{llncs}}
+% \changes{0.3}{2015/12/03}{Fix for \texttt{\textbackslash listoftodos} causing problems with
+% \texttt{hyperref}}
+% \begin{macrocode}
+\newcounter{todonotes@oldtocdepth}
+\newcommand{\listoftodos}[1][\@todonotes@todolistname]{%
+ \setcounter{todonotes@oldtocdepth}{\value{tocdepth}}%
+ \setcounter{tocdepth}{1}%
+ \@ifundefined{chapter}{\section*{#1}}{\chapter*{#1}} \@starttoc{tdo}%
+ \setcounter{tocdepth}{\value{todonotes@oldtocdepth}}%
+}
+\newcommand{\l@todo}
+ {\@dottedtocline{1}{0em}{2.3em}}
+% \end{macrocode}
+% \end{macro}
+% Define styles used by the todo command.
+% Colors are set directly when placing the notes.
+% \begin{macrocode}
+\tikzset{@todonotes@todoarea/.style={
+ decoration={snake,amplitude=3.5pt,segment length=5pt}}}
+\tikzset{@todonotes@notestyleraw/.style={
+ line width=0.5pt,
+ inner sep = \@todonotes@noteInnerSep,
+ rounded corners=4pt}}
+% \end{macrocode}
+% Add shadows and rounded corners to the inserted todonotes.
+% \begin{macrocode}
+\if@todonotes@shadowenabled
+ \tikzset{@todonotes@notestyle/.style={@todonotes@notestyleraw,
+ general shadow={shadow xshift=.5ex, shadow yshift=-.5ex,
+ opacity=1,fill=black!50}}}
+\else
+ \tikzset{@todonotes@notestyle/.style={@todonotes@notestyleraw}}
+\fi
+\tikzset{@todonotes@leader/.style={}}
+\tikzset{@todonotes@textmark/.style={rounded corners}}
+\tikzset{@todonotes@inlinenote/.style={
+ @todonotes@notestyle,
+ draw=\@todonotes@currentbordercolor,
+ fill=\@todonotes@currentbackgroundcolor,
+ text width=\linewidth - 1.6 ex - 1 pt}}
+% \end{macrocode}
+% \begin{macro}{\@todocommon}
+% Common macro used from |\@todo| and |\@todoarea|.
+% Used to actually draw/save the note.
+% \begin{macrocode}
+\newcommand{\@todocommon}[2]{%
+% \end{macrocode}
+% Use the global value for determining the default prepend behavior.
+% \begin{macrocode}
+\if@todonotes@prependcaptionglobal%
+\@todonotes@prependcaptiontrue%
+\else%
+\@todonotes@prependcaptionfalse%
+\fi%
+% \end{macrocode}
+% Store the original text for later usage and parse the given options.
+% \begin{macrocode}
+\renewcommand{\@todonotes@text}{#2}%
+\renewcommand{\@todonotes@caption}{#2}%
+\setkeys{todonotes}{#1}%
+% \end{macrocode}
+% If the option |disable| is given to the command, no output is generated.
+% \begin{macrocode}
+\if@todonotes@localdisable%
+\else%
+% \end{macrocode}
+% Add the item to the list of todos. When the option
+% |colorinlistoftodos| is given to the package a small colored
+% square is added in front of the text.
+% \begin{macrocode}
+\addtocounter{@todonotes@numberoftodonotes}{1}%
+\if@todonotes@appendtolistoftodos%
+ \phantomsection%
+ \if@todonotes@captiongiven%
+ \else%
+ \renewcommand{\@todonotes@caption}{#2}%
+ \fi%
+ \@todonotes@addElementToListOfTodos%
+\fi%
+% \end{macrocode}
+% Prepend the short caption given if it is requested
+% \begin{macrocode}
+\if@todonotes@captiongiven%
+ \if@todonotes@prependcaption%
+ \renewcommand{\@todonotes@text}{\@todonotes@caption: #2}%
+ \fi%
+\fi%
+% \end{macrocode}
+% Place the todonote as indicated by the options (inline or in a
+% marginpar), below is the code for the inline placement.
+% \begin{macrocode}
+\if@todonotes@inlinenote%
+ \@todonotes@drawInlineNote%
+\else%
+ \@todonotes@drawMarginNoteWithLine%
+\fi%\if@todonotes@inlinenote
+\fi%\if@todonotes@localdisable
+}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@todo}
+% Command that draws normal notes.
+% \begin{macrocode}
+\newcommand{\@todo}[2][]{%
+ \@todonotes@areaselectedfalse%
+ \@todocommon{#1}{#2}%
+}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@todoarea}
+% Command that draws notes that highlight a certain area in text.
+% \begin{macrocode}
+\newcommand{\@todoarea}[3][]{%
+ \@todonotes@areaselectedtrue%
+ \@todocommon{#1}{#2}%
+ \todonotes@textmark@highlight{#3}%
+% \end{macrocode}
+% Mark the end of the highlighted area with a Tikz coordinate.
+% The begin is marked by |\@todocommon|.
+% \begin{macrocode}
+ \begin{tikzpicture}[remember picture, overlay]%
+ \node [coordinate] (@todonotes@\arabic{@todonotes@numberoftodonotes} %
+ inTextEnd) {};%
+ \end{tikzpicture}%
+ \zref@label{@todonotes@\arabic{@todonotes@numberoftodonotes}@end}%
+}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{drawMarginNoteWithLine}
+% Define helper function |drawMarginNoteWithLine|.
+% \begin{macrocode}
+\newcommand{\@todonotes@drawMarginNoteWithLine}{%
+% \end{macrocode}
+% When the todonote should be placed inside a marginpar, the code
+% below is applied.
+% First is the current location in the document stored, this enables
+% us later to connect this point with the inserted todonote.
+% \begin{macrocode}
+ \begin{tikzpicture}[remember picture, overlay]%
+ \node [coordinate] (@todonotes@\arabic{@todonotes@numberoftodonotes} %
+ inText) {};%
+ \end{tikzpicture}%
+% \end{macrocode}
+% Update the dimensions to be accessed by Lua.
+% \begin{macrocode}
+ \@todonotes@baselineskip=\baselineskip%
+ \@todonotes@normalbaselineskip=\normalbaselineskip%
+ \@todonotes@fontsize=\f@size pt%
+% \end{macrocode}
+% Place a label at the site.
+% We use this to query the page number, on which the note was placed.
+% \begin{macrocode}
+ \zref@label{@todonotes@\arabic{@todonotes@numberoftodonotes}}%
+% \end{macrocode}
+% Append author before the note text if one is given.
+% \begin{macrocode}
+ \if@todonotes@authorgiven%
+ \let\@todonotes@text@old=\@todonotes@text
+ \renewcommand{\@todonotes@text}{\@todonotes@author: \@todonotes@text@old}%
+ \fi%
+% \end{macrocode}
+% We use edef here to get these macros fully expanded.
+% After that we write them to a toks register and read them from Lua.
+% \begin{macrocode}
+ \edef\@todonotes@tmp{\@todonotes@currentlinecolor}%
+ \@todonotes@toks@currentlinecolor=\expandafter{\@todonotes@tmp}%
+ \edef\@todonotes@tmp{\@todonotes@currentbackgroundcolor}%
+ \@todonotes@toks@currentbackgroundcolor=\expandafter{\@todonotes@tmp}%
+ \edef\@todonotes@tmp{\@todonotes@currentbordercolor}%
+ \@todonotes@toks@currentbordercolor=\expandafter{\@todonotes@tmp}%
+ \edef\@todonotes@tmp{\@todonotes@currentleaderwidth}%
+ \@todonotes@toks@currentleaderwidth=\expandafter{\@todonotes@tmp}%
+% \end{macrocode}
+% We cannot fully expand the size command (using |\edef| causes errors when
+% compiling).
+% \begin{macrocode}
+ \@todonotes@toks@sizecommand=\expandafter{\@todonotes@sizecommand}%
+% \end{macrocode}
+% We store the text that should be shown in this note into a box and copy this
+% box to a variable in Lua. The commands |\@parboxrestore|, |\@marginparreset|,
+% |\@minipagefalse| and |\outer@nobreak| are copied from the definition of
+% |\marginpar| in \LaTeX 2e to reset font settings, for example.
+% This is important when a note is placed inside a theorem environment.
+% \changes{0.2}{2015/02/20}{Reset font settings at begin of a todo note}
+% \begin{macrocode}
+ \savebox\@todonotes@notetextbox{%
+ \@parboxrestore
+ \@marginparreset
+ \@todonotes@sizecommand\@todonotes@text%
+ \@minipagefalse
+ \outer@nobreak
+ }%
+% \end{macrocode}
+% Prepare parameters and add the note to the list in Lua.
+% \begin{macrocode}
+ \if@todonotes@line%
+ \def\@todonotes@param@drawLeader{true}%
+ \else%
+ \def\@todonotes@param@drawLeader{false}%
+ \fi%
+ \if@todonotes@areaselected%
+ \def\@todonotes@param@noteType{area}%
+ \else%
+ \def\@todonotes@param@noteType{}%
+ \fi%
+ \directlua{luatodonotes.addNoteToList(\arabic{@todonotes@numberoftodonotes},%
+ \@todonotes@param@drawLeader,\luastringO{\@todonotes@param@noteType})}%
+}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{addElementToListOfTodos}
+% Define helper function |addElementToListOfTodos|.
+% \begin{macrocode}
+\newcommand{\@todonotes@addElementToListOfTodos}{%
+ \if@todonotes@colorinlistoftodos%
+ \addcontentsline{tdo}{todo}{%
+ \fcolorbox{\@todonotes@currentbordercolor}%
+ {\@todonotes@currentbackgroundcolor}%
+ {\textcolor{\@todonotes@currentbackgroundcolor}{o}}%
+ \ \@todonotes@caption}%
+ \else%
+ \addcontentsline{tdo}{todo}{\@todonotes@caption}%
+ \fi}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{drawInlineNote}
+% Define helper function |drawInlineNote|.
+% \begin{macrocode}
+\newcommand{\@todonotes@drawInlineNote}{%
+ {\par\noindent\begin{tikzpicture}[remember picture]%
+ \draw node[@todonotes@inlinenote,font=\@todonotes@sizecommand]{%
+ \if@todonotes@authorgiven%
+ {\noindent \@todonotes@sizecommand %
+ \@todonotes@author:\,\@todonotes@text}%
+ \else%
+ {\noindent \@todonotes@sizecommand \@todonotes@text}%
+ \fi};%
+ \end{tikzpicture}\par}%
+ }%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\missingfigure}
+% Defines the |\missingfigure| macro.
+% \begin{macrocode}
+\newcommand{\missingfigure}[2][]{%
+\setkeys{todonotes}{#1}%
+\addcontentsline{tdo}{todo}{\@todonotes@MissingFigureText: #2}%
+\par
+\noindent
+\begin{tikzpicture}
+\draw[fill=\@todonotes@currentfigcolor, draw = black!40, line width=2pt]
+ (-2, -2.5) rectangle +(\@todonotes@currentfigwidth, \@todonotes@currentfigheight);
+\draw (2, -0.3) node[right, text
+ width=\@todonotes@currentfigwidth-4.5cm] {#2};
+\draw[red, fill=white, rounded corners = 5pt, line width=10pt]
+ (30:2cm) -- (150:2cm) -- (270:2cm) -- cycle;
+\draw (0, 0.3) node {\@todonotes@MissingFigureUp};
+\draw (0, -0.3) node {\@todonotes@MissingFigureDown};
+\end{tikzpicture}\hfill
+}% Ending \missingfigure command
+\fi% Ending \@todonotes@ifdisabled
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\todototoc}
+% Inserts a reference to the list of todos in the table of contents. If |chapter| is defined,
+% |chapter| is used as level otherwise will |section| be used.
+% The |\todototoc| command respects the disable option.
+% \begin{macrocode}
+\newcommand{\todototoc}
+{
+ \if@todonotes@disabled
+ \else
+ \addcontentsline{toc}{\@ifundefined{chapter}{section}{chapter}}{\@todonotes@todolistname}
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\todo}
+% Define the |\todo| command as a redirection to |\@todo|.
+% \begin{macrocode}
+\newcommand{\todo}[2][]{\@bsphack\@todo[#1]{#2}\@esphack\ignorespaces}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\todoarea}
+% Define the |\todoarea| command as a redirection to |\@todoarea|.
+% We don't want to ignore spaces after this command.
+% \begin{macrocode}
+\newcommand{\todoarea}[3][]{\@bsphack\@todoarea[#1]{#2}{#3}\@esphack}%
+% \end{macrocode}
+% \end{macro}
+% The following commands are executed when a page is complete and is written to
+% the output PDF (shipout in \TeX\ terms).
+% The |\AtBeginShipout| command is provided by package atbegshi.
+% \begin{macrocode}
+\if@todonotes@disabled
+\else
+\AtBeginShipout{%
+% \end{macrocode}
+% We draw to the foreground or background of the page (depending if debug option
+% is set for the package).
+% \begin{macrocode}
+ \@todonotes@AtBeginShipoutUpperLeft{
+ \@todonotes@writeNextpageToLpo
+% \end{macrocode}
+% Determine if we are on a left or on a right side (important for margins) and
+% set variables accordingly.
+% |\relax| seems to be needed at end to really write new value for
+% currentsidemargin.
+% \begin{macrocode}
+ \checkoddpage%
+ \ifoddpageoroneside%
+ \@todonotes@currentsidemargin=\the\oddsidemargin%
+ \else%
+ \@todonotes@currentsidemargin=\the\evensidemargin%
+ \fi\relax%
+% \end{macrocode}
+% We switch to the default catcodes of \LaTeX\ here.
+% This is important if catcodes are changed in the main text, e.\,g., by a
+% verbatim environment at the end of the page.
+% \begin{macrocode}
+ \BeginCatcodeRegime\CatcodeTableLaTeX
+% \end{macrocode}
+% Calculates the areas, in which the labels can be placed.
+% This calculation depends on currentsidemargin.
+% So this has to be done inside |\AtBeginShipoutUpperLeft| (otherwise odd/even
+% page detection won't work).
+% \begin{macrocode}
+ \directlua{luatodonotes.calcLabelAreaDimensions()}%
+% \end{macrocode}
+% Calculates the needed height for every note.
+% This has to be outside of the tikzpicture because it uses a savebox to compute
+% the height.
+% This box does not work in the tikzpicture.
+% \begin{macrocode}
+ \directlua{luatodonotes.calcHeightsForNotes()}% has to be outside of tikzpicture
+% \end{macrocode}
+% Some classes modify the page margins using |\voffset| and |\hoffset|.
+% Our |tikzpicture| would be aligned using this modified page origin.
+% So we overrule the offsets using a |raisebox| and a negative |hspace|.
+% \changes{0.3}{2015/11/30}{Consider defined values for \texttt{\textbackslash
+% voffset} and \texttt{\textbackslash hoffset} to place the notes in the right
+% position}
+% \begin{macrocode}
+ \raisebox{\voffset}{%
+ \hspace{-\hoffset}%
+ \begin{tikzpicture}[remember picture,overlay]
+% \end{macrocode}
+% Reads the absolute coordinates of every note on the page and writes them to
+% the Lua objects.
+% \begin{macrocode}
+ \directlua{luatodonotes.getInputCoordinatesForNotes()}
+% \end{macrocode}
+% Runs the positioning algorithm and actually draws the notes and leaders.
+% \begin{macrocode}
+ \directlua{luatodonotes.printNotes()}
+ \end{tikzpicture}%
+ }%
+% \end{macrocode}
+% Delete the drawn notes from the Lua lists and prepare for the next page.
+% \begin{macrocode}
+ \directlua{luatodonotes.clearNotes()}%
+ \EndCatcodeRegime
+ }%
+}
+\fi % Ending \@todonotes@ifdisabled
+% \end{macrocode}
+%
+% \newpage
+% \Finale
+\endinput
+
diff --git a/macros/luatex/latex/luatodonotes/luatodonotes.ins b/macros/luatex/latex/luatodonotes/luatodonotes.ins
new file mode 100644
index 0000000000..1fc75094df
--- /dev/null
+++ b/macros/luatex/latex/luatodonotes/luatodonotes.ins
@@ -0,0 +1,75 @@
+%%
+%% Copyright (C) 2014-2015 by Fabian Lipp <fabian.lipp@gmx.de>
+%% based on the todonotes package by
+%% Henrik Skov Midtiby <henrikmidtiby@gmail.com>
+%%
+%% This file may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.2 of this license
+%% or (at your option) any later version. The latest version of this
+%% license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.2 or later is part of all distributions of LaTeX version
+%% 1999/12/01 or later.
+%%
+
+\input docstrip.tex
+\keepsilent
+
+\usedir{tex/lualatex/luatodonotes}
+
+\preamble
+
+This is a generated file.
+
+Copyright (C) 2014-2015 by Fabian Lipp <fabian.lipp@gmx.de>
+based on the todonotes package by
+ Henrik Skov Midtiby <henrikmidtiby@gmail.com>
+
+This file may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.2 of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.2 or later is part of all distributions of LaTeX version
+1999/12/01 or later.
+
+\endpreamble
+
+\generate{\file{luatodonotes.sty}{\from{luatodonotes.dtx}{package}}}
+
+\catcode`~=11\relax % needed to write ~ in the following message
+\obeyspaces
+\Msg{*************************************************************}
+\Msg{* *}
+\Msg{* To finish the installation you have to move the following *}
+\Msg{* files into a directory searched by TeX: *}
+\Msg{* *}
+\Msg{* luatodonotes.sty *}
+\Msg{* luatodonotes.lua *}
+\Msg{* path_line.lua *}
+\Msg{* path_point.lua *}
+\Msg{* inspect.lua *}
+\Msg{* *}
+\Msg{* A suitable directory would be *}
+\Msg{* texmf/tex/lualatex/luatodonotes *}
+\Msg{* in your local texmf-tree. For example, on a Linux system *}
+\Msg{* with TeX Live you can find the texmf-directory in your *}
+\Msg{* home directory under ~/texmf or system-wide under *}
+\Msg{* /usr/share/texmf. *}
+\Msg{* Don't forget to run texhash after copying the files (as *}
+\Msg{* root if installed system-wide). *}
+\Msg{* *}
+\Msg{* To produce the documentation run the file todonotes.dtx *}
+\Msg{* through LaTeX. *}
+\Msg{* *}
+\Msg{* Happy TeXing! *}
+\Msg{* *}
+\Msg{*************************************************************}
+
+
+\endbatchfile
+
diff --git a/macros/luatex/latex/luatodonotes/luatodonotes.lua b/macros/luatex/latex/luatodonotes/luatodonotes.lua
new file mode 100644
index 0000000000..5ef9b8f03b
--- /dev/null
+++ b/macros/luatex/latex/luatodonotes/luatodonotes.lua
@@ -0,0 +1,2231 @@
+--
+-- Copyright (C) 2014-2015 by Fabian Lipp <fabian.lipp@gmx.de>
+-- ------------------------------------------------------------
+--
+-- This file may be distributed and/or modified under the
+-- conditions of the LaTeX Project Public License, either version 1.2
+-- of this license or (at your option) any later version.
+-- The latest version of this license is in:
+--
+-- http://www.latex-project.org/lppl.txt
+--
+-- and version 1.2 or later is part of all distributions of LaTeX
+-- version 1999/12/01 or later.
+--
+
+require("lualibs")
+--require("debugger")()
+local inspect = require('inspect')
+
+local point = require'path_point'
+local pathLine = require'path_line'
+--local bezier3 = require'path_bezier3'
+
+luatodonotes = {}
+
+-- strings used to switch to standard catcodes for LaTeX packages
+local catcodeStart = "\\makeatletter"
+local catcodeEnd = "\\makeatother"
+
+local currentPage = 1
+
+local const1In = string.todimen("1in") -- needed for calculations of page borders
+ -- (used as a constant in TeX)
+-- constants set in sty-file
+-- + noteInnerSep (inner sep used for tikz nodes)
+-- + noteInterSpace (vertical space between notes)
+-- + routingAreaWidth (width of the track routing area for opo-leaders)
+-- + minNoteWidth (width that must be available for labels to consider the left or
+-- right border of the page for placing labels)
+-- + distanceNotesPageBorder (distance from the page borders to the outmost point
+-- of the labels)
+-- + distanceNotesText (horizontal distance between the labels and the text area)
+-- + rasterHeight (height of raster for po leader algorithm)
+-- + todonotesDebug (activate debug outputs when true)
+--
+-- values are filled into local variables in function initTodonotes (from
+-- corresponding fields luatodonotes.*)
+local noteInnerSep = nil
+local noteInterSpace = nil
+local routingAreaWidth = nil
+local minNoteWidth = nil
+local distanceNotesPageBorder = nil
+local distanceNotesText = nil
+local rasterHeight = nil
+local todonotesDebug = nil
+
+
+-- stores information about available algorithms
+local positioningAlgos = {}
+local splittingAlgos = {}
+local leaderTypes = {}
+
+local positioning = nil
+local splitting = nil
+local leaderType = nil
+function luatodonotes.setPositioningAlgo(algo)
+ if positioningAlgos[algo] ~= nil then
+ positioning = positioningAlgos[algo]
+ else
+ positioning = positioningAlgos["inputOrderStacks"]
+ tex.print("\\PackageWarningNoLine{luatodonotes}{Invalid value for parameter positioning: " .. algo .. "}")
+ end
+end
+function luatodonotes.setSplittingAlgo(algo)
+ if splittingAlgos[algo] ~= nil then
+ splitting = splittingAlgos[algo]
+ else
+ splitting = splittingAlgos["none"]
+ tex.print("\\PackageWarningNoLine{luatodonotes}{Invalid value for parameter split: " .. algo .. "}")
+ end
+end
+function luatodonotes.setLeaderType(typ)
+ if leaderTypes[typ] ~= nil then
+ leaderType = leaderTypes[typ]
+ else
+ leaderType = leaderTypes["opo"]
+ tex.print("\\PackageWarningNoLine{luatodonotes}{Invalid value for parameter leadertype: " .. typ .. "}")
+ end
+end
+
+-- stores the notes for the current page
+luatodonotes.notesForPage = {}
+local notesForPage = luatodonotes.notesForPage
+luatodonotes.notesForNextPage = {}
+local notesForNextPage = luatodonotes.notesForNextPage
+-- Fields for each note:
+-- index: numbers notes in whole document
+-- indexOnPage: index of the note in the notesForPage array
+-- textbox: links to a hbox that contains the text, which is displayed inside
+-- the note
+-- origInputX, origInputY: position in which the todo-command was issued
+-- inputX, inputY: position to which the leader should be attached (can have a
+-- certain offset to origInputX/Y)
+-- heightLeft, heightRight: height of the contained text when placed on
+-- left/right side
+-- pageNr: absolute number of page on which site for note is placed
+-- rightSide: true means the note should be placed on the right side;
+-- otherwise left side is meant
+-- fontsize: fontsize used for paragraph in that the note was defined
+-- baselineskip: \baselineskip in the paragraph in that the note was defined
+-- normalbaselineskip: \normalbaselineskip in the paragraph in that the note was defined
+-- outputX, outputY: position on which the north west anchor of the note should
+-- be placed
+-- lineColor: color of line connecting note to text
+-- backgroundColor: color of background of note
+-- borderColor: color of border of note
+-- leaderWidth: width of leader (used as argument for tikz line width)
+-- sizeCommand: fontsize command given as parameter for this note
+--
+-- Additional fields for text area:
+-- noteType: constant string "area"
+-- origInputEndX, origInputEndY: position at which the todo area ends
+-- pageNrEnd: absolute number of page on which todo area ends
+-- lineCountInArea: highest line index in area
+-- linesInArea: positions of lines in area (to detect page/column break)
+
+-- stores the areas for the labels on the current page
+-- (calculated in function calcLabelAreaDimensions())
+local labelArea = {}
+
+-- stores the positions of the text lines on every page
+local linePositions = {}
+-- Fields for every position:
+-- 1: position of baseline
+-- 2: upper bound of line (baseline + height)
+-- 3: lower bound of line (baseline - depth)
+
+-- variables used for construction of linePositions list when reading the file
+local linePositionsCurPage = {}
+local linePositionsPageNr = 0
+
+
+-- *** metatable for note objects ***
+local noteMt = {}
+-- getHeight(): yield heightLeft or heightRight depending on rightSide (implemented by metatable)
+function noteMt:getHeight()
+ if self.rightSide then
+ return self.heightRight
+ else
+ return self.heightLeft
+ end
+end
+function noteMt:getLabelAnchorY()
+ local leaderAnchor = positioning.leaderAnchor
+ local y
+ if leaderAnchor == "north east" then
+ y = self.outputY
+ elseif leaderAnchor == "east" then
+ y = self.outputY - noteInnerSep - self:getHeight() / 2
+ else
+ error("Invalid anchor for algorithm")
+ end
+
+ if positioning.leaderShift then
+ y = y + self.leaderShiftY
+ end
+
+ return y
+end
+function noteMt:getInTextAnchorTikz()
+ return "(" .. self.inputX .. "sp," .. self.inputY .. "sp)"
+end
+function noteMt:getLabelAnchorTikz()
+ local leaderAnchor = positioning.leaderAnchor
+ if leaderAnchor == "north east" and self.rightSide then
+ leaderAnchor = "north west"
+ elseif leaderAnchor == "east" and self.rightSide then
+ leaderAnchor = "west"
+ end
+
+ local shiftStr = ""
+ if positioning.leaderShift then
+ shiftStr = "[shift={(" .. self.leaderShiftX .. "sp," .. self.leaderShiftY .. "sp)}]"
+ end
+
+ return "(" .. shiftStr .. " @todonotes@" .. self.index .. " note." .. leaderAnchor .. ")"
+end
+function noteMt:boxForNoteText(rightSide)
+ local area = labelArea:getArea(rightSide)
+ local noteWidth
+ if area == nil then
+ noteWidth = minNoteWidth
+ else
+ noteWidth = area.noteWidth - 2*noteInnerSep
+ end
+ local retval = "\\directlua{tex.box[\"@todonotes@notetextbox\"] = " ..
+ "node.copy_list(luatodonotes.notesForPage[" .. self.indexOnPage .. "].textbox)}"
+ retval = retval .. "\\parbox{" .. noteWidth .. "sp}" ..
+ "{\\raggedright\\unhbox\\@todonotes@notetextbox}"
+ return retval
+end
+
+function noteMt:getClipPathForTodoArea()
+ -- detext which lines are in same column/page as start of area
+ local lineCount = self.lineCountInArea
+ local maxLine = 1
+ local lines = self.linesInArea
+ local lastY = lines[1]
+ while maxLine < lineCount do
+ if lines[maxLine + 1] < lastY then
+ maxLine = maxLine + 1
+ lastY = lines[maxLine]
+ end
+ end
+
+ local function nodename(i, corner)
+ return "(@todonotes@" .. self.index .. "@" .. i .. " area" .. corner .. ")"
+ end
+ local path = nodename(1, "NW")
+ local pathLeft = ""
+ if maxLine == 1 then
+ -- only one line
+ path = path .. " -- " .. nodename(1, "NE") ..
+ " -- " .. nodename(1, "SE")
+ else
+ path = path .. " -- " .. nodename(1, "NE") ..
+ " decorate[@todonotes@todoarea] { -- " .. nodename(1, "SE") .. "}"
+ end
+ for i = 2, maxLine do
+ if i == lineCount then
+ -- area does not use the whole line
+ path = path .. " -| " .. nodename(i, "NE") ..
+ " -- " .. nodename(i, "SE")
+ else
+ -- area uses whole line
+ path = path .. " -- " .. nodename(i, "NE") ..
+ " decorate[@todonotes@todoarea] { -- " .. nodename(i, "SE") .. "}"
+ end
+ pathLeft = " -- " .. nodename(i, "SW") ..
+ " decorate[@todonotes@todoarea] { -- " .. nodename(i, "NW") .. "}" ..
+ pathLeft
+ end
+ path = path .. pathLeft .. " -| " .. nodename(1, "SW") .. "-- cycle"
+ return path
+end
+
+
+
+-- *** label areas ***
+-- stores areas for placing labels on current page
+function labelArea:getArea(rightSide)
+ if rightSide then
+ return self.right
+ else
+ return self.left
+ end
+end
+-- yields the x-coordinate of the boundary of the label that is pointing
+-- towards the text
+function labelArea:getXTextSide(rightSide)
+ if rightSide then
+ return self.right.left
+ else
+ return self.left.right
+ end
+end
+function labelArea:isOneSided()
+ if self.right == nil or self.left == nil then
+ return true
+ else
+ return false
+ end
+end
+
+
+
+-- divides notes in two lists (for left and right side)
+-- side must be stored in note.rightSide for every note before using this function
+local function segmentNotes(notes)
+ local availableNotesLeft = {}
+ local availableNotesRight = {}
+ for k, v in pairs(notes) do
+ if v.rightSide == true then
+ table.insert(availableNotesRight, k)
+ else
+ table.insert(availableNotesLeft, k)
+ end
+ end
+ return availableNotesLeft, availableNotesRight
+end
+
+
+
+-- is called by the sty-file when all settings (algorithms etc.) are made
+function luatodonotes.initTodonotes()
+ -- fill local variables (defined at begin of file) with package options
+ noteInnerSep = luatodonotes.noteInnerSep
+ noteInterSpace = luatodonotes.noteInterSpace
+ routingAreaWidth = luatodonotes.routingAreaWidth
+ minNoteWidth = luatodonotes.minNoteWidth
+ distanceNotesPageBorder = luatodonotes.distanceNotesPageBorder
+ distanceNotesText = luatodonotes.distanceNotesText
+ rasterHeight = luatodonotes.rasterHeight
+ todonotesDebug = luatodonotes.todonotesDebug
+
+ if positioning.needLinePositions then
+ luatexbase.add_to_callback("post_linebreak_filter", luatodonotes.callbackOutputLinePositions, "outputLinePositions")
+ tex.print("\\@starttoc{lpo}")
+ tex.print("\\directlua{lpoFileStream = \\the\\tf@lpo}")
+ end
+end
+
+
+-- valid values for noteType: nil/"" (for point in text), "area"
+function luatodonotes.addNoteToList(index, drawLeader, noteType)
+ if next(notesForPage) ~= nil
+ and index <= notesForPage[#notesForPage].index then
+ -- Index is the same as for one of the previous note.
+ -- This can happen when commands are read multiple times
+ -- => don't add anything to list in this case
+ return
+ end
+ local newNote = {}
+ newNote.index = index
+ newNote.textbox = node.copy_list(tex.box["@todonotes@notetextbox"])
+ newNote.baselineskip = tex.dimen["@todonotes@baselineskip"]
+ newNote.normalbaselineskip = tex.dimen["@todonotes@normalbaselineskip"]
+ newNote.fontsize = tex.dimen["@todonotes@fontsize"]
+ newNote.lineColor = tex.toks["@todonotes@toks@currentlinecolor"]
+ newNote.backgroundColor = tex.toks["@todonotes@toks@currentbackgroundcolor"]
+ newNote.borderColor = tex.toks["@todonotes@toks@currentbordercolor"]
+ newNote.leaderWidth = tex.toks["@todonotes@toks@currentleaderwidth"]
+ newNote.sizeCommand = tex.toks["@todonotes@toks@sizecommand"]
+ newNote.drawLeader = drawLeader
+ if noteType == "area" then
+ newNote.noteType = "area"
+ newNote.lineCountInArea = 0
+ -- else: newNote.noteType = nil (default value)
+ end
+ setmetatable(newNote, {__index = noteMt})
+ newNote.indexOnPage = #notesForPage + 1
+ notesForPage[newNote.indexOnPage] = newNote
+end
+
+function luatodonotes.clearNotes()
+ -- delete the texts for the notes on this page from memory
+ -- (garbage collection does not work for nodes)
+ for _, v in pairs(notesForPage) do
+ node.free(v.textbox)
+ end
+ luatodonotes.notesForPage = notesForNextPage
+ notesForPage = luatodonotes.notesForPage
+ -- update indexOnPage for the new notes
+ for k, v in pairs(notesForPage) do
+ v.indexOnPage = k
+ end
+
+ currentPage = currentPage + 1
+end
+
+function luatodonotes.processLastLineInTodoArea()
+ -- LaTeX counter is accessed as TeX count by prefixing c@
+ ind = tex.count["c@@todonotes@numberoftodonotes"]
+ val = tex.count["c@@todonotes@numberofLinesInArea"]
+ notesForPage[#notesForPage].lineCountInArea = val
+end
+
+
+-- *** constructing the linePositions list ***
+function luatodonotes.linePositionsNextPage()
+ linePositionsPageNr = linePositionsPageNr + 1
+ linePositionsCurPage = {}
+ linePositions[linePositionsPageNr] = linePositionsCurPage
+end
+
+function luatodonotes.linePositionsAddLine(ycoord, lineheight, linedepth)
+ local baseline = ycoord - tex.pageheight
+ linePositionsCurPage[#linePositionsCurPage + 1] = {baseline, baseline + lineheight, baseline - linedepth}
+end
+
+
+function luatodonotes.getInputCoordinatesForNotes()
+ tex.sprint(catcodeStart)
+ for k, v in ipairs(notesForPage) do
+ local nodename = "@todonotes@" .. v.index .. " inText"
+
+ tex.sprint("\\pgfextractx{\\@todonotes@extractx}{\\pgfpointanchor{" ..
+ nodename .. "}{center}}")
+ tex.sprint("\\pgfextracty{\\@todonotes@extracty}{\\pgfpointanchor{" ..
+ nodename .. "}{center}}")
+ tex.print("\\directlua{luatodonotes.notesForPage[" .. k .. "].origInputX = " ..
+ "tex.dimen[\"@todonotes@extractx\"]}")
+ tex.print("\\directlua{luatodonotes.notesForPage[" .. k .. "].origInputY = " ..
+ "tex.dimen[\"@todonotes@extracty\"]}")
+
+ if v.noteType == "area" then
+ nodename = nodename .. "End"
+ tex.sprint("\\pgfextractx{\\@todonotes@extractx}{\\pgfpointanchor{" ..
+ nodename .. "}{center}}")
+ tex.sprint("\\pgfextracty{\\@todonotes@extracty}{\\pgfpointanchor{" ..
+ nodename .. "}{center}}")
+ tex.print("\\directlua{luatodonotes.notesForPage[" .. k .. "].origInputEndX = " ..
+ "tex.dimen[\"@todonotes@extractx\"]}")
+ tex.print("\\directlua{luatodonotes.notesForPage[" .. k .. "].origInputEndY = " ..
+ "tex.dimen[\"@todonotes@extracty\"]}")
+
+ notesForPage[k].linesInArea = {}
+ for i = 1, v.lineCountInArea do
+ nodename = "@todonotes@" .. v.index .. "@" .. i .. " areaSW"
+ tex.sprint("\\pgfextracty{\\@todonotes@extracty}{\\pgfpointanchor{" ..
+ nodename .. "}{center}}")
+ tex.print("\\directlua{luatodonotes.notesForPage[" .. k .. "].linesInArea[" ..
+ i .. "] = " .. "tex.dimen[\"@todonotes@extracty\"]}")
+ end
+ end
+ end
+ tex.sprint(catcodeEnd)
+end
+
+function luatodonotes.calcLabelAreaDimensions()
+ local routingAreaSpace = 0
+ if leaderType.needRoutingArea then
+ routingAreaSpace = routingAreaWidth
+ end
+
+ local top = tex.voffset + tex.dimen.topmargin + const1In
+ local bottom = top + tex.dimen.headheight + tex.dimen.headsep + tex.dimen.textheight + tex.dimen.footskip
+ local currentsidemargin = tex.hoffset + tex.dimen["@todonotes@currentsidemargin"] + const1In
+
+ local left = {}
+ left.top = -top
+ left.bottom = -bottom
+ left.left = distanceNotesPageBorder
+ left.right = currentsidemargin - distanceNotesText - routingAreaSpace
+ if left.right - left.left < minNoteWidth then
+ -- not enough space left of text
+ left = nil
+ else
+ left.noteWidth = left.right - left.left
+ end
+
+ local right = {}
+ right.top = -top
+ right.bottom = -bottom
+ right.left = currentsidemargin + tex.dimen.textwidth + distanceNotesText + routingAreaSpace
+ right.right = tex.pagewidth - distanceNotesPageBorder
+ if right.right - right.left < minNoteWidth then
+ -- not enough space right of text
+ right = nil
+ else
+ right.noteWidth = right.right - right.left
+ end
+
+ local text = {}
+ text.left = currentsidemargin
+ text.right = currentsidemargin + tex.dimen.textwidth
+
+ labelArea.left = left
+ labelArea.right = right
+ labelArea.text = text
+end
+
+function luatodonotes.calcHeightsForNotes()
+ -- function has to be called outside of a tikzpicture-environment
+ tex.sprint(catcodeStart)
+ for k, v in ipairs(notesForPage) do
+ -- store height for note
+ -- (is determined by creating a box with the text and reading its size)
+
+ -- left side
+ tex.sprint("\\savebox{\\@todonotes@heightcalcbox}" ..
+ "{" .. v.sizeCommand .. v:boxForNoteText(false) .. "}")
+ tex.sprint("\\@todonotes@heightcalcboxdepth=\\dp\\@todonotes@heightcalcbox")
+ tex.sprint("\\@todonotes@heightcalcboxheight=\\ht\\@todonotes@heightcalcbox")
+ tex.sprint("\\directlua{luatodonotes.notesForPage[" .. k .. "].heightLeft = " ..
+ "tex.dimen[\"@todonotes@heightcalcboxheight\"]" ..
+ " + tex.dimen[\"@todonotes@heightcalcboxdepth\"]}")
+
+ -- right side
+ tex.sprint("\\savebox{\\@todonotes@heightcalcbox}" ..
+ "{" .. v.sizeCommand .. v:boxForNoteText(true) .. "}")
+ tex.sprint("\\@todonotes@heightcalcboxdepth=\\dp\\@todonotes@heightcalcbox")
+ tex.sprint("\\@todonotes@heightcalcboxheight=\\ht\\@todonotes@heightcalcbox")
+ tex.sprint("\\directlua{luatodonotes.notesForPage[" .. k .. "].heightRight = " ..
+ "tex.dimen[\"@todonotes@heightcalcboxheight\"]" ..
+ " + tex.dimen[\"@todonotes@heightcalcboxdepth\"]}")
+
+ -- store pageNr for note
+ -- (is determined as reference to a label)
+ tex.sprint("\\directlua{luatodonotes.notesForPage[" .. k .. "].pageNr = " ..
+ "\\zref@extract{@todonotes@" .. v.index .. "}{abspage}}")
+ if v.noteType == "area" then
+ tex.sprint("\\directlua{luatodonotes.notesForPage[" .. k .. "].pageNrEnd = " ..
+ "\\zref@extract{@todonotes@" .. v.index .. "@end}{abspage}}")
+ end
+ end
+ tex.sprint(catcodeEnd)
+end
+
+local inputShiftX = string.todimen("-0.05cm") -- sensible value depends on shape of mark
+function luatodonotes.printNotes()
+ print("Drawing notes for page " .. currentPage)
+
+ -- seperate notes that should be placed on another page
+ -- This can occur when note is in a paragraph which doesn't fit on the
+ -- current page and is thus moved to the next one. But the \todo-command is
+ -- still read before the shipout of the current page is done
+ luatodonotes.notesForNextPage = {}
+ notesForNextPage = luatodonotes.notesForNextPage
+ local k=1
+ while k <= #notesForPage do
+ local v = notesForPage[k]
+ if v.pageNr == 0 then
+ -- Notes without a page number occur when the zref label is not
+ -- defined correctly. This happens with notes in a
+ -- \caption-command, e.g.
+ -- In this case two version of the note are stored and we drop the
+ -- note that does not have a valid page number (the other note
+ -- seems to have one).
+ table.remove(notesForPage, k)
+ if todonotesDebug then
+ print("deleting note: " .. k .. " (" .. v.index .. ")")
+ end
+ elseif v.pageNr ~= currentPage then
+ table.insert(notesForNextPage, v)
+ table.remove(notesForPage, k)
+ if todonotesDebug then
+ print("moving note to next page: " .. k .. " (" .. v.index .. ")")
+ end
+ else
+ -- update index here (needed if a note was deleted before)
+ v.indexOnPage = k
+ k = k + 1
+ end
+ end
+
+ -- add offset to input coordinates
+ for _, v in pairs(notesForPage) do
+ if v.noteType ~= "area" then
+ v.inputX = v.origInputX + inputShiftX
+ local bls = v.baselineskip
+ if v.baselineskip == 0 then
+ bls = v.normalbaselineskip
+ end
+ v.inputY = v.origInputY - 1.3 * (bls - v.fontsize)
+ else
+ v.inputX = v.origInputX
+ v.inputY = v.origInputY
+ end
+ end
+
+ splitting.algo()
+ if positioning.twoSided then
+ local notesLeft, notesRight = segmentNotes(notesForPage)
+ if #notesLeft > 0 then
+ positioning.algo(notesLeft, false)
+ end
+ if #notesRight > 0 then
+ positioning.algo(notesRight, true)
+ end
+ else
+ positioning.algo()
+ end
+ for k, v in ipairs(notesForPage) do
+ if todonotesDebug then
+ local function outputWithPoints(val)
+ if val ~= nil then
+ return val .. " (" .. number.topoints(val, "%s%s") .. ")"
+ else
+ return ""
+ end
+ end
+ print("-----------------")
+ print(k .. ": ")
+ print("index: " .. v.index)
+ print("origInputX: " .. v.origInputX)
+ print("origInputY: " .. v.origInputY)
+ if (v.noteType ~= nil) then
+ print("noteType: " .. v.noteType)
+ print("origInputEndX:" .. v.origInputEndX)
+ print("origInputEndY:" .. v.origInputEndY)
+ print("lineCountInArea:" .. v.lineCountInArea)
+ print("linesInArea :" .. inspect(v.linesInArea))
+ else
+ print("noteType: nil")
+ end
+ print("inputX: " .. v.inputX)
+ print("inputY: " .. v.inputY)
+ print("outputX: " .. v.outputX)
+ print("outputY: " .. v.outputY)
+ if (v.rasterSlots ~= nil) then
+ print("rasterSlots: " .. v.rasterSlots)
+ end
+ print("baselineskip: " .. outputWithPoints(v.baselineskip))
+ print("nbaselineskip:" .. outputWithPoints(v.normalbaselineskip))
+ print("fontsize: " .. outputWithPoints(v.fontsize))
+ print("textbox: " .. inspect(v.textbox))
+ print("height: " .. outputWithPoints(v:getHeight()))
+ print("heightLeft: " .. outputWithPoints(v.heightLeft))
+ print("heightRight: " .. outputWithPoints(v.heightRight))
+ print("rightSide: " .. tostring(v.rightSide))
+ if v.pageNr ~= nil then
+ print("pageNr: " .. v.pageNr)
+ end
+ print("lineColor: " .. v.lineColor)
+ print("backgroundColor:" .. v.backgroundColor)
+ print("borderColor: " .. v.borderColor)
+ print("leaderWidth: " .. v.leaderWidth)
+ print("sizeCommand: " .. v.sizeCommand)
+ print("drawLeader: " .. tostring(v.drawLeader))
+ end
+
+ -- print note
+ tex.print(catcodeStart)
+ tex.print("\\node[@todonotes@notestyle,anchor=north west," ..
+ "fill=" .. v.backgroundColor .. ",draw=" .. v.borderColor .. "," ..
+ "font=" .. v.sizeCommand .. "] " ..
+ "(@todonotes@" .. v.index ..
+ " note) at (" .. v.outputX .. "sp," .. v.outputY .. "sp) {" ..
+ v:boxForNoteText(v.rightSide) .. "};")
+ tex.print(catcodeEnd)
+
+
+ -- output debugging hints on page
+ if todonotesDebug then
+ tex.print("\\node[anchor=north west,text=blue,fill=white,rectangle] at (@todonotes@" .. v.index .. " inText) {" .. v.index .. "};")
+ tex.print("\\draw[green,fill] (@todonotes@" .. v.index .. " inText) circle(2pt);")
+ tex.print("\\draw[black,fill] (@todonotes@" .. v.index .. " inText) circle(0.2pt);")
+ if v.noteType == "area" then
+ tex.print("\\draw[red,fill] (@todonotes@" .. v.index .. " inTextEnd) circle(2pt);")
+ end
+
+ if (v.noteType ~= nil) then
+ print(v:getClipPathForTodoArea())
+ tex.print("\\draw[blue] " .. v:getClipPathForTodoArea() .. ";")
+ --for i=1, v.lineCountInArea do
+ --tex.print(" (@todonotes@" .. v.index .. "@" .. i .. " areaSW) -- ")
+ --end
+ --tex.print("cycle;")
+ end
+ end
+ end
+ -- draw leader
+ leaderType.algo()
+
+ -- draw mark in text
+ for _, v in pairs(notesForPage) do
+ if v.drawLeader ~= false and v.noteType ~= "area" then
+ local shiftStr = "(" .. v.inputX .. "sp," .. v.inputY .. "sp)"
+ tex.print("\\draw[@todonotes@textmark," ..
+ "draw=" .. v.lineColor .. ",fill=" .. v.lineColor .. "," ..
+ "shift={" .. shiftStr .. "}," ..
+ "scale around={0.5:(-0,-0)},shift={(-0.5,-0.1)}]" ..
+ "(1,0) .. controls (0.5,0.2) and (0.65,0.3) .." ..
+ "(0.5,0.7) .. controls (0.35,0.3) and (0.5,0.2) .." ..
+ "(0,0) -- cycle;")
+ end
+ end
+
+ --- draw label areas when requested
+ if todonotesDebug then
+ local area = labelArea.left
+ if area ~= nil then
+ tex.print("\\draw[blue] (" .. area.left .. "sp," .. area.top .. "sp) rectangle (" ..
+ area.right .. "sp," .. area.bottom .. "sp);")
+ end
+ area = labelArea.right
+ if area ~= nil then
+ tex.print("\\draw[blue] (" .. area.left .. "sp," .. area.top .. "sp) rectangle (" ..
+ area.right .. "sp," .. area.bottom .. "sp);")
+ end
+ end
+end
+
+
+
+
+-- ********** Helper Functions **********
+
+-- * comparators for table.sort() *
+-- (yields true if first parameter should be placed before second parameter in
+-- sorted table)
+local function compareNoteInputXAsc(note1, note2)
+ if note1.inputX < note2.inputX then
+ return true
+ end
+end
+
+local function compareNoteIndInputXAsc(key1, key2)
+ if notesForPage[key1].inputX < notesForPage[key2].inputX then
+ return true
+ end
+end
+
+local function compareNoteIndInputXDesc(key1, key2)
+ if notesForPage[key1].inputX > notesForPage[key2].inputX then
+ return true
+ end
+end
+
+local function compareNoteIndInputYDesc(key1, key2)
+ local v1 = notesForPage[key1]
+ local v2 = notesForPage[key2]
+ if v1.inputY > v2.inputY then
+ return true
+ elseif v1.inputY == v2.inputY then
+ if v1.inputX < v2.inputX then
+ return true
+ end
+ end
+end
+
+-- * callbacks for Luatex *
+local function appendStrToTokenlist(tokenlist, str)
+ str:gsub(".", function(c)
+ tokenlist[#tokenlist + 1] = {12, c:byte(), 0}
+ end)
+end
+-- writes commands into the node tree that print the absolute position on the
+-- page to the output file (streamId is taken from lpoFileStream) at the
+-- beginning of every line
+-- should be called as post_linebreak_filter
+local ID_GLYPH_NODE = node.id("glyph")
+local ID_HLIST_NODE = node.id("hlist")
+function luatodonotes.callbackOutputLinePositions(head)
+ while head do
+ if head.id == ID_HLIST_NODE then
+ -- check if we are in the main text area (hlists in, e.g.,
+ -- tikz nodes should have other widths)
+ if head.width == tex.dimen.textwidth then
+ -- check if there is a glyph in this hlist
+ -- -> then we consider it a text line
+ local foundGlyph = false
+ local glyphTest = head.head
+ while glyphTest do
+ if glyphTest.id == ID_GLYPH_NODE then
+ foundGlyph = true
+ break
+ end
+ glyphTest = glyphTest.next
+ end
+
+ if foundGlyph then
+ local w = node.new("whatsit", "write") -- 8/1
+ w.stream = lpoFileStream
+ local tokenlist = {
+ {12, 92, 0}, -- \
+ {12, 64, 0}, -- @
+ {12, 116, 0}, -- t
+ {12, 111, 0}, -- o
+ {12, 100, 0}, -- d
+ {12, 111, 0}, -- o
+ {12, 110, 0}, -- n
+ {12, 111, 0}, -- o
+ {12, 116, 0}, -- t
+ {12, 101, 0}, -- e
+ {12, 115, 0}, -- s
+ {12, 64, 0}, -- @
+ {12, 108, 0}, -- l
+ {12, 105, 0}, -- i
+ {12, 110, 0}, -- n
+ {12, 101, 0}, -- e
+ {12, 112, 0}, -- p
+ {12, 111, 0}, -- o
+ {12, 115, 0}, -- s
+ {12, 105, 0}, -- i
+ {12, 116, 0}, -- t
+ {12, 105, 0}, -- i
+ {12, 111, 0}, -- o
+ {12, 110, 0}, -- n
+ {12, 123, 0} -- {
+ }
+ t = token.create("@todonotes@pdflastypos")
+ tokenlist[#tokenlist + 1] = t
+ tokenlist[#tokenlist + 1] = {12, 125, 0}
+ tokenlist[#tokenlist + 1] = {12, 123, 0}
+ appendStrToTokenlist(tokenlist, tostring(head.height))
+ tokenlist[#tokenlist + 1] = {12, 125, 0}
+ tokenlist[#tokenlist + 1] = {12, 123, 0}
+ appendStrToTokenlist(tokenlist, tostring(head.depth))
+ tokenlist[#tokenlist + 1] = {12, 125, 0}
+ w.data = tokenlist
+ head.head = node.insert_before(head.head,head.head,w)
+
+ local w = node.new("whatsit", "pdf_save_pos") -- 8/23
+ head.head = node.insert_before(head.head,head.head,w)
+ end
+ end
+ end
+ head = head.next
+ end
+ return true
+end
+
+
+
+
+
+-- ********** Leader Drawing Algorithms **********
+
+local function drawLeaderPath(note, path)
+ if note.drawLeader == false then
+ return
+ end
+ local clipPath
+ if note.noteType == "area" then
+ clipPath = note:getClipPathForTodoArea()
+ tex.print("\\begin{scope}")
+ tex.print("\\clip (current page.north west) rectangle (current page.south east) ")
+ tex.print(clipPath)
+ tex.print(";")
+ end
+ tex.print("\\draw[@todonotes@leader,draw=" .. note.lineColor ..
+ ",line width=" .. note.leaderWidth .. ",name path=leader] " .. path .. ";")
+ if note.noteType == "area" then
+ tex.print("\\path[name path=clipping] " .. clipPath .. ";")
+ tex.print("\\fill[@todonotes@leader,name intersections={of=leader and clipping, by=x,sort by=leader},fill=" .. note.lineColor .. "] (x) circle(3pt);")
+ tex.print("\\end{scope}")
+ end
+end
+
+
+-- ** leader drawing: s-leaders
+local function drawSLeaders()
+ for k, v in ipairs(notesForPage) do
+ drawLeaderPath(v, v:getLabelAnchorTikz() ..
+ " -- " .. v:getInTextAnchorTikz())
+ end
+end
+leaderTypes["s"] = {algo = drawSLeaders}
+
+
+
+-- ** leader drawing: opo-leaders
+local function drawOpoLeader(v, opoShift, rightSide)
+ if rightSide then
+ opoShift = - opoShift
+ end
+ drawLeaderPath(v, v:getLabelAnchorTikz() .. " -- +(" .. opoShift .. "sp,0) " ..
+ "|- " .. v:getInTextAnchorTikz())
+end
+local function drawOpoGroup(group, directionDown, rightSide)
+ if directionDown == nil then
+ for _, v2 in ipairs(group) do
+ drawOpoLeader(notesForPage[v2], 0, rightSide)
+ end
+ else
+ if #group == 1 then
+ -- place p-section of leader in center of routing area
+ local opoShift = distanceNotesText / 2 + routingAreaWidth / 2
+ drawOpoLeader(notesForPage[group[1]], opoShift, rightSide)
+ else
+ local leaderDistance = routingAreaWidth / (#group - 1)
+
+ -- initialise shift value
+ local nextOpoShift, move
+ if directionDown then
+ nextOpoShift = distanceNotesText / 2 + routingAreaWidth
+ move = -leaderDistance
+ else
+ nextOpoShift = distanceNotesText / 2
+ move = leaderDistance
+ end
+
+ -- cycle through group
+ for _, v2 in ipairs(group) do
+ drawOpoLeader(notesForPage[v2], nextOpoShift, rightSide)
+ nextOpoShift = nextOpoShift + move
+ end
+ end
+ end
+end
+local function drawOpoLeadersSide(notes, rightSide)
+ table.sort(notes, compareNoteIndInputYDesc)
+
+ local lastDirectionDown = nil
+ local group = {}
+ local prevNote
+ for _, ind in ipairs(notes) do
+ local v = notesForPage[ind]
+
+ local leaderAnchorY = v:getLabelAnchorY()
+ if leaderAnchorY > v.inputY then
+ newDirectionDown = true
+ elseif leaderAnchorY < v.inputY then
+ newDirectionDown = false
+ else
+ newDirectionDown = nil
+ end
+
+ if lastDirectionDown == newDirectionDown and
+ prevNote ~= nil and
+ -- following conditions check that leaders would really intersect
+ -- otherwise we can start a new group
+ ((newDirectionDown and leaderAnchorY >= prevNote.inputY) or
+ (not newDirectionDown and v.inputY >= prevNote:getLabelAnchorY())) then
+ -- note belongs to group
+ table.insert(group, ind)
+ else
+ -- draw leaders for group
+ drawOpoGroup(group, lastDirectionDown, rightSide)
+
+ -- initialise new group with this note
+ lastDirectionDown = newDirectionDown
+ group = {ind}
+ end
+
+ prevNote = v
+ end
+ drawOpoGroup(group, lastDirectionDown, rightSide)
+end
+local function drawOpoLeaders()
+ local notesLeft, notesRight = segmentNotes(notesForPage)
+ if #notesLeft > 0 then
+ drawOpoLeadersSide(notesLeft, false)
+ end
+ if #notesRight > 0 then
+ drawOpoLeadersSide(notesRight, true)
+ end
+end
+leaderTypes["opo"] = {algo = drawOpoLeaders,
+ needRoutingArea = true}
+
+
+
+-- ** leader drawing: po-leaders
+local function drawPoLeaders()
+ for _, v in ipairs(notesForPage) do
+ drawLeaderPath(v, v:getLabelAnchorTikz() .. " -| " .. v:getInTextAnchorTikz())
+ end
+end
+leaderTypes["po"] = {algo = drawPoLeaders}
+
+
+
+-- ** leader drawing: os-leaders
+local function drawOsLeaders()
+ for _, v in ipairs(notesForPage) do
+ local cornerX
+ if v.rightSide then
+ cornerX = labelArea.right.left - distanceNotesText / 2 - routingAreaWidth
+ else
+ cornerX = labelArea.left.right + distanceNotesText / 2 + routingAreaWidth
+ end
+ drawLeaderPath(v, v:getInTextAnchorTikz() ..
+ " -- (" .. cornerX .. "sp,0 |- 0," .. v.inputY .. "sp) -- " ..
+ v:getLabelAnchorTikz())
+ end
+end
+leaderTypes["os"] = {algo = drawOsLeaders,
+ needRoutingArea = true}
+
+
+
+-- ** leader drawing: s-Bezier-leaders
+-- additional fields for each note:
+-- leaderArmY
+-- movableControlPointX
+-- optimalPositionX
+-- currentForce
+-- forceLimitDec
+-- forceLimitInc
+
+-- settings for algorithm
+local maxIterations = 1000
+local factorRepulsiveControlPoint = 1
+local factorAttractingControlPoint = 1
+local stopCondition = 65536 -- corresponds to 1pt
+
+local function constructCurve(l)
+ local curve = {}
+
+ -- site
+ curve[1] = {}
+ curve[1].x = l.inputX
+ curve[1].y = l.inputY
+
+ -- unmovable control point (middle point of site and movable control point)
+ curve[2] = {}
+ curve[2].x = (l.inputX + l.movableControlPointX) / 2
+ curve[2].y = (l.inputY + l.leaderArmY) / 2
+
+ -- movable control point
+ curve[3] = {}
+ curve[3].x = l.movableControlPointX
+ curve[3].y = l.leaderArmY
+
+ -- port
+ curve[4] = {}
+ curve[4].x = labelArea:getXTextSide(l.rightSide)
+ curve[4].y = l.leaderArmY
+
+ return curve
+end
+local function getPointOnCurve(t, curve)
+ if #curve ~= 4 then
+ error("4 points needed for a Bezier-curve. Given size was: " .. #curve)
+ end
+
+ local x = (1 - t) * (1 - t) * (1 - t) * curve[1].x +
+ 3 * t * (1 - t) * (1 - t) * curve[2].x +
+ 3 * t * t * (1 - t) * curve[3].x +
+ t * t * t * curve[4].x
+
+ local y = (1 - t) * (1 - t) * (1 - t) * curve[1].y +
+ 3 * t * (1 - t) * (1 - t) * curve[2].y +
+ 3 * t * t * (1 - t) * curve[3].y +
+ t * t * t * curve[4].y;
+
+ return x, y
+end
+local function getDistance(line1, line2)
+ local t1, t2 = pathLine.line_line_intersection(line1.x1, line1.y1, line1.x2, line1.y2,
+ line2.x1, line2.y1, line2.x2, line2.y2)
+ if 0 <= t1 and t1 <= 1 and 0 <= t2 and t2 <= 1 then
+ -- the lines do intersect
+ return 0
+ end
+
+ local d1 = pathLine.hit(line2.x1, line2.y1, line1.x1, line1.y1, line1.x2, line1.y2)
+ local d2 = pathLine.hit(line2.x2, line2.y2, line1.x1, line1.y1, line1.x2, line1.y2)
+ local d3 = pathLine.hit(line1.x1, line1.y1, line2.x1, line2.y1, line2.x2, line2.y2)
+ local d4 = pathLine.hit(line1.x2, line1.y2, line2.x1, line2.y1, line2.x2, line2.y2)
+ return math.sqrt(math.min(d1, d2, d3, d4))
+end
+local function checkCurveApproximation(curve1, curve2)
+ -- these lists will contain the sections of the approximation of the two curves
+ local sectionsCurve1 = {}
+ local sectionsCurve2 = {}
+
+ -- get line segments of the first curve
+ local numberOfSectionsCurve1 = luatodonotes.numberOfCurvePartitions
+ local temp1X, temp1Y = getPointOnCurve(0, curve1)
+ local i = 1
+ while i <= numberOfSectionsCurve1 do
+ local t = i / numberOfSectionsCurve1
+ local temp2X, temp2Y = getPointOnCurve(t, curve1)
+ local line = {}
+ line.x1 = temp1X
+ line.y1 = temp1Y
+ line.x2 = temp2X
+ line.y2 = temp2Y
+ table.insert(sectionsCurve1, line)
+ temp1X, temp1Y = temp2X, temp2Y
+ i = i + 1
+ end
+
+ -- get line segments of the second curve
+ local numberOfSectionsCurve2 = luatodonotes.numberOfCurvePartitions
+ temp1X, temp1Y = getPointOnCurve(0, curve2)
+ i = 1
+ while i <= numberOfSectionsCurve2 do
+ local t = i / numberOfSectionsCurve2
+ local temp2X, temp2Y = getPointOnCurve(t, curve2)
+ local line = {}
+ line.x1 = temp1X
+ line.y1 = temp1Y
+ line.x2 = temp2X
+ line.y2 = temp2Y
+ table.insert(sectionsCurve2, line)
+ temp1X, temp1Y = temp2X, temp2Y
+ i = i + 1
+ end
+
+ -- get the minimal distance of the 2 curve approximations
+ local minDistance = math.huge
+ for _, line1 in pairs(sectionsCurve1) do
+ for _, line2 in pairs(sectionsCurve2) do
+ local distance = getDistance(line1, line2)
+ if distance <= minDistance then
+ minDistance = distance
+ end
+ end
+ end
+
+ return minDistance
+end
+local function computeRepulsiveControlPointForces()
+ for k1, l1 in pairs(notesForPage) do
+ for k2, l2 in pairs(notesForPage) do
+ if k1 ~= k2 then
+ -- curves of the leaders
+ local curve1 = constructCurve(l1)
+ local curve2 = constructCurve(l2)
+
+ local distance = checkCurveApproximation(curve1, curve2);
+
+ -- check if R1 has to be increased or decreased to increase the distance of the 2 curves
+ -- if curve1 is bent into the direction of curve2, R1 has to be decreased
+ local actualR = math.abs(labelArea:getXTextSide(l1.rightSide) - l1.movableControlPointX)
+ if ((l1.inputY < l1.leaderArmY and
+ l2.leaderArmY < l1.leaderArmY) or
+ (l1.inputY > l1.leaderArmY and
+ l2.leaderArmY > l1.leaderArmY)) then
+ -- R1 has to be increased
+ local desiredR = math.abs(labelArea:getXTextSide(l1.rightSide) - l1.optimalPositionX)
+ local diff = math.abs(desiredR - actualR)
+ if distance == 0 then
+ distance = 0.01
+ end
+ local force = diff / distance
+ local newForce = force * factorRepulsiveControlPoint
+ l1.currentForce = l1.currentForce + newForce
+ l1.forceLimitDec = math.min(l1.forceLimitDec, distance * 0.45)
+ else
+ -- R1 has to be decreased
+ if distance == 0 then
+ distance = 0.01
+ end
+ local force = actualR / distance
+ local newForce = -force * factorRepulsiveControlPoint
+ l1.currentForce = l1.currentForce + newForce
+ local oldLim = l1.forceLimitInc
+ l1.forceLimitInc = math.min(l1.forceLimitInc, distance * 0.45)
+ --if oldLim ~= l1.forceLimitInc then
+ --print(k1 .. ": Reduced forceLimitInc from " .. oldLim .. " to " .. l1.forceLimitInc .. " because of " .. k2 .. " (distance: " .. distance .. ")")
+ --end
+ end
+ end
+ end
+ end
+end
+local function computeAttractingControlPointForces()
+ for _, l in pairs(notesForPage) do
+ local desiredR = math.abs(labelArea:getXTextSide(l.rightSide) - l.optimalPositionX)
+ local actualR = math.abs(labelArea:getXTextSide(l.rightSide) - l.movableControlPointX)
+ local newForce = (desiredR - actualR) * factorAttractingControlPoint
+ l.currentForce = l.currentForce + newForce
+ end
+end
+local function applyForces(v)
+ --print("force on note " .. v.index .. ": " .. v.currentForce .. " (limit: +" .. v.forceLimitInc .. ", -" .. v.forceLimitDec .. ")")
+
+ -- limit the force so the movable control point is between the port and the optimal position
+ local actualR = math.abs(labelArea:getXTextSide(v.rightSide) - v.movableControlPointX)
+ local differenceR = math.abs(labelArea:getXTextSide(v.rightSide) - v.optimalPositionX) - actualR
+ if (v.currentForce < 0 and math.abs(v.currentForce) > actualR) then
+ v.currentForce = (-1) * actualR
+ end
+ if (v.currentForce > 0 and v.currentForce > differenceR) then
+ v.currentForce = differenceR
+ end
+
+ -- limit the force so 2 curves do not get too close to each other and do not cross
+ if v.currentForce > v.forceLimitInc then
+ v.currentForce = v.forceLimitInc
+ end
+ if v.currentForce < (-1) * v.forceLimitDec then
+ v.currentForce = (-1) * v.forceLimitDec
+ end
+ v.forceLimitDec = math.huge
+ v.forceLimitInc = math.huge
+
+ if v.rightSide then
+ v.movableControlPointX = v.movableControlPointX - v.currentForce
+ else
+ v.movableControlPointX = v.movableControlPointX + v.currentForce
+ end
+
+ --print("force on note " .. v.index .. ": " .. v.currentForce)
+ local c = v.currentForce
+ v.currentForce = 0
+ return c
+end
+local function getAngle(centerX, centerY, x, y)
+ local vectorX = x - centerX
+ local vectorY = y - centerY
+ local length = math.sqrt((vectorX ^ 2) + (vectorY ^ 2))
+
+ vectorX = vectorX / length
+ vectorY = vectorY / length
+
+ local radAngle = math.acos(vectorX)
+ local degAngle = (radAngle * 180) / math.pi
+
+ if vectorY < 0 then
+ degAngle = 360 - degAngle
+ end
+
+ return degAngle
+end
+local function solveQuadraticEquation(a, b, c)
+ local discr = (b * b) - (4 * a * c)
+
+ if discr < 0 then
+ error("Fehler bei der Berechnung das optimalen Punktes")
+ end
+
+ local solution1 = ((-b) + math.sqrt(discr)) / (2 * a)
+ local solution2 = ((-b) - math.sqrt(discr)) / (2 * a)
+
+ if solution1 < 0 and solution2 < 0 then
+ error("no positive solution")
+ end
+
+ if solution1 < solution2 then
+ return solution2
+ else
+ return solution1
+ end
+end
+local function computeOptimalPosition(v)
+ local distance = point.distance(v.inputX, v.inputY, labelArea:getXTextSide(v.rightSide), v.leaderArmY)
+
+ -- the angle at the port between the point and the movable control point
+ local tempAngle = getAngle(v.inputX, v.inputY, labelArea:getXTextSide(v.rightSide), v.leaderArmY)
+
+ local gamma
+ if v.rightSide then
+ if tempAngle < 180 then
+ gamma = tempAngle
+ else
+ gamma = 360 - tempAngle
+ end
+ else
+ if tempAngle < 180 then
+ gamma = 180 - tempAngle
+ else
+ gamma = tempAngle - 180
+ end
+ end
+
+ -- a quadratic formula has to be solved to get the optimal position
+ local a = 3
+ local b = 2 * distance * math.cos(math.rad(gamma))
+ local c = -(distance * distance)
+
+ local r = solveQuadraticEquation(a, b, c)
+
+ if v.rightSide then
+ v.optimalPositionX = labelArea:getXTextSide(v.rightSide) - r
+ else
+ v.optimalPositionX = labelArea:getXTextSide(v.rightSide) + r
+ end
+end
+local function drawSBezierLeaders()
+ for _, v in pairs(notesForPage) do
+ -- initialise leader
+ v.leaderArmY = v:getLabelAnchorY()
+ v.movableControlPointX = labelArea:getXTextSide(v.rightSide)
+ v.currentForce = 0
+ v.forceLimitDec = math.huge
+ v.forceLimitInc = math.huge
+ end
+
+ luatodonotes.numberOfCurvePartitions = #notesForPage * 3
+
+ for _, v in pairs(notesForPage) do
+ computeOptimalPosition(v)
+ end
+
+ -- main loop
+ local proceed = true
+ local loopCounter = 0
+ while (proceed and loopCounter < maxIterations) do
+ if todonotesDebug then
+ print("Iteration " .. loopCounter)
+ end
+
+ -- compute forces
+ computeRepulsiveControlPointForces()
+ computeAttractingControlPointForces()
+
+ -- apply forces
+ proceed = false
+ for _, l in pairs(notesForPage) do
+ local diff = applyForces(l)
+ if diff > stopCondition then
+ proceed = true
+ end
+ end
+
+ loopCounter = loopCounter + 1
+ end
+
+ if todonotesDebug then
+ print("End of Force-directed algo, number of iterations: " .. loopCounter)
+ end
+
+ -- draw
+ for _, v in pairs(notesForPage) do
+ local curve = constructCurve(v)
+ local unmovableStr = "(" .. curve[2].x .. "sp," .. curve[2].y .. "sp)"
+ local movableStr = "(" .. curve[3].x .. "sp," .. curve[3].y .. "sp)"
+ drawLeaderPath(v, v:getLabelAnchorTikz() .. " .. controls " ..
+ movableStr .. " and " .. unmovableStr .. " .. " ..
+ v:getInTextAnchorTikz())
+
+ -- draw control points when requested
+ if todonotesDebug then
+ local optimalStr = "(" .. v.optimalPositionX .. "sp," .. v.leaderArmY .. "sp)"
+ tex.print("\\node[anchor=north west,text=pink,fill=white,rectangle] at " .. optimalStr .. " {" .. v.index .. "};")
+ tex.print("\\node[anchor=north west,text=red,fill=white,rectangle] at " .. movableStr .. " {" .. v.index .. "};")
+ tex.print("\\node[anchor=north west,text=orange,fill=white,rectangle] at " .. unmovableStr .. " {" .. v.index .. "};")
+ tex.print("\\draw[red,fill] " .. movableStr .. " circle(2pt);")
+ tex.print("\\draw[orange,fill] " .. unmovableStr .. " circle(2pt);")
+ tex.print("\\draw[pink,fill] " .. optimalStr .. " circle(1pt);")
+ end
+ end
+end
+leaderTypes["sBezier"] = {algo = drawSBezierLeaders}
+
+
+
+
+
+-- ********** Positioning Algorithms **********
+
+-- ** helper functions
+
+-- finds the index in the list given as parameter with the minimum angle
+-- the function used for computation of the angle is given as second parameter
+-- (the alphaFormula gets the note, to which the angle should be computed, as
+-- the only parameter)
+local function findIndexMinAlpha(availableNotesIndex, alphaFormula)
+ local minAlpha = math.huge -- infinity
+ local minIndex = -1
+
+ for k, v in pairs(availableNotesIndex) do
+ local alpha = alphaFormula(notesForPage[v])
+ if alpha < minAlpha then
+ minAlpha = alpha
+ minIndex = k
+ end
+ end
+
+ return minIndex
+end
+
+
+
+-- ** partition into stacks
+local function getMeanYHeight(stack)
+ -- TODO: Alternative: nicht das arithmetische Mittel verwenden, sondern
+ -- Mittelpunkt zwischen dem obersten und untersten Punkt
+ local sumY = 0
+ local height = 0
+ for _, v in pairs(stack) do
+ sumY = sumY + notesForPage[v].inputY
+ height = height + notesForPage[v]:getHeight() + 2 * noteInnerSep + noteInterSpace
+ end
+
+ local area = labelArea:getArea(notesForPage[stack[1]].rightSide)
+
+ local meanY = sumY / #stack
+ local height = height - noteInterSpace
+ if meanY + (height/2) > area.top then
+ meanY = area.top - (height/2)
+ elseif meanY - (height/2) < area.bottom then
+ meanY = area.bottom + (height/2)
+ end
+ return meanY, height
+end
+local function stacksIntersect(stackTop, stackBottom)
+ local topMeanY, topHeight = getMeanYHeight(stackTop)
+ local topLower = topMeanY - topHeight/2
+
+ local bottomMeanY, bottomHeight = getMeanYHeight(stackBottom)
+ local bottomUpper = bottomMeanY + bottomHeight/2
+
+ if topLower - bottomUpper < noteInterSpace then
+ return true
+ else
+ return false
+ end
+end
+local function findStacks(notesOnSide)
+ local notes = table.copy(notesOnSide)
+ table.sort(notes, compareNoteIndInputYDesc)
+
+ -- list that contains stacks
+ -- is initialized by putting all notes as single stacks ordered by their inputY
+ local stacks = {}
+ for _, v in pairs(notes) do
+ table.insert(stacks, {v})
+ end
+
+ -- Collapse Stacks where needed
+ local i = 1
+ while i <= #stacks - 1 do
+ if stacksIntersect(stacks[i], stacks[i+1]) then
+ collapsedStacks = true
+ for _, v in pairs(stacks[i+1]) do
+ table.insert(stacks[i], v)
+ end
+ table.remove(stacks,i+1)
+ if i > 1 then
+ -- as stack i has increased in size we look at the previous
+ -- stack again in next iteration
+ i = i - 1
+ end
+ else
+ -- look at next stack in next iteration
+ i = i + 1
+ end
+ end
+
+ return stacks
+end
+
+
+-- ** positioning: inText
+local function posInText()
+ -- trivial algorithm
+ -- places notes in text on position where todo-command was issued
+ for k, v in ipairs(notesForPage) do
+ v.outputX = v.inputX
+ v.outputY = v.inputY
+ end
+end
+positioningAlgos["inText"] = {algo = posInText,
+ leaderAnchor = "north west",
+ leaderShift = false,
+ twoSided = false}
+
+
+
+-- ** positioning: inputOrderStacks
+local function placeNotesInputOrder(stack, yStart, rightSide)
+ local freeY = yStart
+
+ for _, k in ipairs(stack) do
+ local v = notesForPage[k]
+ v.outputX = labelArea:getArea(rightSide).left
+ v.outputY = freeY
+ freeY = freeY - v:getHeight() - 2 * noteInnerSep - noteInterSpace
+ end
+end
+local function posInputOrderStacks(notesOnSide, rightSide)
+ table.sort(notesOnSide, compareNoteIndInputYDesc)
+
+ local stacks = findStacks(notesOnSide)
+
+ -- place stacks
+ for k, stack in pairs(stacks) do
+ local meanY, height = getMeanYHeight(stack)
+ local stackStart = meanY + height / 2
+ placeNotesInputOrder(stack, stackStart, rightSide)
+ end
+end
+positioningAlgos["inputOrderStacks"] = {algo = posInputOrderStacks,
+ leaderAnchor = "east",
+ leaderShift = false,
+ twoSided = true}
+
+
+
+-- ** positioning: inputOrder
+-- start at top and place notes below each other on left/right side
+-- notes are placed in the order induced by their y-coordinates
+local function posInputOrder(notes, rightSide)
+ table.sort(notes, compareNoteIndInputYDesc)
+ placeNotesInputOrder(notes, labelArea:getArea(rightSide).top, rightSide)
+end
+positioningAlgos["inputOrder"] = {algo = posInputOrder,
+ leaderAnchor = "east",
+ leaderShift = false,
+ twoSided = true}
+
+
+
+-- ** positioning: sLeaderNorthEast
+local function posSLeaderNorthEast(notes, rightSide)
+ local noteY = labelArea:getArea(rightSide).top
+
+ local alphaFormula
+ local noteX = labelArea:getXTextSide(rightSide)
+ local outputX = labelArea:getArea(rightSide).left
+ if rightSide then
+ alphaFormula = function (note)
+ return (noteY - note.inputY) / (noteX - note.inputX)
+ end
+ else
+ alphaFormula = function (note)
+ return (noteY - note.inputY) / (note.inputX - noteX)
+ end
+ end
+
+ while #notes > 0 do
+ local minIndex = findIndexMinAlpha(notes, alphaFormula)
+
+ -- place note identified by minIndex
+ local note = notesForPage[notes[minIndex]]
+ note.outputX = outputX
+ note.outputY = noteY
+ noteY = noteY - note:getHeight() - 2 * noteInnerSep - noteInterSpace
+
+ table.remove(notes, minIndex)
+ end
+end
+positioningAlgos["sLeaderNorthEast"] = {algo = posSLeaderNorthEast,
+ leaderAnchor = "north east",
+ leaderShift = false,
+ twoSided = true}
+
+
+
+-- ** positioning: sLeaderNorthEastBelow
+local function placeNotesNorthEastBelow(stack, yStart, rightSide)
+ -- calculate minimum height of all notes
+ local minHeight = math.huge -- (infinity)
+ for _, v in pairs(stack) do
+ if notesForPage[v]:getHeight() < minHeight then
+ minHeight = notesForPage[v]:getHeight()
+ end
+ end
+ local leaderShiftY = (- minHeight - 2 * noteInnerSep) / 2
+
+ local noteY = yStart
+ local availableNotes = table.copy(stack)
+
+ local alphaFormula
+ local noteX = labelArea:getXTextSide(rightSide)
+ local outputX = labelArea:getArea(rightSide).left
+ if rightSide == true then
+ alphaFormula = function (note)
+ return ((noteY + leaderShiftY) - note.inputY) / (noteX - note.inputX)
+ end
+ else
+ alphaFormula = function (note)
+ return ((noteY + leaderShiftY) - note.inputY) / (note.inputX - noteX)
+ end
+ end
+ while #availableNotes > 0 do
+ local minIndex = findIndexMinAlpha(availableNotes, alphaFormula)
+
+ -- place note identified by minIndex
+ local note = notesForPage[availableNotes[minIndex]]
+ note.outputX = outputX
+ note.outputY = noteY
+ note.leaderShiftX = 0
+ note.leaderShiftY = leaderShiftY
+ noteY = noteY - note:getHeight() - 2 * noteInnerSep - noteInterSpace
+
+ table.remove(availableNotes, minIndex)
+ end
+end
+local function posSLeaderNorthEastBelow(notes, rightSide)
+ placeNotesNorthEastBelow(notes, labelArea:getArea(rightSide).top, rightSide)
+end
+positioningAlgos["sLeaderNorthEastBelow"] = {algo = posSLeaderNorthEastBelow,
+ leaderAnchor = "north east",
+ leaderShift = true,
+ twoSided = true}
+
+
+
+-- ** positioning: sLeaderNorthEastBelowStacks
+local function posSLeaderNorthEastBelowStacks(notesOnSide, rightSide)
+ local stacks = findStacks(notesOnSide)
+
+ -- place stacks
+ for k, stack in pairs(stacks) do
+ local meanY, height = getMeanYHeight(stack)
+ local stackStart = meanY + height / 2
+ placeNotesNorthEastBelow(stack, stackStart, rightSide)
+ end
+end
+positioningAlgos["sLeaderNorthEastBelowStacks"] = {algo = posSLeaderNorthEastBelowStacks,
+ leaderAnchor = "north east",
+ leaderShift = true,
+ twoSided = true}
+
+
+
+-- ** positioning: sLeaderEast
+local function posSLeaderEast(notes, rightSide)
+ local leaderPosY
+ local noteY = labelArea:getArea(rightSide).top
+
+ local alphaFormula
+ local noteX = labelArea:getXTextSide(rightSide)
+ local outputX = labelArea:getArea(rightSide).left
+ if rightSide == true then
+ alphaFormula = function (note)
+ return (leaderPosY - note.inputY) / (noteX - note.inputX)
+ end
+ else
+ alphaFormula = function (note)
+ return (leaderPosY - note.inputY) / (note.inputX - noteX)
+ end
+ end
+
+ local placedNotes = {}
+ while #notes > 0 do
+ -- build a array with all distinct heights of the notes
+ -- first create a set and then convert to sorted array
+ local heights = {}
+ for _, v in pairs(notes) do
+ heights[notesForPage[v]:getHeight()] = true
+ end
+ heights = table.keys(heights)
+ table.sort(heights)
+
+ local chosenIndex = -1
+ local chosenH = -1
+ for _, h in pairs(heights) do
+ if todonotesDebug then
+ print("testing height: " .. h)
+ end
+ leaderPosY = noteY - noteInnerSep - h/2
+
+ -- find point with highest angle
+ local minIndex = findIndexMinAlpha(notes, alphaFormula)
+
+ -- found a valid note
+ if notesForPage[notes[minIndex]]:getHeight() <= h then
+ chosenIndex = minIndex
+ chosenH = h
+ if todonotesDebug then
+ print("placed note " .. notesForPage[notes[chosenIndex]].index)
+ end
+ break
+ end
+ end
+
+ -- place note identified by chosenIndex
+ local note = notesForPage[notes[chosenIndex]]
+ note.outputX = outputX
+ -- let free space above note if needed (if chosenH ~= note:getHeight())
+ note.outputY = noteY - (chosenH - note:getHeight()) / 2
+ -- no extraordinary free space below note (even if chosenH ~= note:getHeight())
+ noteY = note.outputY - note:getHeight() - 2 * noteInnerSep - noteInterSpace
+ if todonotesDebug and chosenH ~= note:getHeight() then
+ print("Creating free space above note " .. note.index)
+ end
+
+ table.insert(placedNotes, notes[chosenIndex])
+ table.remove(notes, chosenIndex)
+ end
+
+ -- postprocessing: reduce spaces between notes where possible
+ for ind, noteNr in pairs(placedNotes) do
+ local note = notesForPage[noteNr]
+
+ local aimedPos
+ if ind == 1 then
+ aimedPos = labelArea:getArea(rightSide).top
+ else
+ local prevNote = notesForPage[placedNotes[ind-1]]
+ aimedPos = prevNote.outputY - prevNote:getHeight() - 2 * noteInnerSep - noteInterSpace
+ end
+
+ if todonotesDebug and aimedPos ~= note.outputY then
+ print("note " .. note.index .. " got moved:")
+ print("aimed: " .. aimedPos)
+ print("real: " .. note.outputY)
+ end
+
+ local aimedLeaderAnchorY = aimedPos - noteInnerSep - note:getHeight() / 2
+ local realLeaderAnchorY = note.outputY - noteInnerSep - note:getHeight() / 2
+ -- it holds: realLeaderAnchorY < aimedLeaderAnchorY (realLeaderAnchor is lower on page)
+
+ -- check if there are points in triangle (aimedLeaderAnchor, note.input, realLeaderAnchor)
+ -- we perform this check by calculating the angle of the points referred to note.input
+ local pointsInTriangle = false
+ local denom
+ if rightSide then
+ denom = noteX - note.inputX
+ else
+ denom = note.inputX - noteX
+ end
+ local aimedLeaderAnchorAngle = (aimedLeaderAnchorY - note.inputY) / denom
+ local realLeaderAnchorAngle = (realLeaderAnchorY - note.inputY) / denom
+ local minAngle = math.huge
+ local minAngleIndex = -1 -- takes index of lowest point in triangle
+ for otherInd, otherNote in pairs(notesForPage) do
+ if otherInd ~= noteNr and
+ ((not rightSide and otherNote.inputX < note.inputX) or
+ (rightSide and otherNote.inputX > note.inputX)) then
+ local otherNoteAngle
+ if rightSide then
+ otherNoteAngle = (otherNote.inputY - note.inputY) / (otherNote.inputX - note.inputX)
+ else
+ otherNoteAngle = (otherNote.inputY - note.inputY) / (note.inputX - otherNote.inputX)
+ end
+
+ if (realLeaderAnchorAngle < otherNoteAngle)
+ and (otherNoteAngle < aimedLeaderAnchorAngle) then
+ pointsInTriangle = true
+ if otherNoteAngle < minAngle then
+ minAngle = otherNoteAngle
+ minAngleIndex = otherInd
+ end
+ if todonotesDebug then
+ print(otherNote.index .. " is in triangle for " .. note.index)
+ end
+ end
+ end
+ end
+
+ if not pointsInTriangle then
+ -- no points in triangle
+ -- => we can move this note to aimedPos
+ note.outputY = aimedPos
+ else
+ -- move note upwards so that leader touches lowest point in triangle
+ -- new point for leader anchor is determined by the ray from note.input through the lowest point in triangle (otherNote.input)
+ -- TODO: force a certain distance between leader and other points (at the moment a leader can contain endpoints of other leaders)
+ local otherNote = notesForPage[minAngleIndex]
+ local aimedLeaderAnchorY = note.inputY - (note.inputY - otherNote.inputY) * (note.inputX - noteX) / (note.inputX - otherNote.inputX)
+ note.outputY = aimedLeaderAnchorY + noteInnerSep + note:getHeight() / 2
+ end
+ end
+end
+positioningAlgos["sLeaderEast"] = {algo = posSLeaderEast,
+ leaderAnchor = "east",
+ leaderShift = false,
+ twoSided = true}
+
+
+
+-- ** positioning: poLeaders
+local function getRasterAbsolute(rasterHeight, top, rasterIndex)
+ return top - (rasterIndex - 1) * rasterHeight
+end
+ -- distance between line and leader that algorithm tries to reach when there is
+ -- no neighbouring line
+local poMinDistLine = string.todimen("4pt")
+local function getPosAboveLine(linePositionsCurPage, lineInd)
+ local line = linePositionsCurPage[lineInd]
+ local posAbove
+ if linePositionsCurPage[lineInd - 1] ~= nil then
+ posAbove = (line[2] + linePositionsCurPage[lineInd - 1][3]) / 2
+ end
+ if posAbove == nil or posAbove - line[2] > poMinDistLine then
+ posAbove = line[2] + poMinDistLine
+ end
+ return posAbove
+end
+local function getPosBelowLine(linePositionsCurPage, lineInd)
+ local line = linePositionsCurPage[lineInd]
+ local posBelow
+ if linePositionsCurPage[lineInd + 1] ~= nil then
+ posBelow = (line[3] + (linePositionsCurPage[lineInd + 1][2])) / 2
+ end
+ if posBelow == nil or line[3] - posBelow > poMinDistLine then
+ posBelow = line[3] - poMinDistLine
+ end
+ return posBelow
+end
+local function posPoLeaders(notes, rightSide, avoidLines)
+ local linePositionsCurPage
+ if avoidLines then
+ linePositionsCurPage = linePositions[currentPage] or {}
+ end
+
+ -- number of slots on the whole page
+ local area = labelArea:getArea(rightSide)
+ local totalNumSlots = math.floor((area.top - area.bottom) / rasterHeight)
+
+ -- calculate number of raster slots for each note
+ for _, ind in pairs(notes) do
+ local v = notesForPage[ind]
+ local height = v:getHeight() + 2 * noteInnerSep + noteInterSpace
+ v.rasterSlots = math.ceil(height / rasterHeight)
+ end
+
+ -- sort notes by inputY
+ table.sort(notes, compareNoteIndInputYDesc)
+
+ -- draw slots
+ if todonotesDebug then
+ for i = 1,totalNumSlots+1 do
+ local pos = area.top - (i-1) * rasterHeight
+ tex.print("\\draw[blue,dashed] (0," .. pos .. "sp) -- +(21cm,0);")
+ end
+ end
+
+ -- initialise table opt for dynamic program
+ -- opt[topPoint, bottomPoint, topSlot, bottomSlot, numberLabeledSites]
+ -- opt[a][b][c][d][e] describes length-minimal placement of the labels for
+ -- sites from a to b in the raster slots c to d
+ -- the leftmost/rightmost e sites between a and b are selected until there
+ -- are no more free slots
+ local opt = {}
+ for a = 1, #notes do
+ opt[a] = {}
+ for b = a, #notes do
+ opt[a][b] = {}
+ -- TODO: needed label slots are restricted by points
+ -- only create tables for needed slots
+ for i = 1, totalNumSlots do
+ opt[a][b][i] = {}
+ for j = i, totalNumSlots do
+ if i == j then
+ opt[a][b][i][j] = {}
+ opt[a][b][i][j][0] = {}
+ opt[a][b][i][j][0].totalLength = 0
+ opt[a][b][i][j][0].positions = {}
+ opt[a][b][i][j][0].leaderShiftY = {}
+ end
+ end
+ end
+ end
+ end
+
+ -- constant use an partial solution without labeled points
+ local optEmpty = {}
+ optEmpty.totalLength = 0
+ optEmpty.positions = {}
+ optEmpty.leaderShiftY = {}
+
+ -- fill table opt for dynamic program
+ -- numberOfPoints is difference between topPoint and bottomPoint when computing opt
+ for numberOfPoints = 1, #notes do
+ for topPoint = 1, (#notes - numberOfPoints + 1) do
+ -- compute opt[topStrip][bottomStrip]
+ local bottomPoint = topPoint + numberOfPoints - 1
+
+ local pointsBetween = {}
+ for i = topPoint, bottomPoint do
+ table.insert(pointsBetween, notes[i])
+ end
+ if rightSide then
+ table.sort(pointsBetween, compareNoteIndInputXDesc)
+ else
+ table.sort(pointsBetween, compareNoteIndInputXAsc)
+ end
+
+ -- TODO: Einschränken, nicht alle Kombinationen von Slots notwendig
+ -- (siehe auch oben)
+ -- numberOfSlots is difference between topSlot and bottomSlot when computing opt
+ for numberOfSlots = 1, totalNumSlots do
+ for topSlot = 1, (totalNumSlots - numberOfSlots + 1) do
+ local bottomSlot = topSlot + numberOfSlots - 1
+
+ -- DEBUG
+ --print("computing opt[" .. topPoint .. "][" .. bottomPoint ..
+ --"][" .. topSlot .. "][" .. bottomSlot .. "]")
+
+ opt[topPoint][bottomPoint][topSlot][bottomSlot] = {}
+ opt[topPoint][bottomPoint][topSlot][bottomSlot][0] = {}
+ opt[topPoint][bottomPoint][topSlot][bottomSlot][0].totalLength = 0
+ opt[topPoint][bottomPoint][topSlot][bottomSlot][0].positions = {}
+ opt[topPoint][bottomPoint][topSlot][bottomSlot][0].leaderShiftY = {}
+
+ -- stelle fest, wie viele Punkte gelabelt werden (bestimme also r)
+ local labeledSites = {}
+ local usedSlots = 0
+ for _, v in pairs(pointsBetween) do
+ local note = notesForPage[v]
+ if usedSlots + note.rasterSlots <= numberOfSlots then
+ usedSlots = usedSlots + note.rasterSlots
+ table.insert(labeledSites, v)
+ else
+ break
+ end
+ end
+
+ -- TODO: Teste, ob bei kleinerer Anzahl an Slots gleiche Punkte gelabelt werden
+ -- -> dann kann Teillösung übernommen werden
+
+ -- Mögliche Aufteilungen (Positionierung des Labels für r) testen
+ -- und Optimum auswählen
+ if #labeledSites > 0 then
+ for numLabeledSites = 1, #labeledSites do
+ -- we place rightmost point: labeledSites[#labeledSites]
+ local rIndex = labeledSites[numLabeledSites]
+ local r = notesForPage[rIndex]
+
+ -- slotIndexR is the slot in that the label for r begins (topmost slot)
+ local bestVal = math.huge
+ local bestOpt = {}
+ -- try all label positions for r (leader should enter the label at east-anchor)
+ for slotIndexR = topSlot, (bottomSlot + 1 - r.rasterSlots) do
+ -- calculate position in which leader arm is placed
+ local labelTopR = getRasterAbsolute(rasterHeight, area.top, slotIndexR)
+ local leaderArmR, leaderShiftR
+ if avoidLines then
+ leaderArmR = labelTopR - noteInnerSep - r:getHeight() / 2 -- east anchor
+
+ -- find first line (from the top) which lower bound is below leaderArmR
+ local lineBelowInd
+ for ind, v in pairs(linePositionsCurPage) do
+ if v[3] <= leaderArmR then
+ lineBelowInd = ind
+ break
+ end
+ end
+
+ -- choose the desired position for the leader arm
+ -- (later we check if the label is high enough to shift the port to this position)
+ local desiredPos = leaderArmR
+ if lineBelowInd == nil then
+ -- there is no line below the leaderArmR
+ local lowestLine = linePositionsCurPage[#linePositionsCurPage]
+ if lowestLine ~= nil and lowestLine[3] - leaderArmR < poMinDistLine then
+ -- leader is too near to lowest line on page
+ -- -> use the valid position below this line
+ desiredPos = getPosBelowLine(linePositionsCurPage, #linePositionsCurPage)
+ end
+ else
+ local lineBelow = linePositionsCurPage[lineBelowInd]
+ local lineAbove = linePositionsCurPage[lineBelowInd - 1]
+ if lineBelow ~= nil and leaderArmR - lineBelow[2] < poMinDistLine then
+ -- leader is too near (or conflicting) to the line below
+ -- -> move below or above this line (using the position closer to the original one)
+
+ local posAbove = getPosAboveLine(linePositionsCurPage, lineBelowInd)
+ local posBelow = getPosBelowLine(linePositionsCurPage, lineBelowInd)
+
+ -- chose position which is closer to east anchor
+ if posAbove - leaderArmR <= leaderArmR - posBelow then
+ desiredPos = posAbove
+ else
+ desiredPos = posBelow
+ end
+ elseif lineAbove ~= nil and lineAbove[3] - leaderArmR < poMinDistLine then
+ -- leader is too near to the line below
+ -- -> use the valid position above this line
+ desiredPos = getPosAboveLine(linePositionsCurPage, lineBelowInd)
+ end
+ end
+
+ -- check if label is high enough to move leader to desired position
+ if math.abs(desiredPos - leaderArmR) <= r:getHeight() / 2 + noteInnerSep then
+ leaderShiftR = desiredPos - leaderArmR
+ leaderArmR = desiredPos
+ else
+ leaderShiftR = 0
+ end
+ else
+ leaderArmR = labelTopR - noteInnerSep - r:getHeight() / 2
+ end
+
+ -- determine index of last point above arm
+ local pointAboveArm = 0
+ for k, ind in pairs(notes) do
+ v = notesForPage[ind]
+ if v.inputY >= leaderArmR then
+ pointAboveArm = k
+ else
+ break
+ end
+ end
+ local numPointsAbove = 0
+ local numPointsBelow = 0
+ for _, v in pairs(pointsBetween) do
+ if v == rIndex then
+ break
+ end
+
+ local note = notesForPage[v]
+ if note.inputY >= leaderArmR then
+ numPointsAbove = numPointsAbove + 1
+ else
+ numPointsBelow = numPointsBelow + 1
+ end
+ end
+
+ local optAbove, optBelow
+ if pointAboveArm < topPoint then
+ optAbove = optEmpty
+ elseif slotIndexR - 1 < topSlot then
+ optAbove = optEmpty
+ elseif pointAboveArm > bottomPoint then
+ optAbove = opt[topPoint][bottomPoint][topSlot][slotIndexR - 1][numPointsAbove]
+ else
+ optAbove = opt[topPoint][pointAboveArm][topSlot][slotIndexR - 1][numPointsAbove]
+ end
+ if pointAboveArm + 1 > bottomPoint then
+ optBelow = optEmpty
+ elseif slotIndexR + r.rasterSlots > bottomSlot then
+ optBelow = optEmpty
+ elseif pointAboveArm + 1 < topPoint then
+ optBelow = opt[topPoint][bottomPoint][slotIndexR + r.rasterSlots][bottomSlot][numPointsBelow]
+ else
+ optBelow = opt[pointAboveArm + 1][bottomPoint][slotIndexR + r.rasterSlots][bottomSlot][numPointsBelow]
+ end
+
+ local partitionValid = true
+ if optAbove == nil or optBelow == nil then
+ partitionValid = false
+ else
+ local labeledAboveArm = table.keys(optAbove.positions)
+ local labeledBelowArm = table.keys(optBelow.positions)
+ if #labeledAboveArm + #labeledBelowArm + 1 ~= numLabeledSites then
+ partitionValid = false
+ else
+ -- test if all of labeledNotes are in one of the sets
+ -- last element (= r) must not be tested
+ for testIndex = 1, (numLabeledSites - 1) do
+ if not table.contains(labeledAboveArm, labeledSites[testIndex])
+ and not table.contains(labeledBelowArm, labeledSites[testIndex]) then
+ partitionValid = false
+ end
+ end
+ end
+ end
+
+ if partitionValid then
+ local newVal = math.abs(r.inputY - leaderArmR) + optAbove.totalLength + optBelow.totalLength
+ if newVal < bestVal then
+ bestVal = newVal
+ bestOpt = {}
+ bestOpt.totalLength = newVal
+ bestOpt.positions = {}
+ for k, v in pairs(optAbove.positions) do
+ bestOpt.positions[k] = v
+ end
+ for k, v in pairs(optBelow.positions) do
+ bestOpt.positions[k] = v
+ end
+ -- DEBUG
+ if bestOpt.positions[rIndex] ~= nil then
+ error("WARNING: Overwriting position of " .. rIndex .. " from " .. bestOpt.positions[rIndex] .. " to " .. slotIndexR)
+ end
+ bestOpt.positions[rIndex] = slotIndexR
+ bestOpt.leaderShiftY = {}
+ if avoidLines then
+ for k, v in pairs(optAbove.leaderShiftY) do
+ bestOpt.leaderShiftY[k] = v
+ end
+ for k, v in pairs(optBelow.leaderShiftY) do
+ bestOpt.leaderShiftY[k] = v
+ end
+ bestOpt.leaderShiftY[rIndex] = leaderShiftR
+ end
+ end
+ end
+ end
+ if next(bestOpt) ~= nil then -- bestOpt is not an empty table
+ --print("setting opt[" .. topPoint .. "][" .. bottomPoint ..
+ --"][" .. topSlot .. "][" .. bottomSlot .. "][" .. numLabeledSites .. "] = " .. inspect(bestOpt))
+ opt[topPoint][bottomPoint][topSlot][bottomSlot][numLabeledSites] = bestOpt
+ else
+ --print ("WARNING: Found no valid position for label in opt[" .. topPoint .. "][" .. bottomPoint ..
+ --"][" .. topSlot .. "][" .. bottomSlot .. "][" .. numLabeledSites .. "] = " .. inspect(bestOpt))
+ opt[topPoint][bottomPoint][topSlot][bottomSlot][numLabeledSites] = nil
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ if #notes > 0 then
+ --DEBUG
+ local maxPlaced = 0
+ for i = 1,#notes do
+ if opt[1][#notes][1][totalNumSlots][i] ~= nil then
+ maxPlaced = i
+ end
+ end
+
+ if maxPlaced < #notes then
+ print("WARNING: could not fit all labels on page")
+ end
+
+ local res = opt[1][#notes][1][totalNumSlots][maxPlaced]
+ local positions = res.positions
+ local leaderShiftY = res.leaderShiftY
+ if todonotesDebug then
+ local length = res.totalLength
+ -- in console
+ print("----------------")
+ print("po-leader algorithm: Using result: opt[1][" .. #notes ..
+ "][1][" .. totalNumSlots .. "][" .. maxPlaced .. "]")
+
+ print("resulting length: " .. length)
+ print("resulting positions:")
+ print(inspect(positions))
+ print("resulting leaderShifts:")
+ print(inspect(leaderShiftY))
+ print("----------------")
+
+ -- on page
+ tex.print("\\node[text=blue,fill=white,rectangle,align=center] at (10.5cm,-27cm) {" ..
+ "total length: " .. number.tocentimeters(length, "%s%s") .. "\\\\ " ..
+ "rasterHeight: " .. number.tocentimeters(rasterHeight, "%s%s") ..
+ "};")
+ end
+
+ for _, ind in pairs(notes) do
+ local v = notesForPage[ind]
+ v.outputX = area.left
+ v.leaderShiftX = 0
+ if positions[ind] == nil then
+ print("did not define a position for note " .. v.index)
+ v.outputY = 0
+ v.leaderShiftY = 0
+ else
+ v.outputY = getRasterAbsolute(rasterHeight, area.top, positions[ind])
+ if leaderShiftY[ind] ~= nil then
+ v.leaderShiftY = leaderShiftY[ind]
+ end
+ end
+ end
+ end
+end
+positioningAlgos["poLeaders"] = {algo = posPoLeaders,
+ leaderAnchor = "east",
+ leaderShift = false,
+ twoSided = true}
+
+local function posPoLeadersAvoid(notes, rightSide)
+ posPoLeaders(notes, rightSide, true)
+end
+positioningAlgos["poLeadersAvoidLines"] = {algo = posPoLeadersAvoid,
+ leaderAnchor = "east",
+ leaderShift = true,
+ twoSided = true,
+ needLinePositions = true}
+
+
+
+
+-- ********** Splitting Algorithms **********
+
+-- ** splittingAlgorithm: none
+-- place all notes on the wider side
+local function splitNone()
+ local rightSideSelected = false
+ if labelArea.left == nil and labelArea.right == nil then
+ error("Cannot place labels on any side of text (not enough space). " ..
+ "Consider using the additionalMargin option of the package to " ..
+ "extend the page margins " ..
+ "or minNoteWidth to decrease the minimum width required")
+ elseif labelArea.left == nil then
+ rightSideSelected = true
+ elseif labelArea.right ~= nil and
+ labelArea.right.noteWidth > labelArea.left.noteWidth then
+ rightSideSelected = true
+ end
+
+ for _, v in pairs(notesForPage) do
+ v.rightSide = rightSideSelected
+ end
+end
+splittingAlgos["none"] = {algo = splitNone}
+
+
+
+-- ** splittingAlgorithm: middle
+-- split on middle of page
+local function splitMiddle()
+ if labelArea:isOneSided() then
+ splitNone()
+ else
+ local splitLine = (labelArea.text.right + labelArea.text.left)/2
+ for _, v in pairs(notesForPage) do
+ if v.inputX <= splitLine then
+ v.rightSide = false
+ else
+ v.rightSide = true
+ end
+ end
+ end
+end
+splittingAlgos["middle"] = {algo = splitMiddle}
+
+
+
+-- ** splittingAlgorithm: median
+-- split at median (sites sorted by x-coordinate)
+local function splitMedian()
+ if labelArea:isOneSided() then
+ splitNone()
+ else
+ if #notesForPage == 0 then
+ return
+ end
+
+ -- list that contains notes sorted by their inputX-coordinate
+ local notesSorted = {}
+ for _, v in pairs(notesForPage) do
+ table.insert(notesSorted, v)
+ end
+ table.sort(notesSorted, compareNoteInputXAsc)
+
+ local maxIndLeft
+ if #notesSorted % 2 == 1 then
+ maxIndLeft = math.ceil(#notesSorted / 2)
+ else
+ maxIndLeft = #notesSorted / 2
+ end
+
+ for k, v in pairs(notesSorted) do
+ if k <= maxIndLeft then
+ v.rightSide = false
+ else
+ v.rightSide = true
+ end
+ end
+ end
+end
+splittingAlgos["median"] = {algo = splitMedian}
+
+
+
+-- ** splittingAlgorithm: weightedMedian
+-- split at weighted median (sites sorted by x-coordinate)
+-- sum of heights of labels on both sides are similiar to each other
+local function splitWeightedMedian()
+ if labelArea:isOneSided() then
+ splitNone()
+ else
+ if #notesForPage == 0 then
+ return
+ end
+
+ -- list that contains notes sorted by their inputX-coordinate
+ local notesSorted = {}
+ for _, v in pairs(notesForPage) do
+ table.insert(notesSorted, v)
+ end
+ table.sort(notesSorted, compareNoteInputXAsc)
+
+ local heightLeft = 0
+ local heightRight = 0
+ while #notesSorted > 0 do
+ if heightRight < heightLeft then
+ -- place next note on the right side
+ local note = notesSorted[#notesSorted]
+ note.rightSide = true
+ heightRight = heightRight + note:getHeight() + 2 * noteInnerSep + noteInterSpace
+ table.remove(notesSorted, #notesSorted)
+ else
+ -- place next note on the left side
+ local note = notesSorted[1]
+ note.rightSide = false
+ heightLeft = heightLeft + note:getHeight() + 2 * noteInnerSep + noteInterSpace
+ table.remove(notesSorted, 1)
+ end
+ end
+ end
+end
+splittingAlgos["weightedMedian"] = {algo = splitWeightedMedian}
+
diff --git a/macros/luatex/latex/luatodonotes/luatodonotes.pdf b/macros/luatex/latex/luatodonotes/luatodonotes.pdf
new file mode 100644
index 0000000000..3235a373c2
--- /dev/null
+++ b/macros/luatex/latex/luatodonotes/luatodonotes.pdf
Binary files differ
diff --git a/macros/luatex/latex/luatodonotes/path_line.lua b/macros/luatex/latex/luatodonotes/path_line.lua
new file mode 100644
index 0000000000..e365a36bf4
--- /dev/null
+++ b/macros/luatex/latex/luatodonotes/path_line.lua
@@ -0,0 +1,120 @@
+-- Taken from luapower.com (Public domain)
+--
+--math for 2D line segments defined as (x1, y1, x2, y2).
+
+local abs, min, max = math.abs, math.min, math.max
+
+local distance = require'path_point'.distance
+local distance2 = require'path_point'.distance2
+
+--evaluate a line at time t using linear interpolation.
+--the time between 0..1 covers the segment interval.
+local function point(t, x1, y1, x2, y2)
+ return x1 + t * (x2 - x1), y1 + t * (y2 - y1)
+end
+
+--length of line at time t.
+local function length(t, x1, y1, x2, y2)
+ return t * distance(x1, y1, x2, y2)
+end
+
+--bounding box of line in (x,y,w,h) form.
+local function bounding_box(x1, y1, x2, y2)
+ if x1 > x2 then x1, x2 = x2, x1 end
+ if y1 > y2 then y1, y2 = y2, y1 end
+ return x1, y1, x2-x1, y2-y1
+end
+
+--split line segment into two line segments at time t (t is capped between 0..1).
+local function split(t, x1, y1, x3, y3)
+ t = min(max(t,0),1)
+ local x2, y2 = point(t, x1, y1, x3, y3)
+ return
+ x1, y1, x2, y2, --first segment
+ x2, y2, x3, y3 --second segment
+end
+
+--intersect infinite line with its perpendicular from point (x, y); return the intersection point.
+local function point_line_intersection(x, y, x1, y1, x2, y2)
+ local dx = x2 - x1
+ local dy = y2 - y1
+ local k = dx^2 + dy^2
+ if k == 0 then return x1, y1 end --line has no length
+ local k = ((x - x1) * dy - (y - y1) * dx) / k
+ return x - k * dy, y + k * dx
+end
+
+--return shortest distance-squared from point (x0, y0) to line, plus the touch point, and the time in the line
+--where the touch point splits the line.
+local function hit(x0, y0, x1, y1, x2, y2)
+ local x, y = point_line_intersection(x0, y0, x1, y1, x2, y2)
+ local tx = x2 == x1 and 0 or (x - x1) / (x2 - x1)
+ local ty = y2 == y1 and 0 or (y - y1) / (y2 - y1)
+ if tx < 0 or ty < 0 then --intersection occurs outside the segment, closer to the first endpoint
+ return distance2(x0, y0, x1, y1), x1, y1, 0
+ elseif tx > 1 or ty > 1 then --intersection occurs outside the segment, closer to the second endpoint
+ return distance2(x0, y0, x2, y2), x2, y2, 1
+ end
+ return distance2(x0, y0, x, y), x, y, max(tx, ty)
+end
+
+--intersect line segment (x1, y1, x2, y2) with line segment (x3, y3, x4, y4).
+--returns the time on the first line and the time on the second line where intersection occurs.
+--if the intersection occurs outside the segments themselves, then t1 and t2 are outside the 0..1 range.
+--if the lines are parallel or coincidental then t1 and t2 are infinite.
+local function line_line_intersection(x1, y1, x2, y2, x3, y3, x4, y4)
+ local d = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
+ if d == 0 then return 1/0, 1/0 end --lines are parallel or coincidental
+ return
+ ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / d,
+ ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / d
+end
+
+--transform to a quad bezier that advances linearly i.e. the point on the line at t
+--best matches the point on the curve at t.
+local function to_bezier2(x1, y1, x2, y2)
+ return
+ x1, y1,
+ (x1 + x2) / 2,
+ (y1 + y2) / 2,
+ x2, y2
+end
+
+--transform to a cubic bezier that advances linearly i.e. the point on the line at t
+--best matches the point on the curve at t.
+local function to_bezier3(x1, y1, x2, y2)
+ return
+ x1, y1,
+ (2 * x1 + x2) / 3,
+ (2 * y1 + y2) / 3,
+ (x1 + 2 * x2) / 3,
+ (y1 + 2 * y2) / 3,
+ x2, y2
+end
+
+--parallel line segment at a distance on the right side of a segment.
+--use a negative distance for the left side, or reflect the returned points against their respective initial points
+local function offset(d, x1, y1, x2, y2)
+ local dx, dy = -(y2-y1), x2-x1 --normal vector of the same length as original segment
+ local k = d / distance(x1, y1, x2, y2) --normal vector scale factor
+ return --normal vector scaled and translated to (x1,y1) and (x2,y2)
+ x1 + dx * k, y1 + dy * k,
+ x2 + dx * k, y2 + dy * k
+end
+
+if not ... then require'path_line_demo' end
+
+return {
+ point_line_intersection = point_line_intersection,
+ line_line_intersection = line_line_intersection,
+ to_bezier2 = to_bezier2,
+ to_bezier3 = to_bezier3,
+ offset = offset,
+ --path API
+ bounding_box = bounding_box,
+ point = point,
+ length = length,
+ split = split,
+ hit = hit,
+}
+
diff --git a/macros/luatex/latex/luatodonotes/path_point.lua b/macros/luatex/latex/luatodonotes/path_point.lua
new file mode 100644
index 0000000000..1144e6de09
--- /dev/null
+++ b/macros/luatex/latex/luatodonotes/path_point.lua
@@ -0,0 +1,73 @@
+-- Taken from luapower.com (Public domain)
+
+--basic math for the cartesian plane.
+--angles are expressed in degrees, not radians.
+
+local sqrt, abs, min, max, sin, cos, radians, degrees, atan2 =
+ math.sqrt, math.abs, math.min, math.max, math.sin, math.cos, math.rad, math.deg, math.atan2
+
+--hypotenuse function: computes sqrt(a^2 + b^2) without underflow / overflow problems.
+local function hypot(a, b)
+ if a == 0 and b == 0 then return 0 end
+ a, b = abs(a), abs(b)
+ a, b = max(a,b), min(a,b)
+ return a * sqrt(1 + (b / a)^2)
+end
+
+--distance between two points. avoids underflow and overflow.
+local function distance(x1, y1, x2, y2)
+ return hypot(x2-x1, y2-y1)
+end
+
+--distance between two points squared.
+local function distance2(x1, y1, x2, y2)
+ return (x2-x1)^2 + (y2-y1)^2
+end
+
+--point at a specified angle on a circle.
+local function point_around(cx, cy, r, angle)
+ angle = radians(angle)
+ return
+ cx + cos(angle) * r,
+ cy + sin(angle) * r
+end
+
+--rotate point (x,y) around origin (cx,cy) by angle.
+local function rotate_point(x, y, cx, cy, angle)
+ if angle == 0 then return x, y end
+ angle = radians(angle)
+ x, y = x-cx, y-cy
+ local c, s = cos(angle), sin(angle)
+ return cx + x*c - y*s, cy + y*c + x*s
+end
+
+--angle between two points in -360..360 degree range.
+local function point_angle(x, y, cx, cy)
+ return degrees(atan2(y - cy, x - cx))
+end
+
+--reflect point through origin (i.e. rotate point 180deg around another point).
+local function reflect_point(x, y, cx, cy)
+ return 2 * cx - x, 2 * cy - y
+end
+
+--reflect point through origin at a specified distance.
+local function reflect_point_distance(x, y, cx, cy, length)
+ local d = distance(x, y, cx, cy)
+ if d == 0 then return cx, cy end
+ local scale = length / d
+ return
+ cx + (cx - x) * scale,
+ cy + (cy - y) * scale
+end
+
+return {
+ hypot = hypot,
+ distance = distance,
+ distance2 = distance2,
+ point_around = point_around,
+ rotate_point = rotate_point,
+ point_angle = point_angle,
+ reflect_point = reflect_point,
+ reflect_point_distance = reflect_point_distance,
+}
diff --git a/macros/luatex/latex/makecookbook/README.old b/macros/luatex/latex/makecookbook/README.old
new file mode 100644
index 0000000000..4e81ac4662
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/README.old
@@ -0,0 +1,109 @@
+VERSION
+
+This is the README file for the MAKECOOKBOOK bundle, version 0.85 dated
+2018-12-02.
+
+BRIEF DESCRIPTION
+
+The MAKECOOKBOOK bundle contains the files needed to create (using
+LuaTex) a nice quality family cookbook in a form ready to submit to a
+print-on-demand printer. Modifiable choices have been made regarding
+standard book features such as trim size, margins, headers/footers,
+chapter heading formatting, front matter (copyright page, table of
+contents, etc.) and back matter (recipe index). Commands and environments
+have been created to format the food stories and recipes. The user will
+need to: (1) supply their own food stories and recipes(!), and (2) select
+(install if necessary) the needed OpenType fonts as briefly discussed
+below and further described in the documentation. Please note that no new
+document class or package is included here. Rather, we provide a
+modifiable preamble and a small number of other files that, together,
+fully support creation of all of the internal pages of a cookbook (i.e.,
+everything except the cover art).
+
+COPYRIGHT AND LICENSE
+
+Copyright 2018 Terrence P. Murphy and Rosalie A. D’Amico
+
+This work may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (“LPPL”), either version 1.3c of this
+license or (at your option) any later version. The latest version of this
+license is at:
+
+ http://www.latex-project.org/lppl.txt
+
+This work is author-maintained and consists of the files listed in the
+FILES section of this README file.
+
+CHANGE HISTORY
+
+This is the initial version 0.85, dated 2018-12-02.
+
+MAINTENANCE
+
+Please report bugs or request features to Terrence P. Murphy:
+ latex@rd-tpm.com
+
+FILES
+
+This work consists of the following files:
+
+README this file
+makecookbook-doc.tex documentation file
+makecookbook-doc.pdf PDF of the above
+makecookbook.tex the “root” cookbook file
+makecookbook.pdf PDF of the cookbook
+cb-preamble.tex the preamble for the cookbook
+cb-lettrine.cfl config file for the lettrine package
+cb-idxstyle.ist config file for makeindex/imakeidx
+cb-frontmatter.tex the cookbook front matter
+cb-chapterA.tex a sample cookbook chapter
+cb-chapterB.tex a sample cookbook chapter
+cb-imageA.jpg a sample image (from mwe package)
+cb-imageB.jpg a sample image (from mwe package)
+
+FILE DIRECTORIES
+
+In the CTAN zip archive, the above files are organized into directories
+and subdirectories as follows:
+
+makecookbook/ The top level makecookbook package directory
+| README
+| makecookbook-doc.tex
+| makecookbook-doc.pdf
+|
+|--- mycookbook/
+ | makecookbook.tex
+ | makecookbook.pdf
+ | cb-preamble.tex
+ | cb-lettrine.cfl
+ | cb-idxstyle.ist
+ |
+ |--- tex/
+ | cb-frontmatter.tex
+ | cb-chapterA.tex
+ | cb-chapterB.tex
+ |
+ |--- img/
+ cb-imageA.jpg
+ cb-imageB.jpg
+
+As described in the documentation, the idea is that the mycookbook/
+directory will be the root directory of your cookbook project.
+All of your cookbook chapters will be held in mycookbook/tex/
+All of your cookbook images will be held in mycookbook/img/
+
+FONTS
+
+The MAKECOOKBOOK bundle assumes you have installed the three fonts
+listed below. (All are OpenType, including TrueType, and all are
+licensed under the SIL Open Font License, Version 1.1). To have a
+successful compile "out of the box", these fonts must be installed
+on your system:
+
+SERIF-------> EB Garamond (version from Google Fonts)
+SANS SERIF--> Lato (version from http://www.latofonts.com)
+SCRIPT------> Italianno (version from Google Fonts)
+
+As described in the documentation, you can easily replace those three
+fonts with your favorite serif, sans serif and script fonts, so long
+as your replacement fonts have certain required font features.
diff --git a/macros/luatex/latex/makecookbook/README.txt b/macros/luatex/latex/makecookbook/README.txt
new file mode 100644
index 0000000000..9f90046ac7
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/README.txt
@@ -0,0 +1,110 @@
+VERSION
+sdfsfsf
+
+This is the README file for the MAKECOOKBOOK bundle, version 0.85 dated
+2018-12-02.
+
+BRIEF DESCRIPTION
+
+The MAKECOOKBOOK bundle contains the files needed to create (using
+LuaTex) a nice quality family cookbook in a form ready to submit to a
+print-on-demand printer. Modifiable choices have been made regarding
+standard book features such as trim size, margins, headers/footers,
+chapter heading formatting, front matter (copyright page, table of
+contents, etc.) and back matter (recipe index). Commands and environments
+have been created to format the food stories and recipes. The user will
+need to: (1) supply their own food stories and recipes(!), and (2) select
+(install if necessary) the needed OpenType fonts as briefly discussed
+below and further described in the documentation. Please note that no new
+document class or package is included here. Rather, we provide a
+modifiable preamble and a small number of other files that, together,
+fully support creation of all of the internal pages of a cookbook (i.e.,
+everything except the cover art).
+
+COPYRIGHT AND LICENSE
+
+Copyright 2018 Terrence P. Murphy and Rosalie A. D'Amico
+
+This work may be distributed and/or modified under the conditions of the
+LaTeX Project Public License ("LPPL"), either version 1.3c of this
+license or (at your option) any later version. The latest version of this
+license is at:
+
+ http://www.latex-project.org/lppl.txt
+
+This work is author-maintained and consists of the files listed in the
+FILES section of this README file.
+
+CHANGE HISTORY
+
+This is the initial version 0.85, dated 2018-12-02.
+
+MAINTENANCE
+
+Please report bugs or request features to Terrence P. Murphy:
+ latex@rd-tpm.com
+
+FILES
+
+This work consists of the following files:
+
+README this file
+makecookbook-doc.tex documentation file
+makecookbook-doc.pdf PDF of the above
+makecookbook.tex the "root" cookbook file
+makecookbook.pdf PDF of the cookbook
+cb-preamble.tex the preamble for the cookbook
+cb-lettrine.cfl config file for the lettrine package
+cb-idxstyle.ist config file for makeindex/imakeidx
+cb-frontmatter.tex the cookbook front matter
+cb-chapterA.tex a sample cookbook chapter
+cb-chapterB.tex a sample cookbook chapter
+cb-imageA.jpg a sample image (from mwe package)
+cb-imageB.jpg a sample image (from mwe package)
+
+FILE DIRECTORIES
+
+In the CTAN zip archive, the above files are organized into directories
+and subdirectories as follows:
+
+makecookbook/ The top level makecookbook package directory
+| README
+| makecookbook-doc.tex
+| makecookbook-doc.pdf
+|
+|--- mycookbook/
+ | makecookbook.tex
+ | makecookbook.pdf
+ | cb-preamble.tex
+ | cb-lettrine.cfl
+ | cb-idxstyle.ist
+ |
+ |--- tex/
+ | cb-frontmatter.tex
+ | cb-chapterA.tex
+ | cb-chapterB.tex
+ |
+ |--- img/
+ cb-imageA.jpg
+ cb-imageB.jpg
+
+As described in the documentation, the idea is that the mycookbook/
+directory will be the root directory of your cookbook project.
+All of your cookbook chapters will be held in mycookbook/tex/
+All of your cookbook images will be held in mycookbook/img/
+
+FONTS
+
+The MAKECOOKBOOK bundle assumes you have installed the three fonts
+listed below. (All are OpenType, including TrueType, and all are
+licensed under the SIL Open Font License, Version 1.1). To have a
+successful compile "out of the box", these fonts must be installed
+on your system:
+
+SERIF-------> EB Garamond (version from Google Fonts)
+SANS SERIF--> Lato (version from http://www.latofonts.com)
+SCRIPT------> Italianno (version from Google Fonts)
+
+As described in the documentation, you can easily replace those three
+fonts with your favorite serif, sans serif and script fonts, so long
+as your replacement fonts have certain required font features.
diff --git a/macros/luatex/latex/makecookbook/makecookbook-doc.pdf b/macros/luatex/latex/makecookbook/makecookbook-doc.pdf
new file mode 100644
index 0000000000..aa5ba6225e
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/makecookbook-doc.pdf
Binary files differ
diff --git a/macros/luatex/latex/makecookbook/makecookbook-doc.tex b/macros/luatex/latex/makecookbook/makecookbook-doc.tex
new file mode 100644
index 0000000000..ad4906620e
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/makecookbook-doc.tex
@@ -0,0 +1,1819 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LICENSE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Copyright 2018 Terrence P. Murphy and Rosalie D'Amico.
+% This file may be distributed and/or modified under the conditions of the LaTeX Project
+% Public License (“LPPLâ€), either version 1.3c of this license or (at your option) any
+% later version. The latest version of this license is at:
+% http://www.latex-project.org/lppl.txt.
+% This file is author-maintained and is one of the files that, collectively, make up the
+% MAKECOOKBOOK bundle available at https://ctan.org/pkg/makecookbook
+% For additional information, please see the associated README file.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\documentclass[10pt]{article}
+\emergencystretch 3em
+\usepackage{enumitem,multicol,xcolor, textcomp, xparse, fancyvrb, array, graphicx}
+
+\usepackage{ifluatex, ifxetex}
+\ifluatex
+ \usepackage{fontspec}
+\else
+ \ifxetex
+ \usepackage{fontspec}
+ \else
+ \usepackage[T1]{fontenc}
+ \usepackage{lmodern}
+ \fi
+\fi
+
+\usepackage{geometry}
+\geometry{
+ inner=1.0in,
+ outer=1.0in,
+ top=0.75in,
+ bottom=1in,
+ nomarginpar,
+ footskip=40pt}
+
+\usepackage{titlesec}
+\titlespacing{\subsubsection}{15pt}{5pt}{5pt}
+
+\usepackage{chngcntr}
+%\counterwithin*{section}{part}
+
+\newcommand{\Cmd}[1]{\texttt{\textbackslash{}#1}}
+
+\NewDocumentCommand \latex{o}{\IfNoValueTF{#1}{\LaTeX{} }{\LaTeX{}#1}}%
+\NewDocumentCommand \tex{o}{\IfNoValueTF{#1}{\TeX{} }{\TeX{}#1}}%
+\NewDocumentCommand \pdftex{o}{\IfNoValueTF{#1}{pdfTeX }{pdfTeX#1}}%
+\NewDocumentCommand \luatex{o}{\IfNoValueTF{#1}{LuaTeX }{LuaTeX#1}}%
+\NewDocumentCommand \xetex{o}{\IfNoValueTF{#1}{XeTeX }{XeTeX#1}}%
+
+\NewDocumentCommand \pkg{m}{\texttt{#1}}
+\NewDocumentCommand \boldit{m} {\textbf{\textit{#1}}}
+
+\NewDocumentCommand \RedText{+m}{{{\color{red} #1}}}%
+\NewDocumentCommand \Quote{m}{``#1"}
+\NewDocumentCommand \NL{}{\par}
+
+\newsavebox{\HatBox}
+\AtBeginDocument{\savebox{\HatBox}[\hatwidth]{\MakeChefHat}}%
+\NewDocumentCommand \ChefHat {}{\usebox{\HatBox}}%
+\NewDocumentCommand \ChefNote {}{{\raisebox{.4ex}{\ChefHat}}}
+
+%\newcommand*{\fvtextcolor}[2]{\textcolor{#1}{#2}} % for Verbatim/fancyvrb -- see Q 23091
+\DefineVerbatimEnvironment{MyVerbatim}{Verbatim}{fontsize=\small, fontseries=b, xleftmargin=17pt}
+\DefineVerbatimEnvironment{MyVerbatimNums}{Verbatim}{fontsize=\small, fontseries=b, numbers=left, xleftmargin=17pt}
+
+\usepackage{xcolor}
+\definecolor{clrBackSideNote}{rgb}{1.0, 0.95, 0.95} % red!5!white
+\definecolor{clrFrameSideNote}{rgb}{0.75, 0.0, 0.0} % red!75!black
+\definecolor{clrBackTip}{rgb}{1.0, 0.95, 0.95} % red!5!white
+\definecolor{clrFrameTip}{rgb}{0.75, 0.0, 0.0} % red!75!black
+\definecolor{clrBackCheffy}{rgb}{1.0, 1.0, 1.0} % white
+\definecolor{clrFrameCheffy}{rgb}{0.0, 0.0, 0.75} % blue!75!black
+\definecolor{clrBackNotes}{rgb}{1.0, 1.0, 1.0} % white
+\definecolor{clrFrameNotes}{rgb}{0.0, 0.75, 0.0} % green!75!black
+\definecolor{clrHyperRef}{cmyk}{0.00, 1.00, 1.00, 0.00} % true red
+
+\usepackage{tcolorbox}
+\tcbset{fonttitle=\rmfamily\large\bfseries}
+
+\NewDocumentEnvironment{SideNote}{+m}
+{
+\begin{tcolorbox}[colback=clrBackSideNote,colframe=clrFrameSideNote, title=Side Note]
+ {#1}%
+\end{tcolorbox}
+}
+
+\NewDocumentEnvironment{Tip}{+m}
+{
+\begin{tcolorbox}[colback=clrBackTip,colframe=clrFrameTip, title=Food for Thought]
+ {#1}%
+\end{tcolorbox}
+}
+
+\NewDocumentEnvironment{Cheffy}{+m}
+{
+\begin{tcolorbox}[colback=clrBackCheffy,colframe=clrFrameCheffy, title=Let's Get Cheffy]
+ {#1}%
+\end{tcolorbox}
+}
+
+\NewDocumentEnvironment{ChefNotes}{+m}
+{
+\begin{tcolorbox}[colback=clrBackNotes,colframe=clrFrameNotes,title=Chefnotes]
+ \ChefNote{}{#1}%
+\end{tcolorbox}
+}
+
+\usepackage{xfrac}
+\def\fr#1/#2 {\sfrac{#1}{#2} }
+\def\frx#1/#2 {\sfrac{#1}{#2}}
+
+%************ TIKZ DRAWINGS ************************************************
+\usepackage{tikz}
+\usetikzlibrary{calc}
+
+\def\hatscale{0.05}
+\def\hatwidth{12.5pt}
+\NewDocumentCommand \MakeChefHat{}
+{
+ \begin{tikzpicture}[scale=\hatscale]
+ \coordinate (HA) at (1.27, 0.635);
+ \coordinate (HB) at (5.87375, 0);
+ \coordinate (HC) at (1.5825, 0.9475);
+ \coordinate (HD) at (5.77375, 0.15);
+ \coordinate (HE) at (1.5875,1.905);
+ \coordinate (HF) at (1.8,1.74625);
+ \coordinate (HG) at (6.0325, 1.27);
+ \coordinate (HH) at (6.22, 1.33);
+ \coordinate (HI) at (6.45, 2.18);
+ \coordinate (HJ) at (6.35, 2.70);
+ \coordinate (HK) at (8.5725, 3.97);
+ \coordinate (HL) at (6.03, 4.7625);
+ \coordinate (HM) at (6.03, 3.651);
+ \coordinate (HN) at (2.2225, 5.3975);
+ \coordinate (HO) at (0.159, 4.603);
+ \coordinate (HP) at (1.587, 3.55);
+ \coordinate (HQ) at (2.5, 4.7625);
+ \coordinate (HR) at (2.778, 2.08);
+ \coordinate (HS) at (2.7, 4.1275);
+ \coordinate (HT) at (4.0, 1.98);
+ \coordinate (HU) at (4.286, 3.4925);
+ \coordinate (HV) at (5.3, 1.7);
+ \coordinate (HW) at (5.55, 2.85);
+ \coordinate (HX) at (4.286, 5.0);
+ %
+ \path[fill=black] (HA) to [bend left=20] (HB) to (HD) to [bend right=20] (HC) to (HA);
+ \path[fill=black] (HA) to (HC) to (HF) to (HE) to (HA);
+ \path[fill=black] (HE) to (HF) to [bend left=20] (HG) to (HH) to [bend right=20] (HE);
+ \path[fill=black] (HB) to (HD) to (HG) to (HH) to (HB);
+ \path[fill=black] (HH) to (HI) to (HJ) to (HG);
+ \draw[line width=5*\hatscale] (HI) to [bend right=50] (HK);
+ \draw[line width=5*\hatscale] (HK) to [bend right=50] (HL);
+ \draw[line width=5*\hatscale] (HL) to [bend right=45] (HX);
+ \draw[line width=5*\hatscale] ($(HX) + (0.4, -.4)$) to [bend right=45] (HN);
+ \path[fill=black] (HM) to ($(HL) -(0.15, 0)$) to ($(HL) + (0.15, 0)$) to (HM);
+ \draw[line width=5*\hatscale] (HN) to [bend right=50] (HO);
+ \draw[line width=5*\hatscale] (HO) to [bend right=50] (HP);
+ \draw[line width=5*\hatscale] ($(HF) +(0, 0.15)$) to (HP);
+ \path[fill=black] (HQ) to ($(HN) -(0.15, 0)$) to ($(HN) + (0.15, 0)$) to (HQ);
+ \path[fill=black] (HS) to ($(HR) -(0.15, 0)$) to ($(HR) + (0.15, 0)$) to (HS);
+ \path[fill=black] (HU) to ($(HT) -(0.15, 0)$) to ($(HT) + (0.15, 0)$) to (HU);
+ \path[fill=black] (HW) to ($(HV) -(0.15, 0)$) to ($(HV) + (0.15, 0)$) to (HW);
+ \end{tikzpicture}
+}
+
+\usepackage[bookmarks=true,colorlinks=true, allcolors=clrHyperRef]{hyperref}
+\usepackage{bookmark}
+% the following must be run AFTER hyperref has changed \counterwithin
+\counterwithin*{section}{part}
+
+\pdfstringdefDisableCommands{% see Q 10555
+ \def\latex{LaTeX }%
+ \def\Quote#1{"#1"}%
+ \def\pkg#1{#1}%
+}
+
+% see Q 193380
+\NewDocumentCommand \MyLabel{o m}{\IfValueTF{#1}{\phantomsection}{} \label{#2}}
+
+
+\begin{document}
+
+\title{The \pkg{MakeCookbook} Bundle\NL Make a Cookbook Using \latex}
+\author{Terrence P. Murphy \and Rosalie A. D'Amico}
+\maketitle
+
+\tableofcontents
+\newpage
+\part{Introduction}
+
+\section{About}
+
+The \pkg{makecookbook} bundle contains the files needed to create a nice quality family cookbook in a form ready to submit to most print-on-demand companies. Modifiable choices have been made regarding standard book features such as trim size, margins, headers/footers, chapter heading formatting, front matter (copyright page, table of contents, etc.) and back matter (index). Commands and environments have been created to format the food stories and recipes. The user will need to: (1) supply their own food stories and recipes(!), and (2) select (install if necessary) the needed fonts.
+
+The design, layout and typography for cookbooks varies substantially, so we necessarily take a \Quote{point of view} on the desired look of the cookbook. However, even if your goal is a significantly different layout, you may find this work helpful in thinking through and implementing your design.
+
+Please note that no new document class or package is included here. Rather, we provide a modifiable preamble and a small number of other files that, together, fully support creation of all of the \textit{internal} pages of a cookbook (i.e., everything except the cover art). We may refer to the \pkg{makecookbook} \Quote{package} in this documentation -- by that we mean package in a broader sense and do \textit{not} mean an actual .sty style package.
+
+\section{Preliminaries}
+
+\subsection{Requirements}
+
+\subsubsection{Compiler}
+
+The \pkg{makecookbook} bundle uses the \pkg{fontspec} package. That means it must be compiled with either Lua\TeX{} or Xe\TeX. We have only tested with Lua\TeX . However, we have not used Lua code, so we expect you should be successful (after a possible tweak or two) with an Xe\TeX{} compile.
+
+\subsubsection{Fonts}\MyLabel{IntroFonts}
+
+The \pkg{makecookbook} bundle assumes you have installed the three fonts listed below. (All are licensed under the SIL Open Font License, Version 1.1). To have a successful compile \Quote{out of the box}, these fonts must be installed on your system:
+
+\begin{center}
+ \begin{tabular}{ >{\bfseries} l | >{\itshape}l | l | l }
+ \hline
+ Serif & EB Garamond & TrueType & Version from Google Fonts\\ \hline
+ Sans Serif & Lato & TrueType & Version from \pkg{www.latofonts.com} \\ \hline
+ Script & Italianno & OpenType & Version from Google Fonts\\
+ \hline
+ \end{tabular}
+\end{center}
+
+Please note: we assume that the \textit{EB Garamond} and \textit{Italianno} fonts were obtained from Google Fonts, and that the \textit{Lato} font was obtained from \pkg{http://www.latofonts.com}. These fonts \textit{do not} required installation of any font-related packgages other than \pkg{fontspec}.
+
+Beginning on page \pageref{Fonts}, we discuss how you can easily substitute your own favorite OpenType (including TrueType flavored) fonts, subject only to certain requirements regarding feature set.
+
+\subsection{License}
+
+Copyright \copyright{} 2018 Terrence P. Murphy and Rosalie A. D'Amico. This work may be distributed and/or modified under the conditions of the \latex Project Public License (“LPPLâ€), either version 1.3c of this license or (at your option) any later version. The latest version of this license is at:
+
+\quad \pkg{http://www.latex-project.org/lppl.txt}.
+
+\noindent This work is author-maintained and consists of the files listed in the FILES section of the README file.
+
+The \pkg{makecookbook} bundle includes an example cookbook with seven recipes. Those recipes are courtesy of Rosalie D'Amico\footnote{D'Amico, Rosalie A. \textit{Mama, How Do You Make...}. (self-published, 2018).}.
+You are, of course, welcome to try them! They are included in the bundle to provide real-world examples of using \latex code to enter recipes. We only ask that you consider those recipes as for you personal use and not (without attribution) for further food-related publication (further publication OK in a \latex context).
+
+\subsection{Contact Information / Feedback}
+
+No doubt, this documents contains typos, poorly explained (or unexplained) items, and other errors. It is equally likely the \pkg{makecookbook} package includes coding errors. We value your feedback. Please report problems or make other suggestions to Terry Murphy: \pkg{latex@rd-tpm.com}.
+
+\subsection{Version Information / Change History}
+
+Version 0.85 dated \date{\today}. This is the initial version of the \pkg{makecookbook} bundle.
+
+\subsection{The \latex Community / StackExchange}
+
+In this \pkg{makecookbook} package, much of the code (except for the mistakes!) is not original. When we ran into difficulties, we usually turned to \pkg{tex.stackexchange.com} for help. We often found solutions in previous questions and answers, but sometimes had to ask our own questions. The \latex community is amazingly generous with their time.
+
+You may see in the text or in the comments to the code something like \Quote{See Q 59619}. That is a reference to a specific question and answer on \pkg{tex.stackexchange.com}. You can often track it down by a Google search of \Quote{latex 59619}; if that doesn't work, try \Quote{tex.stackexchange.com 59619}.
+
+\section{Installing \pkg{makecookbook}}
+
+Go to the CTAN homepage of the \pkg{makecookbook} package: \pkg{https://ctan.org/pkg/makecookbook}. On that page you can download the complete zip file using the download button next to \Quote{\textit{Download the contents of this package in one zip archive}}. After unzipping, you will have the following files and directories:
+
+\begin{MyVerbatim}
+makecookbook/
+| README
+| makecookbook-doc.tex
+| makecookbook-doc.pdf
+|
+|--- mycookbook/
+ | makecookbook.tex
+ | makecookbook.pdf
+ | cb-preamble.tex
+ | cb-lettrine.cfl
+ | cb-idxstyle.ist
+ |
+ |--- tex/
+ | cb-frontmatter.tex
+ | cb-chapterA.tex
+ | cb-chapterB.tex
+ |
+ |--- img/
+ cb-imageA.jpg
+ cb-imageB.jpg
+\end{MyVerbatim}
+
+Copy the \pkg{mycookbook} directory (including all its subdirectories and files) to you \latex project area. Choose a location so that the \pkg{mycookbook} directory is the root directory of your cookbook project.
+
+Next, download and install\footnote{We are not experts on font installation. Because we load fonts by filename, our understanding is that you just need to follow the normal instructions of your operating system for installing a system font. That's all we did for our Windows 10 system. If you run into problems, first verify that the installed font is available for other non-\latex programs. Beyond that, check the \luatex documentation, check the \pkg{fontspec} documentation, or ask a question at \pkg{tex.stackexchage.com}.}
+the three required fonts. Get \textit{EB Garamond} and \textit{Italianno} from Google Fonts. Get \textit{Lato} from \pkg{http://www.latofonts.com/}. We highly recommend that you download the three fonts from those sources to ensure you have the same versions as we have used, with the same filenames.
+
+Once the fonts are installed, you will be able to build the initial version of your cookbook by doing a Lua\TeX{} compile (or two) of \pkg{makecookbook.tex}.
+
+If you decide to substitute you own fonts for any of the three fonts, you cannot compile until you modify \pkg{cb-preamble.tex} to associate your selected fonts with your cookbook project. Instructions on how to make the required modifications are given, beginning on page \pageref{Fonts}.
+
+\section{How This Document is Organized}
+
+Before we discuss the details of the \pkg{makecookbook} files and our \latex code, we first (in Parts II and III) look at the cookbook-writing project at a higher level:
+
+\begin{description}
+\item[Part II - Managing/Organizing Your Cookbook Files.] Keeping a book size project well organized is critical. We start by describing our approach to organizing the cookbook files.
+
+\item[Part III - Elements of a Book/Cookbook.] Next, we provide an \textit{overview} of the key elements that make up a cookbook. This include elements common to most any book (title page, table of contents, chapters, index, etc.), as well as elements particular to a cookbook (recipe names, ingredients, steps, etc.). All of the elements listed here will be discussed in detail further below.
+\end{description}
+
+Then, we dig deeper into the elements that make a book/cookbook:
+
+\begin{description}
+ \item[Part IV - Elements of a Book - the Details.] We list and discuss the key elements that are common to most books. We describe the choices we made regarding each element and, where appropriate, we describe how you can make a different choice for that element.
+
+ \item[Part V - Elements of a Book - the Details (Fonts).] Due to the length of this discussion, and due to the importance of font selection and usage, we break this topic out separately.
+
+ \item[Part VI - Elements of a Cookbook - the Details.] We list and discuss the elements that are particular to cookbooks. For each element, we describe the \latex commands and environments you will use to include that element in your cookbook, including any options that have been programmed into those commands and environments. Using the files provided and the information discussed here, you should have the tools to make a complete cookbook.
+
+ \item[Part VII - The PDF File.] We discuss the sometimes conflicting requirements for building a PDF file for a digital cookbook (with bookmarks and links) versus building a PDF file for submittal to a print-on-demand company.
+
+ \item[Part VIII - Examples.] We present and discuss several recipe examples. This allows you to see real world examples of the \latex commands and environments needed to make your cookbook.
+\end{description}
+
+\newpage
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\part{Managing/Organizing Your Cookbook Files}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Writing a cookbook is a large project. Early on, you should think through how you will manage your cookbook files. We describe below our fairly standard approach to organizing a book-size document in \latex[:]\footnote{See, e.g.: https://en.wikibooks.org/wiki/LaTeX/Modular\_Documents}
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item Create a directory devoted exclusively to the cookbook. We will call that directory the \textit{root directory} of the cookbook (in the files distributed with the \pkg{makecookbook} package, we call that directory \pkg{mycookbook}). All other directories used in the cookbook project will be referenced relative to the root directory. The root directory holds: (1) a one-page \pkg{makecookbook.tex} file that includes the instructions needed to pull all of the cookbook files together, (2) the \pkg{cb-preamble.tex} file that includes the \latex packages and programming code used by the cookbook, and (3) any special files needed by \pkg{cb-preamble.tex} (in our case, the \pkg{cb-lettrine.cfl} and \pkg{cb-idxstyle.ist} files).
+ \item Create two subdirectories under the root directory, one called \texttt{tex} and one called \texttt{img}. The \texttt{tex} directory holds a \pkg{.tex} file for each chapter of the cookbook (plus \pkg{cb-frontmatter.tex}). The \texttt{img} directory holds any image files used in the cookbook.
+\end{itemize}
+
+It is helpful to see the full contents of the \pkg{makecookbook.tex} file. This file brings in the preamble, the front matter and the cookbook chapters and handles a few other \Quote{housekeeping} items:
+
+\begin{MyVerbatim}
+\documentclass[11pt]{book}
+\input{cb-preamble}
+
+\begin{document}
+ \frontmatter
+ \include{./tex/cb-frontmatter}
+
+ \mainmatter
+ \include{./tex/cb-chapterA}
+ .
+ . (you include here all of the chapters of your cookbook)
+ .
+ \include{./tex/cb-chapterB}
+
+ \backmatter
+ \CookbookIndex{}
+\end{document}
+\end{MyVerbatim}
+
+\newpage
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\part{Elements of a Book/Cookbook}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Here we present an \textit{overview} of the elements that make up a book (in general), plus the special additional elements that make up a cookbook.
+
+An excellent source for the elements of a book is \textit{A Few Notes on Book Design} by Peter Wilson\footnote{https://ctan.org/pkg/memdesign}. Although the entire article is well worth reading, see in particular \textit{Chapter Two - The Parts of a Book}.
+
+\section{Elements of a Book}
+We list here some of the typical elements of a book. The first five are very basic elements:
+
+\begin{description}
+ \item[Trim Size] The physical size (height x width) of the paper used to print the book.
+ \item[Margins] In its simplest form, this is the top, bottom, inner and outer margins of the text area. Allowances must also be made for the areas where any header or footer is printed.
+ \item[Headers and Footers] This is where (above or below the text area) things like page number and current chapter name/number are printed.
+ \item[Chapter Title Formatting] The chapter name/number as printed on the first page of each new chapter.
+ \item[Fonts] Selection of fonts and choice of point size both play a fundamental role in all books.
+ \item[Odds and Ends] We will briefly consider a few other elements, such as color, drop caps and images.
+
+\end{description}
+
+Next we list the elements associated with the three traditional areas of a book: the front matter, the main matter and the back matter:
+
+\begin{description}
+ \item[Front Matter] This is the first part of the book, and includes an assortment of preliminary information. Typically, in this order, there is a title page, a copyright page, a dedication page, and a table of contents, all of which may be followed by one or more short chapters such as a preface or acknowledgments.
+ \item[Main Matter] This is the heart of the book. We follow the typical case where the main matter consists only of the chapters of the book.
+ \item[Back Matter] We follow the typical case where the back matter contains the book index. This is where you might include other ancillary information such as a bibliography, an appendix, notes, etc.
+\end{description}
+
+\section{Elements of a Cookbook}
+
+\begin{description}
+ \item[Chapter Intro] In a cookbook, chapters tend to be organized into logical units such as cookies, desserts, pasta, appetizers, etc. Following the chapter name, there will usually be some introductory text for that chapter. We call that the \textit{chapter intro}.
+ \item[Recipe Name and Yield] A new recipe is introduced with a recipe name and, often, with information regarding the ``yield" of the recipe (e.g., ``makes 36 cookies" or ``serves 4 to 6", etc.).
+ \item[Recipe Intro/Story] Often there is a story or other information specific to a recipe.
+ \item[Ingredients and Steps] Following the recipe name/yield and (possibly) a recipe story, there is a list of the ingredients, plus the steps required to make the recipe.
+ \item[Attribution] If the source of the recipe is known, it is proper to acknowledge that source.
+ \item[Additional Comments/Advice] There may be some recipe side notes and/or advice that is not properly included within the recipe, but is noted afterwards.
+\end{description}
+
+\newpage
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\part{Elements of a Book -- the Details}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Terminology}
+
+We define here some of the terms used below. Our book is two-sided, so visualize an open book with both the left and right page visible.
+
+The terms \boldit{recto} and \boldit{verso} (from the Latin) refer to the text written or printed on the right (front) side and on the left (reverse or back) side of a leaf of paper. By book publishing convention, the first page of a book, and the start of each chapter of a book, is on a recto page. That means all recto pages will have odd page numbers and all verso pages will have even page numbers.
+
+Still visualizing our open book, the \boldit{outer margin} is the right margin on a right/recto page and the left margin on a left/verso page -- the margin \textit{away from} the book binding. Similarly, the \boldit{inner margin} is the left margin on a recto page and the right margin on a verso page -- the margin \textit{closest to} the book binding.
+
+\section{Trim Size and Margins}
+
+In deciding on the trim size of the cookbook, we started with two requirements: (1) for the main text, we wanted an easily readable font size of at least 11 points, and (2) with very few exceptions, we wanted all recipes to fit on one page. With trial and error on margins and possible use of multiple columns, plus research on best practices in typography, and testing of various fonts, we ended up with the trim size and margins described below. Then we used the \pkg{geometry} package to set those parameters.
+
+We chose an industry standard trim size of 8{\thinspace}x{\thinspace}10 inches. That trim size allows for printing by most print-on-demand printing companies.
+
+It is tempting to set small margins to allow for more text on the page. Typographers have given much thought to these matters and it just isn't that simple. A useful discussion is found in Chapter 2 of the KOMA-script documentation\footnote{https://ctan.org/pkg/koma-script}. As a result, we increased our margins well beyond our initial instincts. Even so, there is still not as much margin space as some experts might like.
+
+We set the outer margins to 1.0 inch. When the book is open, you see both sides of the inner margin together; it is therefore recommended that you set the inner margins to one-half the outer margin (here, 0.5 inch). Visually, it is as if you had three margins: a 1-inch verso outer margin, a 1-inch combined recto/verso inner margin, and a 1-inch recto outer margin. You should also add a \textbf{\textit{binding offset}} to compensate for the part of the inner margin that disappears into the binding -- we have set the binding offset (for \textit{each} side of the inner margin) to 0.375 inches.
+
+Because we are using footers but not headers, we have set the top margin to 0.75 inches and the bottom margin to 1.0 inch. That leaves the text area at 6.125{\thinspace}x{\thinspace}8.25 inches, about 63\% of the full page size.
+
+We have set the distance between the bottom of the text area and the baseline of the footer to 40 points, which seems to give a nice separation between the text area and the footer.
+
+The above is obtained with the following \pkg{geometry} package settings:
+
+\begin{MyVerbatim}
+\usepackage{geometry}
+
+\ifCookbookDraft
+\geometry{paper=letterpaper, % the physical paper size during draft mode
+ layoutsize={8in,10in}, % always use intended final paper size for layout
+ layouthoffset=0.25in, % center the "layout" horizontally
+ layoutvoffset=0.5in, % center the "layout" vertically
+ %showframe, % use when needed
+ showcrop}
+\else
+\geometry{papersize={8in,10in}} % the physical paper size in final production mode
+\fi
+
+\geometry{nomarginpar, % do not reserve space for margin notes
+ bindingoffset=0.375in,
+ inner=0.5in,
+ outer=1in,
+ top=0.75in,
+ bottom=1in,
+ footskip=40pt} % default seems to be 27pt
+\end{MyVerbatim}
+
+\MyLabel[1]{Geometry}When you submit your cookbook to a print-on-demand printer, the PDF file's metadata must show the paper size equal to the intended trim size. In the \pkg{geometry} package, this is done by making sure that \pkg{papersize} equals \pkg{layoutsize}. However, during the time you are working on your cookbook (in draft mode), you want to set the \pkg{geometry} package \pkg{papersize} equal to the physical size of the paper coming out of your local printer. In our case, we are printing draft pages in \pkg{letterpaper} size (8.5 x 11 inches). You manage this draft vs.{}\thinspace final difference, by setting the \Cmd{newif} value of \Cmd{ifCookbookDraft} to \Cmd{CookbookDrafttrue} (draft) or \Cmd{CookbookDraftfalse} (final). You will find these settings near the very top of \pkg{cb-preamble.tex}.
+
+Just modify the above \pkg{geometry} settings for your needed trim size, draft paper size, margins, etc.
+
+\section{Headers and Footers}
+
+\latex sets headers and footers with the \pkg{pagestyle} command. Several page\-styles are predefined by \latex[,] but you are also allowed to define your own. We are using the \pkg{book} document class, which by default uses: (1) the predefined \pkg{empty} pagestyle (no header or footer on the page), (2) the predefined \pkg{plain} pagestyle (no header, the footer contains only a centered page number), and (3) a modified version of the predefined \pkg{headings} pagestyle.
+
+In the cookbook, we use the \pkg{empty} pagestyle, a modified version of the \pkg{plain} pagestyle, plus a \pkg{main} pagestyle that we define. We use the \pkg{fancyhdr} package to redefine the \pkg{plain} pagestyle and to define our own \pkg{main} pagestyle, as follows:
+
+\begin{MyVerbatim}
+\usepackage{emptypage, fancyhdr} % for emptypage, see Q360739
+ % NOTE: RO = right/odd; LE = left/even; CE = center/even; CO = center/odd
+\fancypagestyle{plain}{%
+ \fancyhf{} % clear the header and footer
+ \renewcommand{\headrulewidth}{0pt} % use 0 to disable header ruler line
+ \renewcommand{\footrulewidth}{0.2pt}
+ \fancyfoot[RO, LE] {Page \thepage}}
+
+\makeatletter % \makeatletter must be OUTSIDE the command - see Q 444532
+\fancypagestyle{main}{ % identical to plain, except in mainmatter, where
+ % it includes \leftmark in the center of the footer
+ \fancyhf{}
+ \renewcommand{\headrulewidth}{0pt}
+ \renewcommand{\footrulewidth}{0.2pt}
+ \fancyfoot[RO, LE] {Page \thepage}
+ \fancyfoot[CE,CO]{\if@mainmatter \leftmark\fi}} % See Q340125
+\makeatother
+\end{MyVerbatim}
+
+The above code does as follows:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item By loading the \pkg{emptypage} package, we force all completely empty pages to use the \pkg{empty} pagestyle.
+ \item The redefined \pkg{plain} pagestyle: (1) has no header and no header-area rule line, (2) has a footer-area rule line that is 0.2 points thick, and (3) prints the page number at the outer margin -- the right side of the footer on \textit{recto} (odd numbered) pages and the left side of the footer on \textit{verso} (even numbered) pages.
+ \item The \pkg{main} pagestyle is identical to the redefined \pkg{plain} pagestyle, except, \textit{in the mainmatter area only}, it prints the \Cmd{leftmark} in the center of the footer on both even and odd numbered pages. In the \pkg{book} class, the \Cmd{leftmark} is in all-caps and looks like \Quote{CHAPTER 2. COOKIES}. %is \Quote{CHAPTER} followed by the chapter number (Arabic) and the chapter name.
+\end{itemize}
+
+With our pagestyles defined, we now describe how they are used. We follow a very typical approach to headers and footers in printed books:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item Empty Page: if a page is otherwise completely empty, we use the \pkg{empty} pagestyle. This rule applies through the frontmatter, mainmatter and backmatter, \textit{and supersedes all other rules}. An empty page happens, for example, when a chapter ends on a recto page. Since all new chapters start on a recto page, the intervening verso page is completely empty.
+ \item Frontmatter: We employ the \pkg{empty} pagestyle from the beginning (title page) up to and including the page just before the \Cmd{tableofcontents} page. Then, from that page through the end of the frontmatter, we employ the (redefined) \pkg{plain} pagestyle. We follow the default rule for the \pkg{book} class, where frontmatter page numbers are indicated by small roman numerals. Note that there is “pagination†(page counting) from the first page, but only printing of the page number after switching to the \pkg{plain} pagestyle.
+ \item Mainmatter: We employ the \pkg{main} pagestyle, except on the first page of each \Cmd{chapter}, which switches to the redefined \pkg{plain} pagestyle (this switch is the default book class \Cmd{chapter} behavior, so requires no coding by us). Page numbers are arabic, with page 1 being the first page of the first mainmatter chapter.
+ \item Backmatter: We employ the \pkg{plain} pagestyle. Page numbers are arabic, and continue with the pagination from the mainmatter.
+\end{itemize}
+
+Our code only needs to issue two \Cmd{pagestyle} commands: (1) we include \Cmd{pagestyle\{empty\}} as the first line of \pkg{cb-frontmatter.tex}, and (2) we include \Cmd{pagestyle\{main\}} just after the \Cmd{tableofcontents} command in \pkg{cb-frontmatter.tex}. (Recall that the \pkg{main} pagestyle is identical to the \pkg{plain} pagestyle in the frontmatter and backmatter). To implement our rule for empty pages, we load the \pkg{emptypage} package, which automatically applies the \pkg{empty} pagestyle to all empty pages.
+
+The \pkg{fancyhdr} documentation is a good source of additional information on these matters.
+
+\section{Chapter Title Formatting}
+
+We use the \pkg{titlesec} package for the formatting of chapter titles. Following are some key concepts of the \pkg{titlesec} package:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item The \boldit{label} means the basic chapter information, such as ``Chapter 6".
+ \item To obtain the current \boldit{label}, you use the \Cmd{chaptertitlename} command (to obtain ``Chapter") and the \Cmd{thechapter} command (to obtain the current chapter number). Importantly, per the \pkg{book} class default, both of those commands are blank in the frontmatter and backmatter, so we only obtain a non-empty \boldit{label} in the mainmatter.
+ \item The \boldit{title body} means the text identifying the current chapter, such as ``Sauces and Chutneys".
+ \item the \boldit{title} means the entire chapter title (\textit{label} plus \textit{title body}).
+ \item Two commands are provided to change the \boldit{title} format. The \Cmd{titleformat} command is used for the “internal†format (i.e., shape, font, label, etc.) and the \Cmd{titlespacing} command defines the “external†format (i.e., spacing before and after, etc.).
+\end{itemize}
+
+Following is our code:
+
+\begin{MyVerbatim}
+\usepackage{titlesec}
+
+\titleformat{\chapter}[display] % [display] puts the label in a separate paragraph
+ {\filleft\FontChapterLabel} % The format for the whole title (label and title body text)
+ {\chaptertitlename\ \thechapter} % This defines the text for the label
+ {1pt} % The horizontal separation between label and title body:
+ % Next is optional code preceding the title body. We change
+ % the title body font from the initial setting above.
+ % we include \raggedleft because text may exceed one line.
+ {\titlerule\vspace{1ex}\raggedleft\FontChapterTitle}
+
+\titlespacing*{\chapter} % The starred version kills the indentation of the
+ % paragraph following the title.
+ {0pt} % amount to increase left margin
+ {20pt} % vertical space before title
+ {20pt} % verticle space between title and text
+\end{MyVerbatim}
+
+The \pkg{titlesec} documentation is a good source of additional information on these matters.
+
+\section{Odds and Ends}
+
+\subsection{Color}\MyLabel{Color}
+
+An important decision in a cookbook is whether to print in black and white or color. The printing costs can be substantially different. One option is to first print a small number of books in black and white, live with the book for a while, edit as necessary, and then move to color printing when you are fully satisfied with the final product.
+
+Our approach is to define all colors used in the cookbook in one place in the preamble. We use the \pkg{xcolor} package and the \Cmd{definecolor} command to create our defined names for all of our colors. That allows us (in one place) to change those color definitions to accommodate either a black and white or color cookbook.
+
+You should check with your print on demand printer to determine whether they prefer (or require) either the CMYK or RGB color model. In our code, below, we provide examples of both color models:
+
+\begin{MyVerbatim}
+\usepackage{xcolor}
+\definecolor{clrWhite}{cmyk}{0.00, 0.00, 0.00, 0.00} % true white
+\definecolor{clrBackTip}{rgb}{1.0, 0.95, 0.95} % red!5!white
+\definecolor{clrFrameTip}{rgb}{0.75, 0.0, 0.0} % red!75!black
+\definecolor{clrBackCheffy}{rgb}{1.0, 1.0, 1.0} % white
+\definecolor{clrFrameCheffy}{rgb}{0.0, 0.0, 0.75} % blue!75!black
+\definecolor{clrBackNotes}{rgb}{1.0, 1.0, 1.0} % white
+\definecolor{clrFrameNotes}{rgb}{0.0, 0.75, 0.0} % green!75!black
+\definecolor{clrLettrineBig}{gray}{0.5}
+\definecolor{clrLettrineSmall}{gray}{0.5}
+\definecolor{clrIngTitle}{cmyk}{0.00, 1.00, 1.00, 0.00} % true red
+\definecolor{clrEditNote}{cmyk}{0.00, 1.00, 1.00, 0.00} % true red
+\definecolor{clrHyperRef}{cmyk}{0.00, 1.00, 1.00, 0.00} % true red
+\end{MyVerbatim}
+
+See the \pkg{xcolor} package for helpful information on the CMYK and RGB color models.
+
+\subsection{Drop Cap}\MyLabel{DropCap}
+
+A \textit{drop cap letter} is a single letter (usually at the beginning of a chapter or important paragraph) that is larger than the following text. The practice began more than 2,000 years ago. Originally, the drop cap was very ornate and several lines high. As typesetting took hold in the mid 15th century, the typesetter would leave the necessary blank space to allow for a hand-drawn drop cap. The drop cap served two purposes: (1) it was a decorative element and (2) it assisted the reader by dividing the text into different parts. By the latter part of the 19th century, drop caps had mostly lost their ornamental flourish and usually consisted only of a larger letter (maybe sized to two or three lines) signifying the start of a chapter or section.
+
+There was a substantial reduction in the use of drop caps at the beginning of the 20th century. More recently, there has been a bit of a revival. Our review of modern cookbooks found that it now quite common, but hardly universal. We have elected to use drop caps in the chapter intro and in the recipe story, but our code does not require it. We use the \pkg{lettrine} package to implement our drop caps (\Quote{lettrine} is the French word for drop caps). As is customary, the \pkg{lettrine} package (optionally) uses a different font style for the first several characters following the drop cap (by default they are set to small caps). We call these special characters the \textit{drop caps text}. Our code:
+
+\begin{MyVerbatim}
+\usepackage{lettrine}
+\renewcommand{\LettrineFontHook}{\MyScriptFont\color{clrLettrineBig}}
+\renewcommand{\LettrineTextFont}{\color{clrLettrineSmall}\FontLettrineText}
+\renewcommand{\DefaultOptionsFile}{cb-lettrine.cfl}
+\end{MyVerbatim}
+
+We use the \Cmd{LettrineFontHook} command to set the font (and color) of the \textit{drop cap letter} to our script font. We use the \Cmd{LettrineTextFont} command to set the font (and color) of our \textit{drop caps text} to a small-caps version of the current roman font. Finally, we use the \Cmd{DefaultOptionsFile} command to point to a \pkg{lettrine} package configuration file (here \pkg{cb-lettrine.cfl}) where we fine-tuned the height (in rows) and width of each alphabetic letter that may be used as a \textit{drop cap letter}. See the \pkg{lettrine} package documentation for more details.
+
+\subsection{Images/Photos}
+
+There is very little material here on using images in your cookbook. We use the well-documented \pkg{graphicx} package and its\Cmd{includegraphics} command as the starting point for displaying photos. Our advice is to use non-\latex programs to put your images in final form (any rotation or cropping needed, as well as any needed adjustments to size or dpi).
+
+By way of example, we include the code for our \Cmd{SideBySide} command, used for displaying two images side-by-side. Some comments on the setup:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item Recall that all of our \pkg{*.tex} files (and therefore our \Quote{current directory}) will either be in: (1) the root directory of the cookbook project, or (2) the \pkg{tex} subdirectory under that root directory. Also, all of our image files will be in the \pkg{img} subdirectory under that root directory. We use the \Cmd{graphicspath} command to tell \latex to look for the image files either: (1) in the \pkg{img} subdirectory under the current directory, or (2) in the \pkg{img} directory that is a sibling of the current directory.
+ \item We use the \pkg{caption} package to manage any caption we put under an image. With \pkg{skip=2pt}, the vertical distance between the image and caption is set to 2 points. With \pkg{labelformat=empty}, we have an empty caption label. With \pkg{font=\{rm,it\}}, the caption font is \Cmd{rmfamily} and italic. The \pkg{caption} package options can be selected in the \Cmd{usepackage} command, or separately in the \Cmd{captionsetup} command. To demonstrate the latter, we select the \pkg{justification=centering} option in \Cmd{captionsetup}.
+ \item The \Cmd{SideBySide} command has two mandatory arguments. For the two side-by-side images, \textbf{Arg \#2} is the left image and \textbf{Arg \#3} is the right image.
+ \item \textbf{Arg \#1} is an optional key-value argument with three possible entries. \pkg{VertAlign=} defaults to \pkg{c} (vertically align images at their centers) and can also be set to \pkg{t} (align at their tops) or \pkg{b} (align at their bottoms). \pkg{LeftCaption=} and \pkg{RightCaption=} default to \Cmd{empty} and can be use to include a caption under one or both of the images.
+\end{itemize}
+
+
+
+\begin{MyVerbatim}
+\graphicspath{{img/}{../img/}} % look in img directory (subdir of book root or sibling of tex)
+\usepackage[skip=2pt, labelformat=empty, font={rm,it}]{caption} %
+\captionsetup{justification=centering} % this is needed to have multi-line captions centered
+
+\pgfkeys{
+ /SideBySide/.is family, /SideBySide,
+ default/.style = {VertAlign = c, LeftCaption = \empty, RightCaption = \empty},
+ VertAlign/.estore in = \VerticalAlign,
+ LeftCaption/.estore in = \LeftText,
+ RightCaption/.estore in = \RightText,
+}
+
+\NewDocumentCommand \SideBySide{O{\empty} m m} % Q 5769
+{
+\pgfkeys{/SideBySide, default, #1}%
+%
+\begin{figure}[htb]
+ \centering
+ \begin{minipage}[\VerticalAlign]{0.49\textwidth} % align at t= top, c = center, b = bottom
+ \centering
+ \includegraphics[width=0.97\textwidth]{#2} %
+ \ifx\LeftText\empty\relax\else\caption{\LeftText}\fi
+ \end{minipage}\hfill%
+ \begin{minipage}[\VerticalAlign]{0.49\textwidth}
+ \centering
+ \includegraphics[width=0.97\textwidth]{#3} %
+ \ifx\RightText\empty\relax\else\caption{\RightText}\fi
+ \end{minipage}
+ \end{figure}
+}
+\end{MyVerbatim}
+
+
+\section{Front Matter, Main Matter and Back Matter}
+
+\subsection{Introduction}
+
+Almost all books have a structure consisting of three sections: the front matter, the main matter and the back matter. We describe here the organization and contents of those three sections. Although there are many options regarding the organization and contents of those three sections, we limit our discussion to the actual (and very typical) structure we have selected.
+
+\subsection{Front Matter}
+
+The \textbf{front matter} (sometimes called \Quote{preliminaries}) is the first section of a book. Because the front matter is normally the last section of a book to be completed, small roman numerals are traditionally used for the front matter page numbers. That way, last-minute changes will not require renumbering the main text.
+
+For our cookbook, the front matter is contained in the file \pkg{cb-frontmatter.tex}. We now describe, in order of appearance, the parts that make up the front matter.
+
+\subsubsection{Title Page}
+
+It is actually typical for old-line publishers to start with a half-title page (just the book name and no other information) and then the full title page (including author's name and possibly other information). We include only a full title page.
+
+\subsubsection{Copyright Page}
+
+Here we provide the copyright information. As is common, we also includes information on the publisher, the book edition and edition history, the ISBN number (if any), and the Library of Congress number (if a USA book). We also include here information about the production, design and fonts (the \Quote{colophon}). \textit{You will need to make several edits to this page -- see the \Quote{front matter helper commands} section of the preamble}.
+
+\subsubsection{Dedication}
+
+The dedication, if any, follows the copyright page and is the only element on that page.
+
+\subsubsection{Table of Contents}
+
+We provide the page number for each chapter in the book, and for the index. If your book has an appendix (or similar), you should also include that in the table of contents.
+
+With the book class, no package is required to include chapters, sections and subsections in the table of contents. Because our cookbook has no sections or subsections, we list only chapters (plus the index) in our table of contents. We insert the table of contents at the desired location in the front matter simply by issuing the \Cmd{tableofcontents} command. Section \ref{BackMatter} (page \pageref{BackMatter}) shows how we add the index to our table of contents.
+
+\subsubsection{Other}
+
+Following the table of contents, there may be some or all of the following (each as a separate chapter and each included in the table of contents): foreword, preface, acknowledgments, introduction, or similar.
+
+\subsection{Main Matter}
+
+The \textbf{main matter} (sometimes called the \Quote{body matter}) follows the front matter. This is the actual text of your book. We follow the typical case where the main matter consists only of the chapters of the book. The first page of the main matter is page 1 of the book (Arabic numbering).
+
+\subsection{Back Matter}\label{BackMatter}
+
+The \textbf{back matter} (sometimes called the \Quote{end matter}) follows the main matter. Ours is a typical case, where the back matter contains only the book index. The back matter is where you might include other ancillary information such as an appendix, notes, a glossary, a bibliography, etc. Our index consists only of the recipes in the cookbook. See page \pageref{RecNameYield} and the \Cmd{RecipeNameAndYield} command for how we put our recipes in the index.
+
+Following is the code to include the index in the back matter. First, from \pkg{cb-preamble.tex} we have:
+
+\begin{MyVerbatim}
+\usepackage{imakeidx} % supports creation of an index (here, a recipe index)
+\makeindex[intoc] % make the *.idx file; intoc = include this Index in TOC (Q 59619)
+
+\NewDocumentCommand \CookbookIndex{}{
+ \cleardoublepage % flush all material and clear until you start new odd numbered (recto) page
+ \phantomsection\addcontentsline{toc}{chapter}{\indexname} % see also Q 59619
+ \printindex
+}
+\end{MyVerbatim}
+
+\noindent And from \pkg{makecookbook.tex} we have:
+
+\begin{MyVerbatim}
+\backmatter
+\CookbookIndex{}
+\end{MyVerbatim}
+
+With the above code, you get the standard index format for the \pkg{book} document class (plus inclusion in the table of contents). We have also added code that modifies the format of the index in three ways: (1) it slightly changes the hanging indent of long index items, (2) it right justifies the page number associated with the index item, and (3) it \Quote{dot fills} between the index item and the page number. Our code:
+
+\begin{MyVerbatim}
+\makeatletter
+\def\@idxitem{\par\hangindent 10pt} % not needed unless you want to fine tune hanging indent
+\newcommand{\betterdotfill} % see Q 396898
+ {\leavevmode \nobreak\cleaders \hb@xt@ .44em{\hss .\hss }\hskip .5em plus 1fill \kern \z@}
+\makeatother
+\makeindex[options=-s cb-idxstyle] % use cb-idxstyle.ist for style; Q 132465 & Q 396898
+\end{MyVerbatim}
+
+You might want to temporarily comment out this additional code, just to compare the results to the standard \pkg{book} class index format.
+
+The above code: (1) slightly changes the hanging indent for index items that are longer than a single line (this code is definitely \textit{not} necessary), (2) defines the \Cmd{betterdotfill} command (more on this below), and (3) uses the \Cmd{makeindex} command to load an \Quote{index style file} named \pkg{cb-idxstyle.ist} to modify the format of the index\footnote{See \pkg{https://ctan.org/tex-archive/indexing/makeindex/paper/ind.pdf} for documentation on the index style file.}. The \pkg{cb-idxstyle.ist} file is a text file with the following contents:
+
+\begin{MyVerbatim}
+ delim_0 "\\betterdotfill "
+ delim_1 "\\betterdotfill "
+ delim_2 "\\betterdotfill "
+\end{MyVerbatim}
+
+What is with that strange \Cmd{betterdotfill} command (courtesy of Enrico Gregorio in Q 396898)? If you still have the default setup of the \pkg{makecookbook} package (including fonts, margins, etc.), we can demonstrate why it is needed. In the above \pkg{cb-idxstyle.ist} file, change the three \pkg{betterdotfill} entries to standard \pkg{dotfill} entries:
+
+\begin{MyVerbatim}
+ delim_0 "\\dotfill "
+ delim_1 "\\dotfill "
+ delim_2 "\\dotfill "
+\end{MyVerbatim}
+
+Now compile and look at the index entry for the recipe named \Quote{G -- Potato Salad with Sherry Shallot Vinaigrette}. That recipe is \textit{exactly} the wrong size, causing \Cmd{dotfill} to fail. The page number is not right justified and there is no dot fill. Enrico's magic code\footnote{Don't ask us to fully explain Enrico's code, although there are strong hints in \textit{The TeXbook} by Donald E. Knuth.} solves the problem by forcing the last part of \Quote{wrong-sized} recipe names to spill over to the next line.
+
+\newpage
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\part{Elements of a Book -- the Details (Fonts)}\MyLabel{Fonts}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Introduction}
+
+The \texttt{METAFONT} font selection scheme in original \tex was developed beginning in the late 1970's. Although advanced for its time, it is quite limiting by today's standards. In \latex[,] a 'New Font Selection Scheme' (NFSS) was released in 1989 and then updated in 1993. While certainly a great improvement, allowing package writers to make many new fonts available, it is still a cumbersome and limiting system.
+
+Backward compatibility has been a limiting factor in \latex development, due to: (1) the expectation that older documents will still compile and produce identical output and (2) the large ecosystem of third-party packages. Until recently, one of the most important advances was the \pkg{pdfTeX} compiler, which produced PDF output directly from a \tex or \latex compile. However, \pkg{pdfTeX} is still an 8-bit system with the same font limitations. While there are packages and methods for incorporating Unicode in a \pkg{pdfTeX} compile, it is both kludgy and incomplete.
+
+Recently, the \xetex and \luatex compilers have been released. They are Unicode-based 32-bit systems. Both can load any OpenType (including TrueType) font installed on your computer -- all you need is the \pkg{fontspec} package. That allows easy use of the advanced typographic features of OpenType. It must be noted that these two new compilers have some subtle incompatibilities with \tex and \latex{}. However, those incompatibilities are minimal and will impact a small group of uses -- primarily those with old legacy code. Of course, \pkg{pdfTeX} is still available for any such legacy code.
+
+To allow for more modern font handling, we therefore decided to use the \luatex compiler. As between \luatex and \xetex[,] we decided that \luatex is a better choice due to its more complete support of the \pkg{microtype} package and for the option (which we have not used) of Lua scripting.
+
+\subsection{Fonts}
+
+We discussed on page \pageref{IntroFonts} the three fonts you must install if you want a successful compile \Quote{out of the box}. Here we discuss the attributes required of substitute fonts. We begin by again listing the three font, along with the weights and shapes required of substitute fonts:
+
+\begin{description}
+ \item[Serif] \textit{EB Garamond} (version from Google Fonts). Any substitute font should have regular and bold weights, both to include the italics shape. Also, the regular weight should include the small caps shape.
+ \item[Sans Serif] \textit{Lato} (version from \pkg{www.latofonts.com}). Any substitute font should have regular, semi-bold and bold weights, all to include the italics shape.
+ \item [Script] \textit{Italianno} (version from Google Fonts). We only need the regular font weight and shape.
+\end{description}
+
+In addition to the above, the substitute fonts must be OpenType (including TrueType) and should support the \pkg{Ligatures=TeX} font feature described in the \pkg{fontspec} package manual. Finally, the \textit{serif} and \textit{sans serif} fonts should support the following (there are workarounds if they do not):
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item These glyphs: \textit{degree} (char 176), \textit{copyright} (char 169), \textit{center dot} (char 183), and \textit{bullet} (char 8226).
+ \item The \pkg{Fractions=On} OpenType font feature, as described in the \pkg{fontspec} package manual.
+\end{itemize}
+
+On page \pageref{FontCode} and following, below, we discuss the simple changes to \pkg{cb-preamble.tex} you must make to substitute your own favorite fonts.
+
+\section{Line Length and Font Size}
+
+Part of the font selection process is choosing a proper point size for the intended use. And these decisions directly impact other issues, such as the choice of trim size and margins. We consider here the important relationship between point size and line length.
+
+Lines of text can be less comfortable to read if they are either too long or too short. Following are a couple of (sometimes contradictory) rules of thumb for the body text of a printed book\footnote{See, e.g.: \pkg{https://en.wikipedia.org/wiki/Line\_length} and the references cited there.}:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item Line length should be between 45 and 75 characters per line. For printed works with multiple columns, 40 to 50 characters per line is preferred.
+ \item Line length should be about 30 times the point size of the font, with an acceptable range between 20 and 40 times. We call that number the \textit{point multiple}, and calculate it by dividing the length (in points) of the line by the point size of the font. We assume that 1 inch equals 72.27 points (often rounded to 72 points in desktop publishing applications). Our 6.125-inch text margin is therefore about 443 points wide.
+\end{itemize}
+
+Now let's relate the above rules of thumb to our four different layouts of body text.
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item The introductory text at the beginning of each chapter has a font size of 14 points. Dividing 443 by 14, we have a nearly ideal \textit{point multiple} of about 31.6. We roughly calculate the characters per line at between 78 and 80 -- a little high, but we find the text easily readable and note the \textit{point multiple} is right where it needs to be.
+ \item The introductory text at the beginning of each recipe has a font size of 13 points. Also, the text is indented on each side by 20 points, giving a text width of 403 points. Dividing 403 by 13, we have a nearly ideal \textit{point multiple} of about 31. We roughly calculate the characters per line at about 78 -- again, a little high, but we find the text easily readable and note the \textit{point multiple} is right where it needs to be.
+ \item The recipe ingredients and steps are presented in a two-column format, with a font size of 10.95 points. Listing of ingredients should not be considered \Quote{body text}, so we focus on the recipe steps. With a 10 point separation between the two columns, each column is about 217 points wide. Dividing 217 by 10.95, we have a \textit{point multiple} of just about 20 -- at the low end, as might be expected for multi-column text. We roughly calculate the characters per line at 48, right where it should be for multi-column text.
+ \item The copyright page uses a font size of 9 points. This is a \Quote{fine print} page and should not be considered as body text. It is of no concern that the characters per line and \textit{point multiple} are not within prescribed parameters.
+
+\end{itemize}
+
+\section{Our Selected Fonts}
+
+Below we provide additional detail on the fonts and font sizes we selected.
+
+\subsection{Serif Font}
+
+For the \pkg{makecookbook} package, we selected the \textit{EB Garamond} font. Garamond (produced in many versions) is an old-style serif typeface, named for sixteenth-century Parisian engraver Claude Garamond. It and related typefaces are very popular for printing body text in books. It is a classic design that does not shout \Quote{look at me} but just unobtrusively makes for very easy to read text.
+
+\textit{EB Garamond} is the primary font used in the cookbook. It is used everywhere in the cookbook that is not specifically mentioned below for the other fonts. Some of the key places where this font is used:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item When listing the steps to make a recipe. This is in a two-column environment, using a 10.95 point font.
+ \item At the beginning of recipes, when telling a story about the recipe or describing other special information regarding the recipe. This is in a one-column environment, indented 20 points on both the left and right sides. We use a 13 point font.
+ \item At the beginning of each chapter, when discussing the recipes in that chapter. This is in a one-column full-width environment, using a 14 point font.
+ \item On the copyright page, where it is typical to have a smaller font. We use a 9 point font.
+ \item In the chapter title, this font is used as the chapter \boldit{label} (e.g., ``Chapter 7"), using a 14.4 point font.
+\end{itemize}
+
+\subsection{Sans Serif Font}
+
+For the \pkg{makecookbook} package, we selected the \textit{Lato} font. \textit{Lato} is described as \Quote{clean and modern} as well as \Quote{transparent} (unobtrusive), meeting our goal for easy to read but low-key body text fonts. This is the only other font used for body text. It is used in two places:
+
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item When listing recipe ingredients. This is in a two-column environment, using a 10.95 point font. We use the semi-bold face to provide a better visual contrast between recipe ingredients and recipe steps.
+ \item When a recipe has multiple sections of ingredients/steps, we use this font for the title of a recipe section. It is still 10.95 points, but in italics with a bold face.
+\end{itemize}
+
+\subsection{Script}
+
+For the \pkg{makecookbook} package, we selected the \textit{Italianno} font. We believe it provides an interesting contrast to our two body text fonts, while still remaining readable. It is used in three places:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item In the chapter title, it is used for the name of the chapter. We use a 40 point font size.
+ \item In recipes, it is used for the recipe name. We use a 24 point font size.
+ \item As the large \textit{drop cap letter}. (Font size determined by the \Cmd{lettrine} package).
+\end{itemize}
+
+
+\begin{SideNote}
+ {
+ We have a confession to make. For our cookbook, we do not use the \textit{EB Garamond} or \textit{Lato} font. (We do use \textit{Italianno}). In their place, we use the \textit{Adobe Garamond Pro} and \textit{Adobe Myriad Pro} commercial fonts. Although both implementation of Garamond are excellent, for our main font we wanted a well-tested and reliable font (\textit{EB Garamond} is still in development). For our secondary font, we just very much like the look and readability of the Myriad typeface. Of course, we could not use a commercial font in this package.
+ }
+\end{SideNote}
+
+\section{Code to Implement our Font Usage}\MyLabel{FontCode}
+
+\subsection{Load Our Fonts}
+
+The first step is to load our three fonts using the \pkg{fontspec} package:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item Our \textit{serif} font is loaded using the \Cmd{setmainfont} command. After that, our code refers to this family as the \Cmd{rmfamily}.
+ \item Our \textit{sans serif} font is loaded using the \Cmd{setsansfont} command. After that, our code refers to this family as the \Cmd{sffamily}.
+ \item Our \textit{script} font is loaded using the \Cmd{newfontfamily} command. The \Cmd{newfontfamily} command allows us to name the family (similar to \Cmd{rmfamily}). We name our script font \Cmd{MyScriptFont}.
+\end{itemize}
+
+All three font loading commands include a mandatory argument to identify the font, plus various optional key-value augments. The \pkg{fontspec} package provides several options for identifying the font. We use their \Quote{by file name} option. The easiest way to understand this is to look at the six font files that make up \textit{EB Garamond's} regular, regular italic, bold, bold italic, semi-bold and semi-bold italic font faces:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item \pkg{ebgaramond-regular.ttf}
+ \item \pkg{ebgaramond-italic.ttf}
+ \item \pkg{ebgaramond-bold.ttf}
+ \item \pkg{ebgaramond-bolditalic.ttf}
+ \item \pkg{ebgaramond-semibold.ttf}
+ \item \pkg{ebgaramond-semibolditalic.ttf}
+\end{itemize}
+
+The leading part of the font name (\pkg{ebgaramond}) is entered as the mandatory argument. The \pkg{.ttf} file extension is entered in the optional key-value argument: \pkg{Extension=.ttf}. The six font faces are identified by their filename, with a \pkg{*} representing the leading part of their filename. The complete code to load the fonts (see the \pkg{fontspec} package for more details):
+
+\begin{MyVerbatim}
+\usepackage{fontspec}
+\usepackage{microtype}
+
+\setmainfont{ebgaramond}[
+ Extension=.ttf,
+ UprightFont=*-regular,
+ ItalicFont=*-italic,
+ BoldFont=*-bold,
+ BoldItalicFont=*-bolditalic,
+ FontFace={sb}{n}{*-semibold},
+ FontFace={sb}{it}{*-semibolditalic},
+ Ligatures=TeX,
+ Numbers=Lining]
+
+\setsansfont{lato}[
+ Extension=.ttf,
+ UprightFont=*-regular,
+ ItalicFont=*-italic,
+ BoldFont=*-bold,
+ BoldItalicFont=*-bolditalic,
+ FontFace={sb}{n}{*-semibold},
+ FontFace={sb}{it}{*-semibolditalic},
+ FontFace={k}{n}{*-black},
+ FontFace={k}{it}{*-blackitalic},
+ Ligatures=TeX,
+ Numbers=Lining]
+
+\newfontfamily\MyScriptFont{Italianno}[
+ Extension=.otf,
+ UprightFont=*-Regular-OTF,
+ Ligatures=TeX]
+\end{MyVerbatim}
+
+As mentioned above, in our cookbook, we use the \textit{Adobe Garamond Pro} and \textit{Adobe Myriad Pro} fonts. To replace \textit{EB Garamond} and \textit{Lato} with those fonts, it is as simple as changing the \Cmd{setmainfont} and \Cmd{setsansfont} commands with (you can do the same to substitute your favorite fonts):
+
+\begin{MyVerbatim}
+\setmainfont{agaramondpro}[
+ Extension=.otf,
+ UprightFont=*-regular,
+ ItalicFont=*-italic,
+ BoldFont=*-bold,
+ BoldItalicFont=*-bolditalic,
+ FontFace={sb}{n}{*-semibold},
+ FontFace={sb}{it}{*-semibolditalic},
+ Ligatures=TeX,
+ Numbers=Lining]
+
+\setsansfont{myriadpro}[
+ Extension=.otf,
+ UprightFont=*-regular,
+ ItalicFont=*-it,
+ BoldFont=*-bold,
+ BoldItalicFont=*-boldit,
+ FontFace={sb}{n}{*-semibold},
+ FontFace={sb}{it}{*-semiboldit},
+ FontFace={k}{n}{*-black},
+ FontFace={k}{it}{*-blackit},
+ Ligatures=TeX,
+ Numbers=Lining]
+\end{MyVerbatim}
+
+\subsection{Handle Special Font Faces}
+
+We handle the two special font faces, semi-bold and black, giving them commands that are similar to the built-in commands used, for example, by bold (i.e., similar to the \Cmd{textbf} and \Cmd{bfseries} comands):
+
+\begin{MyVerbatim}
+\NewDocumentCommand \sbseries {}{\fontseries{sb}\selectfont}
+\DeclareTextFontCommand{\textsb}{\sbseries}
+\NewDocumentCommand \kseries {}{\fontseries{k}\selectfont}
+\DeclareTextFontCommand{\textk}{\kseries}
+\end{MyVerbatim}
+
+\subsection{Commands to Select Our Fonts}
+
+Next, we provide the commands needed to select the fonts. This gives us a level of indirection between the actual font used and the more abstract name we use for that font. In referencing/selecting a font, we will only use the below command names:
+
+\begin{MyVerbatim}
+\NewDocumentCommand \FontSteps {}{\rmfamily\mdseries}
+\NewDocumentCommand \FontStepsDefault {}{\rmfamily\mdseries}
+\NewDocumentCommand \FontIngredients {}{\sffamily\sbseries}
+\NewDocumentCommand \FontIngDefault {}{\sffamily\sbseries}
+\NewDocumentCommand \FontIngTitle {}{\sffamily\bfseries\itshape}
+\NewDocumentCommand \FontChapterIntro {}{\rmfamily\fontsize{14}{16.8}\selectfont}
+\NewDocumentCommand \FontRecipeStory {}{\rmfamily\fontsize{13}{15.6}\selectfont}
+\NewDocumentCommand \FontCopyrightPage {}{\rmfamily\fontsize{9}{11}\selectfont}
+\NewDocumentCommand \FontChapterLabel {}{\rmfamily\fontsize{14.4}{18}\selectfont}
+\NewDocumentCommand \FontChapterTitle {}{\MyScriptFont\fontsize{40}{48}\selectfont}
+\NewDocumentCommand \FontRecipeName {}{\MyScriptFont\fontsize{24}{29}\selectfont}
+\NewDocumentCommand \FontLettrineText {}{\rmfamily\scshape\sbseries}
+\NewDocumentCommand \FontTitleColorBox {}{\rmfamily\Large\bfseries}
+\NewDocumentCommand \FontTitlepageTitle {}{\MyScriptFont\fontsize{40}{48}\selectfont}
+\NewDocumentCommand \FontTitlepageAuthor{}{\rmfamily\sbseries\scshape\fontsize{14.4}{18}\selectfont}
+\end{MyVerbatim}
+
+\subsection{Special Handling of Fractions}
+
+For a cookbook, it is important to have a consistent way to display \Quote{nice} (and readable) fractions. For cookbooks, fractions are almost always of the \Quote{split level} type. Based on a suggestion in Q416164, we began by using the \pkg{xfrac} package and the \Cmd{sfrac} command, as follows:
+
+\begin{MyVerbatim}
+\usepackage{xfrac}
+\def\fr#1/#2 {\sfrac{#1}{#2} }
+\def\frx#1/#2 {\sfrac{#1}{#2}}
+\end{MyVerbatim}
+
+The first \Cmd{def} allows you to type \Cmd{fr}1/2 to get nicely formatted \fr1/2 followed by a space.
+The second \Cmd{def} allows you to type \Cmd{frx}1/2 to get nicely formatted \fr1/2 where the space following
+your entry is “gobbled†by the \Cmd{def} because there is a space between \Cmd{def} and \{. This second form is needed in the less common case when you want a parenthesis, comma, period or other character to immediately follow the fraction (i.e., no space between). Thus, to have a period immediately follow a nice \fr1/2 fraction, you would
+enter \Cmd{frx}1/2 . (Note the space between the 2 and the period).
+
+Later we noted the discussion in Q234857 and the possibility of using the OpenType \pkg{Fractions=On} option. Our serif and sans serif fonts include full support for \pkg{Fractions=On}. So we replaced the \Cmd{sfrac} command with the \Cmd{addfontfeatures} command (below). Although \Cmd{sfrac} does a good job of producing \Quote{nice} fractions, the fractions look even nicer when you use an OpenType font that fully supports \pkg{Fractions=On}. The new \Cmd{def} still uses the same “space trick†as the old \Cmd{def}. NOTE: some OpenType fonts \Quote{support} \pkg{Fractions=On} only partially – if there is an internal \Quote{pre-made} fraction they will use that, but things don’t otherwise look so nice (or consistent). Check you font.
+
+Our final code (you can revert to \Cmd{sfrac} if you desired font does not support this feature):
+
+\begin{MyVerbatim}
+\def\fr#1/#2 {{\addfontfeatures{Fractions=On}#1/#2} }
+\def\frx#1/#2 {{\addfontfeatures{Fractions=On}#1/#2}}
+\end{MyVerbatim}
+
+\subsection{Commands for Certain Glyphs}\MyLabel{Glyphs}
+
+The degree, copyright, bullet and center (or mid) dot glyphs all have standard unicode character codes, and all are available in our serif and sans serif fonts. We therefore provide our own commands for these glyphs, rather than using the associated \latex commands. Our goal is to avoid the possible loading by \latex of other unnecessary fonts to create those glyphs. A font uses only for a few glyphs can cause some confusion, and even failed print jobs, at some of the print on demand companies.
+
+Similarly, to avoid use of the math command \texttt{\$\Cmd{cdot}\$} (and possible loading of a math font), we “rolled our own†using our \Cmd{CtrDot} glyph and appropriate kerning to build the \Cmd{CtrDots} (plural) command.
+
+If you use a font that does not provide these glyphs, use the \latex macros \Cmd{textdegree} or \Cmd{copyright} or \Cmd{textbullet} or (math) \texttt{\$\Cmd{cdot}\$}.
+
+We also include here the code to use two \Quote{glyph-like} images: \Cmd{ChefHat} and \Cmd{Oven}. We made those two images using the \pkg{tikz} package and then saved them each in a \tex box. They are used in selected places, in the same fashion as normal font glyphs.
+
+\begin{MyVerbatim}
+\NewDocumentCommand \TextDegree {}{{\char176}} % or ^^^^00B0
+\NewDocumentCommand \Copyright {}{{\char169}} % or ^^^^00A9
+\NewDocumentCommand \TextBullet {}{{\char8226}} % or ^^^^2022
+\NewDocumentCommand \CtrDot {}{{\char183}} % or ^^^^00B7
+\NewDocumentCommand \CtrDots {}{{\CtrDot\kern 0.2em\CtrDot\kern 0.2em\CtrDot\kern 0.2em}}
+
+\newsavebox{\HatBox}
+\AtBeginDocument{\savebox{\HatBox}[\hatwidth]{\MakeChefHat}}%
+\NewDocumentCommand \ChefHat {}{\usebox{\HatBox}}%
+\NewDocumentCommand \ChefNote {}{{\raisebox{.4ex}{\ChefHat}}}
+
+\newsavebox{\OvenBox}
+\AtBeginDocument{\savebox{\OvenBox}[\ovenwidth]{\MakeOven}}%
+\NewDocumentCommand \Oven {}{\usebox{\OvenBox}}%
+\end{MyVerbatim}
+
+\subsection{Point Size of Default Roman and Sans Fonts}
+
+The \pkg{IngredientsAndSteps} environment and the \Cmd{RecipeStory} and \Cmd{ChapterIntro} commands (discussed further below) need to know certain default font parameters (in points) for the fonts they use. We calculated those values beforehand and stored the hard-coded values:
+
+\begin{MyVerbatim}
+\def\StdIFontSize{10.95}
+\def\StdSFontSize{10.95}
+\def\StdIBaseline{13.6}
+\def\StdSBaseline{13.6}
+\def\RStoryFontBaseline{15.6pt}
+\def\CIntroFontBaseline{16.8pt}
+\end{MyVerbatim}
+
+\newpage
+
+\part{Elements of a Cookbook -- the Details}
+
+\section{Chapter Introduction}
+
+In a cookbook, chapters tend to be organized into logical units such as cookies, pasta, appetizers, etc. Following the chapter name, there will usually be some introductory text for that chapter. We call that the \textit{chapter intro}.
+
+Use the \Cmd{ChapterIntro} command to enter your \textit{chapter intro} text. The command sets the default (roman serif) font to a larger size (14 points). A simplified version of the \Cmd{ChapterIntro} command follows. The actual code (page \pageref{RealChapterIntro}) includes an optional argument that you will rarely use:
+
+\begin{MyVerbatim}
+\NewDocumentCommand \ChapterIntro {+m}{\FontChapterIntro{#1\par}} % the \par needed by \lettrine
+\end{MyVerbatim}
+
+As noted, the \Cmd{ChapterIntro} command sets a default font face and size. However, you are free to use most any of the \latex text markup commands. You might make some text \textbf{bold} or \textit{italic}, or use an \pkg{enumerate} environment (e.g., to list you favorite cookie recipes). In our book, we have elected to use the \Cmd{lettrine} command to create a \Quote{drop cap} effect -- see the separate discussion of this on page \pageref{DropCap}.
+
+\section{Recipe Name and Yield}\MyLabel{RecNameYield}
+
+A new recipe is introduced with a recipe name and, often, with information regarding the ``yield" of the recipe (e.g., ``makes 36 cookies" or ``serves 4 to 6", etc.). To enter this information, we use the \Cmd{RecipeNameAndYield} command. It uses a key/value interface of the form:
+
+\begin{MyVerbatim}
+\RecipeNameAndYield{〈key=value, ...〉}
+\end{MyVerbatim}
+
+The key/value options are as follows:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item \textbf{[Name=]} Required. This is the recipe name. it is the only required key/value option.
+ \item \textbf{[Yield=]} Optional. You can optionally provide the \Quote{yield} of the recipe.
+ \item \textbf{[NoIdxName=]} Optional. As a general rule, the recipe name (as entered in the \textbf{Name=} option) is included in the Index to the cookbook (in the back matter). However, if you set this key to the number '1', the recipe name will not be placed in the Index. The purpose of this option is to allow you to make enties in the \Cmd{index} that are somewhat different than the actual recipe name. For example, perhaps you want to slightly shorten the recipe name for the Index.
+ \item \textbf{[IndexA=]} Optional. This is where you would enter alternate text for this recipe's index.
+ \item \textbf{[IndexB=]} Optional. Use this if you want another recipe index entry.
+ \item \textbf{[IndexC=]} Optional. Use this if you want yet another recipe index entry.
+ \item \textbf{[XRefLabel=]} Optional. Normally, recipes do not have a cross-reference \Cmd{label} created. Use this key/value option if you want to create a cross-reference \Cmd{label} for this recipe (the value entered here is the \Cmd{label}). That allows you to reference this recipe's page number from another location in the cookbook.
+\end{itemize}
+
+\begin{SideNote}
+ {This is a good place to remind you of the special handling needed when the \pkg{value} element of a key/value entry includes a comma. Suppose, for example, that your recipe is \textit{Pasta with Sausage, Tomatoes and Cream}. If your key/value entry is \textbf{Name=Pasta with Sausage, Tomatoes and Cream}, then they key/value parser will think the \pkg{Name=} entry ends at the comma. The solution is to put an extra set of curly braces around the value, such as: \textbf{Name=\{Pasta with Sausage, Tomatoes and Cream\}}. That tells the parser to treat the internally braced text as one unit.
+ }
+\end{SideNote}
+
+Following is the code defining the \Cmd{RecipeNameAndYield} command:
+
+\begin{MyVerbatim}
+\pgfkeys{
+ /RecipeNameAndYield/.is family, /RecipeNameAndYield,
+ default/.style = {Name = 0, NoIdxName = 0, XRefLabel = \empty, Yield = \empty,
+ IndexA = \empty, IndexB = \empty, IndexC = \empty},
+ Name/.estore in = \RecipeName,
+ NoIdxName/.estore in = \NoIndexName,
+ IndexA/.estore in = \IdxA,
+ IndexB/.estore in = \IdxB,
+ IndexC/.estore in = \IdxC,
+ XRefLabel/.estore in = \XRefLbl,
+ Yield/.estore in = \RecipeYield,
+}
+
+\NewDocumentCommand \RecipeNameAndYield {m}{%
+ \pgfkeys{/RecipeNameAndYield, default, #1}%
+ % Put the recipe name in the Index, unless the user sets NoIdxName = 1:
+ \ifnum\NoIndexName=1 \relax\else\index{\RecipeName}\fi
+ % Can add up to three other Index entries:
+ \ifx\IdxA\empty\relax\else\index{\IdxA}\fi
+ \ifx\IdxB\empty\relax\else\index{\IdxB}\fi
+ \ifx\IdxC\empty\relax\else\index{\IdxC}\fi
+ % Did the user ask us to set up a label for cross-reference?:
+ \ifx\XRefLbl\empty\relax\else\RecipeLabel{\XRefLbl}\fi
+ % Add a bookmark (only adds bookmark if hyperref is active):
+ \ifnum\NoIndexName=1 \RecipeBookmark{\IdxA}\else\RecipeBookmark{\RecipeName}\fi
+ % Now write the recipe name and (possibly) the yield
+ \begin{center}%
+ {\FontRecipeName{\RecipeName}}\par%
+ \ifx\RecipeYield\empty\relax\else {\textit{\RecipeYield}}\par \fi%
+ \end{center}%
+}
+\end{MyVerbatim}
+
+
+\section{Recipe Story}
+
+Often there is a story or other information specific to a recipe. In our design, that story follows the recipe's \pkg{RecipeNameAndYield} and precedes its \pkg{IngredientsAndSteps}. We call it the \textit{recipe story}.
+
+For reasons of readability, and for visual interest, we indent both the left and right margin of the \textit{recipe story} by 20 points and use a font size of 13 points. However, like the chapter intro, you are free to use most any of the \latex text markup commands\footnote{But see Q 66332 and Q 183569. You cannot use a list environment or similar.}. A simplified version of the \Cmd{RecipeStory} command follows. The actual code (page \pageref{RealRecipeStory}) includes an optional argument that you will rarely (if ever) use.
+
+\begin{MyVerbatim}
+\def\RecipeStoryIndent{20 pt}
+\NewDocumentCommand \RecipeStory {+m}{%
+ \FontRecipeStory
+ \leftskip=\RecipeStoryIndent \rightskip=\leftskip
+ {#1\par} % the \par needed by \lettrine
+}
+\end{MyVerbatim}
+
+
+\section{Ingredients and Steps}
+
+Following the recipe name/yield and (possibly) a recipe story, there is a list of the ingredients, plus the steps required to make the recipe. We have formatted this section into two columns, with the ingredients in a semi-bold face of the sans serif font and the steps in a normal face of the roman (serif) font. Both fonts use the default font size of 10.95 points.
+
+The code to accomplish this uses the \pkg{IngredientsAndSteps} environment to establish the two-column format, and then the \Cmd{ListIngredientsAndSteps} command to list the ingredients and steps. We discuss them below.
+
+\subsection{The \pkg{IngredientsAndSteps} Environment}
+
+A simplified version of the \pkg{IngredientsAndSteps} environment follows. The actual code (page \pageref{RealIngStepEnv}) is somewhat complicated. It has no mandatory arguments, but has several optional \pkg{key=value} style arguments that you will rarely (if ever) use.
+
+When used without optional arguments, the \pkg{IngredientsAndSteps} environment is very simple. Its only purpose is to establish the two-column format, using code that is equivalent to the following:
+
+\begin{MyVerbatim}
+\NewDocumentEnvironment{IngredientsAndSteps}{}
+ {\begin{multicols}{2}} % The "before environment" setup
+ {\end{multicols}} % The "after environment" cleanup
+\end{MyVerbatim}
+
+\noindent We simply provide a wrapper around the \pkg{multicols} environment where we select the two-column option.
+
+\subsection{The \Cmd{ListIngredientsAndSteps} Command}
+
+We use the \Cmd{ListIngredientsAndSteps} command to list the ingredients and provide the steps needed to make the recipe. There is one optional argument and two mandatory arguments, as follows:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item \textbf{[Arg 1]} Optional. In some recipes, there may be multiple sections of ingredients and steps. For example, the first section might be the ingredients and steps to make the cake, and the second section the ingredients and steps to make the frosting. In that case, you may want a label associated with each ingredients and steps section. The optional argument is the name of that section, formatted in bold italics and using the \pkg{clrIngTitle} color.
+ \item \textbf{[Arg 2]} Required. This is the list of ingredients. Each ingredient entry is separated by a blank line (i.e., the paragraph indicator in \latex text entry). Each paragraph becomes an ingredient in the list, formatted as \Cmd{raggedright} (not right justified), with a separation of 2 points between paragraphs.
+ \item \textbf{[Arg 3]} Required. This is the recipe steps. Each step entry is separated by a blank line (again, the paragraph indicator). Each paragraph becomes a recipe step. Unlike the ingredients, the steps are formatted as justified (the document default). We use the \pkg{enumerate} list environment to list the steps by number.
+\end{itemize}
+
+Following is the code defining the \Cmd{ListIngredientsAndSteps} command:\MyLabel{IngredientsHeading}
+
+\begin{MyVerbatim}
+\NewDocumentCommand \IngredientsHeading {O{0} m O{2}}%
+ {\begingroup \setlength{\parindent}{0pt} \ifnum #1 > 0 {\vspace{#1 pt}}\fi
+ \FontIngTitle\color{clrIngTitle} #2\par\vspace{#3 pt} \endgroup}%
+
+\NewDocumentCommand \ListIngredientsAndSteps {o +m +m}{%
+ \IfValueT {#1}{\IngredientsHeading{#1}[3]}%
+ {\begingroup\ifx\relax#2\relax\else\FontIngredients{}\IngredientsList{#2}\fi\endgroup}% arg2
+ {\begingroup\ifx\relax#3\relax\else\FontSteps{}\RecipeSteps{#3}\fi\endgroup}% % arg3
+}
+
+\NewDocumentCommand \IngredientsList { >{\SplitList{\par}} +m}{%
+ \setlength{\parskip}{2pt}\raggedright%
+ \ProcessList{#1}{\ProcessIngList}}
+
+\newcommand\ProcessIngList[1]{\hangindent1em #1\par}
+
+\NewDocumentCommand \RecipeSteps { >{\SplitList{\par}} +m}{%
+ \begin{enumerate}[itemsep=2pt plus 1 pt minus 1pt, parsep=0pt plus 1pt,
+ topsep=4.5pt plus 2.0pt minus 1.0pt, leftmargin=*]
+ \ProcessList{#1}{\item}
+ \end{enumerate}
+}
+\end{MyVerbatim}
+
+As indicated in the description of the optional argument, please note that one \pkg{IngredientsAndSteps} environment may contain more than one \Cmd{ListIngredientsAndSteps} command.
+
+\section{Attribution}
+
+If the source of the recipe is known, it is proper to acknowledge that source. In that case, after the listing of ingredients and steps, we include an attribution. It is formatted as right justified and italics, in the default 11 point roman/serif font. The code:
+
+\begin{MyVerbatim}
+\NewDocumentCommand \Attribution{m}{{\hspace*\fill}{\textit{#1}}}%
+\end{MyVerbatim}
+
+\section{Additional Comments/Advice}
+
+There may be some recipe side notes and/or advice that is not properly included within the recipe, but is noted afterwards. We provide three separate environments to display that information -- the \pkg{Tip}, the \pkg{Cheffy}, and the \pkg{ChefNotes} environments -- all based on the \pkg{tcolorbox} package. All three environments take one mandatory arguments, which is the text (and any associated \latex markup commands) to be included in the body of the \pkg{tcolorbox} environment.
+
+For example, the following code...:
+
+\begin{MyVerbatim}
+\begin{Tip}
+ {You can substitute \fr1/2 cup of vegetable or light olive oil for the butter.}
+\end{Tip}
+
+\begin{Cheffy}
+ {Using some almond flour results in biscotti with a delightful crunchy texture without making
+ them hard. I encourage you try useing 25\% almond flour.}
+\end{Cheffy}
+
+\begin{ChefNote}
+ {The amount of flour might vary if you use all-purpose flour versus “00†flour. If Tipo “00â€
+ flour, you might need a little more flour. Use the texture of your dough as a guide.}
+\end{ChefNote}
+\end{MyVerbatim}
+
+\noindent...gives you the following results:
+\vspace{5pt}
+
+\begin{Tip}
+ {You can substitute \fr1/2 cup of vegetable or light olive oil for the butter.}
+\end{Tip}
+
+\begin{Cheffy}
+ {Using some almond flour results in biscotti with a delightful crunchy texture without making them
+ hard. I encourage you try using 25\% almond flour.}
+\end{Cheffy}
+
+\begin{ChefNotes}
+ {The amount of flour might vary if you use all-purpose flour versus “00†flour. If Tipo “00†flour,
+ you might need a little more flour. Use the texture of your dough as a guide.}
+\end{ChefNotes}
+
+Of course, given the needs of your cookbook, you can easily change the title and color of these three environments. The \latex code follows (see page \pageref{Color} for information on the colors used below):
+
+\begin{MyVerbatim}
+\usepackage{tcolorbox}
+\tcbset{fonttitle=\FontTitleColorBox}
+
+\NewDocumentEnvironment{Tip}{+m}
+ {
+ \begin{tcolorbox}[colback=clrBackTip,colframe=clrFrameTip, title=Food for Thought]
+ {#1}%
+ \end{tcolorbox}
+ }
+
+\NewDocumentEnvironment{Cheffy}{+m}
+ {
+ \begin{tcolorbox}[colback=clrBackCheffy,colframe=clrFrameCheffy, title=Let's Get Cheffy]
+ {#1}%
+ \end{tcolorbox}
+ }
+
+\NewDocumentEnvironment{ChefNotes}{+m}
+ {
+ \begin{tcolorbox}[colback=clrBackNotes,colframe=clrFrameNotes,title=Chefnotes]
+ \ChefNote{}{#1}%
+ \end{tcolorbox}
+ }
+\end{MyVerbatim}
+
+\section{Odds and Ends}
+
+This section includes a number of cooking-related commands that were included in our preamble. Some you may find useful; others, not so much. Even if not right for your cookbook, we hope you can use the ideas here to make your own \Quote{helper} commands.
+
+\subsection{Various Simple but Useful Commands/Defines}
+
+We present the code immediately below and selectively discuss that code following:
+
+\begin{MyVerbatim}
+\def\nl{\par} % see Q 96247 for why we defined \nl for use with pgfkeys
+
+\NewDocumentCommand \PreheatC{m}{Preheat oven to #1\Degrees convection.\thinspace\Oven}%
+\NewDocumentCommand \PreheatR{m}{Preheat oven to #1\Degrees regular oven.\thinspace\Oven}%
+
+\NewDocumentCommand \Tbl{o}{\IfNoValueTF{#1}{tablespoon }{tablespoon#1}}%
+\NewDocumentCommand \tsp{o}{\IfNoValueTF{#1}{teaspoon }{teaspoon#1}}%
+\NewDocumentCommand \Pd{o}{\IfNoValueTF{#1}{pound }{pound#1}}%
+\NewDocumentCommand \Ounce{o}{\IfNoValueTF{#1}{ounce }{ounce#1}}%
+\NewDocumentCommand \Degrees{o}{\IfNoValueTF{#1}{\TextDegree{} }{\TextDegree{}#1}}%
+
+\NewDocumentCommand \AxB{m m o}{{#1\thinspace{x}\thinspace#2}\IfValueT{#3}{#3}}%
+\NewDocumentCommand \AxBxC{m m m o}{%
+ {#1\thinspace{x}\thinspace#2\thinspace{x}\thinspace#3}\IfValueT{#4}{#4}}%
+
+\NewDocumentCommand \Inch{m}{{#1-inch}}%
+\NewDocumentCommand \EditNote{m}{{{\color{clrEditNote} #1}}}%
+\NewDocumentCommand \Quote{m}{{``#1''}}%
+
+\NewDocumentCommand \IngredientsSeparator{}{{\FontStepsDefault \CtrDots\CtrDots}}%
+\NewDocumentCommand \SeparateParagraphs{}{{\vskip 5pt}}%
+\NewDocumentCommand \Recipe{+m}{{\textit{\textsb{#1}}}}%
+\end{MyVerbatim}
+
+The definition of \Cmd{nl} is needed to get around a problem with the \pkg{pgfkeys} package (for handling \pkg{key=value} arguments), because \pkg{pgfkeys} does not allow use of \Cmd{par} in a \pkg{value}.
+
+There is a story behind the \Cmd{Preheat} commands. Traditionally, cookbooks have assumed the reader has only a regular (not convection) oven. We went back and forth on whether we should stick with tradition. When we surveyed friends and family most likely to use our cookbook, almost all had convection ovens. If we gave cooking times and temperatures only for regular ovens, those times and temperatures would be wrong for the vast majority of our readers. Our compromise was to include an \Cmd{Oven} image (drawn using the \pkg{tikz} package) after the \Cmd{Preheat} instructions. That oven acts as a reminder to the reader that they may need to adjust time and temperature based on their particular oven type. Of course, even if the reader has the indicated oven type, it also acts as a reminder that each oven is different -- they should adjust if their oven normally cooks hotter or cooler. If the \Cmd{Oven} image is too quirky for you, just remove it from the \Cmd{Preheat} commands.
+
+The five commands (beginning with \Cmd{Tbl} and ending with \Cmd{D}egrees) first came about due to indecision. When first entering our recipes, we couldn't decide whether \Quote{teaspoon} and \Quote{tablespoon} should be spelled our or abbreviated. We put off the decision by using these commands, which could be redefined later based on our final decision. We quickly ran into a problem in cases where we wanted no space after the command, such as plurals (needing an 's' after tablespoon), punctuation or closed parenthesis. That lead to the current approach, with an optional argument that is appended without an space; without the optional argument, a space is automatically inserted.
+
+The next two commands (\Cmd{AxB} and \Cmd{AxBxC}) are used to get the right spacing when you want \Quote{5 x 7} or \Quote{5 x 7 x 2}. By using \Cmd{thinspace}, we believe the results are better: e.g.: \Quote{5\thinspace{x}\thinspace{7}} and \Quote{5\thinspace{x}\thinspace{7}\thinspace{x}\thinspace{2}}. We also use the same optional argument technique as with teaspoon.
+
+We use the \Cmd{EditNote} command to insert editing notes {\color{red}{(in red)}} in the cookbook, allowing comments and notes at places that need some further work. The \Cmd{Quote} command ensures that quote marks around text are the correct shape for beginning and ending quotes.
+
+In some recipes, there is a logical separation of ingredients into two parts. The \Cmd{IngredientsSeparator} command provides a visual marker (6 center dots) for that separation.
+
+\subsection{\Cmd{BakeUntil}}
+
+No doubt, your collection of recipes come from all sorts of sources, many no longer even known to you. There is no standard way to describe the steps to make a recipe, so your recipes likely vary substantially in the ordering and wording used to describe common recipe steps. It is good goal to make your cookbook recipes as consistent as possible in this regard.
+
+One place we constantly ran across this issue is in \Quote{Bake Until} instructions. We decided to standardize our instruction by use of a \Cmd{BakeUntil} command. This command takes one key/value style argument.
+
+The key/value options are as follows:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item \textbf{[Min=]} Required. The minimum baking time.
+ \item \textbf{[Max=]} Optional. The maximum baking time.
+ \item \textbf{[TPick=]} Optional. If equal to 1, then the \Quote{until} is \Quote{until toothpick tests clean}
+ \item \textbf{[GBrown=]} Optional. If equal to 1, then the \Quote{until} is \Quote{until golden brown}
+ \item \textbf{[Until=]} Optional. Use this if you want any other \Quote{until} phrase.
+\end{itemize}
+
+Here are three examples:
+
+\begin{MyVerbatim}
+\BakeUntil[Min=15, Max=18, GBrown=1]
+\BakeUntil[Min=15, TPick=1]
+\BakeUntil[Min=15, Max=18, Until=until firm to the touch]
+\end{MyVerbatim}
+
+The results:
+
+\vspace{5pt}
+\quad Bake about 15-18 minutes, until golden brown
+
+\quad Bake about 15 minutes, until toothpick tests clean
+
+\quad Bake about 15-18 minutes, until firm to the touch
+
+\vspace{5pt}
+Following is the code defining the \Cmd{BakeUntil} command:
+
+\begin{MyVerbatim}
+\pgfkeys{
+ /BakeUntil/.is family, /BakeUntil,
+ default/.style = {Min = 0, Max = 0, TPick = 0, GBrown = 0, Until = \empty},
+ Min/.estore in = \BkMin,
+ Max/.estore in = \BkMax,
+ TPick/.estore in = \BkTPick,
+ GBrown/.estore in = \BkGBrown,
+ Until/.estore in = \BkUntil,
+}
+
+\NewDocumentCommand \BakeUntil{m}{%
+ \pgfkeys{/BakeUntil, default, #1}%
+ \newcount\MyCount \MyCount = \BkMax%
+ \newcount\MyCase%
+ {Bake about \BkMin}%
+ \ifnum\MyCount > 0 {-\BkMax}\fi
+ { minutes}%
+ \ifx\BkUntil\empty \MyCase = 0 \else \MyCase = 1 \fi%
+ \ifnum\BkTPick = 1 \MyCase = 2 \fi%
+ \ifnum\BkGBrown = 1 \MyCase = 3 \fi%
+ \ifcase\MyCase% '0' case - do nothing
+ \or {, \BkUntil}% '1' case - use the "Until" text
+ \or {, until toothpick tests clean}% '2' case - TPick
+ \or {, until golden brown}% '3' case - GBrown
+ \fi
+}
+\end{MyVerbatim}
+
+
+\subsection{A Few Other Commands}
+
+\textbf{Copyright}. We establish the environment for the copyright page. In that environment: (1) the font size is set to 9 points, (2) there is no indentation of the first line of a paragraph, and (3) all of the text is pushed down (as far as possible) to the bottom of the page.
+
+\begin{MyVerbatim}
+\NewDocumentEnvironment{CopyrightPage}{} % See 31186
+ {\FontCopyrightPage\setlength{\parindent}{0pt}\par\vspace*{\fill}}
+ {\clearpage}
+\end{MyVerbatim}
+
+\noindent \textbf{Hidden Lines}. When listing recipe ingredients and steps, the \pkg{multicol} environment matches the lengths of the first and second columns. There are some cases where the results don't look quite right. For example, the ingredients may take up \textit{almost} all of the first column, but not quite. So the listing of steps begins with one (lonely) line in the first column. We use the \Cmd{InsertHiddenLines} command to insert an extra (non-visible) ingredient that tricks the \pkg{multicol} environment into moving the first line of the recipe steps to the second column.
+
+The \Cmd{InsertHiddenLines} command takes one parameter: the number of hidden lines to insert:
+
+\begin{MyVerbatim}
+\newcount\LineCount
+\NewDocumentCommand \InsertHiddenLines{m}{%
+ \LineCount = #1
+ {%
+ \newcount\foo \foo=0
+ \loop % \loop starts the construct ended by \repeat
+ \phantom{.}\par \advance \foo by 1
+ \ifnum \foo < \LineCount \repeat % \repeat also “serves as†the \fi to the \ifnum
+ }%
+}
+\end{MyVerbatim}
+
+\section{Handling of Long Recipes}
+
+The code for the \Cmd{RecipeStory} command and the \pkg{IngredientsAndSteps} environment is actually more complicated than was shown above. In both cases, the actual code includes a rarely-used optional parameter. For a longer recipe, these optional parameters allow certain tweaks to the recipe layout that may allow you to keep the recipe name plus the full text of the ingredients and steps on one page.
+
+\subsection{The \Quote{Real} \Cmd{RecipeStory} Command}\MyLabel{RealRecipeStory}
+
+In our standard setup, the recipe story comes after the recipe name and before the ingredients and steps. One potential problem is that the length of the recipe story may cause the ingredients and steps to continue past the bottom of the current page. To avoid that problem, we designed the \Cmd{RecipeStory} command to include an option of dividing the recipe story into two parts. That allows one part (or none) to print before the ingredients and steps and the remaining part to print after.
+
+The parameters for the actual \Cmd{RecipeStory} command:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item \textbf{[Arg \#1]} Optional. Permitted values: non-negative integers less than or equal to the number of lines in the recipe story. If a value is provided, then the given number of lines (possibly zero) of the recipe story will be printed \textit{before} the ingredients and steps. To print the remaining lines after the ingredients and steps, you issue the \Cmd{Finish RecipeStory} command.
+ \item \textbf{[Arg \#2]} Required. This is the text of the recipe story. As mentioned above, this may also include many of the \latex text markup commands. (However, if you use the optional argument, your \latex code should not change the height of the baseline from the predefine \Cmd{RStoryFontBaseline} value).
+\end{itemize}
+
+The actual code follows:
+
+\begin{MyVerbatim}
+\def\RecipeStoryIndent{20 pt}
+\newbox\StoryBox
+\newbox\StoryBoxA
+\NewDocumentCommand \RecipeStory {o +m} % arg1 = optional = lines for first part
+{ % arg2 = story text
+\setbox\StoryBox\vbox
+ {
+ \FontRecipeStory
+ \leftskip=\RecipeStoryIndent \rightskip=\leftskip % Q 66332
+ {#2\par} % the \par needed by \lettrine
+ }
+ \IfNoValueTF {#1} % NoValue=TRUE or NoValue=FALSE?
+ {\unvbox\StoryBox} % NoValue=TRUE, so flush the full StoryBox
+ { % handle the NoValue=FALSE case
+ \ifnum #1 > 0 % > 0 means we split the story into two part; print the first part here
+ { % = 0 means ALL of story is deferred
+ \setbox\StoryBoxA=\vsplit\StoryBox to #1\dimexpr \RStoryFontBaseline %
+ \unvbox\StoryBoxA%
+ }
+ \fi
+ }
+}
+
+\NewDocumentCommand \FinishRecipeStory{}%
+ {\ifvoid\StoryBox \else \smallskip\unvbox\StoryBox\par\medskip\fi} %
+\end{MyVerbatim}
+
+\subsection{The \Quote{Real} \pkg{IngredientsAndSteps} Environment}\MyLabel{RealIngStepEnv}
+
+There is one more thing to try if splitting the recipe story, above, does not work to fit the recipe name plus ingredients and steps all on one page. We have coded the \pkg{IngredientsAndSteps} environment to provide some additional options.
+
+In it default mode, the \pkg{IngredientsAndSteps} environment simply: (1) creates a two-column environment, and (2) sets the \Cmd{FontIngredients} and \Cmd{FontSteps} font selection commands to use their default font size of 10.95 points.
+
+Using an optional parameter with a key/value interface, the the \pkg{IngredientsAndSteps} environment can be used to change (temporarily) the default text width and default font size. By increasing the text width and/or decreasing the font size for the ingredients and steps, it might be possible to fit the recipe on one page. The key/value options are as follows:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item \textbf{[AdjIFont=]} Default value = 1. This is a floating point number that indicates the size you want the \Cmd{FontIngredients} font, computed as a ratio of the default size. For example, if AdjIFont=0.92, then the font would be set to 92 percent of its default size. IMPORTANT: This is the \Quote{controlling} ratio for all font parameters. If any of the other font parameters are set to 0 or not entered, then that other parameter will have the same value as set here.
+ \item \textbf{[AdjIBaseline=]} Default value = 0. This is a floating point number that indicates the size you want the \Cmd{FontIngredients} baseline, computed as a ratio of the default baseline size. For example, if AdjIBaseline=0.92, then the ingredient font's baseline would be set to 92 percent of its default size. If 0 or not entered, then AdjIBaseline = AdjIFont.
+ \item \textbf{[AdjSFont=]} Default value = 0. This is a floating point number that indicates the size you want the \Cmd{FontSteps} font, computed as a ratio of the default size. For example, if AdjIFont=0.92, then the font would be set to 92 percent of its default size. If 0 or not entered, then AdjSFont = AdjIFont.
+ \item \textbf{[AdjSBaseline=]} Default value = 0. This is a floating point number that indicates the size you want the \Cmd{FontSteps} baseline, computed as a ratio of the default baseline size. For example, if AdjIBaseline=0.92, then the steps font's baseline would be set to 92 percent of its default size. If 0 or not entered, then AdjSBaseline = AdjIFont.
+ \item \textbf{[AddWidth=]} Default value = 0. This is amount (taken as points) that you want to increase both the left and right margins. So, if AddWidth=5, then the text width will be increased by 5 points on both the left and right margins.
+\end{itemize}
+
+Following is the code defining the \pkg{IngredientsAndSteps} environment:
+
+\begin{MyVerbatim}
+\usepackage{multicol} % allows multiple column environments
+\usepackage[strict]{changepage} % for \adjustwidth
+\usepackage{xfp} % for fpeval floating point macro
+
+\pgfkeys{ /IngredientsAndSteps/.is family, /IngredientsAndSteps,
+ default/.style = {AdjIFont = 1, AdjIBaseline = 0,
+ AdjSFont = 0, AdjSBaseline = 0,
+ AddWidth = 0, RaggedCols = 0},
+ AdjIFont/.estore in = \AdjustIFont,
+ AdjIBaseline/.estore in = \AdjustIBaseline,
+ AdjSFont/.estore in = \AdjustSFont,
+ AdjSBaseline/.estore in = \AdjustSBaseline,
+ AddWidth/.estore in = \AddPageWidth,
+ RaggedCols/.estore in = \RaggedColumns,
+}
+
+\newdimen\IFont \newdimen\IBase \newdimen\SFont \newdimen\SBase \newdimen\AddWidth
+
+\NewDocumentEnvironment{IngredientsAndSteps}{o}
+{ % Do the before-environment setup:
+\IfNoValueTF {#1}%
+ % Handle the simple case = no optional key/value argument:
+ {\AddWidth = 0 pt}
+ % Handle the special case = there IS an optional key/value argument:
+ {
+ \pgfkeys{/IngredientsAndSteps, default, #1}%
+
+ \IFont = \AdjustIFont pt
+ \IBase = \AdjustIBaseline pt
+ \SFont = \AdjustSFont pt
+ \SBase = \AdjustSBaseline pt
+ \AddWidth = \AddPageWidth pt
+
+ \ifdim\IBase = 0 pt \IBase = \IFont \fi
+ \ifdim\SFont = 0 pt \SFont = \IFont \fi
+ \ifdim\SBase = 0 pt \SBase = \IFont \fi
+
+ \RenewDocumentCommand\FontIngredients{}{\FontIngDefault\fontsize{\fpeval{\StdIFontSize * \IFont}}
+ {\fpeval{\StdIBaseline * \IBase}}\selectfont}
+ \RenewDocumentCommand\FontSteps{}{\FontStepsDefault\fontsize{\fpeval{\StdSFontSize * \SFont}}
+ {\fpeval{\StdSBaseline * \SBase}}\selectfont}
+ }
+ % Now, finish setup:
+\adjustwidth{-\AddWidth}{-\AddWidth}
+\begin{multicols}{2}%
+} % End of the before-environment setup
+ % Now do the after-environment cleanup:
+{
+\end{multicols}
+\endadjustwidth
+ % We need to restore the fonts to default size IF there was an optional key/value argument:
+\IfValueT {#1}
+ {
+ \RenewDocumentCommand \FontIngredients {}{\FontIngDefault}
+ \RenewDocumentCommand \FontSteps {}{\FontStepsDefault}
+ }
+} % End of the "after environment" cleanup
+\end{MyVerbatim}
+
+\section{Adding Images in the Chapter Intro}
+
+You may wish to strategically place images in the middle of the \textit{chapter intro} text. For example, on the first page of a chapter, you may begin with the \textit{chapter intro} text, then include image(s) at the bottom of that first page, and then complete the \textit{chapter intro} text on the next page.
+
+\subsection{The \Quote{Real} \Cmd{ChapterIntro} Command}\MyLabel{RealChapterIntro}
+
+The code for the \Cmd{ChapterIntro} command is shown below. It allows for splitting the \textit{chapter intro} into two parts and is essentially identical to the code for the \Cmd{RecipeStory} command. For the use of the optional first argument, see the \Cmd{RecipeStory} command (page \pageref{RealRecipeStory}). To print the second part of the \textit{chapter intro} text, you issue the \Cmd{FinishChapterIntro} command.
+
+\begin{MyVerbatim}
+\newbox\IntroBox
+\newbox\IntroBoxA
+\NewDocumentCommand \ChapterIntro {o +m} % arg1 = optional = lines for first part
+{ % arg2 = chapter intro text
+\setbox\IntroBox\vbox
+ {
+ \FontChapterIntro {#2\par}% the \par needed by \lettrine
+ }
+\IfNoValueTF {#1} % NoValue=TRUE or NoValue=FALSE?
+ {\unvbox\IntroBox} % NoValue=TRUE, so flush the full IntroBox
+ { % handle the NoValue=FALSE case
+ \ifnum #1 > 0 % > 0 means we split the story into two part; print the first part here
+ { % = 0 means ALL of story is deferred
+ \setbox\IntroBoxA=\vsplit\IntroBox to #1\dimexpr \CIntroFontBaseline %
+ \unvbox\IntroBoxA %
+ }
+ \fi
+ }
+}
+
+\NewDocumentCommand \FinishChapterIntro{}%
+ {\ifvoid\IntroBox \else \smallskip\unvbox\IntroBox\par\medskip\fi} %
+\end{MyVerbatim}
+
+\newpage
+\part{The PDF File}
+
+We have two separate goals for the PDF file created by \latex[.] We need a PDF file in the proper form to submit to a print-on-demand printer. We also need a PDF file that is a digital version of the cookbook, but also includes bookmarks and links. Unfortunately, the two styles of PDF files are not identical and therefore require different compile-time options.
+
+The best way to show the differences between the digital and print-on-demand compiles is to first describe our setup for the digital cookbook. We will then describe the changes needed to generate the print-on-demand PDF file.
+
+\section{The Digital Cookbook}
+
+In the digital version of the cookbook, we would like to include bookmarks and other links to content. Specifically, we would like:
+
+\begin{itemize}[label=\textbullet, leftmargin=*, itemsep=1pt, parsep=1pt]
+ \item Top-level bookmarks equal to the entries in the Table of Contents.
+ \item Second-level bookmarks for each recipe (associated with its top-level cookbook chapter).
+ \item For the recipe Index, links back to each recipe by clicking on the recipe's indicated page number.
+ \item Within the cookbook main text, where there is a page number cross-reference to another recipe, a link back to that recipe by clicking on the cross-reference page number.
+\end{itemize}
+
+We implement these bookmarks and links by using the \pkg{hyperref} and \pkg{bookmark} packages. First, we load the packages (and set the color of the links):
+
+\begin{MyVerbatim}
+\usepackage[bookmarks=true,colorlinks=true, allcolors=clrHyperRef]{hyperref}
+\usepackage{bookmark} % Q 247158 shows Heiko (the author) loads both hyperref and bookmark
+\end{MyVerbatim}
+
+To create a bookmark/link for each recipe, we define the \Cmd{RecipeBookmark} command, which will be called by the \Cmd{RecipeNameAndYield} command. (The [1] in \Cmd{pdfbookmark} makes the recipe a second-level bookmark):
+
+\begin{MyVerbatim}
+\newcounter{ctrRecipe} % initially set to zero by \newcounter macro
+\NewDocumentCommand \RecipeBookmark{m}{%
+ \ifx\%1\empty\relax\else\stepcounter{ctrRecipe}\pdfbookmark[1]{#1}{Recipe\arabic{ctrRecipe}}\fi
+}
+\end{MyVerbatim}
+
+To create a linkable \Cmd{label} to a recipe, we define the \Cmd{RecipeLabel} command (note: \Cmd{phantomsection} is from \pkg{hyperref} and marks the linkable location of the recipe). Our \Cmd{RecipePageNo} command then uses \Cmd{pageref} to display the page number and (via \pkg{hyperref}) provide a link to the recipe \Cmd{label}:
+
+\begin{MyVerbatim}
+\NewDocumentCommand \RecipeLabel{m}{\phantomsection\label{recipe:#1}}
+\NewDocumentCommand \RecipePageNo{m}{\pageref{recipe:#1}}
+\end{MyVerbatim}
+
+Finally, we define the \Cmd{CookbookIndex} command (called from \pkg{cb-frontmatter.tex}) to create the recipe Index, make the Index a top-level part of the bookmarks, and include the Index in the Table of Contents:
+
+\begin{MyVerbatim}
+\NewDocumentCommand \CookbookIndex{}
+{
+\cleardoublepage % flush all material and clear until you start new odd numbered (recto) page
+\phantomsection\addcontentsline{toc}{chapter}{\indexname} % see also Q 59619
+\printindex
+}
+\end{MyVerbatim}
+
+\section{The Print-On-Demand Cookbook}
+
+There are generally stricter requirements for PDF files submitted for print-on-demand printing. We discuss the various issues below.
+
+\subsection{Embedded Fonts}
+
+Your print-on-demand company will require that all of your fonts are embedded in the PDF file. In most cases, it will be sufficient to include an \Quote{embedded subset} (i.e., includes only the glyphs that were actually used). However, we note Q 24005, where the questioner stated that the print-on-demand company lulu.com requires full font embedding. If that happens to you, a solution is provided at that question. But, as stated there, many font licenses disallow full font embedding. Check your font license if that situation arises.
+
+We note that our compiled PDF file includes an embedded subset of our fonts without any special or additional steps. You should still double-check your PDF file to make sure your fonts are embedded.
+
+As discussed at Section \ref{Glyphs} (page \pageref{Glyphs}), to avoid any unnecessary font issues, it is best to avoid loading any font you do not really need. For that reason, we relied on our already loaded fonts (rather than relying on \latex macros) for the degree, copyright, bullet and center (or mid) dot glyphs.
+
+\subsection{Bookmarks, Annotations, and Comments}
+
+Your PDF file should not include any bookmarks, links, annotations or comments. Because our digital cookbook includes bookmarks and links, we will need different compile-time options. We handle that by making a few small changes to the preamble. Near the top of the preamble, we use \Cmd{newif} to create a new conditional: \Cmd{ifHyperRef}. We set the value to \Cmd{HyperReftrue} if we are making the digital cookbook, and to \Cmd{HyperReffalse} if we are making the printed cookbook. For example, for the printed cookbook:
+
+\begin{MyVerbatim}
+ \newif\ifHyperRef \HyperReffalse
+\end{MyVerbatim}
+
+We also modify the first two code snippets shown in the above discussion of the Digital Cookbook. Below, the \pkg{hyperref} and \pkg{bookmark} packages are only loaded if we have \Cmd{HyperReftrue}. If \Cmd{HyperReffalse}, we only need to set the \Cmd{phantomsection} and \Cmd{RecipeBookmark} commands to do nothing:
+
+\begin{MyVerbatim}
+\ifHyperRef
+ \usepackage[bookmarks=true,colorlinks=true, allcolors=clrHyperRef]{hyperref}
+ \usepackage{bookmark}
+
+ \newcounter{ctrRecipe}
+ \NewDocumentCommand \RecipeBookmark{m}{%
+ \ifx\%1\empty\relax\else\stepcounter{ctrRecipe}\pdfbookmark[1]{#1}{Recipe\arabic{ctrRecipe}}\fi
+}
+\else
+ \providecommand\phantomsection{}% Q 44088
+ \NewDocumentCommand \RecipeBookmark{m}{}%
+\fi
+\end{MyVerbatim}
+
+\begin{SideNote}
+ {
+ You may run into anomalies in your compile if you switch back and forth between \Cmd{HyperReftrue} and \Cmd{HyperReffalse}. Because the \pkg{*.ind} index file was created with the \Quote{other} option, in the first switched compile, the contents of that file may contain unknown commands causing compile errors. Just run the compile again and all should be OK.
+ }
+\end{SideNote}
+
+
+\subsection{Trim Size, Crop Marks and Other Printer's Marks}
+
+Almost all print-on-demand companies require: (1) that the trim size indicated in the PDF file matches the trim size requested for the printed cookbooks, and (2) that there are no crop marks or other printer's marks in the submitted PDF file.
+
+The \Cmd{ifCookbookDraft} logic discussed on page \pageref{Geometry} handles the trim size, plus the crop marks and other printer's marks made by the \pkg{geometry} package. We also use \Cmd{ifCookbookDraft} logic to only load the \pkg{layout} and \pkg{lipsum} packages when we are in draft mode:
+
+\begin{MyVerbatim}
+\ifCookbookDraft
+ \usepackage{lipsum, layout}
+\fi
+\end{MyVerbatim}
+
+\noindent Note that some print-on-demand printers (e.g., Kindle Direct Publishing) will not accept a PDF file that includes filler from the \pkg{lipsum} package (or similar).
+
+\subsection{PDF/X}
+
+Although very few print-on-demand companies \textit{require} PDF/X compliant documents, it is almost always their preferred format. We have not taken the extra steps needed for full PDF/X compliance. However, you may wish to familiarize yourself with this (very large) topic. A good starting point is the documentation for the \pkg{pdfx} package.
+
+If you use \pkg{pdfx} or other methods of entering metadata (such as title, author, etc.) into you PDF file, be sure the entered information \boldit{exactly} matches the information you give to your print-on-demand company in their submittal forms.
+
+\subsection{Other Print-on-Demand Issues}
+
+Of course, document security of any type must not be used. For the best results, all images should be sized at 100\%, flattened to one layer and inserted into your file at a minimum resolution of 300 dots per inch. You should expect that all transparent objects will be flattened. See also Section \ref{Color} on page \pageref{Color} for consideration relating to color.
+
+\newpage
+\part{Examples}
+
+In this part, we present and discuss some example code (mostly for entering recipes). You will see \Quote{in action} the use of various commands and environments, and you will see how we use some of the helper macros. We assume you have downloaded and installed the \pkg{makecookbook} package, and that you are ready to compile the sample cookbook that uses \pkg{mycookbook} as its root directory.
+
+Recall that the \pkg{mycookbook/tex} directory holds two example chapters of recipes. To make those recipes easier to reference here, we name the first recipe \textbf{\Quote{A -- (With Recipe Name Here)}}, the second recipe \textbf{\Quote{B -- (With Recipe Name Here)}}, and so on. Here, we will refer to the included recipes by their first alphabetic letter only (e.g., \Quote{see recipe \textbf{D}}).
+
+\section{\Cmd{RecipeNameAndYield} Command}
+
+\subsection{Recipe A}
+
+Recipe \textbf{A} presents the simplest case of the \Cmd{RecipeNameAndYield} command. We enter only the recipe name (no yield, no special Index entries, no cross-reference label). Our actual code:
+
+\begin{MyVerbatim}
+\RecipeNameAndYield{Name=A -- Lemon Roasted Potatoes}
+\end{MyVerbatim}
+
+\subsection{Recipe B}
+
+In recipe \textbf{B} the \Cmd{RecipeNameAndYield} command includes an entry for \pkg{Yield=}. We also wanted the Index to hold only the actual recipe name (without the leading \textbf{B}), so we included \pkg{NoIdxName=1} and \pkg{IndexA=Pumpkin Pancakes}.
+
+On second thought, we decided a leading \textbf{B} was needed so you could use the index to find the recipe. We therefore added \pkg{IndexB=B!Pumpkin Pancakes}, which also allowed us to demonstrate the sub-entry indicator character !\footnote{see the \pkg{makeindex} package at \pkg{ctan.org/pkg/makeindex} for documentation of the \Cmd{index} command.} and create a sub-entry for this recipe. (Yes, it looks a little funny. In the real world, a sub-entry only looks right if there are multiple sub-entries under the entry).
+
+Check the Index entries for recipe \textbf{A} and recipe \textbf{B} to see the differences. Please note that you \textit{do not} need to include \pkg{NoIdxName=1} when you use \pkg{IndexA=} (You can have \textit{both} the original name and up to three alternate names).
+
+\begin{MyVerbatim}
+\RecipeNameAndYield{Name=B -- Pumpkin Pancakes, Yield=Yield: 6 Pancakes, NoIdxName=1,
+ IndexA=Pumpkin Pancakes, IndexB=B!Pumpkin Pancakes}
+\end{MyVerbatim}
+
+\subsection{Recipe C}
+
+Recipe \textbf{C} demonstrates use of \pkg{XRefLabel=} to create a cross-reference label for this recipe. (See recipe \textbf{D} for the reference back to this recipe). Our actual code:
+
+\begin{MyVerbatim}
+\RecipeNameAndYield{Name=C -- Pesto, XRefLabel=Pesto}%
+\end{MyVerbatim}
+
+\subsection{Recipe D}
+
+Recipe \textbf{D} demonstrates two things regarding the \Cmd{RecipeNameAndYield} command: (1) the use of \Cmd{nl} to manage multi-line text for the recipe or yield, and (2) the use of an extra set of curly braces when the key/value text includes commas. Our actual code:
+
+\begin{MyVerbatim}
+\RecipeNameAndYield{Name=D -- Pasta Genovese,
+ Yield={(Pasta with Pesto, Potatoes and Green Beans)\nl Makes 4 to 6 servings}}
+\end{MyVerbatim}
+
+\section{\Cmd{RecipeStory} Command}
+
+\subsection{Recipe A}
+
+Recipe \textbf{A} presents the typical case, using the \Cmd{RecipeStory} command \textit{without} the optional argument. We also demonstrate use of the \Cmd{lettrine} command. Our actual code:
+
+\begin{MyVerbatim}
+\RecipeStory{\lettrine{T}{his is a recipe} story. \lipsum[66]}
+\end{MyVerbatim}
+
+\subsection{Recipe E}
+
+Recipe \textbf{E} presents the special case, using the \Cmd{RecipeStory} command \textit{with} the optional argument. Note that our recipe is the same as recipe \textbf{A}, except we: (1) increased the length of the recipe story, and (2) included the optional argument to the \Cmd{RecipeStory} command ([8]) that prints only the first 8 lines of the recipe story before the recipe, with the balance printed at the location of the \Cmd{FinishRecipeStory} command. Our actual code:
+
+\begin{MyVerbatim}
+\RecipeStory[8]{\lettrine{T}{his is a recipe} story. \lipsum[1-3]}
+\end{MyVerbatim}
+
+
+\section{\pkg{IngredientsAndSteps} Environment}
+
+\subsection{Recipe A}
+
+Recipe \textbf{A} presents the typical case, using the \pkg{IngredientsAndSteps} environment \textit{without} the optional (key/value style) argument. In that case, they only thing the \pkg{IngredientsAndSteps} environment does is set up a two-column environment (using the \pkg{multicol} package) for entering the ingredients and steps. Our actual code (with pseudo-code for the \Cmd{ListIngredientsAndSteps} command):
+
+\begin{MyVerbatim}
+\begin{IngredientsAndSteps}
+ \ListIngredientsAndSteps{...ingredients...}{...steps...}
+\end{IngredientsAndSteps}
+\end{MyVerbatim}
+
+\subsection{Recipe F}
+
+Recipe \textbf{F} presents the special case, using the \pkg{IngredientsAndSteps} environment \textit{with} the optional (key/value style) argument. Here, we want to shrink the ingredients and steps fonts, and and their baselines, to 92\% of their default size. We also want to increase both the left and right margins by 5 points. Our actual code (with pseudo-code for the \Cmd{ListIngredientsAndSteps} command):
+
+\begin{MyVerbatim}
+\begin{IngredientsAndSteps}[AdjIFont=0.92, AddWidth=5]
+ \ListIngredientsAndSteps[Tomato Meat Sauce]{...ingredients...}{...steps...}
+ \ListIngredientsAndSteps[Béchamel]{...ingredients...}{...steps...}
+ \ListIngredientsAndSteps[Assembly]{...ingredients...}{...steps...}
+\end{IngredientsAndSteps}
+\end{MyVerbatim}
+
+Note that these values allow the recipe to fit on one page (try that recipe without any optional key/value entries). You might also try playing with the optional key/value entries by entering your own values. For example, set both fonts and their baselines to different values.
+
+\section{\Cmd{ListIngredientsAndSteps} Command}
+
+\subsection{Recipe A}
+
+Recipe \textbf{A} presents the typical case, using the \Cmd{ListIngredientsAndSteps} command \textit{without} its optional argument. The first required argument is the list of ingredients, and the second is the list of steps. Our actual code:
+
+\begin{MyVerbatim}
+\ListIngredientsAndSteps
+ { % begin ingredients
+ 2 \Pd[s] baby Dutch gold potatoes, washed and cut in half
+
+ \fr1/2 cup water
+
+ \fr1/4 cup extra-virgin olive oil
+
+ ...and the rest of the ingredients
+ } % end ingredients
+ { % begin steps
+ \PreheatC{375} \ChefNote
+
+ In a \Inch{\AxB{9}{13}} baking dish, combine all ingredients except parsley.
+
+ Roast for 30 minutes.
+
+ ...and the rest of the steps
+ } % end steps
+\end{MyVerbatim}
+
+\subsection{Recipe F}
+
+Recipe \textbf{F} presents the special case, using the \Cmd{ListIngredientsAndSteps} command \textit{with} its optional argument. This normally is needed when you have more than one listing of ingredients and steps (e.g., one for making the cake and one for making the frosting). Our actual code (mostly pseudo-code, and for clarity we also show the \pkg{IngredientsAndSteps} environment, but not its optional arguments):
+
+\begin{MyVerbatim}
+\begin{IngredientsAndSteps}
+ \ListIngredientsAndSteps[Tomato Meat Sauce]
+ {
+ ...ingredients...
+ }
+ {
+ ...steps...
+ }
+ \ListIngredientsAndSteps[Béchamel]
+ {
+ ...ingredients...
+ }
+ {
+ ...steps...
+ }
+ \ListIngredientsAndSteps[Assembly]
+ {
+ ...ingredients...
+ }
+ {
+ ...steps...
+ }
+\end{IngredientsAndSteps}
+\end{MyVerbatim}
+
+\subsection{Recipe I}
+
+Recipe \textbf{I} presents another special case. You might wish to divide the ingredients into separate groupings, each with a heading, but only have one grouping of recipe steps. We use the \Cmd{ListIngredientsAndSteps} command \textit{without} its optional argument. But we use the \Cmd{IngredientsHeading} helper command (page \pageref{IngredientsHeading}) to enter those heading within the listing of ingredients. Note the use of optional \pkg{Arg \#1} (for the second heading) -- that is the number of points of vertical skip before the heading. (Not really needed here, but it would be useful if the heading was not at the top of a column).
+
+\subsection{Recipes B, C and G}
+
+Our \pkg{IngredientsAndSteps} environment uses the \pkg{multicols} environment (from the \pkg{multicol} package). It creates a two-column environment for entering ingredients and steps. One of the features of the \pkg{multicols} environment is that it balances the lengths of the first and second column. In some instances, the result may not look right to you. For example, the ingredients may take up \textit{almost} all of the first column, but not quite. To balance the two columns, the \pkg{multicols} environment may put one line from the recipe steps in the first column.
+
+To work around the above problem, you can use the \Cmd{InsertHiddenLines} command. That command takes one mandatory parameter, which is the number of hidden lines to insert. Now look at the printed output for recipes \textbf{B}, \textbf{C} and \textbf{G}. You can probably see that we inserted, respectively, 1, 2 and 3 hidden lines at the bottom of the first column of those recipes.
+
+Recipe \textbf{B} also uses the \Cmd{IngredientsSeparator} command. That command provides a visual separation between ingredients. In this case, it separates the dry ingredients from the wet ingredients.
+
+\section{\Cmd{ChapterIntro} Command}
+
+\subsection{Chapter One}
+
+Chapter One presents the typical case, using the \Cmd{ChapterIntro} command \textit{without} the optional argument. We also demonstrate use of the \Cmd{lettrine} command. Our actual code:
+
+\begin{MyVerbatim}
+\ChapterIntro{
+ \lettrine{T}{his is the} chapter intro. \lipsum[1-3]
+}
+\end{MyVerbatim}
+
+\subsection{Chapter Two}
+
+Chapter Two presents the special case, using the \Cmd{ChapterIntro} command \textit{with} the optional argument. We wanted two side-by-side images at the bottom of the first page of the chapter. After a trial run, we calculated that the first 16 lines of the \textit{chapter into} text would fit (with the images) on page one. We print the balance of the \textit{chapter into} text with the \Cmd{FinishChapterIntro} command. Our actual code:
+
+\begin{MyVerbatim}
+\ChapterIntro[16]{\lipsum[1-3]}
+\SideBySide[LeftCaption={left caption}, RightCaption={right caption}]{image-a}{image-b}
+\FinishChapterIntro{}
+\end{MyVerbatim}
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/makecookbook/mycookbook/cb-idxstyle.ist b/macros/luatex/latex/makecookbook/mycookbook/cb-idxstyle.ist
new file mode 100644
index 0000000000..0ea4255595
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/mycookbook/cb-idxstyle.ist
@@ -0,0 +1,16 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This file is from a question and answer (answer by Enrico Gregorio) at:
+%
+% https://tex.stackexchange.com/questions/396898/weird-padding-using-imakeidx
+%
+% This file is author-maintained and is one of the files that, collectively,
+% make up the MAKECOOKBOOK bundle available at:
+%
+% https://ctan.org/pkg/makecookbook
+%
+% For additional information, please see the associated README file.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ delim_0 "\\betterdotfill "
+ delim_1 "\\betterdotfill "
+ delim_2 "\\betterdotfill "
diff --git a/macros/luatex/latex/makecookbook/mycookbook/cb-lettrine.cfl b/macros/luatex/latex/makecookbook/mycookbook/cb-lettrine.cfl
new file mode 100644
index 0000000000..f2fa4a0506
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/mycookbook/cb-lettrine.cfl
@@ -0,0 +1,44 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LICENSE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Copyright 2018 Terrence P. Murphy and Rosalie D'Amico.
+% This file may be distributed and/or modified under the conditions of the LaTeX Project
+% Public License (“LPPL”), either version 1.3c of this license or (at your option) any
+% later version. The latest version of this license is at:
+% http://www.latex-project.org/lppl.txt.
+% This file is author-maintained and is one of the files that, collectively, make up the
+% MAKECOOKBOOK bundle available at https://ctan.org/pkg/makecookbook
+% For additional information, please see the associated README file.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%% The settings below, for the Italianno font, were defined according to our visual tastes.
+%%% No mathematical rule based on the metrices was applied.
+%%% Though the result may not please you, it should be better than the default placement.
+%%% That said, comments are welcome.
+
+\LettrineOptionsFor{A}{loversize=0.15, findent=0.25\LettrineWidth, nindent=-0.07\LettrineWidth}
+\LettrineOptionsFor{B}{loversize=0.15, findent=0.12\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{C}{loversize=0.15, findent=0.14\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{D}{loversize=0.15, findent=0.15\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{E}{loversize=0.15, findent=0.20\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{F}{loversize=0.15, findent=0.34\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{G}{loversize=0.15, findent=0.16\LettrineWidth, nindent=0.00\LettrineWidth, depth=1}
+\LettrineOptionsFor{H}{loversize=0.15, findent=0.19\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{I}{loversize=0.15, findent=0.62\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{J}{loversize=0.15, findent=0.68\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{K}{loversize=0.15, findent=0.40\LettrineWidth, nindent=-0.18\LettrineWidth}
+\LettrineOptionsFor{L}{loversize=0.15, findent=0.05\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{M}{loversize=0.15, findent=0.21\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{N}{loversize=0.15, findent=0.28\LettrineWidth, nindent=-0.11\LettrineWidth}
+\LettrineOptionsFor{O}{loversize=0.15, findent=0.15\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{P}{loversize=0.15, findent=0.15\LettrineWidth, nindent=-0.18\LettrineWidth}
+\LettrineOptionsFor{Q}{loversize=0.15, findent=0.15\LettrineWidth, nindent=0.00\LettrineWidth, depth=1}
+\LettrineOptionsFor{R}{loversize=0.15, findent=0.07\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{S}{loversize=0.15, findent=0.18\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{T}{loversize=0.15, findent=0.64\LettrineWidth, nindent=-0.29\LettrineWidth}
+\LettrineOptionsFor{U}{loversize=0.15, findent=0.18\LettrineWidth, nindent=0.00\LettrineWidth}
+\LettrineOptionsFor{V}{loversize=0.15, findent=0.67\LettrineWidth, nindent=-0.43\LettrineWidth}
+\LettrineOptionsFor{W}{loversize=0.15, findent=0.43\LettrineWidth, nindent=-0.26\LettrineWidth}
+\LettrineOptionsFor{X}{loversize=0.15, findent=0.42\LettrineWidth, nindent=-0.23\LettrineWidth}
+\LettrineOptionsFor{Y}{loversize=0.15, findent=0.46\LettrineWidth, nindent=-0.39\LettrineWidth}
+\LettrineOptionsFor{Z}{loversize=0.15, findent=0.29\LettrineWidth, nindent=0.30\LettrineWidth, depth=1}
+
+\endinput
diff --git a/macros/luatex/latex/makecookbook/mycookbook/cb-preamble.tex b/macros/luatex/latex/makecookbook/mycookbook/cb-preamble.tex
new file mode 100644
index 0000000000..bf5e77529c
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/mycookbook/cb-preamble.tex
@@ -0,0 +1,762 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION 0 - LICENSE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Copyright 2018 Terrence P. Murphy and Rosalie D'Amico.
+% This file may be distributed and/or modified under the conditions of the LaTeX Project
+% Public License (“LPPLâ€), either version 1.3c of this license or (at your option) any
+% later version. The latest version of this license is at:
+% http://www.latex-project.org/lppl.txt.
+% This file is author-maintained and is one of the files that, collectively, make up the
+% MAKECOOKBOOK bundle available at https://ctan.org/pkg/makecookbook
+% For additional information, please see the associated README file.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION 1 - INITIAL SETUP %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\raggedbottom % Q320739 and Q65355
+\emergencystretch 3em % can also use for only parts of a document
+%\tracingmacros=1
+%\tracingcommands=1 % or =2
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % We use the TeX \newif macro to choose betweeen the makecookbook code and the code for
+ % our own cookbook. One of the key differences is our use of commercial fonts (Adobe Garamond
+ % Pro and Adobe Myriad Pro) vs. makecookbook's free fonts (EB Garamond and Lato).
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\newif\ifMakeCookbook \MakeCookbooktrue
+ % \newif to indicate whether \geometry (and other) settings are for draft or final form
+\newif\ifCookbookDraft \CookbookDrafttrue
+ % newif to indicate whether we are using the hyperref/bookmark packages
+\newif\ifHyperRef \HyperReftrue
+
+%************************* FIRST PACKAGES **************************************************
+% We load the packages that are used for multiple purposes. The single-purpose packages
+% will be loaded with their associated code to make their purpose clearer.
+%*******************************************************************************************
+\usepackage{%
+ xparse, % For \NewDocumentCommand and related
+ enumitem, % improvements to the standard list environments
+ pgfkeys, % For Key=Value arguments to commands
+ graphicx} % for including photos = \includegraphics
+
+\ifCookbookDraft
+\usepackage{lipsum, layout} %
+\fi
+%\usepackage{indentfirst} % use if you want first paragraphs indented; see Q 39227 (Warner)
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION 2 - FONTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%************ SECTION 2A - FONT PACKAGES ***************************************************
+\usepackage{fontspec} % Needed for our font handling -- how about [no-math] ??
+\usepackage{microtype} % Highly advised-READ UP to understand better; see Q 66052 and S.K. link
+
+%************ SECTION 2B - ESTABLISH ALL FONTS TO BE USED **********************************
+\ifMakeCookbook
+ \setmainfont{ebgaramond}[ % EB Garamond
+ Extension=.ttf,
+ UprightFont=*-regular, % this face includes small caps
+ ItalicFont=*-italic,
+ BoldFont=*-bold,
+ BoldItalicFont=*-bolditalic,
+ FontFace={sb}{n}{*-semibold}, % this face includes small caps
+ FontFace={sb}{it}{*-semibolditalic},
+ Ligatures=TeX,
+ Numbers=Lining] % !!! consider Numbers=OldStyle
+\else
+ \setmainfont{agaramondpro}[ % Abobe Garamond Pro
+ Extension=.otf,
+ UprightFont=*-regular, % this face includes small caps
+ ItalicFont=*-italic,
+ BoldFont=*-bold,
+ BoldItalicFont=*-bolditalic,
+ FontFace={sb}{n}{*-semibold}, % this face includes small caps
+ FontFace={sb}{it}{*-semibolditalic},
+ Ligatures=TeX,
+ Numbers=Lining]
+\fi
+
+\ifMakeCookbook
+ \setsansfont{lato}[ % Lato
+ Extension=.ttf,
+ UprightFont=*-regular, % \mdseries
+ ItalicFont=*-italic,
+ BoldFont=*-bold, % \bfseries
+ BoldItalicFont=*-bolditalic,
+ FontFace={sb}{n}{*-semibold},
+ FontFace={sb}{it}{*-semibolditalic},
+ FontFace={k}{n}{*-black},
+ FontFace={k}{it}{*-blackitalic},
+ Ligatures=TeX,
+ Numbers=Lining]
+\else
+ \setsansfont{myriadpro}[ % Adobe Myriad Pro
+ Extension=.otf, % None of the font faces include small caps
+ UprightFont=*-regular, % \mdseries
+ ItalicFont=*-it,
+ BoldFont=*-bold, % \bfseries
+ BoldItalicFont=*-boldit,
+ FontFace={sb}{n}{*-semibold},
+ FontFace={sb}{it}{*-semiboldit},
+ FontFace={k}{n}{*-black},
+ FontFace={k}{it}{*-blackit},
+ Ligatures=TeX,
+ Numbers=Lining] % the OldStyle '1' is not too good for ingredients
+\fi
+
+\newfontfamily\MyScriptFont{Italianno}[ % Italianno script font
+Extension=.otf,
+UprightFont=*-Regular-OTF, % This is the only face for this font
+Ligatures=TeX] % Otherwise, don't get -- converted to en dash, etc. Q 53413
+ % (and \textendash doesn't work that well with Italianno)
+
+%************ SECTION 2C - HANDLE THE SPECIAL FONT FACES ***********************************
+\NewDocumentCommand \sbseries {}{\fontseries{sb}\selectfont} % egreg uses \DeclareRobustCommand
+\DeclareTextFontCommand{\textsb}{\sbseries}
+\NewDocumentCommand \kseries {}{\fontseries{k}\selectfont} % egreg uses \DeclareRobustCommand
+\DeclareTextFontCommand{\textk}{\kseries}
+
+%************ SECTION 2D - SET COMMANDS TO SELECT FONTS ************************************
+\NewDocumentCommand \FontSteps {}{\rmfamily\mdseries}
+\NewDocumentCommand \FontStepsDefault {}{\rmfamily\mdseries}
+\NewDocumentCommand \FontIngredients {}{\sffamily\sbseries}
+\NewDocumentCommand \FontIngDefault {}{\sffamily\sbseries}
+\NewDocumentCommand \FontIngTitle {}{\sffamily\bfseries\itshape} % consider \kseries
+\NewDocumentCommand \FontChapterIntro {}{\rmfamily\fontsize{14}{16.8}\selectfont}
+\NewDocumentCommand \FontRecipeStory {}{\rmfamily\fontsize{13}{15.6}\selectfont}
+\NewDocumentCommand \FontCopyrightPage {}{\rmfamily\fontsize{9}{11}\selectfont}
+\NewDocumentCommand \FontChapterLabel {}{\rmfamily\fontsize{14.4}{18}\selectfont}
+\NewDocumentCommand \FontChapterTitle {}{\MyScriptFont\fontsize{40}{48}\selectfont}
+\NewDocumentCommand \FontRecipeName {}{\MyScriptFont\fontsize{24}{29}\selectfont}
+\NewDocumentCommand \FontLettrineText {}{\rmfamily\scshape} % consider adding \sbseries
+\NewDocumentCommand \FontTitleColorBox {}{\rmfamily\Large\bfseries}
+\NewDocumentCommand \FontTitlepageTitle {}{\MyScriptFont\fontsize{40}{48}\selectfont}
+\NewDocumentCommand \FontTitlepageAuthor{}{\rmfamily\sbseries\scshape\fontsize{14.4}{18}\selectfont}
+
+%************ SECTION 2E - SPECIAL HANDLING OF FRACTIONS ***********************************
+\def\fr#1/#2 {{\addfontfeatures{Fractions=On}#1/#2} } %
+\def\frx#1/#2 {{\addfontfeatures{Fractions=On}#1/#2}} %
+
+%************ SECTION 2F - SPECIAL GLYPHS NEEDED IN COOKBOOK *******************************
+\NewDocumentCommand \TextDegree {}{{\char176}} % or ^^^^00B0
+\NewDocumentCommand \Copyright {}{{\char169}} % or ^^^^00A9
+\NewDocumentCommand \TextBullet {}{{\char8226}} % or ^^^^2022
+\NewDocumentCommand \CtrDot {}{{\char183}} % or ^^^^00B7
+ % The following replaces $\cdots$ -- it is essentially identical and uses our fonts:
+\NewDocumentCommand \CtrDots{}{{\CtrDot\kern 0.2em\CtrDot\kern 0.2em\CtrDot\kern 0.2em}}%
+
+ % \ChefHat and \Oven are not actually glyphs - they were created (further below)
+ % with \MakeChefHat and \MakeOven using TIKZ
+\newsavebox{\HatBox}
+\AtBeginDocument{\savebox{\HatBox}[\hatwidth]{\MakeChefHat}}%
+\NewDocumentCommand \ChefHat {}{\usebox{\HatBox}}%
+\NewDocumentCommand \ChefNote {}{{\raisebox{.4ex}{\ChefHat}}}
+
+\newsavebox{\OvenBox}
+\AtBeginDocument{\savebox{\OvenBox}[\ovenwidth]{\MakeOven}}%
+\NewDocumentCommand \Oven {}{\usebox{\OvenBox}}%
+
+%************ SECTION 2G - FONT SIZE INFORMATION NEEDED IN CODE FURTHER BELOW ***************
+\def\StdIFontSize{10.95} % Needed in IngredientsAndSteps environment
+\def\StdSFontSize{10.95} % Needed in IngredientsAndSteps environment
+\def\StdIBaseline{13.6} % Needed in IngredientsAndSteps environment
+\def\StdSBaseline{13.6} % Needed in IngredientsAndSteps environment
+\def\RStoryFontBaseline{15.6pt} % Needed in \RecipeStory command; value from \FontRecipeStory
+\def\CIntroFontBaseline{16.8pt} % Needed in \ChapterIntro command; value from \FontChapterIntro
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION 3 - PACKAGES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%************ SECTION 3A - GEOMETRY ********************************************************
+\usepackage{geometry} %
+
+\ifCookbookDraft
+\geometry{paper=letterpaper, % the physical paper size during draft mode
+layoutsize={8in,10in}, % always use intended final paper size for layout
+layouthoffset=0.25in, % center the "layout" horizontally
+layoutvoffset=0.5in, % center the "layout" vertically
+%showframe, % use when needed
+showcrop}
+\else
+\geometry{papersize={8in,10in}} % the physical paper size in final production mode
+\fi
+ % The following are the same in draft and final:
+\geometry{nomarginpar, % do not reserve space for margin notes
+bindingoffset=0.375in,
+inner=0.5in,
+outer=1in,
+top=0.75in,
+bottom=1in,
+footskip=40pt} % default seems to be 27pt
+
+%************ SECTION 3B - IMAKEIDX PACKAGE ************************************************
+\usepackage{imakeidx} % supports creation of an index (here, a recipe index)
+
+ %%% COMMENT OUT THE FOLLOWING CODE IF YOU WANT THE STANDARD BOOK CLASS INDEX FORMAT %%%%%%
+\makeatletter
+\def\@idxitem{\par\hangindent 10pt} % NOT needed unless you want to fine tune hanging indent
+\newcommand{\betterdotfill}%
+ {\leavevmode \nobreak\cleaders \hb@xt@ .44em{\hss .\hss }\hskip .5em plus 1fill \kern \z@}
+\makeatother
+\makeindex[options=-s cb-idxstyle] % use cb-idxstyle.ist for style; Q 132465 & Q 396898
+ %%% END OF SPECIAL INDEX FORMAT %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%************ SECTION 3C - LETTRINE PACKAGE ************************************************
+\usepackage{lettrine} % Sets first character to multi-line height with various options
+\renewcommand{\LettrineFontHook}{\MyScriptFont\color{clrLettrineBig}} % for the BIG first letter
+\renewcommand{\LettrineTextFont}{\color{clrLettrineSmall}\FontLettrineText} % for the following text
+\renewcommand{\DefaultOptionsFile}{cb-lettrine.cfl} % for the lettrine package
+
+%************ SECTION 3D - FANCYHDR PACKAGE ************************************************
+\usepackage{emptypage} % per Q 360739 replaces \clearpage{\pagestyle{empty}\cleardoublepage} which
+ % would have to be issued at the end of each chapter and possibly the last
+ % page of the frontmatter and as needed in the backmatter
+\usepackage{fancyhdr}
+
+\fancypagestyle{plain}{ % Need to redefine the "plain" style
+ \fancyhf{} % clear the header and footer
+ \renewcommand{\headrulewidth}{0pt} % use 0 to disable header ruler line
+ \renewcommand{\footrulewidth}{0.2pt}
+ \fancyfoot[RO, LE] {Page \thepage}
+}
+
+\makeatletter % must be OUTSIDE of the command - see Q 444532
+\fancypagestyle{main}{ % identical to plain, except non-\chapter pages in mainmatter
+ \fancyhf{}
+ \renewcommand{\headrulewidth}{0pt}
+ \renewcommand{\footrulewidth}{0.2pt}
+ \fancyfoot[RO, LE] {Page \thepage}
+ \fancyfoot[CE,CO]{\if@mainmatter \leftmark\fi} % See Q340125
+}
+\makeatother
+
+%************ SECTION 3E - TITLESEC PACKAGE ************************************************
+\usepackage{titlesec}
+\titleformat{\chapter}[display]
+{\filleft\FontChapterLabel}{\chaptertitlename\ \thechapter}{1pt}
+{\titlerule\vspace{1ex}\raggedleft\FontChapterTitle}
+\titlespacing*{\chapter}{0pt}{20pt}{20pt}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION 4 - CERTAIN SIMPLE MACROS %%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%************ SECTION 4A - COLORS **********************************************************
+\usepackage{xcolor}
+\definecolor{clrWhite}{cmyk}{0.00, 0.00, 0.00, 0.00} % true white
+\definecolor{clrBackTip}{rgb}{1.0, 0.95, 0.95} % red!5!white
+\definecolor{clrFrameTip}{rgb}{0.75, 0.0, 0.0} % red!75!black
+\definecolor{clrBackCheffy}{rgb}{1.0, 1.0, 1.0} % white
+\definecolor{clrFrameCheffy}{rgb}{0.0, 0.0, 0.75} % blue!75!black
+\definecolor{clrBackNotes}{rgb}{1.0, 1.0, 1.0} % white
+\definecolor{clrFrameNotes}{rgb}{0.0, 0.75, 0.0} % green!75!black
+\definecolor{clrLettrineBig}{gray}{0.25} % 0.0 = black; 1.0 = white
+\definecolor{clrLettrineSmall}{gray}{0.25} % 0.0 = black; 1.0 = white
+\definecolor{clrIngTitle}{cmyk}{0.00, 1.00, 1.00, 0.00} % true red
+\definecolor{clrEditNote}{cmyk}{0.00, 1.00, 1.00, 0.00} % true red
+\definecolor{clrHyperRef}{cmyk}{0.00, 1.00, 1.00, 0.00} % true red
+
+%************ SECTION 4B - A FIX FOR PGFKEYS ***********************************************
+\def\nl{\par} % see Q 96247 for why we defined \nl for use with pgfkeys
+
+%************ SECTION 4C - VARIOUS SIMPLE BUT USEFUL COMMANDS ******************************
+\NewDocumentCommand \PreheatC{m}{Preheat oven to #1\Degrees convection.\thinspace\Oven}%
+\NewDocumentCommand \PreheatR{m}{Preheat oven to #1\Degrees regular oven.\thinspace\Oven}%
+
+\NewDocumentCommand \Tbl{o}{\IfNoValueTF{#1}{tablespoon }{tablespoon#1}}%
+\NewDocumentCommand \tsp{o}{\IfNoValueTF{#1}{teaspoon }{teaspoon#1}}%
+\NewDocumentCommand \Pd{o}{\IfNoValueTF{#1}{pound }{pound#1}}%
+\NewDocumentCommand \Ounce{o}{\IfNoValueTF{#1}{ounce }{ounce#1}}%
+\NewDocumentCommand \Degrees{o}{\IfNoValueTF{#1}{\TextDegree{} }{\TextDegree{}#1}}%
+
+\NewDocumentCommand \AxB{m m o}{{#1\thinspace{x}\thinspace#2}\IfValueT{#3}{#3}}%
+\NewDocumentCommand \AxBxC{m m m o}{%
+ {#1\thinspace{x}\thinspace#2\thinspace{x}\thinspace#3}\IfValueT{#4}{#4}}%
+
+\NewDocumentCommand \Inch{m}{{#1-inch}}%
+\NewDocumentCommand \EditNote{m}{{{\color{clrEditNote} #1}}}%
+\NewDocumentCommand \Quote{m}{{``#1''}}%
+
+\NewDocumentCommand \IngredientsSeparator{}{{\FontStepsDefault \CtrDots\CtrDots}}%
+\NewDocumentCommand \SeparateParagraphs{}{{\vskip 5pt}}%
+\NewDocumentCommand \Recipe{+m}{{\textit{\textsb{#1}}}}%
+
+%************ SECTION 4D - BAKE UNTIL ******************************************************
+\pgfkeys{
+ /BakeUntil/.is family, /BakeUntil,
+ default/.style = {Min = 0, Max = 0, TPick = 0, GBrown = 0, Until = \empty},
+ Min/.estore in = \BkMin,
+ Max/.estore in = \BkMax,
+ TPick/.estore in = \BkTPick,
+ GBrown/.estore in = \BkGBrown,
+ Until/.estore in = \BkUntil,
+}
+
+\NewDocumentCommand \BakeUntil{m}{%
+\pgfkeys{/BakeUntil, default, #1}%
+\newcount\MyCount \MyCount = \BkMax%
+\newcount\MyCase%
+{Bake about \BkMin}%
+\ifnum\MyCount > 0 {-\BkMax}\fi
+{ minutes}%
+%
+\ifx\BkUntil\empty \MyCase = 0 %
+ \else \MyCase = 1 \fi%
+\ifnum\BkTPick = 1 \MyCase = 2 \fi%
+\ifnum\BkGBrown = 1 \MyCase = 3 \fi%
+%
+\ifcase\MyCase% '0' case - do nothing
+\or {, \BkUntil}% '1' case - use the "Until" text
+\or {, until toothpick tests clean}% '2' case - TPick
+\or {, until golden brown}% '3' case - GBrown
+\fi
+}
+
+%************ SECTION 4E - OTHER MISCELLANEOUS COMMANDS ************************************
+\NewDocumentEnvironment{CopyrightPage}{} % See 31186
+{\FontCopyrightPage\setlength{\parindent}{0pt}\par\vspace*{\fill}}
+{\clearpage}
+
+\NewDocumentCommand \Attribution{m}{{\hspace*\fill}{\textit{#1}}}%
+\NewDocumentCommand \ThreeLines{}{%
+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut,
+ placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu libero,
+ nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque.
+}
+
+\newcount\LineCount
+\NewDocumentCommand \InsertHiddenLines{m}{%
+ \LineCount = #1
+ {%
+ \newcount\foo \foo=0
+ \loop % \loop starts the construct ended by \repeat
+ \phantom{.}\par \advance \foo by 1
+ \ifnum \foo < \LineCount \repeat % \repeat also “serves as†the \fi to the \ifnum
+ }%
+}
+
+%************ SECTION 4F - CHAPTER INTRO ***************************************************
+\newbox\IntroBox
+\newbox\IntroBoxA
+\NewDocumentCommand \ChapterIntro {o +m} % arg1 = optional = lines for first part
+{ % arg2 = story text
+\setbox\IntroBox\vbox
+ {
+ \FontChapterIntro
+ {#2\par} % the \par needed by \lettrine
+ }
+\IfNoValueTF {#1} % NoValue=TRUE or NoValue=FALSE?
+ {\unvbox\IntroBox} % NoValue=TRUE, so flush the full IntroBox
+ { % handle the NoValue=FALSE case
+ \ifnum #1 > 0 % > 0 means we split the story into two part; print the first part here
+ { % = 0 means ALL of story is deferred
+ \setbox\IntroBoxA=\vsplit\IntroBox to #1\dimexpr \CIntroFontBaseline %
+ \unvbox\IntroBoxA %
+ }
+ \fi
+ }
+}
+
+\NewDocumentCommand \FinishChapterIntro{}%
+{\ifvoid\IntroBox \else \smallskip\unvbox\IntroBox\par\medskip\fi} %
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION 5 - RECIPE ENVIRONMENTS AND COMMANDS %%%%%%%%%%%%%%%%
+
+%************ SECTION 5A - RECIPE NAME AND YIELD *******************************************
+\pgfkeys{
+ /RecipeNameAndYield/.is family, /RecipeNameAndYield,
+ default/.style = {Name = 0, NoIdxName = 0, XRefLabel = \empty, Yield = \empty, %
+ IndexA = \empty, IndexB = \empty, IndexC = \empty},
+ Name/.estore in = \RecipeName,
+ NoIdxName/.estore in = \NoIndexName,
+ IndexA/.estore in = \IdxA,
+ IndexB/.estore in = \IdxB,
+ IndexC/.estore in = \IdxC,
+ XRefLabel/.estore in = \XRefLbl,
+ Yield/.estore in = \RecipeYield,
+}
+
+\NewDocumentCommand \RecipeNameAndYield {m}{% !!! Need a way to show "starred" (favorite) recipes??
+ \pgfkeys{/RecipeNameAndYield, default, #1}%
+ % Put the recipe name in the Index, unless the user sets NoIdxName = 1:
+ % (How about any non-empty instead of = 1)?
+ \ifnum\NoIndexName=1 \relax\else\index{\RecipeName}\fi
+ % Can add up to three other Index entries:
+ \ifx\IdxA\empty\relax\else\index{\IdxA}\fi
+ \ifx\IdxB\empty\relax\else\index{\IdxB}\fi
+ \ifx\IdxC\empty\relax\else\index{\IdxC}\fi
+ % Did the user ask us to set up a label for cross-reference?:
+ \ifx\XRefLbl\empty\relax\else\RecipeLabel{\XRefLbl}\fi
+ % Add a bookmark (only adds bookmark if hyperref is active):
+ \ifnum\NoIndexName=1 \RecipeBookmark{\IdxA}\else\RecipeBookmark{\RecipeName}\fi
+ \begin{center}%
+ {\FontRecipeName{\RecipeName}}\par%
+ \ifx\RecipeYield\empty\relax\else {\textit{\RecipeYield}}\par \fi%
+ \end{center}%
+}
+
+%************ SECTION 5B - RECIPE STORY ****************************************************
+\def\RecipeStoryIndent{20 pt}
+\newbox\StoryBox
+\newbox\StoryBoxA
+\NewDocumentCommand \RecipeStory {o +m} % arg1 = optional = lines for first part
+{ % arg2 = story text
+\setbox\StoryBox\vbox
+ {
+ \FontRecipeStory
+ \leftskip=\RecipeStoryIndent \rightskip=\leftskip % Q 66332 see also Q 156986 (egreg and his comment)
+ {#2\par} % the \par needed by \lettrine
+ }
+\IfNoValueTF {#1} % NoValue=TRUE or NoValue=FALSE?
+ {\unvbox\StoryBox} % NoValue=TRUE, so flush the full StoryBox
+ { % handle the NoValue=FALSE case
+ \ifnum #1 > 0 % > 0 means we split the story into two part; print the first part here
+ { % = 0 means ALL of story is deferred
+ \setbox\StoryBoxA=\vsplit\StoryBox to #1\dimexpr \RStoryFontBaseline %
+ \unvbox\StoryBoxA %
+ }
+ \fi
+ }
+}
+
+\NewDocumentCommand \FinishRecipeStory{}%
+ {\ifvoid\StoryBox \else \smallskip\unvbox\StoryBox\par\medskip\fi} %
+
+%************ SECTION 5C - INGREDIENTS AND STEPS ENVIRONMENT *******************************
+\usepackage{multicol} % allows multiple columns in selected areas of a single-column document
+\usepackage[strict]{changepage} % for \adjustwidth
+\usepackage{xfp} % for fpeval floating point macro
+
+\pgfkeys{
+ /IngredientsAndSteps/.is family, /IngredientsAndSteps,
+ default/.style = {AdjIFont = 1, AdjIBaseline = 0,
+ AdjSFont = 0, AdjSBaseline = 0,
+ AddWidth = 0, RaggedCols = 0},
+ AdjIFont/.estore in = \AdjustIFont,
+ AdjIBaseline/.estore in = \AdjustIBaseline,
+ AdjSFont/.estore in = \AdjustSFont,
+ AdjSBaseline/.estore in = \AdjustSBaseline,
+ AddWidth/.estore in = \AddPageWidth,
+ RaggedCols/.estore in = \RaggedColumns,
+}
+
+\newdimen\IFont \newdimen\IBase \newdimen\SFont \newdimen\SBase \newdimen\AddWidth
+
+\NewDocumentEnvironment{IngredientsAndSteps}{o} % !!! Need \raggedcolumns ??
+ % Do the before-environment setup:
+ {
+ \IfNoValueTF {#1}%
+ % Handle the simple case = no optional key/value argument:
+ {\AddWidth = 0 pt}
+ % Handle the special case = there IS an optional key/value argument:
+ {
+ \pgfkeys{/IngredientsAndSteps, default, #1}%
+
+ \IFont = \AdjustIFont pt
+ \IBase = \AdjustIBaseline pt
+ \SFont = \AdjustSFont pt
+ \SBase = \AdjustSBaseline pt
+ \AddWidth = \AddPageWidth pt
+
+ \ifdim\IBase = 0 pt \IBase = \IFont \fi
+ \ifdim\SFont = 0 pt \SFont = \IFont \fi
+ \ifdim\SBase = 0 pt \SBase = \IFont \fi
+
+ \RenewDocumentCommand \FontIngredients {}{\FontIngDefault\fontsize{\fpeval{\StdIFontSize * \IFont}}
+ {\fpeval{\StdIBaseline * \IBase}}\selectfont}
+ \RenewDocumentCommand \FontSteps {}{\FontStepsDefault\fontsize{\fpeval{\StdSFontSize * \SFont}}
+ {\fpeval{\StdSBaseline * \SBase}}\selectfont}
+ }
+ % Now, finish setup:
+ \adjustwidth{-\AddWidth}{-\AddWidth}
+ \begin{multicols}{2}%
+ } % End of the before-environment setup
+ % Now do the after-environment cleanup:
+ {
+ \end{multicols}
+ \endadjustwidth
+ % We need to restore the fonts to default size IF there was an optional key/value argument:
+ \IfValueT {#1}
+ {
+ \RenewDocumentCommand \FontIngredients {}{\FontIngDefault}
+ \RenewDocumentCommand \FontSteps {}{\FontStepsDefault}
+ }
+ } % End of the "after environment" cleanup
+
+%************ SECTION 5D - COMMANDS TO DISPLAY INGREDIENTS AND STEPS ***********************
+\NewDocumentCommand \IngredientsHeading {O{0} m O{2}}%
+ {\begingroup
+ \setlength{\parindent}{0pt}
+ \ifnum #1 > 0 {\vspace{#1 pt}}\fi
+ \FontIngTitle\color{clrIngTitle} #2\par%
+ \vspace{#3 pt}
+ \endgroup}%
+
+\NewDocumentCommand \ListIngredientsAndSteps {o +m +m}
+{
+\IfValueT {#1}{\IngredientsHeading{#1}[3]}%
+{\begingroup\ifx\relax#2\relax\else\FontIngredients{}\IngredientsList{#2}\fi\endgroup}%
+{\begingroup\ifx\relax#3\relax\else\FontSteps{}\RecipeSteps{#3}\fi\endgroup}%
+}
+
+\NewDocumentCommand \IngredientsList { >{\SplitList{\par}} +m}{%
+ \setlength{\parskip}{2pt}\raggedright%
+ \ProcessList{#1}{\ProcessIngList}
+}
+\newcommand\ProcessIngList[1]{\hangindent1em #1\par}
+
+\NewDocumentCommand \RecipeSteps { >{\SplitList{\par}} +m}{%
+\begin{enumerate}[itemsep=2pt plus 1 pt minus 1pt, parsep=0pt plus 1pt,
+ topsep=4.5pt plus 2.0pt minus 1.0pt, leftmargin=*]
+ \ProcessList{#1}{\item}
+\end{enumerate}
+ }
+
+%************ SECTION 5E - THE TIPS, CHEFFY AND CHEFNOTES ENVIRONMENTS *********************
+\usepackage{tcolorbox}
+\tcbset{fonttitle=\FontTitleColorBox}
+
+\NewDocumentEnvironment{Tip}{+m} %
+{
+\begin{tcolorbox}[colback=clrBackTip,colframe=clrFrameTip, title=Food for Thought] %
+ {#1}%
+\end{tcolorbox}
+}
+
+\NewDocumentEnvironment{Cheffy}{+m} %
+{
+\begin{tcolorbox}[colback=clrBackCheffy,colframe=clrFrameCheffy, title=Let's Get Cheffy] %
+ {#1}%
+\end{tcolorbox}
+}
+
+\NewDocumentEnvironment{ChefNotes}{+m} %
+{
+\begin{tcolorbox}[colback=clrBackNotes,colframe=clrFrameNotes,title=Chefnotes] %
+ \ChefNote{}{#1}%
+\end{tcolorbox}
+}
+
+%************ SECTION 6 - ANY TIKZ DRAWINGS ************************************************
+\usepackage{tikz}
+\usetikzlibrary{calc}
+
+\def\hatscale{0.05}
+\def\hatwidth{12.5pt}
+\NewDocumentCommand \MakeChefHat{}
+{
+ \begin{tikzpicture}[scale=\hatscale]
+ \coordinate (HA) at (1.27, 0.635);
+ \coordinate (HB) at (5.87375, 0);
+ \coordinate (HC) at (1.5825, 0.9475);
+ \coordinate (HD) at (5.77375, 0.15);
+ \coordinate (HE) at (1.5875,1.905);
+ \coordinate (HF) at (1.8,1.74625);
+ \coordinate (HG) at (6.0325, 1.27);
+ \coordinate (HH) at (6.22, 1.33);
+ \coordinate (HI) at (6.45, 2.18);
+ \coordinate (HJ) at (6.35, 2.70);
+ \coordinate (HK) at (8.5725, 3.97);
+ \coordinate (HL) at (6.03, 4.7625);
+ \coordinate (HM) at (6.03, 3.651);
+ \coordinate (HN) at (2.2225, 5.3975);
+ \coordinate (HO) at (0.159, 4.603);
+ \coordinate (HP) at (1.587, 3.55);
+ \coordinate (HQ) at (2.5, 4.7625);
+ \coordinate (HR) at (2.778, 2.08);
+ \coordinate (HS) at (2.7, 4.1275);
+ \coordinate (HT) at (4.0, 1.98);
+ \coordinate (HU) at (4.286, 3.4925);
+ \coordinate (HV) at (5.3, 1.7);
+ \coordinate (HW) at (5.55, 2.85);
+ \coordinate (HX) at (4.286, 5.0);
+ %
+ \path[fill=black] (HA) to [bend left=20] (HB) to (HD) to [bend right=20] (HC) to (HA);
+ \path[fill=black] (HA) to (HC) to (HF) to (HE) to (HA);
+ \path[fill=black] (HE) to (HF) to [bend left=20] (HG) to (HH) to [bend right=20] (HE);
+ \path[fill=black] (HB) to (HD) to (HG) to (HH) to (HB);
+ \path[fill=black] (HH) to (HI) to (HJ) to (HG);
+ \draw[line width=5*\hatscale] (HI) to [bend right=50] (HK);
+ \draw[line width=5*\hatscale] (HK) to [bend right=50] (HL);
+ \draw[line width=5*\hatscale] (HL) to [bend right=45] (HX);
+ \draw[line width=5*\hatscale] ($(HX) + (0.4, -.4)$) to [bend right=45] (HN);
+ \path[fill=black] (HM) to ($(HL) -(0.15, 0)$) to ($(HL) + (0.15, 0)$) to (HM);
+ \draw[line width=5*\hatscale] (HN) to [bend right=50] (HO);
+ \draw[line width=5*\hatscale] (HO) to [bend right=50] (HP);
+ \draw[line width=5*\hatscale] ($(HF) +(0, 0.15)$) to (HP);
+ \path[fill=black] (HQ) to ($(HN) -(0.15, 0)$) to ($(HN) + (0.15, 0)$) to (HQ);
+ \path[fill=black] (HS) to ($(HR) -(0.15, 0)$) to ($(HR) + (0.15, 0)$) to (HS);
+ \path[fill=black] (HU) to ($(HT) -(0.15, 0)$) to ($(HT) + (0.15, 0)$) to (HU);
+ \path[fill=black] (HW) to ($(HV) -(0.15, 0)$) to ($(HV) + (0.15, 0)$) to (HW);
+ \end{tikzpicture}
+}
+
+\def\ovenscale{0.2666}
+\def\ovenwidth{18pt}
+\NewDocumentCommand \MakeOven{} % inspired by the oven in the tikzsymbols package
+{
+ \begin{tikzpicture}[scale=\ovenscale]
+ \draw [line width=2*\ovenscale] (0,0) rectangle (2,1.5);
+ \draw [line width=2*\ovenscale] (0.125,0.125) rectangle (1.875,1);
+ \draw [line width=2*\ovenscale] (0.75,1.125) rectangle (1.25,1.375);
+ \draw [line width=2*\ovenscale] (0.5,0.875) to (1.5,0.875);
+ \draw [fill=black] (0.23, 1.25) circle [radius=0.1];
+ \draw [fill=black] (0.52, 1.25) circle [radius=0.1];
+ \draw [fill=black] (1.48, 1.25) circle [radius=0.1];
+ \draw [fill=black] (1.77, 1.25) circle [radius=0.1];
+ \end{tikzpicture}
+}
+
+\ifMakeCookbook
+\else
+\NewDocumentCommand \MakeTitlePage{}
+{
+\begingroup
+%\centering
+ \begin{tikzpicture}[x=1in,y=1in]
+ \coordinate (TA) at (0, 0);
+ \coordinate (TB) at (6.125, 8); % we ignore bottom 0.25 of text area to prevent newpage
+ \coordinate (TC) at (1, 0.25);
+ \coordinate (TD) at (5.125, 7.5);
+ \coordinate (TE) at (1, 7.5);
+ \coordinate (TF) at (5.125, 0.25);
+ \useasboundingbox (TA) rectangle (TB);
+ \draw [line width=1] (TC) to (TD);
+ \node[anchor=north west, align=left, font=\FontTitlepageTitle] at (TE) {Mama, How \\ Do You \\ Make...};
+ \node[left, font=\FontTitlepageAuthor] at (TF) {Rosalie A. D'Amico};
+ \end{tikzpicture}
+\endgroup
+}
+\fi
+
+%************ SECTION 7 - FRONT MATTER HELPER COMMANDS *************************************
+
+\ifMakeCookbook
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % This group for the MAKECOOKBOOK bundle
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\NewDocumentCommand \MyTitlePage{}
+{
+\noindent\vspace{144pt}
+\begin{center}
+ {
+ {\FontTitlepageTitle Smith Family Cookbook} \par
+ \vspace*{\fill}
+ {\FontTitlepageAuthor by Henry A. Smith}\par
+ }
+\end{center}
+\vspace{40pt} \clearpage
+}
+
+\NewDocumentCommand \ColophonFonts{}
+{
+Serif font (primary document font):
+EB Garamond, \Copyright{} The EB Garamond Project Authors\par
+\quad (github.com/octaviopardo/EBGaramond12). Licensed under the SIL Open Font License, Version 1.1.\par
+Sans Serif font:
+Lato, \Copyright{} Åukasz Dziedzic. Licensed under the SIL Open Font License, Version 1.1.\par
+Script font: Italianno, \Copyright{} TypeSETit, LLC. Licensed under the SIL Open Font License, Version 1.1.\par
+}
+
+\NewDocumentCommand \CopyrightInfo{}
+ {Copyright \Copyright{} 2018, Henry A. Smith, all rights reserved}
+
+\NewDocumentCommand \MyDedication{}
+ {\hrule\vspace{5pt} To my family. And possibly some other stuff. \vspace{5pt}\hrule}
+
+\NewDocumentCommand \DedicationVerso{}{}
+
+\else
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % This group for our cookbook
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\NewDocumentCommand \MyTitlePage{} {\noindent \MakeTitlePage{} \clearpage}
+
+\NewDocumentCommand \ColophonFonts{}
+{
+Serif font (primary document font):
+Adobe Garamond Pro, \Copyright{} Adobe Systems Incorporated.\par
+Sans Serif font:
+Adobe Myriad Pro, \Copyright{} Adobe Systems Incorporated.\par
+Script font: Italianno, \Copyright{} TypeSETit, LLC. Licensed under the SIL Open Font License, Version 1.1.\par
+}
+
+\NewDocumentCommand \CopyrightInfo{}
+ {Copyright \Copyright{} 2018, Rosalie A. D'Amico, all rights reserved}
+
+\NewDocumentCommand \MyDedication{}
+ {\hrule\vspace{5pt}
+ To my family. Now when you ask \Quote{how do you make...}, I just need to give you a page number.%
+ \vspace{5pt}\hrule}
+
+\NewDocumentCommand \DedicationVerso{}
+{
+\begin{center}
+ {\FontChapterTitle
+ One cannot think well, \\
+ love well, sleep well, \\
+ if one has not dined well.\\
+ \vspace{5pt}
+ \hrule
+ \vspace{5pt}
+ Uno non pu\`o pensare bene, \\
+ amare bene, dormire bene, \\
+ se non ha mangiato bene. \\
+ \vspace{5pt}
+ \hrule
+ \vspace{5pt}
+ Virginia Woolf
+ }
+\end{center}
+}
+\fi
+
+%************ SECTION 8 - GRAPHICX RELATED COMMANDS ****************************************
+\graphicspath{{img/}{../img/}} % look in the img directory (subdir of book root or sibling of tex)
+\usepackage[skip=2pt, labelformat=empty, font={rm,it}]{caption} % <-
+\captionsetup{justification=centering} % this is needed to have multi-line captions centered
+
+\pgfkeys{
+ /SideBySide/.is family, /SideBySide,
+ default/.style = {VertAlign = c, LeftCaption = \empty, RightCaption = \empty},
+ VertAlign/.estore in = \VerticalAlign,
+ LeftCaption/.estore in = \LeftText,
+ RightCaption/.estore in = \RightText,
+}
+
+\NewDocumentCommand \SideBySide{O{\empty} m m} % Q 5769
+{
+\pgfkeys{/SideBySide, default, #1}%
+%
+ \begin{figure}[htb]
+ \centering
+ \begin{minipage}[\VerticalAlign]{0.49\textwidth} % align at t= top, c = center, b = bottom
+ \centering
+ \includegraphics[width=0.97\textwidth]{#2} %
+ \ifx\LeftText\empty\relax\else\caption{\LeftText}\fi
+ \end{minipage}\hfill%
+ \begin{minipage}[\VerticalAlign]{0.49\textwidth}
+ \centering
+ \includegraphics[width=0.97\textwidth]{#3} %
+ \ifx\RightText\empty\relax\else\caption{\RightText}\fi
+ \end{minipage}
+ \end{figure}
+}
+
+%************ SECTION 9 - HYPERREF RELATED COMMANDS ****************************************
+\ifHyperRef
+\usepackage[bookmarks=true,colorlinks=true, allcolors=clrHyperRef]{hyperref}
+\usepackage{bookmark} % Q 247158 shows Heiko (the author) loads both hyperref and bookmark
+
+\newcounter{ctrRecipe} % initially set to zero by \newcounter macro
+\NewDocumentCommand \RecipeBookmark{m}{%
+ \ifx\%1\empty\relax\else\stepcounter{ctrRecipe}\pdfbookmark[1]{#1}{Recipe\arabic{ctrRecipe}}\fi
+}
+\else
+\providecommand\phantomsection{}% Q 44088
+\NewDocumentCommand \RecipeBookmark{m}{}%
+\fi
+
+\NewDocumentCommand \RecipeLabel{m}{\phantomsection\label{recipe:#1}}
+\NewDocumentCommand \RecipePageNo{m}{\pageref{recipe:#1}}
+
+\NewDocumentCommand \CookbookIndex{}
+{
+\cleardoublepage % flush all material and clear until you start new odd numbered (recto) page
+%
+% the following line needed if hyperref is loaded (p. 18 of hyperref manual):
+\phantomsection\addcontentsline{toc}{chapter}{\indexname} % see also Q 59619
+%
+\printindex
+}
+
diff --git a/macros/luatex/latex/makecookbook/mycookbook/img/image-a.jpg b/macros/luatex/latex/makecookbook/mycookbook/img/image-a.jpg
new file mode 100644
index 0000000000..19ac8b9cf4
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/mycookbook/img/image-a.jpg
Binary files differ
diff --git a/macros/luatex/latex/makecookbook/mycookbook/img/image-b.jpg b/macros/luatex/latex/makecookbook/mycookbook/img/image-b.jpg
new file mode 100644
index 0000000000..1179cba6cd
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/mycookbook/img/image-b.jpg
Binary files differ
diff --git a/macros/luatex/latex/makecookbook/mycookbook/makecookbook.pdf b/macros/luatex/latex/makecookbook/mycookbook/makecookbook.pdf
new file mode 100644
index 0000000000..ef295364c8
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/mycookbook/makecookbook.pdf
Binary files differ
diff --git a/macros/luatex/latex/makecookbook/mycookbook/makecookbook.tex b/macros/luatex/latex/makecookbook/mycookbook/makecookbook.tex
new file mode 100644
index 0000000000..4518c25c9a
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/mycookbook/makecookbook.tex
@@ -0,0 +1,24 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LICENSE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Copyright 2018 Terrence P. Murphy and Rosalie D'Amico.
+% This file may be distributed and/or modified under the conditions of the LaTeX Project
+% Public License (“LPPLâ€), either version 1.3c of this license or (at your option) any
+% later version. The latest version of this license is at:
+% http://www.latex-project.org/lppl.txt.
+% This file is author-maintained and is one of the files that, collectively, make up the
+% MAKECOOKBOOK bundle available at https://ctan.org/pkg/makecookbook
+% For additional information, please see the associated README file.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\documentclass[11pt]{book}
+\input{cb-preamble}
+
+\begin{document}
+\frontmatter
+\include{./tex/cb-frontmatter}
+
+\mainmatter
+\include{./tex/cb-chapterA}
+\include{./tex/cb-chapterB}
+
+\backmatter
+\CookbookIndex{}
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/makecookbook/mycookbook/tex/cb-chapterA.tex b/macros/luatex/latex/makecookbook/mycookbook/tex/cb-chapterA.tex
new file mode 100644
index 0000000000..8df5468122
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/mycookbook/tex/cb-chapterA.tex
@@ -0,0 +1,413 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LICENSE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Copyright 2018 Terrence P. Murphy and Rosalie D'Amico.
+% This file may be distributed and/or modified under the conditions of the LaTeX Project
+% Public License (“LPPLâ€), either version 1.3c of this license or (at your option) any
+% later version. The latest version of this license is at:
+% http://www.latex-project.org/lppl.txt.
+% This file is author-maintained and is one of the files that, collectively, make up the
+% MAKECOOKBOOK bundle available at https://ctan.org/pkg/makecookbook
+% For additional information, please see the associated README file.
+%
+% The MAKECOOKBOOK bundle includes an example cookbook with seven recipes. Those recipes are
+% courtesy of Rosalie D'Amico. You are, of course, welcome to try them! They are included in
+% the bundle to provide real-world examples of using LaTex code to enter recipes. We only ask
+% that you consider those recipes as for you personal use and not (without attribution) for
+% further food-related publication (further publication OK in a LaTex context).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\chapter{Some Chapter Name}
+
+\ChapterIntro{
+ \lettrine{T}{his is the} chapter intro. \lipsum[1-3]
+}
+
+\newpage
+\RecipeNameAndYield{Name=A -- Lemon Roasted Potatoes}
+\RecipeStory{\lettrine{T}{his is a recipe} story. \lipsum[66]}
+
+\begin{IngredientsAndSteps}
+ \ListIngredientsAndSteps
+ {
+ 2 \Pd[s] baby Dutch gold potatoes, washed and cut in half
+
+ \fr1/2 cup water
+
+ \fr1/4 cup extra-virgin olive oil
+
+ 4 cloves garlic, finely minced
+
+ \fr1/2 \tsp salt
+
+ Several grinds of black pepper
+
+ \fr1/2 \tsp dried oregano
+
+ \fr1/2 \tsp Piment\'on
+
+ Juice and zest from 1 large lemon
+
+ \fr1/2 cup chopped Italian parsley
+ }
+ {
+ \PreheatC{375} \ChefNote
+
+ In a \Inch{\AxB{9}{13}} baking dish, combine all ingredients except parsley.
+
+ Roast for 30 minutes.
+
+ Stir potatoes and roast another 15 minutes or until well done.
+
+ Serve sprinkled with parsley.
+ }
+
+\end{IngredientsAndSteps}
+\Attribution{Recipe courtesy of Rosalie D'Amico}
+\begin{Tip}
+ {Add \fr1/2 cup pitted kalamata olives before roasting. The olives mellow out and add a nice salty note with the long roasting time.}
+\end{Tip}
+
+\begin{ChefNotes}
+ {If your oven has a convection roast option, use that. }
+\end{ChefNotes}
+
+\newpage
+
+\RecipeNameAndYield{Name=B -- Pumpkin Pancakes, Yield=Yield: 6 Pancakes, NoIdxName=1, IndexA=Pumpkin Pancakes,
+ IndexB=B!Pumpkin Pancakes}
+
+\RecipeStory{\lettrine{W}{e tell a story} here. \lipsum[66]}
+
+\begin{IngredientsAndSteps}
+
+ \ListIngredientsAndSteps
+ {
+ 1\fr1/4 cups all-purpose flour
+
+ 2 \tsp[s] baking powder
+
+ \fr1/2 \tsp cinnamon
+
+ \fr1/2 \tsp ginger
+
+ \fr1/2 \tsp nutmeg
+
+ Pinch of cloves and allspice
+
+ \fr1/4 \tsp salt
+
+ \IngredientsSeparator
+
+ \InsertHiddenLines{1} % also try the multicol \columnbreak command
+
+ \fr1/2 cup canned solid pack pumpkin
+
+ 2 \Tbl[s] brown sugar or Maple Syrup
+
+ 1 large egg
+
+ 2 \Tbl[s] oil
+
+ 1 cup milk
+ }
+ {
+ Mix dry ingredients in bowl. In another bowl, whisk pumpkin and remaining ingredients together until well mixed. Add to dry ingredients and fold together. Do not overmix.
+ }
+
+\end{IngredientsAndSteps}
+\Attribution{Recipe courtesy of Rosalie D'Amico}
+\newpage
+\RecipeNameAndYield{Name=C -- Pesto, XRefLabel=Pesto}%
+\RecipeStory{\lettrine{W}{ith such a} simple, uncooked sauce, it is important to use the freshest and highest-quality ingredients possible -- a very good, extra-virgin olive oil, genuine Parmigiano-Reggiano cheese, American or Italian pine nuts. Avoid pine nuts from China. They can cause \Quote{pine mouth} syndrome, which can leave a bitter, metallic taste in your mouth for up to two weeks. Italian pine nuts are difficult to find and extremely expensive, so I generally use American grown pine nuts.}
+
+\begin{IngredientsAndSteps}
+
+ \ListIngredientsAndSteps
+ {
+ 3 cups packed fresh basil leaves (washed, just shake water out, leaving a bit of water clinging to the leaves), roughly chopped
+
+ 2 cloves garlic
+
+ 2 \Tbl[s] toasted pine nuts
+
+ \fr1/4 \tsp salt
+
+ \fr3/4 cup olive oil divided \fr1/2 and \fr1/4 cup
+
+ \fr1/4 cup chopped Italian parsley (optional)
+
+ \fr1/2 cup grated Parmigiano-Reggiano cheese
+
+ \InsertHiddenLines{2} % see also \columnbreak in the multicol documentation
+ }
+ {
+ Put pine nuts, garlic, salt, and \fr1/2 cup olive oil in food processor. Blend to combine and chop the garlic and pine nuts.
+
+ Add basil (and parsley if using) and remaining olive oil. Blend together until mixture is smooth and bright green.
+
+ Add Parmigiano. Blend until cheese is evenly dispersed. Adjust seasonings and consistency to your liking.
+
+ Transfer to a small bowl and cover the top with a drizzle of olive oil to prevent the pesto from darkening in color.
+ }
+
+\end{IngredientsAndSteps}
+\Attribution{Recipe courtesy of Rosalie D'Amico}
+\begin{Cheffy}
+ {To blanch or not to blanch the basil leaves……
+
+ My personal conclusion: I'd skip the blanching if planning to serve (or consume) the pesto that same day. But if I'm going to store it in the refrigerator (or the freezer) for some time, where it will continue to oxidize (which degrades the flavor anyway), that's when I'd consider blanching first. I personally feel blanching takes away some of the flavor. If you do blanch, be sure to blanch for no more than 5 seconds and immediately immerse in an ice bath.}
+\end{Cheffy}
+
+\newpage
+\RecipeNameAndYield{Name=D -- Pasta Genovese, Yield={(Pasta with Pesto, Potatoes and Green Beans)\nl %
+ Makes 4 to 6 servings}}
+\RecipeStory{\lettrine{A}{ccording to} Marcella Hazan, there is no single dish more delicious in the entire Italian pasta repertory than \textit{Pasta Genovese}. And my husband and I could not agree more!
+
+ \textit{Pasta with Pesto, Potatoes, and Green Beans} is the classic Genovese pasta dish from Liguria, a small coastal region of north-western Italy. Liguria is considered to be the birthplace of pesto. Ask any Italian where the best basil in Italy is grown and they will tell you it comes from the area of Pra on the hills to the west of Genoa.
+
+ It may seem odd to have two starches in one dish, but it works. It is very easy to prepare since the green beans and potatoes cook in the same water as the pasta. Use any pasta you desire. Good choices are gemelli, linguine, or my favorite, garganelli. Add more or less potatoes and green beans to your taste.}
+
+\begin{IngredientsAndSteps}
+
+ \ListIngredientsAndSteps
+ {
+ Pesto (one recipe -- page \RecipePageNo{Pesto})
+
+ 8 \Ounce of pasta of your choice
+
+ 3 cups green beans, cut into \Inch{2} pieces
+
+ 5 small red or Dutch gold potatoes, washed, unpeeled and sliced into \Inch{\frx1/4 } slices
+
+ Parmigiano-Reggiano for serving
+ }
+ {
+ Bring a pot of salted water to a boil. You want the water nicely salted for flavor and also to maintain the shape of the potatoes and greenness of the beans.
+
+ Cook the potatoes first, just until they are done. Remove the potatoes with a strainer or slotted spoon and place in a bowl. \textit{Do not throw away the water.}
+
+ Add the beans to the water and cook until they are done all the way. Remove with a slotted spoon and add to the bowl with the potatoes, keeping the cooking water.
+
+ Add the pasta to the boiling water and cook to al dente. When pasta is cooked, add the potatoes and beans and leave in the hot water for one minute just to re-heat them.
+
+ Reserve a cup or more cooking water before draining the pasta, potatoes and beans.
+
+ Add the pasta, potatoes and beans back to the pot you cooked them in. Add the pesto and mix together. Add a little of the pasta cooking water if you want it “saucierâ€. Serve with grated Parmigiano-Reggiano cheese.
+ }
+\end{IngredientsAndSteps}
+\Attribution{Recipe courtesy of Rosalie D'Amico}
+\newpage
+\RecipeNameAndYield{Name=E -- Lemon Roasted Potatoes}
+\RecipeStory[8]{\lettrine{T}{his is a recipe} story. \lipsum[1-3]}
+
+\begin{IngredientsAndSteps}
+ \ListIngredientsAndSteps
+ {
+ 2 \Pd[s] baby Dutch gold potatoes, washed and cut in half
+
+ \fr1/2 cup water
+
+ \fr1/4 cup extra-virgin olive oil
+
+ 4 cloves garlic, finely minced
+
+ \fr1/2 \tsp salt
+
+ Several grinds of black pepper
+
+ \fr1/2 \tsp dried oregano
+
+ \fr1/2 \tsp Piment\'on
+
+ Juice and zest from 1 large lemon
+
+ \fr1/2 cup chopped Italian parsley
+ }
+ {
+ \PreheatC{375} \ChefNote
+
+ In a \Inch{\AxB{9}{13}} baking dish, combine all ingredients except parsley.
+
+ Roast for 30 minutes.
+
+ Stir potatoes and roast another 15 minutes or until well done.
+
+ Serve sprinkled with parsley.
+ }
+
+\end{IngredientsAndSteps}
+\Attribution{Recipe courtesy of Rosalie D'Amico}
+\begin{Tip}
+ {Add \fr1/2 cup pitted kalamata olives before roasting. The olives mellow out and add a nice salty note with the long roasting time.}
+\end{Tip}
+
+\begin{ChefNotes}
+ {If your oven has a convection roast option, use that. }
+\end{ChefNotes}
+
+\FinishRecipeStory{}
+
+\newpage
+% !!! Note: Fits on one page with \RecipeStory[0] and fonts at 0.925
+\RecipeNameAndYield {Name={F -- Lasagne with Meat Sauce}, %
+ Yield={Makes one \Inch{\AxB{9}{13}} Baking Dish or two \Inch{\AxB{8}{8}} Baking Dishes}}
+\RecipeStory[0]{\ThreeLines}
+
+\begin{IngredientsAndSteps}[AdjIFont=0.92, AddWidth=5]
+
+ \ListIngredientsAndSteps[Tomato Meat Sauce]
+ {
+ 3 \Tbl[s] olive oil or butter
+
+ 2 \Ounce[s] pancetta, finely chopped
+
+ 1 medium onion, finely chopped
+
+ 3 ribs celery, leaves included
+
+ 2 small carrots, peeled and finely chopped
+
+ 3 cloves garlic
+
+ Chili pepper flakes to taste (not traditional)
+
+ 8 \Ounce[s] ground veal
+
+ 8 \Ounce[s] ground pork
+
+ 8 \Ounce[s] ground beef
+
+ 2 \Tbl[s] tomato paste
+
+ 1 cup red wine
+
+ 1\fr1/2 cups chicken or beef stock
+
+ 1 (28 \Ounce[)] can crushed Italian tomatoes in purèe
+
+ \fr1/4 \tsp ground nutmeg
+
+ Salt and pepper to taste
+ }
+ {
+ Sauté the pancetta and vegetables for about 10 minutes, stirring frequently.
+
+ Add chili pepper flakes along with the meats and cook, breaking meat into small pieces with a wooden spoon, until meat is in very small pieces.
+
+ Stir in the tomato paste and wine. Cook and reduce by half.
+
+ Add stock, tomatoes, salt, pepper and nutmeg. Bring to a boil, reduce heat and simmer very slowly partially covered for 45-60 minutes, stirring occasionally.
+ }
+
+ \ListIngredientsAndSteps[B\'echamel]
+ {
+ 4 \Tbl[s] butter
+
+ 4 \Tbl[s] flour
+
+ \fr1/4 \tsp nutmeg
+
+ 4 cups milk, heated
+
+ Salt and pepper to taste
+ }
+ {
+ Melt the butter over medium-low heat.
+
+ Sprinkle with the flour and nutmeg and whisk until smooth.
+
+ Cook 5 minutes on low heat, whisking frequently. Do not let the butter brown. But do cook for the full time to cook off the raw flour.
+
+ Gradually whisk in the HOT milk. Bring to a slow bubble until sauce thickens and continue cooking on low heat for 5 minutes.
+
+ While béchamel is cooling, whisk every few minutes to prevent a “skin†from forming. But don’t be concerned if that happens. Just whisk it before using.
+ }
+
+ \ListIngredientsAndSteps[Assembly]
+ {
+ 9-\Ounce box of no-boil lasagne noodles (my favorite brand is Barilla)
+
+ Béchamel sauce
+
+ Tomato meat sauce
+
+ 4 cups grated Italian cheese (a combination of Parmigiano and Mozzarella or other Italian cheese of your choice)
+
+ \fr1/4 cup fresh parsley, chopped
+
+ \fr1/4 cup fresh basil, chopped
+ }
+ {
+ \PreheatC{375}
+
+ Have the pasta, sauce, béchamel and cheese at hand. Spray the pan with non-stick cooking spray.
+
+ Cover the no-boil pasta sheets in hot tap water for 5 minutes. Lay on paper towels or a kitchen towel before using to remove excess water.
+
+ Spread a very thin layer of meat sauce in the bottom of the baking dish. Cover with lasagne sheets in a single layer. Spread a thin layer of béchamel over the pasta and then spoon some sauce on top of the pasta. Sprinkle with cheese, fresh parsley, and basil. Repeat the layers, ending with a nice layer of meat sauce and generous sprinkling of cheese.
+
+ Cover with foil (coat the foil with non-stick cooking spray to keep it from sticking to the cheese).
+ \BakeUntil{Min=30, Max=45}. Remove the foil for the last 15 minutes. Let the Lasagne rest 10 minutes before cutting. Garnish with chopped parsley and basil.
+ }
+\end{IngredientsAndSteps}
+\Attribution{Recipe courtesy of Rosalie D'Amico}
+\FinishRecipeStory{}
+
+\newpage
+\RecipeNameAndYield{Name=G -- Potato Salad with Sherry Shallot Vinaigrette}
+\RecipeStory{\ThreeLines}
+
+\begin{IngredientsAndSteps}
+ \ListIngredientsAndSteps[Vinaigrette]
+ {
+ 1 \Tbl Dijon mustard
+
+ 1 \Tbl sherry vinegar
+
+ \fr1/2 \tsp salt
+
+ \fr1/4 cup olive oil
+
+ 1 \Tbl finely chopped shallots
+
+ 1 \Tbl finely chopped fresh thyme
+
+ Black pepper to taste
+ }
+ {
+ Whisk mustard, vinegar, and salt together. Drizzle in olive oil while whisking until emulsified.
+
+ Stir in shallots and thyme.
+
+ Add black pepper to taste.
+ }
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % HERE WE PUSH "SALAD" TO THE NEXT COLUMN
+ \InsertHiddenLines{3}
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ \ListIngredientsAndSteps[Salad]
+ {
+ 1 \Pd small yellow gold potatoes
+
+ 2 slices bacon, \Inch{\frx1/4 } dice
+
+ 2 hardboiled eggs diced
+
+ Fresh parsley finely chopped
+ }
+ {
+ Boil potatoes in salted water (1 \tsp per pound) and 2 \tsp[s] vinegar until tender.
+
+ As soon as you can handle the potatoes, peel and slice into thick coins or cut into quarters. Do not let them get cold.
+
+ Toss in a little of the dressing while warm.
+
+ Meanwhile, cook bacon over medium heat in a skillet until brown and crisp. Drain on paper towels.
+
+ Toss potatoes with bacon, eggs, fresh parsley, and more dressing if needed to your taste.
+ }
+
+\end{IngredientsAndSteps}
+\Attribution{Recipe courtesy of Rosalie D'Amico}
+\begin{Tip}
+ {Double the dressing recipe and save half for a green salad the next day. Romaine lettuce, bacon, and hard-boiled egg with this dressing is yummy.}
+\end{Tip}
+
diff --git a/macros/luatex/latex/makecookbook/mycookbook/tex/cb-chapterB.tex b/macros/luatex/latex/makecookbook/mycookbook/tex/cb-chapterB.tex
new file mode 100644
index 0000000000..92a139bafb
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/mycookbook/tex/cb-chapterB.tex
@@ -0,0 +1,121 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LICENSE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Copyright 2018 Terrence P. Murphy and Rosalie D'Amico.
+% This file may be distributed and/or modified under the conditions of the LaTeX Project
+% Public License (“LPPLâ€), either version 1.3c of this license or (at your option) any
+% later version. The latest version of this license is at:
+% http://www.latex-project.org/lppl.txt.
+% This file is author-maintained and is one of the files that, collectively, make up the
+% MAKECOOKBOOK bundle available at https://ctan.org/pkg/makecookbook
+% For additional information, please see the associated README file.
+%
+% The MAKECOOKBOOK bundle includes an example cookbook with seven recipes. Those recipes are
+% courtesy of Rosalie D'Amico. You are, of course, welcome to try them! They are included in
+% the bundle to provide real-world examples of using LaTex code to enter recipes. We only ask
+% that you consider those recipes as for you personal use and not (without attribution) for
+% further food-related publication (further publication OK in a LaTex context).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\chapter{Another Chapter Name}
+\ChapterIntro[16]{
+ \lipsum[1-3]
+}
+
+\SideBySide[LeftCaption={left caption}, RightCaption={right caption}]{image-a}{image-b}
+\FinishChapterIntro{}
+
+\newpage
+\RecipeNameAndYield{Name=H -- Chicken Scarpariello}
+\RecipeStory{\lettrine{S}{carpariello} is \textit{shoemaker} in Italian. \textit{Shoemaker’s} chicken may refer to Neapolitan shoemakers making delicious food in the little time they had at the end of the day.}
+
+\begin{IngredientsAndSteps}
+
+ \ListIngredientsAndSteps
+ {
+ \fr1/2 \Pd Italian sausage, links or bulk
+
+ 6 boneless, skinless chicken thighs
+
+ 1 large yellow onion diced small
+
+ \fr1/2 large red bell pepper diced small
+
+ 6 cloves finely minced garlic
+
+ 1 cup dry white wine
+
+ 1 cup chicken broth
+
+ \fr1/2 cup diced pickled Peppadew peppers*
+
+ \fr1/4 cup white wine vinegar
+
+ 3 sprigs fresh rosemary
+
+ Italian parsley for serving
+ }
+ {
+ Brown sausage in skillet with a little oil for 6-8 minutes (they will not be fully cooked). If using links, slice before cooking. Transfer to a plate.
+
+ Salt and pepper the chicken and dredge in flour. Cook in same skillet until nice and brown and remove from skillet (it will not be fully cooked). Transfer to plate with sausage.
+
+ Cook onions, bell pepper and garlic in same skillet for 8 to 10 minutes, adding a bit more oil if necessary.
+
+ Add wine and cook about 5 minutes until slightly reduced.
+
+ Add broth, peppers, vinegar, and rosemary and bring to a boil.
+
+ Add chicken and sausages to skillet and cook until chicken is cooked through, about 10 to 15 minutes.
+
+ Garnish with chopped parsley and serve with steamed rice.
+ }
+
+\end{IngredientsAndSteps}
+\Attribution{Recipe courtesy of Rosalie D'Amico -- Adapted from Bon Appetit}
+
+\begin{Tip}
+ {* Peppadew is the brand name for the pickled grape-size red pepper known as Juanita. They are available on Amazon or can be found bulk in “Olive Bars†in many grocery stores.}
+\end{Tip}
+\newpage
+\RecipeNameAndYield{Name=I -- Pumpkin Pancakes, Yield=Yield: 6 Pancakes}
+
+\RecipeStory{\lettrine{W}{e tell a story} here. \lipsum[66]}
+
+\begin{IngredientsAndSteps}
+
+ \ListIngredientsAndSteps
+ {
+ \IngredientsHeading {Dry Ingredients}%
+
+ 1\fr1/4 cups all-purpose flour
+
+ 2 \tsp[s] baking powder
+
+ \fr1/2 \tsp cinnamon
+
+ \fr1/2 \tsp ginger
+
+ \fr1/2 \tsp nutmeg
+
+ Pinch of cloves and allspice
+
+ \fr1/4 \tsp salt
+
+ \InsertHiddenLines{2} % also try the multicol \columnbreak command
+
+ \IngredientsHeading [2]{Wet Ingredients}%
+
+ \fr1/2 cup canned solid pack pumpkin
+
+ 2 \Tbl[s] brown sugar or Maple Syrup
+
+ 1 large egg
+
+ 2 \Tbl[s] oil
+
+ 1 cup milk
+ }
+ {
+ Mix dry ingredients in bowl. In another bowl, whisk pumpkin and remaining ingredients together until well mixed. Add to dry ingredients and fold together. Do not overmix.
+ }
+
+\end{IngredientsAndSteps}
+\Attribution{Recipe courtesy of Rosalie D'Amico} \ No newline at end of file
diff --git a/macros/luatex/latex/makecookbook/mycookbook/tex/cb-frontmatter.tex b/macros/luatex/latex/makecookbook/mycookbook/tex/cb-frontmatter.tex
new file mode 100644
index 0000000000..8ef9bb98f0
--- /dev/null
+++ b/macros/luatex/latex/makecookbook/mycookbook/tex/cb-frontmatter.tex
@@ -0,0 +1,66 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LICENSE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Copyright 2018 Terrence P. Murphy and Rosalie D'Amico.
+% This file may be distributed and/or modified under the conditions of the LaTeX Project
+% Public License (“LPPLâ€), either version 1.3c of this license or (at your option) any
+% later version. The latest version of this license is at:
+% http://www.latex-project.org/lppl.txt.
+% This file is author-maintained and is one of the files that, collectively, make up the
+% MAKECOOKBOOK bundle available at https://ctan.org/pkg/makecookbook
+% For additional information, please see the associated README file.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagestyle{empty}
+\MyTitlePage{} % this does a \clearpage
+
+\begin{CopyrightPage}
+{
+First Beta Edition (file created \today ) \par
+\CopyrightInfo{}\par
+
+No part of this publication may be reproduced, distributed, or transmitted in any form or by any means, including photocopying, recording, or other electronic or mechanical methods, without the prior written permission of the publisher, except in the case of brief quotations embodied in critical reviews and certain other noncommercial uses permitted by copyright law. For permission requests, write to the publisher at the address below. \par
+\vspace{5pt}
+ISBN No: {\textsb{978-3-00-000000-0}}\par
+Library of Congress Control Number: {\textsb{00000000000}} \par
+\vspace{5pt}
+Publisher: \par
+Example Publisher\par
+111 Address St.\par
+City, State, 12345\par
+www.theirwebsite.com
+
+\vspace{5pt}
+\hrule
+\vspace{5pt}
+The formatting/layout of this book was produced using MiK\TeX\space (with the Lua\TeX\space compiler), which is a software front-end for the \TeX\space / \LaTeX\space typesetting and document preparation system. See also the \textsb{makecookbook} bundle at:
+
+\quad https://ctan.org/pkg/makecookbook
+
+\vspace{5pt}
+The fonts used in this book are:\par
+\vspace{6pt}
+\ColophonFonts{}
+\vspace{5pt}
+Front cover image by [Artist].\par
+Book design by Terrence P. Murphy and Rosalie A. D'Amico.\par
+Printed by [printer name here], in the United States of America. \par
+}
+\end{CopyrightPage} % ends with a \clearpage
+
+\MyDedication{}
+\newpage
+
+\DedicationVerso{} % Optional content for the usually empty verso page after the dedication (and before TOC)
+\newpage
+
+% The \pagestyle{main} call seems to be "in time" to apply to the \tableofcontents
+% (and I even tested making the TOC two pages and the first page was still correct)
+
+\tableofcontents
+\pagestyle{main}
+
+\chapter{Preface}
+\ChapterIntro{
+ \lipsum[1-10]
+}
+
+
+
diff --git a/macros/luatex/latex/novel/README.md b/macros/luatex/latex/novel/README.md
new file mode 100644
index 0000000000..db96138c6b
--- /dev/null
+++ b/macros/luatex/latex/novel/README.md
@@ -0,0 +1,30 @@
+# THE NOVEL DOCUMENT CLASS
+
+The *novel* LuaLaTeX document class is specifically written to meet the needs of original fiction writers, who are typesetting their own novels for non-color print-on-demand technology. If that does not describe your objective, then this is the wrong document class for you. There is no support for E-books. The needs of academic writers and picture-book layout are largely unmet.
+
+If your book is a detective novel, science fiction, romance, or collection of short stories, then you are in the right place. This document class has been used for creating several actual printed novels, both text interior and color cover. Internal code can create PDF/X files for the interior and cover. Furthermore, a color cover image can be separated to CMYK at 240% ink limit, as required by some print-on-demand services.
+
+This class requires TeXLive 2016 or later, or recent MiKTeX. Distributions based on TeXLive 2015 or earlier will fail.
+
+Extensive documentation is in HTML format. The "novel.pdf" file is merely a place-holder.
+
+## News:
+
+Version 1.52, April 26, 2018: Enhanced detection and Warnings, using Lua code.
+
+Version 1.50.5, April 11, 2018: Minor bug fix (incorrect warning message).
+
+Version 1.50.4, April 7, 2018: Enhancements to novel-scripts.
+
+Version 1.50.3, April 5, 2018: Further minor enhancements to novel-scripts.
+
+Version 1.50.2, April 3, 2018: Minor enhancements to novel-scripts.
+
+Version 1.50.1, March 29, 2018: New features pertaining to image placement. Scripts for pre-processing images. Sandbox mode. Internal drop cap capability. Reference to obsolete macros removed from documentation. General cleanup of documentation and internal code.
+
+Version 1.46.2, January 14, 2018: Now called the "old" version. Internal code cleanup, docs cleanup. No known bugs.
+
+## License:
+
+The LaTeX code and documentation are licensed under the LaTeX Project Public License, v.1.3c. The included fonts NovelDeco.otf and CPmodified.otf are licensed under the SIL Open Font License, v.1.1.
+
diff --git a/macros/luatex/latex/novel/doc/extras/CPmodified.otf b/macros/luatex/latex/novel/doc/extras/CPmodified.otf
new file mode 100644
index 0000000000..29df311a97
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/extras/CPmodified.otf
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/extras/NovelDeco-glyphs.pdf b/macros/luatex/latex/novel/doc/extras/NovelDeco-glyphs.pdf
new file mode 100644
index 0000000000..27fa8e9905
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/extras/NovelDeco-glyphs.pdf
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/extras/novel-Gallery-ChapterStart.pdf b/macros/luatex/latex/novel/doc/extras/novel-Gallery-ChapterStart.pdf
new file mode 100644
index 0000000000..2e623ca54b
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/extras/novel-Gallery-ChapterStart.pdf
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/extras/novel-example.tex b/macros/luatex/latex/novel/doc/extras/novel-example.tex
new file mode 100644
index 0000000000..c6f025585c
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/extras/novel-example.tex
@@ -0,0 +1,127 @@
+% !TeX TS-program = LuaLaTeX
+% !TeX encoding = UTF-8
+%
+% EXAMPLE OF NOVEL DOCUMENT CLASS
+% Uses mostly default layout.
+% IF YOU COMPILE THIS DOCUMENT: Be sure that this file, and its generated PDF,
+% have read/write permissions for any user. If they don't, then
+% compile will fail at the point where files are written.
+\documentclass{novel} % v. 1.52.
+\SetTitle{Dark and Stormy}
+\SetSubtitle{A Tale of Nights}
+\SetAuthor{Dirk Hardcase}
+\SetPDFX[CGATSTR001]{X-1a:2001}
+\begin{document}
+
+\frontmatter
+
+% i. Half-Title page:
+\thispagestyle{empty}
+\vspace*{6\nbs}
+\hfill\charscale[1.8]{\textbf{Dark and}}\par
+\vspace{\nbs}
+\hfill\charscale[2.4]{\textbf{\color{gray}Stormy}}\par
+\clearpage
+
+% ii. Blank page:
+\thispagestyle{empty}
+\null
+\clearpage
+
+% iii. Full Title page:
+\thispagestyle{empty}
+\vspace*{5\nbs}
+\begin{center}
+\charscale[3.6]{\textbf{Dark and}}\par
+\vspace{2\nbs}
+\charscale[4.8]{\textbf{\color{gray}Stormy}}\par
+\vspace{1.5\nbs}
+\charscale[1.6]{A Tale of Nights}\par
+\vspace{4\nbs}
+\ChapterDeco[6]{\decoglyph{n9548}}
+\vspace{4\nbs}
+{\addfontfeature{Scale=3}\theAuthor}
+\vfill
+{\addfontfeature{Scale=1.25} Nonexistent Publications\\
+Anytown • Anyplace • Anywhere}\par
+
+\end{center}
+\clearpage
+
+
+% iv. Copyright page:
+\thispagestyle{empty}
+\begin{center}
+\itshape{
+\null
+\vfill
+\textsc{Dark and Stormy}\par
+Copyright ©2017 Dirk Hardcase.\par % Whichever year, copyright holder.
+All Rights Reserved.\par % Usually no need to be elaborate.
+\null
+This is a work of fiction.\\
+All persons and events are\\
+from the author's imagination.\\
+Resemblance to any real person,\\
+living or dead, is coincidental.\par % Or similar language.
+\null
+Printed on acid-free paper.\par % If true. Usually is true.
+Printed in the United States of America.\par % Or whichever nation.
+\null
+ISBN 0-12345678-9\par % Whatever it is. No barcode, just number.
+\null
+
+Independently Published by Dirk Hardcase,\par % Publisher is you, not the print/distribution service.
+Anytown, Anystate USA\par % Publisher's location.
+www.example.com/dhardcase/publications/\par % Contact for publisher or author.
+\null
+Publisher's Cataloging-In-Publication Data\\
+available upon request.\par
+% Fiction often does not need catalog data.
+} % end itshape
+\end{center}
+\clearpage
+
+% v. Epigraph, Dedication, Table of Contents, or repeated Half-Title.
+% In this case, an Epigraph:
+\thispagestyle{empty}
+\vspace*{7\nbs}
+\begin{adjustwidth}{5em}{5em}
+\noindent When the lone raccoon howls at dusk,\\
+And white birds cease their twitter,\\
+Then shall the rivers overflow with mead.\par
+\hfill---\textit{Prophecy of Claudius}\par
+\end{adjustwidth}
+\cleartorecto % here, inserts blank, so mainmatter begins recto
+
+% Now to begin your story:
+\mainmatter
+
+% Chapter One:
+\begin{ChapterStart}
+\vspace*{3\nbs}
+\ChapterTitle{Chapter One}
+\end{ChapterStart}
+
+It was a dark and stormy night. Lord Withens rode his horse through the gloom, which was, as heretofore mentioned, dark. Most gloom is dark, eh wot?
+
+Moving right along, his horse arrived at the back door of Lady Wishintale's quarters. Sadly, Lord Withens was not on it, having slipped off his saddle along the way. That was because the weather was stormy.
+
+\lipsum
+
+% Chapter Two:
+\clearpage % next chapter may begin recto or verso
+\begin{ChapterStart}
+\vspace*{3\nbs}
+\ChapterTitle{Chapter Two}
+\end{ChapterStart}
+
+The night was still dark and stormy. This should not be surprising, seeing as how only half an hour has elapsed since the first chapter. That information was necessary, in case you put the book down and haven't read any of it for the last two weeks.
+
+Lord Withens, wet and bruised, finally arrived at his destination. The reason he was wet was because, as has been noted, the weather was stormy. It was dark, too.
+
+\lipsum
+
+
+\end{document}
+
diff --git a/macros/luatex/latex/novel/doc/extras/novel-extras-README.html b/macros/luatex/latex/novel/doc/extras/novel-extras-README.html
new file mode 100644
index 0000000000..c199c3cad5
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/extras/novel-extras-README.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+<meta charset="UTF-8" />
+<title>README for novel extras</title>
+</head>
+<body style="padding:16px">
+
+<h2>README for novel extras</h2>
+
+<p>This folder contains items that may be helpful, but are not essential to operation of the <i>novel</i> document class. Version 1.52.</p>
+
+<p>File <i>novel-example.tex</i> is a fake short novel. If you wish to compile it, place a copy in your user home folder (or other place where you have read/write privilege) and compile it there.</p>
+
+<p>File <i>novel-testsuite.tex</i> exercises the various capabilities of the document class. You can look at the code, and see how it compiles. You may also change settings, to see what they do. It requires files <i>novel-testimage.png</i>, <i>novel-testimage.jpg</i>, <i>novel-testscript.png</i>, and <i>novel-testscript.jpg</i>. If you wish to compile it, place a copy (along with images) in your user home folder (or other place where you have read/write privilege) and compile it there.</p>
+
+<p>File <i>novel-decoglyphs.pdf</i> shows the decorative characters in the <i>NovelDeco.otf</i> file, along with the codes needed to retrieve them.</p>
+
+<p>File <i>novel-Gallery-ChapterStart.pdf</i> shows a number of different ways to begin a chapter, making use of the ChapterStart environment and related commands. These are only suggestions.</p>
+
+<p>File <i>CPmodified.otf</i> is not (normally) for use in TeX. I use it when editing my work in a word processor, prior to TeX markup. To use it, install the font in your operating system (not in TeX) where a word processor can find it. This font is nearly-monospaced, with exaggerated punctuation marks. I have found that punctuation errors are most frequently overlooked during editing, since they are so small in many fonts, and the spell-check software doesn't find the errors.</p>
+
+
+<div>
+<h3>novel-scripts.zip</h3>
+<p>This zip archive contains Windows batch scripts, and Linux/OSX BASH scripts, for automatic image conversion.</p>
+<p>The scripts are meant to ensure that your use of images complies with commercial printing standards. In particular, they provide a method for converting color cover artwork to CMYK at 240% ink limit, in a PDF/X-1a:2001 file.</p>
+<p>Complete usage instructions are documented within the zip archive.</p>
+</div>
+
+
+
+
+</body>
+</html>
diff --git a/macros/luatex/latex/novel/doc/extras/novel-testimage.jpg b/macros/luatex/latex/novel/doc/extras/novel-testimage.jpg
new file mode 100644
index 0000000000..6e39d29be5
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/extras/novel-testimage.jpg
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/extras/novel-testimage.png b/macros/luatex/latex/novel/doc/extras/novel-testimage.png
new file mode 100644
index 0000000000..1fabb2ccf2
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/extras/novel-testimage.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/extras/novel-testscript.jpg b/macros/luatex/latex/novel/doc/extras/novel-testscript.jpg
new file mode 100644
index 0000000000..e1fac7cd45
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/extras/novel-testscript.jpg
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/extras/novel-testscript.png b/macros/luatex/latex/novel/doc/extras/novel-testscript.png
new file mode 100644
index 0000000000..77fb7e1da9
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/extras/novel-testscript.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/extras/novel-testsuite.tex b/macros/luatex/latex/novel/doc/extras/novel-testsuite.tex
new file mode 100644
index 0000000000..ae341921db
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/extras/novel-testsuite.tex
@@ -0,0 +1,312 @@
+% !TeX TS-program = LuaLaTeX
+% !TeX encoding = UTF-8
+%
+% TEST SUITE FOR NOVEL DOCUMENT CLASS
+%
+% IF YOU COMPILE THIS DOCUMENT: Be sure that this file, and its generated PDF,
+% have read/write permissions for any user. If they don't, then
+% compile will fail at the point where files are written.
+%
+% This document tests the various capabilities of `novel' document class.
+% The Preamble settings are originally the defaults.
+% Change them to exercise the setting, and see the result.
+% In the document body, various commands are exercised.
+%
+% You need all fonts from the `libertinus' package,
+% all fonts from `lmodern' package,
+% and the included NovelDeco.otf.
+%
+% You also need the file` novel-testimage.png'
+% in the same folder as this document.
+% It is grayscale png, 150x150 pixels, with resolution 300pdi.
+%
+% The `test' class option is required. You may add others.
+\documentclass[test,shademargins,draft]{novel} % v. 1.52.
+\SetTitle{Test Suite}
+\SetSubtitle{Novel Document Class}
+\SetAuthor{Author Name}
+% Additional Preamble, if desired.
+
+
+\begin{document}
+
+\frontmatter % begins at page i.
+
+\thispagestyle{footer}
+\vspace*{5\nbs}
+\begin{center}
+\charscale[3.6]{\textbf{Test Suite}}\par
+\vspace{1.5\nbs}
+\charscale[1.6]{Novel Document Class}\par
+\vspace{4\nbs}
+\ChapterDeco[6]{\decoglyph{n9548}}
+\vspace{2\nbs}
+\charscale[1.5]{The following page will be blank!}\par
+\vfill
+If you choose a head/foot style with footer, then page number i (lowercase roman) will appear in the footer below.\par
+But if the head/foot style has no footer, then nothing below.\par
+\end{center}
+\clearpage
+
+
+% Now to begin at page 1:
+\mainmatter
+
+\begin{ChapterStart}[10]
+\vspace*{3\nbs}
+\ChapterTitle{Chapter One}
+\ChapterSubtitle{Dark and Stormy}
+\ChapterDeco[4]{\decoglyph{n9548}}
+\end{ChapterStart}
+
+This tests the ChapterStart environment, plus \string\ChapterTitle, \string\ChapterSubtitle, \string\ChapterDeco, and \string\decoglyph.
+
+In the TeX document, you can change the height of the environment, the alignment of its components, the decoglyph, and so forth.
+
+The first paragraph will not be indented, but all following paragraphs will be indented.
+
+Since this is a recto (odd-numbered) page at right side, the default margins will be a little larger at left, where there is an allowance for binding gutter.
+
+Unless you change the head/foot style, you should see no heading. Arabic page number 1 should be at the bottom.
+
+\clearpage
+
+
+% NEXT PAGE:
+
+This page tests the \string\charscale\space command, and \string\rotatebox. The combined effect is shown below:\par
+\vspace{1.5\nbs} % trial and error
+\charscale[2,3em,-4em]{\rotatebox[origin=c]{45}{Random Test Items}}
+\vspace{7.5\nbs} % trial and error
+
+Above, you should see the phrase Random Test Items in larger than normal text, tilted 45 degrees, nicely fitting between the text above and this text. Offset has been used, so it is not quite centered.
+
+If you change the font size or number of lines per page, then the tilted phrase might not fit nicely. That can be fixed by changing the amount of \string\vspace\space above and below the rotated text.
+
+The amount of \string\vspace\space is not calculated automatically. You have to determine it by trial and error (or do some math). The total amount of \string\vspace, top and bottom, must be an integer.
+
+If you use \string\rotatebox\space without \string\charscale, then it will create its own vertical gap. Unfortunately, the height of this gap is very difficult for you to calculate, so you would not be able to easily restore the line grid by adding some amount of \string\vspace. So, don't use \string\rotatebox\space without \string\charscale.
+
+\clearpage
+
+
+% NEXT PAGE:
+
+This page tests \string\FloatImage\space effects. Remember that \textit{novel} uses its own methods of placing images.
+
+There will be a gap before the image appears. In the tex code, find \string\vspace\space there, and change the space. At some point, the image will float to the top of the following page.
+
+\vspace{7\nbs}
+
+\FloatImage[ht]{novel-testimage.png}
+
+Above, the top of the image sits where the baseline of text would be. If the image fits where placed, then this paragraph comfortably clears the bottom of the image. If the gap is increased so that the image flats to the top of the next page, then this paragraph will be directly beneath the preceding paragraph.
+
+
+
+\clearpage
+
+% NEXT PAGE:
+
+This page tests \string\InlineImage\space effects. Note that the command also has a starred version. The difference: Unstarred, the width of the image is taken into account. Starred, the width of the image is ignored.
+
+\null
+
+\noindent\InlineImage*[0,\normalXheight]{novel-testimage.png}This paragraph is not indented. The starred command places an image, offset so that its top sits at the X-height of the text. The image underlies the following text. If you use this effect, then be sure that the image is much lighter, or the text will be hard to read.
+
+\null\null\null
+
+\noindent\InlineImage[0,b-\normaldescender]{novel-testimage.jpg}This paragraph is not indented. The unstarred command places an image, offset so that its bottom sits at the descender of the text. It was necessary to insert previous blank lines, or the image would overlie (and obscure) the preceding paragraph.
+
+\null\null
+
+\noindent\InlineImage[0,1.5em]{novel-testscript.png}This paragraph is not indented. The unstarred command places an image, offset so that it rises above the paragraph, and also descends beneath the following text.
+
+\null\null
+
+In all of the above, the alignments will change, if you change the text size or lines per page.
+
+\clearpage
+
+
+% NEXT PAGE:
+
+This page tests \string\WrapImage. The command is written following the paragraph you are now reading.
+
+\WrapImage[r]{novel-testscript.jpg}
+
+The image will appear at right, with this text flowing around it. the first few lines will be at the left of the image. Then, as the paragraph continues, it eventually is restored to full text width, once it gets past the bottom of the image. Note that the top of the image is aligned to the X-height of the first line of text.
+
+\null
+\null
+
+\clearpage
+
+% NEXT 2 PAGES:
+
+This page, combined with the following page, test the detection mechanism for \string\scenebreak, \string\sceneline, and \string\scenestars.
+
+In the source document, there is \string\vspace\space following this paragraph. To detect the effects, vary the \string\vspace.
+
+% Change this to see the effects:
+\vspace{20\nbs} % originally 20\nbs
+
+Following this paragraph is the \string\scenestars\space command. It prints a few asterisks centered in a gap. It is one way to indicate that a scenbreak is present, when the break occurs at the very top or bottom of a page (because a blank line might not be noticed there).
+
+\scenestars
+
+If you change the above \string\vspace\space to 25\string\nbs, you will get a Warning about the line being too close to the bottom. Change to 28\string\nbs, and the Warning will say that it is too close to the top (of the following page. Note that \string\scenestars\space is allowed to be at the very bottom or very top, or somewhere in the middle of the page. The same applies to \string\sceneline.
+
+If you wish, you can always use \string\scenestars\space or \string\sceneline\space to indicate a scene break. But more common practice is to use a blank line, \string\scenebreak, except for those cases where you ``must'' use one of the others.
+
+\scenebreak
+
+Above this paragraph is \string\scenebreak, which appears as a blank line. A \string\scenebreak\space cannot be located close to the top or bottom of a page. Unlike \string\sceneline\space or \string\scenestars, you cannot place \string\scenebreak\space at the very top or bottom, either. So, changing the \string\vspace\space to any of 14\string\nbs\space through 17\string\nbs\space will generate a Warning.
+
+\clearpage
+
+
+% NEXT PAGE:
+
+This page tests the footnote and endnote capabilities.\footnote{This is the first sample footnote. Unless you change the marker style, it will be marked with an asterisk.} Two footnotes have been placed.\footnote{This is the second footnote. Unless you change the marker style, it will be marked by a dagger.}
+
+\null
+
+Test of \string\QuickChapter:
+
+
+\QuickChapter[3em]{Just Before Midnight}
+
+Above, \string\QuickChapter\space inserted two blank lines, in which a phrase is followed by a short line. The text is slightly larger than normal, and sits slightly above the normal baseline.
+
+\null
+
+There is a \string\bigemdash\space between here\makebox[2.5em]{\bigemdash}and here. Its length is set at 2.5em, using \string\makebox. Compare to normal—emdash. Thickness and yoffset is adjustable.
+
+\null
+
+This tests the endnote capability.\endnote You will see marker 1 after the last sentence, and marker 2 after this one.\endnote\memo{This text does not print.} But no actual endnotes are created. You may manually place them wherever you wish. For that, you may use the \string\endnotetext\space command (if its style works for you), or any other method.
+
+\null
+
+\endnotetext{1}{This tests the \string\endnotetext\space command, although you would not normally place the text of an endnote here. It is only a test.\par}
+
+\endnotetext{2}{Text for a second endnote.\par}
+
+\clearpage
+
+
+% NEXT PAGE:
+
+The following tests the \textit{parascale} environment:
+
+\begin{parascale}[0.8]
+But this text has a different scale than normal. Both the font size and the baseline skip have been proportionately changed. As a result, the lines are not on the normal line grid.\par
+If the following normal text needs to be back on grid (usually the case), here is what you must do: Compile, and note the number of lines occupied by the scaled text. Calculate the discrepancy, and fix with \string\vspace. Or let \textit{novel} do the thinking for you; there will be a Warning message with advice.\par
+\vspace{0.2\nbs} % based on result of Warning.
+\end{parascale}
+
+Back to normal text. At the dimensions originally used for this test, there are 9 lines of scaled text. Not counting the first scaled line, the remaining 8 scaled lines each introduce a deficit of 0.2\string\nbs. So, the cumulative deficit is 1.6\string\nbs. The integer part doesn't matter. So, \string\vspace{0.6\string\nbs} must be added prior to \string\end\{parascale\}, to restore the normal line grid.
+
+It is also possible to split the \string\vspace, prior to \string\begin\{parascale\} and \string\end\{parascale\}, as long as the total is correct.
+
+If the \string\vspace\space is not added, then there will be a Warning message.
+
+If the parascale spans more than one page, then the correct amount to add will depend on the lines present on the final page, not the total number of lines.
+
+\clearpage
+
+
+% NEXT PAGE
+
+This page tests the \textit{adjustwidth} environment. Changing textwidth is a useful way to create block indents, occasionally used for long quotations, or for other special text that must be visually distinguished from normal.
+
+\begin{adjustwidth}{2\normalparindent}{\normalparindent}
+\forceindent This text uses the \textit{adjustwidth} environment. It is set to block indent 2\string\normalparindent\space at left, and indent 1\string\normalparindent\space at right. The \string\forceindent\space command precedes the text, so that (within the block) it indents like an ordinary paragraph.\par
+\end{adjustwidth}
+
+This text is after the environment, so it occupies the normal amount of text width.
+
+\clearpage
+
+
+% NEXT PAGE:
+
+This tests various text effects:
+
+\null
+
+\FirstLine{\noindent\charscale[2]{T}\hspace{-2pt}his line has its first letter enlarged, and sets the first line in small caps. After the first line, text continues as usual. Note that space must be provided prior to this paragraph, so that the first letter does not intrude on text (or margin) above it.}
+
+The \string\charscale\space command scales the letter, and \string\FirstLine\space performs the small caps. Also, some kerning was applied so that the large T has the following \textsc{h} resting beneath its top. The \string\noindent\space command goes inside \string\FirstLine.
+
+\null\null
+
+\dropcap{H}ere is placed is a drop cap, using \textit{novel's} \string\dropcap\space command. Alternatively, the \textit{lettrine} package could be used. There are differences in how the drop caps are specified, depending on what you do. So, be sure to read the documentation, or you will be surprised.\par
+In general, it is difficult to style drop caps so that they look good for many different letters. An alternative is to use images for the drop caps. If you use images, please read the \textit{novel} documentation, as the method is not the same as the usual methods from the \textsc{lettrine} package.\par
+Note that there is no automated way to combine a drop cap with a first line in small caps. This is discussed in \textsc{novel} documentation.
+
+\null
+This line is in the main font.\par
+\textsf{This line is in the sans font.}\par
+\texttt{This line is in the mono font.}\par
+{\mustbelibertinus This line is in Libertinus Serif.}\par % specific to testsuite
+{\mustbelmodern This line is in Latin Modern Roman.}\par % specific to testsuite
+
+
+\clearpage
+
+
+% NEXT PAGE:
+
+\thispagestyle{dropfoliobeneath} % compare to dropfolioinside
+
+This page tests drop folio. There will be no page header. If your head/foot style normally has a footer, then you will see it as usual.
+
+If you choose a head/foot style without footer, you will still see a page number centered below. Exactly where it appears will depend on which kind of drop folio is used.
+
+If using \string\thispagestyle\{dropfoliobeneath\} then the page number will appear within the lower margin.
+
+If using \string\thispagestyle\{dropfolioinside\} then the page number will appear just above the lower margin, where the final line of text would otherwise be placed.
+
+Use class options [draft,shademargins] to see the position.
+
+The initial choice is \textit{dropfoliobeneath}.
+
+\clearpage
+
+% NEXT PAGE:
+
+This tests the \string\cleartoend\space command. If this page is recto (odd), then exactly one blank page will follow. If this page is verso (even), then exactly two blank pages will follow.
+
+\null\null
+
+
+When you request PDF/X (default), whether or not you are in draft mode, each image placed in your document is inspected. This is one of those things that require Lua code, which is one reason why the \textit{novel} class requires LuaLaTeX only.
+
+When an image is inspected, it is added to one of two lists, either good or unknown. Each time an image is requested, the lists are examined, so the same image file is not inspected twice. This saves time.
+
+The lists are saved in the \textit{aux} file. Then, if you re-compile, images already inspected won't be re-inspected. To re-initialize the lists, discard the \textit{aux} file.
+
+\null
+
+Two of the images were pre-processed via \textit{novel-scripts}. These will be detected as good. They are:
+
+\makeatletter\@AllGoodImages\makeatother
+
+\null
+
+Two of the images were not pre-processed, so their compliance is unknown. They might be good or bad. They are:
+
+ \makeatletter\@UnknownImages\makeatother
+
+\null
+
+Note: If you change the document settings to \string\SetPDFX\{off\} then you will not see either of the image lists, and will not get the Warning message.
+
+Also, using \string\SetPDFX\{off\} will re-initialize the lists.
+
+
+
+\end{document}
+
diff --git a/macros/luatex/latex/novel/doc/html-resources/10transold.png b/macros/luatex/latex/novel/doc/html-resources/10transold.png
new file mode 100644
index 0000000000..515a544795
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/10transold.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/10trueold.png b/macros/luatex/latex/novel/doc/html-resources/10trueold.png
new file mode 100644
index 0000000000..5b9809dc25
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/10trueold.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/CPmodified-sample.png b/macros/luatex/latex/novel/doc/html-resources/CPmodified-sample.png
new file mode 100644
index 0000000000..e7efeb44ae
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/CPmodified-sample.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/I-shade.png b/macros/luatex/latex/novel/doc/html-resources/I-shade.png
new file mode 100644
index 0000000000..b22694e83f
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/I-shade.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/Iboxcap.png b/macros/luatex/latex/novel/doc/html-resources/Iboxcap.png
new file mode 100644
index 0000000000..f23548fe79
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/Iboxcap.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/acronym2.png b/macros/luatex/latex/novel/doc/html-resources/acronym2.png
new file mode 100644
index 0000000000..62399d36b7
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/acronym2.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/alphabetagamma.png b/macros/luatex/latex/novel/doc/html-resources/alphabetagamma.png
new file mode 100644
index 0000000000..da3750d618
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/alphabetagamma.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/authorsnote.png b/macros/luatex/latex/novel/doc/html-resources/authorsnote.png
new file mode 100644
index 0000000000..a07b0b1b1f
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/authorsnote.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/badaboom.png b/macros/luatex/latex/novel/doc/html-resources/badaboom.png
new file mode 100644
index 0000000000..209e3638e6
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/badaboom.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/bixby-original.png b/macros/luatex/latex/novel/doc/html-resources/bixby-original.png
new file mode 100644
index 0000000000..60b88ab019
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/bixby-original.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/bixby-softproof.png b/macros/luatex/latex/novel/doc/html-resources/bixby-softproof.png
new file mode 100644
index 0000000000..e30c22804c
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/bixby-softproof.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/bookmanglerdashboard.png b/macros/luatex/latex/novel/doc/html-resources/bookmanglerdashboard.png
new file mode 100644
index 0000000000..860ba4db7b
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/bookmanglerdashboard.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/bookofbeirh.png b/macros/luatex/latex/novel/doc/html-resources/bookofbeirh.png
new file mode 100644
index 0000000000..75c93f7358
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/bookofbeirh.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/chaptertitlesubtitle.png b/macros/luatex/latex/novel/doc/html-resources/chaptertitlesubtitle.png
new file mode 100644
index 0000000000..f82d20a9fe
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/chaptertitlesubtitle.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/charscaletext.png b/macros/luatex/latex/novel/doc/html-resources/charscaletext.png
new file mode 100644
index 0000000000..1f7dc9a245
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/charscaletext.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/closecrop.png b/macros/luatex/latex/novel/doc/html-resources/closecrop.png
new file mode 100644
index 0000000000..0aee0430d5
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/closecrop.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/colormax-original.png b/macros/luatex/latex/novel/doc/html-resources/colormax-original.png
new file mode 100644
index 0000000000..f7ba4e22da
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/colormax-original.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/colormax-softproof.png b/macros/luatex/latex/novel/doc/html-resources/colormax-softproof.png
new file mode 100644
index 0000000000..cd0072ecd5
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/colormax-softproof.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/colorsampler-softproof.png b/macros/luatex/latex/novel/doc/html-resources/colorsampler-softproof.png
new file mode 100644
index 0000000000..ecc217db4c
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/colorsampler-softproof.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/colorsampler.png b/macros/luatex/latex/novel/doc/html-resources/colorsampler.png
new file mode 100644
index 0000000000..bc1850a71d
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/colorsampler.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/cropmarks.png b/macros/luatex/latex/novel/doc/html-resources/cropmarks.png
new file mode 100644
index 0000000000..56bb38f4c0
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/cropmarks.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/cropview.png b/macros/luatex/latex/novel/doc/html-resources/cropview.png
new file mode 100644
index 0000000000..4c317fdfef
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/cropview.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/ctimg35.png b/macros/luatex/latex/novel/doc/html-resources/ctimg35.png
new file mode 100644
index 0000000000..17f17cc90e
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/ctimg35.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/doordie.png b/macros/luatex/latex/novel/doc/html-resources/doordie.png
new file mode 100644
index 0000000000..7d2682b3ac
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/doordie.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/dorfmcnorf.png b/macros/luatex/latex/novel/doc/html-resources/dorfmcnorf.png
new file mode 100644
index 0000000000..71d5d6cc1d
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/dorfmcnorf.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/dropcap-antestar.png b/macros/luatex/latex/novel/doc/html-resources/dropcap-antestar.png
new file mode 100644
index 0000000000..8032e77c39
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/dropcap-antestar.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/dropcap-gap.png b/macros/luatex/latex/novel/doc/html-resources/dropcap-gap.png
new file mode 100644
index 0000000000..f224662d6c
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/dropcap-gap.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/dropcap-scalebloat.png b/macros/luatex/latex/novel/doc/html-resources/dropcap-scalebloat.png
new file mode 100644
index 0000000000..10642ee212
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/dropcap-scalebloat.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/dropcap.png b/macros/luatex/latex/novel/doc/html-resources/dropcap.png
new file mode 100644
index 0000000000..19343ec823
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/dropcap.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/emblembar.png b/macros/luatex/latex/novel/doc/html-resources/emblembar.png
new file mode 100644
index 0000000000..ace8baa000
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/emblembar.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/emblemdingbats.png b/macros/luatex/latex/novel/doc/html-resources/emblemdingbats.png
new file mode 100644
index 0000000000..d7a1963dcb
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/emblemdingbats.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/emblemimg.png b/macros/luatex/latex/novel/doc/html-resources/emblemimg.png
new file mode 100644
index 0000000000..6d85eab129
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/emblemimg.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/endnotetext.png b/macros/luatex/latex/novel/doc/html-resources/endnotetext.png
new file mode 100644
index 0000000000..b8364968fd
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/endnotetext.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/firstletterspecial.png b/macros/luatex/latex/novel/doc/html-resources/firstletterspecial.png
new file mode 100644
index 0000000000..e527dfab3b
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/firstletterspecial.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/firstlinespecial.png b/macros/luatex/latex/novel/doc/html-resources/firstlinespecial.png
new file mode 100644
index 0000000000..e1ebfe3cb5
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/firstlinespecial.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/fluffy-conspiracy.png b/macros/luatex/latex/novel/doc/html-resources/fluffy-conspiracy.png
new file mode 100644
index 0000000000..00e9d5b89b
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/fluffy-conspiracy.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/font-tree.png b/macros/luatex/latex/novel/doc/html-resources/font-tree.png
new file mode 100644
index 0000000000..8dfd260197
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/font-tree.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/fontbyfamily.png b/macros/luatex/latex/novel/doc/html-resources/fontbyfamily.png
new file mode 100644
index 0000000000..1f67748159
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/fontbyfamily.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/fontbyfilenamei.png b/macros/luatex/latex/novel/doc/html-resources/fontbyfilenamei.png
new file mode 100644
index 0000000000..77c8ca74db
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/fontbyfilenamei.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/fpaper.png b/macros/luatex/latex/novel/doc/html-resources/fpaper.png
new file mode 100644
index 0000000000..204be0027d
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/fpaper.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/frankenfont.png b/macros/luatex/latex/novel/doc/html-resources/frankenfont.png
new file mode 100644
index 0000000000..3ecb22dd7e
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/frankenfont.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/gnome-censored.png b/macros/luatex/latex/novel/doc/html-resources/gnome-censored.png
new file mode 100644
index 0000000000..7a362452b6
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/gnome-censored.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/graytext.png b/macros/luatex/latex/novel/doc/html-resources/graytext.png
new file mode 100644
index 0000000000..c37f843954
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/graytext.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/head-foot-jumps.png b/macros/luatex/latex/novel/doc/html-resources/head-foot-jumps.png
new file mode 100644
index 0000000000..d7f3495735
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/head-foot-jumps.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/headfont-default.png b/macros/luatex/latex/novel/doc/html-resources/headfont-default.png
new file mode 100644
index 0000000000..57b57c46a6
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/headfont-default.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/headfont-montserrat-el.png b/macros/luatex/latex/novel/doc/html-resources/headfont-montserrat-el.png
new file mode 100644
index 0000000000..d19d0664c1
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/headfont-montserrat-el.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/headfont-roboto.png b/macros/luatex/latex/novel/doc/html-resources/headfont-roboto.png
new file mode 100644
index 0000000000..8363bb9baa
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/headfont-roboto.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/headfoot1.png b/macros/luatex/latex/novel/doc/html-resources/headfoot1.png
new file mode 100644
index 0000000000..d418c4a6f5
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/headfoot1.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/headfoot2.png b/macros/luatex/latex/novel/doc/html-resources/headfoot2.png
new file mode 100644
index 0000000000..9dbd29dd6c
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/headfoot2.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/headfoot3.png b/macros/luatex/latex/novel/doc/html-resources/headfoot3.png
new file mode 100644
index 0000000000..90b2ffecfe
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/headfoot3.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/headfoot4.png b/macros/luatex/latex/novel/doc/html-resources/headfoot4.png
new file mode 100644
index 0000000000..1970088379
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/headfoot4.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/headfoot5.png b/macros/luatex/latex/novel/doc/html-resources/headfoot5.png
new file mode 100644
index 0000000000..c8ddd6f1bc
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/headfoot5.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/headfoot6.png b/macros/luatex/latex/novel/doc/html-resources/headfoot6.png
new file mode 100644
index 0000000000..bf39f21d3a
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/headfoot6.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/human-robot-talk.png b/macros/luatex/latex/novel/doc/html-resources/human-robot-talk.png
new file mode 100644
index 0000000000..461b4eb6d4
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/human-robot-talk.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/imgdialogs.png b/macros/luatex/latex/novel/doc/html-resources/imgdialogs.png
new file mode 100644
index 0000000000..a8fce8d662
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/imgdialogs.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/info18.png b/macros/luatex/latex/novel/doc/html-resources/info18.png
new file mode 100644
index 0000000000..7a58a6c706
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/info18.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/inlineimagest.png b/macros/luatex/latex/novel/doc/html-resources/inlineimagest.png
new file mode 100644
index 0000000000..18420d8b20
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/inlineimagest.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/jackbequick.png b/macros/luatex/latex/novel/doc/html-resources/jackbequick.png
new file mode 100644
index 0000000000..5a63e4d37e
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/jackbequick.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/jollybeers.png b/macros/luatex/latex/novel/doc/html-resources/jollybeers.png
new file mode 100644
index 0000000000..f9f94ffc4f
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/jollybeers.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/jpgcolorspace.png b/macros/luatex/latex/novel/doc/html-resources/jpgcolorspace.png
new file mode 100644
index 0000000000..33c1fb7eb9
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/jpgcolorspace.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/jump-change.png b/macros/luatex/latex/novel/doc/html-resources/jump-change.png
new file mode 100644
index 0000000000..e9bf5a1b72
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/jump-change.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/looseheads.png b/macros/luatex/latex/novel/doc/html-resources/looseheads.png
new file mode 100644
index 0000000000..8eda2d17da
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/looseheads.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/lowdown.png b/macros/luatex/latex/novel/doc/html-resources/lowdown.png
new file mode 100644
index 0000000000..3d0f6ae7cd
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/lowdown.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/map.png b/macros/luatex/latex/novel/doc/html-resources/map.png
new file mode 100644
index 0000000000..f11a133a93
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/map.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/margins-trim-media.png b/macros/luatex/latex/novel/doc/html-resources/margins-trim-media.png
new file mode 100644
index 0000000000..55cca64c0f
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/margins-trim-media.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/mcdingle.png b/macros/luatex/latex/novel/doc/html-resources/mcdingle.png
new file mode 100644
index 0000000000..f6449ce9a6
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/mcdingle.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/mediasize.png b/macros/luatex/latex/novel/doc/html-resources/mediasize.png
new file mode 100644
index 0000000000..6e2319389c
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/mediasize.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/megadocprops.png b/macros/luatex/latex/novel/doc/html-resources/megadocprops.png
new file mode 100644
index 0000000000..e89828153d
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/megadocprops.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/megatitlepagesm.png b/macros/luatex/latex/novel/doc/html-resources/megatitlepagesm.png
new file mode 100644
index 0000000000..6726c89395
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/megatitlepagesm.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/monitorgamut.png b/macros/luatex/latex/novel/doc/html-resources/monitorgamut.png
new file mode 100644
index 0000000000..0bbabd4a94
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/monitorgamut.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/no-brainer.png b/macros/luatex/latex/novel/doc/html-resources/no-brainer.png
new file mode 100644
index 0000000000..7bf7f96468
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/no-brainer.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/novel-color-sampler.png b/macros/luatex/latex/novel/doc/html-resources/novel-color-sampler.png
new file mode 100644
index 0000000000..259d4e1ed7
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/novel-color-sampler.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/overflowrule.png b/macros/luatex/latex/novel/doc/html-resources/overflowrule.png
new file mode 100644
index 0000000000..97c4f63cd4
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/overflowrule.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/page-leaf.png b/macros/luatex/latex/novel/doc/html-resources/page-leaf.png
new file mode 100644
index 0000000000..70562ef094
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/page-leaf.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/parascale.png b/macros/luatex/latex/novel/doc/html-resources/parascale.png
new file mode 100644
index 0000000000..60fc03b15e
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/parascale.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/perfectbinding.png b/macros/luatex/latex/novel/doc/html-resources/perfectbinding.png
new file mode 100644
index 0000000000..3073971ea7
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/perfectbinding.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/pngcolortype.png b/macros/luatex/latex/novel/doc/html-resources/pngcolortype.png
new file mode 100644
index 0000000000..78cce712fe
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/pngcolortype.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/printgamut.png b/macros/luatex/latex/novel/doc/html-resources/printgamut.png
new file mode 100644
index 0000000000..3b14f07365
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/printgamut.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/quickchapter.png b/macros/luatex/latex/novel/doc/html-resources/quickchapter.png
new file mode 100644
index 0000000000..59f2dcf4d7
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/quickchapter.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/raffaelino-original.png b/macros/luatex/latex/novel/doc/html-resources/raffaelino-original.png
new file mode 100644
index 0000000000..4767d1290f
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/raffaelino-original.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/raffaelino-softproof.png b/macros/luatex/latex/novel/doc/html-resources/raffaelino-softproof.png
new file mode 100644
index 0000000000..b542d6097c
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/raffaelino-softproof.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/robberies.png b/macros/luatex/latex/novel/doc/html-resources/robberies.png
new file mode 100644
index 0000000000..6e93704cbd
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/robberies.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/scenebreaks.png b/macros/luatex/latex/novel/doc/html-resources/scenebreaks.png
new file mode 100644
index 0000000000..8ef958c7e5
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/scenebreaks.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/shademargins.png b/macros/luatex/latex/novel/doc/html-resources/shademargins.png
new file mode 100644
index 0000000000..a0b48f41c1
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/shademargins.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/shakepi.png b/macros/luatex/latex/novel/doc/html-resources/shakepi.png
new file mode 100644
index 0000000000..6104e38c2a
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/shakepi.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/signature.png b/macros/luatex/latex/novel/doc/html-resources/signature.png
new file mode 100644
index 0000000000..8d0b0d782d
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/signature.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/simpletoc.png b/macros/luatex/latex/novel/doc/html-resources/simpletoc.png
new file mode 100644
index 0000000000..752f122326
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/simpletoc.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/sixpage-frontmatter.png b/macros/luatex/latex/novel/doc/html-resources/sixpage-frontmatter.png
new file mode 100644
index 0000000000..e8b206679d
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/sixpage-frontmatter.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/skygrad.jpg b/macros/luatex/latex/novel/doc/html-resources/skygrad.jpg
new file mode 100644
index 0000000000..14cc5b7014
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/skygrad.jpg
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/smallcapsrealfake.png b/macros/luatex/latex/novel/doc/html-resources/smallcapsrealfake.png
new file mode 100644
index 0000000000..9c367cb1fa
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/smallcapsrealfake.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/smfingerprint8.png b/macros/luatex/latex/novel/doc/html-resources/smfingerprint8.png
new file mode 100644
index 0000000000..7370d52370
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/smfingerprint8.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/smythsewn.png b/macros/luatex/latex/novel/doc/html-resources/smythsewn.png
new file mode 100644
index 0000000000..c877c9b9dc
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/smythsewn.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/toc.png b/macros/luatex/latex/novel/doc/html-resources/toc.png
new file mode 100644
index 0000000000..27d15fa5f0
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/toc.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/topmargins.png b/macros/luatex/latex/novel/doc/html-resources/topmargins.png
new file mode 100644
index 0000000000..7f4ecfc34b
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/topmargins.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/trdol.png b/macros/luatex/latex/novel/doc/html-resources/trdol.png
new file mode 100644
index 0000000000..d61c3e96fd
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/trdol.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/trimsize.png b/macros/luatex/latex/novel/doc/html-resources/trimsize.png
new file mode 100644
index 0000000000..b21a18b026
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/trimsize.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/ublibser.png b/macros/luatex/latex/novel/doc/html-resources/ublibser.png
new file mode 100644
index 0000000000..7d4c393cb5
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/ublibser.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/unsafe-vs-margin.png b/macros/luatex/latex/novel/doc/html-resources/unsafe-vs-margin.png
new file mode 100644
index 0000000000..1b70d3c350
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/unsafe-vs-margin.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/whichgutter.png b/macros/luatex/latex/novel/doc/html-resources/whichgutter.png
new file mode 100644
index 0000000000..f1d1274104
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/whichgutter.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/win10libser.png b/macros/luatex/latex/novel/doc/html-resources/win10libser.png
new file mode 100644
index 0000000000..5c5459a5e1
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/win10libser.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/workedforme.png b/macros/luatex/latex/novel/doc/html-resources/workedforme.png
new file mode 100644
index 0000000000..aeb26f6025
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/workedforme.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/html-resources/wrapme.png b/macros/luatex/latex/novel/doc/html-resources/wrapme.png
new file mode 100644
index 0000000000..b2f433cefb
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/html-resources/wrapme.png
Binary files differ
diff --git a/macros/luatex/latex/novel/doc/novel-documentation.html b/macros/luatex/latex/novel/doc/novel-documentation.html
new file mode 100644
index 0000000000..c2f454e47a
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/novel-documentation.html
@@ -0,0 +1,3270 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+<title>Document class "novel" - documentation</title>
+
+<style>
+body {font-family:sans-serif; line-height:150%; font-size:14pt; color:#000000; background:#ffffff none;}
+p {font-family:sans-serif,sans-serif; font-size:1em; margin:0px 16px 0px 16px; text-indent:16px;}
+ol, ul {list-style-type:none; margin:0px; padding:0px;}
+li {margin:3px 8px 3px 16px; padding:0px;}
+li p {margin: 0px 8px 0px 44px; text-indent:-44px;}
+a {text-decoration:none; color:#990000}
+h1 {font-size:1.33em; margin:16px 16px 0px 8px; font-weight:bold; clear:both; padding-top:8px;}
+h2 {font-size:1.25em; margin:8px 16px 0px 8px; font-weight:bold; clear:both; padding-top:8px;}
+h3 {font-size:1.15em; margin:8px 16px 0px 8px; font-weight:bold; clear:both; padding-top:8px;}
+h4 {font-size:1em; margin:8px 16px 0px 8px; font-weight:bold; clear:both; padding-top:8px;}
+h5 {font-size:1em; margin:8px 16px 0px 8px; clear:both; padding-top:8px;}
+h6 {font-size:1em; margin:8px 16px 0px 8px; clear:both; padding-top:8px;}
+em {font-weight:normal}
+img {max-width:100%;}
+img.nodisplaynav {display:none; height:1em;}
+img.openclose {display:none; height:1em;}
+*.noimg {padding-left:1.5em;}
+div.d1 {margin:0px 16px 16px 16px;}
+div.d2 {margin:0px 0px 16px 16px; padding-bottom:1em; border-top:0; border-right: 0px; border-bottom:1px dotted #666666; border-left:1px dotted #666666;}
+div.d3 {margin:0px 0px 16px 16px; padding-bottom:1em; border-top:0; border-right: 0px; border-bottom:1px dotted #666666; border-left:1px dotted #666666;}
+div.d4 {margin:0px 0px 16px 16px; padding-bottom:1em; border-top:0; border-right: 0px; border-bottom:1px dotted #666666; border-left:1px dotted #666666;}
+div.d5 {margin:0px 0px 16px 16px; padding-bottom:1em; border-top:0; border-right: 0px; border-bottom:1px dotted #666666; border-left:1px dotted #666666;}
+div.d6 {margin:0px 0px 16px 16px; padding-bottom:1em; border-top:0; border-right: 0px; border-bottom:1px dotted #666666; border-left:1px dotted #666666;}
+div.page {padding:16px 0px 16px 0px; border-top:4px solid #505050;}
+div.codeblock {overflow:auto; margin:16px; padding: 8px; border: 1px solid #000000;}
+code {font-size:1em; font-family:monospace,monospace; color:#200050; background:transparent none; padding:0px 3px 0px 3px;}
+*.smaller {font-weight:normal; font-size:88%;}
+*.noindent {text-indent:0px;}
+*.noindent1 {text-indent:0px; margin-top:8px;}
+*.noindent2 {text-indent:0px; margin-bottom:8px;}
+*.noindentcmd {text-indent:0px; margin-top:16px;}
+*.isolate {padding-left:10px;margin-top:10px; margin-bottom:10px; text-indent:0px;}
+*.dbloc {padding-left:1.8em; visibility:hidden}
+table.preconf {margin-left:auto; margin-right:auto; margin-top:20px; margin-bottom:20px; border:1px solid #000000}
+table.preconf caption {font-weight:bold;}
+table.preconf th {text-align:left; padding:6px; font-weight:normal; border-bottom:1px solid #000000;}
+table.preconf td {text-align:left; padding:6px;}
+table.preconf tfoot td {border-top:1px solid #000000;}
+table.preconf p {text-indent:0px; margin:6px;}
+*.onedown {font-size:smaller}
+*.menuitem {text-indent:-8px; margin-left:24px; margin-top:0px; margin-bottom:0px;}
+small {line-height:50%;}
+span.ap {color: #996633;} /* percent comment in code */
+*.floatright {float:right; margin-left:1em; margin-right:16px;}
+*.n {display:none; border:1px solid #990000; font-family:monospace,monospace; font-size:0.92em; font-weight:bold; padding: 0 0.3em 0 0.3em; color:#990000; background: #ffdddd none; margin-right:0.5em;}
+p.centerimg {text-indent:0px; text-align:center; margin-top:0.5em; margin-bottom:0.5em;}
+p.code {text-indent:0px; margin: 4px 16px 4px 16px; padding-left:32px;}
+p.item {text-indent:0px; padding-top:8px;}
+b em {font-weight:normal;}
+hr.newpage {margin-top:2em; margin-bottom:2em; height:4px; color:#505050; background:#505050;}
+p.overhang {margin-left:32px; text-indent:-16px;}
+*.sampledoc {margin:1em}
+*.sampledoc em {font-size:92%; color:#666666}
+#master {position:relative;}
+#finish {clear:both;}
+#toc {display:block;}
+#toc li ul li {display:none;}
+#main {width:auto; float:none; background:#ffffff none;}
+*.noshowprint {display:none;}
+div.codeblock p {text-indent:0px;}
+*.screennoscript {display:none;}
+</style>
+
+<style id="screenstyle">
+@media screen {
+ body {color:#203310; background:#cccccc none;}
+ #toc {display:block; font-size:14pt; width:30%; background:#ffffff none; position:fixed; overflow:scroll; height:98%;}
+ #toc li ul li {display:block;}
+ #main {float:right; background:#ffffff none; width:68%; padding-bottom:40px;}
+ div.codeblock p {text-indent:0px; white-space:nowrap;}
+ *.screennoscript {display:inline;}
+ *.toptitle {display:none;}
+}
+</style>
+<script>var doprint=false;</script>
+
+
+<!-- Trouble Printing? Remove the following line, and another one below: -->
+<!-- REMOVE ME
+
+<style>
+ body {color:#000000; background:#ffffff none;}
+ #toc {display:block; font-size:1em; width:auto; background:#ffffff none; position:static; overflow:auto; height:auto;}
+ #toc li ul li {display:none;}
+ #main {float:none; background:#ffffff none; width:auto; padding-bottom:0;}
+ div.codeblock p {text-indent:0px; white-space:auto;}
+ *.screennoscript {display:none;}
+ *.toptitle {display:block;}
+ *.notprinted {display:none;}
+</style>
+<script>doprint=true;</script>
+
+REMOVE ME TOO -->
+<!-- Also remove the above line, if trouble printing. Then load with JavaScript off. -->
+
+
+<script>
+if(!doprint) {window.onload = loadnav;}
+function loadnav() {
+ nspans = document.getElementsByClassName("n");
+ placenav();
+}
+function placenav(){
+ for(var n=0; nspans.length>n; n++){
+ nspans[n].style.display="inline";
+ nspans[n].style.cursor="pointer";
+ nspans[n].title="open";
+ nspans[n].setAttribute("data-state",0);
+ nspans[n].innerHTML="+";
+ nspans[n].onclick=openclose;
+ lstartclose(n);
+ }
+}
+function lstartclose(whichn) {
+ whichparid = nspans[whichn].parentElement.id;
+ whichdiv = document.getElementById("u" + whichparid.substring(1));
+ if(whichdiv) whichdiv.style.display="none";
+}
+function openclose(){
+ thisparid = this.parentElement.id;
+ thisdiv = document.getElementById("u" + thisparid.substring(1));
+ if(this.title=="close") {thisdiv.style.display="none";}
+ if(this.title=="open") {thisdiv.style.display="block";}
+ thisstate = this.getAttribute("data-state");
+ thisval = 1 - thisstate;
+ this.setAttribute("data-state",thisval);
+ if(this.getAttribute("data-state")=="1") {this.title="close"; this.innerHTML="&ndash;";}
+ if(this.getAttribute("data-state")=="0") {this.title="open"; this.innerHTML="+";}
+}
+function openall() {
+ for(var n=0; nspans.length>n; n++){
+ nspans[n].setAttribute("data-state",1);
+ nspans[n].title="close";
+ nspans[n].innerHTML="&ndash;";
+ thisparid = nspans[n].parentElement.id;
+ thisdiv = document.getElementById("u" + thisparid.substring(1));
+ thisdiv.style.display="block";
+ }
+}
+function closeall() {
+ placenav();
+}
+</script>
+
+</head>
+
+<body>
+<div id="master">
+
+
+<div id="toc" class="toc">
+
+<h1 class="toptitle">Document class <em>novel</em> - Documentation</h1>
+<h3 class="noshowprint"><a href="#main">Contents</a> &nbsp; <span class="smaller"><a href="javascript:openall();">(open all)</a> &nbsp; <a href="javascript:closeall();">(close all)</a></span></h3>
+
+<ul><!-- master toc ul -->
+
+ <li id="l0"><a href="#h0"><b>&ldquo;Novel&rdquo; Document Class</b></a></li>
+
+ <li id="l1"><span class="n"></span><a href="#h1"><b>1. Before You Begin</b></a>
+ <ul id="u1">
+ <li id="l1.1"><span class="n"></span><a href="#h1.1">1.1 Do These Things</a>
+ <ul id="u1.1">
+ <li><a href="#h1.1.1">1.1.1 LuaLateX Compiler</a></li>
+ <li><a href="#h1.1.2">1.1.2 UTF-8 Encoding</a></li>
+ <li><a href="#h1.1.3">1.1.3 Polyglossia</a></li>
+ <li><a href="#h1.1.4">1.1.4 Open Type Fonts</a></li>
+ <li><a href="#h1.1.5">1.1.5 Book Design</a></li>
+ </ul>
+ </li><!-- end 1.1 -->
+ <li id="l1.2"><span class="n"></span><a href="#h1.2">1.2 Avoid These Things</a>
+ <ul id="u1.2">
+ <li><a href="#h1.2.1">1.2.1 Non-Fontspec Font Loader</a></li>
+ <li><a href="#h1.2.2">1.2.2 TeX Font Sizes</a></li>
+ <li><a href="#h1.2.3">1.2.3 Academic Structures</a></li>
+ <li><a href="#h1.2.4">1.2.4 TeX Editors and IDEs</a></li>
+ </ul>
+ </li><!-- end 1.2 -->
+ <li id="l1.3"><span class="n"></span><a href="#h1.3">1.3 Beware of These Things</a>
+ <ul id="u1.3">
+ <li><a href="#h1.3.1">1.3.1 TeX Special Characters</a></li>
+ <li><a href="#h1.3.2">1.3.2 Layout Surprises</a></li>
+ </ul>
+ </li><!-- end 1.3 -->
+ </ul>
+ </li><!-- end 1 -->
+
+ <li id="l2"><span class="n"></span><a href="#h2"><b>2. Document Class Options</b></a>
+ <ul id="u2">
+ <li><a href="#h2.1">2.1 draft</a></li>
+ <li><a href="#h2.2">2.2 sandbox</a></li>
+ <li><a href="#h2.3">2.3 shademargins</a></li>
+ <li><a href="#h2.4">2.4 cropmarks</a></li>
+ <li><a href="#h2.5">2.5 cropview</a></li>
+ <li><a href="#h2.6">2.6 closecrop</a></li>
+ <li><a href="#h2.7">2.7 xml</a></li>
+ <li><a href="#h2.8">2.8 coverart</a></li>
+ <li><a href="#h2.9">2.9 developer options</a></li>
+ </ul>
+ </li><!-- end 2 -->
+
+ <li id="l3"><span class="n"></span><a href="#h3"><b>3. Metadata, File Data, PDF/X</b></a>
+ <ul id="u3">
+ <li id="l3.1"><span class="n"></span><a href="#h3.1">3.1 Definitions of Terms</a>
+ <ul id="u3.1">
+ <li><a href="#h3.1.1">3.1.1 ISBN Metadata</a></li>
+ <li><a href="#h3.1.2">3.1.2 Printed Metadata</a></li>
+ <li><a href="#h3.1.3">3.1.3 File (PDF) Metadata</a></li>
+ </ul>
+ </li><!-- end 3.1 -->
+ <li id="l3.2"><span class="n"></span><a href="#h3.2">3.2 Rules for File Data</a>
+ <ul id="u3.2">
+ <li><a href="#h3.2.1">3.2.1 Required, Prohibited?</a></li>
+ <li><a href="#h3.2.2">3.2.2 Limited to Latin-1?</a></li>
+ <li><a href="#h3.2.3">3.2.3 TeX Escapes</a></li>
+ <li><a href="#h3.2.4">3.2.4 Forbidden Characters</a></li>
+ </ul>
+ </li><!-- end 3.2 -->
+ <li id="l3.3"><span class="n"></span><a href="#h3.3">3.3 File Data Commands</a>
+ <ul id="u3.3">
+ <li><a href="#h3.3.1">3.3.1 \SetTitle</a></li>
+ <li><a href="#h3.3.2">3.3.2 \SetAuthor</a></li>
+ <li><a href="#h3.3.3">3.3.3 \SetSubtitle</a></li>
+ <li><a href="#h3.3.4">3.3.4 \SetApplication, \SetProducer</a></li>
+ </ul>
+ </li><!-- end 3.3 -->
+ <li id="l3.4"><span class="n"></span><a href="#h3.4">3.4 PDF/X</a>
+ <ul id="u3.4">
+ <li><a href="#h3.4.1">3.4.1 Compliance Standards</a></li>
+ <li><a href="#h3.4.2">3.4.2 Output Intents</a></li>
+ <li><a href="#h3.4.3">3.4.3 Built-IN OI Codes</a></li>
+ <li><a href="#h3.4.4">3.4.4 Other Output Intents</a></li>
+ <li><a href="#h3.4.5">3.4.5 Embed *.icc or Not?</a></li>
+ <li><a href="#h3.4.6">3.4.6 Finding *.icc Files</a></li>
+ </ul>
+ </li><!-- end 3.4 -->
+ </ul>
+ </li><!-- end 3 -->
+
+ <li id="l4"><span class="n"></span><a href="#h4"><b>4. Book Size, Page Layout, Fonts</b></a>
+ <ul id="u4">
+ <li id="l4.1"><span class="n"></span><a href="#h4.1">4.1 Book Dimensions</a>
+ <ul id="u4.1">
+ <li><a href="#h4.1.1">4.1.1 Trim Size, TrimBox</a></li>
+ <li><a href="#h4.1.2">4.1.2 Media Size, MediaBox</a></li>
+ </ul>
+ </li><!-- end 4.1 -->
+ <li id="l4.2"><span class="n"></span><a href="#h4.2">4.2 Fonts, Normal Font Size</a>
+ <ul id="u4.2">
+ <li><a href="#h4.2.1">4.2.1 Parent (Main) Font, Size</a>
+ <ul id="u4.2.1">
+ <li><a href="#h4.2.1.1">4.2.1.1 \SetParentFont</a></li>
+ <li><a href="#h4.2.1.2">4.2.1.2 \SetFontSize</a></li>
+ </ul>
+ </li>
+ <li><a href="#h4.2.2">4.2.2 Descendant Fonts</a></li>
+ <li><a href="#h4.2.3">4.2.3 Advanced: Deco Font</a></li>
+ <li><a href="#h4.2.4">4.2.4 Advanced: Mono, Sans, Math</a></li>
+ <li><a href="#h4.2.5">4.2.5 Advanced: New Fonts</a></li>
+ </ul>
+ </li><!-- end 4.2 -->
+ <li id="l4.3"><span class="n"></span><a href="#h4.3">4.3 Interior Page Layout</a>
+ <ul id="u4.3">
+ <li><a href="#h4.3.1">4.3.1 Margins</a>
+ <ul id="u4.3.1">
+ <li><a href="#h4.3.1.1">4.3.1.1 Gutter? Which?</a></li>
+ <li><a href="#h4.3.1.2">4.3.1.2 Unsafe Zone</a></li>
+ </ul>
+ </li>
+ <li><a href="#h4.3.2">4.3.2 Lines Per Page</a></li>
+ <li><a href="#h4.3.3">4.3.3 Global Header/Footer</a>
+ <ul id="u4.3.3">
+ <li><a href="#h4.3.3.1">4.3.3.1 H/F Style Choices</a></li>
+ <li><a href="#h4.3.3.2">4.3.3.2 Custom H/F Style</a></li>
+ </ul>
+ </li>
+ <li><a href="#h4.3.4">4.3.4 Tweaking Global H/F Style</a>
+ <ul id="u4.3.4">
+ <li><a href="#h4.3.4.1">4.3.4.1 Head/Foot Jump</a></li>
+ <li><a href="#h4.3.4.2">4.3.4.2 \SetHeadFont</a></li>
+ <li><a href="#h4.3.4.3">4.3.4.3 \SetLooseHead</a></li>
+ <li><a href="#h4.3.4.4">4.3.4.4 \SetPageNumberStyle</a></li>
+ <li><a href="#h4.3.4.5">4.3.4.5 \SetEmblems</a></li>
+ <li><a href="#h4.3.4.6">4.3.4.6 Header Text</a></li>
+ </ul>
+ </li>
+ <li><a href="#h4.3.5">4.3.5 H/F Exceptional Pages</a>
+ <ul id="u4.3.5">
+ <li><a href="#h4.3.5.1">4.3.5.1 \thispagestyle</a></li>
+ <li><a href="#h4.3.5.2">4.3.5.2 \SetChapterStartStyle</a></li>
+ </ul>
+ </li>
+ </ul>
+ </li><!-- end 4.3 -->
+ </ul>
+ </li><!-- end 4 -->
+
+ <li id="l5"><span class="n"></span><a href="#h5"><b>5. Chapter Structure</b></a>
+ <ul id="u5">
+ <li id="l5.1"><span class="n"></span><a href="#h5.1">5.1 Starting a Chapter</a>
+ <ul id="u5.1">
+ <li><a href="#h5.1.1">5.1.1 \clearpage, \cleartorecto</a></li>
+ <li><a href="#h5.1.2">5.1.2 ChapterStart Environment</a>
+ <ul>
+ <li><a href="#h5.1.2.1">5.1.2.1 \SetChapterStartStyle</a></li>
+ <li><a href="#h5.1.2.2">5.1.2.2 \SetChapterStartHeight</a></li>
+ <li><a href="#h5.1.2.3">5.1.2.3 Begin ChapterStart</a></li>
+ </ul>
+ </li>
+ <li><a href="#h5.1.3">5.1.3 Chapter Title, etc.</a>
+ <ul>
+ <li><a href="#h5.1.3.1">5.1.3.1 \SetChapterFont, \SetSubchFont</a></li>
+ <li><a href="#h5.1.3.2">5.1.3.2 \ChapterTitle, \ChapterSubtitle</a></li>
+ <li><a href="#h5.1.3.3">5.1.3.3 \ChapterDeco</a></li>
+ <li><a href="#h5.1.3.4">5.1.3.4 Chapter Epigraph</a></li>
+ </ul>
+ </li>
+ <li><a href="#h5.1.4">5.1.4 ChapterStart With Image</a>
+ <ul>
+ <li><a href="#h5.1.4.1">5.1.4.1 Text Over Image</a></li>
+ <li><a href="#h5.1.4.2">5.1.4.2 Text Within Image</a></li>
+ </ul>
+ </li>
+ </ul>
+ </li><!-- end 5.1 -->
+ <li id="l5.2"><span class="n"></span><a href="#h5.2">5.2 Continuous Chapters</a>
+ <ul id="u5.2">
+ <li><a href="#h5.2.1">5.2.1 Short ChapterStart</a></li>
+ <li><a href="#h5.2.2">5.2.2 \QuickChapter</a></li>
+ </ul>
+ </li><!-- end 5.2 -->
+ <li id="l5.3"><span class="n"></span><a href="#h5.3">5.3 Scene Breaks</a>
+ <ul id="u5.3">
+ <li><a href="#h5.3.1">5.3.1 \SetScenebreakIndent</a></li>
+ </ul>
+ </li><!-- end 5.3 -->
+ <li id="l5.4"><span class="n" style="visibility:hidden"></span><a href="#h5.4">5.4 Chapter Numbering</a>
+ </li><!-- end 5.4 -->
+ <li id="l5.5"><span class="n"></span><a href="#h5.5">5.5 First Lines</a>
+ <ul id="u5.5">
+ <li><a href="#h5.5.1">5.5.1 First Character Special</a></li>
+ <li><a href="#h5.5.2">5.5.2 First Line Small Caps</a></li>
+ <li><a href="#h5.5.3">5.5.3 Drop Caps</a></li>
+ </ul>
+ </li><!-- end 5.5 -->
+ </ul>
+ </li><!-- end 5 -->
+
+ <li id="l6"><span class="n"></span><a href="#h6"><b>6. Text Size, Style, Position</b></a>
+ <ul id="u6">
+ <li id="l6.1"><span class="n"></span><a href="#h6.1">6.1 Text Sizes</a>
+ <ul id="u6.1">
+ <li><a href="#h6.1.1">6.1.1 Standard Sizes: Disabled!</a></li>
+ <li><a href="#h6.1.2">6.1.2 Local sizing: \charscale</a></li>
+ <li><a href="#h6.1.3">6.1.3 Environment: parascale</a></li>
+ <li><a href="#h6.1.4">6.1.4 Open Type Scale</a></li>
+ </ul>
+ </li><!-- end 6.1 -->
+ <li id="l6.2"><span class="n"></span><a href="#h6.2">6.2 General Styling</a>
+ <ul id="u6.2">
+ <li><a href="#h6.2.1">6.2.1 Italics and Emphasis</a></li>
+ <li><a href="#h6.2.2">6.2.2 Bold and Semibold</a></li>
+ <li><a href="#h6.2.3">6.2.3 Underlining</a></li>
+ <li><a href="#h6.2.4">6.2.4 Small Caps, Midcase</a></li>
+ <li><a href="#h6.2.5">6.2.5 Local Tracking</a></li>
+ <li><a href="#h6.2.6">6.2.6 Local Font Selection</a></li>
+ <li><a href="#h6.2.7">6.2.7 Local Font Features</a></li>
+ <li><a href="#h6.2.8">6.2.8 Grayscale Text</a></li>
+ </ul>
+ </li><!-- end 6.2 -->
+ <li id="l6.3"><span class="n"></span><a href="#h6.3">6.3 Positioning and Alignment</a>
+ <ul id="u6.3">
+ <li><a href="#h6.3.1">6.3.1 What to Avoid</a></li>
+ <li><a href="#h6.3.2">6.3.2 Some Useful Commands</a></li>
+ </ul>
+ </li><!-- end 6.3 -->
+ <li id="l6.4"><span class="n"></span><a href="#h6.4">6.4 Superscripts, Subscripts</a>
+ <ul id="u6.4">
+ <li><a href="#h6.4.1">6.4.1 Global Marker Style</a></li>
+ <li><a href="#h6.4.2">6.4.2 Local Real or Fake</a></li>
+ </ul>
+ </li><!-- end 6.4 -->
+ </ul>
+ </li><!-- end 6 -->
+
+ <li id="l7"><span class="n"></span><a href="#h7"><b>7. Images, Pictures, Drawings</b></a>
+ <ul id="u7">
+ <li id="l7.1"><span class="n"></span><a href="#h7.1">7.1 Technical Requirements</a>
+ <ul id="u7.1">
+ <li><a href="#h7.1.1">7.1.1 Interior B/W, Grayscale</a></li>
+ <li><a href="#h7.1.2">7.1.2 Color Cover</a></li>
+ </ul>
+ </li><!-- end 7.1 -->
+ <li id="l7.2"><span class="n"></span><a href="#h7.2">7.2 Placing Interior Images</a>
+ <ul id="u7.2">
+ <li><a href="#h7.2.1">7.2.1 Image-Like Text</a></li>
+ <li><a href="#h7.2.2">7.2.2 \InlineImage</a></li>
+ <li><a href="#h7.2.3">7.2.3 Text Over \InlineImage</a></li>
+ <li><a href="#h7.2.4">7.2.4 \FloatImage</a></li>
+ <li><a href="#h7.2.5">7.2.5 \WrapImage</a></li>
+ </ul>
+ </li><!-- end 7.2 -->
+ </ul>
+ </li><!-- end 7 -->
+
+ <li id="l8"><span class="n"></span><a href="#h8"><b>8. Tables, Lists</b></a>
+ <ul id="u8">
+ <li id="l8.1"><span class="n"></span><a href="#h8.1">8.1 The toc Environment</a>
+ <ul id="u8.1">
+ <li><a href="#h8.1.1">8.1.1 Entries Using \tocitem</a></li>
+ <li><a href="#h8.1.2">8.1.2 Example Table</a></li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+
+ <li id="l9"><span class="n"></span><a href="#h9"><b>9. Footnotes, Endnotes</b></a>
+ <ul id="u9">
+ <li id="l9.1"><span class="n" style="visibility:hidden"></span><a href="#h9.1">9.1 Footnotes</a></li>
+ <li id="l9.2"><span class="n"></span><a href="#h9.2">9.2 Endnotes</a>
+ <ul id="u9.2">
+ <li><a href="#h9.2.1">9.2.1 Placing: \endnote</a></li>
+ <li><a href="#h9.2.2">9.2.2 Writing: \endnotetext</a></li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+
+
+
+ <li><i>Appendices:</i></li>
+
+ <li id="lA"><span class="n" style="visibility:hidden"></span><a href="#hA"><b>A. Sample Document</b></a>
+ </li><!-- end A -->
+
+ <li id="lB"><span class="n"></span><a href="#hB"><b>B. Six-Page Front Matter</b></a>
+ <ul id="uB">
+ <li><a href="#hB.1">B.1 Half-Title to Copyright</a></li>
+ <li><a href="#hB.2">B.2 Post-Copyright</a></li>
+ </ul>
+ </li><!-- end B -->
+
+ <li id="lC"><span class="n"></span><a href="#hC"><b>C. Shopping for Fonts</b></a>
+ <ul id="uC">
+ <li><a href="#hC.1">C.1 Licensing Issues</a></li>
+ <li><a href="#hC.2">C.2 Technical Issues</a></li>
+ <li><a href="#hC.3">C.3 Appearance Issues</a></li>
+ </ul>
+ </li><!-- end C -->
+
+ <li id="lD"><span class="n"></span><a href="#hD"><b>D. Book Design</b></a>
+ <ul id="uD">
+ <li id="lD.1"><span class="n"></span><a href="#hD.1">D.1 Terminology</a>
+ <ul id="uD.1">
+ <li><a href="#hD.1.1">D.1.1 Sheet, Page, Leaf</a></li>
+ <li><a href="#hD.1.2">D.1.2 Folio, Spine</a></li>
+ <li><a href="#hD.1.3">D.1.3 Signature, Imposition</a></li>
+ </ul>
+ </li><!-- end D.1 -->
+ <li id="lD.2"><span class="n"></span><a href="#hD.2">D.2 Book Manufacture</a>
+ <ul id="uD.2">
+ <li><a href="#hD.2.1">D.2.1 Perfect Binding</a></li>
+ <li><a href="#hD.2.2">D.2.2 Library Binding</a></li>
+ <li><a href="#hD.2.3">D.2.3 Other Bindings</a></li>
+ <li><a href="#hD.2.4">D.2.4 Paper, Cover Materials</a></li>
+ </ul>
+ </li><!-- end D.2 -->
+ <li id="lD.3"><span class="n"></span><a href="#hD.3">D.3 Interior Structure</a>
+ <ul id="uD.3">
+ <li id="lD.3.1"><span class="n"></span><a href="#hD.3.1">D.3.1 Display, Chapter-Like</a>
+ <ul id="uD.3.1">
+ <li><a href="#hD.3.1.1">D.3.1.1 Display Pages</a></li>
+ <li><a href="#hD.3.1.2">D.3.1.2 Chapter-Like Sections</a></li>
+ </ul>
+ </li>
+ <li id="lD.3.2"><span class="n"></span><a href="#hD.3.2">D.3.2 Front Matter</a>
+ <ul id="uD.3.2">
+ <li><a href="#hD.3.2.1">D.3.2.1 Half-Title, i</a></li>
+ <li><a href="#hD.3.2.2">D.3.2.2 Blank, ii</a></li>
+ <li><a href="#hD.3.2.3">D.3.2.3 Title Page, iii</a></li>
+ <li><a href="#hD.3.2.4">D.3.2.4 Copyright Page, iv</a></li>
+ <li><a href="#hD.3.2.5">D.3.2.5 Dedication</a></li>
+ <li><a href="#hD.3.2.6">D.3.2.6 Epigraph</a></li>
+ <li><a href="#hD.3.2.7">D.3.2.7 Table of Contents</a></li>
+ <li><a href="#hD.3.2.8">D.3.2.8 Foreword, Preface, Intro</a></li>
+ <li><a href="#hD.3.2.9">D.3.2.9 Acknowledgements</a></li>
+ <li><a href="#hD.3.2.10">D.3.2.10 Author's Note</a></li>
+ <li><a href="#hD.3.2.11">D.3.2.11 Map</a></li>
+ <li><a href="#hD.3.2.12">D.3.2.12 Second Half-Title</a></li>
+ <li><a href="#hD.3.2.13">D.3.2.13 End of Front Matter</a></li>
+ </ul>
+ </li>
+ <li id="lD.3.3"><span class="n"></span><a href="#hD.3.3">D.3.3 Main Matter</a>
+ <ul id="uD.3.3">
+ <li><a href="#hD.3.3.1">D.3.3.1 Half-Title in Main</a></li>
+ <li><a href="#hD.3.3.2">D.3.3.2 Part Separator</a></li>
+ <li><a href="#hD.3.3.3">D.3.3.3 Introduction</a></li>
+ <li><a href="#hD.3.3.4">D.3.3.4 Prologue</a></li>
+ <li><a href="#hD.3.3.5">D.3.3.5 Chapters</a></li>
+ <li><a href="#hD.3.3.6">D.3.3.6 Epilogue, Conclusion</a></li>
+ <li><a href="#hD.3.3.7">D.3.3.7 End Notes, Appendix</a></li>
+ </ul>
+ </li>
+ <li id="lD.3.4"><span class="n"></span><a href="#hD.3.4">D.3.4 At the End</a>
+ <ul id="uD.3.4">
+ <li><a href="#hD.3.4.1">D.3.4.1 Back Matter? Not!</a></li>
+ <li><a href="#hD.3.4.2">D.3.4.2 About the Author</a></li>
+ </ul>
+ </li>
+ </ul>
+ </li><!-- end D.3 -->
+ </ul>
+ </li><!-- end D -->
+
+ <li id="lE"><span class="n"></span><a href="#hE"><b>E. Fontspec Syntax</b></a>
+ <ul id="uE">
+ <li id="lE.1"><span class="n"></span><a href="#hE.1">E.1 Family vs. File Name</a>
+ <ul id="uE.1">
+ <li><a href="#hE.1.1">E.1.1 Set/New by Name</a></li>
+ </ul>
+ </li>
+ <li id="lE.2"><span class="n"></span><a href="#hE.2">E.2 Open Type Features</a>
+ <ul id="uE.2">
+ <li><a href="#hE.2.1">E.2.1 Scale Pseudo-Feature</a></li>
+ <li><a href="#hE.2.2">E.2.2 Color and Opacity</a></li>
+ <li><a href="#hE.2.3">E.2.3 Create Font Feature</a></li>
+ </ul>
+ </li>
+ <li id="lE.3"><a href="#hE.3">E.3 Local Font Modification</a></li>
+ </ul>
+ </li><!-- end E -->
+
+ <li id="lF"><span class="n"></span><a href="#hF"><b>F. Drop Caps</b></a>
+ <ul id="uF">
+ <li><a href="#hF.1">F.1 Built-In vs Lettrine</a></li>
+ <li><a href="#hF.2">F.2 \dropcap[]{}</a></li>
+ <li><a href="#hF.3">F.3 \dropcap*[]{}</a></li>
+ <li><a href="#hF.4">F.4 Drop Cap Font, Color</a></li>
+ <li><a href="#hF.5">F.5 Drop Cap and First Line</a></li>
+ </ul>
+ </li><!-- end F -->
+
+ <li id="lY"><span class="n" style="visibility:hidden"></span><a href="#hY"><b>Y. Licensing and Credits</b></a>
+ </li><!-- end Y -->
+
+ <li id="lZ"><span class="n" style="visibility:hidden"></span><a href="#hZ"><b>Z. Important Changes</b></a>
+ </li><!-- end Z -->
+
+</ul><!-- end master toc ul -->
+
+<div style="height:1em"></div>
+
+</div><!-- end toc -->
+
+
+<!-- **************************************************************************************** -->
+
+<div id="main">
+<!-- **************************************************************************************** -->
+
+<h1 id="h0" style="padding-top:16px">Document class <i>novel</i> - documentation. &nbsp; <span style="font-size:75%">V. 1.52, 2018/04/26</span></h1>
+<p class="noindent"><span id="screennoscript" class="screennoscript"><b>For enhanced navigation of this file, turn on JavaScript.</b></span></p>
+<div><script>if(document.getElementById("screennoscript")){document.getElementById("screennoscript").style.display="none";}</script></div>
+
+<p class="item">ALERT: If you have been using this document class prior to version 1.50, see <a href="#hZ">Appendix Z</a> for important changes.</p>
+
+<!-- ********************************************************************** -->
+<div id="page01" class="page">
+
+<p class="noindent">The <i>novel</i> document class is for authors of text-intensive original fiction, such as detective novels, murder mysteries, romance, sci-fi, and collections of short stories. Academic works and graphic novels are excluded.</p>
+<p>The resulting PDF uses built-in technology to produce PDF/X compliant files for print-on-demand (P.O.D.) services. There is no capability for E-books, and never will be.</p>
+<p>To use <i>novel</i>, you need TeXLive 2016 or later, or recent MikTeX. Open your TeX package manager, and install both <i>novel</i> and <i>libertinus</i>.</p>
+
+
+<h2 id="h1">1. Before You Begin</h2>
+<div class="d2" id="d1">
+<p class="noindent"><img src="html-resources/doordie.png" class="floatright" width="167" height="171" title="TeX Commandments" alt="TeX Commandments"/>This documentation assumes that you have some familiarity with TeX, but not much expertise.</p>
+<p>You usually cannot take an existing document, written with some other class, and just change it to <i>novel</i>. The command set used by <i>novel</i> is very different from that used by others.</p>
+<p>Before you wonder why your document doesn't work, you need to understand the differences. All of these are features, not bugs. They are done with the intent of making <i>novel</i> best for its intended purpose. But if you have been in the habit of writing academic papers, the differences may surprise you.</p>
+
+
+<h3 id="h1.1">1.1. Do These Things</h3>
+<div class="d3" id="d1.1">
+
+<h4 id="h1.1.1">1.1.1. Use the LuaLaTeX Compiler</h4>
+<div class="d4" id="d1.1.1">
+<p class="item"><b>A.</b> At the top of your *.tex main document, before the document class, place these lines:</p>
+<p class="code"><code>% !TeX TS-program = LuaLaTeX</code><br/>
+<code>% !TeX encoding = UTF-8</code></p>
+<p>Those instructions are read and understood by many TeX editors, and also serve as a reminder to yourself.</p>
+<p class="item"><b>B.</b> If you compile by command line, try this:</p>
+<p class="code"><code>lualatex yourdocument.tex</code><p>
+<p class="item"><b>C.</b> If using a service such as ShareLaTeX online, open the Menu, and scroll down to where you can choose the compiler. Set it to LuaLaTeX.</p>
+</div><!-- end 1.1.1 -->
+
+<h4 id="h1.1.2">1.1.2. Use UTF-8 Encoding</h4>
+<div class="d4" id="d1.1.2">
+<p class="item"><b>A.</b> You must create your document in <span style="white-space:nowrap">utf-8</span> encoding. No OT1, no T1, no LY1, or other TeX font encoding that pre-dates cell phones. Do not call for <i>fontenc</i> in your Preamble, because <span style="white-space:nowrap">utf-8</span> is <span style="white-space:nowrap">pre-configured</span>.</p>
+<p class="item"><b>B.</b> If you use a plain text editor, or TeXWorks, or export plain text from a word processor, be sure that your text is encoded as <span style="white-space:nowrap">utf-8</span>, <i>without</i> byte order mark (BOM).</p>
+<p class="item"><b>C.</b> Instead of typing TeX codes such as <code>\`{e}</code> you can simply paste <code>è</code> from a Unicode character map. Other alphabets such as Greek and Cyrillic are directly supported, as long as you choose fonts that support those character sets.</p>
+<p class="item"><b>D.</b> If you are on Windows, <i>do not</i> use Notepad! The free <a class="external" rel="external" target="new" href="https://notepad-plus-plus.org">Notepad++</a> (also <a class="external" rel="external" target="new" href="https://portableapps.com/apps/development/notepadpp_portable">Portable</a> version) is a suitable plain text editor. Configure it as specified, with utf-8 but without BOM. Does not matter whether UNIX or DOS line endings, as long as you are consistent.</p>
+</div><!-- end 1.1.2 -->
+
+<h4 id="h1.1.3">1.1.3. Use Polyglossia Language Support</h4>
+<div class="d4" id="d1.1.3">
+<p class="item"><b>A.</b> The pre-loaded <i>polyglossia</i> package provides language support. By default, <i>novel</i> is configured for American English.</p>
+<p class="item"><b>B.</b> If your document's language is something else, or if you will be writing in multiple languages, see the <i>polyglossia</i> package documentation regarding <code>\setdefaultlanguage</code> and related commands.</p>
+</div><!-- end 1.1.3 -->
+
+<h4 id="h1.1.4">1.1.4. Use Open Type Fonts</h4>
+<div class="d4" id="d1.1.4">
+<p class="item"><b>A.</b> The built-in <i>fontspec</i> package requires utf-8 encoding. It is able to load Open Type fonts, and access their internal feature sets. Forget Type 1 fonts and special encodings! If you wish to use Greek or Cyrillic, all you need are compatible fonts.</p>
+<p class="item"><b>B.</b> If you accept the pre-configured fonts (from <i>libertinus</i>), then you do not need to know anything about <i>fontspec</i>. But if you wish to configure your own fonts, <a href="#hE">Appendix E</a> reviews the most important parts of <i>fontspec</i> syntax.</p>
+<div style="clear:both"></div>
+</div><!-- end 1.1.4 -->
+
+<h4 id="h1.1.5">1.1.5. Read About Book Design</h4>
+<div class="d4" id="d1.1.5">
+<p class="item"><b>A.</b> This documentation has an extensive section regarding <a href="#hD">book design</a>. Read it.</p>
+<p class="item"><b>B.</b> In particular, you will learn how to format pages according to their position and purpose in the book; you will learn how to construct a table of contents; you will learn how you must end your document.</p>
+<div style="clear:both"></div>
+</div><!-- end 1.1.5 -->
+</div><!-- end 1.1 -->
+
+
+<h3 id="h1.2">1.2. Avoid These Things</h3>
+<div class="d3" id="d1.2">
+
+<h4 id="h1.2.1">1.2.1. Avoid Non-Fontspec Font Loaders</h4>
+<div class="d4" id="d1.2.1">
+<p class="item"><b>A.</b> The method for loading fonts is described in <a href="#h4.2">section 4.2</a>. Be sure you read it.</p>
+<p class="item"><b>B.</b> Do not load fonts via <code>\usepackage</code> or <code>\RequirePackage</code>, or by <code>\setmainfont</code>.</p>
+</div><!-- end 1.2.1 -->
+
+<h4 id="h1.2.2">1.2.2. Avoid TeX Font Sizes</h4>
+<div class="d4" id="d1.2.2">
+<p class="item"><b>A.</b> Standard text size commands, such as <code>\small</code> or <code>\LARGE</code>, will be ignored. The text will appear at its normal size, just as if the commands did not exist.</p>
+<p class="item"><b>B.</b> <i>Novel</i> provides its own capability to size text, using <a href="#h6.1">different commands</a>.</p>
+<p class="item" style="position:relative"><b>C.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> The <i>novel</i>-specific size commands maintain text line grid, where possible. This is important for printed fiction.</p>
+</div><!-- end 1.2.2 -->
+
+<h4 id="h1.2.3">1.2.3. Avoid Academic Structures</h4>
+<div class="d4" id="d1.2.3">
+<p class="item"><img class="floatright" src="html-resources/fpaper.png" width="134" height="215" alt="flunked math"/><b>A.</b> Commands such as <code>\section</code>, <code>\chapter</code>, <code>\abstract</code>, <code>\index</code>, <code>\tableofcontents</code>, <code>\maketitle</code>, and many other structural commands will not work with <i>novel</i>. This is intentional.</p>
+<p class="item"><b>B.</b> The <i>float</i>, <i>picture</i>, and <i>table</i> environments are disallowed, unless you are in <a href="#h2.2">sandbox</a> mode. This is intentional. In <i>novel</i> there are specific ways to <a href="#h7.3">place images</a> or construct a <a href="#hD.3.2.7">table of contents</a>.</p>
+<p class="item"><b>C.</b> <i>Novel</i> has <a href="#h5">chapter-related commands</a> specifically created for the needs of fictional works.</p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> <i>Novel</i> is focused on doing one thing well, rather than many things poorly. That is why so many "academic" commands have been discarded. They are not necessary in popular fiction.</p>
+<div style="clear:both"></div>
+</div><!-- end 1.2.3 -->
+
+<h4 id="h1.2.4">1.2.4. Avoid TeX Editors and IDEs</h4>
+<div class="d4" id="d1.2.4">
+<p class="item"><b>A.</b> Many TeX editors assume that you are using a standard TeX document class. They may attempt to insert code that does not work in <i>novel</i> class. Or, they may not understand the commands specific to <i>novel</i>. Do not use those editors.</p>
+<p class="item"><b>B.</b> The TeXWorks editor is satisfactory. Be sure that you do not run scripts that change the content of your document.</p>
+</div><!-- end 1.2.4 -->
+</div><!-- end 1.2 -->
+
+
+<h3 id="h1.3">1.3. Beware of These</h3>
+<div class="d3" id="d1.3">
+
+<h4 id="h1.3.1">1.3.1. Beware of $, %, and Other TeX Special Characters</h4>
+<div class="d4" id="d1.3.1">
+<p class="item"><b>A.</b> This is standard TeX behavior. Just a reminder!</p>
+<p class="item"><img class="floatright" src="html-resources/trdol.png" width="238" height="67" alt="dollar is math mode"/><b>B.</b> TeX has a number of special characters. If you type them in a document, they will not appear as an ordinary printed character, but will do something else. These are:</p>
+<p class="code"><code>$ % # _ ^ & ~ \ { }</code> and sometimes <code>[ ]</code></p>
+<p class="item"><b>C.</b> In some cases, an incorrect usage will provide an error message that can be easily deciphered.</p>
+<p class="item"><b>D.</b> Incorrect use of the dollar sign may either place your text in math mode (not your intent) or produce a baffling error message that points to an innocent package.</p>
+<p class="item"><b>E.</b> The percent symbol normally produces no error, since it is a comment character. But then, whatever text follows on that line will be missing from your PDF. Unless you carefully review the PDF, you might not notice that text is missing.</p>
+<p class="item"><b>F.</b> Special characters, other than the backslash, are escaped by placing a backslash in front, thus: <code>\$</code> for the dollar sign, <code>\%</code> for percent. If you must print a backslash, <code>\string\</code> does it.</p>
+<p class="item" style="position:relative"><b>G.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> To avoid unforeseen problems, you should review your document in a text editor, prior to compiling. Search for any instances of special characters, particularly dollar and percent. Backslash them as needed.</p>
+<div style="clear:both"></div>
+</div><!-- end 1.3.1 -->
+
+
+<h4 id="h1.3.2">1.3.2. Beware of Layout Surprises</h4>
+<div class="d4" id="d1.3.2">
+<p class="item"><b>A.</b> In <i>novel</i>, inter-line spacing is fixed. There is no padding between paragraphs. No plus/minus "flexible glue." This is standard for printed fiction.</p>
+<p class="item"><b>B.</b> When TeX processes a document on a paragraph-by-paragraph basis, it chooses the layout that has the least total "penalty." Penalties are assessed based on factors such as word spacing, hyphenation, widows, and orphans (clubs). <i>Novel</i> applies a moderately strong penalty to hyphens; they are allowed, but discouraged. Widows and orphans are penalized very little. Word spacing, and even the spacing and characters within words, are controlled by moderate settings of the built-in <i>microtype</i> package.</p>
+<p class="item" style="position:relative"><b>C.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> You are likely to find widows and orphans on many pages. If you wish to remove them, you must edit your text. This choice was made for several reasons: First, attention to widows and orphans would reduce the effectiveness of the other, more important, layout penalties. Second, fiction often has numerous short paragraphs (especially with dialogue), and it is very difficult for software to deal with all of them. Third, a great deal of contemporary fiction allows widows and orphans, when they are not distracting.</p>
+</div><!-- end 1.3.2 -->
+</div><!-- end 1.3 -->
+
+
+</div><!-- end 1 -->
+</div><!-- end page01 -->
+<!-- ********************************************************************** -->
+<div id="page02" class="page">
+
+
+<h2 id="h2">2. Document Class Options</h2>
+<div class="d2" id="d2">
+<p class="item"><b>A.</b> As with other LaTeX classes, <i>novel</i> is called this way:</p>
+<p><code>\documentclass[options,separated,by,commas]{novel}</code></p>
+<p class="item"><b>B.</b> You do NOT use class options to choose paper size, font size, or any other dimensions. The settings are described in <a href="#h4">section 4</a>.</p>
+<p class="item"><b>C.</b> Default sizes are appropriate for most print-on-demand, softcover fiction.</p>
+
+<h3 id="h2.1">2.1. draft</h3>
+<div class="d3" id="d2.1">
+<p class="item"><b>A.</b> May NOT be used for final, print-ready PDF.</p>
+<p class="item"><b>B.</b> The word DRAFT will appear at the upper left of each page.</p>
+<p class="item"><b>C.</b> When text cannot be precisely wrapped, a small black bar (overflow rule) appears at right. These locations are reported in the log file as "overfull hbox" warnings. Example:</p>
+<p class="centerimg"><img src="html-resources/overflowrule.png" width="525" height="155" title="draft mode, overflow rule" alt="overflow rule"/></p>
+<p class="item"><b>D.</b> Some class options are only effective when used with <i>draft</i> option.</p>
+<p class="item"><b>E.</b> PDF/X compliance is turned <i>off</i>. This over-rides any PDF/X setting.</p>
+<p class="item"><b>F.</b> Some packages take note of whether or not the document is in draft mode, and change their behavior accordingly. However, the included <i>microtype</i> package will always be in final mode, and the included <i>hyperref</i> package will always be in draft mode.</p>
+</div><!-- end 2.1 -->
+
+<h3 id="h2.2">2.2. sandbox</h3>
+<div class="d3" id="d2.2">
+<p class="noindent">New in version 1.50. You work in <code>sandbox</code> mode as a class option:</p>
+<p class="code"><code>\documentclass[sandbox]{novel}</code></p>
+<p class="item"><b>A.</b> In <code>sandbox</code> mode, you can use many packages that would otherwise be prohibited. This will allow you to create tables and diagrams using nearly any methods ordinarily available in most other document classes. Of course, you may have to load some additional packages.</p>
+<p>Also, when in <code>sandbox</code> mode, many glues and lengths are set to values that are typical of other document classes, rather than the special values ordinarily used by <i>novel</i>.
+<p class="item"><b>B.</b> The <code>sandbox</code> is limited to 4 pages of output, regardless of document length. So, you cannot use <code>sandbox</code> for your whole book. Instead, create one or more separate <code>sandbox</code> files.</p>
+<p class="item"><b>C.</b> Your <code>sandbox</code> document should have the same layout as your full document. Then it is a drawing canvas. On a per-page basis, whatever fits in <code>sandbox</code> will also fit in your main document.</p>
+<p class="item"><b>D.</b> If you also enable draft mode and shademargins, you can see the size of available space on the <code>sandbox</code> pages.</p>
+<p class="item"><b>E.</b> When not in draft mode, the <code>sandbox</code> pages will have empty headers and footers (no matter which style you use).</p>
+<p class="item"><b>F.</b> Post-process your <code>sandbox</code> PDF using <i style="white-space:nowrap">novel-scripts</i>. Then you will obtain black/white or grayscale raster images, with surrounding white space trimmed away. These images can be placed as ordinary images in your main document.</p>
+<p class="item" style="position:relative"><b>G.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Why <code>sandbox</code>? Certain ordinary TeX commands and environments will disturb the <i>novel</i> page layout. Others will invalidate PDF/X. When you create something in <code>sandbox</code>, then convert it to a raster image, those bad effects are neutralized.</p>
+
+</div><!-- end 2.2 -->
+
+<h3 id="h2.3">2.3. shademargins</h3>
+<div class="d3" id="d2.3">
+<p class="item"><img class="floatright" style="margin-top:6px" src="html-resources/shademargins.png" width="132" height="205" title="shademargins" alt="shademargins"/><b>A.</b> Only effective with <i>draft</i> option.</p>
+<p class="item"><b>B.</b> Helps to visualize and detect possible layout problems.</p>
+<p class="item"><b>C.</b> Applies dark gray shade to unsafe areas (if set). Applies medium gray shade to margin areas. Applies light gray shade to header/footer areas.
+<p class="item"><b>D.</b> <a href="#h4.3.1">Margins</a> include areas inside and outside the <a href="#h4.3.1.2">unsafe zones</a>.</p>
+<p class="item"><b>E.</b> If <a href="#h4.1.2">Media Size</a> exceeds <a href="#h4.1.1">Trim Size</a>, the area outside the Trim Size will <em>not</em> be gray, because it is not part of the finished book.</p>
+<p class="item" style="position:relative"><b>F.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Technical Info: During page shipout, the gray areas are added as background colors, with a white box above it, then text (and images, if any) on top.</p>
+<div style="clear:both"></div>
+</div><!-- end 2.3 -->
+
+<h3 id="h2.4">2.4. cropmarks <em>(do not use unless required)</em></h3>
+<div class="d3" id="d2.4">
+<p class="item"><img class="floatright" style="margin-top:6px" src="html-resources/cropmarks.png" width="205" height="265" title="cropmarks" alt="cropmarks"/><b>A.</b> May be used with or without <i>draft</i> option.</p>
+<p class="item"><b>B.</b> Marks are 0.25pt weight, 0.125in long, beginning 0.125in from the <a href="#h4.1.1">TrimBox</a>, ending 0.25in away from TrimBox.</p>
+<p>The illustration shows a document with <a href="#h4.1.1">Trim Size</a> floated in a larger <a href="#h4.1.2">Media Size</a>. The invisible <a href="#h4.1.1">TrimBox</a> is outlined in green. The tiny crop marks sit outside the TrimBox.</p>
+<p class="item" style="position:relative"><b>C.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Do not load any package that provides other cropmarks. They are incompatible, whether or not you use the <code>cropmarks</code> option.</p>
+<p class="item"><b>D.</b> Most print-on-demand services do NOT want crop marks (also known as trim marks). Do not use this option unless you are certain that you need crop marks!</p>
+<p class="item"><b>E.</b> Whether or not you use <code>cropmarks</code> option: In PDF/X, the file contains invisible information (TrimBox) that is understood by automatic print/cut machines.</p>
+<p class="item"><b>F.</b> The PDF term CropBox is related to <a href="#h2.5">cropview</a>, NOT crop marks.</p>
+</div><!-- end 2.4 -->
+
+<h3 id="h2.5">2.5. cropview</h3>
+<div class="d3" id="d2.5">
+<p class="item"><img class="floatright" style="margin-top:6px" src="html-resources/cropview.png" width="132" height="203" title="cropview" alt="cropview"/><b>A.</b> Only effective with <i>draft</i> option.</p>
+<p class="item"><b>B.</b> Ignored if <a href="#h4.1.1">Trim Size</a> is same as <a href="#h4.1.2">Media Size</a>.</p>
+<p class="item"><b>C.</b> Instructs PDF viewer: Only display Trim Size on screen.</p>
+<p class="item"><b>D.</b> Helps to visualize trimmed book size, when Media Size is larger than Trim Size.</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Technical Info: Normally, the PDF CropBox is equal to the MediaBox. This option sets the CropBox equal to the TrimBox.</p>
+<div style="clear:both"></div>
+</div><!-- end 2.5 -->
+
+<h3 id="h2.6">2.6. closecrop</h3>
+<div class="d3" id="d2.6">
+<p class="item"><img class="floatright" style="margin-top:6px" src="html-resources/closecrop.png" width="110" height="186" title="closecrop" alt="closecrop"/><b>A.</b> Only effective with <i>draft</i> option.</p>
+<p class="item"><b>B.</b> Minimizes white space surrounding the text/header/footer, so that the result may be viewed on a hand-held device at largest practical text size.</p>
+<p class="item"><b>C.</b> Purpose: Helps you to visualize your own book, while traveling, before you make final edits.</p>
+<p class="item"><b>D.</b> This is NOT an e-book. It does not meet e-book standards, and cannot be changed to meet e-book standards.</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Technical Info: First, the live area (text plus head/foot) is calculated from the original settings. Then, small margins are added, and the Trim Size is reduced to fit. So, the closecrop PDF size is not the same as in the print-ready PDF, although the page layout is the same.</p>
+<div style="clear:both"></div>
+</div><!-- end 2.6 -->
+
+<h3 id="h2.7">2.7. xml</h3>
+<div class="d3" id="d2.7">
+<p class="item"><b>A.</b> Only effective with PDF/X. Only effective when NOT in draft mode.</p>
+<p class="item"><b>B.</b> Copies internal XMP Metadata to a separate <i>jobname-XMPasXML.xml</i> file.</p>
+<p class="item"><b>C.</b> Not necessary. Only informative. Does not affect structure or content of PDF.</p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Technical Info: XMP packet may be isolated by editing the *.xml file, in a plain text editor (requires utf-8). Necessary edits are obvious.</p>
+</div><!-- end 2.7 -->
+
+<h3 id="h2.8">2.8. coverart</h3>
+<div class="d3" id="d2.8">
+<p class="item">This option is only used for cover artwork. See <a href="#h7.1.2">section 7.1.2</a>.</p>
+</div><!-- end 2.8 -->
+
+<h3 id="h2.9">2.9. Developer Options</h3>
+<div class="d3" id="d2.9">
+<p class="noindent">These options are primarily used for developer testing, not user production. Using them may cause compilation to fail, or produce an undesirable result. That is not considered a bug.</p>
+<p class="item"><b>A.</b> <code>mtoff</code> The <i>microtype</i> package will not be loaded.</p>
+<p class="item"><b>B.</b> <code>polyoff</code> The <i>polyglossia</i> package will not be loaded.</p>
+<p class="item"><b>C.</b> <code>test</code> Only used with file <i>novel-testsuite.tex</i>.</p>
+<p class="item"><b>D.</b> <code>unblock</code> Allows use of some packages that would otherwise be blocked.</p>
+</div><!-- end 2.9 -->
+
+
+</div><!-- end 2 -->
+</div><!-- end page02 -->
+<!-- ********************************************************************* -->
+<div id="page03" class="page">
+
+<h2 id="h3">3. Metadata, File Data, and PDF/X</h2>
+<div class="d2" id="d3">
+<p class="item"><b>A.</b> The commands described on this page are used only in the Preamble.</p>
+<p class="item"><b>B.</b> These commands write non-printing information to the PDF file. Some of the information is used to identify and classify the file. Other information is read by the printer, to assist it with printing choices.</p>
+<p class="item" style="position:relative"><b>C.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Some of the terms have different meanings, depending on whether they are used in the context of printing, book distribution, or ebooks. To avoid confusion <em>within this documentation</em> I will use different terms when they mean different things. When you are communicating with your printing and distribution service, take care to ensure that your understanding of terminology is what they really mean.</p>
+
+<h3 id="h3.1">3.1. Definition of Terms</h3>
+<div class="d3" id="d3.1">
+<p class="noindent">This section is more detailed than it needs to be, because my review of various online forums (unrelated to TeX) shows a lot of user confusion.</p>
+
+<h4 id="h3.1.1">3.1.1. ISBN Metadata</h4>
+<div class="d4" id="d3.1.1">
+<p class="item"><b>A.</b> When you obtain the ISBN for your book, either directly through the issuing agency or via your chosen print service, you will enter <em>ISBN Metadata</em> in an online form.</p>
+<p class="item"><img class="floatright" src="html-resources/bookmanglerdashboard.png" width="500" height="309" alt="online form for ISBN metadata"/><b>B.</b> This metadata goes into a database, and identifies your printed book in distribution and sales channels. It neither knows nor cares about PDF. (If you were marketing a PDF ebook, instead of print, that would be a different story.)</p>
+<p class="item"><b>C.</b> ISBN Metadata includes title, author(s), subtitle if any, ISBN, and other identifying information. Once the book is released, this information (normally) cannot be changed.</p>
+<p class="item"><b>D.</b> You may also enter a description, genre classification, and other information that will help people find your book by browsing, and help to sell your book. This information can usually be changed at a later date.</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> The ISBN refers to your <em>printed book</em>, not to the PDF file. You are not selling copies of the PDF.</p>
+<div style="clear:both"></div>
+</div><!-- end 3.1.1 -->
+
+<h4 id="h3.1.2">3.1.2. Printed Metadata</h4>
+<div class="d4" id="d3.1.2">
+<p class="item"><b>A.</b> <em>Printed Metadata</em> refers to the information that can be seen on paper, in expected places: the book cover, the title page, and the copyright page.</p>
+<p class="item"><img class="floatright" src="html-resources/megatitlepagesm.png" width="165" height="256" alt="printed metadata, cover page"/><b>B.</b> Whether your book was printed from a PDF file, or by some other method, is not relevant.</p>
+<p class="item"><b>C.</b> Your print service will insist that the title, subtitle (if any), author, and ISBN in these places exactly match what appears in the ISBN database. Of course, you can (and usually will) use styling or images to make the Printed Metadata more attractive than the plain-text ISBN Metadata.</p>
+<p class="item"><b>D.</b> Some print services may object to artwork that is too fancy, on the grounds that it is difficult to discern the title and author. Although this is very unlikely, it is better to ask before committing resources.</p>
+<div style="clear:both"></div>
+</div><!-- end 3.1.2 -->
+
+<h4 id="h3.1.3">3.1.3. File Data (PDF Metadata)</h4>
+<div class="d4" id="d3.1.3">
+<p class="item"><b>A.</b> Your PDF has internal metadata, which can been seen by PDF reader software.</p>
+<p class="item"><img class="floatright" src="html-resources/megadocprops.png" width="298" height="215" alt="PDF metadata"/><b>B.</b> To avoid confusion, this documentation uses the term <i>File Data</i> to mean this internal PDF Metadata.</p>
+<p class="item"><b>C.</b> You can see some of the File Data when you open the PDF in any reader, and go to <i>File&gt;Properties</i>. To see all of it, you need professional software (such as Adobe Acrobat Pro).</p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Be sure to read the rules for File Data, below. Some of it is generic, and some is particular to TeX or to the <i>novel</i> class.</p>
+<div style="clear:both"></div>
+</div><!-- end 3.1.3 -->
+</div><!-- end 3.1 -->
+
+<h3 id="h3.2">3.2. Rules for File Data</h3>
+<div class="d3" id="d3.2">
+<p class="item">File Data must conform to several specifications, in terms of what you may or may not write. Some of the limitations are imposed by the book distribution industry, which stores information in its databases a certain way.</p>
+<p>What File Data do you need, if any? Ask your print service.</p>
+
+<h4 id="h3.2.1">3.2.1. Required, Prohibited, Optional?</h4>
+<div class="d4" id="d3.2.1">
+<p class="item"><b>A.</b> If PDF/X compliance is required, then you <em>must</em> at least set the title in File Data, using the <code><a href="#h3.3.1">\SetTitle</a></code> command. Note that this title is not styled in any way.</p>
+<p class="item"><b>B.</b> Some print services require a minimum amount of file data, particularly title and author, which must match the printed metadata and ISBN metadata for these fields.</p>
+<p class="item"><b>C.</b> Other services may require that the book's ISBN number, with something like <i>_text</i> added, be used in place of the title. Remember that underscore is a special character in LaTeX, so it must be preceded by a backslash.</p>
+<p class="item"><b>D.</b> Many print services do not care about File Data, one way or the other. Your PDF is passed through production according to its file name, not its internals. In such a case, assume that title and author are required.</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Be sure that any included images are stripped of their own image metadata, such as EXIF. The procedure is described in <i>novel-scripts</i>.</p>
+</div><!-- end 3.2.1 -->
+
+<h4 id="h3.2.2">3.2.2. Limited to Latin-1?</h4>
+<div class="d4" id="d3.2.2">
+<p class="item"><b>A.</b> At least in the USA, your print service may require that File Data be limited to characters in the Latin-1 set. This is because their production and distribution software uses Latin-1 for the database.</p>
+<p class="item"><b>B.</b> Latin-1 does not include curly quotes or em dash. You will still be using utf-8 encoding in your document files, but your choice of characters is restricted.</p>
+<p class="item"><b>C.</b> <i>Novel</i> allows the title, and other File Data, to be in alphabets such as Greek or Cyrillic. If you are limited to Latin-1, the limitation has nothing to do with TeX or PDF.</p>
+<p class="item"><b>D.</b> If your book has File Data using quotes, then use the special commands <code>\straightquote{}</code> and <code>\straightdblquote{}</code>. Be sure to use the braces, so that you don't have to worry about gobbled space. When you use these commands, you eliminate the risk that your software will automatically convert them to the forbidden curly quotes. Example:</p>
+<p class="code"><code>\SetTitle{That\straightquote{}s Amore} % That's Amore</code></p>
+<p class="item"><b>E.</b> If you are limited to Latin-1 in File Data, you can still use curly quotes and em dash on the cover and title page, and in headings.</p>
+<p class="item" style="position:relative"><b>F.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> There is no <code>\maketitle</code> command in <i>novel</i>. You may (and should) apply styling to the printed title, even though the File Data title cannot be styled.</p>
+</div><!-- end 3.2.2 -->
+
+<h4 id="h3.2.3">3.2.3. TeX escapes</h4>
+<div class="d4" id="d3.2.3">
+<p class="item"><b>A.</b> In File Data, you must obey the same TeX rules that apply everywhere: Certain characters have special meaning, and must be preceded by a backslash, if you wish to use them as ordinary characters.</p>
+<p class="item"><b>B.</b> The list of special characters:</p>
+<p><code># $ % &amp; _</code> &nbsp; &nbsp; (hash, dollar, percent, ampersand, underscore)</p>
+<p>Example: The title <em>Doing 9% &amp; Gone</em> is coded:</p>
+<p class="code"><code>\SetTitle{Doing 9\% \&amp; Gone}</code></p>
+<p class="item"><b>C.</b> The above characters are rarely needed in File Data. Sometimes they must be spelled out, in order to agree with your book's ISBN Metadata. For example, you may need to write "and" rather than the ampersand, "dollar" rather than the dollar symbol, and "percent" or "per-cent" rather than the percent symbol.</p>
+<p class="item"><b>D.</b> Fun fact: <i>The Seven-Per-Cent Solution</i> and <i>The 7% Solution</i> are different books, in entirely different gnres.</p>
+
+</div><!-- end 3.2.3 -->
+
+<h4 id="h3.2.4">3.2.4. Forbidden Characters</h4>
+<div class="d4" id="d3.2.4">
+<p class="item"><b>A.</b> Do not use the backslash <code>\</code> except as described above.</p>
+<p class="item"><b>B.</b> Do not use the tilde <code>~</code> or the circumflex <code>^</code>.</p>
+<p class="item"><b>C.</b> Do not use TeX code, such as <code>\`e</code> for e with grave; instead paste <code>è</code> directly from a character map.</p>
+<p class="item"><b>D.</b> Do not use styling, such as <code>{\small text}</code> or <code>\textit{text}</code>.</p>
+<p class="item"><b>E.</b> If necessary, use <code>\straightquote{}</code> and <code>\straightdblquote{}</code>. Do not use TeX code for apostrophe or quote.</p>
+<p class="item"><b>F.</b> Do not use multiple hyphens to create longer dashes. Do not use em dash or en dash.</p>
+</div><!-- end 3.2.4 -->
+</div><!-- end 3.2 -->
+
+<h3 id="h3.3">3.3. File Data Commands</h3>
+<div class="d3" id="d3.3">
+<p class="noindent">Now that you understand what File Data means, and how it may be written, you can use commands to write it.</p>
+
+<h4 id="h3.3.1">3.3.1. <code>\SetTitle{<em>text</em>}</code></h4>
+<div class="d4" id="d3.3.1">
+<p class="item"><b>A.</b> The <i>novel</i> document class does not have <code>\maketitle</code>. The title is <i>not</i> automatically transferred to a title page, because there is no automatic title page.</p>
+<p class="item"><b>B.</b> The title can be retrieved as <code>\theTitle</code> anywhere in your document.</p>
+<p class="item"><b>C.</b> In certain page layouts, the title is used as default text in recto page headings. You may <a href="#h4.3.4.6">over-ride</a> this behavior.</p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> You may set the title as empty (or blank space). In <i>very rare</i> cases, that is useful. However, if you do that, then you must follow <code>\SetTitle{}</code> with <code>\SetPDFX{off}</code>, or an error will result. This is because PDF/X standards require a real title.</p>
+</div><!-- end 3.3.1 -->
+
+<h4 id="h3.3.2">3.3.2. <code>\SetAuthor{<em>text</em>}</code></h4>
+<div class="d4" id="d3.3.2">
+<p class="item"><b>A.</b> The default author is empty (no author).</p>
+<p class="item"><b>B.</b> In certain page layouts, the author is used as default text in verso page headings. You may <a href="#h4.3.4.6">over-ride</a> this behavior.</p>
+<p class="item"><b>C.</b> The author can be retrieved as <code>\theAuthor</code> anywhere in your document.</p>
+<p class="item"><b>D.</b> If in doubt, use the name as it is spoken. <i>Correct:</i> Mary Smith. <i>Incorrect:</i> Smith, Mary. <i>Possibly correct, if true:</i> Mary Smith, Ph. D.</p>
+<p class="item"><b>E.</b> Your PDF file is <i>not</i> seen by a public database. Instead, the public database contains the <a href="#h3.1.1">information you entered</a>, when you obtained the ISBN. So, if you have multiple authors or minor contributors, that is the place to provide search information.</p>
+<p class="item"><b>F.</b> Ask your print service about how to enter multiple authors, and how to display them in print. Do not assume that authorship rules pertaining to academic papers will also apply to your novel.</p>
+<p class="item" style="position:relative"><b>G.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Print-On-Demand services do not like to split royalty payments among multiple authors. Instead, the entire account is the responsibility of one main author or editor.</p>
+<p>If anyone else is involved, that is a matter of private contract betwen the one main author/editor, and any other contributors. The print service neither knows nor cares about such agreements, and will do nothing to cooperate.</p>
+<p>[DISCLAIMER] Here is my amateur advice: Consider using other contributors on a <i><span style="white-space:nowrap">work-for-hire</span></i> basis. This involves a written contract, prior payment of a fixed amount that does not depend on sales, and no grant of rights. You also need written assurance that the hired persons have the right to sell you the work they provide. If you need professional advice, then consult a professional.</p>
+</div><!-- end 3.3.2 -->
+
+<h4 id="h3.3.3">3.3.3. <code>\SetSubtitle{<em>text</em>}</code></h4>
+<div class="d4" id="d3.3.3">
+<p class="item"><b>A.</b> The subtitle can be retrieved as <code>\theSubtitle</code> anywhere in your document.</p>
+<p class="item"><b>B.</b> The subtitle does <i>not</i> appear in File Data, and does <i>not</i> appear anywhere in your book, unless you manually write it there (either manually, or via <code>\theSubtitle</code>.</p>
+<p class="item"><b>C.</b> If you want the subtitle to appear in File Data, manually include it via <code>\SetTitle</code>. Example:</p>
+<p class="code"><code>\SetTitle{Megabarf: The Green Plague of London}</code></p>
+<p>Then, you may need to <a href="#h4.3.4.6">adjust page headings</a> so that only the main title appears.</p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Usually, there is no benefit to including the subtitle in File Data. The search database does not read your PDF. It reads the information you entered as <a href="#h3.1.1">ISBN Metadata</a>, which does have an entry for subtitle.</p>
+</div><!-- end 3.3.3 -->
+
+<h4 id="h3.3.4">3.3.4 Advanced: <code>\SetApplication{<em>text</em>}</code> and <code>\SetProducer{<em>text</em>}</code></h4>
+<div class="d4" id="d3.3.4">
+<p class="item"><b>A.</b> The <i>Application</i>, also known as <i>CreatorTool</i>, is the program used to create your source document. Text editors, word processors, and page layout programs are the most common Applications (not specific to TeX).</p>
+<p class="item"><b>B.</b> The PDF <i>Producer</i> is the program that converts the source document to PDF. In many cases, the Producer is a back-end, directly linked to the Application.</p>
+<p class="item"><b>C.</b> These details are automatically created when you compile your document, without any input from you. However, if you have the need to provide a custom text string for the Application or Producer, these commands will do it.</p>
+</div><!-- end 3.3.4 -->
+</div><!-- end 3.3 -->
+
+<h3 id="h3.4">3.4. PDF/X</h3>
+<div class="d3" id="d3.4">
+<p class="item"><b>A.</b> Commercial printers are very likely to require PDF/X compliance. This ensures that your PDF meets a variety of criteria, by containing those things it must contain, and omitting those things it must not contain.</p>
+<p class="item"><b>B.</b> Most perfectly valid PDF files are <em>not</em> PDF/X compliant, simply because they are not intended for commercial printing.</p>
+<p class="item"><b>C.</b> To set PDF/X compliance, use this command in Preamble:</p>
+<p class="code"><code>\SetPDFX[<em>OutputIntent</em>]{<em>ComplianceStandard</em>}</code> &nbsp; and starred version</p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> A non-PDF/X file is not a defective file! It complies with PDF standards, but not PDF/X standards. Some print services insist on PDF/X. Others don't care, as long as the fonts are embedded (which they always are).</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Some document class options are not used for final print production. When you use these options, PDF/X will be temporarily turned <i>off</i>, regardless of your setting.</p>
+
+<h4 id="h3.4.1">3.4.1. Compliance Standards</h4>
+<div class="d4" id="d3.4.1">
+<p class="item"><b>A.</b> The following choices are available:</p>
+<p><code>X-1a:2001</code> (default)</p>
+<p><code>X-1a:2003</code></p>
+<p><code>X-3:2002</code></p>
+<p><code>X-3:2003</code></p>
+<p><code>off</code></p>
+<p class="item"><b>B.</b> The first of these is the one that is most widely accepted in commercial printing. Anything meeting X-1a:2001 necessarily meets the other standards.</p>
+<p class="item"><b>C.</b> If your book involved complicated color artwork, then the correct choice might be crucial. But for a black and white book block, <span style="white-space:nowrap">X-1a:2001</span> is the preferred choice, unless your print service says otherwise.</p>
+</div><!-- end 3.4.1 -->
+
+<h4 id="h3.4.2">3.4.2. Output Intent</h4>
+<div class="d4" id="d3.4.2">
+<p class="item"><b>A.</b> Output Intent informs the printer that you "intend" your PDF to be printed according to certain technical capabilities, particularly regarding color.</p>
+<p class="item"><b>B.</b> If your are using color-managed workflow with a calibrated monitor and color profile, and if the actual printer matches your intent, then you can expect accurate printed colors within the technical limits.</p>
+<p class="item"><b>C.</b> If the intended printer does not match the actual printer, there are three possible results: (1) The file will still be printed, but colors may be inaccurate. Home and office printers do this routinely. (2) If the printer is very advanced, it will adjust its properties to emulate the intended printer. (3) The printer may reject the print job, because it knows that it cannot produce the intended results.</p>
+<p class="item"><b>D.</b> The above considerations are very important for glossy fashion magazines, somewhat important for color book covers, and unimportant for non-color book text. Nevertheless, an Output Intent is required to meet PDF/X compliance, even when it does not matter.</p>
+<p class="item"><b>E.</b> The Output Intent is an optional argument to <code>\SetPDFX</code>, because a default will be used when the Intent is not specified.</p>
+</div><!-- end 3.4.2 -->
+
+<h4 id="h3.4.3">3.4.3. Built-in Output Intent Codes</h4>
+<div class="d4" id="d3.4.3">
+<p class="item"><b>A.</b> There are three pre-defined choices for Output Intent:</p>
+<p><code>CGATS TR 001</code> (default) (can also use CGATSTR001)</p>
+<p><code>FOGRA39</code></p>
+<p><code>JC200103</code></p>
+<p class="item"><b>B.</b> The first of these is known as "US&nbsp;Web&nbsp;Coated&nbsp;SWOP&nbsp;v2" in the USA, and is the most commonly-used American print standard for this kind of book.</p>
+<p class="item"><b>C.</b> The second is widely used in Europe, the third in Japan.</p>
+</div><!-- end 3.4.3 -->
+
+<h4 id="h3.4.4">3.4.4. Other Output Intents</h4><div class="d4" id="d3.4.4">
+<p class="item"><b>A.</b> If you are required to use an Output Intent that is not one of the above three, then you have to code it yourself.</p>
+<p class="item"><b>B.</b> In a place where TeX can find it, create a plain text file with its file name in the following format:</p>
+<p class="code">File name begins with <code>novel-</code> (note the hyphen).</p>
+<p class="code">No spaces or underscores in file name, no matter what the Intent.</p>
+<p class="code">File extension is <code>.clo</code></p>
+<p class="item"><b>C.</b> Example valid file name: <code>novel-YourIntent.clo</code>.</p>
+<p class="code">The above file is loaded using <code>\SetPDFX[YourIntent]{<em>compliance</em>}</code>.</p>
+<p class="item"><b>D.</b> The file contains (up to) five <code>\gdef</code> commands. The <code>\@OIidentifier</code> is called "reference name" by some authorities. Here is the code used for <code>CGATS TR 001</code>:</p>:
+<div style="margin:0px 16px 0px 16px; background: #dddddd none">
+<p class="code"><code>\gdef\@OIidentifier{CGATS TR 001}</code></p>
+<p class="code"><code>\gdef\@OIcondition{SWOP (Publication) printing in USA (Printing process definition: ANSI CGATS.6).}</code></p>
+<p class="code"><code>\gdef\@OIinfo{U.S. Web Coated (SWOP) v2}</code></p>
+<p class="code"><code>\gdef\@OIregistry{http://www.color.org}</code></p>
+<p class="code"><code>\gdef\@OIprofile{USWebCoatedSWOP.icc}</code></p>
+</div>
+<p class="item"><b>E.</b> If the data contains any TeX special characters, such as underscore, percent, ampersand, or number sign, they must be escaped using a backslash.</p>
+<p class="item"><b>F.</b> The necessary data may be provided by your print service, or perhaps can be found at resources such as the <a href="http://color.org/registry/index.xalter" rel="external" class="external" target="new">International Color Consortium</a>. Alas, this source (and others) do not make it easy to discern the data.</p>
+<p class="item"><b>G.</b> Another place to look for Output Intent data is in your (texmf)/tex/latex/pdfx folder. This will be in your TeX system if package <i>pdfx</i> is installed (but do not load this package into <i>novel</i> class). Files <i>AdobeColorProfiles.tex</i> and <i>AdobeExternalProfiles.tex</i> contain code prepared by the author of the <i>pdfx</i> package. The macro names are not the same, but they are easy to decode: <code>\@OIidentifer</code> is <i>/OutputConditionIdentifier</i>; <code>\@OIcondition</code> is <i>/ProfileName</i>; <code>\@OIinfo</code> is <i>/OutputCondition</i>; <code>\@OIregistry</code> is <i>/RegistryName</i>; and <code>\@OIprofile</code> follows <i>\setCMYKcolorprofile</i>.</p>
+</div><!-- end 3.4.4 -->
+
+<h4 id="h3.4.5">3.4.5. Whether or Not to Embed *.icc</h4><div class="d4" id="d3.4.5">
+<p class="item"><b>A.</b> Each Output Intent has a color profile, in the form of a file with extension <i>*.icc</i>.</p>
+<p class="item"><b>B.</b> You usually do not need the color profile, because the printer knows which profile corresponds with which standard Output Intent code.</p>
+<p class="item"><b>C.</b> When you use <code>\SetPDFX</code> in its un-starred form, the *.icc color profile will not be embedded in the PDF. This is the normal situation.</p>
+<p class="item"><b>D.</b> If your print service demands that you embed the *.icc color profile, then use <code>\SetPDFX*</code> (with the asterisk). You must have the actual *.icc file available where TeX can find it.</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Do not embed the *.icc color profile unless specifically requested by your print service. If you embed it when you should not, the result may be worse!</p>
+<p class="item" style="position:relative"><b>F.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> If your printer requests "US Web Coated SWOP v2" and, as usual, requests that you <em>not</em> embed the corresponding *.icc color profile, then some software will read the Output Intent as "CGATS&nbsp;TR&nbsp;001" instead of "US&nbsp;Web&nbsp;Coated&nbsp;SWOP&nbsp;v2". They are identical.</p>
+</div><!-- end 3.4.5 -->
+
+<h4 id="h3.4.6">3.4.6. Where to Find *.icc Files</h4><div class="d4" id="d3.4.6">
+<p class="item"><b>A.</b> You do not need an *.icc color profile unless you choose to embed it.</p>
+<p class="item"><b>B.</b> Although many *.icc color profiles are freely available, they usually cannot be distributed within an open-source project. You might already have them in your system, wherever such files are stored. Note that TeX uses forward slash in file paths, not backslash, even if the platform is Windows:</p>
+<p class="isolate">
+Windows: <code>C:/Windows/System32/spool/drivers/color/</code><br/>
+Linux: <code>/usr/share/color</code> or hidden <code>~/.local/share/icc/</code> or other places<br/>
+OSX: <code>/Library/Colorsync/Profiles/</code> or hidden <code>(username)/Library/Colorsync/Profiles/</code>
+</p>
+<p class="item"><b>C.</b> If you do not have a file you need, look on the Internet <a href="https://www.adobe.com/support/downloads/iccprofiles/icc_eula_win_end.html" target="new">here</a> and <a href="http://www.color.org/profiles.xalter" target="new">here</a>. These links also have many other profiles, beyond the basic three.</p>
+<p class="item"><b>D.</b> In a few cases, your print service may provide the necessary *.icc file.</p>
+<p class="item"><b>E.</b> You want <i>printer</i> profiles, usually CMYK. Don't worry about the files being "for Windows," as they are actually cross-platform.</p>
+<p class="item"><b>F.</b> If your system has the necessary <i>*.icc</i> file for your Output Intent, but <i>novel</i> cannot find it, then copy the file to the same folder as your TeX document.</p>
+<p class="item" style="position:relative"><b>G.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Again: Do not embed the color profile unless the printer requests embedding.</p>
+</div><!-- end 3.4.6 -->
+</div><!-- end 3.4 -->
+
+
+</div><!-- end 3 -->
+</div><!-- end page03 -->
+<!-- ************************************************************ -->
+<div id="page04" class="page">
+
+
+<h2 id="h4">4. Book Size, Page Layout, and Fonts</h2>
+<div class="d2" id="d4">
+<p class="noindent">In <i>novel</i>, you do not use class options to set the size or layout of your book, or font size.</p>
+
+<h3 id="h4.1">4.1. Book Dimensions</h3>
+<div class="d3" id="d4.1">
+
+<h4 id="h4.1.1">4.1.1. Trim Size and TrimBox</h4>
+<div class="d4" id="d4.1.1">
+<p class="noindent">Trim Size is globally set in Preamble:</p>
+<p class="code"><code>\SetTrimSize{<em>width</em>}{<em>height</em>}</code></p>
+<p>The width and height must have dimensions, such as <i>in</i> or <i>cm</i>.</p>
+<p class="item"><img src="html-resources/trimsize.png" class="floatright" width="130" height="190" alt="Trim Size" title="Trim Size"/><b>A.</b> <b>Trim Size</b> is the finished size of your book, width and height (but not thickness). In the case of softcover books, it is the exact size.</p>
+<p>In the case of hardcover books, where the cover is slightly larger than the pages, your print service will tell you whether they mean the cover size or the page size.</p>
+<p class="item"><b>B.</b> PDF/X internally specifies the Trim Size as a rectangular <b>TrimBox</b>. This provides invisible instructions to an automated cutting machine, when the Trim Size is smaller than the actual paper sheet. You do not set the TrimBox yourself.</p>
+<p class="item"><b>C.</b> Your print service has a list of standard trim sizes. For fiction, you probably want "creme" (off-white) paper, which eliminates a few of the choices. Choice of size may also be limited by the distribution channels.</p>
+<p class="item"><b>D.</b> If you do not specify the Trim Size, the default is <i>5.5in</i> wide, <i>8.5in</i> high. This is a widely-used "trade" size for softcover print-on-demand fiction in the U.S.A. If in doubt, leave the default.</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Do not request a <i>mass-market paperback</i> Trim Size unless you really, truly, know what you are doing. Since you are not a major writer for a major publishing house, you don't know; so, don't do it.</p>
+</div><!-- end 4.1.1 -->
+
+<h4 id="h4.1.2">4.1.2. Media Size, MediaBox, Bleed, and BleedBox</h4>
+<div class="d4" id="d4.1.2">
+<p class="noindent"><b>PDF page size</b> is known as <b>Media Size</b>, defined by an invisible <b>MediaBox</b> in PDF internal code. It is known as <b>paperwidth</b> and <b>paperheight</b> in TeX terminology.</p>
+<p class="item"><b>A.</b> For cover artwork, the PDF page size <i>must</i> be larger than the artwork <a href="#h4.1.1">Trim Size</a>, so that the image can <b>bleed</b> outside the <a href="#h4.1.1">TrimBox</a>. Use this command in Preamble:</p>
+<p class="code"><code>\SetMediaSize{<i>width</i>}{<i>height</i>}</code></p>
+<p>This will center the Trim Size in the larger Media Size.</p>
+<p class="item"><b>B.</b> Generally, the American standard is 0.125in bleed on all four sides of the cover image; metric nations may use 3mm. Then, the Media Size would be 0.25in (or 6mm) larger than Trim Size in both dimensions.</p>
+<p class="item"><b>C.</b> <b>Example:</b> Suppose that the Trim Size of your book is 5.5in wide x 8.5in high. Based on the number of pages, its spine width is 0.6in.</p>
+<p>Then, the Trim Width of the (Perfect Print) cover will be 5.5in + 0.6in + 5.5in = 11.6in. The Trim Height is 8.5in.</p>
+<p>If you are required to provide 0.125in bleed on all four sides, the Media Width is 0.125in + 11.6in + 0.125in = 11.85in. The Media Height is 0.125in + 8.5in + 0.125in = 8.75in. The commands:</p>
+<p class="code"><code>\SetTrimSize{11.6in}{8.5in}</code></p>
+<p class="code"><code>\SetMediaSize{11.85in}{8.75in}</code></p>
+<p class="item"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> If you fail to use <code>\SetMediaSize</code> with <code>coverart</code>, or choose surprising values, then you will get an error or warning from <i>novel</i>.</p>
+<p class="item"><b>E.</b> For the interior book block, almost all P.O.D. services require that the PDF page size be identical to the <a href="#h4.1.1">Trim Size</a>. This is done automatically. You do not use <code>\SetMediaSize</code>.</p>
+<p class="item"><b>F.</b> In rare cases, a P.O.D. service will ask you to float the interior book block in a larger, standard paper size. You may use <code>\SetMediaSize</code> for this purpose. The <i>novel</i> class does not support interior bleed, so when you are not using <code>coverart</code> mode, no BleedBox is set.</p>
+</div><!-- end 4.1.2 -->
+</div><!-- end 4.1 -->
+
+<h3 id="h4.2">4.2. Fonts and Normal Font Size</h3>
+<div class="d3" id="d4.2">
+
+<h4 id="h4.2.1">4.2.1. Parent (Main) Font and Size</h4>
+<div class="d4" id="d4.2.1">
+<p class="item"><b>A.</b> In <i>novel</i> you do not directly set the main font (also known as <i>roman default</i>). Instead, you set a parent font, from which the main font is derived.</p>
+<p class="item"><b>B.</b> The default parent font is <i>Libertinus Serif</i>, which is an updated branch of <i>Linux Libertine O</i>. You must install it as package <i>libertinus</i>.</p>
+<p>Online services, such as ShareLaTeX, have <i>libertinus</i>.</p>
+<p> If you do not have the Libertinus fonts, then <i>Latin Modern Roman</i> will be used as fallback. But LMR is not really suitable for use in printed fiction; it is allowed so that test documents can compile, until you choose a more suitable font.</p>
+<p class="item"><b>C.</b> Choose only Open Type or TrueType fonts, not the ancient Type 1 (PostScript) or Metafonts. The font you choose does not have to be part of any TeX package, because you do not need any <i>*.sty</i> file or TeX metrics. All of that is built into the font itself. This is thanks to <i>LuaLaTeX</i> and the built-in <i>fontspec</i> package.</p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> You do <i>not</i> write <code>\usepackage{<i>fontname</i>}</code>, or <code>\RequirePackage{<i>fontname</i>}</code>, or <code>\setmainfont{<i>fontname</i>}</code>. If you do that, then a warning or error will result, and in any case the font you get won't be the one you were expecting.</p>
+
+<h5 id="h4.2.1.1">4.2.1.1. <code>\SetParentFont[<em>features</em>]{<em>fontname</em>}</code></h5>
+<div class="d5" id="d4.2.1.1">
+<p class="item"><b>A.</b> In <i>novel</i> you set a parent font, which is the ancestor of several pre-defined font styles, including the main font. In Preamble:</p>
+<p class="code"><code>\SetParentFont[<em>features</em>]{<em>fontname</em>}</code><p>
+<p class="item"><b>B.</b> The command uses <i>fontspec</i> syntax, which is reviewed in <a href="#hE">Appendix E</a>, and described in full detail by the <i>fontspec</i> package documentation.</p>
+<p class="item"><b>C.</b> Whether you use <code>\SetParentFont</code> or accept the default, the features and fontname are stored as strings in macros <code>\parentfontfeatures</code> and <code>\parentfontname</code>. You may use <code>\parentfontfeatures</code> and <code>\parentfontname</code> as arguments to other font commands.</p>
+<p class="item"><b>D.</b> If you have the proper license, you can use a commercial font. For example:</p>
+<p class="code"><code>\SetParentFont{Adobe Garamond Pro}</code></p>
+<p>See how easy that is? By default, <i>novel</i> will apply TeX Ligatures and Kerning to the parent font and all its descendants. Common Ligatures and OldStyle numbers will be added for the main font. This is ideal for fiction.</p>
+</div><!-- end 4.2.1.1 -->
+
+<h5 id="h4.2.1.2">4.2.1.2. <code>\SetFontSize{<em>length</em>}</code></h5>
+<div class="d5" id="d4.2.1.2">
+<p class="item"><b>A.</b> In the <i>novel</i> document class, you do not set point size as a class option. Instead you use <code>\SetFontSize</code> in the Preamble. It applies to the parent (main) font, and is used as the basis for scaling font sizes.</p>
+<p class="item"><b>B.</b> The size may be any units TeX understands, including decimal values. So, <i>12.8bp</i> and <i>13.1pt</i> are acceptable. This is because you will be using scalable, Open&nbsp;Type and TrueType fonts throughout your document. They do not need TeX metrics.<p>
+<p class="item"><b>C.</b> If you insist on using ancient TeX fonts, then you may need to specify a convenient integer font size such as 11pt or 12pt. But why? Forget those fonts! Welcome to the Twenty-First Century.</p>
+<p class="item"><b>D.</b> The minimum global font size is <i>8pt</i>, and the maximum is <i>18bp</i>. On a local basis, text may be larger or smaller than this.</p>
+<p class="item"><b>E.</b> If you do not use <code>\SetFontSize</code>, the default will be <i>11.4pt</i> more or less. That is, the size is calculated from other layout settings. When there is less available text area, the default size is <i>11pt</i>. For larger books, the default is <i>12pt</i>.</p>
+<p class="item"><b>F.</b> Once you have set the Trim Size, margins, and parent font, set the font size for readability. Depending on whom you ask, each line of free-running text should average 60 to 66 characters (including spaces). If you use all of the <i>novel</i> default settings, including <i>Libertinus Serif</i> parent font, that's what you will get. But if you change anything, then do a test document to see what font size works best.</p>
+</div><!-- end 4.2.1.2 -->
+</div><!-- end 4.2.1 -->
+
+<h4 id="h4.2.2">4.2.2. Descendant Fonts: main font, chapter font, subch font, head font</h4>
+<div class="d4" id="d4.2.2">
+<p class="item"><b>A.</b> The descendant fonts are automatically set, as variations of the <i>parent font</i>:</p>
+<p class="centerimg"><img src="html-resources/font-tree.png" width="600" height="177" title="font tree" alt="font tree"/></p>
+<p>For example, the <i>main font</i> uses the <i>parent font</i> family. It has TeX Ligatures and Kerning (inherited from the <i>parent font</i>), and also Common Ligatures and OldStyle numbers.</p>
+<p class="item"><b>B.</b> The <i>main font</i> is not configured directly. Instead, configure the <i>parent font</i>, then the <i>main font</i> (and other descendants) will obey. For example, if you don't want OldStyle numbers:</p>
+<p class="code"><code>\SetParentFont[<em>Numbers=Lining</em>]{<em>fontname</em>}</code></p>
+<p>Then, Lining numbers will be used for the <i>main font</i> (and other descendants).<p>
+<p class="item"><b>C.</b> If you don't like the defaults, you can set the other descendant fonts directly, in Preamble:</p>
+<p class="code">
+<code>\SetChapterFont[<em>features</em>]{<em>fontname</em>}</code> &nbsp; % <em>see section <a href="#h5.1.3.1">5.1.3.1</a></em><br/>
+<code>\SetSubchFont[<em>features</em>]{<em>fontname</em>}</code> &nbsp; % <em>see section <a href="#h5.1.3.1">5.1.3.1</a></em><br/>
+<code>\SetHeadFont[<em>features</em>]{<em>fontname</em>}</code> &nbsp; % <em>see section <a href="#h4.3.4.2">4.3.4.2</a></em>
+</p>
+<p class="item"><b>D.</b> You may use <code>\parentfontfeatures</code> and/or <code>\parentfontname</code> as arguments, if you wish.</p>
+</div><!-- end 4.2.2 -->
+
+<h4 id="h4.2.3">4.2.3. Advanced: The Deco Font</h4>
+<div class="d4" id="d4.2.3">
+<p class="item"><b>A.</b> Open Type font <i>NovelDeco.otf</i> is packaged with the <i>novel</i> class. It is a special-purpose font that provides characters for the <code><a href="#h5.1.3.3">\decoglyph</a></code> and <code><a href="#h6.2.4">\midcase</a></code> commands.</p>
+<p class="item"><b>B.</b> Normally, you do not need to configure this font, as it is automatic. The only reason for changng it is if you are an advanced user, who wishes to use a substitute font with different decorations. However, you may <i>not</i> specify just any font! The substitute must be an edited version of <i>NovelDeco.otf</i>, with a different font name. If you don't know what that means, then don't do it.</p>
+<p class="code">
+<code>\SetDecoFont[<em>features</em>]{<em>fontname</em>}</code> &nbsp; % <em>see section <a href="#h5.1.3.3">5.1.3.3</a></em>
+</p>
+</div><!-- end 4.2.3 -->
+
+<h4 id="h4.2.4">4.2.4. Advanced: Mono, Sans, and Math Fonts</h4>
+<div class="d4" id="d4.2.4">
+<p class="item"><b>A.</b> There are several pre-defined fonts that do not descend from the <i>parent font</i>. In each case, an appropriate default font is selected. You will probably never need to use them; but TeX being what it is, default fonts are chosen "whether you like it or not."</p>
+<p class="item"><b>B.</b> The default sans-serif font will be <i>Libertinus Sans</i> if available. If not, the fallback font is <i>Latin Modern Sans</i>. To choose your own, use this command in Preamble, with <i>fontspec</i> syntax:</p>
+<p class="code"><code>\SetSansFont[<em>features</em>]{<em>fontname</em>}</code></p>
+<p class="item"><b>C.</b> The default monospaced font will be <i>Libertinus Mono</i> if available. If not, the fallback font is <i>Latin Modern Mono</i>. To choose your own, use this command in Preamble, with <i>fontspec</i> syntax:</p>
+<p class="code"><code>\SetMonoFont[<em>features</em>]{<em>fontname</em>}</code></p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> If you need a math font, then may I gently suggest that maybe <i>novel</i> is not the right document class for you?</p>
+<p>Nevertheless, <i>Libertinus Math</i> is loaded if available; otherwise <i>Latin Modern Math</i>.</p>
+<p>If neither of those fonts are found, then <i>NovelDeco.otf</i> will be loaded as a fake math font, with no actual math symbols. That allows you to proceed without a real math font. But if you attempt to print math, it will look wrong.</p>
+<p>You may choose your own math font using <code>\setmathfont</code> from package <i>unicode-math</i>. See that package documentation for details.</p>
+</div><!-- end 4.2.4 -->
+
+<h4 id="h4.2.5">4.2.5. Advanced: Defining New Font Commands</h4>
+<div class="d4" id="d4.2.5">
+<p class="item"><b>A.</b> You can define new font commands in Preamble. The syntax depends on whether the new font is part of a family (where you might have bold and italic variants), or just a single file (no variants). If part of a family, use <code>\NewFontFamily</code>. If alone, use <code>\NewFontFace</code>.</p>
+<p>The <code>\NewFontFamily</code> command (or <code>\NewFontFace</code>) takes three arguments: First, the name you assign to the new font command is required. Second, font features are optional. Third, the font name is required. The <i>fontspec</i> syntax is used in Preamble:</p>
+<p class="code"><code>
+\NewFontFamily<em>\pickaname</em>[<em>features</em>]{<em>fontfamily</em>}<br/>
+\NewFontFace<em>\pickaname</em>[<em>features</em>]{<em>singlefont</em>}
+</code></p>
+<p>In the document body, you use the new font command:</p>
+<p class="code"><code>{\pickaname Text in the font selected by pickaname command.}</code></p>
+<p class="item"><b>B.</b> If you define a font <em>family</em> when you should have just defined a font <em>face</em>, there will be complaints in the log file, because the font loader cannot find the (nonexistent) other members of the family. But the document will compile.</p>
+<p>On the other hand, if you define a font <em>face</em> when you should have defined a font <em>family</em>, then commands for bold or italic will have no effect, since the other family members were not loaded. Again, the document will compile.</p>
+<p class="item"><b>C.</b> Example: Suppose your work is science fiction, and one if its characters is a talking robot. You wish to depict its utterances in a robotic-looking font, which will be called using a new <code>\robovoice</code> command. You shop around, and find that the <em>Orbitron</em> font suits your purpose, except that it is too large compared to your <i>main font</i>. So, you scale it.</p>
+<p>In the Preamble, you define the new font command:</p>
+<p class="code"><code>\NewFontFace\robovoice[Scale=0.8]{Orbitron} % not part of a family</code></p>
+<p>After some experimentation, you realize that the \robovoice letters need to be spread apart a bit. Do not use <code>\textls</code>. Instead, go back and change the font definition like this:
+<p class="code"><code>\NewFontFace\robovoice[Scale=0.8,LetterSpace=<em>number</em>]{Orbitron} % pick a number</code></p>
+<p>In the document body:</p>
+<p class="code"><code>
+``Want some oil?'' asked Captain Withens.\par<br/>
+{\robovoice ``Is it Gamma-42 Special oil?''} asked the robot.\par<br/>
+``No, I got it on sale at Cosmo-Mart.''\par<br/>
+{\robovoice ``Forget it. I'm an oil gourmet.''}\par
+</code></p>
+<p>The result:</p>
+<p class="centerimg"><img src="html-resources/human-robot-talk.png" width="483" height="127" alt="conversation, human-robot"/></p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Caution: If you are using a new font within body text (as above), then it is a bad idea to use Scale greater than 1.0. Reason: An excessively tall font will cause lines to spread apart, and you will lose the line grid.</p>
+<p class="item"><b>E.</b> <img class="floatright" src="html-resources/fluffy-conspiracy.png" width="265" height="409" alt="the fluffy conspiracy"/> Example: Suppose that you wish to style the title of your book, in a font that is not used for other things such as chapter titles. You purchase a license for the <em>Bernhard Modern Std</em> fonts, in Regular and Italic.</p>
+<p>In the Preamble:</p>
+<p class="code"><code>\NewFontFamily\booktitlefont{Bernhard Modern Std}</code></p>
+<p>The title page, using <code><a href="#h6.1.2">\charscale</a></code> for size:</p>
+<p class="code"><code>
+\thispagestyle{empty}<br/>
+\vspace*{7<span style="cursor:help" title="normal baseline skip">\nbs</span>}<br/>
+\begin{center}<br/>
+\charscale[3]{\booktitlefont The \textit{Fluffy} Conspiracy}\par<br/>
+\vspace{6<span style="cursor:help" title="normal baseline skip">\nbs</span>}<br/>
+\charscale[2]{Priscilla Milde}\par<br/>
+\vfill<br/>
+Nonexistent Publications • Portland, Oregon\par<br/>
+\end{center}
+</code></p>
+<div style="clear:both"></div>
+</div><!-- end 4.2.5 -->
+</div><!-- end 4.2 -->
+
+<h3 id="h4.3">4.3. Interior Page Layout</h3>
+<div class="d3" id="d4.3">
+<p class="noindent">Everything is pre-configured, specifically for the purpose of fiction. You only need to write a layout command if you don't like the defaults.</p>
+
+<h4 id="h4.3.1">4.3.1. Margins</h4>
+<div class="d4" id="d4.3.1">
+<p class="noindent">Margins are globally set in Preamble:</p>
+<p class="code"><code>\SetMargins{<em>top</em>}{<em>outer</em>}{<em>bottom</em>}{<em>inner</em>}</code></p>
+<p>Mnemonic for order of margins (<i>Hamlet</i>): "TOBI, or not TOBI, that is the question."</p>
+<p>Each of the settings must have dimension, such as <i>in</i> or <i>mm</i>.</p>
+<p class="item"><b>A.</b> <b>Margins</b> are required on all four edges of the page (but not cover art). They do not have to be the same width. Generally the margin at the inside edge (spine margin) is wider. The <i>novel</i> class does not provide for marginal notes.</p>
+<p class="item"><b>B.</b> In the case of fiction, it is usually the case that the inner margin is the widest. But this is not a rule for all books. All that is required is that each margin be "wide enough" for the printing process.</p>
+<p class="item"><b>C.</b> Print services are not used to seeing books with exotic margins (such as bottom margin twice the size of top margin). They may think that there is a mistake in your PDF, or in the print job, if you do that.</p>
+<p class="item"><img class="floatright" src="html-resources/margins-trim-media.png" width="202" height="264" title="Trim Size floated in larger Media Size" alt="Trim Size floated in larger Media Size"/><b>D.</b> Normally, your TeX document will be compiled to a PDF that is electronically at the exact Trim Size. And normally, print services want it to be that way. When you view your PDF, the text will shift from side to side as you move through the pages, due to the slightly increased margin at the inside edge.</p>
+<p class="item"><b>E.</b> Margins are always relative to the Trim Size. If you are using a larger Media Size, the area outside the TrimBox is <i>not</i> counted among the margins; it is simply wasted area. This is illustrated at right, where a smaller Trim Size is floated in a marger Media Size. The margins are shown in gray.</p>
+<p class="item" style="clear:both"><img src="html-resources/topmargins.png" class="floatright" width="158" height="292" alt="top margins, with and without header" title="top margins, with and without header"/><b>F.</b> If you do not use <code>\SetMargins</code>, then margins are pre-configured. The minimum pre-configured margins are 0.5in at top, outside, and bottom, and 0.75in at inside. This meets the requirements of nearly any printing technology, unless your book is extremely thick. </p>
+<p>If your Trim Size is among the larger ones, then the pre-configured margins are larger than these minimums.</p>
+<p class="item"><b>G.</b> If your page layout uses header and/or footer, these elements sit within the rectangle bounded by the four margins. That is, they share the same space as main text.</p>
+<p>At right, the top margin is shown in gray, for three situations. Layout #1 has a header. Layout #2 also has a header, but this particular page leaves the header empty. Layout #3 has no header.</p>
+<div style="clear:both"></div>
+
+<h5 id="h4.3.1.1">4.3.1.1. Gutter? Which Gutter?</h5>
+<div class="d5" id="d4.3.1.1">
+<p><img class="floatright" src="html-resources/whichgutter.png" width="276" height="219" title="Which gutter?" alt="Which gutter?"/>Be aware that there is a lot of confusion regarding the word "gutter."</p>
+<p>In the accompanying diagram, the central shaded area is at the spine, where there must be an allowance for the book assembly process. "Gutter" might mean any of A, B, C, or D, depending on who is doing the talking, and which software is in use.</p>
+<p>The <i>novel</i> class uses <em>inner margin</em>, also known as <em>spine margin</em>, to mean <i>C</i>. There is no setting for "gutter" as such.</p>
+<div style="clear:both"></div>
+</div><!-- end 4.3.1.1 -->
+
+<h5 id="h4.3.1.2">4.3.1.2. Unsafe Zone</h5>
+<div class="d5" id="d4.3.1.2">
+<p class="noindent">Optional global setting, in Preamble:</p>
+<p class="code"><code>\SetUnsafeZone{<em>top</em>}{<em>outer</em>}{<em>bottom</em>}{<em>inner</em>}</code></p>
+<p class="item"><b>A.</b> This applies only to interior text block. Although cover artwork has unsafe zones, they are specified by a graphic design template.</p>
+<p class="item"><img class="floatright" src="html-resources/unsafe-vs-margin.png" width="228" height="150" title="unsafe zone vs margin" alt="unsafe zone vs margin"/><b>B.</b> Printers have a "safe zone," where you are allowed to place text and images. The area outside the safe zone is the "unsafe zone." If anything lies within the unsafe zone, even in part, then the file may print badly, or be rejected by commercial printers.</p>
+<p class="item"><b>C.</b> Unsafe zone is a sub-area of the margins. That is, the margins include the unsafe zone (if set), and usually some additional area. The accompanying image shows a page with narrow unsafe zone, and wider margin.</p>
+<p class="item"><b>D.</b> Some printers describe the unsafe zone as "minimum margin." But in most cases, visually appealing margins are wider than the unsafe zone. You may be able to place items out there, for special effects.</p>
+<p class="item"><b>E.</b> You do not need to set the unsafe zone. Whether or not you do, and regardless of any values you choose, the result does not affect the finished, final PDF. The zones are not enforced. Margins are unaffected.</p>
+<p class="item"><b>F.</b> If you set unsafe zone, then the unsafe area will have a dark gray background, when you use <code>[draft,shademargins]</code> as class options. This allows you to visualize whether anything intrudes into the unsafe zone.</p>
+<div style="clear:both"></div>
+</div><!-- end 4.3.1.1 -->
+</div><!-- end 4.3.1 -->
+
+<h4 id="h4.3.2">4.3.2. Lines Per Page</h4>
+<div class="d4" id="d4.3.2">
+<p class="item"><b>A.</b> Lines per page refers only to the textblock, and does <em>not</em> include header/footer. Lines are not stretched to fill short pages.</p>
+<p class="item"><b>B.</b> By default, a suitable number of lines per page are automatically set, based on other dimensions. You can change the default with this command, in Preamble:</p>
+<p class="code"><code>\SetLinesPerPage{<em>integer</em>}</code></p>
+<p> Any non-integer will be rounded. There is no direct command to set the <em>leading</em>, also known as line-to-line spacing or <em>baselineskip</em>. Instead, it is calculated from the textblock height and number of lines.</p>
+<p class="item"><b>C.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> If you change any other dimensions (margins, head/foot, font size, etc.) then the calculated default number of lines per page will probably change. If you like the initial default value, then set it manually.</p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> If the calculated leading is less than <i>1.2x</i> the font size, an error will result. It is difficult for TeX to honor all layout settings with such a small leading, which would normally be unacceptable for fiction in any case.</p>
+<p>If the calculated leading is at least <i>1.2x</i> the normal size, but less than <i>1.25x</i> the normal size, then the log file will have an Alert message, suggesting that you should consider using fewer lines per page. If the leading exceeds <i>1.4x</i> the font size, then the log will have an Alert, suggesting more lines per page. The Alert messages are friendly; you do not necessarily have to do anything.</p>
+</div><!-- end 4.3.2 -->
+
+<h4 id="h4.3.3">4.3.3. Global Header/Footer Styles</h4>
+<div class="d4" id="d4.3.3">
+<p class="item"><b>A.</b> Global choice of header/footer style is made in Preamble. Although some individual pages may have no visible header or footer, in reality the header/footer is "still there" in terms of occupying space, but has no content.</p>
+<p class="item"><b>B.</b> There are six pre-configured header/footer styles, numbered <i>1</i> through <i>6</i>. These address every style I have seen in fiction. When you choose one of these styles, it reserves space for a header (if any) above the main text, and space for a footer (if any) below the main text. You may <i>not</i> write multi-line headers or footers.</p>
+<p class="item"><b>C.</b> The default style is <i>1</i>, which has header, but no footer. Page numbers appear at the outside. Text (such as author or title) appears centered.</p>
+<p class="item"><b>D.</b> Style <i>0</i> has no header or footer. This is not used in fiction, but it is available.</p>
+<p class="item"><b>E.</b> Throughout the body of your document, you can use <a href="#h4.3.5">local commands</a> to <a href="#h4.3.4.6">change the content</a> of headers and footers, or blank them. But you may not change the global header/footer style mid-document.</p>
+
+<h5 id="h4.3.3.1">4.3.3.1. List of Header/Footer Style Choices</h5>
+<div class="d5" id="d4.3.3.1">
+<p>&nbsp;</p>
+<img class="floatright" style="margin-bottom:8px" src="html-resources/headfoot1.png" width="276" height="219" alt="style 1" title="style 1"/>
+<p class="overhang">
+<code><b>\SetHeadFootStyle{1}</b></code><br/>
+Only Header.<br/>
+Page number at outside (left verso, right recto).<br/>
+Optional emblem adjacent to page number.<br/>
+Text centered. Default author verso, title recto.<br/>
+<em>This is the default for the novel document class.</em></p>
+<div style="clear:both"></div>
+<img class="floatright" style="margin-bottom:8px" src="html-resources/headfoot2.png" width="276" height="219" alt="style 2" title="style 2"/>
+<p class="overhang">
+<code><b>\SetHeadFootStyle{2}</b></code><br/>
+Only Footer.<br/>
+Page number at outside (left verso, right recto).<br/>
+Optional emblem adjacent to page number.</p>
+<div style="clear:both"></div>
+<img class="floatright" style="margin-bottom:8px" src="html-resources/headfoot3.png" width="276" height="219" alt="style 3" title="style 3"/>
+<p class="overhang">
+<code><b>\SetHeadFootStyle{3}</b></code><br/>
+Only Footer.<br/>
+Page number centered.<br/>
+Disregards emblem, if coded.</p>
+<div style="clear:both"></div>
+<img class="floatright" style="margin-bottom:8px" src="html-resources/headfoot4.png" width="276" height="219" alt="style 4" title="style 4"/>
+<p class="overhang">
+<code><b>\SetHeadFootStyle{4}</b></code><br/>
+Only Header.<br/>
+Page number at outside (left verso, right recto).<br/>
+Optional emblem adjacent to page number.<br/>
+Text towards outside, instead of centered.<br/>
+Text begins or ends 1em from the emblem.<br/>
+Default author verso, title recto.</p>
+<div style="clear:both"></div>
+<img class="floatright" style="margin-bottom:8px" src="html-resources/headfoot5.png" width="276" height="219" alt="style 5" title="style 5"/>
+<p class="overhang">
+<code><b>\SetHeadFootStyle{5}</b></code><br/>
+Header and Footer.<br/>
+Page number centered in footer.<br/>
+Disregards emblem, if coded.<br/>
+Text centered in header.<br/>
+Default author verso, title recto.</p>
+<div style="clear:both"></div>
+<img class="floatright" style="margin-bottom:8px" src="html-resources/headfoot6.png" width="276" height="219" alt="style 6" title="style 6"/>
+<p class="overhang">
+<code><b>\SetHeadFootStyle{6}</b></code><br/>
+Only Header.<br/>
+Page number at outside (left verso, right recto).<br/>
+Optional emblem adjacent to page number.<br/>
+Text towards inside, instead of centered.<br/>
+Default author verso, title recto.</p>
+<div style="clear:both"></div>
+</div><!-- end 4.3.3.1 -->
+
+<h5 id="h4.3.3.2">4.3.3.2. Custom Header/Footer Style</h5>
+<div class="d5" id="d4.3.3.2">
+<p class="item"><b>A.</b> Before you think about writing a custom header/footer style, be sure to try the above pre-configured choices. I have looked through a lot of fiction of all kinds. The pre-configured choices include every style I have seen, with the exception of the most highly decorative.</p>
+<p class="item"><b>B.</b> If none of the above are satisfactory, then you can write your own headers and footers using the syntax of the <i>fancyhdr</i> package. Strategy:</p>
+<p>&bull; In the Preamble, you must use one of the above <code>\SetHeadFootStyle</code> choices to pick a starting point, in terms of whether or not there is a header and/or footer. <em>This is required, so that the layout engine knows how to calculate space.</em> After that, write the <i>fancyhdr</i> code for your custom header/footer in the Preamble. It will over-ride the numerical style in terms of appearance, but occupy the same space.</p>
+<p>&bull; You normally cannot use a header or footer with more than one line. If you have the expertise, two lines can be used, with sufficient <a href="#h4.3.4.1">jump</a>. Not recommended, and not documented.</p>
+<p>&bull; See the file <i>novel-HeadFootStyles.sty</i> for how it is done in the pre-configured styles. In the file, the relevant portion follows <em>Look here for the pre-defined styles, for use as models.</em></p>
+<p>&bull; Particularly note that your own style will not automatically use the <i>head font</i>, or add extra space between letters, unless you include the necessary code in your own definition. Do not use the <code>\textls</code> command.</p>
+<p>&bull; No cheating! If you choose a numerical style that does not have a header, then do not attempt to write a custom style that includes a header. Same with footer. Also, if you you choose a numerical style with both header and footer, then you cannot only customize one of them; you must customize both.</p>
+</div><!-- end 4.3.3.2 -->
+</div><!-- end 4.3.3 -->
+
+<h4 id="h4.3.4">4.3.4. Tweaking the Global Header/Footer Style</h4>
+<div class="d4" id="d4.3.4">
+<p class="noindent">You may customize the appearance, and to some extent the content, of the various parts of the header and footer. These are global settings, in Preamble.</p>
+
+<h5 id="h4.3.4.1">4.3.4.1. Gap Between Header/Footer and Main Text</h5>
+<div class="d5" id="d4.3.4.1">
+<p class="code"><code>\SetHeadJump{<em>number</em>}</code>, <code>\SetFootJump{<em>number</em>}</code></p>
+<p class="item"><b>A.</b> These two commands control the separation between the header/footer and the main text. If your style does not have a header and/or footer, then the corresponding setting will be ignored.</p>
+
+<p class="item"><b>B.</b> The head and/or foot "jump" is a multiple of the normal baseline skip. Each value is a number between 1 and 3, and may be decimal. The jumps do not need to be identical. Default is 1.5 for each. Measurements are from baseline to baseline.</p>
+<p class="centerimg" style="text-indent:0px"><img src="html-resources/head-foot-jumps.png" width="552" height="151" alt="headjump and footjump" title="headjump and footjump"/></p>
+<p class="item"><img src="html-resources/jump-change.png" class="floatright" style="padding-top:12px" width="360" height="272" alt="jump changes" title="jump changes"/><b>C.</b> When a "jump" is changed, its header or footer remains in the same place. The margins are unchanged.</p>
+<p class="item"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> If you <a href="#h4.3.2">manually choose</a> the number of lines per page, then it will remain the same when you change "jump." The inter-line spacing (baselineskip) will change.</p>
+<p>However, if you allow <i>novel</i> to use the default number of lines per page, then it will change when "jump" is changed.</p>
+<p class="item"><b>E.</b> Note that <i>novel</i> does not use arcane settings such as <i>headsep</i>, <i>footskip</i>, or <i>headheight</i>. Those TeX internals are automatically calculated.</p>
+<p class="item" style="clear:both"><b>F.</b> The distance from the topmost baseline (whether header or main text), to the top margin, is fixed at 1 normal em. This provides adequate clearance for capital letters with upper diacritical marks.</p>
+<p>The distance from the lowermost baseline (whether main text or footer), to the lower margin, is fixed at 0.3 normal em. This provides adequate clearance for descenders.</p>
+<p class="item"><b>G.</b> When in draft mode, the <code>shademargins</code> option shades the margins in medium gray, and shades the area reserved for header/footer in light gray. This was used in the above image.</p>
+<p class="item" style="position:relative"><b>H.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> The head/foot jumps are global, and cannot be changed later in the document.</p>
+</div><!-- end 4.3.4.1 -->
+
+<h5 id="h4.3.4.2">4.3.4.2. <code>\SetHeadFont[<em>features</em>]{<em>font</em>}</code></h5>
+<div class="d5" id="d4.3.4.2">
+<p class="item"><b>A.</b> The <i>novel</i> pre-configured header/footer styles automatically use the <em>head font</em>, which is pre-defined as a variation of the parent font: scaled to slightly smaller size, using lining numbers (if available), and small caps (if available). This is a general-purpose style, widely used in fiction. It may not be the most artistic, but it is unlikely to cause visual distraction:</p>
+<p class="centerimg"><img src="html-resources/headfont-default.png" width="419" height="81" title="default head font" alt="default head font"/></p>
+<p class="item"><b>B.</b> If you would like to use something else as <i>head font</i>, use <code>\SetHeadFont</code> to define it by its font name and Open Type features.</p>
+<p>In the simplest case, you merely pick an Open Type (or TrueType) font, and <i>novel</i> automatically adds some Open Type features, including small caps:</p>
+<p class="code"><code>\SetHeadFont{Roboto}</code></p>
+<p class="centerimg"><img src="html-resources/headfont-roboto.png" width="419" height="81" title="Roboto head font" alt="Roboto head font"/></p>
+<p class="item"><b>C.</b> The above example is not best if your style has header text, because the <i>head font</i> is too pronounced, compared to the main text. A more complex example uses <i>fontspec</i> syntax to customize the Open Type Features:</p>
+<p class="code"><code>\SetHeadFont[Scale=0.75,Numbers=Lining,%<br/>
+Letters=SmallCaps,%<br/>
+Letters=UppercaseSmallCaps,%<br/>
+ItalicFont=Montserrat-ExtraLightItalic.otf]%<br/>
+{Montserrat-ExtraLight.otf}</code></p>
+<p class="centerimg"><img src="html-resources/headfont-montserrat-el.png" width="419" height="81" title="Montserrat EL head font" alt="Montserrat EL head font"/></p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> If you do <i>not</i> want SmallCaps to be automatically added, use <code>Letters=ResetAll</code> as a feature:</p>
+<p class="code"><code>\SetHeadFont[Letters=ResetAll]{\parentfontname}</code></p>
+<div style="clear:both"></div>
+</div><!-- end 4.3.4.2 -->
+
+<h5 id="h4.3.4.3">4.3.4.3. <code>\SetLooseHead{<em>number</em>}</code></h5>
+<div class="d5" id="d4.3.4.3">
+<p class="item"><b>A.</b> This command applies to both headers and footers, but its effect is most noticeable when the style has header text.</p>
+<p class="item"><b>B.</b> For best appearance of header text, its characters should be adjusted with a little extra space (tracking) between them, so that they are more easily distinguished from the main text. This is especially true if you are using small caps.</p>
+<p class="centerimg"><img src="html-resources/looseheads.png" width="400" height="76" alt="loosehead 50 and 100"/></p>
+<p class="item"><b>C.</b> The argument of <code>\SetLooseHead</code> is a number from <i>0</i> to <i>200</i>. At <i>0</i> there is no extra space between the letters. Values from <i>50</i> (default) to <i>100</i> are most useful.</p>
+<p class="item"><b>D.</b> Page number tracking will be clamped at a maximum of <i>50</i>, even when a larger (looser) tracking is applied to text.</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Do not use the <code>\textls</code> command. It is disabled in <i>novel</i>.</p>
+<div style="clear:both"></div>
+</div><!-- end 4.3.4.3 -->
+
+<h5 id="h4.3.4.4">4.3.4.4. <code>\SetPageNumberStyle{<em>code using \thepage</em>}</code></h5>
+<div class="d5" id="d4.3.4.4">
+<p class="item"><b>A.</b> By default, the page number is styled using <i>head font</i>, but without small caps (so that page roman xiv does not show as XIV).</p>
+<p class="item"><b>B.</b> If you wish to change how the page number is displayed, you can style it using <code>\SetPageNumber</code> with an argument that uses <code>\thepage</code>. Examples:</p>
+<p class="code" style="text-indent:0px"><code>\SetPageNumberStyle{\textit{\thepage}} % Page number in italics.<br/>
+\SetPageNumberStyle{-- \thepage{} --} % En-dashes, style 3 or 5.</code></p>
+<p class="item"><b>C.</b> The <i>head font</i> is applied automatically, unless you over-ride it in your code. For example, suppose you would like the page numbers (but not anything else in header/footer) to be in a different font, which you have defined in Preamble as <code>\yourpnfont</code> using <code>\NewFontFamily</code> or <code>\NewFontFace</code>. Then you could write:</p>
+<p class="code"><code>\SetPageNumberStyle{{\yourpnfont\thepage}}</code> % note double braces</p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Avoid over-doing it. If you are tempted to use a macro that counts page numbers backwards, or writes them upside-down, be aware that your print service will likely reject it. Anyway, it has already been done in fiction.</p>
+<div style="clear:both"></div>
+</div><!-- end 4.3.4.4 -->
+
+<h5 id="h4.3.4.5">4.3.4.5. <code>\SetEmblems{<em>verso</em>}{<em>recto</em>}</code></h5>
+<div class="d5" id="d4.3.4.5">
+<p class="item"><b>A.</b> If the head/foot style supports it, you may place an "emblem" that appears at a fixed distance (2.5em) from the outer margin. Thus, it will appear to the right of the page number on verso pages, and to the left of the page number on recto pages. In the case of style <i>4</i>, there will be a clearance of 1em between the emblem and the header text.</p>
+<p class="item"><b>B.</b> Emblems are minor decorations that should not distract the eye from the main text. If the style supports emblems but you do not set them, then no emblems are placed.</p>
+<p class="item"><b>C.</b> <img class="floatright" src="html-resources/emblembar.png" width="380" height="104" alt="simple emblems using vertical bar"/> Most books do not use an emblem. When they do, it is typically a vertical bar, or a bullet, like this:</p>
+<p class="code"><code>\SetHeadFootStyle{4}</code></p>
+<p class="code"><code>\SetEmblems{|}{|}</code></p>
+<p class="item"><b>D.</b> The font used for emblems will be the same as the <i>head font</i>, unless you specifically code the emblem to use a different font, or unless you use one of the built-in <code>\decoglyph</code> codes.</p>
+<p class="item"><b>E.</b> The verso and recto emblems may be different. If you set one side, you must also set the other. Blanks are allowed.</p>
+<p class="item"><b>F.</b> <img class="floatright" src="html-resources/emblemdingbats.png" width="380" height="104" alt="dingbat emblems"/> Emblems may be styled. For example, the header emblems shown at right were produced using the code below. Dingbats from the NovelDeco font were specified, adjusted for size and position.</p>
+<p style="clear:both" class="code"><code>\SetEmblems{\charscale{1.1}{\raisebox{-0.05em}{\decoglyph{l9825}}}}%</code></p>
+<p class="code"><code>{\charscale{1.1}{\raisebox{-0.05em}{\decoglyph{l9826}}}}</code></p>
+<div style="clear:both"></div>
+<p class="item"><b>G.</b> You may also use images, or combined images and text. If you use images, they must be at the exact resolution required by your print service (typically 300dpi for gray, 800dpi for b/w), and at exact size without scaling. The <code><a href="#h7.2.2">\InlineImage</a></code> command must be used. You may find that a vertical offset of <code>\nfs</code> (normal font size) is useful, as this will place the top of the emblem image at the top margin.</p>
+<p class="code" style="text-indent:0px"><img class="floatright" src="html-resources/emblemimg.png" width="295" height="77" alt="emblem image"/>
+<code>\SetHeadFootStyle{4}<br/>
+\SetEmblems{\InlineImage[0pt,b]{spy.png}}%<br/>
+{\InlineImage[0pt,b]{spy.png}}
+</code></p>
+<p class="item" style="position:relative"><b>H.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> At the small size of an emblem, it is difficult to use detailed artwork. A black/white image at 800dpi will print similarly to a font dingbat. Grayscale at 300dpi will probably not be satisfactory unless the emblem is a single shade of gray. For the above example, a character from the <i>Fontawesome</i> font was converted to a png image at mid-gray. It is less distracting than a black character from the font, but hard to discern. Note that "gray ink" will not be used for your book.</p>
+<p>Ask your print service whether the presence of a small image in each page header will affect production costs. Probably not, but if there is a different per-page charge when pages have an image... Oops!</p>
+<p class="item" style="position:relative"><b>I.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> The layout calculation does not care whether emblems intrude into the margins. You will have to inspect your PDF to determine whether a header emblem is too tall, or a footer emblem too deep, for the allowed top and bottom margin clearance. Class option <i>shademargins</i> (in draft mode only) is helpful.</p>
+<div style="clear:both"></div>
+</div><!-- end 4.3.4.5 -->
+
+<h5 id="h4.3.4.6">4.3.4.6. Setting and Changing Header Text</h5>
+<div class="d5" id="d4.3.4.6">
+<p class="item"><b>A.</b> If you are using <a href="#h4.3.3.1">head/foot style</a> <i>1</i>, <i>4</i>, <i>5</i>, or <i>6</i>, it has text in the header. By default, that text is the author on verso pages, the title on recto pages. That is an accepted design for fiction, but it is not always the appropriate thing to do.</p>
+<p>For example, in exotic cases you may use something such as <code>\SetTitle{ISBN9780123456789TEXTBLOCK}</code>, instead of the book's actual title, if required for the printer's database. Obviously you do not want that to appear in page headings!</p>
+<p class="item"><b>B.</b> Header text may be changed to whatever you wish (as long as it fits):</p>
+<p class="code"><code>\SetVersoHeadText{<em>text</em>}</code><br/>
+<code>\SetRectoHeadText{<em>text</em>}</code></p>
+<p class="item"><b>C.</b> These commands can be used <i>both</i> in Preamble <i>and</i> in the document body. Whatever you set will take effect immediately (for pages that have header text) and remain in effect until changed by repeating these commands. For example, you might want to do that for a collection of short stories, or if your book has a Preface.</p>
+<p class="item"><b>D.</b> You may use ordinary LaTeX styling commands for the text:</p>
+<p class="code"><code>\SetRectoHeadText{The \emph{Bad Boy} Chronicles}</code></p>
+<p>You may also do more complicated things, such as setting certain words in a font other than the <i>head font</i>. This is not advised, because you do not want to distract the reader from the main text; but it can be done.</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Avoid bold. Avoid underline. Really. Don't do it. No, no, no!</p>
+</div><!-- end 4.3.4.6 -->
+</div><!-- end 4.3.4 -->
+
+<h4 id="h4.3.5">4.3.5. Header/Footer Exceptional Pages</h4>
+<div class="d4" id="d4.3.5">
+<p class="noindent">There are a number of cases where a specific page must have a header/footer style that appears to differ from the global style. The key words are "appears to differ." The global header/footer is always there, in terms of vertical space. But either or both may be blank, or have unusual content, on certain pages.</p>
+
+<h5 id="h4.3.5.1">4.3.5.1. <code>\thispagestyle{<em>choice</em>}</code></h5>
+<div class="d5" id="d4.3.5.1">
+<p class="item"><b>A.</b> Command <code>\thispagestyle</code> is used in the document body, not Preamble. It changes the appearance of header/footer, only for the page on which the command appears. Ideally the command is used immediately after <code>\clearpage</code> or <code>\cleartorecto</code>, so that the applicable page is certain.</p>
+<p class="item"><b>B.</b> The command will be effective if used anywhere on a page, as long as you are certain <i>which</i> page is current. So, if you know that a particular portion of text runs exactly two pages before <code>\clearpage</code>, you can use <code>\thispagestyle</code> at the beginning and end of the text, so that it applies to both pages.</p>
+<p class="item"><b>C.</b> The choice of page style is <i>not</i> one of the numbered global head/foot styles. Instead, choose from the following list. These are more versatile than the choices available in other TeX document classes. They are: <i>fancy</i>, <i>empty</i>, <i>footer</i>, <i>forcenumber</i>, <i>dropfoliobeneath</i>, and <i>dropfolioinside</i>. If you choose <i>plain</i>, you will get <i>footer</i>, but that might not be what you want.</p>
+<p class="overhang"><code><b>\thispagestyle{fancy}</b></code><br/>
+This applies the default (fancy) page style, so it is not normally needed. Only use this command to over-ride some other <code>\thispagestyle</code> command, or to over-ride the <code>\SetChapterStartStyle</code> setting.</p>
+<p class="overhang"><code><b>\thispagestyle{empty}</b></code><br/>
+Header and footer are both blank.</p>
+<p class="overhang"><code><b>\thispagestyle{footer}</b></code><br/>
+Ignored if the style has no footer. If it does, then the usual footer appears. Note that this does <i>not</i> cause a page number to appear, when the style has no footer. Header, if any, is blank.</p>
+<p class="overhang"><code><b>\thispagestyle{forcenumber}</b></code><br/>
+If the style has a footer, then it appears as usual, and the header (if any) is blank. If the style has a header but no footer, then the outside portion of the header (which is presumed to contain the page number and emblem) appears, but the text portion of the header is blank.<br/>
+&bull; The <i>forcenumber</i> choice is non-standard. Use it only if you must have a page number, and no other choice is suitable.</p>
+<p class="overhang"><code><b>\thispagestyle{dropfoliobeneath}</b></code><br/>
+In this context, "folio" means page number. The header (if any) is blank. If there is a footer, then it appears as usual. But if there is no footer, this command creates a one-page fake footer, which contains the centered page number. The fake footer is located where the next line of text would be, if the textblock were one line longer than its actual value.<br/>
+&bull; For the fake footer to be acceptable in print, the bottom margin must be wider than the minimum amount required by your print service. For example, suppose that the minimum bottom margin is 0.5in, but you set the bottom margin to 0.75in. That gives you 0.25in wiggle room, into which the fake footer will probably fit, because typical baselineskip is 0.2in to 0.25in.<br/>
+&bull; The document class does not know whether or not you have extra space available in the bottom margin. It is your responsibility to know.</p>
+<p class="overhang">&nbsp; <code><b>\thispagestyle{dropfolioinside}</b></code><br/>
+In this context, "folio" means page number. The header (if any) is blank. If there is a footer, then it appears as usual. But if there is no footer, this commands temporarily reduces the number of lines per page by one. At the bottom, where the last line of text would normally be, the page number is centered. Thus, there is no intrusion into the bottom margin.<br/>
+&bull; This command may only be used following <code>\clearpage</code>. Thus, it may be used at the start of new chapters, or on pages that do not flow from a previous page. If you use it elsewhere, the print will have incorrect layout, but there will be no error or warning, since the compiler is not sure what you are trying to do.<br/>
+&bull; If used on a page with <i>ChapterStart</i> environment, you must place <code>\thispagestyle{dropfolioinside}</code> <em>before</em> <code>\begin{ChapterStart}</code>. Reason: The <i>ChapterStart</i> block has a disposable blank line at its top, which is removed when <i>dropfolioinside</i> is used (instead of removing a line from the following text block).<br/>
+&bull; With this style, the specified height of <i>ChapterStart</i> must be <i>4</i> or more. This command will reduce it to 3 or more.</p>
+<div style="clear:both"></div>
+</div><!-- end 4.3.5.1 -->
+
+<h5 id="h4.3.5.2">4.3.5.2. <code>\SetChapterStartStyle{<em>choice</em>}</code></h5>
+<div class="d5" id="d4.3.5.2">
+<p class="item"><b>A.</b> The first page of each chapter, or of a section that is styled like a chapter, is usually an exception to the global page style.</p>
+<p class="item"><b>B.</b> In Preamble, <code>\SetChapterStartStyle</code> sets the default <code>thispagestyle</code> that will be applied on pages with the <i>ChapterStart</i> environment. You may still over-ride locally.</p>
+<p class="item"><b>B.</b> The choices are the same as available for <code>\thispagestyle</code>. Default is <i>footer</i>.</p>
+</div><!-- end 4.3.5.2 -->
+</div><!-- end 4.3.5 -->
+</div><!-- end 4.3 -->
+
+
+</div><!-- end 4 -->
+</div><!-- end page04 -->
+<!-- ************************************************************ -->
+<div id="page05" class="page">
+
+
+<h2 id="h5">5. Chapters and Chapter-Like Sections</h2>
+<div class="d2" id="d5">
+<p class="noindent">This section describes how chapters are designed. The <i>novel</i> class has commands specifically for this purpose. Do not use the ordinary TeX <code>\chapter</code> command, or any other TeX partitioning such as <code>\section</code>.</p>
+<p>This also applies to content that is styled like a chapter, regardless of what it is called or where it appears. For example, if your book's front matter has a Preface, it is probably styled like a chapter. Something such as Acknowledgements might or might not be styled like a chapter, depending on length. Advice can be found in <a href="#h8">section 8</a> of this documentation, regarding Book Design.</p>
+
+<h3 id="h5.1">5.1. Starting a Chapter</h3>
+<div class="d3" id="d5.1">
+<p class="noindent">Unlike most other TeX document classes, <i>novel</i> does <i>not</i> honor the <code>\chapter</code> command. And, <i>novel</i> does <i>not</i> automatically start chapters on a new page.</p>
+
+<h4 id="h5.1.1">5.1.1. <code>\clearpage</code> or <code>\cleartorecto</code></h4>
+<div class="d4" id="d5.1.1">
+<p class="item"><b>A.</b> Unless your chapters run continuously without page break, begin a new chapter using <code>\clearpage</code> or <code>\cleartorecto</code>. The first of these provides a new page, which will be verso or recto, without skipping a page. The second forces the chapter to begin on a recto page, if necessary inserting a blank verso.</p>
+<p class="item"><b>B.</b> The common modern practice in fiction is to allow new chapters to begin either verso or recto, once you get past Chapter One. The only recent book I've read (from a major publisher), where chapters always started recto, had about 20 blank pages throughout the story. I believe the reason was to pad the book, so that it looked bigger. If you are using an American P.O.D. service, such padding might knock about $0.10 (estimated) from your profit, for each copy sold. So it's up to you to think about the tradeoffs between style, profit per book, and expected sales.</p>
+<p class="item"><b>C.</b> Prologue (if any), Chapter One, Epilogue (if any), and other special sections always begin recto.</p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Don't worry about using <code>\clearpage</code> or <code>\cleartorecto</code> twice. The compiler is smart enough to understand that you only meant to do it once, as long as there is no other code in between.</p>
+</div><!-- end 5.1.1 -->
+
+<h4 id="h5.1.2">5.1.2. ChapterStart Environment</h4>
+<div class="d4" id="d5.1.2">
+<p class="item"><b>A.</b> The ChapterStart environment creates a block of white space, with a fixed height (number of normal lines). If you do not place much inside it, or even if you place nothing inside it, the space is the same.</p>
+<p class="item"><b>B.</b> If you place too much inside it, the space does not grow. Instead, the excess material overflows the bottom of the environment. There, the excess will underlie the main text. This is usually undesirable, but can sometimes be used for special effects.</p>
+
+<h5 id="h5.1.2.1">5.1.2.1. <code>\SetChapterStartStyle{<em>choice</em>}</code></h5>
+<div class="d5" id="d5.1.2.1">
+<p class="item"><b>A.</b> This command may be used in Preamble. Its default setting is <i>footer</i>.</p>
+<p class="item"><b>B.</b> In most cases, a <i>ChapterStart</i> page has a head/foot style that differs from the global default. Instead of writing <code><a href="#h4.3.5.1">\thispagestyle</a></code> commands for every chapter, use <code>\SetChapterStartStyle</code> to pick a style that will be applied wherever <i>ChapterStart</i> is used. The available choices are: fancy, footer, empty, dropfoliobeneath, dropfolioinside, forcenumber.</p>
+<p class="item"><b>C.</b> Regardless of this setting, you can over-ride the style on a per-chapter basis, via an optional argument at the beginning of the <i>ChapterStart</i> environment.</p>
+</div><!-- end 5.1.2.1 -->
+
+<h5 id="h5.1.2.2">5.1.2.2. <code>\SetChapterStartHeight{<em>lines</em>}</code></h5>
+<div class="d5" id="d5.1.2.2">
+<p class="item"><b>A.</b> This command may be used in Preamble. Its default setting is <i>10</i>.</p>
+<p class="item"><b>B.</b> This command sets the default height of the <i>ChapterStart</i> environment, measured as an integer number of normal lines. The smallest value is <i>3</i>.</p>
+<p class="item"><b>C.</b> However, if the chapter also uses <i>dropfolioinside</i>, then the smallest value is <i>4</i>, because one line is lost when processing the <i>dropfolioinside</i> command.</p>
+<p class="item"><b>D.</b> Regardless of this setting, you can over-ride the height on a per-chapter basis, via an optional argument at the beginning of the <i>ChapterStart</i> environment.</p>
+</div><!-- end 5.1.2.2 -->
+
+<h5 id="h5.1.2.3">5.1.2.3. <code>\begin{ChapterStart}[<em>lines</em>][<em>style</em>]</code></h5>
+<div class="d5" id="d5.1.2.3">
+<p class="item"><b>A.</b> The <i>ChapterStart</i> environment takes up to two optional arguments.</p>
+<p class="item"><b>B.</b> The first optional argument over-rides the default height of <i>ChapterStart</i>, for just this chapter. Its smallest value is <i>3</i>, except that its smallest value is <i>4</i> when <i>dropfolioinside</i> is used.</p>
+<p class="item"><b>C.</b> The second optional argument over-rides the header/footer style, for just this chapter. If you use the second optional argument, it must be one of the allowed choices for <code>\thispagestyle</code>, namely: fancy, footer, empty, dropfoliobeneath, dropfolioinside, forcenumber.</p>
+<p class="item"><b>D.</b> To use the second argument without the first, place an asterisk: <code>[*][<em>style</em>]</code></p>
+<p class="item"><b>E.</b> Whatever you place within <i>ChapterStart</i> will probably be higher on the page than you would like. To move it down, use the <code>\vspace*{<em>length</em>}</code> command (with asterisk) immediately after the environment begins.</p>
+<p>As with all environments, this one must be closed using <code>\end{ChapterStart}</code>.</p>
+</div><!-- end 5.1.2.3 -->
+</div><!-- end 5.1.2 -->
+
+<h4 id="h5.1.3">5.1.3. Chapter Title, Subtitle, Deco, Epigraph</h4>
+<div class="d4" id="d5.1.3">
+<p class="noindent">You can put anything you like within <i>ChapterStart</i>, including ordinary text and even images. All <i>ChapterStart</i> does is reserve a fixed space. However, there are special commands that make it easy to place a chapter title, chapter subtitle, and decorative element.</p>
+
+<h5 id="h5.1.3.1">5.1.3.1. <code>\SetChapterFont[<em>features</em>]{<em>font</em>}</code><br/>
+<span class="dbloc">5.1.3.1 &nbsp; </span><code>\SetSubchFont[<em>features</em>]{<em>font</em>}</code></h5>
+<div class="d5" id="d5.1.3.1">
+<p class="item"><b>A.</b> These global commands may be used in Preamble. They create font commands <code>\chapterfont</code> and <code>\subchfont</code> that may be used to style text anywhere in your document, like this:</p>
+<p class="code"><code>{\chapterfont <em>text</em>}<br/>
+{\subchfont <em>text</em>}</code></p>
+<p class="item"><b>B.</b> The <i>chapter font</i> is automatically applied to text in <code>\ChapterTitle</code> commands.</p>
+<p class="item"><b>C.</b> The <i>subch</i> font is automatically applied to text in chapter subtitles (see below).</p>
+<p class="item"><b>D.</b> These fonts are pre-configured, based on the document's parent font. They have TeX ligatures and kerning, and use Lining numbers instead of Old Style. The <i>chapter font</i> is scaled at 1.6, and the <i>subch font</i> is scaled at 1.2, compared to normal font size. Ordinary (common) ligatures are not used, because such ligatures are best avoided with enlarged text.</p>
+<p class="item"><b>E.</b> If you don't like the pre-configured fonts, then you may specify your own, using <i>fontspec</i> syntax. Here is what the default codes look like:</p>
+<p class="code"><code>\SetChapterFont[Numbers=Lining,Scale=1.6]{\parentfont}<br/>
+\SetSubchFont[Numbers=Lining,Scale=1.2]{\parentfont}</code></p>
+</div><!-- end 5.1.3.1 -->
+
+<h5 id="h5.1.3.2">5.1.3.2. <code>\ChapterTitle[<em>alignment</em>]{<em>text</em>}</code><br/>
+<span class="dbloc">5.1.3.2. &nbsp; </span><code>\ChapterSubtitle[<em>alignment</em>]{<em>text</em>}</code></h5>
+<div class="d5" id="d5.1.3.2">
+<p class="item"><b>A.</b> Text within <code>\ChapterTitle</code> is styled using the <i>chapter font</i>, and text within <code>\ChapterSubtitle</code> is automatically styled using the <i>subch font</i>.</p>
+<p class="item"><b>B.</b> You can locally over-ride these fonts, using font commands in the text.</p>
+<p class="item"><b>C.</b> The optional <i>alignment</i> controls how the element is horizontally placed. Choices are <i>l</i>, <i>c</i>, <i>r</i> (left, center, right). Default <i>c</i>.</p>
+<p class="item"><b>D.</b> You don't have to use either of these commands. Or, you can use either of them more than once! All these commands do is style the text. They do not have any meaning that is controlled by other macros.</p>
+<p class="item"><b>E.</b> The styled text is limited to one line (no wrap) per command. If you have a long chapter title or subtitle, then break it into pieces of manageable size, by repeating the command(s). Example:</p>
+<p class="code"><img class="floatright" src="html-resources/chaptertitlesubtitle.png" width="338" height="179" title="chapter title and subtitle, left aligned" alt="chapter title and subtitle, left aligned"/>
+<code><small>
+\begin{ChapterStart}<br/>
+\vspace{2<span style="cursor:help" title="normal baseline skip">\nbs</span>}<br/>
+\ChapterTitle[l]{XV}<br/>
+\vspace{<span style="cursor:help" title="normal baseline skip">\nbs</span>}<br/>
+\ChapterSubtitle[l]{In which Lord Withens, returned from his quest,}<br/>
+\ChapterSubtitle[l]{encounters an Army of Gnomes at his castle gate.}<br/>
+\end{\ChapterStart}<br/>
+Following the dark and stormy night, it was a bright and sunny day. That did nothing to improve the demeanor of Lord Withens, who was still soaked from riding through the rain. ...\par
+</small></code></p>
+</div><!-- end 5.1.3.2 -->
+
+<h5 id="h5.1.3.3">5.1.3.3. <code>\ChapterDeco[<em>alignment scale</em>]{<em>text</em>}</code></h5>
+<div class="d5" id="d5.1.3.3">
+<p class="item"><b>A.</b> This command is simply a way for you to remember that its content is neither the title nor subtitle of the chapter. Typical usage is to place a decorative element.</p>
+<p class="item"><b>B.</b> There is a single command option, which is parsed for a letter and/or a number, with our without comma or space. The <i>alignment</i> letter is one of <i>l</i>, <i>c</i>, <i>r</i> (left, center, right). Default <i>c</i>. The numerical <i>scale</i> (may be decimal) changes the size of the text, and tweaks its vertical position. Default scale is <i>1</i>.</p>
+<p class="item"><b>C.</b> For your convenience, the <i>NovelDeco</i> font (included with <i>novel</i> has a few possibilities. they are accessed via the <code>\decoglyph</code> command. The list of available decorations, and codes to access them, are in the file <i>NovelDeco-glyphs.pdf</i>, which is in the <i>extras</i> folder within this documentation. Note that the decorations can be placed anywhere in your document, not just in <code>\ChapterDeco</code>.</p>
+<p class="item"><b>D.</b> <img class="floatright" src="html-resources/lowdown.png" width="300" height="141" title="chapter title with decoration" alt="chapter title with decoration"/>Most of the <code>\decoglyph</code> decorations look best when the optional <i>scale</i> is near <i>4</i>. Example:</p>
+<p class="code"><code><small>
+\begin{ChapterStart}[8]<br/>
+\vspace{2<span style="cursor:help" title="normal baseline skip">\nbs</span>}<br/>
+\ChapterTitle[l]{3}<br/>
+\ChapterSubtitle[l]{The Low-Down}<br/>
+\ChapterDeco[l4]{\decoglyph{n9591}\decoglyph{r9656}}<br/>
+\end{ChapterStart}<br/>
+I didn't hear the low-down until the following Saturday. By then, all hell had broken loose at Vinny's joint, and the boys were looking for me in trash cans, just in case that was where I was hiding, or maybe dead. ...\par
+</small></code></p>
+</div><!-- end 5.1.3.3 -->
+
+<h5 id="h5.1.3.4">5.1.3.4. Chapter Epigraph</h5>
+<div class="d5" id="d5.1.3.4">
+<p class="item"><b>A.</b> If you would like to place an Epigraph within <i>ChapterStart</i>, there is no special command for that purpose. You do it the same way you would do it anywhere else: Use the <i>adjustwidth</i> environment to limit the text width. You may use the <i>parascale</i> environment to scale the block of text, without disturbing the following line grid, as long as you are within <i>ChapterStart</i>.</p>
+<p class="item"><b>B.</b> <b>Example:</b></p>
+<p class="code"><img class="floatright" src="html-resources/bookofbeirh.png" width="344" height="191" title="chapter title with epigraph" alt="chapter title with epigraph"/><code><small>
+\begin{ChapterStart}<br/>
+\vspace{2<span style="cursor:help" title="normal baseline skip">\nbs</span>}<br/>
+\ChapterTitle{16. The Great Incantation}<br/>
+\vspace{<span style="cursor:help" title="normal baseline skip">\nbs</span>}<br/>
+\begin{adjustwidth}{4em}{4em}<br/>
+\begin{parascale}[0.88]<br/>
+In the third moon of the third raveling, in the third hour of the third day, Fingly shall come again.\par<br/>
+\stake\hfill \textit{Book of Beirh}\par<br/>
+\end{parascale}<br/>
+\end{adjustwidth}<br/>
+\end{ChapterStart}<br/>
+In the latter days of the Dorf dynasty, a marvelous apparition sent the King's guard scrambling in terror. Elders soon declared that it was the return of Fingly, prophesized in the Book of Beirh. ...\par
+</small></code></p>
+<p class="item" style="position:relative"><b>C.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> It is not necessary to load the <i>epigraph</i> package. Simply construct your own style of epigraph using other methods. But if you do load <i>epigraph</i>: Only use <code>\epigraph</code>, or the <code>epigraphs</code> environment, within the ChapterStart environment, or on a display page. Commands <code>\epigraphhead</code>, <code>\dropchapter</code>, <code>\undocrop</code> do not work in <i>novel</i>. The <code>\cleartoevenpage[<i>option</i>]</code> command does work. Ignore the material regarding epigraphs on part pages or in bibliographies.</p>
+</div><!-- end 5.1.3.4 -->
+</div><!-- end 5.1.3 -->
+
+<h4 id="h5.1.4">5.1.4. ChapterStart With Image</h4>
+<div class="d4" id="d5.1.4">
+<p class="item"><b>A.</b> You can use an image in chapter titles. If you place an image, use one of the image commands defined by <i>novel</i> elsewhere in the documentation.</p>
+<p class="item"><b>B.</b> Be sure that you are licensed to use the image. Many clipart catalogs "for personal use only," prohibit usage in commercial books. One possible source is <a href="http://openclipart.org" rel="external" target="new">openclipart.org</a> (note the <em>.org</em>).</p>
+
+<h5 id="h5.1.4.1">5.1.4.1. Text Over Inline Image</h5>
+<div class="d5" id="d5.1.4.1">
+<p class="item"><b>A.</b> <img class="floatright" src="html-resources/ctimg35.png" width="79" height="196" alt="example of chapter title image, text over"/> You may position text over an <code><a href="#h7.2.2">\InlineImage</a></code>. You must use black text, or grayscale text that is much darker than the underlying image.</p>
+<p class="item"><b>B.</b> <b>Example:</b> Here, the command <code>\unifrac</code> calls for the font <i>UnifrakturMaguntia.ttf</i>. Note that the font command is <i>outside</i> \charscale:</p>
+<p class="code"><code><small>\begin{ChapterStart}<br/>
+\FloatImage{sword.png} <span class="ap">% centered by default</span><br/>
+{\unifrak\centering\charscale[3,0pt,4<span style="cursor:help" title="normal baseline skip">\nbs</span>]{35}\par}<br/>
+</small>\end{ChapterStart}</code></p>
+</div><!-- end 5.1.4.1 -->
+
+<h5 id="h5.1.4.2">5.1.4.2. Text Built Into Image</h5>
+<div class="d5" id="d5.1.4.2">
+<p class="item"><b>A.</b> If the text is not much darker than the background image, then it is better to include the text as part of the raster image. The reason is that "white ink" will not be used for your book. Also, you cannot use image transparency.</p>
+<p class="item"><b>B.</b> <b>Example:</b> The number is built into the image itself.</p>
+<p class="code"><img class="floatright" src="html-resources/smfingerprint8.png" width="86" height="70" alt="example of chapter title image, raster text"/><code><small>\begin{ChapterStart}<br/>
+\FloatImage[l]{smfingerprint8.png}<br/>
+\end{ChapterStart}</small></code></p>
+</div><!-- end 5.1.4.2 -->
+</div><!-- end 5.1.4 -->
+</div><!-- end 5.1 -->
+
+<h3 id="h5.2">5.2. Continuously Running Chapters</h3>
+<div class="d3" id="d5.2">
+<p class="noindent">Standard book design calls for each chapter to begin on a new page. However, some books are designed with numerous short chapters that run continously, so that chapters may start anywhere on a page. There are two ways to handle this in <i>novel</i>, or you can simply design your own method.</p>
+
+<h4 id="h5.2.1">5.2.1. Reduced-Height ChapterStart</h4>
+<div class="d4" id="d5.2.1">
+<p class="item"><b>A.</b> Since the <i>ChapterStart</i> environment does not automatically begin a new page, you can use it for continuously running chapters. In Preamble, set a short height, such as <code>\SetChapterStartHeight{4}</code>. Also use <code>\SetChapterStartStyle{fancy}</code> so that headers don't disappear.</p>
+<p class="item"><b>B.</b> Throughout the book, you can make local adjustments to the <i>ChapterStart</i> height, so that they don't fall at an inconvenient location (such as at the bottom of a page). Yes, I have seen this done in published works. If a particular chapter is sufficiently important that it deserves a page break, or a lot more space, you can do that easily.</p>
+</div><!-- end 5.2.1 -->
+
+<h4 id="h5.2.2">5.2.2. <code>\QuickChapter[<em>linelength</em>]{<em>chapter title</em>}</code></h4>
+<div class="d4" id="d5.2.2">
+<p class="item"><b>A.</b> The <code>\QuickChapter</code> command inserts two blank lines. In the gap, the chapter title is left-justified using <i>subch font</i> (not <i>chapter font</i>). It is slightly raised from the normal baseline, because this looks better; but the following text is back on-grid. By default, the start of the following text will be un-indented.</p>
+<p class="item"><b>B.</b> If the optional <i>linelength</i> is provided, then a dash will be written after the title, at the position and thickness typical of the em dash in <i>subch font</i>. If <i>linelength</i> is specified in units of length, then that will be the length of the line. But if <i>linelength</i> is an asterisk, then the line will fill to the right margin.</p>
+<p class="item"><b>C.</b> <code>\QuickChapter</code> is probably too obtrusive, for mere scene changes within a chapter.</p>
+<p class="item"><b>D.</b> <b>Example:</b></p>
+<p class="code"><code><small>Then he looked at me with a sneer, and barked, &ldquo;You better haul your can over to Vinny's joint, before the Boss finds out.&rdquo;\par<br/>
+\QuickChapter[3em]{16. At Vinny&rsquo;s}<br/>
+So I took his advice, and hauled my can over to Vinny&rsquo;s. It was everything I had expected, and worse.\par<br/>
+The bouncer wasn't the biggest one I&rsquo;d ever seen, but he was the ugliest. ...</small></code></p>
+<p class="centerimg"><img src="html-resources/quickchapter.png" width="629" height="240" alt="quick chapter"/></p>
+</div><!-- end 5.2.2 -->
+</div><!-- end 5.2 -->
+
+<h3 id="h5.3">5.3. Scene Breaks</h3>
+<div class="d3" id="d5.3">
+<p class="item"><b>A.</b> There are several commands dedicated to the purpose of scene breaks.</p>
+<p class="code"><code><b>\scenebreak</b></code> inserts a one-line blank skip. The following line of text is not indented.</p>
+<p class="code"><code><b>\sceneline</b></code> inserts a one-line skip, containing a short centered line. The following line of text is not indented.</p>
+<p class="code"><code><b>\scenestars</b></code> inserts a one-line skip, containing three spaced, centered asterisks. The following line of text is not indented.</p>
+<p class="item"><b>B.</b> <b>Examples:</b></p>
+<p class="code"><img style="float:right; margin-left:16px;" src="html-resources/scenebreaks.png" width="331" height="236" alt="scene breaks"/>
+<code><small>
+\noindent It was a dark and stormy night.\par<br/>
+Lord Withens, the last of his line, hurried through the gloom to Castle McWhistle, where Lady McWhistle awaited.\par<br/>
+\scenebreak<br/>
+Well, maybe it was not very dark.\par<br/>
+But to Lord Withens, it seemed dark enough. Or rather, he hoped it was dark enough. Lord McWhistle was suspicious.\par<br/>
+\sceneline<br/>
+Actually, it was not all that stormy, either. But the Withens clan never tolerated drizzle, much less a storm.\par<br/>
+Who could blame them? It's not like they lived in Italy.\par<br/>
+\scenestars<br/>
+Ah, such ill fortune haunted the Withens!\par<br/>
+Unfortunately, novelists of that era had so little to write about, or they would have chosen another family to pursue.\par
+</small></code></p>
+<p class="item"><b>C.</b> From version 1.52, a badly-placed scene break will be detected, and a Warning message will be issued.</p>
+<p>If <code>\scenebreak</code> is positioned at the very top or bottom of a page, then the Warning will advise you to substitute it with either <code>\scenestars</code> or <code>\sceneline</code>. The substitution is not automatic.</p>
+<p>If any of <code>scenebreak</code>, <code>\sceneline</code>, or <code>\scenestars</code> appears just one line away from the top or bottom of a page, you will get a Warning.</p>
+
+<h4 id="h5.3.1">5.3.1. <code>\SetScenebreakIndent{<em>true</em> or <em>false</em>}</code></h4>
+<div class="d4" id="d5.3.1">
+<p class="noindent">This global command may only be used in the Preamble. Default is <i>false</i>.</p>
+<p>Normally, text begins without a paragraph indent, after each scene break. This is standard in fiction. If you prefer that each new scene begins indented, use this command. It works only with <code>\scenebreak</code>, <code>\sceneline</code>, and <code>\scenestars</code>.</p>
+</div><!-- end 5.3.1 -->
+</div><!-- end 5.3 -->
+
+<h3 id="h5.4">5.4. Automatic Chapter Numbering</h3>
+<div class="d3" id="d5.4">
+<p class="noindent">By popular demand, here is how to add automatic chapter numbering, even though it is easier to just type <i>Chapter One</i> or whatever you need:</p>
+<p class="item"><b>A.</b> Counter <i>novelcn</i> is pre-defined, and initialized to <i>1</i> (not zero). If you simply wish to print its value as a number, then increment the count, do something like this:</p>
+<p class="code"><code>
+\ChapterTitle{Chapter \the\value{novelcn}\stepcounter{novelcn}}
+</code></p>
+<p>That will print Chapter 1, Chapter 2, and so forth. Of course, only do this for real, numbered chapters, not for "chapter-like" sections. If your book has several parts, and each part re-sets its own chapter count, use \setcounter{novelcn}{1} prior to the first chapter in each part.</p>
+<p class="item"><b>B.</b> If you would like the number to be spelled out, as in Chapter One, Chapter Two, and so forth, then try the <i>fmtcount</i> package. It can also do ordinals such as First Chapter, Second Chapter. See the <i>fmtcount</i> package documentation for details.</p>
+<p class="item"><b>C.</b> If your document's language is other than English, use <code>\setdefaultlanguage</code> <i>before</i> you load the <i>fmtcount</i> package. If you do it later, then positioning will be incorrect.</p>
+<p class="item"><b>D.</b> <b>Example:</b> With <i>fmtcount</i> loaded in Preamble.</p>
+<p class="code"><code>
+% if necessary, use \setdefaultlanguage first.<br/>
+\RequirePackage{fmtcount}<br/>
+</code></p>
+<p>Example usage in chapter titles:</p>
+<p class="code"><code>
+\ChapterTitle{\Ordinalstring{novelcn}\stepcounter{novelcn} Robbery} %1<br/>
+\ChapterTitle{\Ordinalstring{novelcn}\stepcounter{novelcn} Robbery} %2<br/>
+\ChapterTitle{\Ordinalstring{novelcn}\stepcounter{novelcn} Robbery} %3
+</code></p>
+<p class="centerimg"><img src="html-resources/robberies.png" width="411" height="98" title="odinal chapter numbering" alt="ordinal chapter numbering"/></p>
+</div><!-- end 5.4 -->
+
+<h3 id="h5.5">5.5. First Lines and Drop Caps</h3>
+<div class="d3" id="d5.5">
+<p class="noindent">The first line of chapter text is often treated with a style of its own. Often, all or part of the first line is in small caps. The first letter may be larger than the rest. Or, the first letter may occupy several lines (sometimes using an image). This last effect is known as <i>drop cap</i> (French <i>lettrine</i>).</p>
+
+<h4 id="h5.5.1">5.5.1. First Character Special</h4>
+<div class="d4" id="d5.5.1">
+<p class="item"><b>A.</b> Use the <code>\charscale</code> command to size the first letter (or more than one letter) so that it stands above the remainder of the line. Remember that you will see a capital letter standing next to lowercase letters, so it will appear taller. You may also use a font command.</p>
+<p class="item"><b>B.</b> <b>Example:</b> Where <code>\NewFontFace\alexbrush{AlexBrush-Regular.ttf}</code> appears in Preamble.</p>
+<p class="code"><code>
+\noindent\charscale[1.6]{\alexbrush I}\hspace{0.2em}t was a dark and stormy night. Well, it really wasn't all that dark, seeing as how this story is set in Las Vegas.
+</code></p>
+<p class="centerimg"><img src="html-resources/firstletterspecial.png" width="680" height="83" alt="first letter special" title="first letter special"/></p>
+</div><!-- end 5.5.1 -->
+
+<h4 id="h5.5.2">5.5.2. First Line Small Caps</h4>
+<div class="d4" id="d5.5.2">
+<p class="item"><b>A.</b> If you want to place a portion of the first line in small caps, then simply do it using <code>\textsc{text}</code>. This effect can also continue to additional lines. That is, it does not automatically stop at the end of the first line.</p>
+<p class="item"><b>B.</b> The <i>magaz</i> package is pre-loaded in <i>novel</i>. It provides the <code>\FirstLine</code> command, which takes the entire first paragraph as its argument. Place <code>\noindent</code> inside. You may also style the first letter (or more than one) as described above; the styled letter appears inside the <code>\FirstLine</code> command.</p>
+<p class="item"><b>C.</b> <b>Example:</b></p>
+<p class="code"><code>
+\FirstLine{\noindent\charscale[1.6]{\alexbrush I}\hspace{0.2em}t was a dark and stormy night. Well, it really wasn't all that dark, seeing as how this story is set in Las Vegas.}
+</code></p>
+<p class="centerimg"><img src="html-resources/firstlinespecial.png" width="682" height="84" alt="first line small caps" title="first line small caps"/></p>
+</div><!-- end 5.5.2 -->
+
+<h4 id="h5.5.3">5.5.3. Drop Caps</h4>
+<div class="d4" id="d5.5.3">
+<p class="item"><b>A.</b> The <i>drop cap</i> is an enlarged letter (or image) at the beginning of chapter text, with the first few lines of text wrapped around it:</p>
+<p class="centerimg"><img src="html-resources/dropcap.png" width="431" height="112" title="drop cap" alt="drop cap"/></p>
+<p class="item"><b>B.</b> Works of popular fiction rarely use drop caps. Instead, having a special first character (<a href="#h5.5.1">section 5.5.1</a>) is more common, as it presents fewer layout problems, and is less distracting.</p>
+<p class="item" style="position:relative"><b>C.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> The <code>\dropcap</code> command is native to <i>novel</i>. You may also load and use <i>lettrine</i>. An extensive discussion of drop caps is in <a href="#hF">Appendix F</a>.</p>
+</div><!-- end 5.5.3 -->
+</div><!-- end 5.5 -->
+
+
+</div><!-- end 5 -->
+</div><!-- end page05 -->
+<!-- ************************************************************ -->
+<div id="page06" class="page">
+
+
+<h2 id="h6">6. Text Sizes and Styling</h2>
+<div class="d2" id="d6">
+<p class="noindent">This section describes how to change the size of text, how to style text (such as italics), and how to move it around. It also describes some miscellaneous commands that are intended to modify text.</p>
+<p class="item"><b>A.</b> Information about how to choose the global, main text point size is described in <a href="#h4.2.1.2">section 4.2.1.2</a>. General information about choosing fonts and font features is in <a href="#hC">Appendix C</a> and <a href="#hE">Appendix E</a>. Styles particularly used at chapter openings are described in <a href="#h5">section 5</a>.</p>
+<p class="item"><b>B.</b> There is no direct setting for normal baselineskip; it is automatically calculated from the size of the textblock (using Trim Size, Margins, and header/footer layouts) and <a href="#h4.3.2">lines per page</a>.</p>
+<p class="item"><b>C.</b> The included <i>microtype</i> package is pre-configured, using these settings:</p>
+<p class="code"><code>\microtypesetup{config=novel-microtype,final,stretch=20,shrink=20}</code></p>
+<p>File <i>novel-microtype.cfg</i> uses settings typical of the kind of book-weight font that you are likely to use. The stretch and shrink factors are moderate. Calculation is always final, so that you see the same effect whether or not you use the <i>draft</i> class option. If you wish to change any of these, see the <i>microtype</i> package documentation. Note that since you are compiling with LuaLaTeX, some features of <i>microtype</i> may not be available.</p>
+
+<h3 id="h6.1">6.1. Text Sizes</h3>
+<div class="d3" id="d6.1">
+<p class="noindent">Be sure to read through this. In <i>novel</i>, standard TeX font size commands are disabled. There are new commands that address the limited needs for font sizing, in the context of fiction. These new commands are primarily for local adjustments of a few characters, or for display pages that are outside the main flow of text.</p>
+
+<h4 id="h6.1.1">6.1.1. Surprise! Traditional TeX Font Size Commands Are Disabled.</h4>
+<div class="d4" id="d6.1.1">
+<p class="item"><b>A.</b> Standard LaTeX font size commands, such as <code>\small</code> and <code>\LARGE</code>, are disabled in <i>novel</i>. If you use them, they will be ignored, and the affected text will be printed without modification. This is by intent, for the purpose of maintaining the baseline grid.</p>
+<p class="item"><b>B.</b> The one exception is that <a href="#h6.5.1">footnotes</a> will appear with smaller than normal size and skip. But this is done automatically. You cannot manipulate it with a size command.</p>
+<p class="item"><b>C.</b> Use <i>novel's</i> own commands for manipulating font size. The correct command depends on the quantity of text involved.</p>
+</div><!-- end 6.1.1 -->
+
+<h4 id="h6.1.2">6.1.2. <code>\charscale[<em>scale,hoffset,voffset</em>]{<em>text, but not image</em>}</code> and starred</h4>
+<div class="d4" id="d6.1.2">
+<p class="item"><b>A.</b> The contents of <code>\charscale{}</code> occupy no vertical space. Thus, scaled text does not push baselines apart. Excessive scale may cause characters to overlap; in some cases this is a desirable special effect.</p>
+<p class="item"><b>B.</b> The optional argument has up to three comma-separated components. The first is a number, which scales the text relative to its natural size. If the text was already scaled by some other operation (such as using <i>fontspec</i> to define the font with Scale feature), then the effect is cumulative.</p>
+<p>Do not use a scale close to zero, or negative. The result is unpredictable.</p>
+<p class="item"><b>C.</b> <code>\charscale</code> may be used for a short amount of text, where there is no line break, and no wrap. The command will throw an error if the included text has <code>\\</code> or <code>\par</code> or any other method that breaks the line.</p>
+<p>Excessive text will not wrap. It will overflow into the right margin.</p>
+<p class="item"><b>D.</b> <b>Example:</b> In this example, line 4 is so enarged that its ascenders and descenders overlap other text.</p>
+<p class="code" style="margin-left:0px"><img class="floatright" src="html-resources/jackbequick.png" width="222" height="94" title="use of \charscale" alt="use of \charscale"/><code><small>
+Jack be quick. (1)\par<br/>
+\charscale[1.2]{Jack be quick.} (2)\par<br/>
+\charscale[1.5]{Jack be quick.} (3)\par<br/>
+\charscale[2.5]{Jack be quick.} (4)\par<br/>
+\charscale[1.2]{Jack be quick, JACK} (5)\par
+</small></code></p>
+<p class="item"><b>E.</b> The second optional component, if used, is horizontal offset. The third optional component, if used, is vertical offset. Offsets are lengths, measured in units such as <code>em</code> or <code><span style="cursor:help" title="normal baseline skip">\nbs</span></code>.</p>
+<p class="item"><b>F.</b> In its starred form, the contents of <code>\charscale*{}</code> occupy neither vertical nor horizontal space. <b>Example:</b></p>
+<p class="code" style="margin-left:0px"><img class="floatright" src="html-resources/alphabetagamma.png" width="263" height="124" title="use of \charscale" alt="use of \charscale"/><code><small>
+Alpha \charscale[1.25]{Beta} Gamma. (1)\par<br/>
+Alpha \charscale[1.25,8em,1.3<span style="cursor:help" title="normal baseline skip">\nbs</span>]{Beta} Gamma. (2)\par<br/>
+Alpha Gamma. (3)\par<br/>
+Alpha\charscale*[1.25,8em,1.3<span style="cursor:help" title="normal baseline skip">\nbs</span>]{Beta} Gamma. (4)\par
+</small></code></p>
+<p>In line 1, Beta is enlarged, but not offset. It occupies slightly more width than it would have occupied unscaled. In line 2, Beta has been offset. Since the unstarred <code>\charscale</code> was used, the horizontal space is still there.</p>
+<p>Line 3 has no Beta. Line 4 uses the starred <code>\charscale*</code> to offset Beta, but no width is left behind. Note that the space between Alpha and Gamma is an ordinary inter-word space, because there is a space following the command.</p>
+<p class="item"><b>G.</b> <code>\charscale</code> is very effective on <a href="#hD.3.1.1">display pages</a>, where you can scale and move text however you wish. The starred version is especially useful, since back-to-back <code>\charscale*</code> will place text from a single vantage point.</p>
+<p class="item"><b>H.</b> In main text, the most practical application of <code>\charscale</code> is to enlarge the first character of chapter text. See <a href="#h5.5.1">section 5.5.1</a>. Otherwise, the command is rarely used, mostly for local correction of characters that need some size adjustment.</p>
+<p class="item" style="position:relative"><b>I.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> <code>\charscale</code> does not commute with some other TeX commands. That is, the results of <code>\charscale{\othercommand{<em>text</em>}}</code> and <code>\othercommand{\charscale{<em>text</em>}}</code> may differ.</p>
+</div><!-- end 6.1.2 -->
+
+<h4 id="h6.1.3">6.1.3. <code>\begin{parascale}[<em>scale</em>] ... \end{parascale}</code></h4>
+<div class="d4" id="d6.1.3">
+<p class="item"><b>A.</b> The <i>parascale</i> environment is used on a paragraph basis. More than one paragraph may be included. The scale is applied to the font size and to the baselineskip within.</p>
+<p>Note that the scale is an optional argument. Default is <code>1</code>.</p>
+<p class="item"><b>B.</b> The <i>parascale</i> environment is allowed to cross page boundaries.</p>
+<p>Trick: If you place an ordinary paragraph in <i>parascale</i> at scale <code>1</code>, then you will know whether or not that paragraph remains on one page.</p>
+<p class="item"><b>C.</b> For scale less than or equal to <code>1</code>, the first line in <i>parascale</i> will be at the normal baseline position. The following lines will progressively depart from the normal grid (unless scale is <code>1</code>). Thus, you will usually need to add some amount of vertical space following <i>parascale</i>, in order to restore subsequent text to the line grid.</p>
+<p class="item"><b>D.</b> You will usually get a Warning message, advising you that <i>parascale</i> caused the subsequent text (after the environment closed) to be off-grid. Fix by adding the requisite <code>\vspace</code> just prior to <code>\end{parascale}</code>.</p>
+<p>If <i>parascale</i> is entirely on a single page, you may also split the <code>\vspace</code>: Place part of it prior to <code>\begin{parascale}</code>, and part of it prior to <code>\end{parascale}</code>.</p>
+<p class="item"><b>E.</b> If multiple <i>parascale</i> end on a single page, the line deficit is cumulative. For example, if the first deficit is <code>0.5\nbs</code> and the second defict is <code>0.8\nbs</code>, you would fix them by adding <code>0.5\nbs</code> and <code>0.3\nbs</code> respectively.</p>
+<p class="item"><b>E.</b> Example:</p>
+<p class="code"><code><small>
+Lord Withens sneaked out the door of the veranda, and hastily opened the letter. In it was a message that curled his jodphurs:\par<br/>
+\begin{parascale}[0.87]<br/>
+We knows where youse been a-goin all a them dark and stormy nights. We knows what you been doin out there. We got yer number, Jack. So youse better play nice or we gonna rat to the lady.\par<br/>
+\vspace{0.26\nbs} % Without this, a Warning is issued, adivisng 0.26\nbs.<br/>
+\end{parascale}<br/>
+Even after his jodphurs had finally uncurled, Lord Withens could not master his rage. ``My name's not Jack,'' he mumbled.\par
+</small></code></p>
+<p class="centerimg"><img src="html-resources/parascale.png" width="598" height="214" title="parascale with vspace" alt="parascale with vspace"/></p>
+</div><!-- end 6.1.3 -->
+
+<h4 id="h6.1.4">6.1.4. Open Type Scale (fontspec)</h4>
+<div class="d4" id="d6.1.4">
+<p class="item"><b>A.</b> If you will be using a font in a way that it will <em>always</em> be at a size different from the normal font size, you may use the <a href="#hE.2.1">Scale</a> feature when you first define the font. This is defined by the <i>fontspec</i> package, which is automatically loaded with <i>novel</i>. Example:</p>
+<p class="code"><code>\NewFontFamily\minifont[Scale=0.75,Numbers=Lining]{\parentfont}</code></p>
+<p class="item"><b>B.</b> The scaled font can be used anywhere. It is not limited to a single line, and it will maintain the line grid at scales not exceeding 1.</p>
+<p class="item" style="position:relative"><b>C.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Scaled text may disturb the line grid, if its scale is more than 1.</p>
+</div><!-- end 6.1.4 -->
+</div><!-- end 6.1 -->
+
+<h3 id="h6.2">6.2. General Styling</h3>
+<div class="d3" id="d6.2">
+<p class="noindent">Many of these commands are directly from LaTeX, and are mentioned here because they are frequently used. Other commands are specific to <i>novel</i>.</p>
+
+<h4 id="h6.2.1">6.2.1. Italics and Emphasis</h4>
+<div class="d4" id="d6.2.1">
+<p class="item"><b>A.</b> <code>\itshape{<em>text, may cross paragraphs</em>}</code> is a general-purpose command for italics.</p>
+<p class="item"><b>B.</b> <code>\textit{<em>text</em>}</code> will not cross paragraphs.</p>
+<p class="item"><b>C.</b> <code>\emph{<em>text</em>}</code> changes regular text to italics, and italic text to regular. You may nest <code>\emph</code> commands. Many writers opine that this is the preferred way to specify italics. It cannot cross paragraphs.</p>
+<p class="item"><b>D.</b> If the italicized text leans too far into the following space, try adding <code>\/</code> (back and forward slashes) just before closing the braces.</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Italics are not faked (such as by slanting). If the font does not have an italic font file, then regular text will appear. You may use <i>fontspec</i> syntax to substitute a different italic font, if necessary. See <a href="#hE.1.1">Appendix E.1.1</a> <i>file name combinations</i>.</p>
+</div><!-- end 6.2.1 -->
+
+<h4 id="h6.2.2">6.2.2. Bold, Semibold, etc.</h4>
+<div class="d4" id="d6.2.2">
+<p class="item"><b>A.</b> <code>\bfshape{<em>text, may cross paragraphs</em>}</code> is a general-purpose command for bold.</p>
+<p class="item"><b>B.</b> <code>\textbf{<em>text</em>}</code> will not cross paragraphs.</p>
+<p class="item"><b>C.</b> The default main font in <i>novel</i> is <i>Libertinus Serif</i>, which has both bold and semibold weights. The semibold weight is pre-configured to substitute for bold.</p>
+<p class="item"><b>D.</b> If you use a different font, and it has an alternative to bold weight, see <a href="#hE.1.1">Appendix E.1.1</a> <i>file name combinations</i> for how to configure the choice. Bold is not faked by thickening.</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Bold is rare in fiction. It <em>might</em> be the case that this weight is useful for titles, but you ought to consider a fancy-looking font for that purpose, rather than mere Bold. Or, make the letters big and bold, but balance the effect by using gray.</p>
+</div><!-- end 6.2.2 -->
+
+<h4 id="h6.2.3">6.2.3. Underlining</h4>
+<div class="d4" id="d6.2.3">
+<p class="noindent">Underlining is inappropriate for fiction. Don't do it. Besides, there are some issues regarding line grid and appearance, which are not a problem in academic works, but are noticeable in fiction.</p>
+<p>If you are using a line for its graphic effect, the <code><a href="#bigemdash">\bigemdash</a></code> command might be helpful.</p>
+</div><!-- end 6.2.3 -->
+
+<h4 id="h6.2.4">6.2.4. Small Caps and Midcase</h4>
+<div class="d4" id="d6.2.4">
+<p class="item"><b>A.</b> <code>\scshape{text, may cross paragraphs}</code> is a general-purpose command for converting lowercase to small caps.</p>
+<p class="item"><b>B.</b> <code>\textsc{<em>text</em>}</code> does not cross paragraphs. Alias: <code>\smcp{<em>text</em>}</code>.</p>
+<p class="item"><b>C.</b> <code>\allsmcp{<em>text</em>}</code> places both uppercase and lowercase letters in small caps. It does not cross paragraphs.</p>
+<p class="item"><b>D.</b> Small caps are taken from the font's <i>smcp</i> Open Type feature. If the font is not Open Type, or does not have this feature, then small caps will not be faked. Command <code>\allsmcp</code> also uses feature <i>c2sc</i> if it is available; otherwise it converts letters to lowercase, then applies <i>smcp</i>.</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> If you require small caps, but your font does not have them, you can fake them by scaling uppercase. But this is usually unattractive. A better method is described in the <i>fontspec</i> package documentation: You may appoint a different font that will provide small caps.</p>
+<p class="item" style="position:relative"><b>F.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> If you insist on using old-fashioned TeX fonts, which do not have the <i>smcp</i> Open Type feature, then you may need to write this code in the Preamble:</p>
+<p class="code"><code>\let\smcp\oldscshape\relax<br/>
+\let\textsc\oldscshape\relax<br/>
+\let\scshape\oldscshape\relax</code></p>
+<p>The above code sends you in a time machine back to the Twentieth Century.</p>
+<p class="item"><b>G.</b> <code>\midcase{<em>text</em>}</code> is special to <i>novel</i>. If the <i>NovelDeco</i> font is installed, uppercase letters in the text will be converted to "mid-size capitals," and lowercase will remain lowercase, but with ascenders slightly reduced. The purpose of this command is so that acronyms such as NASA and NATO blend well with surrounding text. I have found that whereas ordinary uppercase is too conspicuous, small caps also looks wrong. Example:</p>
+<p class="code"><img class="floatright" src="html-resources/acronym2.png" width="192" height="89" alt="midcase"/>
+<code>
+The NATO alliance...\par<br/>
+The \midcase{NATO} alliance...\par<br/>
+The \allsmcp{NATO} alliance...\par
+</code></p>
+<p class="item" style="position:relative"><b>H.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Whether or not to use the <code>\midcase</code> command, is up to you. Since its letters are drawn from the <i>NovelDeco</i> font, rather than your main font, there may be some stylistic differences if your <i>parent font</i> is not Libertinus Serif.</p>
+</div><!-- end 6.2.4 -->
+
+<h4 id="h6.2.5">6.2.5. Local Tracking Adjustment</h4>
+<div class="d4" id="d6.2.5">
+<p class="item"><b>A.</b> <i>Tracking</i> refers to how tight or loose is the space between adjacent letters. This is a property of the font itself, and is automatically tweaked by the included <i>microtype</i> package. Do not confuse tracking with <i>inter-word spacing</i>, which is more widely adjusted during paragraph layout calculations.</p>
+<p class="item"><b>B.</b> If only two adjacent letters are involved, use the <code>\kern</code> or <code>\hspace</code> command. The following examples have the same effect. Note that there is no added space character, and that the units of length are <code>em</code>:</p>
+<p class="code"><code>
+I\kern-.05emt was a dark and stormy night.<br/>
+I\hspace{-.05em}t was a dark and stormy night.
+</code></p>
+<p class="item"><b>C.</b> Loose tracking is often used in page header text. In <i>novel</i>, this is addressed by a special command. See <a href="#h4.3.4.3">section 4.3.4.3</a>.</p>
+<p class="item"><b>D.</b> Do not use the <code>\textls</code> command. It will be ignored, and its contents will be rendered with ordinary tracking.</p>
+<p class="item"><b>E.</b> The included <i>fontspec</i> package allows you to globally set the tracking of an Open Type font, or locally change its tracking, using the <i>LetterSpace</i> feature. It is unlikely that you will need this capability. If you do, see <i>fontspec</i> package documentation 6.8.</p>
+</div><!-- end 6.2.5 -->
+
+<h4 id="h6.2.6">6.2.6. Local Font Selection</h4>
+<div class="d4" id="d6.2.6">
+<p class="item"><b>A.</b> The following font commands are pre-defined in <i>novel</i>: \rmfamily (alias <a href="#h4.2.2">\mainfont</a>) <a href="#h4.2.4">\sffamily</a> <a href="#h4.2.4">\ttfamily</a> <a href="#h5.1.3.1">\chapterfont</a> <a href="#h5.1.3.1">\subchfont</a> <a href="#h4.3.4.2">\headfont</a> <a href="#h4.2.3">\decofont</a> <a href="#hF.4">\decodropcapfont</a>.</p>
+<p class="item"><b>B.</b> Although most of the pre-defined font commands are automatically applied in specific situations, you may apply any of them yourself, in any location, using this syntax:</p>
+<p class="code"><code>{\subchfont This text will be in the subch font.}</code></p>
+<p class="item"><b>C.</b> If you wish, use <i>fontspec</i> syntax to create additional font selection commands. See <a href="#h4.2.5">section 4.2.5</a> and <a href="#hE">Appendix E</a> for the essentials. For example, if you have the licensed font, this code would define the font selection command <code>\agarp</code> in Preamble:</p>
+<p class="code"><code>\NewFontFamily\agarp[Numbers=OldStyle,Ligatures=Common]{Adobe Garamond Pro}</code></p>
+<p>Then you would apply it to text:</p>
+<p class="code"><code>{\agarp Text to appear in that font.}</code></p>
+</div><!-- end 6.2.6 -->
+
+<h4 id="h6.2.7">6.2.7. Local Feature Changes</h4>
+<div class="d4" id="d6.2.7">
+<p class="noindent"><code><b>{\addfontfeature{<em>feature</em>} <em>text</em>}</b></code> for changing Open Type features.</p>
+<p class="item"><b>A.</b> If a font is already defined, you can locally add one or more <a href="#hE.2">features</a>. For example, suppose that you defined <code>\mynewfont</code> without using its Open Type feature <i>ss03</i> (we will assume that the font actually has this feature). In a particular place, you wish to activate <i>ss03</i>. The code looks like this:</p>
+<p class="code"><code>{\mynewfont\addfontfeature{RawFeature=+ss03} <em>text</em>}</code> % Note + sign. Braces outside.</p>
+<p>That limits the scope of the feature to the included group, in TeX terminology.</p>
+<p class="item"><b>B.</b> You can modify features used by any defined font, whether you defined it yourself or it is one of the <i>novel</i> built-in font commands. You can add more than one feature. If the requested feature does not exist in the font, then your request will be ignored.</p>
+<p class="item"><b>C.</b> What about removing a feature that is already present in the font definition? Suppose you defined <code>\mynewfont</code> so that <i>Numbers=OldStyle</i> is used. On a local basis, can you change the style of numbers? Usually, yes. You could use <i>Numbers=Lining</i> to over-ride the feature. Sometimes it depends on how you chose the features, as a matter of syntax. See the <i>fontspec</i> documentation.</p>
+</div><!-- end 6.2.7 -->
+
+<h4 id="h6.2.8">6.2.8. Grayscale Text</h4>
+<div class="d4" id="d6.2.8">
+<p class="item"><b>A.</b> <code><b>\color{<em>name</em>}</b></code> or <code><b>\color[gray]{<em>scale</em>}</b></code> is used within a group. All text will be in grayscale, from where the command is placed, until the group ends. If the command is not at the beginning of the group, it does not affect prior text. Example:</p>
+<p class="code"><code>
+\begingroup<br/>
+This text is unaffected by the following command.<br/>
+\color{lightgray} % Alternative: \color[gray]{number 0 to 1}<br/>
+This text is in lightgray, until the group ends.<br/>
+\endgroup
+</code></p>
+<p style="margin-top:10px"><code><b>\textcolor{<em>text</em>}</b></code> or <code><b>\textcolor[gray]{<em>scale</em>}{<em>text</em>}</b></code> affects only the included text.</p>
+<p class="code"><code>\textcolor{gray7}{This text is in color gray7, a medium-light gray.}<br/>
+\textcolor[gray]{0.32}{This text is in 32 percent gray.}</code></p>
+<p style="margin-top:10px">Whether you use <code>\color</code> or <code>\textcolor</code>, there are two ways to specify the color: by name, or by scale, using package <i>xcolor</i> syntax.</p>
+<p class="item"><b>B.</b> The following color names are accepted, and will be converted to some shade of gray (from dark to light): black, blue, violet, darkgray, purple, red, teal, olive, magenta, gray, brown, green, orange, cyan, lightgray, lime, pink, yellow, white.</p>
+<p class="item"><b>C.</b> The above names are often not helpful, so <i>novel</i> also allows you to use these: black, gray1, gray2, gray3, gray4, gray5, gray6, gray7, gray8, gray9, white. The scale is not uniform (gray5 is not 50 percent gray), but the values are usefully spaced.</p>
+<p class="item"><b>D.</b> To specify color by scale, follow the color command with <i>[gray]{<em>scale</em>}</i>, where the scale is a number between 0 (black) and 1 (white). Example:<code> \color[gray]{0.63}</code>.</p>
+<p>If you use <i>xcolor</i> syntax to request an rgb color, it will be converted to 1-channel grayscale.</p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Absolutely no transparency!</p>
+<p class="item" style="position:relative"><b>F.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Other names "known to dvips," such as <i>Apricot</i>, do not work. An error will result.</p>
+</div><!-- end 6.2.8 -->
+</div><!-- end 6.2 -->
+
+<h3 id="h6.3">6.3. Positioning and Alignment</h3>
+<div class="d3" id="d6.3">
+<p class="noindent">By now, you already know: In <i>novel</i> there are new ways to position or align text, and some of the standard TeX methods are discouraged or disabled.</p>
+
+<h4 id="h6.3.1">6.3.1. What to Avoid</h4>
+<div class="d4" id="d6.3.1">
+<p class="item"><b>A.</b> The <code>\raisebox</code> command does not play well with novel. It can be used on a <a href="#hD.3.1.1">display page</a>, where line grid is less important. In main text, avoid it. Use <code><a href="#h6.1.2">\charscale</a></code> instead.</p>
+<p class="item"><b>B.</b> If you must use the <code>\vspace</code> command (or its relative, <code>\vskip</code>) be sure to measure the space in units of <code><span style="cursor:help" title="normal baseline skip">\nbs</span></code> (normal baseline skip).</p>
+<p class="item"><b>C.</b> Avoid the <i>minipage</i> and <i>parbox</i> environments. These are likely to disrupt the line grid. When that happens, restoring the grid is your own responsibility. You may find the <i>adjustwidth</i> environment to be useful, as described in the next section.</p>
+<p class="item"><b>D.</b> In most cases, do not use the center environment. You may use <code>{\centering ... \par}</code> instead, for a single paragraph. The center environment may cause the text to go off-grid. That's not a problem on some <a href="#hD.3.1.1">display pages</a> where you don't care about the grid, but it is ugly in the middle of running text.</p>
+<p class="item"><b>E.</b> Avoid positioning via the <i>textblock</i> or <i>textblock*</i> environments (package <i>textpos</i>).</p>
+<p>Actually, <i>novel</i> uses that code internally. But if not handled with more care than usual, positioned text can disrupt the baseline and position of surrounding text. You may use <code><a href="#h6.1.2">\charscale</a></code> to position small amounts of text safely, but not on a paragraph basis.</p>
+<p>Images have built-in positioning arguments.</p>
+<p class="item"><b>F.</b> Do not use floats (except in <a href="#h2.2">sandbox</a>). Use <i>novel's</i> own <code>\FloatImage</code>.</p>
+<p class="item"><b>G.</b> Do not use tables (except in <a href="#h2.2">sandbox</a>). But <i>novel</i> has its <a href="#hD.3.2.7">own provision</a> for a Table of Contents, and the code may be used for other purposes as well.</p>
+<p class="item"><b>H.</b> Do not use picture environment (except in <a href="#h2.2">sandbox</a>). Use only the image commands provided by novel: <code><a href="#h7.2.2">\InlineImage</a></code>, <code><a href="#h7.2.4">\FloatImage</a></code>, and <code><a href="#h7.2.5">\WrapImage</a></code>. There is also a special provision for <a href="#h7.1.2">color cover artwork</a>.<p>
+</div><!-- end 6.3.1 -->
+
+<h4 id="h6.3.2">6.3.2. Some Useful Commands</h4>
+<div class="d4" id="d6.3.2">
+<p class="noindent">This is not a complete list. It merely addresses a few situations that you are likely to encounter, without the need for elaborate code, and without loading additional packages.</p>
+<p style="margin-top:10pt"><code>\begin{adjustwidth}{<em>left</em>}{<em>right</em>} ... \end{adjustwidth}</code></p>
+<p>This environment, from the included <i>changepage</i> package, is the most useful way to create block indents. The included text may have multiple paragraphs and span pages. The left and right arguments are lengths, being the amount to <em>increase</em> the respective margins from their normal values.</p>
+<p style="margin-top:10pt"><code>\rotatebox{<em>text</em>}</code></p>
+<p>This command is from the included <i>graphicx</i> package. It rotates the text, about an axis at the lower left of the text. If you wish to rotate the text about its center, use <code>\rotatebox[origin=c]{text}</code>.</p>
+<p>This command plays nicely with <code>\charscale</code>, so you can size, rotate, and displace a string of text (single line). It makes a difference which command goes inside the other. More likely than not, the effect you want is obtained by using <code>\charscale</code> on the outside, with <code>\rotatebox</code> inside.</p>
+<p>To avoid disturbing the line grid, <code>\rotatebox</code> is best used with <a href="#h6.1.2">\charscale</a> and a few blank lines.</p>
+<p style="margin-top:10pt"><code>\phantom{<em>text</em>}</code></p>
+<p>Does not print the text, but leaves a horizontal gap as if the text were there. Caution: In some locations, this command has unexpected results, such as by adding a line.</p>
+<p style="margin-top:10pt"><code>\mbox{<em>text</em>}</code></p>
+<p>Prevents a specific word from being hyphenated, or to ensure that two consecutive words always appear on the same line. The box will not be broken across lines. However, it may overhang the margin, which is undesirable.</p>
+<p style="margin-top:10pt"><code>\makebox[<em>width</em>][<em>alignment</em>]{<em>text</em>}</code></p>
+<p>Puts the text in a box of fixed width (usually much larger than the text's own width) and aligns it left, center, or right in the box. If using this across the full textwidth, be sure to precede it with <code>\noindent</code> to prevent offset.</p>
+<p style="margin-top:10pt"><code>\hspace{<em>length</em>}</code></p>
+<p>Creates a horizontal space.</p>
+<p style="margin-top:10pt"><code>\strut</code></p>
+<p>Places an invisible box with no width, which has the height and depth of the font. Sometimes used as a placeholder.</p>
+<p style="margin-top:10pt"><code>\stake</code></p>
+<p>Placeholder like <code>\strut</code>, but does not occupy the height or depth of the font.</p>
+<p style="margin-top:10pt"><code>\indent</code>, <code>\noindent</code>, <code>\forceindent</code>, <code>\backindent</code></p>
+<p>Commands <code>\indent</code> and <code>\noindent</code> have their ordinary TeX meaning. Sometimes, the action of other macros will remove an indent that should be there, or add an indent that should not be there. If writing <code>\indent</code> and <code>\noindent</code> do not fix the problems, use <code>\forceindent</code> and <code>\backindent</code> as more forceful solutions.</p>
+<p style="margin-top:10pt"><code>\hfill</code></p>
+<p>Pushes the following text to the right end of the line. Actual effect depends on what precedes and follows. Sometimes a \strut is needed at the beginning of a line.</p>
+<p style="margin-top:10pt"><code>\vfill</code>, <code>\vfill*</code></p>
+<p>Pushes the following text to the bottom of the page. Actual effect depends on paragraph organization. Use the asterisk if there is nothing printed above this command, on the same page.</p>
+<p style="margin-top:10pt"><code>\kern</code></p>
+<p>Tweaks the spacing between consecutive letters. A tricky command, as it is always used without braces, and makes the surrounding text illegible in your source code. If you use it, the units of length should always be <i>em</i>, rather than <i>pt</i>. Example:</p>
+<p class="code"><code>It wa\kern-.02ems a da\kern.03emrk and stormy ni\kern-.004emght.</code></p>
+<p>The <code>\kern</code> command is not useful for globally changing kern values.</p>
+<p id="bigemdash" style="margin-top:10pt"><code>\bigemdash[<em>yoffset,thickness</em>]</code></p>
+<p>Simulates a "big emdash" of variable length. Horizontal width is from command to end of line marked by <code>\par</code>, or limited by a fixed width such as created by <code>\makebox</code>. If placed in other situations, the line may be missing or too long.</p>
+<p>The line's normal position is at the typical height of an emdash, which is slightly above half the height of lowercase x. Its normal width is typical of an emdash width. Thus, the line is like an extended emdash.</p>
+<p>You can tweak the line using its optional argument. The first value tweaks the vertical position by a scale factor, where 1 equals its normal position (so that 0.9 places it a little lower). The second argument, if used, is separated from the first by a comma. It tweaks the line thickness by a scale factor (so that 0.9 makes it a little thinner).</p>
+<p>Since <code>\bigemdash</code> allows an optional argument, but no mandatory argument, you may not immediately follow it with text. If it is boxed, then first close the box; otherwise, end the paragraph.</p>
+<p style="margin-top:10pt"><code>\straightquote{}</code>, <code>\straightdblquote{}</code></p>
+<p>These insert the single quote (apostrophe), and double quote, as ASCII straight characters. Prevents TeX (or your software) from automatically substituting the curly characters. The empty braces are mandatory.</p>
+</div><!-- end 6.3.2 -->
+</div><!-- end 6.3 -->
+
+<h3 id="h6.4">6.4 Superscripts, Subscripts</h3>
+<div class="d3" id="d6,4">
+<p class="item"><b>A.</b> In <i>novel</i>, superscripts and subscripts are called "markers." Most book-quality Open Type fonts have markers in style sets (<i>sups</i>, <i>sinf</i>, <i>subs</i>).</p>
+<p class="item"><b>B.</b> In professional fonts, marker glyph weights are adjusted for consistent appearance compared to ordinary glyphs. However, many free fonts do not adjust marker glyph weights, so the markers may appear too small, or too light. You may choose whether to use a font's own markers, or allow <i>novel</i> to generate markers, depending on whichever you think looks better.</p>
+<p class="item"><b>C.</b> <i>real</i> markers attempt to use the Open Type feature <i>sups</i> for superscripts, and the feature <i>sinf</i> (preferred) or <i>subs</i> (alternate) for subscripts. Real markers are the best choice for professional fonts. If the requested feature is not available for the font, then it will be automatically faked, by scaling/raising/lowering ordinary characters from the basefont (lining numerals will be used).</p>
+<p class="item"><b>D.</b> <i>fake</i> markers ignore whether the Open Type features are available, and simply fakes them. Sometimes this is the best choice for fonts that do not have properly designed markers.</p>
+
+<h4 id="h6.4.1">6.4.1. <code>\SetMarkerStyle[<em>real,fake</em>]{<em>asterisk, dagger, number</em>}</code></h4>
+<div class="d4" id="d6.4.1">
+<p class="item"><b>A.</b> This command may only be used in the Preamble. It globally sets the kind of marker to be used. Default is <i>real</i> and <i>asterisk</i>.</p>
+<p class="item"><b>B.</b> The optional argument applies real or fake markers, as described above.</p>
+<p class="item"><b>C.</b> The required argument applies only to markers created by the <a href="#h9.1"><code>\footnote</code></a> command. It does not apply to endnotes, or to manually placed superscripts and subscripts.</p>
+<p class="item"><b>D.</b> The available choices for marker style:</p>
+<p>&bull; <i>asterisk</i> (default) uses symbolic footnote markers. The symbols rotate in order * † ‡ § ** †† ‡‡ §§ until reset.</p>
+<p>&bull; <i>dagger</i> uses symbolic footnote markers, but without asterisks. The symbols rotate in order † ‡ § †† ‡‡ §§ until reset.</p>
+<p>&bull; <i>number</i> uses numerical footnote markers. Due to possible conflict, the log file will have a "Big Bad Warning" if you use a numerical footnote marker in a document that also has endnotes, since endnotes always have numerical markers.</p>
+</div><!-- end 6.4.1 -->
+
+<h4 id="h6.4.2">6.4.2. <code>\realmarker</code>, <code>\fakemarker</code></h4>
+<div class="d4" id="d6.4.2">
+<p class="item"><b>A.</b> Within the body of the document, you may use <code>\realmarker</code> and <code>\fakemarker</code> to change your preference. The choice remains in effect until you change it again.</p>
+<p class="item"><b>B.</b> The option real/fake applies wherever superscripts or subscripts are used, not just for footnotes or endnotes.</p>
+</div><!-- end 6.4.2 -->
+</div><!-- end 6.4 -->
+
+
+</div><!-- end 6 -->
+</div><!-- end page06 -->
+<!-- ************************************************************ -->
+<div id="page07" class="page">
+
+
+<h2 id="h7">7. Images, Pictures, Drawings</h2>
+<div class="d2" id="d7">
+<p class="item"><b>A.</b> <b>Interior Bleed</b> is not supported. Only cover artwork has bleed.</p>
+<p>If your book consists primarily of artwork, rather than text, then you should use a page layout program designed for that purpose, instead of TeX.</p>
+<p class="item"><b>B.</b> The <b>picture environment</b> is not supported.</p>
+<p>If you try to use a <code>picture</code> environment, it will probably not throw an error, because pictures are used in the internal code. However, you will get unexpected layout. In any case, <b>caption</b> is not supported.</p>
+<p class="item"><b>C.</b> Most <b>vector drawings</b> (pgfplots, pstricks, TikZ) are not supported.</p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> You may work with the picture environment, and use vector drawings, in <code><a href="#h2.2">sandbox</a></code> mode.</p>
+<p>This requires you to create your picture or drawing in a separate document, then process the PDF to a raster image. The raster image is placed in your main document, using the commands provided in this section.</p>
+<p class="item"><b>E.</b> You cannot crop, transform, resize, or resample images within <i>novel</i>. Each image must be placed at exact size and resolution.</p>
+<p>So, if an image has print size 1.5" by 2" at 300dpi resolution, then its dimensions must be 450x600 pixels. Be sure that the image file contains its resolution.</p>
+
+<h3 id="h7.1">7.1. Technical Requirements for Raster Images</h3>
+<div class="d3" id="d7.1">
+
+<p class="noindent">Interior images may be black/white line art, or grayscale. Interior color is not supported. Color cover artwork has strong support.</p>
+
+<h4 id="h7.1.1">7.1.1. Black/White and Grayscale Interior Images</h4>
+<div class="d4" id="d7.1.1">
+<p class="item"><b>A.</b> Interior images may be grayscale, or black/white. There is no provision for color interior.</p>
+<p class="item"><b>B.</b> There is no provision for interior bleed. No image may approach the edge of the page. The amount of clearance is specified by your print service, and is often called the <a href="#h4.3.1.2">unsafe zone</a>.</p>
+<p class="item"><b>C.</b> Black/White line art has a single channel, at 1-bit per pixel. This format is only used for material that is inherently black and white, without shading. It is also useful for including black text prepared as an image. Most print services request resolution 600 to 800 pixels per inch.</p>
+<p class="item"><b>D.</b> Grayscale images have a single channel, at 8-bits per pixel. This format is used for photos and shaded artwork. It is also useful for including text prepared as an image, where the text is not black. Most print services request resolution 300 pixels per inch.</p>
+ <p class="item"><b>E.</b> Each image must be flat (no layers, no transparency).</p>
+<p class="item"><b>F.</b> Most print services require that images must be stripped of private metadata (such as EXIF), and that the color space be DeviceGray, rather than specified by a transfer profile.</p>
+<p class="item"><b>G.</b> Black/White images must be in <i>png</i> file format. Grayscale images may be in either <i>png</i> or <i>jpg</i> file format.</p>
+<p class="item" style="position:relative"><b>H.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> In the documentation <i>extras</i> folder, <i style="white-space:nowrap">novel-scripts.zip</i> will help you comply with these requirements. Complete usage information is provided there.</p>
+ <p class="item"><b>I.</b> From version 1.52, <i>novel</i> detects whether or not an interior image was pre-processed using <i>novel-scripts</i>. If yes, it is "known good". If no, it is "unknown" and may be good or bad.</p>
+<p>If your document has any "unknown" images, you will get a Warning. The list of "unknown" images is written near the bottom of the log file.</p>
+<p>If you know that an image meets specs (because you are a graphic artists who knows these things), but it wasn't processed by <i>novel-scripts</i>, you can manually add it to the list of "known good" images. In Preamble:</p>
+<p class="code"><code>\SetKnownGoodImages{somefile.png anotherfile.jpg}</code></p>
+</div><!-- end 7.1.1 -->
+
+<h4 id="h7.1.2">7.1.2. Color Cover</h4>
+<div class="d4" id="d7.1.2">
+<p class="item"><b>A.</b> The book cover may be (usually is) in color. Bleed is required.</p>
+<p class="item"><b>B.</b> If your print service allows you to submit cover artwork as an ordinary RGB image file, that's the easiest way to do it. Then, <i>novel</i> is not used.</p>
+<p class="item" style="position:relative"><b>C.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Complete support for creating a PDF/X-1a:2001 (or other) color cover, with image in CMYK at 240% ink limit, is provided in <i>novel-scripts.zip</i>. This format is required by some American print-on-demand services.</p>
+<p>The scripts, and supporting documentation, are in the <i>novel</i> documentation <i>extras</i> folder.</p>
+</div><!-- end 7.1.2 -->
+</div><!-- end 7.1 -->
+
+
+<h3 id="h7.2">7.2. Placing Interior Images</h3>
+<div class="d3" id="d7.2">
+<p class="item"><b>A.</b> If your book has a lot of images mingled with text, then you should consider using a page layout program (such as Scribus) instead of TeX. That's because the best strategies for an image-intensive picture book are very different from the strategies adoped by <i>novel</i>.</p>
+<p class="item"><b>B.</b> Images are not allowed to overlap each other, in the kind of commercial printing that is likely to be used for your book. However, since overlap is generally legal in PDF, TeX will not issue an error.</p>
+<p class="item"><b>C.</b> Remember: Images must be at exact size and resolution.</p>
+
+<h4 id="h7.2.1">7.2.1. Image-Like Effects in Text</h4>
+<div class="d4" id="d7.2.1">
+<p class="noindent">You may scale, rotate, and displace text. This is done using text commands, and the result is still text. When cleverly done, it provides an image-like effect. See <a href="#h6">section 6</a> for the possibilities.</p>
+</div><!-- end 7.2.1 -->
+
+<h4 id="h7.2.2">7.2.2. <code>\InlineImage[<em>hoffset,voffset</em>]{<em>imageFile.png or .jpg</em>}</code> and starred version</h4>
+<div class="d4" id="d7.2.2">
+<p class="item"><b>A.</b> This command places the image as an inline element, at 100% scale. The use of <i>png</i> or <i>jpg</i> images, with file extension, is required.<p>
+<p class="item"><b>B.</b> You may offset the image horizontally or vertically. Positive direction is to the right and up. If you use one offset, then you must use both (if necessary, <i>0em</i>). Any units of length may be used, but the preferred units are <i>em</i> or <code>\textwidth</code> for horizontal, and <i>em</i> or <code><span style="cursor:help" title="normal baseline skip">\nbs</span></code> for vertical.</p>
+<p class="item"><b>C.</b> By default, the <em>top</em> of the image is at the text baseline. If you prefer that the <em>bottom</em> of the image be at the text baseline, use voffset <i>b</i>. Example:</p>
+<p class="code"><code>\InlineImage[0em,b]{imageFile.png}</code></p>
+<p class="item"><b>D.</b> Thanks to the included <i>calc</i> package, offsets may use <code>\widthof{<em>text</em>}</code>, <code>\heightof{<em>text</em>}</code>, or <code>\depthof{<em>text</em>}</code> as lengths. The most useful of these is when you wish to align the top of an image at the X-height of surrounding text:</p>
+<p class="code"><code>\InlineImage[0em,\heightof{X}]{imageFile.png}</code></p>
+<p>You may also use <code>\heightof{\Aring}</code> for the tallest accented letter normally found in Latin-1.</p>
+<p>Another possibility is to align the bottom of an image with the lowercase descender:</p>
+<p class="code"><code>\InlineImage[0em,b-\depthof{gjpqy}]{imageFile.png}</code></p>
+<p class="item"><b>E.</b> Lengths <code>\imagewidth</code> and <code>\imageheight</code> may also be used for offsets. These lengths remain set, and can be used for other purposes (such as displacing text) until another image is placed.</p>
+<p class="item"><b>F.</b> Offsets may be written as combinations of lengths. If you use the baseline <i>b</i> as above, it must be the first character of voffset. If you use <code>\widthof</code> or <code>\heightof</code>, then its backslash must be the first character <em>unless</em> it is preceded by another length. Thus, an offset of <code style="white-space:nowrap">-\heightof{X}</code> is prohibited, but you can use <code>0pt-\heightof{X}</code>.
+<p>Here are some examples of allowable code:</p>
+<p class="code"><code>
+\InlineImage[2.3em, -0.4em]{imageFile.png}<br/>
+\InlineImage[0pt-\widthof{eee}, b+\heightof{X}-0.2em]{imageFile.jpg}
+</code></p>
+<p class="item"><b>G.</b> The image occupies zero vertical space. So, it will not push apart baselines. The next line(s) of text may overlie the image. In some cases, this is desirable. If you do not want that effect, then you can either insert a suitable number of <code>\null</code> lines after the image, or use the <code>\FloatImage</code> command instead.</p>
+<p class="item"><b>H.</b> With the un-starred <code>\InlineImage</code> command, the image occupies its natural horizontal width. That is, text following the image will (if it fits) continue from the right edge of the image. But with the starred <code>\InlineImage*</code> command, the image occupies zero width. In this case, text following the image will continue from the left of the image, and overlie the image.</p>
+<p class="item"><b>I.</b> Having text overlie the image is allowable, and can create some interesting special effects. But when your print service sees what you have done, they may think that it is a mistake. Be sure that you discuss this with them.</p>
+<p>If you do allow text to overlie an image, be sure that the image is very light. Repeat: <em>very light</em>. Depending on the printing technology, an image may print darker than you see on your computer screen, and that would make text hard to read. At low print volume, your print service will probably use a technology that can make very sharp text over images. However, if your book goes to volume production, then the technology will be different. Volume printing will use halftoned images, and the text overlay may also become halftoned, which will reduce its sharpness considerably.</p>
+<p class="item"><b>J.</b> An image may be placed in a way that prints some of the image in the margin. That's allowable if your margin is wider than the minimum required for printing clearance. But even if it is not allowable, there will be no complaint or warning from TeX. Use the <a href="#h2.3">shademargins</a> class option to ascertain position, and consider setting an <a href="#h4.3.1.2">unsafe zone</a>.</p>
+<p class="item" style="position:relative"><b>K.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Do not place an image so that it approaches or goes beyond the page edge. That requires a "bleed box" which is not part of <i>novel</i> capabilities (except for cover art). If your book needs that kind of image handling, use a page layout program instead.</p>
+</div><!-- end 7.2.2 -->
+
+<h4 id="h7.2.3">7.2.3. Text Over <code>\InlineImage</code></h4>
+<div class="d4" id="d7.2.3">
+<p class="item"><b>A.</b> As noted above, an <code>\InlineImage</code> (or its starred version) can be used as the background to any subsequent text. Whatever sits atop an image must be darker. If you need text in gray, it is better to integrate the rasterized text with the image in an external graphics program, instead of using gray text in your document.</p>
+<p class="item"><b>B.</b> When text overlies an image, it retains its identity as vector paths, as far as the PDF is concerned. In some printing processes, particularly those for very low volume production, the result will be as sharp and dark as ordinary text. However, if your book sells well (or is being prepared to sell well), the image will be converted to halftone, and the text that lies above it may also be converted to halftone. This will reduce the sharpness of the text. It is not necessarily a problem, unless your text is very small or has fine details.</p>
+<p>If the text-over-image is part of a title, then the text is naturally large and dark, and will easily withstand halftoning.</p>
+<p class="item"><b>C.</b> Not all print services will accept text over images. It's not that they <em>cannot</em> do it; after all, your home and office printers can easily do it. The reason they object is because the pages of your book will be handled in small volume by persons who are unfamiliar with the book. Text over an image may be flagged as a printing error or a bug in the PDF. In the advertising world, text over image is routine. But in the world of fictional novels, it is unusual.</p>
+<p class="item"><b>D.</b> An inline image occupies zero vertical space. If you place its top near the bottom of the textblock, then the image will happily flow into the lower margin and perhaps off the bottom of the page, without an error (but the print service will reject it). The reason that TeX does not provide an error message is quite simple: Technically, it is not an error! It is just not what you meant to do. The software cannot read your mind. This is where the <a href="#h2.3">shademargins</a> class option helps, especially when you set an <a href="#h4.3.1.2">unsafe zone</a>.</p>
+<p>Example:</p>
+<p class="code"><code>
+\noindent\InlineImage*[0pt,1.2<span style="cursor:help" title="normal baseline skip">\nbs</span>]{gavel.png} Lord Withens took a seat at the rear of the courtroom, attempting to be inconspicuous. Yet his effort was in vain, as he was the only person there with a riding crop and spurs.\par<br/>
+He would have taken the car, had it not been stolen. But that was why he was here, at the arraignment of the person charged with the theft. It was most unfortunate that the accused was his own elderly father; but then, theft ran in the family line.\par
+</code></p>
+<p class="centerimg"><img src="html-resources/inlineimagest.png" width="651" height="249" alt="example of InlineImage*"/></p>
+</div><!-- end 7.2.3 -->
+
+<h4 id="h7.2.4">7.2.4. <code>\FloatImage[<em>floatmethod,xoffset,yoffset</em>]{<em>ImageFile .png or .jpg</em>}</code></h4>
+<div class="d4" id="d7.2.4">
+<p class="item"><b>A.</b> <code>\FloatImage</code> places the image in its own block, like a paragraph.</p>
+<p class="item"><b>B.</b> The image will always be horizontally centered. If that is not what you wish, then you can widen the image in a graphics program, adding white space as needed. Or, you can use <code>xoffset</code> to move the image.</p>
+<p class="item"><b>C.</b> The top of the image will be positioned at the baseline of text, where text would have been without the image. You may adjust that position using <code>yoffset</code> (a positive length is upward). In some cases, <code>\normalXheight</code> (the normal text X height) is a good choice for <code>yoffset</code>.</p>
+<p class="item"><b>D.</b> The height of the image is automatically measured, so that the following paragraph will be positioned at an integer number of baseline skips. This maintains the text line grid.</p>
+<p class="item"><b>E.</b> The optional argument is comma-separated, with up to three values. The first is float method. The second (if used) is horizontal offset. The third (if used) is vertical offset. In some cases, changing the vertical offset will determine where the image fits.</p>
+<p class="item"><b>F.</b> The <i>float method</i> is a code describing how the floated image should be placed. The available choices are <code>t</code>, <code>b</code>, <code>ht</code>, and <code>hb</code>. Default is <code>ht</code>. Any un-listed float method will be substituted with <code>ht</code>.</p>
+<p class="code"><code>ht</code> places the float "here" (mid-page, where code appears) if possible. But if the image doesn't fit, it will appear at the top of the following page.</p>
+<p class="code"><code>hb</code> places the float "here" (mid-page, where code appears) if possible. But if the image doesn't fit, it will appear at the bottom of the following page. This method is unusual.</p>
+<p class="code"><code>t</code> places the float at the top of the following page. It may appear at the top of the page where the code is written, but only if the image happens to be the first content there.</p>
+<p class="code"><code>b</code> places the float at the first page bottom where it can fit.</p>
+<p class="item"><b>G.</b> No other kind of float is available, not even by loading other packages. The <i>novel</i> class is not intended for books that rely on floats. Other document classes already have that capability. Or, consider using a page layout program instead of TeX.</p>
+<p class="item"><b>H.</b> When a floated image is pushed to the following page, it will appear there, even if the image is too large for the page size. Other TeX classes will defer it.</p>
+<p class="item"><b>I.</b> The <i>floatpag</i> package does not work in <i>novel</i>. If a floated image occupies a full page, you cannot customize the head/foot style for that page; it will be the same as it was on the calling page.</p>
+</div><!-- end 7.2.4 -->
+
+<h4 id="h7.2.5">7.2.5. <code>\WrapImage[<em>position</em>]{<em>ImageFile.png or .jpg</em>}</code></h4>
+<div class="d4" id="d7.2.5">
+<p class="item"><b>A.</b> The <code>\WrapImage</code> command is a front-end to the included <i>wrapfig</i> package. Do not use commands from <i>wrapfig</i> directly.</p>
+<p class="item"><b>B.</b> <code>\WrapImage</code> is written between paragraphs. The image will appear with the next paragraph (unless moved). You cannot achieve the effect of wrapping an image mid-paragraph.</p>
+<p class="item" style="text-align:justify"><b>C.</b> <img class="floatright" style="position:relative; top:6px; margin-right:0px" src="html-resources/wrapme.png" width="104" height="104" alt="Wrap me!" title="Wrap me!"/><code>\WrapImage</code> allows text (may be more than one paragraph) to wrap around an image. What you are now reading uses this technique in HTML. The text is wrapped around the image at right. Next to the image, the lines of text are shorter. Past the bottom of the image, the line length is restored to its usual size. In HTML, this is called <i>floating</i> an image; but in TeX, it is called <i>wrapping</i>. Wrapped images are uncommon in fiction, but they might be more useful on display pages, which have many positioned elements but little running text.</p>
+<p class="item"><b>D.</b> The optional argument is position, any one of these letters: <code style="white-space:nowrap">l r o i L R O I</code>. Default is <code>r</code>. The letters place the image at left, right, outside, or inside (spine).</p>
+<p>Lowercase position places the image where you wrote the code. However, if there is not enough space to fit it (too close to bottom of page), then both the image and the wrapped text will be moved to the next page. This leaves a white gap at the bottom of the previous page, which is undesirable. But it guarantees that the image remains attached to the expected text.</p>
+<p>Uppercase position places the image where you wrote the code, if possible. However, if the image cannot fit there, then the image is floated to the next page, and accompanies the first new paragraph. This avoids a white gap at page bottom, but the image no longer accompanies the expected text. If you use this kind of position, avoid referring to "the image at right" or anything else that makes no sense if the image is moved.</p>
+<p class="item"><b>E.</b> The top of the image will be placed as the X-height of normal text. This provides a good compromise between visual clearance and conserving space. You cannot increase the separation between text and image via command. If you need more white space around the image, then enlarge it in a graphics program, with surrounding white areas.</p>
+<p class="item"><b>F.</b> You cannot wrap around a shape other than a rectangle. For that, you need a page layout program. Note: Actually, it can be done in TeX, but the code is mind-boggling and not part of any package. Don't ask.</p>
+</div><!-- end 7.2.5 -->
+</div><!-- end 7.2 -->
+
+
+</div><!-- end 7 -->
+</div><!-- end page07 -->
+<!-- ************************************************************ -->
+<div id="page08" class="page">
+
+
+<h2 id="h8">8. Tables and Lists</h2>
+<div class="d2" id="d8">
+<p class="item"><b>A.</b> <b>Lists</b> are not supported.</p>
+<p>If you attempt to use any of the well-known list environments, an error will result. This is because lists are typeset using layout incompatible with the rest of <i>novel</i></p>
+<p>If you need a list, you can use <code><a href="#h2.2">sandbox</a></code> mode in a separate document, convert the list to a raster image, then place the image in your main document.</p>
+<p class="item"><b>B.</b> <b>Tables</b> are not supported, except for the built-in <code><a href="#h8.1">toc</a></code>.</p>
+<p>If you attempt to use any of the well-known table environments, an error will result. This is because tables are typeset using layout incompatible with the rest of <i>novel</i></p>
+<p>If you need a table, you can use <code><a href="#h2.2">sandbox</a></code> mode in a separate document, convert the table to a raster image, then place the image in your main document. This is unnecessary if you use <code><a href="#h8.1">toc</a></code>.</p>
+
+<h3 id="h8.1">8.1. The <code>toc</code> Environment</h3>
+<div class="d3" id="d8.1">
+<p class="item"><b>A.</b> You may create a Table of Contents in your own style, or use the <i>toc</i> environment for <i>novel's</i> own style. The choice is yours.</p>
+<p class="item"><b>B.</b> Since <code>toc</code> is not synchronized against any other code, you may use it more than once, and you may use it for any purpose (not necessarily a Table of Contents).</p>
+<p class="item"><b>C.</b> The <code>toc</code> is an environment:</p>
+<p class="code"><code>\begin{toc}[<em>extra entry separation</em>]{<em>extra margins</em>} <em>...</em> \end{toc}</code></p>
+<p>The table is not indented, and text within it is not indented.</p>
+<p class="item"><b>D.</b> The optional argument is a number. It is the portion of normal baselineskip that will be added beneath each <code><a href="#h8.1.1">\tocitem</a></code> entry. Default is 0, meaning that there is no extra skip between items, and normal baselineskip is maintained.</p>
+<p>A value greater than 0 spreads the entries, which could be attractive if there are only a few chapters and you'd like to use more space on the page. For example, a value of <i>0.25</i> means that a gap of 0.25 normal baselineskip will be added beneath each entry.</p>
+<p>A small negative value will crowd the lines together, but there is a limit (approximately -0.1) before the lines cannot be squeezed any tighter.</p>
+<p>Note that the optional argument only applies to <code>\tocitem</code> entries, not to any other text within the environment.</p>
+<p class="item"><b>E.</b> The required argument is a length, which will be the amount of extra margin added at left and right of the table (using <i>adjustwidth</i>). A value of <i>0em</i> allows the table to occupy the full width of the textblock. A value of <i>2em</i> adds 2em to the margin on each side, so that the width of the table is 4em less than the width of the textblock.</p>
+<p> It is best to specify horizontal lengths in units of <i>em</i> or the proportional <code>\parindent</code> or <code>\textwidth</code>.</p>
+<p class="item" style="position:relative"><b>F.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Place at least one empty line above the Table's title, using <code>\null</code> or <code>\vspace*</code>. This will prevent the title (which is normally enlarged using <code>\charscale</code>) from encroaching into the top margin.</p>
+
+<h4 id="h8.1.1">8.1.1. Entries Using <code>\tocitem</code></h4>
+<div class="d4" id="d8.1.1">
+<p class="code"><code>\tocitem[<em>chapter number</em>]{<em>description</em>}{<em>page number</em>}</code> and starred</p>
+<p class="item"><b>A.</b> Use <code>\tocitem</code> for entries in <code>toc</code>. Do not use it for non-Table text on the page.</p>
+<p class="item"><b>B.</b> The optional argument is the <i>chapter number</i>, at most two digits. The number will be left-aligned, with a period automatically added. Following the period will be whatever amount of space is needed to keep the following description aligned.</p>
+<p>&bull; If the optional argument is omitted (or empty), then the <i>description</i> will align to the left of the table.</p>
+<p>&bull; If the optional argument is the tilde character <code>~</code> then no number or period is printed, but the space for <i>chapter number</i> is occupied, so that the following <i>description</i> aligns as if you had entered a <i>chapter number</i>.</p>
+<p class="item"><b>C.</b> The <i>description</i> is usually the chapter title. If it cannot easily fit on one line, then use an additional <code>\tocitem</code>, because the text cannot be wrapped. The following example shows how this can be done.</p>
+<p class="item"><b>D.</b> Without the asterisk, <code>\tocitem</code> fills the area between the description and the page number with empty space. The more popular, starred <code>\tocitem*</code> command fills with a dotted line, and is very attractive.</p>
+<p class="item"><b>E.</b> You may use ordinary style commands, such as <code>\textit</code>, in the entries.</p>
+</div><!-- end 8.1.1 -->
+
+<h4 id="h8.1.2">8.1.2. Example Table of Contents</h4>
+<div class="d3" id="d8.1.2">
+<p class="code" style="text-indent:0px; font-size:small"><img class="floatright" src="html-resources/toc.png" width="264" height="408" alt="toc example"/>
+<code>
+\cleartorecto % because ToC must start recto<br/>
+\thispagestyle{empty}<br/>
+\vspace*{4<span style="cursor:help" title="normal baseline skip">\nbs</span>}<br/>
+\begin{toc}[0.25]{5.5em}<br/>
+{\centering\charscale[1.25]{Contents}\par}<br/>
+\null\null<br/>
+\tocitem*{Prologue}{1}<br/>
+\tocitem*[1]{The Evil Weeds}{5}<br/>
+\tocitem*[2]{A Plan of Attack}{18}<br/>
+\tocitem*[3]{Lady Withens Objects}{35}<br/>
+\tocitem*[4]{Back-Hoe to the Rescue}{48}<br/>
+\tocitem*[5]{Invasion of the Dandelions}{63}<br/>
+\tocitem*[~]{\emph{Interlude}}{90}<br/>
+\tocitem*[6]{Army of the Gardeners}{94}<br/>
+\tocitem*[7]{Too Much Rain}{113}<br/>
+\tocitem*[8]{To Nuke, or Not to Nuke?}{145}<br/>
+\tocitem*[9]{Revenge of the Zucchini}{162}<br/>
+\tocitem*[10]{Lady Withens Sneezes}{180}<br/>
+\tocitem*[11]{The Concrete Lawn}{206}<br/>
+\tocitem*{Epilogue}{228}<br/>
+\end{toc}<br/>
+\clearpage
+</code>
+</p>
+<div style="clear:both"></div>
+</div><!-- end 8.1.2 -->
+</div><!-- end 8.2 -->
+
+</div><!-- end 8 -->
+</div><!-- end page08 -->
+<!-- ************************************************************ -->
+<div id="page9" class="page">
+
+
+<h2 id="h9">9. Footnotes and Endnotes</h2>
+<div class="d2" id="d9">
+<p class="item"><b>A.</b> The <i>novel</i> class has <em>limited</em> support for <a href="#h9.1">footnotes</a>. The support is adequate for the needs of fictional works, but not academic works.</p>
+<p class="item"><b>B.</b> There is <em>em</em> limited support for <a href="#h9.2">endnotes</a>. The primary difference between <i>novel's</i> method, and the method used by other document classes, is that <i>novel</i> only places a marker. It does not remember or automate the text of endnotes. You must write the notes yourself.</p>
+<p class="item"><b>C.</b> You may use both footnotes and endnotes.</p>
+<p class="item"><b>D.</b> In the running text, markers for footnotes and endnotes are superscripts. You may control their appearance using the method of <a href="#h6.4">section 6.4</a>.</p>
+<p class="item"><b>E.</b> The actual footnote (at base of page) or endnote (wherever placed) does <i>not</i> use a superscript for its marker. Instead, the marker has ordinary size and position. This is the recommended style.</p>
+<p class="item"><b>F.</b> <b>Margin notes</b> are not supported.</p>
+
+<h3 id="h9.1">9.1. Footnotes</h3>
+<div class="d3" id="d9.1">
+<p class="item"><b>A.</b> Footnotes appear at the bottom of the page where they are placed. There is no option to accumulate them to another location. Very long footnotes might straddle pages, but that is automatic, and not within your control.</p>
+<p class="code"><code>\footnote[<em>option</em>]{<em>text</em>}</code></p>
+<p class="item"><b>B.</b> The <code>\footnote</code> command places a <a href="#h6.4">superscript</a> "marker" at the place where the command is written. The included text is written at the bottom of the page, beneath a short line that separates it from the main text. The footnote text is at smaller size and line skip, and has the same marker placed before it (but not as superscript). All of this is automatic.</p>
+<p class="item"><b>C.</b> You may, if necessary, apply some style to the footnote text. For example, if you are referring to another work, its title might be in italics.</p>
+<p class="item"><b>D.</b> Normally, no option is used. If you use option <i>0</i> (zero) then no marker will appear in the main text, and the footnote text will also appear without a marker. The count of markers is not incremented. This applies whether the markers are numbers or symbols.</p>
+<p><b>E.</b> If you are normally using footnote <i>numbers</i>, but wish to place a particular footnote using a <i>symbol</i> instead, you can do it manually. For example:</p>
+<p class="code"><code>He blinked.*\footnote[0]{* No, he didn't.}</code></p>
+<p><b>F.</b> Avoid use of underlining or bold. It is considered bad style, due to visual distraction. If necessary, use italics.</p>
+<p class="item" style="position:relative"><b>G.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> Sorry, but even though there are numerous TeX packages for custom footnote styles, they will not work in <i>novel</i>. This is intentional.</p>
+</div><!-- end 9.1 -->
+
+<h3 id="h9.2">9.2. Endnotes</h3>
+<div class="d3" id="d9.2">
+<p class="item"><b>A.</b> Endnotes are sometimes used in fiction. Often, the endnotes are also fictional.</p>
+<p class="item"><b>B.</b> You may use both footnotes and endnotes. However, if endnotes are used, then footnotes must be marked by symbols, rather than by numbers, to avoid confusion. The counts for endnotes and footnotes are independent.</p>
+<p class="item"><b>C.</b> If you gather endnotes at the rear of your book, then arabic page numbering continues. Think of the endnotes as just another chapter. If you use page headings, then the preferred style is to use something like <i>Notes to Chapters 3-4</i> in the headings, changing it on a page by page basis using <code><a href="#h4.3.4.6">\SetRectoheadText</a></code> and <code><a href="#h4.3.4.6">\SetVersoheadText</a></code>.</p>
+<p class="item" style="position:relative"><b>D.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> The <i>endnotes</i> package may not be used, due to conflict with <i>novel's</i> built-in commands.</p>
+
+<h4 id="h9.2.1">9.2.1. <code>\endnote{<i>comment</i>}</code>, <code>\ResetEndnote</code></h4>
+<div class="d4" id="d9.2.1">
+<p class="item"><b>A.</b> The <code>\endnote</code> command inserts a numerical superscript in the text. A running count of the numbers is automatically updated.</p>
+<p class="item"><b>B.</b> Endnote numbers normally run continuously through the text. If you wish to reset the count (perhaps at new chapters), you have to do it manually, using <code>\ResetEndnote</code> at the appropriate location.</p>
+<p class="item"><b>C.</b> No argument is needed. But if you write <code style="white-space:nowrap">\endnote{<i>some comment</i>}</code>, then the comment will not print. It is merely a note to yourself, reminding you why you put an endnote there. The comment is not stored for later use, so it is not the actual content of the endnote text.</p>
+<p class="item"><b>D.</b> You may not immediately follow <code>\endnote</code> with a square bracket <code>[</code>. If you do that, an error results. If you need to follow the command with a printing square bracket, then use <code>\endnote{}[</code>.
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> The <i>novel</i> class does not know, and does not care, whether or not you actually write the endnotes later. The <code>\endnote</code> command merely places a marker. It does not record data for later use.</p>
+</div><!-- end 9.2.1 -->
+
+<h4 id="h9.2.2">9.2.2. <code>\endnotetext{<i>number</i>}{<i>text</i>}</code></h4>
+<div class="d4" id="d9.2.2">
+<p class="item"><b>A.</b> The built-in <code>\endnotetext{}{}</code> takes two mandatory arguments. No optional argument. If you follow <code>\endnotetext</code> with a square bracket <code>[</code>, then an error results.</p>
+<p class="item"><b>B.</b> The first argument is usually the endnote number. A period and following space will automatically be added. You may use <code>\emph{<em>number</em>}</code> if you prefer the number to be in italics.</p>
+<p class="item"><b>C.</b> The text will be block-indented. It is limited to one paragraph. If the note needs more than one paragraph, then continue like this, with an empty note number:</p>
+<p class="code"><code>\endnotetext{}{\indent <em>text</em>}</code></p>
+<p class="item"><b>D.</b> Example of an endnote:</p>
+<p class="code">
+<code><small>
+\endnotetext{9}{Yang Sho-Nuff was the twelfth son of the elder god of the ancient Who-Zit Clan, with power over the forces of rust.\par}<br/>
+\endnotetext{}{\indent However, since this was not yet the Iron Age, the terrible might of Yang Sho-Nuff was largely unrecognized.\par}<br/>
+\endnotetext{10}{As Professor Withens notes in his treatise, \emph{When Sho-Nuff Was Not Enough}, the ceremony of daily human sacrifice had a devastating effect on the tribal population.\par}
+</small></code></p>
+<p class="centerimg"><img src="html-resources/endnotetext.png" width="447" height="151" alt="using endnotetext"/></p>
+<p class="item" style="position:relative"><b>E.</b> <img src="html-resources/info18.png" width="18" height="18" style="position:relative; bottom:-3px" title="tech info" alt="tech info"/> If you don't like the built-in <code>\endnotetext</code> style, you can change it to suit your needs, using <code>\renewcommand</code>. Coding is up to you!</p>
+</div><!-- end 9.2.2 -->
+</div><!-- end 9.2 -->
+
+
+</div><!-- end 9 -->
+</div><!-- end page09 -->
+<!-- ************************************************************ -->
+<div id="pageA" class="page">
+
+
+<h2 id="hA">Appendix A. Sample Document</h2>
+<div class="d2" id="dA">
+<p class="noindent">If you click on a command, you will be taken to its documentation.
+There are many other commands available, but they are not specific to novel class.</p>
+<div class="sampledoc">
+<p>Non-empty default values are <em>shown like this</em>.<br/>
+&nbsp;</p>
+<p style="text-indent:0">
+<a href="#h1.1.1">% !TeX TS-program = LuaLaTeX</a><br/>
+<a href="#h1.1.2">% !TeX encoding = UTF-8</a><br/>
+<a href="#h2">\documentclass{novel}</a> % See list of class options; usually none needed.<br/>
+%%% METADATA (FILE DATA):<br/>
+<a href="#h3.3.1">\SetTitle{<em>IMPORTANT: Provide Book Title</em>}</a> % Required for PDF/X.<br/>
+<a href="#h3.3.3">\SetSubtitle{}</a> % Default: empty.<br/>
+<a href="#h3.3.2">\SetAuthor{}</a> % Default: empty.<br/>
+<a href="#h3.3.4">\SetApplication{<em>LuaLaTeX with novel and microtype</em>}</a><br/>
+<a href="#h3.3.4">\SetProducer{<em>LuaLaTeX with novel-pdfx and hyperref</em>}</a><br/>
+<a href="#h3.4">\SetPDFX[<em>CGATSTR001</em>]{<em>X-1a:2001</em>}</a><br/>
+%%% DIMENSIONS:<br/>
+<a href="#h4.1.1">\SetTrimSize{<em>5.5in</em>}{<em>8.5in</em>}</a> % Sets width, height of your book.<br/>
+% Default Media Size equals Trim Size.<br/>
+% Rarely-used over-ride, except for cover artwork:<br/>
+% <a href="#h4.1.2">\SetMediaSize[<em>alignment</em>]{<em>width</em>}{<em>height</em>}</a><br/>
+% Default margins vary with Trim Size. Defaults for {5.5in}{8.5in}:<br/>
+<a href="#h4.3.1">\SetMargins{<em>0.5in</em>}{<em>0.5in</em>}{<em>0.5in</em>}{<em>0.75in</em>}</a><br/>
+%%% GENERAL FONTS:<br/>
+% Percent at end of line is necessary, when writing font settings multi-line:<br/>
+<a href="#h4.2.1.1">\SetParentFont[%<br/>
+<em>SmallCapsFeatures={Renderer=Basic},</em></a>% Effective when small caps requested locally.<br/>
+<a href="#h4.2.1.1"><em>Kerning=On,</em> %<br/>
+<em>Ligatures=TeX,</em> %<br/>
+]{<em>Libertinus&nbsp;Serif</em>}</a><br/>
+% Main text font automatically adds <em>Numbers=OldStyle,Ligatures=Common</em>.<br/>
+% Default main font size is based on other layout settings.<br/>
+% Varies from 11pt to 12pt. With all default layouts, value is 11.4pt.<br/>
+% You may manually choose a different main font size:<br/>
+% <a href="#h4.2.1.2">\SetFontSize{<em>length</em>}</a><br/>
+% Default lines per page (main textblock) is calculated from other layout settings.<br/>
+% When using all defaults, the calculated value is 35.<br/>
+% If used, \SetLinesPerPage manually chooses the value:<br/>
+% <a href="#h4.3.2">\SetLinesPerPage{<em>integer</em>}</a><br/>
+<a href="#h4.2.3">\SetDecoFont{<em>NovelDeco.otf</em>}</a><br/>
+<a href="#h4.2.4">\setsansfont{<em>Libertinus Sans</em>}</a><br/>
+<a href="#h4.2.4">\setmonofont{<em>Libertinus Mono</em>}</a><br/>
+<a href="#h4.2.4">\setmathfont{<em>Libertinus Math</em>}</a> % unicode-math<br/>
+%%% HEADERS/FOOTERS:<br/>
+<a href="#h4.3.3">\SetHeadFootStyle{<em>1</em>}</a> % This style has headers only.<br/>
+<a href="#h4.3.4.1">\SetHeadJump{<em>1.5</em>}</a><br/>
+<a href="#h4.3.4.1">\SetFootJump{<em>1.5</em>}</a><br/>
+<a href="#h4.3.4.3">\SetLooseHead{<em>50</em>}</a><br/>
+<a href="#h4.3.4.5">\SetEmblems{}{}</a> % Default blanks.<br/>
+<a href="#h4.3.4.2">\SetHeadFont[<em>\parentfontfeatures,Letters=SmallCaps,Scale=0.92</em>]{<em>\parentfontname</em>}</a><br/>
+<a href="#h4.3.4.4">\SetPageNumberStyle{<em>\thepage</em>}</a><br/>
+<a href="#h4.3.4.6">\SetVersoHeadText{<em>\theAuthor</em>}</a><br/>
+<a href="#h4.3.4.6">\SetRectoHeadText{<em>\theTitle</em>}</a><br/>
+%%% CHAPTERS:<br/>
+<a href="#h5.1.2.1">\SetChapterStartStyle{<em>footer</em>}</a> % Equivalent to empty, when style has no footer.<br/>
+<a href="#h5.1.2.2">\SetChapterStartHeight{<em>10</em>}</a><br/>
+<a href="#h5.1.3.1">\SetChapterFont[<em>Numbers=Lining,Scale=1.6</em>]{<em>\parentfontname</em>}</a><br/>
+<a href="#h5.1.3.1">\SetSubchFont[<em>Numbers=Lining,Scale=1.2</em>]{<em>\parentfontname</em>}</a><br/>
+<a href="#h5.3.1">\SetScenebreakIndent{<em>false</em>}</a><br/>
+%%% CUSTOM FONTS:<br/>
+% <a href="#h4.2.5">\NewFontFamily[]{}</a> % Optional command.<br/>
+% <a href="#h4.2.5">\NewFontFace[]{}</a> % Optional command.<br/>
+% <a href="#hE.2.3">\CreateFontFeature{}{}</a> % Optional command.<br/>
+%%% OTHER:<br/>
+<a href="#h1.1.3">\setdefaultlanguage[<em>variant=american</em>]{<em>english</em>}</a> % polyglossia<br/>
+<a href="#h6">\microtypesetup{<em>config=novel-microtype,stretch=20,shrink=20,final</em>}</a> % microtype<br/>
+%%% BEGIN DOCUMENT:<br/>
+\begin{document}<br/>
+<a href="#hD.3.2">\frontmatter</a> % Required.<br/>
+% Typically <a href="#hB">six pages</a> of front matter, but <a href="#hD.3.2">could be more</a>.<br/>
+<a href="#hD.3.3">\mainmatter</a> % Required<br/>
+% <a href="#h5">Chapters</a> go here. SAMPLE Chapter structure:<br/>
+<a href="#h5.1.1">\clearpage</a> % or <a href="#h5.1.1">\cleartorecto</a><br/>
+<a href="#h5.1.2.3">\begin{ChapterStart}</a><br/>
+\vspace*{2<span style="cursor:help" title="normal baseline skip">\nbs</span>} % Space above chapter title. \nbs = normal baseline skip.<br/>
+<a href="#h5.1.3">\ChapterTitle{</a>— 1 —<a href="#h5.1.3">}</a> % Perhaps also <a href="#h5.1.3">ChapterSubtitle</a>, <a href="#h5.1.3">ChapterDeco</a>.<br/>
+<a href="#h5.1.2.3">\end{ChapterStart}</a><br/>
+It was a dark and stormy night, etc.<br/>
+<a href="#h5.1.1">\clearpage</a> % or <a href="#h5.1.1">\cleartorecto</a><br/>
+\end{document}
+</p>
+</div>
+
+
+</div><!-- end A -->
+</div><!-- end Appendix A -->
+<!-- ************************************************************ -->
+<div id="pageB" class="page">
+
+
+<h2 id="hB">Appendix B. &nbsp; Basic Six-Page Front Matter</h2>
+<div class="d2" id="dB" style="padding-top:0.5em">
+<p class="imgcentered"><img src="html-resources/sixpage-frontmatter.png" width="740" height="189" alt="Six-page front matter, with Epigraph on page v." title="Six-page front matter."/></p>
+<p class="noindent1">In many instances, six pages of front matter are all you need for fiction. This is often true for major publishers, not just self-published P.O.D. authors.</p>
+<p class="noindent1">You can use six pages, provided that:</p>
+<p class="overhang">&bull; Your front matter does not contain material written by someone else (such as a Foreword), no matter how short. Exception: You may use an Epigraph.</p>
+<p class="overhang">&bull; Your front matter contains at most one of the following, limited to a single page: Dedication, Epigraph, Table of Contents, Acknowledgements, Author's Note, Map.</p>
+<p class="noindent2">If both of the above points apply, then your front matter is organized as follows. Be sure that your document begins with the <code>\frontmatter</code> command, and that each page begins with <code>\thispagestyle{empty}</code> and ends with <code>\clearpage</code>.</p>
+
+<h3 id="hB.1">B.1. &nbsp; Half-Title to Copyright</h3>
+<div class="d3" id="dB.1">
+<p class="noindent">The first four pages (i - iv) are the same for nearly every book.</p>
+<p class="overhang"><b>Page i. Half-Title.</b></p>
+<p class="overhang"><b>Page ii. Blank.</b> Alternatively, if you wrote numerous books, you can provide a list of them. However, many print/distribution services will not allow such a list, unless they carry everything on the list.</p>
+<p class="overhang"><b>Page iii. Title Page.</b></p>
+<p class="overhang"><b>Page iv. Copyright Page.</b></p>
+</div><!-- end B.1 -->
+
+<h3 id="hB.2">B.2. &nbsp; Post-Copyright</h3>
+<div class="d3" id="dB.2">
+<p class="noindent">After the copyright page, there may be some variation.</p>
+<p class="overhang"><b>Page v. Varies.</b> One of: Dedication, Epigraph, Table of Contents, Acknowledgements, Author's Note, Map. If you have none of them, then repeat the Half-Title.</p>
+<p>Don't be afraid to simply repeat the Half-Title. Even major publishers do it, when they have nothing else to say in front matter.</p>
+<p class="overhang"><b>Page vi. Blank.</b> Exception: If Page v does not have an Epigraph or Half-Title, you may place an Epigraph here, provided that it does not visually detract from the story that begins on the facing page.</p>
+</div><!-- end B2 -->
+
+<h3 id="hB.3">B.3. &nbsp; Sample TeX Code</h3>
+<div class="d3" id="dB.3">
+<div style="margin-left:32px">
+<p class="code"><code>
+\begin{document}<br/>
+\frontmatter % Sets page number to i.<br/>
+\thispagestyle{empty}<br/>
+% Half-Title Page.<br/>
+\clearpage<br/>
+\thispagestyle{empty}<br/>
+\null % Necessary for blank page.<br/>
+% Alternatively, List of Books.<br/>
+\clearpage<br/>
+\thispagestyle{empty}<br/>
+% Title Page.<br/>
+\clearpage<br/>
+\thispagestyle{empty}<br/>
+% Copyright Page.<br/>
+\clearpage<br/>
+\thispagestyle{empty}<br/>
+% Dedication or Epigraph or TOC or Acknowledgements or Author's Note or Map.<br/>
+% Alternatively, repeat the Half-Title.<br/>
+\clearpage<br/>
+\thispagestyle{empty}<br/>
+\null % Necessary for blank page.<br/>
+% Alternatively, Epigraph if it does not detract from facing page.<br/>
+\clearpage<br/>
+\mainmatter % Sets page number to 1 for following material.
+</code></p>
+</div>
+</div><!-- end B.3 -->
+
+
+</div><!-- end B -->
+</div><!-- end Appendix B -->
+<!-- ************************************************************ -->
+<div id="pageC" class="page">
+
+
+<h2 id="hC">Appendix C. &nbsp; Shopping for Fonts</h2>
+<div class="d2" id="dC">
+<p class="noindent1">Since the <i>novel</i> class uses only <i>LuaLaTeX</i> and <i>fontspec</i> with utf-8 encoding, you may use any Open&nbsp;Type or TrueType font, subject to licensing. You are not limited to TeX fonts.</p>
+<p>Many TeX fonts are only available in older Type 1 format (PostScript). Use of such fonts is <i>strongly discouraged</i>, due to possible issues in <i>novel</i> class (which will not be fixed, if they appear).</p>
+<p>In some other cases, a TeX font package provides both the older format, and a newer Open&nbsp;Type or TrueType format. The different formats will have different font names. Sometimes the difference is very slight. Carefully look at the font name for the Open&nbsp;Type format, using TrueType only as a second choice. Remember that most on-line discussions will refer to the older Type 1 PostScript fonts, simply because they have been around longer. For example: <i>Linux&nbsp;Biolinum</i> is a sans-serif font available via TeX as a PostScript font. But <i>Linux&nbsp;Biolinum&nbsp;O</i> (note the O) is an Open&nbsp;Type font. If you need this font, then call for <i>Linux&nbsp;Biolinum&nbsp;O</i>, not simply <i>Linux&nbsp;Biolinum</i>.</p>
+<p><b>Important:</b> Do not attempt to load a font by the <code>\RequirePackage</code> or <code>\usepackage</code> commands. Instead, if you choose to use fonts other than the defaults, load them via the <a href="#h4.2">font setting commands</a> described in this documentation. If you attempt to load a font the wrong way, you may get an error message, or the font may quietly fail to load.</p>
+
+<h3 id="hC.1">C.1. &nbsp; Licensing Issues</h3>
+<div class="d3" id="dC.1">
+<p class="noindent1">Presumably, you are writing your novel for commercial value, and do not intend to give anything away for free. For that reason, avoid any font licensed under the GPL (GNU Public License) unless it has the <a class="external" rel="external" target="new" href="https://en.wikipedia.org/wiki/GPL_font_exception">font exception</a> clause. Many TeX fonts, and many non-TeX free fonts, are licensed under GPL, but <i>without</i> the relatively-recent font exception clause. Be careful!</p>
+<p>Beware of fonts "free for personal use" from download sites. Your commercial application is not "personal use." Of course, if you like the font, you may purchase its commercial license.</p>
+<p>Also beware of fonts generically labeled as "freeware" with no particular designer name. If you don't know who created the font, then how do you know that it can be given away for free? Even if there is a designer name, some of them had second thoughts about "freeware." They intended the fonts to be free only if you give your own work away for free. But they didn't mention it. Maybe they have no legal recourse, but you don't want them making anonymous negative reviews of your book.</p>
+<p>You have numerous fonts already installed in your operating system, and perhaps others that came bundled with a particular application. If you intend to use those fonts, carefully read their licenses. It is often the case that fonts bundled with an application may <em>only</em> be used for documents created within, or processed by, that application. Or, the fonts may be OK to use for printing directly by your own home printer, but not for embedding in a PDF that will go to a commercial printer.</p>
+<p>Although it does not pertain to TeX, another issue can arise if you later publish an ebook version. Fonts licensed for printing are often not licensed for an ebook. Indeed, the ebook distributor may ban them.</p>
+<p>Always look for a Copyright notice, which can be identified with a particular person or organization. Copyright is good! It means that someone is claiming authorship of the font software. Only the Copyright owner has the right to give the font away for free, or license it to you after payment (often through an intermediary).</p>
+<p>If you prefer free fonts, the most widely accepted license is the <a class="external" rel="external" target="new" href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL">SIL Open Font License</a>. This allows you to use the font for commercial purposes, embed it in PDF, modify it to suit your needs (if you change the font name), and even re-distribute the modifications. The recommended default <i>Libertinus Serif</i> bears this font license. So does the included font <i>NovelDeco</i>.</p>
+</div><!-- end C.1 -->
+
+<h3 id="hC.2">C.2. &nbsp; Technical Issues</h3>
+<div class="d3" id="dC.2">
+<p class="noindent1">Many fonts have technical errors, even among professional fonts. Some of the errors are so minor that they are not worth fixing.</p>
+<p>However, beware of fonts based on traced artwork. The late 1990s had an explosion of amateur dingbat and decorative fonts produced this way, by scanning images from old books and digitizing the scan. The resulting vector glyphs rarely meet standards, and often are quite awful. The problem is that when a commercial printer renders your PDF to print, the printer's software is very different from what you have on your home computer. A technically erroneous glyph might look OK at home, but be rejected commercially.</p>
+<p>If you have the knowledge, you can open a font in font editor software (such as <i>FontForge</i>) and ask it for validation. Missing extrema are rarely a problem, even if a lot of them are missing. Self-intersecting glyphs are not a problem if the the glyph is composed of two elements stuck together, such as Ç composed of C with separate cedilla. However, a self-intersecting glyph may be a problem if its lines criss-cross each other. Open paths, and outer paths drawn the wrong way, are often a problem. If the errors are confined to glyphs that you will not be using, then it can pass.</p>
+</div><!-- end C.2 -->
+
+<h3 id="hC.3">C.3. &nbsp; Appearance Issues</h3>
+<div class="d3" id="dC.3">
+<p class="noindent1">There are general expectations for book fonts, in terms of character sizes and shapes, and weights. Many of the widely-used TeX fonts, including Latin&nbsp;Modern, are unacceptable in fiction for this reason. Times&nbsp;New&nbsp;Roman is not quite acceptable for fiction; but it is often mis-used by amateurs with a word processor.</p>
+<p>The best way to assess a font is to print it to paper, at actual size. Use an inkjet (not laser) printer with only-black cartridge.</p>
+<p>Depending on whom you ask for an opinion, fiction is most easily read when there are about 60 to 66 characters (including spaces) per line. To evaluate a font for the main text, print out some paragraphs about 4" to 4.25" wide, and scale the font's point size so that you get an average number of characters per line in that range. Be sure to do that. Adobe&nbsp;Garamond&nbsp;Pro at 12pt, Libertinus&nbsp;Serif at 11.4pt, and Libre&nbsp;Caslon&nbsp;Text at 9.6pt (!) provide about the same number of characters per line of text. At the proper point size, some fonts will look too dark, and others will look too light.</p>
+<p>Things to look for: (1) Are the lowercase letters too tall? If they are, then it is hard for readers in many Western languages to find where sentences start, by looking for capital letters. Also, there is less white space between lines, which makes the text appear dense and harder to read. (2) Is the shape of the characters so natural that you don't notice them? That's good! It is your writing, not the font, that is to be noticed. (3) Remember that some fonts are designed for use at large size, in posters; such fonts tend to look mechanical in fiction. Other fonts are designed for computer screens; the letters will be too widely-spaced in fiction. Nearly all modern fonts have decent kerning and important ligatures, so that's not usually a decisive factor.</p>
+<p>The prevailing rule: If you notice the font, it's wrong.</p>
+</div><!-- end C.3 -->
+
+
+</div><!-- end C -->
+</div><!--end Appendix C -->
+<!-- ************************************************************ -->
+<div id="pageD" class="page">
+
+
+<h2 id="hD">D. Book Design</h2>
+<div class="d2" id="dD">
+<p class="noindent">Most authors in P.O.D. use an ordinary word processor, particularly MS Word. For that reason, many print services, and most online user forums, refer to the terminology and settings of MS Word, rather than to the meanings in traditional book publishing. In the case of images, Photoshop settings are often described.</p>
+<p>Since you are neither using MS Word nor Photoshop, you must understand the terminology of printed book design. Then, you can apply that knowledge to the physical layout and internal design of your book, using <i>novel</i> document class.</p>
+
+<h3 id="hD.1">D.1. Terminology</h3>
+<div class="d3" id="dD.1">
+<p class="noindent">You <i>must</i> understand these terms, as used in printing.</p>
+
+<h4 id="hD.1.1">D.1.1. Sheet, Page, Leaf</h4>
+<div class="d4" id="dD.1.1">
+<p class="noindent">A <b>sheet</b> of paper is a single, physical piece of paper, regardless of whether anything is printed on it, or where. Often, paper starts out as a large sheet that will subsequently be cut into smaller sheets. The size doesn't matter. A sheet of paper is, in ordinary understanding, a piece of paper.</p>
+<p><img class="floatright" src="html-resources/page-leaf.png" width="490" height="155" alt="page, leaf"/> In a finished book, a <b>page</b> is one side of a <b>leaf</b>. Thus, there are always exactly twice as many pages are there are leaves. From the manufacturer's point of view, a 240-page (double-sided printing) book has 120 leaves, regardless of whether or not anything is printed on the pages, or how they are numbered.</p>
+</div><!-- end D.1.1 -->
+
+<h4 id="hD.1.2">D.1.2. Folio, Spine</h4>
+<div class="d4" id="dD.1.2">
+<p class="noindent">Imagine a single sheet of US Letter 8.5"Wx11"H paper. It has two pages, since you can print on both sides (even if one is empty).</p>
+<p>If you fold that sheet in half across its width, it is still one sheet. But now you have a <b>folio</b>, consisting of two leaves of size 5.5"Wx8.5"H. Each leaf has two pages, so you now have four pages. The fold is at the <b>spine</b>.</p>
+<p>Caution: The term "folio" has several different meanings, even in the narrow field of book publishing. It may refer to folded paper, as mentioned above. Or it may refer to a particular sheet size of paper ("foolscap"). Or, it may simply refer to the number printed on a page. This last use of "folio" is discussed in the context of headers and footers.</p>
+</div><!-- end D.1.2 -->
+
+<h4 id="hD.1.3">D.1.3. Signature, Imposition</h4>
+<div class="d4" id="dD.1.3">
+<p class="noindent"><img class="floatright" src="html-resources/signature.png" width="133" height="102" alt="signature"/> When a book is commercially manufactured, folios are nested to form <b>signatures</b>. The number of folios in a signature is typically 6 to 16 (that would be 24 to 64 pages). If you were hand-making a single book at home, you might use only one folio per signature.</p>
+<p>Now, think about how those pages must be ordered. Suppose a book contains a single signature of 4 folios. The outermost folio is printed with pages 1 and 16 on one side (before folding), and pages 2 and 15 on its other side. The next nested folio has pages 3/14 and 4/13. Nested inside is 5/12 and 6/11. Innermost is 7/10 and 8/9.</p>
+<p>Re-arranging the page order is part of the <b>imposition</b> process. The process may involve tweaking the position of each page slightly, to account for offset due to paper thickness when the folios are grouped into signatures. If numerous folios are printed on a larger sheet of paper before cutting, the process may involve rotating folios so that they waste less paper.</p>
+<p>Your home printer software can probably do imposition for a single-folio design (four pages). Anything beyond that is left to professional software. You don't need to do it. The print service does it for you, automatically.</p>
+</div><!-- end D.1.3 -->
+</div><!-- end D.1 -->
+
+<h3 id="hD.2">D.2. Book Manufacture</h3>
+<div class="d3" id="dD.2">
+<p class="noindent">In many cases, when you choose how your book will be manufactured, you will have <i>at most</i> these choices: Trim Size, interior b/w or color, paper, binding, cover finish. The <i>novel</i> class does not address the particular requirements of color interiors (grayscale is OK, since it is emulated by black and white). When you choose the Trim Size, other options may be limited.</p>
+
+<h4 id="hD.2.1">D.2.1. Perfect Binding</h4>
+<div class="d4" id="dD.2.1">
+<p class="noindent"><img class="floatright" src="html-resources/perfectbinding.png" width="160" height="290" alt="perfect binding"/>Most modern softcover books (and some inexpensive hardcovers) are manufactured using a process named <b>Perfect Binding</b>.
+<p>In Perfect Binding, the signatures are clamped together, and the folded area is removed by a cutting machine. Then there are no longer any folios, just individual leaves.</p>
+<p>The leaves are glued together at the spine, possibly with reinforcement. Note that the glue is not merely at the edge of the leaves; it penetrates the paper slightly, for better strength. Finally, the cover is attached.</p>
+<p>The Perfect Binding method is inexpensive, and is more than adequate for a book that will not receive rough handling. Whether using P.O.D. or a major mass-quantity publisher, most softcover books have been made this way for a long time. Unless you know that your book will be acquired by libraries for addition to their long-term literary collection, there is little reason to have your book manufactured by any other process. The possible exception would be books for small children, which receive rough handling under all circumstances.</p>
+</div><!-- end D.2.1 -->
+
+<h4 id="hD.2.2">D.2.2. Library Binding</h4>
+<div class="d4" id="dD.2.2">
+<p class="noindent">Libraries rarely purchase Perfect Binding books (regardless of soft or hard cover) due to lack of durability in a library environment. The exceptions are popular books of no lasting literary value, and how-to books for evolving technologies. These may be obtained by libraries in the cheapest softcover version, because such books will be discarded long before they wear out.</p>
+<p>Unless you are sure that your book will be acquired by numerous libraries for long-term addition to their collections, there is little reason to produce a quality hardcover version. Not all P.O.D. services offer hardcover. If you do need a hardcover version, then be sure to carefully inquire regarding its manufacture, and preferably obtain a copy of someone else's book manufactured that way.</p>
+<p><img class="floatright" src="html-resources/smythsewn.png" width="177" height="141" title="Smyth sewing" alt="Smyth sewing"/> The best hardcovers, suitable for library use, are made using the <b>Smyth Sewing</b> process. A Smyth Sewn book has signatures of (typically) 12 or 16 folios. But instead of removing the creases after folding, each signature is sewn through its crease using strong thread, onto a durable spine material. The pages will remain attached, even with hard usage. If the spine material is sufficiently flexible, then the book will lie flat when opened.</p>
+<p>Be sure to ask about spine flexibility. The most flexible methods have a soft, curved spine, and are best suited to thick novels. There is also a variety that has a square (flat) spine, which will not quite lie flat when opened. Square-spine Smyth Sewn books seem to be the fashion for documenting intellectual property.</p>
+<p>If a major publisher is producing a book that is sure to be ordered by many libraries, due to its author's popularity or maybe a movie tie-in, then it is likely to be released as a Smyth Sewn hardcover. That's because the production method is affordable in quantity. But on a P.O.D. basis, it is a significant expense.</p>
+<p>Different bindings must have different ISBNs, because they are different products.</p>
+<p>If you are ordering a hardcover edition, and the supplier calls it <b>casebound</b>, be careful. If a hardcover book is Smyth sewn, then it is almost certain to be casebound. But not the other way around! A book can be casebound, without being Smyth sewn.</p>
+</div><!-- end D.2.2 -->
+
+<h4 id="hD.2.3">D.2.3. Other Bindings</h4>
+<div class="d4" id="dD.2.3">
+<p class="noindent">A Perfect Bound softcover cannot be retroactively converted to Smyh Sewn. However, it is possible to convert it to a glued-on casebound. Sometimes the original paper cover will be glued onto the new hard cover. Books of this type are sometimes used as souvenirs.</p>
+<p>If a book has very few copies, intended for permanent archiving (as with patents, and other large legal documents), then in addition to gluing, the pages may be sewn cross-wise at the spine, before attaching a hard cover. This techique is only used when the book must be tamper-resistant. It is not suited to casual reading.</p>
+</div><!-- end D.2.3 -->
+
+<h4 id="hD.2.4">D.2.4. Paper and Cover Materials</h4>
+<div class="d4" id="dD.2.4">
+<p class="noindent">The interior paper may be white or "creme" (off-white). White paper is generally used for nonfiction, and must be used if there are interior color images (<i>novel</i> does not do interior color). Creme paper is generally used for fiction. The idea is that white paper creates an air of authority, whereas creme paper is more comfortable for lengthy reading. I agree. I recently read a novel that was (mis-) printed on white paper, and it was hard to read in a bright area. So, for your novel, choose creme paper.</p>
+<p>The cover of a Perfect-Binding softcover book may be produced with a glossy or a matte finish. The fashion is to use glossy for nonfiction, matte for fiction. Again, the idea is authority versus comfort. But you may choose what you wish. "Instant Best-Seller" mass-market paperbacks often have an embossed texture, and maybe even metal foil. In the print-on-demand market, forget it. Don't even think about it.</p>
+<p>If you do request a hardcover edition, then it may or may not have a dust jacket (costs extra). The general rule is that books for libraries have a dust jacket, which will be encased in plastic by the library. Books for documentation generally have no dust jacket, with the title and other info embossed in the cover material, for permanance. If the printer offer harcover, but does not even offer you the option of purchasing a dust jacket, then beware: Are you sure that the book is <a href="#hD.2.2">Smyth Sewn</a>?</p>
+</div><!-- end D.2.4 -->
+</div><!-- end D.2 -->
+
+<h3 id="hD.3">D.3. Interior Structure</h3>
+<div class="d3" id="dD.3">
+<p class="noindent">This section discusses how a book is designed, in terms of its component pages, where they are placed, and how they are styled. The emphasis is on popular fiction. Some sections that would be required in a dissertation or other nonfiction, are much rarer in popular fiction, or are entirely missing. There is also considerable "wiggle room" in terms of structure, particularly for genres that <i>pretend to be</i> a truthful report of someone else's writing.</p>
+<p>The advice you are about to receive is <em>not</em> authoritative. It is combined from <i style="cursor:help" title="Chicago Manual of Style">CMoS</i> (which focuses on nonfiction) and on actual practice, as I have seen by looking through numerous professionally-published works of popular fiction at the local public library. There is a certain amount of variation.</p>
+
+<h4 id="hD.3.1">D.3.1. Display Pages vs. Chapter-Like Sections</h4>
+<div class="d4" id="dD.3.1">
+
+<h5 id="hD.3.1.1">D.3.1.1. Display Pages</h5>
+<div class="d5" id="dD.3.1.1">
+<p class="noindent">A <em>Display Page</em> has its own design, and stands by itself. Examples are Half-Title, Title, Copyright, Dedication, Epigraph, Table of Contents, Map, Part Separator, and of course Blank.</p>
+<p>Half-Title, Title, Dedication, and Part Separators are always single-page recto. A Table of Contents begins recto, but may continue verso. An Epigraph is single-page, and may be recto or verso.</p>
+<p>Maps are one per page, and may be recto or verso. If you intend to create a large map that spreads verso-recto, be aware that the technology you will be using does not allow continuous image through the spine area. Instead, you must create two separate maps, one per page. There will be the usual inside margins.</p>
+<p>A Blank page is almost always verso; the only exception is when multiple blanks appear at the very end of the book.</p>
+<p>Each kind of display page has its own style, and position. What they have in common is that all of them lack a header or footer (and thus, lack a printed page number). Use <code>\thispagestyle{empty}</code>.</p>
+<p>If a display page extends to a second page (such as Table of Contents), then use <code>\thispagestyle{empty}</code> at its begining and end, to ensure that both pages omit header and footer.</p>
+</div><!-- end D.3.1.1 -->
+
+<h5 id="hD.3.1.2">D.3.1.2. Chapter-Like Sections</h5>
+<div class="d5" id="dD.3.1.2">
+<p>A <em>Chapter-Like Section</em> includes things that are styled like a chapter. This includes Foreword, Preface, Introduction, Author's Note, Acknowledgements, Prologue, Chapters, Epilogue, Conclusion, Endnotes.</p>
+<p>Almost all Chapter-Like Sections begins recto. However, chapters <i>after</i> Chapter One may begin recto or verso. If there is subsequent material (Epilogue, Conclusion, Endnotes, etc.) then the begin-recto rule applies.</p>
+<p>The first page of a Chapter-Like Section section has no header, but <i>may</i> have a footer with page number. See the available choices for <code><a href="#h4.3.5.1">\thispagestyle</a></code>.</p>
+<p>Remaining pages in the section will have such header/footer style as pertains to ordinary chapters in the book. Exception: If a Chapter-Like Section in front matter is only two pages long, then you may optionally omit the header, or footer, on both pages. Then, use <code>\thispagestyle</code> at the end of the section, with choice that matches its beginning.</p>
+<p>When a Chapter-Like Section appears in front matter, its page headers (if any) do <em>not</em> show the author and title of the book, the way they would appear in main matter. Instead, they show the name of the section (such as Author's Note) both verso and recto. Commands <code><a href="#h4.3.4.6">\SetVersoHeadText</a></code> and <code><a href="#h4.3.4.6">\SetRectoheadText</a></code> are your friends, as they permit you to dynamically change header text as you move through the book.</p>
+</div><!-- end D.3.1.2 -->
+</div><!-- end D.3.1 -->
+
+<h4 id="hD.3.2">D.3.2. Front Matter</h4>
+<div class="d4" id="D.3.2">
+<p class="noindent">The <code><b>\frontmatter</b></code> command must be written immediately after <code>\begin{document}</code>. This sets page numbering to lowercase roman, and performs some other actions.</p>
+<p>A book's front matter is <em>about the book</em>. It is not part of the story. The only mandatory front matter is the Title Page and its verso, the Copyright Page. On a practical basis, six pages of front matter are the minimum, and this minimum is often used, even by major publishers. See <a href="#hB">Appendix B</a> for how to construct basic six-page front matter.</p>
+
+<h5 id="hD.3.2.1">D.3.2.1. Half-Title, page i</h5>
+<div class="d5" id="dD.3.2.1">
+<p class="noindent"><p>Some book manufacturers (particulary in hardcover) place a blank or decorative <em>flyleaf</em> before any part of the book interior. A flyleaf (if present) is added at the bookbinding factory, and is not part of your book's interior PDF file.</p>
+<p>Your book's first interior recto page is a Half-Title. It is a <a href="#hD.3.1.1">Display Page</a>. Historically it was a protective page for the full title page, in the era when a printed interior was not immediately bound. That tradition lives on.</p>
+<p>The Half-Title contains nothing but the book's title. No subtitle. It should be styled in the same manner as is used on the full Title Page, but typically smaller. You can place the title anywhere it looks good. It is almost never placed upper left.</p>
+</div><!-- end D.3.2.1 -->
+
+<h5 id="hD.3.2.2">D.3.2.2. Blank, page ii</h5>
+<div class="d5" id="dD.3.2.2">
+<p class="noindent">Verso page ii is a <a href="#hD.3.1.1">Display Page</a>. In most cases, it will be blank. This is achieved by using <code>\cleartorecto</code> at the end of the Half-Title page. But if you wish to manually create a blank page, verso or recto:</p>
+<p class="code"><code>
+\clearpage\thispagestyle{empty}\null\clearpage</code></p>
+<p>Instead of blank, prolific authors may show a list of their books. However, even if you wrote other books, many print services won't allow you to list them, unless the same service exclusively carries all of them.</p>
+<p>Major publishers may provide an advertisement for the related movie. In the good old days (looong ago) an expensive book might have a high-quality illustration, known as <b>Frontispiece</b>. Unless you truly know what you are doing, avoid these, and just use a blank page.</p>
+<p>At the very fancy end of book design, or often for children's picture books, the full title uses two pages, beginning here and ending on the usual title page iii. You can do that, but <i>novel</i> does not provide for continuing an image (or text) across the spine. Each page is independent, and there will be the usual inside margins. So, a two-page title is not recommended.</p>
+</div><!-- end D.3.2.2 -->
+
+<h5 id="hD.3.2.3">D.3.2.3. Title Page, iii</h5>
+<div class="d5" id="dD.3.2.3">
+<p class="noindent">The Title Page is a recto <a href="#hD.3.1.1">display page</a>. It shows the title, subtitle (if any), and author. These elements are often very decorative, and may involve imagery. They must exactly match the information you provided when you obtained the book's ISBN. Exception: Some services allow the author's name to use initials.</p>
+<p>If there is a publisher's imprint, it goes at the base. This is achieved by using <code>\vfill</code> just above it.</p>
+<p>Remember that a self-publishing service is not the publisher; <em>you are</em>. That's why it is called self-publishing. If you don't have anything else to put there, and don't like leaving the base of the page empty, you might use "Independently Published in Your City, YourState" or something similar.</p>
+<p>&bull; Note: Others have written (and I agree) that the surest sign that a book was written by an amateur, is when the Title Page simply uses the book's main text font (perhaps bold and larger). That has "term paper" written all over it. Instead, be creative.</p>
+</div><!-- end D.3.2.3 -->
+
+<h5 id="hD.3.2.4">D.3.2.4. Copyright Page, iv</h5>
+<div class="d5" id="D.3.2.4">
+<p class="noindent">The Copyright Page is a verso <a href="#hD.3.1.1">display page</a>. It is primarily legalistic in nature, providing essential details about the book, as an item in commerce.</p>
+<p>Some nations require specific information to appear on a Copyright Page. That is your responsibility to know, and is beyond the scope of this documentation.</p>
+<p>At least in the U.S.A., the nation where the book is printed must be indicated, either on the Copyright Page or some other allowed location (such as the final verso). Many print-on-demand services use multiple printers, which may be in various nations, depending on who purchases your book. With the services I have used, this is solved by omitting "Printed in the United States of America" on the Copyright page, because it may not be true. At the printing factory, the necessary information is added by them, as a Colophon on the final verso page. This is one reason why that final verso page must be blank (in your PDF). Ask your P.O.D. service.</p>
+<p>A Copyright Page is in ordinary text, perhaps using minimal styling such as italics or small caps. In all cases, its overall page style must differ from the page style of main text. Almost always, the content of the Copyright Page is forced downward, so that excess white space is on top, and the final line appears at the base of the textblock. This is achieved using <code>\null\vfill</code> at the beginning of the page.</p>
+<p>The <i>legalese</i> environment prevents hyphenation, aligns paragraphs ragged-right (instead of justified), and omits paragraph indents. This style is widely used for a Copyright Page. Be sure to use <code>\null</code>, or a similar vertical spacing command, to separate paragraphs. If you nest the <code>center</code> environment within <i>legalese</i>, it will over-ride the ragged-right alignment.</p>
+<p>The <i>adjustwidth</i> environment can be used to set the width of the lines at less than the full width. This is especially helpful if you have little to say, and choose to center the content.</p>
+<p>Always review where lines break, if necessary inserting manual line breaks, to ensure that the meaning is sensible.</p>
+<p>If you use them, certain words or phrases such as <span style="text-transform:lowercase; font-variant:small-caps">FIRST EDITION</span> are traditionally set in all small caps. Use <code>\allsmcp{FIRST EDITION}</code>.</p>
+<p>Numbers, such as date and ISBN, may be Old Style or Lining. The text default is probably Old Style. If you prefer Lining (looks more legalistic), then use <code>\lnum{<em>numbers</em>}</code>. Anything other than digits (and related characters) will remain unchanged by the <code>\lnum</code> command.
+<p>The Copyright Symbol © is pasted from a Unicode character map. Avoid using TeX code.</p>
+<p>I have never seen a Copyright Page extend to a second page. Never. If you have that much to say, it may be that some of the information may be moved to an Author's Note or Acknowledgements section. Or, if necessary, you may use the <a href="#h6.1.3">parascale</a> environment to slightly shrink the text and baseline skip.</p>
+<p>If you have a Cataloging-in-Publication data block (probably you do not), then be aware that its content may be provided to you in MS Word format. Pay attention to indents, as they are part of how the data is presented. Use <code>\forceindent</code> or <code>\backindent</code> to over-ride the normal indentation (or lack thereof). Use the <i>adjustwidth</i> environment for block indents, but be aware that nesting one <i>adjustwidth</i> inside another may cause problems. It is better to end one <i>adjustwidth</i> before beginning a new one.</p>
+<p>Also, CIP data uses emdash in places. MS Word may represent an emdash with <i>two</i> hyphens, whereas TeX uses <i>three</i> hyphens. Better to simply paste the emdash from a Unicode character map, which will appear the same in both MS Word and TeX.</p>
+<p>If you need straight apostrophe or straight quotes, use <code>\straightquote{}</code> and <code>\straightdblquote{}</code> to insert a character that won't be converted to curly.</p>
+</div><!-- end D.3.2.4 -->
+
+<h5 id="hD.3.2.5">D.3.2.5. Dedication</h5>
+<div class="d5" id="dD.3.2.5">
+<p class="noindent">If you use a Dedication, it is a recto <a href="#hD.3.1.1">display page</a>, and must be placed immediately facing the Copyright Page.</p>
+<p>A Dedication is not required. But sadly, nowadays many authors write a frivolous Dedication, which detracts from the book. If you feel that you need a Dedication, why not put it on your web site? Then you can always edit or remove it, if the subject of your affection runs off with someone else (or, you do). Keep it simple.</p>
+<p>A Dedication is centered. If it is more than a few words, use the <i>adjustwidth</i> environment to keep it bounded, as you would for an Epigraph.</p>
+</div><!-- end D.3.2.5 -->
+
+<h5 id="hD.3.2.6">D.3.2.6. Epigraph</h5>
+<div class="d5" id="dD.3.2.6">
+<p class="noindent">If you use an Epigraph, it is a <a href="#hD.3.1.1">display page</a>, which may be placed verso or recto.</p>
+<p>An Epigraph is optional. It is a short quotation, traditionally from a work by someone else. Its purpose is to set the tone of your own book, or shamelessly imply that your own talents resemble that of the person quoted. However, even though it is short, do not place copyrighted material there, unless you have the necessary legal permission. You probably don't, so forget about quoting a famous contemporary author or performer. Quotations from the Bible, Shakespeare, and Nineteenth-Century authors are popular; but even then, a more recent translation may be still under copyright.</p>
+<p>Alternatively, you can quote from your own book, or make up something entirely new. One famous Epigraph is used in J.R.R. Tolkien's <i>Lord of the Rings</i> trilogy, in which each book uses the long form of the Ring's incantation as its Epigraph.</p>
+<p>One possible use of an Epigraph is on recto page v, in books that lack a Dedication, a Table of Contents, or other important front matter beyond the Copyright Page. Alternatively, if a book has both Dedication and Table of Contents, an Epigraph may be placed on the otherwise-blank verso page vi between them. Or, an Epigraph may appear in some later convenient place in front matter.</p>
+<p>In general, an Epigraph is set as a centered block, not occupying the full page width. The <i>adjustwidth</i> environment serves this purpose. You will have to manually adjust the widths at left and right, for best visual effect.</p>
+<p>The source of the quotation should be right-justified within the block, and may be preceded by an emdash. Typically, names of people are not italicized, but titles of books are. It is not necessary to give elaborate details; this is not a bibliography.<p>
+<p>It is not necessary to load the <i>epigraph</i> package. Simply construct your own style of epigraph using other methods. But if you do load <i>epigraph</i>: Only use <code>\epigraph</code>, or the <code>epigraphs</code> environment, within the ChapterStart environment, or on a display page. Commands <code>\epigraphhead</code>, <code>\dropchapter</code>, <code>\undocrop</code> do not work in <i>novel</i>. The <code>\cleartoevenpage[<i>option</i>]</code> command does work. Ignore the material regarding epigraphs on part pages or in bibliographies.</p>
+
+<h6 id="hD.3.2.6.1"><span class="n"></span>D.3.2.6.1. Example Epigraph: Real Quotation</h6>
+<div class="d6" id="uD.3.2.6.1">
+<p class="noindent">This might be used for an action adventure:</p>
+<p class="code"><img class="floatright" src="html-resources/shakepi.png" width="131" height="208" alt="sample epigraph: Shakespeare"/>
+<code><small>
+\clearpage<br/>
+\thispagestyle{empty}<br/>
+\vspace*{10<span style="cursor:help" title="normal baseline skip">\nbs</span>}<br/>
+\begin{adjustwidth}{7em}{7em}<br/>
+Cowards die many times before their deaths;\\<br/>
+The valiant never taste of death but once.\par<br/>
+\stake\hfill---Shakespeare\par<br/>
+\end{adjustwidth}<br/>
+\clearpage
+</small></code></p>
+<div style="clear:both"></div>
+</div><!-- end D.3.2.6.1 -->
+
+<h6 id="hD.3.2.6.2"><span class="n"></span>D.3.2.6.2. Example Epigraph: Imaginary Quotation</h6>
+<div class="d6" id="uD.3.2.6.2">
+<p class="noindent">This might be used for contemporary fiction with a humorous style. The fictional speaker will appear as a character in the book:</p>
+<p class="code"><img class="floatright" src="html-resources/dorfmcnorf.png" width="131" height="208" alt="sample epigraph: imaginary"/>
+<code><small>
+\clearpage<br/>
+\thispagestyle{empty}<br/>
+\vspace*{10<span style="cursor:help" title="normal baseline skip">\nbs</span>}<br/>
+\begin{adjustwidth}{7em}{7em}<br/>
+Let me tell you, there's nothing more exciting than the brouhaha at Mickey's Pub each Saturday night in April.\par<br/>
+\stake\hfill---Dorf McNorf\par<br/>
+\end{adjustwidth}<br/>
+\clearpage
+</small></code></p>
+<div style="clear:both"></div>
+</div><!-- end D.3.2.6.2 -->
+</div><!-- end D.3.2.6 -->
+
+<h5 id="hD.3.2.7">D.3.2.7. Table of Contents</h5>
+<div class="d5" id="dD.3.2.7">
+<p class="noindent">If you use a Table of Contents, it is a <a href="#hD.3.1.1">display page</a>, beginning recto. If a second page is needed, add <code>\thispagestyle{empty}</code> after the table completes, but before you clear that page.</p>
+<p>Most fiction does not have, and does not need, a Table of Contents. It is more useful when the story consists of discrete episodes with distinctive names, not just numbers. Or, if the book is a collection of short stories, a table of contents is suggested. If your book is a critical edition, or has sections by different authors, then a Table of Contents is mandatory.</p>
+<p><img src="html-resources/simpletoc.png" class="floatright" width="232" height="342" title="simple table of contents" alt="simple table of contents"/> A basic Table of Contents uses the <i>center</i> environment, so that the Table's title and each entry appear centered on the page, without any fancy layout. The text may be italics. So simple. So effective. However, if you prefer a more formal, rectangular table, <i>novel</i> has its own <code><a href="#h8.1">toc environment</a></code>.</p>
+<p>Avoid any of the table environments that come with TeX or its packages. These do not provide the most attractive presentation for fiction, without a lot of work on your part. But if you wish the use them, do it using <a href="#h2.2">sandbox</a> mode.</p>
+<p>A Table of Contents has no header or footer, and no printed page number. Use <code>\thispagestyle{empty}</code>. If it continues to a second page, add <code>\thispagestyle{empty}</code> at the end, if you don't know where the page breaks.</p>
+<p>Anything preceding a Table of Contents is not listed in the table. Neither is the table itself. An Epigraph is normally not listed, even if it follows the table.</p>
+<p>You may or may not list maps or other illustrations in the table. Fiction rarely has more than a map or two, easily located in front matter by the reader, so there's no need to mention them. Use your judgement. That's different from the practice in nonfiction, especially academic works, where the illustrations convey factual data rather than artistry.</p>
+</div><!-- end D.3.2.7 -->
+
+<h5 id="hD.3.2.8">D.3.2.8. Foreword, Preface, Introduction</h5>
+<div class="d5" id="dD.3.2.8">
+<p class="noindent">A Foreword, Preface, or Introduction is a <a href="#hD.3.1.2">Chapter-Like Section</a>, beginning recto.</p>
+<p>A <i>Foreword</i> is written by someone other than the author. It is essentially a marketing tool, by which the publisher addes credence to the work, or mere publicity, by having an expert or celebrity write something in front matter. Introductions are common in nonfiction, but extremely rare (I have never seen one) in fiction, except for critical editions of older works (where the new, original material is essentially nonfiction).</p>
+<p>A <i>Preface</i> is written by the author, speaking as author, and may include a general discussion of how the author came to write the book. It may also include acknowledgements, if they are not in a separate section. A Preface is rather formal, and very rare in popular fiction. If you wish to address the reader, the less-formal <i>Author's Note</i> is better for your purpose.</p>
+<p>An <i>Introduction</i>, when used in front matter, is written by the author. Its purpose is to provide sufficient background for understanding the material that is to follow. Thus, an Introduction is sometimes seen in the front matter of historical or technical nonfiction.</p>
+<p>An Introduction in front matter is inappropriate for popular fiction, but I suppose it <i>might</i> be used for the purpose of world-building in that genre, where the main story assumes that the reader is familiar with the setting. In such a case, the setup is described by the author (as author), but <i>not</i> by a character in the story. Also see <i>Author's Note</i>.</p>
+<p>A Foreword, Preface, or Introduction is a "chapter-like" section. That is, its style is the same as if it were a chapter, in terms of how it is titled, and the use of page header/footer. But there is a significant exception: If your book design uses header text, you do <i>not</i> write the author and title in headers. Instead, you use <code>\SetVersoHeadText</code> and <code>\SetRectoHeadText</code> to write Foreword, Preface, or Introduction in both. See the example <a href="#hD.3.2.10">Author's Note</a>, below, for how this is done.</p>
+<p>A Foreword or Preface is often signed at the end by its writer, with place and date. A lengthy Foreword might instead place its writer's name and credentials under the Foreword title.</p>
+</div><!-- end D.3.2.8 -->
+
+<h5 id="hD.3.2.9">D.3.2.9. Acknowledgements</h5>
+<div class="d5" id="dD.3.2.9">
+<p class="noindent">If you use Acknowledgements, it begins recto. If very short, style it as a <a href="#hD.3.1.1">Display Page</a>, possibly even using limited text width (as with an <a href="#hD.3.2.6">Epigraph</a>, above). Otherwise, it is a <a href="#hD.3.1.2">Chapter-Like Section</a>.</p>
+<p>Most fiction doesn't need acknowledgements. Don't write Acknowledgements just because you can. Acknowledgements are for those who provided real assistance. If you want to provide a shout-out to your friends for their encouragement, consider doing it on a web page.</p>
+<p>If you have a Preface or Author's Note, you can often include acknowledgements there (if you wish), rather than in separate Acknowledgements.</p>
+<p>If styled like a chapter, in a book that has page headers, the verso and recto head text is set to Acknowledgements, not the author and title. Then, the opening page of Acknowledgements has no header (as with a chapter), but following pages have the header. See the Author's Note, below, for how this is done.</p>
+</div><!-- end D.3.2.9 -->
+
+<h5 id="hD.3.2.10">D.3.2.10. Author's Note</h5>
+<div class="d5" id="dD.3.2.10">
+<p class="noindent">If you use an Author's Note, it begins recto. If very short, style it as a <a href="#hD.3.1.1">Display Page</a>, possibly even using limited text width (as with an Epigraph, above). Otherwise, it is a <a href="#hD.3.1.2">Chapter-Like Section</a>.</p>
+<p>An Author's Note directly addresses the reader, from the author. It is often signed with name, place, and date at the end. There is no particular content. Some authors point out that a particular element of the story, which seems fictional, is actually based on a real historical event. Others babble their life stories, and how they came to write the book. Others use it as a catch-all, including acknowledgements and whatever else fits.</p>
+<p>There is some wiggle room regarding whether the Author's note is fact or fancy. For example, in the "lost manuscript" genre, authors may (fictionally) tell how the manuscript came into their hands; but a lengthy tale of discovery is better placed in main matter, as a fictional Introduction.</p>
+<p>If an Author's Note is two pages long, then on the second page use the same page style that you would ordinary use to start a chapter. Normally, this is <code>\thispagestyle{footer}</code>.</p>
+<p>If an Author's Note is three or more pages long, then a header is permitted (if the book's main style has header). You may allow author and title to appear in header text, but it is better to indicate that this is <em>not</em> the main story, using <code>\SetVersoHeadText{Author's&nbsp;Note}</code> and <code>\SetRectoHeadText{Author's&nbsp;Note}</code>.</p>
+
+<h6 id="hD.3.2.10.1"><span class="n"></span>D.3.2.10.1. Example Author's Note</h6>
+<div class="d6" id="uD.3.2.10.1">
+<p class="noindent">In a book of historical fiction, based on the author's own travels and expertise:</p>
+<p class="code"><code><small>
+\cleartorecto % begins recto<br/>
+\SetVersoHeadText{Author's Note}<br/>
+\SetRectoHeadText{Author's Note}<br/>
+\begin{ChapterStart} % because chapter-like<br/>
+\null\null<br/>
+\ChapterTitle{Author's Note}<br/>
+\end{ChapterStart}<br/>
+After many years of studying the late Roman Empire... \lipsum[1]<br/>
+The Third-Century burial practices of the Alemanni... \lipsum[1-2]<br/>
+I have taken great liberty with the likely behavior... \lipsum[1]<br/>
+The battles with Roman forces are entirely imaginary... \lipsum[1-2]<br/>
+Finally, I would like to thank... \lipsum[1]<br/>
+\null<br/>
+\stake\hfill \textsc{Dirk Hardcase}\par<br/>
+\stake\hfill Springfield, September 22, 2016\par<br/>
+\clearpage<br/>
+% Be sure to re-set the verso and recto head texts!
+</small></code></p>
+<p class="centerimg"><img src="html-resources/authorsnote.png" width="813" height="415" alt="sample author's note in frontmatter"/></p>
+<div style="clear:both"></div>
+</div><!-- end D.3.2.10.1 -->
+</div><!-- end D.3.2.10 -->
+
+<h5 id="hD.3.2.11">D.2.1.11. Map</h5>
+<div class="d5" id="dD.3.2.11">
+<p class="noindent">A Map is a <a href="#hD.3.1.1">Display Page</a>, which may be verso or recto. You may use more than one Map, but be aware that in the printing technology available to you via <i>novel</i> class, a single Map cannot be continued as a spread across the spine; you must break it into two independent Maps, allowing for the inside margins.</p>
+<p>Many works of fiction have a map or other diagram. It might be the map of a real or fictional geographic area. It might be the map of a crime scene. It might be an inheritance chart. Even though fictional, it is usually placed in front matter, presumably because a map does not actually tell any part of the story.</p>
+<p>I have seen maps placed very early, or very late, in front matter. The general rule seems to be, "put it where it fits." However, do not place a map where some other item <i>must</i> be located, and do not place a map on the final verso that faces the beginning of main matter, due to its visual distraction.</p>
+<p>A single map, or maybe two, need not be mentioned in a table of contents or illustrations. If you have a lot of them strewn around the book, then they should be listed in such a table; but this is very rare in fiction.</p>
+<p>As with all images, a map must be placed using <i>novel's</i> own <a href="#h7">image placement methods</a>.</p>
+
+<h6 id="hD.3.2.11.1"><span class="n"></span>D.3.2.11.1. Example Map</h6>
+<div class="d6" id="uD.3.2.11.1">
+<p class="noindent">Typically, there will be nothing but the single image on a Map page, with all text self-contained. But in this example, the image only occupies part of the page. It is followed by ordinary text for the numbered locations:
+<p class="code"><img class="floatright" src="html-resources/map.png" width="178" height="274" alt="sample map"/>
+<code><small>
+\clearpage<br/>
+\thispagestyle{empty}<br/>
+\FloatImage{areamap.png} <span class="ap">% b/w</span><br/>
+\vspace{2<span style="cursor:help" title="normal baseline skip">\nbs</span>}<br/>
+\begin{center}<br/>
+1. Alice Springs\\<br/>
+2. Tuktoyaktuk\\<br/>
+3. Pflugerville\\<br/>
+4. Pucallpa\\<br/>
+5. Kolwezi\\<br/>
+6. Dushanbe\\<br/>
+7. Mittenwald\\<br/>
+8. Sanya\\<br/>
+9. Ice Station 414\par<br/>
+\end{center}<br/>
+\clearpage
+</small></code></p>
+<div style="clear:both"></div>
+</div><!-- end D.3.2.11.1 -->
+</div><!-- end D.3.2.11 -->
+
+<h5 id="hD.3.2.12">D.3.2.12. Second Half-Title</h5>
+<div class="d5" id="dD.3.2.12">
+<p class="noindent">In many cases, front matter has very little content. After the Copyright Page, there is nothing else to say. But it is visually bad practice to go directly from verso Copyright Page to the start of the story on recto page 1. This can be solved by repeating the Half-Title as recto page <i>v</i>, with blank verso page <i>vi</i>. I've seen it with major writers and major publishers.</p>
+<p>You can do the same thing with longer front matter, if it would otherwise end on a verso page.</p>
+<p>When there is a lot of front matter (no particular amount), it is customary to use a second Half-Title to mark the boundary where front matter finally ends.</p>
+<p><i style="cursor:help" title="Chicago Manual of Style">CMoS</i> recommends that a second Half-Title be the first page of main matter. Thus, it would be page 1, with the actual story beginning on page 3. But it acknowledges that a <i>common practice</i> is for a second Half-Title and its verso to remain part of front matter, so that main matter begins with the story on page 1. Although I have seen a few books that follow the <i style="cursor:help" title="Chicago Manual of Style">CMoS</i> recommendation, it appears that the great majority of them follow the <i>common practice</i>.</p>
+<p>If your book has <a href="#hD.3.3.2">Part Separators</a> in main matter, then you can do without a second Half-Title.</p>
+</div><!-- end D.3.2.12 -->
+
+<h5 id="hD.3.2.13">D.3.2.13. Final Page of Front Matter</h5>
+<div class="d5" id="dD.3.2.13">
+<p class="noindent">The final page of front matter is always verso. It is almost always blank. The easiest way to insert a blank page is to write <code>\cleartorecto</code> at the end of the preceding recto page.</p>
+<p>Why is the final page of front matter almost always blank? It is because it faces the opening page of the main story, and you don't want to show anything that detracts from the scene or mood. But there are exceptions. For example, an Epigraph might usefully contribute to the setting. Or, in the case of an old-style English murder mystery (where you already know that the murderer did it with arsenic to inherit the family estate), a map of the estate, or a family tree, would not detract from the setting. The choice is yours.</p>
+</div><!-- end D.3.2.13 -->
+</div><!-- end D.3.2 -->
+
+<h4 id="hD.3.3">D.3.3. Main Matter</h4>
+<div class="d4" id="dD.3.3">
+<p class="noindent">Main matter begins with the <code>\mainmatter</code> command. It forces its page to recto, changes the page numbering to Arabic, and sets the count to 1.</p>
+<p>Main matter is <i>the story itself</i>. In some cases, this also includes a fictional setup (Introduction or Prologue) that leads to the longer story line. It also includes material in the aftermath of the story, such as Epilogue, Conclusion, and end notes.</p>
+
+<h5 id="hD.3.3.1">D.3.3.1. Half-Title in Main Matter ?</h5>
+<div class="d5" id="dD.3.3.1">
+<p class="noindent">The <i style="cursor:help" title="Chicago Manual of Style">CMoS</i> prefers that a second Half-Title page (if used) mark the beginning of main matter. Thus, it would be page 1 (number not printed). Then, the story begins on page 3.</p>
+<p>However, <i style="cursor:help" title="Chicago Manual of Style">CMoS</i> also notes that this is not the regular practice, especially with fiction. In fact, among the many popular fiction books I have inspected, when a second Half-Title is used, it is <i>almost</i> always the last recto page of front matter, followed by a blank verso; then main matter begins with page 1 of the story.</p>
+<p>The choice is yours. I suggest agreeing with regular practice: If you use a second Half-Title, keep it in front matter.</p>
+</div><!-- end D.3.3.1 -->
+
+<h5 id="hD.3.3.2">D.3.3.2. Part Separator in Main Matter</h5>
+<div class="d5" id="dD.3.3.2">
+<p class="noindent">If used, a Part Separator is a recto <a href="#hD.3.1.1">Display Page</a>.</p>
+<p>Some books are partitioned into distinct sub-books. A sub-book is of substantial length, not individual chapters or short stories.</p>
+<p>If your book has distinct sub-books, then each of them has its own recto cover page, known as a Part Separator. Its verso is blank or an Epigraph. Then the accompanying story begins recto.</p>
+<p>A Part Separator is <i>always</i> main matter. So, the first Part Separator is <i>always</i> page 1 (number not printed). Then its text begins on page 3. Do not re-initialize the page count when you get to the next Part Separator.</p>
+<p>Part separators could be simply <i>Part I</i>, <i>Part II</i>, and so forth. They could be <i>Book I</i>, <i>Book II</i>. Or, they could have distinctive titles, such as <i>The Northern Front</i> and <i>The Southern Front</i>. If your book is two novelettes in one, then the Part Separators would be the title (and subtitle, if any) of the individual novelettes. Sometimes a Part Separator has a brief description of its purpose, as in <i>Book I. On Earth</i> followed by <i>Book II. On Mars</i>.</p>
+<p>Unless your book has a very complex structure, do <i>not</i> use both a second Half-Title (whether in front matter or main matter) and a Part Separator. Combine them as the recto main matter page 1: <i>The Withens Chronicles. Part I</i>, or simply <i>Part I</i>. Then the next Part Separator would be <i>Part II</i>.</p>
+<p>In one book I recently noticed, there were five parts, each of which corresponded to one calendar day. The Part Separator showed the day, as in <i>Monday, September 25</i>. Then within each part there were several chapters, each of which took us to some different event in a different setting, all on that same day. I also note that this book had no Table of Contents; the progress of the novel was therefore a surprise, by its author's intent.</p>
+</div><!-- end D.3.3.2 -->
+
+<h5 id="hD.3.3.3">D.3.3.3. Introduction in Main Matter</h5>
+<div class="d5" id="dD.3.3.3">
+<p class="noindent">An Introduction is a <a href="#hD.3.1.2">Chapter-Like Section</a>. If the book is nonfiction and the Introduction is factual, it belongs in front matter, as described above. But in fiction, where an Introduction is a fictional lead-in to the larger story, it belongs in main matter.</p>
+<p>A main matter Introduction is typically used in the "lost manuscript" genre, where some fictional adventurer or archaeologist describes how the manuscript was found and translated. Often, the narration is a moderately lengthy adventure tale, told in the first person, by some adventurer or achaeologist. Following such an Introduction, the various chapters will reveal the contents of the manuscript. If the voice of the Introduction returns at the end, it is called a Conclusion, and is in main matter.</p>
+<p>If an Introduction is in main matter, its header text (if any) is whatever is used throughout the main story. Typically that's author verso, title recto. The reason is that such an Introduction is actually part of the overall story.</p>
+</div><!-- end D.3.3.3 -->
+
+<h5 id="hD.3.3.4">D.3.3.4. Prologue in Main Matter</h5>
+<div class="d5" id="dD.3.3.4">
+<p class="noindent">A Prologue, even if one page, is a <a href="#hD.3.1.2">Chapter-Like Section</a>. It belongs in main matter.</p>
+<p>The purpose of a Prologue is to provide a quick lead-in or setting for the story, and get the reader's attention. It is confined in place and time (one scene, one perspective). The narrator may be first-person or third-person.</p>
+<p>Do not use a Prologue for the voice of the author speaking about the book, as author; that goes in front matter, as an <a href="#hD.3.2.10">Author's Note</a>.</p>
+<p>If a book has a Prologue, then it is likely to have an Epilogue after the main story ends. An Epilogue also belongs in main matter.</p>
+<p>I do not know of any fiction with both a fictional Introduction and a Prologue. If so, Introduction precedes Prologue.</p>
+<p>Note: I have seen some web pages advising that a Prologue should go in front matter, and be narrated by a character who appears in the following story. Based on <i style="cursor:help" title="Chicago Manual of Style">CMoS</i> and actual books, I do not think that is correct.</p>
+</div><!-- end D.3.3.4 -->
+
+<h5 id="hD.3.3.5">D.3.3.5. Chapters</h5>
+<div class="d5" id="dD.3.3.5">
+<p class="noindent">Finally, you have arrived at Chapter One! Not surprisingly, it is a <a href="#hD.3.1.2">Chapter-Like Section</a>. Chapter One is always recto, whether or not preceded by an Introduction or Prologue.</p>
+<p>Subsequent chapters may begin recto or verso. Or, the book may be designed so that each chapter always begins recto. In the majority of novels I have seen, recto/verso is used. The <code>\clearpage</code> command starts a new page (recto or verso), and the <code>\cleartorecto</code> command will (if necessary) insert a blank verso, so that the following material is always recto.</p>
+<p>In the case of short stories, especially if they are by different authors, it is customary to begin each one as recto.</p>
+</div><!-- end D.3.3.5 -->
+
+<h5 id="hD.3.3.6">D.3.3.6. Epilogue, Conclusion</h5>
+<div class="d5" id="dD.3.3.6">
+<p class="noindent">If your book has an Epilogue or Conclusion, it begins recto as a <a href="#hD.3.1.2">Chapter-Like Section</a> in main matter.</p>
+<p>An Epilogue is structurally like a Prologue, but tells the aftermath of the story. A Conclusion is like an Introduction, in which we step outside the main story. I am not aware of any book that has both; but if so, Epilogue precedes Conclusion.</p>
+</div><!-- end D.3.3.6 -->
+
+<h5 id="hD.3.3.7">D.3.3.7. End Notes, Appendix, etc.</h5>
+<div class="d5" id="dD.3.3.7">
+<p class="noindent">If used, End Notes begin recto, as a <a href="#hD.3.1.2">Chapter-Like Section</a> in main matter. The same applies to an Appendix and like material.</p>
+<p>Page numbering continues Arabic. It may surprise you to learn that this is still main matter, but <i style="cursor:help" title="Chicago Manual of Style">CMoS</i> says so, and that's what was done in the few fictional books that have them, among those I have seen.</p>
+<p>The reason is that this kind of material, which is fictional, is actually the original author's writing, entwined with the main story. It was always intended to be part of the book. Never mind that it "looks like" academic material added later.</p>
+</div><!-- end D.3.3.7 -->
+</div><!-- end D.3.3 -->
+
+<h4 id="hD.3.4">D.3.4. At the End</h4>
+<div class="d4" id="dD.3.4">
+<p class="noindent">The final page of your book is necessarily verso. P.O.D. printers (and many others) require that it be completely blank, because they will add some manufacturing information to that page.</p>
+<p>So, if the text of your book finishes on a recto page, then one blank page is automatically added. However, if the text of your book finishes on a verso page, then <i>two</i> blank pages are automatically added.</p>
+
+<h5 id="hD.3.4.1">D.3.4.1. Backmatter? Not!</h5>
+<div class="d5" id="dD.3.4.1">
+<p class="noindent">
+Once upon a time, when printing was not so electronically automated, it was difficult to add material to the end of a previously-typeset section of front matter. So, if there was a subsequent printing of the book, with new material that ought to go in front matter, the problem was solved by placing the new material in "back matter." Then, the original pagination did not have to be altered. To stress that the added material was not part of the original, it would have non-Arabic page numbering, which might be a continuation of lowercase roman numerals from where the front matter left off, or might begin with uppercase Roman numerals.</p>
+<p>A similar situation applied to critical editions of earlier works, which added material from different authors. The added material was never part of the original book.</p>
+<p>That is a situation you are never likely to address. When most authors speak about "back matter," what they mean is explanatory material that follows the end of the story. That is, anything after the final Chapter, Epilogue, or Conclusion. A good example can be found in J.R.R. Tolkien's <i>The Return of the King,</i> which has quite a bit of material following the end of the story. That material discusses the language and history of the Elves, and a variety of other things. But its page numbering continues Arabic. It looks like critical commentary, but it is part of Tolkien's original, fictional structure for the book. Thus, it is main matter.</p>
+<p>So, your book is unlikely to have true back matter. If you use the <code>\backmatter</code> command, it does nothing. If you really wish to change page numbering, then you must code it manually. This is not advised for P.O.D. books, as it may confuse someone performing quality inspection; true back matter is so rare.</p>
+</div><!-- end D.3.4.1 -->
+
+<h5 id="hD.3.4.2">D.3.4.2. About the Author</h5>
+<div class="d5" id="dD.3.4.2">
+<p class="noindent">A hardcover book often has "About the Author" on the inside flap of its dust jacket. Softcover doesn't have a dust jacket, so one strategy is to add a leaf after the story finishes, and place "About the Author" on its recto. That avoids repagination of the original. It is still treated as main matter, with continued (non-printing) Arabic page number. Thus:</p>
+<p class="code"><code>
+.. and they rode off into the sunset. % end of story<br/>
+\cleartorecto<br/>
+\thispagestyle{empty}<br/>
+\begin{ChapterStart}<br/>
+\ChapterTitle{About the Author}<br/>
+\end{ChapterStart}<br/>
+Dirk Hardcase is a former... etc.\par<br/>
+\end{document}
+</code></p>
+<p>&bull; I suggest that if you wish to tell about yourself, you can put it on a web site instead, where you can easily edit or delete it.</p>
+</div><!-- end D.3.4.2 -->
+</div><!-- end D.3.4 -->
+</div><!-- end D.3 -->
+
+
+</div><!-- end D -->
+</div><!-- end Appendix D -->
+<!-- ************************************************************ -->
+<div id="pageE" class="page">
+
+
+<h2 id="hE">Appendix E. &nbsp; Overview of <i>fontspec</i> Syntax</h2>
+<div class="d2" id="dE">
+<p class="noindent">Much of what follows is a digested portion of the full <i>fontspec</i> package documentation. There are many more features, and ways to use them, than will be described below.</p>
+
+<h3 id="hE.1">E.1. &nbsp; Font (Family) Name vs. Font File Name</h3>
+<div class="d3" id="dE.1">
+<p class="noindent">A <em>font file</em> is an individual file, with its own <em>file name</em>, including file extension. For example, libertinusserif-regular.otf and libertinusserif-italic.otf are two different font files. This much is obvious.</p>
+<p>A <em>font family name</em>, often merely called <em>font name</em>, refers to one or more font files that are variations of the same basic font. Some fonts are so unique that the family consists of just one file. For example, the <i>NovelDeco</i> font family consists of the one file <i>NovelDeco.otf</i>. Typically, a font family has four files, consisting of Regular, Italic, Bold, and BoldItalic variants. Even though there are four font files, there is a single font family name.</p>
+<p>Many font families have more than four files, including Semibold and Light weights, and Condensed tracking. It is up to the font designer to decide whether a Condensed variation of the "Bubble Turble" font should be treated as a member of the "Burble Turble" family, or as a separate "Burble Turble Condensed" family.</p>
+<p>The font (family) name can be learned by opening font files in your system font viewer. Currently, the Windows 10 font viewer uses "Font name" and the Ubuntu font viewer puts the font name in more prominent type. A font (family) name may contain more than one word, with or without spaces, and may contain a general classification such as <em>serif</em>, <em>sans</em>, or <em>mono</em>, because those are actually different families. But it will not contain words such as <em>regular</em>, <em>medium</em>, <em>semibold</em>, <em>bold</em>, or <em>italic</em>; those are for individual members of the same family. Within TeX, some of the older PostScript fonts have been re-worked as newer TrueType and Open Type fonts. The family names are slightly different, so pay attention.</p>
+<p class="centerimg">
+<img src="html-resources/win10libser.png" width="268" height="184" alt="Windows 10 font viewer"/> &nbsp;
+<img src="html-resources/ublibser.png" width="431" height="176" alt="Ubuntu font viewer"/>
+</p>
+
+<h4 id="hE.1.1">E.1.1. &nbsp; Set/New by Font Name vs. File Name</h4>
+<div class="d4" id="dE.1.1">
+<p class="noindent">When you set an existing font, or create a new font command, you can use either the font (family) name, or the specific font file name. However, there may be a big difference in results!</p>
+<p style="margin-top:10px"><b>By family name:</b></p>
+<p><img class="floatright" style="padding-top:12px" src="html-resources/fontbyfamily.png" width="338" height="42" alt="font family defined"/> When you use the <em>font family name</em>, you configure all of the Regular, Italic, Bold, and BoldItalic variants. The usual TeX commands will be applied:</p>
+<p>Preamble:</p>
+<p class="code" style="clear:both"><code>\NewFontFamily\rway{Raleway}</code></p>
+<p>Document Body:</p>
+<p class="code"><code>{\rway I came, \textbf{I saw}, \emph{I conquered}, \textsc{I left}.}</code></p>
+<p style="margin-top:10px"><b>By file name:</b></p>
+<p><img class="floatright" style="padding-top:12px" src="html-resources/fontbyfilenamei.png" width="335" height="44" alt="font file defined"/> However, if you specify a single <em>font file name</em>, then <em>only</em> that font file will be used, regardless of requests for bold or italic. Small caps will be honored, if the specific file has them:</p>
+<p>Preamble:</p>
+<p class="code" style="clear:both"><code>\NewFontFamily\rwayi{Raleway-Regular-Italic.otf}</code></p>
+<p>Document Body:</p>
+<p class="code"><code>{\rwayi I came, \textbf{I saw}, \emph{I conquered}, \textsc{I left}.}</code></p>
+<p style="margin-top:10px"><b>File Name Combinations:</b></p>
+<p><img class="floatright" style="padding-top:12px" src="html-resources/frankenfont.png" width="312" height="41" alt="frankenfont"/> What you write is what you get. You can customize a font family by individually selecting its members. Here is the syntax.</p>
+<p>Preamble:</p>
+<p class="code" style="clear:both"><code>\NewFontFamily\frankenfont[% note the % at linebreaks<br/>
+&nbsp; ItalicFont=BaskervilleF-Italic.otf,%<br/>
+&nbsp; BoldFont=libertinusserif-semibold.otf,%<br/>
+&nbsp; BoldItalicFont=texgyrepagella-bolditalic.otf,%<br/>
+]{Raleway-Medium.otf}</code></p>
+<p>Document Body:</p>
+<p class="code"><code>{\frankenfont I came, \textbf{I saw}, \emph{I conquered}, \textsc{I left}.}</code></p>
+<p style="margin-top:10px"><b>Semibold, Light, etc.:</b> The above syntax is especially useful when you wish to specify semibold (if available), rather than bold. It is also a way to select something such as light versions:</p>
+<p class="code"><code>\NewFontFamily\rwlight[% note the % at linebreaks<br/>
+&nbsp; ItalicFont=Raleway-Light-Italic.otf,%<br/>
+&nbsp; BoldFont=Raleway-Medium.otf,%<br/>
+&nbsp; BoldItalicFont=Raleway-Medium-Italic.otf,%<br/>
+]{Raleway-Light.otf}</code></p>
+<p>Note that the font file in braces is the one used as the "regular" font, in this definition.</p>
+</div><!-- end E.1.1 -->
+</div><!-- end E.1 -->
+
+<h3 id="hE.2">E.2. &nbsp; Open Type Features</h3>
+<div class="d3" id="dE.2">
+<p class="noindent">Features are variations, contained within a single font file. In the bad old days, when you wanted true small caps, you had to load a separate font file that had them (and did not have ordinary lowercase letters). Now, if an Open Type font file has the <i>smcp</i> feature (most do), you obtain the small caps from within the same file, by asking for them. Requests for the feature may be made on-the-fly, or pre-loaded for global use.</p>
+<p>Here are several of the most frequently-used features, relevant to fiction writing. There are many more, and most fonts have only a few of them. Even when a font has a feature, it may be limited to some portion of the characters. For example, it is common for small caps to be available only for Latin-1 letters, even though the font also contains Greek and Cyrillic. To put this another way: The availability of a feature does not tell you its breadth of coverage. Unless the font has documentation showing coverage of its features, the only way to find out is to create and print a test page.</p>
+<table class="preconf">
+<caption>
+Some Frequently-Used Open Type Features
+</caption>
+<thead>
+<tr>
+<th>Description</th>
+<th>Open Type code &nbsp;</th>
+<th>fontspec code</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><p>kerning</p></td>
+<td><p>kern</p></td>
+<td><p>Kerning=On<br/><em>enabled by default</em></p></td>
+</tr>
+<tr>
+<td><p>common ligatures</p></td>
+<td><p>liga</p></td>
+<td><p>Ligatures=Common<br/><em>enabled: mainfont, sansfont</em></p></td>
+</tr>
+<tr>
+<td><p>Tex ligatures</p></td>
+<td><p>tlig</p></td>
+<td><p>Ligatures=TeX<br/><em>enabled by default</em></p></td>
+</tr>
+<tr>
+<td><p>lowercase letters to small caps</p></td>
+<td><p>smcp</p></td>
+<td><p>Letters=SmallCaps</p></td>
+</tr>
+<tr>
+<td><p>uppercase letters to small caps</p></td>
+<td><p>c2sc</p></td>
+<td><p>Letters=UppercaseSmallCaps</p></td>
+</tr>
+<tr>
+<td><p>lining numerals</p></td>
+<td><p>lnum</p></td>
+<td><p>Numbers=Lining</p></td>
+</tr>
+<tr>
+<td><p>oldstyle numerals</p></td>
+<td><p>onum</p></td>
+<td><p>Numbers=OldStyle<br/><em>enabled: mainfont, sansfont</em></p></td>
+</tr>
+</tbody>
+</table>
+<p>&bull; Kerning is the automatic adjustment of spacing between letters, so that they fit together nicely. The values are read from tables within the font.</p>
+<p>&bull; Common ligatures are substitutions, such as a combined <i>ff</i> character for two consecutive <i>f</i> characters. It is up to the font designer to determine which ligatures, if any, are common.</p>
+<p>&bull; TeX ligatures (such as replacing `` with “ and --- with &mdash;) are not actually an Open Type feature, but they are treated that way by the software. All of these are enabled by default. The <i>fontspec</i> manual explains how to disable them, if necessary.</p>
+<p>&bull; The SmallCaps feature applies only to lowercase letters; ordinary capitals remain ordinary capitals. UppercaseSmallCaps deals only with converting ordinary capitals to small caps. If you want both, use both. In most fonts that have them, small caps are slightly taller than lowercase, and slightly more widely spaced. What distinguishes real small caps from fake ones (obtained by scaling ordinary capitals) is that the weight and spacing are more compatible with surrounding text.</p>
+<p class="centerimg"><img src="html-resources/smallcapsrealfake.png" width="478" height="43" alt="real vs fake small caps"/></p>
+<p>&bull; Lining numerals are the ones most familiar to you, from math or accounting. They sit on the baseline and have the height of capital letters. That's just right for doing calculations, and is acceptable for things such as page numbers and chapter numbers.</p>
+<p>&bull; When lining numerals are mingled with flowing text, they may stand out too much. OldStyle numerals are more like flowing text: Most of the numerals are at lowercase height, with ascenders and descenders. Compare the first number as OldStyle, the second as Lining:</p>
+<p class="centerimg"><img src="html-resources/jollybeers.png" width="499" height="52" alt="oldstyle vs lining numerals"/></p>
+<p>Most fonts use Lining numerals as their default. A few default to OldStyle numerals. Thus, you should explicitly call for the kind of numerals you wish to use.</p>
+<p>&bull; True OldStyle numerals have a flat top on <em>one</em>, and a very round <em>zero</em>: <img src="html-resources/10trueold.png" width="37" height="13" alt="true oldstyle 10"/> This may be a bit distracting. Some fonts use a transitional form, where the one has a tilted top (like big 1) and the zero is not so round: <img src="html-resources/10transold.png" width="37" height="13" alt="transitional oldstyle 10"/> Others offer you a choice, via an Open Type "style set." See the <i>fontspec</i> manual for how to code style sets.</p>
+<p>&bull; There are many more Open Type features, most of which are not useful in ordinary fiction writing. Fonts rarely have more than a few features. Some features (such as the ones shown above) have a specific meaning. Other features, such as "style sets", have whatever meaning the font designer assigns them; Thus the <i>ss03</i> feature of one font may do something very different from <i>ss03</i> in a different font.</p>
+
+<h4 id="hE.2.1">E.2.1. &nbsp; Scale as Pseudo-Feature</h4>
+<div class="d4" id="dE.2.1">
+<p class="noindent">Although it is not an Open Type feature, <i>Scale=number</i> may be written like a feature. <i>Scale</i> globally adjusts the size of the font, relative to what it would otherwise be. If a local font size command is also applied, then the result is the compounded value.</p>
+<p>If the font will be mingled with other fonts in the same place, Scale can tweak a font so that it does not stand out. If Scale does not exceed 1, then the baselineskip will not be affected. Over 1 risks spreading lines to accomodate the extra size; this should not be done for fonts that will appear in the flowing main text. But over 1 is acceptable for display fonts that do not wrap lines and do not mingle with main text.</p>
+<p>Example: <em>Orbitron</em> is a special-purpose font with a mechanical or futuristic look. Its characters are much larger and heavier than would be found in book fonts. If I wish to mingle Orbitron with ordinary text, I might load the font like this:</p>
+<p class="code"><code>\NewFontFace\orbitron[Scale=0.6]{Orbitron} % Preamble</code></p>
+<p>Then in the document body, I could use it like this:</p>
+<p class="code"><code>The message was brief: {\orbitron DIE, EARTHLING.} Captain Withens smiled as he oiled his ray-gun. But ray-guns don't use oil.\par</code></p>
+<p class="centerimg"><img src="html-resources/charscaletext.png" width="522" height="63" alt="charscale text"/>
+<p>Scale is more often used for fonts that are pre-defined to have a special meaning and location, such as <a href="#h5.1.3.1">chapter titles</a> or <a href="#h4.3.4.2">page headers</a>. There, the font is not mingled with ordinary text, and it is OK to use a larger Scale. Then, it is not necessary to use local font scaling commands each time the font is used.</p>
+</div><!-- end E.2.1 -->
+
+<h4 id="hE.2.2">E.2.2. &nbsp; Color and Opacity</h4>
+<div class="d4" id="dE.2.2">
+<p class="noindent">Even though the <i>fontspec</i> syntax allows you to set <i>Color</i> and <i>Opacity</i> as pseudo-features when you define a font, <em>the novel class blocks these features.</em> If you attempt to set them as features in a font definition, an error will result. The same applies if you attempt to add them, using <code>\addfontfeature</code>. However, you can still make use of grayscale using ordinary, local color commands.</p>
+<p>You may write text in grayscale, using commands from the included <i>xcolor</i> package. You should only do this for text that is in special locations. For example, if you begin each chapter with a number that is very large, you might wish to make that number gray, so that it does not overpower the main text.</p>
+<p>To avoid possible conflicts, the color specification should be chosen from a limited list of names. In order from dark to light: black, blue, violet, darkgray, purple, red, teal, olive, magenta, gray, brown, green, orange, cyan, lightgray, lime, pink, yellow, white. They will all be rendered in <em>shades of gray</em> (of course, black and white will be themselves). You may also choose from this more convenient list: black, gray1, gray2, gray3, gray4, gray5, gray6, gray7, gray8, gray9, white.</p>
+<p>&bull; Placing light text over a dark background may produce unexpected results in print, even if it looks good in PDF. If you need this effect, it is better to build the text into the background, as a single image.</p>
+</div><!-- end E.2.2 -->
+
+<h4 id="hE.2.3">E.2.3. &nbsp; <code>\CreateFontFeature{<em>code</em>}{<em>substitutions</em>}</code></h4>
+<div class="d4" id="dE.2.3">
+<p class="noindent">Once in a while, a font has a glyph that you would like to use, but it is not included in any of the font's Open Type feature sets. So, how to you grab that particular glyph? For example: One well-known font has a glyph named <em>emdash.alt</em>, which is not as long as the font's ordinary <em>emdash</em> glyph, and looks better in text. Unfortunately, <em>emdash.alt</em> is not in any of the font's style sets. Without some trickery, only a program such as InDesign can grab that glyph.</p>
+<p>Thanks to <i>fontspec</i>, <i>novel</i> has the necessary trickery. Command <code>\CreateFontFeature</code> creates a fake Open Type feature code, and assigns your list of substitutions to that code. Use comma-separated entries if there are multiple substitutions. For the case in question:</p>
+<p class="code"><code>\CreateFontFeature{myem}{emdash=emdash.alt}</code></p>
+<p>The code <i>myem</i> was randomly chosen as something that is not already defined among Open Type feature codes. Once specified, the fake feature may be used in any font definition, such as this:</p>
+<p class="code"><code>\SetParentFont[RawFeature=+myem]{Adobe Garamond Pro}</code></p>
+<p>Of course, the fake feature has no effect if the font does not have the substitution character.</p>
+<p>This technique may be used for more complicated features, but that is beyond the scope of this documentation. See the <i>fontspec</i> manual if you need to do more.</p>
+</div><!-- end E.2.3 -->
+</div><!-- end E.2 -->
+
+<h3 id="hE.3">E.3. &nbsp; Local Modifications to Open Type Features</h3>
+<div class="d3" id="dE.3">
+<p class="noindent">If you specify a particular Open Type feature, it will be generally used for that font command. So if you define a new font command with <i>Letters=SmallCaps</i> as a feature (and if the font actually has them), then small caps will be used for that font, whether or not you locally request them with a command such as <code>\textsc</code>.</p>
+<p>Often, you can add (or sometimes remove) features on a local basis. For example, suppose that you defined the font without using its <i>ss03</i> style set. You can locally add that feature to some text, using a command that looks like this:</p>
+<p class="code"><code>{\addfontfeature{<em>which feature</em>} <em>applied to this text</em>}</code></p>
+<p>The above code assumes that you are already using the font in that location. You cannot apply <i>ss03</i> from one font to an entirely different font!</p>
+<p>See the <i>fontspec</i> documentation for details of <code>\addfontfeature</code>.</p>
+<p>As an alternative to changing features locally, you can define different font commands to call the same underlying font, but with different features.</p>
+<p>Two ways to accomplish the same thing:</p>
+<p class="code"><code>
+\NewFontFamily\baskf{BaskervilleF}<br/>
+\NewFontFamily\baskftab[Numbers=Monospaced]{BaskervilleF} % tnum feature<br/>
+\begin{document}<br/>
+Some text {\baskftab hello 123} is here.<br/>
+Some text {\baskf\addfontfeature{Numbers=Monospaced} hello 123} is here.
+</code></p>
+</div><!-- end E.3 -->
+
+
+</div><!-- end E -->
+</div><!-- end Appendix E -->
+<!-- ************************************************************ -->
+<div id="pageF" class="page">
+
+
+<h2 id="hF">Appendix F. &nbsp; Drop Caps</h2>
+<div class="d2" id="dF">
+<p class="item">A <i>drop cap</i> is an enlarged letter (or image) at the beginning of chapter text, with the first few lines of text wrapped around it:</p>
+<p class="centerimg"><img src="html-resources/dropcap.png" width="431" height="112" title="drop cap" alt="drop cap"/></p>
+<p>Drop caps are out of fashion, largely because they do not look good when used with dialog or with short paragraphs. If you intend to use them, be prepared to write in a style where each chapter begins with a substantial paragraph. Or, consider using a specially designed <a href="#h5.5">first line</a> instead.</p>
+<p>If you use a drop cap, the first paragraph must be long enough to fill all of the shortened lines, and continue to the line beneath the drop cap letter. If instead you try to have two or more short paragraphs, then the drop cap will not work as expected. To solve this problem, you can break using <code>\\</code> to fake a paragraph ending, then use <code>\forceindent</code> to fake a new paragraph indent.</p>
+
+<h3 id="hF.1">F.1. &nbsp; Built-In Method vs. Lettrine</h3>
+<div class="d3" id="dF.1">
+<p class="item"><b>A.</b> In <i>novel</i>, the built-in <code>\dropcap</code> command is preferred to any other method for creating a drop cap. See the next section for its usage.</p>
+<p class="item"><b>B.</b> Alternatively, you may load the <i>lettrine</i> package, and use it as described in its own documentation. If <i>lettrine</i> is detected, <i>novel</i> will configure it so that lines remain on grid, and are not pushed down.</p>
+<p class="item"><b>C.</b> You may use both <code>\dropcap</code> and <code>\lettrine</code> in the same document, as they are independent, and use different settings.</p>
+<p class="item"><b>D.</b> In <i>novel</i>, the <code>\lettrine</code> command does not accept an image. Use <code>\dropcap</code>.</p>
+<p class="item"><b>E.</b> Only <i>lettrine</i> offers the rarely-used <i>slope</i> feature.</p>
+<p class="item"><b>F.</b> Both <code>\dropcap</code> and <code>\lettrine</code> are incompatible with <code>\FirstLine</code>. If you need to set the entire first line in small caps, you are more likely to be successful using <code>\dropcap</code> as described below.</p>
+</div><!-- end F.1 -->
+
+<h3 id="hF.2">F.2. &nbsp; \dropcap[<em>options</em>]{<em>letter or image</em>}</h3>
+<div class="d3" id="dF.2">
+<p class="noindent">To ensure that this command works as described here, verify that font <i>NovelDeco.otf</i> is at least version 1.48. If you use your own <i>deco font</i>, be sure that it is based on at least that version. Also, clear <i>luatex-cache</i> so that the version is updated. If you do not do that, the <code>\dropcap</code> command still works, but the appearance of the result will differ.</p>
+<p class="item"><b>A.</b> The <code>\dropcap</code> command is based on <i>lettrine</i> technology, but has different options and behavior.</p>
+<p class="item"><b>B.</b> The <code>\dropcap</code> command accepts the following options as <span style="white-space:nowrap">comma-separated</span> key values:</p>
+<p class="code"><code>lines=<em>integer</em></code> &nbsp; Number of lines indented by the drop cap. Default 3.</p>
+<p class="code"><code>gap=<em>length</em></code> &nbsp; Distance from drop cap to indented text. Default 0.25em. (note 1)</p>
+<p class="code"><code>hoffset=<em>length</em></code> &nbsp; Moves drop cap horizontally. Default 0em.</p>
+<p class="code"><code>voffset=<em>length</em></code> &nbsp; Moves drop cap vertically. Default 0em.</p>
+<p class="code"><code>ante={<em>text</em>}</code> &nbsp; Precedes drop cap with normal text. Default empty. (notes 2,4)</p>
+<p class="code"><code>ante*={<em>text</em>}</code> &nbsp; Like <code>ante={<em>text</em>}</code> but auto-hangs text in left margin. (notes 3,4)</p>
+<p class="code"><code>scale=<em>number</em></code> &nbsp; Scales drop cap letter (not image). Default 1.</p>
+<p class="code"><code>bloat=<em>number</em></code> &nbsp; Horizontally scales drop cap letter (not image). Default 1. (note5)</p>
+<p class="code"><code>depth=<em>integer</em></code> &nbsp; Adds blank line(s) beneath drop cap baseline. Default 0. (note 6)</p>
+<p><img src="html-resources/dropcap-gap.png" class="floatright" width="82" height="150" title="dropcap gap" alt="dropcap gap"/>&bull; Note 1: The <code>gap</code> is equivalent to <i>lettrine's</i> <code>findent</code>. There is no equivalent to <code>nindent</code> or <code>slope</code>. If you wish to move the first line of text closer to the drop cap, use <code>\kern</code> or <code>\hspace</code> there.</p>
+<p>&bull; Note 2: <code>ante</code> is typically used for placing quotation mark before the drop cap. But the authoritative <i style="cursor:help" title="Chicago Manual of Style">CMoS</i> recommends that such an opening mark be omitted, at least in American style. If the mark is placed, it is at normal text font, size, and position (this is the style used).</p>
+<p><img src="html-resources/dropcap-antestar.png" class="floatright" width="110" height="102" title="ante*=``" alt="ante*=``"/>&bull; Note 3: <code>ante</code> begins at the margin, and thus pushes the drop cap to the right. With <code>ante*</code> its text hangs in the left margin, so that the drop cap is aligned with the margin. This is visually better, providing that you have enough margin to accomodate the ante text. Setting an <i>unsafe zone</i> may be helpful. See the main documentation.</p>
+<p>Example at right: <code>\dropcap[ante*=``]{O}</code></p>
+<p>&bull; Note 4: You may use <code>\charscale</code> to manipulate the size and position of ante text. No other styling (such as font or color) may be applied. The ante text will always be black, in the main font. This is standard.</p>
+<p><img src="html-resources/dropcap-scalebloat.png" class="floatright" width="98" height="107" title="scale=1.2,bloat=.75" alt="scale=1.2,bloat=.75"/>&bull; Note 5: <code>bloat</code> multiplies <code>scale</code> horizontally. The primary use of <code>bloat</code> is to tweak where the lines break, by making the drop cap slightly narrower or thicker.</p>
+<p>Example at right: <code>\dropcap[scale=1.2,bloat=0.75]{O}</code>. The effective vertical scale is 1.2, and the effective horizontal scale is 1.2x0.75=0.8.</p>
+<p>&bull; Note 6: If the drop cap character has a prominent descender, then you may need to create room underneath it using <code>depth</code>, or the descender will intrude into the text beneath it. This can only be decided on a per-character basis, depending on the font.</p>
+<p class="item"><img src="html-resources/I-shade.png" class="floatright" width="84" height="88" title="dropcap I image" alt="dropcap I image"/><b>C.</b> If the content of the drop cap ends with png, PNG, jpg, JPG, jpeg, or JPEG, it will be interpreted as an image. It will be aligned so that its bottom is at the lowest indented baseline. You may position the image using the <code>hoffset</code> and <code>voffset</code> option keys. The image cannot be scaled by <code>hscale</code> or <code>vscale</code>, because it must be at exact size and resolution. Thus, whether or not the image's top aligns in the desired location, depends on how you created the image.</p>
+<p>Example at right: <code>\dropcap[voffset=-0.15em]{I-shade.png}</code>.</p>
+<p class="item"><b>D.</b> If <code>lines=1</code>, then <code>\dropcap</code> has no effect. This applies whether or not the command or <code>ante</code> is starred. That is, the following lines of code have the same result:</p>
+<p class="code"><code>&ldquo;It was dark and stormy,&rdquo; he said.</code></p>
+<p class="code"><code>\dropcap[<i>any keys</i>,lines=1,ante*=&ldquo;]{I}t was dark and stormy,&rdquo; he said.</code></p>
+<p class="item"><b>E.</b> When the drop cap is a letter (not image) without scale, or with <code>scale=1</code>, its top will lie at the capital X-height of main text. This is the most commonly-used style. If the letter has upper diacritical mark, then the mark will be set higher.</p>
+</div><!-- end F.2 -->
+
+<h3 id="hF.3">F.3. &nbsp; \dropcap*[<em>options</em>]{<em>letter</em>} &nbsp; starred version</h3>
+<div class="d3" id="dF.3">
+<p class="item"><b>A.</b> <img src="html-resources/Iboxcap.png" class="floatright" width="84" height="191" title="starred dropcap and image" alt="starred dropcap and image"/>In its starred form, <code>\dropcap*</code> will place a rectangular box around the drop cap letter (but not image).</p>
+<p class="item"><b>B.</b> If the letter is in the Latin-1 or Latin Extended A character sets, then the box will ignore any upper diacritical mark, so that the mark sits above the box.</p>
+<p class="item"><b>C.</b> The boxed letter is a convenient reference frame, in case you wish to create an image of the letter in a graphics program. If you do that, then you will probably need to apply some negative <code>voffset</code> to the image. You may also wish to kern the first line closer to the image.</p>
+<p class="item"><b>D.</b> Example: At right, the top section shows a drop cap I with box. This portion of the PDF was imported to a graphics program, and the boxed area was used as template for the image shown in the lower section. Then the image was substituted for the original boxed letter.</p>
+</div><!-- end F.3 -->
+
+<h3 id="hF.4">F.4. &nbsp; Drop Cap Font and Color</h3>
+<div class="d3" id="dF.4">
+<p class="item"><b>A.</b> These settings apply to <code>\dropcap</code>, but not <code>\lettrine</code>.</p>
+<p class="item"><b>B.</b> The default drop cap font is <i>NovelDeco.otf</i> with its Open Type feature <i>dcap</i>. These glyphs are modeled after the <i>Libertinus Serif Display</i> font, and are specially designed to look good at the enlarged size of drop caps, as well as align with the left margin. Also, characters with prominent descenders (such as Ccedilla) are designed so that the descender, rather than the base letter, sits at the baseline. This avoids the need for <code>depth</code> setting.</p>
+<p class="item"><b>C.</b> To change the font used by <code>\dropcap</code>, you must first define one or more font commands in Preamble. For example:</p>
+<p class="code"><code>\NewFontFace\mynicedc[<em>features</em>]{font file name}</code></p>
+<p>Then, you set the font. This may be changed anywhere:</p>
+<p class="code"><code>\SetDropCapFont{\mynicedc}</code></p>
+<p class="item"><b>D.</b> Do not use Type1 or Metafont fonts. If the desired font is only available in one of those formats, you can use a font editor such as <a href="https://fontforge.github.io/en-US/" class="external" rel="external" target="new">FontForge</a> to convert it to Open Type or TrueType format. Then, as described above, load the converted file by its exact file name. If the font has mssing extrema, that is almost never a problem. Overlapped hints are rarely a problem. But self-intersecting glyphs and open paths may be a problem, if you use those glyphs.</p>
+<p class="item"><b>E.</b> Default drop cap color is black. To change it, use <i>xcolor</i> syntax. Either of these:</p>
+<p class="code"><code>\SetDropCapColor[<em>color model</em>]{<em>color value</em>}</code></p>
+<p class="code"><code>\SetDropCapColor{<em>color name</em>}</code></p>
+<p>Only grayscale may be used.</p>
+</div><!-- end F.4 -->
+
+<h3 id="hF.5">F.5. &nbsp; Drop Cap With First Line Small Caps</h3>
+<div class="d3" id="dF.5">
+<p class="item"><b>A.</b> The <code>\FirstLine</code> command does not play well with either <code>\dropcap</code> or <code>\lettrine</code>. This is not a trivial fix.</p>
+<p class="item"><b>B.</b> If you require a drop cap to be followed by an entire first line in small caps, Then you must manually code it. You will probably get better results using <code>\dropcap</code> instead of <code>\lettrine</code>.
+<p class="item"><b>C.</b> Use <code>\dropcap{letter or image}\textsc{some text} rest of paragraph.</code></p>
+<p class="item"><b>D.</b> Guess at how much <code>{some text}</code> needs to be. Compile, look at result, then adjust and try again.</p>
+<p class="item"><b>E.</b> It is possible (although unsightly) to end <code>{some text}</code> at a hyphenation point in its final word.</p>
+<p class="item"><b>F.</b> Again: There is no known better way to do this.</p>
+</div><!-- end F.5 -->
+
+
+</div><!-- end F -->
+</div><!-- end Appendix F -->
+<!-- ************************************************************ -->
+
+
+<!-- Future appendices go here. -->
+
+
+<!-- ************************************************************ -->
+<div id="pageY" class="page">
+
+
+<h2 id="hY">Appendix Y. &nbsp; Licensing and Credits</h2>
+<div class="d2" id="dY">
+
+<p class="item"><b>A. Licensing:</b> The <i>novel</i> document class, including software, examples, documentation and supporting images, is distributed under the terms of the <a class="external" rel="external" target="new" href="https://www.latex-project.org/lppl/lppl-1-3c/">LaTeX Project Public License, version 1.3c</a>, or (at your option) any later version. Exception: The included fonts <i>NovelDeco.otf</i> and <i>CPmodified.otf</i> are distributed under terms of the <a class="external" rel="external" target="new" href="http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web">SIL Open Font License, v.1.1.</a></p>
+<p>To ensure that your book may be sold commercially, be careful to use only fonts that allow commercial usage. That may exclude some of the fonts in the LaTeX font catalog. See <a href="#hC">Appendix&nbsp;C</a>.</p>
+
+<p class="item"><b>B. Credits:</b> Within the TeX code files, you will find places where small or large pieces of code are the work of someone else. Names or organizations are credited in-place within the TeX code, according to license.</p>
+<p>Various clipart graphics were obtained from <a class="external" rel="external" target="new" href="https://openclipart.org">openclipart.org</a>.</p>
+<p>Font <i>NovelDeco.otf</i> was created using <a class="external" rel="external" target="new" href="https://fontforge.github.io/en-US/">FontForge</a>. The font is partly derived from <a class="external" rel="external" target="new" href="https://github.com/khaledhosny/libertinus"><span style="white-space:nowrap"><i>Libertinus Serif</i></span></a>, which in turn is derived from <a class="external" rel="external" target="new" href="http://www.linuxlibertine.org/"><span style="white-space:nowrap"><i>Linux Libertine O</i></span></a>.</p>
+<p>In places, I offer opinions or make suggestions regarding design. These are largely based on my own inspection of popular fiction books, at my local public library. In some cases, I follow the <a class="external" rel="external" target="new" href="http://www.chicagomanualofstyle.org/home.html"><i>Chicago Manual of Style</i></a> (CMoS), hardcover 16th edition. However, please do not regard my opinions and suggestions as authoritative.</p>
+<p>&nbsp;</p>
+
+
+</div><!-- end Y -->
+</div><!-- end Appendix Y -->
+<!-- ************************************************************ -->
+<div id="pageZ" class="page">
+
+
+<h2 id="hZ">Appendix Z. &nbsp; Changes in v.1.50 and Later</h2>
+<div class="d2" id="dZ">
+
+<h4>Changes in version 1.52</h4>
+<div class="d4">
+<p>The <code>linegap</code> environment is deprecated. It will still be honored in code, but has been removed from the documentation. It was never very useful.</p>
+<p>The <code>parascale</code> environment now measures how much it disturbs the line grid. Although it cannot automatically correct the disturbance, it does provide a useful warning so that you can make the change yourself.</p>
+<p>Best practice avoids scene breaks too close to the top or bottom of a page, unless you place something visible there. Now, a badly-placed <code>\scenebreak</code> can be detected, and a warning will be issued.</p>
+<p>Version 1.50 already included an advanced method for PDF/X-1a color covers. In version 1.52, this is extended to non-color interior book blocks. Now, any image placed in your document will be inspected, and classified either as <i>known-compliant</i> or <i>unknown</i>. Images with <i>unknown</i> compliance will be reported in the log file, and if any were detected, there will be a warning.</p>
+<p>There have been some miscellaneous small tweaks, unlikely to be noticeable by most users.</p>
+<p>Documents that successfully compiled with version 1.50 should look the same in version 1.52, but you may see more warnings.</p>
+</div>
+
+<h4>Changes in Version 1.50</h4>
+<div class="d3">
+<p>Version 1.50 introduced many new features, and some changes, from version 1.46.2.</p>
+
+<p class="noindent"><b>Post-Release Reversion to Old</b></p>
+<p>If you have an existing document created with version prior to 1.50, in rare circumstances the layout will change. </p>
+<p>If the only change is the number of lines per page, then you can simply fix it manually, using the <code>\SetLinesPerPage</code> command. But if version 1.50 creates problems, you can run the old and new versions side-by-side. Be sure to keep the new version installed.</p>
+<p>In the short term, an older version of <i>novel</i> can be found <a href="https://github.com/RobtAll/novel">here</a>, in the archives folder. Be sure that the zip file is named "novel-old".</p>
+<p>1) Unpack novel-old.zip into your texmf-local directory.</p>
+<p>2) Refresh your file name database.</p>
+<p>3) Change your document class from <i>novel</i> to <i>novel-old</i>.</p>
+<p>If performed correctly, you will be using version 1.46.2 of <i>novel</i>, when you change the document class to <i>novel-old</i>. To avoid version conflict, be sure that you do not duplicate font <i>NovelDeco.otf</i> in texmf-local; <i>novel-old</i> will rely on the current version installed with <i>novel</i>.</p>
+<p>Any document using <i>novel</i> will get the installed version, rather than <i>novel-old</i>.</p>
+<p>In the long term, the older version will be removed. No particular time frame. I do not believe that many users (if any) will be affected.</p>
+<p>If your existing documents have no problem with version 1.50, then use the newer version.</p>
+
+<p class="noindent"><b>Cover Art Methods Changed</b></p>
+<p>From version 1.50, the method used for cover art has changed. If you have existing cover artwork using the older syntax, it will still be honored, but it is no longer documented.</p>
+<p>The new cover art syntax requires you to pre-process your image using a script, included in the documentation <i>extras</i> folder. The scripts works on Windows, Linux, and Mac OSX. The processed image will be PDF, separated to CMYK, at 240% ink limit.</p>
+<p>To obtain PDF/X, you post-process the above PDF in lualatex, using a template. Complete instructions are in the zip file containing the scripts.</p>
+<p>Of course, you don't need to use TeX at all, if your print service accepts an ordinary RGB image.</p>
+
+<p class="noindent"><b>New Class Option: sandbox</b></p>
+<p><i>Novel</i> does not permit things such as TikZ diagams, tables (other than its own method), imported PDf pages, and some other TeX effects. The purpose of the prohibition is to maintain grid layout, and ensure PDF/X compliance.</p>
+<p>From version 1.50, the <code>sandbox</code> class option allows you to do nearly anything, provided that the result is no more than four pages. Then, you can create drawings or whatever, convert to raster images, and place the images in your main document.</p>
+
+<p class="noindent"><b>\BlockImage Obsolete</b></p>
+<p>From version 1.50 the \BlockImage command is obsolete. It was never a very good macro. If you have an existing document that uses \BlockImage, it will be honored, but it is no longer documented.</p>
+<p>You may prefer the new <code>\FloatImage</code> and <code>\WrapImage</code> commands.</p>
+
+<p class="noindent"><b>\FloatImage Added</b></p>
+<p>Better than <code>\BlockImage</code>: Version 1.50 now has <code>\FloatImage</code>, which can place an image "here" or float it to the next page, if it doesn't immdiately fit. Full-page floats are supported. See the full documentation, above.</p>
+<p>The <code>\InlineImage</code> command remains unchanged, and will probably remain forever. It's a good macro.</p>
+
+<p class="noindent"><b>\WrapImage Added</b></p>
+<p>The new <code>\WrapImage</code> command provides limited support for wrapping text around an image. It is all you need in the context of fiction writing.</p>
+<p>The <i>wrapfig</i> package is automatically loaded, and provides the layout engine. However, do not directly use the commands and environments from that package (they won't work). Instead, <i>novel</i> provides macro <code>\WrapImage</code>, which will format your input so that it can be processed correctly.</p>
+
+<p class="noindent"><b>Drop Caps Added</b></p>
+<p>As before, you may use the <i>lettrine</i> package, if you wish. From version 1.50, <i>novel</i> now has built-in support for a certain style of drop caps, as a special interface to the <i>lettrine</i> layout engine.</p>
+<p>Since the new <code>\dropcap</code> command requires an updated version of the <i>NovelDeco.otf</i> font, be sure to update your <span style="white-space:nowrap">luatex-cache</span>.</p>
+
+<p class="noindent"><b>\Rework Obsolete</b></p>
+<p>From its early days, <i>novel</i> had an exotic built-in method for preserving layout if your book's Trim Size changed. It was a complicated piece of code, and even though it worked, it was inherently incapable of addressing some layout situations.</p>
+<p>In version 1.46.1 it was quietly removed from the documentation. In the short term, existing documents that rely on <code>\Rework</code> commands will still compile. In the long term, forget it. To my knowledge, nobody is using it.</p>
+
+<p class="noindent"><b>Class Option <i>graytext</i> Obsolete</b></p>
+<p>Formerly, you could use a class option to specify whether or not the use of grayscale text (anything other than solid black) was permitted. There was never any good reason for having that choice, so it has been removed. Now, you can always use grayscale text, if you wish.</p>
+
+<p class="noindent"><b>\SetCropmarkGap Obsolete</b></p>
+<p>Formerly, there was a minimal ability to configure crop marks. It was not very useful, and made the code more complex. Now, the size of cropmarks is fixed.</p>
+
+<p class="noindent"><b>New Error Messages for Endnotes</b></p>
+<p>Prior to version 1.50, incorrect use of <a href="#h9.2"><code>\endnote</code></a> commands would simply produce bad typesetting, without warning.</p>
+<p>New error messages have been added. If you use <a href="#h9.2"><code>\endnote</code></a>, and get error messages that did not appear before, then be sure to read the command documentation again. The most likely reason for error is that you are using the commands according to the syntax of some other package, rather than using <i>novel's</i> own syntax.</p>
+
+<p class="noindent"><b>New Algorithm for Layout Calculations</b></p>
+<p>Under the hood, version 1.50 uses a more accurate method for page layout. In most cases, the change is microscopic, and will not affect existing documents.</p>
+<p>Books that use widely-spaced lines are most likely to show a noticeable change for the better. In a few cases, the default number of lines per page will change. If you have an existing document using default lines per page, and it has changed, then simply specify the exact number manually.</p>
+
+<p class="noindent"><b>Revised Documentation Format</b></p>
+<p>This documentation has been slightly revised. Now, long sections are broken down into items, marked A, B, etc. This is for the convenience of translators.</p>
+<p>Under the hood, in the TeX code, there has been some cleanup, for the benefit of future package maintainers.</p>
+
+<p class="noindent"><b>What's Unchanged</b></p>
+<p>Most of <i>novel</i> is just as before, and will be...</p>
+<p>In particular, there is no support for tables (other than novel's own Table of Contents), no support for automatic divisions into sections and other kinds of partitions, no support for automatic index or bibliography, and generally no support for the "academic" structure used by other document classes.</p>
+</div>
+
+
+</div><!-- end Z -->
+</div><!-- end Appendix Z -->
+<!-- ************************************************************ -->
+
+
+
+</div><!-- end main -->
+<div id="finish"></div>
+</div><!-- end master -->
+</body>
+</html>
+
diff --git a/macros/luatex/latex/novel/doc/novel.pdf b/macros/luatex/latex/novel/doc/novel.pdf
new file mode 100644
index 0000000000..05afb49738
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/novel.pdf
@@ -0,0 +1,860 @@
+%PDF-1.3
+%ÐÔÅØ
+4 0 obj
+<</Type /Metadata /Subtype /XML
+/Length 6630 >>
+stream
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+ <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.2.1-c043 52.372728, 2009/01/18-15:08:04 ">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description rdf:about=""
+ xmlns:xmp="http://ns.adobe.com/xap/1.0/">
+ <xmp:ModifyDate>2018-04-25T14:02:52-07:00</xmp:ModifyDate>
+ <xmp:CreateDate>2018-04-25T14:02:52-07:00</xmp:CreateDate>
+ <xmp:CreatorTool>LuaLaTeX with novel and microtype</xmp:CreatorTool>
+ <xmp:MetadataDate>2018-04-25T14:02:52-07:00</xmp:MetadataDate>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <dc:format>application/pdf</dc:format>
+ <dc:title>
+ <rdf:Alt>
+ <rdf:li xml:lang="x-default">Novel Document Class</rdf:li>
+ </rdf:Alt>
+ </dc:title>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">
+ <xmpMM:DocumentID>uuid:A12D98E081B6A0EC2CBA2D468474F922</xmpMM:DocumentID>
+ <xmpMM:InstanceID>uuid:A99D5F97282F8D328BFD492B6475A679</xmpMM:InstanceID>
+ <xmpMM:RenditionClass>default</xmpMM:RenditionClass>
+ <xmpMM:VersionID>1</xmpMM:VersionID>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
+ <pdf:Producer>LuaLaTeX with novel-pdfx and hyperref</pdf:Producer>
+ <pdf:Trapped>False</pdf:Trapped>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/">
+ <pdfx:GTS_PDFXVersion>PDF/X-1a:2001</pdfx:GTS_PDFXVersion>
+ <pdfx:GTS_PDFXConformance>PDF/X-1a:2001</pdfx:GTS_PDFXConformance>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:pdfxid="http://www.npes.org/pdfx/ns/id/">
+ <pdfxid:GTS_PDFXVersion>PDF/X-1a:2001</pdfxid:GTS_PDFXVersion>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"
+ xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#"
+ xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#">
+ <pdfaExtension:schemas>
+ <rdf:Bag>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaSchema:namespaceURI>http://ns.adobe.com/pdf/1.3/</pdfaSchema:namespaceURI>
+ <pdfaSchema:prefix>pdf</pdfaSchema:prefix>
+ <pdfaSchema:schema>Adobe PDF Schema</pdfaSchema:schema>
+ <pdfaSchema:property>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>internal</pdfaProperty:category>
+ <pdfaProperty:description>A name object indicating whether the document has been modified to include trapping information</pdfaProperty:description>
+ <pdfaProperty:name>Trapped</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ </rdf:Seq>
+ </pdfaSchema:property>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaSchema:namespaceURI>http://ns.adobe.com/pdfx/1.3/</pdfaSchema:namespaceURI>
+ <pdfaSchema:prefix>pdfx</pdfaSchema:prefix>
+ <pdfaSchema:schema>PDF/X ID Schema</pdfaSchema:schema>
+ <pdfaSchema:property>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>internal</pdfaProperty:category>
+ <pdfaProperty:description>ID of PDF/X standard</pdfaProperty:description>
+ <pdfaProperty:name>GTS_PDFXVersion</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>internal</pdfaProperty:category>
+ <pdfaProperty:description>Conformance level of PDF/X standard</pdfaProperty:description>
+ <pdfaProperty:name>GTS_PDFXConformance</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ </rdf:Seq>
+ </pdfaSchema:property>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaSchema:namespaceURI>http://ns.adobe.com/xap/1.0/mm/</pdfaSchema:namespaceURI>
+ <pdfaSchema:prefix>xmpMM</pdfaSchema:prefix>
+ <pdfaSchema:schema>XMP Media Management Schema</pdfaSchema:schema>
+ <pdfaSchema:property>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>internal</pdfaProperty:category>
+ <pdfaProperty:description>UUID based identifier for specific incarnation of a document</pdfaProperty:description>
+ <pdfaProperty:name>InstanceID</pdfaProperty:name>
+ <pdfaProperty:valueType>URI</pdfaProperty:valueType>
+ </rdf:li>
+ </rdf:Seq>
+ </pdfaSchema:property>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaSchema:namespaceURI>http://www.npes.org/pdfx/ns/id/</pdfaSchema:namespaceURI>
+ <pdfaSchema:prefix>pdfxid</pdfaSchema:prefix>
+ <pdfaSchema:schema>PDF/X ID Schema</pdfaSchema:schema>
+ <pdfaSchema:property>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>internal</pdfaProperty:category>
+ <pdfaProperty:description>ID of PDF/X standard</pdfaProperty:description>
+ <pdfaProperty:name>GTS_PDFXVersion</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ </rdf:Seq>
+ </pdfaSchema:property>
+ </rdf:li>
+ </rdf:Bag>
+ </pdfaExtension:schemas>
+ </rdf:Description>
+ </rdf:RDF>
+ </x:xmpmeta>
+ <?xpacket end="w"?>
+endstream
+endobj
+7 0 obj
+<</Length 8268 >>
+stream
+0 g 0 G
+0 g 0 G
+0 g 0 G
+BT
+/F57 18.17191 Tf 1 0 0 1 178.388 541.455 Tm [<002F0030>-37<00370026002D>]TJ
+/F57 13.62884 Tf 1 0 0 1 105.124 508.167 Tm [<0022>-250<00250050>-7<00440056004E0046004F0055>-250<0024004D004200540054>-250<004700500053>-250<005500490046>-250<0033004600540055>-250<00500047>-250<00360054>]TJ
+ET
+1 0 0 1 161.57 481.537 cm
+q
+4 0 0 4 0 0 cm
+1 0 0 1 -161.57 -481.537 cm
+BT
+/F59 11.3574 Tf 1 0 0 1 161.57 481.537 Tm [<0176>]TJ
+ET
+1 0 0 1 161.57 481.537 cm
+Q
+1 0 0 1 -161.57 -481.537 cm
+BT
+/F60 11.3574 Tf 1 0 0 1 53.432 446.286 Tm [<0038004900460053>5<0046>-250<004A0054>-249<005500490046>-250<00450050>-7<00440056004E0046004F005500420055004A0050004F00200020>]TJ
+/F57 11.3574 Tf 1.017 0 0 1 203.432 446.286 Tm [<002A0055>-245<004A0054>-246<004A004F>-246<0029>-36<0035002E002D>-246<004700500053004E00420055000D>-246<0042004F0045>-246<00440042004F004F00500055>]TJ
+1 0 0 1 54 431.492 Tm [<0043>-10<0046>-249<0053>7<004600550053004A0046>7<0057>8<0046>-6<0045>-249<0057004A0042>]TJ
+/F61 11.3574 Tf 1 0 0 1 128.745 431.492 Tm [<00550046>7<005900450050>-7<0044>]TJ
+/F57 11.3574 Tf 1 0 0 1 157.229 431.492 Tm [<000F>-333<002A0047>-249<005A>7<00500056>-248<004900420057>7<0046>-248<00550049004A0054>-249<005100420044004C004200480046>-249<004A004F005400550042004D004D0046>-7<0045000D>-249<004D0050>-7<0050004C>-249<004700500053>]TJ
+0.996 0 0 1 53.659 416.697 Tm [<000900550046>7<00590053>8<0050>-7<00500055000A001000450050>-7<00440010004D00560042004D004200550046>7<00590010004F0050>7<0057>8<0046004D0010004F0050>7<0057>8<0046004D000E00450050>-6<00440056004E0046004F005500420055004A0050004F000F00490055004E004D000F>-341<002A0047>-253<005A>7<00500056>-252<00420053>7<0046>]TJ
+0.98 0 0 1 54 401.903 Tm [<0050004F004D004A004F0046>10<000D>-248<00480050>-247<00550050>-247<005500490046>-247<00240035>49<0022002F>-247<0051004200480046>-247<00420055>-247<00490A1D00510054001B00100010004400550042004F000F00500053004800100051004C00480010004F0050>6<0057>9<0046004D>-247<0042004F0045>-247<0044004D004A0044004C>]TJ
+1 0 0 1 53.148 387.108 Tm [<06E0003100420044004C004200480046>-250<00250050>-7<00440056004E0046004F005500420055004A0050004F>-250<00090029>-37<0035002E002D000A000F>122<06E1>]TJ
+/F60 11.3574 Tf 1 0 0 1 54 357.519 Tm [<0025>-5<0046005400440053004A00510055004A0050004F001B>]TJ
+/F57 11.3574 Tf 1.02 0 0 1 117.818 357.519 Tm [<09AB0046>]TJ
+/F61 11.3574 Tf 1.02 0 0 1 138.758 357.519 Tm [<004F0050>6<0057>8<0046004D>]TJ
+/F57 11.3574 Tf 1.02 0 0 1 167.321 357.519 Tm [<00450050>-6<00440056004E0046004F0055>-313<0044004D004200540054>-313<004A0054>-312<004700500053>-313<00580053004A0055004600530054>-312<00500047>-313<00500053004A0048004A004F0042004D>]TJ
+0.98 0 0 1 54 342.725 Tm [<098B00440055004A0050004F000D>-245<00550050>-244<0043>-10<0046>-243<00510053004A004F00550046>-7<0045>-244<00550050>-243<005100420051>-7<00460053>59<000D>-245<0058004A00550049>-243<00420A1D0046004F0055004A0050004F>-243<00550050>-244<005500490046>-243<0053>7<0046>-6<00520056004A0053>7<0046004E0046004F00550054>-242<00500047>]TJ
+0.995 0 0 1 54 327.93 Tm [<005500490046>-249<00510053004A004F0055000E0050004F000E00450046004E0042004F0045>-250<004E00420053004C00460055000F>-335<002F0050004F000E00440050004D00500053>-249<004A004F005500460053004A005000530054>-250<0042004F0045>-250<00440050004D00500053>-250<00440050>6<0057>8<004600530054>]TJ
+1.02 0 0 1 54 313.136 Tm [<00420053>7<0046>-293<0054005600510051>-7<0050005300550046>-7<0045000F>-474<002A004E0042004800460054>-295<00420053>7<0046>-293<0054005600510051>-7<0050005300550046>-7<0045000D>-306<004300560055>-295<0050004F004D005A>-294<00420054>-294<005500490046>6<005A>-294<004E004A004800490055>-294<0043>-10<0046>]TJ
+1 0 0 1 54 298.341 Tm [<005600540046>-7<0045>-250<004A004F>-250<098B00440055004A0050004F000D>-250<004F00500055>-250<0051004A0044005500560053>8<0046>-250<0043>-10<0050>-7<0050004C0054000F>]TJ
+0.98 0 0 1 71.036 283.547 Tm [<002A0047>-226<005A>8<005000560053>-226<0058>8<00500053004C>-226<004A0054>-226<0042004F>-226<0026000E0043>-10<0050>-7<0050004C000D>-232<00500053>-226<0056005400460054>-226<004A004F005500460053004A00500053>-226<00440050004D00500053>-226<00500055004900460053>-227<005500490042004F>-226<004800530042005A>60<000D>]TJ
+1 0 0 1 54 268.752 Tm [<00500053>-250<004A0054>-250<00420044004200450046004E004A0044000D>-250<005500490046004F>-250<00550049004A0054>-250<00450050>-7<00440056004E0046004F0055>-250<0044004D004200540054>-250<004A0054>-250<004F00500055>-250<004700500053>-250<005A>8<00500056000F>]TJ
+1 0 0 1 71.036 253.958 Tm [<002300560055>-250<004A0047>-250<005A>7<00500056>-250<00420053>7<0046>-249<00580053004A0055004A004F0048>-250<0042>-251<0045004600550046>-7<00440055004A0057>7<0046>-249<004F0050>6<0057>8<0046004D000D>-250<00500053>-250<00540044004A0046004F00440046>-250<098B00440055004A0050004F000D>-251<00500053>-250<0042>]TJ
+1 0 0 1 54 239.163 Tm [<00440050004D004D0046>-7<00440055004A0050004F>-250<00500047>-250<00540049005000530055>-250<0054005500500053004A00460054000D>-250<005500490046004F>-250<0053>8<004600420045>-250<0050004F0002>]TJ
+/F57 13.62884 Tf 1 0 0 1 54 213.663 Tm [<0012000F>-333<002700460042005500560053>7<00460054>]TJ
+/F57 11.3574 Tf 1.02 0 0 1 54 194.779 Tm [<09AB0053>7<0050005600480049005000560055000D>-334<004A0055>-318<004A0054>-317<0042005400540056004E0046>-7<0045>-318<0055004900420055>-317<005500490046>-318<0051005600530051>-6<005000540046>-318<00500047>-317<005A>7<005000560053>-317<00580053004A0055004A004F0048>-318<004A0054>-317<0042>]TJ
+1 0 0 1 54 179.985 Tm [<00440050004E004E00460053>8<0044004A0042004D004D005A>-250<00510053004A004F00550046>-7<0045>-250<0043>-10<0050>-7<0050004C>-250<00500047>-250<098B00440055004A0050004F000F>]TJ
+0.98 0 0 1 71.036 165.19 Tm [<0022>-244<004F0046>6<0058>]TJ
+/F61 11.3574 Tf 0.98 0 0 1 103.452 165.19 Tm [<004F0050>7<0057>8<0046004D>]TJ
+/F57 11.3574 Tf 0.98 0 0 1 130.156 165.19 Tm [<004A0054>-244<00510053>7<0046000E00440050004F098B004800560053>9<0046>-7<0045>-244<00550050>-244<00510053>7<0050>-6<0045005600440046>-244<0042>-245<005400550042004F004500420053>8<0045>-244<00550053004200450046>-244<0043>-10<0050>-7<0050004C>]TJ
+1.003 0 0 1 54 150.396 Tm [<0054004A005B0046>-249<00500047>-249<0A25000F0A25004A004F>-249<0038>-249<0059>-249<0A28000F0A25004A004F>-249<0029000D>-250<0058004A00550049>-249<004D0042005A>7<005000560055>-248<004E004200530048004A004F0054>-249<0055004900420055>-249<00420053>7<0046>-248<004D004A004C0046004D005A>-250<00550050>-249<0043>-10<0046>]TJ
+0.998 0 0 1 54 135.601 Tm [<00420044004400460051005500420043004D0046>-249<00550050>-249<005500490046>-250<004E005000540055>-249<0058004A00450046004D005A000E005600540046>-7<0045>-249<00510053004A004F0055>-250<005400460053>-15<0057004A004400460054000F>-333<09AB0046>-250<098B004D0046>-249<005A>7<00500056>-248<00420053>7<0046>]TJ
+0.98 0 0 1 54 120.807 Tm [<004F0050>7<0058>-203<0053>8<004600420045004A004F0048>-202<004A0054>-204<004A004F>-203<00550049004A0054>-203<004700500053004E00420055000F>-323<002300560055>-203<004A0047>-203<0055004900420055>-203<004A0054>-203<004F00500055>-203<005500490046>-203<0054004A005B0046>-203<00500053>-203<004D0042005A>7<005000560055>-202<005A>7<00500056>]TJ
+0.986 0 0 1 53.58 106.012 Tm [<00580042004F0055000D>-252<005500490046004F>-253<0055004900460053>8<0046>-252<00420053>7<0046>-251<00440050004E004E0042004F00450054>-252<0055004900420055>-253<00440050004F098B004800560053>7<0046>-251<004B005600540055>-252<00420043>-11<005000560055>-252<0042004F005A00550049004A004F0048000D>]TJ
+1.02 0 0 1 54 91.218 Tm [<00560054004A004F0048>-243<005400550042004F004500420053>7<0045>-243<005500460053004E004A004F0050004D00500048005A>-244<0042004F0045>-243<0056004F004500460053005400550042004F004500420043004D0046>-244<0051005600530051>-7<005000540046>9<000F>-325<0023004600540055>-244<00500047>]TJ
+0.984 0 0 1 54 76.423 Tm [<0042004D004D000D>-253<005500490046>-253<0029>-38<0035002E002D>-253<00450050>-7<00440056004E0046004F005500420055004A0050004F>-254<00440050004E00460054>-253<0058004A00550049>-253<004A004E0042004800460054>-254<0042004F0045>-253<0046>6<00590042004E0051004D00460054000D>-252<00540050>]TJ
+1 0 0 1 54 61.629 Tm [<005A>8<00500056>-250<004C004F0050>7<0058>-250<0058004900420055>-250<005A>8<00500056>-250<00420053>8<0046>-250<00450050004A004F0048000F>]TJ
+0 g 0 G
+/F57 10.44878 Tf 1 0 0 1 204.571 39.437 Tm [<0012>]TJ
+0 g 0 G
+ET
+
+endstream
+endobj
+6 0 obj
+<</Type/Page/Contents 7 0 R/Resources 5 0 R/MediaBox[0 0 396 612]/CropBox[0 0 396 612]
+
+/TrimBox[0 0 396 612]/Parent 12 0 R>>
+endobj
+5 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font<</F57 8 0 R/F59 9 0 R/F60 10 0 R/F61 11 0 R>>/ProcSet[/PDF/Text]>>
+endobj
+15 0 obj
+<</Length 8727 >>
+stream
+0 g 0 G
+0 g 0 G
+BT
+/F57 11.3574 Tf 1.02 0 0 1 53.036 564.643 Tm [<0022004D004E005000540055>-285<0046>6<0057>8<00460053>-14<005A00550049004A004F0048>-286<004A0054>-286<00510053>7<0046000E00440050004F098B004800560053>8<0046>-6<0045>-286<00550050>-285<06E0004B005600540055>-286<0058>7<00500053004C000D>120<06E1>-295<0046>6<0057>7<0046004F>-284<005500490046>]TJ
+0.997 0 0 1 36 549.848 Tm [<004400490050004A00440046>-250<00500047>-251<00470050004F00550054000F>-335<09AB0046>-251<00440049005000540046004F>-250<00440050004E0051004A004D00460053>-251<004A0054>-251<002D00560042002D00420035>62<00460039000D>-250<0042004F0045>-251<00300051>-7<0046004F>-251<0035>49<005A0051>-6<0046>]TJ
+1.02 0 0 1 36 535.054 Tm [<00470050004F00550054>-254<00420053>7<0046>-253<004D0050004200450046>-7<0045>-254<00560054004A004F0048>]TJ
+/F61 11.3574 Tf 1.02 0 0 1 143.404 535.054 Tm [<00470050004F005500540051>-6<0046>-7<0044>]TJ
+/F57 11.3574 Tf 1.02 0 0 1 184.399 535.054 Tm [<00550046>-6<00440049004F0050004D00500048005A>57<000F>-353<002A0047>-254<005A>7<00500056>-254<00510053>7<0046004700460053>-253<00550050>-254<005600540046>-254<0042>]TJ
+1 0 0 1 36 520.259 Tm [<00510053>8<00500047004600540054004A0050004F0042004D>-250<00470050004F0055000D>-250<004A0055>-250<0058004A004D004D>-250<0043>-10<0046>-250<004600420054005A>-250<00550050>-250<004D005000420045>-250<0042004F0045>-250<005600540046>-250<004A004F>-250<005600550047000E0A28000F>]TJ
+1.02 0 0 1 53.036 505.465 Tm [<002E0042004F005A>-339<005400550042004F004500420053>7<0045>-338<002D00420035>60<00460039>-338<00440050004E004E0042004F00450054>-339<00420053>7<0046>-339<0045004A005400420043004D0046>-7<0045000F>-609<09AB004A0054>-339<0058004A004D004D>-340<0043>-9<0046>]TJ
+0.98 0 0 1 36 490.67 Tm [<00540056005300510053004A0054004A004F0048>-227<00420055>-228<098B005300540055000F>-331<002300560055>]TJ
+/F61 11.3574 Tf 0.98 0 0 1 138.827 490.67 Tm [<004F0050>7<0057>8<0046004D>]TJ
+/F57 11.3574 Tf 0.98 0 0 1 165.349 490.67 Tm [<004A0054>-227<00470050>-8<0044005600540046>-7<0045>-227<0050004F>-228<0050004F0046>-228<00550049004A004F0048>-228<0050004F004D005A>59<000F>-330<0022004F005A00550049004A004F0048>]TJ
+0.986 0 0 1 36 475.875 Tm [<0055004900420055>-254<004E004A004800490055>-254<004A004F005500460053004700460053>7<0046>-254<0058004A00550049>-254<0055004900420055>-254<0051005600530051>-7<005000540046>-255<004E0042005A>-254<004900420057>7<0046>-254<0043>-10<0046>-7<0046004F>-254<00550050005400540046>-7<0045>-255<00420054004A00450046>10<000F>]TJ
+0.98 0 0 1 36 461.081 Tm [<00340050>10<000D>-231<0043>-10<0046>-226<005400560053>7<0046>-224<0055004900420055>-226<005A>7<00500056>-225<0053>8<004600420045>-225<005500490046>-226<00450050>-7<00440056004E0046004F005500420055004A0050004F0002>-331<002A0047>-225<005A>7<00500056>-225<00550042004C0046>-226<0042004F>-225<0046>6<0059004A00540055004A004F0048>]TJ
+0.98 0 0 1 36 446.286 Tm [<002D00420035>64<00460039>-173<00450050>-8<00440056004E0046004F0055>-174<0042004F0045>-174<004B005600540055>-174<004400490042004F00480046>-175<005500490046>-174<0044004D004200540054>-174<00550050>]TJ
+/F61 11.3574 Tf 0.98 0 0 1 237.08 446.286 Tm [<004F0050>7<0057>8<0046004D000D>]TJ
+/F57 11.3574 Tf 0.98 0 0 1 264.884 446.286 Tm [<004A0055>-174<004A0054>-174<0057>7<00460053>-14<005A>-175<0056004F004D004A004C0046004D005A>]TJ
+1 0 0 1 36 431.492 Tm [<00550050>-250<0058>8<00500053004C>-250<00420054>-250<0046>7<00590051>-7<0046>-7<004400550046>-7<0045000F>]TJ
+1.02 0 0 1 53.036 416.697 Tm [<002E0042004F005A>-273<004F0046>6<0058>-274<00440050004E004E0042004F00450054>-273<00420053>7<0046>-273<00510053>6<0050>7<0057004A00450046>-6<0045000F>-413<09AB0046>6<005A>-273<00420053>7<0046>-273<00470050>-7<0044005600540046>-7<0045>-274<0050004F>-273<005500490046>]TJ
+0.98 0 0 1 36 401.903 Tm [<004F0046>-7<0046>-7<00450054>-239<00500047>-240<00510053004A004F0055>-240<098B00440055004A0050004F>-239<00580053004A0055004600530054000D>-243<0051>-7<00460053004A0050>-7<0045000F>-335<0022004F0045000D>]TJ
+/F61 11.3574 Tf 0.98 0 0 1 231.129 401.903 Tm [<004F0050>7<0057>8<0046004D>]TJ
+/F57 11.3574 Tf 0.98 0 0 1 257.782 401.903 Tm [<004900420054>-239<00430056004A004D0055000E004A004F>-240<00310025002700100039>]TJ
+0.98 0 0 1 36 387.108 Tm [<00550046>-7<00440049004F0050004D00500048005A>-185<0055004900420055>-186<0046>6<005900440046>-6<0046>-7<00450054>-186<005500490046>-185<00440042005100420043004A004D004A0055004A00460054>-186<0044005600530053>7<0046004F0055004D005A>-184<004200570042004A004D00420043004D0046>-186<0057004A0042>-186<00500055004900460053>]TJ
+1 0 0 1 36 372.314 Tm [<002D00420035>63<00460039>-250<005100420044004C0042004800460054000F>]TJ
+/F57 13.62884 Tf 1 0 0 1 36 346.813 Tm [<0013000F>-333<00240050004E0051004D004600550046>-250<00250050>-7<00440056004E0046004F005500420055004A0050004F>]TJ
+/F57 11.3574 Tf 1.012 0 0 1 35.455 327.93 Tm [<0038004900420055>-246<005A>7<00500056>-245<00420053>7<0046>-246<0053>7<004600420045004A004F0048>-245<004F0050>6<0058>58<000D>-246<004A0054>-246<0050004F004D005A>-246<0042004F>-247<004A004F00550053>7<0050>-6<0045005600440055004A0050004F000F>-329<09AB0046>-246<00440050004E0051004D004600550046>]TJ
+0.98 0 0 1 36 313.136 Tm [<00450050>-7<00440056004E0046004F005500420055004A0050004F>-223<004A0054>-224<004A004F>-223<0029>-38<0035002E002D>-224<004700500053004E00420055000D>-230<0045004A0053>8<0046>-7<00440055004D005A>-223<00580053004A0A1D0046004F>-224<004A004F>-223<0029>-38<0035002E002D>-224<005300420055004900460053>]TJ
+0.98 0 0 1 36 298.341 Tm [<005500490042004F>-183<0046>6<0059005500530042004400550046>-6<0045>-184<00470053>7<0050004E>-183<00440050>-7<00450046>10<000F>-316<09AB00460053>7<0046>-183<00420053>8<0046>-183<004F0056004E00460053>7<005000560054>-183<0046>7<00590042004E0051004D00460054>-183<0042004F0045>-184<004A004E0042004800460054000D>]TJ
+1 0 0 1 36 283.547 Tm [<00550050>-7<0050>-250<0045004600550042004A004D0046>-7<0045>-250<00550050>-250<0043>-10<0046>-250<00510053>8<004600540046004F00550046>-7<0045>-250<00420054>-250<003100250027>24<000F>]TJ
+/F57 13.62884 Tf 1 0 0 1 36 258.046 Tm [<0014000F>-333<002D004A00440046004F00540046>]TJ
+/F57 11.3574 Tf 1.02 0 0 1 36 239.163 Tm [<09AB0046>-331<002D00420035>61<00460039>-330<00440050>-7<00450046>9<000D>-352<0042004F0045>-331<0042004400440050004E00510042004F005A004A004F0048>-331<00450050>-7<00440056004E0046004F005500420055004A0050004F000D>-353<004A0054>-331<0053>7<0046004D0046004200540046>-6<0045>]TJ
+1 0 0 1 36 224.369 Tm [<0056004F004500460053>-250<005500490046>-250<002D0042005500460039>-250<00310053>8<0050004B0046>-7<00440055>-250<003100560043004D004A0044>-250<002D004A00440046004F00540046>10<000D>-250<0057>8<004600530054004A0050004F>-250<0A21000F0A230044>-250<00500053>-250<004D0042005500460053>59<000F>]TJ
+0.983 0 0 1 53.036 209.574 Tm [<09AB0046>-255<00440050004E00510042004F004A0050004F>-255<00470050004F00550009>11<0054000A>-254<004A00540009>11<00420053>8<0046000A>-254<004D004A00440046004F00540046>-7<0045>-255<0056004F004500460053>-256<005500490046>-255<0034002A002D>-255<00300051>-7<0046004F>-255<00270050004F0055>]TJ
+1 0 0 1 36 194.779 Tm [<002D004A00440046004F00540046>10<000D>-250<0057>8<004600530054004A0050004F>-250<0A21000F0A21000F>]TJ
+/F57 13.62884 Tf 1 0 0 1 36 169.279 Tm [<0015000F>-333<0037>79<004600530054004A0050004F>]TJ
+/F57 11.3574 Tf 0.994 0 0 1 36 150.396 Tm [<0A21000F0A250A22000D>-250<0A220A200A210A28000E0A200A24000E0A220A26001B>-335<0026004F00490042004F00440046>-7<0045>-250<0045004600550046>-7<00440055004A0050004F>-250<0042004F0045>-251<005800420053004F004A004F0048>-250<00560054004A004F0048>-250<002D00560042>-250<00440050>-7<00450046>9<000F>]TJ
+1 0 0 1 36 135.601 Tm [<0A21000F0A250A20000F0A25000D>-250<0A220A200A210A28000E0A200A24000E0A210A21001B>-333<002E004A004F00500053>-250<004300560048>-250<098B005900460054>-250<0009>16<00450050>-6<00440054>-250<0042004F0045>-250<00440050>-7<00450046>-250<0045004A0054004200480053>7<0046>-6<0046>-7<0045000A000F>]TJ
+1 0 0 1 36 120.807 Tm [<0A21000F0A250A20000D>-250<0A220A200A210A28000E0A200A23000E0A220A28001B>-333<002A004E00510053>7<0050>7<0057>8<0046>-6<0045>-250<004A004E004200480046>-250<00490042004F0045004D004A004F0048>-250<00440050004E004E0042004F00450054000D>-250<00540042004F00450043>-10<0050>6<0059000F>]TJ
+1 0 0 1 36 106.012 Tm [<0A21000F0A240A26000F0A22000D>-250<0A220A200A210A28000E0A200A21000E0A210A24001B>-333<0034005500420043004D0046>-250<06E1>23<0050004D004506E1>-249<0057>7<004600530054004A0050004F000F>-332<003600540046>-250<004F0046>6<0058>8<00460053>-249<0A21000F0A250A20000F>]TJ
+1 0 0 1 36 91.218 Tm [<0A21000F0A21000D>-250<0A220A200A210A27000E0A200A23000E0A200A21001B>-333<004A004F004A0055004A0042004D>-250<005100560043004D004A0044>-250<0053>7<0046004D0046004200540046>10<000F>]TJ
+0 g 0 G
+/F57 10.44878 Tf 1 0 0 1 186.571 39.437 Tm [<0013>]TJ
+0 g 0 G
+ET
+
+endstream
+endobj
+14 0 obj
+<</Type/Page/Contents 15 0 R/Resources 13 0 R/MediaBox[0 0 396 612]/CropBox[0 0 396 612]
+
+/TrimBox[0 0 396 612]/Parent 12 0 R>>
+endobj
+13 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font<</F57 8 0 R/F61 11 0 R>>/ProcSet[/PDF/Text]>>
+endobj
+18 0 obj
+<</Length 8573 >>
+stream
+0 g 0 G
+0 g 0 G
+BT
+/F57 13.62884 Tf 1 0 0 1 54 553.937 Tm [<0016000F>-333<0027>58<0022>34<00320054>]TJ
+0 g 0 G
+0 g 0 G
+/F57 11.3574 Tf 1 0 0 1 54 535.054 Tm [<0032>29<000F>-607<00240042004F>-250<00550049004A0054>-250<00450050>-7<00440056004E0046004F0055>-250<0044004D004200540054>-250<0043>-10<0046>-250<005600540046>-7<0045>-250<004700500053>-250<0026000E0043>-10<0050>-7<0050004C00540020>]TJ
+0 g 0 G
+0 g 0 G
+1 0 0 1 54 520.259 Tm [<0022000F>]TJ
+0.997 0 0 1 71.036 520.259 Tm [<002F0050>10<000F>-334<0022004F0045000D>-250<0055004900420055>-250<004700460042005500560053>7<0046>-249<0058004A004D004D>-250<004F0046>6<0057>8<00460053>-249<0043>-10<0046>-250<0042004500450046>-7<0045000D>-251<00420054>-250<005500490046>-250<00550046>-7<00440049004F0050004D00500048005A>-250<004A0054>]TJ
+1 0 0 1 71.036 505.465 Tm [<004A004F004900460053>8<0046004F0055004D005A>-250<004A004F00440050004E005100420055004A0043004D0046>10<000F>-333<0022>-250<0058>7<00500053>8<0045>-249<00510053>7<0050>-6<004400460054005400500053>-250<004A0054>-250<005A>7<005000560053>-249<00470053004A0046004F0045000F>]TJ
+0 g 0 G
+0 g 0 G
+1 0 0 1 54 490.67 Tm [<0032>29<000F>-607<0038004900420055>-250<0049004200510051>-7<0046004F0046>-7<0045>-250<00550050>-250<098C0050004200550054>-250<0042004F0045>-250<004D004A0054005500540020>]TJ
+0 g 0 G
+0 g 0 G
+1 0 0 1 54 475.875 Tm [<0022000F>-585<003600540046>-250<005500490046>-250<004F0046>7<0058>-250<004A004E004200480046>-250<00440050004E004E0042004F00450054000D>-250<00500053>-250<00540042004F00450043>-10<0050>7<0059>-250<004E0050>-7<00450046>10<000F>]TJ
+0 g 0 G
+0 g 0 G
+1 0 0 1 54 461.081 Tm [<0032>29<000F>-607<002E005A>-250<0055004900460054004A0054>-250<004200450057004A005400500053>-250<00550050004D0045>-250<004E004606D8>]TJ
+0 g 0 G
+0 g 0 G
+1 0 0 1 54 446.286 Tm [<0022000F>]TJ
+1.02 0 0 1 71.036 446.286 Tm [<0034005500500051>-323<0053004A004800490055>-323<0055004900460053>6<0046>10<000F>-561<09AB004A0054>-323<00450050>-7<00440056004E0046004F0055>-323<0044004D004200540054>-324<004A0054>-323<0057>7<00460053>-14<005A>-324<0045004A098A00460053>7<0046004F0055>-322<00470053>7<0050004E>]TJ
+1 0 0 1 71.036 431.492 Tm [<0042004F005A00550049004A004F0048>-250<005600540046>-7<0045>-250<004700500053>-250<005500490046005400460054>-250<0042004F0045>-250<00500055004900460053>-250<00420044004200450046004E004A0044>-250<005100560043004D004A004400420055004A0050004F0054000F>]TJ
+0 g 0 G
+0 g 0 G
+1 0 0 1 54 416.697 Tm [<0032>29<000F>-607<002A0047>-250<002A>-250<005600540046>-250<0035004A004C003B>-250<004700500053>-250<00270046>7<005A004F004E0042004F>-250<0045004A0042004800530042004E0054000D>-250<005500490046004F06D8>]TJ
+0 g 0 G
+0 g 0 G
+1 0 0 1 54 401.903 Tm [<0022000F>-585<00280050>-250<004200580042005A>59<000F>]TJ
+0 g 0 G
+0 g 0 G
+1 0 0 1 54 387.108 Tm [<0032>29<000F>-607<002900420054>-250<00550049004A0054>-250<00450050>-7<00440056004E0046004F0055>-250<0044004D004200540054>-250<0046>7<0057>8<00460053>-250<0043>-10<0046>-7<0046004F>-250<005600540046>-7<0045>-250<004700500053>-250<0042004F>-250<00420044005500560042004D>-250<004F0050>7<0057>8<0046004D0020>]TJ
+0 g 0 G
+0 g 0 G
+1 0 0 1 54 372.314 Tm [<0022000F>]TJ
+1.02 0 0 1 71.036 372.314 Tm [<003A>69<00460054>-290<004A004F00450046>-7<0046>-7<00450002>-465<002A004F>-291<0022>32<00560048005600540055>-290<0A220A200A210A27>-292<005500490046>-291<004200560055004900500053>-291<005100560043004D004A005400490046>-7<0045>-291<0042>-291<00440050004E0051004D004600550046>]TJ
+0.98 0 0 1 71.036 357.519 Tm [<004F0050>7<0057>8<0046004D000D>-253<004A004F0044004D00560045004A004F0048>-253<004A00550054>-253<00440050>6<0057>8<00460053>60<000D>-252<00560054004A004F0048>-253<00550049004A0054>-254<00450050>-7<00440056004E0046004F0055>-253<0044004D004200540054000F>-339<0022004D004E005000540055>-254<0042004D004D>]TJ
+0.999 0 0 1 71.036 342.725 Tm [<00500047>-250<005500490046>-250<00540046005500560051>-251<005600540046>-7<0045>-250<00450046004700420056004D00550054000F>-335<09AB0046>-250<098B004D00460054>-251<000900550046>7<005900550043004D0050>-7<0044004C>-250<0042004F0045>-250<00440050>6<0057>8<00460053>17<000A>-250<0058>7<00460053>8<0046>]TJ
+0.98 0 0 1 71.036 327.93 Tm [<005400560043004E004A0A1D0046>-7<0045>-254<00550050>-253<0042>-254<004E0042004B00500053>-254<0022004E00460053004A00440042004F>-254<0031>24<000F>10<0030>30<000F0025>29<000F>-253<005400460053>-15<0057004A00440046>-254<004A004F>]TJ
+/F57 11.3574 Tf 0.98 0 0 1 293.018 327.93 Tm [<00310025002700100039>24<000E00120042001B0013001100110012>]TJ
+/F57 11.3574 Tf 1.02 0 0 1 71.036 313.136 Tm [<004700500053004E00420055000D>-261<005500490046004F>-258<0046004D0046>-7<004400550053>7<0050004F004A00440042004D004D005A>-258<0053>7<0046>7<0057004A0046>7<0058>8<0046>-6<0045>-258<0042004F0045>-259<0042004400440046005100550046>-7<0045>]TJ
+/F61 11.3574 Tf 1.02 0 0 1 310.307 313.136 Tm [<0050004F>-258<005500490046>-258<0848005300540055>]TJ
+1.02 0 0 1 71.036 298.341 Tm [<004208680046004E00510055000F>]TJ
+/F57 11.3574 Tf 1.02 0 0 1 115.343 298.341 Tm [<0022>-313<00510053004A004F00550046>-7<0045>-314<004400500051>6<005A>-314<005800420054>-314<004A004F>-314<005500490046>-314<00420056005500490050005306DD0054>-314<00490042004F00450054>-314<0058004A00550049004A004F>-314<0042>]TJ
+1 0 0 1 70.616 283.547 Tm [<0058>8<0046>-7<0046004C000F>-333<002B005600540055>-250<004D004A004C0046>-250<0055004900420055000F>-333<0035>62<0050>-6<0050004C>-250<004E0050004F005500490054>-250<00550050>-250<00580053004A00550046>9<000D>-249<00500047>-250<004400500056005300540046>9<000F>]TJ
+1 0 0 1 88.072 268.752 Tm [<00360051>-7<0045004200550046001B>-333<0022004F00500055004900460053>-250<004200560055004900500053>-250<0053>7<00460051>-6<0050005300550054>-250<0054005600440044004600540054000F>]TJ
+0 g 0 G
+0 g 0 G
+1 0 0 1 54 253.958 Tm [<0032>29<000F>]TJ
+1.009 0 0 1 71.036 253.958 Tm [<003800490046004F>-247<002A>-247<0058>7<0050004C0046>-247<00560051>-247<00550049004A0054>-248<004E00500053004F004A004F0048000D>-247<004E005A>-247<0049004600420045>-248<00470046004D0055>-247<004D004A004C0046>-248<0042>-247<00550050>-7<00450045004D00460053>-247<004900420045>]TJ
+1.011 0 0 1 71.036 239.163 Tm [<0043>-9<0046>-7<0046004F>-248<0051>-6<00500056004F0045004A004F0048>-248<004A0055>-247<004A004F>-247<0042>-247<00540042004F00450043>-10<0050>6<0059000F>-329<002A>-247<0053>7<0050004D004D0046>-6<0045>-247<0050>6<0057>8<00460053>-246<0042004F0045>-247<004D0050>-7<0050004C0046>-7<0045>-247<00420055>-248<005500490046>]TJ
+0.98 0 0 1 71.036 224.369 Tm [<004E00560048>-234<0054004900500055>-234<0050004F>-235<005500490046>-234<00580042004D004D000F>-333<002A0055>-235<005800420054>-234<0042>-234<0058>7<0050004E0042004F>-234<004A004F>-234<004900460053>-234<0047005000530055004A00460054>-235<0058004A00550049>-234<0042>-235<0045005300560048>]TJ
+1.02 0 0 1 71.036 209.574 Tm [<004900420043004A0055>-266<0055004900420055>-265<005800420054>-266<004300420045000D>-272<0042004F0045>-266<0042004F>-266<00420A1D004A0055005600450046>-266<0055004900420055>-265<005800420054>-266<0046>6<0057>7<0046004F>-265<0058>7<0050005300540046>10<000F>-388<003400490046>]TJ
+0.98 0 0 1 71.036 194.779 Tm [<004900420045>-232<00540046>-7<0046004F>-233<0043>-10<00460A1D00460053>-233<00450042005A0054000D>-237<004D004A004C0046>-232<005500490046>-233<0055004A004E0046>-232<002A>-233<00550050>-7<0050004C>-232<004900460053>-233<00550050>-232<005500490046>-233<0046004A0048004900550049>-233<00480053004200450046>]TJ
+1.02 0 0 1 71.036 179.985 Tm [<00540050>-6<0044004C>-249<004900500051>9<000F>-337<09AB0046004F>-249<002A>-249<004800500055>-248<00560051>9<000D>-249<00580042005400490046>-7<0045000D>-250<0042004F0045>-248<004500530042004800480046>-7<0045>-249<004E005A>-249<004D0050004F0046004D005A>-248<004300560A1D>]TJ
+0.98 0 0 1 71.036 165.19 Tm [<00450050>7<0058004F>-240<00550050>-242<005500490046>-241<0050004F0046000E004E0042004F>-241<0045004600550046>-7<00440055004A0057>7<0046>-240<004200480046004F0044005A>-241<0055004900420055>-241<002A>-241<004B0050004C004A004F0048004D005A>-241<00440042004D004D0046>-7<0045>-241<004E005A>]TJ
+1 0 0 1 71.036 150.396 Tm [<004E00460042004F0054>-250<00500047>-250<004D004A0057004A004F0048000F>-333<003A>70<00500056>-249<004C004F0050>6<0058>-249<0058004900420055>-250<002A>-250<004E00460042004F0020>]TJ
+0 g 0 G
+0 g 0 G
+1 0 0 1 54 135.601 Tm [<0022000F>-585<003A>71<004600420049000F>-333<00340055004A0044004C>-250<0058004A00550049>-250<004E0046>9<000D>-249<004C004A0045000F>-333<09AB004A0054>-250<00450050>-7<00440056004E0046004F0055>-250<0044004D004200540054>-250<004A0054>-250<004700500053>-250<005A>7<00500056000F>]TJ
+0 g 0 G
+/F57 10.44878 Tf 1 0 0 1 204.571 39.437 Tm [<0014>]TJ
+0 g 0 G
+ET
+
+endstream
+endobj
+17 0 obj
+<</Type/Page/Contents 18 0 R/Resources 16 0 R/MediaBox[0 0 396 612]/CropBox[0 0 396 612]
+
+/TrimBox[0 0 396 612]/Parent 12 0 R>>
+endobj
+16 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /Font<</F57 8 0 R/F61 11 0 R>>/ProcSet[/PDF/Text]>>
+endobj
+21 0 obj
+<</Length 32 >>
+stream
+0 g 0 G
+0 g 0 G
+0 g 0 G
+0 g 0 G
+
+endstream
+endobj
+20 0 obj
+<</Type/Page/Contents 21 0 R/Resources 19 0 R/MediaBox[0 0 396 612]/CropBox[0 0 396 612]
+
+/TrimBox[0 0 396 612]/Parent 12 0 R>>
+endobj
+19 0 obj
+<< /ColorSpace 3 0 R /Pattern 2 0 R /ExtGState 1 0 R /ProcSet[/PDF]>>
+endobj
+1 0 obj
+<<>>
+endobj
+2 0 obj
+<<>>
+endobj
+3 0 obj
+<< /pgfprgb [/Pattern /DeviceRGB] >>
+endobj
+22 0 obj
+[13[219]15[219]66[486]68[389 489 401 314]73[519]77[266 783 518 447 489]83[357 353 307]87[472]89[475]2120[564]2152[606]]
+endobj
+23 0 obj
+<</Length 270 >>
+stream
+
+endstream
+endobj
+24 0 obj
+<</Subtype/CIDFontType0C/Length 5776 >>
+stream
+
+
+c # B / «hÿ«ÕÕN‹½ø콋½ø$½½øñ÷>û“û>û“©^÷>÷“÷>û“û ÷À÷>÷“‹ü’û\÷Àû>÷“÷è‹ü8ýøˆùPüˆûêû¢÷æ÷»ɸ‹sšž†›‡š‡‹y‹oÿÿÌ€
+™šÿ
+€
+€
+ÌÌÿÿìšÿ
+€
+LÍ{­‹®‹·žª¿ÿÿü33ÿ
+™šÿÿüÌÍ‹ÿÿõLÍ‹ÿÿöæfÿÿþ³3ÿÿóšÿÿùLÍo\ûb„kb‹x‹x–}©‹»‹¸­¹Æˆ”…“}‹qmn|‹ÿÿøæf‹ÿÿýš‹—‹”ÿ
+fg`ÿÿ½ff¸Ã÷ì²ôÚ÷gØø¾øA•¸”©‹—‹œƒ•k‹g‹_e~Yûo‹•¸ÿ
+² × ×
+endstream
+endobj
+25 0 obj
+<</Type/FontDescriptor/FontName/EKAOGO+LibertinusSerif-Italic/Flags 4/FontBBox[-634 -312 6171 893]/Ascent 894/CapHeight 647/Descent -246/ItalicAngle -12/StemV 73/XHeight 429/FontFile3 24 0 R/CIDSet 23 0 R>>
+endobj
+26 0 obj
+<</Length 992 >>
+stream
+%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-EKAOGO-LibertinusSerif-Italic-0)
+%%Title: (TeX-EKAOGO-LibertinusSerif-Italic-0 TeX EKAOGO-LibertinusSerif-Italic 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (EKAOGO-LibertinusSerif-Italic)
+/Supplement 0
+>> def
+/CMapName /TeX-Identity-EKAOGO-LibertinusSerif-Italic def
+/CMapType 2 def
+1 begincodespacerange
+<0000> <FFFF>
+endcodespacerange
+0 beginbfrange
+endbfrange
+20 beginbfchar
+<000D> <002C>
+<000F> <002E>
+<0042> <0061>
+<0044> <0063>
+<0045> <0064>
+<0046> <0065>
+<0047> <0066>
+<0049> <0068>
+<004D> <006C>
+<004E> <006D>
+<004F> <006E>
+<0050> <006F>
+<0051> <0070>
+<0053> <0072>
+<0054> <0073>
+<0055> <0074>
+<0057> <0076>
+<0059> <0078>
+<0848> <00660069>
+<0868> <00740074>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+
+endstream
+endobj
+11 0 obj
+<</Type/Font/Subtype/Type0/Encoding/Identity-H/BaseFont/EKAOGO+LibertinusSerif-Italic/DescendantFonts[27 0 R]/ToUnicode 26 0 R>>
+endobj
+27 0 obj
+<</Type/Font/Subtype/CIDFontType0/BaseFont/EKAOGO+LibertinusSerif-Italic/FontDescriptor 25 0 R/W 22 0 R/CIDSystemInfo<</Registry (Adobe)/Ordering (Identity)/Supplement 0>>>>
+endobj
+28 0 obj
+[27[219]32[430]37[718]56[998]66[476]68[435 527 461]73[550 286]78[801 563 519 523]83[401 401 331 550]]
+endobj
+29 0 obj
+<</Length 11 >>
+stream
+
+endstream
+endobj
+30 0 obj
+<</Subtype/CIDFontType0C/Length 3826 >>
+stream
+
+ [ ¢
+­ ¦ - š Ad‹½ø콋½ø$½½øñ÷>û“û>û“©^÷>÷“÷>û“û ÷À÷>÷“‹ü’û\÷Àû>÷“÷è‹ü8ýøˆùPüˆûÔ²÷÷,÷Õ÷Õém¤rªª¤¤©ªr¤llrrl÷›m¤rªª¤¤©ªr¤llrrlû÷øž¯¥ð”÷1ÐÆ÷ì÷øϧ®£·ÿ
+ûöq?vÏû÷ïxÄ­¯‹Ž‹£‰‹û ŠZcSŒ‹‰‰‹t†ˆ’Ž²‹}“p KŒ‚‹‚‹~ˆ~‡AûvtEtÓû ÷ö~°²‹Ž‘‹¡ˆ‹1ŠXeBŒ‹‰‰‹t†ˆ’˜§‹q”r÷Bü£–m™z¬‹LÂ÷ý±¯ô.è÷!÷
+)'û#ûÑ:÷"ҋï©È½ª÷ëµ÷V­¥w°÷÷J÷¾÷â÷ëû—giuw‹R\Ã÷÷%É®´ª‹¥q¡j÷÷„ÌŽ³‹’„Ž‚ÿÿææfÿÿ™™š~ÿÿ×€
+€
+¡ŽŽŽŽ ÷ ÷’•
+endstream
+endobj
+31 0 obj
+<</Type/FontDescriptor/FontName/IZNYRK+LibertinusSerif-Semibold/Flags 4/FontBBox[-446 -328 6171 900]/Ascent 894/CapHeight 647/Descent -246/ItalicAngle 0/StemV 81/XHeight 463/FontFile3 30 0 R/CIDSet 29 0 R>>
+endobj
+32 0 obj
+<</Length 966 >>
+stream
+%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-IZNYRK-LibertinusSerif-Semibold-0)
+%%Title: (TeX-IZNYRK-LibertinusSerif-Semibold-0 TeX IZNYRK-LibertinusSerif-Semibold 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (IZNYRK-LibertinusSerif-Semibold)
+/Supplement 0
+>> def
+/CMapName /TeX-Identity-IZNYRK-LibertinusSerif-Semibold def
+/CMapType 2 def
+1 begincodespacerange
+<0000> <FFFF>
+endcodespacerange
+0 beginbfrange
+endbfrange
+18 beginbfchar
+<001B> <003A>
+<0020> <003F>
+<0025> <0044>
+<0038> <0057>
+<0042> <0061>
+<0044> <0063>
+<0045> <0064>
+<0046> <0065>
+<0049> <0068>
+<004A> <0069>
+<004E> <006D>
+<004F> <006E>
+<0050> <006F>
+<0051> <0070>
+<0053> <0072>
+<0054> <0073>
+<0055> <0074>
+<0056> <0075>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+
+endstream
+endobj
+10 0 obj
+<</Type/Font/Subtype/Type0/Encoding/Identity-H/BaseFont/IZNYRK+LibertinusSerif-Semibold/DescendantFonts[33 0 R]/ToUnicode 32 0 R>>
+endobj
+33 0 obj
+<</Type/Font/Subtype/CIDFontType0/BaseFont/IZNYRK+LibertinusSerif-Semibold/FontDescriptor 31 0 R/W 28 0 R/CIDSystemInfo<</Registry (Adobe)/Ordering (Identity)/Supplement 0>>>>
+endobj
+34 0 obj
+[374[2000]]
+endobj
+35 0 obj
+<</Length 47 >>
+stream
+
+endstream
+endobj
+36 0 obj
+<</Subtype/CIDFontType0C/Length 471 >>
+stream
+
+¯ Ú Ú’
+endstream
+endobj
+37 0 obj
+<</Type/FontDescriptor/FontName/ETXLAD+NovelDeco/Flags 4/FontBBox[-392 -234 1985 838]/Ascent 894/CapHeight 537/Descent -246/ItalicAngle 0/StemV 61/XHeight 429/FontFile3 36 0 R/CIDSet 35 0 R>>
+endobj
+38 0 obj
+<</Length 652 >>
+stream
+%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-ETXLAD-NovelDeco-0)
+%%Title: (TeX-ETXLAD-NovelDeco-0 TeX ETXLAD-NovelDeco 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (ETXLAD-NovelDeco)
+/Supplement 0
+>> def
+/CMapName /TeX-Identity-ETXLAD-NovelDeco def
+/CMapType 2 def
+1 begincodespacerange
+<0000> <FFFF>
+endcodespacerange
+0 beginbfrange
+endbfrange
+1 beginbfchar
+<0176> <254C>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+
+endstream
+endobj
+9 0 obj
+<</Type/Font/Subtype/Type0/Encoding/Identity-H/BaseFont/ETXLAD+NovelDeco/DescendantFonts[39 0 R]/ToUnicode 38 0 R>>
+endobj
+39 0 obj
+<</Type/Font/Subtype/CIDFontType0/BaseFont/ETXLAD+NovelDeco/FontDescriptor 37 0 R/W 34 0 R/CIDSystemInfo<</Registry (Adobe)/Ordering (Identity)/Supplement 0>>>>
+endobj
+40 0 obj
+[2[288]9[298 298]13[220 338 220 323 465 465 465 465 465 465]27[236]32[435]34[695 588 646 701 557 485 685 730 297 322]45[528 839 699 702 541 702 587 485 597 661 652 951 660 575 604]66[457 493 428 506 447 310 500 538 271 272 512 264 790 542 504 519 503 372 390 316 531 497 747 490 515 424]1752[742]1757[268]1760[375 375]2442[582 560 540]2475[1048]2589[614]2592[465 465 465 465 465 465 465 465 465]]
+endobj
+41 0 obj
+<</Length 326 >>
+stream
+ gþ¿÷ÿð?ÿÿð
+endstream
+endobj
+42 0 obj
+<</Subtype/CIDFontType0C/Length 18212 >>
+stream
+
+) "
+
+
+
+!
+"
+#
+$
+%
+&
+'
+(
+½ º ž …«^€MÒ€(%—F觞๠ • è!ê"a"ï#þ%7%Ô&Y'Ë(")¶*³+J,¦-µ.–/Y0%0ü1ì374è6"727U7™88Ž9Õ:ï;Þ=Õ??F?Ì@„AhBB˜CQCÊD,‹½ø龋½ø$½½øï÷>û’û>û’©^÷>÷’÷>û’û ÷¿÷>÷’‹üû\÷¿û>÷‘÷è‹ü8ýøˆùNüˆûÇõøÆwæõ÷$ù&snxU‹E™h”3“=‘1vŒ…Ž„•‹•‹Ž”Œ–™‹Ç˜÷
+÷«¯ÿÿü™šÿ
+LÍÿÿùÌÌÿ
+ûkgÿ
+‹ûZ‹ÿÿ•ffÿ
+LÍÿ
+ÌÍÿ
+‹è¤ÏÅ€”†“‹–÷‹ÿ
+ffÿ
+ûDo*[÷y¨—®Ò8ü„÷=ß‹ÿ
+€
+eŽ‰‹‰‰‹Š‡^W€[•‡—Š—‹¼ŸÛ¹¥Í‹¼°•eNü‹8z†;ˆ……‹v‘…¼Œÿ
+ffÿ
+÷,ÿ
+™špÿ
+LÍ—‘‹–ÿÿöÌÍÿ
+€
+LÍÿÿýæfÿ
+LÍÿÿýæfÿ
+LÍÿÿýæfÿ
+33ÿÿûÌÍÿ
+LÍÿÿýæfÿ
+³3u¢€·…¤…‘xŠ……û«Â÷í²äÚ¶øA}‡ƒ~†ŒŠÆûÁDªo¹¹‹½¡²·‰ÿ
+LÍ…ÿ
+æfÿ
+æfÿÿõÌÍÿ
+²÷øª¡ §‹ÿ
+²÷šùNluvo‹ÿÿà€
+³3ÿÿçš”w”w¥‹ÿ
+eŽ‰‹‰‰‹Š‡^W€[•‡—Š—‹۹¥Í‹¼°•eNü‹8z†;ˆ……‹v‘…¼Œÿ
+LÍ…ÿ
+±ÎÓ®û22ûû'á9÷÷ÞÞ÷&÷BÝûû‰¬÷檵w÷jØ÷j÷‹8p†Eˆ……‹v‘…¼Œÿ
+æ€ÿÿüæ€ÿ
+€ÿÿþÌÀ–ÿ
+¯ Ú Ú’
+endstream
+endobj
+43 0 obj
+<</Type/FontDescriptor/FontName/VEKDRV+LibertinusSerif/Flags 4/FontBBox[-1082 -256 6171 1125]/Ascent 894/CapHeight 647/Descent -246/ItalicAngle 0/StemV 73/XHeight 429/FontFile3 42 0 R/CIDSet 41 0 R>>
+endobj
+44 0 obj
+<</Length 1865 >>
+stream
+%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-VEKDRV-LibertinusSerif-0)
+%%Title: (TeX-VEKDRV-LibertinusSerif-0 TeX VEKDRV-LibertinusSerif 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (VEKDRV-LibertinusSerif)
+/Supplement 0
+>> def
+/CMapName /TeX-Identity-VEKDRV-LibertinusSerif def
+/CMapType 2 def
+1 begincodespacerange
+<0000> <FFFF>
+endcodespacerange
+0 beginbfrange
+endbfrange
+84 beginbfchar
+<0002> <0021>
+<0009> <0028>
+<000A> <0029>
+<000D> <002C>
+<000E> <002D>
+<000F> <002E>
+<0010> <002F>
+<0011> <0030>
+<0012> <0031>
+<0013> <0032>
+<0014> <0033>
+<0015> <0034>
+<0016> <0035>
+<001B> <003A>
+<0020> <003F>
+<0022> <0041>
+<0023> <0042>
+<0024> <0043>
+<0025> <0044>
+<0026> <0045>
+<0027> <0046>
+<0028> <0047>
+<0029> <0048>
+<002A> <0049>
+<002B> <004A>
+<002D> <004C>
+<002E> <004D>
+<002F> <004E>
+<0030> <004F>
+<0031> <0050>
+<0032> <0051>
+<0033> <0052>
+<0034> <0053>
+<0035> <0054>
+<0036> <0055>
+<0037> <0056>
+<0038> <0057>
+<0039> <0058>
+<003A> <0059>
+<003B> <005A>
+<0042> <0061>
+<0043> <0062>
+<0044> <0063>
+<0045> <0064>
+<0046> <0065>
+<0047> <0066>
+<0048> <0067>
+<0049> <0068>
+<004A> <0069>
+<004B> <006A>
+<004C> <006B>
+<004D> <006C>
+<004E> <006D>
+<004F> <006E>
+<0050> <006F>
+<0051> <0070>
+<0052> <0071>
+<0053> <0072>
+<0054> <0073>
+<0055> <0074>
+<0056> <0075>
+<0057> <0076>
+<0058> <0077>
+<0059> <0078>
+<005A> <0079>
+<005B> <007A>
+<06D8> <2014>
+<06DD> <2019>
+<06E0> <201C>
+<06E1> <201D>
+<098A> <00660066>
+<098B> <00660069>
+<098C> <0066006C>
+<09AB> <00540068>
+<0A1D> <00740074>
+<0A20> <0030>
+<0A21> <0031>
+<0A22> <0032>
+<0A23> <0033>
+<0A24> <0034>
+<0A25> <0035>
+<0A26> <0036>
+<0A27> <0037>
+<0A28> <0038>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+
+endstream
+endobj
+8 0 obj
+<</Type/Font/Subtype/Type0/Encoding/Identity-H/BaseFont/VEKDRV+LibertinusSerif/DescendantFonts[45 0 R]/ToUnicode 44 0 R>>
+endobj
+45 0 obj
+<</Type/Font/Subtype/CIDFontType0/BaseFont/VEKDRV+LibertinusSerif/FontDescriptor 43 0 R/W 40 0 R/CIDSystemInfo<</Registry (Adobe)/Ordering (Identity)/Supplement 0>>>>
+endobj
+12 0 obj
+<</Type/Pages /Count 4/Kids[6 0 R 14 0 R 17 0 R 20 0 R]>>
+endobj
+46 0 obj
+<</Type/Catalog/Pages 12 0 R /Metadata 4 0 R/OutputIntents [ <</Type/OutputIntent/S/GTS_PDFX/OutputCondition (SWOP (Publication) printing in USA (Printing process definition: ANSI CGATS.6).)/OutputConditionIdentifier (CGATS TR 001)/Info (U.S. Web Coated (SWOP) v2)/RegistryName (http://www.color.org)>> ]>>
+endobj
+47 0 obj
+<<
+ /Title(Novel\040Document\040Class)/Creator(LuaLaTeX\040with\040novel\040and\040microtype)/CreationDate(D:20180425140252-07'00')/ModDate(D:20180425140252-07'00')/Producer(LuaLaTeX\040with\040novel-pdfx\040and\040hyperref)/Trapped/False/GTS_PDFXVersion(PDF/X-1a:2001)/GTS_PDFXConformance(PDF/X-1a:2001)
+>>
+endobj
+xref
+0 48
+0000000000 65535 f
+0000033600 00000 n
+0000033620 00000 n
+0000033640 00000 n
+0000000015 00000 n
+0000015196 00000 n
+0000015055 00000 n
+0000006731 00000 n
+0000070426 00000 n
+0000048893 00000 n
+0000046955 00000 n
+0000041283 00000 n
+0000070746 00000 n
+0000024265 00000 n
+0000024121 00000 n
+0000015337 00000 n
+0000033160 00000 n
+0000033016 00000 n
+0000024386 00000 n
+0000033514 00000 n
+0000033370 00000 n
+0000033281 00000 n
+0000033693 00000 n
+0000033829 00000 n
+0000034156 00000 n
+0000040011 00000 n
+0000040234 00000 n
+0000041428 00000 n
+0000041618 00000 n
+0000041736 00000 n
+0000041804 00000 n
+0000045709 00000 n
+0000045932 00000 n
+0000047102 00000 n
+0000047294 00000 n
+0000047322 00000 n
+0000047426 00000 n
+0000047976 00000 n
+0000048184 00000 n
+0000049024 00000 n
+0000049201 00000 n
+0000049614 00000 n
+0000049997 00000 n
+0000068288 00000 n
+0000068504 00000 n
+0000070563 00000 n
+0000070820 00000 n
+0000071143 00000 n
+trailer
+<</Size 48/Root 46 0 R/Info 47 0 R/ID[<66C207AB9E1E764B97BB23DE55BCCEC2> <66C207AB9E1E764B97BB23DE55BCCEC2>]>>
+startxref
+71467
+%%EOF
diff --git a/macros/luatex/latex/novel/doc/novel.tex b/macros/luatex/latex/novel/doc/novel.tex
new file mode 100644
index 0000000000..98189b5d42
--- /dev/null
+++ b/macros/luatex/latex/novel/doc/novel.tex
@@ -0,0 +1,125 @@
+% !TeX TS-program = LuaLaTeX
+% !TeX encoding = UTF-8
+%
+% SOURCE CODE FOR FILE novel.pdf, the cover info for novel document class.
+% IF YOU COMPILE THIS DOCUMENT: Be sure that both this file and
+% novel.pdf (if present) have read/write permissions for any user.
+% Otherwise, compile may fail at the point where files are written.
+\documentclass{novel} % v. 1.52.
+% Almost all settings are defaults.
+\SetHeadFootStyle{3}
+\SetTitle{Novel Document Class} % only footer, with page number
+% The following PDF/X standard is typical for USA print-on-demand.
+% However, not every P.O.D. service needs PDF/X these days.
+\SetPDFX[CGATSTR001]{X-1a:2001}
+\begin{document}
+\begin{ChapterStart}[8]
+\vspace{\nbs} % \nbs is normal baselineskip
+\ChapterTitle{NOVEL}
+\vspace{\nbs}
+\ChapterSubtitle{A Document Class for the Rest of Us}
+\vspace{\nbs}
+\ChapterDeco[4]{\decoglyph{n9548}}
+\end{ChapterStart}
+
+\textbf{Where is the documentation??} It is in HTML format, and cannot be retrieved via \textit{texdoc}. If you have this package installed, look for (texroot)/doc/lualatex/novel/novel-documentation.html. If you are online, go to the CTAN page at https://ctan.org/pkg/novel and click ``Package Documentation (HTML).''
+
+\scenebreak
+
+\textbf{Description:} The \emph{novel} document class is for writers of original fiction, to be printed to paper, with attention to the requirements of the print-on-demand market. Non-color interiors and color covers are supported. Images are supported, but only as they might be used in fiction, not picture books.
+
+If your work is an E-book, or uses interior color other than gray, or is academic, then this document class is not for you.
+
+But if you are writing a detective novel, or science fiction, or a collection of short stories, then read on!
+
+\QuickChapter{1. Features}
+
+Throughout, it is assumed that the purpose of your writing is a commercially printed book of fiction.
+
+A new \emph{novel} is pre-configured to produce a standard trade book size of 5.5in W x 8.5in H, with layout margins that are likely to be acceptable to the most widely-used print services. The file you are now reading is in this format. But if that is not the size or layout you want, then there are commands that configure just about anything, using standard terminology and understandable purpose. Best of all, the HTML documentation comes with images and examples, so you know what you are doing.
+
+Almost everything is pre-configured to “just work,†even the choice of fonts. The chosen compiler is LuaLaTeX, and Open Type fonts are loaded using \textit{fontspec} technology. If you prefer to use a professional font, it will be easy to load and use in utf-8.
+
+Many standard LaTeX commands are disabled. This will be surprising at first. But \emph{novel} is focused on one thing only. Anything that might interfere with that purpose may have been tossed aside. So, be sure that you read the documentation! If you take an existing LaTeX document and just change the class to \emph{novel,} it is very unlikely to work as expected.
+
+Many new commands are provided. They are focused on the needs of print fiction writers, period. And, \emph{novel} has built-in PDF/X technology that exceeds the capabilities currently available via other LaTeX packages.
+
+\QuickChapter{2. Complete Documentation}
+
+What you are reading now, is only an introduction. The complete documentation is in HTML format, directly written in HTML rather than extracted from code. There are numerous examples and images, too detailed to be presented as PDF.
+
+\QuickChapter{3. License}
+
+The LaTeX code, and accompanying documentation, is released under the LateX Project Public License, version 1.3c or later.
+
+The companion font(s) is(are) licensed under the SIL Open Font License, version 1.1.
+
+
+
+\QuickChapter{4. Version}
+
+\noindent 1.52, 2018-04-26: Enhanced detection and warning using Lua code.
+
+\noindent 1.50.5, 2018-04-11: Minor bug fixes (docs and code disagreed).
+
+\noindent 1.50, 2018-03-28: Improved image handling commands, sandbox.
+
+\noindent 1.46.2, 2018-01-14: Stable "old" version. Use newer 1.50.
+
+\noindent 1.1, 2017-03-01: initial public release.
+
+\clearpage
+
+\QuickChapter{5. FAQs}
+
+\begin{adjustwidth}{\parindent}{0pt}
+\backindent\makebox[\parindent][l]{Q. }Can this document class be used for E-books?
+\end{adjustwidth}
+\begin{adjustwidth}{\parindent}{0pt}
+\backindent\makebox[\parindent][l]{A. }No. And, that feature will never be added, as the technology is inherently incompatible. A word processor is your friend.
+\end{adjustwidth}
+
+\begin{adjustwidth}{\parindent}{0pt}
+\backindent\makebox[\parindent][l]{Q. }What happened to floats and lists?
+\end{adjustwidth}
+\begin{adjustwidth}{\parindent}{0pt}
+\backindent\makebox[\parindent][l]{A. }Use the new image commands, or sandbox mode.
+\end{adjustwidth}
+
+\begin{adjustwidth}{\parindent}{0pt}
+\backindent\makebox[\parindent][l]{Q. }My thesis advisor told me---
+\end{adjustwidth}
+\begin{adjustwidth}{\parindent}{0pt}
+\backindent\makebox[\parindent][l]{A. }Stop right there. This document class is very different from anything used for theses and other academic publications.
+\end{adjustwidth}
+
+\begin{adjustwidth}{\parindent}{0pt}
+\backindent\makebox[\parindent][l]{Q. }If I use TikZ for Feynman diagrams, then---
+\end{adjustwidth}
+\begin{adjustwidth}{\parindent}{0pt}
+\backindent\makebox[\parindent][l]{A. }Go away.
+\end{adjustwidth}
+
+\begin{adjustwidth}{\parindent}{0pt}
+\backindent\makebox[\parindent][l]{Q. }Has this document class ever been used for an actual novel?
+\end{adjustwidth}
+\begin{adjustwidth}{\parindent}{0pt}
+\backindent\makebox[\parindent][l]{A. }Yes indeed! In August 2017 the author published a complete novel, including its cover, using this document class. Almost all of the setup used defaults. The files (textblock and cover) were submitted to a major American P.O.D. service in \lnum{PDF/X-1a:2001} format, then electronically reviewed and accepted \textit{on the first attempt.} A printed copy was in the author's hands within a week. Just like that. Took months to write, of course.\par
+Update: Another author reports success.
+\end{adjustwidth}
+
+\begin{adjustwidth}{\parindent}{0pt}
+\backindent\makebox[\parindent][l]{Q. }When I woke up this morning, my head felt like a toddler had been pounding it in a sandbox. I rolled over and looked at the mug shot on the wall. It was a woman in her forties with a drug habit that was bad, and an attitude that was even worse. She had seen better days, like the time I took her to the eighth grade sock hop. Then I got up, washed, and dragged my lonely butt down to the one-man detective agency that I jokingly called my means of living. You know what I mean?
+\end{adjustwidth}
+\begin{adjustwidth}{\parindent}{0pt}
+\backindent\makebox[\parindent][l]{A. }Yeah. Stick with me, kid. This document class is for you.
+\end{adjustwidth}
+
+\end{document}
+
+
+
+
+
+
+
diff --git a/macros/luatex/latex/novel/fonts/NovelDeco.otf b/macros/luatex/latex/novel/fonts/NovelDeco.otf
new file mode 100644
index 0000000000..b0c81ecb61
--- /dev/null
+++ b/macros/luatex/latex/novel/fonts/NovelDeco.otf
Binary files differ
diff --git a/macros/luatex/latex/novel/novel-CGATSTR001.clo b/macros/luatex/latex/novel/novel-CGATSTR001.clo
new file mode 100644
index 0000000000..a550245b83
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-CGATSTR001.clo
@@ -0,0 +1,28 @@
+%%
+%% This is file `novel-CGATSTR001.clo', part of `novel' document class.
+%% The values of the arguments are public industry standards.
+%%
+\ProvidesFile{novel-CGATSTR001.clo}%
+[2018/01/14 any version. (novel Output Intent CGATS TR 001)]
+%%
+
+% Typically used in the USA.
+
+% Remember: TeX special characters must be backslashed here.
+% You may see % or # or _ in the data or file names.
+% Be sure that they are written as \% \# \_ or there will be trouble.
+
+% If any line is long, let it wrap. Do not attempt to break it onto multiple lines.
+
+% This identifier has spaces, even though file name has no spaces.
+\gdef\@OIidentifier{CGATS TR 001} % also called "reference name"
+\gdef\@OIcondition{SWOP (Publication) printing in USA (Printing process definition: ANSI CGATS.6).}
+\gdef\@OIinfo{U.S. Web Coated (SWOP) v2}
+\gdef\@OIregistry{http://www.color.org}
+\gdef\@OIprofile{USWebCoatedSWOP.icc}
+
+%%
+\endinput
+%%
+%% end of file `novel-CGATSTR001.clo'
+
diff --git a/macros/luatex/latex/novel/novel-CalculateLayout.sty b/macros/luatex/latex/novel/novel-CalculateLayout.sty
new file mode 100644
index 0000000000..fbb8671302
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-CalculateLayout.sty
@@ -0,0 +1,328 @@
+%%
+%% This is file `novel-CalculateLayout.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%% It may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-CalculateLayout.sty}%
+[2018/04/26 v1.52 LaTeX file (layout calculations)]
+%%
+
+%%
+%% This file is loaded \AtEndPreamble, which precedes \AtBeginDocument.
+%%
+
+
+
+%% PROVIDE DEFAULT TRIM SIZE, MARGINS, AND NORMAL EM SIZE, IF NOT SET BY USER
+%% ----------------------------------------------------------------------------
+% Default Trim Size is 5.5in W x 8.5in H, unless \SetTrimSize used.
+% This size is typical of American P.O.D. softcover fiction:
+\if@SetTrimSize\else
+ \gsetlength\@TrimWidth{5.5in}
+ \gsetlength\@TrimHeight{8.5in}
+\fi
+% Default margins based on Trim Height, unless \SetMargins used:
+\if@SetMargins\else
+ \ifdimcomp{\@TrimHeight}{<}{8.99in}{ % small sizes:
+ \gsetlength\@TopMargin{0.5in}
+ \gsetlength\@OuterMargin{0.5in}
+ \gsetlength\@BottomMargin{0.5in}
+ \gsetlength\@InnerMargin{0.75in}
+ }{ % medium sizes:
+ \ifdimcomp{\@TrimHeight}{<}{9.99in}{ %
+ \gsetlength\@TopMargin{0.75in}
+ \gsetlength\@OuterMargin{0.75in}
+ \gsetlength\@BottomMargin{0.75in}
+ \gsetlength\@InnerMargin{1in}
+ }{ % large sizes:
+ \gsetlength\@TopMargin{1in}
+ \gsetlength\@OuterMargin{1in}
+ \gsetlength\@BottomMargin{1in}
+ \gsetlength\@InnerMargin{1.25in}
+ } %
+ } %
+\fi
+% Default normal em size is based on Trim Width:
+\if@FontSizeSet\else
+ \ifdimcomp{\@TrimWidth}{<}{5.49in}{
+ \gsetlength\@SetFontSize{11pt} % smaller books
+ }{
+ \ifdimcomp{\@TrimWidth}{<}{6.24in}{
+ \gsetlength\@SetFontSize{11.4pt} % medium books
+ }{
+ \gsetlength\@SetFontSize{12pt} % larger books
+ } %
+ } %
+\fi
+%% end set default trim, margins, normal em size.
+
+
+%% THEORY OF PAGE LAYOUT
+%% ----------------------------------------------------------------------------
+% The "available width" is the trim width minus the outer and inner margins:
+\newlength\@AvailableWidth
+\gsetlength\@AvailableWidth{\@TrimWidth-\@OuterMargin-\@InnerMargin}
+% The "occupied width" of the text block is the TeX dimension \textwidth.
+% Your originally set layout can always fill the available width,
+% although that is not always true when using \Rework:
+\gsetlength\textwidth{\@AvailableWidth}
+% The "available height" is the trim height minus the top and bottom margins:
+\newlength\@AvailableHeight
+\gsetlength\@AvailableHeight{\@TrimHeight-\@TopMargin-\@BottomMargin}
+% The "occupied height" includes header, textblock, footer, and allowances
+% for risers/diacriticals at top, descenders at bottom. It must fit within
+% the available height. This is the tricky part, so pay attention:
+% In `novel' class, the topmost line of text (main block or header)
+% is positioned with its baseline at 1 normal em below available top.
+% That provides good clearance for uppercase letters with diacritical marks.
+% The lowermost line of text (main block or footer) is positioned with its
+% baseline at 0.3 normal em above available bottom. This provides
+% good clearance for descenders.
+% So, if your text does not have uppercase diacriticals, or if you use
+% a footer with lining numbers (no descenders), then the upper/lower margins
+% will appear to be a little larger than you set them.
+% The headjump includes the line itself, plus any added gap to the main text.
+% An unused jump is re-set to 0:
+\if@HasHeader\else\gdef\@HeadJump{0}\fi
+%%
+% TeX assumes that your layout has a footer, even if you do not want one.
+% Novel handles this by setting the baseline of the mandatory footer at
+% 1 normal baselineskip below the last line of main text. Then, one line is
+% subtracted from the occupied line count. That places the empty, unused
+% virtual footer in the lower margin, where it does not matter. When you
+% do have a footer, the necessary line space is added, and the content
+% is positioned from the virtual footer using \smash and \raisebox.
+% Yes, it is complicated, but it handles more layout possibilities.
+% The \@FootJumpFix is one less than \@FootJump, or -1 when no footer:
+\if@HasFooter
+ \FPsub\@FootJumpFix{\@FootJump}{1}
+\else
+ \gdef\@FootJumpFix{-1}
+\fi
+% Putting it all together, the "occupied height" is:
+% 1.3\@SetFontSize + (\@HeadJump+\@LinesPerPage+\@FootJumpFix)\baselineskip
+%
+%% end theory of page layout.
+
+
+%% SET DEFAULT LINES PER PAGE, IF NOT SET BY USER
+%% ----------------------------------------------------------------------------
+% Lines per page refers only to the main text block, not header/footer:
+\if@LinesPerPage\else
+ % Estimate \baselineskip as 1.3\@SetFontSize, which is a comfortable value.
+ % Calculate resulting \@LinesPerPage, then proceed as if set.
+ % Actual \baselineskip will be re-calculated later.
+ \edef\@tempLPP{%
+ \fpeval{% package xfp
+ (\@AvailableHeight - 0.3\@SetFontSize) % adjusts for final descenders
+ / (1.3*\@SetFontSize) % denominator, with desired skip/em ratio
+ -\@HeadJump -\@FootJumpFix % adjustments
+ }%
+ } %
+ \FPtrunc{\@LinesPerPage}{\@tempLPP}{0} % final, integer floor
+\fi
+% Error if too few lines per page, whether set or default:
+\FPiflt{\@LinesPerPage}{2}
+ \ClassError{novel}{Calculated LinesPerPage less than 2}%
+ {Too few lines. Either font size too big, or text height too small.}%
+\fi
+%% end set default lines per page.
+
+
+%% CALCULATE BASELINESKIP
+%% ----------------------------------------------------------------------------
+% In `novel' class, the user does not directly set line-to-line spacing,
+% known as \baselineskip. Instead, \baselineskip is calculated from other
+% settings, so that "occupied height" fills "available height."
+% See the above theory of layout, for the equations. Solve for \baselineskip =
+% (\@AvailableHeight-1.3\@SetFontSize) divided by
+% (\@HeadJump+\@LinesPerPage+\@FootJumpFix)
+%
+\xdef\@AdjLPP{\fpeval{\@HeadJump+\@LinesPerPage+\@FootJumpFix}} % used often
+\edef\@tempBLS{%
+ \fpeval{(\@AvailableHeight-1.3\@SetFontSize) / \@AdjLPP}%
+} %
+\FPtrunc\@tempBLS{\@tempBLS}{2} % round down to 2 decimalplaces
+\gsetlength\baselineskip{\@tempBLS pt}
+%
+% Error if \baselineSkip is too tight, in relation to normal em size:
+\ifdimcomp{\baselineskip}{<}{1.2\@SetFontSize}{%
+ \ClassError{novel}{Calculated baselineskip is too small}%
+ {Default baselineskip is calculated from normal em size, ^^J%
+ available text height, and lines per page. Result is too small. ^^J%
+ Change something, then try again.}%
+}{}%
+%% end calculate baselineskip.
+
+
+%% LOAD REWORK, IF USED
+%% REWORK IS EXPERIMENTAL CODE. NOT DOCUMENTED.
+%% ----------------------------------------------------------------------------
+% Note that \Rework does not change lines per page.
+\gdef\@TMratio{1}
+\if@ReworkTrimSize
+ \ObsoleteRework
+\else
+ \if@ReworkMargins
+ \ObsoleteRework
+ \fi
+\fi
+%% end load rework.
+
+
+%% FINISH LAYOUT (but post-layout deals with special class options)
+%% ----------------------------------------------------------------------------
+% Caution if font size (set or reworked) is small:
+\ifdimcomp{\@SetFontSize}{<}{10pt}{ %
+ \typeout{^^JClass `novel' Alert: Normal font at less than 10pt. ^^J%
+ Whether or not this is too small, depends on circumstances. ^^J%
+ Beware if you use footnotes, which are smaller. ^^J%
+ }
+}{} %
+\ifdimcomp{\@SetFontSize}{<}{8.03pt}{ % 8 PostScript points (TeX bp)
+ \ClassWarning{novel}{^^JNormal font at less than 8 points. ^^J%
+ This is usually undesirable. May be rejected by some print services. ^^J%
+ }
+}{} %
+% Default Media Size is same as Trim Size, unless \SetMediaSize used:
+\if@MediaSize\else
+ \gsetlength\paperwidth{\@TrimWidth}
+ \gsetlength\paperheight{\@TrimHeight}
+\fi
+% Sanity check for cover art, which needs bleed:
+\if@coverart
+ \setlength\@tempLength{\paperwidth-\@TrimWidth}
+ \ifthenelse{\dimtest{\@tempLength}{<}{6mm}}{%
+ \ClassWarning{novel}{^^JBIG BAD WARNING! Insufficient bleed width ?^^J%
+ Commercial printers generally require 0.125in (3mm) bleed,^^J%
+ on all four sides of the Trim. But your dimensions do not provide this.^^J%
+ Perhaps you need to increase the Media Width ?^^J}
+ }{}
+ \ifthenelse{\dimtest{\@tempLength}{>}{0.5in}}{%
+ \ClassWarning{novel}{^^JBIG BAD WARNING! Too much bleed width ?^^J%
+ Commercial printers generally require 0.125in (3mm) bleed,^^J%
+ on all four sides of the Trim. Sometimes as much as 0.25in (6mm) each.^^J%
+ But your dimensions provide more than this.
+ Perhaps you need to decrease the Media Width ?^^J}
+ }{}
+ \setlength\@tempLength{\paperheight-\@TrimHeight}
+ \ifthenelse{\dimtest{\@tempLength}{<}{5.83mm}}{% allows for pixel rounding
+ \ClassWarning{novel}{^^JBIG BAD WARNING! Insufficient bleed height ?^^J%
+ Commercial printers generally require 0.125in (3mm) bleed,^^J%
+ on all four sides of the Trim. But your dimensions do not provide this.^^J%
+ Perhaps you need to increase the MediaSize ?^^J}
+ }{}
+ \ifthenelse{\dimtest{\@tempLength}{>}{0.507in}}{% allows for pixel rounding
+ \ClassWarning{novel}{^^JBIG BAD WARNING! Too much bleed height ?^^J%
+ Commercial printers generally require 0.125in (3mm) bleed,^^J%
+ on all four sides of the Trim. Sometimes as much as 0.25in (6mm) each.^^J%
+ But your dimensions provide more than this.
+ Perhaps you need to decrease the MediaSize ?^^J}
+ }{}
+\fi
+% \textheight, normal font size, etc:
+\gsetlength\textheight{\@LinesPerPage\baselineskip}
+\renewcommand\normalsize{%
+ \@setfontsize\normalsize{\strip@pt\@SetFontSize}{\strip@pt\baselineskip}%
+}
+\normalsize % from this point, the "real" normal font size is effective
+%
+
+%
+\if@HasHeader
+ % \headheight is mis-named. Text "height" is supposed to be measured upward
+ % from the baseline. But \headheight is measured from 0.3em below
+ % the baseline, to allow for descenders. Thus, to provide actual "height"
+ % of 1em, \headheight must be set to 1.3em:
+ \gsetlength\headheight{1.3\@SetFontSize}
+ % \headsep is a confusing term. It is the separation between the nominal
+ % 0.3em descenders of header text, and one baseline above the baseline
+ % of the top line of main text. Got that? Let me do the thinking for you:
+ \gsetlength\headsep{\@HeadJump\baselineskip-\baselineskip-0.3\@SetFontSize}
+\else % no header, no problem:
+ \gsetlength\headheight{0pt}
+ \gsetlength\headsep{0pt}
+\fi
+% \oddsidemargin is at the left (inner, spine edge) of recto pages.
+% Measured 1in (72.27pt) inside MediaBox, to the textblock. May be negative.
+
+ \gsetlength\oddsidemargin{%
+ \@InnerMargin+0.5\paperwidth-0.5\@TrimWidth-72.27pt%
+ }
+
+%
+% \evensidemargin is at the left (outer edge) of verso pages.
+
+ \gsetlength\evensidemargin{%
+ \@OuterMargin+0.5\paperwidth-0.5\@TrimWidth-72.27pt%
+ }
+
+%
+\if@closecrop
+ \gsetlength\oddsidemargin{-0.9in}
+ \gsetlength\evensidemargin{-0.9in}
+\fi
+%
+% \topmargin is measured from 1in (72.27pt) below the top of the MediaBox,
+% to the top of whatever comes first (header or textblock). May be negative.
+% For consistency, the topmost baseline (header or main text) will be
+% positioned at 1em below the margin.
+
+ \gsetlength\topmargin{\@TopMargin+0.5\paperheight-0.5\@TrimHeight-72.27pt}
+ \if@HasHeader\else
+ \gsetlength\topmargin{\topmargin-\baselineskip+\@SetFontSize}
+ \fi
+
+% novel.cls sets a tentative em size (probably 10pt) so that packages requiring
+% an integer point size of 10, 11, or 12 will load without complaint.
+% Then, the real point size is established here, when it is too late for
+% such packages to complain. Sneaky, eh?
+% However, TeX places a strut in the header, rising 0.7x tentative size above
+% the header baseline. If the real size is too small, then the strut is
+% too large, which displaces the header text downward, simultaneously
+% shrinking the headsep and possibly affecting the textblock position.
+% This unlikely problem cannot be fixed by adjusting the headheight, but it
+% can be fixed by adjusting the topmargin and headsep to compensate:
+\ifdimcomp{\@SetFontSize}{<}{\@TentativeEmN pt}{ %
+ \setlength\@tempLength{\@TentativeEmN pt}
+ \gsetlength\topmargin{\topmargin-0.7\@tempLength+0.7\@SetFontSize}
+ \gsetlength\headsep{\headsep+0.7\@tempLength-0.7\@SetFontSize}
+}{} %
+%%
+% It seems that, unless specified by user, TeX may place the top text baseline
+% in a vertical position that depends on the height of text in that line.
+% That height may vary, depending on ascenders or diacriticals there.
+% In order to fix the position, \topskip gets a non-flexible setting.
+% The best value is normal baselineskip, partly because it looks right,
+% and also to avoid underfull vboxes on nearly every page.
+\gsetlength\topskip{\baselineskip} % absorber
+% In `novel' class, footers are done in an unusual manner, as explained above.
+% To fix the position of the virtual footer baseline:
+\gsetlength\footskip{\baselineskip}
+%% Sanity check: Trim Size must be contained within Media Size.
+\ifthenelse{%
+ \dimtest{\@TrimWidth}{>}{\paperwidth} %
+ \OR \dimtest{\@TrimHeight}{>}{\paperheight}%
+}{%
+ \ClassError{novel}{Media Size too small for TrimSize}%
+ {You wrote \string\SetMediaSize\space with length(s) too small ^^J%
+ for the default Trim Size or your values in \string\SetTrimSize.}%
+}{} %
+% end sanity check
+%% end finish layout.
+
+
+%%
+\endinput
+%%
+%% End of file `novel-CalculateLayout.sty'.
+
+
diff --git a/macros/luatex/latex/novel/novel-ChapterScene.sty b/macros/luatex/latex/novel/novel-ChapterScene.sty
new file mode 100644
index 0000000000..e297eeacd3
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-ChapterScene.sty
@@ -0,0 +1,406 @@
+%%
+%% This is file `novel-ChapterScene.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-ChapterScene.sty}%
+[2018/04/26 v1.52 LaTeX file (chapter and scene macros)]
+%%
+
+
+% Each new chapter generally has its own header/footer style. This allows a
+% default setting when chapters begin with ChapterStart environment:
+\gdef\SetChapterStartStyle#1{% from v. 1.40.3
+ \@tempTFfalse%
+ \ifthenelse{\equal{#1}{fancy}}{\@tempTFtrue}{}%
+ \ifthenelse{\equal{#1}{empty}}{\@tempTFtrue}{}%
+ \ifthenelse{\equal{#1}{plain} %
+ \OR \equal{#1}{fancyplain} \OR \equal{#1}{footer}}{%
+ \@tempTFtrue%
+ }{}%
+ \ifthenelse{\equal{#1}{forcenumber}}{\@tempTFtrue}{}%
+ \ifthenelse{\equal{#1}{dropfolioinside} %
+ \OR \equal{#1}{dropfolio} \OR \equal{#1}{dropfoliolater}}{%
+ \@tempTFtrue%
+ }{}%
+ \ifthenelse{\equal{#1}{dropfoliobeneath}}{\@tempTFtrue}{}%
+ \if@tempTF%
+ \gdef\@setchapterstart{#1}%
+ \else%
+ \ClassError{novel}{Invalid choice for \string\SetChapterStartStyle}%
+ {Choose: fancy, empty, plain, footer, forcenumber, %
+ dropfolioinside, dropfoliobeneath.}%
+ \fi%
+}
+\let\SetChapterStart\SetChapterStartStyle\relax % deprecated from v1.40.3.
+\SetChapterStartStyle{footer} % default
+% New in version 1.40.2:
+\gdef\SetChapterStartHeight#1{%
+ \FPifint{#1}\else%
+ \ClassError{novel}{\string\SetChapterStartHeight\space integer >= 4}%
+ {Height of ChapterStart must be integer, greater than or equal to 4.}%
+ \fi%
+ \FPiflt{#1}{4}%
+ \ClassError{novel}{\string\SetChapterStartHeight\space integer >= 4}%
+ {Height of ChapterStart must be integer, greater than or equal to 4.}%
+ \else\fi%
+ \gdef\@setchapterstartheight{#1}%
+}
+\SetChapterStartHeight{10} % default
+% See novel.cls for the accompanying AtBeginDocument routine.
+% Scene breaks:
+% \SetScenebreakIndent controls whether line after \scenebreak, \sceneline,
+% or \scenestars will be indented. Set true or false, default false.
+%% End reserve space for header/footer and set default ChapterStart
+\newif\if@IndentAfterScenebreak
+\newcommand\SetScenebreakIndent[1]{% true or false, default false.
+ \@tempTFfalse
+ \ifthenelse{\equal{#1}{true}}{%
+ \@tempTFtrue
+ \global\@IndentAfterScenebreaktrue
+ }{}%
+ \ifthenelse{\equal{#1}{false}}{%
+ \@tempTFtrue
+ \global\@IndentAfterScenebreakfalse
+ }{}%
+ \if@tempTF\else%
+ \ClassError{novel}{Bad argument for \string\SetScenebreakIndent\space}%
+ {\string\SetScenebreakIndent\space argument must be true or false.}%
+ \fi%
+}
+\SetScenebreakIndent{false} % default
+% Deprected from v. 1.40.3:
+\newcommand\IndentAfterScenebreak{\global\@IndentAfterScenebreaktrue}
+
+
+
+%% SCENE CHANGES
+%% ----------------------------------------------------------------------------
+% \scenebreak \sceneline \scenestars
+% Use anywhere in document body.
+% These commands skip a line.
+% \scenebreak leaves the gap empty.
+% \sceneline centers a line, about 1/3 textwidth.
+% \scenestars centers three widely-spaced asterisks.
+% Default behavior is \noindent for following paragraph.
+% Use \SetScenebreakIndent{true or false} in Preamble to change globally.
+% Either way, local behavior changed using \forceindent or \backindent.
+% \newcommand\scenebreak{\null}
+%
+\newcommand\scenebreak{% revised in version 1.52.
+ \leavevmode\getBreakpos{scenebreak}~\par
+}
+%
+\newcommand\sceneline{%
+ \noindent\getBreakpos{sceneline}\hfil%
+ \raisebox{0.2em}{\rule{0.35\textwidth}{.4pt}}\hfil\par%
+}
+%
+\newcommand\scenestars{%
+ \noindent\getBreakpos{scenestars}\hfil%
+ \raisebox{-.3em}{*\quad\quad*\quad\quad*}\hfil\par%
+}
+%
+\gdef\getBreakpos#1{%
+ \begingroup%
+ \savepos%
+ \protected@write\@auxout{}{%
+ \protect\@getBreakpos{\noexpand\number\lastypos}{\thepage}{#1}%
+ }%
+ \endgroup%
+}
+%
+\newlength\CurrentBreakpos
+\gdef\@getBreakpos#1#2#3{} % nothing, when reading aux at beginning
+\gdef\@RedefineBreakpos{ % called by `novel.cls' \AtBeginDocument
+ \gdef\@getBreakpos##1##2##3{% numerical position sp, page, break type
+ \gsetlength\CurrentBreakpos{##1sp}% measured up from very bottom of page.
+ \FPsub{\@BreakLines}{\strip@pt\TotalYpos}{\strip@pt\CurrentBreakpos}
+ \FPdiv{\@BreakLines}{\@BreakLines}{\strip@pt\nbs}%
+ \FPround{\@BreakLines}{\@BreakLines}{0}% integer lines from text top
+ \ifthenelse{\equal{##3}{scenebreak}}{%
+ \xdef\thisline{\@BreakLines}%
+ \ifnum\@BreakLines=1%
+ \ClassWarning{novel}{Replace \string\scenebreak\space at top of ^^J%
+ page ##2 with \string\sceneline\space or \string\scenestars.}%
+ \fi%
+ \ifnum\@BreakLines=\@LinesPerPage%
+ \ClassWarning{novel}{Replace \string\scenebreak\space at bottom of ^^J%
+ page ##2 with \string\sceneline\space or \string\scenestars.}%
+ \fi%
+ }{}%
+ \FPsub{\@nearthebottom}{\@LinesPerPage}{1}%
+ \ifnum\@BreakLines=2%
+ \ClassWarning{novel}{\string\ ##3 too close to top of page ##2.}%
+ \fi%
+ \ifnum\@BreakLines=\@nearthebottom%
+ \ClassWarning{novel}{\string\ ##3 too close to bottom of page ##2.}%
+ \fi%
+ }%
+} % end @RedefineBreakpos
+%%
+
+
+%% Repair \FirstLine{} command from `magaz' package.
+% Problem: Conflict with \noindent\nov@AfterGroup as used in ChapterStart.
+% The \noindent is carried past \FirstLine to the following paragraph.
+% Solution: After FirstLine completes, back up one line vertically, then insert
+% and empty line to restore grid and absorb the noindent.
+% Starred version uses the original \FirstLine definition, just in case
+% the following paragraph has some exotic feature.
+% Thanks to user `egreg' at tex.stackexchange.com for assistance.
+\let\oldFirstLine\FirstLine
+\def\FirstLine{\@ifstar\FirstLineFoo\@FirstLineFoo} % improved
+\def\FirstLineFoo#1{\oldFirstLine{#1}} % starred restores original def.
+\def\@FirstLineFoo#1{%
+ \oldFirstLine{#1}\par\vspace{-\nbs}\strut\par%
+}
+%%
+
+
+%% Chapter number count. New in version 1.44. See documentation.
+%% Do NOT use for "chapter-like" sections, only numbered chapters.
+\newcounter{novelcn}
+\setcounter{novelcn}{1}
+%%
+
+%% ChapterStart environment.
+% The most useful way to start a new chapter. Occupies a fixed amount of
+% vertical space. Also self-adjust when used with dropfolio. Automatically
+% calls \thispagestyle if set for all chapter displays.
+% This environment is not restricted to chapters. It is also used for
+% chapter-like sections in front matter or main matter,
+% as long as they are styled like a chapter.
+\newcounter{@linequarter}
+
+%
+% The argument is the number of normal baselineskips high.
+\newif\if@WithinChapterStart
+\DeclareDocumentEnvironment {ChapterStart} %
+{ O{\@setchapterstartheight} O{\@setchapterstart} }{%
+ \if@ThisPageStyle\else%
+ \gdef\@thiscsstyle{#2}%
+ \thispagestyle{\@thiscsstyle}%
+ \fi%
+ \global\@WithinChapterStarttrue%
+ \suppressfloats[t]% ensures that a floated image does not go on top
+ \gsetlength\parindent{0pt}% within environment
+ \ResetFootnoteSymbol% resets symbolic markers, but not numerical markers
+ \IfStrEq{#1}{*}{%
+ \gdef\@thiscsheight{\@setchapterstartheight}%
+ }{%
+ \gdef\@thiscsheight{#1}%
+ }%
+ \FPsub{\@fixlines}{\@thiscsheight}{2}%
+ \FPsub{\@fixlines}{\@fixlines}{0.001}% fudge to avoid rounding problems
+ \FPround{\@thiscsheight}{\@thiscsheight}{0}%
+ \FPiflt{\@thiscsheight}{4}%
+ \def\@smcserr{%
+ \ClassError{novel}{ChapterStart height insufficient for thispagestyle}%
+ {With your choice for thispagestyle, the height must be at least 4.}%
+ }%
+ \IfStrEq{\@thiscsstyle}{dropfolioinside}{\@smcserr}{}%j
+ \IfStrEq{\@thiscsstyle}{plain}{\@smcserr}{}%
+ \IfStrEq{\@thiscsstyle}{fancyplain}{\@smcserr}{}%
+ \else\fi%
+ \FPiflt{\@thiscsheight}{3}%
+ \ClassError{novel}{ChapterStart height must be at least 3}%
+ {If you need height less than 3, consider \string\QuickChapter.}%
+ \else\fi%
+ \null% always a line above the first thing to appear within the environment
+ \setcounter{@linequarter}{0}%
+ \begin{textblock*}{\textwidth}[0,0](0pt,0pt)%
+}{% close the environment:
+ \ifthenelse{%
+ \equal{\value{@linequarter}}{1} \OR \equal{\value{@linequarter}}{5}%
+ \OR \equal{\value{@linequarter}}{9} \OR \equal{\value{@linequarter}}{13}%
+ }{\vspace{0.75\nbs}}{}%
+ \ifthenelse{%
+ \equal{\value{@linequarter}}{2} \OR \equal{\value{@linequarter}}{6}%
+ \OR \equal{\value{@linequarter}}{10} \OR \equal{\value{@linequarter}}{14}%
+ }{\vspace{0.5\nbs}}{}%
+ \ifthenelse{%
+ \equal{\value{@linequarter}}{3} \OR \equal{\value{@linequarter}}{7}%
+ \OR \equal{\value{@linequarter}}{11} \OR \equal{\value{@linequarter}}{15}%
+ }{\vspace{0.25\nbs}}{}%
+ \end{textblock*}%
+ \vspace{\@fixlines\nbs}%
+ \if@DeleteCSline\else\null\fi% adjusts when dropfolioinside
+ \global\@WithinChapterStartfalse%
+ \vspace{0.1pt plus 0pt minus 0.2pt}% caulk
+ \gsetlength\parindent{\normalparindent}% restored
+ \nov@AfterGroup\NoIndentAfterThis% etextools and noindentafter
+}
+% end ChapterStart environment
+
+
+%%
+\LetLtxMacro\ChapterDisplay\ChapterStart\relax % deprecated
+\LetLtxMacro\endChapterDisplay\endChapterStart\relax % deprecated
+%
+\newcommand\ChapterTitle[2][c]{% optional alignment l, c, r
+ \ignorespaces%
+ \vspace{0.5\nbs}\addtocounter{@linequarter}{2}%
+ \@tempTFfalse%
+ \ifthenelse{\equal{#1}{l}}{\let\@csalign\relax\@tempTFtrue}{}%
+ \ifthenelse{\equal{#1}{c}}{\let\@csalign\centering\relax\@tempTFtrue}{}%
+ \ifthenelse{\equal{#1}{r}}{\let\@csalign\hfill\relax\@tempTFtrue}{}%
+ \if@tempTF\else%
+ \ClassError{novel}{Chapter Title, Deco, Subtitle align must be l, c, or r}%
+ {On page \thepage you wrote a Chapter command with alignment ^^J%
+ other than the allowed l, c, or r.}%
+ \fi%
+ {\@csalign\stake\smash{{\chapterfont{}#2}}\par}%
+}
+%
+\newcommand\ChapterSubtitle[2][c]{% optional alignment l, c, r
+ \vspace{0.25\nbs}\addtocounter{@linequarter}{1}
+ \@tempTFfalse%
+ \ifthenelse{\equal{#1}{l}}{\let\@csalign\relax\@tempTFtrue}{}
+ \ifthenelse{\equal{#1}{c}}{\let\@csalign\centering\relax\@tempTFtrue}{}
+ \ifthenelse{\equal{#1}{r}}{\let\@csalign\hfill\relax\@tempTFtrue}{}
+ \if@tempTF\else%
+ \ClassError{novel}{Chapter Title, Deco, Subtitle align must be l, c, or r}%
+ {On page \thepage you wrote a Chapter command with alignment ^^J%
+ other than the allowed l, c, or r.}%
+ \fi%
+ {\@csalign{\stake\smash{\subchfont #2}}\par}%
+}
+% In ChapterDeco, a trick is used. Instead of two optional arguments, and
+% instead of using expl3 syntax to create different argument delimiters,
+% the arguments for alignment and scale are passed as a single option.
+% This works because one is a letter, and the other is a number.
+% So it is easy to separte them by parsing.
+\newcommand\ChapterDeco[2][c1]{% optional alignment and scale, either order
+ \@tempTFfalse
+ \StrDel{#1}{ }[\temp@cds]% may use space separator
+ \StrDel{\temp@cds}{,}[\temp@cd]% may use comma separator
+ \IfSubStr{#1}{l}{% left align
+ \let\@csalign\relax\@tempTFtrue%
+ \StrDel{\temp@cd}{l}[\temp@cd]%
+ }{}%
+ \IfSubStr{#1}{c}{% centered
+ \let\@csalign\centering\relax\@tempTFtrue%
+ \StrDel{\temp@cd}{c}[\temp@cd]%
+ }{}%
+ \IfSubStr{#1}{r}{% right align
+ \let\@csalign\hfill\relax\@tempTFtrue%
+ \StrDel{\temp@cd}{r}[\temp@cd]%
+ }{}%
+ \if@tempTF\else%
+ \let\@csalign\centering\relax\@tempTFtrue%
+ \fi%
+ % Now for scaling, with adjusted vertical position:
+ \IfEndWith{\temp@cd}{.}{\StrSubstitute{\temp@cd}{.}{.0}[\temp@cd]}{}%
+ \IfBeginWith{\temp@cd}{.}{\StrSubstitute{\temp@cd}{.}{1.}[\temp@cd]}{}%
+ \IfDecimal{\temp@cd}{\def\@thisScale{\temp@cd}}{\def\@thisScale{1}}%
+ {\@csalign\charscale[\@thisScale,0pt,0.2\nbs]{#2}\par}%
+}
+%
+%%
+
+
+%% \Epigraph[align,scale,width]{text} OBSOLETE IN CODE VERSION 1.2
+
+
+%% \QuickChapter[line style]{text} intended for a story consisting of numerous
+% short chapters without page breaks. Two blank lines are inserted. In the gap
+% is the text, using subchfont. Optional line follows using \bigemdash style.
+% If option is empty, no line. If a length, then the line is that length.
+% If option * then the line fills to end of text line.
+\newcommand\QuickChapter[2][]{%
+ \null%
+ \noindent{\subchfont\charscale[1,0pt,0.3em]{#2}%
+ \gsetlength\@tempLength{\heightof{x}}% height of x in subchfont
+ }% end subchfont
+ \FPdiv{\@qclineth}{\strip@pt\@tempLength}{\strip@pt\normalxheight}% fontscale
+ \FPmul{\@howthick}{\@qclineth}{0.049}% typical emdash thickness, em.
+ \FPmul{\@howraise}{0.23}{\@qclineth}% typical emdash height em raised.
+ \ifthenelse{\equal{#1}{} \OR \equal{#1}{ }}{}{% no line, else:
+ \ifthenelse{\equal{#1}{*}}{% line fills:
+ ~\leaders%
+ \hbox{\smash{\rule[\@howraise em]{1pt}{\@howthick em}}}%
+ \hfill\stake\par%
+ }{% else line at specific length:
+ ~\makebox[#1][l]{%
+ \leaders\hbox{\smash{\rule[\@howraise em]{1pt}{\@howthick em}}}\hfill%
+ }%
+ }%
+ }%
+ \NoIndentAfterThis%
+} % end \QuickChapter
+%%
+
+
+%% New in version 1.40: \cleartorecto and \cleartoend
+% \cleartorecto works same as \clearpage when next page is recto.
+% If next page would be verso, a blank verso is inserted,
+% so that the following material is recto.
+% \cleartoend is used at very end of book.
+% It adds a blank page. If the blank is verso, end of book.
+% But if that blank is recto, it adds a second blank page, end of book.
+% So, the book always ends with a blank verso.
+\gdef\cleartorecto{
+ \clearpage
+ \ifodd\c@page
+ \else
+ \thispagestyle{empty}
+ \null
+ \clearpage
+ \fi
+}
+\newif \if@cleartoend
+\gdef\cleartoend{
+ \if@cleartoend\else
+ \clearpage
+ \ifodd\c@page
+ \thispagestyle{empty}
+ \null
+ \clearpage
+ \fi
+ \thispagestyle{empty}
+ \null
+ \clearpage
+ \fi
+ \global\@cleartoendtrue
+}
+%
+
+
+%%
+\gdef\@ActivateChapterScene{% called by `novel.cls' \AtBeginDocument
+ % Activate user choice of whether or not to indent after scenebreak commands:
+ \if@IndentAfterScenebreak\else
+ \NoIndentAfterCmd{\scenebreak}
+ \NoIndentAfterCmd{\sceneline}
+ \NoIndentAfterCmd{\scenestars}
+ \fi
+}% end \@ActivateChapterScene
+%%
+
+
+%% Neutralize settings commands:
+\gdef\@DisableChapterSceneSettings{% called by `novel.cls' \AtBeginDocument
+ \LetLtxMacro\SetHeadFootStyle\relax
+ \LetLtxMacro\IndentAfterScenebreak\relax
+ \LetLtxMacro\SetScenebreakIndent\relax
+}% end \@DisableChapterSceneSettings
+%%
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-ChapterScene.sty'.
+
+
diff --git a/macros/luatex/latex/novel/novel-DropCap.sty b/macros/luatex/latex/novel/novel-DropCap.sty
new file mode 100644
index 0000000000..3a6233e3f5
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-DropCap.sty
@@ -0,0 +1,235 @@
+%%
+%% This is file `novel-DropCap.sty', part of `novel' document class.
+%% Copyright (C) 2017-2018 Robert Allgeyer.
+%%
+%% It is based on `lettrine.sty', part of `lettrine' package,
+%% Copyright (C) 1999-2015 Daniel Flipo.
+%%
+%% The license for this file is that same for `lettrine':
+%
+% This program can be distributed and/or modified under the terms
+% of the LaTeX Project Public License either version 1.3c of this
+% license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+%%
+% This file is new in `novel' version 1.50.
+%
+\ProvidesFile{novel-DropCap.sty}%
+ [2018/04/26 v1.52 (Drop Caps)]
+\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%
+%
+
+%
+\newcounter{NDCDefaultLines}
+\setcounter{NDCDefaultLines}{3}
+\newcounter{NDCDefaultDepth}
+\newdimen\NDCDefaultVoffset
+\newdimen\NDCDefaultHoffset
+\newcommand*{\NDCDefaultScale}{1}
+\newcommand*{\NDCDefaultBloat}{1}
+\newdimen\NDCDefaultGap
+\gsetlength{\NDCDefaultGap}{0.25em} % approx. width of normal space
+\newsavebox{\NDC@dropcapbox}
+\newsavebox{\NDC@normalXbox}
+\newcounter{NDC@lines}
+\newcounter{NDC@depth}
+\newdimen\NDC@antewidth
+\newdimen\NDC@Pindent
+\newdimen\NDC@Gap % equivalent to lettrine findent
+\newdimen\NDC@Nindent % not a user setting
+\newdimen\NDC@voffset
+\newdimen\NDC@hoffset
+\newdimen\NDC@first
+\newdimen\NDC@next
+\newdimen\NDC@height
+\newcommand*{\NDC@ante}{}
+\newcommand*{\NDC@bloat}{}
+\newcommand*{\NDC@scale}{}
+\def\@getNDCheight{% offsets do not affect height:
+ \@tempdima=\baselineskip
+ \setlength{\NDC@height}{\value{NDC@lines}\@tempdima}% local
+ \addtolength{\NDC@height}{-\@tempdima}%
+ \sbox{\NDC@normalXbox}{X}% Normal capital X, rather than something else.
+ \addtolength{\NDC@height}{\ht\NDC@normalXbox}%
+ \setlength{\NDC@height}{\NDC@scale\NDC@height}% local
+} %
+\newcommand*{\NDC@char}{%
+ \@getNDCheight%
+ % Measures drop cap capital X, rather than something else:
+ \sbox{\@tempboxa}{%
+ \NDC@charstyle\fontsize{\NDC@height}{\NDC@height}\selectfont X%
+ }%
+ \@tempcntb=\ht\@tempboxa%
+ \@tempcnta=\NDC@height%
+ \multiply\@tempcnta by 100%
+ \divide\@tempcntb by 100%
+ \divide\@tempcnta by \@tempcntb%
+ \advance\@tempcnta by -9999%
+ \ifnum\@tempcnta>0%
+ \def\@tempa{1.\the\@tempcnta}%
+ \else%
+ \def\@tempa{1}%
+ \fi%
+ \NDC@charstyle\fontsize{\@tempa\NDC@height}{\@tempa\NDC@height}\selectfont
+} %
+\define@key{NDC}{lines}{\setcounter{NDC@lines}{#1}}
+\define@key{NDC}{depth}{\setcounter{NDC@depth}{#1}}
+\define@key{NDC}{hoffset}{\setlength{\NDC@hoffset}{#1}}
+\define@key{NDC}{voffset}{\setlength{\NDC@voffset}{#1}}
+\define@key{NDC}{ante}{\renewcommand*{\NDC@ante}{#1}} % Like `lettrine' ante,
+\define@key{NDC}{ante*}{\renewcommand*{\NDC@ante}{% Like `lettrine' ante, but
+ \setlength\NDC@antewidth{\widthof{#1}}% auto-hangs the ante in left margin.
+ \addtolength\NDC@antewidth{0.2em}% provides breathing room
+ \stake\hspace{-\NDC@antewidth}#1\hspace{0.2em}}% restores alignment
+}
+\define@key{NDC}{gap}{\setlength{\NDC@Gap}{#1}}
+\define@key{NDC}{bloat}{\renewcommand*{\NDC@bloat}{#1}}
+\define@key{NDC}{scale}{\renewcommand*{\NDC@scale}{#1}}
+\newdimen\NDCboxwidth
+\newdimen\NDCboxheight
+\newdimen\NDCboxdepth
+%
+\DeclareDocumentCommand \NDC@boxcap { m }{%
+ \begingroup%
+ % The model letter has no upper diacritical.
+ \def\@NDCmodel{}%
+ \IfSubStr{ÀÃÂÃÄÅĀĂ}{#1}{\def\@NDCmodel{A}}{}%
+ \IfSubStr{ĆĈĊČ}{#1}{\def\@NDCmodel{C}}{}%
+ \IfSubStr{ÄŽ}{#1}{\def\@NDCmodel{D}}{}%
+ \IfSubStr{ÈÉÊËĒĔĖĚ}{#1}{\def\@NDCmodel{E}}{}%
+ \IfSubStr{ĜĞĠ}{#1}{\def\@NDCmodel{G}}{}%
+ \IfSubStr{Ĥ}{#1}{\def\@NDCmodel{H}}{}%
+ \IfSubStr{ÃŒÃÃŽÃĨĪĬİ}{#1}{\def\@NDCmodel{I}}{}%
+ \IfSubStr{Ä´}{#1}{\def\@NDCmodel{J}}{}%
+ \IfSubStr{Ĺ}{#1}{\def\@NDCmodel{L}}{}%
+ \IfSubStr{ÑŃŇ}{#1}{\def\@NDCmodel{N}}{}%
+ \IfSubStr{ÒÓÔÕÖŌŎÅ}{#1}{\def\@NDCmodel{O}}{}%
+ \IfSubStr{ŔŘ}{#1}{\def\@NDCmodel{R}}{}%
+ \IfSubStr{ŚŜŠ}{#1}{\def\@NDCmodel{S}}{}%
+ \IfSubStr{Ť}{#1}{\def\@NDCmodel{T}}{}%
+ \IfSubStr{ÙÚÛÜŨŪŬŮŰ}{#1}{\def\@NDCmodel{U}}{}%
+ \IfSubStr{Å´}{#1}{\def\@NDCmodel{W}}{}%
+ \IfSubStr{ÃŶŸ}{#1}{\def\@NDCmodel{Y}}{}%
+ \IfSubStr{ŹŻŽ}{#1}{\def\@NDCmodel{Z}}{}%
+ \IfSubStr{DŽ}{#1}{\def\@NDCmodel{DZ}}{}% diglyph
+ \setlength\fboxsep{0.16\@SetFontSize}%
+ \setlength\fboxrule{0.02\@SetFontSize}%
+ \ifthenelse{\equal{\@NDCmodel}{}}{%
+ \framebox{\phantom{|}#1\phantom{|}}%
+ }{%
+ \framebox{\phantom{|\@NDCmodel}\llap{\smash{#1}}\phantom{|}}%
+ }%
+ \endgroup%
+}% end boxcap
+%
+\DeclareDocumentCommand \dropcap { s O{} m } {%
+ \@tempTFfalse%
+ \IfSubStr{#3}{png}{\@tempTFtrue}{}%
+ \IfSubStr{#3}{PNG}{\@tempTFtrue}{}%
+ \IfSubStr{#3}{jpg}{\@tempTFtrue}{}%
+ \IfSubStr{#3}{JPG}{\@tempTFtrue}{}%
+ \IfSubStr{#3}{jpeg}{\@tempTFtrue}{}%
+ \IfSubStr{#3}{JPEG}{\@tempTFtrue}{}%
+ \setcounter{NDC@lines}{\value{NDCDefaultLines}}%
+ \setcounter{NDC@depth}{\value{NDCDefaultDepth}}%
+ \setlength{\NDC@hoffset}{\NDCDefaultHoffset}%
+ \renewcommand*{\NDC@bloat}{\NDCDefaultBloat}%
+ \renewcommand*{\NDC@scale}{\NDCDefaultScale}%
+ \setlength{\NDC@voffset}{\NDCDefaultVoffset}%
+ \renewcommand*{\NDC@ante}{}%
+ \setlength{\NDC@Gap}{\NDCDefaultGap}%
+ \setlength{\NDC@Nindent}{0pt}%
+ \setkeys{NDC}{#2}%
+ \if@tempTF%
+ \def\@dropthisthing{\InlineImage[0em,b]{#3}}%
+ \else%
+ \IfBooleanTF{#1}%
+ {\def\@dropthisthing{\NDC@boxcap{#3}}}%
+ {\def\@dropthisthing{#3}}%
+ \fi%
+ \ifnum\value{NDC@lines}=1%
+ \par\noindent%
+ \NDC@ante%
+ \@dropthisthing%
+ \else%
+ % Compensate for effect of using \Rework:
+ \if@ReworkTrimSize%
+ \FPdiv{\@tempN}{\strip@pt\textwidth}{\strip@pt\@OriginalTextWidth}%
+ \FPmul{\NDC@bloat}{\NDC@bloat}{\@tempN}%
+ \else%
+ \if@ReworkMargins%
+ \FPdiv{\@tempN}{\strip@pt\textwidth}{\strip@pt\@OriginalTextWidth}%
+ \FPmul{\NDC@bloat}{\NDC@bloat}{\@tempN}%
+ \fi%
+ \fi%
+ \sbox{\NDC@normalXbox}{X}% Normal capital X.
+ \sbox{\NDC@dropcapbox}{\scalebox{\NDC@bloat}[1]{\NDC@char\@dropthisthing}}%
+ \@tempdima=\baselineskip%
+ \setlength{\NDC@first}{-\value{NDC@lines}\@tempdima}%
+ \addtolength{\NDC@first}{\@tempdima}%
+ \sbox{\@tempboxa}{X}%
+ \addtolength{\NDC@first}{-\ht\@tempboxa}%
+ \addtolength{\NDC@first}{\NDC@voffset}%
+ \addtolength{\NDC@first}{\ht\NDC@dropcapbox}%
+ \addtolength{\NDC@voffset}{-\value{NDC@lines}\@tempdima}%
+ \addtolength{\NDC@voffset}{\@tempdima}%
+ \par%
+ \setlength{\NDC@Pindent}{\wd\NDC@dropcapbox}%
+ \addtolength{\NDC@Pindent}{\NDC@hoffset}%
+ \settowidth{\NDC@first}{\NDC@ante}%
+ \addtolength{\NDC@Pindent}{\NDC@first}%
+ \addtolength{\NDC@Pindent}{\NDC@Gap}%
+ \setlength{\NDC@first}{\linewidth}%
+ \addtolength{\NDC@first}{-\NDC@Pindent}%
+ \addtolength{\NDC@Nindent}{\NDC@Pindent}%
+ \setlength{\NDC@next}{\linewidth}%
+ \addtolength{\NDC@next}{-\NDC@Nindent}%
+ \addtolength{\NDC@Pindent}{\rightmargin}%
+ \addtolength{\NDC@Nindent}{\rightmargin}%
+ \setlength{\NDCboxwidth}{\wd\NDC@dropcapbox}%
+ \setlength{\NDCboxheight}{\ht\NDC@dropcapbox}%
+ \setlength{\NDCboxdepth}{\dp\NDC@dropcapbox}%
+ \addtocounter{NDC@lines}{1}%
+ \addtocounter{NDC@lines}{\value{NDC@depth}}%
+ \def\NDC@parshape{\c@NDC@lines \the\NDC@Pindent \the\NDC@first}%
+ \@tempcnta=\tw@%
+ \@whilenum \@tempcnta<\c@NDC@lines\do{%
+ \edef\NDC@parshape{\NDC@parshape \the\NDC@Nindent \the\NDC@next}%
+ \advance\@tempcnta\@ne}%
+ \edef\NDC@parshape{\NDC@parshape \rightmargin \the\linewidth}%
+ \noindent%
+ \parshape=\NDC@parshape\relax%
+ \smash{%
+ \llap{%
+ \mbox{\NDC@ante}%
+ \raisebox{\NDC@voffset}{\usebox{\NDC@dropcapbox}}%
+ \hskip\the\NDC@Gap%
+ }%
+ }%
+ \fi%
+}% end @NDCdropcap
+%%
+
+
+%% In case the user prefers `lettrine':
+\gdef\@ActivateDropCaps{% called by `novel.cls' \AtBeginDocument
+ \@ifpackageloaded{lettrine}{%
+ \global\LettrineOnGridtrue % Necessary.
+ \gsetlength\DiscardVskip{10\nbs} % effectively infinite
+ }{ % For test purposes only:
+ \providecommand\lettrine[3][]{##2##3} % echoes its mandatory arguments
+ }%
+}% end \@ActivateDropCaps
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-DropCap.sty'.
+
diff --git a/macros/luatex/latex/novel/novel-FOGRA39.clo b/macros/luatex/latex/novel/novel-FOGRA39.clo
new file mode 100644
index 0000000000..dab3501fb9
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-FOGRA39.clo
@@ -0,0 +1,27 @@
+%%
+%% This is file `novel-FOGRA39.clo', part of `novel' document class.
+%% The values of the arguments are public industry standards.
+\ProvidesFile{novel-FOGRA39.clo}%
+[2018/01/14 any version. (novel Output Intent FOGRA39)]
+%%
+
+
+% Typically used in Europe.
+
+% Remember: TeX special characters must be backslashed here.
+% You may see % or # or _ in the data or file names.
+% Be sure that they are written as \% \# \_ or there will be trouble.
+
+% If any line is long, let it wrap. Do not attempt to break it onto multiple lines.
+
+\gdef\@OIidentifier{FOGRA39} % also called "reference name"
+\gdef\@OIcondition{Offset commercial and specialty printing according to ISO 12647-2:2004 / Amd 1, paper type 1 or 2 (gloss or matte coated offset, 115 g/m2), screen frequency 60/cm.}
+\gdef\@OIinfo{Coated FOGRA39 (ISO 12647-2:2004)}
+\gdef\@OIregistry{http://www.color.org}
+\gdef\@OIprofile{CoatedFOGRA39.icc}
+
+%%
+\endinput
+%%
+%% end of file `novel-FOGRA39.clo'
+
diff --git a/macros/luatex/latex/novel/novel-FileData.sty b/macros/luatex/latex/novel/novel-FileData.sty
new file mode 100644
index 0000000000..803ef635c0
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-FileData.sty
@@ -0,0 +1,208 @@
+%%
+%% This is file `novel-FileData.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-FileData.sty}%
+[2018/04/26 v1.52 LaTeX file (File Data settings)]
+%%
+
+
+%% File Data, also known as PDF Metadata, is non-printing identifying
+%% information in the PDF file. Some or all of it can be read by various
+%% PDF reader software.
+%% PDF/X is also considered File Data, as it concerns the structure of the
+%% file and its relationaship to printers, rather than its visible content.
+%% In principle, you could set the title as empty. But in that case, no other
+%% File Data will be included, and you cannot have PDF/X compliance.
+%% There are many more kinds of File Data that a PDF can include, such as
+%% subject and keywords. But `novel' is specifically for printing to paper,
+%% not for electronic documents that would be found by database search.
+%% Thus, there is no provision for such additional File Data.
+%% When you sign up with a print service, you will provide subject, keywords,
+%% and description directly to their database, rather than in the PDF.
+%% No need to set copyright in metadata, since your file is only for use by
+%% the print service, and is not being distributed as a PDF e-book.
+%% Your copyright notice is on the printed page, where it should be.
+%% Particularly note that your print service is NOT the publisher: YOU are!
+
+
+%% FILE DATA (PDF Metadata)
+%% ----------------------------------------------------------------------------
+%%
+% \title{} or \SetTitle{}
+% Copied to File Data at end of Preamble, unless not set.
+% Provides \theTitle anywhere.
+% If not set, PDF cannot conform to PDF/X.
+\newif \if@HasTitle % true if \SetTitle or \title used
+\gdef\SetTitle#1{\gdef\@title{#1}} % for stylistic consistency
+\gdef\title#1{\gdef\@title{#1}}
+\gdef\thetitle{\@title} % for convenience
+\gdef\theTitle{\@title}
+\SetTitle{IMPORTANT: Provide Book Title} % Default v. 1.46.1. Formerly empty.
+%
+% \author{} or \SetAuthor{}
+% Copied to File Data at end of preamble, unless not set.
+% Provides \theAuthor anywhere.
+\gdef\SetAuthor#1{\gdef\@author{#1}} % for stylistic consistency
+\gdef\author#1{\gdef\@author{#1}}
+\gdef\theauthor{\@author} % for convenience
+\gdef\theAuthor{\@author}
+\SetAuthor{}
+%
+% \subtitle{} or \SetSubtitle{} (if any)
+% Not copied to File Data by itself, as there is no such metadata entry.
+% Provides \theSubtitle anywhere.
+\gdef\SetSubtitle#1{\gdef\@subtitle{#1}} % for stylistic consistency
+\gdef\subtitle#1{\gdef\@subtitle{#1}}
+\gdef\thesubtitle{\@subtitle} % compatibility
+\gdef\theSubtitle{\@subtitle}
+\SetSubtitle{}
+%
+% \SetApplication{} (rarely used)
+% Also known as CreatorTool.
+% Name of the software that created the source document.
+% Changing this does not change the software, it just changes the information.
+% Normally leave as default, but can change if urgent.
+\gdef\SetApplication#1{\gdef\@novelApplication{#1}}
+\SetApplication{LuaLaTeX with novel and microtype} % default
+%
+% \SetProducer{} (rarely used)
+% Name of the software that compiles the source to make PDF.
+% Changing this does not change the software, it just changes the information.
+% Normally leave as default, but can change if urgent.
+\gdef\SetProducer#1{\gdef\@novelProducer{#1}}
+\SetProducer{LuaLaTeX with novel-pdfx and hyperref} % default
+%
+%% End file data.
+
+
+%% SET PDF/X ARGUMENTS
+%% ----------------------------------------------------------------------------
+%% \SetPDFX[Output Intent]{compliance standard} % No embed *.icc. Default.
+%% \SetPDFX*[Output Intent]{compliance standard} % Embed *.icc.
+%% Default up to and including v. 1.46: \SetPDFX{off}
+%% Default as of v. 1.46.1: \SetPDFX[CGATSTR001]{X-1a:2001}
+%
+% \@pdfxSEToff refers to the setting, rather than whether it really is off.
+% \@pdfxISoff refers to whether it really is off.
+\newif \if@pdfxSEToff % Prior to v. 1.46.1, was \ifpdfx@isOFF.
+\newif \if@pdfxISoff % New in v. 1.46.1.
+% These will get meaningful info when an output intent file is loaded:
+\gdef\@OIidentifier{}
+\gdef\@OIcondition{}
+\gdef\@OIinfo{}
+\gdef\@OIregistry{}
+\gdef\@OIprofile{}
+%
+%%
+\newif \if@HasConformance
+\newif \if@EmbedICC
+\gdef\SetPDFX{\@ifstar\@setpdfxst\@setpdfxns}
+\newcommand\@setpdfxst[2][CGATSTR001]{
+ \global\@EmbedICCtrue
+ \@setpdfx{#1}{#2}
+}
+\newcommand\@setpdfxns[2][CGATSTR001]{
+ \global\@EmbedICCfalse
+ \@setpdfx{#1}{#2}
+}
+%
+\newcommand\@setpdfx[2]{
+ \@tempTFfalse
+ \ifthenelse{\equal{#2}{off}}{
+ \@tempTFtrue
+ \global\@pdfxSETofftrue
+ \global\@pdfxISofftrue
+ }{}
+ \ifthenelse{\equal{#2}{X-1a:2001}}{
+ \@tempTFtrue
+ \global\@pdfxSETofffalse
+ \global\@pdfxISofffalse
+ \gdef\@PDFversion{PDF/X-1}
+ \gdef\@PDFXversion{PDF/X-1a:2001}
+ \gdef\@PDFXconformance{PDF/X-1a:2001}
+ \global\@HasConformancetrue
+ \global\pdfminorversion=3
+ }{}
+ \ifthenelse{\equal{#2}{X-1a:2003}}{
+ \@tempTFtrue
+ \global\@pdfxSETofffalse
+ \global\@pdfxISofffalse
+ \gdef\@PDFversion{PDF/X-1}
+ \gdef\@PDFXversion{PDF/X-1a:2003}
+ \gdef\@PDFXconformance{PDF/X-1a:2003}
+ \global\@HasConformancetrue
+ \global\pdfminorversion=3
+ }{}
+ \ifthenelse{\equal{#2}{X-3:2002}}{
+ \@tempTFtrue
+ \global\@pdfxSETofffalse
+ \global\@pdfxISofffalse
+ \gdef\@PDFversion{PDF/X-3}
+ \gdef\@PDFXversion{PDF/X-3:2002}
+ \global\pdfminorversion=3
+ }{}
+ \ifthenelse{\equal{#2}{X-3:2003}}{
+ \@tempTFtrue
+ \global\@pdfxSETofffalse
+ \global\@pdfxISofffalse
+ \gdef\@PDFversion{PDF/X-3}
+ \gdef\@PDFXversion{PDF/X-3:2003}
+ \global\pdfminorversion=4
+ }{}
+ \if@tempTF\else
+ \ClassError{novel}{Bad compliance argument for \string\SetPDFX}%
+ {Choose: X-1a:2001, X-1a:2003, X-3:2002, X-3:2003, off.}%
+ \fi
+ % Grab the file that defines the Output Intent information:
+ % File name format: novel-YourIntent.clo
+ % Setting: \SetPDFX[YourIntent]{compliance}
+ % Contents of file: See the above included Output Intent data.
+ \StrDel{#1}{\space}[\NPDFXOINS]
+ \IfFileExists{novel-\NPDFXOINS.clo}{\input{novel-\NPDFXOINS.clo}}{%
+ \ClassError{novel}{Bad Output Intent for \string\SetPDFX}%
+ {Use filename (without extension) of a file with *.clo extension. ^^J%
+ Filename must begin with novel- ^^J%
+ Example: File novel-FOGRA39.clo is called as [FOGRA39]. ^^J%
+ The file must be where TeX can find it. ^^J%
+ For contents of the file, see package documentation.}%
+ }{}%
+} % end \@setpdfx
+%
+\SetPDFX[CGATSTR001]{X-1a:2001} % Default, from v. 1.46.1. Formerly off.
+%%
+
+
+
+%% Neutralize file data settings:
+\gdef\@DisableFileDataSettings{% called by `novel.cls' \AtBeginDocument
+ \let\title\relax
+ \let\author\relax
+ \let\subtitle\relax
+ \LetLtxMacro\SetAuthor\relax
+ \LetLtxMacro\SetTitle\relax
+ \LetLtxMacro\SetSubtitle\relax
+ \LetLtxMacro\SetApplication\relax
+ \LetLtxMacro\SetProducer\relax
+ \LetLtxMacro\SetPDFX\relax
+}% end \@DisableFileDataSettings
+%%
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-FileData.sty'.
+
+
diff --git a/macros/luatex/latex/novel/novel-Fonts.sty b/macros/luatex/latex/novel/novel-Fonts.sty
new file mode 100644
index 0000000000..11341046f0
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-Fonts.sty
@@ -0,0 +1,416 @@
+%%
+%% This is file `novel-Fonts.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-Fonts.sty}%
+[2018/04/26 v1.52 LaTeX file (font settings and defaults)]
+%%
+
+
+%% Package `fontspec' was previously loaded by `\novel.cls'.
+
+
+%% INITIALIZATION
+%% ----------------------------------------------------------------------------
+% Fonts are chosen in Preamble using \Set commands. But they are not activated
+% until \AtEndPreamble. Until then, the basic TeX font families must be
+% temporarily specified, so that certain packages can load without compliant.
+% These are Latin Modern fonts, which are Open Type and will work, but are not
+% stylistically suitable for works of fiction. The only reason they are
+% used here, is because just about every TeX installation has them.
+\gdef\rmdefault{lmr} % Latin Modern Roman
+\gdef\sfdefault{lmss} % Latin Modern Sans
+\gdef\ttdefault{lmtt} % Latin Modern Mono
+% The following might become unnecessary if fontspec adds the capability to
+% disable keys. For now: Color and Opacity cannot be used as font features,
+% for a black/white printed book. Alas, fontspec over-rules xcolor.
+% So, this code over-rules fontspec:
+\gdef\@CheckFontspecFeatures#1{%
+ \@tempTFfalse%
+ \IfSubStr{#1}{Color}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{Colour}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{color}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{colour}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{Opacity}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{opacity}{\@tempTFtrue}{}%
+ \if@tempTF%
+ \ClassError{novel}{Color and Opacity forbidden as font features}%
+ {You defined a font, or added a font feature, with Color or Opacity. ^^J%
+ That is disallowed in `novel' class.}%
+ \fi%
+} % end \@CheckFontspecFeatures
+% Default font features (will be changed later):
+\defaultfontfeatures{} % reset
+\defaultfontfeatures{SmallCapsFeatures={Renderer=Basic},Ligatures=TeX,} % all
+% Main and sans fonts: kerning, ligatures, and OldStyle numbers if available:
+\defaultfontfeatures[\rmfamily,\sffamily]%
+ {Kerning=On,Numbers=OldStyle,Ligatures=Common}
+% Fake \microtypesetup until package loaded by \@ActivateFonts, \AtEndPreamble:
+\newif \if@MicrotypeSet
+\gdef\microtypesetup#1{
+ \gdef\@mymicrotypesetup{#1} % used in novel-Fonts.sty
+ \global\@MicrotypeSettrue
+}%
+%% end initialization
+
+
+%% SETTINGS FOR PARENT FONT, DESCENDANTS, OTHERS
+%% ----------------------------------------------------------------------------
+% In `novel' you do not \usepackage{font name} or \RequirePackage{font name}.
+% You do not directly write \renewcommand\rmdefault{font name}.
+% You do not directly use \setmainfont[features]{font name}.
+% Instead, `novel' requires a `parent font' to be set. The parent font is
+% the ancestor of the main (normal) font, and several other descendants.
+% The parent font features, if any, should be a minimal set that will be
+% applied to all descendants. For example, if the font has an an alternate
+% style for a particular letter, and you want to use it for all descendants,
+% then you would spedify that feature for the parent font.
+% For now, these settings are merely stored. Later, \AtEndPreamble,
+% the main (normal) font inherits the settings for the parent font.
+% Other descendants inherit those settings, with their own features added.
+% Anything not set by you, will have a suitable default set automatically.
+\newif \if@ParentFontSet
+\gdef\parentfontfeatures{}
+\gdef\parentfontname{}
+\DeclareDocumentCommand \SetParentFont { O{} m O{} } {% from version 1.1.
+ \@CheckFontspecFeatures{#1,#3}
+ \gdef\parentfontfeatures{#1,#3}
+ \gdef\parentfontname{#2}
+ \global\@ParentFontSettrue
+}%
+\DeclareDocumentCommand \SetMasterFont { O{} m O{} } {% DEPRECATED
+ \@CheckFontspecFeatures{#1,#3}
+ \gdef\parentfontfeatures{#1,#3}
+ \gdef\parentfontname{#2}
+ \global\@ParentFontSettrue
+}%
+%
+% In a work of fiction, you probably do not need a sans or mono font.
+% But TeX expects you do have them. So, \AtEndPreamble, Libertinus Sans
+% and Libertinus Mono will be set as defaults, if you have those fonts.
+% Otherwise, Latin Modern Sans and Mono will be used, but they are not
+% well-suited to works of fiction.
+% If you wish to set your own sans and mono fonts, do it using standard
+% `fontspec' syntax. There is no special method in `novel' class:
+% \setsansfont[features]{font name}
+% \setmonofont[features]{font name}
+%
+% The headfont is used in headers and footers:
+\newif \if@HeadFontSet
+\gdef\@headfontfeatures{}
+\gdef\@headfontname{}
+\DeclareDocumentCommand \SetHeadFont { O{} m O{} } {% revised v 1.40.3
+ \@CheckFontspecFeatures{#1,#3}
+ \gdef\@headfontfeatures{Numbers=Lining,%
+ WordSpace=\@looseheadword,#1,#3}% loose letters added in head/foot styles
+ \gdef\@headfontname{#2}
+ \global\@HeadFontSettrue
+}%
+% The chapter font is used by the \ChapterTitle{} command:
+\newif \if@ChapterFontSet
+\gdef\@chapterfontfeatures{}
+\gdef\@chapterfontname{}
+\DeclareDocumentCommand \SetChapterFont { O{} m O{} } {%
+ \@CheckFontspecFeatures{#1,#3}
+ \gdef\@chapterfontfeatures{Numbers=Lining,#1,#3}
+ \gdef\@chapterfontname{#2}
+ \global\@ChapterFontSettrue
+}%
+% The subch font is used by the \ChapterSubtitle{} command:
+\newif \if@SubchFontSet
+\gdef\@subchfontfeatures{}
+\gdef\@subchfontname{}
+\DeclareDocumentCommand \SetSubchFont { O{} m O{} } {%
+ \@CheckFontspecFeatures{#1,#3}
+ \gdef\@subchfontfeatures{Numbers=Lining,#1,#3}
+ \gdef\@subchfontname{#2}
+ \global\@SubchFontSettrue
+}%
+% The deco font is used for decorations and acronyms.
+% It must be NovelDeco.otf or a font based on NovelDeco.otf. No other!
+\newif \if@DecoFontSet
+\newif \if@HasDecoFont
+\gdef\@decofontfeatures{}
+\gdef\@decofontname{}
+\DeclareDocumentCommand \SetDecoFont { O{} m O{} } {%
+ \@CheckFontspecFeatures{#1,#3}
+ \gdef\@decofontname{#2}
+ \global\@DecoFontSettrue
+ \global\@HasDecoFonttrue
+ \newfontface\decofont[#1,#3]{#2}
+}%
+% For syntax consistency:
+\ExplSyntaxOn
+\cs_new_eq:NN \NewFontFamily \newfontfamily
+\cs_new_eq:NN \NewFontFace \newfontface
+\cs_new_eq:NN \SetSansFont \setsansfont
+\cs_new_eq:NN \SetMonoFont \setmonofont
+\cs_new_eq:NN \SetMathFont \setmathfont
+\cs_new_eq:NN \AddFontFeatures \addfontfeatures
+\cs_new_eq:NN \AddFontFeature \addfontfeatures
+\ExplSyntaxOff
+% New in v. 1.50: built-in drop caps.
+\gdef\@DropCapFont{} % until actually set, will be default main font
+\gdef\@DropCapColorModel{} % until actually set, using `xcolor' syntax
+\gdef\@DropCapColorValue{black} % until actually set, using `xcolor' syntax
+\gdef\NDC@charstyle{}
+% The argument to \SetDropCapFont is a user-defined `fontspec' font command.
+% Example syntax, using `fontspec' in LuaLaTeX:
+% Create font command, such as: \newfontface\mynicefont[options]{fontname}
+% Then: \SetDropCapFont{\mynicefont}
+\newif \if@HasDropCapFont
+\DeclareDocumentCommand \SetDropCapFont { m } {%
+ \@HasDropCapFonttrue%
+ \gdef\@DropCapFont{#1}%
+ \gdef\NDC@charstyle{%
+ #1%
+ \if@HasDropCapColor%
+ \ifthenelse{\equal{\@DropCapColorModel}{}}{%
+ \color{\@DropCapColorValue}%
+ }{%
+ \color[\@DropCapColorModel]{\@DropCapColorValue}%
+ }%
+ \fi%
+ }%
+}%
+% The argument(s) to \SetDropCapColor use `xcolor' syntax:
+% [colormodel]{value} OR {colorname}
+\newif \if@HasDropCapColor
+\DeclareDocumentCommand \SetDropCapColor { O{} m } {%
+ \@setdropcapcolor[#1]{#2}%
+}% end \SetDropCapColor
+\DeclareDocumentCommand \@setdropcapcolor { O{} m } {%
+ \global\@HasDropCapColortrue%
+ \gdef\@DropCapColorModel{#1}%
+ \gdef\@DropCapColorValue{#2}%
+ \renewcommand\NDC@charstyle{%
+ \@DropCapFont%
+ \ifthenelse{\equal{\@DropCapColorModel}{}}{%
+ \color{\@DropCapColorValue}%
+ }{%
+ \color[\@DropCapColorModel]{\@DropCapColorValue}%
+ }%
+ }%
+}% end \@setdropcapcolor
+% for convenience:
+\ExplSyntaxOn
+\cs_new_eq:NN \SetDropcapFont \SetDropCapFont
+\cs_new_eq:NN \SetDropcapColor \SetDropCapColor
+\ExplSyntaxOff
+%
+% A default math font (which presumably you do not need) is chosen here.
+% You may over-ride using `unicode-math' syntax \setmathfont in Preamble.
+\IfFontExistsTF{Libertinus Math}{ % stylistically consisent with novel text
+ \setmathfont[BoldFont={libertinusmath-regular.otf}]%
+ {libertinusmath-regular.otf}
+}{
+ \IfFontExistsTF{Latin Modern Math}{}{% default for package `unicode-math'
+ }{ % The following hack allows you to proceed without a real math font,
+ % (but then you cannot print math):
+ \IfFontExistsTF{NovelDeco.otf}{%
+ \setmathfont[BoldFont={NovelDeco.otf}]{NovelDeco.otf} % fake math feature
+ \ClassWarning{novel}{^^JIgnore this if you used \string\setmathfont. ^^J%
+ Did not find suitable default math font. Used NovelDeco.otf. ^^J%
+ But NovelDeco does not have real math symbols. ^^J%
+ Math notation will print incorrectly. No problem if no math. ^^J}%
+ }{}% if no NovelDeco, do nothing here
+ }
+}%
+%% end settings for parent font and others.
+
+
+%% CREATING NEW FONT FONT FEATURES
+%% ----------------------------------------------------------------------------
+% \CreateFontFeature{substitutions}{feature code}
+% Problem: Font has one or more alternate glyphs that you would like to use,
+% but they are not listed in a feature set for the font.
+% Solution: Create your own feature set, with \CreateFontFeature. The created
+% feature may then be used like a real feature, in any font definition.
+% The substitutions are a comma-separated list, char=char.alt and so forth.
+% For example, the following substitutions are syntactically OK:
+% emdash=emdah.alt, one=one.rev, ntilde=ntilde.03
+% If a substitution is not available in a particular font, it is ignored.
+% You have to look at the font in a font editor, to know what is available.
+% It is possible to make silly substitutions, such as a=b, five=three without
+% throwing an error, unless your code causes a cycle.
+% The most useful application of this command is to reach alternate emdash,
+% and alternate oldstyle one. Not every font has these.
+% The feature code is a 4-character pseudo- Open Type code, otherwise unused.
+% For example, the feature code might be myfs (my fake substitution)
+% but it cannot be a pre-defined code such as lnum or smcp. It may be
+% a style set such as ss03 if you are sure that the font in question
+% do not already have ss03 (but this is taking a chance).
+% Once defined, you may use it like this (for example):
+% \SetParentFont[RawFeature=+myfs]{fontname}
+% \NewFontFamily\myfake[RawFeature=+myfs]{fontname}
+% In the document body: {\addfontfeature{myfs} text}
+\DeclareDocumentCommand \CreateFontFeature { m m } {%
+ \IfEndWith{#1}{,}{\StrGobbleRight{#1}{1}[\@fakezero]}{\def\@fakezero{#1}}
+ \def\@fakeone{"\@fakezero"}
+ \StrSubstitute{\@fakeone}{=}{"]="}[\@fakeone]
+ \StrSubstitute{\@fakeone}{,}{",\space["}[\@fakeone]
+ \directlua{
+ fonts.handlers.otf.addfeature {
+ name = "#2",
+ type = "substitution",
+ data = {\@fakeone},
+ }
+ }
+} %
+%% end \CreateFontFeature. Above thanks to fontspec 2016.
+
+
+%% ACTIVATE FONTS \AtEndPreamble
+%% ----------------------------------------------------------------------------
+\gdef\@ActivateFonts{% called by `novel.cls' \AtEndPreamble
+ % We begin with the parent font:
+ \if@coverart
+ \SetParentFont{NovelDeco.otf}
+ \fi
+ \if@ParentFontSet\else
+ \ifthenelse{\equal{\rmdefault}{lmr}}{%
+ % At this point, if \rmdefault is lmr, it means the user did not choose
+ % a different font. Then, Libertinus Serif or Latin Modern Roman
+ % will be automatically set as \rmdefault, if available:
+ \IfFontExistsTF{Libertinus Serif}{ % preferred default
+ \SetParentFont[%
+ BoldFont=libertinusserif-semibold.otf,%
+ BoldItalicFont=libertinusserif-semibolditalic.otf,%
+ ]{Libertinus Serif}
+ }{ % backup default, if Libertinus Serif not available:
+ \SetParentFont[%
+ SmallCapsFont={Latin Modern Roman Caps}%
+ ]{Latin Modern Roman}% only because it comes with LaTeX
+ \let\scshape\oldscshape % or small caps won't work
+ \let\smcp\oldscshape % or small caps won't work
+ }%
+ }{% However, if \rmdefault is not lmr, it means the user chose the font.
+ % If the choice was made via \SetParentFont, no problem. But if done by
+ % incorrect method such as \setmainfont, \renewcommand\rmdefault,
+ % or \usepackage{fontname}, an error is thrown:
+ \if@ParentFontSet\else
+ \ClassError{novel}{Wrong command used to set main font}%
+ {You tried to define the main document font the wrong way. ^^J%
+ Bad: \string\renewcommand\string\rmdefault{font}\space ^^J%
+ Bad: \string\usepackage{font package}\space ^^J%
+ Bad: \string\RequirePackage{font package}\space ^^J%
+ Bad: \string\setmainfont[features]{font}\sapce ^^J%
+ Those are incorrect in `novel' class. ^^J%
+ Use \string\SetParentFont[features]{font}\space instead. ^^J%
+ See `novel' documentation.}%
+ \fi
+ }%
+ \fi % end \if@ParentFontSet
+ % Now we are ready for the main (normal) font, descending from parent font:
+ \setmainfont[\parentfontfeatures]{\parentfontname}
+ \let\mainfont\rmfamily\relax % backwards compatibility
+ % The headfont, which descends from parent font:
+ \if@HeadFontSet\else % default if not user-set:
+ \SetHeadFont[Letters=SmallCaps,\parentfontfeatures,Scale=0.92]%
+ {\parentfontname}
+ \fi
+ \newfontfamily\headfont[\@headfontfeatures]{\@headfontname}
+ % The chapter font, descending from parent font:
+ \if@ChapterFontSet\else % if no user-set font, default:
+ \SetChapterFont[\parentfontfeatures,Scale=1.6]{\parentfontname}
+ \fi
+ \newfontfamily\chapterfont[\@chapterfontfeatures]{\@chapterfontname}
+ % The subch font, descending from parent font:
+ \if@SubchFontSet\else % if no user-set font, default:
+ \SetSubchFont[\parentfontfeatures,Scale=1.2]{\parentfontname}
+ \fi
+ \newfontfamily\subchfont[\@subchfontfeatures]{\@subchfontname}
+ % The remaining fonts are not descendants of parent font:
+ % The mono font:
+ \ifthenelse{\equal{\ttdefault}{lmtt}}{% over-ride:
+ \IfFontExistsTF{Libertinus Mono}{ % if available
+ \setmonofont[%
+ ItalicFont={},% Doesn't have these.
+ BoldFont={},%
+ BoldItalicFont={},%
+ ]{Libertinus Mono}
+ }{
+ \setmonofont{Latin Modern Mono}% backup
+ }
+ }{} % User \setmonofont, so leave alone.
+ % The sans font:
+ \ifthenelse{\equal{\sfdefault}{lmss}}{ % override:
+ \IfFontExistsTF{Libertinus Sans}{ % if available
+ \setsansfont{Libertinus Sans}
+ }{
+ \setsansfont{Latin Modern Sans}% backup
+ }
+ }{} % User \setsansfont, so leave alone.
+ % The decofont must be NovelDeco.otf or a user modification of that font:
+ \if@DecoFontSet\else
+ \IfFontExistsTF{NovelDeco.otf}{
+ \SetDecoFont{NovelDeco}
+ }{} % if not available, this will be detected below
+ \fi
+ % Decorative glyphs, only in this font. Should not be re-set by user.
+ \if@HasDecoFont % NovelDeco or a user-defined alternative was found:
+ \newfontface\@decoglyph[%
+ \@decofontfeatures,%
+ ]{\@decofontname}
+ \newfontface\@decoglypha[%
+ \@decofontfeatures,RawFeature=+ss01,%
+ ]{\@decofontname}
+ \newfontface\@decoglyphb[%
+ \@decofontfeatures,RawFeature=+ss02,%
+ ]{\@decofontname}
+ \newfontface\@decoglyphc[%
+ \@decofontfeatures,RawFeature=+ss03,%
+ ]{\@decofontname}
+ \fi% end \if@HasDecoFont
+ % New in version 1.50:
+ \if@HasDecoFont
+ \NewFontFace\decodropcapfont[RawFeature=+dcap]{\@decofontname}
+ \else
+ \NewFontFace\decodropcapfont[\parentfontfeatures,Numbers=Lining]%
+ {\parentfontname}
+ \fi
+ \if@HasDropCapFont\else
+ \SetDropCapFont{\decodropcapfont} % default
+ \fi
+ % This provides default microtype settings, allows the user to over-ride,
+ % and hopefully prevents the user from choosing inappropriate settings:
+ \let\microtypesetup\relax % fake command no longer needed
+ \if@MicrotypeSet % true if user wrote \microtypesetup{} in Preamble
+ \IfSubStr{\@mymicrotypesetup}{config}{% user specified own config file
+ \gdef\@mymicrotypeset{\@mymicrotypesetup}
+ }{ % default to novel's config file
+ \gdef\@mymicrotypeset{%
+ config=novel-microtype,final,\@mymicrotypesetup}
+ }
+ \else % user did not write \microtypesetup{} in Preamble
+ \gdef\@mymicrotypeset{%
+ config=novel-microtype,final,stretch=20,shrink=20}
+ \fi
+ \if@mtoff
+ \providecommand\textls[2][]{##2} % echoes its mandatory argument
+ \else
+ \RequirePackage[\@mymicrotypeset]{microtype}
+ \renewcommand\textls[2][]{##2} % nullifies the microtype command (problems)
+ \fi
+ % end microtypesetup
+%
+} % end \@ActivateFonts, called by `novel.cls' \AtEndPreamble.
+%%
+
+
+%%
+\endinput
+%%
+%% End of file `novel-Fonts.sty'
+
+
diff --git a/macros/luatex/latex/novel/novel-Footnotes.sty b/macros/luatex/latex/novel/novel-Footnotes.sty
new file mode 100644
index 0000000000..fb21fb1f7c
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-Footnotes.sty
@@ -0,0 +1,431 @@
+%%
+%% This is file `novel-Footnotes.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-Footnotes.sty}%
+[2018/04/26 v1.52 LaTeX file (commands for footnotes and endnotes)]
+%%
+
+
+
+%% Markers (superscript, subscripts):
+\newtoggle{@usesymbolmark} % true when footnote markers are symbolic
+\newtoggle{@realmarker} % true when OT features sups, sinf, subs requested
+%
+
+
+%% superscripts and subscripts
+\let\subs\relax
+\let\sups\relax
+\let\textsuperscript\relax
+\let\textsubscript\relax
+% Perhaps superscripts and subscripts (scientific) are in the font, or not.
+% Problem: The best fonts have these characters at size/weight designed
+% to mingle with normal size. But many fonts merely scaled characters,
+% which will be too light at the small size.
+% The unstarred version of these commands use the Open Type features when
+% they are present, then faking (auto scale/raise) if features not present.
+% The starred version just fakes, without regard for features.
+%
+
+% Note that the effect of these commands continues, not just one-shot:
+\gdef\realmarker{\global\toggletrue{@realmarker}} % anywhere in text
+\gdef\fakemarker{\global\togglefalse{@realmarker}} % anywhere in text
+\newlength\@hoAhl % height of Ahl, locally measured and set when needed
+%%
+\ExplSyntaxOn
+%
+\DeclareDocumentCommand \sups { m } {%
+ \iftoggle{@realmarker}{%
+ \fontspec_if_feature:nTF {sups}{%
+ \ifvmode\else\unskip\fi%
+ {\addfontfeature{VerticalPosition=Superior}\smash{#1}}%
+ }{%
+ \setlength\@hoAhl{\heightof{Ahl}}% local
+ \ifvmode\else\unskip\fi\charscale[0.7,0pt,0.5\@hoAhl]{#1}%
+ }%
+ }{%
+ \setlength\@hoAhl{\heightof{Ahl}}% local
+ \ifvmode\else\unskip\fi%
+ {\addfontfeature{Numbers=Lining}\charscale[0.7,0pt,0.5\@hoAhl]{#1}}%
+ }%
+}% end \sups
+%
+\DeclareDocumentCommand \subs { m } {%
+ \iftoggle{@realmarker}{%
+ \fontspec_if_feature:nTF {sinf}{%
+ \ifvmode\else\unskip\fi%
+ {\addfontfeature{VerticalPosition=ScientificInferior}\smash{#1}}%
+ }{%
+ \fontspec_if_feature:nTF {subs}{%
+ \ifvmode\else\unskip\fi%
+ {\addfontfeature{VerticalPosition=Inferior}\smash{#1}}%
+ }{%
+ \setlength\@hoAhl{\heightof{Ahl}}% local
+ \ifvmode\else\unskip\fi\charscale[0.7,0pt,-0.2\@hoAhl]{#1}%
+ }%
+ }%
+ }{%
+ \setlength\@hoAhl{\heightof{Ahl}}% local
+ \ifvmode\else\unskip\fi%
+ {\addfontfeature{Numbers=Lining}\charscale[0.7,0pt,-0.2\@hoAhl]{#1}}%
+ }%
+}% end \subs
+%
+\cs_new_eq:NN \textsuperscript \sups
+\cs_new_eq:NN \textsubscript \subs
+\ExplSyntaxOff
+%%
+
+
+
+% \SetMarkerStyle does two things.
+% Option real: OT features sups, sinf, subs requested. Fake if not available.
+% Option fake: Always fake OT features sups, sinf, subs.
+% Mandatory: asterisk, dagger, number. Pertains to footnote markers only.
+% No matter real or fake, the asterisk symbol is always real, and the
+% dagger, dbldagger, and section (when used as footnote markers)
+% are always partially faked.
+\newcommand\SetMarkerStyle[2][real]{
+ \def\@goodfnm{no}
+ \ifthenelse{\equal{#2}{asterisk}}{%
+ \def\@goodfnm{yes}\global\toggletrue{@usesymbolmark}%
+ \gdef\@myfnsymbols{*}}{}
+ \ifthenelse{\equal{#2}{dagger}}{%
+ \def\@goodfnm{yes}\global\toggletrue{@usesymbolmark}%
+ \gdef\@myfnsymbols{†}}{}
+ \ifthenelse{\equal{#2}{number}}{%
+ \def\@goodfnm{yes}\global\togglefalse{@usesymbolmark}}{}
+ \def\@goodfnk{no}
+ \ifthenelse{\equal{#1}{real}\OR\equal{#1}{}}{%
+ \def\@goodfnk{yes}\global\toggletrue{@realmarker}}{}
+ \ifthenelse{\equal{#1}{fake}}{%
+ \def\@goodfnk{yes}\global\togglefalse{@realmarker}}{}
+ \ifthenelse{\equal{\@goodfnm}{no}\OR\equal{\@goodfnk}{no}}{%
+ \ClassError{novel}{Bad choice for \string\SetMarkers}%
+ {Optional: real, fake. Required: asterisk, dagger, number.}%
+ }{}
+}
+\LetLtxMacro{\SetMarkers}{\SetMarkerStyle} % backward compatibilty pre-v1.40.3.
+%
+\SetMarkerStyle[real]{asterisk} % default
+%%
+
+
+
+%% FOOTNOTES
+%% ----------------------------------------------------------------------------
+% In `novel' class, you may place footnotes at the botom of the textblock.
+% The markers may be symbolic (default begins with asterisk), or
+% set so that the asterisk is not used, or the markers may be numbers,
+% If symbolic, they will be automatically reset by ChapterStart.
+% You can manually reset them at any time.
+% You can also make a non-marked footnote, which does not increment the count.
+
+
+% Lengths used to tweak vertical position of symbolic (text) footnote markers:
+\newlength\@twast % tweaks asterisk
+\newlength\@twdag % tweaks dagger
+\newlength\@twdbldag % tweaks double dagger
+\newlength\@twsect % tweaks section mark
+\newlength\@tweight % tweaks 8, reliably the tallest digit
+
+
+%% footnotesize is calculated by layout, based on normal font size and skip.
+%% It is used only for actual footnotes!
+
+%
+\newcounter{@fnsymbolcount} % counter, footenote symbolic markers
+ \setcounter{@fnsymbolcount}{1}
+\newcounter{@fnnumbercount} % counter, footnote numerical markers
+ \setcounter{@fnnumbercount}{1}
+\newcounter{@rnnumbercount} % counter, endnote markers (always numerical)
+ \setcounter{@rnnumbercount}{1}
+\newcounter{@maxfnsymbol} % max footnote symbol count before recycle
+%
+\gdef\ResetFootnote{% symbols or numbers
+ \setcounter{@fnsymbolcount}{1}%
+ \setcounter{@fnnumbercount}{1}%
+}
+\gdef\ResetFootnoteSymbol{\setcounter{@fnsymbolcount}{1}} % only symbols
+\gdef\Resetendnote{\setcounter{@rnnumbercount}{1}}
+%
+\newtoggle{@usenomark} % when true: no mark, no increment count
+\newtoggle{@placedfootnotenumber} % true if any numerical footnote placed
+%
+\let\@myoldfootnote\footnote\relax % copies the original definition
+\let\footnote\relax % so it can be re-defined, below
+%
+\gdef\@fourem{% length of rule separating footnotes from main text
+ \vspace{-\nbs}%
+ \noindent\strut\smash{\rule[-2pt]{0.33\textwidth}{0.05\@SetFontSize}}%
+}
+\let\footnoterule\@fourem
+%
+
+
+% \@makefnmark applies to the footnote marker in the flow of main text:
+\gdef\@makefnmark{\iftoggle{@usenomark}{}{\@getfnmark}}
+%
+\long\gdef\@makefntext#1{% the actual footnote, at bottom of textblock
+ \iftoggle{@usenomark}%
+ {\forceindent#1}%
+ {\forceindent\@getbotfnmark\,#1}%
+} % end \@makefntext
+% Now re-define \footnote:
+\newcommand\footnote[2][]{%
+ \ifthenelse{\equal{#1}{0}}{%
+ \global\toggletrue{@usenomark}%
+ }{%
+ \global\togglefalse{@usenomark}%
+ }%
+ \gdef\footnoterule{\vfill\@fourem}%
+ \begingroup%
+ \def\footnotesize{% Not gdef. Local to footnote. Calculated during layout.
+ \@setfontsize\footnotesize{\@myfootnotesizeN pt}{\@myfootnoteskipN pt}%
+ }%
+ \unskip\@myoldfootnote{#2}%
+ \endgroup%
+} % end \footnote
+%
+% \@rollfnsymbol prevents running out of symbolic markers:
+\gdef\@rollfnsymbol{%
+ \stepcounter{@fnsymbolcount}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{\value{@maxfnsymbol}}}{%
+ \setcounter{@fnsymbolcount}{1}%
+ }{}%
+} % end \@rollfnsymbol
+%
+% \@getfnmark places a footnote marker in the running text.
+% The marker depends upon whether it should be a number or a symbol.
+% If the latter, then it depends on whether the symbols include asterisks.
+% And, it depends upon the current count for that type of marker.
+\gdef\@getfnmark{%
+ \iftoggle{@usesymbolmark}%
+ {%
+ \global\togglefalse{@placedfootnotenumber}%
+ \ifthenelse{\equal{\@myfnsymbols}{*}}{%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{1}}{%
+ \charscale[1,0pt,-\@twast]{*}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{2}}{%
+ \charscale[0.8,0pt,-\@twdag]{†}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{3}}{%
+ \charscale[0.8,0pt,-\@twdbldag]{‡}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{4}}{%
+ \charscale[0.8,0pt,-\@twsect]{§}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{5}}{%
+ \charscale[1,0pt,-\@twast]{**}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{6}}{%
+ \charscale[0.8,0pt,-\@twdag]{††}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{7}}{%
+ \charscale[0.8,0pt,-\@twdbldag]{‡‡}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{8}}{%
+ \charscale[0.8,0pt,-\@twsect]{§§}%
+ }{}%
+ }{}%
+ \ifthenelse{\equal{\@myfnsymbols}{†}}{%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{1}}{%
+ \charscale[0.8,0pt,-\@twdag]{†}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{2}}{%
+ \charscale[0.8,0pt,-\@twdbldag]{‡}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{3}}{%
+ \charscale[0.8,0pt,-\@twsect]{§}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{4}}{%
+ \charscale[0.8,0pt,-\@twdag]{††}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{5}}{%
+ \charscale[0.8,0pt,-\@twdbldag]{‡‡}%
+ }{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{6}}{%
+ \charscale[0.8,0pt,-\@twsect]{§§}%
+ }{}%
+ }{}%
+ }{%
+ \global\toggletrue{@placedfootnotenumber}%
+ \sups{\arabic{@fnnumbercount}}%
+ }%
+} % end \@getfnmark
+%
+% \@getbotfnmark places the marker in front of the actual footnote,
+% towards the bottom of the textblock. It duplicates the marker used in
+% running text, but is not elevated. Then, it increments the relevant count.
+% Note that (unlike some other TeX document classes) this marker is at
+% the indent, so that the footnote text is farther inward than the indent.
+% This is the preferred style.
+\gdef\@getbotfnmark{%
+ \iftoggle{@usesymbolmark}%
+ {%
+ \ifthenelse{\equal{\@myfnsymbols}{*}}{%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{1}}{*}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{2}}{†}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{3}}{‡}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{4}}{§}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{5}}{**}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{6}}{††}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{7}}{‡‡}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{8}}{§§}{}%
+ }{}%
+ \ifthenelse{\equal{\@myfnsymbols}{†}}{%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{1}}{†}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{2}}{‡}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{3}}{§}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{4}}{††}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{5}}{‡‡}{}%
+ \ifthenelse{\equal{\value{@fnsymbolcount}}{6}}{§§}{}%
+ }{}%
+ \@rollfnsymbol%
+ }{%
+ \textrm{\arabic{@fnnumbercount}.}%
+ \stepcounter{@fnnumbercount}%
+ }%
+} %end \@getbotfnmark
+%
+%% end footnotes
+
+
+
+%% ENDNOTES. Behavior modified in v. 1.50 (added error messages).
+%% ----------------------------------------------------------------------------
+% \endnote only places a marker. It does not store a note for later use.
+% Any argument is non-printing. So \endnote{ancestry of yada} does not print
+% anything other than the endnote marker number, and does not save
+% `ancestry of Yada' for later use. The argument is a self-memo, so that you
+% remember why you want an endnote there, when you look at the source.
+% Following \endnote or \endnotetext with [ will produce an error.
+% Reason: Confuses novel's commands with those from banned `endnote' package.
+% Whenever \endnote is used, the marker number and page is added to a list,
+% and the list is typed into the log file after the document ends. That way,
+% you can hunt down where the endnotes markers were placed.
+\newtoggle{@gotendnotes} % true if \endnote used
+%
+\long\gdef\@endnotelist{}
+\newcounter{@endnotecount}
+%
+\def\@addendnote{%
+ \global\toggletrue{@gotendnotes}%
+ \stepcounter{@endnotecount}\sups{\arabic{@endnotecount}}%
+ \long\edef\@endnotelist{%
+ \@endnotelist\space (\arabic{@endnotecount},p.\thepage)%
+ }%
+}
+\def\@nendnote#1{\@addendnote}
+\def\@nenspace{\@addendnote\space}
+\def\@nenerror{%
+ \ClassError{novel}{\string\endnote\space cannot be followed by [ character}%
+ {To avoid possible confusion with similar command from other packages, ^^J%
+ you may not follow \string\endnote\space with [ character. ^^J%
+ However, you may do \string\endnote\string{\string}[ if desired.}%
+}
+\def\@ndospace{\@ifnextchar[\@nenerror\@nenspace}
+\def\endnote{\@ifnextchar\bgroup\@nendnote\@ndospace}
+%%
+% \endnotetext{ID}{text} where ID is (usually) the endnote number.
+% If ID is other than space or tilde, it prints at left margin, followed by
+% period. Then the entire text is block-indented. Only one paragraph allowed.
+% If ID is space or empty, then the entire text is block-indented. This is
+% the method for continuing a prior endnote to a new paragraph. The text
+% may begin with \forceindent, according to your needs.
+\def\@nentexterror{%
+ \ClassError{novel}{\string\endnotetext\space cannot be followed by [ character}%
+ {To avoid possible confusion with similar command from other packages, ^^J%
+ you may not follow \string\endnotetext\space with [ character. ^^J%
+ This command takes two mandatory arguments. No optional argument.}%
+}
+%
+\newcommand\nentext[2]{%
+ \ifthenelse{\equal{#1}{\space}\OR\equal{#1}{}}%
+ {\noindent\hangindent=\parindent\flexbox{\space}#2\par}%
+ {\noindent\hangindent=\parindent\flexbox{\lnum{#1}. }#2\par}%
+}
+% In case the user inadvertently uses systax from `endnotes' package:
+\def\endnotetext{\@ifnextchar[\@nentexterror\nentext}
+%
+%% end endnotes
+
+
+%% See novel.cls for the accompanying \AtBeginDocument routine.
+
+
+%% Pertains to some standard LaTeX footnote code:
+\AtBeginShipout{\gdef\@fnafter{}}
+%%
+
+
+\gdef\@ActivateFootnotes{% called by `novel.cls' \AtBeginDocument
+ % Pertains to novel-footnotes.sty:
+ \LetLtxMacro\SetMarkerStyle\relax
+ \gsetlength\footnotesep{0.8\nbs}
+ % Adjusted position of footnote markers. Must wait for main font size:
+ \gsetlength\@twast{\heightof{*}-\normalAringheight}
+ \gsetlength\@twdag{\heightof{†}}
+ \gsetlength\@twdag{0.8\@twdag-\normalAringheight}
+ \gsetlength\@twdbldag{\heightof{‡}}
+ \gsetlength\@twdbldag{0.8\@twdbldag-\normalAringheight}
+ \gsetlength\@twsect{\heightof{§}}
+ \gsetlength\@twsect{0.8\@twsect-\normalAringheight}
+ \gsetlength\@tweight{\heightof{8}}%
+ \gsetlength\@tweight{0.8\@tweight-\normalAringheight}%
+ % Must wait to see how \SetFootnoteMarker was used:
+ \ifthenelse{\equal{\@myfnsymbols}{*}}{\setcounter{@maxfnsymbol}{8}}{}
+ \ifthenelse{\equal{\@myfnsymbols}{†}}{\setcounter{@maxfnsymbol}{6}}{}
+ % Values to be used by footnotes:
+ \FPdiv{\@myFontScale}{\strip@pt\@SetFontSize}{12}
+ % Substitute for \footnotesize, but only works for actual footnotes,
+ % about 10pt with similarly reduced skip:
+ \FPmul{\@myfootnotesizeN}{\@myFontScale}{10}
+ \FPround{\@myfootnotesizeN}{\@myfootnotesizeN}{2}
+ \FPmul{\@myfootnoteskipN}{\@myFontScale}{\strip@pt\nbs}
+ \FPmul{\@myfootnoteskipN}{\@myfootnoteskipN}{0.84}
+ \FPround{\@myfootnoteskipN}{\@myfootnoteskipN}{2}
+}% end \@ActivateFootnotes
+
+
+
+
+
+
+%% ATENDDOCUMENT
+%% ----------------------------------------------------------------------------
+%% Write a list of endnote (number,page) into log file,
+% and Big Bad Warning if numerical footnotes and endnotes both used:
+\AtEndDocument{%
+ \iftoggle{@gotendnotes}{%
+ \typeout{^^JClass `novel' Alert: You placed endnotes (number,page): ^^J%
+ \@endnotelist ^^J}%
+ }{}
+ %
+ \iftoggle{@placedfootnotenumber}{%
+ \iftoggle{@gotendnotes}{%
+ \ClassWarning{novel}{^^JBIG BAD WARNING! You used numbered footnotes ^^J%
+ and numbered endnotes. Better change to symbolic footnotes! ^^J}%
+ }{}
+ }{}%
+}% end \AtEndDocument
+%%
+
+
+%%
+\endinput
+%%
+%% end of file `novel-Footnotes.sty'
+
diff --git a/macros/luatex/latex/novel/novel-HeadFootStyles.sty b/macros/luatex/latex/novel/novel-HeadFootStyles.sty
new file mode 100644
index 0000000000..e19000bb26
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-HeadFootStyles.sty
@@ -0,0 +1,498 @@
+%%
+%% This is file `novel-HeadFootStyles.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-HeadFootStyles.sty}%
+[2018/04/26 v1.52 LaTeX file (header and footer layouts and styles)]
+%%
+
+
+
+%% File `novel-LayoutSettings.sty' reserved space for header/footer,
+%% but did not place anything there. In this file, `fancyhdr' syntax
+%% defines the layout. The layout are not activated until
+%% \AtEndPreamble, and only if the user did not already define the layout
+%% in the Preamble.
+
+\gdef\@HeadFootStyle{1} % default: header but not footer
+\gdef\@VersoEmblem{} % no default emblem
+\gdef\@RectoEmblem{} % no default emblem
+
+
+%% SET HEADER/FOOTER STYLE AND RESERVE SPACE FOR HEADER/FOOTER
+%% ----------------------------------------------------------------------------
+% There are several pre-configured header/footer styles, addressing every
+% situation likely to be seen in popular fiction. The style details are
+% coded, using `fancyhdr' syntax, in novel-HeadFootStyles.sty.
+% If you wish to create a custom head/foot style, you must first choose
+% one of the pre-configured styles, then customize it. That way,
+% the layout engine knows whether header or footer are present.
+\newif \if@StyledHeader % true if user-customized header using \fancyhead
+\newif \if@StyledFooter % true if user-customized footer using \fancyfoot
+%
+\gdef\SetHeadFootStyle#1{%
+ \if@coverart
+ \gdef\@HeadFootStyle{0} % required: no header/footer for coverart
+ \ifthenelse{\equal{#1}{0}}{}{%
+ \ClassWarning{novel}{^^JClass option `coverart' does not %
+ allow header/footer. Ignored. ^^J}
+ }%
+ \else
+ \@tempTFfalse
+ \ifthenelse{\equal{#1}{0}}{%
+ \global\@HasHeaderfalse\global\@HasFooterfalse\@tempTFtrue%
+ }{}
+ \ifthenelse{\equal{#1}{1}}{%
+ \global\@HasHeadertrue\global\@HasFooterfalse\@tempTFtrue%
+ }{}
+ \ifthenelse{\equal{#1}{2}}{%
+ \global\@HasHeaderfalse\global\@HasFootertrue\@tempTFtrue%
+ }{}
+ \ifthenelse{\equal{#1}{3}}{%
+ \global\@HasHeaderfalse\global\@HasFootertrue\@tempTFtrue%
+ }{}
+ \ifthenelse{\equal{#1}{4}}{%
+ \global\@HasHeadertrue\global\@HasFooterfalse\@tempTFtrue%
+ }{}
+ \ifthenelse{\equal{#1}{5}}{%
+ \global\@HasHeadertrue\global\@HasFootertrue\@tempTFtrue%
+ }{}
+ \ifthenelse{\equal{#1}{6}}{%
+ \global\@HasHeadertrue\global\@HasFootertrue\@tempTFtrue%
+ }{}
+ % Ensure that user choice was on the allowed list:
+ \if@tempTF\else
+ \ClassError{novel}{Invalid choice for \string\SetHeadFootStyle}%
+ {\string\SetHeadFootStyle\space needs choice of 0,1,2,3,4,5,6, ^^J%
+ even if you wish to customize using fancyhdr syntax.}%
+ \fi
+ \gdef\@HeadFootStyle{#1}
+ \fi
+}%
+\SetHeadFootStyle{1} % default, header only
+\let\SetHeadStyle\SetHeadFootStyle\relax % deprecated
+%
+% \HeadJump is a number from 1 to 3 (may be decimal). It measures the
+% distance from baseline of header text, to first baseline of main text,
+% then divides by the normal baseline.
+% So, a \HeadJump of 1 means that the header text is positioned exactly
+% one line above main text (unlikely). A value of 2 skips a whole line.
+% The default value is 1.5, which is often used in popular fiction.
+% No matter what value is set, it will be re-set to 0 later, if the
+% choice of head/foot style does not have a header.
+% Likewise for \FootJump, measuring from baseline of lowermost main text,
+% to baseline of footer text.
+\gdef\SetHeadJump#1{%
+ \IfDecimal{#1}{%
+ \FPiflt{#1}{1}
+ \ClassError{novel}{\string\SetHeadJump\space must be at least 1}%
+ {\string\SetHeadJump\string from 1 to 3, may be decimal.}%
+ \fi
+ \FPifgt{#1}{3}
+ \ClassError{novel}{\string\SetHeadJump\space must not exceed 3}%
+ {\string\SetHeadJump\string from 1 to 3, may be decimal.}%
+ \fi
+ \gdef\@HeadJump{#1}
+ }{%
+ \ClassError{novel}{Unable to parse \string\SetHeadJump\space argument}%
+ {Needs integer or decimal, but not ending in decimal point or comma. ^^J%
+ Must be a number from 1 to 3, but may not be a macro.}%
+ }%
+}
+\SetHeadJump{1.5} % default
+%
+\gdef\SetFootJump#1{%
+ \IfDecimal{#1}{%
+ \FPiflt{#1}{1}
+ \ClassError{novel}{\string\SetFootJump\space must be at least 1}%
+ {\string\SetFootJump\string from 1 to 3, may be decimal.}%
+ \fi
+ \FPifgt{#1}{3}
+ \ClassError{novel}{\string\SetFootJump\space must not exceed 3}%
+ {\string\SetFootJump\string from 1 to 3, may be decimal.}%
+ \fi
+ \gdef\@FootJump{#1}
+ }{%
+ \ClassError{novel}{Unable to parse \string\SetFootJump\space argument}%
+ {Needs integer or decimal, but not ending in decimal point or comma. ^^J%
+ Must be a number from 1 to 3, but may not be a macro.}%
+ }%
+}
+\SetFootJump{1.5} % default
+%
+%% end set style and reserve space for header/footer.
+
+
+%% Used in novel-headfootstyles.sty:
+% \SetLooseHead looseness factor (fontspec LetterSpace) 0=tight, 50=default
+\gdef\SetLooseHead#1{
+ \FPdiv{\@loosehead}{#1}{10} % change method fontspec w/ microtype
+ \FPmin{\@looseheadN}{\@loosehead}{50} % don't want numbers too loose
+ \FPdiv{\@looseheadword}{\@loosehead}{30} % inter-word, new in v. 1.40.3
+ \FPadd{\@looseheadword}{\@looseheadword}{1}
+}
+\SetLooseHead{50}
+%%
+
+%
+% See docs for what these emblems do, if used:
+\newcommand\SetEmblems[2]{ % verso, recto
+ \gdef\@VersoEmblem{{\headfont #1}}
+ \gdef\@RectoEmblem{{\headfont #2}}
+}
+\let\SetEmblem\SetEmblems% for convenience
+% If you want something fancier than \thepage:
+\gdef\SetPageNumberStyle#1{% no small caps, so lowercase roman preserved
+ \gdef\pagenumberstyle{{\addfontfeature{Letters=ResetAll}#1}}
+}
+\SetPageNumberStyle{\thepage}% no small caps
+% See novel.cls for the accompanying AtBeginDocument routine.
+
+
+%% INITIALIZE FANCYHDR
+%% ----------------------------------------------------------------------------
+% Earlier, space was reserved for header/footer, but the content of
+% headers and footers was not specified. Now, package `fancyhdr'
+% will be used to create the content.
+% Start by loading package `fancyhdr' and blanking everything:
+\RequirePackage{fancyhdr}
+ \renewcommand\headrulewidth{0pt}
+ \renewcommand\footrulewidth{0pt}
+ \fancyhead[LO,RE,LE,RO,CE,CO]{}
+ \fancyfoot[LO,RE,LE,RO,CE,CO]{}
+% It might be useful to know whether something is being placed in main text,
+% or within a header/footer. A new boolean is created, which is only true
+% when within a header or footer. You can define macros so that they test
+% this boolean.
+% To make this work, \fancyhead and \fancyfoot are re-defined:
+\newtoggle{@inheadfoot} % true within header or footer
+\LetLtxMacro{\@myfancyhead}{\fancyhead}
+\LetLtxMacro{\@myfancyfoot}{\fancyfoot}
+\renewcommand\fancyhead[2][]{%
+ \global\@StyledHeadertrue%
+ \@myfancyhead[#1]{\toggletrue{@inheadfoot}{\normalsize #2}}% not global
+}
+\renewcommand\fancyfoot[2][]{%
+ \global\@StyledFootertrue%
+ \FPsub{\@footraise}{\@FootJump}{1}%
+ \FPmul{\@footraise}{-\@footraise}{\strip@pt\nbs}%
+ \@myfancyfoot[#1]{%
+ \toggletrue{@inheadfoot}% not global
+ \stake\smash{\raisebox{\@footraise pt}{\normalsize #2}}%
+ }%
+}
+%% end initialize fancyhdr.
+
+
+%% THISPAGESTYLE COMMANDS
+%% ----------------------------------------------------------------------------
+% Re-define \thispagestyle based on layout. When it requests only the page
+% number, decide what to do based on this command and whether footer is used:
+\newif \if@ThisPageStyle % true if \thispagestyle declared for current page
+\newif \if@DeleteCSline % true when using @dropfolioinside
+\AtBeginShipout{% re-sets when page done
+ \global\@DeleteCSlinefalse%
+ \global\@ThisPageStylefalse%
+}
+\LetLtxMacro{\@myTempTPS}{\thispagestyle}
+%
+\gdef\thispagestyle#1{%
+ \global\@ThisPageStyletrue%
+ \@tempTFfalse%
+ % Style `fancy' is same as normal style:
+ \ifthenelse{\equal{#1}{fancy}}{%
+ \@tempTFtrue%
+ \@myTempTPS{fancy}%
+ }{}%
+ % Style `empty' has no visible content in header or footer.
+ % This style is pre-defined, so no need to re-define it here.
+ \ifthenelse{\equal{#1}{empty}}{%
+ \@tempTFtrue%
+ \@myTempTPS{empty}%
+ }{}%
+ % Style `footer' has no visible content in header.
+ % If the normal style has a footer, it will be used as-is. However, if the
+ % normal style does not have a footer, then (unlike the above style)
+ % the page number will not be placed at bottom; as with style `empty'.
+ \ifthenelse{\equal{#1}{footer}}{%
+ \@tempTFtrue%
+ \if@HasFooter\@myTempTPS{@footer}%
+ \else\@myTempTPS{empty}%
+ \fi%
+ }{}%
+ % Style `forcenumber' is rarely used. If the normal style has a footer,
+ % it will be used as-is (presumably contains the page number), and there
+ % will be no visible content in the header.
+ % But if there is no normal footer, then the outside portion of the header
+ % is printed. No other portion of the header. Presumably the page number
+ % is located at the outside of the header.
+ \ifthenelse{\equal{#1}{forcenumber}}{%
+ \@tempTFtrue%
+ \if@HasFooter\@myTempTPS{@footer}%
+ \else\@myTempTPS{@forcenumber}%
+ \fi%
+ }{}%
+ % Style `dropfoliobeneath': There will be no visible content in header.
+ % If the normal style has a footer, it will be used as-is. This assumes
+ % that the page number is contained in the footer, the usual case.
+ % If the normal style has no footer, then the page number will be centered
+ % within the lower margin, at the position where an exta line would be.
+ % Thus, pagination of the main text is unaffected.
+ % Since the number is closer than usual to the page bottom edge, you must
+ % ensure that it does not intrude into the unsafe zone (where printers
+ % prohibit any printable matter). TeX cannot check this for you. However,
+ % you can define an Unsafe Zone, and inspect placement of the number
+ % in draft mode.
+ % Styles `plain*' and `fancyplain*' (with asterisk) are aliases.
+ \ifthenelse{\equal{#1}{dropfoliobeneath}%
+ \OR \equal{#1}{plain*} \OR \equal{#1}{fancyplain*}}{%
+ \@tempTFtrue%
+ \if@HasFooter\@myTempTPS{@footer}%
+ \else%
+ \@myTempTPS{@dropfoliobeneath}%
+ \typeout{^^JClass `novel' Alert: Page no. \thepage\space in margin. ^^J%
+ Review layout to ensure that this is within the Safe Area. ^^J%
+ }%
+ \fi%
+ }{}%
+ % Style `dropfolioinside': There will be no visible content in header.
+ % If the normal style has a footer, it will be used as-is. This assumes
+ % that the page number is contained in the footer, the usual case.
+ % If the normal style has not footer, then the page number will be centered
+ % where the last line of main text would ordinarily be. No extra gap.
+ % That may cause the (former) last line of main text to flow to the top of
+ % the next page, and so forth. However, if this page style is used on
+ % a page with ChapterStart, then the height of ChapterStart will be
+ % automatically reduced by one line, so that there is no repagination.
+ % Styles `plain', `fancyplain', `dropfolio', and `dropfoliolater' are aliases
+ % for `dropfolioinside'. I couldn't make up my mind regarding the
+ % command name. For compatibility, all these do the same thing.
+ \ifthenelse{\equal{#1}{dropfolioinside}%
+ \OR \equal{#1}{plain} \OR \equal{#1}{fancyplain}%
+ \OR \equal{#1}{dropfolio} \OR \equal{#1}{dropfoliolater}}{%
+ \@tempTFtrue%
+ \if@HasFooter\@myTempTPS{@footer}%
+ \else%
+ \global\@DeleteCSlinetrue%
+ \enlargethispage{-\nbs}%
+ \@myTempTPS{@dropfolioinside}%
+ \fi%
+ }{}%
+ % Verify that an allowable choice was made:
+ \if@tempTF\else%
+ \ClassError{novel}{^^JPage \thepage\space has \string\thispagestyle ^^J%
+ but its argument is not on the list of choices. See docs. ^^J}%
+ \fi%
+} % end \thispagestyle.
+%
+\let\dropfolionow\relax % compatibility with earlier version.
+%
+% Here are the thispagestyle definitions:
+\fancypagestyle{@footer}{ % blanks header, but leaves footer as-is
+ \renewcommand\headrulewidth{0pt}
+ \renewcommand\footrulewidth{0pt}
+ \fancyhead[LO,RE,LE,RO,CE,CO]{}
+}
+\fancypagestyle{@dropfolioinside}{ % page number where last line would be
+ \renewcommand\headrulewidth{0pt}
+ \renewcommand\footrulewidth{0pt}
+ \fancyhead[LO,RE,LE,RO,CE,CO]{}
+ \fancyfoot[LO,RE,LE,RO]{}
+ \fancyfoot[CO,CE]{%
+ \raisebox{\dimexpr\@FootJump\nbs}{\@lspagenum\pagenumberstyle}%
+ }
+}
+\fancypagestyle{@dropfoliobeneath}{ % page number in margin below text
+ \renewcommand\headrulewidth{0pt}
+ \renewcommand\footrulewidth{0pt}
+ \fancyhead[LO,RE,LE,RO,CE,CO]{}
+ \fancyfoot[LO,RE,LE,RO]{}
+ \fancyfoot[CO,CE]{%
+ \raisebox{\dimexpr\@FootJump\nbs-\nbs}{\@lspagenum\pagenumberstyle}%
+ }
+}
+\fancypagestyle{@forcenumber}{ % if has header but not footer
+ \renewcommand\headrulewidth{0pt}
+ \renewcommand\footrulewidth{0pt}
+ \fancyhead[LO,RE,LE,RO,CE,CO]{}
+ \fancyhead[LE]{%
+ \makebox[2.5em][l]{\@lspagenum\pagenumberstyle}%
+ \@VersoEmblem%
+ }
+ \fancyhead[RO]{%
+ \@RectoEmblem%
+ \makebox[2.5em][r]{\@lspagenum\pagenumberstyle}%
+ }
+ \fancyfoot[LO,RE,LE,RO,CE,CO]{}
+}
+%% end \thispagestyle commands.
+
+
+%%
+\gdef\@lshftext{\headfont\addfontfeature{LetterSpace=\@loosehead}}
+\gdef\@lspagenum{\headfont\addfontfeature{LetterSpace=\@looseheadN}}
+%%
+
+% Content of header text (if present) can be changed at any time within
+% the body, using the following commands. If not used, then
+% Verso is initialized to \theauthor and Recto is initialized to \thetitle
+% AtBeginDocument, with adjustments to interword spacing.
+% If you wish, you may write the commands with empty arguments, in which case
+% the header still appears with page number (if present), but no text.
+%
+\gdef\NewVersoHeadText#1{\gdef\versoheadtext{#1}}
+\let\SetVersoHeadText\NewVersoHeadText\relax % for convenience
+\let\RenewVersoHeadText\NewVersoHeadText\relax % for convenience
+%
+\gdef\NewRectoHeadText#1{\gdef\rectoheadtext{#1}}
+\LetLtxMacro\SetRectoHeadText\NewRectoHeadText\relax % for convenience
+\LetLtxMacro\RenewRectoHeadText\NewRectoHeadText\relax % for convenience
+%
+%%
+
+
+%% See AtBeginDocument routine in novel.cls:
+%% ----------------------------------------------------------------------------
+\gdef\@ActivateHeadFootStyles{ % called AtBeginDocument by novel.cls
+ % Pre-configured header/footer styles, unless user over-rode them:
+ % \versoheadtext is initialized to \theauthor
+ % \rectoheadtext is initialized to \thetitle
+ \@ifundefined{versoheadtext}{
+ \NewVersoHeadText{\theauthor} % revised in v. 1.40.3
+ }{}
+ \@ifundefined{rectoheadtext}{
+ \NewRectoHeadText{\thetitle} % revised in v. 1.40.3
+ }{}
+ %
+ % ---------------------------------------------------------------------------
+ % IF YOU ARE WRITING YOUR OWN HEADER/FOOTER LAYOUT:
+ % Look here for the pre-defined layouts, for use as models.
+ % Note that if you write \fancyhead or \fancyfoot in the Preamble,
+ % that sets the \@StyledHeader flag, so these codes do not over-ride yours.
+ % \@lshftext loosens text tracking.
+ % \@lspagenum loosens page number tracking, like \@lshftext but capped
+ % at a maximum looseness.
+ \ifthenelse{\equal{\@HeadFootStyle}{1}}{ % default
+ \if@StyledHeader\else
+ \fancyhead[LE]{%
+ \makebox[2.5em][l]{\@lspagenum\pagenumberstyle}%
+ \@VersoEmblem%
+ }
+ \fancyhead[RO]{%
+ \@RectoEmblem%
+ \makebox[2.5em][r]{\@lspagenum\pagenumberstyle}%
+ }
+ \fancyhead[CE]{\@lshftext\versoheadtext}
+ \fancyhead[CO]{\@lshftext\rectoheadtext}
+ \fi
+ }{}
+ %
+ \ifthenelse{\equal{\@HeadFootStyle}{2}}{
+ \global\@StyledHeaderfalse
+ \if@StyledFooter\else
+ \fancyfoot[LE]{%
+ \makebox[2.5em][l]{\@lspagenum\pagenumberstyle}%
+ \@VersoEmblem%
+ }
+ \fancyfoot[RO]{%
+ \@RectoEmblem%
+ \makebox[2.5em][r]{\@lspagenum\pagenumberstyle}%
+ }
+ \fi
+ }{}
+ %
+ \ifthenelse{\equal{\@HeadFootStyle}{3}}{
+ \if@StyledFooter\else
+ \fancyfoot[CO,CE]{\@lspagenum\pagenumberstyle}
+ \fi
+ }{}
+ %
+ \ifthenelse{\equal{\@HeadFootStyle}{4}}{
+ \if@StyledHeader\else
+ \fancyhead[LE]{%
+ \makebox[2.5em][l]{\@lspagenum\pagenumberstyle}%
+ \@VersoEmblem%
+ \hspace{1em}%
+ {\@lshftext\versoheadtext}%
+ }
+ \fancyhead[RO]{%
+ {\@lshftext\rectoheadtext}%
+ \hspace{1em}%
+ \@RectoEmblem%
+ \makebox[2.5em][r]{\@lspagenum\pagenumberstyle}%
+ }
+ \fi
+ }{}
+ %
+ \ifthenelse{\equal{\@HeadFootStyle}{5}}{
+ \if@StyledHeader\else
+ \fancyhead[CE]{\@lshftext\versoheadtext}
+ \fancyhead[CO]{\@lshftext\rectoheadtext}
+ \fi
+ \if@StyledFooter\else
+ \fancyfoot[CO,CE]{%
+ {\@lspagenum\pagenumberstyle}%
+ }
+ \fi
+ }{}
+ %
+ \ifthenelse{\equal{\@HeadFootStyle}{6}}{
+ \if@StyledHeader\else
+ \fancyhead[LE]{%
+ \makebox[2.5em][l]{\@lspagenum\pagenumberstyle}%
+ \@VersoEmblem%
+ }
+ \fancyhead[RO]{%
+ \@RectoEmblem%
+ \makebox[2.5em][r]{\@lspagenum\pagenumberstyle}%
+ }
+ \fancyhead[RE]{\@lshftext\versoheadtext}
+ \fancyhead[LO]{\@lshftext\rectoheadtext}
+ \fi
+ }{}
+ % END MODELS FOR WRITING YOUR OWN.
+ %
+ % END PRE-DEFINED LAYOUTS AND STYLES.
+ % ---------------------------------------------------------------------------
+ %
+ % Now put `fancyhdr' to work:
+ \pagestyle{fancy} % default unless over-ridden by \thispagestyle{}
+ %
+} % end \@ActivateHeadFootStyles
+%
+%%
+
+
+%% Neutralize settings that cannot be used after Preamble:
+\gdef\@DisableHeadFootSettings{% called by `novel.cls' \AtBeginDocument
+ \LetLtxMacro\SetHeadFootStyle\relax
+ \LetLtxMacro\SetHeadStyle\relax
+ \LetLtxMacro\SetHeadJump\relax
+ \LetLtxMacro\SetFootJump\relax
+ \LetLtxMacro\SetLooseHead\relax
+}% end \@DisableHeadFootSettings
+%%
+
+% The following settings can continue to be re-issued after \begin{document}:
+% \SetEmblems also \SetEmblem
+% \SetPageNumberStyle
+% \SetVersoHeadText also \New and \Renew
+% \SetRectoHeadText also \New and \Renew
+
+
+%%
+\endinput
+%%
+%% End of file `novel-HeadFootStyles.sty'
+
+
diff --git a/macros/luatex/latex/novel/novel-Images.sty b/macros/luatex/latex/novel/novel-Images.sty
new file mode 100644
index 0000000000..fc6261e072
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-Images.sty
@@ -0,0 +1,567 @@
+%%
+%% This is file `novel-Images.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-Images.sty}%
+[2018/04/26 v1.52 LaTeX file (image placement)]
+%%
+
+
+%% In `novel', images are handled with a view to preserving uniform line grid.
+%% Normally, a work of fiction has no (or very few) images within the main
+%% body of text. Images are more likely on display pages (such as title page)
+%% or in chapter starts, or maps.
+
+%% There are two ways to place an image: inline, or float.
+%% Inline image does not occupy its own block, but mingles with flowing text.
+%% Float image occupies its own block, which will be placed where the command
+%% is written, if it fits on that page. If it doesn't fit, then it will be
+%% placed at the top of the following page. Surrounding text will be
+%% typeset so at to not leave a big gap. Althouth TeX allows several
+%% options for positioning a float, `novel' only allows one method.
+
+%% Be sure to read the separate documentation about how to prepare images.
+%% In general: (1) png or jpg only. (2) Flattened, no transparency.
+%% (3) 300dpi (grayscale) or 600dpi (black/white) are industry norms.
+%% (4) Image file must contain its resolution. (5) Exact size, without scaling.
+%% (6) No private metadata. (7) Be sure grayscale is 1-channel, not rgb gray.
+
+
+%% Luacode and related macro thanks to user Marcel Krüger,
+%% at tex.stackexchange.com.
+\RequirePackage{luacode}
+\begin{luacode*}
+ function check_colorspaces(allowed_colorspace, name)
+ local doc = epdf.open(name);
+ if doc == nil then
+ tex.sprint(luatexbase.catcodetables['latex-package'],
+ "\\errmessage{Could not open " .. name .. "}{}{}\\@gobbletwo")
+ return;
+ else
+ for pageno=1,doc:getNumPages() do
+ local xobjs= doc:getCatalog():getPage(pageno):getResourceDict():lookup("XObject");
+ if not xobjs:isNull() then
+ for i=1,xobjs:dictGetLength() do
+ xobjDict = xobjs:dictGetVal(i):streamGetDict()
+ if xobjDict:lookup('Subtype'):getName() == 'Image' then
+ if not allowed_colorspace[xobjDict:lookup('ColorSpace'):getName()] then
+ tex.sprint(luatexbase.catcodetables['latex-package'], '\\@firstoftwo')
+ return
+ end
+ end
+ end
+ end
+ end
+ end
+ tex.sprint(luatexbase.catcodetables['latex-package'], '\\@secondoftwo')
+ return;
+end
+\end{luacode*}
+%
+\newcommand\PDFHasDisallowedColorspaceTF[1]{%
+ \directlua{check_colorspaces({DeviceCMYK=true, DeviceGray=true},"\luaescapestring{#1}")}%
+}
+%%
+%%
+\begin{luacode*}
+ function utf16to8(u16str)
+ local result = ""
+ local i = 1
+ if #u16str % 2 == 1 then
+ print("ERROR")
+ return
+ end
+ while i < #u16str do
+ local high, low = u16str:byte(i, i + 1)
+ i = i + 2
+ local current = bit32.replace(low, high, 8, 8)
+ if bit32.band(high, 0xFC) == 0xD8 then
+ current = bit32.replace(0, current, 10, 10)
+ if i > #u16str then
+ print("ERROR")
+ return
+ end
+ high, low = u16str:byte(i, i + 1)
+ i = i + 2
+ current = bit32.replace(current, bit32.replace(low, high, 8, 8), 0, 10) + 0x10000
+ elseif bit32.band(high, 0xFC) == 0xDC then
+ print("ERROR")
+ return
+ end
+ result = result .. unicode.utf8.char(current)
+ end
+ return result
+ end
+ function normalize_string(str)
+ if str:sub(1,2) == "\xFE\xFF" then
+ return utf16to8(str:sub(3,-3))
+ else
+ return str
+ end
+ end
+ function check_pdf_info(name, field, expected)
+ local doc = epdf.open(name);
+ if doc == nil then
+ tex.sprint(luatexbase.catcodetables['latex-package'],
+ "\\errmessage{Could not open " .. name .. "}{}{}\\@gobbletwo")
+ else
+ local producer = doc:getDocInfo():dictLookup(field)
+ if not producer:isNull() and normalize_string(producer:getString()) == expected then
+ tex.sprint(luatexbase.catcodetables['latex-package'], '\\@firstoftwo')
+ else
+ tex.sprint(luatexbase.catcodetables['latex-package'], '\\@secondoftwo')
+ end
+ end
+ end
+\end{luacode*}
+\newcommand\PDFVerifyInfoFieldTF[3]{\directlua{check_pdf_info("\luaescapestring{#1}", "\luaescapestring{#2}", "\luaescapestring{#3}")}}
+%%
+
+
+%% New in version 1.50, makecmyk script, with special syntax:
+\LetLtxMacro\@scriptincludepdf\includepdf\relax
+\providecommand\includepdf[2][]{}
+\renewcommand\includepdf[2][]{% from package `pdfpages'
+ \ClassError{novel}{Cannot use \string\includepdf\space command}%
+ {You can use novel-scripts `makegray' and `makebw' to convert pdf %%J%
+ to a raster jpg or png, suitable for placement as an image.}%
+}
+\gdef\ScriptCoverImage#1{%
+ \if@coverart%
+ \PDFVerifyInfoFieldTF{#1}{NSprocessed}{true}%
+ {\@scriptincludepdf{#1}}%
+ {\ClassError{novel}{Book cover pdf must be pre-processed by novel-scripts}%
+ {Each pdf processed by novel-scripts is marked internally. ^^J%
+ Your cover artwork pdf is unmarked. Use `makecmykpdf' script.}%
+ }%
+ \else%
+ \ClassError{novel}{Cannot use \string\ScriptCoverImage\space in interior}%
+ {\string\ScriptCoverImage\space only with `coverart' class option.}%
+ \fi%
+} %
+%%
+
+
+% Pertains to images:
+\newlength\imagewidth
+\newlength\imageheight
+\newlength\imagehoffset
+\newlength\imagevoffset
+\newlength\@imagewidth
+\newlength\@imageheight
+\newlength\@imagehoffset
+\newlength\@imagevoffset
+\newlength\@mytotalht
+\newif \if@UsingNovelCommand % true within \InlineImage etc.
+%%
+\gdef\imagestarred{false}
+\gdef\imagefilename{unknown}
+\setkeys{Gin}{draft=false} % always shows the image, not a box outline
+\LetLtxMacro\novel@sub@inclgr\includegraphics\relax
+\if@coverart\else % Need to allow it, for possible use by \includepdf in cover.
+ \renewcommand\includegraphics[2][]{%
+ \ClassError{novel}{Direct use of \string\includegraphics\space forbidden}%
+ {You may only place images using commands specific to `novel' class. ^^J%
+ See `novel' documentation, section 7.}%
+ }
+\fi
+%
+\newcommand\@TestImageExtension[1]{%
+ \@tempTFfalse%
+ \IfEndWith{#1}{.png}{\@tempTFtrue}{}%
+ \IfEndWith{#1}{.PNG}{\@tempTFtrue}{}%
+ \IfEndWith{#1}{.jpg}{\@tempTFtrue}{}%
+ \IfEndWith{#1}{.JPG}{\@tempTFtrue}{}%
+ \IfEndWith{#1}{.jpeg}{\@tempTFtrue}{}%
+ \IfEndWith{#1}{.JPEG}{\@tempTFtrue}{}%
+ \if@tempTF\else%
+ \ClassError{novel}{Image format `#1' not allowed, page \thepage}%
+ {Image `#1' has file type not allowed in `novel' class. ^^J%
+ Must have file extension png, jpg, jpeg (or capitalized). ^^J%
+ Others such as pdf, bmp, tiff, eps, svg, jp2, jbig, are not allowed. ^^J%
+ The file extension is mandatory. Provide it, if missing.}%
+ \fi%
+} %
+%%
+
+
+%% INLINE IMAGE
+%% ----------------------------------------------------------------------------
+% \InlineImage[xoffset,yoffset]{imagename.png} or jpg
+% As the name implies, an inline image is used within the flow of text, rather
+% than in its own block. It may be used in main body, header, and footer.
+% Macros such as \imagefilename, \imagewidth, etc.
+% are only set or re-set when the image in in the body. That prevents an
+% intervening header/footer image from over-writing values set by%
+% the most recent body image.
+% Without offsets, the image is positioned with is left edge at the cursor,
+% and its top edge at the text baseline. Positive offsets are right and up.
+% If improperly positioned, the image can overlie (obscure) text that was
+% previously placed. This is rarely desirable and may be flagged by
+% some print services, because it looks wrong.
+% The image will underlie anything that follows. This may be used as a
+% special effect, if allowed by the print service (probably OK).
+% With the un-starred command, the image occupies its natural cursor width.
+% With the starred command, the image occupies zero cursor width, so that
+% anything following will overlie it.
+\DeclareDocumentCommand \InlineImage { s O{0pt} m }{%
+ \@TestImageExtension{#3}%
+ \@tempTFfalse%
+ \if@pdfxSEToff%
+ \@tempTFtrue%
+ \else%
+ \IfSubStr*{\@UnknownImages}{#3}{\@tempTFtrue}{}%
+ \IfSubStr*{\@AllGoodImages}{#3}{\@tempTFtrue}{}%
+ \fi%
+ \if@tempTF\else\@NovelInspectImage{#3}\fi%
+ \StrDel{#2}{\space}[\@myila]%
+ \StrCut{\@myila}{,}{\@myilxa}{\@myilya}%
+ \ifthenelse{\equal{\@myilxa}{} \OR \equal{\@myilxa}{0}}{%
+ \def\@myilx{0pt}}{\def\@myilx{\@myilxa}%
+ }%
+ \ifthenelse{\equal{\@myilya}{} \OR \equal{\@myilya}{0}}{%
+ \def\@myily{0pt}}{\def\@myily{\@myilya}%
+ }%
+ \iftoggle{@inheadfoot}{}{\gdef\imagefilename{#3}}% for possible later use
+ \global\@UsingNovelCommandtrue%
+ \gdef\@mygraphic{\novel@sub@inclgr{#3}}%
+ \gdef\@mygraphicname{#3}%
+ \setlength\@imagewidth{\widthof{\@mygraphic}}%
+ \global\@imagewidth=\@imagewidth%
+ \iftoggle{@inheadfoot}{}{\setlength\imagewidth{\@imagewidth}}%
+ \setlength\@imageheight{\heightof{\@mygraphic}}%
+ \global\@imageheight=\@imageheight%
+ \iftoggle{@inheadfoot}{}{%
+ \setlength\imageheight{\@imageheight}%
+ \global\imageheight=\imageheight%
+ }%
+ %
+ \setlength\@imagehoffset{\@myilx}%
+ \IfBeginWith{\@myily}{b}{%
+ \StrDel[1]{\@myily}{b}[\temp@adjVoffseta]%
+ \ifthenelse{\equal{\temp@adjVoffseta}{} \OR \equal{\temp@adjVoffseta}{0}}{%
+ \def\temp@adjVoffset{0pt}}{\def\temp@adjVoffset{\temp@adjVoffseta}%
+ }%
+ \setlength\@imagevoffset{\temp@adjVoffset}%
+ }{%
+ \setlength\@imagevoffset{-\@imageheight}%
+ \addtolength\@imagevoffset{\@myily}%
+ }%
+ %
+ \IfBooleanTF{#1}%
+ % starred:
+ {%
+ \iftoggle{@inheadfoot}{}{\gdef\imagestarred{true}}%
+ \makebox[0pt][l]{%
+ \hspace{\@imagehoffset}%
+ \stake\smash{\raisebox{\@imagevoffset}{\@mygraphic}}%
+ }%
+ }%
+ % unstarred:
+ {%
+ \iftoggle{@inheadfoot}{}{\gdef\imagestarred{false}}%
+ \hspace{\@imagehoffset}%
+ \stake\smash{\raisebox{\@imagevoffset}{\@mygraphic}}%
+ }% end IfBooleanTF{#1}
+ \iftoggle{@inheadfoot}{}{\setlength\imagehoffset{\@imagehoffset}}%
+ \iftoggle{@inheadfoot}{}{\setlength\imagevoffset{\@imagevoffset}}%
+ \global\@UsingNovelCommandfalse%
+} %
+% end Inline Image
+%%
+
+
+%% FLOAT IMAGE
+%% ----------------------------------------------------------------------------
+%% New in v.1.50. \FloatImage. Centered unless offset.
+% \FloatImage[floatmethod,xoffset,yoffset]{yourimagename.png} % or jpg
+% This is a substitute for other floats. Does not require `float' package.
+% Default: [ht,0pt,\nfs].
+% Method ht attempts to place the image where the code is written. But if it
+% doesn't fit on that page, it will float to the top of the next page.
+% Method b attempts to place the image on the bottom of the page where the
+% code is written. If not, it floats to the bottom of the next page.
+% Allowed float methods: ht hb t b. Equivalent to LaTeX floats with !.
+% Parsing the optional argument: comma-separated values, ignoring space.
+% May be empty before or between commas.
+% Example: [,,2em] is read as default method, xoffset 0pt, yoffset 2em.
+% Example: [b] is valid, because a single value is read as method.
+\providecommand*\floatlocation[2]{\@namedef{fps@#1}{#2}}
+\floatlocation{figure}{!ht} % default
+\gdef\ftype@figure{1} % mystery TeX code
+\DeclareDocumentCommand \FloatImage { s O{ht} m } {% starred not in use
+ \iftoggle{@inheadfoot}{%
+ \ClassError{novel}{Cannot use \string\FloatImage\space in header/footer}%
+ {Header footer allow \string\InlineImage, but not \string\FloatImage.}%
+ }{}%
+ \@TestImageExtension{#3}%
+ \@tempTFfalse%
+ \if@pdfxSEToff%
+ \@tempTFtrue%
+ \else%
+ \IfSubStr*{\@UnknownImages}{#3}{\@tempTFtrue}{}%
+ \IfSubStr*{\@AllGoodImages}{#3}{\@tempTFtrue}{}%
+ \fi%
+ \if@tempTF\else\@NovelInspectImage{#3}\fi%
+ % Sadly, parsing with `xstring' involves roundabout code:
+ \StrDel{#2}{\space}[\@tempArgs]%
+ \StrCut{\@tempArgs}{,}{\@tempArgA}{\@tempArgX}%
+ \StrCut{\@tempArgX}{,}{\@tempArgB}{\@tempArgC}%
+ \ifthenelse{\equal{\@tempArgA}{}}{%
+ \def\@tempArgAa{ht}%
+ }{%
+ \def\@tempArgAa{\@tempArgA}%
+ }%
+ \ifthenelse{\equal{\@tempArgB}{0}\OR\equal{\@tempArgB}{}}{%
+ \def\@tempArgBb{0pt}%
+ }{%
+ \def\@tempArgBb{\@tempArgB}%
+ }%
+ \ifthenelse{\equal{\@tempArgC}{0}\OR\equal{\@tempArgC}{}}{%
+ \def\@tempArgCc{0pt}%
+ }{%
+ \def\@tempArgCc{\@tempArgC}%
+ }%
+ \StrDel{\@tempArgAa}{!}[\@tempArgAa]%
+ \@tempTFfalse%
+ \ifthenelse{\equal{\@tempArgAa}{ht}}{\@tempTFtrue}{}%
+ \ifthenelse{\equal{\@tempArgAa}{hb}}{\@tempTFtrue}{}%
+ \ifthenelse{\equal{\@tempArgAa}{t}}{\@tempTFtrue}{}%
+ \ifthenelse{\equal{\@tempArgAa}{b}}{\@tempTFtrue}{}%
+ \if@tempTF\else%
+ \ClassWarning{novel}{Incorrect position for \string\FloatImage, ^^J%
+ page \thepage. Default position ht substituted.}%
+ \fi%
+ \floatlocation{figure}{!\@tempArgAa}% enable current float method
+ %\vfil% One l.
+ \@float{figure}%
+ \@FloatImage{\@tempArgBb}{\@tempArgCc}{#3}%
+ \end@float\par%
+ \floatlocation{figure}{!ht}% restore default float method
+ \null%
+ \vspace{0.01pt plus 0pt minus 0.02pt} % caulk
+} %
+%
+
+%% Environment @floatimagegap. Only used by \@FloatImage command.
+% Creates a gap at fixed height, regardless of content.
+% Needs to compensate for prior line depth.
+\newcounter{@gaplines} % passes the argument down to environment end
+\DeclareDocumentEnvironment {@floatimagegap} { m } {%
+ \par%
+ \null%
+ \vspace*{-\nbs}%
+ \begin{textblock*}{\textwidth}[0,0](0pt,0pt)%
+ \setcounter{@gaplines}{#1}%
+ \strut\par%
+ \vspace*{-\nbs}%
+}{% close the environment:
+ \end{textblock*}%
+ \par%
+ \vspace*{#1\nbs}%
+} %
+%%
+\DeclareDocumentCommand \@FloatImage { m m m }{% DO NOT CALL DIRECTLY
+ \global\@UsingNovelCommandtrue%
+ \gdef\@mygraphic{\novel@sub@inclgr[scale=\@TMratio]{#3}}%
+ \gdef\@mygraphicname{#3}%
+ \gsetlength\@imagewidth{\widthof{\@mygraphic}}%
+ \gsetlength\@imageheight{\heightof{\@mygraphic}}%
+ \setlength\@imagehoffset{#1}%
+ \setlength\@imagevoffset{#2-\@imageheight+\normalXheight}%
+ \setlength\@mytotalht{\@imageheight+0.3\nbs}%
+ \FPdiv{\@mytotalhtN}{\strip@pt\@mytotalht}{\strip@pt\nbs}%
+ \FPadd{\@mytotalhtN}{\@mytotalhtN}{0.5}% round upward
+ \FPround{\@mytotalhtN}{\@mytotalhtN}{0}% to integer
+ \FPmin{\@allowmyoverflow}{\@mytotalhtN}{\@LinesPerPage}% not exceeding lpp
+ % If a full-page image is too tall for a page, standard TeX float will
+ % delay it until the time that floats are cleared, typically by \clearpage.
+ % That would probably be at the end of a chapter.
+ % In `novel' this behavior is hacked. Regardless of the image's actual
+ % height, it is treated as if its height does not exceed whatever will
+ % fit on a single page. Then, a full-page float will appear at the first
+ % opportunity, rather than being delayed. As a consquence, an oversized
+ % full-page float may overflow into the footer or bottom margin.
+ % To fix that (if it matters), you need to edit the image in graphics.
+ \begin{@floatimagegap}{\@allowmyoverflow}%
+ \vspace*{-\nfs}%
+ \null%
+ {\centering%
+ \makebox[0pt][l]{%
+ \hspace{\dimexpr\@imagehoffset-0.5\@imagewidth}%
+ \stake\smash{\raisebox{\@imagevoffset}{\@mygraphic}}%
+ }%
+ \par%
+ }%
+ \end{@floatimagegap}%
+ \global\@UsingNovelCommandfalse%
+} %
+% end Float Image
+%%
+
+
+%% WRAP IMAGE
+%% New in v. 1.50. Wraps text around an image, with limited float support.
+% This is a shim to `wrapfig' package. Since `novel' uses its own method for
+% placing images, environments defined in `wrapfig' cannot be used directly.
+% \WrapImage[position]{image} % default position r
+% Optional position is same as with `wrapfig':
+% l r o i places image "exactly here", left, right, outside, inside.
+% L R O I allows image to float.
+% Since novel's \InlineImage normally can be over-written by following text,
+% it needs an accompanying \rule to act as a strut.
+%
+\RequirePackage{wrapfig}
+%
+\DeclareDocumentCommand\WrapImage { O{r} m } {%
+ \begin{wrapfloat}{figure}{#1}{0pt}%
+ \InlineImage[0pt,\normalXheight]{#2}%
+ \rule[\dimexpr\normalXheight-\imageheight]{0pt}%
+ {\dimexpr\imageheight-\normalXheight+0.3\nfs}%
+ \end{wrapfloat}%
+}%
+\LetLtxMacro\wrapimage\WrapImage\relax
+% end Wrap Image.
+%%
+
+
+%% New in version 1.52: read file bytes as plain text, for later parsing.
+% Output is comma-separated list of byte codes, decimal 0-255.
+% Returns -1 if requested start is more than file size.
+% Returns all bytes if requested number exceeds file size.
+% Does not test if file exists; error if not found.
+\DeclareDocumentCommand\novelgetbytes { m m m } {%
+ % filename, start byte number (0=beginning, e=up to end), number of bytes
+ \ifthenelse{\equal{#2}{e}}{% package xifthen
+ \long\edef\novelbytesare{%
+ \directlua{
+ inp = assert(io.open("#1", "rb"))
+ local e=inp:seek("end")
+ if #3>e+1 then
+ inp:seek("set")
+ local r=inp:read(e)
+ sep=""
+ for i,_ in string.bytes(r)
+ do
+ tex.sprint(sep)
+ sep=","
+ tex.sprint(i)
+ end
+ else
+ local b=e-2-math.min(e,#3)
+ local w=1+math.min(e,#3)
+ inp:seek("set",b)
+ local r=inp:read(w)
+ sep=""
+ for i,_ in string.bytes(r)
+ do
+ tex.sprint(sep)
+ sep=","
+ tex.sprint(i)
+ end
+ end
+ }%
+ }%
+ }{%
+ \long\edef\novelbytesare{%
+ \directlua{
+ inp = assert(io.open("#1", "rb"))
+ local e=inp:seek("end")
+ if #2>e then tex.sprint(-1) else
+ local w=math.min(#3,e-#2)
+ inp:seek("set",#2)
+ local r=inp:read(w)
+ sep=""
+ for i,_ in string.bytes(r)
+ do
+ tex.sprint(sep)
+ sep=","
+ tex.sprint(i)
+ end
+ end
+ }%
+ }%
+ }%
+} % end @novelgetbytes
+
+%%
+% png bit depth is 8 for ordinary color or gray, 1 for b/w monochrome.
+% Although png allows more than 8, `novel' does not.
+\def\novelpngbitdepth#1{\novelgetbytes{#1}{24}{1}\novelbytesare}
+% png color type: 0=grayscale (incl. b/w).
+% `novel' only permits colortype 0 for non-color book interiors.
+% other: 2=rgb, 3=indexed rgb, 4=gray alpha, 6=rgb alpha.
+\def\novelpngcolortype#1{\novelgetbytes{#1}{25}{1}\novelbytesare}
+%%
+
+%%
+% Examine png or jpg image for novel-make as comment:
+% Known-good images, will not be inspected. Comma-separated list:
+\newcommand\SetKnownGoodImages[1]{
+ \gdef\@KnownGoodImages{#1}
+}
+\SetKnownGoodImages{} % default empty
+\gdef\@AllGoodImages{}
+\gdef\@UnknownImages{}
+%
+\gdef\@GatherGoodImages{% called \AtBeginDocument by `novel.cls'.
+ \let\SetKnownGoodImages\relax
+ \xdef\@AllGoodImages{\@KnownGoodImages\space \@AllGoodImages}
+ \if@pdfxSEToff
+ \xdef\@AllGoodImages{\@KnownGoodImages}
+ \xdef\@UnknownImages{}
+ \fi
+}
+% This is the (decimal) code string:
+\gdef\@novelmake{110,111,118,101,108,109,97,107,101}
+%
+\newcommand\@NovelInspectImage[1]{%
+ \StrRight{#1}{3}[\tempEXT]%
+ \ifthenelse{\equal{\tempEXT}{png} \OR \equal{\tempEXT}{PNG}}{%
+ \novelgetbytes{#1}{e}{256}%
+ }{% jpg or JPG:
+ \novelgetbytes{#1}{0}{256}%
+ }%
+ \IfSubStr{\novelbytesare}{\@novelmake}{%
+ \xdef\@AllGoodImages{\@AllGoodImages\space #1}%
+ }{%
+ \xdef\@UnknownImages{\@UnknownImages\space #1}%
+ }%
+}
+%%
+
+
+%% Called \AfterEndDocument by `novel.cls`:
+\long\gdef\@WarnUnknownImages{%
+ \@tempTFfalse%
+ \ifthenelse{\equal{\@UnknownImages}{}}{}{\@tempTFtrue}%
+ \if@pdfxSEToff\@tempTFfalse\fi%
+ \if@tempTF%
+ \typeout{^^JClass `novel' Alert: Some images not processed by scripts.^^J%
+ \space List of unprocessed images: \@UnknownImages ^^J%
+ \space Above list does not include any `known good' set by you. ^^J^^J}%
+ \ClassWarning{novel}{\@testintentional %
+ Some images may not meet PDF/X specifications. ^^J%
+ See near end of log file for `Some images not processed by scripts`. ^^J}%
+ \fi%
+}
+%%
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-Images.sty'.
+
+
diff --git a/macros/luatex/latex/novel/novel-JC200103.clo b/macros/luatex/latex/novel/novel-JC200103.clo
new file mode 100644
index 0000000000..578f883adb
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-JC200103.clo
@@ -0,0 +1,27 @@
+%%
+%% This is file `novel-JC200103.clo', part of `novel' document class.
+%% The values of the arguments are public industry standards.
+\ProvidesFile{novel-JC200103.clo}%
+[2018/01/14 any version. (novel Output Intent JC200103)]
+%%
+
+
+% Typically used in Japan.
+
+% Remember: TeX special characters must be backslashed here.
+% You may see % or # or _ in the data or file names.
+% Be sure that they are written as \% \# \_ or there will be trouble.
+
+% If any line is long, let it wrap. Do not attempt to break it onto multiple lines.
+
+\gdef\@OIidentifier{JC200103} % also called "reference name"
+\gdef\@OIcondition{Japan Color 2001 Coated: Printing process definition: ISO 12647-2:2004, sheet-fed offset printing, positive plates, paper type 3 (coated, 105 gsm), screen frequency 69/cm.}
+\gdef\@OIinfo{Japan Color 2001 Coated}
+\gdef\@OIregistry{http://www.color.org}
+\gdef\@OIprofile{JapanColor2001Coated.icc}
+
+%%
+\endinput
+%%
+%% end of file `novel-JC200103.clo'
+
diff --git a/macros/luatex/latex/novel/novel-LayoutSettings.sty b/macros/luatex/latex/novel/novel-LayoutSettings.sty
new file mode 100644
index 0000000000..690a4b03e6
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-LayoutSettings.sty
@@ -0,0 +1,435 @@
+%%
+%% This is file `novel-LayoutSettings.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-LayoutSettings.sty}%
+[2018/04/26 v1.52 LaTeX file (layout settings)]
+%%
+
+
+%% Note that nearly all layout settings are pre-configured based on Trim Size.
+%% In general, these user commands may be used to over-ride the presets.
+
+
+
+%% SIZE-RELATED COMMANDS AVAILABLE IN PREAMBLE.
+%% ----------------------------------------------------------------------------
+%% Use if necessary for customization.
+%% If you like a class option that pre-sets these values,
+%% then you do not have to use any of these commands.
+%
+% Note: This class does not ask you to set the width/height of the textblock.
+% Instead, these values are automatically calculated from other dimensions.
+
+
+%% Trim Size is the finished width and height of the book (not thickness).
+% Books are (usually) manufactured to a small number of standard Trim Sizes.
+% The available choice of sizes will depend on your print service,
+% and may by limited by binding method, paper, or distribution channels.
+% These are NOT the usual TeX "paper size" choices, such as A4 or letterpaper.
+% In the U.S.A., 5.5in W x 8.5in H is very common for softcover fiction,
+% so it will (later) be set as default, unless you set your own.
+\newif \if@SetTrimSize % true if \SetTrimSize rather than defaults.
+\newlength\@TrimWidth
+\newlength\@TrimHeight
+\newcommand\SetTrimSize[2]{% width, height
+ \global\@SetTrimSizetrue
+ \gsetlength\@TrimWidth{#1}
+ \gsetlength\@TrimHeight{#2}
+}% end set trimsize
+%%
+
+
+%% Margins are measured from Trim Size inwards, always positive.
+% If the Media Size is larger than Trim Size, then the area beyond
+% the Trim Size is NOT margins. It is discarded scrap paper.
+% However, word processors (in general) do not understand the difference
+% between Trim Size and Media Size. So, if you are ever asked to
+% lay out the book in a word processor, using a standard (A4 or letter)
+% physical paper size, then you will be asked to set the "margins"
+% very wide, because the word processor margins include both
+% the finished book margins, and the discarded scrap paper.
+% In certain circumstances, text or images may intrude into the margin area.
+% This is not always an error, because it may be intentional.
+% Margins at top and bottom are relative to:
+% top of header, or top of textblock if no header;
+% bottom of footer, or bottom of textblock if no footer.
+% Inner margin generally greater than Outer, due to gutter.
+% Standard margins command ("TOBI, or not TOBI, that is the question."):
+\newif \if@SetMargins % true if \SetMargins rather than defaults.
+\newlength\@TopMargin
+\newlength\@OuterMargin
+\newlength\@BottomMargin
+\newlength\@InnerMargin
+\newcommand\SetMargins[4]{ % top, outer, bottom, inner
+ \global\@SetMarginstrue
+ \gsetlength\@TopMargin{#1}
+ \gsetlength\@OuterMargin{#2}
+ \gsetlength\@BottomMargin{#3}
+ \gsetlength\@InnerMargin{#4}
+}% end set margins
+\LetLtxMacro\SetMargin{\SetMargins}\relax % for those who mis-type
+%%
+
+
+%% New in version 1.50: Unsafe Zone (opposite of "safe area").
+% This feature only applies with class options `draft,shademargins'
+% and does NOT apply in `coverart'.
+% The purpose of margins is to confine the main text (and header/footer).
+% In `novel' (unlike most other TeX document classes) there is no provision
+% for marginal notes, because they are not used in popular fiction.
+% Yet there may be circumstances where you intentionally or accidentally
+% have text, or part of an image, placed or overflowing into a margin.
+% In PDF, even PDF/X, that is not a problem. It cannot read your mind.
+% However, every print service specifies a "safe area." All text, and
+% all images without bleed, must remain within the safe area.
+% The limits of the safe area are typically 0.125in to 0.5in inside the
+% Trim Size, depending on technology. This defines how close you may
+% place anything near the page edges.
+% In `novel' the opposite of the safe area is the "unsafe zone" (UZ).
+% So, the UZ lies just inside the perimeter of the Trim Size.
+% Each margin is at least as wide as its corresponding UZ.
+% Some print services use "minimum margin" to mean the UZ.
+% When you are in draft mode with `shademargins' class option,
+% the UZ (if it is set) will be displayed in dark gray.
+% Then, you can inspect the PDF for any intrusion into the UZ.
+% If you intrude into the UZ, there is no warning or error.
+% The UZ is strictly for visualization. There is no default setting.
+% If you do not set the UZ yourself, then no UZ will be displayed.
+% In any case, the final PDF is unaffected.
+\newif \if@UnsafeZone % true if \SetUnsafeZone used
+\newlength\@TopUZWidth
+\newlength\@OuterUZWidth
+\newlength\@BottomUZWidth
+\newlength\@InnerUZWidth
+\newcommand\SetUnsafeZone[4]{% top, outer, bottom, inner.
+ \global\@UnsafeZonetrue
+ \gsetlength\@TopUZWidth{#1}
+ \gsetlength\@OuterUZWidth{#2}
+ \gsetlength\@BottomUZWidth{#3}
+ \gsetlength\@InnerUZWidth{#4}
+} % end \SetUnsafeZone
+\LetLtxMacro\SetUnsafeZones{\SetUnsafeZone}\relax % for those who mis-type
+%%
+
+
+% PDF Media Size is already known to TeX as \paperwidth and \paperheight.
+% For this reason, there is no need to define additional lengths.
+% Sheet-fed printers use a small number of standard paper sizes.
+% Whether you use P.O.D. or print at home or office, your print job will
+% almost certainly be sheet-fed. After printing, the sheet is trimmed
+% to the specified Trim Size. Note that the sheet sizes used in
+% commercial printing are specialized for the purpose, and may be
+% different from the routine A4 and USletter sizes familiar to you.
+% In most cases (except for cover artwork), your PDF Media Size will be
+% exactly the same as the finished Trim Size. Placement of the Trim Size
+% onto a larger sheet of paper is done automatically at the print service,
+% a procedure known as "imposition." Several small Trim Sizes may be
+% printed onto a single sheet, in order to waste less paper in trimming.
+% In a few cases, the print service will ask you to provide a PDF that has
+% the Trim Size centered H/V within a larger Media Size.
+% Sometimes (especially for cover artwork), that's because you are
+% doing the imposition yourself. In other cases (especially for interiors)
+% it is because most of the files seen at the print service came from
+% word processors, where the writers (not knowing better) created layouts
+% on A4 or USletter with large "margins," rather than correct Trim Size.
+% Then, if you submit a file at actual Trim Size, it looks wrong,
+% not because it is wrong, but because it stands out from the crowd.
+% You may use \SetMediaSize to deal with this situation.
+% You do not need \SetMediaSize, if (as usual) it is identical to TrimSize.
+% Changing the Media Size does not affect Trim Size or internal page layout.
+% Class options `cropview' and `closecrop' (only in draft mode)
+% affect Media Size. See their descriptions below.
+%
+% \SetMediaSize[<obsolete option>]{width}{height} usage:
+% The optional argument is obsolete. Anything there will be ignored.
+\newif \if@MediaSize % true if \SetMediaSize rather than default = Trim Size.
+\DeclareDocumentCommand\SetMediaSize { O{} m m } {% width, height
+ \@MediaSizetrue
+ \gsetlength\paperwidth{#2}
+ \gsetlength\paperheight{#3}
+}% end \SetMediaSize
+%%
+
+
+%% Lines Per Page refers to the main textblock, not including header or footer.
+% If you do not set it, a suitable default will be based on other settings.
+% The number of lines is contrained by Trim Height, Margins, and normal em.
+% This is because the minimum \baselineskip must be 1.2x normal em size,
+% to avoid crowding of the text and variable line heights.
+% The check for constraint is done in file novel-CalculateLayout.sty.
+% The same check also verifies that the number is an integer >=10.
+\newif \if@LinesPerPage % true if \SetLinesPerPage rather than default.
+\newcommand\SetLinesPerPage[1]{
+ \IfInteger{#1}{}{%
+ \ClassError{novel}{\string\SetLinesPerPage\space must be integer >=10}%
+ {Do not write period, comma, or space within \string\SetLinesPerPage.}%
+ }
+ \FPiflt{#1}{10}
+ \ClassError{novel}{\string\SetLinesPerPage\ must be at least 10}%
+ {LinesPerPage were set or calculated at less than 10.}%
+ \fi
+ \global\@LinesPerPagetrue
+ \gdef\@LinesPerPage{#1}
+}% end set linesperpage
+%%
+
+
+%% \SetFontSize may be in any units, even decimals: 12.2pt, 11.5bp, etc.
+% Before external packages load, the font size is temporarily set to
+% 10pt at 13pt skip, so that moldy-oldie packages don't get confused.
+% Later, the size is changed to its actual value based on this command,
+% or on the defaults for Trim Size.
+\newif \if@FontSizeSet % true if \SetFontSize rather than default.
+\newlength\@SetFontSize
+\newcommand\SetFontSize[1]{
+ \global\@FontSizeSettrue
+ \gsetlength\@SetFontSize{#1}
+}% end set font size
+%%
+
+
+%% MISCELLANOUS SETTINGS. Mostly remove "glue". Best to leave as-is.
+%% ----------------------------------------------------------------------------
+% Standard TeX \hoffset and \voffset is not relative to the MediaBox, but is
+% relative to 1in from the top left corner of the MediaBox. Ouch.
+% When necessary, the 1in (72.27pt) is compensated in later calculations.
+\setlength\hoffset{0pt} % relative to 1in built-in offset at left
+\setlength\voffset{0pt} % relative to 1in built-in offset at top
+%
+\@twocolumnfalse
+\@twosidetrue
+\setlength\columnsep{12pt} % not needed, picked something at random
+\setlength\columnseprule{0pt}
+%
+\@mparswitchtrue % irrelevant
+\setlength\marginparwidth{0pt} % no marginal paragraphs allowed
+\setlength\marginparsep{0pt}
+\setlength\marginparpush{0pt}
+%
+\global\@topnum \z@
+\setlength\abovedisplayskip{0pt}
+\setlength\abovedisplayshortskip{0pt}
+\setlength\belowdisplayshortskip{0pt}
+\setlength\belowdisplayskip{0pt}
+\setlength\smallskipamount{0pt}
+\setlength\medskipamount{0pt}
+\setlength\bigskipamount{0pt}
+% `novel' uses grid setting. However, to allow for roundoff errors in
+% vertical position calculations, there is a tiny amount of wiggle room:
+\setlength\topsep{0pt}
+\setlength\partopsep{0pt}
+\setlength\parsep{0pt}
+\setlength\parskip{0pt}
+\setlength\floatsep{0pt}
+\setlength\textfloatsep{0pt}
+\setlength\dbltextfloatsep{0pt}
+\setlength\intextsep{0pt}
+% \topskip will be set as normal baselineskip, which must first be calculated.
+% That is done in novel-CalculateLayout.sty.
+\setlength\lineskip{0pt}
+\setlength\normallineskip{0pt}
+\setlength\lineskiplimit{-2pt} % allows some limited vertical clash
+\renewcommand\baselinestretch{1} % multiplier
+\widowpenalty 150 % same as TeX default
+\clubpenalty 150 % same as TeX default
+\@lowpenalty 51
+\@medpenalty 151
+\@highpenalty 301
+% Floats are limited, but just in case:
+\setcounter{topnumber}{2}
+\renewcommand\topfraction{.7}
+\setcounter{bottomnumber}{1}
+\renewcommand\bottomfraction{.3}
+\setcounter{totalnumber}{3}
+\renewcommand\textfraction{.2}
+\renewcommand\floatpagefraction{.5}
+\setcounter{dbltopnumber}{2}
+\renewcommand\dbltopfraction{.7}
+\renewcommand\dblfloatpagefraction{.5}
+%
+\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\normalfont\rmfamily}
+\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\normalfont\sffamily}
+\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\normalfont\ttfamily}
+\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\normalfont\bfseries}
+\DeclareOldFontCommand{\it}{\normalfont\itshape}{\normalfont\itshape}
+\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\normalfont\slshape}
+\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\normalfont\scshape}
+%
+\pagestyle{empty} % will be over-ridden by fancyhead in separate file
+\pagenumbering{arabic} % may be over-ridden in document
+\flushbottom % best for continuous text
+%
+%% End miscellaneous settings.
+
+
+
+%% FRONTMATTER, MAINMATTER. BUT NO BACKMATTER!
+%% ----------------------------------------------------------------------------
+%
+% See novel.cls for the AtBeginShipout routine.
+%
+% These do not have @ in name, so that they can be used in document body:
+\newif \ifWithinFrontmatter % true within frontmatter
+\newif \ifWithinMainmatter % true within mainmatter
+\def\frontmatter{ % starts page count and frontmatter count at 1.
+ \ifWithinFrontmatter
+ \ClassError{novel}{\string\frontmatter\ used more than once}%
+ {You issued \string\frontmatter\ more than once.}%
+ \fi
+ \ifWithinMainmatter
+ \ClassError{novel}{\string\frontmatter\ cannot follow \mainmatter}%
+ {In order: \string\frontmatter\ \string\mainmatter ^^J%
+ but you do not need both of them.}%
+ \fi
+ \global\WithinFrontmattertrue\global\WithinMainmatterfalse
+ \clearpage
+ \pagenumbering{roman}
+ \setcounter{page}{1}
+}
+%
+\def\mainmatter{ % restarts page to 1, arabic numbers; freeze frontpagecount
+ \ifWithinMainmatter
+ \ClassError{novel}{\string\mainmatter\ used more than once}%
+ {You issued \string\mainmatter\ more than once.}%
+ \fi
+ \cleartorecto % added v. 1.40.1
+ \global\WithinFrontmatterfalse\global\WithinMainmattertrue
+ \pagenumbering{arabic}
+ \setcounter{page}{1}
+}
+%
+\def\backmatter{\@ifstar\@backmatterst\@backmatterns} % asterisk obsolete
+\def\@backmatterst{%
+ \ClassWarning{novel}{^^J\string\backmatter*\ ignored. Do not use. ^^J}%
+}
+%
+\def\@backmatterns{%
+ \cleartorecto% v. 1.40.2
+ \typeout{^^JClass `novel' Alert: \string\backmatter\space merely %
+ clears to recto. See docs. ^^J}% v. 1.42
+%
+}
+%
+\def\Backmatter{\@ifstar\@Backmatterst\@Backmatterns} % obsolete
+%
+\def\@Backmatterst{% continues frontmatter count w/ uppercase Roman numerals
+ \ClassWarning{novel}{^^J\string\Backmatter*\ ignored. Do not use. ^^J}%
+}
+%
+\def\@Backmatterns{%
+ \ClassWarning{novel}{^^J\string\Backmatter\ ignored. Do not use. ^^J}%
+}
+%
+%% end frontmatter, mainmatter. No backmatter!
+
+
+%% DISABLE OR NEUTRALIZE SOME STANDARD LATEX COMMANDS
+%% ----------------------------------------------------------------------------
+% The `novel' class disallows these commands, or neutralizes them by simply
+% repeating their arguments. In some cases, they request functionality that's
+% not implemented in `novel'. In other cases, functionality is part of core,
+% but would interfere with the `novel' emphasis on constant line skip.
+% You may redefine the commands using your own Preamble code (discouraged).
+%
+%%%%%\gdef\null{\hbox{\strut}} % May be important!
+%
+% Standard LaTeX font sizes are ineffective:
+\gdef\@noSizeCommand#1{\ClassWarning{novel}{%
+ Standard LaTeX font sizes are ineffective in `novel' class. ^^J%
+ Your use of command `#1' was ignored. ^^J}%
+}
+\gdef\@DisableFontSizes{% called by `novel.cls' \AtBeginDocument
+ \gdef\HUGE{\@noSizeCommand{HUGE}}
+ \gdef\Huge{\@noSizeCommand{Huge}}
+ \gdef\huge{\@noSizeCommand{huge}}
+ \gdef\LARGE{\@noSizeCommand{LARGE}}
+ \gdef\Large{\@noSizeCommand{Large}}
+ \gdef\large{\@noSizeCommand{large}}
+ \gdef\small{\@noSizeCommand{small}}
+ \gdef\footnotesize{\@noSizeCommand{footnotesize}}
+ \gdef\scriptsize{\@noSizeCommand{scriptsize}}
+ \gdef\tiny{\@noSizeCommand{tiny}}
+} %
+% In `novel' there is no academic organization.
+% All these do is echo the argument, if any:
+\long\gdef\part#1{#1}
+\long\gdef\chapter#1{#1}
+\long\gdef\section#1{#1}
+\long\gdef\subsection#1{#1}
+\long\gdef\subsubsection#1{#1}
+\long\gdef\paragraph#1{#1}
+\long\gdef\subparagraph#1{#1}
+\long\gdef\appendix#1{#1}
+% In some situations, the use will be interrupted:
+\DeclareDocumentCommand\@nodocommand { O{} +m } {%
+ \ClassError{novel}{No command or environment `#1' in this class}%
+ {Many academic layout commands or environments are disabled in `novel'.}%
+}
+\DeclareDocumentCommand\@sandboxonly { m } {%
+ \ClassError{novel}{ ^^J%
+ Command or environment `#1' only allowed in `sandbox' mode. ^^J%
+ See `novel' documentation 2.2. ^^J
+ The offending command may have been called by another macro.}%
+ {Fix your code. If you do not, then compile will fail or be unexpected.}%
+}
+% Here is the interruption list:
+\long\gdef\maketitle{\@nodocommand{maketitle}}
+\long\gdef\makeindex{\@nodocommand{makeindex}}
+\long\gdef\tableofcontents{\@nodocommand{tableofcontents}}
+\long\gdef\listoftables{\@nodocommand{listoftables}}
+\long\gdef\listoffigures{\@nodocommand{listoffigures}}
+\long\gdef\thebibliography{\@nodocommand{thebibliography}}
+\long\gdef\theindex{\@nodocommand{theindex}}
+\long\gdef\abstract{\@nodocommand{abstract}}
+\if@sandbox\else
+ \DeclareDocumentCommand\caption{}{\@sandboxonly{caption}}
+ \DeclareDocumentEnvironment{tabular}{s o +m}{\@sandboxonly{tabular}}{}
+ \DeclareDocumentEnvironment{table}{s o}{\@sandboxonly{table}}{}
+ \DeclareDocumentEnvironment{figure}{s o}{\@sandboxonly{figure}}{}
+ \DeclareDocumentEnvironment{itemize}{s}{\@sandboxonly{itemize}}{}
+ \DeclareDocumentEnvironment{enumerate}{s}{\@sandboxonly{enumerate}}{}
+ \DeclareDocumentEnvironment{description}{s}{\@sandboxonly{description}}{}
+ \DeclareDocumentEnvironment{labeling}{s}{\@sandboxonly{labeling}}{}
+\fi
+%
+\newif \if@OnTitlePage % not really useful
+\DeclareDocumentEnvironment{titlepage}{s}{%
+ \clearpage
+ \thispagestyle{empty}
+ \global\@OnTitlePagetrue
+}{
+ \clearpage
+ \global\@OnTitlePagefalse
+}
+%% end disable or neutralize.
+
+
+%% Neutralize settings commands:
+\gdef\@DisableLayoutSettings{% called by `novel.cls' \AtBeginDocument
+ \LetLtxMacro\SetMediaSize\relax
+ \LetLtxMacro\SetTrimSize\relax
+ \LetLtxMacro\SetMargins\relax
+ \LetLtxMacro\SetLinesPerPage\relax
+ \LetLtxMacro\SetFontSize\relax
+ \LetLtxMacro\SetUnsafeZone\relax
+}% end \@DisableLayoutSettings
+%%
+
+
+%%
+\endinput
+%%
+%% End of file `novel-LayoutSettings.sty'.
+
+
diff --git a/macros/luatex/latex/novel/novel-Obsolete.sty b/macros/luatex/latex/novel/novel-Obsolete.sty
new file mode 100644
index 0000000000..305fc7b7c7
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-Obsolete.sty
@@ -0,0 +1,485 @@
+%%
+%% This is file `novel-Obsolete.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-Obsolete.sty}%
+[2018/04/26 v1.52 LaTeX file (obsolete macros)]
+%%
+
+
+%% OBSOLETE MACROS !!!
+%%
+%% Prior to version 1.50, `novel' contained some macros or features that
+%% worked but were hard to maintain, or worked in a fashion that was
+%% user-unfriendly, or was not as good as some better code.
+%% These macros have been gathered here. DO NOT USE THEM IN NEW DOCUMENTS.
+%% They have only been retained for backwards-compatibility.
+%% If you find a bug -- too bad! Anything here is "won't fix."
+%%
+
+
+%% OBSOLETE
+\gdef\SetCropmarkGap#1{} % simply ignored
+%%
+
+
+%% OBSOLETE
+\newcommand\pushtextdown[1]{% OBSOLETE
+ \ifthenelse{\equal{#1}{} \OR \equal{#1}{ } \OR \equal{#1}{0}}{%
+ \def\@howmuchdown{0em}%
+ }{%
+ \def\@howmuchdown{#1}%
+ }%
+ ~\par\vspace*{-\nbs}\vspace*{\@howmuchdown}\par%
+}
+%%
+
+
+%% OBSOLETE
+%% \squeeze{} and \crush{} slightly shrink the horizonal dimension of the
+% enclosed text. May span paragraphs. Emergency only! No compounding.
+\long\gdef\squeeze#1{{\addfontfeature{FakeStretch=0.99}#1}}
+\long\gdef\crush#1{{\addfontfeature{FakeStretch=0.98}#1}}
+%%
+
+
+%% OBSOLETE
+\gdef\specialblankline{\null} % deprecated
+%%
+
+
+%% OBSOLETE.
+%%Replaced by better method. Will be honored, but not documented.
+\newcommand\TestCoverImage[1]{%
+ \@tempTFfalse%
+ \IfSubStr{#1}{jpg}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{jpeg}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{JPG}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{JPEG}{\@tempTFtrue}{}%
+ \IfSubStr{#1}{png}{%
+ \@tempTFtrue
+ \if@pdfxISoff\else
+ \ifthenelse{\equal{\@PDFversion}{PDF/X-1}}{
+ \ClassError{novel}{Cannot use png cover image with PDF/X-1a}%
+ {PDF/X-1a requires CMYK image. But png format is always RGB.}%
+ }{}
+ \fi
+ \ClassWarning{novel}{^^JCover image is png file type. ^^J%
+ Format png only supports RGB, not CMYK. ^^J%
+ This might be OK if you are not using PDF/X-1a, ^^J%
+ and if your print service accepts RGB artwork. ^^J%
+ But in many cases, not OK. Did you need CMYK? ^^J}%
+ }{}%
+ \IfSubStr{#1}{PNG}{%
+ \@tempTFtrue
+ \if@pdfxISoff\else
+ \ifthenelse{\equal{\@PDFversion}{PDF/X-1}}{
+ \ClassError{novel}{Cannot use png cover image with PDF/X-1a}%
+ {PDF/X-1a requires CMYK image. But png format is always RGB.}%
+ }{}
+ \fi
+ \ClassWarning{novel}{^^JCover image is png file type. ^^J%
+ Format png only supports RGB, not CMYK. ^^J%
+ This might be OK if you are not using PDF/X-1a, ^^J%
+ and if your print service accepts RGB artwork. ^^J%
+ But in many cases, not OK. Did you need CMYK? ^^J}%
+ }{}%
+ \if@tempTF\else%
+ \ClassError{novel}{Cover image has wrong file extension}%
+ {Cover image must be jpg, JPG, jpeg, JPEG. ^^J%
+ Can also use png or PNG if CMYK not required.}%
+ \fi%
+} % end \TestCoverImage
+%%
+\newcommand\SetCoverImage[1]{%
+ \if@coverart%
+ \ClassWarning{novel}{^^J\string\SetCoverImage\space is obsolete. ^^J%
+ It will be honored, but not documented. From `novel' version 1.50 use ^^J%
+ novel-scripts, then \ScriptCoverImage\space instead. ^^J}%
+ \TestCoverImage{#1}%
+ \AddToShipoutPictureBG{%
+ \AtPageUpperLeft{%
+ \InlineImage{#1}%
+ }%
+ }%
+ \null% without this, page has no "content"
+ \else%
+ \ClassError{novel}{\string\SetCoverImage\space requires `coverart' option}%
+ {You must use the `coverart' document class option, for cover image.}%
+ \fi%
+} % end \SetCoverImage
+%%
+
+
+%% OBSOLETE
+\newif \if@FlexResolutionSet
+\gdef\@novereserror{%
+ \ClassError{novel}{\string\SetFlexResolution\space bad value}%
+ {Resolution dpi must be integer from 200 to 9600. Default 300.}%
+}
+\newcommand\SetFlexResolution[1]{
+ \IfInteger{#1}{ %
+ \FPiflt{#1}{200}\@novereserror\else\fi % not enough
+ \FPifgt{#1}{9600}\@novereserror\else\fi % too much
+ \gdef\@novimgres{#1} %
+ }{ %
+ \@novreserror %
+ } %
+ \@FlexResolutionSettrue %
+}%
+%
+\AtEndPreamble{% called by `novel.cls' \AtEndPreamble
+ \if@FlexResolutionSet %
+ \pdfimageresolution=\@novimgres % from \SetFlexResolution. Default 300.
+ \fi %
+}%
+%%
+
+
+%% BLOCK IMAGE (OBSOLETE)
+%% ----------------------------------------------------------------------------
+%% \BlockImage[alignment]{image}[text]
+%% OBSOLETE FROM VERSION 1.50. Use \FloatImage instead.
+\DeclareDocumentCommand \BlockImage { O{c} m +O{} }{%
+ \ClassWarning{novel}{^^J\string\BlockImage\space command is obsolete. ^^J%
+ It will remain in effect for existing documents that have it. ^^J%
+ New documents: Use \string\FloatImage, or \string\WrapImage, instead. ^^J%
+ Purpose and syntax is slightly different. See docs. ^^J}%
+ \iftoggle{@inheadfoot}{%
+ \ClassError{novel}{Cannot use \string\BlockImage\space in header/footer}%
+ {Header footer allow \string\InlineImage, but not \string\BlockImage.}%
+ }{}%
+ \@TestImageExtension{#2}%
+ % Allows empty or blank to be used, and still provide default values:
+ \ifthenelse{\equal{#1}{} \OR \equal{#1}{\space}}{%
+ \def\@myargs{c}}{\def\@myargs{#1}%
+ }%
+ \StrDel{\@myargs}{\space}[\@myargsns]% needs {\space} not { }
+ \StrCut{\@myargsns}{,}{\@myalign}{\@mycoord}%
+ \StrCut{\@mycoord}{,}{\@myxt}{\@myyt}%
+ \ifthenelse{\equal{\@myxt}{}\OR\equal{\@myxt}{0}}{%
+ \def\@myx{0pt}}{\def\@myx{\@myxt}%
+ }%
+ \ifthenelse{\equal{\@myyt}{}\OR\equal{\@myyt}{0}}{%
+ \def\@myy{0pt}}{\def\@myy{\@myyt}%
+ }%
+ %
+ \global\@UsingNovelCommandtrue%
+ \gdef\@mygraphic{\novel@sub@inclgr{#2}}%
+ \gdef\@mygraphicname{#2}%
+ \setlength\@imagewidth{\widthof{\@mygraphic}}%
+ \global\@imagewidth=\@imagewidth%
+ \setlength\@imageheight{\heightof{\@mygraphic}}%
+ \global\@imageheight=\@imageheight%
+ \setlength\@imagehoffset{\@myx}%
+ \IfBeginWith{\@myy}{b}{%
+ \ClassError{novel}{Cannot use voffset `b' on %
+ \string\BlockImage, page \thepage}%
+ {The `b' voffset only works with \string\InlineImage, %
+ not \string\BlockImage.}%
+ }{%
+ \setlength\@imagevoffset{-\@imageheight}%
+ \addtolength\@imagevoffset{\@myy}%
+ }%
+ %
+ \setlength\@mytotalht{0pt}%
+ \addtolength\@mytotalht{\@imageheight}%
+ \addtolength\@mytotalht{-\@myy}%
+ \addtolength\@mytotalht{1em}%
+ \def\@mytotalhtN{\strip@pt\@mytotalht}%
+ \FPdiv{\@mytotalhtN}{\@mytotalhtN}{\strip@pt\nbs}%
+ \FPadd{\@mytotalhtN}{\@mytotalhtN}{0.5}%
+ \FPround{\@mytotalhtN}{\@mytotalhtN}{0}%
+ %
+ \begin{linegap}{\@mytotalhtN}%
+ %
+ \ifthenelse{\equal{\@myalign}{c}\OR\equal{\@myalign}{}}{%
+ {\centering%
+ \makebox[0pt][l]{%
+ \hspace{\dimexpr\@myx-0.5\@imagewidth}%
+ \stake\smash{\raisebox{\dimexpr\@myy-\@imageheight}{\@mygraphic}}%
+ }%
+ \par%
+ }
+ \vspace*{-\nbs}%
+ {\centering #3\par}%
+ }{}%
+ \ifthenelse{\equal{\@myalign}{r}}{%
+ \noindent\makebox[0pt][l]{%
+ \hspace{\dimexpr\textwidth+\@myx-\@imagewidth}%
+ \stake\smash{\raisebox{\dimexpr\@myy-\@imageheight}{\@mygraphic}}%
+ }\par%
+ \vspace{-2\nbs}%
+ \begin{adjustwidth}{0pt}{\@imagewidth+\parindent}%
+ \strut\par%
+ #3\par%
+ \end{adjustwidth}%
+ }{}%
+ \ifthenelse{\equal{\@myalign}{l}}{%
+ \noindent\makebox[0pt][l]{%
+ \hspace{\@myx}%
+ \stake\smash{\raisebox{\dimexpr\@myy-\@imageheight}{\@mygraphic}}%
+ }%
+ \par%
+ \vspace{-2\nbs}%
+ \begin{adjustwidth}{\@imagewidth+\parindent}{0pt}%
+ \strut\par%
+ #3\par%
+ \end{adjustwidth}%
+ }{}%
+ \end{linegap}%
+ \global\@UsingNovelCommandfalse%
+} % end \BlockImage (OBSOLETE)
+%%
+
+
+%% LINEGAP IS OBSOLETE CODE. NOT DOCUMENTED.
+%% ----------------------------------------------------------------------------
+% Allows text to be placed (potentially) off-grid, with grid resuming after.
+\newif \if@WithinLinegap % true within linegap environment
+\newcounter{currentlinegap} % 0 when not within linegap, >0 otherwise.
+\DeclareDocumentEnvironment {linegap} { m } {%
+ \FPifint{#1}\else%
+ \ClassError{novel}{Non-integer linegap on page \thepage}%
+ {Only integer >= 1 allowed for linegap.}%
+ \fi%
+ \FPiflt{#1}{1}%
+ \ClassError{novel}{Insufficient linegap on page \thepage}%
+ {Only integer >= 1 allowed for linegap.}%
+ \fi%
+ \par%
+ \null%
+ \vspace*{-\nbs}%
+ \global\@WithinLinegaptrue%
+ \begin{textblock*}{\textwidth}[0,0](0pt,0pt)%
+ \setcounter{currentlinegap}{#1}
+ \strut\par%
+ \vspace*{-\nbs}%
+}{% close the environment:
+ \end{textblock*}%
+ \global\@WithinLinegapfalse%
+ \par%
+ \vspace*{#1\nbs}%
+ \setcounter{currentlinegap}{0}%
+} % end linegap (obsolete)
+%%
+
+
+%% REWORK IS OBSOLETE CODE. NOT DOCUMENTED.
+%% ----------------------------------------------------------------------------
+%% \ReworkTrimSize retroactively changes Trim Size after layout.
+% If you use \ReworkTrimSize, you must first use \SetTrimSize (not defaults):
+\newlength\@NewTrimWidth
+\newlength\@NewTrimHeight
+\newif \if@ReworkTrimSize
+\newcommand\ReworkTrimSize[2]{% width, height
+ \ClassWarning{novel}{\string\Rework\space commands are obsolete. ^^J%
+ The \string\Rework\space commands are still effective for old documents, ^^J%
+ but should not be used for new documents, due to potential layout issues.}%
+ \if@SetTrimSize\else
+ \ClassError{novel}{Must use \string\SetTrimSize\space %
+ before \string\ReworkTrimSize}%
+ {\string\ReworkTrimSize\space cannot be applied to default Trim Size. ^^J%
+ You must manually \string\SetTrimSize\space prior to %
+ \string\ReworkTrimSize.}%
+ \fi
+ \if@coverart % New in version 1.2
+ \ClassError{novel}{\string\Rework\space commands cannot be used %
+ with `coverart' option}%
+ {Instead of \string\Rework, you must re-do the graphics artwork.}
+ \else
+ \global\@ReworkTrimSizetrue
+ \gsetlength\@NewTrimWidth{#1}
+ \gsetlength\@NewTrimHeight{#2}
+ \typeout{^^J Class `novel' Alert: %
+ Used \string\ReworkTrimSize\space command. ^^J%
+ Carefully review your PDF to ensure that line breaks, paragraphs, ^^J%
+ and page breaks are where you expect them to be. ^^J}%
+ \fi
+}% end \ReworkTrimSize
+%%
+
+
+%% REWORK IS OBSOLETE CODE. NOT DOCUMENTED.
+%% Retroactively change margins after layout. See documentation.
+% If you use \ReworkMargins, you must first use \SetMargins (not defaults):
+\newlength\@NewTopMargin
+\newlength\@NewOuterMargin
+\newlength\@NewBottomMargin
+\newlength\@NewInnerMargin
+\newif \if@ReworkMargins
+\newcommand\ReworkMargins[4]{ % top, outer, bottom, inner
+ \ClassWarning{novel}{\string\Rework\space commands are obsolete. ^^J%
+ The \string\Rework\space commands are still effective for old documents, ^^J%
+ but should not be used for new documents, due to potential layout issues.}%
+ \if@coverart % New in version 1.2
+ \ClassError{novel}{\string\Rework\space commands cannot be used %
+ with coverart option}%
+ {Instead of \string\Rework, you must re-do the graphics artwork.}
+ \else
+ \global\@ReworkMarginstrue
+ \gsetlength\@NewTopMargin{#1}
+ \gsetlength\@NewOuterMargin{#2}
+ \gsetlength\@NewBottomMargin{#3}
+ \gsetlength\@NewInnerMargin{#4}
+ \typeout{^^JClass novel Alert: Used \string\ReworkMargins. ^^J%
+ Carefully review your PDF to ensure that line breaks, paragraphs, ^^J%
+ and page breaks are where you expect them to be. ^^J}%
+ \fi
+}% end \ReworkMargins
+\LetLtxMacro\ReworkMargin{\ReworkMargins}\relax % for those who mis-type
+%% When \Rework, should result honor new margins (if possible), or should
+% result maintain original aspect ratio?
+\newif \if@AspectPriority
+\newcommand\ReworkPriority[1]{%
+ \@tempTFfalse
+ \ifthenelse{\equal{#1}{aspect}}{\@AspectPrioritytrue\@tempTFtrue}{}
+ \ifthenelse{\equal{#1}{margins}}{\@AspectPriorityfalse\@tempTFtrue}{}
+ \ifthenelse{\equal{#1}{margin}}{\@AspectPriorityfalse\@tempTFtrue}{}
+ \if@tempTF\else
+ \ClassError{novel}{Bad choice for \string\ReworkPriority}%
+ {Rework priority choices: aspect, margins (default margins).}%
+ \fi
+}
+\ReworkPriority{margins} % default
+%%
+
+
+%% REWORK IS OBSOLETE CODE. NOT DOCUMENTED.
+\gdef\ObsoleteRework{ %
+% A few values from the original calculation must be stored:
+\newlength\@OriginalEmSize
+ \gsetlength\@OriginalEmSize{\@SetFontSize}
+\newlength\@OriginalTextWidth % same as original available width
+ \gsetlength\@OriginalTextWidth{\textwidth}
+\newlength\@OriginalHeight % includes header/footer
+ \gsetlength\@OriginalHeight{\@AvailableHeight}
+\newlength\@OriginalBaselineSkip
+ \gsetlength\@OriginalBaselineSkip{\baselineskip}
+% Change the values of trim size and margins, as requested.
+% If not changed, same as before:
+\if@ReworkTrimSize
+ \gsetlength\@TrimWidth{\@NewTrimWidth}
+ \gsetlength\@TrimHeight{\@NewTrimHeight}
+\fi
+\if@ReworkMargins
+ \gsetlength\@TopMargin{\@NewTopMargin}
+ \gsetlength\@OuterMargin{\@NewOuterMargin}
+ \gsetlength\@BottomMargin{\@NewBottomMargin}
+ \gsetlength\@InnerMargin{\@NewInnerMargin}
+\fi
+% Re-calculate:
+\gsetlength\@AvailableWidth{\@TrimWidth-\@OuterMargin-\@InnerMargin}
+\gsetlength\@AvailableHeight{\@TrimHeight-\@TopMargin-\@BottomMargin}
+%%
+\xdef\@TWratio{\fpeval{\@AvailableWidth/\@OriginalTextWidth}}
+\xdef\@THratio{\fpeval{\@AvailableHeight/\@OriginalHeight}}
+\FPmin{\@TMratio}{\@TWratio}{\@THratio}
+%%
+\if@AspectPriority
+ \gsetlength\textwidth{\@TMratio\@OriginalTextWidth}
+ \gsetlength\@SetFontSize{\@TMratio\@OriginalEmSize}
+ \gsetlength\baselineskip{\@TMratio\@OriginalBaselineSkip}
+ % Find whether limiting factor is width or height:
+ \ifnumcomp{\@TWratio}{<}{\@THratio}{%
+ \setlength\@tempLength{\@AvailableHeight-\@AdjLPP\baselineskip}
+ \setlength\@tempLength{\@tempLength-\baselineskip+\@SetFontSize}
+ \setlength\@tempLength{0.5\@tempLength}
+ \gsetlength{\@TopMargin}{\@TopMargin+\@tempLength}
+ \gsetlength{\@BottomMargin}{\@BottomMargin+\@tempLength}
+ \FPround{\@tempN}{\strip@pt\@tempLength}{2}
+ \setlength\@tempLength{\@tempN pt}
+ \FPround{\@tempN}{\@TMratio}{4}
+ \typeout{^^JClass `novel' Info: Rework preserving aspect ratio. ^^J Each%
+ vertical margin \the\@tempLength\space over requested rework value. ^^J%
+ Scale \@tempN\space applied to text size and baselineskip. ^^J%
+ } %
+ }{%
+ \gsetlength\@OuterMargin{\@OuterMargin+0.5\@AvailableWidth-0.5\textwidth}
+ \gsetlength\@InnerMargin{\@InnerMargin+0.5\@AvailableWidth-0.5\textwidth}
+ \setlength\@tempLength{0.5\@AvailableWidth-0.5\textwidth}
+ \FPround{\@tempN}{\strip@pt\@tempLength}{2}
+ \setlength\@tempLength{\@tempN pt}
+ \FPround{\@tempN}{\@TMratio}{4}
+ \typeout{^^JClass `novel' Info: Rework preserving aspect ratio. ^^J%
+ Each side margin \the\@tempLength\space over requested rework value. ^^J%
+ Scale \@tempN\space applied to text size and baselineskip. ^^J%
+ } %
+ } % end \ifnumcomp
+\else % margins priority:
+ % Discover what happens if scaled according to text width:
+ \gsetlength\textwidth{\@AvailableWidth}
+ \gsetlength\@SetFontSize{\@TWratio\@OriginalEmSize}
+ \gsetlength\baselineskip{1.2\@SetFontSize} % test for least allowable
+ \setlength\@tempLength{\@AdjLPP\baselineskip}
+ \ifdimcomp{\@AvailableHeight-\@tempLength}{<}{0pt}{%
+ % Will not fit vertically, so will need to re-scale \@SetFontSize.
+ \gsetlength\@SetFontSize{\@OriginalEmSize}
+ \gsetlength\baselineskip{\fpeval{\@AvailableHeight/(\@AdjLPP+1.3)}pt}
+ \FPdiv\@THratio{\strip@pt\baselineskip}{\strip@pt\@OriginalBaselineSkip}
+ \gsetlength\@SetFontSize{0.8333\baselineskip} % 0.8333 = 1/1.2, tight skip
+ \FPdiv{\@tempN}{\strip@pt\@SetFontSize}{\strip@pt\@OriginalEmSize}
+ \gsetlength\textwidth{\@tempN\@OriginalTextWidth}
+ \gsetlength\@OuterMargin{%
+ 0.5\@OuterMargin+0.5\@TrimWidth-0.5\@InnerMargin-0.5\textwidth%
+ }
+ \gsetlength\@InnerMargin{%
+ 0.5\@InnerMargin+0.5\@TrimWidth-0.5\@OuterMargin-0.5\textwidth%
+ }
+ \FPround{\@ActualOuterN}{\strip@pt\@OuterMargin}{2}
+ \FPround{\@ActualInnerN}{\strip@pt\@InnerMargin}{2}
+ \FPmul{\@TWratio}{\@TWratio}{\@THratio}
+ \FPmul{\@THratio}{\@TWratio}{1.2}
+ \FPround{\@TWratio}{\@TWratio}{4}
+ \FPround{\@THratio}{\@THratio}{4}
+ \typeout{^^JClass `novel' Info: Reworked side margins enlarged. ^^J%
+ Actual Outer Margin is now \@ActualOuterN pt. ^^J%
+ Actual Inner Margin is now \@ActualInnerN pt. ^^J%
+ Scale \@TWratio\space applied to text, ^^J%
+ \@THratio\space applied to baselineskip. ^^J%
+ } %
+ }{% Fits vertically. Keep \@SetFontSize. Calculate \baselineskip to fit:
+ \gsetlength\baselineskip{%
+ \fpeval{(\@AvailableHeight-1.3*\@SetFontSize)/\@AdjLPP}pt%
+ } %
+ \FPdiv{\@BLratio}{\strip@pt\baselineskip}{\strip@pt\@OriginalBaselineSkip}
+ \FPround{\@BLratio}{\@BLratio}{4}
+ \FPround{\@TWratio}{\@TWratio}{4}
+ \typeout{^^JClass `novel' Info: Rework was able to fit new margins. ^^J%
+ Scale applied to font size: \@TWratio. ^^J%
+ Scale applied to baselineskip: \@BLratio. ^^J%
+ } %
+ }% end \ifdimcomp.
+\fi
+} % end ObsoleteRework.
+%%
+
+
+%%
+\AtBeginDocument{%
+ \LetLtxMacro\ReworkTrimSize\relax
+ \LetLtxMacro\ReworkMargins\relax
+ \LetLtxMacro\ReworkPriority\relax
+ \LetLtxMacro\SetFlexResolution\relax % cannot use past Preamble
+ \providecommand\acronym[1]{\midcase{#1}}% acronym deprecated
+} %
+%%
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-Obsolete.sty'.
+
+
diff --git a/macros/luatex/latex/novel/novel-PostLayout.sty b/macros/luatex/latex/novel/novel-PostLayout.sty
new file mode 100644
index 0000000000..a2796db1d1
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-PostLayout.sty
@@ -0,0 +1,263 @@
+%%
+%% This is file `novel-PostLayout.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%% It may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-PostLayout.sty}%
+[2018/04/26 v1.52 LaTeX file (post-layout modifications)]
+%%
+
+%%
+%% This file is loaded \AtEndPreamble, which precedes \AtBeginDocument.
+%%
+
+
+
+% \@getPageXY is used by `shademargins' and `cropmarks' options.
+% The 72.27pt compensates for built-in 1in TeX offsets.
+% Position of left edge of TrimBox, rightwards from left edge of MediaBox:
+\newlength\Trim@Left
+% Position of bottom of TrimBox, upwards from bottom of MediaBox:
+\newlength\Trim@Bottom
+\gdef\@getPageXY{%
+ \ifodd\c@page% Adjusts for left-right margin switching, verso/recto,
+ % and also for horizontal position of TrimBox within MediaBox:
+ \gsetlength\Trim@Left{\oddsidemargin-\@InnerMargin+72.27pt}%
+ \else%
+ \gsetlength\Trim@Left{\evensidemargin-\@OuterMargin+72.27pt}%
+ \fi%
+ % Adjusts for vertical position of TrimBox within MediaBox:
+
+ \gsetlength\Trim@Bottom{0.5\paperheight-0.5\@TrimHeight+\hoffset}%
+
+}%
+%% end \@getPageXY.
+
+
+%% ACTIVATE CLOSECROP CLASS OPTION
+%% ----------------------------------------------------------------------------
+% The `closecrop' class option is only effective in draft mode.
+% It preserves the text layout, but removes most of the margin white space.
+% The resulting file is more easily readable on a hand-held device.
+% However, the cropped file is not suitable for distribution as an E-book,
+% as it is missing reflow information, marketing metadata, etc.
+\if@closecrop
+ \gsetlength\paperwidth{\textwidth+0.2in}
+ \if@HasHeader
+ \gsetlength\topmargin{-1in}
+ \else
+ \gsetlength\topmargin{-0.9in}
+ \fi
+ \if@HasFooter
+ \if@HasHeader
+ \gsetlength\paperheight{%
+ \textheight+\headsep+\headheight+\@FootJump\baselineskip+1pt%
+ }
+ \else
+ \gsetlength\paperheight{%
+ \textheight+\headsep+\headheight+\@FootJump\baselineskip+\@SetFontSize%
+ }
+ \fi
+ \else
+ \gsetlength\paperheight{\textheight+\headsep+\headheight+0.1in}
+ \fi
+\fi
+%% end closecrop
+
+
+%% ACTIVATE SHADEMARGINS CLASS OPTION (Includes Unsafe Zone)
+%% ----------------------------------------------------------------------------
+%% With class option `shademargins' (only effective in draft mode):
+% Based on code by Ulrike Fischer at tex.stackexchange.com, CC-by-sa-3.0:
+% 0.542763, 0.883215 and 0.949123 are unlikely user choices.
+% The re-defined \color command makes an exception for those values.
+\definecolor[named]{hingledingle}{gray}{1} % fake white, when white disallowed
+%
+\if@shademargins
+ % Margins are visualized by filling the TrimBox background with gray.
+ % Then, the rectangle defining the Englosed area is filled with white.
+ % Then header and/or footer are filled with a lighter gray background.
+ % Then Unsafe Zone (UZ) sits atop the other background fills, as darker gray.
+ % The UZ is constructed from four strips, one at each side.
+ \AddToShipoutPictureBG{% fills trim area with medium gray
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.883215}%
+ \hspace{\Trim@Left}%
+ \rule[\Trim@Bottom]{\@TrimWidth}{\@TrimHeight}%
+ }%
+ }%
+ %
+ \AddToShipoutPictureBG{% fills enclosed area with white
+ \@getPageXY%
+ \AtPageLowerLeft{\color{hingledingle}%
+ \ifodd\c@page%
+ \hspace{\dimexpr\oddsidemargin+72.27pt}%
+ \else%
+ \hspace{\dimexpr\evensidemargin+72.27pt}%
+ \fi%
+ \rule[\dimexpr\Trim@Bottom+\@BottomMargin]%
+ {\textwidth}{\dimexpr\@TrimHeight-\@TopMargin-\@BottomMargin}
+ }%
+ }%
+ \if@HasHeader% fills header (and its jump) with light gray
+ \AddToShipoutPictureBG{%
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.949123}%
+ \ifodd\c@page%
+ \hspace{\dimexpr\oddsidemargin+72.27pt}%
+ \else%
+ \hspace{\dimexpr\evensidemargin+72.27pt}%
+ \fi%
+ \rule[\Trim@Bottom+\@TrimHeight-\@TopMargin-\@HeadJump\nbs]%
+ {\@TrimWidth-\@OuterMargin-\@InnerMargin}{\@HeadJump\nbs}%
+ }%
+ }%
+ \fi%
+ %
+ \if@HasFooter% fills footer (and its jump) with light gray
+ \AddToShipoutPictureBG{%
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.949123}%
+ \ifodd\c@page%
+ \hspace{\dimexpr\oddsidemargin+72.27pt}%
+ \else%
+ \hspace{\dimexpr\evensidemargin+72.27pt}%
+ \fi%
+ \rule[\Trim@Bottom+\@BottomMargin]%
+ {\@TrimWidth-\@OuterMargin-\@InnerMargin}{\@FootJump\nbs}%
+ }%
+ }%
+ \fi%
+ %
+ \if@UnsafeZone% fills unsafe zones with dark gray
+ \AddToShipoutPictureBG{% top unsafe zone
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.542763}%
+ \hspace{\Trim@Left}%
+ \rule[\Trim@Bottom+\@TrimHeight-\@TopUZWidth]%
+ {\@TrimWidth}{\@TopUZWidth}%
+ }%
+ }%
+ \AddToShipoutPictureBG{% outer unsafe zone
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.542763}%
+ \ifodd\c@page%
+ \hspace{\dimexpr\Trim@Left+\@TrimWidth-\@OuterUZWidth}%
+ \rule[\Trim@Bottom]{\@OuterUZWidth}{\@TrimHeight}%
+ \else%
+ \hspace{\dimexpr\Trim@Left+\@TrimWidth-\@InnerUZWidth}%
+ \rule[\Trim@Bottom]{\@InnerUZWidth}{\@TrimHeight}%
+ \fi%
+ }%
+ }%
+ \AddToShipoutPictureBG{% bottom unsafe zone
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.542763}%
+ \hspace{\Trim@Left}%
+ \rule[\Trim@Bottom]{\@TrimWidth}{\@BottomUZWidth}%
+ }%
+ }%
+ \AddToShipoutPictureBG{% inner unsafe zone
+ \@getPageXY%
+ \AtPageLowerLeft{\color[gray]{0.542763}%
+ \hspace{\Trim@Left}%
+ \ifodd\c@page%
+ \rule[\Trim@Bottom]{\@InnerUZWidth}{\@TrimHeight}%
+ \else%
+ \rule[\Trim@Bottom]{\@OuterUZWidth}{\@TrimHeight}%
+ \fi%
+ }%
+ }%
+ \fi% end \if@UnsafeZone
+ %
+\fi % end \if@shademargins
+%
+%% end shademargins and unsafe zone
+
+
+%% LABEL DRAFT OPTION
+%% ----------------------------------------------------------------------------
+% Writes DRAFT inside upper left of TrimBox, when in draft mode.
+% This macro must go here, in order, so that the label is not over-shaded.
+\ifdraftdoc
+ \AddToShipoutPictureBG{%
+ \@getPageXY%
+ \AtPageUpperLeft{%
+ \raisebox{-\@SetFontSize}{\textbf{~DRAFT}}%
+ }%
+ }%
+\fi
+%% end label draft.
+
+
+%% ACTIVATE CROPMARKS CLASS OPTION
+%% ----------------------------------------------------------------------------
+% Cropmarks (trim marks, really) are not important in this document class.
+% That's because the targeted printing services generally do not want them.
+% But a minimal capability was easy to add. The far end of each mark is
+% 0.25in from the trim area. The close end is separated by 0.125in.
+% So the length of the marks essentially 1/8in. Width 0.25bp.
+% The marks are turned on using `cropmarks' class option.
+% When Media Size = Trim Size, cropmarks are disabled.
+% Too late for \@cropviewfalse; OK since CropBox already calculated properly.
+\ifthenelse{%
+ \dimtest{\@TrimWidth}{=}{\paperwidth} %
+ \AND \dimtest{\@TrimHeight}{=}{\paperheight}%
+}{\global\@cropmarksfalse}{}
+%
+\if@cropmarks% Cropmark begins 0.125in from TrimBox, ends 0.25in from TrimBox.
+ % H top left:
+ \AddToShipoutPictureBG{\@getPageXY%
+ \AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left-0.25in}%
+ \rule[0.5\paperheight+0.5\@TrimHeight]{0.25in-0.125in}{0.25bp}}}
+ % H bottom left:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left-0.25in}%
+ \rule[\Trim@Bottom-0.5pt]{0.25in-0.125in}{0.25bp}}}
+ % H top right:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left+\@TrimWidth+0.125in}%
+ \rule[0.5\paperheight+0.5\@TrimHeight]{0.25in-0.125in}{0.25bp}}}
+ % H bottom right:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left+\@TrimWidth+0.125in}%
+ \rule[\Trim@Bottom-0.25bp]{0.25in-0.125in}{0.25bp}}}
+ % V top left:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left-0.25bp}%
+ \rule[0.5\paperheight+0.5\@TrimHeight+0.125in]%
+ {0.25bp}{0.25in-0.125in}}}
+ % V bottom left:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left-0.25bp}%
+ \rule[\Trim@Bottom-0.25in]{0.25bp}{0.25in-0.125in}}}
+ % V top right:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left+\@TrimWidth}%
+ \rule[0.5\paperheight+0.5\@TrimHeight+0.125in]%
+ {0.25bp}{0.25in-0.125in}}}
+ % V bottom right:
+ \AddToShipoutPictureBG{\@getPageXY\AtPageLowerLeft{%
+ \hspace{\dimexpr\Trim@Left+\@TrimWidth}%
+ \rule[\Trim@Bottom-0.25in]{0.25bp}{0.25in-0.125in}}}
+\fi
+%
+%% end cropmarks
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-PostLayout.sty'.
+
+
diff --git a/macros/luatex/latex/novel/novel-Sandbox.sty b/macros/luatex/latex/novel/novel-Sandbox.sty
new file mode 100644
index 0000000000..9939c66110
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-Sandbox.sty
@@ -0,0 +1,145 @@
+%%
+%% This is file `novel-Sandbox.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%% Material extracted from `article.cls', a LaTeX document class.
+%% Copyright 1993-2016
+%% The LaTeX3 Project and any individual authors listed elsewhere
+%% in this file.
+%%
+%% It may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-Sandbox.sty}%
+[2018/04/26 v1.52 LaTeX file (used only with sandbox class option)]
+%%
+
+%%
+%% This file is only loaded when the `sandbox' document class is used.
+%% It provides support for tables, and a few other things that ordinarily
+%% would be prohibited in `novel' due to possible layout incompatibility.
+%%
+%% Normally, `novel' sets many glues and lengths to zero, to maintain line grid.
+%% But `sandbox', sets the glues to values typical of other document classes.
+%% So, not only can you construct tables, they will look as expected.
+%%
+
+
+
+
+\setlength\leftmargini {2.5em}
+\leftmargin \leftmargini
+\setlength\leftmarginii {2.2em}
+\setlength\leftmarginiii {1.87em}
+\setlength\leftmarginiv {1.7em}
+\setlength\leftmarginv {1em}
+\setlength\leftmarginvi {1em}
+\setlength \labelsep {.5em}
+\setlength \labelwidth{\leftmargini}
+\addtolength\labelwidth{-\labelsep}
+\@beginparpenalty -\@lowpenalty
+\@endparpenalty -\@lowpenalty
+\@itempenalty -\@lowpenalty
+\renewcommand\theenumi{\@arabic\c@enumi}
+\renewcommand\theenumii{\@alph\c@enumii}
+\renewcommand\theenumiii{\@roman\c@enumiii}
+\renewcommand\theenumiv{\@Alph\c@enumiv}
+\newcommand\labelenumi{\theenumi.}
+\newcommand\labelenumii{(\theenumii)}
+\newcommand\labelenumiii{\theenumiii.}
+\newcommand\labelenumiv{\theenumiv.}
+\renewcommand\p@enumii{\theenumi}
+\renewcommand\p@enumiii{\theenumi(\theenumii)}
+\renewcommand\p@enumiv{\p@enumiii\theenumiii}
+\newcommand\labelitemi{\textbullet}
+\newcommand\labelitemii{\normalfont\bfseries \textendash}
+\newcommand\labelitemiii{\textasteriskcentered}
+\newcommand\labelitemiv{\textperiodcentered}
+\newenvironment{description}
+ {\list{}{\labelwidth\z@ \itemindent-\leftmargin
+ \let\makelabel\descriptionlabel}}
+ {\endlist}
+\newcommand*\descriptionlabel[1]{\hspace\labelsep
+ \normalfont\bfseries #1}
+
+
+
+\setlength\tabcolsep{6pt}
+\setlength\arrayrulewidth{.4pt}
+\setlength\doublerulesep{2pt}
+\setlength\tabbingsep{\labelsep}
+
+
+\newcounter{figure}
+\renewcommand \thefigure {\@arabic\c@figure}
+\def\fps@figure{tbp}
+\def\ftype@figure{1}
+\def\ext@figure{lof}
+\def\fnum@figure{\figurename\nobreakspace\thefigure}
+
+\newenvironment{figure}
+ {\@float{figure}}
+ {\end@float}
+\newenvironment{figure*}
+ {\@float{figure}}
+ {\end@float}
+
+
+
+\newcounter{table}
+\renewcommand\thetable{\@arabic\c@table}
+\def\fps@table{tbp}
+\def\ftype@table{2}
+\def\ext@table{lot}
+\def\fnum@table{\tablename\nobreakspace\thetable}
+
+\newenvironment{table}
+ {\@float{table}}
+ {\end@float}
+\newenvironment{table*}
+ {\@float{table}}
+ {\end@float}
+
+
+
+\newlength\abovecaptionskip
+\newlength\belowcaptionskip
+
+\setlength\abovecaptionskip{\nbs}
+
+\setlength\belowcaptionskip{0pt}
+
+\long\def\@makecaption#1#2{%
+ \vskip\abovecaptionskip
+ \sbox\@tempboxa{#1: #2}%
+ \ifdim \wd\@tempboxa >\hsize
+ #1: #2\par
+ \else
+ \global \@minipagefalse
+ \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
+ \fi
+ \vskip\belowcaptionskip}
+
+
+
+
+
+
+
+\def\today{\ifcase\month\or
+ January\or February\or March\or April\or May\or June\or
+ July\or August\or September\or October\or November\or December\fi
+ \space\number\day, \number\year}
+
+
+
+\endinput
+
+%% end of file `novel-Sandbox.sty'.
+
diff --git a/macros/luatex/latex/novel/novel-TextMacros.sty b/macros/luatex/latex/novel/novel-TextMacros.sty
new file mode 100644
index 0000000000..5b994c2538
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-TextMacros.sty
@@ -0,0 +1,587 @@
+%%
+%% This is file `novel-TextMacros.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\ProvidesFile{novel-TextMacros.sty}%
+[2018/04/26 v1.52 LaTeX file (text macros usable within document body)]
+%%
+
+
+%% This file contains various commands usable within the document body,
+%% for styling and otherwise manipulating text.
+%% These are not commands used in Preamble for setup, although a few of them
+%% can be used in Preamble for setup, then again in body for change.
+
+
+
+%% The following commands are BANNED.
+%% ----------------------------------------------------------------------------
+% The `novel' class disallows these commands, or neutralizes them by simply
+% repeating their arguments. In some cases, they request functionality
+% not implemented in `novel'. In other cases, the function is part of core,
+% but would interfere with the `novel' emphasis on constant line skip.
+% You may re-define the commands via your own code in Preamble (discouraged).
+%
+%% Standard LaTeX font sizes are ineffective. Use novel's own methods.
+% If you write one of these size commands, it will silently be ignored:
+% \small, \footnotesize, \scriptsize, \tiny,
+% \ large, \Large, \LARGE, \huge, \Huge, \HUGE, \textls
+%
+%% Internal subdivisions are ineffective.
+% The command will merely echo its argument, without any functionality:
+% \part, \chapter, \section, \subsection, \subsubsection,
+% \paragraph, \subparagraph.
+%
+%% Some commands will generate an error, so that you know they cannot be used:
+% \maketitle, \makeindex, \tableofcontents, \listoftables, \listoffigures,
+%
+%% You can only use \includepdf (package: pdfpages) for pdf files pre-processed
+%% by novel-scripts.
+%
+%% You cannot use \includegraphics. Instead use novel's own image commands.
+%
+%% Commands normally provided in other classes, pertaining to floats, figures,
+% and tables, are not defined in `novel' class.
+% If you attempt to use them, an error will result.
+%%
+
+
+%% AND NOW TO THE GOOD STUFF
+%% ----------------------------------------------------------------------------
+
+%%
+% New in version 1.38, \straightquote and \straightdblquote:
+\gdef\straightquote{{\addfontfeature{Ligatures=ResetAll}'}}
+\gdef\straightdblquote{{\addfontfeature{Ligatures=ResetAll}"}}
+%%
+
+%% Acronyms often look too big in regular capitals, but too small in
+% small caps. Command \midcase{} provides an intermediate size:
+\gdef\midcase#1{%
+ \if@HasDecoFont%
+ {\decofont{#1}}%
+ \else%
+ #1% simply echo the argument, if no decofont
+ \fi%
+}%
+%%
+
+%% Deco glyphs are decorative elements chosen from the decofont by code.
+% They are documented in file NovelDeco-glyphs.pdf, in the `extras' folder.
+\gdef\decoglyph#1{%
+ \if@HasDecoFont%
+ \IfBeginWith{#1}{n}{% normal weight symbol (same as regular)
+ \StrBehind{#1}{n}[\@tempdecoglyph]{\@decoglyph\symbol{\@tempdecoglyph}}%
+ }{}%
+ \IfBeginWith{#1}{r}{% regular weight symbol
+ \StrBehind{#1}{r}[\@tempdecoglyph]{\@decoglyph\symbol{\@tempdecoglyph}}%
+ }{}%
+ \IfBeginWith{#1}{l}{% light weight symbol
+ \StrBehind{#1}{l}[\@tempdecoglyph]{\@decoglypha\symbol{\@tempdecoglyph}}%
+ }{}%
+ \IfBeginWith{#1}{e}{% extra light weight symbol
+ \StrBehind{#1}{e}[\@tempdecoglyph]{\@decoglyphb\symbol{\@tempdecoglyph}}%
+ }{}%
+ \IfBeginWith{#1}{t}{% thin weight symbol
+ \StrBehind{#1}{t}[\@tempdecoglyph]{\@decoglyphc\symbol{\@tempdecoglyph}}%
+ }{}%
+ \else%
+ ~% non-breaking space, if no decofont
+ \fi%
+}%
+%%
+
+%% \memo{} does not print or save its argument.
+% Useful when you wish to put a note to yourself in the *.tex document.
+% Not the same as % comment, because anything after the braces will print.
+\long\gdef\memo#1{}
+%%
+
+%% \stake is like \strut, but does not occupy uch vertical space.
+\gdef\stake{\rule{0pt}{1pt}} % placeholder
+%%
+
+%% \smcp{} and \textsc{} small caps (Open Type) and \allsmcp{}:
+\DeclareDocumentCommand \smcp { +m } {% lowercase to small caps
+ {\addfontfeature{Letters=SmallCaps}#1}%
+}
+\ExplSyntaxOn
+\DeclareDocumentCommand \allsmcp { +m } {% lowercase+uppercase to small caps
+ \fontspec_if_feature:nTF {c2sc}{%
+ {\addfontfeatures{Letters=UppercaseSmallCaps, Letters=SmallCaps}#1}%
+ }{%
+ {\addfontfeature{Letters=SmallCaps}\MakeLowercase{#1}}%
+ }%
+ }
+\ExplSyntaxOff
+\let\textsc\smcp\relax % unified
+\let\oldscshape\scshape\relax % in case needed later
+\let\scshape\smcp\relax % unified
+\providecommand\FirstLineFont{\smcp} % package `magaz'
+\renewcommand\FirstLineFont{\smcp}
+%%
+
+%% `novel' class normally allows only black or grayscale text on white paper.
+%% In draft mode, option `shademargins` provides light gray margins,
+%% but still black text on white paper.
+%% Just in case `xcolor' re-defines its internals, to prevent code bomb:
+\ProvideDocumentCommand\@declaredcolor { m } {}
+\ProvideDocumentCommand\@undeclaredcolor { o m } {}
+% For convenience:
+\definecolor[named]{gray1}{gray}{0.15} % ten percent gray, etc.
+\definecolor[named]{gray2}{gray}{0.25}
+\definecolor[named]{gray3}{gray}{0.33}
+\definecolor[named]{gray4}{gray}{0.4}
+\definecolor[named]{gray5}{gray}{0.5}
+\definecolor[named]{gray6}{gray}{0.6}
+\definecolor[named]{gray7}{gray}{0.68}
+\definecolor[named]{gray8}{gray}{0.75}
+\definecolor[named]{gray9}{gray}{0.87}
+%%
+% This code is slightly modified from package `etextools' by Florent Chervet.
+% Its license: "This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3 of this
+% license or (at your option) any later version."
+% My rationale for not simply loading the package: Other parts of the package
+% generate warning messages, but the warnings do not apply in `novel'
+% Also, I might wish to hack the code at some point.
+\newcount\nov@ettl@fter
+\newrobustcmd\nov@AfterGroup{%
+ \@ifstar{\nov@ettl@AfterGroup\@firstofone}{\nov@ettl@AfterGroup\unexpanded}%
+}
+\newrobustcmd\nov@ettl@AfterGroup[2]{%
+\csxdef{nov@ettl@fterGroup\number\numexpr\the\nov@ettl@fter+1}%
+{\global\csundef{nov@ettl@fterGroup\number\numexpr\the\nov@ettl@fter+1}#1{#2}}%
+\global\advance\nov@ettl@fter\@ne%
+\expandafter\aftergroup\csname nov@ettl@fterGroup\the\nov@ettl@fter\endcsname%
+}
+%% End code from `etextools`.
+
+%% \flexbox based on code by Werner at tex.stackexchange.com, CC-by-sa-3.0:
+% Optional first argument is minimum width of box.
+% Second argument is contents of box.
+% Box width will be the greater of #1 or the width of #2.
+\newcommand{\flexbox}[2][\parindent]{%
+ \settowidth{\@tempLength}{#2}%
+ \ifdimcomp{\@tempLength}{<}{#1}{\makebox[#1][l]{#2}}{#2}%
+}
+%%
+
+%% \bigemdash inspired by code by RTBarnard at stackoverflow.com, CC-by-sa-3.0:
+% Allows a rule of variable length to fill available space at its right.
+% There must be a "right-hand limit" imposed by something, such as by enclosing
+% the rule in a \makebox of known width, or by an immediate \par.
+% Without this limit, rule will be missing (zero width) or excessively long,
+% or an error will result (referring to \leaders).
+% Takes a single optional argument: Comma-separated raise, line thickness.
+% If no argument or empty, defaults to [1,1].
+% Without comma, argument defaults to [argument,1].
+% First number: Scales raise/down. 1 = raise of emdash in typical fonts.
+% Second number: Scales line thickness. 1 = emdash in typical fonts.
+% NOTE: Built-in TeX PDF viewer might show the line at slightly incorrect
+% width and height. Best seen in a "real" PDF viewer.
+\DeclareDocumentCommand \bigemdash { O{1,1} }
+ {%
+ \ifthenelse{\equal{#1}{}\OR\equal{#1}{\space}}{%
+ \def\@myargsi{1,1}}{\def\@myargsi{#1}%
+ }%
+ \StrDel{\@myargsi}{\space}[\@myargs]%
+ \StrCut{\@myargs}{,}{\@myraisei}{\@mythicki}%
+ \ifthenelse{\equal{\@myraisei}{}\OR\equal{\@myraisei}{\space}}{%
+ \def\@myraise{1}}{\def\@myraise{\@myraisei}%
+ }%
+ \ifthenelse{\equal{\@mythicki}{}\OR\equal{\@mythicki}{\space}}{%
+ \def\@mythick{1}}{\def\@mythick{\@mythicki}%
+ }%
+ \FPmul{\@myraise}{\@myraise}{0.56}% ex, typical font emdash raise
+ \FPmul{\@mythick}{\@mythick}{0.049}% em, typical font emdash thickness
+ {\leaders\hbox{\rule[\@myraise ex]{1pt}{\@mythick em}}\hfill\stake}%
+ }
+%%
+
+%% \charscale[scale,x,y]{text} and starred version
+% This is an "in-line" means of adjusting font size
+% and position, without changing the baselineskip.
+% If the optional argument is unused or empty, then the text is not scaled
+% or moved, but equivalent to \stake\smash{text}.
+% Up to 3 arguments may be used in the single optional argument.
+% They are separated by commas. Spaces ignored.
+% First argument is scale. Number>=0.5. Default 1. Relative to what the size
+% would otherwise be. May multiply with an already-scaled font.
+% Second and third arguments are x-offset and y-offset, respectively.
+% Offsets are lengths, best measured in em or \nfs for horizontal,
+% and em or \nfs or \nbs for vertical. Default 0pt. Can abbreviate as 0.
+% Posiive offsets are horizontal right, vertical up.
+% Text is "smashed" and may go anywhere, even overlying other text or image.
+% The unstarred command occupies width equal to the scaled text,
+% thus leaving a "hole" where the text would have been.
+% The starred command occupies zero width, thus no hole. Consecutive starred
+% commands, without intervening space, displace from same origin.
+% The text must be on a single line, without break or wrap.
+% Do not use \\ or \par inside \charscale. Sometimes you need \par after it.
+% If the text is in a font other than usual, place the font command
+% outside \charscale, not inside.
+\DeclareDocumentCommand \charscale { s O{1} m } {%
+ % Allows empty or blank to be used, and still provide default values:
+ \ifthenelse{\equal{#2}{}\OR\equal{#2}{\space}}{%
+ \def\@myargs{1}%
+ }{%
+ \def\@myargs{#2}%
+ }%
+ \StrDel{\@myargs}{\space}[\@myargsns]% needs {\space} not { }
+ \StrCut{\@myargsns}{,}{\@myscalet}{\@mycoord}%
+ \ifthenelse{\equal{\@myscalet}{}}{%
+ \def\@myscale{1}%
+ }{%
+ \def\@myscale{\@myscalet}%
+ }%
+ \FPmax{\@myscale}{\@myscale}{0.5}% not permitted below this scale
+ \StrCut{\@mycoord}{,}{\@myxt}{\@myyt}%
+ \ifthenelse{\equal{\@myxt}{}\OR\equal{\@myxt}{0}}{%
+ \def\@myx{0pt}%
+ }{%
+ \def\@myx{\@myxt}%
+ }%
+ \ifthenelse{\equal{\@myyt}{}\OR\equal{\@myyt}{0}}{%
+ \def\@myy{0pt}%
+ }{%
+ \def\@myy{\@myyt}%
+ }%
+ \IfBooleanTF{#1}%
+ {% starred
+ \ifvmode\else\unskip\fi%
+ \stake\makebox[0pt][l]{%
+ \smash{\hspace{\@myx}\raisebox{\@myy}{\scalebox{\@myscale}{#3}}}%
+ }%
+ }{% unstarred
+ \stake\makebox[0pt][l]{%
+ \smash{\hspace{\@myx}\raisebox{\@myy}{\scalebox{\@myscale}{#3}}}%
+ }%
+ \smash{\phantom{\scalebox{\@myscale}{#3}}}%
+ }%
+ }% end \charscale
+%%
+
+
+% Note that \savepos is a luatex primitive, not a macro from gridset package.
+% Length \TotalYpos is measured from the very bottom of the page,
+% upward to the baseline of non-existent "line zero" in main text.
+% The first printed main text line is line 1.
+% Neither header nor footer influence this.
+\newlength\TotalYpos
+\gdef\@GetInitialYpos{% called by `novel.cls' \AtEndPreamble
+ \begingroup%
+ \savepos%
+ \protected@write\@auxout{}{%
+ \protect\@TotalYpos{\noexpand\number\lastypos}%
+ }%
+ \endgroup%
+}
+%
+\gdef\@TotalYpos#1{\gsetlength\TotalYpos{#1sp}}
+%
+
+
+%%
+\newlength\PosTolerance % How close is close enough?
+\setlength\PosTolerance{0.0625pt} % should be good enough
+%%
+
+
+%% Environment parascale. Scales one or more paragraphs. Modified in v. 1.52.
+% Warns when (as is often the case) the line after \end{parascale}
+% will be off grid. Then, add some \vspace just before \end{parascale}.
+\newenvironment{parascale}[1][1]{% optional argument is scale, default 1.
+ \FPmax{\@mytempDetailsN}{#1}{0.5}% must be at least half normal.
+ \FPmul{\@mytempDetailsFontN}{\@mytempDetailsN}{\strip@pt\@SetFontSize}%
+ \FPround{\@mytempDetailsFontN}{\@mytempDetailsFontN}{2}%
+ \FPmul{\@mytempDetailsSkipN}{\@mytempDetailsN}{\strip@pt\baselineskip}%
+ \FPround{\@mytempDetailsSkipN}{\@mytempDetailsSkipN}{2}%
+ \FPsub{\@mytempSkipN}{\strip@pt\baselineskip}{\@mytempDetailsSkipN}%
+ \vspace{\@mytempSkipN pt}% puts first scaled line at normal baseline
+ \begingroup%
+ \fontsize{\@mytempDetailsFontN pt}{\@mytempDetailsSkipN pt}\selectfont%
+ \ignorespaces%
+}{%
+ \par\endgroup%
+ \vspace{-\nbs}%
+ \leavevmode\getParapos\par% detects if following line will be off-grid
+ \vspace{0.002\nbs plus 0pt minus 0.2pt}% math fudge factor, in case of roundoff
+}
+%
+\gdef\getParapos{%
+ \begingroup%
+ \savepos%
+ \protected@write\@auxout{}{%
+ \protect\@getParapos{\noexpand\number\lastypos}{\thepage}%
+ }%
+ \endgroup%
+}
+%
+\newlength\CurrentParapos
+\gdef\@getParapos#1#2{} % initialized to nothing, when reading aux at beginning
+\gdef\@RedefineParapos{ % called by `novel.cls' \AtBeginDocument
+ \gdef\@getParapos##1##2{% numerical position sp, page
+ \gsetlength\CurrentParapos{##1sp}% measured up from very bottom of page.
+ % Now change it, to measure downward from "line zero" of main text:
+ \gsetlength\CurrentParapos{\TotalYpos-\CurrentParapos}% calc package.
+ \FPdiv{\ParaHowdown}{\strip@pt\CurrentParapos}{\strip@pt\nbs}% package fp
+ \FPtrunc{\ParaLinesdown}{\ParaHowdown}{0}% integer number of lines down
+ \FPsub{\ParaResidual}{\ParaHowdown}{\ParaLinesdown}% portion of line
+ \FPdiv{\@PosTolerance}{\strip@pt\PosTolerance}{\strip@pt\nbs}%
+ \gdef\ParaComplain{yes}%
+ \FPifgt{\@PosTolerance}{\ParaResidual}%
+ \gdef\ParaComplain{no}% within tolerance
+ \fi%
+ \FPsub{\ParaDeficit}{\strip@pt\nbs}{\ParaResidual}%
+ \FPifgt{\@PosTolerance}{\ParaDeficit}%
+ \gdef\ParaComplain{no}%
+ \fi%
+ \FPsub{\ParaResidual}{1}{\ParaResidual}%
+ \FPifgt{\@PosTolerance}{\ParaResidual}%
+ \gdef\ParaComplain{no}% within tolerance
+ \fi%
+ \FPifgt{\@PosTolerance}{\ParaDeficit}%
+ \gdef\ParaComplain{no}%
+ \fi%
+ \FPround{\ParaResidual}{\ParaResidual}{3}%
+ \FPclip{\ParaResidual}{\ParaResidual}%
+ \ifthenelse{\equal{\ParaComplain}{yes}}{%
+ \ClassWarning{novel}{Line after parascale may be off-grid, page ##2. ^^J%
+ Appears to be \ParaResidual\string\nbs\space higher than expected.}%
+ }{}%
+ }
+} % end @RedefineParapos
+%%
+
+
+%% Environment toc (alternative table of contents):
+% optional argument: additional vspace (\nbs) after each \tocitem entry.
+% required: LR margin increase, to narrow the table (0pt = full textwidth).
+\newlength\@tocnumwid
+\newlength\@tocskip
+\newenvironment{toc}[2][0]{%
+ \begin{adjustwidth}{#2}{#2}%
+ \begingroup%
+ \setlength\parindent{0pt}% local
+ \setlength\@tocnumwid{\widthof{00.~}}% local
+ \setlength\@tocskip{#1\nbs}% local
+}{%
+ \endgroup%
+ \end{adjustwidth}\par%
+}%
+% \tocitem[number]{description}{page} provides a one-line table entry in toc.
+% optional number might be chapter number. Can use ~ to offset.
+% unstarred: distance between description and page is not decorated.
+% starred (better): distance between description and page has dotted line.
+\newcommand\tocitem{\@ifstar\@tocitemst\@tocitemns}
+\newcommand\@tocitemst[3][]{%
+ \ifthenelse{\equal{#1}{}}{}{%
+ \ifthenelse{\equal{#1}{~}}{%
+ \makebox[\@tocnumwid][l]{~}%
+ }{%
+ \makebox[\@tocnumwid][l]{#1.}%
+ }%
+ }%
+ #2\,%
+ \leaders\hbox to 0.3em{\hfil.\hfil}\hfill% Thanks to user daniel-j via GitHub.
+ \,#3\par\vspace{\@tocskip}%
+}%
+%
+\newcommand\@tocitemns[3][]{%
+ \ifthenelse{\equal{#1}{}}{}{%
+ \ifthenelse{\equal{#1}{~}}{%
+ \makebox[\@tocnumwid][l]{~}%
+ }{%
+ \makebox[\@tocnumwid][l]{#1.}%
+ }%
+ }%
+ #2%
+ \hfill%
+ #3\par\vspace{\@tocskip}%
+}%
+%% end toc and \tocitem.
+
+%% legalese environment. Certain info, such as Copyright page, customarily is
+% neither justified nor hyphenated. Can be used wherever desired, of course.
+\newenvironment{legalese}
+{\raggedright\hyphenpenalty=10000\exhyphenpenalty=10000}
+{}
+%
+\gdef\hangleft#1{% places content to left of usual position.
+ \setlength\@tempLength{\widthof{#1}}% local
+ \stake\hspace{-\@tempLength}#1%
+}
+%%
+
+%% \showlength[decimal places]{length}{units}
+% Returns length as a string with the units, but does not change the length.
+% length is any existing length
+% units may be pt, bp, mm, cm, in
+% decimal places for rounding (0=integer, 1=one decimal point, etc.)
+% Example: \showlength[3]{17bp}{in} returns 0.236in
+\newcommand\showlength[3][]{%
+ \setlength\@tempLength{#2}%
+ \def\@tempLengthN{\strip@pt\@tempLength}%
+ \ifthenelse{\equal{#3}{bp}}{%
+ \FPmul{\@tempLengthN}{\@tempLengthN}{0.99626401}%
+ }{}%
+ \ifthenelse{\equal{#3}{mm}}{%
+ \FPmul{\@tempLengthN}{\@tempLengthN}{0.351459804}%
+ }{}%
+ \ifthenelse{\equal{#3}{cm}}{%
+ \FPmul{\@tempLengthN}{\@tempLengthN}{0.0351459804}%
+ }{}%
+ \ifthenelse{\equal{#3}{in}}{%
+ \FPmul{\@tempLengthN}{\@tempLengthN}{0.013837}%
+ }{}%
+ \ifthenelse{\equal{#1}{}}{}{\FPround{\@tempLengthN}{\@tempLengthN}{#1}}%
+ \@tempLengthN{#3}%
+} %
+%% end \showlength
+
+%% \lnum for lining numbers.
+\gdef\lnum#1{{\addfontfeature{Numbers=Lining}#1}}
+%%
+
+
+%% For developer use: prints a number of yada yada lines.
+% Starred version adds extra smashed lines above and below.
+\newcount\yadacurrentcount
+\newcount\yadaendcount
+\DeclareDocumentCommand\novelyadayada { s O{1} }{%
+ \yadacurrentcount=1%
+ \yadaendcount=#2%
+ \ifthenelse{\equal{#2}{0}}{}{%
+ \IfBooleanTF{#1}{%
+ \def\@yadadblup{\charscale*[1,\normalparindent,2\nbs]{Dbl Raised yada}}%
+ \def\@yadaup{\charscale*[1,\normalparindent,\nbs]{Raised yada}}%
+ \def\@yadadown{%
+ \ifnum\yadacurrentcount=\yadaendcount%
+ \charscale*[1,\normalparindent,-\nbs]{Dropped yada}%
+ \fi%
+ }%
+ \def\@yadadbldown{%
+ \ifnum\yadacurrentcount=\yadaendcount%
+ \charscale*[1,\normalparindent,-2\nbs]{Dropped yada}%
+ \fi%
+ }%
+ }{%
+ \def\@yadadblup{}%
+ \def\@yadaup{}%
+ \def\@yadadown{}%
+ \def\@yadadbldown{}%
+ }%
+ \loop%
+ \noindent\@yadadblup\@yadaup\@yadadown\@yadadbldown%
+ \makebox[\normalparindent][l]{\the\yadacurrentcount.}%
+ Lotta yada.\par
+ \def\@yadaup{}%
+ \def\@yadadblup{}%
+ \advance\yadacurrentcount 1%
+ \ifnum\yadacurrentcount<\yadaendcount%
+ \repeat%
+ }%
+}
+%%
+
+
+%% New in version 1.50: two columns, cannot cross page break.
+%% \sidebyside[a,b,c,d]{column 1 content}{column 2 content} % a,b,c,d lengths
+% a = left margin to left edge of left column (left indent)
+% b = left margin to right edge of left column ( = a + column width)
+% c = left margin to left edge of right column ( = a + b + gap)
+% d = left margin to right edge of right column ( = textwidth - right indent)
+% Thus 0pt <= a < b < c < d <= \textwidth.
+% Default: no indents, equal column widths, separated by \normalparindent.
+\DeclareDocumentCommand\sidebyside { O{} +m +m } {% no ExplSyntax, no more %:
+ \StrDel{#1}{\space}[\@argsns]
+ \StrCut{\@argsns}{,}{\@argsone}{\@argsothera}
+ \StrCut{\@argsothera}{,}{\@argstwo}{\@argsotherb}
+ \StrCut{\@argsotherb}{,}{\@argsthree}{\@argsfour}
+ \ifthenelse{\equal{\@argsone}{}}{%
+ \def\@sbsll{0pt}
+ }{%
+ \def\@sbsll{\@argsone}
+ }%
+ \setlength\@tempLength{0.5\textwidth-0.5\normalparindent}
+ \ifthenelse{\equal{\@argstwo}{}}{%
+ \edef\@sbslr{\the\@tempLength}
+ }{%
+ \edef\@sbslr{\@argstwo}
+ }%
+ \setlength\@tempLength{0.5\textwidth+0.5\normalparindent}
+ \ifthenelse{\equal{\@argsthree}{}}{%
+ \edef\@sbsrl{\the\@tempLength}
+ }{%
+ \edef\@sbsrl{\@argsthree}
+ }%
+ \ifthenelse{\equal{\@argsfour}{}}{%
+ \edef\@sbsrr{\the\textwidth}
+ }{%
+ \edef\@sbsrr{\@argsfour}
+ }%
+ \null\vspace{-\baselineskip}
+ \begin{adjustwidth}{\@sbsll}{\dimexpr\textwidth-\@sbsrr}
+ \noindent\begin{minipage}[t]{\dimexpr\@sbslr-\@sbsll}
+ \strut #2\strut
+ \end{minipage}\hspace{\normalparindent}\begin{minipage}[t]{\dimexpr\@sbsrr-\@sbsrl}
+ \strut #3\strut
+ \end{minipage}
+ \end{adjustwidth}
+ \null\vspace{-\baselineskip}
+} %
+%% end \sidebyside
+
+
+
+%% Some things must wait until after layout calculations:
+\gdef\@ActivateTextLengths{% called by `novel.cls' \AtEndPreamble
+ % Store some normal values (main font) for global use in document body:
+ \newlength\nfs % abbreviation for normal font point size
+ \gsetlength\nfs{\@SetFontSize}
+ \newlength\nbs % abbreviation for normal baselineskip
+ \gsetlength\nbs{\baselineskip}
+ \gsetlength\parindent{1.5em} % may be locally changed
+ \newlength\normalparindent
+ \gsetlength\normalparindent{\parindent}
+ \newlength\normalxheight % height of lowercase x
+ \gsetlength\normalxheight{\heightof{x}}
+ \newlength\normalXheight % height of uppercase X
+ \gsetlength\normalXheight{\heightof{X}}
+ \newlength\normalscxheight % height of small cap x
+ \gsetlength\normalscxheight{\heightof{\textsc{x}}}
+ \newlength\normalAringheight % height of Ã… (usually tallest in Latin-1)
+ \gsetlength\normalAringheight{\heightof{Ã…}}
+ \newlength\normaldescender % depth of lowercase gjpqy
+ \gsetlength\normaldescender{\depthof{gjpqy}}
+}% end \@ActivateTextLengths
+%%
+
+
+%% More things that must wait:
+\gdef\@ActivateTextMacros{% called by `novel.cls' \AtBeginDocument
+ % \forceindent and \backindent perform or remove indent, using \hspace{}.
+ % Rationale: Sometimes \indent and \noindent neutralized by another command.
+ \gdef\forceindent{\ifvmode\else\unskip\fi\stake\hspace{\normalparindent}}
+ \gdef\backindent{\ifvmode\else\unskip\fi\hspace{-\normalparindent}}
+}% end \@ActivateTextMacros
+%%
+
+
+%%
+\endinput
+%%
+%% End of file `novel-TextMacros.sty'.
+
+
diff --git a/macros/luatex/latex/novel/novel-microtype.cfg b/macros/luatex/latex/novel/novel-microtype.cfg
new file mode 100644
index 0000000000..d5bb8e639f
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-microtype.cfg
@@ -0,0 +1,252 @@
+%%
+%% This is file `novel-microtype.cfg', part of `novel' document class.
+%% Modified from file `microtype.cfg' by Robert Allgeyer, 2017-2018.
+%%
+%% Original notice from `microtype.cfg' follows.
+%% Same license for `novel-microtype.cfg'.
+%%
+%% ------------------------------------------------------------------------
+%%
+%% This work may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License, either version 1.3c of this license or (at
+%% your option) any later version. The latest version of this license is in:
+%% http://www.latex-project.org/lppl.txt, and version 1.3c or later is part
+%% of all distributions of LaTeX version 2005/12/01 or later.
+%%
+%% ------------------------------------------------------------------------
+%%
+%% When modifying this file, also change the identification line below.
+%% ------------------------------------------------------------------------
+%%
+\ProvidesFile{novel-microtype.cfg}%
+[2018/01/14 any version. (default microtype configuration for novel class)]
+
+%%% ---------------------------------------------------------------------------
+%%% FONT SETS
+
+\DeclareMicrotypeSet{all}
+ { }
+
+\DeclareMicrotypeSet{allmath}
+ { }
+
+\DeclareMicrotypeSet{alltext}
+ { }
+
+\DeclareMicrotypeSet{allmath-nott}
+ { family = {rm*,sf*} }
+
+\DeclareMicrotypeSet{alltext-nott}
+ { family = {rm*,sf*} }
+
+\DeclareMicrotypeSet{basicmath}
+ { family = {rm*,sf*}, series = {md*} }
+
+\DeclareMicrotypeSet{basictext}
+ { family = {rm*,sf*}, series = {md*}, }
+
+\DeclareMicrotypeSet{smallcaps}
+ { shape = {sc*,si,scit} }
+
+\DeclareMicrotypeSet{normalfont}
+ { font = */*/*/*/* }
+
+%%% ---------------------------------------------------------------------------
+%%% DEFAULT SETS
+
+\DeclareMicrotypeSetDefault[protrusion]{alltext}
+\DeclareMicrotypeSetDefault[expansion] {basictext}
+\DeclareMicrotypeSetDefault[spacing] {basictext}
+\DeclareMicrotypeSetDefault[kerning] {alltext}
+\DeclareMicrotypeSetDefault[tracking] {smallcaps}
+
+%%% ---------------------------------------------------------------------------
+%%% FONT VARIANTS AND ALIASES
+
+\DeclareMicrotypeVariants{x,j,w,a,d,0,1}
+
+\DeclareMicrotypeAlias{lmr} {Latin Modern Roman}
+\DeclareMicrotypeAlias{lmm} {Latin Modern Math}
+
+%%% ---------------------------------------------------------------------------
+%%% INTERACTION WITH THE `babel' PACKAGE
+
+\DeclareMicrotypeBabelHook
+ {english,UKenglish,british,USenglish,american}
+ {kerning=, spacing=nonfrench}
+
+\DeclareMicrotypeBabelHook
+ {french,francais,acadian,canadien}
+ {kerning=french, spacing=}
+
+\DeclareMicrotypeBabelHook
+ {turkish}
+ {kerning=turkish, spacing=}
+
+%%% ---------------------------------------------------------------------------
+%%% CHARACTER INHERITANCE
+
+\DeclareCharacterInheritance
+ { encoding = * }
+ { A = {\`A,\'A,\^A,\~A,\"A,\r A,\k A,\u A},
+ a = {\`a,\'a,\^a,\~a,\"a,\r a,\k a,\u a},
+ C = {\'C,\c C,\v C},
+ c = {\'c,\c c,\v c},
+ D = {\v D,\DH},
+ d = {\v d,\dj},
+ E = {\`E,\'E,\^E,\"E,\k E,\v E},
+ e = {\`e,\'e,\^e,\"e,\k e,\v e},
+ G = {\u G},
+ g = {\u g},
+ I = {\`I,\'I,\^I,\"I,\.I},
+ i = {\`i,\'i,\^i,\"i,\i},
+ L = {\L,\'L,\v L},
+ l = {\l,\'l,\v l},
+ N = {\'N,\~N,\v N},
+ n = {\'n,\~n,\v n},
+ O = {\O,\`O,\'O,\^O,\~O,\"O,\H O},
+ o = {\o,\`o,\'o,\^o,\~o,\"o,\H o},
+ R = {\'R,\v R},
+ r = {\'r,\v r},
+ S = {\'S,\c S,\v S}, % \SS
+ s = {\'s,\c s,\v s},
+ T = {\c T,\v T},
+ t = {\c t,\v t},
+ U = {\`U,\'U,\^U,\"U,\H U,\r U},
+ u = {\`u,\'u,\^u,\"u,\H u,\r u},
+ Y = {\'Y,\"Y},
+ y = {\'y,\"y},
+ Z = {\'Z,\.Z,\v Z},
+ z = {\'z,\.z,\v z},
+ }
+
+%%% ---------------------------------------------------------------------------
+%%% TRACKING/LETTERSPACING
+
+\SetTracking
+ [ name = default,
+ no ligatures = {f, T} ]
+ { encoding = * }
+ { }
+
+%%% ---------------------------------------------------------------------------
+%%% EXPANSION
+
+\SetExpansion
+ [ name = default ]
+ { encoding = * }
+ {
+ A = 500, a = 700,
+ \AE = 500, \ae = 700,
+ B = 700, b = 700,
+ C = 700, c = 700,
+ D = 500, d = 700,
+ E = 700, e = 700,
+ F = 700,
+ G = 500, g = 700,
+ H = 700, h = 700,
+ K = 700, k = 700,
+ M = 700, m = 700,
+ N = 700, n = 700,
+ O = 500, o = 700,
+ \OE = 500, \oe = 700,
+ P = 700, p = 700,
+ Q = 500, q = 700,
+ R = 700,
+ S = 700, s = 700,
+ U = 700, u = 700,
+ W = 700, w = 700,
+ Z = 700, z = 700,
+ 2 = 700,
+ 3 = 700,
+ 6 = 700,
+ 8 = 700,
+ 9 = 700,
+ }
+
+
+
+%%% ---------------------------------------------------------------------------
+%%% PROTRUSION
+
+\SetProtrusion
+ [ name = default ]
+ { encoding = * }
+ {
+ A = {50,50},
+ \AE = {50,50},
+ F = { ,50},
+ J = {50, },
+ K = { ,50},
+ L = { ,50},
+ T = {50,50},
+ V = {50,50},
+ W = {50,50},
+ X = {50,50},
+ Y = {50,50},
+ k = { ,50},
+ r = { ,50},
+ v = {50,50},
+ w = {50,50},
+ x = {50,50},
+ y = { ,50},
+ 1 = {50,50},
+ 4 = {50,50},
+ 7 = {50,50},
+ . = { ,200},
+ {,}= { ,200},
+ : = { ,200},
+ ; = { ,200},
+ ! = { ,100},
+ ? = { ,100},
+ @ = {50,50},
+ ~ = {200,200},
+ \% = {50,50},
+ * = {200,200},
+ + = {200,200},
+ ( = {100, },
+ ) = { ,200},
+ / = {100,200},
+ - = {200,200},
+ \textendash = {200,200}, \textemdash = {150,150},
+ \textquoteleft = {200, }, \textquoteright = { ,200},
+ \textquotedblleft = {200, }, \textquotedblright = { ,200},
+ }
+
+
+\SetProtrusion
+ [ name = it-default, ]
+ { encoding = * ,
+ shape = {it,sl} }
+ {
+ . = { ,500},
+ {,}= { ,500},
+ : = { ,300},
+ ; = { ,300},
+ & = {50,50},
+ \% = {100, },
+ * = {200,200},
+ + = {150,200},
+ @ = {50,50},
+ ~ = {150,150},
+ ( = {200, },
+ ) = { ,200},
+ / = {100,200},
+ - = {300,300},
+ \textendash = {200,200}, \textemdash = {150,150},
+ \textquoteleft = {400,200}, \textquoteright = {400,200},
+ \textquotedblleft = {400,200}, \textquotedblright = {400,200},
+ \textbackslash = {100,200},
+ \quotesinglbase = {300,700}, \quotedblbase = {400,500},
+ \guilsinglleft = {400,400}, \guilsinglright = {300,500},
+ \guillemotleft = {300,300}, \guillemotright = {300,300},
+ \textexclamdown = {100, }, \textquestiondown = {200, },
+ \textbraceleft = {200,100}, \textbraceright = {200,200},
+ }
+
+
+
+\endinput
+%%
+%% End of file `novel-microtype.cfg'.
+
diff --git a/macros/luatex/latex/novel/novel-pdfx.sty b/macros/luatex/latex/novel/novel-pdfx.sty
new file mode 100644
index 0000000000..4af4ea09f0
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-pdfx.sty
@@ -0,0 +1,517 @@
+%%
+%% This is file `novel-pdfx.sty', part of `novel' document class.
+%% Copyright (c) 2017-2018 Robert Allgeyer.
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% ----------------------------------------------------------------------------
+%%
+%% File `novel-pdfx.sty' uses code, directly copied or modified,
+%% from file `pdfx.sty', part of LaTeX package `pdfx': Copyright (c) 2015,
+%% CV Radhakrishnan, Han The Thanh, Ross Moore, Peter Selinger.
+%% Licensed LPPL 1.2+.
+%%
+%% ----------------------------------------------------------------------------
+%%
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesFile{novel-pdfx.sty}%
+[2018/04/26 v1.52 LaTeX file (PDF/X support for novel class)]
+% This package supports, and is part of, class `novel'.
+% No support for anything but LuaLaTeX.
+
+% DO NOT ATTEMPT TO USE OUTSIDE `NOVEL' DOCUMENT CLASS.
+% Reason: Other files in this class define stuff that is used here.
+
+%%
+%% This file is loaded \AtEndPreamble.
+%%
+
+
+%% Preliminary tests for cases forbidding PDF/X:
+\ifdraftdoc
+ \global\@pdfxISofftrue
+\fi
+\if@sandbox
+ \global\@pdfxISofftrue
+\fi
+%
+\gdef\@AlertNoPDFX{% called by `novel.cls' AtBeginDocument
+ \if@pdfxSEToff\else
+ \ifdraftdoc
+ \typeout{^^JClass `novel' Alert: No PDF/X in draft mode. ^^J%
+ Your document was processed with \string\SetPDFX{off}. ^^J}%
+ \fi
+ \if@sandbox
+ \typeout{^^JClass `novel' Alert: No PDF/X with sandbox option. ^^J%
+ Your document was processed with \string\SetPDFX{off}. ^^J}%
+ \fi
+ \fi
+} % end @AlertNoPDFX
+%%
+
+
+% Hyperref options for PDF/X with LuaLaTeX:
+\def\pdfx@pdfX@opts@luatex{%
+ draft,pdfpagemode=UseNone,bookmarks=false,hyperfootnotes=false,%
+ hyperindex=false,implicit=false,pdfversion=1.\the\pdfminorversion,%
+ pdfpagelabels=true,pageanchor=false,pdfstartview=}
+%
+\RequirePackage[\pdfx@pdfX@opts@luatex]{hyperref}
+%
+\hypersetup{pdfencoding=auto}
+\expandafter\ifx\csname KV@Hyp@psdextra\endcsname\relax\else
+ \hypersetup{psdextra}
+\fi
+\Hy@bookmarksfalse
+%
+\ifthenelse{\equal{\@title}{} \OR \equal{\@title}{ }}{%
+ \global\@HasTitlefalse}{\global\@HasTitletrue%
+}
+\ifthenelse{\equal{\@title}{IMPORTANT: Provide Book Title}}{%
+ \ClassWarning{novel}{^^JDid not provide title using \string\SetTitle. ^^J%
+ Default used: `IMPORTANT: Provide Book Title'. Be sure to change it! ^^J}%
+}{}%
+%
+% Sanity check: If title is missing at this step, then compliance must be off:
+\if@pdfxISoff\else
+ \if@HasTitle\else
+ \ClassError{novel}{PDF/X requires non-empty \string\SetTitle\space}%
+ {Unless \string\SetPDFX\space is off, must use \string\SetTitle\space ^^J%
+ with non-empty title. Blank space counts as empty.}%
+ \fi
+\fi
+%
+\if@HasTitle\else
+ \ClassWarning{novel}{^^JYour file has been compiled without standard ^^J%
+ PDF internal metadata, such as the title. This is allowable, and in ^^J%
+ some cases desirable. But in most cases it is not what you intended. ^^J%
+ If you want title and other metadata to be in PDF internal metadata, ^^J%
+ then you must place them prior to the \string\SetPDFX. ^^J}
+\fi
+%
+\expandafter\ifx\csname pdfresetpageorigin\endcsname\relax\else
+ \pdfresetpageorigin=0
+\fi
+\edef\pdfcreationdate{\pdfcreationdate}%
+\let\pdfx@mdfivesum\pdf@mdfivesum
+%
+
+
+
+%% CALCULATE AND SPECIFY CROPBOX AND TRIMBOX
+%% ----------------------------------------------------------------------------
+%%
+% The MediaBox is automatically provided, so there is no need to write
+% MediaBox in /pdfInfo (because it would be a duplicate).
+% TrimBox is always necessary for PDF/X.
+% Although CropBox is not necessary, it seems that it is often written
+% by professional PDF software. For that reason, and for proper centering
+% of TrimBox when MediaBox is larger, CropBox is created (= MediaBox).
+%
+\newcommand\@myMWN{\strip@pt\paperwidth}
+\FPmul{\@myMWN}{\@myMWN}{0.99626401}
+\FPround{\@myMWN}{\@myMWN}{3}
+\FPclip{\@myMWN}{\@myMWN}
+\newcommand\@myMHN{\strip@pt\paperheight}
+\FPmul{\@myMHN}{\@myMHN}{0.99626401}
+\FPround{\@myMHN}{\@myMHN}{3}
+\FPclip{\@myMHN}{\@myMHN}
+\newcommand\@myTWN{\strip@pt\@TrimWidth}
+\FPmul{\@myTWN}{\@myTWN}{0.99626401}
+\FPround{\@myTWN}{\@myTWN}{3}
+\newcommand\@myTHN{\strip@pt\@TrimHeight}
+\FPmul{\@myTHN}{\@myTHN}{0.99626401}
+\FPround{\@myTHN}{\@myTHN}{3}
+%
+\FPsub{\@myTWorigin}{\@myMWN}{\@myTWN}
+\FPmul{\@myTWorigin}{\@myTWorigin}{0.5}
+\FPround{\@myTWorigin}{\@myTWorigin}{3}
+\FPadd{\@myTWcorner}{\@myTWorigin}{\@myTWN}
+\FPround{\@myTWcorner}{\@myTWcorner}{3}
+\FPsub{\@myTHorigin}{\@myMHN}{\@myTHN}
+\FPmul{\@myTHorigin}{\@myTHorigin}{0.5}
+\FPround{\@myTHorigin}{\@myTHorigin}{3}
+\FPadd{\@myTHcorner}{\@myTHorigin}{\@myTHN}
+\FPround{\@myTHcorner}{\@myTHcorner}{3}
+%
+\FPclip{\@myTWorigin}{\@myTWorigin}
+\FPclip{\@myTWcorner}{\@myTWcorner}
+\FPclip{\@myTHorigin}{\@myTHorigin}
+\FPclip{\@myTHcorner}{\@myTHcorner}
+%
+\newcommand\novel@CropBox{%
+ \if@cropview%
+ /CropBox[\@myTWorigin\space\@myTHorigin\space\@myTWcorner\space\@myTHcorner]%
+ \else%
+ /CropBox[0\space0\space\@myMWN\space\@myMHN]%
+ \fi%
+}
+%
+\newcommand\novel@TrimBox{%
+ /TrimBox[\@myTWorigin\space\@myTHorigin\space\@myTWcorner\space\@myTHcorner]%
+}
+%
+% New in version 1.2: BleedBox, only for cover art. Same size as MediaBox.
+\newcommand\novel@BleedBox{%
+ \if@coverart%
+ /BleedBox[0\space0\space\@myMWN\space\@myMHN]%
+ \fi%
+}
+%
+\begingroup\edef\next{%
+\endgroup\pdfpageattr{\novel@CropBox^^J\novel@BleedBox^^J\novel@TrimBox}}\next
+%
+%% End calculate and specify TrimBox.
+
+
+
+%% GENERAL PDF INTERNAL METADATA PREPARATION
+%% ----------------------------------------------------------------------------
+%
+% Create hashes that will be used for uuid data. Does not need to be fancy:
+\edef\xmp@docid{\pdfx@mdfivesum{jobname.pdf}}
+\edef\xmp@instid{\pdfx@mdfivesum{\pdfcreationdate}}
+%
+%% End general PDF in internal metadata preparation.
+
+
+
+%% PREPARATION OF XMP METADATA
+%% ----------------------------------------------------------------------------
+%% Data prepared here, will later be inserted into the XMP packet template,
+%% then the processed template will be incuded in the PDF.
+%% XMP metadata is in utf-8 encoding.
+%
+% Make the XMP look pretty:
+\def\pad@ii{\space\space}
+\def\pad@iv{\pad@ii\pad@ii}
+\def\pad@vi{\pad@iv\pad@ii}
+\def\pad@viii{\pad@vi\pad@ii}
+\def\pad@x{\pad@viii\pad@ii}
+\def\pad@xii{\pad@x\pad@ii}
+\def\pad@xiv{\pad@xii\pad@ii}
+\def\pad@xvi{\pad@xiv\pad@ii}
+\def\pad@xviii{\pad@xvi\pad@ii}
+\def\pad@xx{\pad@xviii\pad@ii}
+\def\pad@xxxii{\pad@xvi\pad@xvi}
+\def\pad@lxiv{\pad@xxxii\pad@xxxii}
+\def\pad@cxxviii{\pad@lxiv\pad@lxiv}
+\def\pad@cclvi{\pad@cxxviii\pad@cxxviii}
+\def\pad@dxii{\pad@cclvi\pad@cclvi}
+%
+% Frankly, I am not sure if all this rigamarole is necessary, but it works!
+% Here, portions of XMP code are prepared. Later, they will be inserted
+% into the XMP packet template.
+\gdef\@titleString{
+ \pad@vi<dc:title>^^J
+ \pad@viii<rdf:Alt>^^J
+ \pad@x<rdf:li xml:lang="x-default">\@title</rdf:li>^^J
+ \pad@viii</rdf:Alt>^^J
+ \pad@vi</dc:title>^^J
+}
+%
+\ifthenelse{\equal{\@author}{}}{
+ \gdef\@authorString{}
+}{
+ \gdef\@authorString{
+ \pad@vi<dc:creator>^^J
+ \pad@viii<rdf:Bag>^^J
+ \pad@x<rdf:li>\@author</rdf:li>^^J
+ \pad@viii</rdf:Bag>^^J
+ \pad@vi</dc:creator>^^J
+ }
+}
+%
+\def\@documentID{uuid:\xmp@docid}
+\def\@instanceID{uuid:\xmp@instid}
+%
+\def\@pdfVersion{1.\the\pdfminorversion}
+%
+\if@pdfxISoff
+ \gdef\@verconfString{}%
+\else
+ \gdef\@verconfString{
+ \pad@vi<pdfx:GTS_PDFXVersion>\@PDFXversion</pdfx:GTS_PDFXVersion>^^J
+ \if@HasConformance
+ \pad@vi<pdfx:GTS_PDFXConformance>%
+ \@PDFXconformance</pdfx:GTS_PDFXConformance>^^J
+ \fi
+ }
+\fi
+%
+\if@pdfxISoff
+ \gdef\@pdfidString{}%
+\else
+ \gdef\@pdfidString{
+ \pad@vi<pdfxid:GTS_PDFXVersion>\@PDFXversion</pdfxid:GTS_PDFXVersion>^^J
+ }
+\fi
+%
+\ifthenelse{\equal{\@novelApplication}{} \OR \equal{\@novelApplication}{ }}{
+ \gdef\@applicationString{}%
+}{
+ \gdef\@applicationString{\pad@vi<xmp:CreatorTool>%
+ \@novelApplication</xmp:CreatorTool>^^J}%
+}
+%
+\ifthenelse{\equal{\@novelProducer}{} \OR \equal{\@novelProducer}{ }}{
+ \gdef\@producerString{}%
+}{
+ \gdef\@producerString{\pad@vi<pdf:Producer>%
+ \@novelProducer</pdf:Producer>^^J}%
+}
+%
+% Calculation of Dates and Times, which must be in a specific format.
+% Each time you process to PDF, the current date/time is used,
+% for all of the several metadata date/time strings.
+\def\xmp@cDate{\pdfx@getYear}
+{\catcode`\D=12 \catcode`\:=12
+ \gdef\pdfx@getYear D:#1#2#3#4{\edef\pdfx@xYear{#1#2#3#4}\pdfx@getMonth}
+}
+\def\pdfx@getMonth#1#2{\edef\pdfx@xMonth{#1#2}\pdfx@getDay}
+\def\pdfx@getDay#1#2{\edef\pdfx@xDay{#1#2}\pdfx@getHour}
+\def\pdfx@getHour#1#2{\edef\pdfx@xHour{#1#2}\pdfx@getMin}
+\def\pdfx@getMin#1#2{\edef\pdfx@xMin{#1#2}\pdfx@getSec}
+\def\pdfx@getSec#1#2{\edef\pdfx@xSec{#1#2}\pdfx@getTZh}
+\def\pdfx@getTZh{\futurelet\pdfx@next\pdfx@getTzh@branches}
+%
+{\catcode`\@=11 \catcode`\Z=12 \catcode`\+=12 \catcode`\-=12 % ends below
+\gdef\pdfx@getTzh@branches{%
+ \ifx\pdfx@next Z\let\pdfx@getTzbranch\pdfx@getTznozone
+ \else\ifx\pdfx@next +\let\pdfx@getTzbranch\pdfx@getTzplus
+ \else\ifx\pdfx@next -\let\pdfx@getTzbranch\pdfx@getTzminus
+ \else\let\pdfx@getTzbranch\pdfx@getTzerror
+ \fi\fi\fi \pdfx@getTzbranch }
+%
+\catcode`\0=12
+\gdef\pdfx@getTznozone Z#1\pdfx@getTzend{%
+ \edef\pdfx@xTzh{+00}\edef\pdfx@xTzm{00}}
+\gdef\pdfx@getTzplus +#1'#2'#3\pdfx@getTzend{%
+ \edef\pdfx@xTzh{+#1}\edef\pdfx@xTzm{#2}%
+ \ifx\relax#2\relax\def\pdfx@xTzm{00}\fi}
+\gdef\pdfx@getTzminus -#1'#2'#3\pdfx@getTzend{%
+ \edef\pdfx@xTzh{-#1}\edef\pdfx@xTzm{#2}%
+ \ifx\relax#2\relax\def\pdfx@xTzm{00}\fi}
+%
+\expandafter\ifx\csname pdfcreationdate\endcsname\relax
+\else
+ \expandafter\expandafter\expandafter\xmp@cDate\pdfcreationdate''\pdfx@getTzend
+ \xdef\pdfx@convDate{\pdfx@xYear\pdfx@xMonth\pdfx@xDay\pdfx@xHour
+ \pdfx@xMin\pdfx@xSec\pdfx@xTzh'\pdfx@xTzm'}%
+ \xdef\xmp@cDate{\pdfx@xYear-\pdfx@xMonth-\pdfx@xDay
+ T\pdfx@xHour:\pdfx@xMin:\pdfx@xSec\pdfx@xTzh:\pdfx@xTzm}%
+\fi
+}% End of \catcode`\@=11 etc.
+\let\@modifyDate\xmp@cDate
+\let\@createDate\xmp@cDate
+\let\@metadataDate\xmp@cDate
+% End dates and times.
+%
+%% End Prepare XMP metadata.
+
+
+
+%% WRITE THE XMP METADATA, UNLESS PDF/X IS OFF OR NO TITLE
+%%-----------------------------------------------------------------------------
+%% Inserts the prepared XMP metadata into XMP packet template, then writes
+%% the result at the start of the PDF, right now, before the document.
+%
+\if@pdfxISoff\else
+ \if@HasTitle
+ \begingroup
+ \makeatletter
+ \input{novel-xmppacket.sty}
+ \global\let\@xmpData\@xmpPacket % from the above file
+ \begingroup
+ \pdfcompresslevel=0
+ \immediate\pdfobj stream attr {/Type /Metadata /Subtype /XML} {\@xmpData}
+ \pdfcatalog{/Metadata \the\pdflastobj\space 0 R}
+ \endgroup
+ \endgroup
+ % Creates external xml file, if requested:
+ \if@wantXMPasXML
+ \newwrite\file
+ \immediate\openout\file=\jobname-XMPasXML.xml
+ \immediate\write\file{<?xml version="1.0" encoding="UTF-8" %
+ standalone="yes" ?>^^J}
+ \immediate\write\file{<!-- Ignore any message about not having style %
+ information. That is normal. -->^^J}
+ \immediate\write\file{<!-- Your viewer's font must be able to display %
+ any characters used in the XMP. -->^^J}
+ \immediate\write\file{<!-- For example, if your XMP has Cyrillic, %
+ then you need a Cyrillic-capable font. -->^^J}
+ \immediate\write\file{<!-- Any decorations (such as dashes in front of %
+ lines) are added by the viewer. Not in XMP. -->^^J}
+ \immediate\write\file{<!-- Note: xpacket begin="" contains the invisible %
+ 3-byte utf-8 BOM within its quotes. -->^^J}
+ \immediate\write\file{<!-- The above xml declaration, and these %
+ comments, are not part of the XMP packet. -->^^J}
+ \immediate\write\file{\@xmpData^^J}
+ \closeout\file
+ \fi
+ \fi
+\fi
+%
+%
+%% End write the XMP metadata.
+
+
+
+%% PREPARE PDF /INFO METADATA
+%% ----------------------------------------------------------------------------
+%% PDF /Info is another form of metadata, older than XMP but still used.
+%% It is NOT in utf-8 encoding. Depending on content, one of two encodings
+%% will be automatically used: PDFDoc encoding if metadata uses only
+%% characters within Latin-1, or utf-16 if metadata is not within Latin-1.
+%% Either way, the input was utf-8 before processing.
+%% In principle, PDF /Info is obsolete whenever PDF/X is used, because
+%% XMP metadata is supposed to prevail through the printing workflow.
+%% In practice, things don't always work that way. So, unless your PDF
+%% has no metadata, essential items are re-encoded and copied to PDF /Info.
+%% Other than encoding, XMP metadata and PDF /Info must be exactly the same.
+%% All of those issues are handled automatically here.
+%% The result is written at the end of the PDF, after the document.
+%
+% Macro for massaging encodings:
+\def\@infotopdfstring#1#2{%
+ \ifx#2\@empty
+ \global\let#1\empty
+ \else
+ \begingroup
+ \hypersetup{pdfencoding=auto}%
+ \pdfstringdef#1{#2}%
+ \endgroup
+ \fi
+}
+% Now, massage the metadata:
+\@infotopdfstring{\@infotitle}{\@title}
+\@infotopdfstring{\@infoauthor}{\@author}
+\@infotopdfstring{\@infoapplication}{\@novelApplication}
+\@infotopdfstring{\@infoproducer}{\@novelProducer}
+%
+%% End prepare PDF /Info.
+
+
+
+%% WRITE THE OUTPUT INTENT, UNLESS PDFX IS OFF.
+%% ----------------------------------------------------------------------------
+% Data for CGATS TR 001, FOGRA39, and JC200103 are in file novel-FileData.sty.
+\if@pdfxISoff\else
+ \begingroup
+ \edef\@pctchar{\expandafter\@gobble\string\%} % Escaped in TeX, not PDF.
+ \edef\@bchar{\expandafter\@gobble\string\\} % For use as escape, below.
+ \edef\0{\string\0} % Not sure why, but it works.
+ \edef\({\string\(} % PDF Catalog requires escaped parentheses.
+ \edef\){\string\)} % PDF Catalog requires escaped parentheses.
+ \catcode`\_ 12 % The icc file name might contain underscores.
+ %
+ \if@EmbedICC
+ \IfFileExists{\@OIprofile}{%
+ \immediate\pdfobj stream attr{/N 4} file{\@OIprofile}%
+ \edef\OBJ@OI{\the\pdflastobj\space 0 R}%
+ }{%
+ \ClassError{novel}{Requested icc color profile not found}%
+ {You used the starred \string\SetPDFX*\space which embeds the ^^J%
+ associated icc color profile. But the file could not be located. ^^J%
+ If necessary, put it in the same folder as your *.tex document. ^^J%
+ Incidentally: Do you really need to embed the profile?}%
+ }
+ \fi
+ \ifthenelse{\equal{\@OIcondition}{}}{
+ \edef\@OIconditionString{}%
+ }{
+ \edef\@OIconditionString{/OutputCondition (\@OIcondition)}%
+ }
+ \ifthenelse{\equal{\@OIidentifier}{}}{
+ \edef\@OIidentifierString{}%
+ }{
+ \edef\@OIidentifierString{/OutputConditionIdentifier (\@OIidentifier)}%
+ }
+ \ifthenelse{\equal{\@OIinfo}{}}{
+ \edef\@OIinfoString{}%
+ }{
+ \edef\@OIinfoString{/Info (\@OIinfo)}%
+ }
+ \ifthenelse{\equal{\@OIregistry}{}}{
+ \edef\@OIregistryString{}%
+ }{
+ \edef\@OIregistryString{/RegistryName (\@OIregistry)}%
+ }
+ \pdfcatalog{%
+ /OutputIntents [ <<%
+ /Type/OutputIntent%
+ /S/GTS_PDFX%
+ \@OIconditionString%
+ \@OIidentifierString%
+ \@OIinfoString%
+ \@OIregistryString%
+ \if@EmbedICC/DestOutputProfile \OBJ@OI\fi%
+ >> ]%
+ }%
+ \endgroup
+\fi
+%
+%% End write the output intent.
+
+
+
+%% DISABLE HYPERREF OPTIONS
+%%-----------------------------------------------------------------------------
+%% Prevents changes that will cause an incompatibility.
+%
+\Hy@DisableOption{pdfauthor}%
+\Hy@DisableOption{pdftitle}%
+\Hy@DisableOption{pdfsubject}%
+\Hy@DisableOption{pdfcreator}%
+\Hy@DisableOption{pdfcreationdate}%
+\Hy@DisableOption{pdfmoddate}%
+\Hy@DisableOption{pdfproducer}%
+\Hy@DisableOption{pdfkeywords}%
+%
+%% End disable hyperref options.
+
+
+
+%% PREPARE PDF/Info
+%% ----------------------------------------------------------------------------
+\gdef\@ActivatePDFInfo{% called by `novel.cls' \AtBeginDocument
+ \if@HasTitle
+ \pdfinfo{
+ \ifx\@infotitle\@empty\else /Title(\@infotitle)\fi
+ \ifx\@infoauthor\@empty\else /Author(\@infoauthor)\fi
+ \ifx\@infoapplication\@empty\else /Creator(\@infoapplication)\fi
+ \ifx\@pdfcreationdate\@empty
+ /CreationDate(D:\pdfx@convDate)%
+ \else
+ /CreationDate(\@pdfcreationdate)%
+ \fi
+ \ifx\@pdfmoddate\@empty
+ /ModDate(D:\pdfx@convDate)%
+ \else
+ /ModDate(\@pdfmoddate)%
+ \fi
+ \ifx\@infoproducer\@empty\else /Producer(\@infoproducer)\fi%
+ /Trapped/False%
+ \if@pdfxISoff\else
+ /GTS_PDFXVersion(\@PDFXversion)%
+ \if@HasConformance /GTS_PDFXConformance(\@PDFXconformance)\fi%
+ \fi
+ }
+ \fi
+}%
+%% End \@ActivatePDFInfo.
+
+
+
+%%
+\endinput
+%%
+%% End of file `novel-pdfx.sty'.
+
+
diff --git a/macros/luatex/latex/novel/novel-xmppacket.sty b/macros/luatex/latex/novel/novel-xmppacket.sty
new file mode 100644
index 0000000000..a70419c6fe
--- /dev/null
+++ b/macros/luatex/latex/novel/novel-xmppacket.sty
@@ -0,0 +1,186 @@
+%%
+%% This is file `novel-xmppacket.sty', part of `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer.
+%%
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+%% ----------------------------------------------------------------------------
+%%
+%% The descriptive properties of the namespaces, and the general format of XMP,
+%% are public standards released by Adobe Systems Incorporated.
+%% See http://www.adobe.com/products/xmp.html
+%%
+%% ----------------------------------------------------------------------------
+%%
+%%
+\ProvidesFile{novel-xmppacket.sty}%
+[2018/01/14 any version. (novel XMP packet template)]
+%%
+
+
+
+% This packet uses utf-8 BOM.
+% The catcodes allow # _ ~ $ % & to be used as ordinary characters.
+% \edef and \let get rid of escape backslashes in front of those characters.
+% NO COMMENTS AFTER THIS! Until \endgroup.
+
+
+
+
+
+\begingroup
+\catcode`\¤=12\relax
+\lccode`\¤="FEFF
+\lowercase{\gdef\@novelBOM{¤}}
+\catcode`\#=12
+\catcode`\_=12
+\catcode`\~=12
+\catcode`\$=12
+\catcode`\%=12
+\catcode`\&=12
+
+\edef\@pctchar{\expandafter\@gobble\string\%}
+\let\%\@pctchar
+\edef\@hashchar{\expandafter\@gobble\string\#}
+\let\#\@hashchar
+\edef\@ampchar{\expandafter\@gobble\string\&amp;}
+\let\&\@ampchar
+\edef\@dollarchar{\expandafter\@gobble\string\$}
+\let\$\@dollarchar
+\edef\@underchar{\expandafter\@gobble\string\_}
+\let\_\@underchar
+\edef\@tildechar{\expandafter\@gobble\string\~}
+\let\~\@tildechar
+
+\xdef\@xmpPacket{<?xpacket begin="\@novelBOM" id="W5M0MpCehiHzreSzNTczkc9d"?>^^J
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.2.1-c043 52.372728, 2009/01/18-15:08:04\pad@iv\pad@iv">^^J
+\pad@ii<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:xmp="http://ns.adobe.com/xap/1.0/">^^J
+\pad@vi<xmp:ModifyDate>\@modifyDate</xmp:ModifyDate>^^J
+\pad@vi<xmp:CreateDate>\@createDate</xmp:CreateDate>^^J
+\@applicationString
+\pad@vi<xmp:MetadataDate>\@metadataDate</xmp:MetadataDate>^^J
+\pad@iv</rdf:Description>^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:dc="http://purl.org/dc/elements/1.1/">^^J
+\pad@vi<dc:format>application/pdf</dc:format>^^J
+\@titleString
+\@authorString
+\pad@iv</rdf:Description>^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">^^J
+\pad@vi<xmpMM:DocumentID>\@documentID</xmpMM:DocumentID>^^J
+\pad@vi<xmpMM:InstanceID>\@instanceID</xmpMM:InstanceID>^^J
+\pad@vi<xmpMM:RenditionClass>default</xmpMM:RenditionClass>^^J
+\pad@vi<xmpMM:VersionID>1</xmpMM:VersionID>^^J
+\pad@iv</rdf:Description>^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:pdf="http://ns.adobe.com/pdf/\@pdfVersion/">^^J
+\@producerString
+\pad@vi<pdf:Trapped>False</pdf:Trapped>^^J
+\pad@iv</rdf:Description>^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:pdfx="http://ns.adobe.com/pdfx/\@pdfVersion/">^^J
+\@verconfString
+\pad@iv</rdf:Description>^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:pdfxid="http://www.npes.org/pdfx/ns/id/">^^J
+\@pdfidString
+\pad@iv</rdf:Description>^^J
+\pad@iv<rdf:Description rdf:about=""^^J
+\pad@viii xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"^^J
+\pad@viii xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#"^^J
+\pad@viii xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#">^^J
+\pad@vi<pdfaExtension:schemas>^^J
+\pad@viii<rdf:Bag>^^J
+\pad@x<rdf:li rdf:parseType="Resource">^^J
+\pad@xii<pdfaSchema:namespaceURI>http://ns.adobe.com/pdf/\@pdfVersion/</pdfaSchema:namespaceURI>^^J
+\pad@xii<pdfaSchema:prefix>pdf</pdfaSchema:prefix>^^J
+\pad@xii<pdfaSchema:schema>Adobe PDF Schema</pdfaSchema:schema>^^J
+\pad@xii<pdfaSchema:property>^^J
+\pad@xiv<rdf:Seq>^^J
+\pad@xvi<rdf:li rdf:parseType="Resource">^^J
+\pad@xviii<pdfaProperty:category>internal</pdfaProperty:category>^^J
+\pad@xviii<pdfaProperty:description>A name object indicating whether the document has been modified to include trapping information</pdfaProperty:description>^^J
+\pad@xviii<pdfaProperty:name>Trapped</pdfaProperty:name>^^J
+\pad@xviii<pdfaProperty:valueType>Text</pdfaProperty:valueType>^^J
+\pad@xvi</rdf:li>^^J
+\pad@xiv</rdf:Seq>^^J
+\pad@xii</pdfaSchema:property>^^J
+\pad@x</rdf:li>^^J
+\pad@x<rdf:li rdf:parseType="Resource">^^J
+\pad@xii<pdfaSchema:namespaceURI>http://ns.adobe.com/pdfx/\@pdfVersion/</pdfaSchema:namespaceURI>^^J
+\pad@xii<pdfaSchema:prefix>pdfx</pdfaSchema:prefix>^^J
+\pad@xii<pdfaSchema:schema>PDF/X ID Schema</pdfaSchema:schema>^^J
+\pad@xii<pdfaSchema:property>^^J
+\pad@xiv<rdf:Seq>^^J
+\pad@xvi<rdf:li rdf:parseType="Resource">^^J
+\pad@xviii<pdfaProperty:category>internal</pdfaProperty:category>^^J
+\pad@xviii<pdfaProperty:description>ID of PDF/X standard</pdfaProperty:description>^^J
+\pad@xviii<pdfaProperty:name>GTS_PDFXVersion</pdfaProperty:name>^^J
+\pad@xviii<pdfaProperty:valueType>Text</pdfaProperty:valueType>^^J
+\pad@xvi</rdf:li>^^J
+\pad@xvi<rdf:li rdf:parseType="Resource">^^J
+\pad@xviii<pdfaProperty:category>internal</pdfaProperty:category>^^J
+\pad@xviii<pdfaProperty:description>Conformance level of PDF/X standard</pdfaProperty:description>^^J
+\pad@xviii<pdfaProperty:name>GTS_PDFXConformance</pdfaProperty:name>^^J
+\pad@xviii<pdfaProperty:valueType>Text</pdfaProperty:valueType>^^J
+\pad@xvi</rdf:li>^^J
+\pad@xiv</rdf:Seq>^^J
+\pad@xii</pdfaSchema:property>^^J
+\pad@x</rdf:li>^^J
+\pad@x<rdf:li rdf:parseType="Resource">^^J
+\pad@xii<pdfaSchema:namespaceURI>http://ns.adobe.com/xap/1.0/mm/</pdfaSchema:namespaceURI>^^J
+\pad@xii<pdfaSchema:prefix>xmpMM</pdfaSchema:prefix>^^J
+\pad@xii<pdfaSchema:schema>XMP Media Management Schema</pdfaSchema:schema>^^J
+\pad@xii<pdfaSchema:property>^^J
+\pad@xiv<rdf:Seq>^^J
+\pad@xvi<rdf:li rdf:parseType="Resource">^^J
+\pad@xviii<pdfaProperty:category>internal</pdfaProperty:category>^^J
+\pad@xviii<pdfaProperty:description>UUID based identifier for specific incarnation of a document</pdfaProperty:description>^^J
+\pad@xviii<pdfaProperty:name>InstanceID</pdfaProperty:name>^^J
+\pad@xviii<pdfaProperty:valueType>URI</pdfaProperty:valueType>^^J
+\pad@xvi</rdf:li>^^J
+\pad@xiv</rdf:Seq>^^J
+\pad@xii</pdfaSchema:property>^^J
+\pad@x</rdf:li>^^J
+\pad@x<rdf:li rdf:parseType="Resource">^^J
+\pad@xii<pdfaSchema:namespaceURI>http://www.npes.org/pdfx/ns/id/</pdfaSchema:namespaceURI>^^J
+\pad@xii<pdfaSchema:prefix>pdfxid</pdfaSchema:prefix>^^J
+\pad@xii<pdfaSchema:schema>PDF/X ID Schema</pdfaSchema:schema>^^J
+\pad@xii<pdfaSchema:property>^^J
+\pad@xiv<rdf:Seq>^^J
+\pad@xvi<rdf:li rdf:parseType="Resource">^^J
+\pad@xviii<pdfaProperty:category>internal</pdfaProperty:category>^^J
+\pad@xviii<pdfaProperty:description>ID of PDF/X standard</pdfaProperty:description>^^J
+\pad@xviii<pdfaProperty:name>GTS_PDFXVersion</pdfaProperty:name>^^J
+\pad@xviii<pdfaProperty:valueType>Text</pdfaProperty:valueType>^^J
+\pad@xvi</rdf:li>^^J
+\pad@xiv</rdf:Seq>^^J
+\pad@xii</pdfaSchema:property>^^J
+\pad@x</rdf:li>^^J
+\pad@viii</rdf:Bag>^^J
+\pad@vi</pdfaExtension:schemas>^^J
+\pad@iv</rdf:Description>^^J
+\pad@ii</rdf:RDF>^^J
+</x:xmpmeta>^^J
+\pad@dxii
+<?xpacket end="w"?>}
+\endgroup
+
+
+% OK to use comments now.
+%%
+\endinput
+%%
+%% End of file `novel-xmppacket.sty'.
+
diff --git a/macros/luatex/latex/novel/novel.cls b/macros/luatex/latex/novel/novel.cls
new file mode 100644
index 0000000000..e029b43c79
--- /dev/null
+++ b/macros/luatex/latex/novel/novel.cls
@@ -0,0 +1,678 @@
+%%
+%% This is file `novel.cls', LuaLaTeX `novel' document class.
+%% Copyright 2017-2018 Robert Allgeyer. Contact: anytthree [at] gmail.com
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%%
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+% Actually needs LuaLaTeX, at least version 0.95 from TeXLive 2016.
+\ProvidesClass{novel}[2018/04/26 v1.52 LaTeX document class]
+%%
+%% Version 1.50.n (any n) incremental minor changes from 1.50.
+%% Version 1.50: Improved image handled, sandbox, scripts.
+%% Version 1.46.2: Now called "novel-old" version.
+%% Version 1.43: General cleanup of docs and code, for improved readbaility.
+%% Version 1.42: Greatly improved HTML documentation.
+%% Version 1.41: Improved HTML documentation.
+%% Versions 1.40.x: Incremental minor changes, leading to 1.42.
+%% Version 1.40: removed `debug' option (was not useful). Major docs rewrite.
+%% This version was successfully used for a P.O.D. novel, with cover.
+%% Version 1.38: corrected offset in cover artwork; some docs modified.
+%% Version 1.36: minor documentation correction.
+%% Version 1.34: Added debug class option and related code. [Later removed.]
+%% Version 1.32 includes a minor documentation fix, and a major bug fix
+%% concerning looose text tracking. The bug occasionally appeared when
+%% page headings were compiled, but gave a cryptic error message
+%% about MT@res@a. The fix is expected to be permanent.
+%% Version 1.2: Added capability for cover artwork.
+%% Versions 1.1.x: First general release, occasional documentation changes.
+
+
+%% DESCRIPTION:
+%% ----------------------------------------------------------------------------
+%% Class `novel' is designed for print fiction: novels or short stories.
+%% It cannot be used for e-books or for journal publication.
+%% It is not suitable for most non-fiction, because routine academic features
+%% such as bibiography and automatic sectioning are defeated.
+%%
+%% There are pre-configured layouts for the most commonly used choices of
+%% trim size (finished book width and height), and internal layout consistent
+%% with fiction. The user can over-ride the pre-configured settings.
+%%
+%% The class will automatically create PDF/X compliant files upon request,
+%% using a self-contained command structure. Results have been tested.
+%%
+%% LuaLaTeX is required, and input files must be encoded utf-8.
+%%
+%% Fonts are loaded by luaotfload and fontspec, and massaged by microtype.
+%% For best results, use modern Open Type fonts, or TrueType fonts.
+%%
+%% The Libertinus font family, a fork of [Linux] Libertine/Biolinum,
+%% is the default. Actually, I recommend it! In addition, an included
+%% custom font, NovelDeco.otf, is used for special purposes.
+%%
+
+
+%% REQUIRE LUATEX and do some preliminary setup.
+%% ----------------------------------------------------------------------------
+%% These are not user settings.
+%
+\RequirePackage{ifluatex} % LuaTeX is required. Not XeTeX, dvips, or pdfTeX.
+\RequirePackage{ifxetex} % For occasional hacks (hiss, boo).
+\RequirePackage{luatex85} % Needed for compatibility with LuaTeX 0.95 etc.
+\RequirePackage{pdftexcmds} % compatibility
+\ifluatex
+ % New with TeXlive 2016. Removes unnecessary File Data:
+ \pdfvariable suppressoptionalinfo 511 % writes only ID to PDF Catalog
+\else
+ \ClassError{novel}{Must compile with LuaLaTeX 0.95+}%
+ {Sorry, LuaLaTeX only. No pdfTeX, dvips, or XeTeX.}
+\fi
+\pdfimageresolution=300 % default dpi if image does not say
+%
+\RequirePackage{etoolbox} % general good stuff
+\RequirePackage{xifthen} % improved ifthenelse handling
+\RequirePackage{xstring} % parses strings
+\RequirePackage{fp} % used everywhere for math calculations
+\RequirePackage{xfp} % more math calculations
+\RequirePackage{keyval} % used by drop cap
+\FPmessagesfalse % eliminates numerous friendly messages from the log
+%
+\pdfminorversion=3 % might be reset later, depending on settings
+\gdef\thepdfminorversion{\pdfminorversion} % compatibility
+%
+\RequirePackage{silence} % Used here:
+% hyperref draft mode is always on, even when novel is not in draft mode:
+\WarningFilter{hyperref}{Draft mode on} % So, get rid of the hyperref warning.
+% Prevent complaints about no protrusion list for cmr, cmm, etc. in decimal pt:
+\WarningFilter{microtype}{I cannot find a protrusion list} % It's not there!
+%
+\WarningsOff[Fancyhdr,fancyhdr] % complains about headheight when no header
+\RequirePackage[relative]{textpos} % for inserting images
+\RequirePackage{calc} % allows length expression calculations
+\RequirePackage{atbegshi} % in oberdiek bundle. For one-page header changes. Also used by hyperref.
+\RequirePackage{letltxmacro} % in oberdiek bundle. For re-defining some macros
+\RequirePackage{xparse} % for writing cool-looking commands
+%
+% In addition, the following packages are required, but not loaded yet.
+% They must wait for something else to happen first. Then they will be loaded
+% with suitable arguments, when the time comes:
+% fontspec -- in novel-LayoutSettings.sty
+% unicode-math -- in novel-LayoutSettings.sty
+% polyglossia -- in novel-LayoutSettings.sty
+% microtype -- in novel-Fonts.sty
+% hyperref -- in novel-pdfx.sty
+% fancyhdr -- in novel.HeadFootStyles.sty
+% xcolor -- lower in this page
+% adjustbox -- lower on this page
+% eso-pic -- lower on this page
+% lipsum -- lower on this page
+%%
+
+
+\newlength\@tempLength % scratch length for local calculations
+\newif \if@tempTF % scratch boolean for local tests
+
+
+%% Global lengths are often passed around in `novel'.
+%% But \setlength is not always global in effect.
+%% This code defines a global command.
+%% Via Heiko Oberdiek at tex.stackexchange.com:
+\gdef\gsetlength#1#2{% #1 is the length command, #2 is the length value
+ \begingroup%
+ \setlength\skip@{#2}% Local assignment to a TeX scratch register.
+ \global#1=\skip@% Global assignment to #1
+ \endgroup% \skip@ is restored by end of group.
+}% end \gsetlength
+%%
+
+
+%% Process document class options.
+%% ----------------------------------------------------------------------------
+% Allowed option list:
+% draft xml shademargins cropmarks cropview closecrop
+% coverart sandbox unblock mtoff polyoff test
+% Yes, I realize that this could have been done another way, but I want
+% to issue error messages from `novel' rather than (say) `keyval':
+\gdef\@mycol{\@classoptionslist}
+\StrDel{\@mycol}{ }[\@mycol]
+\StrDel{\@mycol}{,}[\@mycol]
+\StrDel{\@mycol}{draft}[\@mycol]
+\StrDel{\@mycol}{xml}[\@mycol]
+\StrDel{\@mycol}{shademargins}[\@mycol]
+\StrDel{\@mycol}{graytext}[\@mycol] % Obsolete. Now always allows graytext.
+\StrDel{\@mycol}{greytext}[\@mycol] % See above.
+\StrDel{\@mycol}{cropmarks}[\@mycol]
+\StrDel{\@mycol}{cropview}[\@mycol]
+\StrDel{\@mycol}{closecrop}[\@mycol]
+\StrDel{\@mycol}{coverart}[\@mycol]
+\StrDel{\@mycol}{unblock}[\@mycol]
+\StrDel{\@mycol}{mtoff}[\@mycol]
+\StrDel{\@mycol}{polyoff}[\@mycol]
+\StrDel{\@mycol}{test}[\@mycol]
+\StrDel{\@mycol}{sandbox}[\@mycol]
+%
+\ifthenelse{\equal{\@mycol}{}}{}{
+ \ClassWarning{novel}{^^JUnrecognized class option: \@mycol. ^^J%
+ The unrecognized option was ignored! ^^J%
+ If `debug' it is obsolete from v.1.40. ^^J%
+ Note that font size, document size, and language ^^J%
+ are not `novel' class options. See documentation. ^^J}%
+}
+% If used, option `draft' shows overflow rule.
+% Prior to v. 1.46.1, the following was \if@useDraftMode.
+% Changed for possible compatibility with packages that detect draft mode.
+\newif \ifdraftdoc
+\setlength\overfullrule{0pt}
+\DeclareOption{draft}{
+ \setlength\overfullrule{6pt}
+ \draftdoctrue
+ \ClassWarning{novel}{^^JCompiled with draft mode. Not for final release! ^^J}
+}
+\newif \ifmsdoc % manuscript, always false. Compatibility with other packages.
+% If used, option `xml' creates a file `\jobname-XMPasXML.xml` that contains
+% the XMP metadata with an xml declaration and comments at top.
+% Only works when \SetPDFX is not `off'. Note that you do not need to use
+% this option to get PDF/X. It is only for your own usage.
+\newif \if@wantXMPasXML
+\DeclareOption{xml}{\@wantXMPasXMLtrue}
+\DeclareOption{xmp}{ % in case you mis-type.
+ \ClassError{novel}{No class option `xmp'. Use `xml'}%
+ {There is no class option named `xmp'. It is `xml'.}
+}
+% Option `shademargins' does just that. Ignored unless in draft mode.
+\newif \if@shademargins
+\DeclareOption{shademargins}{\@shademarginstrue}
+%
+\newif \if@graytext % remains here for backwards compatibility
+\@graytexttrue % from v.1.50 always true, no longer an option.
+%
+% Usually you do NOT want crop (trim) marks!
+\newif \if@cropmarks
+\DeclareOption{cropmarks}{\@cropmarkstrue}
+% PDF viewers display CropBox, which normally is identical to MediaBox.
+% Option `cropview', sets CropBox to TrimBox instead, so that's all you see.
+% Only makes a difference when MediaBox is larger than TrimBox.
+% Ignored unless in draft mode.
+\newif \if@cropview
+\DeclareOption{cropview}{\@cropviewtrue}
+% With `closecrop', the TrimSize and margins are re-sized, to preserve the
+% live area, but with reduced margins on all sides (same for verso/recto).
+% This option is available only in draft mode, and disables shademargins.
+% The purpose is to create a PDF that is more easily read on a handheld device,
+% so you can think about edits while traveling. It is NOT an e-book, since
+% it has no hyperlinks and is missing some features that an e-book should have.
+\newif \if@closecrop
+\DeclareOption{closecrop}{\@cropviewtrue\@closecroptrue}
+% New in version 1.2: `coverart' option. See documentation.
+% This is used to create a 1-page file with no text, just an image.
+% Intended purpose is PDF/X for novel cover.
+\newif \if@coverart
+\DeclareOption{coverart}{\@coverarttrue}
+% New in version 1.34: unblock option, for developer use only.
+% Normally, a number of packages known to be incompatible with `novel'
+% are blocked from loading. If the user tries to get them via \usepackage
+% or \RequirePackage, or if they are called within some other loaded package,
+% then compile halts with an error. The `unblock' option turns off blocking,
+% and allows incompatible packages to load. Use only at own risk!
+\newif \if@novelunblock % For developer use.
+\DeclareOption{unblock}{\@novelunblocktrue}
+% New in version 1.44: mtoff option, primarily for developer use.
+% With mtoff, the microtype package is not loaded.
+\newif \if@mtoff
+\DeclareOption{mtoff}{\@mtofftrue}
+% New in version 1.44: polyoff option, primarily for developer use.
+% With polyoff, the polyglossia package is not loaded.
+% You may need to load babel, or not, via \RequirePackage[options]{babel}.
+\newif \if@polyoff
+\DeclareOption{polyoff}{\@polyofftrue}
+% New in version 1.46: test option, primarily for developer use.
+\newif \if@testsuite
+\DeclareOption{test}{\@testsuitetrue}
+%
+% New in version 1.50: sandbox option, for artwork and tables. Max 4 pages.
+\newif \if@sandbox
+\DeclareOption{sandbox}{\@sandboxtrue}
+%
+%% Note that document size and normal font size are not class options.
+%% They are set by commands in the Preamble, and have default values.
+%
+\ProcessOptions\relax
+% Disable some options, depending on compatibilities:
+\ifdraftdoc\else
+ \global\@shademarginsfalse
+ \global\@cropviewfalse
+ \global\@closecropfalse
+\fi
+%
+\if@testsuite
+ \gdef\@testintentional{Test suite intentionally generates this warning. ^^J}
+\else
+ \gdef\@testintentional{}
+\fi
+%
+\if@cropview
+ \global\@cropmarksfalse
+\fi
+%
+\if@closecrop
+ \global\@cropviewtrue
+ \global\@shademarginsfalse
+ \global\@cropmarksfalse
+\fi
+%
+\if@coverart
+ \global\draftdocfalse
+ \global\@shademarginsfalse
+ \global\@cropviewfalse
+ \global\@closecropfalse
+ \global\@sandboxfalse
+\fi
+%
+\if@sandbox
+ % Thanks to user Compholio at stackexchange.com:
+ \newcounter{sandboxcount}
+ \ifx\latex@outputpage\@undefined\relax%
+ \global\let\latex@outputpage\@outputpage%
+ \fi%
+ \gdef\@outputpage{%
+ \addtocounter{sandboxcount}{1}%
+ \ifnum\value{sandboxcount}>4\relax% no output after 4 pages
+ \else%
+ \latex@outputpage%
+ \fi%
+ }%
+ \AtEndPreamble{%
+ \gdef\@title{untitled interior artwork}%
+ }%
+ \AfterEndPreamble{%
+ \ifdraftdoc\else\thispagestyle{empty}\fi%
+ }%
+\fi
+%% end class options
+
+
+\RequirePackage{noindentafter} % for unindented chapter and scene starts
+\RequirePackage{changepage} % provides block indents, etc. Do not use strict!
+\RequirePackage{magaz} % special treatment of first lines
+
+
+%% Activate xcolor, adjustbox, and eso-pic:
+%% ----------------------------------------------------------------------------
+% The final book must be black/white and gray only, for all text.
+% Interior images must be raster black/white or grayscale. See documentation.
+% Vector graphics are strongly discouraged, in any case.
+% In draft mode only, the `shademargins' option requires `grayscale',
+% which will be temporarily enabled, even if not specifically requested.
+%
+\RequirePackage[gray,hyperref]{xcolor}
+%
+% adjustbox and eso-pic cannot precede xcolor.
+\RequirePackage{adjustbox} % for scaling and moving
+\RequirePackage{eso-pic} % background effects in draft mode
+\RequirePackage{pdfpages} % only used for pdf pre-processed by novel-scripts
+%% end activate xcolor and adjustbox
+
+
+%% Temporary normal font size, baselineskip, and fontspec
+%% ----------------------------------------------------------------------------
+%% This normalsize is temporary, so that packages can load without complaint.
+%% It will be modified later, during layout calculations.
+%% Actual default font size will be 11pt-12pt, with 11.4pt average.
+%% The small temporary size is to ensure that overly-large struts and skips
+%% are not created prior to page layout calculation.
+\gdef\@TentativeEmN{10}
+\gdef\@TentativeBLSkipN{13}
+\renewcommand\normalsize{%
+ \@setfontsize\normalsize{\@TentativeEmN}{\@TentativeBLSkipN}%
+}
+\normalsize
+\RequirePackage[no-math]{fontspec} % For LuaLaTeX. NOT package `fontenc'.
+% The `novel' class is not intended for math. But TeX assumes you do math,
+% so it needs a math font, whether you like it or not.
+\RequirePackage{unicode-math}
+%% end temporary normal point size, baselineskip, and fontspec.
+
+
+%% Define commands used for File Data, including PDF/X Settings.
+%% ----------------------------------------------------------------------------
+%% As used here, `File Data' refers to PDF metadata as found in PDF/Info
+%% and in XMP. This class does not write it to the PDF Catalog.
+\RequirePackage{novel-FileData}
+%%
+
+
+%% Physical Layout Commands and Settings.
+%% ----------------------------------------------------------------------------
+%% Define user commands that over-ride class option pre-configured settings.
+%% Also sets a variety of miscellaneous lengths:s \parsep, \parindent, etc.
+\RequirePackage{novel-LayoutSettings}
+
+
+%% Polyglossia.
+%% ----------------------------------------------------------------------------
+% Language-specific settings:
+\if@polyoff % polyoff is new in v 1.44.
+ \ClassWarning{novel}{^^JYou chose the `polyoff' class option. ^^J%
+ So, the polyglossia package was not loaded. But like it or not, ^^J%
+ the babel package was loaded, with generic hyphenation. ^^J%
+ This behavior, or choice of language, cannot be changed. ^^J%
+ If you want a specific language, you will have to use polyglossia. ^^J}%
+\else
+ \RequirePackage{polyglossia} % loading order changed in v. 1.40.3.
+ \setdefaultlanguage[variant=american]{english} % may be changed by user
+\fi
+%% end polyglossia
+
+
+%% Additional Macros, Loaded in Preamble.
+%% ----------------------------------------------------------------------------
+\RequirePackage{novel-Fonts} % font settings and defaults
+\if@coverart\else\RequirePackage{lipsum}\fi % generates dummy text for examples
+%% New in version 1.50:
+\RequirePackage{novel-DropCap}
+% Macros for use in document body:
+\RequirePackage{novel-TextMacros}
+% Standard header footer styles, based on `fancyhdr':
+% Each pre-configured style will set these booleans true or false:
+\newif\if@HasHeader \newif\if@HasFooter
+\RequirePackage{novel-HeadFootStyles}
+% Chapter and Scene styles:
+\RequirePackage{novel-ChapterScene}
+% Image placement:
+\RequirePackage{novel-Images}
+% Footnotes and endnotes:
+\RequirePackage{novel-Footnotes}
+% Obsolete code. Do not use in new documents:
+\RequirePackage{novel-Obsolete}
+%%
+
+
+%% For convenience, from `article' class.
+%% ----------------------------------------------------------------------------
+\newenvironment{verse}{% Not very useful.
+ \let\\\@centercr
+ \list{}{%
+ \itemsep\z@
+ \itemindent -\parindent%
+ \listparindent\itemindent
+ \rightmargin \leftmargin
+ \advance\leftmargin \parindent%
+ }%
+ \item\relax%
+}{%
+ \endlist%
+}
+%%
+\newenvironment{quotation}{% Not very useful.
+ \list{}{%
+ \listparindent \parindent%
+ \itemindent \listparindent
+ \rightmargin \leftmargin
+ \parsep \z@%
+ }%
+ \item\relax%
+}{%
+ \endlist%
+}
+%%
+\newenvironment{quote}{% Not very useful.
+ \list{}{%
+ \rightmargin\leftmargin%
+ }%
+ \item\relax%
+}{%
+ \endlist%
+}
+%
+%% end convenience.
+
+
+
+%% Special features of test suite (for developers and error reporting)
+%% ----------------------------------------------------------------------------
+% Files `novel-testsuite.tex' and `novel-testimage.png' are within the novel
+% documentation extras folder. To run the test suite, copy these files to
+% a writeable location (such as your home directory) and compile there.
+\newcommand\testsuiteoops[1]{%
+ \ClassError{novel}{#1 missing}{Install the necessary file(s).}%
+}
+\if@testsuite
+ \IfFontExistsTF{libertinusserif-regular.otf}{}{%
+ \testsuiteoops{`libertinus' fonts}%
+ }
+ \IfFileExists{lmodern.sty}{}{\testsuiteoops{`lmodern' package}}
+ \IfFileExists{novel-testimage.png}{}{\testsuiteoops{`novel-testimage.png'}}
+ \NewFontFamily\mustbelibertinus{Libertinus Serif}
+ \NewFontFamily\mustbelmodern{Latin Modern Roman}
+\fi
+%% end special features of test suite.
+
+
+%% \AtEndPreamble sets defaults, calculates layout, and writes PDF/X
+%% ----------------------------------------------------------------------------
+% This is prior to \AtBeginDocument, and ensures that the results are available
+% prior to any \AtBeginDocument routines from user macros or loaded packages.
+\AtEndPreamble{
+ \@ActivateFonts % in `novel-Fonts.sty'
+ \RequirePackage{novel-CalculateLayout} % may load novel-ChangeLayout.sty
+ \RequirePackage{novel-PostLayout} % calculates shademargins, cropmarks, etc.
+ \RequirePackage{novel-pdfx}% also provides an \AtBeginDocument macro
+ \@GetInitialYpos% in `novel-TextMacros.sty
+}%
+%% end AtEndPreamble
+
+
+%% Messages that may be issued by \AtBeginDocument routines:
+%% ----------------------------------------------------------------------------
+%
+%% Dealing with known incompatible packages:
+\gdef\really@no#1#2#3{ % cannot be used, even with unblock or sandbox
+ \@ifpackageloaded{#1}{%
+ \ClassError{novel}{Sorry, package `#1' cannot be used in `novel' class}%
+ {No exceptions. You are out of luck. ^^J%
+ Reason: `novel' has #2 ^^J%
+ See `novel' HTML documentation, section #3. ^^J%
+ Note: The offending package may have been loaded by another package.}%
+ }{}%
+} %
+%
+%% Command or environment native to LuaLaTeX, but banned except in sandbox:
+\gdef\@OnlySandbox#1{%
+ \ClassError{novel}{Use of `#1' page \thepage\space requires sandbox}%
+ {`novel' class prohibits command or environment `#1' ^^J%
+ unless you use class option `sandbox'. See documentation.}%
+}
+%
+%% Package can be used, but Alert:
+\gdef\alert@nodisp#1{%
+ \@ifpackageloaded{#1}{%
+ \typeout{^^JClass `novel' Alert: Beware of package #1. ^^J%
+ Commands from this package may cause mis-positioning in main text. ^^J%
+ Maybe, maybe not. Best if usage is confined to display pages. ^^J}%
+ }%
+}
+%
+%% Dealing with blocked packages, allowed with `unblock':
+\if@novelunblock
+ \gdef\sorry@no#1{} % no package-specific errors, when unblock
+ \ClassWarning{novel}{Using `unblock' class option, at your own risk. ^^J%
+ The `unblock' option is for developer use, not production documents. ^^J%
+ If the unblocked packages and commands cause problems, ^^J%
+ they are not bugs. Do not report them. You have been warned. ^^J%
+ Perhaps your document will compile without error, and perhaps the ^^J%
+ results are OK. But in other cases, unexpected typesetting results. ^^J}%
+\else % package-specific errors, when no unblock
+ \gdef\sorry@no#1{
+ \@ifpackageloaded{#1}{%
+ \ClassError{novel}{Sorry, package `#1' cannot be used in `novel' class}%
+ {See `novel' HTML documentation, regarding `sandbox' option. ^^J%
+ Note: The offending package may have been loaded by another package.}%
+ }{}%
+ } %
+\fi
+%
+\gdef\@needsandboxmsg{%
+ \ClassError{novel}{Need `sandbox' for picture, figure, table environments}%
+ {You cannot use picture, figure, or table environments in `novel' unless ^^J%
+ you use the `sandbox' document class option. See docs.}%
+}
+%% end messages.
+
+
+%% \AtBeginDocument finishes the setup
+%% ----------------------------------------------------------------------------
+%
+\AtBeginDocument{ %
+ \@RedefineParapos % in `novel-TextMacros.sty'
+ \@ActivateTextLengths % in `novel-TextMacros.sty'
+ \@ActivateDropCaps % in `novel-DropCaps.sty'
+ \@ActivateChapterScene % in `novel-ChapterScene.sty'
+ \@ActivateHeadFootStyles % in file `novel-HeadFootStyles.sty'
+ \@AlertNoPDFX % in file `novel-pdfx.sty'
+ \@ActivatePDFInfo % in file `novel-pdfx.sty'
+ \@ActivateTextMacros % in `novel-TextMacros.sty'
+ \@ActivateFootnotes % in `novel-Footnotes.sty'
+ \@DisableFontSizes % in file `novel-LayoutSettings.sty'
+ \@DisableLayoutSettings % in file `novel-LayoutSettings.sty'
+ \@DisableFileDataSettings % in file `novel-FileData.sty'
+ \@DisableChapterSceneSettings % in file `novel-ChapterScene.sty'
+ \@RedefineBreakpos % in file `novel-ChapterScene.sty'
+ \@DisableHeadFootSettings % in file `novel-HeadFootStyles.sty'
+ \@GatherGoodImages % in file `novel-Images.sty'.
+ % List of always-blocked packages (not exhaustive, since TeX has so many):
+ \really@no{geometry}{its own layout commands.}{4}
+ \really@no{pdfx}{built-in PDF/X capability.}{3.4}
+ \really@no{xmpincl}{built-in PDF/X capability.}{3.4}
+ \really@no{hyperxmp}{built-in PDF/X capability.}{3.4}
+ \really@no{pdfxmult}{built-in PDF/X capability.}{3.4}
+ \really@no{inputenc}{utf-8 encoding always.}{1.2.1}
+ \really@no{fontenc}{`fontspec' and utf-8 encoding always.}{1.2.1, 1.2.3}
+ \really@no{biblatex}{no bibiography capability.}{1.2.5}
+ \really@no{showkeys}{an incompatible layout method.}{1.2.5}
+ \really@no{booktabs}{no capability for this, due to printer specs.}{3.4}
+ \really@no{pax}{no capability for this, due to printer specs.}{3.4}
+ \really@no{bookmark}{focus on paper books, not e-books.}{(top of file)}
+ \really@no{endnotes}{limited, built-in endnote methods.}{6.5}
+ \really@no{acronym}{focus on paper books, not e-books.}{(top of file)}
+ \really@no{embedfile}{incompatible print requirements.}{(top of file)}
+ \really@no{makeidx}{an incompatible layout method.}{1.2.5}
+ \really@no{gridset}{a command name conflict.}{4}
+ % Potential problem packages, allowed in sandbox or with unblock:
+ \if@sandbox
+ \RequirePackage{novel-Sandbox}
+ \else
+ \gdef\mplibcode{\@OnlySandbox{mplibcode}}
+ % Related to floats:
+ \sorry@no{floatflt}
+ \sorry@no{floatfig}
+ \sorry@no{flafter}
+ \sorry@no{float}
+ \sorry@no{morefloats}
+ \sorry@no{endfloat}
+ \sorry@no{placeins}
+ % Related to footnotes and endnotes:
+ \sorry@no{footmisc}
+ \sorry@no{footnote}
+ \sorry@no{manyfoot}
+ % Related to tables:
+ \sorry@no{multirow}
+ \sorry@no{tabu}
+ \sorry@no{tabularx}
+ \sorry@no{tabulary}
+ \sorry@no{longtable}
+ % Related to lists:
+ \sorry@no{array}
+ \sorry@no{easylist}
+ \sorry@no{listings}
+ \sorry@no{numitem}
+ \sorry@no{tasks}
+ % Related to graphics or layout:
+ \sorry@no{pagegrid}
+ \sorry@no{subfig}
+ \sorry@no{lpic}
+ \sorry@no{pinlabel}
+ \sorry@no{overpic}
+ \sorry@no{caption}
+ \sorry@no{sidecap}
+ \sorry@no{subcaption}
+ \sorry@no{paracol}
+ \sorry@no{scrextend}
+ \sorry@no{exsheets}
+ \sorry@no{eqparbox}
+ \sorry@no{colortbl}
+ \sorry@no{tikz}
+ \sorry@no{pstricks}
+ \sorry@no{xypic}
+ \sorry@no{xfig}
+ \sorry@no{pgfcalendar}
+ \sorry@no{pgfpages}
+ \sorry@no{pst-pdf}
+ \sorry@no{auto-pst-pdf}
+ \sorry@no{epstopdf}
+ \sorry@no{pdftricks}
+ \sorry@no{pdftricks2}
+ \sorry@no{mpgraphics}
+ \sorry@no{pict2e}
+ \sorry@no{picman}
+ \sorry@no{scalerel}
+ \sorry@no{pmgraph}
+ \sorry@no{reflectgraphics}
+ \fi % end sandbox.
+ % Alert packages, might cause minor layout problems, not enough to block:
+ \alert@nodisp{nth}
+ \alert@nodisp{engord}
+ \alert@nodisp{ulem}
+ \alert@nodisp{soul}
+ % end list of Alert packages.
+ % Package `pagegrid' interacts with `shademargins' and `draft' options:
+ \@ifpackageloaded{pagegrid}{ % that is, if permitted by sandbox or unblock
+ \ifdraftdoc
+ \if@shademargins
+ \ClassWarning{novel}{^^JGrid from `pagegrid' is concealed. ^^J%
+ Document class option `shademargins' over-writes page grid. ^^J%
+ To see the grid, use `draft' but not `shademargins'. ^^J}
+ \else\fi
+ \else
+ \ClassError{novel}{Package `pagegrid' needs `draft' mode}%
+ {Package `pagegrid' only with document class option `draft'.}%
+ \fi
+ }{} % end if pagegrid
+}% end \AtBeginDocument
+%%
+
+
+%% AtEndDocument adds one or two blank pages, required by printers.
+% Also writes list of inspected, good images to aux, for later use:
+\AtEndDocument{%
+ \if@coverart\else%
+ \if@sandbox\else%
+ \immediate\write\@auxout{%
+ \string\xdef\string\@AllGoodImages{\@AllGoodImages}^^J%
+ \string\xdef\string\@UnknownImages{\@UnknownImages}^^J%
+ }%
+ \cleartoend% adds 1 or 2 blanks, for final verso blank
+ \fi%
+ \fi%
+}
+%%
+
+
+%% AfterEndDocument writes final message:
+\AfterEndDocument{
+ \@WarnUnknownImages % in `novel-Images.sty'.
+}
+%%
+
+
+
+%%
+%% End of file `novel.cls'
+
diff --git a/macros/luatex/latex/odsfile/README b/macros/luatex/latex/odsfile/README
new file mode 100644
index 0000000000..50ba5f3333
--- /dev/null
+++ b/macros/luatex/latex/odsfile/README
@@ -0,0 +1,53 @@
+Introduction
+------------
+
+The odsfile is LuaLaTeX package and lua library for working with
+opendocument spreadsheet (ods) documents from Open/Libre Office Calc.
+It is possible to select cells from sheets and typeset them as LaTeX tables,
+it is also possible to pass these data to LaTeX macros and make some plots,
+for example.
+
+There is also simple interface to add data to existing spreadsheets. This
+functionality requires external zip utility.
+
+This package uses LuaTeX's zip library and scripting to read these files.
+It also requires LuaXML library, which is available to download from
+CTAN site.
+
+Because of lua scripting, it is not possible to use this package with pdfLaTeX
+or XeLaTeX. On the other side, odsfile.lua library can be used from PlainTeX,
+ConTeXt or pure lua scripts.
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this license or
+(at your option) any later version. The latest version of this license is in
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3 or later is part of all distributions of LaTeX version
+2005/12/01 or later.
+
+Basic usage
+-----------
+
+\usepackage{odsfile,booktabs}
+
+...
+
+\includespread[\begin{tabular}{l l}
+\includespread[file=pokus.ods]
+\end{tabular}
+
+...
+
+You can also use templates to specify tabular properties automaticaly
+\includespread[columns=top,template=booktabs,range=a3:c5]
+
+Author
+------
+Michal Hoftich
+Email: michal.h21@gmail.com
+
+If you are interested in the process of development you may observe
+
+ https://github.com/michal-h21/odsfile
diff --git a/macros/luatex/latex/odsfile/odsfile.lua b/macros/luatex/latex/odsfile/odsfile.lua
new file mode 100644
index 0000000000..5017b7bc16
--- /dev/null
+++ b/macros/luatex/latex/odsfile/odsfile.lua
@@ -0,0 +1,300 @@
+module(...,package.seeall)
+require "zip"
+local xmlparser = require ("luaxml-mod-xml")
+local handler = require("luaxml-mod-handler")
+
+local namedRanges = {}
+
+function load(filename)
+ local p = {
+ file = zip.open(filename),
+ content_file_name = "content.xml",
+ loadContent = function(self,filename)
+ local treehandler = handler.simpleTreeHandler()
+ local filename = filename or self.content_file_name
+ local xmlfile = self.file:open(filename)
+ local text = xmlfile:read("*a")
+ local xml = xmlparser.xmlParser(treehandler)
+ xml:parse(text)
+ return treehandler
+ end
+ }
+ return p
+end
+
+function getTable(x,table_name)
+ local t = getTable0(x,table_name)
+ local t2 = {}
+
+ for key, val in pairs(t) do
+ if key == "table:table-row" then
+ local rows = {}
+
+ for i = 1, #val do
+ local r = val[i]
+ local rowRep = r["_attr"]["table:number-rows-repeated"] or 1
+
+ row = {}
+ row["_attr"] = r["_attr"]
+ local cc = r["table:table-cell"] or {}
+ if #cc == 0 then
+ cc = {cc}
+ end
+
+ local columns = {}
+ --for j = 1, #cc do
+ -- local c = cc[j]
+ for _, c in ipairs(cc) do
+ c["_attr"] = c["_attr"] or {}
+ local colRep = c["_attr"]["table:number-columns-repeated"] or 1
+ for k = 1, colRep, 1 do
+ table.insert(columns, c)
+ end
+ end
+ row["table:table-cell"] = columns
+
+ for j = 1, rowRep, 1 do
+ table.insert(rows, row)
+ end
+ end
+
+ t2[key] = rows
+ else
+ t2[key] = val
+ end
+ end
+
+ return t2
+end
+
+function getTable0(x,table_name)
+ local tables = x.root["office:document-content"]["office:body"]["office:spreadsheet"]["table:table"]
+ namedRanges = loadNameRanges(x, table_name)
+ if #tables > 1 then
+ if type(tables) == "table" and table_name ~= nil then
+ for k,v in pairs(tables) do
+ if(v["_attr"]["table:name"]==table_name) then
+ return v, k
+ end
+ end
+ elseif type(tables) == "table" and table_name == nil then
+ return tables[1], 1
+ else
+ return tables
+ end
+ else
+ return tables
+ end
+end
+
+function getColumnCount(tbl)
+ local tbl = tbl or {}
+ local columns = tbl["table:table-column"] or {}
+ local x = 0
+ for _, c in pairs(columns) do
+ local rep = c["table:number-columns-repeated"] or 1
+ x = x + rep
+ end
+ return x
+end
+
+function loadNameRanges(root, tblname)
+ local tblname = tblname or ""
+ local t = {}
+ local ranges = root.root["office:document-content"]["office:body"]["office:spreadsheet"]["table:named-expressions"]
+ if not ranges then return {} end
+ ranges = ranges["table:named-range"] or {}
+ if #ranges == 0 then
+ ranges = {ranges}
+ end
+ for _,r in ipairs(ranges) do
+ local a = r["_attr"] or {}
+ local range = a["table:cell-range-address"] or ""
+ local name = a["table:name"]
+ if name and range:match("^"..tblname) then
+ range = range:gsub("^[^%.]*",""):gsub("[%$%.]","")
+ print("named range", name, range)
+ t[name] = range
+ end
+ end
+ return t
+end
+
+
+
+
+
+function tableValues(tbl,x1,y1,x2,y2)
+ local t= {}
+ local x1 = x1 or 1
+ local x2 = x2 or getColumnCount(tbl)
+ if type(tbl["table:table-row"])=="table" then
+ local rows = table_slice(tbl["table:table-row"],y1,y2)
+ for k,v in pairs(rows) do
+ -- In every sheet, there are two rows with no data at the bottom, we need to strip them
+ if(v["_attr"] and v["_attr"]["table:number-rows-repeated"] and tonumber(v["_attr"]["table:number-rows-repeated"])>10000) then break end
+ local j = {}
+ if #v["table:table-cell"] > 1 then
+ local r = table_slice(v["table:table-cell"],x1,x2)
+ for p,n in pairs(r) do
+ local attr = n["_attr"]
+ local cellValue = n["text:p"] or ""
+ table.insert(j,{value=cellValue,attr=attr})
+ end
+ else
+ local p = {value=v["table:table-cell"]["text:p"],attr=v["table:table-cell"]["_attr"]}
+ table.insert(j,p)
+ end
+ table.insert(t,j)
+ end
+ end
+ return t
+end
+
+function getRange(range)
+ local range = namedRanges[range] or range
+ local r = range:lower()
+ local function getNumber(s)
+ if s == "" or s == nil then return nil end
+ local f,ex = 0,0
+ for i in string.gmatch(s:reverse(),"(.)") do
+ f = f + (i:byte()-96) * 26 ^ ex
+ ex = ex + 1
+ end
+ return f
+ end
+ for x1,y1,x2,y2 in r:gmatch("(%a*)(%d*):*(%a*)(%d*)") do
+ return getNumber(x1),tonumber(y1),getNumber(x2),tonumber(y2)
+ --print(string.format("%s, %s, %s, %s",getNumber(x1),y1,getNumber(x2),y2))
+ end
+end
+
+function table_slice (values,i1,i2)
+ -- Function from http://snippets.luacode.org/snippets/Table_Slice_116
+ local res = {}
+ local n = #values
+ -- default values for range
+ i1 = i1 or 1
+ i2 = i2 or n
+ if i2 < 0 then
+ i2 = n + i2 + 1
+ elseif i2 > n then
+ i2 = n
+ end
+ if i1 < 1 or i1 > n then
+ return {}
+ end
+ local k = 1
+ for i = i1,i2 do
+ res[k] = values[i]
+ k = k + 1
+ end
+ return res
+end
+
+function interp(s, tab)
+ return (s:gsub('(-%b{})',
+ function(w)
+ s = w:sub(3, -2)
+ s = tonumber(s) or s
+ return tab[s] or w
+ end)
+ )
+end
+
+get_link = function(val)
+ local k = val["text:a"][1]
+ local href = val["text:a"]["_attr"]["xlink:href"]
+ return "\\odslink{"..href.."}{"..k.."}"
+end
+
+function escape(s)
+ return string.gsub(s, "([#%%$&])", "\\%1")
+end
+
+function get_cell(val, delim)
+ local val = val or ""
+ local typ = type(val)
+ if typ == "string" then
+ return escape(val)
+ elseif typ == "table" then
+ if val["text:a"] then
+ return get_link(val)
+ elseif val["text:span"] then
+ return get_cell(val["text:span"], delim)
+ elseif val["text:s"] then
+ -- return get_cell(val["text:s"], delim)
+ return table.concat(val, " ")
+ else
+ local t = {}
+ for _,v in ipairs(val) do
+ local c = get_cell(v, delim)
+ table.insert(t, c)
+ end
+ return table.concat(t,delim)
+ end
+ end
+end
+
+-- Interface for adding new rows to the spreadsheet
+
+function newRow()
+ local p = {
+ pos = 0,
+ cells = {},
+ -- Generic function for inserting cell
+ addCell = function(self,val, attr,pos)
+ if pos then
+ table.insert(self.cells,pos,{["text:p"] = val, ["_attr"] = attr})
+ self.pos = pos
+ else
+ self.pos = self.pos + 1
+ table.insert(self.cells,self.pos,{["text:p"] = val, ["_attr"] = attr})
+ end
+ end,
+ addString = function(self,s,attr,pos)
+ local attr = attr or {}
+ attr["office:value-type"] = "string"
+ self:addCell(s,attr,pos)
+ end,
+ addFloat = function(self,i,attr,pos)
+ local attr = attr or {}
+ local s = tonumber(i) or 0
+ s = tostring(s)
+ attr["office:value-type"] = "float"
+ attr["office:value"] = s
+ self:addCell(s,attr,pos)
+ end,
+ findLastRow = function(self,sheet)
+ for i= #sheet["table:table-row"],1,-1 do
+ if sheet["table:table-row"][i]["_attr"]["table:number-rows-repeated"] then
+ return i
+ end
+ end
+ return #sheet["table:table-row"]+1
+ end,
+ insert = function(self, sheet, pos)
+ local t = {}
+ local pos = pos or self:findLastRow(sheet)
+ print("pos je: ",pos)
+ if sheet["table:table-column"]["_attr"] and sheet["table:table-column"]["_attr"]["table:number-columns-repeated"] then
+ table_columns = sheet["table:table-column"]["_attr"]["table:number-columns-repeated"]
+ else
+ table_columns = #sheet["table:table-column"]
+ end
+ for i=1, table_columns do
+ table.insert(t,self.cells[i] or {})
+ end
+ t = {["table:table-cell"]=t}
+ table.insert(sheet["table:table-row"],pos,t)
+ end
+ }
+ return p
+end
+
+
+-- function for updateing the archive. Depends on external zip utility
+function updateZip(zipfile, updatefile)
+ local command = string.format("zip %s %s",zipfile, updatefile)
+ print ("Updating an ods file.\n" ..command .."\n Return code: ", os.execute(command))
+end
diff --git a/macros/luatex/latex/odsfile/odsfile.pdf b/macros/luatex/latex/odsfile/odsfile.pdf
new file mode 100644
index 0000000000..3aaee3587b
--- /dev/null
+++ b/macros/luatex/latex/odsfile/odsfile.pdf
Binary files differ
diff --git a/macros/luatex/latex/odsfile/odsfile.sty b/macros/luatex/latex/odsfile/odsfile.sty
new file mode 100644
index 0000000000..97f9e0d9c6
--- /dev/null
+++ b/macros/luatex/latex/odsfile/odsfile.sty
@@ -0,0 +1,256 @@
+\ProvidesPackage{odsfile}
+\RequirePackage{luacode,xkeyval}
+
+%keyval keys
+
+\define@key{includespread}{file}{\loadodsfile{#1}}%
+\define@key{includespread}{sheet}{\luaexec{sheetname = "\luatexluaescapestring{#1}"}}%
+\define@key{includespread}{range}{\luaexec{%
+local x1,y1,x2,y2 = odsreader.getRange("\luatexluaescapestring{#1}")%
+range = {x1,y1,x2,y2}%
+}}
+\define@key{includespread}{template}{\luaexec{currenttemplate="\luatexluaescapestring{#1}"}}%
+\define@key{includespread}{rowtemplate}{\luaexec{rowtemplate="\luatexluaescapestring{\unexpanded{#1}}"}}%
+\define@key{includespread}{multicoltemplate}{\luaexec{multicoltpl="\luatexluaescapestring{\unexpanded{#1}}"}}%
+
+\define@choicekey*+{includespread}{rowseparator}[\val\nr]{tableline,hline,newline}[tableline]%
+{%
+\ifcase\nr\relax%
+ \luaexec{rowseparator=""}%
+\or%
+ \luaexec{rowseparator="\\hline "}%
+\or%
+\luaexec{%
+rowseparator=[[\\n]]
+}
+\fi%
+}{%
+ \luaexec{rowseparator="\luatexluaescapestring{#1}"}
+}
+\define@key{includespread}{columnbreak}{%
+ \luaexec{columnbreak="\luatexluaescapestring{\unexpanded{#1}}{}"}%
+}
+\define@key{includespread}{coltypes}{%
+ \luaexec{coltypes="\luatexluaescapestring{\unexpanded{#1}}"}%
+}
+\define@choicekey*+{includespread}{columns}[\val\nr]{head,top,none}{%
+\ifcase\nr\relax%
+ \luaexec{columns=1}%
+\or%
+ \luaexec{columns=2}%
+\fi%
+}{%
+\luaexec{%
+local function split(s,sep)
+ local sep, fields = sep or ":", {}
+ local pattern = string.format("([^\%s]+)", sep)
+ s:gsub(pattern, function(c) fields[\#fields+1] = c end)
+ return fields
+end
+local s="\luatexluaescapestring{#1}"
+columns = split(s,",")
+}%
+}{}%
+
+
+% Variable initialization and helper functions
+\begin{luacode*}
+odsreader = require("odsfile")
+odsfile = nil
+sheetname = nil
+range = {nil,nil,nil,nil}
+columns = nil
+templates = {}
+row = {}
+body = nil
+odsfilename = ""
+currenttemplate = nil
+rowtemplate = nil
+multicoltpl = "\\multicolumn{-{count}}{l}{-{value}}"
+\end{luacode*}
+
+\newcommand\loadodsfile[2][]{%
+ \setkeys{includespread}{#1}%
+ \luaexec{%
+ odsfilename = "\luatexluaescapestring{#2}"%
+ local ods = odsreader.load(odsfilename)%
+ odsfile, e = ods:loadContent()%
+ }%
+}
+
+\newcommand\tabletemplate[2]{%
+ \luaexec{%
+ templates["#1"]="\luatexluaescapestring{\unexpanded{#2}}"%
+ }
+}
+
+\newcommand\includespread[1][]{%
+ \luaexec{%
+ range = {nil,nil,nil,nil}
+ rowseparator = ""
+ columns=nil
+ currenttemplate = nil
+ rowtemplate = nil
+ columnbreak = "\\linebreak{}"
+ coltypes = nil
+ }%
+ \setkeys{includespread}{#1}%
+ \luaexec{%
+ body = odsreader.getTable(odsfile,sheetname)
+ local values = odsreader.tableValues(body,range[1],range[2],range[3],range[4])
+ %-- Conversion of odsfile table values to LaTeX tabular
+ local concatParagraphs = function(column)
+ % -- second returned value signalize whether cell contain paragraph, or not
+ local getCell = odsreader.get_cell
+ if type(column) =="table" then
+ return getCell(column, columnbreak), true
+ end
+ return getCell(column,""), false
+ end
+ local rowValues = function(row, headings)
+ local headings = headings or {}
+ local t={}
+ local i = 1
+ for _,column in pairs(row) do
+ local attr = column.attr or {}
+ local value, br = concatParagraphs(column.value)
+ value = value or ""
+ local x = attr["table:number-columns-spanned"] or "1"
+ x = tonumber(x)
+ if x > 1 then
+ value = odsreader.interp(multicoltpl, {value = value, count = x})
+ end
+ table.insert(t,value)
+ headings[i] = br
+ i = i + x
+ end
+ return t, headings
+ end
+ local makeColtypes = function(h)
+ local maxsize = tex.hsize / 65536
+ local h = h or {}
+ local p = 0
+ for _, c in pairs(h) do
+ if c then
+ p = p + 1
+ end
+ end
+ if p > 0 then
+ local j = {}
+ local size = tostring(math.floor(maxsize / \#h)) .. "pt"
+ for _, c in pairs(h) do
+ local k = "l"
+ if c then k = "p{"..size.."}" end
+ j[\#j+1]= k
+ end
+ return table.concat(j)
+ else
+ return string.rep("l",\#h)
+ end
+ end
+ if rowtemplate == nil then
+ local headings = {}
+ local currow = {}
+ currenttemplate = currenttemplate or "default"
+ content = {}
+ for i,row in pairs(values) do
+ currow, headings = rowValues(row, headings)
+ table.insert(content,table.concat(currow," & "))
+ end
+ %-- Column headings handling
+ local colheading=""
+ if type(columns) == "number" and columns == 1 then
+ columns = rowValues(values[1])
+ content = odsreader.table_slice(content,2,nil)
+ elseif type(columns) == "number" and columns == 2 then
+ local t = odsreader.tableValues(body,range[1],1,range[3],2)
+ columns = rowValues(t[1])
+ end
+ if type(columns) == "table" then colheading = table.concat(columns," & ") .. "\\\\" end
+ % coltypes = ""
+ if type(content)== "table" then
+ % coltypes= string.rep("l",\#content[1])
+ if not coltypes then
+ coltypes = makeColtypes(headings)
+ end
+ end
+ content = table.concat(content, "\\\\ "..rowseparator) .. "\\\\"
+ local result = odsreader.interp(templates[currenttemplate],{content=content,coltypes=coltypes,colheading=colheading,rowsep=rowseparator})
+ print(result)
+ tex.print(result)
+ else
+ local content = {}
+ currenttemplate = currenttemplate or "empty"
+ for _,row in pairs(values) do
+ table.insert(content,odsreader.interp(rowtemplate,rowValues(row)))
+ end
+ content = table.concat(content,rowseparator)
+ local result = odsreader.interp(templates[currenttemplate],{content=content,coltypes=coltypes,colheading=colheading,rowsep=rowseparator})
+ print(result)
+ tex.sprint(result)
+ end
+ }%
+}%
+
+\tabletemplate{empty}{-{content}}
+
+\tabletemplate{default}{-{colheading}-{rowsep}-{content}}
+
+\tabletemplate{booktabs}{%
+\begin{tabular}{-{coltypes}}
+\toprule
+-{colheading}
+\midrule
+-{content}
+\\ \bottomrule
+\end{tabular}
+}
+
+% Interface for adding of new rows
+
+\newenvironment{AddRow}[1][]{%
+\def\AddString##1##2{%
+\luaexec{%
+local pos = "\luatexluaescapestring{##2}"%
+if pos == "" then pos = nil end; row:addString("\luatexluaescapestring{\unexpanded{##1}}",nil,pos)%
+}%
+}%
+\def\AddNumber##1##2{%
+\luaexec{%
+local pos = "\luatexluaescapestring{##2}"%
+if pos == "" then pos = nil end; row:addFloat("\luatexluaescapestring{##1}",nil,pos)%
+}%
+}%
+\luaexec{%
+pos = "\luatexluaescapestring{#1}"%
+if pos == "" then pos = nil end; row = odsreader.newRow()%
+}%
+}{%
+\luaexec{%
+body = body or odsreader.getTable(odsfile)
+row:insert(body,pos)%
+}%
+}
+
+% Interface for saving the spreadsheet
+
+\newcommand\savespreadsheet{%
+\luaexec{%
+ local xml = require("luaxml-mod-xml")
+ f = io.open("content.xml","w")%
+ f:write(xml.serialize(odsfile.root))%
+ f:close()%
+ odsreader.updateZip(odsfilename,"content.xml")%
+}%
+}
+
+% support for hyperlinks in cells
+
+\newcommand\odslink[2]{\texttt{#2}}
+
+\AtBeginDocument{%
+ \@ifpackageloaded{hyperref}{%
+ \renewcommand\odslink[2]{\href{#1}{#2}}%
+ }{}
+}
+\endinput
diff --git a/macros/luatex/latex/odsfile/odsfile.tex b/macros/luatex/latex/odsfile/odsfile.tex
new file mode 100644
index 0000000000..cf2d141f6a
--- /dev/null
+++ b/macros/luatex/latex/odsfile/odsfile.tex
@@ -0,0 +1,404 @@
+\documentclass{ltxdoc}
+\usepackage[utf8]{luainputenc}
+\usepackage[T1]{fontenc}
+\usepackage{odsfile,tgschola,metalogo,hyperref,xspace,microtype,showexpl,booktabs,url}
+\author{Michal Hoftich (\url{michal.h21@gmail.com})}
+\title{The \textsf{odsfile} package:\\
+accessing of the \textsf{opendocument spreadsheet} from \LaTeX{}
+documents\thanks{Version 0.6, last revisited 2015-09-20.}
+}
+\usepackage[english]{babel}
+\lstloadlanguages{[LaTeX]Tex}
+\lstset{%
+ basicstyle=\ttfamily,
+ commentstyle=\itshape\ttfamily,
+ showspaces=false,
+ showstringspaces=false,
+ breaklines=true,
+ breakautoindent=true,
+ captionpos=t
+}
+
+\newcommand\ods{\textsf{ods}\xspace}
+
+\begin{document}
+\maketitle
+
+\tableofcontents
+
+\section{Introduction}
+
+This is \LuaLaTeX{} package and \textsf{lua} library for working with
+\textsf{opendocument spreadsheet} (\ods) documents from Open/Libre Office Calc.
+Their contents can be read as \LaTeX{} tables, can be pass to macros,
+ you can also add new data to existing spreadsheets.
+
+\ods format consist of number of |xml| files packed in the |zip| file.
+This package uses \LuaTeX's zip library, LuaXML library\footnote{Pure |lua| library
+for working with |xml| files, it is available form CTAN or \url{https://github.com/michal-h21/LuaXML}} and lua scripting to read |xml| content from this archive,
+which means that it is not possible to use this package with pdf\LaTeX{} or \XeLaTeX.
+On the other side, |odsfile.lua| library can be used from Plain\TeX,
+Con\TeX{}t or pure |lua| scripts.
+
+Creation of this package was motivated by question\footnote{\url{http://tex.stackexchange.com/questions/60378/insert-libreoffice-table-as-input}} on site \url{http://tex.stackexchange.com/}. Development version of the package can be found at \url{https://github.com/michal-h21/odsfile}, all contributions and comments are welcome.
+\section{Usage}
+
+You can load |odsfile| classically with
+\begin{verbatim}
+\usepackage{odsfile}
+\end{verbatim}
+There are macros:
+\begin{itemize}
+\item \cmd{\includespread}
+\item \cmd{\tabletemplate}
+\item \cmd{\loadodsfile}
+\item \cmd{\savespreadsheet}
+\item |AddRow| environment
+\end{itemize}
+
+\noindent Main command is\marginpar{\cmd{\includespread}} \cmd{\includespread}. It's syntax is:\\
+\cmd{\includespread}\oarg{key-value list}
+
+Options are:
+
+\begin{description}
+\item[file] Filename of file to be loaded. You should specify this only on first use of \cmd{\includespread}.
+\item[sheet] Name of sheet to be loaded. If it's not specified on first use of
+ \cmd{\includespread}, then first sheet from the file is loaded. The sheet
+ remains selected until another use of |sheet|.
+
+\begin{LTXexample}
+\begin{tabular}{l l}
+\includespread[file=pokus.ods,sheet=List2]
+\end{tabular}
+\end{LTXexample}
+
+\item[range] Selects range from table to be inserted. Range is specified in
+ format similar to spreadsheet processors, like |a2:c4|, selecting cells
+ starting at first column, second row and ending and third column, fourth row.
+ Other variant of supported ranges are \textit{named ranges}, which can be
+ saved in the |ods file|.
+
+\begin{LTXexample}
+\begin{tabular}{lll}
+\includespread[sheet=List1,range=a2:c4]
+\end{tabular}
+\end{LTXexample}
+You can omit some or both of the numbers:
+\begin{LTXexample}
+\begin{tabular}{lll}
+\includespread[range=a:c4]
+\end{tabular}
+\end{LTXexample}
+
+\begin{LTXexample}
+\begin{tabular}{ll}
+\includespread[range=a:b]
+\end{tabular}
+\end{LTXexample}
+
+\begin{LTXexample}
+\begin{tabular}{ll}
+\includespread[range=b2:c]
+\end{tabular}
+\end{LTXexample}
+\item[columns] Column heading specification. It can be either |head|, |top|, or comma separated list of values.
+\begin{description}
+\item[top] Use as headers first line from the table.
+\begin{LTXexample}
+\begin{tabular}{ll}
+\includespread[range=b3:c5,columns=top]
+\end{tabular}
+\end{LTXexample}
+Note that if you include whole table, first line is included twice:
+\begin{LTXexample}
+\begin{tabular}{lll}
+\includespread[columns=top]
+\end{tabular}
+\end{LTXexample}
+in this case you can use
+\item[head] use first row from selection as headings.
+\begin{LTXexample}
+\begin{tabular}{lll}
+\includespread[columns=head,range=a:c3]
+\end{tabular}
+\end{LTXexample}
+\item[manually specified list] If column headings are not specified in the file, you can set them manually.
+\begin{LTXexample}
+\begin{tabular}{ll}
+\includespread[columns={title,amount},sheet=List2]
+\end{tabular}
+\end{LTXexample}
+\end{description}
+\item[columnbreak] Command inserted in manual linebreaks in cells. Default value is |\linebreak|
+
+\item[rowseparator] Rows are normally separated with newlines, if you really want, you can separate them with hlines.
+
+Possible values:
+\begin{description}
+\item[tableline (default)] Inserts |\\| character
+\item[hline] Inserts |\\ \\hline|
+\item[newline] Inserts blank line
+\item[user specified separator] useful in conjunction with \ref{it:rowtemplate}
+(p. \pageref{it:rowtemplate}), for example if you want to include sheets
+as plaintext or input for plotting functions.
+\end{description}
+\begin{LTXexample}
+\begin{tabular}{lll}
+\includespread[columns=top,sheet=List1,rowseparator=hline,range=a2:b5]
+\end{tabular}
+\end{LTXexample}
+
+\item[template] Templates are simple mechanism to insert whole tabular environment with column specification. All columns are aligned to the left, if you want to do more advanced stuff with column specifications, you must enter them manually as in all previous examples.
+\begin{LTXexample}
+\includespread[columns=top,template=booktabs,range=a3]
+\end{LTXexample}
+For more info about templates, see next section \ref{sec:tpl}
+
+\item[coltypes] When using template, column types are inferred automatically. If that doesn't work well in your case, you can specify them manually with |coltypes| option.
+
+ \begin{LTXexample}
+ \includespread[columns=head, template=booktabs, coltypes=lrr]
+ \end{LTXexample}
+
+\item[rowtemplate]
+\makeatletter
+\edef\@currentlabel{rowtemplate}
+\label{it:rowtemplate} Enables to convert tabular data to something different than \LaTeX\ tables.
+Syntax for rowtemplates is similar to the table templates, variables are inserted with |-{number}|, where
+number is the position of the cell from beginning of the selection.
+\makeatother
+\begin{LTXexample}
+\includespread[range=a2:b,rowseparator={,\ },rowtemplate={\textit{-{1}}:-{2}}]
+\end{LTXexample}
+
+\item[multicoltemplate]
+supports merged cells. Default template uses left aligned \verb|\multicolumn|
+command
+\begin{LTXexample}
+ \begin{tabular}{lll}
+ \includespread[sheet=Sheet3, multicoltemplate={\multicolumn{-{count}}{r}{-{value}}}]
+ \end{tabular}
+\end{LTXexample}
+
+\end{description}
+
+
+\section{Templates}\label{sec:tpl}
+
+If you don't want to specify tabular environment by hand, you can use simple templating mechanism to insert tabular environment by hand.
+
+Templates are defined with macro\marginpar{\cmd{\tabletemplate}}\\
+\cmd{\tabletemplate}\marg{template name}\marg{template code}\\
+there is default template:
+\begin{verbatim}
+\tabletemplate{default}{-{colheading}-{rowsep}-{content}}
+\end{verbatim}
+
+Code |-{variable name}| inserts one of the following variables:
+
+\begin{description}
+\item[coltypes] This is code to be inserted in |\begin{tabular}{coltypes}|. %In current version, it inserts |l| for left alignment column, for all columns of inserted table.
+%It should be possible to use more intelligent method based on types of column content, or \ods styles, maybe in future versions some of them will be used. If you want other alignment of columns now, you have to specify |\begin{tabular}{column types}| manually.
+The |p| column specifier is used for each column, where cell with manual line break occurs, |l| is used otherwise.
+
+\item[colheading] Column headings.
+\item[rowsep] It inserts row separator defined with |rowsepartor| key of |\includespread|. It is used in default style to delimit column headings and table contents.
+\item[content] Tabular data.
+\end{description}
+
+\paragraph{More powerful template for the \textsc{booktabs} package}
+
+\begin{verbatim}
+\tabletemplate{booktabs}{%
+\begin{tabular}{-{coltypes}}
+\toprule
+-{colheading}
+\midrule
+-{content}
+\\ \bottomrule
+\end{tabular}
+}
+\end{verbatim}
+
+\section{Adding data}
+
+There is simple interface for adding new rows to the spreadsheet.
+
+|AddRow|\oarg{row number}\marginpar{|AddRow|} environment for adding new row to the current sheet. Optional argument \oarg{row number} specifies where it should be inserted, if blank, it will be inserted at end.
+
+Inside |AddRow|, you can use
+\begin{itemize}
+ \item \cmd{\AddString}\marg{text}\marg{position}
+ \item \cmd{\AddNumber}\marg{number}\marg{position}
+\end{itemize}
+Position specifies cell, where data should be added, if you leave it blank, it will be laced next to the previous one.
+
+\begin{LTXexample}
+\includespread[columns=head,template=booktabs]
+\begin{AddRow}
+ \AddString{last row}{}
+\end{AddRow}
+\begin{AddRow}[3]
+ \AddString{third row}{}
+ \AddNumber{22}{2}
+\end{AddRow}
+\includespread[columns=head,template=booktabs]
+\end{LTXexample}
+
+\section{Loading and saving of the \ods file}
+
+You can explicitly load \ods file with \marginpar{\cmd{\loadodsfile}}\cmd{\loadodsfile}\oarg{key val list}\marg{filename}. This can be useful, if you only want to write some data to the file, otherwise it is better to use \cmd{\includespread}.
+
+For saving spreadsheets modified with |AddRow|, you can use \cmd{\savespreadsheet}\marginpar{\cmd{\savespreadsheet}}. This command uses call to external |zip| utility, so you should have installed it and you have to call lua\LaTeX with |lualatex --shell-escape filename|. Lua\LaTeX also must have write permissions for accessing the \ods file. This command creates file |content.xml| in the current directory, so if externall call fails, you can run
+\begin{verbatim}
+zip -r filename.ods content.xml
+\end{verbatim}
+by hand.
+\section{Lua library}
+
+
+The |lua| library uses |luazip| library integrated to \LuaTeX{} and |LuaXML|\footnote{\url{https://github.com/michal-h21/LuaXML}}, pure |lua| library for working with |XML| files.
+
+To use library in your code, you can use:
+
+\begin{verbatim}
+require("odsfile")
+\end{verbatim}
+
+Function |odsfile.load(filename)| returns |odsfile| object, with |loadContent()| method, which returns |lua| table representing |content.xml| file. We can select sheet from the spreadsheet with |odsfile.getTable(xmlobject,sheet_name)|. If we omit |sheet_name|, first sheet from spreadsheet is selected.
+
+Data from sheet can be read with |odsfile.tableValues(sheet, x1, y1, x2, y2)|. |x1 - y2| are range to be selected, they can be |nil|, in which case whole rows and cells are selected. For converting of standard range expressions of form |a1:b2| to this representation, function |odsfile.getRange(range)| can be used.
+
+\paragraph{Example usage -- file \textsf{odsexample.lua}}
+
+\begin{verbatim}
+require "odsfile"
+
+-- Helper function to print structure of the table
+function printable(tb, level)
+ level = level or 1
+ local spaces = string.rep(' ', level*2)
+ for k,v in pairs(tb) do
+ if type(v) ~= "table" then
+ print(spaces .. k..'='..v)
+ else
+ print(spaces .. k)
+ level = level + 1
+ printable(v, level)
+ end
+ end
+end
+
+local ods = odsfile.load("filename.ods")
+local f, e = ods:loadContent()
+
+-- Get First sheet from the table
+body= odsfile.getTable(f)
+-- Print structure of the range a4:b5
+printable(odsfile.tableValues(body,odsfile.getRange("a4:b5")))
+\end{verbatim}
+
+Run the example with |texlua odsexample.lua| from the command line, you should get following result:
+
+\begin{verbatim}
+ 1
+ 1
+ value=AA
+ attr
+ office:value-type=string
+ 2
+ value=3
+ attr
+ office:value-type=float
+ office:value=3
+ 2
+ 1
+ value=BB
+ attr
+ office:value-type=string
+ 2
+ value=4
+ attr
+ office:value-type=float
+ office:value=4
+\end{verbatim}
+
+To convert this structure to \LaTeX{} tabular code, you can use following function:
+
+\begin{verbatim}
+function tableToTabular(values)
+ local rowValues = function(row)
+ local t={}
+ for _,column in pairs(row) do table.insert(t,column.value) end
+ return t
+ end
+ content = {}
+ for i,row in pairs(values) do
+ table.insert(content,table.concat(rowValues(row)," & "))
+ end
+ return table.concat(content,"\\\\\n")
+end
+-- Now use it with objects from previous example
+print(tableToTabular(odsfile.tableValues(body)))
+\end{verbatim}
+
+This example yields
+
+\begin{verbatim}
+Label & Position & Count\\
+Hello & 1 & 3\\
+World & 2 & 4\\
+AA & 3 & 5\\
+BB & 4 & 6\\
+CC & 5 & 7
+\end{verbatim}
+
+
+
+\section{Changes}
+
+\begin{description}
+
+\item[v0.6]
+ \begin{itemize}
+ \item Fixed bug in handling of rows with only one cell\footnote{Thanks to Ulrike Fisher}
+ \item Added support for named ranges
+ \item Fixed text:s handling. Beware that using multiple formatting styles
+ in one cell may result in discarding whole cell, or wrong order. This is
+ caused by underlying LuaXML library and it is likely to remain.
+\end{itemize}
+\item[v0.5]
+\begin{itemize}
+ \item Fixed bug: cell attributes weren't saved
+ \item Added support for merged cells
+ \item Added \texttt{multicoltemplate} option
+\end{itemize}
+
+\item[v0.4]
+\begin{itemize}
+ \item Fixed bugs in loading sheets without ranges
+ \item Fixed bugs in behaviour of empty cells\footnote{Thanks to \href{https://github.com/TripleWhy}{TrippleWhy}}
+ \item Fixed bug in row counting\footnote{Thanks to \href{https://github.com/yamsu}{yamsu}}
+ \item Added support for children element in column paragraphs
+ \item Added cell value escaping
+\end{itemize}
+\item[v0.3]
+\begin{itemize}
+ \item Added support for multiline cells
+ \item Improved automatic column types generation
+ \item Added new options, |coltypes| and |columnbreak|
+\end{itemize}
+\item[v0.2]
+\begin{itemize}
+ \item LuaXML is now distributed as separate library, so other projects can use it.
+ \item New |AddRow| environment for adding data to the \ods file
+ \item New command |\savespreadsheet| for saving \ods file
+ \item Bug fixes: corrected loading of the sheets, corrected behaviour of blank cell
+\end{itemize}
+\item[v0.1] First version
+\end{description}
+
+
+
+\end{document}
diff --git a/macros/luatex/latex/odsfile/pokus.ods b/macros/luatex/latex/odsfile/pokus.ods
new file mode 100644
index 0000000000..e59b876215
--- /dev/null
+++ b/macros/luatex/latex/odsfile/pokus.ods
Binary files differ
diff --git a/macros/luatex/latex/pdfarticle/README b/macros/luatex/latex/pdfarticle/README
new file mode 100644
index 0000000000..ddfc7a690f
--- /dev/null
+++ b/macros/luatex/latex/pdfarticle/README
@@ -0,0 +1,6 @@
+pdfArticle is simple document class dedicated
+for creating pdf documents with LuaLaTeX.
+
+Copyright (C) 2015-2019, Robert Ryszard Paciorek <rrp@opcode.eu.org>
+
+This is free software distributed under terms of The MIT License.
diff --git a/macros/luatex/latex/pdfarticle/pdfArticle.cls b/macros/luatex/latex/pdfarticle/pdfArticle.cls
new file mode 100644
index 0000000000..6f6fe3aab3
--- /dev/null
+++ b/macros/luatex/latex/pdfarticle/pdfArticle.cls
@@ -0,0 +1,162 @@
+% Copyright (c) 2015-2019 Robert Ryszard Paciorek <rrp@opcode.eu.org>
+%
+% MIT License
+%
+% Permission is hereby granted, free of charge, to any person obtaining a copy
+% of this software and associated documentation files (the "Software"), to deal
+% in the Software without restriction, including without limitation the rights
+% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+% copies of the Software, and to permit persons to whom the Software is
+% furnished to do so, subject to the following conditions:
+%
+% The above copyright notice and this permission notice shall be included in all
+% copies or substantial portions of the Software.
+%
+% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+% SOFTWARE.
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{pdfArticle}[2019/05/01 v1.0 simple class for creating PDF documents with LuaLaTeX]
+
+\RequirePackage{kvoptions} % key=value option for class ... use also by hyperref, so zero overhead
+ \SetupKeyvalOptions{family=KVP, prefix=KVP@} % KVP = Key Val Parameters
+
+ % Fonts settings
+ \DeclareStringOption[11pt] {fontSize} % base size of font (8pt, 9pt, 10pt, 11pt, 12pt, 14pt, 17pt, or 20pt with extarticle document class)
+ \DeclareStringOption[
+ UprightFeatures = { SmallCapsFont={ lmromancaps10regular } },
+ ItalicFeatures = { SmallCapsFont={ lmromancaps10oblique } },
+ SlantedFont = lmromanslant10regular,
+ BoldSlantedFont = lmromanslant10bold,
+ Ligatures=TeX
+ ] {mainFontFeat} % features settings for mainFont
+ \DeclareStringOption[Latin Modern Roman] {mainFont} % document default main (serif) fornt
+ \DeclareStringOption[
+ Ligatures=TeX
+ ] {sansFontFeat} % features settings for sansFont
+ \DeclareStringOption[Latin Modern Sans] {sansFont} % document default main sans-serif fornt
+ \DeclareStringOption[
+ UprightFeatures = { SmallCapsFont={ lmmonocaps10regular } },
+ ItalicFont = lmmono10italic,
+ ItalicFeatures = { SmallCapsFont={ lmmonocaps10oblique } },
+ SlantedFont = lmmonoslant10regular
+ ] {monoFontFeat} % features settings for monoFont
+ \DeclareStringOption[Latin Modern Mono Light] {monoFont} % document default main mono-space fornt
+
+ % Paper settings
+ \DeclareStringOption[a4paper] {paperSize} % paper size
+ \DeclareStringOption[portrait] {paperMode} % paper orientation: portrait lub landscape
+ \DeclareStringOption[2.2cm] {tmargin} % top margin size
+ \DeclareStringOption[2.5cm] {bmargin} % bottom margin size
+ \DeclareStringOption[2.2cm] {lmargin} % left margin size
+ \DeclareStringOption[2.2cm] {rmargin} % right margin size
+ \DeclareBoolOption [true] {twoside} % two side mode (switch left/right margin size): true lub false
+
+ % Other settings
+ \DeclareStringOption[150] {imgResolution} % default resolution (ppi) for raster images inserted into PDF files (override by file header info)
+ \DeclareBoolOption [false] {extra} % enable load extra package set
+
+ \ProcessKeyvalOptions*
+
+% disable automatic convert eps -> pdf
+\def\DoNotLoadEpstopdf{\relax}
+
+% use extarticle as base class
+\LoadClass[\KVP@fontSize]{extarticle}
+
+% advanced fonts for LuaLaTeX
+\RequirePackage{fontspec}
+ \defaultfontfeatures[\rmfamily,\sffamily, \ttfamily]{}
+ \setmainfont{\KVP@mainFont}[\KVP@mainFontFeat]
+ \setsansfont{\KVP@sansFont}[\KVP@sansFontFeat]
+ \setmonofont{\KVP@monoFont}[\KVP@monoFontFeat]
+
+% insert images, with extended key=value interface ... set some defaults
+\RequirePackage{graphicx, graphbox}
+ \DeclareGraphicsExtensions{.mp, .pdf, .png, .jpg, .jpeg}
+ \pdfvariable imageresolution \KVP@imgResolution
+
+% foreground and background colours ... use stack of colors
+\RequirePackage{xcolor, fifo-stack}
+ \FSCreate{colors}{black}
+
+% page size and settings
+\RequirePackage{geometry}
+ \geometry{
+ \KVP@paperSize, \KVP@paperMode,
+ tmargin=\KVP@tmargin, bmargin=\KVP@bmargin, lmargin=\KVP@lmargin, rmargin=\KVP@rmargin
+ }
+ \ifKVP@twoside \geometry{twoside=true} \else \geometry{twoside=false} \fi
+
+% command for enforce new page geometry inside document, in contrast to \newgeometry:
+% * allow chage paper size and orientation (only pdf output)
+% * don't reset current settings (but allow modifies it)
+\newcommand{\forceNewPageGeometry}[1]{%
+ \clearpage%
+ \Gm@clean\setkeys{Gm}{#1}\Gm@process%
+ \eject \pagewidth=\paperwidth \pageheight=\paperheight%
+ \Gm@changelayout%
+ \ifdefined\headwidth\headwidth=\textwidth\fi%
+}
+
+% better verbatim environment ... replace standard verbatim environment by fancyvrb package
+\RequirePackage{fancyvrb, fvextra}
+ \DefineVerbatimEnvironment{verbatim}{Verbatim}{}
+ \let\verb\Verb
+ \fvset{breaklines=true, breakafter={/-}, breakaftersymbolpre={}, breakaftersymbolpost={\tiny\ensuremath{\ \hookrightarrow\ }}}
+
+ % text decorations (under line, striking out, highlight, contours, shadows, ...)
+\RequirePackage[normalem]{ulem}
+ \newcommand{\ul}[1][blue]{\bgroup\markoverwith{\textcolor{#1}{\rule[-0.6ex]{2pt}{0.17ex}}}\ULon}
+ \newcommand{\st}[1][red]{\bgroup\markoverwith{\textcolor{#1}{\rule[0.5ex]{2pt}{0.25ex}}}\ULon}
+ \newcommand{\hl}[1][yellow]{\bgroup\markoverwith{\textcolor{#1}{\rule[-0.6ex]{1.02pt}{2.7ex}}}\ULon}
+\RequirePackage{contour, shadowtext}
+
+% items lists
+\RequirePackage{enumitem} % better enumerate, itemize and description environments
+\RequirePackage{alphalph} % use display counters as letters with support for big numbers (as: ... x, y, z, aa, ab, ac, ...)
+ \let\alph\relax \def\alph#1{\alphalph{\value{#1}}}
+ \let\Alph\relax \def\Alph#1{\AlphAlph{\value{#1}}}
+
+% other useful stuff ...
+\RequirePackage{pbox,varwidth} % vertical box with automatic minimal width
+\RequirePackage{overpic} % put LaTeX stuff on images
+\RequirePackage{wrapfig} % wrapfigure and wraptable environments for wraping text around images, tables, etc
+\RequirePackage{array,dcolumn} % extentions for tables
+\RequirePackage{tabto} % tabbing to fixed positions
+\RequirePackage{changepage} % for adjustwidth environment
+\RequirePackage{ragged2e} % \justifying command, justify environment and alternative left, center and right ragged text
+\RequirePackage{setspace} % set line stretch with \setstretch{} command (it's more powerful way than \linespread{}\selectfont or manualy set \baselineskip)
+\RequirePackage{amsmath,unicode-math} % math with unicode open-type fonts
+\RequirePackage{adjustbox} % scale, clip, rotate, etc boxes
+
+\ifKVP@extra
+ \typeout{Document class "pdfArticle" starting to load "EXTRA" packages ...}\typeout{}
+ \RequirePackage{minted} % nice code highlight (use minted insted of listings, due to encoding problems in listings)
+ % \ifnum\pdf@shellescape=1 \RequirePackage{minted} \else \typeout{}\typeout{Warning: No -shell-escape, so DO NOT use minted package.} \fi
+ \RequirePackage[many,vignette,minted,magazine,poster,external]{tcolorbox} % nice framed boxes
+\fi
+
+% if \pdfArticlePreHyperRef is defined run it before load hyperref, but after load all other packages
+% (for loading packages and do other stuff than should be do before load hyperref)
+\ifdefined\pdfArticlePreHyperRef\pdfArticlePreHyperRef\fi
+
+% internal and external links ... use curent color from stack for refernces
+\RequirePackage[unicode=true, colorlinks=true, linkcolor=black, urlcolor=blue]{hyperref}
+ \let\oldref\ref
+ \AtBeginDocument{\renewcommand\ref[1]{\hyperref[#1]{\color{\FSTop{colors}}\oldref*{#1}}}}
+
+% create label with explicit provided name; usage: \namedLabel{label}{name}
+\newcommand\namedLabel[2]{\begingroup%
+ \let\@currentlabel\@currentlabelx%
+ \def\@currentlabel{#2}%
+ \label{#1}%
+ \let\@currentlabelx\@currentlabel%
+\endgroup}
+
+\typeout{Loading document class "pdfArticle" completed!}\typeout{}
diff --git a/macros/luatex/latex/pdfarticle/pdfArticle.pdf b/macros/luatex/latex/pdfarticle/pdfArticle.pdf
new file mode 100644
index 0000000000..7fd593d7c6
--- /dev/null
+++ b/macros/luatex/latex/pdfarticle/pdfArticle.pdf
Binary files differ
diff --git a/macros/luatex/latex/pdfarticle/pdfArticle.tex b/macros/luatex/latex/pdfarticle/pdfArticle.tex
new file mode 100644
index 0000000000..4a52518bf8
--- /dev/null
+++ b/macros/luatex/latex/pdfarticle/pdfArticle.tex
@@ -0,0 +1,125 @@
+% Copyright (c) 2015-2019 Robert Ryszard Paciorek <rrp@opcode.eu.org>
+%
+% MIT License
+%
+% Permission is hereby granted, free of charge, to any person obtaining a copy
+% of this software and associated documentation files (the "Software"), to deal
+% in the Software without restriction, including without limitation the rights
+% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+% copies of the Software, and to permit persons to whom the Software is
+% furnished to do so, subject to the following conditions:
+%
+% The above copyright notice and this permission notice shall be included in all
+% copies or substantial portions of the Software.
+%
+% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+% SOFTWARE.
+
+\documentclass[ fontSize=10pt, ]{pdfArticle}
+
+
+\title {Features of \texttt{pdfArticle} document class}
+\author{Robert Ryszard Paciorek <rrp@opcode.eu.org>}
+\date {2019-05-05}
+
+\makeatletter\hypersetup{
+ pdftitle = {\@title},
+ pdfauthor = {\@author}
+}\makeatother
+
+\setstretch{1.0} \setlength{\parindent}{0pt} \setlength{\parskip}{2pt}
+
+\usepackage{titling}
+\renewcommand{\maketitlehooka}{\vspace{-44pt}}
+\renewcommand{\maketitlehookb}{\vspace{-14pt}}
+\renewcommand{\maketitlehookd}{\vspace{-13pt}}
+\renewcommand{\maketitlehookd}{\vspace{-12pt}}
+
+\usepackage{hologo}
+\newcommand{\pkgLink}[1]{\texttt{\href{https://ctan.org/pkg/#1}{#1}}}
+
+\begin{document}
+
+\maketitle\thispagestyle{empty}
+
+Document class \texttt{pdfArticle} is simple document class dedicated for creating pdf documents with \hologo{LuaLaTeX}.
+This class:
+\begin{itemize}
+\item Use \texttt{extarticle} (from \pkgLink{extsizes}) as base document class (for support wide range of base font sizes).
+\item Require and configure \pkgLink{fontspec} package, that enable support for Unicode Open Type fonts.
+ Configure default document \textrm{sherif}, \textsf{sans} and \texttt{mono} fonts via \texttt{fontspec} according to class options.
+ By default use \textit{Latin Modern} fonts with support for \textsc{small caps} in sherif and mono fonts.
+\item Require and configure \pkgLink{graphicx} and \pkgLink{graphbox} packages (for including graphics).
+ Set file extensions for search graphics files to \texttt{.mp, .pdf, .png, .jpg, .jpeg} (in this order -- first \hologo{METAPOST}, last JPEG) and default image resolution to \texttt{imgResolution} class atribute (default 150).
+\item Require \pkgLink{xcolor} (for foreground and background colors) and \pkgLink{fifo-stack} packages and configure colours stack (you can use it with \Verb$\FSPush{colors}$, \Verb$\FSPop{colors}$ and \Verb$\FSTop{colors}$ commands).
+\item Require \pkgLink{hyperref} package (for internal and external links in pdfs) and configure color external (url) link as blue and internal (\Verb$\ref{}$) links as color from top of colours stack.
+ More setting (eg. set PDF title, author, etc) can be do via \Verb$\hypersetup{}$ command.
+\item Require \pkgLink{geometry} package and configure page gemetry (paper size, orientation and marings) according to class options. By default use portrait A4 paper.
+\item Provide \Verb$\forceNewPageGeometry$ commad for enforce new page geometry (like \Verb$\newgeometry$, but allow change paper size too).
+\item Require \pkgLink{fancyvrb} and \pkgLink{fvextra} (for good verbatim enviromet with line breaking, line numbering, titles, frames, etc).
+ Redefine standard \Verb$verbatim$ enviromet and \Verb$\verb$ commad to using fancyvrb. Allow break long lines on spaces, \Verb$/$ or \Verb$-$, set $\hookrightarrow$ as post break marker.
+\item Require \pkgLink{ulem}, \pkgLink{contour} and \pkgLink{shadowtext} (for text decorations).
+\item Is incompatible with \texttt{sout} package,
+ because define own \Verb$\ul[color]{text}$, \Verb$\st[color]{text}$ and \Verb$\hl[color]{text}$ commands (based on \texttt{ulem} package)
+ for \ul[blue]{underline}, \st[red]{strike out} and \hl[yellow]{highlight} text with selected color.
+\item Require \pkgLink{enumitem} (for better enumerate, itemize and description environments).
+\item Redefine \Verb$\alph$ and \Verb$\Alph$ with \pkgLink{alphalph} package (for converting big numbers to letters as \Verb[breaklines=true]$a, b, ..., x, y, z, aa, ab, ac, ..., az, ba, ..., zz, aaa, ...$).
+\item Require \pkgLink{pbox} and \pkgLink{varwidth} (for vertical box with automatic minimal width).
+\item Require \pkgLink{overpic} (for putting \hologo{LaTeXTeX} stuff on images).
+\item Require \pkgLink{wrapfig} (for wraping text around images).
+\item Require \pkgLink{array} and \pkgLink{dcolumn} (for useful extentions for tables).
+\item Require \pkgLink{tabto} (for tabbing to fixed positions).
+\item Require \pkgLink{ragged2e} (for \Verb$justify$ environment and configurable \Verb$Center$, \Verb$FlushLeft$, \Verb$FlushRight$).
+\item Require \pkgLink{changepage} (for changes margins via \Verb$adjustwidth$ environment).
+\item Require \pkgLink{setspace} (for setting line stretch -- global and via \Verb$spacing$ environment).
+\item Require \pkgLink{amsmath} and \pkgLink{unicode-math} (for better math with Unicode Open Type fonts).
+\item Require \pkgLink{adjustbox} (for scaling, rotating, clipping, etc boxes).
+\item Only when \Verb$extra$ option was given require: \pkgLink{minted} (code highlight), \pkgLink{tcolorbox} (nice framed boxes).
+\end{itemize}
+
+\clearpage
+Class can be simple used by: \Verb$\documentclass{pdfArticle}$. Below is example of class usage with all avalible options, all options in this example are set to default values:
+\begin{Verbatim}[xleftmargin=5mm]
+\documentclass[
+ fontSize=12pt,
+
+ mainFont={Latin Modern Roman},
+ mainFontFeat={
+ UprightFeatures = { SmallCapsFont={ lmromancaps10regular } },
+ ItalicFeatures = { SmallCapsFont={ lmromancaps10oblique } },
+ SlantedFont = lmromanslant10regular,
+ BoldSlantedFont = lmromanslant10bold,
+ Ligatures=TeX
+ },
+ sansFont={Latin Modern Sans},
+ sansFontFeat={
+ Ligatures=TeX
+ },
+ monoFont={Latin Modern Mono},
+ monoFontFeat={
+ UprightFeatures = { SmallCapsFont={ lmmonocaps10regular } },
+ ItalicFont = lmmono10italic,
+ ItalicFeatures = { SmallCapsFont={ lmmonocaps10oblique } },
+ SlantedFont = lmmonoslant10regular
+ },
+
+ paperSize=a4paper, paperMode=portrait, twoside=true,
+ tmargin=2.2cm, bmargin=2.5cm, lmargin=2.2cm, rmargin=2.2cm,
+
+ imgResolution=150, extra=false
+]{pdfArticle}
+\end{Verbatim}
+
+It's also possible load some packages (or do other things) right before load \texttt{hyperref} package (after load all other packages) via \Verb$\pdfArticlePreHyperRef$:
+\begin{Verbatim}[xleftmargin=5mm]
+\newcommand\pdfArticlePreHyperRef{
+% stuff to do before load hyperref
+}
+\documentclass{pdfArticle}
+\end{Verbatim}
+\end{document}
diff --git a/macros/luatex/latex/pgfmolbio/README b/macros/luatex/latex/pgfmolbio/README
new file mode 100644
index 0000000000..291e363151
--- /dev/null
+++ b/macros/luatex/latex/pgfmolbio/README
@@ -0,0 +1,18 @@
+The pgfmolbio package v0.21
+------------------------------------------------------------------------------
+This package is released under the LaTeX Project Public License v1.3c or later
+(see http://www.latex-project.org/lppl.txt).
+
+
+The experimental package pgfmolbio draws graphs typically found in
+molecular biology texts. Currently, the package contains modules
+for drawing DNA sequencing chromatograms and protein domain diagrams.
+
+The package requires pgf/TikZ (http://tug.ctan.org/pkg/pgf)
+and LuaTeX (http://www.luatex.org).
+
+Installation: Run pgfmolbio.ins through LaTeX and follow the instructions.
+
+--
+Wolfgang Skala
+August 1st, 2013
diff --git a/macros/luatex/latex/pgfmolbio/SampleGff.gff b/macros/luatex/latex/pgfmolbio/SampleGff.gff
new file mode 100644
index 0000000000..0c6754989f
--- /dev/null
+++ b/macros/luatex/latex/pgfmolbio/SampleGff.gff
@@ -0,0 +1,14 @@
+##gff-version 3
+##sequence-region TestProtein 1 200
+TestProtein TheDatabase disulfide 5 45 . . . Disulfide 1
+TestProtein TheDatabase disulfide 30 122 . . . Disulfide 2
+TestProtein TheDatabase disulfide 51 99 . . . Disulfide 3
+TestProtein TheDatabase domain 10 40 . . . Domain 1
+TestProtein TheDatabase domain 60 120 . . . Domain 2
+TestProtein TheDatabase domain 135 178 . . . Domain 3
+TestProtein TheDatabase beta strand 15 23 . . . Strand 1
+TestProtein TheDatabase beta strand 25 32 . . . Strand 2
+TestProtein TheDatabase alpha helix 60 75 . . . Helix 1
+TestProtein TheDatabase alpha helix 80 108 . . . Helix 1
+TestProtein TheDatabase carbohydrate 151 151 . . . Sugar 1
+TestProtein TheDatabase carbohydrate 183 183 . . . Sugar 2 \ No newline at end of file
diff --git a/macros/luatex/latex/pgfmolbio/SampleScf.scf b/macros/luatex/latex/pgfmolbio/SampleScf.scf
new file mode 100644
index 0000000000..89dde13d67
--- /dev/null
+++ b/macros/luatex/latex/pgfmolbio/SampleScf.scf
Binary files differ
diff --git a/macros/luatex/latex/pgfmolbio/SampleUniprot.txt b/macros/luatex/latex/pgfmolbio/SampleUniprot.txt
new file mode 100644
index 0000000000..ca0f6b98ec
--- /dev/null
+++ b/macros/luatex/latex/pgfmolbio/SampleUniprot.txt
@@ -0,0 +1,19 @@
+ID TestProtein Reviewed; 200 AA.
+FT DISULFID 5 45 Disulfide 1
+FT DISULFID 30 122 Disulfide 2
+FT DISULFID 51 99 Disulfide 3
+FT DOMAIN 10 40 Domain 1
+FT DOMAIN 60 120 Domain 2
+FT DOMAIN 135 178 Domain 3
+FT STRAND 15 23 Strand 1
+FT STRAND 25 32 Strand 2
+FT HELIX 60 75 Helix 1
+FT HELIX 80 108 Helix 2
+FT CARBOHYD 151 151 Sugar 1
+FT CARBOHYD 183 183 Sugar 2
+SQ SEQUENCE 200 AA; 22041 MW; 00A52FE2EC5431D9 CRC64;
+ MGSKRSVPSR HRSLTTYEVM FAVLFVILVA LCAGLIAVSW LSIQGSVKDA AFGKSHEARG
+ TLKIISGATY NPHLQDKLSV DFKVLAFDIQ QMIDDIFQSS NLKNEYKNSR VLQFENGSII
+ VIFDLLFDQW VSDKNVKEEL IQGIEANKSS QLVTFHIDLN SIDITASLEN FSTISPATTS
+ EKLTTSIPLA TPGNVSIECP
+// \ No newline at end of file
diff --git a/macros/luatex/latex/pgfmolbio/pgfmolbio.dtx b/macros/luatex/latex/pgfmolbio/pgfmolbio.dtx
new file mode 100644
index 0000000000..eb4fc31525
--- /dev/null
+++ b/macros/luatex/latex/pgfmolbio/pgfmolbio.dtx
@@ -0,0 +1,5135 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2013 by Wolfgang Skala
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% \fi
+%
+% \iffalse
+%<pgfmolbio-tex>\ProvidesPackage{pgfmolbio}[2013/08/01 v0.21 Molecular biology graphs with TikZ]
+%<pgfmolbio-tex>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<pgfmolbio-lua>module("pgfmolbio", package.seeall)
+%<pmb-chr-tex>\ProvidesFile{pgfmolbio.chromatogram.tex}[2013/08/01 v0.21 SCF chromatograms]
+%<pmb-chr-lua>module("pgfmolbio.chromatogram", package.seeall)
+%<pmb-dom-tex>\ProvidesFile{pgfmolbio.domains.tex}[2013/08/01 v0.21 Protein domains]
+%<pmb-dom-lua>module("pgfmolbio.domains", package.seeall)
+%<pmb-con-tex>\ProvidesFile{pgfmolbio.convert.tex}[2013/08/01 v0.21 pgfmolbio graph conversion]
+%
+%<*driver>
+\documentclass[captions=tableheading,cleardoublepage=empty,titlepage=false]{scrreprt}
+ \setkomafont{title}{\rmfamily\bfseries}
+ \addtokomafont{sectioning}{\rmfamily}
+
+\usepackage[ngerman,english]{babel}
+\usepackage[hdivide={2cm,*,5cm}]{geometry}
+\usepackage{fontspec}
+\usepackage{array,booktabs,tabularx}
+\usepackage[chromatogram,domains]{pgfmolbio}
+ \usetikzlibrary{patterns,backgrounds,decorations.pathreplacing}
+
+\usepackage{ydoc-doc,ydoc-code,ydoc-desc,ydoc-expl}
+ \AlsoImplementation
+ \hypersetup{%
+ colorlinks=false,%
+ bookmarksnumbered,%
+ bookmarksopen,%
+ bookmarksopenlevel=1,%
+ breaklinks,%
+ pdfborder=0 0 0,%
+ pdfhighlight=/N,%
+ }
+ \AtBeginDocument{%
+ \lstMakeShortInline[style=latex-expl,basicstyle=\ttfamily,numbers=none,firstnumber=last]|%
+ \lstMakeShortInline[style=lua-doc,basicstyle=\ttfamily,frame=none,numbers=none]§%
+ }
+ \makeatletter
+ \newcommand\DescribeOption[4][=]{%
+ \gdef\OptDefault{\textcolor{black!50}{Default:}~\texttt{#4}}%
+ \DescribeMacros
+ \let\DescribeMacros\y@egroup
+ \optionalon
+ \def\after@Macro@args{\y@egroup\PrintOptions\endgroup}%
+ \hbox\y@bgroup
+ \texttt{\textcolor{opt!50}{/pgfmolbio/#2}\textcolor{opt}{#3}~#1}%
+ \ydoc@macrocatcodes
+ \macroargsstyle
+ \read@Macro@arg%
+ }
+ \def\PrintOptions{%
+ \par\vspace\beforedescskip
+ \begingroup
+ \sbox\@tempboxa{\descframe{\usebox{\descbox}}}%
+ \Needspace*{\dimexpr\ht\@tempboxa+2\baselineskip\relax}%
+ \par\noindent
+ \ifdim\wd\@tempboxa>\dimexpr\linewidth-2\descindent\relax
+ \makebox[\linewidth][c]{\usebox\@tempboxa}%
+ \else
+ \hspace*{\descindent}%
+ \usebox\@tempboxa
+ \fi
+ \endgroup
+ \par\medskip\makebox{\kern10pt\OptDefault}
+ \vspace\afterdescskip
+ \par\noindent
+ }
+ \def\PrintExample{%
+ \begingroup
+ \BoxExample
+ \@tempdima\textwidth
+ \advance\@tempdima-\wd\examplecodebox\relax
+ \advance\@tempdima-\wd\exampleresultbox\relax
+ \advance\@tempdima-1cm\relax
+ \ifdim\@tempdima>0pt
+ \@tempdimb\wd\exampleresultbox
+ \advance\@tempdimb2\fboxsep
+ \advance\@tempdimb2\fboxrule
+ \par\bigskip\noindent%
+ \centerline{%
+ \parbox[c]{\@tempdimb}{\fbox{\usebox\exampleresultbox}}
+ \hskip1cm
+ \parbox[c]{\wd\examplecodebox}{\usebox\examplecodebox}
+ }%
+ \par\bigskip
+ \else
+ \par\bigskip\noindent%
+ \vbox{%
+ \centerline{\fbox{\usebox\exampleresultbox}}%
+ \vspace{\bigskipamount}%
+ \centerline{\usebox\examplecodebox}%
+ }%
+ \par\bigskip
+ \fi
+ \endgroup
+ }
+ \newcommand\DescribeFeature{\@ifstar\DescribeFeatureNoAlias\DescribeFeatureAlias}
+ \newcommand\DescribeFeatureAlias[2]{\paragraph{Feature \texttt{#1}} (\textit{alias} \texttt{#2})\\}
+ \newcommand\DescribeFeatureNoAlias[1]{\paragraph{Feature \texttt{#1}} (\textit{no alias})\\}
+ \makeatother
+ \def\ometa#1{{\optional\meta{#1}}}
+ \lstdefinestyle{exampleextract}{gobble=2}
+ \lstdefinestyle{examplecode}{style=latex-expl}
+ \def\ydoclistingssettings{\lstset{style=latex-expl}}
+ \definecolor{opt}{named}{OliveGreen}
+ \definecolor{mod}{named}{black}
+ \definecolor{macrodesc}{named}{ProcessBlue}
+ \definecolor{macroimpl}{named}{ProcessBlue}
+ \newcommand\module[1]{\textsf{\textcolor{mod}{#1}}}
+ \renewcommand*\optstyle[1]{\texttt{\textcolor{opt}{#1}}}
+
+\lstdefinestyle{latex-expl}{
+ language=[AlLaTeX]TeX,
+ columns=fullflexible,
+ keepspaces=true,
+ tabsize=2,
+ numbers=left,
+ numberstyle=\sffamily\tiny\color{gray},
+ numbersep=5pt,
+ firstnumber=auto,
+ prebreak={},
+ basicstyle=\ttfamily\small,
+ texcsstyle=*\color{MidnightBlue},
+ texcsstyle=*[2]\color{ProcessBlue},
+ keywordstyle=\color{RedOrange},
+ commentstyle=\itshape\color{black!50},
+ morekeywords={tikzpicture,pgfinterruptboundingbox,pgfinterruptpicture,pmbdomains,scope},
+ moretexcs=[1]{
+ @empty,@ifundefined,@nameuse,clip,colorlet,definecolor,directlua,draw,ifluatex,
+ luaescapestring,node,path,pdfdraftmode,pgf@protocolsizes,pgf@x,pgf@y,pgfdeclareverticalshading,
+ pgfkeys,pgfkeysalso,pgfkeysdef,pgfkeyssetvalue,pgfkeysvalueof,pgfmathsetmacro,pgfpoint,pgfqkeys,
+ ProcessOptions,RequireLuaModule,textcolor,tikzset,useasboundingbox,usetikzlibrary
+ },
+ moretexcs=[2]{
+ @pmb@chr@getkey,@pmb@chr@keydef,@pmb@chr@stylekeydef,
+ @pmb@dom@feature@default@shape,@pmb@dom@helixsegment,@pmb@dom@helixhalfsegment,@pmb@dom@keydef,
+ @pmb@toksa,@pmb@toksb,@tempa,adddisulfidefeatures,addfeature,featureSequence,currentResidue,
+ pmb@chr@tikzpicturefalse,pmb@chr@tikzpicturetrue,ifpmb@chr@showbasenumbers,ifpmb@chr@tikzpicture,
+ ifpmb@con@includedescription,ifpmb@con@outputtikzcode,ifpmb@dom@showname,ifpmb@dom@showruler,
+ ifpmb@dom@showsecstructure,ifpmb@dom@tikzpicture,ifpmb@loadmodule@chromatogram,ifpmb@loadmodule@convert,
+ ifpmb@loadmodule@domains,inputuniprot,inputgff,
+ pgfmolbioset,pmb@con@outputtikzcodefalse,pmb@con@outputtikzcodetrue,
+ pmb@dom@addfeature,pmb@dom@inputgff,pmb@dom@inputuniprot,pmb@dom@tikzpicturetrue,pmb@dom@tikzpicturefalse,
+ pmb@loadmodule@chromatogramtrue,pmb@loadmodule@converttrue,
+ pmb@loadmodule@domainstrue,pmb@magnifiedsequence@width,pmbchromatogram,pmbdomdrawfeature,
+ pmbdomvalueof,pmbprotocolsizes,removedisulfidefeatures,removefeatureprintfunction,
+ residueNumber,setdisulfidefeatures,setfeaturealias,
+ setfeatureprintfunction,setfeatureshape,setfeatureshapealias,setfeaturestyle,setfeaturestylealias,
+ turnXradius,turnYradius,xLeft,xLowerLeft,xLowerRight,xMid,xRight,xUpperLeft,xUpperRight,
+ yLower,yMid,yShift,yUpper
+ },
+ escapebegin=\begin{rmfamily}\color{black!50},
+ escapeend=\end{rmfamily}
+}
+
+\lstdefinestyle{latex-doc}{
+ style=latex-expl,
+ showlines,
+ firstnumber=last,
+ breaklines,
+ frame=single,
+ frameround=tttt,
+ rulecolor=\color{black!50}
+}
+
+\lstdefinestyle{lua-doc}{
+ language=lua,
+ columns=fullflexible,
+ keepspaces=true,
+ tabsize=2,
+ basicstyle=\ttfamily\small\color{ForestGreen},
+ keywordstyle=\color{MidnightBlue},
+ keywordstyle=[2]\color{ProcessBlue},
+ stringstyle=\color{Red},
+ identifierstyle=\color{Black},
+ emphstyle=\color{BurntOrange!50!Black},
+ showstringspaces=false,
+ numbers=left,
+ numberstyle=\sffamily\tiny\color{gray},
+ numbersep=5pt,
+ firstnumber=last,
+ breaklines,
+ showlines,
+ frame=single,
+ frameround=tttt,
+ rulecolor=\color{black!50},
+ belowskip=\bigskipamount
+}
+
+\lstdefinelanguage{lua}{
+ morekeywords={and,break,do,else,elseif,end,false,for,function,if,in,local,
+ nil,not,or,repeat,return,then,true,until,while},
+ morekeywords=[2]{arg,assert,collectgarbage,dofile,error,_G,format,getfenv,
+ getmetatable,__index,ipairs,load,loadfile,loadstring,next,pairs,pcall,print,
+ rawequal,rawget,rawset,select,self,setfenv,setmetatable,tonumber,tostring,__tostring,
+ type,unpack,_VERSION,xpcall},
+ morekeywords=[2]{module,require,package,seeall},
+ morekeywords=[2]{string,byte,char,dump,find,
+ format,gmatch,string,gsub,len,lower,
+ match,rep,reverse,sub,trim,upper},
+ morekeywords=[2]{table,concat,insert,maxn,remove,sort},
+ morekeywords=[2]{math,min},
+ morekeywords=[2]{io,input,open,output,close,flush,
+ lines,read,seek,setvbuf,write},
+ morekeywords=[2]{os.clock,os.date,os.difftime,os.execute,os.exit,os.getenv,
+ os.remove,os.rename,os.setlocale,os.time,os.tmpname},
+ morekeywords=[2]{tex,sprint},
+ emph={addFeature,aliasFeatureStyle,calculateDisulfideLevels,Chromatogram,clearKeys,dimToString,findBasesInStr,
+ getBaseKey,getMinMaxProbability,getParameters,getRange,getSampleAndPeakIndex,new,packageError,
+ packageWarning,printSequenceFeature,printHelixFeature,printTikzChromatogram,printTikzDomains,Protein,
+ readGffFile,readInt,readScfFile,readUniprotFile,selectStyleFromList,setCoordinateFormat,
+ setFeatureStyle,setKeys,setParameters,SpecialKeys,stdProbStyle,stringToDim,toAbsoluteResidueNumber},
+ sensitive=true,
+ alsoletter={0123456789},
+ morecomment=[l]{--},
+ morecomment=[s]{--[[}{]]--},
+ morestring=[b]{"},
+ morestring=[d]{'}
+}
+
+\def\TikZ{Ti\textit{k}Z}
+
+\usepackage{caption}
+ \captionsetup{format=plain,indention=1em,labelsep=colon,font={footnotesize,sf},labelfont={bf},skip=0pt}
+ \makeatletter\@addtoreset{example}{chapter}\makeatother
+ \renewcommand\theexample{\arabic{chapter}.\arabic{example}}
+
+\pdfpageattr{/Group <</S /Transparency /I true /CS /DeviceRGB>>}
+
+
+\begin{document}
+ \DocInput{pgfmolbio.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \GetFileInfo{pgfmolbio.sty}
+%
+% \CheckSum{1254}
+%
+% \pagenumbering{roman}
+% \title{The \texttt{pgfmolbio} package --\texorpdfstring{\\}{}Molecular Biology Graphs with \TikZ\texorpdfstring{\footnote{This document describes version \fileversion, dated \filedate.}}{}}
+% \author{\texorpdfstring{Wolfgang Skala\thanks{Division of Structural Biology, Department of Molecular Biology, University of Salzburg, Austria; \texttt{Wolfgang.Skala@stud.sbg.ac.at}}}{Wolfgang Skala}}
+% \date{\filedate}
+% \maketitle
+%
+% \begin{abstract}
+% The experimental package \pkg{pgfmolbio} draws graphs typically found in molecular biology texts. Currently, the package contains three modules: \module{chromatogram} creates DNA sequencing chromatograms from files in standard chromatogram format (\file{scf}); \module{domains} draws protein domain diagrams; \module{convert} integrates \pkg{pgfmolbio} with \TeX\ engines that lack Lua support.
+% \end{abstract}
+%
+% \tableofcontents
+%
+%
+% \chapter{Introduction}
+% \label{cha:Introduction}
+% \pagenumbering{arabic}
+%
+%
+% \section{About \texorpdfstring{\pkg{pgfmolbio}}{pgfmolbio}}
+% \label{sec:IntroAbout}
+%
+% Over the decades, \TeX\ has gained popularity across a large number of disciplines. Although originally designed as a mere typesetting system, packages such as \pkg{pgf}\footnote{Tantau, T. (2010). The \TikZ\ and \textsc{pgf} packages. \url{http://ctan.org/tex-archive/graphics/pgf/}.} and \pkg{pstricks}\footnote{van Zandt, T., Niepraschk, R., and Voß, H. (2007). PSTricks: PostScript macros for Generic \TeX. \url{http://ctan.org/tex-archive/graphics/pstricks}.} have strongly extended its \textit{drawing} abilities. Thus, one can create complicated charts that perfectly integrate with the text.
+%
+% Texts on molecular biology include a range of special graphs, e.\,g. multiple sequence alignments, membrane protein topologies, DNA sequencing chromatograms, protein domain diagrams, plasmid maps and others. The \pkg{texshade}\footnote{Beitz, E. (2000). \TeX shade: shading and labeling multiple sequence alignments using \LaTeXe. \textit{Bioinformatics}~\textbf{16}(2), 135--139.\\\url{http://ctan.org/tex-archive/macros/latex/contrib/texshade}.} and \pkg{textopo}\footnote{Beitz, E. (2000). \TeX topo: shaded membrane protein topology plots in \LaTeXe. \textit{Bioinformatics} \textbf{16}(11), 1050--1051.\\\url{http://ctan.org/tex-archive/macros/latex/contrib/textopo}.} packages cover alignments and topologies, respectively, but packages dedicated to the remaining graphs are absent. Admittedly, one may create those images with various external programs and then include them in the \TeX\ document. Nevertheless, purists (like the author of this document) might prefer a \TeX-based approach.
+%
+% The \pkg{pgfmolbio} package aims at becoming such a purist solution. In the current development release, \pkg{pgfmolbio} is able to
+% \begin{itemize}
+% \item read DNA sequencing files in standard chromatogram format (\file{scf}) and draw the corresponding chromatogram;
+% \item read protein domain information from Uniprot or general feature format files (\file{gff}) and draw domain diagrams.
+% \end{itemize}
+% To this end, \pkg{pgfmolbio} relies on routines from \pkg{pgf}'s \TikZ\ frontend and on the Lua scripting language implemented in Lua\TeX. Consequently, the package will not work directly with traditional engines like pdf\TeX. However, a converter module ensures a high degree of backward compatibility.
+%
+% Since this is a development release, \pkg{pgfmolbio} presumably includes a number of bugs, and its commands and features are likely to change in future versions. Moreover, the current version is far from complete, but since time is scarce, I am unable to predict when (and if) additional functions become available. Nevertheless, I would greatly appreciate any comments or suggestions.
+%
+%
+% \section{Getting Started}
+% \label{sec:IntroGettingStarted}
+%
+% Before you consider using \pkg{pgfmolbio}, please make sure that both your Lua\TeX\ (at least 0.70.2) and \pkg{pgf} (at least 2.10) installations are up-to-date. Once your \TeX\ system meets these requirements, just load \pkg{pgfmolbio} as usual, i.\,e. by
+%
+% \DescribeMacro\usepackage[<module>]{pgfmolbio}
+%
+% The package is divided into \textit{modules}, each of which produces a certain type of graph. Currently, three \ometa{module}s are available:
+% \begin{itemize}
+% \item \module{chromatogram} (chapter~\ref{cha:Chromatogram}) allows you to draw DNA sequencing chromatograms obtained by the Sanger sequencing method.
+% \item \module{domains} (chapter~\ref{cha:Domains}) provides macros for drawing protein domain diagrams and is also able to read domain information from files in Uniprot or general feature format.
+% \item Furthermore, \module{convert} (chapter~\ref{cha:Convert}) is used with one of the modules above and generates ``pure'' \TikZ\ code suitable for \TeX\ engines lacking Lua support.
+% \end{itemize}
+%
+% \DescribeMacro\pgfmolbioset[<module>]{<key-value list>}
+% Fine-tunes the graphs produced by each \pkg{pgfmolbio} module. The possible keys are described in the sections on the respective modules.
+%
+%
+%
+%
+% \chapter{The \texorpdfstring{\module{chromatogram}}{chromatogram} module}
+% \label{cha:Chromatogram}
+%
+%
+% \section{Overview}
+% \label{sec:ChrOverview}
+%
+% The \module{chromatogram} module draws DNA sequencing chromatograms stored in standard chromatogram format (\file{scf}), which was developed by Simon Dear and Rodger Staden\footnote{Dear, S. and Staden, R. (1992). A standard file format for data from DNA sequencing instruments. \textit{DNA Seq.} \textbf{3}(2), 107--110.}. The documentation for the Staden package\footnote{\url{http://staden.sourceforge.net/}} describes the current version of the \file{scf} format in detail. As far as they are crucial to understanding the Lua code, we will discuss some details of this file format in the documented source code (section~\ref{sec:DocChrLua}). Note that \pkg{pgfmolbio} only supports \file{scf} version 3.00.
+%
+%
+% \section{Drawing Chromatograms}
+% \label{sec:ChrDrawingChromatograms}
+%
+% \DescribeMacro\pmbchromatogram[<key-value list>]{<scf file>}
+% The \module{chromatogram} module defines a single command, which reads a chromatogram from an \meta{scf file} and draws it with routines from \TikZ\ (Example~\ref{exa:ChrTikzpicture}). The options, which are set in the \ometa{key-value list}, configure the appearance of the chromatogram. The following sections will elaborate on the available keys.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:ChrTikzpicture}
+% \begin{examplecode}
+% \begin{tikzpicture} % optional
+% \pmbchromatogram{SampleScf.scf}
+% \end{tikzpicture} % optional
+% \end{examplecode}
+% \end{exampletable}
+%
+% Although you will often put |\pmbchromatogram| into a |tikzpicture| environment, you may actually use the macro on its own. \pkg{pgfmolbio} checks whether the command is surrounded by a |tikzpicture| and adds this environment if necessary.
+%
+%
+% \section{Displaying Parts of the Chromatogram}
+% \label{sec:ChrDisplayingParts}
+%
+% \DescribeOption{chromatogram/}{sample range}{1-500 step 1}<lower>'-'<upper>[' step '<int>]\relax
+% \opt{sample range} selects the part of the chromatogram which \pkg{pgfmolbio} should display. The value for this key consists of two or three parts, separated by the keywords |-| and |step|. The package will draw the chromatogram data between the \meta{lower} and \meta{upper} boundary. There are two ways of specifying these limits:
+% \begin{enumerate}
+% \item If you enter a number, \pkg{pgfmolbio} includes the data from the \meta{lower} to the \meta{upper} sample point (Example~\ref{exa:ChrLimitsSamplePoints}). A \textit{sample point} represents one measurement of the fluorescence signal along the time axis, where the first sample point has index 1. One peak comprises about 20 sample points.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:ChrLimitsSamplePoints}
+% \begin{examplecode}
+% \pmbchromatogram[sample range=200-600]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+% \item If you enter the keyword |base| followed by an optional space and a number, the chromatogram starts or stops at the peak corresponding to the respective base. The first detected base peak has index 1. Compare Examples~\ref{exa:ChrLimitsSamplePoints} and~\ref{exa:ChrLimitsBases} to see the difference.
+% \end{enumerate}
+% The optional third part of the value for \opt{sample range} orders the package to draw every \ometa{int}th sample point. If your document contains large chromatograms or a great number of them, drawing fewer sample points increases typesetting time at the cost of image quality (Example~\ref{exa:ChrSampleStep}). Nevertheless, the key may be especially useful while optimizing the layout of complex chromatograms.
+%
+% \begin{exampletable}[p]
+% \caption{}
+% \label{exa:ChrLimitsBases}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 50-base60
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \begin{exampletable}[p]
+% \caption{}
+% \label{exa:ChrSampleStep}
+% \pgfmolbioset[chromatogram]{canvas height=1cm}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 20-base 50 step 1
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 20-base 50 step 2
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 20-base 50 step 4
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{General Layout}
+% \label{sec:ChrGeneralLayout}
+%
+% \DescribeOption{chromatogram/}{x unit}{0.2mm}<dimension>
+% \DescribeOption{chromatogram/}{y unit}{0.01mm}<dimension>
+% These keys set the horizontal distance between two consecutive sample points and the vertical distance between two fluorescence intensity values, respectively. Example~\ref{exa:Chrxyunit} illustrates how you can enlarge a chromatogram twofold by doubling these values.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:Chrxyunit}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 50-base 60,
+% x unit=0.4mm,
+% y unit=0.02mm
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+
+% \DescribeOption{chromatogram/}{samples per line}{500}<number>
+% \DescribeOption{chromatogram/}{baseline skip}{3cm}<dimension>
+% A new chromatogram ``line'' starts after \meta{number} sample points, and the baselines of adjacent lines (i.\,e., the $y$-value of fluorescence signals with zero intensity) are separated by \meta{dimension}. In Example~\ref{exa:ChrSamplesPerLine}, you see two lines, each of which contains 250 of the 500 sample points drawn. Furthermore, the baselines are 3.5~cm apart.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:ChrSamplesPerLine}
+% \begin{examplecode}
+% \begin{tikzpicture}%
+% [decoration=brace]
+% \pmbchromatogram[%
+% sample range=401-900,
+% samples per line=250,
+% baseline skip=3.5cm
+% ]{SampleScf.scf}
+% \draw[decorate]
+% (-0.1cm, -3.5cm) -- (-0.1cm, 0cm)
+% node[pos=0.5, rotate=90, above=5pt]
+% {baseline skip};
+% \end{tikzpicture}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeOption[/.style=]{chromatogram/}{canvas style}{draw=none, fill=none}<style>\newpage
+% \DescribeOption{chromatogram/}{canvas height}{2cm}<dimension>
+%
+% The \textit{canvas} is the background of the trace area. Its left and right boundaries coincide with the start and the end of the chromatogram, respectively. Its lower boundary is the baseline, and its upper border is separated from the lower one by \meta{dimension}. Although the canvas is usually transparent, its \meta{style} can be changed. In Example~\ref{exa:ChrCanvasStyle}, we decrease the height of the canvas and color it light gray.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:ChrCanvasStyle}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 50-base 60,
+% canvas style/.style={draw=none, fill=black!10},
+% canvas height=1.6cm
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{Traces}
+% \label{sec:ChrTraces}
+%
+% \DescribeOption[/.style=]{chromatogram/}{trace A style}{pmbTraceGreen}<style>
+% \DescribeOption[/.style=]{chromatogram/}{trace C style}{pmbTraceBlue}<style>
+% \DescribeOption[/.style=]{chromatogram/}{trace G style}{pmbTraceBlack}<style>
+% \DescribeOption[/.style=]{chromatogram/}{trace T style}{pmbTraceRed}<style>
+% \DescribeOption{chromatogram/}{trace style}{\textrm{(none)}}<style>
+% The \textit{traces} indicate variations in fluorescence intensity during chromatography, and each trace corresponds to a base. The first four keys set the respective \meta{style} basewise, whereas \opt{trace style} changes all styles simultaneously. Note the syntax differences between \opt{trace style} and \opt{trace A style} etc. The standard styles simply color the traces; Table~\ref{tab:pmbColors} lists the color specifications.
+%
+% \begin{table}[h]
+% \centering
+% \caption{Colors defined by the \module{chromatogram} module.}
+% \label{tab:pmbColors}
+% \begin{tabular}{*3{>{\ttfamily}l}l}
+% \toprule
+% Name & \pkg{xcolor} model & Values & Example \\
+% \midrule
+% pmbTraceGreen & RGB & ~34, 114, ~46 & \color{pmbTraceGreen}\rule{3cm}{1ex} \\
+% pmbTraceBlue & RGB & ~48, ~37, 199 & \color{pmbTraceBlue}\rule{3cm}{1ex} \\
+% pmbTraceBlack & RGB & ~~0, ~~0, ~~0 & \color{pmbTraceBlack}\rule{3cm}{1ex} \\
+% pmbTraceRed & RGB & 191, ~27, ~27 & \color{pmbTraceRed}\rule{3cm}{1ex} \\
+% pmbTraceYellow & RGB & 233, 230, ~~0 & \color{pmbTraceYellow}\rule{3cm}{1ex} \\
+% \bottomrule
+% \end{tabular}
+% \end{table}
+%
+% In Example~\ref{exa:ChrTraceStyle}, we change the style of all traces to a thin line and then add some patterns and colors to the A and T trace.
+% \begin{exampletable}[h]
+% \caption{}
+% \label{exa:ChrTraceStyle}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 50-base 60,
+% trace style=thin,
+% trace A style/.append style={dashdotted, green},
+% trace T style/.style={thick, dashed, purple}
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeOption{chromatogram/}{traces drawn}{ACGT}'A|C|G|T|'!\textrm{any combination thereof}!
+% The value of this key governs which traces appear in the chromatogram. Any combination of the single-letter abbreviations for the standard bases will work. Example~\ref{exa:ChrTracesDrawn} only draws the cytosine and guanine traces.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:ChrTracesDrawn}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 50-base 60,
+% traces drawn=CG
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{Ticks}
+% \label{sec:ChrTicks}
+%
+% \DescribeOption[/.style=]{chromatogram/}{tick A style}{thin, pmbTraceGreen}<style>
+% \DescribeOption[/.style=]{chromatogram/}{tick C style}{thin, pmbTraceBlue}<style>
+% \DescribeOption[/.style=]{chromatogram/}{tick G style}{thin, pmbTraceBlack}<style>
+% \DescribeOption[/.style=]{chromatogram/}{tick T style}{thin, pmbTraceRed}<style>
+% \DescribeOption{chromatogram/}{tick style}{\textrm{(none)}}<style>
+% \textit{Ticks} below the baseline indicate the maxima of the trace peaks. The first four keys set the respective \meta{style} basewise, whereas \opt{tick style} changes all styles simultaneously. Note the syntax differences between \opt{tick style} and \opt{tick A style} etc. Example~\ref{exa:ChrTickStyle} illustrates how one can draw thick ticks, which are red if they indicate a cytosine peak.
+% \begin{exampletable}[ht]
+% \caption{}
+% \label{exa:ChrTickStyle}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 50-base 60,
+% tick style=thick,
+% tick C style/.append style={red}
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeOption{chromatogram/}{tick length}{1mm}<dimension>
+% This key determines the length of each tick. In Example~\ref{exa:ChrTickLength}, the ticks are twice as long as usual.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:ChrTickLength}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 50-base 60,
+% tick length=2mm
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeOption{chromatogram/}{ticks drawn}{ACGT}'A|C|G|T|'!\textrm{any combination thereof}!
+% The value of this key governs which ticks appear in the chromatogram. Any combination of the single-letter abbreviations for the standard bases will work. Example~\ref{exa:ChrTicksDrawn} only displays the cytosine and guanine ticks.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:ChrTicksDrawn}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 50-base 60,
+% ticks drawn=CG
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{Base Labels}
+% \label{sec:ChrBaseLabels}
+%
+% \DescribeOption{chromatogram/}{base label A text}{\cs{strut} A}<text>
+% \DescribeOption{chromatogram/}{base label C text}{\cs{strut} C}<text>
+% \DescribeOption{chromatogram/}{base label G text}{\cs{strut} G}<text>
+% \DescribeOption{chromatogram/}{base label T text}{\cs{strut} T}<text>
+% \textit{Base labels} below each tick spell the nucleotide sequence deduced from the traces. By default, the \meta{text} that appears in these labels equals the single-letter abbreviation of the respective base. The |\strut| macro ensures equal vertical spacing. In Example~\ref{exa:ChrBaseLabelText}, we print lowercase letters beneath adenine and thymine.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:ChrBaseLabelText}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 50-base 60,
+% base label A text=\strut a,
+% base label T text=\strut t
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeOption[/.style=]{chromatogram/}{base label A style}{below=4pt, font=\cs{ttfamily}\cs{footnotesize}, pmbTraceGreen}<style>
+% \DescribeOption[/.style=]{chromatogram/}{base label C style}{below=4pt, font=\cs{ttfamily}\cs{footnotesize}, pmbTraceBlue}<style>
+% \DescribeOption[/.style=]{chromatogram/}{base label G style}{below=4pt, font=\cs{ttfamily}\cs{footnotesize}, pmbTraceBlack}<style>
+% \DescribeOption[/.style=]{chromatogram/}{base label T style}{below=4pt, font=\cs{ttfamily}\cs{footnotesize}, pmbTraceRed}<style>
+% \DescribeOption{chromatogram/}{base label style}{\textrm{(none)}}<style>
+% The first four keys set the respective \meta{style} basewise, whereas \opt{base label style} changes all styles simultaneously. Each base label is a \TikZ\ node anchored to the lower end of the respective tick. Thus, the \meta{style} should contain placement keys such as |below| or |anchor=south|. Example~\ref{exa:ChrBaseLabelStyle} shows some (imaginative) base label styles.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:ChrBaseLabelStyle}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 50-base 60,
+% base label style=%
+% {below=2pt, font=\sffamily\footnotesize},
+% base label T style/.append style=%
+% {below=4pt, font=\tiny}
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeOption{chromatogram/}{base labels drawn}{ACGT}'A|C|G|T|'!\textrm{any combination thereof}!
+% The value of this key governs which base labels appear in the chromatogram. Any combination of the single-letter abbreviations for the standard bases will work. Example~\ref{exa:ChrBaseLabelsDrawn} only displays cytosine and guanine base labels.
+% \begin{exampletable}[ht]
+% \caption{}
+% \label{exa:ChrBaseLabelsDrawn}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 50-base 60,
+% base labels drawn=CG
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{Base Numbers}
+% \label{sec:ChrBaseNumbers}
+%
+% \DescribeOption{chromatogram/}{show base numbers}{true}<boolean>
+% Turns the \textit{base numbers} on or off, which indicate the indices of the base peaks below the traces.
+% \DescribeOption[/.style=]{chromatogram/}{base number style}{pmbTraceBlack, below=-3pt, font=\cs{sffamily}\cs{tiny}}<style>
+% Determines the placement and appearance of the base numbers. Example~\ref{exa:ChrBaseNumberStyle} contains bold red base numbers that are shifted slightly upwards.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:ChrBaseNumberStyle}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 40-base 50,
+% base number style/.style={below=-3pt,%
+% font=\rmfamily\bfseries\tiny, red}
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeOption{chromatogram/}{base number range}{auto-auto step 10}<lower>'-'<upper>[' step '<interval>]
+% This key decides that every \ometa{interval}th base number from \meta{lower} to \meta{upper} should show up in the output; the |step| part is optional. If you specify the keyword |auto| instead of a number for \meta{lower} or \meta{upper}, the base numbers start or finish at the leftmost or rightmost base peak shown, respectively. In Example~\ref{exa:ChrBaseNumberRange}, only peaks 42 to 46 receive a number.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:ChrBaseNumberRange}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 40-base 50,
+% base number range=42-46 step 1,
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{Probabilities}
+% \label{sec:ChrProbabilities}
+%
+% Programs such as \file{phred}\footnote{Ewing, B., Hillier, L., Wendl, M.\,C., and Green, P. (1998). Base-calling of automated sequencer traces using phred. I. Accuracy assessment. \textit{Genome Res.} \textbf{8}(3), 175--185.} assign a \textit{probability} or \textit{quality value} $Q$ to each called base after chromatography. $Q$ is calculated from the error probability $P_e$ by $Q = -10 \log_{10} P_e$. For example, a $Q$ value of 20 means that 1 in 100 base calls is wrong.
+%
+% \DescribeOption{chromatogram/}{probability distance}{0.8cm}<dimension>
+% Sets the distance between the base probability rules and the baseline.
+% \DescribeOption{chromatogram/}{probabilities drawn}{ACGT}'A|C|G|T|'!\textrm{any combination thereof}!
+% Governs which probabilities appear in the chromatogram. Any combination of the single-letter abbreviations for the standard bases will work. In Example~\ref{exa:ChrProbabilities}, we shift the probability indicator upwards and only show the quality values of cytosine and thymine peaks.
+% \begin{exampletable}
+% \caption{}
+% \label{exa:ChrProbabilities}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 10-base 30,
+% probabilities drawn=CT,
+% probability distance=1mm
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeOption{chromatogram/}{probability style function}{nil}<Lua function name>
+% By default, the probability rules are colored black, red, yellow and green for quality scores $<10$, $<20$, $<30$ and $\geq30$, respectively. However, you can override this behavior by providing a \meta{Lua function name} to \opt{probability style function}. This Lua function must read a single argument of type number and return a string appropriate for the optional argument of \TikZ's |\draw| command. For instance, the function shown in Example~\ref{exa:ChrProbStyleFunction} determines the lowest and highest probability and colors intermediate values according to a red--yellow--green gradient.
+% \begin{exampletable}[htp]
+% \caption{}
+% \label{exa:ChrProbStyleFunction}
+% \begin{examplecode}
+% \directlua{
+% function probabilityGradient (prob)
+% local minProb, maxProb = pmbChromatogram:getMinMaxProbability()
+% local scaledProb = prob / maxProb * 100
+% local color = ''
+% if scaledProb < 50 then
+% color = 'yellow!' .. scaledProb * 2 .. '!red'
+% else
+% color = 'green!' .. (scaledProb - 50) * 2 .. '!yellow'
+% end
+% return 'ultra thick, ' .. color
+% end
+% }
+% \pmbchromatogram[%
+% samples per line=1000,
+% sample range=base 1-base 50,
+% probability style function=probabilityGradient
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{Miscellaneous Keys}
+% \label{sec:ChrMiscKeys}
+%
+% \DescribeOption{chromatogram/}{bases drawn}{ACGT}'A|C|G|T|'!\textrm{any combination thereof}!
+% This key simultaneously sets \opt{traces drawn}, \opt{ticks drawn}, \opt{base labels drawn} and \opt{probabilities drawn} (see Example~\ref{exa:ChrBasesDrawn}).
+% \begin{exampletable}[p]
+% \caption{}
+% \label{exa:ChrBasesDrawn}
+% \begin{examplecode}
+% \pmbchromatogram[%
+% sample range=base 50-base 60,
+% bases drawn=AC
+% ]{SampleScf.scf}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+%
+% \chapter{The \texorpdfstring{\module{domains}}{domains} module}
+% \label{cha:Domains}
+%
+% \section{Overview}
+% \label{sec:DomOverview}
+%
+% Protein domain diagrams appear frequently in databases such as Pfam\footnote{Finn, R.\,D., Mistry, J. \textit{et al.} (2010). The Pfam protein families database. \textit{Nucleic Acids Res.} \textbf{38}, D211--D222.} or \textsc{prosite}\footnote{Sigrist, C.\,J.\,A., Cerutti, L. \textit{et al.} (2010). \textsc{prosite}, a protein domain database for functional characterization and annotation. \textit{Nucleic Acids Res.} \textbf{38}, D161--D166.}. Domain diagrams are often drawn using standard graphics software or tools such as \textsc{prosite}'s MyDomains image creator\footnote{\url{http://prosite.expasy.org/mydomains/}}. However, the \module{domains} module provides an integrated approach for generating domain diagrams from \TeX\ code or from external files.
+%
+%
+% \section{Domain Diagrams and Their Features}
+% \label{sec:DomDiagrams}
+%
+% \DescribeEnv[\meta{features}]{pmbdomains}[<key-value list>]{<sequence length>}
+% Draws a domain diagram with the \meta{features} given. The \ometa{key-value list} configures its appearance. \meta{sequence length} is the total number of residues in the protein. (Although you must eventually specify a sequence length, you may actually leave the mandatory argument empty and use the \opt{sequence length} key instead; see section~\ref{sec:DomFileInput}).
+%
+% You can put a |pmbdomains| environment into a |tikzpicture|, but you also may use the environment on its own. \pkg{pgfmolbio} checks whether it is surrounded by a |tikzpicture| and adds this environment if necessary.
+%
+% \DescribeOption{domains/}{name}{Protein}<text>
+% The name of the protein, which usually appears centered above the diagram.
+%
+% \DescribeOption{domains/}{show name}{true}<boolean>
+% Determines whether both the name and sequence length are shown.
+%
+% \DescribeMacro\addfeature[<key-value list>]{<type>}{<start>}{<stop>}
+% Adds a feature of the given \meta{type} to the current domain diagram (only defined inside |pmbdomains|). The feature spans the residues from \meta{start} to \meta{stop}. These arguments are either numbers, which refer to residues in the relative numbering scheme, or numbers in parentheses, which refer to absolute residue numbers (see section~\ref{sec:DomGeneralLayout}).
+%
+% \DescribeOption{domains/}{description}{\textrm{(none)}}<text>
+% Sets the feature description (Example~\ref{exa:DomTikzpicture}).
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomTikzpicture}
+% \begin{examplecode}
+% \begin{tikzpicture} % optional
+% \begin{pmbdomains}[name=\TeX ase]{200}
+% \addfeature{disulfide}{40}{129}
+% \addfeature{disulfide}{53}{65}
+% \addfeature[description=Domain 1]{domain}{30}{80}
+% \addfeature[description=Domain 2]{domain}{93}{163}
+% \addfeature{domain}{168}{196}
+% \end{pmbdomains}
+% \end{tikzpicture} % optional
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{General Layout}
+% \label{sec:DomGeneralLayout}
+%
+% \DescribeOption{domains/}{x unit}{0.5mm}<dimension>
+% The width of a single residue.
+%
+% \DescribeOption{domains/}{y unit}{6mm}<dimension>
+% The height of a default \texttt{domain} feature.
+%
+% \DescribeOption{domains/}{residues per line}{200}<number>
+% A new domain diagram ``line'' starts after \meta{number} residues.
+%
+% \DescribeOption{domains/}{baseline skip}{3}<factor>
+% The baselines of consecutive lines (i.\,e., the main chain $y$-coordinates) are separated by \meta{factor} times the value of \opt{y unit}. In Example~\ref{exa:DomResiduesPerLine}, you see four lines, each of which contains up to 30~residues. Note how domains are correctly broken across lines. Furthermore, the baselines are $2 \times 4 = 8$~mm apart.
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomResiduesPerLine}
+% \begin{examplecode}
+% \begin{pmbdomains}%
+% [show name=false, x unit=2mm, y unit=4mm,
+% residues per line=30, baseline skip=2]{110}
+% \addfeature[description=Domain 1]{domain}{10}{23}
+% \addfeature[description=Domain 2]{domain}{29}{71}
+% \addfeature[description=Domain 3]{domain}{80}{105}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeOption{domains/}{residue numbering}{auto}<numbering scheme>
+% A protein's amino acid residues are usually numbered consecutively starting from~1. However, there are different numbering schemes. For example, residue numbering in a serine protease related to chymotrypsin typically follows the numbering in chymotrypsinogen\footnote{Bode, W., Mayr, I. \textit{et al.} (1989). The refined 1.9 Ã… crystal structure of human $\alpha$-thrombin: interaction with \textsc{d}-Phe-Pro-Arg chloromethylketone and significance of the Tyr-Pro-Pro-Trp insertion segment. \textit{EMBO J.} \textbf{8}(11), 3467--3475.}. The target protease sequence is aligned to the chymotrypsinogen sequence, and equivalent residues receive the same number. Insertions into the target sequence are indicated by appending letters to the last aligned residue (e.\,g., 186, \textit{186A}, \textit{186B}, 187), whereas gaps in the target sequence cause gaps in the numbering (e.\,g., 124, 125, 128, 129).
+%
+% In \pkg{pgfmolbio}, you can specify a relative \meta{numbering scheme} via the \opt{residue numbering} key. The keyword |auto| indicates that residues are numbered from 1 to (sequence length), i.\,e. absolute and relative numberings coincide. This is the case in all examples above. The complete syntax for the key is
+% \begin{quote}
+% \meta{numbering scheme} := \MacroArgs{<range>[','<range>', ...']}\\
+% \meta{range} := \MacroArgs<start>'-'<end>' | '<start>\\
+% \meta{start} := \MacroArgs<number>' | '<number><letter>\\
+% \meta{end} := \MacroArgs<number>' | '<letter>
+% \end{quote}
+%
+% Example~\ref{exa:DomResidueNumbering} shows a custom \meta{numbering scheme}, in this case for kallikrein-related peptidase 2 (KLK2), a chymotrypsin-like serine proteases. (In the following explanation, the subscripts `abs' and `rel' denote absolute and relative numbering, respectively).
+% \begin{itemize}
+% \item Residue 1\textsubscript{abs} is labeled 16\textsubscript{rel}, residue 2\textsubscript{abs} is labeled 17\textsubscript{rel} etc. until residue 24\textsubscript{abs}, which is labeled 39\textsubscript{rel} (range |16-39|).
+% \item Residue 25\textsubscript{abs} corresponds to 41\textsubscript{rel} etc. until residue 57\textsubscript{abs}/73\textsubscript{rel} (range |41-73|).
+% \item Residue 40\textsubscript{rel} is missing -- no residue in KLK2 is equivalent to residue 40 in chymotrypsinogen.
+% \item An insertion of 11 amino acids follows residue 95\textsubscript{rel}. These residues are numbered from 95A\textsubscript{rel} to 95K\textsubscript{rel}. Note that both |95A-K| and |95A-95K| are valid ranges.
+% \item The number of the last residue is 245A\textsubscript{rel}(range |245A|).
+% \end{itemize}
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomResidueNumbering}
+% \begin{examplecode}
+% \begin{pmbdomains}[%
+% sequence=IVGGWECEKHSQPWQVAVYSHGWAHCGGVLVHPQWVLTAAHCLK%
+% KNSQVWLGRHNLFEPEDTGQRVPVSHSFPHPLYNMSLLKHQSLRPDEDSSH%
+% DLMLLRLSEPAKITDVVKVLGLPTQEPALGTTCYASGWGSIEPEEFLRPRS%
+% LQCVSLHLLSNDMCARAYSEKVTEFMLCAGLWTGGKDTCGGDSGGPLVCNG%
+% VLQGITSWGPEPCALPEKPAVYTKVVHYRKWIKDTIAANP,
+% residue numbering={16-39,41-73,75-95,95A-K,96-125,%
+% 128-186,186A-186B,187-203,208-223,223A,224-245,245A},
+% x unit=4mm,
+% residues per line=40,
+% show name=false,
+% ruler range=auto-auto step 1,
+% ruler distance=-.3,
+% baseline skip=2
+% ]{237}
+% \setfeaturestyle{other/main chain}{*1{draw, line width=2pt, black!10}}
+% \addfeature{other/sequence}{16}{245A}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeOption{domains/}{residue range}{auto-auto}<lower>'-'<upper>
+% All residues from \meta{lower} to \meta{upper} will appear in the output. Possible values for \meta{lower} and \meta{upper} are:
+% \begin{itemize}
+% \item |auto|, which indicates the first or last residue, respectively;
+% \item a plain number, which denotes a residue in the \textit{relative} numbering scheme set by \opt{residue numbering};
+% \item a parenthesized number, which denotes a residue in the \textit{absolute} numbering scheme.
+% \end{itemize}
+% In Example~\ref{exa:DomResidueRange}, only residues 650\textsubscript{abs} to 850\textsubscript{rel} are shown. If a domain boundary lies outside of the range shown, only the appropriate part of the domain appears.
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomResidueRange}
+% \begin{examplecode}
+% \begin{pmbdomains}[%
+% show name=false, residue range=(650)-850,
+% residue numbering={1-500,601-1100}]{1000}
+% \addfeature[description=Domain 1]{domain}{(630)}{(660)}
+% \addfeature[description=Domain 2]{domain}{(680)}{(710)}
+% \addfeature[description=Domain 3]{domain}{840}{1000}
+% \addfeature[description=Domain 4 (invisible)]{domain}{1010}{1040}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeOption{domains/}{enlarge left}{0cm}<dimension>
+% \DescribeOption{domains/}{enlarge right}{0cm}<dimension>
+% \DescribeOption{domains/}{enlarge top}{1cm}<dimension>
+% \DescribeOption{domains/}{enlarge bottom}{0cm}<dimension>
+% % \pkg{pgfmolbio} clips features that would protrude into the left or right margin. However, limits in the \TikZ\ clipping mechanism prevent correct automatic updates of the bounding box for the domain diagram. Although the package tries hard to establish a bounding box that is sufficiently large, the process may require manual intervention. To this end, each \opt{enlarge ...} key enlarges the bounding box at the respective side (Example~\ref{exa:DomEnlargeBB}).
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomEnlargeBB}
+% \begin{examplecode}
+% \tikzset{%
+% baseline, tight background,%
+% background rectangle/.style={draw=red, thick}%
+% }
+% \pgfmolbioset[domains]{show name=false, y unit=1cm, show ruler=false}
+%
+% \begin{tikzpicture}[show background rectangle]
+% \begin{pmbdomains}{80}
+% \addfeature[description=Oops!]{domain}{20}{60}
+% \end{pmbdomains}
+% \end{tikzpicture}
+% \begin{tikzpicture}[show background rectangle]
+% \begin{pmbdomains}[enlarge bottom=-5mm]{80}
+% \addfeature[description=Better!]{domain}{20}{60}
+% \end{pmbdomains}
+% \end{tikzpicture}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{Feature Styles and Shapes}
+% \label{sec:DomFeatureStylesAndShapes}
+%
+% Each (implicit and explicit) feature of a domain chart has a certain \textit{shape} and \textit{style}. For instance, you can see five different feature \textit{shapes} in Example~\ref{exa:DomTikzpicture}: We explicitly added two features of shape (and type) \texttt{disulfide} and three features of shape \texttt{domain}. Furthermore, the package implicitly included features of shape \texttt{other/name}, \texttt{other/main chain} and \texttt{other/ruler}.
+%
+% Although the three \texttt{domain} features agree in shape, they differ in color, or (more generally) \textit{style}. Since \pkg{pgfmolbio} distinguishes between shapes and styles, you may draw equally shaped features with different colors, strokes, shadings etc.
+%
+% \DescribeMacro\setfeaturestyle{<type>}{<style list>}
+% Specifies a \meta{style list} for the given feature \meta{type}. The complete syntax ist
+%
+% \begin{quote}
+% \meta{style list} := \MacroArgs{<style list item>[','<style list item>', ...']}\\
+% \meta{style list item} := \MacroArgs<multiplier><style>\\
+% \meta{multiplier} := \MacroArgs['*'<number>]\\
+% \meta{style} := \MacroArgs<single key-value pair>' | '{<key-value list>}
+% \end{quote}
+%
+% A style list item of the general form |*|\meta{n}|{|\meta{style}|}| instructs the package to repeat the \meta{style} \meta{n}-times. (This syntax is reminiscent of column specifications in a |tabular| environment. However, do \textit{not} enclose numbers with more than one digit in curly braces!) You may omit the trivial multiplier |*1|, but never forget the curly braces surrounding a \meta{style} that contains two or more key-value pairs. Furthermore, \pkg{pgfmolbio} loops over the style list until all features have been drawn.
+%
+% For instance, the style list in Example~\ref{exa:DomFeatureStyle} fills the first feature red, then draws a green one with a thick stroke, and finally draws two dashed blue features.
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomFeatureStyle}
+% \begin{examplecode}
+% \begin{pmbdomains}[show name=false]{200}
+% \setfeaturestyle{domain}%
+% {fill=red, {thick, fill=green}, *2{blue, dashed}}
+% \addfeature{domain}{11}{30}
+% \addfeature{domain}{41}{60}
+% \addfeature{domain}{71}{90}
+% \addfeature{domain}{101}{120}
+% \addfeature{domain}{131}{150}
+% \addfeature{domain}{161}{180}
+% \addfeature{domain}{191}{200}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+
+% \DescribeOption{domains/}{style}{\textrm{(empty)}}<style>
+% Although |\setfeaturestyle| may appear in a |pmbdomains| environment, changes introduced in this way are not limited to the current \TeX\ group (since feature styles are stored in Lua variables). Instead, use the \opt{style} key to locally override a feature style (Example~\ref{exa:DomFeatureStyleKey}).
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomFeatureStyleKey}
+% \begin{examplecode}
+% \begin{pmbdomains}[show name=false]{100}
+% \addfeature{domain}{11}{30}
+% \begingroup
+% \setfeaturestyle{domain}{{thick, fill=red}}
+% \addfeature{domain}{41}{60}
+% \endgroup
+% \addfeature{domain}{71}{90} % the new style persists ...
+% \end{pmbdomains}
+%
+% \begin{pmbdomains}[show name=false]{100}
+% \addfeature{domain}{11}{30}
+% \addfeature[style={thick, fill=red}]{domain}{41}{60}
+% \addfeature{domain}{71}{90} % correct solution
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeMacro\setfeaturestylealias{<new type>}{<existing type>}
+% After calling this macro, the \meta{new type} and \meta{existing type} share a common style, while they still differ in their shapes.
+%
+% \DescribeMacro\setfeatureshape{<type>}{<TikZ code>}\relax
+% Defines a new feature shape named \meta{type} or changes an existing one. \textbf{Caution:} If you change a shape within |pmbdomains|, you will also change the features of equal type that you already added. Thus, it is best to use |\setfeatureshape| only outside of this environment.
+%
+% \begin{exampletable}[p]
+% \caption{}
+% \label{exa:DomFeatureShape1}
+% \begin{examplecode}
+% \setfeatureshape{domain}{%
+% \draw [/pgfmolbio/domains/current style]
+% (\xLeft, \yMid + .5 * \pmbdomvalueof{y unit}) rectangle
+% (\xRight, \yMid - .5 * \pmbdomvalueof{y unit});
+% \node at (\xMid, \yMid) {\pmbdomvalueof{description}};
+% }
+%
+% \begin{pmbdomains}[show name=false]{200}
+% \addfeature[description=Domain 1]{domain}{30}{80}
+% \addfeature[description=Domain 2]{domain}{93}{163}
+% \addfeature[description=Domain 3]{domain}{168}{196}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \begin{exampletable}[p]
+% \caption{}
+% \label{exa:DomFeatureShape2}
+% \begin{examplecode}
+% \setfeatureshape{domain}{%
+% \pgfmathsetmacro\middlecorners{%
+% \xLeft + (\xRight - \xLeft) * .618%
+% }
+% \draw [/pgfmolbio/domains/current style]
+% (\xLeft, \yMid + 2mm) --
+% (\middlecorners pt, \yMid + 3mm) --
+% (\xRight, \yMid) --
+% (\middlecorners pt, \yMid - 3mm) --
+% (\xLeft, \yMid - 2mm) --
+% cycle;
+% }
+%
+% \begin{pmbdomains}[show name=false]{200}
+% \addfeature[description=Domain 1]{domain}{30}{80}
+% \addfeature[description=Domain 2]{domain}{93}{163}
+% \addfeature[description=Domain 3]{domain}{168}{196}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomFeatureShape3}
+% \begin{examplecode}
+% \pgfdeclareverticalshading[bordercolor,middlecolor]{mydomain}{100bp}{
+% color(0bp)=(bordercolor);
+% color(25bp)=(bordercolor);
+% color(40bp)=(middlecolor);
+% color(60bp)=(middlecolor);
+% color(75bp)=(bordercolor);
+% color(100bp)=(bordercolor)
+% }
+%
+% \tikzset{%
+% domain middle color/.code=\colorlet{middlecolor}{#1},%
+% domain border color/.code=\colorlet{bordercolor}{#1}%
+% }
+%
+% \setfeatureshape{domain}{%
+% \draw [shading=mydomain, rounded corners=2mm,
+% /pgfmolbio/domains/current style]
+% (\xLeft, \yMid + .5 * \pmbdomvalueof{y unit}) rectangle
+% (\xRight, \yMid - .5 * \pmbdomvalueof{y unit});
+% \node [above=3mm] at (\xMid, \yMid)
+% {\pmbdomvalueof{domain font}{\pmbdomvalueof{description}}};
+% }
+%
+% \begin{pmbdomains}[show name=false]{200}
+% \setfeaturestyle{domain}{%
+% {domain middle color=yellow!85!orange,%
+% domain border color=orange},%
+% {domain middle color=green,%
+% domain border color=green!50!black}%
+% {domain middle color=cyan,%
+% domain border color=cyan!50!black}%
+% }
+% \addfeature[description=Domain 1]{domain}{30}{80}
+% \addfeature[description=Domain 2]{domain}{93}{163}
+% \addfeature[description=Domain 3]{domain}{168}{196}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% Several commands that are only available in the \meta{TikZ code} allow you to design generic feature shapes:
+% \begin{itemize}
+% \item |\xLeft|, |\xMid| and |\xRight| expand to the left, middle and right $x$-coordinate of the feature. The coordinates are in a format suitable for |\draw| and similar commands.
+% \item |\yMid| expands to the $y$-coordinate of the feature, i.\,e. the $y$-coordinate of the current line.
+% \item You can access any values stored in the package’s \meta{key}s with the macro |\pmbdomvalueof{|\meta{key}|}|.
+% \item The style key \opt{/pgfmolbio/domains/current style} represents the current feature style selected from the associated style list.
+% \end{itemize}
+% The commands above are available for all features. By contrast, the following macros are limited to certain feature types:
+% \begin{itemize}
+% \item |\featureSequence| provides the amino acid sequence of the current feature. This macro is only available for explicitly added features and for \texttt{other/main chain}.
+% \item |\residueNumber| equals the current residue number. This macro is only available for shape \texttt{other/ruler} (see section~\ref{sec:DomRuler}).
+% \item |\currentResidue| expands to a single letter amino acid abbreviation. This macro is only available for shape \texttt{other/sequence} (see section~\ref{sec:DomSequences}).
+% \end{itemize}
+%
+% In Example~\ref{exa:DomFeatureShape1}, we develop a simple \texttt{domain} shape, which is a rectangle containing a centered label with the feature description. Example~\ref{exa:DomFeatureShape2} calculates an additional coordinate for a pentagonal domain shape and stores this coordinate in |\middlecorners|. Note that you have to insert ``pt'' after |\middlecorners| when using the stored coordinate. The domains in Example~\ref{exa:DomFeatureShape3} display a custom shading and inherit their style from the style list.
+%
+% \DescribeMacro\setfeatureshapealias{<new type>}{<existing type>}
+% After calling this macro, the \meta{new type} and \meta{existing type} share a common shape, while they still differ in their styles.
+%
+% \DescribeMacro\setfeaturealias{<new type>}{<existing type>}
+% This is a shorthand for calling both |\setfeatureshape| and |\setfeaturestyle|.
+%
+%
+% \section{Standard Features}
+% \label{sec:DomStandardFeatures}
+%
+% \pkg{pgfmolbio} provides a range of standard features. This section explains simple features (i.\,e., those that support no or only few options), while later sections cover advanced ones. Some features include predefined aliases, which facilitate inclusion of external files (see section~\ref{sec:DomFileInput}).
+%
+% \DescribeFeature*{default}
+% A fallback for undefined features, in which case \TeX\ issues a warning (Example~\ref{exa:DomFeatureDefault}).
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomFeatureDefault}
+% \begin{examplecode}
+% \begin{pmbdomains}[show name=false]{100}
+% \addfeature{default}{21}{50}
+% \addfeature{unknown}{61}{90} % i.e. default shape/style
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeFeature{domain}{DOMAIN}
+% A generic feature for protein domains. It consists of a rectangle with rounded corners and a label in the center, which shows the value of \opt{description}.
+%
+% \DescribeOption{domains/}{domain font}{\string\footnotesize}<font commands>
+% Sets the font for the label of a \texttt{domain} feature. The last command may take a single argument (Example~\ref{exa:DomFeatureDomain}).
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomFeatureDomain}
+% \begin{examplecode}
+% \begin{pmbdomains}[show name=false]{100}
+% \addfeature[description=Domain 1]{domain}{21}{50}
+% \addfeature[description=Domain 2,%
+% domain font=\tiny\textit]{DOMAIN}{61}{90}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeFeature{signal peptide}{SIGNAL}
+% Adds a signal peptide (Example~\ref{exa:DomFeatureProSignal}).
+%
+% \DescribeFeature{propeptide}{PROPEP}
+% Adds a propeptide (Example~\ref{exa:DomFeatureProSignal}).
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomFeatureProSignal}
+% \begin{examplecode}
+% \begin{pmbdomains}[show name=false]{100}
+% \addfeature{signal peptide}{1}{15}
+% \addfeature{propeptide}{16}{50}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeFeature{carbohydrate}{CARBOHYD}
+% Adds glycosylation (Example~\ref{exa:DomFeatureCarbohyd}).
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomFeatureCarbohyd}
+% \begin{examplecode}
+% \begin{pmbdomains}[show name=false]{100}
+% \addfeature[description=GlcNAc]{carbohydrate}{25}{25}
+% \addfeature[description=Xyl]{CARBOHYD}{60}{60}
+% \addfeature[description=Domain 1]{domain}{21}{50}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeFeature*{other/main chain}
+% This feature is automatically added to the feature list at the end of each |pmbdomains| environment. It represents the protein main chain, which appears as a grey line by default. Nevertheless, you can alter the backbone just like any other feature (Example~\ref{exa:DomFeatureMainchain}).
+%
+% \begin{exampletable}[p]
+% \caption{}
+% \label{exa:DomFeatureMainchain}
+% \begin{examplecode}
+% \setfeatureshape{other/main chain}{%
+% \draw [/pgfmolbio/domains/current style]
+% (\xLeft, \yMid + .5 * \pmbdomvalueof{y unit}) rectangle
+% (\xRight, \yMid - .5 * \pmbdomvalueof{y unit});
+% \draw (\xLeft, \yMid) --
+% (\xLeft - 2mm, \yMid)
+% node [left] {\tiny H$_2$N};
+% \draw (\xRight, \yMid) --
+% (\xRight + 2mm, \yMid)
+% node [right] {\tiny COOH};
+% }
+% \begin{pmbdomains}%
+% [show name=false, enlarge left=-0.8cm, enlarge right=1.2cm]{100}
+% \setfeaturestyle{other/main chain}{{draw=black,fill=black!20}}
+% \addfeature[description=1]{domain}{10}{25}
+% \addfeature[description=2]{domain}{30}{55}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeFeature*{other/name}
+% This feature is automatically added to the feature list at the end of each |pmbdomains| environment. It relates to the protein name, which is normally displayed at the top center of the chart, together with the number of residues (Example~\ref{exa:DomFeatureName}). The following auxiliary commands are available for the feature style \TikZ\ code: |\xLeft|, |\xMid|, |\xRight| and \opt{current style}.
+%
+% \begin{exampletable}[p]
+% \caption{}
+% \label{exa:DomFeatureName}
+% \begin{examplecode}
+% \setfeatureshape{other/name}{%
+% \node [/pgfmolbio/domains/current style]
+% at (\xLeft, \pmbdomvalueof{baseline skip}
+% * \pmbdomvalueof{y unit} / 2)
+% {A \pmbdomvalueof{sequence length} residues long protein
+% called `\pmbdomvalueof{name}'};
+% }
+% \begin{pmbdomains}[name=\TeX ase]{150}
+% \setfeaturestyle{other/name}{{font=\bfseries, right}}
+% \addfeature[description=1]{domain}{10}{25}
+% \addfeature[description=2]{domain}{55}{123}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{Disulfides and Ranges}
+% \label{sec:DomDisulfides}
+%
+% \DescribeFeature{disulfide}{DISULFID}
+% \pkg{pgfmolbio} indicates disulfide bridges by brackets above the main chain. Since disulfides are often interleaved in linear representations of proteins, the package automatically stacks them in order to avoid overlaps (Example~\ref{exa:DomFeatureDisulfide}).
+%
+% \DescribeOption{domains/}{level}{\textrm{(empty)}}<number>
+% Manually sets the level of a disulfide feature.
+%
+% \DescribeOption{domains/}{disulfide base distance}{1}<number>
+% The distance (as a multiple of $y$-units) between the main chain and the first level.
+%
+% \DescribeOption{domains/}{disulfide level distance}{.2}<number>
+% The space (as a multiple of $y$-units) between levels (see the figure below).
+%
+% \begin{center}
+% \begin{tikzpicture}[decoration=brace]
+% \begin{pmbdomains}[show name=false, disulfide level distance=.6]{100}
+% \setfeaturestyle{disulfide}{draw=red, draw=blue, draw=violet}
+% \addfeature{disulfide}{2}{10}
+% \addfeature{disulfide}{5}{50}
+% \addfeature{disulfide}{8}{15}
+% \addfeature{disulfide}{20}{45}
+% \addfeature[level=1]{disulfide}{70}{85}
+% \addfeature[level=1]{disulfide}{80}{92}
+% \addfeature{domain}{25}{60}
+% \draw [dashed, black!80]
+% (-5 * \pmbdomvalueof{x unit},
+% \pmbdomvalueof{disulfide base distance} * \pmbdomvalueof{y unit}) --
+% (105 * \pmbdomvalueof{x unit},
+% \pmbdomvalueof{disulfide base distance} * \pmbdomvalueof{y unit})
+% node [right] {\small Level 1};
+% \draw [dashed, black!60]
+% (-5 * \pmbdomvalueof{x unit},
+% \pmbdomvalueof{disulfide base distance} * \pmbdomvalueof{y unit} +
+% \pmbdomvalueof{disulfide level distance} * \pmbdomvalueof{y unit}) --
+% (105 * \pmbdomvalueof{x unit},
+% \pmbdomvalueof{disulfide base distance} * \pmbdomvalueof{y unit} +
+% \pmbdomvalueof{disulfide level distance} * \pmbdomvalueof{y unit})
+% node [right] {\small Level 2};
+% \draw [dashed, black!40]
+% (-5 * \pmbdomvalueof{x unit},
+% \pmbdomvalueof{disulfide base distance} * \pmbdomvalueof{y unit} +
+% 2 * \pmbdomvalueof{disulfide level distance} * \pmbdomvalueof{y unit}) --
+% (105 * \pmbdomvalueof{x unit},
+% \pmbdomvalueof{disulfide base distance} * \pmbdomvalueof{y unit} +
+% 2 * \pmbdomvalueof{disulfide level distance} * \pmbdomvalueof{y unit})
+% node [right] {\small Level 3};
+% \draw [decorate]
+% (-6 * \pmbdomvalueof{x unit},
+% 0) --
+% (-6 * \pmbdomvalueof{x unit},
+% \pmbdomvalueof{disulfide base distance} * \pmbdomvalueof{y unit})
+% node [pos=.5, left] {\small\texttt{disulfide base distance}};
+% \draw [decorate]
+% (-6 * \pmbdomvalueof{x unit},
+% \pmbdomvalueof{disulfide base distance} * \pmbdomvalueof{y unit} +
+% \pmbdomvalueof{disulfide level distance} * \pmbdomvalueof{y unit}) --
+% (-6 * \pmbdomvalueof{x unit},
+% \pmbdomvalueof{disulfide base distance} * \pmbdomvalueof{y unit} +
+% 2 * \pmbdomvalueof{disulfide level distance} * \pmbdomvalueof{y unit})
+% node [pos=.5, left] {\small\texttt{disulfide level distance}};
+% \end{pmbdomains}
+% \end{tikzpicture}
+% \end{center}
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomFeatureDisulfide}
+% \begin{examplecode}
+% \begin{pmbdomains}[show name=false,
+% disulfide base distance=.7,
+% disulfide level distance=.4]{100}
+% \setfeaturestyle{disulfide}{draw=red, draw=blue, draw=violet}
+% \addfeature{disulfide}{2}{10}
+% \addfeature{disulfide}{5}{50}
+% \addfeature{disulfide}{8}{15}
+% \addfeature{disulfide}{20}{45}
+% \addfeature[level=1]{disulfide}{70}{85}
+% \addfeature[level=1]{disulfide}{80}{92}
+% \addfeature{domain}{25}{60}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \begin{DescribeMacros}
+% \Macro\setdisulfidefeatures{<key list>}
+% \Macro\adddisulfidefeatures{<key list>}
+% \Macro\removedisulfidefeatures{<key list>}
+% \end{DescribeMacros}
+% These macros edit the list of ``disulfide-like'' features, i.\,e. those subject to the automatic stacking mechanism. |\setdisulfidefeatures| renews this list, replacing any previous contents. |\adddisulfidefeatures| adds the features in its \meta{key list} to an existing list, while |\removedisulfidefeatures| removes selected features. By default, there are three disulfide-like features: \texttt{disulfide}, \texttt{DISULFID} and \texttt{range}. Note that |\setfeaturealias| and its relatives do not influence the list.
+%
+% \DescribeFeature*{range}
+% Indicates a range of residues. \texttt{range} features are disulfide-like in order to prevent them from overlapping.
+%
+% \DescribeOption{domains/}{range font}{\string\sffamily\string\scriptsize}<font commands>
+% Changes the font for the range label. The last command may take a single argument (Example~\ref{exa:DomFeatureRange}).
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomFeatureRange}
+% \begin{examplecode}
+% \begin{pmbdomains}[show name=false]{100}
+% \addfeature[description=1]{domain}{10}{25}
+% \addfeature[description=2]{domain}{40}{70}
+% \addfeature[description=Range 1]{range}{15}{30}
+% \addfeature[description=Range 2]{range}{25}{60}
+% \addfeature[description=Range 3,%
+% style={very thick, draw=black},%
+% range font=\tiny\textcolor{red}]{range}{68}{86}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{Ruler}
+% \label{sec:DomRuler}
+%
+% \DescribeFeature*{other/ruler}
+% This feature is automatically added to the feature list at the end of each |pmbdomains| environment. It draws a ruler below the main chain, which indicates the residue numbers (Example~\ref{exa:DomFeatureRuler}). The following auxiliary commands are available for the feature style \TikZ\ code: |\xMid|, |\yMid|, |\residueNumber| and \opt{current style}.
+%
+% \DescribeOption{domains/}{show ruler}{true}<boolean>
+% Determines whether the rule is drawn.
+%
+% \DescribeOption{domains/}{ruler range}{auto-auto}<ruler range list>
+% The complete syntax for \opt{ruler range} is
+% \begin{quote}
+% \meta{ruler range list} := \MacroArgs{<ruler range>[','<ruler range>', ...']}\\
+% \meta{ruler range} := \MacroArgs<lower>'-'<upper>[' step '<interval>]\\
+% \meta{lower} := \MacroArgs'auto | '<number>[<letter>]' | '(<number>)\\
+% \meta{upper} := \MacroArgs'auto | '<number>[<letter>]' | '(<number>)\\
+% \meta{interval} := \MacroArgs<number>
+% \end{quote}
+% Each \meta{ruler range} tells the package to mark every \ometa{interval}th residue from \meta{lower} to \meta{upper} by an \texttt{other/ruler} feature; the |step| part is optional. Possible values for \meta{lower} and \meta{upper} are:
+% \begin{itemize}
+% \item |auto|, which indicates the leftmost or rightmost residue shown, respectively;
+% \item a plain number (with an optional letter), which denotes a residue in the \textit{relative} numbering scheme set by \opt{residue numbering};
+% \item a parenthesized number, which denotes a residue in the \textit{absolute} numbering scheme.
+% \end{itemize}
+%
+% \DescribeOption{domains/}{default ruler step size}{50}<number>
+% Step size for a \meta{ruler range} that lacks the optional |step| part.
+%
+% \DescribeOption{domains/}{ruler distance}{-.5}<factor>
+% Separation (multiples of the $y$-unit) between ruler and main chain (Example~\ref{exa:DomFeatureRuler}).
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomFeatureRuler}
+% \begin{examplecode}
+% \begin{pmbdomains}[x unit=2mm,
+% show name=false,
+% residue numbering={1-40,101-120},
+% ruler range={auto-10 step 1, 31-(41), 110-120 step 2},
+% default ruler step size=5,
+% ruler distance=-.7]{60}
+% \addfeature{domain}{10}{25}
+% \addfeature{domain}{40}{(50)}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{Sequences}
+% \label{sec:DomSequences}
+%
+% \DescribeOption{domains/}{sequence}{\textrm{empty}}<sequence>
+% Sets the amino acid \meta{sequence} of a protein (single-letter abbreviations).
+%
+% \DescribeFeature*{other/sequence}
+% Displays a sequence which is vertically centered at the main chain. Since a residue is only 0.5~mm wide by default, you should increase the \opt{x unit} when showing \texttt{sequence} features (Example~\ref{exa:DomFeatureSequence}).
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomFeatureSequence}
+% \begin{examplecode}
+% \begin{pmbdomains}[%
+% sequence=MGSKRSVPSRHRSLTTYEVMFAVLFVILV%
+% ALCAGLIAVSWLSIQGSVKDAAFGKSHEARGTL,
+% residues per line=50,
+% x unit=2mm, show name=false,
+% ruler range=auto-auto step 10]{50}
+% \setfeaturestyle{other/sequence}{font=\ttfamily\footnotesize}
+% \addfeature{domain}{20}{35}
+% \addfeature{other/sequence}{7}{42}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \begin{DescribeMacros}
+% \Macro\setfeatureprintfunction{<key list>}{<Lua function>}
+% \Macro\removefeatureprintfunction{<key list>}
+% \Macro\pmbdomdrawfeature{<type>}
+% \end{DescribeMacros}
+% Some features require sophisticated coordinate calculations. Hence, you might ocasionally want to call a Lua function as ``preprocessor'' before executing the \meta{TikZ code} of |\setfeatureshape|. For this purpose, |\setfeatureprintfunction| registers such a \meta{Lua function} and |\removefeatureprintfunction| deletes the preprocessing function(s) for all features in the \meta{key list}.
+%
+% A suitable Lua function
+% \begin{itemize}
+% \item receives up to six arguments in the following order (see also section~\ref{ssc:DocDomLuaPrintFunctions}):
+% \begin{enumerate}
+% \item A table describing the feature (see section~\ref{ssc:DocDomLuaProteinClass} for its fields);
+% \item the left $x$-coordinate of the feature (an integer);
+% \item its right $x$-coordinate (an integer);
+% \item the $y$-coordinate of the current line (an integer);
+% \item the dimension stored in \opt{x unit}, converted to scaled points (an integer);
+% \item the dimension stored in \opt{y unit}, converted to scaled points (an integer);
+% \end{enumerate}
+% \item performs all necessary calculations and defines all \TeX\ macros required by |\setfeatureshape|;
+% \item may execute |\pmbdomdrawfeature| with the appropriate feature \meta{type} to draw the feature.
+% \end{itemize}
+%
+%
+% Example~\ref{exa:DomPrintFunction} devises a new print function, §printFunnySequence§ (lines 2--17). It is similar to the default print function for \texttt{other/sequence} features, but adds random values to the $y$-coordinate of the individual letters.
+%
+% §printFunnySequence§ is a function with six arguments (line 2). We add the width of half a residue to the left $x$-coordinate, §xLeft§ (line 3), since each letter should be horizontally centered. We iterate over each letter in the §sequence§ field of the §feature§ table (lines 4--16). In each loop, calculated coordinates are stored in the \TeX\ macros |\xMid| (lines 5--7) and |\yMid| (lines 8--10). The construction |\string\\...| is expanded to |\\...| when §tex.sprint§ passes its argument back to \TeX. §pgfmolbio.dimToString§ converts a number representing a dimension in scaled points to a string (e.\,g., 65536 to ``1pt'', see section~\ref{sec:DocPkgLua}). The letter of the current residue is stored in |\currentResidue| (lines 11--13). Finally, each letter is drawn by calling |\pmbdomdrawfeature{other/sequence}| (line 14), and the $x$-coordinate increases by one (line 15). Line 25 registers §printFunnySequence§ for \texttt{other/sequence} features.
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomPrintFunction}
+% \begin{examplecode}
+% \directlua{
+% function printFunnySequence (feature, xLeft, xRight, yMid, xUnit, yUnit)
+% xLeft = xLeft + 0.5
+% for currResidue in feature.sequence:gmatch(".") do
+% tex.sprint("\string\\def\string\\xMid{" ..
+% pgfmolbio.dimToString(xLeft * xUnit) ..
+% "}")
+% tex.sprint("\string\\def\string\\yMid{" ..
+% pgfmolbio.dimToString((yMid + math.random(-5, 5) / 20) * yUnit) ..
+% "}")
+% tex.sprint("\string\\def\string\\currentResidue{" ..
+% currResidue ..
+% "}")
+% tex.sprint("\string\\pmbdomdrawfeature{other/sequence}")
+% xLeft = xLeft + 1
+% end
+% end
+% }
+%
+% \begin{pmbdomains}[%
+% sequence=MGSKRSVPSRHRSLTTYEVMFAVLFVILVALCAGLIAVSWLSIQGSVKDAAF,
+% x unit=2mm, show name=false,
+% ruler range=auto-auto step 10]{40}
+% \setfeaturestyle{other/sequence}{font=\ttfamily\footnotesize}
+% \setfeatureprintfunction{other/sequence}{printFunnySequence}
+% \addfeature{domain}{20}{30}
+% \addfeature{other/sequence}{7}{38}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeFeature*{other/magnified sequence above}
+% Displays its sequence as a single string above the main chain, with dashed lines indicating the sequence start and stop on the backbone. This feature allows you to show sequences without the need to increase the \opt{x unit}.
+%
+% \DescribeFeature*{other/magnified sequence below}
+% Displays the sequence \textit{below} the backbone.
+%
+% \DescribeOption{domains/}{magnified sequence font}{\string\ttfamily\string\footnotesize}<font commands>
+% The font used for a magnified sequence (Example~\ref{exa:DomFeatureMagnifiedSequence}).
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomFeatureMagnifiedSequence}
+% \begin{examplecode}
+% \begin{pmbdomains}[%
+% sequence=MGSKRSVPSRHRSLTTYEVMFAVLFVIL%
+% VALCAGLIAVSWLSIQGSVKDAAFGKSHEARGTL,
+% enlarge left=-1cm, enlarge right=1cm, enlarge bottom=-1cm,
+% show name=false, show ruler=false]{50}
+% \addfeature{other/magnified sequence above}{7}{20}
+% \addfeature[magnified sequence font=\scriptsize\sffamily]%
+% {other/magnified sequence below}{34}{42}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+%
+% \section{Secondary Structure}
+% \label{sec:DomSecondaryStructure}
+%
+% \DescribeOption{domains/}{show secondary structure}{false}<boolean>
+% Determines whether the secondary structure is shown.
+%
+% \DescribeOption{domains/}{secondary structure distance}{1}<factor>
+% Secondary structures appear along a thin line \meta{factor} times the value of \opt{y unit} above the main chain. In accordance with the categories established by the Dictionary of Protein Secondary Structure\footnote{Kabsch, W. and Sander, C. (1983). Dictionary of protein secondary structure: pattern recognition of hydrogen-bonded and geometrical features. \textit{Biopolymers} \textbf{22}(12), 2577--2637.}, \pkg{pgfmolbio} provides seven features for displaying secondary structure types (Example~\ref{exa:DomShowSecStructure}):
+%
+% \begin{exampletable}
+% \caption{}
+% \label{exa:DomShowSecStructure}
+% \begin{examplecode}
+% \begin{pmbdomains}[%
+% show name=false,
+% sequence=MGSKRSVPSRHRSLTTYEVMFAVLFVILVALCAGL,
+% x unit=2.5mm,
+% enlarge top=1.5cm,
+% ruler range=auto-auto step 1,
+% show secondary structure=true,
+% secondary structure distance=1.5
+% ]{35}
+% \setfeaturestyle{other/sequence}{{font=\ttfamily\small}}
+% \addfeature{alpha helix}{2}{8}
+% \addfeature{pi helix}{9}{11}
+% \addfeature{310 helix}{13}{18}
+% \addfeature{beta strand}{20}{23}
+% \addfeature{beta bridge}{25}{28}
+% \addfeature{beta turn}{30}{31}
+% \addfeature{bend}{33}{34}
+% \addfeature{other/sequence}{1}{35}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeFeature{alpha helix}{HELIX}
+% Shows an $\alpha$-helix.
+%
+% \DescribeFeature*{pi helix}
+% Shows a $\pi$-helix.
+%
+% \DescribeFeature*{310 helix}
+% Shows a $3_{10}$-helix.
+%
+% \DescribeFeature{beta strand}{STRAND}
+% Shows a $\beta$-strand.
+%
+% \DescribeFeature{beta turn}{TURN}
+% Shows a $\beta$-turn.
+%
+% \DescribeFeature*{beta bridge}
+% Shows a $\beta$-bridge.
+%
+% \DescribeFeature*{bend}
+% Shows a bend.
+%
+% \begin{figure}
+% \centering
+% \caption{Shading colors of helix features.}
+% \label{fig:DomHelixColors}
+% \begin{tabular}{*4{>{\ttfamily}l}}
+% \toprule
+% \rmfamily\itshape Name & \multicolumn{3}{c}{\itshape \pkg{xcolor} definition} \\
+% \cmidrule(lr){2-4}
+% & \rmfamily $\alpha$-helix & \rmfamily $\pi$-helix & \rmfamily $3_{10}$-helix \\
+% \midrule
+% helix back border color & \multicolumn{3}{c}{\ttfamily white!50!black \color{white!50!black}\rule{1ex}{1ex}} \\
+% helix back main color & \multicolumn{3}{c}{\ttfamily white!90!black \color{white!90!black}\rule{1ex}{1ex}} \\
+% helix back middle color & \multicolumn{3}{c}{\ttfamily white \color{white}\rule{1ex}{1ex}} \\
+% \midrule
+% helix front border color & red!50!black \color{red!50!black}\rule{1ex}{1ex}
+% & yellow!50!black \color{yellow!50!black}\rule{1ex}{1ex}
+% & magenta!50!black \color{magenta!50!black}\rule{1ex}{1ex} \\
+% helix front main color & red!90!black \color{red!90!black}\rule{1ex}{1ex}
+% & yellow!70!red~~ \color{yellow!70!red}\rule{1ex}{1ex}
+% & magenta!90!black \color{magenta!90!black}\rule{1ex}{1ex} \\
+% helix front middle color & red!10!white \color{red!10!white}\rule{1ex}{1ex}
+% & yellow!10!white \color{yellow!10!white}\rule{1ex}{1ex}
+% & magenta!10!white \color{magenta!10!white}\rule{1ex}{1ex} \\
+% \bottomrule
+% \end{tabular}\hspace*{-67pt}\par\bigskip
+% \begin{tikzpicture}[font=\ttfamily\scriptsize]
+% \makeatletter
+% \draw [shading=helix full back] (1.5, 0) \@pmb@dom@helixsegment{1.5mm};
+% \tikzset{left}
+% \draw [->] (0, 0) node {helix back border color} -- (.5, 0);
+% \draw [->] (0, .225) node {helix back main color} -- (.5, .225);
+% \draw [->] (0, .675) node {helix back middle color} -- (.5, .675);
+% \draw [->] (0, 1.575) node {helix back main color} -- (.5, 1.575);
+% \draw [->] (0, 2.25) node {helix back border color} -- (.5, 2.25);
+% \tikzset{right}
+% \draw [shading=helix full front] (4, 0) [xscale=-1] \@pmb@dom@helixsegment{1.5mm};
+% \draw [<-] (5, 0) -- (5.5, 0) node {helix front border color};
+% \draw [<-] (5, .675) -- (5.5, .675) node {helix front main color};
+% \draw [<-] (5, 1.575) -- (5.5, 1.575) node {helix front middle color};
+% \draw [<-] (5, 2.025) -- (5.5, 2.025) node {helix front main color};
+% \draw [<-] (5, 2.25) -- (5.5, 2.25) node {helix front border color};
+% \tikzset{font=\rmfamily\scriptsize}
+% \draw (-4, -.2) -- (-4, -.5) -- (2.5, -.5)
+% node [pos=.5, below] {Shading \texttt{helix full back}}
+% -- (2.5, -.2);
+% \draw (3, -.2) -- (3, -.5) -- (9.5, -.5)
+% node [pos=.5, below] {Shading \texttt{helix full front}}
+% -- (9.5, -.2);
+% \end{tikzpicture}
+% \end{figure}
+%
+% \begin{table}[p]
+% \centering
+% \caption{Customizing helices in the \module{domains} module.}
+% \label{tab:DomHelixHelperFeatures}
+% \begin{tabular}{*2{>{\ttfamily}l} *2{>{\ttfamily\color{ProcessBlue}}l}}
+% \toprule
+% \rmfamily\itshape (a) Subfeatures
+% & \rmfamily\itshape (b) Corresponding shadings
+% & \multicolumn{2}{l}{\itshape (c) Coordinates} \\
+% \cmidrule(r){1-1}\cmidrule(r){2-2}\cmidrule{3-4}
+% helix/half upper back & helix half upper back & \string\xLeft & \string\yMid \\
+% helix/half lower back & helix half lower back & \string\xRight & \string\yMid \\
+% helix/full back & helix full back & \string\xMid & \string\yLower \\
+% helix/half upper front & helix half upper front & \string\xRight & \string\yMid \\
+% helix/full front & helix full front & \string\xMid & \string\yLower \\
+% \bottomrule
+% \end{tabular}
+% \end{table}
+%
+% \begin{exampletable}[p]
+% \caption{}
+% \label{exa:DomHelixColors}
+% \begin{examplecode}
+% \begin{pmbdomains}[%
+% show name=false,
+% x unit=2.5mm,
+% enlarge top=1.5cm,
+% ruler range=auto-auto step 5,
+% show secondary structure
+% ]{35}
+% \setfeaturestyle{alpha helix}{%
+% *1{helix front border color=blue!50!black,%
+% helix front main color=orange,%
+% helix front middle color=yellow!50},%
+% *1{helix front border color=olive,%
+% helix front main color=magenta,%
+% helix front middle color=green!50}%
+% }
+% \addfeature{alpha helix}{2}{8}
+% \addfeature{alpha helix}{9}{15}
+% \addfeature{alpha helix}{20}{27}
+% \addfeature{alpha helix}{30}{34}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \begin{exampletable}[p]
+% \caption{}
+% \label{exa:DomHelixHelperFeature}
+% \begin{examplecode}[basicstyle=\ttfamily\tiny]
+% \pgfmathsetmacro\yShift{%
+% \pmbdomvalueof{secondary structure distance}
+% * \pmbdomvalueof{y unit}%
+% }
+%
+% \setfeatureshape{helix/half upper back}{%
+% \draw [shading=helix half upper back]
+% (\xLeft, \yMid + \yShift pt) --
+% (\xLeft + .5 * \pmbdomvalueof{x unit},
+% \yMid + 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+% (\xLeft + 1.5 * \pmbdomvalueof{x unit},
+% \yMid + 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+% (\xLeft + \pmbdomvalueof{x unit}, \yMid + \yShift pt) --
+% cycle;
+% }
+%
+% \setfeatureshape{helix/half lower back}{%
+% \draw [shading=helix half lower back]
+% (\xRight, \yMid + \yShift pt) --
+% (\xRight - .5 * \pmbdomvalueof{x unit},
+% \yMid - 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+% (\xRight - 1.5 * \pmbdomvalueof{x unit},
+% \yMid - 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+% (\xRight - \pmbdomvalueof{x unit}, \yMid + \yShift pt) --
+% cycle;
+% }
+%
+% \setfeatureshape{helix/full back}{%
+% \draw [shading=helix full back]
+% (\xMid, \yLower + \yShift pt) --
+% (\xMid - \pmbdomvalueof{x unit}, \yLower + \yShift pt) --
+% (\xMid, \yLower + 3 * \pmbdomvalueof{x unit} + \yShift pt) --
+% (\xMid + \pmbdomvalueof{x unit},
+% \yLower + 3 * \pmbdomvalueof{x unit} + \yShift pt) --
+% cycle;
+% }
+%
+% \setfeatureshape{helix/half upper front}{%
+% \draw [shading=helix half upper front]
+% (\xRight, \yMid + \yShift pt) --
+% (\xRight - .5 * \pmbdomvalueof{x unit},
+% \yMid + 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+% (\xRight - 1.5 * \pmbdomvalueof{x unit},
+% \yMid + 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+% (\xRight - \pmbdomvalueof{x unit}, \yMid + \yShift pt) --
+% cycle;
+% }
+%
+% \setfeatureshape{helix/full front}{%
+% \draw [shading=helix full front]
+% (\xMid, \yLower + \yShift pt) --
+% (\xMid + \pmbdomvalueof{x unit}, \yLower + \yShift pt) --
+% (\xMid, \yLower + 3 * \pmbdomvalueof{x unit} + \yShift pt) --
+% (\xMid - \pmbdomvalueof{x unit},
+% \yLower + 3 * \pmbdomvalueof{x unit} + \yShift pt) --
+% cycle;
+% }
+%
+% \begin{pmbdomains}[%
+% show name=false, sequence=MGSKRSVPSR,
+% x unit=2.5mm, enlarge top=1.5cm,
+% ruler range=auto-auto step 1,
+% show secondary structure
+% ]{10}
+% \setfeaturestyle{other/sequence}{{font=\ttfamily\small}}
+% \addfeature{alpha helix}{2}{6}
+% \addfeature{alpha helix}{8}{9}
+% \addfeature{other/sequence}{1}{10}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \bigskip While changing the appearance of nonhelical secondary structure elements is simple, the complex helical features employ the print function §printHelixFeature§ (section~\ref{ssc:DocDomLuaPrintFunctions}). However, their appearance can be customized on several levels:
+% \begin{enumerate}
+% \item The elements of a helical feature are drawn by five ``subfeatures'', which are called by §printHelixFeature§ (Table~\ref{tab:DomHelixHelperFeatures}a).
+% \item For each subfeature, there is a corresponding shading (Table~\ref{tab:DomHelixHelperFeatures}b; see section~\ref{ssc:DocDomTexSecondaryStructure} and section~83 of the \TikZ\ manual for their definitions).
+% \item These shadings use six colors in total, three for front and three for back shadings (Figure~\ref{fig:DomHelixColors}). For each color, there is a key of the same name, so you can change helix colors in feature style lists (Example~\ref{exa:DomHelixColors}).
+% \end{enumerate}
+%
+%
+% \section{File Input}
+% \label{sec:DomFileInput}
+%
+% \begin{DescribeMacros}
+% \Macro\inputuniprot{<Uniprot file>}
+% \Macro\inputgff{<gff file>}
+% \end{DescribeMacros}
+% Include the features defined in an \meta{Uniprot file} or \meta{gff file}, respectively (Example~\ref{exa:DomInputExternalFiles}). These macros are only defined in |pmbdomains|.
+%
+% \begin{exampletable}[hb]
+% \caption{}
+% \label{exa:DomInputExternalFiles}
+% \begin{examplecode}
+% \begin{pmbdomains}[show secondary structure]{}
+% \setfeaturestyle{disulfide}{{draw=olive,thick}}
+% \inputuniprot{SampleUniprot.txt}
+% \end{pmbdomains}
+% \end{examplecode}
+% \begin{examplecode}
+% \begin{pmbdomains}[show name=false,show secondary structure]{200}
+% \setfeaturestyle{disulfide}{{draw=olive,thick}}
+% \inputgff{SampleGff.gff}
+% \end{pmbdomains}
+% \end{examplecode}
+% \end{exampletable}
+%
+% \DescribeOption{domains/}{sequence length}{\textrm{(empty)}}<number>
+% Note that in Example~\ref{exa:DomInputExternalFiles}, we had to set a sequence length for the |pmbdomains| environment that contains the |\inputgff| macro. \file{gff} files lack a sequence length field. By contrast, \pkg{pgfmolbio} reads the sequence length from an Uniprot file, and thus the mandatory argument of |pmbdomains| may remain empty. In general, the sequence length is stored in the key of the same name.
+%
+%
+%
+% \chapter{The \texorpdfstring{\module{convert}}{convert} module}
+% \label{cha:Convert}
+%
+%
+% \section{Overview}
+% \label{sec:ConOverview}
+%
+% The \module{convert} module supports users who wish to include \pkg{pgfmolbio} graphs, but who do not want to typeset their documents with a \TeX\ engine that implements Lua. To this end, the \module{convert} workflow comprises two steps: (1) Running Lua\LaTeX\ on an input file that contains at least one |\pmbchromatogram| or similar macros/environments. This will generate one \file{tex} file per graph macro/environment that contains only \TikZ\ commands. (2) Including this file in another \TeX\ document (via |\input|) which is then processed by any \TeX\ engine that supports \TikZ.
+%
+%
+% \section{Converting Chromatograms}
+% \label{sec:ConChromatograms}
+%
+% In order to create the external \TikZ\ file, run an input file like the one below through Lua\LaTeX:
+% \begin{lstlisting}[style=latex-expl,gobble=2]
+% \documentclass{article}
+% \usepackage[chromatogram,convert]{pgfmolbio}
+%
+% \begin{document}
+% \pmbchromatogram[sample range=base 50-base 60]{SampleScf.scf}
+% \pmbchromatogram[/pgfmolbio/convert/output file name=mytikzfile]%
+% {SampleScf.scf}
+% \pmbchromatogram[sample range=base 60-base 70]{SampleScf.scf}
+% \end{document}
+% \end{lstlisting}
+% The \module{convert} module disables \file{pdf} output and introduces the following keys:
+%
+% \DescribeOption{convert/}{output file name}{(auto)}<text>\relax
+% \DescribeOption{convert/}{output file extension}{tex}<text>\relax
+% With the default value for \opt{output file name} (``|(auto)|''), \pkg{pgfmolbio} creates files that are named \file{pmbconverted} and numbered consecutively (\file{pmbconverted0.tex}, \file{pmbconverted1.tex} etc.). Both keys can be changed locally (e.\,g., in the optional argument of |\pmbchromatogram|), but this turns off automatic numbering.
+%
+% The code above produces the files \file{pmbconverted0.tex}, \file{mytikzfile.tex} and \file{pmbconverted2.tex}. Below is an annotated excerpt from \file{pmbconverted0.tex}:
+% \begin{lstlisting}[style=latex-expl,gobble=2,escapeinside=`',basicstyle=\ttfamily\scriptsize,breaklines]
+% \begin{tikzpicture}
+% `[canvas section]'
+% \draw [/pgfmolbio/chromatogram/canvas style] (0mm, -0mm) rectangle (25mm, 20mm);
+% `[traces section]'
+% \draw [/pgfmolbio/chromatogram/trace A style] (0mm, 6.37mm) -- (0.2mm, 6.66mm) -- `[many coordinates]' -- (25mm, 0mm);
+% \draw [/pgfmolbio/chromatogram/trace C style] (0mm, 0.06mm) -- (0.2mm, 0.05mm) -- `[...]' -- (25mm, 6.27mm);
+% \draw [/pgfmolbio/chromatogram/trace G style] (0mm, 0.01mm) -- (0.2mm, 0.01mm) -- `[...]' -- (25mm, 0.05mm);
+% \draw [/pgfmolbio/chromatogram/trace T style] (0mm, 0mm) -- (0.2mm, 0mm) -- `[...]' -- (25mm, 0.06mm);
+% `[ticks/base labels/probabilities section]'
+% \draw [/pgfmolbio/chromatogram/tick A style] (0mm, -0mm) -- (0mm, -1mm) node [/pgfmolbio/chromatogram/base label A style] {\pgfkeysvalueof{/pgfmolbio/chromatogram/base label A text}} node [/pgfmolbio/chromatogram/base number style] {\strut 50};
+% \draw [ultra thick, pmbTraceGreen] (0mm, -8mm) -- (0.9mm, -8mm);
+% \draw [/pgfmolbio/chromatogram/tick T style] (1.8mm, -0mm) -- (1.8mm, -1mm) node [/pgfmolbio/chromatogram/base label T style] {\pgfkeysvalueof{/pgfmolbio/chromatogram/base label T text}};
+% \draw [ultra thick, pmbTraceGreen] (0.9mm, -8mm) -- (3mm, -8mm);
+% \draw [/pgfmolbio/chromatogram/tick A style] (4.2mm, -0mm) -- (4.2mm, -1mm) node [/pgfmolbio/chromatogram/base label A style] {\pgfkeysvalueof{/pgfmolbio/chromatogram/base label A text}};
+% \draw [ultra thick, pmbTraceGreen] (3mm, -8mm) -- (5.4mm, -8mm);
+% `[...]'
+% `[more ticks, base labels and probability rules]'
+% \end{tikzpicture}
+% \end{lstlisting}
+%
+% You can change the format of the coordinates by the following keys:
+%
+% \DescribeOption{}{coordinate unit}{mm}<unit>
+% \DescribeOption{}{coordinate format string}{\letterpercent s\letterpercent s}<format string>\relax
+% \pkg{pgfmolbio} internally calculates dimensions in scaled points, but usually converts them before returning them to \TeX. To this end, it selects the \meta{unit} stored in \opt{coordinate unit} (any of the standard \TeX\ units of measurement: \texttt{bp}, \texttt{cc}, \texttt{cm}, \texttt{dd}, \texttt{in}, \texttt{mm}, \texttt{pc}, \texttt{pt} or \texttt{sp}). In addition, the package formats the dimension according to the \meta{format string} given by \opt{coordinate format string}. This string basically follows the syntax of C's \texttt{printf} function, as described in the Lua reference manual. (Note: Use |\letterpercent| instead of \texttt{\%}, since \TeX\ treats anything following a percent character as comment.)
+%
+% Depending on the values of \opt{coordinate unit} and \opt{coordinate format string}, dimensions will be printed in different ways (Table~\ref{tab:CoordFormat}).
+%
+% \begin{table}
+% \centering
+% \caption{Effects of \texttt{\color{opt}coordinate unit} and \texttt{\color{opt}coordinate format string} when converting an internal \pkg{pgfmolbio} dimension of 200000~[sp].}
+% \label{tab:CoordFormat}
+% \begin{tabularx}{\textwidth}{*3{>{\ttfamily}l}X}
+% \toprule
+% \multicolumn{2}{c}{\itshape Values} & \multicolumn{1}{l}{\itshape Output} & \itshape Notes \\
+% \cmidrule(r){1-2}\cmidrule(r){3-3}\cmidrule{4-4}
+% sp & \%s\%s & 200000sp & simple conversion \\
+% mm & \%s\%s & 1.0725702011554mm & default settings, may lead to a large number of decimal places \\
+% mm & \%.3f\%s & 1.073mm & round to three decimal places \\
+% cm & \%.3f & 0.107 & don't print any unit, i.\,e. use \TikZ's \texttt{xyz} coordinate system \\
+% \bottomrule
+% \end{tabularx}
+% \end{table}
+%
+% \bigskip
+% The output files can be included in a file which is processed by pdf\LaTeX:
+% \begin{lstlisting}[style=latex-expl,gobble=2]
+% \documentclass{article}
+% \usepackage[chromatogram]{pgfmolbio}
+%
+% \begin{document}
+% \input{pmbconverted.tex}
+% \end{document}
+% \end{lstlisting}
+%
+% Several keys of the \module{chromatogram} module must contain their final values before conversion, while others can be changed afterwards, i.\,e., before the generated file is loaded with |\input| (Table~\ref{tab:ConvertChrKeys}).
+%
+% \begin{table}[ht]
+% \centering
+% \caption{Keys of the \module{chromatogram} module that require final values prior to conversion.}
+% \label{tab:ConvertChrKeys}
+% \begin{tabular}{*3{>{\ttfamily\color{opt}}l}}
+% \toprule
+% \multicolumn{2}{c}{\itshape Required} & \multicolumn{1}{c}{\itshape Not required} \\
+% \cmidrule(r){1-2}\cmidrule(l){3-3}
+% base labels drawn & sample range & base label style \\
+% base number range & samples per line & base label X style \\
+% baseline skip & show base numbers & base label X text \\
+% bases drawn & tick length & base number style \\
+% canvas height & ticks drawn & canvas style \\
+% probabilities drawn & traces drawn & tick style \\
+% probability distance & x unit & tick X style \\
+% probability style function & y unit & trace style \\
+% & & trace X style \\
+% \bottomrule
+% \end{tabular}
+% \end{table}
+%
+%
+% \section{Converting Domain Diagrams}
+% \label{sec:ConDomains}
+%
+% \DescribeOption{convert/}{output code}{tikz}'pgfmolbio | tikz'
+% In principle, domain diagrams are converted like sequencing chromatograms (section~\ref{sec:ConChromatograms}). However, \opt{output code} lets you choose the kind of code \module{convert} writes to the output file: |pgfmolbio| generates a |pmbdomains| environment containing |\addfeature| commands, |tikz| produces \TikZ\ code.
+%
+% ``Converting'' one |pmbdomains| environment in the input file to another one in the output file might seem pointless. Nonetheless, this conversion mechanism can be highly useful for extracting features from a Uniprot or \file{gff} file. For example, consider the following input file:
+% \begin{lstlisting}[style=latex-expl,gobble=2]
+% \documentclass{article}
+% \usepackage[domains,convert]{pgfmolbio}
+%
+% \begin{document}
+% \pgfmolbioset[convert]{output code=pgfmolbio}
+% \begin{pmbdomains}{}
+% \inputuniprot{SampleUniprot.txt}
+% \end{pmbdomains}
+% \end{document}
+% \end{lstlisting}
+% The corresponding output is
+% \begin{lstlisting}[style=latex-expl,gobble=2,escapeinside=`']
+% \begin{pmbdomains}
+% [name={TestProtein},
+% sequence=MGSKRSVPSRHRSL`[...]'PLATPGNVSIECP]{200}
+% \addfeature[description={Disulfide 1}]{DISULFID}{5}{45}
+% \addfeature[description={Disulfide 2}]{DISULFID}{30}{122}
+% \addfeature[description={Disulfide 3}]{DISULFID}{51}{99}
+% \addfeature[description={Domain 1}]{DOMAIN}{10}{40}
+% \addfeature[description={Domain 2}]{DOMAIN}{60}{120}
+% \addfeature[description={Domain 3}]{DOMAIN}{135}{178}
+% \addfeature[description={Strand 1}]{STRAND}{15}{23}
+% \addfeature[description={Strand 2}]{STRAND}{25}{32}
+% \addfeature[description={Helix 1}]{HELIX}{60}{75}
+% \addfeature[description={Helix 2}]{HELIX}{80}{108}
+% \addfeature[description={Sugar 1}]{CARBOHYD}{151}{151}
+% \addfeature[description={Sugar 2}]{CARBOHYD}{183}{183}
+% \end{pmbdomains}
+% \end{lstlisting}
+% Obviously, this method is particularly suitable for Uniprot files containing many features.
+%
+% \DescribeOption{convert/}{include description}{true}<boolean>
+% Decides whether the feature description obtained from the input should appear in the output. Since the description field in FT entries of Uniprot files can be quite long, you may not wish to show it in the output. For example, the output of the example above with \opt{include description}|=false| looks like
+% \begin{lstlisting}[style=latex-expl,gobble=2,escapeinside=`']
+% \begin{pmbdomains}
+% [name={TestProtein},
+% sequence=MGSKRSVPSRHRSL`[...]'PLATPGNVSIECP]{200}
+% \addfeature{DISULFID}{5}{45}
+% \addfeature{DISULFID}{30}{122}
+% \addfeature{DISULFID}{51}{99}
+% `[...]'
+% \end{pmbdomains}
+% \end{lstlisting}
+%
+% \bigskip
+% With \opt{output code}|=tikz|, we obtain the following (annotated) output file:
+% \begin{lstlisting}[style=latex-expl,gobble=2,escapeinside=`',basicstyle=\ttfamily\scriptsize,breaklines]
+% `[set relevant keys]'
+% \pgfmolbioset[domains]{name={TestProtein},sequence={MGSKRS`[...]'VSIECP},sequence length=200}
+% `[the actual \TikZ\ picture]'
+% \begin{tikzpicture}
+% `[each feature appears within its own scope]'
+% \begin{scope}\begin{pgfinterruptboundingbox}
+% \def\xLeft{0mm}
+% \def\xMid{50mm}
+% \def\xRight{100mm}
+% \def\yMid{-0mm}
+% \def\featureSequence{MGSKRS`[...]'VSIECP}
+% \clip (-50mm, \yMid + 100mm) rectangle (150mm, \yMid - 100mm);
+% \pgfmolbioset[domains]{style={{draw, line width=2pt, black!25}},@layer=1}
+% \pmbdomdrawfeature{other/main chain}
+% \end{pgfinterruptboundingbox}\end{scope}
+% `[more features]'
+% `[...]'
+% `[helix features require additional drawing commands]'
+% \begin{scope}\begin{pgfinterruptboundingbox}
+% \def\xLeft{29.5mm}
+% \def\xMid{33.5mm}
+% \def\xRight{37.5mm}
+% \def\yMid{-0mm}
+% \def\featureSequence{GTLKIISGATYNPHLQ}
+% \clip (-50mm, \yMid + 100mm) rectangle (87.5mm, \yMid - 100mm);
+% \pgfmolbioset[domains]{style={{helix front border color=red!50!black,helix front main color=red!90!black,helix front middle color=red!10!white}},description={Helix 1}}
+% \pgfmolbioset[domains]{current style}
+% \def\xLeft{29.5mm}
+% \def\yMid{-0mm}
+% \pmbdomdrawfeature{helix/half upper back}
+% \def\xMid{30.75mm}
+% \def\yLower{-0.75mm}
+% \pmbdomdrawfeature{helix/full back}
+% `[more helix parts]'
+% \end{pgfinterruptboundingbox}\end{scope}
+% `[...]'
+% `[ruler section]'
+% \begin{scope}
+% \pgfmolbioset[domains]{current style/.style={black}}
+% \def\xMid{0.25mm}
+% \let\xLeft\xMid\let\xRight\xMid
+% \def\yMid{-0mm}
+% \def\residueNumber{1}
+% \pmbdomdrawfeature{other/ruler}
+% \pgfmolbioset[domains]{current style/.style={black!50}}
+% \def\xMid{25.25mm}
+% \let\xLeft\xMid\let\xRight\xMid
+% \def\yMid{-0mm}
+% \def\residueNumber{51}
+% \pmbdomdrawfeature{other/ruler}
+% `[more ruler numbers]'
+% `[...]'
+% \end{scope}
+% `[name section]'
+% \begin{scope}
+% \pgfmolbioset[domains]{current style/.style={font=\sffamily }}
+% \def\xLeft{0mm}
+% \def\xMid{50mm}
+% \def\xRight{100mm}
+% \def\yMid{0mm}
+% \pmbdomdrawfeature{other/name}
+% \end{scope}
+% `[adjust picture size]'
+% \pmbprotocolsizes{\pmbdomvalueof{enlarge left}}{\pmbdomvalueof{enlarge top}}
+% \pmbprotocolsizes{100mm + \pmbdomvalueof{enlarge right}}{-0mm + \pmbdomvalueof{enlarge bottom}}
+% \end{tikzpicture}
+% \end{lstlisting}
+%
+% Several keys of the \module{domains} module must contain their final values before conversion, and some macros can't be used afterwards (Table~\ref{tab:ConvertDomKeysAndMacros}).
+%
+% \begin{table}[ht]
+% \caption{Keys and macros of the \module{domain} module that require final values prior to conversion or can't be used afterwards, respectively.}
+% \label{tab:ConvertDomKeysAndMacros}\small
+% \begin{tabular}{*3{>{\ttfamily\color{opt}}l}}
+% \toprule
+% \multicolumn{2}{c}{\itshape Required} & \multicolumn{1}{c}{\itshape Not required} \\
+% \cmidrule(r){1-2}\cmidrule(l){3-3}
+% baseline skip & ruler distance & domain font \\
+% default ruler step size & ruler range & enlarge bottom \\
+% description & secondary structure distance & enlarge left \\
+% disulfide base distance & sequence & enlarge right \\
+% disulfide level distance & sequence length & enlarge top \\
+% level & show ruler & magnified sequence font \\
+% name & style & range font \\
+% residue numbering & x unit & show secondary structure \\
+% residue range & y unit & \\
+% residues per line & & \\
+% \cmidrule(r){1-2}\cmidrule(l){3-3}
+% \color{ProcessBlue}\string\adddisulfidefeatures
+% & \color{ProcessBlue}\string\setfeatureprintfunction
+% & \color{ProcessBlue}\string\setfeaturealias \\
+% \color{ProcessBlue}\string\removedisulfidefeatures
+% & \color{ProcessBlue}\string\setfeaturestyle
+% & \color{ProcessBlue}\string\setfeatureshape \\
+% \color{ProcessBlue}\string\removefeatureprintfunction
+% & \color{ProcessBlue}\string\setfeaturestylealias
+% & \color{ProcessBlue}\string\setfeatureshapealias \\
+% \color{ProcessBlue}\string\setdisulfidefeatures & & \\
+% \bottomrule
+% \end{tabular}\hspace*{-53pt}
+% \end{table}
+%
+%
+% \StopEventually{}
+% \chapter{Implementation}
+% \label{cha:Implementation}
+% \renewcommand*\thelstnumber{\arabic{section}.\arabic{lstnumber}}
+%
+% \iffalse
+%<*pgfmolbio-tex>
+% \fi
+%
+% \section{\texorpdfstring{\file{pgfmolbio.sty}}{pgfmolbio.sty}}
+% \label{sec:DocPkgTex}
+%
+% \def\ydoclistingssettings{\lstset{style=latex-doc}}
+% The options for the main style file determine which module(s) should be loaded.
+%
+% \begin{macrocode}
+\newif\ifpmb@loadmodule@chromatogram
+\newif\ifpmb@loadmodule@domains
+\newif\ifpmb@loadmodule@convert
+
+\DeclareOption{chromatogram}{%
+ \pmb@loadmodule@chromatogramtrue%
+}
+\DeclareOption{domains}{%
+ \pmb@loadmodule@domainstrue%
+}
+\DeclareOption{convert}{%
+ \pmb@loadmodule@converttrue%
+}
+
+\ProcessOptions
+
+% \end{macrocode}
+% The main style file also loads the following packages and \TikZ\ libraries.
+% \begin{macrocode}
+\RequirePackage{ifluatex}
+\ifluatex
+ \RequirePackage{luatexbase-modutils}
+ \RequireLuaModule{lualibs}
+ \RequireLuaModule{pgfmolbio}
+\fi
+\RequirePackage[svgnames,dvipsnames]{xcolor}
+\RequirePackage{tikz}
+ \usetikzlibrary{positioning,svg.path}
+
+% \end{macrocode}
+% \begin{macro}{\pgfmolbioset}[2]{The \ometa{module} to which the options apply.}{A \meta{key-value list} which configures the graphs.}
+% \begin{macrocode}
+\newcommand\pgfmolbioset[2][]{%
+ \def\@tempa{#1}%
+ \ifx\@tempa\@empty%
+ \pgfqkeys{/pgfmolbio}{#2}%
+ \else%
+ \pgfqkeys{/pgfmolbio/#1}{#2}%
+ \fi%
+}
+
+% \end{macrocode}
+% \end{macro}
+% We introduce two package-wide keys.
+% \begin{macrocode}
+\pgfkeyssetvalue{/pgfmolbio/coordinate unit}{mm}
+\pgfkeyssetvalue{/pgfmolbio/coordinate format string}{\letterpercent s\letterpercent s}
+
+% \end{macrocode}
+% Furthermore, we define two scratch token registers. Strictly speaking, the two conditionals belong to the \module{convert} module, but all modules need to know them.
+% \begin{macrocode}
+\newtoks\@pmb@toksa
+\newtoks\@pmb@toksb
+\newif\ifpmb@con@includedescription
+\newif\ifpmb@con@outputtikzcode
+
+% \end{macrocode}
+% \begin{macro}{\pmbprotocolsizes}[2]{$x$-coordinate.}{$y$-coordinate.}
+% An improved version of |\pgf@protocolsizes| that accepts coordinate calculations.
+% \begin{macrocode}
+\def\pmbprotocolsizes#1#2{%
+ \pgfpoint{#1}{#2}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+}
+
+% \end{macrocode}
+% \end{macro}
+% Finally, we load the modules requested by the user.
+% \begin{macrocode}
+\ifpmb@loadmodule@chromatogram
+ \input{pgfmolbio.chromatogram.tex}
+\fi
+\ifpmb@loadmodule@domains
+ \input{pgfmolbio.domains.tex}
+\fi
+\ifpmb@loadmodule@convert
+ \input{pgfmolbio.convert.tex}
+\fi
+% \end{macrocode}
+%
+% \iffalse
+%</pgfmolbio-tex>
+%<*pgfmolbio-lua>
+% \fi
+%
+%
+% \section{\texorpdfstring{\file{pgfmolbio.lua}}{pgfmolbio.lua}}
+% \label{sec:DocPkgLua}
+%
+% \def\ydoclistingssettings{\lstset{style=lua-doc}}\setcounter{lstnumber}{1}
+% Identification of the Lua module.
+% \begin{macrocode}
+if luatexbase then
+ luatexbase.provides_module({
+ name = "pgfmolbio",
+ version = 0.2,
+ date = "2012/10/01",
+ description = "Molecular biology graphs wit LuaLaTeX",
+ author = "Wolfgang Skala",
+ copyright = "Wolfgang Skala",
+ license = "LPPL",
+ })
+end
+
+% \end{macrocode}
+% §setCoordinateFormat§ sets the output format of §dimToString§ (see below). Both its parameters §unit§ and §fmtString§ are strings, which correspond to the values of \opt{coordinate unit} and \opt{coordinate format string}.
+% \begin{macrocode}
+local coordUnit, coordFmtStr
+
+function setCoordinateFormat(unit, fmtString)
+ coordUnit = unit
+ coordFmtStr = fmtString
+end
+
+% \end{macrocode}
+% §stringToDim§ converts a string describing a \TeX\ dimension to a number corresponding to scaled points. §dimToString§ converts a dimension in scaled points to a string, formatting it according to the values of the local variables §coordUnit§ and §coordFmtString§.
+% \begin{macrocode}
+function stringToDim(x)
+ if type(x) == "string" then
+ return dimen(x)[1]
+ end
+end
+
+function dimToString(x)
+ return number.todimen(x, coordUnit, coordFmtStr)
+end
+
+% \end{macrocode}
+% §getRange§ extracts a variable number of strings from §rangeInput§ by applying the regular expressions in the table §matchStrings§, which derives from the varargs. §rangeInput§ contains the values of any of the \opt{... range} keys.
+% \begin{macrocode}
+function getRange(rangeInput, ...)
+ if type(rangeInput) ~= "string" then return end
+ local result = {}
+ local matchStrings = table.pack(...)
+ for i = 1, matchStrings.n do
+ if type(matchStrings[i]) == "string" then
+ table.insert(result, rangeInput:match(matchStrings[i]))
+ end
+ end
+ return unpack(result)
+end
+
+% \end{macrocode}
+% §packageWarning§ and §packageError§ throw \TeX\ warnings and errors, respectively. §packageError§ also sets the global variable §errorCatched§ to §true§. Some Lua functions check the value of this variable and terminate if an error has occurred.
+% \begin{macrocode}
+function packageWarning(message)
+ tex.sprint("\\PackageWarning{pgfmolbio}{" .. message .. "}")
+end
+
+function packageError(message)
+ tex.error("Package pgfmolbio Error: " .. message)
+ errorCatched = true
+end
+
+errorCatched = false
+
+% \end{macrocode}
+% We extend the §string§ table by the function §string.trim§, which removes leading and trailing spaces.
+% \begin{macrocode}
+if not string.trim then
+ string.trim = function(self)
+ return self:match("^%s*(.-)%s*$")
+ end
+end
+
+% \end{macrocode}
+% §outputFileId§ is a counter to enumerate several output files by the \module{convert} module.
+% \begin{macrocode}
+outputFileId = 0
+% \end{macrocode}
+% \iffalse
+%</pgfmolbio-lua>
+%<*pmb-chr-tex>
+% \fi
+%
+% \section{\texorpdfstring{\file{pgfmolbio.chromatogram.tex}}{pgfmolbio.chromatogram.tex}}
+% \label{sec:DocChrTex}
+%
+% \def\ydoclistingssettings{\lstset{style=latex-doc}}\setcounter{lstnumber}{1}
+% Since the Lua script of the \module{chromatogram} module does the bulk of the work, we can keep the \TeX\ file relatively short.
+%
+% \begin{macrocode}
+\ifluatex
+ \RequireLuaModule{pgfmolbio.chromatogram}
+\fi
+
+% \end{macrocode}
+% We define five custom colors for the traces and probability indicators (see Table~\ref{tab:pmbColors}).
+% \begin{macrocode}
+\definecolor{pmbTraceGreen}{RGB}{34,114,46}
+\definecolor{pmbTraceBlue}{RGB}{48,37,199}
+\definecolor{pmbTraceBlack}{RGB}{0,0,0}
+\definecolor{pmbTraceRed}{RGB}{191,27,27}
+\definecolor{pmbTraceYellow}{RGB}{233,230,0}
+
+% \end{macrocode}
+% \begin{macro}{\@pmb@chr@keydef}[2]{\meta{key} name}{default \meta{value}}
+% Most of the keys simply store their value. |\@pmb@chr@keydef| simplifies the declaration of such keys by calling |\pgfkeyssetvalue| with the appropriate path, \meta{key} and \meta{value}.
+% \begin{macrocode}
+\def\@pmb@chr@keydef#1#2{%
+ \pgfkeyssetvalue{/pgfmolbio/chromatogram/#1}{#2}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@pmb@chr@stylekeydef}[2]{\meta{key} name}{default \meta{value}}
+% This macro initializes a style \meta{key} with a \meta{value}.
+% \begin{macrocode}
+\def\@pmb@chr@stylekeydef#1#2{%
+ \pgfkeys{/pgfmolbio/chromatogram/#1/.style={#2}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@pmb@chr@getkey}[1]{\meta{key} name}
+% |\@pmb@chr@getkey| retrieves the value stored by the \meta{key}.
+% \begin{macrocode}
+\def\@pmb@chr@getkey#1{%
+ \pgfkeysvalueof{/pgfmolbio/chromatogram/#1}%
+}
+
+% \end{macrocode}
+% \end{macro}
+% After providing these auxiliary macros, we define all keys of the \module{chromatogram} module.
+% \begin{macrocode}
+\@pmb@chr@keydef{sample range}{1-500 step 1}
+
+\@pmb@chr@keydef{x unit}{0.2mm}
+\@pmb@chr@keydef{y unit}{0.01mm}
+\@pmb@chr@keydef{samples per line}{500}
+\@pmb@chr@keydef{baseline skip}{3cm}
+\@pmb@chr@stylekeydef{canvas style}{draw=none, fill=none}
+\@pmb@chr@keydef{canvas height}{2cm}
+
+\@pmb@chr@stylekeydef{trace A style}{pmbTraceGreen}
+\@pmb@chr@stylekeydef{trace C style}{pmbTraceBlue}
+\@pmb@chr@stylekeydef{trace G style}{pmbTraceBlack}
+\@pmb@chr@stylekeydef{trace T style}{pmbTraceRed}
+\pgfmolbioset[chromatogram]{%
+ trace style/.code=\pgfkeysalso{
+ trace A style/.style={#1},
+ trace C style/.style={#1},
+ trace G style/.style={#1},
+ trace T style/.style={#1}
+ }%
+}
+\@pmb@chr@keydef{traces drawn}{}
+
+\@pmb@chr@stylekeydef{tick A style}{thin, pmbTraceGreen}
+\@pmb@chr@stylekeydef{tick C style}{thin, pmbTraceBlue}
+\@pmb@chr@stylekeydef{tick G style}{thin, pmbTraceBlack}
+\@pmb@chr@stylekeydef{tick T style}{thin, pmbTraceRed}
+\pgfmolbioset[chromatogram]{%
+ tick style/.code=\pgfkeysalso{
+ tick A style/.style={#1},
+ tick C style/.style={#1},
+ tick G style/.style={#1},
+ tick T style/.style={#1}
+ }%
+}
+\@pmb@chr@keydef{tick length}{1mm}
+\@pmb@chr@keydef{ticks drawn}{}
+
+\@pmb@chr@keydef{base label A text}{\strut A}
+\@pmb@chr@keydef{base label C text}{\strut C}
+\@pmb@chr@keydef{base label G text}{\strut G}
+\@pmb@chr@keydef{base label T text}{\strut T}
+\@pmb@chr@stylekeydef{base label A style}%
+ {below=4pt, font=\ttfamily\footnotesize, pmbTraceGreen}
+\@pmb@chr@stylekeydef{base label C style}%
+ {below=4pt, font=\ttfamily\footnotesize, pmbTraceBlue}
+\@pmb@chr@stylekeydef{base label G style}%
+ {below=4pt, font=\ttfamily\footnotesize, pmbTraceBlack}
+\@pmb@chr@stylekeydef{base label T style}%
+ {below=4pt, font=\ttfamily\footnotesize, pmbTraceRed}
+\pgfmolbioset[chromatogram]{%
+ base label style/.code=\pgfkeysalso{
+ base label A style/.style={#1},
+ base label C style/.style={#1},
+ base label G style/.style={#1},
+ base label T style/.style={#1}
+ }%
+}
+\@pmb@chr@keydef{base labels drawn}{}
+
+\newif\ifpmb@chr@showbasenumbers
+\pgfmolbioset[chromatogram]{%
+ show base numbers/.is if=pmb@chr@showbasenumbers,
+ show base numbers
+}
+\@pmb@chr@stylekeydef{base number style}%
+ {pmbTraceBlack, below=-3pt, font=\sffamily\tiny}
+\@pmb@chr@keydef{base number range}{auto-auto step 10}
+
+\@pmb@chr@keydef{probability distance}{0.8cm}
+\@pmb@chr@keydef{probabilities drawn}{}
+\@pmb@chr@keydef{probability style function}{nil}
+
+\pgfmolbioset[chromatogram]{
+ bases drawn/.code=\pgfkeysalso{
+ traces drawn=#1,
+ ticks drawn=#1,
+ base labels drawn=#1,
+ probabilities drawn=#1
+ },
+ bases drawn=ACGT
+}
+
+% \end{macrocode}
+% If \pkg{pgfmolbio} is used with a \TeX\ engine that does not support Lua, the package ends here.
+% \begin{macrocode}
+\ifluatex\else\expandafter\endinput\fi
+
+% \end{macrocode}
+% \begin{macro}{\pmbchromatogram}[2]{A \ometa{key-value list} that configures the chromatogram.}{The name of an \meta{scf file}.}
+% If |\pmbchromatogram| appears outside of a |tikzpicture|, we implicitly start this environment, otherwise we begin a new group. ``Within a |tikzpicture|'' means that |\useasboundingbox| is defined.
+% \begin{macrocode}
+\newif\ifpmb@chr@tikzpicture
+
+\newcommand\pmbchromatogram[2][]{%
+ \@ifundefined{useasboundingbox}%
+ {\pmb@chr@tikzpicturefalse\begin{tikzpicture}}%
+ {\pmb@chr@tikzpicturetrue\begingroup}%
+% \end{macrocode}
+% Of course, we consider the \ometa{key-value list} before drawing the chromatogram.
+% \begin{macrocode}
+ \pgfmolbioset[chromatogram]{#1}%
+% \end{macrocode}
+% We generate a new §Chromatogram§ object and invoke several Lua functions: (1) §readScfFile§ reads the given \meta{scf file} (section~\ref{ssc:DocChrLuaReadScfFile}). (2) §setParameters§ passes the values stored by the keys to the Lua script. Note that this function is called twice, since §baseNumberRange§ requires that §sampleRange§ has been already set, and the implementation of §setParameters§ does not ensure this (section~\ref{ssc:DocChrLuaSetParameters}). (3) §pgfmolbio.setCoordinateFormat§ sets the coordinate output format (section~\ref{sec:DocPkgLua}).
+% \begin{macrocode}
+ \directlua{
+ pmbChromatogram = pgfmolbio.chromatogram.Chromatogram:new()
+ pmbChromatogram:readScfFile("#2")
+ pmbChromatogram:setParameters{
+ sampleRange = "\@pmb@chr@getkey{sample range}",
+ xUnit = "\@pmb@chr@getkey{x unit}",
+ yUnit = "\@pmb@chr@getkey{y unit}",
+ samplesPerLine = "\@pmb@chr@getkey{samples per line}",
+ baselineSkip = "\@pmb@chr@getkey{baseline skip}",
+ canvasHeight = "\@pmb@chr@getkey{canvas height}",
+ tracesDrawn = "\@pmb@chr@getkey{traces drawn}",
+ tickLength = "\@pmb@chr@getkey{tick length}",
+ ticksDrawn = "\@pmb@chr@getkey{ticks drawn}",
+ baseLabelsDrawn = "\@pmb@chr@getkey{base labels drawn}",
+ showBaseNumbers = "\ifpmb@chr@showbasenumbers true\else false\fi",
+ probDistance = "\@pmb@chr@getkey{probability distance}",
+ probabilitiesDrawn = "\@pmb@chr@getkey{probabilities drawn}",
+ probStyle = \@pmb@chr@getkey{probability style function}
+ }
+ pmbChromatogram:setParameters{
+ baseNumberRange = "\@pmb@chr@getkey{base number range}",
+ }
+ pgfmolbio.setCoordinateFormat(
+ "\pgfkeysvalueof{/pgfmolbio/coordinate unit}",
+ "\pgfkeysvalueof{/pgfmolbio/coordinate format string}"
+ )
+% \end{macrocode}
+% If the \module{convert} module is loaded, we open the appropriate output file, change §tex.sprint§ so that the function writes to this file and then call §printTikzChromatogram§. Without the \module{convert} module, §printTikzChromatogram§ simply returns the drawing commands for the chromatogram to the \TeX\ input stream (section~\ref{ssc:DocChrLuaPrint}).
+% \begin{macrocode}
+ \ifpmb@loadmodule@convert
+ local filename =
+ "\pgfkeysvalueof{/pgfmolbio/convert/output file name}"
+ if filename == "(auto)" then
+ filename = "pmbconverted" .. pgfmolbio.outputFileId
+ end
+ filename = filename ..
+ ".\pgfkeysvalueof{/pgfmolbio/convert/output file extension}"
+ outputFile, ioError = io.open(filename, "w")
+ if ioError then
+ tex.error(ioError)
+ end
+ tex.sprint = function (a) outputFile:write(a) end
+ tex.sprint("\string\\begin{tikzpicture}")
+ pmbChromatogram:printTikzChromatogram()
+ tex.sprint("\string\n\string\\end{tikzpicture}")
+ outputFile:close()
+ pgfmolbio.outputFileId = pgfmolbio.outputFileId + 1
+ \else
+ pmbChromatogram:printTikzChromatogram()
+ \fi
+ }%
+% \end{macrocode}
+% At the end of |\pmbchromatogram|, we either close the |tikzpicture| or the group, depending on how we started.
+% \begin{macrocode}
+ \ifpmb@chr@tikzpicture\endgroup\else\end{tikzpicture}\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \iffalse
+%</pmb-chr-tex>
+%<*pmb-chr-lua>
+% \fi
+%
+% \section{\texorpdfstring{\file{pgfmolbio.chromatogram.lua}}{pgfmolbio.chromatogram.lua}}
+% \label{sec:DocChrLua}
+%
+% \def\ydoclistingssettings{\lstset{style=lua-doc}}\setcounter{lstnumber}{1}
+% This Lua script is the true workhorse of the \module{chromatogram} module. Remember that the documentation for the Staden package\footnote{\url{http://staden.sourceforge.net/}} is the definite source for information on the \file{scf} file format.
+% \begin{macrocode}
+if luatexbase then
+ luatexbase.provides_module{
+ name = "pgfmolbio.chromatogram",
+ version = 0.2,
+ date = "2012/10/01",
+ description = "DNA sequencing chromatograms",
+ author = "Wolfgang Skala",
+ copyright = "Wolfgang Skala",
+ license = "LPPL",
+ }
+end
+
+% \end{macrocode}
+%
+% \subsection{Module-Wide Variables and Auxiliary Functions}
+% \label{ssc:DocChrLuaAuxiliaryFunctions}
+%
+% \begin{itemize}
+% \item §ALL_BASES§: A table of four indexed string fields, which represent the nucleotide single-letter abbreviations.
+% \item §PGFKEYS_PATH§: A string that contains the \pkg{pgfkeys} path for \module{chromatogram} keys.
+% \end{itemize}
+% \begin{macrocode}
+local ALL_BASES = {"A", "C", "G", "T"}
+local PGFKEYS_PATH = "/pgfmolbio/chromatogram/"
+
+% \end{macrocode}
+% These local functions point to functions in \file{pgfmolbio.lua} (section~\ref{sec:DocPkgLua}).
+% \begin{macrocode}
+local stringToDim = pgfmolbio.stringToDim
+local dimToString = pgfmolbio.dimToString
+local packageError = pgfmolbio.packageError
+local packageWarning = pgfmolbio.packageWarning
+local getRange = pgfmolbio.getRange
+
+% \end{macrocode}
+% §stdProbStyle§ is the default \opt{probability style function}. It returns a string representing an optional argument of |\draw|. Depending on the value of §prob§, the probability rule thus drawn is colored black, red, yellow or green for quality scores $< 10$, $< 20$, $< 30$ or $\geq 30$, respectively (see also section~\ref{sec:ChrProbabilities}).
+% \begin{macrocode}
+local function stdProbStyle(prob)
+ local color = ""
+ if prob >= 0 and prob < 10 then
+ color = "black"
+ elseif prob >= 10 and prob < 20 then
+ color = "pmbTraceRed"
+ elseif prob >= 20 and prob < 30 then
+ color = "pmbTraceYellow"
+ else
+ color = "pmbTraceGreen"
+ end
+ return "ultra thick, " .. color
+end
+
+% \end{macrocode}
+% §findBasesInStr§ searches for nucleotide single-letter abbreviations in its string argument. It returns a table of zero to four indexed string fields (one field per character found, which contains that letter).
+% \begin{macrocode}
+local function findBasesInStr(target)
+ if not target then return end
+ local result = {}
+ for _, v in ipairs(ALL_BASES) do
+ if target:upper():find(v) then
+ table.insert(result, v)
+ end
+ end
+ return result
+end
+
+% \end{macrocode}
+% §readInt§ reads §n§ bytes from a §file§, starting at §offset§ or at the current position if §offset§ is §nil§. By assuming big-endian byte order, the byte sequence is converted to a number and returned.
+% \begin{macrocode}
+local function readInt(file, n, offset)
+ if offset then file:seek("set", offset) end
+ local result = 0
+ for i = 1, n do
+ result = result * 0x100 + file:read(1):byte()
+ end
+ return result
+end
+
+% \end{macrocode}
+%
+% \subsection{The \texorpdfstring{\texttt{Chromatogram}}{Chromatogram} Class}
+% \label{ssc:DocChrLuaClass}
+%
+% The §Chromatogram§ class (table) represents a single \file{scf} chromatogram. The constructor §Chromatogram:new§ returns a new instance and initializes its variables, which store the values of \module{chromatogram} keys. Most variables are self-explanatory, since their name is similar to their corresponding key.
+% \begin{macrocode}
+Chromatogram = {}
+
+function Chromatogram:new()
+ newChromatogram = {
+ sampleMin = 1,
+ sampleMax = 500,
+ sampleStep = 1,
+ peakMin = -1,
+ peakMax = -1,
+ xUnit = stringToDim("0.2mm"),
+ yUnit = stringToDim("0.01mm"),
+ samplesPerLine = 500,
+ baselineSkip = stringToDim("3cm"),
+ canvasHeight = stringToDim("2cm"),
+ traceStyle = {
+ A = PGFKEYS_PATH .. "trace A style",
+ C = PGFKEYS_PATH .. "trace C style",
+ G = PGFKEYS_PATH .. "trace G style",
+ T = PGFKEYS_PATH .. "trace T style"
+ },
+ tickStyle = {
+ A = PGFKEYS_PATH .. "tick A style",
+ C = PGFKEYS_PATH .. "tick C style",
+ G = PGFKEYS_PATH .. "tick G style",
+ T = PGFKEYS_PATH .. "tick T style"
+ },
+ tickLength = stringToDim("1mm"),
+ baseLabelText = {
+ A = "\\pgfkeysvalueof{" .. PGFKEYS_PATH .. "base label A text}",
+ C = "\\pgfkeysvalueof{" .. PGFKEYS_PATH .. "base label C text}",
+ G = "\\pgfkeysvalueof{" .. PGFKEYS_PATH .. "base label G text}",
+ T = "\\pgfkeysvalueof{" .. PGFKEYS_PATH .. "base label T text}"
+ },
+ baseLabelStyle = {
+ A = PGFKEYS_PATH .. "base label A style",
+ C = PGFKEYS_PATH .. "base label C style",
+ G = PGFKEYS_PATH .. "base label G style",
+ T = PGFKEYS_PATH .. "base label T style"
+ },
+ showBaseNumbers = true,
+ baseNumberMin = -1,
+ baseNumberMax = -1,
+ baseNumberStep = 10,
+ probDistance = stringToDim("0.8cm"),
+ probStyle = stdProbStyle,
+ tracesDrawn = ALL_BASES,
+ ticksDrawn = "ACGT",
+ baseLabelsDrawn = "ACGT",
+ probabilitiesDrawn = "ACGT",
+ }
+ setmetatable(newChromatogram, self)
+ self.__index = self
+ return newChromatogram
+end
+
+% \end{macrocode}
+% §getMinMaxProbability§ returns the minimum and maximum probability value in the current chromatogram.
+% \begin{macrocode}
+function Chromatogram:getMinMaxProbability()
+ local minProb = 0
+ local maxProb = 0
+ for _, currPeak in ipairs(self.selectedPeaks) do
+ for __, currProb in pairs(currPeak.prob) do
+ if currProb > maxProb then maxProb = currProb end
+ if currProb < minProb then minProb = currProb end
+ end
+ end
+ return minProb, maxProb
+end
+
+% \end{macrocode}
+% §getSampleAndPeakIndex§ returns the sample (§sampleId§) and peak index (§peakId§) that correspond to §baseIndex§. If §baseIndex§ is a number, the function simply returns it as sample index. However, if §baseIndex§ is a string of the form §"base§ \meta{number}§"§ (as in a valid value for the \opt{sample range} key), the function returns the offset of the \meta{number}-th peak. §isLowerLimit§ must be §true§ if the function should return the indices of the lower end of a range.
+% \begin{macrocode}
+function Chromatogram:getSampleAndPeakIndex(baseIndex, isLowerLimit)
+ local sampleId, peakId
+
+ sampleId = tonumber(baseIndex)
+ if sampleId then
+ for i, v in ipairs(self.peaks) do
+ if isLowerLimit then
+ if v.offset >= sampleId then
+ peakId = i
+ break
+ end
+ else
+ if v.offset == sampleId then
+ peakId = i
+ break
+ elseif v.offset > sampleId then
+ peakId = i - 1
+ break
+ end
+ end
+ end
+ else
+ peakId = tonumber(baseIndex:match("base%s*(%d+)"))
+ if peakId then
+ sampleId = self.peaks[peakId].offset
+ end
+ end
+ return sampleId, peakId
+end
+
+% \end{macrocode}
+%
+% \subsection{Read the \texorpdfstring{\file{scf}}{scf} File}
+% \label{ssc:DocChrLuaReadScfFile}
+%
+% §Chromatogram:readScfFile§ introduces three further fields to §Chromatogram§:
+% \begin{itemize}
+% \item §header§: A table of 14 named number fields that save the information in the \file{scf} header.
+% \item §samples§: A table of four named subtables §A§, §C§, §G§, §T§. Each subtable contains §header.samplesNumber§ indexed number fields that represent the fluorescence intensities along a trace.
+% \item §peaks§: A table of §header.basesNumber§ indexed subtables which in turn contain three named fields:
+% \begin{itemize}
+% \item §offset§: A number indicating the offset of the current peak.
+% \item §prob§: A table of four named number fields §A§, §C§, §G§, §T§. These numbers store the probability that the current peak is one of the four bases.
+% \item §base§: A string that states the base represented by the current peak.
+% \end{itemize}
+% \end{itemize}
+%
+% §Chromatogram:readScfFile§ checks whether the requested \file{scf} file ``§filename§'' corresponds to the most recently opened one (via §lastScfFile§). In this case, the variables §peaks§ and §samples§ already contain the relevant data, so we can refrain from re-reading the file. Otherwise, the program tries to open and evaluate the specified file, raising an error on failure.
+% \begin{macrocode}
+function Chromatogram:readScfFile(filename)
+ if filename ~= self.lastScfFile then
+ self.lastScfFile = filename
+ local scfFile, errorMsg = io.open(filename, "rb")
+ if not scfFile then packageError(errorMsg) end
+
+ self.samples = {A = {}, C = {}, G = {}, T = {}}
+ self.peaks = {}
+% \end{macrocode}
+% The function collects the relevant data from the file. \textit{Firstly}, §header§ saves the information in the file header:
+% \begin{itemize}
+% \item §magicNumber§: Each \file{scf} file must start with the four bytes §2E736366§, which is the string ``§.scf§''. If this sequence is absent, the \module{chromatogram} module raises an error.
+% \item §samplesNumber§: The number of sample points.
+% \item §samplesOffset§: The offset of the sample data start.
+% \item §basesNumber§: The number of recognized bases.
+% \item §version§: Since the \module{chromatogram} module currently only supports \file{scf} version 3.00 (the string ``§3.00§'' equals §332E3030§), \TeX\ stops with an error message if the file version is different.
+% \item §sampleSize§: The size of each sample point in bytes.
+% \end{itemize}
+% \begin{macrocode}
+ self.header = {
+ magicNumber = readInt(scfFile, 4, 0),
+ samplesNumber = readInt(scfFile, 4),
+ samplesOffset = readInt(scfFile, 4),
+ basesNumber = readInt(scfFile, 4),
+ leftClip = readInt(scfFile, 4),
+ rightClip = readInt(scfFile, 4),
+ basesOffset = readInt(scfFile, 4),
+ comments = readInt(scfFile, 4),
+ commentsOffset = readInt(scfFile, 4),
+ version = readInt(scfFile, 4),
+ sampleSize = readInt(scfFile, 4),
+ codeSet = readInt(scfFile, 4),
+ privateSize = readInt(scfFile, 4),
+ privateOffset = readInt(scfFile, 4)
+ }
+ if self.header.magicNumber ~= 0x2E736366 then
+ packageError(
+ "Magic number in scf scfFile '" ..
+ self.lastScfFile ..
+ "' corrupt!"
+ )
+ end
+ if self.header.version ~= 0x332E3030 then
+ packageError(
+ "Scf scfFile '" ..
+ self.lastScfFile ..
+ "' is not version 3.00!"
+ )
+ end
+% \end{macrocode}
+% \textit{Secondly}, §samples§ receives the samples data from the file. Note that the values of the sample points are stored as unsigned integers representing second derivatives (i.\,e., differences between differences between two consecutive sample points). Hence, we convert them back to signed, absolute values.
+% \begin{macrocode}
+ scfFile:seek("set", self.header.samplesOffset)
+ for baseIndex, baseName in ipairs(ALL_BASES) do
+ for i = 1, self.header.samplesNumber do
+ self.samples[baseName][i] =
+ readInt(scfFile, self.header.sampleSize)
+ end
+
+ for _ = 1, 2 do
+ local preValue = 0
+ for i = 1, self.header.samplesNumber do
+ self.samples[baseName][i] = self.samples[baseName][i] + preValue
+ if self.samples[baseName][i] > 0xFFFF then
+ self.samples[baseName][i] = self.samples[baseName][i] - 0x10000
+ end
+ preValue = self.samples[baseName][i]
+ end
+ end
+ end
+% \end{macrocode}
+% \textit{Finally}, we store the peak information in §peaks§.
+% \begin{macrocode}
+ for i = 1, self.header.basesNumber do
+ self.peaks[i] = {
+ offset = readInt(scfFile, 4),
+ prob = {A, C, G, T},
+ base
+ }
+ end
+
+ for i = 1, self.header.basesNumber do
+ self.peaks[i].prob.A = readInt(scfFile, 1)
+ end
+
+ for i = 1, self.header.basesNumber do
+ self.peaks[i].prob.C = readInt(scfFile, 1)
+ end
+
+ for i = 1, self.header.basesNumber do
+ self.peaks[i].prob.G = readInt(scfFile, 1)
+ end
+
+ for i = 1, self.header.basesNumber do
+ self.peaks[i].prob.T = readInt(scfFile, 1)
+ end
+
+ for i = 1, self.header.basesNumber do
+ self.peaks[i].base = string.char(readInt(scfFile, 1))
+ end
+
+ scfFile:close()
+ end
+end
+
+% \end{macrocode}
+%
+% \subsection{Set Chromatogram Parameters}
+% \label{ssc:DocChrLuaSetParameters}
+%
+% §Chromatogram:setParameters§ passes options from the \module{chromatogram} module to the Lua script. Each field of the table §keyHash§ is named after a §Chromatogram§ attribute and represents a function that receives one string parameter (the value of a \LaTeX\ key). For instance, §keyHash.sampleRange§ extracts the range and step values from the value stored in the \opt{sample range} key.
+% \begin{macrocode}
+function Chromatogram:setParameters(newParms)
+ local keyHash = {
+ sampleRange = function(v)
+ local sampleRangeMin, sampleRangeMax, sampleRangeStep =
+ getRange(
+ v:trim(),
+ "^([base]*%s*%d+)%s*%-",
+ "%-%s*([base]*%s*%d+)",
+ "step%s*(%d+)$"
+ )
+ self.sampleMin, self.peakMin =
+ self:getSampleAndPeakIndex(sampleRangeMin, true)
+ self.sampleMax, self.peakMax =
+ self:getSampleAndPeakIndex(sampleRangeMax, false)
+ if self.sampleMin >= self.sampleMax then
+ packageError("Sample range is smaller than 1.")
+ end
+ self.sampleStep = sampleRangeStep or self.sampleStep
+ end,
+ xUnit = stringToDim,
+ yUnit = stringToDim,
+ samplesPerLine = tonumber,
+ baselineSkip = stringToDim,
+ canvasHeight = stringToDim,
+ tickLength = stringToDim,
+ showBaseNumbers = function(v)
+ if v == "true" then return true else return false end
+ end,
+ baseNumberRange = function(v)
+ local baseNumberRangeMin, baseNumberRangeMax, baseNumberRangeStep =
+ getRange(
+ v:trim(),
+ "^([auto%d]*)%s+%-",
+ "%-%s+([auto%d]*$)"
+ )
+ if tonumber(baseNumberRangeMin) then
+ self.baseNumberMin = tonumber(baseNumberRangeMin)
+ else
+ self.baseNumberMin = self.peakMin
+ end
+ if tonumber(baseNumberRangeMax) then
+ self.baseNumberMax = tonumber(baseNumberRangeMax)
+ else
+ self.baseNumberMax = self.peakMax
+ end
+ if self.baseNumberMin >= self.baseNumberMax then
+ packageError("Base number range is smaller than 1.")
+ end
+ if self.baseNumberMin < self.peakMin then
+ self.baseNumberMin = self.peakMin
+ packageWarning("Lower base number range is smaller than lower sample range. It was adjusted to " .. self.baseNumberMin .. ".")
+ end
+ if self.baseNumberMax > self.peakMax then
+ self.baseNumberMax = self.peakMax
+ packageWarning("Upper base number range exceeds upper sample range. It was adjusted to " .. self.baseNumberMax .. ".")
+ end
+ self.baseNumberStep = tonumber(baseNumberRangeStep)
+ or self.baseNumberStep
+ end,
+ probDistance = stringToDim,
+ probStyle = function(v) return v end,
+ tracesDrawn = findBasesInStr,
+ ticksDrawn = function(v) return v end,
+ baseLabelsDrawn = function(v) return v end,
+ probabilitiesDrawn = function(v) return v end,
+ probStyle = function(v) return v end
+ }
+% \end{macrocode}
+% We iterate over all fields in the argument of §setParameters§. If a field of the same name exists in §keyHash§, we call this field with the value of the corresponding field in §newParms§ as parameter.
+% \begin{macrocode}
+ for key, value in pairs(newParms) do
+ if keyHash[key] then
+ self[key] = keyHash[key](value)
+ end
+ end
+end
+
+% \end{macrocode}
+%
+% \subsection{Print the Chromatogram}
+% \label{ssc:DocChrLuaPrint}
+%
+% §Chromatogram:printTikzChromatogram§ writes all commands that draw the chromatogram to the \TeX\ input stream (via §tex.sprint§), but only if no error has occurred previously.
+% \begin{macrocode}
+function Chromatogram:printTikzChromatogram()
+ if pgfmolbio.errorCatched then return end
+% \end{macrocode}
+% \paragraph{(1) Select peaks to draw} In order to simplify the drawing operations, we select the peaks that appear in the final output and store information on them in §selectedPeaks§. §selectedPeaks§ is a table of zero to §header.basesNumber§ indexed subtables. It is similar to §peaks§ but only describes the peaks in the displayed part of the chromatogram, which is selected by the \opt{samples range} key. Each subtable of §selectedPeaks§ consists of the following five named fields:
+% \begin{itemize}
+% \item §offset§: A number indicating the offset of the current peak in ``transformed'' coordinates (i.\,e., the $x$-coordinate of the first sample point shown equals 1).
+% \item §base§: See §peaks.base§ (section~\ref{ssc:DocChrLuaReadScfFile}).
+% \item §prob§: See §peaks.prob§ (section~\ref{ssc:DocChrLuaReadScfFile}).
+% \item §baseIndex§: A number that stores the index of the current peak. The first detected peak in the chromatogram has index~1.
+% \item §probXRight§: A number corresponding to the right $x$-coordinate of the probability indicator.
+% \end{itemize}
+% \begin{macrocode}
+ self.selectedPeaks = {}
+ local tIndex = 1
+ for rPeakIndex, currPeak in ipairs(self.peaks) do
+ if currPeak.offset >= self.sampleMin
+ and currPeak.offset <= self.sampleMax then
+ self.selectedPeaks[tIndex] = {
+ offset = currPeak.offset + 1 - self.sampleMin,
+ base = currPeak.base,
+ prob = currPeak.prob,
+ baseIndex = rPeakIndex,
+ probXRight = self.sampleMax + 1 - self.sampleMin
+ }
+% \end{macrocode}
+% The right $x$-coordinate of the probability indicator (§probXRight§) is the mean between the offsets of the adjacent peaks. For the last peak, §probXRight§ equals the largest transformed $x$-coordinate.
+% \begin{macrocode}
+ if tIndex > 1 then
+ self.selectedPeaks[tIndex-1].probXRight =
+ (self.selectedPeaks[tIndex-1].offset
+ + self.selectedPeaks[tIndex].offset) / 2
+ end
+ tIndex = tIndex + 1
+ end
+ end
+
+% \end{macrocode}
+% Furthermore, we adjust §baseNumberMin§ and §baseNumberMax§ if any peak was detected in the displayed part of the chromatogram. The value §-1§, which indicates the keyword |auto|, is replaced by the index of the first or last peak, respectively.
+% \begin{macrocode}
+ if tIndex > 1 then
+ if self.baseNumberMin == -1 then
+ self.baseNumberMin = self.selectedPeaks[1].baseIndex
+ end
+ if self.baseNumberMax == -1 then
+ self.baseNumberMax = self.selectedPeaks[tIndex-1].baseIndex
+ end
+ end
+
+% \end{macrocode}
+% \paragraph{(2) Canvas} For each line, we draw a rectangle in \opt{canvas style} whose left border coincides with the $y$-axis.\\
+% §yLower§, §yUpper§, §xRight§: rectangle coordinates;\\
+% §currLine§: current line, starting from 0;\\
+% §samplesLeft§: sample points left to draw after the end of the current line.
+% \begin{macrocode}
+ local samplesLeft = self.sampleMax - self.sampleMin + 1
+ local currLine = 0
+ while samplesLeft > 0 do
+ local yLower = -currLine * self.baselineSkip
+ local yUpper = -currLine * self.baselineSkip + self.canvasHeight
+ local xRight =
+ (math.min(self.samplesPerLine, samplesLeft) - 1) * self.xUnit
+ tex.sprint(
+ "\n\t\\draw [" .. PGFKEYS_PATH .. "canvas style] (" ..
+ dimToString(0) ..
+ ", " ..
+ dimToString(yLower) ..
+ ") rectangle (" ..
+ dimToString(xRight) ..
+ ", " ..
+ dimToString(yUpper) ..
+ ");"
+ )
+ samplesLeft = samplesLeft - self.samplesPerLine
+ currLine = currLine + 1
+ end
+
+% \end{macrocode}
+% \paragraph{(3) Traces} The traces in §tracesDrawn§ are drawn sequentially.\\
+% §currSampleIndex§: original $x$-coordinate of a sample point;\\
+% §sampleX§: transformed $x$-coordinate of a sample point, starting at 1;\\
+% §x§ and §y§: ``real'' coordinates (in scaled points) of a sample point;\\
+% §currLine§: current line, starting at 0;\\
+% §firstPointInLine§: boolean that indicates if the current sample point is the first in the line.
+% \begin{macrocode}
+ for _, baseName in ipairs(self.tracesDrawn) do
+ tex.sprint("\n\t\\draw [" .. self.traceStyle[baseName] .. "] ")
+ local currSampleIndex = self.sampleMin
+ local sampleX = 1
+ local x = 0
+ local y = 0
+ local currLine = 0
+ local firstPointInLine = true
+
+% \end{macrocode}
+% We iterate over each sample point. As long as the current sample point is within the selected range, we calculate the real coordinates of the sample point; add the lineto operator |--| if at least one sample point has already appeared in the current line; and write the point to the \TeX\ input stream.
+% \begin{macrocode}
+ while currSampleIndex <= self.sampleMax do
+ x = ((sampleX - 1) % self.samplesPerLine) * self.xUnit
+ y = self.samples[baseName][currSampleIndex] * self.yUnit
+ - currLine * self.baselineSkip
+ if sampleX % self.sampleStep == 0 then
+ if not firstPointInLine then
+ tex.sprint(" -- ")
+ else
+ firstPointInLine = false
+ end
+ tex.sprint(
+ "(" ..
+ dimToString(x) ..
+ ", " ..
+ dimToString(y) ..
+ ")"
+ )
+ end
+% \end{macrocode}
+% Besides, we add line breaks at the appropriate positions.
+% \begin{macrocode}
+ if sampleX ~= self.sampleMax + 1 - self.sampleMin then
+ if sampleX >= (currLine + 1) * self.samplesPerLine then
+ currLine = currLine + 1
+ tex.sprint(";\n\t\\draw [" .. self.traceStyle[baseName] .. "] ")
+ firstPointInLine = true
+ end
+ else
+ tex.sprint(";")
+ end
+ sampleX = sampleX + 1
+ currSampleIndex = currSampleIndex + 1
+ end
+ end
+
+% \end{macrocode}
+% \paragraph{(4) Annotations} We iterate over each selected peak and start by finding the line in which the first peak resides.\\
+% §currLine§: current line, starting at 0;\\
+% §lastProbX§: right $x$-coordinate of the probability rule of the last peak;\\
+% §probRemainder§: string that draws the remainder of a probability indicator following a line break;\\
+% §x§, §yUpper§, §yLower§: ``real'' tick coordinates;\\
+% §tickOperation§: string that equals either \TikZ's moveto or lineto operation, depending on whether the current peak should be marked with a tick.
+% \begin{macrocode}
+ local currLine = 0
+ local lastProbX = 1
+ local probRemainder = false
+
+ for _, currPeak in ipairs(self.selectedPeaks) do
+ while currPeak.offset > (currLine + 1) * self.samplesPerLine do
+ currLine = currLine + 1
+ end
+
+ local x = ((currPeak.offset - 1) % self.samplesPerLine) * self.xUnit
+ local yUpper = -currLine * self.baselineSkip
+ local yLower = -currLine * self.baselineSkip - self.tickLength
+ local tickOperation = ""
+ if self.ticksDrawn:upper():find(currPeak.base) then
+ tickOperation = "--"
+ end
+
+% \end{macrocode}
+% \paragraph{(4a) Ticks and labels} Having calculated all coordinates, we draw the tick and the base label, given the latter has been specified by \opt{base labels drawn}.
+% \begin{macrocode}
+ tex.sprint(
+ "\n\t\\draw [" ..
+ self.tickStyle[currPeak.base] ..
+ "] (" ..
+ dimToString(x) ..
+ ", " ..
+ dimToString(yUpper) ..
+ ") " ..
+ tickOperation ..
+ " (" ..
+ dimToString(x) ..
+ ", " ..
+ dimToString(yLower) ..
+ ")"
+ )
+ if self.baseLabelsDrawn:upper():find(currPeak.base) then
+ tex.sprint(
+ " node [" ..
+ self.baseLabelStyle[currPeak.base] ..
+ "] {" ..
+ self.baseLabelText[currPeak.base] ..
+ "}"
+ )
+ end
+
+% \end{macrocode}
+% \paragraph{(4b) Base numbers} If \opt{show base numbers} is true and the current base number is within the interval given by \opt{base number range}, a base number is printed.
+% \begin{macrocode}
+ if self.showBaseNumbers
+ and currPeak.baseIndex >= self.baseNumberMin
+ and currPeak.baseIndex <= self.baseNumberMax
+ and (currPeak.baseIndex - self.baseNumberMin)
+ % self.baseNumberStep == 0 then
+ tex.sprint(
+ " node [" ..
+ PGFKEYS_PATH ..
+ "base number style] {\\strut " ..
+ currPeak.baseIndex ..
+ "}"
+ )
+ end
+ tex.sprint(";")
+
+% \end{macrocode}
+% \paragraph{(4c) Probabilities} First, we draw the remainder of the last probability rule. Such a remainder has been stored in §probRemainder§ if the last rule had protruded into the right margin (see below). Furthermore, we determine if a probability rule should appear beneath the current peak.
+% \begin{macrocode}
+ if probRemainder then
+ tex.sprint(probRemainder)
+ probRemainder = false
+ end
+ local drawCurrProb =
+ self.probabilitiesDrawn:upper():find(currPeak.base)
+% \end{macrocode}
+% Now comes the tricky part. Whenever we choose to paint a probability rule, we may envision three scenarios. \textit{Firstly}, the probability rule starts in the left margin of the current line (i.\,e., §xLeft§ is negative). This means that the part protruding into the left margin must instead appear at the end of the last line. Therefore, we calculate the coordinates of this part (storing them in §xLeftPrev§, §xRightPrev§ and §yPrev§) and draw the segment. Since the remainder of the rule necessarily starts at the left border of the current line, we set §xLeft§ to zero.
+% \begin{macrocode}
+ local xLeft = lastProbX - 1 - currLine * self.samplesPerLine
+ if xLeft < 0 then
+ local xLeftPrev = (self.samplesPerLine + xLeft) * self.xUnit
+ local xRightPrev = (self.samplesPerLine - 1) * self.xUnit
+ local yPrev = -(currLine-1) * self.baselineSkip - self.probDistance
+ if drawCurrProb then
+ tex.sprint(
+ "\n\t\\draw [" ..
+ self.probStyle(currPeak.prob[currPeak.base]) ..
+ "] (" ..
+ dimToString(xLeftPrev) ..
+ ", " ..
+ dimToString(yPrev) ..
+ ") -- (" ..
+ dimToString(xRightPrev) ..
+ ", " ..
+ dimToString(yPrev) ..
+ ");"
+ )
+ end
+ xLeft = 0
+ else
+ xLeft = xLeft * self.xUnit
+ end
+
+% \end{macrocode}
+% \textit{Secondly}, the probability rule ends in the right margin of the current line (i.\,e., §xRight§ at least equals §samplesPerLine§). This means that the part protruding into the right margin must instead appear at the start of the following line. Therefore, we calculate the coordinates of this part (storing them in §xRightNext§ and §yNext§) and save the drawing command in §probRemainder§ (whose contents were printed above). Since the remainder of the rule necessarily ends at the right border of the current line, we set §xRight§ to this coordinate.
+% \begin{macrocode}
+ local xRight = currPeak.probXRight - 1 - currLine * self.samplesPerLine
+ if xRight >= self.samplesPerLine then
+ if drawCurrProb then
+ local xRightNext = (xRight - self.samplesPerLine) * self.xUnit
+ local yNext = -(currLine+1) * self.baselineSkip - self.probDistance
+ probRemainder =
+ "\n\t\\draw [" ..
+ self.probStyle(currPeak.prob[currPeak.base]) ..
+ "] (" ..
+ dimToString(0) ..
+ ", " ..
+ dimToString(yNext) ..
+ ") -- (" ..
+ dimToString(xRightNext) ..
+ ", " ..
+ dimToString(yNext) ..
+ ");"
+ end
+ xRight = (self.samplesPerLine - 1) * self.xUnit
+ else
+ xRight = xRight * self.xUnit
+ end
+
+% \end{macrocode}
+% \textit{Thirdly}, the probability rule starts and ends within the boundaries of the current line. In this lucky case, the $y$-coordinate is the only one missing, since we previously calculated §xLeft§ (case~1) and §xRight§ (case~2). Drawing of the probability rule proceeds as usual.
+% \begin{macrocode}
+ local y = -currLine * self.baselineSkip - self.probDistance
+ if drawCurrProb then
+ tex.sprint(
+ "\n\t\\draw [" ..
+ self.probStyle(currPeak.prob[currPeak.base]) ..
+ "] (" ..
+ dimToString(xLeft) ..
+ ", " ..
+ dimToString(y) ..
+ ") -- (" ..
+ dimToString(xRight) ..
+ ", " ..
+ dimToString(y) ..
+ ");"
+ )
+ end
+ lastProbX = currPeak.probXRight
+ end
+end
+% \end{macrocode}
+% \iffalse
+%</pmb-chr-lua>
+%<*pmb-dom-tex>
+% \fi
+%
+%
+% \section{\texorpdfstring{\file{pgfmolbio.domains.tex}}{pgfmolbio.domains.tex}}
+% \label{sec:DocDomTex}
+%
+% \def\ydoclistingssettings{\lstset{style=latex-doc}}\setcounter{lstnumber}{1}
+% \begin{macrocode}
+\ProvidesFile{pgfmolbio.domains.tex}[2012/10/01 v0.2 Protein Domains]
+
+% \end{macrocode}
+% If the \module{domains} module is requested by Lua\TeX\, it loads the corresponding Lua module and generates a new §SpecialKeys§ object, which will store all feature styles, disulfide keys and print functions (section~\ref{ssc:DocDomLuaSpecialKeysClass}).
+% \begin{macrocode}
+\ifluatex
+ \RequireLuaModule{pgfmolbio.domains}
+ \directlua{pmbSpecialKeys = pgfmolbio.domains.SpecialKeys:new()}
+\fi
+
+% \end{macrocode}
+%
+% \subsection{Keys}
+% \label{ssc:DocDomTexKeys}
+%
+% \begin{macro}{\@pmb@dom@keydef}[2]{\meta{key} name}{default \meta{value}}
+% |\@pmb@dom@keydef| declares a \meta{key} in path |/pgfmolbio/domains| and assigns a default \meta{value}.
+% \begin{macrocode}
+\def\@pmb@dom@keydef#1#2{%
+ \pgfkeyssetvalue{/pgfmolbio/domains/#1}{#2}%
+}
+
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\pmbdomvalueof}[1]{\meta{key} name}
+% |\pmbdomvalueof| retrieves the value of a \meta{key} in path |/pgfmolbio/domains|. Note that the control word lacks an |@| and is thus freely accessible within a \LaTeX\ document (see section~\ref{sec:DomFeatureStylesAndShapes}).
+% \begin{macrocode}
+\def\pmbdomvalueof#1{%
+ \pgfkeysvalueof{/pgfmolbio/domains/#1}%
+}
+
+% \end{macrocode}
+% \end{macro}
+% Aided by these auxiliary macros, we define all keys of the \module{domains} module.
+% \begin{macrocode}
+\@pmb@dom@keydef{name}{Protein}
+\newif\ifpmb@dom@showname
+\pgfmolbioset[domains]{%
+ show name/.is if=pmb@dom@showname,
+ show name
+}
+\@pmb@dom@keydef{description}{}
+
+\@pmb@dom@keydef{x unit}{.5mm}
+\@pmb@dom@keydef{y unit}{6mm}
+\@pmb@dom@keydef{residues per line}{200}
+\@pmb@dom@keydef{baseline skip}{3}
+\@pmb@dom@keydef{residue numbering}{auto}
+\@pmb@dom@keydef{residue range}{auto-auto}
+\@pmb@dom@keydef{enlarge left}{0cm}
+\@pmb@dom@keydef{enlarge right}{0cm}
+\@pmb@dom@keydef{enlarge top}{1cm}
+\@pmb@dom@keydef{enlarge bottom}{0cm}
+
+\pgfmolbioset[domains]{%
+ style/.code=\pgfmolbioset[domains]{current style/.style={#1}}
+}
+
+\@pmb@dom@keydef{domain font}{\footnotesize}
+
+\@pmb@dom@keydef{level}{}
+\@pmb@dom@keydef{disulfide base distance}{1}
+\@pmb@dom@keydef{disulfide level distance}{.2}
+\@pmb@dom@keydef{range font}{\sffamily\scriptsize}
+
+\newif\ifpmb@dom@showruler
+\pgfmolbioset[domains]{%
+ show ruler/.is if=pmb@dom@showruler,
+ show ruler
+}
+\@pmb@dom@keydef{ruler range}{auto-auto}
+\@pmb@dom@keydef{default ruler step size}{50}
+\@pmb@dom@keydef{ruler distance}{-.5}
+
+\@pmb@dom@keydef{sequence}{}
+\@pmb@dom@keydef{magnified sequence font}{\ttfamily\footnotesize}
+
+
+\newif\ifpmb@dom@showsecstructure
+\pgfmolbioset[domains]{%
+ show secondary structure/.is if=pmb@dom@showsecstructure,
+ show secondary structure=false
+}
+\@pmb@dom@keydef{secondary structure distance}{1}
+\pgfmolbioset[domains]{%
+ helix back border color/.code=\colorlet{helix back border color}{#1},
+ helix back main color/.code=\colorlet{helix back main color}{#1},
+ helix back middle color/.code=\colorlet{helix back middle color}{#1},
+ helix front border color/.code=\colorlet{helix front border color}{#1},
+ helix front main color/.code=\colorlet{helix front main color}{#1},
+ helix front middle color/.code=\colorlet{helix front middle color}{#1},
+ helix back border color=white!50!black,
+ helix back main color=white!90!black,
+ helix back middle color=white,
+ helix front border color=red!50!black,
+ helix front main color=red!90!black,
+ helix front middle color=red!10!white
+}
+
+\@pmb@dom@keydef{sequence length}{}
+
+\@pmb@dom@keydef{@layer}{}
+
+% \end{macrocode}
+%
+% \subsection{Feature Shapes}
+% \label{ssc:DocDomTexFeatureShapes}
+%
+% \begin{macro}{\setfeatureshape}[2]{Shape \meta{name}.}{\TikZ\ \meta{code}.}
+% Stores the \meta{code} for a shape in the macro |\@pmb@dom@feature@|\meta{name}|@shape|.
+% \begin{macrocode}
+\newcommand\setfeatureshape[2]{%
+ \expandafter\def\csname @pmb@dom@feature@#1@shape\endcsname{#2}%
+}
+
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\setfeatureshapealias}[2]{New shape.}{Existing shape.}
+% Links a new shape to an existing one.
+% \begin{macrocode}
+\newcommand\setfeatureshapealias[2]{%
+ \expandafter\def\csname @pmb@dom@feature@#1@shape\endcsname{%
+ \@nameuse{@pmb@dom@feature@#2@shape}%
+ }%
+}
+
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\setfeaturestylealias}[2]{New style.}{Existing style.}
+% This macro and the next one are only defined in Lua\TeX\. Depending on whether |\setfeaturestylealias| occurs within a |pmbdomains| environment, it either sets the feature styles of the §SpecialKeys§ object in the current §Protein§ (§pmbProtein.specialKeys§) or of the global §SpecialKeys§ object (§pmbSpecialKeys§).
+% \begin{macro}{\setfeaturealias}[2]{New feature.}{Existing feature.}
+% Calls |\setfeatureshapealias| and possibly |\setfeaturestylealias|.
+% \begin{macrocode}
+\ifluatex
+ \newcommand\setfeaturestylealias[2]{%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:aliasFeatureStyle("#1", "#2")
+ else
+ pmbSpecialKeys:aliasFeatureStyle("#1", "#2")
+ end
+ }%
+ }
+ \newcommand\setfeaturealias[2]{%
+ \setfeatureshapealias{#1}{#2}%
+ \setfeaturestylealias{#1}{#2}%
+ }
+\else
+ \let\setfeaturealias\setfeatureshapealias%
+\fi
+
+% \end{macrocode}
+% \end{macro}\end{macro}
+% \begin{macro}{\pmbdomdrawfeature}[1]{The feature \meta{type} that should be drawn.}
+% If a feature \meta{type} (i.\,e., the corresponding macro) is undefined, we issue a warning and draw feature \texttt{default}.
+% \begin{macrocode}
+\newcommand\pmbdomdrawfeature[1]{%
+ \@ifundefined{@pmb@dom@feature@#1@shape}{%
+ \PackageWarning{pgfmolbio}%
+ {Feature shape `#1' unknown, using `default'.}%
+ \@pmb@dom@feature@default@shape%
+ }{%
+ \@nameuse{@pmb@dom@feature@#1@shape}%
+ }%
+}
+
+% \end{macrocode}
+% \end{macro}
+% Definitions of standard features and their aliases.
+% \begin{macrocode}
+\setfeatureshape{default}{%
+ \path [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid + .5 * \pmbdomvalueof{y unit}) rectangle
+ (\xRight, \yMid - .5 * \pmbdomvalueof{y unit});
+}
+
+\setfeatureshape{domain}{
+ \draw [/pgfmolbio/domains/current style, rounded corners=2pt]
+ (\xLeft, \yMid + .5 * \pmbdomvalueof{y unit}) rectangle
+ (\xRight, \yMid - .5 * \pmbdomvalueof{y unit});
+ \node at (\xMid, \yMid)
+ {\pmbdomvalueof{domain font}{\pmbdomvalueof{description}}};
+}
+\setfeaturealias{DOMAIN}{domain}
+
+\setfeatureshape{signal peptide}{%
+ \path [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid + \pmbdomvalueof{y unit} / 5) rectangle
+ (\xRight, \yMid - \pmbdomvalueof{y unit} / 5);
+}
+\setfeaturealias{SIGNAL}{signal peptide}
+
+\setfeatureshape{propeptide}{%
+ \path [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid + .5 * \pmbdomvalueof{y unit}) rectangle
+ (\xRight, \yMid - .5 * \pmbdomvalueof{y unit});
+}
+\setfeaturealias{PROPEP}{propeptide}
+
+\setfeatureshape{carbohydrate}{%
+ \draw [/pgfmolbio/domains/current style]
+ (\xMid, \yMid) --
+ (\xMid, \yMid + .7 * \pmbdomvalueof{y unit})
+ node [above] {\tiny\strut\pmbdomvalueof{description}};
+ \fill [/pgfmolbio/domains/current style]
+ (\xMid, \yMid + .7 * \pmbdomvalueof{y unit}) circle [radius=1pt];
+}
+\setfeaturealias{CARBOHYD}{carbohydrate}
+
+\setfeatureshape{other/main chain}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yUpper{%
+ \yMid + \pmbdomvalueof{secondary structure distance}
+ * \pmbdomvalueof{y unit}%
+ }
+ \draw [thin]
+ (\xLeft, \yUpper pt) --
+ (\xRight, \yUpper pt);%
+ \fi%
+ \path [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid) --
+ (\xRight, \yMid);%
+}
+
+\setfeatureshape{other/name}{%
+ \ifpmb@dom@showname%
+ \node [/pgfmolbio/domains/current style]
+ at (\xMid, \pmbdomvalueof{baseline skip} * \pmbdomvalueof{y unit})
+ {\pmbdomvalueof{name} (\pmbdomvalueof{sequence length} residues)};
+ \fi%
+}
+
+\setfeatureshape{disulfide}{%
+ \pgfmathsetmacro\yUpper{%
+ \yMid + (
+ \pmbdomvalueof{disulfide base distance} +
+ (\pmbdomvalueof{level} - 1) *
+ \pmbdomvalueof{disulfide level distance}
+ ) * \pmbdomvalueof{y unit}
+ }
+ \path [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid) --
+ (\xLeft, \yUpper pt) --
+ (\xRight, \yUpper pt) --
+ (\xRight, \yMid);
+}
+\setfeaturealias{DISULFID}{disulfide}
+
+\setfeatureshape{range}{%
+ \pgfmathsetmacro\yUpper{%
+ \yMid + (
+ \pmbdomvalueof{disulfide base distance} +
+ (\pmbdomvalueof{level} - 1) *
+ \pmbdomvalueof{disulfide level distance}
+ ) * \pmbdomvalueof{y unit}
+ }
+ \path [/pgfmolbio/domains/current style]
+ (\xLeft, \yUpper pt) --
+ (\xRight, \yUpper pt)
+ node [pos=.5, above]
+ {\pmbdomvalueof{range font}{\pmbdomvalueof{description}}};
+}
+
+\setfeatureshape{other/ruler}{%
+ \draw [/pgfmolbio/domains/current style]
+ (\xMid,
+ \yMid + \pmbdomvalueof{ruler distance} *
+ \pmbdomvalueof{y unit}) --
+ (\xMid,
+ \yMid + \pmbdomvalueof{ruler distance} *
+ \pmbdomvalueof{y unit} - 1mm)
+ node [below=-1mm] {\tiny\sffamily\strut\residueNumber};
+}
+
+
+\setfeatureshape{other/sequence}{%
+ \node [/pgfmolbio/domains/current style]
+ at (\xMid, \yMid) {\strut\currentResidue};
+}
+
+\newlength\pmb@magnifiedsequence@width
+
+\setfeatureshape{other/magnified sequence above}{%
+ \settowidth\pmb@magnifiedsequence@width{%
+ \begin{pgfinterruptpicture}%
+ \pmbdomvalueof{magnified sequence font}%
+ \featureSequence%
+ \end{pgfinterruptpicture}%
+ }%
+ \pgfmathsetmacro\xUpperLeft{\xMid - \pmb@magnifiedsequence@width / 2}
+ \pgfmathsetmacro\xUpperRight{\xMid + \pmb@magnifiedsequence@width / 2}
+
+ \draw [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid) --
+ (\xLeft, \yMid + \pmbdomvalueof{y unit} / 6) --
+ (\xUpperLeft pt, \yMid + \pmbdomvalueof{y unit} * 4/6) --
+ (\xUpperLeft pt, \yMid + \pmbdomvalueof{y unit} * 5/6)
+ (\xUpperRight pt, \yMid + \pmbdomvalueof{y unit} * 5/6) --
+ (\xUpperRight pt, \yMid + \pmbdomvalueof{y unit} * 4/6) --
+ (\xRight, \yMid + \pmbdomvalueof{y unit} / 6) --
+ (\xRight, \yMid);
+ \node [anchor=mid]
+ at (\xMid, \yMid + \pmbdomvalueof{y unit})
+ {\pmbdomvalueof{magnified sequence font}\featureSequence};
+}
+
+\setfeatureshape{other/magnified sequence below}{%
+ \settowidth\pmb@magnifiedsequence@width{%
+ \begin{pgfinterruptpicture}%
+ \pmbdomvalueof{magnified sequence font}%
+ \featureSequence%
+ \end{pgfinterruptpicture}%
+ }%
+ \pgfmathsetmacro\xLowerLeft{\xMid - \pmb@magnifiedsequence@width / 2}
+ \pgfmathsetmacro\xLowerRight{\xMid + \pmb@magnifiedsequence@width / 2}
+
+ \draw [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid) --
+ (\xLeft, \yMid - \pmbdomvalueof{y unit} / 6) --
+ (\xLowerLeft pt, \yMid - \pmbdomvalueof{y unit}) --
+ (\xLowerLeft pt, \yMid - \pmbdomvalueof{y unit} * 7/6)
+ (\xLowerRight pt, \yMid - \pmbdomvalueof{y unit} * 7/6) --
+ (\xLowerRight pt, \yMid - \pmbdomvalueof{y unit}) --
+ (\xRight, \yMid - \pmbdomvalueof{y unit} / 6) --
+ (\xRight, \yMid);
+ \node [anchor=mid]
+ at (\xMid, \yMid - \pmbdomvalueof{y unit} * 8/6)
+ {\pmbdomvalueof{magnified sequence font}\featureSequence};
+}
+
+
+% \end{macrocode}
+%
+% \subsection{Secondary Structure Elements}
+% \label{ssc:DocDomTexSecondaryStructure}
+%
+% \begin{macro}{\@pmb@dom@helixsegment}[1]{Scale factor for \TikZ's \texttt{svg} action.}
+% Draws a full helix segment at the current canvas position. We use the (unusual) \file{svg} syntax since the helix segment was designed in Inkscape, and the \file{svg} commands were copied from the resulting vector graphics file.
+% \begin{macrocode}
+\newcommand\@pmb@dom@helixsegment[1]{%
+ svg [scale=#1] "%
+ c 0.30427 0
+ 0.62523 0.59174
+ 0.79543 0.96646
+ c 0.97673 2.15039
+ 1.34005 4.49858
+ 1.84538 6.6178
+ c 0.56155 2.35498
+ 0.99602 4.514
+ 1.82948 6.72355
+ c 0.11069 0.29346
+ 0.23841 0.69219
+ 0.56172 0.69219
+ l -5 0
+ c -0.27235 0.0237
+ -0.55793 -0.51373
+ -0.65225 -0.76773
+ c -0.98048 -2.64055
+ -1.40233 -5.46534
+ -2.06809 -8.00784
+ c -0.50047 -1.91127
+ -0.94696 -3.73368
+ -1.68631 -5.43929
+ c -0.14066 -0.3245
+ -0.34516 -0.78514
+ -0.69997 -0.78514
+ z"
+}
+
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@pmb@dom@helixhalfsegment}[1]{Scale factor for \TikZ's \texttt{svg} action.}
+% Draws a half helix segment.
+% \begin{macrocode}
+\newcommand\@pmb@dom@helixhalfsegment[1]{%
+ svg [scale=#1] "%
+ c 0.50663 2.18926
+ 0.96294 4.51494
+ 1.78125 6.71875
+ c 0.09432 0.254
+ 0.35265 0.80495
+ 0.625 0.78125
+ l 5 0
+ c -0.32331 0
+ -0.45181 -0.42529
+ -0.5625 -0.71875
+ c -0.83346 -2.20955
+ -1.2822 -4.36377
+ -1.84375 -6.78125
+ l -5 0
+ z"
+}
+
+% \end{macrocode}
+% \end{macro}
+% Shadings for helix segments.
+% \begin{macrocode}
+\pgfdeclareverticalshading[%
+ helix back border color,%
+ helix back main color,%
+ helix back middle color%
+ ]{helix half upper back}{100bp}{
+ color(0bp)=(helix back middle color);
+ color(5bp)=(helix back middle color);
+ color(45bp)=(helix back main color);
+ color(75bp)=(helix back border color);
+ color(100bp)=(helix back border color)
+}
+
+\pgfdeclareverticalshading[%
+ helix back border color,%
+ helix back main color,%
+ helix back middle color%
+ ]{helix half lower back}{100bp}{
+ color(0bp)=(helix back border color);
+ color(25bp)=(helix back border color);
+ color(35bp)=(helix back main color);
+ color(55bp)=(helix back middle color);
+ color(95bp)=(helix back main color);
+ color(100bp)=(helix back main color)
+}
+
+\pgfdeclareverticalshading[%
+ helix back border color,%
+ helix back main color,%
+ helix back middle color%
+ ]{helix full back}{100bp}{
+ color(0bp)=(helix back border color);
+ color(25bp)=(helix back border color);
+ color(30bp)=(helix back main color);
+ color(40bp)=(helix back middle color);
+ color(60bp)=(helix back main color);
+ color(75bp)=(helix back border color);
+ color(100bp)=(helix back border color)
+}
+
+\pgfdeclareverticalshading[%
+ helix front border color,%
+ helix front main color,%
+ helix front middle color%
+ ]{helix half upper front}{100bp}{
+ color(0bp)=(helix front main color);
+ color(5bp)=(helix front main color);
+ color(45bp)=(helix front middle color);
+ color(65bp)=(helix front main color);
+ color(75bp)=(helix front border color);
+ color(100bp)=(helix front border color)
+}
+
+\pgfdeclareverticalshading[%
+ helix front border color,%
+ helix front main color,%
+ helix front middle color%
+ ]{helix full front}{100bp}{
+ color(0bp)=(helix front border color);
+ color(25bp)=(helix front border color);
+ color(40bp)=(helix front main color);
+ color(60bp)=(helix front middle color);
+ color(70bp)=(helix front main color);
+ color(75bp)=(helix front border color);
+ color(100bp)=(helix front border color)
+}
+
+% \end{macrocode}
+% The following features print single helical turns. They are drawn with appropriate coordinates by §printHelixFeature§ (section~\ref{ssc:DocDomLuaPrintFunctions}).
+% \begin{macrocode}
+\setfeatureshape{helix/half upper back}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [shading=helix half upper back]
+ (\xLeft, \yMid + \yShift pt)
+ \@pmb@dom@helixhalfsegment{\pmbdomvalueof{x unit} / 5};
+ \fi%
+}
+
+\setfeatureshape{helix/half lower back}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [shading=helix half lower back]
+ (\xRight, \yMid + \yShift pt) [rotate=180]
+ \@pmb@dom@helixhalfsegment{\pmbdomvalueof{x unit} / 5};
+ \fi%
+}
+
+\setfeatureshape{helix/full back}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [shading=helix full back]
+ (\xMid, \yLower + \yShift pt)
+ \@pmb@dom@helixsegment{\pmbdomvalueof{x unit} / 5};
+ \fi%
+}
+
+\setfeatureshape{helix/half upper front}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [shading=helix half upper front]
+ (\xRight, \yMid + \yShift pt) [xscale=-1]
+ \@pmb@dom@helixhalfsegment{\pmbdomvalueof{x unit} / 5};
+ \fi%
+}
+
+\setfeatureshape{helix/full front}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [shading=helix full front]
+ (\xMid, \yLower + \yShift pt) [xscale=-1]
+ \@pmb@dom@helixsegment{\pmbdomvalueof{x unit} / 5};
+ \fi%
+}
+
+% \end{macrocode}
+% Definitions of the remaining secondary structure features.
+% \begin{macrocode}
+\definecolor{strand left color}{RGB}{42,127,255}
+\definecolor{strand right color}{RGB}{128,179,255}
+
+\setfeatureshape{beta strand}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid + \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid + \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid + 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight, \yMid + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid - 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid - \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xLeft, \yMid - \pmbdomvalueof{x unit} + \yShift pt) --
+ cycle;%
+ \fi%
+}
+\setfeaturealias{STRAND}{beta strand}
+
+\setfeatureshape{beta turn}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \pgfmathsetmacro\turnXradius{(\xRight - \xLeft) / 2}%
+ \pgfmathsetmacro\turnYradius{\pmbdomvalueof{x unit} * 1.5}%
+ \fill [white]
+ (\xLeft, \yMid + 1mm + \yShift pt) rectangle
+ (\xRight, \yMid - 1mm + \yShift pt);%
+ \draw [/pgfmolbio/domains/current style]
+ (\xLeft - .5pt, \yMid + \yShift pt) --
+ (\xLeft, \yMid + \yShift pt) arc
+ [start angle=180, end angle=0,
+ x radius=\turnXradius pt, y radius=\turnYradius pt] --
+ (\xRight + .5pt, \yMid + \yShift pt);%
+ \fi%
+}
+\setfeaturealias{TURN}{beta turn}
+
+\setfeatureshape{beta bridge}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid + .25 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid + .25 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid + 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight, \yMid + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid - 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid - .25 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xLeft, \yMid - .25 * \pmbdomvalueof{x unit} + \yShift pt) --
+ cycle;%
+ \fi%
+}
+
+\setfeatureshape{bend}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \fill [white]
+ (\xLeft, \yMid + 1mm + \yShift pt) rectangle
+ (\xRight, \yMid - 1mm + \yShift pt);%
+ \draw [/pgfmolbio/domains/current style]
+ (\xLeft - .5pt, \yMid + \yShift pt) --
+ (\xLeft, \yMid + \yShift pt) --
+ (\xMid, \yMid + .5 * \pmbdomvalueof{y unit} + \yShift pt) --
+ (\xRight, \yMid + \yShift pt) --
+ (\xRight + .5pt, \yMid + \yShift pt);%
+ \fi%
+}
+
+% \end{macrocode}
+% This concludes the part of the package that is always loaded. The remaining code is only executed within Lua\TeX.
+% \begin{macrocode}
+\ifluatex\else\expandafter\endinput\fi
+
+
+% \end{macrocode}
+%
+% \subsection{Adding Features}
+% \label{ssc:DocDomTexAddingFeatures}
+%
+% \begin{macro}{\pmb@dom@inputuniprot}[1]{The \meta{name} of a Uniprot file.}
+% |\pmb@dom@inputuniprot| reads some attributes and all features from a Uniprot file (§readUniprotFile§, section~\ref{ssc:DocDomLuaReadFiles}). It then updates some keys of the \module{domains} module (§getParameters§, section~\ref{ssc:DocDomLuaParameters}) and then passes the value of \opt{residue numbering} to the §pmbProtein§ object.
+% \begin{macrocode}
+\newcommand\pmb@dom@inputuniprot[1]{%
+ \directlua{
+ pmbProtein:readUniprotFile("#1")
+ pmbProtein:getParameters()
+ pmbProtein:setParameters{
+ residueNumbering = "\pmbdomvalueof{residue numbering}"
+ }
+ }%
+}
+
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\pmb@dom@inputgff}[1]{The \meta{name} of a General Feature Format (\file{gff}) file.}
+% This macro reads all features from a \file{gff} file (§readGffFile§, section~\ref{ssc:DocDomLuaReadFiles}). It then passes the value of residue numbering to §pmbProtein§.
+% \begin{macrocode}
+\newcommand\pmb@dom@inputgff[1]{%
+ \directlua{
+ pmbProtein:readGffFile("#1")
+ pmbProtein:setParameters{
+ residueNumbering = "\pmbdomvalueof{residue numbering}"
+ }
+ }%
+}
+
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\pmb@dom@addfeature}[4]{A \ometa{key-value list} that is locally applied to the feature.}{The feature \meta{key}.}{The \meta{first} \dots}{and \meta{last} residue covered by the feature.}
+% This macro adds a feature to §pmbProtein§ by calling its §addFeature§ method. The \ometa{key-value list} should be stored without any expansion in the §kvList§ field of §addFeature§'s single argument table. To this end, we first store the \ometa{key-value list} in the token register |\@pmb@toksa| and then access its contents by the construction |\directlua{|[...]|\the\@pmb@toksa|[...]|}|. This code behaves similarly to |\the| inside an |\edef|, i.\,e. the contents of the token register are not further expanded.
+% \begin{macrocode}
+\newcommand\pmb@dom@addfeature[4][]{%
+ \begingroup%
+ \pgfmolbioset[domains]{#1}%
+ \@pmb@toksa{#1}%
+ \directlua{
+ pmbProtein:addFeature{
+ key = "#2",
+ start = "#3",
+ stop = "#4",
+ kvList = "\luaescapestring{\the\@pmb@toksa}",
+ level = tonumber("\pmbdomvalueof{level}"),
+ layer = tonumber("\pmbdomvalueof{@layer}")
+ }
+ }%
+ \endgroup%
+}
+
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{The Main Environment}
+% \label{ssc:DocDomTexMainEnvironment}
+%
+% % \begin{environment}{pmbdomains}[2]{A \ometa{key-value list} that configures the domain diagram.}{The \meta{sequence length}.}
+% If |pmbdomains| appears outside of a |tikzpicture|, we implicitly start this environment, otherwise we begin a new group. ``Within a |tikzpicture|'' means that |\useasboundingbox| is defined. The \ometa{key-value list} is processed.
+% \begin{macrocode}
+\newif\ifpmb@dom@tikzpicture
+
+\newenvironment{pmbdomains}[2][]{%
+ \@ifundefined{useasboundingbox}%
+ {\pmb@dom@tikzpicturefalse\begin{tikzpicture}}%
+ {\pmb@dom@tikzpicturetrue}%
+ \pgfmolbioset[domains]{sequence length=#2, #1}%
+% \end{macrocode}
+% The macros |\inputuniprot|, |\inputgff| and |\addfeature| only point to their respective internal macros (section~\ref{ssc:DocDomTexAddingFeatures}) within |pmbdomains|.
+% \begin{macrocode}
+ \let\inputuniprot\pmb@dom@inputuniprot%
+ \let\inputgff\pmb@dom@inputgff%
+ \let\addfeature\pmb@dom@addfeature%
+% \end{macrocode}
+% §pmbProtein§ is a new §Protein§ object whose §specialKeys§ attribute is initialized with the values from the package-wide §SpecialKeys§ object. Since §pmbProtein§ must know the sequence length and residue numbering before the environment's body is processed, we call §setParameters§ twice to ensure that §sequenceLength§ is set prior to §residueNumbering§.
+% \begin{macrocode}
+ \directlua{
+ pmbProtein = pgfmolbio.domains.Protein:new()
+ pmbProtein.specialKeys =
+ pgfmolbio.domains.SpecialKeys:new(pmbSpecialKeys)
+ pmbProtein:setParameters{
+ sequenceLength = "\pmbdomvalueof{sequence length}"
+ }
+ pmbProtein:setParameters{
+ residueNumbering = "\pmbdomvalueof{residue numbering}"
+ }
+ }%
+}{%
+% \end{macrocode}
+% At the end of |pmbdomains|'s body, §pmbProtein§ stores all features that have been defined there. We add one more feature, \texttt{other/main chain}, which spans the whole protein and occupies the lowermost layer (this is the only instance where we need the \opt{@layer} key).
+% \begin{macrocode}
+ \pmb@dom@addfeature[@layer=1]{other/main chain}%
+ {(1)}{(\pmbdomvalueof{sequence length})}%
+% \end{macrocode}
+% The following syntactical gem ensures that the token register |\@pmb@toksa| contains the value of the \opt{name} key without expansion of any macros within the value.
+% \begin{macrocode}
+ \@pmb@toksa=%
+ \expandafter\expandafter\expandafter\expandafter%
+ \expandafter\expandafter\expandafter{%
+ \pgfkeysvalueof{/pgfmolbio/domains/name}%
+ }%
+% \end{macrocode}
+% Set the remaining attributes of §pmbProtein§.
+% \begin{macrocode}
+ \directlua{
+ pmbProtein:setParameters{
+ residueRange = "\pmbdomvalueof{residue range}",
+ defaultRulerStepSize = "\pmbdomvalueof{default ruler step size}"
+ }
+ pmbProtein:setParameters{
+ name = "\luaescapestring{\the\@pmb@toksa}",
+ xUnit = "\pmbdomvalueof{x unit}",
+ yUnit = "\pmbdomvalueof{y unit}",
+ residuesPerLine = "\pmbdomvalueof{residues per line}",
+ baselineSkip = "\pmbdomvalueof{baseline skip}",
+ showRuler = "\ifpmb@dom@showruler true\else false\fi",
+ rulerRange = "\pmbdomvalueof{ruler range}",
+ sequence = "\pmbdomvalueof{sequence}"
+ }
+% \end{macrocode}
+% Calculate he appropriate levels of disulfide-like features (section~\ref{ssc:DocDomLuaDisulfideLevels}). §pgfmolbio.setCoordinateFormat§ sets the coordinate output format (section~\ref{sec:DocPkgLua}).
+% \begin{macrocode}
+ pmbProtein:calculateDisulfideLevels()
+ pgfmolbio.setCoordinateFormat(
+ "\pgfkeysvalueof{/pgfmolbio/coordinate unit}",
+ "\pgfkeysvalueof{/pgfmolbio/coordinate format string}"
+ )
+% \end{macrocode}
+% If the \module{convert} module is loaded, we open the appropriate output file. If we wish to output final \TikZ\ code, we change §tex.sprint§ so that the function writes to this file and then call §printTikzDomains§. Otherwise, we write a string representation of §pmbProtein§ to the file (section~\ref{ssc:DocDomLuaTostring}). Without the \module{convert} module, §printTikzDomains§ simply returns the drawing commands for the chromatogram to the \TeX\ input stream (section~\ref{ssc:DocDomLuaPrintTikzDomains}).
+% \begin{macrocode}
+ \ifpmb@loadmodule@convert
+ local filename =
+ "\pgfkeysvalueof{/pgfmolbio/convert/output file name}"
+ if filename == "(auto)" then
+ filename = "pmbconverted" .. pgfmolbio.outputFileId
+ end
+ filename = filename ..
+ ".\pgfkeysvalueof{/pgfmolbio/convert/output file extension}"
+ outputFile, ioError = io.open(filename, "w")
+ if ioError then
+ tex.error(ioError)
+ end
+ \ifpmb@con@outputtikzcode
+ tex.sprint = function(a) outputFile:write(a) end
+ pmbProtein:getParameters()
+ tex.sprint("\string\n\string\\begin{tikzpicture}")
+ pmbProtein:printTikzDomains()
+ tex.sprint("\string\n\string\\end{tikzpicture}")
+ \else
+ \ifpmb@con@includedescription
+ pmbProtein.includeDescription = true
+ \fi
+ outputFile:write(tostring(pmbProtein))
+ \fi
+ outputFile:close()
+ pgfmolbio.outputFileId = pgfmolbio.outputFileId + 1
+ \else
+ pmbProtein:printTikzDomains()
+ \fi
+ pmbProtein = nil
+ }%
+% \end{macrocode}
+% At the end of |pmbdomains|, we close an implicitly added |tikzpicture|.
+% \begin{macrocode}
+ \ifpmb@dom@tikzpicture\else\end{tikzpicture}\fi%
+}
+
+% \end{macrocode}
+% \end{environment}
+%
+% \subsection{Feature Styles}
+% \label{ssc:DocDomTexFeatureStyles}
+%
+% \begin{macro}{\setdisulfidefeatures}[1]{A list of \meta{features}.}
+% Clears the list of disulfide-like features and adds the \meta{features} to the empty list. Disulfide-like features are arranged in non-overlapping layers (section~\ref{sec:DomDisulfides}). Depending on whether this macro appears inside a |pmbdomains| environment or not, the appropriate methods of either §pmbProtein.specialKeys§ or §pmbSpecialKeys§ are called, respectively.
+% \begin{macrocode}
+\newcommand\setdisulfidefeatures[1]{%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:clearKeys("disulfideKeys")
+ pmbProtein.specialKeys:setKeys("disulfideKeys", "#1", true)
+ else
+ pmbSpecialKeys:clearKeys("disulfideKeys")
+ pmbSpecialKeys:setKeys("disulfideKeys", "#1", true)
+ end
+ }%
+}
+
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\adddisulfidefeatures}[1]{A list of \meta{features}.}
+% Adds the \meta{features} to the list of disulfide-like features without overwriting the current list.
+% \begin{macrocode}
+\newcommand\adddisulfidefeatures[1]{%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:setKeys("disulfideKeys", "#1", true)
+ else
+ pmbSpecialKeys:setKeys("disulfideKeys", "#1", true)
+ end
+ }%
+}
+
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\removedisulfidefeatures}[1]{A list of \meta{features}.}
+% Removes the \meta{features} from the list of disulfide-like features.
+% \begin{macrocode}
+\newcommand\removedisulfidefeatures[1]{%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:setKeys("disulfideKeys", "#1", nil)
+ else
+ pmbSpecialKeys:setKeys("disulfideKeys", "#1", nil)
+ end
+ }%
+}
+
+% \end{macrocode}
+% \end{macro}
+% Declare the default disulfide-like features.
+% \begin{macrocode}
+\setdisulfidefeatures{DISULFID, disulfide, range}
+
+% \end{macrocode}
+% \begin{macro}{\setfeatureprintfunction}[2]{A \meta{list} of features.}{Name of a Lua \meta{function}.}
+% Assigns a feature print \meta{function} to each feature in the \meta{list}. Feature print functions are preprocessors which, for instance, calculate coordinates for features (section~\ref{sec:DomSequences}).
+% \begin{macrocode}
+\newcommand\setfeatureprintfunction[2]{%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:setKeys("printFunctions", "#1", #2)
+ else
+ pmbSpecialKeys:setKeys("printFunctions", "#1", #2)
+ end
+ }%
+}
+
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\removefeatureprintfunction}[1]{A \meta{list} of features.}
+% Removes any feature print function from the features in the \meta{list}.
+% \begin{macrocode}
+\newcommand\removefeatureprintfunction[1]{%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:setKeys("printFunctions", "#1", nil)
+ else
+ pmbSpecialKeys:setKeys("printFunctions", "#1", nil)
+ end
+ }%
+}
+
+% \end{macrocode}
+% \end{macro}
+% Assign default feature print functions.
+% \begin{macrocode}
+\setfeatureprintfunction{other/sequence}%
+ {pgfmolbio.domains.printSequenceFeature}
+\setfeatureprintfunction{alpha helix, pi helix, 310 helix, HELIX}%
+ {pgfmolbio.domains.printHelixFeature}
+
+% \end{macrocode}
+%
+% \begin{macro}{\setfeaturestyle}[2]{A \meta{feature} name.}{A \meta{style list}.}
+% Sets the style of a \meta{feature} to the style described in the \meta{style list}. Note that the contents of \meta{style list} are passed to the Lua function without expansion (via the token register |\@pmb@toksa|).
+% \begin{macrocode}
+\newcommand\setfeaturestyle[2]{%
+ \@pmb@toksa{#2}%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:setFeatureStyle(
+ "#1", "\luaescapestring{\the\@pmb@toksa}"
+ )
+ else
+ pmbSpecialKeys:setFeatureStyle(
+ "#1", "\luaescapestring{\the\@pmb@toksa}"
+ )
+ end
+ }%
+}
+
+% \end{macrocode}
+% \end{macro}
+% Declare default feature styles.
+% \begin{macrocode}
+\setfeaturestyle{default}{draw}
+\setfeaturestyle{domain}%
+ {fill=Chartreuse,fill=LightSkyBlue,fill=LightPink,fill=Gold!50}
+\setfeaturestyle{signal peptide}{fill=black}
+\setfeaturestyle{propeptide}%
+ {*1{fill=Gold, opacity=.5, rounded corners=4pt}}
+\setfeaturestyle{carbohydrate}{red}
+\setfeaturestyle{other/main chain}{*1{draw, line width=2pt, black!25}}
+\setfeaturestyle{other/name}{font=\sffamily}
+\setfeaturestyle{disulfide}{draw=olive}
+\setfeaturestyle{range}{*1{draw,decorate,decoration=brace}}
+\setfeaturestyle{other/ruler}{black, black!50}
+\setfeaturestyle{other/sequence}{*1{font=\ttfamily\tiny}}%
+\setfeaturestyle{other/magnified sequence above}%
+ {*1{draw=black!50, densely dashed}}
+\setfeaturestylealias{other/magnified sequence below}%
+ {other/magnified sequence above}
+\setfeaturestyle{alpha helix}{%
+ *1{helix front border color=red!50!black,%
+ helix front main color=red!90!black,%
+ helix front middle color=red!10!white}%
+}
+\setfeaturestylealias{HELIX}{alpha helix}
+\setfeaturestyle{pi helix}{%
+ *1{helix front border color=yellow!50!black,%
+ helix front main color=yellow!70!red,%
+ helix front middle color=yellow!10!white}%
+}
+\setfeaturestyle{310 helix}{%
+ *1{helix front border color=magenta!50!black,%
+ helix front main color=magenta!90!black,%
+ helix front middle color=magenta!10!white}%
+}
+\setfeaturestyle{beta strand}{%
+ *1{left color=strand left color, right color=strand right color}%
+}
+\setfeaturestyle{beta turn}{*1{draw=violet, thick}}
+\setfeaturestyle{beta bridge}{*1{fill=MediumBlue}}
+\setfeaturestyle{bend}{*1{draw=magenta, thick}}
+% \end{macrocode}
+%
+% \iffalse
+%</pmb-dom-tex>
+%<*pmb-dom-lua>
+% \fi
+%
+%
+%
+% \section{\texorpdfstring{\file{pgfmolbio.domains.lua}}{pgfmolbio.domains.lua}}
+% \label{sec:DocDomLua}
+%
+% \def\ydoclistingssettings{\lstset{style=lua-doc}}\setcounter{lstnumber}{1}
+% \begin{macrocode}
+if luatexbase then
+ luatexbase.provides_module({
+ name = "pgfmolbio.domains",
+ version = 0.2,
+ date = "2012/10/01",
+ description = "Domain graphs",
+ author = "Wolfgang Skala",
+ copyright = "Wolfgang Skala",
+ license = "LPPL",
+ })
+end
+
+% \end{macrocode}
+% These local functions point to functions in \file{pgfmolbio.lua} (section~\ref{sec:DocPkgLua}).
+% \begin{macrocode}
+local stringToDim = pgfmolbio.stringToDim
+local dimToString = pgfmolbio.dimToString
+local packageError = pgfmolbio.packageError
+local packageWarning = pgfmolbio.packageWarning
+local getRange = pgfmolbio.getRange
+
+% \end{macrocode}
+%
+% \subsection{Predefined Feature Print Functions}
+% \label{ssc:DocDomLuaPrintFunctions}
+%
+% §printSequenceFeature§ prints the letters of a sequence between the $x$-coordinates §xLeft§ and §xRight§.
+% \begin{macrocode}
+function printSequenceFeature(feature, xLeft, xRight, yMid, xUnit, yUnit)
+ xLeft = xLeft + 0.5
+ for currResidue in feature.sequence:gmatch(".") do
+ tex.sprint("\n\t\t\\def\\xMid{" .. dimToString(xLeft * xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\yMid{" .. dimToString(yMid * yUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\currentResidue{" .. currResidue .. "}")
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{other/sequence}")
+ xLeft = xLeft + 1
+ end
+end
+
+% \end{macrocode}
+%
+% §printHelixFeature§ prints a helix feature between the $x$-coordinates §xLeft§ and §xRight§.
+% \begin{macrocode}
+function printHelixFeature(feature, xLeft, xRight, yMid, xUnit, yUnit)
+ local residuesLeft, currX
+ tex.sprint("\n\t\t\\pgfmolbioset[domains]{current style}")
+
+% \end{macrocode}
+% \textit{Firstly}, three different background parts are drawn: one \texttt{half upper back} at the left, zero or more \texttt{full back} in the middle and possibly one \texttt{half lower back} at the right.
+% \begin{macrocode}
+ residuesLeft = feature.stop - feature.start + 1
+ currX = xLeft
+ tex.sprint("\n\t\t\\def\\xLeft{" .. dimToString(currX * xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\yMid{" .. dimToString(yMid * yUnit) .. "}")
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{helix/half upper back}")
+ residuesLeft = residuesLeft - 2
+ currX = currX + 2.5
+
+ while residuesLeft > 0 do
+ if residuesLeft == 1 then
+ tex.sprint(
+ "\n\t\t\\def\\xRight{" ..
+ dimToString((currX + 0.5) * xUnit) ..
+ "}"
+ )
+ tex.sprint("\n\t\t\\def\\yMid{" .. dimToString(yMid * yUnit) .. "}")
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{helix/half lower back}")
+ else
+ tex.sprint("\n\t\t\\def\\xMid{" .. dimToString(currX * xUnit) .. "}")
+ tex.sprint(
+ "\n\t\t\\def\\yLower{" ..
+ dimToString(yMid * yUnit - 1.5 * xUnit) ..
+ "}"
+ )
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{helix/full back}")
+ end
+ residuesLeft = residuesLeft - 2
+ currX = currX + 2
+ end
+
+% \end{macrocode}
+% \textit{Secondly}, two different foreground parts are drawn: at least one \texttt{full front} at the left and in the middle, and possibly one \texttt{half upper front} at the right.
+% \begin{macrocode}
+ residuesLeft = feature.stop - feature.start
+ currX = xLeft + 1.5
+ while residuesLeft > 0 do
+ if residuesLeft == 1 then
+ tex.sprint(
+ "\n\t\t\\def\\xRight{" ..
+ dimToString((currX + 0.5) * xUnit) ..
+ "}"
+ )
+ tex.sprint("\n\t\t\\def\\yMid{" .. dimToString(yMid * yUnit) .. "}")
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{helix/half upper front}")
+ else
+ tex.sprint("\n\t\t\\def\\xMid{" .. dimToString(currX * xUnit) .. "}")
+ tex.sprint(
+ "\n\t\t\\def\\yLower{" ..
+ dimToString(yMid * yUnit - 1.5 * xUnit) ..
+ "}"
+ )
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{helix/full front}")
+ end
+ residuesLeft = residuesLeft - 2
+ currX = currX + 2
+ end
+end
+
+% \end{macrocode}
+%
+% \subsection{The \texorpdfstring{\texttt{SpecialKeys}}{SpecialKeys} Class}
+% \label{ssc:DocDomLuaSpecialKeysClass}
+%
+% The §SpecialKeys§ class contains three member variables: §disulfideKeys§ (a list of keys that indicate disulfide-like features, like \texttt{disulfide}), §featureStyles§ (a list of feature styles) and §printFunctions§ (a list of keys associated with a feature print function, like \texttt{alpha helix}). Furthermore, it provides methods to manipulate these fields.
+%
+% The constructor §SpecialKeys:new§ generates a new §SpecialKeys§ object and initializes it with values from §parms§.
+% \begin{macrocode}
+SpecialKeys = {}
+
+function SpecialKeys:new(parms)
+ parms = parms or {}
+ local newSpecialKeys = {
+ disulfideKeys = {},
+ featureStyles = {},
+ printFunctions = {}
+ }
+
+ for keyList, listContents in pairs(parms) do
+ for key, value in pairs(listContents) do
+ newSpecialKeys[keyList][key] = value
+ end
+ end
+
+ setmetatable(newSpecialKeys, self)
+ self.__index = self
+ return newSpecialKeys
+end
+
+% \end{macrocode}
+% §SpecialKeys:setKeys§ sets a §value§ for a §key§ in the §keylist§. Possible values for §keyList§ are §"disulfideKeys"§, §"featureStyles"§ or §"printFunctions"§.
+% \begin{macrocode}
+function SpecialKeys:setKeys(keylist, keys, value)
+ for key in keys:gmatch("([^,]+)") do
+ key = key:trim()
+ self[keylist][key] = value
+ end
+end
+
+% \end{macrocode}
+%
+% §SpecialKeys:setFeatureStyle§ parses the style list §style§ and associates it with a certain §key§. In Lua, a style list is an array of tables. Each table contains the fields §cycles§ and §style§. §cycles§ determines how often the §style§ (a string suitable for the mandatory argument of |\pgfmolbioset|) is to be used. In addition, an optional field §alias§ contains a reference to another key, if the current key is an alias of it (see below).
+% \begin{macrocode}
+function SpecialKeys:setFeatureStyle(key, style)
+ local newStyleList, styleCycles, styleContents
+
+ newStyleList = {}
+ while style ~= "" do
+ styleCycles = 1
+ if style:sub(1,1) == "{" then
+ styleContents = style:match("%b{}")
+ style = style:match("%b{}(.*)")
+ elseif style:sub(1,1) == "*" then
+ styleCycles, styleContents = style:match("%*(%d*)(%b{})")
+ if styleCycles == "" then styleCycles = 1 end
+ style = style:match("%*%d*%b{}(.*)")
+ elseif style:sub(1,1) == "," or style:sub(1,1) == " " then
+ style = style:match("[,%s]+(.*)")
+ styleCycles, styleContents = nil, nil
+ else
+ styleContents = style:match("([^,]+),")
+ if not styleContents then
+ styleContents = style
+ style = ""
+ else
+ style = style:match("[^,]+,(.*)")
+ end
+ end
+ if styleCycles then
+ table.insert(
+ newStyleList,
+ {cycles = styleCycles, style = styleContents}
+ )
+ end
+ end
+ self.featureStyles[key] = newStyleList
+end
+
+% \end{macrocode}
+% §SpecialKeys:aliasFeatureStyle§ sets the §alias§ field of a style list so that feature §newKey§ uses the same feature style as feature §oldKey§.
+% \begin{macrocode}
+function SpecialKeys:aliasFeatureStyle(newKey, oldKey)
+ self.featureStyles[newKey] = {alias = oldKey}
+end
+
+% \end{macrocode}
+% §SpecialKeys:getBaseKey§ returns either the name of §key§ itself or of its parent key if §key§ is an alias.
+% \begin{macrocode}
+function SpecialKeys:getBaseKey(key)
+ if self.featureStyles[key] then
+ if self.featureStyles[key].alias then
+ return self.featureStyles[key].alias
+ end
+ end
+ return key
+end
+
+% \end{macrocode}
+% §SpecialKeys:clearKeys§ clears a §keylist§.
+% \begin{macrocode}
+function SpecialKeys:clearKeys(keylist)
+ self[keylist] = {}
+end
+
+% \end{macrocode}
+% §SpecialKeys:selectStyleFromList§ returns the §styleID§-th style from the style list associated with §key§. Firstly, the correct style list is selected.
+% \begin{macrocode}
+function SpecialKeys:selectStyleFromList(key, styleID)
+ local styleList
+
+ if not self.featureStyles[key] then
+ packageWarning(
+ "Feature style `" ..
+ key ..
+ "' unknown, using `default'."
+ )
+ styleList = self.featureStyles.default
+ elseif self.featureStyles[key].alias then
+ styleList = self.featureStyles[self.featureStyles[key].alias]
+ else
+ styleList = self.featureStyles[key]
+ end
+
+% \end{macrocode}
+% Secondly, the method choses the appropriate style in the list.
+% \begin{macrocode}
+ while true do
+ for _, v in ipairs(styleList) do
+ styleID = styleID - v.cycles
+ if styleID < 1 then
+ return v.style
+ end
+ end
+ end
+end
+
+% \end{macrocode}
+%
+% \subsection{The \texorpdfstring{\texttt{Protein}}{Protein} Class}
+% \label{ssc:DocDomLuaProteinClass}
+%
+% The §Protein§ class represents a domain diagram in Lua. Its member variables largely correspond to the keys of the \module{domains} module. In detail:
+% \begin{itemize}
+% \item §sequenceLength§: A value of §-1§ indicates that the sequence length has not been properly set.
+% \item §ft§ is the feature table, i.\,e. an array of tables with the following fields:
+% \begin{itemize}
+% \item §key§: A string that equals the feature key.
+% \item §start§: The start \dots
+% \item §stop§: \dots\ and the end residue of the feature, both in \textit{absolute} numbering. (For the difference between absolute and relative numbering, see section~\ref{sec:DomGeneralLayout}.)
+% \item §kvList§: A string containing comma-separated key-value pairs, which is passed to |\pgfmolbioset| immediately before the feature is drawn.
+% \item §level§: The level of the feature (only relevant for disulfide-like features).
+% \end{itemize}
+% \item §residueNumbering§: An array of strings. The indices are absolute residue numbers, while the fields represent the corresponding relative residue numbers.
+% \item §revResidueNumbering§: The inverse of §residueNumbering§ (i.\,e., a table of numbers).
+% \item §rulerRange§: An array of tables. Each table represents one mark of the ruler and has the fields §pos§ (position in absolute residue numbers) and §number§ (relative number of the marked residue).
+% \item §currentStyle§: A table whose field names equal feature keys. Each field denotes the index of the style that was last selected from that feature's style list.
+% \item §includeDescription§: This boolean field remains uninitialized. Instead, it is directly set in \file{pgfmolbio.domains.tex} if the \module{convert} module is loaded and the user requests a string representation of a §Protein§ object (section~\ref{ssc:DocDomLuaTostring}).
+% \end{itemize}
+%
+% The constructor §Protein:new§ initializes the member variables with default values.
+% \begin{macrocode}
+Protein = {}
+
+function Protein:new()
+ local newProtein = {
+ name = "",
+ sequenceLength = -1,
+ ft = {},
+ sequence = "",
+ xUnit = stringToDim("0.5mm"),
+ yUnit = stringToDim("6mm"),
+ residuesPerLine = 250,
+ residueRangeMin = 1,
+ residueRangeMax = 100,
+ residueNumbering = {},
+ revResidueNumbering = {},
+ baselineSkip = 3,
+ rulerRange = {},
+ defaultRulerStepSize = 50,
+ showRuler = true,
+ currentStyle = {},
+ specialKeys = SpecialKeys:new()
+ }
+ setmetatable(newProtein, self)
+ self.__index = self
+ return newProtein
+end
+
+% \end{macrocode}
+% §Protein:toAbsoluteResidueNumber§ converts a string that either contains an absolute or relative residue number to an absolute residue number.
+% \begin{macrocode}
+function Protein:toAbsoluteResidueNumber(value)
+ local result = value:match("%b()")
+ if result then
+ result = tonumber(result:sub(2, -2))
+ else
+ result = self.revResidueNumbering[(value:gsub("[<>%?]", ""))]
+ end
+ if not result then
+ packageError("Bad or missing start/end point value: " .. value)
+ end
+ return result
+end
+
+% \end{macrocode}
+%
+% \subsection{Uniprot and GFF Files}
+% \label{ssc:DocDomLuaReadFiles}
+%
+% §Protein:readUniprotFile§ reads the relevant parts of Uniprot file §filename§\footnote{For a detailed description of this format, see \url{http://web.expasy.org/docs/userman.html}.}.
+% \begin{macrocode}
+function Protein:readUniprotFile(filename)
+ local uniprotFile, errorMsg = io.open(filename, "r")
+ if not uniprotFile then packageError(errorMsg) end
+
+% \end{macrocode}
+% Each line in a Uniprot file starts with a line code consisting of two letters. This code determines the syntax of the remainder of the line.
+% \begin{macrocode}
+ local sequence = {}
+ local inSequence = false
+ local featureTable = {}
+
+ for currLine in uniprotFile:lines() do
+ local lineCode = currLine:sub(1, 2)
+ local lineContents = currLine:sub(3)
+% \end{macrocode}
+% The \texttt{ID} line is the first line in a Uniprot file. It provides two relevant properties of the protein, namely its name and ints sequence length. For example, in the file \file{SampleUniprot.txt} (see section~\ref{sec:DomFileInput}), the \texttt{ID} line reads\\
+% |ID TestProtein Reviewed; 200 AA.|\\
+% which declares a protein with 200 residues called TestProtein.
+% \begin{macrocode}
+ if lineCode == "ID" then
+ local name, sequenceLength =
+ lineContents:match("%s*(%S+)%s*%a+;%s*(%d+)%s*AA%.")
+ self.name = name
+ self.sequenceLength = tonumber(sequenceLength)
+ self.residueRangeMax = self.sequenceLength
+% \end{macrocode}
+% \texttt{FT} lines describe features of the protein (domains, disulfides, sugars etc.). The first line of a feature always contains its key (columns 6--13) and endpoints (columns 15--20 and 22--27, respectively). The description (columns 35--75) may span several lines, in which case the key columns of consecutive lines are empty. For instance,\\
+% |FT DOMAIN 10 40 Domain 1|\\
+% declares a \texttt{DOMAIN} feature between residues 10 and 40 with description ``Domain 1''.
+% \begin{macrocode}
+ elseif lineCode == "FT" then
+ local key = currLine:sub(6, 13):trim()
+ local start, stop, description =
+ currLine:sub(15, 20), currLine:sub(22, 27), currLine:sub(35, 75)
+ if key ~= "" then
+ table.insert(featureTable, {
+ key = key,
+ start = "(" .. start .. ")",
+ stop = "(" .. stop .. ")",
+ description = description,
+ style = "",
+ kvList = ""
+ })
+ else
+ featureTable[#featureTable].description =
+ featureTable[#featureTable].description .. description
+ end
+% \end{macrocode}
+% The \texttt{SQ} line starts the sequence block. Each of the following sequence data lines lacks a line code and shows the amino acid sequence in one letter code, e.\,g.\\
+% |SQ SEQUENCE 200 AA; 22041 MW; 00A52FE2EC5431D9 CRC64;|\\
+% | MGSKRSVPSR HRSLTTYEVM FAVLFVILVA LCAGLIAVSW LSIQ| [\dots]
+% \begin{macrocode}
+ elseif lineCode == "SQ" then
+ inSequence = true
+ elseif lineCode == " " and inSequence then
+ table.insert(sequence, (lineContents:gsub("%s+", "")))
+% \end{macrocode}
+% The |\\| line terminates the Uniprot file.
+% \begin{macrocode}
+ elseif lineCode == "\\\\" then
+ break
+ end
+ end
+% \end{macrocode}
+% After closing the file, features are converted to the proper format (section~\ref{ssc:DocDomLuaProteinClass}).
+% \begin{macrocode}
+ uniprotFile:close()
+ if next(sequence) then self.sequence = table.concat(sequence) end
+ for _, v in ipairs(featureTable) do self:addFeature(v) end
+end
+
+% \end{macrocode}
+% §Protein:readGffFile§ reads the relevant parts of General Feature Format file §filename§\footnote{For a detailed description of this format, see \url{http://http://www.sanger.ac.uk/resources/software/gff/spec.html}.}.
+% \begin{macrocode}
+function Protein:readGffFile(filename)
+ local gffFile, errorMsg = io.open(filename, "r")
+ local lineContents, fields, lineNumber
+
+ if not gffFile then packageError(errorMsg) end
+% \end{macrocode}
+% Each line in a \file{gff} file describes a feature and consists of up to 9 tabulator-separated fields, of which only fields 3 (key), 4 (start) and 5 (end) are required for the \module{domains} module. Everything following the comment sign (|#|) on a line is ignored.
+% \begin{macrocode}
+ lineNumber = 1
+ for currLine in gffFile:lines() do
+ lineContents = currLine:gsub("#.*$", "")
+ fields = {}
+ if lineContents ~= "" then
+ for currField in lineContents:gmatch("([^\t]+)") do
+ table.insert(fields, currField)
+ end
+ if not fields[5] then
+ packageError("Bad line (" .. lineNumber .. ") in gff file '" ..
+ filename .. "':\n" .. currLine)
+ break
+ end
+ self:addFeature{
+ key = fields[3],
+ start = "(" .. fields[4] .. ")",
+ stop = "(" .. fields[5] .. ")",
+ description = fields[9] or "",
+ style = "",
+ kvList = ""
+ }
+ end
+ lineNumber = lineNumber + 1
+ end
+ gffFile:close()
+end
+
+% \end{macrocode}
+%
+% \subsection{Getter and Setter Methods}
+% \label{ssc:DocDomLuaParameters}
+%
+% §Protein:getParameters§ informs \TeX\ of the protein name, sequence and sequence length. This method is called after reading a Uniprot file (section~\ref{ssc:DocDomTexAddingFeatures}).
+% \begin{macrocode}
+function Protein:getParameters()
+ tex.sprint(
+ "\\pgfmolbioset[domains]{name={" ..
+ self.name ..
+ "},sequence={" ..
+ self.sequence ..
+ "},sequence length=" ..
+ self.sequenceLength ..
+ "}"
+ )
+end
+
+% \end{macrocode}
+% §Protein:setParameters§ passes options from the \module{domains} module to the Lua script. Each field of the table §keyHash§ is named after a §Protein§ attribute and represents a function that receives one string parameter (the value of a \LaTeX\ key).
+% \begin{macrocode}
+function Protein:setParameters(newParms)
+ local keyHash = {
+% \end{macrocode}
+% §keyHash.sequenceLength§ checks for an invalid sequence length.
+% \begin{macrocode}
+ sequenceLength = function(v)
+ v = tonumber(v)
+ if not v then return self.sequenceLength end
+ if v < 1 then
+ packageError("Sequence length must be larger than zero.")
+ end
+ return v
+ end,
+% \end{macrocode}
+% §keyHash.residueNumbering§ generates the residue numbering array and its inverse (described in section~\ref{ssc:DocDomLuaProteinClass}).
+% \begin{macrocode}
+ residueNumbering = function(v)
+ local ranges = {}
+ local start, startNumber, startLetter, stop
+ self.revResidueNumbering = {}
+ if v:trim() == "auto" then
+ for i = 1, self.sequenceLength do
+ table.insert(ranges, tostring(i))
+ end
+ else --example list: `1-4,5,6A-D'
+ for _, value in ipairs(v:explode(",+")) do
+ value = value:trim()
+ start, stop = value:match("(%w*)%s*%-%s*(%w*)$")
+ if not start then
+ start = value:match("(%w*)")
+ end
+ if not start or start == "" then --invalid range
+ packageError("Unknown residue numbering range: " .. value)
+ end
+ if stop then
+ if tonumber(start) and tonumber(stop) then
+ --process range `1-4'
+ for currNumber = tonumber(start), tonumber(stop) do
+ table.insert(ranges, tostring(currNumber))
+ end
+ else --process range `6A-D'
+ startNumber, startLetter = start:match("(%d*)(%a)")
+ stop = stop:match("(%a)")
+ for currLetter = startLetter:byte(), stop:byte() do
+ table.insert(ranges,
+ startNumber .. string.char(currLetter))
+ end
+ end
+ else --process range `5'
+ table.insert(ranges, start)
+ end
+ end
+ end
+ for i, value in ipairs(ranges) do
+ if self.revResidueNumbering[value] then
+ packageError("The range value " .. value ..
+ " appears more than once.")
+ else
+ self.revResidueNumbering[value] = i
+ end
+ end
+ return ranges
+ end,
+% \end{macrocode}
+% §keyHash.residueRange§ sets the residue range, treating possible errors.
+% \begin{macrocode}
+ residueRange = function(v)
+ local num
+ local residueRangeMin, residueRangeMax =
+ getRange(v:trim(), "^([%w%(%)]+)%s*%-", "%-%s*([%w%(%)]+)$")
+ if residueRangeMin == "auto" then
+ self.residueRangeMin = 1
+ else
+ num = residueRangeMin:match("%b()")
+ if num then
+ self.residueRangeMin = tonumber(num:sub(2, -2))
+ elseif self.revResidueNumbering[residueRangeMin] then
+ self.residueRangeMin = self.revResidueNumbering[residueRangeMin]
+ else
+ packageError("Invalid residue range: " .. residueRangeMin)
+ end
+ end
+
+ if residueRangeMax == "auto" then
+ self.residueRangeMax = self.sequenceLength
+ else
+ num = residueRangeMax:match("%b()")
+ if num then
+ self.residueRangeMax = tonumber(num:sub(2, -2))
+ elseif self.revResidueNumbering[residueRangeMax] then
+ self.residueRangeMax = self.revResidueNumbering[residueRangeMax]
+ else
+ packageError("Invalid residue range: " .. residueRangeMax)
+ end
+ end
+
+ if self.residueRangeMin >= self.residueRangeMax then
+ packageError("Residue range is smaller than 1.")
+ end
+ end,
+% \end{macrocode}
+% The following fields map to functions already defined.
+% \begin{macrocode}
+ defaultRulerStepSize = tonumber,
+ name = tostring,
+ sequence = tostring,
+ xUnit = stringToDim,
+ yUnit = stringToDim,
+ residuesPerLine = tonumber,
+ baselineSkip = tonumber,
+% \end{macrocode}
+% §keyHash.rulerRange§ sets the ruler range, treating possible errors and inconsistencies (for example, if the upper ruler range exceeds the upper residue range).
+% \begin{macrocode}
+ rulerRange = function(v)
+ local num
+ local ranges = {}
+ local rulerRangeMin, rulerRangeMax, rulerRangeStep
+ for _, value in ipairs(v:explode(",+")) do
+ rulerRangeMin, rulerRangeMax, rulerRangeStep =
+ getRange(value:trim(), "^([%w%(%)]+)",
+ "%-%s*([%w%(%)]+)", "step%s*(%d+)$")
+
+ if rulerRangeMin == "auto" then
+ rulerRangeMin = self.residueRangeMin
+ else
+ num = rulerRangeMin:match("%b()")
+ if num then
+ rulerRangeMin = tonumber(num:sub(2, -2))
+ elseif self.revResidueNumbering[rulerRangeMin] then
+ rulerRangeMin = self.revResidueNumbering[rulerRangeMin]
+ else
+ packageError("Invalid lower ruler range: " .. rulerRangeMin)
+ end
+ end
+
+ if rulerRangeMax then
+ if rulerRangeMax == "auto" then
+ rulerRangeMax = self.residueRangeMax
+ else
+ num = rulerRangeMax:match("%b()")
+ if num then
+ rulerRangeMax = tonumber(num:sub(2, -2))
+ elseif self.revResidueNumbering[rulerRangeMax] then
+ rulerRangeMax = self.revResidueNumbering[rulerRangeMax]
+ else
+ packageError("Invalid upper ruler range: " .. rulerRangeMax)
+ end
+ end
+
+ if rulerRangeMin >= rulerRangeMax then
+ packageError("Ruler range is smaller than 1.")
+ end
+ if rulerRangeMin < self.residueRangeMin then
+ rulerRangeMin = self.residueRangeMin
+ packageWarning(
+ "Lower ruler range is smaller than" ..
+ "lower residue range. It was adjusted to " ..
+ rulerRangeMin .. "."
+ )
+ end
+ if rulerRangeMax > self.residueRangeMax then
+ rulerRangeMax = self.residueRangeMax
+ packageWarning(
+ "Upper ruler range exceeds" ..
+ "upper residue range. It was adjusted to " ..
+ rulerRangeMax .. "."
+ )
+ end
+ else
+ rulerRangeMax = rulerRangeMin
+ end
+ rulerRangeStep = tonumber(rulerRangeStep)
+ or self.defaultRulerStepSize
+
+ for i = rulerRangeMin, rulerRangeMax, rulerRangeStep do
+ table.insert(
+ ranges,
+ {pos = i, number = self.residueNumbering[i]}
+ )
+ end
+ end
+ return ranges
+ end,
+% \end{macrocode}
+% §keyHash.showRuler§ determines if the ruler is visible.
+% \begin{macrocode}
+ showRuler = function(v)
+ if v == "true" then return true else return false end
+ end
+ }
+% \end{macrocode}
+% We iterate over all fields in the argument of §setParameters§. If a field of the same name exists in §keyHash§, we call this field with the value of the corresponding field in §newParms§ as parameter.
+% \begin{macrocode}
+ for key, value in pairs(newParms) do
+ if keyHash[key] then
+ self[key] = keyHash[key](value)
+ if pgfmolbio.errorCatched then return end
+ end
+ end
+end
+
+% \end{macrocode}
+%
+% \subsection{Adding Feature}
+% \label{ssc:DocDomLuaAddFeature}
+%
+% §Protein:addFeature§ converts raw feature information to the format of §ft§ fields (described in section~\ref{ssc:DocDomLuaProteinClass}). Firstly, the method determines the index of the style that should be used for the current feature.
+% \begin{macrocode}
+function Protein:addFeature(newFeature)
+ local baseKey, ftEntry
+
+ baseKey = self.specialKeys:getBaseKey(newFeature.key)
+ if self.currentStyle[baseKey] then
+ self.currentStyle[baseKey] = self.currentStyle[baseKey] + 1
+ else
+ self.currentStyle[baseKey] = 1
+ end
+
+% \end{macrocode}
+% Then, a new field for the feature table is set up.
+% \begin{macrocode}
+ ftEntry = {
+ key = newFeature.key,
+ start = self:toAbsoluteResidueNumber(newFeature.start),
+ stop = self:toAbsoluteResidueNumber(newFeature.stop),
+ kvList = "style={" ..
+ self.specialKeys:selectStyleFromList(baseKey,
+ self.currentStyle[baseKey]) .. "}",
+ level = newFeature.level or nil
+ }
+% \end{macrocode}
+% Finally, the key-value list §kvList§ is modified (if applicable) and the new field is inserted into §ft§.
+% \begin{macrocode}
+ if newFeature.kvList ~= "" then
+ ftEntry.kvList = ftEntry.kvList .. "," .. newFeature.kvList
+ end
+ if newFeature.description then
+ ftEntry.kvList = ftEntry.kvList ..
+ ",description={" .. newFeature.description .. "}"
+ ftEntry.description = newFeature.description
+ end
+ table.insert(self.ft, newFeature.layer or #self.ft + 1, ftEntry)
+end
+
+% \end{macrocode}
+%
+% \subsection{Calculate Disulfide Levels}
+% \label{ssc:DocDomLuaDisulfideLevels}
+%
+% §Protein:calculateDisulfideLevels§ arranges disulfide-like features in non-\hskip0ptoverlapping levels.
+% \begin{macrocode}
+function Protein:calculateDisulfideLevels()
+ if pgfmolbio.errorCatched then return end
+ local disulfideGrid, currLevel, levelFree
+ disulfideGrid = {}
+
+ for i, v in ipairs(self.ft) do
+ if self.specialKeys.disulfideKeys[v.key] then
+% \end{macrocode}
+% If the §level§ field of a disulfide-like feature is already specified, it overrides the automatic mechanism of level determination. This may lead to clashes.
+% \begin{macrocode}
+ if v.level then
+ if not disulfideGrid[v.level] then
+ disulfideGrid[v.level] = {}
+ end
+ for currPos = v.start, v.stop do
+ disulfideGrid[v.level][currPos] = true
+ end
+% \end{macrocode}
+% Otherwise, the algorithm looks for the first free level (starting at level 1), i.\,e. the first level the feature may occupy without clashing with another one. (1) If the level currently checked already exists, it has been created by a previous disulfide-like feature. In this case, it is considered free if the previous feature does not overlap with the current one.
+% \begin{macrocode}
+ else
+ currLevel = 1
+ repeat
+ levelFree = true
+ if disulfideGrid[currLevel] then
+ for currPos = v.start, v.stop do
+ levelFree = levelFree
+ and not disulfideGrid[currLevel][currPos]
+ end
+ if levelFree then
+ self.ft[i].level = currLevel
+ for currPos = v.start, v.stop do
+ disulfideGrid[currLevel][currPos] = true
+ end
+ end
+% \end{macrocode}
+% (2) If the level currently checked does not exist, it must be free.
+% \begin{macrocode}
+ else
+ self.ft[i].level = currLevel
+ disulfideGrid[currLevel] = {}
+ for currPos = v.start, v.stop do
+ disulfideGrid[currLevel][currPos] = true
+ end
+ levelFree = true
+ end
+ currLevel = currLevel + 1
+ until levelFree == true
+ end
+ end
+ end
+end
+
+% \end{macrocode}
+%
+% \subsection{Print Domains}
+% \label{ssc:DocDomLuaPrintTikzDomains}
+%
+% §Protein:printTikzDomains§ is the heart of the Lua script, since it converts a §Protein§ object to \TeX\ code.
+% \begin{macrocode}
+function Protein:printTikzDomains()
+ if pgfmolbio.errorCatched then return end
+ local xLeft, xMid, xRight, yMid, xLeftClip, xRightClip,
+ currLine, residuesLeft, currStyle
+
+% \end{macrocode}
+% \paragraph{(1) Features (excluding \texttt{other/ruler} and \texttt{other/name})} For each feature in the feature table, we first calculate its coordinates (§xLeft§, §xMid§, §xRight§ and §yMid§) and clipped areas (§xLeftClip§, §xRightClip§).
+% \begin{macrocode}
+ for _, currFeature in ipairs(self.ft) do
+ currLine = 0
+ xLeft = currFeature.start - self.residueRangeMin -
+ currLine * self.residuesPerLine + 1
+ while xLeft > self.residuesPerLine do
+ xLeft = xLeft - self.residuesPerLine
+ currLine = currLine + 1
+ end
+ xLeft = xLeft - 1
+ xRight = currFeature.stop - self.residueRangeMin -
+ currLine * self.residuesPerLine + 1
+ residuesLeft = self.residueRangeMax - self.residueRangeMin -
+ currLine * self.residuesPerLine + 1
+ xLeftClip = stringToDim("-5cm")
+ xRightClip = self.residuesPerLine * self.xUnit
+
+ if currFeature.start <= self.residueRangeMax
+ and currFeature.stop >= self.residueRangeMin then
+ repeat
+ if residuesLeft <= self.residuesPerLine then
+ if residuesLeft < xRight then
+ xRightClip = residuesLeft * self.xUnit
+ else
+ xRightClip = xRight * self.xUnit + stringToDim("5cm")
+ end
+ else
+ if xRight <= self.residuesPerLine then
+ xRightClip = xRight * self.xUnit + stringToDim("5cm")
+ end
+ end
+ if xLeft < 0 then xLeftClip = stringToDim("0cm") end
+
+ xMid = (xLeft + xRight) / 2
+ yMid = -currLine * self.baselineSkip
+% \end{macrocode}
+% The current feature is extended by any level and sequence information present.
+% \begin{macrocode}
+ if currFeature.level then
+ currFeature.kvList = currFeature.kvList ..
+ ",level=" .. currFeature.level
+ end
+ currFeature.sequence =
+ self.sequence:sub(currFeature.start, currFeature.stop)
+
+% \end{macrocode}
+% Each feature appears within its own |scope|. A |pgfinterruptboundingbox| ensures that the bounding box of the picture ignores the feature, since the |\clip| macro would enlarge it too much. Auxiliary macros for |\setfeatureshape| are defined (section~\ref{sec:DomFeatureStylesAndShapes}).
+% \begin{macrocode}
+ tex.sprint("\n\t\\begin{scope}\\begin{pgfinterruptboundingbox}")
+ tex.sprint("\n\t\t\\def\\xLeft{" ..
+ dimToString(xLeft * self.xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\xMid{" ..
+ dimToString(xMid * self.xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\xRight{" ..
+ dimToString(xRight * self.xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\yMid{" ..
+ dimToString(yMid * self.yUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\featureSequence{" ..
+ currFeature.sequence .. "}")
+ tex.sprint(
+ "\n\t\t\\clip (" ..
+ dimToString(xLeftClip) ..
+ ", \\yMid + " ..
+ dimToString(stringToDim("10cm")) ..
+ ") rectangle (" ..
+ dimToString(xRightClip) ..
+ ", \\yMid - " ..
+ dimToString(stringToDim("10cm")) ..
+ ");"
+ )
+ tex.sprint(
+ "\n\t\t\\pgfmolbioset[domains]{" ..
+ currFeature.kvList ..
+ "}"
+ )
+% \end{macrocode}
+% We invoke either the print function associated with the current feature or directly call |\pmbdomdrawfeature|. Afterwards, we close both surrounding environments.
+% \begin{macrocode}
+ if self.specialKeys.printFunctions[currFeature.key] then
+ self.specialKeys.printFunctions[currFeature.key](
+ currFeature, xLeft, xRight, yMid, self.xUnit, self.yUnit)
+ else
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{" ..
+ currFeature.key .. "}")
+ end
+ tex.sprint("\n\t\\end{pgfinterruptboundingbox}\\end{scope}")
+
+% \end{macrocode}
+% Calculate coordinates for the next line of the feature.
+% \begin{macrocode}
+ currLine = currLine + 1
+ xLeft = xLeft - self.residuesPerLine
+ xRight = xRight - self.residuesPerLine
+ residuesLeft = residuesLeft - self.residuesPerLine
+ until xRight < 1 or residuesLeft < 1
+ end
+ end
+
+% \end{macrocode}
+% \paragraph{(2) Feature \texttt{other/ruler}} The ruler requires special treatment, buth the algorithm is actually simple: For each marker, calculate its coordinates, select its style and print it.
+% \begin{macrocode}
+ if self.showRuler then
+ currStyle = 1
+ tex.sprint("\n\t\\begin{scope}")
+ for _, currRuler in ipairs(self.rulerRange) do
+ currLine = 0
+ xMid = currRuler.pos - self.residueRangeMin -
+ currLine * self.residuesPerLine + 1
+ while xMid > self.residuesPerLine do
+ xMid = xMid - self.residuesPerLine
+ currLine = currLine + 1
+ end
+ xMid = xMid - 0.5
+ yMid = -currLine * self.baselineSkip
+ tex.sprint(
+ "\n\t\t\\pgfmolbioset[domains]{current style/.style={" ..
+ self.specialKeys:selectStyleFromList("other/ruler", currStyle) ..
+ "}}"
+ )
+ tex.sprint("\n\t\t\t\\def\\xMid{" ..
+ dimToString(xMid * self.xUnit) .. "}")
+ tex.sprint("\n\t\t\t\\let\\xLeft\\xMid\\let\\xRight\\xMid")
+ tex.sprint("\n\t\t\t\\def\\yMid{" ..
+ dimToString(yMid * self.yUnit) .. "}")
+ tex.sprint("\n\t\t\t\\def\\residueNumber{" ..
+ currRuler.number .. "}")
+ tex.sprint("\n\t\t\t\\pmbdomdrawfeature{other/ruler}")
+ currStyle = currStyle + 1
+ end
+ tex.sprint("\n\t\\end{scope}")
+ end
+
+% \end{macrocode}
+% \paragraph{(3) Feature \texttt{other/name}} Similarly, we calculate the coordinates of the name and print it.
+% \begin{macrocode}
+ xMid =
+ math.min(
+ self.residuesPerLine,
+ self.residueRangeMax - self.residueRangeMin + 1
+ ) / 2
+ tex.sprint("\n\t\\begin{scope}")
+ tex.sprint(
+ "\n\t\t\\pgfmolbioset[domains]{current style/.style={" ..
+ self.specialKeys:selectStyleFromList("other/name", 1) ..
+ "}}"
+ )
+ tex.sprint("\n\t\t\\def\\xLeft{0mm}")
+ tex.sprint("\n\t\t\\def\\xMid{" .. dimToString(xMid * self.xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\xRight{" ..
+ dimToString(self.residuesPerLine * self.xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\yMid{0mm}")
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{other/name}")
+ tex.sprint("\n\t\\end{scope}")
+
+% \end{macrocode}
+% \paragraph{(4) Set bounding box} The bounding box is determined manually in order to prevent excessive enlargement due to clipping. The top left corner of the bounding box is the coordinate (|enlarge left|, |enlarge top|).
+% \begin{macrocode}
+ tex.sprint(
+ "\n\t\\pmbprotocolsizes{" ..
+ "\\pmbdomvalueof{enlarge left}}{\\pmbdomvalueof{enlarge top}}"
+ )
+% \end{macrocode}
+% The $x$-coordinate of its right border is the largest line width plus the value of |enlarge right|. The $y$-coordinate of its bottom border is that of the lowermost line plus the value of |enlarge bottom|.
+% \begin{macrocode}
+ currLine =
+ math.ceil(
+ (self.residueRangeMax - self.residueRangeMin + 1) /
+ self.residuesPerLine
+ ) - 1
+ xRight =
+ math.min(
+ self.residuesPerLine,
+ self.residueRangeMax - self.residueRangeMin + 1
+ )
+ tex.sprint(
+ "\n\t\\pmbprotocolsizes{" ..
+ dimToString(xRight * self.xUnit) ..
+ " + \\pmbdomvalueof{enlarge right}}{" ..
+ dimToString(-currLine * self.baselineSkip * self.yUnit) ..
+ " + \\pmbdomvalueof{enlarge bottom}}"
+ )
+end
+
+% \end{macrocode}
+%
+% \subsection{Converting a \texorpdfstring{\texttt{Protein}}{Protein} to a String}
+% \label{ssc:DocDomLuaTostring}
+%
+% §Protein:__tostring§ is required by the \module{convert} module and returns a |pmbdomains| environment that contains all the information stored in the §Protein§ object (section~\ref{sec:ConDomains}). Firstly, we start the environment.
+% \begin{macrocode}
+function Protein:__tostring()
+ local result = {}
+ local currLine
+
+ currLine = "\\begin{pmbdomains}\n\t\t[name={" ..
+ self.name ..
+ "}"
+ if self.sequence ~= "" then
+ currLine = currLine ..
+ ",\n\t\tsequence=" ..
+ self.sequence
+ end
+ currLine = currLine ..
+ "]{" ..
+ self.sequenceLength ..
+ "}"
+ table.insert(result, currLine)
+
+% \end{macrocode}
+% Afterwards, each feature in the feature table is converted to an |\addfeature| macro. Note the use of the §includeDescription§ field (described in section~\ref{ssc:DocDomLuaProteinClass}).
+% \begin{macrocode}
+ for i, v in ipairs(self.ft) do
+ if v.key ~= "other/main chain" then
+ currLine = "\t\\addfeature"
+ if self.includeDescription and v.description then
+ currLine =
+ currLine ..
+ "[description={" ..
+ v.description ..
+ "}]"
+ end
+ currLine =
+ currLine ..
+ "{" ..
+ v.key ..
+ "}{" ..
+ v.start ..
+ "}{" ..
+ v.stop ..
+ "}"
+ table.insert(result, currLine)
+ end
+ end
+% \end{macrocode}
+% Finally, we close the environment.
+% \begin{macrocode}
+ table.insert(result,
+ "\\end{pmbdomains}"
+ )
+ return table.concat(result, "\n")
+end
+% \end{macrocode}
+%
+% \iffalse
+%</pmb-dom-lua>
+%<*pmb-con-tex>
+% \fi
+%
+%
+%
+% \section{\texorpdfstring{\file{pgfmolbio.convert.tex}}{pgfmolbio.convert.tex}}
+% \label{sec:DocConTex}
+%
+% \def\ydoclistingssettings{\lstset{style=latex-doc}}\setcounter{lstnumber}{1}
+% The code for the \module{convert} module is short: We only need to declare four options and set |\pdfdraftmode| to 1 in order to prevent pdf\TeX\ from producing any \file{pdf} output.
+% \begin{macrocode}
+\pdfdraftmode1
+
+\pgfkeyssetvalue{/pgfmolbio/convert/output file name}{(auto)}
+\pgfkeyssetvalue{/pgfmolbio/convert/output file extension}{tex}
+
+\pgfmolbioset[convert]{%
+ output code/.is choice,
+ output code/tikz/.code=\pmb@con@outputtikzcodetrue,
+ output code/pgfmolbio/.code=\pmb@con@outputtikzcodefalse,
+ output code=tikz
+}
+
+\pgfmolbioset[convert]{%
+ include description/.is if=pmb@con@includedescription,
+ include description
+}
+% \end{macrocode}
+%
+% \iffalse
+%</pmb-con-tex>
+% \fi
+%
+% \Finale
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/pgfmolbio/pgfmolbio.ins b/macros/luatex/latex/pgfmolbio/pgfmolbio.ins
new file mode 100644
index 0000000000..94e88bfb81
--- /dev/null
+++ b/macros/luatex/latex/pgfmolbio/pgfmolbio.ins
@@ -0,0 +1,102 @@
+% pgfmolbio.ins
+%%
+%% Copyright (C) 2013 by Wolfgang Skala
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%%
+%% The Current Maintainer of this work is Wolfgang Skala.
+%%
+%% This work consists of the files pgfmolbio.dtx and pgfmolbio.ins
+%% and the derived files pgfmolbio.sty, pgfmolbio.chromatogram.tex
+%% and pgfmolbio.chromatogram.lua.
+
+\input docstrip.tex
+\keepsilent
+
+\usedir{tex/lualatex/pgfmolbio}
+
+\preamble
+
+Copyright (C) 2013 by Wolfgang Skala
+
+This work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3
+of this license or (at your option) any later version.
+The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+\endpreamble
+
+\edef\luapreamble{%
+--^^J%
+-- This is file `\outFileName ',^^J%
+-- generated with the docstrip utility.^^J%
+\ReferenceLines%
+--^^J%
+-- Copyright (C) 2013 by Wolfgang Skala^^J%
+--^^J%
+-- This work may be distributed and/or modified under the^^J%
+-- conditions of the LaTeX Project Public License, either version 1.3^^J%
+-- of this license or (at your option) any later version.^^J%
+-- The latest version of this license is in^^J%
+-- \space\space http://www.latex-project.org/lppl.txt^^J%
+-- and version 1.3 or later is part of all distributions of LaTeX^^J%
+-- version 2005/12/01 or later.^^J%
+--}
+
+\edef\luapostamble{%
+--^^J%
+--\space End of file `\outFileName'.%
+}
+
+
+\generate{%
+ \file{pgfmolbio.sty}{\from{pgfmolbio.dtx}{pgfmolbio-tex}}%
+ \file{pgfmolbio.chromatogram.tex}{\from{pgfmolbio.dtx}{pmb-chr-tex}}%
+ \file{pgfmolbio.domains.tex}{\from{pgfmolbio.dtx}{pmb-dom-tex}}%
+ \file{pgfmolbio.convert.tex}{\from{pgfmolbio.dtx}{pmb-con-tex}}
+}
+
+\def\LuaComment{--}
+\let\MetaPrefix\LuaComment
+\generate{%
+ \usepreamble\luapreamble\usepostamble\luapostamble%
+ \file{pgfmolbio.lua}{\from{pgfmolbio.dtx}{pgfmolbio-lua}}%
+ \file{pgfmolbio.chromatogram.lua}{\from{pgfmolbio.dtx}{pmb-chr-lua}}%
+ \file{pgfmolbio.domains.lua}{\from{pgfmolbio.dtx}{pmb-dom-lua}}%
+}
+
+\obeyspaces
+\Msg{****************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the}
+\Msg{* following files into a directory searched by TeX}
+\Msg{*}
+\Msg{* pgfmolbio.sty}
+\Msg{* pgfmolbio.lua}
+\Msg{* pgfmolbio.chromatogram.tex}
+\Msg{* pgfmolbio.chromatogram.lua}
+\Msg{* pgfmolbio.domains.tex}
+\Msg{* pgfmolbio.domains.lua}
+\Msg{* pgfmolbio.convert.tex}
+\Msg{*}
+\Msg{* To produce the documentation execute the}
+\Msg{* following command:}
+\Msg{*}
+\Msg{* lualatex pgfmolbio.dtx (2x)}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{****************************************************}
+
+\endbatchfile
diff --git a/macros/luatex/latex/pgfmolbio/pgfmolbio.pdf b/macros/luatex/latex/pgfmolbio/pgfmolbio.pdf
new file mode 100644
index 0000000000..4139932d7f
--- /dev/null
+++ b/macros/luatex/latex/pgfmolbio/pgfmolbio.pdf
Binary files differ
diff --git a/macros/luatex/latex/placeat/README.md b/macros/luatex/latex/placeat/README.md
new file mode 100644
index 0000000000..a521ff69d8
--- /dev/null
+++ b/macros/luatex/latex/placeat/README.md
@@ -0,0 +1,18 @@
+This is the README file of the placeat package. The package provides several commands to place content at an arbitrary position of the current page in any document. For orientation, a grid is drawn. Simple graphical elements like arrows and circles can easily be drawn and positioned.
+
+To produce the package files, run lualatex on placeat.dtx, wich should result in the creation of the following files:
+ placeat.pdf (documentation)
+ placeat.sty (LaTeX user interface)
+ placeat.lua (Lua package code)
+
+You need an up-to-date TeX Live (2017 at best) and compilation with LuaLaTeX to use this package. A full, updated MiKTeX should also work. (Not tested.)
+
+For any comments or suggestions, contact me:
+arno dot trautmann at gmx dot de
+
+Hope you have fun with this package!
+
+This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+modified under the conditions of the LaTeX Project Public License, either version 1.3c
+of this license or (at your option) any later version. This work has the LPPL mainten-
+ance status ‘maintained’.
diff --git a/macros/luatex/latex/placeat/placeat.dtx b/macros/luatex/latex/placeat/placeat.dtx
new file mode 100644
index 0000000000..90acae766c
--- /dev/null
+++ b/macros/luatex/latex/placeat/placeat.dtx
@@ -0,0 +1,813 @@
+% \iffalse
+%<*driver>
+%% File: placeat.dtx by Arno Trautmann, mail: arno dot trautmann at gmx dot de
+\iffalse
+%</driver>
+%<*readme>
+This is the README file of the placeat package. The package provides several commands to place content at an arbitrary position of the current page in any document. For orientation, a grid is drawn. Simple graphical elements like arrows and circles can easily be drawn and positioned.
+
+To produce the package files, run lualatex on placeat.dtx, wich should result in the creation of the following files:
+ placeat.pdf (documentation)
+ placeat.sty (LaTeX user interface)
+ placeat.lua (Lua package code)
+
+You need an up-to-date TeX Live (2017 at best) and compilation with LuaLaTeX to use this package. A full, updated MiKTeX should also work. (Not tested.)
+
+For any comments or suggestions, contact me:
+arno dot trautmann at gmx dot de
+
+Hope you have fun with this package!
+
+This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+modified under the conditions of the LaTeX Project Public License, either version 1.3c
+of this license or (at your option) any later version. This work has the LPPL mainten-
+ance status ‘maintained’.
+%</readme>
+%<*driver>
+\fi
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+\input docstrip.tex
+\keepsilent
+\let\MetaPrefix\relax
+\preamble
+
+EXPERIMENTAL CODE
+
+This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+modified under the conditions of the LaTeX Project Public License, either version 1.3c
+of this license or (at your option) any later version. This work has the LPPL mainten-
+ance status ‘maintained’.
+\endpreamble
+\let\MetaPrefix\DoubleperCent
+\postamble
+\endpostamble
+\askforoverwritefalse
+
+\generate{\file{placeat.sty}{\from{placeat.dtx}{package}}}
+\generate{\file{placeat.tex}{\from{placeat.dtx}{tex}}}
+\def\MetaPrefix{-- }
+\def\luapostamble{%
+ \MetaPrefix^^J%
+ \MetaPrefix\space End of File `\outFileName'.%
+}
+\def\currentpostamble{\luapostamble}%
+
+\generate{\file{placeat.lua}{\from{placeat.dtx}{lua}}}
+\nopreamble\nopostamble
+\catcode`\@12
+
+\generate{\file{README.}{\from{placeat.dtx}{readme}}}
+% readme will not be generated until I figured out how to write a file without extension
+
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+\documentclass[11pt,english]{ltxdoc}
+\usepackage{
+ array,
+ babel,
+ booktabs,
+ fontspec, %% has to be in this order because of strange check in fixltl2e …
+ float,
+ geometry,
+ graphicx,
+ hyperref,
+ microtype,
+ scrpage2,
+ tabu
+}
+\usepackage[svgnames]{xcolor}
+\hypersetup{
+ colorlinks = true,
+ linkcolor = blue,
+ filecolor = blue,
+ urlcolor = blue
+}
+
+\cfoot{\pagemark}
+\ohead{}
+\pagestyle{scrheadings}
+\setmainfont{Linux Libertine O}
+\setsansfont{Linux Biolinum O}
+
+\usepackage{placeat}
+\placeatsetup{nogrid}
+
+\def\ALT{%
+ \bgroup%
+ \fontspec{Latin Modern Sans}%
+ A%
+ \kern-.37em \raisebox{.7ex}{\scalebox{0.25}{L}}%
+ \kern-.0em \raisebox{-0.98ex}{T}%
+ \egroup%
+}
+
+\begin{document}
+\centerline{\fontsize{40}{55}\selectfont place\ALT}
+
+\centerline{v0.1d1}
+\centerline{\hspace*{2cm} Arno L. Trautmann}
+\centerline{\href{mailto:arno.trautmann@gmx.de}{arno.trautmann@gmx.de}}
+
+\kern.5cm
+\begin{abstract}
+The package \textsf{placeat} offers the command \verb|\placeat(2,5){}| which places arbitrary content freely on any page. It is mainly thought for use with the beamer class but may also be used with any other \LaTeX\ class. This package requires Lua\LaTeX; don't try it with any other \TeX\ flavour, it just won't work.
+\end{abstract}
+
+\begin{figure}[b]
+\small\noindent
+\fbox{\parbox{.97\textwidth}{
+This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+modified under the conditions of the LaTeX Project Public License, either version 1.3c
+of this license or (at your option) any later version. This work has the LPPL maintenance status ‘maintained’. Whoever notes the face in the title gets a cookie when we meet.}}
+\end{figure}
+
+\textcolor{red}{\textls{ATTENTION}} This package is in a very preliminary version and released for testing only. Any feature might be subject to changes without notice.
+
+\section*{Introduction}
+This is the documentation of the package |placeat|. When you load the package, a grid is drawn on every page of your document to aid you at placing stuff where you want it to be. This mainly makes sense in presentations, but might be used in any document. The main macro of this package \verb|\placeat...{}| offers several ways to use it:
+\begin{verbatim}
+\placeat<D4>{some content}
+\placeat(3,4){some content}
+\placeat{3}{4}{some content}
+\end{verbatim}
+
+To deactivate the grid, use the setup command \verb|\placeatsetup{nogrid}|. There are also some other commands that allow you to draw simple sketches which might be useful in presentations, too, like arrows, circles etc., but no fancy stuff.
+
+\vspace{1cm}
+
+\textcolor{red}{\emph{Attention}}: This package is under development and everything presented here might and will be subject to incompatible changes.
+
+If you have any suggestions or comments, just drop me a mail, I’ll be happy to get any response! The latest source code is hosted on github – Feel free to comment or report bugs there, to fork, pull, etc.:
+\url{https://github.com/alt/placeat}\\
+
+\newpage
+\tableofcontents
+\newpage
+\part{User Documentation}
+\section{How do I use it?}
+\subsection{Placing – the Main Commands}
+The command \verb|\placeat| takes several arguments, the last of which is the content you want to place:
+\begin{verbatim}
+\placeat(4,5){content}
+\end{verbatim}
+This may range from single letters to graphic objects or (mostly) any valid \LaTeX\ code. Take note that the content will be placed \emph{above} and \emph{right of}\footnote{See below for placing to the left via an optional argument.} the specified coordinates.\footnote{To be more precise, the ground line of the first line of the content is placed at the specified vertical coordinate. This may result in strange placement of anything that is not pure text.} Exceptions are floating environments – you have to pack them into a minipage or similar construct, see below.
+
+If you want to place something \emph{left of} the specified coordinates, there is an additional optional argument to \verb|\placeat|:
+
+\begin{verbatim}
+\placeat{4}{5}[left]{right}
+\end{verbatim}
+
+This allows you to center your content (by hand) around the given place. Do not forget to enter an empty \verb|{}| if you use only the optional content.
+
+Verbatim material does definitely \emph{not} work and makes troubles as always in moving arguments (like footnotes etc.). So far I have no idea how to handle that correctly. Please tell me any further problems, I'll happily tackle them or sadly note them here if I cannot fix it …
+
+You may use \verb|\placeat| in one of the following variants (feel free to mix them in one document):
+\begin{verbatim}
+\placeat<D5>{content-right}
+\placeat(4,5){content-right}
+\placeat{4}{5}{content}
+\end{verbatim}
+The result will be the same in all three cases, so it's just a matter of taste which one you choose. They all will place the \verb|<content>| at a position that is specified by the grid which is drawn on your document. While the grid is drawn using letters and numbers, you might prefer using two numbers as you then also can use decimals for fine tuning which is not possible with a letter-number combination:
+\begin{verbatim}
+\placeat{4.3}{5.2}{content}
+\placeat(4.3,5.2){content}
+\end{verbatim}
+Finally, there is one more argument you can give as second-to-last argument:
+\begin{verbatim}
+\placeat{4.3}{5.2}[content-left]{content}
+\placeat(4.3,5.2)[content-left]{content}
+\end{verbatim}
+This content will be placed to the left of the specified coordinates as opposed to the normal content expanding to the right.
+
+\subsection{Relative Placing}
+It is also possible to place a second element relative to another one. For this, you have to give the first one a name and refer to this name in the second one. Then you can repeat and refer a third one to the second one (or the first one, however you like to).
+\begin{verbatim}
+\placeat(4,5){content}[first]
+\placerelto[first](2,2){content2}[second]
+\placerelto[second]{2}{2}{content3}[third]
+\end{verbatim}
+Although it does not make any sense, you still can use the chess-pattern notation for |\placerelto|. But that's just for raising the obscurity level of this package.
+
+\subsection{Placing of figures, floats etc.}
+Placing figures might be a bit tricky because the placing actually places the \emph{groundline} of any object. You may make your life easier when inserting figures if you use the |[t]| argument:
+\begin{verbatim}
+\placeat{4}{5}{\includegraphics[t]{bose-gas}}
+\end{verbatim}
+This way it is easier to fit graphics at the same height. However, you might have to test where it lands in the end.
+
+For floating environments, even if they don't float (that would be stupid, wouldn't it?), you need to packg them into e.\,g. a minipage. You can do this by hand or just use the command \verb|\placeminipageat|. This command only has one kind of interface, the one with two braces:
+\begin{verbatim}
+\placeminipageat{4}{5}[4cm]{content}
+\end{verbatim}
+Here, the third, argument is optional and specifies the width of the minipage. If not given, it will default to 10cm, which should be wide enough to contain anything you ever want to set using \verb|placeat|.
+
+\subsection{User Options}
+Some of this package's features can be adjusted at any time in the document with the command
+\begin{verbatim}
+\placeatsetup{}
+\end{verbatim}
+Some of the options only make sense when used in the preamble, others only have a result when used in the text. However, none should result in an error, so feel free to do whatever nonesens you want to.
+
+\subsection{The Grid}
+If the number of grid lines does not suit you (there are ten horizontally and vertically), you can increase or decrease the number by
+\begin{verbatim}
+\placeatsetup{gridnumber = 12}
+\end{verbatim}
+You may change the gridnumber during your document, but don't expect everything to work fine.
+
+The horizontal and vertical gridnumbers can be adjusted independently:
+\begin{verbatim}
+\placeatsetup{
+ gridnumberx = 12,
+ gridnumbery = 8,
+}
+\end{verbatim}
+
+The grid can be deactivated by the document options \verb|final| or \verb|nogrid| and re-activated by the option \verb|drawgrid| in the setup macro:
+\begin{verbatim}
+\placeatsetup{nogrid}
+\placeatsetup{drawgrid}
+\end{verbatim}
+
+\subsection{Offsetting}
+You can choose the zero point of the grid by setting the options
+\begin{verbatim}
+\placeatsetup{
+ offsetx = 2
+ offsety = -1
+}
+\end{verbatim}
+The grid and placement are adapted correspondingly. If you are a C-head thinking that everything should start with 0 instead of 1, you can call
+\begin{verbatim}
+\placeatsetup{
+ startzero
+}
+\end{verbatim}
+which corresponds to |offsetx = 1,offsety = 1| so that the upper right corner has coordinates |(0,0)| instead of |(1,1)|.
+
+
+\section{Drawing simple forms}
+This package also allows to draw simple forms like arrows and circles, to support the user e.\,g. when creating presentations. A single line is drawn by calling
+\begin{verbatim}
+\placelineat(2.5,1.5)(1.5,2.5)
+\end{verbatim}
+where the first coordinate pair specifies the start of the line and the second one the end. As you typically need fine tuning to place the line exactly where you want it, it is not possible to use another interface, i.\,e. the \verb|<D4>| style.
+
+By now, the following commands and respective forms are possible:
+\begin{table}[H]
+\begin{tabu}{>{\ttfamily\textbackslash}lX}
+\toprule
+placelineat(x1,y1)(x2,y2) & Draws a single line pointing from |(x1,y1)| to |(x2,y2)|\\\midrule
+placearrowat(x1,y1)(x2,y2) & As the line, but with an arrowhead at the end.\\\midrule
+placecircleat(x,y)\{r\} & Draws a circle at position |(x,y)| with diameter |r|. If omitted, |r| will default to |3|. The diameter is not scaled to the same scale as the coordinates, and most likely you have to test what size fits. Start with~5, it's a nice number. Right now, the circle is not really a circle, but slightly deformed as we only have cubic splines. May change to something better.\\\midrule
+placesquareat(x,y)\{r\} & Draws a square with center at |(x,y)| and side lingth |r|. If omitted, |r| will default to |3|.\\\midrule
+placerectangleat(x1,y1)(x2,y2) & draws a rectangle from the (upper left) corner |(x1,y1)| to the (lower right) corner |(x2,y2)|.\\\midrule
+placefilledrectangleat(x1,y1)(x2,y2) & draws a filled rectangle.
+\\\bottomrule
+\end{tabu}
+\end{table}
+
+You can change the linewidth and therefore the thickness of lines with the simple call
+\begin{verbatim}
+\placeatsetup{linewidth=5}
+\end{verbatim}
+Default is 1, I have no idea in which unit, but it is a very nice thickness, I think. You can change the thickness any time and as often as you want.
+
+Missing are eliptical shapes, maybe rounded corners for the rectangles and maybe some funny stuff.\footnote{Yes, I \emph{will} add a penis-shape macro, but that will not be documented explicitely.} The arrowheads need a lot of work, too, of course.
+
+\subsection{Colored forms}
+You need to load the \textsc{xcolor} package to use colors.\footnote{Why is it not required in the \textsc{placeat} package? Because you might want to specify package options and that may collide with the loading here. However, every sane document working with color requires the package by default.} Every command of the ones listed above takes an optional argument that allows the specification of a color. This is based on the \textsc{xcolor}, so all colors known by that package are possible:
+
+\begin{verbatim}
+\placecircleat[blue](5,5)
+\placearrowat[green!50!yellow](6,5)(8,5)
+\placerectangleat[red!25!black](8,4)(9,6)
+\placefilledrectangleat[blue!25!red](8.5,4.5)(8.75,5.6)
+\end{verbatim}
+
+By now, it is not possible to specify an rgb code or similar. If you want a very special color that is not defined in the \textsc{xcolor} package, just define it by yourself. However, as shown above, it is possible to mix colors using the \verb|red!50!green| syntax, which is very flexible and should cover normal every day use.
+
+\section{Example}
+Now, here are two examples on how to use the package. The first one is a code example only, while the second one shows the effect directly on the page.
+
+\subsection{Example use with beamer}
+As this package makes most sense in combination with beamer, here is a small example about how to use it.
+\begin{verbatim}
+\documentclass[ngerman]{beamer}
+\usepackage{babel,blindtext}
+\usepackage{fontspec}
+\usepackage{placeat}
+\begin{document}
+\begin{frame}{Test frame}
+Test
+\placeat<D5>{Test}
+\placeminipageat{4}{5}[3cm]{\includegraphics{fermi_gas_1}}
+\end{frame}
+\end{document}
+\end{verbatim}
+
+\subsection{Example use inside this document}
+The following page is typeset using the features of this package and shows the corresponding code.
+\newpage
+\placeatsetup{drawgrid, gridnumber=15}
+However, this very page is using the \verb|drawgrid| option, with an increased grid number of 15. There are several elements placed with the given code, respectively.\footnote{Don't let me fool you, the code is not printed using \texttt{\textbackslash verb}, but only with a \texttt{\textbackslash texttt}, as verbatim is not possible with \texttt{\textbackslash placeat}.}
+\placeat<F5>{\texttt{\textbackslash placeat<F5>{}}}
+\placeat(4,7){\texttt{\textbackslash placeat(4.5,7.2){}}}
+\placeat{2.3}{4.1}{\texttt{\textbackslash placeat\{2.3\}\{4.1\}{}}}
+\placecircleat[blue](6,9)
+\placeat(6.2,9){\texttt{\textbackslash placecircleat[blue](6,9)}}
+\placearrowat[green](6,9)(8.5,5)
+\placeat(7.5,7){\texttt{\textbackslash placearrowat[green](6,9)(8.5,5)}}
+\placerectangleat[red](8,4)(9,6)
+\placeat(9.2,5){\texttt{\textbackslash placerectangleat[red](8,4)(9,6)}}
+
+\newpage
+\section{How is it done?}
+\placeatsetup{nogrid}
+The short answer is: Look at the source code. While the coding is quite simple in principle, it might be very confusing when reading it, and I am still surprised it works at all …
+
+Mainly, everything is based on the \LaTeX\ command \verb|\put(){}|. You could of course just use this, but then it's hard to get an absolute positioning as \verb|\put| only allows relative positions. You could then put your code into, say, a header line, and that is nearly the idea of this package. However, this would require a header and would not let the user freely decide what to put there. Also, users might do strange stuff to that and that could destroy the placing.
+
+Instead, we use the ability of Heiko Oberdiek's \verb|atbegshi| package which adds content to the to-be-shipped-out-page. I still do not understand how it works, but it is absolutely robust and does just what we need here: It allows to put stuff on the page relative to, say, the upper right corner. Also, it can be put in front of every other thing, so we are sure nothing gets lost.
+
+The next step is collecting and saving the material you specify to be placed somewhere. Collection is done using the \verb|xparse| package which allows for a very flexible macro definition which makes it possible to enter the different positioning options. Finally, everything is glued together with some Lua magic …
+
+We save the content to be placed in \TeX\ macros that are numbered using a Lua counter; the final coordinates are also calculated by Lua. The \TeX-Lua interface is heavily used here which is possible due to the \verb|luacode| package. The macros are then executed in the call of \verb|\AtBeginShipout|, again inside a Lua loop, where also the grid is drawn.
+
+\section{To Do}
+A list of things I would like to have solved by some time:
+\catcode`\•13
+\let•\item
+\begin{itemize}
+• allow the |wave| color model as it is very very cool
+• placing stuff at every page or reuse stuff at all
+• allow course placing (put at upper left corner, put at left side etc.) for presentations
+• verbatim in placeat
+• drawing maybe based on metapost instead of pdf drawing
+\end{itemize}
+
+\section{How can I help?}
+There are several ways how you can help. First, and most important:
+
+Testing. Try to use this code and tell me what you think about it.
+
+Bug reporting. Tell me especially what is buggy. I'd like to keep the package rather small and simple, so some bugs might be called features, but we'll see.
+
+Suggestions. I'm open to extend the functionality. Just tell me what you want and I'll try to implement it as soon as possible. Which might be never. But also maybe the next day. Well, try it!~{\huge ☺}
+
+\section{Thanks}
+Of course I have to thank Paul Isambert again for the code for drawing to the pdf file. Also I want to thank Rembrandt Wolpert who was the first one to report bugs and feature requests.
+
+\newpage
+That's it for the documentation, have fun, and\vspace{2cm}
+
+\placeat(5,7){\Huge\rotatebox{45}{Happy \TeX ing!}}[happy]
+\placecircleat[red](4,4.5)(.2)
+\placecircleat[green](9,4.5)(.2)
+\placecircleat[blue](4,7.5)(.2)
+\placecircleat[orange](9,7.5)(.2)
+
+\begin{luacode}
+for i = 1,20 do
+ tex.print("\\placecircleat[blue](12,6)("..(0.05*i)..")")
+end
+\end{luacode}
+
+
+\DocInput{placeat.dtx}
+\end{document}
+%</driver>
+%<*package>
+% \fi
+% \clearpage
+%\part{Implementation}
+%\label{sec:implementation}
+%\section{The \LaTeX\ package: placeat.sty}
+% Everything to get stuff working from the \TeX\ side. Here, only a .sty file is provided and plain/Con\TeX t users have to find their way. I'll happily support them, though!
+% \subsection{Loading Files}
+% The Lua file is not found by using a simple |dofile("placeat.lua")| call, but we have to use kpse's |find_file|.
+% \begin{macrocode}
+\ProvidesPackage{placeat}%
+ [2017/08/19 v0.1d1 absolute content positioning]
+\RequirePackage{luatexbase}
+\RequirePackage{luacode}
+\RequirePackage{atbegshi}
+\RequirePackage{xparse}
+\directlua{dofile(kpse.find_file("placeat.lua",'lua'))}
+% \end{macrocode}
+% \subsection{User Commands}
+% The main command \verb|\placeat|. There are several ways to use it, so we define a wrapper macro that is only for the user interface. Nice separation of interface and code. But actually, both are quite hard interwoven and it's not really clear at any time what happens. However, it works most of the time.
+%
+% The macro arguments of placeat at the moment are:\ \
+% |g{}g{}|: two braced arguments for coordinates\\
+% |d()|: one argument for picture-like coordinate pairs\\
+% |d<>|: one argument for alpha-numeric coordinates\\
+% |O{}|: content to be typeset on the left of the point\\
+% |m|: main content to be typeset on the right.
+% |o|: optional label for relative placement. This might now be the point to change the internal structure and go to a node mode.
+% \begin{macrocode}
+\NewDocumentCommand\placeat{ggd()d<>O{}mo}{
+ \IfValueT{#1}{ %% two coordinates in { }{ } pair.
+ \IfValueT{#2}{ %% if second argument is not given, everything breaks. not nice.
+ \def\cox{#1}
+ \def\coy{#2}
+ }
+ }
+ \IfValueT{#3}{ %% one argument as ( , ) coordinate pair.
+ \def\cox{\firstof#3X}
+ \def\coy{\secondof#3X}
+ }
+ \IfValueT{#4}{
+ \luadirect{
+ y = string.byte('#4',1)-64
+ x = string.byte('#4',2)-48
+ x2 = string.byte('#4',3)
+ if x2 then x = x*10 + x2-48 end -- FIXME: what exactly happens here? …
+ }
+ \def\cox{\luadirect{tex.print(x)}}
+ \def\coy{\luadirect{tex.print(y)}}
+ }
+ \placeatthreenumbers{\cox}{\coy}{\llap{#5}#6}
+
+ \IfValueT{#7}{
+ \expandafter\gdef\csname #7x\endcsname{\firstof#3X}
+ \expandafter\gdef\csname #7y\endcsname{\secondof#3X}
+ }
+}
+% \end{macrocode}
+% \subsection{Relative Placement}
+% The first stage of this works just the same as normal |\placeat|. However, there is an additional first optional argument that actually is \emph{not} optional! This is the node that is taken as base. So the |\placeatthreenumbers| is just called with the given coordinates added to the base coordinates.
+% \begin{macrocode}
+\NewDocumentCommand\placerelto{oggd()d<>O{}mo}{
+ \IfValueT{#2}{ %% two coordinates in { }{ } pair.
+ \IfValueT{#3}{ %% if second argument is not given, everything breaks. not nice.
+ \def\cox{#2}
+ \def\coy{#3}
+ }
+ }
+ \IfValueT{#4}{ %% one argument as ( , ) coordinate pair.
+ \def\cox{\firstof#4X}
+ \def\coy{\secondof#4X}
+ }
+ \IfValueT{#5}{
+ \luaexec{
+ y = string.byte('#5',1)-64
+ x = string.byte('#5',2)-48
+ x2 = string.byte('#5',3)
+ if x2 then x = x*10 + x2-48 end -- FIXME: what exactly happens here? …
+ tex.print("\\def\\cox{"..(x).."}\\def\\coy{"..(y).."}")
+ }
+ }
+ \placeatthreenumbers
+ {\cox + \csname #1x\endcsname}
+ {\coy + \csname #1y\endcsname}
+ {\llap{#6}#7}
+ \IfValueT{#8}{
+ \expandafter\xdef\csname #8x\endcsname{\cox + \csname #1x\endcsname}
+ \expandafter\xdef\csname #8y\endcsname{\coy + \csname #1y\endcsname}
+ }
+}
+% \end{macrocode}
+% \subsection{Placing of floats etc.}
+% For floats and similar stuff, it might be necessary or useful to pack everything into a minipage. You can do this by yourself, but I thought it might be nice to specify a corresponding user interface. Using \verb|\placeminipageat| is the same as using \verb|\placeat{}{}{content}| where content is packed into a minipage. The first two argument of \verb|\placeminipageat| must be given in braces |{4}{5}| and determine the position of the content. The third argument is optional and specifies the width of the minipage; if not give, it is assumed to be 10cm, wide enough for mostly anything you ever will place at.
+% \begin{macrocode}
+\NewDocumentCommand\placeminipageat{r()O{10cm}m}{
+ \gdef\widthofplaceat{#2}
+ \placeat(#1)
+ {\begin{minipage}{\widthofplaceat}{#3}\end{minipage}}
+}
+% \end{macrocode}
+% \subsection{Helper Macros}
+% The real stuff is done in the macro \verb|\placeatthreenumbers| which takes exactly three arguments defining the position of the content. The content is stored in a macro that is defined using Lua code, and the position is also calculated by Lua code. Everything is put together into a Lua-\TeX-bastard and surprisingly works stable as far as I can tell.
+%
+% This place is also where the offset and scaling happens.
+% \begin{macrocode}
+\def\placeatthreenumbers#1#2#3{
+ \luaexec{
+ nr = nr+1
+ dacoordtmp = ((#1-1+offsetx)*tex.pagewidth/65536/gridnrx*1.005)..","..(-(#2-1+offsety)*tex.pageheight/65536/gridnry)
+ dacoord[nr] = "\\put("..dacoordtmp..")"
+ tex.print("\\expandafter\\gdef\\csname command"..(nr).."\\endcsname")}% begin of command definition
+ {#3} %% this is what \command[nr] will contain
+}
+% \end{macrocode}
+% Two tiny helpers that might be substituted by some standard commands:
+% \begin{macrocode}
+\def\firstof #1,#2X{#1}
+\def\secondof #1,#2X{#2}
+% \end{macrocode}
+% Setup of variables and macros we need later.
+% \begin{macrocode}
+\gdef\drawgridnum{1}
+\luaexec{
+ arrowheadlength = 5
+ drawgrid = false
+ nr = 0
+ dacoord = {}
+ gridnr = 10
+ gridnrx = 10
+ gridnry = 10
+ gridlinewidth = 0.01
+ offsetx = 0
+ offsety = 0
+}
+% \end{macrocode}
+% Now the code that does the actual work here. We use Heiko Oberdiek's package \textsf{atbegshi} with the very useful macros \verb|\AtBeginShipout| and \verb|\AtBeginShipoutUpperLeftForeground|. Using these, we are free from any context of where the code is written, it is always executed at the shipout and therefore absolute positioning is possible.
+%
+% I have to use a quite weird way of checking wether to draw the grid or not, using a number instead of defining a \verb|\ifdrawgrid|. That one was working at some time, but now it is not anymore. No idea why, some handling of the input parsing in the arguments must have changed. Anyways, this is working and not too ugly, so we'll stick with that one for now.
+% \begin{macrocode}
+\AtBeginDocument{
+ \AtBeginShipout{%
+ \AtBeginShipoutUpperLeftForeground{%
+ \ifnum\drawgridnum = 1 \drawgrid\fi
+ \luaexec{%
+ for i = 1,nr do
+ tex.print(dacoord[i].."{\\csname command"..(i).."\\endcsname}")
+ end
+ nr=0
+ }
+ }
+ }
+}
+% \end{macrocode}
+% \section{The Grid}
+% The grid is made by drawing directly into the pdf as suggested by Paul Isambert in his TUGboat article “\textit{Drawing tables: Graphic fun with Lua\TeX}â€. Labeling is done by simple \verb|\put| commands, controlled via Lua code.
+% \begin{macrocode}
+\def\drawgrid{
+ \luatexlatelua{
+ pdf_print("q")
+ linewidth(gridlinewidth)
+ local factorh = tex.pageheight/gridnry/65536
+ local factorw = tex.pagewidth/gridnrx/65536
+ for i = 1,math.max(gridnrx,gridnry) do
+ h = i*factorh
+ w = i*factorw
+ move(0,-h) line(tex.pagewidth,-h) stroke()
+ move(w,0) line(w,-tex.pageheight) stroke()
+ end
+ pdf_print("Q")
+ }
+ { %% extra grouping to keep font size change local. Going to normalfont seems to make sense. An explicit font for the grid might also be nice. Implementation only upon request.
+%% would also be nice to maybe adapt the fontsize to the grid size
+ \normalfont\fontsize{8}{10}\selectfont
+ \luaexec{
+ for i=1,math.max(gridnrx+offsetx,gridnry+offsety) do
+ hfac = tex.pageheight/gridnry/65536
+ wfac = tex.pagewidth/gridnrx/65536*1.005 %% another empirical factor
+ h = (i-1)*hfac
+ w = (i-1)*wfac
+ tex.print("\\put("..(w)..",-7){\\rlap{"..(i-offsetx).."}}")
+ if alphanumgrid then
+ tex.print("\\put(0,"..(-h-0.05*hfac).."){\\char00"..(64+i-offsety).."}") %%-- for alphanumeric grid.
+ else
+ tex.print("\\put(0,"..(-h-0.05*hfac).."){"..(i-offsety).."}")
+ end
+ end
+ }
+ }
+}
+% \end{macrocode}
+% \section{Drawing Stuff}
+% Drawing is done in the same way as the grid. While the grid has no interface, the rest of the drawing stuff needs a \TeX\ interface, which is defined here. Every command calls a Lua function that does the actual work, as always.
+%
+% I try to provide a basic set of stuff that might be useful. The \TeX\ interface implementation might change, but for now it is done with xparse instead of a much more saner simple |\def|. We will see where this will head to. First, there is an arrow, whose head looks very bad. I don't know how to fix this yet. Then there are circle, square and rectangle.
+% \begin{macrocode}
+\NewDocumentCommand\placelineat{or()r()}{
+ \placeat(#2){\ignorespaces\IfValueT{#1}{\color{#1}} % only to fix the color!
+ \luatexlatelua{placelineat(#2,#3)}
+ }
+}
+\NewDocumentCommand\placearrowat{or()r()}{
+ \placeat(#2){\ignorespaces\IfValueT{#1}{\color{#1}}%
+ \luatexlatelua{placearrowat(#2,#3)}
+ }
+}
+\NewDocumentCommand\placecircleat{or()D(){.3}}{
+ \placeat(#2){\ignorespaces\IfValueT{#1}{\color{#1}}%
+ \luatexlatelua{placecircleat(#3,1)}
+ }
+}
+\NewDocumentCommand\placefilledcircleat{or()D(){.3}}{
+ \placeat(#2){\ignorespaces\IfValueT{#1}{\color{#1}}%
+ \luatexlatelua{placecircleat(#3,1,true)}
+ }
+}
+\NewDocumentCommand\placesquareat{or()G{3}}{
+ \placeat(#2){\ignorespaces\IfValueT{#1}{\color{#1}}%
+ \luatexlatelua{placesquareat(#3)}
+ }
+}
+\NewDocumentCommand\placecurveat{or()r()r()r()}{
+ \placeat(#2){\ignorespaces\IfValueT{#1}{\color{#1}}%
+ \luatexlatelua{placecurveat(#2,#3,#4,#5)}
+ }
+}
+\NewDocumentCommand\placerectangleat{O{black}r()d()}{
+ \placeat(#2){\ignorespaces\color{#1}%
+ \luatexlatelua{placerectangleat(#2,#3)}
+ }
+}
+\NewDocumentCommand\placefilledrectangleat{O{black}r()r()}{
+ \placeat(#2){\ignorespaces\color{#1}%
+ \luatexlatelua{placerectangleat(#2,#3,true)}
+ }
+}
+\NewDocumentCommand\placeroundedat{sO{black}r()D(){0.1}D<>{1.5}}{
+ \placeat(#3){\ignorespaces\color{#2}%
+ \IfBooleanTF{#1}{\luatexlatelua{placecircleat(#4,#5,true)}}%
+ {\luatexlatelua{placecircleat(#4,#5)}}
+ }
+}
+% \end{macrocode}
+% \section{Key-Value Interface}
+% It's a modern package, so we make use of \LaTeX3 once more. Let's see how stable this is. So far, no options can be used as package option, but only inside the \verb|\placeatsetup{}| macro. I'm not much into \LaTeX3 syntax and stuff anymore, so feel free to correct any non-nice coding here!
+%
+% Especially one thing will be annoying, the space-gobbling. Nice feature on one hand, but annoying inside the |\directlua| on the other hand. Therefore, we need the |~| to separate |gridnr| and |gridnry| below.
+% \begin{macrocode}
+\ExplSyntaxOn
+\gdef\drawgridnum{1}
+\keys_define:nn{placeat}{
+ alphanumgrid.code:n = \directlua{alphanumgrid = true},
+ arrowheadlength.code:n = \directlua{arrowheadlength=#1},
+ final.code:n = \luaexec{placeat_final = true} \gdef\drawgridnum{0},
+ drawgrid.code:n = \gdef\drawgridnum{1},
+ gridnumber.code:n = \directlua{gridnr = #1 gridnrx = gridnr~gridnry = gridnr},
+ gridnumberx.code:n = \directlua{gridnrx = #1},
+ gridnumbery.code:n = \directlua{gridnry = #1},
+ gridlinewidth.code:n = \directlua{gridlinewidth = #1},
+ linewidth.code:n = {\placeat(1,1){\luatexlatelua{linewidth(#1)}}}, %% FIXME: this is a very nasty hack to implement user's choice of linewidth!
+ nogrid.code:n = \gdef\drawgridnum{0},
+ numnumgrid.code:n = \directlua{alphanumgrid = false},
+ offsetx.code:n = \directlua{offsetx = #1},
+ offsety.code:n = \directlua{offsety = #1},
+ startzero.code:n = \directlua{offsetx = 1 offsety = 1}
+}
+\DeclareDocumentCommand\placeatsetup{m}{
+ \keys_set:nn{placeat}{#1}
+}
+\ExplSyntaxOff
+% \end{macrocode}
+%\iffalse
+%</package>
+%<*lua>
+%\fi
+% \section{Lua Module}
+% \label{sec:luamodule}
+% So far, the only usage of the Lua module is for graphics, based on the article by Paul Isambert about drawing directly to the pdf using Lua. We exploit this here and make use of the basic drawing functions he provided. Maybe this will be outsorced once there is a Lua-to-pdf-based graphics bundle.
+% \begin{macrocode}
+function pdf_print (...)
+ for _, str in ipairs({...}) do
+ pdf.print(str .. " ")
+ end
+ pdf.print("\n")
+end
+
+function move (p1,p2)
+ if (p2) then
+ pdf_print(p1,p2,"m")
+ else
+ pdf_print(p1[1],p1[2],"m")
+ end
+end
+
+function line(p1,p2)
+ pdf_print(p1,p2,"l")
+end
+
+function curve(p11,p12,p21,p22,p31,p32)
+ if (p22) then
+ p1,p2,p3 = {p11,p12},{p21,p22},{p31,p32}
+ else
+ p1,p2,p3 = p11,p12,p21
+ end
+ pdf_print(p1[1], p1[2],
+ p2[1], p2[2],
+ p3[1], p3[2], "c")
+end
+
+function linewidth(w)
+ pdf_print(w,"w")
+end
+
+function fill()
+ pdf_print("f")
+end
+
+function stroke()
+ pdf_print("S")
+end
+
+-- welp, let's have some fun!
+-- with the function radd, a random coordinate change is added if used
+-- randfact will adjust the amount of randomization
+-- everything is relative in the grid size
+-- BUT: In fact, do we really want to have wiggly lines? …
+local randfact = 100
+local radd = function()
+ return (math.random()-0.5)*randfact
+end
+
+function placelineat(x1,y1,x2,y2)
+ xfac = tex.pagewidth/gridnrx/65536 -- factors to convert given number to absolute coordinates
+ yfac = tex.pageheight/gridnry/65536 -- should both be global!
+ xar = (x2-x1)*xfac -- end point of the arrow
+ yar = (y1-y2)*yfac --
+ move(0,0) -- start
+ line(xar,yar) -- draw main line
+ stroke()
+end
+
+function placearrowat(x1,y1,x2,y2)
+ xfac = tex.pagewidth/gridnrx/65536 -- factors to convert given number to absolute coordinates
+ yfac = tex.pageheight/gridnry/65536 -- should both be global!
+ xar = (x2-x1)*xfac -- end point of the arrow
+ yar = (y1-y2)*yfac --
+ parx = xar/math.sqrt(xar^2+yar^2) -- direction of the arrow
+ pary = yar/math.sqrt(xar^2+yar^2) --
+ perpx = -pary -- perp of the arrow direction
+ perpy = parx --
+ move(0,0) -- start
+ line(xar,yar) -- draw main line
+ move(xar,yar)
+ line(xar-arrowheadlength*parx+arrowheadlength*perpx,yar-arrowheadlength*pary+arrowheadlength*perpy) -- draw arrowhead
+ move(xar,yar)
+ line(xar-arrowheadlength*parx-arrowheadlength*perpx,yar-arrowheadlength*pary-arrowheadlength*perpy)
+ stroke()
+end
+
+-- better circle-approximation by using quarter circles, according to wikipedia article about Bézier curves
+-- k = 1 gives a circle, everything else something else …
+function placecircleat(r,k,filled)
+ local P0,P1,P2,P3
+ r = r * 59.5 -- next arbitrary scale factor; the circle has radius "1" in x-units
+ local rk = 0.55228*r*k
+
+ P0 = {r,0}
+ move (P0[1],P0[2])
+
+ P1 = {r,rk} P2 = {rk,r} P3 = {0,r}
+ curve (P1,P2,P3)
+
+ P1 = {-rk,r} P2 = {-r,rk} P3 = {-r,0}
+ curve (P1,P2,P3)
+
+ P1 = {-r,-rk} P2 = {-rk,-r} P3 = {0,-r}
+ curve (P1,P2,P3)
+
+ P1 = {rk,-r} P2 = {r,-rk} P3 = {r,0}
+ curve (P1,P2,P3)
+
+ if filled then
+ fill()
+ end
+ stroke()
+end
+
+function placesquareat(length)
+ move (-length,-length)
+ line ( length,-length)
+ line ( length, length)
+ line (-length, length)
+ line (-length,-length)
+ stroke()
+end
+
+function placecurveat(x1,y1,x2,y2,x3,y3,x4,y4) -- start point and three numbers. Start is only offset.
+ xfac = tex.pagewidth/gridnrx/65536 -- factors to convert given number to absolute coordinates
+ yfac = tex.pageheight/gridnry/65536 -- should both be global!
+ x2 = (x2-x1)*xfac
+ y2 = (y2-y1)*yfac
+ x3 = (x3-x1)*xfac
+ y3 = (y3-y1)*yfac
+ x4 = (x4-x1)*xfac
+ y4 = (y4-y1)*yfac
+ move(0,0) -- start
+ curve(x2,-y2,x3,-y3,x4,-y4) -- coordinates for Bezier curve
+ stroke()
+end
+
+function placerectangleat(x1,y1,x2,y2,filled)
+ xfac = tex.pagewidth/gridnrx/65536
+ yfac = tex.pageheight/gridnry/65536
+ x2 = (x2-x1)*xfac
+ y2 = (y1-y2)*yfac
+ move(0,0)
+ line(x2,0)
+ line(x2,y2)
+ line(0,y2)
+ line(0,0)
+ if filled then
+ fill()
+ end
+ stroke()
+end
+% \end{macrocode}
+% \Finale
+% \endinput
diff --git a/macros/luatex/latex/placeat/placeat.lua b/macros/luatex/latex/placeat/placeat.lua
new file mode 100644
index 0000000000..898ff9a3ca
--- /dev/null
+++ b/macros/luatex/latex/placeat/placeat.lua
@@ -0,0 +1,162 @@
+--
+-- This is file `placeat.lua',
+-- generated with the docstrip utility.
+--
+-- The original source files were:
+--
+-- placeat.dtx (with options: `lua')
+--
+-- EXPERIMENTAL CODE
+--
+-- This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+-- modified under the conditions of the LaTeX Project Public License, either version 1.3c
+-- of this license or (at your option) any later version. This work has the LPPL mainten-
+-- ance status ‘maintained’.
+function pdf_print (...)
+ for _, str in ipairs({...}) do
+ pdf.print(str .. " ")
+ end
+ pdf.print("\n")
+end
+
+function move (p1,p2)
+ if (p2) then
+ pdf_print(p1,p2,"m")
+ else
+ pdf_print(p1[1],p1[2],"m")
+ end
+end
+
+function line(p1,p2)
+ pdf_print(p1,p2,"l")
+end
+
+function curve(p11,p12,p21,p22,p31,p32)
+ if (p22) then
+ p1,p2,p3 = {p11,p12},{p21,p22},{p31,p32}
+ else
+ p1,p2,p3 = p11,p12,p21
+ end
+ pdf_print(p1[1], p1[2],
+ p2[1], p2[2],
+ p3[1], p3[2], "c")
+end
+
+function linewidth(w)
+ pdf_print(w,"w")
+end
+
+function fill()
+ pdf_print("f")
+end
+
+function stroke()
+ pdf_print("S")
+end
+
+-- welp, let's have some fun!
+-- with the function radd, a random coordinate change is added if used
+-- randfact will adjust the amount of randomization
+-- everything is relative in the grid size
+-- BUT: In fact, do we really want to have wiggly lines? …
+local randfact = 100
+local radd = function()
+ return (math.random()-0.5)*randfact
+end
+
+function placelineat(x1,y1,x2,y2)
+ xfac = tex.pagewidth/gridnrx/65536 -- factors to convert given number to absolute coordinates
+ yfac = tex.pageheight/gridnry/65536 -- should both be global!
+ xar = (x2-x1)*xfac -- end point of the arrow
+ yar = (y1-y2)*yfac --
+ move(0,0) -- start
+ line(xar,yar) -- draw main line
+ stroke()
+end
+
+function placearrowat(x1,y1,x2,y2)
+ xfac = tex.pagewidth/gridnrx/65536 -- factors to convert given number to absolute coordinates
+ yfac = tex.pageheight/gridnry/65536 -- should both be global!
+ xar = (x2-x1)*xfac -- end point of the arrow
+ yar = (y1-y2)*yfac --
+ parx = xar/math.sqrt(xar^2+yar^2) -- direction of the arrow
+ pary = yar/math.sqrt(xar^2+yar^2) --
+ perpx = -pary -- perp of the arrow direction
+ perpy = parx --
+ move(0,0) -- start
+ line(xar,yar) -- draw main line
+ move(xar,yar)
+ line(xar-arrowheadlength*parx+arrowheadlength*perpx,yar-arrowheadlength*pary+arrowheadlength*perpy) -- draw arrowhead
+ move(xar,yar)
+ line(xar-arrowheadlength*parx-arrowheadlength*perpx,yar-arrowheadlength*pary-arrowheadlength*perpy)
+ stroke()
+end
+
+-- better circle-approximation by using quarter circles, according to wikipedia article about Bézier curves
+-- k = 1 gives a circle, everything else something else …
+function placecircleat(r,k,filled)
+ local P0,P1,P2,P3
+ r = r * 59.5 -- next arbitrary scale factor; the circle has radius "1" in x-units
+ local rk = 0.55228*r*k
+
+ P0 = {r,0}
+ move (P0[1],P0[2])
+
+ P1 = {r,rk} P2 = {rk,r} P3 = {0,r}
+ curve (P1,P2,P3)
+
+ P1 = {-rk,r} P2 = {-r,rk} P3 = {-r,0}
+ curve (P1,P2,P3)
+
+ P1 = {-r,-rk} P2 = {-rk,-r} P3 = {0,-r}
+ curve (P1,P2,P3)
+
+ P1 = {rk,-r} P2 = {r,-rk} P3 = {r,0}
+ curve (P1,P2,P3)
+
+ if filled then
+ fill()
+ end
+ stroke()
+end
+
+function placesquareat(length)
+ move (-length,-length)
+ line ( length,-length)
+ line ( length, length)
+ line (-length, length)
+ line (-length,-length)
+ stroke()
+end
+
+function placecurveat(x1,y1,x2,y2,x3,y3,x4,y4) -- start point and three numbers. Start is only offset.
+ xfac = tex.pagewidth/gridnrx/65536 -- factors to convert given number to absolute coordinates
+ yfac = tex.pageheight/gridnry/65536 -- should both be global!
+ x2 = (x2-x1)*xfac
+ y2 = (y2-y1)*yfac
+ x3 = (x3-x1)*xfac
+ y3 = (y3-y1)*yfac
+ x4 = (x4-x1)*xfac
+ y4 = (y4-y1)*yfac
+ move(0,0) -- start
+ curve(x2,-y2,x3,-y3,x4,-y4) -- coordinates for Bezier curve
+ stroke()
+end
+
+function placerectangleat(x1,y1,x2,y2,filled)
+ xfac = tex.pagewidth/gridnrx/65536
+ yfac = tex.pageheight/gridnry/65536
+ x2 = (x2-x1)*xfac
+ y2 = (y1-y2)*yfac
+ move(0,0)
+ line(x2,0)
+ line(x2,y2)
+ line(0,y2)
+ line(0,0)
+ if filled then
+ fill()
+ end
+ stroke()
+end
+--
+-- End of File `placeat.lua'.
diff --git a/macros/luatex/latex/placeat/placeat.pdf b/macros/luatex/latex/placeat/placeat.pdf
new file mode 100644
index 0000000000..31a1adbddd
--- /dev/null
+++ b/macros/luatex/latex/placeat/placeat.pdf
Binary files differ
diff --git a/macros/luatex/latex/placeat/placeat.sty b/macros/luatex/latex/placeat/placeat.sty
new file mode 100644
index 0000000000..1fec067a56
--- /dev/null
+++ b/macros/luatex/latex/placeat/placeat.sty
@@ -0,0 +1,223 @@
+%%
+%% This is file `placeat.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% placeat.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+%% modified under the conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version. This work has the LPPL mainten-
+%% ance status ‘maintained’.
+\ProvidesPackage{placeat}%
+ [2017/08/19 v0.1d1 absolute content positioning]
+\RequirePackage{luatexbase}
+\RequirePackage{luacode}
+\RequirePackage{atbegshi}
+\RequirePackage{xparse}
+\directlua{dofile(kpse.find_file("placeat.lua",'lua'))}
+\NewDocumentCommand\placeat{ggd()d<>O{}mo}{
+ \IfValueT{#1}{ %% two coordinates in { }{ } pair.
+ \IfValueT{#2}{ %% if second argument is not given, everything breaks. not nice.
+ \def\cox{#1}
+ \def\coy{#2}
+ }
+ }
+ \IfValueT{#3}{ %% one argument as ( , ) coordinate pair.
+ \def\cox{\firstof#3X}
+ \def\coy{\secondof#3X}
+ }
+ \IfValueT{#4}{
+ \luadirect{
+ y = string.byte('#4',1)-64
+ x = string.byte('#4',2)-48
+ x2 = string.byte('#4',3)
+ if x2 then x = x*10 + x2-48 end -- FIXME: what exactly happens here? …
+ }
+ \def\cox{\luadirect{tex.print(x)}}
+ \def\coy{\luadirect{tex.print(y)}}
+ }
+ \placeatthreenumbers{\cox}{\coy}{\llap{#5}#6}
+
+ \IfValueT{#7}{
+ \expandafter\gdef\csname #7x\endcsname{\firstof#3X}
+ \expandafter\gdef\csname #7y\endcsname{\secondof#3X}
+ }
+}
+\NewDocumentCommand\placerelto{oggd()d<>O{}mo}{
+ \IfValueT{#2}{ %% two coordinates in { }{ } pair.
+ \IfValueT{#3}{ %% if second argument is not given, everything breaks. not nice.
+ \def\cox{#2}
+ \def\coy{#3}
+ }
+ }
+ \IfValueT{#4}{ %% one argument as ( , ) coordinate pair.
+ \def\cox{\firstof#4X}
+ \def\coy{\secondof#4X}
+ }
+ \IfValueT{#5}{
+ \luaexec{
+ y = string.byte('#5',1)-64
+ x = string.byte('#5',2)-48
+ x2 = string.byte('#5',3)
+ if x2 then x = x*10 + x2-48 end -- FIXME: what exactly happens here? …
+ tex.print("\\def\\cox{"..(x).."}\\def\\coy{"..(y).."}")
+ }
+ }
+ \placeatthreenumbers
+ {\cox + \csname #1x\endcsname}
+ {\coy + \csname #1y\endcsname}
+ {\llap{#6}#7}
+ \IfValueT{#8}{
+ \expandafter\xdef\csname #8x\endcsname{\cox + \csname #1x\endcsname}
+ \expandafter\xdef\csname #8y\endcsname{\coy + \csname #1y\endcsname}
+ }
+}
+\NewDocumentCommand\placeminipageat{r()O{10cm}m}{
+ \gdef\widthofplaceat{#2}
+ \placeat(#1)
+ {\begin{minipage}{\widthofplaceat}{#3}\end{minipage}}
+}
+\def\placeatthreenumbers#1#2#3{
+ \luaexec{
+ nr = nr+1
+ dacoordtmp = ((#1-1+offsetx)*tex.pagewidth/65536/gridnrx*1.005)..","..(-(#2-1+offsety)*tex.pageheight/65536/gridnry)
+ dacoord[nr] = "\\put("..dacoordtmp..")"
+ tex.print("\\expandafter\\gdef\\csname command"..(nr).."\\endcsname")}% begin of command definition
+ {#3} %% this is what \command[nr] will contain
+}
+\def\firstof #1,#2X{#1}
+\def\secondof #1,#2X{#2}
+\gdef\drawgridnum{1}
+\luaexec{
+ arrowheadlength = 5
+ drawgrid = false
+ nr = 0
+ dacoord = {}
+ gridnr = 10
+ gridnrx = 10
+ gridnry = 10
+ gridlinewidth = 0.01
+ offsetx = 0
+ offsety = 0
+}
+\AtBeginDocument{
+ \AtBeginShipout{%
+ \AtBeginShipoutUpperLeftForeground{%
+ \ifnum\drawgridnum = 1 \drawgrid\fi
+ \luaexec{%
+ for i = 1,nr do
+ tex.print(dacoord[i].."{\\csname command"..(i).."\\endcsname}")
+ end
+ nr=0
+ }
+ }
+ }
+}
+\def\drawgrid{
+ \luatexlatelua{
+ pdf_print("q")
+ linewidth(gridlinewidth)
+ local factorh = tex.pageheight/gridnry/65536
+ local factorw = tex.pagewidth/gridnrx/65536
+ for i = 1,math.max(gridnrx,gridnry) do
+ h = i*factorh
+ w = i*factorw
+ move(0,-h) line(tex.pagewidth,-h) stroke()
+ move(w,0) line(w,-tex.pageheight) stroke()
+ end
+ pdf_print("Q")
+ }
+ { %% extra grouping to keep font size change local. Going to normalfont seems to make sense. An explicit font for the grid might also be nice. Implementation only upon request.
+%% would also be nice to maybe adapt the fontsize to the grid size
+ \normalfont\fontsize{8}{10}\selectfont
+ \luaexec{
+ for i=1,math.max(gridnrx+offsetx,gridnry+offsety) do
+ hfac = tex.pageheight/gridnry/65536
+ wfac = tex.pagewidth/gridnrx/65536*1.005 %% another empirical factor
+ h = (i-1)*hfac
+ w = (i-1)*wfac
+ tex.print("\\put("..(w)..",-7){\\rlap{"..(i-offsetx).."}}")
+ if alphanumgrid then
+ tex.print("\\put(0,"..(-h-0.05*hfac).."){\\char00"..(64+i-offsety).."}") %%-- for alphanumeric grid.
+ else
+ tex.print("\\put(0,"..(-h-0.05*hfac).."){"..(i-offsety).."}")
+ end
+ end
+ }
+ }
+}
+\NewDocumentCommand\placelineat{or()r()}{
+ \placeat(#2){\ignorespaces\IfValueT{#1}{\color{#1}} % only to fix the color!
+ \luatexlatelua{placelineat(#2,#3)}
+ }
+}
+\NewDocumentCommand\placearrowat{or()r()}{
+ \placeat(#2){\ignorespaces\IfValueT{#1}{\color{#1}}%
+ \luatexlatelua{placearrowat(#2,#3)}
+ }
+}
+\NewDocumentCommand\placecircleat{or()D(){.3}}{
+ \placeat(#2){\ignorespaces\IfValueT{#1}{\color{#1}}%
+ \luatexlatelua{placecircleat(#3,1)}
+ }
+}
+\NewDocumentCommand\placefilledcircleat{or()D(){.3}}{
+ \placeat(#2){\ignorespaces\IfValueT{#1}{\color{#1}}%
+ \luatexlatelua{placecircleat(#3,1,true)}
+ }
+}
+\NewDocumentCommand\placesquareat{or()G{3}}{
+ \placeat(#2){\ignorespaces\IfValueT{#1}{\color{#1}}%
+ \luatexlatelua{placesquareat(#3)}
+ }
+}
+\NewDocumentCommand\placecurveat{or()r()r()r()}{
+ \placeat(#2){\ignorespaces\IfValueT{#1}{\color{#1}}%
+ \luatexlatelua{placecurveat(#2,#3,#4,#5)}
+ }
+}
+\NewDocumentCommand\placerectangleat{O{black}r()d()}{
+ \placeat(#2){\ignorespaces\color{#1}%
+ \luatexlatelua{placerectangleat(#2,#3)}
+ }
+}
+\NewDocumentCommand\placefilledrectangleat{O{black}r()r()}{
+ \placeat(#2){\ignorespaces\color{#1}%
+ \luatexlatelua{placerectangleat(#2,#3,true)}
+ }
+}
+\NewDocumentCommand\placeroundedat{sO{black}r()D(){0.1}D<>{1.5}}{
+ \placeat(#3){\ignorespaces\color{#2}%
+ \IfBooleanTF{#1}{\luatexlatelua{placecircleat(#4,#5,true)}}%
+ {\luatexlatelua{placecircleat(#4,#5)}}
+ }
+}
+\ExplSyntaxOn
+\gdef\drawgridnum{1}
+\keys_define:nn{placeat}{
+ alphanumgrid.code:n = \directlua{alphanumgrid = true},
+ arrowheadlength.code:n = \directlua{arrowheadlength=#1},
+ final.code:n = \luaexec{placeat_final = true} \gdef\drawgridnum{0},
+ drawgrid.code:n = \gdef\drawgridnum{1},
+ gridnumber.code:n = \directlua{gridnr = #1 gridnrx = gridnr~gridnry = gridnr},
+ gridnumberx.code:n = \directlua{gridnrx = #1},
+ gridnumbery.code:n = \directlua{gridnry = #1},
+ gridlinewidth.code:n = \directlua{gridlinewidth = #1},
+ linewidth.code:n = {\placeat(1,1){\luatexlatelua{linewidth(#1)}}}, %% FIXME: this is a very nasty hack to implement user's choice of linewidth!
+ nogrid.code:n = \gdef\drawgridnum{0},
+ numnumgrid.code:n = \directlua{alphanumgrid = false},
+ offsetx.code:n = \directlua{offsetx = #1},
+ offsety.code:n = \directlua{offsety = #1},
+ startzero.code:n = \directlua{offsetx = 1 offsety = 1}
+}
+\DeclareDocumentCommand\placeatsetup{m}{
+ \keys_set:nn{placeat}{#1}
+}
+\ExplSyntaxOff
+%%
+%%
+%% End of file `placeat.sty'.
diff --git a/macros/luatex/latex/placeat/placeat.tex b/macros/luatex/latex/placeat/placeat.tex
new file mode 100644
index 0000000000..459dbbf10d
--- /dev/null
+++ b/macros/luatex/latex/placeat/placeat.tex
@@ -0,0 +1,17 @@
+%%
+%% This is file `placeat.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% placeat.dtx (with options: `tex')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+%% modified under the conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version. This work has the LPPL mainten-
+%% ance status ‘maintained’.
+%%
+%%
+%% End of file `placeat.tex'.
diff --git a/macros/luatex/latex/plantuml/CHANGELOG.md b/macros/luatex/latex/plantuml/CHANGELOG.md
new file mode 100644
index 0000000000..5c84bfc5b2
--- /dev/null
+++ b/macros/luatex/latex/plantuml/CHANGELOG.md
@@ -0,0 +1,50 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/)
+and this project adheres to [Semantic Versioning](http://semver.org/).
+
+## [0.2.3] - 2018-06-04
+
+## Added
+
+- Add `release.sh` to CTAN upload-
+
+## Removed
+
+- Removed `\usepackage{aeguill}` as 1) PlantUML seems not to rely on it any more and 2) [it is obsolete and should not be used anymore](https://tex.stackexchange.com/a/5901/9075).
+
+## [0.2.2] - 2018-03-22
+
+## Changed
+
+- Added version number in generated `plantuml.pdf`.
+- Do not strip down `README.md` for CTAN anymore and provide "*.png" for generation of `plantuml.pdf`.
+
+## [0.2.1] - 2018-03-21
+
+### Fixed
+
+- Added short version of `README.md` to CTAN distribution again, because of [CTAN rules](https://mirror.informatik.hs-fulda.de/tex-archive/help/ctan/CTAN-upload-addendum.html#readme).
+
+## [0.2.0] - 2018-03-20
+
+### Changed
+
+- `README.md` is not distributed to CTAN anymore, because `plantuml.pdf` is distributed to follow latex software conventions to name the manual according to the name of the package.
+ `plantuml.pdf` generated out of `README.md`.
+- Removed call to `pdfcrop` is not necessary anymore, because inkscape is called without `-D` for svg convertion.
+
+### Added
+
+- `release.sh` for creating a release.
+
+## 0.1.0 - 2018-03-08
+
+Initial public release
+
+[unreleased]: https://github.com/latextemplates/plantuml/compare/0.2.3...HEAD
+[0.2.3]: https://github.com/latextemplates/plantuml/compare/0.2.2...0.2.3
+[0.2.2]: https://github.com/latextemplates/plantuml/compare/0.2.1...0.2.2
+[0.2.1]: https://github.com/latextemplates/plantuml/compare/0.2.0...0.2.1
+[0.2.0]: https://github.com/latextemplates/plantuml/compare/0.1.0...0.2.0
diff --git a/macros/luatex/latex/plantuml/README.md b/macros/luatex/latex/plantuml/README.md
new file mode 100644
index 0000000000..531ee379f2
--- /dev/null
+++ b/macros/luatex/latex/plantuml/README.md
@@ -0,0 +1,104 @@
+# plantuml
+
+Version 0.2.3
+
+> A LuaLaTeX package for PlantUML in LaTeX
+
+[PlantUML](http://plantuml.com/) is a program which transforms text into UML diagrams.
+This package allows for embedding PlantUML diagrams using the PlantUML source.
+
+Currently, this project runs with [lualatex](http://www.luatex.org/) only.
+Check [issue #1](https://github.com/latextemplates/plantuml/issues/1) for the current state of affairs for support pdflatex.
+
+## Preconditions
+
+1. Environment variable `PLANTUML_JAR` set to the location of `plantuml.jar`.
+ You get it from <https://sourceforge.net/projects/plantuml/files/plantuml.jar/download>.
+2. Enviroment variable `GRAPHVIZ_DOT` set to the location of `dot.exe`.
+ Example: `C:\Program Files (x86)\Graphviz2.38\bin\dot.exe`.
+ You can install graphviz using `choco install graphviz`.
+3. lualatex available with command line parameter `-shell-escape` included.
+4. In case you want to have the images as PDFs (and not using TikZ or PNG), ensure that `inkscape.exe` and `pdfcrop` are in your path.
+ You can get inkscape using `choco install inkscape`.
+ `pdfcrop` should be part of your latex distribution.
+
+## Examples
+
+### Minimal Example
+
+**LaTeX source:**
+
+```latex
+\documentclass{scrartcl}
+\usepackage{plantuml}
+\begin{document}
+\begin{plantuml}
+ @startuml
+ Alice -> Bob: test
+ @enduml
+\end{plantuml}
+\end{document}
+```
+
+**Compilation:** `lualatex -shell-escape example-minimal`
+
+**Result:**
+
+![Minimal example](example-minimal.png)
+
+### Example Class Relations Rendered Using SVG
+
+**LaTeX source:**
+
+```latex
+\documentclass{scrartcl}
+\usepackage{graphics}
+\usepackage{epstopdf}
+\epstopdfDeclareGraphicsRule{.svg}{pdf}{.pdf}{
+ inkscape -z --file=#1 --export-pdf=\OutputFile
+}
+\usepackage[output=svg]{plantuml}
+\begin{document}
+\begin{plantuml}
+@startuml
+class Car
+
+Driver - Car : drives >
+Car *- Wheel : have 4 >
+Car -- Person : < owns
+@enduml
+\end{plantuml}
+\end{document}
+```
+
+**Compilation:** `lualatex -shell-escape example-class-relations`
+
+**Result:**
+
+![Class relations rendered using SVG](example-class-relations--svg.png)
+
+## Installation
+
+Your latex distribution should take care.
+
+For manual installation, copy `plantuml.*` to your local texmf folder in the subdirectoy `tex/latex/plantuml`.
+See [the discussion at tex.sx](https://tex.stackexchange.com/q/27982/9075) for the concrete location of the folder on your system.
+
+## Development
+
+The release is built at [CircleCI](http://circleci.com/) using [release.sh](release.sh).
+
+Release prepration:
+
+1. Adapt date and version number in `plantuml.sty`.
+1. Adapt `CHANGELOG.md`.
+1. Set a git tag and push.
+
+## Alternative Solutions
+
+[TikZ-UML](https://perso.ensta-paristech.fr/~kielbasi/tikzuml/) is a very powerful package based in [TikZ](https://www.ctan.org/pkg/pgf).
+More alternative solutions are collected at the [CTAN topic UML](https://www.ctan.org/topic/uml).
+
+## License
+
+`SPDX-License-Identifier: LPPL-1.3c+`
diff --git a/macros/luatex/latex/plantuml/example-class-relations--latex.tex b/macros/luatex/latex/plantuml/example-class-relations--latex.tex
new file mode 100644
index 0000000000..190b2f5668
--- /dev/null
+++ b/macros/luatex/latex/plantuml/example-class-relations--latex.tex
@@ -0,0 +1,19 @@
+\documentclass{scrartcl}
+
+\usepackage{graphics}
+
+\usepackage[output=latex]{plantuml}
+% Have sans serif font at each tikz diagram. Source: https://tex.stackexchange.com/a/4888/9075
+\tikzstyle{every picture}+=[font=\sffamily]
+
+\begin{document}
+\begin{plantuml}
+@startuml
+class Car
+
+Driver - Car : drives >
+Car *- Wheel : have 4 >
+Car -- Person : < owns
+@enduml
+\end{plantuml}
+\end{document}
diff --git a/macros/luatex/latex/plantuml/example-class-relations--svg.png b/macros/luatex/latex/plantuml/example-class-relations--svg.png
new file mode 100644
index 0000000000..2461e00812
--- /dev/null
+++ b/macros/luatex/latex/plantuml/example-class-relations--svg.png
Binary files differ
diff --git a/macros/luatex/latex/plantuml/example-class-relations--svg.tex b/macros/luatex/latex/plantuml/example-class-relations--svg.tex
new file mode 100644
index 0000000000..5d7d9b8ed8
--- /dev/null
+++ b/macros/luatex/latex/plantuml/example-class-relations--svg.tex
@@ -0,0 +1,26 @@
+\documentclass{scrartcl}
+
+\usepackage{graphics}
+
+% Enables inclusion of SVG graphics - 1:1 approach
+% This is NOT the approach of https://ctan.org/pkg/svg-inkscape
+% which allows text in SVG to be typeset using LaTeX.
+% We just include the SVG as is.
+\usepackage{epstopdf}
+\epstopdfDeclareGraphicsRule{.svg}{pdf}{.pdf}{%
+ inkscape -z --file=#1 --export-pdf=\OutputFile
+}
+
+\usepackage[output=svg]{plantuml}
+
+\begin{document}
+\begin{plantuml}
+@startuml
+class Car
+
+Driver - Car : drives >
+Car *- Wheel : have 4 >
+Car -- Person : < owns
+@enduml
+\end{plantuml}
+\end{document}
diff --git a/macros/luatex/latex/plantuml/example-minimal.png b/macros/luatex/latex/plantuml/example-minimal.png
new file mode 100644
index 0000000000..7699a8b185
--- /dev/null
+++ b/macros/luatex/latex/plantuml/example-minimal.png
Binary files differ
diff --git a/macros/luatex/latex/plantuml/example-minimal.tex b/macros/luatex/latex/plantuml/example-minimal.tex
new file mode 100644
index 0000000000..36c0dac014
--- /dev/null
+++ b/macros/luatex/latex/plantuml/example-minimal.tex
@@ -0,0 +1,9 @@
+\documentclass{scrartcl}
+\usepackage{plantuml}
+\begin{document}
+\begin{plantuml}
+@startuml
+Alice -> Bob: test
+@enduml
+\end{plantuml}
+\end{document}
diff --git a/macros/luatex/latex/plantuml/plantuml.lua b/macros/luatex/latex/plantuml/plantuml.lua
new file mode 100644
index 0000000000..d94e93b5b4
--- /dev/null
+++ b/macros/luatex/latex/plantuml/plantuml.lua
@@ -0,0 +1,48 @@
+-- SPDX-License-Identifier: LPPL-1.3c+
+
+require "lfs"
+
+-- @param mode directly passed to PlantUML. Recommended: png, svg, pdf (requires Apache Batik to convert svg to pdf)
+function convertPlantUmlToTikz(jobname, mode)
+ local plantUmlSourceFilename = jobname .. "-plantuml.txt"
+ local plantUmlTargetFilename = jobname .. "-plantuml." .. mode
+
+ -- delete generated file to ensure they are really recreated
+ os.remove(plantUmlTargetFilename)
+
+ if not (lfs.attributes(plantUmlSourceFilename)) then
+ texio.write_nl("Source " .. plantUmlSourceFilename .. " does not exist.")
+ return
+ end
+
+ local plantUmlJar = os.getenv("PLANTUML_JAR")
+ if not plantUmlJar then
+ texio.write_nl("Environment variable PLANTUML_JAR not set.")
+ return
+ end
+
+ texio.write("Executing PlantUML... ")
+ local cmd = "java -jar " .. plantUmlJar .. " -t"
+ if (mode == "latex") then
+ cmd = cmd .. "latex:nopreamble"
+ else
+ cmd = cmd .. mode
+ end
+ cmd = cmd .. " " .. plantUmlSourceFilename
+ texio.write_nl(cmd)
+ local handle,error = io.popen(cmd)
+ if not handle then
+ texio.write_nl("Error during execution of PlantUML.")
+ texio.write_nl(error)
+ return
+ end
+ io.close(handle)
+
+ if not (lfs.attributes(plantUmlTargetFilename)) then
+ texio.write_nl("PlantUML did not generate anything.")
+ handle = io.open(plantUmlTargetFilename, "w")
+ handle:write("Error during latex code generation")
+ io.close(handle)
+ return
+ end
+end
diff --git a/macros/luatex/latex/plantuml/plantuml.pdf b/macros/luatex/latex/plantuml/plantuml.pdf
new file mode 100644
index 0000000000..7c9d89e4c3
--- /dev/null
+++ b/macros/luatex/latex/plantuml/plantuml.pdf
Binary files differ
diff --git a/macros/luatex/latex/plantuml/plantuml.sty b/macros/luatex/latex/plantuml/plantuml.sty
new file mode 100644
index 0000000000..d6777ed44e
--- /dev/null
+++ b/macros/luatex/latex/plantuml/plantuml.sty
@@ -0,0 +1,101 @@
+%% Copyright (C) 2018 Oliver Kopp, https://github.com/koppor
+%%
+%% SPDX-License-Identifier: LPPL-1.3c+
+\NeedsTeXFormat{LaTeX2e}\relax
+\ProvidesPackage{plantuml}
+ [2018/03/22 v0.2.2
+ Embed PlantUML diagrams in latex documents.]
+
+% Required by PlantUML LaTeX output
+\RequirePackage{tikz}
+
+% Enable checking for active -shell-escape
+% Source: https://tex.stackexchange.com/a/88620/9075
+\RequirePackage{pdftexcmds}
+
+% Prepare writing contents of a self-defined environment to a file
+% Source: https://tex.stackexchange.com/a/130298/9075
+\RequirePackage{fancyvrb}
+
+\RequirePackage{l3keys2e}
+\RequirePackage{xparse}
+
+\RequirePackage{ifthen}
+
+\RequirePackage{adjustbox}
+
+\ExplSyntaxOn
+\keys_define:nn { plantuml } {
+ output .choices:nn = {
+ {latex, png, svg}
+ { \tl_gset:NV \l_plantuml_mode \l_keys_choice_tl }
+ },
+ output .initial:n = latex
+}
+\ProcessKeysOptions { plantuml }
+\ExplSyntaxOff
+
+%hint from https://tex.stackexchange.com/a/86355/9075
+\makeatletter
+\def\maxwidth#1{\ifdim\Gin@nat@width>#1 #1\else\Gin@nat@width\fi}
+\makeatother
+
+\ExplSyntaxOn
+\let\PlantUmlMode\l_plantuml_mode
+\ExplSyntaxOff
+
+\newcounter{PlantUmlFigureNumber}
+
+\ifluatex
+ \RequirePackage{luacode}
+\else
+ \RequirePackage[usefamily=bash]{pythontex}
+\fi
+
+\makeatletter
+\ifcase\pdf@shellescape
+ \message{No shell escape. PlantUML cannot be called. Start pdflatex/lualatex with -shell-escape.}
+ \newenvironment{plantuml}{%
+ No shell escape. PlantUML cannot be called. Start pdflatex/lualatex with -shell-escape.
+ }{}
+\or
+ \ifluatex
+ \directlua{
+ local plantUmlJar = os.getenv("PLANTUML_JAR")
+ if not plantUmlJar then
+ texio.write_nl("Environment variable PLANTUML_JAR not set.")
+ end
+ }
+ \fi
+ \NewDocumentEnvironment{plantuml}{}{%
+ \VerbatimOut{\jobname-plantuml.txt}}
+ {%
+ \endVerbatimOut
+ \ifluatex
+ \directlua{
+ local jobname=\luastring{\jobname}
+ local plantUmlMode=\luastring{\PlantUmlMode}
+ require("plantuml.lua")
+ convertPlantUmlToTikz(jobname, plantUmlMode)
+ }
+ \else
+ \stepcounter{PlantUmlFigureNumber}
+ %TODO: Execute pyhton here
+ \typeout{*** plantuml only works with lualatex ***}
+ \fi
+ \ifthenelse{\equal{\PlantUmlMode}{latex}}{
+ \begin{adjustbox}{max width=\linewidth}
+ \input{\jobname-plantuml.latex}
+ \end{adjustbox}
+ }{
+ \includegraphics[width=\maxwidth{\textwidth}]{\jobname-plantuml.\PlantUmlMode}
+ }
+ }
+\or
+ \message{Restricted shell escape. PlantUML cannot be called. Start pdflatex/lualatex with -shell-escape.}
+ \newenvironment{plantuml}{%
+ Restricted shell escape. PlantUML cannot be called. Start pdflatex/lualatex with -shell-escape.
+ }{}
+\fi
+\makeatother
+
diff --git a/macros/luatex/latex/plantuml/release.sh b/macros/luatex/latex/plantuml/release.sh
new file mode 100755
index 0000000000..bf8bbd5444
--- /dev/null
+++ b/macros/luatex/latex/plantuml/release.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+TAG=`git describe --abbrev=0 --tags`
+
+# remove shields.io badge
+sed -i "s/# plantuml.*/# plantuml\n\nVersion $TAG/" README.md
+
+# generate plantuml.pdf based on README.md based on pandoc 2.x
+pandoc README.md --pdf-engine=lualatex -o plantuml.pdf
+
+# Prepare for CTAN
+ctanify --notds plantuml.sty plantuml.lua plantuml.pdf README.md CHANGELOG.md release.sh "example-*.tex" "example-*.png"
diff --git a/macros/luatex/latex/selnolig/README b/macros/luatex/latex/selnolig/README
new file mode 100644
index 0000000000..6fa78bb1a8
--- /dev/null
+++ b/macros/luatex/latex/selnolig/README
@@ -0,0 +1,25 @@
+The selnolig package suppresses typographic ligatures selectively, i.e., based
+on predefined search patterns. The search patterns identify ligatures that are
+deemed inappropriate because they span morpheme boundaries. For example, the
+word *shelfful*, which is mentioned in the TeXbook as a word for which the "ff"
+ligature might be inappropriate, is automatically typeset as shelf{}ful,
+i.e., without the ff ligature.
+
+For English and German language documents, the selnolig package provides
+extensive rules for the selective suppression of so-called "common" ligatures.
+These comprise the ff, fi, fl, ffi, and ffl ligatures as well as the ft and
+fft ligatures. Other f-ligatures, such as fb, fh, fj and fk, are suppressed
+globally. However, the package provides exceptions for names and words of
+non-English/German origin, such as fjord and Kafka.
+
+For English language documents, the package further provides ligature
+suppression rule for a number of so-called "discretionary" or "rare"
+ligatures, such as ct, st, and sp.
+
+The package's user guide is in the file selnolig.pdf. If you're not (yet)
+familiar with this package, you may want to at least skim the user guide in
+order to get a sense of how the package may be used.
+
+The selnolig package requires use of the LuaLaTeX format provided by a recent
+TeX distribution, such as TeXLive2015 or MiKTeX2.9.
+
diff --git a/macros/luatex/latex/selnolig/gpp-ft.fea b/macros/luatex/latex/selnolig/gpp-ft.fea
new file mode 100644
index 0000000000..d7422ed83c
--- /dev/null
+++ b/macros/luatex/latex/selnolig/gpp-ft.fea
@@ -0,0 +1,23 @@
+# OpenType feature file to suppress the "rare" f_t.alt
+# ligature provided by the font "Garamond Premier Pro".
+# This feature file is employed by selnolig.tex, the
+# user guide for the 'selnolig' package.
+# Created by Mico Loretan, January 2013, based on
+# important (crucial!) help provided by Khaled Hosny
+# (see http://tex.stackexchange.com/q/89963/5001).
+
+# Scripts and languages
+# If the font uses others, they should be defined here too
+languagesystem DFLT dflt;
+languagesystem latn dflt;
+
+# Undo the "f_t.alt" discretionary ligature
+feature dlig {
+ sub f_t.alt by f t;
+} dlig;
+
+# Apply the regular ligatures for ft and fft
+feature liga {
+ sub f f t by f_f_t;
+ sub f t by f_t;
+} liga; \ No newline at end of file
diff --git a/macros/luatex/latex/selnolig/selnolig-bugreport.tex b/macros/luatex/latex/selnolig/selnolig-bugreport.tex
new file mode 100644
index 0000000000..328c608dc7
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig-bugreport.tex
@@ -0,0 +1,35 @@
+% !TEX TS-program = lualatex
+% selnolig-bugreport.tex, 2015/10/26
+
+\documentclass{article}
+\usepackage[margin=1in]{geometry}
+\usepackage{fontspec}
+% Choose a different font if desired:
+\setmainfont{EB Garamond 12 Regular}
+
+% Comment out the next instruction if you don't use babel;
+% and set the language version that meets your needs.
+\usepackage[ngerman]{babel}
+
+% Choose either ngerman or english as the language option
+\usepackage[ngerman]{selnolig}
+
+\begin{document}
+\paragraph*{Version of selnolig package used:}
+\selnoligpackageversion, \selnoligpackagedate
+ % these macros are defined in selnolig.sty
+
+\subsection*{Type-I errors: Words that contain ligatures that should be suppressed}
+
+[List words here]
+
+\subsection*{Type-II errors: Words for which ligatures are being suppressed improperly}
+
+[List words here]
+
+\subsection*{Other issues}
+
+Examples: problems with user guide; problems caused by the package's lua code
+
+(and, please, suggestions for bug fixes)
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/selnolig/selnolig-english-hyphex.sty b/macros/luatex/latex/selnolig/selnolig-english-hyphex.sty
new file mode 100644
index 0000000000..92a1f504c1
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig-english-hyphex.sty
@@ -0,0 +1,212 @@
+% !TeX root = selnolig.tex
+% !TEX TS-program = lualatex
+
+\ProvidesPackage{selnolig-english-hyphex}%
+[2015/10/26]
+
+% This entire package is placed under the
+% terms of the LaTeX Project Public License,
+% version 1.3 or later
+% (http://www.latex-project.org/lppl.txt).
+% It has the status "maintained".
+%
+% Author: Mico Loretan
+% (loretan dot mico at gmail dot com)
+
+
+\hyphenation{re-roof re-roof-ing
+ be-dwarf be-dwarf-ing be-gulf be-gulf-ing feoff en-feoff in-feoff
+ re-staff re-stuff
+ dam-sel dam-sel-fish dam-sel-fly dam-sel-flies
+ dis-tel-fink but-ter-fin-ger
+ man-tel-shelf man-tel-shelf-ful man-tel-shelf-fuls
+ dwarf-ish elf-ish oaf-ish serf-ish un-self-ish wolf-ish draff-ish
+ gi-raff-ish raff-ish
+ dwarf-ish-ness elf-ish-ness oaf-ish-ness serf-ish-ness un-self-ish-ness
+ wolf-ish-ness
+ beef-i-est comf-i-est goof-i-est gulf-i-est leaf-i-est surf-i-est
+ turf-i-est
+ goof-i-ness
+ cuff-less turf-less
+ calf-like dwarf-like elf-like gulf-like hoof-like leaf-like roof-like
+ serf-like sheaf-like shelf-like surf-like turf-like waif-like wolf-like
+ cliff-like
+ half-life half-lives shelf-life shelf-lives half-line half-lines
+ roof-line roof-lines roof-tree roof-trees
+ leaf-let leaf-lets leaf-leted leaf-let-ing leaf-let-ting leaf-let-ted
+ leaf-le-teer pdf-latex
+ baff-ing chaff-ing coiff-ing daff-ing en-feoff-ing in-feoff-ing
+ feoff-ing gaff-ing piaff-ing quaff-ing re-staff-ing re-stuff-ing
+ sclaff-ing over-staff-ing un-der-staff-ing staff-ing waff-ing yaff-ing
+ buff-i-est chaff-i-est chuff-i-est cliff-i-est daff-i-est fluff-i-est
+ gruff-i-est huff-i-est iff-i-est miff-i-est puff-i-est scruff-i-est
+ sniff-i-est snuff-i-est spiff-i-est stuff-i-est
+ daff-i-ness fluff-i-ness gruff-i-ness huff-i-ness iff-i-ness puff-i-ness
+ scruff-i-ness sniff-i-ness snuff-i-ness spiff-i-ness stuff-i-ness
+ baff-ies biff-ies jiff-ies taff-ies toff-ies waff-ies
+ Pfaff-ian Wolff-ian Wulff-ian
+ scoff-law scoff-laws cuff-link cuff-links off-load off-loads
+ off-load-ing
+ off-line ruff-like
+ chaf-finch chaf-finches wolf-fish
+ fif-ties fif-ti-eth fif-ti-eths fif-ty-ish
+ half-tone half-tones roof-top roof-tops
+ bat-house boat-house cat-house proph-et-hood rat-hole
+ boat-hook meat-hook pot-hook
+ foot-hold root-hold ant-hill foot-hill goat-herd neat-herd
+ boat-houses cat-houses rat-holes boat-hooks meat-hooks pot-hooks
+ foot-holds root-holds ant-hills foot-hills goat-herds neat-herds
+ apart-heid anti-apart-heid dust-heap dust-heaps
+ night-hawk night-hawks pot-hunt post-hu-mous wart-hog wart-hogs
+ watt-hour watt-hours kilo-watt-hour kilo-watt-hours
+ pot-hold-ers
+ pains-taker pains-tak-ing dogs-tail cross-talk gas-tight
+ off-key
+ blog-o-sphere arc-tan-gent co-arc-ta-tion ant-arc-tica ant-arc-tic
+ busi-ness-per-son con-gress-per-son crafts-per-son drafts-per-son
+ news-per-son spokes-per-son
+ dis-pir-its dis-pir-it-ing dis-pir-it-ed-ness
+ dis-pa-rate dis-pa-rate-ness dis-par-ag-ing
+ dis-pel-ling dis-pen-sa-ries dis-pen-sa-to-ries dis-pens-ers
+ dis-pers-ers dis-pers-ible dis-pit-eous dis-play-able
+ dis-pos-ers dis-plum-ing
+ dis-put-able dis-put-ably dis-put-ant dis-put-ants
+ mono-dis-perse non-dis-pers-ive
+ in-dis-put-able in-dis-put-ably in-dis-put-able-ness
+ un-dis-put-able wolf-hound
+ trans-pa-ci-fic ca-tas-tro-phe
+ tran-spond tran-spon-der co-respond trans-pla-cen-tal
+ leaf-hop-per leaf-hop-pers
+ al-a-bas-ter anti-pasto sea-strand sto-chas-tic
+ dis-trib-ute dis-trib-uted
+ be-thank be-thorn be-thought be-thump fire-thorn
+ flame-thrower none-the-less re-thread white-throat
+ nine-ti-eth nine-ti-eths Beet-hoven breth-ren
+ le-thal le-thar-gic meth-a-done non-eth-i-cal
+ cath-o-lic ca-thol-i-cism
+ name-tag name-tags re-table re-tab-les time-table
+ re-tie re-teach re-tile re-tint re-ti-tle
+ bud-get-ary di-et-ary pro-pri-e-tary
+ cov-et-able de-plet-able get-able in-ter-pret-able
+ mar-ket-able pock-et-able veg-e-ta-ble
+ cen-trip-e-tal pet-al skel-e-tal so-ci-e-tal
+ tris-kai-deka-pho-bia raths-kel-ler
+ mis-keep mis-kept mis-know
+ greens-keep-ers grounds-keep-ers
+ an-i-mal-like jew-el-like drive-train
+ in-tra-spe-cies
+ trans-pierce de-tick blue-tick
+ for-tune-tell-ing for-tune-tell-ers
+ pre-term pre-test pre-ti-tling
+ en-tire-ties sure-ties scho-las-tic scho-las-tics
+ mega-star meta-sta-ble
+ ca-thar-sis cath-e-ter mar-a-thon
+ tri-ath-lon tri-ath-lete eth-ane
+ an-ti-sag an-ti-slip in-fra-struc-ture me-tath-e-sis
+ mega-spore mega-spores tetra-spore tetra-spores
+ safe-ties ar-che-type ar-che-typ-al
+ or-tho-don-tist or-tho-don-tia
+ cliff-hang-ers cliff-jump cliff-jump-ers
+ pre-eth-i-cal teeth-ridge teeth-ridges
+ free-think-ers rijst-tafel
+ re-treat-ant re-treat-ants re-treat-ers
+ re-trourse retro re-trorse re-try re-try-ing
+ ret-ro-act ret-ro-acts ret-ro-ac-ted ret-ro-ac-ting
+ ret-ro-ac-tion ret-ro-ac-tions
+ ret-ro-ac-tive ret-ro-ac-tively
+ ret-ro-ac-ti-vi-ties ret-ro-ac-ti-vity
+ ret-ro-cede ret-ro-ceded ret-ro-cedes ret-ro-ced-ing
+ ret-ro-ces-sion ret-ro-ces-sions
+ ret-ro-dict ret-ro-dicts ret-ro-dicted ret-ro-dict-ing
+ ret-ro-dic-tion ret-ro-dic-tions ret-ro-dic-tive
+ ret-ro-fire ret-ro-fired ret-ro-fires ret-ro-fir-ing
+ ret-ro-fit ret-ro-fits ret-ro-fit-ted ret-ro-fit-ting
+ ret-ro-flec-tion ret-ro-flec-tions
+ ret-ro-flex ret-ro-flex-ion ret-ro-flex-ions
+ ret-ro-gra-da-tion ret-ro-gra-da-tions
+ ret-ro-grade ret-ro-graded
+ ret-ro-gress ret-ro-gress-ion ret-ro-gress-ions
+ ret-ro-gress-ive ret-ro-gress-ively
+ ret-ro-pack ret-ro-packs
+ ret-ro-pe-ri-ton-eal ret-ro-pe-ri-ton-e-ally
+ ret-ro-re-flec-tion ret-ro-re-flec-tions ret-ro-re-flec-tive
+ ret-ro-re-flec-tor ret-ro-re-flec-tors
+ ret-ro-rocket ret-ro-rockets
+ ret-ro-spect ret-ro-spects ret-ro-spected ret-ro-specting
+ ret-ro-spection ret-ro-spections
+ ret-ro-spective ret-ro-spectively ret-ro-spectives
+ ret-ro-version ret-ro-versions
+ ret-ro-viral ret-ro-virus ret-ro-viruses
+ re-twist re-twists re-twisted re-twist-ing
+ fore-tell-ers fore-tell-ing
+ pre-tele-vi-sion pre-the-ater
+ re-team re-teamed re-team-ing re-teams
+ re-tear re-tears re-tear-ing
+ re-test re-tests re-test-ing re-tests
+ re-tic-u-lo-en-do-the-lial re-tic-u-lum
+ re-tie re-ties re-tied
+ re-tighten re-tight-ened re-tight-en-ing re-tight-ens
+ re-tiled re-tiles re-til-ing
+ ret-ina ret-i-nae ret-i-nas ret-i-nal ret-i-nal
+ ret-ina-cula ret-ina-cu-lum ret-i-form
+ cats-kills peeks-kill gott-hard det-ri-ment
+ che-tah
+}
+
+\ifnum\righthyphenmin=2
+ \hyphenation{beef-i-er cliff-i-er comf-i-er goof-i-er gulf-i-er
+ leaf-i-er surf-i-er turf-i-er
+ dwarf-ish-ly elf-ish-ly oaf-ish-ly serf-ish-ly un-self-ish-ly
+ wolf-ish-ly wolf-fish-ly
+ fif-ty
+ buff-i-er chaff-i-er chuff-i-er daff-i-er fluff-i-er gruff-i-er
+ huff-i-er iff-i-er miff-i-er puff-i-er scruff-i-er sniff-i-er
+ snuff-i-er spiff-i-er stuff-i-er
+ elf-in
+ sniff-i-ly snuff-i-ly spiff-i-ly stuff-i-ly
+ beef-i-ly goof-i-ly
+ cuff-less-ly
+ aloof-ly brief-ly chief-ly lief-ly
+ bluff-ly gruff-ly ruff-ly snuff-ly stiff-ly
+ draff-ish-ly gi-raff-ish-ly raff-ish-ly daff-i-ly fluff-i-ly
+ gruff-i-ly huff-i-ly puff-i-ly scruff-i-ly
+ pot-hold-er post-hu-mous-ly
+ off-hand-ed off-load-ed
+ rath-er slath-er
+ trans-per-son-al sphe-ric-i-ty cis-plat-in
+ dis-pir-it dis-pir-it-ed dis-pir-it-ed-ly dis-pir-it-ed-ness-es
+ dis-pa-rate-ly dis-par-ag-ing-ly dis-pa-rate-ness-es
+ dis-pen-sa-ry dis-pen-sa-to-ry dis-pens-er un-dis-put-ed
+ in-tra-spe-cif-ic in-fra-spe-cif-ic
+ cliff-hang-er cliff-jump-er
+ pleth-o-ra meth-od
+ greens-keep-er grounds-keep-er for-tune-tell-er
+ in-tra-tho-rac-ic aro-ma-ther-a-py
+ ar-che-typ-al free-think-er
+ in-fra-spe-cif-ic in-tra-spe-cif-ic}
+\else
+ \hyphenation{beef-ier comf-ier goof-ier gulf-ier leaf-ier surf-ier
+ turf-ier
+ dwarf-ishly elf-ishly oaf-ishly serf-ishly un-self-ishly
+ wolfish-ly wolf-fishly
+ buff-ier chaff-ier chuff-ier cliff-ier daff-ier fluff-ier gruff-ier
+ huff-ier iff-ier miff-ier puff-ier scruff-ier sniff-ier snuff-ier
+ spiff-ier
+ stuff-ier sniff-ily snuff-ily spiff-ily stuff-ily
+ beef-ily goof-ily
+ cuff-lessly
+ draff-ishly gi-raff-ishly raff-ishly daff-ily fluff-ily gruff-ily
+ huff-ily puff-ily scruff-ily
+ pot-holder post-hu-mously
+ off-handed off-loaded
+ trans-per-sonal sphe-ric-ity cis-platin
+ dis-pirit dis-pir-ited dis-pir-it-edly dis-pir-it-ed-nesses
+ dis-pa-rately dis-par-ag-ingly dis-pa-rate-nesses
+ dis-pen-sary dis-pen-sa-tory dis-penser un-dis-puted
+ in-tra-spe-cific in-fra-spe-cific
+ pleth-ora
+ greens-keeper grounds-keeper for-tune-teller
+ in-tra-tho-racic aro-ma-ther-apy
+ ar-che-typal cliff-hanger cliff-jumper
+ free-thinker}
+\fi
diff --git a/macros/luatex/latex/selnolig/selnolig-english-patterns.sty b/macros/luatex/latex/selnolig/selnolig-english-patterns.sty
new file mode 100644
index 0000000000..a5d0c5a756
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig-english-patterns.sty
@@ -0,0 +1,1125 @@
+% !TeX root = selnolig.tex
+% !TEX TS-program = lualatex
+
+\ProvidesPackage{selnolig-english-patterns}%
+[2015/10/26]
+
+% This entire package is placed under the
+% terms of the LaTeX Project Public License,
+% version 1.3 or later
+% (http://www.latex-project.org/lppl.txt).
+% It has the status "maintained".
+%
+% Author: Mico Loretan
+% (loretan dot mico at gmail dot com)
+
+
+% Part 1: "Basic" f-ligature patterns
+% ===================================
+
+% (a) ff -> f-f
+
+\nolig{lfful}{lf|ful}
+ % shelfful bookshelffuls -- TeXBook, p. 19
+
+% (b) fi -> f-i
+ % no cases in 'basic' group
+
+% (c) fl -> f-l
+
+\nolig{fless}{f|less}
+ % beefless leafless ...
+ % Also: cuffless stuffless
+
+\nolig{flike}{f|like}
+ % dwarflike elflike ...
+ % Also: rufflike clifflike
+
+\nolig{flife}{f|life}
+ % halflife shelflife
+
+\nolig{flive}{f|live}
+ % halflives shelflives
+
+\nolig{fline}{f|line}
+ % halfline roofline offline
+
+\nolig{eaflet}{eaf|let}
+ % leaflet(-s, -ed) leafleting
+ % leafletting leafletted
+ % leafleteer(s)
+
+\nolig{pdflatex}{pdf|latex}
+\nolig{Pdflatex}{Pdf|latex}
+ % better, though, to write 'pdf\LaTeX'
+
+\nolig{otfload}{otf|load}
+ % for the 'luaotfload' package...
+
+% (d) ffi -> ff-i
+
+\nolig{faffian}{faff|ian}
+ % Pfaffian
+ % (must avoid picking up 'affianced')
+
+\nolig{lffian}{lff|ian}
+ % Wolffian Wulffian
+
+% (e) ffl -> ff-l
+
+\nolig{fflaw}{ff|law}
+ % scofflaw scofflaws
+
+\nolig{fflink}{ff|link}
+ % cufflink cufflinks
+
+\nolig{ffload}{ff|load}
+ % offload offloads offloaded
+
+% (f) ffi -> f-fi
+
+\nolig{haffinch}{haf|finch}
+ % chaffinch(es)
+
+\nolig{lffish}{lf|fish}
+ % wolffish
+
+% (g) ffl -> f-fl
+
+\nolig{afflower}{af|flower}
+ % safflower
+
+% (h) ft -> f-t
+
+\if@noftligs % suppress ft ligatures globally
+ \nolig{ft}{f|t}
+\else % suppress ft ligatures selectively...
+ \nolig{ieftain}{ief|tain}
+ \nolig{alftime}{alf|time}
+ \nolig{alftone}{alf|tone}
+ \nolig{ooftop}{oof|top}
+ \nolig{ooftree}{oof|tree}
+ % chieftain halftime halftone
+ % rooftop rooftree
+
+ \nolig{ifth}{if|th}
+ % fifth(s)
+ \nolig{elfth}{elf|th}
+ % twelfth(s)
+
+ \nolig{lftr}{lf|tr}
+ % wolftrap calftrap
+
+ \nolig{eaftr}{eaf|tr}
+ % leaftrap
+
+ \nolig{fftr}{ff|tr}
+ % offtrack
+\fi % end of \if@noftligs conditional block
+
+% (i) fb, fh, fj, and fk ligatures
+
+% suppress these ligatures globally
+\nolig{fb}{f|b}
+\nolig{fh}{f|h}
+\nolig{fj}{f|j}
+\nolig{fk}{f|k}
+
+% But, make exceptions for fjord, fjell, etc
+ \keeplig{fjord} % Norwegian spelling
+ \keeplig{fjör} % Icelandic spelling, e.g., in
+ % Isafjördur and Ãsafjörður
+ \keeplig{fjarð} % Ãsafjarðarbær (in Iceland)
+ \keeplig{fjell} % Norwegian
+ \keeplig{fjall} % Swedish (?)
+ \keeplig{fjäll}
+ \keeplig{fjöll}
+
+ \keeplig{Prokofjew}
+ \keeplig{Sufjan} % Stevens
+ \keeplig{Eefje} % Dutch first name
+ \keeplig{Astafjew}
+ % Author (Wiktor) and soccer player (Maksim)
+
+% Further exceptions for names that contain 'fk'
+ \keeplig{Kafka}
+ \keeplig{Safka}
+ \keeplig{Potrafke}
+ \keeplig{Sprafke}
+ \keeplig{Shirafkan}
+ \keeplig{Tirafkan}
+ \keeplig{Rifkin}
+
+
+
+% Part 2: Additional f-ligature suppression
+% patterns if the 'broadf' option is set.
+% =========================================
+
+\if@broadfset
+
+% (a) ff -> f-f
+ % no cases in 'broad' group
+
+% (b) fi -> f-i
+
+\nolig{elfin}{elf|in}
+\nolig{Elfin}{Elf|in}
+ \keeplig{elfink} % distelfink
+
+% For words ending in -f-ing, allow for
+% "colloquial" abbreviations (-f-in').
+\nolig{afing}{af|ing}
+\nolig{afin'}{af|in'}
+ % chafing leafing loafing sheafing
+ % strafing vouchsafing
+
+\nolig{eefing}{eef|ing}
+\nolig{eefin'}{eef|in'}
+% beefing reefing
+
+\nolig{iefing}{ief|ing}
+\nolig{iefin'}{ief|in'}
+% briefing debriefing
+
+\nolig{ifing}{if|ing}
+\nolig{ifin'}{if|in'}
+ % coifing fifing jackknifing knifing
+ % midwifing waifing wifing
+
+\nolig{oofing}{oof|ing}
+\nolig{oofin'}{oof|in'}
+ % goofing hoofing roofing ...
+
+\nolig{lfing}{lf|ing}
+\nolig{lfin'}{lf|in'}
+ % golfing rolfing selfing ...
+
+\nolig{rfing}{rf|ing}
+\nolig{rfin'}{rf|in'}
+ % barfing bedwarfing dwarfing...
+ % kerfing enserfing ...
+ % (wind-) surfing turfing
+ \keeplig{tterfinger} % butterfinger
+
+\nolig{rfism}{rf|ism}
+ % dwarfism
+
+\nolig{rfist}{rf|ist}
+ % dwarfist
+
+\nolig{deafish}{deaf|ish}
+\nolig{dwarfish}{dwarf|ish}
+\nolig{elfish}{elf|ish}
+ % elfish selfish unselfish, etc.
+ \keeplig{amselfish} % damselfish
+
+\nolig{oafish}{oaf|ish}
+\nolig{serfish}{serf|ish}
+\nolig{wolfish}{wolf|ish}
+
+\nolig{Deafish}{Deaf|ish}
+\nolig{Dwarfish}{Dwarf|ish}
+\nolig{Elfish}{Elf|ish}
+\nolig{Oafish}{Oaf|ish}
+\nolig{Serfish}{Serf|ish}
+\nolig{Wolfish}{Wolf|ish}
+
+\nolig{beefier}{beef|ier}
+\nolig{comfier}{comf|ier}
+\nolig{goofier}{goof|ier}
+\nolig{gulfier}{gulf|ier}
+\nolig{leafier}{leaf|ier}
+\nolig{reefier}{reef|ier}
+\nolig{surfier}{surf|ier}
+\nolig{turfier}{turf|ier}
+
+\nolig{Beefier}{Beef|ier}
+\nolig{Comfier}{Comf|ier}
+\nolig{Goofier}{Goof|ier}
+\nolig{Gulfier}{Gulf|ier}
+\nolig{Leafier}{Leaf|ier}
+\nolig{Reefier}{Reef|ier}
+\nolig{Surfier}{Surf|ier}
+\nolig{Turfier}{Turf|ier}
+ % (Mustn't perform 'fier -> f-ier'
+ % substitution because of words
+ % such as pacifier, reifier, etc.)
+
+\nolig{fiest}{f|iest}
+ \keeplig{fiesta}
+ % leafiest beefiest reefiest ...
+
+\nolig{fily}{f|ily}
+ % beefily goofily
+ % This rule also catches the
+ % ffily -> ff-ily case:
+ % daffily fluffily gruffily ...
+
+\nolig{oofiness}{oof|iness}
+ % goofiness
+ % (Mustn't do 'finess -> f-iness'
+ % substitution b/c of 'finesse')
+
+% (c) fl -> f-l
+
+\nolig{aloofly}{aloof|ly}
+\nolig{briefly}{brief|ly}
+\nolig{chiefly}{chief|ly}
+\nolig{deafly}{deaf|ly}
+\nolig{liefly}{lief|ly}
+
+\nolig{Aloofly}{Aloof|ly}
+\nolig{Briefly}{Brief|ly}
+\nolig{Chiefly}{Chief|ly}
+\nolig{Deafly}{Deaf|ly}
+\nolig{Liefly}{Lief|ly}
+ % (Mustn't perform 'fly -> f-ly' subst.
+ % b/c of 'fly' 'butterfly' ...)
+
+% (d) ffi -> ff-i
+
+\nolig{affish}{aff|ish}
+\nolig{offish}{off|ish}
+\nolig{iffish}{iff|ish}
+\nolig{uffish}{uff|ish}
+ % draffish offish sniffish gruffish
+
+\nolig{ffing}{ff|ing}
+\nolig{ffin'}{ff|in'}
+ % baffing biffing bluffing...
+
+\nolig{ffier}{ff|ier}
+ % buffier chaffier ...
+
+%\nolig{ffily}{ff|ily}
+ % Caught by 'fily -> f-ily' rule
+
+\nolig{ffiness}{ff|iness}
+ % fluffiness huffiness puffiness
+
+\nolig{ffies}{ff|ies}
+ % baffies biffies jiffies stuffies ...
+ % buffiest chaffiest ...
+
+% (e) ffl -> ff-l
+
+\nolig{ffly}{ff|ly}
+ % bluffly gruffly ruffly ...
+
+% (f) ffi -> f-fi
+ % nothing additional in 'broad' group
+
+% (g) ffl -> f-fl
+ % nothing additional in 'broad' group
+
+% (h) ft -> f-t
+
+\if@noftligs
+\else % suppress some more ft ligatures selectively
+ \nolig{ifteen}{if|teen}
+ % fifteen fifteens fifteenth
+
+ \nolig{fifti}{fif|ti}
+ \nolig{Fifti}{Fif|ti}
+ % fifties fiftieth fiftieths
+
+ \nolig{fifty}{fif|ty}
+ \nolig{Fifty}{Fif|ty}
+ % fifty fiftyish
+\fi % end of \if@noftligs conditional block
+
+\fi % end of \if@broadfset conditional block
+
+
+
+% Part 3: Discretionary ligatures crossing
+% morpheme boundaries
+% st, ct, sp,
+% th, at, et, as, is, us, ta, ll, sk
+% ----------------------------------------
+
+\if@hdligset
+
+% (A) st -> s-t
+% -------------
+
+\nolig{aspidistra}{a|spidi|stra}
+\nolig{Aspidistra}{Aspidi|stra}
+\nolig{osstalk}{oss|talk}
+ % crosstalk
+\nolig{gstai}{gs|tai}
+ % dogstail
+\nolig{nstak}{ns|tak}
+ % painstaker painstaking
+\nolig{stight}{s|tight}
+ % gastight
+\nolig{stooth}{s|tooth}
+ % houndstooth
+\nolig{steeth}{s|teeth}
+ % houndsteeth
+\nolig{astime}{as|time}
+ % pastime
+
+%%% dis-t... words
+\nolig{distast}{dis|tast}
+\nolig{Distast}{Dis|tast}
+ % distasteful
+\nolig{distem}{dis|tem}
+\nolig{Distem}{Dis|tem}
+ % distemperate
+\nolig{disten}{dis|ten}
+\nolig{Disten}{Dis|ten}
+ % distended
+\nolig{distor}{dis|tor}
+\nolig{Distor}{Dis|tor}
+ % distort distortion
+\nolig{distra[cu]}{dis|tra}
+\nolig{Distra[cu]}{Dis|tra}
+ % distract distraught
+\nolig{distrib}{dis|trib}
+\nolig{Distrib}{Dis|trib}
+ % distribution
+\nolig{distrust}{dis|trust}
+\nolig{Distrust}{Dis|trust}
+ % distrust distrustful
+\nolig{distu}{dis|tu}
+\nolig{Distu}{Dis|tu}
+ % disturb
+
+%%% mis-t... words
+\nolig{mista}{mis|ta}
+\nolig{Mista}{Mis|ta}
+ % mistake mistaken mistaught unmistakable
+\nolig{mistea}{mis|tea}
+\nolig{Mistea}{Mis|tea}
+ % misteach
+\nolig{istend}{is|tend}
+ % mistend distend
+\nolig{isterm}{is|term}
+ % misterm misterms
+\nolig{isth}{is|th}
+ % misthink misthought misthrew misthrow
+ % isthmus calisthenic
+\nolig{istime}{is|time}
+ % mistime mistimed
+\nolig{istitl}{is|titl}
+ % mistitle
+\nolig{istook}{is|took}
+ % mistook
+\nolig{istouc}{is|touc}
+ % mistouch
+\nolig{mistrac}{mis|trac}
+\nolig{Mistrac}{Mis|trac}
+ % Mistrace
+\nolig{mistran}{mis|tran}
+\nolig{Mistran}{Mis|tran}
+ % Mistranscribe Mistranslate
+\nolig{mistrain}{mis|train}
+\nolig{Mistrain}{Mis|train}
+ % mistrain
+\nolig{istrea}{is|trea}
+ % mistreat mistreatment
+\nolig{mistru}{mis|tru}
+\nolig{Mistru}{Mis|tru}
+ % mistrust mistruth
+\nolig{istrys}{is|trys}
+ % mistryst
+\nolig{mistu}{mis|tu}
+\nolig{Mistu}{Mis|tu}
+ % mistune Mistutor
+\nolig{istyp}{is|typ}
+ % mistype
+
+\nolig{aastricht}{aas|tricht}
+ % Maastricht
+
+\nolig{sthes}{s|thes}
+ % anaesthesia synesthesia prosthesis
+\nolig{sthet}{s|thet}
+ % aesthetic esthetic unesthetic
+ % prosthetist
+
+\nolig{Esth}{Es|th} % Esther
+
+\nolig{stown}{s|town}
+ % crosstown Williamstown
+
+
+% (B) ct -> c-t
+% -------------
+
+\nolig{rctan}{rc|tan}
+ % arctangent
+\nolig{rctat}{rc|tat}
+ % coarctation
+
+% (C) sp -> s-p
+% -------------
+
+\nolig{othesp}{othes|p}
+ % clothespin clothespress
+\nolig{speople}{s|people}
+ % business- congress- crafts-
+ % dis- news- sales- spokes-
+ % towns- trades- tribes- people
+\nolig{sperson}{s|person}
+ % business- congress- crafts- drafts-
+ % news- sales- spokes- person
+\nolig{espas}{es|pas}
+ % trespass trespassing
+\nolig{isplat}{is|plat}
+ % cisplatin (cis-platin, not cisp-latin!)
+
+\nolig{despot}{des|pot}
+\nolig{Despot}{Des|pot}
+ % despot despotic
+
+\nolig{spresso}{s|presso}
+
+ \nolig{despon}{de|spon}
+ \nolig{Despon}{De|spon}
+ \nolig{despir}{de|spir}
+ \nolig{Despir}{De|spir}
+ \nolig{despoil}{de|spoil}
+ \nolig{Despoil}{De|spoil}
+ \nolig{sidesp}{side|sp} % sidespin, sidesplitting
+ \nolig{Sidesp}{Side|sp}
+ \nolig{widesp}{wide|sp} % widespread
+ \nolig{Widesp}{Wide|sp}
+ \nolig{desprung}{Wide|sp} % gelandesprung
+
+\nolig{dispa[rst]}{dis|pa}
+\nolig{Dispa[rst]}{Dis|pa}
+ % disparage disparaging dispart
+ % dispassion dispatch
+\nolig{dispel}{dis|pel}
+\nolig{Dispel}{Dis|pel}
+ % dispel
+\nolig{dispen[ds]}{dis|pen}
+\nolig{Dispen[ds]}{Dis|pe}
+ % dispend dispense dispensation
+\nolig{displa[cny]}{dis|pla}
+\nolig{Displa[cny]}{Dis|pla}
+ % display displant displace
+\nolig{displea}{dis|plea}
+\nolig{Displea}{Dis|plea}
+ % displease displeasure
+\nolig{displ[ou]}{dis|pl}
+\nolig{Displ[ou]}{Dis|pl}
+ % displode displume
+\nolig{disp[ou]}{dis|p}
+\nolig{Disp[ou]}{Dis|p}
+ % disport dispose disposition
+ % dispossess dispute
+\nolig{dispr[aio]}{dis|pr}
+\nolig{Dispr[aio]}{Dis|pr}
+ % dispraise disprize disproof
+ % disproportion disprove
+
+
+\nolig{misp}{mis|p}
+\nolig{Misp}{Mis|p}
+ % misplace misperception misprint
+
+\nolig{suspen}{sus|pen}
+\nolig{Suspen}{Sus|pen}
+ % suspend suspension
+
+\nolig{sph}{s|ph} % 'ph' from Greek 'phi'!
+ % atmosphere biosphere hemisphere
+ % spherical asphodel phosphorous phosphate
+ % blaspheme blasphemy
+
+\nolig{ranspa}{rans|pa}
+ % transparent transpacific
+\nolig{ranspe}{rans|pe}
+ % transpersonal
+\nolig{ranspie}{rans|pie}
+ % transpierce
+\nolig{ranspl}{rans|pl}
+ % transplant
+\nolig{ranspol}{rans|pol}
+ % transpolar
+\nolig{ranspor}{rans|por}
+ % transport transportation
+\nolig{ranspos}{rans|pos}
+ % transpose transposon
+
+\nolig{risprud}{ris|prud}
+ % jurisprudence
+\nolig{spiece}{s|piece}
+ % crosspiece frontispiece
+
+\nolig{ewsp[ae]}{ews|p}
+ % newspaper newsprint
+
+\nolig{Hyannisp}{Hyannis|p}
+ % Hyannisport
+\nolig{Keyesp}{Keyes|p}
+ % Keyesport
+\nolig{Williamsp}{Williams|p}
+ % Williamsport
+
+\nolig{assport}{ass|port}
+ % passport
+
+
+% (D) th -> t-h
+% -------------
+
+\nolig{eethov}{eet|hov}
+ % Beethoven
+\nolig{thook}{t|hook}
+ % boathook meathook pothook
+\nolig{thouse}{t|house}
+ % boathouse cathouse courthouse ...
+\nolig{othol}{ot|hol}
+ % foothold knothole potholder ...
+\nolig{lthol}{lt|hol}
+ % bolthole
+\nolig{sthol}{st|hol}
+ % posthole pesthole
+\nolig{rathol}{rat|hol}
+\nolig{Rathol}{Rat|hol}
+ % rathole
+\nolig{arthog}{art|hog}
+ % warthog
+\nolig{stha}{st|ha}
+ % firsthand postharvest posthaste
+\nolig{thawk}{t|hawk}
+ % nighthawk
+\nolig{horth}{hort|h}
+ % shorthair shorthand shorthorn
+\nolig{arthei}{art|hei}
+ % apartheid antiapartheid
+\nolig{thead}{t|head}
+ % bolthead cathead fathead ...
+\nolig{thard}{t|hard}
+ % Gotthard
+\nolig{therd}{t|herd}
+ % goatherd neatherd
+\nolig{theap}{t|heap}
+ % dustheap
+\nolig{theart}{t|heart}
+ % fainthearted sweetheart ...
+\nolig{uthear}{ut|hear}
+ % outhear outheard
+\nolig{thill}{t|hill}
+ % anthill foothill
+\nolig{thood}{t|hood}
+ % adulthood knighthood ...
+\nolig{thunt}{t|hunt}
+ % pothunt outhunt
+\nolig{orthol}{ort|hol}
+ % porthole
+\nolig{posth}{post|h}
+\nolig{Posth}{post|h}
+ % postharvest
+\nolig{sthum}{st|hum}
+ % posthumous
+\nolig{uthau}{ut|hau}
+ % outhaul
+\nolig{uthit}{ut|hit}
+ % outhit
+\nolig{uthom}{ut|hom}
+ % outhomer
+\nolig{uthow}{ut|how}
+ % outhowl
+\nolig{uthum}{ut|hum}
+ % outhumor
+\nolig{uthust}{ut|hust}
+ % outhustle
+\nolig{tthour}{tt|hour}
+ % watthour kilowatthour
+\nolig{sthm}{s|thm}
+ % asthma isthmus
+
+% (E) at -> a-t
+% -------------
+
+\nolig{lbatr}{lba|tr}
+ % albatross
+\nolig{atroop}{a|troop}
+ % paratrooper
+\nolig{eatra}{ea|tra}
+ % seatrain seatransport
+
+% (F) et -> e-t
+% -------------
+
+\nolig{ninet}{nine|t}
+\nolig{Ninet}{Nine|t}
+ % ninetieth ninetieths ninety nineteen nineties
+
+\nolig{ametag}{ame|tag}
+ % nametag
+\nolig{betat}{be|tat}
+\nolig{Betat}{Be|tat}
+ % betatter beta
+\nolig{betr}{be|tr}
+\nolig{Betr}{Be|tr}
+ % betray betroth
+
+\nolig{deta}{de|ta}
+ % detach detain detail
+\nolig{etect}{e|tect}
+ % detect undetectable detective
+\nolig{detent}{de|tent}
+\nolig{Detent}{De|tent}
+ % detent detention
+\nolig{detest}{de|test}
+\nolig{Detest}{De|test}
+ % detest
+\nolig{detr}{de|tr}
+\nolig{Detr}{De|tr}
+ % detract detrain detriment detritus
+
+\nolig{etail}{e|tail}
+ % bristletail detail dovetail horsetail
+\nolig{etah}{e|tah}
+ % cheetah chetah
+\nolig{etak}{e|tak}
+ % betake retake caretaker
+\nolig{etax}{e|tax}
+ % betax
+\nolig{eteach}{e|teach}
+ % reteach
+\nolig{etell}{e|tell}
+ % foretell fortunetelling
+\nolig{eterg}{e|terg}
+ % detergent
+\nolig{eterio}{e|terio}
+ % deteriorate
+\nolig{eterm}{e|term}
+ % determent determinant preterm
+\nolig{etext}{e|text}
+ % pretext retext teletext
+\nolig{ethink}{e|think}
+ % freethinking
+\nolig{ethrow}{e|throw}
+ % freethrow
+\nolig{etick}{e|tick}
+ % bluetick detick
+\nolig{etide}{e|tide}
+ % betide yuletide
+\nolig{etigh}{e|tigh}
+ % retighten
+\nolig{etime}{e|time}
+ % betime lifetime peacetime sometime
+\nolig{eetop}{ee|top}
+ % treetop
+\nolig{etrain}{e|train}
+ % detrain drivetrain housetrain retrain
+\nolig{etrap}{e|trap}
+ % firetrap livetrap mousetrap
+\nolig{etree}{e|tree}
+ % axletree saddletree shoetree
+
+\nolig{foret}{fore|t}
+\nolig{Foret}{Fore|t}
+ % foretaste foretell foretold foretime
+ % foretoken foretop foretopman
+\nolig{imetable}{ime|table}
+ % timetable
+
+\nolig{reteen}{re|teen}
+ % preteen
+\nolig{retend}{re|tend}
+ % pretend
+\nolig{retenc}{re|tenc}
+ % pretence
+\nolig{retens}{re|tens}
+ % pretense pretension
+\nolig{retent}{re|tent}
+\nolig{Retent}{Re|tent}
+ % pretentious retention retentive
+\nolig{retest}{re|test}
+\nolig{Retest}{Re|test}
+ % pretest retest
+
+\nolig{reta}{re|ta}
+\nolig{Reta}{Re|ta}
+ % retag retape retake
+ % foretaste caretaker
+ % pretaste pretape pretaxretain
+ % retain retake retaliate retard
+ % retarget retaste wiretap
+ \keeplig{pretable} % interpretable
+ \keeplig{cretar} % secretary
+
+\nolig{reteam}{re|team}
+\nolig{Reteam}{Re|team}
+ % reteam reteamed reteaming reteams
+\nolig{retear}{re|tear}
+\nolig{Retear}{Re|tear}
+ % retear retears
+\nolig{retemp}{re|temp}
+\nolig{Retemp}{Re|temp}
+ % retemper retempering
+
+\nolig{retie}{re|tie}
+\nolig{Retie}{Re|tie}
+ % retie entireties sureties
+\nolig{retil}{re|til}
+\nolig{Retil}{Re|til}
+ % retile
+\nolig{retim}{re|tim}
+\nolig{Retim}{Re|tim}
+ % retime beforetime
+\nolig{retint}{re|tint}
+\nolig{Retint}{Re|tint}
+ % retint
+\nolig{retir}{re|tir}
+\nolig{Retir}{Re|tir}
+ % retire retiring
+\nolig{retitl}{re|titl}
+\nolig{Retitl}{Re|titl}
+ % retitle pretitling
+
+\nolig{retold}{re|told}
+\nolig{Retold}{Re|told}
+ % retold
+\nolig{retoo}{re|too}
+\nolig{Retoo}{Re|too}
+ % retook retool
+\nolig{retor}{re|tor}
+\nolig{Retor}{Re|tor}
+ % retore retorn retort retorted
+\nolig{retou}{re|tou}
+\nolig{Retou}{Re|tou}
+ % retouch retouched
+\nolig{retra}{re|tra}
+\nolig{Retra}{Re|tra}
+ % retrace retrack retract retrans retransmit
+\nolig{retre}{re|tre}
+\nolig{Retre}{Re|tre}
+ % pretreat retread retreat retrench
+\nolig{retri}{re|tri}
+\nolig{Retri}{Re|tri}
+ % pretrim pretrial retrieve retribution
+ % retries retrim
+\nolig{etrors}{e|trors}
+ % retrorse
+\nolig{retrous}{re|trous}
+\nolig{Retrous}{Re|trous}
+ % retrousse
+\nolig{retry}{re|try}
+\nolig{Retry}{Re|try}
+ % retry retrying
+
+\nolig{retu}{re|tu}
+\nolig{Retu}{Re|tu}
+ % return retune unreturnable
+\nolig{retwi}{re|twi}
+\nolig{Retwi}{Re|twi}
+ % retwist retwisting
+
+\nolig{etooth}{e|tooth}
+ % bluetooth eyetooth snaggletoothed
+\nolig{eteeth}{e|teeth}
+ % snaggleteeth eyeteeth
+
+\nolig{deter}{de|ter}
+\nolig{Deter}{De|ter}
+ % deter determine deteriorate undeterred
+
+\nolig{ceties}{ce|ties}
+ % niceties
+\nolig{cety}{ce|ty}
+ % nicety
+
+\nolig{feties}{fe|ties}
+ % safeties unsafeties biosafeties
+\nolig{fety}{fe|ty}
+ % safety
+
+\nolig{leties}{le|ties}
+ % subtleties
+\nolig{lety}{le|ty}
+ % subtlety teletype teletypewriter
+
+\nolig{rety}{re|ty}
+ % surety entirety retype pretype
+
+\nolig{etelev}{e|telev}
+ % pretelevision
+\nolig{etyp}{e|typ}
+ % archetype archetypal retype pretype
+
+% (G) as -> a-s
+% -------------
+
+\nolig{asea}{a|sea}
+ % asea
+ \keeplig{casea} % casease caseate
+ \keeplig{Casea}
+ \keeplig{haseal} % phaseal
+\nolig{asplut}{a|splut}
+ % asplutter
+\nolig{eastran}{ea|stran}
+ % seastrand
+\nolig{aspor[ae]}{a|spor}
+ % diaspora megaspore tetraspore
+\nolig{asep[st]}{a|sep}
+ % asepsis aseptic aseptically
+\nolig{asophist}{a|sophist}
+ % ultrasophisticated
+\nolig{asound}{a|sound}
+ % ultrasound
+\nolig{asund}{a|sund}
+\nolig{Asund}{A|sund}
+ % asunder
+\nolig{aspec}{a|spec}
+\nolig{Aspec}{A|spec}
+ % aspect infraspecific intraspecies
+ % intraspecific
+\nolig{infras}{infra|s}
+\nolig{Infras}{Infra|s}
+ % infrastructure infraspecific
+\nolig{megast}{mega|st}
+\nolig{Megast}{Mega|st}
+ % megastructure megastar
+\nolig{megasp}{mega|sp}
+\nolig{Megasp}{Mega|sp}
+ % megaspores megascopic
+\nolig{aspoon}{a|spoon}
+ % teaspoon
+
+
+% (H) is -> i-s
+% -------------
+
+% (a) not across morpheme boundaries
+% (The following may be a bug in fontspec)
+
+\nolig{fish}{fi|sh}
+\nolig{fist}{fi|st}
+\nolig{Fist}{Fi|st}
+
+
+% (b) across morpheme boundaries
+
+%% Mustn't do global \nolig{antis}{anti|s}
+%% because of words such as sycophantism,
+%% vigilantism, and mantissa.
+
+\nolig{antis[ace]}{anti|s}
+\nolig{Antis[ace]}{Anti|s}
+ % antisag antisatellite
+ % antiscience
+ % antisecrecy antisense antiseptic
+\nolig{antish[aio]}{anti|sh}
+\nolig{Antish[aio]}{Anti|sh}
+ % antishark antiship antishock
+\nolig{antis[kl]}{anti|s}
+\nolig{Antis[kl]}{Anti|s}
+ % antiskid
+ % antislavery antislip
+\nolig{antism[ou]}{anti|sm}
+\nolig{Antism[ou]}{Anti|sm}
+ % antismog antismoke
+ % antismuggling antismut
+\nolig{antis[noptuy]}{anti|s}
+\nolig{Antis[noptuy]}{Anti|s}
+ % antisnob
+ % antisocial antisolar
+ % antispasmodic antispeculative
+ % antistatic antistick antistress
+ % antisubmarine antisubversion
+ % antisymmetric antisyphilitics
+
+\nolig{multis[a-z]}{multi|s}
+\nolig{Multis[a-z]}{Multi|s}
+ % multiscreen multisense multisensory
+ % multiservice multisided multisite
+ % multisize multiskilled multisource
+ % multispecies multispectral multispeed
+ % multisport multistage multistate
+ % multistemmed multistep multistoried
+ % multistory multistranded multisyllabic
+ % multisystem
+
+\nolig{isph}{i|sph}
+ % hemisphere planisphere hemispheric
+ \keeplig{isphr} % misphrase misphrased ...
+
+% (I) us -> u-s
+% -------------
+
+% %% (no examples yet)
+
+
+% (J) sk -> s-k
+% (available in EB Garamond font)
+% -------------------------------
+
+\nolig{skeep}{s|keep}
+ % greenskeeper groundskeeper miskeep
+\nolig{iskai}{is|kai}
+ % triskaidekaphobia
+\nolig{thsk}{ths|k}
+ % rathskeller
+\nolig{misk}{mis|k}
+\nolig{Misk}{Mis|k}
+ % miskeep miskept miskick misknow
+\nolig{atskill}{ats|kill}
+ % Catskills Mountains, Catskill Park
+\nolig{eekskill}{eeks|kill}
+ % Peekskill % a town on the Hudson River
+
+
+% (K) ll -> l-l
+% -------------
+
+\nolig{llike}{l|like}
+ % animallike soullike
+\nolig{lless}{l|less}
+ % soulless tailless
+
+% (L) fr -> f-r
+% -------------
+
+\nolig{oofr}{oof|r}
+ % proofread proofroom proofrock
+
+
+% (M) ij -> i-j
+% -------------
+
+% The 'ij' ligature seems to have no good
+% use in English-language words -- incl.
+% words introduced to English from other
+% languages, such as marijuana, gaijin, and
+% bijou; the 'ij' ligature seems to span
+% morpheme boundaries in all of these cases.
+% Hence, we disable this ligature globally.
+% We do make exceptions for words of Dutch
+% origin, where the ij ligature does have
+% legitimate uses.
+
+\nolig{ij}{i|j}
+ \keeplig{ijs} % rijsttafel (Indonesian dish)
+ \keeplig{ijn} % de Bruijn
+ \keeplig{eije}% Meijer
+
+
+
+% Part 4: Disabling one discretionary
+% ligature so that a subsequent, more
+% important one doesn't get pre-empted
+% ------------------------------------
+
+% (i) as, is, and us preceding st
+% ...............................
+
+\nolig{ast}{a|st}
+\nolig{ust}{u|st}
+\nolig{ist}{i|st}
+
+% (ii) as, es, is, and us preceding sp
+% .............................-......
+
+\nolig{aspar}{a|spar}
+\nolig{Aspar}{A|spar}
+ % asparagus Caspar aspartame asparkle
+\nolig{asper}{a|sper}
+\nolig{Asper}{A|sper}
+ % aspersion Casper Jasper exasperate
+\nolig{aspir}{a|spir}
+\nolig{Aspir}{A|spir}
+ % aspire aspirator aspirin
+\nolig{gasp}{ga|sp}
+\nolig{Gasp}{Ga|sp}
+ % gasp
+\nolig{hasp}{ha|sp}
+\nolig{Hasp}{Ha|sp}
+ % hasp
+\nolig{lasp}{la|sp}
+ % clasp unclasp beclasp enclasp
+\nolig{rasp}{ra|sp}
+\nolig{Rasp}{Ra|sp}
+ % grasp rasp raspberry
+\nolig{wasp}{wa|sp}
+\nolig{Wasp}{Wa|sp}
+ % wasp waspish
+
+
+\nolig{espi[ct]}{e|spi}
+ % despicable despite
+%%% more rules to come...
+
+\nolig{risp}{ri|sp}
+ % crisp
+\nolig{ispani}{i|spani}
+ % hispanic
+\nolig{hispid}{hi|spid}
+\nolig{Hispid}{Hi|spid}
+ % hispid hispidulous
+\nolig{lisp}{li|sp}
+\nolig{Lisp}{Li|sp}
+ % lisp lisping
+\nolig{whisp}{whi|sp}
+\nolig{Whisp}{Whi|sp}
+ % whisper
+\nolig{wisp}{wi|sp}
+\nolig{Wisp}{Wi|sp}
+ % wisp
+
+\nolig{cusp}{cu|sp}
+\nolig{Cusp}{Cu|sp}
+ % cusp bicuspid tricuspid
+\nolig{ausp}{au|sp}
+\nolig{Ausp}{Au|sp}
+ % auspicious inauspicious
+
+\nolig{Suspect}{Su|spect}
+\nolig{suspect}{su|spect}
+ % suspect suspects
+\nolig{uspici}{u|spici}
+ % suspicion suspicious
+
+% (iii) at and et preceding th
+% ............................
+
+%% If you have 'at' and 'et' ligatures as
+%% well as the 'th' ligature and want a
+%% trailing 'th' ligature to take precedence
+%% over these ligs, use the following rules:
+
+\nolig{ath}{a|th}
+\nolig{eth}{e|th}
+
+% The preceding rules are a bit too
+% broad as they also suppress the 'at' ligature
+% for words such as boathook and flathead
+% and the 'et' ligature in words such as
+% Beethoven, prophethood, and sweetheart.
+% Thus, also provide some \keeplig macros:
+
+\keeplig{oathook} % boathook
+\keeplig{eathook} % meathook
+\keeplig{athouse} % bathouse boathouse cathouse
+%%\keeplig{rathole} % this will re-enable "th" liga
+%%\keeplig{Rathole} % if "at" liga doesn't exist...
+\keeplig{athead} % cathead fathead flathead meathead
+\keeplig{atherd} % goatherd neatherd
+\keeplig{eatheart} % greathearted
+\keeplig{eetheart} % sweetheart
+
+\keeplig{Beethoven}
+\keeplig{ophethood}
+
+
+% (iv) at and et preceding ta
+% ...........................
+
+\nolig{atap}{a|tap}
+ \keeplig{catap} % catapult cataphoresis
+ \keeplig{Catap}
+ \keeplig{ratap} % rataplan
+ \keeplig{Ratap}
+
+\nolig{Loretan}{Lore|tan} % :-)
+
+\fi %% end of \@ifhdligset
diff --git a/macros/luatex/latex/selnolig/selnolig-english-test.pdf b/macros/luatex/latex/selnolig/selnolig-english-test.pdf
new file mode 100644
index 0000000000..60f4a448cf
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig-english-test.pdf
Binary files differ
diff --git a/macros/luatex/latex/selnolig/selnolig-english-test.tex b/macros/luatex/latex/selnolig/selnolig-english-test.tex
new file mode 100644
index 0000000000..0dec5a98b5
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig-english-test.tex
@@ -0,0 +1,109 @@
+% !TEX TS-program = lualatex
+\documentclass[english]{article}
+
+% Test program: Apply the 'selnolig' package, with
+% 'english' language option set, to a list of English
+% words which contain various character pairs that
+% should not be ligated. The list of English words is
+% in the companion file 'selnolig-english-wordlist.tex'.
+%
+% Author: Mico Loretan (loretan dot mico at gmail dot com)
+% Date: 2015/10/26
+
+% Check first that we're running Lua(La)TeX.
+\usepackage{ifluatex}
+\ifluatex\else
+ \typeout{===============================================}
+ \typeout{The file selnolig-english-test.tex must be }
+ \typeout{compile using lualatex. Exiting immediately. }
+ \typeout{===============================================}
+ \endinput
+\fi
+
+\usepackage[margin=1in]{geometry}
+
+
+
+\usepackage{fancyvrb}
+
+\usepackage{fontspec}
+
+\defaultfontfeatures{%
+ Ligatures={TeX,Common,Rare},
+ Numbers = OldStyle}
+
+\setmainfont[ FeatureFile= gpp-ft.fea,
+ ItalicFont = {Garamond Premier Pro Italic},
+ BoldItalicFont = {Garamond Premier Pro Italic},
+ BoldFont = {Garamond Premier Pro}]
+ {Garamond Premier Pro}
+
+\setmonofont[Scale=MatchLowercase,
+ Ligatures=NoCommon]
+ {Consolas}
+
+\newfontfamily\ebg[
+ Ligatures = {TeX,Common,Rare,Historic},
+ ItalicFont = {EB Garamond 12 Italic}]
+ {EB Garamond 12 Regular}
+
+\usepackage[document]{ragged2e}
+\usepackage{babel}
+\usepackage[hdlig,broadf]{selnolig}
+\debugon
+
+%%%\usepackage{showhyphens}
+
+\setlength\parindent{0pt}
+\parskip=0.3\baselineskip
+\usepackage{multicol}
+ \setlength\columnseprule{.4pt}
+\title{selnolig-english-test\\ (Package version: \selnoligpackageversion; \selnoligpackagedate)}
+\author{\null}
+\date{}
+
+\righthyphenmin=2 % set this to either 3 (normal) or 2
+
+
+\begin{document}
+\maketitle
+
+\begin{tabular}{@{}*{10}{l}}
+Appearance of ``common'' ligatures
+ &ff &fi &fl &ffi &ffl &ft & \mbox{fj} & {\ebg\mbox{fk}}
+ & \emph{fr}\\
+Sample words with these ligatures
+ &off &fit &fly &office &baffle &often & fjord
+ &{\ebg Kafka} &\emph{from}\\
+\end{tabular}
+
+\bigskip
+
+\begin{tabular}{@{}*{15}{l}}
+Appearance of ``discretionary'' (``rare'') ligatures
+ & st & ct & sp
+ & \emph{as} & {\ebg\em es} & \emph{is, th, us}
+ & \emph{at} & \emph{et} & {\ebg\emph{sk}}& \emph{ll} & \emph{\uselig{ij}, st, ta}\\
+Sample words with these ligatures
+ & stay & act & spy
+ & \emph{was} & {\ebg\em sees}& \emph{\uselig{isthmus}} & \emph{cat} & \emph{net}
+ & {\ebg\emph{ask}} & \emph{ill} & \emph{rijsttafel}\\
+\end{tabular}
+
+
+\bigskip
+
+\makeatletter
+\begin{tabular}{@{}ll}
+Package options and other parameters:\\
+\ \ \ \ \ Extent of suppressing f-ligatures: basic or broadf? & \if@broadfset broadf \else basic \fi \\
+\ \ \ \ \ Value of \texttt{\textbackslash righthyphenmin} parameter & \the\righthyphenmin\\
+\end{tabular}
+\makeatother
+
+\bigskip
+
+\begin{multicols}{2}
+\input selnolig-english-wordlist
+\end{multicols}
+\end{document}
diff --git a/macros/luatex/latex/selnolig/selnolig-english-wordlist.tex b/macros/luatex/latex/selnolig/selnolig-english-wordlist.tex
new file mode 100644
index 0000000000..616d5d0d7e
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig-english-wordlist.tex
@@ -0,0 +1,762 @@
+% !TeX root = selnolig-english-test.tex
+% !TEX TS-program = lualatex
+
+% Last updated: 2015/10/26
+% For use with the 'selnolig' package and the
+% driver program 'selnolig-english-test.tex'.
+
+
+\section*{Part 1: Basic set of f-ligatures suppression rules}
+
+
+\begin{itemize}
+
+\item ff to f\kern0pt f
+
+shelfful shelffuls bookshelfful selffulfilling
+
+
+\item fi to f\kern0pt i
+
+(None in basic set)
+
+\item fl to f\kern0pt l
+
+beefless briefless hoofless leafless roofless selfless turfless selflessly selflessness
+
+calflike dwarflike elflike gulflike hooflike leaflike rooflike serflike sheaflike shelflike surflike turflike waiflike wolflike
+
+halflife shelflife
+halflives shelflives
+
+halfline roofline
+halflines rooflines
+
+leaflet leaflets leafleted leafleting leafletting leafletted leafleteer
+
+pdflatex (even better: pdfLaTeX or pdf\LaTeX)
+
+
+\item ffi to ff\kern0pt i
+
+Pfaffian Wolffian Wulffian
+
+
+\item ffl to ff\kern0pt l
+
+cuffless stuffless cufflessly stufflessness
+
+scofflaw scofflaws cufflink cufflinks
+
+offline
+
+offload offloads offloading offloaded
+
+rufflike clifflike
+
+
+\item ffi to f\kern0pt fi
+
+chaffinch chaffinches wolffish wolffishly
+
+\item ffl to f\kern0pt fl
+
+safflower
+
+
+
+\item ft to f\kern0pt t
+
+chieftain chieftaincy chieftaincies chieftainship chieftainships
+
+halftime halftone halftimes halftones
+
+rooftop rooftops rooftree rooftrees
+
+wolftrap calftrap leaftrap offtrack
+
+fifth fifths fifthly twelfth twelfths
+
+
+
+\item \emph{fr} to \emph{f\kern0pt r} (italic font shape only)
+
+\emph{proofread proofreader proofroom}
+
+
+\item \bgroup \ebg \uselig{fb}, \uselig{fh}, \uselig{fj}, and \uselig{fk} ligatures \egroup
+
+halfback golfball goofball wolfberry halfbeak hoofbeat surfbird surfboard surfboarder surfboat
+
+halfhearted selfheal leafhopper selfhood serfhood wolfhound
+
+offbeat puffball snuffbox
+
+cliffhanger offhand offhanded offhandedly
+
+cliffjumper
+
+offkey
+
+\emph{but:} {\ebg Kafka, Sognefjord, Dovrefjell}
+
+
+
+
+\end{itemize}
+
+\section*{Part 2: Further f-ligatures suppressed if ``broadf'' option is set}
+
+\begin{itemize}
+
+\item ff to f\kern0pt f
+
+(No extra cases in broadf set)
+
+
+\item fi to f\kern0pt i
+
+elfin
+
+chafing leafing loafing sheafing strafing vouchsafing
+beefing reefing briefing debriefing
+coifing fifing jackknifing knifing midwifing waifing wifing
+
+airproofing childproofing fireproofing flameproofing mothproofing rustproofing soundproofing waterproofing weatherproofing proofing
+
+goofing hoofing reroofing roofing spoofing whoofing woofing
+
+begulfing engulfing ingulfing gulfing golfing rolfing selfing wolfing
+barfing
+
+bedwarfing dwarfing enserfing kerfing scarfing snarfing
+surfing turfing wharfing windsurfing
+
+deafish dwarfish elfish oafish selfish serfish unselfish wolfish
+
+deafishly dwarfishly elfishly oafishly selfishly serfishly unselfishly wolfishly
+
+deafishness dwarfishness elfishness oafishness selfishness serfishness unselfishness wolfishness
+
+beefier comfier goofier gulfier leafier surfier turfier
+
+beefiest comfiest goofiest gulfiest leafiest surfiest turfiest
+
+beefily goofily goofiness
+
+
+\item fl to f\kern0pt l
+
+aloofly briefly chiefly deafly liefly
+
+
+\item ffi to ff\kern0pt i
+
+baffing biffing outbluffing bluffing boffing buffing chaffing cheffing chuffing coffing coiffing handcuffing uncuffing cuffing daffing doffing enfeoffing infeoffing feoffing fluffing gaffing gruffing huffing luffing miffing muffing offing piaffing puffing quaffing rebuffing reffing restaffing restuffing riffing crossruffing overruffing underruffing ruffing sclaffing scoffing scuffing shroffing sluffing sniffing snuffing spiffing overstaffing understaffing staffing stiffing overstuffing stuffing tariffing tiffing waffing whiffing yaffing
+
+draffish giraffish gruffish offish raffish sniffish standoffish stiffish toffish
+
+draffishly giraffishly raffishly
+
+buffier chaffier chuffier cliffier daffier fluffier gruffier huffier iffier miffier puffier scruffier sniffier snuffier spiffier stuffier
+
+buffiest chaffiest chuffiest cliffiest daffiest fluffiest gruffiest huffiest iffiest miffiest puffiest scruffiest sniffiest snuffiest spiffiest stuffiest
+
+daffily fluffily gruffily huffily puffily scruffily sniffily snuffily spiffily stuffily
+
+fluffiness huffiness iffiness puffiness scruffiness sniffiness spiffiness stuffiness
+
+baffies biffies jiffies stuffies taffies toffies waffie waffies
+
+
+\item ffl to ff\kern0pt l
+
+bluffly gruffly ruffly snuffly stiffly
+
+
+\item ffi to f\kern0pt fi
+
+(No extra cases in broadf set)
+
+
+\item ffl to f\kern0pt fl
+
+(No extra cases in broadf set)
+
+
+\item ft to f\kern0pt t
+
+fifty fiftyish
+
+fifties fiftieth fiftieths
+
+fifteen fifteens fifteenth fifteenths
+
+
+
+\end{itemize}
+
+
+\section*{Part 3: Ligatures suppressed if ``hdlig'' option is set}
+
+\begin{itemize}
+
+\item ct to c\kern0pt t
+
+arctangent coarctation
+
+
+\item st to s\kern0pt t
+
+First reason: ``th'' (from $\theta$ or $\vartheta$) after ``s'':
+
+asthma isthmus aesthetic
+
+Esther
+
+
+\medskip
+Second reason: avoid instances of st spanning a morpheme boundary
+
+painstaker painstaking dogstail crosstalk gastight
+
+distasteful distemperate distended distort distract distraught distribute distributed distribution distrust disturb
+
+\emph{but}: distant distillation district
+
+mistrust mistake mistaken
+
+Maastricht
+
+Charlestown crosstown
+
+
+
+
+\emph{And, do not suppress the st ligature for} castle forecastle, nestle wrestle, bristle bristletail distelfink epistle glisten gristle listen mistletoe thistle whistle, apostle jostle, bustle hustle rustle
+
+
+
+
+\item sp to s\kern0pt p
+
+First reason: ``ph'' (from $\phi$ or $\varphi$) after ``s'':
+
+asphalt asphodel asphyxiate blaspheme blasphemy
+
+dysphagia dysphonia dysphoria sphagnum sphinx
+
+atmosphere bathysphere biosphere blogosphere ecosphere exosphere hemisphere hydrosphere ionosphere magnetosphere stratosphere
+
+spherical sphericity spheroid
+
+phosphorous phosphates phosphorescent
+
+\medskip
+Second reason: don't cross morpheme boundaries
+
+clothespin clothespress
+
+passport
+
+businesspeople congresspeople craftspeople dispeople newspeople salespeople spokespeople townspeople tradespeople tribespeople
+
+businessperson congressperson craftsperson draftsperson newsperson salesperson spokesperson
+
+transpacific transparent transpersonal transpierce transplant transplacental transpolar transport transpose transposon
+
+(but: transpicuous transpire transponder)
+
+(also: respond despondent corespond correspond)
+
+trespass trespassing
+
+cisplatin
+
+disparage disparaged disparagement disparagements disparager disparagers disparages disparaging disparagingly
+
+disparate disparately disparateness disparatenesses
+
+disparities disparity dispart disparted disparting disparts
+
+dispassion dispassionate dispassionately dispassionateness dispassionatenesses dispassions
+
+dispatch dispatched dispatcher dispatchers dispatches dispatching
+
+dispel dispelled dispelling dispels
+
+dispend dispended dispending dispends dispensabilities dispensability dispensable dispensaries dispensary dispensation dispensational dispensations dispensatories dispensatory dispense dispensed dispenser dispensers dispenses dispensing
+
+dispeople dispeopled dispeoples dispeopling
+
+displace displaceable displaced displacement displacements displaces displacing
+
+displant displanted displanting displants
+
+display displayable displayed displaying displays
+
+displease displeased displeases displeasing displeasure displeasures
+
+displode disploded displodes disploding displosion displosions
+
+displume displumed displumes displuming
+
+disport disported disporting disportment disportments disports
+
+disposabilities disposability disposable disposables disposal disposals dispose disposed disposer disposers disposes disposing
+
+disposition dispositional dispositions dispositive
+
+dispossess dispossessed dispossesses dispossessing dispossession dispossessions dispossessor dispossessors
+
+disposure disposures
+
+dispraise dispraised dispraiser dispraisers dispraises dispraising dispraisingly
+
+disprize disprized disprizes disprizing
+
+disproof disproofs
+
+disproportion disproportional disproportionate disproportionated disproportionately disproportionates disproportionating disproportionation disproportionations disproportioned disproportioning disproportions
+
+disprovable disprove disproved disproven disproves disproving
+
+disputable disputably disputant disputants disputation disputations disputatious disputatiously disputatiousness disputatiousnesses dispute disputed disputer disputers disputes disputing
+
+espresso (--- from ex and press, right?!)
+
+indispensabilities indispensability indispensable indispensableness indispensablenesses indispensables indispensably
+
+indispose indisposed indisposes indisposing indisposition indispositions
+
+indisputable indisputableness indisputablenesses indisputably
+
+misperception misphrase misplace misplant misplay misprice misprint mispronounce
+
+predispose predisposed predisposes predisposing predisposition predispositions
+
+redisplay redisplayed redisplaying redisplays
+
+redispose redisposed redisposes redisposing redisposition redispositions
+
+undisputable undisputed
+
+suspend suspended suspends suspension
+
+
+\emph{but}: dispersal dispersals dispersant dispersants disperse dispersed dispersedly disperser dispersers disperses dispersible dispersing dispersion dispersions dispersive dispersively dispersiveness dispersivenesses
+
+dispersoid dispersoids
+
+dispirit dispirited dispiritedly dispiritedness dispiritednesses dispiriting dispirits
+
+dispiteous
+
+dispread dispreading dispreads
+
+monodisperse nondispersive
+
+polydisperse polydispersities polydispersity
+
+\end{itemize}
+
+
+
+\bigskip
+
+Note: The test words in the remainder of this document are generally set in \emph{italics} because the text font that's used by the ``driver'' program, \emph{selnolig-english-test.tex}, does not feature the applicable ligatures in the upright font shape.
+
+
+\begin{itemize}
+
+\item \emph{th} to \emph{t\kern0pt h}
+
+\bgroup \em
+
+bathouse boathouse cathouse courthouse guesthouse hothouse lighthouse nuthouse oasthouse outhouse penthouse pesthouse pilothouse pothouse
+
+bolthead cathead fathead flathead gilthead hothead lightheaded masthead meathead pithead pothead printhead softhead softheaded
+
+fainthearted greathearted lighthearted softhearted stouthearted sweetheart sweethearts
+
+adulthood aunthood knighthood parenthood priesthood prophethood sainthood servanthood
+
+bolthole knothole porthole posthole pesthole pothole rathole
+
+boathook meathook pothook
+
+foothold potholder roothold
+
+anthill foothill
+
+goatherd neatherd
+
+outhaul outhear outhit outhomer outhowl outhumor outhunt outhustle
+
+shorthair shorthanded shorthorn % a breed of sheep...
+
+antiapartheid apartheid dustheap firsthand nighthawk
+
+postharvest
+
+posthumous posthumously
+
+pothunt warthog
+
+watthour kilowatthour
+
+Gotthard
+
+
+
+
+\egroup
+
+
+\item \emph{at} to \emph{a\kern0pt t}
+
+\bgroup \em
+
+anathema aromatherapy intrathoracic metathesis ultrathin ultrathick
+\egroup
+
+\item \emph{et} to \emph{e\kern0pt t}
+
+\bgroup \em
+ninetieth ninetieths ninety nineteen
+
+nametag
+
+betake betatter betray betroth
+
+bluetooth
+
+detach detain detail
+
+detect undetectable detective
+
+detent detention detest
+
+detract detrain detribalize detriment detritus
+
+bristletail dovetail horsetail
+
+cheetah chetah caretaker
+
+foretell fortunetelling
+
+detergent deteriorate determent determinant
+
+preterm pretext
+
+retext teletext
+
+bluetick detick
+
+betide yuletide
+
+betime beforetime lifetime peacetime sometime
+
+detrain drivetrain housetrain pretrain retrain
+
+firetrap livetrap mousetrap
+
+axletree saddletree shoetree
+
+timetable
+
+preteen pretend pretence pretense pretentious pretest pretext pretitling
+
+pretreat pretrim pretrial
+
+retag retape retake reteach retie retile retime retint retire retiring retitle retrace retrack retract retrans retransmit retread retreat retrench retrieve retribution retries retrim retune
+
+return unreturnable
+
+entirety surety safety
+
+{\ebg entireties sureties safeties (EB Garamond for ``es''!)}
+
+archetype archetypal
+
+subtlety teletype teletypewriter
+
+\egroup
+
+
+\item \emph{as} to \emph{a\kern0pt s}
+
+\bgroup \em
+
+teaspoon infrastructure seastrand
+
+infraspecific intraspecies intraspecific
+
+ultrasound ultrasophisticated
+
+\egroup
+
+\item {\ebg \emph{es} to e\kern0pt s (EB Garamond)}
+
+\bgroup \ebg \em
+ loftiest scariest funniest \emph{(lots of words ending in ``iest'')}
+
+estrange estate establish
+
+\ \ \ \emph{but:} trespass
+
+
+\egroup
+
+
+\item \emph{is} to \emph{i\kern0pt s}
+
+\bgroup \em
+
+\emph{Lots of words \emph{starting} with ``anti\dots'':} antisag antisatellite antiscience antisecrecy antisense antiseptic antishark antiship antishock antiskid antislavery antislip antismog antismoke antismuggling antismut antisocial antisolar antispasmodic antispeculative antistatic antistick antistress antistrike antisubmarine antisubversion antisymmetric antisyphilitics
+
+\ \ \ \emph{but:} mantissa, gigantism, sycophantism, sycophantish
+
+\egroup
+
+\item {\ebg \emph{sk} to \emph{s\kern0pt k} (EB Garamond)}
+
+\bgroup \ebg \em
+greenskeeper groundskeeper
+
+triskaidekaphobia rathskeller
+
+miskeep miskept miskick misknow
+
+Catskills Peekskill
+
+\egroup
+
+
+
+\item \emph{ll} to \emph{l\kern0pt l}
+
+\bgroup \em
+animallike bowllike eellike jewellike owllike petallike seallike snaillike soullike taillike tunnellike veillike woollike
+
+bowelless coalless goalless heelless idealless keelless mailless mealless recoilless skilless skillessness skillessnesses soilless soulless soullessly soullessness soullessnesses tailless toolless trailless wheelless
+
+\egroup
+
+\item \emph{\uselig{ij}} to \emph{ij}
+
+\bgroup \em
+antijam hijack demijohns hijinks
+
+trijet trijets
+
+bijection bijective
+
+bijou bijouterie
+
+gaijin
+
+jipijapa marijuana frijoles
+
+\emph{but:} mijnheer, de Bruijn, rijsttafel (from Dutch)
+
+
+\egroup
+
+\end{itemize}
+
+
+
+\section*{Part 4: Cases where one ligature pre-empts the use of a subsequent ligature}
+
+\subsection*{Cases of \emph{as}, {\ebg \emph{es}}, \emph{is}, and \emph{us} ligatures pre-empting use of \emph{st} ligature}
+
+\bgroup \em
+
+\begin{itemize}
+\item as \emph{pre-empting} st
+
+abreast aghast alabaster antipasto astern astir astonish astound astride astringent astronomy astute avast
+
+bastard baste beast blast boast breakfast breast
+
+cast caste coast catastrophe chaste coast contrast
+
+devastate disaster drastic dynasty
+
+east ecclesiastic fast fasten feast forecast
+
+ghastly gastronomy gymnastics haste lambast last least
+
+mast master megastar metastable nasty oast oasthouse
+
+past pasta pastel pastor pasteurize plastic roast
+
+scholastic spastic steadfast stochastic toast upcoast waste yeast
+
+\item {\ebg es} \emph{pre-empting} st
+
+{\ebg
+establish
+estate
+esteem
+ester
+estrange
+estuary
+}
+
+
+
+
+\item is \emph{pre-empting} st
+
+fist gist grist heist list mist
+
+administer statistics statistically
+
+\emph{plus, \emph{hundreds} of words ending in -ist:}
+activist agronomist biologist etc.
+
+\ \ \ \emph{but:} m\uselig{is}think m\uselig{is}throw cal\uselig{is}thenic
+
+
+
+\item us \emph{pre-empting} st
+
+bust crust disgust dust exhaust joust just lust must oust rust thrust wanderlust
+
+
+\end{itemize}
+\egroup
+
+
+\subsection*{Cases of \emph{at} and \emph{et} ligatures pre-empting a \emph{th} ligature}
+
+\begin{itemize}
+\item \emph{at} ligature preempting the \emph{th} ligature
+
+\bgroup \em
+
+bath math lath lathe path
+
+atheism athlete
+
+beneath bequeath blather breath
+
+catharsis catheter cathode catholic catholicism
+
+death empathy father fathom feather
+
+gather heath heathen loath
+
+marathon oath pathetic pathology
+
+rather rathskeller
+
+scathe sheath slather strath swath
+
+triathlon triathlete weather wrath wreath
+
+
+\egroup
+\medskip
+Words for which the \emph{at} ligature need \emph{not} be suppressed in favor of the \emph{th} ligature:
+\emph{bathouse boathouse cathouse boathook meathook goatherd neatherd cathead fathead flathead meathead rathole greathearted}
+
+
+\item \emph{et} ligature preempting the \emph{th} ligature
+
+\bgroup \em
+bethank bethink bethorn bethought bethump
+
+dethrone doublethink firethorn flamethrower forethought freethinker methinks nonetheless nonethical
+
+rethink rethread something whitethroat
+
+twentieth thirtieth fortieth fiftieth sixtieth seventieth eightieth ninetieth hundreth
+
+amethyst bellwether brethren ethical ethane ether ethnic ethyl lethal lethargic methadone method plethora seethe teeth teethe tether together urethane
+
+\egroup
+\medskip
+Words for which \emph{et}-ligature needn't be suppressed:
+\emph{Beethoven prophethood sweetheart sweethearts}
+
+\end{itemize}
+
+
+\subsection*{Cases of \emph{as}-, \emph{\ebg es}, \emph{is}-, and \emph{us}-ligatures pre-empting use of \emph{sp}-ligature}
+
+\bgroup \em
+asparagus aspidistra aspect aspire Casper Caspar clasp gasp grasp hasp Jasper rasp raspberry wasp \emph{(but what to do about} asp\emph{?)}
+
+megaspores tetraspore
+
+{\ebg
+archesporia bespake bespatter bespeak bespoke bespoke besprinkle
+
+espy espied espionage counterespionage
+
+despair desperation desperado
+despise despite
+
+especially
+esplanade
+espouse
+
+finespun homespun
+gelandesprung
+
+prespecified
+
+respell respire respiratory
+respect disrespect
+doublespeak
+respray respring
+tablespoon
+
+
+\ \ \ \emph{but:} clothespin clothespress despot salespeople spokesperson trespass
+}
+
+crisp lisp whisper wisp
+
+\ \ \ \emph{but:} disparity dispart mispackage misplace
+
+cusp tricuspid, auspicious suspect suspicious
+
+\ \ \ \emph{but:} suspend suspense suspension etc.
+
+\egroup
+
+
+\subsection*{Cases of an \emph{et} ligature pre-empting a \emph{ta} ligature}
+
+Note: It appears to be the case that in all instances for which an \emph{et} ligature should be suppressed in favor of a subsequent \emph{ta} ligature, the \emph{et} ligature spans a morpheme boundary and hence shouldn't be used anyway. Some examples:
+
+\bgroup \em
+betake betatter bristletail caretaker cheetah
+detach detail detain dovetail
+foretaste horsetail nametag pretake
+pretape pretaste pretax retable retack
+retag retape retake retaliate retard retarget
+whitetail wiretap
+
+\egroup
+\medskip
+Note that the \emph{et}-ligature should not be suppressed \emph{globally} in favor of a subsequent \emph{ta} ligature because of the following groups of words:
+
+\bgroup \em
+\begin{itemize}
+\item \emph{Words ending in -et-ary:}
+budgetary dietary monetary planetary proprietary secretary
+
+\item \emph{Words ending in -et-able :}
+covetable depletable getable interpretable marketable pocketable vegetable (but: retable, timetable)
+
+\item \emph{Words ending in -et-al:} centripetal
+metal petal skeletal societal varietal vegetal
+
+\item \emph{Words containing metal:} metal metallic metallurgy
+\end{itemize}
+\egroup
diff --git a/macros/luatex/latex/selnolig/selnolig-german-hyphex.sty b/macros/luatex/latex/selnolig/selnolig-german-hyphex.sty
new file mode 100644
index 0000000000..03560441b6
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig-german-hyphex.sty
@@ -0,0 +1,6402 @@
+% !TeX root = selnolig.tex
+% !TEX TS-program = lualatex
+
+\RequirePackage{ifluatex} % provides \ifluatex macro
+\ProvidesPackage{selnolig-german-hyphex}%
+[2015/10/26]
+
+% This entire package is placed under the
+% terms of the LaTeX Project Public License,
+% version 1.3 or later
+% (http://www.latex-project.org/lppl.txt).
+% It has the status "maintained".
+%
+% Author: Mico Loretan
+% (loretan dot mico at gmail dot com)
+
+\hyphenation{
+ab-brand-an-flug
+ab-brand-an-flu-ges
+ab-flug-ruf
+ab-flug-ru-fe
+ab-flug-ru-fen
+ab-flug-ru-fes
+ab-fluss-trich-ter
+ab-fluss-trich-tern
+ab-fluss-trich-ters
+ab-hol-auf-for-de-rung
+ab-hol-auf-for-de-run-gen
+ab-hol-auf-trag
+ab-hol-auf-tra-gs
+ab-lauf-trich-ter
+ab-lauf-trich-tern
+ab-lauf-trich-ters
+ab-setz-ei-gen-schaft
+ab-setz-ei-gen-schaf-ten
+ab-sinth-fla-sche
+ab-sinth-fla-schen
+ab-strahl-ef-fekt
+ab-strahl-ef-fekte
+ab-strahl-ef-fek-ten
+ab-strahl-ef-fek-tes
+ab-wurf-la-dung
+ab-wurf-la-dun-gen
+ab-wurf-last
+ab-wurf-li-nie
+ab-wurf-li-ni-en
+ab-wurf-lu-ke
+ach-ter-schiff
+ach-ter-schif-fe
+ach-ter-schif-fen
+ach-ter-schiffs
+ac-tion-gru-sel-film
+ac-tion-gru-sel-fil-me
+ac-tion-gru-sel-fil-men
+ac-tion-gru-sel-films
+ac-tion-gru-sel-film-chen
+ac-tion-gru-sel-film-chens
+adop-tiv-nef-fe
+adop-tiv-nef-fen
+aero-flot
+af-fekt-er-le-di-gung
+af-fekt-er-le-di-gun-gen
+af-fekt-er-re-gung
+af-fekt-er-re-gun-gen
+af-fekt-epi-lep-sie
+af-fekt-epi-lep-si-en
+af-fekt-in-kon-ti-nenz
+af-fekt-re-ak-ti-on
+af-fekt-re-ak-tio-nen
+af-fen-ad-ler
+af-fen-ad-lern
+af-fen-ad-lers
+af-fen-ze-cke
+af-fen-ze-cken
+af-ter-image
+af-ter-ima-ges
+af-ter-shave
+af-ter-shave-lo-ti-on
+af-ter-shave-lo-tio-nen
+af-ter-skor-pi-on
+af-ter-skor-pio-nen
+al-ko-hol-ef-fekt
+al-ko-hol-ef-fek-te
+al-ko-hol-ef-fek-ten
+al-ters-ef-fekt
+al-ters-ef-fek-te
+al-ters-ef-fek-ten
+al-ters-pon-ti-fi-kat
+al-ters-pon-ti-fi-kats
+al-ters-pro-fil
+al-ters-pro-fi-le
+al-ters-pro-fi-len
+al-ters-pro-fils
+al-ters-wis-sen-schaft
+al-ters-wis-sen-schaf-ten
+al-ters-zer-ti-fi-zie-rung
+alt-ort-schaft
+alt-ort-schaf-ten
+alt-roh-stoff
+alt-roh-stof-fe
+alt-roh-stof-fen
+alt-roh-stoffs
+alu-flach-stab
+ame-ri-ka-luft-schiff
+ame-ri-ka-luft-schif-fe
+ame-ri-ka-luft-schif-fen
+ame-ri-ka-luft-schiffs
+am-mo-niak-ent-gif-tung
+am-mo-niak-ent-gif-tun-gen
+am-mo-ni-um-sul-fid
+ana-nas-pflan-ze
+ana-nas-pflan-zen
+an-bau-pflan-ze
+an-bau-pflan-zen
+an-bau-pflug
+an-bau-pflu-ges
+an-bau-pflugs
+an-den-kar-tof-fel
+an-den-kar-tof-feln
+an-ge-impft
+an-gel-aus-flug
+an-gel-aus-flu-ge
+an-gel-aus-flu-ges
+an-gel-aus-flugs
+an-ge-stell-ten-fluk-tu-a-ti-on
+an-ge-stell-ten-fluk-tu-a-tio-nen
+an-griffs-idee
+an-griffs-ide-en
+an-griffs-pan-zer
+an-griffs-pan-zern
+an-griffs-pan-zers
+an-griffs-tar-nung
+an-griffs-tar-nun-gen
+an-griffs-team
+an-griffs-teams
+an-griffs-ur-sa-che
+an-griffs-ur-sa-chen
+angst-af-fekt
+angst-af-fek-te
+angst-af-fek-ten
+angst-re-flex
+angst-re-fle-xe
+angst-re-fle-xen
+angst-re-fle-xes
+an-la-ge-stif-tung
+an-la-ge-stif-tun-gen
+an-ti-atom-kraft-be-we-gung
+an-ti-atom-kraft-be-we-gun-gen
+an-ti-haft-ef-fekt
+an-ti-haft-ef-fek-te
+an-ti-haft-ef-fek-ten
+an-ti-haft-ef-fekts
+an-ti-mon-sul-fid
+ant-wort-re-flex
+ant-wort-re-fle-xe
+ant-wort-re-fle-xen
+ar-beits-markt-ef-fekt
+ar-beits-markt-ef-fek-te
+ar-beits-markt-ef-fek-ten
+ar-sen-fla-sche
+ar-sen-fla-schen
+ar-sen-kampf-stoff
+ar-sen-kampf-stof-fe
+ar-sen-kampf-stof-fen
+ar-sen-kampf-stoffs
+ar-sen-ver-gif-tung
+ar-sen-ver-gif-tun-gen
+ar-til-le-rie-flie-ger
+arzt-ab-rech-nungs-soft-ware
+aschen-tuff
+aschen-tuf-fe
+aschen-tuf-fen
+as-tro-treff
+as-tro-treffs
+as-tro-treff-the-men
+atem-pfle-ge
+atem-pfle-gen
+at-lan-tik-luft
+au-dio-file
+auf-fahrt-ram-pe
+auf-fahrt-ram-pen
+auf-fang-alm
+auf-fang-al-men
+auf-fang-sacks
+auf-fang-sa-ckes
+auf-fang-trich-ter
+auf-fang-trich-tern
+auf-fang-trich-ters
+auf-frisch-imp-fung
+auf-frisch-imp-fun-gen
+auf-ga-ben-ei-gen-schaft
+auf-ga-ben-ei-gen-schaf-ten
+auf-prall-ef-fekt
+auf-prall-ef-fek-te
+auf-prall-ef-fek-ten
+auf-prall-ei-gen-schaft
+auf-prall-ei-gen-schaf-ten
+auf-trags-ta-bel-le
+auf-trags-ta-bel-len
+auf-trags-ta-fel
+auf-trags-tak-tik
+auf-trags-tak-ti-ken
+auf-tritts-arie
+auf-tritts-ari-en
+au-gen-aus-fluss
+au-gen-auf-flus-ses
+aus-fall-an-griff
+aus-fall-an-grif-fe
+aus-fall-an-grif-fen
+aus-fall-an-griffs
+aus-flo-cken
+aus-flo-ckens
+aus-flo-ckung
+aus-flugs-areal
+aus-flugs-area-le
+aus-flugs-area-len
+aus-flugs-au-to-bus
+aus-flugs-in-sel
+aus-flugs-in-seln
+aus-flugs-res-tau-rant
+aus-flugs-res-tau-rants
+aus-lands-toch-ter-ge-sell-schaft
+aus-lands-toch-ter-ge-sell-schaf-ten
+aus-kunft-schal-ter
+aus-kunft-schal-tern
+aus-kunft-schal-ters
+aus-puff-ab-gas
+aus-puff-ab-ga-se
+aus-puff-ab-ga-sen
+aus-puff-end-ohr
+aus-puff-end-oh-re
+aus-puff-end-oh-ren
+aus-puff-end-rohr
+aus-puff-end-roh-re
+aus-puff-end-roh-res
+aus-puff-lack
+aus-puff-lei-tung
+aus-puff-lei-tun-gen
+aus-puff-los
+aus-puff-luft
+aus-puff-to-pfes
+aus-puff-topfs
+aus-tausch-of-fi-zier
+aus-tausch-of-fi-zie-re
+aus-tausch-of-fi-zie-ren
+aus-tausch-of-fi-ziers
+aus-wahl-ef-fekt
+aus-wahl-ef-fek-te
+aus-wahl-ef-fek-ten
+aus-wahl-tref-fen
+aus-wahl-tref-fens
+aus-wan-de-rer-schiff
+aus-wan-de-rer-schif-fe
+aus-wan-de-rer-schif-fen
+aus-wan-de-rer-schiffs
+aus-wurf-leis-tung
+aus-wurf-leis-tun-gen
+au-to-mo-bil-flot-te
+au-to-mo-bil-flot-ten
+au-to-flau-te
+au-to-pfle-ge
+au-to-pfle-gen
+au-to-pfle-ge-mit-tel
+au-to-pfle-ge-mit-teln
+au-to-pfle-ge-mit-tels
+au-to-pfle-ge-pro-dukt
+au-to-pfle-ge-pro-duk-te
+au-to-pfle-ge-pro-duk-ten
+au-to-pfle-ge-pro-duk-tes
+back-fisch-al-ter
+back-fisch-al-ters
+back-fisch-li-te-ra-tur
+back-fisch-li-te-ra-tu-ren
+back-fisch-ro-man
+back-fisch-ro-ma-ne
+back-fisch-ro-ma-nen
+back-fisch-ro-mans
+bahn-elek-tri-fi-zie-rung
+bahn-elek-tri-fi-zie-run-gen
+bahn-hof-fo-to
+bahn-hof-fo-tos
+bahn-nei-gungs-flug
+bahn-nei-gungs-flu-ges
+bahn-nei-gungs-flugs
+ball-ein-wurf-loch
+bal-sam-pflan-ze
+bal-sam-pflan-zen
+band-pro-fil-walz-an-la-ge
+band-pro-fil-walz-an-la-gen
+bart-af-fe
+bart-af-fen
+ba-salt-tuff
+ba-salt-tuf-fe
+ba-salt-tuf-fen
+ba-sis-tref-fen
+ba-sis-tref-fens
+bat-te-rie-griff
+bat-te-rie-grif-fe
+bat-te-rie-grif-fen
+bass-ef-fekt
+bass-ef-fek-te
+bass-ef-fek-ten
+bass-emp-fin-den
+bau-art-spe-zi-fi-ka-ti-on
+bau-art-spe-zi-fi-ka-tio-nen
+bauch-haut-re-flex
+bauch-haut-re-fle-xe
+bauch-haut-re-fle-xen
+bau-ern-hof-fahrt
+bau-ern-hof-fahr-ten
+bau-ern-hof-frei-zeit
+bau-flau-te
+bau-flau-ten
+bau-flucht
+bau-flucht-li-nie
+bau-flucht-li-ni-en
+bau-hof-fahr-zeug
+bau-hof-fahr-zeu-ge
+baum-an-pflan-zung
+baum-an-pflan-zun-gen
+baum-ei-gen-schaft
+baum-ei-gen-schaf-ten
+baum-woll-an-pflan-zung
+baum-woll-an-pflan-zun-gen
+bau-pfle-ge
+bau-pfle-gen
+bau-pflicht
+bau-pflich-ten
+bau-platz-ei-gen-schaft
+bau-platz-ei-gen-schaf-ten
+bau-stoff-ei-gen-schaft
+bau-stoff-ei-gen-schaf-ten
+bau-stoff-er-zeu-gung
+bau-stoff-er-zeu-gun-gen
+bau-stoff-sor-ti-ment
+bau-stoff-sor-ti-men-te
+bau-stoff-sor-ti-men-ten
+beau-ty-fo-to-gra-fie
+beau-ty-fo-to-gra-fi-en
+be-gleit-ef-fekt
+be-gleit-ef-fek-te
+be-gleit-ef-fek-ten
+be-griffs-ab-lei-tung
+be-griffs-ab-lei-tun-gen
+be-griffs-an-ein-an-der-rei-hung
+be-griffs-an-ein-an-der-rei-hun-gen
+be-griffs-cha-os
+be-griffs-ein-en-gung
+be-griffs-ein-en-gun-gen
+be-griffs-im-pe-ria-lis-mus
+be-griffs-um-schrei-bung
+be-griffs-um-schrei-bun-gen
+be-griffs-ur-sprung
+be-griffs-ur-sprungs
+be-nut-zer-iden-ti-fi-ka-ti-on
+be-nut-zer-iden-ti-fi-zie-rung
+be-nut-zer-iden-ti-fi-zie-run-gen
+ber-ber-af-fe
+ber-ber-af-fen
+berg-af-fe
+berg-af-fen
+berg-aus-flug
+berg-aus-flu-ges
+berg-aus-flugs
+berg-ef-fekt
+berg-ef-fek-te
+berg-ef-fek-ten
+berg-lei-den-schaft
+berg-lei-den-schaf-ten
+be-reit-schafts-ta-sche
+be-reit-schafts-ta-schen
+be-ton-kopf-li-nie
+be-triebs-fluk-tu-a-ti-on
+be-triebs-fluk-tu-a-tio-nen
+bi-bel-auf-fas-sung
+bi-bel-auf-fas-sun-gen
+bi-ber-fla-den
+bi-ber-fla-dens
+bi-blio-theks-pro-fil
+bi-blio-theks-pro-fi-le
+bi-blio-theks-pro-fi-len
+bi-blio-theks-pro-fils
+bie-nen-gift-sal-be
+bie-nen-gift-sal-ben
+bild-er-fin-dung
+bild-er-fin-dun-gen
+bil-lard-ku-gel-ef-fekt
+bil-lard-ku-gel-ef-fek-te
+bil-lard-ku-gel-ef-fek-ten
+bil-lig-flug-seg-ment
+bil-lig-flug-seg-men-te
+bil-lig-flug-seg-men-ten
+bin-de-stoff
+bin-de-stoffs
+bin-de-stof-fe
+bin-de-stof-fen
+bio-pflas-ter
+%bi-schof-fin-ger
+bis-tums-pa-ten-schaft
+bis-tums-pa-ten-schaf-ten
+blan-ko-un-ter-schrift
+blan-ko-un-ter-schrif-ten
+blatt-alu-mi-ni-um-auf-la-ge
+blatt-alu-mi-ni-um-auf-la-gen
+blau-farb-stoff
+blau-farb-stof-fe
+blau-farb-stof-fen
+blau-farb-stoffs
+blau-fil-ter
+blau-fil-tern
+blau-fil-ters
+blau-flau-schig
+blau-flau-schi-ge
+blau-flau-schi-gen
+blau-fle-ckig
+blau-fle-cki-ge
+blau-fle-ckig-keit
+blau-topf-lo-go
+bleich-fi-xier-ba-des
+blei-stift-strich
+blei-stift-stri-che
+blei-stift-stri-chen
+blei-stift-trick
+blei-stift-tricks
+blink-ef-fekt
+blink-ef-fek-te
+blink-ef-fek-ten
+blink-schrift
+blink-schrif-ten
+bluff-leck
+brei-flo-cken
+bo-den-ne-bel-ef-fekt
+bo-den-ne-bel-ef-fek-te
+bo-den-ne-bel-ef-fek-ten
+bo-den-see-schiff-fahrts-pa-tent
+bo-den-see-schiff-fahrts-pa-ten-te
+bo-den-see-schiff-fahrts-pa-ten-ten
+bord-waf-fen-an-ord-nung
+bord-waf-fen-an-ord-nun-gen
+bot-schafts-tre-sor
+bot-schafts-tre-so-re
+bot-schafts-tre-so-ren
+box-calf-le-der
+box-calf-le-ders
+brat-ei-gen-schaft
+brat-ei-gen-schaf-ten
+brech-kraft-ano-ma-lie
+brech-kraft-ano-ma-li-en
+brenn-glas-ef-fekt
+brenn-glas-ef-fek-te
+brenn-glas-ef-fek-ten
+brenn-punkt-ei-gen-schaft
+brenn-punkt-ei-gen-schaf-ten
+brenn-stoff-art
+brenn-stoff-ar-ten
+brenn-stoff-ein-satz
+brenn-stoff-ein-sat-zes
+brenn-stoff-ein-spa-rung
+brenn-stoff-ein-spa-run-gen
+brenn-stoff-ele-ment
+brenn-stoff-ele-men-te
+brenn-stoff-ele-men-ten
+brenn-stoff-ener-gie
+brenn-stoff-ener-gi-en
+brenn-stoff-er-spar-nis
+brenn-stoff-im-port
+brenn-stoff-im-por-te
+brenn-stoff-im-por-ten
+brenn-stoff-spei-cher
+brenn-stoff-spei-chers
+brenn-stoff-stab
+brenn-stoff-sta-bes
+brenn-stoff-stro-mes
+brenn-stoff-ta-ges-tank
+brenn-wert-ef-fekt
+brenn-wert-ef-fek-te
+brenn-wert-ef-fek-ten
+brief-ab-schrift
+brief-ab-schrif-ten
+brief-in-tri-ge
+brief-in-tri-gen
+bron-ze-in-schrift
+bron-ze-in-schrif-ten
+bruch-emp-find-lich-keit
+brunft-ruf
+brunft-ru-fe
+brunft-ru-fen
+brunft-rufs
+brunft-schrei
+brunft-schreie
+brunft-schrei-en
+brunft-schauf-ler
+brut-pfle-ge-instinkt
+brut-pfle-ge-instink-te
+brut-pfle-ge-instink-ten
+brut-to-tref-fer
+brut-to-tref-fern
+brut-to-tref-fers
+bu-bi-kopf-fri-sur
+bu-bi-kopf-fri-su-ren
+buch-iden-ti-fi-ka-ti-ons-num-mer
+buch-iden-ti-fi-ka-ti-ons-num-mern
+buch-sta-ben-ei-gen-schaft
+buch-sta-ben-ei-gen-schaf-ten
+bun-des-fi-nanz-hof-ent-schei-dung
+bun-des-fi-nanz-hof-ent-schei-dun-gen
+burg-graf-tum
+but-ter-fly-stil
+but-ter-fly-sti-les
+but-ter-fly-stils
+cal-ci-um-sul-fid
+cal-ci-um-sul-fi-de
+cal-ci-um-sul-fi-den
+cam-ping-aus-flug
+cam-ping-aus-flu-ges
+cam-ping-aus-flugs
+cha-rak-ter-er-schaf-fung
+cha-rak-ter-er-schaf-fun-gen
+chef-in-nen-le-ben
+chef-in-nen-raum
+chef-li-mou-si-ne
+chef-li-mou-si-nen
+chef-of-fi-zier
+chef-of-fi-zie-re
+chef-of-fi-zie-ren
+chef-of-fi-ziers
+che-mie-roh-stoff
+che-mie-roh-stof-fe
+che-mie-roh-stof-fen
+che-mie-roh-stoffs
+chi-li-pflan-ze
+chi-li-pflan-zen
+chif-fre-text-raum
+chif-fre-text-rau-mes
+chif-frier-al-go-rith-mus
+chi-na-fla-neur
+cola-fla-sche
+cola-fla-schen
+co-mic-heft
+co-mic-hef-te
+co-mic-hef-ten
+co-mic-heft-chen
+com-pu-ter-ste-no-gra-fie
+com-pu-ter-ste-no-gra-fi-en
+dampf-fre-gat-te
+dampf-fre-gat-ten
+dampf-in-ha-la-ti-on
+dampf-in-ha-la-tio-nen
+dampf-in-jek-ti-on
+dampf-in-jek-tio-nen
+dampf-lan-ze
+dampf-lan-zen
+dampf-schiff-sta-ti-on
+dampf-schiff-sta-tio-nen
+dampf-top-fes
+dampf-topfs
+da-tei-suf-fix
+da-tei-suf-fi-xe
+da-tei-suf-fi-xen
+da-ten-ana-ly-se-ei-gen-schaft
+da-ten-ana-ly-se-ei-gen-schaf-ten
+dau-er-spar-auf-trag
+dau-er-spar-auf-trags
+dau-er-spar-auf-tra-ges
+dau-er-tropf-in-fu-si-on
+dau-er-tropf-in-fu-sio-nen
+da-vi-doff
+deck-of-fi-zier
+deck-of-fi-zie-re
+deck-of-fi-zie-ren
+deck-of-fi-ziers
+del-ta-flie-gens
+del-ta-flie-ger
+del-ta-flie-gern
+de-mo-kra-tie-flau-te
+denk-auf-fas-sung
+denk-auf-fas-sun-gen
+denk-ein-fluss
+denk-ein-flus-ses
+den-tal-suf-fix
+den-tal-suf-fi-xe
+den-tal-suf-fi-xen
+deo-stift
+deo-stif-te
+deo-stif-ten
+deo-stif-tes
+de-pot-ef-fekt
+de-pot-ef-fek-te
+de-pot-ef-fek-ten
+de-sign-auf-trag
+de-sign-auf-tra-ges
+de-sign-auf-trags
+de-sign-che-fin
+de-sign-ei-gen-schaft
+de-sign-ei-gen-schaf-ten
+de-sign-fin-dung
+de-sign-fin-dun-gen
+de-sign-wis-sen-schaft
+de-sign-wis-sen-schaf-ten
+de-sign-wis-sen-schaft-ler
+deutsch-or-dens-herr-schaft
+dich-ter-hand-schrift
+dich-ter-hand-schrif-ten
+dicht-stoff-ent-wick-lung
+dicht-stoff-ent-wick-lun-gen
+dif-fe-ren-ti-al-blut-bild
+dif-fe-ren-ti-al-blut-bil-der
+dif-fe-ren-ti-al-blut-bil-dern
+dif-fe-ren-ti-al-blut-bil-des
+dif-fe-ren-ti-al-glied
+dif-fe-ren-ti-al-glie-der
+dif-fe-ren-ti-al-glie-des
+dif-fe-ren-ti-al-ope-ra-ti-on
+dif-fe-ren-ti-al-ope-ra-tio-nen
+dif-fe-ren-ti-al-ope-ra-tor
+dif-fe-ren-ti-al-ope-ra-to-ren
+dif-fe-ren-ti-al-ope-ra-tors
+dif-fe-ren-ti-al-ther-mo-ana-ly-se
+dif-fe-ren-ti-al-ther-mo-ana-ly-sen
+dif-fe-renz-er-mitt-lung
+dif-fe-renz-er-mitt-lun-gen
+di-mi-nu-tiv-suf-fix
+di-mi-nu-tiv-suf-fi-xe
+diph-the-rie-impf-stoff
+diph-the-rie-impf-stof-fe
+diph-the-rie-impf-stof-fen
+diph-the-rie-impf-stoffs
+dis-tanz-pflock
+dis-tanz-pflo-ckes
+dis-zi-pli-nar-of-fi-zier
+dis-zi-pli-nar-of-fi-zie-re
+dis-zi-pli-nar-of-fi-zie-ren
+dis-zi-pli-nar-of-fi-ziers
+dok-tor-fisch-art
+do-ku-ment-ei-gen-schaft
+do-ku-ment-ei-gen-schaf-ten
+do-nau-fluss
+do-nau-fluss-bett
+do-nau-fluss-bet-tes
+do-nau-ge-sell-schaft
+do-nau-graf-schaft
+do-nau-graf-schaf-ten
+dop-pel-ef-fekt
+dop-pel-ef-fek-te
+dop-pel-ef-fek-ten
+dop-pel-end-rohr-aus-puff
+dop-pel-end-rohr-aus-puf-fe
+dop-pel-end-rohr-aus-puf-fen
+dop-pel-end-rohr-aus-puffs
+dop-pel-im-mun-fluo-res-zenz
+dop-pel-kopf-li-nie
+dop-pel-kopf-li-ni-en
+dop-pel-tref-fer
+dop-pel-tref-fern
+dop-pel-tref-fers
+dorf-fas-nets-um-zug
+dorf-idyl-le
+dorf-idyl-len
+dorf-in-for-ma-ti-on
+dorf-in-for-ma-ti-o-nen
+dorf-in-nen-raum
+dorf-in-nen-rau-mes
+dorf-in-sti-tut
+dorf-in-sti-tu-te
+dorf-in-sti-tu-ten
+dorf-in-sti-tuts
+dorf-la-ge
+dorf-la-gen
+dorf-leit-plan
+dorf-lis-te
+dorf-lis-ten
+dorf-tanz
+do-sen-thun-fisch
+do-sen-thun-fischs
+dot-off-set
+dot-off-sets
+dovre-fjell
+dreh-film-ort
+dreh-film-or-te
+dreh-film-or-ten
+drei-ecks-part-ner-schaft
+drei-ecks-part-ner-schaf-ten
+drei-fleck
+drei-fle-cke
+drei-fle-cken
+droh-of-fen-si-ve
+druck-luft-ra-ke-te
+druck-luft-ra-ke-ten
+druck-luft-schei-ben-brem-se
+druck-luft-schei-ben-brem-sen
+druck-luft-spann-zan-ge
+druck-luft-spann-zan-gen
+druck-luft-tank
+druck-luft-tanks
+druck-schlag-ef-fekt
+druck-schlag-ef-fek-te
+druck-schlag-ef-fek-ten
+druck-un-emp-find-lich
+druck-un-emp-find-li-che
+druck-un-emp-find-li-chem
+druck-un-emp-find-li-chen
+druck-un-emp-find-li-cher
+druck-un-emp-find-li-ches
+druck-ver-lust-ei-gen-schaft
+druck-ver-lust-ei-gen-schaf-ten
+druck-was-ser-stoff-spei-che-rung
+druck-was-ser-stoff-spei-che-run-gen
+duft-er-geb-nis
+duft-er-geb-nis-se
+duft-er-geb-nis-sen
+duft-er-geb-nis-ses
+duft-er-leb-nis
+duft-er-leb-nis-se
+duft-er-leb-nis-sen
+duft-er-leb-nis-ses
+duft-es-senz
+duft-es-sen-zen
+duft-in-for-ma-ti-on
+duft-in-for-ma-tio-nen
+duft-or-gan
+duft-or-ga-ne
+duft-or-ga-nen
+duft-or-gans
+duft-or-gel
+duft-or-geln
+duft-or-gie
+duft-or-gi-en
+duft-reiz
+duft-rei-ze
+duft-rei-zes
+duft-rich-tung
+duft-rich-tun-gen
+echo-ef-fekt
+echo-ef-fek-te
+echo-ef-fek-ten
+echo-flos-kel
+echo-flos-keln
+ef-fek-ten-emis-si-on
+ef-fek-ten-emis-sio-nen
+ef-fek-ten-en-gage-ment
+ef-fek-ten-en-gage-ments
+ef-fek-ten-stem-pel
+ef-fek-ten-stem-peln
+ef-fek-ten-stem-pels
+ef-fek-tiv-strom
+ef-fek-tiv-stro-mes
+ef-fek-tiv-zins-er-mitt-lung
+ef-fek-tiv-zins-er-mitt-lun-gen
+ef-fekt-reich
+ef-fekt-rei-che
+ef-fekt-rei-chem
+ef-fekt-rei-chen
+ef-fekt-rei-cher
+ef-fekt-rei-ches
+ef-fi-zi-enz-as-pekt
+ef-fi-zi-enz-as-pek-te
+ef-fi-zi-enz-as-pek-tes
+eich-hof-fried-hof
+eich-hof-fried-ho-fes
+ei-gen-lenk-ef-fekt
+ei-gen-lenk-ef-fek-te
+ei-gen-lenk-ef-fek-ten
+ei-gen-schafts-ta-bel-le
+ei-gen-schafts-ta-bel-len
+ei-lei-ter-schan-ger-schaft
+ei-lei-ter-schan-ger-schaf-ten
+ein-lauf-trich-ter
+ein-lauf-trich-tern
+ein-lauf-trich-ters
+ein-wurf-lu-ke
+ein-nah-me-dif-fe-renz
+ein-nah-me-dif-fe-ren-zen
+ein-satz-stabs-of-fi-zier
+ein-satz-stabs-of-fi-zie-re
+ein-satz-stabs-of-fi-zie-ren
+ein-satz-stabs-of-fi-ziers
+ein-weg-ef-fekt
+ein-weg-ef-fek-te
+ein-weg-ef-fek-ten
+ein-zel-pro-te-in-iden-ti-fi-ka-ti-on
+ein-zel-tref-fen
+ein-zel-tref-fens
+eis-flo-cke
+eis-flo-cken
+eis-lauf-in-stru-ment
+eis-lauf-in-stru-men-te
+eis-lauf-in-stru-men-ten
+eis-treff
+eis-treffs
+ekel-ef-fekt
+ekel-ef-fek-te
+ekel-ef-fek-ten
+ekel-emp-find-lich-keit
+ekel-emp-find-lich-kei-ten
+elek-tro-flo-rett
+elek-tro-flo-ret-te
+elek-tro-flo-ret-ten
+elek-tro-iso-lier-stoff
+elek-tro-iso-lier-stof-fe
+elek-tro-iso-lier-stof-fen
+elek-tro-iso-lier-stoffs
+ele-men-tar-ei-gen-schaft
+ele-men-tar-ei-gen-schaf-ten
+elf-land
+elf-lan-des
+elf-me-ter-tref-fer
+elf-me-ter-tref-fern
+el-tern-ei-gen-schaft
+el-tern-ei-gen-schaf-ten
+end-an-flug
+end-an-flu-ges
+end-an-flugs
+end-an-flug-kon-trol-le
+end-an-flug-kon-trol-len
+end-an-flug-rech-ner
+end-an-flug-rech-nern
+end-los-kon-flikt
+end-los-kon-flik-te
+end-los-kon-flik-ten
+end-los-kon-flik-tes
+end-los-kon-flikts
+end-los-pro-fil
+end-los-pro-fi-le
+end-los-pro-fi-len
+end-los-pro-fils
+en-er-gie-flau-te
+en-er-gie-roh-stoff
+en-er-gie-roh-stof-fe
+en-er-gie-roh-stof-fen
+en-er-gie-roh-stoffs
+en-ten-fi-gur
+en-ten-fi-gu-ren
+en-ten-fleisch
+en-ten-flin-te
+en-ten-flin-ten
+en-ten-flug-zeug
+en-ten-flug-zeu-ge
+en-ten-flug-zeu-gen
+en-ten-flug-zeugs
+en-ten-ge-fie-der
+en-ten-ge-fie-dern
+en-ten-ge-fie-ders
+en-ten-kon-fi-gu-ra-ti-on
+en-ten-kon-fi-gu-ra-tio-nen
+erb-auf-tei-lung
+erb-auf-tei-lun-gen
+erb-ei-gen-schaft
+erb-ei-gen-schaf-ten
+erb-ein-fluss
+erb-ein-flus-ses
+erb-hof-fa-mi-lie
+erb-hof-fa-mi-li-en
+erd-er-schaf-fung
+erd-er-schaf-fun-gen
+er-eig-nis-iden-ti-fi-ka-ti-on
+ern-te-af-fe
+ern-te-af-fen
+erst-an-griff
+erst-an-grif-fe
+erst-an-grif-fen
+erst-an-griffs
+erst-an-griffs-fahr-zeug
+erst-an-griffs-fahr-zeu-ge
+erst-an-griffs-fahr-zeu-gen
+erst-an-griffs-fahr-zeugs
+erst-au-tor-schaft
+erst-au-tor-schaf-ten
+erst-jah-res-fluk-tu-a-ti-on
+erst-jah-res-fluk-tu-a-tio-nen
+eu-ro-fla-sche
+eu-ro-fla-schen
+eu-ro-pa-flag-ge
+eu-ro-pa-flag-gen
+eu-ro-pa-fla-sche
+eu-ro-pa-fla-schen
+fa-brik-fang-schiff
+fa-brik-fang-schif-fe
+fa-brik-fang-schif-fen
+fa-brik-fang-schiffs
+fah-rer-fi-gur
+fah-rer-fi-gu-ren
+fahrt-ei-gen-schaft
+fahrt-ei-gen-schaf-ten
+fahr-zeug-iden-ti-fi-ka-tions-num-mer
+fahr-zeug-iden-ti-fi-ka-tions-num-mern
+fahr-zeug-iden-ti-fi-ka-tions-sys-tem
+fahr-zeug-iden-ti-fi-ka-tions-sys-te-me
+fahr-zeug-iden-ti-fi-ka-tions-sys-te-men
+fahr-zeug-iden-ti-fi-ka-tions-sys-tems
+fang-schiff
+fang-schif-fe
+fang-schif-fen
+fang-schiffs
+fan-ta-sie-flie-ger
+farb-ef-fekt
+farb-ef-fek-te
+farb-ef-fek-ten
+farb-emp-fin-den
+farb-emp-fin-dens
+farb-emp-find-lich
+farb-emp-find-li-che
+farb-emp-find-li-chem
+farb-emp-find-li-chen
+farb-emp-find-li-cher
+farb-emp-find-li-ches
+farb-emp-find-lich-keit
+farb-emp-find-lich-kei-ten
+farb-emp-fin-dung
+farb-emp-fin-dun-gen
+farb-er-fin-dung
+farb-er-fin-dun-gen
+farb-iden-ti-fi-ka-ti-ons-schal-ter
+farb-iden-ti-fi-ka-ti-ons-schal-tern
+farb-iden-ti-fi-ka-ti-ons-schal-ters
+farb-li-tho-gra-fie
+farb-li-tho-gra-fi-en
+farb-stoff-ein-tei-lung
+farb-stoff-ein-tei-lun-gen
+farb-stoff-ent-wick-lung
+farb-stoff-ent-wick-lun-gen
+farb-stoff-sor-ti-ment
+farb-stoff-sor-ti-men-te
+farb-stoff-sor-ti-men-ten
+farb-stoff-tin-te
+fa-ser-ei-gen-schaft
+fa-ser-ei-gen-schaf-ten
+feh-ler-ei-gen-schaft
+feh-ler-ei-gen-schaf-ten
+fehl-er-fin-dung
+fehl-er-fin-dun-gen
+feh-ler-iden-ti-fi-ka-ti-ons-quo-te
+feh-ler-iden-ti-fi-ka-ti-ons-quo-ten
+feh-ler-kor-rek-tur-ei-gen-schaft
+feh-ler-kor-rek-tur-ei-gen-schaf-ten
+fehl-iden-ti-fi-ka-ti-on
+fehl-tref-fer
+fehl-tref-fern
+fehl-tref-fers
+fel-da-fing
+fel-sen-kliff
+fel-sen-kliffs
+fern-seh-trick-film-se-rie
+fern-seh-trick-film-se-ri-en
+fern-sprech-auf-trags-dienst
+fern-sprech-auf-trags-diens-te
+fern-sprech-auf-trags-diens-ten
+fern-sprech-auf-trags-diens-tes
+fern-sprech-aus-kunft
+fest-hef-ten
+fest-hef-tens
+fest-of-fer-te
+fest-stoff-ex-trak-ti-on
+fest-stoff-ex-trak-tio-nen
+fest-stoff-ra-ke-ten-trieb-werk
+fest-stoff-ra-ke-ten-trieb-wer-ke
+fest-stoff-ra-ke-ten-trieb-wer-ken
+fest-stoff-ra-ke-ten-trieb-werks
+fest-stoff-sta-bi-li-sa-tor
+fest-stoff-sta-bi-li-sa-to-ren
+fest-stoff-iso-la-ti-on
+fest-stoff-iso-la-tio-nen
+feuch-tig-keits-ge-halts-pro-fil
+feuch-tig-keits-ge-halts-pro-fi-le
+feuch-tig-keits-ge-halts-pro-fi-len
+feuch-tig-keits-ge-halts-pro-fils
+feu-er-ef-fekt
+feu-er-ef-fek-te
+feu-er-ef-fek-ten
+fiat
+fiats
+fi-ber-op-tik
+fi-ber-op-tik-ka-bel
+fi-ber-op-tik-ka-beln
+fich-ten-na-del-ex-trakt
+fich-ten-na-del-ex-trak-te
+fich-ten-na-del-ex-trak-tes
+fich-ten-na-del-ex-trakts
+fi-de-li-tas
+fi-dschi-aner
+fi-dschi-anisch
+fi-dschi-ani-sche
+fi-dschi-ani-schem
+fi-dschi-ani-schen
+fi-dschi-ani-scher
+fi-dschi-ani-sches
+fi-dschis
+fie-ber-klee
+fie-ber-klees
+fie-ber-rin-de
+fifa
+fi-let-steak
+fi-let-steaks
+fi-li-gran-ar-beit
+fi-li-gran-glas
+fi-li-gran-gla-ses
+film-adap-ti-on
+film-adap-tio-nen
+film-af-fe
+film-af-fen
+film-agent
+film-agen-ten
+film-agen-tur
+film-agen-tu-ren
+film-agi-ta-tor
+film-agi-ta-to-ren
+film-al-ma-nach
+film-al-ma-na-che
+film-al-ma-na-chen
+film-ama-teur
+film-an-druck-ku-fe
+film-an-druck-ku-fen
+film-an-druck-plat-te
+film-an-druck-plat-ten
+film-an-fang
+film-an-fan-ges
+film-an-fangs
+film-an-ga-be
+film-an-ga-ben
+film-an-stalt
+film-an-stal-ten
+film-an-stel-lung
+film-an-stel-lun-gen
+film-an-wen-dung
+film-an-wen-dun-gen
+film-ap-pa-rat
+film-ap-pa-ra-te
+film-ap-pa-ra-ten
+film-ar-ran-ge-ment
+film-ar-ran-ge-ments
+film-art
+film-ar-ten
+film-ar-ti-kel
+film-ar-ti-keln
+film-ar-ti-kels
+film-as-sis-tent
+film-as-sis-ten-ten
+film-as-sis-ten-tin
+film-as-sis-ten-tin-nen
+film-au-ge
+film-au-gen
+film-au-ges
+film-dar-bie-tung
+film-dar-bie-tun-gen
+film-ebe-ne
+film-ebe-nen
+film-echo
+film-echos
+film-ef-fekt
+film-ef-fek-te
+film-ef-fek-ten
+film-ehe-frau
+film-ehe-frau-en
+film-ehe-mann
+film-ehe-man-nes
+film-ein-fuhr-ver-bot
+film-ein-fuhr-ver-bo-te
+film-ein-fuhr-ver-bo-ten
+film-ein-fuhr-ver-bo-tes
+film-ein-fuhr-ver-bots
+film-ein-kaufs-or-ga-ni-sa-ti-on
+film-ein-kaufs-or-ga-ni-sa-tio-nen
+film-ein-le-gung
+film-ein-le-gun-gen
+film-ein-nah-me
+film-ein-nah-men
+film-ein-rich-tung
+film-ein-rich-tun-gen
+film-ein-satz
+film-ein-sat-zes
+film-ein-spie-lung
+film-ein-spie-lun-gen
+film-ein-trag
+film-ein-tra-ges
+film-ein-trags
+film-emul-si-on
+film-emul-sio-nen
+film-end-schal-ter
+film-end-schal-tern
+film-end-schal-ters
+film-en-ga-ge-ment
+film-en-ga-ge-ments
+film-ent-wurf
+film-ent-wur-fes
+film-ent-wurfs
+film-ent-zug
+film-er-eig-nis
+film-er-eig-nis-se
+film-er-eig-nis-sen
+film-er-eig-nis-ses
+film-er-fah-rung
+film-er-fah-run-gen
+film-er-folg
+film-er-fol-ge
+film-er-fol-gen
+film-er-folgs
+film-er-ken-nung
+film-er-ken-nun-gen
+film-er-leb-nis
+film-er-leb-nis-se
+film-er-leb-nis-sen
+film-er-leb-nis-ses
+film-exil
+film-idee
+film-ide-en
+film-iden-ti-fi-ka-ti-ons-num-mer
+film-iden-ti-fi-ka-ti-ons-num-mern
+film-iko-ne
+film-iko-nen
+film-il-lu-si-on
+film-il-lu-sio-nen
+film-in-for-ma-ti-on
+film-in-for-ma-tio-nen
+film-in-halt
+film-in-hal-te
+film-in-hal-te
+film-in-ten-dant
+film-in-ter-pre-ta-ti-on
+film-in-ter-pre-ta-tio-nen
+film-in-ter-view
+film-in-ter-views
+film-le-se-ein-heit
+film-le-se-ein-hei-ten
+film-of-fi-zier
+film-of-fi-zie-re
+film-of-fi-zie-ren
+film-of-fi-ziers
+film-op-fer
+film-op-fern
+film-op-fers
+film-or-gel
+film-ort
+film-or-ten
+film-out-put
+film-pa-ro-die
+film-pa-ro-di-en
+film-res-tau-ra-ti-on
+film-res-tau-ra-tio-nen
+film-res-tau-ra-tor
+film-res-tau-ra-to-rin
+film-res-tau-ra-tors
+film-res-tau-rie-rung
+film-res-tau-rie-run-gen
+film-scan-ner
+film-scan-nern
+film-scan-ners
+film-schau-spiel-er-le-ben
+film-schau-spiel-er-le-bens
+film-sin-fo-nie-or-ches-ter
+film-sin-fo-nie-or-ches-tern
+film-sin-fo-nie-or-ches-ters
+film-sketch
+film-sket-che
+film-sket-chen
+film-skript
+film-skrip-tes
+film-snob
+film-snobs
+film-trick
+film-tricks
+film-trick-tech-nik
+film-trick-tech-ni-ken
+film-um-lauf
+film-um-laufs
+film-um-set-zung
+film-um-set-zun-gen
+film-un-ter-hal-tung
+film-un-ter-hal-tun-gen
+film-un-ter-la-ge
+film-un-ter-la-gen
+film-un-ter-ma-lung
+film-un-ter-ma-lun-gen
+film-un-ter-neh-men
+film-un-ter-neh-mens
+fil-ter-ap-pa-rat
+fil-ter-ap-pa-ra-te
+fil-ter-ap-pa-ra-ten
+fil-ter-asche
+fil-ter-eck-fre-quenz
+fil-ter-eck-fre-quen-zen
+fil-ter-fa-brik
+fil-ter-fa-bri-ken
+fil-ter-fak-tor
+fil-ter-fak-to-ren
+fil-ter-fak-tors
+fil-ter-far-be
+fil-ter-far-ben
+fil-ter-fein
+fil-ter-fei-ne
+fil-ter-fei-nem
+fil-ter-fei-nen
+fil-ter-fei-ner
+fil-ter-fei-nes
+fil-ter-fein-heit
+fil-ter-fein-hei-ten
+fil-ter-fo-lie
+fil-ter-fo-li-en
+fil-ter-fo-li-en-hal-ter
+fil-ter-fo-li-en-hal-tern
+fil-ter-fo-li-en-hal-ters
+fil-ter-funk-ti-on
+fil-ter-funk-tio-nen
+fil-ter-kenn-li-nie
+fil-ter-kenn-li-ni-en
+fil-ter-vlies
+fil-ter-vlie-se
+fil-ter-vlie-sen
+fi-nanz-aris-to-kra-tie
+fi-nanz-aris-to-kra-ti-en
+fi-nanz-en-ga-ge-ment
+fi-nanz-en-ga-ge-ments
+fi-nanz-er-fah-rung
+fi-nanz-er-fah-run-gen
+fi-nanz-er-mitt-lungs-grup-pe
+fi-nanz-er-trag
+fi-nanz-er-tra-ges
+fi-nanz-etat
+fi-nanz-etats
+fi-nanz-idee
+fi-nanz-ide-en
+fi-nanz-ober-rat
+fi-nanz-ober-ra-tes
+fi-nanz-oli-gar-chie
+fi-nanz-oli-gar-chi-en
+fi-nanz-markt-ope-ra-ti-on
+fi-nanz-markt-ope-ra-tio-nen
+fi-nanz-op-ti-on
+fi-nanz-op-tio-nen
+fi-nanz-wech-sel
+fi-nanz-wech-seln
+fi-nanz-wech-sels
+fin-ger-ab-druck-scan-ner
+fin-ger-ab-druck-scan-nern
+fin-ger-ab-druck-scan-ners
+fin-ger-al-pha-bet
+fin-ger-al-pha-be-te
+fin-ger-al-pha-be-ten
+fin-ger-al-pha-be-tes
+fin-ger-al-pha-bets
+fin-ger-an-schlag
+fin-ger-an-schla-ges
+fin-ger-bild-er-ken-nung
+fin-ger-bild-er-ken-nun-gen
+fin-ger-end-ge-lenk
+fin-ger-end-ge-len-ke
+fin-ger-end-ge-len-ken
+fin-ger-end-ge-len-kes
+fin-ger-end-ge-lenks
+fin-ger-end-glied
+fin-ger-end-glie-der
+fin-ger-end-glie-dern
+fin-ger-end-glie-ders
+fin-ger-er-kran-kung
+fin-ger-er-kran-kun-gen
+fin-ger-er-satz
+fin-ger-er-sat-zes
+fin-ger-hut-her-stel-lung
+fin-ger-hut-her-stel-lun-gen
+fin-ger-ot-ter
+fin-ger-ot-tern
+fin-ger-ot-ters
+fin-ger-yo-ga
+fin-no-ugrisch
+fin-no-ugri-sche
+fin-no-ugri-schem
+fin-no-ugri-schen
+fin-no-ugri-scher
+fin-no-ugri-sches
+fin-no-ugrist
+fire-fox
+fir-men-al-ter
+fir-men-al-tern
+fir-men-al-ters
+fir-men-as-so-zia-ti-on
+fir-men-as-so-zia-tio-nen
+fir-men-edi-ti-on
+fir-men-en-ga-ge-ment
+fir-men-en-ga-ge-ments
+fir-men-er-pro-bung
+fir-men-er-pro-bun-gen
+fir-men-slo-gan
+fir-men-slo-gans
+fir-men-stem-pel
+fir-men-stem-peln
+fir-men-stem-pels
+fir-men-ti-cket
+fir-men-ti-ckets
+first-ha-ken
+first-ha-kens
+fisch-ab-bil-dung
+fisch-ab-bil-dun-gen
+fisch-as-sel
+fisch-as-seln
+fisch-auf-lauf
+fisch-auf-stieg
+fisch-auf-stie-ge
+fisch-auf-stie-gen
+fisch-auf-stiegs-an-la-ge
+fisch-auf-stiegs-an-la-gen
+fisch-auf-zucht
+fisch-auf-zuch-ten
+fisch-au-ge
+fisch-au-gen
+fisch-au-ges
+fisch-aus-schei-dungs-stoff
+fisch-aus-schei-dungs-stof-fe
+fisch-aus-schei-dungs-stof-fen
+fisch-aus-schei-dungs-stoffs
+fisch-au-gen-auf-nah-me
+fisch-au-gen-auf-nah-men
+fisch-au-gen-fo-to
+fisch-au-gen-fo-tos
+fisch-au-gen-lin-se
+fisch-au-gen-lin-sen
+fisch-au-gen-ob-jek-tiv
+fisch-au-gen-ob-jek-ti-ve
+fisch-au-gen-ob-jek-ti-ven
+fisch-au-gen-ob-jek-tivs
+fisch-au-gen-pro-jek-ti-on
+fisch-au-gen-pro-jek-tio-nen
+fisch-bein-stab
+fisch-bein-sta-bes
+fisch-brut
+fisch-bru-ten
+fisch-brut-an-la-ge
+fisch-brut-an-la-gen
+fisch-brut-an-stalt
+fisch-brut-an-stal-ten
+fisch-ech-se
+fi-sche-rei-fre-vel
+fi-sche-rei-fre-vels
+fi-sche-rei-ge-biet
+fi-sche-rei-ge-bie-te
+fi-sche-rei-ge-bie-ten
+fi-sche-rei-ge-bie-tes
+fi-sche-rei-ge-rech-tig-keit
+fi-sche-rei-gren-ze
+fi-sche-rei-gren-zen
+fi-sche-rei-kreu-zer
+fi-sche-rei-kreu-zern
+fi-sche-rei-kreu-zers
+fi-sche-rei-na-ti-on
+fi-sche-rei-schei-ne
+fi-sche-rei-schei-nen
+fi-sche-rei-strei-tig-keit
+fi-sche-rei-strei-tig-kei-ten
+fi-sche-rei-zweck
+fi-sche-rei-zwe-cke
+fi-sche-rei-zwe-cken
+fisch-eu-le
+fisch-eu-len
+fisch-imi-ta-ti-on
+fisch-imi-ta-tio-nen
+fisch-lift
+fisch-lu-pe
+fisch-maul-at-mung
+fisch-maul-at-mun-gen
+fisch-molch
+fisch-mol-che
+fisch-mol-chen
+fisch-mond-sa-men
+fisch-mond-sa-mens
+fisch-ora-kel
+fisch-ora-kels
+fisch-rat-te
+fisch-rat-ten
+fisch-res-tau-rant
+fisch-res-tau-rants
+fisch-ro-gen
+fisch-ro-gens
+fisch-scan-ner
+fisch-scan-nern
+fisch-scan-ners
+fisch-stern-bild
+fisch-stern-bil-des
+fisch-sud
+fisch-uhu
+fisch-uhus
+fisch-wil-de-rei
+fleisch-auf-lauf
+fjord-ar-tig
+fjord-ar-ti-ge
+fjord-ar-ti-gen
+flach-bett-scan-ner
+flach-bett-scan-nern
+flach-bett-scan-ners
+flag-gen-al-pha-bet
+flag-gen-al-pha-be-te
+flag-gen-al-pha-bets
+flak-leit-stand
+flansch-ab-zie-her
+flansch-ab-zie-hers
+flansch-la-ger
+flansch-la-gers
+fla-schen-eti-kett
+fla-schen-eti-ket-ten
+fla-schen-eti-ketts
+fleisch-ab-fall
+fleisch-ab-schnitt
+fleisch-ab-schnit-te
+fleisch-ab-schnit-ten
+fleisch-ab-schnitts
+fleisch-ab-tei-lung
+fleisch-ab-tei-lun-gen
+fleisch-am-pel
+fleisch-am-peln
+fleisch-an-satz
+fleisch-an-sat-zes
+fleisch-an-teil
+fleisch-an-tei-le
+fleisch-an-tei-len
+fleisch-an-teils
+fleisch-are-al
+fleisch-area-le
+fleisch-area-len
+fleisch-arm
+fleisch-ar-me
+fleisch-ar-mem
+fleisch-ar-men
+fleisch-ar-mer
+fleisch-ar-mes
+fleisch-auf-be-rei-tung
+fleisch-auf-be-rei-tun-gen
+fleisch-auf-schnitt
+fleisch-auf-schnit-te
+fleisch-er-satz
+fleisch-er-sat-zes
+fleisch-er-satz-er-zeug-nis
+fleisch-er-satz-er-zeug-nis-se
+fleisch-er-satz-er-zeug-nis-sen
+fleisch-er-satz-er-zeug-nis-ses
+fleisch-er-trag
+fleisch-er-tra-ges
+fleisch-er-zeug-nis
+fleisch-er-zeug-nis-se
+fleisch-er-zeug-nis-sen
+fleisch-er-zeug-nis-ses
+fleisch-er-zeu-gung
+fleisch-er-zeu-gun-gen
+fleisch-fon-dues
+fleisch-lie-fe-rant
+fleisch-lie-fe-ran-ten
+fleisch-lie-fe-ran-tin
+fleisch-lie-fe-ran-tin-nen
+fleisch-lie-fe-rung
+fleisch-lie-fe-run-gen
+fleisch-mi-schung
+fleisch-mi-schun-gen
+fleisch-mo-le
+fleisch-mo-len
+fleisch-ras-se
+fleisch-ras-sen
+fleisch-ra-ti-on
+fleisch-ra-tio-nen
+fleisch-rei-fung
+fleisch-rei-fun-gen
+fleisch-rest
+fleisch-res-te
+fleisch-res-ten
+fleisch-rip-pe
+fleisch-rip-pen
+fleisch-stier
+fleisch-stie-re
+fleisch-stie-ren
+fleisch-tas-se
+fleisch-tas-sen
+fleisch-to-ma-te
+fleisch-to-ma-ten
+fleisch-trau-be
+fleisch-trau-ben
+fleisch-wan-gen
+fleisch-war-ze
+fleisch-war-zen
+fleisch-wurst-ring
+fleisch-wurst-rin-ge
+fleisch-wurst-rings
+flie-der-blau
+flie-der-blaue
+flie-der-blau-em
+flie-der-blau-en
+flie-der-blau-er
+flie-der-blau-es
+flie-gen-au-ge
+flie-gen-au-gen
+flie-gen-au-ges
+flie-gen-draht
+flie-gen-drah-tes
+flie-gen-sal-to
+flie-gen-sal-tos
+flie-ger-ass
+flie-ger-as-se
+flie-ger-as-sen
+flie-ger-epen
+flie-ger-epos
+flie-ger-er-satz-ab-tei-lung
+flie-ger-er-satz-ab-tei-lun-gen
+flie-ger-in-ge-nieur
+flie-ger-in-ge-nieu-re
+flie-ger-in-ge-nieu-ren
+flie-ger-in-ge-nieu-rin
+flie-ger-in-ge-nieurs
+flie-ger-in-ge-nieur-aka-de-mie
+flie-ger-in-ge-nieur-aka-de-mi-en
+flie-ger-in-ge-nieur-dienst
+flie-ger-in-ge-nieur-diens-te
+flie-ger-in-ge-nieur-diens-ten
+flie-ger-in-ge-nieur-diens-tes
+flie-ger-kraft-sprit-ze
+flie-ger-kraft-sprit-zen
+flie-ger-uhr
+flie-ger-uh-ren
+flie-ger-war-nung
+flie-ger-war-nun-gen
+flim-mer-au-ra
+flip-per-au-to-mat
+flip-per-au-to-ma-ten
+flit-ter-gold
+flit-ter-gol-des
+flit-ter-tand
+flot-ten-er-neue-rung
+flot-ten-er-neue-run-gen
+flucht-er-fah-rung
+flucht-er-fah-run-gen
+flucht-or-te
+flucht-or-ten
+flucht-rich-tung
+flucht-rich-tun-gen
+flucht-stab
+flucht-sta-bes
+flug-aben-teu-er
+flug-aben-teu-ern
+flug-aben-teu-ers
+flub-ab-rech-nung
+flub-ab-rech-nun-gen
+flug-ab-wehr-bri-ga-de
+flug-ab-wehr-bri-ga-den
+flug-ab-wehr-in-sti-tut
+flug-ab-wehr-in-sti-tu-te
+flug-ab-wehr-in-sti-tu-ten
+flug-ab-wehr-in-sti-tuts
+flug-akro-bat
+flug-akro-ba-ten
+flug-akro-ba-tik
+flug-aus-fall-stem-pel
+flug-aus-fall-stem-peln
+flug-aus-fall-stem-pels
+flug-bahn-ele-men-te
+flug-bahn-ele-men-ten
+flug-blatt-agi-ta-ti-on
+flug-blatt-agi-ta-tio-nen
+flug-bri-ga-de
+flug-bri-ga-den
+flug-dra-che
+flug-dra-chen
+flug-deck-ecke
+flug-deck-ecken
+flug-ech-se
+flug-ech-sen
+flug-ele-ment
+flug-ele-men-te
+flug-ener-gie
+flug-ener-gi-en
+flug-en-te
+flug-en-ten
+flug-en-ten-art
+flug-en-ten-ar-ten
+flug-ent-fer-nung
+flug-ent-fer-nun-gen
+flug-es-ka-pa-de
+flug-es-ka-pa-den
+flug-funk-na-vi-ga-ti-on
+flug-funk-na-vi-ga-ti-ons-ver-fah-ren
+flug-funk-na-vi-ga-ti-ons-ver-fah-rens
+flug-gast-an-nah-me
+flug-gast-an-nah-men
+flug-ha-fen-are-ale
+flug-ha-fen-are-alen
+flug-ha-fen-res-tau-rant
+flug-ha-fen-res-tau-rants
+flug-hahn
+flug-iden-ti-fi-ka-ti-on
+flug-in-for-ma-ti-on
+flug-in-for-ma-tio-nen
+flug-in-for-ma-tions-dienst
+flug-in-for-ma-tions-diens-te
+flug-in-for-ma-tions-diens-ten
+flug-in-for-ma-tions-diens-tes
+flug-in-for-ma-tions-re-gi-on
+flug-in-for-ma-tions-re-gio-nen
+flug-in-for-ma-tions-sys-tem
+flug-in-for-ma-tions-sys-te-me
+flug-in-for-ma-tions-sys-te-men
+flug-in-for-ma-tions-sys-tems
+flug-in-ge-nieur
+flug-in-ge-nieu-re
+flug-in-ge-nieu-ren
+flug-in-ge-nieu-rin
+flug-in-ge-nieurs
+flug-lo-ko-mo-ti-ve
+flug-lo-ko-mo-ti-ven
+flug-plan-dar-stel-lung
+flug-of-fi-zier
+flug-of-fi-zie-re
+flug-of-fi-zie-ren
+flug-of-fi-ziers
+flug-ope-ra-ti-on
+flug-ope-ra-tio-nen
+flug-ope-ra-t-ions-sys-tem
+flug-ope-ra-t-ions-sys-te-me
+flug-ope-ra-t-ions-sys-te-men
+flug-ope-ra-t-ions-sys-tems
+flug-or-den
+flug-or-dens
+flug-rost
+flug-ruf
+flug-ru-fe
+flug-sal-be
+flug-sal-ben
+flug-san-da-le
+flug-san-da-len
+flug-san-de
+flug-san-den
+flug-sand-schicht
+flug-sand-schich-ten
+flug-sand-um-la-ge-rung
+flug-sand-um-la-ge-run-gen
+flug-sand-wehr
+flug-sand-weh-re
+flug-sand-weh-ren
+flug-seg-ment
+flug-seg-men-te
+flug-seg-men-ten
+flug-se-kun-de
+flug-se-kun-den
+flug-ser-vice
+flug-ser-vices
+flug-sil-hou-et-te
+flug-sil-hou-et-ten
+flug-spar-ren
+flug-spar-rens
+flug-sprung
+flug-sprun-ges
+flug-spur
+flug-spu-ren
+flug-sta-bes
+flug-sta-bi-li-sa-tor
+flug-sta-bi-li-sa-to-ren
+flug-sta-bi-li-sie-rend
+flug-sta-bi-li-sie-ren-de
+flug-sta-bi-li-sie-ren-dem
+flug-sta-bi-li-sie-ren-den
+flug-sta-bi-li-sie-rer
+flug-sta-bi-li-sie-ren-des
+flug-sta-bi-li-sie-rung
+flug-sta-bi-li-sie-run-gen
+flug-staub
+flug-stau-bes
+flug-staub-kam-mer
+flug-staub-kam-mern
+flug-staub-re-ak-tor
+flug-staub-re-ak-to-ren
+flug-staub-re-ak-tors
+flug-stil
+flug-sti-le
+flug-sti-len
+flug-sti-les
+flug-stils
+flug-strei-fen
+flug-strei-fens
+flug-stro-mes
+flug-strom-ver-ga-sung
+flug-strom-ver-ga-sun-gen
+flug-test-in-ge-nieur
+flug-test-in-ge-nieu-re
+flug-test-in-ge-nieu-ren
+flug-test-in-ge-nieu-rin
+flug-test-in-ge-nieurs
+flug-trick
+flug-tricks
+flug-uni-on
+flug-unio-nen
+flug-zeug-an-griff
+flug-zeug-an-grif-fe
+flug-zeug-an-grif-fen
+flug-zeug-an-griffs
+flug-zeu-gen-typ
+flug-zeu-gen-ty-pen
+flug-zeu-gen-typs
+flug-zeug-in-ge-nieur
+flug-zeug-in-ge-nieu-re
+flug-zeug-in-ge-nieu-ren
+flug-zeug-in-ge-nieu-rin
+flug-zeug-in-ge-nieurs
+flug-zeug-in-ne-re
+flug-zeug-in-ne-ren
+flug-zeug-rei-fen
+flug-zeug-rei-fens
+fluk-tu-a-ti-on
+fluk-tu-a-tio-nen
+fluk-tu-a-ti-ons-be-dingt
+fluk-tu-a-ti-ons-be-ding-te
+fluk-tu-a-ti-ons-be-ding-tem
+fluk-tu-a-ti-ons-be-ding-ten
+fluk-tu-a-ti-ons-be-ding-ter
+fluk-tu-a-ti-ons-be-ding-tes
+flu-or-cal-ci-um
+fluo-rid-be-hand-lung
+fluo-rid-be-hand-lun-gen
+fluo-rid-hal-tig
+fluo-rid-hal-ti-ge
+fluo-rid-hal-ti-gem
+fluo-rid-hal-ti-gen
+fluo-rid-hal-ti-ger
+fluo-rid-hal-ti-ges
+flu-or-kal-zi-um
+flu-or-koh-len-was-ser-stoff
+flu-or-koh-len-was-ser-stof-fe
+flu-or-koh-len-was-ser-stof-fen
+flu-or-koh-len-was-ser-stoffs
+flu-or-pro-phy-la-xe
+flu-or-test
+flu-or-ver-gif-tung
+flu-or-was-ser-stoff
+flu-or-was-ser-stof-fe
+flu-or-was-ser-stof-fen
+flu-or-was-ser-stoffs
+flur-ord-nung
+flur-um-gang
+flur-um-gan-ges
+flur-zwang
+fluss-ein-schnitt
+fluss-ein-schnit-te
+fluss-ein-schnit-ten
+fluss-ein-zugs-ge-biet
+fluss-ein-zugs-ge-bie-te
+fluss-ein-zugs-ge-bie-ten
+fluss-ein-zugs-ge-bie-tes
+fluss-ein-zugs-sys-tem
+fluss-ein-zugs-sys-te-me
+fluss-ein-zugs-sys-te-men
+fluss-ein-zugs-sys-tems
+fluss-en-de
+fluss-en-den
+fluss-en-des
+fluss-er-hal-tung
+fluss-er-hal-tun-gen
+fluss-ero-si-on
+fluss-ero-sio-nen
+fluss-er-wei-te-rung
+fluss-er-wei-te-run-gen
+fluss-im-pe-danz
+fluss-im-pe-dan-zen
+fluss-mit-tel-ein-tei-lung
+fluss-mit-tel-ein-tei-lun-gen
+fluss-neun-au-ge
+fluss-neun-au-gen
+fluss-neun-au-ges
+fluss-ot-ter
+fluss-ot-tern
+fluss-ot-ters
+fluss-pe-gel
+fluss-pe-geln
+fluss-pio-nie-re
+fluss-pio-nie-ren
+fluss-por-tal
+fluss-por-ta-le
+fluss-por-ta-len
+fluss-um-ge-bung
+fluss-um-ge-bun-gen
+fluss-um-kehr
+fluss-was-ser-am-sel
+fluss-was-ser-am-seln
+flut-aue
+flut-au-en
+flut-ein-satz
+flut-hy-po-the-se
+flut-hy-po-the-sen
+form-pflicht
+form-pflich-ten
+form-pflich-tig
+for-ti-fi-ka-ti-on
+for-ti-fi-ka-tio-nen
+for-ti-fi-ka-to-risch
+for-ti-fi-ka-to-ri-sche
+for-ti-fi-ka-to-ri-schem
+for-ti-fi-ka-to-ri-schen
+for-ti-fi-ka-to-ri-scher
+for-ti-fi-ka-to-ri-sches
+for-ti-fi-zie-ren
+frach-ter-flot-te
+frach-ter-flot-ten
+freund-schafts-te-le-fon
+freund-schafts-te-le-fo-ne
+freund-schafts-te-le-fo-nen
+freund-schafts-te-le-fons
+freund-schafts-tem-pel
+freund-schafts-tem-peln
+freund-schafts-tem-pels
+freund-schafts-turm
+freund-schafts-trunk
+freund-schafts-trun-kes
+frisch-fleisch-ab-tei-lung
+frisch-fleisch-ab-tei-lun-gen
+front-an-griff
+front-an-grif-fe
+front-an-grif-fen
+front-an-griffs
+front-flug-span-ge
+front-flug-span-gen
+front-of-fi-zier
+front-of-fi-zie-re
+front-of-fi-ziers
+frucht-ei-gen-schaft
+frucht-ei-gen-schaf-ten
+frucht-fleisch-rest
+frucht-fleisch-res-te
+frucht-fleisch-res-ten
+gas-puf-fer
+gas-puf-fern
+gas-puf-fers
+gas-wech-sel-ef-fi-zienz
+ge-frier-fleisch-or-den
+ge-frier-fleisch-or-dens
+ge-gen-stands-ei-gen-schaft
+ge-gen-stands-ei-gen-schaf-ten
+ge-gen-strom-ef-fekt
+ge-gen-strom-ef-fek-te
+ge-mein-de-iden-ti-fi-ka-ti-on
+ge-mein-schaft-ate-lier
+ge-mein-schafts-chor
+ge-mein-schafts-cho-res
+ge-mein-schafts-chors
+ge-mein-schafts-com-pu-ter-sys-tem
+ge-mein-schafts-com-pu-ter-sys-te-me
+ge-mein-schafts-com-pu-ter-sys-te-men
+ge-mein-schafts-com-pu-ter-sys-tems
+ge-mein-schafts-pseu-do-nym
+ge-mein-schafts-pseu-do-ny-me
+ge-mein-schafts-pseu-do-ny-men
+ge-mein-schafts-ta-fel
+ge-mein-schafts-toi-let-te
+ge-mein-schafts-toi-let-ten
+ge-mein-schafts-wasch-raum
+ge-mein-schafts-wasch-rau-mes
+ge-mein-schafts-wasch-raums
+ge-nos-sen-schafts-res-tau-rant
+ge-nos-sen-schafts-res-tau-rants
+geoff-rey
+geo-gra-fie-in-sti-tut
+geo-gra-fie-in-sti-tu-te
+geo-gra-fie-in-sti-tu-ten
+geo-gra-fie-in-sti-tuts
+ge-richts-hof-feind-lich
+ge-richts-hof-feind-li-chen
+ge-ruchs-iden-ti-fi-ka-ti-on
+ge-samt-ef-fekt
+ge-samt-ef-fek-te
+ge-samt-ef-fek-ten
+ge-samt-fluk-tu-a-ti-on
+ge-samt-fluk-tu-a-tio-nen
+ge-samt-schirm-herr-schaft
+ge-samt-schirm-herr-schaf-ten
+ge-schmacks-pro-fil
+ge-schmacks-pro-fi-le
+ge-schmacks-pro-fi-len
+ge-schmacks-pro-fils
+ge-sell-schafts-chro-nik
+ge-sell-schafts-chro-ni-ken
+ge-sell-schafts-me-ta-phy-sik
+ge-sell-schafts-me-ta-phy-si-ken
+ge-sell-schafts-rein-ge-winn
+ge-sell-schafts-rein-ge-win-ne
+ge-sell-schafts-rein-ge-win-nen
+ge-sell-schafts-tra-gend
+ge-sell-schafts-tra-gen-de
+ge-sell-schafts-tra-gen-dem
+ge-sell-schafts-tra-gen-den
+ge-sell-schafts-tra-gen-der
+ge-sell-schafts-tra-gen-des
+ge-sell-schafts-typ
+ge-sell-schafts-ty-pen
+ge-sell-schafts-uto-pie
+ge-sell-schafts-uto-pi-en
+ge-sell-schafts-uto-pist
+ge-set-zes-of-fen-ba-rung
+ge-set-zes-of-fen-ba-run-gen
+ge-trei-de-puff-er-zeug-nis
+ge-trei-de-puff-er-zeug-nis-se
+ge-trei-de-puff-er-zeug-nis-sen
+ge-trei-de-puff-er-zeug-nis-ses
+ge-winn-er-mitt-lungs-vor-schrift
+ge-winn-er-mitt-lungs-vor-schrif-ten
+gift-am-pul-le
+gift-am-pul-len
+gift-ap-pa-rat
+gift-ap-pa-ra-te
+gift-ap-pa-ra-ten
+gift-at-ten-tat
+gift-at-ten-ta-te
+gift-at-ten-ta-ten
+gift-at-ten-ta-tes
+gift-efeu
+gift-efeus
+gift-ei-che
+gift-ei-chen
+gift-gas-at-ten-tat
+gift-gas-at-ten-ta-te
+gift-gas-at-ten-ta-ten
+gift-gas-at-ten-tats
+gift-gas-ein-satz
+gift-gas-ein-sat-zes
+gift-gas-ent-wick-lung
+gift-gas-ent-wick-lun-gen
+gift-gas-er-kran-kung
+gift-gas-er-kran-kun-gen
+gift-in-for-ma-ti-on
+gift-in-for-ma-tio-nen
+gift-in-for-ma-ti-ons-dienst
+gift-in-for-ma-ti-ons-diens-te
+gift-in-for-ma-ti-ons-diens-ten
+gift-in-for-ma-ti-ons-diens-tes
+gift-in-for-ma-ti-ons-zen-tra-le
+gift-in-for-ma-ti-ons-zen-tra-len
+gift-raum
+gift-rau-mes
+gift-rest
+gift-res-te
+gift-res-ten
+gift-se-kret
+gift-se-kre-te
+gift-se-kre-ten
+gift-selbst-mord
+gift-selbst-mor-de
+gift-selbst-mor-den
+gift-selbst-mor-des
+gift-stoff-ein-fluss
+gift-stoff-ein-flus-ses
+gift-wa-re
+gift-wa-ren
+glas-ei-gen-schaft
+glas-ei-gen-schaf-ten
+glas-iso-lier-stoff
+glas-iso-lier-stof-fe
+glas-iso-lier-stof-fen
+glas-iso-lier-stoffs
+glas-tuff
+glas-tuf-fe
+glas-tuf-fen
+gleich-emp-fin-dend
+gleich-emp-fin-den-de
+gleich-emp-fin-den-dem
+gleich-emp-fin-den-den
+gleich-emp-fin-den-der
+gleich-emp-fin-den-des
+gleich-emp-fin-dung
+gleich-emp-fin-dun-gen
+glo-bal-in-suf-fi-zi-enz
+glo-bal-in-suf-fi-zi-en-zen
+gnu-fla-den
+gold-af-fe
+gold-af-fen
+gold-blech-auf-la-ge
+gold-blech-auf-la-gen
+gold-fin-ger-sex-tett
+gold-fin-ger-sex-tet-te
+gold-fin-ger-sex-tet-ten
+golf-la-sche
+golf-la-schen
+golf-latz
+golf-le-gen-de
+golf-le-gen-den
+golf-lauf-bahn
+golf-lauf-bah-nen
+golf-lek-tion
+golf-lek-tio-nen
+golf-len-ker
+golf-len-ke-rin
+golf-lieb-ha-ber
+golf-lieb-ha-be-rin
+golf-lieb-ha-bern
+golf-luft
+golf-traum
+got-tes-of-fen-ba-rung
+got-tes-of-fen-ba-run-gen
+grab-auf-schrift
+grab-auf-schrif-ten
+gra-fik-ab-zug
+gra-fik-ab-zu-ges
+gra-fik-an-for-de-rung
+gra-fik-an-for-de-run-gen
+gra-fik-ani-ma-ti-on
+gra-fik-ani-ma-tio-nen
+gra-fik-an-schluss
+gra-fik-an-schlus-ses
+gra-fik-an-sicht
+gra-fik-an-sich-ten
+gra-fik-an-steue-rung
+gra-fik-an-steue-run-gen
+gra-fik-as-sis-tent
+gra-fik-as-sis-ten-ten
+gra-fik-as-sis-ten-tin
+gra-fik-as-sis-ten-tin-nen
+gra-fik-ate-lier
+gra-fik-ate-liers
+gra-fik-de-sign-buch
+gra-fik-de-sign-bu-ches
+gra-fik-de-sign-buchs
+gra-fik-ef-fekt
+gra-fik-ef-fek-te
+gra-fik-ef-fek-ten
+gra-fik-ele-ment
+gra-fik-ele-men-te
+gra-fik-ele-men-ten
+gra-fik-ele-men-tes
+gra-fik-er-stel-ler
+gra-fik-er-stel-lern
+gra-fik-er-stel-lers
+gra-fik-er-stel-lung
+gra-fik-er-stel-lun-gen
+gra-fik-leis-tung
+gra-fik-leis-tun-gen
+gra-fik-ni-veau
+gra-fik-ni-veaus
+gra-fik-ope-ra-ti-on
+gra-fik-ope-ra-tio-nen
+gra-fik-op-ti-on
+gra-fik-op-tio-nen
+gra-fik-ori-en-tiert
+gra-fik-ori-en-tier-te
+gra-fik-ori-en-tier-tem
+gra-fik-ori-en-tier-ten
+gra-fik-ori-en-tier-ter
+gra-fik-ori-en-tier-tes
+gra-fik-ori-en-tie-rung
+gra-fik-ori-en-tie-run-gen
+gra-fik-um-ge-bung
+gra-fik-um-ge-bun-gen
+gra-nat-schleif-lei-nen
+grape-fruit-saft
+grau-fle-cken-test
+grau-flei-schig
+grau-flei-schi-ge
+grau-flei-schi-gen
+greif-re-flex
+greif-re-fle-xe
+greif-re-fle-xen
+greif-re-fle-xes
+griff-ele-men-te
+griff-ele-men-ten
+griff-la-sche
+griff-la-schen
+griff-leis-te
+griff-leis-ten
+griff-loch
+griff-lo-ches
+griff-lochs
+griff-loch-zie-gel
+griff-loch-zie-geln
+griff-loch-zie-gels
+gro-tesk-schrift
+grund-er-fin-dung
+grund-er-fin-dun-gen
+gruft-as-sel
+gruft-as-seln
+gru-sel-ef-fekt
+gru-sel-ef-fek-te
+gru-sel-ef-fek-ten
+gum-mi-fluss
+gum-mi-flus-ses
+gum-mi-pflan-zen
+gum-mi-pfle-ge-mit-tel
+gum-mi-pfle-ge-mit-teln
+gum-mi-pfle-ge-mit-tels
+gum-mi-schaft
+gum-mi-schaf-tes
+gum-mi-schleif-tel-ler
+gum-mi-schleif-tel-lern
+gum-mi-schleif-tel-lers
+gurt-flat-tern
+hack-fleisch-an-teil
+hack-fleisch-an-tei-le
+hack-fleisch-an-tei-len
+hack-fleisch-an-teils
+hack-fleisch-auf-lauf
+haft-an-ord-nung
+haft-an-ord-nun-gen
+haft-ecke
+haft-ecken
+haft-elek-tro-de
+haft-elek-tro-den
+haft-er-satz
+haft-er-sat-zes
+haft-in-sas-se
+haft-in-sas-sen
+haft-pflicht-recht
+haft-pflicht-rech-te
+haft-pflicht-rech-ten
+haft-sal-be
+haft-sal-ben
+haft-schei-be
+haft-schei-ben
+haft-soh-le
+haft-soh-len
+halb-fi-na-le-teil-neh-mer
+halb-fi-na-le-teil-neh-me-rin
+halb-fi-na-le-teil-neh-me-rin-nen
+halb-fi-na-le-teil-neh-mern
+halb-fi-na-le-teil-neh-mers
+halb-schef-fel
+halb-schef-fels
+halb-stoff
+halb-stof-fe
+halb-stof-fen
+halb-stoffs
+hal-len-eu-ro-pa-meis-ter-schaft
+hal-len-eu-ro-pa-meis-ter-schaf-ten
+han-dels-schiff-raum
+han-dels-schiff-rau-mes
+hanf-la-by-rinth
+hanf-la-den
+hanf-la-den-be-sit-zer
+hanf-la-den-be-trei-ber
+hanf-land
+hanf-lang
+hanf-le-bens-mit-tel
+hanf-le-bens-mit-teln
+hanf-le-ga-li-sie-rung
+hanf-lehm
+hanf-lei-ne
+hanf-lei-nen
+hanf-lieb-ha-ber
+hanf-lied
+hanf-li-te-ra-tur
+hanf-lob-by
+hanf-lob-by-is-ten
+hanf-lounge
+hang-ab-triebs-kraft
+harn-stoff-spal-tung
+harn-stoff-spal-tun-gen
+haupt-bahn-hof-funk-ti-on
+haupt-bahn-hof-funk-tio-nen
+haupt-ef-fekt
+haupt-ef-fek-te
+haupt-ef-fek-ten
+haupt-ef-fekts
+haupt-fluss-ader
+haupt-fluss-adern
+haupt-iden-ti-fi-ka-ti-ons-merk-mal
+haupt-iden-ti-fi-ka-ti-ons-merk-ma-le
+haupt-iden-ti-fi-ka-ti-ons-merk-ma-len
+haupt-iden-ti-fi-ka-ti-ons-merk-mals
+haus-wirt-schafts-cen-ter
+haus-wirt-schafts-cen-ters
+haut-re-flex
+haut-re-fle-xe
+haut-re-fle-xen
+haute-fi-nance
+haut-emp-fin-dung
+haut-emp-fin-dun-gen
+heft-in-halt
+heft-in-hal-te
+heft-in-hal-ten
+heft-in-halts
+heil-ef-fekt
+heil-ef-fek-te
+heil-ef-fek-ten
+heil-er-zie-hungs-pfle-ge
+heil-er-zie-hungs-pfle-gen
+heil-er-zie-hungs-pfle-ge-hil-fe
+heil-er-zie-hungs-pfle-ge-hil-fen
+herr-schafts-cha-rak-ter
+herr-schafts-cha-rak-ters
+herr-schafts-tra-gend
+herr-schafts-tra-gen-de
+herr-schafts-tra-gen-dem
+herr-schafts-tra-gen-den
+herr-schafts-tra-gen-der
+herr-schafts-tra-gen-des
+herz-aus-wurf-leis-tung
+her-zens-hof-fahrt
+her-zens-emp-fin-dung
+her-zens-emp-fin-dun-gen
+herz-fleisch-ent-ar-tung
+herz-fleisch-ent-ar-tun-gen
+herz-mus-kel-in-suf-fi-zi-enz
+herz-mus-kel-in-suf-fi-zi-en-zen
+heul-af-fe
+heul-af-fen
+hil-fe-file
+hilf-fonds
+hip-pie-flair
+hin-du-schrift
+hin-du-schrif-ten
+hin-ter-flan-ke
+hin-ter-flan-ken
+hin-ter-hof-fa-brik
+hoch-fre-quenz-ei-gen-schaft
+hoch-fre-quenz-ei-gen-schaf-ten
+hoch-strom-ef-fekt
+hoch-strom-ef-fek-te
+hoch-strom-ef-fek-ten
+hof-fahrt
+hof-fahrts-pflicht
+hof-fahrts-tag
+hof-fahrt-sucht
+hof-fak-tor
+hof-fak-to-ren
+hof-fak-tors
+hof-fak-to-rin
+hof-fa-mi-lie
+hof-fan
+hof-fans
+hof-fas-sa-de
+hof-fas-sa-den
+hof-fi-nanz
+hof-fi-nan-zen
+hof-fi-nan-zier
+hof-fi-nan-ziers
+hof-fi-nanz-mann
+hof-fisch-ross
+hof-fol-ge-zeug-nis
+hof-fol-ge-zeug-nis-se
+hof-fol-ge-zeug-nis-sen
+hof-fol-ge-zeug-nis-ses
+hof-fo-to-graf
+hof-fo-to-gra-fen
+hof-frau
+hof-frau-en
+hof-frei
+hof-freie
+hof-frei-en
+hof-fremd
+hof-frem-de
+hof-frem-dem
+hof-frem-den
+hof-frem-der
+hof-fri-seur
+hof-front
+hof-fron-ten
+hof-in-ge-nieur
+hof-in-ge-nieu-re
+hof-in-ge-nieu-ren
+hof-in-ge-nieu-rin
+hof-in-ge-nieurs
+hof-in-stru-ment
+hof-in-stru-men-te
+hof-in-stru-men-ten
+hof-tanz
+hof-tan-zes
+hof-teich
+hof-tei-che
+hof-tei-chen
+holz-bot-tref-fen
+holz-boot-tref-fens
+holz-pflock
+holz-pflo-ckes
+hor-mon-stoff-wech-sel
+hor-mon-stoff-wech-seln
+hor-mon-stoff-wech-sels
+horn-haut-re-flex
+huf-far-be
+huf-far-ben
+huf-trag-rand
+huf-trag-ran-des
+im-mun-in-suf-fi-zi-enz
+impf-la-bo-ra-to-ri-um
+impf-lan-zet-te
+impf-le-gen-de
+impf-lan-zet-ten
+impf-lun-ge
+impf-lun-gen
+im-pres-sum-pflicht
+im-pres-sum-pflich-tig
+in-dif-fe-renz-elek-tro-de
+in-di-go-pflan-ze
+in-di-go-pflan-zen
+in-dus-trie-flair
+in-dus-trie-flot-te
+in-dus-trie-flot-ten
+in-dus-trie-in-ge-nieurs-wis-sen-schaft
+in-dus-trie-in-ge-nieurs-wis-sen-schaf-ten
+in-dus-trie-roh-stoff
+in-dus-trie-roh-stof-fe
+in-dus-trie-roh-stof-fen
+in-dus-trie-roh-stoffs
+in-fan-te-rie-flie-ger
+in-fan-te-rie-flie-gern
+in-fan-te-rie-flie-gers
+in-fra-rot-re-fle-xi-on
+in-fra-rot-re-fle-xio-nen
+in-ge-nieur-of-fi-zier
+in-ge-nieur-of-fi-zie-re
+in-ge-nieur-of-fi-zie-ren
+in-ge-nieur-of-fi-ziers
+in-ge-nieurs-of-fi-zier
+in-ge-nieurs-of-fi-zie-re
+in-ge-nieurs-of-fi-zie-ren
+in-ge-nieurs-of-fi-ziers
+in-nen-hof-fas-sa-de
+in-nen-hof-fas-sa-den
+in-nen-hof-fries
+in-nen-stern-an-griff
+in-nen-stern-an-grif-fe
+in-nen-stern-an-grif-fen
+in-nen-stern-an-griffs
+in-schrif-ten-ta-fel
+in-schrif-ten-ta-feln
+in-tel-li-genz-ei-gen-schaft
+in-tel-li-genz-ei-gen-schaf-ten
+in-ter-net-treff-punkt
+in-ter-net-treff-punk-te
+in-ter-net-treff-punk-ten
+in-ter-net-treff-punk-tes
+in-tim-pfle-ge
+jagd-flie-ger-waf-fe
+jagd-flie-ger-waf-fen
+ja-mai-ka-pfef-fer
+ja-mai-ka-pfef-fers
+ja-nu-ar-tref-fen
+ja-nu-ar-tref-fens
+jeff-rey
+ju-gend-dorf-lei-ter
+ju-gend-dorf-lei-tern
+ju-gend-dorf-lei-ters
+ju-gend-fest-spiel-tref-fen
+ju-gend-fest-spiel-tref-fens
+ju-gend-wohn-ge-mein-schaft
+ju-gend-wohn-ge-mein-schaf-ten
+jung-och-sen-fleisch
+jung-och-sen-fleischs
+kaf-fee-haus-ster-ben
+kaf-fee-haus-ster-bens
+kaf-fee-in-sel
+kaf-fee-in-seln
+kaf-fee-oli-gar-chie
+kaf-fee-oli-gar-chi-en
+kaf-fee-oli-gar-chin
+kaf-fee-satz-er-bre-chen
+kaf-fee-satz-er-bre-chens
+ka-kao-pflan-ze
+ka-kao-pflan-zen
+ka-len-der-zeit-ef-fekt
+ka-len-der-zeit-ef-fek-te
+ka-len-der-zeit-ef-fek-ten
+kalk-tuff
+ka-min-ef-fekt
+ka-min-ef-fek-te
+ka-min-ef-fek-ten
+ka-min-ef-fek-tes
+ka-min-ef-fekts
+kampf-ideo-lo-gie
+kampf-ideo-lo-gi-en
+kampf-lan-ze
+kampf-lan-zen
+kampf-stoff-art
+kampf-stoff-ar-ten
+kampf-tan-zes
+ka-pu-zi-ner-af-fe
+ka-pu-zi-ner-af-fen
+ka-ros-se-rie-stei-fig-keit
+kar-tell-ent-flech-tung
+kar-tell-ent-flech-tun-gen
+kar-tof-fel-au-gen-scho-ner
+kar-tof-fel-au-gen-scho-nern
+kar-tof-fel-au-gen-scho-ners
+kar-tof-fel-bo-fist
+kar-tof-fel-frucht
+kar-tof-fel-frucht-was-ser
+kar-tof-fel-frucht-was-sern
+kar-tof-fel-frucht-was-sers
+kasch-mir-kon-flikt
+kasch-mir-kon-flik-tes
+kauf-im-puls
+kauf-im-pul-se
+kauf-im-pul-sen
+kauf-in-dex
+kauf-in-de-xe
+kauf-in-de-xes
+kauf-in-di-ces
+kauf-in-di-zes
+kauf-in-ger
+kauf-kraft-ef-fekt
+kauf-kraft-ef-fek-te
+kauf-kraft-in-for-ma-ti-on
+kauf-kraft-in-for-ma-tio-nen
+kauf-kraft-stan-dard
+kauf-kraft-stan-dards
+kauf-soft-ware
+kehl-kopf-lip-pen
+keil-schrift-ur-kun-de
+keil-schrift-ur-kun-den
+keim-pflan-ze
+keim-pflan-zen
+kel-le-rei-ge-hil-fin
+kenn-zif-fer-an-schrift
+kenn-zif-fer-er-wer-bung
+kern-ei-gen-schaft
+kern-ei-gen-schaf-ten
+kern-ener-gie-roh-stoff
+kern-ener-gie-roh-stof-fe
+kern-ener-gie-roh-stof-fen
+kern-ener-gie-roh-stoffs
+kern-kraft-in-sti-tu-ti-on
+kern-kraft-in-sti-tu-tio-nen
+kern-kraft-werks-typ
+kern-kraft-werks-ty-pen
+kern-kraft-werks-typs
+kern-waf-fen-test-ope-ra-ti-on
+kern-waf-fen-test-ope-ra-tio-nen
+kin-der-asyl-stif-tung
+kin-der-asyl-stif-tun-gen
+ki-no-flair
+ki-no-flairs
+kirch-weih-auf-takt
+kirch-weih-auf-tak-te
+kirch-weih-auf-tak-ten
+kirch-weih-auf-tak-tes
+kirch-weih-auf-takts
+kirsch-auf-lauf
+kirsch-auf-lau-fes
+klaf-ter-lang
+klaf-ter-lan-ge
+klaf-ter-lan-gem
+klaf-ter-lan-gen
+klaf-ter-lan-ger
+klaf-ter-lan-ges
+klam-mer-af-fe
+klam-mer-af-fen
+klang-ef-fekt
+klang-ef-fek-te
+klang-ef-fek-ten
+klapp-mes-ser-griff
+klapp-mes-ser-grif-fe
+klapp-mes-ser-grif-fen
+klapp-mes-ser-griffs
+kleb-stoff-tu-be
+kleb-stoff-tu-ben
+kleie-flo-cken
+klein-af-fen-haus
+klein-af-fen-hau-ses
+klein-fisch-art
+klein-spo-ren-flech-te
+klet-ter-af-fe
+klet-ter-af-fen
+kli-ma-klas-si-fi-ka-ti-on
+kli-ma-klas-si-fi-ka-tio-nen
+kli-ma-klas-si-fi-zie-rung
+kli-ma-klas-si-fi-zie-run-gen
+knie-fli-cken
+knoepff-ler
+knuf-fen
+knuf-fens
+knuf-fig
+knuf-fi-ge
+knuf-fi-gem
+knuf-fi-gen
+knuf-fi-ger
+knuf-fi-ges
+kof-fe-in-arm
+kof-fe-in-ar-me
+kof-fe-in-ar-mem
+kof-fe-in-ar-men
+kof-fe-in-ar-mer
+kof-fe-in-ar-mes
+kof-fe-in-ge-halt
+kof-fe-in-ge-hal-te
+kof-fe-in-ge-hal-ten
+kof-fe-in-ge-halts
+kof-fe-in-hal-tig
+kof-fe-in-hal-ti-ge
+kof-fe-in-hal-ti-gem
+kof-fe-in-hal-ti-gen
+kof-fe-in-hal-ti-ger
+kof-fe-in-hal-ti-ges
+kof-fe-in-re-du-ziert
+kof-fe-in-re-du-zier-te
+kof-fe-in-re-du-zier-tem
+kof-fe-in-re-du-zier-ten
+kof-fe-in-re-du-zier-ter
+kof-fe-in-re-du-zier-tes
+kol-lek-tiv-suf-fix
+kol-lek-tiv-suf-fi-xe
+kol-lek-tiv-suf-fi-xen
+kol-lek-tiv-un-ter-schrift
+kon-sum-pflicht
+kon-sum-pflich-tig
+koh-len-stoff-te-tra-chlo-rid
+kof-fer-ab-la-ge
+kof-fer-ab-la-gen
+kof-fer-ap-pa-ra-tur
+kof-fer-ap-pa-ra-tu-ren
+kof-fer-eti-kett
+kof-fer-eti-ket-ten
+kof-fer-eti-ketts
+kof-fer-oper
+kof-fer-opern
+kof-fer-raum-ab-de-ckung
+kof-fer-raum-ab-de-ckun-gen
+koh-len-stoff-art
+koh-len-stoff-ar-ten
+koh-len-stoff-ar-tig
+koh-len-stoff-ar-ti-ge
+koh-len-stoff-ar-ti-gem
+koh-len-stoff-ar-ti-gen
+koh-len-stoff-ar-ti-ger
+koh-len-stoff-ar-ti-ges
+koh-len-stoff-ein-bau
+koh-len-stoff-ein-bau-es
+koh-len-stoff-ein-schluss
+koh-len-stoff-ein-schlus-ses
+koh-len-stoff-ent-fer-nung
+koh-len-stoff-ent-fer-nun-gen
+koh-len-stoff-iso-top
+koh-len-stoff-iso-to-pe
+koh-len-stoff-iso-to-pen
+koh-len-stoff-spei-cher
+koh-len-stoff-spei-chern
+koh-len-stoff-stahl
+koh-len-stoff-sul-fid
+koh-len-stoff-sul-fi-de
+koh-len-stoff-sul-fi-den
+ko-ka-pflan-ze
+ko-ka-pflan-zen
+ko-lo-ni-al-of-fi-zier
+ko-lo-ni-al-of-fi-zie-re
+ko-lo-ni-al-of-fi-zie-ren
+ko-lo-ni-al-of-fi-ziers
+kom-man-do-flag-ge
+kom-man-do-flag-gen
+kom-man-do-of-fi-zier
+kom-man-do-of-fi-zie-re
+kom-man-do-of-fi-zie-ren
+kom-man-do-of-fi-ziers
+kon-flikt-er-zeu-gend
+kon-flikt-er-zeu-gen-de
+kon-flikt-er-zeu-gen-dem
+kon-flikt-er-zeu-gen-den
+kon-flikt-er-zeu-gen-der
+kon-flikt-er-zeu-gen-des
+kon-sum-be-ein-flus-sung
+kon-sum-be-ein-flus-sun-gen
+kon-to-pfle-ge
+kon-to-pfle-gen
+kon-troll-an-griff
+kon-troll-an-grif-fe
+kon-troll-an-grif-fen
+kon-troll-an-griffs
+ko-nus-ef-fekt
+kon-zern-ent-flech-tung
+kon-zern-ent-flech-tun-gen
+kon-zern-ober-ge-sell-schaft
+kon-zern-ober-ge-sell-schaf-ten
+kopf-in-for-ma-ti-on
+kopf-in-for-ma-tio-nen
+kopf-leer
+kopf-lee-re
+kopf-lin-de
+kopf-lin-den
+kopf-li-nie
+kopf-li-ni-en
+kopf-lin-ken
+kopf-lis-te
+kopf-lis-ten
+kopf-lu-pe
+kopf-lymph-kno-ten
+kopf-lymph-kno-tens
+kopf-stein-ge-pflas-tert
+kopf-stein-ge-pflas-ter-te
+kopf-stein-ge-pflas-ter-tem
+kopf-stein-ge-pflas-ter-ten
+kopf-stein-ge-pflas-ter-ter
+kopf-stein-ge-pflas-ter-tes
+kraft-ecke
+kraft-ecken
+kraft-ele-ment
+kraft-ele-men-te
+kraft-ele-men-ten
+kraft-er-re-gung
+kraft-er-re-gun-gen
+kraft-er-spar-nis
+kraft-er-zeu-gung
+kraft-er-zeu-gun-gen
+kraft-fahr-zeug-ele-ment
+kraft-fahr-zeug-ele-men-te
+kraft-fahr-zeug-ele-men-ten
+kraft-fahr-zeug-er-satz-teil
+kraft-fahr-zeug-er-satz-tei-le
+kraft-fahr-zeug-er-satz-tei-len
+kraft-fahr-zeug-er-satz-teils
+kraft-fahr-zeug-re-pa-ra-tur-werk-statt
+kraft-fahr-zeug-sperr-grab
+kraft-fahr-zeug-sperr-gra-bes
+kraft-om-ni-bus
+kraft-om-ni-bus-fahrt
+kraft-om-ni-bus-fahr-ten
+kraft-om-ni-bus-ver-kehr
+kraft-om-ni-bus-ver-kehrs
+kraft-spa-rend
+kraft-spa-ren-de
+kraft-spa-ren-dem
+kraft-spa-ren-den
+kraft-spa-ren-der
+kraft-spa-ren-des
+kraft-spei-cher
+kraft-spei-chern
+kraft-spei-chers
+kraft-sprit-ze
+kraft-sprit-zen
+kraft-sprung
+kraft-sprun-ges
+kraft-stoff-al-ko-hol
+kraft-stoff-al-ko-ho-le
+kraft-stoff-al-ko-ho-len
+kraft-stoff-art
+kraft-stoff-ar-ten
+kraft-stoff-ei-gen-schaft
+kraft-stoff-ei-gen-schaf-ten
+kraft-stoff-ein-spa-rung
+kraft-stoff-ein-spa-run-gen
+kraft-stoff-ein-spritz-an-la-ge
+kraft-stoff-ein-spritz-an-la-gen
+kraft-stoff-ein-spritz-be-ginn
+kraft-stoff-ein-spritz-sys-tem
+kraft-stoff-ein-spritz-sys-te-me
+kraft-stoff-ein-spritz-sys-te-men
+kraft-stoff-ein-spritz-sys-tems
+kraft-stoff-ein-sprit-zung
+kraft-stoff-ein-sprit-zun-gen
+kraft-stoff-ein-trag
+kraft-stoff-ein-tra-ges
+kraft-stoff-ein-trags
+kraft-stoff-er-spar-nis
+kraft-stoff-er-zeu-gung
+kraft-stoff-er-zeu-gun-gen
+kraft-stoff-etha-nol
+kraft-stoff-etha-nols
+kraft-stoff-luft-ge-misch
+kraft-stoff-luft-ge-mi-sche
+kraft-stoff-luft-ge-mi-schen
+kraft-stoff-luft-ge-mi-sches
+kraft-stoff-luft-ge-mischs
+kraft-stoff-sor-te
+kraft-stoff-sor-ten
+kraft-stoff-spa-rend
+kraft-stoff-spa-ren-de
+kraft-stoff-spa-ren-dem
+kraft-stoff-spa-ren-den
+kraft-stoff-spa-ren-der
+kraft-stoff-spa-ren-des
+kraft-stoff-spei-cher
+kraft-stoff-spei-chern
+kraft-stoff-spei-chers
+kraft-werk-ne-ben-pro-dukt
+kraft-werk-ne-ben-pro-duk-te
+kraft-werk-ne-ben-pro-duk-ten
+kraft-werk-ne-ben-pro-duk-tes
+kraft-werk-neu-bau
+kraft-werk-neu-bau-es
+kraft-werks-asche
+kraft-werks-tur-bi-ne
+kraft-werks-tur-bi-nen
+kraft-werks-typ
+kraft-werks-ty-pen
+kraft-werks-typs
+kraft-werk-tei-le
+kraft-werk-teilen
+kraft-werk-teils
+kreis-lauf-in-suf-fi-zi-enz
+kreis-lauf-in-suf-fi-zi-en-zen
+kreuz-auf-fin-dung
+kreuz-auf-fin-dun-gen
+kunst-stoff-elle
+kunst-stoff-tu-be
+kraft-atom
+kraft-ato-me
+krapp-farb-stoff
+kreis-tref-fen
+kreis-tref-fens
+krepp-flor
+kreuz-ei-gen-schaft
+kreuz-ei-gen-schaf-ten
+kreuz-fah-rer-fi-bel
+kreuz-fah-rer-fi-beln
+kul-tur-ei-gen-schaft
+kul-tur-ei-gen-schaf-ten
+kul-tur-of-fen-heit
+kul-tur-of-fen-hei-ten
+kunst-flug-seg-ler
+kunst-flug-seg-lern
+kunst-flug-seg-lers
+kunst-re-fle-xi-on
+kunst-re-fle-xio-nen
+kunst-stoff-ab-de-ckung
+kunst-stoff-ab-de-ckun-gen
+kunst-stoff-art
+kunst-stoff-ar-ten
+kunst-stoff-ar-ti-kel
+kunst-stoff-ar-ti-keln
+kunst-stoff-ar-ti-kels
+kunst-stoff-ecke
+kunst-stoff-ei
+kunst-stoff-ei-er
+kunst-stoff-ei-ern
+kunst-stoff-ein-la-ge
+kunst-stoff-ein-la-gen
+kunst-stoff-ein-satz
+kunst-stoff-ein-sat-zes
+kunst-stoff-ein-sit-zer
+kunst-stoff-ein-sit-zern
+kunst-stoff-ele-ment
+kunst-stoff-ele-men-te
+kunst-stoff-ele-men-ten
+kunst-stoff-em-blem
+kunst-stoff-em-ble-me
+kunst-stoff-em-ble-men
+kunst-stoff-ent-wick-lung
+kunst-stoff-ent-wick-lun-gen
+kunst-stoff-er-zeug-nis
+kunst-stoff-er-zeug-nis-se
+kunst-stoff-er-zeug-nis-sen
+kunst-stoff-er-zeug-nis-ses
+kunst-stoff-er-zeug-ung
+kunst-stoff-etui
+kunst-stoff-etuis
+kunst-stoff-iso-la-tor
+kunst-stoff-iso-la-to-ren
+kunst-stoff-iso-lie-rung
+kunst-stoff-iso-lie-run-gen
+kunst-stoff-ob-jekt
+kunst-stoff-ob-jek-te
+kunst-stoff-ob-jek-ten
+kunst-stoff-ob-jek-tes
+kunst-stoff-se-gel
+kunst-stoff-se-geln
+kunst-stoff-seg-ment
+kunst-stoff-seg-men-te
+kunst-stoff-seg-men-ten
+kunst-stoff-soh-le
+kunst-stoff-soh-len
+kunst-stoff-spa-tel
+kunst-stoff-spa-teln
+kunst-stoff-spei-se-kar-te
+kunst-stoff-spei-se-kar-ten
+kunst-stoff-sprit-ze
+kunst-stoff-sprit-zen
+kunst-stoff-spritz-guss-ma-schi-ne
+kunst-stoff-spritz-guss-ma-schi-nen
+kunst-stoff-spritz-guss
+kunst-stoff-spritz-gus-ses
+kunst-stoff-spritz-guss-ma-schi-ne
+kunst-stoff-spritz-guss-ma-schi-nen
+kunst-stoff-spritz-ma-schi-ne
+kunst-stoff-spritz-ma-schi-nen
+kunst-stoff-stab
+kunst-stoff-sta-bes
+kunst-stoff-steg
+kunst-stoff-ste-ge
+kunst-stoff-topfs
+kunst-stoff-top-fes
+kunst-stoff-tu-ben
+kunst-wort-er-fin-dung
+kunst-wort-er-fin-dun-gen
+kur-ven-stei-fig-keit
+kurz-trick-film
+kurz-trick-fil-me
+kurz-trick-fil-men
+kurz-trick-fil-mes
+kurz-trick-film-chen
+kurz-trick-film-chens
+kurz-start-ei-gen-schaft
+kurz-start-ei-gen-schaf-ten
+kurz-zeit-ef-fekt
+kurz-zeit-ef-fek-te
+kurz-zeit-ef-fek-ten
+kurz-zeit-ef-fek-tes
+lang-sam-lauf-the-ra-pie
+la-ger-flansch
+la-gu-nen-riff
+la-gu-nen-rif-fe
+la-gu-nen-rif-fen
+la-gu-nen-riffs
+lan-de-schiff
+lan-de-schif-fe
+lan-de-schif-fen
+lan-de-schiffs
+land-schafts-ach-se
+land-schafts-ach-sen
+land-schafts-aqua-rell
+land-schafts-aqua-rel-le
+land-schafts-aqua-rel-len
+land-schafts-cha-rak-ter
+land-schafts-cha-rak-ters
+land-schafts-en-sem-ble
+land-schafts-en-sem-bles
+land-schafts-tem-pel
+land-schafts-tem-peln
+land-schafts-tem-pels
+land-schafts-tier
+land-schafts-tie-re
+land-schafts-tier-gar-ten
+land-schafts-tun-nel
+land-schafts-tun-neln
+land-schafts-tun-nels
+land-schafts-typ
+land-schafts-ty-pen
+land-schafts-typs
+land-sturm-of-fi-zier
+land-sturm-of-fi-zie-re
+land-sturm-of-fi-zie-ren
+land-sturm-of-fi-ziers
+land-wirt-schafts-typ
+land-wirt-schafts-ty-pen
+land-wirt-schafts-tys
+lang-lauf-idol
+lang-lauf-ido-le
+lang-lauf-ido-len
+lang-zeit-ef-fekt
+lang-zeit-ef-fek-te
+lang-zeit-ef-fek-ten
+lang-zeit-ef-fek-tes
+la-ser-ef-fekt
+la-ser-ef-fek-te
+la-ser-ef-fek-ten
+la-ser-ei-gen-schaft
+la-ser-ei-gen-schaf-ten
+lauf-idol
+lauf-ido-le
+lauf-ido-len
+lauf-in-dex
+lauf-in-de-xe
+lauf-in-de-xes
+lauf-in-di-ces
+lauf-in-di-zes
+lauf-in-sekt
+lauf-in-sek-te
+lauf-in-sek-tes
+lauf-the-ra-pie
+lauf-the-ra-pi-en
+lauf-trom-mel
+lauf-zeit-ef-fekt
+lauf-zeit-ef-fek-te
+lauf-zeit-ef-fek-ten
+lauf-zeit-ef-fek-tes
+le-bend-impf-stoff
+le-bend-impf-stof-fe
+le-bend-impf-stof-fen
+le-bend-impf-stoffs
+lehr-ein-fluss
+lehr-ein-flus-ses
+lehr-stabs-of-fi-zier
+lehr-stabs-of-fi-zie-re
+lehr-stabs-of-fi-zie-ren
+lehr-stabs-of-fi-ziers
+lei-ter-bahn-ent-flech-tung
+lei-ter-bahn-ent-flech-tun-gen
+lenk-ef-fekt
+lenk-ef-fek-te
+lenk-ef-fek-ten
+lenk-ef-fek-tes
+lenk-ein-griff
+lenk-ein-grif-fe
+lenk-ein-grif-fen
+lenk-luft-schiff
+lenk-luft-schif-fe
+lenk-luft-schif-fen
+lenk-luft-schiffs
+li-bi-do-fi-xie-rung
+libre-office
+licht-ei-gen-schaft
+licht-ei-gen-schaf-ten
+licht-hof-frei
+licht-hof-freie
+licht-hof-frei-em
+licht-hof-frei-en
+licht-hof-frei-es
+licht-un-emp-find-lich
+licht-un-emp-find-li-che
+licht-un-emp-find-li-chem
+licht-un-emp-find-li-chen
+licht-un-emp-find-li-cher
+licht-un-emp-find-li-ches
+lid-spal-ten-fleck
+lie-bes-auf-fas-sung
+lie-bes-auf-fas-sun-gen
+lie-fer-an-schrift
+lie-fer-an-schrif-ten
+li-ni-en-ge-flecht
+li-ni-en-ge-flech-te
+li-ni-en-ge-flech-ten
+li-te-ra-tur-wis-sen-schaft-um-strit-ten
+live-auf-tritt
+live-auf-trit-te
+live-auf-trit-ten
+live-auf-tritts
+log-file
+lo-go-gra-fie
+lo-kal-ei-sen-bahn-ge-sell-schaft
+lo-kal-ei-sen-bahn-ge-sell-schaf-ten
+luft-ab-len-kung
+luft-ab-len-kun-gen
+luft-an-ker
+luft-an-kers
+luft-at-mung
+luft-at-ta-cke
+luft-at-ta-cken
+luft-bri-ga-de
+luft-bri-ga-den
+luft-druck-er-nied-ri-gung
+luft-druck-er-nied-ri-gun-gen
+luft-eil-fracht
+luft-eil-frach-ten
+luft-elek-trisch
+luft-elek-tri-sche
+luft-elek-tri-schem
+luft-elek-tri-schen
+luft-elek-tri-scher
+luft-elek-tri-sches
+luft-eva-ku-ie-rung
+luft-eva-ku-ie-run-gen
+luft-emis-si-on
+luft-emis-sio-nen
+luft-emis-sions-wert
+luft-emis-sions-wer-te
+luft-emis-sions-wer-tes
+luft-eva-ku-ie-rung
+luft-eva-ku-ie-run-gen
+luft-fahrt-aka-de-mie
+luft-fahrt-aka-de-mi-en
+luft-fahrt-al-li-anz
+luft-fahrt-al-li-an-zen
+luft-fahrt-elek-tro-nik
+luft-fahrt-elek-tro-ni-ken
+luft-fahrt-etat
+luft-fahrt-etats
+luft-fahrt-in-ge-ni-eur
+luft-fahrt-in-ge-ni-eu-re
+luft-fahrt-in-ge-ni-eu-ren
+luft-fahrt-in-ge-ni-eu-rin
+luft-fahrt-in-ge-ni-eurs
+luft-fahrt-in-ge-ni-eur-we-sen
+luft-fahrt-in-ge-ni-eur-we-sens
+luft-fahrt-in-sti-tut
+luft-fahrt-in-sti-tu-te
+luft-fahrt-in-sti-tu-ten
+luft-fahrt-in-sti-tuts
+luft-fahrt-rol-le
+luft-fahrt-rol-len
+luft-fahr-zeug-re-gis-ter
+luft-fahr-zeug-re-gis-tern
+luft-fahr-zeug-re-gis-ters
+luft-fracht-rau-mes
+luft-fracht-sen-dung
+luft-fracht-sen-dun-gen
+luft-fracht-spe-di-ti-on
+luft-fracht-spe-di-tio-nen
+luft-fracht-er-satz-ver-kehr
+luft-fracht-er-satz-ver-kehrs
+luft-lan-de-in-va-si-on
+luft-lan-de-in-va-sio-nen
+luft-lan-de-schlacht
+luft-lan-de-schlach-ten
+luft-of-fen-si-ve
+luft-of-fen-si-ven
+luft-ope-ra-ti-on
+luft-ope-ra-tio-nen
+luft-oxi-da-ti-on
+luft-oxi-da-tio-nen
+luft-post-ak-ti-en-ge-sell-schaft
+luft-post-ak-ti-en-ge-sell-schaf-ten
+luft-post-um-schlag
+luft-post-um-schla-ges
+luft-post-um-schlags
+luft-ra-des
+luft-ra-ke-te
+luft-ra-ke-ten
+luft-ree-de-rei
+luft-ree-de-rei-en
+luft-rei-bung
+luft-rei-bun-gen
+luft-rei-fen
+luft-rei-fens
+luft-rich-tung
+luft-sport-ring
+luft-stan-dard
+luft-stan-dards
+luft-strom-ab-len-kung
+luft-strom-ab-len-kun-gen
+luft-strom-man-gel
+luft-strom-man-gels
+luft-strom-um-kehr
+luft-sturm-ein-heit
+luft-tank
+luft-tanks
+luft-tan-ken
+luft-tan-ker
+luft-tan-kern
+luft-tan-kers
+luft-trans-port-bri-ga-de
+luft-trans-port-bri-ga-den
+luft-trich-ter
+luft-trich-tern
+luft-trich-ters
+luft-un-ru-hen
+luft-ver-kehrs-ho-heit
+luft-ver-kehrs-ho-hei-ten
+luft-waf-fen-ad-ju-tant
+luft-waf-fen-er-pro-bungs-stel-le
+luft-waf-fen-er-pro-bungs-stel-len
+lutsch-re-flex
+lutsch-re-fle-xe
+lutsch-re-fle-xen
+lutsch-re-fle-xes
+ly-ra-flos-sig
+ly-ra-flos-si-ge
+ly-ra-flos-si-ger
+mac-guf-fin
+ma-cho-haft
+ma-cho-haf-te
+ma-cho-haf-tem
+ma-cho-haf-ten
+ma-cho-haf-ter
+ma-cho-haf-tes
+ma-fia-hoch-burg
+ma-fia-hoch-bur-gen
+ma-fia-sa-ga
+ma-gie-fla-sche
+ma-gie-fla-schen
+mag-net-ef-fekt
+mag-net-ef-fek-te
+mag-net-ef-fek-ten
+mag-net-ei-gen-schaft
+mag-net-ei-gen-schaf-ten
+ma-gnum-fla-sche
+ma-gnum-fla-schen
+mai-abend-ge-sell-schaft
+mai-abend-ge-sell-schaf-ten
+ma-kro-fluss-dia-gramm
+ma-kro-fluss-dia-gram-me
+ma-kro-fluss-dia-gram-men
+ma-kro-fluss-dia-gramms
+man-go-pflau-me
+man-go-pflau-men
+man-na-flech-te
+man-na-flech-ten
+man-tel-ei-gen-schaft
+man-tel-ei-gen-schaf-ten
+ma-schi-nen-ste-no-gra-fie
+ma-schi-nen-ste-no-gra-fi-en
+mas-sen-fisch-art
+maul-af-fe
+maul-af-fen
+maul-wurf-lob-by-ist
+maul-wurf-lob-by-is-ten
+maus-ohr-fle-der-maus
+mehl-fla-den
+mehl-fla-dens
+me-di-ter-ran-flo-ra
+meis-ter-schafts-team
+meis-ter-schafts-teams
+meis-ter-schafts-tor
+meis-ter-schafts-to-re
+meis-ter-schafts-to-ren
+meis-ter-schafts-tur-nier
+meis-ter-schafts-tur-nie-re
+meis-ter-schafts-tur-nie-ren
+meis-ter-schafts-tur-niers
+men-gen-auf-fas-sung
+men-gen-auf-fas-sun-gen
+men-gen-auf-trag
+men-gen-auf-tra-ges
+men-gen-auf-trags
+mes-ser-heft
+mes-ser-hef-te
+mes-ser-hef-ten
+mes-ser-hef-tes
+milch-glas-ef-fekt
+milch-glas-ef-fek-te
+milch-glas-ef-fek-ten
+min-dest-ei-gen-schaft
+min-dest-ei-gen-schaf-ten
+mi-ne-ral-stoff-ader
+mi-ne-ral-stoff-adern
+misch-ef-fekt
+misch-ef-fek-te
+misch-ef-fek-ten
+misch-sul-fi-de
+mit-ar-bei-ter-fluk-tu-a-ti-on
+mit-ar-bei-ter-fluk-tu-a-tio-nen
+mit-ar-bei-ter-suf-fix
+mit-ar-bei-ter-suf-fi-xe
+mit-ar-bei-ter-suf-fi-xen
+mit-tel-fin-ger-end-glied
+mit-tel-fin-ger-end-glie-des
+mo-del-auf-tritt
+mo-del-auf-trit-te
+mo-del-auf-trit-ten
+mond-raum-schiff
+mond-raum-schif-fe
+mond-raum-schif-fen
+mond-raum-schiffs
+mond-schein-ef-fekt
+mond-schein-ef-fek-te
+mond-schein-ef-fek-ten
+mon-sun-zeit
+mo-no-spe-zi-fisch
+mo-no-spe-zi-fi-sche
+mo-no-spe-zi-fi-schem
+mo-no-spe-zi-fi-schen
+mo-no-spe-zi-fi-scher
+mo-no-spe-zi-fi-sches
+mo-ral-of-fi-zier
+mo-ral-of-fi-zie-re
+mo-ral-of-fi-zie-ren
+mo-ral-of-fi-ziers
+mor-gen-duft-ap-fel
+mor-gen-duft-ap-fels
+mor-gen-stei-fig-keit
+mo-tor-kraft-sprit-ze
+mo-tor-kraft-sprit-zen
+mo-tor-topf-fil-ter
+muff-lig
+muff-li-ge
+muff-li-gen
+muff-li-ger
+mull-auf-la-ge
+mull-auf-la-gen
+mund-art-schrift-stel-ler
+mund-art-schrift-stel-le-rin
+mund-art-schrift-stel-lern
+mund-art-schrift-stel-lers
+mund-luft-tank
+mund-luft-tanks
+mu-sik-ef-fekt
+mu-sik-ef-fek-te
+mu-sik-ef-fek-ten
+mu-sik-file
+mu-sik-lei-den-schaft
+mu-sik-lei-den-schaf-ten
+mu-sik-of-fi-zier
+mu-sik-of-fi-zie-re
+mu-sik-of-fi-zie-ren
+mu-sik-of-fi-ziers
+mu-sik-treff
+mu-sik-treffs
+mus-kel-fleisch-an-teil
+mus-kel-fleisch-an-tei-le
+nach-ste-no-gra-fie-re
+nach-ste-no-gra-fie-ren
+nach-ste-no-gra-fierst
+nach-ste-no-gra-fiert
+nach-ste-no-gra-fier-te
+nach-ste-no-gra-fier-ten
+nach-ste-no-gra-fier-test
+nach-zu-ste-no-gra-fie-ren
+na-cken-stei-fig-keit
+na-del-holz-an-pflan-zung
+na-del-holz-an-pflan-zun-gen
+na-del-stich-emp-fin-dung
+na-del-stich-emp-fin-dun-gen
+na-sen-dok-tor-fisch-art
+na-tri-um-sul-fit
+na-tur-ei-gen-schaft
+na-tur-ei-gen-schaf-ten
+na-tur-stoff-ex-trak-ti-on
+na-tur-stoff-ex-trak-tio-nen
+ne-bel-ef-fekt
+ne-bel-ef-fek-te
+ne-bel-ef-fek-ten
+ne-bel-ef-fekts
+ne-bel-emp-find-lich
+ne-bel-emp-find-li-che
+ne-bel-emp-find-li-chem
+ne-bel-emp-find-li-chen
+ne-bel-emp-find-li-cher
+ne-bel-emp-find-li-chen
+net-to-fluss
+net-to-flus-ses
+netz-ei-gen-schaft
+netz-ei-gen-schaf-ten
+netz-haut-re-flex
+netz-haut-re-fle-xe
+netz-haut-re-fle-xen
+netz-haut-re-fle-xes
+netz-kauf-ini-tia-ti-ve
+netz-kauf-ini-tia-ti-ven
+netz-werk-ef-fekt
+netz-werk-ef-fek-te
+netz-werk-ef-fek-ten
+netz-werk-tref-fen
+netz-werk-tref-fens
+neu-schef-fel
+neu-schef-fels
+nie-der-flur-an-teil
+nie-der-flur-an-tei-le
+nie-der-flur-an-tei-len
+nie-der-flur-an-teils
+nie-der-flur-ein-stieg
+nie-der-flur-ein-stie-ge
+nie-der-flur-ein-stie-gen
+ni-ko-tin-ver-gif-tung
+ni-ko-tin-ver-gif-tun-gen
+nor-mal-schrift-er-lass
+nor-mal-schrift-er-las-ses
+nor-mal-was-ser-stoff-elek-tro-de
+nor-mal-was-ser-stoff-elek-tro-den
+norm-pflicht
+norm-pflich-tig
+norm-pflich-ti-ge
+nos-tal-gie-fla-sche
+nos-tal-gie-fla-schen
+nos-tal-gie-floh-markt
+not-fall-ein-griff
+not-fall-ein-grif-fe
+not-fall-ein-grif-fen
+null-acht-fuff-zehn
+ober-deck-of-fi-zier
+ober-deck-of-fi-zie-re
+ober-deck-of-fi-zie-ren
+ober-deck-of-fi-ziers
+ober-hof-fak-tor
+ober-hof-fak-tors
+ober-hof-fak-to-ren
+ober-she-riff
+ober-she-riffs
+ob-jekt-ei-gen-schaft
+ob-jekt-ei-gen-schaf-ten
+ob-jekt-iden-ti-fi-zie-rung
+ob-jekt-iden-ti-fi-zie-run-gen
+of-fi-ziers-ka-bi-ne
+of-fi-ziers-ka-bi-nen
+off-shore-boh-rung
+off-shore-boh-run-gen
+oran-gen-haut-ef-fekt
+pa-pri-ka-pflan-ze
+pa-pri-ka-pflan-zen
+papst-herr-schaft
+papst-herr-schaf-ten
+par-la-ments-ste-no-gra-fie
+par-la-ments-ste-no-gra-fi-en
+par-tei-iden-ti-fi-ka-ti-on
+par-tei-tref-fen
+par-tei-tref-fens
+pas-sa-gier-rund-flug
+pas-sa-gier-rund-flugs
+pass-er-satz-be-schaf-fung
+pass-er-satz-be-schaf-fun-gen
+per-so-nal-fluk-tu-a-ti-on
+per-so-nal-fluk-tu-a-tio-nen
+per-so-nal-of-fi-zier
+per-so-nal-of-fi-zie-re
+per-so-nal-of-fi-zie-ren
+per-so-nal-of-fi-ziers
+per-so-nal-suf-fix
+per-so-nal-suf-fi-xe
+per-so-nal-suf-fi-xen
+pfand-brief-in-ha-ber
+pfand-brief-in-ha-bern
+pfand-brief-in-ha-bers
+pfef-fer-minz-aro-ma
+pfef-fer-minz-aro-mas
+pfeif-laut
+pfeif-lau-te
+pfeif-lau-ten
+pfiff-laut
+pfiff-lau-te
+pfiff-lau-ten
+pfingst-och-se
+pfingst-och-sen
+pfir-sich-aro-ma
+pfir-sich-aro-mas
+pfir-sich-aro-men
+plan-dampf-fahrt
+plan-dampf-fahr-ten
+pflan-zen-ana-to-mie
+pflan-zen-ana-to-mi-en
+pflan-zen-asche
+pflan-zen-as-so-zia-ti-on
+pflan-zen-as-so-zia-tio-nen
+pflan-zen-dau-ne
+pflan-zen-dau-nen
+pflan-zen-eli-xier
+pflan-zen-eli-xie-re
+pflan-zen-eli-xie-ren
+pflan-zen-en-zym
+pflan-zen-en-zy-me
+pflan-zen-en-zy-men
+pflan-zen-fres-ser-ge-biss
+pflan-zen-fres-ser-ge-bis-se
+pflan-zen-fres-ser-ge-bis-sen
+pflan-zen-fres-ser-ge-bis-ses
+pflan-zen-or-na-ment
+pflan-zen-or-na-men-te
+pflan-zen-sau-ger
+pflan-zen-sau-gern
+pflan-zen-sau-gers
+pflan-zen-spross
+pflan-zen-spros-se
+pflan-zen-spros-sen
+pflan-zen-seele
+pflan-zen-see-len
+pflan-zen-zer-fall
+pflan-zen-zer-falls
+pflau-men-aro-ma
+pflau-men-aro-mas
+pfle-ge-anam-ne-se
+pfle-ge-anam-ne-sen
+pfle-ge-in-for-ma-tik
+pfle-ge-in-sti-tut
+pfle-ge-in-sti-tu-te
+pfle-ge-in-sti-tu-ten
+pfle-ge-in-sti-tuts
+pfle-ge-in-sti-tu-ti-on
+pfle-ge-in-sti-tu-tio-nen
+pfle-ge-in-ten-siv
+pfle-ge-in-ten-si-ve
+pfle-ge-in-ten-si-vem
+pfle-ge-in-ten-si-ven
+pfle-ge-in-ten-si-ver
+pfle-ge-in-ten-si-ves
+pfle-ge-rat
+pfle-ge-ra-tes
+pfle-ge-stra-te-gie
+pfle-ge-stra-te-gi-en
+pflicht-ab-lie-fe-rung
+pflicht-ab-lie-fe-run-gen
+pflicht-ei-fer
+pflicht-ele-ment
+pflicht-ele-men-te
+pflicht-ele-men-ten
+pflicht-er-be
+pflicht-er-bes
+pflicht-er-ben
+pflicht-er-bens
+pflicht-ethik
+pflicht-ethi-ken
+pflicht-ethos
+pflicht-log-in
+pflicht-rau-mes
+pflug-soh0le
+pflug-sterz
+phos-phat-roh-stoff
+phos-phat-roh-stof-fe
+phos-phat-roh-stof-fen
+phos-phat-roh-stoffs
+pic-co-lo-fla-sche
+pic-co-lo-fla-schen
+pik-ko-lo-fla-sche
+pik-ko-lo-fla-schen
+plas-ti-lin-fi-gur
+plas-ti-lin-fi-gu-ren
+po-lit-auf-trag
+po-li-zei-flie-ger
+po-li-zei-flie-gern
+po-li-zei-flie-gers
+po-li-zei-flie-ge-rei
+po-li-zei-flie-ger-staf-fel
+po-li-zei-not-ruf-tech-nik
+po-li-zei-not-ruf-tech-ni-ken
+pomp-haft
+pomp-haf-te
+pomp-haf-tem
+pomp-haf-ten
+pomp-haf-ter
+pomp-haf-tes
+pomp-haf-tig-keit
+pop-flair
+pos-ses-siv-suf-fix
+pos-ses-siv-suf-fi-xe
+pos-ses-siv-suf-fi-xes
+preis-ein-fluss
+preis-ein-flus-ses
+pres-se-stabs-of-fi-zier
+pres-se-stabs-of-fi-zie-re
+pres-se-stabs-of-fi-zie-ren
+pres-se-stabs-of-fi-ziers
+pri-vat-ei-sen-bahn-ge-sell-schaft
+pri-vat-ei-sen-bahn-ge-sell-schaf-ten
+pri-vat-of-fen-ba-rung
+pri-vat-of-fen-ba-run-gen
+pro-dukt-ei-gen-schaft
+pro-dukt-ei-gen-schaf-ten
+pro-dukt-iden-ti-fi-ka-ti-on
+pro-dukt-iden-ti-fi-ka-ti-ons-num-mer
+pro-dukt-iden-ti-fi-ka-ti-ons-num-mern
+pro-dukt-roh-stoff
+pro-dukt-roh-stof-fe
+pro-dukt-roh-stof-fen
+pro-dukt-roh-stoffs
+pro-fi-ab-ge-ord-ne-te
+pro-fi-ab-ge-ord-ne-ten
+pro-fi-ab-ge-ord-ne-ter
+pro-fi-er-fah-rung
+pro-fi-er-fah-run-gen
+pro-fil-ar-beit
+pro-fil-ar-bei-ten
+pro-fil-aus-wahl
+pro-fil-aus-tritt
+pro-fil-aus-trit-te
+pro-fil-aus-trit-ten
+pro-fil-bau-glas
+pro-fil-bau-gla-ses
+pro-fil-blech
+pro-fil-ble-che
+pro-fil-ble-chen
+pro-fil-ei-sen
+pro-fil-ei-sens
+pro-fil-ele-ment
+pro-fil-ele-men-te
+pro-fil-ele-men-ten
+pro-fil-en-de
+pro-fil-en-den
+pro-fil-en-des
+pro-fil-er-stel-lung
+pro-fil-er-stel-lun-gen
+pro-fil-er-stel-lungs-pro-gramm
+pro-fil-er-stel-lungs-pro-gram-me
+pro-fil-er-stel-lungs-pro-gram-men
+pro-fil-er-stel-lungs-pro-gramms
+pro-fil-er-wei-te-rung
+pro-fil-ober-sei-te
+pro-fil-ober-sei-ten
+pro-fil-ober-stu-fe
+pro-fil-ober-stu-fen
+pro-fil-ord-ner
+pro-fil-ord-nern
+pro-fil-ord-ners
+pro-fi-zweif-ler
+pro-jekt-of-fi-zier
+pro-jekt-of-fi-zie-re
+pro-jekt-of-fi-zie-ren
+pro-jekt-of-fi-ziers
+pro-pa-gan-da-be-griff
+pro-pa-gan-da-be-grif-fe
+pro-pa-gan-da-be-grif-fen
+pro-pa-gan-da-be-griffs
+pro-pa-gan-da-flos-kel
+pro-pa-gan-da-flos-keln
+pro-te-in-iden-ti-fi-ka-ti-on
+pro-te-in-pflan-zen
+pro-te-in-re-ser-ve-stoff
+pro-te-in-re-ser-ve-stof-fe
+pro-te-in-re-ser-ve-stof-fen
+pro-te-in-re-ser-ve-stoffs
+pro-zess-ei-gen-schaft
+pro-zess-ei-gen-schaf-ten
+puf-fer-an-schlag
+puf-fer-an-schla-ges
+puf-fer-ele-ment
+puf-fer-ele-men-te
+puf-fer-ele-men-ten
+puff-er-zeug-nis
+puff-er-zeug-nis-se
+puff-er-zeug-nis-sen
+puff-er-zeug-nis-ses
+pup-pen-trick-film
+pup-pen-trick-fil-me
+pup-pen-trick-fil-men
+pup-pen-trick-films
+psy-chi-a-trie
+psy-chi-a-trisch
+quer-schiff-ach-se
+quer-schiff-ach-sen
+ra-dar-re-flek-toren
+ra-dar-re-flex
+ra-dar-re-flek-tor
+rad-dampf-fre-gat-te
+rad-dampf-fre-gat-ten
+ra-dio-dif-fu-si-on
+ra-dio-treff
+ra-dio-treffs
+raffles-hos-pi-tal
+rah-men-stoff-plan
+rah-men-stoff-pla-nes
+raum-ef-fekt
+raum-ef-fek-te
+raum-ef-fek-ten
+raum-ei-gen-schaft
+raum-ei-gen-schaf-ten
+raum-ein-fluss
+raum-ein-flus-ses
+raum-fahrt-in-ge-nieur-wis-sen-schaft
+raum-fahrt-in-ge-nieur-wis-sen-schaf-ten
+raum-schiff-uhr
+raum-schiff-uh-ren
+rausch-gift-ex-trakt
+rausch-gift-ex-trak-te
+rausch-gift-ex-trak-ten
+rausch-gift-ex-trakts
+rausch-gift-re-ha-bi-li-ta-ti-ons-pro-gramm
+rausch-gift-re-ha-bi-li-ta-ti-ons-zen-trum
+rausch-gift-re-ha-bi-li-ta-ti-ons-zen-trums
+rausch-gift-res-te
+rausch-gift-res-ten
+rausch-gift-selbst-hil-fe
+rausch-gift-selbst-hil-fe-ver-ein
+rausch-gift-selbst-hil-fe-ver-ei-ne
+rausch-gift-selbst-hil-fe-ver-ei-nen
+rausch-gift-selbst-hil-fe-ver-eins
+rechts-guts-an-griff
+rechts-guts-an-grif-fe
+rechts-guts-an-grif-fen
+rechts-guts-an-griffs
+re-cy-cling-stoff
+re-cy-cling-stof-fe
+re-cy-cling-stof-fen
+re-cy-cling-stoffs
+re-flex-epi-lep-sie
+re-flex-um-kehr
+re-flex-vi-sier
+re-gel-auf-la-ge
+re-gel-auf-la-gen
+reif-land
+reif-land-schaf-ten
+reiz-ei-gen-schaft
+reiz-ei-gen-schaf-ten
+reiz-ein-fluss
+reiz-ein-flus-ses
+reg-ler-ei-gen-schaf-ten
+re-kord-erst-auf-la-ge
+re-kord-erst-auf-la-gen
+re-mote-zu-griff
+re-mote-zu-grif-fe
+re-mote-zu-grif-fen
+re-mote-zu-griffs
+renn-fah-rer-film
+renn-fah-rer-fil-me
+renn-fah-rer-fil-men
+renn-fah-rer-films
+renn-fah-rer-film-chen
+renn-fah-rer-film-chens
+re-ser-ve-feu-er-schiff
+re-ser-ve-feu-er-schif-fe
+re-ser-ve-feu-er-schif-fen
+re-ser-ve-feu-er-schiffs
+re-ser-ve-kampf-trup-pe
+re-ser-ve-kampf-trup-pen
+re-ser-ve-kraft-stoff
+re-ser-ve-kraft-stof-fe
+re-ser-ve-kraft-stof-fen
+re-ser-ve-kraft-stoffs
+re-ser-ve-kraft-stoff-ka-nis-ter
+re-ser-ve-kraft-stoff-ka-nis-tern
+re-ser-ve-kraft-stoff-ka-nis-ters
+re-ser-ve-luft
+re-ser-ve-luft-vor-rat
+re-ser-ve-luft-vor-ra-tes
+re-ser-ve-luft-vor-rats
+re-ser-ve-stoff
+re-ser-ve-stof-fe
+re-ser-ve-stof-fen
+re-ser-ve-stoffs
+re-ser-ve-stoff-spei-che-rung
+re-ser-ve-stoff-spei-che-run-gen
+res-tau-rant
+res-tau-rants
+re-tro-flex
+re-tro-fle-xe
+re-tro-fle-xem
+re-tro-fle-xem
+re-tro-fle-xer
+re-tro-fle-xes
+rie-sen-tin-ten-fisch
+rie-sen-tin-ten-fi-sche
+rie-sen-tin-ten-fi-schen
+riff-la-gu-ne
+riff-la-gu-nen
+riff-lat-scher
+riff-lat-schern
+rit-ter-schlag-ef-fekt
+rit-ter-schlag-ef-fek-te
+rit-ter-schlag-ef-fek-ten
+roh-stoff-er-spar-nis
+rot-stift-ak-ti-on
+rou-ti-ne-ein-griff
+rou-ti-ne-ein-grif-fe
+rou-ti-ne-ein-grif-fen
+rou-ti-ne-ein-griffs
+ruf-far-be
+ruf-far-ben
+ru-he-in-suf-fi-zi-enz
+ru-he-in-suf-fi-zi-en-zen
+rumpf-li-ga
+rumpf-li-nie
+rumpf-li-ni-en
+saft-oran-ge
+saft-oran-gen
+sam-mel-auf-trag
+sam-mel-auf-tra-ges
+sam-mel-auf-trags
+salz-uf-len
+salz-uf-ler
+sand-riff
+sand-rif-fe
+sa-ti-re-heft-chen
+sa-ti-re-heft-chens
+sat-tel-kopf-lift
+sau-er-stoff-al-te-rung
+sau-er-stoff-al-te-run-gen
+sau-er-stoff-die-be
+sau-er-stoff-ein-satz
+sau-er-stoff-ein-sat-zes
+sau-er-stoff-ein-schluss
+sau-er-stoff-ein-schlus-ses
+sau-er-stoff-ein-trag
+sau-er-stoff-ein-tra-ges
+sau-er-stoff-elek-tro-de
+sau-er-stoff-elek-tro-den
+sau-er-stoff-emp-find-lich
+sau-er-stoff-emp-find-li-che
+sau-er-stoff-emp-find-li-chem
+sau-er-stoff-emp-find-li-chen
+sau-er-stoff-emp-find-li-cher
+sau-er-stoff-emp-find-li-ches
+sau-er-stoff-ent-wick-lung
+sau-er-stoff-ent-wick-lun-gen
+sau-er-stoff-ent-zug
+sau-er-stoff-ent-zu-ges
+sau-er-stoff-iso-top
+sau-er-stoff-iso-to-pe
+sau-er-stoff-iso-to-pen
+sau-er-stoff-li-mi-tiert
+sau-er-stoff-li-mi-tier-te
+sau-er-stoff-li-mi-tier-ten
+sau-er-stoff-spei-cher
+sau-er-stoff-spei-chern
+sau-er-stoff-spei-chers
+sau-er-stoff-spei-che-rung
+sau-er-stoff-stro-mes
+sau-er-stoff-the-ra-pie
+sau-er-stoff-the-ra-pi-en
+sauf-trot-tel
+schad-stoff-li-mi-tiert
+schad-stoff-li-mi-tier-te
+schad-stoff-li-mi-tier-ten
+schaf-in-sel
+schaf-in-seln
+schaf-laus-flie-ge
+schaf-laus-flie-gen
+schaf-talg
+schaf-tals-grund
+schaf-teich
+schaf-tei-che
+schaf-trans-port
+schaf-trans-por-te
+schaf-trieb
+schaf-trift
+schall-ein-fluss
+schall-ein-flus-ses
+schall-emp-fin-den
+schall-emp-fin-dens
+schall-emp-fin-dung
+schall-emp-fin-dun-gen
+schall-emp-fin-dungs-ap-pa-rat
+schall-emp-fin-dungs-ap-pa-ra-te
+schall-emp-fin-dungs-ap-pa-ra-ten
+schalt-ei-gen-schaft
+schalt-ei-gen-schaf-ten
+schaum-stoff-iso-la-ti-on
+schaum-stoff-iso-la-tio-nen
+schif-fer-bart
+schif-fer-denk-mal
+schif-fer-denk-ma-les
+schiff-fahrts-in-ge-nieur-we-sen
+schiff-fahrts-in-ge-nieur-we-sens
+schiff-fahrts-pe-ri-ode
+schiff-fahrts-pe-ri-oden
+schiff-fahrts-po-li-zei
+schiff-fahrts-po-li-zei-en
+schiff-fahrts-pro-to-koll
+schiff-fahrts-pro-to-kol-le
+schiff-fahrts-pro-to-kol-len
+schiff-fahrts-pro-to-kolls
+schiff-fahrts-pro-zes-si-on
+schiff-fahrts-pro-zes-sio-nen
+schiff-la-che
+schiff-lan-ge
+schiff-lau-be
+schiff-raum
+schiffs-ach-se
+schiffs-ach-sen
+schiffs-agent
+schiffs-agen-ten
+schiffs-amt
+schiffs-am-tes
+schiffs-com-pu-ter
+schiffs-com-pu-tern
+schiffs-com-pu-ters
+schiffs-con-tai-ner
+schiffs-con-tai-nern
+schiffs-con-tai-ners
+schiffs-crew
+schiffs-crews
+schiffs-en-de
+schiffs-en-den
+schiffs-en-des
+schiffs-ei-chung
+schiffs-ei-chun-gen
+schiffs-eti-ket-te
+schiffs-in-dus-trie
+schiffs-in-dus-tri-en
+schiffs-in-ge-nieur
+schiffs-in-ge-nieu-re
+schiffs-in-ge-nieu-ren
+schiffs-in-ge-nieu-rin
+schiffs-in-ge-nieurs
+schiffs-in-ne-re
+schiffs-in-ne-ren
+schiffs-in-spek-ti-on
+schiffs-in-spek-tio-nen
+schiffs-in-stal-la-ti-on
+schiffs-in-stal-la-tio-nen
+schiffs-in-stand-set-zungs-ar-beit
+schiffs-in-stand-set-zungs-ar-bei-ten
+schiffs-in-stand-set-zungs-werk
+schiffs-in-stand-set-zungs-wer-ke
+schiffs-in-stand-set-zungs-wer-ken
+schiffs-in-stand-set-zungs-werks
+schiffs-kiel
+schiffs-kie-le
+schiffs-kie-len
+schiffs-me-ta-pher
+schiffs-me-ta-phern
+schiff-sor-te
+schiff-sor-ten
+schiffs-part
+schiffs-pa-ten-schaft
+schiffs-pa-ten-schaf-ten
+schiffs-res-tau-rant
+schiffs-res-tau-rants
+schiff-sta-ti-on
+schiff-sta-tio-nen
+schiffs-tau
+schiffs-taue
+schiffs-tau-en
+schiffs-tau-fe
+schiffs-tau-fen
+schiffs-ti-cket
+schiffs-ti-ckets
+schiffs-tun-nel
+schiffs-tun-neln
+schiffs-tun-nels
+schiffs-tur-bi-ne
+schiffs-tur-bi-nes
+schiffs-turm
+schi-flie-gen
+schilf-in-sel
+schilf-in-seln
+schlacht-hof-fa-brik
+schlacht-hof-fa-bri-ken
+schlaf-far-be
+schlaf-far-ben
+schlaf-la-bor-taug-lich
+schlaf-la-bor-taug-li-che
+schlaf-la-bor-taug-li-ches
+schlaf-tracht
+schlaf-trach-ten
+schlaf-trank
+schlaf-tran-kes
+schlaf-trieb
+schlaf-trie-be
+schlaf-trie-ben
+schlag-an-griff
+schlag-an-grif-fe
+schlag-an-grif-fen
+schlag-an-griffs
+schlag-emp-find-lich-keit
+schlag-emp-find-lich-kei-ten
+schlag-werk-ef-fekt
+schlag-werk-ef-fek-te
+schlag-werk-ef-fek-ten
+schlamm-ab-setz-ei-gen-schaft
+schlamm-ab-setz-ei-gen-schaf-ten
+schlamm-ufer-ge-sell-schaft
+schlamm-ufer-ge-sell-schaf-ten
+schleif-fleck
+schleif-fleck-lein
+schleif-lack
+schleif-la-cke
+schleif-la-cken
+schleif-lack-ehe-bett
+schleif-lack-rah-men
+schleif-lack-schlaf-zim-mer
+schleif-la-de
+schleif-la-den
+schleif-la-den-or-gel
+schleif-la-den-or-geln
+schleif-la-den-tech-nik
+schleif-la-den-or-ga-ni-sa-tion
+schlupf-lid
+schlupf-li-der
+schlupf-li-dern
+schmelz-ei-gen-schaft
+schmelz-ei-gen-schaf-ten
+schmelz-fluss-elek-tro-ly-se
+schmelz-tuff
+schmelz-tuf-fe
+schmelz-tuf-fen
+schmerz-un-emp-find-lich
+schmerz-un-emp-find-li-che
+schmerz-un-emp-find-li-chem
+schmerz-un-emp-find-li-chen
+schmerz-un-emp-find-li-cher
+schmerz-un-emp-find-li-ches
+schmerz-un-emp-find-lich-keit
+schmor-topf-le-gen
+schmug-gel-auf-trag
+schmug-gel-auf-tra-ges
+schmug-gel-auf-trags
+schmutz-un-emp-find-lich
+schmutz-un-emp-find-li-che
+schmutz-un-emp-find-li-chem
+schmutz-un-emp-find-li-chen
+schmutz-un-emp-find-li-cher
+schmutz-un-emp-find-li-ches
+schnell-an-griff
+schnell-an-grif-fe
+schnell-an-grif-fen
+schnell-an-griffs
+schnell-an-griffs-ein-rich-tung
+schnell-an-griffs-ein-rich-tun-gen
+schnell-an-griffs-schlauch
+schnell-an-griffs-schlau-ches
+schnell-an-griffs-schlauchs
+schnell-an-griffs-ta-sche
+schnell-an-griffs-ta-schen
+schnell-an-griffs-vor-rich-tung
+schnell-an-griffs-vor-rich-tun-gen
+schnitt-ef-fekt
+schnitt-ef-fek-te
+schnitt-ef-fek-ten
+schock-emp-find-lich-keit
+schock-emp-find-lich-kei-ten
+schopf-li-lie
+schopf-li-li-en
+schorn-stein-er-fin-dung
+schorn-stein-er-fin-dun-gen
+schreck-emp-fin-dung
+schreck-emp-fin-dun-gen
+schreib-tisch-auf-la-ge
+schreib-tisch-auf-la-gen
+schreib-tisch-wis-sen-schaft-ler
+schrift-akt
+schrift-ak-te
+schrift-ak-ten
+schrift-at-tri-but
+schrift-at-tri-bu-te
+schrift-at-tri-bu-ten
+schrift-er-fin-dung
+schrift-er-fin-dun-gen
+schrift-er-lass
+schrift-er-las-ses
+schrift-er-satz
+schrift-erz
+schrift-er-zen
+schrift-er-zeug-nis
+schrift-er-zeug-nis-se
+schrift-er-zeug-nis-sen
+schrift-er-zeug-nis-ses
+schrift-rat
+schrift-ra-tes
+schrift-raum
+schrift-rau-mes
+schrift-schei-be
+schrift-schei-ben
+schrift-sinn
+schrift-sin-ne
+schrift-sin-nen
+schrift-sinns
+schrift-sip-pe
+schrift-sip-pen
+schrift-stan-dard
+schrift-stan-dards
+schrift-um-set-zung
+schrift-um-set-zun-gen
+schrift-um-stel-lung
+schrift-um-stel-lun-gen
+schrumpf-licht
+schrumpf-lo-tion
+schul-hof-fa-schis-mus
+schutz-ei-gen-schaft
+schutz-ei-gen-schaf-ten
+schwarz-kopf-lift
+schwer-kraft-er-ken-nung
+schwert-fisch-ar-tig
+schwert-fisch-ar-ti-ge
+schwert-fisch-ar-ti-gem
+schwert-fisch-ar-ti-gen
+schwert-fisch-ar-ti-ger
+schwert-fisch-ar-ti-ges
+schwimm-eu-ro-pa-meis-ter-schaft
+schwimm-eu-ro-pa-meis-ter-schaf-ten
+see-ret-tungs-flug-zeug
+see-ret-tungs-flug-zeu-ge
+see-ret-tungs-flug-zeu-gen
+see-ret-tungs-flug-zeugs
+se-gel-aus-flug
+se-gel-aus-flu-ges
+se-gel-aus-flugs
+se-gel-auf-trieb
+se-gel-auf-trie-be
+se-gel-auf-trie-ben
+se-gel-auf-triebs
+se-gel-tref-fen
+se-gel-tref-fens
+seif-lap-pen
+selbst-an-griff
+selbst-an-grif-fe
+selbst-an-grif-fen
+selbst-an-griffs
+selbst-aus-wahl-ef-fekt
+selbst-aus-wahl-ef-fek-te
+selbst-iden-ti-fi-ka-ti-on
+selbst-iden-ti-fi-zie-rung
+selbst-iden-ti-fi-zie-run-gen
+selbst-of-fen-ba-rung
+selbst-of-fen-ba-run-gen
+senf-fa-brik
+senf-fa-bri-ken
+senf-far-be
+senf-far-ben
+senf-far-be-ne
+senf-far-big
+senf-far-bi-gen
+senf-feld
+senf-fel-der
+senf-fleck
+senf-fle-cken
+senf-fon-due
+senf-frucht
+senf-fuss-bad
+senf-la-den
+senf-le-ben
+senf-lieb-ha-ber
+se-sam-pflan-ze
+se-sam-pflan-zen
+shaftes-bury
+shuf-fle-rhyth-mus
+shuf-fle-rhyth-men
+sie-ges-in-schrift
+sie-ges-in-schrif-ten
+sil-ber-af-fe
+sil-ber-af-fen
+sig-nal-of-fi-zier
+sig-nal-of-fi-zie-re
+sig-nal-of-fi-zie-ren
+sig-nal-of-fi-ziers
+soft-ware-bau-stein
+soft-ware-bau-stei-ne
+soft-ware-bau-stei-nes
+soft-ware-ebe-ne
+soft-ware-hil-fe
+soft-ware-hil-fen
+soft-ware-hil-fe-grup-pe
+soft-ware-hil-fe-grup-pen
+soft-ware-in-stal-la-ti-on
+soft-ware-in-stal-la-tio-nen
+soft-ware-in-stal-la-tions-for-mat
+soft-ware-in-stal-la-tions-for-ma-te
+soft-ware-in-stal-la-tions-for-ma-ten
+soft-ware-in-stal-la-tions-for-ma-tes
+soft-ware-in-stal-la-tions-for-mats
+soft-ware-in-stal-la-tions-in-for-ma-ti-on
+soft-ware-in-stal-la-tions-in-for-ma-tio-nen
+soft-ware-schwach-stel-le
+soft-ware-schwach-stel-len
+soft-ware-trick
+soft-ware-tricks
+soft-ware-up-date
+soft-ware-up-dates
+sogne-fjord
+son-der-farb-ef-fekt
+son-der-farb-ef-fek-te
+son-der-farb-ef-fek-ten
+son-nen-schutz-ei-gen-schaft
+son-nen-schutz-ei-gen-schaf-ten
+spalt-ei-gen-schaft
+spalt-ei-gen-schaf-ten
+spei-cher-ei-gen-schaft
+spei-cher-ei-gen-schaf-ten
+speer-wurf-leis-tung
+sper-ma-fleck
+sper-ma-fle-cken
+sper-ma-flecks
+sperr-heft
+sperr-hef-te
+sperr-hef-ten
+spie-gel-ef-fekt
+spie-gel-ef-fek-te
+spie-gel-ef-fek-ten
+spie-ler-ge-mein-schaft
+spiel-film-ele-ment
+spiel-film-ele-men-te
+spiel-film-ele-men-ten
+spiel-film-er-folg
+spiel-film-er-fol-ge
+spiel-film-er-fol-gen
+spiel-film-er-folgs
+spiel-tref-fen
+spiel-tref-fens
+sprach-erb-schaft
+sprach-erb-schaf-ten
+sprach-er-fin-dung
+sprach-er-fin-dun-gen
+sprach-file
+sprach-iden-ti-fi-ka-ti-ons-sys-tem
+sprach-iden-ti-fi-ka-ti-ons-sys-te-me
+sprach-iden-ti-fi-ka-ti-ons-sys-te-men
+sprach-iden-ti-fi-ka-ti-ons-sys-tems
+spreng-stoff-art
+spreng-stoff-ar-ten
+spreng-stoff-ei-gen-schaft
+spreng-stoff-ei-gen-schaf-ten
+spreng-stoff-ein-zel-schrift
+spreng-stoff-ein-zel-schrif-ten
+spreng-stoff-spür-hund
+spreng-stoff-spür-hun-de
+spreng-stoff-spür-hun-den
+sprung-ei-gen-schaft
+sprung-ei-gen-schaf-ten
+sprung-schiff
+sprung-schif-fe
+sprung-schif-fen
+sprung-schiffs
+stadt-eil-treff
+stadt-eil-treffs
+stadt-teil-treff
+stadt-teil-treffs
+stamm-suf-fix
+stamm-suf-fixe
+stamm-suf-fi-xen
+stamm-tisch-tref-fen
+stamm-tisch-tref-fens
+stan-dard-an-flug-ver-fah-ren
+stan-dard-an-flug-ver-fah-rens
+stan-dard-raum-schiff
+stan-dard-raum-schif-fe
+stan-dard-raum-schif-fen
+stan-dard-raum-schiffs
+stan-dard-um-schrift
+stan-dard-um-schrif-ten
+stan-dard-impf-stoff
+stan-dard-impf-stof-fe
+stan-dard-impf-stof-fen
+stan-dard-impf-stoffs
+star-office
+start-ei-gen-schaft
+start-ei-gen-schaf-ten
+staub-auf-fang-be-reich
+staub-auf-fang-be-rei-che
+staub-auf-fang-be-rei-chen
+staub-auf-fang-be-rei-ches
+staub-auf-fang-be-reichs
+staub-auf-la-ge
+staub-auf-la-gen
+staub-ei-gen-schaft
+staub-ei-gen-schaf-ten
+staub-tuff
+staub-tuf-fe
+staub-tuf-fen
+steig-ei-gen-schaft
+steig-ei-gen-schaf-ten
+staub-emp-find-lich-keit
+staub-emp-find-lich-kei-ten
+stein-bruch-in-schrift
+stein-bruch-in-schrif-ten
+stell-auf-trag
+stell-auf-tra-ges
+stell-auf-trags
+steu-er-ei-gen-schaft
+steu-er-ei-gen-schaf-ten
+stick-stoff-ein-satz
+stick-stoff-ein-sat-zes
+stick-stoff-ein-trag
+stick-stoff-ein-tra-ges
+stick-stoff-em-bo-lie
+stick-stoff-em-bo-li-en
+stick-stoff-ent-fer-nung
+stick-stoff-ent-fer-nun-gen
+stick-stoff-ent-sor-gung
+stick-stoff-ent-sor-gun-gen
+stick-stoff-iso-top
+stick-stoff-iso-to-pe
+stick-stoff-stro-mes
+stift-akt
+stift-ak-te
+stift-an-ker-hem-mung
+stift-an-ker-hem-mun-gen
+stift-rad
+stift-ra-des
+stift-rui-ne
+stift-rui-nen
+stift-schei-be
+stift-schei-ben
+stoff-ab-zei-chen
+stoff-ab-zei-chen
+stoff-art
+stoff-ar-ten
+stoff-ar-ti-kel
+stoff-ar-ti-keln
+stoff-ar-ti-kels
+stoff-ei-gen-schaft
+stoff-ei-gen-schaf-ten
+stoff-ein-gren-zung
+stoff-ein-gren-zun-gen
+stoff-ein-la-ge-rung
+stoff-ein-la-ge-run-gen
+stoff-ein-trag
+stoff-ein-tra-ges
+stoff-ein-trags
+stoff-ele-fant
+stoff-ele-fan-ten
+stoff-ele-ment
+stoff-ele-men-te
+stoff-ele-men-ten
+stoff-ent-wurf
+stoff-ent-wur-fes
+stoff-ent-wurfs
+stoff-ent-zug
+stoff-ent-zu-ges
+stoff-er-hal-tung
+stoff-er-hal-tun-gen
+stoff-er-zeu-gung
+stoff-er-zeu-gun-gen
+stoff-iden-ti-fi-ka-ti-on
+stoff-ori-en-tie-rung
+stoff-ori-en-tie-run-gen
+stoff-sacks
+stoff-se-gel
+stoff-spei-che-rung
+stoff-spei-che-run-gen
+stoff-stro-mes
+stoff-strom-ana-ly-se
+stoff-strom-ana-ly-sen
+stoff-strom-dich-te
+stoff-strom-dich-ten
+stoff-strom-ma-nage-ment
+stoff-strom-ma-nage-ments
+stoff-strom-mo-dell
+stoff-strom-mo-del-le
+stoff-strom-mo-del-len
+stoff-strom-mo-dells
+stoff-strom-netz
+stoff-strom-net-ze
+stoff-strom-net-zen
+stoff-strom-net-zes
+stoff-strom-op-ti-mie-rung
+stoff-strom-op-ti-mie-run-gen
+stoff-strom-sys-tem
+stoff-strom-sys-te-me
+stoff-strom-sys-te-men
+stoff-strom-sys-tems
+stoff-strom-wirt-schaft
+stoff-strom-wirt-schaf-ten
+stoff-ther-mo-dy-na-mik
+stoff-ther-mo-dy-na-mi-ken
+stoff-uhr
+stoff-uh-ren
+stoff-ur-sa-che
+stoff-ur-sa-chen
+stoff-wech-sel-ano-ma-lie
+stoff-wech-sel-ano-ma-li-en
+stoff-wech-sel-ein-stel-lung
+stoff-wech-sel-ein-stel-lun-gen
+stoff-wech-sel-end-pro-dukt
+stoff-wech-sel-end-pro-duk-te
+stoff-wech-sel-end-pro-duk-ten
+stoff-wech-sel-end-pro-duk-tes
+stoff-wech-sel-zwi-schen-pro-dukt
+stoff-wech-sel-zwi-schen-pro-duk-te
+stoff-wech-sel-zwi-schen-pro-duk-ten
+stoff-wech-sel-zwi-schen-pro-duk-tes
+straf-in-sel
+straf-in-seln
+straf-in-stru-ment
+straf-in-stru-men-te
+straf-in-stru-men-ten
+straf-ta-xe
+straf-ta-xen
+straf-tref-fer
+straf-tref-fern
+straf-tref-fers
+straf-tri-bu-nal
+straf-tri-but
+straf-tri-bu-te
+straf-tri-bu-ten
+straf-wurf-li-nie
+straf-wurf-li-ni-en
+streif-la-cher
+streif-les-wald
+streit-stoff
+streit-stof-fe
+streit-stof-fen
+streit-stoffs
+strumpf-in-du-strie
+strumpf-in-du-stri-en
+strumpf-lied
+strumpf-lie-der
+strumpf-lie-des
+stuf-trot-tel
+stumpf-li-la
+sturz-an-griff
+sturz-an-grif-fe
+sturz-an-grif-fen
+sturz-an-griffs
+such-er-geb-nis-tref-fer
+such-er-geb-nis-tref-fers
+such-tref-fer
+such-tref-fern
+such-tref-fers
+suff-lot
+sul-fid-hal-tig
+sul-fid-hal-ti-ge
+sul-fid-hal-ti-gem
+sul-fid-hal-ti-gen
+sul-fid-hal-ti-ger
+sul-fid-hal-ti-ges
+sumpf-lab-kraut
+sumpf-la-by-rinth
+sumpf-la-che
+sumpf-la-chen
+sumpf-lan-ze
+sumpf-lan-zen
+sumpf-le-gen-de
+sumpf-le-gen-den
+sumpf-licht
+sumpf-lich-ter
+sumpf-lie-bend
+sumpf-lie-ben-de
+sumpf-lie-ben-dem
+sumpf-lie-ben-den
+sumpf-lie-ben-der
+sumpf-lie-ben-des
+sumpf-li-lie
+sumpf-li-li-en
+sumpf-tro-cken-le-gung
+sup-pen-duft-as-so-zia-ti-on
+sup-pen-duft-as-so-zia-tio-nen
+surf-la-den
+surf-le-gen-de
+surf-le-gen-den
+surf-lei-den-schaft
+surf-li-mit
+sys-tem-be-ein-flus-sung
+sys-tem-be-ein-flus-sun-gen
+sys-tem-ef-fi-zi-enz
+sys-tem-iden-ti-fi-ka-ti-on
+sys-tem-iden-ti-fi-ka-ti-ons-da-tei
+sys-tem-iden-ti-fi-ka-ti-ons-da-tei-en
+sys-tem-iden-ti-fi-zie-rung
+sys-tem-iden-ti-fi-zie-run-gen
+sys-tem-of-fi-zier
+sys-tem-of-fi-zie-re
+sys-tem-of-fi-ziers
+ta-ges-an-griff
+ta-ges-an-grif-fe
+ta-ges-an-grif-fes
+ta-ges-an-griffs
+ta-rif-in-for-ma-ti-on
+ta-rif-in-for-ma-ti-o-nen
+ta-rif-land-kar-te
+ta-rif-land-schaft
+ta-rif-land-schaf-ten
+ta-rif-las-ten
+tast-emp-fin-dung
+tast-emp-fin-dun-gen
+teil-an-griffs-ope-ra-ti-on
+teil-an-griffs-ope-ra-tio-nen
+teil-pflicht-ab-lie-fe-rung
+teil-pflicht-ab-lie-fe-run-gen
+te-le-aus-kunft
+te-le-fo-nie-flat-rate
+tem-pe-ra-tur-ei-gen-schaft
+tem-pe-ra-tur-ei-gen-schaf-ten
+tem-pe-ra-tur-fluk-tu-a-ti-on
+tem-pe-ra-tur-fluk-tu-a-tio-nen
+text-auf-lis-tung
+text-auf-lis-tun-gen
+text-heft
+text-hef-te
+text-hef-ten
+theo-rie-fleck
+theo-rie-fle-cken
+the-ra-pie-flan-kie-rend
+the-ra-pie-flan-kie-ren-de
+the-ra-pie-flan-kie-ren-derx
+thule-ge-sell-schaft
+tief-in-nen
+tief-in-ne-re
+tief-in-ne-res
+tief-in-ner-ste
+tief-in-ner-sten
+tief-in-ner-lich
+tief-in-ner-li-che
+tief-in-nig
+tief-in-ni-ge
+tief-in-ni-gen
+tief-lo-tend
+tief-lo-ten-de
+tief-lo-ten-den
+tief-lo-ten-der
+tief-luft-kurs
+tief-luft-kur-se
+tief-tank
+tief-tanks
+tief-traum
+tief-traum-pha-se
+tief-traum-pha-sen
+tier-er-schaf-fung
+tier-er-schaf-fun-gen
+tier-iden-ti-fi-ka-ti-on
+tier-impf-stoff
+tier-impf-stof-fe
+tier-impf-stof-fen
+tier-impf-stoffs
+tier-schau-flair
+ti-ger-an-griff
+ti-ger-an-grif-fe
+ti-ger-an-griffs
+tin-ten-fisch-art
+tin-ten-fisch-tin-te
+tin-ten-fisch-tin-ten
+toch-ter-stif-tung
+toch-ter-stif-tun-gen
+to-ma-ten-saft-at-ta-cke
+torf-lie-fe-rant
+ton-ef-fekt
+ton-ef-fek-te
+ton-ef-fek-ten
+ton-ef-fekts
+ton-film-ap-pa-rat
+ton-film-ap-pa-ra-te
+ton-film-ap-pa-ra-ten
+ton-film-auf-nah-me-ate-lier
+ton-film-auf-nah-me-ate-liers
+top-of-fi-zier
+top-of-fi-zie-re
+top-of-fi-zie-ren
+top-of-fi-zie-rin
+top-of-fi-ziers
+torf-tau-cher
+torf-tau-chern
+tou-ris-ten-fi-sche-rei-schein
+tou-ris-ten-fi-sche-rei-schei-ne
+tou-ris-ten-fi-sche-rei-schei-nen
+tou-ris-ten-fi-sche-rei-scheins
+tra-ge-kraft-sprit-ze
+tra-ge-kraft-sprit-zen
+trans-pa-zi-fik-dienst
+trans-pa-zi-fik-diens-tes
+trans-port-ei-gen-schaft
+trans-port-ei-gen-schaf-ten
+traum-ef-fekt
+traum-ef-fek-te
+traum-ef-fek-ten
+treff-ass
+treff-as-se
+treff-as-sen
+treib-stoff-art
+treib-stoff-ar-ten
+treib-stoff-ein-spa-rung
+treib-stoff-ein-spa-run-gen
+treib-stoff-ein-sprit-zung
+treib-stoff-ein-sprit-zun-gen
+treib-stoff-er-brauch
+treib-stoff-er-brau-chen
+treib-stoff-er-spar-nis
+treib-stoff-er-zeu-gung
+treib-stoff-er-zeu-gun-gen
+treib-stoff-im-puls
+treib-stoff-im-pul-se
+treib-stoff-im-pul-sen
+treib-stoff-sor-te
+treib-stoff-sor-ten
+treib-stoff-spei-cher
+treib-stoff-spei-chern
+treib-stoff-spei-chers
+trenn-ef-fekt
+trenn-ef-fek-te
+trenn-ef-fek-ten
+trenn-ef-fi-zi-enz
+trick-film-ein-lei-tung
+trick-film-ein-lei-tun-gen
+trick-film-ele-ment
+trick-film-ele-men-te
+trick-film-ele-men-ten
+trick-film-sketch
+trick-film-sket-che
+trick-film-sket-ches
+tritt-an-griff
+tritt-an-grif-fe
+tritt-an-grif-fen
+tritt-an-griffs
+tropf-le-cka-ge
+tropf-le-cka-gen
+tse-tse-flie-ge
+tse-tse-flie-gen
+tun-nel-ef-fekt
+tun-nel-ef-fek-te
+tun-nel-ef-fek-ten
+tu-sche-fleck
+tu-sche-flor
+ul-tra-kurz-zeit-ef-fekt
+ul-tra-kurz-zeit-ef-fek-te
+ul-tra-kurz-zeit-ef-fek-ten
+um-kehr-ef-fekt
+um-kehr-ef-fek-te
+um-kehr-ef-fek-ten
+uni-form-pflicht
+un-ter-flansch
+un-ter-flur-fracht-rau-mes
+un-ter-neh-mens-che-fin
+un-ter-neh-mens-pa-ten-schaft
+un-ter-neh-mens-pa-ten-schaf-ten
+va-ku-um-fluk-tu-a-ti-on
+va-ku-um-fluk-tu-a-tio-nen
+vam-pir-fle-der-maus
+va-ter-schafts-an-er-kennt-nis
+va-ter-schafts-an-er-ken-nung
+va-ter-schafts-an-er-ken-nun-gen
+ver-eins-fi-lia-le
+ver-eins-fi-lia-len
+ver-hal-tens-ei-gen-schaft
+ver-hal-tens-ei-gen-schaf-ten
+ver-kauf-the-ke
+ver-kauf-the-ken
+ver-kehrs-pro-fil
+ver-kehrs-pro-fi-le
+ver-kehrs-pro-fi-len
+ver-kehrs-pro-fils
+ver-nunft-ori-en-tiert
+ver-nunft-ori-en-tier-te
+ver-nunft-ori-en-tier-tes
+ver-sand-han-dels-che-fin
+ver-suchs-atom-kraft-werk
+ver-suchs-atom-kraft-wer-ke
+ver-suchs-atom-kraft-wer-ken
+ver-suchs-atom-kraft-werks
+ver-wandt-schafts-ta-fel
+ver-wand-schafts-ta-fel
+ver-wandt-schafts-typ
+ver-wandt-schafts-ty-pen
+ver-wandt-schafts-typs
+ver-wand-schafts-typ
+ver-wand-schafts-ty-pen
+ver-wand-schafts-typs
+vi-deo-file
+vi-deo-hor-ror-film
+vi-deo-hor-ror-fil-me
+vi-deo-hor-ror-fil-men
+vi-deo-hor-ror-films
+vi-ze-deck-of-fi-zier
+vi-ze-deck-of-fi-zie-re
+vi-ze-deck-of-fi-zie-ren
+vi-ze-deck-of-fi-ziers
+vor-bei-tref-fen
+vor-hof-fre-quenz
+vor-hof-fre-quen-zen
+vor-hof-funk-ti-on
+vor-hof-funk-tio-nen
+vor-hof-im-puls
+vor-hof-im-pul-se
+vor-hof-im-pul-sen
+vor-lauf-in-di-ka-tor
+vor-lauf-in-di-ka-to-ren
+vor-mon-sun-zeit
+vor-wurf-li-te-ra-tur
+vul-kan-tuff
+vul-kan-tuffs
+wach-of-fi-zier
+wach-of-fi-zie-re
+wach-of-fi-zie-ren
+wach-of-fi-ziers
+wachs-taft
+waf-fen-sys-tem-of-fi-zier
+waf-fen-sys-tem-of-fi-zie-re
+waf-fen-sys-tem-of-fi-zie-ren
+waf-fen-sys-tem-of-fi-ziers
+wahl-kampf-far-ce
+wahl-kampf-far-cen
+wahl-kampf-trick
+wahl-kampf-tricks
+wald-hof-fan
+wald-hof-fans
+wal-fang-schiff
+wal-fang-schif-fe
+wal-fang-schif-fen
+wal-fang-schiffs
+wa-ren-zwi-schen-fi-nan-zie-rung
+wa-ren-zwi-schen-fi-nan-zie-run-gen
+wasch-brett-ef-fekt
+wasch-brett-ef-fek-te
+wasch-ef-fekt
+wasch-ef-fek-te
+wasch-ef-fek-ten
+was-ser-af-fe
+was-ser-af-fen
+was-ser-af-fen-theo-rie
+was-ser-af-fen-theo-ri-en
+was-ser-ef-fekt
+was-ser-ef-fek-te
+was-ser-ef-fek-ten
+was-ser-fle-der-maus
+was-ser-kraft-er-zeu-gung
+was-ser-kraft-er-zeu-gun-gen
+was-ser-ski-lift
+was-ser-ski-lif-te
+was-ser-ski-lif-ten
+was-ser-stoff-chlo-rid
+was-ser-stoff-chlo-ri-de
+was-ser-stoff-chlo-ri-den
+was-ser-stoff-elek-tro-de
+was-ser-stoff-elek-tro-den
+was-ser-stoff-ent-wick-lung
+was-ser-stoff-ent-wick-lun-gen
+was-ser-stoff-er-zeu-gung
+was-ser-stoff-er-zeu-gun-gen
+was-ser-stoff-ion
+was-ser-stoff-io-nen
+was-ser-stoff-iso-top
+was-ser-stoff-iso-to-pe
+was-ser-stoff-iso-to-pen
+was-ser-stoff-spei-cher
+was-ser-stoff-spei-chern
+was-ser-stoff-spei-chers
+was-ser-stoff-spei-che-rung
+was-ser-stoff-spei-che-run-gen
+was-ser-stoff-spek-trum
+was-ser-stoff-spek-trums
+was-ser-stoff-stro-mes
+was-ser-stoff-sul-fid
+was-ser-stoff-sul-fi-de
+was-ser-stoff-sul-fi-den
+was-ser-stoff-uhr
+was-ser-stoff-uh-ren
+web-auf-tritt
+web-auf-trit-te
+web-auf-trit-ten
+web-auf-tritts
+web-schiff-chen
+web-schiff-chens
+wech-sel-ef-fekt
+weg-werf-la-sche
+weg-werf-la-schen
+weg-werf-lied
+weg-werf-lie-der
+weg-werf-li-te-ra-tur
+weg-werf-lo-gik
+weg-werf-tar-nung
+weg-werf-tar-nun-gen
+weih-in-schrift
+weih-in-schrif-ten
+wehr-pflicht-er-satz-ab-ga-be
+wehr-pflicht-er-satz-ab-ga-ben
+wein-bau-fleck
+wein-bau-fle-cken
+wein-berg-land-schaft
+wein-berg-land-schaf-ten
+welt-ener-gie-wirt-schaft
+welt-ener-gie-wirt-schaf-ten
+welt-meis-ter-schafts-tur-nier
+welt-meis-ter-schafts-tur-nie-re
+welt-meis-ter-schafts-tur-nie-ren
+welt-meis-ter-schafts-tur-niers
+welt-raum-ef-fekt
+welt-raum-ef-fek-te
+welt-raum-ef-fek-ten
+wer-be-per-si-fla-ge
+wer-be-per-si-fla-gen
+werk-auf-trag
+werk-auf-tra-ges
+werk-auf-trags
+werk-stoff-art
+werk-stoff-ar-ten
+werk-stoff-ei-gen-schaft
+werk-stoff-ei-gen-schaf-ten
+werk-stoff-ent-wick-lung
+werk-stoff-ent-wick-lun-gen
+werk-stoff-er-hal-tung
+werk-stoff-er-hal-tun-gen
+werk-stoff-spek-trum
+werk-stoff-spek-trums
+west-flan-dern
+west-flan-derns
+wett-kampf-ei-gen-schaft
+wett-kampf-ei-gen-schaf-ten
+wett-be-werbs-ef-fekt
+wett-be-werbs-ef-fek-te
+wett-be-werbs-ef-fek-ten
+wi-ckel-tisch-auf-la-ge
+wi-ckel-tisch-auf-la-gen
+wies-lauf-tal-ge-mein-de
+wi-kin-ger-an-griff
+wi-kin-ger-an-grif-fe
+wi-kin-ger-an-grif-fen
+wi-kin-ger-an-griffs
+wind-kes-sel-ef-fekt
+wind-kes-sel-ef-fek-te
+wind-kes-sel-ef-fek-ten
+wind-se-gel-ef-fekt
+wind-se-gel-ef-fek-te
+wind-se-gel-ef-fek-ten
+win-kel-ef-fekt
+win-kel-ef-fek-te
+wirt-schafts-abi-tur
+wirt-schafts-abi-tu-re
+wirt-schafts-abi-tu-ren
+wirt-schafts-ab-ord-nung
+wirt-schafts-ab-ord-nun-gen
+wirt-schafts-aris-to-kra-tie
+wirt-schafts-aris-to-kra-ti-en
+wirt-schafts-etat
+wirt-schafts-etats
+wirt-schafts-ini-ti-a-ti-ve
+wirt-schafts-ini-ti-a-ti-ven
+wirt-schafts-oli-gar-chie
+wirt-schafts-oli-gar-chi-en
+wirt-schafts-tor
+wirt-schafts-to-re
+wirt-schafts-to-ren
+wirt-schafts-trend
+wirt-schafts-trends
+wirt-schafts-tier
+wirt-schafts-tie-re
+wirt-schafts-tie-ren
+wirt-schafts-tie-res
+wirt-schafts-trup-pe
+wirt-schafts-trup-pen
+wirt-schafts-typ
+wirt-schafts-ty-pen
+wirt-schafts-typs
+wis-sen-schafts-team
+wis-sen-schafts-teams
+wis-sen-schafts-tra-di-ti-on
+wis-sen-schafts-tra-di-tio-nen
+wis-sen-schafts-turm
+wis-sens-iden-ti-fi-ka-ti-on
+wolf-last
+wolf-the-ma
+woll-af-fe
+woll-af-fen
+woll-af-fen-halb-in-sel
+woll-af-fen-halb-in-seln
+woll-af-ter
+woll-af-ters
+woll-stone-craft
+wer-wolf-the-ma-tik
+wort-ei-gen-schaft
+wort-ei-gen-schaf-ten
+wort-klas-sen-suf-fix
+wort-klas-sen-suf-fi-xe
+wort-klas-sen-suf-fi-xen
+wort-ste-no-gra-fie
+wort-ste-no-gra-fi-en
+wort-suf-fix
+wort-suf-fi-xe
+wort-suf-fi-xen
+wulff
+wulffs
+wun-der-af-fe
+wun-der-af-fen
+wun-der-floh
+wun-der-flo-hes
+wurf-lau-ne
+wurf-lan-ze
+wurf-lan-zen
+wurf-leis-tung
+wurf-leis-tun-gen
+wurf-li-nie
+wurf-li-ni-en
+wurf-re-flex
+wurf-re-fle-xe
+wurf-re-fle-xen
+wurf-re-fle-xes
+zahn-fleisch-an-teil
+zahn-fleisch-an-tei-le
+zahn-fleisch-an-tei-len
+zahn-fleisch-an-teils
+zahn-fleisch-auf-la-ge
+zahn-fleisch-auf-la-gen
+zahn-fleisch-re-sek-ti-on
+zapf-loch
+zapf-lo-ches
+zapf-lochs
+zapf-luft
+zapf-luft-sys-tem
+zapf-luft-sys-tems
+zei-chen-be-darf-la-den
+zei-chen-trick-film-adap-ta-ti-on
+zei-chen-trick-film-adap-ta-tio-nen
+zeit-ef-fi-zi-ent
+zeit-ef-fi-zi-en-te
+zeit-ef-fi-zi-en-tem
+zeit-ef-fi-zi-en-ten
+zeit-ef-fi-zi-en-ter
+zeit-ef-fi-zi-en-tes
+zeit-ef-fi-zi-enz
+zeit-emp-fin-den
+zeit-emp-fin-dens
+zeit-emp-fin-dung
+zeit-emp-fin-dun-gen
+zeit-re-fle-xi-on
+zeit-re-fle-xio-nen
+zeit-schif-ten-abon-ne-ment
+zell-af-ter
+zell-af-ters
+zell-stoff-er-zeu-gung
+zell-stoff-er-zeu-gun-gen
+zell-stoff-sor-te
+zell-stoff-sor-ten
+zen-tral-ak-ti-en-ge-sell-schaft
+zen-tral-ak-ti-en-ge-sell-schaf-ten
+zen-tral-flo-ri-da
+zen-tral-flo-ri-das
+zer-rau-fen
+zer-rauft
+zie-gel-hof-teich
+zie-gel-hof-tei-che
+zie-gel-hof-tei-chen
+ziel-iden-ti-fi-zie-rung
+ziel-iden-ti-fi-zie-run-gen
+ziel-in-dif-fe-renz
+zier-af-fe
+zier-af-fen
+zier-schrift
+zier-schif-ten
+zi-vil-flag-ge
+zi-vil-flag-gen
+zoll-schiff-sta-ti-on
+zoll-schiff-sta-tio-nen
+zu-cker-raf-fi-na-de
+zu-cker-raf-fi-ne-rie
+zu-cker-raf-fi-ne-ri-en
+zu-falls-ein-fluss
+zu-falls-ein-flus-ses
+zu-falls-er-fin-dung
+zu-falls-er-fin-dun-gen
+zug-aus-kunft
+zug-of-fi-zier
+zug-of-fi-zie-re
+zug-of-fi-ziers
+zu-griffs-in-for-ma-ti-on
+zu-griffs-in-for-ma-tio-nen
+zu-griffs-ma-kro
+zu-griffs-ma-kros
+zu-kunfts-taug-lich-keit
+zu-kunfts-uto-pie
+zu-kunfts-uto-pi-en
+zunft-ord-nung
+zunft-ord-nun-gen
+zupf-fest
+zupf-fes-te
+zupf-fes-ten
+zupf-lei-er
+zu-satz-ei-gen-schaft
+zu-satz-ei-gen-schaf-ten
+zu-satz-er-fin-dung
+zu-satz-er-fin-dun-gen
+zu-stands-haf-tung
+zu-stands-haf-tun-gen
+zu-stell-an-schrift
+zu-stell-an-schrif-ten
+zwei-blatt-luft-schrau-ben
+zwei-blatt-luft-schrau-bens
+zwei-fluss-land
+zwei-fluss-lan-des
+zwei-flu-tig
+zwei-kraft-lo-ko-mo-ti-ve
+zwei-kraft-lo-ko-mo-ti-ven
+zwei-kraft-trak-tor
+zwei-kraft-trak-to-ren
+zwei-kraft-trak-tors
+zwei-rad-dampf-fre-gat-te
+zwei-rad-dampf-fre-gat-ten
+zwei-weg-ef-fekt
+zwei-weg-ef-fek-te
+zwei-weg-ef-fek-ten
+zwerg-tin-ten-fisch
+zwerg-tin-ten-fi-sche
+zwerg-tin-ten-fi-schen
+zwerg-tin-ten-fischs
+}
+
+\ifluatex % words containing umlauts and ß characters...
+\hyphenation{
+ab-fluss-öff-nung
+ab-fluss-öff-nun-gen
+ab-hol-auf-trä-ge
+ab-hol-auf-trä-gen
+ab-lass-öff-nung
+ab-lass-öff-nun-gen
+ab-lauf-län-ge
+ab-lauf-län-gen
+ab-tast-öff-nung
+ab-tast-öff-nun-gen
+ab-tau-flüs-sig-keit
+ab-tau-flüs-sig-kei-ten
+acker-bau-flä-che
+acker-bau-flä-chen
+ak-kre-di-tiv-er-öff-nung
+ak-kre-di-tiv-er-öff-nun-gen
+alu-tritt-flä-che
+alu-tritt-flä-chen
+an-bau-flä-chen-er-mitt-lung
+an-bau-flä-chen-er-mitt-lun-gen
+an-bau-pflü-ge
+an-bau-pflü-gen
+an-den-ken-ge-schäft
+an-den-ken-ge-schäf-te
+an-den-ken-ge-schäf-tes
+an-den-ken-ge-schäfts
+an-gel-aus-flü-ge
+an-gel-aus-flü-gen
+an-lauf-län-ge
+an-lauf-län-gen
+an-griffs-in-ten-si-tät
+äqui-va-lenz-ei-gen-schaft
+äqui-va-lenz-ei-gen-schaf-ten
+ar-beits-kräf-te-er-he-bung
+ar-beits-kräf-te-er-he-bun-gen
+ar-sen-sau-er-stoff-säu-re
+ar-sen-sau-er-stoff-säu-ren
+arz-nei-trä-ger-stoff
+arz-nei-trä-ger-stof-fe
+arz-nei-trä-ger-stof-fen
+arz-nei-trä-ger-stoffs
+atem-öff-nung
+atem-öff-nun-gen
+atom-ober-fläche
+atom-ober-flä-chen
+auf-fang-sä-cke
+auf-fang-sä-cken
+auf-fang-säck-chen
+auf-fang-säck-chens
+auf-lö-sungs-chart
+auf-lö-sungs-charts
+auf-tau-flüs-sig-keit
+auf-tau-flüs-sig-kei-ten
+auf-triebs-än-de-rung
+auf-triebs-än-de-run-gen
+auf-tritts-tä-tig-keit
+auf-tritts-tä-tig-kei-ten
+au-gust-ein-künf-te
+au-gust-ein-künf-ten
+aus-fluss-öff-nung
+aus-fluss-öff-nun-gen
+aus-puff-ähn-lich
+aus-puff-ähn-li-che
+aus-puff-ähn-li-chem
+aus-puff-län-ge
+aus-puff-län-gen
+aus-puff-lärm
+aus-schuss-öff-nung
+aus-schuss-öff-nun-gen
+aus-zu-lüf-ten
+bahn-er-öff-nung
+bahn-er-öff-nun-gen
+bahn-hof-frei-ge-län-de
+bahn-nei-gungs-flü-ge
+bahn-nei-gungs-flü-gen
+bahn-ober-flä-che
+bahn-ober-flä-chen
+bahn-steig-ober-flä-che
+bahn-steig-ober-flä-chen
+bal-lon-ober-flä-che
+bal-lon-ober-flä-chen
+bat-te-rie-flüs-sig-keit
+bat-te-rie-flüs-sig-kei-ten
+bauch-ober-flä-che
+bauch-ober-flä-chen
+bauch-öff-nung
+bauch-öff-nun-gen
+bau-ern-hof-lö-sung
+bau-ern-hof-lö-sun-gen
+bau-flucht-li-ni-en-plä-ne
+bau-flucht-li-ni-en-plä-nen
+bau-markt-er-öff-nung
+bau-markt-er-öff-nun-gen
+baum-woll-stoff-stück
+baum-woll-stoff-stü-cke
+baum-woll-stoff-stü-cken
+baum-woll-stoff-stücks
+bau-teil-ober-flä-che
+bau-teil-ober-flä-chen
+be-druck-stoff-ober-flä-che
+be-griffs-iden-ti-tät
+be-griffs-iden-ti-tä-ten
+berg-aus-flü-ge
+berg-aus-flü-gen
+berg-ober-flä-che
+berg-ober-flä-chen
+be-ton-ober-flä-che
+be-ton-ober-flä-chen
+be-triebs-sys-tem-ober-flä-che
+be-triebs-sys-tem-ober-flä-chen
+be-völ-ke-rungs-fluk-tu-a-ti-on
+be-völ-ke-rungs-fluk-tu-a-tio-nen
+bild-ober-flä-che
+bild-ober-flä-chen
+bio-top-flä-che
+bio-top-flä-chen
+bio-top-flä-chen-fak-tor
+bio-top-flä-chen-fak-to-ren
+bio-top-flä-chen-fak-tors
+bild-schirm-ober-flä-che
+bild-schirm-ober-flä-chen
+blatt-hälf-te
+blatt-hälf-ten
+blatt-ober-flä-che
+blatt-ober-flä-chen
+blut-ei-weiß-stoff
+blut-ei-weiß-stof-fe
+blut-ei-weiß-stof-fen
+blut-ei-weiß-stoffs
+blut-ober-flä-che
+blut-ober-flä-chen
+brems-ent-lüf-tung
+brems-ent-lüf-tun-gen
+brenn-raum-ober-flä-che
+brenn-raum-ober-flä-chen
+brenn-stoff-er-gän-zung
+brenn-stoff-er-gän-zun-gen
+brot-ober-flä-che
+brot-ober-flä-chen
+bruch-ober-flä-che
+bruch-ober-flä-chen
+brü-cken-er-öff-nung
+brü-cken-er-öff-nun-gen
+brust-bein-hälf-te
+brust-bein-hälf-ten
+bü-gel-ef-fekt
+bü-gel-ef-fek-te
+bü-gel-ei-sen-griff
+bü-gel-ei-sen-grif-fe
+bü-gel-ei-sen-grif-fen
+bü-gel-ski-lift
+bü-gel-ski-lif-te
+bü-gel-ski-lif-ten
+bun-des-platz-er-öff-nung
+bun-des-platz-er-öff-nun-gen
+büh-nen-ge-nos-sen-schaft
+büh-nen-ge-nos-sen-schaf-ten
+bun-des-wehr-af-fä-re
+bun-des-wehr-af-fä-ren
+burg-in-nen-flä-che
+burg-in-nen-flä-chen
+burg-see-flü-gel
+burg-see-flü-geln
+burg-see-flü-gels
+bü-ro-fach-ge-schäft
+bü-ro-fach-ge-schäf-te
+bü-ro-fach-ge-schäf-ten
+bü-ro-fach-ge-schäf-tes
+bü-ro-fach-ge-schäfts
+bü-ro-flur
+bü-ro-flu-re
+bü-ro-flu-ren
+cam-ping-aus-flü-ge
+cam-ping-aus-flü-gen
+chef-in-nen-räu-me
+chip-auf-lö-sung
+chip-auf-lö-sun-gen
+com-pu-ter-af-fi-ni-tät
+com-pu-ter-af-fi-ni-tä-ten
+darm-ober-flä-che
+darm-ober-flä-chen
+da-ten-trä-ger-ober-flä-che
+da-ten-trä-ger-ober-flä-chen
+dau-er-stau-flä-che
+dau-er-stau-flä-chen
+de-ckel-öff-nung
+de-ckel-öff-nun-gen
+deck-ober-flä-che
+deck-ober-flä-chen
+del-ta-flü-gel
+del-ta-flü-geln
+del-ta-flü-gels
+de-sign-för-der-ge-mein-schaft
+de-sign-för-der-ge-mein-schaf-ten
+dis-ket-ten-zu-griff-lämp-chen
+dis-ket-ten-zu-griff-lämp-chens
+duft-öl
+duft-öle
+duft-stäb-chen
+duft-stäb-chens
+dünn-saft
+dünn-saf-tes
+dürr-fle-cken-krank-heit
+durch-fluss-öff-nung
+durch-fluss-öff-nun-gen
+ef-fi-zi-enz-er-hö-hung
+ef-fi-zi-enz-er-hö-hun-gen
+ein-falls-öff-nung
+ein-füll-öff-nung
+ein-füll-öff-nun-gen
+ein-lass-öff-nung
+ein-lass-öff-nun-gen
+ein-satz-öff-nung
+ein-satz-öff-nun-gen
+en-ten-flü-gel
+en-ten-flü-geln
+en-ten-flü-gels
+en-ten-kä-fig
+en-ten-kä-fi-ge
+en-ten-kä-fi-gen
+en-ten-kä-figs
+ei-lei-ter-öff-nung
+ei-lei-ter-öff-nun-gen
+ein-füll-öff-nung
+ein-füll-öff-nun-gen
+ein-griffs-in-ten-si-tät
+ein-griffs-in-ten-si-tä-ten
+ein-lass-öff-nung
+ein-lass-öff-nun-gen
+ein-zel-trag-flä-che
+ein-zel-trag-flä-chen
+elek-tro-fach-ge-schäft
+elek-tro-fach-ge-schäf-te
+elek-tro-fach-ge-schäf-ten
+elek-tro-fach-ge-schäf-tes
+elek-tro-fach-ge-schäfts
+elek-tro-fach-ge-schäfts-füh-rer
+elek-tro-fach-ge-schäfts-füh-rern
+elek-tro-fach-ge-schäfts-füh-rers
+emp-fän-ger-an-schrift
+emp-fän-ger-an-schrif-ten
+end-an-flü-ge
+end-an-flü-gen
+er-öff-nungs-din-ner
+erst-er-öff-nung
+erst-er-öff-nun-gen
+erst-öff-nung
+erst-öff-nun-gen
+erst-über-schrift
+erst-über-schrif-ten
+fa-brik-er-öff-nung
+fa-brik-er-öff-nun-gen
+fä-cher-öff-nung
+fä-cher-öff-nun-gen
+fahr-bahn-ober-flä-che
+fahr-bahn-ober-flä-chen
+fähr-schiff-ree-der
+fahr-zeug-ober-flä-che
+fahr-zeug-ober-flä-chen
+fal-ter-flü-gel
+fal-ter-flü-geln
+farb-ober-flä-che
+farb-ober-flä-chen
+farb-über-fluss
+farb-über-flus-ses
+fa-ser-end-flä-che
+fa-ser-end-flä-chen
+fehl-öff-nung
+fehl-öff-nun-gen
+fels-öff-nung
+fels-öff-nun-gen
+fest-er-öff-nung
+fest-er-öff-nun-gen
+fest-stoff-ober-stu-fe
+fest-stoff-ober-stu-fen
+feu-er-er-öff-nung
+feu-er-er-öff-nun-gen
+feu-er-er-öff-nungs-li-nie
+feu-er-er-öff-nungs-li-ni-en
+fi-let-hä-ke-lei
+fi-li-gran-glä-ser
+fi-li-gran-glä-sern
+film-an-kün-di-gung
+film-an-kün-di-gun-gen
+film-ärz-te
+film-ärz-ten
+film-äs-the-tik
+film-äs-the-ti-ken
+film-äs-the-tisch
+film-äs-the-ti-sche
+film-äs-the-ti-schem
+film-äs-the-ti-schen
+film-äs-the-ti-scher
+film-äs-the-ti-sches
+film-ein-trä-ge
+film-ein-trä-gen
+film-ent-wür-fe
+film-ent-wür-fen
+film-en-zy-klo-pä-die
+film-en-zy-klo-pä-di-en
+film-er-lös
+film-er-lö-se
+film-er-lö-sen
+film-ober-flä-che
+film-ober-flä-chen
+film-öf-fent-lich-keit
+film-öf-fent-lich-kei-ten
+film-uni-ver-si-tät
+film-uni-ver-si-tä-ten
+film-vor-führ-ap-pa-rat
+film-vor-führ-ap-pa-ra-te
+film-vor-führ-ap-pa-ra-ten
+film-vor-führ-ap-pa-ra-tes
+fil-ter-füh-rung
+fil-ter-füh-run-gen
+fil-ter-fül-lung
+fil-ter-fül-lun-gen
+fi-nanz-än-de-rungs-ge-setz
+fi-nanz-än-de-rungs-ge-set-ze
+fi-nanz-än-de-rungs-ge-set-zen
+fi-nanz-än-de-rungs-ge-set-zes
+fi-nanz-öko-nom
+fi-nanz-öko-no-men
+fi-nanz-öko-no-mens
+fi-nanz-öko-no-mie
+fi-nanz-öko-no-mie-en
+fi-nanz-pfrün-de
+fi-nanz-pfrün-den
+fin-ger-stoß
+fin-ger-sto-ßes
+fisch-auf-läu-fe
+fi-sche-rei-ge-rät
+fi-sche-rei-ge-rä-te
+fi-sche-rei-ge-rä-ten
+fisch-öko-lo-gie
+fisch-öle
+fisch-ölen
+fisch-öls
+fisch-schwanz-ähn-lich
+fisch-schwanz-ähn-li-che
+fisch-schwanz-ähn-li-chem
+fisch-schwanz-ähn-li-chen
+fisch-schwanz-ähn-li-cher
+fisch-schwanz-ähn-li-ches
+fisch-über-rest
+fisch-über-res-te
+fisch-über-res-ten
+fisch-über-res-tes
+fjord-ähn-lich
+fjord-ähn-li-che
+fjord-ähn-li-chen
+flä-chen-drai-na-ge
+flä-chen-drai-na-gen
+flä-chen-ero-si-on
+flä-chen-ero-sio-nen
+flä-chen-or-na-ment
+flä-chen-or-na-men-te
+flä-chen-or-na-men-ten
+flä-chen-ta-rif-land-schaft
+fla-schen-er-näh-rung
+fla-schen-er-näh-run-gen
+fleisch-an-sät-ze
+fleisch-an-sät-zen
+fleisch-an-satz-ver-mö-gen
+fleisch-an-satz-ver-mö-gens
+fleisch-auf-läu-fe
+fleisch-ober-flä-che
+fleisch-ober-flä-chen
+fleisch-über-rest
+fleisch-über-res-te
+fleisch-über-res-ten
+fleisch-wöl-fe
+fleisch-wöl-fen
+fleisch-wür-fel
+fleisch-wür-feln
+fleisch-wür-mer
+fleisch-wür-mern
+fleisch-würst-chen
+fleisch-würst-chens
+fleisch-würs-te
+fleisch-würs-ten
+flie-ger-atem-ge-rät
+flie-ger-atem-ge-rä-te
+flie-ger-atem-ge-rä-ten
+fließ-kom-ma-arith-me-tik
+fließ-quel-le
+fließ-quel-len
+fließ-quer-schnitt
+fließ-quer-schnit-te
+fließ-quer-schnit-ten
+fließ-quer-schnitts
+flücht-lings-ini-ti-a-ti-ve
+flücht-lings-ini-ti-a-ti-ven
+flücht-lings-rück-strom
+flücht-lings-rück-stro-mes
+flücht-lings-tross
+flücht-lings-tros-se
+flücht-lings-tros-sen
+flü-gel-ach-se
+flü-gel-ach-sen
+flü-gel-ader
+flü-gel-adern
+flü-gel-ad-ju-tant
+flü-gel-äh-ren-fisch
+flü-gel-äh-ren-fi-sche
+flü-gel-äh-ren-fi-schen
+flü-gel-är-mel
+flü-gel-är-mels
+flü-gel-auf-bau
+flü-gel-auf-bau-es
+flü-gel-auf-baus
+flü-gel-au-ßen-teil
+flü-gel-au-ßen-tei-le
+flü-gel-au-ßen-tei-len
+flü-gel-dam-mes
+flü-gel-eg-ge
+flü-gel-eg-gen
+flü-gel-en-de
+flü-gel-en-den
+flü-gel-en-des
+flü-gel-end-tank
+flü-gel-end-tanks
+flü-gel-frucht
+flü-gel-haupt-holm
+flü-gel-haupt-hol-me
+flü-gel-haupt-hol-men
+flü-gel-in-nen-sei-te
+flü-gel-in-nen-sei-ten
+flü-gel-kak-tus
+flü-gel-ske-lett
+flü-gel-ske-let-te
+flü-gel-ske-let-ten
+flü-gel-ske-letts
+flü-gel-ober-flä-che
+flü-gel-ober-flä-chen
+flü-gel-ober-sei-te
+flü-gel-ober-sei-ten
+flü-gel-schlag-ap-pa-rat
+flü-gel-schlag-ap-pa-ra-te
+flü-gel-schlag-ap-pa-ra-ten
+flü-gel-schlag-ap-pa-ra-tes
+flü-gel-trakt
+flü-gel-trak-te
+flü-gel-trak-ten
+flü-gel-trep-pe
+flü-gel-trep-pen
+flug-ha-fen-er-öff-nung
+flug-ha-fen-er-öff-nun-gen
+flug-kör-per-ach-se
+flug-kör-per-ach-sen
+flug-platz-un-glück
+flug-platz-un-glü-cke
+flug-platz-un-glü-cken
+flug-platz-un-glücks
+flug-sand-an-hö-he
+flug-sand-an-hö-hen
+flug-sand-de-cke
+flug-sand-de-cken
+flug-sand-dü-ne
+flug-sand-dü-nen
+flug-sand-flä-che
+flug-sand-flä-chen
+flug-sta-bi-li-tät
+flug-sta-bi-li-tä-ten
+flu-or-was-ser-stoff-säu-re
+flur-zäu-ne
+flur-zäu-nen
+fluss-än-de-rung
+fluss-än-de-run-gen
+fluss-ein-mün-dung
+fluss-ein-mün-dun-gen
+flüs-sig-drach-me
+flüs-sig-drach-men
+flüs-sig-dün-ger
+flüs-sig-dün-gern
+flüs-sig-ein-satz
+flüs-sig-ein-sat-zes
+flüs-sig-ein-spei-sung
+flüs-sig-ein-spei-sun-gen
+flüs-sig-erd-gas
+flüs-sig-erd-ga-se
+flüs-sig-erd-ga-sen
+flüs-sig-gas-was-ser-stoff-spei-che-rung
+flüs-sig-gas-was-ser-stoff-spei-che-run-gen
+flüs-sig-keits-ra-ke-ten-trieb-werk
+flüs-sig-keits-ra-ke-ten-trieb-wer-ke
+flüs-sig-keits-ra-ke-ten-trieb-wer-ken
+flüs-sig-keits-ra-ke-ten-trieb-werks
+flüs-sig-keits-tren-nung
+flüs-sig-keits-tren-nun-gen
+flüs-sig-la-tex
+flüs-sig-nah-rung
+flüs-sig-nah-run-gen
+flüs-sig-ra-ke-te
+flüs-sig-ra-ke-ten
+flüs-sig-rauch
+flüs-sig-rau-chen
+flüs-sig-raum
+flüs-sig-rau-mes
+flüs-sig-skru-pel
+flüs-sig-stahl
+flüs-sig-stick-stoff-küh-lung
+flüs-sig-stick-stoff-küh-lun-gen
+flüs-sig-stoff
+flüs-sig-stof-fe
+flüs-sig-stof-fen
+flüs-sig-stoffs
+flüs-sig-keits-tank
+flüs-sig-treib-stoff-ra-ke-ten-trieb-werk
+flüs-sig-treib-stoff-ra-ke-ten-trieb-wer-ke
+flüs-sig-treib-stoff-ra-ke-ten-trieb-wer-ken
+flüs-sig-treib-stoff-ra-ke-ten-trieb-werks
+flüs-sig-un-ze
+flüs-sig-un-zen
+flüs-sig-was-ser-stoff-spei-che-rung
+flüs-sig-was-ser-stoff-spei-che-run-gen
+fluss-lauf-än-de-rung
+fluss-lauf-än-de-run-gen
+flut-er-zäh-lung
+flut-er-zäh-lun-gen
+för-der-ef-fekt
+för-der-ef-fek-te
+för-der-ef-fek-ten
+för-der-ef-fi-zienz
+frucht-fleisch-wür-fel
+frucht-fleisch-wür-feln
+früh-fluk-tu-a-ti-on
+früh-fluk-tu-a-tio-nen
+füll-öff-nung
+füll-öff-nun-gen
+füh-rungs-kräfte-aus-bil-dung
+füh-rungs-kräfte-aus-bil-dun-gen
+füh-rungs-kräfte-ent-wick-lung
+füh-rungs-kräfte-ent-wick-lun-gen
+fünf-la-gig
+fünf-la-gi-ge
+fünf-la-gi-gem
+fünf-län-der
+fünf-län-der-kampf
+fünf-lap-pig
+fünf-lap-pi-ge
+fünf-lap-pi-gen
+fünf-läp-pig
+fünf-läp-pi-gen
+fünf-lei-ten
+fünf-lei-ter-netz
+fünf-lei-ter-net-ze
+fünf-lei-ter-net-zen
+fünf-lei-ter-net-zes
+fünf-li-ter
+fünf-li-tern
+fünf-li-ters
+fünf-li-ter-au-to
+fünf-li-ter-au-tos
+fünf-li-ter-be-hält-nis
+fünf-li-ter-fla-sche
+fünf-li-ter-fla-schen
+fünf-li-ter-ka-nis-ter
+fünf-lit-ri-gen
+fünf-lit-ri-ges
+fünf-loch-dü-sen
+fünf-löch-rig
+fünf-löch-ri-ges
+fuß-ende
+fuß-enden
+fuß-un-ter-flä-che
+fuß-un-ter-flä-chen
+ge-bäu-de-iden-ti-fi-ka-ti-ons-num-mer
+ge-bäu-de-iden-ti-fi-ka-ti-ons-num-mern
+ge-flü-gel-auf-schnitt
+ge-flü-gel-auf-schnit-te
+ge-flü-gel-auf-schnitts
+ge-flü-gel-auf-zucht
+ge-flü-gel-auf-zuch-ten
+ge-flü-gel-ein-la-ge
+ge-flü-gel-ein-la-gen
+ge-flü-gel-er-zeug-nis
+ge-flü-gel-er-zeug-nis-se
+ge-flü-gel-er-zeug-nis-sen
+ge-flü-gel-er-zeug-nis-ses
+ge-flü-gel-tu-ber-ku-lo-se
+ge-hirn-ober-flä-che
+ge-hirn-ober-flä-chen
+geis-ter-af-fä-re
+geis-ter-af-fä-ren
+geld-rück-fluss
+geld-rück-flus-ses
+ge-mein-schafts-chö-re
+ge-mein-schafts-cho-ren
+ge-mein-schafts-phä-no-men
+ge-mein-schafts-phä-no-me-ne
+ge-mein-schafts-phä-no-me-nen
+ge-mein-schafts-phä-no-mens
+ge-mein-schafts-tü-cher
+ge-mein-schafts-tü-chern
+ge-mein-schafts-wasch-räu-me
+ge-mü-se-löf-fel
+ge-mü-se-löf-feln
+ge-mü-se-löf-fels
+geo-gra-fie-fa-kul-tät
+geo-gra-fie-fa-kul-tä-ten
+ge-räusch-ef-fekt
+ge-räusch-ef-fek-te
+ge-räusch-ef-fek-ten
+ge-samt-se-gel-flä-che
+ge-samt-se-gel-flä-chen
+ge-samt-bio-top-flä-che
+ge-samt-bio-top-flä-chen
+ge-samt-ober-flä-che
+ge-samt-ober-flä-chen
+ge-schäf-te-hal-ber
+ge-schäfts-ord-nungs-ter-ror
+ge-schäfts-ord-nungs-ter-rors
+ge-schäfts-ta-lent
+ge-schäfts-ta-len-te
+ge-schäfts-ta-len-ten
+ge-schäfts-ta-lents
+ge-schäfts-trick
+ge-schäfts-tricks
+gieß-öff-nung
+gieß-öff-nun-gen
+gift-gas-ein-sät-ze
+gift-gas-ein-sät-zen
+gift-gas-ein-sät-zes
+gift-gas-un-glück
+gift-gas-un-glü-cke
+gift-gas-un-glü-cken
+gift-gas-un-glücks
+gift-stän-gel
+gift-stän-geln
+gift-stän-gels
+gla-sur-ober-flä-che
+glüh-ef-fekt
+glüh-ef-fek-te
+glüh-ef-fek-ten
+gold-kopf-lö-wen-äff-chen
+gold-kopf-lö-wen-äff-chens
+gold-ober-flä-che
+gold-ober-flä-chen
+golf-län-der
+golf-län-dern
+golf-lät-ze
+golf-lek-tü-re
+golf-träu-me
+gra-fik-ab-zü-ge
+gra-fik-ab-zü-gen
+gra-fik-än-de-rung
+gra-fik-än-de-run-gen
+gra-fik-de-sign-bü-cher
+gra-fik-de-sign-bü-chern
+gra-fik-lö-sung
+gra-fik-lö-sun-gen
+gra-fik-qua-li-tät
+gra-fik-qua-li-tä-ten
+grenz-er-trags-flä-che
+grenz-er-trags-flä-chen
+grenz-flä-chen-ener-gie
+grenz-flä-chen-ener-gi-en
+griff-lü-cke
+griff-lü-cken
+griff-stück
+griff-stü-cke
+griff-stü-cken
+griff-stücks
+groß-kunst-stoff-ar-ti-kel
+groß-kunst-stoff-ar-ti-keln
+groß-kunst-stoff-ar-ti-kels
+groß-schrift-tas-ta-tur
+groß-schrift-tas-ta-tu-ren
+grund-er-öff-nung
+grund-er-öff-nun-gen
+grund-mit-tel-ef-fek-ti-vi-tät
+grund-mit-tel-ef-fek-ti-vi-tä-ten
+gum-mi-ober-flä-che
+gum-mi-ober-flä-chen
+grund-zu-stands-fluk-tu-a-ti-oin
+gru-sel-film-er-folg
+gru-sel-film-er-fol-ge
+gru-sel-film-er-fol-gen
+gschaftl-hu-ber
+gür-tel-flech-te
+gür-tel-flech-ten
+haft-öl
+haft-öle
+haft-ölen
+haft-uni-ver-si-tät
+haft-uni-ver-si-tä-ten
+halb-ku-gel-ober-flä-che
+halb-ku-gel-ober-flä-chen
+hals-band-af-fä-re
+hals-band-af-fä-ren
+hals-öff-nung
+hals-öff-nun-gen
+hand-in-nen-flä-che
+hand-in-nen-flä-chen
+hand-in-nen-flä-chen-zeich-nung
+hand-in-nen-flä-chen-zeich-nun-gen
+han-dy-ober-flä-che
+han-dy-ober-flä-chen
+haut-emp-fin-dungs-stö-rung
+haut-emp-fin-dungs-stö-run-gen
+herz-raum-öff-nung
+herz-raum-öff-nun-gen
+%him-mels-öff-nung
+%him-mels-öff-nun-gen
+hin-ter-flü-gel-ober-sei-te
+hin-ter-flü-gel-ober-sei-ten
+hirn-ober-flä-che
+hirn-ober-flä-chen
+höchst-auf-la-ge
+höchst-auf-la-gen
+hof-fest-er-lös
+hof-früh-stück
+hof-fuß
+hof-fu-ßes
+hof-fuss
+hof-fus-ses
+hof-lä-cheln
+hof-lösch-ma-schi-ne
+hof-lösch-ma-schi-nen
+hof-lö-sung
+hof-ober-flä-che
+hof-ober-flä-chen
+holz-ober-flä-che
+holz-ober-flä-chen
+holz-pflö-cke
+holz-pflö-cken
+hüft-ano-ma-lie
+hüft-ano-ma-li-en
+hüft-an-schlag
+hüft-an-schla-ges
+hüft-er-kran-kung
+hüft-er-kran-kun-gen
+hüft-ex-ar-ti-ku-liert
+hüft-ex-ar-ti-ku-lier-te
+hüft-ex-ar-ti-ku-lier-ten
+hüft-ge-lenk-er-satz
+hüft-ge-lenk-er-sat-zes
+hüft-ge-lenk-lu-xa-ti-on
+hüft-kopf-um-stel-lung
+hüft-kopf-um-stel-lun-gen
+hüft-rie-men
+hüft-rie-mens
+hüft-speck
+hüft-specks
+im-mun-ober-flä-che
+impf-lü-cke
+impf-lü-cken
+impf-lü-cken-schlie-ßung
+impf-lü-cken-schlies-sung
+in-dus-trie-flü-ge
+in-dus-trie-flü-gen
+in-fil-tra-ti-ons-anäs-the-sie
+in-sel-ober-flä-che
+in-sel-ober-flä-chen
+in-sol-venz-er-öff-nung
+in-sol-venz-er-öff-nun-gen
+in-sol-venz-er-öff-nungs-an-trag
+in-sol-venz-er-öff-nungs-an-tra-ges
+in-sol-venz-er-öff-nungs-an-trags
+in-sol-venz-er-öff-nungs-an-trä-ge
+in-sol-venz-er-öff-nungs-an-trä-ges
+in-sol-venz-er-öff-nungs-ver-fah-ren
+in-sol-venz-er-öff-nungs-ver-fah-rens
+jä-ger-waf-fe
+jä-ger-waf-fen
+jod-sau-er-stoff-säu-re
+jod-was-ser-stoff-säu-re
+kaf-fee-haus-füh-rer
+kaf-fee-haus-füh-rern
+kaf-fee-haus-füh-rers
+kaf-fee-känn-chen
+kaf-fee-känn-chens
+kä-fig-aus-stat-tung
+kä-fig-aus-stat-tun-gen
+kä-fig-dach
+kä-fig-da-ches
+kä-fig-dachs
+kä-fig-dä-cher
+kä-fig-dä-chern
+kä-fig-ecke
+kä-fig-ecken
+kä-fig-rad
+kä-fig-rand
+kä-fig-ran-de
+kä-fig-raum
+kä-fig-rau-mes
+kä-fig-stab
+kä-fig-stabs
+kä-fig-stä-be
+kä-fig-stä-ben
+kä-fig-stre-ben
+käl-te-mu-mi-fi-zie-rung
+kampf-kraft-er-hö-hung
+kampf-kraft-er-hö-hun-gen
+kar-tof-fel-klö-ße
+kar-tof-fel-klö-ßen
+kar-tof-fel-klöß-chen
+kar-tof-fel-klöß-chens
+kampf-lä-cheln
+kar-tell-ent-flech-tungs-be-hör-de
+kauf-läh-mung
+kampf-lüs-tern
+kampf-lüs-ter-ne
+kampf-stoff-spür-ge-rät
+kampf-stoff-spür-ge-rä-te
+kampf-stoff-spür-ge-rä-ten
+kauf-in-ger-stra-ße
+kau-tschuk-ober-flä-che
+kau-tschuk-ober-flä-chen
+ka-val-le-rie-flü-gel
+ka-val-le-rie-flü-geln
+ka-val-le-rie-flü-gels
+ke-gel-ober-flä-che
+ke-gel-ober-flä-chen
+kern-ober-flä-che
+kern-ober-flä-chen
+kla-vier-schleif-lack-ober-flä-che
+kleb-stoff-auf-trag-dü-se
+kleb-stoff-auf-trag-dü-sen
+klein-af-fen-häu-ser
+klein-af-fen-häu-sern
+ko-bold-äff-chen
+ko-bold-äff-chens
+kof-fer-an-hän-ger
+kof-fer-an-hän-gern
+kof-fer-an-hän-gers
+koh-le-flöz
+koh-le-flö-ze
+koh-le-flö-zen
+koh-len-stoff-ober-flä-che
+koh-len-stoff-ober-flä-chen
+koh-len-stoff-säu-re
+koh-len-stoff-säu-ren
+kö-nigs-an-griff
+kö-nigs-an-grif-fe
+kö-nigs-an-grif-fen
+kö-nigs-an-griffs
+kö-nigs-auf-fas-sung
+kö-nigs-auf-fas-sun-gen
+kon-ser-ven-öff-ner
+kon-ser-ven-öff-nern
+kon-ser-ven-öff-ners
+kon-takt-ober-flä-che
+kon-takt-ober-flä-chen
+kopf-ober-flä-che
+kopf-ober-flä-chen
+kör-per-an-griff
+kör-per-an-grif-fe
+kör-per-an-grif-fen
+kör-per-an-griffs
+kör-per-ent-gif-tung
+kör-per-ent-gif-tun-gen
+kör-per-flan-ke
+kör-per-flan-ken
+kot-flü-gel-ober-sei-te
+kot-flü-gel-ober-sei-ten
+kräf-te-aus-gleich
+kräf-te-de-mon-stra-ti-on
+kräf-te-de-mon-stra-tio-nen
+kraft-er-füllt
+kraft-er-füll-te
+kraft-er-füll-tem
+kraft-er-füll-ten
+kraft-er-füll-ter
+kraft-er-füll-tes
+kräf-te-mul-ti-pli-ka-tor
+kräf-te-stei-ge-rung
+Kräftesteigerun-gen
+kraft-in-ge-nieurs-ge-schäf-te
+kraft-in-ge-nieurs-ge-schäf-tes
+kraft-stoff-ein-spritz-dü-se
+kraft-stoff-ein-spritz-dü-sen
+kraft-stoff-ein-trä-ge
+kraft-stoff-ein-trä-gen
+kraft-stoff-luft-ver-hält-nis
+kraft-stoff-luft-ver-hält-nis-ses
+kraft-stoff-ober-flä-che
+kraft-stoff-ober-flä-chen
+kraft-süpp-chen
+kraft-süpp-chens
+kre-dit-af-fä-re
+kre-dit-af-fä-ren
+kreis-lauf-läh-mung
+kreis-lauf-läh-mun-gen
+kreis-öff-nung
+kreis-öff-nun-gen
+ku-gel-ober-flä-che
+ku-gel-ober-flä-chen
+kühl-ef-fekt
+kühl-ef-fek-te
+kühl-ef-fek-ten
+kühl-ef-fekts
+kühl-ober-flä-che
+kühl-ober-flä-chen
+kühl-öff-nung
+kühl-öff-nun-gen
+kunst-stoff-ähn-lich
+kunst-stoff-ähn-li-che
+kunst-stoff-ober-flä-che
+kunst-stoff-ober-flä-chen
+kunst-stoff-rä-der
+kunst-stoff-rä-dern
+kunst-stoff-sä-cke
+kunst-stoff-sä-cken
+kunst-stoff-stöp-sel
+kunst-stoff-stöp-seln
+kunst-stoff-stöp-sels
+kup-fer-ober-flä-che
+kup-fer-ober-flä-chen
+kurs-er-trags-kraft-ver-hält-nis
+kurs-er-trags-kraft-ver-hält-nis-ses
+lan-des-elek-tri-zi-täts-ge-nos-sen-schaft
+lan-des-elek-tri-zi-täts-ge-nos-sen-schaf-ten
+län-der-spiel-tref-fer
+län-der-spiel-tref-fern
+län-der-spiel-tref-fers
+län-gen-auf-la-ge
+län-gen-auf-la-gen
+län-gen-aus-deh-nungs-ko-ef-fi-zi-ent
+län-gen-aus-deh-nungs-ko-ef-fi-zi-en-ten
+lärm-be-ein-flus-sung
+lärm-be-ein-flus-sun-gen
+lärm-ein-fluss
+lärm-ein-flus-ses
+lauf-län-ge
+lauf-län-gen
+lauf-län-gen-an-ga-be
+lauf-län-gen-an-ga-ben
+lauf-län-gen-co-die-rung
+lauf-län-gen-co-die-run-gen
+lauf-län-gen-ko-die-rung
+lauf-län-gen-ko-die-run-gen
+lauf-lärm
+lauf-lärm-pe-gel
+lauf-lärm-pe-geln
+le-der-köf-fer-chen
+le-der-köf-fer-chens
+leit-ton-auf-lö-sung
+leit-ton-auf-lö-sun-gen
+leucht-kraft-än-de-rung
+leucht-kraft-än-de-run-gen
+leucht-kraft-er-hö-hung
+leucht-kraft-er-hö-hun-gen
+li-kör-fla-sche
+li-kör-fla-schen
+lösch-auf-trag
+lösch-auf-tra-ges
+lösch-auf-trags
+lösch-ef-fekt
+lösch-ef-fek-te
+lösch-ef-fek-ten
+los-knüpf-te
+los-knüpf-ten
+los-knüpf-test
+lö-wen-äff-chen
+lö-wen-äff-chens
+luft-at-mo-sphä-re
+luft-at-mo-sphä-ren
+luft-elek-tri-zi-tät
+luft-fahrt-ak-ti-vi-tät
+luft-fahrt-ak-ti-vi-tä-ten
+luft-fahrt-un-glück
+luft-fahrt-un-glü-cke
+luft-fahrt-un-glü-cken
+luft-fahrt-un-glücks
+luft-fahrt-uni-ver-si-tät
+luft-fahrt-uni-ver-si-tä-ten
+luft-post-um-schlä-ge
+luft-post-um-schlä-gen
+luft-räu-me
+luft-räu-men
+luft-rüs-tung
+luft-rüs-tun-gen
+luft-rüs-tungs-pro-gramm
+luft-rüs-tungs-pro-gram-me
+luft-rüs-tungs-pro-gram-men
+luft-rüs-tungs-pro-gramms
+luft-schiff-stütz-punkt
+luft-schiff-stütz-punk-te
+luft-schiff-stütz-punk-ten
+luft-schiff-stütz-punk-tes
+luft-stä-be
+luft-stä-ben
+luft-un-be-stän-dig-keit
+mag-net-ober-flä-che
+mag-net-ober-flä-chen
+män-ner-zeit-schrift
+män-ner-zeit-schrif-ten
+märz-er-run-gen-schaft
+märz-er-run-gen-schaf-ten
+maus-ohr-fle-der-mäu-se
+maus-ohr-fle-der-mäu-sen
+maus-ohr-fle-der-mäus-chen
+meis-ter-schafts-tro-phäe
+meis-ter-schafts-tro-phäen
+men-schen-fleisch-wöl-fe
+men-schen-fleisch-wöl-fen
+mess-öff-nung
+mess-öff-nun-gen
+milch-ober-flä-che
+milch-ober-flä-chen
+milch-trüf-fel
+milch-trüf-feln
+mi-li-tär-er-fin-dung
+mi-li-tär-er-fin-dun-gen
+mi-li-tär-luft-fahrt-aka-de-mie
+mi-li-tär-luft-fahrt-aka-de-mi-en
+mi-li-tär-pflicht-er-satz
+mi-li-tär-pflicht-er-sat-zes
+mi-li-tär-pflicht-er-satz-steu-er
+mi-li-tär-pflicht-er-satz-steu-ern
+min-dest-au-ßen-luft-an-teil
+min-dest-au-ßen-luft-an-tei-le
+min-dest-au-ßen-luft-an-tei-len
+min-dest-au-ßen-luft-an-teils
+mi-ne-ral-stoff-er-näh-rung
+mi-ne-ral-stoff-er-näh-run-gen
+mit-glie-der-af-fä-re
+mit-glie-der-af-fä-ren
+mit-tel-öff-nung
+mit-tel-öff-nun-gen
+mit-sträf-ling
+mit-sträf-lin-ge
+mit-sträf-lin-gen
+mö-bel-ober-flä-che
+mö-bel-ober-flä-chen
+mo-dell-auf-füh-rung
+mo-dell-auf-füh-run-gen
+mok-ka-löf-fel
+mok-ka-löf-feln
+mok-ka-löf-fels
+moos-pflänz-chen
+moos-pflänz-chens
+mor-gen-duft-äp-fel
+mor-gen-duft-äp-feln
+mo-tor-ober-flä-che
+mo-tor-ober-flä-chen
+münz-in-schrift
+münz-in-schrif-ten
+münz-ober-flä-che
+münz-ober-flä-chen
+mu-si-cal-auf-füh-rung
+mu-si-cal-auf-füh-run-gen
+mu-sik-öf-fent-lich-keit
+mu-sik-öf-fent-lich-kei-ten
+mu-sik-vi-deo-ver-öf-fent-li-chung
+mu-sik-vi-deo-ver-öf-fent-li-chun-gen
+mus-ter-köf-fer-chen
+nähr-stoff-li-mi-tiert
+mus-ter-köf-fer-chen
+mus-ter-köf-fer-chens
+nähr-stoff-li-mi-tier-te
+nähr-stoff-li-mi-tier-ten
+na-sen-flü-gel-at-men
+na-sen-flü-gel-at-mens
+na-sen-flü-gel-at-mung
+na-sen-flü-gel-at-mun-gen
+na-tur-eis-flä-che
+na-tur-eis-flä-chen
+net-to-flü-gel-flä-che
+net-to-flü-gel-flä-chen
+netz-öf-fent-lich-keit
+netz-öf-fent-lich-kei-ten
+netz-öff-nung
+netz-öff-nun-gen
+neu-flü-ge
+neu-flü-gen
+neu-tro-nen-fluss-än-de-rung
+neu-tro-nen-fluss-än-de-run-gen
+nicht-er-öff-nung
+nicht-er-öff-nun-gen
+nicht-er-öff-nung-be-schluss
+nicht-er-öff-nung-be-schlus-ses
+nie-der-flur-tank-lösch-fahr-zeug
+nie-der-flur-tank-lösch-fahr-zeu-ge
+nie-der-flur-tank-lösch-fahr-zeu-gen
+nie-der-flur-tank-lösch-fahr-zeugs
+neu-fünf-land
+neu-fünf-län-der
+ni-veau-flä-che
+ni-veau-flä-chen
+not-durft-röh-re
+null-auf-fül-lung
+null-auf-fül-lun-gen
+nutz-ober-flä-che
+nutz-ober-flä-chen
+ober-flä-chen-anäs-the-sie
+ober-flä-chen-anäs-the-si-en
+ober-flä-chen-ener-gie
+ober-flä-chen-ener-gi-en
+ober-flä-chen-ener-gie-dich-te
+ober-flä-chen-ener-gie-dich-ten
+ober-flä-chen-ero-si-on
+ober-flä-chen-ero-sio-nen
+ober-flä-chen-iso-la-ti-on
+ober-flä-chen-iso-la-tio-nen
+ob-jekt-ober-flä-che
+ob-jekt-ober-flä-chen
+obst-pflü-cke-rin-nen
+obst-pflü-ckers
+of-fi-ziers-prü-fung
+or-gan-af-fi-ni-tät
+or-gan-af-fi-ni-tä-ten
+or-gan-ober-flä-che
+or-gan-ober-flä-chen
+pa-pier-bahn-ober-flä-che
+pa-pier-bahn-ober-flä-chen
+park-er-öff-nung
+park-er-öff-nun-gen
+pas-sa-gier-rund-flü-ge
+pas-sa-gier-rund-flü-gen
+pa-tent-schutz-öff-nung
+pa-tent-schutz-öff-nun-gen
+pfef-fer-minz-öl
+pfef-fer-minz-öls
+pflan-zen-er-näh-rung
+pflan-zen-er-näh-run-gen
+pflas-ter-be-lä-ge
+pflas-ter-be-lä-gen
+pfle-ge-in-ten-si-tät
+pfle-ge-in-ten-si-tä-ten
+phos-phor-sau-er-stoff-säu-re
+pin-sel-äff-chen
+pin-sel-äff-chens
+po-lit-auf-trä-ge
+po-lit-auf-trä-gen
+po-ly-eder-flä-che
+po-ly-eder-flä-chen
+por-tal-flü-gel
+por-tal-flü-geln
+por-tal-flü-gels
+por-trät-haft
+por-trät-haf-te
+por-trät-haf-tem
+por-trät-haf-ten
+por-trät-haf-ter
+por-trät-haf-tes
+pro-dukt-ef-fek-ti-vi-tät
+pro-dukt-ef-fek-ti-vi-tä-ten
+pro-fil-ober-flä-che
+pro-fil-ober-flä-chen
+pro-gramm-ober-flä-che
+pro-gramm-ober-flä-chen
+pro-gramm-öff-nung
+pro-pa-gan-da-flü-ge
+pro-pa-gan-da-flü-gen
+pro-te-in-ober-flä-che
+prüf-in-stanz
+prüf-in-stan-zen
+prüf-in-sti-tut
+prüf-in-sti-tu-te
+prüf-in-sti-tu-ten
+prüf-in-sti-tu-ti-on
+prüf-in-sti-tu-tio-nen
+prüf-in-stru-ment
+prüf-in-stru-men-te
+prüf-in-stru-men-ten
+prüf-trich-ter
+prüf-trich-tern
+prüf-trich-ters
+psy-chi-a-trie-flücht-ling
+psy-chi-a-trie-flücht-lin-ge
+rad-ober-flä-che
+rad-ober-flä-chen
+ras-ter-öff-nung
+ras-ter-öff-nun-gen
+rauch-öff-nung
+rauch-öff-nun-gen
+rech-nungs-hof-lö-sung
+rech-nungs-hof-lö-sun-gen
+reif-län-der
+rei-se-köf-fer-chen
+rei-se-köf-fer-chens
+reiz-stoff-sprüh-ge-rät
+reiz-stoff-sprüh-ge-rä-te
+reiz-stoff-sprüh-ge-rä-ten
+re-ser-ve-luft-be-häl-ter
+re-ser-ve-luft-be-häl-tern
+re-ser-ve-luft-be-häl-ters
+re-ser-ve-luft-vor-rä-te
+re-ser-ve-luft-vor-rä-ten
+riff-ähn-lich
+riff-ähn-li-che
+rohr-ober-flä-che
+rohr-ober-flä-chen
+roh-stoff-ähn-lich
+roh-stoff-ähn-li-che
+rück-lauf-ther-mos-tat
+rück-ruf-trick
+rück-ruf-tricks
+rück-schlag-ef-fekt
+rück-schlag-ef-fek-te
+rück-schlag-ef-fek-ten
+rück-stoß-ef-fekt
+rück-stoß-ef-fek-te
+rück-stoß-ef-fek-ten
+saft-sä-cke
+saft-sä-cken
+sä-ge-zahn-ef-fekt
+sä-ge-zahn-ef-fek-te
+sä-ge-zahn-ef-fek-ten
+sau-er-stoff-spei-cher-fä-hig-keit
+sau-er-stoff-spei-cher-fä-hig-kei-ten
+sau-er-stoff-säu-re
+sau-er-stoff-säu-ren
+sau-er-stoff-über-druck-the-ra-pie
+sau-er-stoff-über-druck-the-ra-pi-en
+säu-re-un-emp-find-lich
+säu-re-un-emp-find-li-che
+säu-re-un-emp-find-li-chem
+säu-re-un-emp-find-li-chen
+säu-re-un-emp-find-li-cher
+säu-re-un-emp-find-li-ches
+schä-del-er-öff-nung
+schä-del-er-öff-nun-gen
+schä-del-öff-nung
+schä-del-öff-nun-gen
+schaf-läm-mer
+schaf-lämp-chen
+schall-öff-nung
+schall-öff-nun-gen
+schall-emp-fin-dungs-stö-rung
+schall-emp-fin-dungs-stö-run-gen
+schau-floß
+schau-flo-ßes
+schau-flü-ge
+schau-flü-gen
+schaum-stoff-lösch-mo-ni-tor
+schaum-stoff-lösch-mo-ni-tors
+schaum-stoff-lösch-mo-ni-to-re
+schaum-stoff-lösch-mo-ni-to-ren
+schaum-stoff-stöp-sel
+schaum-stoff-stöp-seln
+schaum-stoff-stöp-sels
+schen-kel-klopf-lek-tü-re
+schilf-flö-te
+schilf-flö-ten
+schilf-lü-cke
+schilf-lü-cken
+schirm-öff-nung
+schirm-öff-nun-gen
+schlaf-läh-mung
+schlaf-läh-mun-gen
+schlaf-län-ge
+schlauch-ober-flä-che
+schlauch-ober-flä-chen
+schlauch-öff-nung
+schlauch-öff-nun-gen
+schleif-lack-mö-bel
+schleif-lack-mö-beln
+schleif-lack-mö-bels
+schleim-haut-ober-flä-che
+schlepp-flü-ge
+schlepp-flü-gen
+schließ-mus-kel-öff-nung
+schließ-mus-kel-öff-nun-gen
+schliess-mus-kel-öff-nung
+schliess-mus-kel-öff-nun-gen
+schlitz-öff-nung
+schlitz-öff-nun-gen
+schlürf-lau-te
+schlürf-lau-ten
+schlüs-sel-er-fin-dung
+schlüs-sel-er-fin-dun-gen
+schlüs-sel-tref-fen
+schlüs-sel-tref-fens
+schmelz-ober-flä-che
+schmelz-ober-flä-chen
+schneid-öff-nung
+schneid-öff-nun-gen
+schnell-ent-lüf-tung
+schnell-ent-lüf-tun-gen
+schnell-an-griffs-schläu-che
+schnell-an-griffs-schläu-chen
+schnüf-fel-dro-ge
+schnüf-fel-dro-gen
+schreib-tisch-ober-flä-che
+schreib-tisch-ober-flä-chen
+schul-hof-lärm
+schul-öf-fent-lich-keit
+schul-öf-fent-lich-kei-ten
+schürf-loch
+schürf-lö-cher
+schürf-lö-chern
+schürf-li-zenz
+schürf-li-zen-zen
+schwarz-kopf-lö-wen-äff-chen
+schwarz-kopf-lö-wen-äff-chens
+schweif-län-ge
+schweif-län-gen
+schwei-ne-fleisch-wür-fel
+schwei-ne-fleisch-wür-feln
+schwei-ne-fleisch-wür-fels
+schweiß-tuff
+schweiß-tuf-fe
+schweiß-tuf-fen
+schwenk-löf-fel
+schwenk-löf-feln
+schwenk-löf-fels
+se-gel-aus-flü-ge
+se-gel-aus-flü-ge
+se-gel-ober-flä-che
+se-gel-ober-flä-chen
+seh-öff-nung
+seh-öff-nun-gen
+sei-den-äff-chen
+sei-den-äff-chens
+seil-ober-flä-che
+seil-ober-flä-chen
+sei-ten-schiff-ähn-lich
+se-kun-där-ef-fekt
+se-kun-där-ef-fek-te
+se-kun-där-ef-fek-ten
+se-kun-där-ef-fek-tes
+selbst-öff-nung
+selbst-öff-nun-gen
+senf-früch-te
+senf-früch-ten
+senf-fül-lung
+senf-fuß-bad
+senf-läd-chen
+sieb-ober-flä-che
+sieb-ober-flä-chen
+sil-ber-äff-chen
+sil-ber-äff-chens
+soft-ware-bün-del
+soft-ware-bün-deln
+soft-ware-bün-dels
+spät-schrift
+spät-schrif-ten
+spie-gel-ober-flä-che
+spie-gel-ober-flä-chen
+spiel-bank-er-öff-nung
+spiel-bank-er-öff-nun-gen
+spiel-er-öff-nung
+spiel-er-öff-nun-gen
+spiel-ober-flä-che
+spiel-ober-flä-chen
+spül-ef-fekt
+spül-ef-fek-te
+spül-ef-fek-ten
+spül-öff-nung
+spül-öff-nun-gen
+stadt-bahn-er-öff-nung
+stadt-bahn-er-öff-nun-gen
+stahl-ober-flä-che
+stahl-ober-flä-chen
+stan-dard-ar-beits-flä-che
+stan-dard-ar-beits-flä-chen
+start-ober-flä-che
+start-ober-flä-chen
+staub-blatt-hälf-te
+staub-blatt-hälf-ten
+staub-ober-flä-che
+staub-ober-flä-chen
+stau-flüs-sig-keit
+stau-flüs-sig-kei-ten
+stein-koh-le-flöz
+stein-koh-le-flö-ze
+stein-koh-le-flö-zen
+stein-wurf-län-ge
+stem-pel-ober-flä-che
+stem-pel-ober-flä-chen
+stern-ober-flä-che
+stern-ober-flä-chen
+stern-ober-flä-chen-stuk-tur
+stift-er-ken-nungs-hö-he
+stift-er-ken-nungs-hö-hen
+stock-fisch-wür-fel
+stock-fisch-wür-feln
+stoff-ei-gen-schafts-än-de-rung
+stoff-ei-gen-schafts-än-de-run-gen
+stoff-ein-trä-ge
+stoff-ein-trä-gen
+stoff-ent-wür-fe
+stoff-ent-wür-fen
+stoff-sä-cke
+stoff-sä-cken
+stoff-säck-chen
+stoff-säck-chens
+stoff-stück
+stoff-stü-cke
+stoff-stü-cken
+stoff-stücks
+stör-ef-fekt
+stör-ef-fek-te
+stör-flug-zeug
+stör-flug-zeu-ge
+stör-flug-zeu-gen
+stör-flug-zeugs
+stoß-ef-fekt
+stoß-ef-fek-te
+stoß-ef-fek-ten
+stoß-emp-find-lich-keit
+stoß-emp-find-lich-kei-ten
+straf-län-ge
+straf-län-gen
+straf-läs-sig
+straf-lü-cke
+straf-lü-cken
+streit-kräf-te-amt
+streit-kräf-te-ar-ti-kel
+streit-kräf-te-ar-ti-keln
+streit-kräf-te-ar-ti-kels
+streit-kräf-te-aus-schuss
+streit-kräf-te-aus-schus-ses
+streit-kräf-te-aus-schüs-se
+streit-kräf-te-aus-schüs-sen
+strom-öff-nung
+strom-öff-nun-gen
+sturm-wurf-lö-cher
+sturm-wurf-lö-chern
+sturm-wurf-lü-cke
+sturm-wurf-lü-cken
+stumm-film-ära
+such-ober-flä-che
+such-ober-flä-chen
+süd-ame-ri-ka-qua-li-fi-ka-ti-on
+süd-ame-ri-ka-qua-li-fi-ka-tio-nen
+sün-den-knecht-schaft
+sün-den-knecht-schaf-ten
+süß-was-ser-fisch-art
+süß-was-ser-fisch-ar-ten
+surf-lek-tü-ren
+sym-bol-lei-sten-schalt-flä-che
+sym-bol-lei-sten-schalt-flä-chen
+sys-tem-ober-flä-che
+sys-tem-ober-flä-chen
+ta-ges-ober-flä-che
+ta-ges-ober-flä-chen
+ta-ges-öff-nung
+ta-ges-öff-nun-gen
+tank-ent-lüf-tung
+tank-ent-lüf-tun-gen
+tank-öff-nung
+tank-öff-nun-gen
+ta-rif-län-gen-er-mitt-lung
+ta-rif-lü-cke
+ta-rif-lü-cken
+tau-flüs-sig-keit
+tau-flüs-sig-kei-ten
+text-ober-flä-che
+tisch-ober-flä-che
+ton-film-um-rüs-tung
+ton-film-um-rüs-tun-gen
+to-ten-kopf-äff-chen
+to-ten-kopf-äff-chens
+trä-ger-ober-flä-che
+trä-ger-ober-flä-chen
+trä-ger-stoff
+trä-ger-stof-fe
+trä-ger-stof-fen
+trä-ger-stoffs
+trä-ger-waf-fe
+trä-ger-waf-fen
+trä-ger-waf-fen-sys-tem
+trä-ger-waf-fen-sys-te-me
+trä-ger-waf-fen-sys-te-men
+trä-ger-waf-fen-sys-tems
+trep-pen-lauf-län-ge
+trep-pen-lauf-län-gen
+treu-flei-ßig
+treu-flei-ßi-ge
+treu-flei-ßi-gen
+treu-flei-ßi-ger
+trink-öff-nung
+trink-öff-nun-gen
+trom-mel-ober-flä-che
+trom-mel-ober-flä-chen
+tüpf-li-schei-ßer
+tüpf-li-scheis-ser
+tüpf-li-schies-ser
+tun-nel-er-öff-nung
+tun-nel-er-öff-nun-gen
+turm-öff-nung
+turm-öff-nun-gen
+über-fall-an-griff
+über-fall-an-grif-fe
+über-fall-an-grif-fen
+über-fall-an-griffs
+über-lauf-trich-ter
+über-lauf-trich-tern
+über-lauf-trich-ters
+über-schrift-sche-ma
+über-schrift-sche-ma-ta
+über-trä-ger-stoff
+über-trä-ger-stof-fe
+über-trä-ger-stof-fen
+über-trä-ger-stoffs
+um-lauf-län-ge
+um-lauf-län-gen
+un-ter-flü-gel-auf-hän-gung
+un-ter-flü-gel-auf-hän-gun-gen
+un-ter-wä-sche-fir-ma
+un-ter-wä-sche-fir-men
+ul-tra-hoch-auf-lö-sung
+ul-tra-hoch-auf-lö-sun-gen
+vam-pir-fle-der-mäu-se
+vam-pir-fle-der-mäu-sen
+vam-pir-fle-der-mäus-chen
+va-ri-eté-auf-füh-rung
+va-ri-eté-auf-füh-run-gen
+ver-eins-auf-lö-sung
+ver-eins-auf-lö-sun-gen
+ver-nunft-er-wä-gung
+ver-nunft-er-wä-gun-gen
+vi-deo-ver-fil-mung
+vi-deo-ver-öf-fent-li-chung
+vi-deo-ver-öf-fent-li-chun-gen
+vier-pass-öff-nung
+vier-pass-öff-nun-gen
+vor-der-flü-gel-ober-sei-te
+vor-der-flü-gel-ober-sei-ten
+vor-der-trag-flä-che
+vor-der-trag-flä-chen
+vor-flü-gel-an-ord-nung
+vor-flü-gel-an-ord-nun-gen
+vor-führ-ef-fekt
+vor-führ-ef-fek-te
+vor-führ-ef-fek-ten
+vor-führ-ef-fekts
+vor-hof-lü-cke
+vor-hof-lü-cken
+vor-stau-flä-che
+vor-stau-flä-chen
+wäh-ler-iden-ti-fi-ka-ti-on
+wahl-kampf-er-öff-nung
+wahl-kampf-er-öff-nun-gen
+wahl-kampf-lek-tü-re
+wahl-kampf-lü-ge
+wahl-kampf-lü-gen
+wäh-rungs-fluk-tu-a-ti-on
+wäh-rungs-fluk-tu-a-tio-nen
+wär-me-dif-fe-renz
+wär-me-dif-fe-ren-zen
+wär-me-dif-fu-si-on
+wär-me-schutz-ei-gen-schaft
+wär-me-schutz-ei-gen-schaf-ten
+wär-me-spei-cher-ei-gen-schaft
+wär-me-spei-cher-ei-gen-schaf-ten
+was-ser-fle-der-mäus-chen
+was-ser-fle-der-mäu-se
+was-ser-fle-der-mäu-sen
+weg-werf-lek-tü-re
+wer-be-film-äs-the-tik
+wer-be-film-äs-the-ti-ken
+werk-auf-füh-rung
+werk-auf-füh-run-gen
+werks-öff-nung
+werk-stoff-än-de-rung
+werk-stoff-än-de-run-gen
+werk-stoff-ober-flä-che
+werk-stoff-ober-flä-chen
+werk-stück-stoff
+werk-stück-stof-fe
+werk-stück-stof-fen
+werk-stück-stoffs
+wet-ter-öff-nung
+wet-ter-öff-nun-gen
+wett-kampf-lü-cke
+win-kel-öff-nung
+win-kel-öff-nun-gen
+win-ter-öff-nung
+win-ter-öff-nun-gen
+wirt-schafts-at-ta-ché
+wölf-ling
+wölf-linge
+wür-fel-lei-den-schaft
+wür-fel-lei-den-schaf-ten
+wurf-län-der-kampf
+wur-zel-ober-flä-che
+wur-zel-ober-flä-chen
+wur-zel-trüf-fel
+wur-zel-trüf-feln
+zäh-ler-suf-fix
+zäh-ler-suf-fi-xe
+zäh-ler-suf-fi-xen
+zahn-fleisch-ent-zün-dung
+zahn-fleisch-ent-zün-dun-gen
+zahn-fleisch-rück-gang
+zahn-fleisch-rück-gan-ges
+zahn-ober-flä-che
+zahn-ober-flä-chen
+zahn-schmelz-ober-flä-che
+zahn-schmelz-ober-flä-chen
+zapf-lö-cher
+zapf-lö-chern
+zau-ber-köf-fer-chen
+zau-ber-köf-fer-chens
+zeit-wert-er-öff-nungs-bi-lanz
+zeit-wert-er-öff-nungs-bi-lan-zen
+zell-auf-lö-sung
+zell-auf-lö-sun-gen
+ze-ment-ober-flä-che
+ze-ment-ober-flä-chen
+zi-vil-flü-ge
+zi-vil-flü-gen
+zu-griffs-prio-ri-tät
+zu-griffs-prio-ri-tä-ten
+zwölf-far-ben-ma-schi-ne
+zwölf-far-ben-ma-schi-nen
+zwölf-far-big
+zwölf-far-bi-ge
+zwölf-far-bi-gen
+zwölf-fin-ger-darm-ar-te-rie
+zwölf-fin-ger-darm-ar-te-ri-en
+zwölf-li-ni-en-spiel
+zwölf-li-ni-en-spie-le
+zwölf-li-ni-en-spie-len
+zwölf-li-ni-en-spie-les
+zwölf-li-ni-en-spiels
+zwölf-li-ter-glas
+zwölf-ton-oper
+zwölf-ton-opern
+zy-lin-der-in-nen-flä-che
+zy-lin-der-in-nen-flä-chen
+}
+\fi
diff --git a/macros/luatex/latex/selnolig/selnolig-german-patterns.sty b/macros/luatex/latex/selnolig/selnolig-german-patterns.sty
new file mode 100644
index 0000000000..6d878a50e9
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig-german-patterns.sty
@@ -0,0 +1,2017 @@
+% !TeX root = selnolig.tex
+% !TEX TS-program = lualatex
+
+\ProvidesPackage{selnolig-german-patterns}%
+[2015/10/26]
+
+% This entire package is placed under the
+% terms of the LaTeX Project Public License,
+% version 1.3 or later
+% (http://www.latex-project.org/lppl.txt).
+% It has the status "maintained".
+%
+% Author: Mico Loretan
+% (loretan dot mico at gmail dot com)
+
+
+% A note on the organization of the \nolig
+% macros in this file: They are grouped by
+% the f-ligature being suppressed: ff -> f-f;
+% fi -> f-i, fl -> f-l, etc. Within each of
+% these sections, the \nolig commands are
+% listed first for word-beginnings and
+% second by word-interior search strings,
+% alphabetically within each group.
+
+
+% 1. ff -> f-f
+% ------------
+
+\nolig{Auff[aeiloruyäöü]}{Auf|f}
+\nolig{auff[aeiloruyäöü]}{auf|f}
+ % Hundreds (thousands?!) of words that
+ % start with or contain [aA]uff-,
+ % [kK]auff-, [lL]auf- and don't end
+ % with "ff".
+ % We must provide a few \keeplig macros,
+ % though, to deal with some surnames and
+ % some words of French origin.
+ \keeplig{Lauffen}
+ \keeplig{Stauffach} % Stauffacher
+ \keeplig{Stauffen} % Stauffenbergattentat
+ \keeplig{stauffen}
+ \keeplig{Stauffer}
+ \keeplig{stauffer}
+ \keeplig{Stauffisch}
+ \keeplig{stauffisch}
+
+ \keeplig{chauffier}
+ \keeplig{Chauffier}
+ \keeplig{chauffeur}
+ \keeplig{Chauffeur}
+ \keeplig{chauffement} % Echauffement
+
+\nolig{Brieff}{Brief|f}
+\nolig{brieff}{brief|f}
+ % Brief-f... (viele Fälle!)
+\nolig{Cheff}{Chef|f}
+\nolig{cheff[aäeioöruü]}{chef|f}
+ % Cheffahrer Cheffront ...
+ \keeplig{cheffekt} % Lacheffekt Wischeffekt
+ \keeplig{Scheffel}
+ \keeplig{scheffel} % scheffeln
+ \keeplig{cheffizi} % hocheffizient
+ \keeplig{cheffé} % Scheffé (a statistician)
+\nolig{cheffl[aiou]}{chef|fl}
+\nolig{Dampff}{Dampf|f}
+\nolig{dampff}{dampf|f}
+ % (viele Fälle!)
+\nolig{Dorff[aäeiloöruü]}{Dorf|f}
+\nolig{dorff[aäeiloöruü]}{dorf|f}
+ % (viele Fälle!)
+\nolig{Hanff}{Hanf|f}
+\nolig{hanff}{hanf|f}
+ % Hanffasern Hanffeld
+\nolig{Hoff[aäiloöruü]}{Hof|f}
+ % (viele Fälle!)
+ \keeplig{Hoffacker}
+ \keeplig{Hoffart}
+ \keeplig{Hoffärt} % Hoffärtigkeit
+ \keeplig{Hoffricht} % Hoffrichter
+ \keeplig{Hoffranz} % Hoffranzen (?)
+
+\nolig{Golff}{Golf|f}
+\nolig{golff}{golf|f}
+ % (viele Fälle!)
+\nolig{Hoffern}{Hof|fern}
+\nolig{hoffern}{hof|fern}
+ % Hofferne hofferner
+\nolig{Hoffest}{Hof|fest}
+ % Hoffest Hoffesterlös Hoffestteam
+\nolig{Impff}{Impf|f}
+ % Impffurcht Impffortbildung
+\nolig{Kampff[aäeoöruü]}{Kampf|f}
+\nolig{kampff[aäeoöruü]}{kampf|f}
+ % kampffertig Kampffigur
+ % Kampffuchs Kampffüchse
+ % Wahlkampffloskeln
+\nolig{Kopff[aäeoöruü]}{Kopf|f}
+\nolig{kopff[aäeoöruü]}{kopf|f}
+ % (viele Fälle!)
+ % [kK]opffi -> caught by pffi rule
+ % [kK]opffl -> caught by pffl rule
+\nolig{Klopff}{Klopf|f}
+\nolig{klopff}{klopf|f}
+ % Schenkelklopffrohsinn klopfrei
+\nolig{Prüff}{Prüf|f}
+\nolig{prüff}{prüf|f}
+ % (viele Fälle!)
+\nolig{Ruffach}{Ruf|fach}
+ % Ruffach
+\nolig{ruffach}{ruf|fach}
+ % Hausnotruffachberater beruffachlichen
+\nolig{Rumpff}{Rumpf|f}
+ % Rumpffassung
+\nolig{Schaffang}{Schaf|fang}
+\nolig{Schaffarm}{Schaf|farm}
+\nolig{Schaffels}{Schaf|fels}
+
+\nolig{Schilff}{Schilf|f}
+\nolig{schilff}{schilf|f}
+ % Schilffeld Schilfflöte Schilffloß
+\nolig{Senff}{Senf|f}
+\nolig{senffa}{senf|fa}
+ % Senffabrik senffarbig
+\nolig{senffl}{senf|fl}
+ % senffleckig
+\nolig{senfl[aä]}{senf|l}
+ % senfladen senflädchen
+\nolig{Sumpff}{Sumpf|f}
+\nolig{sumpff}{sumpf|f}
+ % (viele Fälle!)
+\nolig{Tariff}{Tarif|f}
+\nolig{tariff}{tarif|f}
+ % (viele Fälle!)
+\nolig{Tieff}{Tief|f}
+\nolig{tieff}{tief|f}
+ % (viele Fälle!)
+ \keeplig{tieffekt}
+ % Multieffekt Konfettieffekt
+ \keeplig{tieffiz}
+ % Antieffizienz
+
+
+\nolig{chaffron}{chaf|fron}
+ % Schaffron
+\nolig{eiffest}{eif|fest}
+ % reiffest
+
+\nolig{ffabrik}{f|fabrik}
+ % Strumpffabrik
+\nolig{ffacet}{f|facet}
+ % Relieffacetten
+\nolig{ffachl}{f|fachl}
+ % beruffachlich golffachlich
+\nolig{ffachm}{f|fachm}
+ % Huffachmann Wahlkampffachmann
+ % Golffachmesse Fünffachmord
+\nolig{ffäch}{f|fäch}
+ % Brieffächer Einwurffächer fünffächrig
+\nolig{ffaden}{f|faden}
+ % Einzelknopffaden Knüpffaden
+\nolig{ffäd}{f|fäd}
+ % Einzelknopffäden Tropffäden
+\nolig{ffähig}{f|fähig}
+ % hoffähig kampffähig lauffähig
+\nolig{ffahn}{f|fahn}
+ % Totenkopffahne Dorffahne Wahlkampffahnen
+\nolig{ffahr}{f|fahr}
+ % Schifffahrt Schleiffahrt Tariffahrplan
+ \keeplig{iffahrt}
+ % Schiffahrt [alte Rechtschreibung...]
+\nolig{ffähr}{f|fähr}
+ % Dampffährdienst
+\nolig{ffaktor}{f|faktor}
+ % Hoffaktor Schlupffaktoren
+\nolig{ffakult}{f|fakult}
+ % Rumpffakultät
+\nolig{ffall}{f|fall}
+ % Anruffalle auffallen Straffall
+ % Tariffalle Streiffall Maulwurffalle
+ \keeplig{ffallee} % Oppenhoffallee
+ \keeplig{ffallerg} % Duftstoffallergie
+ \keeplig{ffallokat}% Rohstoffallokation
+\nolig{ffäll}{f|fäll}
+ % straffällig unauffällig
+\nolig{ffalt}{f|falt}
+ % Fünffaltigkeit Dickkopffalter
+ \keeplig{iffalt} % Segelschiffalter
+ \keeplig{offalt} % Kraftstoffalternativen
+\nolig{ffält}{f|fält}
+ % fünffältig
+\nolig{ffami}{f|fami}
+ % Zwölffamilienhäuser
+ \keeplig{Diffami} % Diffamierung
+ \keeplig{diffami} % diffamierend
+\nolig{ffanat}{f|fanat}
+ % Schärffanatiker
+\nolig{ffans}{f|fans}
+ % Waldhoffans
+ \keeplig{riffans} % Griffansätze
+ \keeplig{toffans} % Sprengstoffanschlag
+\nolig{ffanta}{f|fanta}
+ % Schlaffantasie Straffantasie
+\nolig{ffarb}{f|farb}
+ % Zwölffarbenmaschine zwölffarbig
+ \keeplig{ffarbeit}
+\nolig{ffärb}{f|färb}
+ % Kopffärbung
+\nolig{ffaschi}{f|faschi}
+ % Schulhoffaschismus
+\nolig{ffassad}{f|fassad}
+ % Innenhoffassade
+\nolig{ffäul}{f|fäul}
+ % Sumpffäulnis
+
+\nolig{ffecht}{f|fecht}
+ % Klopffechter
+\nolig{ffeder}{f|feder}
+ % -f-feder...
+\nolig{ffedr}{f|fedr}
+ % zwölffedrig
+\nolig{ffehl}{f|fehl}
+ % Schärffehler
+\nolig{ffeier}{f|feier}
+ % Hoffeierlichkeiten
+ \keeplig{toffeier} % kunststoffeier
+\nolig{ffeind[els]}{f|feind}
+ % -f-feinde -f-feindlich -f-feindschaft
+ \keeplig{ffeindealer} % Koffeindealer
+\nolig{ffeld}{f|feld}
+ % Prüffeld Schilffeld Kampffeld
+ \keeplig{Büffeld} % Büffeldecke
+ \keeplig{büffeld}
+ \keeplig{ffeldenk} % Scheffeldenkmal
+ \keeplig{Iffeld} % Iffeldorf
+ \keeplig{Löffeld} % Löffeldüngung
+ \keeplig{löffeld}
+ \keeplig{Müffeld} % Müffeldoktor
+ \keeplig{müffeld}
+ \keeplig{nüffeld} % Schnüffeldienst -droge
+ \keeplig{Riffeld} % Riffeldielen
+ \keeplig{taffeld} % Staffeldach -diplomatie
+ \keeplig{toffeld} % Kartoffeldruck -dieb
+ \keeplig{Trüffeld} % Trüffelduft -dorf
+ \keeplig{trüffeld}
+ \keeplig{Waffeld} % Waffelduft
+ \keeplig{waffeld}
+
+\nolig{ffell}{f|fell}
+ % Werwolffell Schaffell
+ \keeplig{ffelleck} % Waffelleckereien
+ \keeplig{ffellinde}% Scheffellinde
+ \keeplig{Muffell} % Muffellämmer
+ \keeplig{muffell} % muffellig
+ \keeplig{öffell}
+ % Löffellamm Kochlöffellängen
+ \keeplig{taffell} % Staffellauf -läufer
+ \keeplig{toffell}
+ % Kartoffellager -liebhaber
+ % Pantoffellarve Kunstoffelle
+ \keeplig{üffell} % Büffelleber -leder -leib
+ % Trüffelleidenschaft Schnüffellust
+\nolig{ffeile}{f|feile}
+ % Prüffeile
+\nolig{ffenster}{f|fenster}
+ % Hinterhoffenster Schlaf- Tarif-
+\nolig{fferien}{f|ferien}
+ % Reiterhofferien Bauernhofferien
+\nolig{ffernseh}{f|fernseh}
+ % Abruffernsehen
+\nolig{ffertig}{f|fertig}
+ % schlaffertig
+\nolig{ffestl}{f|festl}
+ % Straffestlegung
+\nolig{ffests}{f|fests}
+ % Straffestsetzung
+ % Hoffestspiele Dorffestspiel
+\nolig{ffetisch}{f|fetisch}
+ % Schaffetischisten
+\nolig{ffetus}{f|fetus}
+ % Schaffetus
+\nolig{ffett}{f|fett}
+ % Huffett Rumpffett Scharffetter
+ \keeplig{Buffett} % Buffettheke
+ \keeplig{Büffett}
+ \keeplig{buffett}
+ \keeplig{büffett} % Obstbüffett
+\nolig{ffetz}{f|fetz}
+ % Brieffetzen Stofffetzen
+ \keeplig{Buffetz} % Buffetzeit
+ \keeplig{Büffetz} % Büffetzusammenstellung
+\nolig{ffeud}{f|feud}
+ % Kasernenhoffeudalismus
+\nolig{ffeue}{f|feue}
+ % Dorffeuerwehr Torffeuer Lauffeuer
+
+\nolig{ffilet}{f|filet}
+ % Meerwolffilet
+\nolig{ffindung}{f|findung}
+ % Beruffindungsprozess
+\nolig{ffirm}{f|firm}
+ % Brieffirmen Tariffirmen
+ \keeplig{affirm}
+ \keeplig{Affirm}
+
+\nolig{ffolg}{f|folg}
+ % Impffolgen
+\nolig{ffoli}{f|foli}
+ % Relieffolien
+\nolig{ffolter}{f|folter}
+ % Tropffolter
+ \keeplig{Affoltern} % town near Zurich
+\nolig{ffond}{f|fond}
+ % Tariffondslösung
+\nolig{fforder}{f|forder}
+ % Tarifforderung Strafforderung
+\nolig{fförder}{f|förder}
+ % ruffördernd kreislauffördernd schlaffördernd
+\nolig{fforell}{f|forell}
+ % Werfforellen
+\nolig{fform}{f|form}
+ % Kopfform Gugelhupfform aufformen
+\nolig{fförm}{f|förm}
+ % reifförmig schweifförmig
+\nolig{fforsch}{f|forsch}
+ % Schlafforschung Impfforschung
+\nolig{fforen}{f|foren}
+ % Abrufforen
+\nolig{fforu}{f|foru}
+ % Schlafforum
+\nolig{ffoto}{f|foto}
+ % Schlaffotogalerie
+\nolig{fföt}{f|föt}
+ % Wolffötus
+
+\nolig{ffracht}{f|fracht}
+ % Dampffrachter
+\nolig{ffrag}{f|frag}
+ % Streiffragen
+ \keeplig{Suffrage} % Suffragette
+ \keeplig{suffrage}
+\nolig{ffrak}{f|frak}
+ % Rumpffraktion
+ \keeplig{toffrak} % Flüssigstoffrakete
+\nolig{ffrank}{f|frank}
+ % Fünffrankenstück
+\nolig{ffräs}{f|fräs}
+ % Baumstumpffräse
+\nolig{ffrau}{f|frau}
+ % Hoffrau Kauffrau
+ \keeplig{ffraum} % Sprengstoffraub
+ \keeplig{ffraub} % Treffraum
+ \keeplig{ffrausch} % Klebstoffrausch
+ \keeplig{ffraup} % Stoffraupe
+
+\nolig{ffreak}{f|freak}
+ % Surffreak
+ \keeplig{toffreak} % Schadstoffreaktionen
+\nolig{ffregat}{f|fregat}
+ % Kampffregatte Dampffregatte
+\nolig{ffrei}{f|frei}
+ % tariffrei Schlaffrei
+ \keeplig{chiffrei}% Schiffreise
+ \keeplig{toffrei} % stoffrein sauerstoffreich
+ \keeplig{uffreis} % Puffreis
+ \keeplig{luffrei} % schluffreich
+ \keeplig{iffreig} % Riffreigen
+\nolig{ffremd}{f|fremd}
+ % hoffremd
+\nolig{ffreq}{f|freq}
+ % Schlaffrequenz
+\nolig{ffreu}{f|freu}
+ % Straffreude Brieffreund
+
+\nolig{ffrisch}{f|frisch}
+ % Schaffrischkäse zapffrisch
+\nolig{ffried}{f|fried}
+ % Dorffrieden Hoffrieden
+\nolig{ffries}{f|fries}
+ % Relieffries
+ \keeplig{toffries} % Rohstoffriese
+\nolig{ffrist}{f|frist}
+ % Prüffrist Ablauffrist
+\nolig{ffriseu}{f|friseu}
+ % Hoffriseur Dorffriseur
+\nolig{ffrisur}{f|frisur}
+ % Schlaffrisur Topffrisur Zopffrisur
+
+\nolig{ffront}{f|front}
+ % Hoffront Kampffront
+ \keeplig{affront}
+ \keeplig{Affront}
+\nolig{ffrosch}{f|frosch}
+ % Pfeiffrosch
+\nolig{ffrösch}{f|frösch}
+ % Pfeiffrösche
+\nolig{ffrucht}{f|frucht}
+ % Rumtopffrucht
+\nolig{ffrücht}{f|frücht}
+ % Rumtopffrüchte
+\nolig{ffrüh}{f|früh}
+ % Hoffrühstück Cheffrühstück
+
+\nolig{ffund}{f|fund}
+ % Brückenkopffundament
+ \keeplig{iffund} % diffundieren
+ \keeplig{toffund} % stoffundurchlässig
+\nolig{fführ}{f|führ}
+ % Kampffführung aufführen
+\nolig{ffunk}{f|funk}
+ % Brieffunktion Abruffunktion
+\nolig{ffühl}{f|fühl}
+ % Scharffühler
+\nolig{ffüll}{f|füll}
+ % Prüffüllgut Dampffüllung
+\nolig{ffürst}{f|fürst}
+ % -f-fürst
+\nolig{ffuß}{f|fuß}
+\nolig{ffuss}{f|fuss}
+\nolig{ffüß}{f|füß}
+\nolig{ffüss}{f|füss}
+ % Greiffuß Greiffüße
+ \keeplig{iffuss}
+ % Diffusschall -strahlung
+\nolig{ffutter}{f|futter}
+ % Prüffutter
+\nolig{ffütter}{f|fütter}
+ % Abruffütterung
+
+\nolig{hoffan}{hof|fan}
+ % Waldhoffan
+\nolig{hoffersch}{hof|fersch}
+ % Talhofferschen
+\nolig{hoffest}{hof|fest}
+ % Pfarrhoffest Hinterhoffest
+\nolig{hoffete}{hof|fete}
+ % Schneckenhoffete
+
+\nolig{lffach}{lf|fach}
+ % elffach zwölffach
+
+\nolig{offegen}{of|fegen}
+ % Hoffegen
+
+\nolig{pffach}{pf|fach}
+ % Strumpffach
+\nolig{pffern}{pf|fern}
+ % rumpffern
+\nolig{pffest}{pf|fest}
+ % Klopffestigkeit tropffester
+\nolig{pffels}{pf|fels}
+ % Hirschkopffelsen
+\nolig{pffont}{pf|font}
+ % Dampffontäne
+\nolig{pffüh}{pf|füh}
+ % Kampfführung
+
+\nolig{reiffern}{reif|fern}
+ % reiffern
+\nolig{rffan}{rf|fan}
+ % Surffan
+\nolig{rffeel}{rf|feel}
+ % Surffeeling
+\nolig{rffest}{rf|fest}
+ % Surffest
+\nolig{rffinn}{rf|finn}
+ % Surffinne
+\nolig{rffleck}{rf|fleck}
+ % Schorfflecken
+
+\nolig{straffern}{straf|fern}
+ \keeplig{rtstraffern} % Gurtstraffern
+ \keeplig{ssstraffern}
+ % Gurtschlossstraffern
+
+\nolig{ünff}{ünf|f}
+ % fünffarbig fünffingrig fünfflügelig
+ % Fünfflach fünfflammig fünffleckige
+
+\nolig{wurff[aäeiloöruü]}{wurf|f}
+ % Auswurffach Einwurffehler
+ % Hammerwurffinale
+
+
+% 2. fi -> f-i
+% ------------
+
+\nolig{Aufi}{Auf|i}
+\nolig{aufinstr}{auf|instr}
+ % aufinstruieren
+\nolig{aufirr}{auf|irr}
+ % hinaufirrte
+\nolig{aufisst}{auf|isst}
+
+\nolig{Briefi}{Brief|i}
+\nolig{briefi}{brief|i}
+ % Briefidiom Briefinhalt Pfandbriefinhaber
+ \keeplig{Briefing} % neu-Deutsch...
+ \keeplig{ebriefing} % debriefing, Debriefing
+
+\nolig{Chefi}{Chef|i}
+\nolig{chefi}{chef|i}
+ % Chefideologe Chefindianer
+ % Chefinformatiker
+ \keeplig{Chefin} % Chefin Chefinnen
+ \nolig{Chefin[a-mo-z]}{Chef|in}
+ % Chefinder -indianer -inspektor
+ % -inquisitor
+ \keeplig{chefin}
+ \nolig{chefind}{chef|ind}
+ \keeplig{chefibel} % Recherchefibel
+ \keeplig{chefiebe} % Recherchefieber
+ \keeplig{chefigur} % Nietzschefigur
+ \keeplig{chefilm} % Rachefilm
+ \keeplig{chefili} % Wäschefiliale
+ \keeplig{chefirm} % Geldwäschefirma
+ \keeplig{chefisch} % Wäschefische
+
+\nolig{Dorfi}{Dorf|i}
+\nolig{dorfi}{dorf|i}
+ % Dorfidylle -information -institute
+\nolig{Hofi}{Hof|i}
+ % (viele Fälle!)
+ \keeplig{Hofier} % Hofieren
+\nolig{Kampfi}{Kampf|i}
+\nolig{kampfi}{kampf|i}
+ % Kampfideologie Kampfinstrument
+\nolig{Kaufi}{Kauf|i}
+\nolig{kaufi}{kauf|i}
+ % Kaufidee kaufinteressiert Kaufimpuls
+\nolig{Laufi}{Lauf|i}
+\nolig{laufi}{lauf|i}
+ % Laufidol Kreislaufinsuffizienz
+ \keeplig{Laufig}
+ \keeplig{Blaufi}
+ % Blaufichte Blaufilter Blaufisch
+ \keeplig{laufilter} % Planetenblaufilter
+ \keeplig{laufiedr} % blaufiedrig
+\nolig{rüfi}{rüf|i}
+ % Prüfinhalt Prüfinstitution Prüfintervall
+\nolig{Rumpfi}{Rumpf|i}
+\nolig{rumpfi}{rumpf|i}
+ % Rumpfitalien Strumpfindustrie
+ \keeplig{rumpfig}
+
+\nolig{chafi}{chaf|i} % Schaf-i...
+ % Schafimperium Schafinnereien
+ \keeplig{schafigu} % Maharadschafigur
+\nolig{chlafi}{chlaf|i} % Schlaf-i-...
+ % Schlafiglu schlafinduzierend
+ \keeplig{chlafitt} % Schlafittchen
+
+\nolig{Strafi}{Straf|i}
+\nolig{strafi}{straf|i}
+ % strafisolierend Strafinstanz
+\nolig{Tarifi}{Tarif|i}
+\nolig{tarifi}{tarif|i}
+ % (viele Fälle!)
+ \keeplig{Tarifier} % Tarifierung
+ \keeplig{tarifier} % tarifierbar
+\nolig{Tiefinn}{Tief|inn}
+\nolig{tiefinn}{tief|inn}
+ % tiefinnen -innerste -innig -innerste
+
+\nolig{fidee}{f|idee}
+ % Kopfidee Luftschiffidee
+\nolig{fideol}{f|ideol}
+ % Tiefideologie
+\nolig{fidentif}{f|identif}
+ % Stoffidentifizierung
+\nolig{fidentit}{f|identit}
+ % Steppenwolfidentität Berufidentität
+\nolig{fidol}{f|idol}
+ % Golfidol
+\nolig{fidyll}{f|idyll}
+ % Bauernhofidyll
+\nolig{figel}{f|igel}
+ % Köpfigel Stoffigel
+ \keeplig{figelehrt} % Sufigelehrter
+\nolig{fikone}{f|ikone}
+ % Laufikone
+\nolig{fillus}{f|illus}
+ % Sumpfillusion
+\nolig{fimman}{f|imman}
+ % ablaufimmanente
+\nolig{fimmob}{f|immob}
+ % Kaufhofimmobilie
+\nolig{fimmun}{f|immun}
+ % Strafimmunität
+\nolig{fimp}{f|imp}
+ % Torfimporte Kaufimpuls aufimpft
+
+\nolig{findex}{f|index}
+ % Kaufindex Pfandbriefindex
+\nolig{findikat}{f|indikat}
+ % Impfindikation
+\nolig{findiv}{f|indiv}
+ % Hofindividualität
+\nolig{findiz}{f|indiz}
+ % Tarifindizes
+\nolig{findust}{f|indust}
+ % Golfindustrie
+\nolig{finfekt}{f|infekt}
+ % Dampfinfektion
+\nolig{finfiz}{f|infiz}
+ % Laufinfizierte
+\nolig{finfo}{f|info}
+ % Tarifinformation Telefoninformation
+ \keeplig{Delfinfo}
+ % Delfinforscher -foto
+\nolig{finfra}{f|infra}
+ % Hofinfrastruktur
+\nolig{finfus}{f|infus}
+ % Tropfinfusion
+\nolig{fingenieur}{f|ingenieur}
+ % Prüfingenieur Kaufingenieur
+\nolig{finhab}{f|inhab}
+ % Hofinhaber
+\nolig{finhalat}{f|inhalat}
+ % Kamilledampfinhalationen
+\nolig{finhalt}{f|inhalt}
+ % Begriffinhalte Kropfinhalt
+ \keeplig{Delfinhalt} % Delfinhaltung
+ \keeplig{raffinhalt} % Paraffinhaltig
+\nolig{finitia}{f|initia}
+ % Korallenriffinitiative
+\nolig{finjekt}{f|injekt}
+ % Dampfinjektionsverfahren
+\nolig{finkont}{f|inkont}
+ % Ueberlaufinkontinenz
+ \keeplig{Delfinkont} % Delfinkontakt
+
+\nolig{finnenaus}{f|innenaus}
+ % Schiffinnenausbau
+\nolig{finnenohr}{f|innenohr}
+ % Schafinnenohr
+\nolig{finnenfl}{f|innenfl}
+ % Hofinnenflächen
+\nolig{finnenl}{f|innenfl}
+ % Hofinnenleben
+\nolig{finnenraum}{f|innenraum}
+ % Kopfinnenraum
+\nolig{finnenräum}{f|innenräum}
+ % Schlafinnenräumen
+\nolig{finnens}{f|innens}
+ % Rumpfinnenseite
+
+\nolig{finner}{f|inner}
+ % tiefinnerlich Kopfinneres
+\nolig{finnig}{f|innig}
+ % tiefinnige
+\nolig{finnov}{f|innov}
+ % Tarifinnovationen
+\nolig{finsass}{f|insass}
+ % Raumschiffinsassen
+\nolig{finsekt}{f|insekt}
+ % Laufinsekt
+\nolig{finsel}{f|insel}
+ % Schafinsel Schilfinsel Saufinsel
+\nolig{finserat}{f|inserat}
+ % Titelkopfinserat
+\nolig{finsign}{f|insign}
+ % Knopfinsignien
+\nolig{finspek}{f|inspek}
+ % Kirchhofinspektor
+\nolig{finsta}{f|insta}
+ % Kunstriffinstallateur
+ % Schiffinstandsetzung
+ % Strafinstanz rumpfinstabil
+\nolig{finstinkt}{f|instinkt}
+ % Zupfinstinkt
+\nolig{finstitu}{f|institu}
+ % Strafinstitutionen
+\nolig{finstrukt[io]}{f|instrukt}
+ % Wurfinstruktion Chefinstruktor
+\nolig{finstrum}{f|instrum}
+ % Zupfinstrumente Schleif- Greif-
+\nolig{finsuff}{f|insuff}
+ % Kreislaufinsuffizienz
+\nolig{finszen}{f|inszen}
+ % Kopfinszenierung
+\nolig{fintars}{f|intars}
+ % Griffintarsien
+\nolig{fintell}{f|intell}
+ % Hofintellektueller
+\nolig{fintegr}{f|integr}
+ % Tarifintegration
+\nolig{fintens}{f|intens}
+ % eingriffintensiv
+\nolig{finter}{f|inter}
+ % Feuerschiffinteressierte
+ % Begriffinterpretationen
+ % Strafinterventionen Rufintervalle
+\nolig{finton}{f|inton}
+ % Tiefintonieren
+\nolig{fintrig}{f|intrig}
+ % Briefintrige Hofintrige
+\nolig{finvent}{f|invent}
+ % Laufinventar
+\nolig{finvest}{f|invest}
+ % Anlaufinvestitition
+
+\nolig{firis}{f|iris}
+ % Sumpfiris
+\nolig{fironi}{f|ironi}
+ % tiefironisch
+\nolig{firre}{f|irre}
+ % Dorfirre
+\nolig{firru}{f|irru}
+ % Werfirrung
+
+\nolig{fisolat}{f|isolat}
+ % Strafisolator Schaumstoffisolation
+\nolig{fisolie}{f|isolie}
+ % Griffisolierung
+
+\nolig{uffax}{uf|fax}
+ % Notruffax Abruffax
+
+
+
+% 3. fl -> f-l
+% ------------
+
+\nolig{Aufl[aeiouyäöü]}{Auf|l}
+ % Must avoid catching "Aufl.".
+\nolig{aufl}{auf|l}
+ % Hundreds (thousands?!) of words
+ % However, must allow for quite a few
+ % exceptions:
+ \keeplig{auflair} % Tierschauflair
+ \keeplig{aufläche}% Anbau- Grau- Kau- ...
+ % Niveau- Plateau- Schau- Staufläche
+ \keeplig{aufliegl}% Tauflieglein
+ \keeplig{auflüssig} % Tauflüssigkeit
+ \keeplig{baufl}
+ % Modellbauflieger Weinbauflecken
+ \keeplig{Baufl} % Bauflaute
+ \nolig{bauflösen}{bauf|lösen}
+ % grobauflösend
+ \keeplig{blaufl}% blaufleckig blauflauschig
+ \nolig{blaufloch}{blauf|loch}
+ % Ablaufloch
+ \nolig{blauflog}{blauf|log}
+ % Ablauflogik
+ \keeplig{Blaufl}% Blauflügel (Libelle)
+ \keeplig{fraufl}% Frauflüge
+ \keeplig{Fraufl}
+ \keeplig{gauflöte} % Rheingauflöte
+ \keeplig{graufl}% Graufleckentest
+ \keeplig{Graufl}
+ \keeplig{onauflo} % Donauflotte
+ \keeplig{onauflu} % Donauflut Donaufluss
+ \keeplig{Moskaufl} % Moskauflug
+ \keeplig{Schauflieg}% Schaufliegen
+ \keeplig{Schaufloß} % Schaufloßfahrten
+ \keeplig{schauflöß}
+ \keeplig{Schauflug}
+ \keeplig{Schauflüg} % Schauflüge
+ \keeplig{schauflieg}
+ \keeplig{schaufloß}
+ \keeplig{schauflöß} % Wahrschauflöße
+ \keeplig{schauflug}
+ \keeplig{schauflüg}
+ \keeplig{Taufliege}
+
+
+\nolig{Briefl}{Brief|l}
+\nolig{briefl}{brief|l}
+ % lots and lots of words ...
+\nolig{Chefl}{Chef|l}
+\nolig{chefl}{chef|l}
+ % Cheflieferant -limousine -lobbyist -los
+ \keeplig{achefl}
+ % Rachefluch Einspracheflut
+ \keeplig{ichefl} % Speichefluss
+ \keeplig{schefl}
+ % Ascheflocken Tuschefleck
+ \keeplig{chefläche} % Bracheflächen
+\nolig{Dampfl}{Dampf|l}
+\nolig{dampfl}{dampf|l}
+ % Dampflanze Natriumdampflampe
+\nolig{Dorfl}{Dorf|l}
+\nolig{dorfl}{dorf|l}
+ % Dorfladen Dorflage Dorfleitplan
+ \keeplig{dorfliese} % Korridorfliesen
+ \keeplig{dorflüg} % Condorflüge
+\nolig{Fünfl}{Fünf|l}
+\nolig{fünfl}{fünf|l}
+ % fünflitrig Fünflochdüsen
+\nolig{Golfl}{Golf|l}
+\nolig{golfl}{golf|l}
+ % viele Faelle
+\nolig{Hanfl}{Hanf|l}
+\nolig{hanfl}{hanf|l}
+ % Hanfladen Hanfland Hanflegalisierung
+ \keeplig{thanflamm} % Methanflamme
+\nolig{Hofl}{Hof|l}
+\nolig{hofl}{hof|l}
+ % Hoflaborant Hoflieferant
+ \keeplig{hoflosk} % Echofloskeln
+\nolig{Huflatt}{Huf|latt}
+\nolig{huflatt}{huf|latt}
+ % Huflattich huflattichartig
+\nolig{Hufled}{Huf|led}
+\nolig{hufled}{huf|led}
+ % Huflederhautentzundung
+\nolig{Impfl}{Impf|l}
+\nolig{impfla}{impf|la}
+ % Schimpflaute
+ \keeplig{eimpflanz} % Keimpflanze
+\nolig{impfle}{impf|le}
+ % Impflegende
+ \keeplig{eimpfleg} % Heimpfleger
+ \keeplig{timpfleg} % Intimpflege
+\nolig{impflücke}{impf|lück}
+\nolig{Kampfl}{Kampf|l}
+\nolig{kampfl}{kampf|l}
+ % Kampflegende kampflüstern
+ % Wahlkampflüge
+\nolig{Kopfl[äeioöuüy]}{Kopf|l}
+\nolig{kopfl[äeioöuüy]}{kopf|l}
+\nolig{Köpfl[aäioöuüy]}{Köpf|l}
+\nolig{köpfl[aäioöuüy]}{köpf|l}
+ % Dutzende (Hunderte?) von Worten...
+ % [kK]opfla -> caught by opfla rule
+ % [kK]öpfle -> caught by öpfle rule
+ \keeplig{kopflaster}% Ökopflaster
+ \keeplig{kopfleg} % Risikopflege
+ \keeplig{kopflaum} % Schokopflaumen
+\nolig{Pfeifl}{Pfeif|l}
+\nolig{pfeifl}{pfeif|l}
+\nolig{Pfiffl}{Pfiff|l}
+\nolig{pfiffl}{pfiff|l}
+ % Pfeiflaute Pfifflaut
+\nolig{Prüfl}{Prüf|l}
+\nolig{prüfl}{prüf|l}
+ % Prüflabor Prüflast Prüflampe
+\nolig{Reliefl}{Relief|l}
+\nolig{reliefl}{relief|l}
+ % Relieflandschaft -lagen -landkarte
+ % relieflos
+\nolig{Rufl}{Ruf|l}
+\nolig{rufl}{ruf|l}
+ % viele Fälle, aber...
+ \keeplig{Durufl} % Duruflé
+ \keeplig{mbarufl} % Gambarufluss
+ \keeplig{ruflagge} % Peruflagge
+ \keeplig{rufleisch} % Kängurufleisch
+
+\nolig{Schafl}{Schaf|l}
+\nolig{schafl}{schaf|l}
+ % Schafleder Schaflaus Schafleber
+\nolig{Schiefl}{Schief|l}
+\nolig{schiefl}{schief|l}
+ % schieflachen Schieflage schieflaufen
+\nolig{Schilfl}{Schilf|l}
+\nolig{schilfl}{schilf|l}
+ % Schilflabyrinth Schilflieder
+\nolig{Schlafl}{Schlaf|l}
+\nolig{schlafl}{schlaf|l}
+ % lots and lots of words...
+\nolig{Schleifl}{Schleif|l}
+\nolig{schleifl}{schleif|l}
+ % Schleiflack Schleiflade
+\nolig{Schrumpfl}{Schrumpf|l}
+\nolig{schrumpfl}{schrumpf|l}
+ % Schrumpflack
+
+\nolig{Schweifl}{Schweif|l}
+\nolig{schweifl}{schweif|l}
+ % Schweiflecken
+\nolig{Senfl}{Senf|l}
+ % Senfladen Senfliebhaber
+\nolig{Steifl}{Steif|l}
+\nolig{steifl}{steif|l}
+ % steiflippig
+\nolig{Strafl}{Straf|l}
+\nolig{strafl}{straf|l}
+ % lots and lots of words..
+\nolig{Strumpfl}{Strumpf|l}
+\nolig{strumpfl}{strumpf|l}
+ % Strumpfladen Strumpfloch
+\nolig{Sumpfl}{Sumpf|l}
+ % Sumpflabkraut -land -ländern
+ % -leiche -licht
+ % lowercase version: allow for words that are
+ % based on Visum/Konsum/Impressum-pflicht
+\nolig{sumpfl}{sumpf|l}
+ \keeplig{nsumpfl} % konsumpflichtig
+ \keeplig{isumpfl} % visumpflichtig
+ \keeplig{ssumpfl} % impressumpflichtig
+
+\nolig{Surfl}{Surf|l}
+\nolig{surfl}{surf|l}
+ % Surflizenz Surflegende
+ \keeplig{surfleck}% Lasurfleck
+ \keeplig{surflüg} % Klausurflügel
+ \keeplig{surflüss}% Glasurflüssigkeit
+\nolig{Tarifl}{Tarif|l}
+\nolig{tarifl}{tarif|l}
+ % lots and lots of words...
+\nolig{Tiefl}{Tief|l}
+\nolig{tiefl}{tief|l}
+ % Tieflager stieflich
+ \keeplig{tiefläche} % Garantieflächen
+ \keeplig{atieflaute}% Demokratieflaute
+ \keeplig{atieflut} % Bürokratieflut
+
+\nolig{Topfl}{Topf|l}
+\nolig{topfl}{topf|l}
+ % Topflappen Topflumpen
+ \keeplig{Topflagg} % Topflaggen
+ \keeplig{Topflitz} % Topflitzer
+ \keeplig{Topflor} % Topflor
+ \keeplig{rtopfli} % portopflichtig
+ \keeplig{topfläch} % Biotopfläche
+ \keeplig{topfleg} % Autopflege
+ \nolig{rtopfleg}{rtopf|leg}
+ % Schmortopflegen
+ \keeplig{topflop} % Megatopflop
+ \keeplig{topflug} % Nonstopflug
+ \keeplig{topflüg} % Nonstopflüge
+
+\nolig{Torfl}{Torf|l}
+\nolig{torfl}{torf|l}
+ % Torflieferant Torfloch
+ \keeplig{Torflagge}
+ \keeplig{Torflügel}
+ \keeplig{Torflut}
+ \keeplig{torfläche} % Rotorfläche
+ \keeplig{torflasch} % Applikatorflasche
+ \keeplig{torflieg} % Motorfliegen
+ \keeplig{torflimm} % Monitorflimmern
+ \keeplig{torflitz} % Motorflitzer
+ \keeplig{torfloss} % Stabilisatorflossen
+ \keeplig{torflott} % Exploratorflotte
+ \keeplig{torfluch} % Auswärtstorfluch
+ \keeplig{torflug} % Simulatorflug
+ \keeplig{torflüg} % Motorflüge
+ \keeplig{torflüss} % Indikatorflüssigkeit
+ \keeplig{torfluss}
+ \keeplig{torfluß} % Motorflußschiff
+
+
+\nolig{Tropfl}{Tropf|l}
+\nolig{tropfl}{tropf|l}
+ % Tropfleckagen
+ \keeplig{tropflug} % Elektropflug
+
+\nolig{Wurfl}{Wurf|l}
+\nolig{wurfl}{wurf|l}
+ % Wurfluke Abwurfluke Einwurfluke
+\nolig{Würfl}{Würf|l}
+\nolig{würfl}{würf|l}
+ % Würflung würfle
+
+\nolig{alflede}{alf|lede}
+ % Boxcalfleder
+\nolig{aflied}{af|lied}
+ % Schlaflied
+\nolig{aflos}{af|los}
+ % straflos schlaflos
+ \keeplig{aflosk} % Propagandafloskel
+ \keeplig{rafloss} % lyraflossig
+\nolig{aflück}{af|lück}
+ % Straflücke
+\nolig{ampfl[aäou]}{ampf|l}
+ % Dampflokomotive
+ % Kampflärm Kampfluftschiff
+ \keeplig{ampfläch} % Campfläche
+ \keeplig{ampflanz} % Balsampflanzungen
+ \keeplig{ampfleg} % Teampflege
+\nolig{arflad}{arf|lad}
+ % Zeichenbedarfladen
+\nolig{äufle}{äuf|le}
+ % Häuflein träufle
+
+\nolig{eufle}{euf|le}
+ % verteufle
+ \keeplig{eufleiß} % treufleißig
+ \keeplig{eufleiss} % treufleissig
+
+\nolig{flaberer}{f|laberer}
+ % Dumpflaberer
+\nolig{flabor}{f|labor}
+ % Edelsteinprüflabor
+\nolig{flage}{f|lage}
+ % Rohstofflager Straflager Auflage
+ \keeplig{siflage} % Persiflage
+ \keeplig{ouflage} % Camouflage
+\nolig{flagun}{f|lagun}
+ % Rifflagune
+\nolig{flähm}{f|lähm}
+ % Kehlkopflähmung
+\nolig{flaminat}{f|laminat}
+ % Rumpflaminat
+\nolig{flamp}{f|lamp}
+ % Kompaktleuchtstofflampe Notruflampe
+\nolig{fland}{f|land}
+ % Hofland Kauf- Sumpf- Tief-
+ % Straflandesgericht Dorflandwirtschaft
+ % Iffland Rifflandschaft
+ % Altelfland Delfland
+ \keeplig{flandern} % Ostflandern
+ \keeplig{flandrisch}
+\nolig{fländ}{f|länd}
+ % hofländlich Sumpfländer Tiefländer
+\nolig{fläng}{f|läng}
+ % Straflänge Rumpflänge Lauflänge
+\nolig{flapp}{f|lapp}
+ % Seiflappen Topflappen
+\nolig{flärm}{f|lärm}
+ % Auspufflärm
+\nolig{fflatter}{f|flatter}
+ % Vorhofflattern aufflattert
+\nolig{flauf}{f|lauf}
+ % schieflaufen Auflauf Brieflauf
+\nolig{fläuf}{f|läuf}
+ % schiefläuft Hofläufer Strafläufe
+ % Prüfläufe Aufläufe Tiefläufer
+\nolig{flaun}{f|laun}
+ % Kauflaune Wurflaune Kampflaune
+
+\nolig{fleb}{f|leb}
+ % Hofleben Kopfleben
+ % Druckkopflebensdauer
+ \keeplig{huffleb} % shuffleboard
+\nolig{alfleder}{alf|leder} % boxcalfleder
+\nolig{flehn}{f|lehn} % steiflehnig
+ \keeplig{nflehn} % anflehn dahinflehn
+ % Seelenflehn (found in "Faust I")
+ \keeplig{rflehn} % erflehn Schwesterflehn
+ \keeplig{Hoflehn} % Hoflehner (arch.)
+\nolig{flehr}{f|lehr}
+ % Dorflehrer Eislauflehrerin
+\nolig{fleiden}{f|leiden}
+ % Kropfleidende
+\nolig{flein}{f|lein}
+ % Laufleine Scherflein Wölflein
+ % Köpflein Zöpflein
+\nolig{fleist}{f|leist}
+ % Dampfleistung Knopfleiste
+ % Kopfleiste Auswurfleistung
+ % Griffleiste Stoffleiste
+ % Abstreifleiste
+\nolig{fleit}{f|leit}
+ % Dampfleitung Hofleitung Baufhofleiter
+ % Kaufleitung Notrufleitung aufleiten
+ % inbegriffleitend Kraftstoffleitung
+ \keeplig{Kaltefleiter} % a surname...
+\nolig{flektür}{f|lektür}
+ % Schenkelklopflektüre
+\nolig{fler}{f|ler}
+ % Freiberufler Löffler Büffler Schnüffler Höfler
+ \keeplig{Hoefler} % famous American font designer
+ \keeplig{Knoepffler}
+ \keeplig{fflerhyth} % Shufflerhythmus
+\nolig{fleut}{f|leut}
+ % Hofleute Kaufleute
+
+\nolig{flich}{f|lich}
+ % tariflich reiflich glimpflich ...
+ % (Viele Wörter!)
+ %% Vorsicht aber mit Pflicht und pflicht,
+ %% sowie mit einflicht, verflicht, etc.:
+ \keeplig{flicht}
+ \nolig{öpflicht}{öpf|licht}
+ % kröpflicht (??)
+
+\nolig{flieb}{f|lieb}
+ % freiberufliebend riffliebend
+\nolig{flief}{f|lief}
+ % schieflief Hoflieferant
+\nolig{flift}{f|lift}
+ % Sattelkopflift
+\nolig{flig}{f|lig}
+ % schweflig würflig knifflig mufflig
+ % zweigipflig fünfzipflig
+\nolig{flila}{f|lila}
+ % tieflila stumpflila
+\nolig{flinde}{f|linde}
+ % Dorflinde Wolflinde Ziegelhoflinde
+ % krampflindernd
+\nolig{fling}{f|ling}
+ % Prüfling Fünfling Sträfling Täufling
+ \keeplig{Bempfling} % Bempflingen
+ \keeplig{Haflinge} % Haflinger Haflingergestüt
+\nolig{flini}{f|lini}
+ % Wurflinie Straflinie Rumpflinie
+\nolig{flinse}{f|linse}
+ % Fünflinser Wegwerflinsen
+\nolig{flisch}{f|lisch}
+ % teuflisch Tüpflischeißer
+\nolig{flist}{f|list}
+ % Prüfliste Rufliste Kaufliste
+\nolig{fliter}{f|liter}
+ % Hofliteratur Fünflitermotor
+\nolig{flizenz}{f|lizenz}
+ % Radfahrprüflizenz
+
+\nolig{flobby}{f|lobby}
+ % Maulwurflobbyisten
+\nolig{flöch}{f|löch}
+ % Sturmwurflöcher Knopflöcher
+ % Sufflöcher Grifflöcher
+ \keeplig{flöchte}
+\nolig{flöff}{f|löff}
+ % Tieflöffelbagger auflöffeln
+ % Schöpflöffel
+\nolig{flohn}{f|lohn}
+ % Tariflohn Tieflohnland
+ \keeplig{flohnetz} % Wasserflohnetz
+ \keeplig{ntflohn} % entflohn (Faust I [!])
+\nolig{flöhn}{f|löhn}
+ % Tariflöhne
+\nolig{flok}{f|lok}
+ % Dampflokomotive dampflokartig
+ % Dorflokal Trefflokal
+\nolig{flord}{f|lord}
+ % Wolflord
+\nolig{flösch}{f|lösch}
+ % Hoflöschmaschine
+\nolig{flösu}{f|lösu}
+ % Schmierseiflösung
+
+\nolig{fluft}{f|luft}
+ % Auspuffluft
+\nolig{flung}{f|lung}
+ % Verzweiflungsakt Verteuflung Stafflung
+\nolig{flust}{f|lust}
+ % Kampflust Impflust kauflustig Rauflust
+
+\nolig{Gipfle}{Gipf|le}
+\nolig{gipfle}{gipf|le}
+ % gipfle
+
+\nolig{chopfl}{chopf|l}
+ % Schopflilie Schopflavendel
+
+\nolig{lflady}{lf|lady}
+ % Golflady
+\nolig{lflast}{lf|last}
+ % Wolflast
+
+\nolig{lflos}{lf|los}
+ % hilflos
+ \keeplig{lfloss}
+ % Walflosse Kiel- Paddel-
+ \keeplig{lflosk}
+ % Moralfloskel Sozial- Spiel-
+
+\nolig{nflehm}{nf|lehm}
+ % Hanflehm
+
+\nolig{oflad}{of|lad}
+ % Biohofladen
+\nolig{ofläd}{of|läd}
+ % Biohofläden
+\nolig{oflück}{of|lück}
+ % Vorhoflücke
+
+\nolig{opfla}{opf|la}
+ % Topflappen Kopflaus kopflastig
+ \keeplig{gopflaum} % Mangopflaumen
+ \keeplig{iopflast} % Biopflaster
+ \keeplig{nopflaster}% Kinopflaster
+ \keeplig{opflair} % Popflair
+ \keeplig{opflanz} % Kakaopflanzen
+\nolig{öpfle}{öpf|le}
+ % köpfle tröpfle Knöpfle
+\nolig{orflad}{orf|lad}
+ % Dorfladen
+
+\nolig{pflaut}{pf|laut}
+ % Kehlkopflaut
+\nolig{pfleier}{pf|leier}
+ % Zupfleier
+\nolig{pflehm}{pf|lehm}
+ % Stampflehm
+\nolig{pfleis}{pf|leis}
+ % Knopfleise
+\nolig{pfleu}{pf|leu}
+ % Natriumdampfleuchten Kopfleuchte
+\nolig{pflid}{pf|lid}
+ % Schlupflid
+\nolig{pflied}{pf|lied}
+ % Kampflied
+\nolig{pfloch}{pf|loch}
+ % Knopfloch
+\nolig{pflos}{pf|los}
+ % kampflos kopflos
+ \keeplig{pfloss} % Pappflossen
+\nolig{pflös}{pf|lös}
+ % krampflösend Hüftkopflösung
+\nolig{pflup}{pf|lup}
+ % Kopflupe
+\nolig{pflux}{pf|lux}
+ % Hüftkopfluxation
+
+\nolig{rfläd}{rf|läd}
+ % Dorfläden Surfläden Schulbedarfläden
+\nolig{rflück}{rf|lück}
+ % Sturmwurflücken
+\nolig{rfluke}{rf|luke}
+ % Abwurfluke Einwurfluke
+
+\nolig{reifl}{reif|l}
+\nolig{Reifl}{Reif|l}
+ % Greiflippe Stegreiflieder Streiflacher
+ \keeplig{Breifl}
+ \keeplig{breifl}
+ \keeplig{Dreifl}
+ \keeplig{dreifl}
+ \keeplig{Freifl}
+ \keeplig{freifl}
+ \keeplig{eiereifl} % Meiereiflügel
+ \keeplig{reifläch} % Freiflächen
+ \keeplig{reiflagg} % Reedereiflagge
+ \keeplig{reiflamm} % dreiflammig
+ \keeplig{reiflasch}% Milchbreiflaschen
+ \keeplig{reiflies} % Fleischereifliesen
+ \keeplig{reiflock} % Breiflocken
+ \keeplig{reifloh} % Büchereiflohmarkt
+ \keeplig{reiflöhe} % Gießereiflöhe
+ \keeplig{reiflott} % Fischereiflotte
+
+\nolig{Tafle}{Taf|le}
+\nolig{tafle}{taf|le}
+ % tafle
+ \keeplig{tafleck} % Zahnpastaflecken
+ \keeplig{taflege} % Regattaflegel
+
+\nolig{urflad}{urf|lad}
+ % Surfladen
+\nolig{ürfla}{ürf|la}
+ % Schlürflaut Schürflader
+
+\nolig{urfloch}{urf|loch}
+ % Balleinwurfloch
+\nolig{ürfloch}{ürf|loch}
+ % Schürfloch
+
+\nolig{wafle}{waf|le}
+ % schwafle
+\nolig{wefle}{wef|le}
+ % schwefle
+\nolig{weifle}{weif|le}
+ % bezweifle verzweifle
+ \keeplig{weifleck} % zweifleckig
+\nolig{werfl}{werf|l}
+ % Wegwerflied
+ \keeplig{chwerfl}
+ % Schwerflugzeug schwerfließend
+ \keeplig{werflitz} % Powerflitzer
+
+
+
+
+% 4. ffi -> f-fi
+% --------------
+
+\nolig{affind}{af|find}
+ % Straffindung
+ \keeplig{araffind} % Paraffinduft
+
+\nolig{ffibel}{f|fibel}
+ % Zwiebelknopffibeln
+\nolig{ffieb}{f|fieb}
+ % Sumpffieber Wahlkampffieber
+\nolig{ffigu}{f|figu}
+ % Streiffigur
+\nolig{ffilm}{f|film}
+ % Werwolffilm
+\nolig{ffilter}{f|filter}
+ % Tropffilter Topffilter
+\nolig{ffinal}{f|final}
+ % Hammerwurffinale
+\nolig{ffinte}{f|finte}
+ % Sprungwurffinte
+ \keeplig{raffinte} % Paraffintest
+\nolig{ffinanz}{f|finanz}
+ % Hoffinanz Kauffinanzierung
+\nolig{ffistel}{f|fistel}
+ % Kropffistel
+\nolig{ffixier}{f|fixier}
+ % Dampffixiergerät
+
+%%\nolig{hoffing}{hof|fing}
+ % No need to suppress ffi ligature in
+ % Bischoffingen and Bischoffinger!
+
+\nolig{iffind}{if|find}
+ % Tariffindung
+
+\nolig{lffing}{lf|fing}
+ % Zwölffingerdarm
+\nolig{lffisch}{lf|fisch}
+ % Wolffisch
+
+\nolig{nffing}{nf|fing}
+ % fünffingrig Fünffingergebirge
+
+\nolig{pffi}{pf|fi}
+ % Kopffilm Wahlkampffinanzierung
+ % Schlangenkopffisch Kampffisch
+
+\nolig{reiffing}{reif|fing}
+ % Greiffinger
+
+
+
+% 5. ffi -> ff-i
+% --------------
+
+\nolig{Stoffi}{Stoff|i}
+\nolig{stoffi}{stoff|i}
+ % Rohstoffindustrieller -importe
+ % Baustoffingenieur Kunststoffingenieur
+ % Kohlenstoffisotope
+ \keeplig{stoffiz}
+ % Geheimdienstoffiziere
+ \keeplig{stoffig}
+ % permit ffi ligature for ff-ig suffix
+
+\nolig{ffinnen}{ff|innen}
+ % Schiffinnenraum Schiffinnenausbau
+
+
+% 6. ffl -> ff-l
+% --------------
+
+\nolig{Griffl}{Griff|l}
+\nolig{griffl}{griff|l}
+ % Grifflängen -laschen -leiste
+ % grifflos angrifflustig
+\nolig{Offline}{Off|line}
+\nolig{offline}{off|line}
+ % offline, Offline
+\nolig{Pfiffl}{Pfiff|l}
+ % Pfifflaute
+\nolig{Scheffle}{Scheff|le}
+\nolig{scheffle}{scheff|le}
+ % Scheffler Geldscheffler
+\nolig{Schiffl}{Schiff|l}
+\nolig{schiffl}{schiff|l}
+ % Schifflache Schiffladung Schifflinie
+\nolig{Stoffl}{Stoff|l}
+\nolig{stoffl}{stoff|l}
+ % lots of words...
+
+\nolig{afflu}{aff|lu}
+ % Gafflust
+
+\nolig{fflamell}{ff|lamell}
+ % Rafflamellen
+\nolig{fflast}{ff|last}
+ % Rohstofflastigkeit Treibstofflaster
+\nolig{fflatsch}{ff|latsch}
+ % Rifflatschern
+\nolig{ffloch}{ff|loch}
+ % Suffloch Griffloch Sauerstoffloch
+\nolig{fflos}{ff|los}
+ % auspufflos
+
+\nolig{ifflo}{iff|lo}
+ % Schifflogbuch grifflos Griffloch
+
+\nolig{offlad}{off|lad}
+ % Sprengstoffladung
+\nolig{öffle}{öff|le}
+ % löffle
+\nolig{offlo}{off|lo}
+ % wirkstofflos Sauerstoffloch
+ % offload
+
+\nolig{pufflack}{puff|lack}
+ % Auspufflack
+
+\nolig{taffle}{taff|le}
+ % staffle
+
+\nolig{ufflad}{uff|lad}
+ % Suffladen
+\nolig{uffläd}{uff|läd}
+ % Suffläden
+\nolig{luffleck}{luff|leck}
+ % Bluffleck
+\nolig{äfle}{äf|le}
+ % Schäfle
+\nolig{üffle}{üff|le}
+ % schnüffle büffle trüffle
+%%%\nolig{ufflon}{uff|lon}
+ %%% Mufflon
+
+
+
+% 7. ffl -> f-fl
+% --------------
+
+\nolig{Auffl}{Auf|fl}
+\nolig{auffl}{auf|fl}
+ % aufflackern aufflammen Aufflickung
+ % Auffliegen
+
+\nolig{eiffleck}{eif|fleck}
+ % Schleifflecklein
+
+\nolig{ffläch}{f|fläch}
+ % Lauffläche Kampfflächen
+ % Zwölfflächner zwölfflächig
+\nolig{fflech}{f|flech}
+ % aufflechten
+\nolig{ffleisch}{f|fleisch}
+ % Schaffleisch Kopffleisch
+\nolig{fflexib}{f|flexib}
+ % Tarifflexibilitat
+\nolig{fflies}{f|flies}
+ % Relieffliesen
+\nolig{fflimm}{f|flimm}
+ % Vorhofflimmern
+\nolig{ffluch}{f|fluch}
+ % Tarifflucht Werwolffluch
+\nolig{fflüch}{f|flüch}
+ % Tarifflüchtling
+\nolig{fflug}{f|flug}
+ % Tiefflug Kampfflugzeug Chefflugleiter
+\nolig{fflüg}{f|flüg}
+ % Streifflüge zwölfflügelig Tiefflüge
+\nolig{fflur}{f|flur}
+ % Klosterhofflur
+\nolig{ffluss}{f|flus}
+ % Prüffluss
+\nolig{fflüs}{f|flüs}
+ % Schleifflüsigkeit}
+\nolig{fflut}{f|flut}
+ % Brieffluten Rückrufflut Anrufflut
+
+\nolig{iefflieg}{ief|flieg}
+ % tieffliegend
+\nolig{iefflog}{ief|flog}
+ % tiefflog
+
+\nolig{lfflach}{lf|flach}
+ % Zwölfflach
+
+\nolig{mpffl}{mpf|fl}
+\nolig{opffl}{opf|fl}
+\nolig{upffl}{upf|fl}
+ % Sumpffläche Sturzkampfflieger
+ % Impfflüssigkeit
+ % Totenkopfflagge
+ % Hupfflug
+
+\nolig{rfflad}{rf|flad}
+ % Torffladen
+\nolig{rfflasch}{rf|flasch}
+ % Wegwerfflasche
+
+%%\nolig{ufflot}{uff|lot}
+ % originally meant to capture "Sufflot"
+ %% But: - Jacques-Germain Soufflot (1713-80)
+ %% "Rue Soufflot" in Paris, sometimes
+ %% mis-spelled as "Rue Sufflot"
+
+\nolig{wurfl}{wurf|l}
+ % Freiwurflinie Maulwurflobbyist
+
+
+
+
+% 8. ft -> f-t
+% ------------
+
+\if@noftligs
+ \nolig{ft}{f|t} % "ft"-Ligatur global unterdrücken
+\else % "ft"-Ligatur selektiv unterdrücken
+ \nolig{Auft[aähioöruüy]}{Auf|t}
+ \nolig{auft[aähioöruüy]}{auf|t}
+ % (viele viele Fälle)
+ % Aber: ft-Ligatur wird doch verwendet für "Auft.")
+
+ \nolig{Brieft}{Brief|t}
+ \nolig{brieft}{brief|t}
+ % Brieftasche Brieftaube
+ \nolig{Cheft}{Chef|t}
+ \nolig{cheft[a-z]}{chef|t}
+ % Cheftheoretiker Cheftrainer
+ \keeplig{omicheft[ceg]}
+ \nolig{Dorft}{Dorf|t}
+ \nolig{dorft}{dorf|t}
+ % Dorftrottel -tratsch -tümpel
+ \nolig{Elfte}{Elf|te}
+ \nolig{elfte}{elf|te}
+ % elfte elftens
+ \keeplig{elfterfolg} % elfterfolgreichste
+
+ \nolig{Fünft[aäeoöruy]}{Fünf|t} % Fünftagewoche ...
+ \nolig{fünft[aäeoöruy]}{fünf|t} % fünftens...
+ \keeplig{fünfterfolg} % fünfterfolgreichste
+ \keeplig{Fünfterfolg}
+ \keeplig{fünftrang} % fünftrangig
+ \keeplig{Fünftrang}
+ \keeplig{fünftreich} % fünftreichste
+ \keeplig{Fünftreich}
+ \keeplig{Fünftoper} % Fünftoperation
+ \keeplig{Fünftrund} % Fünftrunden
+ \keeplig{Fünftäon}
+ \keeplig{fünftältest}
+ \keeplig{Fünftältest}
+
+ \nolig{Golft}{Golf|t}
+ \nolig{golft[hiruüy]}{golf|t}
+ % Golfträume -turnier -typ -talent
+
+ \nolig{Greift[eio]}{Greif|t}
+ % Greiftest -tentakeln -tier -tor
+ \nolig{Hanftau}{Hanf|tau}
+ % Hanftau
+ % aber: ft-Lig. OK im Familienname "Hanftaler"
+ \nolig{Hoft[aäehioäruüy]}{Hof|t}
+ \nolig{hoft[aähioöruü]}{hof|t}
+ % Hoftor Klosterhoftor
+
+ \nolig{Huftra}{Huf|tra}
+ % Huftragrand(es)
+
+ \nolig{Kopft[aäehioäruüy]}{Kopf|t}
+ % Kopfteil Kopftetanus Kopftreffer Kopftyp
+
+ \nolig{Laufte}{Lauf|te}
+ % Lauftermin Lauftest Lauftext
+ \nolig{Prüft[aähioäruüy]}{Prüf|t}
+ \nolig{prüft[aähioöruü]}{prüf|t}
+ % Prüftheorie
+ \nolig{Ruft[aäehioäruüy]}{Ruf|t}
+ % Ruftaxi Rufterz Rufton Ruftöne
+
+ \nolig{Schaftal}{Schaf|tal} % Schaftalg, Schaftal
+ \nolig{Schaftor}{Schaf|tor}
+ \nolig{Schaftreib}{Schaf|treib}
+ \nolig{schaftal}{schaf|tal}
+ \nolig{schaftor}{schaf|tor}
+ \nolig{schaftreib}{schaf|treib}
+
+ \nolig{Schlaft}{Schlaf|t}
+ \nolig{schlaft[aähioäruüy]}{schlaf|t}
+ % Schlaftablette
+ \nolig{Schilft[äehiruüy]}{Schilf|t}
+ \nolig{schilft[hiruüy]}{schilf|t}
+ % Schilfteich Schlilftümpel
+ \nolig{Senft[aäehioäruy]}{Senf|t}
+ % Senftube
+ \keeplig{Senftenberg}
+ \nolig{Straft[aähioöruüy]}{Straf|t}
+ \nolig{straft[aähioöruüy]}{straf|t}
+ % (viele Fälle)
+ \keeplig{straftheit} % Unbestraftheit
+ \nolig{Sufft}{Suff|t}
+ % Sufftest Sufftext
+ \nolig{Surft[ähiöüy]}{Surf|t}
+ % Surfthema Surftipp
+ \nolig{Tarift}{Tarif|t}
+ \nolig{tarift}{tarif|t}
+ % Tarifthemen Tariftabelle
+ \nolig{Tieft}{Tief|t}
+ % Tieftänzer -träumen -tresor -tunnel
+ \nolig{Torft}{Torf|t}
+ \nolig{torft}{torf|t}
+ % Torftabletten Torftaucher Torftoilette
+ \nolig{Wurft}{Wurf|t}
+ \nolig{wurft}{wurf|t}
+ % Wurftalent Wurftaler
+
+ \nolig{fft[aähioöruüy]}{ff|t}
+ % Stofftasche Sauerstofftank Stofftheorie
+ % Stofftier Stofftiger Stofftischtuch
+ % Auspufftopf Kunststofftonne
+ % Stofftradition Stofftrennung
+ % Kunststofftube Stoffturnschuhe
+ % Stofftäschchen Auspufftöpfe
+ % Kunststofftöpfe Kunststofftüten
+
+ %% Words that start with a capital letter
+ %% and end in f-test
+ \nolig{Abstreiftest}{Abstreif|test}
+ \nolig{Ankauftest}{Ankauf|test}
+ \nolig{Hörprüftest}{Hörprüf|test}
+ \nolig{Hüpftest}{Hüpf|test}
+ \nolig{Impftest}{Impf|test}
+ \nolig{Kauftest}{Kauf|test}
+ \nolig{Klopftest}{Klopf|test}
+ \nolig{Kneiftest}{Kneif|test}
+ \nolig{Lichtschweiftest}{Lichtschweif|test}
+ \nolig{Rückruftest}{Rückruf|test}
+ \nolig{Schnupftest}{Schnupf|test}
+ \nolig{Sumpftest}{Sumpf|test}
+ \nolig{Tropftest}{Tropf|test}
+ \nolig{Wettkampftest}{Wettkampf|test}
+ \nolig{tofftest}{toff|test}
+ % Impfstofftest Treibstofftests
+
+ \nolig{aftee}{af|tee}
+ % Schlaftee
+ \nolig{auftee}{auf|tee}
+ % Kreislauftee
+ \nolig{lauftest}{lauf|test}
+ % Kreislauftest
+
+ \nolig{eiftie}{eif|tie}
+ % Greiftiefe Steiftier
+ \nolig{eiftit}{eif|tit}
+ % Eingreiftitel
+ \nolig{eiftr}{eif|tr}
+ % Eingreiftruppe Nadelstreifträger
+ % Greiftrupp -tier -training
+ \nolig{elieft}{elief|t}
+ % Relieftäfelchen -tropfen -türme
+ \nolig{enftei}{enf|tei}
+ % Senfteig
+
+ \nolig{ftabell}{f|tabell}
+ % Ruftabelle
+ \nolig{ftablett}{f|tablett}
+ % Schlaftabletten
+ \nolig{ftafel}{f|tafel}
+ % Pfeiftafel
+ \nolig{ftag}{f|tag}
+ % Tauftag Fünftagewoche
+ \keeplig{ftagent} % Luftagentur
+ \nolig{ftäg}{f|täg}
+ % fünftägig elfftägig zwölftägig
+ \nolig{ftalsg}{f|talsg}
+ % schaftalsgrundig
+ \nolig{ftanz}{f|tanz}
+ % Kampftanz Schilftanz
+ \keeplig{ftanzahl} % Heftanzahl
+ \keeplig{ftanzeig} % Luftanzeige
+ \keeplig{ftanzieh} % Schwerkraftanziehung
+ \keeplig{ftanzüg} % Haftanzüge
+ \nolig{ftänz}{f|tänz}
+ % Tieftänzer
+ \nolig{ftari}{f|tari}
+ % Anruftarif
+ \keeplig{ftaristokr} % Zunftaristokratie
+ \nolig{ftarn}{f|tarn}
+ % Wegwerftarnungen
+ \nolig{ftasse}{f|tasse}
+ % Schürftasse
+ \keeplig{ftassel} % Gruftasseln
+ \nolig{ftatb}{f|tatb}
+ % Straftatbestände
+ \nolig{ftaten}{f|taten}
+ % Kampftaten Straftaten
+ \nolig{ftätig}{f|tätig}
+ % Schürftätigkeit
+ \nolig{ftauch}{f|tauch}
+ % Beruftaucher Kreislauftauchgerät
+ \nolig{ftaugl}{f|taugl}
+ % prüftauglich
+ \nolig{ftaume}{f|taume}
+ % Nachruftaumel
+ \nolig{ftax}{f|tax}
+ % Ruftaxi
+
+ \nolig{fteam}{f|team}
+ % Jugendtreffteam Impfteam
+ \keeplig{fteamt} % Streitkräfteamt
+ \nolig{ftechn}{f|techn}
+ % Stampftechnik schlaftechnisch
+ % Kraftstofftechnologie Pfeiftechnik
+ \nolig{ftedd}{f|tedd}
+ % Schlafteddy
+ \nolig{fteich}{f|teich}
+ % Schilfteich Dorfteich
+ \keeplig{nfteich} % Zunfteiche
+ \keeplig{ifteich} % Schrifteiche
+ \nolig{fteigw}{f|teigw}
+ % Dampfteigwaren
+ \nolig{fteil}{f|teil}
+ % fünfteilig Friedhofteil
+ % Raumschiffteil Riffteil Stoffteil
+ \keeplig{fteilfr} % Lufteilfracht
+ \nolig{ftelef}{f|telef}
+ \nolig{fteleph}{f|teleph} % old spelling...
+ % Wegwerftelefon Notruftelefonnummern
+ \nolig{ftelegr}{f|telegr} % Aufruftelegramm
+ \nolig{fteller}{f|teller}
+ % Schiefteller
+ \nolig{ftempel}{f|tempel}
+ % Kauftempel
+ \nolig{ftemper}{f|temper}
+ % Schlaftemperatur
+ \nolig{ftempo}{f|tempo}
+ % Dauerlauftempo
+ \nolig{ftendenz}{f|tendenz}
+ % Klassenkampftendenz
+ \nolig{ftentak}{f|tentak}
+ % Greiftentakeln
+ \nolig{fteppi}{f|teppi}
+ % Schaumstoffteppich Knüpfteppich
+ \nolig{ftermin}{f|termin}
+ % Anpfifftermin Passagierschiffterminal
+ \keeplig{fterminder}
+ % Gesellschafterminderheiten
+ \nolig{ftermit}{f|termit}
+ % Kampftermiten
+ \keeplig{ftermitt} % Rauschgiftermittler
+ \nolig{fterrain}{f|terrain}
+ % Kampfterrain
+ \nolig{fterrass}{f|terrass}
+ % Tuffterrassen
+ \nolig{fterrin}{f|terrin}
+ % Kohlkopfterrine
+ \nolig{fterror}{f|terror}
+ % Schadstoffterror
+ \nolig{ftestat}{f|testat}
+ % Prüftestate
+ \keeplig{ftestation}
+ % Streitkräftestationierung
+ \keeplig{ftestatist}
+ % Lehrkräftestatistik
+ \nolig{fteuf}{f|teuf}
+ % Dorfteufel Saufteufel
+ \nolig{ftext}{f|text}
+ % Betrefftext Stofftextur Stegreiftexte
+ \keeplig{ftextrakt} % Duftextrakt
+
+ \nolig{ftheat}{f|theat}
+ % Stegreiftheater
+ \nolig{fthem}{f|them}
+ % Wolfthema
+ \keeplig{fthemm} % Wirtschafthemmnis
+ \nolig{ftheor}{f|theor}
+ % -f-theorie -f-theorien
+ \nolig{ftherap}{f|therap}
+ % Impftherapie Wurftherapie
+ % Schröpftherapeut
+ \nolig{ftick}{f|tick}
+ % Rückruftickets Diskuswurfticket
+ \nolig{ftief}{f|tief}
+ % tieftief (?)
+ \keeplig{ftiefigur} % Softiefigur
+ \nolig{ftier}{f|tier}
+ % Wegwerftier Huftier
+ \keeplig{haftier} % inhaftieren
+ \keeplig{Muftier} % Muftierben
+ \nolig{ftipp}{f|tipp}
+ % Surftipp
+ \nolig{ftirad}{f|tirad}
+ % Schimpftirade
+ \nolig{ftisch}{f|tisch}
+ % Schleiftisch
+ \keeplig{stiftisch} % hochstiftisch
+ \keeplig{ünftisch} % zünftisch
+
+ \nolig{ftod}{f|tod}
+ % Hanftod
+ \keeplig{ftodem} % Giftodem
+ \nolig{fton}{f|ton}
+ % Pfeifton Zwölftonmusik Rufton
+ \nolig{ftön}{f|tön}
+ % Pfeiftöne Ruftöne
+ \nolig{ftool}{f|tool}
+ % Prüftool
+ \nolig{ftopf}{f|topf}
+ % Schleiftopf Dampf- Auspuff- Schöpf-
+ \keeplig{ftopfer}
+ % Duftopfer Gift- Haft-
+ \nolig{ftöpf}{f|töpf}
+ % Senftöpfchen Torftöpfchen
+ % Kunststofftöpfe
+ \nolig{ftorig}{f|torig}
+ % schaftorig fünftorig
+ \nolig{ftour}{f|tour}
+ % Streiftour
+
+ \nolig{ftrader}{f|trader}
+ % Cheftrader
+ \nolig{ftradition}{f|tradition}
+ % Ruftraditionen
+ \nolig{fträg}{f|träg}
+ % Notrufträger
+ \nolig{ftrain}{f|train}
+ % Lauftrainer
+ \nolig{ftränk}{f|tränk}
+ % Rückruftränke Schaftränke
+ \nolig{ftransp}{f|transp}
+ % Hilftransport Schaftransport
+ \nolig{fträume}{f|träume}
+ % tiefträumend Tiefschlafträume
+ \keeplig{afträume} % Einzelhafträumen
+ \keeplig{äfträume} % Geschäfträumen
+ \keeplig{rifträume}% Schrifträume
+ \keeplig{ufträume} % Lufträumen
+ \nolig{ftrauri}{f|traurig}
+ % tieftraurig
+ \nolig{ftreff}{f|treff}
+ % Notruftreffen
+ \nolig{ftresor}{f|tresor}
+ % Tieftresor
+ \keeplig{ftresorp} % Luftresorption
+ \nolig{ftret}{f|tret}
+ % Mieftreter
+ \keeplig{ftrett} % Luftrettungsdienst
+ \keeplig{ftreturn}% Softreturn
+ \nolig{ftrick}{f|trick}
+ % Rückruftricks
+ \nolig{ftrieb}{f|trieb}
+ % auftriebte schaftriebig
+ \nolig{ftrief}{f|trief}
+ % tieftriefend
+ \nolig{ftrift}{f|trift}
+ % schaftriftig Schaftrift
+ \nolig{ftrimest}{f|trimest}
+ % fünftrimestrig zwölftrimestrig
+ \nolig{ftritt}{f|tritt}
+ % Huftritte
+ \keeplig{ftritter} % Kernkraftritter
+ \keeplig{Luftritt}
+ \nolig{ftrott}{f|trott}
+ % Sauftrottel
+
+ \nolig{ftrüb}{f|trüb}
+ % tieftrübe
+ \nolig{ftrunk}{f|trunk}
+ % schlaftrunken
+ \nolig{ftrupp}{f|trupp}
+ % Prüftruppe
+
+ \nolig{ftuch}{f|tuch}
+ % Schnieftuch Kopftuch
+ \nolig{ftüch}{f|tüch}
+ % Schnieftücher
+ \nolig{ftürk}{f|türk}
+ % tieftürkis
+ \nolig{fturm}{f|turm}
+ % Wolfturm
+ \nolig{ftürm}{f|türm}
+ % Wolftürme
+
+ \nolig{ftyp}{f|typ}
+ % Schifftyp Stofftyp waldorftypisch
+ \nolig{ftyr}{f|tyr}
+ % Dorftyrann Hoftyrann
+ \nolig{ftwist}{f|twist}
+ % Kopftwister
+
+ \nolig{graftum}{graf|tum}
+ % Burggraftum Markgraftum
+ \nolig{graftüm}{graf|tüm}
+ % Markgraftümer
+
+ \nolig{hoftest}{hof|test}
+ % Schlachthoftest
+
+ \nolig{iefta}{ief|ta}
+ % Tieftaucher Brieftasche Brieftaube
+ \nolig{iefto}{ief|to}
+ % Stieftochter Tiefton
+ \nolig{ieftö}{ief|tö}
+ % Stieftöchter tieftönend
+ \nolig{ieftra}{ief|tra}
+ % Tieftraumphase
+
+ \nolig{lfta}{lf|ta}
+ % elftausend zwölftausend Golftasche
+ \nolig{lfto}{lf|to}
+ % Zwölftonmusik Elftonner Golftour
+ \nolig{lftö}{lf|tö}
+ % zwölftönend
+ \nolig{lftum}{lf|tum}
+ % Werwolftum
+
+ \nolig{nftü}{nf|tü}
+ % fünftürig Senftüte
+ \keeplig{nftüb}
+ % Vernunftüberlegung zunftüblich
+ \nolig{nftübchen}{nf|tübchen}
+ % Senftübchen
+
+ \nolig{ölfte}{ölf|te}
+ % zwölfte zwölftens
+
+ \nolig{pft[aähioöruüy]}{pf|t}
+ % Wettkampftag -trubel -tauglich -töne
+ % Kampftaktik -truppe -tätigkeit -tänzer
+ % Schnupftabak -tuch -tücher -tüchlein
+ % Schimpftiraden Mehrkampftitel
+ % Stapftiefe Zopfträger
+ % Dampftopf Sumpftour Herzklopftöne
+ % Kopftreffer -tuch -tücher
+ % Impftabelle -tarif -tierarzt -tod
+ \keeplig{pftheit}
+ % Gedämpftheit Umkämpftheit
+ \nolig{pftee}{pf|tee}
+ % Schlumpftee (?!)
+ \nolig{pfteig}{pf|teig}
+ % Sumpfteig Hefetropfteig
+ \nolig{pftender}{pf|tender}
+ % Heißdampftenderlok
+
+ %\nolig{rftrag}{rf|trag}
+ % Wegwerftragtasche Dorftragödie
+
+ \nolig{rftr}{rf|tr}
+ % Wurftraining Surftrip Freiwurftreffer
+ \keeplig{tdurftrö} % Notdurftröhre
+ \keeplig{Werftr} % Werftreparatur
+ \keeplig{werftr}
+ \nolig{werftrage}{werf|trage}
+ % Wegwerftragetasche
+ \nolig{rftu}{rf|tu}
+ % Wurftuch
+ \keeplig{Werftu}
+ \keeplig{werftu}
+ % Werftumfeld Werftunternehmen
+
+ \nolig{uftas}{uf|tas}
+ % Ruftaste Vorlauftaste Kauftasche
+ \keeplig{Duftas} % Duftaspekte
+ \keeplig{duftas}
+ \keeplig{Gruftas} % Gruftassel
+ \keeplig{gruftas}
+ \keeplig{Luftas} % Luftasket
+ \keeplig{luftas}
+ \keeplig{uftassoz}
+ % Duftassoziationen Schuftassoziationen
+
+ \nolig{urfta}{urf|ta}
+ % Wurftalent Auswurftaste Surftalent
+ \keeplig{tdurfta} % Notdurftanlage
+ \nolig{urfto}{urf|to}
+ % Freiwurftor Surftour
+
+ \nolig{ünftor}{ünf|tor}
+ % fünftorig Fünftore-Vorsprung
+
+\fi % end of \if@noftligs condition
+
+
+% 9. fb -> f-b, fh -> f-h, fk -> f-k
+% ----------------------------------
+
+% Disable these ligatures globally.
+% I can't think of a single *German* word
+% for which these ligatures would not
+% cross a morpheme boundary.
+
+\nolig{fb}{f|b}
+\nolig{fh}{f|h}
+\nolig{fk}{f|k}
+
+ % However, there are names of *non-German*
+ % origin for which the 'fk' ligature
+ % shouldn't be suppressed:
+ \keeplig{Kafka}
+ \keeplig{kafka}
+ \keeplig{Piefke}
+ \keeplig{piefkei} % Ostpiefkei
+ \keeplig{Safka}
+ \keeplig{Potrafke}
+ \keeplig{Sprafke}
+ \keeplig{Shirafkan}
+ \keeplig{Tirafkan}
+ \keeplig{Selfkant}
+ \keeplig{Rifkin}
+
+
+% 10. fj -> f-j
+% -------------
+
+% Suppress this ligature globally. Words
+% of German origin seem to feature 'fj'
+% only across morpheme boundaries.
+
+\nolig{fj}{f|j}
+ % aufjauchzen aufjaulen fünfjährig Kampfjet
+ % Strafjustizgebäude Dorfjugend Kopfjäger ...
+
+ % Once more, though, there are some words of
+ % *non-German* (e.g., Nordic and Slavic)
+ % origin for which the 'fj' ligature should
+ % not be suppressed. Use \keeplig macros to
+ % treat such cases.
+ \keeplig{fjord} % Norwegian
+ \keeplig{fjör} % Icelandic, e.g.,
+ % Isafjördur and Ãsafjörður
+ \keeplig{Ãsafjarðarbær} % city in Iceland
+ \keeplig{fjell} % Norwegian
+ \keeplig{fjall} % Swedish (?)
+ \keeplig{fjäll}
+ \keeplig{fjöll}
+
+ \keeplig{Prokofjew}
+ \keeplig{Sufjan} % Stevens
+ \keeplig{Eefje} % Dutch first name
+ \keeplig{Astafjew} % Wiktor, Maksim, ...
+
+
+% 11. fff -> ff-f
+% ---------------
+ % Just in case there's a font that
+ % features a triple-f ligature:
+
+\nolig{fff}{ff|f}
+ % grifffest Futterstofffabrik Hafffischer
+ % sauerstofffrei Schifffahrt
+ % Stofffarbe Stofffaser Stofffülle
+
+ % This macro will also break up any 'fffl'
+ % ligatures into 'ff' and 'fl' parts.
+ % Examples: Auspuffflamme Kunststoffflügel
+ % Sauerstoffflasche Sauserstoffflamme
+ % Schlifffläche Stofffleck
+ % Treibstofffluss
+
diff --git a/macros/luatex/latex/selnolig/selnolig-german-test.pdf b/macros/luatex/latex/selnolig/selnolig-german-test.pdf
new file mode 100644
index 0000000000..b973e1e907
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig-german-test.pdf
Binary files differ
diff --git a/macros/luatex/latex/selnolig/selnolig-german-test.tex b/macros/luatex/latex/selnolig/selnolig-german-test.tex
new file mode 100644
index 0000000000..d84e2d354a
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig-german-test.tex
@@ -0,0 +1,61 @@
+% !TEX TS-program = lualatex
+\documentclass[ngerman]{article}
+
+% Test program: Apply the 'selnolig' package, with
+% 'german' language option set, to a list of German words
+% which contain one or more non-ligation points. The list
+% of test words is in 'selnolig-german-wordlist.tex'.
+%
+% Author: Mico Loretan (loretan dot mico at gmail dot com)
+% Date: 2015/10/26
+
+% Check first that we're running lua(la)tex.
+\usepackage{ifluatex}
+\ifluatex\else
+ \typeout{==============================================}
+ \typeout{ The file selnolig-german-test.tex must be }
+ \typeout{compiled using LuaLaTeX. Exiting immediately. }
+ \typeout{==============================================}
+ \endinput
+\fi
+
+\usepackage[vmargin=1in,hmargin=0.75in]{geometry}
+
+\usepackage{fontspec}
+\defaultfontfeatures{%
+ Ligatures={TeX,Common},
+ Numbers = OldStyle}
+\setmainfont{EB Garamond 12 Regular}
+%\newfontfamily\gpp{Garamond Premier Pro}
+\newfontfamily\ebg{EB Garamond 12 Regular}
+
+\usepackage[document]{ragged2e}
+\setlength\parindent{0pt}
+\parskip=0.3\baselineskip
+
+\usepackage{babel}
+\usepackage{selnolig}
+
+%%%\usepackage{showhyphens}
+\usepackage{multicol}
+ \setlength\columnseprule{.4pt}
+\title{selnolig-german-test\\ (Package version: \selnoligpackageversion; \selnoligpackagedate)}
+\author{\null}
+\date{}
+\begin{document}
+%\gpp
+\maketitle
+
+\begin{tabular}{@{} *{9}{l} }
+Erscheinungsbild der f-Ligaturen
+ &ff &fi &fl &ffi &ffl &ft & \uselig{fj} &\uselig{fk}\\
+Beispiele
+ &Affe &finden &flink &offiziell &soufflieren & Luft & Sognefjord &Kafka\\
+\end{tabular}
+
+\bigskip
+
+\begin{multicols}{2}
+\input selnolig-german-wordlist
+\end{multicols}
+\end{document}
diff --git a/macros/luatex/latex/selnolig/selnolig-german-wordlist.tex b/macros/luatex/latex/selnolig/selnolig-german-wordlist.tex
new file mode 100644
index 0000000000..a2df2dbb5d
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig-german-wordlist.tex
@@ -0,0 +1,987 @@
+% !TeX root = selnolig-german-test.tex
+% !TEX TS-program = lualatex
+
+% Last updated: 2015/10/26
+% For use with the 'selnolig' package and the
+% driver program 'selnolig-german-test.tex'.
+
+\section*{Wörter, für welche man ff-, fi-, fl-, ffi- und ffl-Ligaturen vermeiden sollte}
+
+Auflaufform Auflaufformen (weder fl- noch ff-Ligatur!)
+
+\medskip
+Ablauffolge Ablauffolgen
+
+ablauffähig ablauffähige ablauffähigem ablauffähigen ablauffähiger ablauffähiges Ablauffähigkeit Ablauffähigkeiten
+
+Ablaufleitung Ablaufleitungen
+
+Ablaufliste Ablauflisten
+
+Abruffunktion Abruffunktionen
+
+Anruffalle Anruffallen
+
+Anruffunktion Anruffunktionen
+
+Anzweiflung Anzweiflungen
+
+auffahrbar auffahrbare auffahrbarem auffahrbaren auffahrbarer auffahrbares auffahre auffahren auffahrend auffahrende auffahrendem auffahrenden auffahrender auffahrendes auffahrt Auffahrten Auffahrtsweg Auffahrunfall Auffahrunfalls Auffahrunfälle Auffahrunfällen
+
+auffalle auffallen auffallend auffallende auffallendem auffallenden auffallender auffallendere auffallenderem auffallenderen auffallenderer auffallenderes auffallenderweise auffallendes auffallendst auffallendste auffallendstem auffallendsten auffallendster auffallendstes auffallt
+
+auffaltbar Auffaltungen
+
+auffand auffanden auffandest auffandet auffandst
+
+auffangbar auffangbare auffangbarem auffangbaren auffangbarer auffangbares auffange auffangen auffangend auffangende auffangendem auffangenden auffangender auffangendes
+
+Auffangbecken Auffangbeckens Auffanglager Auffanglagern Auffanglagers Auffangregister Auffangregistern Auffangregisters Auffangt Auffangvorrichtung Auffangvorrichtungen Auffangwanne Auffangwannen Auffangweiche Auffangweichen
+
+auffassbar auffassbare auffassbarem auffassbaren auffassbarer auffassbares auffasse auffassen auffassend auffassende auffassendem auffassenden auffassender auffassendes auffassens auffassest auffasst auffasste auffassten auffasstest auffasstet
+
+Auffassbarkeit Auffassbarkeiten Auffassung Auffassungen Auffassungsgabe Auffassungsgaben Auffassungsvermögen Auffassungsvermögens
+
+auffasst auffasste auffassten auffasstest auffasstet
+
+auffaßt auffaßte auffaßten auffaßtest auffaßtet
+
+auffiel auffiele auffielen auffielst auffielt
+
+auffindbar auffindbare auffindbarem auffindbaren auffindbarer auffindbares Auffindbarkeit Auffindbarkeiten auffinde auffinden auffindend auffindende auffindendem auffindenden auffindender auffindendes auffindens auffindest auffindet Auffindung Auffindungen
+
+auffing auffinge auffingen auffingst auffingt
+
+auffische auffischen auffischend auffischende auffischendem auffischenden auffischender auffischendes auffischest auffischst auffischt auffischte auffischten auffischtest auffischtet
+
+aufflackern Aufflackerns
+
+aufflamme aufflammen aufflammend aufflammende aufflammendem aufflammenden aufflammender aufflammendes aufflammst aufflammt aufflammte aufflammten aufflammtest aufflammtet
+
+auffliege auffliegen auffliegend auffliegende auffliegendem auffliegenden auffliegender auffliegendes auffliegst auffliegt
+
+auffloge aufflogen aufflogest auffloget
+
+aufflöge aufflögen aufflögest aufflöget
+
+auffordere auffordern auffordernd auffordernde aufforderndem auffordernden auffordernder aufforderndes aufforderns aufforderst auffordert aufforderte aufforderten auffordertest auffordertet Aufforderung Aufforderungen auffordre
+
+aufforstbar aufforstbare aufforstbarem aufforstbaren aufforstbarer aufforstbares aufforste aufforsten aufforstend aufforstende aufforstendem aufforstenden aufforstender aufforstendes aufforstens aufforstest aufforstet aufforstete aufforsteten aufforstetest aufforstetet Aufforstung Aufforstungen
+
+auffrass auffrassen auffrassest auffrasst
+
+auffraß auffraßen auffraßest auffraßt
+
+auffresse auffressen auffressend auffressende auffressendem auffressenden auffressender auffressendes
+
+auffresst
+
+auffreßt
+
+auffrischbar auffrischbare auffrischbarem auffrischbaren auffrischbarer auffrischbares auffrische auffrischen auffrischend auffrischende auffrischendem auffrischenden auffrischender auffrischendes auffrischens auffrischest auffrischst auffrischt auffrischte auffrischten auffrischtest auffrischtet Auffrischung Auffrischungen
+
+auffrisiere auffrisieren auffrisierend auffrisierende auffrisierendem auffrisierenden auffrisierender auffrisierendes auffrisierst auffrisiert auffrisierte auffrisiertem auffrisierten auffrisierter auffrisiertes auffrisiertest auffrisiertet
+
+auffrisst
+
+auffrißt
+
+auffräse auffräsen auffräsest auffräset
+
+auffrässe auffrässen auffrässest auffrässet
+
+auffräße auffräßen auffräßest auffräßet
+
+auffuhr auffuhren auffuhrst auffuhrt
+
+auffächerbar auffächerbare auffächerbarem auffächerbaren auffächerbarer auffächerbares auffächere auffächern auffächernd auffächernde auffächerndem auffächernden auffächernder auffächerndes auffächerns auffächerst auffächert auffächerte auffächerten auffächertest auffächertet Auffächerung Auffächerungen auffächre
+
+auffährst auffährt hinauffährt
+
+arbeitskampffähig hoffähig Kampffähigkeit kampffähig lauffähig prüffähige straffähig tariffähig Tariffähigkeit Umlauffähigkeit wettkampffähiges
+
+auffällig auffällige auffälligem auffälligen auffälliger auffälligere auffälligerem auffälligeren auffälligerer auffälligeres auffälliges auffälligkeit auffälligkeiten auffälligst auffälligste auffälligstem auffälligsten auffälligster auffälligstes auffällst auffällt
+
+auffängst auffängt
+
+aufführbar aufführbare aufführbarem aufführbaren aufführbarer aufführbares aufführe aufführen aufführend aufführende aufführendem aufführenden aufführender aufführendes aufführens aufführst aufführt aufführte aufführten aufführtest aufführtet Aufführung Aufführungen Aufführungsstatistik Aufführungsstil Aufführungsstile Aufführungsstilen Aufführungsstils
+
+auffüllbar auffüllbare auffüllbarem auffüllbaren auffüllbarer auffüllbares auffülle auffüllen auffüllend auffüllende auffüllendem auffüllenden auffüllender auffüllendes auffüllens auffüllst auffüllt auffüllte auffüllten auffülltest auffülltet Auffüllung Auffüllungen
+
+aufisst
+
+auflache auflachen auflachend auflachende auflachendem auflachenden auflachender auflachendes
+
+auflachst
+
+auflacht auflachte auflachten auflachtest auflachtet
+
+aufladbar aufladbare aufladbarem aufladbaren aufladbarer aufladbares
+
+auflade aufladen aufladend aufladende aufladendem aufladenden aufladender aufladendes aufladens Auflader Aufladerin Aufladerinnen Aufladern Aufladers Aufladet Aufladevorgang Aufladevorgangs
+
+Aufladung Aufladungen
+
+Auflage Auflagefläche Auflageflächen Auflagen Auflagenerhöhung Auflagenerhöhungen Auflagenstark Auflagenstarke Auflagenstarkem Auflagenstarken Auflagenstarker Auflagenstarkes Auflagenstärke Auflagenzahl Auflagenzahlen Auflagenziffer Auflagenziffern
+
+auflandig auflandige auflandigem auflandigen auflandiger auflandiges
+
+auflasse auflassen auflassend auflassende auflassendem auflassenden auflassender auflassendes auflassens auflasst Auflassung Auflassungen
+
+auflauere auflauern auflauernd auflauernde auflauerndem auflauernden auflauernder auflauerndes auflauerst auflauert auflauerte auflauerten auflauertest auflauertet
+
+Auflauf auflaufe auflaufen auflaufend auflaufende auflaufendem auflaufenden auflaufender auflaufendes Auflaufs auflauft
+
+auflaure
+
+auflaßt
+
+auflebe aufleben auflebend auflebende auflebendem auflebenden auflebender auflebendes
+
+auflebst
+
+auflebt auflebte auflebten auflebtest auflebtet
+
+auflege auflegen auflegend auflegende auflegendem auflegenden auflegender auflegendes
+
+auflegst
+
+auflegt auflegte auflegten auflegtest auflegtet
+
+auflehne auflehnen auflehnend auflehnende auflehnendem auflehnenden auflehnender auflehnendes auflehnens auflehnst auflehnt auflehnte auflehnten auflehntest auflehntet Auflehnung Auflehnungen
+
+auflese auflesen auflesend auflesende auflesendem auflesenden auflesender auflesendes
+
+auflest
+
+aufleuchte aufleuchten aufleuchtend aufleuchtende aufleuchtendem aufleuchtenden aufleuchtender aufleuchtendes aufleuchtest aufleuchtet aufleuchtete aufleuchteten aufleuchtetest aufleuchtetet
+
+aufliege aufliegen aufliegend aufliegende aufliegendem aufliegenden aufliegender aufliegendes Aufliegeschema aufliegst aufliegt
+
+aufliesse aufliessen aufliessest aufliesset
+
+aufließe aufließen aufließest aufließet
+
+auflistbar auflistbare auflistbarem auflistbaren auflistbarer auflistbares
+
+aufliste auflisten auflistend auflistende auflistendem auflistenden auflistender auflistendes auflistens auflistest auflistet auflistete auflisteten auflistetest auflistetet Auflistung Auflistungen
+
+auflockere auflockern auflockernd auflockernde auflockerndem auflockernden auflockernder auflockerndes auflockerns auflockerst auflockert auflockerte auflockerten auflockertest auflockertet Auflockerung Auflockerungen Auflockerungstendenz Auflockerungstendenzen auflockre
+
+auflodere auflodern auflodernd auflodernde aufloderndem auflodernden auflodernder aufloderndes aufloderns aufloderst auflodert aufloderte aufloderten auflodertest auflodertet auflodre
+
+auflädst auflädt
+
+Aufläufe Aufläufen aufläuft
+
+auflösbar auflösbare auflösbarem auflösbaren auflösbarer auflösbares auflöse auflösen auflösend auflösende auflösendem auflösenden auflösender auflösendes auflösens auflösest auflöst auflöste auflösten auflöstest auflöstet Auflösung Auflösungen Auflösungsbeschluss Auflösungsbeschlusses Auflösungsbeschluß Auflösungsbeschlüsse Auflösungsbeschlüssen Auflösungserscheinung Auflösungserscheinungen Auflösungsprozess Auflösungsprozesse Auflösungsprozessen Auflösungsprozeß
+
+auflüde auflüden auflüdest auflüdet
+
+Autobahnauffahrt
+
+Bauauflage Bauauflagen
+
+Baustoffindustrie Baustoffindustrien
+
+Baustoffingenieur Baustoffingenieure
+
+begreiflich begreifliche begreiflichem begreiflichen begreiflicher begreiflichere begreiflicherem begreiflicheren begreiflicherer begreiflicheres begreiflicherweise begreifliches begreiflichst begreiflichste begreiflichstem begreiflichsten begreiflichster begreiflichstes
+
+begrifflich begriffliche begrifflichem begrifflichen begrifflicher begriffliches
+
+behilflich behilfliche behilflichem behilflichen behilflicher behilfliches
+
+beruflich berufliche beruflichem beruflichen beruflicher berufliches
+
+Bettauflage Bettauflagen
+
+bezweifle bezweiflete bezweifleten
+
+Bezweiflung
+
+Bildschirmauflösung Bildschirmauflösungen
+
+Biohofladen
+
+bischöflich bischöfliche bischöflichem bischöflichen bischöflicher bischöfliches
+
+Bischoffinger
+
+Brieffach
+
+Briefform
+
+Brieffächer
+
+Briefintrige
+
+Brieflaufzeiten
+
+brieflich briefliche brieflichem brieflichen brieflicher briefliches
+
+Büffler Büfflerin Büfflerinnen
+
+Chefflugleiter
+
+Cheffunktion
+
+Chefideologe
+
+Dampfleistung
+
+Dampflokomotiven
+
+darauffolge darauffolgen darauffolgend darauffolgende darauffolgendem darauffolgenden darauffolgender darauffolgendes darauffolgst darauffolgt darauffolgte darauffolgten darauffolgtest darauffolgtet
+
+Darstellungsauffassung Darstellungsauffassungen
+
+Dauertropfflasche
+
+Dorffeuerwehr
+
+Dorfladen
+
+drauflege drauflegen drauflegend drauflegende drauflegendem drauflegenden drauflegender drauflegendes drauflegst drauflegt drauflegte drauflegten drauflegtest drauflegtet
+
+drauflos drauflosgegangen drauflosgegangene drauflosgegangenem drauflosgegangenen drauflosgegangener drauflosgegangenes drauflosgehe drauflosgehen drauflosgehend drauflosgehende drauflosgehendem drauflosgehenden drauflosgehender drauflosgehendes drauflosgehst drauflosgeht drauflosging drauflosginge drauflosgingen drauflosgingst drauflosgingt
+
+dörflich dörfliche dörflichem dörflichen dörflicher dörfliches
+
+Düsenkampfflugzeug
+
+Eingabeaufforderung
+
+Einwurffächer
+
+Einzelhandelskaufleute Einzelhandelskaufleuten
+
+elffach elffache elffachem elffachen elffacher elffaches
+
+elffingrig elffingrige
+
+Erstaufführung
+
+Erstauflage
+Erstauflagen
+
+erzbischöflich erzbischöfliche erzbischöflichem erzbischöflichen erzbischöflicher erzbischöfliches
+
+Freiberufler Freiberuflerin Freiberuflerinnen Freiberuflern Freiberuflers
+
+freiberuflich freiberufliche freiberuflichem freiberuflichen freiberuflicher freiberufliches
+
+Freilichtaufführung Freilichtaufführungen
+
+fünffach fünffache fünffachem fünffachen fünffacher fünffaches
+
+fünffingerig fünffingerige fünffingerigem fünffingerigen fünffingeriger fünffingeriges
+
+Fünflinge Fünflingen
+
+Gastspielaufführung
+
+Gebirgsauffaltung
+
+glimpflich glimpfliche glimpflichem glimpflichen glimpflicher glimpfliches
+
+Grafikauflösung Grafikauflösungen Grafikkartenauflösung Grafikkartenauflösungen
+
+grifffest grifffeste grifffestem grifffesten grifffester grifffestes
+
+Großkaufleute Großkaufleuten % Buddenbrooks
+
+Grundauffassung Grundauffassungen
+
+Gugelhupfform
+
+handgreiflich handgreifliche handgreiflichem handgreiflichen handgreiflicher handgreifliches Handgreiflichkeit Handgreiflichkeiten
+
+hauptberuflich hauptberufliche hauptberuflichem hauptberuflichen hauptberuflicher hauptberufliches
+
+hilflos hilflose hilflosem hilflosen hilfloser hilflosere hilfloserem hilfloseren hilfloserer hilfloseres hilfloses hilflosest hilfloseste hilflosestem hilflosesten hilflosester hilflosestes
+
+hinauffahre hinauffahren hinauffahrend hinauffahrende hinauffahrendem hinauffahrenden hinauffahrender hinauffahrendes hinauffahrt
+
+hinauffuhr hinauffuhren hinauffuhrst hinauffuhrt
+
+hinaufführe hinaufführen hinaufführend hinaufführende hinaufführendem hinaufführenden hinaufführender hinaufführendes hinaufführst hinaufführt hinaufführte hinaufführten hinaufführtest hinaufführtet
+
+hochauflösend hochauflösende hochauflösendem hochauflösenden hochauflösender hochauflösendes
+
+hoffähig
+
+Hofladen
+
+Hoflandwirtschaft
+
+Hofleben
+
+Hufform
+
+Häuflein Häufleins
+
+höflich höfliche höflichem höflichen höflicher höflichere höflicherem höflicheren höflicherer höflicheres höfliches höflichkeit höflichkeiten höflichkeitsbesuche höflichkeitsbesuches höflichkeitsformeln höflichst höflichste höflichstem höflichsten höflichster höflichstes
+
+Impffolgen
+
+Impfforschung
+
+Impfflüssigkeit
+
+inbegriffleitend
+
+Kampfflieger Kampffliegers
+
+Kampfflugzeug Kampfflugzeuge Kampfflugzeuges
+
+Kampffront
+
+kampffähig kampffähige kampffähigem kampffähigen kampffähiger kampffähiges Kampffähigkeit
+
+Kampfführung
+
+Kampflaune
+
+Kampflied Kampflieder Kampfliedern
+
+kampflos kampflose kampflosem kampflosen kampfloser kampfloses
+
+kampflustig kampflustige kampflustigem kampflustigen kampflustiger kampflustigere kampflustigerem kampflustigeren kampflustigerer kampflustigeres kampflustiges kampflustigst kampflustigste kampflustigstem kampflustigsten kampflustigster kampflustigstes
+
+Kauffahrer Kauffahrerin Kauffahrerinnen Kauffahrern Kauffahrers
+Kauffahrt
+
+Kauffrau Kauffrauen
+
+Kaufindex Kaufindizes
+
+Kaufinteresse Kaufinteressenten
+
+Kaufladen Kaufladens
+
+Kauflaune
+
+Kaufleidenschaft
+
+Kaufleitung
+
+Kaufleute Kaufleuten
+
+Kauflust kauflustig kauflustige kauflustiger kauflustigste kauflustigsten
+
+Kaufläden
+
+Kettensträfling Kettensträflinge Kettensträflingen Kettensträflings
+
+Kleiderstoffindustrie
+
+knifflig knifflige kniffligem kniffligen kniffliger kniffligere kniffligerem kniffligeren kniffligerer kniffligeres kniffliges kniffligst kniffligste kniffligstem kniffligsten kniffligster kniffligstes
+
+Knopfloch
+
+Knopflöcher
+
+Knoepffler
+
+Kontoauflösung
+
+Kopfform Menschenkopfform
+
+kopflastig kopflastige kopflastigem kopflastigen kopflastiger kopflastiges
+
+Kopfleiste
+
+kopflos kopflose kopflosem kopflosen kopfloser kopflosere kopfloserem kopfloseren kopfloserer kopfloseres kopfloses kopflosest kopfloseste kopflosestem kopflosesten kopflosester kopflosestes
+
+Kreislauffunktion
+
+Kreislaufleiden
+
+Kunststoffindustrie
+
+käuflich käufliche käuflichem käuflichen käuflicher käufliches Käuflichkeit
+
+Köpflein
+
+Lagerauffüllung
+
+Lagerauflösung
+
+Lauffeuer Lauffeuern Lauffeuers
+
+Lauffolgen
+
+lauffähig lauffähige lauffähigem lauffähigen lauffähiger lauffähiges Lauffähigkeit
+
+Laufindex Laufindexe Laufindexen Laufindexes Laufindices
+
+Laufleine Laufleinen
+
+Lauflernhilfen
+
+Lebensauffassung Lebensauffassungen
+
+Liebhaberaufführung
+
+Löffler
+
+markgräflich markgräfliche markgräflichem markgräflichen markgräflicher markgräfliches
+
+Mindestreserveauflagen
+
+Monitorauflösung Monitorauflösungen
+
+nebenberuflich nebenberufliche nebenberuflichem nebenberuflichen nebenberuflicher nebenberufliches
+
+Neuauflage Neuauflagen
+
+Oberstufler
+
+offline
+
+Opernaufführung Opernaufführungen
+
+Parlamentsauflösung
+
+Politikauffassung Politikauffassungen
+
+Produktionsauflagen
+
+Prüffach
+
+Prüffeld
+
+Prüffächer
+
+Prüfingenieur
+
+Prüfling Prüflinge Prüflingen Prüflings
+
+Prüfliste Prüflisten
+
+rauflustig rauflustige rauflustigem rauflustigen rauflustiger rauflustiges
+
+Reichstagsauflösung
+
+reiflich reifliche reiflichem reiflichen reiflicher reiflichere reiflicherem reiflicheren reiflicherer reiflicheres reifliches reiflichst reiflichste reiflichstem reiflichsten reiflichster reiflichstes
+
+Restauflage Restauflagen
+
+Rinderkopffleisch
+
+Rohstoffindex Rohstoffindexe Rohstoffindices Rohstoffindustrie
+
+Rohstoffingenieur Rohstoffingenieure
+
+Schaffell Schaffelle Schaffellen Schaffells
+
+Schafleder Schafledern Schafleders
+
+Scherflein Scherfleins
+
+schieflache schieflachen schieflachend schieflachende schieflachendem schieflachenden schieflachender schieflachendes schieflachst schieflacht schieflachte schieflachten schieflachtest schieflachtet
+
+schieflag Schieflage Schieflagen schieflagst schieflagt
+
+Schieflaufen
+
+schiefliege schiefliegen schiefliegend schiefliegende schiefliegendem schiefliegenden schiefliegender schiefliegendes schiefliegst schiefliegt
+
+schiefläuft
+
+Schilffeld Schilffelder % Th. Mann's "Tod in Venedig"
+
+Schilfinsel Schilfinseln
+
+schimpflich schimpfliche schimpflichem schimpflichen schimpflicher schimpfliches
+
+Schlafforscher Schlafforschung
+
+Schlaffrisur
+
+Schlaflied Schlaflieder Schlafliedern Schlafliedes Schlaflieds
+
+schlaflos schlaflose schlaflosem schlaflosen schlafloser schlafloses Schlaflosigkeit Schlaflosigkeiten
+
+Schlupfloch Schlupfloches Schlupflochs
+
+Schlupflöcher Schlupflöchern
+
+Schnüffler Schnüfflerin Schnüfflerinnen Schnüfflern Schnüfflers
+
+schweflig schweflige schwefligem schwefligen schwefliger schwefliges
+
+Schöpflöffel Schöpflöffeln Schöpflöffels
+
+selbstauffaltend
+
+Selbstauflösung
+
+Serienbrieffunktion
+
+Sprengstofffallen
+
+steckbrieflich
+
+Steuerschnüffler Steuerschnüfflern Steuerschnüfflers
+
+Straffall Straffalls
+
+straffrisch
+
+Straffälle straffällig straffällige straffälligem straffälligen straffälliger straffälliges
+
+Strafforderung
+
+straffähig
+
+Straflager Straflagern Straflagers
+
+straflos straflose straflosem straflosen strafloser strafloses
+
+Streiflicht Streiflichter Streiflichtern Streiflichts
+
+sträflich sträfliche sträflichem sträflichen sträflicher sträfliches
+
+Sträfling Sträflinge Sträflingen Sträflings
+
+Sturzkampfflugzeug Sturzkampfflugzeuge Sturzkampfflugzeugen Sturzkampfflugzeugs
+
+Sumpffieber
+
+Sumpffliege Sumpffliegen
+
+Sumpfland Sumpflandes Sumpflands
+
+Sumpflicht Sumpflichter
+
+Sumpfländer Sumpfländern
+
+Surfladen
+
+tariflich tarifliche tariflichem tariflichen tariflicher tarifliches
+
+Tariffalle Tariffallen
+
+Tarifforderung
+
+Tariffront
+
+Tariflohn Tariflohns
+
+Tariflöhne Tariflöhnen
+
+teuflisch teuflische teuflischem teuflischen teuflischer teuflischere teuflischerem teuflischeren teuflischerer teuflischeres teuflisches teuflischst teuflischste teuflischstem teuflischsten teuflischster teuflischstes
+
+Theateraufführung Theateraufführungen
+
+tieffliege tieffliegen tieffliegend tieffliegende tieffliegendem tieffliegenden tieffliegender tieffliegendes Tiefflieger Tieffliegern Tieffliegers tieffliegst tieffliegt
+
+tiefflog tiefflogen tiefflogst tiefflogt
+
+Tiefflug Tieffluges Tiefflugs
+
+Tiefflüge Tiefflügen
+
+tiefladbar tiefladbare tiefladbarem tiefladbaren tiefladbarer tiefladbares tieflade tiefladen Tieflader Tiefladeprogramm
+
+Tieflage Tieflagen
+
+Tiefland Tieflandes Tieflands
+
+tiefliege tiefliegen tiefliegend tiefliegende tiefliegendem tiefliegenden tiefliegender tiefliegendes tiefliegst tiefliegt
+
+Tiefländer Tiefländern
+
+Tieflöffel Tieflöffelbagger Tieflöffelbaggern tieflöffeln Tieflöffels
+
+Torffeuer
+
+Totenkopfflagge
+
+trefflich treffliche trefflichem trefflichen trefflicher trefflichere trefflicherem trefflicheren trefflicherer trefflicheres treffliches trefflichkeit trefflichst trefflichste trefflichstem trefflichsten trefflichster trefflichstes
+
+Täufling Täuflinge Täuflingen Täuflings
+
+Tüpflischeißer Tüpflischiesser
+
+unauffindbar unauffindbare unauffindbarem unauffindbaren unauffindbarer unauffindbares Unauffindbarkeit Unauffindbarkeiten
+
+unauffällig unauffällige unauffälligem unauffälligen unauffälliger unauffälligere unauffälligerem unauffälligeren unauffälligerer unauffälligeres unauffälliges unauffälligkeit unauffälligkeiten unauffälligst unauffälligste unauffälligstem unauffälligsten unauffälligster unauffälligstes
+
+unauflösbar unauflösbare unauflösbarem unauflösbaren unauflösbarer unauflösbares
+
+unauflöslich unauflösliche unauflöslichem unauflöslichen unauflöslicher unauflösliches
+
+unbegreiflich unbegreifliche unbegreiflichem unbegreiflichen unbegreiflicher unbegreiflichere unbegreiflicherem unbegreiflicheren unbegreiflicherer unbegreiflicheres unbegreifliches unbegreiflichkeit unbegreiflichst unbegreiflichste unbegreiflichstem unbegreiflichsten unbegreiflichster unbegreiflichstes
+
+unerschöpflich unerschöpfliche unerschöpflichem unerschöpflichen unerschöpflicher unerschöpflichere unerschöpflicherem unerschöpflicheren unerschöpflicherer unerschöpflicheres unerschöpfliches unerschöpflichst unerschöpflichste unerschöpflichstem unerschöpflichsten unerschöpflichster unerschöpflichstes
+
+unglimpflich unglimpfliche unglimpflichem unglimpflichen unglimpflicher unglimpfliches
+
+unhöflich unhöfliche unhöflichem unhöflichen unhöflicher unhöflichere unhöflicherem unhöflicheren unhöflicherer unhöflicheres unhöfliches unhöflichkeit unhöflichkeiten unhöflichst unhöflichste unhöflichstem unhöflichsten unhöflichster unhöflichstes
+
+unverkäuflich unverkäufliche unverkäuflichem unverkäuflichen unverkäuflicher unverkäufliches Unverkäuflichkeit
+
+unwiderruflich unwiderrufliche unwiderruflichem unwiderruflichen unwiderruflicher unwiderrufliches
+
+unübertrefflich
+
+uraufführe uraufführen uraufführend uraufführende uraufführendem uraufführenden uraufführender uraufführendes uraufführst uraufführt uraufführte uraufführten uraufführtest uraufführtet Uraufführung Uraufführungen
+
+übertariflich übertarifliche übertariflichem übertariflichen übertariflicher übertarifliches
+
+verelffache verelffachen verelffachend verelffachende verelffachendem verelffachenden verelffachender verelffachendes verelffachst verelffacht verelffachte verelffachtem verelffachten verelffachter verelffachtes verelffachtest verelffachtet
+
+verfünffache verfünffachen verfünffachend verfünffachende verfünffachendem verfünffachenden verfünffachender verfünffachendes verfünffachst verfünffacht verfünffachte verfünffachtem verfünffachten verfünffachter verfünffachtes verfünffachtest verfünffachtet
+
+verkäuflich verkäufliche verkäuflichem verkäuflichen verkäuflicher verkäufliches Verkäuflichkeit
+
+verwerflich verwerfliche verwerflichem verwerflichen verwerflicher verwerflichere verwerflicherem verwerflicheren verwerflicherer verwerflicheres verwerfliches verwerflichst verwerflichste verwerflichstem verwerflichsten verwerflichster verwerflichstes
+
+Verzweiflung Verzweiflungsschritt Verzweiflungstat
+
+verzwölffache verzwölffachen verzwölffachend verzwölffachende verzwölffachendem verzwölffachenden verzwölffachender verzwölffachendes verzwölffachst verzwölffacht verzwölffachte verzwölffachtem verzwölffachten verzwölffachter verzwölffachtes verzwölffachtest verzwölffachtet
+
+Voraufführung Voraufführungen
+
+vorberuflich vorberufliche vorberuflichem vorberuflichen vorberuflicher vorberufliches
+
+Vorlaufindikator Vorlaufindikatoren
+
+vortrefflich vortreffliche vortrefflichem vortrefflichen vortrefflicher vortreffliches
+
+Wahlkampffieber Wahlkampfflyer Wahlkampfflamme Wahlkampffloskeln
+
+Waldorflehrer Waldorflehrerin Waldorflehrerinnen Waldorflehrern Waldorflehrers
+
+Wegwerfformat
+
+Wettkampffieber Wettkampffläche Wettkampfflair
+
+widerruflich widerrufliche widerruflichem widerruflichen widerruflicher widerrufliches
+
+wiederaufführung wiederaufführungen
+
+wiederaufladbar wiederaufladbare wiederaufladbarem wiederaufladbaren wiederaufladbarer wiederaufladbares
+
+wiederauflade wiederaufladen wiederaufladend wiederaufladende wiederaufladendem wiederaufladenden wiederaufladender wiederaufladendes wiederaufladet Wiederaufladung
+
+wiederauflebe wiederaufleben wiederauflebend wiederauflebende wiederauflebendem wiederauflebenden wiederauflebender wiederauflebendes wiederauflebst wiederauflebt wiederauflebte wiederauflebten wiederauflebtest wiederauflebtet
+
+Wirtschaftsauffassung
+
+
+würflig würflige würfligem würfligen würfliger würfliges
+
+Wölflein
+
+Wölfling
+
+Wurflaune
+
+Zahlungsaufforderung Zahlungsaufforderungen
+
+Zeitauflösung
+
+Zöpflein
+
+Zupfinstrument Zupfinstrumente Zupfinstrumenten Zupfinstrumentes Zupfinstruments
+
+zweifle
+
+Zweifler Zweiflerin Zweiflerinnen Zweiflern Zweiflers
+
+Zweitauflage Zweitauflagen
+
+zwölffach zwölffache zwölffachem zwölffachen zwölffacher zwölffaches
+
+Zwölffingerdarm Zwölffingerdarmes Zwölffingerdarms
+
+
+
+
+\section*{Wörter, für welche man die ft- und fft-Ligaturen vermeiden sollte}
+
+Auftakt
+
+auftanken auftasten auftat
+auftauen auftaute
+auftauchen auftauchte
+aufteilen Aufteilung Aufteilungen
+auftischen auftischte auftoupieren
+auftraben
+Auftrag, auftragen, Auftraggeber
+auftrat
+auftreiben
+auftreten
+Auftritt
+Aufträge
+auftun auftürmen
+
+Sauftrottel
+
+kauftüchtig
+
+Lauftherapie
+
+Golftheorie Kampftheorien Auflauftheorien Kreislauftheorie
+
+Tauftag Fünftagewoche
+
+Treibstofftank
+
+fünftausend Fünftausender
+
+fünftürig Senftüte
+
+Hoftür
+
+elftausend zwölftausend Golftasche
+
+Ruftaste Vorlauftaste
+
+Ruftaxi
+
+Wettkampftag Kampftaktik
+wahlkampftauglich Schnupftabak
+%kämpfte schimpfte schrumpfte
+%klopfte schöpften
+Schimpftiraden Mehrkampftitel Stapftiefe
+Dampftopf Sumpftour
+Kampftruppe Wettkampftrubel
+Kopftreffer Zopfträger
+Kopftuch Schnupftuch
+Kampftätigkeit Kampftänzer
+Herzklopftöne Wahlkampftöne
+Kopftücher Kopftüchlein Schnupftücher
+
+Stofftasche Stofftapete Sauerstofftank
+%schaffte hoffte klaffte verpuffte
+Stofftheorie
+Stofftier Stofftiger Stofftischtuch
+Auspufftopf Kunststofftonne
+Stofftradition Stofftrennung
+Kunststofftube Stoffturnschuhe
+Stofftäschchen
+Auspufftöpfe Kunststofftöpfe
+Kunststofftüten
+
+
+Schlaftablette Schlafteddy Schlaftee Schlaftemperatur
+Schlaftherapeut Schlaftherapie Schlaftier Schlaftod
+Schlaftrank schlaftrunken
+
+Straftarif Strafteam Straftechnisch Straftendenz
+Straftermin Straftheologisch Straftilgung
+Straftor Straftribunal
+
+\ \ \ aber: bestraft, vorbestraft
+
+Brieftasche Brieftaube
+
+Cheftheoretiker Cheftestpilot Cheftrainer
+
+Dorftrottel Dorftratsch Dorftradition Dorftölpel
+
+Wurftraining Surftrip Freiwurftreffer
+
+Wurftuch Dorftümpel
+
+Lauftrainer
+
+Eingreiftruppe Nadelstreifträger
+
+Pfeifton Zwölftonmusik Rufton
+
+Wurftalent Auswurftaste Surftalent
+
+%Hälfte
+
+Schifftyp Stofftyp waldorftypisch Dorftyrann Hoftyrann
+
+Stieftochter Tiefton
+
+Stieftöchter tieftönend
+
+fünfte fünfter elfte elfter zwölfte zwölfter
+
+\ \ \ aber: zu fünft, zu elft, zu zwölft
+
+zwölftönend
+
+Zwölftonmusik Elftonner Golftour
+
+Senftopf Senftöpfchen
+
+Freiwurftor Surftour Dorftourismus
+
+\ebg
+
+\section*{Wörter, für welche man \uselig{fb}-, \uselig{fh}-, \uselig{fj}- und \uselig{fk}-Ligaturen vermeiden sollte}
+
+Einige wenige Beispiele genügen\ldots
+
+
+
+\begin{itemize}
+
+
+\item \uselig{fb} und \uselig{ffb}
+
+
+abrufbar
+Anrufbeantworter
+
+aufbahren aufbauen aufbegehren aufbereiten aufbessern aufbewahren aufbefördern aufbieten aufblasen aufblicken Aufblick aufblitzen aufblähen aufblühen aufbrauchen aufbrausen aufbrechen aufbringen Aufbruch aufbäumen aufbürden
+
+Aufbauspieler
+
+Briefbombe Briefbogen
+
+Chefberater
+
+Dampfbad Dorfbewohner Dorfbevölkerung
+
+greifbar angreifbar unangreifbar griffbereit Golfball
+
+Griffbrett
+
+Briefbeschwerer Hofbräuhaus
+
+Kopfbewegung Kopfball Kopfbedeckung Kaufbeleg kampfbetont
+
+Laufbahn Laufband Laufbereitschaft Laufbursche
+
+Raufbold Rohstoffboom Regenüberlaufbecken
+
+Schadstoffbelastung Schlafbedürfnis Scharfblick
+
+schiffbar Schiffbau Schiffbruch
+
+steifbeinig Stoffbahnen
+
+Sauerstoffbedarf Stiefbruder
+
+Strafbestimmungen strafbar Strafbefehl
+
+Surfbretter
+
+Tarifbezirk Tarifbindung
+
+Tiefbau tiefbelustigt tiefblau
+
+Umlaufbahn überprüfbar
+
+(un)widerrufbar
+
+Wasserstoffbombe
+
+Wiederaufbau
+
+
+\item \uselig{fh} und \uselig{ffh}
+
+
+aufhaben aufhacken aufhalsen aufhalten aufhatte aufheben aufheitern aufheizen aufhelfen aufhellen aufhetzen aufheulen aufholen aufhorchen aufhängen aufhören aufhübschen
+
+Chefhändler
+
+daraufhin draufhat draufhauen
+
+Dorfhaus
+
+Eislaufhalle
+
+fünfhundert
+
+Hofherr
+
+Kampfhandlung Kampfhubschrauber Kampfhunde Kampfhähne
+
+Kopfhaar Kopfhaltung Kopfhaube Kopfhaut Kopfhörer
+
+Kaufhalle Kaufhaus Kaufherr Kaufhold
+
+krampfhaft
+
+Schafhaltung Schafherde Schafhirte
+
+Schilfhütte
+
+Steifheit Schlaffheit
+
+Strafhaft
+
+Strumpfhose Stumpfheit
+
+Topfhaarschnitt
+
+unaufhaltsam unaufhörlich
+
+Wahlkampfhelfer
+
+Impfstoffhersteller
+
+Luftschiffhafen
+
+Pfaffhausen Schaffhausen
+
+Riffhai
+
+Stoffhändler
+
+Werkstoffhof
+
+
+
+\item \uselig{fj} und \uselig{ffj}
+
+
+aufjagen aufjaulen aufjauchzen aufjohlt
+
+Dorfjunge Dorfjustiz Dorfjugend Dorfjäger Dorfjubiläum
+
+Fünfjahresplan Fünfjahresfeier Knefjahr Tarifjahr Strafjahr
+
+fünfjährig elfjährig zwölfjährig
+
+Kopfjäger Kopfjucken Kopfjagd
+
+Strafjustiz Strafjurist Chefjurist
+
+Laufjunge Laufjahr Laufjacke
+
+Wahlkampfjahr Wettkampfjahr Kampfjet
+
+Stoffjacke
+
+Kampfjagd Kampfjodeln (gibt's so etwas?!)
+
+Hofjäger
+
+Golfjahr Golfjunge Golfjunioren Golfjuniorinnen
+
+\ \ \ aber: Sognefjord Dovrefjell Prokofjew
+
+
+
+\item \uselig{fk} und \uselig{ffk}
+
+
+aufkam aufkaufen aufkeimen aufkehren aufklaffen aufkläffen aufklappen aufklatschen aufklauben aufkleben aufklären aufklingen aufklopfen aufknacken aufknöpfen aufknüpfen aufkochen aufkommen aufkreischen aufkrempeln aufkreuzen aufkriegen aufkurbeln aufkündigen
+
+Napfkuchen Stopfkugel Briefkasten Briefkästen Kopfkissen
+ Kehlkopfknoten Kaufkraft
+
+Pfeifkonzert Trumpfkarte
+
+Tarifkonflikt Tarifkommission
+
+Stoffkissen Stoffkatze Treibstoffkosten Kliffkante Auspuffklang
+
+\end{itemize}
+
+
+
diff --git a/macros/luatex/latex/selnolig/selnolig.lua b/macros/luatex/latex/selnolig/selnolig.lua
new file mode 100644
index 0000000000..7bf40d135e
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig.lua
@@ -0,0 +1,201 @@
+-- Lua code for the selnolig package.
+-- To be loaded with an instruction such as
+-- \directlua{ require("selnolig.lua") }
+-- from a (Lua)LaTeX .sty file.
+--
+-- Author: Mico Loretan (loretan dot mico at gmail dot com)
+-- (with crucial contributions from Taco Hoekwater,
+-- Patrick Gundlach, and Steffen Hildebrandt)
+--
+-- The entire selnolig package is placed under the terms
+-- of the LaTeX Project Public License, version 1.3 or
+-- later. (http://www.latex-project.org/lppl.txt).
+-- It has the status "maintained".
+
+selnolig = { }
+selnolig.module = {
+ name = "selnolig",
+ version = "0.256",
+ date = "2015/10/26",
+ description = "Selective suppression of typographic ligatures",
+ author = "Mico Loretan",
+ copyright = "Mico Loretan",
+ license = "LPPL 1.3 or later"
+}
+
+debug=false -- default: don't output detailed information
+
+-- Define variables corresponding to various text nodes;
+-- cf. sections 8.1.2 and 8.1.4 of LuaTeX reference guide
+local rule = node.id('rule')
+local glue = node.id("glue") --
+local kern = node.id('kern')
+local glyph = node.id('glyph') --
+local whatsit = node.id("whatsit") --
+
+local userdefined
+
+for n,v in pairs ( node.whatsits() ) do
+ if v == 'user_defined' then userdefined = n end
+end
+
+local identifier = 123456 -- any unique identifier
+local noliga={}
+local keepliga={} -- String -> Boolean
+
+function debug_info(s)
+ if debug then
+ texio.write_nl(s)
+ end
+end
+
+local blocknode = node.new(whatsit, userdefined)
+blocknode.type = 100
+blocknode.user_id = identifier
+
+local suppression_on = true -- if false, process_ligatures won't do anything
+
+local prefix_length = function(word, byte)
+ return unicode.utf8.len( string.sub(word,0,byte) )
+end
+
+ -- Problem: string.find and unicode.utf8.find return
+ -- the byte-position at which the pattern is found
+ -- instead of the character-position. Fix this by
+ -- providing a dedicated string search function.
+
+local unicode_find = function(s, pattern, position)
+ -- Start by correcting the incoming position
+ if position ~= nil then
+ -- debug_info("Position: "..position)
+ sub = string.sub(s, 1, position)
+ position=position+string.len(sub) - unicode.utf8.len(sub)
+ -- debug_info("Corrected position: "..position)
+ end
+ -- Now execute find and fix it accordingly
+ byte_pos = unicode.utf8.find(s, pattern, position)
+ if byte_pos ~= nil then
+ -- "convert" byte_pos to "unicode_pos"
+ return unicode.utf8.len( string.sub(s, 1, byte_pos) )
+ else
+ return nil
+ end
+end
+
+function process_ligatures(nodes,tail)
+ if not suppression_on then
+ return -- suppression disabled
+ end
+
+ local s={}
+ local current_node=nodes
+ local build_liga_table = function(strlen,t)
+ local p={}
+ for i = 1, strlen do
+ p[i]=0
+ end
+ for k,v in pairs(t) do
+ -- debug_info("Match: "..v[3])
+ local c= unicode_find(noliga[v[3]],"|")
+ local correction=1
+ while c~=nil do
+ --debug_info("Position "..(v[1]+c))
+ p[v[1]+c-correction] = 1
+ c = unicode_find(noliga[v[3]],"|",c+1)
+ correction = correction+1
+ end
+ end
+ --debug_info("Liga table: "..table.concat(p, ""))
+ return p
+ end
+ local apply_ligatures=function(head,ligatures)
+ local i=1
+ local hh=head
+ local last=node.tail(head)
+ for curr in node.traverse_id(glyph,head) do
+ if ligatures[i]==1 then
+ debug_info("Inserting nolig whatsit before glyph: " ..unicode.utf8.char(curr.char))
+ node.insert_before(hh,curr, node.copy(blocknode))
+ hh=curr
+ end
+ last=curr
+ if i==#ligatures then
+ -- debug_info("Leave node list on position: "..i)
+ break
+ end
+ i=i+1
+ end
+ if(last~=nil) then
+ debug_info("Last char: "..unicode.utf8.char(last.char))
+ end
+ end
+ for t in node.traverse(nodes) do
+ if t.id==glyph then
+ s[#s+1]=unicode.utf8.char(t.char)
+ end
+ if ( t.id==glue or t.next==nil or t.id==kern or t.id==rule ) then
+ local f=string.gsub(table.concat(s,""),"[\\?!,\\.]+","")
+ local throwliga={}
+ for k,v in pairs (noliga) do
+ local count=1
+ local match = string.find(f,k)
+ while match do
+ count = match
+ keep = false
+ debug_k1 = ""
+ for k1,v1 in pairs (keepliga) do
+ if v1 and string.find(f,k1) and string.find(k1,k) then
+ debug_k1=k1
+ keep=true
+ break
+ end
+ end
+ if not keep then
+ debug_info("pattern match: "..f .." - "..k)
+ local n = match + string.len(k) - 1
+ table.insert(throwliga,{prefix_length(f,match),n,k})
+ else
+ debug_info("pattern match nolig and keeplig: "..f .." - "..k.." - "..debug_k1)
+ end
+ match= string.find(f,k,count+1)
+ end
+ end
+ if #throwliga==0 then
+ -- debug_info("No ligature suppression for: "..f)
+ else
+ debug_info("Do ligature suppression for: "..f)
+ local ligabreaks = build_liga_table(f:len(),throwliga)
+ apply_ligatures(current_node,ligabreaks)
+ end
+ s = {}
+ current_node = t
+ end
+ end
+end -- end of function process_ligatures(nodes,tail)
+
+function suppress_liga(s,t)
+ noliga[s] = t
+end
+
+function always_keep_liga(s)
+ keepliga[s] = true
+end
+
+function enable_suppression(val)
+ suppression_on = val
+ if val then
+ debug_info("Turning ligature suppression back on")
+ else
+ debug_info("Turning ligature suppression off")
+ end
+end
+
+function enableselnolig()
+ luatexbase.add_to_callback( "ligaturing",
+ process_ligatures, "Suppress ligatures selectively", 1 )
+end
+
+function disableselnolig()
+ luatexbase.remove_from_callback( "ligaturing",
+ "Suppress ligatures selectively" )
+end
diff --git a/macros/luatex/latex/selnolig/selnolig.pdf b/macros/luatex/latex/selnolig/selnolig.pdf
new file mode 100644
index 0000000000..0399b46a73
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig.pdf
Binary files differ
diff --git a/macros/luatex/latex/selnolig/selnolig.sty b/macros/luatex/latex/selnolig/selnolig.sty
new file mode 100644
index 0000000000..a31b9ebd88
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig.sty
@@ -0,0 +1,267 @@
+% !TeX root = selnolig.tex
+% !TEX TS-program = lualatex
+
+% This entire package is placed under the terms of the
+% LaTeX Project Public License, version 1.3 or later
+% (http://www.latex-project.org/lppl.txt).
+% It has the status "maintained".
+%
+% Author: Mico Loretan (loretan dot mico at gmail dot com)
+
+
+% Part 1: Preliminaries
+% ---------------------
+
+\def\selnoligpackagename{selnolig}
+\def\selnoligpackageversion{0.302}
+\def\selnoligpackagedate{2015/10/26}
+
+% Announce who we are.
+
+\typeout{=== Package \selnoligpackagename,
+ Version \selnoligpackageversion,
+ Date \selnoligpackagedate\space ===}
+\ProvidesPackage{selnolig}[\selnoligpackagedate]
+
+
+% Issue warning message if not running under LuaLaTeX.
+
+\RequirePackage{ifluatex}
+\ifluatex
+ \RequirePackage{luatexbase}
+\else
+ \typeout{ ======================================= }
+ \typeout{ WARNING WARNING WARNING }
+ \typeout{ --------------------------------------- }
+ \typeout{ The ligature suppression macros of the }
+ \typeout{ selnolig package *require* LuaLaTeX. }
+ \typeout{ Because you're NOT running this package }
+ \typeout{ under LuaLaTeX, ligature suppression }
+ \typeout{ *can not* be performed. }
+ \typeout{=========================================}
+\fi
+
+% If the 'fontspec' package isn't loaded by the time
+% the '\begin{document}' directive is encoutered, issue
+% an error message and exit.
+
+\AtBeginDocument{%
+\ifluatex
+ \@ifpackageloaded{fontspec}{}{%
+ \PackageError{selnolig}{%
+ ========================================== \MessageBreak
+ Error Alert Error Alert \MessageBreak
+ ------------------------------------------ \MessageBreak
+ The selnolig package *requires* the \MessageBreak
+ 'fontspec' package, but it hasn't been \MessageBreak
+ loaded. Exiting now. \MessageBreak
+ ===========================================}
+ }
+\fi
+}
+
+% Set up some fundamental Boolean variables, their
+% default values, and define the user options.
+
+% The main language options are 'english' and 'german'.
+% We provide the option 'otherlang' option just in case
+% a user wants to provide ligature suppression patterns
+% for languages other than English and German.
+
+\newif\if@english\@englishfalse
+\newif\if@german\@germanfalse
+\newif\if@otherlang\@otherlangfalse
+
+\DeclareOption{english}{\@englishtrue}
+% synonymous options:
+ \DeclareOption{usenglish}{\@englishtrue}
+ \DeclareOption{ukenglish}{\@englishtrue}
+ \DeclareOption{USenglish}{\@englishtrue}
+ \DeclareOption{UKenglish}{\@englishtrue}
+ \DeclareOption{american}{\@englishtrue}
+ \DeclareOption{british}{\@englishtrue}
+ \DeclareOption{canadian}{\@englishtrue}
+ \DeclareOption{australian}{\@englishtrue}
+ \DeclareOption{newzealand}{\@englishtrue}
+
+\DeclareOption{ngerman}{\@germantrue}
+% synonymous options:
+ \DeclareOption{german}{\@germantrue}
+ \DeclareOption{austrian}{\@germantrue}
+ \DeclareOption{naustrian}{\@germantrue}
+ \DeclareOption{swiss}{\@germantrue}
+ \DeclareOption{swissgerman}{\@germantrue}
+
+\DeclareOption{otherlang}{\@otherlangtrue}
+% synonymous option:
+ \DeclareOption{otherlanguage}{\@otherlangtrue}
+
+
+% For English, the default is to load only a fairly basic
+% set of non-ligation rules pertaining to f-ligatures.
+% Among them are the "standard five" (ff, fi, fl, ffi,
+% and ffl) ligatures as well as the ft ligature.
+%
+% Two options to augment the "basic" setting:
+% - broadf More non-ligation rules for f-ligatures
+% - hdlig Additional ligature suppression rules for
+% 'historic' and/or 'discretionary' ligatures,
+% e.g., ct, sp, st, sk, th, as, is, us, fr,
+% ll, et, at, and ta
+
+\newif\if@broadfset\@broadfsetfalse
+\DeclareOption{broadf}{\@broadfsettrue}
+
+\newif\if@hdligset\@hdligsetfalse
+\DeclareOption{hdlig}{\@hdligsettrue}
+
+% The 'basic' option automatically sets the preceding
+% Booleans to 'false'.
+
+\DeclareOption{basic}{\@broadfsetfalse\@hdligsetfalse}
+
+
+% The package also provides hyphenation exception
+% patterns for English and German language words.
+% Loading these patterns is enabled by default. This
+% can be disabled by providing the option
+% 'noadditionalhyphenationpatterns'.
+
+\newif\if@addlhyph\@addlhyphtrue
+\DeclareOption{noadditionalhyphenationpatterns}{\@addlhyphfalse}
+
+
+
+% The option 'noftligs' serves to suppress ft and fft
+% ligatures *globally*. Default value: 'false'.
+
+\newif\if@noftligs\@noftligsfalse
+\DeclareOption{noftligs}{\@noftligstrue}
+
+
+% Finally, an option to set most language-related
+% Boolean variables (other than '@addlhyph') to
+% 'true' simultaneously.
+
+\DeclareOption{all}{%
+ \@englishtrue \@broadfsettrue \@hdligsettrue
+ \@germantrue \@otherlangtrue}
+
+% Finally, process all options
+\ProcessOptions\relax
+
+
+
+% Part 2: Load the lua code and set up the user macros
+% ----------------------------------------------------
+
+\ifluatex
+ % Load the lua code contained in 'selnolig.lua'.
+ \directlua{ require("selnolig.lua") }
+
+ % Commands to switch selnolig's routines on and off
+ \newcommand\selnoligon{%
+ \directlua{ enableselnolig() }%
+ }
+
+ \newcommand\selnoligoff{%
+ \directlua{ disableselnolig() }%
+ }
+
+ % By default, selnolig's macros are switched on
+ \selnoligon
+
+
+ % Recording operations of selnolig package to the log
+ % file is enabled via the '\debugon' command.
+ % Note: the default value of 'debug' (set in
+ % 'selnolig.lua') is 'false'. To turn off logging
+ % of selnolig's activity, use the command \debugoff.
+ \newcommand\debugon{%
+ \directlua{ debug=true }
+ }
+ \newcommand\debugoff{%
+ \directlua{ debug=false }
+ }
+
+
+ % The first main user macro is called '\nolig':
+ \newcommand\nolig[2]{
+ \directlua{
+ suppress_liga( "\luatexluaescapestring{#1}",
+ "\luatexluaescapestring{#2}" )
+ }
+ }
+
+ % A second user macro allows global overriding of
+ % rules set by \nolig instructions:
+ \newcommand\keeplig[1]{
+ \directlua{
+ always_keep_liga( "\luatexluaescapestring{#1}" )
+ }
+ }
+
+ % A third user macro turns ligature suppression off
+ % temporarily:
+ \newcommand\uselig[1]{%
+ \directlua{ enable_suppression(false) }%
+ \mbox{#1}%
+ \directlua{ enable_suppression(true) }%
+ }
+
+ % A fourth user macro: '\breaklig'. This is
+ % hopefully easier to remember than having to
+ % type "\-\hspace{0pt}".
+
+ \newcommand{\breaklig}{\-{\hspace{0pt}}}
+
+
+\else
+ % If *not* running under LuaLaTeX, provide dummy
+ % definitions for package's four main user macros
+ % as well as for the auxilliary macros \selnoligon,
+ % \selnoligoff, \debugon, and \debugoff.
+ \newcommand{\nolig}[2]{}
+ \newcommand{\keeplig}[1]{}
+ \newcommand{\uselig}[1]{\mbox{#1}}
+ \newcommand{\breaklig}{\-{\hspace{0pt}}}
+ \let\selnoligon\relax
+ \let\selnoligoff\relax
+ \let\debugon\relax
+ \let\debugoff\relax
+
+\fi
+
+
+% Part 3: What to do if the 'english' option is set
+% -------------------------------------------------
+
+\if@english
+ \ifluatex % English ligature suppression rules
+ \RequirePackage{selnolig-english-patterns}
+ \fi
+ \if@addlhyph
+ \RequirePackage{selnolig-english-hyphex}
+ \fi
+\fi
+
+
+% Part 4: What to do if the 'ngerman' option is set
+% -------------------------------------------------
+
+\if@german
+ \ifluatex % German ligature suppression rules
+ \RequirePackage{selnolig-german-patterns}
+ \fi
+ \if@addlhyph
+ \RequirePackage{selnolig-german-hyphex}
+ \fi
+\fi
+
+
+% Part 5: What to do if the 'otherlang' option is set
+% ---------------------------------------------------
+
+\if@otherlang
+ % currently nothing included
+\fi
diff --git a/macros/luatex/latex/selnolig/selnolig.tex b/macros/luatex/latex/selnolig/selnolig.tex
new file mode 100644
index 0000000000..a639c8840e
--- /dev/null
+++ b/macros/luatex/latex/selnolig/selnolig.tex
@@ -0,0 +1,1331 @@
+% !TEX TS-program = lualatex
+% arara: lualatex
+% arara: lualatex
+\documentclass[11pt]{article}
+\usepackage{lua-check-hyphen}
+
+% This entire package is placed under the terms of the
+% LaTeX Project Public License, version 1.3 or later
+% (http://www.latex-project.org/lppl.txt).
+% It has the status "maintained".
+%
+% Author: Mico Loretan (loretan dot mico at gmail dot com)
+% Date: 2015/10/26
+
+% The file selnolig.tex contains the user guide to the
+% selnolig package.
+
+% Can only compile this file if running Lua(La)TeX:
+\usepackage{ifluatex}
+\ifluatex\else
+ \typeout{ =========================================}
+ \typeout{ The file selnolig.tex must be compiled }
+ \typeout{ using LuaLaTeX. Exiting immediately. }
+ \typeout{ =========================================}
+ \endinput
+\fi
+
+% Load the fontspec package and specify
+% several font families
+\usepackage{fontspec}
+
+\ifdefined\suppressfontnotfounderror
+ \expandafter\let\csname xetex_suppressfontnotfounderror:D\endcsname
+ \suppressfontnotfounderror
+\else
+ \expandafter\let\csname xetex_suppressfontnotfounderror:D\endcsname
+ \luatexsuppressfontnotfounderror
+\fi
+
+
+\setmainfont[FeatureFile= gpp-ft.fea,
+ Numbers = OldStyle,
+ Ligatures = {TeX, Common, Rare},
+ BoldFont = {Garamond Premier Pro},
+ ItalicFont = {Garamond Premier Pro Italic}]
+ {Garamond Premier Pro}
+
+\setsansfont[Scale=MatchLowercase,
+ Ligatures = NoCommon]
+ {Myriad Pro}
+
+\setmonofont[Scale=0.81,
+ Ligatures = NoCommon]
+ {Consolas}
+
+\newfontfamily\ebg[ Numbers = OldStyle,
+ Ligatures = {TeX, Common, Discretionary, Historic},
+ ItalicFeatures = {Scale = MatchLowercase},
+ ItalicFont = {EB Garamond 12 Italic}]
+ {EB Garamond 12 Regular}
+
+\newfontfamily\sabon[Ligatures={Common,Rare,TeX},
+ Scale=MatchLowercase]
+ {Sabon Next LT Pro}
+
+\newfontfamily\blackletter[Ligatures=NoCommon]
+ {UnifrakturMaguntia}
+
+
+
+% Load several more packages, including babel
+% and -- of course! -- selnolig.
+
+\usepackage{geometry,tabularx,booktabs,ragged2e}
+\usepackage[english=american]{csquotes}
+
+\usepackage[ngerman,english]{babel}
+
+\usepackage[ngerman,english,hdlig,broadf]{selnolig}
+
+% Suppress st ligatures for German words that
+% occur in this user guide.
+\nolig{Kunststo}{Kuns|ts|to} % Kunststoff
+\nolig{Bausto}{Baus|to} % Baustoff
+\nolig{streif}{s|treif} % streifte
+\nolig{instrum}{ins|trum} % Zupfinstrument
+\nolig{justiz}{jus|tiz} % Strafjustiz
+\nolig{Konstanz}{Kons|tanz}
+\nolig{Institut}{Ins|titut}
+\nolig{Wasserstoff}{Wassers|toff}
+\nolig{stiefl}{s|tiefl} % stiefle
+\nolig{straff}{s|traff}
+\nolig{aufisst}{auf|iss|t} % suppress st liga as well
+\nolig{löste}{lös|te}
+\nolig{straße}{s|traße}
+\nolig{steifbein}{s|teifbein}
+\nolig{steiflehnig}{s|teiflehnig}
+\nolig{strafbar}{s|trafbar}
+\nolig{belustigt}{belus|tigt}
+\nolig{flichst}{flichs|t} % flichst, höflichst
+\nolig{trittst}{tritts|t}
+\nolig{vortrefflichsten}{vortrefflichs|ten}
+\nolig{schnellste}{schnells|te}
+\nolig{sträflich}{s|träflich}
+\nolig{Surftest}{Surftes|t}
+\nolig{bestanden}{bes|tanden}
+\nolig{leistung}{leis|tung}
+\nolig{Faust}{Faus|t}
+
+% Undo action of rule, activated by broadf option
+% \nolig{ffing}{ff|ing}
+% for a couple of German words:
+ \keeplig{ffingrig}
+ \keeplig{ffinger}
+
+\nolig{tzeit}{t|zeit} % for Fraktur example in section 6
+
+\hyphenation{charles-town}
+% provide some German hyphenation patterns for ...
+\hyphenation{jugend-treff-lei-ter vor-treff-lich
+ vor-treff-li-che auf-for-de-rung hin-auf-blick-te
+ auf-füh-ren auf-hor-chen-den her-auf-kom-men
+ un-er-schöpf-lich un-be-greif-lich kauf-leu-ten
+ schlaf-lo-sig-keit ver-werf-li-che}
+
+\debugon
+
+
+% Load still a few more packages...
+\usepackage{microtype}
+ \LoadMicrotypeFile{pad}
+\usepackage{multicol}
+\usepackage[bottom,splitrule]{footmisc}
+
+\usepackage{sectsty}
+ \allsectionsfont{\mdseries}
+
+\usepackage{tocloft}
+ \cftsetindents{sec}{0em}{1.75em}
+ \cftsetindents{subsec}{1.75em}{2em}
+ \cftsetindents{subsubsec}{3.75em}{3em}
+ \setlength\cftbeforesecskip{1ex}
+ \renewcommand{\cfttoctitlefont}{\large}
+ \renewcommand{\cftsecfont}{\mdseries}
+ \renewcommand{\cftsubsecfont}{\mdseries}
+ \renewcommand{\cftsecpagefont}{\mdseries}
+ \renewcommand{\cftsubsecpagefont}{\mdseries}
+ \renewcommand{\cftsecleader}{\cftdotfill{\cftdotsep}}
+
+\usepackage{fancyvrb}
+\DefineShortVerb{\|}
+
+% Logos for "LuaLaTeX" and "XeLaTeX"
+\usepackage{metalogo}
+ \makeatletter
+ \def\xl@drop@TeX@e{0.34ex} % default: 0.5ex
+ \def\xl@drop@Xe@e{0.34ex} % default: 0.5ex
+ \def\xl@kern@La@La{-.33em} % default: -0.36ex
+ \def\xl@kern@LaTeX@aT{-.16em} % default: -0.15ex
+ \makeatother
+
+% Some frequently-used commands in this document:
+\newcommand{\pkg}[1]{\textsf{#1}}
+\newcommand{\opt}[1]{\texttt{#1}}
+\newcommand{\cmmd}[1]{\texttt{\textbackslash #1}}
+
+\newcommand\utf{\textsc{utf-8}}
+
+% Modify the \appendix command
+\let\oldappendix\appendix
+\renewcommand\appendix{%
+ %\clearpage
+ \addtocontents{toc}{\protect{\vspace{1\baselineskip}}}
+ \addtocontents{toc}{\protect{\mdseries Appendices\par}}
+ \noindent
+ {\Large Appendices}
+ \oldappendix}
+
+\frenchspacing
+\clubpenalty10000
+\widowpenalty10000
+
+\usepackage[svgnames]{xcolor}
+\usepackage[colorlinks=true,linktocpage,
+ allcolors=DarkBlue]{hyperref}
+\usepackage[capitalize,nameinlink,noabbrev]{cleveref}
+
+% The macros \selnoligpackagename,
+% \selnoligpackageversion, and \selnoligpackagedate
+% used below are defined in 'selnolig.sty'.
+
+\title{The \selnoligpackagename\ package: \\
+Selective suppression of typographic ligatures\thanks{
+Current version: \selnoligpackageversion. Features of the \pkg{selnolig} package are subject to change without prior notice.
+\newline\hspace*{\parindent}
+The main text font used in this document is Garamond Premier Pro. {\ebg EB Garamond} is used for words that use the {\ebg fb, fh, fj, fk, ffb, ffh, ffj, ffk, \emph{es}, and \emph{sk}} ligatures. \enquote{Common}, \enquote{discretionary}, and \enquote{historic} typographic ligatures are enabled for these text fonts\textemdash \emph{and} are suppressed selectively using the rules of the \pkg{selnolig} package.} }
+
+\author{Mico Loretan\thanks{
+\href{mailto:loretan.mico@gmail.com}{loretan dot mico at gmail dot com}.}}
+
+\date{\selnoligpackagedate}
+
+\begin{document}
+\VerbatimFootnotes
+\pagenumbering{roman}
+
+\selnoligoff
+\maketitle
+\selnoligon
+
+\begin{abstract}
+
+The \pkg{selnolig} package suppresses typographic ligatures selectively, i.e., based on predefined search patterns. The search patterns focus on ligatures deemed inappropriate because they span morpheme boundaries. For example, the word \opt{shelfful}, which is mentioned in the \TeX book as a word for which the ff~ligature might be inappropriate, is automatically typeset as shelfful rather than as \uselig{shelfful}.
+\newline\hspace*{\parindent}
+For English and German language documents, the \pkg{selnolig} package provides extensive rules for the selective suppression of so-called \enquote{common} ligatures. These comprise the ff, fi, fl, ffi, and~ffl ligatures as well as the ft and~fft ligatures. Other f-ligatures, such as {\ebg\uselig{fb}}, {\ebg\uselig{fh}}, {\ebg\uselig{fj}} and {\ebg\uselig{fk}}, are suppressed globally, while making exceptions for names and words of non-English/German origin, such as {\ebg Kafka} and {\ebg fjord}.
+\newline\hspace*{\parindent}
+For English language documents, the package further provides ligature suppression rules for a number of so-called \enquote{discretionary} or \enquote{rare} ligatures, such as~ct, st, and~sp.
+\newline\hspace*{\parindent}
+The \pkg{selnolig} package requires use of the \LuaLaTeX\ format provided by a recent \TeX\ distribution, e.g., \TeX Live\,2013 and MiK\TeX\,2.9.
+\end{abstract}
+
+\tocloftpagestyle{empty}
+\tableofcontents
+
+\clearpage
+\pagenumbering{arabic}
+
+\section{Introduction}
+
+The ability of \TeX\ and Friends to use typographic ligatures has long been cherished by its users. Indeed, the automated and transparent use of typographic ligatures by \TeX\ and Friends is often offered up as one of the reasons for using these programs to obtain high-quality typeset output.
+
+However, even though the automatic use of typographic ligatures is highly desirable in general, there are words for which the use of certain typographic ligatures may not be appropriate. The \TeX book observes, on page~19, that the word |shelfful| may look better if it is typeset as \enquote{shelfful}, i.e., \emph{without} the ff-ligature, rather than as \enquote{\uselig{shelfful}}. Some other English-language words that would generally be considered to be good candidates for non-use of ligatures are \uselig{cufflink} and \uselig{offload}; compare their appearance with that of cufflink and offload. Observe that all three of these words are composed of two meaning-bearing particles or \emph{morphemes}: the first morpheme ends in an~\enquote{f\,} or~\enquote{ff\,} while the second morpheme starts with either an~\enquote{f\,} (in the case of shelfful) or an~\enquote{l} (in the cases of cufflink and offload). A \href{http://en.wikipedia.org/wiki/Morpheme}{morpheme}, briefly stated, is the smallest linguistic unit within a word that bears distinct meaning; all words\textemdash other than nonsense words, I suppose\textemdash contain at least one morpheme. The words apple and orange contain one morpheme each, and the words apples, oranges, shelfful, cufflink, and offload each contain \emph{two} morphemes. The main purpose of the \pkg{selnolig} package is to provide methods and rules for an automated yet selective (rather than global) suppression of typographic ligatures that span certain morpheme boundaries.
+
+For English language documents, the need to suppress typographic ligatures that span morpheme boundaries does not appear to be a hugely pressing typographic concern, possibly because English doesn't feature composite words that frequently. However, in other languages, such as German, composite words are much more common. In these languages, there is naturally a much greater potential for composite words to feature instances of |ff|, |fi|, |fl| etc.\ character pairs that span morpheme boundaries. In German typography, a ligature that spans a morpheme boundary appears to be something that should be avoided at (nearly) all cost, presumably because the presence of such ligatures has the potential to impair seriously the intelligibility of the composite words.%\footnote{For German texts, I believe that the \emph{Duden} provides authoritative backing for questions related to selective ligature suppression. For English texts, I'm not aware of the existence of a document, issued by an official or quasi-official body, that prescribes whether ligatures that span morpheme boundaries should be suppressed. If anybody can provide such a reference, I would be happy to list it.}
+
+\TeX\ and Friends offer several methods for suppressing ligatures on a case-by-case basis. In \LaTeX, there are three basic methods for suppressing ligatures: (i)~insertion of an \enquote{empty atom}, |{}|, between the characters whose ligature should be avoided; (ii)~insertion of an explicit italic correction, |\/|; and (iii)~insertion of an explicit \enquote{kern}, e.g., |\kern0pt| or \Verb/\hspace{0pt}/.\footnote{Note, though, that the first ligature suppression method, \Verb/{}/, does \emph{not} work if the document is compiled with \LuaLaTeX, and that the italic-correction method can produce inferior results if the text is being typeset in, well, the italic font shape.} The \pkg{babel} package, when used with the \opt{ngerman} or \opt{german} options, offers the \enquote{shortcut} macro \Verb/"|/ to suppress ligatures. A drawback of these ligature suppression methods is that they must be applied separately to each and every occurrence of all words that contain unwanted ligatures. As such, these case-by-case methods are both time-intensive and tedious. Moreover, there's always a residual risk that some words for which ligatures should be suppressed will be overlooked in the editing process.
+
+There are also several preprocessor-type packages and scripts\textemdash I mention \pkg{rmligs} and \pkg{Ligatures-German} in \cref{sec:thanks} below, but others exist as well\textemdash that scan the input file(s) and insert marks (usually, but not necessarily, the \pkg{babel} \Verb/"|/ shortcuts) in the places where ligatures should be avoided. While ingenious, these preprocessor-based solutions suffer from several drawbacks which, taken together, may help explain why they do not appear to be in widespread use despite their usefulness. First, they add complexity to the document preparation process. E.g., if the document is being edited inside an IDE or integrated development environment, the input files have to be closed prior to running the preprocessor scripts on them; then the files have to be re-opened in order to recompile them. Second, the presence of \Verb+"|+ macros in the input may interfere with the work of programs such as spell checkers. Third, \textsc{afaict} none of the ligature-suppressing preprocessor packages I'm familiar with have been written to handle ligature suppression for English language texts. Fourth, their scope generally seems to be limited to the most basic f-ligatures (ff, fi, fl, ffi, and ffl), making them less than fully useful for fonts that provide further f-ligatures, such as ft and fft, or \enquote{rare} ligatures such as st and sp. Fifth, they usually require access to auxilliary programs (e.g., a \textsc{unix} environment and a \opt{perl} distribution in the case of the \pkg{rmligs} package) that need not be present on a given user's computer.
+
+What has \emph{not} been available so far is a \LaTeX\ package that performs selective ligature suppression while avoiding the drawbacks associated with the preprocessor approach. Such a package should provide lists of language-specific word patterns for which ligatures should be suppressed, and it should systematically discover, during compilation, all words to which these patterns apply and proceed to suppress the indicated ligatures. Such a package should, at a minimum, be able to handle the basic f-ligatures (ff, fi, fl, ffi, and ffl); given the increasing prevalence of ligature-rich Opentype fonts, it would be useful is the \LaTeX\ package were also able to suppress additional f-ligatures, such as ft and fft, as well as rare ligatures. The package should also be reasonably easy to extend, in the sense that users should be able to augment or modify the ligature-suppression rules to suit their documents' characteristics. The \pkg{selnolig} package is meant to meet all of these goals and criteria.
+
+The \pkg{selnolig} package provides rules to suppress \emph{selectively} the following f-ligatures, for both English and German documents: ff, fi, fl, ffi, and ffl\textemdash the \enquote{standard} f-ligatures that should be familiar to most users of Computer Modern fonts\textemdash as well as the~ft and~fft ligatures. The latter two ligatures, while not provided by the Computer Modern and Latin Modern font families, are frequently available in \href{http://en.wikipedia.org/wiki/Serif#Old_Style}{oldstyle} (also known as \enquote{Garalde}) font families.\footnote{In some oldstyle font families, the ligatures \enquote{ft} and \enquote{fft} are rendered as \enquote{\sabon ft} and \enquote{\sabon fft}, respectively.} Oldstyle-type font families generally feature a great variety of typographic ligatures. Given the beauty and growing popularity of these font families, it's important to be able to make good use of many of their features, including the presence of ligatures outside the \enquote{basic five} set.
+
+In addition to supressing ligatures selectively for the f-ligatures mentioned above, the ligatures {\ebg \uselig{fb}, \uselig{fh}, \uselig{fj}, \uselig{fk},} and \emph{\uselig{ij}} are suppressed \emph{globally} for both English and German language documents. Exceptions are provided, however, so as not to suppress these ligatures for selected words of \emph{non-English\slash German} origin, such as {\ebg fjord, fjell, Prokofjew, Kafka,} and \emph{rijsttafel}.
+
+\enlargethispage{0.5\baselineskip}
+
+For English documents, the \pkg{selnolig} package recognizes two further options, \opt{broadf} and \opt{hdlig}. If \opt{broadf} is set, additional f-ligatures will be suppressed selectively. If \opt{hdlig} option is set, selective ligature suppression is performed on discretionary\slash rare ligatures such as ct, st, sp, {\ebg\emph{sk}}, \emph{th}, \emph{at}, \emph{et}, \emph{ll}, \emph{as}, \emph{\ebg es}, \emph{is}, and~\emph{us}. No rules are currently provided to suppress historic and/or disrectionary\slash rare ligatures for German documents.\footnote{A quick remark on the classification of typographic ligatures. The f-ligatures are generally called \enquote{common} in most families. Beyond this group, though, there appears to be little or no standardization across Opentype fonts as to which typographic ligatures should be labelled \enquote{historic} and which ones should be labelled \enquote{discretionary}\slash\enquote{rare}. For instance, the fonts Latin Modern Roman, Garamond Premier Pro, and Hoefler Text report having \enquote{only} discretionary ligatures. In contrast, the fonts Junicode, Cardo, EB Garamond, and Palatino Linotype all report having both historic and discretionary ligatures. The name of the package option |hdlig| is supposed to convey a sense of agnosticism as to how these non-common ligatures should be labelled.}
+
+Of course, no claim as to the completeness of either the English or German language list is or can be made. Hence, the \pkg{selnolig} package also makes it straightforward for users to provide their own, supplemental, ligature suppression rules to treat words that occur in their documents but aren't yet covered by the package. Please feel free to email me such words, so that I can augment and update the package's ligature suppression rules suitably. A suggested template for reporting issues with the \pkg{selnolig} package is provided in \cref{sec:template}.
+
+The \pkg{selnolig} package further provides supplemental hyphenation exception lists for both English and German language words. The words in these lists are generally composite and contain one or more typographic ligatures that should be suppressed.
+
+The remainder of this document is organized as follows. \Cref{sec:hurry} provides instructions for loading the \pkg{selnolig} package and making one's document(s) suitable for compilation under \LuaLaTeX. The package's overall approach to the suppression of ligatures that span morpheme boundaries is explained in \cref{sec:approach}, the user macros are presented in \cref{sec:structure}, and options that affect the package's workings are discussed in \cref{sec:options}. \Cref{sec:further} addresses further issues that may arise when looking to break up typographic ligatures. The package's ligature suppression rules for English and German language documents are listed in \cref{sec:eng-listing,sec:germ-listing}. The code of the package's main ``style'' file, \pkg{selnolig.sty}, and Lua code file, \pkg{selnolig.lua}, is listed in \cref{sec:sty,sec:luacode}. \Cref{sec:template} provides a suggested template for reporting bugs and other issues with the package.
+
+Finally, in \cref{sec:budd} I provide lists of ligature-containing words caught by \pkg{selnolig}'s rules in two English-language and three German-language literary classics. The English pieces are \emph{Call of the Wild} and \emph{The Sea Wolf}, both by Jack London. The German pieces are Thomas Mann's \emph{Die Buddenbrooks} and Goethe's \emph{Faust}, both \emph{Part~I} and \emph{Part~II}. (Of course, I make no claim whatsoever as to any kind of statistical representativeness of this selection!) Unsurprisingly, the German pieces contain far more words for which ligatures are broken up by \pkg{selnolig} than do the English pieces.
+
+
+
+\section{I'm in a hurry! How do I start using this package?} \label{sec:hurry}
+
+\subsection[How do I load the selnolig package?]{How do I load the \pkg{selnolig} package?}
+
+\begin{itemize}
+\item If your document is in English and you want to enable a \enquote{basic} set of rules to suppress f-ligatures selectively, load the package by issuing the following instruction in the preamble of your document:
+\begin{Verbatim}
+ \usepackage[english]{selnolig}
+\end{Verbatim}
+Synonymous options are \opt{UKenglish}, \opt{british}, \opt{USenglish}, \opt{american}, \opt{cana\-dian}, \opt{australian}, and \opt{new\-zea\-land}.
+
+If you want to load a set of f-ligature suppression rules that's broader than the set that's enabled by default, be sure to also specify the option \opt{broadf}; see \cref{sec:eng-opt}. If \enquote{historic} and/or \enquote{discretionary} ligatures (e.g., ct, st, sp, \emph{th}, \emph{\uselig{ij}}, \emph{ll}, \emph{\ebg sk}, \emph{at}, \emph{et}, \emph{as}, \emph{\ebg es}, \emph{is}, and~\emph{us}) are enabled for your text font(s), be sure to specify the option~\opt{hdlig}. The options \opt{broadf} and \opt{hdlig} may be specified independently.
+
+\enlargethispage{1\baselineskip}
+
+\item If your document is written in German, load the package as follows:
+\begin{Verbatim}
+ \usepackage[ngerman]{selnolig}
+\end{Verbatim}
+Synonymous language options are \opt{german}, \opt{austrian}, \opt{naustrian}, \opt{swissgerman}, and \opt{swiss}.
+
+\item If you load the package \emph{without} an explicit language option, i.e., as
+\begin{Verbatim}
+ \usepackage{selnolig}
+\end{Verbatim}
+but if one or more of the language options noted above are specified as options in the \cmmd{documentclass} instruction, \LaTeX\ will pass these options on to the \pkg{selnolig} package.
+
+\item If no language options are set either when the package is loaded or as options in the \cmmd{documentclass} instruction, you will need to provide your own ligature suppression rules. This approach is called for if you write in a language other than German or English\textemdash the only two languages currently supported by the \pkg{selnolig} package\textemdash and are able to devise your own ligature suppression rules using \pkg{selnolig}'s \cmmd{nolig} and \cmmd{keeplig} macros.
+
+\end{itemize}
+
+
+\subsection{Any hints on how to get started with \LuaLaTeX?}
+
+\begingroup
+\renewcommand\theenumi{(\roman{enumi})}
+\renewcommand\labelenumi\theenumi
+
+
+The ligature suppression macros of the \pkg{selnolig} package \emph{require} the use of \LuaLaTeX; they will not work under either pdf\LaTeX\ or \XeLaTeX. If the \pkg{selnolig} package is not run under \LuaLaTeX, a warning message will be issued and only the package's supplemental hyphenation rules will be available to the user.
+
+If you've been using pdf\LaTeX\ until now, the requirement to use \LuaLaTeX\ will likely force you to make some changes to your existing documents. Fortunately, these changes should be minor and straightforward to implement because \LuaLaTeX\ is, for the most part, a strict superset of pdf\LaTeX. Almost all documents that compile correctly under pdf\LaTeX\ should also compile correctly under \LuaLaTeX.
+The two most important changes you'll need to make are:
+\begin{enumerate}
+\item Do not load either the |inputenc| or the |fontenc| package.
+\item Be sure to load the |fontspec| package,\footnote{If the \pkg{selnolig} package is run under \LuaLaTeX\ but the \pkg{fontspec} package isn't loaded by the time the \Verb+\begin{document}+ statement is encountered, \pkg{selnolig} will terminate with an error message.} and use \cmmd{setmainfont}, \cmmd{setsansfont}, and related commands to load the fonts you wish to use.
+\end{enumerate}
+\endgroup
+
+
+Depending on your \TeX\ distribution, the default font family used by \LuaLaTeX\ will be either Computer Modern or Latin Modern. (This is true of pdf\LaTeX\ as well, of course.) If you wish to use a different font family, issuing some font-related instructions will be required. \emph{How} to specify fonts and font families and set up various font-related options in \LuaLaTeX\ are topics that go far beyond the scope of this user guide. I urge you to become familiar with the very well-written
+ \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fontspec/fontspec.pdf}{user guide} of the \pkg{fontspec} package.
+
+You will also need to use a \TeX\ distribution that features a fairly recent version of \LuaLaTeX. \TeX Live 2013, \TeX Live\,2012, and MiK\TeX\,2.9 satisfy this requirement; versions of \TeX Live before 2011 probably do not.
+
+If you use a command-line interface to compile a document named, say, |myfile.tex|, type
+\begin{Verbatim}
+ lualatex myfile
+\end{Verbatim}
+rather than either |latex myfile| or |pdflatex myfile| to initiate compilation. If you use a text editing program with pull-down menus or buttons to invoke a suitable compiler, be sure to select |LuaLaTeX|.
+
+The very first time one runs \LuaLaTeX\ on a document with a new set of fonts, the compilation speed will likely be quite slow because \LuaLaTeX\ (actually, a package loaded by \LuaLaTeX) has to create various cache files to store font-related information. Subsequent compilation runs should be much faster.
+
+The answers to the questions entitled \href{http://tex.stackexchange.com/q/28642/5001}{Frequently loaded packages: Differences between pdf\LaTeX\ and \LuaLaTeX?} and \href{http://tex.stackexchange.com/q/32295/5001}{Using Lua\TeX\ as a replacement for pdf\TeX}, both posted to \href{http://tex.stackexchange.com/}{tex.stackexchange.com}, provide lots of very useful information for people who are new to \LuaLaTeX\ and are at least somewhat familiar with pdf\LaTeX. Another great resource for people who wish to become more familiar with \LuaLaTeX\ is \href{http://mirror.ctan.org/info/luatex/lualatex-doc/lualatex-doc.pdf}{A Guide to \LuaLaTeX} by Manuel Pégourié-Gonnard.
+
+
+
+
+\subsection{Anything else I need to do or know?} \label{sec:anythingelse}
+
+For multilingual support, \LuaLaTeX\ and the \pkg{selnolig} package work well with the \href{http://www.ctan.org/pkg/babel}{\pkg{babel}} package. If you use the \pkg{babel} package, be sure to load \pkg{selnolig} \emph{after} \pkg{babel}; that way, the supplemental hyphenation patterns provided by the \pkg{selnolig} package won't get clobbered by \pkg{babel}'s hyphenation settings.\footnote{The \pkg{selnolig} package is also compatible with the \href{http://www.ctan.org/pkg/hyphsubst}{\pkg{hyphsubst}} package (which, if used, should be loaded with a \Verb+\RequirePackage+ statement \emph{before} the \Verb+\documentclass+ instruction). Since mid-2013, one can also use the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/polyglossia}{\pkg{polyglossia}} package with \LuaLaTeX.}
+
+\LuaLaTeX\ natively supports the so-called \utf\ input encoding scheme. In fact, \utf\ is also the \emph{only} input encoding scheme that \LuaLaTeX\ knows about. Nowadays, many modern \TeX-aware editors support \utf\ directly; \LuaLaTeX\ and \pkg{selnolig} should have no problems with \TeX\ files produced by these editors. Older files, however, may employ input encoding schemes incompatible with \utf. If your input files currently use a different input encoding scheme, e.g., \textsc{latin1}, they need to be converted to \utf before \LuaLaTeX\ can process them properly. Several methods exist for changing a file's input encoding scheme. Please see the posting \href{http://tex.stackexchange.com/q/87406/5001}{How to change a .tex file's input encoding system (preferably to \utf)?} on \href{http://tex.stackexchange.com/}{tex.stackexchage.com} for several possible conversion methods.
+
+If your document is written in German, it is assumed that all vowels with diereses (Umlaute) are entered as \Verb|ä|, \Verb|ö|, \Verb|ü|, etc.\ rather than, say, as \Verb|\"{a}|, \Verb|\"{o}|, and~\Verb|\"{u}| or, if you tend to use the \pkg{babel} \enquote{shortcuts}, as \Verb|"a|, \Verb|"o|, and~\Verb|"u|. Likewise, it's assumed that you enter the \enquote{eszett} (\enquote{scharfes~s}) character as~|ß| rather than as~|\ss|.\footnote{\TeX nically speaking, |selnolig| requires the use of |ä|, |ö|, |ü|, and |ß| only in the search strings of the ligature suppression rules.} It is also assumed that you use the triple-f (modern) spelling of words such as \texttt{Schifffahrt},\footnote{The \pkg{selnolig} package's German language rules are set to recognize words containing the old-spelling version |schiffahrt|; the ff ligature is not broken up for these words. However, most other words that have two f's in the old spelling and three f's in the new spelling don't get any special treatment in the package.} \texttt{Stofffarbe}, and \texttt{grifffest} and the double-t (modern) spelling of words such as |Mannschafttest|.
+
+Finally, all \pkg{babel}-style ``\Verb+"|+'' ligature-suppressing shortcuts should either be removed entirely or be replaced with |\breaklig| instructions; the \pkg{selnolig} package's |\breaklig| macro is explained in \cref{sec:breaklig}.\footnote{On my \LuaLaTeX\ system, whenever a \Verb+"|+ command is encountered, I either get a bad crash that requires a reboot of the computer (under Mac\TeX\,2012) or I get a stern error message about \enquote{Forbidden control sequence found while scanning use of \cmmd{FancyVerbGetVerb}} (under Mac\TeX\,2013).}
+
+
+
+
+
+\section[The selnolig package's approach to breaking up ligatures]{The \pkg{selnolig} package's approach to breaking up ligatures} \label{sec:approach}
+
+\subsection[Free, derivational, and inflectional morphemes]{Free, derivational, and inflectional morphemes, and their relationship to ligature suppression}
+
+Good typography supports and enhances the readability of the typeset text. There are obviously a great many facets to how typography may contribute to good readability. One aspect is the ease with which readers can discern the \emph{meaning} of the typeset text and its constituent parts\textemdash words. Because a typographic ligature groups two or more characters into a composite glyph, it is natural for the reader to \enquote{read} a ligature as forming a single unit and, moreover, to associate the ligature with some part of the word's meaning. Whereas this mental association of visual unity and meaning can be helpful when it comes to discerning the meaning of single-morpheme words,\footnote{Some examples of single-morpheme words containing a ligature are off, fit, flat, office, baffle, left, act, cost, and spin.} it \emph{may} detract from the word's readability if the word is composite and the ligature happens to span a morpheme boundary. Ligatures that span a morpheme boundaries \emph{may} impair a composite word's readability if their presence make readers slow down and perform a \enquote{double take} in order to figure out which morphemes are used in the composite word.
+
+What exactly are morphemes? Briefly put, morphemes are the smallest linguistic units in a word that carry \emph{meaning}. Because words are, by definition, standalone units of text, each word contains at least one morpheme.\footnote{Please don't try to get me involved in a discussion of what it may mean to have words without meaning\dots} Morphemes are classified as \emph{free} if they can stand alone as words (e.g., cat, dog, sea, see), and as \emph{bound} if they can not. E.g., the letter~|s| in the words cats, dogs, and rivers indicates the plural forms of the associated nouns; because the |s| particle cannot stand by itself as a word, it is a bound morpheme.
+
+Bound morphemes can be divided further into derivational and inflectional morphemes. A \emph{derivational} morpheme changes the meaning of the associated free morpheme in a fundamental way. E.g., the \enquote{un} in \enquote{untrue} serves to create a word with the opposite meaning of the free morpheme \enquote{true}, and the \enquote{ful} in \enquote{shelfful} indicates the word is a quantity measure (\enquote{two shelffuls of books on typography}, say).
+An \emph{inflectional} morpheme signifies a less fundamental change in meaning. In nouns (and, depending on the language, adjectives as well), inflectional morphemes can indicate plural forms (child vs. children, cat vs. cats) and other forms of declination.\footnote{In modern English, the virtually sole type of declination is to indicate plural status. In other languages, declination can also occur to indicate genitive, dative, accusative,~etc. forms of nouns \emph{and} adjectives. E.g., in German one says das schöne Kind, des schönen Kindes, dem schönen Kinde,~etc. The particles |en|/|es| and |en|/|e| represent inflectional morphemes associated with the genitive and dative forms of the nouns and adjectives.} In verbs, inflectional morphemes indicate conjugation, such as a change in tense of the verb. E.g., call vs. called, walk vs. walked, but also \enquote{swim} vs. \enquote{swims}, etc.
+
+Words containing more than one morpheme can consist either of \enquote{just} free morphemes\textemdash rooftop, newspaper, etc.\textemdash or of free and bound morphemes joined together\textemdash untrue, shelfful, childish, laughs, etc. Bound morphemes generally occur either as prefixes or suffixes to the word's \enquote{main part} or \enquote{stem} (the free morpheme). Prefixes almost invariably represent derivational morphemes (e.g., untrue, review, perform). Suffixes, in contrast, can consist of free, derivational, or inflectional morphemes. For instance, the suffixes |like| and |less| in dwarflike and leafless are free morphemes, whereas the suffix~|ed| in hounded and laughed is an inflectional morpheme.
+
+It is important to realize that not all ligatures that span morpheme boundaries are equally inimical to good readability. Consider, say, the word \emph{umbrellas}, which contains the ligature~\emph{as}. Note that this ligature spans the boundary between the free morpheme \emph{umbrella} and the suffix~\emph{s}. Nevertheless, I'm quite confident that very few will claim that the presence of the \emph{as} ligature detracts from the readability of the plural word \emph{umbrellas}. I believe there are two reasons why this particular word's readability is not impaired by the presence of a morpheme-spanning ligature. First, the suffix~\emph{s} is an inflectional morpheme: it \enquote{merely} serves to change the noun's state from singular to plural; clearly, most of the composite word's meaning is conveyed by the free morpheme \emph{umbrella}. Second, the ligature occurs at the very \emph{end} of the word rather than, say, closer to the beginning or middle of the word; by the time the eye reaches the \emph{s} character, most of the word's meaning will already have been perceived.
+
+Because not all morpheme-spanning ligature are equally problematic in terms of their impact on a composite word's readability, the \pkg{selnolig} package follows rules that leaves some ligatures untouched, while others are broken up. The package adopts the following broad principles: First, ligatures that cross the boundaries of two free morphemes are always suppressed. Second, ligatures that cross the boundary between a free morpheme and a derivational morpheme are also suppressed\textemdash with certain exceptions that are explained below. Third, ligatures that span the boundary between a free morpheme and an inflectional morpheme are generally not suppressed. In \cref{sec:german-rules} below, the third principle is shown to be particularly relevant for decisions related to the (non)suppression of ft and fft ligatures in certain German texts.
+
+\subsection{Sidebar: Morpheme boundaries, syllable boundaries, and ligature suppression}
+
+Observe that morphemes need not coincide with \emph{syllables}, and hence that morpheme boundaries need not coincide with syllable boundaries and/or permissible hyphenation points. Indeed, words can contain several syllables but consist of only one morpheme (e.g., apple, orange, banana), or they can contain only one syllable but consist of two or more morphemes. E.g., the words \enquote{cats} and \enquote{dogs} each contain two morphemes, and the single-syllable word \enquote{twelfths} contains three morphemes (the free morpheme |twelve|, the derivational morpheme~|th|, and the inflectional morpheme~|s|).
+
+The fact that a ligature may span a syllable boundary in no way implies that the ligature should be suppressed. Consider, for instance, the German words Affe, Griffel, Kaffee, Koffer, Löffel, Muffel, and Schiffe: All feature a syllable boundary and hyphenation point between the two |f|'s. Nevertheless, none of the ff ligatures need be broken up, because the |ff| character pair doesn't span a morpheme boundary in any of these words. Or, consider the following German words that feature ft ligatures: bekräftigen, duftend, haften, heftig, Lüftung, and vergiftet. The ft ligatures are not suppressed because the |ft| pairs don't span morpheme boundaries.
+
+Should TeX need to hyphenate some of the words listed in the preceding paragraph to generate a well-typeset paragraph, it can of course do so\textemdash and break up the ff and ft ligatures in the process. There's no need, though, to break up a ligature just because hyphenation \emph{might} occur at that point. As always, there's no meaningful rule without at least one exception; in \enquote{Interlude~I} in \cref{sec:german-rules} below, I discuss what \emph{Duden} calls ambiguous cases for which ligature suppression follows syllable boundaries.
+
+To further highlight the critical importance of morpheme boundaries for matters of ligature suppression, consider the words single-syllable words fifths and twelfth. The ft ligature is broken up for these words because it spans a boundary between a free morpheme (five and twelve, respectively) and a derivational morpheme~(th). The fact that there's no syllable boundary is immaterial.
+
+
+
+
+
+\subsection[selnolig's ligature suppression rules: English language case]{\pkg{selnolig}'s ligature suppression rules: English language case} \label{sec:english-rules}
+
+
+Typographic ligatures are suppressed if the following conditions apply to a word:
+\begin{itemize}
+\item if two free morphemes are joined:
+\uselig{halfline} $\to$ halfline,
+\uselig{halflife} $\to$ halflife,
+\uselig{cufflink} $\to$ cufflink,
+\uselig{halftone} $\to$ halftone,
+%\uselig{wolftrap} $\to$ wolftrap,
+\uselig{pastime} $\to$ pastime,
+\uselig{houndstooth} $\to$ houndstooth,
+\uselig{Charlestown} $\to$ Charlestown,
+\uselig{painstaking} $\to$ painstaking,
+\uselig{arctangent} $\to$ arctangent,
+\uselig{passport} $\to$ passport,
+\uselig{newspaper} $\to$ newspaper,
+\uselig{Hyannisport} $\to$ Hyannisport,
+\uselig{clothespin} $\to$ clothespin,
+\emph{\uselig{seastrand}} $\to$ \emph{seastrand},
+\emph{\ebg \uselig{Catskills} $\to$ Catskills},
+\emph{\ebg \uselig{Peekskill} $\to$ Peekskill},%
+\footnote{The relevant morpheme in the last two words in this list is |kill| (from an old Dutch word for stream), not |skill|.} etc.
+
+\item if a prefix and main word are joined:
+\uselig{offload} $\to$ offload,
+\uselig{mistake} $\to$ mistake,
+\uselig{mistrust}~$\to$ mistrust,
+\uselig{displease}~$\to$ displease,
+\uselig{suspend}~$\to$ suspend,
+\emph{\uselig{asea} $\to$ asea},
+\emph{\uselig{ultrasound} $\to$ ultrasound},
+etc.
+
+Note: If the main word, etymologically speaking, starts with |sp| or~|st|, the sp and st ligatures \emph{are} used even if the prefix ends in~|s|: disperse, dispirit, distant, distill, distress, etc.
+
+\item if a main word is followed by a suffix beginning with~|f| or~|l| other than |ly|: \uselig{shelfful}~$\to$ shelfful,
+\uselig{leafless} $\to$ leafless,
+\uselig{dwarflike}~$\to$ dwarflike,
+\uselig{leaflet}~$\to$ leaflet,
+\emph{\uselig{soulless} $\to$ soulless},
+\emph{\uselig{seallike} $\to$ seallike},
+etc.
+
+\enlargethispage{1.5\baselineskip}
+
+Note that the suffixes used above\textemdash |ful[l]|, |less|, |let|, and |like|\textemdash are all free morphemes. In contrast, the short suffix |ly|, if used to make adjectives into adverbs, is a derivational morpheme. The fl ligature is thus \emph{not} broken up for words such as \uselig{briefly} and \uselig{chiefly} (unless the |broadf| option is set; see below).
+
+\item If the main word ends with an~|f| and the suffix starts with an~|i|, the fi and ffi ligatures are \emph{not suppressed} (unless, again, the |broadf| option is set). Examples:
+\uselig{elfin},
+\uselig{selfish},
+\uselig{fluffily}.
+
+\item The ft ligature is also suppressed for words that end in |fth| or |fths|: \uselig{fifth}~$\to$ fifth, \uselig{twelfths}~$\to$ twelfths. Note that the particle |th| contained in these words is a derivational morpheme.
+
+\end{itemize}
+
+
+
+If the \opt{broadf} package option is set\textemdash as is the case for this user guide; after all, it's written to demonstrate the package's capabilities\textemdash the \pkg{selnolig} package will also suppress
+\begin{itemize}
+\item fi and ffi ligatures if the main word ends in~|f| and the suffix starts with an~|i|: elfin, selfish, golfing, surfing, beefier, fluffily, fluffiness, goofiness, standoffish, jiffies, buffiest,~etc.;
+\item fl and ffl ligatures in adverbs ending in |fly| and |ffly|, such as chiefly, briefly, and gruffly; and
+\item ft ligatures in words such as fifty and fiftieth.
+\end{itemize}
+
+The option \opt{broadf} is \emph{not} enabled by default. This is because I believe that any gains in readability that might result from breaking up the f-ligatures caught by the |broadf| rules are likely to be minor and aren't worth running the serious risk of creating unsightly visual clashes caused by unligated~f\kern0pt i, ff\kern0pt i, f\kern0pt l, and ff\kern0pt l glyphs.
+
+If the package's \opt{hdlig} option is set, an additional ligature-suppressing principle is activated:
+\begin{itemize}
+\item The~st and~sp ligatures are also suppressed for words with Greek roots that contain the character triples~|sth| and~|sph|; examples: isthmus and atmosphere. Typesetting these words as \uselig{isthmus} and \uselig{atmosphere}, i.e., with the very distinctive looking st and sp ligatures, risks reducing their readability, because doing so would obscure the presence of the \opt{th} and \opt{ph} character pairs which derive from single Greek letters~$\theta$/$\vartheta$ and $\phi$/$\varphi$, respectively. For these words, then, it seems advisable to suppress the st and sp ligatures even though, strictly speaking, no morpheme-crossing issues are involved.
+
+\end{itemize}
+
+In addition, as is explained in more detail in \cref{sec:global-nolig}, the ligatures {\ebg \uselig{fb}, \uselig{fh}, \uselig{fj}}, and {\ebg \uselig{fk}} are suppressed \emph{globally} for English language documents. This is done because there seem to be no words of \emph{English} origin for which these ligatures do not span a morpheme boundary. However, these ligatures are not suppressed for certain words of non-English origin, such as {\ebg Kafka, fjord, and fjell}.
+
+
+\subsection[selnolig's ligature suppression rules: German language case]{Ligature suppression rules: German language case} \label{sec:german-rules}
+
+For German words, the following rules apply when it comes to deciding which ligatures to break up and which ones to permit. These rules are built mainly from statements found in the \emph{Duden} and various websites that have taken an interest in this subject\textemdash with adaptations for the ft and fft ligatures.
+\begin{itemize}
+\item Case 1: Joining of two free morphemes: Ligatures are suppressed. Examples:
+\uselig{Schilfinsel} $\to$ Schilfinsel,
+%\uselig{Zupfinstrument} $\to$ Zupfinstrument,
+\uselig{Baus\kern0pt toffingenieur} $\to$ Baustoffingenieur,
+\uselig{Wassers\kern0pt toffionen} $\to$ Wasserstoffionen;
+\uselig{Impffurcht} $\to$ Impffurcht,
+\uselig{Senffabrik} $\to$ Senffabrik,
+\uselig{Ablauflogik} $\to$ Ablauflogik,
+\uselig{Schorfflecken} $\to$ Schorfflecken;
+\uselig{Zwölffingerdarm} $\to$ Zwölffingerdarm;
+\uselig{Brieftaube} $\to$ Brieftaube,
+\uselig{elfteilig} $\to$ elfteilig,
+%\uselig{Stofftasche} $\to$ Stofftasche,
+etc.
+
+\item Case 2: Joining of a prefix (whether a free or a derivational morpheme) ending in~|f| and a main word (free morpheme) starting with~|b|, |f|, |h|, |i|, |j|, |k|, |l|, or~|t|: Ligatures are suppressed. By far the most common prefix that gives rise to the need to suppress various f-ligatures at the junction of a prefix and main word is the word \enquote{auf}, as in aufbrechen, auffassen, Aufführung, auffliegen, auffischen, aufhören, aufisst, aufjaulen, aufklingen, Auflage, Auftrag, auftreten, etc.
+
+\item Case 3: Joining of a main word (free morpheme) ending in \enquote{f} or \enquote{ff} and a suffix (either a derivational or an inflectional morpheme) starting with \enquote{f}, \enquote{i}, \enquote{l}, or~\enquote{t}.
+
+\begin{itemize}
+\item Case 3a: Suffixes (bound morphemes) that start with an \enquote{f}, e.g., |-fach| and |-faltig|: The ff-ligature is suppressed. Examples: fünffach and zwölffaltig.
+
+\item Case 3b: Suffixes (bound morphemes) that start with an \enquote{i}, e.g., |-ig|, |-in|, and |-isch|: The~fi and~ffi ligatures are \emph{not} suppressed. Examples: streifig, äffisch, Chefin, Chefinnen.
+
+I haven't found a clear justification for this rule so far. I assume the rule is there because unligated f\breaklig i and ff\breaklig i character pairs are potentially sufficiently unsightly to make them stand out as an infraction against good typography that's even more grievous than having fi and ffi ligatures that span the boundary between a main word and a suffix.
+
+\item Case 3c: Suffixes that start with an \enquote{l}, e.g., |-lich|, |-ling|, |-lein| and |-los|: The fl-ligature is suppressed. Example words: trefflich, höflich, Prüfling, Köpflein, and s\breaklig traflos.
+
+\item Interlude~I: In ambiguous cases that could give rise to fl-ligatures that involve certain suffixes, according to \emph{Duden} preference should be given to \enquote{how the syllables are pronounced and how a word would be hyphenated}. For instance, \emph{Duden} says that the fl-ligature should be suppressed in the words Verzweiflung, Bezweifler, schweflig, and würflig.\footnote{%
+Note that the real suffixes in these words are |ung|, |er|, and~|ig|\textemdash not |lung|, |ler|, and~|lig|. Justifying the suppression of the fl-ligature for these words is thus not a simple matter of not letting a ligature span the \enquote{gap} between a main word and suffix.
+In my opinion, the rationale generally given for suppressing the fl-ligature in these cases\textemdash reliance on how the syllables are divided and how the composite words are hyphenated\textemdash is not entirely satisfactory. This is because, morphologically speaking, the main words Schwefel, Würfel, and Zweifel each contain two morphemes: a stem and the \emph{derivational} morpheme~|el|: \Verb+Schwef|el+, \Verb+Würf|el+, and \Verb+Zweif|el+. It is therefore not necessary, in my opinion, to create a new rule to justify the (non-)use of the fl-ligature for these cases. Given the presence of two morphemes in each of the main words, one could simply rely on the general rule of not letting ligatures span morpheme boundaries within the main words to motivate the suppression of the fl-ligature for words such as schweflig, würfle, and Verzweiflung, as their morphological components are \Verb+schwef|[e]l|ig+, \Verb+würf|[e]l|e+, and \Verb+Ver|zweif|[e]l|ung+.
+
+It's fair to say, though, that most modern German speakers are only vaguely aware of the fact that the~|el| particle constitutes a morpheme in words such as Würfel and Griffel\textemdash and that they are probably entirely unaware of this fact for words such as Schwefel and Zweifel. To be sure, the typographical convention adduced by \emph{Duden} for suppressing the fl-ligature in words such as schweflig, Verzweiflung, and würfle does \emph{not} appear to be based on the fact that letters~|f| and~|l| in these words belong to different morphemes.}
+
+This convention may also be applied to justify the non-use of the fl-ligature in words such as knifflig and mufflig as well as in the present-tense\slash first-person-singular forms of the verbs büffeln, löffeln, schaufeln, stiefeln, verteufeln, and zweifeln: these form are typeset \emph{without} the fl/ffl-ligature, i.e., as büffle, löffle, schaufle, stiefle, verteufle, and zweifle, respectively.
+
+\item Interlude~II: If a word \emph{ends} with an |fl| character pair because an abbreviation is in effect, \emph{Duden} says it's OK to use the fl-ligature even if the~f and~l characters belong to different morphemes. E.g., in the abbreviation \enquote{Aufl.}, the fl-ligature \emph{is} employed even though the ligature should not be used for the full, unabbreviated form of the word (\emph{viz.}, Auflage).
+
+Although not mentioned explicitly by \emph{Duden}, I believe the convention mentioned in the preceding paragraph may be extended to justify the use of the ff-ligature in the abbreviated word \enquote{Auff.} (full form: Aufführung\textemdash no ff ligature) and of the ft-ligature in \enquote{Auft.} (full form: Auftrag\textemdash no ft ligature).
+
+This convention further suggests (implies?) that it's permissible (a)~to use the ff ligature in surnames that end in |ff|, such as Orff and Hausdorff, and (b)~to use the ffi- and ffl-ligatures in abbreviated names such as Steffi and Steffl.
+
+\item Case 3d: Suffixes (derivational or inflectional morphemes) starting with~|t|. Unfortunately, not much official wisdom seems to exist to guide this case, possibly because the~ft and~fft ligatures are not (yet?) used as widely as are the other f-ligatures. The following four rules, and especially the second one, should therefore be understood to be somewhat provisional.
+
+\begin{itemize}
+\item The convention mentioned in \enquote{Interlude II} above, about not breaking up an fl-ligature if it occurs at the very end of a word (as in ``Aufl.''), may be extended to apply to the case of~ft and~fft ligatures as well, i.e., they are not suppressed \emph{if} they occur at the very ends of words (or word fragments that have separate meaning), as in verschärft, gestreift, gerafft, Dahingerafftsein, unbedarft, and Unbedarftheit.
+
+Note that the ft and fft ligatures span a morpheme boundary in these cases: the single-letter second morpheme, the letter~|t|, is an \emph{inflectional} morpheme that indicates a form of conjugation of the associated verb (viz., past tense and/or past participle).
+
+\item Should ft and fft ligatures be broken up in past tense and past-participle forms of verbs that do not end in~ft but, instead, in -fte, -ften, -ftes, -ftest, etc? Example words: |streifte|, |rafften|, and |schlürftest|. Because these suffixes are \enquote{merely} \emph{inflectional} rather than derivational morphemes, the \pkg{selnolig} package does \emph{not} break up the~ft and~fft ligatures in these cases either. Thus, the words will be typset as streifte, schlürftes\kern0pt t, and rafften rather than as streif\breaklig te, schlürf\breaklig tes\kern0pt t, and raff\breaklig ten.\footnote{I haven't yet come across any kind of authoritative discussion of this specific case. Should someone be able to furnish a good counterargument to the setting proposed here, I would be happy to change the settings accordingly.}
+
+\enlargethispage{1.2\baselineskip}
+
+\item Again appealing to the convention mentioned in \enquote{Interlude~II}, it would also seem OK to use the ft-ligature in expressions such as \enquote{zu fünft} and \enquote{die zwölftschnellste Sprinterin Bayerns}: Even though the~|t| at the end of |fünft| and |zwölft| is a \emph{derivational} morpheme, the ft ligature also occurs at the very end of the word or word fragment. In the case of the word \enquote{zwölftschnellste}, the argument for keeping the ft~ligature may also be based, in part, on the observation that the entire fragment \enquote{zwölft} is a prefix to \enquote{schnellste}; grouping the |t| character visually to its stem, |zwölf|, via an ft-ligature surely helps to enhance the overall readability of the sixteen-character word zwölftschnellste, right?
+
+\item In contrast, the ft-ligature should \emph{not} be used in \enquote{Beethoven's Fünfte Sinfonie} and \enquote{zum elften Mal}. The argument for breaking up the ft-ligature in the words \enquote{Fünfte} and \enquote{elften} rests on the fact that the particles |te| and |ten| are derivational morphemes and that the ft ligatures are no longer at the very end of the word (or word fragment). The justification for breaking up the ft ligatures does not rest on the that the syllable boundaries (and hyphenation points) happen to fall between the letters~|f| and~|t|.
+
+\end{itemize}
+
+\item Case 4: A free morpheme \emph{ends} in~|ft| (e.g., Saft, Kraft, Luft, Duft, Haft, and Vernunft) and is joined either to another free morpheme or to a suffix that's a bound morpheme. Example words:
+\opt{Saftladen},
+\opt{Säfte},
+\opt{Kraftfahrzeug},
+\opt{Luftagentur},
+\opt{duftend},
+\opt{bekräftigen},
+\opt{Haftung}, and
+\opt{vernünftig}.
+Because the~|ft| character pair doesn't cross a morpheme boundary, the \pkg{selnolig} package does \emph{not} break up the~ft ligature. Thus, the words are typeset as
+Saftladen,
+Säfte,
+Kraftfahrzeug,
+Luftagentur,
+duftend,
+bekräftigen,
+Haftung, and
+vernünftig.
+The fact that a \emph{syllable boundary} occurs between the letters~|f| and~|t| in all of these words should not affect the decision whether or not to employ the ft (or~fft) ligature.
+\end{itemize}
+\end{itemize}
+
+In addition, as is explained in more detail in \cref{sec:global-nolig}, the ligatures {\ebg \uselig{fb}, \uselig{fh}, \uselig{fj}}, and {\ebg\uselig{fk}} are suppressed \emph{globally} for German language documents. This is done because there seem to be no words of \emph{German} origin for which these ligatures do not span a morpheme boundary. However, these ligatures are not suppressed for selected words of non-German origin, such as {\ebg Kafka, Sognefjord, and Dovrefjell}.
+
+
+
+
+\section[Structure of the selnolig package]{Structure of the \pkg{selnolig} package} \label{sec:structure}
+
+\subsection{The main user commands} \label{sec:syntax}
+
+The four main user macros of the \pkg{selnolig} package are \cmmd{nolig}, \cmmd{keeplig}, \cmmd{uselig}, and \cmmd{breaklig}. The first two macros are meant to be used in the preamble to set up ligature-suppression rules on a document-wide basis. The latter two may be used, as needed, within the body of the document on an \emph{ad~hoc} or case-by-case basis to either supplement or override rules set up by \cmmd{nolig} and \cmmd{keeplig} instructions.
+
+The package provides four additional user commands. The instructions \cmmd{debugon} and \cmmd{debugoff}, described in more detail in \cref{sec:debugon}, serve to turn on and switch off logging of the activity of the \pkg{selnolig} package. The directives \cmmd{selnoligon} and \cmmd{selnoligoff}, described in \cref{sec:selnoligon}, turn on and switch off \pkg{selnolig}'s ligature-suppressing algorithms.
+
+
+
+\subsubsection{The \cmmd{nolig} macro}
+\label{sec:nolig}
+
+The package's main user macro is called \cmmd{nolig}. Each \cmmd{nolig} instruction, or rule, takes two arguments. The first is search string, and the second is a string that contains one or more ``\Verb+|+'' characters to indicates where in the search string the non-ligation \enquote{whatsits} should be inserted. E.g., the instruction
+\begin{Verbatim}
+ \nolig{lfful}{lf|ful}
+\end{Verbatim}
+sets up a rule to suppress the ff-ligature in words such as \enquote{shelfful}, \enquote{bookshelfful}, and \enquote{selffulfilling}.\footnote{\TeX nically speaking, the \cmmd{nolig} macros perform their job by inserting special \enquote{whatsits} into the input stream whenever a pattern match occurs. These whatsits prevent the paragraph-building algorithm from replacing the affected character pairs (or triples) with corresponding ligatures. The package's \cmmd{keeplig} macro, described below, works by removing any nonligation whatsits from the input stream whenever a pattern match occurs, thereby re-enabling the use of ligatures.}
+
+It is possible (and permissible) to have more than one \Verb+|+ character in the second argument of a \cmmd{nolig} instruction. For instance, one \emph{could} specify the rule \Verb+\nolig{Auflaufform}{Auf|lauf|form}+ to suppress both the fl- and the ff-ligature in the words Auflaufform and Auflaufformen. For added flexibility, though, the \pkg{selnolig} package's German language rules actually uses separate \cmmd{nolig} rules to suppress the ff and fl ligature in this word; see \cref{sec:debugon} for the precise format of the rules that affect the word Auflaufform.
+
+It is also possible to use Lua-style wildcard characters in the search string, as long as the wildcard characters occur \emph{after} the non-ligation point. For example, the file \pkg{selnolig-german-patterns.sty} sets up the rules
+\begin{Verbatim}
+ \nolig{Dorff[aäeiloöruü]}{Dorf|f}
+ \nolig{dorff[aäeiloöruü]}{dorf|f}
+\end{Verbatim}
+to search for words that contain the strings \opt{Dorff} and \opt{dorff} followed by a letter in the set |aäeiloöruü|.\footnote{In case you're curious: These particular, some complicated looking search strings are used to avoid suppressing the ff-ligatures in words that \emph{end} in either \opt{Dorff} or \opt{dorff}, as would be the case with the surnames Dorff and Hausdorff.} Incidentally, it is not strictly necessary, in the second argument of the \cmmd{nolig} command, to provide any material \emph{after} the vertical bar that indicates the non-ligation point. However, the readability of your \cmmd{nolig} rules may suffer if you don't list that material.
+
+If you examine the \cmmd{nolig} rules provided in the files \pkg{selnolig-german-patterns.sty} and \pkg{selnolig-english-patterns.sty}, you'll notice soon that there's some redundancy built in, in the sense that some words' ligatures will be broken up by more than one rule. For instance, the need to suppress the ff-ligature in \enquote{auffallen} happens to be met by both \Verb+\nolig{auff}{auf|f}+ and \Verb+\nolig{ffall}{f|fall}+. This redundancy is deliberate, because not all words that might fit one pattern will also fit the other. Providing some redundancy of this type seems like a reasonable way to proceed.
+
+As with all \LaTeX\ instructions, the arguments of \cmmd{nolig}, \cmmd{keeplig}, and \cmmd{uselig} commands are case-sensitive.
+
+\subsubsection{The \cmmd{keeplig} macro}
+\label{sec:keeplig}
+
+
+The macro |\keeplig{<string>}| allows users to create rules that override \cmmd{nolig} rules selectively: for words that contain fragment |<string>|, the corresponding \cmmd{nolig} rule will not be executed. For a \cmmd{keeplig} rule to work properly, then, the command's argument must be a string that includes \emph{as a subset} a string treated by one or more \cmmd{nolig} rules.
+
+The \cmmd{keeplig} macro is very useful tool because it permits devising a (much) smaller set of broader, i.e., less restrictive, \cmmd{nolig} rules; any Type-II errors that may arise from having \cmmd{nolig} rules whose scope is too broad can be undone by providing judiciously crafted \cmmd{keeplig} rules.\footnote{In the present context, a Type-II error is the suppression of a ligature that is, in fact, valid for the word at hand. }
+
+Consider the following example: If the \opt{ngerman} language option is set, the \pkg{selnolig} package uses the rule
+\begin{Verbatim}
+ \nolig{flich}{f|lich}
+\end{Verbatim}
+to break up the fl-ligature in a multitude of words that end in the suffix |lich| (a derivational morpheme): begrifflich, beruflich, brieflich, glimpflich, hilflich, höflich, käuflich, s\breaklig träflich, tariflich, trefflich, unerschöpflich, and verwerflich, to name but just a few. This \cmmd{nolig} rule, incidentally, also (correctly) catches the word \enquote{Lauflicht}, which contains the free morphemes |Lauf| and |licht|.
+
+However, the scope of this \cmmd{nolig} rule is a bit too broad (or, if you will, it is insufficiently restrictive) because it also catches certain words, such as \opt{Pflicht} and \opt{verpflichten}, for which the fl-ligature should \emph{not} be suppressed. Rather than provide a large number of more restrictive \cmmd{nolig} rules aimed at avoiding catching the Pflicht- and pflicht-words, the package provides the simple command
+\begin{Verbatim}
+ \keeplig{flicht}
+\end{Verbatim}
+This rule tells \pkg{selnolig} to override the action of the \Verb+\nolig{flich}{f|lich}+ rule for all words that contain the string \opt{flicht}. Most words affected by this \cmmd{keeplig} rule happen to contain the strings \enquote{Pflicht} and \enquote{pflicht}. In addition, this rule also helps preserve the fl-ligature in words such as \enquote{entflicht} and \enquote{verflicht} (the third-person-singular forms of the verbs entflechten and verflechten, respectively).
+
+%%%%flichst verflichst entflichst
+
+It is important to be aware of the following fact: It is \emph{not necessarily} the case that ligatures contained in the argument of a \cmmd{keeplig} rule will be used in words that contain the rule's search string. Why?! It is because, as was noted above, \emph{more than one} \cmmd{nolig} rule can apply to a given word. Consider, for instance, the word \opt{Lauflicht} mentioned earlier. This word happens to be caught by two \cmmd{nolig} rules and one \cmmd{keeplig} rule provided in the file \pkg{selnolig-german-patterns.sty}:
+\begin{Verbatim}
+ \nolig{aufl}{auf|l}
+ \nolig{flich}{f|lich}
+ \keeplig{flicht}
+\end{Verbatim}
+For the word |Lauflicht|, \Verb+\keeplig{flicht}+ serves to undo the action of \Verb+\nolig{flich}{f|lich}+. However, because the string |aufl| is \emph{not} a subset of the string |flicht|, |\keeplig{flicht}| does not undo the action of \Verb+\nolig{aufl}{auf|l}+. Hence, the word |Lauflicht| ends up being typeset\textemdash correctly!\textemdash as Lauflicht, i.e., \emph{without} the fl-ligature.
+
+Interestingly, the rule |\keeplig{flicht}| is itself a bit too broad because it improperly catches the composite noun |Sumpflicht|, for which the fl-ligature \emph{should} in fact be suppressed.%
+%\footnote{The free morphemes contained in the word |Sumpflicht| are |Sumpf| and |licht|\textemdash \emph{not} |Sum| and |pflicht|!}
+To address this case, the file \pkg{selnolig-german-patterns.sty} provides the rule \Verb+\nolig{Sumpfl}{Sumpf|l}+; for the word Sumpflicht, this \cmmd{nolig} rule is not overridden by the rule |\keeplig{flicht}|. This \cmmd{nolig} rule also serves to suppress the fl ligature in words such as Sumpflabkraut and Sumpfleiche.
+
+
+\subsubsection{The \cmmd{uselig} macro}
+\label{sec:uselig}
+
+The \pkg{selnolig} package also provides the user command \cmmd{uselig}, which acts very much like the \cmmd{keeplig} command to override the action of a \cmmd{nolig} rule. However, it does so purely on a one-off basis. E.g., the command \Verb+\uselig{fj}+ will typeset \enquote{\uselig{fj}} even if the rule \Verb+\nolig{fj}{f|j}+\textemdash which suppresses the |fj| ligature on a global, i.e., document-wide basis\textemdash is active; \emph{without} \cmmd{uselig}, you'd get \enquote{fj}.
+
+You should use \cmmd{uselig} instructions only for single words and word fragments; don't use them for longer stretches of text. If you need to suspend the operation of the ligature suppression macros for longer stretches, including entire paragraphs or more, you should use the macros \cmmd{selnoligoff} and \cmmd{selnoligon}, which are described in more detail in \cref{sec:selnoligon}.
+
+
+
+\subsubsection{The \cmmd{breaklig} macro}
+\label{sec:breaklig}
+
+The macro \cmmd{breaklig}, which doesn't take an argument, is provided as a hopefully easy-to-remember substitute for the lower-level \LaTeX\ command ``\Verb+\-\hspace{0pt}+''. You should insert this macro in places where you want to break up a ligature on an ad-hoc basis and also wish to permit hyphenation. To suppress a ligature on an ad-hoc basis \emph{without} introducing a potential hyphenation point, insert the instruction \enquote{\cmmd{kern0pt}}.
+
+For instance, to suppress the {\ebg\emph{sk}} ligature in the word \Verb+groundskeeper+ on a one-off basis, one might enter it as \enquote{\Verb+grounds\textbackslash breaklig keeper+} in order to obtain \emph{\ebg groundskeeper} rather than \emph{\ebg \uselig{groundskeeper}}. To suppress the {\ebg \emph{sk}} ligature for this word as well as for words such as \emph{\ebg greenskeeper} and \emph{\ebg miskeep} throughout the entire document, one could issue the directive \Verb+\nolig{skeep}{s|keep}+; the package provides just such a rule.
+
+
+
+
+\subsection[Components of the selnolig package]{Components of the \pkg{selnolig} package}
+\label{sec:components}
+
+The \pkg{selnolig} package has the following components:
+\begin{itemize}
+\item The main \enquote{driver} file is called \pkg{selnolig.sty}. It sets up the package's main user macros, \cmmd{nolig}, \cmmd{keeplig}, \cmmd{uselig}, and \cmmd{breaklig}, that were explained in detail in the preceding subsection and loads several other files.
+\item The package's lua code is in the file \pkg{selnolig.lua}.
+\item The ligature suppression rules for English and German language documents are contained in the files \pkg{selnolig-english-patterns.sty} and \pkg{selnolig-english-patterns.sty}, respectively.
+\item Supplemental hyphenation exception patterns, mostly for composite words that involve ligatures that are suppressed by the package's \cmmd{nolig} rules, are contained in the files \pkg{selnolig-english-hyphex.sty} and \pkg{selnolig-english-hyphex.sty}.
+\item The user guide\textemdash the document you're reading right now\textemdash is provided in the file \pkg{selnolig.pdf}; the associated source code is in the file \pkg{selnolig.tex}.
+\item Ancillary files: the files \pkg{selnolig-english-test.tex} and \pkg{selnolig-german-test.tex} load the \pkg{selnolig} package as well as either \pkg{selnolig-english-wordlist.tex} or \pkg{selnolig-german-wordlist.tex}. They serve to demonstrate the output of the \pkg{selnolig} package when run on lists of English or German words that are candidates for non-use of ligatures. The files \pkg{selnolig-english-test.pdf} and \pkg{selnolig-german-test.pdf} contain the results of compiling the test programs.
+Assuming your \TeX\ distribution is either \TeX Live or MiK\TeX, you can access these files by typing \Verb+texdoc selnolig-english-test+ or \Verb+texdoc selnolig-german-test+ at a command prompt.
+\end{itemize}
+
+The \enquote{driver} file \pkg{selnolig.sty} starts by setting up several Boolean switches to structure the processing of options. It then loads the file \pkg{selnolig.lua}, which contains the package's lua code and sets up the user macros discussed in the preceding subsection.
+
+The remaining steps in the startup process depend on which language-related options were selected:
+\begin{itemize}
+\item If \emph{no} language-specific options are in effect, the setup process terminates. Users may, of course, provide their own \cmmd{nolig}, \cmmd{keeplig}, \cmmd{uselig}, and \cmmd{breaklig} instructions.
+
+\item If the \opt{english} option (or one of its synonymous options) is set, the files \pkg{selnolig-english-patterns.sty} and \pkg{selnolig-english-hyphex.sty} are loaded. The former file contains a detailed list of \cmmd{nolig} and \cmmd{keeplig} rules adapted to English language typographic usage; \Cref{sec:eng-listing} provides a complete listing of these rules. The latter file contains a list of hyphenation exceptions, mainly for words that contain one or more potential non-ligation points and for which \TeX's hypenation algorithm either misses valid hyphenation points or selects invalid hyphenation points; see \cref{sec:addlhyph} below.
+
+\item If the \opt{ngerman} option (or one of its synonymous options) is set, the files \pkg{selnolig-german-patterns.sty} and \pkg{selnolig-german-hyphex.sty} are loaded. The former file contains ligature suppression rules appropriate for German typographic usage; \cref{sec:germ-listing} lists its contents. The latter file provides additional hyphenation rules for German-language words.
+
+\item If the user specifies both the \opt{english} and \opt{ngerman} options (or some of their synonymous options), \emph{both} language-specific style files will be loaded. Under normal circumstances, a user will probably want to load only one or the other set of language-specific files, but not both.
+\end{itemize}
+
+The following is an admittedly rough and rather imperfect indication of just how much more complex the task is of creating a set of ligature suppression rules for German than it is for English: As of the mid-May 2013 version of the \pkg{selnolig} package, the \enquote{basic} set of English language ligature suppression rules for \enquote{common} f-ligatures consists of 32 \cmmd{nolig} and 17 \cmmd{keeplig} directives.\footnote{Including the rules that are activated if the |broadf| and |hdlig| options are both activated, the tally rises to about 420 \cmmd{nolig} and 52 \cmmd{keeplig} instructions.} In contrast, the set of German language ligature suppression rules for \enquote{common} f-ligatures consists of roughly 700 \cmmd{nolig} and~335 \cmmd{keeplig} directives. A ratio of roughly 1:20 in terms of detail and complexity!
+
+
+
+\section{Additional ligature-related matters}
+\label{sec:options}
+
+
+%\subsection{The package's main language options}
+%
+%The \pkg{selnolig} package currently offers two main language-specific options:
+%\begin{itemize}
+%\item \opt{english}; synonyms: \opt{british}, \opt{ukenglish}, \opt{UKenglish}, \opt{amer\-ican}, \opt{usenglish}, \opt{USenglish}, \opt{cana\-dian}, \opt{australian}, and \opt{new\-zealand}.
+%\item \opt{ngerman}; synonyms: \opt{german}, \opt{austrian}, \opt{naustrian}, \opt{swiss}, and \opt{swiss\-german}.
+%\end{itemize}
+%These language options may be used either individually or jointly. Indeed, this user guide was compiled with both the \opt{english} and \opt{ngerman} options set.
+%
+%The English and German ligature suppression rules are listed in \cref{sec:eng-listing,sec:germ-listing}, respectively.
+%
+
+\subsection{The \opt{noftligs} option}
+
+By default, the \pkg{selnolig} package will load rules to suppress ft and fft ligatures selectively, for both English and German documents. In case you want to suppress these two ligatures \emph{globally} rather than selectively, you could specify the option \opt{noftligs} when loading the package. Doing so will make the package set up the simple rule \Verb+\nolig{ft}{f|t}+ rather than load many separate rules for suppressing ft ligatures selectively.\footnote{For German language documents in particular, suppressing ft and fft ligatures \emph{globally} may help speed up compilation noticeably, as there will be roughly 180 \cmmd{nolig} and 60 \cmmd{keeplig} instructions fewer to run on the document.} You may also wish to specify the \opt{noftligs} option if the font you use in your document doesn't even feature ft and fft ligatures.
+
+
+
+\subsection[English language case: The broadf and hdlig options]{English language case: The \opt{broadf} and \opt{hdlig} options} \label{sec:eng-opt}
+
+The ligature suppression patterns for English language words, contained in the file \pkg{selnolig-english-patterns.sty} and listed in \cref{sec:eng-listing} below, are grouped into four parts. The first two parts concern the suppression of f-ligatures. Part~1 provides a fairly limited, or \enquote{basic}, set of patterns that will always be executed, and Part~2 contains a broader set of ligation suppression rules that will be executed if the \opt{broadf} option is specified.
+
+As noted in \cref{sec:english-rules} above, for English-language documents only the fairly limited number of f-ligature suppression rules contained in Part~1 of the file is enabled by default. This is done because eliminating the morpheme-crossing f-ligatures caught if the |broadf| option is set does not appear to be a major concern in English-language typography. There simply doesn't appear to be a need to suppress the~fi (ffi) ligature words that end in~f (ff\,) followed by the particles -ing, -ish, -ier, -iest, -ily, and -iness. Any gain in readability resulting from suppressing these fi and fl ligatures would appear to be more than offset by unsightly visual clashes created by unligated f\kern0pti, ff\kern0pti, f\kern0ptl, and ff\kern0ptl combinations.
+
+
+Part 3 of the file \pkg{selnolig-english-patterns.sty}, which is enabled if the \opt{hdlig} option is set, provides ligature suppression rules for the ct, st, and sp ligatures. Examples are words such as arctangent (not: \uselig{arctangent}), painstaking (not: \uselig{painstaking}), mistake (not: \uselig{mistake}), and trespass (not \uselig{trespass}).
+
+Setting the \opt{hdlig} option also enables ligature suppression rules for additional discretionary ligatures such as \emph{th}, \emph{at}, and~\emph{et}. These ligatures might be deemed inappropriate for use in words such as \emph{\uselig{lighthouse}, \uselig{pothole}, \uselig{aromatherapy}, \uselig{albatross}, \uselig{ninety}, \emph{and} \uselig{nonetheless}}. With the \opt{hdlig} option set, these words will be typeset as \emph{lighthouse}, \emph{pothole}, \emph{aromatherapy}, \emph{albatross}, \emph{ninety}, and \emph{nonetheless}. Ligature suppression rules are provided for the following discretionary ligatures, which occur only in the \emph{italic} font shape of the font families used in this document: \emph{th}, \emph{at}, \emph{et}, \emph{as}, \emph{is}, \emph{us}, \emph{ll}, \emph{fr}, and {\ebg \emph{sk}}. Part~3 of \cref{sec:eng-listing} lists these rules.
+
+Part 4 of the file \pkg{selnolig-english-patterns.sty}, which is also processed if the \opt{hdlig} option is set, deals with cases where one discretionary typographic literature, say \emph{as}, might pre-empt the use of a more appropriate but trailing typographic ligature, say \emph{st} or~\emph{sp}, in words such as \emph{f\uselig{as}t}~$\to$ \emph{fast} and \emph{cl\uselig{as}p}~$\to$ \emph{clasp}. Note that the issue being addressed in this part is not that of a ligature improperly spanning a morpheme boundary; instead, it is the possibility that \TeX\ might pre-empt one typographic ligature with another ligature within one and the same morpheme. This issue is discussed in more detail in \cref{sec:preempt} below.
+
+
+\subsection{Composite words with ambiguous morphology}
+
+Some composite words can be made up of two different morpheme pairs, or even morpheme triples. For instance, the German words \opt{Saufladen} and \opt{Wachstube} may be constructed as \opt{Sauf-laden}\slash \opt{Sau-fladen} and as \opt{Wachs-tube}\slash \opt{Wach-stube}, respectively. In one case, using the fl and st ligatures would be wrong; in the other, using the ligatures helps indicate the intended meaning of the composite words.
+For words such as these, software isn't smart enough to \enquote{discern} which possible meaning is intended.\footnote{If the \opt{ngerman} option is set and the \pkg{babel} package is loaded as well, the \opt{selnolig} package will break up the fl ligature in \opt{Saufladen} but not the st ligature in \opt{Wachstube}, i.e., the words will be typeset as \enquote{Saufladen} and \enquote{Wachstube}, respectively. If that's \emph{not} what you want, you'll need to mark up the words explicitly as follows: \Verb+\uselig{Saufladen}+ and \Verb+Wachs\breaklig tube+.}
+Writers, of course, could choose to insert explicit hyphen characters to indicate the intended meaning.
+
+The preceding two examples each involve pairs of free morphemes. More complicated cases can occur too. For instance, the composite word \opt{Surftest} can have a meaning that involves a free morpheme and an inflectional morpheme (indicating the past-tense use of the verb), whereas the other meaning involves two free morphemes. Consider the questions \enquote{Surftest Du vergangene Woche in Hawaii?} and \enquote{Hat die Athletin den Surf\breaklig tes\breaklig t bestanden?} In the second question, it would clearly be wrong to use the ft-ligature; the word \opt{Surftest} is therefore entered as ``|Surf\breaklig test|'' in that question.
+
+An even more complicated example is the word \opt{Chefinnenleben}, which contains three morphemes. This word can be deconstructed either as \opt{Chefinnen-leben} (\enquote{lives of female bosses}) \emph{or} as \opt{Chef-innenleben} (\enquote{inner life, or lives, of a boss}); the word's middle particle\textemdash\enquote{innen}\textemdash can function both as a suffix to \enquote{Chef} and as a prefix to~\enquote{Leben}. Only in the second case is it wrong to use the fi-ligature.
+
+It turns out that the rules of the \pkg{selnolig} package are set so as \emph{not} break up the fi-ligature in the shorter words Chefin and Chefinnen, in keeping with the principle that the fi-ligature is permitted for suffixes that start with an~\enquote{i}. In contrast, \pkg{selnolig} will break up the fi-ligature in the longer words Chefinnenleben and Chefinnenräume; in these cases, the working assumption is that \opt{innen} acts as a prefix to the third morpheme (Leben or Räume). If this is \emph{not} what you want, i.e., if you really do mean to refer to lives or spaces of female bosses, be sure to use \Verb+\uselig{fi}+ instructions to preserve the fi-ligatures. Better yet, use explicit hyphens: Chefinnen-Leben and Chefinnen-Räume. And, while you're at it, do consider writing the other forms as Chef-Innenleben and Chef-Innenräume. Your readers will thank you.
+
+Summing up: Some composite words are morphologically ambiguous. For such words, it is (currently) not possible to program software to decide unambiguously whether or not ligatures that might occur in the words should be suppressed. The best advice I can give is to be on the lookout for such words and to take corrective action should \pkg{selnolig}'s choices be wrong.
+
+
+
+\subsection{How to provide additional ligature suppression patterns}
+
+As already noted, it's not possible to claim that the non-ligation rules provided in \pkg{selnolig-english-patterns.sty} and \pkg{selnolig-german-patterns.sty} are complete or, for that matter, will \emph{ever} be complete. If you come across words containing ligatures that ought to be suppressed but aren't caught (yet) by the \pkg{selnolig} package, you could do the following. First, you could insert \cmmd{breaklig} instructions to suppress the ligatures on a case-by-case basis; conversely, if you discover an instance for which \pkg{selnolig} improperly breaks up a ligature, you could override that action by encasing the character pair (or triple) in a \cmmd{uselig} statement. Second, you could create your own \cmmd{nolig} and \cmmd{keeplig} rules to deal with the cases you've discovered on a document-wide basis. A third option, naturally, is to bring this case to the attention of the maintainer of the \pkg{selnolig} package and ask him/her to update the package's ligature suppresssion rules\dots
+
+To give an extended example of how one might go about augmenting the set of ligature-suppression rules already provided by the \pkg{selnolig} package, suppose that you've been tasked with preparing a special edition of Thomas Mann's novel \emph{Der Tod in Venedig}. Suppose further that you have chosen to use an \enquote{Antiqua} (\enquote{Roman}) font\textemdash which, naturally, features a ligature for the ffl character triple\textemdash to typeset this special edition, because fewer and fewer people nowadays can manage to read with ease text set in a {\blackletter period-appropriate blackletter font}. During your preparations, you happen to notice (i)~that the novel contains the word \opt{inbegriffleitend}\footnote{This word really does occur in the aforementioned novel! This novel may very well also be the \emph{only place} ever where you'll encounter this word. I performed a Google search for the term \enquote{inbegriffleitend}; the only hits, apart from online editions of the novel itself, were the sites of a couple of French bloggers who agonized over how this word might possibly be translated from German to French\dots} and (ii)~that the \pkg{selnolig} package does not (yet) provide a rule that suppresses the ffl-ligature for this word.
+
+To meet the need to suppress the ffl-ligature in \opt{inbegriffleitend}, you could insert a \cmmd{breaklig} instruction, i.e., enter it as ``\Verb|inbegriff\breaklig leitend|''. (Doing so isn't inefficient in the present example because the word \opt{inbegriffleitend} occurs exactly once in the novel.) Alternatively, you could devise a new \cmmd{nolig} rule to catch this word. For instance, you could add the following \cmmd{nolig} rule (to be inserted in your document's preamble, after the \pkg{selnolig} package has been loaded) to suppress the ffl ligature in \opt{inbegriffleitend} as well as in the far more common words \opt{Jugendtreffleiter} and \opt{Kunststoffleitung}:
+\begin{Verbatim}
+ \nolig{ffleit}{ff|leit}
+\end{Verbatim}
+With this rule in place, the words will be typeset as inbegriffleitend, Jugendtreffleiter, and Kunststoffleitung, respectively. Just in case this discussion has made you curious: the file \pkg{selnolig-german-patterns.sty} provides the more general (i.e., less restrictive) rule \Verb+\nolig{fleit}{f|leit}+ to catch these words.
+
+When designing your own \cmmd{nolig} and \cmmd{keeplig} rules, you would ideally do so in a way that ensures that the rules are neither too specific (and hence only apply to a very small set of words) nor too general (and hence end up applying to words for which the rule wasn't meant to apply).
+
+Of course, this may be easier said than done. Consider, say, what would happen if you came up with the rule
+\begin{Verbatim}
+ \nolig{flei}{f|lei}
+\end{Verbatim}
+This rule would certainly succeed in breaking up the ffl-ligature in the words inbegriffleitend, Jugendtreffleiter, and Kunststoffleitung. It will also break up the fl-ligature in Laufleistung, Häuflein, Kreislaufleiden, Scherflein, and many more words. However, this rule would also \emph{incorrectly} break up the fl-ligature in many other words, including f\kern0pt leissig\slash f\kern0pt leißig, f\kern0pt leischig, Hackf\kern0pt leisch, and Diplomf\kern0pt leißarbeit; I believe most German readers would prefer to see these words typeset \emph{with} the fl-ligature, i.e., as fleissig\slash fleißig, fleischig,~etc. When in doubt, try to err on the side of making your \cmmd{nolig} rules a bit too restrictive.
+
+
+
+\subsection[How to use the selnolig package to suppress certain ligatures globally]{How to use the \pkg{selnolig} package to suppress certain ligatures \emph{globally}}
+\label{sec:global-nolig}
+
+
+The main purpose of the \pkg{selnolig} package is, obviously, to disable certain ligatures selectively. However, it can also be used to suppress ligation globally for selected character pairs.\footnote{I first became aware of the potential need for such a feature from reading Frank Mittelbach's posting, \href{http://tex.stackexchange.com/q/61042/5001}{Suppress certain ligatures generally}, on \href{http://tex.stackexchange.com/}{tex.stackexchange.com}.}
+
+For instance, suppose that you are typesetting a Turkish text. The Turkish alphabet features both a dotted~i and a dotless~\char"0131\ character. I understand that in Turkish typesetting practice, the fi and ffi ligatures should \emph{never} be employed, so as to avoid creating any doubts as to whether it's an~i or an~\char"0131\ character that follows the~\enquote{f} character. To satisfy the need of Turkish typography for global suppression of the fi and ffi ligatures, one could place the following instruction in the document's preamble:
+\begin{Verbatim}
+ \nolig{fi}{f|i}
+\end{Verbatim}
+
+%\enlargethispage{0.5\baselineskip}
+
+Or, suppose that you have a font that provides ligatures for the {\ebg \uselig{fb}, \uselig{fh}, \uselig{fj},} and {\ebg\uselig{fk}} character pairs (as well as, possibly, the {\ebg \uselig{ffb}, \uselig{ffh}, \uselig{ffj},} and {\ebg\uselig{ffk}} character triples). If you wanted to suppress the four former f-ligatures globally (and also break up the latter ligatures into ff\kern0pt b, ff\kern0pt h, ff\kern0pt j, and~ff\kern0pt k, respectively), you could do so by issuing the following commands:
+\begin{Verbatim}
+ \nolig{fb}{f|b}
+ \nolig{fh}{f|h}
+ \nolig{fj}{f|j}
+ \nolig{fk}{f|k}
+\end{Verbatim}
+In fact, as was already mentioned in \cref{sec:approach}, these commands are activated automatically if the \opt{ngerman} or \opt{english} language options are set. This is done because I was unable to come up with a single word of \emph{German} or \emph{English} origin involving these character combinations that doesn't also entail a morpheme boundary collision.
+
+Of course, your document may contain words \emph{not} of German or English origin that contain some of these character pairs and do not involve a morpheme boundary crossing. For such words, it is not necessary to suppress the corresponding ligatures. For instance, in the word \opt{Kafka}, one may not wish to suppress the {\ebg\uselig{fk}}-ligature for this specific word. The \pkg{selnolig} package provides \cmmd{keeplig} rules to preserve the {\ebg\uselig{fk}}-ligature in names such as {\ebg Kafka, Safka, Piefke, Potrafke, Sprafke, Shirafkan, Tirafkan}, and {\ebg Rifkin}.\footnote{Aside: It was Felix Lehmann's desire to preserve the {\ebg\uselig{fk}} ligature in the name \enquote{{\ebg Kafka}} that stimulated the creation of the package's \cmmd{keeplig} macro. Of course, once the \cmmd{keeplig} macro was created, I quickly discovered all kinds of further uses for it.}
+
+Your documents may also feature words of \emph{Nordic} origin that contain the \opt{fj} character pair, such as \opt{Sognefjord} and \opt{Dovrefjell}. Because the \opt{fj} character pair in these words does not span a morpheme boundary, the {\ebg\uselig{fj}}-ligature should not be broken up; i.e., the words should be typeset as {\ebg Sognefjord} and {\ebg Dovrefjell}, respectively. The package therefore provides \cmmd{keeplig} rules to take care of (a)~words that contain the particles {\ebg fjord, fjör, fjell}, and {\ebg fjäll} and (b)~names such as {\ebg Eefje, Sufjan, Prokofjew}, and {\ebg Astafjew}.
+
+A \enquote{rare} typographic ligature that may warrant global suppression, at least for English language documents, is~\uselig{\emph{ij}}.\footnote{For many fonts I'm familiar with, including the one used for this user guide, the |ij| character pair is available in the upright font shape as a \emph{digraph} rather than as a true, i.e., joined-up, ligature.} To the best of my knowledge, a morpheme boundary crossing occurs for all English language words that contain the~\opt{ij} character pair: \emph{antijam}, \emph{bijection}, \emph{demijohns}, and \emph{hijack}. By the logic set forth above, this ligature should therefore be suppressed for all of these words.\footnote{If this ligature weren't suppressed, the preceding words would be typeset as \emph{\uselig{antijam}, \uselig{bijection}, \uselig{demijohns}, \emph{and} \uselig{hijack}}.} The \uselig{\emph{ij}} ligature also seems inappropriate for most words that came into English from languages such as French, Japanese, and Spanish, including \emph{bijou} (jewel), \emph{gaijin} (foreigner), \emph{jipijapa} (Panama hat), and \emph{marijuana} (Maryjane). (What? Were you maybe thinking of a different meaning of this word? How come?!) The \uselig{\emph{ij}} ligature is therefore suppressed \emph{globally} by the \pkg{selnolig} package if the options \opt{english} and \opt{hdlig} are set.
+However, this ligature \emph{does} get used a lot in Dutch. Thus, the \pkg{selnolig} package issues various \cmmd{keeplig} directives so that this ligature isn't suppressed for some names and words of Dutch origin, such as \emph{de~Bruijn} and \emph{rijsttafel}.\footnote{The word \emph{rijsttafel}, incidentally, features three consecutive \enquote{rare} ligatures. Another word that contains three rare ligatures, though not consecutive ones, is \emph{\uselig{is}thmus}. }
+
+
+
+\subsection{What if one ligature pre-empts a trailing, more appropriate ligature?} \label{sec:preempt}
+
+If a font provides many discretionary ligatures, the likelihood is high that words will occur for which the use of a ligature for the first two characters of a character \emph{triple} might incorrectly pre-empt the use of a more appropriate ligature for the last two characters of that triple. Incidentally, the issue of ligature pre-emption is not limited to \enquote{discretionary} ligatures; it can also arise when dealing solely with \enquote{common} f-ligatures. Suppose, for instance, that a certain font provides~ff, fi, and fl ligatures but no ffi and~ffl ligatures. Consider how \TeX\ would typeset words containing \opt{ffi} and \opt{ffl} character triples. Left to its own devices, \TeX\ would let the leading ff-ligature pre-empt the trailing fi- and fl-ligatures, resulting in typographically incorrect outcomes for words such as \uselig{wolff}ish (better: wolffish), \uselig{saff}lower (safflower), \uselig{auff}inden (auffinden), and \uselig{Schaff}leisch (Schaffleisch).
+
+In this section, we examine the use of \cmmd{nolig} rules to address the ligature pre-emption issue, focusing on cases of~\emph{st}, \emph{sp}, \emph{th}, and~\emph{ta} character pairs being preceded by character pairs (for which the font provides ligatures) that end in~\emph{s} or~\emph{t}, respectively. This focus is dictated largely by the discretionary ligatures provided by the main text font used for this user guide (Garamond Premier Pro). Other ligature-rich fonts may provide further possibilities for one ligature inappropriately pre-empting that for a trailing character pair.%
+\footnote{For the font Garamond Premier Pro, I've discovered the following, rather peculiar exception to the general rule that \TeX\ always gives precedence to a ligature for the first two characters of a character triple: For the character triple \opt{fis} (as in \opt{fist} and \opt{fish}), \LuaTeX\ gives preference to the trailing \emph{is} ligature over the leading\, \emph{fi} ligature, causing these words to be typeset as \emph{\uselig{fish}} and \emph{\uselig{fist}}, respectively. I can't tell if this is a conscious design feature or a bug in this font. The \pkg{selnolig} package overrides this behavior, i.e., it is set to give preference to the leading\, \emph{fi} ligature over the trailing \emph{is} ligature for words that contain the strings \opt{fist} and \opt{fish}; hence, they'll be typeset as \emph{fish} and \emph{fist}, respectively.
+
+Note that if the \opt{broadf} option is set, as is the case for the document you're currently reading, a side effect of this setting is that words such as \emph{deafish, dwarfish, elfish, oafish, selfish, unselfish, wolfish, draffish, giraffish, gruffish, offish, raffish, sniffish, standoffish, stiffish, \emph{and} toffish}, as well as the associated adverbs ending in \emph{-ly}, will \emph{not} feature an \emph{is} ligature. This loss is, hopefully, not too serious.}
+
+\subsubsection*{Ligatures for \emph{as}, \emph{\ebg es}, \emph{is}, and \emph{us} that pre-empt an \emph{st} ligature}
+
+Suppose that the text font in use provides ligatures for the \emph{as}, \emph{is}, and \emph{us} character pairs as well as for the \emph{st} character pair. By \TeX's rules for forming typographic ligatures, words that contain the character \emph{triples} \opt{ast}, \opt{ist}, or \opt{ust} will see the first two characters ligated, pre-empting the use of a typographic ligature for the trailing \emph{st} character pair. There are at least three distinct reasons why this outcome is not desirable.
+
+
+First, given the rather distinctive look of the \emph{st}~ligature, the word \opt{stochastic} may look a bit odd if the \emph{st} ligature is used only once\textemdash\emph{\uselig{stochastic}}\textemdash simply because the \emph{as} ligature is allowed to pre-empt the second \emph{st} ligature; readers may prefer the look of \emph{stochastic}. Second, non-use of the st/\emph{st} ligature may be undesirable if the same word occurs twice and in close visual proximity, once set in the upright font shape\textemdash for which there are no ligatures for the \opt{as}, \opt{is}, and \opt{us} character pairs and hence for which the issue of pre-emption of the st doesn't arise\textemdash and once in italics: must and \emph{\uselig{must}}; readers may prefer the look of must and \emph{must}. Or, consider the words \enquote{historian} and \enquote{history} when typesetting them in italics: I'd say it's much better to typeset them as \emph{historian} and \emph{history} rather than as \emph{\uselig{historian}} and \emph{\uselig{history}}. Similarly, I suspect that Austrians and Australians\textemdash at least the ones who care about discretionary typographic ligatures\textemdash may prefer to see the name of their country typeset as \emph{Austria} and \emph{Australia} rather than as \emph{\uselig{Austria}} and \emph{\uselig{Australia}}. Finally: Do you prefer the look of \emph{Do \uselig{fast} festive \uselig{fists} foster \uselig{fustiness}?} or that of \emph{Do fast festive fists foster fustiness?} You prefer the latter look too? Great!
+
+Third, there may be cases where an \emph{as} ligature both pre-empts a subsequent \emph{st} ligature \emph{and} spans a morpheme boundary, as in the words \emph{\uselig{astride}}, \emph{\uselig{infrastructure}}, and \emph{\uselig{seastrand}}. The readability of such words definitely increases if the \emph{as} ligature is suppressed: \emph{astride}, \emph{infrastructure}, and \emph{seastrand}.
+
+The \pkg{selnolig} package is set to give preference to the distinctive-looking \emph{st} ligature over \emph{as}, \emph{is}, and \emph{us} ligatures. To this end, the following \cmmd{nolig} rules are provided:\footnote{The second of these three commands, while correct for most words that contain the string \opt{ist}, unnecessarily suppresses the \emph{is} ligature for words for which the \emph{st} character pair crosses a morpheme boundary, e.g., words that start with \emph{dis-t\ldots}\textemdash e.g., \emph{distend, distribute, distrust, disturb}\textemdash or with \emph{mis-t\ldots}\textemdash e.g., \emph{mistake, mistranslate, mistype}. (Note that separate \cmmd{nolig} rules already suppress the st/\emph{st} ligature for these words.) At this time there are no plans to address this (overall hopefully minor?) issue.}
+\begin{Verbatim}
+ \nolig{ast}{a|st}
+ \nolig{ist}{i|st}
+ \nolig{ust}{u|st}
+\end{Verbatim}
+
+
+
+\subsubsection*{Ligatures for \emph{as}, \emph{\ebg es}, \emph{is}, and \emph{us} that pre-empt an \emph{sp} ligature}
+
+The same three reasons for not letting \emph{as}, \emph{\ebg es}, \emph{is}, and \emph{us} ligatures pre-empt an \emph{st} ligature also apply to the case of the equally distinctive-looking \emph{sp} ligature. The \pkg{selnolig} package therefore provides rules to ensure that the \emph{sp} ligature is used in words such as \emph{clasp}, \emph{hasp}, \emph{raspberry}, \emph{teaspoon}, \emph{wasp}, \emph{\ebg espionage}, \emph{hispanic}, \emph{crisp}, \emph{lisp}, \emph{whisper}, and \emph{cusp}.
+
+
+
+\subsubsection*{Ligatures for \emph{at} and \emph{et} that pre-empt a \emph{th} ligature}
+
+Suppose that a font provides ligatures for the \emph{at}, \emph{et}, and \emph{th} character pairs. By \TeX's rules for forming ligatures, without special intervention the word \opt{mathematics} will be typeset as \emph{\uselig{mathematics}} rather than as \emph{mathematics} because the first \emph{at} ligature pre-empts the \emph{th} ligature. The same happens for words such as \emph{\uselig{bath}}, \emph{\uselig{Kathryn}}, and \emph{\uselig{pathology}}.
+Given the commonness and the distinctive pronuciation of the \opt{th} character pair in the English language, as well as the high frequency of this character pair in words of Greek origin (for which the Latin-alphabet \opt{th} character pair derives from the single Greek character $\theta$/$\vartheta$), it seems undesirable to let the \emph{at}-ligature pre-empt the \emph{th} ligature for these words.
+
+Fixing the \emph{at}--\emph{th} ligature pre-emption issue globally\textemdash e.g., via \Verb+\nolig{ath}{a|th}+\textemdash is not completely innocuous, though, because doing so will also suppress the \emph{at} ligature for words such as \opt{boathook}, for which the \emph{th} ligature would span a morpheme boundary and thus shouldn't be employed anyway. For such words, then, there's no need to suppress the \emph{at} ligature. These cases are dealt with by providing specific \cmmd{keeplig} rules to re-enable the use of the \emph{at} ligature.
+
+Suppressing an \emph{et} ligature in favor of a subsequent \emph{th} ligature via \Verb+\nolig{eth}{e|th}+ is almost universally correct, either because the \emph{th} ligature \emph{should} take precedence\textemdash as in the words \emph{ethics}, \emph{methane}, and \emph{teeth}\textemdash or because the \emph{et} ligature would cross a morpheme boundary and hence shouldn't be used anyway, as in the words \emph{forethought} and \emph{rethink}.
+I say that it's \emph{almost} universally correct to do so; however, there are some words, such as \opt{Beethoven}, \opt{prophethood}, and \opt{sweetheart}, for which the \emph{th} ligature would be inappropriate anyway and for which the use of the \emph{et} ligature would hence be unproblematic. To address this issue, \cmmd{keeplig} rules are provided to override the rule \Verb+\nolig{eth}{e|th}+ for these words, so that they'll get typeset as \emph{Beethoven}, \emph{prophethood}, and \emph{sweetheart}.\footnote{Note that this method works if the font being used provides both \emph{et} and \emph{th} ligatures. If the text font you employ provides only a \emph{th} ligature but no \emph{et} ligature, these \cmmd{keeplig} rules should be disabled.}
+
+
+\subsubsection*{Ligatures for \emph{at} and \emph{et} that pre-empt a \emph{ta} ligature}
+
+There seem to be very few English words for which an \emph{at} ligature might inappropriately pre-empt a \emph{ta} ligature. One such word is \opt{atap}; its readability is likely enhanced if it's typeset as~\emph{atap} rather than as~\emph{\uselig{atap}}.
+
+Virtually all words for which an \emph{et} ligature might inappropriately pre-empt the use of a trailing \emph{ta} ligature appear to be words for which the \emph{et} ligature crosses a morpheme boundary and should be suppressed. Examples are \emph{betake, betatter, bristletail, caretaker, detach, dovetail, foretaste, pretax, retable, retack, retard, retarget, timetable, \emph{and} wiretap}. The \emph{et}-related ligature suppression rules already put in place to deal with morpheme boundary crossing cases should therefore suffice to catch these cases as well.
+
+Do be on the lookout for cases of persons' names which include the string |eta| and for which the trailing \emph{ta} ligature should not be pre-empted by the leading \emph{et} ligature. For instance, the author of this package prefers to see his surname typeset as \emph{Loretan} rather than as \emph{\uselig{Loretan}}\dots
+
+
+
+\section{Further issues} \label{sec:further}
+
+\subsection{Known bugs}
+
+I'm not sure if the following constitutes a bug or \enquote{merely} a case of incompatibility between \LaTeX\ packages. The \pkg{selnolig} package does not interact well with the \LaTeX\ packages \pkg{ngerman} and \pkg{german}. Fortunately, the \pkg{selnolig} package \emph{does} interact nicely with the \pkg{babel} package if one of the options \opt{ngerman}, \opt{german}, \opt{austrian}, \opt{naustrian}, \opt{swissgerman}, or \opt{swiss} is set. Unless someone can convince me that using the \pkg{ngerman} or \pkg{german} packages is preferable to using the \pkg{babel} package, I probably won't bother addressing this incompatibility.
+
+
+
+\subsection{Supplementary hyphenation exception patterns} \label{sec:addlhyph}
+
+\TeX's hyphenation algorithms are widely acknowledged to be very good. However, for the English language case at least, it tends to miss quite a few permissible hyphenation points when dealing with words that end in |-f-ing|, |-f-ier|, |-f-iest|, |-f-less|, |-f-like|, etc. Hyphenation exception lists are provided in the files \pkg{selnolig-english-hyphex.sty} and \pkg{selnolig-german-hyphex.sty}, respectively, for English and German words.
+
+The German-language hyphenation exception list is currently still the shorter of the two. The German word list is shorter in part because it is assumed that writers of German-language documents use the \pkg{babel} package and select the option \opt{ngerman} (or one of the synonymous language options); doing so also loads specialized hyphenation patterns suitable for German texts.\footnote{As was already noted earlier, the \pkg{selnolig} package is also compatible with the \pkg{hyphsubst} and \pkg{polyglossia} packages.}
+
+It is possible to instruct \pkg{selnolig} \emph{not} to load the package's hyphenation exception lists. You may want to do so, for instance, if you must use UK-English hyphenation patterns and therefore shouln't use the US English-based hyphenation patterns provided by the package. (To the best of my knowledge, most of the hyphenation patterns employed in \pkg{selnolig-english-hyphex.sty} are common to UK and US English.) To skip loading the additional hyphenation patterns when invoking the \pkg{selnolig} package, you should specify the option \opt{noadditional\-hyphen\-a\-tion\-patterns}. (I am obviously not trying to make it too easy to invoke this option~\dots)
+
+As was already noted in \cref{sec:anythingelse}, if you use the \pkg{babel} package with, say, the \opt{ngerman} option, be sure to load \pkg{selnolig} package \emph{after} the \pkg{babel} package. That way, the \pkg{selnolig} package's additional hyphenation exception patterns won't be overridden by \pkg{babel}'s settings.
+
+Incidentally, if the files \pkg{selnolig-english-hyphex.sty} and \pkg{selnolig-german-hyphex.sty} are located in a directory that's in the search path of your TeX distribution, these packages may be loaded via the usual \cmmd{usepackage} statements without having to load the entire \pkg{selnolig} package.
+
+
+
+\subsection[How to track what the selnolig package is doing]{How to track what the \pkg{selnolig} package is doing} \label{sec:debugon}
+
+If you execute the command \cmmd{debugon}, detailed information about each \cmmd{nolig} and \cmmd{keeplig} pattern match that is encountered is written to the \opt{.log} file. Note that the default setting is \cmmd{debugoff}, i.e., the package's activity is not recorded by default to the \opt{.log} file.
+
+
+Because of the redundancy built into some of the package's \cmmd{nolig} commands, it is possible that more than one pattern match will occur for a given word. E.g., for the verb \enquote{auffahren}, two separate \cmmd{nolig} commands apply simultaneously, \emph{viz.}, \Verb+\nolig{auff[aeiloruyäöü]}{auf|f}+ and \Verb+\nolig{ffahr}{f|fahr}+. For this word, then, the following information is written to the \opt{.log} file:
+\begin{Verbatim}
+ pattern match: auffahren - auff[aeiloruyäöü]
+ pattern match: auffahren - ffahr
+ Do ligature suppression for: auffahren
+ Inserting nolig whatsit before glyph: f
+ Last char: n
+\end{Verbatim}
+
+Some words contain more than one potential ligature suppression point. For example, if the word \enquote{Auflaufform}\textemdash which happens to have both an fl- and an ff-ligature that should be suppressed\textemdash is encountered, the following lines are written to the \opt{.log} file; note that in this case, two separate \cmmd{nolig} commands \enquote{catch} the fl and ff ligatures:
+\begin{Verbatim}
+ pattern match: Auflaufform - flauf
+ pattern match: Auflaufform - Aufl[aeiouyäöü]
+ pattern match: Auflaufform - auff[aeiloruyäöü]
+ pattern match: Auflaufform - fform
+ Do ligature suppression for: Auflaufform
+ Inserting nolig whatsit before glyph: l
+ Inserting nolig whatsit before glyph: f
+ Last char: m
+\end{Verbatim}
+
+If \emph{both} a \cmmd{nolig} and a \cmmd{keeplig} command apply to a word\textemdash as is the case for \opt{fjord}, to which both \Verb+\nolig{fj}{f|j}+ and \Verb+\keeplig{fjord}+ apply\textemdash the following (mercifully short) bit of information is written to the \opt{.log} file:
+\begin{Verbatim}
+ pattern match nolig and keeplig: fjord - fj - fjord
+p\end{Verbatim}
+
+If more than one \cmmd{nolig} rule \emph{as well as} a \cmmd{keeplig} rule apply to a given word, as is the case for the word \enquote{Streiflicht}, the following information is written to the \opt{.log} file:
+\begin{Verbatim}
+ pattern match nolig and keeplig: Streiflicht - flich - flicht
+ pattern match: Streiflicht - reifl
+ Do ligature suppression for: Streiflicht
+ Inserting nolig whatsit before glyph: l
+ Last char: t
+ \end{Verbatim}
+
+Observe that the first nolig rule's pattern, |flich|, is overridden by the keeplig rule's pattern |flicht|. The second nolig rule's pattern, |reifl|, is \emph{not} overridden, and it is the debugging-related information associated with the second \cmmd{nolig} rule that ends up being written to the |.log| file.
+
+To terminate or suspend the writing of the debugging-related information to the \opt{.log} file, execute the command \cmmd{debugoff}. To restart the logging of this information, issue the command \cmmd{debugon}.
+
+
+
+\subsection[Suspending and restarting the operation of selnolig's macros]{Suspending and restarting the operation of \pkg{selnolig}'s macros} \label{sec:selnoligon}
+
+By default, \pkg{selnolig}'s macros are switched on (assuming, of course, that your document is compiled under \LuaLaTeX). If you want to suspend their operation, you should issue the command
+\begin{Verbatim}
+ \selnoligoff
+\end{Verbatim}
+at the desired point in your document. For instance, in this document the command \cmmd{selnoligoff} is issued at the start of the appendices. This is done because most of the material in the appendices (which contain mostly listings of lua and \LaTeX\ code) is typeset using a monospaced font for which all typographic ligatures have been disabled up front. Hence, there's no need to disable any ligatures selectively in that part of the document, is there?
+
+Conversely, if \pkg{selnolig}'s macros need to be switched back on, just issue the command
+\begin{Verbatim}
+ \selnoligon
+\end{Verbatim}
+In this document, this is done at that start of \cref{sec:budd}, which provides a long list of words found in \emph{Die Buddenbrooks} for which f-ligatures should be suppressed.
+
+\subsection{Lists of words that fit German and English non-ligation patterns} \label{sec:lists}
+
+Extensive lists of German and English language words for which one or more ligatures should be suppressed are provided in the supplemental files \pkg{selnolig-german-test.pdf} and \pkg{selnolig-english-test.pdf}. As was already mentioned in \cref{sec:components}, these documents may be viewed by opening a command window and typing \pkg{texdoc selnolig-german-test} and \pkg{texdoc selnolig-english-test}.
+
+The list of words in \pkg{selnolig-german-test.pdf} consisted initially almost entirely of the words provided by the \pkg{rmligs} script. However, I've added quite a few more words to that list in the meantime. Thanks to the great work of Felix Lehmann and Steffen Hildebrand explained in more detail in \cref{sec:thanks}, the package's German language ligature-suppression rules now apply to a much larger set of words than what's listed in \pkg{selnolig-german-test.pdf}. Naturally, suggestions for still more words to be de-ligated are always welcome.
+
+%The files \pkg{selnolig-german-test.tex} and \pkg{selnolig-english-text.tex} are \enquote{driver programs} that load the \pkg{selnolig} package and then run it on the respective lists of German- and English-language words. To compile the driver programs, be sure to use \LuaLaTeX.
+
+
+\subsection{Making suggestions and reporting bugs}
+
+Feedback on the \pkg{selnolig} package is always welcome, whether for making general suggestions, heaping praise on the package's author, or for reporting bugs and other problems. \href{mailto:loretan.mico@gmail.com}{Emailing me} about \pkg{selnolig} will definitely get my attention. I'm also a fairly active participant (handle: \enquote{Mico}) on \href{http://tex.stackexchange.com/}{tex.stackexchange.com}, and I occasionally check what goes on in \href{http://texwelt.de/wissen/}{TeXwelt.de}, \href{https://groups.google.com/forum/?fromgroups#!forum/comp.text.tex}{comp.text.tex} and \href{https://groups.google.com/forum/#!forum/de.comp.text.tex}{de.comp.text.tex}. In case I appear to miss any \pkg{selnolig}-related discussions on these sites, please don't hesitate to contact me to alert me to them.
+
+When reporting what you believe to be shortcomings and/or mistakes with the package's ligature suppression rules, please use a structure similar to the template given in \cref{sec:template} of this document.
+
+If anyone is thinking of creating rules to suppress ligatures selectively for languages other than English and German and would like to make use of the \enquote{machinery} provided by the \pkg{selnolig} package, I'd be delighted to provide reasonable amounts of programming-related assistance.\footnote{A promising candidate (in my view at least) for getting the \pkg{selnolig} treatment would be {\blackletter blackletter} or {\blackletter Fraktur} fonts and their special ligatures. When used to write German documents, it is well known that these ligatures need to be suppressed for certain words, i.e., selectively. E.g., to suppress the {\blackletter tz} (|tz|) ligature for the words {\blackletter Brotzeit}, {\blackletter Nachtzeit}, and {\blackletter Tatzeit}, one could set up the rule \Verb+\nolig{tzeit}{t|zeit}+. If somebody wants to take on this project, I'd be happy to help you get started.}
+
+The latest versions of all files that comprise the \pkg{selnolig} package may be found at the \href{https://github.com/micoloretan/selnolig}{package's GitHub site}. What's there may be slightly more up to date than what I manage to push to the \href{http://ctan.org/tex-archive/macros/luatex/latex/selnolig}{CTAN page}.
+
+\section{License and acknowledgments} \label{sec:thanks}
+
+The entire \pkg{selnolig} package is placed under the terms of the \LaTeX\ Project Public License, version~1.3 or later (\url{http://www.latex-project.org/lppl.txt}).
+It has the status \enquote{maintained}.
+
+I owe a huge intellectual and programming debt to Patrick Gundlach and Taco Hoekwater, who responded kindly and generously with detailed computer code to various queries I posted to \href{http://tex.stackexchange.com}{\texttt{tex.stackexchange.com}}.\footnote{See especially the questions \href{http://tex.stackexchange.com/q/37443/5001}{Any suggestions/requests for features for a new package that allows disabling ligatures for (pre)selected words?}, \href{http://tex.stackexchange.com/q/48516/5001}{How to suppress the operation of a luatex-defined macro on a string if the string is part of macro or a label}, and \href{http://tex.stackexchange.com/q/63005/5001}{Ligature suppression algorithm fails if the word in question contains an Umlaut (dieresis) before the ligature}.} Without their help and support, this package would not exist. They certainly deserve most of the credit for the lua code used by the \pkg{selnolig} package.
+
+Felix Lehmann (a linguist and expert in morphology, i.e., the study of morphemes) and Steffen Hildebrandt (computer scientist extraordinaire) served as patient and careful testers of several early beta versions of this package, uncovering and fixing bugs, pointing out unclear passages in the user guide, writing scripts to automate the discovery of redundancies and syntax errors in the package's \cmmd{nolig} and \cmmd{keeplig} rules, and providing many excellent suggestions for improving the package. Steffen also provided crucial modifications to the package's lua code to make possible the \cmmd{keeplig} and \cmmd{uselig} macros.
+
+Equally importantly, Felix and Steffen created scripts to test systematically and comprehensively the package's German \cmmd{nolig} and \cmmd{keeplig} rules for linguistic adequacy and (relative) completeness.
+They began with a corpus of almost 850 million [!!] German words, which they marked up with information on the morphological constituents of each word. From this huge word list, they extracted a set of 462,000 unique word forms containing potential f-ligatures.
+According to their analysis, an early version (October 2012) of the \pkg{selnolig} package already dealt correctly with 85 percent (394,000) of those word forms, while still generating 21,000 Type~I errors and 48,000 Type~II errors!\footnote{In the context of the \pkg{selnolig} package, a Type~I error is the failure to suppress a typographically inappropriate ligature, and a Type~II error is the improper suppression of a typographically appropriate ligature.}\textsuperscript{,}\footnote{1,000 words contained more than one potential f-ligature, hence the difference.}
+
+Fortunately for me, they quickly discovered that a non-negligible part of the 69,000 errors wasn't real but, rather, the result of spelling errors in the words included in the corpus and/or of suspect morphological analysis. Moreover, the detailed Type~I and Type~II error lists they generated were critical in helping me refine\textemdash and occasionally revise completely\textemdash the package's \cmmd{nolig} and \cmmd{keeplig} rules, rapidly bringing down the number of Type~I and~II errors. For instance, after Steffen wrote the lua code that made possible the \cmmd{keeplig} macro, the single rule \Verb+\keeplig{flicht}+ eliminated, in one fell swoop, more than 10,000~[really!] Type~II errors generated by the package's initial suppression of the fl-ligature in words that contain the morpheme \opt{pflicht}. All major changes to the German language ligature suppression patterns are still being subjected to their testing algorithms, streamlining the tasks of detecting what's left to improve and catching any newly introduced errors.
+
+Felix and Steffen started the automated testing of the package's |\nolig| and |\keeplig| rules as their finals project for the course \emph{Introduction to Computational Linguistics} at the University of Massachusetts at Amherst which they attended in the fall of~2012.%
+\footnote{Both their \href{https://github.com/SHildebrandt/selnolig-check}{code} and their \href{https://github.com/SHildebrandt/selnolig-check/blob/master/selnolig-check-documentation.pdf?raw=true}{finals paper} are available online.} They wish to thank the Institut für Maschinelle Sprachverarbeitung at the Universität Stuttgart for granting them a license for the morphological analysis tool SMOR\footnote{Schmid, H., A. Fitschen, and U. Heid, 2004, \enquote{SMOR: A German Computational Morphology Covering Derivation, Composition, and Inflection}, \emph{Proceedings of the IVth International Conference on Language Resources and Evaluation (LREC)}, pp.~1263--1266, Lisbon, Portugal.} and, in particular, Helmut Schmid for his guidance. They also express their gratitude to the \emph{Web-as-Corpus kool ynitiative} (\emph{WaCky}) for letting them use the SDeWaC corpus,\footnote{Baroni, M., S.~Bernardini, A.~Ferraresi, and E.~Zanchetta, 2009, \enquote{The WaCky Wide Web: A Collection of Very Large Linguistically Processed Web-Crawled Corpora}, \emph{Language Resources and Evaluation}, 43~(3), pp. 209--226.} as well as to Rajesh Bhatt (University of Massachusetts at Amherst), Miriam Butt (Universität Konstanz), and Sabine Schulte im~Walde (Universität Stuttgart) for helping them find the right resources for their project.
+
+The \href{http://www.ctan.org/tex-archive/support/rmligs}{\pkg{rmligs}} perl script by Björn Jacke lists about 1,700 German language words for which various f-ligatures should be suppressed. The initial set of German-language \cmmd{nolig} rules I wrote were designed to capture the words listed by \pkg{rmligs}.\footnote{All versions of the \pkg{rmligs} package are archived at \url{http://www.j3e.de/ispell/igerman98/dict/}.}
+
+Matthias Vogel very kindly shared with me a set of regular-expression based ligature suppressing macros, named \href{http://www.winedt.org/Macros/LaTeX/Ligatures-German.php}{Ligatures-German}, he wrote for the WinEdt programmer's editor. Matthias's macros work by inserting \pkg{babel}-style~\Verb+"|+ ligature-suppressing directives in the appropriate places in the |.tex| file, which can then be compiled with pdf\LaTeX. These macros, and a file he sent me containing an extensive list of German words for which one or more f-ligatures should be suppressed, led me to thoroughly refine and extend the scope of the \pkg{selnolig} package's German language ligature suppressing rules.
+
+Barbara Beeton provided very detailed comments on an early version of the package's user guide and its English language ligature suppression rules. She also noted that the readability of my surname might be enhanced if it were typeset as \emph{Loretan} instead of as \emph{\uselig{Loretan}}\dots\ David Bellows contacted me about the package and provided a suggestion that led me to extend some of the \cmmd{nolig} rules in Part~2 (activated by setting the option |broadf|) of the file \pkg{selnolig-english-patterns.sty}.
+
+Other contributors who posted answers and comments to various ligature-related questions I've asked occasionally on \href{http://tex.stackexchange.com/}{tex.stackexchange.com} and \href{https://groups.google.com/forum/#!forum/comp.text.tex}{comp.text.tex}, too numerous to name individually, also helped influence the genesis of this package. To all of you, I express my sincere thanks.
+
+%The website \url{http://www.morewords.com} provides very convenient methods for searching English language words that may contain cases of ligature collisions across morpheme boundaries. For German words, the site \url{http://corpora.informatik.uni-leipzig.de/?dict=de} provides a similar resource.
+
+
+\clearpage
+\appendix
+\selnoligoff % turn off selnolig's macros
+
+\clubpenalty100
+\widowpenalty100
+
+\small % reduce text font size from 11pt to 10pt
+
+
+\section[The package's English-language ligature suppression rules]{English-language ligature suppression rules:
+\pkg{selnolig-english-patterns.sty}}
+\label{sec:eng-listing}
+
+\begin{multicols}{2}
+\VerbatimInput{selnolig-english-patterns.sty}
+\end{multicols}
+
+\clearpage
+\section[The package's German-language ligature suppression rules]{German-language ligature suppression rules: \pkg{selnolig-german-patterns.sty}}
+\label{sec:germ-listing}
+
+Introductory note: To accommodate the practice of Swiss-German writers of not using the \enquote{ß} character and using \enquote{ss} in its place, all search-and-insert strings that contain an \enquote{ß} character are duplicated with equivalent search-and-insert strings containing~\enquote{ss}.
+
+\bigskip
+
+\begin{multicols}{2}
+\VerbatimInput{selnolig-german-patterns.sty}
+\end{multicols}
+
+\clearpage
+\section[The package's main style file: selnolig.sty]
+{The package's main style file: \pkg{selnolig.sty}}
+\label{sec:sty}
+
+\VerbatimInput{selnolig.sty}
+
+\clearpage
+\section[The package's lua code: selnolig.lua]{The package's lua code: \pkg{selnolig.lua}}
+\label{sec:luacode}
+
+\VerbatimInput{selnolig.lua}
+
+\clearpage
+
+\section[Reporting bugs and other issues with the selnolig package: A suggested template]{Reporting bugs and other issues with the \pkg{selnolig} package:\\A suggested template} \label{sec:template}
+
+\VerbatimInput{selnolig-bugreport.tex}
+
+\clearpage
+\selnoligon
+\section{A case study: f-ligatures suppressed in \emph{Die Buddenbrooks} and in \emph{Faust I \& II}} \label{sec:budd}
+
+\ebg
+
+As I noted in the introduction, in English language documents the suppression of ligatures that cross morpheme boundaries is generally not considered to be an urgent typographical priority, possibly because words with ligatures that cross morpheme boundaries aren't all that common. I performed a quick check of this claim by compiling Jack London's novels \emph{Call of the Wild} and \emph{The Sea Wolf}, obtained from Project Gutenberg's site in plain-text format, with \pkg{selnolig}. Sure enough, in \emph{Call of the Wild} only one f-ligature is suppressed: the \enquote{fl} ligature in \uselig{wolflike}\slash wolflike. In \emph{The Sea Wolf}, again only one f-ligature is suppressed: the \enquote{ft} ligature in \uselig{fifth}\slash fifth (3 instances). Not exactly a lot of words, right?!
+
+The situation is quite different for German texts. E.g., in Thomas Mann's novel \emph{Die Buddenbrooks}, more than 430 words are caught by \pkg{selnolig}'s rules; they are listed below. (Incidentally, the fi-ligature in the words Kaufinger and Kaufingerstraße is suppressed because \enquote{\uselig{Kaufinger}} (\enquote{chew-finger}) looks unintentionally hilarious.)
+
+\enlargethispage{1.5\baselineskip}
+
+\smallskip
+
+{\RaggedRight
+
+\noindent
+\begin{tabularx}{\textwidth}{@{}lX@{}}
+\midrule
+f-lig.\ & Words for which the f-lig.\ is suppressed by \pkg{selnolig}'s rules (433 total) \\
+\midrule
+\uselig{fb}, \uselig{ffb} &
+Aufbahrung,
+aufbegehrt,
+aufbegehrte,
+Aufbewahrungsort,
+Aufbietung,
+aufblicken,
+aufblitzenden,
+aufblitzt,
+aufblitzten,
+aufblühende,
+aufbrach,
+aufbrechen,
+aufbringen,
+aufbringt,
+Aufblick,
+Aufbrausen~(2),
+Aufbruch~(4),
+Briefbeschwerer,
+Dampfbrot,
+daraufbringen,
+greifbaren,
+Greifbares,
+heraufbefördert,
+hinaufblickte,
+Hofbräu,
+Hofbräuhaus~(3),
+Hofbräuhause,
+Kopfbewegung~(3),
+Kopfbewegungen,
+Krippenaufbaus,
+Laufbahn,
+Privatbriefbogen,
+Scharfblick,
+Schiffbrüchen,
+Schlafbedürfnis,
+steifbeinigen,
+Stiefbruder~(4),
+strafbar~(2),
+tiefbelustigt,
+tiefblauen~(2),
+unangreifbar\\ %%
+ff &
+Auffahren,
+Auffahrt,
+auffallend~(5),
+auffassen,
+Auffassung,
+auffordern~(2),
+aufforderte~(4),
+Aufforderung~(2),
+Aufforderungen,
+Aufführung,
+auffällig~(2),
+auffällige~(2),
+auffälliger~(2),
+auffällt,
+aufführen,
+aufführte,
+fünffacher~(2),
+herauffuhr,
+heraufführte,
+Kauffahrteischiffen (Type~II error\slash arch. spelling?),
+Liebhaberaufführung,
+Schlaffrisur,
+unauffällig,
+unauffällige\\ %%
+ffi & Auffinden\\ %%
+ffl &
+ffl $\to$ f\kern0ptfl:
+Aufflackern,
+aufflog;
+ffl $\to$ ff\kern0ptl:
+unübertrefflich~(3),
+unübertrefflichen,
+vortrefflich~(11),
+vor\-treff\-li\-che~(2),
+vortrefflichen,
+vortrefflicher,
+vortreffliches,
+vortrefflichsten\\ %%
+{\ebg \uselig{fh}, \uselig{ffh}} &
+aufheben~(3),
+Aufhebens,
+aufhebt,
+Aufhebung,
+aufheitert,
+aufhellte,
+aufhielt~(3),
+Aufhorchend,
+aufhorchenden,
+aufhält~(2),
+aufhören~(14),
+aufhörte~(6),
+daraufhin~(2),
+Fünfhausen~(2),
+fünfhundert~(5),
+Hundertsiebenundzwanzigtausendfünfhundert~[!!],
+Kaufherren~(2),
+krampfhaft~(6),
+krampfhafte~(2),
+krampfhafte,
+krampfhaften~(4),
+Schlaffheit,
+Steifheit~(2),
+unaufhaltsam~(5),
+unaufhaltsame,
+unaufhaltsamen,
+unaufhaltsamer,
+unaufhörlich~(14),
+unaufhörliche,
+unaufhörlichen\\ %%
+fi &
+Kaufinger,
+Kaufingerstraße,
+tiefinnere\\ %%
+{\ebg \uselig{fj}} &
+Aufjauchzen,
+elfjährig,
+fünfjährigen,
+zwölfjährig~(2)\\
+{\ebg \uselig{fk}, \uselig{ffk}} &
+aufkam,
+aufklingen,
+aufklärte,
+Aufklärung,
+aufkommen,
+Briefkas\breaklig{}ten,
+Haffkrug,
+heraufkamen,
+heraufkommen~(3),
+Heraufkommenden,
+Kehlkopfknoten,
+Kopfkissen~(2),
+Napfkuchens,
+Stopfkugel~(2)\\
+fl &
+auflehnte,
+aufleuchtete~(2),
+auflösen,
+auflöste,
+Auflösung~(11),
+begreiflich,
+Begreiflicherweise,
+be\-hilf\-lich~(6),
+beruflichen~(3),
+glimpflich~(2),
+gräflichen,
+Großkaufleuten,
+Handgreifliches,
+hilflos~(7),
+hilfloses,
+Hilf\-losigkeit~(2),
+Hilflosigkeitsgefühl,
+hinaufläuft,
+höflich~(7),
+höfliche~(2),
+höflichen,
+Höflichkeit~(6),
+Höflichkeitsform,
+höflichst,
+kampflose,
+kampflosen,
+Kaufleute~(9),
+Kaufleute-Witwenkasse,
+Kauf\-leuten~(3),
+Knopfloch,
+käuflich~(2),
+reiflich,
+schimpfliche,
+schimpflichen,
+schlaflos,
+schlaflose,
+schlaflosen,
+Schlaflosigkeit,
+steiflehnige,
+teuflischem,
+teuflischer,
+teuflisches,
+tiefliegende,
+tiefliegenden~(20),
+unbegreif\-lich~(3),
+unbegreifliche,
+unbegreiflichen~(3),
+unbegreiflicher,
+Unbegreiflicherweise,
+unerschöpflich,
+unhöflichen,
+Verzweiflung~(23),
+verzweiflungsvoll~(2),
+Zöpflein,
+zweifle~(2)\\
+ft &
+auftat~(2),
+auftauchen,
+auftauchte,
+auftauen,
+auftreten,
+Auftreten~(3),
+Auftritt~(3),
+Auftritte~(2),
+Auftritten,
+Auftrittes,
+auftrittst,
+Aufträge,
+Briefträger,
+elftausend,
+Elfter,
+Elftes~(3),
+fünftausend~(2),
+fünften~(3),
+fünfter,
+Fünfter,
+Fünftes~(9),
+Hoftheater,
+Hoftheaterbesuchen,
+Hoftore (2),
+Hoftür,
+schlaftrunkenen,
+schlaftrunkener,
+Schnupftuch~(3),
+Schnupftuche,
+Schnupftuches,
+Tauftages,
+Zwölftes\\
+\bottomrule
+\end{tabularx}
+
+\clearpage
+Here are the analogous compilations for Johann Wolfgang Goethe's \emph{Faust~I} and \emph{Faust~II}:
+
+\smallskip
+\noindent
+\begin{tabularx}{\textwidth}{@{}lX@{}}
+\midrule
+f-lig.\ & Words for which the f-lig.\ is suppressed by \pkg{selnolig}'s rules\\
+\midrule
+\multicolumn{2}{@{}l@{}}{\emph{Faust I} (30 words total)}\\
+\uselig{fb} &
+aufbewahrt,
+aufbindend,
+Schiffbruchs,
+Strumpfband,
+tiefbewegte\\
+\uselig{fh} &
+fünfhundert\\
+fl &
+hilflos,
+höflich,
+Höflichkeit~(3),
+Unhöfliches,
+Verzweiflung~(2),
+teuflisch,
+teuflischen~(2),
+unbegreiflich~(3),
+würfle\\
+ffl &
+Schifflein,
+trefflich~(4),
+treffliche,
+trefflichen,
+trefflicher\\
+ft &
+Auftrag\\[2ex]
+\multicolumn{2}{@{}l@{}}{\emph{Faust II} (31 words total)}\\
+\uselig{fb} &
+Aufbau,
+aufbewahrt,
+aufblühender,
+Raufbold,
+Ungreifbarer\\
+\uselig{fh} &
+unaufhaltsam~(2)\\
+fl &
+flehn [Type~II error!],
+fünften,
+greiflich,
+höflich~(2),
+Liebesbrieflein,
+Scherflein,
+schimpflich,
+sträflich,
+Tiefauflauerndes,
+Tröpflein,
+überteuflisch,
+unbegreifliche,
+unbehülflich,
+Verwerfliche,
+Verzweiflung,
+Zweifler,
+verwerflich,
+verzweiflend,
+zweiflen\\
+ffl &
+trefflich\\
+ft &
+Auftrag,
+Auftretend,
+Fünftausend\\
+\bottomrule
+\end{tabularx}
+} % end of \RaggedRight
+
+\medskip
+Without meaning to comment in any way on the literary merits of these works, I find it interesting that Goethe's two pieces contain far fewer instances of words for which ligatures need to be broken up than does \emph{Die Buddenbrooks}. I also find it mildly interesting that no \opt{fj} and \opt{fk} instances are present in the two Goethe pieces. Also at least somewhat interestingly, the noun \enquote{Verzweiflung} occurs 23 times in \emph{Die Buddenbrooks} but only 3~times across both parts of \emph{Faust}.
+
+Note the Type~II error, \emph{viz.}, the word \enquote{flehn} (better: \uselig{flehn}), in the listing for \emph{Faust~II}. This error (which I've deliberately not removed) serves to illustrate\textemdash just in case this wasn't already clear\textemdash that \pkg{selnolig} is not and cannot ever be entirely error-free. If you use the package in your work, I recommend that you compile your document with \cmmd{debugon} turned on from time to time. Doing so will write the results of \pkg{selnolig}'s work to the |.log| file. Then, examine the log file, either directly or via a machine search for lines containing the string \enquote{ligature suppression}. (This is, by the way, precisely how I started putting together the word lists shown above.) Any Type~II errors should be fairly easy to spot this way. To fix them, you can edit your file and encase the words in question in \cmmd{uselig} instructions, or you can create new \cmmd{keeplig} instructions to override the action of the offending \cmmd{nolig} instructions. When creating new \cmmd{keeplig} rules, do take care not to introduce new Type~I errors in the process. For instance, don't create the rule \Verb+\keeplig{flehn}+, as doing so would cause failures to break up the fl ligatures in, \emph{inter alia}, auflehnen, Auto\-kopflehne, Stofflehne, and steiflehnig. (Actually, since these particular words don't occur in \emph{Faust~II}, you'd be \enquote{safe} with \Verb+\keeplig{flehn}+ as long as \emph{Faust~II} is the only document you need to typeset\dots)
+
+It's important to keep in mind that the lists shown above contain (i) \pkg{selnolig}'s \enquote{success stories} and (ii) any Type~II errors. By design, they cannot show the package's Type~I errors, \emph{viz.}, failures to break up ligatures that span morpheme boundaries. To catch any Type~I errors, I'm afraid you'll have read your output file and scan it for inappropriate ligatures. (Hopefully, there won't be too many such instances!) To remedy any Type~I errors, you should either insert \cmmd{breaklig} instructions in the words in question or devise new \cmmd{nolig} instructions\textemdash whatever works best for you.
+
+A final plea: Please feel free to inform me about any Type~I and/or Type~II errors you believe are generated by the \pkg{selnolig} package. My email address is stated on the front page of this user guide. Happy \TeX ing!
+
+
+
+\end{document}
diff --git a/macros/luatex/latex/showhyphens/README b/macros/luatex/latex/showhyphens/README
new file mode 100644
index 0000000000..cf245e5b75
--- /dev/null
+++ b/macros/luatex/latex/showhyphens/README
@@ -0,0 +1,11 @@
+The LaTeX package 'showhyphens' shows all possible hyphenation points in
+the PDF output.
+
+Usage:
+
+\usepackage{showhyphens}
+
+Requirements: The package only works with LuaLaTeX.
+
+Copyright 2011-2016 Patrick Gundlach (patrick@gundla.ch),
+licensed under the MIT license. See the style for details.
diff --git a/macros/luatex/latex/showhyphens/showhyphens-doc.pdf b/macros/luatex/latex/showhyphens/showhyphens-doc.pdf
new file mode 100644
index 0000000000..06a175f325
--- /dev/null
+++ b/macros/luatex/latex/showhyphens/showhyphens-doc.pdf
Binary files differ
diff --git a/macros/luatex/latex/showhyphens/showhyphens-doc.tex b/macros/luatex/latex/showhyphens/showhyphens-doc.tex
new file mode 100644
index 0000000000..0ec2875290
--- /dev/null
+++ b/macros/luatex/latex/showhyphens/showhyphens-doc.tex
@@ -0,0 +1,102 @@
+\documentclass{ltxdockit}
+\usepackage{dtklogos,csquotes,graphicx}
+
+\newcommand\pkgversion{0.5c}
+
+\titlepage{%
+ title={The showhyphens package},
+ subtitle={Show all possible hyphenation points},
+ url={(none yet)},
+ author={Patrick Gundlach},
+ email={patrick@gundla.ch},
+ revision={\pkgversion},
+ date={\today}}
+
+\begin{document}
+\printtitlepage
+\tableofcontents
+
+\section{Documentation}
+
+When you load the package \texttt{showhyphens} in your Lua\LaTeX\ document, \LaTeX\ will show all possible hyphenation points. This
+package requires you to process the document with Lua\LaTeX.
+
+\begin{verbatim}
+\documentclass{article}
+\usepackage{showhyphens}
+
+\begin{document}
+A wonderful serenity has taken
+possession of my entire soul, like these
+sweet mornings of spring which I enjoy
+with my whole heart. I am alone, and
+feel the charm of existence in this
+spot, which was created for the bliss of
+souls like mine. I am so happy, my dear
+friend, so absorbed in the exquisite
+sense of mere tranquil existence, that I
+neglect my talents. I should be
+incapable of drawing a single stroke at
+the present moment; and yet I feel that
+I never was a greater artist than now.
+\end{document}
+\end{verbatim}
+
+yields \vspace{5mm}
+
+\noindent \includegraphics{showhyphens-sample}
+
+\section{Bugs and limitations}
+
+% see http://tex.stackexchange.com/q/268884
+Hyphenation points within ligatures cannot be shown correctly. The package marks the ligature with a horizontal bar on top. The hyphenation point is somewhere within the ligature.
+For example \enquote{office} gives the word \enquote{office} with a horizontal bar on top of \enquote{ffi} but should show of'fice instead.
+While it is possible to look inside
+the ffi ligature and find out where the original hyphen character was placed
+(between the first f and the following component fi), it is very hard to draw
+the line indicating the hyphenation point correctly. The ffi ligature is one
+opaque rectangle to the package. Drawing a line at the correct position is
+pure luck, and therefore out of the scope of the package.
+
+\section{Options}
+
+\begin{optionlist}
+\legitem{blue}{Shows hyphenation marker in blue, instead of red.}
+\end{optionlist}
+
+
+\section{Changes}
+
+\begin{changelog}
+\begin{release}{0.5c}{2016-02-19}
+ \item Remove viz-nodelist
+\end{release}
+\begin{release}{0.5b}{2016-02-05}
+ \item Fix version number
+\end{release}
+\begin{release}{0.5a}{2016-02-05}
+ \item Remove debug message
+\end{release}
+\begin{release}{0.5}{2016-02-05}
+ \item Mark ligatures
+\end{release}
+\begin{release}{0.4a}{2015-09-23}
+ \item Documentation update.
+\end{release}
+\begin{release}{0.4}{2015-09-22}
+ \item Document limitation on ligatures.
+\end{release}
+\begin{release}{0.3}{2014-07-30}
+ \item Internal changes (node structure corrected, node ids not hard coded)
+\end{release}
+\begin{release}{0.2}{2012-10-25}
+ \item New option \enquote{blue}, thanks go to Herbert Vo\ss.
+\end{release}
+\end{changelog}
+
+\section{Copying}
+
+Copyright 2011-2016 Patrick Gundlach (patrick@gundla.ch), licensed under the MIT license. See the style for details.
+
+
+\end{document}
diff --git a/macros/luatex/latex/showhyphens/showhyphens-sample.pdf b/macros/luatex/latex/showhyphens/showhyphens-sample.pdf
new file mode 100644
index 0000000000..1a961538ab
--- /dev/null
+++ b/macros/luatex/latex/showhyphens/showhyphens-sample.pdf
Binary files differ
diff --git a/macros/luatex/latex/showhyphens/showhyphens.sty b/macros/luatex/latex/showhyphens/showhyphens.sty
new file mode 100644
index 0000000000..38d1d2603a
--- /dev/null
+++ b/macros/luatex/latex/showhyphens/showhyphens.sty
@@ -0,0 +1,68 @@
+\ProvidesPackage{showhyphens}[2016/02/19 v0.5c Show hyphenation points (PGU)]
+\RequirePackage{ifluatex,luatexbase}
+% License: MIT style license
+
+% Copyright (c) 2011-2016 Patrick Gundlach patrick@gundla.ch
+
+% Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
+% "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
+% publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
+% so, subject to the following conditions:
+%
+% The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+%
+% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+% FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+% WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+\def\lua@SHcolor{1 0 0}% red
+\DeclareOption{blue}{\def\lua@SHcolor{0 0 1 }}% must be a rgb color
+\ProcessOptions
+
+\ifluatex
+\directlua{
+local show_hyph
+local hlist_node = node.id("hlist")
+local vlist_node = node.id("vlist")
+local disc_node = node.id("disc")
+local glyph_node = node.id("glyph")
+
+local function round(num)
+ return math.floor(num * 10^3 + 0.5) / 10^3
+end
+
+show_hyph = function(head)
+ while head do
+ if head.id == hlist_node or head.id == vlist_node then
+ show_hyph(head.list)
+ elseif head.id == disc_node then
+ if head.replace and head.replace.id == glyph_node and head.replace.components then
+ local wd = round(head.replace.width / 65781) or 0
+ local ht = round(head.replace.height / 65781) + 0.5 or 0
+ local r = node.new("whatsit","pdf_literal")
+ r.data = "q 0.3 w 0 " .. tostring(ht) .. " m " .. tostring(-wd) .. " " .. tostring(ht) .. " l S Q"
+ node.insert_after(head.replace,head.replace,r)
+ else
+ local n = node.new("whatsit","pdf_literal")
+ n.mode = 0
+ n.data = "q \lua@SHcolor RG 0.3 w 0 2 m 0 7 l S Q"
+ n.next = head.next
+ head.next.prev = n
+ n.prev = head
+ head.next = n
+ head = n
+ end
+ end
+ head = head.next
+ end
+ return true
+end
+
+
+luatexbase.add_to_callback("post_linebreak_filter",show_hyph,"show_hyph")
+}
+\else
+\errhelp{Please use LuaLaTeX when you require the package 'showhyphens'}
+\errmessage{Package showhyphens error: This works only with LuaLaTeX!}
+\fi
diff --git a/macros/luatex/latex/simurgh/README b/macros/luatex/latex/simurgh/README
new file mode 120000
index 0000000000..22386b956c
--- /dev/null
+++ b/macros/luatex/latex/simurgh/README
@@ -0,0 +1 @@
+./doc/README \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/doc/ChangeLog b/macros/luatex/latex/simurgh/doc/ChangeLog
new file mode 100644
index 0000000000..0df495cc4e
--- /dev/null
+++ b/macros/luatex/latex/simurgh/doc/ChangeLog
@@ -0,0 +1,25 @@
+2013-09-22 0.01b Vafa Khalighi
+ * 0.01b
+ * Supported `letter.cls'
+ * Supported `memoir.cls'
+ * Supported `rapport1.cls'
+ * Supported `rapport3.cls'
+ * Supported `refrep.cls'
+ * Supported `report.cls'
+ * Supported `scrartcl.cls'
+ * Supported `scrbook.cls'
+ * Supported `scrlettr.cls'
+ * Supported `scrreprt.cls'
+ * Fixed equation numbers.
+ * Fixed bad margin of `multline' environment of `amsmath' package with
+ `fleqn' option.
+ * Fixed bad positioning of `align*' environment.
+ * Fixed `\intertext' command of `amsmath' package.
+ * Better `\llap' and `\rlap' macros.
+ * Updated `simurgh-empheq.sty'.
+
+2013-09-18 0.01a Vafa Khalighi
+ * 0.01a
+ * First version of `simurgh' package released; this version provides basic
+ functionality for Parsi typesetting in LaTeX2e, using the LuaTeX engine.
+ \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/doc/README b/macros/luatex/latex/simurgh/doc/README
new file mode 100644
index 0000000000..32306b53a2
--- /dev/null
+++ b/macros/luatex/latex/simurgh/doc/README
@@ -0,0 +1,17 @@
+The simurgh package
+=================
+
+The `simurgh' package provides an automatic and unified interface for
+Parsi typesetting in LaTeX, using the LuaTeX engine.
+
+See the documentation `simurgh-doc.pdf` for full information.
+
+
+License
+----------
+
+Copyright 2013 Vafa Khalighi <persian-tex@tug.org>
+
+Permission is granted to copy, distribute and/or modify
+all files of this package under the terms of the GNU Public License,
+Version 2 or any later version published by the Free Software Foundation. \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/doc/simurgh-doc.pdf b/macros/luatex/latex/simurgh/doc/simurgh-doc.pdf
new file mode 100644
index 0000000000..32349abcd7
--- /dev/null
+++ b/macros/luatex/latex/simurgh/doc/simurgh-doc.pdf
Binary files differ
diff --git a/macros/luatex/latex/simurgh/doc/simurgh-doc.tex b/macros/luatex/latex/simurgh/doc/simurgh-doc.tex
new file mode 100644
index 0000000000..6890542761
--- /dev/null
+++ b/macros/luatex/latex/simurgh/doc/simurgh-doc.tex
@@ -0,0 +1,658 @@
+\documentclass{simurgh-doc}
+\pagestyle{docheadings}
+\setmainfont[Ligatures=TeX,Numbers=OldStyle]{Iwona}
+\newminted{tex}{frame=leftline,framerule=5pt,rulecolor=\color{gray}}
+\newminted{lua}{frame=leftline,framerule=4pt,rulecolor=\color{lightgray}}
+\usemintedstyle{emacs}
+\makeindex
+\renewcommand*{\baselinestretch}{1.5}
+\title{\textcolor{red!65!black}{\Huge The \simurgh{} \textit{package}}\\
+\LARGE Typeset Parsi in Lua\LaTeX\\[5pt]
+\large Documentation for \textcolor{red!65!black}{version 0.01b}}
+\author{Vafa Khalighi\\
+\url{persian-tex@tug.org}}
+\begin{document}
+\setcounter{page}{0}
+\thispagestyle{empty}
+\includegraphics[width=.3\textwidth]{simurgh-logo}\qquad
+\parindent 0pt
+\vbox{\Huge
+\textcolor{red!65!black}{The \simurgh{} \textit{package}}
+
+\Large
+Documentation for \textcolor{red!65!black}{version 0.01b}}
+
+
+
+
+
+\vskip 0pt plus 3fill
+\textit{\large to my Master, \textbf{Ferdowsi The Great}}
+
+
+\vskip 0pt plus 3fill
+{\color{red!85!black}\fbox{\begin{minipage}{\textwidth}
+This document will eventually become the documentation of the \simurgh{} \textit{package}.
+At the moment, it simply reports the behaviour of the \textit{package}
+matching the release version in the title page.
+
+\medskip
+Features may come and go. The current version of \simurgh{} \textit{package} is not
+meant for production and users can not depend on stability, nor on
+functionality staying the same.
+
+\medskip
+Nothing is considered stable just yet. This documentation therefore
+simply reflects the current state of the \textit{package}. \textbf{\textit{
+Absolutely nothing}} on the following pages is set in stone. When
+the need arises, anything can (and will) be changed.
+
+\medskip
+\textbf{If you are not willing to deal with this situation, you should
+wait for the stable version. Currently there is no set date for the stable version. Full stabilization will not happen soon, the
+TODO list is still large.}
+\end{minipage}}}
+
+
+\vskip 0pt plus 3fill
+
+
+Copyright 2013 by Vafa Khalighi
+
+\medskip
+Permission is granted to copy, distribute and/or modify all files of this package under the terms of the \textsc{gnu} Public License, Version 2 or any later version published by the Free Software Foundation. A copy of the license is included in the section entitled \textsc{gnu} Public License.
+
+
+\clearpage
+
+
+
+
+
+
+
+
+\maketitle
+
+
+\tableofcontents
+
+\clearpage
+
+
+\section{Introduction}
+
+\subsection{Overview of the package}
+
+\subsection{How to Read This Documentation}
+
+This documentation explains the commands of the \simurgh{} \textit{package} and its usage. The ``public'' commands and environments provided by the \simurgh{} \textit{package} are described throughout the text. In each such description, the described command, environment or option is printed in red. Text shown in green is optional and can be left out.
+
+In the following documentation, the installation is explained first, followed by an overview of the basic concepts used. Then, we explain the usage of the \textit{package}.
+
+\subsection{Contributing}
+
+\subsection{Getting Help}
+
+When you need help with the \textit{package}, please do the following:
+
+\begin{enumerate}
+ \item Read this documentation, at least the part that has to do with your problem.
+ \item Consider rereading the documentation, especially the part that has to do with your problem.
+ \item If that does not solve the problem, \emph{as a last resort} you can try to email me. I do not mind getting emails, I simply get way too many of them. Because of this, I can not guarantee that your emails will be answered timely or even at all.
+ \item Before you file a bug report, especially a bug report concerning the installation, make sure that this is really a bug. In particular, have a look at the |.log| file that results when you run |lualatex| on your files. This |.log| file should show that all the right files are loaded from the right directories. Nearly all installation problems can be resolved by looking at the |.log| file.
+\end{enumerate}
+
+\section{Installation}
+
+This \textit{package} is distributed under the \textsc{gpl} license, see \autoref{subsection:gpl}.
+
+Typically, the \textit{package} will already be installed on your system. Naturally, in this case you do not need to worry about the installation process at all and you can skip the rest of this section.
+
+\subsection{\textit{package} and Driver Versions}
+
+This documentation is part of version 0.01b of the \simurgh{} \textit{package}. To use it, you just need a reasonably up-to-date \LaTeX-system, but the requirements are rather low. There are no special dependencies.
+
+\subsection{Installing Prebundled Packages}
+
+I do not create or manage prebundled packages of \simurgh, but perhaps other people might be willing to do so. If you have a problem with installing such a bundle, you might wish to have a look at the page of whoever created the package.
+
+
+\subsection{Installation in a texmf Tree}
+
+For a permanent installation, you place the files of the \simurgh{} \textit{package} in an appropriate |texmf| tree.
+
+When you ask |lualatex| to use a certain class or package, it usually looks for the necessary files in so-called |texmf| trees. These trees are simply huge directories that contain these files. By default, |lualatex| looks for files in three different |texmf| trees:
+\begin{itemize}
+ \item The root |texmf| tree, which is usually located at |/usr/share/texmf/| or |c:\texmf\| or somewhere similar.
+ \item The local |texmf| tree, which is usually located at |/usr/local/share/texmf/| or |c:\localtexmf\| or somewhere similar.
+ \item Your personal |texmf| tree, which is usually located in your home directory at |~/texmf/| or |~/Library/texmf/|.
+\end{itemize}
+
+You should install the \textit{package} either in the local tree or in your personal tree, depending on whether you have write access to the local tree. Installation in the root tree can cause problems, since an update of the whole \TeX\ installation will replace this whole tree.
+
+Inside whatever texmf-tree that you have chosen, create the sub-directory |texmf/tex/lualatex/simurgh| and put all the |.cls| and |.sty| files from the \textit{package} in this directory.
+
+Finally, you may need to run the program |texhash| to rebuild \TeX's cache. In Mik\TeX, there is a menu option for this.
+
+\subsection{Updating the Installation}
+
+To update your installation from a previous version, all you need to do is to replace everything in the directory |texmf/tex/lualatex/simurgh| with the files of the new version. The easiest way to do this is to first delete the old version and then proceed as described above.
+
+Sometimes, there are changes in the syntax of certain command from version to version. If things no longer work that used to work, you may wish to have a look at the documentation and at the change log.
+
+\section{Basic Concepts}
+
+\subsection{The \simurgh{} \textit{package} logo}
+The logo of the \simurgh{} \textit{package} is simurgh shown on the titlepage and footer of this documentation.
+
+
+
+
+\subsection{Package Loading Process}
+\begin{package}{simurgh}
+You load the package in the ordinary way.
+\end{package}
+
+
+
+
+
+\section{Usage}
+
+
+\subsection{Basic Usage}
+\example
+\begin{texcode}
+\documentclass{article}
+\usepackage{simurgh}
+\setmainparsifont{XB Kayhan}
+\begin{document}
+
+\end{document}
+\end{texcode}
+
+
+\subsection{Options of the \textit{Package}}
+
+\begin{packageoption}{debug footnote direction=\meta{value}}
+\meta{value} can be any of the following values:
+\begin{description}
+\item[\defaultkeyval\opt{off}] Does not write the direction of the first footnote on each page, in the terminal and in the log file.
+\item[\opt{on}] Writes the direction of the first footnote on each page, in the terminal and in the log file.
+\end{description}
+\end{packageoption}
+
+\begin{packageoption}{footnote direction=\meta{value}}
+\meta{value} can be any of the following values:
+\begin{description}
+\item[\opt{left to right}] The direction of |\footnote| is left to right.
+\item[\defaultkeyval\opt{right to left}] The direction of |\footnote| is right to left.
+\end{description}
+\end{packageoption}
+
+\begin{packageoption}{footnote rule=\meta{value}}
+\meta{value} can be any of the following values:
+\begin{description}
+\item[\defaultkeyval\opt{automatic}] Left or right aligned footnote rule based on the direction of the first footnote following the rule (i.e. put in the current page).
+\item[\opt{left}] Left aligned footnote rule.
+\item[\opt{right}] Right aligned footnote rule.
+\item[\opt{split}] Puts a full-width rule above the split-off part of a split footnote.
+\item[\opt{textwidth}] Full-width footnote rule.
+\end{description}
+\end{packageoption}
+
+
+\begin{packageoption}{main direction=\meta{value}}
+\meta{value} can be any of the following values:
+\begin{description}
+\item[\opt{left to right}] The main direction of the document is left to right. This value has no practical applications in Parsi typesetting (it only exists for debugging purposes).
+\item[\defaultkeyval\opt{right to left}] The main direction of the document is right to left.
+\end{description}
+\end{packageoption}
+
+
+\begin{packageoption}{math digits=\meta{value}}
+\meta{value} can be any of the following values:
+\begin{description}
+\item[\defaultkeyval\opt{automatic}] If you use |\setmathparsidigitfont| at least once, then in Parsi mode you get Parsi digits in math mode and in Latin mode you get ``Latin Modern'' fonts \footnote{Of course if you have not loaded any math font packages.} and Latin digits in math mode, otherwise you get \LaTeX{} default digits in math mode everywhere.
+\item[\opt{default}] \LaTeX{} default font and digits in math mode everywhere.
+\item[\opt{parsi}] Parsi digits in math mode everywhere.
+\end{description}
+\end{packageoption}
+
+\begin{packageoption}{math direction=\meta{value}}
+\meta{value} can be any of the following values:
+\begin{description}
+\item[\defaultkeyval\opt{left to right}] The direction of math is left to right.
+\item[\opt{right to left}] The direction of math is right to left.
+\end{description}
+\end{packageoption}
+
+
+\begin{packageoption}{unicode bidi=\meta{value}}
+\meta{value} can be any of the following values:
+\begin{description}
+\item[\defaultkeyval\opt{global}] Activates unicode bidi and does not obey groupings\footnote{There is no concept of grouping in unicode bidi}.
+\item[\opt{local}] Activates unicode bidi and obeys groupings.
+\item[\opt{off}] Turns unicode bidi off.
+\end{description}
+\end{packageoption}
+
+
+\subsection{Font Commands}
+\subsubsection{Text}
+\paragraph{Basic Font Commands}
+\begin{command}{\setmainparsifont\oarg{options}\marg{font name}}
+Chooses the main Parsi font. If you do not use this command at least once, then you get an error asking you to choose the main Parsi font.
+\end{command}
+
+
+
+
+\begin{command}{\setmainlatinfont\oarg{options}\marg{font name}}
+Chooses the main Latin font. If you do not use this command at least once, then ``Latin Modern'' fonts will be used instead.
+\end{command}
+
+\paragraph{Loading New Parsi and Latin Fonts}
+\begin{command}{\loadnewparsifont\myprintocmmand{fontcs}\oarg{options}\marg{font name}}
+Loads new Parsi font.
+\example
+\begin{texcode}
+\documentclass{article}
+\usepackage{simurgh}
+\setmainparsifont{XB Kayhan}
+\loadnewparsifont\nastalighfont[Scale=1]{IranNastaliq}
+\begin{document}
+ \nastalighfont
+
+\end{document}
+\end{texcode}
+\end{command}
+
+
+\begin{command}{\loadnewlatinfont\myprintocmmand{fontcs}\oarg{options}\marg{font name}}
+Loads new Latin font.
+\example
+\begin{texcode}
+\documentclass{article}
+\usepackage{simurgh}
+\setmainparsifont{XB Kayhan}
+\loadnewlatinfont\timesfont[Scale=1]{Times New Roman}
+\begin{document}
+
+ \begin{LTRpar}
+ \timesfont
+
+ \end{LTRpar}
+
+\end{document}
+\end{document}
+\end{texcode}
+\end{command}
+
+\paragraph{Parsi Sans Font Commands}
+\begin{command}{\setparsisansfont\oarg{options}\marg{font name}}
+
+\end{command}
+
+
+\begin{command}{\parsisffamily}
+
+
+\end{command}
+
+\begin{command}{\textparsisf\marg{text}}
+
+\end{command}
+
+\paragraph{Latin Sans Font Commands}
+\begin{command}{\setlatinsansfont\oarg{options}\marg{font name}}
+
+\end{command}
+
+\begin{command}{\sffamily}
+
+\end{command}
+
+
+\begin{command}{\textsf\marg{text}}
+
+\end{command}
+
+
+\paragraph{Parsi Mono Font Commands}
+\begin{command}{\setparsimonofont\oarg{options}\marg{font name}}
+
+\end{command}
+
+\begin{command}{\parsittfamily}
+
+\end{command}
+
+
+\begin{command}{\textparsitt\marg{text}}
+
+
+\end{command}
+
+\paragraph{Latin Mono Font Commands}
+\begin{command}{\setlatinmonofont\oarg{options}\marg{font name}}
+
+\end{command}
+
+
+\begin{command}{\ttfamily}
+
+\end{command}
+
+\begin{command}{\texttt\marg{text}}
+
+\end{command}
+
+
+\paragraph{Parsi Iranic Font Commands}
+\begin{command}{\setiranicfont\oarg{options}\marg{font name}}
+
+\end{command}
+
+\begin{command}{\iranicfamily}
+
+\end{command}
+
+\begin{command}{\textiranic\marg{text}}
+
+\end{command}
+
+
+\paragraph{Parsi Navar Font Commnands}
+\begin{command}{\setnavarfont\oarg{options}\marg{options}}
+
+\end{command}
+
+
+\begin{command}{\navarfamily}
+
+
+\end{command}
+
+\begin{command}{\textnavar\marg{text}}
+
+\end{command}
+
+
+
+\paragraph{Parsi Pook Font Commands}
+\begin{command}{\setpookfont\oarg{options}\marg{font name}}
+
+\end{command}
+
+\begin{command}{\pookfamily}
+
+\end{command}
+
+\begin{command}{\textpook\marg{text}}
+
+\end{command}
+
+\paragraph{Parsi Sayeh Font Commands}
+\begin{command}{\setsayehfont\oarg{options}\marg{font name}}
+
+\end{command}
+
+\begin{command}{\sayehfamily}
+
+\end{command}
+
+\begin{command}{\textsayeh\marg{text}}
+
+\end{command}
+
+
+
+
+\subsubsection{Math}
+\begin{command}{\setmathparsidigitfont\oarg{options}\marg{font name}}
+Chooses the Parsi font for digits in math mode. If you use |\setmathparsidigitfont| at least once, then in Parsi mode you get Parsi digits in math mode and in Latin mode you get ``Latin Modern'' font and Latin digits in math mode, otherwise you get \LaTeX{} default digits in math mode everywhere.
+\end{command}
+
+\begin{command}{\setmathsfparsidigitfont\oarg{options}\marg{font name}}
+Chooses the Parsi font for digits in math mode inside |\mathsf| command. If you use |\setmathsfparsidigitfont| at least once, then in Parsi mode you get Parsi digits in math mode inside |\mathsf| and in Latin mode you get ``Latin Modern'' font and Latin digits in math mode inside |\mathsf|, otherwise you get ``Latin Modern'' fonts and Latin digits in math mode inside |\mathsf| everywhere.
+\end{command}
+
+\begin{command}{\setmathttparsidigitfont\oarg{options}\marg{font name}}
+Chooses the Parsi font for digits in math mode inside |\mathtt| command. If you use |\setmathttparsidigitfont| at least once, then in Parsi mode you get Parsi digits in math mode inside |\mathtt| and in Latin mode you get ``Latin Modern'' font and Latin digits in math mode inside |\mathtt|, otherwise you get ``Latin Modern'' fonts and Latin digits in math mode inside |\mathtt| everywhere.
+\end{command}
+
+
+\subsection{Paragraph Switching Commands}
+\begin{command}{\setLTRpar}
+Makes the direction of the paragraph left to right. The command does not change the current font.
+\end{command}
+
+\begin{command}{\setRTLpar}
+Makes the direction of the paragraph right to left. The command does not change the current font.
+\end{command}
+
+\subsection{Paragraph Switching Environments}
+\begin{environment}{{LTRpar}}
+Makes the direction of the paragraph left to right. The environment does not change the current font.
+\end{environment}
+
+\begin{environment}{{RTLpar}}
+Makes the direction of the paragraph right to left. The environment does not change the current font.
+\end{environment}
+
+\begin{environment}{{latinpar}}
+Makes the direction of the paragraph left to right. The environment changes the current font to Latin font.
+\end{environment}
+
+
+\begin{environment}{{parsipar}}
+Makes the direction of the paragraph right to left. The environment changes the current font to Parsi font.
+\end{environment}
+
+\subsection{Typesetting Short left to right and right to left Texts}
+\label{subsection:tslrrlt}
+\begin{command}{\textLRE\marg{text}}
+Typesets short left to right texts in right to left paragraphs. The command does not change the current font.
+\end{command}
+
+\begin{command}{\textRLE\marg{text}}
+Typesets short right to left texts in left to right paragraphs. The command does not change the current font.
+\end{command}
+
+\begin{command}{\textLatin\marg{text}}
+Typesets short left to right texts in right to left paragraphs. The command changes the curent font to Latin font.
+\end{command}
+
+\begin{command}{\textParsi\marg{text}}
+Typesets short right to left texts in left to right paragraphs. The command changes the current font to Parsi font.
+\end{command}
+Note that when \declare{unicode bidi} options of the package has any of the \opt{global} or \opt{local} values, then you rarely need to use any of the commands in \autoref{subsection:tslrrlt}.
+
+
+
+\subsection{Footnote Commands}
+\begin{command}{\footnote\oarg{num}\marg{text}}
+Typesets right to left footnote in right to left mode and left to right footnote in left to right mode.
+\end{command}
+
+\begin{command}{\thanks\marg{text}}
+Behaves like |\footnote| but only should be used inside |\title| and |\author| arguments.
+\end{command}
+
+\begin{command}{\footnotetext\oarg{num}\marg{text}}
+Used in conjuction with |\footnotemark|, behaves like |\footnote|.
+\end{command}
+
+\begin{command}{\LTRfootnote\oarg{num}\marg{text}}
+Always typesets left to right footnote independent on the current mode.
+\end{command}
+
+\begin{command}{\LTRthanks\marg{text}}
+Behaves like |\LTRfootnote| but only should be used inside |\title| and |\author| arguments.
+\end{command}
+
+\begin{command}{\LTRfootnotetext\oarg{num}\marg{text}}
+Used in conjuction with |\footnotemark|, behaves like |\LTRfootnote|.
+\end{command}
+
+
+\begin{command}{\RTLfootnote\oarg{num}\marg{text}}
+Always typesets right to left footnote independent on the current mode.
+\end{command}
+
+
+\begin{command}{\RTLthanks\marg{text}}
+Behaves like |\RTLfootnote| but only should be used inside |\title| and |\author| arguments.
+\end{command}
+
+\begin{command}{\RTLfootnotetext\oarg{num}\marg{text}}
+Used in conjuction with |\footnotemark|, behaves like |\RTLfootnote|.
+\end{command}
+
+\subsubsection{Footnote Rule Commands}
+The behaviour of the footnote rule can be controlled.
+
+\begin{command}{\autofootnoterule}
+Footnote rule is right or left aligned based on the direction of the first footnote following the rule (i.e. put in the current page).
+\end{command}
+
+\begin{command}{\rightfootnoterule}
+Footnote rule is always right aligned.
+\end{command}
+
+
+\begin{command}{\leftfootnoterule}
+Footnote rule is always left aligned.
+\end{command}
+
+\begin{command}{\textwidthfootnoterule}
+Full-width footnote rule.
+\end{command}
+
+
+\begin{command}{\SplitFootnoteRule}
+Puts a full-width rule above the split-off part of a split footnote.
+\end{command}
+
+\begin{command}{\debugfootnotedirection}
+Writes the direction of the first footnote on each page, to the terminal and the log file.
+\end{command}
+
+
+
+
+
+
+\section{License of the \textit{Package}}
+
+
+\subsection{The GNU General Public License, Version 2}
+\label{subsection:gpl}
+
+\subsubsection{Preamble}
+
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the \textsc{gnu} General Public License is intended to guarantee your freedom to share and change free software---to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the \textsc{gnu} Library General Public License instead.) You can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification follow.
+
+\subsubsection{Terms and Conditions For Copying, Distribution and Modification}
+
+\begin{enumerate}
+\addtocounter{enumi}{-1}
+\item
+ This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The ``Program'', below, refers to any such program or work, and a ``work based on the Program'' means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term ``modification''.) Each licensee is addressed as ``you''.
+
+ Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
+\item
+ You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
+
+ You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
+\item
+ You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
+ \begin{enumerate}
+ \item
+ You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
+ \item
+ You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
+ \item
+ If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
+ \end{enumerate}
+
+ These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
+
+ Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
+
+ In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+\item
+ You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
+ \begin{enumerate}
+ \item
+ Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+ \item
+ Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+ \item
+ Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsubsection b above.)
+ \end{enumerate}
+
+ The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
+
+ If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
+\item
+ You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
+\item
+ You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
+\item
+ Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
+\item
+ If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
+
+ If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
+
+ It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
+
+ This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+\item
+ If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+\item
+ The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and ``any later version'', you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
+\item
+ If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
+\end{enumerate}
+
+\subsubsection{No Warranty}
+
+\begin{enumerate}
+\addtocounter{enumi}{9}
+\item
+ Because the program is licensed free of charge, there is no warranty for the program, to the extent permitted by applicable law. Except when otherwise stated in writing the copyright holders and/or other parties provide the program ``as is'' without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the program is with you. Should the program prove defective, you assume the cost of all necessary servicing, repair or correction.
+\item
+ In no event unless required by applicable law or agreed to in writing will any copyright holder, or any other party who may modify and/or redistribute the program as permitted above, be liable to you for damages, including any general, special, incidental or consequential damages arising out of the use or inability to use the program (including but not limited to loss of data or data being rendered inaccurate or losses sustained by you or third parties or a failure of the program to operate with any other programs), even if such holder or other party has been advised of the possibility of such damages.
+\end{enumerate}
+
+
+
+\printindex
+
+
+
+
+
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/doc/simurgh-logo.pdf b/macros/luatex/latex/simurgh/doc/simurgh-logo.pdf
new file mode 100644
index 0000000000..b52b3e0e9a
--- /dev/null
+++ b/macros/luatex/latex/simurgh/doc/simurgh-logo.pdf
Binary files differ
diff --git a/macros/luatex/latex/simurgh/doc/simurgh-logo.tex b/macros/luatex/latex/simurgh/doc/simurgh-logo.tex
new file mode 100644
index 0000000000..78456669d3
--- /dev/null
+++ b/macros/luatex/latex/simurgh/doc/simurgh-logo.tex
@@ -0,0 +1,1483 @@
+\documentclass{minimal}
+\usepackage{pstricks}
+\begin{document}
+\psset{xunit=.5pt,yunit=.5pt,runit=.5pt}
+\begin{pspicture}(644,645)
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(336.4,15.6)
+\curveto(336.4,7.6)(329.9,1.201)(322,1.201)
+\curveto(314,1.201)(307.6,7.701)(307.6,15.6)
+\curveto(307.6,23.5)(314.1,30)(322,30)
+\curveto(329.9,30)(336.4,23.6)(336.4,15.6)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(368.4,18.8)
+\curveto(369.2,10.901)(363.5,3.8)(355.599,2.901)
+\curveto(347.7,2.1)(340.599,7.8)(339.7,15.701)
+\curveto(338.9,23.6)(344.599,30.701)(352.5,31.6)
+\curveto(360.5,32.5)(367.6,26.7)(368.4,18.8)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(400,25.3)
+\curveto(401.7,17.5)(396.7,9.8)(388.9,8.2)
+\curveto(381.099,6.5)(373.4,11.5)(371.799,19.3)
+\curveto(370.099,27.1)(375.099,34.8)(382.9,36.401)
+\curveto(390.6,38.1)(398.3,33.1)(400,25.3)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(430.7,35.1)
+\curveto(433.2,27.5)(429,19.401)(421.4,16.901)
+\curveto(413.799,14.401)(405.7,18.6)(403.2,26.201)
+\curveto(400.7,33.801)(404.9,41.901)(412.5,44.401)
+\curveto(420.1,46.901)(428.2,42.7)(430.7,35.1)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(460.2,48.1)
+\curveto(463.4,40.8)(460.2,32.3)(452.9,29)
+\curveto(445.599,25.8)(437.099,29)(433.799,36.3)
+\curveto(430.599,43.6)(433.799,52.1)(441.099,55.3)
+\curveto(448.4,58.6)(456.9,55.3)(460.2,48.1)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(488.2,64)
+\curveto(492.2,57.1)(489.8,48.3)(482.9,44.3)
+\curveto(476,40.3)(467.2,42.7)(463.2,49.6)
+\curveto(459.2,56.5)(461.599,65.3)(468.5,69.3)
+\curveto(475.401,73.3)(484.2,70.9)(488.2,64)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(514.3,82.8)
+\curveto(519,76.401)(517.6,67.3)(511.1,62.6)
+\curveto(504.6,57.901)(495.6,59.3)(490.901,65.8)
+\curveto(486.201,72.3)(487.701,81.3)(494.1,86)
+\curveto(500.6,90.7)(509.6,89.3)(514.3,82.8)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(538.4,104.2)
+\curveto(543.7,98.3)(543.299,89.099)(537.299,83.8)
+\curveto(531.4,78.5)(522.199,79)(516.9,84.901)
+\curveto(511.6,90.8)(512.1,100)(518,105.3)
+\curveto(523.9,110.7)(533.1,110.2)(538.4,104.2)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(560.1,128.1)
+\curveto(566,122.8)(566.5,113.6)(561.201,107.701)
+\curveto(555.901,101.801)(546.701,101.301)(540.801,106.6)
+\curveto(534.902,111.901)(534.402,121.1)(539.701,127)
+\curveto(545,132.9)(554.2,133.4)(560.1,128.1)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(579.2,154)
+\curveto(585.7,149.3)(587.099,140.3)(582.4,133.8)
+\curveto(577.7,127.3)(568.7,125.901)(562.2,130.6)
+\curveto(555.7,135.3)(554.3,144.3)(559,150.8)
+\curveto(563.7,157.3)(572.7,158.7)(579.2,154)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(595.4,181.8)
+\curveto(602.299,177.8)(604.7,169)(600.7,162.1)
+\curveto(596.7,155.201)(587.9,152.8)(581,156.8)
+\curveto(574.1,160.8)(571.7,169.6)(575.7,176.5)
+\curveto(579.7,183.5)(588.5,185.8)(595.4,181.8)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(608.7,211.2)
+\curveto(616,208)(619.3,199.4)(616,192.099)
+\curveto(612.8,184.799)(604.2,181.599)(596.9,184.799)
+\curveto(589.6,188)(586.3,196.6)(589.6,203.9)
+\curveto(592.9,211.2)(601.4,214.5)(608.7,211.2)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(618.8,241.8)
+\curveto(626.401,239.3)(630.5,231.2)(628.1,223.6)
+\curveto(625.6,216)(617.5,211.901)(609.901,214.3)
+\curveto(602.3,216.8)(598.201,224.901)(600.6,232.5)
+\curveto(603.1,240.1)(611.2,244.3)(618.8,241.8)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(625.7,273.3)
+\curveto(633.5,271.7)(638.5,264)(636.8,256.2)
+\curveto(635.2,248.4)(627.5,243.4)(619.7,245.099)
+\curveto(611.9,246.799)(606.9,254.4)(608.599,262.2)
+\curveto(610.2,270)(617.9,274.9)(625.7,273.3)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(629.2,305.3)
+\curveto(637.099,304.5)(642.9,297.401)(642,289.401)
+\curveto(641.2,281.501)(634.1,275.701)(626.1,276.6)
+\curveto(618.201,277.401)(612.401,284.5)(613.3,292.5)
+\curveto(614.2,300.4)(621.3,306.1)(629.2,305.3)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(629.4,337.5)
+\curveto(637.4,337.5)(643.9,331)(643.799,323.1)
+\curveto(643.799,315.1)(637.299,308.7)(629.4,308.7)
+\curveto(621.4,308.7)(615,315.2)(615,323.1)
+\curveto(615,331.1)(621.4,337.5)(629.4,337.5)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(626.2,369.6)
+\curveto(634.099,370.4)(641.2,364.7)(642.099,356.8)
+\curveto(642.9,348.9)(637.2,341.8)(629.299,340.9)
+\curveto(621.4,340.1)(614.299,345.8)(613.499,353.8)
+\curveto(612.5,361.7)(618.3,368.8)(626.2,369.6)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(619.7,401.1)
+\curveto(627.5,402.8)(635.2,397.8)(636.8,390)
+\curveto(638.5,382.2)(633.5,374.5)(625.7,372.9)
+\curveto(617.9,371.2)(610.2,376.2)(608.599,384)
+\curveto(606.9,391.8)(611.9,399.5)(619.7,401.1)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(609.9,431.8)
+\curveto(617.5,434.3)(625.599,430.1)(628.099,422.5)
+\curveto(630.599,414.9)(626.4,406.8)(618.799,404.3)
+\curveto(611.199,401.8)(603.099,406)(600.599,413.6)
+\curveto(598.099,421.2)(602.3,429.4)(609.9,431.8)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(596.9,461.4)
+\curveto(604.2,464.7)(612.7,461.4)(615.9,454.1)
+\curveto(619.2,446.8)(615.9,438.3)(608.599,435)
+\curveto(601.299,431.8)(592.799,435)(589.499,442.3)
+\curveto(586.4,449.6)(589.6,458.1)(596.9,461.4)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(581,489.3)
+\curveto(587.9,493.3)(596.7,490.9)(600.7,484)
+\curveto(604.7,477.1)(602.3,468.3)(595.4,464.3)
+\curveto(588.5,460.3)(579.7,462.7)(575.7,469.6)
+\curveto(571.7,476.5)(574.1,485.3)(581,489.3)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(562.2,515.5)
+\curveto(568.599,520.2)(577.7,518.8)(582.4,512.3)
+\curveto(587.099,505.9)(585.7,496.8)(579.2,492.1)
+\curveto(572.7,487.4)(563.7,488.9)(559,495.3)
+\curveto(554.3,501.8)(555.7,510.8)(562.2,515.5)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(540.8,539.6)
+\curveto(546.7,544.9)(555.901,544.5)(561.2,538.5)
+\curveto(566.5,532.6)(566.099,523.5)(560.099,518.1)
+\curveto(554.2,512.8)(544.999,513.3)(539.7,519.2)
+\curveto(534.3,525.1)(534.8,534.2)(540.8,539.6)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(516.9,561.3)
+\curveto(522.2,567.2)(531.4,567.7)(537.299,562.4)
+\curveto(543.199,557.1)(543.699,547.9)(538.4,542)
+\curveto(533.099,536.1)(523.9,535.6)(518,540.9)
+\curveto(512.1,546.2)(511.6,555.3)(516.9,561.3)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(491,580.3)
+\curveto(495.7,586.8)(504.7,588.2)(511.2,583.5)
+\curveto(517.7,578.8)(519.099,569.8)(514.4,563.3)
+\curveto(509.7,556.9)(500.7,555.4)(494.2,560.1)
+\curveto(487.7,564.9)(486.3,573.9)(491,580.3)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(463.1,596.6)
+\curveto(467.1,603.5)(475.901,605.9)(482.8,601.9)
+\curveto(489.7,597.9)(492.1,589.1)(488.1,582.2)
+\curveto(484.1,575.3)(475.3,572.9)(468.401,576.9)
+\curveto(461.5,580.9)(459.2,589.7)(463.1,596.6)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(433.8,609.9)
+\curveto(437,617.2)(445.6,620.5)(452.901,617.2)
+\curveto(460.201,614)(463.501,605.4)(460.201,598.1)
+\curveto(457.001,590.8)(448.401,587.6)(441.1,590.8)
+\curveto(433.8,594)(430.5,602.6)(433.8,609.9)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(403.2,620)
+\curveto(405.7,627.6)(413.8,631.7)(421.4,629.3)
+\curveto(429,626.8)(433.099,618.7)(430.7,611.1)
+\curveto(428.2,603.5)(420.099,599.4)(412.5,601.8)
+\curveto(404.9,604.3)(400.7,612.4)(403.2,620)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(371.7,626.9)
+\curveto(373.3,634.7)(381,639.7)(388.8,638)
+\curveto(396.6,636.3)(401.6,628.7)(399.901,620.9)
+\curveto(398.201,613.1)(390.6,608.1)(382.8,609.8)
+\curveto(375,611.4)(370.1,619)(371.7,626.9)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(339.7,630.4)
+\curveto(340.5,638.3)(347.6,644.1)(355.6,643.2)
+\curveto(363.5,642.4)(369.3,635.3)(368.5,627.3)
+\curveto(367.7,619.4)(360.5,613.6)(352.6,614.5)
+\curveto(344.6,615.4)(338.8,622.5)(339.7,630.4)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(307.5,630.6)
+\curveto(307.5,638.6)(314,645)(321.9,645)
+\curveto(329.9,645)(336.299,638.5)(336.299,630.6)
+\curveto(336.299,622.6)(329.799,616.2)(321.9,616.2)
+\curveto(313.9,616.1)(307.5,622.6)(307.5,630.6)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(275.4,627.4)
+\curveto(274.5,635.3)(280.3,642.4)(288.2,643.3)
+\curveto(296.1,644.1)(303.2,638.4)(304.1,630.5)
+\curveto(304.9,622.6)(299.2,615.5)(291.2,614.7)
+\curveto(283.3,613.7)(276.2,619.4)(275.4,627.4)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(243.9,620.8)
+\curveto(242.2,628.7)(247.2,636.3)(255,638)
+\curveto(262.8,639.7)(270.5,634.7)(272.1,626.9)
+\curveto(273.8,619.1)(268.8,611.4)(261,609.8)
+\curveto(253.2,608.1)(245.5,613)(243.9,620.8)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(213.2,611.1)
+\curveto(210.7,618.7)(214.9,626.8)(222.5,629.3)
+\curveto(230.1,631.8)(238.2,627.6)(240.7,620)
+\curveto(243.2,612.4)(239,604.3)(231.4,601.8)
+\curveto(223.8,599.3)(215.6,603.5)(213.2,611.1)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(183.6,598.1)
+\curveto(180.3,605.4)(183.6,613.9)(190.9,617.2)
+\curveto(198.2,620.4)(206.7,617.2)(210,609.9)
+\curveto(213.2,602.6)(209.9,594.1)(202.7,590.9)
+\curveto(195.4,587.5)(186.9,590.8)(183.6,598.1)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(155.7,582.2)
+\curveto(151.7,589.1)(154.1,597.9)(161,601.9)
+\curveto(167.9,605.9)(176.7,603.5)(180.7,596.6)
+\curveto(184.7,589.7)(182.3,580.9)(175.4,576.9)
+\curveto(168.5,572.9)(159.7,575.2)(155.7,582.2)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(129.5,563.4)
+\curveto(124.8,569.8)(126.3,578.9)(132.7,583.6)
+\curveto(139.2,588.3)(148.2,586.9)(152.9,580.4)
+\curveto(157.6,574)(156.1,564.9)(149.7,560.2)
+\curveto(143.2,555.5)(134.2,556.9)(129.5,563.4)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(105.4,541.9)
+\curveto(100,547.8)(100.6,557)(106.5,562.3)
+\curveto(112.4,567.6)(121.5,567.2)(126.9,561.2)
+\curveto(132.2,555.3)(131.7,546.1)(125.8,540.8)
+\curveto(119.9,535.5)(110.8,536)(105.4,541.9)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(83.7,518.1)
+\curveto(77.7,523.4)(77.3,532.6)(82.6,538.5)
+\curveto(87.9,544.4)(97,544.9)(103,539.6)
+\curveto(108.9,534.3)(109.4,525.1)(104,519.2)
+\curveto(98.8,513.2)(89.7,512.8)(83.7,518.1)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(64.7,492.1)
+\curveto(58.2,496.8)(56.8,505.8)(61.5,512.3)
+\curveto(66.2,518.8)(75.2,520.2)(81.7,515.5)
+\curveto(88.1,510.8)(89.6,501.8)(84.9,495.3)
+\curveto(80.1,488.9)(71.1,487.4)(64.7,492.1)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(48.4,464.3)
+\curveto(41.5,468.3)(39.1,477.1)(43.1,484)
+\curveto(47.1,490.9)(55.9,493.3)(62.8,489.3)
+\curveto(69.7,485.3)(72.1,476.5)(68,469.6)
+\curveto(64.1,462.7)(55.3,460.3)(48.4,464.3)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(35.1,435)
+\curveto(27.8,438.2)(24.5,446.8)(27.8,454.1)
+\curveto(31,461.4)(39.6,464.7)(46.9,461.4)
+\curveto(54.2,458.2)(57.4,449.6)(54.2,442.3)
+\curveto(51,435)(42.4,431.7)(35.1,435)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(25,404.4)
+\curveto(17.4,406.8)(13.3,415)(15.8,422.6)
+\curveto(18.3,430.2)(26.4,434.3)(34,431.9)
+\curveto(41.6,429.4)(45.7,421.3)(43.2,413.7)
+\curveto(40.8,406.1)(32.6,401.9)(25,404.4)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(18.1,372.9)
+\curveto(10.3,374.5)(5.4,382.2)(7,390)
+\curveto(8.6,397.8)(16.3,402.8)(24.1,401.1)
+\curveto(31.9,399.4)(36.9,391.8)(35.2,384)
+\curveto(33.6,376.2)(26,371.2)(18.1,372.9)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(14.6,340.9)
+\curveto(6.7,341.7)(0.9,348.8)(1.8,356.8)
+\curveto(2.6,364.7)(9.7,370.5)(17.7,369.7)
+\curveto(25.6,368.9)(31.4,361.7)(30.5,353.8)
+\curveto(29.6,345.8)(22.5,340)(14.6,340.9)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(14.4,308.6)
+\curveto(6.4,308.6)(0,315.1)(0,323)
+\curveto(0,331)(6.5,337.4)(14.5,337.4)
+\curveto(22.4,337.4)(28.9,330.9)(28.9,322.9)
+\curveto(28.9,315.1)(22.4,308.6)(14.4,308.6)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(17.6,276.6)
+\curveto(9.7,275.701)(2.6,281.5)(1.7,289.401)
+\curveto(0.9,297.3)(6.6,304.401)(14.6,305.3)
+\curveto(22.5,306.1)(29.6,300.401)(30.4,292.401)
+\curveto(31.3,284.5)(25.6,277.4)(17.6,276.6)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(24.1,245)
+\curveto(16.3,243.3)(8.6,248.3)(7,256.1)
+\curveto(5.3,263.901)(10.3,271.5)(18.1,273.201)
+\curveto(25.9,274.801)(33.6,269.901)(35.2,262.1)
+\curveto(36.9,254.4)(32,246.7)(24.1,245)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(33.9,214.3)
+\curveto(26.3,211.8)(18.2,216)(15.7,223.6)
+\curveto(13.2,231.201)(17.4,239.3)(25,241.8)
+\curveto(32.6,244.3)(40.7,240.1)(43.2,232.5)
+\curveto(45.7,224.9)(41.5,216.8)(33.9,214.3)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(46.9,184.8)
+\curveto(39.6,181.5)(31.1,184.8)(27.8,192.1)
+\curveto(24.5,199.401)(27.8,207.901)(35.1,211.201)
+\curveto(42.4,214.401)(50.9,211.1)(54.1,203.801)
+\curveto(57.5,196.6)(54.2,188.1)(46.9,184.8)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(62.8,156.8)
+\curveto(55.9,152.8)(47.1,155.2)(43.1,162.1)
+\curveto(39.1,169)(41.5,177.8)(48.4,181.8)
+\curveto(55.3,185.8)(64.1,183.401)(68.1,176.5)
+\curveto(72.1,169.7)(69.8,160.8)(62.8,156.8)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(81.6,130.7)
+\curveto(75.2,126)(66.1,127.4)(61.5,133.9)
+\curveto(56.8,140.299)(58.2,149.4)(64.7,154.099)
+\curveto(71.1,158.799)(80.2,157.299)(84.8,150.9)
+\curveto(89.5,144.4)(88.1,135.4)(81.6,130.7)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(103.1,106.6)
+\curveto(97.2,101.2)(88,101.7)(82.7,107.7)
+\curveto(77.4,113.599)(77.8,122.7)(83.8,128.099)
+\curveto(89.7,133.4)(98.9,132.9)(104.2,126.999)
+\curveto(109.5,121.1)(109,111.9)(103.1,106.6)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(126.9,84.9)
+\curveto(121.6,79)(112.4,78.5)(106.5,83.799)
+\curveto(100.6,89.098)(100.1,98.199)(105.4,104.199)
+\curveto(110.7,110.098)(119.9,110.598)(125.8,105.199)
+\curveto(131.8,100)(132.2,90.8)(126.9,84.9)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(152.9,65.8)
+\curveto(148.2,59.3)(139.2,57.901)(132.7,62.6)
+\curveto(126.2,67.3)(124.8,76.3)(129.5,82.8)
+\curveto(134.2,89.2)(143.2,90.7)(149.7,86)
+\curveto(156.1,81.3)(157.6,72.3)(152.9,65.8)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(180.7,49.6)
+\curveto(176.7,42.701)(167.9,40.3)(161,44.3)
+\curveto(154.1,48.3)(151.7,57.1)(155.7,64)
+\curveto(159.7,70.9)(168.5,73.2)(175.4,69.2)
+\curveto(182.3,65.3)(184.7,56.5)(180.7,49.6)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(210,36.3)
+\curveto(206.8,29)(198.2,25.7)(190.9,29)
+\curveto(183.6,32.2)(180.3,40.8)(183.6,48.1)
+\curveto(186.8,55.401)(195.4,58.6)(202.7,55.401)
+\curveto(210,52.1)(213.3,43.6)(210,36.3)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(240.6,26.2)
+\curveto(238.2,18.599)(230,14.5)(222.4,16.9)
+\curveto(214.8,19.4)(210.7,27.5)(213.1,35.099)
+\curveto(215.6,42.7)(223.7,46.799)(231.3,44.299)
+\curveto(238.9,41.9)(243.1,33.8)(240.6,26.2)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(272.1,19.3)
+\curveto(270.5,11.5)(262.8,6.5)(255,8.2)
+\curveto(247.2,9.8)(242.2,17.5)(243.9,25.3)
+\curveto(245.6,33.1)(253.2,38.1)(261,36.401)
+\curveto(268.8,34.8)(273.8,27.1)(272.1,19.3)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.7764706 0.78431374 0.79215688}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(304.1,15.8)
+\curveto(303.3,7.901)(296.2,2.1)(288.2,3)
+\curveto(280.3,3.8)(274.5,10.9)(275.3,18.9)
+\curveto(276.1,26.799)(283.3,32.599)(291.2,31.7)
+\curveto(299.2,30.8)(305,23.7)(304.1,15.8)
+\closepath
+}
+}
+{
+\newrgbcolor{curcolor}{0.60784316 0.50588238 0.34117648}
+\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]
+{
+\newpath
+\moveto(291.4,500.2)
+\curveto(301.1,484.1)(307,462.5)(307,439.8)
+\curveto(307,435.5)(306.8,431.2)(306.3,426.9)
+\curveto(314.6,418.4)(321.3,409.1)(326,401.8)
+\curveto(327.6,410.1)(328.4,418.8)(328.4,427.4)
+\curveto(328.4,463.9)(314.9,501.1)(293.6,519.1)
+\curveto(284,522)(276.8,520.1)(274.4,519.3)
+\curveto(280.9,514.7)(286.6,508.1)(291.4,500.2)
+\closepath
+\moveto(302.4,527.6)
+\curveto(319.6,526.4)(337.6,516.9)(351.3,499.5)
+\curveto(365,482.1)(374.5,457.9)(374.5,430.5)
+\curveto(374.5,400.5)(363.1,368.7)(333.6,336.2)
+\curveto(340,335.8)(346.1,333.4)(350.5,329.8)
+\curveto(351.6,330)(352.7,330.1)(353.8,330.1)
+\lineto(354.5,330.1)
+\curveto(383.3,356.7)(394.6,389.2)(394.6,420.6)
+\curveto(394.6,450)(384.6,478.3)(369.5,499.2)
+\curveto(354.5,520.1)(334.6,533.4)(315.1,533.3)
+\curveto(308.3,533.3)(295.201,530)(288.6,526.5)
+\curveto(289.1,526.4)(294.5,528.1)(302.4,527.6)
+\closepath
+\moveto(372.7,501.3)
+\curveto(388.2,479.8)(398.4,450.8)(398.5,420.6)
+\curveto(398.5,389.2)(387.4,356.4)(359.4,329.5)
+\curveto(365.4,328.2)(370.7,325)(373.9,320.8)
+\curveto(374.299,320.2)(374.7,319.6)(375,319)
+\curveto(407,346.7)(419.5,380.5)(419.5,413.6)
+\curveto(419.5,446.6)(406.9,478.8)(388.4,502.7)
+\curveto(370,526.6)(345.8,542)(323,541.9)
+\curveto(312.4,541.9)(301.9,538.6)(292.3,531.1)
+\curveto(299.7,535.1)(307.401,537)(315.1,537)
+\curveto(336.4,536.9)(357.2,522.7)(372.7,501.3)
+\closepath
+\moveto(282.7,533.4)
+\curveto(277,534)(271.1,533.9)(265.2,533)
+\curveto(270.2,533)(275,532.1)(279.6,530.4)
+\curveto(280.5,531.4)(281.5,532.5)(282.7,533.4)
+\closepath
+\moveto(258.7,497.6)
+\curveto(264.6,487.7)(268.1,475)(268.1,463)
+\curveto(268.1,459.9)(267.9,456.8)(267.4,453.9)
+\curveto(272.3,451.7)(277.8,448.9)(283.8,445.1)
+\curveto(284,447.5)(284.1,449.9)(284.1,452.4)
+\curveto(284.1,468)(279.8,484.7)(272.5,497.4)
+\curveto(265.2,510.2)(255.1,518.7)(243.7,518.7)
+\curveto(238.8,518.7)(233.6,517.1)(228.1,513.6)
+\curveto(230.3,514.3)(232.5,514.6)(234.6,514.6)
+\curveto(244.5,514.6)(252.9,507.5)(258.7,497.6)
+\closepath
+\moveto(274.7,498.6)
+\curveto(282.2,485.4)(286.6,468.4)(286.6,452.4)
+\curveto(286.6,449.4)(286.4,446.5)(286.1,443.6)
+\curveto(289.6,441.3)(293.3,438.6)(297.1,435.6)
+\curveto(299.6,433.6)(301.9,431.5)(304.1,429.3)
+\curveto(304.4,432.8)(304.6,436.4)(304.6,439.9)
+\curveto(304.6,462.1)(298.8,483.4)(289.3,499)
+\curveto(279.8,514.6)(266.9,524.5)(252.7,524.5)
+\curveto(247.3,524.5)(241.6,523.1)(235.8,519.9)
+\curveto(238.5,520.7)(241.2,521.1)(243.8,521.1)
+\curveto(256.5,521.1)(267.2,511.7)(274.7,498.6)
+\closepath
+\moveto(247.5,460.9)
+\curveto(251.3,459.7)(257.4,458.1)(265,454.9)
+\curveto(265.4,457.5)(265.6,460.2)(265.6,463)
+\curveto(265.6,474.5)(262.2,486.9)(256.6,496.4)
+\curveto(251,505.9)(243.2,512.2)(234.6,512.1)
+\curveto(229.7,512.1)(224.3,510.1)(218.6,505.1)
+\curveto(235.7,512.7)(255.7,492)(247.5,460.9)
+\closepath
+\moveto(273.9,519.8)
+\curveto(274.4,521.3)(275.6,524.8)(278,528.3)
+\curveto(273.9,529.7)(269.6,530.5)(265.1,530.5)
+\curveto(259.2,530.5)(253,529.2)(246.5,526.3)
+\curveto(248.6,526.7)(250.7,526.9)(252.7,526.9)
+\curveto(260.3,526.9)(267.4,524.3)(273.9,519.8)
+\closepath
+\moveto(428.7,500)
+\curveto(430.9,497.5)(432.599,495.4)(434.599,492.7)
+\curveto(435.499,495.7)(437.499,498.8)(437.499,501.7)
+\curveto(441.499,499.1)(448.099,497.9)(451.699,493.7)
+\lineto(451.899,493.7)
+\curveto(458.999,503.7)(476.699,494.6)(472.899,484.5)
+\lineto(471.699,482.3)
+\curveto(469.699,479.4)(467.199,478.3)(464.899,478.2)
+\curveto(461.798,478.3)(459.298,480.2)(459.298,483.7)
+\curveto(459.298,485.2)(459.798,486.5)(460.399,487.5)
+\curveto(461.098,488.4)(461.899,488.9)(462.598,488.9)
+\curveto(463.199,488.9)(463.798,488.7)(464.498,487.9)
+\curveto(465.298,487.1)(465.498,486.5)(465.498,486.1)
+\curveto(465.498,485.7)(465.298,485.2)(464.898,484.9)
+\curveto(464.498,484.6)(463.998,484.4)(463.797,484.4)
+\lineto(463.697,484.4)
+\curveto(463.096,484.2)(462.297,484.5)(461.997,483.9)
+\curveto(461.697,483.3)(461.897,482.5)(462.497,482.2)
+\lineto(462.497,482.2)
+\curveto(462.897,482)(463.297,481.9)(463.697,481.9)
+\curveto(465.596,482)(467.797,483.5)(467.897,486.1)
+\curveto(467.897,487.3)(467.296,488.5)(466.197,489.6)
+\curveto(465.096,490.7)(463.797,491.3)(462.497,491.3)
+\curveto(458.997,491.2)(456.697,487.6)(456.697,483.7)
+\curveto(456.697,481.3)(457.596,479.2)(459.197,477.8)
+\curveto(460.697,476.4)(462.697,475.7)(464.897,475.7)
+\lineto(464.897,475.7)
+\curveto(467.596,475.7)(470.497,477)(472.796,479.6)
+\curveto(484.496,464.8)(484.096,446.4)(479.897,438.1)
+\curveto(527.7,488.7)(462.8,525.4)(428.7,500)
+\closepath
+\moveto(422.2,266.6)
+\curveto(441,286.901)(460.2,314.6)(465.5,356.201)
+\curveto(466.4,363.401)(466.8,370.401)(466.8,377.401)
+\curveto(466.8,386.501)(466.1,395.401)(464.7,404.101)
+\lineto(464.7,401.101)
+\curveto(464.7,354.901)(443.599,311.801)(407.599,284.101)
+\lineto(407.599,282.902)
+\curveto(407.599,282.202)(407.599,281.502)(407.499,280.902)
+\curveto(412.299,276.601)(415.799,269.801)(415.799,261.702)
+\curveto(415.799,261.101)(415.799,260.502)(415.699,259.902)
+\curveto(417.9,262)(420,264.2)(422.2,266.6)
+\closepath
+\moveto(442.8,496)
+\curveto(441.7,496.6)(440.5,497)(439.3,497.6)
+\curveto(439,496.1)(438.6,495.6)(438.1,494.1)
+\curveto(437.6,492.8)(437.201,491.3)(436.901,490.1)
+\curveto(439.8,486.5)(441.701,483.8)(443.3,481.3)
+\curveto(444,480)(446.7,474.8)(449.8,468.9)
+\curveto(453.3,462.1)(457.3,454.3)(458.901,450.6)
+\curveto(459.1,450.1)(459.6,449.9)(460.001,449.9)
+\curveto(460.201,449.9)(460.301,449.9)(460.501,450)
+\curveto(461.101,450.3)(461.401,451)(461.101,451.6)
+\curveto(458.501,457.6)(450.402,473.1)(446.902,479.7)
+\curveto(447.002,484.2)(448.002,488.2)(449.601,491.4)
+\curveto(447.7,493.3)(445.3,494.8)(442.8,496)
+\closepath
+\moveto(412.1,505.1)
+\curveto(432.1,480.1)(446.5,447.4)(446.5,412)
+\curveto(446.5,376.4)(431.8,338.2)(393.9,302.9)
+\curveto(394.099,302.4)(394.2,302)(394.4,301.5)
+\curveto(399,299.8)(402.299,296.9)(404.4,293.8)
+\curveto(405.7,291.901)(406.5,289.901)(407,288.1)
+\curveto(443,314.8)(461.1,355.3)(461.1,401.201)
+\curveto(461.1,411.501)(460,421.901)(457.8,432.301)
+\curveto(449.3,457.501)(435.5,479.901)(419,498.101)
+\curveto(416.7,500.5)(414.4,502.8)(412.1,505.1)
+\closepath
+\moveto(468.7,321.6)
+\curveto(467.9,321.6)(467.099,321.6)(466.3,321.701)
+\curveto(463.8,314.401)(460.8,307.501)(457.5,301.201)
+\curveto(473.7,307.1)(489.7,314.001)(500.3,327.301)
+\curveto(520.2,352.201)(520.8,405.201)(472.901,407.401)
+\curveto(473.6,403.401)(474.1,399.401)(474.501,395.301)
+\lineto(474.501,395.301)
+\curveto(474.501,395.301)(475.101,390.601)(475.201,387.201)
+\curveto(476.701,384.301)(477.301,381.701)(477.301,379.301)
+\curveto(477.301,376.301)(476.301,373.501)(474.701,370.901)
+\lineto(474.701,366.701)
+\curveto(477.6,370.301)(479.801,374.401)(479.801,379.301)
+\curveto(479.801,382.401)(478.501,386.201)(476.402,389.801)
+\curveto(476.402,389.801)(476.301,390.101)(476.502,390.401)
+\curveto(481.202,396.101)(486.302,398.301)(494.002,398.001)
+\curveto(495.902,394.801)(496.002,387.401)(495.902,382.801)
+\curveto(486.301,379.201)(483.702,371.901)(483.801,364.601)
+\curveto(483.801,357.801)(485.701,350.701)(485.701,344.901)
+\curveto(485.701,341.301)(485.001,338.401)(483.001,336.401)
+\curveto(482.501,335.901)(482.501,335.101)(483.001,334.701)
+\curveto(483.201,334.501)(483.601,334.301)(483.901,334.301)
+\curveto(484.201,334.301)(484.501,334.401)(484.8,334.701)
+\curveto(487.5,337.401)(488.3,341.101)(488.3,344.901)
+\curveto(488.3,351.101)(486.401,358.201)(486.401,364.601)
+\curveto(486.501,371.801)(487.501,377.901)(497.1,381.201)
+\curveto(497.3,381.301)(498.701,381.301)(499.1,381.301)
+\curveto(505.6,381.101)(510.901,374.201)(510.901,374.201)
+\curveto(492.2,375.9)(515.8,321.6)(468.7,321.6)
+\closepath
+\moveto(200.6,450.7)
+\lineto(200.6,448.7)
+\lineto(200.6,448.5)
+\lineto(200.6,448.3)
+\curveto(200.6,448.2)(200.5,447.7)(200.3,446.9)
+\curveto(205.2,447.9)(210.7,448.4)(216.8,448.4)
+\curveto(249.8,448.4)(297.4,431.9)(320.5,377.2)
+\curveto(323.1,380.4)(325.6,383.6)(327.9,387)
+\curveto(327.799,387.1)(327.7,387.2)(327.599,387.3)
+\curveto(323.7,394.3)(310.9,416.4)(293.299,430.6)
+\curveto(283.399,438.6)(274.399,443.8)(266.799,447.3)
+\curveto(244.899,456.8)(221.599,459.5)(200.099,458.5)
+\curveto(200.6,456)(200.6,453.5)(200.6,450.7)
+\closepath
+\moveto(391.4,504.8)
+\curveto(410.299,480.3)(423.2,447.4)(423.2,413.5)
+\curveto(423.2,380)(410.5,345.4)(378.7,317.2)
+\curveto(382.3,316)(385.5,313.8)(388,311.4)
+\curveto(389.6,309.799)(391,308.099)(392.1,306.299)
+\curveto(428.8,340.799)(442.701,377.599)(442.701,411.899)
+\curveto(442.701,449.199)(426.201,483.599)(404.001,508.799)
+\curveto(397.901,515.699)(391.401,521.899)(384.701,527.199)
+\curveto(365.401,539.699)(345.301,546.699)(327.901,546.699)
+\curveto(320.501,546.699)(313.701,545.499)(307.401,542.999)
+\curveto(312.501,544.599)(317.8,545.399)(323.1,545.399)
+\curveto(347.6,545.5)(372.5,529.3)(391.4,504.8)
+\closepath
+\moveto(287.4,329.7)
+\curveto(289.7,330.4)(291.9,330.8)(294.1,330.8)
+\curveto(295,330.8)(295.9,330.7)(296.7,330.6)
+\curveto(298.3,332.3)(300.4,333.5)(302.5,334.4)
+\curveto(305.8,335.7)(309.5,336.4)(313.2,336.4)
+\curveto(316.7,336.3)(320.099,335.9)(323.099,334.3)
+\curveto(325.599,335.5)(328.299,336.1)(330.999,336.3)
+\curveto(359.999,368.6)(370.899,401.5)(370.899,430.6)
+\curveto(370.899,457.2)(361.699,480.6)(348.499,497.3)
+\curveto(337.699,511)(318.899,524)(301.599,524.2)
+\curveto(309.899,521.3)(319.799,519.9)(333.699,500.8)
+\curveto(345.598,484.3)(354.699,460.9)(354.699,438.2)
+\curveto(354.699,428.8)(353.098,419.2)(349.598,409.8)
+\curveto(339.699,383.7)(322.899,365.9)(305.898,348.7)
+\curveto(299.6,342.4)(293.4,336.2)(287.4,329.7)
+\closepath
+\moveto(343.5,419.6)
+\curveto(352.3,470.2)(320.7,503.9)(303.8,514.5)
+\curveto(302.5,515.3)(301.2,516)(299.9,516.7)
+\curveto(319.2,496.8)(330.8,461.9)(330.9,427.5)
+\curveto(330.9,417.8)(330,408.1)(328,398.8)
+\curveto(329.4,396.5)(330.6,394.5)(331.5,392.9)
+\curveto(335.3,399)(338.6,405.6)(341.3,412.8)
+\curveto(342.2,415)(342.9,417.3)(343.5,419.6)
+\closepath
+\moveto(259.7,291.3)
+\lineto(259.7,291.3)
+\lineto(259.7,291.3)
+\lineto(259.7,291.3)
+\closepath
+\moveto(396,240.9)
+\curveto(398.4,243.2)(399.1,244.5)(401.9,247.599)
+\lineto(403.799,250.4)
+\lineto(404.299,251.4)
+\curveto(406.4,255.099)(407.099,258.5)(407.099,261.7)
+\curveto(407.2,268.099)(403.599,273.4)(400.299,275.5)
+\lineto(397.199,277.5)
+\lineto(398.699,280.9)
+\lineto(398.699,281)
+\curveto(398.699,281.1)(398.799,281.2)(398.799,281.4)
+\curveto(398.9,281.799)(398.9,282.299)(398.9,282.9)
+\curveto(398.9,284.7)(398.4,287)(397.099,289)
+\curveto(395.7,291)(393.599,292.9)(389.4,294)
+\lineto(386.2,294.8)
+\lineto(386.2,298.1)
+\curveto(386.3,299.1)(384.9,302.6)(382.099,305.1)
+\curveto(379.299,307.8)(375.7,309.6)(372.099,309.6)
+\lineto(367.799,309.6)
+\lineto(367.799,314)
+\curveto(367.799,314)(367.699,314.6)(367.099,315.4)
+\curveto(366.499,316.2)(365.4,317.299)(363.999,318.2)
+\curveto(361.199,320)(357.299,321.4)(353.999,321.4)
+\curveto(352.799,321.4)(351.699,321.2)(350.699,320.9)
+\lineto(348.199,320.099)
+\lineto(346.399,321.9)
+\curveto(343.598,324.799)(337.598,327.5)(332.399,327.5)
+\curveto(329.699,327.5)(327.298,326.9)(325.399,325.5)
+\lineto(322.399,323.4)
+\lineto(319.8,326)
+\curveto(319.3,326.7)(316.5,327.7)(313.2,327.7)
+\curveto(310.599,327.7)(307.8,327.2)(305.8,326.4)
+\curveto(303.7,325.6)(302.7,324.4)(302.7,324.2)
+\lineto(301.1,320.099)
+\lineto(297,321.7)
+\curveto(296.3,322)(295.3,322.2)(294.1,322.2)
+\curveto(290.2,322.2)(285.1,320.2)(282.4,315.2)
+\lineto(281.2,313)
+\lineto(273.4,313)
+\curveto(268.4,306.4)(263.8,299.2)(259.8,291.3)
+\lineto(259.8,291.3)
+\lineto(259.8,291.3)
+\curveto(259.8,291.3)(258,288.8)(255.8,283.901)
+\curveto(266.3,301.001)(284,315.201)(311.6,315.3)
+\curveto(320.401,315.3)(330.1,313.901)(340.901,310.6)
+\curveto(374.8,300.5)(383.501,280.8)(383.501,262)
+\curveto(383.501,244.3)(376.001,227.3)(375.201,219.6)
+\curveto(375.1,218.6)(375.001,217.701)(375.001,216.8)
+\curveto(375.001,206.401)(381.601,201.6)(387.701,201.6)
+\curveto(391.701,201.6)(395.401,203.6)(397.301,207.5)
+\curveto(397.101,207.3)(396.902,207.2)(396.701,207)
+\curveto(395.1,205.9)(393.201,205.4)(391.201,205.4)
+\curveto(389.001,205.4)(386.501,206.099)(384.6,207.9)
+\curveto(382.6,209.7)(379.401,213.799)(380.701,220.599)
+\curveto(382,227.3)(388.6,233.7)(396,240.9)
+\closepath
+\moveto(214.3,227)
+\curveto(219.4,223.4)(225.2,220.3)(230.1,219.2)
+\curveto(223.6,228.599)(218.3,240.2)(215.7,254.3)
+\curveto(213.2,255)(210.9,255.5)(208.9,255.901)
+\curveto(208.8,256.001)(208.6,256.201)(208.5,256.3)
+\curveto(208.6,255.7)(208.6,255.1)(208.6,254.5)
+\curveto(208.6,250.2)(207,243.5)(201.1,239.5)
+\curveto(202.8,236.7)(208.1,231.4)(214.3,227)
+\closepath
+\moveto(261.2,156.2)
+\curveto(269.1,159.8)(269.7,169.599)(269.7,174)
+\curveto(269.7,175.7)(268.6,178.1)(266.6,180)
+\curveto(265.3,181.3)(263.6,182.4)(261.8,183)
+\curveto(260,183.2)(258.2,183.5)(256.5,183.9)
+\curveto(254.4,184.4)(252.5,184.599)(250.7,184.599)
+\curveto(242.7,184.599)(238.1,179.7)(233.1,174.999)
+\curveto(232.6,173.399)(232.2,171.399)(232.2,169.199)
+\curveto(232.2,165.098)(233.3,160.499)(236,156.999)
+\curveto(238.1,154.399)(241,152.299)(245.2,151.399)
+\curveto(248.8,150.999)(255.6,152.699)(261.2,155.899)
+\lineto(261.2,156.2)
+\closepath
+\moveto(234.1,155.6)
+\curveto(230.9,159.701)(229.7,164.8)(229.7,169.3)
+\curveto(229.7,170.3)(229.8,171.3)(229.9,172.2)
+\curveto(226.3,169.099)(222.2,166.5)(216.3,166)
+\curveto(213.3,165.8)(210.2,165.7)(207.1,165.7)
+\curveto(204.5,165.7)(201.9,165.7)(199.3,165.8)
+\curveto(196.7,165.8)(194.2,165.901)(191.7,165.901)
+\curveto(178.1,165.901)(166.8,164.401)(166.7,153.501)
+\curveto(166.8,148.501)(169.1,141.601)(174.5,132.101)
+\curveto(174.5,132.101)(175.3,130.801)(176.8,128.902)
+\curveto(175.4,132.301)(174.6,135.801)(174.6,139.402)
+\curveto(174.6,142.902)(175.4,146.402)(177.2,149.502)
+\curveto(178.7,152.102)(181.1,153.702)(183.8,154.502)
+\curveto(186.5,155.302)(189.4,155.502)(192.5,155.502)
+\curveto(196.5,155.502)(200.7,155.202)(204.7,155.202)
+\curveto(210.8,155.202)(216.2,156.002)(219.5,159.402)
+\lineto(219.5,159.402)
+\curveto(220.2,160.101)(221.4,160.101)(222.1,159.402)
+\curveto(222.8,158.702)(222.8,157.502)(222.1,156.801)
+\curveto(217.5,152.201)(211,151.501)(204.6,151.501)
+\curveto(200.4,151.501)(196.2,151.901)(192.4,151.801)
+\curveto(189.5,151.801)(186.8,151.601)(184.8,150.902)
+\curveto(182.7,150.202)(181.3,149.301)(180.3,147.601)
+\curveto(178.9,145.202)(178.2,142.402)(178.2,139.402)
+\curveto(178.2,134.402)(180.1,129.002)(183.2,124.702)
+\curveto(186.3,120.402)(190.4,117.502)(194.7,116.902)
+\curveto(195.6,116.801)(196.5,116.702)(197.2,116.702)
+\curveto(201.8,116.802)(204,118.502)(205.7,121.402)
+\curveto(207.4,124.301)(208.1,128.601)(208.7,132.702)
+\curveto(208.8,133.202)(209.1,133.702)(209.6,134.002)
+\curveto(220.6,140.802)(221.6,145.802)(224.9,149.102)
+\curveto(225.6,149.802)(226.8,149.802)(227.5,149.102)
+\curveto(228.2,148.403)(228.2,147.203)(227.5,146.502)
+\curveto(225.4,144.502)(223.2,138.202)(212.3,131.302)
+\curveto(211.7,127.302)(211,123.102)(209,119.502)
+\curveto(207.2,116.202)(204.1,113.602)(199.5,113.002)
+\curveto(203.2,112.102)(207.2,111.902)(211.5,112.602)
+\curveto(228.1,120.302)(238.5,140.002)(242.8,149.403)
+\curveto(239.1,150.8)(236.1,153)(234.1,155.6)
+\closepath
+\moveto(178.4,227)
+\curveto(182.2,223.2)(191.4,221.9)(195.9,226.3)
+\curveto(198,221.1)(212,186.6)(270.9,187.401)
+\curveto(264.4,189.401)(255.1,193.6)(245.2,202.201)
+\curveto(241,205.901)(236.9,210.1)(233.1,215.1)
+\curveto(226.3,215.401)(218.7,219.401)(212.1,224)
+\curveto(206,228.4)(200.9,233.2)(198.4,236.8)
+\curveto(195.7,236.1)(193.2,235.8)(191,235.8)
+\curveto(185.4,235.8)(181,237.8)(178.1,240.901)
+\curveto(175.2,244.001)(173.9,248.001)(173.9,251.8)
+\curveto(173.9,254)(174.3,256.1)(175.2,258)
+\curveto(171.3,255.5)(168.2,252.6)(166.7,250.6)
+\curveto(133.8,254.701)(116.2,252.3)(109.6,246.8)
+\curveto(104.4,236.3)(100,215.901)(133.4,206.2)
+\curveto(132.1,207.5)(132.3,208.8)(133.1,210)
+\curveto(129,211)(125.4,212.6)(122.4,214.7)
+\curveto(116.7,218.7)(113.4,224.599)(113.4,231.599)
+\curveto(113.4,232.099)(113.4,232.599)(113.5,233.099)
+\curveto(113.7,236.9)(115.5,239.7)(118.2,241.2)
+\curveto(120.9,242.7)(124.2,243.099)(127.8,243.099)
+\curveto(134.7,243.099)(143.1,241.599)(150.6,241.599)
+\curveto(158.5,241.599)(165,243.099)(168.6,248.7)
+\lineto(168.6,248.7)
+\curveto(169.2,249.599)(170.3,249.8)(171.2,249.2)
+\curveto(172.1,248.599)(172.3,247.5)(171.7,246.599)
+\curveto(167,239.4)(158.8,237.799)(150.6,237.799)
+\curveto(142.6,237.799)(134.2,239.299)(127.8,239.299)
+\curveto(124.5,239.299)(121.7,238.9)(120,237.9)
+\curveto(118.3,236.9)(117.4,235.7)(117.2,232.799)
+\lineto(117.2,231.499)
+\curveto(117.2,225.699)(119.7,221.099)(124.6,217.599)
+\curveto(129.3,214.299)(136.3,212.299)(145.2,212.2)
+\curveto(148.4,215.599)(149.9,219.099)(149.8,221.5)
+\curveto(149.8,222.1)(149.7,222.6)(149.6,223)
+\curveto(149.4,223.7)(149.6,224.4)(150.1,224.9)
+\curveto(151.3,226.099)(152.8,226.5)(154.2,226.799)
+\curveto(155.7,227.099)(157.3,227.4)(159,227.9)
+\curveto(162.4,228.9)(166.2,230.599)(170.1,235.7)
+\curveto(170.7,236.5)(171.9,236.7)(172.7,236.099)
+\curveto(173.5,235.499)(173.7,234.299)(173.1,233.499)
+\curveto(166.6,224.799)(159,224.099)(155.1,223.199)
+\curveto(154.4,223.098)(153.9,222.899)(153.5,222.699)
+\curveto(153.6,222.299)(153.6,221.899)(153.6,221.499)
+\curveto(153.6,217.499)(151.4,213.099)(147.3,209.099)
+\curveto(147.1,208.9)(146.8,208.7)(146.5,208.599)
+\curveto(146.5,207.9)(146.2,207.2)(145.4,206.4)
+\curveto(153.2,205.7)(163.5,203.299)(168.5,208.299)
+\curveto(173.4,213.3)(174.9,223.5)(178.4,227)
+\closepath
+\moveto(137.5,369.6)
+\curveto(138.8,371.1)(150.4,383.1)(157.7,388.3)
+\curveto(150.7,386.6)(139.4,380.6)(129.8,372.9)
+\curveto(131.7,371.5)(135.2,369.9)(137.5,369.6)
+\closepath
+\moveto(139.8,354.8)
+\curveto(144.9,360)(162.2,379.5)(161.1,383.3)
+\curveto(155.1,377.5)(150.2,373.2)(147.6,370.2)
+\curveto(143.7,365.7)(141,361.9)(139.8,354.8)
+\closepath
+\moveto(112.4,270.4)
+\curveto(112.4,281.4)(130.8,280)(133.9,291.9)
+\curveto(137.4,305.2)(123.1,305.799)(129.8,316.2)
+\curveto(120.1,322.7)(110.1,319.099)(110.1,327.2)
+\curveto(110.1,335.4)(128.6,339.3)(135.6,363.3)
+\curveto(135.6,363.3)(133.7,358.2)(128.3,353.7)
+\curveto(113.3,341.3)(96,340.4)(95.4,324)
+\curveto(94.7,306.2)(114.8,294.5)(107.6,287.3)
+\curveto(100.6,280.3)(108.9,273.9)(112.4,270.4)
+\closepath
+\moveto(191.5,437.6)
+\curveto(197.2,430.6)(211.2,411.6)(211.2,392.9)
+\curveto(211.2,385.5)(208.9,378)(202.9,371.7)
+\curveto(245.8,352.7)(214.3,317.599)(219.2,256.099)
+\curveto(223.3,232.4)(235.3,215.9)(247.7,204.999)
+\curveto(259.6,194.499)(270.3,187.999)(279.2,187.999)
+\curveto(279.4,187.999)(280.4,188.199)(280.6,188.299)
+\curveto(267.1,193.199)(254.7,205.299)(248.9,216.799)
+\curveto(246.1,222.4)(243.7,229.299)(242.6,235.099)
+\curveto(241.6,240.599)(241.5,243.299)(241.5,249.999)
+\curveto(241.5,277.999)(252,295.099)(252,295.099)
+\curveto(264.7,320.299)(282.8,337.599)(299.7,354.7)
+\curveto(306,361)(312.099,367.4)(317.7,374)
+\curveto(295.5,428.5)(248.9,444.7)(216.7,444.7)
+\curveto(210.1,444.7)(204.2,444)(199.2,442.9)
+\lineto(199.2,442.9)
+\curveto(198.9,442.8)(198.6,442.8)(198.3,442.9)
+\curveto(196.9,441.1)(194.8,439.1)(191.5,437.6)
+\closepath
+\moveto(351.3,167.9)
+\curveto(347.7,163.4)(341.1,158.9)(329.7,155.5)
+\curveto(316.8,151.7)(304.7,149.7)(294,149.7)
+\curveto(283.8,149.7)(274.7,151.5)(267,155)
+\curveto(266.1,154.3)(265.1,153.6)(264,153)
+\curveto(261.7,148.3)(258.3,145.3)(253.8,143.4)
+\curveto(294.6,128)(363.6,139.299)(381.7,155.2)
+\lineto(381.7,156.4)
+\curveto(381.7,159.099)(381.8,161.5)(382,163.7)
+\lineto(381,163.7)
+\curveto(368.4,163.7)(358.6,165.7)(351.3,167.9)
+\closepath
+\moveto(396,161.5)
+\curveto(399.4,161.5)(402.8,162.1)(405.9,163.2)
+\curveto(413.9,164.8)(421.4,168.099)(427.099,171)
+\curveto(409.599,165.8)(394.999,163.9)(382.9,163.7)
+\curveto(386.4,162.4)(390.7,161.5)(396,161.5)
+\closepath
+\moveto(414.5,154.1)
+\curveto(410.6,140.5)(433.7,139.6)(443.2,141.701)
+\curveto(441.5,142.701)(440.099,144.301)(439.3,146.801)
+\curveto(438.2,150.201)(439.401,153.402)(441.401,155.601)
+\curveto(435,158.9)(418.3,167.3)(414.5,154.1)
+\closepath
+\moveto(553,374.7)
+\curveto(550.8,446.1)(503.9,525.6)(428.7,533.7)
+\curveto(423.099,527.5)(418.2,521.4)(413.9,515.4)
+\curveto(417.799,511.7)(421.599,507.9)(425.299,503.8)
+\curveto(425.499,503.6)(425.699,503.3)(425.9,503.1)
+\curveto(426.5,503.6)(427.2,504.1)(427.799,504.6)
+\curveto(445.999,517.4)(483.099,519.7)(498.699,487.7)
+\curveto(514.098,456.1)(484.899,432.1)(484.899,432.1)
+\curveto(481.598,429.2)(475.699,426.3)(468.798,424.9)
+\curveto(469.998,420.5)(470.998,416.1)(471.899,411.6)
+\lineto(472.098,411.6)
+\curveto(491.598,413.1)(513.498,401.4)(517.498,373.2)
+\curveto(525.298,318)(470.098,296.3)(452.198,290.099)
+\curveto(449.597,288.9)(448.798,287.099)(448.798,287.099)
+\curveto(453.498,286.4)(457.598,282.7)(460.098,277.7)
+\curveto(461.298,275.2)(461.798,273)(461.798,271)
+\curveto(461.798,266.2)(458.698,262.6)(454.399,260.1)
+\curveto(450.098,257.6)(444.499,256.401)(440.499,256.401)
+\curveto(438.699,256.401)(437.099,256.701)(436.199,257.1)
+\curveto(435.699,257.3)(435.399,257.5)(435.299,257.701)
+\curveto(435.4,258.1)(435.499,258.6)(435.699,259.001)
+\curveto(439.199,266.801)(458.199,258.001)(454.799,275.301)
+\curveto(453.699,280.701)(450.699,283.101)(446.599,283.501)
+\curveto(431.499,261.501)(413.599,246.301)(401.7,234.801)
+\curveto(394.4,227.902)(388.8,223.301)(387.599,219.701)
+\curveto(387.2,218.501)(386.2,214.901)(388.499,212.501)
+\curveto(389.099,211.901)(389.999,211.101)(390.899,211.001)
+\curveto(396.999,210.001)(397.699,216.801)(397.699,216.801)
+\curveto(398.699,215.501)(399.299,214.001)(399.299,212.402)
+\curveto(399.299,212.002)(399.199,211.601)(399.199,211.202)
+\lineto(399.199,210.902)
+\curveto(398.199,204.002)(392.899,200.402)(387.399,200.402)
+\lineto(387.3,200.402)
+\curveto(383.901,200.402)(380.401,201.801)(377.7,204.502)
+\curveto(375,207.302)(373.3,211.402)(373.3,216.902)
+\curveto(373.3,217.801)(373.401,218.801)(373.5,219.801)
+\curveto(374.4,227.902)(381.8,244.701)(381.8,262.101)
+\curveto(381.8,280.501)(373.6,299.402)(340.1,309.501)
+\curveto(329.401,312.701)(319.8,314.101)(311.1,314.101)
+\curveto(279.5,314.101)(261.1,295.101)(251.8,274.702)
+\curveto(249.7,268.002)(247.8,259.402)(247.3,248.902)
+\curveto(247.1,244.502)(247.5,239.202)(248,235.301)
+\curveto(248.6,231.301)(251.1,222.902)(253.8,217.301)
+\curveto(259.6,205.701)(268.2,194.601)(279.7,189.801)
+\lineto(281.5,189.101)
+\curveto(287.4,190.402)(290.8,191.601)(297.2,193.902)
+\lineto(298.7,194.402)
+\curveto(308.9,198.101)(318.5,201.601)(327.8,201.601)
+\curveto(333.8,201.601)(339,200.301)(343.7,197.301)
+\curveto(344.3,197.001)(344.8,196.601)(345.3,196.201)
+\lineto(348.2,193.901)
+\lineto(348.2,193.901)
+\lineto(348.9,193.201)
+\curveto(352.5,189.401)(355.2,183.901)(354.799,178.1)
+\curveto(354.599,175.701)(353.9,172.901)(352.199,170.1)
+\curveto(359.199,168)(368.499,166.201)(380.499,166.201)
+\curveto(394.799,166.201)(413.099,168.801)(435.899,176.701)
+\lineto(435.999,176.701)
+\curveto(436.099,176.701)(436.099,176.801)(436.099,176.801)
+\curveto(474.299,176.801)(459.099,152.101)(454.9,157.001)
+\curveto(450.299,162.201)(439.4,154.801)(442.5,146.301)
+\curveto(447.2,133.101)(468.7,144.801)(471,153.501)
+\curveto(466.6,124.701)(421.8,137.001)(411.5,138.401)
+\curveto(399.4,140.1)(394.5,128.901)(396.2,118.6)
+\curveto(397.599,110.1)(392.3,102.3)(389.9,100)
+\curveto(407,96.7)(415.099,111.2)(421.799,115.8)
+\curveto(428.599,120.5)(453.199,118.2)(467.099,128.901)
+\curveto(481,139.5)(479.2,165.1)(479.2,168.1)
+\curveto(482.4,169.401)(493.2,173.8)(493.2,186.201)
+\curveto(493.2,197.001)(485.2,202.401)(477,201.401)
+\curveto(467.9,200.3)(465.2,189.1)(475.5,188.901)
+\curveto(473.2,191.201)(475.9,194.701)(479,193.001)
+\curveto(483.7,190.401)(478.4,182.601)(468.7,184.201)
+\curveto(465.3,184.801)(457.599,185.901)(450.3,186.901)
+\curveto(505.7,215.9)(556.1,275.2)(553,374.7)
+\closepath
+\moveto(435.5,254.8)
+\curveto(436.9,254.2)(438.7,254)(440.8,254)
+\curveto(445.401,254)(451.2,255.3)(456,258)
+\curveto(460.8,260.7)(464.7,265.1)(464.7,271)
+\curveto(464.7,273.4)(464.099,276)(462.7,278.8)
+\curveto(462,280.2)(461.3,281.3)(460.4,282.3)
+\curveto(465.2,278.6)(467.599,275)(468.599,271.8)
+\curveto(468.799,271)(468.999,270.2)(469.2,269.5)
+\curveto(469.3,268.7)(469.4,268)(469.4,267.3)
+\curveto(469.4,264.8)(468.799,262.6)(468.099,260.901)
+\curveto(464.7,251.5)(455.8,247.1)(445.9,247)
+\curveto(444.299,247)(442.599,247.1)(441,247.4)
+\curveto(438.3,248.9)(435.9,251.7)(435.4,255)
+\curveto(435.4,254.8)(435.4,254.8)(435.5,254.8)
+\closepath
+\moveto(436.1,245.8)
+\curveto(439.3,244.901)(442.6,244.5)(445.8,244.5)
+\lineto(445.901,244.5)
+\curveto(456.401,244.5)(466.401,249.4)(470.3,259.8)
+\curveto(470,250.5)(465.3,246.401)(458.901,243.1)
+\curveto(452.3,239.701)(444.001,237.6)(438.001,232.6)
+\curveto(433.201,228.6)(431.201,223.701)(431.201,218.8)
+\curveto(431.201,211.8)(435.1,204.8)(440.1,199)
+\curveto(405,220.5)(420.6,241.6)(436.1,245.8)
+\closepath
+\moveto(452.6,224.5)
+\curveto(439.8,220.2)(441.8,205.1)(443.201,199.1)
+\curveto(437.801,204.901)(433.701,212.1)(433.701,218.701)
+\curveto(433.701,222.901)(435.301,227.001)(439.6,230.6)
+\curveto(445,235.201)(453.1,237.3)(460,240.8)
+\curveto(466.9,244.3)(472.8,249.7)(472.8,260.401)
+\curveto(472.8,263.201)(472.401,266.3)(471.6,269.8)
+\curveto(470.701,275.8)(466.201,282.8)(453.8,289.401)
+\curveto(463.901,288.701)(482.7,284.201)(486,265.001)
+\curveto(489.7,243.8)(468.7,229.9)(452.6,224.5)
+\closepath
+\moveto(281.2,184.7)
+\curveto(276.6,183.599)(272,182.9)(267.3,182.8)
+\curveto(267.7,182.5)(268,182.2)(268.4,181.901)
+\curveto(270.7,179.6)(272.2,176.901)(272.3,174.1)
+\curveto(272.3,170.8)(272.1,164.1)(268.3,159)
+\curveto(270.5,156.8)(281.7,154.5)(281.7,154.5)
+\curveto(283.1,154.3)(284,154.4)(285,154.4)
+\curveto(288.3,154.4)(290.7,156.2)(292.5,159.099)
+\curveto(294.2,161.999)(295.1,165.999)(295.1,169.799)
+\curveto(295.1,170.799)(295,171.9)(294.9,172.9)
+\curveto(293.8,180.5)(289.1,184.9)(281.9,184.9)
+\curveto(281.6,184.7)(281.4,184.7)(281.2,184.7)
+\closepath
+\moveto(298.9,190.4)
+\curveto(295.1,189)(291.3,187.599)(287.4,186.4)
+\curveto(292.9,184.5)(296.6,179.599)(297.4,173)
+\curveto(297.5,171.9)(297.6,170.8)(297.6,169.6)
+\curveto(297.6,165.401)(296.6,161)(294.6,157.6)
+\curveto(293.7,156.1)(292.6,154.8)(291.3,153.8)
+\curveto(298.5,153.6)(305.7,154.3)(312.5,155.5)
+\lineto(312.5,155.5)
+\curveto(320.6,156.6)(325.2,166.3)(325.2,174.5)
+\curveto(325.2,175.6)(325.099,176.7)(324.9,177.7)
+\curveto(323.7,185.099)(316.599,193.3)(307.4,193.3)
+\curveto(304.7,192.5)(301.8,191.4)(298.9,190.4)
+\closepath
+\moveto(342.3,194)
+\curveto(337.901,196.9)(333.2,198)(328.3,198)
+\curveto(323.401,198)(318.2,196.9)(312.8,195.2)
+\curveto(320.8,192.7)(326.3,185.3)(327.5,178.3)
+\curveto(327.7,177.1)(327.8,175.901)(327.8,174.6)
+\curveto(327.8,168.701)(325.6,161.8)(321.3,157.5)
+\curveto(323.901,158.1)(326.3,158.8)(328.7,159.5)
+\curveto(337.9,162.2)(351.099,169)(351.8,178.4)
+\lineto(351.8,178.299)
+\curveto(351.8,178.699)(351.901,178.999)(351.901,179.4)
+\curveto(351.7,186.1)(346.1,191.3)(342.3,194)
+\closepath
+\moveto(124.6,372.3)
+\curveto(139.1,383.8)(159.7,393.3)(163.6,389.4)
+\curveto(167.5,385.5)(151.7,361.4)(135,344.7)
+\curveto(148.8,344.7)(163.4,347.4)(194.7,374.5)
+\curveto(198.5,380.2)(200,386.1)(200,392)
+\curveto(200.1,410.6)(184.6,429)(178.3,435.6)
+\curveto(170.3,436.8)(167.6,442.5)(167.5,442.8)
+\lineto(167.4,443.1)
+\lineto(167.3,443.4)
+\curveto(167.3,443.6)(166.4,448.1)(166.9,454.1)
+\curveto(145,449.2)(128.2,441.5)(121.7,436.1)
+\curveto(121.7,436.1)(123.6,433.7)(122.8,428.8)
+\curveto(126.4,427.3)(132.4,435.8)(140.9,432.2)
+\curveto(148.2,429)(154.9,422.4)(162.3,423.4)
+\lineto(163,420.3)
+\curveto(155,418)(147.7,426)(140.2,428.8)
+\curveto(132.4,431.8)(126.3,423.4)(122.1,425.9)
+\curveto(121.8,424.9)(121.3,423.7)(120.7,422.5)
+\curveto(121.3,418.1)(124.1,412.6)(128.3,409.3)
+\curveto(128.4,409.2)(128.5,409)(128.5,408.8)
+\curveto(128.5,408.6)(128.4,408.4)(128.3,408.3)
+\curveto(125.1,405.7)(106.6,392.3)(101.8,387.6)
+\curveto(102.1,387.4)(102.4,387.2)(102.8,387)
+\curveto(109.4,382.9)(117.4,378.9)(122.4,378.9)
+\lineto(123.3,378.9)
+\curveto(125.9,381)(147.7,395.5)(160.4,395.6)
+\curveto(164.4,395.6)(167.7,394)(168.7,389.9)
+\curveto(168.8,389.6)(168.6,389.2)(168.3,389.1)
+\curveto(168,389)(167.6,389.2)(167.5,389.5)
+\curveto(166.6,392.9)(164.1,394.2)(160.4,394.2)
+\curveto(148.2,394.3)(124.9,378.7)(124,377.7)
+\curveto(123.9,377.6)(123.8,377.5)(123.6,377.5)
+\curveto(123.2,377.5)(122.8,377.4)(122.4,377.4)
+\curveto(112.4,377.5)(94.5,390.6)(90.8,393.4)
+\curveto(93.6,385.4)(108,374.8)(124.6,372.3)
+\closepath
+\moveto(136,408.7)
+\curveto(126.6,410.2)(125.5,420.7)(125.5,420.7)
+\curveto(127.8,426.2)(141.1,427.3)(148.8,416.8)
+\curveto(148.8,416.8)(143.4,407.5)(136,408.7)
+\closepath
+\moveto(184.9,262.5)
+\curveto(180.7,260.4)(177.7,256.6)(177.7,251.9)
+\curveto(177.8,245.9)(181.7,239.599)(191.1,239.5)
+\curveto(193.1,239.5)(195.4,239.8)(198,240.5)
+\curveto(204.4,243.5)(206.2,250.2)(206.2,254.4)
+\curveto(206.2,255.2)(206.1,255.9)(206,256.4)
+\curveto(205.8,257.299)(205.6,258.2)(205.3,258.9)
+\curveto(198.4,263.9)(191.2,264.2)(184.9,262.5)
+\closepath
+\moveto(100.7,388.4)
+\curveto(105.3,392.9)(122.3,405.4)(126.8,408.8)
+\curveto(122.9,412.1)(120.4,416.5)(119.7,420.8)
+\curveto(119.4,420.2)(119,419.5)(118.5,418.9)
+\curveto(112.3,409.2)(98.6,401.4)(90.8,395)
+\curveto(91.5,394.5)(95.5,391.5)(100.6,388.2)
+\curveto(100.7,388.3)(100.7,388.4)(100.7,388.4)
+\closepath
+\moveto(208.7,392.9)
+\curveto(208.8,410.9)(194.2,430.5)(189,436.7)
+\curveto(188.5,436.6)(188.1,436.4)(187.6,436.3)
+\curveto(185.6,435.8)(183.7,435.6)(181.9,435.5)
+\curveto(189,427.6)(202.4,410.4)(202.5,392.1)
+\curveto(202.5,386)(201,379.9)(197.2,374)
+\curveto(198.3,373.6)(199.4,373.2)(200.4,372.8)
+\lineto(200.4,372.8)
+\curveto(206.5,378.7)(208.7,385.7)(208.7,392.9)
+\closepath
+\moveto(159.6,456.1)
+\curveto(157.3,460.5)(152.9,464.6)(140.5,471)
+\curveto(133.4,463.1)(132.9,454)(134.1,447)
+\curveto(141.3,450.6)(149.9,453.7)(159.6,456.1)
+\closepath
+\moveto(186.9,439.3)
+\curveto(196.7,441.7)(197.5,448.8)(197.5,448.8)
+\curveto(197.5,457.5)(198.9,461.8)(183.6,477.1)
+\curveto(165.7,466.7)(170.3,444.2)(170.3,444.2)
+\curveto(170.3,444.2)(174,436.1)(186.9,439.3)
+\closepath
+}
+}
+\end{pspicture}
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-abjad.sty b/macros/luatex/latex/simurgh/tex/simurgh-abjad.sty
new file mode 100644
index 0000000000..70c1f24334
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-abjad.sty
@@ -0,0 +1,51 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-abjad}[2013/09/18 v0.01a abjad counter]
+\if@simurgh@csundef{abjadnumeral}{%
+\def\abjadnumeral#1{%
+\ifnum#1>1999 \simurgh@warning{Illegal value (#1) for abjad numeral} {#1}
+\else
+ \ifnum#1<\z@\space\simurgh@warning{Illegal value (#1) for abjad numeral}%
+ \else
+ \ifnum#1<10\expandafter\abj@num@i\number#1%
+ \else
+ \ifnum#1<100\expandafter\abj@num@ii\number#1%
+ \else
+ \ifnum#1<\@m\expandafter\abj@num@iii\number#1%
+ \else
+ \ifnum#1<\@M\expandafter\abj@num@iv\number#1%since #1<2000, we must have 1000
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+\fi
+}
+\def\abjad@zero{}
+\def\abj@num@i#1{%
+ \ifcase#1\or آ\or ب\or ج\or د%
+ \or Ù‡â€\or Ùˆ\or ز\or Ø­\or Ø·\fi
+ \ifnum#1=\z@\abjad@zero\fi}
+\def\abj@num@ii#1{%
+ \ifcase#1\or ی\or ک\or ل\or م\or ن%
+ \or س\or ع\or Ù\or ص\fi
+ \ifnum#1=\z@\fi\abj@num@i}
+\def\abj@num@iii#1{%
+ \ifcase#1\or ق\or ر\or ش\or ت\or ث%
+ \or خ\or ذ\or ض\or ظ\fi
+ \ifnum#1=\z@\fi\abj@num@ii}
+\def\abj@num@iv#1{%
+ \ifcase#1\or غ\fi
+ \ifnum#1=\z@\fi\abj@num@iii}
+}{}
+ \let\@latinalph\@alph%
+ \let\@latinAlph\@Alph%
+\def\ParsiAlphs{%
+ \let\@alph\abjadnumeral%
+ \let\@Alph\abjadnumeral%
+}
+\def\LatinAlphs{%
+ \let\@alph\@latinalph%
+ \let\@Alph\@latinAlph%
+}
+\ParsiAlphs
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-adadi.sty b/macros/luatex/latex/simurgh/tex/simurgh-adadi.sty
new file mode 100644
index 0000000000..1aff8d261d
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-adadi.sty
@@ -0,0 +1,109 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-adadi}[2013/09/18 v0.01a adadi counter]
+\newcommand{\adadi}[1]{%
+\expandafter\@adadi\csname c@#1\endcsname%
+}
+\newcommand{\@adadi}[1]{%
+\simurgh@numberstring{#1}\simurgh@yekanii{صÙر}{}%
+}
+\let\adadinumeral\@adadi%
+\def\simurgh@numberoutofrange#1#2{%
+\simurgh@error{The number `#1' is too large %
+to be formatted using simurgh}{The largest possible %
+number is 999,999,999.}%
+}
+\def\simurgh@numberstring#1#2#3#4{%
+\ifnum\number#1<\@ne%
+#3%
+\else\ifnum\number#1<1000000000 %
+\expandafter\simurgh@adadi\expandafter{\number#1}#2%
+\else%
+\simurgh@numberoutofrange{#1}{#4}%
+\fi\fi%
+}
+\def\simurgh@adadi#1#2{%
+\expandafter\simurgh@@adadi%
+\ifcase%
+\ifnum#1<10 1%
+\else\ifnum#1<100 2%
+\else\ifnum#1<\@m 3%
+\else\ifnum#1<\@M 4%
+\else\ifnum#1<100000 5%
+\else\ifnum#1<1000000 6%
+\else\ifnum#1<10000000 7%
+\else\ifnum#1<100000000 8%
+\else9%
+\fi\fi\fi\fi\fi\fi\fi\fi %
+\or00000000#1% case 1: Add 8 leading zeros
+\or0000000#1% case 2: Add 7 leading zeros
+\or000000#1% case 3: Add 6 leading zeros
+\or00000#1% case 4: Add 5 leading zeros
+\or0000#1% case 5: Add 4 leading zeros
+\or000#1% case 6: Add 3 leading zeros
+\or00#1% case 7: Add 2 leading zeros
+\or0#1% case 8: Add 1 leading zero
+\or#1% case 9: Add no leading zeros
+\or%
+\@nil#2%
+\fi%
+}
+\def\simurgh@@adadi#1#2#3#4#5#6#7\or#8\@nil#9{%
+\ifnum#1#2#3>\z@
+\simurgh@milyoongan#1#2#3%
+\ifnum#7>\z@\ifnum#4#5#6>\z@\ Ùˆ \else\ Ùˆ \fi\else\ifnum#4#5#6>\z@\ Ùˆ \fi\fi%
+\fi%
+\ifnum#4#5#6>\z@%
+\simurgh@sadgan#4#5#6{#1#2#3}{#4#5}\simurgh@yekani%
+\ifnum#4#5#6>\@ne‌\fi%
+هزار%
+\ifnum#7>\z@\ Ùˆ \fi%
+\fi%
+\simurgh@sadgan#7{#4#5#6}1#9%
+}
+\def\simurgh@milyoongan#1#2#3{%
+\ifnum#1#2#3=\@ne%
+\simurgh@sadgan#1#2#301\simurgh@yekaniii%
+‌%
+میلیون%
+\else%
+\simurgh@sadgan#1#2#301\simurgh@yekanii%
+‌%
+میلیون%
+\fi%
+}
+\def\simurgh@sadgan#1#2#3#4#5#6{%
+\ifnum#1>\z@%
+\ifnum#4#1>\@ne\simurgh@yekaniv#1\fi%
+صد%
+\ifnum#2#3>\z@\ Ùˆ \fi%
+\fi%
+\ifnum#2#3<20%
+\ifnum#5#2#3>\@ne#6{#2#3}\fi%
+\else%
+\simurgh@dahgan#2%
+\ifnum#3>\z@\ Ùˆ \simurgh@yekani#3\fi%
+#60%
+\fi%
+}
+\def\simurgh@yekani#1{%
+\ifcase#1\@empty\or یک\or دو\or سه\or چهار\or پنج\or شش%
+\or Ù‡Ùت\or هشت\or نه\or ده\or یازده\or دوازده\or سیزده%
+\or چهارده\or پانزده\or شانزده\or Ù‡Ùده%
+\or هجده\or نوزده\fi%
+}
+\def\simurgh@yekanii#1{%
+\ifcase#1\@empty\or یک\else\simurgh@yekani{#1}\fi%
+}
+\def\simurgh@yekaniii#1{%
+\ifcase#1\@empty\or یک\else\simurgh@yekani{#1}\fi%
+}
+\def\simurgh@yekaniv#1{%
+\ifcase#1\@empty\or\or دوی\or سی\or چهار\or پان\or شش%
+\or Ù‡Ùت\or هشت\or نه\fi%
+}
+\def\simurgh@dahgan#1{%
+\ifcase#1\or\or بیست\or سی\or چهل%
+\or پنجاه\or شصت\or Ù‡Ùتاد\or هشتاد%
+\or نود\fi%
+}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-algorithm.sty b/macros/luatex/latex/simurgh/tex/simurgh-algorithm.sty
new file mode 100644
index 0000000000..c7773e8698
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-algorithm.sty
@@ -0,0 +1,8 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-algorithm}[2013/09/18 v0.01a changes to `algorithm.sty']
+\def\ALG@name{\if@RTL الگوریتم\else Algorithm\fi}
+\def\ALGS@name{الگوریتم‌ها}
+\def\listalgorithmname{\if@RTL Ùهرست \ALGS@name\else List of \ALG@name s\fi}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-algorithmic.sty b/macros/luatex/latex/simurgh/tex/simurgh-algorithmic.sty
new file mode 100644
index 0000000000..ce58cc9fd1
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-algorithmic.sty
@@ -0,0 +1,7 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-algorithmic}[2013/09/18 v0.01a changes to `algorithmic.sty']
+\def\algorithmicrequire{\if@RTL\textbf{ورودی:}\else\textbf{Require:}\fi}
+\def\algorithmicensure{\if@RTL\textbf{خروجی:}\else\textbf{Ensure:}\fi}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-amsart.sty b/macros/luatex/latex/simurgh/tex/simurgh-amsart.sty
new file mode 100644
index 0000000000..b42c2860ee
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-amsart.sty
@@ -0,0 +1,118 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-amsart}[2013/09/18 v0.01a changes to `amsart.cls']
+\renewcommand\thesubsection {\thesection\@SepMark\arabic{subsection}}
+\renewcommand\thesubsubsection {\thesubsection \@SepMark\arabic{subsubsection}}
+\renewcommand\theparagraph {\thesubsubsection\@SepMark\arabic{paragraph}}
+\renewcommand\thesubparagraph {\theparagraph\@SepMark\arabic{subparagraph}}
+\def\part{\@startsection{part}{0}%
+ \z@{\linespacing\@plus\linespacing}{.5\linespacing}%
+ {\normalfont\bfseries\simurgh@raggedright}}%
+\def\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{\kern-.4\p@
+ \hrule\@width 5pc\kern11\p@\kern-\footnotesep}\hfil}}
+\def\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{\kern-.4\p@
+ \hrule\@width 5pc\kern11\p@\kern-\footnotesep}\hfil}}
+
+\long\def\@footnotetext#1{%
+ \insert\footins{%
+ \if@RTL@footnote%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \reset@parsifont%
+ \else%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \reset@latinfont%
+ \fi%
+ \footnotesize
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\footnotesep \splitmaxdepth \dp\strutbox
+ \floatingpenalty\@MM \hsize\columnwidth
+ \@parboxrestore \parindent\normalparindent \sloppy
+ \protected@edef\@currentlabel{%
+ \csname p@footnote\endcsname\@thefnmark}%
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\unskip\strut\par}}}
+
+\long\def\@RTLfootnotetext#1{%
+ \insert\footins{%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \reset@parsifont%
+ \footnotesize
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\footnotesep \splitmaxdepth \dp\strutbox
+ \floatingpenalty\@MM \hsize\columnwidth
+ \@parboxrestore \parindent\normalparindent \sloppy
+ \protected@edef\@currentlabel{%
+ \csname p@footnote\endcsname\@thefnmark}%
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\unskip\strut\par}}}
+
+\long\def\@LTRfootnotetext#1{%
+ \insert\footins{%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \reset@latinfont%
+ \footnotesize
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\footnotesep \splitmaxdepth \dp\strutbox
+ \floatingpenalty\@MM \hsize\columnwidth
+ \@parboxrestore \parindent\normalparindent \sloppy
+ \protected@edef\@currentlabel{%
+ \csname p@footnote\endcsname\@thefnmark}%
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\unskip\strut\par}}}
+
+\footdir@temp\footdir@ORG@simurgh@amsart@footnotetext\@footnotetext{\simurgh@footdir@footnote}%
+\footdir@temp\footdir@ORG@simurgh@amsart@RTLfootnotetext\@RTLfootnotetext{R}%
+\footdir@temp\footdir@ORG@simurgh@amsart@LTRfootnotetext\@LTRfootnotetext{L}%
+
+\renewenvironment{thebibliography}[1]{%
+ \@bibtitlestyle
+ \normalfont\bibliofont\labelsep .5em\relax
+ \renewcommand\theenumiv{\arabic{enumiv}}\let\p@enumiv\@empty
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\theenumiv}}{\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth \advance\leftmargin\labelsep
+ \usecounter{enumiv}}%
+ \sloppy \clubpenalty\@M \widowpenalty\clubpenalty
+ \sfcode`\.=\@m
+}{%
+ \def\@noitemerr{\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist
+}
+\def\theindex{\@restonecoltrue\if@twocolumn\@restonecolfalse\fi
+ \columnseprule\z@ \columnsep 35\p@
+ \@indextitlestyle
+ \thispagestyle{plain}%
+ \let\item\@idxitem
+ \parindent\z@ \parskip\z@\@plus.3\p@\relax
+ \simurgh@raggedright
+ \hyphenpenalty\@M
+ \footnotesize}
+
+\renewcommand \thepart {\@tartibi\c@part}
+\def\appendix{\par\c@section\z@ \c@subsection\z@
+ \let\sectionname\appendixname
+ \def\thesection{\@harfi\c@section}}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-amsbook.sty b/macros/luatex/latex/simurgh/tex/simurgh-amsbook.sty
new file mode 100644
index 0000000000..fcf5e2c386
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-amsbook.sty
@@ -0,0 +1,117 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-amsbook}[2013/09/18 v0.01a changes to `amsbook.cls']
+\renewcommand\thesubsection {\thesection\@SepMark\arabic{subsection}}
+\renewcommand\thesubsubsection {\thesubsection \@SepMark\arabic{subsubsection}}
+\renewcommand\theparagraph {\thesubsubsection\@SepMark\arabic{paragraph}}
+\renewcommand\thesubparagraph {\theparagraph\@SepMark\arabic{subparagraph}}
+\def\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{\kern-.4\p@
+ \hrule\@width 5pc\kern11\p@\kern-\footnotesep}\hfil}}
+\def\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{\kern-.4\p@
+ \hrule\@width 5pc\kern11\p@\kern-\footnotesep}\hfil}}
+
+\long\def\@footnotetext#1{%
+ \insert\footins{%
+ \if@RTL@footnote%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \reset@parsifont%
+ \else%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \reset@latinfont%
+ \fi%
+ \footnotesize
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\footnotesep \splitmaxdepth \dp\strutbox
+ \floatingpenalty\@MM \hsize\columnwidth
+ \@parboxrestore \parindent\normalparindent \sloppy
+ \protected@edef\@currentlabel{%
+ \csname p@footnote\endcsname\@thefnmark}%
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\unskip\strut\par}}}
+
+\long\def\@RTLfootnotetext#1{%
+ \insert\footins{%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \reset@parsifont%
+ \footnotesize
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\footnotesep \splitmaxdepth \dp\strutbox
+ \floatingpenalty\@MM \hsize\columnwidth
+ \@parboxrestore \parindent\normalparindent \sloppy
+ \protected@edef\@currentlabel{%
+ \csname p@footnote\endcsname\@thefnmark}%
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\unskip\strut\par}}}
+
+\long\def\@LTRfootnotetext#1{%
+ \insert\footins{%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \reset@latinfont%
+ \footnotesize
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\footnotesep \splitmaxdepth \dp\strutbox
+ \floatingpenalty\@MM \hsize\columnwidth
+ \@parboxrestore \parindent\normalparindent \sloppy
+ \protected@edef\@currentlabel{%
+ \csname p@footnote\endcsname\@thefnmark}%
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\unskip\strut\par}}}
+
+\footdir@temp\footdir@ORG@simurgh@amsbook@footnotetext\@footnotetext{\simurgh@footdir@footnote}%
+\footdir@temp\footdir@ORG@simurgh@amsbook@RTLfootnotetext\@RTLfootnotetext{R}%
+\footdir@temp\footdir@ORG@simurgh@amsbook@LTRfootnotetext\@LTRfootnotetext{L}%
+
+\renewenvironment{thebibliography}[1]{%
+ \@bibtitlestyle
+ \normalfont\bibliofont\labelsep .5em\relax
+ \renewcommand\theenumiv{\arabic{enumiv}}\let\p@enumiv\@empty
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\theenumiv}}{\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth \advance\leftmargin\labelsep
+ \usecounter{enumiv}}%
+ \sloppy \clubpenalty\@M \widowpenalty\clubpenalty
+ \sfcode`\.=\@m
+}{%
+ \def\@noitemerr{\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist
+}
+\def\theindex{\@restonecoltrue\if@twocolumn\@restonecolfalse\fi
+ \columnseprule\z@ \columnsep 35\p@
+ \@indextitlestyle
+ \thispagestyle{plain}%
+ \let\item\@idxitem
+ \parindent\z@ \parskip\z@\@plus.3\p@\relax
+ \simurgh@raggedright
+ \hyphenpenalty\@M
+ \footnotesize}
+
+\def\frontmatter{\cleardoublepage\pagenumbering{harfi}}
+\renewcommand \thepart {\@tartibi\c@part}
+\def\appendix{\par
+ \c@chapter\z@ \c@section\z@
+ \let\chaptername\appendixname
+ \def\thechapter{\@harfi\c@chapter}}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-amsmath.sty b/macros/luatex/latex/simurgh/tex/simurgh-amsmath.sty
new file mode 100644
index 0000000000..315762e4fb
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-amsmath.sty
@@ -0,0 +1,128 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-amsmath}[2013/09/22 v0.01b changes to `amsmath.sty']
+\def\maketag@@@#1{\if@RTL\hboxR\else\hboxL\fi{\m@th\normalfont#1}}
+\iftagsleft@
+ \def\@eqnnum{\hbox to1sp{}
+ \if@RTL
+ \llapR{\normalfont\normalcolor
+ \tagform@\theequation\hskip -\displaywidth}
+ \else
+ \rlapL{\normalfont\normalcolor
+ \hskip -\displaywidth\tagform@\theequation}
+ \fi}
+\else
+ \def\@eqnnum{{\normalfont\normalcolor \tagform@\theequation}}
+\fi
+\renewcommand{\numberwithin}[3][\arabic]{%
+ \@ifundefined{c@#2}{\@nocounterr{#2}}{%
+ \@ifundefined{c@#3}{\@nocnterr{#3}}{%
+ \@addtoreset{#2}{#3}%
+ \@xp\xdef\csname the#2\endcsname{%
+ \@xp\@nx\csname the#3\endcsname \@nx\@SepMark\@nx#1{#2}}}}%
+}
+
+\def\intertext@{%
+ \def\intertext##1{%
+ \ifvmode\else\\\@empty\fi
+ \noalign{%
+ \penalty\postdisplaypenalty\vskip\belowdisplayskip
+ \if@RTL\vboxR\else\vboxL\fi{\normalbaselines
+ \ifdim\linewidth=\columnwidth
+ \else \parshape\@ne \@totalleftmargin \linewidth
+ \fi
+ \noindent##1\par}%
+ \penalty\predisplaypenalty\vskip\abovedisplayskip%
+ }%
+}}
+
+
+\def\multline@#1{%
+ \Let@
+ \@display@init{\global\advance\row@\@ne \global\dspbrk@lvl\m@ne}%
+ \chardef\dspbrk@context\z@
+ \restore@math@cr
+ \let\tag\tag@in@align
+ \global\tag@false \global\let\raise@tag\@empty
+ \mmeasure@{#1}%
+ \let\tag\gobble@tag \let\label\@gobble
+% \tabskip \if@fleqn \@mathmargin \else \z@skip \fi
+ \tabskip \z@skip
+ \totwidth@\displaywidth
+ \if@fleqn
+ \advance\totwidth@-\@mathmargin
+ \fi
+ \halign\bgroup
+ \hbox to\totwidth@{%
+ \if@fleqn
+ \hskip \@centering \relax
+ \else
+ \hfil
+ \fi
+ \strut@
+ $\m@th\displaystyle{}##\endmultline@math
+ \hfil
+ }%
+ \crcr
+ \if@fleqn
+ \hskip-\@mathmargin
+ \def\multline@indent{\hskip\@mathmargin}% put it back
+ \else
+ \hfilneg
+ \def\multline@indent{\hskip\multlinegap}%
+ \fi
+ \iftagsleft@
+ \iftag@
+ \begingroup
+ \ifshifttag@
+ \rlap{\vbox{%
+ \normalbaselines
+ \hbox{%
+ \strut@
+ \make@display@tag
+ }%
+ \vbox to\lineht@{}%
+ \raise@tag
+ }}%
+ \multline@indent
+ \else
+ \setbox\z@\hbox{\make@display@tag}%
+ \dimen@\@mathmargin \advance\dimen@-\wd\z@
+ \ifdim\dimen@<\multlinetaggap
+ \dimen@\multlinetaggap
+ \fi
+ \box\z@ \hskip\dimen@\relax
+ \fi
+ \endgroup
+ \else
+ \multline@indent
+ \fi
+ \else
+ \multline@indent
+ \fi
+ #1%
+}
+
+\def\math@cr@@@align{%
+ \ifst@rred\nonumber\fi
+ \if@eqnsw \global\tag@true \fi
+ \global\advance\row@\@ne
+ \add@amps\maxfields@
+ \omit
+ \kern-\alignsep@
+% \iftag@
+% \setboxz@h{\@lign\strut@{\make@display@tag}}%
+% \place@tag
+% \fi
+ \iftag@
+ \setboxz@h{\@lign\strut@{\make@display@tag}}%
+ \place@tag
+ \else
+ \place@tag
+ \fi
+ \ifst@rred\else\global\@eqnswtrue\fi
+ \global\lineht@\z@
+ \cr
+}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-amstext.sty b/macros/luatex/latex/simurgh/tex/simurgh-amstext.sty
new file mode 100644
index 0000000000..bee317c0f4
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-amstext.sty
@@ -0,0 +1,9 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-amstext}[2013/09/22 v0.01a changes to `amstext.sty']
+\def\textdef@#1#2#3{\if@RTL\hboxR\else\hboxL\fi{{%
+ \everymath{#1}%
+ \let\f@size#2\selectfont
+ #3}}}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-amsthm.sty b/macros/luatex/latex/simurgh/tex/simurgh-amsthm.sty
new file mode 100644
index 0000000000..4b988a8318
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-amsthm.sty
@@ -0,0 +1,4 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-amsthm}[2013/09/18 v0.01a changes to `amsthm.sty']
+\def\@thmcountersep{\@SepMark}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-array.sty b/macros/luatex/latex/simurgh/tex/simurgh-array.sty
new file mode 100644
index 0000000000..d8e9f1152f
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-array.sty
@@ -0,0 +1,61 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-array}[2013/09/18 v0.01a changes to `array.sty']
+\def\@testpach{\@chclass
+ \ifnum \@lastchclass=6 \@ne \@chnum \@ne \else
+ \ifnum \@lastchclass=7 5 \else
+ \ifnum \@lastchclass=8 \tw@ \else
+ \ifnum \@lastchclass=9 \thr@@
+ \else \z@
+ \ifnum \@lastchclass = 10 \else
+ \edef\@nextchar{\expandafter\string\@nextchar}%
+ \@chnum
+ \if \@nextchar c\z@ \else
+ \if \@nextchar \if@RTLtab r\else l\fi\@ne \else
+ \if \@nextchar \if@RTLtab l\else r\fi\tw@ \else
+ \z@ \@chclass
+ \if\@nextchar |\@ne \else
+ \if \@nextchar !6 \else
+ \if \@nextchar @7 \else
+ \if \@nextchar <8 \else
+ \if \@nextchar >9 \else
+ 10
+ \@chnum
+ \if \@nextchar m\thr@@\else
+ \if \@nextchar p4 \else
+ \if \@nextchar b5 \else
+ \z@ \@chclass \z@ \@preamerr \z@ \fi \fi \fi \fi
+ \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi}
+\def\@tabular{\if@RTL\@RTLtabtrue\fi%
+ \leavevmode
+ \hbox \bgroup $\col@sep\tabcolsep \let\d@llarbegin\begingroup
+ \let\d@llarend\endgroup
+ \@tabarray}
+\def\endtabular{\endarray $\egroup\@RTLtabfalse}
+\expandafter\let\csname endtabular*\endcsname=\endtabular
+\def\@array[#1]#2{%
+ \@tempdima \ht \strutbox
+ \advance \@tempdima by\extrarowheight
+ \setbox \@arstrutbox \hbox{\vrule
+ \@height \arraystretch \@tempdima
+ \@depth \arraystretch \dp \strutbox
+ \@width \z@}%
+ \begingroup
+ \@mkpream{#2}%
+ \xdef\@preamble{\noexpand \ialign \@halignto
+ \bgroup \@arstrut \@preamble
+ \tabskip \z@ \cr}%
+ \endgroup
+ \@arrayleft
+ \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi \fi
+ \bgroup
+ \let \@sharp ##\let \protect \relax
+ \lineskip \z@
+ \baselineskip \z@
+ \m@th
+ \let\\\@arraycr \let\tabularnewline\\\let\par\@empty \if@RTLtab\textdir TRT\fi\@preamble}
+\def\@tabarray{\@ifnextchar[{\@array}{\@array[c]}}
+\def\endarray{\crcr \egroup \egroup \@arrayright \gdef\@preamble{}}
+\def\array{\col@sep\arraycolsep
+ \def\d@llarbegin{$}\let\d@llarend\d@llarbegin\gdef\@halignto{}%
+ \@RTLtabfalse\@tabarray}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-article.sty b/macros/luatex/latex/simurgh/tex/simurgh-article.sty
new file mode 100644
index 0000000000..ee39fe43d9
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-article.sty
@@ -0,0 +1,77 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-article}[2013/09/18 v0.01a changes to `article.cls']
+\renewcommand*{\left@footnoterule}{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern2.6\p@}\hfil}}
+\renewcommand*{\right@footnoterule}{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern2.6\p@}\hfil}}
+\renewcommand\thesubsection {\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand\thesubsubsection{\thesubsection\@SepMark\@arabic\c@subsubsection}
+\renewcommand\theparagraph {\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand\thesubparagraph {\theparagraph\@SepMark\@arabic\c@subparagraph}
+\def\@part[#1]#2{%
+ \ifnum \c@secnumdepth >\m@ne
+ \refstepcounter{part}%
+ \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}%
+ \else
+ \addcontentsline{toc}{part}{#1}%
+ \fi
+ {\parindent \z@ \simurgh@raggedright
+ \interlinepenalty \@M
+ \normalfont
+ \ifnum \c@secnumdepth >\m@ne
+ \Large\bfseries \partname\nobreakspace\thepart
+ \par\nobreak
+ \fi
+ \huge \bfseries #2%
+ \markboth{}{}\par}%
+ \nobreak
+ \vskip 3ex
+ \@afterheading}
+\renewenvironment{thebibliography}[1]
+ {\section*{\refname}%
+ \@mkboth{\MakeUppercase\refname}{\MakeUppercase\refname}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy
+ \clubpenalty4000
+ \@clubpenalty \clubpenalty
+ \widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+
+\renewcommand \thepart {\@tartibi\c@part}
+\renewcommand\appendix{\par
+ \setcounter{section}{0}%
+ \setcounter{subsection}{0}%
+ \gdef\thesection{\@harfi\c@section}}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-artikel1.sty b/macros/luatex/latex/simurgh/tex/simurgh-artikel1.sty
new file mode 100644
index 0000000000..c941523877
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-artikel1.sty
@@ -0,0 +1,59 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-artikel1}[2013/09/18 v0.01a changes to `artikel1.cls']
+\renewcommand*\thesubsection{\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand*\thesubsubsection{\thesubsection\@SepMark\@arabic\c@subsubsection}
+\renewcommand*\theparagraph{\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand*\thesubparagraph{\theparagraph\@SepMark\@arabic\c@subparagraph}
+\renewenvironment{thebibliography}[1]
+ {\section*{\refname}%
+ \@mkboth{\MakeUppercase\refname}{\MakeUppercase\refname}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand*\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy\clubpenalty4000\widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \kern.5\baselineskip
+ \hrule\@width\unitindent
+ \kern.4\baselineskip}\hfil}
+}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \kern.5\baselineskip
+ \hrule\@width\unitindent
+ \kern.4\baselineskip}\hfil}
+}
+
+\renewcommand*\thepart{\@tartibi\c@part}
+\renewcommand*\appendix{\par
+ \setcounter{section}{0}%
+ \setcounter{subsection}{0}%
+ \gdef\thesection{\@harfi\c@section}}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-artikel2.sty b/macros/luatex/latex/simurgh/tex/simurgh-artikel2.sty
new file mode 100644
index 0000000000..7dca7c3353
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-artikel2.sty
@@ -0,0 +1,56 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-artikel2}[2013/09/18 v0.01a changes to `artikel2.cls']
+\renewcommand*\thesubsection{\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand*\thesubsubsection{\thesubsection\@SepMark\@arabic\c@subsubsection}
+\renewcommand*\theparagraph{\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand*\thesubparagraph{\theparagraph\@SepMark\@arabic\c@subparagraph}
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width 3\unitindent
+ \kern 2.6\p@}\hfil}
+}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width 3\unitindent
+ \kern 2.6\p@}\hfil}
+}
+\renewenvironment{thebibliography}[1]
+ {\section*{\refname}%
+ \@mkboth{\MakeUppercase\refname}{\MakeUppercase\refname}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand*\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy\clubpenalty4000\widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+
+\renewcommand*\thepart{\@tartibi\c@part}
+\renewcommand*\appendix{\par
+ \setcounter{section}{0}%
+ \setcounter{subsection}{0}%
+ \gdef\thesection{\@harfi\c@section}}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-artikel3.sty b/macros/luatex/latex/simurgh/tex/simurgh-artikel3.sty
new file mode 100644
index 0000000000..06caaba301
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-artikel3.sty
@@ -0,0 +1,58 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-artikel3}[2013/09/18 v0.01a changes to `artikel3.cls']
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \kern.5\baselineskip
+ \hrule\@width\unitindent
+ \kern.4\baselineskip}\hfil}
+}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \kern.5\baselineskip
+ \hrule\@width\unitindent
+ \kern.4\baselineskip}\hfil}
+}
+\renewcommand*\thesubsection{\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand*\thesubsubsection{\thesubsection\@SepMark\@arabic\c@subsubsection}
+\renewcommand*\theparagraph{\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand*\thesubparagraph{\theparagraph\@SepMark\@arabic\c@subparagraph}
+\renewenvironment{thebibliography}[1]
+ {\section*{\refname}%
+ \@mkboth{\MakeUppercase\refname}{\MakeUppercase\refname}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand*\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy\clubpenalty4000\widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+
+\renewcommand*\thepart{\@tartibi\c@part}
+\renewcommand*\appendix{\par
+ \setcounter{section}{0}%
+ \setcounter{subsection}{0}%
+ \gdef\thesection{\@harfi\c@section}}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-arydshln.sty b/macros/luatex/latex/simurgh/tex/simurgh-arydshln.sty
new file mode 100644
index 0000000000..5921767904
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-arydshln.sty
@@ -0,0 +1,90 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-arydshln}[2013/09/18 v0.01a changes to `arydshln.sty']
+\def\endarray{\adl@endarray \egroup \adl@arrayrestore \egroup}
+\def\endtabular{\endarray $\egroup\@RTLtabfalse}
+\expandafter\let\csname endtabular*\endcsname\endtabular
+\let\adl@array\@array
+\def\@array{\adl@everyvbox\everyvbox
+ \everyvbox{\adl@arrayinit \the\adl@everyvbox \everyvbox\adl@everyvbox}%
+ \ifadl@inactive \adl@inactivate \else \adl@activate \fi
+ \let\adl@noalign\noalign
+ \adl@array}
+\ifadl@usingarypkg
+\def\@testpach{\@chclass
+ \ifnum \@lastchclass=6 \@ne \@chnum \@ne \else
+ \ifnum \@lastchclass=7 5 \else
+ \ifnum \@lastchclass=8 \tw@ \else
+ \ifnum \@lastchclass=9 \thr@@
+ \else \z@
+ \ifnum \@lastchclass = 10 \else
+ \edef\@nextchar{\expandafter\string\@nextchar}%
+ \@chnum
+ \if \@nextchar c\z@ \else
+ \if \@nextchar \if@RTLtab r\else l\fi\@ne \else
+ \if \@nextchar \if@RTLtab l\else r\fi\tw@ \else
+ \z@ \@chclass
+ \if\@nextchar |\@ne \let\@arrayrule\adl@arrayrule \else
+ \if\@nextchar :\@ne \let\@arrayrule\adl@arraydashrule \else
+ \if\@nextchar ;\@ne \let\@arrayrule\adl@argarraydashrule \else
+ \if \@nextchar !6 \else
+ \if \@nextchar @7 \else
+ \if \@nextchar <8 \else
+ \if \@nextchar >9 \else
+ 10
+ \@chnum
+ \if \@nextchar m\thr@@\else
+ \if \@nextchar p4 \else
+ \if \@nextchar b5 \else
+ \z@ \@chclass \z@ \@preamerr \z@ \fi \fi \fi \fi \fi \fi
+ \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi}
+
+\def\@classz{\@classx
+ \@tempcnta \count@
+ \prepnext@tok
+ \@addtopreamble{\ifcase \@chnum
+ \hfil
+ \adl@putlrc{\d@llarbegin \insert@column \d@llarend}\hfil \or
+ \hskip1sp\adl@putlrc{\d@llarbegin \insert@column \d@llarend}\hfil \or
+ \hfil\hskip1sp\adl@putlrc{\d@llarbegin \insert@column \d@llarend}\or
+ \setbox\adl@box\hbox \adl@startmbox{\@nextchar}\insert@column
+ \adl@endmbox\or
+ \setbox\adl@box\vtop \@startpbox{\@nextchar}\insert@column \@endpbox \or
+ \setbox\adl@box\vbox \@startpbox{\@nextchar}\insert@column \@endpbox
+ \fi}\prepnext@tok}
+\def\adl@class@start{4}
+\def\adl@class@iiiorvii{7}
+
+\else
+\def\@testpach#1{\@chclass \ifnum \@lastchclass=\tw@ 4\relax \else
+ \ifnum \@lastchclass=\thr@@ 5\relax \else
+ \z@ \if #1c\@chnum \z@ \else
+ \if \if@RTLtab#1r\else#1l\fi\@chnum \@ne \else
+ \if \if@RTLtab#1l\else#1r\fi\@chnum \tw@ \else
+ \@chclass
+ \if #1|\@ne \let\@arrayrule\adl@arrayrule \else
+ \if #1:\@ne \let\@arrayrule\adl@arraydashrule \else
+ \if #1;\@ne \let\@arrayrule\adl@argarraydashrule \else
+ \if #1@\tw@ \else
+ \if #1p\thr@@ \else \z@ \@preamerr 0\fi
+ \fi \fi \fi \fi \fi \fi \fi \fi \fi}
+
+\def\@arrayclassz{\ifcase \@lastchclass \@acolampacol \or \@ampacol \or
+ \or \or \@addamp \or
+ \@acolampacol \or \@firstampfalse \@acol \fi
+ \edef\@preamble{\@preamble
+ \ifcase \@chnum
+ \hfil\adl@putlrc{$\relax\@sharp$}\hfil
+ \or \adl@putlrc{$\relax\@sharp$}\hfil
+ \or \hfil\adl@putlrc{$\relax\@sharp$}\fi}}
+\def\@tabclassz{\ifcase \@lastchclass \@acolampacol \or \@ampacol \or
+ \or \or \@addamp \or
+ \@acolampacol \or \@firstampfalse \@acol \fi
+ \edef\@preamble{\@preamble
+ \ifcase \@chnum
+ \hfil\adl@putlrc{\@sharp\unskip}\hfil
+ \or \adl@putlrc{\@sharp\unskip}\hfil
+ \or \hfil\hskip\z@ \adl@putlrc{\@sharp\unskip}\fi}}
+\def\adl@class@start{6}
+\def\adl@class@iiiorvii{3}
+\fi
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-backref.sty b/macros/luatex/latex/simurgh/tex/simurgh-backref.sty
new file mode 100644
index 0000000000..0c6aea1d30
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-backref.sty
@@ -0,0 +1,24 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-backref}[2013/09/18 v0.01a changes to `backref.sty']
+\def\backrefpagesname{\if@RTL صÙحات\else pages\fi}
+\def\BR@Latincitex[#1]#2{%
+ \BRorg@Latincitex[{#1}]{#2}%
+ \ifBR@verbose
+ \PackageInfo{backref}{back Latin cite \string`#2\string'}%
+ \fi
+ \Hy@backout{#2}%
+}
+\AtBeginDocument{%
+ \@ifundefined{NAT@parse}{%
+ \global\let\BRorg@Latincitex\@Latincitex
+ \global\let\@Latincitex\BR@Latincitex
+ }{%
+ \@ifpackageloaded{hyperref}{}{%
+ \def\hyper@natlinkstart#1{\Hy@backout{#1}}%
+ }%
+ \PackageInfo{backref}{** backref set up for natbib **}%
+ }%
+}%
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-bidi.sty b/macros/luatex/latex/simurgh/tex/simurgh-bidi.sty
new file mode 100644
index 0000000000..d7a0ded868
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-bidi.sty
@@ -0,0 +1,108 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-bidi}[2013/09/18 v0.01a bidirectional typesetting]
+\directlua { tex.enableprimitives('',{'pagedir','bodydir','pardir','textdir','mathdir','boxdir'}) }
+\newif\if@RTLmain
+\newif\if@RTL
+\newif\if@Latin
+\@RTLmainfalse
+\AtBeginDocument{%
+ \if@RTLmain\else
+ \if@RTL\@RTLmaintrue%
+ \else\@RTLmainfalse%
+ \fi%
+ \fi%
+}
+\let\simurgh@n@xt=\
+\simurgh@newrobustcmd*{\textLRE}{\protect\simurgh@ptextLRE}%
+\def\simurgh@ptextLRE{\protect\afterassignment\simurgh@moretextLRE \let\simurgh@n@xt= }
+\simurgh@newrobustcmd*{\textRLE}{\protect\simurgh@ptextRLE}
+\def\simurgh@ptextRLE{\protect\afterassignment\simurgh@moretextRLE \let\simurgh@n@xt= }
+\def\simurgh@bracetext{\ifcat\simurgh@n@xt{\else\ifcat\simurgh@n@xt}\fi
+ \simurgh@error{missing left brace has been substituted}{}\fi \bgroup}
+\def\simurgh@moretextLRE{\simurgh@bracetext \@RTLfalse\textdir TLT}
+\def\simurgh@moretextRLE{\simurgh@bracetext \@RTLtrue\textdir TRT}
+
+\simurgh@newrobustcmd*{\textLatin}[1]{\textLRE{\@Latintrue\latinmainfont #1}}
+\simurgh@newrobustcmd*{\textParsi}[1]{\textRLE{\@Latinfalse\parsimainfont #1}}
+
+\simurgh@newrobustcmd*{\LROtextdir}{\textdir TLT}
+\simurgh@newrobustcmd*{\RLOtextdir}{\textdir TRT}
+
+\protected\def\hboxR{\hbox\bgroup
+ \everyhbox{%
+ \aftergroup\egroup
+ \everyhbox{}%
+ \@RTLtrue%
+ \textdir TRT%
+ }\hbox dir TRT}
+\protected\def\hboxL{\hbox\bgroup
+ \everyhbox{%
+ \aftergroup\egroup
+ \everyhbox{}%
+ \@RTLfalse%
+ \textdir TLT%
+ }\hbox dir TLT}
+\protected\def\vboxR{\vbox\bgroup
+ \everyvbox{%
+ \aftergroup\egroup
+ \everyvbox{}%
+ \@RTLtrue%
+ }\vbox dir TRT}
+\protected\def\vboxL{\vbox\bgroup
+ \everyvbox{%
+ \aftergroup\egroup
+ \everyvbox{}%
+ \@RTLfalse%
+ }\vbox dir TLT}
+\protected\def\vtopR{\vtop\bgroup
+ \everyvbox{%
+ \aftergroup\egroup
+ \everyvbox{}%
+ \@RTLtrue%
+ }\vtop dir TRT}
+\protected\def\vtopL{\vtop\bgroup
+ \everyvbox{%
+ \aftergroup\egroup
+ \everyvbox{}%
+ \@RTLfalse%
+ }\vtop dir TLT}
+
+
+
+ \def\LTRpar{\par\@RTLfalse\@RTL@footnotefalse\pardir TLT \textdir TLT \hsize\linewidth\parshape\z@}
+\def\endLTRpar{\par}
+\def\RTLpar{\par\@RTLtrue\@RTL@footnotetrue\pardir TRT \textdir TRT \hsize\linewidth\parshape\z@}
+\let\endRTLpar\endLTRpar
+\def\setRTLpar{\@RTLtrue\@RTL@footnotetrue\pardir TRT \textdir TRT}
+\def\setLTRpar{\@RTLfalse\@RTL@footnotefalse\pardir TLT \textdir TLT}
+\let\unsetRTLpar\setLTRpar
+\let\unsetLTRpar\setRTLpar
+
+
+\def\latinpar{\LTRpar\LatinAlphs\@Latintrue\@RTL@footnotefalse\reset@latinfont}
+\let\endlatinpar\endLTRpar
+\def\parsipar{\RTLpar\ParsiAlphs\@RTL@footnotetrue\reset@parsifont}
+\let\endparsipar\endRTLpar
+
+\def\setRTLmath{\mathdir TRT}
+\def\setLTRmath{\mathdir TLT}
+\let\unsetRTLmath\setLTRmath
+\let\unsetLTRmath\setRTLmath
+
+\def\ensureRTLtext#1{\if@RTL#1\else\textRLE{#1}\fi}
+\def\ensureLTRtext#1{\if@RTL\textLRE{#1}\else#1\fi}
+\def\simurgh@par@RTL{RTL}
+\def\simurgh@par@LTR{LTR}
+\def\savepardir{\if@RTL\gdef\saved@par@dir{RTL}\else\gdef\saved@par@dir{LTR}\fi}
+\def\resetpardir{\ifx\saved@par@dir\simurgh@par@RTL\setRTLpar\else\ifx\saved@par@dir\simurgh@par@LTR\setLTRpar\else\relax\fi\fi}
+
+
+\def\ensureparsitext#1{\if@Latin\textParsi{#1}\else #1 \fi}
+\def\ensurelatintext#1{\if@Latin #1 \else\textLatin{#1}\fi}
+
+\long\def\ensuresboxdir#1#2{\if@RTL\setbox#1\hbox dir TRT{%
+ \color@setgroup#2\color@endgroup}\else%
+\setbox#1\hbox dir TLT{%
+ \color@setgroup#2\color@endgroup}\fi}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-boek.sty b/macros/luatex/latex/simurgh/tex/simurgh-boek.sty
new file mode 100644
index 0000000000..bdba43beb4
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-boek.sty
@@ -0,0 +1,72 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-boek}[2013/09/18 v0.01a changes to `boek.cls']
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \kern.5\baselineskip
+ \hrule\@width\unitindent
+ \kern.4\baselineskip}\hfil}
+}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \kern.5\baselineskip
+ \hrule\@width\unitindent
+ \kern.4\baselineskip}\hfil}
+}
+\renewenvironment{thebibliography}[1]
+ {\chapter*{\bibname}%
+ \@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand*\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy\clubpenalty4000\widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+\renewcommand*\thesection{\thechapter\@SepMark\@arabic\c@section}
+\renewcommand*\thesubsection{\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand*\thesubsubsection{\thesubsection\@SepMark\@arabic\c@subsubsection}
+\renewcommand*\theparagraph{\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand*\thesubparagraph{\theparagraph\@SepMark\@arabic\c@subparagraph}
+\renewcommand*\theequation{%
+ \ifnum \c@chapter>\z@ \thechapter\@SepMark\fi\@arabic\c@equation}
+\renewcommand*\thefigure{%
+ \ifnum\c@chapter>\z@\thechapter\@SepMark\fi\@arabic\c@figure}
+\renewcommand*\thetable{%
+ \ifnum\c@chapter>\z@\thechapter\@SepMark\fi\@arabic\c@table}
+
+
+
+\renewcommand*\thepart{\@tartibi\c@part}
+\renewcommand*\frontmatter{%
+ \cleardoublepage
+ \@mainmatterfalse
+ \pagenumbering{harfi}}
+\renewcommand*\appendix{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-boek3.sty b/macros/luatex/latex/simurgh/tex/simurgh-boek3.sty
new file mode 100644
index 0000000000..10689d342b
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-boek3.sty
@@ -0,0 +1,70 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-boek3}[2013/09/18 v0.01a changes to `boek3.cls']
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \kern.5\baselineskip
+ \hrule\@width\unitindent
+ \kern.4\baselineskip}\hfil}
+}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \kern.5\baselineskip
+ \hrule\@width\unitindent
+ \kern.4\baselineskip}\hfil}
+}
+\renewenvironment{thebibliography}[1]
+ {\chapter*{\bibname}%
+ \@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand*\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy\clubpenalty4000\widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+\renewcommand*\thesection{\thechapter\@SepMark\@arabic\c@section}
+\renewcommand*\thesubsection{\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand*\thesubsubsection{\thesubsection\@SepMark\@arabic\c@subsubsection}
+\renewcommand*\theparagraph{\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand*\thesubparagraph{\theparagraph\@SepMark\@arabic\c@subparagraph}
+\renewcommand*\theequation{%
+ \ifnum \c@chapter>\z@ \thechapter\@SepMark\fi\@arabic\c@equation}
+\renewcommand*\thefigure{%
+ \ifnum\c@chapter>\z@\thechapter\@SepMark\fi\@arabic\c@figure}
+\renewcommand*\thetable{%
+ \ifnum\c@chapter>\z@\thechapter\@SepMark\fi\@arabic\c@table}
+
+\renewcommand*\thepart{\@tartibi\c@part}
+\renewcommand*\frontmatter{%
+ \cleardoublepage
+ \@mainmatterfalse
+ \pagenumbering{harfi}}
+\renewcommand*\appendix{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-book.sty b/macros/luatex/latex/simurgh/tex/simurgh-book.sty
new file mode 100644
index 0000000000..87297d3d55
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-book.sty
@@ -0,0 +1,93 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-book}[2013/09/18 v0.01a changes to `book.cls']
+\renewcommand*{\left@footnoterule}{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern2.6\p@}\hfil}}
+\renewcommand*{\right@footnoterule}{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern2.6\p@}\hfil}}
+\renewcommand\theequation
+ {\ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@equation}
+\renewcommand \thefigure
+ {\ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@figure}
+\renewcommand \thetable
+ {\ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@table}
+\renewcommand \thechapter {\@arabic\c@chapter}
+\renewcommand \thesection {\thechapter\@SepMark\@arabic\c@section}
+\renewcommand\thesubsection {\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand\thesubsubsection{\thesubsection \@SepMark\@arabic\c@subsubsection}
+\renewcommand\theparagraph {\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand\thesubparagraph {\theparagraph\@SepMark\@arabic\c@subparagraph}
+\def\@makechapterhead#1{%
+ \vspace*{50\p@}%
+ {\parindent \z@ \simurgh@raggedright \normalfont
+ \ifnum \c@secnumdepth >\m@ne
+ \if@mainmatter
+ \huge\bfseries \@chapapp\space \thechapter
+ \par\nobreak
+ \vskip 20\p@
+ \fi
+ \fi
+ \interlinepenalty\@M
+ \Huge \bfseries #1\par\nobreak
+ \vskip 40\p@
+ }}
+\def\@makeschapterhead#1{%
+ \vspace*{50\p@}%
+ {\parindent \z@ \simurgh@raggedright
+ \normalfont
+ \interlinepenalty\@M
+ \Huge \bfseries #1\par\nobreak
+ \vskip 40\p@
+ }}
+\renewenvironment{thebibliography}[1]
+ {\chapter*{\bibname}%
+ \@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy
+ \clubpenalty4000
+ \@clubpenalty \clubpenalty
+ \widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+
+\renewcommand\frontmatter{%
+ \cleardoublepage
+ \@mainmatterfalse
+ \pagenumbering{harfi}}
+\renewcommand \thepart {\@tartibi\c@part}
+\renewcommand\appendix{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}
+}%end appendix
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-bookest.sty b/macros/luatex/latex/simurgh/tex/simurgh-bookest.sty
new file mode 100644
index 0000000000..edf43d6132
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-bookest.sty
@@ -0,0 +1,43 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-bookest}[2013/09/18 v0.01a changes to `bookest.cls']
+\def\@makechapterhead#1{%
+ \vspace*{20\p@}
+ {\parindent \z@ \simurgh@raggedright \normalfont
+ \ifnum \c@secnumdepth >\m@ne
+ \if@mainmatter
+ {\colorA\huge\scshape \@chapapp\space \thechapter}
+ \par\nobreak
+ \vskip 10\p@
+ \fi
+ \fi
+ \interlinepenalty\@M
+ {\colorB\hrule}
+ \vskip 15\p@
+ \if@RTL\begin{flushleft}\else\begin{flushright}\fi
+ {\colorA\Huge \bfseries #1}\par\nobreak
+ \if@RTL\end{flushleft}\else\end{flushright}\fi
+ \vskip 5\p@
+ {\colorB\hrule}
+ \vskip 30\p@
+ }}
+\def\@makeschapterhead#1{%
+ \vspace*{20\p@}
+ {\parindent \z@ \raggedright \normalfont
+ {\colorB\hrule}
+ \vskip 15\p@
+ \begin{center}
+ {\colorA\Huge \bfseries #1}\par\nobreak
+ \end{center}
+ \vskip 5\p@
+ {\colorB\hrule}
+ \vskip 30\p@
+ }}
+
+\renewcommand \thepart {\@tartibi\c@part}
+\renewcommand\appendix{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}
+}%end appendix
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-caption3.sty b/macros/luatex/latex/simurgh/tex/simurgh-caption3.sty
new file mode 100644
index 0000000000..37292fd4e3
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-caption3.sty
@@ -0,0 +1,7 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-caption3}[2013/09/18 v0.01a changes to `caption3.sty']
+
+\renewcommand*\caption@@par{%
+ \parindent\caption@parindent\hangindent\if@RTL\else -\fi\caption@hangindent}%
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-char-def.lua b/macros/luatex/latex/simurgh/tex/simurgh-char-def.lua
new file mode 100644
index 0000000000..0c05e77fe0
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-char-def.lua
@@ -0,0 +1,193863 @@
+if not modules then modules = { } end modules ['simurgh-char-def'] = {
+ version = 0.01,
+ comment = "chracter definition",
+ author = "Vafa Khalighi",
+ copyright = "Vafa Khalighi",
+ license = "see simurgh package documentation",
+ derived = "derived from char-def by Hans Hagen"
+}
+
+--[[
+The first version of this table was generated from unicode tables but after that was
+mostly updated manual using data present in ConTeXt and elsewhere. I did my best to
+make this table as complete as needed for proper use in ConTeXt MkIV. All errors are
+mine. If you find an error or ommision, just let me know. This file is updated every
+now and then using mtx-unicode where we check against the latest unicode txt files
+(normally once per year around the tex live code freeze) and checked afterwards for
+differences. We could save some bytes by sharing variant tables but it's not worth
+the trouble. Some additional data is kept in other files.
+]]--
+
+characters = characters or { }
+
+characters.data={
+ [0x0000]={
+ category="cc",
+ description="NULL",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0000,
+ },
+ {
+ adobename="controlSTX",
+ category="cc",
+ description="START OF HEADING",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0001,
+ },
+ {
+ adobename="controlSOT",
+ category="cc",
+ description="START OF TEXT",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0002,
+ },
+ {
+ adobename="controlETX",
+ category="cc",
+ description="END OF TEXT",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0003,
+ },
+ {
+ adobename="controlEOT",
+ category="cc",
+ description="END OF TRANSMISSION",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0004,
+ },
+ {
+ adobename="controlENQ",
+ category="cc",
+ description="ENQUIRY",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0005,
+ },
+ {
+ adobename="controlACK",
+ category="cc",
+ description="ACKNOWLEDGE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0006,
+ },
+ {
+ adobename="controlBEL",
+ category="cc",
+ description="BELL",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0007,
+ },
+ {
+ adobename="controlBS",
+ category="cc",
+ description="BACKSPACE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0008,
+ },
+ {
+ adobename="controlHT",
+ category="cc",
+ description="CHARACTER TABULATION",
+ direction="s",
+ linebreak="ba",
+ unicodeslot=0x0009,
+ },
+ {
+ adobename="controlLF",
+ category="cc",
+ description="LINE FEED (LF)",
+ direction="b",
+ linebreak="lf",
+ unicodeslot=0x000A,
+ },
+ {
+ adobename="controlVT",
+ category="cc",
+ description="LINE TABULATION",
+ direction="s",
+ linebreak="bk",
+ unicodeslot=0x000B,
+ },
+ {
+ adobename="controlFF",
+ category="cc",
+ description="FORM FEED (FF)",
+ direction="ws",
+ linebreak="bk",
+ unicodeslot=0x000C,
+ },
+ {
+ adobename="controlCR",
+ category="cc",
+ description="CARRIAGE RETURN (CR)",
+ direction="b",
+ linebreak="cr",
+ unicodeslot=0x000D,
+ },
+ {
+ adobename="controlSO",
+ category="cc",
+ description="SHIFT OUT",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x000E,
+ },
+ {
+ adobename="controlSI",
+ category="cc",
+ description="SHIFT IN",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x000F,
+ },
+ {
+ adobename="controlDLE",
+ category="cc",
+ description="DATA LINK ESCAPE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0010,
+ },
+ {
+ adobename="controlDC1",
+ category="cc",
+ description="DEVICE CONTROL ONE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0011,
+ },
+ {
+ adobename="controlDC2",
+ category="cc",
+ description="DEVICE CONTROL TWO",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0012,
+ },
+ {
+ adobename="controlDC3",
+ category="cc",
+ description="DEVICE CONTROL THREE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0013,
+ },
+ {
+ adobename="controlDC4",
+ category="cc",
+ description="DEVICE CONTROL FOUR",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0014,
+ },
+ {
+ adobename="controlNAK",
+ category="cc",
+ description="NEGATIVE ACKNOWLEDGE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0015,
+ },
+ {
+ adobename="controlSYN",
+ category="cc",
+ description="SYNCHRONOUS IDLE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0016,
+ },
+ {
+ adobename="controlETB",
+ category="cc",
+ description="END OF TRANSMISSION BLOCK",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0017,
+ },
+ {
+ adobename="controlCAN",
+ category="cc",
+ description="CANCEL",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0018,
+ },
+ {
+ adobename="controlEM",
+ category="cc",
+ description="END OF MEDIUM",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0019,
+ },
+ {
+ adobename="controlSUB",
+ category="cc",
+ description="SUBSTITUTE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x001A,
+ },
+ {
+ adobename="controlESC",
+ category="cc",
+ description="ESCAPE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x001B,
+ },
+ {
+ adobename="controlFS",
+ category="cc",
+ description="INFORMATION SEPARATOR FOUR",
+ direction="b",
+ linebreak="cm",
+ unicodeslot=0x001C,
+ },
+ {
+ adobename="controlGS",
+ category="cc",
+ description="INFORMATION SEPARATOR THREE",
+ direction="b",
+ linebreak="cm",
+ unicodeslot=0x001D,
+ },
+ {
+ adobename="controlRS",
+ category="cc",
+ description="INFORMATION SEPARATOR TWO",
+ direction="b",
+ linebreak="cm",
+ unicodeslot=0x001E,
+ },
+ {
+ adobename="controlUS",
+ category="cc",
+ description="INFORMATION SEPARATOR ONE",
+ direction="s",
+ linebreak="cm",
+ unicodeslot=0x001F,
+ },
+ {
+ adobename="space",
+ category="zs",
+ cjkwd="na",
+ description="SPACE",
+ direction="ws",
+ linebreak="sp",
+ unicodeslot=0x0020,
+ },
+ {
+ adobename="exclam",
+ category="po",
+ cjkwd="na",
+ description="EXCLAMATION MARK",
+ direction="on",
+ linebreak="ex",
+ mathclass="close",
+ unicodeslot=0x0021,
+ },
+ {
+ adobename="quotedbl",
+ category="po",
+ cjkwd="na",
+ contextname="quotedbl",
+ description="QUOTATION MARK",
+ direction="on",
+ linebreak="qu",
+ mathclass="default",
+ unicodeslot=0x0022,
+ },
+ {
+ adobename="numbersign",
+ category="po",
+ cjkwd="na",
+ description="NUMBER SIGN",
+ direction="et",
+ linebreak="al",
+ unicodeslot=0x0023,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ {
+ adobename="dollar",
+ category="sc",
+ cjkwd="na",
+ contextname="textdollar",
+ description="DOLLAR SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x0024,
+ },
+ {
+ adobename="percent",
+ category="po",
+ cjkwd="na",
+ contextname="percent",
+ description="PERCENT SIGN",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x0025,
+ },
+ {
+ adobename="ampersand",
+ category="po",
+ cjkwd="na",
+ description="AMPERSAND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0026,
+ },
+ {
+ adobename="quotesingle",
+ category="po",
+ cjkwd="na",
+ contextname="quotesingle",
+ description="APOSTROPHE",
+ direction="on",
+ linebreak="qu",
+ mathclass="default",
+ unicodeslot=0x0027,
+ },
+ {
+ adobename="parenleft",
+ category="ps",
+ cjkwd="na",
+ description="LEFT PARENTHESIS",
+ direction="on",
+ linebreak="op",
+ mathclass="open",
+ mathname="lparent",
+ mirror=0x0029,
+ textclass="open",
+ unicodeslot=0x0028,
+ },
+ {
+ adobename="parenright",
+ category="pe",
+ cjkwd="na",
+ description="RIGHT PARENTHESIS",
+ direction="on",
+ linebreak="cp",
+ mathclass="close",
+ mathname="rparent",
+ mirror=0x0028,
+ textclass="close",
+ unicodeslot=0x0029,
+ },
+ {
+ adobename="asterisk",
+ category="po",
+ cjkwd="na",
+ description="ASTERISK",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="ast",
+ mathsymbol=0x2217,
+ unicodeslot=0x002A,
+ },
+ {
+ adobename="plus",
+ category="sm",
+ cjkwd="na",
+ description="PLUS SIGN",
+ direction="es",
+ linebreak="pr",
+ mathclass="binary",
+ unicodeslot=0x002B,
+ },
+ {
+ adobename="comma",
+ category="po",
+ cjkwd="na",
+ contextname="textcomma",
+ description="COMMA",
+ direction="cs",
+ linebreak="is",
+ mathclass="punctuation",
+ unicodeslot=0x002C,
+ },
+ {
+ adobename="hyphen",
+ category="pd",
+ cjkwd="na",
+ description="HYPHEN-MINUS",
+ direction="es",
+ linebreak="hy",
+ mathextensible="h",
+ mathfiller="relfill",
+ mathsymbol=0x2212,
+ unicodeslot=0x002D,
+ },
+ {
+ adobename="period",
+ category="po",
+ cjkwd="na",
+ comment="class needed for autopunctuation",
+ contextname="textperiod",
+ description="FULL STOP",
+ direction="cs",
+ linebreak="is",
+ mathclass="punctuation",
+ mathspec={
+ {
+ class="punctuation",
+ name="ldotp",
+ },
+ },
+ unicodeslot=0x002E,
+ },
+ {
+ adobename="slash",
+ category="po",
+ cjkwd="na",
+ comment="mathsymbol=0x2044",
+ contextname="textslash",
+ description="SOLIDUS",
+ direction="cs",
+ linebreak="sy",
+ mathspec={
+ {
+ class="middle",
+ unicode=0x2044,
+ },
+ {
+ class="ordinary",
+ unicode=0x2044,
+ },
+ },
+ unicodeslot=0x002F,
+ },
+ {
+ adobename="zero",
+ category="nd",
+ cjkwd="na",
+ description="DIGIT ZERO",
+ direction="en",
+ linebreak="nu",
+ mathclass="number",
+ unicodeslot=0x0030,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ {
+ adobename="one",
+ category="nd",
+ cjkwd="na",
+ description="DIGIT ONE",
+ direction="en",
+ linebreak="nu",
+ mathclass="number",
+ unicodeslot=0x0031,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ {
+ adobename="two",
+ category="nd",
+ cjkwd="na",
+ description="DIGIT TWO",
+ direction="en",
+ linebreak="nu",
+ mathclass="number",
+ unicodeslot=0x0032,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ {
+ adobename="three",
+ category="nd",
+ cjkwd="na",
+ description="DIGIT THREE",
+ direction="en",
+ linebreak="nu",
+ mathclass="number",
+ unicodeslot=0x0033,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ {
+ adobename="four",
+ category="nd",
+ cjkwd="na",
+ description="DIGIT FOUR",
+ direction="en",
+ linebreak="nu",
+ mathclass="number",
+ unicodeslot=0x0034,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ {
+ adobename="five",
+ category="nd",
+ cjkwd="na",
+ description="DIGIT FIVE",
+ direction="en",
+ linebreak="nu",
+ mathclass="number",
+ unicodeslot=0x0035,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ {
+ adobename="six",
+ category="nd",
+ cjkwd="na",
+ description="DIGIT SIX",
+ direction="en",
+ linebreak="nu",
+ mathclass="number",
+ unicodeslot=0x0036,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ {
+ adobename="seven",
+ category="nd",
+ cjkwd="na",
+ description="DIGIT SEVEN",
+ direction="en",
+ linebreak="nu",
+ mathclass="number",
+ unicodeslot=0x0037,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ {
+ adobename="eight",
+ category="nd",
+ cjkwd="na",
+ description="DIGIT EIGHT",
+ direction="en",
+ linebreak="nu",
+ mathclass="number",
+ unicodeslot=0x0038,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ {
+ adobename="nine",
+ category="nd",
+ cjkwd="na",
+ description="DIGIT NINE",
+ direction="en",
+ linebreak="nu",
+ mathclass="number",
+ unicodeslot=0x0039,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ {
+ adobename="colon",
+ category="po",
+ cjkwd="na",
+ comment="mathclass=punctuation,mathname=colon",
+ description="COLON",
+ direction="cs",
+ linebreak="is",
+ mathclass="relation",
+ unicodeslot=0x003A,
+ },
+ {
+ adobename="semicolon",
+ category="po",
+ cjkwd="na",
+ description="SEMICOLON",
+ direction="on",
+ linebreak="is",
+ mathclass="punctuation",
+ unicodeslot=0x003B,
+ },
+ {
+ adobename="less",
+ category="sm",
+ cjkwd="na",
+ description="LESS-THAN SIGN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="lt",
+ mirror=0x003E,
+ textclass="open",
+ unicodeslot=0x003C,
+ },
+ {
+ adobename="equal",
+ category="sm",
+ cjkwd="na",
+ comment="mathclass=binary",
+ description="EQUALS SIGN",
+ direction="on",
+ linebreak="al",
+ mathextensible="h",
+ mathfiller="equalfill",
+ mathspec={
+ {
+ class="relation",
+ name="eq",
+ },
+ {
+ class="relation",
+ name="Relbar",
+ },
+ },
+ unicodeslot=0x003D,
+ },
+ {
+ adobename="greater",
+ category="sm",
+ cjkwd="na",
+ description="GREATER-THAN SIGN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="gt",
+ mirror=0x003C,
+ textclass="close",
+ unicodeslot=0x003E,
+ },
+ {
+ adobename="question",
+ category="po",
+ cjkwd="na",
+ description="QUESTION MARK",
+ direction="on",
+ linebreak="ex",
+ mathclass="close",
+ unicodeslot=0x003F,
+ },
+ {
+ adobename="at",
+ category="po",
+ cjkwd="na",
+ contextname="textat",
+ description="COMMERCIAL AT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0040,
+ },
+ {
+ adobename="A",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER A",
+ direction="l",
+ lccode=0x0061,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0041,
+ },
+ {
+ adobename="B",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER B",
+ direction="l",
+ lccode=0x0062,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0042,
+ },
+ {
+ adobename="C",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER C",
+ direction="l",
+ lccode=0x0063,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0043,
+ },
+ {
+ adobename="D",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER D",
+ direction="l",
+ lccode=0x0064,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0044,
+ },
+ {
+ adobename="E",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER E",
+ direction="l",
+ lccode=0x0065,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0045,
+ },
+ {
+ adobename="F",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER F",
+ direction="l",
+ lccode=0x0066,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0046,
+ },
+ {
+ adobename="G",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER G",
+ direction="l",
+ lccode=0x0067,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0047,
+ },
+ {
+ adobename="H",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER H",
+ direction="l",
+ lccode=0x0068,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0048,
+ },
+ {
+ adobename="I",
+ category="lu",
+ cjkwd="na",
+ contextname="dotlessI",
+ description="LATIN CAPITAL LETTER I",
+ direction="l",
+ lccode=0x0069,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0049,
+ },
+ {
+ adobename="J",
+ category="lu",
+ cjkwd="na",
+ contextname="dotlessJ",
+ description="LATIN CAPITAL LETTER J",
+ direction="l",
+ lccode=0x006A,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x004A,
+ },
+ {
+ adobename="K",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER K",
+ direction="l",
+ lccode=0x006B,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x004B,
+ },
+ {
+ adobename="L",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER L",
+ direction="l",
+ lccode=0x006C,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x004C,
+ },
+ {
+ adobename="M",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER M",
+ direction="l",
+ lccode=0x006D,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x004D,
+ },
+ {
+ adobename="N",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER N",
+ direction="l",
+ lccode=0x006E,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x004E,
+ },
+ {
+ adobename="O",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER O",
+ direction="l",
+ lccode=0x006F,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x004F,
+ },
+ {
+ adobename="P",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER P",
+ direction="l",
+ lccode=0x0070,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0050,
+ },
+ {
+ adobename="Q",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER Q",
+ direction="l",
+ lccode=0x0071,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0051,
+ },
+ {
+ adobename="R",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER R",
+ direction="l",
+ lccode=0x0072,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0052,
+ },
+ {
+ adobename="S",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER S",
+ direction="l",
+ lccode=0x0073,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0053,
+ },
+ {
+ adobename="T",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER T",
+ direction="l",
+ lccode=0x0074,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0054,
+ },
+ {
+ adobename="U",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER U",
+ direction="l",
+ lccode=0x0075,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0055,
+ },
+ {
+ adobename="V",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER V",
+ direction="l",
+ lccode=0x0076,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0056,
+ },
+ {
+ adobename="W",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER W",
+ direction="l",
+ lccode=0x0077,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0057,
+ },
+ {
+ adobename="X",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER X",
+ direction="l",
+ lccode=0x0078,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0058,
+ },
+ {
+ adobename="Y",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER Y",
+ direction="l",
+ lccode=0x0079,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x0059,
+ },
+ {
+ adobename="Z",
+ category="lu",
+ cjkwd="na",
+ description="LATIN CAPITAL LETTER Z",
+ direction="l",
+ lccode=0x007A,
+ linebreak="al",
+ mathclass="variable",
+ unicodeslot=0x005A,
+ },
+ {
+ adobename="bracketleft",
+ category="ps",
+ cjkwd="na",
+ description="LEFT SQUARE BRACKET",
+ direction="on",
+ linebreak="op",
+ mathclass="open",
+ mathname="lbracket",
+ mirror=0x005D,
+ textclass="open",
+ unicodeslot=0x005B,
+ },
+ {
+ adobename="backslash",
+ category="po",
+ cjkwd="na",
+ contextname="textbackslash",
+ description="REVERSE SOLIDUS",
+ direction="on",
+ linebreak="pr",
+ mathclass="nothing",
+ mathname="backslash",
+ unicodeslot=0x005C,
+ },
+ {
+ adobename="bracketright",
+ category="pe",
+ cjkwd="na",
+ description="RIGHT SQUARE BRACKET",
+ direction="on",
+ linebreak="cp",
+ mathclass="close",
+ mathname="rbracket",
+ mirror=0x005B,
+ textclass="close",
+ unicodeslot=0x005D,
+ },
+ {
+ adobename="asciicircum",
+ category="sk",
+ cjkwd="na",
+ contextname="textasciicircum",
+ description="CIRCUMFLEX ACCENT",
+ direction="on",
+ linebreak="al",
+ mathclass="topaccent",
+ unicodeslot=0x005E,
+ },
+ {
+ adobename="underscore",
+ category="pc",
+ cjkwd="na",
+ contextname="textunderscore",
+ description="LOW LINE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x005F,
+ },
+ {
+ adobename="grave",
+ category="sk",
+ cjkwd="na",
+ contextname="textgrave",
+ description="GRAVE ACCENT",
+ direction="on",
+ linebreak="al",
+ mathclass="topaccent",
+ mathname="grave",
+ unicodeslot=0x0060,
+ },
+ {
+ adobename="a",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER A",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0041,
+ unicodeslot=0x0061,
+ },
+ {
+ adobename="b",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER B",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0042,
+ unicodeslot=0x0062,
+ },
+ {
+ adobename="c",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER C",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0043,
+ unicodeslot=0x0063,
+ },
+ {
+ adobename="d",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER D",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0044,
+ unicodeslot=0x0064,
+ },
+ {
+ adobename="e",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER E",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0045,
+ unicodeslot=0x0065,
+ },
+ {
+ adobename="f",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER F",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0046,
+ unicodeslot=0x0066,
+ },
+ {
+ adobename="g",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER G",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0047,
+ unicodeslot=0x0067,
+ },
+ {
+ adobename="h",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER H",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0048,
+ unicodeslot=0x0068,
+ },
+ {
+ adobename="i",
+ category="ll",
+ cjkwd="na",
+ contextname="idotaccent",
+ description="LATIN SMALL LETTER I",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0049,
+ unicodeslot=0x0069,
+ },
+ {
+ adobename="j",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER J",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x004A,
+ unicodeslot=0x006A,
+ },
+ {
+ adobename="k",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER K",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x004B,
+ unicodeslot=0x006B,
+ },
+ {
+ adobename="l",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER L",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x004C,
+ unicodeslot=0x006C,
+ },
+ {
+ adobename="m",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER M",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x004D,
+ unicodeslot=0x006D,
+ },
+ {
+ adobename="n",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER N",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x004E,
+ unicodeslot=0x006E,
+ },
+ {
+ adobename="o",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER O",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x004F,
+ unicodeslot=0x006F,
+ },
+ {
+ adobename="p",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER P",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0050,
+ unicodeslot=0x0070,
+ },
+ {
+ adobename="q",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER Q",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0051,
+ unicodeslot=0x0071,
+ },
+ {
+ adobename="r",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER R",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0052,
+ unicodeslot=0x0072,
+ },
+ {
+ adobename="s",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER S",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0053,
+ unicodeslot=0x0073,
+ },
+ {
+ adobename="t",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER T",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0054,
+ unicodeslot=0x0074,
+ },
+ {
+ adobename="u",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER U",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0055,
+ unicodeslot=0x0075,
+ },
+ {
+ adobename="v",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER V",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0056,
+ unicodeslot=0x0076,
+ },
+ {
+ adobename="w",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER W",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0057,
+ unicodeslot=0x0077,
+ },
+ {
+ adobename="x",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER X",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0058,
+ unicodeslot=0x0078,
+ },
+ {
+ adobename="y",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER Y",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x0059,
+ unicodeslot=0x0079,
+ },
+ {
+ adobename="z",
+ category="ll",
+ cjkwd="na",
+ description="LATIN SMALL LETTER Z",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ uccode=0x005A,
+ unicodeslot=0x007A,
+ },
+ {
+ adobename="braceleft",
+ category="ps",
+ cjkwd="na",
+ contextname="textbraceleft",
+ description="LEFT CURLY BRACKET",
+ direction="on",
+ linebreak="op",
+ mathclass="open",
+ mathname="lbrace",
+ mirror=0x007D,
+ textclass="open",
+ unicodeslot=0x007B,
+ },
+ {
+ adobename="verticalbar",
+ category="sm",
+ cjkwd="na",
+ comment="mathclass=binary,mathname=bar",
+ contextname="textbar",
+ description="VERTICAL LINE",
+ direction="on",
+ linebreak="ba",
+ mathspec={
+ {
+ class="nothing",
+ name="arrowvert",
+ },
+ {
+ class="delimiter",
+ name="vert",
+ },
+ {
+ class="open",
+ name="lvert",
+ },
+ {
+ class="close",
+ name="rvert",
+ },
+ {
+ class="relation",
+ name="mid",
+ },
+ },
+ unicodeslot=0x007C,
+ },
+ {
+ adobename="braceright",
+ category="pe",
+ cjkwd="na",
+ contextname="textbraceright",
+ description="RIGHT CURLY BRACKET",
+ direction="on",
+ linebreak="cl",
+ mathclass="close",
+ mathname="rbrace",
+ mirror=0x007B,
+ textclass="close",
+ unicodeslot=0x007D,
+ },
+ {
+ adobename="asciitilde",
+ category="sm",
+ cjkwd="na",
+ contextname="textasciitilde",
+ description="TILDE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x007E,
+ },
+ {
+ adobename="controlDEL",
+ category="cc",
+ description="DELETE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x007F,
+ },
+ {
+ category="cc",
+ description="NONE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0080,
+ },
+ {
+ category="cc",
+ description="NONE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0081,
+ },
+ {
+ category="cc",
+ description="BREAK PERMITTED HERE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0082,
+ },
+ {
+ category="cc",
+ description="NO BREAK HERE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0083,
+ },
+ {
+ category="cc",
+ description="NONE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0084,
+ },
+ {
+ category="cc",
+ description="NEXT LINE (NEL)",
+ direction="b",
+ linebreak="nl",
+ unicodeslot=0x0085,
+ },
+ {
+ category="cc",
+ description="START OF SELECTED AREA",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0086,
+ },
+ {
+ category="cc",
+ description="END OF SELECTED AREA",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0087,
+ },
+ {
+ category="cc",
+ description="CHARACTER TABULATION SET",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0088,
+ },
+ {
+ category="cc",
+ description="CHARACTER TABULATION WITH JUSTIFICATION",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0089,
+ },
+ {
+ category="cc",
+ description="LINE TABULATION SET",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x008A,
+ },
+ {
+ category="cc",
+ description="PARTIAL LINE FORWARD",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x008B,
+ },
+ {
+ category="cc",
+ description="PARTIAL LINE BACKWARD",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x008C,
+ },
+ {
+ category="cc",
+ description="REVERSE LINE FEED",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x008D,
+ },
+ {
+ category="cc",
+ description="SINGLE SHIFT TWO",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x008E,
+ },
+ {
+ category="cc",
+ description="SINGLE SHIFT THREE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x008F,
+ },
+ {
+ category="cc",
+ description="DEVICE CONTROL STRING",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0090,
+ },
+ {
+ category="cc",
+ description="PRIVATE USE ONE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0091,
+ },
+ {
+ category="cc",
+ description="PRIVATE USE TWO",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0092,
+ },
+ {
+ category="cc",
+ description="SET TRANSMIT STATE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0093,
+ },
+ {
+ category="cc",
+ description="CANCEL CHARACTER",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0094,
+ },
+ {
+ category="cc",
+ description="MESSAGE WAITING",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0095,
+ },
+ {
+ category="cc",
+ description="START OF GUARDED AREA",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0096,
+ },
+ {
+ category="cc",
+ description="END OF GUARDED AREA",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0097,
+ },
+ {
+ category="cc",
+ description="START OF STRING",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0098,
+ },
+ {
+ category="cc",
+ description="NONE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x0099,
+ },
+ {
+ category="cc",
+ description="SINGLE CHARACTER INTRODUCER",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x009A,
+ },
+ {
+ category="cc",
+ description="CONTROL SEQUENCE INTRODUCER",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x009B,
+ },
+ {
+ category="cc",
+ description="STRING TERMINATOR",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x009C,
+ },
+ {
+ category="cc",
+ description="OPERATING SYSTEM COMMAND",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x009D,
+ },
+ {
+ category="cc",
+ description="PRIVACY MESSAGE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x009E,
+ },
+ {
+ category="cc",
+ description="APPLICATION PROGRAM COMMAND",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x009F,
+ },
+ {
+ adobename="nonbreakingspace",
+ category="zs",
+ contextname="nobreakspace",
+ description="NO-BREAK SPACE",
+ direction="cs",
+ linebreak="gl",
+ specials={ "nobreak", 0x0020 },
+ unicodeslot=0x00A0,
+ },
+ {
+ adobename="exclamdown",
+ category="po",
+ cjkwd="a",
+ contextname="exclamdown",
+ description="INVERTED EXCLAMATION MARK",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0x00A1,
+ },
+ {
+ adobename="cent",
+ category="sc",
+ cjkwd="na",
+ contextname="textcent",
+ description="CENT SIGN",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x00A2,
+ },
+ {
+ adobename="sterling",
+ category="sc",
+ cjkwd="na",
+ contextname="textsterling",
+ description="POUND SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x00A3,
+ },
+ {
+ adobename="currency",
+ category="sc",
+ cjkwd="a",
+ contextname="textcurrency",
+ description="CURRENCY SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x00A4,
+ },
+ {
+ adobename="yen",
+ category="sc",
+ cjkwd="na",
+ contextname="textyen",
+ description="YEN SIGN",
+ direction="et",
+ linebreak="pr",
+ mathclass="nothing",
+ mathname="yen",
+ unicodeslot=0x00A5,
+ },
+ {
+ adobename="brokenbar",
+ category="so",
+ cjkwd="na",
+ contextname="textbrokenbar",
+ description="BROKEN BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x00A6,
+ },
+ {
+ adobename="section",
+ category="so",
+ cjkwd="a",
+ contextname="sectionmark",
+ description="SECTION SIGN",
+ direction="on",
+ linebreak="ai",
+ mathclass="box",
+ mathname="S",
+ unicodeslot=0x00A7,
+ },
+ {
+ adobename="dieresis",
+ category="sk",
+ cjkwd="a",
+ contextname="textdiaeresis",
+ description="DIAERESIS",
+ direction="on",
+ linebreak="ai",
+ mathclass="topaccent",
+ mathname="ddot",
+ specials={ "compat", 0x0020, 0x0308 },
+ unicodeslot=0x00A8,
+ },
+ {
+ adobename="copyright",
+ category="so",
+ contextname="copyright",
+ description="COPYRIGHT SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x00A9,
+ },
+ {
+ adobename="ordfeminine",
+ category="ll",
+ cjkwd="a",
+ contextname="ordfeminine",
+ description="FEMININE ORDINAL INDICATOR",
+ direction="l",
+ linebreak="ai",
+ specials={ "super", 0x0061 },
+ unicodeslot=0x00AA,
+ },
+ {
+ adobename="guillemotleft",
+ category="pi",
+ contextname="leftguillemot",
+ description="LEFT-POINTING DOUBLE ANGLE QUOTATION MARK",
+ direction="on",
+ linebreak="qu",
+ mirror=0x00BB,
+ textclass="open",
+ unicodeslot=0x00AB,
+ },
+ {
+ adobename="logicalnot",
+ category="sm",
+ cjkwd="na",
+ contextname="textlognot",
+ description="NOT SIGN",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="ordinary",
+ name="lnot",
+ },
+ {
+ class="ordinary",
+ name="neg",
+ },
+ },
+ unicodeslot=0x00AC,
+ },
+ {
+ adobename="softhyphen",
+ category="cf",
+ cjkwd="a",
+ contextname="softhyphen",
+ description="SOFT HYPHEN",
+ direction="bn",
+ linebreak="ba",
+ unicodeslot=0x00AD,
+ },
+ {
+ adobename="registered",
+ category="so",
+ cjkwd="a",
+ contextname="registered",
+ description="REGISTERED SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x00AE,
+ },
+ {
+ adobename="macron",
+ category="sk",
+ cjkwd="na",
+ contextname="textmacron",
+ description="MACRON",
+ direction="on",
+ linebreak="al",
+ mathclass="topaccent",
+ mathname="bar",
+ specials={ "compat", 0x0020, 0x0304 },
+ unicodeslot=0x00AF,
+ },
+ {
+ adobename="degree",
+ category="so",
+ cjkwd="a",
+ contextname="textdegree",
+ description="DEGREE SIGN",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x00B0,
+ },
+ {
+ adobename="plusminus",
+ category="sm",
+ cjkwd="a",
+ contextname="textpm",
+ description="PLUS-MINUS SIGN",
+ direction="et",
+ linebreak="pr",
+ mathclass="binary",
+ mathname="pm",
+ unicodeslot=0x00B1,
+ },
+ {
+ adobename="twosuperior",
+ category="no",
+ cjkwd="a",
+ contextname="twosuperior",
+ description="SUPERSCRIPT TWO",
+ direction="en",
+ linebreak="ai",
+ specials={ "super", 0x0032 },
+ unicodeslot=0x00B2,
+ },
+ {
+ adobename="threesuperior",
+ category="no",
+ cjkwd="a",
+ contextname="threesuperior",
+ description="SUPERSCRIPT THREE",
+ direction="en",
+ linebreak="ai",
+ specials={ "super", 0x0033 },
+ unicodeslot=0x00B3,
+ },
+ {
+ adobename="acute",
+ category="sk",
+ cjkwd="a",
+ contextname="textacute",
+ description="ACUTE ACCENT",
+ direction="on",
+ linebreak="bb",
+ mathclass="topaccent",
+ mathname="acute",
+ specials={ "compat", 0x0020, 0x0301 },
+ unicodeslot=0x00B4,
+ },
+ {
+ adobename="mu1",
+ category="ll",
+ contextname="textmu",
+ description="MICRO SIGN",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x03BC },
+ uccode=0x039C,
+ unicodeslot=0x00B5,
+ },
+ {
+ adobename="paragraph",
+ category="so",
+ cjkwd="a",
+ contextname="paragraphmark",
+ description="PILCROW SIGN",
+ direction="on",
+ linebreak="ai",
+ mathclass="box",
+ mathname="P",
+ unicodeslot=0x00B6,
+ },
+ {
+ adobename="periodcentered",
+ category="po",
+ cjkwd="a",
+ contextname="periodcentered",
+ description="MIDDLE DOT",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="centerdot",
+ unicodeslot=0x00B7,
+ },
+ {
+ adobename="cedilla",
+ category="sk",
+ cjkwd="a",
+ contextname="textcedilla",
+ description="CEDILLA",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0020, 0x0327 },
+ unicodeslot=0x00B8,
+ },
+ {
+ adobename="onesuperior",
+ category="no",
+ cjkwd="a",
+ contextname="onesuperior",
+ description="SUPERSCRIPT ONE",
+ direction="en",
+ linebreak="ai",
+ specials={ "super", 0x0031 },
+ unicodeslot=0x00B9,
+ },
+ {
+ adobename="ordmasculine",
+ category="ll",
+ cjkwd="a",
+ contextname="ordmasculine",
+ description="MASCULINE ORDINAL INDICATOR",
+ direction="l",
+ linebreak="ai",
+ specials={ "super", 0x006F },
+ unicodeslot=0x00BA,
+ },
+ {
+ adobename="guillemotright",
+ category="pf",
+ contextname="rightguillemot",
+ description="RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK",
+ direction="on",
+ linebreak="qu",
+ mirror=0x00AB,
+ textclass="close",
+ unicodeslot=0x00BB,
+ },
+ {
+ adobename="onequarter",
+ category="no",
+ cjkwd="a",
+ contextname="onequarter",
+ description="VULGAR FRACTION ONE QUARTER",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x0031, 0x2044, 0x0034 },
+ unicodeslot=0x00BC,
+ },
+ {
+ adobename="onehalf",
+ category="no",
+ cjkwd="a",
+ contextname="onehalf",
+ description="VULGAR FRACTION ONE HALF",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x0031, 0x2044, 0x0032 },
+ unicodeslot=0x00BD,
+ },
+ {
+ adobename="threequarters",
+ category="no",
+ cjkwd="a",
+ contextname="threequarter",
+ description="VULGAR FRACTION THREE QUARTERS",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x0033, 0x2044, 0x0034 },
+ unicodeslot=0x00BE,
+ },
+ {
+ adobename="questiondown",
+ category="po",
+ cjkwd="a",
+ contextname="questiondown",
+ description="INVERTED QUESTION MARK",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0x00BF,
+ },
+ {
+ adobename="Agrave",
+ category="lu",
+ contextname="Agrave",
+ description="LATIN CAPITAL LETTER A WITH GRAVE",
+ direction="l",
+ lccode=0x00E0,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0300 },
+ unicodeslot=0x00C0,
+ },
+ {
+ adobename="Aacute",
+ category="lu",
+ contextname="Aacute",
+ description="LATIN CAPITAL LETTER A WITH ACUTE",
+ direction="l",
+ lccode=0x00E1,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0301 },
+ unicodeslot=0x00C1,
+ },
+ {
+ adobename="Acircumflex",
+ category="lu",
+ contextname="Acircumflex",
+ description="LATIN CAPITAL LETTER A WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x00E2,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0302 },
+ unicodeslot=0x00C2,
+ },
+ {
+ adobename="Atilde",
+ category="lu",
+ contextname="Atilde",
+ description="LATIN CAPITAL LETTER A WITH TILDE",
+ direction="l",
+ lccode=0x00E3,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0303 },
+ unicodeslot=0x00C3,
+ },
+ {
+ adobename="Adieresis",
+ category="lu",
+ contextname="Adiaeresis",
+ description="LATIN CAPITAL LETTER A WITH DIAERESIS",
+ direction="l",
+ lccode=0x00E4,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0308 },
+ unicodeslot=0x00C4,
+ },
+ {
+ adobename="Aring",
+ category="lu",
+ contextname="Aring",
+ description="LATIN CAPITAL LETTER A WITH RING ABOVE",
+ direction="l",
+ lccode=0x00E5,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x030A },
+ unicodeslot=0x00C5,
+ },
+ {
+ adobename="AE",
+ category="lu",
+ cjkwd="a",
+ contextname="AEligature",
+ description="LATIN CAPITAL LETTER AE",
+ direction="l",
+ lccode=0x00E6,
+ linebreak="al",
+ shcode={ 0x0041, 0x0045 },
+ unicodeslot=0x00C6,
+ },
+ {
+ adobename="Ccedilla",
+ category="lu",
+ contextname="Ccedilla",
+ description="LATIN CAPITAL LETTER C WITH CEDILLA",
+ direction="l",
+ lccode=0x00E7,
+ linebreak="al",
+ shcode=0x0043,
+ specials={ "char", 0x0043, 0x0327 },
+ unicodeslot=0x00C7,
+ },
+ {
+ adobename="Egrave",
+ category="lu",
+ contextname="Egrave",
+ description="LATIN CAPITAL LETTER E WITH GRAVE",
+ direction="l",
+ lccode=0x00E8,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0300 },
+ unicodeslot=0x00C8,
+ },
+ {
+ adobename="Eacute",
+ category="lu",
+ contextname="Eacute",
+ description="LATIN CAPITAL LETTER E WITH ACUTE",
+ direction="l",
+ lccode=0x00E9,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0301 },
+ unicodeslot=0x00C9,
+ },
+ {
+ adobename="Ecircumflex",
+ category="lu",
+ contextname="Ecircumflex",
+ description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x00EA,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0302 },
+ unicodeslot=0x00CA,
+ },
+ {
+ adobename="Edieresis",
+ category="lu",
+ contextname="Ediaeresis",
+ description="LATIN CAPITAL LETTER E WITH DIAERESIS",
+ direction="l",
+ lccode=0x00EB,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0308 },
+ unicodeslot=0x00CB,
+ },
+ {
+ adobename="Igrave",
+ category="lu",
+ contextname="Igrave",
+ description="LATIN CAPITAL LETTER I WITH GRAVE",
+ direction="l",
+ lccode=0x00EC,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0300 },
+ unicodeslot=0x00CC,
+ },
+ {
+ adobename="Iacute",
+ category="lu",
+ contextname="Iacute",
+ description="LATIN CAPITAL LETTER I WITH ACUTE",
+ direction="l",
+ lccode=0x00ED,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0301 },
+ unicodeslot=0x00CD,
+ },
+ {
+ adobename="Icircumflex",
+ category="lu",
+ contextname="Icircumflex",
+ description="LATIN CAPITAL LETTER I WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x00EE,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0302 },
+ unicodeslot=0x00CE,
+ },
+ {
+ adobename="Idieresis",
+ category="lu",
+ contextname="Idiaeresis",
+ description="LATIN CAPITAL LETTER I WITH DIAERESIS",
+ direction="l",
+ lccode=0x00EF,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0308 },
+ unicodeslot=0x00CF,
+ },
+ {
+ adobename="Eth",
+ category="lu",
+ cjkwd="a",
+ contextname="Eth",
+ description="LATIN CAPITAL LETTER ETH",
+ direction="l",
+ lccode=0x00F0,
+ linebreak="al",
+ unicodeslot=0x00D0,
+ },
+ {
+ adobename="Ntilde",
+ category="lu",
+ contextname="Ntilde",
+ description="LATIN CAPITAL LETTER N WITH TILDE",
+ direction="l",
+ lccode=0x00F1,
+ linebreak="al",
+ shcode=0x004E,
+ specials={ "char", 0x004E, 0x0303 },
+ unicodeslot=0x00D1,
+ },
+ {
+ adobename="Ograve",
+ category="lu",
+ contextname="Ograve",
+ description="LATIN CAPITAL LETTER O WITH GRAVE",
+ direction="l",
+ lccode=0x00F2,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x0300 },
+ unicodeslot=0x00D2,
+ },
+ {
+ adobename="Oacute",
+ category="lu",
+ contextname="Oacute",
+ description="LATIN CAPITAL LETTER O WITH ACUTE",
+ direction="l",
+ lccode=0x00F3,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x0301 },
+ unicodeslot=0x00D3,
+ },
+ {
+ adobename="Ocircumflex",
+ category="lu",
+ contextname="Ocircumflex",
+ description="LATIN CAPITAL LETTER O WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x00F4,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x0302 },
+ unicodeslot=0x00D4,
+ },
+ {
+ adobename="Otilde",
+ category="lu",
+ contextname="Otilde",
+ description="LATIN CAPITAL LETTER O WITH TILDE",
+ direction="l",
+ lccode=0x00F5,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x0303 },
+ unicodeslot=0x00D5,
+ },
+ {
+ adobename="Odieresis",
+ category="lu",
+ contextname="Odiaeresis",
+ description="LATIN CAPITAL LETTER O WITH DIAERESIS",
+ direction="l",
+ lccode=0x00F6,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x0308 },
+ unicodeslot=0x00D6,
+ },
+ {
+ adobename="multiply",
+ category="sm",
+ cjkwd="a",
+ contextname="textmultiply",
+ description="MULTIPLICATION SIGN",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="times",
+ unicodeslot=0x00D7,
+ },
+ {
+ adobename="Oslash",
+ category="lu",
+ cjkwd="a",
+ contextname="Ostroke",
+ description="LATIN CAPITAL LETTER O WITH STROKE",
+ direction="l",
+ lccode=0x00F8,
+ linebreak="al",
+ shcode=0x004F,
+ unicodeslot=0x00D8,
+ },
+ {
+ adobename="Ugrave",
+ category="lu",
+ contextname="Ugrave",
+ description="LATIN CAPITAL LETTER U WITH GRAVE",
+ direction="l",
+ lccode=0x00F9,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0300 },
+ unicodeslot=0x00D9,
+ },
+ {
+ adobename="Uacute",
+ category="lu",
+ contextname="Uacute",
+ description="LATIN CAPITAL LETTER U WITH ACUTE",
+ direction="l",
+ lccode=0x00FA,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0301 },
+ unicodeslot=0x00DA,
+ },
+ {
+ adobename="Ucircumflex",
+ category="lu",
+ contextname="Ucircumflex",
+ description="LATIN CAPITAL LETTER U WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x00FB,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0302 },
+ unicodeslot=0x00DB,
+ },
+ {
+ adobename="Udieresis",
+ category="lu",
+ contextname="Udiaeresis",
+ description="LATIN CAPITAL LETTER U WITH DIAERESIS",
+ direction="l",
+ lccode=0x00FC,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0308 },
+ unicodeslot=0x00DC,
+ },
+ {
+ adobename="Yacute",
+ category="lu",
+ contextname="Yacute",
+ description="LATIN CAPITAL LETTER Y WITH ACUTE",
+ direction="l",
+ lccode=0x00FD,
+ linebreak="al",
+ shcode=0x0059,
+ specials={ "char", 0x0059, 0x0301 },
+ unicodeslot=0x00DD,
+ },
+ {
+ adobename="Thorn",
+ category="lu",
+ cjkwd="a",
+ contextname="Thorn",
+ description="LATIN CAPITAL LETTER THORN",
+ direction="l",
+ lccode=0x00FE,
+ linebreak="al",
+ unicodeslot=0x00DE,
+ },
+ {
+ adobename="germandbls",
+ category="ll",
+ cjkwd="a",
+ contextname="ssharp",
+ description="LATIN SMALL LETTER SHARP S",
+ direction="l",
+ linebreak="al",
+ uccode={ 0x0053, 0x0053 },
+ unicodeslot=0x00DF,
+ },
+ {
+ adobename="agrave",
+ category="ll",
+ cjkwd="a",
+ contextname="agrave",
+ description="LATIN SMALL LETTER A WITH GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0300 },
+ uccode=0x00C0,
+ unicodeslot=0x00E0,
+ },
+ {
+ adobename="aacute",
+ category="ll",
+ cjkwd="a",
+ contextname="aacute",
+ description="LATIN SMALL LETTER A WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0301 },
+ uccode=0x00C1,
+ unicodeslot=0x00E1,
+ },
+ {
+ adobename="acircumflex",
+ category="ll",
+ contextname="acircumflex",
+ description="LATIN SMALL LETTER A WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0302 },
+ uccode=0x00C2,
+ unicodeslot=0x00E2,
+ },
+ {
+ adobename="atilde",
+ category="ll",
+ contextname="atilde",
+ description="LATIN SMALL LETTER A WITH TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0303 },
+ uccode=0x00C3,
+ unicodeslot=0x00E3,
+ },
+ {
+ adobename="adieresis",
+ category="ll",
+ contextname="adiaeresis",
+ description="LATIN SMALL LETTER A WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0308 },
+ uccode=0x00C4,
+ unicodeslot=0x00E4,
+ },
+ {
+ adobename="aring",
+ category="ll",
+ contextname="aring",
+ description="LATIN SMALL LETTER A WITH RING ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x030A },
+ uccode=0x00C5,
+ unicodeslot=0x00E5,
+ },
+ {
+ adobename="ae",
+ category="ll",
+ cjkwd="a",
+ contextname="aeligature",
+ description="LATIN SMALL LETTER AE",
+ direction="l",
+ linebreak="al",
+ shcode={ 0x0061, 0x0065 },
+ uccode=0x00C6,
+ unicodeslot=0x00E6,
+ },
+ {
+ adobename="ccedilla",
+ category="ll",
+ contextname="ccedilla",
+ description="LATIN SMALL LETTER C WITH CEDILLA",
+ direction="l",
+ linebreak="al",
+ shcode=0x0063,
+ specials={ "char", 0x0063, 0x0327 },
+ uccode=0x00C7,
+ unicodeslot=0x00E7,
+ },
+ {
+ adobename="egrave",
+ category="ll",
+ cjkwd="a",
+ contextname="egrave",
+ description="LATIN SMALL LETTER E WITH GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0300 },
+ uccode=0x00C8,
+ unicodeslot=0x00E8,
+ },
+ {
+ adobename="eacute",
+ category="ll",
+ cjkwd="a",
+ contextname="eacute",
+ description="LATIN SMALL LETTER E WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0301 },
+ uccode=0x00C9,
+ unicodeslot=0x00E9,
+ },
+ {
+ adobename="ecircumflex",
+ category="ll",
+ cjkwd="a",
+ contextname="ecircumflex",
+ description="LATIN SMALL LETTER E WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0302 },
+ uccode=0x00CA,
+ unicodeslot=0x00EA,
+ },
+ {
+ adobename="edieresis",
+ category="ll",
+ contextname="ediaeresis",
+ description="LATIN SMALL LETTER E WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0308 },
+ uccode=0x00CB,
+ unicodeslot=0x00EB,
+ },
+ {
+ adobename="igrave",
+ category="ll",
+ cjkwd="a",
+ contextname="igrave",
+ description="LATIN SMALL LETTER I WITH GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x0300 },
+ uccode=0x00CC,
+ unicodeslot=0x00EC,
+ },
+ {
+ adobename="iacute",
+ category="ll",
+ cjkwd="a",
+ contextname="iacute",
+ description="LATIN SMALL LETTER I WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x0301 },
+ uccode=0x00CD,
+ unicodeslot=0x00ED,
+ },
+ {
+ adobename="icircumflex",
+ category="ll",
+ contextname="icircumflex",
+ description="LATIN SMALL LETTER I WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x0302 },
+ uccode=0x00CE,
+ unicodeslot=0x00EE,
+ },
+ {
+ adobename="idieresis",
+ category="ll",
+ contextname="idiaeresis",
+ description="LATIN SMALL LETTER I WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x0308 },
+ uccode=0x00CF,
+ unicodeslot=0x00EF,
+ },
+ {
+ adobename="eth",
+ category="ll",
+ cjkwd="a",
+ comment="contextname=eth",
+ description="LATIN SMALL LETTER ETH",
+ direction="l",
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="eth",
+ uccode=0x00D0,
+ unicodeslot=0x00F0,
+ },
+ {
+ adobename="ntilde",
+ category="ll",
+ contextname="ntilde",
+ description="LATIN SMALL LETTER N WITH TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ specials={ "char", 0x006E, 0x0303 },
+ uccode=0x00D1,
+ unicodeslot=0x00F1,
+ },
+ {
+ adobename="ograve",
+ category="ll",
+ cjkwd="a",
+ contextname="ograve",
+ description="LATIN SMALL LETTER O WITH GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x0300 },
+ uccode=0x00D2,
+ unicodeslot=0x00F2,
+ },
+ {
+ adobename="oacute",
+ category="ll",
+ cjkwd="a",
+ contextname="oacute",
+ description="LATIN SMALL LETTER O WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x0301 },
+ uccode=0x00D3,
+ unicodeslot=0x00F3,
+ },
+ {
+ adobename="ocircumflex",
+ category="ll",
+ contextname="ocircumflex",
+ description="LATIN SMALL LETTER O WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x0302 },
+ uccode=0x00D4,
+ unicodeslot=0x00F4,
+ },
+ {
+ adobename="otilde",
+ category="ll",
+ contextname="otilde",
+ description="LATIN SMALL LETTER O WITH TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x0303 },
+ uccode=0x00D5,
+ unicodeslot=0x00F5,
+ },
+ {
+ adobename="odieresis",
+ category="ll",
+ contextname="odiaeresis",
+ description="LATIN SMALL LETTER O WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x0308 },
+ uccode=0x00D6,
+ unicodeslot=0x00F6,
+ },
+ {
+ adobename="divide",
+ category="sm",
+ cjkwd="a",
+ contextname="textdiv",
+ description="DIVISION SIGN",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="div",
+ unicodeslot=0x00F7,
+ },
+ {
+ adobename="oslash",
+ category="ll",
+ cjkwd="a",
+ contextname="ostroke",
+ description="LATIN SMALL LETTER O WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ uccode=0x00D8,
+ unicodeslot=0x00F8,
+ },
+ {
+ adobename="ugrave",
+ category="ll",
+ cjkwd="a",
+ contextname="ugrave",
+ description="LATIN SMALL LETTER U WITH GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0300 },
+ uccode=0x00D9,
+ unicodeslot=0x00F9,
+ },
+ {
+ adobename="uacute",
+ category="ll",
+ cjkwd="a",
+ contextname="uacute",
+ description="LATIN SMALL LETTER U WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0301 },
+ uccode=0x00DA,
+ unicodeslot=0x00FA,
+ },
+ {
+ adobename="ucircumflex",
+ category="ll",
+ contextname="ucircumflex",
+ description="LATIN SMALL LETTER U WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0302 },
+ uccode=0x00DB,
+ unicodeslot=0x00FB,
+ },
+ {
+ adobename="udieresis",
+ category="ll",
+ cjkwd="a",
+ contextname="udiaeresis",
+ description="LATIN SMALL LETTER U WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0308 },
+ uccode=0x00DC,
+ unicodeslot=0x00FC,
+ },
+ {
+ adobename="yacute",
+ category="ll",
+ contextname="yacute",
+ description="LATIN SMALL LETTER Y WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0079,
+ specials={ "char", 0x0079, 0x0301 },
+ uccode=0x00DD,
+ unicodeslot=0x00FD,
+ },
+ {
+ adobename="thorn",
+ category="ll",
+ cjkwd="a",
+ contextname="thorn",
+ description="LATIN SMALL LETTER THORN",
+ direction="l",
+ linebreak="al",
+ uccode=0x00DE,
+ unicodeslot=0x00FE,
+ },
+ {
+ adobename="ydieresis",
+ category="ll",
+ contextname="ydiaeresis",
+ description="LATIN SMALL LETTER Y WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0079,
+ specials={ "char", 0x0079, 0x0308 },
+ uccode=0x0178,
+ unicodeslot=0x00FF,
+ },
+ {
+ adobename="Amacron",
+ category="lu",
+ contextname="Amacron",
+ description="LATIN CAPITAL LETTER A WITH MACRON",
+ direction="l",
+ lccode=0x0101,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0304 },
+ unicodeslot=0x0100,
+ },
+ {
+ adobename="amacron",
+ category="ll",
+ cjkwd="a",
+ contextname="amacron",
+ description="LATIN SMALL LETTER A WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0304 },
+ uccode=0x0100,
+ unicodeslot=0x0101,
+ },
+ {
+ adobename="Abreve",
+ category="lu",
+ contextname="Abreve",
+ description="LATIN CAPITAL LETTER A WITH BREVE",
+ direction="l",
+ lccode=0x0103,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0306 },
+ unicodeslot=0x0102,
+ },
+ {
+ adobename="abreve",
+ category="ll",
+ contextname="abreve",
+ description="LATIN SMALL LETTER A WITH BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0306 },
+ uccode=0x0102,
+ unicodeslot=0x0103,
+ },
+ {
+ adobename="Aogonek",
+ category="lu",
+ contextname="Aogonek",
+ description="LATIN CAPITAL LETTER A WITH OGONEK",
+ direction="l",
+ lccode=0x0105,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0328 },
+ unicodeslot=0x0104,
+ },
+ {
+ adobename="aogonek",
+ category="ll",
+ contextname="aogonek",
+ description="LATIN SMALL LETTER A WITH OGONEK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0328 },
+ uccode=0x0104,
+ unicodeslot=0x0105,
+ },
+ {
+ adobename="Cacute",
+ category="lu",
+ contextname="Cacute",
+ description="LATIN CAPITAL LETTER C WITH ACUTE",
+ direction="l",
+ lccode=0x0107,
+ linebreak="al",
+ shcode=0x0043,
+ specials={ "char", 0x0043, 0x0301 },
+ unicodeslot=0x0106,
+ },
+ {
+ adobename="cacute",
+ category="ll",
+ contextname="cacute",
+ description="LATIN SMALL LETTER C WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0063,
+ specials={ "char", 0x0063, 0x0301 },
+ uccode=0x0106,
+ unicodeslot=0x0107,
+ },
+ {
+ adobename="Ccircumflex",
+ category="lu",
+ contextname="Ccircumflex",
+ description="LATIN CAPITAL LETTER C WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x0109,
+ linebreak="al",
+ shcode=0x0043,
+ specials={ "char", 0x0043, 0x0302 },
+ unicodeslot=0x0108,
+ },
+ {
+ adobename="ccircumflex",
+ category="ll",
+ contextname="ccircumflex",
+ description="LATIN SMALL LETTER C WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x0063,
+ specials={ "char", 0x0063, 0x0302 },
+ uccode=0x0108,
+ unicodeslot=0x0109,
+ },
+ {
+ adobename="Cdotaccent",
+ category="lu",
+ contextname="Cdotaccent",
+ description="LATIN CAPITAL LETTER C WITH DOT ABOVE",
+ direction="l",
+ lccode=0x010B,
+ linebreak="al",
+ shcode=0x0043,
+ specials={ "char", 0x0043, 0x0307 },
+ unicodeslot=0x010A,
+ },
+ {
+ adobename="cdotaccent",
+ category="ll",
+ contextname="cdotaccent",
+ description="LATIN SMALL LETTER C WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0063,
+ specials={ "char", 0x0063, 0x0307 },
+ uccode=0x010A,
+ unicodeslot=0x010B,
+ },
+ {
+ adobename="Ccaron",
+ category="lu",
+ contextname="Ccaron",
+ description="LATIN CAPITAL LETTER C WITH CARON",
+ direction="l",
+ lccode=0x010D,
+ linebreak="al",
+ shcode=0x0043,
+ specials={ "char", 0x0043, 0x030C },
+ unicodeslot=0x010C,
+ },
+ {
+ adobename="ccaron",
+ category="ll",
+ contextname="ccaron",
+ description="LATIN SMALL LETTER C WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0063,
+ specials={ "char", 0x0063, 0x030C },
+ uccode=0x010C,
+ unicodeslot=0x010D,
+ },
+ {
+ adobename="Dcaron",
+ category="lu",
+ contextname="Dcaron",
+ description="LATIN CAPITAL LETTER D WITH CARON",
+ direction="l",
+ lccode=0x010F,
+ linebreak="al",
+ shcode=0x0044,
+ specials={ "char", 0x0044, 0x030C },
+ unicodeslot=0x010E,
+ },
+ {
+ adobename="dcaron",
+ category="ll",
+ contextname="dcaron",
+ description="LATIN SMALL LETTER D WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ specials={ "char", 0x0064, 0x030C },
+ uccode=0x010E,
+ unicodeslot=0x010F,
+ },
+ {
+ adobename="Dslash",
+ category="lu",
+ contextname="Dstroke",
+ description="LATIN CAPITAL LETTER D WITH STROKE",
+ direction="l",
+ lccode=0x0111,
+ linebreak="al",
+ shcode=0x0044,
+ unicodeslot=0x0110,
+ },
+ {
+ adobename="dmacron",
+ category="ll",
+ cjkwd="a",
+ contextname="dstroke",
+ description="LATIN SMALL LETTER D WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ uccode=0x0110,
+ unicodeslot=0x0111,
+ },
+ {
+ adobename="Emacron",
+ category="lu",
+ contextname="Emacron",
+ description="LATIN CAPITAL LETTER E WITH MACRON",
+ direction="l",
+ lccode=0x0113,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0304 },
+ unicodeslot=0x0112,
+ },
+ {
+ adobename="emacron",
+ category="ll",
+ cjkwd="a",
+ contextname="emacron",
+ description="LATIN SMALL LETTER E WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0304 },
+ uccode=0x0112,
+ unicodeslot=0x0113,
+ },
+ {
+ adobename="Ebreve",
+ category="lu",
+ contextname="Ebreve",
+ description="LATIN CAPITAL LETTER E WITH BREVE",
+ direction="l",
+ lccode=0x0115,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0306 },
+ unicodeslot=0x0114,
+ },
+ {
+ adobename="ebreve",
+ category="ll",
+ contextname="ebreve",
+ description="LATIN SMALL LETTER E WITH BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0306 },
+ uccode=0x0114,
+ unicodeslot=0x0115,
+ },
+ {
+ adobename="Edotaccent",
+ category="lu",
+ contextname="Edotaccent",
+ description="LATIN CAPITAL LETTER E WITH DOT ABOVE",
+ direction="l",
+ lccode=0x0117,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0307 },
+ unicodeslot=0x0116,
+ },
+ {
+ adobename="edotaccent",
+ category="ll",
+ contextname="edotaccent",
+ description="LATIN SMALL LETTER E WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0307 },
+ uccode=0x0116,
+ unicodeslot=0x0117,
+ },
+ {
+ adobename="Eogonek",
+ category="lu",
+ contextname="Eogonek",
+ description="LATIN CAPITAL LETTER E WITH OGONEK",
+ direction="l",
+ lccode=0x0119,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0328 },
+ unicodeslot=0x0118,
+ },
+ {
+ adobename="eogonek",
+ category="ll",
+ contextname="eogonek",
+ description="LATIN SMALL LETTER E WITH OGONEK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0328 },
+ uccode=0x0118,
+ unicodeslot=0x0119,
+ },
+ {
+ adobename="Ecaron",
+ category="lu",
+ contextname="Ecaron",
+ description="LATIN CAPITAL LETTER E WITH CARON",
+ direction="l",
+ lccode=0x011B,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x030C },
+ unicodeslot=0x011A,
+ },
+ {
+ adobename="ecaron",
+ category="ll",
+ cjkwd="a",
+ contextname="ecaron",
+ description="LATIN SMALL LETTER E WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x030C },
+ uccode=0x011A,
+ unicodeslot=0x011B,
+ },
+ {
+ adobename="Gcircumflex",
+ category="lu",
+ contextname="Gcircumflex",
+ description="LATIN CAPITAL LETTER G WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x011D,
+ linebreak="al",
+ shcode=0x0047,
+ specials={ "char", 0x0047, 0x0302 },
+ unicodeslot=0x011C,
+ },
+ {
+ adobename="gcircumflex",
+ category="ll",
+ contextname="gcircumflex",
+ description="LATIN SMALL LETTER G WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x0067,
+ specials={ "char", 0x0067, 0x0302 },
+ uccode=0x011C,
+ unicodeslot=0x011D,
+ },
+ {
+ adobename="Gbreve",
+ category="lu",
+ contextname="Gbreve",
+ description="LATIN CAPITAL LETTER G WITH BREVE",
+ direction="l",
+ lccode=0x011F,
+ linebreak="al",
+ shcode=0x0047,
+ specials={ "char", 0x0047, 0x0306 },
+ unicodeslot=0x011E,
+ },
+ {
+ adobename="gbreve",
+ category="ll",
+ contextname="gbreve",
+ description="LATIN SMALL LETTER G WITH BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0067,
+ specials={ "char", 0x0067, 0x0306 },
+ uccode=0x011E,
+ unicodeslot=0x011F,
+ },
+ {
+ adobename="Gdotaccent",
+ category="lu",
+ contextname="Gdotaccent",
+ description="LATIN CAPITAL LETTER G WITH DOT ABOVE",
+ direction="l",
+ lccode=0x0121,
+ linebreak="al",
+ shcode=0x0047,
+ specials={ "char", 0x0047, 0x0307 },
+ unicodeslot=0x0120,
+ },
+ {
+ adobename="gdotaccent",
+ category="ll",
+ contextname="gdotaccent",
+ description="LATIN SMALL LETTER G WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0067,
+ specials={ "char", 0x0067, 0x0307 },
+ uccode=0x0120,
+ unicodeslot=0x0121,
+ },
+ {
+ adobename="Gcommaaccent",
+ category="lu",
+ contextname="Gcommaaccent",
+ description="LATIN CAPITAL LETTER G WITH CEDILLA",
+ direction="l",
+ lccode=0x0123,
+ linebreak="al",
+ shcode=0x0047,
+ specials={ "char", 0x0047, 0x0327 },
+ unicodeslot=0x0122,
+ },
+ {
+ adobename="gcommaaccent",
+ category="ll",
+ contextname="gcommaaccent",
+ description="LATIN SMALL LETTER G WITH CEDILLA",
+ direction="l",
+ linebreak="al",
+ shcode=0x0067,
+ specials={ "char", 0x0067, 0x0327 },
+ uccode=0x0122,
+ unicodeslot=0x0123,
+ },
+ {
+ adobename="Hcircumflex",
+ category="lu",
+ contextname="Hcircumflex",
+ description="LATIN CAPITAL LETTER H WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x0125,
+ linebreak="al",
+ shcode=0x0048,
+ specials={ "char", 0x0048, 0x0302 },
+ unicodeslot=0x0124,
+ },
+ {
+ adobename="hcircumflex",
+ category="ll",
+ contextname="hcircumflex",
+ description="LATIN SMALL LETTER H WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x0068,
+ specials={ "char", 0x0068, 0x0302 },
+ uccode=0x0124,
+ unicodeslot=0x0125,
+ },
+ {
+ adobename="Hbar",
+ category="lu",
+ cjkwd="a",
+ contextname="Hstroke",
+ description="LATIN CAPITAL LETTER H WITH STROKE",
+ direction="l",
+ lccode=0x0127,
+ linebreak="al",
+ shcode=0x0048,
+ unicodeslot=0x0126,
+ },
+ {
+ adobename="hbar",
+ category="ll",
+ cjkwd="a",
+ contextname="hstroke",
+ description="LATIN SMALL LETTER H WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0068,
+ uccode=0x0126,
+ unicodeslot=0x0127,
+ },
+ {
+ adobename="Itilde",
+ category="lu",
+ contextname="Itilde",
+ description="LATIN CAPITAL LETTER I WITH TILDE",
+ direction="l",
+ lccode=0x0129,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0303 },
+ unicodeslot=0x0128,
+ },
+ {
+ adobename="itilde",
+ category="ll",
+ contextname="itilde",
+ description="LATIN SMALL LETTER I WITH TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x0303 },
+ uccode=0x0128,
+ unicodeslot=0x0129,
+ },
+ {
+ adobename="Imacron",
+ category="lu",
+ contextname="Imacron",
+ description="LATIN CAPITAL LETTER I WITH MACRON",
+ direction="l",
+ lccode=0x012B,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0304 },
+ unicodeslot=0x012A,
+ },
+ {
+ adobename="imacron",
+ category="ll",
+ cjkwd="a",
+ contextname="imacron",
+ description="LATIN SMALL LETTER I WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x0304 },
+ uccode=0x012A,
+ unicodeslot=0x012B,
+ },
+ {
+ adobename="Ibreve",
+ category="lu",
+ contextname="Ibreve",
+ description="LATIN CAPITAL LETTER I WITH BREVE",
+ direction="l",
+ lccode=0x012D,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0306 },
+ unicodeslot=0x012C,
+ },
+ {
+ adobename="ibreve",
+ category="ll",
+ contextname="ibreve",
+ description="LATIN SMALL LETTER I WITH BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x0306 },
+ uccode=0x012C,
+ unicodeslot=0x012D,
+ },
+ {
+ adobename="Iogonek",
+ category="lu",
+ contextname="Iogonek",
+ description="LATIN CAPITAL LETTER I WITH OGONEK",
+ direction="l",
+ lccode=0x012F,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0328 },
+ unicodeslot=0x012E,
+ },
+ {
+ adobename="iogonek",
+ category="ll",
+ contextname="iogonek",
+ description="LATIN SMALL LETTER I WITH OGONEK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x0328 },
+ uccode=0x012E,
+ unicodeslot=0x012F,
+ },
+ {
+ adobename="Idotaccent",
+ category="lu",
+ contextname="Idotaccent",
+ description="LATIN CAPITAL LETTER I WITH DOT ABOVE",
+ direction="l",
+ lccode=0x0069,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0307 },
+ unicodeslot=0x0130,
+ },
+ {
+ adobename="dotlessi",
+ category="ll",
+ cjkwd="a",
+ contextname="dotlessi",
+ description="LATIN SMALL LETTER DOTLESS I",
+ direction="l",
+ linebreak="al",
+ uccode=0x0049,
+ unicodeslot=0x0131,
+ },
+ {
+ adobename="IJ",
+ category="lu",
+ cjkwd="a",
+ contextname="IJligature",
+ description="LATIN CAPITAL LIGATURE IJ",
+ direction="l",
+ lccode=0x0133,
+ linebreak="al",
+ shcode={ 0x0049, 0x004A },
+ specials={ "compat", 0x0049, 0x004A },
+ unicodeslot=0x0132,
+ },
+ {
+ adobename="ij",
+ category="ll",
+ cjkwd="a",
+ contextname="ijligature",
+ description="LATIN SMALL LIGATURE IJ",
+ direction="l",
+ linebreak="al",
+ shcode={ 0x0069, 0x006A },
+ specials={ "compat", 0x0069, 0x006A },
+ uccode=0x0132,
+ unicodeslot=0x0133,
+ },
+ {
+ adobename="Jcircumflex",
+ category="lu",
+ contextname="Jcircumflex",
+ description="LATIN CAPITAL LETTER J WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x0135,
+ linebreak="al",
+ shcode=0x004A,
+ specials={ "char", 0x004A, 0x0302 },
+ unicodeslot=0x0134,
+ },
+ {
+ adobename="jcircumflex",
+ category="ll",
+ contextname="jcircumflex",
+ description="LATIN SMALL LETTER J WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x006A,
+ specials={ "char", 0x006A, 0x0302 },
+ uccode=0x0134,
+ unicodeslot=0x0135,
+ },
+ {
+ adobename="Kcommaaccent",
+ category="lu",
+ contextname="Kcommaaccent",
+ description="LATIN CAPITAL LETTER K WITH CEDILLA",
+ direction="l",
+ lccode=0x0137,
+ linebreak="al",
+ shcode=0x004B,
+ specials={ "char", 0x004B, 0x0327 },
+ unicodeslot=0x0136,
+ },
+ {
+ adobename="kcommaaccent",
+ category="ll",
+ contextname="kcommaaccent",
+ description="LATIN SMALL LETTER K WITH CEDILLA",
+ direction="l",
+ linebreak="al",
+ shcode=0x006B,
+ specials={ "char", 0x006B, 0x0327 },
+ uccode=0x0136,
+ unicodeslot=0x0137,
+ },
+ {
+ adobename="kgreenlandic",
+ category="ll",
+ cjkwd="a",
+ contextname="kkra",
+ description="LATIN SMALL LETTER KRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0138,
+ },
+ {
+ adobename="Lacute",
+ category="lu",
+ contextname="Lacute",
+ description="LATIN CAPITAL LETTER L WITH ACUTE",
+ direction="l",
+ lccode=0x013A,
+ linebreak="al",
+ shcode=0x004C,
+ specials={ "char", 0x004C, 0x0301 },
+ unicodeslot=0x0139,
+ },
+ {
+ adobename="lacute",
+ category="ll",
+ contextname="lacute",
+ description="LATIN SMALL LETTER L WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ specials={ "char", 0x006C, 0x0301 },
+ uccode=0x0139,
+ unicodeslot=0x013A,
+ },
+ {
+ adobename="Lcommaaccent",
+ category="lu",
+ contextname="Lcommaaccent",
+ description="LATIN CAPITAL LETTER L WITH CEDILLA",
+ direction="l",
+ lccode=0x013C,
+ linebreak="al",
+ shcode=0x004C,
+ specials={ "char", 0x004C, 0x0327 },
+ unicodeslot=0x013B,
+ },
+ {
+ adobename="lcommaaccent",
+ category="ll",
+ contextname="lcommaaccent",
+ description="LATIN SMALL LETTER L WITH CEDILLA",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ specials={ "char", 0x006C, 0x0327 },
+ uccode=0x013B,
+ unicodeslot=0x013C,
+ },
+ {
+ adobename="Lcaron",
+ category="lu",
+ contextname="Lcaron",
+ description="LATIN CAPITAL LETTER L WITH CARON",
+ direction="l",
+ lccode=0x013E,
+ linebreak="al",
+ shcode=0x004C,
+ specials={ "char", 0x004C, 0x030C },
+ unicodeslot=0x013D,
+ },
+ {
+ adobename="lcaron",
+ category="ll",
+ contextname="lcaron",
+ description="LATIN SMALL LETTER L WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ specials={ "char", 0x006C, 0x030C },
+ uccode=0x013D,
+ unicodeslot=0x013E,
+ },
+ {
+ adobename="Ldotaccent",
+ category="lu",
+ cjkwd="a",
+ contextname="Ldotmiddle",
+ description="LATIN CAPITAL LETTER L WITH MIDDLE DOT",
+ direction="l",
+ lccode=0x0140,
+ linebreak="al",
+ shcode=0x004C,
+ specials={ "compat", 0x004C, 0x00B7 },
+ unicodeslot=0x013F,
+ },
+ {
+ adobename="ldotaccent",
+ category="ll",
+ cjkwd="a",
+ contextname="ldotmiddle",
+ description="LATIN SMALL LETTER L WITH MIDDLE DOT",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ specials={ "compat", 0x006C, 0x00B7 },
+ uccode=0x013F,
+ unicodeslot=0x0140,
+ },
+ {
+ adobename="Lslash",
+ category="lu",
+ cjkwd="a",
+ contextname="Lstroke",
+ description="LATIN CAPITAL LETTER L WITH STROKE",
+ direction="l",
+ lccode=0x0142,
+ linebreak="al",
+ shcode=0x004C,
+ unicodeslot=0x0141,
+ },
+ {
+ adobename="lslash",
+ category="ll",
+ cjkwd="a",
+ contextname="lstroke",
+ description="LATIN SMALL LETTER L WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ uccode=0x0141,
+ unicodeslot=0x0142,
+ },
+ {
+ adobename="Nacute",
+ category="lu",
+ contextname="Nacute",
+ description="LATIN CAPITAL LETTER N WITH ACUTE",
+ direction="l",
+ lccode=0x0144,
+ linebreak="al",
+ shcode=0x004E,
+ specials={ "char", 0x004E, 0x0301 },
+ unicodeslot=0x0143,
+ },
+ {
+ adobename="nacute",
+ category="ll",
+ cjkwd="a",
+ contextname="nacute",
+ description="LATIN SMALL LETTER N WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ specials={ "char", 0x006E, 0x0301 },
+ uccode=0x0143,
+ unicodeslot=0x0144,
+ },
+ {
+ adobename="Ncommaaccent",
+ category="lu",
+ contextname="Ncommaaccent",
+ description="LATIN CAPITAL LETTER N WITH CEDILLA",
+ direction="l",
+ lccode=0x0146,
+ linebreak="al",
+ shcode=0x004E,
+ specials={ "char", 0x004E, 0x0327 },
+ unicodeslot=0x0145,
+ },
+ {
+ adobename="ncommaaccent",
+ category="ll",
+ contextname="ncommaaccent",
+ description="LATIN SMALL LETTER N WITH CEDILLA",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ specials={ "char", 0x006E, 0x0327 },
+ uccode=0x0145,
+ unicodeslot=0x0146,
+ },
+ {
+ adobename="Ncaron",
+ category="lu",
+ contextname="Ncaron",
+ description="LATIN CAPITAL LETTER N WITH CARON",
+ direction="l",
+ lccode=0x0148,
+ linebreak="al",
+ shcode=0x004E,
+ specials={ "char", 0x004E, 0x030C },
+ unicodeslot=0x0147,
+ },
+ {
+ adobename="ncaron",
+ category="ll",
+ cjkwd="a",
+ contextname="ncaron",
+ description="LATIN SMALL LETTER N WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ specials={ "char", 0x006E, 0x030C },
+ uccode=0x0147,
+ unicodeslot=0x0148,
+ },
+ {
+ adobename="quoterightn",
+ category="ll",
+ cjkwd="a",
+ contextname="napostrophe",
+ description="LATIN SMALL LETTER N PRECEDED BY APOSTROPHE",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x02BC, 0x006E },
+ unicodeslot=0x0149,
+ },
+ {
+ adobename="Eng",
+ category="lu",
+ cjkwd="a",
+ contextname="Neng",
+ description="LATIN CAPITAL LETTER ENG",
+ direction="l",
+ lccode=0x014B,
+ linebreak="al",
+ unicodeslot=0x014A,
+ },
+ {
+ adobename="eng",
+ category="ll",
+ cjkwd="a",
+ contextname="neng",
+ description="LATIN SMALL LETTER ENG",
+ direction="l",
+ linebreak="al",
+ uccode=0x014A,
+ unicodeslot=0x014B,
+ },
+ {
+ adobename="Omacron",
+ category="lu",
+ contextname="Omacron",
+ description="LATIN CAPITAL LETTER O WITH MACRON",
+ direction="l",
+ lccode=0x014D,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x0304 },
+ unicodeslot=0x014C,
+ },
+ {
+ adobename="omacron",
+ category="ll",
+ cjkwd="a",
+ contextname="omacron",
+ description="LATIN SMALL LETTER O WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x0304 },
+ uccode=0x014C,
+ unicodeslot=0x014D,
+ },
+ {
+ adobename="Obreve",
+ category="lu",
+ contextname="Obreve",
+ description="LATIN CAPITAL LETTER O WITH BREVE",
+ direction="l",
+ lccode=0x014F,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x0306 },
+ unicodeslot=0x014E,
+ },
+ {
+ adobename="obreve",
+ category="ll",
+ contextname="obreve",
+ description="LATIN SMALL LETTER O WITH BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x0306 },
+ uccode=0x014E,
+ unicodeslot=0x014F,
+ },
+ {
+ adobename="Ohungarumlaut",
+ category="lu",
+ contextname="Ohungarumlaut",
+ description="LATIN CAPITAL LETTER O WITH DOUBLE ACUTE",
+ direction="l",
+ lccode=0x0151,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x030B },
+ unicodeslot=0x0150,
+ },
+ {
+ adobename="ohungarumlaut",
+ category="ll",
+ contextname="ohungarumlaut",
+ description="LATIN SMALL LETTER O WITH DOUBLE ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x030B },
+ uccode=0x0150,
+ unicodeslot=0x0151,
+ },
+ {
+ adobename="OE",
+ category="lu",
+ cjkwd="a",
+ contextname="OEligature",
+ description="LATIN CAPITAL LIGATURE OE",
+ direction="l",
+ lccode=0x0153,
+ linebreak="al",
+ shcode={ 0x004F, 0x0045 },
+ unicodeslot=0x0152,
+ },
+ {
+ adobename="oe",
+ category="ll",
+ cjkwd="a",
+ contextname="oeligature",
+ description="LATIN SMALL LIGATURE OE",
+ direction="l",
+ linebreak="al",
+ shcode={ 0x006F, 0x0065 },
+ uccode=0x0152,
+ unicodeslot=0x0153,
+ },
+ {
+ adobename="Racute",
+ category="lu",
+ contextname="Racute",
+ description="LATIN CAPITAL LETTER R WITH ACUTE",
+ direction="l",
+ lccode=0x0155,
+ linebreak="al",
+ shcode=0x0052,
+ specials={ "char", 0x0052, 0x0301 },
+ unicodeslot=0x0154,
+ },
+ {
+ adobename="racute",
+ category="ll",
+ contextname="racute",
+ description="LATIN SMALL LETTER R WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ specials={ "char", 0x0072, 0x0301 },
+ uccode=0x0154,
+ unicodeslot=0x0155,
+ },
+ {
+ adobename="Rcommaaccent",
+ category="lu",
+ contextname="Rcommaaccent",
+ description="LATIN CAPITAL LETTER R WITH CEDILLA",
+ direction="l",
+ lccode=0x0157,
+ linebreak="al",
+ shcode=0x0052,
+ specials={ "char", 0x0052, 0x0327 },
+ unicodeslot=0x0156,
+ },
+ {
+ adobename="rcommaaccent",
+ category="ll",
+ contextname="rcommaaccent",
+ description="LATIN SMALL LETTER R WITH CEDILLA",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ specials={ "char", 0x0072, 0x0327 },
+ uccode=0x0156,
+ unicodeslot=0x0157,
+ },
+ {
+ adobename="Rcaron",
+ category="lu",
+ contextname="Rcaron",
+ description="LATIN CAPITAL LETTER R WITH CARON",
+ direction="l",
+ lccode=0x0159,
+ linebreak="al",
+ shcode=0x0052,
+ specials={ "char", 0x0052, 0x030C },
+ unicodeslot=0x0158,
+ },
+ {
+ adobename="rcaron",
+ category="ll",
+ contextname="rcaron",
+ description="LATIN SMALL LETTER R WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ specials={ "char", 0x0072, 0x030C },
+ uccode=0x0158,
+ unicodeslot=0x0159,
+ },
+ {
+ adobename="Sacute",
+ category="lu",
+ contextname="Sacute",
+ description="LATIN CAPITAL LETTER S WITH ACUTE",
+ direction="l",
+ lccode=0x015B,
+ linebreak="al",
+ shcode=0x0053,
+ specials={ "char", 0x0053, 0x0301 },
+ unicodeslot=0x015A,
+ },
+ {
+ adobename="sacute",
+ category="ll",
+ contextname="sacute",
+ description="LATIN SMALL LETTER S WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ specials={ "char", 0x0073, 0x0301 },
+ uccode=0x015A,
+ unicodeslot=0x015B,
+ },
+ {
+ adobename="Scircumflex",
+ category="lu",
+ contextname="Scircumflex",
+ description="LATIN CAPITAL LETTER S WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x015D,
+ linebreak="al",
+ shcode=0x0053,
+ specials={ "char", 0x0053, 0x0302 },
+ unicodeslot=0x015C,
+ },
+ {
+ adobename="scircumflex",
+ category="ll",
+ contextname="scircumflex",
+ description="LATIN SMALL LETTER S WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ specials={ "char", 0x0073, 0x0302 },
+ uccode=0x015C,
+ unicodeslot=0x015D,
+ },
+ {
+ adobename="Scedilla",
+ category="lu",
+ contextname="Scedilla",
+ description="LATIN CAPITAL LETTER S WITH CEDILLA",
+ direction="l",
+ lccode=0x015F,
+ linebreak="al",
+ shcode=0x0053,
+ specials={ "char", 0x0053, 0x0327 },
+ unicodeslot=0x015E,
+ },
+ {
+ adobename="scedilla",
+ category="ll",
+ contextname="scedilla",
+ description="LATIN SMALL LETTER S WITH CEDILLA",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ specials={ "char", 0x0073, 0x0327 },
+ uccode=0x015E,
+ unicodeslot=0x015F,
+ },
+ {
+ adobename="Scaron",
+ category="lu",
+ contextname="Scaron",
+ description="LATIN CAPITAL LETTER S WITH CARON",
+ direction="l",
+ lccode=0x0161,
+ linebreak="al",
+ shcode=0x0053,
+ specials={ "char", 0x0053, 0x030C },
+ unicodeslot=0x0160,
+ },
+ {
+ adobename="scaron",
+ category="ll",
+ contextname="scaron",
+ description="LATIN SMALL LETTER S WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ specials={ "char", 0x0073, 0x030C },
+ uccode=0x0160,
+ unicodeslot=0x0161,
+ },
+ {
+ adobename="Tcommaaccent",
+ category="lu",
+ contextname="Tcedilla",
+ description="LATIN CAPITAL LETTER T WITH CEDILLA",
+ direction="l",
+ lccode=0x0163,
+ linebreak="al",
+ shcode=0x0054,
+ specials={ "char", 0x0054, 0x0327 },
+ unicodeslot=0x0162,
+ },
+ {
+ adobename="tcommaaccent",
+ category="ll",
+ contextname="tcedilla",
+ description="LATIN SMALL LETTER T WITH CEDILLA",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ specials={ "char", 0x0074, 0x0327 },
+ uccode=0x0162,
+ unicodeslot=0x0163,
+ },
+ {
+ adobename="Tcaron",
+ category="lu",
+ contextname="Tcaron",
+ description="LATIN CAPITAL LETTER T WITH CARON",
+ direction="l",
+ lccode=0x0165,
+ linebreak="al",
+ shcode=0x0054,
+ specials={ "char", 0x0054, 0x030C },
+ unicodeslot=0x0164,
+ },
+ {
+ adobename="tcaron",
+ category="ll",
+ contextname="tcaron",
+ description="LATIN SMALL LETTER T WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ specials={ "char", 0x0074, 0x030C },
+ uccode=0x0164,
+ unicodeslot=0x0165,
+ },
+ {
+ adobename="Tbar",
+ category="lu",
+ cjkwd="a",
+ contextname="Tstroke",
+ description="LATIN CAPITAL LETTER T WITH STROKE",
+ direction="l",
+ lccode=0x0167,
+ linebreak="al",
+ shcode=0x0054,
+ unicodeslot=0x0166,
+ },
+ {
+ adobename="tbar",
+ category="ll",
+ cjkwd="a",
+ contextname="tstroke",
+ description="LATIN SMALL LETTER T WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ uccode=0x0166,
+ unicodeslot=0x0167,
+ },
+ {
+ adobename="Utilde",
+ category="lu",
+ contextname="Utilde",
+ description="LATIN CAPITAL LETTER U WITH TILDE",
+ direction="l",
+ lccode=0x0169,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0303 },
+ unicodeslot=0x0168,
+ },
+ {
+ adobename="utilde",
+ category="ll",
+ contextname="utilde",
+ description="LATIN SMALL LETTER U WITH TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0303 },
+ uccode=0x0168,
+ unicodeslot=0x0169,
+ },
+ {
+ adobename="Umacron",
+ category="lu",
+ contextname="Umacron",
+ description="LATIN CAPITAL LETTER U WITH MACRON",
+ direction="l",
+ lccode=0x016B,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0304 },
+ unicodeslot=0x016A,
+ },
+ {
+ adobename="umacron",
+ category="ll",
+ cjkwd="a",
+ contextname="umacron",
+ description="LATIN SMALL LETTER U WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0304 },
+ uccode=0x016A,
+ unicodeslot=0x016B,
+ },
+ {
+ adobename="Ubreve",
+ category="lu",
+ contextname="Ubreve",
+ description="LATIN CAPITAL LETTER U WITH BREVE",
+ direction="l",
+ lccode=0x016D,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0306 },
+ unicodeslot=0x016C,
+ },
+ {
+ adobename="ubreve",
+ category="ll",
+ contextname="ubreve",
+ description="LATIN SMALL LETTER U WITH BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0306 },
+ uccode=0x016C,
+ unicodeslot=0x016D,
+ },
+ {
+ adobename="Uring",
+ category="lu",
+ contextname="Uring",
+ description="LATIN CAPITAL LETTER U WITH RING ABOVE",
+ direction="l",
+ lccode=0x016F,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x030A },
+ unicodeslot=0x016E,
+ },
+ {
+ adobename="uring",
+ category="ll",
+ contextname="uring",
+ description="LATIN SMALL LETTER U WITH RING ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x030A },
+ uccode=0x016E,
+ unicodeslot=0x016F,
+ },
+ {
+ adobename="Uhungarumlaut",
+ category="lu",
+ contextname="Uhungarumlaut",
+ description="LATIN CAPITAL LETTER U WITH DOUBLE ACUTE",
+ direction="l",
+ lccode=0x0171,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x030B },
+ unicodeslot=0x0170,
+ },
+ {
+ adobename="uhungarumlaut",
+ category="ll",
+ contextname="uhungarumlaut",
+ description="LATIN SMALL LETTER U WITH DOUBLE ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x030B },
+ uccode=0x0170,
+ unicodeslot=0x0171,
+ },
+ {
+ adobename="Uogonek",
+ category="lu",
+ contextname="Uogonek",
+ description="LATIN CAPITAL LETTER U WITH OGONEK",
+ direction="l",
+ lccode=0x0173,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0328 },
+ unicodeslot=0x0172,
+ },
+ {
+ adobename="uogonek",
+ category="ll",
+ contextname="uogonek",
+ description="LATIN SMALL LETTER U WITH OGONEK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0328 },
+ uccode=0x0172,
+ unicodeslot=0x0173,
+ },
+ {
+ adobename="Wcircumflex",
+ category="lu",
+ contextname="Wcircumflex",
+ description="LATIN CAPITAL LETTER W WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x0175,
+ linebreak="al",
+ shcode=0x0057,
+ specials={ "char", 0x0057, 0x0302 },
+ unicodeslot=0x0174,
+ },
+ {
+ adobename="wcircumflex",
+ category="ll",
+ contextname="wcircumflex",
+ description="LATIN SMALL LETTER W WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x0077,
+ specials={ "char", 0x0077, 0x0302 },
+ uccode=0x0174,
+ unicodeslot=0x0175,
+ },
+ {
+ adobename="Ycircumflex",
+ category="lu",
+ contextname="Ycircumflex",
+ description="LATIN CAPITAL LETTER Y WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x0177,
+ linebreak="al",
+ shcode=0x0059,
+ specials={ "char", 0x0059, 0x0302 },
+ unicodeslot=0x0176,
+ },
+ {
+ adobename="ycircumflex",
+ category="ll",
+ contextname="ycircumflex",
+ description="LATIN SMALL LETTER Y WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x0079,
+ specials={ "char", 0x0079, 0x0302 },
+ uccode=0x0176,
+ unicodeslot=0x0177,
+ },
+ {
+ adobename="Ydieresis",
+ category="lu",
+ contextname="Ydiaeresis",
+ description="LATIN CAPITAL LETTER Y WITH DIAERESIS",
+ direction="l",
+ lccode=0x00FF,
+ linebreak="al",
+ shcode=0x0059,
+ specials={ "char", 0x0059, 0x0308 },
+ unicodeslot=0x0178,
+ },
+ {
+ adobename="Zacute",
+ category="lu",
+ contextname="Zacute",
+ description="LATIN CAPITAL LETTER Z WITH ACUTE",
+ direction="l",
+ lccode=0x017A,
+ linebreak="al",
+ shcode=0x005A,
+ specials={ "char", 0x005A, 0x0301 },
+ unicodeslot=0x0179,
+ },
+ {
+ adobename="zacute",
+ category="ll",
+ contextname="zacute",
+ description="LATIN SMALL LETTER Z WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ specials={ "char", 0x007A, 0x0301 },
+ uccode=0x0179,
+ unicodeslot=0x017A,
+ },
+ {
+ adobename="Zdotaccent",
+ category="lu",
+ contextname="Zdotaccent",
+ description="LATIN CAPITAL LETTER Z WITH DOT ABOVE",
+ direction="l",
+ lccode=0x017C,
+ linebreak="al",
+ shcode=0x005A,
+ specials={ "char", 0x005A, 0x0307 },
+ unicodeslot=0x017B,
+ },
+ {
+ adobename="zdotaccent",
+ category="ll",
+ contextname="zdotaccent",
+ description="LATIN SMALL LETTER Z WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ specials={ "char", 0x007A, 0x0307 },
+ uccode=0x017B,
+ unicodeslot=0x017C,
+ },
+ {
+ adobename="Zcaron",
+ category="lu",
+ contextname="Zcaron",
+ description="LATIN CAPITAL LETTER Z WITH CARON",
+ direction="l",
+ lccode=0x017E,
+ linebreak="al",
+ shcode=0x005A,
+ specials={ "char", 0x005A, 0x030C },
+ unicodeslot=0x017D,
+ },
+ {
+ adobename="zcaron",
+ category="ll",
+ contextname="zcaron",
+ description="LATIN SMALL LETTER Z WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ specials={ "char", 0x007A, 0x030C },
+ uccode=0x017D,
+ unicodeslot=0x017E,
+ },
+ {
+ adobename="slong",
+ category="ll",
+ contextname="slong",
+ description="LATIN SMALL LETTER LONG S",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0073 },
+ uccode=0x0053,
+ unicodeslot=0x017F,
+ },
+ {
+ adobename="bstroke",
+ category="ll",
+ contextname="bstroke",
+ description="LATIN SMALL LETTER B WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0062,
+ uccode=0x0243,
+ unicodeslot=0x0180,
+ },
+ {
+ adobename="Bhook",
+ category="lu",
+ contextname="Bhook",
+ description="LATIN CAPITAL LETTER B WITH HOOK",
+ direction="l",
+ lccode=0x0253,
+ linebreak="al",
+ shcode=0x0042,
+ unicodeslot=0x0181,
+ },
+ {
+ adobename="Btopbar",
+ category="lu",
+ description="LATIN CAPITAL LETTER B WITH TOPBAR",
+ direction="l",
+ lccode=0x0183,
+ linebreak="al",
+ shcode=0x0042,
+ unicodeslot=0x0182,
+ },
+ {
+ adobename="btopbar",
+ category="ll",
+ description="LATIN SMALL LETTER B WITH TOPBAR",
+ direction="l",
+ linebreak="al",
+ shcode=0x0062,
+ uccode=0x0182,
+ unicodeslot=0x0183,
+ },
+ {
+ adobename="Tonesix",
+ category="lu",
+ description="LATIN CAPITAL LETTER TONE SIX",
+ direction="l",
+ lccode=0x0185,
+ linebreak="al",
+ unicodeslot=0x0184,
+ },
+ {
+ adobename="tonesix",
+ category="ll",
+ description="LATIN SMALL LETTER TONE SIX",
+ direction="l",
+ linebreak="al",
+ uccode=0x0184,
+ unicodeslot=0x0185,
+ },
+ {
+ adobename="Oopen",
+ category="lu",
+ description="LATIN CAPITAL LETTER OPEN O",
+ direction="l",
+ lccode=0x0254,
+ linebreak="al",
+ unicodeslot=0x0186,
+ },
+ {
+ adobename="Chook",
+ category="lu",
+ contextname="Chook",
+ description="LATIN CAPITAL LETTER C WITH HOOK",
+ direction="l",
+ lccode=0x0188,
+ linebreak="al",
+ shcode=0x0043,
+ unicodeslot=0x0187,
+ },
+ {
+ adobename="chook",
+ category="ll",
+ contextname="chook",
+ description="LATIN SMALL LETTER C WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0063,
+ uccode=0x0187,
+ unicodeslot=0x0188,
+ },
+ {
+ adobename="Dafrican",
+ category="lu",
+ contextname="Dafrican",
+ description="LATIN CAPITAL LETTER AFRICAN D",
+ direction="l",
+ lccode=0x0256,
+ linebreak="al",
+ unicodeslot=0x0189,
+ },
+ {
+ adobename="Dhook",
+ category="lu",
+ contextname="Dhook",
+ description="LATIN CAPITAL LETTER D WITH HOOK",
+ direction="l",
+ lccode=0x0257,
+ linebreak="al",
+ shcode=0x0044,
+ unicodeslot=0x018A,
+ },
+ {
+ adobename="Dtopbar",
+ category="lu",
+ description="LATIN CAPITAL LETTER D WITH TOPBAR",
+ direction="l",
+ lccode=0x018C,
+ linebreak="al",
+ shcode=0x0044,
+ unicodeslot=0x018B,
+ },
+ {
+ adobename="dtopbar",
+ category="ll",
+ description="LATIN SMALL LETTER D WITH TOPBAR",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ uccode=0x018B,
+ unicodeslot=0x018C,
+ },
+ {
+ adobename="deltaturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED DELTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x018D,
+ },
+ {
+ adobename="Ereversed",
+ category="lu",
+ description="LATIN CAPITAL LETTER REVERSED E",
+ direction="l",
+ lccode=0x01DD,
+ linebreak="al",
+ unicodeslot=0x018E,
+ },
+ {
+ adobename="Schwa",
+ category="lu",
+ contextname="Schwa",
+ description="LATIN CAPITAL LETTER SCHWA",
+ direction="l",
+ lccode=0x0259,
+ linebreak="al",
+ unicodeslot=0x018F,
+ },
+ {
+ adobename="Eopen",
+ category="lu",
+ description="LATIN CAPITAL LETTER OPEN E",
+ direction="l",
+ lccode=0x025B,
+ linebreak="al",
+ unicodeslot=0x0190,
+ },
+ {
+ adobename="Fhook",
+ category="lu",
+ contextname="Fhook",
+ description="LATIN CAPITAL LETTER F WITH HOOK",
+ direction="l",
+ lccode=0x0192,
+ linebreak="al",
+ shcode=0x0046,
+ unicodeslot=0x0191,
+ },
+ {
+ adobename="florin",
+ category="ll",
+ contextname="fhook",
+ description="LATIN SMALL LETTER F WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0066,
+ uccode=0x0191,
+ unicodeslot=0x0192,
+ },
+ {
+ adobename="Ghook",
+ category="lu",
+ contextname="Ghook",
+ description="LATIN CAPITAL LETTER G WITH HOOK",
+ direction="l",
+ lccode=0x0260,
+ linebreak="al",
+ shcode=0x0047,
+ unicodeslot=0x0193,
+ },
+ {
+ adobename="Gammaafrican",
+ category="lu",
+ description="LATIN CAPITAL LETTER GAMMA",
+ direction="l",
+ lccode=0x0263,
+ linebreak="al",
+ unicodeslot=0x0194,
+ },
+ {
+ adobename="hv",
+ category="ll",
+ description="LATIN SMALL LETTER HV",
+ direction="l",
+ linebreak="al",
+ uccode=0x01F6,
+ unicodeslot=0x0195,
+ },
+ {
+ adobename="Iotaafrican",
+ category="lu",
+ description="LATIN CAPITAL LETTER IOTA",
+ direction="l",
+ lccode=0x0269,
+ linebreak="al",
+ unicodeslot=0x0196,
+ },
+ {
+ adobename="Istroke",
+ category="lu",
+ contextname="Istroke",
+ description="LATIN CAPITAL LETTER I WITH STROKE",
+ direction="l",
+ lccode=0x0268,
+ linebreak="al",
+ shcode=0x0049,
+ unicodeslot=0x0197,
+ },
+ {
+ adobename="Khook",
+ category="lu",
+ contextname="Khook",
+ description="LATIN CAPITAL LETTER K WITH HOOK",
+ direction="l",
+ lccode=0x0199,
+ linebreak="al",
+ shcode=0x004B,
+ unicodeslot=0x0198,
+ },
+ {
+ adobename="khook",
+ category="ll",
+ contextname="khook",
+ description="LATIN SMALL LETTER K WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x006B,
+ uccode=0x0198,
+ unicodeslot=0x0199,
+ },
+ {
+ adobename="lbar",
+ category="ll",
+ contextname="lbar",
+ description="LATIN SMALL LETTER L WITH BAR",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ uccode=0x023D,
+ unicodeslot=0x019A,
+ },
+ {
+ adobename="lambdastroke",
+ category="ll",
+ description="LATIN SMALL LETTER LAMBDA WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x019B,
+ },
+ {
+ adobename="Mturned",
+ category="lu",
+ description="LATIN CAPITAL LETTER TURNED M",
+ direction="l",
+ lccode=0x026F,
+ linebreak="al",
+ unicodeslot=0x019C,
+ },
+ {
+ adobename="Nhookleft",
+ category="lu",
+ description="LATIN CAPITAL LETTER N WITH LEFT HOOK",
+ direction="l",
+ lccode=0x0272,
+ linebreak="al",
+ shcode=0x004E,
+ unicodeslot=0x019D,
+ },
+ {
+ adobename="nlegrightlong",
+ category="ll",
+ description="LATIN SMALL LETTER N WITH LONG RIGHT LEG",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ uccode=0x0220,
+ unicodeslot=0x019E,
+ },
+ {
+ adobename="Ocenteredtilde",
+ category="lu",
+ description="LATIN CAPITAL LETTER O WITH MIDDLE TILDE",
+ direction="l",
+ lccode=0x0275,
+ linebreak="al",
+ shcode=0x004F,
+ unicodeslot=0x019F,
+ },
+ {
+ adobename="Ohorn",
+ category="lu",
+ contextname="Ohorn",
+ description="LATIN CAPITAL LETTER O WITH HORN",
+ direction="l",
+ lccode=0x01A1,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x031B },
+ unicodeslot=0x01A0,
+ },
+ {
+ adobename="ohorn",
+ category="ll",
+ contextname="ohorn",
+ description="LATIN SMALL LETTER O WITH HORN",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x031B },
+ uccode=0x01A0,
+ unicodeslot=0x01A1,
+ },
+ {
+ adobename="Oi",
+ category="lu",
+ description="LATIN CAPITAL LETTER OI",
+ direction="l",
+ lccode=0x01A3,
+ linebreak="al",
+ unicodeslot=0x01A2,
+ },
+ {
+ adobename="oi",
+ category="ll",
+ description="LATIN SMALL LETTER OI",
+ direction="l",
+ linebreak="al",
+ uccode=0x01A2,
+ unicodeslot=0x01A3,
+ },
+ {
+ adobename="Phook",
+ category="lu",
+ contextname="Phook",
+ description="LATIN CAPITAL LETTER P WITH HOOK",
+ direction="l",
+ lccode=0x01A5,
+ linebreak="al",
+ shcode=0x0050,
+ unicodeslot=0x01A4,
+ },
+ {
+ adobename="phook",
+ category="ll",
+ contextname="phook",
+ description="LATIN SMALL LETTER P WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0070,
+ uccode=0x01A4,
+ unicodeslot=0x01A5,
+ },
+ {
+ adobename="yr",
+ category="lu",
+ description="LATIN LETTER YR",
+ direction="l",
+ lccode=0x0280,
+ linebreak="al",
+ unicodeslot=0x01A6,
+ },
+ {
+ adobename="Tonetwo",
+ category="lu",
+ description="LATIN CAPITAL LETTER TONE TWO",
+ direction="l",
+ lccode=0x01A8,
+ linebreak="al",
+ unicodeslot=0x01A7,
+ },
+ {
+ adobename="tonetwo",
+ category="ll",
+ description="LATIN SMALL LETTER TONE TWO",
+ direction="l",
+ linebreak="al",
+ uccode=0x01A7,
+ unicodeslot=0x01A8,
+ },
+ {
+ adobename="Esh",
+ category="lu",
+ description="LATIN CAPITAL LETTER ESH",
+ direction="l",
+ lccode=0x0283,
+ linebreak="al",
+ unicodeslot=0x01A9,
+ },
+ {
+ adobename="eshreversedloop",
+ category="ll",
+ description="LATIN LETTER REVERSED ESH LOOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x01AA,
+ },
+ {
+ adobename="tpalatalhook",
+ category="ll",
+ description="LATIN SMALL LETTER T WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ unicodeslot=0x01AB,
+ },
+ {
+ adobename="Thook",
+ category="lu",
+ contextname="Thook",
+ description="LATIN CAPITAL LETTER T WITH HOOK",
+ direction="l",
+ lccode=0x01AD,
+ linebreak="al",
+ shcode=0x0054,
+ unicodeslot=0x01AC,
+ },
+ {
+ adobename="thook",
+ category="ll",
+ contextname="thook",
+ description="LATIN SMALL LETTER T WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ uccode=0x01AC,
+ unicodeslot=0x01AD,
+ },
+ {
+ adobename="Tretroflexhook",
+ category="lu",
+ description="LATIN CAPITAL LETTER T WITH RETROFLEX HOOK",
+ direction="l",
+ lccode=0x0288,
+ linebreak="al",
+ shcode=0x0054,
+ unicodeslot=0x01AE,
+ },
+ {
+ adobename="Uhorn",
+ category="lu",
+ contextname="Uhorn",
+ description="LATIN CAPITAL LETTER U WITH HORN",
+ direction="l",
+ lccode=0x01B0,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x031B },
+ unicodeslot=0x01AF,
+ },
+ {
+ adobename="uhorn",
+ category="ll",
+ contextname="uhorn",
+ description="LATIN SMALL LETTER U WITH HORN",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x031B },
+ uccode=0x01AF,
+ unicodeslot=0x01B0,
+ },
+ {
+ adobename="Upsilonafrican",
+ category="lu",
+ description="LATIN CAPITAL LETTER UPSILON",
+ direction="l",
+ lccode=0x028A,
+ linebreak="al",
+ unicodeslot=0x01B1,
+ },
+ {
+ adobename="Vhook",
+ category="lu",
+ contextname="Uhook",
+ description="LATIN CAPITAL LETTER V WITH HOOK",
+ direction="l",
+ lccode=0x028B,
+ linebreak="al",
+ shcode=0x0056,
+ unicodeslot=0x01B2,
+ },
+ {
+ adobename="Yhook",
+ category="lu",
+ contextname="Yhook",
+ description="LATIN CAPITAL LETTER Y WITH HOOK",
+ direction="l",
+ lccode=0x01B4,
+ linebreak="al",
+ shcode=0x0059,
+ unicodeslot=0x01B3,
+ },
+ {
+ adobename="yhook",
+ category="ll",
+ contextname="yhook",
+ description="LATIN SMALL LETTER Y WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0079,
+ uccode=0x01B3,
+ unicodeslot=0x01B4,
+ },
+ {
+ adobename="Zstroke",
+ category="lu",
+ contextname="Zstroke",
+ description="LATIN CAPITAL LETTER Z WITH STROKE",
+ direction="l",
+ lccode=0x01B6,
+ linebreak="al",
+ shcode=0x005A,
+ unicodeslot=0x01B5,
+ },
+ {
+ adobename="zstroke",
+ category="ll",
+ contextname="zstroke",
+ description="LATIN SMALL LETTER Z WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ uccode=0x01B5,
+ unicodeslot=0x01B6,
+ },
+ {
+ adobename="Ezh",
+ category="lu",
+ description="LATIN CAPITAL LETTER EZH",
+ direction="l",
+ lccode=0x0292,
+ linebreak="al",
+ unicodeslot=0x01B7,
+ },
+ {
+ adobename="Ezhreversed",
+ category="lu",
+ description="LATIN CAPITAL LETTER EZH REVERSED",
+ direction="l",
+ lccode=0x01B9,
+ linebreak="al",
+ unicodeslot=0x01B8,
+ },
+ {
+ adobename="ezhreversed",
+ category="ll",
+ description="LATIN SMALL LETTER EZH REVERSED",
+ direction="l",
+ linebreak="al",
+ uccode=0x01B8,
+ unicodeslot=0x01B9,
+ },
+ {
+ adobename="ezhtail",
+ category="ll",
+ description="LATIN SMALL LETTER EZH WITH TAIL",
+ direction="l",
+ linebreak="al",
+ shcode=0x0292,
+ unicodeslot=0x01BA,
+ },
+ {
+ adobename="twostroke",
+ category="lo",
+ description="LATIN LETTER TWO WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x01BB,
+ },
+ {
+ adobename="Tonefive",
+ category="lu",
+ description="LATIN CAPITAL LETTER TONE FIVE",
+ direction="l",
+ lccode=0x01BD,
+ linebreak="al",
+ unicodeslot=0x01BC,
+ },
+ {
+ adobename="tonefive",
+ category="ll",
+ description="LATIN SMALL LETTER TONE FIVE",
+ direction="l",
+ linebreak="al",
+ uccode=0x01BC,
+ unicodeslot=0x01BD,
+ },
+ {
+ adobename="glottalinvertedstroke",
+ category="ll",
+ description="LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x01BE,
+ },
+ {
+ adobename="wynn",
+ category="ll",
+ description="LATIN LETTER WYNN",
+ direction="l",
+ linebreak="al",
+ uccode=0x01F7,
+ unicodeslot=0x01BF,
+ },
+ {
+ adobename="clickdental",
+ category="lo",
+ description="LATIN LETTER DENTAL CLICK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x01C0,
+ },
+ {
+ adobename="clicklateral",
+ category="lo",
+ description="LATIN LETTER LATERAL CLICK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x01C1,
+ },
+ {
+ adobename="clickalveolar",
+ category="lo",
+ description="LATIN LETTER ALVEOLAR CLICK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x01C2,
+ },
+ {
+ adobename="clickretroflex",
+ category="lo",
+ description="LATIN LETTER RETROFLEX CLICK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x01C3,
+ },
+ {
+ adobename="DZcaron",
+ category="lu",
+ contextname="DZcaronligature",
+ description="LATIN CAPITAL LETTER DZ WITH CARON",
+ direction="l",
+ lccode=0x01C6,
+ linebreak="al",
+ shcode=0x01F1,
+ specials={ "compat", 0x0044, 0x017D },
+ uccode=0x01C5,
+ unicodeslot=0x01C4,
+ },
+ {
+ adobename="Dzcaron",
+ category="lt",
+ contextname="Dzcaronligature",
+ description="LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON",
+ direction="l",
+ lccode=0x01C6,
+ linebreak="al",
+ shcode=0x01F2,
+ specials={ "compat", 0x0044, 0x017E },
+ uccode=0x01C4,
+ unicodeslot=0x01C5,
+ },
+ {
+ adobename="dzcaron",
+ category="ll",
+ contextname="dzcaronligature",
+ description="LATIN SMALL LETTER DZ WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x01F3,
+ specials={ "compat", 0x0064, 0x017E },
+ uccode=0x01C4,
+ unicodeslot=0x01C6,
+ },
+ {
+ adobename="LJ",
+ category="lu",
+ contextname="LJligature",
+ description="LATIN CAPITAL LETTER LJ",
+ direction="l",
+ lccode=0x01C9,
+ linebreak="al",
+ shcode={ 0x004C, 0x004A },
+ specials={ "compat", 0x004C, 0x004A },
+ uccode=0x01C8,
+ unicodeslot=0x01C7,
+ },
+ {
+ adobename="Lj",
+ category="lt",
+ contextname="Ljligature",
+ description="LATIN CAPITAL LETTER L WITH SMALL LETTER J",
+ direction="l",
+ lccode=0x01C9,
+ linebreak="al",
+ shcode={ 0x004C, 0x006A },
+ specials={ "compat", 0x004C, 0x006A },
+ uccode=0x01C7,
+ unicodeslot=0x01C8,
+ },
+ {
+ adobename="lj",
+ category="ll",
+ contextname="ljligature",
+ description="LATIN SMALL LETTER LJ",
+ direction="l",
+ linebreak="al",
+ shcode={ 0x006C, 0x006A },
+ specials={ "compat", 0x006C, 0x006A },
+ uccode=0x01C7,
+ unicodeslot=0x01C9,
+ },
+ {
+ adobename="NJ",
+ category="lu",
+ contextname="NJligature",
+ description="LATIN CAPITAL LETTER NJ",
+ direction="l",
+ lccode=0x01CC,
+ linebreak="al",
+ shcode={ 0x004E, 0x004A },
+ specials={ "compat", 0x004E, 0x004A },
+ uccode=0x01CB,
+ unicodeslot=0x01CA,
+ },
+ {
+ adobename="Nj",
+ category="lt",
+ contextname="Njligature",
+ description="LATIN CAPITAL LETTER N WITH SMALL LETTER J",
+ direction="l",
+ lccode=0x01CC,
+ linebreak="al",
+ shcode=0x004E,
+ specials={ "compat", 0x004E, 0x006A },
+ uccode=0x01CA,
+ unicodeslot=0x01CB,
+ },
+ {
+ adobename="nj",
+ category="ll",
+ contextname="njligature",
+ description="LATIN SMALL LETTER NJ",
+ direction="l",
+ linebreak="al",
+ shcode={ 0x006E, 0x006A },
+ specials={ "compat", 0x006E, 0x006A },
+ uccode=0x01CA,
+ unicodeslot=0x01CC,
+ },
+ {
+ adobename="Acaron",
+ category="lu",
+ contextname="Acaron",
+ description="LATIN CAPITAL LETTER A WITH CARON",
+ direction="l",
+ lccode=0x01CE,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x030C },
+ unicodeslot=0x01CD,
+ },
+ {
+ adobename="acaron",
+ category="ll",
+ cjkwd="a",
+ contextname="acaron",
+ description="LATIN SMALL LETTER A WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x030C },
+ uccode=0x01CD,
+ unicodeslot=0x01CE,
+ },
+ {
+ adobename="Icaron",
+ category="lu",
+ contextname="Icaron",
+ description="LATIN CAPITAL LETTER I WITH CARON",
+ direction="l",
+ lccode=0x01D0,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x030C },
+ unicodeslot=0x01CF,
+ },
+ {
+ adobename="icaron",
+ category="ll",
+ cjkwd="a",
+ contextname="icaron",
+ description="LATIN SMALL LETTER I WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x030C },
+ uccode=0x01CF,
+ unicodeslot=0x01D0,
+ },
+ {
+ adobename="Ocaron",
+ category="lu",
+ contextname="Ocaron",
+ description="LATIN CAPITAL LETTER O WITH CARON",
+ direction="l",
+ lccode=0x01D2,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x030C },
+ unicodeslot=0x01D1,
+ },
+ {
+ adobename="ocaron",
+ category="ll",
+ cjkwd="a",
+ contextname="ocaron",
+ description="LATIN SMALL LETTER O WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x030C },
+ uccode=0x01D1,
+ unicodeslot=0x01D2,
+ },
+ {
+ adobename="Ucaron",
+ category="lu",
+ contextname="Ucaron",
+ description="LATIN CAPITAL LETTER U WITH CARON",
+ direction="l",
+ lccode=0x01D4,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x030C },
+ unicodeslot=0x01D3,
+ },
+ {
+ adobename="ucaron",
+ category="ll",
+ cjkwd="a",
+ contextname="ucaron",
+ description="LATIN SMALL LETTER U WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x030C },
+ uccode=0x01D3,
+ unicodeslot=0x01D4,
+ },
+ {
+ adobename="Udieresismacron",
+ category="lu",
+ contextname="Udiaeresismacron",
+ description="LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON",
+ direction="l",
+ lccode=0x01D6,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x00DC, 0x0304 },
+ unicodeslot=0x01D5,
+ },
+ {
+ adobename="udieresismacron",
+ category="ll",
+ cjkwd="a",
+ contextname="udiaeresismacron",
+ description="LATIN SMALL LETTER U WITH DIAERESIS AND MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x00FC, 0x0304 },
+ uccode=0x01D5,
+ unicodeslot=0x01D6,
+ },
+ {
+ adobename="Udieresisacute",
+ category="lu",
+ contextname="Udiaeresisacute",
+ description="LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE",
+ direction="l",
+ lccode=0x01D8,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x00DC, 0x0301 },
+ unicodeslot=0x01D7,
+ },
+ {
+ adobename="udieresisacute",
+ category="ll",
+ cjkwd="a",
+ contextname="udiaeresisacute",
+ description="LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x00FC, 0x0301 },
+ uccode=0x01D7,
+ unicodeslot=0x01D8,
+ },
+ {
+ adobename="Udieresiscaron",
+ category="lu",
+ contextname="Udiaeresiscaron",
+ description="LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON",
+ direction="l",
+ lccode=0x01DA,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x00DC, 0x030C },
+ unicodeslot=0x01D9,
+ },
+ {
+ adobename="udieresiscaron",
+ category="ll",
+ cjkwd="a",
+ contextname="udiaeresiscaron",
+ description="LATIN SMALL LETTER U WITH DIAERESIS AND CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x00FC, 0x030C },
+ uccode=0x01D9,
+ unicodeslot=0x01DA,
+ },
+ {
+ adobename="Udieresisgrave",
+ category="lu",
+ contextname="Udiaeresisgrave",
+ description="LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE",
+ direction="l",
+ lccode=0x01DC,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x00DC, 0x0300 },
+ unicodeslot=0x01DB,
+ },
+ {
+ adobename="udieresisgrave",
+ category="ll",
+ cjkwd="a",
+ contextname="udiaeresisgrave",
+ description="LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x00FC, 0x0300 },
+ uccode=0x01DB,
+ unicodeslot=0x01DC,
+ },
+ {
+ adobename="eturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED E",
+ direction="l",
+ linebreak="al",
+ uccode=0x018E,
+ unicodeslot=0x01DD,
+ },
+ {
+ adobename="Adieresismacron",
+ category="lu",
+ contextname="Adiaeresismacron",
+ description="LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON",
+ direction="l",
+ lccode=0x01DF,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x00C4, 0x0304 },
+ unicodeslot=0x01DE,
+ },
+ {
+ adobename="adieresismacron",
+ category="ll",
+ contextname="adiaeresismacron",
+ description="LATIN SMALL LETTER A WITH DIAERESIS AND MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x00E4, 0x0304 },
+ uccode=0x01DE,
+ unicodeslot=0x01DF,
+ },
+ {
+ adobename="Adotmacron",
+ category="lu",
+ contextname="Adotaccentmacron",
+ description="LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON",
+ direction="l",
+ lccode=0x01E1,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0226, 0x0304 },
+ unicodeslot=0x01E0,
+ },
+ {
+ adobename="adotmacron",
+ category="ll",
+ contextname="adotaccentmacron",
+ description="LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0227, 0x0304 },
+ uccode=0x01E0,
+ unicodeslot=0x01E1,
+ },
+ {
+ adobename="AEmacron",
+ category="lu",
+ contextname="AEmacron",
+ description="LATIN CAPITAL LETTER AE WITH MACRON",
+ direction="l",
+ lccode=0x01E3,
+ linebreak="al",
+ shcode=0x00C6,
+ specials={ "char", 0x00C6, 0x0304 },
+ unicodeslot=0x01E2,
+ },
+ {
+ adobename="aemacron",
+ category="ll",
+ contextname="aemacron",
+ description="LATIN SMALL LETTER AE WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x00E6,
+ specials={ "char", 0x00E6, 0x0304 },
+ uccode=0x01E2,
+ unicodeslot=0x01E3,
+ },
+ {
+ adobename="Gstroke",
+ category="lu",
+ contextname="Gstroke",
+ description="LATIN CAPITAL LETTER G WITH STROKE",
+ direction="l",
+ lccode=0x01E5,
+ linebreak="al",
+ shcode=0x0047,
+ unicodeslot=0x01E4,
+ },
+ {
+ adobename="gstroke",
+ category="ll",
+ contextname="gstroke",
+ description="LATIN SMALL LETTER G WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0067,
+ uccode=0x01E4,
+ unicodeslot=0x01E5,
+ },
+ {
+ adobename="Gcaron",
+ category="lu",
+ contextname="Gcaron",
+ description="LATIN CAPITAL LETTER G WITH CARON",
+ direction="l",
+ lccode=0x01E7,
+ linebreak="al",
+ shcode=0x0047,
+ specials={ "char", 0x0047, 0x030C },
+ unicodeslot=0x01E6,
+ },
+ {
+ adobename="gcaron",
+ category="ll",
+ contextname="gcaron",
+ description="LATIN SMALL LETTER G WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0067,
+ specials={ "char", 0x0067, 0x030C },
+ uccode=0x01E6,
+ unicodeslot=0x01E7,
+ },
+ {
+ adobename="Kcaron",
+ category="lu",
+ contextname="Kcaron",
+ description="LATIN CAPITAL LETTER K WITH CARON",
+ direction="l",
+ lccode=0x01E9,
+ linebreak="al",
+ shcode=0x004B,
+ specials={ "char", 0x004B, 0x030C },
+ unicodeslot=0x01E8,
+ },
+ {
+ adobename="kcaron",
+ category="ll",
+ contextname="kcaron",
+ description="LATIN SMALL LETTER K WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x006B,
+ specials={ "char", 0x006B, 0x030C },
+ uccode=0x01E8,
+ unicodeslot=0x01E9,
+ },
+ {
+ adobename="Oogonek",
+ category="lu",
+ contextname="Oogonek",
+ description="LATIN CAPITAL LETTER O WITH OGONEK",
+ direction="l",
+ lccode=0x01EB,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x0328 },
+ unicodeslot=0x01EA,
+ },
+ {
+ adobename="oogonek",
+ category="ll",
+ contextname="oogonek",
+ description="LATIN SMALL LETTER O WITH OGONEK",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x0328 },
+ uccode=0x01EA,
+ unicodeslot=0x01EB,
+ },
+ {
+ adobename="Oogonekmacron",
+ category="lu",
+ contextname="Oogonekmacron",
+ description="LATIN CAPITAL LETTER O WITH OGONEK AND MACRON",
+ direction="l",
+ lccode=0x01ED,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x01EA, 0x0304 },
+ unicodeslot=0x01EC,
+ },
+ {
+ adobename="oogonekmacron",
+ category="ll",
+ contextname="oogonekmacron",
+ description="LATIN SMALL LETTER O WITH OGONEK AND MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x01EB, 0x0304 },
+ uccode=0x01EC,
+ unicodeslot=0x01ED,
+ },
+ {
+ adobename="Ezhcaron",
+ category="lu",
+ description="LATIN CAPITAL LETTER EZH WITH CARON",
+ direction="l",
+ lccode=0x01EF,
+ linebreak="al",
+ shcode=0x01B7,
+ specials={ "char", 0x01B7, 0x030C },
+ unicodeslot=0x01EE,
+ },
+ {
+ adobename="ezhcaron",
+ category="ll",
+ description="LATIN SMALL LETTER EZH WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0292,
+ specials={ "char", 0x0292, 0x030C },
+ uccode=0x01EE,
+ unicodeslot=0x01EF,
+ },
+ {
+ adobename="jcaron",
+ category="ll",
+ contextname="jcaron",
+ description="LATIN SMALL LETTER J WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x006A,
+ specials={ "char", 0x006A, 0x030C },
+ unicodeslot=0x01F0,
+ },
+ {
+ adobename="DZ",
+ category="lu",
+ contextname="DZligature",
+ description="LATIN CAPITAL LETTER DZ",
+ direction="l",
+ lccode=0x01F3,
+ linebreak="al",
+ specials={ "compat", 0x0044, 0x005A },
+ uccode=0x01F2,
+ unicodeslot=0x01F1,
+ },
+ {
+ adobename="Dz",
+ category="lt",
+ contextname="Dzligature",
+ description="LATIN CAPITAL LETTER D WITH SMALL LETTER Z",
+ direction="l",
+ lccode=0x01F3,
+ linebreak="al",
+ shcode=0x0044,
+ specials={ "compat", 0x0044, 0x007A },
+ uccode=0x01F1,
+ unicodeslot=0x01F2,
+ },
+ {
+ adobename="dz",
+ category="ll",
+ contextname="dzligature",
+ description="LATIN SMALL LETTER DZ",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0064, 0x007A },
+ uccode=0x01F1,
+ unicodeslot=0x01F3,
+ },
+ {
+ adobename="Gacute",
+ category="lu",
+ contextname="Gacute",
+ description="LATIN CAPITAL LETTER G WITH ACUTE",
+ direction="l",
+ lccode=0x01F5,
+ linebreak="al",
+ shcode=0x0047,
+ specials={ "char", 0x0047, 0x0301 },
+ unicodeslot=0x01F4,
+ },
+ {
+ adobename="gacute",
+ category="ll",
+ contextname="gacute",
+ description="LATIN SMALL LETTER G WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0067,
+ specials={ "char", 0x0067, 0x0301 },
+ uccode=0x01F4,
+ unicodeslot=0x01F5,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER HWAIR",
+ direction="l",
+ lccode=0x0195,
+ linebreak="al",
+ unicodeslot=0x01F6,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER WYNN",
+ direction="l",
+ lccode=0x01BF,
+ linebreak="al",
+ unicodeslot=0x01F7,
+ },
+ {
+ category="lu",
+ contextname="Ngrave",
+ description="LATIN CAPITAL LETTER N WITH GRAVE",
+ direction="l",
+ lccode=0x01F9,
+ linebreak="al",
+ shcode=0x004E,
+ specials={ "char", 0x004E, 0x0300 },
+ unicodeslot=0x01F8,
+ },
+ {
+ category="ll",
+ contextname="ngrave",
+ description="LATIN SMALL LETTER N WITH GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ specials={ "char", 0x006E, 0x0300 },
+ uccode=0x01F8,
+ unicodeslot=0x01F9,
+ },
+ {
+ adobename="Aringacute",
+ category="lu",
+ contextname="Aringacute",
+ description="LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE",
+ direction="l",
+ lccode=0x01FB,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x00C5, 0x0301 },
+ unicodeslot=0x01FA,
+ },
+ {
+ adobename="aringacute",
+ category="ll",
+ contextname="aringacute",
+ description="LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x00E5, 0x0301 },
+ uccode=0x01FA,
+ unicodeslot=0x01FB,
+ },
+ {
+ adobename="AEacute",
+ category="lu",
+ contextname="AEacute",
+ description="LATIN CAPITAL LETTER AE WITH ACUTE",
+ direction="l",
+ lccode=0x01FD,
+ linebreak="al",
+ shcode=0x00C6,
+ specials={ "char", 0x00C6, 0x0301 },
+ unicodeslot=0x01FC,
+ },
+ {
+ adobename="aeacute",
+ category="ll",
+ contextname="aeacute",
+ description="LATIN SMALL LETTER AE WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x00E6,
+ specials={ "char", 0x00E6, 0x0301 },
+ uccode=0x01FC,
+ unicodeslot=0x01FD,
+ },
+ {
+ adobename="Ostrokeacute",
+ category="lu",
+ contextname="Ostrokeacute",
+ description="LATIN CAPITAL LETTER O WITH STROKE AND ACUTE",
+ direction="l",
+ lccode=0x01FF,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x00D8, 0x0301 },
+ unicodeslot=0x01FE,
+ },
+ {
+ adobename="ostrokeacute",
+ category="ll",
+ contextname="ostrokeacute",
+ description="LATIN SMALL LETTER O WITH STROKE AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x00F8, 0x0301 },
+ uccode=0x01FE,
+ unicodeslot=0x01FF,
+ },
+ {
+ adobename="Adblgrave",
+ category="lu",
+ contextname="Adoublegrave",
+ description="LATIN CAPITAL LETTER A WITH DOUBLE GRAVE",
+ direction="l",
+ lccode=0x0201,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x030F },
+ unicodeslot=0x0200,
+ },
+ {
+ adobename="adblgrave",
+ category="ll",
+ contextname="adoublegrave",
+ description="LATIN SMALL LETTER A WITH DOUBLE GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x030F },
+ uccode=0x0200,
+ unicodeslot=0x0201,
+ },
+ {
+ adobename="Ainvertedbreve",
+ category="lu",
+ contextname="Ainvertedbreve",
+ description="LATIN CAPITAL LETTER A WITH INVERTED BREVE",
+ direction="l",
+ lccode=0x0203,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0311 },
+ unicodeslot=0x0202,
+ },
+ {
+ adobename="ainvertedbreve",
+ category="ll",
+ contextname="ainvertedbreve",
+ description="LATIN SMALL LETTER A WITH INVERTED BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0311 },
+ uccode=0x0202,
+ unicodeslot=0x0203,
+ },
+ {
+ adobename="Edblgrave",
+ category="lu",
+ contextname="Edoublegrave",
+ description="LATIN CAPITAL LETTER E WITH DOUBLE GRAVE",
+ direction="l",
+ lccode=0x0205,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x030F },
+ unicodeslot=0x0204,
+ },
+ {
+ adobename="edblgrave",
+ category="ll",
+ contextname="edoublegrave",
+ description="LATIN SMALL LETTER E WITH DOUBLE GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x030F },
+ uccode=0x0204,
+ unicodeslot=0x0205,
+ },
+ {
+ adobename="Einvertedbreve",
+ category="lu",
+ contextname="Einvertedbreve",
+ description="LATIN CAPITAL LETTER E WITH INVERTED BREVE",
+ direction="l",
+ lccode=0x0207,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0311 },
+ unicodeslot=0x0206,
+ },
+ {
+ adobename="einvertedbreve",
+ category="ll",
+ contextname="einvertedbreve",
+ description="LATIN SMALL LETTER E WITH INVERTED BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0311 },
+ uccode=0x0206,
+ unicodeslot=0x0207,
+ },
+ {
+ adobename="Idblgrave",
+ category="lu",
+ contextname="Idoublegrave",
+ description="LATIN CAPITAL LETTER I WITH DOUBLE GRAVE",
+ direction="l",
+ lccode=0x0209,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x030F },
+ unicodeslot=0x0208,
+ },
+ {
+ adobename="idblgrave",
+ category="ll",
+ contextname="idoublegrave",
+ description="LATIN SMALL LETTER I WITH DOUBLE GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x030F },
+ uccode=0x0208,
+ unicodeslot=0x0209,
+ },
+ {
+ adobename="Iinvertedbreve",
+ category="lu",
+ contextname="Iinvertedbreve",
+ description="LATIN CAPITAL LETTER I WITH INVERTED BREVE",
+ direction="l",
+ lccode=0x020B,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0311 },
+ unicodeslot=0x020A,
+ },
+ {
+ adobename="iinvertedbreve",
+ category="ll",
+ contextname="iinvertedbreve",
+ description="LATIN SMALL LETTER I WITH INVERTED BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x0311 },
+ uccode=0x020A,
+ unicodeslot=0x020B,
+ },
+ {
+ adobename="Odblgrave",
+ category="lu",
+ contextname="Odoublegrave",
+ description="LATIN CAPITAL LETTER O WITH DOUBLE GRAVE",
+ direction="l",
+ lccode=0x020D,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x030F },
+ unicodeslot=0x020C,
+ },
+ {
+ adobename="odblgrave",
+ category="ll",
+ contextname="odoublegrave",
+ description="LATIN SMALL LETTER O WITH DOUBLE GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x030F },
+ uccode=0x020C,
+ unicodeslot=0x020D,
+ },
+ {
+ adobename="Oinvertedbreve",
+ category="lu",
+ contextname="Oinvertedbreve",
+ description="LATIN CAPITAL LETTER O WITH INVERTED BREVE",
+ direction="l",
+ lccode=0x020F,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x0311 },
+ unicodeslot=0x020E,
+ },
+ {
+ adobename="oinvertedbreve",
+ category="ll",
+ contextname="oinvertedbreve",
+ description="LATIN SMALL LETTER O WITH INVERTED BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x0311 },
+ uccode=0x020E,
+ unicodeslot=0x020F,
+ },
+ {
+ adobename="Rdblgrave",
+ category="lu",
+ contextname="Rdoublegrave",
+ description="LATIN CAPITAL LETTER R WITH DOUBLE GRAVE",
+ direction="l",
+ lccode=0x0211,
+ linebreak="al",
+ shcode=0x0052,
+ specials={ "char", 0x0052, 0x030F },
+ unicodeslot=0x0210,
+ },
+ {
+ adobename="rdblgrave",
+ category="ll",
+ contextname="rdoublegrave",
+ description="LATIN SMALL LETTER R WITH DOUBLE GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ specials={ "char", 0x0072, 0x030F },
+ uccode=0x0210,
+ unicodeslot=0x0211,
+ },
+ {
+ adobename="Rinvertedbreve",
+ category="lu",
+ contextname="Rinvertedbreve",
+ description="LATIN CAPITAL LETTER R WITH INVERTED BREVE",
+ direction="l",
+ lccode=0x0213,
+ linebreak="al",
+ shcode=0x0052,
+ specials={ "char", 0x0052, 0x0311 },
+ unicodeslot=0x0212,
+ },
+ {
+ adobename="rinvertedbreve",
+ category="ll",
+ contextname="rinvertedbreve",
+ description="LATIN SMALL LETTER R WITH INVERTED BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ specials={ "char", 0x0072, 0x0311 },
+ uccode=0x0212,
+ unicodeslot=0x0213,
+ },
+ {
+ adobename="Udblgrave",
+ category="lu",
+ contextname="Udoublegrave",
+ description="LATIN CAPITAL LETTER U WITH DOUBLE GRAVE",
+ direction="l",
+ lccode=0x0215,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x030F },
+ unicodeslot=0x0214,
+ },
+ {
+ adobename="udblgrave",
+ category="ll",
+ contextname="udoublegrave",
+ description="LATIN SMALL LETTER U WITH DOUBLE GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x030F },
+ uccode=0x0214,
+ unicodeslot=0x0215,
+ },
+ {
+ adobename="Uinvertedbreve",
+ category="lu",
+ contextname="Uinvertedbreve",
+ description="LATIN CAPITAL LETTER U WITH INVERTED BREVE",
+ direction="l",
+ lccode=0x0217,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0311 },
+ unicodeslot=0x0216,
+ },
+ {
+ adobename="uinvertedbreve",
+ category="ll",
+ contextname="uinvertedbreve",
+ description="LATIN SMALL LETTER U WITH INVERTED BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0311 },
+ uccode=0x0216,
+ unicodeslot=0x0217,
+ },
+ {
+ adobename="Scommaaccent",
+ category="lu",
+ contextname="Scommaaccent",
+ description="LATIN CAPITAL LETTER S WITH COMMA BELOW",
+ direction="l",
+ lccode=0x0219,
+ linebreak="al",
+ shcode=0x0053,
+ specials={ "char", 0x0053, 0x0326 },
+ unicodeslot=0x0218,
+ },
+ {
+ adobename="scommaaccent",
+ category="ll",
+ contextname="scommaaccent",
+ description="LATIN SMALL LETTER S WITH COMMA BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ specials={ "char", 0x0073, 0x0326 },
+ uccode=0x0218,
+ unicodeslot=0x0219,
+ },
+ {
+ category="lu",
+ contextname="Tcommaaccent",
+ description="LATIN CAPITAL LETTER T WITH COMMA BELOW",
+ direction="l",
+ lccode=0x021B,
+ linebreak="al",
+ shcode=0x0054,
+ specials={ "char", 0x0054, 0x0326 },
+ unicodeslot=0x021A,
+ },
+ {
+ category="ll",
+ contextname="tcommaaccent",
+ description="LATIN SMALL LETTER T WITH COMMA BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ specials={ "char", 0x0074, 0x0326 },
+ uccode=0x021A,
+ unicodeslot=0x021B,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER YOGH",
+ direction="l",
+ lccode=0x021D,
+ linebreak="al",
+ unicodeslot=0x021C,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER YOGH",
+ direction="l",
+ linebreak="al",
+ uccode=0x021C,
+ unicodeslot=0x021D,
+ },
+ {
+ category="lu",
+ contextname="Hcaron",
+ description="LATIN CAPITAL LETTER H WITH CARON",
+ direction="l",
+ lccode=0x021F,
+ linebreak="al",
+ shcode=0x0048,
+ specials={ "char", 0x0048, 0x030C },
+ unicodeslot=0x021E,
+ },
+ {
+ category="ll",
+ contextname="hcaron",
+ description="LATIN SMALL LETTER H WITH CARON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0068,
+ specials={ "char", 0x0068, 0x030C },
+ uccode=0x021E,
+ unicodeslot=0x021F,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER N WITH LONG RIGHT LEG",
+ direction="l",
+ lccode=0x019E,
+ linebreak="al",
+ shcode=0x004E,
+ unicodeslot=0x0220,
+ },
+ {
+ category="ll",
+ contextname="dcurl",
+ description="LATIN SMALL LETTER D WITH CURL",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ unicodeslot=0x0221,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER OU",
+ direction="l",
+ lccode=0x0223,
+ linebreak="al",
+ unicodeslot=0x0222,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER OU",
+ direction="l",
+ linebreak="al",
+ uccode=0x0222,
+ unicodeslot=0x0223,
+ },
+ {
+ category="lu",
+ contextname="Zhook",
+ description="LATIN CAPITAL LETTER Z WITH HOOK",
+ direction="l",
+ lccode=0x0225,
+ linebreak="al",
+ shcode=0x005A,
+ unicodeslot=0x0224,
+ },
+ {
+ category="ll",
+ contextname="zhook",
+ description="LATIN SMALL LETTER Z WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ uccode=0x0224,
+ unicodeslot=0x0225,
+ },
+ {
+ category="lu",
+ contextname="Adotaccent",
+ description="LATIN CAPITAL LETTER A WITH DOT ABOVE",
+ direction="l",
+ lccode=0x0227,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0307 },
+ unicodeslot=0x0226,
+ },
+ {
+ category="ll",
+ contextname="adotaccent",
+ description="LATIN SMALL LETTER A WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0307 },
+ uccode=0x0226,
+ unicodeslot=0x0227,
+ },
+ {
+ category="lu",
+ contextname="Ecedilla",
+ description="LATIN CAPITAL LETTER E WITH CEDILLA",
+ direction="l",
+ lccode=0x0229,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0327 },
+ unicodeslot=0x0228,
+ },
+ {
+ category="ll",
+ contextname="ecedilla",
+ description="LATIN SMALL LETTER E WITH CEDILLA",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0327 },
+ uccode=0x0228,
+ unicodeslot=0x0229,
+ },
+ {
+ category="lu",
+ contextname="Odiaeresismacron",
+ description="LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON",
+ direction="l",
+ lccode=0x022B,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x00D6, 0x0304 },
+ unicodeslot=0x022A,
+ },
+ {
+ category="ll",
+ contextname="odiaeresismacron",
+ description="LATIN SMALL LETTER O WITH DIAERESIS AND MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x00F6, 0x0304 },
+ uccode=0x022A,
+ unicodeslot=0x022B,
+ },
+ {
+ category="lu",
+ contextname="Otildemacron",
+ description="LATIN CAPITAL LETTER O WITH TILDE AND MACRON",
+ direction="l",
+ lccode=0x022D,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x00D5, 0x0304 },
+ unicodeslot=0x022C,
+ },
+ {
+ category="ll",
+ contextname="otildemacron",
+ description="LATIN SMALL LETTER O WITH TILDE AND MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x00F5, 0x0304 },
+ uccode=0x022C,
+ unicodeslot=0x022D,
+ },
+ {
+ category="lu",
+ contextname="Odotaccent",
+ description="LATIN CAPITAL LETTER O WITH DOT ABOVE",
+ direction="l",
+ lccode=0x022F,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x0307 },
+ unicodeslot=0x022E,
+ },
+ {
+ category="ll",
+ contextname="odotaccent",
+ description="LATIN SMALL LETTER O WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x0307 },
+ uccode=0x022E,
+ unicodeslot=0x022F,
+ },
+ {
+ category="lu",
+ contextname="Odotaccentmacron",
+ description="LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON",
+ direction="l",
+ lccode=0x0231,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x022E, 0x0304 },
+ unicodeslot=0x0230,
+ },
+ {
+ category="ll",
+ contextname="odotaccentmacron",
+ description="LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x022F, 0x0304 },
+ uccode=0x0230,
+ unicodeslot=0x0231,
+ },
+ {
+ category="lu",
+ contextname="Ymacron",
+ description="LATIN CAPITAL LETTER Y WITH MACRON",
+ direction="l",
+ lccode=0x0233,
+ linebreak="al",
+ shcode=0x0059,
+ specials={ "char", 0x0059, 0x0304 },
+ unicodeslot=0x0232,
+ },
+ {
+ category="ll",
+ contextname="ymacron",
+ description="LATIN SMALL LETTER Y WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0079,
+ specials={ "char", 0x0079, 0x0304 },
+ uccode=0x0232,
+ unicodeslot=0x0233,
+ },
+ {
+ category="ll",
+ contextname="lcurl",
+ description="LATIN SMALL LETTER L WITH CURL",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ unicodeslot=0x0234,
+ },
+ {
+ category="ll",
+ contextname="ncurl",
+ description="LATIN SMALL LETTER N WITH CURL",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ unicodeslot=0x0235,
+ },
+ {
+ category="ll",
+ contextname="tcurl",
+ description="LATIN SMALL LETTER T WITH CURL",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ unicodeslot=0x0236,
+ },
+ {
+ category="ll",
+ contextname="dotlessj",
+ description="LATIN SMALL LETTER DOTLESS J",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0237,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER DB DIGRAPH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0238,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER QP DIGRAPH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0239,
+ },
+ {
+ category="lu",
+ contextname="Astroke",
+ description="LATIN CAPITAL LETTER A WITH STROKE",
+ direction="l",
+ lccode=0x2C65,
+ linebreak="al",
+ shcode=0x0041,
+ unicodeslot=0x023A,
+ },
+ {
+ category="lu",
+ contextname="Cstroke",
+ description="LATIN CAPITAL LETTER C WITH STROKE",
+ direction="l",
+ lccode=0x023C,
+ linebreak="al",
+ shcode=0x0043,
+ unicodeslot=0x023B,
+ },
+ {
+ category="ll",
+ contextname="cstroke",
+ description="LATIN SMALL LETTER C WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0063,
+ uccode=0x023B,
+ unicodeslot=0x023C,
+ },
+ {
+ category="lu",
+ contextname="Lbar",
+ description="LATIN CAPITAL LETTER L WITH BAR",
+ direction="l",
+ lccode=0x019A,
+ linebreak="al",
+ shcode=0x004C,
+ unicodeslot=0x023D,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER T WITH DIAGONAL STROKE",
+ direction="l",
+ lccode=0x2C66,
+ linebreak="al",
+ shcode=0x0054,
+ unicodeslot=0x023E,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER S WITH SWASH TAIL",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ unicodeslot=0x023F,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER Z WITH SWASH TAIL",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ unicodeslot=0x0240,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER GLOTTAL STOP",
+ direction="l",
+ lccode=0x0242,
+ linebreak="al",
+ unicodeslot=0x0241,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER GLOTTAL STOP",
+ direction="l",
+ linebreak="al",
+ uccode=0x0241,
+ unicodeslot=0x0242,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER B WITH STROKE",
+ direction="l",
+ lccode=0x0180,
+ linebreak="al",
+ shcode=0x0042,
+ unicodeslot=0x0243,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER U BAR",
+ direction="l",
+ lccode=0x0289,
+ linebreak="al",
+ unicodeslot=0x0244,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER TURNED V",
+ direction="l",
+ lccode=0x028C,
+ linebreak="al",
+ unicodeslot=0x0245,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER E WITH STROKE",
+ direction="l",
+ lccode=0x0247,
+ linebreak="al",
+ shcode=0x0045,
+ unicodeslot=0x0246,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER E WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ uccode=0x0246,
+ unicodeslot=0x0247,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER J WITH STROKE",
+ direction="l",
+ lccode=0x0249,
+ linebreak="al",
+ shcode=0x004A,
+ unicodeslot=0x0248,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER J WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006A,
+ uccode=0x0248,
+ unicodeslot=0x0249,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL",
+ direction="l",
+ lccode=0x024B,
+ linebreak="al",
+ unicodeslot=0x024A,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER Q WITH HOOK TAIL",
+ direction="l",
+ linebreak="al",
+ shcode=0x0071,
+ uccode=0x024A,
+ unicodeslot=0x024B,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER R WITH STROKE",
+ direction="l",
+ lccode=0x024D,
+ linebreak="al",
+ shcode=0x0052,
+ unicodeslot=0x024C,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER R WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ uccode=0x024C,
+ unicodeslot=0x024D,
+ },
+ {
+ category="lu",
+ description="LATIN CAPITAL LETTER Y WITH STROKE",
+ direction="l",
+ lccode=0x024F,
+ linebreak="al",
+ shcode=0x0059,
+ unicodeslot=0x024E,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER Y WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0079,
+ uccode=0x024E,
+ unicodeslot=0x024F,
+ },
+ {
+ adobename="aturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0250,
+ },
+ {
+ adobename="ascript",
+ category="ll",
+ cjkwd="a",
+ description="LATIN SMALL LETTER ALPHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0251,
+ },
+ {
+ adobename="ascriptturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED ALPHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0252,
+ },
+ {
+ adobename="bhook",
+ category="ll",
+ contextname="bhook",
+ description="LATIN SMALL LETTER B WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0062,
+ uccode=0x0181,
+ unicodeslot=0x0253,
+ },
+ {
+ adobename="oopen",
+ category="ll",
+ description="LATIN SMALL LETTER OPEN O",
+ direction="l",
+ linebreak="al",
+ uccode=0x0186,
+ unicodeslot=0x0254,
+ },
+ {
+ adobename="ccurl",
+ category="ll",
+ contextname="ccurl",
+ description="LATIN SMALL LETTER C WITH CURL",
+ direction="l",
+ linebreak="al",
+ shcode=0x0063,
+ unicodeslot=0x0255,
+ },
+ {
+ adobename="dtail",
+ category="ll",
+ contextname="dtail",
+ description="LATIN SMALL LETTER D WITH TAIL",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ uccode=0x0189,
+ unicodeslot=0x0256,
+ },
+ {
+ adobename="dhook",
+ category="ll",
+ contextname="dhook",
+ description="LATIN SMALL LETTER D WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ uccode=0x018A,
+ unicodeslot=0x0257,
+ },
+ {
+ adobename="ereversed",
+ category="ll",
+ description="LATIN SMALL LETTER REVERSED E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0258,
+ },
+ {
+ adobename="schwa",
+ category="ll",
+ contextname="schwa",
+ description="LATIN SMALL LETTER SCHWA",
+ direction="l",
+ linebreak="al",
+ uccode=0x018F,
+ unicodeslot=0x0259,
+ },
+ {
+ adobename="schwahook",
+ category="ll",
+ contextname="schwahook",
+ description="LATIN SMALL LETTER SCHWA WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0259,
+ unicodeslot=0x025A,
+ },
+ {
+ adobename="eopen",
+ category="ll",
+ description="LATIN SMALL LETTER OPEN E",
+ direction="l",
+ linebreak="al",
+ uccode=0x0190,
+ unicodeslot=0x025B,
+ },
+ {
+ adobename="eopenreversed",
+ category="ll",
+ description="LATIN SMALL LETTER REVERSED OPEN E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x025C,
+ },
+ {
+ adobename="eopenreversedhook",
+ category="ll",
+ description="LATIN SMALL LETTER REVERSED OPEN E WITH HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x025D,
+ },
+ {
+ adobename="eopenreversedclosed",
+ category="ll",
+ description="LATIN SMALL LETTER CLOSED REVERSED OPEN E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x025E,
+ },
+ {
+ adobename="jdotlessstroke",
+ category="ll",
+ contextname="dotlessjstroke",
+ description="LATIN SMALL LETTER DOTLESS J WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x025F,
+ },
+ {
+ adobename="ghook",
+ category="ll",
+ description="LATIN SMALL LETTER G WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0067,
+ uccode=0x0193,
+ unicodeslot=0x0260,
+ },
+ {
+ adobename="gscript",
+ category="ll",
+ cjkwd="a",
+ description="LATIN SMALL LETTER SCRIPT G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0261,
+ },
+ {
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0262,
+ },
+ {
+ adobename="gammalatinsmall",
+ category="ll",
+ description="LATIN SMALL LETTER GAMMA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0194,
+ unicodeslot=0x0263,
+ },
+ {
+ adobename="ramshorn",
+ category="ll",
+ description="LATIN SMALL LETTER RAMS HORN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0264,
+ },
+ {
+ adobename="hturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0265,
+ },
+ {
+ adobename="hhook",
+ category="ll",
+ description="LATIN SMALL LETTER H WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0068,
+ unicodeslot=0x0266,
+ },
+ {
+ adobename="henghook",
+ category="ll",
+ description="LATIN SMALL LETTER HENG WITH HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0267,
+ },
+ {
+ adobename="istroke",
+ category="ll",
+ description="LATIN SMALL LETTER I WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ uccode=0x0197,
+ unicodeslot=0x0268,
+ },
+ {
+ adobename="iotalatin",
+ category="ll",
+ description="LATIN SMALL LETTER IOTA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0196,
+ unicodeslot=0x0269,
+ },
+ {
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x026A,
+ },
+ {
+ adobename="lmiddletilde",
+ category="ll",
+ description="LATIN SMALL LETTER L WITH MIDDLE TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ uccode=0x2C62,
+ unicodeslot=0x026B,
+ },
+ {
+ adobename="lbelt",
+ category="ll",
+ description="LATIN SMALL LETTER L WITH BELT",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ unicodeslot=0x026C,
+ },
+ {
+ adobename="lhookretroflex",
+ category="ll",
+ description="LATIN SMALL LETTER L WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ unicodeslot=0x026D,
+ },
+ {
+ adobename="lezh",
+ category="ll",
+ description="LATIN SMALL LETTER LEZH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x026E,
+ },
+ {
+ adobename="mturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED M",
+ direction="l",
+ linebreak="al",
+ uccode=0x019C,
+ unicodeslot=0x026F,
+ },
+ {
+ adobename="mlonglegturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED M WITH LONG LEG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0270,
+ },
+ {
+ adobename="mhook",
+ category="ll",
+ description="LATIN SMALL LETTER M WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x006D,
+ unicodeslot=0x0271,
+ },
+ {
+ adobename="nhookleft",
+ category="ll",
+ description="LATIN SMALL LETTER N WITH LEFT HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ uccode=0x019D,
+ unicodeslot=0x0272,
+ },
+ {
+ adobename="nhookretroflex",
+ category="ll",
+ description="LATIN SMALL LETTER N WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ unicodeslot=0x0273,
+ },
+ {
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL N",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0274,
+ },
+ {
+ adobename="obarred",
+ category="ll",
+ description="LATIN SMALL LETTER BARRED O",
+ direction="l",
+ linebreak="al",
+ uccode=0x019F,
+ unicodeslot=0x0275,
+ },
+ {
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL OE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0276,
+ },
+ {
+ adobename="omegalatinclosed",
+ category="ll",
+ description="LATIN SMALL LETTER CLOSED OMEGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0277,
+ },
+ {
+ adobename="philatin",
+ category="ll",
+ description="LATIN SMALL LETTER PHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0278,
+ },
+ {
+ adobename="rturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0279,
+ },
+ {
+ adobename="rlonglegturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED R WITH LONG LEG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x027A,
+ },
+ {
+ adobename="rhookturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED R WITH HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x027B,
+ },
+ {
+ adobename="rlongleg",
+ category="ll",
+ description="LATIN SMALL LETTER R WITH LONG LEG",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ unicodeslot=0x027C,
+ },
+ {
+ adobename="rhook",
+ category="ll",
+ description="LATIN SMALL LETTER R WITH TAIL",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ uccode=0x2C64,
+ unicodeslot=0x027D,
+ },
+ {
+ adobename="rfishhook",
+ category="ll",
+ description="LATIN SMALL LETTER R WITH FISHHOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ unicodeslot=0x027E,
+ },
+ {
+ adobename="rfishhookreversed",
+ category="ll",
+ description="LATIN SMALL LETTER REVERSED R WITH FISHHOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x027F,
+ },
+ {
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL R",
+ direction="l",
+ linebreak="al",
+ uccode=0x01A6,
+ unicodeslot=0x0280,
+ },
+ {
+ adobename="Rsmallinverted",
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL INVERTED R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0281,
+ },
+ {
+ adobename="shook",
+ category="ll",
+ description="LATIN SMALL LETTER S WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ unicodeslot=0x0282,
+ },
+ {
+ adobename="esh",
+ category="ll",
+ description="LATIN SMALL LETTER ESH",
+ direction="l",
+ linebreak="al",
+ uccode=0x01A9,
+ unicodeslot=0x0283,
+ },
+ {
+ adobename="dotlessjstrokehook",
+ category="ll",
+ description="LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0284,
+ },
+ {
+ adobename="eshsquatreversed",
+ category="ll",
+ description="LATIN SMALL LETTER SQUAT REVERSED ESH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0285,
+ },
+ {
+ adobename="eshcurl",
+ category="ll",
+ description="LATIN SMALL LETTER ESH WITH CURL",
+ direction="l",
+ linebreak="al",
+ shcode=0x0283,
+ unicodeslot=0x0286,
+ },
+ {
+ adobename="tturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED T",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0287,
+ },
+ {
+ adobename="tretroflexhook",
+ category="ll",
+ description="LATIN SMALL LETTER T WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ uccode=0x01AE,
+ unicodeslot=0x0288,
+ },
+ {
+ adobename="ubar",
+ category="ll",
+ description="LATIN SMALL LETTER U BAR",
+ direction="l",
+ linebreak="al",
+ uccode=0x0244,
+ unicodeslot=0x0289,
+ },
+ {
+ adobename="upsilonlatin",
+ category="ll",
+ description="LATIN SMALL LETTER UPSILON",
+ direction="l",
+ linebreak="al",
+ uccode=0x01B1,
+ unicodeslot=0x028A,
+ },
+ {
+ adobename="vhook",
+ category="ll",
+ description="LATIN SMALL LETTER V WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0076,
+ uccode=0x01B2,
+ unicodeslot=0x028B,
+ },
+ {
+ adobename="vturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED V",
+ direction="l",
+ linebreak="al",
+ uccode=0x0245,
+ unicodeslot=0x028C,
+ },
+ {
+ adobename="wturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED W",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x028D,
+ },
+ {
+ adobename="yturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED Y",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x028E,
+ },
+ {
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x028F,
+ },
+ {
+ adobename="zretroflexhook",
+ category="ll",
+ description="LATIN SMALL LETTER Z WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ unicodeslot=0x0290,
+ },
+ {
+ adobename="zcurl",
+ category="ll",
+ description="LATIN SMALL LETTER Z WITH CURL",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ unicodeslot=0x0291,
+ },
+ {
+ adobename="ezh",
+ category="ll",
+ description="LATIN SMALL LETTER EZH",
+ direction="l",
+ linebreak="al",
+ uccode=0x01B7,
+ unicodeslot=0x0292,
+ },
+ {
+ adobename="ezhcurl",
+ category="ll",
+ description="LATIN SMALL LETTER EZH WITH CURL",
+ direction="l",
+ linebreak="al",
+ shcode=0x0292,
+ unicodeslot=0x0293,
+ },
+ {
+ adobename="glottalstop",
+ category="lo",
+ description="LATIN LETTER GLOTTAL STOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0294,
+ },
+ {
+ adobename="glottalstopreversed",
+ category="ll",
+ description="LATIN LETTER PHARYNGEAL VOICED FRICATIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0295,
+ },
+ {
+ adobename="glottalstopinverted",
+ category="ll",
+ description="LATIN LETTER INVERTED GLOTTAL STOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0296,
+ },
+ {
+ adobename="cstretched",
+ category="ll",
+ description="LATIN LETTER STRETCHED C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0297,
+ },
+ {
+ adobename="bilabialclick",
+ category="ll",
+ description="LATIN LETTER BILABIAL CLICK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0298,
+ },
+ {
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0299,
+ },
+ {
+ adobename="eopenclosed",
+ category="ll",
+ description="LATIN SMALL LETTER CLOSED OPEN E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x029A,
+ },
+ {
+ adobename="Gsmallhook",
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL G WITH HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x029B,
+ },
+ {
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x029C,
+ },
+ {
+ adobename="jcrossedtail",
+ category="ll",
+ description="LATIN SMALL LETTER J WITH CROSSED-TAIL",
+ direction="l",
+ linebreak="al",
+ shcode=0x006A,
+ unicodeslot=0x029D,
+ },
+ {
+ adobename="kturned",
+ category="ll",
+ description="LATIN SMALL LETTER TURNED K",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x029E,
+ },
+ {
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x029F,
+ },
+ {
+ adobename="qhook",
+ category="ll",
+ description="LATIN SMALL LETTER Q WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0071,
+ unicodeslot=0x02A0,
+ },
+ {
+ adobename="glottalstopstroke",
+ category="ll",
+ description="LATIN LETTER GLOTTAL STOP WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02A1,
+ },
+ {
+ adobename="glottalstopstrokereversed",
+ category="ll",
+ description="LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02A2,
+ },
+ {
+ adobename="dzaltone",
+ category="ll",
+ description="LATIN SMALL LETTER DZ DIGRAPH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02A3,
+ },
+ {
+ adobename="dezh",
+ category="ll",
+ description="LATIN SMALL LETTER DEZH DIGRAPH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02A4,
+ },
+ {
+ adobename="dzcurl",
+ category="ll",
+ description="LATIN SMALL LETTER DZ DIGRAPH WITH CURL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02A5,
+ },
+ {
+ adobename="ts",
+ category="ll",
+ description="LATIN SMALL LETTER TS DIGRAPH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02A6,
+ },
+ {
+ adobename="tesh",
+ category="ll",
+ description="LATIN SMALL LETTER TESH DIGRAPH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02A7,
+ },
+ {
+ adobename="tccurl",
+ category="ll",
+ description="LATIN SMALL LETTER TC DIGRAPH WITH CURL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02A8,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER FENG DIGRAPH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02A9,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER LS DIGRAPH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02AA,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER LZ DIGRAPH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02AB,
+ },
+ {
+ category="ll",
+ description="LATIN LETTER BILABIAL PERCUSSIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02AC,
+ },
+ {
+ category="ll",
+ description="LATIN LETTER BIDENTAL PERCUSSIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02AD,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER TURNED H WITH FISHHOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02AE,
+ },
+ {
+ category="ll",
+ description="LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02AF,
+ },
+ {
+ adobename="hsuperior",
+ category="lm",
+ description="MODIFIER LETTER SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0068 },
+ unicodeslot=0x02B0,
+ },
+ {
+ adobename="hhooksuperior",
+ category="lm",
+ description="MODIFIER LETTER SMALL H WITH HOOK",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0266 },
+ unicodeslot=0x02B1,
+ },
+ {
+ adobename="jsuperior",
+ category="lm",
+ description="MODIFIER LETTER SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x006A },
+ unicodeslot=0x02B2,
+ },
+ {
+ category="lm",
+ description="MODIFIER LETTER SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0072 },
+ unicodeslot=0x02B3,
+ },
+ {
+ adobename="rturnedsuperior",
+ category="lm",
+ description="MODIFIER LETTER SMALL TURNED R",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0279 },
+ unicodeslot=0x02B4,
+ },
+ {
+ adobename="rhookturnedsuperior",
+ category="lm",
+ description="MODIFIER LETTER SMALL TURNED R WITH HOOK",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x027B },
+ unicodeslot=0x02B5,
+ },
+ {
+ adobename="Rsmallinvertedsuperior",
+ category="lm",
+ description="MODIFIER LETTER SMALL CAPITAL INVERTED R",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0281 },
+ unicodeslot=0x02B6,
+ },
+ {
+ adobename="wsuperior",
+ category="lm",
+ description="MODIFIER LETTER SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0077 },
+ unicodeslot=0x02B7,
+ },
+ {
+ adobename="ysuperior",
+ category="lm",
+ description="MODIFIER LETTER SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0079 },
+ unicodeslot=0x02B8,
+ },
+ {
+ adobename="primemod",
+ category="lm",
+ description="MODIFIER LETTER PRIME",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02B9,
+ },
+ {
+ adobename="dblprimemod",
+ category="lm",
+ description="MODIFIER LETTER DOUBLE PRIME",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02BA,
+ },
+ {
+ adobename="commaturnedmod",
+ category="lm",
+ description="MODIFIER LETTER TURNED COMMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02BB,
+ },
+ {
+ adobename="apostrophemod",
+ category="lm",
+ description="MODIFIER LETTER APOSTROPHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02BC,
+ },
+ {
+ adobename="commareversedmod",
+ category="lm",
+ description="MODIFIER LETTER REVERSED COMMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02BD,
+ },
+ {
+ adobename="ringhalfright",
+ category="lm",
+ description="MODIFIER LETTER RIGHT HALF RING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02BE,
+ },
+ {
+ adobename="ringhalfleft",
+ category="lm",
+ description="MODIFIER LETTER LEFT HALF RING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02BF,
+ },
+ {
+ adobename="glottalstopmod",
+ category="lm",
+ description="MODIFIER LETTER GLOTTAL STOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02C0,
+ },
+ {
+ adobename="glottalstopreversedmod",
+ category="lm",
+ description="MODIFIER LETTER REVERSED GLOTTAL STOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02C1,
+ },
+ {
+ adobename="arrowheadleftmod",
+ category="sk",
+ description="MODIFIER LETTER LEFT ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02C2,
+ },
+ {
+ adobename="arrowheadrightmod",
+ category="sk",
+ description="MODIFIER LETTER RIGHT ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02C3,
+ },
+ {
+ adobename="arrowheadupmod",
+ category="sk",
+ cjkwd="a",
+ description="MODIFIER LETTER UP ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02C4,
+ },
+ {
+ adobename="arrowheaddownmod",
+ category="sk",
+ description="MODIFIER LETTER DOWN ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02C5,
+ },
+ {
+ adobename="circumflex",
+ category="lm",
+ comment="check special",
+ contextname="textcircumflex",
+ description="MODIFIER LETTER CIRCUMFLEX ACCENT",
+ direction="on",
+ linebreak="al",
+ mathclass="topaccent",
+ mathname="hat",
+ specials={ "compat", 0x0020, 0x0302 },
+ unicodeslot=0x02C6,
+ },
+ {
+ adobename="caron",
+ category="lm",
+ cjkwd="a",
+ comment="check special",
+ contextname="textcaron",
+ description="CARON",
+ direction="on",
+ linebreak="ai",
+ mathclass="topaccent",
+ mathname="check",
+ specials={ "compat", 0x0020, 0x030C },
+ unicodeslot=0x02C7,
+ },
+ {
+ adobename="verticallinemod",
+ category="lm",
+ description="MODIFIER LETTER VERTICAL LINE",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x02C8,
+ },
+ {
+ adobename="firsttonechinese",
+ category="lm",
+ cjkwd="a",
+ description="MODIFIER LETTER MACRON",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x02C9,
+ },
+ {
+ adobename="secondtonechinese",
+ category="lm",
+ cjkwd="a",
+ description="MODIFIER LETTER ACUTE ACCENT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x02CA,
+ },
+ {
+ adobename="fourthtonechinese",
+ category="lm",
+ cjkwd="a",
+ description="MODIFIER LETTER GRAVE ACCENT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x02CB,
+ },
+ {
+ adobename="verticallinelowmod",
+ category="lm",
+ description="MODIFIER LETTER LOW VERTICAL LINE",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x02CC,
+ },
+ {
+ adobename="macronlowmod",
+ category="lm",
+ cjkwd="a",
+ description="MODIFIER LETTER LOW MACRON",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x02CD,
+ },
+ {
+ adobename="gravelowmod",
+ category="lm",
+ description="MODIFIER LETTER LOW GRAVE ACCENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02CE,
+ },
+ {
+ adobename="acutelowmod",
+ category="lm",
+ description="MODIFIER LETTER LOW ACUTE ACCENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02CF,
+ },
+ {
+ adobename="colontriangularmod",
+ category="lm",
+ cjkwd="a",
+ description="MODIFIER LETTER TRIANGULAR COLON",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x02D0,
+ },
+ {
+ adobename="colontriangularhalfmod",
+ category="lm",
+ description="MODIFIER LETTER HALF TRIANGULAR COLON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02D1,
+ },
+ {
+ adobename="ringhalfrightcentered",
+ category="sk",
+ description="MODIFIER LETTER CENTRED RIGHT HALF RING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02D2,
+ },
+ {
+ adobename="ringhalfleftcentered",
+ category="sk",
+ description="MODIFIER LETTER CENTRED LEFT HALF RING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02D3,
+ },
+ {
+ adobename="uptackmod",
+ category="sk",
+ description="MODIFIER LETTER UP TACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02D4,
+ },
+ {
+ adobename="downtackmod",
+ category="sk",
+ description="MODIFIER LETTER DOWN TACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02D5,
+ },
+ {
+ adobename="plusmod",
+ category="sk",
+ description="MODIFIER LETTER PLUS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02D6,
+ },
+ {
+ adobename="minusmod",
+ category="sk",
+ description="MODIFIER LETTER MINUS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02D7,
+ },
+ {
+ adobename="breve",
+ category="sk",
+ cjkwd="a",
+ contextname="textbreve",
+ description="BREVE",
+ direction="on",
+ linebreak="ai",
+ mathclass="topaccent",
+ mathname="breve",
+ specials={ "compat", 0x0020, 0x0306 },
+ unicodeslot=0x02D8,
+ },
+ {
+ adobename="dotaccent",
+ category="sk",
+ cjkwd="a",
+ contextname="textdotaccent",
+ description="DOT ABOVE",
+ direction="on",
+ linebreak="ai",
+ mathclass="topaccent",
+ mathname="dot",
+ specials={ "compat", 0x0020, 0x0307 },
+ unicodeslot=0x02D9,
+ },
+ {
+ adobename="ring",
+ category="sk",
+ cjkwd="a",
+ contextname="textring",
+ description="RING ABOVE",
+ direction="on",
+ linebreak="ai",
+ mathclass="topaccent",
+ mathname="mathring",
+ specials={ "compat", 0x0020, 0x030A },
+ unicodeslot=0x02DA,
+ },
+ {
+ adobename="ogonek",
+ category="sk",
+ cjkwd="a",
+ contextname="textogonek",
+ description="OGONEK",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0020, 0x0328 },
+ unicodeslot=0x02DB,
+ },
+ {
+ adobename="tilde",
+ category="sk",
+ contextname="texttilde",
+ description="SMALL TILDE",
+ direction="on",
+ linebreak="al",
+ mathclass="topaccent",
+ mathname="tilde",
+ specials={ "compat", 0x0020, 0x0303 },
+ unicodeslot=0x02DC,
+ },
+ {
+ adobename="hungarumlaut",
+ category="sk",
+ cjkwd="a",
+ contextname="texthungarumlaut",
+ description="DOUBLE ACUTE ACCENT",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0020, 0x030B },
+ unicodeslot=0x02DD,
+ },
+ {
+ adobename="rhotichookmod",
+ category="sk",
+ description="MODIFIER LETTER RHOTIC HOOK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02DE,
+ },
+ {
+ category="sk",
+ cjkwd="a",
+ description="MODIFIER LETTER CROSS ACCENT",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x02DF,
+ },
+ {
+ adobename="gammasuperior",
+ category="lm",
+ description="MODIFIER LETTER SMALL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0263 },
+ unicodeslot=0x02E0,
+ },
+ {
+ category="lm",
+ description="MODIFIER LETTER SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x006C },
+ unicodeslot=0x02E1,
+ },
+ {
+ category="lm",
+ description="MODIFIER LETTER SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0073 },
+ unicodeslot=0x02E2,
+ },
+ {
+ adobename="xsuperior",
+ category="lm",
+ description="MODIFIER LETTER SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0078 },
+ unicodeslot=0x02E3,
+ },
+ {
+ adobename="glottalstopreversedsuperior",
+ category="lm",
+ description="MODIFIER LETTER SMALL REVERSED GLOTTAL STOP",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0295 },
+ unicodeslot=0x02E4,
+ },
+ {
+ adobename="tonebarextrahighmod",
+ category="sk",
+ description="MODIFIER LETTER EXTRA-HIGH TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02E5,
+ },
+ {
+ adobename="tonebarhighmod",
+ category="sk",
+ description="MODIFIER LETTER HIGH TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02E6,
+ },
+ {
+ adobename="tonebarmidmod",
+ category="sk",
+ description="MODIFIER LETTER MID TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02E7,
+ },
+ {
+ adobename="tonebarlowmod",
+ category="sk",
+ description="MODIFIER LETTER LOW TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02E8,
+ },
+ {
+ adobename="tonebarextralowmod",
+ category="sk",
+ description="MODIFIER LETTER EXTRA-LOW TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02E9,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER YIN DEPARTING TONE MARK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02EA,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER YANG DEPARTING TONE MARK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02EB,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER VOICING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02EC,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER UNASPIRATED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02ED,
+ },
+ {
+ category="lm",
+ description="MODIFIER LETTER DOUBLE APOSTROPHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x02EE,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER LOW DOWN ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02EF,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER LOW UP ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02F0,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER LOW LEFT ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02F1,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER LOW RIGHT ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02F2,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER LOW RING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02F3,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER MIDDLE GRAVE ACCENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02F4,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02F5,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02F6,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER LOW TILDE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02F7,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER RAISED COLON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02F8,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER BEGIN HIGH TONE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02F9,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER END HIGH TONE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02FA,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER BEGIN LOW TONE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02FB,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER END LOW TONE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02FC,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER SHELF",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02FD,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER OPEN SHELF",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02FE,
+ },
+ {
+ category="sk",
+ description="MODIFIER LETTER LOW LEFT ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x02FF,
+ },
+ {
+ adobename="gravecomb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING GRAVE ACCENT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0300,
+ },
+ {
+ adobename="acutecomb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING ACUTE ACCENT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0301,
+ },
+ {
+ adobename="circumflexcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING CIRCUMFLEX ACCENT",
+ direction="nsm",
+ linebreak="cm",
+ mathclass="topaccent",
+ mathname="widehat",
+ mathstretch="h",
+ unicodeslot=0x0302,
+ },
+ {
+ adobename="tildecomb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING TILDE",
+ direction="nsm",
+ linebreak="cm",
+ mathclass="topaccent",
+ mathname="widetilde",
+ mathstretch="h",
+ unicodeslot=0x0303,
+ },
+ {
+ adobename="macroncmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING MACRON",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0304,
+ },
+ {
+ adobename="overlinecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING OVERLINE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0305,
+ },
+ {
+ adobename="brevecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING BREVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0306,
+ },
+ {
+ adobename="dotaccentcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOT ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0307,
+ },
+ {
+ adobename="dieresiscmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DIAERESIS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0308,
+ },
+ {
+ adobename="hookcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING HOOK ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0309,
+ },
+ {
+ adobename="ringcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING RING ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x030A,
+ },
+ {
+ adobename="hungarumlautcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE ACUTE ACCENT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x030B,
+ },
+ {
+ adobename="caroncmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING CARON",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x030C,
+ },
+ {
+ adobename="verticallineabovecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING VERTICAL LINE ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x030D,
+ },
+ {
+ adobename="dblverticallineabovecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE VERTICAL LINE ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x030E,
+ },
+ {
+ adobename="dblgravecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE GRAVE ACCENT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x030F,
+ },
+ {
+ adobename="candrabinducmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING CANDRABINDU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0310,
+ },
+ {
+ adobename="breveinvertedcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING INVERTED BREVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0311,
+ },
+ {
+ adobename="commaturnedabovecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING TURNED COMMA ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0312,
+ },
+ {
+ adobename="commaabovecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING COMMA ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0313,
+ },
+ {
+ adobename="commareversedabovecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING REVERSED COMMA ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0314,
+ },
+ {
+ adobename="commaaboverightcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING COMMA ABOVE RIGHT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0315,
+ },
+ {
+ adobename="gravebelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING GRAVE ACCENT BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0316,
+ },
+ {
+ adobename="acutebelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING ACUTE ACCENT BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0317,
+ },
+ {
+ adobename="lefttackbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LEFT TACK BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0318,
+ },
+ {
+ adobename="righttackbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING RIGHT TACK BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0319,
+ },
+ {
+ adobename="leftangleabovecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LEFT ANGLE ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x031A,
+ },
+ {
+ adobename="horncmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING HORN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x031B,
+ },
+ {
+ adobename="ringhalfleftbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LEFT HALF RING BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x031C,
+ },
+ {
+ adobename="uptackbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING UP TACK BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x031D,
+ },
+ {
+ adobename="downtackbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOWN TACK BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x031E,
+ },
+ {
+ adobename="plusbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING PLUS SIGN BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x031F,
+ },
+ {
+ adobename="minusbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING MINUS SIGN BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0320,
+ },
+ {
+ adobename="hookpalatalizedbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING PALATALIZED HOOK BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0321,
+ },
+ {
+ adobename="hookretroflexbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING RETROFLEX HOOK BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0322,
+ },
+ {
+ adobename="dotbelowcomb",
+ category="mn",
+ cjkwd="a",
+ contextname="textbottomdot",
+ description="COMBINING DOT BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0323,
+ },
+ {
+ adobename="dieresisbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DIAERESIS BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0324,
+ },
+ {
+ adobename="ringbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING RING BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0325,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ contextname="textbottomcomma",
+ description="COMBINING COMMA BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0326,
+ },
+ {
+ adobename="cedillacmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING CEDILLA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0327,
+ },
+ {
+ adobename="ogonekcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING OGONEK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0328,
+ },
+ {
+ adobename="verticallinebelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING VERTICAL LINE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0329,
+ },
+ {
+ adobename="bridgebelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING BRIDGE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x032A,
+ },
+ {
+ adobename="dblarchinvertedbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING INVERTED DOUBLE ARCH BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x032B,
+ },
+ {
+ adobename="caronbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING CARON BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x032C,
+ },
+ {
+ adobename="circumflexbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING CIRCUMFLEX ACCENT BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x032D,
+ },
+ {
+ adobename="brevebelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING BREVE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x032E,
+ },
+ {
+ adobename="breveinvertedbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING INVERTED BREVE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x032F,
+ },
+ {
+ adobename="tildebelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING TILDE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0330,
+ },
+ {
+ adobename="macronbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING MACRON BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0331,
+ },
+ {
+ adobename="lowlinecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LOW LINE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0332,
+ },
+ {
+ adobename="dbllowlinecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE LOW LINE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0333,
+ },
+ {
+ adobename="tildeoverlaycmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING TILDE OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0334,
+ },
+ {
+ adobename="strokeshortoverlaycmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING SHORT STROKE OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0335,
+ },
+ {
+ adobename="strokelongoverlaycmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LONG STROKE OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0336,
+ },
+ {
+ adobename="solidusshortoverlaycmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING SHORT SOLIDUS OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0337,
+ },
+ {
+ adobename="soliduslongoverlaycmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LONG SOLIDUS OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ mathclass="relation",
+ mathname="not",
+ unicodeslot=0x0338,
+ },
+ {
+ adobename="ringhalfrightbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING RIGHT HALF RING BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0339,
+ },
+ {
+ adobename="bridgeinvertedbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING INVERTED BRIDGE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x033A,
+ },
+ {
+ adobename="squarebelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING SQUARE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x033B,
+ },
+ {
+ adobename="seagullbelowcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING SEAGULL BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x033C,
+ },
+ {
+ adobename="xabovecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING X ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x033D,
+ },
+ {
+ adobename="tildeverticalcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING VERTICAL TILDE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x033E,
+ },
+ {
+ adobename="dbloverlinecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE OVERLINE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x033F,
+ },
+ {
+ adobename="gravetonecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING GRAVE TONE MARK",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0300 },
+ unicodeslot=0x0340,
+ },
+ {
+ adobename="acutetonecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING ACUTE TONE MARK",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0301 },
+ unicodeslot=0x0341,
+ },
+ {
+ adobename="perispomenigreekcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING GREEK PERISPOMENI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0342,
+ },
+ {
+ adobename="koroniscmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING GREEK KORONIS",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0313 },
+ unicodeslot=0x0343,
+ },
+ {
+ adobename="dialytikatonoscmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING GREEK DIALYTIKA TONOS",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0308, 0x0301 },
+ unicodeslot=0x0344,
+ },
+ {
+ adobename="ypogegrammenigreekcmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING GREEK YPOGEGRAMMENI",
+ direction="nsm",
+ linebreak="cm",
+ uccode=0x0399,
+ unicodeslot=0x0345,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING BRIDGE ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0346,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING EQUALS SIGN BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0347,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE VERTICAL LINE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0348,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LEFT ANGLE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0349,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING NOT TILDE ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x034A,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING HOMOTHETIC ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x034B,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING ALMOST EQUAL TO ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x034C,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LEFT RIGHT ARROW BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x034D,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING UPWARDS ARROW BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x034E,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING GRAPHEME JOINER",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x034F,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING RIGHT ARROWHEAD ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0350,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LEFT HALF RING ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0351,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING FERMATA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0352,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING X BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0353,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LEFT ARROWHEAD BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0354,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING RIGHT ARROWHEAD BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0355,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0356,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING RIGHT HALF RING ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0357,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOT ABOVE RIGHT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0358,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING ASTERISK BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0359,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE RING BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x035A,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING ZIGZAG ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x035B,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE BREVE BELOW",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x035C,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE BREVE",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x035D,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE MACRON",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x035E,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE MACRON BELOW",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x035F,
+ },
+ {
+ adobename="tildedoublecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE TILDE",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x0360,
+ },
+ {
+ adobename="breveinverteddoublecmb",
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE INVERTED BREVE",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x0361,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING DOUBLE RIGHTWARDS ARROW BELOW",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x0362,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0363,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0364,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0365,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0366,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0367,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER C",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0368,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER D",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0369,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER H",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x036A,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER M",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x036B,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER R",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x036C,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER T",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x036D,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER V",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x036E,
+ },
+ {
+ category="mn",
+ cjkwd="a",
+ description="COMBINING LATIN SMALL LETTER X",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x036F,
+ },
+ {
+ category="lu",
+ description="GREEK CAPITAL LETTER HETA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0370,
+ },
+ {
+ category="ll",
+ description="GREEK SMALL LETTER HETA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0371,
+ },
+ {
+ category="lu",
+ description="GREEK CAPITAL LETTER ARCHAIC SAMPI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0372,
+ },
+ {
+ category="ll",
+ description="GREEK SMALL LETTER ARCHAIC SAMPI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0373,
+ },
+ {
+ adobename="numeralsigngreek",
+ category="sk",
+ description="GREEK NUMERAL SIGN",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x02B9 },
+ unicodeslot=0x0374,
+ },
+ {
+ adobename="numeralsignlowergreek",
+ category="sk",
+ description="GREEK LOWER NUMERAL SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0375,
+ },
+ {
+ category="lu",
+ description="GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0376,
+ },
+ {
+ category="ll",
+ description="GREEK SMALL LETTER PAMPHYLIAN DIGAMMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0377,
+ },
+ [0x037A]={
+ adobename="ypogegrammeni",
+ category="lm",
+ description="GREEK YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0020, 0x0345 },
+ unicodeslot=0x037A,
+ },
+ [0x037B]={
+ category="ll",
+ description="GREEK SMALL REVERSED LUNATE SIGMA SYMBOL",
+ direction="l",
+ linebreak="al",
+ uccode=0x03FD,
+ unicodeslot=0x037B,
+ },
+ [0x037C]={
+ category="ll",
+ description="GREEK SMALL DOTTED LUNATE SIGMA SYMBOL",
+ direction="l",
+ linebreak="al",
+ uccode=0x03FE,
+ unicodeslot=0x037C,
+ },
+ [0x037D]={
+ category="ll",
+ description="GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL",
+ direction="l",
+ linebreak="al",
+ uccode=0x03FF,
+ unicodeslot=0x037D,
+ },
+ [0x037E]={
+ adobename="questiongreek",
+ category="po",
+ description="GREEK QUESTION MARK",
+ direction="on",
+ linebreak="is",
+ specials={ "char", 0x003B },
+ unicodeslot=0x037E,
+ },
+ [0x0384]={
+ adobename="tonos",
+ category="sk",
+ contextname="greektonos",
+ description="GREEK TONOS",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x0020, 0x0301 },
+ unicodeslot=0x0384,
+ },
+ [0x0385]={
+ adobename="dieresistonos",
+ category="sk",
+ contextname="greekdialytikatonos",
+ description="GREEK DIALYTIKA TONOS",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x00A8, 0x0301 },
+ unicodeslot=0x0385,
+ },
+ [0x0386]={
+ adobename="Alphatonos",
+ category="lu",
+ contextname="greekAlphatonos",
+ description="GREEK CAPITAL LETTER ALPHA WITH TONOS",
+ direction="l",
+ lccode=0x03AC,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x0391, 0x0301 },
+ unicodeslot=0x0386,
+ },
+ [0x0387]={
+ adobename="anoteleia",
+ category="po",
+ description="GREEK ANO TELEIA",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x00B7 },
+ unicodeslot=0x0387,
+ },
+ [0x0388]={
+ adobename="Epsilontonos",
+ category="lu",
+ contextname="greekEpsilontonos",
+ description="GREEK CAPITAL LETTER EPSILON WITH TONOS",
+ direction="l",
+ lccode=0x03AD,
+ linebreak="al",
+ shcode=0x0395,
+ specials={ "char", 0x0395, 0x0301 },
+ unicodeslot=0x0388,
+ },
+ [0x0389]={
+ adobename="Etatonos",
+ category="lu",
+ contextname="greekEtatonos",
+ description="GREEK CAPITAL LETTER ETA WITH TONOS",
+ direction="l",
+ lccode=0x03AE,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x0397, 0x0301 },
+ unicodeslot=0x0389,
+ },
+ [0x038A]={
+ adobename="Iotatonos",
+ category="lu",
+ contextname="greekIotatonos",
+ description="GREEK CAPITAL LETTER IOTA WITH TONOS",
+ direction="l",
+ lccode=0x03AF,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x0399, 0x0301 },
+ unicodeslot=0x038A,
+ },
+ [0x038C]={
+ adobename="Omicrontonos",
+ category="lu",
+ contextname="greekOmicrontonos",
+ description="GREEK CAPITAL LETTER OMICRON WITH TONOS",
+ direction="l",
+ lccode=0x03CC,
+ linebreak="al",
+ shcode=0x039F,
+ specials={ "char", 0x039F, 0x0301 },
+ unicodeslot=0x038C,
+ },
+ [0x038E]={
+ adobename="Upsilontonos",
+ category="lu",
+ contextname="greekUpsilontonos",
+ description="GREEK CAPITAL LETTER UPSILON WITH TONOS",
+ direction="l",
+ lccode=0x03CD,
+ linebreak="al",
+ shcode=0x03A5,
+ specials={ "char", 0x03A5, 0x0301 },
+ unicodeslot=0x038E,
+ },
+ [0x038F]={
+ adobename="Omegatonos",
+ category="lu",
+ contextname="greekOmegatonos",
+ description="GREEK CAPITAL LETTER OMEGA WITH TONOS",
+ direction="l",
+ lccode=0x03CE,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x03A9, 0x0301 },
+ unicodeslot=0x038F,
+ },
+ [0x0390]={
+ adobename="iotadieresistonos",
+ category="ll",
+ contextname="greekiotadialytikatonos",
+ description="GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x03CA, 0x0301 },
+ unicodeslot=0x0390,
+ },
+ [0x0391]={
+ adobename="Alpha",
+ category="lu",
+ cjkwd="a",
+ contextname="greekAlpha",
+ description="GREEK CAPITAL LETTER ALPHA",
+ direction="l",
+ lccode=0x03B1,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Alpha",
+ unicodeslot=0x0391,
+ },
+ [0x0392]={
+ adobename="Beta",
+ category="lu",
+ cjkwd="a",
+ contextname="greekBeta",
+ description="GREEK CAPITAL LETTER BETA",
+ direction="l",
+ lccode=0x03B2,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Beta",
+ unicodeslot=0x0392,
+ },
+ [0x0393]={
+ adobename="Gamma",
+ category="lu",
+ cjkwd="a",
+ contextname="greekGamma",
+ description="GREEK CAPITAL LETTER GAMMA",
+ direction="l",
+ lccode=0x03B3,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Gamma",
+ unicodeslot=0x0393,
+ },
+ [0x0394]={
+ adobename="Deltagreek",
+ category="lu",
+ cjkwd="a",
+ contextname="greekDelta",
+ description="GREEK CAPITAL LETTER DELTA",
+ direction="l",
+ lccode=0x03B4,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Delta",
+ unicodeslot=0x0394,
+ },
+ [0x0395]={
+ adobename="Epsilon",
+ category="lu",
+ cjkwd="a",
+ contextname="greekEpsilon",
+ description="GREEK CAPITAL LETTER EPSILON",
+ direction="l",
+ lccode=0x03B5,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Epsilon",
+ unicodeslot=0x0395,
+ },
+ [0x0396]={
+ adobename="Zeta",
+ category="lu",
+ cjkwd="a",
+ contextname="greekZeta",
+ description="GREEK CAPITAL LETTER ZETA",
+ direction="l",
+ lccode=0x03B6,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Zeta",
+ unicodeslot=0x0396,
+ },
+ [0x0397]={
+ adobename="Eta",
+ category="lu",
+ cjkwd="a",
+ contextname="greekEta",
+ description="GREEK CAPITAL LETTER ETA",
+ direction="l",
+ lccode=0x03B7,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Eta",
+ unicodeslot=0x0397,
+ },
+ [0x0398]={
+ adobename="Theta",
+ category="lu",
+ cjkwd="a",
+ contextname="greekTheta",
+ description="GREEK CAPITAL LETTER THETA",
+ direction="l",
+ lccode=0x03B8,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Theta",
+ unicodeslot=0x0398,
+ },
+ [0x0399]={
+ adobename="Iota",
+ category="lu",
+ cjkwd="a",
+ contextname="greekIota",
+ description="GREEK CAPITAL LETTER IOTA",
+ direction="l",
+ lccode=0x03B9,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Iota",
+ unicodeslot=0x0399,
+ },
+ [0x039A]={
+ adobename="Kappa",
+ category="lu",
+ cjkwd="a",
+ contextname="greekKappa",
+ description="GREEK CAPITAL LETTER KAPPA",
+ direction="l",
+ lccode=0x03BA,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Kappa",
+ unicodeslot=0x039A,
+ },
+ [0x039B]={
+ adobename="Lambda",
+ category="lu",
+ cjkwd="a",
+ contextname="greekLambda",
+ description="GREEK CAPITAL LETTER LAMDA",
+ direction="l",
+ lccode=0x03BB,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Lambda",
+ unicodeslot=0x039B,
+ },
+ [0x039C]={
+ adobename="Mu",
+ category="lu",
+ cjkwd="a",
+ contextname="greekMu",
+ description="GREEK CAPITAL LETTER MU",
+ direction="l",
+ lccode=0x03BC,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Mu",
+ unicodeslot=0x039C,
+ },
+ [0x039D]={
+ adobename="Nu",
+ category="lu",
+ cjkwd="a",
+ contextname="greekNu",
+ description="GREEK CAPITAL LETTER NU",
+ direction="l",
+ lccode=0x03BD,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Nu",
+ unicodeslot=0x039D,
+ },
+ [0x039E]={
+ adobename="Xi",
+ category="lu",
+ cjkwd="a",
+ contextname="greekXi",
+ description="GREEK CAPITAL LETTER XI",
+ direction="l",
+ lccode=0x03BE,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Xi",
+ unicodeslot=0x039E,
+ },
+ [0x039F]={
+ adobename="Omicron",
+ category="lu",
+ cjkwd="a",
+ contextname="greekOmicron",
+ description="GREEK CAPITAL LETTER OMICRON",
+ direction="l",
+ lccode=0x03BF,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Omicron",
+ unicodeslot=0x039F,
+ },
+ [0x03A0]={
+ adobename="Pi",
+ category="lu",
+ cjkwd="a",
+ contextname="greekPi",
+ description="GREEK CAPITAL LETTER PI",
+ direction="l",
+ lccode=0x03C0,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Pi",
+ unicodeslot=0x03A0,
+ },
+ [0x03A1]={
+ adobename="Rho",
+ category="lu",
+ cjkwd="a",
+ contextname="greekRho",
+ description="GREEK CAPITAL LETTER RHO",
+ direction="l",
+ lccode=0x03C1,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Rho",
+ unicodeslot=0x03A1,
+ },
+ [0x03A3]={
+ adobename="Sigma",
+ category="lu",
+ cjkwd="a",
+ contextname="greekSigma",
+ description="GREEK CAPITAL LETTER SIGMA",
+ direction="l",
+ lccode=0x03C3,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Sigma",
+ unicodeslot=0x03A3,
+ },
+ [0x03A4]={
+ adobename="Tau",
+ category="lu",
+ cjkwd="a",
+ contextname="greekTau",
+ description="GREEK CAPITAL LETTER TAU",
+ direction="l",
+ lccode=0x03C4,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Tau",
+ unicodeslot=0x03A4,
+ },
+ [0x03A5]={
+ adobename="Upsilon",
+ category="lu",
+ cjkwd="a",
+ contextname="greekUpsilon",
+ description="GREEK CAPITAL LETTER UPSILON",
+ direction="l",
+ lccode=0x03C5,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Upsilon",
+ unicodeslot=0x03A5,
+ },
+ [0x03A6]={
+ adobename="Phi",
+ category="lu",
+ cjkwd="a",
+ contextname="greekPhi",
+ description="GREEK CAPITAL LETTER PHI",
+ direction="l",
+ lccode=0x03C6,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Phi",
+ unicodeslot=0x03A6,
+ },
+ [0x03A7]={
+ adobename="Chi",
+ category="lu",
+ cjkwd="a",
+ contextname="greekChi",
+ description="GREEK CAPITAL LETTER CHI",
+ direction="l",
+ lccode=0x03C7,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Chi",
+ unicodeslot=0x03A7,
+ },
+ [0x03A8]={
+ adobename="Psi",
+ category="lu",
+ cjkwd="a",
+ contextname="greekPsi",
+ description="GREEK CAPITAL LETTER PSI",
+ direction="l",
+ lccode=0x03C8,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Psi",
+ unicodeslot=0x03A8,
+ },
+ [0x03A9]={
+ adobename="Omegagreek",
+ category="lu",
+ cjkwd="a",
+ contextname="greekOmega",
+ description="GREEK CAPITAL LETTER OMEGA",
+ direction="l",
+ lccode=0x03C9,
+ linebreak="al",
+ mathclass="variable",
+ mathname="Omega",
+ unicodeslot=0x03A9,
+ },
+ [0x03AA]={
+ adobename="Iotadieresis",
+ category="lu",
+ contextname="greekIotadialytika",
+ description="GREEK CAPITAL LETTER IOTA WITH DIALYTIKA",
+ direction="l",
+ lccode=0x03CA,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x0399, 0x0308 },
+ unicodeslot=0x03AA,
+ },
+ [0x03AB]={
+ adobename="Upsilondieresis",
+ category="lu",
+ contextname="greekUpsilondialytika",
+ description="GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA",
+ direction="l",
+ lccode=0x03CB,
+ linebreak="al",
+ shcode=0x03A5,
+ specials={ "char", 0x03A5, 0x0308 },
+ unicodeslot=0x03AB,
+ },
+ [0x03AC]={
+ adobename="alphatonos",
+ category="ll",
+ contextname="greekalphatonos",
+ description="GREEK SMALL LETTER ALPHA WITH TONOS",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x03B1, 0x0301 },
+ uccode=0x0386,
+ unicodeslot=0x03AC,
+ },
+ [0x03AD]={
+ adobename="epsilontonos",
+ category="ll",
+ contextname="greekepsilontonos",
+ description="GREEK SMALL LETTER EPSILON WITH TONOS",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B5,
+ specials={ "char", 0x03B5, 0x0301 },
+ uccode=0x0388,
+ unicodeslot=0x03AD,
+ },
+ [0x03AE]={
+ adobename="etatonos",
+ category="ll",
+ contextname="greeketatonos",
+ description="GREEK SMALL LETTER ETA WITH TONOS",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x03B7, 0x0301 },
+ uccode=0x0389,
+ unicodeslot=0x03AE,
+ },
+ [0x03AF]={
+ adobename="iotatonos",
+ category="ll",
+ contextname="greekiotatonos",
+ description="GREEK SMALL LETTER IOTA WITH TONOS",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x03B9, 0x0301 },
+ uccode=0x038A,
+ unicodeslot=0x03AF,
+ },
+ [0x03B0]={
+ adobename="upsilondieresistonos",
+ category="ll",
+ contextname="greekupsilondialytikatonos",
+ description="GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03CB, 0x0301 },
+ unicodeslot=0x03B0,
+ },
+ [0x03B1]={
+ adobename="alpha",
+ category="ll",
+ cjkwd="a",
+ contextname="greekalpha",
+ description="GREEK SMALL LETTER ALPHA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="alpha",
+ uccode=0x0391,
+ unicodeslot=0x03B1,
+ },
+ [0x03B2]={
+ adobename="beta",
+ category="ll",
+ cjkwd="a",
+ contextname="greekbeta",
+ description="GREEK SMALL LETTER BETA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="beta",
+ uccode=0x0392,
+ unicodeslot=0x03B2,
+ },
+ [0x03B3]={
+ adobename="gamma",
+ category="ll",
+ cjkwd="a",
+ contextname="greekgamma",
+ description="GREEK SMALL LETTER GAMMA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="gamma",
+ uccode=0x0393,
+ unicodeslot=0x03B3,
+ },
+ [0x03B4]={
+ adobename="delta",
+ category="ll",
+ cjkwd="a",
+ contextname="greekdelta",
+ description="GREEK SMALL LETTER DELTA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="delta",
+ uccode=0x0394,
+ unicodeslot=0x03B4,
+ },
+ [0x03B5]={
+ adobename="epsilon",
+ category="ll",
+ cjkwd="a",
+ contextname="greekepsilon",
+ description="GREEK SMALL LETTER EPSILON",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="varepsilon",
+ uccode=0x0395,
+ unicodeslot=0x03B5,
+ },
+ [0x03B6]={
+ adobename="zeta",
+ category="ll",
+ cjkwd="a",
+ contextname="greekzeta",
+ description="GREEK SMALL LETTER ZETA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="zeta",
+ uccode=0x0396,
+ unicodeslot=0x03B6,
+ },
+ [0x03B7]={
+ adobename="eta",
+ category="ll",
+ cjkwd="a",
+ contextname="greeketa",
+ description="GREEK SMALL LETTER ETA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="eta",
+ uccode=0x0397,
+ unicodeslot=0x03B7,
+ },
+ [0x03B8]={
+ adobename="theta",
+ category="ll",
+ cjkwd="a",
+ contextname="greektheta",
+ description="GREEK SMALL LETTER THETA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="theta",
+ uccode=0x0398,
+ unicodeslot=0x03B8,
+ },
+ [0x03B9]={
+ adobename="iota",
+ category="ll",
+ cjkwd="a",
+ contextname="greekiota",
+ description="GREEK SMALL LETTER IOTA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="iota",
+ uccode=0x0399,
+ unicodeslot=0x03B9,
+ },
+ [0x03BA]={
+ adobename="kappa",
+ category="ll",
+ cjkwd="a",
+ contextname="greekkappa",
+ description="GREEK SMALL LETTER KAPPA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="kappa",
+ uccode=0x039A,
+ unicodeslot=0x03BA,
+ },
+ [0x03BB]={
+ adobename="lambda",
+ category="ll",
+ cjkwd="a",
+ contextname="greeklambda",
+ description="GREEK SMALL LETTER LAMDA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="lambda",
+ uccode=0x039B,
+ unicodeslot=0x03BB,
+ },
+ [0x03BC]={
+ adobename="mugreek",
+ category="ll",
+ cjkwd="a",
+ contextname="greekmu",
+ description="GREEK SMALL LETTER MU",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="mu",
+ uccode=0x039C,
+ unicodeslot=0x03BC,
+ },
+ [0x03BD]={
+ adobename="nu",
+ category="ll",
+ cjkwd="a",
+ contextname="greeknu",
+ description="GREEK SMALL LETTER NU",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="nu",
+ uccode=0x039D,
+ unicodeslot=0x03BD,
+ },
+ [0x03BE]={
+ adobename="xi",
+ category="ll",
+ cjkwd="a",
+ contextname="greekxi",
+ description="GREEK SMALL LETTER XI",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="xi",
+ uccode=0x039E,
+ unicodeslot=0x03BE,
+ },
+ [0x03BF]={
+ adobename="omicron",
+ category="ll",
+ cjkwd="a",
+ contextname="greekomicron",
+ description="GREEK SMALL LETTER OMICRON",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="omicron",
+ uccode=0x039F,
+ unicodeslot=0x03BF,
+ },
+ [0x03C0]={
+ adobename="pi",
+ category="ll",
+ cjkwd="a",
+ contextname="greekpi",
+ description="GREEK SMALL LETTER PI",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="pi",
+ uccode=0x03A0,
+ unicodeslot=0x03C0,
+ },
+ [0x03C1]={
+ adobename="rho",
+ category="ll",
+ cjkwd="a",
+ contextname="greekrho",
+ description="GREEK SMALL LETTER RHO",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="rho",
+ uccode=0x03A1,
+ unicodeslot=0x03C1,
+ },
+ [0x03C2]={
+ adobename="sigmafinal",
+ category="ll",
+ contextname="greekfinalsigma",
+ description="GREEK SMALL LETTER FINAL SIGMA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="varsigma",
+ uccode=0x03A3,
+ unicodeslot=0x03C2,
+ },
+ [0x03C3]={
+ adobename="sigma",
+ category="ll",
+ cjkwd="a",
+ contextname="greeksigma",
+ description="GREEK SMALL LETTER SIGMA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="sigma",
+ uccode=0x03A3,
+ unicodeslot=0x03C3,
+ },
+ [0x03C4]={
+ adobename="tau",
+ category="ll",
+ cjkwd="a",
+ contextname="greektau",
+ description="GREEK SMALL LETTER TAU",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="tau",
+ uccode=0x03A4,
+ unicodeslot=0x03C4,
+ },
+ [0x03C5]={
+ adobename="upsilon",
+ category="ll",
+ cjkwd="a",
+ contextname="greekupsilon",
+ description="GREEK SMALL LETTER UPSILON",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="upsilon",
+ uccode=0x03A5,
+ unicodeslot=0x03C5,
+ },
+ [0x03C6]={
+ adobename="phi",
+ category="ll",
+ cjkwd="a",
+ contextname="greekphi",
+ description="GREEK SMALL LETTER PHI",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="varphi",
+ uccode=0x03A6,
+ unicodeslot=0x03C6,
+ },
+ [0x03C7]={
+ adobename="chi",
+ category="ll",
+ cjkwd="a",
+ contextname="greekchi",
+ description="GREEK SMALL LETTER CHI",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="chi",
+ uccode=0x03A7,
+ unicodeslot=0x03C7,
+ },
+ [0x03C8]={
+ adobename="psi",
+ category="ll",
+ cjkwd="a",
+ contextname="greekpsi",
+ description="GREEK SMALL LETTER PSI",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="psi",
+ uccode=0x03A8,
+ unicodeslot=0x03C8,
+ },
+ [0x03C9]={
+ adobename="omega",
+ category="ll",
+ cjkwd="a",
+ contextname="greekomega",
+ description="GREEK SMALL LETTER OMEGA",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="omega",
+ uccode=0x03A9,
+ unicodeslot=0x03C9,
+ },
+ [0x03CA]={
+ adobename="iotadieresis",
+ category="ll",
+ contextname="greekiotadialytika",
+ description="GREEK SMALL LETTER IOTA WITH DIALYTIKA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x03B9, 0x0308 },
+ uccode=0x03AA,
+ unicodeslot=0x03CA,
+ },
+ [0x03CB]={
+ adobename="upsilondieresis",
+ category="ll",
+ contextname="greekupsilondiaeresis",
+ description="GREEK SMALL LETTER UPSILON WITH DIALYTIKA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03C5, 0x0308 },
+ uccode=0x03AB,
+ unicodeslot=0x03CB,
+ },
+ [0x03CC]={
+ adobename="omicrontonos",
+ category="ll",
+ contextname="greekomicrontonos",
+ description="GREEK SMALL LETTER OMICRON WITH TONOS",
+ direction="l",
+ linebreak="al",
+ shcode=0x03BF,
+ specials={ "char", 0x03BF, 0x0301 },
+ uccode=0x038C,
+ unicodeslot=0x03CC,
+ },
+ [0x03CD]={
+ adobename="upsilontonos",
+ category="ll",
+ contextname="greekupsilontonos",
+ description="GREEK SMALL LETTER UPSILON WITH TONOS",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03C5, 0x0301 },
+ uccode=0x038E,
+ unicodeslot=0x03CD,
+ },
+ [0x03CE]={
+ adobename="omegatonos",
+ category="ll",
+ contextname="greekomegatonos",
+ description="GREEK SMALL LETTER OMEGA WITH TONOS",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x03C9, 0x0301 },
+ uccode=0x038F,
+ unicodeslot=0x03CE,
+ },
+ [0x03CF]={
+ category="lu",
+ description="GREEK CAPITAL KAI SYMBOL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x03CF,
+ },
+ [0x03D0]={
+ adobename="betasymbolgreek",
+ category="ll",
+ description="GREEK BETA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x03B2 },
+ uccode=0x0392,
+ unicodeslot=0x03D0,
+ },
+ [0x03D1]={
+ adobename="thetasymbolgreek",
+ category="ll",
+ contextname="greekthetaalt",
+ description="GREEK THETA SYMBOL",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="varTheta",
+ specials={ "compat", 0x03B8 },
+ uccode=0x0398,
+ unicodeslot=0x03D1,
+ },
+ [0x03D2]={
+ adobename="Upsilonhooksymbol",
+ category="lu",
+ description="GREEK UPSILON WITH HOOK SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x03A5 },
+ unicodeslot=0x03D2,
+ },
+ [0x03D3]={
+ adobename="Upsilonacutehooksymbolgreek",
+ category="lu",
+ description="GREEK UPSILON WITH ACUTE AND HOOK SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x03D2, 0x0301 },
+ unicodeslot=0x03D3,
+ },
+ [0x03D4]={
+ adobename="Upsilondieresishooksymbolgreek",
+ category="lu",
+ description="GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x03D2, 0x0308 },
+ unicodeslot=0x03D4,
+ },
+ [0x03D5]={
+ adobename="phisymbolgreek",
+ category="ll",
+ contextname="greekphialt",
+ description="GREEK PHI SYMBOL",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="phi",
+ specials={ "compat", 0x03C6 },
+ uccode=0x03A6,
+ unicodeslot=0x03D5,
+ },
+ [0x03D6]={
+ adobename="pisymbolgreek",
+ category="ll",
+ contextname="greekpialt",
+ description="GREEK PI SYMBOL",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="varpi",
+ specials={ "compat", 0x03C0 },
+ uccode=0x03A0,
+ unicodeslot=0x03D6,
+ },
+ [0x03D7]={
+ category="ll",
+ description="GREEK KAI SYMBOL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x03D7,
+ },
+ [0x03D8]={
+ category="lu",
+ description="GREEK LETTER ARCHAIC KOPPA",
+ direction="l",
+ lccode=0x03D9,
+ linebreak="al",
+ unicodeslot=0x03D8,
+ },
+ [0x03D9]={
+ category="ll",
+ contextname="greekkoppa",
+ description="GREEK SMALL LETTER ARCHAIC KOPPA",
+ direction="l",
+ linebreak="al",
+ uccode=0x03D8,
+ unicodeslot=0x03D9,
+ },
+ [0x03DA]={
+ adobename="Stigmagreek",
+ category="lu",
+ description="GREEK LETTER STIGMA",
+ direction="l",
+ lccode=0x03DB,
+ linebreak="al",
+ unicodeslot=0x03DA,
+ },
+ [0x03DB]={
+ category="ll",
+ contextname="greekstigma",
+ description="GREEK SMALL LETTER STIGMA",
+ direction="l",
+ linebreak="al",
+ uccode=0x03DA,
+ unicodeslot=0x03DB,
+ },
+ [0x03DC]={
+ adobename="Digammagreek",
+ category="lu",
+ description="GREEK LETTER DIGAMMA",
+ direction="l",
+ lccode=0x03DD,
+ linebreak="al",
+ mathclass="variable",
+ mathname="digamma",
+ unicodeslot=0x03DC,
+ },
+ [0x03DD]={
+ category="ll",
+ contextname="greekdigamma",
+ description="GREEK SMALL LETTER DIGAMMA",
+ direction="l",
+ linebreak="al",
+ uccode=0x03DC,
+ unicodeslot=0x03DD,
+ },
+ [0x03DE]={
+ adobename="Koppagreek",
+ category="lu",
+ description="GREEK LETTER KOPPA",
+ direction="l",
+ lccode=0x03DF,
+ linebreak="al",
+ unicodeslot=0x03DE,
+ },
+ [0x03DF]={
+ category="ll",
+ contextname="greeknumkoppa",
+ description="GREEK SMALL LETTER KOPPA",
+ direction="l",
+ linebreak="al",
+ uccode=0x03DE,
+ unicodeslot=0x03DF,
+ },
+ [0x03E0]={
+ adobename="Sampigreek",
+ category="lu",
+ description="GREEK LETTER SAMPI",
+ direction="l",
+ lccode=0x03E1,
+ linebreak="al",
+ unicodeslot=0x03E0,
+ },
+ [0x03E1]={
+ category="ll",
+ contextname="greeksampi",
+ description="GREEK SMALL LETTER SAMPI",
+ direction="l",
+ linebreak="al",
+ uccode=0x03E0,
+ unicodeslot=0x03E1,
+ },
+ [0x03E2]={
+ adobename="Sheicoptic",
+ category="lu",
+ description="COPTIC CAPITAL LETTER SHEI",
+ direction="l",
+ lccode=0x03E3,
+ linebreak="al",
+ unicodeslot=0x03E2,
+ },
+ [0x03E3]={
+ adobename="sheicoptic",
+ category="ll",
+ description="COPTIC SMALL LETTER SHEI",
+ direction="l",
+ linebreak="al",
+ uccode=0x03E2,
+ unicodeslot=0x03E3,
+ },
+ [0x03E4]={
+ adobename="Feicoptic",
+ category="lu",
+ description="COPTIC CAPITAL LETTER FEI",
+ direction="l",
+ lccode=0x03E5,
+ linebreak="al",
+ unicodeslot=0x03E4,
+ },
+ [0x03E5]={
+ adobename="feicoptic",
+ category="ll",
+ description="COPTIC SMALL LETTER FEI",
+ direction="l",
+ linebreak="al",
+ uccode=0x03E4,
+ unicodeslot=0x03E5,
+ },
+ [0x03E6]={
+ adobename="Kheicoptic",
+ category="lu",
+ description="COPTIC CAPITAL LETTER KHEI",
+ direction="l",
+ lccode=0x03E7,
+ linebreak="al",
+ unicodeslot=0x03E6,
+ },
+ [0x03E7]={
+ adobename="kheicoptic",
+ category="ll",
+ description="COPTIC SMALL LETTER KHEI",
+ direction="l",
+ linebreak="al",
+ uccode=0x03E6,
+ unicodeslot=0x03E7,
+ },
+ [0x03E8]={
+ adobename="Horicoptic",
+ category="lu",
+ description="COPTIC CAPITAL LETTER HORI",
+ direction="l",
+ lccode=0x03E9,
+ linebreak="al",
+ unicodeslot=0x03E8,
+ },
+ [0x03E9]={
+ adobename="horicoptic",
+ category="ll",
+ description="COPTIC SMALL LETTER HORI",
+ direction="l",
+ linebreak="al",
+ uccode=0x03E8,
+ unicodeslot=0x03E9,
+ },
+ [0x03EA]={
+ adobename="Gangiacoptic",
+ category="lu",
+ description="COPTIC CAPITAL LETTER GANGIA",
+ direction="l",
+ lccode=0x03EB,
+ linebreak="al",
+ unicodeslot=0x03EA,
+ },
+ [0x03EB]={
+ adobename="gangiacoptic",
+ category="ll",
+ description="COPTIC SMALL LETTER GANGIA",
+ direction="l",
+ linebreak="al",
+ uccode=0x03EA,
+ unicodeslot=0x03EB,
+ },
+ [0x03EC]={
+ adobename="Shimacoptic",
+ category="lu",
+ description="COPTIC CAPITAL LETTER SHIMA",
+ direction="l",
+ lccode=0x03ED,
+ linebreak="al",
+ unicodeslot=0x03EC,
+ },
+ [0x03ED]={
+ adobename="shimacoptic",
+ category="ll",
+ description="COPTIC SMALL LETTER SHIMA",
+ direction="l",
+ linebreak="al",
+ uccode=0x03EC,
+ unicodeslot=0x03ED,
+ },
+ [0x03EE]={
+ adobename="Deicoptic",
+ category="lu",
+ description="COPTIC CAPITAL LETTER DEI",
+ direction="l",
+ lccode=0x03EF,
+ linebreak="al",
+ unicodeslot=0x03EE,
+ },
+ [0x03EF]={
+ adobename="deicoptic",
+ category="ll",
+ description="COPTIC SMALL LETTER DEI",
+ direction="l",
+ linebreak="al",
+ uccode=0x03EE,
+ unicodeslot=0x03EF,
+ },
+ [0x03F0]={
+ adobename="kappasymbolgreek",
+ category="ll",
+ description="GREEK KAPPA SYMBOL",
+ direction="l",
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="varkappa",
+ specials={ "compat", 0x03BA },
+ uccode=0x039A,
+ unicodeslot=0x03F0,
+ },
+ [0x03F1]={
+ adobename="rhosymbolgreek",
+ category="ll",
+ contextname="greekrhoalt",
+ description="GREEK RHO SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x03C1 },
+ uccode=0x03A1,
+ unicodeslot=0x03F1,
+ },
+ [0x03F2]={
+ adobename="sigmalunatesymbolgreek",
+ category="ll",
+ contextname="greeksigmalunate",
+ description="GREEK LUNATE SIGMA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x03C2 },
+ uccode=0x03F9,
+ unicodeslot=0x03F2,
+ },
+ [0x03F3]={
+ adobename="yotgreek",
+ category="ll",
+ description="GREEK LETTER YOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x03F3,
+ },
+ [0x03F4]={
+ category="lu",
+ description="GREEK CAPITAL THETA SYMBOL",
+ direction="l",
+ lccode=0x03B8,
+ linebreak="al",
+ specials={ "compat", 0x0398 },
+ unicodeslot=0x03F4,
+ },
+ [0x03F5]={
+ category="ll",
+ contextname="greekepsilonalt",
+ description="GREEK LUNATE EPSILON SYMBOL",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="epsilon",
+ specials={ "compat", 0x03B5 },
+ uccode=0x0395,
+ unicodeslot=0x03F5,
+ },
+ [0x03F6]={
+ category="sm",
+ description="GREEK REVERSED LUNATE EPSILON SYMBOL",
+ direction="on",
+ linebreak="al",
+ mathclass="variable",
+ mathname="backepsilon",
+ unicodeslot=0x03F6,
+ },
+ [0x03F7]={
+ category="lu",
+ description="GREEK CAPITAL LETTER SHO",
+ direction="l",
+ lccode=0x03F8,
+ linebreak="al",
+ unicodeslot=0x03F7,
+ },
+ [0x03F8]={
+ category="ll",
+ description="GREEK SMALL LETTER SHO",
+ direction="l",
+ linebreak="al",
+ uccode=0x03F7,
+ unicodeslot=0x03F8,
+ },
+ [0x03F9]={
+ category="lu",
+ contextname="greekSigmalunate",
+ description="GREEK CAPITAL LUNATE SIGMA SYMBOL",
+ direction="l",
+ lccode=0x03F2,
+ linebreak="al",
+ specials={ "compat", 0x03A3 },
+ unicodeslot=0x03F9,
+ },
+ [0x03FA]={
+ category="lu",
+ description="GREEK CAPITAL LETTER SAN",
+ direction="l",
+ lccode=0x03FB,
+ linebreak="al",
+ unicodeslot=0x03FA,
+ },
+ [0x03FB]={
+ category="ll",
+ description="GREEK SMALL LETTER SAN",
+ direction="l",
+ linebreak="al",
+ uccode=0x03FA,
+ unicodeslot=0x03FB,
+ },
+ [0x03FC]={
+ category="ll",
+ description="GREEK RHO WITH STROKE SYMBOL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x03FC,
+ },
+ [0x03FD]={
+ category="lu",
+ description="GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL",
+ direction="l",
+ lccode=0x037B,
+ linebreak="al",
+ unicodeslot=0x03FD,
+ },
+ [0x03FE]={
+ category="lu",
+ description="GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL",
+ direction="l",
+ lccode=0x037C,
+ linebreak="al",
+ unicodeslot=0x03FE,
+ },
+ [0x03FF]={
+ category="lu",
+ description="GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL",
+ direction="l",
+ lccode=0x037D,
+ linebreak="al",
+ unicodeslot=0x03FF,
+ },
+ [0x0400]={
+ category="lu",
+ contextname="cyrillicEgrave",
+ description="CYRILLIC CAPITAL LETTER IE WITH GRAVE",
+ direction="l",
+ lccode=0x0450,
+ linebreak="al",
+ shcode=0x0415,
+ specials={ "char", 0x0415, 0x0300 },
+ unicodeslot=0x0400,
+ },
+ [0x0401]={
+ adobename="afii10023",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicYO",
+ description="CYRILLIC CAPITAL LETTER IO",
+ direction="l",
+ lccode=0x0451,
+ linebreak="al",
+ specials={ "char", 0x0415, 0x0308 },
+ unicodeslot=0x0401,
+ },
+ [0x0402]={
+ adobename="afii10051",
+ category="lu",
+ contextname="cyrillicDJE",
+ description="CYRILLIC CAPITAL LETTER DJE",
+ direction="l",
+ lccode=0x0452,
+ linebreak="al",
+ unicodeslot=0x0402,
+ },
+ [0x0403]={
+ adobename="afii10052",
+ category="lu",
+ contextname="cyrillicGJE",
+ description="CYRILLIC CAPITAL LETTER GJE",
+ direction="l",
+ lccode=0x0453,
+ linebreak="al",
+ specials={ "char", 0x0413, 0x0301 },
+ unicodeslot=0x0403,
+ },
+ [0x0404]={
+ adobename="afii10053",
+ category="lu",
+ contextname="cyrillicIE",
+ description="CYRILLIC CAPITAL LETTER UKRAINIAN IE",
+ direction="l",
+ lccode=0x0454,
+ linebreak="al",
+ unicodeslot=0x0404,
+ },
+ [0x0405]={
+ adobename="afii10054",
+ category="lu",
+ contextname="cyrillicDZE",
+ description="CYRILLIC CAPITAL LETTER DZE",
+ direction="l",
+ lccode=0x0455,
+ linebreak="al",
+ unicodeslot=0x0405,
+ },
+ [0x0406]={
+ adobename="afii10055",
+ category="lu",
+ contextname="cyrillicII",
+ description="CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I",
+ direction="l",
+ lccode=0x0456,
+ linebreak="al",
+ unicodeslot=0x0406,
+ },
+ [0x0407]={
+ adobename="afii10056",
+ category="lu",
+ contextname="cyrillicYI",
+ description="CYRILLIC CAPITAL LETTER YI",
+ direction="l",
+ lccode=0x0457,
+ linebreak="al",
+ specials={ "char", 0x0406, 0x0308 },
+ unicodeslot=0x0407,
+ },
+ [0x0408]={
+ adobename="afii10057",
+ category="lu",
+ contextname="cyrillicJE",
+ description="CYRILLIC CAPITAL LETTER JE",
+ direction="l",
+ lccode=0x0458,
+ linebreak="al",
+ unicodeslot=0x0408,
+ },
+ [0x0409]={
+ adobename="afii10058",
+ category="lu",
+ contextname="cyrillicLJE",
+ description="CYRILLIC CAPITAL LETTER LJE",
+ direction="l",
+ lccode=0x0459,
+ linebreak="al",
+ unicodeslot=0x0409,
+ },
+ [0x040A]={
+ adobename="afii10059",
+ category="lu",
+ contextname="cyrillicNJE",
+ description="CYRILLIC CAPITAL LETTER NJE",
+ direction="l",
+ lccode=0x045A,
+ linebreak="al",
+ unicodeslot=0x040A,
+ },
+ [0x040B]={
+ adobename="afii10060",
+ category="lu",
+ contextname="cyrillicTSHE",
+ description="CYRILLIC CAPITAL LETTER TSHE",
+ direction="l",
+ lccode=0x045B,
+ linebreak="al",
+ unicodeslot=0x040B,
+ },
+ [0x040C]={
+ adobename="afii10061",
+ category="lu",
+ contextname="cyrillicKJE",
+ description="CYRILLIC CAPITAL LETTER KJE",
+ direction="l",
+ lccode=0x045C,
+ linebreak="al",
+ specials={ "char", 0x041A, 0x0301 },
+ unicodeslot=0x040C,
+ },
+ [0x040D]={
+ category="lu",
+ contextname="cyrillicIgrave",
+ description="CYRILLIC CAPITAL LETTER I WITH GRAVE",
+ direction="l",
+ lccode=0x045D,
+ linebreak="al",
+ shcode=0x0418,
+ specials={ "char", 0x0418, 0x0300 },
+ unicodeslot=0x040D,
+ },
+ [0x040E]={
+ adobename="afii10062",
+ category="lu",
+ contextname="cyrillicUSHRT",
+ description="CYRILLIC CAPITAL LETTER SHORT U",
+ direction="l",
+ lccode=0x045E,
+ linebreak="al",
+ specials={ "char", 0x0423, 0x0306 },
+ unicodeslot=0x040E,
+ },
+ [0x040F]={
+ adobename="afii10145",
+ category="lu",
+ contextname="cyrillicDZHE",
+ description="CYRILLIC CAPITAL LETTER DZHE",
+ direction="l",
+ lccode=0x045F,
+ linebreak="al",
+ unicodeslot=0x040F,
+ },
+ [0x0410]={
+ adobename="afii10017",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicA",
+ description="CYRILLIC CAPITAL LETTER A",
+ direction="l",
+ lccode=0x0430,
+ linebreak="al",
+ unicodeslot=0x0410,
+ },
+ [0x0411]={
+ adobename="afii10018",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicB",
+ description="CYRILLIC CAPITAL LETTER BE",
+ direction="l",
+ lccode=0x0431,
+ linebreak="al",
+ unicodeslot=0x0411,
+ },
+ [0x0412]={
+ adobename="afii10019",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicV",
+ description="CYRILLIC CAPITAL LETTER VE",
+ direction="l",
+ lccode=0x0432,
+ linebreak="al",
+ unicodeslot=0x0412,
+ },
+ [0x0413]={
+ adobename="afii10020",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicG",
+ description="CYRILLIC CAPITAL LETTER GHE",
+ direction="l",
+ lccode=0x0433,
+ linebreak="al",
+ unicodeslot=0x0413,
+ },
+ [0x0414]={
+ adobename="afii10021",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicD",
+ description="CYRILLIC CAPITAL LETTER DE",
+ direction="l",
+ lccode=0x0434,
+ linebreak="al",
+ unicodeslot=0x0414,
+ },
+ [0x0415]={
+ adobename="afii10022",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicE",
+ description="CYRILLIC CAPITAL LETTER IE",
+ direction="l",
+ lccode=0x0435,
+ linebreak="al",
+ unicodeslot=0x0415,
+ },
+ [0x0416]={
+ adobename="afii10024",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicZH",
+ description="CYRILLIC CAPITAL LETTER ZHE",
+ direction="l",
+ lccode=0x0436,
+ linebreak="al",
+ unicodeslot=0x0416,
+ },
+ [0x0417]={
+ adobename="afii10025",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicZ",
+ description="CYRILLIC CAPITAL LETTER ZE",
+ direction="l",
+ lccode=0x0437,
+ linebreak="al",
+ unicodeslot=0x0417,
+ },
+ [0x0418]={
+ adobename="afii10026",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicI",
+ description="CYRILLIC CAPITAL LETTER I",
+ direction="l",
+ lccode=0x0438,
+ linebreak="al",
+ unicodeslot=0x0418,
+ },
+ [0x0419]={
+ adobename="afii10027",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicISHRT",
+ description="CYRILLIC CAPITAL LETTER SHORT I",
+ direction="l",
+ lccode=0x0439,
+ linebreak="al",
+ specials={ "char", 0x0418, 0x0306 },
+ unicodeslot=0x0419,
+ },
+ [0x041A]={
+ adobename="afii10028",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicK",
+ description="CYRILLIC CAPITAL LETTER KA",
+ direction="l",
+ lccode=0x043A,
+ linebreak="al",
+ unicodeslot=0x041A,
+ },
+ [0x041B]={
+ adobename="afii10029",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicL",
+ description="CYRILLIC CAPITAL LETTER EL",
+ direction="l",
+ lccode=0x043B,
+ linebreak="al",
+ unicodeslot=0x041B,
+ },
+ [0x041C]={
+ adobename="afii10030",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicM",
+ description="CYRILLIC CAPITAL LETTER EM",
+ direction="l",
+ lccode=0x043C,
+ linebreak="al",
+ unicodeslot=0x041C,
+ },
+ [0x041D]={
+ adobename="afii10031",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicN",
+ description="CYRILLIC CAPITAL LETTER EN",
+ direction="l",
+ lccode=0x043D,
+ linebreak="al",
+ unicodeslot=0x041D,
+ },
+ [0x041E]={
+ adobename="afii10032",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicO",
+ description="CYRILLIC CAPITAL LETTER O",
+ direction="l",
+ lccode=0x043E,
+ linebreak="al",
+ unicodeslot=0x041E,
+ },
+ [0x041F]={
+ adobename="afii10033",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicP",
+ description="CYRILLIC CAPITAL LETTER PE",
+ direction="l",
+ lccode=0x043F,
+ linebreak="al",
+ unicodeslot=0x041F,
+ },
+ [0x0420]={
+ adobename="afii10034",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicR",
+ description="CYRILLIC CAPITAL LETTER ER",
+ direction="l",
+ lccode=0x0440,
+ linebreak="al",
+ unicodeslot=0x0420,
+ },
+ [0x0421]={
+ adobename="afii10035",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicS",
+ description="CYRILLIC CAPITAL LETTER ES",
+ direction="l",
+ lccode=0x0441,
+ linebreak="al",
+ unicodeslot=0x0421,
+ },
+ [0x0422]={
+ adobename="afii10036",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicT",
+ description="CYRILLIC CAPITAL LETTER TE",
+ direction="l",
+ lccode=0x0442,
+ linebreak="al",
+ unicodeslot=0x0422,
+ },
+ [0x0423]={
+ adobename="afii10037",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicU",
+ description="CYRILLIC CAPITAL LETTER U",
+ direction="l",
+ lccode=0x0443,
+ linebreak="al",
+ unicodeslot=0x0423,
+ },
+ [0x0424]={
+ adobename="afii10038",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicF",
+ description="CYRILLIC CAPITAL LETTER EF",
+ direction="l",
+ lccode=0x0444,
+ linebreak="al",
+ unicodeslot=0x0424,
+ },
+ [0x0425]={
+ adobename="afii10039",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicH",
+ description="CYRILLIC CAPITAL LETTER HA",
+ direction="l",
+ lccode=0x0445,
+ linebreak="al",
+ unicodeslot=0x0425,
+ },
+ [0x0426]={
+ adobename="afii10040",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicC",
+ description="CYRILLIC CAPITAL LETTER TSE",
+ direction="l",
+ lccode=0x0446,
+ linebreak="al",
+ unicodeslot=0x0426,
+ },
+ [0x0427]={
+ adobename="afii10041",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicCH",
+ description="CYRILLIC CAPITAL LETTER CHE",
+ direction="l",
+ lccode=0x0447,
+ linebreak="al",
+ unicodeslot=0x0427,
+ },
+ [0x0428]={
+ adobename="afii10042",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicSH",
+ description="CYRILLIC CAPITAL LETTER SHA",
+ direction="l",
+ lccode=0x0448,
+ linebreak="al",
+ unicodeslot=0x0428,
+ },
+ [0x0429]={
+ adobename="afii10043",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicSHCH",
+ description="CYRILLIC CAPITAL LETTER SHCHA",
+ direction="l",
+ lccode=0x0449,
+ linebreak="al",
+ unicodeslot=0x0429,
+ },
+ [0x042A]={
+ adobename="afii10044",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicHRDSN",
+ description="CYRILLIC CAPITAL LETTER HARD SIGN",
+ direction="l",
+ lccode=0x044A,
+ linebreak="al",
+ unicodeslot=0x042A,
+ },
+ [0x042B]={
+ adobename="afii10045",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicERY",
+ description="CYRILLIC CAPITAL LETTER YERU",
+ direction="l",
+ lccode=0x044B,
+ linebreak="al",
+ unicodeslot=0x042B,
+ },
+ [0x042C]={
+ adobename="afii10046",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicSFTSN",
+ description="CYRILLIC CAPITAL LETTER SOFT SIGN",
+ direction="l",
+ lccode=0x044C,
+ linebreak="al",
+ unicodeslot=0x042C,
+ },
+ [0x042D]={
+ adobename="afii10047",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicEREV",
+ description="CYRILLIC CAPITAL LETTER E",
+ direction="l",
+ lccode=0x044D,
+ linebreak="al",
+ unicodeslot=0x042D,
+ },
+ [0x042E]={
+ adobename="afii10048",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicYU",
+ description="CYRILLIC CAPITAL LETTER YU",
+ direction="l",
+ lccode=0x044E,
+ linebreak="al",
+ unicodeslot=0x042E,
+ },
+ [0x042F]={
+ adobename="afii10049",
+ category="lu",
+ cjkwd="a",
+ contextname="cyrillicYA",
+ description="CYRILLIC CAPITAL LETTER YA",
+ direction="l",
+ lccode=0x044F,
+ linebreak="al",
+ unicodeslot=0x042F,
+ },
+ [0x0430]={
+ adobename="afii10065",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillica",
+ description="CYRILLIC SMALL LETTER A",
+ direction="l",
+ linebreak="al",
+ uccode=0x0410,
+ unicodeslot=0x0430,
+ },
+ [0x0431]={
+ adobename="becyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicb",
+ description="CYRILLIC SMALL LETTER BE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0411,
+ unicodeslot=0x0431,
+ },
+ [0x0432]={
+ adobename="vecyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicv",
+ description="CYRILLIC SMALL LETTER VE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0412,
+ unicodeslot=0x0432,
+ },
+ [0x0433]={
+ adobename="gecyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicg",
+ description="CYRILLIC SMALL LETTER GHE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0413,
+ unicodeslot=0x0433,
+ },
+ [0x0434]={
+ adobename="decyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicd",
+ description="CYRILLIC SMALL LETTER DE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0414,
+ unicodeslot=0x0434,
+ },
+ [0x0435]={
+ adobename="iecyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillice",
+ description="CYRILLIC SMALL LETTER IE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0415,
+ unicodeslot=0x0435,
+ },
+ [0x0436]={
+ adobename="zhecyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrilliczh",
+ description="CYRILLIC SMALL LETTER ZHE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0416,
+ unicodeslot=0x0436,
+ },
+ [0x0437]={
+ adobename="zecyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicz",
+ description="CYRILLIC SMALL LETTER ZE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0417,
+ unicodeslot=0x0437,
+ },
+ [0x0438]={
+ adobename="iicyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillici",
+ description="CYRILLIC SMALL LETTER I",
+ direction="l",
+ linebreak="al",
+ uccode=0x0418,
+ unicodeslot=0x0438,
+ },
+ [0x0439]={
+ adobename="iishortcyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicishrt",
+ description="CYRILLIC SMALL LETTER SHORT I",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0438, 0x0306 },
+ uccode=0x0419,
+ unicodeslot=0x0439,
+ },
+ [0x043A]={
+ adobename="kacyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillick",
+ description="CYRILLIC SMALL LETTER KA",
+ direction="l",
+ linebreak="al",
+ uccode=0x041A,
+ unicodeslot=0x043A,
+ },
+ [0x043B]={
+ adobename="elcyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicl",
+ description="CYRILLIC SMALL LETTER EL",
+ direction="l",
+ linebreak="al",
+ uccode=0x041B,
+ unicodeslot=0x043B,
+ },
+ [0x043C]={
+ adobename="emcyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicm",
+ description="CYRILLIC SMALL LETTER EM",
+ direction="l",
+ linebreak="al",
+ uccode=0x041C,
+ unicodeslot=0x043C,
+ },
+ [0x043D]={
+ adobename="encyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicn",
+ description="CYRILLIC SMALL LETTER EN",
+ direction="l",
+ linebreak="al",
+ uccode=0x041D,
+ unicodeslot=0x043D,
+ },
+ [0x043E]={
+ adobename="ocyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillico",
+ description="CYRILLIC SMALL LETTER O",
+ direction="l",
+ linebreak="al",
+ uccode=0x041E,
+ unicodeslot=0x043E,
+ },
+ [0x043F]={
+ adobename="pecyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicp",
+ description="CYRILLIC SMALL LETTER PE",
+ direction="l",
+ linebreak="al",
+ uccode=0x041F,
+ unicodeslot=0x043F,
+ },
+ [0x0440]={
+ adobename="ercyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicr",
+ description="CYRILLIC SMALL LETTER ER",
+ direction="l",
+ linebreak="al",
+ uccode=0x0420,
+ unicodeslot=0x0440,
+ },
+ [0x0441]={
+ adobename="escyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillics",
+ description="CYRILLIC SMALL LETTER ES",
+ direction="l",
+ linebreak="al",
+ uccode=0x0421,
+ unicodeslot=0x0441,
+ },
+ [0x0442]={
+ adobename="tecyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillict",
+ description="CYRILLIC SMALL LETTER TE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0422,
+ unicodeslot=0x0442,
+ },
+ [0x0443]={
+ adobename="ucyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicu",
+ description="CYRILLIC SMALL LETTER U",
+ direction="l",
+ linebreak="al",
+ uccode=0x0423,
+ unicodeslot=0x0443,
+ },
+ [0x0444]={
+ adobename="efcyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicf",
+ description="CYRILLIC SMALL LETTER EF",
+ direction="l",
+ linebreak="al",
+ uccode=0x0424,
+ unicodeslot=0x0444,
+ },
+ [0x0445]={
+ adobename="khacyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillich",
+ description="CYRILLIC SMALL LETTER HA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0425,
+ unicodeslot=0x0445,
+ },
+ [0x0446]={
+ adobename="tsecyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicc",
+ description="CYRILLIC SMALL LETTER TSE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0426,
+ unicodeslot=0x0446,
+ },
+ [0x0447]={
+ adobename="checyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicch",
+ description="CYRILLIC SMALL LETTER CHE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0427,
+ unicodeslot=0x0447,
+ },
+ [0x0448]={
+ adobename="shacyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicsh",
+ description="CYRILLIC SMALL LETTER SHA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0428,
+ unicodeslot=0x0448,
+ },
+ [0x0449]={
+ adobename="shchacyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicshch",
+ description="CYRILLIC SMALL LETTER SHCHA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0429,
+ unicodeslot=0x0449,
+ },
+ [0x044A]={
+ adobename="hardsigncyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillichrdsn",
+ description="CYRILLIC SMALL LETTER HARD SIGN",
+ direction="l",
+ linebreak="al",
+ uccode=0x042A,
+ unicodeslot=0x044A,
+ },
+ [0x044B]={
+ adobename="yericyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicery",
+ description="CYRILLIC SMALL LETTER YERU",
+ direction="l",
+ linebreak="al",
+ uccode=0x042B,
+ unicodeslot=0x044B,
+ },
+ [0x044C]={
+ adobename="softsigncyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicsftsn",
+ description="CYRILLIC SMALL LETTER SOFT SIGN",
+ direction="l",
+ linebreak="al",
+ uccode=0x042C,
+ unicodeslot=0x044C,
+ },
+ [0x044D]={
+ adobename="ereversedcyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicerev",
+ description="CYRILLIC SMALL LETTER E",
+ direction="l",
+ linebreak="al",
+ uccode=0x042D,
+ unicodeslot=0x044D,
+ },
+ [0x044E]={
+ adobename="iucyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicyu",
+ description="CYRILLIC SMALL LETTER YU",
+ direction="l",
+ linebreak="al",
+ uccode=0x042E,
+ unicodeslot=0x044E,
+ },
+ [0x044F]={
+ adobename="iacyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicya",
+ description="CYRILLIC SMALL LETTER YA",
+ direction="l",
+ linebreak="al",
+ uccode=0x042F,
+ unicodeslot=0x044F,
+ },
+ [0x0450]={
+ category="ll",
+ contextname="cyrillicegrave",
+ description="CYRILLIC SMALL LETTER IE WITH GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0435,
+ specials={ "char", 0x0435, 0x0300 },
+ uccode=0x0400,
+ unicodeslot=0x0450,
+ },
+ [0x0451]={
+ adobename="iocyrillic",
+ category="ll",
+ cjkwd="a",
+ contextname="cyrillicyo",
+ description="CYRILLIC SMALL LETTER IO",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0435, 0x0308 },
+ uccode=0x0401,
+ unicodeslot=0x0451,
+ },
+ [0x0452]={
+ adobename="djecyrillic",
+ category="ll",
+ contextname="cyrillicdje",
+ description="CYRILLIC SMALL LETTER DJE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0402,
+ unicodeslot=0x0452,
+ },
+ [0x0453]={
+ adobename="gjecyrillic",
+ category="ll",
+ contextname="cyrillicgje",
+ description="CYRILLIC SMALL LETTER GJE",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0433, 0x0301 },
+ uccode=0x0403,
+ unicodeslot=0x0453,
+ },
+ [0x0454]={
+ adobename="ecyrillic",
+ category="ll",
+ contextname="cyrillicie",
+ description="CYRILLIC SMALL LETTER UKRAINIAN IE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0404,
+ unicodeslot=0x0454,
+ },
+ [0x0455]={
+ adobename="dzecyrillic",
+ category="ll",
+ contextname="cyrillicdze",
+ description="CYRILLIC SMALL LETTER DZE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0405,
+ unicodeslot=0x0455,
+ },
+ [0x0456]={
+ adobename="icyrillic",
+ category="ll",
+ contextname="cyrillicii",
+ description="CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I",
+ direction="l",
+ linebreak="al",
+ uccode=0x0406,
+ unicodeslot=0x0456,
+ },
+ [0x0457]={
+ adobename="yicyrillic",
+ category="ll",
+ contextname="cyrillicyi",
+ description="CYRILLIC SMALL LETTER YI",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0456, 0x0308 },
+ uccode=0x0407,
+ unicodeslot=0x0457,
+ },
+ [0x0458]={
+ adobename="jecyrillic",
+ category="ll",
+ contextname="cyrillicje",
+ description="CYRILLIC SMALL LETTER JE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0408,
+ unicodeslot=0x0458,
+ },
+ [0x0459]={
+ adobename="ljecyrillic",
+ category="ll",
+ contextname="cyrilliclje",
+ description="CYRILLIC SMALL LETTER LJE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0409,
+ unicodeslot=0x0459,
+ },
+ [0x045A]={
+ adobename="njecyrillic",
+ category="ll",
+ contextname="cyrillicnje",
+ description="CYRILLIC SMALL LETTER NJE",
+ direction="l",
+ linebreak="al",
+ uccode=0x040A,
+ unicodeslot=0x045A,
+ },
+ [0x045B]={
+ adobename="tshecyrillic",
+ category="ll",
+ contextname="cyrillictshe",
+ description="CYRILLIC SMALL LETTER TSHE",
+ direction="l",
+ linebreak="al",
+ uccode=0x040B,
+ unicodeslot=0x045B,
+ },
+ [0x045C]={
+ adobename="kjecyrillic",
+ category="ll",
+ contextname="cyrillickje",
+ description="CYRILLIC SMALL LETTER KJE",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x043A, 0x0301 },
+ uccode=0x040C,
+ unicodeslot=0x045C,
+ },
+ [0x045D]={
+ category="ll",
+ contextname="cyrillicigrave",
+ description="CYRILLIC SMALL LETTER I WITH GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0438,
+ specials={ "char", 0x0438, 0x0300 },
+ uccode=0x040D,
+ unicodeslot=0x045D,
+ },
+ [0x045E]={
+ adobename="ushortcyrillic",
+ category="ll",
+ contextname="cyrillicushrt",
+ description="CYRILLIC SMALL LETTER SHORT U",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0443, 0x0306 },
+ uccode=0x040E,
+ unicodeslot=0x045E,
+ },
+ [0x045F]={
+ adobename="dzhecyrillic",
+ category="ll",
+ contextname="cyrillicdzhe",
+ description="CYRILLIC SMALL LETTER DZHE",
+ direction="l",
+ linebreak="al",
+ uccode=0x040F,
+ unicodeslot=0x045F,
+ },
+ [0x0460]={
+ adobename="Omegacyrillic",
+ category="lu",
+ contextname="cyrillicOMEGA",
+ description="CYRILLIC CAPITAL LETTER OMEGA",
+ direction="l",
+ lccode=0x0461,
+ linebreak="al",
+ unicodeslot=0x0460,
+ },
+ [0x0461]={
+ adobename="omegacyrillic",
+ category="ll",
+ contextname="cyrillicomega",
+ description="CYRILLIC SMALL LETTER OMEGA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0460,
+ unicodeslot=0x0461,
+ },
+ [0x0462]={
+ adobename="afii10146",
+ category="lu",
+ contextname="cyrillicYAT",
+ description="CYRILLIC CAPITAL LETTER YAT",
+ direction="l",
+ lccode=0x0463,
+ linebreak="al",
+ unicodeslot=0x0462,
+ },
+ [0x0463]={
+ adobename="yatcyrillic",
+ category="ll",
+ contextname="cyrillicyat",
+ description="CYRILLIC SMALL LETTER YAT",
+ direction="l",
+ linebreak="al",
+ uccode=0x0462,
+ unicodeslot=0x0463,
+ },
+ [0x0464]={
+ adobename="Eiotifiedcyrillic",
+ category="lu",
+ contextname="cyrillicEiotified",
+ description="CYRILLIC CAPITAL LETTER IOTIFIED E",
+ direction="l",
+ lccode=0x0465,
+ linebreak="al",
+ unicodeslot=0x0464,
+ },
+ [0x0465]={
+ adobename="eiotifiedcyrillic",
+ category="ll",
+ contextname="cyrilliceiotified",
+ description="CYRILLIC SMALL LETTER IOTIFIED E",
+ direction="l",
+ linebreak="al",
+ uccode=0x0464,
+ unicodeslot=0x0465,
+ },
+ [0x0466]={
+ adobename="Yuslittlecyrillic",
+ category="lu",
+ contextname="cyrillicLITTLEYUS",
+ description="CYRILLIC CAPITAL LETTER LITTLE YUS",
+ direction="l",
+ lccode=0x0467,
+ linebreak="al",
+ unicodeslot=0x0466,
+ },
+ [0x0467]={
+ adobename="yuslittlecyrillic",
+ category="ll",
+ contextname="cyrilliclittleyus",
+ description="CYRILLIC SMALL LETTER LITTLE YUS",
+ direction="l",
+ linebreak="al",
+ uccode=0x0466,
+ unicodeslot=0x0467,
+ },
+ [0x0468]={
+ adobename="Yuslittleiotifiedcyrillic",
+ category="lu",
+ contextname="cyrillicLITTLEYUSiotified",
+ description="CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS",
+ direction="l",
+ lccode=0x0469,
+ linebreak="al",
+ unicodeslot=0x0468,
+ },
+ [0x0469]={
+ adobename="yuslittleiotifiedcyrillic",
+ category="ll",
+ contextname="cyrilliclittleyusiotified",
+ description="CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS",
+ direction="l",
+ linebreak="al",
+ uccode=0x0468,
+ unicodeslot=0x0469,
+ },
+ [0x046A]={
+ adobename="Yusbigcyrillic",
+ category="lu",
+ contextname="cyrillicBIGYUS",
+ description="CYRILLIC CAPITAL LETTER BIG YUS",
+ direction="l",
+ lccode=0x046B,
+ linebreak="al",
+ unicodeslot=0x046A,
+ },
+ [0x046B]={
+ adobename="yusbigcyrillic",
+ category="ll",
+ contextname="cyrillicbigyus",
+ description="CYRILLIC SMALL LETTER BIG YUS",
+ direction="l",
+ linebreak="al",
+ uccode=0x046A,
+ unicodeslot=0x046B,
+ },
+ [0x046C]={
+ adobename="Yusbigiotifiedcyrillic",
+ category="lu",
+ contextname="cyrillicBIGYUSiotified",
+ description="CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS",
+ direction="l",
+ lccode=0x046D,
+ linebreak="al",
+ unicodeslot=0x046C,
+ },
+ [0x046D]={
+ adobename="yusbigiotifiedcyrillic",
+ category="ll",
+ contextname="cyrillicbigyusiotified",
+ description="CYRILLIC SMALL LETTER IOTIFIED BIG YUS",
+ direction="l",
+ linebreak="al",
+ uccode=0x046C,
+ unicodeslot=0x046D,
+ },
+ [0x046E]={
+ adobename="Ksicyrillic",
+ category="lu",
+ contextname="cyrillicKSI",
+ description="CYRILLIC CAPITAL LETTER KSI",
+ direction="l",
+ lccode=0x046F,
+ linebreak="al",
+ unicodeslot=0x046E,
+ },
+ [0x046F]={
+ adobename="ksicyrillic",
+ category="ll",
+ contextname="cyrillicksi",
+ description="CYRILLIC SMALL LETTER KSI",
+ direction="l",
+ linebreak="al",
+ uccode=0x046E,
+ unicodeslot=0x046F,
+ },
+ [0x0470]={
+ adobename="Psicyrillic",
+ category="lu",
+ contextname="cyrillicPSI",
+ description="CYRILLIC CAPITAL LETTER PSI",
+ direction="l",
+ lccode=0x0471,
+ linebreak="al",
+ unicodeslot=0x0470,
+ },
+ [0x0471]={
+ adobename="psicyrillic",
+ category="ll",
+ contextname="cyrillicpsi",
+ description="CYRILLIC SMALL LETTER PSI",
+ direction="l",
+ linebreak="al",
+ uccode=0x0470,
+ unicodeslot=0x0471,
+ },
+ [0x0472]={
+ adobename="afii10147",
+ category="lu",
+ contextname="cyrillicFITA",
+ description="CYRILLIC CAPITAL LETTER FITA",
+ direction="l",
+ lccode=0x0473,
+ linebreak="al",
+ unicodeslot=0x0472,
+ },
+ [0x0473]={
+ adobename="fitacyrillic",
+ category="ll",
+ contextname="cyrillicfita",
+ description="CYRILLIC SMALL LETTER FITA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0472,
+ unicodeslot=0x0473,
+ },
+ [0x0474]={
+ adobename="afii10148",
+ category="lu",
+ contextname="cyrillicIZHITSA",
+ description="CYRILLIC CAPITAL LETTER IZHITSA",
+ direction="l",
+ lccode=0x0475,
+ linebreak="al",
+ unicodeslot=0x0474,
+ },
+ [0x0475]={
+ adobename="izhitsacyrillic",
+ category="ll",
+ contextname="cyrillicizhitsa",
+ description="CYRILLIC SMALL LETTER IZHITSA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0474,
+ unicodeslot=0x0475,
+ },
+ [0x0476]={
+ adobename="Izhitsadblgravecyrillic",
+ category="lu",
+ contextname="cyrillicIZHITSAdoublegrave",
+ description="CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT",
+ direction="l",
+ lccode=0x0477,
+ linebreak="al",
+ shcode=0x0474,
+ specials={ "char", 0x0474, 0x030F },
+ unicodeslot=0x0476,
+ },
+ [0x0477]={
+ adobename="izhitsadblgravecyrillic",
+ category="ll",
+ contextname="cyrillicizhitsadoublegrave",
+ description="CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT",
+ direction="l",
+ linebreak="al",
+ shcode=0x0475,
+ specials={ "char", 0x0475, 0x030F },
+ uccode=0x0476,
+ unicodeslot=0x0477,
+ },
+ [0x0478]={
+ adobename="Ukcyrillic",
+ category="lu",
+ contextname="cyrillicUK",
+ description="CYRILLIC CAPITAL LETTER UK",
+ direction="l",
+ lccode=0x0479,
+ linebreak="al",
+ unicodeslot=0x0478,
+ },
+ [0x0479]={
+ adobename="ukcyrillic",
+ category="ll",
+ contextname="cyrillicuk",
+ description="CYRILLIC SMALL LETTER UK",
+ direction="l",
+ linebreak="al",
+ uccode=0x0478,
+ unicodeslot=0x0479,
+ },
+ [0x047A]={
+ adobename="Omegaroundcyrillic",
+ category="lu",
+ contextname="cyrillicOMEGAround",
+ description="CYRILLIC CAPITAL LETTER ROUND OMEGA",
+ direction="l",
+ lccode=0x047B,
+ linebreak="al",
+ unicodeslot=0x047A,
+ },
+ [0x047B]={
+ adobename="omegaroundcyrillic",
+ category="ll",
+ contextname="cyrillicomegaround",
+ description="CYRILLIC SMALL LETTER ROUND OMEGA",
+ direction="l",
+ linebreak="al",
+ uccode=0x047A,
+ unicodeslot=0x047B,
+ },
+ [0x047C]={
+ adobename="Omegatitlocyrillic",
+ category="lu",
+ contextname="cyrillicOMEGAtitlo",
+ description="CYRILLIC CAPITAL LETTER OMEGA WITH TITLO",
+ direction="l",
+ lccode=0x047D,
+ linebreak="al",
+ shcode=0x0460,
+ unicodeslot=0x047C,
+ },
+ [0x047D]={
+ adobename="omegatitlocyrillic",
+ category="ll",
+ contextname="cyrillicomegatitlo",
+ description="CYRILLIC SMALL LETTER OMEGA WITH TITLO",
+ direction="l",
+ linebreak="al",
+ shcode=0x0461,
+ uccode=0x047C,
+ unicodeslot=0x047D,
+ },
+ [0x047E]={
+ adobename="Otcyrillic",
+ category="lu",
+ contextname="cyrillicOT",
+ description="CYRILLIC CAPITAL LETTER OT",
+ direction="l",
+ lccode=0x047F,
+ linebreak="al",
+ unicodeslot=0x047E,
+ },
+ [0x047F]={
+ adobename="otcyrillic",
+ category="ll",
+ contextname="cyrillicot",
+ description="CYRILLIC SMALL LETTER OT",
+ direction="l",
+ linebreak="al",
+ uccode=0x047E,
+ unicodeslot=0x047F,
+ },
+ [0x0480]={
+ adobename="Koppacyrillic",
+ category="lu",
+ contextname="cyrillicKOPPA",
+ description="CYRILLIC CAPITAL LETTER KOPPA",
+ direction="l",
+ lccode=0x0481,
+ linebreak="al",
+ unicodeslot=0x0480,
+ },
+ [0x0481]={
+ adobename="koppacyrillic",
+ category="ll",
+ contextname="cyrillickoppa",
+ description="CYRILLIC SMALL LETTER KOPPA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0480,
+ unicodeslot=0x0481,
+ },
+ [0x0482]={
+ adobename="thousandcyrillic",
+ category="so",
+ description="CYRILLIC THOUSANDS SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0482,
+ },
+ [0x0483]={
+ adobename="titlocyrilliccmb",
+ category="mn",
+ contextname="cyrillicTITLO",
+ description="COMBINING CYRILLIC TITLO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0483,
+ },
+ [0x0484]={
+ adobename="palatalizationcyrilliccmb",
+ category="mn",
+ contextname="cyrillicPALATALIZATION",
+ description="COMBINING CYRILLIC PALATALIZATION",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0484,
+ },
+ [0x0485]={
+ adobename="dasiapneumatacyrilliccmb",
+ category="mn",
+ contextname="cyrillicDASIAPNEUMATA",
+ description="COMBINING CYRILLIC DASIA PNEUMATA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0485,
+ },
+ [0x0486]={
+ adobename="psilipneumatacyrilliccmb",
+ category="mn",
+ contextname="cyrillicPSILIPNEUMATA",
+ description="COMBINING CYRILLIC PSILI PNEUMATA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0486,
+ },
+ [0x0487]={
+ category="mn",
+ description="COMBINING CYRILLIC POKRYTIE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0487,
+ },
+ [0x0488]={
+ category="me",
+ description="COMBINING CYRILLIC HUNDRED THOUSANDS SIGN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0488,
+ },
+ [0x0489]={
+ category="me",
+ description="COMBINING CYRILLIC MILLIONS SIGN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0489,
+ },
+ [0x048A]={
+ category="lu",
+ contextname="cyrillicISHRTtail",
+ description="CYRILLIC CAPITAL LETTER SHORT I WITH TAIL",
+ direction="l",
+ lccode=0x048B,
+ linebreak="al",
+ unicodeslot=0x048A,
+ },
+ [0x048B]={
+ category="ll",
+ contextname="cyrillicishrttail",
+ description="CYRILLIC SMALL LETTER SHORT I WITH TAIL",
+ direction="l",
+ linebreak="al",
+ uccode=0x048A,
+ unicodeslot=0x048B,
+ },
+ [0x048C]={
+ category="lu",
+ contextname="cyrillicSEMISOFT",
+ description="CYRILLIC CAPITAL LETTER SEMISOFT SIGN",
+ direction="l",
+ lccode=0x048D,
+ linebreak="al",
+ unicodeslot=0x048C,
+ },
+ [0x048D]={
+ category="ll",
+ contextname="cyrillicsemisoft",
+ description="CYRILLIC SMALL LETTER SEMISOFT SIGN",
+ direction="l",
+ linebreak="al",
+ uccode=0x048C,
+ unicodeslot=0x048D,
+ },
+ [0x048E]={
+ category="lu",
+ contextname="cyrillicERtick",
+ description="CYRILLIC CAPITAL LETTER ER WITH TICK",
+ direction="l",
+ lccode=0x048F,
+ linebreak="al",
+ shcode=0x0420,
+ unicodeslot=0x048E,
+ },
+ [0x048F]={
+ category="ll",
+ contextname="cyrillicertick",
+ description="CYRILLIC SMALL LETTER ER WITH TICK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0440,
+ uccode=0x048E,
+ unicodeslot=0x048F,
+ },
+ [0x0490]={
+ adobename="afii10050",
+ category="lu",
+ contextname="cyrillicGHEupturn",
+ description="CYRILLIC CAPITAL LETTER GHE WITH UPTURN",
+ direction="l",
+ lccode=0x0491,
+ linebreak="al",
+ shcode=0x0413,
+ unicodeslot=0x0490,
+ },
+ [0x0491]={
+ adobename="gheupturncyrillic",
+ category="ll",
+ contextname="cyrillicgheupturn",
+ description="CYRILLIC SMALL LETTER GHE WITH UPTURN",
+ direction="l",
+ linebreak="al",
+ shcode=0x0433,
+ uccode=0x0490,
+ unicodeslot=0x0491,
+ },
+ [0x0492]={
+ adobename="Ghestrokecyrillic",
+ category="lu",
+ contextname="cyrillicGHEstroke",
+ description="CYRILLIC CAPITAL LETTER GHE WITH STROKE",
+ direction="l",
+ lccode=0x0493,
+ linebreak="al",
+ shcode=0x0413,
+ unicodeslot=0x0492,
+ },
+ [0x0493]={
+ adobename="ghestrokecyrillic",
+ category="ll",
+ contextname="cyrillicghestroke",
+ description="CYRILLIC SMALL LETTER GHE WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0433,
+ uccode=0x0492,
+ unicodeslot=0x0493,
+ },
+ [0x0494]={
+ adobename="Ghemiddlehookcyrillic",
+ category="lu",
+ contextname="cyrillicGHEmidhook",
+ description="CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK",
+ direction="l",
+ lccode=0x0495,
+ linebreak="al",
+ shcode=0x0413,
+ unicodeslot=0x0494,
+ },
+ [0x0495]={
+ adobename="ghemiddlehookcyrillic",
+ category="ll",
+ contextname="cyrillicghemidhook",
+ description="CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0433,
+ uccode=0x0494,
+ unicodeslot=0x0495,
+ },
+ [0x0496]={
+ adobename="Zhedescendercyrillic",
+ category="lu",
+ contextname="cyrillicZHEdescender",
+ description="CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER",
+ direction="l",
+ lccode=0x0497,
+ linebreak="al",
+ shcode=0x0416,
+ unicodeslot=0x0496,
+ },
+ [0x0497]={
+ adobename="zhedescendercyrillic",
+ category="ll",
+ contextname="cyrilliczhedescender",
+ description="CYRILLIC SMALL LETTER ZHE WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ shcode=0x0436,
+ uccode=0x0496,
+ unicodeslot=0x0497,
+ },
+ [0x0498]={
+ adobename="Zedescendercyrillic",
+ category="lu",
+ contextname="cyrillicZDSC",
+ description="CYRILLIC CAPITAL LETTER ZE WITH DESCENDER",
+ direction="l",
+ lccode=0x0499,
+ linebreak="al",
+ shcode=0x0417,
+ unicodeslot=0x0498,
+ },
+ [0x0499]={
+ adobename="zedescendercyrillic",
+ category="ll",
+ contextname="cyrilliczdsc",
+ description="CYRILLIC SMALL LETTER ZE WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ shcode=0x0437,
+ uccode=0x0498,
+ unicodeslot=0x0499,
+ },
+ [0x049A]={
+ adobename="Kadescendercyrillic",
+ category="lu",
+ contextname="cyrillicKADC",
+ description="CYRILLIC CAPITAL LETTER KA WITH DESCENDER",
+ direction="l",
+ lccode=0x049B,
+ linebreak="al",
+ shcode=0x041A,
+ unicodeslot=0x049A,
+ },
+ [0x049B]={
+ adobename="kadescendercyrillic",
+ category="ll",
+ contextname="cyrillickadc",
+ description="CYRILLIC SMALL LETTER KA WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ shcode=0x043A,
+ uccode=0x049A,
+ unicodeslot=0x049B,
+ },
+ [0x049C]={
+ adobename="Kaverticalstrokecyrillic",
+ category="lu",
+ contextname="cyrillicKAvertstroke",
+ description="CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE",
+ direction="l",
+ lccode=0x049D,
+ linebreak="al",
+ shcode=0x041A,
+ unicodeslot=0x049C,
+ },
+ [0x049D]={
+ adobename="kaverticalstrokecyrillic",
+ category="ll",
+ contextname="cyrillickavertstroke",
+ description="CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x043A,
+ uccode=0x049C,
+ unicodeslot=0x049D,
+ },
+ [0x049E]={
+ adobename="Kastrokecyrillic",
+ category="lu",
+ contextname="cyrillicKAstroke",
+ description="CYRILLIC CAPITAL LETTER KA WITH STROKE",
+ direction="l",
+ lccode=0x049F,
+ linebreak="al",
+ shcode=0x041A,
+ unicodeslot=0x049E,
+ },
+ [0x049F]={
+ adobename="kastrokecyrillic",
+ category="ll",
+ contextname="cyrillickastroke",
+ description="CYRILLIC SMALL LETTER KA WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x043A,
+ uccode=0x049E,
+ unicodeslot=0x049F,
+ },
+ [0x04A0]={
+ adobename="Kabashkircyrillic",
+ category="lu",
+ contextname="cyrillicKAbashkir",
+ description="CYRILLIC CAPITAL LETTER BASHKIR KA",
+ direction="l",
+ lccode=0x04A1,
+ linebreak="al",
+ unicodeslot=0x04A0,
+ },
+ [0x04A1]={
+ adobename="kabashkircyrillic",
+ category="ll",
+ contextname="cyrillickabashkir",
+ description="CYRILLIC SMALL LETTER BASHKIR KA",
+ direction="l",
+ linebreak="al",
+ uccode=0x04A0,
+ unicodeslot=0x04A1,
+ },
+ [0x04A2]={
+ adobename="Endescendercyrillic",
+ category="lu",
+ contextname="cyrillicENDC",
+ description="CYRILLIC CAPITAL LETTER EN WITH DESCENDER",
+ direction="l",
+ lccode=0x04A3,
+ linebreak="al",
+ shcode=0x041D,
+ unicodeslot=0x04A2,
+ },
+ [0x04A3]={
+ adobename="endescendercyrillic",
+ category="ll",
+ contextname="cyrillicendc",
+ description="CYRILLIC SMALL LETTER EN WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ shcode=0x043D,
+ uccode=0x04A2,
+ unicodeslot=0x04A3,
+ },
+ [0x04A4]={
+ adobename="Enghecyrillic",
+ category="lu",
+ contextname="cyrillicENGHE",
+ description="CYRILLIC CAPITAL LIGATURE EN GHE",
+ direction="l",
+ lccode=0x04A5,
+ linebreak="al",
+ unicodeslot=0x04A4,
+ },
+ [0x04A5]={
+ adobename="enghecyrillic",
+ category="ll",
+ contextname="cyrillicenghe",
+ description="CYRILLIC SMALL LIGATURE EN GHE",
+ direction="l",
+ linebreak="al",
+ uccode=0x04A4,
+ unicodeslot=0x04A5,
+ },
+ [0x04A6]={
+ adobename="Pemiddlehookcyrillic",
+ category="lu",
+ contextname="cyrillicPEmidhook",
+ description="CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK",
+ direction="l",
+ lccode=0x04A7,
+ linebreak="al",
+ shcode=0x041F,
+ unicodeslot=0x04A6,
+ },
+ [0x04A7]={
+ adobename="pemiddlehookcyrillic",
+ category="ll",
+ contextname="cyrillicpemidhook",
+ description="CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x043F,
+ uccode=0x04A6,
+ unicodeslot=0x04A7,
+ },
+ [0x04A8]={
+ adobename="Haabkhasiancyrillic",
+ category="lu",
+ contextname="cyrillicHA",
+ description="CYRILLIC CAPITAL LETTER ABKHASIAN HA",
+ direction="l",
+ lccode=0x04A9,
+ linebreak="al",
+ unicodeslot=0x04A8,
+ },
+ [0x04A9]={
+ adobename="haabkhasiancyrillic",
+ category="ll",
+ contextname="cyrillicha",
+ description="CYRILLIC SMALL LETTER ABKHASIAN HA",
+ direction="l",
+ linebreak="al",
+ uccode=0x04A8,
+ unicodeslot=0x04A9,
+ },
+ [0x04AA]={
+ adobename="Esdescendercyrillic",
+ category="lu",
+ contextname="cyrillicSDSC",
+ description="CYRILLIC CAPITAL LETTER ES WITH DESCENDER",
+ direction="l",
+ lccode=0x04AB,
+ linebreak="al",
+ shcode=0x0421,
+ unicodeslot=0x04AA,
+ },
+ [0x04AB]={
+ adobename="esdescendercyrillic",
+ category="ll",
+ contextname="cyrillicsdsc",
+ description="CYRILLIC SMALL LETTER ES WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ shcode=0x0441,
+ uccode=0x04AA,
+ unicodeslot=0x04AB,
+ },
+ [0x04AC]={
+ adobename="Tedescendercyrillic",
+ category="lu",
+ contextname="cyrillicTEDC",
+ description="CYRILLIC CAPITAL LETTER TE WITH DESCENDER",
+ direction="l",
+ lccode=0x04AD,
+ linebreak="al",
+ shcode=0x0422,
+ unicodeslot=0x04AC,
+ },
+ [0x04AD]={
+ adobename="tedescendercyrillic",
+ category="ll",
+ contextname="cyrillictedc",
+ description="CYRILLIC SMALL LETTER TE WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ shcode=0x0442,
+ uccode=0x04AC,
+ unicodeslot=0x04AD,
+ },
+ [0x04AE]={
+ adobename="Ustraightcyrillic",
+ category="lu",
+ contextname="cyrillicYstr",
+ description="CYRILLIC CAPITAL LETTER STRAIGHT U",
+ direction="l",
+ lccode=0x04AF,
+ linebreak="al",
+ unicodeslot=0x04AE,
+ },
+ [0x04AF]={
+ adobename="ustraightcyrillic",
+ category="ll",
+ contextname="cyrillicystr",
+ description="CYRILLIC SMALL LETTER STRAIGHT U",
+ direction="l",
+ linebreak="al",
+ uccode=0x04AE,
+ unicodeslot=0x04AF,
+ },
+ [0x04B0]={
+ adobename="Ustraightstrokecyrillic",
+ category="lu",
+ contextname="cyrillicYstrstroke",
+ description="CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE",
+ direction="l",
+ lccode=0x04B1,
+ linebreak="al",
+ unicodeslot=0x04B0,
+ },
+ [0x04B1]={
+ adobename="ustraightstrokecyrillic",
+ category="ll",
+ contextname="cyrillicystrstroke",
+ description="CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE",
+ direction="l",
+ linebreak="al",
+ uccode=0x04B0,
+ unicodeslot=0x04B1,
+ },
+ [0x04B2]={
+ adobename="Hadescendercyrillic",
+ category="lu",
+ contextname="cyrillicHADC",
+ description="CYRILLIC CAPITAL LETTER HA WITH DESCENDER",
+ direction="l",
+ lccode=0x04B3,
+ linebreak="al",
+ shcode=0x0425,
+ unicodeslot=0x04B2,
+ },
+ [0x04B3]={
+ adobename="hadescendercyrillic",
+ category="ll",
+ contextname="cyrillichadc",
+ description="CYRILLIC SMALL LETTER HA WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ shcode=0x0445,
+ uccode=0x04B2,
+ unicodeslot=0x04B3,
+ },
+ [0x04B4]={
+ adobename="Tetsecyrillic",
+ category="lu",
+ contextname="cyrillicTETSE",
+ description="CYRILLIC CAPITAL LIGATURE TE TSE",
+ direction="l",
+ lccode=0x04B5,
+ linebreak="al",
+ unicodeslot=0x04B4,
+ },
+ [0x04B5]={
+ adobename="tetsecyrillic",
+ category="ll",
+ contextname="cyrillictetse",
+ description="CYRILLIC SMALL LIGATURE TE TSE",
+ direction="l",
+ linebreak="al",
+ uccode=0x04B4,
+ unicodeslot=0x04B5,
+ },
+ [0x04B6]={
+ adobename="Chedescendercyrillic",
+ category="lu",
+ contextname="cyrillicCHEDC",
+ description="CYRILLIC CAPITAL LETTER CHE WITH DESCENDER",
+ direction="l",
+ lccode=0x04B7,
+ linebreak="al",
+ shcode=0x0427,
+ unicodeslot=0x04B6,
+ },
+ [0x04B7]={
+ adobename="chedescendercyrillic",
+ category="ll",
+ contextname="cyrillicchedc",
+ description="CYRILLIC SMALL LETTER CHE WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ shcode=0x0447,
+ uccode=0x04B6,
+ unicodeslot=0x04B7,
+ },
+ [0x04B8]={
+ adobename="Cheverticalstrokecyrillic",
+ category="lu",
+ contextname="cyrillicCHEvertstroke",
+ description="CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE",
+ direction="l",
+ lccode=0x04B9,
+ linebreak="al",
+ shcode=0x0427,
+ unicodeslot=0x04B8,
+ },
+ [0x04B9]={
+ adobename="cheverticalstrokecyrillic",
+ category="ll",
+ contextname="cyrillicchevertstroke",
+ description="CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0447,
+ uccode=0x04B8,
+ unicodeslot=0x04B9,
+ },
+ [0x04BA]={
+ adobename="Shhacyrillic",
+ category="lu",
+ contextname="cyrillicSHHA",
+ description="CYRILLIC CAPITAL LETTER SHHA",
+ direction="l",
+ lccode=0x04BB,
+ linebreak="al",
+ unicodeslot=0x04BA,
+ },
+ [0x04BB]={
+ adobename="shhacyrillic",
+ category="ll",
+ contextname="cyrillicshha",
+ description="CYRILLIC SMALL LETTER SHHA",
+ direction="l",
+ linebreak="al",
+ uccode=0x04BA,
+ unicodeslot=0x04BB,
+ },
+ [0x04BC]={
+ adobename="Cheabkhasiancyrillic",
+ category="lu",
+ contextname="cyrillicCHEabkhasian",
+ description="CYRILLIC CAPITAL LETTER ABKHASIAN CHE",
+ direction="l",
+ lccode=0x04BD,
+ linebreak="al",
+ unicodeslot=0x04BC,
+ },
+ [0x04BD]={
+ adobename="cheabkhasiancyrillic",
+ category="ll",
+ contextname="cyrilliccheabkhasian",
+ description="CYRILLIC SMALL LETTER ABKHASIAN CHE",
+ direction="l",
+ linebreak="al",
+ uccode=0x04BC,
+ unicodeslot=0x04BD,
+ },
+ [0x04BE]={
+ adobename="Chedescenderabkhasiancyrillic",
+ category="lu",
+ contextname="cyrillicCHEDCabkhasian",
+ description="CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER",
+ direction="l",
+ lccode=0x04BF,
+ linebreak="al",
+ unicodeslot=0x04BE,
+ },
+ [0x04BF]={
+ adobename="chedescenderabkhasiancyrillic",
+ category="ll",
+ contextname="cyrillicchedcabkhasian",
+ description="CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ uccode=0x04BE,
+ unicodeslot=0x04BF,
+ },
+ [0x04C0]={
+ adobename="palochkacyrillic",
+ category="lu",
+ contextname="cyrillicPALOCHKA",
+ description="CYRILLIC LETTER PALOCHKA",
+ direction="l",
+ lccode=0x04CF,
+ linebreak="al",
+ unicodeslot=0x04C0,
+ },
+ [0x04C1]={
+ adobename="Zhebrevecyrillic",
+ category="lu",
+ contextname="cyrillicZHEbreve",
+ description="CYRILLIC CAPITAL LETTER ZHE WITH BREVE",
+ direction="l",
+ lccode=0x04C2,
+ linebreak="al",
+ shcode=0x0416,
+ specials={ "char", 0x0416, 0x0306 },
+ unicodeslot=0x04C1,
+ },
+ [0x04C2]={
+ adobename="zhebrevecyrillic",
+ category="ll",
+ contextname="cyrilliczhebreve",
+ description="CYRILLIC SMALL LETTER ZHE WITH BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0436,
+ specials={ "char", 0x0436, 0x0306 },
+ uccode=0x04C1,
+ unicodeslot=0x04C2,
+ },
+ [0x04C3]={
+ adobename="Kahookcyrillic",
+ category="lu",
+ contextname="cyrillicKAhook",
+ description="CYRILLIC CAPITAL LETTER KA WITH HOOK",
+ direction="l",
+ lccode=0x04C4,
+ linebreak="al",
+ shcode=0x041A,
+ unicodeslot=0x04C3,
+ },
+ [0x04C4]={
+ adobename="kahookcyrillic",
+ category="ll",
+ contextname="cyrillickahook",
+ description="CYRILLIC SMALL LETTER KA WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x043A,
+ uccode=0x04C3,
+ unicodeslot=0x04C4,
+ },
+ [0x04C5]={
+ category="lu",
+ contextname="cyrillicELtail",
+ description="CYRILLIC CAPITAL LETTER EL WITH TAIL",
+ direction="l",
+ lccode=0x04C6,
+ linebreak="al",
+ shcode=0x041B,
+ unicodeslot=0x04C5,
+ },
+ [0x04C6]={
+ category="ll",
+ contextname="cyrilliceltail",
+ description="CYRILLIC SMALL LETTER EL WITH TAIL",
+ direction="l",
+ linebreak="al",
+ shcode=0x043B,
+ uccode=0x04C5,
+ unicodeslot=0x04C6,
+ },
+ [0x04C7]={
+ adobename="Enhookcyrillic",
+ category="lu",
+ contextname="cyrillicENhook",
+ description="CYRILLIC CAPITAL LETTER EN WITH HOOK",
+ direction="l",
+ lccode=0x04C8,
+ linebreak="al",
+ shcode=0x041D,
+ unicodeslot=0x04C7,
+ },
+ [0x04C8]={
+ adobename="enhookcyrillic",
+ category="ll",
+ contextname="cyrillicenhook",
+ description="CYRILLIC SMALL LETTER EN WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x043D,
+ uccode=0x04C7,
+ unicodeslot=0x04C8,
+ },
+ [0x04C9]={
+ category="lu",
+ contextname="cyrillicENtail",
+ description="CYRILLIC CAPITAL LETTER EN WITH TAIL",
+ direction="l",
+ lccode=0x04CA,
+ linebreak="al",
+ shcode=0x041D,
+ unicodeslot=0x04C9,
+ },
+ [0x04CA]={
+ category="ll",
+ contextname="cyrillicentail",
+ description="CYRILLIC SMALL LETTER EN WITH TAIL",
+ direction="l",
+ linebreak="al",
+ shcode=0x043D,
+ uccode=0x04C9,
+ unicodeslot=0x04CA,
+ },
+ [0x04CB]={
+ adobename="Chekhakassiancyrillic",
+ category="lu",
+ contextname="cyrillicCHEkhakassian",
+ description="CYRILLIC CAPITAL LETTER KHAKASSIAN CHE",
+ direction="l",
+ lccode=0x04CC,
+ linebreak="al",
+ unicodeslot=0x04CB,
+ },
+ [0x04CC]={
+ adobename="chekhakassiancyrillic",
+ category="ll",
+ contextname="cyrillicchekhakassian",
+ description="CYRILLIC SMALL LETTER KHAKASSIAN CHE",
+ direction="l",
+ linebreak="al",
+ uccode=0x04CB,
+ unicodeslot=0x04CC,
+ },
+ [0x04CD]={
+ category="lu",
+ contextname="cyrillicEMtail",
+ description="CYRILLIC CAPITAL LETTER EM WITH TAIL",
+ direction="l",
+ lccode=0x04CE,
+ linebreak="al",
+ shcode=0x041C,
+ unicodeslot=0x04CD,
+ },
+ [0x04CE]={
+ category="ll",
+ contextname="cyrillicemtail",
+ description="CYRILLIC SMALL LETTER EM WITH TAIL",
+ direction="l",
+ linebreak="al",
+ shcode=0x043C,
+ uccode=0x04CD,
+ unicodeslot=0x04CE,
+ },
+ [0x04CF]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER PALOCHKA",
+ direction="l",
+ linebreak="al",
+ uccode=0x04C0,
+ unicodeslot=0x04CF,
+ },
+ [0x04D0]={
+ adobename="Abrevecyrillic",
+ category="lu",
+ contextname="cyrillicAbreve",
+ description="CYRILLIC CAPITAL LETTER A WITH BREVE",
+ direction="l",
+ lccode=0x04D1,
+ linebreak="al",
+ shcode=0x0410,
+ specials={ "char", 0x0410, 0x0306 },
+ unicodeslot=0x04D0,
+ },
+ [0x04D1]={
+ adobename="abrevecyrillic",
+ category="ll",
+ contextname="cyrillicabreve",
+ description="CYRILLIC SMALL LETTER A WITH BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0430,
+ specials={ "char", 0x0430, 0x0306 },
+ uccode=0x04D0,
+ unicodeslot=0x04D1,
+ },
+ [0x04D2]={
+ adobename="Adieresiscyrillic",
+ category="lu",
+ contextname="cyrillicAdiaeresis",
+ description="CYRILLIC CAPITAL LETTER A WITH DIAERESIS",
+ direction="l",
+ lccode=0x04D3,
+ linebreak="al",
+ shcode=0x0410,
+ specials={ "char", 0x0410, 0x0308 },
+ unicodeslot=0x04D2,
+ },
+ [0x04D3]={
+ adobename="adieresiscyrillic",
+ category="ll",
+ contextname="cyrillicadiaeresis",
+ description="CYRILLIC SMALL LETTER A WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0430,
+ specials={ "char", 0x0430, 0x0308 },
+ uccode=0x04D2,
+ unicodeslot=0x04D3,
+ },
+ [0x04D4]={
+ adobename="Aiecyrillic",
+ category="lu",
+ contextname="cyrillicAE",
+ description="CYRILLIC CAPITAL LIGATURE A IE",
+ direction="l",
+ lccode=0x04D5,
+ linebreak="al",
+ unicodeslot=0x04D4,
+ },
+ [0x04D5]={
+ adobename="aiecyrillic",
+ category="ll",
+ contextname="cyrillicae",
+ description="CYRILLIC SMALL LIGATURE A IE",
+ direction="l",
+ linebreak="al",
+ uccode=0x04D4,
+ unicodeslot=0x04D5,
+ },
+ [0x04D6]={
+ adobename="Iebrevecyrillic",
+ category="lu",
+ contextname="cyrillicEbreve",
+ description="CYRILLIC CAPITAL LETTER IE WITH BREVE",
+ direction="l",
+ lccode=0x04D7,
+ linebreak="al",
+ shcode=0x0415,
+ specials={ "char", 0x0415, 0x0306 },
+ unicodeslot=0x04D6,
+ },
+ [0x04D7]={
+ adobename="iebrevecyrillic",
+ category="ll",
+ contextname="cyrillicebreve",
+ description="CYRILLIC SMALL LETTER IE WITH BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0435,
+ specials={ "char", 0x0435, 0x0306 },
+ uccode=0x04D6,
+ unicodeslot=0x04D7,
+ },
+ [0x04D8]={
+ adobename="Schwacyrillic",
+ category="lu",
+ contextname="cyrillicSCHWA",
+ description="CYRILLIC CAPITAL LETTER SCHWA",
+ direction="l",
+ lccode=0x04D9,
+ linebreak="al",
+ unicodeslot=0x04D8,
+ },
+ [0x04D9]={
+ adobename="schwacyrillic",
+ category="ll",
+ contextname="cyrillicschwa",
+ description="CYRILLIC SMALL LETTER SCHWA",
+ direction="l",
+ linebreak="al",
+ uccode=0x04D8,
+ unicodeslot=0x04D9,
+ },
+ [0x04DA]={
+ adobename="Schwadieresiscyrillic",
+ category="lu",
+ contextname="cyrillicSCHWAdiaeresis",
+ description="CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS",
+ direction="l",
+ lccode=0x04DB,
+ linebreak="al",
+ shcode=0x04D8,
+ specials={ "char", 0x04D8, 0x0308 },
+ unicodeslot=0x04DA,
+ },
+ [0x04DB]={
+ adobename="schwadieresiscyrillic",
+ category="ll",
+ contextname="cyrillicschwadiaeresis",
+ description="CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x04D9,
+ specials={ "char", 0x04D9, 0x0308 },
+ uccode=0x04DA,
+ unicodeslot=0x04DB,
+ },
+ [0x04DC]={
+ adobename="Zhedieresiscyrillic",
+ category="lu",
+ contextname="cyrillicZHEdiaeresis",
+ description="CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS",
+ direction="l",
+ lccode=0x04DD,
+ linebreak="al",
+ shcode=0x0416,
+ specials={ "char", 0x0416, 0x0308 },
+ unicodeslot=0x04DC,
+ },
+ [0x04DD]={
+ adobename="zhedieresiscyrillic",
+ category="ll",
+ contextname="cyrilliczhediaeresis",
+ description="CYRILLIC SMALL LETTER ZHE WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0436,
+ specials={ "char", 0x0436, 0x0308 },
+ uccode=0x04DC,
+ unicodeslot=0x04DD,
+ },
+ [0x04DE]={
+ adobename="Zedieresiscyrillic",
+ category="lu",
+ contextname="cyrillicZEdiaeresis",
+ description="CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS",
+ direction="l",
+ lccode=0x04DF,
+ linebreak="al",
+ shcode=0x0417,
+ specials={ "char", 0x0417, 0x0308 },
+ unicodeslot=0x04DE,
+ },
+ [0x04DF]={
+ adobename="zedieresiscyrillic",
+ category="ll",
+ contextname="cyrilliczediaeresis",
+ description="CYRILLIC SMALL LETTER ZE WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0437,
+ specials={ "char", 0x0437, 0x0308 },
+ uccode=0x04DE,
+ unicodeslot=0x04DF,
+ },
+ [0x04E0]={
+ adobename="Dzeabkhasiancyrillic",
+ category="lu",
+ contextname="cyrillicDZEabkhasian",
+ description="CYRILLIC CAPITAL LETTER ABKHASIAN DZE",
+ direction="l",
+ lccode=0x04E1,
+ linebreak="al",
+ unicodeslot=0x04E0,
+ },
+ [0x04E1]={
+ adobename="dzeabkhasiancyrillic",
+ category="ll",
+ contextname="cyrillicdzeabkhasian",
+ description="CYRILLIC SMALL LETTER ABKHASIAN DZE",
+ direction="l",
+ linebreak="al",
+ uccode=0x04E0,
+ unicodeslot=0x04E1,
+ },
+ [0x04E2]={
+ adobename="Imacroncyrillic",
+ category="lu",
+ contextname="cyrillicImacron",
+ description="CYRILLIC CAPITAL LETTER I WITH MACRON",
+ direction="l",
+ lccode=0x04E3,
+ linebreak="al",
+ shcode=0x0418,
+ specials={ "char", 0x0418, 0x0304 },
+ unicodeslot=0x04E2,
+ },
+ [0x04E3]={
+ adobename="imacroncyrillic",
+ category="ll",
+ contextname="cyrillicimacron",
+ description="CYRILLIC SMALL LETTER I WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0438,
+ specials={ "char", 0x0438, 0x0304 },
+ uccode=0x04E2,
+ unicodeslot=0x04E3,
+ },
+ [0x04E4]={
+ adobename="Idieresiscyrillic",
+ category="lu",
+ contextname="cyrillicIdiaeresis",
+ description="CYRILLIC CAPITAL LETTER I WITH DIAERESIS",
+ direction="l",
+ lccode=0x04E5,
+ linebreak="al",
+ shcode=0x0418,
+ specials={ "char", 0x0418, 0x0308 },
+ unicodeslot=0x04E4,
+ },
+ [0x04E5]={
+ adobename="idieresiscyrillic",
+ category="ll",
+ contextname="cyrillicidiaeresis",
+ description="CYRILLIC SMALL LETTER I WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0438,
+ specials={ "char", 0x0438, 0x0308 },
+ uccode=0x04E4,
+ unicodeslot=0x04E5,
+ },
+ [0x04E6]={
+ adobename="Odieresiscyrillic",
+ category="lu",
+ contextname="cyrillicOdiaeresis",
+ description="CYRILLIC CAPITAL LETTER O WITH DIAERESIS",
+ direction="l",
+ lccode=0x04E7,
+ linebreak="al",
+ shcode=0x041E,
+ specials={ "char", 0x041E, 0x0308 },
+ unicodeslot=0x04E6,
+ },
+ [0x04E7]={
+ adobename="odieresiscyrillic",
+ category="ll",
+ contextname="cyrillicodiaeresis",
+ description="CYRILLIC SMALL LETTER O WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x043E,
+ specials={ "char", 0x043E, 0x0308 },
+ uccode=0x04E6,
+ unicodeslot=0x04E7,
+ },
+ [0x04E8]={
+ adobename="Obarredcyrillic",
+ category="lu",
+ contextname="cyrillicObarred",
+ description="CYRILLIC CAPITAL LETTER BARRED O",
+ direction="l",
+ lccode=0x04E9,
+ linebreak="al",
+ unicodeslot=0x04E8,
+ },
+ [0x04E9]={
+ adobename="obarredcyrillic",
+ category="ll",
+ contextname="cyrillicobarred",
+ description="CYRILLIC SMALL LETTER BARRED O",
+ direction="l",
+ linebreak="al",
+ uccode=0x04E8,
+ unicodeslot=0x04E9,
+ },
+ [0x04EA]={
+ adobename="Obarreddieresiscyrillic",
+ category="lu",
+ contextname="cyrillicObarreddiaeresis",
+ description="CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS",
+ direction="l",
+ lccode=0x04EB,
+ linebreak="al",
+ specials={ "char", 0x04E8, 0x0308 },
+ unicodeslot=0x04EA,
+ },
+ [0x04EB]={
+ adobename="obarreddieresiscyrillic",
+ category="ll",
+ contextname="cyrillicobarreddiaeresis",
+ description="CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x04E9, 0x0308 },
+ uccode=0x04EA,
+ unicodeslot=0x04EB,
+ },
+ [0x04EC]={
+ category="lu",
+ contextname="cyrillicEdiaeresis",
+ description="CYRILLIC CAPITAL LETTER E WITH DIAERESIS",
+ direction="l",
+ lccode=0x04ED,
+ linebreak="al",
+ shcode=0x042D,
+ specials={ "char", 0x042D, 0x0308 },
+ unicodeslot=0x04EC,
+ },
+ [0x04ED]={
+ category="ll",
+ contextname="cyrillicediaeresis",
+ description="CYRILLIC SMALL LETTER E WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x044D,
+ specials={ "char", 0x044D, 0x0308 },
+ uccode=0x04EC,
+ unicodeslot=0x04ED,
+ },
+ [0x04EE]={
+ adobename="Umacroncyrillic",
+ category="lu",
+ contextname="cyrillicUmacron",
+ description="CYRILLIC CAPITAL LETTER U WITH MACRON",
+ direction="l",
+ lccode=0x04EF,
+ linebreak="al",
+ shcode=0x0423,
+ specials={ "char", 0x0423, 0x0304 },
+ unicodeslot=0x04EE,
+ },
+ [0x04EF]={
+ adobename="umacroncyrillic",
+ category="ll",
+ contextname="cyrillicumacron",
+ description="CYRILLIC SMALL LETTER U WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0443,
+ specials={ "char", 0x0443, 0x0304 },
+ uccode=0x04EE,
+ unicodeslot=0x04EF,
+ },
+ [0x04F0]={
+ adobename="Udieresiscyrillic",
+ category="lu",
+ contextname="cyrillicUdiaeresis",
+ description="CYRILLIC CAPITAL LETTER U WITH DIAERESIS",
+ direction="l",
+ lccode=0x04F1,
+ linebreak="al",
+ shcode=0x0423,
+ specials={ "char", 0x0423, 0x0308 },
+ unicodeslot=0x04F0,
+ },
+ [0x04F1]={
+ adobename="udieresiscyrillic",
+ category="ll",
+ contextname="cyrillicudiaeresis",
+ description="CYRILLIC SMALL LETTER U WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0443,
+ specials={ "char", 0x0443, 0x0308 },
+ uccode=0x04F0,
+ unicodeslot=0x04F1,
+ },
+ [0x04F2]={
+ adobename="Uhungarumlautcyrillic",
+ category="lu",
+ contextname="cyrillicUdoubleacute",
+ description="CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE",
+ direction="l",
+ lccode=0x04F3,
+ linebreak="al",
+ shcode=0x0423,
+ specials={ "char", 0x0423, 0x030B },
+ unicodeslot=0x04F2,
+ },
+ [0x04F3]={
+ adobename="uhungarumlautcyrillic",
+ category="ll",
+ contextname="cyrillicudoubleacute",
+ description="CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0443,
+ specials={ "char", 0x0443, 0x030B },
+ uccode=0x04F2,
+ unicodeslot=0x04F3,
+ },
+ [0x04F4]={
+ adobename="Chedieresiscyrillic",
+ category="lu",
+ contextname="cyrillicCHEdiaeresis",
+ description="CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS",
+ direction="l",
+ lccode=0x04F5,
+ linebreak="al",
+ shcode=0x0427,
+ specials={ "char", 0x0427, 0x0308 },
+ unicodeslot=0x04F4,
+ },
+ [0x04F5]={
+ adobename="chedieresiscyrillic",
+ category="ll",
+ contextname="cyrillicchediaeresis",
+ description="CYRILLIC SMALL LETTER CHE WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0447,
+ specials={ "char", 0x0447, 0x0308 },
+ uccode=0x04F4,
+ unicodeslot=0x04F5,
+ },
+ [0x04F6]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER GHE WITH DESCENDER",
+ direction="l",
+ lccode=0x04F7,
+ linebreak="al",
+ shcode=0x0413,
+ unicodeslot=0x04F6,
+ },
+ [0x04F7]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER GHE WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ shcode=0x0433,
+ uccode=0x04F6,
+ unicodeslot=0x04F7,
+ },
+ [0x04F8]={
+ adobename="Yerudieresiscyrillic",
+ category="lu",
+ contextname="cyrillicYERUdiaeresis",
+ description="CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS",
+ direction="l",
+ lccode=0x04F9,
+ linebreak="al",
+ shcode=0x042B,
+ specials={ "char", 0x042B, 0x0308 },
+ unicodeslot=0x04F8,
+ },
+ [0x04F9]={
+ adobename="yerudieresiscyrillic",
+ category="ll",
+ contextname="cyrillicyerudiaeresis",
+ description="CYRILLIC SMALL LETTER YERU WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x044B,
+ specials={ "char", 0x044B, 0x0308 },
+ uccode=0x04F8,
+ unicodeslot=0x04F9,
+ },
+ [0x04FA]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK",
+ direction="l",
+ lccode=0x04FB,
+ linebreak="al",
+ shcode=0x0413,
+ unicodeslot=0x04FA,
+ },
+ [0x04FB]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0433,
+ uccode=0x04FA,
+ unicodeslot=0x04FB,
+ },
+ [0x04FC]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER HA WITH HOOK",
+ direction="l",
+ lccode=0x04FD,
+ linebreak="al",
+ shcode=0x0425,
+ unicodeslot=0x04FC,
+ },
+ [0x04FD]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER HA WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0445,
+ uccode=0x04FC,
+ unicodeslot=0x04FD,
+ },
+ [0x04FE]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER HA WITH STROKE",
+ direction="l",
+ lccode=0x04FF,
+ linebreak="al",
+ shcode=0x0425,
+ unicodeslot=0x04FE,
+ },
+ [0x04FF]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER HA WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0445,
+ uccode=0x04FE,
+ unicodeslot=0x04FF,
+ },
+ [0x0500]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER KOMI DE",
+ direction="l",
+ lccode=0x0501,
+ linebreak="al",
+ unicodeslot=0x0500,
+ },
+ [0x0501]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER KOMI DE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0500,
+ unicodeslot=0x0501,
+ },
+ [0x0502]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER KOMI DJE",
+ direction="l",
+ lccode=0x0503,
+ linebreak="al",
+ unicodeslot=0x0502,
+ },
+ [0x0503]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER KOMI DJE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0502,
+ unicodeslot=0x0503,
+ },
+ [0x0504]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER KOMI ZJE",
+ direction="l",
+ lccode=0x0505,
+ linebreak="al",
+ unicodeslot=0x0504,
+ },
+ [0x0505]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER KOMI ZJE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0504,
+ unicodeslot=0x0505,
+ },
+ [0x0506]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER KOMI DZJE",
+ direction="l",
+ lccode=0x0507,
+ linebreak="al",
+ unicodeslot=0x0506,
+ },
+ [0x0507]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER KOMI DZJE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0506,
+ unicodeslot=0x0507,
+ },
+ [0x0508]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER KOMI LJE",
+ direction="l",
+ lccode=0x0509,
+ linebreak="al",
+ unicodeslot=0x0508,
+ },
+ [0x0509]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER KOMI LJE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0508,
+ unicodeslot=0x0509,
+ },
+ [0x050A]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER KOMI NJE",
+ direction="l",
+ lccode=0x050B,
+ linebreak="al",
+ unicodeslot=0x050A,
+ },
+ [0x050B]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER KOMI NJE",
+ direction="l",
+ linebreak="al",
+ uccode=0x050A,
+ unicodeslot=0x050B,
+ },
+ [0x050C]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER KOMI SJE",
+ direction="l",
+ lccode=0x050D,
+ linebreak="al",
+ unicodeslot=0x050C,
+ },
+ [0x050D]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER KOMI SJE",
+ direction="l",
+ linebreak="al",
+ uccode=0x050C,
+ unicodeslot=0x050D,
+ },
+ [0x050E]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER KOMI TJE",
+ direction="l",
+ lccode=0x050F,
+ linebreak="al",
+ unicodeslot=0x050E,
+ },
+ [0x050F]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER KOMI TJE",
+ direction="l",
+ linebreak="al",
+ uccode=0x050E,
+ unicodeslot=0x050F,
+ },
+ [0x0510]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER REVERSED ZE",
+ direction="l",
+ lccode=0x0511,
+ linebreak="al",
+ unicodeslot=0x0510,
+ },
+ [0x0511]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER REVERSED ZE",
+ direction="l",
+ linebreak="al",
+ uccode=0x0510,
+ unicodeslot=0x0511,
+ },
+ [0x0512]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER EL WITH HOOK",
+ direction="l",
+ lccode=0x0513,
+ linebreak="al",
+ shcode=0x041B,
+ unicodeslot=0x0512,
+ },
+ [0x0513]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER EL WITH HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x043B,
+ uccode=0x0512,
+ unicodeslot=0x0513,
+ },
+ [0x0514]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER LHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0514,
+ },
+ [0x0515]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER LHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0515,
+ },
+ [0x0516]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER RHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0516,
+ },
+ [0x0517]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER RHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0517,
+ },
+ [0x0518]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER YAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0518,
+ },
+ [0x0519]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER YAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0519,
+ },
+ [0x051A]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER QA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x051A,
+ },
+ [0x051B]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER QA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x051B,
+ },
+ [0x051C]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER WE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x051C,
+ },
+ [0x051D]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER WE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x051D,
+ },
+ [0x051E]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER ALEUT KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x051E,
+ },
+ [0x051F]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER ALEUT KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x051F,
+ },
+ [0x0520]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0520,
+ },
+ [0x0521]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0521,
+ },
+ [0x0522]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0522,
+ },
+ [0x0523]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0523,
+ },
+ [0x0524]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER PE WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0524,
+ },
+ [0x0525]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER PE WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0525,
+ },
+ [0x0526]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0526,
+ },
+ [0x0527]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER SHHA WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0527,
+ },
+ [0x0531]={
+ adobename="Aybarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER AYB",
+ direction="l",
+ lccode=0x0561,
+ linebreak="al",
+ unicodeslot=0x0531,
+ },
+ [0x0532]={
+ adobename="Benarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER BEN",
+ direction="l",
+ lccode=0x0562,
+ linebreak="al",
+ unicodeslot=0x0532,
+ },
+ [0x0533]={
+ adobename="Gimarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER GIM",
+ direction="l",
+ lccode=0x0563,
+ linebreak="al",
+ unicodeslot=0x0533,
+ },
+ [0x0534]={
+ adobename="Daarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER DA",
+ direction="l",
+ lccode=0x0564,
+ linebreak="al",
+ unicodeslot=0x0534,
+ },
+ [0x0535]={
+ adobename="Echarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER ECH",
+ direction="l",
+ lccode=0x0565,
+ linebreak="al",
+ unicodeslot=0x0535,
+ },
+ [0x0536]={
+ adobename="Zaarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER ZA",
+ direction="l",
+ lccode=0x0566,
+ linebreak="al",
+ unicodeslot=0x0536,
+ },
+ [0x0537]={
+ adobename="Eharmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER EH",
+ direction="l",
+ lccode=0x0567,
+ linebreak="al",
+ unicodeslot=0x0537,
+ },
+ [0x0538]={
+ adobename="Etarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER ET",
+ direction="l",
+ lccode=0x0568,
+ linebreak="al",
+ unicodeslot=0x0538,
+ },
+ [0x0539]={
+ adobename="Toarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER TO",
+ direction="l",
+ lccode=0x0569,
+ linebreak="al",
+ unicodeslot=0x0539,
+ },
+ [0x053A]={
+ adobename="Zhearmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER ZHE",
+ direction="l",
+ lccode=0x056A,
+ linebreak="al",
+ unicodeslot=0x053A,
+ },
+ [0x053B]={
+ adobename="Iniarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER INI",
+ direction="l",
+ lccode=0x056B,
+ linebreak="al",
+ unicodeslot=0x053B,
+ },
+ [0x053C]={
+ adobename="Liwnarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER LIWN",
+ direction="l",
+ lccode=0x056C,
+ linebreak="al",
+ unicodeslot=0x053C,
+ },
+ [0x053D]={
+ adobename="Xeharmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER XEH",
+ direction="l",
+ lccode=0x056D,
+ linebreak="al",
+ unicodeslot=0x053D,
+ },
+ [0x053E]={
+ adobename="Caarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER CA",
+ direction="l",
+ lccode=0x056E,
+ linebreak="al",
+ unicodeslot=0x053E,
+ },
+ [0x053F]={
+ adobename="Kenarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER KEN",
+ direction="l",
+ lccode=0x056F,
+ linebreak="al",
+ unicodeslot=0x053F,
+ },
+ [0x0540]={
+ adobename="Hoarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER HO",
+ direction="l",
+ lccode=0x0570,
+ linebreak="al",
+ unicodeslot=0x0540,
+ },
+ [0x0541]={
+ adobename="Jaarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER JA",
+ direction="l",
+ lccode=0x0571,
+ linebreak="al",
+ unicodeslot=0x0541,
+ },
+ [0x0542]={
+ adobename="Ghadarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER GHAD",
+ direction="l",
+ lccode=0x0572,
+ linebreak="al",
+ unicodeslot=0x0542,
+ },
+ [0x0543]={
+ adobename="Cheharmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER CHEH",
+ direction="l",
+ lccode=0x0573,
+ linebreak="al",
+ unicodeslot=0x0543,
+ },
+ [0x0544]={
+ adobename="Menarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER MEN",
+ direction="l",
+ lccode=0x0574,
+ linebreak="al",
+ unicodeslot=0x0544,
+ },
+ [0x0545]={
+ adobename="Yiarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER YI",
+ direction="l",
+ lccode=0x0575,
+ linebreak="al",
+ unicodeslot=0x0545,
+ },
+ [0x0546]={
+ adobename="Nowarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER NOW",
+ direction="l",
+ lccode=0x0576,
+ linebreak="al",
+ unicodeslot=0x0546,
+ },
+ [0x0547]={
+ adobename="Shaarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER SHA",
+ direction="l",
+ lccode=0x0577,
+ linebreak="al",
+ unicodeslot=0x0547,
+ },
+ [0x0548]={
+ adobename="Voarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER VO",
+ direction="l",
+ lccode=0x0578,
+ linebreak="al",
+ unicodeslot=0x0548,
+ },
+ [0x0549]={
+ adobename="Chaarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER CHA",
+ direction="l",
+ lccode=0x0579,
+ linebreak="al",
+ unicodeslot=0x0549,
+ },
+ [0x054A]={
+ adobename="Peharmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER PEH",
+ direction="l",
+ lccode=0x057A,
+ linebreak="al",
+ unicodeslot=0x054A,
+ },
+ [0x054B]={
+ adobename="Jheharmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER JHEH",
+ direction="l",
+ lccode=0x057B,
+ linebreak="al",
+ unicodeslot=0x054B,
+ },
+ [0x054C]={
+ adobename="Raarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER RA",
+ direction="l",
+ lccode=0x057C,
+ linebreak="al",
+ unicodeslot=0x054C,
+ },
+ [0x054D]={
+ adobename="Seharmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER SEH",
+ direction="l",
+ lccode=0x057D,
+ linebreak="al",
+ unicodeslot=0x054D,
+ },
+ [0x054E]={
+ adobename="Vewarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER VEW",
+ direction="l",
+ lccode=0x057E,
+ linebreak="al",
+ unicodeslot=0x054E,
+ },
+ [0x054F]={
+ adobename="Tiwnarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER TIWN",
+ direction="l",
+ lccode=0x057F,
+ linebreak="al",
+ unicodeslot=0x054F,
+ },
+ [0x0550]={
+ adobename="Reharmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER REH",
+ direction="l",
+ lccode=0x0580,
+ linebreak="al",
+ unicodeslot=0x0550,
+ },
+ [0x0551]={
+ adobename="Coarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER CO",
+ direction="l",
+ lccode=0x0581,
+ linebreak="al",
+ unicodeslot=0x0551,
+ },
+ [0x0552]={
+ adobename="Yiwnarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER YIWN",
+ direction="l",
+ lccode=0x0582,
+ linebreak="al",
+ unicodeslot=0x0552,
+ },
+ [0x0553]={
+ adobename="Piwrarmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER PIWR",
+ direction="l",
+ lccode=0x0583,
+ linebreak="al",
+ unicodeslot=0x0553,
+ },
+ [0x0554]={
+ adobename="Keharmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER KEH",
+ direction="l",
+ lccode=0x0584,
+ linebreak="al",
+ unicodeslot=0x0554,
+ },
+ [0x0555]={
+ adobename="Oharmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER OH",
+ direction="l",
+ lccode=0x0585,
+ linebreak="al",
+ unicodeslot=0x0555,
+ },
+ [0x0556]={
+ adobename="Feharmenian",
+ category="lu",
+ description="ARMENIAN CAPITAL LETTER FEH",
+ direction="l",
+ lccode=0x0586,
+ linebreak="al",
+ unicodeslot=0x0556,
+ },
+ [0x0559]={
+ adobename="ringhalfleftarmenian",
+ category="lm",
+ description="ARMENIAN MODIFIER LETTER LEFT HALF RING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0559,
+ },
+ [0x055A]={
+ adobename="apostrophearmenian",
+ category="po",
+ description="ARMENIAN APOSTROPHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x055A,
+ },
+ [0x055B]={
+ adobename="emphasismarkarmenian",
+ category="po",
+ description="ARMENIAN EMPHASIS MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x055B,
+ },
+ [0x055C]={
+ adobename="exclamarmenian",
+ category="po",
+ description="ARMENIAN EXCLAMATION MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x055C,
+ },
+ [0x055D]={
+ adobename="commaarmenian",
+ category="po",
+ description="ARMENIAN COMMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x055D,
+ },
+ [0x055E]={
+ adobename="questionarmenian",
+ category="po",
+ description="ARMENIAN QUESTION MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x055E,
+ },
+ [0x055F]={
+ adobename="abbreviationmarkarmenian",
+ category="po",
+ description="ARMENIAN ABBREVIATION MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x055F,
+ },
+ [0x0561]={
+ adobename="aybarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER AYB",
+ direction="l",
+ linebreak="al",
+ uccode=0x0531,
+ unicodeslot=0x0561,
+ },
+ [0x0562]={
+ adobename="benarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER BEN",
+ direction="l",
+ linebreak="al",
+ uccode=0x0532,
+ unicodeslot=0x0562,
+ },
+ [0x0563]={
+ adobename="gimarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER GIM",
+ direction="l",
+ linebreak="al",
+ uccode=0x0533,
+ unicodeslot=0x0563,
+ },
+ [0x0564]={
+ adobename="daarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER DA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0534,
+ unicodeslot=0x0564,
+ },
+ [0x0565]={
+ adobename="echarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER ECH",
+ direction="l",
+ linebreak="al",
+ uccode=0x0535,
+ unicodeslot=0x0565,
+ },
+ [0x0566]={
+ adobename="zaarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER ZA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0536,
+ unicodeslot=0x0566,
+ },
+ [0x0567]={
+ adobename="eharmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER EH",
+ direction="l",
+ linebreak="al",
+ uccode=0x0537,
+ unicodeslot=0x0567,
+ },
+ [0x0568]={
+ adobename="etarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER ET",
+ direction="l",
+ linebreak="al",
+ uccode=0x0538,
+ unicodeslot=0x0568,
+ },
+ [0x0569]={
+ adobename="toarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER TO",
+ direction="l",
+ linebreak="al",
+ uccode=0x0539,
+ unicodeslot=0x0569,
+ },
+ [0x056A]={
+ adobename="zhearmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER ZHE",
+ direction="l",
+ linebreak="al",
+ uccode=0x053A,
+ unicodeslot=0x056A,
+ },
+ [0x056B]={
+ adobename="iniarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER INI",
+ direction="l",
+ linebreak="al",
+ uccode=0x053B,
+ unicodeslot=0x056B,
+ },
+ [0x056C]={
+ adobename="liwnarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER LIWN",
+ direction="l",
+ linebreak="al",
+ uccode=0x053C,
+ unicodeslot=0x056C,
+ },
+ [0x056D]={
+ adobename="xeharmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER XEH",
+ direction="l",
+ linebreak="al",
+ uccode=0x053D,
+ unicodeslot=0x056D,
+ },
+ [0x056E]={
+ adobename="caarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER CA",
+ direction="l",
+ linebreak="al",
+ uccode=0x053E,
+ unicodeslot=0x056E,
+ },
+ [0x056F]={
+ adobename="kenarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER KEN",
+ direction="l",
+ linebreak="al",
+ uccode=0x053F,
+ unicodeslot=0x056F,
+ },
+ [0x0570]={
+ adobename="hoarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER HO",
+ direction="l",
+ linebreak="al",
+ uccode=0x0540,
+ unicodeslot=0x0570,
+ },
+ [0x0571]={
+ adobename="jaarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER JA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0541,
+ unicodeslot=0x0571,
+ },
+ [0x0572]={
+ adobename="ghadarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER GHAD",
+ direction="l",
+ linebreak="al",
+ uccode=0x0542,
+ unicodeslot=0x0572,
+ },
+ [0x0573]={
+ adobename="cheharmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER CHEH",
+ direction="l",
+ linebreak="al",
+ uccode=0x0543,
+ unicodeslot=0x0573,
+ },
+ [0x0574]={
+ adobename="menarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER MEN",
+ direction="l",
+ linebreak="al",
+ uccode=0x0544,
+ unicodeslot=0x0574,
+ },
+ [0x0575]={
+ adobename="yiarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER YI",
+ direction="l",
+ linebreak="al",
+ uccode=0x0545,
+ unicodeslot=0x0575,
+ },
+ [0x0576]={
+ adobename="nowarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER NOW",
+ direction="l",
+ linebreak="al",
+ uccode=0x0546,
+ unicodeslot=0x0576,
+ },
+ [0x0577]={
+ adobename="shaarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER SHA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0547,
+ unicodeslot=0x0577,
+ },
+ [0x0578]={
+ adobename="voarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER VO",
+ direction="l",
+ linebreak="al",
+ uccode=0x0548,
+ unicodeslot=0x0578,
+ },
+ [0x0579]={
+ adobename="chaarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER CHA",
+ direction="l",
+ linebreak="al",
+ uccode=0x0549,
+ unicodeslot=0x0579,
+ },
+ [0x057A]={
+ adobename="peharmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER PEH",
+ direction="l",
+ linebreak="al",
+ uccode=0x054A,
+ unicodeslot=0x057A,
+ },
+ [0x057B]={
+ adobename="jheharmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER JHEH",
+ direction="l",
+ linebreak="al",
+ uccode=0x054B,
+ unicodeslot=0x057B,
+ },
+ [0x057C]={
+ adobename="raarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER RA",
+ direction="l",
+ linebreak="al",
+ uccode=0x054C,
+ unicodeslot=0x057C,
+ },
+ [0x057D]={
+ adobename="seharmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER SEH",
+ direction="l",
+ linebreak="al",
+ uccode=0x054D,
+ unicodeslot=0x057D,
+ },
+ [0x057E]={
+ adobename="vewarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER VEW",
+ direction="l",
+ linebreak="al",
+ uccode=0x054E,
+ unicodeslot=0x057E,
+ },
+ [0x057F]={
+ adobename="tiwnarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER TIWN",
+ direction="l",
+ linebreak="al",
+ uccode=0x054F,
+ unicodeslot=0x057F,
+ },
+ [0x0580]={
+ adobename="reharmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER REH",
+ direction="l",
+ linebreak="al",
+ uccode=0x0550,
+ unicodeslot=0x0580,
+ },
+ [0x0581]={
+ adobename="coarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER CO",
+ direction="l",
+ linebreak="al",
+ uccode=0x0551,
+ unicodeslot=0x0581,
+ },
+ [0x0582]={
+ adobename="yiwnarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER YIWN",
+ direction="l",
+ linebreak="al",
+ uccode=0x0552,
+ unicodeslot=0x0582,
+ },
+ [0x0583]={
+ adobename="piwrarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER PIWR",
+ direction="l",
+ linebreak="al",
+ uccode=0x0553,
+ unicodeslot=0x0583,
+ },
+ [0x0584]={
+ adobename="keharmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER KEH",
+ direction="l",
+ linebreak="al",
+ uccode=0x0554,
+ unicodeslot=0x0584,
+ },
+ [0x0585]={
+ adobename="oharmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER OH",
+ direction="l",
+ linebreak="al",
+ uccode=0x0555,
+ unicodeslot=0x0585,
+ },
+ [0x0586]={
+ adobename="feharmenian",
+ category="ll",
+ description="ARMENIAN SMALL LETTER FEH",
+ direction="l",
+ linebreak="al",
+ uccode=0x0556,
+ unicodeslot=0x0586,
+ },
+ [0x0587]={
+ adobename="echyiwnarmenian",
+ category="ll",
+ description="ARMENIAN SMALL LIGATURE ECH YIWN",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0565, 0x0582 },
+ unicodeslot=0x0587,
+ },
+ [0x0589]={
+ adobename="periodarmenian",
+ category="po",
+ description="ARMENIAN FULL STOP",
+ direction="l",
+ linebreak="is",
+ unicodeslot=0x0589,
+ },
+ [0x058A]={
+ category="pd",
+ description="ARMENIAN HYPHEN",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x058A,
+ },
+ [0x058F]={
+ category="sc",
+ description="ARMENIAN DRAM SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x058F,
+ },
+ [0x0591]={
+ adobename="etnahtalefthebrew",
+ category="mn",
+ description="HEBREW ACCENT ETNAHTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0591,
+ },
+ [0x0592]={
+ adobename="segoltahebrew",
+ category="mn",
+ description="HEBREW ACCENT SEGOL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0592,
+ },
+ [0x0593]={
+ adobename="shalshelethebrew",
+ category="mn",
+ description="HEBREW ACCENT SHALSHELET",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0593,
+ },
+ [0x0594]={
+ adobename="zaqefqatanhebrew",
+ category="mn",
+ description="HEBREW ACCENT ZAQEF QATAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0594,
+ },
+ [0x0595]={
+ adobename="zaqefgadolhebrew",
+ category="mn",
+ description="HEBREW ACCENT ZAQEF GADOL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0595,
+ },
+ [0x0596]={
+ adobename="tipehalefthebrew",
+ category="mn",
+ description="HEBREW ACCENT TIPEHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0596,
+ },
+ [0x0597]={
+ adobename="reviamugrashhebrew",
+ category="mn",
+ description="HEBREW ACCENT REVIA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0597,
+ },
+ [0x0598]={
+ adobename="zarqahebrew",
+ category="mn",
+ description="HEBREW ACCENT ZARQA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0598,
+ },
+ [0x0599]={
+ adobename="pashtahebrew",
+ category="mn",
+ description="HEBREW ACCENT PASHTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0599,
+ },
+ [0x059A]={
+ adobename="yetivhebrew",
+ category="mn",
+ description="HEBREW ACCENT YETIV",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x059A,
+ },
+ [0x059B]={
+ adobename="tevirlefthebrew",
+ category="mn",
+ description="HEBREW ACCENT TEVIR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x059B,
+ },
+ [0x059C]={
+ adobename="gereshaccenthebrew",
+ category="mn",
+ description="HEBREW ACCENT GERESH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x059C,
+ },
+ [0x059D]={
+ adobename="gereshmuqdamhebrew",
+ category="mn",
+ description="HEBREW ACCENT GERESH MUQDAM",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x059D,
+ },
+ [0x059E]={
+ adobename="gershayimaccenthebrew",
+ category="mn",
+ description="HEBREW ACCENT GERSHAYIM",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x059E,
+ },
+ [0x059F]={
+ adobename="qarneyparahebrew",
+ category="mn",
+ description="HEBREW ACCENT QARNEY PARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x059F,
+ },
+ [0x05A0]={
+ adobename="telishagedolahebrew",
+ category="mn",
+ description="HEBREW ACCENT TELISHA GEDOLA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05A0,
+ },
+ [0x05A1]={
+ adobename="pazerhebrew",
+ category="mn",
+ description="HEBREW ACCENT PAZER",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05A1,
+ },
+ [0x05A2]={
+ category="mn",
+ description="HEBREW ACCENT ATNAH HAFUKH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05A2,
+ },
+ [0x05A3]={
+ adobename="munahlefthebrew",
+ category="mn",
+ description="HEBREW ACCENT MUNAH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05A3,
+ },
+ [0x05A4]={
+ adobename="mahapakhlefthebrew",
+ category="mn",
+ description="HEBREW ACCENT MAHAPAKH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05A4,
+ },
+ [0x05A5]={
+ adobename="merkhalefthebrew",
+ category="mn",
+ description="HEBREW ACCENT MERKHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05A5,
+ },
+ [0x05A6]={
+ adobename="merkhakefulalefthebrew",
+ category="mn",
+ description="HEBREW ACCENT MERKHA KEFULA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05A6,
+ },
+ [0x05A7]={
+ adobename="dargalefthebrew",
+ category="mn",
+ description="HEBREW ACCENT DARGA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05A7,
+ },
+ [0x05A8]={
+ adobename="qadmahebrew",
+ category="mn",
+ description="HEBREW ACCENT QADMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05A8,
+ },
+ [0x05A9]={
+ adobename="telishaqetanahebrew",
+ category="mn",
+ description="HEBREW ACCENT TELISHA QETANA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05A9,
+ },
+ [0x05AA]={
+ adobename="yerahbenyomolefthebrew",
+ category="mn",
+ description="HEBREW ACCENT YERAH BEN YOMO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05AA,
+ },
+ [0x05AB]={
+ adobename="olehebrew",
+ category="mn",
+ description="HEBREW ACCENT OLE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05AB,
+ },
+ [0x05AC]={
+ adobename="iluyhebrew",
+ category="mn",
+ description="HEBREW ACCENT ILUY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05AC,
+ },
+ [0x05AD]={
+ adobename="dehihebrew",
+ category="mn",
+ description="HEBREW ACCENT DEHI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05AD,
+ },
+ [0x05AE]={
+ adobename="zinorhebrew",
+ category="mn",
+ description="HEBREW ACCENT ZINOR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05AE,
+ },
+ [0x05AF]={
+ adobename="masoracirclehebrew",
+ category="mn",
+ description="HEBREW MARK MASORA CIRCLE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05AF,
+ },
+ [0x05B0]={
+ adobename="shevawidehebrew",
+ category="mn",
+ description="HEBREW POINT SHEVA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05B0,
+ },
+ [0x05B1]={
+ adobename="hatafsegolwidehebrew",
+ category="mn",
+ description="HEBREW POINT HATAF SEGOL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05B1,
+ },
+ [0x05B2]={
+ adobename="hatafpatahwidehebrew",
+ category="mn",
+ description="HEBREW POINT HATAF PATAH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05B2,
+ },
+ [0x05B3]={
+ adobename="hatafqamatswidehebrew",
+ category="mn",
+ description="HEBREW POINT HATAF QAMATS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05B3,
+ },
+ [0x05B4]={
+ adobename="hiriqwidehebrew",
+ category="mn",
+ description="HEBREW POINT HIRIQ",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05B4,
+ },
+ [0x05B5]={
+ adobename="tserewidehebrew",
+ category="mn",
+ description="HEBREW POINT TSERE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05B5,
+ },
+ [0x05B6]={
+ adobename="segolwidehebrew",
+ category="mn",
+ description="HEBREW POINT SEGOL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05B6,
+ },
+ [0x05B7]={
+ adobename="patahwidehebrew",
+ category="mn",
+ description="HEBREW POINT PATAH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05B7,
+ },
+ [0x05B8]={
+ adobename="qamatswidehebrew",
+ category="mn",
+ description="HEBREW POINT QAMATS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05B8,
+ },
+ [0x05B9]={
+ adobename="holamwidehebrew",
+ category="mn",
+ description="HEBREW POINT HOLAM",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05B9,
+ },
+ [0x05BA]={
+ category="mn",
+ description="HEBREW POINT HOLAM HASER FOR VAV",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05BA,
+ },
+ [0x05BB]={
+ adobename="qubutswidehebrew",
+ category="mn",
+ description="HEBREW POINT QUBUTS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05BB,
+ },
+ [0x05BC]={
+ adobename="dageshhebrew",
+ category="mn",
+ description="HEBREW POINT DAGESH OR MAPIQ",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05BC,
+ },
+ [0x05BD]={
+ adobename="siluqlefthebrew",
+ category="mn",
+ description="HEBREW POINT METEG",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05BD,
+ },
+ [0x05BE]={
+ adobename="maqafhebrew",
+ category="po",
+ description="HEBREW PUNCTUATION MAQAF",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x05BE,
+ },
+ [0x05BF]={
+ adobename="rafehebrew",
+ category="mn",
+ description="HEBREW POINT RAFE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05BF,
+ },
+ [0x05C0]={
+ adobename="paseqhebrew",
+ category="po",
+ description="HEBREW PUNCTUATION PASEQ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x05C0,
+ },
+ [0x05C1]={
+ adobename="shindothebrew",
+ category="mn",
+ description="HEBREW POINT SHIN DOT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05C1,
+ },
+ [0x05C2]={
+ adobename="sindothebrew",
+ category="mn",
+ description="HEBREW POINT SIN DOT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05C2,
+ },
+ [0x05C3]={
+ adobename="sofpasuqhebrew",
+ category="po",
+ description="HEBREW PUNCTUATION SOF PASUQ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x05C3,
+ },
+ [0x05C4]={
+ adobename="upperdothebrew",
+ category="mn",
+ description="HEBREW MARK UPPER DOT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05C4,
+ },
+ [0x05C5]={
+ category="mn",
+ description="HEBREW MARK LOWER DOT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05C5,
+ },
+ [0x05C6]={
+ category="po",
+ description="HEBREW PUNCTUATION NUN HAFUKHA",
+ direction="r",
+ linebreak="ex",
+ unicodeslot=0x05C6,
+ },
+ [0x05C7]={
+ category="mn",
+ description="HEBREW POINT QAMATS QATAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x05C7,
+ },
+ [0x05D0]={
+ adobename="alefhebrew",
+ category="lo",
+ contextname="hebrewAlef",
+ description="HEBREW LETTER ALEF",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05D0,
+ },
+ [0x05D1]={
+ adobename="bethebrew",
+ category="lo",
+ contextname="hebrewBet",
+ description="HEBREW LETTER BET",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05D1,
+ },
+ [0x05D2]={
+ adobename="gimelhebrew",
+ category="lo",
+ contextname="hebrewGimel",
+ description="HEBREW LETTER GIMEL",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05D2,
+ },
+ [0x05D3]={
+ adobename="dalettserehebrew",
+ category="lo",
+ contextname="hebrewDalet",
+ description="HEBREW LETTER DALET",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05D3,
+ },
+ [0x05D4]={
+ adobename="hehebrew",
+ category="lo",
+ contextname="hebrewHe",
+ description="HEBREW LETTER HE",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05D4,
+ },
+ [0x05D5]={
+ adobename="vavhebrew",
+ category="lo",
+ contextname="hebrewVav",
+ description="HEBREW LETTER VAV",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05D5,
+ },
+ [0x05D6]={
+ adobename="zayinhebrew",
+ category="lo",
+ contextname="hebrewZayin",
+ description="HEBREW LETTER ZAYIN",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05D6,
+ },
+ [0x05D7]={
+ adobename="hethebrew",
+ category="lo",
+ contextname="hebrewHet",
+ description="HEBREW LETTER HET",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05D7,
+ },
+ [0x05D8]={
+ adobename="tethebrew",
+ category="lo",
+ contextname="hebrewTet",
+ description="HEBREW LETTER TET",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05D8,
+ },
+ [0x05D9]={
+ adobename="yodhebrew",
+ category="lo",
+ contextname="hebrewYod",
+ description="HEBREW LETTER YOD",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05D9,
+ },
+ [0x05DA]={
+ adobename="finalkafshevahebrew",
+ category="lo",
+ contextname="hebrewKaffinal",
+ description="HEBREW LETTER FINAL KAF",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05DA,
+ },
+ [0x05DB]={
+ adobename="kafhebrew",
+ category="lo",
+ contextname="hebrewKaf",
+ description="HEBREW LETTER KAF",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05DB,
+ },
+ [0x05DC]={
+ adobename="lamedholamhebrew",
+ category="lo",
+ contextname="hebrewLamed",
+ description="HEBREW LETTER LAMED",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05DC,
+ },
+ [0x05DD]={
+ adobename="finalmemhebrew",
+ category="lo",
+ contextname="hebrewMemfinal",
+ description="HEBREW LETTER FINAL MEM",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05DD,
+ },
+ [0x05DE]={
+ adobename="memhebrew",
+ category="lo",
+ contextname="hebrewMem",
+ description="HEBREW LETTER MEM",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05DE,
+ },
+ [0x05DF]={
+ adobename="finalnunhebrew",
+ category="lo",
+ contextname="hebrewNunfinal",
+ description="HEBREW LETTER FINAL NUN",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05DF,
+ },
+ [0x05E0]={
+ adobename="nunhebrew",
+ category="lo",
+ contextname="hebrewNun",
+ description="HEBREW LETTER NUN",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05E0,
+ },
+ [0x05E1]={
+ adobename="samekhhebrew",
+ category="lo",
+ contextname="hebrewSamekh",
+ description="HEBREW LETTER SAMEKH",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05E1,
+ },
+ [0x05E2]={
+ adobename="ayinhebrew",
+ category="lo",
+ contextname="hebrewAyin",
+ description="HEBREW LETTER AYIN",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05E2,
+ },
+ [0x05E3]={
+ adobename="finalpehebrew",
+ category="lo",
+ contextname="hebrewPefinal",
+ description="HEBREW LETTER FINAL PE",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05E3,
+ },
+ [0x05E4]={
+ adobename="pehebrew",
+ category="lo",
+ contextname="hebrewPe",
+ description="HEBREW LETTER PE",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05E4,
+ },
+ [0x05E5]={
+ adobename="finaltsadihebrew",
+ category="lo",
+ contextname="hebrewTsadifinal",
+ description="HEBREW LETTER FINAL TSADI",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05E5,
+ },
+ [0x05E6]={
+ adobename="tsadihebrew",
+ category="lo",
+ contextname="hebrewTsadi",
+ description="HEBREW LETTER TSADI",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05E6,
+ },
+ [0x05E7]={
+ adobename="qoftserehebrew",
+ category="lo",
+ contextname="hebrewQof",
+ description="HEBREW LETTER QOF",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05E7,
+ },
+ [0x05E8]={
+ adobename="reshtserehebrew",
+ category="lo",
+ contextname="hebrewResh",
+ description="HEBREW LETTER RESH",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05E8,
+ },
+ [0x05E9]={
+ adobename="shinhebrew",
+ category="lo",
+ contextname="hebrewShin",
+ description="HEBREW LETTER SHIN",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05E9,
+ },
+ [0x05EA]={
+ adobename="tavhebrew",
+ category="lo",
+ contextname="hebrewTav",
+ description="HEBREW LETTER TAV",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05EA,
+ },
+ [0x05F0]={
+ adobename="vavvavhebrew",
+ category="lo",
+ description="HEBREW LIGATURE YIDDISH DOUBLE VAV",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05F0,
+ },
+ [0x05F1]={
+ adobename="vavyodhebrew",
+ category="lo",
+ description="HEBREW LIGATURE YIDDISH VAV YOD",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05F1,
+ },
+ [0x05F2]={
+ adobename="yodyodhebrew",
+ category="lo",
+ description="HEBREW LIGATURE YIDDISH DOUBLE YOD",
+ direction="r",
+ linebreak="hl",
+ unicodeslot=0x05F2,
+ },
+ [0x05F3]={
+ adobename="gereshhebrew",
+ category="po",
+ description="HEBREW PUNCTUATION GERESH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x05F3,
+ },
+ [0x05F4]={
+ adobename="gershayimhebrew",
+ category="po",
+ description="HEBREW PUNCTUATION GERSHAYIM",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x05F4,
+ },
+ [0x0600]={
+ arabic="u",
+ category="cf",
+ description="ARABIC NUMBER SIGN",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x0600,
+ visible="yes",
+ },
+ [0x0601]={
+ arabic="u",
+ category="cf",
+ description="ARABIC SIGN SANAH",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x0601,
+ visible="yes",
+ },
+ [0x0602]={
+ arabic="u",
+ category="cf",
+ description="ARABIC FOOTNOTE MARKER",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x0602,
+ visible="yes",
+ },
+ [0x0603]={
+ arabic="u",
+ category="cf",
+ description="ARABIC SIGN SAFHA",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x0603,
+ visible="yes",
+ },
+ [0x0604]={
+ arabic="u",
+ category="cf",
+ description="ARABIC SIGN SAMVAT",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x0604,
+ },
+ [0x0606]={
+ category="sm",
+ description="ARABIC-INDIC CUBE ROOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0606,
+ },
+ [0x0607]={
+ category="sm",
+ description="ARABIC-INDIC FOURTH ROOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0607,
+ },
+ [0x0608]={
+ arabic="u",
+ category="sm",
+ description="ARABIC RAY",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0608,
+ },
+ [0x0609]={
+ category="po",
+ description="ARABIC-INDIC PER MILLE SIGN",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x0609,
+ },
+ [0x060A]={
+ category="po",
+ description="ARABIC-INDIC PER TEN THOUSAND SIGN",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x060A,
+ },
+ [0x060B]={
+ arabic="u",
+ category="sc",
+ description="AFGHANI SIGN",
+ direction="al",
+ linebreak="po",
+ unicodeslot=0x060B,
+ },
+ [0x060C]={
+ adobename="commaarabic",
+ category="po",
+ description="ARABIC COMMA",
+ direction="cs",
+ linebreak="is",
+ unicodeslot=0x060C,
+ },
+ [0x060D]={
+ category="po",
+ description="ARABIC DATE SEPARATOR",
+ direction="al",
+ linebreak="is",
+ unicodeslot=0x060D,
+ },
+ [0x060E]={
+ category="so",
+ description="ARABIC POETIC VERSE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x060E,
+ },
+ [0x060F]={
+ category="so",
+ description="ARABIC SIGN MISRA",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x060F,
+ },
+ [0x0610]={
+ category="mn",
+ description="ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0610,
+ },
+ [0x0611]={
+ category="mn",
+ description="ARABIC SIGN ALAYHE ASSALLAM",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0611,
+ },
+ [0x0612]={
+ category="mn",
+ description="ARABIC SIGN RAHMATULLAH ALAYHE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0612,
+ },
+ [0x0613]={
+ category="mn",
+ description="ARABIC SIGN RADI ALLAHOU ANHU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0613,
+ },
+ [0x0614]={
+ category="mn",
+ description="ARABIC SIGN TAKHALLUS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0614,
+ },
+ [0x0615]={
+ category="mn",
+ description="ARABIC SMALL HIGH TAH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0615,
+ },
+ [0x0616]={
+ category="mn",
+ description="ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0616,
+ },
+ [0x0617]={
+ category="mn",
+ description="ARABIC SMALL HIGH ZAIN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0617,
+ },
+ [0x0618]={
+ category="mn",
+ description="ARABIC SMALL FATHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0618,
+ },
+ [0x0619]={
+ category="mn",
+ description="ARABIC SMALL DAMMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0619,
+ },
+ [0x061A]={
+ category="mn",
+ description="ARABIC SMALL KASRA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x061A,
+ },
+ [0x061B]={
+ adobename="semicolonarabic",
+ category="po",
+ description="ARABIC SEMICOLON",
+ direction="al",
+ linebreak="ex",
+ unicodeslot=0x061B,
+ },
+ [0x061E]={
+ category="po",
+ description="ARABIC TRIPLE DOT PUNCTUATION MARK",
+ direction="al",
+ linebreak="ex",
+ unicodeslot=0x061E,
+ },
+ [0x061F]={
+ adobename="questionarabic",
+ category="po",
+ description="ARABIC QUESTION MARK",
+ direction="al",
+ linebreak="ex",
+ unicodeslot=0x061F,
+ },
+ [0x0620]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KASHMIRI YEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0620,
+ },
+ [0x0621]={
+ adobename="hamzasukunarabic",
+ arabic="u",
+ category="lo",
+ description="ARABIC LETTER HAMZA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0621,
+ },
+ [0x0622]={
+ adobename="alefmaddaabovearabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER ALEF WITH MADDA ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0627,
+ specials={ "char", 0x0627, 0x0653 },
+ unicodeslot=0x0622,
+ },
+ [0x0623]={
+ adobename="alefhamzaabovearabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER ALEF WITH HAMZA ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0627,
+ specials={ "char", 0x0627, 0x0654 },
+ unicodeslot=0x0623,
+ },
+ [0x0624]={
+ adobename="wawhamzaabovearabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER WAW WITH HAMZA ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0648,
+ specials={ "char", 0x0648, 0x0654 },
+ unicodeslot=0x0624,
+ },
+ [0x0625]={
+ adobename="alefhamzabelowarabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER ALEF WITH HAMZA BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0627,
+ specials={ "char", 0x0627, 0x0655 },
+ unicodeslot=0x0625,
+ },
+ [0x0626]={
+ adobename="yehhamzaabovearabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER YEH WITH HAMZA ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x064A,
+ specials={ "char", 0x064A, 0x0654 },
+ unicodeslot=0x0626,
+ },
+ [0x0627]={
+ adobename="alefarabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER ALEF",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0627,
+ },
+ [0x0628]={
+ adobename="beharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER BEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0628,
+ },
+ [0x0629]={
+ adobename="tehmarbutaarabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER TEH MARBUTA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0629,
+ },
+ [0x062A]={
+ adobename="teharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER TEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x062A,
+ },
+ [0x062B]={
+ adobename="theharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER THEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x062B,
+ },
+ [0x062C]={
+ adobename="jeemarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER JEEM",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x062C,
+ },
+ [0x062D]={
+ adobename="haharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HAH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x062D,
+ },
+ [0x062E]={
+ adobename="khaharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KHAH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x062E,
+ },
+ [0x062F]={
+ adobename="dalarabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DAL",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x062F,
+ },
+ [0x0630]={
+ adobename="thalarabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER THAL",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0630,
+ },
+ [0x0631]={
+ adobename="rehyehaleflamarabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0631,
+ },
+ [0x0632]={
+ adobename="zainarabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER ZAIN",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0632,
+ },
+ [0x0633]={
+ adobename="seenarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SEEN",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0633,
+ },
+ [0x0634]={
+ adobename="sheenarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SHEEN",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0634,
+ },
+ [0x0635]={
+ adobename="sadarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SAD",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0635,
+ },
+ [0x0636]={
+ adobename="dadarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER DAD",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0636,
+ },
+ [0x0637]={
+ adobename="taharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER TAH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0637,
+ },
+ [0x0638]={
+ adobename="zaharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER ZAH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0638,
+ },
+ [0x0639]={
+ adobename="ainarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER AIN",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0639,
+ },
+ [0x063A]={
+ adobename="ghainarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER GHAIN",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x063A,
+ },
+ [0x063B]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KEHEH WITH TWO DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x063B,
+ },
+ [0x063C]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KEHEH WITH THREE DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x063C,
+ },
+ [0x063D]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FARSI YEH WITH INVERTED V",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x063D,
+ },
+ [0x063E]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x063E,
+ },
+ [0x063F]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x063F,
+ },
+ [0x0640]={
+ adobename="tatweelarabic",
+ arabic="c",
+ category="lm",
+ description="ARABIC TATWEEL",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0640,
+ },
+ [0x0641]={
+ adobename="feharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0641,
+ },
+ [0x0642]={
+ adobename="qafarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER QAF",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0642,
+ },
+ [0x0643]={
+ adobename="kafarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KAF",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0643,
+ },
+ [0x0644]={
+ adobename="lamarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER LAM",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0644,
+ },
+ [0x0645]={
+ adobename="meemarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER MEEM",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0645,
+ },
+ [0x0646]={
+ adobename="noonarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER NOON",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0646,
+ },
+ [0x0647]={
+ adobename="heharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0647,
+ },
+ [0x0648]={
+ adobename="wawarabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER WAW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0648,
+ },
+ [0x0649]={
+ adobename="alefmaksuraarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER ALEF MAKSURA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0649,
+ },
+ [0x064A]={
+ adobename="yeharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER YEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x064A,
+ },
+ [0x064B]={
+ adobename="fathatanarabic",
+ category="mn",
+ description="ARABIC FATHATAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x064B,
+ },
+ [0x064C]={
+ adobename="dammatanarabic",
+ category="mn",
+ description="ARABIC DAMMATAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x064C,
+ },
+ [0x064D]={
+ adobename="kasratanarabic",
+ category="mn",
+ description="ARABIC KASRATAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x064D,
+ },
+ [0x064E]={
+ adobename="fathalowarabic",
+ category="mn",
+ description="ARABIC FATHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x064E,
+ },
+ [0x064F]={
+ adobename="dammalowarabic",
+ category="mn",
+ description="ARABIC DAMMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x064F,
+ },
+ [0x0650]={
+ adobename="kasraarabic",
+ category="mn",
+ description="ARABIC KASRA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0650,
+ },
+ [0x0651]={
+ adobename="shaddafathatanarabic",
+ category="mn",
+ description="ARABIC SHADDA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0651,
+ },
+ [0x0652]={
+ adobename="sukunarabic",
+ category="mn",
+ description="ARABIC SUKUN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0652,
+ },
+ [0x0653]={
+ category="mn",
+ description="ARABIC MADDAH ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0653,
+ },
+ [0x0654]={
+ category="mn",
+ description="ARABIC HAMZA ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0654,
+ },
+ [0x0655]={
+ category="mn",
+ description="ARABIC HAMZA BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0655,
+ },
+ [0x0656]={
+ category="mn",
+ description="ARABIC SUBSCRIPT ALEF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0656,
+ },
+ [0x0657]={
+ category="mn",
+ description="ARABIC INVERTED DAMMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0657,
+ },
+ [0x0658]={
+ category="mn",
+ description="ARABIC MARK NOON GHUNNA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0658,
+ },
+ [0x0659]={
+ category="mn",
+ description="ARABIC ZWARAKAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0659,
+ },
+ [0x065A]={
+ category="mn",
+ description="ARABIC VOWEL SIGN SMALL V ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x065A,
+ },
+ [0x065B]={
+ category="mn",
+ description="ARABIC VOWEL SIGN INVERTED SMALL V ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x065B,
+ },
+ [0x065C]={
+ category="mn",
+ description="ARABIC VOWEL SIGN DOT BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x065C,
+ },
+ [0x065D]={
+ category="mn",
+ description="ARABIC REVERSED DAMMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x065D,
+ },
+ [0x065E]={
+ category="mn",
+ description="ARABIC FATHA WITH TWO DOTS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x065E,
+ },
+ [0x065F]={
+ category="mn",
+ description="ARABIC WAVY HAMZA BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x065F,
+ },
+ [0x0660]={
+ adobename="zerohackarabic",
+ category="nd",
+ description="ARABIC-INDIC DIGIT ZERO",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x0660,
+ },
+ [0x0661]={
+ adobename="onehackarabic",
+ category="nd",
+ description="ARABIC-INDIC DIGIT ONE",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x0661,
+ },
+ [0x0662]={
+ adobename="twohackarabic",
+ category="nd",
+ description="ARABIC-INDIC DIGIT TWO",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x0662,
+ },
+ [0x0663]={
+ adobename="threehackarabic",
+ category="nd",
+ description="ARABIC-INDIC DIGIT THREE",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x0663,
+ },
+ [0x0664]={
+ adobename="fourhackarabic",
+ category="nd",
+ description="ARABIC-INDIC DIGIT FOUR",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x0664,
+ },
+ [0x0665]={
+ adobename="fivehackarabic",
+ category="nd",
+ description="ARABIC-INDIC DIGIT FIVE",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x0665,
+ },
+ [0x0666]={
+ adobename="sixhackarabic",
+ category="nd",
+ description="ARABIC-INDIC DIGIT SIX",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x0666,
+ },
+ [0x0667]={
+ adobename="sevenhackarabic",
+ category="nd",
+ description="ARABIC-INDIC DIGIT SEVEN",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x0667,
+ },
+ [0x0668]={
+ adobename="eighthackarabic",
+ category="nd",
+ description="ARABIC-INDIC DIGIT EIGHT",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x0668,
+ },
+ [0x0669]={
+ adobename="ninehackarabic",
+ category="nd",
+ description="ARABIC-INDIC DIGIT NINE",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x0669,
+ },
+ [0x066A]={
+ adobename="percentarabic",
+ category="po",
+ description="ARABIC PERCENT SIGN",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x066A,
+ },
+ [0x066B]={
+ adobename="decimalseparatorpersian",
+ category="po",
+ description="ARABIC DECIMAL SEPARATOR",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x066B,
+ },
+ [0x066C]={
+ adobename="thousandsseparatorpersian",
+ category="po",
+ description="ARABIC THOUSANDS SEPARATOR",
+ direction="an",
+ linebreak="nu",
+ unicodeslot=0x066C,
+ },
+ [0x066D]={
+ adobename="asteriskarabic",
+ category="po",
+ description="ARABIC FIVE POINTED STAR",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x066D,
+ },
+ [0x066E]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER DOTLESS BEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x066E,
+ },
+ [0x066F]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER DOTLESS QAF",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x066F,
+ },
+ [0x0670]={
+ category="mn",
+ description="ARABIC LETTER SUPERSCRIPT ALEF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0670,
+ },
+ [0x0671]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER ALEF WASLA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0671,
+ },
+ [0x0672]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0627,
+ unicodeslot=0x0672,
+ },
+ [0x0673]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER ALEF WITH WAVY HAMZA BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0627,
+ unicodeslot=0x0673,
+ },
+ [0x0674]={
+ arabic="u",
+ category="lo",
+ description="ARABIC LETTER HIGH HAMZA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0674,
+ },
+ [0x0675]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER HIGH HAMZA ALEF",
+ direction="al",
+ linebreak="al",
+ specials={ "compat", 0x0627, 0x0674 },
+ unicodeslot=0x0675,
+ },
+ [0x0676]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER HIGH HAMZA WAW",
+ direction="al",
+ linebreak="al",
+ specials={ "compat", 0x0648, 0x0674 },
+ unicodeslot=0x0676,
+ },
+ [0x0677]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER U WITH HAMZA ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x06C7,
+ specials={ "compat", 0x06C7, 0x0674 },
+ unicodeslot=0x0677,
+ },
+ [0x0678]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HIGH HAMZA YEH",
+ direction="al",
+ linebreak="al",
+ specials={ "compat", 0x064A, 0x0674 },
+ unicodeslot=0x0678,
+ },
+ [0x0679]={
+ adobename="tteharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER TTEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0679,
+ },
+ [0x067A]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER TTEHEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x067A,
+ },
+ [0x067B]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER BEEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x067B,
+ },
+ [0x067C]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER TEH WITH RING",
+ direction="al",
+ linebreak="al",
+ shcode=0x062A,
+ unicodeslot=0x067C,
+ },
+ [0x067D]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS",
+ direction="al",
+ linebreak="al",
+ shcode=0x062A,
+ unicodeslot=0x067D,
+ },
+ [0x067E]={
+ adobename="peharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER PEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x067E,
+ },
+ [0x067F]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER TEHEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x067F,
+ },
+ [0x0680]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER BEHEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0680,
+ },
+ [0x0681]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HAH WITH HAMZA ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x062D,
+ unicodeslot=0x0681,
+ },
+ [0x0682]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x062D,
+ unicodeslot=0x0682,
+ },
+ [0x0683]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER NYEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0683,
+ },
+ [0x0684]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER DYEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0684,
+ },
+ [0x0685]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HAH WITH THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x062D,
+ unicodeslot=0x0685,
+ },
+ [0x0686]={
+ adobename="tcheharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER TCHEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0686,
+ },
+ [0x0687]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER TCHEHEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0687,
+ },
+ [0x0688]={
+ adobename="ddalarabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DDAL",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0688,
+ },
+ [0x0689]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DAL WITH RING",
+ direction="al",
+ linebreak="al",
+ shcode=0x062F,
+ unicodeslot=0x0689,
+ },
+ [0x068A]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DAL WITH DOT BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x062F,
+ unicodeslot=0x068A,
+ },
+ [0x068B]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH",
+ direction="al",
+ linebreak="al",
+ shcode=0x062F,
+ unicodeslot=0x068B,
+ },
+ [0x068C]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DAHAL",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x068C,
+ },
+ [0x068D]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DDAHAL",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x068D,
+ },
+ [0x068E]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DUL",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x068E,
+ },
+ [0x068F]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS",
+ direction="al",
+ linebreak="al",
+ shcode=0x062F,
+ unicodeslot=0x068F,
+ },
+ [0x0690]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DAL WITH FOUR DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x062F,
+ unicodeslot=0x0690,
+ },
+ [0x0691]={
+ adobename="rreharabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER RREH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0691,
+ },
+ [0x0692]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH SMALL V",
+ direction="al",
+ linebreak="al",
+ shcode=0x0631,
+ unicodeslot=0x0692,
+ },
+ [0x0693]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH RING",
+ direction="al",
+ linebreak="al",
+ shcode=0x0631,
+ unicodeslot=0x0693,
+ },
+ [0x0694]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH DOT BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0631,
+ unicodeslot=0x0694,
+ },
+ [0x0695]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH SMALL V BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0631,
+ unicodeslot=0x0695,
+ },
+ [0x0696]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0631,
+ unicodeslot=0x0696,
+ },
+ [0x0697]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH TWO DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0631,
+ unicodeslot=0x0697,
+ },
+ [0x0698]={
+ adobename="jeharabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER JEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0698,
+ },
+ [0x0699]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH FOUR DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0631,
+ unicodeslot=0x0699,
+ },
+ [0x069A]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0633,
+ unicodeslot=0x069A,
+ },
+ [0x069B]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SEEN WITH THREE DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0633,
+ unicodeslot=0x069B,
+ },
+ [0x069C]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0633,
+ unicodeslot=0x069C,
+ },
+ [0x069D]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SAD WITH TWO DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0635,
+ unicodeslot=0x069D,
+ },
+ [0x069E]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SAD WITH THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0635,
+ unicodeslot=0x069E,
+ },
+ [0x069F]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER TAH WITH THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0637,
+ unicodeslot=0x069F,
+ },
+ [0x06A0]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER AIN WITH THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0639,
+ unicodeslot=0x06A0,
+ },
+ [0x06A1]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER DOTLESS FEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06A1,
+ },
+ [0x06A2]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FEH WITH DOT MOVED BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0641,
+ unicodeslot=0x06A2,
+ },
+ [0x06A3]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FEH WITH DOT BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0641,
+ unicodeslot=0x06A3,
+ },
+ [0x06A4]={
+ adobename="veharabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER VEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06A4,
+ },
+ [0x06A5]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FEH WITH THREE DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0641,
+ unicodeslot=0x06A5,
+ },
+ [0x06A6]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER PEHEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06A6,
+ },
+ [0x06A7]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER QAF WITH DOT ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0642,
+ unicodeslot=0x06A7,
+ },
+ [0x06A8]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER QAF WITH THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0642,
+ unicodeslot=0x06A8,
+ },
+ [0x06A9]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KEHEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06A9,
+ },
+ [0x06AA]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SWASH KAF",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06AA,
+ },
+ [0x06AB]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KAF WITH RING",
+ direction="al",
+ linebreak="al",
+ shcode=0x0643,
+ unicodeslot=0x06AB,
+ },
+ [0x06AC]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KAF WITH DOT ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0643,
+ unicodeslot=0x06AC,
+ },
+ [0x06AD]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER NG",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06AD,
+ },
+ [0x06AE]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KAF WITH THREE DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0643,
+ unicodeslot=0x06AE,
+ },
+ [0x06AF]={
+ adobename="gafarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER GAF",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06AF,
+ },
+ [0x06B0]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER GAF WITH RING",
+ direction="al",
+ linebreak="al",
+ shcode=0x06AF,
+ unicodeslot=0x06B0,
+ },
+ [0x06B1]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER NGOEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06B1,
+ },
+ [0x06B2]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER GAF WITH TWO DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x06AF,
+ unicodeslot=0x06B2,
+ },
+ [0x06B3]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER GUEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06B3,
+ },
+ [0x06B4]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER GAF WITH THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x06AF,
+ unicodeslot=0x06B4,
+ },
+ [0x06B5]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER LAM WITH SMALL V",
+ direction="al",
+ linebreak="al",
+ shcode=0x0644,
+ unicodeslot=0x06B5,
+ },
+ [0x06B6]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER LAM WITH DOT ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0644,
+ unicodeslot=0x06B6,
+ },
+ [0x06B7]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER LAM WITH THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0644,
+ unicodeslot=0x06B7,
+ },
+ [0x06B8]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER LAM WITH THREE DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0644,
+ unicodeslot=0x06B8,
+ },
+ [0x06B9]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER NOON WITH DOT BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0646,
+ unicodeslot=0x06B9,
+ },
+ [0x06BA]={
+ adobename="noonghunnaarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER NOON GHUNNA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06BA,
+ },
+ [0x06BB]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER RNOON",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06BB,
+ },
+ [0x06BC]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER NOON WITH RING",
+ direction="al",
+ linebreak="al",
+ shcode=0x0646,
+ unicodeslot=0x06BC,
+ },
+ [0x06BD]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER NOON WITH THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0646,
+ unicodeslot=0x06BD,
+ },
+ [0x06BE]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HEH DOACHASHMEE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06BE,
+ },
+ [0x06BF]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER TCHEH WITH DOT ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0686,
+ unicodeslot=0x06BF,
+ },
+ [0x06C0]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER HEH WITH YEH ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0647,
+ specials={ "char", 0x06D5, 0x0654 },
+ unicodeslot=0x06C0,
+ },
+ [0x06C1]={
+ adobename="hehaltonearabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HEH GOAL",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06C1,
+ },
+ [0x06C2]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HEH GOAL WITH HAMZA ABOVE",
+ direction="al",
+ linebreak="al",
+ specials={ "char", 0x06C1, 0x0654 },
+ unicodeslot=0x06C2,
+ },
+ [0x06C3]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER TEH MARBUTA GOAL",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06C3,
+ },
+ [0x06C4]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER WAW WITH RING",
+ direction="al",
+ linebreak="al",
+ shcode=0x0648,
+ unicodeslot=0x06C4,
+ },
+ [0x06C5]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER KIRGHIZ OE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06C5,
+ },
+ [0x06C6]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER OE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06C6,
+ },
+ [0x06C7]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER U",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06C7,
+ },
+ [0x06C8]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER YU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06C8,
+ },
+ [0x06C9]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER KIRGHIZ YU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06C9,
+ },
+ [0x06CA]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER WAW WITH TWO DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0648,
+ unicodeslot=0x06CA,
+ },
+ [0x06CB]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER VE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06CB,
+ },
+ [0x06CC]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FARSI YEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06CC,
+ },
+ [0x06CD]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER YEH WITH TAIL",
+ direction="al",
+ linebreak="al",
+ shcode=0x064A,
+ unicodeslot=0x06CD,
+ },
+ [0x06CE]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER YEH WITH SMALL V",
+ direction="al",
+ linebreak="al",
+ shcode=0x064A,
+ unicodeslot=0x06CE,
+ },
+ [0x06CF]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER WAW WITH DOT ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0648,
+ unicodeslot=0x06CF,
+ },
+ [0x06D0]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER E",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06D0,
+ },
+ [0x06D1]={
+ adobename="yehthreedotsbelowarabic",
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER YEH WITH THREE DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x064A,
+ unicodeslot=0x06D1,
+ },
+ [0x06D2]={
+ adobename="yehbarreearabic",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER YEH BARREE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06D2,
+ },
+ [0x06D3]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER YEH BARREE WITH HAMZA ABOVE",
+ direction="al",
+ linebreak="al",
+ specials={ "char", 0x06D2, 0x0654 },
+ unicodeslot=0x06D3,
+ },
+ [0x06D4]={
+ category="po",
+ description="ARABIC FULL STOP",
+ direction="al",
+ linebreak="ex",
+ unicodeslot=0x06D4,
+ },
+ [0x06D5]={
+ adobename="afii57534",
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER AE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06D5,
+ },
+ [0x06D6]={
+ category="mn",
+ description="ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06D6,
+ },
+ [0x06D7]={
+ category="mn",
+ description="ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06D7,
+ },
+ [0x06D8]={
+ category="mn",
+ description="ARABIC SMALL HIGH MEEM INITIAL FORM",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06D8,
+ },
+ [0x06D9]={
+ category="mn",
+ description="ARABIC SMALL HIGH LAM ALEF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06D9,
+ },
+ [0x06DA]={
+ category="mn",
+ description="ARABIC SMALL HIGH JEEM",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06DA,
+ },
+ [0x06DB]={
+ category="mn",
+ description="ARABIC SMALL HIGH THREE DOTS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06DB,
+ },
+ [0x06DC]={
+ category="mn",
+ description="ARABIC SMALL HIGH SEEN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06DC,
+ },
+ [0x06DD]={
+ arabic="u",
+ category="cf",
+ description="ARABIC END OF AYAH",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x06DD,
+ visible="yes",
+ },
+ [0x06DE]={
+ category="me",
+ description="ARABIC START OF RUB EL HIZB",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x06DE,
+ },
+ [0x06DF]={
+ category="mn",
+ description="ARABIC SMALL HIGH ROUNDED ZERO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06DF,
+ },
+ [0x06E0]={
+ category="mn",
+ description="ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06E0,
+ },
+ [0x06E1]={
+ category="mn",
+ description="ARABIC SMALL HIGH DOTLESS HEAD OF KHAH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06E1,
+ },
+ [0x06E2]={
+ category="mn",
+ description="ARABIC SMALL HIGH MEEM ISOLATED FORM",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06E2,
+ },
+ [0x06E3]={
+ category="mn",
+ description="ARABIC SMALL LOW SEEN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06E3,
+ },
+ [0x06E4]={
+ category="mn",
+ description="ARABIC SMALL HIGH MADDA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06E4,
+ },
+ [0x06E5]={
+ category="lm",
+ description="ARABIC SMALL WAW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06E5,
+ },
+ [0x06E6]={
+ category="lm",
+ description="ARABIC SMALL YEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06E6,
+ },
+ [0x06E7]={
+ category="mn",
+ description="ARABIC SMALL HIGH YEH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06E7,
+ },
+ [0x06E8]={
+ category="mn",
+ description="ARABIC SMALL HIGH NOON",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06E8,
+ },
+ [0x06E9]={
+ category="so",
+ description="ARABIC PLACE OF SAJDAH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x06E9,
+ },
+ [0x06EA]={
+ category="mn",
+ description="ARABIC EMPTY CENTRE LOW STOP",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06EA,
+ },
+ [0x06EB]={
+ category="mn",
+ description="ARABIC EMPTY CENTRE HIGH STOP",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06EB,
+ },
+ [0x06EC]={
+ category="mn",
+ description="ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06EC,
+ },
+ [0x06ED]={
+ category="mn",
+ description="ARABIC SMALL LOW MEEM",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x06ED,
+ },
+ [0x06EE]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DAL WITH INVERTED V",
+ direction="al",
+ linebreak="al",
+ shcode=0x062F,
+ unicodeslot=0x06EE,
+ },
+ [0x06EF]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH INVERTED V",
+ direction="al",
+ linebreak="al",
+ shcode=0x0631,
+ unicodeslot=0x06EF,
+ },
+ [0x06F0]={
+ adobename="zeropersian",
+ category="nd",
+ description="EXTENDED ARABIC-INDIC DIGIT ZERO",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x06F0,
+ },
+ [0x06F1]={
+ adobename="onepersian",
+ category="nd",
+ description="EXTENDED ARABIC-INDIC DIGIT ONE",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x06F1,
+ },
+ [0x06F2]={
+ adobename="twopersian",
+ category="nd",
+ description="EXTENDED ARABIC-INDIC DIGIT TWO",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x06F2,
+ },
+ [0x06F3]={
+ adobename="threepersian",
+ category="nd",
+ description="EXTENDED ARABIC-INDIC DIGIT THREE",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x06F3,
+ },
+ [0x06F4]={
+ adobename="fourpersian",
+ category="nd",
+ description="EXTENDED ARABIC-INDIC DIGIT FOUR",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x06F4,
+ },
+ [0x06F5]={
+ adobename="fivepersian",
+ category="nd",
+ description="EXTENDED ARABIC-INDIC DIGIT FIVE",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x06F5,
+ },
+ [0x06F6]={
+ adobename="sixpersian",
+ category="nd",
+ description="EXTENDED ARABIC-INDIC DIGIT SIX",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x06F6,
+ },
+ [0x06F7]={
+ adobename="sevenpersian",
+ category="nd",
+ description="EXTENDED ARABIC-INDIC DIGIT SEVEN",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x06F7,
+ },
+ [0x06F8]={
+ adobename="eightpersian",
+ category="nd",
+ description="EXTENDED ARABIC-INDIC DIGIT EIGHT",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x06F8,
+ },
+ [0x06F9]={
+ adobename="ninepersian",
+ category="nd",
+ description="EXTENDED ARABIC-INDIC DIGIT NINE",
+ direction="en",
+ linebreak="nu",
+ unicodeslot=0x06F9,
+ },
+ [0x06FA]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SHEEN WITH DOT BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0634,
+ unicodeslot=0x06FA,
+ },
+ [0x06FB]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER DAD WITH DOT BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0636,
+ unicodeslot=0x06FB,
+ },
+ [0x06FC]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER GHAIN WITH DOT BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x063A,
+ unicodeslot=0x06FC,
+ },
+ [0x06FD]={
+ category="so",
+ description="ARABIC SIGN SINDHI AMPERSAND",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06FD,
+ },
+ [0x06FE]={
+ category="so",
+ description="ARABIC SIGN SINDHI POSTPOSITION MEN",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x06FE,
+ },
+ [0x06FF]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HEH WITH INVERTED V",
+ direction="al",
+ linebreak="al",
+ shcode=0x0647,
+ unicodeslot=0x06FF,
+ },
+ [0x0700]={
+ category="po",
+ description="SYRIAC END OF PARAGRAPH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0700,
+ },
+ [0x0701]={
+ category="po",
+ description="SYRIAC SUPRALINEAR FULL STOP",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0701,
+ },
+ [0x0702]={
+ category="po",
+ description="SYRIAC SUBLINEAR FULL STOP",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0702,
+ },
+ [0x0703]={
+ category="po",
+ description="SYRIAC SUPRALINEAR COLON",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0703,
+ },
+ [0x0704]={
+ category="po",
+ description="SYRIAC SUBLINEAR COLON",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0704,
+ },
+ [0x0705]={
+ category="po",
+ description="SYRIAC HORIZONTAL COLON",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0705,
+ },
+ [0x0706]={
+ category="po",
+ description="SYRIAC COLON SKEWED LEFT",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0706,
+ },
+ [0x0707]={
+ category="po",
+ description="SYRIAC COLON SKEWED RIGHT",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0707,
+ },
+ [0x0708]={
+ category="po",
+ description="SYRIAC SUPRALINEAR COLON SKEWED LEFT",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0708,
+ },
+ [0x0709]={
+ category="po",
+ description="SYRIAC SUBLINEAR COLON SKEWED RIGHT",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0709,
+ },
+ [0x070A]={
+ category="po",
+ description="SYRIAC CONTRACTION",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x070A,
+ },
+ [0x070B]={
+ category="po",
+ description="SYRIAC HARKLEAN OBELUS",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x070B,
+ },
+ [0x070C]={
+ category="po",
+ description="SYRIAC HARKLEAN METOBELUS",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x070C,
+ },
+ [0x070D]={
+ category="po",
+ description="SYRIAC HARKLEAN ASTERISCUS",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x070D,
+ },
+ [0x070F]={
+ category="cf",
+ description="SYRIAC ABBREVIATION MARK",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x070F,
+ visible="yes",
+ },
+ [0x0710]={
+ arabic="r",
+ category="lo",
+ description="SYRIAC LETTER ALAPH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0710,
+ },
+ [0x0711]={
+ category="mn",
+ description="SYRIAC LETTER SUPERSCRIPT ALAPH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0711,
+ },
+ [0x0712]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER BETH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0712,
+ },
+ [0x0713]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER GAMAL",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0713,
+ },
+ [0x0714]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER GAMAL GARSHUNI",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0714,
+ },
+ [0x0715]={
+ arabic="r",
+ category="lo",
+ description="SYRIAC LETTER DALATH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0715,
+ },
+ [0x0716]={
+ arabic="r",
+ category="lo",
+ description="SYRIAC LETTER DOTLESS DALATH RISH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0716,
+ },
+ [0x0717]={
+ arabic="r",
+ category="lo",
+ description="SYRIAC LETTER HE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0717,
+ },
+ [0x0718]={
+ arabic="r",
+ category="lo",
+ description="SYRIAC LETTER WAW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0718,
+ },
+ [0x0719]={
+ arabic="r",
+ category="lo",
+ description="SYRIAC LETTER ZAIN",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0719,
+ },
+ [0x071A]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER HETH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x071A,
+ },
+ [0x071B]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER TETH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x071B,
+ },
+ [0x071C]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER TETH GARSHUNI",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x071C,
+ },
+ [0x071D]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER YUDH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x071D,
+ },
+ [0x071E]={
+ arabic="r",
+ category="lo",
+ description="SYRIAC LETTER YUDH HE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x071E,
+ },
+ [0x071F]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER KAPH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x071F,
+ },
+ [0x0720]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER LAMADH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0720,
+ },
+ [0x0721]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER MIM",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0721,
+ },
+ [0x0722]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER NUN",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0722,
+ },
+ [0x0723]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER SEMKATH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0723,
+ },
+ [0x0724]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER FINAL SEMKATH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0724,
+ },
+ [0x0725]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER E",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0725,
+ },
+ [0x0726]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER PE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0726,
+ },
+ [0x0727]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER REVERSED PE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0727,
+ },
+ [0x0728]={
+ arabic="r",
+ category="lo",
+ description="SYRIAC LETTER SADHE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0728,
+ },
+ [0x0729]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER QAPH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0729,
+ },
+ [0x072A]={
+ arabic="r",
+ category="lo",
+ description="SYRIAC LETTER RISH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x072A,
+ },
+ [0x072B]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER SHIN",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x072B,
+ },
+ [0x072C]={
+ arabic="r",
+ category="lo",
+ description="SYRIAC LETTER TAW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x072C,
+ },
+ [0x072D]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER PERSIAN BHETH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x072D,
+ },
+ [0x072E]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER PERSIAN GHAMAL",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x072E,
+ },
+ [0x072F]={
+ arabic="r",
+ category="lo",
+ description="SYRIAC LETTER PERSIAN DHALATH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x072F,
+ },
+ [0x0730]={
+ category="mn",
+ description="SYRIAC PTHAHA ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0730,
+ },
+ [0x0731]={
+ category="mn",
+ description="SYRIAC PTHAHA BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0731,
+ },
+ [0x0732]={
+ category="mn",
+ description="SYRIAC PTHAHA DOTTED",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0732,
+ },
+ [0x0733]={
+ category="mn",
+ description="SYRIAC ZQAPHA ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0733,
+ },
+ [0x0734]={
+ category="mn",
+ description="SYRIAC ZQAPHA BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0734,
+ },
+ [0x0735]={
+ category="mn",
+ description="SYRIAC ZQAPHA DOTTED",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0735,
+ },
+ [0x0736]={
+ category="mn",
+ description="SYRIAC RBASA ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0736,
+ },
+ [0x0737]={
+ category="mn",
+ description="SYRIAC RBASA BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0737,
+ },
+ [0x0738]={
+ category="mn",
+ description="SYRIAC DOTTED ZLAMA HORIZONTAL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0738,
+ },
+ [0x0739]={
+ category="mn",
+ description="SYRIAC DOTTED ZLAMA ANGULAR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0739,
+ },
+ [0x073A]={
+ category="mn",
+ description="SYRIAC HBASA ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x073A,
+ },
+ [0x073B]={
+ category="mn",
+ description="SYRIAC HBASA BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x073B,
+ },
+ [0x073C]={
+ category="mn",
+ description="SYRIAC HBASA-ESASA DOTTED",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x073C,
+ },
+ [0x073D]={
+ category="mn",
+ description="SYRIAC ESASA ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x073D,
+ },
+ [0x073E]={
+ category="mn",
+ description="SYRIAC ESASA BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x073E,
+ },
+ [0x073F]={
+ category="mn",
+ description="SYRIAC RWAHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x073F,
+ },
+ [0x0740]={
+ category="mn",
+ description="SYRIAC FEMININE DOT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0740,
+ },
+ [0x0741]={
+ category="mn",
+ description="SYRIAC QUSHSHAYA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0741,
+ },
+ [0x0742]={
+ category="mn",
+ description="SYRIAC RUKKAKHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0742,
+ },
+ [0x0743]={
+ category="mn",
+ description="SYRIAC TWO VERTICAL DOTS ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0743,
+ },
+ [0x0744]={
+ category="mn",
+ description="SYRIAC TWO VERTICAL DOTS BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0744,
+ },
+ [0x0745]={
+ category="mn",
+ description="SYRIAC THREE DOTS ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0745,
+ },
+ [0x0746]={
+ category="mn",
+ description="SYRIAC THREE DOTS BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0746,
+ },
+ [0x0747]={
+ category="mn",
+ description="SYRIAC OBLIQUE LINE ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0747,
+ },
+ [0x0748]={
+ category="mn",
+ description="SYRIAC OBLIQUE LINE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0748,
+ },
+ [0x0749]={
+ category="mn",
+ description="SYRIAC MUSIC",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0749,
+ },
+ [0x074A]={
+ category="mn",
+ description="SYRIAC BARREKH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x074A,
+ },
+ [0x074D]={
+ arabic="r",
+ category="lo",
+ description="SYRIAC LETTER SOGDIAN ZHAIN",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x074D,
+ },
+ [0x074E]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER SOGDIAN KHAPH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x074E,
+ },
+ [0x074F]={
+ arabic="d",
+ category="lo",
+ description="SYRIAC LETTER SOGDIAN FE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x074F,
+ },
+ [0x0750]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0628,
+ unicodeslot=0x0750,
+ },
+ [0x0751]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0628,
+ unicodeslot=0x0751,
+ },
+ [0x0752]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0628,
+ unicodeslot=0x0752,
+ },
+ [0x0753]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0628,
+ unicodeslot=0x0753,
+ },
+ [0x0754]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0628,
+ unicodeslot=0x0754,
+ },
+ [0x0755]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER BEH WITH INVERTED SMALL V BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0628,
+ unicodeslot=0x0755,
+ },
+ [0x0756]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER BEH WITH SMALL V",
+ direction="al",
+ linebreak="al",
+ shcode=0x0628,
+ unicodeslot=0x0756,
+ },
+ [0x0757]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HAH WITH TWO DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x062D,
+ unicodeslot=0x0757,
+ },
+ [0x0758]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x062D,
+ unicodeslot=0x0758,
+ },
+ [0x0759]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH",
+ direction="al",
+ linebreak="al",
+ shcode=0x062F,
+ unicodeslot=0x0759,
+ },
+ [0x075A]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER DAL WITH INVERTED SMALL V BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x062F,
+ unicodeslot=0x075A,
+ },
+ [0x075B]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH STROKE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0631,
+ unicodeslot=0x075B,
+ },
+ [0x075C]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SEEN WITH FOUR DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0633,
+ unicodeslot=0x075C,
+ },
+ [0x075D]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER AIN WITH TWO DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0639,
+ unicodeslot=0x075D,
+ },
+ [0x075E]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0639,
+ unicodeslot=0x075E,
+ },
+ [0x075F]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0639,
+ unicodeslot=0x075F,
+ },
+ [0x0760]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FEH WITH TWO DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0641,
+ unicodeslot=0x0760,
+ },
+ [0x0761]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0641,
+ unicodeslot=0x0761,
+ },
+ [0x0762]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KEHEH WITH DOT ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x06A9,
+ unicodeslot=0x0762,
+ },
+ [0x0763]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KEHEH WITH THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x06A9,
+ unicodeslot=0x0763,
+ },
+ [0x0764]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x06A9,
+ unicodeslot=0x0764,
+ },
+ [0x0765]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER MEEM WITH DOT ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0645,
+ unicodeslot=0x0765,
+ },
+ [0x0766]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER MEEM WITH DOT BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0645,
+ unicodeslot=0x0766,
+ },
+ [0x0767]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER NOON WITH TWO DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ shcode=0x0646,
+ unicodeslot=0x0767,
+ },
+ [0x0768]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER NOON WITH SMALL TAH",
+ direction="al",
+ linebreak="al",
+ shcode=0x0646,
+ unicodeslot=0x0768,
+ },
+ [0x0769]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER NOON WITH SMALL V",
+ direction="al",
+ linebreak="al",
+ shcode=0x0646,
+ unicodeslot=0x0769,
+ },
+ [0x076A]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER LAM WITH BAR",
+ direction="al",
+ linebreak="al",
+ shcode=0x0644,
+ unicodeslot=0x076A,
+ },
+ [0x076B]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0631,
+ unicodeslot=0x076B,
+ },
+ [0x076C]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH HAMZA ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0631,
+ unicodeslot=0x076C,
+ },
+ [0x076D]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE",
+ direction="al",
+ linebreak="al",
+ shcode=0x0633,
+ unicodeslot=0x076D,
+ },
+ [0x076E]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x076E,
+ },
+ [0x076F]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH AND TWO DOTS",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x076F,
+ },
+ [0x0770]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SEEN WITH SMALL ARABIC LETTER TAH AND TWO DOTS",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0770,
+ },
+ [0x0771]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH SMALL ARABIC LETTER TAH AND TWO DOTS",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0771,
+ },
+ [0x0772]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0772,
+ },
+ [0x0773]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0773,
+ },
+ [0x0774]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0774,
+ },
+ [0x0775]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0775,
+ },
+ [0x0776]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0776,
+ },
+ [0x0777]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0777,
+ },
+ [0x0778]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0778,
+ },
+ [0x0779]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0779,
+ },
+ [0x077A]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x077A,
+ },
+ [0x077B]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x077B,
+ },
+ [0x077C]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER HAH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x077C,
+ },
+ [0x077D]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SEEN WITH EXTENDED ARABIC-INDIC DIGIT FOUR ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x077D,
+ },
+ [0x077E]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER SEEN WITH INVERTED V",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x077E,
+ },
+ [0x077F]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER KAF WITH TWO DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x077F,
+ },
+ [0x0780]={
+ category="lo",
+ description="THAANA LETTER HAA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0780,
+ },
+ [0x0781]={
+ category="lo",
+ description="THAANA LETTER SHAVIYANI",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0781,
+ },
+ [0x0782]={
+ category="lo",
+ description="THAANA LETTER NOONU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0782,
+ },
+ [0x0783]={
+ category="lo",
+ description="THAANA LETTER RAA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0783,
+ },
+ [0x0784]={
+ category="lo",
+ description="THAANA LETTER BAA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0784,
+ },
+ [0x0785]={
+ category="lo",
+ description="THAANA LETTER LHAVIYANI",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0785,
+ },
+ [0x0786]={
+ category="lo",
+ description="THAANA LETTER KAAFU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0786,
+ },
+ [0x0787]={
+ category="lo",
+ description="THAANA LETTER ALIFU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0787,
+ },
+ [0x0788]={
+ category="lo",
+ description="THAANA LETTER VAAVU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0788,
+ },
+ [0x0789]={
+ category="lo",
+ description="THAANA LETTER MEEMU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0789,
+ },
+ [0x078A]={
+ category="lo",
+ description="THAANA LETTER FAAFU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x078A,
+ },
+ [0x078B]={
+ category="lo",
+ description="THAANA LETTER DHAALU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x078B,
+ },
+ [0x078C]={
+ category="lo",
+ description="THAANA LETTER THAA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x078C,
+ },
+ [0x078D]={
+ category="lo",
+ description="THAANA LETTER LAAMU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x078D,
+ },
+ [0x078E]={
+ category="lo",
+ description="THAANA LETTER GAAFU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x078E,
+ },
+ [0x078F]={
+ category="lo",
+ description="THAANA LETTER GNAVIYANI",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x078F,
+ },
+ [0x0790]={
+ category="lo",
+ description="THAANA LETTER SEENU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0790,
+ },
+ [0x0791]={
+ category="lo",
+ description="THAANA LETTER DAVIYANI",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0791,
+ },
+ [0x0792]={
+ category="lo",
+ description="THAANA LETTER ZAVIYANI",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0792,
+ },
+ [0x0793]={
+ category="lo",
+ description="THAANA LETTER TAVIYANI",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0793,
+ },
+ [0x0794]={
+ category="lo",
+ description="THAANA LETTER YAA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0794,
+ },
+ [0x0795]={
+ category="lo",
+ description="THAANA LETTER PAVIYANI",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0795,
+ },
+ [0x0796]={
+ category="lo",
+ description="THAANA LETTER JAVIYANI",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0796,
+ },
+ [0x0797]={
+ category="lo",
+ description="THAANA LETTER CHAVIYANI",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0797,
+ },
+ [0x0798]={
+ category="lo",
+ description="THAANA LETTER TTAA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0798,
+ },
+ [0x0799]={
+ category="lo",
+ description="THAANA LETTER HHAA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x0799,
+ },
+ [0x079A]={
+ category="lo",
+ description="THAANA LETTER KHAA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x079A,
+ },
+ [0x079B]={
+ category="lo",
+ description="THAANA LETTER THAALU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x079B,
+ },
+ [0x079C]={
+ category="lo",
+ description="THAANA LETTER ZAA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x079C,
+ },
+ [0x079D]={
+ category="lo",
+ description="THAANA LETTER SHEENU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x079D,
+ },
+ [0x079E]={
+ category="lo",
+ description="THAANA LETTER SAADHU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x079E,
+ },
+ [0x079F]={
+ category="lo",
+ description="THAANA LETTER DAADHU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x079F,
+ },
+ [0x07A0]={
+ category="lo",
+ description="THAANA LETTER TO",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x07A0,
+ },
+ [0x07A1]={
+ category="lo",
+ description="THAANA LETTER ZO",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x07A1,
+ },
+ [0x07A2]={
+ category="lo",
+ description="THAANA LETTER AINU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x07A2,
+ },
+ [0x07A3]={
+ category="lo",
+ description="THAANA LETTER GHAINU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x07A3,
+ },
+ [0x07A4]={
+ category="lo",
+ description="THAANA LETTER QAAFU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x07A4,
+ },
+ [0x07A5]={
+ category="lo",
+ description="THAANA LETTER WAAVU",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x07A5,
+ },
+ [0x07A6]={
+ category="mn",
+ description="THAANA ABAFILI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07A6,
+ },
+ [0x07A7]={
+ category="mn",
+ description="THAANA AABAAFILI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07A7,
+ },
+ [0x07A8]={
+ category="mn",
+ description="THAANA IBIFILI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07A8,
+ },
+ [0x07A9]={
+ category="mn",
+ description="THAANA EEBEEFILI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07A9,
+ },
+ [0x07AA]={
+ category="mn",
+ description="THAANA UBUFILI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07AA,
+ },
+ [0x07AB]={
+ category="mn",
+ description="THAANA OOBOOFILI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07AB,
+ },
+ [0x07AC]={
+ category="mn",
+ description="THAANA EBEFILI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07AC,
+ },
+ [0x07AD]={
+ category="mn",
+ description="THAANA EYBEYFILI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07AD,
+ },
+ [0x07AE]={
+ category="mn",
+ description="THAANA OBOFILI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07AE,
+ },
+ [0x07AF]={
+ category="mn",
+ description="THAANA OABOAFILI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07AF,
+ },
+ [0x07B0]={
+ category="mn",
+ description="THAANA SUKUN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07B0,
+ },
+ [0x07B1]={
+ category="lo",
+ description="THAANA LETTER NAA",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x07B1,
+ },
+ [0x07C0]={
+ category="nd",
+ description="NKO DIGIT ZERO",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x07C0,
+ },
+ [0x07C1]={
+ category="nd",
+ description="NKO DIGIT ONE",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x07C1,
+ },
+ [0x07C2]={
+ category="nd",
+ description="NKO DIGIT TWO",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x07C2,
+ },
+ [0x07C3]={
+ category="nd",
+ description="NKO DIGIT THREE",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x07C3,
+ },
+ [0x07C4]={
+ category="nd",
+ description="NKO DIGIT FOUR",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x07C4,
+ },
+ [0x07C5]={
+ category="nd",
+ description="NKO DIGIT FIVE",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x07C5,
+ },
+ [0x07C6]={
+ category="nd",
+ description="NKO DIGIT SIX",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x07C6,
+ },
+ [0x07C7]={
+ category="nd",
+ description="NKO DIGIT SEVEN",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x07C7,
+ },
+ [0x07C8]={
+ category="nd",
+ description="NKO DIGIT EIGHT",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x07C8,
+ },
+ [0x07C9]={
+ category="nd",
+ description="NKO DIGIT NINE",
+ direction="r",
+ linebreak="nu",
+ unicodeslot=0x07C9,
+ },
+ [0x07CA]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER A",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07CA,
+ },
+ [0x07CB]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER EE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07CB,
+ },
+ [0x07CC]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER I",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07CC,
+ },
+ [0x07CD]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER E",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07CD,
+ },
+ [0x07CE]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER U",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07CE,
+ },
+ [0x07CF]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER OO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07CF,
+ },
+ [0x07D0]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER O",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07D0,
+ },
+ [0x07D1]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER DAGBASINNA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07D1,
+ },
+ [0x07D2]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER N",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07D2,
+ },
+ [0x07D3]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER BA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07D3,
+ },
+ [0x07D4]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER PA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07D4,
+ },
+ [0x07D5]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER TA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07D5,
+ },
+ [0x07D6]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER JA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07D6,
+ },
+ [0x07D7]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER CHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07D7,
+ },
+ [0x07D8]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER DA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07D8,
+ },
+ [0x07D9]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER RA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07D9,
+ },
+ [0x07DA]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER RRA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07DA,
+ },
+ [0x07DB]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER SA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07DB,
+ },
+ [0x07DC]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER GBA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07DC,
+ },
+ [0x07DD]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER FA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07DD,
+ },
+ [0x07DE]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER KA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07DE,
+ },
+ [0x07DF]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER LA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07DF,
+ },
+ [0x07E0]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER NA WOLOSO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07E0,
+ },
+ [0x07E1]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER MA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07E1,
+ },
+ [0x07E2]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER NYA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07E2,
+ },
+ [0x07E3]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER NA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07E3,
+ },
+ [0x07E4]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER HA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07E4,
+ },
+ [0x07E5]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER WA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07E5,
+ },
+ [0x07E6]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER YA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07E6,
+ },
+ [0x07E7]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER NYA WOLOSO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07E7,
+ },
+ [0x07E8]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER JONA JA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07E8,
+ },
+ [0x07E9]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER JONA CHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07E9,
+ },
+ [0x07EA]={
+ arabic="d",
+ category="lo",
+ description="NKO LETTER JONA RA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07EA,
+ },
+ [0x07EB]={
+ category="mn",
+ description="NKO COMBINING SHORT HIGH TONE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07EB,
+ },
+ [0x07EC]={
+ category="mn",
+ description="NKO COMBINING SHORT LOW TONE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07EC,
+ },
+ [0x07ED]={
+ category="mn",
+ description="NKO COMBINING SHORT RISING TONE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07ED,
+ },
+ [0x07EE]={
+ category="mn",
+ description="NKO COMBINING LONG DESCENDING TONE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07EE,
+ },
+ [0x07EF]={
+ category="mn",
+ description="NKO COMBINING LONG HIGH TONE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07EF,
+ },
+ [0x07F0]={
+ category="mn",
+ description="NKO COMBINING LONG LOW TONE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07F0,
+ },
+ [0x07F1]={
+ category="mn",
+ description="NKO COMBINING LONG RISING TONE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07F1,
+ },
+ [0x07F2]={
+ category="mn",
+ description="NKO COMBINING NASALIZATION MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07F2,
+ },
+ [0x07F3]={
+ category="mn",
+ description="NKO COMBINING DOUBLE DOT ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x07F3,
+ },
+ [0x07F4]={
+ category="lm",
+ description="NKO HIGH TONE APOSTROPHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07F4,
+ },
+ [0x07F5]={
+ category="lm",
+ description="NKO LOW TONE APOSTROPHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07F5,
+ },
+ [0x07F6]={
+ category="so",
+ description="NKO SYMBOL OO DENNEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x07F6,
+ },
+ [0x07F7]={
+ category="po",
+ description="NKO SYMBOL GBAKURUNEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x07F7,
+ },
+ [0x07F8]={
+ category="po",
+ description="NKO COMMA",
+ direction="on",
+ linebreak="is",
+ unicodeslot=0x07F8,
+ },
+ [0x07F9]={
+ category="po",
+ description="NKO EXCLAMATION MARK",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x07F9,
+ },
+ [0x07FA]={
+ arabic="c",
+ category="lm",
+ description="NKO LAJANYALAN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x07FA,
+ },
+ [0x0800]={
+ category="lo",
+ description="SAMARITAN LETTER ALAF",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0800,
+ },
+ [0x0801]={
+ category="lo",
+ description="SAMARITAN LETTER BIT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0801,
+ },
+ [0x0802]={
+ category="lo",
+ description="SAMARITAN LETTER GAMAN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0802,
+ },
+ [0x0803]={
+ category="lo",
+ description="SAMARITAN LETTER DALAT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0803,
+ },
+ [0x0804]={
+ category="lo",
+ description="SAMARITAN LETTER IY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0804,
+ },
+ [0x0805]={
+ category="lo",
+ description="SAMARITAN LETTER BAA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0805,
+ },
+ [0x0806]={
+ category="lo",
+ description="SAMARITAN LETTER ZEN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0806,
+ },
+ [0x0807]={
+ category="lo",
+ description="SAMARITAN LETTER IT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0807,
+ },
+ [0x0808]={
+ category="lo",
+ description="SAMARITAN LETTER TIT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0808,
+ },
+ [0x0809]={
+ category="lo",
+ description="SAMARITAN LETTER YUT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0809,
+ },
+ [0x080A]={
+ category="lo",
+ description="SAMARITAN LETTER KAAF",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x080A,
+ },
+ [0x080B]={
+ category="lo",
+ description="SAMARITAN LETTER LABAT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x080B,
+ },
+ [0x080C]={
+ category="lo",
+ description="SAMARITAN LETTER MIM",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x080C,
+ },
+ [0x080D]={
+ category="lo",
+ description="SAMARITAN LETTER NUN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x080D,
+ },
+ [0x080E]={
+ category="lo",
+ description="SAMARITAN LETTER SINGAAT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x080E,
+ },
+ [0x080F]={
+ category="lo",
+ description="SAMARITAN LETTER IN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x080F,
+ },
+ [0x0810]={
+ category="lo",
+ description="SAMARITAN LETTER FI",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0810,
+ },
+ [0x0811]={
+ category="lo",
+ description="SAMARITAN LETTER TSAADIY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0811,
+ },
+ [0x0812]={
+ category="lo",
+ description="SAMARITAN LETTER QUF",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0812,
+ },
+ [0x0813]={
+ category="lo",
+ description="SAMARITAN LETTER RISH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0813,
+ },
+ [0x0814]={
+ category="lo",
+ description="SAMARITAN LETTER SHAN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0814,
+ },
+ [0x0815]={
+ category="lo",
+ description="SAMARITAN LETTER TAAF",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0815,
+ },
+ [0x0816]={
+ category="mn",
+ description="SAMARITAN MARK IN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0816,
+ },
+ [0x0817]={
+ category="mn",
+ description="SAMARITAN MARK IN-ALAF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0817,
+ },
+ [0x0818]={
+ category="mn",
+ description="SAMARITAN MARK OCCLUSION",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0818,
+ },
+ [0x0819]={
+ category="mn",
+ description="SAMARITAN MARK DAGESH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0819,
+ },
+ [0x081A]={
+ category="lm",
+ description="SAMARITAN MODIFIER LETTER EPENTHETIC YUT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x081A,
+ },
+ [0x081B]={
+ category="mn",
+ description="SAMARITAN MARK EPENTHETIC YUT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x081B,
+ },
+ [0x081C]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN LONG E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x081C,
+ },
+ [0x081D]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x081D,
+ },
+ [0x081E]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN OVERLONG AA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x081E,
+ },
+ [0x081F]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN LONG AA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x081F,
+ },
+ [0x0820]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN AA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0820,
+ },
+ [0x0821]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN OVERLONG A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0821,
+ },
+ [0x0822]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN LONG A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0822,
+ },
+ [0x0823]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0823,
+ },
+ [0x0824]={
+ category="lm",
+ description="SAMARITAN MODIFIER LETTER SHORT A",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0824,
+ },
+ [0x0825]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN SHORT A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0825,
+ },
+ [0x0826]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN LONG U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0826,
+ },
+ [0x0827]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0827,
+ },
+ [0x0828]={
+ category="lm",
+ description="SAMARITAN MODIFIER LETTER I",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0828,
+ },
+ [0x0829]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN LONG I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0829,
+ },
+ [0x082A]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x082A,
+ },
+ [0x082B]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x082B,
+ },
+ [0x082C]={
+ category="mn",
+ description="SAMARITAN VOWEL SIGN SUKUN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x082C,
+ },
+ [0x082D]={
+ category="mn",
+ description="SAMARITAN MARK NEQUDAA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x082D,
+ },
+ [0x0830]={
+ category="po",
+ description="SAMARITAN PUNCTUATION NEQUDAA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0830,
+ },
+ [0x0831]={
+ category="po",
+ description="SAMARITAN PUNCTUATION AFSAAQ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0831,
+ },
+ [0x0832]={
+ category="po",
+ description="SAMARITAN PUNCTUATION ANGED",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0832,
+ },
+ [0x0833]={
+ category="po",
+ description="SAMARITAN PUNCTUATION BAU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0833,
+ },
+ [0x0834]={
+ category="po",
+ description="SAMARITAN PUNCTUATION ATMAAU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0834,
+ },
+ [0x0835]={
+ category="po",
+ description="SAMARITAN PUNCTUATION SHIYYAALAA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0835,
+ },
+ [0x0836]={
+ category="po",
+ description="SAMARITAN ABBREVIATION MARK",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0836,
+ },
+ [0x0837]={
+ category="po",
+ description="SAMARITAN PUNCTUATION MELODIC QITSA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0837,
+ },
+ [0x0838]={
+ category="po",
+ description="SAMARITAN PUNCTUATION ZIQAA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0838,
+ },
+ [0x0839]={
+ category="po",
+ description="SAMARITAN PUNCTUATION QITSA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0839,
+ },
+ [0x083A]={
+ category="po",
+ description="SAMARITAN PUNCTUATION ZAEF",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x083A,
+ },
+ [0x083B]={
+ category="po",
+ description="SAMARITAN PUNCTUATION TURU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x083B,
+ },
+ [0x083C]={
+ category="po",
+ description="SAMARITAN PUNCTUATION ARKAANU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x083C,
+ },
+ [0x083D]={
+ category="po",
+ description="SAMARITAN PUNCTUATION SOF MASHFAAT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x083D,
+ },
+ [0x083E]={
+ category="po",
+ description="SAMARITAN PUNCTUATION ANNAAU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x083E,
+ },
+ [0x0840]={
+ arabic="r",
+ category="lo",
+ description="MANDAIC LETTER HALQA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0840,
+ },
+ [0x0841]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AB",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0841,
+ },
+ [0x0842]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AG",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0842,
+ },
+ [0x0843]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AD",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0843,
+ },
+ [0x0844]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0844,
+ },
+ [0x0845]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER USHENNA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0845,
+ },
+ [0x0846]={
+ arabic="r",
+ category="lo",
+ description="MANDAIC LETTER AZ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0846,
+ },
+ [0x0847]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER IT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0847,
+ },
+ [0x0848]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER ATT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0848,
+ },
+ [0x0849]={
+ arabic="r",
+ category="lo",
+ description="MANDAIC LETTER AKSA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0849,
+ },
+ [0x084A]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AK",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x084A,
+ },
+ [0x084B]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AL",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x084B,
+ },
+ [0x084C]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AM",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x084C,
+ },
+ [0x084D]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x084D,
+ },
+ [0x084E]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AS",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x084E,
+ },
+ [0x084F]={
+ arabic="r",
+ category="lo",
+ description="MANDAIC LETTER IN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x084F,
+ },
+ [0x0850]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AP",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0850,
+ },
+ [0x0851]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER ASZ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0851,
+ },
+ [0x0852]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AQ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0852,
+ },
+ [0x0853]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AR",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0853,
+ },
+ [0x0854]={
+ arabic="r",
+ category="lo",
+ description="MANDAIC LETTER ASH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0854,
+ },
+ [0x0855]={
+ arabic="d",
+ category="lo",
+ description="MANDAIC LETTER AT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0855,
+ },
+ [0x0856]={
+ arabic="u",
+ category="lo",
+ description="MANDAIC LETTER DUSHENNA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0856,
+ },
+ [0x0857]={
+ arabic="u",
+ category="lo",
+ description="MANDAIC LETTER KAD",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0857,
+ },
+ [0x0858]={
+ arabic="u",
+ category="lo",
+ description="MANDAIC LETTER AIN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x0858,
+ },
+ [0x0859]={
+ category="mn",
+ description="MANDAIC AFFRICATION MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0859,
+ },
+ [0x085A]={
+ category="mn",
+ description="MANDAIC VOCALIZATION MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x085A,
+ },
+ [0x085B]={
+ category="mn",
+ description="MANDAIC GEMINATION MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x085B,
+ },
+ [0x085E]={
+ category="po",
+ description="MANDAIC PUNCTUATION",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x085E,
+ },
+ [0x08A0]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER BEH WITH SMALL V BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x08A0,
+ },
+ [0x08A2]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER JEEM WITH TWO DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x08A2,
+ },
+ [0x08A3]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER TAH WITH TWO DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x08A3,
+ },
+ [0x08A4]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER FEH WITH DOT BELOW AND THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x08A4,
+ },
+ [0x08A5]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER QAF WITH DOT BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x08A5,
+ },
+ [0x08A6]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER LAM WITH DOUBLE BAR",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x08A6,
+ },
+ [0x08A7]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER MEEM WITH THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x08A7,
+ },
+ [0x08A8]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER YEH WITH TWO DOTS BELOW AND HAMZA ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x08A8,
+ },
+ [0x08A9]={
+ arabic="d",
+ category="lo",
+ description="ARABIC LETTER YEH WITH TWO DOTS BELOW AND DOT ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x08A9,
+ },
+ [0x08AA]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER REH WITH LOOP",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x08AA,
+ },
+ [0x08AB]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER WAW WITH DOT WITHIN",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x08AB,
+ },
+ [0x08AC]={
+ arabic="r",
+ category="lo",
+ description="ARABIC LETTER ROHINGYA YEH",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x08AC,
+ },
+ [0x08E4]={
+ category="mn",
+ description="ARABIC CURLY FATHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08E4,
+ },
+ [0x08E5]={
+ category="mn",
+ description="ARABIC CURLY DAMMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08E5,
+ },
+ [0x08E6]={
+ category="mn",
+ description="ARABIC CURLY KASRA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08E6,
+ },
+ [0x08E7]={
+ category="mn",
+ description="ARABIC CURLY FATHATAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08E7,
+ },
+ [0x08E8]={
+ category="mn",
+ description="ARABIC CURLY DAMMATAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08E8,
+ },
+ [0x08E9]={
+ category="mn",
+ description="ARABIC CURLY KASRATAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08E9,
+ },
+ [0x08EA]={
+ category="mn",
+ description="ARABIC TONE ONE DOT ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08EA,
+ },
+ [0x08EB]={
+ category="mn",
+ description="ARABIC TONE TWO DOTS ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08EB,
+ },
+ [0x08EC]={
+ category="mn",
+ description="ARABIC TONE LOOP ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08EC,
+ },
+ [0x08ED]={
+ category="mn",
+ description="ARABIC TONE ONE DOT BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08ED,
+ },
+ [0x08EE]={
+ category="mn",
+ description="ARABIC TONE TWO DOTS BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08EE,
+ },
+ [0x08EF]={
+ category="mn",
+ description="ARABIC TONE LOOP BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08EF,
+ },
+ [0x08F0]={
+ category="mn",
+ description="ARABIC OPEN FATHATAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08F0,
+ },
+ [0x08F1]={
+ category="mn",
+ description="ARABIC OPEN DAMMATAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08F1,
+ },
+ [0x08F2]={
+ category="mn",
+ description="ARABIC OPEN KASRATAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08F2,
+ },
+ [0x08F3]={
+ category="mn",
+ description="ARABIC SMALL HIGH WAW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08F3,
+ },
+ [0x08F4]={
+ category="mn",
+ description="ARABIC FATHA WITH RING",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08F4,
+ },
+ [0x08F5]={
+ category="mn",
+ description="ARABIC FATHA WITH DOT ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08F5,
+ },
+ [0x08F6]={
+ category="mn",
+ description="ARABIC KASRA WITH DOT BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08F6,
+ },
+ [0x08F7]={
+ category="mn",
+ description="ARABIC LEFT ARROWHEAD ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08F7,
+ },
+ [0x08F8]={
+ category="mn",
+ description="ARABIC RIGHT ARROWHEAD ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08F8,
+ },
+ [0x08F9]={
+ category="mn",
+ description="ARABIC LEFT ARROWHEAD BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08F9,
+ },
+ [0x08FA]={
+ category="mn",
+ description="ARABIC RIGHT ARROWHEAD BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08FA,
+ },
+ [0x08FB]={
+ category="mn",
+ description="ARABIC DOUBLE RIGHT ARROWHEAD ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08FB,
+ },
+ [0x08FC]={
+ category="mn",
+ description="ARABIC DOUBLE RIGHT ARROWHEAD ABOVE WITH DOT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08FC,
+ },
+ [0x08FD]={
+ category="mn",
+ description="ARABIC RIGHT ARROWHEAD ABOVE WITH DOT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08FD,
+ },
+ [0x08FE]={
+ category="mn",
+ description="ARABIC DAMMA WITH DOT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x08FE,
+ },
+ [0x0900]={
+ category="mn",
+ description="DEVANAGARI SIGN INVERTED CANDRABINDU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0900,
+ },
+ [0x0901]={
+ adobename="candrabindudeva",
+ category="mn",
+ description="DEVANAGARI SIGN CANDRABINDU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0901,
+ },
+ [0x0902]={
+ adobename="anusvaradeva",
+ category="mn",
+ description="DEVANAGARI SIGN ANUSVARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0902,
+ },
+ [0x0903]={
+ adobename="visargadeva",
+ category="mc",
+ description="DEVANAGARI SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0903,
+ },
+ [0x0904]={
+ category="lo",
+ description="DEVANAGARI LETTER SHORT A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0904,
+ },
+ [0x0905]={
+ adobename="adeva",
+ category="lo",
+ description="DEVANAGARI LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0905,
+ },
+ [0x0906]={
+ adobename="aadeva",
+ category="lo",
+ description="DEVANAGARI LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0906,
+ },
+ [0x0907]={
+ adobename="ideva",
+ category="lo",
+ description="DEVANAGARI LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0907,
+ },
+ [0x0908]={
+ adobename="iideva",
+ category="lo",
+ description="DEVANAGARI LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0908,
+ },
+ [0x0909]={
+ adobename="udeva",
+ category="lo",
+ description="DEVANAGARI LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0909,
+ },
+ [0x090A]={
+ adobename="uudeva",
+ category="lo",
+ description="DEVANAGARI LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x090A,
+ },
+ [0x090B]={
+ adobename="rvocalicdeva",
+ category="lo",
+ description="DEVANAGARI LETTER VOCALIC R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x090B,
+ },
+ [0x090C]={
+ adobename="lvocalicdeva",
+ category="lo",
+ description="DEVANAGARI LETTER VOCALIC L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x090C,
+ },
+ [0x090D]={
+ adobename="ecandradeva",
+ category="lo",
+ description="DEVANAGARI LETTER CANDRA E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x090D,
+ },
+ [0x090E]={
+ adobename="eshortdeva",
+ category="lo",
+ description="DEVANAGARI LETTER SHORT E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x090E,
+ },
+ [0x090F]={
+ adobename="edeva",
+ category="lo",
+ description="DEVANAGARI LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x090F,
+ },
+ [0x0910]={
+ adobename="aideva",
+ category="lo",
+ description="DEVANAGARI LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0910,
+ },
+ [0x0911]={
+ adobename="ocandradeva",
+ category="lo",
+ description="DEVANAGARI LETTER CANDRA O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0911,
+ },
+ [0x0912]={
+ adobename="oshortdeva",
+ category="lo",
+ description="DEVANAGARI LETTER SHORT O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0912,
+ },
+ [0x0913]={
+ adobename="odeva",
+ category="lo",
+ description="DEVANAGARI LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0913,
+ },
+ [0x0914]={
+ adobename="audeva",
+ category="lo",
+ description="DEVANAGARI LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0914,
+ },
+ [0x0915]={
+ adobename="kadeva",
+ category="lo",
+ description="DEVANAGARI LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0915,
+ },
+ [0x0916]={
+ adobename="khadeva",
+ category="lo",
+ description="DEVANAGARI LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0916,
+ },
+ [0x0917]={
+ adobename="gadeva",
+ category="lo",
+ description="DEVANAGARI LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0917,
+ },
+ [0x0918]={
+ adobename="ghadeva",
+ category="lo",
+ description="DEVANAGARI LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0918,
+ },
+ [0x0919]={
+ adobename="ngadeva",
+ category="lo",
+ description="DEVANAGARI LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0919,
+ },
+ [0x091A]={
+ adobename="cadeva",
+ category="lo",
+ description="DEVANAGARI LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x091A,
+ },
+ [0x091B]={
+ adobename="chadeva",
+ category="lo",
+ description="DEVANAGARI LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x091B,
+ },
+ [0x091C]={
+ adobename="jadeva",
+ category="lo",
+ description="DEVANAGARI LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x091C,
+ },
+ [0x091D]={
+ adobename="jhadeva",
+ category="lo",
+ description="DEVANAGARI LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x091D,
+ },
+ [0x091E]={
+ adobename="nyadeva",
+ category="lo",
+ description="DEVANAGARI LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x091E,
+ },
+ [0x091F]={
+ adobename="ttadeva",
+ category="lo",
+ description="DEVANAGARI LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x091F,
+ },
+ [0x0920]={
+ adobename="tthadeva",
+ category="lo",
+ description="DEVANAGARI LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0920,
+ },
+ [0x0921]={
+ adobename="ddadeva",
+ category="lo",
+ description="DEVANAGARI LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0921,
+ },
+ [0x0922]={
+ adobename="ddhadeva",
+ category="lo",
+ description="DEVANAGARI LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0922,
+ },
+ [0x0923]={
+ adobename="nnadeva",
+ category="lo",
+ description="DEVANAGARI LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0923,
+ },
+ [0x0924]={
+ adobename="tadeva",
+ category="lo",
+ description="DEVANAGARI LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0924,
+ },
+ [0x0925]={
+ adobename="thadeva",
+ category="lo",
+ description="DEVANAGARI LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0925,
+ },
+ [0x0926]={
+ adobename="dadeva",
+ category="lo",
+ description="DEVANAGARI LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0926,
+ },
+ [0x0927]={
+ adobename="dhadeva",
+ category="lo",
+ description="DEVANAGARI LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0927,
+ },
+ [0x0928]={
+ adobename="nadeva",
+ category="lo",
+ description="DEVANAGARI LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0928,
+ },
+ [0x0929]={
+ adobename="nnnadeva",
+ category="lo",
+ description="DEVANAGARI LETTER NNNA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0928, 0x093C },
+ unicodeslot=0x0929,
+ },
+ [0x092A]={
+ adobename="padeva",
+ category="lo",
+ description="DEVANAGARI LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x092A,
+ },
+ [0x092B]={
+ adobename="phadeva",
+ category="lo",
+ description="DEVANAGARI LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x092B,
+ },
+ [0x092C]={
+ adobename="badeva",
+ category="lo",
+ description="DEVANAGARI LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x092C,
+ },
+ [0x092D]={
+ adobename="bhadeva",
+ category="lo",
+ description="DEVANAGARI LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x092D,
+ },
+ [0x092E]={
+ adobename="madeva",
+ category="lo",
+ description="DEVANAGARI LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x092E,
+ },
+ [0x092F]={
+ adobename="yadeva",
+ category="lo",
+ description="DEVANAGARI LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x092F,
+ },
+ [0x0930]={
+ adobename="radeva",
+ category="lo",
+ description="DEVANAGARI LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0930,
+ },
+ [0x0931]={
+ adobename="rradeva",
+ category="lo",
+ description="DEVANAGARI LETTER RRA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0930, 0x093C },
+ unicodeslot=0x0931,
+ },
+ [0x0932]={
+ adobename="ladeva",
+ category="lo",
+ description="DEVANAGARI LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0932,
+ },
+ [0x0933]={
+ adobename="lladeva",
+ category="lo",
+ description="DEVANAGARI LETTER LLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0933,
+ },
+ [0x0934]={
+ adobename="llladeva",
+ category="lo",
+ description="DEVANAGARI LETTER LLLA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0933, 0x093C },
+ unicodeslot=0x0934,
+ },
+ [0x0935]={
+ adobename="vadeva",
+ category="lo",
+ description="DEVANAGARI LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0935,
+ },
+ [0x0936]={
+ adobename="shadeva",
+ category="lo",
+ description="DEVANAGARI LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0936,
+ },
+ [0x0937]={
+ adobename="ssadeva",
+ category="lo",
+ description="DEVANAGARI LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0937,
+ },
+ [0x0938]={
+ adobename="sadeva",
+ category="lo",
+ description="DEVANAGARI LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0938,
+ },
+ [0x0939]={
+ adobename="hadeva",
+ category="lo",
+ description="DEVANAGARI LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0939,
+ },
+ [0x093A]={
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN OE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x093A,
+ },
+ [0x093B]={
+ category="mc",
+ description="DEVANAGARI VOWEL SIGN OOE",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x093B,
+ },
+ [0x093C]={
+ adobename="nuktadeva",
+ category="mn",
+ description="DEVANAGARI SIGN NUKTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x093C,
+ },
+ [0x093D]={
+ adobename="avagrahadeva",
+ category="lo",
+ description="DEVANAGARI SIGN AVAGRAHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x093D,
+ },
+ [0x093E]={
+ adobename="aavowelsigndeva",
+ category="mc",
+ description="DEVANAGARI VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x093E,
+ },
+ [0x093F]={
+ adobename="ivowelsigndeva",
+ category="mc",
+ description="DEVANAGARI VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x093F,
+ },
+ [0x0940]={
+ adobename="iivowelsigndeva",
+ category="mc",
+ description="DEVANAGARI VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0940,
+ },
+ [0x0941]={
+ adobename="uvowelsigndeva",
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0941,
+ },
+ [0x0942]={
+ adobename="uuvowelsigndeva",
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0942,
+ },
+ [0x0943]={
+ adobename="rvocalicvowelsigndeva",
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN VOCALIC R",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0943,
+ },
+ [0x0944]={
+ adobename="rrvocalicvowelsigndeva",
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN VOCALIC RR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0944,
+ },
+ [0x0945]={
+ adobename="ecandravowelsigndeva",
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN CANDRA E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0945,
+ },
+ [0x0946]={
+ adobename="eshortvowelsigndeva",
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN SHORT E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0946,
+ },
+ [0x0947]={
+ adobename="evowelsigndeva",
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0947,
+ },
+ [0x0948]={
+ adobename="aivowelsigndeva",
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN AI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0948,
+ },
+ [0x0949]={
+ adobename="ocandravowelsigndeva",
+ category="mc",
+ description="DEVANAGARI VOWEL SIGN CANDRA O",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0949,
+ },
+ [0x094A]={
+ adobename="oshortvowelsigndeva",
+ category="mc",
+ description="DEVANAGARI VOWEL SIGN SHORT O",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x094A,
+ },
+ [0x094B]={
+ adobename="ovowelsigndeva",
+ category="mc",
+ description="DEVANAGARI VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x094B,
+ },
+ [0x094C]={
+ adobename="auvowelsigndeva",
+ category="mc",
+ description="DEVANAGARI VOWEL SIGN AU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x094C,
+ },
+ [0x094D]={
+ adobename="viramadeva",
+ category="mn",
+ description="DEVANAGARI SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x094D,
+ },
+ [0x094E]={
+ category="mc",
+ description="DEVANAGARI VOWEL SIGN PRISHTHAMATRA E",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x094E,
+ },
+ [0x094F]={
+ category="mc",
+ description="DEVANAGARI VOWEL SIGN AW",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x094F,
+ },
+ [0x0950]={
+ adobename="omdeva",
+ category="lo",
+ description="DEVANAGARI OM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0950,
+ },
+ [0x0951]={
+ adobename="udattadeva",
+ category="mn",
+ description="DEVANAGARI STRESS SIGN UDATTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0951,
+ },
+ [0x0952]={
+ adobename="anudattadeva",
+ category="mn",
+ description="DEVANAGARI STRESS SIGN ANUDATTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0952,
+ },
+ [0x0953]={
+ adobename="gravedeva",
+ category="mn",
+ description="DEVANAGARI GRAVE ACCENT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0953,
+ },
+ [0x0954]={
+ adobename="acutedeva",
+ category="mn",
+ description="DEVANAGARI ACUTE ACCENT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0954,
+ },
+ [0x0955]={
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN CANDRA LONG E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0955,
+ },
+ [0x0956]={
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN UE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0956,
+ },
+ [0x0957]={
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN UUE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0957,
+ },
+ [0x0958]={
+ adobename="qadeva",
+ category="lo",
+ description="DEVANAGARI LETTER QA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0915, 0x093C },
+ unicodeslot=0x0958,
+ },
+ [0x0959]={
+ adobename="khhadeva",
+ category="lo",
+ description="DEVANAGARI LETTER KHHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0916, 0x093C },
+ unicodeslot=0x0959,
+ },
+ [0x095A]={
+ adobename="ghhadeva",
+ category="lo",
+ description="DEVANAGARI LETTER GHHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0917, 0x093C },
+ unicodeslot=0x095A,
+ },
+ [0x095B]={
+ adobename="zadeva",
+ category="lo",
+ description="DEVANAGARI LETTER ZA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x091C, 0x093C },
+ unicodeslot=0x095B,
+ },
+ [0x095C]={
+ adobename="dddhadeva",
+ category="lo",
+ description="DEVANAGARI LETTER DDDHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0921, 0x093C },
+ unicodeslot=0x095C,
+ },
+ [0x095D]={
+ adobename="rhadeva",
+ category="lo",
+ description="DEVANAGARI LETTER RHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0922, 0x093C },
+ unicodeslot=0x095D,
+ },
+ [0x095E]={
+ adobename="fadeva",
+ category="lo",
+ description="DEVANAGARI LETTER FA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x092B, 0x093C },
+ unicodeslot=0x095E,
+ },
+ [0x095F]={
+ adobename="yyadeva",
+ category="lo",
+ description="DEVANAGARI LETTER YYA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x092F, 0x093C },
+ unicodeslot=0x095F,
+ },
+ [0x0960]={
+ adobename="rrvocalicdeva",
+ category="lo",
+ description="DEVANAGARI LETTER VOCALIC RR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0960,
+ },
+ [0x0961]={
+ adobename="llvocalicdeva",
+ category="lo",
+ description="DEVANAGARI LETTER VOCALIC LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0961,
+ },
+ [0x0962]={
+ adobename="lvocalicvowelsigndeva",
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN VOCALIC L",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0962,
+ },
+ [0x0963]={
+ adobename="llvocalicvowelsigndeva",
+ category="mn",
+ description="DEVANAGARI VOWEL SIGN VOCALIC LL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0963,
+ },
+ [0x0964]={
+ adobename="danda",
+ category="po",
+ description="DEVANAGARI DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x0964,
+ },
+ [0x0965]={
+ adobename="dbldanda",
+ category="po",
+ description="DEVANAGARI DOUBLE DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x0965,
+ },
+ [0x0966]={
+ adobename="zerodeva",
+ category="nd",
+ description="DEVANAGARI DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0966,
+ },
+ [0x0967]={
+ adobename="onedeva",
+ category="nd",
+ description="DEVANAGARI DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0967,
+ },
+ [0x0968]={
+ adobename="twodeva",
+ category="nd",
+ description="DEVANAGARI DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0968,
+ },
+ [0x0969]={
+ adobename="threedeva",
+ category="nd",
+ description="DEVANAGARI DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0969,
+ },
+ [0x096A]={
+ adobename="fourdeva",
+ category="nd",
+ description="DEVANAGARI DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x096A,
+ },
+ [0x096B]={
+ adobename="fivedeva",
+ category="nd",
+ description="DEVANAGARI DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x096B,
+ },
+ [0x096C]={
+ adobename="sixdeva",
+ category="nd",
+ description="DEVANAGARI DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x096C,
+ },
+ [0x096D]={
+ adobename="sevendeva",
+ category="nd",
+ description="DEVANAGARI DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x096D,
+ },
+ [0x096E]={
+ adobename="eightdeva",
+ category="nd",
+ description="DEVANAGARI DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x096E,
+ },
+ [0x096F]={
+ adobename="ninedeva",
+ category="nd",
+ description="DEVANAGARI DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x096F,
+ },
+ [0x0970]={
+ adobename="abbreviationsigndeva",
+ category="po",
+ description="DEVANAGARI ABBREVIATION SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0970,
+ },
+ [0x0971]={
+ category="lm",
+ description="DEVANAGARI SIGN HIGH SPACING DOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0971,
+ },
+ [0x0972]={
+ category="lo",
+ description="DEVANAGARI LETTER CANDRA A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0972,
+ },
+ [0x0973]={
+ category="lo",
+ description="DEVANAGARI LETTER OE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0973,
+ },
+ [0x0974]={
+ category="lo",
+ description="DEVANAGARI LETTER OOE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0974,
+ },
+ [0x0975]={
+ category="lo",
+ description="DEVANAGARI LETTER AW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0975,
+ },
+ [0x0976]={
+ category="lo",
+ description="DEVANAGARI LETTER UE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0976,
+ },
+ [0x0977]={
+ category="lo",
+ description="DEVANAGARI LETTER UUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0977,
+ },
+ [0x0979]={
+ category="lo",
+ description="DEVANAGARI LETTER ZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0979,
+ },
+ [0x097A]={
+ category="lo",
+ description="DEVANAGARI LETTER HEAVY YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x097A,
+ },
+ [0x097B]={
+ category="lo",
+ description="DEVANAGARI LETTER GGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x097B,
+ },
+ [0x097C]={
+ category="lo",
+ description="DEVANAGARI LETTER JJA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x097C,
+ },
+ [0x097D]={
+ category="lo",
+ description="DEVANAGARI LETTER GLOTTAL STOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x097D,
+ },
+ [0x097E]={
+ category="lo",
+ description="DEVANAGARI LETTER DDDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x097E,
+ },
+ [0x097F]={
+ category="lo",
+ description="DEVANAGARI LETTER BBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x097F,
+ },
+ [0x0981]={
+ adobename="candrabindubengali",
+ category="mn",
+ description="BENGALI SIGN CANDRABINDU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0981,
+ },
+ [0x0982]={
+ adobename="anusvarabengali",
+ category="mc",
+ description="BENGALI SIGN ANUSVARA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0982,
+ },
+ [0x0983]={
+ adobename="visargabengali",
+ category="mc",
+ description="BENGALI SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0983,
+ },
+ [0x0985]={
+ adobename="abengali",
+ category="lo",
+ description="BENGALI LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0985,
+ },
+ [0x0986]={
+ adobename="aabengali",
+ category="lo",
+ description="BENGALI LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0986,
+ },
+ [0x0987]={
+ adobename="ibengali",
+ category="lo",
+ description="BENGALI LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0987,
+ },
+ [0x0988]={
+ adobename="iibengali",
+ category="lo",
+ description="BENGALI LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0988,
+ },
+ [0x0989]={
+ adobename="ubengali",
+ category="lo",
+ description="BENGALI LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0989,
+ },
+ [0x098A]={
+ adobename="uubengali",
+ category="lo",
+ description="BENGALI LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x098A,
+ },
+ [0x098B]={
+ adobename="rvocalicbengali",
+ category="lo",
+ description="BENGALI LETTER VOCALIC R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x098B,
+ },
+ [0x098C]={
+ adobename="lvocalicbengali",
+ category="lo",
+ description="BENGALI LETTER VOCALIC L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x098C,
+ },
+ [0x098F]={
+ adobename="ebengali",
+ category="lo",
+ description="BENGALI LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x098F,
+ },
+ [0x0990]={
+ adobename="aibengali",
+ category="lo",
+ description="BENGALI LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0990,
+ },
+ [0x0993]={
+ adobename="obengali",
+ category="lo",
+ description="BENGALI LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0993,
+ },
+ [0x0994]={
+ adobename="aubengali",
+ category="lo",
+ description="BENGALI LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0994,
+ },
+ [0x0995]={
+ adobename="kabengali",
+ category="lo",
+ description="BENGALI LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0995,
+ },
+ [0x0996]={
+ adobename="khabengali",
+ category="lo",
+ description="BENGALI LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0996,
+ },
+ [0x0997]={
+ adobename="gabengali",
+ category="lo",
+ description="BENGALI LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0997,
+ },
+ [0x0998]={
+ adobename="ghabengali",
+ category="lo",
+ description="BENGALI LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0998,
+ },
+ [0x0999]={
+ adobename="ngabengali",
+ category="lo",
+ description="BENGALI LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0999,
+ },
+ [0x099A]={
+ adobename="cabengali",
+ category="lo",
+ description="BENGALI LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x099A,
+ },
+ [0x099B]={
+ adobename="chabengali",
+ category="lo",
+ description="BENGALI LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x099B,
+ },
+ [0x099C]={
+ adobename="jabengali",
+ category="lo",
+ description="BENGALI LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x099C,
+ },
+ [0x099D]={
+ adobename="jhabengali",
+ category="lo",
+ description="BENGALI LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x099D,
+ },
+ [0x099E]={
+ adobename="nyabengali",
+ category="lo",
+ description="BENGALI LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x099E,
+ },
+ [0x099F]={
+ adobename="ttabengali",
+ category="lo",
+ description="BENGALI LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x099F,
+ },
+ [0x09A0]={
+ adobename="tthabengali",
+ category="lo",
+ description="BENGALI LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09A0,
+ },
+ [0x09A1]={
+ adobename="ddabengali",
+ category="lo",
+ description="BENGALI LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09A1,
+ },
+ [0x09A2]={
+ adobename="ddhabengali",
+ category="lo",
+ description="BENGALI LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09A2,
+ },
+ [0x09A3]={
+ adobename="nnabengali",
+ category="lo",
+ description="BENGALI LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09A3,
+ },
+ [0x09A4]={
+ adobename="tabengali",
+ category="lo",
+ description="BENGALI LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09A4,
+ },
+ [0x09A5]={
+ adobename="thabengali",
+ category="lo",
+ description="BENGALI LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09A5,
+ },
+ [0x09A6]={
+ adobename="dabengali",
+ category="lo",
+ description="BENGALI LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09A6,
+ },
+ [0x09A7]={
+ adobename="dhabengali",
+ category="lo",
+ description="BENGALI LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09A7,
+ },
+ [0x09A8]={
+ adobename="nabengali",
+ category="lo",
+ description="BENGALI LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09A8,
+ },
+ [0x09AA]={
+ adobename="pabengali",
+ category="lo",
+ description="BENGALI LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09AA,
+ },
+ [0x09AB]={
+ adobename="phabengali",
+ category="lo",
+ description="BENGALI LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09AB,
+ },
+ [0x09AC]={
+ adobename="babengali",
+ category="lo",
+ description="BENGALI LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09AC,
+ },
+ [0x09AD]={
+ adobename="bhabengali",
+ category="lo",
+ description="BENGALI LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09AD,
+ },
+ [0x09AE]={
+ adobename="mabengali",
+ category="lo",
+ description="BENGALI LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09AE,
+ },
+ [0x09AF]={
+ adobename="yabengali",
+ category="lo",
+ description="BENGALI LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09AF,
+ },
+ [0x09B0]={
+ adobename="rabengali",
+ category="lo",
+ description="BENGALI LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09B0,
+ },
+ [0x09B2]={
+ adobename="labengali",
+ category="lo",
+ description="BENGALI LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09B2,
+ },
+ [0x09B6]={
+ adobename="shabengali",
+ category="lo",
+ description="BENGALI LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09B6,
+ },
+ [0x09B7]={
+ adobename="ssabengali",
+ category="lo",
+ description="BENGALI LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09B7,
+ },
+ [0x09B8]={
+ adobename="sabengali",
+ category="lo",
+ description="BENGALI LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09B8,
+ },
+ [0x09B9]={
+ adobename="habengali",
+ category="lo",
+ description="BENGALI LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09B9,
+ },
+ [0x09BC]={
+ adobename="nuktabengali",
+ category="mn",
+ description="BENGALI SIGN NUKTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x09BC,
+ },
+ [0x09BD]={
+ category="lo",
+ description="BENGALI SIGN AVAGRAHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09BD,
+ },
+ [0x09BE]={
+ adobename="aavowelsignbengali",
+ category="mc",
+ description="BENGALI VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x09BE,
+ },
+ [0x09BF]={
+ adobename="ivowelsignbengali",
+ category="mc",
+ description="BENGALI VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x09BF,
+ },
+ [0x09C0]={
+ adobename="iivowelsignbengali",
+ category="mc",
+ description="BENGALI VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x09C0,
+ },
+ [0x09C1]={
+ adobename="uvowelsignbengali",
+ category="mn",
+ description="BENGALI VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x09C1,
+ },
+ [0x09C2]={
+ adobename="uuvowelsignbengali",
+ category="mn",
+ description="BENGALI VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x09C2,
+ },
+ [0x09C3]={
+ adobename="rvocalicvowelsignbengali",
+ category="mn",
+ description="BENGALI VOWEL SIGN VOCALIC R",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x09C3,
+ },
+ [0x09C4]={
+ adobename="rrvocalicvowelsignbengali",
+ category="mn",
+ description="BENGALI VOWEL SIGN VOCALIC RR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x09C4,
+ },
+ [0x09C7]={
+ adobename="evowelsignbengali",
+ category="mc",
+ description="BENGALI VOWEL SIGN E",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x09C7,
+ },
+ [0x09C8]={
+ adobename="aivowelsignbengali",
+ category="mc",
+ description="BENGALI VOWEL SIGN AI",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x09C8,
+ },
+ [0x09CB]={
+ adobename="ovowelsignbengali",
+ category="mc",
+ description="BENGALI VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x09C7, 0x09BE },
+ unicodeslot=0x09CB,
+ },
+ [0x09CC]={
+ adobename="auvowelsignbengali",
+ category="mc",
+ description="BENGALI VOWEL SIGN AU",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x09C7, 0x09D7 },
+ unicodeslot=0x09CC,
+ },
+ [0x09CD]={
+ adobename="viramabengali",
+ category="mn",
+ description="BENGALI SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x09CD,
+ },
+ [0x09CE]={
+ category="lo",
+ description="BENGALI LETTER KHANDA TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09CE,
+ },
+ [0x09D7]={
+ adobename="aulengthmarkbengali",
+ category="mc",
+ description="BENGALI AU LENGTH MARK",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x09D7,
+ },
+ [0x09DC]={
+ adobename="rrabengali",
+ category="lo",
+ description="BENGALI LETTER RRA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x09A1, 0x09BC },
+ unicodeslot=0x09DC,
+ },
+ [0x09DD]={
+ adobename="rhabengali",
+ category="lo",
+ description="BENGALI LETTER RHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x09A2, 0x09BC },
+ unicodeslot=0x09DD,
+ },
+ [0x09DF]={
+ adobename="yyabengali",
+ category="lo",
+ description="BENGALI LETTER YYA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x09AF, 0x09BC },
+ unicodeslot=0x09DF,
+ },
+ [0x09E0]={
+ adobename="rrvocalicbengali",
+ category="lo",
+ description="BENGALI LETTER VOCALIC RR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09E0,
+ },
+ [0x09E1]={
+ adobename="llvocalicbengali",
+ category="lo",
+ description="BENGALI LETTER VOCALIC LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09E1,
+ },
+ [0x09E2]={
+ adobename="lvocalicvowelsignbengali",
+ category="mn",
+ description="BENGALI VOWEL SIGN VOCALIC L",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x09E2,
+ },
+ [0x09E3]={
+ adobename="llvocalicvowelsignbengali",
+ category="mn",
+ description="BENGALI VOWEL SIGN VOCALIC LL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x09E3,
+ },
+ [0x09E6]={
+ adobename="zerobengali",
+ category="nd",
+ description="BENGALI DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x09E6,
+ },
+ [0x09E7]={
+ adobename="onebengali",
+ category="nd",
+ description="BENGALI DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x09E7,
+ },
+ [0x09E8]={
+ adobename="twobengali",
+ category="nd",
+ description="BENGALI DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x09E8,
+ },
+ [0x09E9]={
+ adobename="threebengali",
+ category="nd",
+ description="BENGALI DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x09E9,
+ },
+ [0x09EA]={
+ adobename="fourbengali",
+ category="nd",
+ description="BENGALI DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x09EA,
+ },
+ [0x09EB]={
+ adobename="fivebengali",
+ category="nd",
+ description="BENGALI DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x09EB,
+ },
+ [0x09EC]={
+ adobename="sixbengali",
+ category="nd",
+ description="BENGALI DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x09EC,
+ },
+ [0x09ED]={
+ adobename="sevenbengali",
+ category="nd",
+ description="BENGALI DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x09ED,
+ },
+ [0x09EE]={
+ adobename="eightbengali",
+ category="nd",
+ description="BENGALI DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x09EE,
+ },
+ [0x09EF]={
+ adobename="ninebengali",
+ category="nd",
+ description="BENGALI DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x09EF,
+ },
+ [0x09F0]={
+ adobename="ramiddlediagonalbengali",
+ category="lo",
+ description="BENGALI LETTER RA WITH MIDDLE DIAGONAL",
+ direction="l",
+ linebreak="al",
+ shcode=0x09B0,
+ unicodeslot=0x09F0,
+ },
+ [0x09F1]={
+ adobename="ralowerdiagonalbengali",
+ category="lo",
+ description="BENGALI LETTER RA WITH LOWER DIAGONAL",
+ direction="l",
+ linebreak="al",
+ shcode=0x09B0,
+ unicodeslot=0x09F1,
+ },
+ [0x09F2]={
+ adobename="rupeemarkbengali",
+ category="sc",
+ description="BENGALI RUPEE MARK",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x09F2,
+ },
+ [0x09F3]={
+ adobename="rupeesignbengali",
+ category="sc",
+ description="BENGALI RUPEE SIGN",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x09F3,
+ },
+ [0x09F4]={
+ adobename="onenumeratorbengali",
+ category="no",
+ description="BENGALI CURRENCY NUMERATOR ONE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09F4,
+ },
+ [0x09F5]={
+ adobename="twonumeratorbengali",
+ category="no",
+ description="BENGALI CURRENCY NUMERATOR TWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09F5,
+ },
+ [0x09F6]={
+ adobename="threenumeratorbengali",
+ category="no",
+ description="BENGALI CURRENCY NUMERATOR THREE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09F6,
+ },
+ [0x09F7]={
+ adobename="fournumeratorbengali",
+ category="no",
+ description="BENGALI CURRENCY NUMERATOR FOUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09F7,
+ },
+ [0x09F8]={
+ adobename="denominatorminusonenumeratorbengali",
+ category="no",
+ description="BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09F8,
+ },
+ [0x09F9]={
+ adobename="sixteencurrencydenominatorbengali",
+ category="no",
+ description="BENGALI CURRENCY DENOMINATOR SIXTEEN",
+ direction="l",
+ linebreak="po",
+ unicodeslot=0x09F9,
+ },
+ [0x09FA]={
+ adobename="issharbengali",
+ category="so",
+ description="BENGALI ISSHAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x09FA,
+ },
+ [0x09FB]={
+ category="sc",
+ description="BENGALI GANDA MARK",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x09FB,
+ },
+ [0x0A01]={
+ category="mn",
+ description="GURMUKHI SIGN ADAK BINDI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A01,
+ },
+ [0x0A02]={
+ adobename="bindigurmukhi",
+ category="mn",
+ description="GURMUKHI SIGN BINDI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A02,
+ },
+ [0x0A03]={
+ category="mc",
+ description="GURMUKHI SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0A03,
+ },
+ [0x0A05]={
+ adobename="agurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A05,
+ },
+ [0x0A06]={
+ adobename="aagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A06,
+ },
+ [0x0A07]={
+ adobename="igurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A07,
+ },
+ [0x0A08]={
+ adobename="iigurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A08,
+ },
+ [0x0A09]={
+ adobename="ugurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A09,
+ },
+ [0x0A0A]={
+ adobename="uugurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A0A,
+ },
+ [0x0A0F]={
+ adobename="eegurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A0F,
+ },
+ [0x0A10]={
+ adobename="aigurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A10,
+ },
+ [0x0A13]={
+ adobename="oogurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A13,
+ },
+ [0x0A14]={
+ adobename="augurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A14,
+ },
+ [0x0A15]={
+ adobename="kagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A15,
+ },
+ [0x0A16]={
+ adobename="khagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A16,
+ },
+ [0x0A17]={
+ adobename="gagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A17,
+ },
+ [0x0A18]={
+ adobename="ghagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A18,
+ },
+ [0x0A19]={
+ adobename="ngagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A19,
+ },
+ [0x0A1A]={
+ adobename="cagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A1A,
+ },
+ [0x0A1B]={
+ adobename="chagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A1B,
+ },
+ [0x0A1C]={
+ adobename="jagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A1C,
+ },
+ [0x0A1D]={
+ adobename="jhagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A1D,
+ },
+ [0x0A1E]={
+ adobename="nyagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A1E,
+ },
+ [0x0A1F]={
+ adobename="ttagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A1F,
+ },
+ [0x0A20]={
+ adobename="tthagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A20,
+ },
+ [0x0A21]={
+ adobename="ddagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A21,
+ },
+ [0x0A22]={
+ adobename="ddhagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A22,
+ },
+ [0x0A23]={
+ adobename="nnagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A23,
+ },
+ [0x0A24]={
+ adobename="tagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A24,
+ },
+ [0x0A25]={
+ adobename="thagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A25,
+ },
+ [0x0A26]={
+ adobename="dagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A26,
+ },
+ [0x0A27]={
+ adobename="dhagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A27,
+ },
+ [0x0A28]={
+ adobename="nagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A28,
+ },
+ [0x0A2A]={
+ adobename="pagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A2A,
+ },
+ [0x0A2B]={
+ adobename="phagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A2B,
+ },
+ [0x0A2C]={
+ adobename="bagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A2C,
+ },
+ [0x0A2D]={
+ adobename="bhagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A2D,
+ },
+ [0x0A2E]={
+ adobename="magurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A2E,
+ },
+ [0x0A2F]={
+ adobename="yagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A2F,
+ },
+ [0x0A30]={
+ adobename="ragurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A30,
+ },
+ [0x0A32]={
+ adobename="lagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A32,
+ },
+ [0x0A33]={
+ category="lo",
+ description="GURMUKHI LETTER LLA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0A32, 0x0A3C },
+ unicodeslot=0x0A33,
+ },
+ [0x0A35]={
+ adobename="vagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A35,
+ },
+ [0x0A36]={
+ adobename="shagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER SHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0A38, 0x0A3C },
+ unicodeslot=0x0A36,
+ },
+ [0x0A38]={
+ adobename="sagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A38,
+ },
+ [0x0A39]={
+ adobename="hagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A39,
+ },
+ [0x0A3C]={
+ adobename="nuktagurmukhi",
+ category="mn",
+ description="GURMUKHI SIGN NUKTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A3C,
+ },
+ [0x0A3E]={
+ adobename="aamatragurmukhi",
+ category="mc",
+ description="GURMUKHI VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0A3E,
+ },
+ [0x0A3F]={
+ adobename="imatragurmukhi",
+ category="mc",
+ description="GURMUKHI VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0A3F,
+ },
+ [0x0A40]={
+ adobename="iimatragurmukhi",
+ category="mc",
+ description="GURMUKHI VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0A40,
+ },
+ [0x0A41]={
+ adobename="umatragurmukhi",
+ category="mn",
+ description="GURMUKHI VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A41,
+ },
+ [0x0A42]={
+ adobename="uumatragurmukhi",
+ category="mn",
+ description="GURMUKHI VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A42,
+ },
+ [0x0A47]={
+ adobename="eematragurmukhi",
+ category="mn",
+ description="GURMUKHI VOWEL SIGN EE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A47,
+ },
+ [0x0A48]={
+ adobename="aimatragurmukhi",
+ category="mn",
+ description="GURMUKHI VOWEL SIGN AI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A48,
+ },
+ [0x0A4B]={
+ adobename="oomatragurmukhi",
+ category="mn",
+ description="GURMUKHI VOWEL SIGN OO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A4B,
+ },
+ [0x0A4C]={
+ adobename="aumatragurmukhi",
+ category="mn",
+ description="GURMUKHI VOWEL SIGN AU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A4C,
+ },
+ [0x0A4D]={
+ adobename="halantgurmukhi",
+ category="mn",
+ description="GURMUKHI SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A4D,
+ },
+ [0x0A51]={
+ category="mn",
+ description="GURMUKHI SIGN UDAAT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A51,
+ },
+ [0x0A59]={
+ adobename="khhagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER KHHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0A16, 0x0A3C },
+ unicodeslot=0x0A59,
+ },
+ [0x0A5A]={
+ adobename="ghhagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER GHHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0A17, 0x0A3C },
+ unicodeslot=0x0A5A,
+ },
+ [0x0A5B]={
+ adobename="zagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER ZA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0A1C, 0x0A3C },
+ unicodeslot=0x0A5B,
+ },
+ [0x0A5C]={
+ adobename="rragurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER RRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A5C,
+ },
+ [0x0A5E]={
+ adobename="fagurmukhi",
+ category="lo",
+ description="GURMUKHI LETTER FA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0A2B, 0x0A3C },
+ unicodeslot=0x0A5E,
+ },
+ [0x0A66]={
+ adobename="zerogurmukhi",
+ category="nd",
+ description="GURMUKHI DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0A66,
+ },
+ [0x0A67]={
+ adobename="onegurmukhi",
+ category="nd",
+ description="GURMUKHI DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0A67,
+ },
+ [0x0A68]={
+ adobename="twogurmukhi",
+ category="nd",
+ description="GURMUKHI DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0A68,
+ },
+ [0x0A69]={
+ adobename="threegurmukhi",
+ category="nd",
+ description="GURMUKHI DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0A69,
+ },
+ [0x0A6A]={
+ adobename="fourgurmukhi",
+ category="nd",
+ description="GURMUKHI DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0A6A,
+ },
+ [0x0A6B]={
+ adobename="fivegurmukhi",
+ category="nd",
+ description="GURMUKHI DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0A6B,
+ },
+ [0x0A6C]={
+ adobename="sixgurmukhi",
+ category="nd",
+ description="GURMUKHI DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0A6C,
+ },
+ [0x0A6D]={
+ adobename="sevengurmukhi",
+ category="nd",
+ description="GURMUKHI DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0A6D,
+ },
+ [0x0A6E]={
+ adobename="eightgurmukhi",
+ category="nd",
+ description="GURMUKHI DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0A6E,
+ },
+ [0x0A6F]={
+ adobename="ninegurmukhi",
+ category="nd",
+ description="GURMUKHI DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0A6F,
+ },
+ [0x0A70]={
+ adobename="tippigurmukhi",
+ category="mn",
+ description="GURMUKHI TIPPI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A70,
+ },
+ [0x0A71]={
+ adobename="addakgurmukhi",
+ category="mn",
+ description="GURMUKHI ADDAK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A71,
+ },
+ [0x0A72]={
+ adobename="irigurmukhi",
+ category="lo",
+ description="GURMUKHI IRI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A72,
+ },
+ [0x0A73]={
+ adobename="uragurmukhi",
+ category="lo",
+ description="GURMUKHI URA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A73,
+ },
+ [0x0A74]={
+ adobename="ekonkargurmukhi",
+ category="lo",
+ description="GURMUKHI EK ONKAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A74,
+ },
+ [0x0A75]={
+ category="mn",
+ description="GURMUKHI SIGN YAKASH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A75,
+ },
+ [0x0A81]={
+ adobename="candrabindugujarati",
+ category="mn",
+ description="GUJARATI SIGN CANDRABINDU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A81,
+ },
+ [0x0A82]={
+ adobename="anusvaragujarati",
+ category="mn",
+ description="GUJARATI SIGN ANUSVARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0A82,
+ },
+ [0x0A83]={
+ adobename="visargagujarati",
+ category="mc",
+ description="GUJARATI SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0A83,
+ },
+ [0x0A85]={
+ adobename="agujarati",
+ category="lo",
+ description="GUJARATI LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A85,
+ },
+ [0x0A86]={
+ adobename="aagujarati",
+ category="lo",
+ description="GUJARATI LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A86,
+ },
+ [0x0A87]={
+ adobename="igujarati",
+ category="lo",
+ description="GUJARATI LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A87,
+ },
+ [0x0A88]={
+ adobename="iigujarati",
+ category="lo",
+ description="GUJARATI LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A88,
+ },
+ [0x0A89]={
+ adobename="ugujarati",
+ category="lo",
+ description="GUJARATI LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A89,
+ },
+ [0x0A8A]={
+ adobename="uugujarati",
+ category="lo",
+ description="GUJARATI LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A8A,
+ },
+ [0x0A8B]={
+ adobename="rvocalicgujarati",
+ category="lo",
+ description="GUJARATI LETTER VOCALIC R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A8B,
+ },
+ [0x0A8C]={
+ category="lo",
+ description="GUJARATI LETTER VOCALIC L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A8C,
+ },
+ [0x0A8D]={
+ adobename="ecandragujarati",
+ category="lo",
+ description="GUJARATI VOWEL CANDRA E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A8D,
+ },
+ [0x0A8F]={
+ adobename="egujarati",
+ category="lo",
+ description="GUJARATI LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A8F,
+ },
+ [0x0A90]={
+ adobename="aigujarati",
+ category="lo",
+ description="GUJARATI LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A90,
+ },
+ [0x0A91]={
+ adobename="ocandragujarati",
+ category="lo",
+ description="GUJARATI VOWEL CANDRA O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A91,
+ },
+ [0x0A93]={
+ adobename="ogujarati",
+ category="lo",
+ description="GUJARATI LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A93,
+ },
+ [0x0A94]={
+ adobename="augujarati",
+ category="lo",
+ description="GUJARATI LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A94,
+ },
+ [0x0A95]={
+ adobename="kagujarati",
+ category="lo",
+ description="GUJARATI LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A95,
+ },
+ [0x0A96]={
+ adobename="khagujarati",
+ category="lo",
+ description="GUJARATI LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A96,
+ },
+ [0x0A97]={
+ adobename="gagujarati",
+ category="lo",
+ description="GUJARATI LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A97,
+ },
+ [0x0A98]={
+ adobename="ghagujarati",
+ category="lo",
+ description="GUJARATI LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A98,
+ },
+ [0x0A99]={
+ adobename="ngagujarati",
+ category="lo",
+ description="GUJARATI LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A99,
+ },
+ [0x0A9A]={
+ adobename="cagujarati",
+ category="lo",
+ description="GUJARATI LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A9A,
+ },
+ [0x0A9B]={
+ adobename="chagujarati",
+ category="lo",
+ description="GUJARATI LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A9B,
+ },
+ [0x0A9C]={
+ adobename="jagujarati",
+ category="lo",
+ description="GUJARATI LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A9C,
+ },
+ [0x0A9D]={
+ adobename="jhagujarati",
+ category="lo",
+ description="GUJARATI LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A9D,
+ },
+ [0x0A9E]={
+ adobename="nyagujarati",
+ category="lo",
+ description="GUJARATI LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A9E,
+ },
+ [0x0A9F]={
+ adobename="ttagujarati",
+ category="lo",
+ description="GUJARATI LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0A9F,
+ },
+ [0x0AA0]={
+ adobename="tthagujarati",
+ category="lo",
+ description="GUJARATI LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AA0,
+ },
+ [0x0AA1]={
+ adobename="ddagujarati",
+ category="lo",
+ description="GUJARATI LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AA1,
+ },
+ [0x0AA2]={
+ adobename="ddhagujarati",
+ category="lo",
+ description="GUJARATI LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AA2,
+ },
+ [0x0AA3]={
+ adobename="nnagujarati",
+ category="lo",
+ description="GUJARATI LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AA3,
+ },
+ [0x0AA4]={
+ adobename="tagujarati",
+ category="lo",
+ description="GUJARATI LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AA4,
+ },
+ [0x0AA5]={
+ adobename="thagujarati",
+ category="lo",
+ description="GUJARATI LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AA5,
+ },
+ [0x0AA6]={
+ adobename="dagujarati",
+ category="lo",
+ description="GUJARATI LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AA6,
+ },
+ [0x0AA7]={
+ adobename="dhagujarati",
+ category="lo",
+ description="GUJARATI LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AA7,
+ },
+ [0x0AA8]={
+ adobename="nagujarati",
+ category="lo",
+ description="GUJARATI LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AA8,
+ },
+ [0x0AAA]={
+ adobename="pagujarati",
+ category="lo",
+ description="GUJARATI LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AAA,
+ },
+ [0x0AAB]={
+ adobename="phagujarati",
+ category="lo",
+ description="GUJARATI LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AAB,
+ },
+ [0x0AAC]={
+ adobename="bagujarati",
+ category="lo",
+ description="GUJARATI LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AAC,
+ },
+ [0x0AAD]={
+ adobename="bhagujarati",
+ category="lo",
+ description="GUJARATI LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AAD,
+ },
+ [0x0AAE]={
+ adobename="magujarati",
+ category="lo",
+ description="GUJARATI LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AAE,
+ },
+ [0x0AAF]={
+ adobename="yagujarati",
+ category="lo",
+ description="GUJARATI LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AAF,
+ },
+ [0x0AB0]={
+ adobename="ragujarati",
+ category="lo",
+ description="GUJARATI LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AB0,
+ },
+ [0x0AB2]={
+ adobename="lagujarati",
+ category="lo",
+ description="GUJARATI LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AB2,
+ },
+ [0x0AB3]={
+ adobename="llagujarati",
+ category="lo",
+ description="GUJARATI LETTER LLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AB3,
+ },
+ [0x0AB5]={
+ adobename="vagujarati",
+ category="lo",
+ description="GUJARATI LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AB5,
+ },
+ [0x0AB6]={
+ adobename="shagujarati",
+ category="lo",
+ description="GUJARATI LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AB6,
+ },
+ [0x0AB7]={
+ adobename="ssagujarati",
+ category="lo",
+ description="GUJARATI LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AB7,
+ },
+ [0x0AB8]={
+ adobename="sagujarati",
+ category="lo",
+ description="GUJARATI LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AB8,
+ },
+ [0x0AB9]={
+ adobename="hagujarati",
+ category="lo",
+ description="GUJARATI LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AB9,
+ },
+ [0x0ABC]={
+ adobename="nuktagujarati",
+ category="mn",
+ description="GUJARATI SIGN NUKTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0ABC,
+ },
+ [0x0ABD]={
+ category="lo",
+ description="GUJARATI SIGN AVAGRAHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0ABD,
+ },
+ [0x0ABE]={
+ adobename="aavowelsigngujarati",
+ category="mc",
+ description="GUJARATI VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0ABE,
+ },
+ [0x0ABF]={
+ adobename="ivowelsigngujarati",
+ category="mc",
+ description="GUJARATI VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0ABF,
+ },
+ [0x0AC0]={
+ adobename="iivowelsigngujarati",
+ category="mc",
+ description="GUJARATI VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0AC0,
+ },
+ [0x0AC1]={
+ adobename="uvowelsigngujarati",
+ category="mn",
+ description="GUJARATI VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0AC1,
+ },
+ [0x0AC2]={
+ adobename="uuvowelsigngujarati",
+ category="mn",
+ description="GUJARATI VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0AC2,
+ },
+ [0x0AC3]={
+ adobename="rvocalicvowelsigngujarati",
+ category="mn",
+ description="GUJARATI VOWEL SIGN VOCALIC R",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0AC3,
+ },
+ [0x0AC4]={
+ adobename="rrvocalicvowelsigngujarati",
+ category="mn",
+ description="GUJARATI VOWEL SIGN VOCALIC RR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0AC4,
+ },
+ [0x0AC5]={
+ adobename="ecandravowelsigngujarati",
+ category="mn",
+ description="GUJARATI VOWEL SIGN CANDRA E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0AC5,
+ },
+ [0x0AC7]={
+ adobename="evowelsigngujarati",
+ category="mn",
+ description="GUJARATI VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0AC7,
+ },
+ [0x0AC8]={
+ adobename="aivowelsigngujarati",
+ category="mn",
+ description="GUJARATI VOWEL SIGN AI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0AC8,
+ },
+ [0x0AC9]={
+ adobename="ocandravowelsigngujarati",
+ category="mc",
+ description="GUJARATI VOWEL SIGN CANDRA O",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0AC9,
+ },
+ [0x0ACB]={
+ adobename="ovowelsigngujarati",
+ category="mc",
+ description="GUJARATI VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0ACB,
+ },
+ [0x0ACC]={
+ adobename="auvowelsigngujarati",
+ category="mc",
+ description="GUJARATI VOWEL SIGN AU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0ACC,
+ },
+ [0x0ACD]={
+ adobename="viramagujarati",
+ category="mn",
+ description="GUJARATI SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0ACD,
+ },
+ [0x0AD0]={
+ adobename="omgujarati",
+ category="lo",
+ description="GUJARATI OM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AD0,
+ },
+ [0x0AE0]={
+ adobename="rrvocalicgujarati",
+ category="lo",
+ description="GUJARATI LETTER VOCALIC RR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AE0,
+ },
+ [0x0AE1]={
+ category="lo",
+ description="GUJARATI LETTER VOCALIC LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AE1,
+ },
+ [0x0AE2]={
+ category="mn",
+ description="GUJARATI VOWEL SIGN VOCALIC L",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0AE2,
+ },
+ [0x0AE3]={
+ category="mn",
+ description="GUJARATI VOWEL SIGN VOCALIC LL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0AE3,
+ },
+ [0x0AE6]={
+ adobename="zerogujarati",
+ category="nd",
+ description="GUJARATI DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0AE6,
+ },
+ [0x0AE7]={
+ adobename="onegujarati",
+ category="nd",
+ description="GUJARATI DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0AE7,
+ },
+ [0x0AE8]={
+ adobename="twogujarati",
+ category="nd",
+ description="GUJARATI DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0AE8,
+ },
+ [0x0AE9]={
+ adobename="threegujarati",
+ category="nd",
+ description="GUJARATI DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0AE9,
+ },
+ [0x0AEA]={
+ adobename="fourgujarati",
+ category="nd",
+ description="GUJARATI DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0AEA,
+ },
+ [0x0AEB]={
+ adobename="fivegujarati",
+ category="nd",
+ description="GUJARATI DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0AEB,
+ },
+ [0x0AEC]={
+ adobename="sixgujarati",
+ category="nd",
+ description="GUJARATI DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0AEC,
+ },
+ [0x0AED]={
+ adobename="sevengujarati",
+ category="nd",
+ description="GUJARATI DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0AED,
+ },
+ [0x0AEE]={
+ adobename="eightgujarati",
+ category="nd",
+ description="GUJARATI DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0AEE,
+ },
+ [0x0AEF]={
+ adobename="ninegujarati",
+ category="nd",
+ description="GUJARATI DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0AEF,
+ },
+ [0x0AF0]={
+ category="po",
+ description="GUJARATI ABBREVIATION SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0AF0,
+ },
+ [0x0AF1]={
+ category="sc",
+ description="GUJARATI RUPEE SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x0AF1,
+ },
+ [0x0B01]={
+ category="mn",
+ description="ORIYA SIGN CANDRABINDU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0B01,
+ },
+ [0x0B02]={
+ category="mc",
+ description="ORIYA SIGN ANUSVARA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0B02,
+ },
+ [0x0B03]={
+ category="mc",
+ description="ORIYA SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0B03,
+ },
+ [0x0B05]={
+ category="lo",
+ description="ORIYA LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B05,
+ },
+ [0x0B06]={
+ category="lo",
+ description="ORIYA LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B06,
+ },
+ [0x0B07]={
+ category="lo",
+ description="ORIYA LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B07,
+ },
+ [0x0B08]={
+ category="lo",
+ description="ORIYA LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B08,
+ },
+ [0x0B09]={
+ category="lo",
+ description="ORIYA LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B09,
+ },
+ [0x0B0A]={
+ category="lo",
+ description="ORIYA LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B0A,
+ },
+ [0x0B0B]={
+ category="lo",
+ description="ORIYA LETTER VOCALIC R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B0B,
+ },
+ [0x0B0C]={
+ category="lo",
+ description="ORIYA LETTER VOCALIC L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B0C,
+ },
+ [0x0B0F]={
+ category="lo",
+ description="ORIYA LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B0F,
+ },
+ [0x0B10]={
+ category="lo",
+ description="ORIYA LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B10,
+ },
+ [0x0B13]={
+ category="lo",
+ description="ORIYA LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B13,
+ },
+ [0x0B14]={
+ category="lo",
+ description="ORIYA LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B14,
+ },
+ [0x0B15]={
+ category="lo",
+ description="ORIYA LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B15,
+ },
+ [0x0B16]={
+ category="lo",
+ description="ORIYA LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B16,
+ },
+ [0x0B17]={
+ category="lo",
+ description="ORIYA LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B17,
+ },
+ [0x0B18]={
+ category="lo",
+ description="ORIYA LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B18,
+ },
+ [0x0B19]={
+ category="lo",
+ description="ORIYA LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B19,
+ },
+ [0x0B1A]={
+ category="lo",
+ description="ORIYA LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B1A,
+ },
+ [0x0B1B]={
+ category="lo",
+ description="ORIYA LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B1B,
+ },
+ [0x0B1C]={
+ category="lo",
+ description="ORIYA LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B1C,
+ },
+ [0x0B1D]={
+ category="lo",
+ description="ORIYA LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B1D,
+ },
+ [0x0B1E]={
+ category="lo",
+ description="ORIYA LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B1E,
+ },
+ [0x0B1F]={
+ category="lo",
+ description="ORIYA LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B1F,
+ },
+ [0x0B20]={
+ category="lo",
+ description="ORIYA LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B20,
+ },
+ [0x0B21]={
+ category="lo",
+ description="ORIYA LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B21,
+ },
+ [0x0B22]={
+ category="lo",
+ description="ORIYA LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B22,
+ },
+ [0x0B23]={
+ category="lo",
+ description="ORIYA LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B23,
+ },
+ [0x0B24]={
+ category="lo",
+ description="ORIYA LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B24,
+ },
+ [0x0B25]={
+ category="lo",
+ description="ORIYA LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B25,
+ },
+ [0x0B26]={
+ category="lo",
+ description="ORIYA LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B26,
+ },
+ [0x0B27]={
+ category="lo",
+ description="ORIYA LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B27,
+ },
+ [0x0B28]={
+ category="lo",
+ description="ORIYA LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B28,
+ },
+ [0x0B2A]={
+ category="lo",
+ description="ORIYA LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B2A,
+ },
+ [0x0B2B]={
+ category="lo",
+ description="ORIYA LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B2B,
+ },
+ [0x0B2C]={
+ category="lo",
+ description="ORIYA LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B2C,
+ },
+ [0x0B2D]={
+ category="lo",
+ description="ORIYA LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B2D,
+ },
+ [0x0B2E]={
+ category="lo",
+ description="ORIYA LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B2E,
+ },
+ [0x0B2F]={
+ category="lo",
+ description="ORIYA LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B2F,
+ },
+ [0x0B30]={
+ category="lo",
+ description="ORIYA LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B30,
+ },
+ [0x0B32]={
+ category="lo",
+ description="ORIYA LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B32,
+ },
+ [0x0B33]={
+ category="lo",
+ description="ORIYA LETTER LLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B33,
+ },
+ [0x0B35]={
+ category="lo",
+ description="ORIYA LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B35,
+ },
+ [0x0B36]={
+ category="lo",
+ description="ORIYA LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B36,
+ },
+ [0x0B37]={
+ category="lo",
+ description="ORIYA LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B37,
+ },
+ [0x0B38]={
+ category="lo",
+ description="ORIYA LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B38,
+ },
+ [0x0B39]={
+ category="lo",
+ description="ORIYA LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B39,
+ },
+ [0x0B3C]={
+ category="mn",
+ description="ORIYA SIGN NUKTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0B3C,
+ },
+ [0x0B3D]={
+ category="lo",
+ description="ORIYA SIGN AVAGRAHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B3D,
+ },
+ [0x0B3E]={
+ category="mc",
+ description="ORIYA VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0B3E,
+ },
+ [0x0B3F]={
+ category="mn",
+ description="ORIYA VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0B3F,
+ },
+ [0x0B40]={
+ category="mc",
+ description="ORIYA VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0B40,
+ },
+ [0x0B41]={
+ category="mn",
+ description="ORIYA VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0B41,
+ },
+ [0x0B42]={
+ category="mn",
+ description="ORIYA VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0B42,
+ },
+ [0x0B43]={
+ category="mn",
+ description="ORIYA VOWEL SIGN VOCALIC R",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0B43,
+ },
+ [0x0B44]={
+ category="mn",
+ description="ORIYA VOWEL SIGN VOCALIC RR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0B44,
+ },
+ [0x0B47]={
+ category="mc",
+ description="ORIYA VOWEL SIGN E",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0B47,
+ },
+ [0x0B48]={
+ category="mc",
+ description="ORIYA VOWEL SIGN AI",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0B47, 0x0B56 },
+ unicodeslot=0x0B48,
+ },
+ [0x0B4B]={
+ category="mc",
+ description="ORIYA VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0B47, 0x0B3E },
+ unicodeslot=0x0B4B,
+ },
+ [0x0B4C]={
+ category="mc",
+ description="ORIYA VOWEL SIGN AU",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0B47, 0x0B57 },
+ unicodeslot=0x0B4C,
+ },
+ [0x0B4D]={
+ category="mn",
+ description="ORIYA SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0B4D,
+ },
+ [0x0B56]={
+ category="mn",
+ description="ORIYA AI LENGTH MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0B56,
+ },
+ [0x0B57]={
+ category="mc",
+ description="ORIYA AU LENGTH MARK",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0B57,
+ },
+ [0x0B5C]={
+ category="lo",
+ description="ORIYA LETTER RRA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0B21, 0x0B3C },
+ unicodeslot=0x0B5C,
+ },
+ [0x0B5D]={
+ category="lo",
+ description="ORIYA LETTER RHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0B22, 0x0B3C },
+ unicodeslot=0x0B5D,
+ },
+ [0x0B5F]={
+ category="lo",
+ description="ORIYA LETTER YYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B5F,
+ },
+ [0x0B60]={
+ category="lo",
+ description="ORIYA LETTER VOCALIC RR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B60,
+ },
+ [0x0B61]={
+ category="lo",
+ description="ORIYA LETTER VOCALIC LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B61,
+ },
+ [0x0B62]={
+ category="mn",
+ description="ORIYA VOWEL SIGN VOCALIC L",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0B62,
+ },
+ [0x0B63]={
+ category="mn",
+ description="ORIYA VOWEL SIGN VOCALIC LL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0B63,
+ },
+ [0x0B66]={
+ category="nd",
+ description="ORIYA DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0B66,
+ },
+ [0x0B67]={
+ category="nd",
+ description="ORIYA DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0B67,
+ },
+ [0x0B68]={
+ category="nd",
+ description="ORIYA DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0B68,
+ },
+ [0x0B69]={
+ category="nd",
+ description="ORIYA DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0B69,
+ },
+ [0x0B6A]={
+ category="nd",
+ description="ORIYA DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0B6A,
+ },
+ [0x0B6B]={
+ category="nd",
+ description="ORIYA DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0B6B,
+ },
+ [0x0B6C]={
+ category="nd",
+ description="ORIYA DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0B6C,
+ },
+ [0x0B6D]={
+ category="nd",
+ description="ORIYA DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0B6D,
+ },
+ [0x0B6E]={
+ category="nd",
+ description="ORIYA DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0B6E,
+ },
+ [0x0B6F]={
+ category="nd",
+ description="ORIYA DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0B6F,
+ },
+ [0x0B70]={
+ category="so",
+ description="ORIYA ISSHAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B70,
+ },
+ [0x0B71]={
+ category="lo",
+ description="ORIYA LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B71,
+ },
+ [0x0B72]={
+ category="no",
+ description="ORIYA FRACTION ONE QUARTER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B72,
+ },
+ [0x0B73]={
+ category="no",
+ description="ORIYA FRACTION ONE HALF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B73,
+ },
+ [0x0B74]={
+ category="no",
+ description="ORIYA FRACTION THREE QUARTERS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B74,
+ },
+ [0x0B75]={
+ category="no",
+ description="ORIYA FRACTION ONE SIXTEENTH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B75,
+ },
+ [0x0B76]={
+ category="no",
+ description="ORIYA FRACTION ONE EIGHTH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B76,
+ },
+ [0x0B77]={
+ category="no",
+ description="ORIYA FRACTION THREE SIXTEENTHS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B77,
+ },
+ [0x0B82]={
+ category="mn",
+ description="TAMIL SIGN ANUSVARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0B82,
+ },
+ [0x0B83]={
+ category="lo",
+ description="TAMIL SIGN VISARGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B83,
+ },
+ [0x0B85]={
+ category="lo",
+ description="TAMIL LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B85,
+ },
+ [0x0B86]={
+ category="lo",
+ description="TAMIL LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B86,
+ },
+ [0x0B87]={
+ category="lo",
+ description="TAMIL LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B87,
+ },
+ [0x0B88]={
+ category="lo",
+ description="TAMIL LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B88,
+ },
+ [0x0B89]={
+ category="lo",
+ description="TAMIL LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B89,
+ },
+ [0x0B8A]={
+ category="lo",
+ description="TAMIL LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B8A,
+ },
+ [0x0B8E]={
+ category="lo",
+ description="TAMIL LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B8E,
+ },
+ [0x0B8F]={
+ category="lo",
+ description="TAMIL LETTER EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B8F,
+ },
+ [0x0B90]={
+ category="lo",
+ description="TAMIL LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B90,
+ },
+ [0x0B92]={
+ category="lo",
+ description="TAMIL LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B92,
+ },
+ [0x0B93]={
+ category="lo",
+ description="TAMIL LETTER OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B93,
+ },
+ [0x0B94]={
+ category="lo",
+ description="TAMIL LETTER AU",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0B92, 0x0BD7 },
+ unicodeslot=0x0B94,
+ },
+ [0x0B95]={
+ category="lo",
+ description="TAMIL LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B95,
+ },
+ [0x0B99]={
+ category="lo",
+ description="TAMIL LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B99,
+ },
+ [0x0B9A]={
+ category="lo",
+ description="TAMIL LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B9A,
+ },
+ [0x0B9C]={
+ category="lo",
+ description="TAMIL LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B9C,
+ },
+ [0x0B9E]={
+ category="lo",
+ description="TAMIL LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B9E,
+ },
+ [0x0B9F]={
+ category="lo",
+ description="TAMIL LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0B9F,
+ },
+ [0x0BA3]={
+ category="lo",
+ description="TAMIL LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BA3,
+ },
+ [0x0BA4]={
+ category="lo",
+ description="TAMIL LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BA4,
+ },
+ [0x0BA8]={
+ category="lo",
+ description="TAMIL LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BA8,
+ },
+ [0x0BA9]={
+ category="lo",
+ description="TAMIL LETTER NNNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BA9,
+ },
+ [0x0BAA]={
+ category="lo",
+ description="TAMIL LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BAA,
+ },
+ [0x0BAE]={
+ category="lo",
+ description="TAMIL LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BAE,
+ },
+ [0x0BAF]={
+ category="lo",
+ description="TAMIL LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BAF,
+ },
+ [0x0BB0]={
+ category="lo",
+ description="TAMIL LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BB0,
+ },
+ [0x0BB1]={
+ category="lo",
+ description="TAMIL LETTER RRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BB1,
+ },
+ [0x0BB2]={
+ category="lo",
+ description="TAMIL LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BB2,
+ },
+ [0x0BB3]={
+ category="lo",
+ description="TAMIL LETTER LLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BB3,
+ },
+ [0x0BB4]={
+ category="lo",
+ description="TAMIL LETTER LLLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BB4,
+ },
+ [0x0BB5]={
+ category="lo",
+ description="TAMIL LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BB5,
+ },
+ [0x0BB6]={
+ category="lo",
+ description="TAMIL LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BB6,
+ },
+ [0x0BB7]={
+ category="lo",
+ description="TAMIL LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BB7,
+ },
+ [0x0BB8]={
+ category="lo",
+ description="TAMIL LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BB8,
+ },
+ [0x0BB9]={
+ category="lo",
+ description="TAMIL LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BB9,
+ },
+ [0x0BBE]={
+ category="mc",
+ description="TAMIL VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0BBE,
+ },
+ [0x0BBF]={
+ category="mc",
+ description="TAMIL VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0BBF,
+ },
+ [0x0BC0]={
+ category="mn",
+ description="TAMIL VOWEL SIGN II",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0BC0,
+ },
+ [0x0BC1]={
+ category="mc",
+ description="TAMIL VOWEL SIGN U",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0BC1,
+ },
+ [0x0BC2]={
+ category="mc",
+ description="TAMIL VOWEL SIGN UU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0BC2,
+ },
+ [0x0BC6]={
+ category="mc",
+ description="TAMIL VOWEL SIGN E",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0BC6,
+ },
+ [0x0BC7]={
+ category="mc",
+ description="TAMIL VOWEL SIGN EE",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0BC7,
+ },
+ [0x0BC8]={
+ category="mc",
+ description="TAMIL VOWEL SIGN AI",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0BC8,
+ },
+ [0x0BCA]={
+ category="mc",
+ description="TAMIL VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0BC6, 0x0BBE },
+ unicodeslot=0x0BCA,
+ },
+ [0x0BCB]={
+ category="mc",
+ description="TAMIL VOWEL SIGN OO",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0BC7, 0x0BBE },
+ unicodeslot=0x0BCB,
+ },
+ [0x0BCC]={
+ category="mc",
+ description="TAMIL VOWEL SIGN AU",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0BC6, 0x0BD7 },
+ unicodeslot=0x0BCC,
+ },
+ [0x0BCD]={
+ category="mn",
+ description="TAMIL SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0BCD,
+ },
+ [0x0BD0]={
+ category="lo",
+ description="TAMIL OM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BD0,
+ },
+ [0x0BD7]={
+ category="mc",
+ description="TAMIL AU LENGTH MARK",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0BD7,
+ },
+ [0x0BE6]={
+ category="nd",
+ description="TAMIL DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0BE6,
+ },
+ [0x0BE7]={
+ category="nd",
+ description="TAMIL DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0BE7,
+ },
+ [0x0BE8]={
+ category="nd",
+ description="TAMIL DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0BE8,
+ },
+ [0x0BE9]={
+ category="nd",
+ description="TAMIL DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0BE9,
+ },
+ [0x0BEA]={
+ category="nd",
+ description="TAMIL DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0BEA,
+ },
+ [0x0BEB]={
+ category="nd",
+ description="TAMIL DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0BEB,
+ },
+ [0x0BEC]={
+ category="nd",
+ description="TAMIL DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0BEC,
+ },
+ [0x0BED]={
+ category="nd",
+ description="TAMIL DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0BED,
+ },
+ [0x0BEE]={
+ category="nd",
+ description="TAMIL DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0BEE,
+ },
+ [0x0BEF]={
+ category="nd",
+ description="TAMIL DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0BEF,
+ },
+ [0x0BF0]={
+ category="no",
+ description="TAMIL NUMBER TEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BF0,
+ },
+ [0x0BF1]={
+ category="no",
+ description="TAMIL NUMBER ONE HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BF1,
+ },
+ [0x0BF2]={
+ category="no",
+ description="TAMIL NUMBER ONE THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0BF2,
+ },
+ [0x0BF3]={
+ category="so",
+ description="TAMIL DAY SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0BF3,
+ },
+ [0x0BF4]={
+ category="so",
+ description="TAMIL MONTH SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0BF4,
+ },
+ [0x0BF5]={
+ category="so",
+ description="TAMIL YEAR SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0BF5,
+ },
+ [0x0BF6]={
+ category="so",
+ description="TAMIL DEBIT SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0BF6,
+ },
+ [0x0BF7]={
+ category="so",
+ description="TAMIL CREDIT SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0BF7,
+ },
+ [0x0BF8]={
+ category="so",
+ description="TAMIL AS ABOVE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0BF8,
+ },
+ [0x0BF9]={
+ category="sc",
+ description="TAMIL RUPEE SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x0BF9,
+ },
+ [0x0BFA]={
+ category="so",
+ description="TAMIL NUMBER SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0BFA,
+ },
+ [0x0C01]={
+ category="mc",
+ description="TELUGU SIGN CANDRABINDU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0C01,
+ },
+ [0x0C02]={
+ category="mc",
+ description="TELUGU SIGN ANUSVARA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0C02,
+ },
+ [0x0C03]={
+ category="mc",
+ description="TELUGU SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0C03,
+ },
+ [0x0C05]={
+ category="lo",
+ description="TELUGU LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C05,
+ },
+ [0x0C06]={
+ category="lo",
+ description="TELUGU LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C06,
+ },
+ [0x0C07]={
+ category="lo",
+ description="TELUGU LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C07,
+ },
+ [0x0C08]={
+ category="lo",
+ description="TELUGU LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C08,
+ },
+ [0x0C09]={
+ category="lo",
+ description="TELUGU LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C09,
+ },
+ [0x0C0A]={
+ category="lo",
+ description="TELUGU LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C0A,
+ },
+ [0x0C0B]={
+ category="lo",
+ description="TELUGU LETTER VOCALIC R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C0B,
+ },
+ [0x0C0C]={
+ category="lo",
+ description="TELUGU LETTER VOCALIC L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C0C,
+ },
+ [0x0C0E]={
+ category="lo",
+ description="TELUGU LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C0E,
+ },
+ [0x0C0F]={
+ category="lo",
+ description="TELUGU LETTER EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C0F,
+ },
+ [0x0C10]={
+ category="lo",
+ description="TELUGU LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C10,
+ },
+ [0x0C12]={
+ category="lo",
+ description="TELUGU LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C12,
+ },
+ [0x0C13]={
+ category="lo",
+ description="TELUGU LETTER OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C13,
+ },
+ [0x0C14]={
+ category="lo",
+ description="TELUGU LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C14,
+ },
+ [0x0C15]={
+ category="lo",
+ description="TELUGU LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C15,
+ },
+ [0x0C16]={
+ category="lo",
+ description="TELUGU LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C16,
+ },
+ [0x0C17]={
+ category="lo",
+ description="TELUGU LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C17,
+ },
+ [0x0C18]={
+ category="lo",
+ description="TELUGU LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C18,
+ },
+ [0x0C19]={
+ category="lo",
+ description="TELUGU LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C19,
+ },
+ [0x0C1A]={
+ category="lo",
+ description="TELUGU LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C1A,
+ },
+ [0x0C1B]={
+ category="lo",
+ description="TELUGU LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C1B,
+ },
+ [0x0C1C]={
+ category="lo",
+ description="TELUGU LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C1C,
+ },
+ [0x0C1D]={
+ category="lo",
+ description="TELUGU LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C1D,
+ },
+ [0x0C1E]={
+ category="lo",
+ description="TELUGU LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C1E,
+ },
+ [0x0C1F]={
+ category="lo",
+ description="TELUGU LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C1F,
+ },
+ [0x0C20]={
+ category="lo",
+ description="TELUGU LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C20,
+ },
+ [0x0C21]={
+ category="lo",
+ description="TELUGU LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C21,
+ },
+ [0x0C22]={
+ category="lo",
+ description="TELUGU LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C22,
+ },
+ [0x0C23]={
+ category="lo",
+ description="TELUGU LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C23,
+ },
+ [0x0C24]={
+ category="lo",
+ description="TELUGU LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C24,
+ },
+ [0x0C25]={
+ category="lo",
+ description="TELUGU LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C25,
+ },
+ [0x0C26]={
+ category="lo",
+ description="TELUGU LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C26,
+ },
+ [0x0C27]={
+ category="lo",
+ description="TELUGU LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C27,
+ },
+ [0x0C28]={
+ category="lo",
+ description="TELUGU LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C28,
+ },
+ [0x0C2A]={
+ category="lo",
+ description="TELUGU LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C2A,
+ },
+ [0x0C2B]={
+ category="lo",
+ description="TELUGU LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C2B,
+ },
+ [0x0C2C]={
+ category="lo",
+ description="TELUGU LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C2C,
+ },
+ [0x0C2D]={
+ category="lo",
+ description="TELUGU LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C2D,
+ },
+ [0x0C2E]={
+ category="lo",
+ description="TELUGU LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C2E,
+ },
+ [0x0C2F]={
+ category="lo",
+ description="TELUGU LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C2F,
+ },
+ [0x0C30]={
+ category="lo",
+ description="TELUGU LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C30,
+ },
+ [0x0C31]={
+ category="lo",
+ description="TELUGU LETTER RRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C31,
+ },
+ [0x0C32]={
+ category="lo",
+ description="TELUGU LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C32,
+ },
+ [0x0C33]={
+ category="lo",
+ description="TELUGU LETTER LLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C33,
+ },
+ [0x0C35]={
+ category="lo",
+ description="TELUGU LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C35,
+ },
+ [0x0C36]={
+ category="lo",
+ description="TELUGU LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C36,
+ },
+ [0x0C37]={
+ category="lo",
+ description="TELUGU LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C37,
+ },
+ [0x0C38]={
+ category="lo",
+ description="TELUGU LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C38,
+ },
+ [0x0C39]={
+ category="lo",
+ description="TELUGU LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C39,
+ },
+ [0x0C3D]={
+ category="lo",
+ description="TELUGU SIGN AVAGRAHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C3D,
+ },
+ [0x0C3E]={
+ category="mn",
+ description="TELUGU VOWEL SIGN AA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C3E,
+ },
+ [0x0C3F]={
+ category="mn",
+ description="TELUGU VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C3F,
+ },
+ [0x0C40]={
+ category="mn",
+ description="TELUGU VOWEL SIGN II",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C40,
+ },
+ [0x0C41]={
+ category="mc",
+ description="TELUGU VOWEL SIGN U",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0C41,
+ },
+ [0x0C42]={
+ category="mc",
+ description="TELUGU VOWEL SIGN UU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0C42,
+ },
+ [0x0C43]={
+ category="mc",
+ description="TELUGU VOWEL SIGN VOCALIC R",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0C43,
+ },
+ [0x0C44]={
+ category="mc",
+ description="TELUGU VOWEL SIGN VOCALIC RR",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0C44,
+ },
+ [0x0C46]={
+ category="mn",
+ description="TELUGU VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C46,
+ },
+ [0x0C47]={
+ category="mn",
+ description="TELUGU VOWEL SIGN EE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C47,
+ },
+ [0x0C48]={
+ category="mn",
+ description="TELUGU VOWEL SIGN AI",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0C46, 0x0C56 },
+ unicodeslot=0x0C48,
+ },
+ [0x0C4A]={
+ category="mn",
+ description="TELUGU VOWEL SIGN O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C4A,
+ },
+ [0x0C4B]={
+ category="mn",
+ description="TELUGU VOWEL SIGN OO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C4B,
+ },
+ [0x0C4C]={
+ category="mn",
+ description="TELUGU VOWEL SIGN AU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C4C,
+ },
+ [0x0C4D]={
+ category="mn",
+ description="TELUGU SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C4D,
+ },
+ [0x0C55]={
+ category="mn",
+ description="TELUGU LENGTH MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C55,
+ },
+ [0x0C56]={
+ category="mn",
+ description="TELUGU AI LENGTH MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C56,
+ },
+ [0x0C58]={
+ category="lo",
+ description="TELUGU LETTER TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C58,
+ },
+ [0x0C59]={
+ category="lo",
+ description="TELUGU LETTER DZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C59,
+ },
+ [0x0C60]={
+ category="lo",
+ description="TELUGU LETTER VOCALIC RR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C60,
+ },
+ [0x0C61]={
+ category="lo",
+ description="TELUGU LETTER VOCALIC LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C61,
+ },
+ [0x0C62]={
+ category="mn",
+ description="TELUGU VOWEL SIGN VOCALIC L",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C62,
+ },
+ [0x0C63]={
+ category="mn",
+ description="TELUGU VOWEL SIGN VOCALIC LL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0C63,
+ },
+ [0x0C66]={
+ category="nd",
+ description="TELUGU DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0C66,
+ },
+ [0x0C67]={
+ category="nd",
+ description="TELUGU DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0C67,
+ },
+ [0x0C68]={
+ category="nd",
+ description="TELUGU DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0C68,
+ },
+ [0x0C69]={
+ category="nd",
+ description="TELUGU DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0C69,
+ },
+ [0x0C6A]={
+ category="nd",
+ description="TELUGU DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0C6A,
+ },
+ [0x0C6B]={
+ category="nd",
+ description="TELUGU DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0C6B,
+ },
+ [0x0C6C]={
+ category="nd",
+ description="TELUGU DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0C6C,
+ },
+ [0x0C6D]={
+ category="nd",
+ description="TELUGU DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0C6D,
+ },
+ [0x0C6E]={
+ category="nd",
+ description="TELUGU DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0C6E,
+ },
+ [0x0C6F]={
+ category="nd",
+ description="TELUGU DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0C6F,
+ },
+ [0x0C78]={
+ category="no",
+ description="TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0C78,
+ },
+ [0x0C79]={
+ category="no",
+ description="TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0C79,
+ },
+ [0x0C7A]={
+ category="no",
+ description="TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0C7A,
+ },
+ [0x0C7B]={
+ category="no",
+ description="TELUGU FRACTION DIGIT THREE FOR ODD POWERS OF FOUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0C7B,
+ },
+ [0x0C7C]={
+ category="no",
+ description="TELUGU FRACTION DIGIT ONE FOR EVEN POWERS OF FOUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0C7C,
+ },
+ [0x0C7D]={
+ category="no",
+ description="TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0C7D,
+ },
+ [0x0C7E]={
+ category="no",
+ description="TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x0C7E,
+ },
+ [0x0C7F]={
+ category="so",
+ description="TELUGU SIGN TUUMU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C7F,
+ },
+ [0x0C82]={
+ category="mc",
+ description="KANNADA SIGN ANUSVARA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0C82,
+ },
+ [0x0C83]={
+ category="mc",
+ description="KANNADA SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0C83,
+ },
+ [0x0C85]={
+ category="lo",
+ description="KANNADA LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C85,
+ },
+ [0x0C86]={
+ category="lo",
+ description="KANNADA LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C86,
+ },
+ [0x0C87]={
+ category="lo",
+ description="KANNADA LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C87,
+ },
+ [0x0C88]={
+ category="lo",
+ description="KANNADA LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C88,
+ },
+ [0x0C89]={
+ category="lo",
+ description="KANNADA LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C89,
+ },
+ [0x0C8A]={
+ category="lo",
+ description="KANNADA LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C8A,
+ },
+ [0x0C8B]={
+ category="lo",
+ description="KANNADA LETTER VOCALIC R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C8B,
+ },
+ [0x0C8C]={
+ category="lo",
+ description="KANNADA LETTER VOCALIC L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C8C,
+ },
+ [0x0C8E]={
+ category="lo",
+ description="KANNADA LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C8E,
+ },
+ [0x0C8F]={
+ category="lo",
+ description="KANNADA LETTER EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C8F,
+ },
+ [0x0C90]={
+ category="lo",
+ description="KANNADA LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C90,
+ },
+ [0x0C92]={
+ category="lo",
+ description="KANNADA LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C92,
+ },
+ [0x0C93]={
+ category="lo",
+ description="KANNADA LETTER OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C93,
+ },
+ [0x0C94]={
+ category="lo",
+ description="KANNADA LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C94,
+ },
+ [0x0C95]={
+ category="lo",
+ description="KANNADA LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C95,
+ },
+ [0x0C96]={
+ category="lo",
+ description="KANNADA LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C96,
+ },
+ [0x0C97]={
+ category="lo",
+ description="KANNADA LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C97,
+ },
+ [0x0C98]={
+ category="lo",
+ description="KANNADA LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C98,
+ },
+ [0x0C99]={
+ category="lo",
+ description="KANNADA LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C99,
+ },
+ [0x0C9A]={
+ category="lo",
+ description="KANNADA LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C9A,
+ },
+ [0x0C9B]={
+ category="lo",
+ description="KANNADA LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C9B,
+ },
+ [0x0C9C]={
+ category="lo",
+ description="KANNADA LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C9C,
+ },
+ [0x0C9D]={
+ category="lo",
+ description="KANNADA LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C9D,
+ },
+ [0x0C9E]={
+ category="lo",
+ description="KANNADA LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C9E,
+ },
+ [0x0C9F]={
+ category="lo",
+ description="KANNADA LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0C9F,
+ },
+ [0x0CA0]={
+ category="lo",
+ description="KANNADA LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CA0,
+ },
+ [0x0CA1]={
+ category="lo",
+ description="KANNADA LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CA1,
+ },
+ [0x0CA2]={
+ category="lo",
+ description="KANNADA LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CA2,
+ },
+ [0x0CA3]={
+ category="lo",
+ description="KANNADA LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CA3,
+ },
+ [0x0CA4]={
+ category="lo",
+ description="KANNADA LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CA4,
+ },
+ [0x0CA5]={
+ category="lo",
+ description="KANNADA LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CA5,
+ },
+ [0x0CA6]={
+ category="lo",
+ description="KANNADA LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CA6,
+ },
+ [0x0CA7]={
+ category="lo",
+ description="KANNADA LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CA7,
+ },
+ [0x0CA8]={
+ category="lo",
+ description="KANNADA LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CA8,
+ },
+ [0x0CAA]={
+ category="lo",
+ description="KANNADA LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CAA,
+ },
+ [0x0CAB]={
+ category="lo",
+ description="KANNADA LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CAB,
+ },
+ [0x0CAC]={
+ category="lo",
+ description="KANNADA LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CAC,
+ },
+ [0x0CAD]={
+ category="lo",
+ description="KANNADA LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CAD,
+ },
+ [0x0CAE]={
+ category="lo",
+ description="KANNADA LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CAE,
+ },
+ [0x0CAF]={
+ category="lo",
+ description="KANNADA LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CAF,
+ },
+ [0x0CB0]={
+ category="lo",
+ description="KANNADA LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CB0,
+ },
+ [0x0CB1]={
+ category="lo",
+ description="KANNADA LETTER RRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CB1,
+ },
+ [0x0CB2]={
+ category="lo",
+ description="KANNADA LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CB2,
+ },
+ [0x0CB3]={
+ category="lo",
+ description="KANNADA LETTER LLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CB3,
+ },
+ [0x0CB5]={
+ category="lo",
+ description="KANNADA LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CB5,
+ },
+ [0x0CB6]={
+ category="lo",
+ description="KANNADA LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CB6,
+ },
+ [0x0CB7]={
+ category="lo",
+ description="KANNADA LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CB7,
+ },
+ [0x0CB8]={
+ category="lo",
+ description="KANNADA LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CB8,
+ },
+ [0x0CB9]={
+ category="lo",
+ description="KANNADA LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CB9,
+ },
+ [0x0CBC]={
+ category="mn",
+ description="KANNADA SIGN NUKTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0CBC,
+ },
+ [0x0CBD]={
+ category="lo",
+ description="KANNADA SIGN AVAGRAHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CBD,
+ },
+ [0x0CBE]={
+ category="mc",
+ description="KANNADA VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0CBE,
+ },
+ [0x0CBF]={
+ category="mn",
+ description="KANNADA VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0CBF,
+ },
+ [0x0CC0]={
+ category="mc",
+ description="KANNADA VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0CBF, 0x0CD5 },
+ unicodeslot=0x0CC0,
+ },
+ [0x0CC1]={
+ category="mc",
+ description="KANNADA VOWEL SIGN U",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0CC1,
+ },
+ [0x0CC2]={
+ category="mc",
+ description="KANNADA VOWEL SIGN UU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0CC2,
+ },
+ [0x0CC3]={
+ category="mc",
+ description="KANNADA VOWEL SIGN VOCALIC R",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0CC3,
+ },
+ [0x0CC4]={
+ category="mc",
+ description="KANNADA VOWEL SIGN VOCALIC RR",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0CC4,
+ },
+ [0x0CC6]={
+ category="mn",
+ description="KANNADA VOWEL SIGN E",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0CC6,
+ },
+ [0x0CC7]={
+ category="mc",
+ description="KANNADA VOWEL SIGN EE",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0CC6, 0x0CD5 },
+ unicodeslot=0x0CC7,
+ },
+ [0x0CC8]={
+ category="mc",
+ description="KANNADA VOWEL SIGN AI",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0CC6, 0x0CD6 },
+ unicodeslot=0x0CC8,
+ },
+ [0x0CCA]={
+ category="mc",
+ description="KANNADA VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0CC6, 0x0CC2 },
+ unicodeslot=0x0CCA,
+ },
+ [0x0CCB]={
+ category="mc",
+ description="KANNADA VOWEL SIGN OO",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0CCA, 0x0CD5 },
+ unicodeslot=0x0CCB,
+ },
+ [0x0CCC]={
+ category="mn",
+ description="KANNADA VOWEL SIGN AU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0CCC,
+ },
+ [0x0CCD]={
+ category="mn",
+ description="KANNADA SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0CCD,
+ },
+ [0x0CD5]={
+ category="mc",
+ description="KANNADA LENGTH MARK",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0CD5,
+ },
+ [0x0CD6]={
+ category="mc",
+ description="KANNADA AI LENGTH MARK",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0CD6,
+ },
+ [0x0CDE]={
+ category="lo",
+ description="KANNADA LETTER FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CDE,
+ },
+ [0x0CE0]={
+ category="lo",
+ description="KANNADA LETTER VOCALIC RR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CE0,
+ },
+ [0x0CE1]={
+ category="lo",
+ description="KANNADA LETTER VOCALIC LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CE1,
+ },
+ [0x0CE2]={
+ category="mn",
+ description="KANNADA VOWEL SIGN VOCALIC L",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0CE2,
+ },
+ [0x0CE3]={
+ category="mn",
+ description="KANNADA VOWEL SIGN VOCALIC LL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0CE3,
+ },
+ [0x0CE6]={
+ category="nd",
+ description="KANNADA DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0CE6,
+ },
+ [0x0CE7]={
+ category="nd",
+ description="KANNADA DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0CE7,
+ },
+ [0x0CE8]={
+ category="nd",
+ description="KANNADA DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0CE8,
+ },
+ [0x0CE9]={
+ category="nd",
+ description="KANNADA DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0CE9,
+ },
+ [0x0CEA]={
+ category="nd",
+ description="KANNADA DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0CEA,
+ },
+ [0x0CEB]={
+ category="nd",
+ description="KANNADA DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0CEB,
+ },
+ [0x0CEC]={
+ category="nd",
+ description="KANNADA DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0CEC,
+ },
+ [0x0CED]={
+ category="nd",
+ description="KANNADA DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0CED,
+ },
+ [0x0CEE]={
+ category="nd",
+ description="KANNADA DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0CEE,
+ },
+ [0x0CEF]={
+ category="nd",
+ description="KANNADA DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0CEF,
+ },
+ [0x0CF1]={
+ category="so",
+ description="KANNADA SIGN JIHVAMULIYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CF1,
+ },
+ [0x0CF2]={
+ category="so",
+ description="KANNADA SIGN UPADHMANIYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0CF2,
+ },
+ [0x0D02]={
+ category="mc",
+ description="MALAYALAM SIGN ANUSVARA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0D02,
+ },
+ [0x0D03]={
+ category="mc",
+ description="MALAYALAM SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0D03,
+ },
+ [0x0D05]={
+ category="lo",
+ description="MALAYALAM LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D05,
+ },
+ [0x0D06]={
+ category="lo",
+ description="MALAYALAM LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D06,
+ },
+ [0x0D07]={
+ category="lo",
+ description="MALAYALAM LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D07,
+ },
+ [0x0D08]={
+ category="lo",
+ description="MALAYALAM LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D08,
+ },
+ [0x0D09]={
+ category="lo",
+ description="MALAYALAM LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D09,
+ },
+ [0x0D0A]={
+ category="lo",
+ description="MALAYALAM LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D0A,
+ },
+ [0x0D0B]={
+ category="lo",
+ description="MALAYALAM LETTER VOCALIC R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D0B,
+ },
+ [0x0D0C]={
+ category="lo",
+ description="MALAYALAM LETTER VOCALIC L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D0C,
+ },
+ [0x0D0E]={
+ category="lo",
+ description="MALAYALAM LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D0E,
+ },
+ [0x0D0F]={
+ category="lo",
+ description="MALAYALAM LETTER EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D0F,
+ },
+ [0x0D10]={
+ category="lo",
+ description="MALAYALAM LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D10,
+ },
+ [0x0D12]={
+ category="lo",
+ description="MALAYALAM LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D12,
+ },
+ [0x0D13]={
+ category="lo",
+ description="MALAYALAM LETTER OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D13,
+ },
+ [0x0D14]={
+ category="lo",
+ description="MALAYALAM LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D14,
+ },
+ [0x0D15]={
+ category="lo",
+ description="MALAYALAM LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D15,
+ },
+ [0x0D16]={
+ category="lo",
+ description="MALAYALAM LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D16,
+ },
+ [0x0D17]={
+ category="lo",
+ description="MALAYALAM LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D17,
+ },
+ [0x0D18]={
+ category="lo",
+ description="MALAYALAM LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D18,
+ },
+ [0x0D19]={
+ category="lo",
+ description="MALAYALAM LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D19,
+ },
+ [0x0D1A]={
+ category="lo",
+ description="MALAYALAM LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D1A,
+ },
+ [0x0D1B]={
+ category="lo",
+ description="MALAYALAM LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D1B,
+ },
+ [0x0D1C]={
+ category="lo",
+ description="MALAYALAM LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D1C,
+ },
+ [0x0D1D]={
+ category="lo",
+ description="MALAYALAM LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D1D,
+ },
+ [0x0D1E]={
+ category="lo",
+ description="MALAYALAM LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D1E,
+ },
+ [0x0D1F]={
+ category="lo",
+ description="MALAYALAM LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D1F,
+ },
+ [0x0D20]={
+ category="lo",
+ description="MALAYALAM LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D20,
+ },
+ [0x0D21]={
+ category="lo",
+ description="MALAYALAM LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D21,
+ },
+ [0x0D22]={
+ category="lo",
+ description="MALAYALAM LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D22,
+ },
+ [0x0D23]={
+ category="lo",
+ description="MALAYALAM LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D23,
+ },
+ [0x0D24]={
+ category="lo",
+ description="MALAYALAM LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D24,
+ },
+ [0x0D25]={
+ category="lo",
+ description="MALAYALAM LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D25,
+ },
+ [0x0D26]={
+ category="lo",
+ description="MALAYALAM LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D26,
+ },
+ [0x0D27]={
+ category="lo",
+ description="MALAYALAM LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D27,
+ },
+ [0x0D28]={
+ category="lo",
+ description="MALAYALAM LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D28,
+ },
+ [0x0D29]={
+ category="lo",
+ description="MALAYALAM LETTER NNNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D29,
+ },
+ [0x0D2A]={
+ category="lo",
+ description="MALAYALAM LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D2A,
+ },
+ [0x0D2B]={
+ category="lo",
+ description="MALAYALAM LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D2B,
+ },
+ [0x0D2C]={
+ category="lo",
+ description="MALAYALAM LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D2C,
+ },
+ [0x0D2D]={
+ category="lo",
+ description="MALAYALAM LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D2D,
+ },
+ [0x0D2E]={
+ category="lo",
+ description="MALAYALAM LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D2E,
+ },
+ [0x0D2F]={
+ category="lo",
+ description="MALAYALAM LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D2F,
+ },
+ [0x0D30]={
+ category="lo",
+ description="MALAYALAM LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D30,
+ },
+ [0x0D31]={
+ category="lo",
+ description="MALAYALAM LETTER RRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D31,
+ },
+ [0x0D32]={
+ category="lo",
+ description="MALAYALAM LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D32,
+ },
+ [0x0D33]={
+ category="lo",
+ description="MALAYALAM LETTER LLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D33,
+ },
+ [0x0D34]={
+ category="lo",
+ description="MALAYALAM LETTER LLLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D34,
+ },
+ [0x0D35]={
+ category="lo",
+ description="MALAYALAM LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D35,
+ },
+ [0x0D36]={
+ category="lo",
+ description="MALAYALAM LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D36,
+ },
+ [0x0D37]={
+ category="lo",
+ description="MALAYALAM LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D37,
+ },
+ [0x0D38]={
+ category="lo",
+ description="MALAYALAM LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D38,
+ },
+ [0x0D39]={
+ category="lo",
+ description="MALAYALAM LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D39,
+ },
+ [0x0D3A]={
+ category="lo",
+ description="MALAYALAM LETTER TTTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D3A,
+ },
+ [0x0D3D]={
+ category="lo",
+ description="MALAYALAM SIGN AVAGRAHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D3D,
+ },
+ [0x0D3E]={
+ category="mc",
+ description="MALAYALAM VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0D3E,
+ },
+ [0x0D3F]={
+ category="mc",
+ description="MALAYALAM VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0D3F,
+ },
+ [0x0D40]={
+ category="mc",
+ description="MALAYALAM VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0D40,
+ },
+ [0x0D41]={
+ category="mn",
+ description="MALAYALAM VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0D41,
+ },
+ [0x0D42]={
+ category="mn",
+ description="MALAYALAM VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0D42,
+ },
+ [0x0D43]={
+ category="mn",
+ description="MALAYALAM VOWEL SIGN VOCALIC R",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0D43,
+ },
+ [0x0D44]={
+ category="mn",
+ description="MALAYALAM VOWEL SIGN VOCALIC RR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0D44,
+ },
+ [0x0D46]={
+ category="mc",
+ description="MALAYALAM VOWEL SIGN E",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0D46,
+ },
+ [0x0D47]={
+ category="mc",
+ description="MALAYALAM VOWEL SIGN EE",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0D47,
+ },
+ [0x0D48]={
+ category="mc",
+ description="MALAYALAM VOWEL SIGN AI",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0D48,
+ },
+ [0x0D4A]={
+ category="mc",
+ description="MALAYALAM VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0D46, 0x0D3E },
+ unicodeslot=0x0D4A,
+ },
+ [0x0D4B]={
+ category="mc",
+ description="MALAYALAM VOWEL SIGN OO",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0D47, 0x0D3E },
+ unicodeslot=0x0D4B,
+ },
+ [0x0D4C]={
+ category="mc",
+ description="MALAYALAM VOWEL SIGN AU",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0D46, 0x0D57 },
+ unicodeslot=0x0D4C,
+ },
+ [0x0D4D]={
+ category="mn",
+ description="MALAYALAM SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0D4D,
+ },
+ [0x0D4E]={
+ category="lo",
+ description="MALAYALAM LETTER DOT REPH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D4E,
+ },
+ [0x0D57]={
+ category="mc",
+ description="MALAYALAM AU LENGTH MARK",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0D57,
+ },
+ [0x0D60]={
+ category="lo",
+ description="MALAYALAM LETTER VOCALIC RR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D60,
+ },
+ [0x0D61]={
+ category="lo",
+ description="MALAYALAM LETTER VOCALIC LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D61,
+ },
+ [0x0D62]={
+ category="mn",
+ description="MALAYALAM VOWEL SIGN VOCALIC L",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0D62,
+ },
+ [0x0D63]={
+ category="mn",
+ description="MALAYALAM VOWEL SIGN VOCALIC LL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0D63,
+ },
+ [0x0D66]={
+ category="nd",
+ description="MALAYALAM DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0D66,
+ },
+ [0x0D67]={
+ category="nd",
+ description="MALAYALAM DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0D67,
+ },
+ [0x0D68]={
+ category="nd",
+ description="MALAYALAM DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0D68,
+ },
+ [0x0D69]={
+ category="nd",
+ description="MALAYALAM DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0D69,
+ },
+ [0x0D6A]={
+ category="nd",
+ description="MALAYALAM DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0D6A,
+ },
+ [0x0D6B]={
+ category="nd",
+ description="MALAYALAM DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0D6B,
+ },
+ [0x0D6C]={
+ category="nd",
+ description="MALAYALAM DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0D6C,
+ },
+ [0x0D6D]={
+ category="nd",
+ description="MALAYALAM DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0D6D,
+ },
+ [0x0D6E]={
+ category="nd",
+ description="MALAYALAM DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0D6E,
+ },
+ [0x0D6F]={
+ category="nd",
+ description="MALAYALAM DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0D6F,
+ },
+ [0x0D70]={
+ category="no",
+ description="MALAYALAM NUMBER TEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D70,
+ },
+ [0x0D71]={
+ category="no",
+ description="MALAYALAM NUMBER ONE HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D71,
+ },
+ [0x0D72]={
+ category="no",
+ description="MALAYALAM NUMBER ONE THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D72,
+ },
+ [0x0D73]={
+ category="no",
+ description="MALAYALAM FRACTION ONE QUARTER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D73,
+ },
+ [0x0D74]={
+ category="no",
+ description="MALAYALAM FRACTION ONE HALF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D74,
+ },
+ [0x0D75]={
+ category="no",
+ description="MALAYALAM FRACTION THREE QUARTERS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D75,
+ },
+ [0x0D79]={
+ category="so",
+ description="MALAYALAM DATE MARK",
+ direction="l",
+ linebreak="po",
+ unicodeslot=0x0D79,
+ },
+ [0x0D7A]={
+ category="lo",
+ description="MALAYALAM LETTER CHILLU NN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D7A,
+ },
+ [0x0D7B]={
+ category="lo",
+ description="MALAYALAM LETTER CHILLU N",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D7B,
+ },
+ [0x0D7C]={
+ category="lo",
+ description="MALAYALAM LETTER CHILLU RR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D7C,
+ },
+ [0x0D7D]={
+ category="lo",
+ description="MALAYALAM LETTER CHILLU L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D7D,
+ },
+ [0x0D7E]={
+ category="lo",
+ description="MALAYALAM LETTER CHILLU LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D7E,
+ },
+ [0x0D7F]={
+ category="lo",
+ description="MALAYALAM LETTER CHILLU K",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D7F,
+ },
+ [0x0D82]={
+ category="mc",
+ description="SINHALA SIGN ANUSVARAYA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0D82,
+ },
+ [0x0D83]={
+ category="mc",
+ description="SINHALA SIGN VISARGAYA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0D83,
+ },
+ [0x0D85]={
+ category="lo",
+ description="SINHALA LETTER AYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D85,
+ },
+ [0x0D86]={
+ category="lo",
+ description="SINHALA LETTER AAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D86,
+ },
+ [0x0D87]={
+ category="lo",
+ description="SINHALA LETTER AEYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D87,
+ },
+ [0x0D88]={
+ category="lo",
+ description="SINHALA LETTER AEEYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D88,
+ },
+ [0x0D89]={
+ category="lo",
+ description="SINHALA LETTER IYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D89,
+ },
+ [0x0D8A]={
+ category="lo",
+ description="SINHALA LETTER IIYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D8A,
+ },
+ [0x0D8B]={
+ category="lo",
+ description="SINHALA LETTER UYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D8B,
+ },
+ [0x0D8C]={
+ category="lo",
+ description="SINHALA LETTER UUYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D8C,
+ },
+ [0x0D8D]={
+ category="lo",
+ description="SINHALA LETTER IRUYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D8D,
+ },
+ [0x0D8E]={
+ category="lo",
+ description="SINHALA LETTER IRUUYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D8E,
+ },
+ [0x0D8F]={
+ category="lo",
+ description="SINHALA LETTER ILUYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D8F,
+ },
+ [0x0D90]={
+ category="lo",
+ description="SINHALA LETTER ILUUYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D90,
+ },
+ [0x0D91]={
+ category="lo",
+ description="SINHALA LETTER EYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D91,
+ },
+ [0x0D92]={
+ category="lo",
+ description="SINHALA LETTER EEYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D92,
+ },
+ [0x0D93]={
+ category="lo",
+ description="SINHALA LETTER AIYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D93,
+ },
+ [0x0D94]={
+ category="lo",
+ description="SINHALA LETTER OYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D94,
+ },
+ [0x0D95]={
+ category="lo",
+ description="SINHALA LETTER OOYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D95,
+ },
+ [0x0D96]={
+ category="lo",
+ description="SINHALA LETTER AUYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D96,
+ },
+ [0x0D9A]={
+ category="lo",
+ description="SINHALA LETTER ALPAPRAANA KAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D9A,
+ },
+ [0x0D9B]={
+ category="lo",
+ description="SINHALA LETTER MAHAAPRAANA KAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D9B,
+ },
+ [0x0D9C]={
+ category="lo",
+ description="SINHALA LETTER ALPAPRAANA GAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D9C,
+ },
+ [0x0D9D]={
+ category="lo",
+ description="SINHALA LETTER MAHAAPRAANA GAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D9D,
+ },
+ [0x0D9E]={
+ category="lo",
+ description="SINHALA LETTER KANTAJA NAASIKYAYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D9E,
+ },
+ [0x0D9F]={
+ category="lo",
+ description="SINHALA LETTER SANYAKA GAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0D9F,
+ },
+ [0x0DA0]={
+ category="lo",
+ description="SINHALA LETTER ALPAPRAANA CAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DA0,
+ },
+ [0x0DA1]={
+ category="lo",
+ description="SINHALA LETTER MAHAAPRAANA CAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DA1,
+ },
+ [0x0DA2]={
+ category="lo",
+ description="SINHALA LETTER ALPAPRAANA JAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DA2,
+ },
+ [0x0DA3]={
+ category="lo",
+ description="SINHALA LETTER MAHAAPRAANA JAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DA3,
+ },
+ [0x0DA4]={
+ category="lo",
+ description="SINHALA LETTER TAALUJA NAASIKYAYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DA4,
+ },
+ [0x0DA5]={
+ category="lo",
+ description="SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DA5,
+ },
+ [0x0DA6]={
+ category="lo",
+ description="SINHALA LETTER SANYAKA JAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DA6,
+ },
+ [0x0DA7]={
+ category="lo",
+ description="SINHALA LETTER ALPAPRAANA TTAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DA7,
+ },
+ [0x0DA8]={
+ category="lo",
+ description="SINHALA LETTER MAHAAPRAANA TTAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DA8,
+ },
+ [0x0DA9]={
+ category="lo",
+ description="SINHALA LETTER ALPAPRAANA DDAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DA9,
+ },
+ [0x0DAA]={
+ category="lo",
+ description="SINHALA LETTER MAHAAPRAANA DDAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DAA,
+ },
+ [0x0DAB]={
+ category="lo",
+ description="SINHALA LETTER MUURDHAJA NAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DAB,
+ },
+ [0x0DAC]={
+ category="lo",
+ description="SINHALA LETTER SANYAKA DDAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DAC,
+ },
+ [0x0DAD]={
+ category="lo",
+ description="SINHALA LETTER ALPAPRAANA TAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DAD,
+ },
+ [0x0DAE]={
+ category="lo",
+ description="SINHALA LETTER MAHAAPRAANA TAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DAE,
+ },
+ [0x0DAF]={
+ category="lo",
+ description="SINHALA LETTER ALPAPRAANA DAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DAF,
+ },
+ [0x0DB0]={
+ category="lo",
+ description="SINHALA LETTER MAHAAPRAANA DAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DB0,
+ },
+ [0x0DB1]={
+ category="lo",
+ description="SINHALA LETTER DANTAJA NAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DB1,
+ },
+ [0x0DB3]={
+ category="lo",
+ description="SINHALA LETTER SANYAKA DAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DB3,
+ },
+ [0x0DB4]={
+ category="lo",
+ description="SINHALA LETTER ALPAPRAANA PAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DB4,
+ },
+ [0x0DB5]={
+ category="lo",
+ description="SINHALA LETTER MAHAAPRAANA PAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DB5,
+ },
+ [0x0DB6]={
+ category="lo",
+ description="SINHALA LETTER ALPAPRAANA BAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DB6,
+ },
+ [0x0DB7]={
+ category="lo",
+ description="SINHALA LETTER MAHAAPRAANA BAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DB7,
+ },
+ [0x0DB8]={
+ category="lo",
+ description="SINHALA LETTER MAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DB8,
+ },
+ [0x0DB9]={
+ category="lo",
+ description="SINHALA LETTER AMBA BAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DB9,
+ },
+ [0x0DBA]={
+ category="lo",
+ description="SINHALA LETTER YAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DBA,
+ },
+ [0x0DBB]={
+ category="lo",
+ description="SINHALA LETTER RAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DBB,
+ },
+ [0x0DBD]={
+ category="lo",
+ description="SINHALA LETTER DANTAJA LAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DBD,
+ },
+ [0x0DC0]={
+ category="lo",
+ description="SINHALA LETTER VAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DC0,
+ },
+ [0x0DC1]={
+ category="lo",
+ description="SINHALA LETTER TAALUJA SAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DC1,
+ },
+ [0x0DC2]={
+ category="lo",
+ description="SINHALA LETTER MUURDHAJA SAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DC2,
+ },
+ [0x0DC3]={
+ category="lo",
+ description="SINHALA LETTER DANTAJA SAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DC3,
+ },
+ [0x0DC4]={
+ category="lo",
+ description="SINHALA LETTER HAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DC4,
+ },
+ [0x0DC5]={
+ category="lo",
+ description="SINHALA LETTER MUURDHAJA LAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DC5,
+ },
+ [0x0DC6]={
+ category="lo",
+ description="SINHALA LETTER FAYANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DC6,
+ },
+ [0x0DCA]={
+ category="mn",
+ description="SINHALA SIGN AL-LAKUNA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0DCA,
+ },
+ [0x0DCF]={
+ category="mc",
+ description="SINHALA VOWEL SIGN AELA-PILLA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0DCF,
+ },
+ [0x0DD0]={
+ category="mc",
+ description="SINHALA VOWEL SIGN KETTI AEDA-PILLA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0DD0,
+ },
+ [0x0DD1]={
+ category="mc",
+ description="SINHALA VOWEL SIGN DIGA AEDA-PILLA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0DD1,
+ },
+ [0x0DD2]={
+ category="mn",
+ description="SINHALA VOWEL SIGN KETTI IS-PILLA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0DD2,
+ },
+ [0x0DD3]={
+ category="mn",
+ description="SINHALA VOWEL SIGN DIGA IS-PILLA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0DD3,
+ },
+ [0x0DD4]={
+ category="mn",
+ description="SINHALA VOWEL SIGN KETTI PAA-PILLA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0DD4,
+ },
+ [0x0DD6]={
+ category="mn",
+ description="SINHALA VOWEL SIGN DIGA PAA-PILLA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0DD6,
+ },
+ [0x0DD8]={
+ category="mc",
+ description="SINHALA VOWEL SIGN GAETTA-PILLA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0DD8,
+ },
+ [0x0DD9]={
+ category="mc",
+ description="SINHALA VOWEL SIGN KOMBUVA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0DD9,
+ },
+ [0x0DDA]={
+ category="mc",
+ description="SINHALA VOWEL SIGN DIGA KOMBUVA",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0DD9, 0x0DCA },
+ unicodeslot=0x0DDA,
+ },
+ [0x0DDB]={
+ category="mc",
+ description="SINHALA VOWEL SIGN KOMBU DEKA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0DDB,
+ },
+ [0x0DDC]={
+ category="mc",
+ description="SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0DD9, 0x0DCF },
+ unicodeslot=0x0DDC,
+ },
+ [0x0DDD]={
+ category="mc",
+ description="SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0DDC, 0x0DCA },
+ unicodeslot=0x0DDD,
+ },
+ [0x0DDE]={
+ category="mc",
+ description="SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x0DD9, 0x0DDF },
+ unicodeslot=0x0DDE,
+ },
+ [0x0DDF]={
+ category="mc",
+ description="SINHALA VOWEL SIGN GAYANUKITTA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0DDF,
+ },
+ [0x0DF2]={
+ category="mc",
+ description="SINHALA VOWEL SIGN DIGA GAETTA-PILLA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0DF2,
+ },
+ [0x0DF3]={
+ category="mc",
+ description="SINHALA VOWEL SIGN DIGA GAYANUKITTA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0DF3,
+ },
+ [0x0DF4]={
+ category="po",
+ description="SINHALA PUNCTUATION KUNDDALIYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0DF4,
+ },
+ [0x0E01]={
+ adobename="kokaithai",
+ category="lo",
+ description="THAI CHARACTER KO KAI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E01,
+ },
+ [0x0E02]={
+ adobename="khokhaithai",
+ category="lo",
+ description="THAI CHARACTER KHO KHAI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E02,
+ },
+ [0x0E03]={
+ adobename="khokhuatthai",
+ category="lo",
+ description="THAI CHARACTER KHO KHUAT",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E03,
+ },
+ [0x0E04]={
+ adobename="khokhwaithai",
+ category="lo",
+ description="THAI CHARACTER KHO KHWAI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E04,
+ },
+ [0x0E05]={
+ adobename="khokhonthai",
+ category="lo",
+ description="THAI CHARACTER KHO KHON",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E05,
+ },
+ [0x0E06]={
+ adobename="khorakhangthai",
+ category="lo",
+ description="THAI CHARACTER KHO RAKHANG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E06,
+ },
+ [0x0E07]={
+ adobename="ngonguthai",
+ category="lo",
+ description="THAI CHARACTER NGO NGU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E07,
+ },
+ [0x0E08]={
+ adobename="chochanthai",
+ category="lo",
+ description="THAI CHARACTER CHO CHAN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E08,
+ },
+ [0x0E09]={
+ adobename="chochingthai",
+ category="lo",
+ description="THAI CHARACTER CHO CHING",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E09,
+ },
+ [0x0E0A]={
+ adobename="chochangthai",
+ category="lo",
+ description="THAI CHARACTER CHO CHANG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E0A,
+ },
+ [0x0E0B]={
+ adobename="sosothai",
+ category="lo",
+ description="THAI CHARACTER SO SO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E0B,
+ },
+ [0x0E0C]={
+ adobename="chochoethai",
+ category="lo",
+ description="THAI CHARACTER CHO CHOE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E0C,
+ },
+ [0x0E0D]={
+ adobename="yoyingthai",
+ category="lo",
+ description="THAI CHARACTER YO YING",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E0D,
+ },
+ [0x0E0E]={
+ adobename="dochadathai",
+ category="lo",
+ description="THAI CHARACTER DO CHADA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E0E,
+ },
+ [0x0E0F]={
+ adobename="topatakthai",
+ category="lo",
+ description="THAI CHARACTER TO PATAK",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E0F,
+ },
+ [0x0E10]={
+ adobename="thothanthai",
+ category="lo",
+ description="THAI CHARACTER THO THAN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E10,
+ },
+ [0x0E11]={
+ adobename="thonangmonthothai",
+ category="lo",
+ description="THAI CHARACTER THO NANGMONTHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E11,
+ },
+ [0x0E12]={
+ adobename="thophuthaothai",
+ category="lo",
+ description="THAI CHARACTER THO PHUTHAO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E12,
+ },
+ [0x0E13]={
+ adobename="nonenthai",
+ category="lo",
+ description="THAI CHARACTER NO NEN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E13,
+ },
+ [0x0E14]={
+ adobename="dodekthai",
+ category="lo",
+ description="THAI CHARACTER DO DEK",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E14,
+ },
+ [0x0E15]={
+ adobename="totaothai",
+ category="lo",
+ description="THAI CHARACTER TO TAO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E15,
+ },
+ [0x0E16]={
+ adobename="thothungthai",
+ category="lo",
+ description="THAI CHARACTER THO THUNG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E16,
+ },
+ [0x0E17]={
+ adobename="thothahanthai",
+ category="lo",
+ description="THAI CHARACTER THO THAHAN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E17,
+ },
+ [0x0E18]={
+ adobename="thothongthai",
+ category="lo",
+ description="THAI CHARACTER THO THONG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E18,
+ },
+ [0x0E19]={
+ adobename="nonuthai",
+ category="lo",
+ description="THAI CHARACTER NO NU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E19,
+ },
+ [0x0E1A]={
+ adobename="bobaimaithai",
+ category="lo",
+ description="THAI CHARACTER BO BAIMAI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E1A,
+ },
+ [0x0E1B]={
+ adobename="poplathai",
+ category="lo",
+ description="THAI CHARACTER PO PLA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E1B,
+ },
+ [0x0E1C]={
+ adobename="phophungthai",
+ category="lo",
+ description="THAI CHARACTER PHO PHUNG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E1C,
+ },
+ [0x0E1D]={
+ adobename="fofathai",
+ category="lo",
+ description="THAI CHARACTER FO FA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E1D,
+ },
+ [0x0E1E]={
+ adobename="phophanthai",
+ category="lo",
+ description="THAI CHARACTER PHO PHAN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E1E,
+ },
+ [0x0E1F]={
+ adobename="fofanthai",
+ category="lo",
+ description="THAI CHARACTER FO FAN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E1F,
+ },
+ [0x0E20]={
+ adobename="phosamphaothai",
+ category="lo",
+ description="THAI CHARACTER PHO SAMPHAO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E20,
+ },
+ [0x0E21]={
+ adobename="momathai",
+ category="lo",
+ description="THAI CHARACTER MO MA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E21,
+ },
+ [0x0E22]={
+ adobename="yoyakthai",
+ category="lo",
+ description="THAI CHARACTER YO YAK",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E22,
+ },
+ [0x0E23]={
+ adobename="roruathai",
+ category="lo",
+ description="THAI CHARACTER RO RUA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E23,
+ },
+ [0x0E24]={
+ adobename="ruthai",
+ category="lo",
+ description="THAI CHARACTER RU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E24,
+ },
+ [0x0E25]={
+ adobename="lolingthai",
+ category="lo",
+ description="THAI CHARACTER LO LING",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E25,
+ },
+ [0x0E26]={
+ adobename="luthai",
+ category="lo",
+ description="THAI CHARACTER LU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E26,
+ },
+ [0x0E27]={
+ adobename="wowaenthai",
+ category="lo",
+ description="THAI CHARACTER WO WAEN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E27,
+ },
+ [0x0E28]={
+ adobename="sosalathai",
+ category="lo",
+ description="THAI CHARACTER SO SALA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E28,
+ },
+ [0x0E29]={
+ adobename="sorusithai",
+ category="lo",
+ description="THAI CHARACTER SO RUSI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E29,
+ },
+ [0x0E2A]={
+ adobename="sosuathai",
+ category="lo",
+ description="THAI CHARACTER SO SUA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E2A,
+ },
+ [0x0E2B]={
+ adobename="hohipthai",
+ category="lo",
+ description="THAI CHARACTER HO HIP",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E2B,
+ },
+ [0x0E2C]={
+ adobename="lochulathai",
+ category="lo",
+ description="THAI CHARACTER LO CHULA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E2C,
+ },
+ [0x0E2D]={
+ adobename="oangthai",
+ category="lo",
+ description="THAI CHARACTER O ANG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E2D,
+ },
+ [0x0E2E]={
+ adobename="honokhukthai",
+ category="lo",
+ description="THAI CHARACTER HO NOKHUK",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E2E,
+ },
+ [0x0E2F]={
+ adobename="paiyannoithai",
+ category="lo",
+ description="THAI CHARACTER PAIYANNOI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E2F,
+ },
+ [0x0E30]={
+ adobename="saraathai",
+ category="lo",
+ description="THAI CHARACTER SARA A",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E30,
+ },
+ [0x0E31]={
+ adobename="maihanakatthai",
+ category="mn",
+ description="THAI CHARACTER MAI HAN-AKAT",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E31,
+ },
+ [0x0E32]={
+ adobename="saraaathai",
+ category="lo",
+ description="THAI CHARACTER SARA AA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E32,
+ },
+ [0x0E33]={
+ adobename="saraamthai",
+ category="lo",
+ description="THAI CHARACTER SARA AM",
+ direction="l",
+ linebreak="sa",
+ specials={ "compat", 0x0E4D, 0x0E32 },
+ unicodeslot=0x0E33,
+ },
+ [0x0E34]={
+ adobename="saraithai",
+ category="mn",
+ description="THAI CHARACTER SARA I",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E34,
+ },
+ [0x0E35]={
+ adobename="saraiithai",
+ category="mn",
+ description="THAI CHARACTER SARA II",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E35,
+ },
+ [0x0E36]={
+ adobename="sarauethai",
+ category="mn",
+ description="THAI CHARACTER SARA UE",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E36,
+ },
+ [0x0E37]={
+ adobename="saraueethai",
+ category="mn",
+ description="THAI CHARACTER SARA UEE",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E37,
+ },
+ [0x0E38]={
+ adobename="sarauthai",
+ category="mn",
+ description="THAI CHARACTER SARA U",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E38,
+ },
+ [0x0E39]={
+ adobename="sarauuthai",
+ category="mn",
+ description="THAI CHARACTER SARA UU",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E39,
+ },
+ [0x0E3A]={
+ adobename="phinthuthai",
+ category="mn",
+ description="THAI CHARACTER PHINTHU",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E3A,
+ },
+ [0x0E3F]={
+ adobename="bahtthai",
+ category="sc",
+ description="THAI CURRENCY SYMBOL BAHT",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x0E3F,
+ },
+ [0x0E40]={
+ adobename="saraethai",
+ category="lo",
+ description="THAI CHARACTER SARA E",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E40,
+ },
+ [0x0E41]={
+ adobename="saraaethai",
+ category="lo",
+ description="THAI CHARACTER SARA AE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E41,
+ },
+ [0x0E42]={
+ adobename="saraothai",
+ category="lo",
+ description="THAI CHARACTER SARA O",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E42,
+ },
+ [0x0E43]={
+ adobename="saraaimaimuanthai",
+ category="lo",
+ description="THAI CHARACTER SARA AI MAIMUAN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E43,
+ },
+ [0x0E44]={
+ adobename="saraaimaimalaithai",
+ category="lo",
+ description="THAI CHARACTER SARA AI MAIMALAI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E44,
+ },
+ [0x0E45]={
+ adobename="lakkhangyaothai",
+ category="lo",
+ description="THAI CHARACTER LAKKHANGYAO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E45,
+ },
+ [0x0E46]={
+ adobename="maiyamokthai",
+ category="lm",
+ description="THAI CHARACTER MAIYAMOK",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E46,
+ },
+ [0x0E47]={
+ adobename="maitaikhuthai",
+ category="mn",
+ description="THAI CHARACTER MAITAIKHU",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E47,
+ },
+ [0x0E48]={
+ adobename="maiekthai",
+ category="mn",
+ description="THAI CHARACTER MAI EK",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E48,
+ },
+ [0x0E49]={
+ adobename="maithothai",
+ category="mn",
+ description="THAI CHARACTER MAI THO",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E49,
+ },
+ [0x0E4A]={
+ adobename="maitrithai",
+ category="mn",
+ description="THAI CHARACTER MAI TRI",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E4A,
+ },
+ [0x0E4B]={
+ adobename="maichattawathai",
+ category="mn",
+ description="THAI CHARACTER MAI CHATTAWA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E4B,
+ },
+ [0x0E4C]={
+ adobename="thanthakhatthai",
+ category="mn",
+ description="THAI CHARACTER THANTHAKHAT",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E4C,
+ },
+ [0x0E4D]={
+ adobename="nikhahitthai",
+ category="mn",
+ description="THAI CHARACTER NIKHAHIT",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E4D,
+ },
+ [0x0E4E]={
+ adobename="yamakkanthai",
+ category="mn",
+ description="THAI CHARACTER YAMAKKAN",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0E4E,
+ },
+ [0x0E4F]={
+ adobename="fongmanthai",
+ category="po",
+ description="THAI CHARACTER FONGMAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0E4F,
+ },
+ [0x0E50]={
+ adobename="zerothai",
+ category="nd",
+ description="THAI DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0E50,
+ },
+ [0x0E51]={
+ adobename="onethai",
+ category="nd",
+ description="THAI DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0E51,
+ },
+ [0x0E52]={
+ adobename="twothai",
+ category="nd",
+ description="THAI DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0E52,
+ },
+ [0x0E53]={
+ adobename="threethai",
+ category="nd",
+ description="THAI DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0E53,
+ },
+ [0x0E54]={
+ adobename="fourthai",
+ category="nd",
+ description="THAI DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0E54,
+ },
+ [0x0E55]={
+ adobename="fivethai",
+ category="nd",
+ description="THAI DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0E55,
+ },
+ [0x0E56]={
+ adobename="sixthai",
+ category="nd",
+ description="THAI DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0E56,
+ },
+ [0x0E57]={
+ adobename="seventhai",
+ category="nd",
+ description="THAI DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0E57,
+ },
+ [0x0E58]={
+ adobename="eightthai",
+ category="nd",
+ description="THAI DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0E58,
+ },
+ [0x0E59]={
+ adobename="ninethai",
+ category="nd",
+ description="THAI DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0E59,
+ },
+ [0x0E5A]={
+ adobename="angkhankhuthai",
+ category="po",
+ description="THAI CHARACTER ANGKHANKHU",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x0E5A,
+ },
+ [0x0E5B]={
+ adobename="khomutthai",
+ category="po",
+ description="THAI CHARACTER KHOMUT",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x0E5B,
+ },
+ [0x0E81]={
+ category="lo",
+ description="LAO LETTER KO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E81,
+ },
+ [0x0E82]={
+ category="lo",
+ description="LAO LETTER KHO SUNG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E82,
+ },
+ [0x0E84]={
+ category="lo",
+ description="LAO LETTER KHO TAM",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E84,
+ },
+ [0x0E87]={
+ category="lo",
+ description="LAO LETTER NGO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E87,
+ },
+ [0x0E88]={
+ category="lo",
+ description="LAO LETTER CO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E88,
+ },
+ [0x0E8A]={
+ category="lo",
+ description="LAO LETTER SO TAM",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E8A,
+ },
+ [0x0E8D]={
+ category="lo",
+ description="LAO LETTER NYO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E8D,
+ },
+ [0x0E94]={
+ category="lo",
+ description="LAO LETTER DO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E94,
+ },
+ [0x0E95]={
+ category="lo",
+ description="LAO LETTER TO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E95,
+ },
+ [0x0E96]={
+ category="lo",
+ description="LAO LETTER THO SUNG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E96,
+ },
+ [0x0E97]={
+ category="lo",
+ description="LAO LETTER THO TAM",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E97,
+ },
+ [0x0E99]={
+ category="lo",
+ description="LAO LETTER NO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E99,
+ },
+ [0x0E9A]={
+ category="lo",
+ description="LAO LETTER BO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E9A,
+ },
+ [0x0E9B]={
+ category="lo",
+ description="LAO LETTER PO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E9B,
+ },
+ [0x0E9C]={
+ category="lo",
+ description="LAO LETTER PHO SUNG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E9C,
+ },
+ [0x0E9D]={
+ category="lo",
+ description="LAO LETTER FO TAM",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E9D,
+ },
+ [0x0E9E]={
+ category="lo",
+ description="LAO LETTER PHO TAM",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E9E,
+ },
+ [0x0E9F]={
+ category="lo",
+ description="LAO LETTER FO SUNG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0E9F,
+ },
+ [0x0EA1]={
+ category="lo",
+ description="LAO LETTER MO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EA1,
+ },
+ [0x0EA2]={
+ category="lo",
+ description="LAO LETTER YO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EA2,
+ },
+ [0x0EA3]={
+ category="lo",
+ description="LAO LETTER LO LING",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EA3,
+ },
+ [0x0EA5]={
+ category="lo",
+ description="LAO LETTER LO LOOT",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EA5,
+ },
+ [0x0EA7]={
+ category="lo",
+ description="LAO LETTER WO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EA7,
+ },
+ [0x0EAA]={
+ category="lo",
+ description="LAO LETTER SO SUNG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EAA,
+ },
+ [0x0EAB]={
+ category="lo",
+ description="LAO LETTER HO SUNG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EAB,
+ },
+ [0x0EAD]={
+ category="lo",
+ description="LAO LETTER O",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EAD,
+ },
+ [0x0EAE]={
+ category="lo",
+ description="LAO LETTER HO TAM",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EAE,
+ },
+ [0x0EAF]={
+ category="lo",
+ description="LAO ELLIPSIS",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EAF,
+ },
+ [0x0EB0]={
+ category="lo",
+ description="LAO VOWEL SIGN A",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EB0,
+ },
+ [0x0EB1]={
+ category="mn",
+ description="LAO VOWEL SIGN MAI KAN",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0EB1,
+ },
+ [0x0EB2]={
+ category="lo",
+ description="LAO VOWEL SIGN AA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EB2,
+ },
+ [0x0EB3]={
+ category="lo",
+ description="LAO VOWEL SIGN AM",
+ direction="l",
+ linebreak="sa",
+ specials={ "compat", 0x0ECD, 0x0EB2 },
+ unicodeslot=0x0EB3,
+ },
+ [0x0EB4]={
+ category="mn",
+ description="LAO VOWEL SIGN I",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0EB4,
+ },
+ [0x0EB5]={
+ category="mn",
+ description="LAO VOWEL SIGN II",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0EB5,
+ },
+ [0x0EB6]={
+ category="mn",
+ description="LAO VOWEL SIGN Y",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0EB6,
+ },
+ [0x0EB7]={
+ category="mn",
+ description="LAO VOWEL SIGN YY",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0EB7,
+ },
+ [0x0EB8]={
+ category="mn",
+ description="LAO VOWEL SIGN U",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0EB8,
+ },
+ [0x0EB9]={
+ category="mn",
+ description="LAO VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0EB9,
+ },
+ [0x0EBB]={
+ category="mn",
+ description="LAO VOWEL SIGN MAI KON",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0EBB,
+ },
+ [0x0EBC]={
+ category="mn",
+ description="LAO SEMIVOWEL SIGN LO",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0EBC,
+ },
+ [0x0EBD]={
+ category="lo",
+ description="LAO SEMIVOWEL SIGN NYO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EBD,
+ },
+ [0x0EC0]={
+ category="lo",
+ description="LAO VOWEL SIGN E",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EC0,
+ },
+ [0x0EC1]={
+ category="lo",
+ description="LAO VOWEL SIGN EI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EC1,
+ },
+ [0x0EC2]={
+ category="lo",
+ description="LAO VOWEL SIGN O",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EC2,
+ },
+ [0x0EC3]={
+ category="lo",
+ description="LAO VOWEL SIGN AY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EC3,
+ },
+ [0x0EC4]={
+ category="lo",
+ description="LAO VOWEL SIGN AI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EC4,
+ },
+ [0x0EC6]={
+ category="lm",
+ description="LAO KO LA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EC6,
+ },
+ [0x0EC8]={
+ category="mn",
+ description="LAO TONE MAI EK",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0EC8,
+ },
+ [0x0EC9]={
+ category="mn",
+ description="LAO TONE MAI THO",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0EC9,
+ },
+ [0x0ECA]={
+ category="mn",
+ description="LAO TONE MAI TI",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0ECA,
+ },
+ [0x0ECB]={
+ category="mn",
+ description="LAO TONE MAI CATAWA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0ECB,
+ },
+ [0x0ECC]={
+ category="mn",
+ description="LAO CANCELLATION MARK",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0ECC,
+ },
+ [0x0ECD]={
+ category="mn",
+ description="LAO NIGGAHITA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x0ECD,
+ },
+ [0x0ED0]={
+ category="nd",
+ description="LAO DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0ED0,
+ },
+ [0x0ED1]={
+ category="nd",
+ description="LAO DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0ED1,
+ },
+ [0x0ED2]={
+ category="nd",
+ description="LAO DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0ED2,
+ },
+ [0x0ED3]={
+ category="nd",
+ description="LAO DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0ED3,
+ },
+ [0x0ED4]={
+ category="nd",
+ description="LAO DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0ED4,
+ },
+ [0x0ED5]={
+ category="nd",
+ description="LAO DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0ED5,
+ },
+ [0x0ED6]={
+ category="nd",
+ description="LAO DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0ED6,
+ },
+ [0x0ED7]={
+ category="nd",
+ description="LAO DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0ED7,
+ },
+ [0x0ED8]={
+ category="nd",
+ description="LAO DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0ED8,
+ },
+ [0x0ED9]={
+ category="nd",
+ description="LAO DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0ED9,
+ },
+ [0x0EDC]={
+ category="lo",
+ description="LAO HO NO",
+ direction="l",
+ linebreak="sa",
+ specials={ "compat", 0x0EAB, 0x0E99 },
+ unicodeslot=0x0EDC,
+ },
+ [0x0EDD]={
+ category="lo",
+ description="LAO HO MO",
+ direction="l",
+ linebreak="sa",
+ specials={ "compat", 0x0EAB, 0x0EA1 },
+ unicodeslot=0x0EDD,
+ },
+ [0x0EDE]={
+ category="lo",
+ description="LAO LETTER KHMU GO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EDE,
+ },
+ [0x0EDF]={
+ category="lo",
+ description="LAO LETTER KHMU NYO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x0EDF,
+ },
+ [0x0F00]={
+ category="lo",
+ description="TIBETAN SYLLABLE OM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F00,
+ },
+ [0x0F01]={
+ category="so",
+ description="TIBETAN MARK GTER YIG MGO TRUNCATED A",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x0F01,
+ },
+ [0x0F02]={
+ category="so",
+ description="TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x0F02,
+ },
+ [0x0F03]={
+ category="so",
+ description="TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x0F03,
+ },
+ [0x0F04]={
+ category="po",
+ description="TIBETAN MARK INITIAL YIG MGO MDUN MA",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x0F04,
+ },
+ [0x0F05]={
+ category="po",
+ description="TIBETAN MARK CLOSING YIG MGO SGAB MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F05,
+ },
+ [0x0F06]={
+ category="po",
+ description="TIBETAN MARK CARET YIG MGO PHUR SHAD MA",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x0F06,
+ },
+ [0x0F07]={
+ category="po",
+ description="TIBETAN MARK YIG MGO TSHEG SHAD MA",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x0F07,
+ },
+ [0x0F08]={
+ category="po",
+ description="TIBETAN MARK SBRUL SHAD",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0x0F08,
+ },
+ [0x0F09]={
+ category="po",
+ description="TIBETAN MARK BSKUR YIG MGO",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x0F09,
+ },
+ [0x0F0A]={
+ category="po",
+ description="TIBETAN MARK BKA- SHOG YIG MGO",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x0F0A,
+ },
+ [0x0F0B]={
+ category="po",
+ description="TIBETAN MARK INTERSYLLABIC TSHEG",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x0F0B,
+ },
+ [0x0F0C]={
+ category="po",
+ description="TIBETAN MARK DELIMITER TSHEG BSTAR",
+ direction="l",
+ linebreak="gl",
+ specials={ "nobreak", 0x0F0B },
+ unicodeslot=0x0F0C,
+ },
+ [0x0F0D]={
+ category="po",
+ description="TIBETAN MARK SHAD",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0x0F0D,
+ },
+ [0x0F0E]={
+ category="po",
+ description="TIBETAN MARK NYIS SHAD",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0x0F0E,
+ },
+ [0x0F0F]={
+ category="po",
+ description="TIBETAN MARK TSHEG SHAD",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0x0F0F,
+ },
+ [0x0F10]={
+ category="po",
+ description="TIBETAN MARK NYIS TSHEG SHAD",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0x0F10,
+ },
+ [0x0F11]={
+ category="po",
+ description="TIBETAN MARK RIN CHEN SPUNGS SHAD",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0x0F11,
+ },
+ [0x0F12]={
+ category="po",
+ description="TIBETAN MARK RGYA GRAM SHAD",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0x0F12,
+ },
+ [0x0F13]={
+ category="so",
+ description="TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F13,
+ },
+ [0x0F14]={
+ category="so",
+ description="TIBETAN MARK GTER TSHEG",
+ direction="l",
+ linebreak="ex",
+ unicodeslot=0x0F14,
+ },
+ [0x0F15]={
+ category="so",
+ description="TIBETAN LOGOTYPE SIGN CHAD RTAGS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F15,
+ },
+ [0x0F16]={
+ category="so",
+ description="TIBETAN LOGOTYPE SIGN LHAG RTAGS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F16,
+ },
+ [0x0F17]={
+ category="so",
+ description="TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F17,
+ },
+ [0x0F18]={
+ category="mn",
+ description="TIBETAN ASTROLOGICAL SIGN -KHYUD PA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F18,
+ },
+ [0x0F19]={
+ category="mn",
+ description="TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F19,
+ },
+ [0x0F1A]={
+ category="so",
+ description="TIBETAN SIGN RDEL DKAR GCIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F1A,
+ },
+ [0x0F1B]={
+ category="so",
+ description="TIBETAN SIGN RDEL DKAR GNYIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F1B,
+ },
+ [0x0F1C]={
+ category="so",
+ description="TIBETAN SIGN RDEL DKAR GSUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F1C,
+ },
+ [0x0F1D]={
+ category="so",
+ description="TIBETAN SIGN RDEL NAG GCIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F1D,
+ },
+ [0x0F1E]={
+ category="so",
+ description="TIBETAN SIGN RDEL NAG GNYIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F1E,
+ },
+ [0x0F1F]={
+ category="so",
+ description="TIBETAN SIGN RDEL DKAR RDEL NAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F1F,
+ },
+ [0x0F20]={
+ category="nd",
+ description="TIBETAN DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0F20,
+ },
+ [0x0F21]={
+ category="nd",
+ description="TIBETAN DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0F21,
+ },
+ [0x0F22]={
+ category="nd",
+ description="TIBETAN DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0F22,
+ },
+ [0x0F23]={
+ category="nd",
+ description="TIBETAN DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0F23,
+ },
+ [0x0F24]={
+ category="nd",
+ description="TIBETAN DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0F24,
+ },
+ [0x0F25]={
+ category="nd",
+ description="TIBETAN DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0F25,
+ },
+ [0x0F26]={
+ category="nd",
+ description="TIBETAN DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0F26,
+ },
+ [0x0F27]={
+ category="nd",
+ description="TIBETAN DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0F27,
+ },
+ [0x0F28]={
+ category="nd",
+ description="TIBETAN DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0F28,
+ },
+ [0x0F29]={
+ category="nd",
+ description="TIBETAN DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x0F29,
+ },
+ [0x0F2A]={
+ category="no",
+ description="TIBETAN DIGIT HALF ONE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F2A,
+ },
+ [0x0F2B]={
+ category="no",
+ description="TIBETAN DIGIT HALF TWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F2B,
+ },
+ [0x0F2C]={
+ category="no",
+ description="TIBETAN DIGIT HALF THREE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F2C,
+ },
+ [0x0F2D]={
+ category="no",
+ description="TIBETAN DIGIT HALF FOUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F2D,
+ },
+ [0x0F2E]={
+ category="no",
+ description="TIBETAN DIGIT HALF FIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F2E,
+ },
+ [0x0F2F]={
+ category="no",
+ description="TIBETAN DIGIT HALF SIX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F2F,
+ },
+ [0x0F30]={
+ category="no",
+ description="TIBETAN DIGIT HALF SEVEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F30,
+ },
+ [0x0F31]={
+ category="no",
+ description="TIBETAN DIGIT HALF EIGHT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F31,
+ },
+ [0x0F32]={
+ category="no",
+ description="TIBETAN DIGIT HALF NINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F32,
+ },
+ [0x0F33]={
+ category="no",
+ description="TIBETAN DIGIT HALF ZERO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F33,
+ },
+ [0x0F34]={
+ category="so",
+ description="TIBETAN MARK BSDUS RTAGS",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x0F34,
+ },
+ [0x0F35]={
+ category="mn",
+ description="TIBETAN MARK NGAS BZUNG NYI ZLA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F35,
+ },
+ [0x0F36]={
+ category="so",
+ description="TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F36,
+ },
+ [0x0F37]={
+ category="mn",
+ description="TIBETAN MARK NGAS BZUNG SGOR RTAGS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F37,
+ },
+ [0x0F38]={
+ category="so",
+ description="TIBETAN MARK CHE MGO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F38,
+ },
+ [0x0F39]={
+ category="mn",
+ description="TIBETAN MARK TSA -PHRU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F39,
+ },
+ [0x0F3A]={
+ category="ps",
+ description="TIBETAN MARK GUG RTAGS GYON",
+ direction="on",
+ linebreak="op",
+ mirror=0x0F3B,
+ unicodeslot=0x0F3A,
+ },
+ [0x0F3B]={
+ category="pe",
+ description="TIBETAN MARK GUG RTAGS GYAS",
+ direction="on",
+ linebreak="cl",
+ mirror=0x0F3A,
+ unicodeslot=0x0F3B,
+ },
+ [0x0F3C]={
+ category="ps",
+ description="TIBETAN MARK ANG KHANG GYON",
+ direction="on",
+ linebreak="op",
+ mirror=0x0F3D,
+ unicodeslot=0x0F3C,
+ },
+ [0x0F3D]={
+ category="pe",
+ description="TIBETAN MARK ANG KHANG GYAS",
+ direction="on",
+ linebreak="cl",
+ mirror=0x0F3C,
+ unicodeslot=0x0F3D,
+ },
+ [0x0F3E]={
+ category="mc",
+ description="TIBETAN SIGN YAR TSHES",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0F3E,
+ },
+ [0x0F3F]={
+ category="mc",
+ description="TIBETAN SIGN MAR TSHES",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x0F3F,
+ },
+ [0x0F40]={
+ category="lo",
+ description="TIBETAN LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F40,
+ },
+ [0x0F41]={
+ category="lo",
+ description="TIBETAN LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F41,
+ },
+ [0x0F42]={
+ category="lo",
+ description="TIBETAN LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F42,
+ },
+ [0x0F43]={
+ category="lo",
+ description="TIBETAN LETTER GHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0F42, 0x0FB7 },
+ unicodeslot=0x0F43,
+ },
+ [0x0F44]={
+ category="lo",
+ description="TIBETAN LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F44,
+ },
+ [0x0F45]={
+ category="lo",
+ description="TIBETAN LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F45,
+ },
+ [0x0F46]={
+ category="lo",
+ description="TIBETAN LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F46,
+ },
+ [0x0F47]={
+ category="lo",
+ description="TIBETAN LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F47,
+ },
+ [0x0F49]={
+ category="lo",
+ description="TIBETAN LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F49,
+ },
+ [0x0F4A]={
+ category="lo",
+ description="TIBETAN LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F4A,
+ },
+ [0x0F4B]={
+ category="lo",
+ description="TIBETAN LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F4B,
+ },
+ [0x0F4C]={
+ category="lo",
+ description="TIBETAN LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F4C,
+ },
+ [0x0F4D]={
+ category="lo",
+ description="TIBETAN LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0F4C, 0x0FB7 },
+ unicodeslot=0x0F4D,
+ },
+ [0x0F4E]={
+ category="lo",
+ description="TIBETAN LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F4E,
+ },
+ [0x0F4F]={
+ category="lo",
+ description="TIBETAN LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F4F,
+ },
+ [0x0F50]={
+ category="lo",
+ description="TIBETAN LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F50,
+ },
+ [0x0F51]={
+ category="lo",
+ description="TIBETAN LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F51,
+ },
+ [0x0F52]={
+ category="lo",
+ description="TIBETAN LETTER DHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0F51, 0x0FB7 },
+ unicodeslot=0x0F52,
+ },
+ [0x0F53]={
+ category="lo",
+ description="TIBETAN LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F53,
+ },
+ [0x0F54]={
+ category="lo",
+ description="TIBETAN LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F54,
+ },
+ [0x0F55]={
+ category="lo",
+ description="TIBETAN LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F55,
+ },
+ [0x0F56]={
+ category="lo",
+ description="TIBETAN LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F56,
+ },
+ [0x0F57]={
+ category="lo",
+ description="TIBETAN LETTER BHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0F56, 0x0FB7 },
+ unicodeslot=0x0F57,
+ },
+ [0x0F58]={
+ category="lo",
+ description="TIBETAN LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F58,
+ },
+ [0x0F59]={
+ category="lo",
+ description="TIBETAN LETTER TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F59,
+ },
+ [0x0F5A]={
+ category="lo",
+ description="TIBETAN LETTER TSHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F5A,
+ },
+ [0x0F5B]={
+ category="lo",
+ description="TIBETAN LETTER DZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F5B,
+ },
+ [0x0F5C]={
+ category="lo",
+ description="TIBETAN LETTER DZHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0F5B, 0x0FB7 },
+ unicodeslot=0x0F5C,
+ },
+ [0x0F5D]={
+ category="lo",
+ description="TIBETAN LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F5D,
+ },
+ [0x0F5E]={
+ category="lo",
+ description="TIBETAN LETTER ZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F5E,
+ },
+ [0x0F5F]={
+ category="lo",
+ description="TIBETAN LETTER ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F5F,
+ },
+ [0x0F60]={
+ category="lo",
+ description="TIBETAN LETTER -A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F60,
+ },
+ [0x0F61]={
+ category="lo",
+ description="TIBETAN LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F61,
+ },
+ [0x0F62]={
+ category="lo",
+ description="TIBETAN LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F62,
+ },
+ [0x0F63]={
+ category="lo",
+ description="TIBETAN LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F63,
+ },
+ [0x0F64]={
+ category="lo",
+ description="TIBETAN LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F64,
+ },
+ [0x0F65]={
+ category="lo",
+ description="TIBETAN LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F65,
+ },
+ [0x0F66]={
+ category="lo",
+ description="TIBETAN LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F66,
+ },
+ [0x0F67]={
+ category="lo",
+ description="TIBETAN LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F67,
+ },
+ [0x0F68]={
+ category="lo",
+ description="TIBETAN LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F68,
+ },
+ [0x0F69]={
+ category="lo",
+ description="TIBETAN LETTER KSSA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x0F40, 0x0FB5 },
+ unicodeslot=0x0F69,
+ },
+ [0x0F6A]={
+ category="lo",
+ description="TIBETAN LETTER FIXED-FORM RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F6A,
+ },
+ [0x0F6B]={
+ category="lo",
+ description="TIBETAN LETTER KKA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F6B,
+ },
+ [0x0F6C]={
+ category="lo",
+ description="TIBETAN LETTER RRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F6C,
+ },
+ [0x0F71]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN AA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F71,
+ },
+ [0x0F72]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F72,
+ },
+ [0x0F73]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN II",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0F71, 0x0F72 },
+ unicodeslot=0x0F73,
+ },
+ [0x0F74]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F74,
+ },
+ [0x0F75]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0F71, 0x0F74 },
+ unicodeslot=0x0F75,
+ },
+ [0x0F76]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN VOCALIC R",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0FB2, 0x0F80 },
+ unicodeslot=0x0F76,
+ },
+ [0x0F77]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN VOCALIC RR",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "compat", 0x0FB2, 0x0F81 },
+ unicodeslot=0x0F77,
+ },
+ [0x0F78]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN VOCALIC L",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0FB3, 0x0F80 },
+ unicodeslot=0x0F78,
+ },
+ [0x0F79]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN VOCALIC LL",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "compat", 0x0FB3, 0x0F81 },
+ unicodeslot=0x0F79,
+ },
+ [0x0F7A]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F7A,
+ },
+ [0x0F7B]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN EE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F7B,
+ },
+ [0x0F7C]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F7C,
+ },
+ [0x0F7D]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN OO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F7D,
+ },
+ [0x0F7E]={
+ category="mn",
+ description="TIBETAN SIGN RJES SU NGA RO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F7E,
+ },
+ [0x0F7F]={
+ category="mc",
+ description="TIBETAN SIGN RNAM BCAD",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x0F7F,
+ },
+ [0x0F80]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN REVERSED I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F80,
+ },
+ [0x0F81]={
+ category="mn",
+ description="TIBETAN VOWEL SIGN REVERSED II",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0F71, 0x0F80 },
+ unicodeslot=0x0F81,
+ },
+ [0x0F82]={
+ category="mn",
+ description="TIBETAN SIGN NYI ZLA NAA DA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F82,
+ },
+ [0x0F83]={
+ category="mn",
+ description="TIBETAN SIGN SNA LDAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F83,
+ },
+ [0x0F84]={
+ category="mn",
+ description="TIBETAN MARK HALANTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F84,
+ },
+ [0x0F85]={
+ category="po",
+ description="TIBETAN MARK PALUTA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x0F85,
+ },
+ [0x0F86]={
+ category="mn",
+ description="TIBETAN SIGN LCI RTAGS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F86,
+ },
+ [0x0F87]={
+ category="mn",
+ description="TIBETAN SIGN YANG RTAGS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F87,
+ },
+ [0x0F88]={
+ category="lo",
+ description="TIBETAN SIGN LCE TSA CAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F88,
+ },
+ [0x0F89]={
+ category="lo",
+ description="TIBETAN SIGN MCHU CAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F89,
+ },
+ [0x0F8A]={
+ category="lo",
+ description="TIBETAN SIGN GRU CAN RGYINGS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F8A,
+ },
+ [0x0F8B]={
+ category="lo",
+ description="TIBETAN SIGN GRU MED RGYINGS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F8B,
+ },
+ [0x0F8C]={
+ category="lo",
+ description="TIBETAN SIGN INVERTED MCHU CAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0F8C,
+ },
+ [0x0F8D]={
+ category="mn",
+ description="TIBETAN SUBJOINED SIGN LCE TSA CAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F8D,
+ },
+ [0x0F8E]={
+ category="mn",
+ description="TIBETAN SUBJOINED SIGN MCHU CAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F8E,
+ },
+ [0x0F8F]={
+ category="mn",
+ description="TIBETAN SUBJOINED SIGN INVERTED MCHU CAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F8F,
+ },
+ [0x0F90]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER KA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F90,
+ },
+ [0x0F91]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER KHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F91,
+ },
+ [0x0F92]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER GA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F92,
+ },
+ [0x0F93]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER GHA",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0F92, 0x0FB7 },
+ unicodeslot=0x0F93,
+ },
+ [0x0F94]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER NGA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F94,
+ },
+ [0x0F95]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER CA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F95,
+ },
+ [0x0F96]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER CHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F96,
+ },
+ [0x0F97]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER JA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F97,
+ },
+ [0x0F99]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER NYA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F99,
+ },
+ [0x0F9A]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER TTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F9A,
+ },
+ [0x0F9B]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER TTHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F9B,
+ },
+ [0x0F9C]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER DDA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F9C,
+ },
+ [0x0F9D]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER DDHA",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0F9C, 0x0FB7 },
+ unicodeslot=0x0F9D,
+ },
+ [0x0F9E]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER NNA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F9E,
+ },
+ [0x0F9F]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER TA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0F9F,
+ },
+ [0x0FA0]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER THA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FA0,
+ },
+ [0x0FA1]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER DA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FA1,
+ },
+ [0x0FA2]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER DHA",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0FA1, 0x0FB7 },
+ unicodeslot=0x0FA2,
+ },
+ [0x0FA3]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER NA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FA3,
+ },
+ [0x0FA4]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER PA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FA4,
+ },
+ [0x0FA5]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER PHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FA5,
+ },
+ [0x0FA6]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER BA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FA6,
+ },
+ [0x0FA7]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER BHA",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0FA6, 0x0FB7 },
+ unicodeslot=0x0FA7,
+ },
+ [0x0FA8]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER MA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FA8,
+ },
+ [0x0FA9]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER TSA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FA9,
+ },
+ [0x0FAA]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER TSHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FAA,
+ },
+ [0x0FAB]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER DZA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FAB,
+ },
+ [0x0FAC]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER DZHA",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0FAB, 0x0FB7 },
+ unicodeslot=0x0FAC,
+ },
+ [0x0FAD]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER WA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FAD,
+ },
+ [0x0FAE]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER ZHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FAE,
+ },
+ [0x0FAF]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER ZA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FAF,
+ },
+ [0x0FB0]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER -A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FB0,
+ },
+ [0x0FB1]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER YA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FB1,
+ },
+ [0x0FB2]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER RA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FB2,
+ },
+ [0x0FB3]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER LA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FB3,
+ },
+ [0x0FB4]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER SHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FB4,
+ },
+ [0x0FB5]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER SSA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FB5,
+ },
+ [0x0FB6]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER SA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FB6,
+ },
+ [0x0FB7]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER HA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FB7,
+ },
+ [0x0FB8]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FB8,
+ },
+ [0x0FB9]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER KSSA",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x0F90, 0x0FB5 },
+ unicodeslot=0x0FB9,
+ },
+ [0x0FBA]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER FIXED-FORM WA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FBA,
+ },
+ [0x0FBB]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER FIXED-FORM YA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FBB,
+ },
+ [0x0FBC]={
+ category="mn",
+ description="TIBETAN SUBJOINED LETTER FIXED-FORM RA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FBC,
+ },
+ [0x0FBE]={
+ category="so",
+ description="TIBETAN KU RU KHA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x0FBE,
+ },
+ [0x0FBF]={
+ category="so",
+ description="TIBETAN KU RU KHA BZHI MIG CAN",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x0FBF,
+ },
+ [0x0FC0]={
+ category="so",
+ description="TIBETAN CANTILLATION SIGN HEAVY BEAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FC0,
+ },
+ [0x0FC1]={
+ category="so",
+ description="TIBETAN CANTILLATION SIGN LIGHT BEAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FC1,
+ },
+ [0x0FC2]={
+ category="so",
+ description="TIBETAN CANTILLATION SIGN CANG TE-U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FC2,
+ },
+ [0x0FC3]={
+ category="so",
+ description="TIBETAN CANTILLATION SIGN SBUB -CHAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FC3,
+ },
+ [0x0FC4]={
+ category="so",
+ description="TIBETAN SYMBOL DRIL BU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FC4,
+ },
+ [0x0FC5]={
+ category="so",
+ description="TIBETAN SYMBOL RDO RJE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FC5,
+ },
+ [0x0FC6]={
+ category="mn",
+ description="TIBETAN SYMBOL PADMA GDAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x0FC6,
+ },
+ [0x0FC7]={
+ category="so",
+ description="TIBETAN SYMBOL RDO RJE RGYA GRAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FC7,
+ },
+ [0x0FC8]={
+ category="so",
+ description="TIBETAN SYMBOL PHUR PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FC8,
+ },
+ [0x0FC9]={
+ category="so",
+ description="TIBETAN SYMBOL NOR BU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FC9,
+ },
+ [0x0FCA]={
+ category="so",
+ description="TIBETAN SYMBOL NOR BU NYIS -KHYIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FCA,
+ },
+ [0x0FCB]={
+ category="so",
+ description="TIBETAN SYMBOL NOR BU GSUM -KHYIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FCB,
+ },
+ [0x0FCC]={
+ category="so",
+ description="TIBETAN SYMBOL NOR BU BZHI -KHYIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FCC,
+ },
+ [0x0FCE]={
+ category="so",
+ description="TIBETAN SIGN RDEL NAG RDEL DKAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FCE,
+ },
+ [0x0FCF]={
+ category="so",
+ description="TIBETAN SIGN RDEL NAG GSUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FCF,
+ },
+ [0x0FD0]={
+ category="po",
+ description="TIBETAN MARK BSKA- SHOG GI MGO RGYAN",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x0FD0,
+ },
+ [0x0FD1]={
+ category="po",
+ description="TIBETAN MARK MNYAM YIG GI MGO RGYAN",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x0FD1,
+ },
+ [0x0FD2]={
+ category="po",
+ description="TIBETAN MARK NYIS TSHEG",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x0FD2,
+ },
+ [0x0FD3]={
+ category="po",
+ description="TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA",
+ direction="l",
+ linebreak="bb",
+ unicodeslot=0x0FD3,
+ },
+ [0x0FD4]={
+ category="po",
+ description="TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FD4,
+ },
+ [0x0FD5]={
+ category="so",
+ description="RIGHT-FACING SVASTI SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FD5,
+ },
+ [0x0FD6]={
+ category="so",
+ description="LEFT-FACING SVASTI SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FD6,
+ },
+ [0x0FD7]={
+ category="so",
+ description="RIGHT-FACING SVASTI SIGN WITH DOTS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FD7,
+ },
+ [0x0FD8]={
+ category="so",
+ description="LEFT-FACING SVASTI SIGN WITH DOTS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x0FD8,
+ },
+ [0x0FD9]={
+ category="po",
+ description="TIBETAN MARK LEADING MCHAN RTAGS",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0x0FD9,
+ },
+ [0x0FDA]={
+ category="po",
+ description="TIBETAN MARK TRAILING MCHAN RTAGS",
+ direction="l",
+ linebreak="gl",
+ unicodeslot=0x0FDA,
+ },
+ [0x1000]={
+ category="lo",
+ description="MYANMAR LETTER KA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1000,
+ },
+ [0x1001]={
+ category="lo",
+ description="MYANMAR LETTER KHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1001,
+ },
+ [0x1002]={
+ category="lo",
+ description="MYANMAR LETTER GA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1002,
+ },
+ [0x1003]={
+ category="lo",
+ description="MYANMAR LETTER GHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1003,
+ },
+ [0x1004]={
+ category="lo",
+ description="MYANMAR LETTER NGA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1004,
+ },
+ [0x1005]={
+ category="lo",
+ description="MYANMAR LETTER CA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1005,
+ },
+ [0x1006]={
+ category="lo",
+ description="MYANMAR LETTER CHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1006,
+ },
+ [0x1007]={
+ category="lo",
+ description="MYANMAR LETTER JA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1007,
+ },
+ [0x1008]={
+ category="lo",
+ description="MYANMAR LETTER JHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1008,
+ },
+ [0x1009]={
+ category="lo",
+ description="MYANMAR LETTER NYA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1009,
+ },
+ [0x100A]={
+ category="lo",
+ description="MYANMAR LETTER NNYA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x100A,
+ },
+ [0x100B]={
+ category="lo",
+ description="MYANMAR LETTER TTA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x100B,
+ },
+ [0x100C]={
+ category="lo",
+ description="MYANMAR LETTER TTHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x100C,
+ },
+ [0x100D]={
+ category="lo",
+ description="MYANMAR LETTER DDA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x100D,
+ },
+ [0x100E]={
+ category="lo",
+ description="MYANMAR LETTER DDHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x100E,
+ },
+ [0x100F]={
+ category="lo",
+ description="MYANMAR LETTER NNA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x100F,
+ },
+ [0x1010]={
+ category="lo",
+ description="MYANMAR LETTER TA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1010,
+ },
+ [0x1011]={
+ category="lo",
+ description="MYANMAR LETTER THA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1011,
+ },
+ [0x1012]={
+ category="lo",
+ description="MYANMAR LETTER DA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1012,
+ },
+ [0x1013]={
+ category="lo",
+ description="MYANMAR LETTER DHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1013,
+ },
+ [0x1014]={
+ category="lo",
+ description="MYANMAR LETTER NA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1014,
+ },
+ [0x1015]={
+ category="lo",
+ description="MYANMAR LETTER PA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1015,
+ },
+ [0x1016]={
+ category="lo",
+ description="MYANMAR LETTER PHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1016,
+ },
+ [0x1017]={
+ category="lo",
+ description="MYANMAR LETTER BA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1017,
+ },
+ [0x1018]={
+ category="lo",
+ description="MYANMAR LETTER BHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1018,
+ },
+ [0x1019]={
+ category="lo",
+ description="MYANMAR LETTER MA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1019,
+ },
+ [0x101A]={
+ category="lo",
+ description="MYANMAR LETTER YA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x101A,
+ },
+ [0x101B]={
+ category="lo",
+ description="MYANMAR LETTER RA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x101B,
+ },
+ [0x101C]={
+ category="lo",
+ description="MYANMAR LETTER LA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x101C,
+ },
+ [0x101D]={
+ category="lo",
+ description="MYANMAR LETTER WA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x101D,
+ },
+ [0x101E]={
+ category="lo",
+ description="MYANMAR LETTER SA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x101E,
+ },
+ [0x101F]={
+ category="lo",
+ description="MYANMAR LETTER HA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x101F,
+ },
+ [0x1020]={
+ category="lo",
+ description="MYANMAR LETTER LLA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1020,
+ },
+ [0x1021]={
+ category="lo",
+ description="MYANMAR LETTER A",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1021,
+ },
+ [0x1022]={
+ category="lo",
+ description="MYANMAR LETTER SHAN A",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1022,
+ },
+ [0x1023]={
+ category="lo",
+ description="MYANMAR LETTER I",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1023,
+ },
+ [0x1024]={
+ category="lo",
+ description="MYANMAR LETTER II",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1024,
+ },
+ [0x1025]={
+ category="lo",
+ description="MYANMAR LETTER U",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1025,
+ },
+ [0x1026]={
+ category="lo",
+ description="MYANMAR LETTER UU",
+ direction="l",
+ linebreak="sa",
+ specials={ "char", 0x1025, 0x102E },
+ unicodeslot=0x1026,
+ },
+ [0x1027]={
+ category="lo",
+ description="MYANMAR LETTER E",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1027,
+ },
+ [0x1028]={
+ category="lo",
+ description="MYANMAR LETTER MON E",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1028,
+ },
+ [0x1029]={
+ category="lo",
+ description="MYANMAR LETTER O",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1029,
+ },
+ [0x102A]={
+ category="lo",
+ description="MYANMAR LETTER AU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x102A,
+ },
+ [0x102B]={
+ category="mc",
+ description="MYANMAR VOWEL SIGN TALL AA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x102B,
+ },
+ [0x102C]={
+ category="mc",
+ description="MYANMAR VOWEL SIGN AA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x102C,
+ },
+ [0x102D]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN I",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x102D,
+ },
+ [0x102E]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN II",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x102E,
+ },
+ [0x102F]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN U",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x102F,
+ },
+ [0x1030]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1030,
+ },
+ [0x1031]={
+ category="mc",
+ description="MYANMAR VOWEL SIGN E",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1031,
+ },
+ [0x1032]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN AI",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1032,
+ },
+ [0x1033]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN MON II",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1033,
+ },
+ [0x1034]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN MON O",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1034,
+ },
+ [0x1035]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN E ABOVE",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1035,
+ },
+ [0x1036]={
+ category="mn",
+ description="MYANMAR SIGN ANUSVARA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1036,
+ },
+ [0x1037]={
+ category="mn",
+ description="MYANMAR SIGN DOT BELOW",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1037,
+ },
+ [0x1038]={
+ category="mc",
+ description="MYANMAR SIGN VISARGA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1038,
+ },
+ [0x1039]={
+ category="mn",
+ description="MYANMAR SIGN VIRAMA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1039,
+ },
+ [0x103A]={
+ category="mn",
+ description="MYANMAR SIGN ASAT",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x103A,
+ },
+ [0x103B]={
+ category="mc",
+ description="MYANMAR CONSONANT SIGN MEDIAL YA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x103B,
+ },
+ [0x103C]={
+ category="mc",
+ description="MYANMAR CONSONANT SIGN MEDIAL RA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x103C,
+ },
+ [0x103D]={
+ category="mn",
+ description="MYANMAR CONSONANT SIGN MEDIAL WA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x103D,
+ },
+ [0x103E]={
+ category="mn",
+ description="MYANMAR CONSONANT SIGN MEDIAL HA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x103E,
+ },
+ [0x103F]={
+ category="lo",
+ description="MYANMAR LETTER GREAT SA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x103F,
+ },
+ [0x1040]={
+ category="nd",
+ description="MYANMAR DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1040,
+ },
+ [0x1041]={
+ category="nd",
+ description="MYANMAR DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1041,
+ },
+ [0x1042]={
+ category="nd",
+ description="MYANMAR DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1042,
+ },
+ [0x1043]={
+ category="nd",
+ description="MYANMAR DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1043,
+ },
+ [0x1044]={
+ category="nd",
+ description="MYANMAR DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1044,
+ },
+ [0x1045]={
+ category="nd",
+ description="MYANMAR DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1045,
+ },
+ [0x1046]={
+ category="nd",
+ description="MYANMAR DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1046,
+ },
+ [0x1047]={
+ category="nd",
+ description="MYANMAR DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1047,
+ },
+ [0x1048]={
+ category="nd",
+ description="MYANMAR DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1048,
+ },
+ [0x1049]={
+ category="nd",
+ description="MYANMAR DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1049,
+ },
+ [0x104A]={
+ category="po",
+ description="MYANMAR SIGN LITTLE SECTION",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x104A,
+ },
+ [0x104B]={
+ category="po",
+ description="MYANMAR SIGN SECTION",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x104B,
+ },
+ [0x104C]={
+ category="po",
+ description="MYANMAR SYMBOL LOCATIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104C,
+ },
+ [0x104D]={
+ category="po",
+ description="MYANMAR SYMBOL COMPLETED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104D,
+ },
+ [0x104E]={
+ category="po",
+ description="MYANMAR SYMBOL AFOREMENTIONED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104E,
+ },
+ [0x104F]={
+ category="po",
+ description="MYANMAR SYMBOL GENITIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x104F,
+ },
+ [0x1050]={
+ category="lo",
+ description="MYANMAR LETTER SHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1050,
+ },
+ [0x1051]={
+ category="lo",
+ description="MYANMAR LETTER SSA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1051,
+ },
+ [0x1052]={
+ category="lo",
+ description="MYANMAR LETTER VOCALIC R",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1052,
+ },
+ [0x1053]={
+ category="lo",
+ description="MYANMAR LETTER VOCALIC RR",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1053,
+ },
+ [0x1054]={
+ category="lo",
+ description="MYANMAR LETTER VOCALIC L",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1054,
+ },
+ [0x1055]={
+ category="lo",
+ description="MYANMAR LETTER VOCALIC LL",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1055,
+ },
+ [0x1056]={
+ category="mc",
+ description="MYANMAR VOWEL SIGN VOCALIC R",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1056,
+ },
+ [0x1057]={
+ category="mc",
+ description="MYANMAR VOWEL SIGN VOCALIC RR",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1057,
+ },
+ [0x1058]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN VOCALIC L",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1058,
+ },
+ [0x1059]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN VOCALIC LL",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1059,
+ },
+ [0x105A]={
+ category="lo",
+ description="MYANMAR LETTER MON NGA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x105A,
+ },
+ [0x105B]={
+ category="lo",
+ description="MYANMAR LETTER MON JHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x105B,
+ },
+ [0x105C]={
+ category="lo",
+ description="MYANMAR LETTER MON BBA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x105C,
+ },
+ [0x105D]={
+ category="lo",
+ description="MYANMAR LETTER MON BBE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x105D,
+ },
+ [0x105E]={
+ category="mn",
+ description="MYANMAR CONSONANT SIGN MON MEDIAL NA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x105E,
+ },
+ [0x105F]={
+ category="mn",
+ description="MYANMAR CONSONANT SIGN MON MEDIAL MA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x105F,
+ },
+ [0x1060]={
+ category="mn",
+ description="MYANMAR CONSONANT SIGN MON MEDIAL LA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1060,
+ },
+ [0x1061]={
+ category="lo",
+ description="MYANMAR LETTER SGAW KAREN SHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1061,
+ },
+ [0x1062]={
+ category="mc",
+ description="MYANMAR VOWEL SIGN SGAW KAREN EU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1062,
+ },
+ [0x1063]={
+ category="mc",
+ description="MYANMAR TONE MARK SGAW KAREN HATHI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1063,
+ },
+ [0x1064]={
+ category="mc",
+ description="MYANMAR TONE MARK SGAW KAREN KE PHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1064,
+ },
+ [0x1065]={
+ category="lo",
+ description="MYANMAR LETTER WESTERN PWO KAREN THA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1065,
+ },
+ [0x1066]={
+ category="lo",
+ description="MYANMAR LETTER WESTERN PWO KAREN PWA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1066,
+ },
+ [0x1067]={
+ category="mc",
+ description="MYANMAR VOWEL SIGN WESTERN PWO KAREN EU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1067,
+ },
+ [0x1068]={
+ category="mc",
+ description="MYANMAR VOWEL SIGN WESTERN PWO KAREN UE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1068,
+ },
+ [0x1069]={
+ category="mc",
+ description="MYANMAR SIGN WESTERN PWO KAREN TONE-1",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1069,
+ },
+ [0x106A]={
+ category="mc",
+ description="MYANMAR SIGN WESTERN PWO KAREN TONE-2",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x106A,
+ },
+ [0x106B]={
+ category="mc",
+ description="MYANMAR SIGN WESTERN PWO KAREN TONE-3",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x106B,
+ },
+ [0x106C]={
+ category="mc",
+ description="MYANMAR SIGN WESTERN PWO KAREN TONE-4",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x106C,
+ },
+ [0x106D]={
+ category="mc",
+ description="MYANMAR SIGN WESTERN PWO KAREN TONE-5",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x106D,
+ },
+ [0x106E]={
+ category="lo",
+ description="MYANMAR LETTER EASTERN PWO KAREN NNA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x106E,
+ },
+ [0x106F]={
+ category="lo",
+ description="MYANMAR LETTER EASTERN PWO KAREN YWA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x106F,
+ },
+ [0x1070]={
+ category="lo",
+ description="MYANMAR LETTER EASTERN PWO KAREN GHWA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1070,
+ },
+ [0x1071]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN GEBA KAREN I",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1071,
+ },
+ [0x1072]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN KAYAH OE",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1072,
+ },
+ [0x1073]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN KAYAH U",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1073,
+ },
+ [0x1074]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN KAYAH EE",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1074,
+ },
+ [0x1075]={
+ category="lo",
+ description="MYANMAR LETTER SHAN KA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1075,
+ },
+ [0x1076]={
+ category="lo",
+ description="MYANMAR LETTER SHAN KHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1076,
+ },
+ [0x1077]={
+ category="lo",
+ description="MYANMAR LETTER SHAN GA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1077,
+ },
+ [0x1078]={
+ category="lo",
+ description="MYANMAR LETTER SHAN CA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1078,
+ },
+ [0x1079]={
+ category="lo",
+ description="MYANMAR LETTER SHAN ZA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1079,
+ },
+ [0x107A]={
+ category="lo",
+ description="MYANMAR LETTER SHAN NYA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x107A,
+ },
+ [0x107B]={
+ category="lo",
+ description="MYANMAR LETTER SHAN DA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x107B,
+ },
+ [0x107C]={
+ category="lo",
+ description="MYANMAR LETTER SHAN NA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x107C,
+ },
+ [0x107D]={
+ category="lo",
+ description="MYANMAR LETTER SHAN PHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x107D,
+ },
+ [0x107E]={
+ category="lo",
+ description="MYANMAR LETTER SHAN FA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x107E,
+ },
+ [0x107F]={
+ category="lo",
+ description="MYANMAR LETTER SHAN BA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x107F,
+ },
+ [0x1080]={
+ category="lo",
+ description="MYANMAR LETTER SHAN THA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1080,
+ },
+ [0x1081]={
+ category="lo",
+ description="MYANMAR LETTER SHAN HA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1081,
+ },
+ [0x1082]={
+ category="mn",
+ description="MYANMAR CONSONANT SIGN SHAN MEDIAL WA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1082,
+ },
+ [0x1083]={
+ category="mc",
+ description="MYANMAR VOWEL SIGN SHAN AA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1083,
+ },
+ [0x1084]={
+ category="mc",
+ description="MYANMAR VOWEL SIGN SHAN E",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1084,
+ },
+ [0x1085]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN SHAN E ABOVE",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1085,
+ },
+ [0x1086]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN SHAN FINAL Y",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1086,
+ },
+ [0x1087]={
+ category="mc",
+ description="MYANMAR SIGN SHAN TONE-2",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1087,
+ },
+ [0x1088]={
+ category="mc",
+ description="MYANMAR SIGN SHAN TONE-3",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1088,
+ },
+ [0x1089]={
+ category="mc",
+ description="MYANMAR SIGN SHAN TONE-5",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1089,
+ },
+ [0x108A]={
+ category="mc",
+ description="MYANMAR SIGN SHAN TONE-6",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x108A,
+ },
+ [0x108B]={
+ category="mc",
+ description="MYANMAR SIGN SHAN COUNCIL TONE-2",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x108B,
+ },
+ [0x108C]={
+ category="mc",
+ description="MYANMAR SIGN SHAN COUNCIL TONE-3",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x108C,
+ },
+ [0x108D]={
+ category="mn",
+ description="MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x108D,
+ },
+ [0x108E]={
+ category="lo",
+ description="MYANMAR LETTER RUMAI PALAUNG FA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x108E,
+ },
+ [0x108F]={
+ category="mc",
+ description="MYANMAR SIGN RUMAI PALAUNG TONE-5",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x108F,
+ },
+ [0x1090]={
+ category="nd",
+ description="MYANMAR SHAN DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1090,
+ },
+ [0x1091]={
+ category="nd",
+ description="MYANMAR SHAN DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1091,
+ },
+ [0x1092]={
+ category="nd",
+ description="MYANMAR SHAN DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1092,
+ },
+ [0x1093]={
+ category="nd",
+ description="MYANMAR SHAN DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1093,
+ },
+ [0x1094]={
+ category="nd",
+ description="MYANMAR SHAN DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1094,
+ },
+ [0x1095]={
+ category="nd",
+ description="MYANMAR SHAN DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1095,
+ },
+ [0x1096]={
+ category="nd",
+ description="MYANMAR SHAN DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1096,
+ },
+ [0x1097]={
+ category="nd",
+ description="MYANMAR SHAN DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1097,
+ },
+ [0x1098]={
+ category="nd",
+ description="MYANMAR SHAN DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1098,
+ },
+ [0x1099]={
+ category="nd",
+ description="MYANMAR SHAN DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1099,
+ },
+ [0x109A]={
+ category="mc",
+ description="MYANMAR SIGN KHAMTI TONE-1",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x109A,
+ },
+ [0x109B]={
+ category="mc",
+ description="MYANMAR SIGN KHAMTI TONE-3",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x109B,
+ },
+ [0x109C]={
+ category="mc",
+ description="MYANMAR VOWEL SIGN AITON A",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x109C,
+ },
+ [0x109D]={
+ category="mn",
+ description="MYANMAR VOWEL SIGN AITON AI",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x109D,
+ },
+ [0x109E]={
+ category="so",
+ description="MYANMAR SYMBOL SHAN ONE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x109E,
+ },
+ [0x109F]={
+ category="so",
+ description="MYANMAR SYMBOL SHAN EXCLAMATION",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x109F,
+ },
+ [0x10A0]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER AN",
+ direction="l",
+ lccode=0x2D00,
+ linebreak="al",
+ unicodeslot=0x10A0,
+ },
+ [0x10A1]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER BAN",
+ direction="l",
+ lccode=0x2D01,
+ linebreak="al",
+ unicodeslot=0x10A1,
+ },
+ [0x10A2]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER GAN",
+ direction="l",
+ lccode=0x2D02,
+ linebreak="al",
+ unicodeslot=0x10A2,
+ },
+ [0x10A3]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER DON",
+ direction="l",
+ lccode=0x2D03,
+ linebreak="al",
+ unicodeslot=0x10A3,
+ },
+ [0x10A4]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER EN",
+ direction="l",
+ lccode=0x2D04,
+ linebreak="al",
+ unicodeslot=0x10A4,
+ },
+ [0x10A5]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER VIN",
+ direction="l",
+ lccode=0x2D05,
+ linebreak="al",
+ unicodeslot=0x10A5,
+ },
+ [0x10A6]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER ZEN",
+ direction="l",
+ lccode=0x2D06,
+ linebreak="al",
+ unicodeslot=0x10A6,
+ },
+ [0x10A7]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER TAN",
+ direction="l",
+ lccode=0x2D07,
+ linebreak="al",
+ unicodeslot=0x10A7,
+ },
+ [0x10A8]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER IN",
+ direction="l",
+ lccode=0x2D08,
+ linebreak="al",
+ unicodeslot=0x10A8,
+ },
+ [0x10A9]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER KAN",
+ direction="l",
+ lccode=0x2D09,
+ linebreak="al",
+ unicodeslot=0x10A9,
+ },
+ [0x10AA]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER LAS",
+ direction="l",
+ lccode=0x2D0A,
+ linebreak="al",
+ unicodeslot=0x10AA,
+ },
+ [0x10AB]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER MAN",
+ direction="l",
+ lccode=0x2D0B,
+ linebreak="al",
+ unicodeslot=0x10AB,
+ },
+ [0x10AC]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER NAR",
+ direction="l",
+ lccode=0x2D0C,
+ linebreak="al",
+ unicodeslot=0x10AC,
+ },
+ [0x10AD]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER ON",
+ direction="l",
+ lccode=0x2D0D,
+ linebreak="al",
+ unicodeslot=0x10AD,
+ },
+ [0x10AE]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER PAR",
+ direction="l",
+ lccode=0x2D0E,
+ linebreak="al",
+ unicodeslot=0x10AE,
+ },
+ [0x10AF]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER ZHAR",
+ direction="l",
+ lccode=0x2D0F,
+ linebreak="al",
+ unicodeslot=0x10AF,
+ },
+ [0x10B0]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER RAE",
+ direction="l",
+ lccode=0x2D10,
+ linebreak="al",
+ unicodeslot=0x10B0,
+ },
+ [0x10B1]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER SAN",
+ direction="l",
+ lccode=0x2D11,
+ linebreak="al",
+ unicodeslot=0x10B1,
+ },
+ [0x10B2]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER TAR",
+ direction="l",
+ lccode=0x2D12,
+ linebreak="al",
+ unicodeslot=0x10B2,
+ },
+ [0x10B3]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER UN",
+ direction="l",
+ lccode=0x2D13,
+ linebreak="al",
+ unicodeslot=0x10B3,
+ },
+ [0x10B4]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER PHAR",
+ direction="l",
+ lccode=0x2D14,
+ linebreak="al",
+ unicodeslot=0x10B4,
+ },
+ [0x10B5]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER KHAR",
+ direction="l",
+ lccode=0x2D15,
+ linebreak="al",
+ unicodeslot=0x10B5,
+ },
+ [0x10B6]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER GHAN",
+ direction="l",
+ lccode=0x2D16,
+ linebreak="al",
+ unicodeslot=0x10B6,
+ },
+ [0x10B7]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER QAR",
+ direction="l",
+ lccode=0x2D17,
+ linebreak="al",
+ unicodeslot=0x10B7,
+ },
+ [0x10B8]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER SHIN",
+ direction="l",
+ lccode=0x2D18,
+ linebreak="al",
+ unicodeslot=0x10B8,
+ },
+ [0x10B9]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER CHIN",
+ direction="l",
+ lccode=0x2D19,
+ linebreak="al",
+ unicodeslot=0x10B9,
+ },
+ [0x10BA]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER CAN",
+ direction="l",
+ lccode=0x2D1A,
+ linebreak="al",
+ unicodeslot=0x10BA,
+ },
+ [0x10BB]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER JIL",
+ direction="l",
+ lccode=0x2D1B,
+ linebreak="al",
+ unicodeslot=0x10BB,
+ },
+ [0x10BC]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER CIL",
+ direction="l",
+ lccode=0x2D1C,
+ linebreak="al",
+ unicodeslot=0x10BC,
+ },
+ [0x10BD]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER CHAR",
+ direction="l",
+ lccode=0x2D1D,
+ linebreak="al",
+ unicodeslot=0x10BD,
+ },
+ [0x10BE]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER XAN",
+ direction="l",
+ lccode=0x2D1E,
+ linebreak="al",
+ unicodeslot=0x10BE,
+ },
+ [0x10BF]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER JHAN",
+ direction="l",
+ lccode=0x2D1F,
+ linebreak="al",
+ unicodeslot=0x10BF,
+ },
+ [0x10C0]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER HAE",
+ direction="l",
+ lccode=0x2D20,
+ linebreak="al",
+ unicodeslot=0x10C0,
+ },
+ [0x10C1]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER HE",
+ direction="l",
+ lccode=0x2D21,
+ linebreak="al",
+ unicodeslot=0x10C1,
+ },
+ [0x10C2]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER HIE",
+ direction="l",
+ lccode=0x2D22,
+ linebreak="al",
+ unicodeslot=0x10C2,
+ },
+ [0x10C3]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER WE",
+ direction="l",
+ lccode=0x2D23,
+ linebreak="al",
+ unicodeslot=0x10C3,
+ },
+ [0x10C4]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER HAR",
+ direction="l",
+ lccode=0x2D24,
+ linebreak="al",
+ unicodeslot=0x10C4,
+ },
+ [0x10C5]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER HOE",
+ direction="l",
+ lccode=0x2D25,
+ linebreak="al",
+ unicodeslot=0x10C5,
+ },
+ [0x10C7]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER YN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10C7,
+ },
+ [0x10CD]={
+ category="lu",
+ description="GEORGIAN CAPITAL LETTER AEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10CD,
+ },
+ [0x10D0]={
+ category="lo",
+ description="GEORGIAN LETTER AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D0,
+ },
+ [0x10D1]={
+ category="lo",
+ description="GEORGIAN LETTER BAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D1,
+ },
+ [0x10D2]={
+ category="lo",
+ description="GEORGIAN LETTER GAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D2,
+ },
+ [0x10D3]={
+ category="lo",
+ description="GEORGIAN LETTER DON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D3,
+ },
+ [0x10D4]={
+ category="lo",
+ description="GEORGIAN LETTER EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D4,
+ },
+ [0x10D5]={
+ category="lo",
+ description="GEORGIAN LETTER VIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D5,
+ },
+ [0x10D6]={
+ category="lo",
+ description="GEORGIAN LETTER ZEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D6,
+ },
+ [0x10D7]={
+ category="lo",
+ description="GEORGIAN LETTER TAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D7,
+ },
+ [0x10D8]={
+ category="lo",
+ description="GEORGIAN LETTER IN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D8,
+ },
+ [0x10D9]={
+ category="lo",
+ description="GEORGIAN LETTER KAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10D9,
+ },
+ [0x10DA]={
+ category="lo",
+ description="GEORGIAN LETTER LAS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10DA,
+ },
+ [0x10DB]={
+ category="lo",
+ description="GEORGIAN LETTER MAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10DB,
+ },
+ [0x10DC]={
+ category="lo",
+ description="GEORGIAN LETTER NAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10DC,
+ },
+ [0x10DD]={
+ category="lo",
+ description="GEORGIAN LETTER ON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10DD,
+ },
+ [0x10DE]={
+ category="lo",
+ description="GEORGIAN LETTER PAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10DE,
+ },
+ [0x10DF]={
+ category="lo",
+ description="GEORGIAN LETTER ZHAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10DF,
+ },
+ [0x10E0]={
+ category="lo",
+ description="GEORGIAN LETTER RAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E0,
+ },
+ [0x10E1]={
+ category="lo",
+ description="GEORGIAN LETTER SAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E1,
+ },
+ [0x10E2]={
+ category="lo",
+ description="GEORGIAN LETTER TAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E2,
+ },
+ [0x10E3]={
+ category="lo",
+ description="GEORGIAN LETTER UN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E3,
+ },
+ [0x10E4]={
+ category="lo",
+ description="GEORGIAN LETTER PHAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E4,
+ },
+ [0x10E5]={
+ category="lo",
+ description="GEORGIAN LETTER KHAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E5,
+ },
+ [0x10E6]={
+ category="lo",
+ description="GEORGIAN LETTER GHAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E6,
+ },
+ [0x10E7]={
+ category="lo",
+ description="GEORGIAN LETTER QAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E7,
+ },
+ [0x10E8]={
+ category="lo",
+ description="GEORGIAN LETTER SHIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E8,
+ },
+ [0x10E9]={
+ category="lo",
+ description="GEORGIAN LETTER CHIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10E9,
+ },
+ [0x10EA]={
+ category="lo",
+ description="GEORGIAN LETTER CAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10EA,
+ },
+ [0x10EB]={
+ category="lo",
+ description="GEORGIAN LETTER JIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10EB,
+ },
+ [0x10EC]={
+ category="lo",
+ description="GEORGIAN LETTER CIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10EC,
+ },
+ [0x10ED]={
+ category="lo",
+ description="GEORGIAN LETTER CHAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10ED,
+ },
+ [0x10EE]={
+ category="lo",
+ description="GEORGIAN LETTER XAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10EE,
+ },
+ [0x10EF]={
+ category="lo",
+ description="GEORGIAN LETTER JHAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10EF,
+ },
+ [0x10F0]={
+ category="lo",
+ description="GEORGIAN LETTER HAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F0,
+ },
+ [0x10F1]={
+ category="lo",
+ description="GEORGIAN LETTER HE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F1,
+ },
+ [0x10F2]={
+ category="lo",
+ description="GEORGIAN LETTER HIE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F2,
+ },
+ [0x10F3]={
+ category="lo",
+ description="GEORGIAN LETTER WE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F3,
+ },
+ [0x10F4]={
+ category="lo",
+ description="GEORGIAN LETTER HAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F4,
+ },
+ [0x10F5]={
+ category="lo",
+ description="GEORGIAN LETTER HOE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F5,
+ },
+ [0x10F6]={
+ category="lo",
+ description="GEORGIAN LETTER FI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F6,
+ },
+ [0x10F7]={
+ category="lo",
+ description="GEORGIAN LETTER YN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F7,
+ },
+ [0x10F8]={
+ category="lo",
+ description="GEORGIAN LETTER ELIFI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F8,
+ },
+ [0x10F9]={
+ category="lo",
+ description="GEORGIAN LETTER TURNED GAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10F9,
+ },
+ [0x10FA]={
+ category="lo",
+ description="GEORGIAN LETTER AIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10FA,
+ },
+ [0x10FB]={
+ category="po",
+ description="GEORGIAN PARAGRAPH SEPARATOR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10FB,
+ },
+ [0x10FC]={
+ category="lm",
+ description="MODIFIER LETTER GEORGIAN NAR",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x10DC },
+ unicodeslot=0x10FC,
+ },
+ [0x10FD]={
+ category="lo",
+ description="GEORGIAN LETTER AEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10FD,
+ },
+ [0x10FE]={
+ category="lo",
+ description="GEORGIAN LETTER HARD SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10FE,
+ },
+ [0x10FF]={
+ category="lo",
+ description="GEORGIAN LETTER LABIAL SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10FF,
+ },
+ [0x1100]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG KIYEOK",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1100,
+ },
+ [0x1101]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGKIYEOK",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1101,
+ },
+ [0x1102]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG NIEUN",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1102,
+ },
+ [0x1103]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG TIKEUT",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1103,
+ },
+ [0x1104]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGTIKEUT",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1104,
+ },
+ [0x1105]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1105,
+ },
+ [0x1106]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG MIEUM",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1106,
+ },
+ [0x1107]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1107,
+ },
+ [0x1108]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGPIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1108,
+ },
+ [0x1109]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1109,
+ },
+ [0x110A]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGSIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x110A,
+ },
+ [0x110B]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x110B,
+ },
+ [0x110C]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x110C,
+ },
+ [0x110D]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGCIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x110D,
+ },
+ [0x110E]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CHIEUCH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x110E,
+ },
+ [0x110F]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG KHIEUKH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x110F,
+ },
+ [0x1110]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG THIEUTH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1110,
+ },
+ [0x1111]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PHIEUPH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1111,
+ },
+ [0x1112]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG HIEUH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1112,
+ },
+ [0x1113]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG NIEUN-KIYEOK",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1113,
+ },
+ [0x1114]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGNIEUN",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1114,
+ },
+ [0x1115]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG NIEUN-TIKEUT",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1115,
+ },
+ [0x1116]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG NIEUN-PIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1116,
+ },
+ [0x1117]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG TIKEUT-KIYEOK",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1117,
+ },
+ [0x1118]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-NIEUN",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1118,
+ },
+ [0x1119]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGRIEUL",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1119,
+ },
+ [0x111A]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-HIEUH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x111A,
+ },
+ [0x111B]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG KAPYEOUNRIEUL",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x111B,
+ },
+ [0x111C]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG MIEUM-PIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x111C,
+ },
+ [0x111D]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG KAPYEOUNMIEUM",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x111D,
+ },
+ [0x111E]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-KIYEOK",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x111E,
+ },
+ [0x111F]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-NIEUN",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x111F,
+ },
+ [0x1120]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-TIKEUT",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1120,
+ },
+ [0x1121]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-SIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1121,
+ },
+ [0x1122]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-SIOS-KIYEOK",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1122,
+ },
+ [0x1123]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-SIOS-TIKEUT",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1123,
+ },
+ [0x1124]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-SIOS-PIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1124,
+ },
+ [0x1125]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-SSANGSIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1125,
+ },
+ [0x1126]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-SIOS-CIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1126,
+ },
+ [0x1127]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-CIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1127,
+ },
+ [0x1128]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-CHIEUCH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1128,
+ },
+ [0x1129]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-THIEUTH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1129,
+ },
+ [0x112A]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-PHIEUPH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x112A,
+ },
+ [0x112B]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG KAPYEOUNPIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x112B,
+ },
+ [0x112C]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG KAPYEOUNSSANGPIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x112C,
+ },
+ [0x112D]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-KIYEOK",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x112D,
+ },
+ [0x112E]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-NIEUN",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x112E,
+ },
+ [0x112F]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-TIKEUT",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x112F,
+ },
+ [0x1130]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-RIEUL",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1130,
+ },
+ [0x1131]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-MIEUM",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1131,
+ },
+ [0x1132]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-PIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1132,
+ },
+ [0x1133]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-PIEUP-KIYEOK",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1133,
+ },
+ [0x1134]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-SSANGSIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1134,
+ },
+ [0x1135]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-IEUNG",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1135,
+ },
+ [0x1136]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-CIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1136,
+ },
+ [0x1137]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-CHIEUCH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1137,
+ },
+ [0x1138]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-KHIEUKH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1138,
+ },
+ [0x1139]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-THIEUTH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1139,
+ },
+ [0x113A]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-PHIEUPH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x113A,
+ },
+ [0x113B]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SIOS-HIEUH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x113B,
+ },
+ [0x113C]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CHITUEUMSIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x113C,
+ },
+ [0x113D]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CHITUEUMSSANGSIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x113D,
+ },
+ [0x113E]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CEONGCHIEUMSIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x113E,
+ },
+ [0x113F]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x113F,
+ },
+ [0x1140]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PANSIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1140,
+ },
+ [0x1141]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG-KIYEOK",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1141,
+ },
+ [0x1142]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG-TIKEUT",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1142,
+ },
+ [0x1143]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG-MIEUM",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1143,
+ },
+ [0x1144]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG-PIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1144,
+ },
+ [0x1145]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG-SIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1145,
+ },
+ [0x1146]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG-PANSIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1146,
+ },
+ [0x1147]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGIEUNG",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1147,
+ },
+ [0x1148]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG-CIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1148,
+ },
+ [0x1149]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG-CHIEUCH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1149,
+ },
+ [0x114A]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG-THIEUTH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x114A,
+ },
+ [0x114B]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG-PHIEUPH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x114B,
+ },
+ [0x114C]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG YESIEUNG",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x114C,
+ },
+ [0x114D]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CIEUC-IEUNG",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x114D,
+ },
+ [0x114E]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CHITUEUMCIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x114E,
+ },
+ [0x114F]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CHITUEUMSSANGCIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x114F,
+ },
+ [0x1150]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CEONGCHIEUMCIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1150,
+ },
+ [0x1151]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1151,
+ },
+ [0x1152]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CHIEUCH-KHIEUKH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1152,
+ },
+ [0x1153]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CHIEUCH-HIEUH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1153,
+ },
+ [0x1154]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CHITUEUMCHIEUCH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1154,
+ },
+ [0x1155]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG CEONGCHIEUMCHIEUCH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1155,
+ },
+ [0x1156]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PHIEUPH-PIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1156,
+ },
+ [0x1157]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG KAPYEOUNPHIEUPH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1157,
+ },
+ [0x1158]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGHIEUH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1158,
+ },
+ [0x1159]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG YEORINHIEUH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x1159,
+ },
+ [0x115A]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG KIYEOK-TIKEUT",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x115A,
+ },
+ [0x115B]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG NIEUN-SIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x115B,
+ },
+ [0x115C]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG NIEUN-CIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x115C,
+ },
+ [0x115D]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG NIEUN-HIEUH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x115D,
+ },
+ [0x115E]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG TIKEUT-RIEUL",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x115E,
+ },
+ [0x115F]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG FILLER",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0x115F,
+ },
+ [0x1160]={
+ category="lo",
+ description="HANGUL JUNGSEONG FILLER",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1160,
+ },
+ [0x1161]={
+ category="lo",
+ description="HANGUL JUNGSEONG A",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1161,
+ },
+ [0x1162]={
+ category="lo",
+ description="HANGUL JUNGSEONG AE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1162,
+ },
+ [0x1163]={
+ category="lo",
+ description="HANGUL JUNGSEONG YA",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1163,
+ },
+ [0x1164]={
+ category="lo",
+ description="HANGUL JUNGSEONG YAE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1164,
+ },
+ [0x1165]={
+ category="lo",
+ description="HANGUL JUNGSEONG EO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1165,
+ },
+ [0x1166]={
+ category="lo",
+ description="HANGUL JUNGSEONG E",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1166,
+ },
+ [0x1167]={
+ category="lo",
+ description="HANGUL JUNGSEONG YEO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1167,
+ },
+ [0x1168]={
+ category="lo",
+ description="HANGUL JUNGSEONG YE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1168,
+ },
+ [0x1169]={
+ category="lo",
+ description="HANGUL JUNGSEONG O",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1169,
+ },
+ [0x116A]={
+ category="lo",
+ description="HANGUL JUNGSEONG WA",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x116A,
+ },
+ [0x116B]={
+ category="lo",
+ description="HANGUL JUNGSEONG WAE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x116B,
+ },
+ [0x116C]={
+ category="lo",
+ description="HANGUL JUNGSEONG OE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x116C,
+ },
+ [0x116D]={
+ category="lo",
+ description="HANGUL JUNGSEONG YO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x116D,
+ },
+ [0x116E]={
+ category="lo",
+ description="HANGUL JUNGSEONG U",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x116E,
+ },
+ [0x116F]={
+ category="lo",
+ description="HANGUL JUNGSEONG WEO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x116F,
+ },
+ [0x1170]={
+ category="lo",
+ description="HANGUL JUNGSEONG WE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1170,
+ },
+ [0x1171]={
+ category="lo",
+ description="HANGUL JUNGSEONG WI",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1171,
+ },
+ [0x1172]={
+ category="lo",
+ description="HANGUL JUNGSEONG YU",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1172,
+ },
+ [0x1173]={
+ category="lo",
+ description="HANGUL JUNGSEONG EU",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1173,
+ },
+ [0x1174]={
+ category="lo",
+ description="HANGUL JUNGSEONG YI",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1174,
+ },
+ [0x1175]={
+ category="lo",
+ description="HANGUL JUNGSEONG I",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1175,
+ },
+ [0x1176]={
+ category="lo",
+ description="HANGUL JUNGSEONG A-O",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1176,
+ },
+ [0x1177]={
+ category="lo",
+ description="HANGUL JUNGSEONG A-U",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1177,
+ },
+ [0x1178]={
+ category="lo",
+ description="HANGUL JUNGSEONG YA-O",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1178,
+ },
+ [0x1179]={
+ category="lo",
+ description="HANGUL JUNGSEONG YA-YO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1179,
+ },
+ [0x117A]={
+ category="lo",
+ description="HANGUL JUNGSEONG EO-O",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x117A,
+ },
+ [0x117B]={
+ category="lo",
+ description="HANGUL JUNGSEONG EO-U",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x117B,
+ },
+ [0x117C]={
+ category="lo",
+ description="HANGUL JUNGSEONG EO-EU",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x117C,
+ },
+ [0x117D]={
+ category="lo",
+ description="HANGUL JUNGSEONG YEO-O",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x117D,
+ },
+ [0x117E]={
+ category="lo",
+ description="HANGUL JUNGSEONG YEO-U",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x117E,
+ },
+ [0x117F]={
+ category="lo",
+ description="HANGUL JUNGSEONG O-EO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x117F,
+ },
+ [0x1180]={
+ category="lo",
+ description="HANGUL JUNGSEONG O-E",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1180,
+ },
+ [0x1181]={
+ category="lo",
+ description="HANGUL JUNGSEONG O-YE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1181,
+ },
+ [0x1182]={
+ category="lo",
+ description="HANGUL JUNGSEONG O-O",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1182,
+ },
+ [0x1183]={
+ category="lo",
+ description="HANGUL JUNGSEONG O-U",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1183,
+ },
+ [0x1184]={
+ category="lo",
+ description="HANGUL JUNGSEONG YO-YA",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1184,
+ },
+ [0x1185]={
+ category="lo",
+ description="HANGUL JUNGSEONG YO-YAE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1185,
+ },
+ [0x1186]={
+ category="lo",
+ description="HANGUL JUNGSEONG YO-YEO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1186,
+ },
+ [0x1187]={
+ category="lo",
+ description="HANGUL JUNGSEONG YO-O",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1187,
+ },
+ [0x1188]={
+ category="lo",
+ description="HANGUL JUNGSEONG YO-I",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1188,
+ },
+ [0x1189]={
+ category="lo",
+ description="HANGUL JUNGSEONG U-A",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1189,
+ },
+ [0x118A]={
+ category="lo",
+ description="HANGUL JUNGSEONG U-AE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x118A,
+ },
+ [0x118B]={
+ category="lo",
+ description="HANGUL JUNGSEONG U-EO-EU",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x118B,
+ },
+ [0x118C]={
+ category="lo",
+ description="HANGUL JUNGSEONG U-YE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x118C,
+ },
+ [0x118D]={
+ category="lo",
+ description="HANGUL JUNGSEONG U-U",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x118D,
+ },
+ [0x118E]={
+ category="lo",
+ description="HANGUL JUNGSEONG YU-A",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x118E,
+ },
+ [0x118F]={
+ category="lo",
+ description="HANGUL JUNGSEONG YU-EO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x118F,
+ },
+ [0x1190]={
+ category="lo",
+ description="HANGUL JUNGSEONG YU-E",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1190,
+ },
+ [0x1191]={
+ category="lo",
+ description="HANGUL JUNGSEONG YU-YEO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1191,
+ },
+ [0x1192]={
+ category="lo",
+ description="HANGUL JUNGSEONG YU-YE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1192,
+ },
+ [0x1193]={
+ category="lo",
+ description="HANGUL JUNGSEONG YU-U",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1193,
+ },
+ [0x1194]={
+ category="lo",
+ description="HANGUL JUNGSEONG YU-I",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1194,
+ },
+ [0x1195]={
+ category="lo",
+ description="HANGUL JUNGSEONG EU-U",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1195,
+ },
+ [0x1196]={
+ category="lo",
+ description="HANGUL JUNGSEONG EU-EU",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1196,
+ },
+ [0x1197]={
+ category="lo",
+ description="HANGUL JUNGSEONG YI-U",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1197,
+ },
+ [0x1198]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-A",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1198,
+ },
+ [0x1199]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-YA",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x1199,
+ },
+ [0x119A]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-O",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x119A,
+ },
+ [0x119B]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-U",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x119B,
+ },
+ [0x119C]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-EU",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x119C,
+ },
+ [0x119D]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-ARAEA",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x119D,
+ },
+ [0x119E]={
+ category="lo",
+ description="HANGUL JUNGSEONG ARAEA",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x119E,
+ },
+ [0x119F]={
+ category="lo",
+ description="HANGUL JUNGSEONG ARAEA-EO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x119F,
+ },
+ [0x11A0]={
+ category="lo",
+ description="HANGUL JUNGSEONG ARAEA-U",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A0,
+ },
+ [0x11A1]={
+ category="lo",
+ description="HANGUL JUNGSEONG ARAEA-I",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A1,
+ },
+ [0x11A2]={
+ category="lo",
+ description="HANGUL JUNGSEONG SSANGARAEA",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A2,
+ },
+ [0x11A3]={
+ category="lo",
+ description="HANGUL JUNGSEONG A-EU",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A3,
+ },
+ [0x11A4]={
+ category="lo",
+ description="HANGUL JUNGSEONG YA-U",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A4,
+ },
+ [0x11A5]={
+ category="lo",
+ description="HANGUL JUNGSEONG YEO-YA",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A5,
+ },
+ [0x11A6]={
+ category="lo",
+ description="HANGUL JUNGSEONG O-YA",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A6,
+ },
+ [0x11A7]={
+ category="lo",
+ description="HANGUL JUNGSEONG O-YAE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0x11A7,
+ },
+ [0x11A8]={
+ category="lo",
+ description="HANGUL JONGSEONG KIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11A8,
+ },
+ [0x11A9]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGKIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11A9,
+ },
+ [0x11AA]={
+ category="lo",
+ description="HANGUL JONGSEONG KIYEOK-SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11AA,
+ },
+ [0x11AB]={
+ category="lo",
+ description="HANGUL JONGSEONG NIEUN",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11AB,
+ },
+ [0x11AC]={
+ category="lo",
+ description="HANGUL JONGSEONG NIEUN-CIEUC",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11AC,
+ },
+ [0x11AD]={
+ category="lo",
+ description="HANGUL JONGSEONG NIEUN-HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11AD,
+ },
+ [0x11AE]={
+ category="lo",
+ description="HANGUL JONGSEONG TIKEUT",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11AE,
+ },
+ [0x11AF]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11AF,
+ },
+ [0x11B0]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-KIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B0,
+ },
+ [0x11B1]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-MIEUM",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B1,
+ },
+ [0x11B2]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-PIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B2,
+ },
+ [0x11B3]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B3,
+ },
+ [0x11B4]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-THIEUTH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B4,
+ },
+ [0x11B5]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-PHIEUPH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B5,
+ },
+ [0x11B6]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B6,
+ },
+ [0x11B7]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B7,
+ },
+ [0x11B8]={
+ category="lo",
+ description="HANGUL JONGSEONG PIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B8,
+ },
+ [0x11B9]={
+ category="lo",
+ description="HANGUL JONGSEONG PIEUP-SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11B9,
+ },
+ [0x11BA]={
+ category="lo",
+ description="HANGUL JONGSEONG SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11BA,
+ },
+ [0x11BB]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGSIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11BB,
+ },
+ [0x11BC]={
+ category="lo",
+ description="HANGUL JONGSEONG IEUNG",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11BC,
+ },
+ [0x11BD]={
+ category="lo",
+ description="HANGUL JONGSEONG CIEUC",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11BD,
+ },
+ [0x11BE]={
+ category="lo",
+ description="HANGUL JONGSEONG CHIEUCH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11BE,
+ },
+ [0x11BF]={
+ category="lo",
+ description="HANGUL JONGSEONG KHIEUKH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11BF,
+ },
+ [0x11C0]={
+ category="lo",
+ description="HANGUL JONGSEONG THIEUTH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C0,
+ },
+ [0x11C1]={
+ category="lo",
+ description="HANGUL JONGSEONG PHIEUPH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C1,
+ },
+ [0x11C2]={
+ category="lo",
+ description="HANGUL JONGSEONG HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C2,
+ },
+ [0x11C3]={
+ category="lo",
+ description="HANGUL JONGSEONG KIYEOK-RIEUL",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C3,
+ },
+ [0x11C4]={
+ category="lo",
+ description="HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C4,
+ },
+ [0x11C5]={
+ category="lo",
+ description="HANGUL JONGSEONG NIEUN-KIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C5,
+ },
+ [0x11C6]={
+ category="lo",
+ description="HANGUL JONGSEONG NIEUN-TIKEUT",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C6,
+ },
+ [0x11C7]={
+ category="lo",
+ description="HANGUL JONGSEONG NIEUN-SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C7,
+ },
+ [0x11C8]={
+ category="lo",
+ description="HANGUL JONGSEONG NIEUN-PANSIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C8,
+ },
+ [0x11C9]={
+ category="lo",
+ description="HANGUL JONGSEONG NIEUN-THIEUTH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11C9,
+ },
+ [0x11CA]={
+ category="lo",
+ description="HANGUL JONGSEONG TIKEUT-KIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11CA,
+ },
+ [0x11CB]={
+ category="lo",
+ description="HANGUL JONGSEONG TIKEUT-RIEUL",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11CB,
+ },
+ [0x11CC]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-KIYEOK-SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11CC,
+ },
+ [0x11CD]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-NIEUN",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11CD,
+ },
+ [0x11CE]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-TIKEUT",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11CE,
+ },
+ [0x11CF]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11CF,
+ },
+ [0x11D0]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGRIEUL",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D0,
+ },
+ [0x11D1]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D1,
+ },
+ [0x11D2]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-MIEUM-SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D2,
+ },
+ [0x11D3]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-PIEUP-SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D3,
+ },
+ [0x11D4]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-PIEUP-HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D4,
+ },
+ [0x11D5]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D5,
+ },
+ [0x11D6]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-SSANGSIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D6,
+ },
+ [0x11D7]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-PANSIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D7,
+ },
+ [0x11D8]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-KHIEUKH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D8,
+ },
+ [0x11D9]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-YEORINHIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11D9,
+ },
+ [0x11DA]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM-KIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11DA,
+ },
+ [0x11DB]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM-RIEUL",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11DB,
+ },
+ [0x11DC]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM-PIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11DC,
+ },
+ [0x11DD]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM-SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11DD,
+ },
+ [0x11DE]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM-SSANGSIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11DE,
+ },
+ [0x11DF]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM-PANSIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11DF,
+ },
+ [0x11E0]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM-CHIEUCH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E0,
+ },
+ [0x11E1]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM-HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E1,
+ },
+ [0x11E2]={
+ category="lo",
+ description="HANGUL JONGSEONG KAPYEOUNMIEUM",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E2,
+ },
+ [0x11E3]={
+ category="lo",
+ description="HANGUL JONGSEONG PIEUP-RIEUL",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E3,
+ },
+ [0x11E4]={
+ category="lo",
+ description="HANGUL JONGSEONG PIEUP-PHIEUPH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E4,
+ },
+ [0x11E5]={
+ category="lo",
+ description="HANGUL JONGSEONG PIEUP-HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E5,
+ },
+ [0x11E6]={
+ category="lo",
+ description="HANGUL JONGSEONG KAPYEOUNPIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E6,
+ },
+ [0x11E7]={
+ category="lo",
+ description="HANGUL JONGSEONG SIOS-KIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E7,
+ },
+ [0x11E8]={
+ category="lo",
+ description="HANGUL JONGSEONG SIOS-TIKEUT",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E8,
+ },
+ [0x11E9]={
+ category="lo",
+ description="HANGUL JONGSEONG SIOS-RIEUL",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11E9,
+ },
+ [0x11EA]={
+ category="lo",
+ description="HANGUL JONGSEONG SIOS-PIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11EA,
+ },
+ [0x11EB]={
+ category="lo",
+ description="HANGUL JONGSEONG PANSIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11EB,
+ },
+ [0x11EC]={
+ category="lo",
+ description="HANGUL JONGSEONG IEUNG-KIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11EC,
+ },
+ [0x11ED]={
+ category="lo",
+ description="HANGUL JONGSEONG IEUNG-SSANGKIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11ED,
+ },
+ [0x11EE]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGIEUNG",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11EE,
+ },
+ [0x11EF]={
+ category="lo",
+ description="HANGUL JONGSEONG IEUNG-KHIEUKH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11EF,
+ },
+ [0x11F0]={
+ category="lo",
+ description="HANGUL JONGSEONG YESIEUNG",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F0,
+ },
+ [0x11F1]={
+ category="lo",
+ description="HANGUL JONGSEONG YESIEUNG-SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F1,
+ },
+ [0x11F2]={
+ category="lo",
+ description="HANGUL JONGSEONG YESIEUNG-PANSIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F2,
+ },
+ [0x11F3]={
+ category="lo",
+ description="HANGUL JONGSEONG PHIEUPH-PIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F3,
+ },
+ [0x11F4]={
+ category="lo",
+ description="HANGUL JONGSEONG KAPYEOUNPHIEUPH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F4,
+ },
+ [0x11F5]={
+ category="lo",
+ description="HANGUL JONGSEONG HIEUH-NIEUN",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F5,
+ },
+ [0x11F6]={
+ category="lo",
+ description="HANGUL JONGSEONG HIEUH-RIEUL",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F6,
+ },
+ [0x11F7]={
+ category="lo",
+ description="HANGUL JONGSEONG HIEUH-MIEUM",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F7,
+ },
+ [0x11F8]={
+ category="lo",
+ description="HANGUL JONGSEONG HIEUH-PIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F8,
+ },
+ [0x11F9]={
+ category="lo",
+ description="HANGUL JONGSEONG YEORINHIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11F9,
+ },
+ [0x11FA]={
+ category="lo",
+ description="HANGUL JONGSEONG KIYEOK-NIEUN",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11FA,
+ },
+ [0x11FB]={
+ category="lo",
+ description="HANGUL JONGSEONG KIYEOK-PIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11FB,
+ },
+ [0x11FC]={
+ category="lo",
+ description="HANGUL JONGSEONG KIYEOK-CHIEUCH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11FC,
+ },
+ [0x11FD]={
+ category="lo",
+ description="HANGUL JONGSEONG KIYEOK-KHIEUKH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11FD,
+ },
+ [0x11FE]={
+ category="lo",
+ description="HANGUL JONGSEONG KIYEOK-HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11FE,
+ },
+ [0x11FF]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGNIEUN",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0x11FF,
+ },
+ [0x1200]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200,
+ },
+ [0x1201]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201,
+ },
+ [0x1202]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202,
+ },
+ [0x1203]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203,
+ },
+ [0x1204]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204,
+ },
+ [0x1205]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205,
+ },
+ [0x1206]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206,
+ },
+ [0x1207]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207,
+ },
+ [0x1208]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208,
+ },
+ [0x1209]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209,
+ },
+ [0x120A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE LI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A,
+ },
+ [0x120B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE LAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B,
+ },
+ [0x120C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE LEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C,
+ },
+ [0x120D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE LE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D,
+ },
+ [0x120E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE LO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E,
+ },
+ [0x120F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE LWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F,
+ },
+ [0x1210]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210,
+ },
+ [0x1211]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211,
+ },
+ [0x1212]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212,
+ },
+ [0x1213]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213,
+ },
+ [0x1214]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214,
+ },
+ [0x1215]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215,
+ },
+ [0x1216]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216,
+ },
+ [0x1217]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE HHWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217,
+ },
+ [0x1218]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218,
+ },
+ [0x1219]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE MU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219,
+ },
+ [0x121A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A,
+ },
+ [0x121B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE MAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B,
+ },
+ [0x121C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE MEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C,
+ },
+ [0x121D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D,
+ },
+ [0x121E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE MO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E,
+ },
+ [0x121F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE MWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F,
+ },
+ [0x1220]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220,
+ },
+ [0x1221]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SZU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221,
+ },
+ [0x1222]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SZI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222,
+ },
+ [0x1223]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SZAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223,
+ },
+ [0x1224]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SZEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224,
+ },
+ [0x1225]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225,
+ },
+ [0x1226]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SZO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226,
+ },
+ [0x1227]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SZWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227,
+ },
+ [0x1228]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228,
+ },
+ [0x1229]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE RU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229,
+ },
+ [0x122A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE RI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A,
+ },
+ [0x122B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE RAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B,
+ },
+ [0x122C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE REE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C,
+ },
+ [0x122D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE RE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D,
+ },
+ [0x122E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE RO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E,
+ },
+ [0x122F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE RWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F,
+ },
+ [0x1230]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230,
+ },
+ [0x1231]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231,
+ },
+ [0x1232]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232,
+ },
+ [0x1233]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233,
+ },
+ [0x1234]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234,
+ },
+ [0x1235]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235,
+ },
+ [0x1236]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236,
+ },
+ [0x1237]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1237,
+ },
+ [0x1238]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1238,
+ },
+ [0x1239]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1239,
+ },
+ [0x123A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x123A,
+ },
+ [0x123B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x123B,
+ },
+ [0x123C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x123C,
+ },
+ [0x123D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x123D,
+ },
+ [0x123E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x123E,
+ },
+ [0x123F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SHWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x123F,
+ },
+ [0x1240]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240,
+ },
+ [0x1241]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241,
+ },
+ [0x1242]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242,
+ },
+ [0x1243]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243,
+ },
+ [0x1244]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244,
+ },
+ [0x1245]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245,
+ },
+ [0x1246]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1246,
+ },
+ [0x1247]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1247,
+ },
+ [0x1248]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1248,
+ },
+ [0x124A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124A,
+ },
+ [0x124B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124B,
+ },
+ [0x124C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124C,
+ },
+ [0x124D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x124D,
+ },
+ [0x1250]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1250,
+ },
+ [0x1251]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1251,
+ },
+ [0x1252]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1252,
+ },
+ [0x1253]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1253,
+ },
+ [0x1254]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1254,
+ },
+ [0x1255]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1255,
+ },
+ [0x1256]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1256,
+ },
+ [0x1258]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QHWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1258,
+ },
+ [0x125A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QHWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x125A,
+ },
+ [0x125B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QHWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x125B,
+ },
+ [0x125C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QHWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x125C,
+ },
+ [0x125D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QHWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x125D,
+ },
+ [0x1260]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1260,
+ },
+ [0x1261]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1261,
+ },
+ [0x1262]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1262,
+ },
+ [0x1263]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1263,
+ },
+ [0x1264]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1264,
+ },
+ [0x1265]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1265,
+ },
+ [0x1266]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1266,
+ },
+ [0x1267]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1267,
+ },
+ [0x1268]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1268,
+ },
+ [0x1269]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE VU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1269,
+ },
+ [0x126A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE VI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126A,
+ },
+ [0x126B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE VAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126B,
+ },
+ [0x126C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE VEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126C,
+ },
+ [0x126D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE VE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126D,
+ },
+ [0x126E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE VO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126E,
+ },
+ [0x126F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE VWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x126F,
+ },
+ [0x1270]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1270,
+ },
+ [0x1271]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1271,
+ },
+ [0x1272]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1272,
+ },
+ [0x1273]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1273,
+ },
+ [0x1274]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1274,
+ },
+ [0x1275]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1275,
+ },
+ [0x1276]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1276,
+ },
+ [0x1277]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1277,
+ },
+ [0x1278]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1278,
+ },
+ [0x1279]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1279,
+ },
+ [0x127A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127A,
+ },
+ [0x127B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127B,
+ },
+ [0x127C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127C,
+ },
+ [0x127D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127D,
+ },
+ [0x127E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127E,
+ },
+ [0x127F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x127F,
+ },
+ [0x1280]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1280,
+ },
+ [0x1281]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1281,
+ },
+ [0x1282]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1282,
+ },
+ [0x1283]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1283,
+ },
+ [0x1284]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1284,
+ },
+ [0x1285]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1285,
+ },
+ [0x1286]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1286,
+ },
+ [0x1287]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1287,
+ },
+ [0x1288]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1288,
+ },
+ [0x128A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x128A,
+ },
+ [0x128B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x128B,
+ },
+ [0x128C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x128C,
+ },
+ [0x128D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x128D,
+ },
+ [0x1290]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1290,
+ },
+ [0x1291]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1291,
+ },
+ [0x1292]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1292,
+ },
+ [0x1293]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1293,
+ },
+ [0x1294]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1294,
+ },
+ [0x1295]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1295,
+ },
+ [0x1296]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1296,
+ },
+ [0x1297]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1297,
+ },
+ [0x1298]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1298,
+ },
+ [0x1299]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NYU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1299,
+ },
+ [0x129A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x129A,
+ },
+ [0x129B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NYAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x129B,
+ },
+ [0x129C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NYEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x129C,
+ },
+ [0x129D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NYE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x129D,
+ },
+ [0x129E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NYO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x129E,
+ },
+ [0x129F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NYWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x129F,
+ },
+ [0x12A0]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GLOTTAL A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A0,
+ },
+ [0x12A1]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GLOTTAL U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A1,
+ },
+ [0x12A2]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GLOTTAL I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A2,
+ },
+ [0x12A3]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GLOTTAL AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A3,
+ },
+ [0x12A4]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GLOTTAL EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A4,
+ },
+ [0x12A5]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GLOTTAL E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A5,
+ },
+ [0x12A6]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GLOTTAL O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A6,
+ },
+ [0x12A7]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GLOTTAL WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A7,
+ },
+ [0x12A8]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A8,
+ },
+ [0x12A9]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12A9,
+ },
+ [0x12AA]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12AA,
+ },
+ [0x12AB]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12AB,
+ },
+ [0x12AC]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12AC,
+ },
+ [0x12AD]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12AD,
+ },
+ [0x12AE]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12AE,
+ },
+ [0x12AF]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12AF,
+ },
+ [0x12B0]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B0,
+ },
+ [0x12B2]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B2,
+ },
+ [0x12B3]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B3,
+ },
+ [0x12B4]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B4,
+ },
+ [0x12B5]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B5,
+ },
+ [0x12B8]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KXA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B8,
+ },
+ [0x12B9]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KXU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12B9,
+ },
+ [0x12BA]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KXI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12BA,
+ },
+ [0x12BB]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KXAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12BB,
+ },
+ [0x12BC]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KXEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12BC,
+ },
+ [0x12BD]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KXE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12BD,
+ },
+ [0x12BE]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KXO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12BE,
+ },
+ [0x12C0]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KXWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C0,
+ },
+ [0x12C2]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KXWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C2,
+ },
+ [0x12C3]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KXWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C3,
+ },
+ [0x12C4]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KXWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C4,
+ },
+ [0x12C5]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KXWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C5,
+ },
+ [0x12C8]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C8,
+ },
+ [0x12C9]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE WU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12C9,
+ },
+ [0x12CA]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE WI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12CA,
+ },
+ [0x12CB]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE WAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12CB,
+ },
+ [0x12CC]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE WEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12CC,
+ },
+ [0x12CD]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE WE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12CD,
+ },
+ [0x12CE]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE WO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12CE,
+ },
+ [0x12CF]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE WOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12CF,
+ },
+ [0x12D0]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHARYNGEAL A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D0,
+ },
+ [0x12D1]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHARYNGEAL U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D1,
+ },
+ [0x12D2]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHARYNGEAL I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D2,
+ },
+ [0x12D3]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHARYNGEAL AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D3,
+ },
+ [0x12D4]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHARYNGEAL EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D4,
+ },
+ [0x12D5]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHARYNGEAL E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D5,
+ },
+ [0x12D6]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHARYNGEAL O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D6,
+ },
+ [0x12D8]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D8,
+ },
+ [0x12D9]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12D9,
+ },
+ [0x12DA]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12DA,
+ },
+ [0x12DB]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12DB,
+ },
+ [0x12DC]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12DC,
+ },
+ [0x12DD]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12DD,
+ },
+ [0x12DE]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12DE,
+ },
+ [0x12DF]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12DF,
+ },
+ [0x12E0]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E0,
+ },
+ [0x12E1]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E1,
+ },
+ [0x12E2]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E2,
+ },
+ [0x12E3]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E3,
+ },
+ [0x12E4]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E4,
+ },
+ [0x12E5]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E5,
+ },
+ [0x12E6]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E6,
+ },
+ [0x12E7]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZHWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E7,
+ },
+ [0x12E8]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E8,
+ },
+ [0x12E9]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE YU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12E9,
+ },
+ [0x12EA]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE YI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12EA,
+ },
+ [0x12EB]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE YAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12EB,
+ },
+ [0x12EC]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE YEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12EC,
+ },
+ [0x12ED]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE YE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12ED,
+ },
+ [0x12EE]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE YO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12EE,
+ },
+ [0x12EF]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE YOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12EF,
+ },
+ [0x12F0]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F0,
+ },
+ [0x12F1]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F1,
+ },
+ [0x12F2]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F2,
+ },
+ [0x12F3]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F3,
+ },
+ [0x12F4]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F4,
+ },
+ [0x12F5]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F5,
+ },
+ [0x12F6]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F6,
+ },
+ [0x12F7]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F7,
+ },
+ [0x12F8]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F8,
+ },
+ [0x12F9]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12F9,
+ },
+ [0x12FA]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12FA,
+ },
+ [0x12FB]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12FB,
+ },
+ [0x12FC]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12FC,
+ },
+ [0x12FD]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12FD,
+ },
+ [0x12FE]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12FE,
+ },
+ [0x12FF]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12FF,
+ },
+ [0x1300]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300,
+ },
+ [0x1301]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE JU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301,
+ },
+ [0x1302]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE JI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302,
+ },
+ [0x1303]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE JAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303,
+ },
+ [0x1304]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE JEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304,
+ },
+ [0x1305]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE JE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305,
+ },
+ [0x1306]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE JO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306,
+ },
+ [0x1307]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE JWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307,
+ },
+ [0x1308]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308,
+ },
+ [0x1309]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309,
+ },
+ [0x130A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A,
+ },
+ [0x130B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B,
+ },
+ [0x130C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C,
+ },
+ [0x130D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D,
+ },
+ [0x130E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E,
+ },
+ [0x130F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F,
+ },
+ [0x1310]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310,
+ },
+ [0x1312]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312,
+ },
+ [0x1313]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313,
+ },
+ [0x1314]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314,
+ },
+ [0x1315]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315,
+ },
+ [0x1318]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318,
+ },
+ [0x1319]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GGU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319,
+ },
+ [0x131A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A,
+ },
+ [0x131B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GGAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B,
+ },
+ [0x131C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GGEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C,
+ },
+ [0x131D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GGE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D,
+ },
+ [0x131E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GGO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E,
+ },
+ [0x131F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GGWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F,
+ },
+ [0x1320]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320,
+ },
+ [0x1321]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE THU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321,
+ },
+ [0x1322]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE THI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322,
+ },
+ [0x1323]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE THAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323,
+ },
+ [0x1324]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE THEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324,
+ },
+ [0x1325]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE THE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1325,
+ },
+ [0x1326]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE THO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326,
+ },
+ [0x1327]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE THWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327,
+ },
+ [0x1328]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328,
+ },
+ [0x1329]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329,
+ },
+ [0x132A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A,
+ },
+ [0x132B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B,
+ },
+ [0x132C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C,
+ },
+ [0x132D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D,
+ },
+ [0x132E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E,
+ },
+ [0x132F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CHWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F,
+ },
+ [0x1330]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330,
+ },
+ [0x1331]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331,
+ },
+ [0x1332]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332,
+ },
+ [0x1333]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333,
+ },
+ [0x1334]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334,
+ },
+ [0x1335]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335,
+ },
+ [0x1336]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336,
+ },
+ [0x1337]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1337,
+ },
+ [0x1338]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338,
+ },
+ [0x1339]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TSU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339,
+ },
+ [0x133A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TSI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A,
+ },
+ [0x133B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TSAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B,
+ },
+ [0x133C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TSEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C,
+ },
+ [0x133D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TSE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D,
+ },
+ [0x133E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TSO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E,
+ },
+ [0x133F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TSWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F,
+ },
+ [0x1340]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340,
+ },
+ [0x1341]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TZU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341,
+ },
+ [0x1342]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TZI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1342,
+ },
+ [0x1343]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TZAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1343,
+ },
+ [0x1344]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TZEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1344,
+ },
+ [0x1345]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1345,
+ },
+ [0x1346]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TZO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1346,
+ },
+ [0x1347]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TZOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1347,
+ },
+ [0x1348]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1348,
+ },
+ [0x1349]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE FU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1349,
+ },
+ [0x134A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE FI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x134A,
+ },
+ [0x134B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE FAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x134B,
+ },
+ [0x134C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE FEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x134C,
+ },
+ [0x134D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE FE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x134D,
+ },
+ [0x134E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE FO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x134E,
+ },
+ [0x134F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE FWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x134F,
+ },
+ [0x1350]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1350,
+ },
+ [0x1351]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1351,
+ },
+ [0x1352]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1352,
+ },
+ [0x1353]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1353,
+ },
+ [0x1354]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1354,
+ },
+ [0x1355]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1355,
+ },
+ [0x1356]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1356,
+ },
+ [0x1357]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1357,
+ },
+ [0x1358]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE RYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1358,
+ },
+ [0x1359]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE MYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1359,
+ },
+ [0x135A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE FYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x135A,
+ },
+ [0x135D]={
+ category="mn",
+ description="ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x135D,
+ },
+ [0x135E]={
+ category="mn",
+ description="ETHIOPIC COMBINING VOWEL LENGTH MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x135E,
+ },
+ [0x135F]={
+ category="mn",
+ description="ETHIOPIC COMBINING GEMINATION MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x135F,
+ },
+ [0x1360]={
+ category="so",
+ description="ETHIOPIC SECTION MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1360,
+ },
+ [0x1361]={
+ category="po",
+ description="ETHIOPIC WORDSPACE",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1361,
+ },
+ [0x1362]={
+ category="po",
+ description="ETHIOPIC FULL STOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1362,
+ },
+ [0x1363]={
+ category="po",
+ description="ETHIOPIC COMMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1363,
+ },
+ [0x1364]={
+ category="po",
+ description="ETHIOPIC SEMICOLON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1364,
+ },
+ [0x1365]={
+ category="po",
+ description="ETHIOPIC COLON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1365,
+ },
+ [0x1366]={
+ category="po",
+ description="ETHIOPIC PREFACE COLON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1366,
+ },
+ [0x1367]={
+ category="po",
+ description="ETHIOPIC QUESTION MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1367,
+ },
+ [0x1368]={
+ category="po",
+ description="ETHIOPIC PARAGRAPH SEPARATOR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1368,
+ },
+ [0x1369]={
+ category="no",
+ description="ETHIOPIC DIGIT ONE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1369,
+ },
+ [0x136A]={
+ category="no",
+ description="ETHIOPIC DIGIT TWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x136A,
+ },
+ [0x136B]={
+ category="no",
+ description="ETHIOPIC DIGIT THREE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x136B,
+ },
+ [0x136C]={
+ category="no",
+ description="ETHIOPIC DIGIT FOUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x136C,
+ },
+ [0x136D]={
+ category="no",
+ description="ETHIOPIC DIGIT FIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x136D,
+ },
+ [0x136E]={
+ category="no",
+ description="ETHIOPIC DIGIT SIX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x136E,
+ },
+ [0x136F]={
+ category="no",
+ description="ETHIOPIC DIGIT SEVEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x136F,
+ },
+ [0x1370]={
+ category="no",
+ description="ETHIOPIC DIGIT EIGHT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1370,
+ },
+ [0x1371]={
+ category="no",
+ description="ETHIOPIC DIGIT NINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1371,
+ },
+ [0x1372]={
+ category="no",
+ description="ETHIOPIC NUMBER TEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1372,
+ },
+ [0x1373]={
+ category="no",
+ description="ETHIOPIC NUMBER TWENTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1373,
+ },
+ [0x1374]={
+ category="no",
+ description="ETHIOPIC NUMBER THIRTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1374,
+ },
+ [0x1375]={
+ category="no",
+ description="ETHIOPIC NUMBER FORTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1375,
+ },
+ [0x1376]={
+ category="no",
+ description="ETHIOPIC NUMBER FIFTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1376,
+ },
+ [0x1377]={
+ category="no",
+ description="ETHIOPIC NUMBER SIXTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1377,
+ },
+ [0x1378]={
+ category="no",
+ description="ETHIOPIC NUMBER SEVENTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1378,
+ },
+ [0x1379]={
+ category="no",
+ description="ETHIOPIC NUMBER EIGHTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1379,
+ },
+ [0x137A]={
+ category="no",
+ description="ETHIOPIC NUMBER NINETY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x137A,
+ },
+ [0x137B]={
+ category="no",
+ description="ETHIOPIC NUMBER HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x137B,
+ },
+ [0x137C]={
+ category="no",
+ description="ETHIOPIC NUMBER TEN THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x137C,
+ },
+ [0x1380]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SEBATBEIT MWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1380,
+ },
+ [0x1381]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE MWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1381,
+ },
+ [0x1382]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE MWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1382,
+ },
+ [0x1383]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE MWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1383,
+ },
+ [0x1384]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SEBATBEIT BWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1384,
+ },
+ [0x1385]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1385,
+ },
+ [0x1386]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1386,
+ },
+ [0x1387]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1387,
+ },
+ [0x1388]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SEBATBEIT FWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1388,
+ },
+ [0x1389]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE FWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1389,
+ },
+ [0x138A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE FWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138A,
+ },
+ [0x138B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE FWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138B,
+ },
+ [0x138C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SEBATBEIT PWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138C,
+ },
+ [0x138D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138D,
+ },
+ [0x138E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138E,
+ },
+ [0x138F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x138F,
+ },
+ [0x1390]={
+ category="so",
+ description="ETHIOPIC TONAL MARK YIZET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1390,
+ },
+ [0x1391]={
+ category="so",
+ description="ETHIOPIC TONAL MARK DERET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1391,
+ },
+ [0x1392]={
+ category="so",
+ description="ETHIOPIC TONAL MARK RIKRIK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1392,
+ },
+ [0x1393]={
+ category="so",
+ description="ETHIOPIC TONAL MARK SHORT RIKRIK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1393,
+ },
+ [0x1394]={
+ category="so",
+ description="ETHIOPIC TONAL MARK DIFAT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1394,
+ },
+ [0x1395]={
+ category="so",
+ description="ETHIOPIC TONAL MARK KENAT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1395,
+ },
+ [0x1396]={
+ category="so",
+ description="ETHIOPIC TONAL MARK CHIRET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1396,
+ },
+ [0x1397]={
+ category="so",
+ description="ETHIOPIC TONAL MARK HIDET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1397,
+ },
+ [0x1398]={
+ category="so",
+ description="ETHIOPIC TONAL MARK DERET-HIDET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1398,
+ },
+ [0x1399]={
+ category="so",
+ description="ETHIOPIC TONAL MARK KURT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1399,
+ },
+ [0x13A0]={
+ category="lo",
+ description="CHEROKEE LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A0,
+ },
+ [0x13A1]={
+ category="lo",
+ description="CHEROKEE LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A1,
+ },
+ [0x13A2]={
+ category="lo",
+ description="CHEROKEE LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A2,
+ },
+ [0x13A3]={
+ category="lo",
+ description="CHEROKEE LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A3,
+ },
+ [0x13A4]={
+ category="lo",
+ description="CHEROKEE LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A4,
+ },
+ [0x13A5]={
+ category="lo",
+ description="CHEROKEE LETTER V",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A5,
+ },
+ [0x13A6]={
+ category="lo",
+ description="CHEROKEE LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A6,
+ },
+ [0x13A7]={
+ category="lo",
+ description="CHEROKEE LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A7,
+ },
+ [0x13A8]={
+ category="lo",
+ description="CHEROKEE LETTER GE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A8,
+ },
+ [0x13A9]={
+ category="lo",
+ description="CHEROKEE LETTER GI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13A9,
+ },
+ [0x13AA]={
+ category="lo",
+ description="CHEROKEE LETTER GO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13AA,
+ },
+ [0x13AB]={
+ category="lo",
+ description="CHEROKEE LETTER GU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13AB,
+ },
+ [0x13AC]={
+ category="lo",
+ description="CHEROKEE LETTER GV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13AC,
+ },
+ [0x13AD]={
+ category="lo",
+ description="CHEROKEE LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13AD,
+ },
+ [0x13AE]={
+ category="lo",
+ description="CHEROKEE LETTER HE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13AE,
+ },
+ [0x13AF]={
+ category="lo",
+ description="CHEROKEE LETTER HI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13AF,
+ },
+ [0x13B0]={
+ category="lo",
+ description="CHEROKEE LETTER HO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B0,
+ },
+ [0x13B1]={
+ category="lo",
+ description="CHEROKEE LETTER HU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B1,
+ },
+ [0x13B2]={
+ category="lo",
+ description="CHEROKEE LETTER HV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B2,
+ },
+ [0x13B3]={
+ category="lo",
+ description="CHEROKEE LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B3,
+ },
+ [0x13B4]={
+ category="lo",
+ description="CHEROKEE LETTER LE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B4,
+ },
+ [0x13B5]={
+ category="lo",
+ description="CHEROKEE LETTER LI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B5,
+ },
+ [0x13B6]={
+ category="lo",
+ description="CHEROKEE LETTER LO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B6,
+ },
+ [0x13B7]={
+ category="lo",
+ description="CHEROKEE LETTER LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B7,
+ },
+ [0x13B8]={
+ category="lo",
+ description="CHEROKEE LETTER LV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B8,
+ },
+ [0x13B9]={
+ category="lo",
+ description="CHEROKEE LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13B9,
+ },
+ [0x13BA]={
+ category="lo",
+ description="CHEROKEE LETTER ME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13BA,
+ },
+ [0x13BB]={
+ category="lo",
+ description="CHEROKEE LETTER MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13BB,
+ },
+ [0x13BC]={
+ category="lo",
+ description="CHEROKEE LETTER MO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13BC,
+ },
+ [0x13BD]={
+ category="lo",
+ description="CHEROKEE LETTER MU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13BD,
+ },
+ [0x13BE]={
+ category="lo",
+ description="CHEROKEE LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13BE,
+ },
+ [0x13BF]={
+ category="lo",
+ description="CHEROKEE LETTER HNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13BF,
+ },
+ [0x13C0]={
+ category="lo",
+ description="CHEROKEE LETTER NAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C0,
+ },
+ [0x13C1]={
+ category="lo",
+ description="CHEROKEE LETTER NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C1,
+ },
+ [0x13C2]={
+ category="lo",
+ description="CHEROKEE LETTER NI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C2,
+ },
+ [0x13C3]={
+ category="lo",
+ description="CHEROKEE LETTER NO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C3,
+ },
+ [0x13C4]={
+ category="lo",
+ description="CHEROKEE LETTER NU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C4,
+ },
+ [0x13C5]={
+ category="lo",
+ description="CHEROKEE LETTER NV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C5,
+ },
+ [0x13C6]={
+ category="lo",
+ description="CHEROKEE LETTER QUA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C6,
+ },
+ [0x13C7]={
+ category="lo",
+ description="CHEROKEE LETTER QUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C7,
+ },
+ [0x13C8]={
+ category="lo",
+ description="CHEROKEE LETTER QUI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C8,
+ },
+ [0x13C9]={
+ category="lo",
+ description="CHEROKEE LETTER QUO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13C9,
+ },
+ [0x13CA]={
+ category="lo",
+ description="CHEROKEE LETTER QUU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13CA,
+ },
+ [0x13CB]={
+ category="lo",
+ description="CHEROKEE LETTER QUV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13CB,
+ },
+ [0x13CC]={
+ category="lo",
+ description="CHEROKEE LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13CC,
+ },
+ [0x13CD]={
+ category="lo",
+ description="CHEROKEE LETTER S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13CD,
+ },
+ [0x13CE]={
+ category="lo",
+ description="CHEROKEE LETTER SE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13CE,
+ },
+ [0x13CF]={
+ category="lo",
+ description="CHEROKEE LETTER SI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13CF,
+ },
+ [0x13D0]={
+ category="lo",
+ description="CHEROKEE LETTER SO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D0,
+ },
+ [0x13D1]={
+ category="lo",
+ description="CHEROKEE LETTER SU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D1,
+ },
+ [0x13D2]={
+ category="lo",
+ description="CHEROKEE LETTER SV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D2,
+ },
+ [0x13D3]={
+ category="lo",
+ description="CHEROKEE LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D3,
+ },
+ [0x13D4]={
+ category="lo",
+ description="CHEROKEE LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D4,
+ },
+ [0x13D5]={
+ category="lo",
+ description="CHEROKEE LETTER DE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D5,
+ },
+ [0x13D6]={
+ category="lo",
+ description="CHEROKEE LETTER TE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D6,
+ },
+ [0x13D7]={
+ category="lo",
+ description="CHEROKEE LETTER DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D7,
+ },
+ [0x13D8]={
+ category="lo",
+ description="CHEROKEE LETTER TI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D8,
+ },
+ [0x13D9]={
+ category="lo",
+ description="CHEROKEE LETTER DO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13D9,
+ },
+ [0x13DA]={
+ category="lo",
+ description="CHEROKEE LETTER DU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13DA,
+ },
+ [0x13DB]={
+ category="lo",
+ description="CHEROKEE LETTER DV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13DB,
+ },
+ [0x13DC]={
+ category="lo",
+ description="CHEROKEE LETTER DLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13DC,
+ },
+ [0x13DD]={
+ category="lo",
+ description="CHEROKEE LETTER TLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13DD,
+ },
+ [0x13DE]={
+ category="lo",
+ description="CHEROKEE LETTER TLE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13DE,
+ },
+ [0x13DF]={
+ category="lo",
+ description="CHEROKEE LETTER TLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13DF,
+ },
+ [0x13E0]={
+ category="lo",
+ description="CHEROKEE LETTER TLO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E0,
+ },
+ [0x13E1]={
+ category="lo",
+ description="CHEROKEE LETTER TLU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E1,
+ },
+ [0x13E2]={
+ category="lo",
+ description="CHEROKEE LETTER TLV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E2,
+ },
+ [0x13E3]={
+ category="lo",
+ description="CHEROKEE LETTER TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E3,
+ },
+ [0x13E4]={
+ category="lo",
+ description="CHEROKEE LETTER TSE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E4,
+ },
+ [0x13E5]={
+ category="lo",
+ description="CHEROKEE LETTER TSI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E5,
+ },
+ [0x13E6]={
+ category="lo",
+ description="CHEROKEE LETTER TSO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E6,
+ },
+ [0x13E7]={
+ category="lo",
+ description="CHEROKEE LETTER TSU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E7,
+ },
+ [0x13E8]={
+ category="lo",
+ description="CHEROKEE LETTER TSV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E8,
+ },
+ [0x13E9]={
+ category="lo",
+ description="CHEROKEE LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13E9,
+ },
+ [0x13EA]={
+ category="lo",
+ description="CHEROKEE LETTER WE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13EA,
+ },
+ [0x13EB]={
+ category="lo",
+ description="CHEROKEE LETTER WI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13EB,
+ },
+ [0x13EC]={
+ category="lo",
+ description="CHEROKEE LETTER WO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13EC,
+ },
+ [0x13ED]={
+ category="lo",
+ description="CHEROKEE LETTER WU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13ED,
+ },
+ [0x13EE]={
+ category="lo",
+ description="CHEROKEE LETTER WV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13EE,
+ },
+ [0x13EF]={
+ category="lo",
+ description="CHEROKEE LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13EF,
+ },
+ [0x13F0]={
+ category="lo",
+ description="CHEROKEE LETTER YE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F0,
+ },
+ [0x13F1]={
+ category="lo",
+ description="CHEROKEE LETTER YI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F1,
+ },
+ [0x13F2]={
+ category="lo",
+ description="CHEROKEE LETTER YO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F2,
+ },
+ [0x13F3]={
+ category="lo",
+ description="CHEROKEE LETTER YU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F3,
+ },
+ [0x13F4]={
+ category="lo",
+ description="CHEROKEE LETTER YV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13F4,
+ },
+ [0x1400]={
+ category="pd",
+ description="CANADIAN SYLLABICS HYPHEN",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x1400,
+ },
+ [0x1401]={
+ category="lo",
+ description="CANADIAN SYLLABICS E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1401,
+ },
+ [0x1402]={
+ category="lo",
+ description="CANADIAN SYLLABICS AAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1402,
+ },
+ [0x1403]={
+ category="lo",
+ description="CANADIAN SYLLABICS I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1403,
+ },
+ [0x1404]={
+ category="lo",
+ description="CANADIAN SYLLABICS II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1404,
+ },
+ [0x1405]={
+ category="lo",
+ description="CANADIAN SYLLABICS O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1405,
+ },
+ [0x1406]={
+ category="lo",
+ description="CANADIAN SYLLABICS OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1406,
+ },
+ [0x1407]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y-CREE OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1407,
+ },
+ [0x1408]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1408,
+ },
+ [0x1409]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1409,
+ },
+ [0x140A]={
+ category="lo",
+ description="CANADIAN SYLLABICS A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x140A,
+ },
+ [0x140B]={
+ category="lo",
+ description="CANADIAN SYLLABICS AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x140B,
+ },
+ [0x140C]={
+ category="lo",
+ description="CANADIAN SYLLABICS WE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x140C,
+ },
+ [0x140D]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE WE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x140D,
+ },
+ [0x140E]={
+ category="lo",
+ description="CANADIAN SYLLABICS WI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x140E,
+ },
+ [0x140F]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE WI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x140F,
+ },
+ [0x1410]={
+ category="lo",
+ description="CANADIAN SYLLABICS WII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1410,
+ },
+ [0x1411]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE WII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1411,
+ },
+ [0x1412]={
+ category="lo",
+ description="CANADIAN SYLLABICS WO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1412,
+ },
+ [0x1413]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE WO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1413,
+ },
+ [0x1414]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1414,
+ },
+ [0x1415]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE WOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1415,
+ },
+ [0x1416]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI WOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1416,
+ },
+ [0x1417]={
+ category="lo",
+ description="CANADIAN SYLLABICS WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1417,
+ },
+ [0x1418]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1418,
+ },
+ [0x1419]={
+ category="lo",
+ description="CANADIAN SYLLABICS WAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1419,
+ },
+ [0x141A]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE WAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141A,
+ },
+ [0x141B]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI WAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141B,
+ },
+ [0x141C]={
+ category="lo",
+ description="CANADIAN SYLLABICS AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141C,
+ },
+ [0x141D]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y-CREE W",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141D,
+ },
+ [0x141E]={
+ category="lo",
+ description="CANADIAN SYLLABICS GLOTTAL STOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141E,
+ },
+ [0x141F]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL ACUTE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x141F,
+ },
+ [0x1420]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL GRAVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1420,
+ },
+ [0x1421]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL BOTTOM HALF RING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1421,
+ },
+ [0x1422]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL TOP HALF RING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1422,
+ },
+ [0x1423]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL RIGHT HALF RING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1423,
+ },
+ [0x1424]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL RING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1424,
+ },
+ [0x1425]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL DOUBLE ACUTE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1425,
+ },
+ [0x1426]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1426,
+ },
+ [0x1427]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL MIDDLE DOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1427,
+ },
+ [0x1428]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1428,
+ },
+ [0x1429]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL PLUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1429,
+ },
+ [0x142A]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL DOWN TACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142A,
+ },
+ [0x142B]={
+ category="lo",
+ description="CANADIAN SYLLABICS EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142B,
+ },
+ [0x142C]={
+ category="lo",
+ description="CANADIAN SYLLABICS IN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142C,
+ },
+ [0x142D]={
+ category="lo",
+ description="CANADIAN SYLLABICS ON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142D,
+ },
+ [0x142E]={
+ category="lo",
+ description="CANADIAN SYLLABICS AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142E,
+ },
+ [0x142F]={
+ category="lo",
+ description="CANADIAN SYLLABICS PE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x142F,
+ },
+ [0x1430]={
+ category="lo",
+ description="CANADIAN SYLLABICS PAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1430,
+ },
+ [0x1431]={
+ category="lo",
+ description="CANADIAN SYLLABICS PI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1431,
+ },
+ [0x1432]={
+ category="lo",
+ description="CANADIAN SYLLABICS PII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1432,
+ },
+ [0x1433]={
+ category="lo",
+ description="CANADIAN SYLLABICS PO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1433,
+ },
+ [0x1434]={
+ category="lo",
+ description="CANADIAN SYLLABICS POO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1434,
+ },
+ [0x1435]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y-CREE POO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1435,
+ },
+ [0x1436]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER HEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1436,
+ },
+ [0x1437]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER HI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1437,
+ },
+ [0x1438]={
+ category="lo",
+ description="CANADIAN SYLLABICS PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1438,
+ },
+ [0x1439]={
+ category="lo",
+ description="CANADIAN SYLLABICS PAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1439,
+ },
+ [0x143A]={
+ category="lo",
+ description="CANADIAN SYLLABICS PWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x143A,
+ },
+ [0x143B]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE PWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x143B,
+ },
+ [0x143C]={
+ category="lo",
+ description="CANADIAN SYLLABICS PWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x143C,
+ },
+ [0x143D]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE PWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x143D,
+ },
+ [0x143E]={
+ category="lo",
+ description="CANADIAN SYLLABICS PWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x143E,
+ },
+ [0x143F]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE PWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x143F,
+ },
+ [0x1440]={
+ category="lo",
+ description="CANADIAN SYLLABICS PWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1440,
+ },
+ [0x1441]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE PWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1441,
+ },
+ [0x1442]={
+ category="lo",
+ description="CANADIAN SYLLABICS PWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1442,
+ },
+ [0x1443]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE PWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1443,
+ },
+ [0x1444]={
+ category="lo",
+ description="CANADIAN SYLLABICS PWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1444,
+ },
+ [0x1445]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE PWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1445,
+ },
+ [0x1446]={
+ category="lo",
+ description="CANADIAN SYLLABICS PWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1446,
+ },
+ [0x1447]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE PWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1447,
+ },
+ [0x1448]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y-CREE PWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1448,
+ },
+ [0x1449]={
+ category="lo",
+ description="CANADIAN SYLLABICS P",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1449,
+ },
+ [0x144A]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE P",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144A,
+ },
+ [0x144B]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144B,
+ },
+ [0x144C]={
+ category="lo",
+ description="CANADIAN SYLLABICS TE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144C,
+ },
+ [0x144D]={
+ category="lo",
+ description="CANADIAN SYLLABICS TAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144D,
+ },
+ [0x144E]={
+ category="lo",
+ description="CANADIAN SYLLABICS TI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144E,
+ },
+ [0x144F]={
+ category="lo",
+ description="CANADIAN SYLLABICS TII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x144F,
+ },
+ [0x1450]={
+ category="lo",
+ description="CANADIAN SYLLABICS TO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1450,
+ },
+ [0x1451]={
+ category="lo",
+ description="CANADIAN SYLLABICS TOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1451,
+ },
+ [0x1452]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y-CREE TOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1452,
+ },
+ [0x1453]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1453,
+ },
+ [0x1454]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1454,
+ },
+ [0x1455]={
+ category="lo",
+ description="CANADIAN SYLLABICS TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1455,
+ },
+ [0x1456]={
+ category="lo",
+ description="CANADIAN SYLLABICS TAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1456,
+ },
+ [0x1457]={
+ category="lo",
+ description="CANADIAN SYLLABICS TWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1457,
+ },
+ [0x1458]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE TWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1458,
+ },
+ [0x1459]={
+ category="lo",
+ description="CANADIAN SYLLABICS TWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1459,
+ },
+ [0x145A]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE TWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145A,
+ },
+ [0x145B]={
+ category="lo",
+ description="CANADIAN SYLLABICS TWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145B,
+ },
+ [0x145C]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE TWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145C,
+ },
+ [0x145D]={
+ category="lo",
+ description="CANADIAN SYLLABICS TWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145D,
+ },
+ [0x145E]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE TWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145E,
+ },
+ [0x145F]={
+ category="lo",
+ description="CANADIAN SYLLABICS TWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x145F,
+ },
+ [0x1460]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE TWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1460,
+ },
+ [0x1461]={
+ category="lo",
+ description="CANADIAN SYLLABICS TWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1461,
+ },
+ [0x1462]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE TWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1462,
+ },
+ [0x1463]={
+ category="lo",
+ description="CANADIAN SYLLABICS TWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1463,
+ },
+ [0x1464]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE TWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1464,
+ },
+ [0x1465]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI TWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1465,
+ },
+ [0x1466]={
+ category="lo",
+ description="CANADIAN SYLLABICS T",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1466,
+ },
+ [0x1467]={
+ category="lo",
+ description="CANADIAN SYLLABICS TTE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1467,
+ },
+ [0x1468]={
+ category="lo",
+ description="CANADIAN SYLLABICS TTI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1468,
+ },
+ [0x1469]={
+ category="lo",
+ description="CANADIAN SYLLABICS TTO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1469,
+ },
+ [0x146A]={
+ category="lo",
+ description="CANADIAN SYLLABICS TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x146A,
+ },
+ [0x146B]={
+ category="lo",
+ description="CANADIAN SYLLABICS KE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x146B,
+ },
+ [0x146C]={
+ category="lo",
+ description="CANADIAN SYLLABICS KAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x146C,
+ },
+ [0x146D]={
+ category="lo",
+ description="CANADIAN SYLLABICS KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x146D,
+ },
+ [0x146E]={
+ category="lo",
+ description="CANADIAN SYLLABICS KII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x146E,
+ },
+ [0x146F]={
+ category="lo",
+ description="CANADIAN SYLLABICS KO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x146F,
+ },
+ [0x1470]={
+ category="lo",
+ description="CANADIAN SYLLABICS KOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1470,
+ },
+ [0x1471]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y-CREE KOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1471,
+ },
+ [0x1472]={
+ category="lo",
+ description="CANADIAN SYLLABICS KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1472,
+ },
+ [0x1473]={
+ category="lo",
+ description="CANADIAN SYLLABICS KAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1473,
+ },
+ [0x1474]={
+ category="lo",
+ description="CANADIAN SYLLABICS KWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1474,
+ },
+ [0x1475]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE KWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1475,
+ },
+ [0x1476]={
+ category="lo",
+ description="CANADIAN SYLLABICS KWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1476,
+ },
+ [0x1477]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE KWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1477,
+ },
+ [0x1478]={
+ category="lo",
+ description="CANADIAN SYLLABICS KWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1478,
+ },
+ [0x1479]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE KWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1479,
+ },
+ [0x147A]={
+ category="lo",
+ description="CANADIAN SYLLABICS KWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x147A,
+ },
+ [0x147B]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE KWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x147B,
+ },
+ [0x147C]={
+ category="lo",
+ description="CANADIAN SYLLABICS KWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x147C,
+ },
+ [0x147D]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE KWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x147D,
+ },
+ [0x147E]={
+ category="lo",
+ description="CANADIAN SYLLABICS KWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x147E,
+ },
+ [0x147F]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE KWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x147F,
+ },
+ [0x1480]={
+ category="lo",
+ description="CANADIAN SYLLABICS KWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1480,
+ },
+ [0x1481]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE KWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1481,
+ },
+ [0x1482]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI KWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1482,
+ },
+ [0x1483]={
+ category="lo",
+ description="CANADIAN SYLLABICS K",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1483,
+ },
+ [0x1484]={
+ category="lo",
+ description="CANADIAN SYLLABICS KW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1484,
+ },
+ [0x1485]={
+ category="lo",
+ description="CANADIAN SYLLABICS SOUTH-SLAVEY KEH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1485,
+ },
+ [0x1486]={
+ category="lo",
+ description="CANADIAN SYLLABICS SOUTH-SLAVEY KIH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1486,
+ },
+ [0x1487]={
+ category="lo",
+ description="CANADIAN SYLLABICS SOUTH-SLAVEY KOH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1487,
+ },
+ [0x1488]={
+ category="lo",
+ description="CANADIAN SYLLABICS SOUTH-SLAVEY KAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1488,
+ },
+ [0x1489]={
+ category="lo",
+ description="CANADIAN SYLLABICS CE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1489,
+ },
+ [0x148A]={
+ category="lo",
+ description="CANADIAN SYLLABICS CAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x148A,
+ },
+ [0x148B]={
+ category="lo",
+ description="CANADIAN SYLLABICS CI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x148B,
+ },
+ [0x148C]={
+ category="lo",
+ description="CANADIAN SYLLABICS CII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x148C,
+ },
+ [0x148D]={
+ category="lo",
+ description="CANADIAN SYLLABICS CO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x148D,
+ },
+ [0x148E]={
+ category="lo",
+ description="CANADIAN SYLLABICS COO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x148E,
+ },
+ [0x148F]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y-CREE COO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x148F,
+ },
+ [0x1490]={
+ category="lo",
+ description="CANADIAN SYLLABICS CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1490,
+ },
+ [0x1491]={
+ category="lo",
+ description="CANADIAN SYLLABICS CAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1491,
+ },
+ [0x1492]={
+ category="lo",
+ description="CANADIAN SYLLABICS CWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1492,
+ },
+ [0x1493]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE CWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1493,
+ },
+ [0x1494]={
+ category="lo",
+ description="CANADIAN SYLLABICS CWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1494,
+ },
+ [0x1495]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE CWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1495,
+ },
+ [0x1496]={
+ category="lo",
+ description="CANADIAN SYLLABICS CWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1496,
+ },
+ [0x1497]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE CWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1497,
+ },
+ [0x1498]={
+ category="lo",
+ description="CANADIAN SYLLABICS CWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1498,
+ },
+ [0x1499]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE CWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1499,
+ },
+ [0x149A]={
+ category="lo",
+ description="CANADIAN SYLLABICS CWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x149A,
+ },
+ [0x149B]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE CWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x149B,
+ },
+ [0x149C]={
+ category="lo",
+ description="CANADIAN SYLLABICS CWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x149C,
+ },
+ [0x149D]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE CWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x149D,
+ },
+ [0x149E]={
+ category="lo",
+ description="CANADIAN SYLLABICS CWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x149E,
+ },
+ [0x149F]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE CWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x149F,
+ },
+ [0x14A0]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI CWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A0,
+ },
+ [0x14A1]={
+ category="lo",
+ description="CANADIAN SYLLABICS C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A1,
+ },
+ [0x14A2]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI TH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A2,
+ },
+ [0x14A3]={
+ category="lo",
+ description="CANADIAN SYLLABICS ME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A3,
+ },
+ [0x14A4]={
+ category="lo",
+ description="CANADIAN SYLLABICS MAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A4,
+ },
+ [0x14A5]={
+ category="lo",
+ description="CANADIAN SYLLABICS MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A5,
+ },
+ [0x14A6]={
+ category="lo",
+ description="CANADIAN SYLLABICS MII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A6,
+ },
+ [0x14A7]={
+ category="lo",
+ description="CANADIAN SYLLABICS MO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A7,
+ },
+ [0x14A8]={
+ category="lo",
+ description="CANADIAN SYLLABICS MOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A8,
+ },
+ [0x14A9]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y-CREE MOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14A9,
+ },
+ [0x14AA]={
+ category="lo",
+ description="CANADIAN SYLLABICS MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14AA,
+ },
+ [0x14AB]={
+ category="lo",
+ description="CANADIAN SYLLABICS MAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14AB,
+ },
+ [0x14AC]={
+ category="lo",
+ description="CANADIAN SYLLABICS MWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14AC,
+ },
+ [0x14AD]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE MWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14AD,
+ },
+ [0x14AE]={
+ category="lo",
+ description="CANADIAN SYLLABICS MWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14AE,
+ },
+ [0x14AF]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE MWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14AF,
+ },
+ [0x14B0]={
+ category="lo",
+ description="CANADIAN SYLLABICS MWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B0,
+ },
+ [0x14B1]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE MWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B1,
+ },
+ [0x14B2]={
+ category="lo",
+ description="CANADIAN SYLLABICS MWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B2,
+ },
+ [0x14B3]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE MWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B3,
+ },
+ [0x14B4]={
+ category="lo",
+ description="CANADIAN SYLLABICS MWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B4,
+ },
+ [0x14B5]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE MWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B5,
+ },
+ [0x14B6]={
+ category="lo",
+ description="CANADIAN SYLLABICS MWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B6,
+ },
+ [0x14B7]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE MWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B7,
+ },
+ [0x14B8]={
+ category="lo",
+ description="CANADIAN SYLLABICS MWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B8,
+ },
+ [0x14B9]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE MWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14B9,
+ },
+ [0x14BA]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI MWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14BA,
+ },
+ [0x14BB]={
+ category="lo",
+ description="CANADIAN SYLLABICS M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14BB,
+ },
+ [0x14BC]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14BC,
+ },
+ [0x14BD]={
+ category="lo",
+ description="CANADIAN SYLLABICS MH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14BD,
+ },
+ [0x14BE]={
+ category="lo",
+ description="CANADIAN SYLLABICS ATHAPASCAN M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14BE,
+ },
+ [0x14BF]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14BF,
+ },
+ [0x14C0]={
+ category="lo",
+ description="CANADIAN SYLLABICS NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C0,
+ },
+ [0x14C1]={
+ category="lo",
+ description="CANADIAN SYLLABICS NAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C1,
+ },
+ [0x14C2]={
+ category="lo",
+ description="CANADIAN SYLLABICS NI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C2,
+ },
+ [0x14C3]={
+ category="lo",
+ description="CANADIAN SYLLABICS NII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C3,
+ },
+ [0x14C4]={
+ category="lo",
+ description="CANADIAN SYLLABICS NO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C4,
+ },
+ [0x14C5]={
+ category="lo",
+ description="CANADIAN SYLLABICS NOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C5,
+ },
+ [0x14C6]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y-CREE NOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C6,
+ },
+ [0x14C7]={
+ category="lo",
+ description="CANADIAN SYLLABICS NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C7,
+ },
+ [0x14C8]={
+ category="lo",
+ description="CANADIAN SYLLABICS NAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C8,
+ },
+ [0x14C9]={
+ category="lo",
+ description="CANADIAN SYLLABICS NWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14C9,
+ },
+ [0x14CA]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE NWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14CA,
+ },
+ [0x14CB]={
+ category="lo",
+ description="CANADIAN SYLLABICS NWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14CB,
+ },
+ [0x14CC]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE NWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14CC,
+ },
+ [0x14CD]={
+ category="lo",
+ description="CANADIAN SYLLABICS NWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14CD,
+ },
+ [0x14CE]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE NWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14CE,
+ },
+ [0x14CF]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI NWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14CF,
+ },
+ [0x14D0]={
+ category="lo",
+ description="CANADIAN SYLLABICS N",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D0,
+ },
+ [0x14D1]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER NG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D1,
+ },
+ [0x14D2]={
+ category="lo",
+ description="CANADIAN SYLLABICS NH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D2,
+ },
+ [0x14D3]={
+ category="lo",
+ description="CANADIAN SYLLABICS LE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D3,
+ },
+ [0x14D4]={
+ category="lo",
+ description="CANADIAN SYLLABICS LAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D4,
+ },
+ [0x14D5]={
+ category="lo",
+ description="CANADIAN SYLLABICS LI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D5,
+ },
+ [0x14D6]={
+ category="lo",
+ description="CANADIAN SYLLABICS LII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D6,
+ },
+ [0x14D7]={
+ category="lo",
+ description="CANADIAN SYLLABICS LO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D7,
+ },
+ [0x14D8]={
+ category="lo",
+ description="CANADIAN SYLLABICS LOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D8,
+ },
+ [0x14D9]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y-CREE LOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14D9,
+ },
+ [0x14DA]={
+ category="lo",
+ description="CANADIAN SYLLABICS LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14DA,
+ },
+ [0x14DB]={
+ category="lo",
+ description="CANADIAN SYLLABICS LAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14DB,
+ },
+ [0x14DC]={
+ category="lo",
+ description="CANADIAN SYLLABICS LWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14DC,
+ },
+ [0x14DD]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE LWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14DD,
+ },
+ [0x14DE]={
+ category="lo",
+ description="CANADIAN SYLLABICS LWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14DE,
+ },
+ [0x14DF]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE LWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14DF,
+ },
+ [0x14E0]={
+ category="lo",
+ description="CANADIAN SYLLABICS LWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E0,
+ },
+ [0x14E1]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE LWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E1,
+ },
+ [0x14E2]={
+ category="lo",
+ description="CANADIAN SYLLABICS LWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E2,
+ },
+ [0x14E3]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE LWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E3,
+ },
+ [0x14E4]={
+ category="lo",
+ description="CANADIAN SYLLABICS LWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E4,
+ },
+ [0x14E5]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE LWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E5,
+ },
+ [0x14E6]={
+ category="lo",
+ description="CANADIAN SYLLABICS LWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E6,
+ },
+ [0x14E7]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE LWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E7,
+ },
+ [0x14E8]={
+ category="lo",
+ description="CANADIAN SYLLABICS LWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E8,
+ },
+ [0x14E9]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE LWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14E9,
+ },
+ [0x14EA]={
+ category="lo",
+ description="CANADIAN SYLLABICS L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14EA,
+ },
+ [0x14EB]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14EB,
+ },
+ [0x14EC]={
+ category="lo",
+ description="CANADIAN SYLLABICS MEDIAL L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14EC,
+ },
+ [0x14ED]={
+ category="lo",
+ description="CANADIAN SYLLABICS SE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14ED,
+ },
+ [0x14EE]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14EE,
+ },
+ [0x14EF]={
+ category="lo",
+ description="CANADIAN SYLLABICS SI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14EF,
+ },
+ [0x14F0]={
+ category="lo",
+ description="CANADIAN SYLLABICS SII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F0,
+ },
+ [0x14F1]={
+ category="lo",
+ description="CANADIAN SYLLABICS SO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F1,
+ },
+ [0x14F2]={
+ category="lo",
+ description="CANADIAN SYLLABICS SOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F2,
+ },
+ [0x14F3]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y-CREE SOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F3,
+ },
+ [0x14F4]={
+ category="lo",
+ description="CANADIAN SYLLABICS SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F4,
+ },
+ [0x14F5]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F5,
+ },
+ [0x14F6]={
+ category="lo",
+ description="CANADIAN SYLLABICS SWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F6,
+ },
+ [0x14F7]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F7,
+ },
+ [0x14F8]={
+ category="lo",
+ description="CANADIAN SYLLABICS SWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F8,
+ },
+ [0x14F9]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14F9,
+ },
+ [0x14FA]={
+ category="lo",
+ description="CANADIAN SYLLABICS SWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14FA,
+ },
+ [0x14FB]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14FB,
+ },
+ [0x14FC]={
+ category="lo",
+ description="CANADIAN SYLLABICS SWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14FC,
+ },
+ [0x14FD]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14FD,
+ },
+ [0x14FE]={
+ category="lo",
+ description="CANADIAN SYLLABICS SWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14FE,
+ },
+ [0x14FF]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x14FF,
+ },
+ [0x1500]={
+ category="lo",
+ description="CANADIAN SYLLABICS SWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1500,
+ },
+ [0x1501]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1501,
+ },
+ [0x1502]={
+ category="lo",
+ description="CANADIAN SYLLABICS SWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1502,
+ },
+ [0x1503]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1503,
+ },
+ [0x1504]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI SWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1504,
+ },
+ [0x1505]={
+ category="lo",
+ description="CANADIAN SYLLABICS S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1505,
+ },
+ [0x1506]={
+ category="lo",
+ description="CANADIAN SYLLABICS ATHAPASCAN S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1506,
+ },
+ [0x1507]={
+ category="lo",
+ description="CANADIAN SYLLABICS SW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1507,
+ },
+ [0x1508]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1508,
+ },
+ [0x1509]={
+ category="lo",
+ description="CANADIAN SYLLABICS MOOSE-CREE SK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1509,
+ },
+ [0x150A]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI SKW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x150A,
+ },
+ [0x150B]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI S-W",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x150B,
+ },
+ [0x150C]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI SPWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x150C,
+ },
+ [0x150D]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI STWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x150D,
+ },
+ [0x150E]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI SKWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x150E,
+ },
+ [0x150F]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI SCWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x150F,
+ },
+ [0x1510]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1510,
+ },
+ [0x1511]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1511,
+ },
+ [0x1512]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1512,
+ },
+ [0x1513]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1513,
+ },
+ [0x1514]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1514,
+ },
+ [0x1515]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1515,
+ },
+ [0x1516]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1516,
+ },
+ [0x1517]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1517,
+ },
+ [0x1518]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SHWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1518,
+ },
+ [0x1519]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1519,
+ },
+ [0x151A]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SHWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x151A,
+ },
+ [0x151B]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x151B,
+ },
+ [0x151C]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SHWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x151C,
+ },
+ [0x151D]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x151D,
+ },
+ [0x151E]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SHWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x151E,
+ },
+ [0x151F]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x151F,
+ },
+ [0x1520]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SHWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1520,
+ },
+ [0x1521]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1521,
+ },
+ [0x1522]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SHWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1522,
+ },
+ [0x1523]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1523,
+ },
+ [0x1524]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE SHWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1524,
+ },
+ [0x1525]={
+ category="lo",
+ description="CANADIAN SYLLABICS SH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1525,
+ },
+ [0x1526]={
+ category="lo",
+ description="CANADIAN SYLLABICS YE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1526,
+ },
+ [0x1527]={
+ category="lo",
+ description="CANADIAN SYLLABICS YAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1527,
+ },
+ [0x1528]={
+ category="lo",
+ description="CANADIAN SYLLABICS YI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1528,
+ },
+ [0x1529]={
+ category="lo",
+ description="CANADIAN SYLLABICS YII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1529,
+ },
+ [0x152A]={
+ category="lo",
+ description="CANADIAN SYLLABICS YO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152A,
+ },
+ [0x152B]={
+ category="lo",
+ description="CANADIAN SYLLABICS YOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152B,
+ },
+ [0x152C]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y-CREE YOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152C,
+ },
+ [0x152D]={
+ category="lo",
+ description="CANADIAN SYLLABICS YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152D,
+ },
+ [0x152E]={
+ category="lo",
+ description="CANADIAN SYLLABICS YAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152E,
+ },
+ [0x152F]={
+ category="lo",
+ description="CANADIAN SYLLABICS YWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x152F,
+ },
+ [0x1530]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE YWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1530,
+ },
+ [0x1531]={
+ category="lo",
+ description="CANADIAN SYLLABICS YWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1531,
+ },
+ [0x1532]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE YWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1532,
+ },
+ [0x1533]={
+ category="lo",
+ description="CANADIAN SYLLABICS YWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1533,
+ },
+ [0x1534]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE YWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1534,
+ },
+ [0x1535]={
+ category="lo",
+ description="CANADIAN SYLLABICS YWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1535,
+ },
+ [0x1536]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE YWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1536,
+ },
+ [0x1537]={
+ category="lo",
+ description="CANADIAN SYLLABICS YWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1537,
+ },
+ [0x1538]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE YWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1538,
+ },
+ [0x1539]={
+ category="lo",
+ description="CANADIAN SYLLABICS YWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1539,
+ },
+ [0x153A]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE YWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153A,
+ },
+ [0x153B]={
+ category="lo",
+ description="CANADIAN SYLLABICS YWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153B,
+ },
+ [0x153C]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE YWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153C,
+ },
+ [0x153D]={
+ category="lo",
+ description="CANADIAN SYLLABICS NASKAPI YWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153D,
+ },
+ [0x153E]={
+ category="lo",
+ description="CANADIAN SYLLABICS Y",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153E,
+ },
+ [0x153F]={
+ category="lo",
+ description="CANADIAN SYLLABICS BIBLE-CREE Y",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x153F,
+ },
+ [0x1540]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE Y",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1540,
+ },
+ [0x1541]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI YI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1541,
+ },
+ [0x1542]={
+ category="lo",
+ description="CANADIAN SYLLABICS RE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1542,
+ },
+ [0x1543]={
+ category="lo",
+ description="CANADIAN SYLLABICS R-CREE RE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1543,
+ },
+ [0x1544]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE LE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1544,
+ },
+ [0x1545]={
+ category="lo",
+ description="CANADIAN SYLLABICS RAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1545,
+ },
+ [0x1546]={
+ category="lo",
+ description="CANADIAN SYLLABICS RI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1546,
+ },
+ [0x1547]={
+ category="lo",
+ description="CANADIAN SYLLABICS RII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1547,
+ },
+ [0x1548]={
+ category="lo",
+ description="CANADIAN SYLLABICS RO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1548,
+ },
+ [0x1549]={
+ category="lo",
+ description="CANADIAN SYLLABICS ROO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1549,
+ },
+ [0x154A]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE LO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x154A,
+ },
+ [0x154B]={
+ category="lo",
+ description="CANADIAN SYLLABICS RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x154B,
+ },
+ [0x154C]={
+ category="lo",
+ description="CANADIAN SYLLABICS RAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x154C,
+ },
+ [0x154D]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x154D,
+ },
+ [0x154E]={
+ category="lo",
+ description="CANADIAN SYLLABICS RWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x154E,
+ },
+ [0x154F]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE RWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x154F,
+ },
+ [0x1550]={
+ category="lo",
+ description="CANADIAN SYLLABICS R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1550,
+ },
+ [0x1551]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1551,
+ },
+ [0x1552]={
+ category="lo",
+ description="CANADIAN SYLLABICS MEDIAL R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1552,
+ },
+ [0x1553]={
+ category="lo",
+ description="CANADIAN SYLLABICS FE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1553,
+ },
+ [0x1554]={
+ category="lo",
+ description="CANADIAN SYLLABICS FAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1554,
+ },
+ [0x1555]={
+ category="lo",
+ description="CANADIAN SYLLABICS FI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1555,
+ },
+ [0x1556]={
+ category="lo",
+ description="CANADIAN SYLLABICS FII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1556,
+ },
+ [0x1557]={
+ category="lo",
+ description="CANADIAN SYLLABICS FO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1557,
+ },
+ [0x1558]={
+ category="lo",
+ description="CANADIAN SYLLABICS FOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1558,
+ },
+ [0x1559]={
+ category="lo",
+ description="CANADIAN SYLLABICS FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1559,
+ },
+ [0x155A]={
+ category="lo",
+ description="CANADIAN SYLLABICS FAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x155A,
+ },
+ [0x155B]={
+ category="lo",
+ description="CANADIAN SYLLABICS FWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x155B,
+ },
+ [0x155C]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE FWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x155C,
+ },
+ [0x155D]={
+ category="lo",
+ description="CANADIAN SYLLABICS F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x155D,
+ },
+ [0x155E]={
+ category="lo",
+ description="CANADIAN SYLLABICS THE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x155E,
+ },
+ [0x155F]={
+ category="lo",
+ description="CANADIAN SYLLABICS N-CREE THE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x155F,
+ },
+ [0x1560]={
+ category="lo",
+ description="CANADIAN SYLLABICS THI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1560,
+ },
+ [0x1561]={
+ category="lo",
+ description="CANADIAN SYLLABICS N-CREE THI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1561,
+ },
+ [0x1562]={
+ category="lo",
+ description="CANADIAN SYLLABICS THII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1562,
+ },
+ [0x1563]={
+ category="lo",
+ description="CANADIAN SYLLABICS N-CREE THII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1563,
+ },
+ [0x1564]={
+ category="lo",
+ description="CANADIAN SYLLABICS THO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1564,
+ },
+ [0x1565]={
+ category="lo",
+ description="CANADIAN SYLLABICS THOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1565,
+ },
+ [0x1566]={
+ category="lo",
+ description="CANADIAN SYLLABICS THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1566,
+ },
+ [0x1567]={
+ category="lo",
+ description="CANADIAN SYLLABICS THAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1567,
+ },
+ [0x1568]={
+ category="lo",
+ description="CANADIAN SYLLABICS THWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1568,
+ },
+ [0x1569]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE THWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1569,
+ },
+ [0x156A]={
+ category="lo",
+ description="CANADIAN SYLLABICS TH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x156A,
+ },
+ [0x156B]={
+ category="lo",
+ description="CANADIAN SYLLABICS TTHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x156B,
+ },
+ [0x156C]={
+ category="lo",
+ description="CANADIAN SYLLABICS TTHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x156C,
+ },
+ [0x156D]={
+ category="lo",
+ description="CANADIAN SYLLABICS TTHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x156D,
+ },
+ [0x156E]={
+ category="lo",
+ description="CANADIAN SYLLABICS TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x156E,
+ },
+ [0x156F]={
+ category="lo",
+ description="CANADIAN SYLLABICS TTH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x156F,
+ },
+ [0x1570]={
+ category="lo",
+ description="CANADIAN SYLLABICS TYE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1570,
+ },
+ [0x1571]={
+ category="lo",
+ description="CANADIAN SYLLABICS TYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1571,
+ },
+ [0x1572]={
+ category="lo",
+ description="CANADIAN SYLLABICS TYO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1572,
+ },
+ [0x1573]={
+ category="lo",
+ description="CANADIAN SYLLABICS TYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1573,
+ },
+ [0x1574]={
+ category="lo",
+ description="CANADIAN SYLLABICS NUNAVIK HE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1574,
+ },
+ [0x1575]={
+ category="lo",
+ description="CANADIAN SYLLABICS NUNAVIK HI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1575,
+ },
+ [0x1576]={
+ category="lo",
+ description="CANADIAN SYLLABICS NUNAVIK HII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1576,
+ },
+ [0x1577]={
+ category="lo",
+ description="CANADIAN SYLLABICS NUNAVIK HO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1577,
+ },
+ [0x1578]={
+ category="lo",
+ description="CANADIAN SYLLABICS NUNAVIK HOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1578,
+ },
+ [0x1579]={
+ category="lo",
+ description="CANADIAN SYLLABICS NUNAVIK HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1579,
+ },
+ [0x157A]={
+ category="lo",
+ description="CANADIAN SYLLABICS NUNAVIK HAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x157A,
+ },
+ [0x157B]={
+ category="lo",
+ description="CANADIAN SYLLABICS NUNAVIK H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x157B,
+ },
+ [0x157C]={
+ category="lo",
+ description="CANADIAN SYLLABICS NUNAVUT H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x157C,
+ },
+ [0x157D]={
+ category="lo",
+ description="CANADIAN SYLLABICS HK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x157D,
+ },
+ [0x157E]={
+ category="lo",
+ description="CANADIAN SYLLABICS QAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x157E,
+ },
+ [0x157F]={
+ category="lo",
+ description="CANADIAN SYLLABICS QI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x157F,
+ },
+ [0x1580]={
+ category="lo",
+ description="CANADIAN SYLLABICS QII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1580,
+ },
+ [0x1581]={
+ category="lo",
+ description="CANADIAN SYLLABICS QO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1581,
+ },
+ [0x1582]={
+ category="lo",
+ description="CANADIAN SYLLABICS QOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1582,
+ },
+ [0x1583]={
+ category="lo",
+ description="CANADIAN SYLLABICS QA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1583,
+ },
+ [0x1584]={
+ category="lo",
+ description="CANADIAN SYLLABICS QAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1584,
+ },
+ [0x1585]={
+ category="lo",
+ description="CANADIAN SYLLABICS Q",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1585,
+ },
+ [0x1586]={
+ category="lo",
+ description="CANADIAN SYLLABICS TLHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1586,
+ },
+ [0x1587]={
+ category="lo",
+ description="CANADIAN SYLLABICS TLHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1587,
+ },
+ [0x1588]={
+ category="lo",
+ description="CANADIAN SYLLABICS TLHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1588,
+ },
+ [0x1589]={
+ category="lo",
+ description="CANADIAN SYLLABICS TLHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1589,
+ },
+ [0x158A]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE RE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x158A,
+ },
+ [0x158B]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE RI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x158B,
+ },
+ [0x158C]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE RO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x158C,
+ },
+ [0x158D]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x158D,
+ },
+ [0x158E]={
+ category="lo",
+ description="CANADIAN SYLLABICS NGAAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x158E,
+ },
+ [0x158F]={
+ category="lo",
+ description="CANADIAN SYLLABICS NGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x158F,
+ },
+ [0x1590]={
+ category="lo",
+ description="CANADIAN SYLLABICS NGII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1590,
+ },
+ [0x1591]={
+ category="lo",
+ description="CANADIAN SYLLABICS NGO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1591,
+ },
+ [0x1592]={
+ category="lo",
+ description="CANADIAN SYLLABICS NGOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1592,
+ },
+ [0x1593]={
+ category="lo",
+ description="CANADIAN SYLLABICS NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1593,
+ },
+ [0x1594]={
+ category="lo",
+ description="CANADIAN SYLLABICS NGAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1594,
+ },
+ [0x1595]={
+ category="lo",
+ description="CANADIAN SYLLABICS NG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1595,
+ },
+ [0x1596]={
+ category="lo",
+ description="CANADIAN SYLLABICS NNG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1596,
+ },
+ [0x1597]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1597,
+ },
+ [0x1598]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI SHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1598,
+ },
+ [0x1599]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI SHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1599,
+ },
+ [0x159A]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x159A,
+ },
+ [0x159B]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE THE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x159B,
+ },
+ [0x159C]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE THI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x159C,
+ },
+ [0x159D]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE THO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x159D,
+ },
+ [0x159E]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x159E,
+ },
+ [0x159F]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE TH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x159F,
+ },
+ [0x15A0]={
+ category="lo",
+ description="CANADIAN SYLLABICS LHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A0,
+ },
+ [0x15A1]={
+ category="lo",
+ description="CANADIAN SYLLABICS LHII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A1,
+ },
+ [0x15A2]={
+ category="lo",
+ description="CANADIAN SYLLABICS LHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A2,
+ },
+ [0x15A3]={
+ category="lo",
+ description="CANADIAN SYLLABICS LHOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A3,
+ },
+ [0x15A4]={
+ category="lo",
+ description="CANADIAN SYLLABICS LHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A4,
+ },
+ [0x15A5]={
+ category="lo",
+ description="CANADIAN SYLLABICS LHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A5,
+ },
+ [0x15A6]={
+ category="lo",
+ description="CANADIAN SYLLABICS LH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A6,
+ },
+ [0x15A7]={
+ category="lo",
+ description="CANADIAN SYLLABICS TH-CREE THE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A7,
+ },
+ [0x15A8]={
+ category="lo",
+ description="CANADIAN SYLLABICS TH-CREE THI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A8,
+ },
+ [0x15A9]={
+ category="lo",
+ description="CANADIAN SYLLABICS TH-CREE THII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15A9,
+ },
+ [0x15AA]={
+ category="lo",
+ description="CANADIAN SYLLABICS TH-CREE THO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15AA,
+ },
+ [0x15AB]={
+ category="lo",
+ description="CANADIAN SYLLABICS TH-CREE THOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15AB,
+ },
+ [0x15AC]={
+ category="lo",
+ description="CANADIAN SYLLABICS TH-CREE THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15AC,
+ },
+ [0x15AD]={
+ category="lo",
+ description="CANADIAN SYLLABICS TH-CREE THAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15AD,
+ },
+ [0x15AE]={
+ category="lo",
+ description="CANADIAN SYLLABICS TH-CREE TH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15AE,
+ },
+ [0x15AF]={
+ category="lo",
+ description="CANADIAN SYLLABICS AIVILIK B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15AF,
+ },
+ [0x15B0]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B0,
+ },
+ [0x15B1]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B1,
+ },
+ [0x15B2]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B2,
+ },
+ [0x15B3]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B3,
+ },
+ [0x15B4]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT WE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B4,
+ },
+ [0x15B5]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT WI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B5,
+ },
+ [0x15B6]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT WO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B6,
+ },
+ [0x15B7]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B7,
+ },
+ [0x15B8]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B8,
+ },
+ [0x15B9]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT NI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15B9,
+ },
+ [0x15BA]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT NO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15BA,
+ },
+ [0x15BB]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15BB,
+ },
+ [0x15BC]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT KE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15BC,
+ },
+ [0x15BD]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15BD,
+ },
+ [0x15BE]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT KO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15BE,
+ },
+ [0x15BF]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15BF,
+ },
+ [0x15C0]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI HE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C0,
+ },
+ [0x15C1]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI HI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C1,
+ },
+ [0x15C2]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI HO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C2,
+ },
+ [0x15C3]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C3,
+ },
+ [0x15C4]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C4,
+ },
+ [0x15C5]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C5,
+ },
+ [0x15C6]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C6,
+ },
+ [0x15C7]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C7,
+ },
+ [0x15C8]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C8,
+ },
+ [0x15C9]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15C9,
+ },
+ [0x15CA]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER RU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15CA,
+ },
+ [0x15CB]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER RO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15CB,
+ },
+ [0x15CC]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER RE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15CC,
+ },
+ [0x15CD]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER REE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15CD,
+ },
+ [0x15CE]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER RI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15CE,
+ },
+ [0x15CF]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15CF,
+ },
+ [0x15D0]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER WU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D0,
+ },
+ [0x15D1]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER WO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D1,
+ },
+ [0x15D2]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER WE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D2,
+ },
+ [0x15D3]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER WEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D3,
+ },
+ [0x15D4]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER WI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D4,
+ },
+ [0x15D5]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D5,
+ },
+ [0x15D6]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER HWU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D6,
+ },
+ [0x15D7]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER HWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D7,
+ },
+ [0x15D8]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER HWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D8,
+ },
+ [0x15D9]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER HWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15D9,
+ },
+ [0x15DA]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER HWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15DA,
+ },
+ [0x15DB]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER HWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15DB,
+ },
+ [0x15DC]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER THU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15DC,
+ },
+ [0x15DD]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER THO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15DD,
+ },
+ [0x15DE]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER THE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15DE,
+ },
+ [0x15DF]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER THEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15DF,
+ },
+ [0x15E0]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER THI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E0,
+ },
+ [0x15E1]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E1,
+ },
+ [0x15E2]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TTU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E2,
+ },
+ [0x15E3]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TTO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E3,
+ },
+ [0x15E4]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TTE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E4,
+ },
+ [0x15E5]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TTEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E5,
+ },
+ [0x15E6]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TTI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E6,
+ },
+ [0x15E7]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E7,
+ },
+ [0x15E8]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER PU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E8,
+ },
+ [0x15E9]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER PO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15E9,
+ },
+ [0x15EA]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER PE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15EA,
+ },
+ [0x15EB]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER PEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15EB,
+ },
+ [0x15EC]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER PI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15EC,
+ },
+ [0x15ED]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15ED,
+ },
+ [0x15EE]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER P",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15EE,
+ },
+ [0x15EF]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15EF,
+ },
+ [0x15F0]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F0,
+ },
+ [0x15F1]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F1,
+ },
+ [0x15F2]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F2,
+ },
+ [0x15F3]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F3,
+ },
+ [0x15F4]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F4,
+ },
+ [0x15F5]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F5,
+ },
+ [0x15F6]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F6,
+ },
+ [0x15F7]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F7,
+ },
+ [0x15F8]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F8,
+ },
+ [0x15F9]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15F9,
+ },
+ [0x15FA]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15FA,
+ },
+ [0x15FB]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KKU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15FB,
+ },
+ [0x15FC]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KKO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15FC,
+ },
+ [0x15FD]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15FD,
+ },
+ [0x15FE]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KKEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15FE,
+ },
+ [0x15FF]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KKI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x15FF,
+ },
+ [0x1600]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KKA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1600,
+ },
+ [0x1601]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER KK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1601,
+ },
+ [0x1602]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER NU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1602,
+ },
+ [0x1603]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER NO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1603,
+ },
+ [0x1604]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1604,
+ },
+ [0x1605]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER NEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1605,
+ },
+ [0x1606]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER NI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1606,
+ },
+ [0x1607]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1607,
+ },
+ [0x1608]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER MU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1608,
+ },
+ [0x1609]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER MO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1609,
+ },
+ [0x160A]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER ME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x160A,
+ },
+ [0x160B]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER MEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x160B,
+ },
+ [0x160C]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x160C,
+ },
+ [0x160D]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x160D,
+ },
+ [0x160E]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER YU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x160E,
+ },
+ [0x160F]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER YO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x160F,
+ },
+ [0x1610]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER YE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1610,
+ },
+ [0x1611]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER YEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1611,
+ },
+ [0x1612]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER YI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1612,
+ },
+ [0x1613]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1613,
+ },
+ [0x1614]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1614,
+ },
+ [0x1615]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI JU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1615,
+ },
+ [0x1616]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1616,
+ },
+ [0x1617]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1617,
+ },
+ [0x1618]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1618,
+ },
+ [0x1619]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1619,
+ },
+ [0x161A]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI JI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x161A,
+ },
+ [0x161B]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x161B,
+ },
+ [0x161C]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JJU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x161C,
+ },
+ [0x161D]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JJO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x161D,
+ },
+ [0x161E]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JJE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x161E,
+ },
+ [0x161F]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JJEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x161F,
+ },
+ [0x1620]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JJI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1620,
+ },
+ [0x1621]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JJA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1621,
+ },
+ [0x1622]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1622,
+ },
+ [0x1623]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER LO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1623,
+ },
+ [0x1624]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER LE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1624,
+ },
+ [0x1625]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER LEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1625,
+ },
+ [0x1626]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER LI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1626,
+ },
+ [0x1627]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1627,
+ },
+ [0x1628]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DLU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1628,
+ },
+ [0x1629]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DLO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1629,
+ },
+ [0x162A]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DLE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x162A,
+ },
+ [0x162B]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DLEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x162B,
+ },
+ [0x162C]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x162C,
+ },
+ [0x162D]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x162D,
+ },
+ [0x162E]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER LHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x162E,
+ },
+ [0x162F]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER LHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x162F,
+ },
+ [0x1630]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER LHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1630,
+ },
+ [0x1631]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER LHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1631,
+ },
+ [0x1632]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER LHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1632,
+ },
+ [0x1633]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER LHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1633,
+ },
+ [0x1634]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TLHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1634,
+ },
+ [0x1635]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TLHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1635,
+ },
+ [0x1636]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TLHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1636,
+ },
+ [0x1637]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TLHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1637,
+ },
+ [0x1638]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TLHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1638,
+ },
+ [0x1639]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TLHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1639,
+ },
+ [0x163A]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TLU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x163A,
+ },
+ [0x163B]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TLO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x163B,
+ },
+ [0x163C]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TLE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x163C,
+ },
+ [0x163D]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TLEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x163D,
+ },
+ [0x163E]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x163E,
+ },
+ [0x163F]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x163F,
+ },
+ [0x1640]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER ZU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1640,
+ },
+ [0x1641]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER ZO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1641,
+ },
+ [0x1642]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER ZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1642,
+ },
+ [0x1643]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER ZEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1643,
+ },
+ [0x1644]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER ZI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1644,
+ },
+ [0x1645]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1645,
+ },
+ [0x1646]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER Z",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1646,
+ },
+ [0x1647]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER INITIAL Z",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1647,
+ },
+ [0x1648]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DZU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1648,
+ },
+ [0x1649]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DZO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1649,
+ },
+ [0x164A]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x164A,
+ },
+ [0x164B]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DZEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x164B,
+ },
+ [0x164C]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DZI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x164C,
+ },
+ [0x164D]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x164D,
+ },
+ [0x164E]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x164E,
+ },
+ [0x164F]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x164F,
+ },
+ [0x1650]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1650,
+ },
+ [0x1651]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1651,
+ },
+ [0x1652]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1652,
+ },
+ [0x1653]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1653,
+ },
+ [0x1654]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1654,
+ },
+ [0x1655]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1655,
+ },
+ [0x1656]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1656,
+ },
+ [0x1657]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1657,
+ },
+ [0x1658]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1658,
+ },
+ [0x1659]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1659,
+ },
+ [0x165A]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER SH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x165A,
+ },
+ [0x165B]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TSU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x165B,
+ },
+ [0x165C]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TSO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x165C,
+ },
+ [0x165D]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TSE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x165D,
+ },
+ [0x165E]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TSEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x165E,
+ },
+ [0x165F]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TSI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x165F,
+ },
+ [0x1660]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1660,
+ },
+ [0x1661]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER CHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1661,
+ },
+ [0x1662]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER CHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1662,
+ },
+ [0x1663]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER CHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1663,
+ },
+ [0x1664]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER CHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1664,
+ },
+ [0x1665]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER CHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1665,
+ },
+ [0x1666]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1666,
+ },
+ [0x1667]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TTSU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1667,
+ },
+ [0x1668]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TTSO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1668,
+ },
+ [0x1669]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TTSE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1669,
+ },
+ [0x166A]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TTSEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166A,
+ },
+ [0x166B]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TTSI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166B,
+ },
+ [0x166C]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER TTSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166C,
+ },
+ [0x166D]={
+ category="po",
+ description="CANADIAN SYLLABICS CHI SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166D,
+ },
+ [0x166E]={
+ category="po",
+ description="CANADIAN SYLLABICS FULL STOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166E,
+ },
+ [0x166F]={
+ category="lo",
+ description="CANADIAN SYLLABICS QAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x166F,
+ },
+ [0x1670]={
+ category="lo",
+ description="CANADIAN SYLLABICS NGAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1670,
+ },
+ [0x1671]={
+ category="lo",
+ description="CANADIAN SYLLABICS NNGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1671,
+ },
+ [0x1672]={
+ category="lo",
+ description="CANADIAN SYLLABICS NNGII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1672,
+ },
+ [0x1673]={
+ category="lo",
+ description="CANADIAN SYLLABICS NNGO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1673,
+ },
+ [0x1674]={
+ category="lo",
+ description="CANADIAN SYLLABICS NNGOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1674,
+ },
+ [0x1675]={
+ category="lo",
+ description="CANADIAN SYLLABICS NNGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1675,
+ },
+ [0x1676]={
+ category="lo",
+ description="CANADIAN SYLLABICS NNGAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1676,
+ },
+ [0x1677]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE THWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1677,
+ },
+ [0x1678]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE THWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1678,
+ },
+ [0x1679]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE THWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1679,
+ },
+ [0x167A]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE THWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167A,
+ },
+ [0x167B]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE THWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167B,
+ },
+ [0x167C]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE THWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167C,
+ },
+ [0x167D]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE THWAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167D,
+ },
+ [0x167E]={
+ category="lo",
+ description="CANADIAN SYLLABICS WOODS-CREE FINAL TH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167E,
+ },
+ [0x167F]={
+ category="lo",
+ description="CANADIAN SYLLABICS BLACKFOOT W",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x167F,
+ },
+ [0x1680]={
+ category="zs",
+ description="OGHAM SPACE MARK",
+ direction="ws",
+ linebreak="ba",
+ unicodeslot=0x1680,
+ },
+ [0x1681]={
+ category="lo",
+ description="OGHAM LETTER BEITH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681,
+ },
+ [0x1682]={
+ category="lo",
+ description="OGHAM LETTER LUIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682,
+ },
+ [0x1683]={
+ category="lo",
+ description="OGHAM LETTER FEARN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683,
+ },
+ [0x1684]={
+ category="lo",
+ description="OGHAM LETTER SAIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684,
+ },
+ [0x1685]={
+ category="lo",
+ description="OGHAM LETTER NION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685,
+ },
+ [0x1686]={
+ category="lo",
+ description="OGHAM LETTER UATH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686,
+ },
+ [0x1687]={
+ category="lo",
+ description="OGHAM LETTER DAIR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687,
+ },
+ [0x1688]={
+ category="lo",
+ description="OGHAM LETTER TINNE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688,
+ },
+ [0x1689]={
+ category="lo",
+ description="OGHAM LETTER COLL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689,
+ },
+ [0x168A]={
+ category="lo",
+ description="OGHAM LETTER CEIRT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A,
+ },
+ [0x168B]={
+ category="lo",
+ description="OGHAM LETTER MUIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B,
+ },
+ [0x168C]={
+ category="lo",
+ description="OGHAM LETTER GORT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C,
+ },
+ [0x168D]={
+ category="lo",
+ description="OGHAM LETTER NGEADAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D,
+ },
+ [0x168E]={
+ category="lo",
+ description="OGHAM LETTER STRAIF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E,
+ },
+ [0x168F]={
+ category="lo",
+ description="OGHAM LETTER RUIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F,
+ },
+ [0x1690]={
+ category="lo",
+ description="OGHAM LETTER AILM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690,
+ },
+ [0x1691]={
+ category="lo",
+ description="OGHAM LETTER ONN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691,
+ },
+ [0x1692]={
+ category="lo",
+ description="OGHAM LETTER UR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692,
+ },
+ [0x1693]={
+ category="lo",
+ description="OGHAM LETTER EADHADH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693,
+ },
+ [0x1694]={
+ category="lo",
+ description="OGHAM LETTER IODHADH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694,
+ },
+ [0x1695]={
+ category="lo",
+ description="OGHAM LETTER EABHADH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695,
+ },
+ [0x1696]={
+ category="lo",
+ description="OGHAM LETTER OR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696,
+ },
+ [0x1697]={
+ category="lo",
+ description="OGHAM LETTER UILLEANN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697,
+ },
+ [0x1698]={
+ category="lo",
+ description="OGHAM LETTER IFIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698,
+ },
+ [0x1699]={
+ category="lo",
+ description="OGHAM LETTER EAMHANCHOLL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699,
+ },
+ [0x169A]={
+ category="lo",
+ description="OGHAM LETTER PEITH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A,
+ },
+ [0x169B]={
+ category="ps",
+ description="OGHAM FEATHER MARK",
+ direction="on",
+ linebreak="op",
+ mirror=0x169C,
+ unicodeslot=0x169B,
+ },
+ [0x169C]={
+ category="pe",
+ description="OGHAM REVERSED FEATHER MARK",
+ direction="on",
+ linebreak="cl",
+ mirror=0x169B,
+ unicodeslot=0x169C,
+ },
+ [0x16A0]={
+ category="lo",
+ description="RUNIC LETTER FEHU FEOH FE F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0,
+ },
+ [0x16A1]={
+ category="lo",
+ description="RUNIC LETTER V",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1,
+ },
+ [0x16A2]={
+ category="lo",
+ description="RUNIC LETTER URUZ UR U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2,
+ },
+ [0x16A3]={
+ category="lo",
+ description="RUNIC LETTER YR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A3,
+ },
+ [0x16A4]={
+ category="lo",
+ description="RUNIC LETTER Y",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A4,
+ },
+ [0x16A5]={
+ category="lo",
+ description="RUNIC LETTER W",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A5,
+ },
+ [0x16A6]={
+ category="lo",
+ description="RUNIC LETTER THURISAZ THURS THORN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A6,
+ },
+ [0x16A7]={
+ category="lo",
+ description="RUNIC LETTER ETH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A7,
+ },
+ [0x16A8]={
+ category="lo",
+ description="RUNIC LETTER ANSUZ A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A8,
+ },
+ [0x16A9]={
+ category="lo",
+ description="RUNIC LETTER OS O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A9,
+ },
+ [0x16AA]={
+ category="lo",
+ description="RUNIC LETTER AC A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AA,
+ },
+ [0x16AB]={
+ category="lo",
+ description="RUNIC LETTER AESC",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AB,
+ },
+ [0x16AC]={
+ category="lo",
+ description="RUNIC LETTER LONG-BRANCH-OSS O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AC,
+ },
+ [0x16AD]={
+ category="lo",
+ description="RUNIC LETTER SHORT-TWIG-OSS O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AD,
+ },
+ [0x16AE]={
+ category="lo",
+ description="RUNIC LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AE,
+ },
+ [0x16AF]={
+ category="lo",
+ description="RUNIC LETTER OE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16AF,
+ },
+ [0x16B0]={
+ category="lo",
+ description="RUNIC LETTER ON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B0,
+ },
+ [0x16B1]={
+ category="lo",
+ description="RUNIC LETTER RAIDO RAD REID R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B1,
+ },
+ [0x16B2]={
+ category="lo",
+ description="RUNIC LETTER KAUNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B2,
+ },
+ [0x16B3]={
+ category="lo",
+ description="RUNIC LETTER CEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B3,
+ },
+ [0x16B4]={
+ category="lo",
+ description="RUNIC LETTER KAUN K",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B4,
+ },
+ [0x16B5]={
+ category="lo",
+ description="RUNIC LETTER G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B5,
+ },
+ [0x16B6]={
+ category="lo",
+ description="RUNIC LETTER ENG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B6,
+ },
+ [0x16B7]={
+ category="lo",
+ description="RUNIC LETTER GEBO GYFU G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B7,
+ },
+ [0x16B8]={
+ category="lo",
+ description="RUNIC LETTER GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B8,
+ },
+ [0x16B9]={
+ category="lo",
+ description="RUNIC LETTER WUNJO WYNN W",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16B9,
+ },
+ [0x16BA]={
+ category="lo",
+ description="RUNIC LETTER HAGLAZ H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16BA,
+ },
+ [0x16BB]={
+ category="lo",
+ description="RUNIC LETTER HAEGL H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16BB,
+ },
+ [0x16BC]={
+ category="lo",
+ description="RUNIC LETTER LONG-BRANCH-HAGALL H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16BC,
+ },
+ [0x16BD]={
+ category="lo",
+ description="RUNIC LETTER SHORT-TWIG-HAGALL H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16BD,
+ },
+ [0x16BE]={
+ category="lo",
+ description="RUNIC LETTER NAUDIZ NYD NAUD N",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16BE,
+ },
+ [0x16BF]={
+ category="lo",
+ description="RUNIC LETTER SHORT-TWIG-NAUD N",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16BF,
+ },
+ [0x16C0]={
+ category="lo",
+ description="RUNIC LETTER DOTTED-N",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C0,
+ },
+ [0x16C1]={
+ category="lo",
+ description="RUNIC LETTER ISAZ IS ISS I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C1,
+ },
+ [0x16C2]={
+ category="lo",
+ description="RUNIC LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C2,
+ },
+ [0x16C3]={
+ category="lo",
+ description="RUNIC LETTER JERAN J",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C3,
+ },
+ [0x16C4]={
+ category="lo",
+ description="RUNIC LETTER GER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C4,
+ },
+ [0x16C5]={
+ category="lo",
+ description="RUNIC LETTER LONG-BRANCH-AR AE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C5,
+ },
+ [0x16C6]={
+ category="lo",
+ description="RUNIC LETTER SHORT-TWIG-AR A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C6,
+ },
+ [0x16C7]={
+ category="lo",
+ description="RUNIC LETTER IWAZ EOH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C7,
+ },
+ [0x16C8]={
+ category="lo",
+ description="RUNIC LETTER PERTHO PEORTH P",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C8,
+ },
+ [0x16C9]={
+ category="lo",
+ description="RUNIC LETTER ALGIZ EOLHX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16C9,
+ },
+ [0x16CA]={
+ category="lo",
+ description="RUNIC LETTER SOWILO S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16CA,
+ },
+ [0x16CB]={
+ category="lo",
+ description="RUNIC LETTER SIGEL LONG-BRANCH-SOL S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16CB,
+ },
+ [0x16CC]={
+ category="lo",
+ description="RUNIC LETTER SHORT-TWIG-SOL S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16CC,
+ },
+ [0x16CD]={
+ category="lo",
+ description="RUNIC LETTER C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16CD,
+ },
+ [0x16CE]={
+ category="lo",
+ description="RUNIC LETTER Z",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16CE,
+ },
+ [0x16CF]={
+ category="lo",
+ description="RUNIC LETTER TIWAZ TIR TYR T",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16CF,
+ },
+ [0x16D0]={
+ category="lo",
+ description="RUNIC LETTER SHORT-TWIG-TYR T",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D0,
+ },
+ [0x16D1]={
+ category="lo",
+ description="RUNIC LETTER D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D1,
+ },
+ [0x16D2]={
+ category="lo",
+ description="RUNIC LETTER BERKANAN BEORC BJARKAN B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D2,
+ },
+ [0x16D3]={
+ category="lo",
+ description="RUNIC LETTER SHORT-TWIG-BJARKAN B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D3,
+ },
+ [0x16D4]={
+ category="lo",
+ description="RUNIC LETTER DOTTED-P",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D4,
+ },
+ [0x16D5]={
+ category="lo",
+ description="RUNIC LETTER OPEN-P",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D5,
+ },
+ [0x16D6]={
+ category="lo",
+ description="RUNIC LETTER EHWAZ EH E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D6,
+ },
+ [0x16D7]={
+ category="lo",
+ description="RUNIC LETTER MANNAZ MAN M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D7,
+ },
+ [0x16D8]={
+ category="lo",
+ description="RUNIC LETTER LONG-BRANCH-MADR M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D8,
+ },
+ [0x16D9]={
+ category="lo",
+ description="RUNIC LETTER SHORT-TWIG-MADR M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16D9,
+ },
+ [0x16DA]={
+ category="lo",
+ description="RUNIC LETTER LAUKAZ LAGU LOGR L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16DA,
+ },
+ [0x16DB]={
+ category="lo",
+ description="RUNIC LETTER DOTTED-L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16DB,
+ },
+ [0x16DC]={
+ category="lo",
+ description="RUNIC LETTER INGWAZ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16DC,
+ },
+ [0x16DD]={
+ category="lo",
+ description="RUNIC LETTER ING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16DD,
+ },
+ [0x16DE]={
+ category="lo",
+ description="RUNIC LETTER DAGAZ DAEG D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16DE,
+ },
+ [0x16DF]={
+ category="lo",
+ description="RUNIC LETTER OTHALAN ETHEL O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16DF,
+ },
+ [0x16E0]={
+ category="lo",
+ description="RUNIC LETTER EAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E0,
+ },
+ [0x16E1]={
+ category="lo",
+ description="RUNIC LETTER IOR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E1,
+ },
+ [0x16E2]={
+ category="lo",
+ description="RUNIC LETTER CWEORTH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E2,
+ },
+ [0x16E3]={
+ category="lo",
+ description="RUNIC LETTER CALC",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E3,
+ },
+ [0x16E4]={
+ category="lo",
+ description="RUNIC LETTER CEALC",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E4,
+ },
+ [0x16E5]={
+ category="lo",
+ description="RUNIC LETTER STAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E5,
+ },
+ [0x16E6]={
+ category="lo",
+ description="RUNIC LETTER LONG-BRANCH-YR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E6,
+ },
+ [0x16E7]={
+ category="lo",
+ description="RUNIC LETTER SHORT-TWIG-YR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E7,
+ },
+ [0x16E8]={
+ category="lo",
+ description="RUNIC LETTER ICELANDIC-YR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E8,
+ },
+ [0x16E9]={
+ category="lo",
+ description="RUNIC LETTER Q",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16E9,
+ },
+ [0x16EA]={
+ category="lo",
+ description="RUNIC LETTER X",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16EA,
+ },
+ [0x16EB]={
+ category="po",
+ description="RUNIC SINGLE PUNCTUATION",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16EB,
+ },
+ [0x16EC]={
+ category="po",
+ description="RUNIC MULTIPLE PUNCTUATION",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16EC,
+ },
+ [0x16ED]={
+ category="po",
+ description="RUNIC CROSS PUNCTUATION",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x16ED,
+ },
+ [0x16EE]={
+ category="nl",
+ description="RUNIC ARLAUG SYMBOL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16EE,
+ },
+ [0x16EF]={
+ category="nl",
+ description="RUNIC TVIMADUR SYMBOL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16EF,
+ },
+ [0x16F0]={
+ category="nl",
+ description="RUNIC BELGTHOR SYMBOL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0,
+ },
+ [0x1700]={
+ category="lo",
+ description="TAGALOG LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1700,
+ },
+ [0x1701]={
+ category="lo",
+ description="TAGALOG LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1701,
+ },
+ [0x1702]={
+ category="lo",
+ description="TAGALOG LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1702,
+ },
+ [0x1703]={
+ category="lo",
+ description="TAGALOG LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1703,
+ },
+ [0x1704]={
+ category="lo",
+ description="TAGALOG LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1704,
+ },
+ [0x1705]={
+ category="lo",
+ description="TAGALOG LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1705,
+ },
+ [0x1706]={
+ category="lo",
+ description="TAGALOG LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1706,
+ },
+ [0x1707]={
+ category="lo",
+ description="TAGALOG LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1707,
+ },
+ [0x1708]={
+ category="lo",
+ description="TAGALOG LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1708,
+ },
+ [0x1709]={
+ category="lo",
+ description="TAGALOG LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1709,
+ },
+ [0x170A]={
+ category="lo",
+ description="TAGALOG LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x170A,
+ },
+ [0x170B]={
+ category="lo",
+ description="TAGALOG LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x170B,
+ },
+ [0x170C]={
+ category="lo",
+ description="TAGALOG LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x170C,
+ },
+ [0x170E]={
+ category="lo",
+ description="TAGALOG LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x170E,
+ },
+ [0x170F]={
+ category="lo",
+ description="TAGALOG LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x170F,
+ },
+ [0x1710]={
+ category="lo",
+ description="TAGALOG LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1710,
+ },
+ [0x1711]={
+ category="lo",
+ description="TAGALOG LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1711,
+ },
+ [0x1712]={
+ category="mn",
+ description="TAGALOG VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1712,
+ },
+ [0x1713]={
+ category="mn",
+ description="TAGALOG VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1713,
+ },
+ [0x1714]={
+ category="mn",
+ description="TAGALOG SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1714,
+ },
+ [0x1720]={
+ category="lo",
+ description="HANUNOO LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1720,
+ },
+ [0x1721]={
+ category="lo",
+ description="HANUNOO LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1721,
+ },
+ [0x1722]={
+ category="lo",
+ description="HANUNOO LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1722,
+ },
+ [0x1723]={
+ category="lo",
+ description="HANUNOO LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1723,
+ },
+ [0x1724]={
+ category="lo",
+ description="HANUNOO LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1724,
+ },
+ [0x1725]={
+ category="lo",
+ description="HANUNOO LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1725,
+ },
+ [0x1726]={
+ category="lo",
+ description="HANUNOO LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1726,
+ },
+ [0x1727]={
+ category="lo",
+ description="HANUNOO LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1727,
+ },
+ [0x1728]={
+ category="lo",
+ description="HANUNOO LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1728,
+ },
+ [0x1729]={
+ category="lo",
+ description="HANUNOO LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1729,
+ },
+ [0x172A]={
+ category="lo",
+ description="HANUNOO LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x172A,
+ },
+ [0x172B]={
+ category="lo",
+ description="HANUNOO LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x172B,
+ },
+ [0x172C]={
+ category="lo",
+ description="HANUNOO LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x172C,
+ },
+ [0x172D]={
+ category="lo",
+ description="HANUNOO LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x172D,
+ },
+ [0x172E]={
+ category="lo",
+ description="HANUNOO LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x172E,
+ },
+ [0x172F]={
+ category="lo",
+ description="HANUNOO LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x172F,
+ },
+ [0x1730]={
+ category="lo",
+ description="HANUNOO LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1730,
+ },
+ [0x1731]={
+ category="lo",
+ description="HANUNOO LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1731,
+ },
+ [0x1732]={
+ category="mn",
+ description="HANUNOO VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1732,
+ },
+ [0x1733]={
+ category="mn",
+ description="HANUNOO VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1733,
+ },
+ [0x1734]={
+ category="mn",
+ description="HANUNOO SIGN PAMUDPOD",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1734,
+ },
+ [0x1735]={
+ category="po",
+ description="PHILIPPINE SINGLE PUNCTUATION",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1735,
+ },
+ [0x1736]={
+ category="po",
+ description="PHILIPPINE DOUBLE PUNCTUATION",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1736,
+ },
+ [0x1740]={
+ category="lo",
+ description="BUHID LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1740,
+ },
+ [0x1741]={
+ category="lo",
+ description="BUHID LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1741,
+ },
+ [0x1742]={
+ category="lo",
+ description="BUHID LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1742,
+ },
+ [0x1743]={
+ category="lo",
+ description="BUHID LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1743,
+ },
+ [0x1744]={
+ category="lo",
+ description="BUHID LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1744,
+ },
+ [0x1745]={
+ category="lo",
+ description="BUHID LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1745,
+ },
+ [0x1746]={
+ category="lo",
+ description="BUHID LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1746,
+ },
+ [0x1747]={
+ category="lo",
+ description="BUHID LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1747,
+ },
+ [0x1748]={
+ category="lo",
+ description="BUHID LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1748,
+ },
+ [0x1749]={
+ category="lo",
+ description="BUHID LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1749,
+ },
+ [0x174A]={
+ category="lo",
+ description="BUHID LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x174A,
+ },
+ [0x174B]={
+ category="lo",
+ description="BUHID LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x174B,
+ },
+ [0x174C]={
+ category="lo",
+ description="BUHID LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x174C,
+ },
+ [0x174D]={
+ category="lo",
+ description="BUHID LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x174D,
+ },
+ [0x174E]={
+ category="lo",
+ description="BUHID LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x174E,
+ },
+ [0x174F]={
+ category="lo",
+ description="BUHID LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x174F,
+ },
+ [0x1750]={
+ category="lo",
+ description="BUHID LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1750,
+ },
+ [0x1751]={
+ category="lo",
+ description="BUHID LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1751,
+ },
+ [0x1752]={
+ category="mn",
+ description="BUHID VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1752,
+ },
+ [0x1753]={
+ category="mn",
+ description="BUHID VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1753,
+ },
+ [0x1760]={
+ category="lo",
+ description="TAGBANWA LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1760,
+ },
+ [0x1761]={
+ category="lo",
+ description="TAGBANWA LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1761,
+ },
+ [0x1762]={
+ category="lo",
+ description="TAGBANWA LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1762,
+ },
+ [0x1763]={
+ category="lo",
+ description="TAGBANWA LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1763,
+ },
+ [0x1764]={
+ category="lo",
+ description="TAGBANWA LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1764,
+ },
+ [0x1765]={
+ category="lo",
+ description="TAGBANWA LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1765,
+ },
+ [0x1766]={
+ category="lo",
+ description="TAGBANWA LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1766,
+ },
+ [0x1767]={
+ category="lo",
+ description="TAGBANWA LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1767,
+ },
+ [0x1768]={
+ category="lo",
+ description="TAGBANWA LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1768,
+ },
+ [0x1769]={
+ category="lo",
+ description="TAGBANWA LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1769,
+ },
+ [0x176A]={
+ category="lo",
+ description="TAGBANWA LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x176A,
+ },
+ [0x176B]={
+ category="lo",
+ description="TAGBANWA LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x176B,
+ },
+ [0x176C]={
+ category="lo",
+ description="TAGBANWA LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x176C,
+ },
+ [0x176E]={
+ category="lo",
+ description="TAGBANWA LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x176E,
+ },
+ [0x176F]={
+ category="lo",
+ description="TAGBANWA LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x176F,
+ },
+ [0x1770]={
+ category="lo",
+ description="TAGBANWA LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1770,
+ },
+ [0x1772]={
+ category="mn",
+ description="TAGBANWA VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1772,
+ },
+ [0x1773]={
+ category="mn",
+ description="TAGBANWA VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1773,
+ },
+ [0x1780]={
+ category="lo",
+ description="KHMER LETTER KA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1780,
+ },
+ [0x1781]={
+ category="lo",
+ description="KHMER LETTER KHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1781,
+ },
+ [0x1782]={
+ category="lo",
+ description="KHMER LETTER KO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1782,
+ },
+ [0x1783]={
+ category="lo",
+ description="KHMER LETTER KHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1783,
+ },
+ [0x1784]={
+ category="lo",
+ description="KHMER LETTER NGO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1784,
+ },
+ [0x1785]={
+ category="lo",
+ description="KHMER LETTER CA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1785,
+ },
+ [0x1786]={
+ category="lo",
+ description="KHMER LETTER CHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1786,
+ },
+ [0x1787]={
+ category="lo",
+ description="KHMER LETTER CO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1787,
+ },
+ [0x1788]={
+ category="lo",
+ description="KHMER LETTER CHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1788,
+ },
+ [0x1789]={
+ category="lo",
+ description="KHMER LETTER NYO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1789,
+ },
+ [0x178A]={
+ category="lo",
+ description="KHMER LETTER DA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x178A,
+ },
+ [0x178B]={
+ category="lo",
+ description="KHMER LETTER TTHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x178B,
+ },
+ [0x178C]={
+ category="lo",
+ description="KHMER LETTER DO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x178C,
+ },
+ [0x178D]={
+ category="lo",
+ description="KHMER LETTER TTHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x178D,
+ },
+ [0x178E]={
+ category="lo",
+ description="KHMER LETTER NNO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x178E,
+ },
+ [0x178F]={
+ category="lo",
+ description="KHMER LETTER TA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x178F,
+ },
+ [0x1790]={
+ category="lo",
+ description="KHMER LETTER THA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1790,
+ },
+ [0x1791]={
+ category="lo",
+ description="KHMER LETTER TO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1791,
+ },
+ [0x1792]={
+ category="lo",
+ description="KHMER LETTER THO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1792,
+ },
+ [0x1793]={
+ category="lo",
+ description="KHMER LETTER NO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1793,
+ },
+ [0x1794]={
+ category="lo",
+ description="KHMER LETTER BA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1794,
+ },
+ [0x1795]={
+ category="lo",
+ description="KHMER LETTER PHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1795,
+ },
+ [0x1796]={
+ category="lo",
+ description="KHMER LETTER PO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1796,
+ },
+ [0x1797]={
+ category="lo",
+ description="KHMER LETTER PHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1797,
+ },
+ [0x1798]={
+ category="lo",
+ description="KHMER LETTER MO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1798,
+ },
+ [0x1799]={
+ category="lo",
+ description="KHMER LETTER YO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1799,
+ },
+ [0x179A]={
+ category="lo",
+ description="KHMER LETTER RO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x179A,
+ },
+ [0x179B]={
+ category="lo",
+ description="KHMER LETTER LO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x179B,
+ },
+ [0x179C]={
+ category="lo",
+ description="KHMER LETTER VO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x179C,
+ },
+ [0x179D]={
+ category="lo",
+ description="KHMER LETTER SHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x179D,
+ },
+ [0x179E]={
+ category="lo",
+ description="KHMER LETTER SSO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x179E,
+ },
+ [0x179F]={
+ category="lo",
+ description="KHMER LETTER SA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x179F,
+ },
+ [0x17A0]={
+ category="lo",
+ description="KHMER LETTER HA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A0,
+ },
+ [0x17A1]={
+ category="lo",
+ description="KHMER LETTER LA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A1,
+ },
+ [0x17A2]={
+ category="lo",
+ description="KHMER LETTER QA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A2,
+ },
+ [0x17A3]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QAQ",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A3,
+ },
+ [0x17A4]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QAA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A4,
+ },
+ [0x17A5]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A5,
+ },
+ [0x17A6]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QII",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A6,
+ },
+ [0x17A7]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A7,
+ },
+ [0x17A8]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QUK",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A8,
+ },
+ [0x17A9]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QUU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17A9,
+ },
+ [0x17AA]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QUUV",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17AA,
+ },
+ [0x17AB]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL RY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17AB,
+ },
+ [0x17AC]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL RYY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17AC,
+ },
+ [0x17AD]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL LY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17AD,
+ },
+ [0x17AE]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL LYY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17AE,
+ },
+ [0x17AF]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17AF,
+ },
+ [0x17B0]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QAI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17B0,
+ },
+ [0x17B1]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QOO TYPE ONE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17B1,
+ },
+ [0x17B2]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QOO TYPE TWO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17B2,
+ },
+ [0x17B3]={
+ category="lo",
+ description="KHMER INDEPENDENT VOWEL QAU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17B3,
+ },
+ [0x17B4]={
+ category="cf",
+ description="KHMER VOWEL INHERENT AQ",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17B4,
+ },
+ [0x17B5]={
+ category="cf",
+ description="KHMER VOWEL INHERENT AA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17B5,
+ },
+ [0x17B6]={
+ category="mc",
+ description="KHMER VOWEL SIGN AA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17B6,
+ },
+ [0x17B7]={
+ category="mn",
+ description="KHMER VOWEL SIGN I",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17B7,
+ },
+ [0x17B8]={
+ category="mn",
+ description="KHMER VOWEL SIGN II",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17B8,
+ },
+ [0x17B9]={
+ category="mn",
+ description="KHMER VOWEL SIGN Y",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17B9,
+ },
+ [0x17BA]={
+ category="mn",
+ description="KHMER VOWEL SIGN YY",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17BA,
+ },
+ [0x17BB]={
+ category="mn",
+ description="KHMER VOWEL SIGN U",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17BB,
+ },
+ [0x17BC]={
+ category="mn",
+ description="KHMER VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17BC,
+ },
+ [0x17BD]={
+ category="mn",
+ description="KHMER VOWEL SIGN UA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17BD,
+ },
+ [0x17BE]={
+ category="mc",
+ description="KHMER VOWEL SIGN OE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17BE,
+ },
+ [0x17BF]={
+ category="mc",
+ description="KHMER VOWEL SIGN YA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17BF,
+ },
+ [0x17C0]={
+ category="mc",
+ description="KHMER VOWEL SIGN IE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C0,
+ },
+ [0x17C1]={
+ category="mc",
+ description="KHMER VOWEL SIGN E",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C1,
+ },
+ [0x17C2]={
+ category="mc",
+ description="KHMER VOWEL SIGN AE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C2,
+ },
+ [0x17C3]={
+ category="mc",
+ description="KHMER VOWEL SIGN AI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C3,
+ },
+ [0x17C4]={
+ category="mc",
+ description="KHMER VOWEL SIGN OO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C4,
+ },
+ [0x17C5]={
+ category="mc",
+ description="KHMER VOWEL SIGN AU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C5,
+ },
+ [0x17C6]={
+ category="mn",
+ description="KHMER SIGN NIKAHIT",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17C6,
+ },
+ [0x17C7]={
+ category="mc",
+ description="KHMER SIGN REAHMUK",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C7,
+ },
+ [0x17C8]={
+ category="mc",
+ description="KHMER SIGN YUUKALEAPINTU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17C8,
+ },
+ [0x17C9]={
+ category="mn",
+ description="KHMER SIGN MUUSIKATOAN",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17C9,
+ },
+ [0x17CA]={
+ category="mn",
+ description="KHMER SIGN TRIISAP",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17CA,
+ },
+ [0x17CB]={
+ category="mn",
+ description="KHMER SIGN BANTOC",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17CB,
+ },
+ [0x17CC]={
+ category="mn",
+ description="KHMER SIGN ROBAT",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17CC,
+ },
+ [0x17CD]={
+ category="mn",
+ description="KHMER SIGN TOANDAKHIAT",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17CD,
+ },
+ [0x17CE]={
+ category="mn",
+ description="KHMER SIGN KAKABAT",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17CE,
+ },
+ [0x17CF]={
+ category="mn",
+ description="KHMER SIGN AHSDA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17CF,
+ },
+ [0x17D0]={
+ category="mn",
+ description="KHMER SIGN SAMYOK SANNYA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17D0,
+ },
+ [0x17D1]={
+ category="mn",
+ description="KHMER SIGN VIRIAM",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17D1,
+ },
+ [0x17D2]={
+ category="mn",
+ description="KHMER SIGN COENG",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17D2,
+ },
+ [0x17D3]={
+ category="mn",
+ description="KHMER SIGN BATHAMASAT",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17D3,
+ },
+ [0x17D4]={
+ category="po",
+ description="KHMER SIGN KHAN",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x17D4,
+ },
+ [0x17D5]={
+ category="po",
+ description="KHMER SIGN BARIYOOSAN",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x17D5,
+ },
+ [0x17D6]={
+ category="po",
+ description="KHMER SIGN CAMNUC PII KUUH",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x17D6,
+ },
+ [0x17D7]={
+ category="lm",
+ description="KHMER SIGN LEK TOO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17D7,
+ },
+ [0x17D8]={
+ category="po",
+ description="KHMER SIGN BEYYAL",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x17D8,
+ },
+ [0x17D9]={
+ category="po",
+ description="KHMER SIGN PHNAEK MUAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x17D9,
+ },
+ [0x17DA]={
+ category="po",
+ description="KHMER SIGN KOOMUUT",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x17DA,
+ },
+ [0x17DB]={
+ category="sc",
+ description="KHMER CURRENCY SYMBOL RIEL",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x17DB,
+ },
+ [0x17DC]={
+ category="lo",
+ description="KHMER SIGN AVAKRAHASANYA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x17DC,
+ },
+ [0x17DD]={
+ category="mn",
+ description="KHMER SIGN ATTHACAN",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x17DD,
+ },
+ [0x17E0]={
+ category="nd",
+ description="KHMER DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E0,
+ },
+ [0x17E1]={
+ category="nd",
+ description="KHMER DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E1,
+ },
+ [0x17E2]={
+ category="nd",
+ description="KHMER DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E2,
+ },
+ [0x17E3]={
+ category="nd",
+ description="KHMER DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E3,
+ },
+ [0x17E4]={
+ category="nd",
+ description="KHMER DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E4,
+ },
+ [0x17E5]={
+ category="nd",
+ description="KHMER DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E5,
+ },
+ [0x17E6]={
+ category="nd",
+ description="KHMER DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E6,
+ },
+ [0x17E7]={
+ category="nd",
+ description="KHMER DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E7,
+ },
+ [0x17E8]={
+ category="nd",
+ description="KHMER DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E8,
+ },
+ [0x17E9]={
+ category="nd",
+ description="KHMER DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x17E9,
+ },
+ [0x17F0]={
+ category="no",
+ description="KHMER SYMBOL LEK ATTAK SON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F0,
+ },
+ [0x17F1]={
+ category="no",
+ description="KHMER SYMBOL LEK ATTAK MUOY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F1,
+ },
+ [0x17F2]={
+ category="no",
+ description="KHMER SYMBOL LEK ATTAK PII",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F2,
+ },
+ [0x17F3]={
+ category="no",
+ description="KHMER SYMBOL LEK ATTAK BEI",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F3,
+ },
+ [0x17F4]={
+ category="no",
+ description="KHMER SYMBOL LEK ATTAK BUON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F4,
+ },
+ [0x17F5]={
+ category="no",
+ description="KHMER SYMBOL LEK ATTAK PRAM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F5,
+ },
+ [0x17F6]={
+ category="no",
+ description="KHMER SYMBOL LEK ATTAK PRAM-MUOY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F6,
+ },
+ [0x17F7]={
+ category="no",
+ description="KHMER SYMBOL LEK ATTAK PRAM-PII",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F7,
+ },
+ [0x17F8]={
+ category="no",
+ description="KHMER SYMBOL LEK ATTAK PRAM-BEI",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F8,
+ },
+ [0x17F9]={
+ category="no",
+ description="KHMER SYMBOL LEK ATTAK PRAM-BUON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x17F9,
+ },
+ [0x1800]={
+ category="po",
+ description="MONGOLIAN BIRGA",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1800,
+ },
+ [0x1801]={
+ category="po",
+ description="MONGOLIAN ELLIPSIS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1801,
+ },
+ [0x1802]={
+ category="po",
+ description="MONGOLIAN COMMA",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x1802,
+ },
+ [0x1803]={
+ category="po",
+ description="MONGOLIAN FULL STOP",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x1803,
+ },
+ [0x1804]={
+ category="po",
+ description="MONGOLIAN COLON",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x1804,
+ },
+ [0x1805]={
+ category="po",
+ description="MONGOLIAN FOUR DOTS",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x1805,
+ },
+ [0x1806]={
+ category="pd",
+ description="MONGOLIAN TODO SOFT HYPHEN",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0x1806,
+ },
+ [0x1807]={
+ category="po",
+ description="MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1807,
+ },
+ [0x1808]={
+ category="po",
+ description="MONGOLIAN MANCHU COMMA",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x1808,
+ },
+ [0x1809]={
+ category="po",
+ description="MONGOLIAN MANCHU FULL STOP",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x1809,
+ },
+ [0x180A]={
+ category="po",
+ description="MONGOLIAN NIRUGU",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x180A,
+ },
+ [0x180B]={
+ category="mn",
+ description="MONGOLIAN FREE VARIATION SELECTOR ONE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x180B,
+ },
+ [0x180C]={
+ category="mn",
+ description="MONGOLIAN FREE VARIATION SELECTOR TWO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x180C,
+ },
+ [0x180D]={
+ category="mn",
+ description="MONGOLIAN FREE VARIATION SELECTOR THREE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x180D,
+ },
+ [0x180E]={
+ category="zs",
+ description="MONGOLIAN VOWEL SEPARATOR",
+ direction="ws",
+ linebreak="gl",
+ unicodeslot=0x180E,
+ },
+ [0x1810]={
+ category="nd",
+ description="MONGOLIAN DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1810,
+ },
+ [0x1811]={
+ category="nd",
+ description="MONGOLIAN DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1811,
+ },
+ [0x1812]={
+ category="nd",
+ description="MONGOLIAN DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1812,
+ },
+ [0x1813]={
+ category="nd",
+ description="MONGOLIAN DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1813,
+ },
+ [0x1814]={
+ category="nd",
+ description="MONGOLIAN DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1814,
+ },
+ [0x1815]={
+ category="nd",
+ description="MONGOLIAN DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1815,
+ },
+ [0x1816]={
+ category="nd",
+ description="MONGOLIAN DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1816,
+ },
+ [0x1817]={
+ category="nd",
+ description="MONGOLIAN DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1817,
+ },
+ [0x1818]={
+ category="nd",
+ description="MONGOLIAN DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1818,
+ },
+ [0x1819]={
+ category="nd",
+ description="MONGOLIAN DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1819,
+ },
+ [0x1820]={
+ category="lo",
+ description="MONGOLIAN LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1820,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ },
+ },
+ [0x1821]={
+ category="lo",
+ description="MONGOLIAN LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1821,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1822]={
+ category="lo",
+ description="MONGOLIAN LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1822,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1823]={
+ category="lo",
+ description="MONGOLIAN LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1823,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1824]={
+ category="lo",
+ description="MONGOLIAN LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1824,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1825]={
+ category="lo",
+ description="MONGOLIAN LETTER OE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1825,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ },
+ },
+ [0x1826]={
+ category="lo",
+ description="MONGOLIAN LETTER UE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1826,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ },
+ },
+ [0x1827]={
+ category="lo",
+ description="MONGOLIAN LETTER EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1827,
+ },
+ [0x1828]={
+ category="lo",
+ description="MONGOLIAN LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1828,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ [0x180D]="separate form",
+ },
+ },
+ [0x1829]={
+ category="lo",
+ description="MONGOLIAN LETTER ANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1829,
+ },
+ [0x182A]={
+ category="lo",
+ description="MONGOLIAN LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182A,
+ variants={
+ [0x180B]="alternative form",
+ },
+ },
+ [0x182B]={
+ category="lo",
+ description="MONGOLIAN LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182B,
+ },
+ [0x182C]={
+ category="lo",
+ description="MONGOLIAN LETTER QA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182C,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ [0x180D]="fourth form",
+ },
+ },
+ [0x182D]={
+ category="lo",
+ description="MONGOLIAN LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182D,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ [0x180D]="feminine form",
+ },
+ },
+ [0x182E]={
+ category="lo",
+ description="MONGOLIAN LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182E,
+ },
+ [0x182F]={
+ category="lo",
+ description="MONGOLIAN LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x182F,
+ },
+ [0x1830]={
+ category="lo",
+ description="MONGOLIAN LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1830,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ },
+ },
+ [0x1831]={
+ category="lo",
+ description="MONGOLIAN LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1831,
+ },
+ [0x1832]={
+ category="lo",
+ description="MONGOLIAN LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1832,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1833]={
+ category="lo",
+ description="MONGOLIAN LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1833,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1834]={
+ category="lo",
+ description="MONGOLIAN LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1834,
+ },
+ [0x1835]={
+ category="lo",
+ description="MONGOLIAN LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1835,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1836]={
+ category="lo",
+ description="MONGOLIAN LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1836,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ },
+ },
+ [0x1837]={
+ category="lo",
+ description="MONGOLIAN LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1837,
+ },
+ [0x1838]={
+ category="lo",
+ description="MONGOLIAN LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1838,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1839]={
+ category="lo",
+ description="MONGOLIAN LETTER FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1839,
+ },
+ [0x183A]={
+ category="lo",
+ description="MONGOLIAN LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183A,
+ },
+ [0x183B]={
+ category="lo",
+ description="MONGOLIAN LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183B,
+ },
+ [0x183C]={
+ category="lo",
+ description="MONGOLIAN LETTER TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183C,
+ },
+ [0x183D]={
+ category="lo",
+ description="MONGOLIAN LETTER ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183D,
+ },
+ [0x183E]={
+ category="lo",
+ description="MONGOLIAN LETTER HAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183E,
+ },
+ [0x183F]={
+ category="lo",
+ description="MONGOLIAN LETTER ZRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x183F,
+ },
+ [0x1840]={
+ category="lo",
+ description="MONGOLIAN LETTER LHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1840,
+ },
+ [0x1841]={
+ category="lo",
+ description="MONGOLIAN LETTER ZHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1841,
+ },
+ [0x1842]={
+ category="lo",
+ description="MONGOLIAN LETTER CHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1842,
+ },
+ [0x1843]={
+ category="lm",
+ description="MONGOLIAN LETTER TODO LONG VOWEL SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1843,
+ },
+ [0x1844]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1844,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1845]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1845,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1846]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1846,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1847]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1847,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ },
+ },
+ [0x1848]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO OE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1848,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1849]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO UE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1849,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x184A]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO ANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184A,
+ },
+ [0x184B]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184B,
+ },
+ [0x184C]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184C,
+ },
+ [0x184D]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO QA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184D,
+ variants={
+ [0x180B]="feminine form",
+ },
+ },
+ [0x184E]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184E,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x184F]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x184F,
+ },
+ [0x1850]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1850,
+ },
+ [0x1851]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1851,
+ },
+ [0x1852]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1852,
+ },
+ [0x1853]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1853,
+ },
+ [0x1854]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1854,
+ },
+ [0x1855]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1855,
+ },
+ [0x1856]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1856,
+ },
+ [0x1857]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1857,
+ },
+ [0x1858]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO GAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1858,
+ },
+ [0x1859]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO HAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1859,
+ },
+ [0x185A]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO JIA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185A,
+ },
+ [0x185B]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO NIA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185B,
+ },
+ [0x185C]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO DZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185C,
+ },
+ [0x185D]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185D,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x185E]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185E,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ },
+ },
+ [0x185F]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE IY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x185F,
+ },
+ [0x1860]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE UE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1860,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1861]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1861,
+ },
+ [0x1862]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE ANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1862,
+ },
+ [0x1863]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1863,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1864]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1864,
+ },
+ [0x1865]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1865,
+ },
+ [0x1866]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1866,
+ },
+ [0x1867]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1867,
+ },
+ [0x1868]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1868,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ },
+ },
+ [0x1869]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1869,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x186A]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186A,
+ },
+ [0x186B]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186B,
+ },
+ [0x186C]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE GAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186C,
+ },
+ [0x186D]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE HAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186D,
+ },
+ [0x186E]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186E,
+ },
+ [0x186F]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x186F,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1870]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE RAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1870,
+ },
+ [0x1871]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1871,
+ },
+ [0x1872]={
+ category="lo",
+ description="MONGOLIAN LETTER SIBE ZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1872,
+ },
+ [0x1873]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1873,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ [0x180D]="fourth form",
+ },
+ },
+ [0x1874]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1874,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="feminine first medial form",
+ [0x180D]="feminine second medial form",
+ },
+ },
+ [0x1875]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1875,
+ },
+ [0x1876]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1876,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1877]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1877,
+ },
+ [0x1880]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI ANUSVARA ONE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1880,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1881]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI VISARGA ONE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1881,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1882]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI DAMARU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1882,
+ },
+ [0x1883]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI UBADAMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1883,
+ },
+ [0x1884]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI INVERTED UBADAMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1884,
+ },
+ [0x1885]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI BALUDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1885,
+ },
+ [0x1886]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI THREE BALUDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1886,
+ },
+ [0x1887]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1887,
+ variants={
+ [0x180B]="second form",
+ [0x180C]="third form",
+ [0x180D]="fourth form",
+ },
+ },
+ [0x1888]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1888,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x1889]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1889,
+ },
+ [0x188A]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188A,
+ variants={
+ [0x180B]="second form",
+ },
+ },
+ [0x188B]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188B,
+ },
+ [0x188C]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188C,
+ },
+ [0x188D]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188D,
+ },
+ [0x188E]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188E,
+ },
+ [0x188F]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x188F,
+ },
+ [0x1890]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1890,
+ },
+ [0x1891]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1891,
+ },
+ [0x1892]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1892,
+ },
+ [0x1893]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1893,
+ },
+ [0x1894]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1894,
+ },
+ [0x1895]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI ZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1895,
+ },
+ [0x1896]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1896,
+ },
+ [0x1897]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI AH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1897,
+ },
+ [0x1898]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO ALI GALI TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1898,
+ },
+ [0x1899]={
+ category="lo",
+ description="MONGOLIAN LETTER TODO ALI GALI ZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1899,
+ },
+ [0x189A]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189A,
+ },
+ [0x189B]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189B,
+ },
+ [0x189C]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189C,
+ },
+ [0x189D]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189D,
+ },
+ [0x189E]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189E,
+ },
+ [0x189F]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x189F,
+ },
+ [0x18A0]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A0,
+ },
+ [0x18A1]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A1,
+ },
+ [0x18A2]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A2,
+ },
+ [0x18A3]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI CYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A3,
+ },
+ [0x18A4]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI ZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A4,
+ },
+ [0x18A5]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A5,
+ },
+ [0x18A6]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI HALF U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A6,
+ },
+ [0x18A7]={
+ category="lo",
+ description="MONGOLIAN LETTER ALI GALI HALF YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A7,
+ },
+ [0x18A8]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18A8,
+ },
+ [0x18A9]={
+ category="mn",
+ description="MONGOLIAN LETTER ALI GALI DAGALGA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x18A9,
+ },
+ [0x18AA]={
+ category="lo",
+ description="MONGOLIAN LETTER MANCHU ALI GALI LHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18AA,
+ },
+ [0x18B0]={
+ category="lo",
+ description="CANADIAN SYLLABICS OY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B0,
+ },
+ [0x18B1]={
+ category="lo",
+ description="CANADIAN SYLLABICS AY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B1,
+ },
+ [0x18B2]={
+ category="lo",
+ description="CANADIAN SYLLABICS AAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B2,
+ },
+ [0x18B3]={
+ category="lo",
+ description="CANADIAN SYLLABICS WAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B3,
+ },
+ [0x18B4]={
+ category="lo",
+ description="CANADIAN SYLLABICS POY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B4,
+ },
+ [0x18B5]={
+ category="lo",
+ description="CANADIAN SYLLABICS PAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B5,
+ },
+ [0x18B6]={
+ category="lo",
+ description="CANADIAN SYLLABICS PWOY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B6,
+ },
+ [0x18B7]={
+ category="lo",
+ description="CANADIAN SYLLABICS TAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B7,
+ },
+ [0x18B8]={
+ category="lo",
+ description="CANADIAN SYLLABICS KAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B8,
+ },
+ [0x18B9]={
+ category="lo",
+ description="CANADIAN SYLLABICS KWAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B9,
+ },
+ [0x18BA]={
+ category="lo",
+ description="CANADIAN SYLLABICS MAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BA,
+ },
+ [0x18BB]={
+ category="lo",
+ description="CANADIAN SYLLABICS NOY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BB,
+ },
+ [0x18BC]={
+ category="lo",
+ description="CANADIAN SYLLABICS NAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BC,
+ },
+ [0x18BD]={
+ category="lo",
+ description="CANADIAN SYLLABICS LAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BD,
+ },
+ [0x18BE]={
+ category="lo",
+ description="CANADIAN SYLLABICS SOY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BE,
+ },
+ [0x18BF]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BF,
+ },
+ [0x18C0]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHOY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C0,
+ },
+ [0x18C1]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C1,
+ },
+ [0x18C2]={
+ category="lo",
+ description="CANADIAN SYLLABICS SHWOY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C2,
+ },
+ [0x18C3]={
+ category="lo",
+ description="CANADIAN SYLLABICS YOY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C3,
+ },
+ [0x18C4]={
+ category="lo",
+ description="CANADIAN SYLLABICS YAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C4,
+ },
+ [0x18C5]={
+ category="lo",
+ description="CANADIAN SYLLABICS RAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C5,
+ },
+ [0x18C6]={
+ category="lo",
+ description="CANADIAN SYLLABICS NWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C6,
+ },
+ [0x18C7]={
+ category="lo",
+ description="CANADIAN SYLLABICS OJIBWAY NWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C7,
+ },
+ [0x18C8]={
+ category="lo",
+ description="CANADIAN SYLLABICS NWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C8,
+ },
+ [0x18C9]={
+ category="lo",
+ description="CANADIAN SYLLABICS OJIBWAY NWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C9,
+ },
+ [0x18CA]={
+ category="lo",
+ description="CANADIAN SYLLABICS NWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CA,
+ },
+ [0x18CB]={
+ category="lo",
+ description="CANADIAN SYLLABICS OJIBWAY NWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CB,
+ },
+ [0x18CC]={
+ category="lo",
+ description="CANADIAN SYLLABICS NWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CC,
+ },
+ [0x18CD]={
+ category="lo",
+ description="CANADIAN SYLLABICS OJIBWAY NWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CD,
+ },
+ [0x18CE]={
+ category="lo",
+ description="CANADIAN SYLLABICS RWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CE,
+ },
+ [0x18CF]={
+ category="lo",
+ description="CANADIAN SYLLABICS RWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CF,
+ },
+ [0x18D0]={
+ category="lo",
+ description="CANADIAN SYLLABICS RWII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D0,
+ },
+ [0x18D1]={
+ category="lo",
+ description="CANADIAN SYLLABICS RWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D1,
+ },
+ [0x18D2]={
+ category="lo",
+ description="CANADIAN SYLLABICS RWOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D2,
+ },
+ [0x18D3]={
+ category="lo",
+ description="CANADIAN SYLLABICS RWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D3,
+ },
+ [0x18D4]={
+ category="lo",
+ description="CANADIAN SYLLABICS OJIBWAY P",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D4,
+ },
+ [0x18D5]={
+ category="lo",
+ description="CANADIAN SYLLABICS OJIBWAY T",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D5,
+ },
+ [0x18D6]={
+ category="lo",
+ description="CANADIAN SYLLABICS OJIBWAY K",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D6,
+ },
+ [0x18D7]={
+ category="lo",
+ description="CANADIAN SYLLABICS OJIBWAY C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D7,
+ },
+ [0x18D8]={
+ category="lo",
+ description="CANADIAN SYLLABICS OJIBWAY M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D8,
+ },
+ [0x18D9]={
+ category="lo",
+ description="CANADIAN SYLLABICS OJIBWAY N",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18D9,
+ },
+ [0x18DA]={
+ category="lo",
+ description="CANADIAN SYLLABICS OJIBWAY S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18DA,
+ },
+ [0x18DB]={
+ category="lo",
+ description="CANADIAN SYLLABICS OJIBWAY SH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18DB,
+ },
+ [0x18DC]={
+ category="lo",
+ description="CANADIAN SYLLABICS EASTERN W",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18DC,
+ },
+ [0x18DD]={
+ category="lo",
+ description="CANADIAN SYLLABICS WESTERN W",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18DD,
+ },
+ [0x18DE]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL SMALL RING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18DE,
+ },
+ [0x18DF]={
+ category="lo",
+ description="CANADIAN SYLLABICS FINAL RAISED DOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18DF,
+ },
+ [0x18E0]={
+ category="lo",
+ description="CANADIAN SYLLABICS R-CREE RWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E0,
+ },
+ [0x18E1]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE LOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E1,
+ },
+ [0x18E2]={
+ category="lo",
+ description="CANADIAN SYLLABICS WEST-CREE LAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E2,
+ },
+ [0x18E3]={
+ category="lo",
+ description="CANADIAN SYLLABICS THWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E3,
+ },
+ [0x18E4]={
+ category="lo",
+ description="CANADIAN SYLLABICS THWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E4,
+ },
+ [0x18E5]={
+ category="lo",
+ description="CANADIAN SYLLABICS TTHWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E5,
+ },
+ [0x18E6]={
+ category="lo",
+ description="CANADIAN SYLLABICS TTHOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E6,
+ },
+ [0x18E7]={
+ category="lo",
+ description="CANADIAN SYLLABICS TTHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E7,
+ },
+ [0x18E8]={
+ category="lo",
+ description="CANADIAN SYLLABICS TLHWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E8,
+ },
+ [0x18E9]={
+ category="lo",
+ description="CANADIAN SYLLABICS TLHOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18E9,
+ },
+ [0x18EA]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI SHWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18EA,
+ },
+ [0x18EB]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI SHOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18EB,
+ },
+ [0x18EC]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI HOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18EC,
+ },
+ [0x18ED]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GWU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18ED,
+ },
+ [0x18EE]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DENE GEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18EE,
+ },
+ [0x18EF]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18EF,
+ },
+ [0x18F0]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER GWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F0,
+ },
+ [0x18F1]={
+ category="lo",
+ description="CANADIAN SYLLABICS SAYISI JUU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F1,
+ },
+ [0x18F2]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER JWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F2,
+ },
+ [0x18F3]={
+ category="lo",
+ description="CANADIAN SYLLABICS BEAVER DENE L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F3,
+ },
+ [0x18F4]={
+ category="lo",
+ description="CANADIAN SYLLABICS BEAVER DENE R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F4,
+ },
+ [0x18F5]={
+ category="lo",
+ description="CANADIAN SYLLABICS CARRIER DENTAL S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18F5,
+ },
+ [0x1900]={
+ category="lo",
+ description="LIMBU VOWEL-CARRIER LETTER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1900,
+ },
+ [0x1901]={
+ category="lo",
+ description="LIMBU LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1901,
+ },
+ [0x1902]={
+ category="lo",
+ description="LIMBU LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1902,
+ },
+ [0x1903]={
+ category="lo",
+ description="LIMBU LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1903,
+ },
+ [0x1904]={
+ category="lo",
+ description="LIMBU LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1904,
+ },
+ [0x1905]={
+ category="lo",
+ description="LIMBU LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1905,
+ },
+ [0x1906]={
+ category="lo",
+ description="LIMBU LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1906,
+ },
+ [0x1907]={
+ category="lo",
+ description="LIMBU LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1907,
+ },
+ [0x1908]={
+ category="lo",
+ description="LIMBU LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1908,
+ },
+ [0x1909]={
+ category="lo",
+ description="LIMBU LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1909,
+ },
+ [0x190A]={
+ category="lo",
+ description="LIMBU LETTER YAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190A,
+ },
+ [0x190B]={
+ category="lo",
+ description="LIMBU LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190B,
+ },
+ [0x190C]={
+ category="lo",
+ description="LIMBU LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190C,
+ },
+ [0x190D]={
+ category="lo",
+ description="LIMBU LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190D,
+ },
+ [0x190E]={
+ category="lo",
+ description="LIMBU LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190E,
+ },
+ [0x190F]={
+ category="lo",
+ description="LIMBU LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x190F,
+ },
+ [0x1910]={
+ category="lo",
+ description="LIMBU LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1910,
+ },
+ [0x1911]={
+ category="lo",
+ description="LIMBU LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1911,
+ },
+ [0x1912]={
+ category="lo",
+ description="LIMBU LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1912,
+ },
+ [0x1913]={
+ category="lo",
+ description="LIMBU LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1913,
+ },
+ [0x1914]={
+ category="lo",
+ description="LIMBU LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1914,
+ },
+ [0x1915]={
+ category="lo",
+ description="LIMBU LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1915,
+ },
+ [0x1916]={
+ category="lo",
+ description="LIMBU LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1916,
+ },
+ [0x1917]={
+ category="lo",
+ description="LIMBU LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1917,
+ },
+ [0x1918]={
+ category="lo",
+ description="LIMBU LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1918,
+ },
+ [0x1919]={
+ category="lo",
+ description="LIMBU LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1919,
+ },
+ [0x191A]={
+ category="lo",
+ description="LIMBU LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x191A,
+ },
+ [0x191B]={
+ category="lo",
+ description="LIMBU LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x191B,
+ },
+ [0x191C]={
+ category="lo",
+ description="LIMBU LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x191C,
+ },
+ [0x1920]={
+ category="mn",
+ description="LIMBU VOWEL SIGN A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1920,
+ },
+ [0x1921]={
+ category="mn",
+ description="LIMBU VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1921,
+ },
+ [0x1922]={
+ category="mn",
+ description="LIMBU VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1922,
+ },
+ [0x1923]={
+ category="mc",
+ description="LIMBU VOWEL SIGN EE",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1923,
+ },
+ [0x1924]={
+ category="mc",
+ description="LIMBU VOWEL SIGN AI",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1924,
+ },
+ [0x1925]={
+ category="mc",
+ description="LIMBU VOWEL SIGN OO",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1925,
+ },
+ [0x1926]={
+ category="mc",
+ description="LIMBU VOWEL SIGN AU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1926,
+ },
+ [0x1927]={
+ category="mn",
+ description="LIMBU VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1927,
+ },
+ [0x1928]={
+ category="mn",
+ description="LIMBU VOWEL SIGN O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1928,
+ },
+ [0x1929]={
+ category="mc",
+ description="LIMBU SUBJOINED LETTER YA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1929,
+ },
+ [0x192A]={
+ category="mc",
+ description="LIMBU SUBJOINED LETTER RA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x192A,
+ },
+ [0x192B]={
+ category="mc",
+ description="LIMBU SUBJOINED LETTER WA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x192B,
+ },
+ [0x1930]={
+ category="mc",
+ description="LIMBU SMALL LETTER KA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1930,
+ },
+ [0x1931]={
+ category="mc",
+ description="LIMBU SMALL LETTER NGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1931,
+ },
+ [0x1932]={
+ category="mn",
+ description="LIMBU SMALL LETTER ANUSVARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1932,
+ },
+ [0x1933]={
+ category="mc",
+ description="LIMBU SMALL LETTER TA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1933,
+ },
+ [0x1934]={
+ category="mc",
+ description="LIMBU SMALL LETTER NA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1934,
+ },
+ [0x1935]={
+ category="mc",
+ description="LIMBU SMALL LETTER PA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1935,
+ },
+ [0x1936]={
+ category="mc",
+ description="LIMBU SMALL LETTER MA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1936,
+ },
+ [0x1937]={
+ category="mc",
+ description="LIMBU SMALL LETTER RA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1937,
+ },
+ [0x1938]={
+ category="mc",
+ description="LIMBU SMALL LETTER LA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1938,
+ },
+ [0x1939]={
+ category="mn",
+ description="LIMBU SIGN MUKPHRENG",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1939,
+ },
+ [0x193A]={
+ category="mn",
+ description="LIMBU SIGN KEMPHRENG",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x193A,
+ },
+ [0x193B]={
+ category="mn",
+ description="LIMBU SIGN SA-I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x193B,
+ },
+ [0x1940]={
+ category="so",
+ description="LIMBU SIGN LOO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1940,
+ },
+ [0x1944]={
+ category="po",
+ description="LIMBU EXCLAMATION MARK",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x1944,
+ },
+ [0x1945]={
+ category="po",
+ description="LIMBU QUESTION MARK",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x1945,
+ },
+ [0x1946]={
+ category="nd",
+ description="LIMBU DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1946,
+ },
+ [0x1947]={
+ category="nd",
+ description="LIMBU DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1947,
+ },
+ [0x1948]={
+ category="nd",
+ description="LIMBU DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1948,
+ },
+ [0x1949]={
+ category="nd",
+ description="LIMBU DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1949,
+ },
+ [0x194A]={
+ category="nd",
+ description="LIMBU DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x194A,
+ },
+ [0x194B]={
+ category="nd",
+ description="LIMBU DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x194B,
+ },
+ [0x194C]={
+ category="nd",
+ description="LIMBU DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x194C,
+ },
+ [0x194D]={
+ category="nd",
+ description="LIMBU DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x194D,
+ },
+ [0x194E]={
+ category="nd",
+ description="LIMBU DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x194E,
+ },
+ [0x194F]={
+ category="nd",
+ description="LIMBU DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x194F,
+ },
+ [0x1950]={
+ category="lo",
+ description="TAI LE LETTER KA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1950,
+ },
+ [0x1951]={
+ category="lo",
+ description="TAI LE LETTER XA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1951,
+ },
+ [0x1952]={
+ category="lo",
+ description="TAI LE LETTER NGA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1952,
+ },
+ [0x1953]={
+ category="lo",
+ description="TAI LE LETTER TSA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1953,
+ },
+ [0x1954]={
+ category="lo",
+ description="TAI LE LETTER SA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1954,
+ },
+ [0x1955]={
+ category="lo",
+ description="TAI LE LETTER YA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1955,
+ },
+ [0x1956]={
+ category="lo",
+ description="TAI LE LETTER TA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1956,
+ },
+ [0x1957]={
+ category="lo",
+ description="TAI LE LETTER THA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1957,
+ },
+ [0x1958]={
+ category="lo",
+ description="TAI LE LETTER LA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1958,
+ },
+ [0x1959]={
+ category="lo",
+ description="TAI LE LETTER PA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1959,
+ },
+ [0x195A]={
+ category="lo",
+ description="TAI LE LETTER PHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x195A,
+ },
+ [0x195B]={
+ category="lo",
+ description="TAI LE LETTER MA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x195B,
+ },
+ [0x195C]={
+ category="lo",
+ description="TAI LE LETTER FA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x195C,
+ },
+ [0x195D]={
+ category="lo",
+ description="TAI LE LETTER VA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x195D,
+ },
+ [0x195E]={
+ category="lo",
+ description="TAI LE LETTER HA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x195E,
+ },
+ [0x195F]={
+ category="lo",
+ description="TAI LE LETTER QA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x195F,
+ },
+ [0x1960]={
+ category="lo",
+ description="TAI LE LETTER KHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1960,
+ },
+ [0x1961]={
+ category="lo",
+ description="TAI LE LETTER TSHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1961,
+ },
+ [0x1962]={
+ category="lo",
+ description="TAI LE LETTER NA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1962,
+ },
+ [0x1963]={
+ category="lo",
+ description="TAI LE LETTER A",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1963,
+ },
+ [0x1964]={
+ category="lo",
+ description="TAI LE LETTER I",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1964,
+ },
+ [0x1965]={
+ category="lo",
+ description="TAI LE LETTER EE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1965,
+ },
+ [0x1966]={
+ category="lo",
+ description="TAI LE LETTER EH",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1966,
+ },
+ [0x1967]={
+ category="lo",
+ description="TAI LE LETTER U",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1967,
+ },
+ [0x1968]={
+ category="lo",
+ description="TAI LE LETTER OO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1968,
+ },
+ [0x1969]={
+ category="lo",
+ description="TAI LE LETTER O",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1969,
+ },
+ [0x196A]={
+ category="lo",
+ description="TAI LE LETTER UE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x196A,
+ },
+ [0x196B]={
+ category="lo",
+ description="TAI LE LETTER E",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x196B,
+ },
+ [0x196C]={
+ category="lo",
+ description="TAI LE LETTER AUE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x196C,
+ },
+ [0x196D]={
+ category="lo",
+ description="TAI LE LETTER AI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x196D,
+ },
+ [0x1970]={
+ category="lo",
+ description="TAI LE LETTER TONE-0x0002",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1970,
+ },
+ [0x1971]={
+ category="lo",
+ description="TAI LE LETTER TONE-0x0003",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1971,
+ },
+ [0x1972]={
+ category="lo",
+ description="TAI LE LETTER TONE-0x0004",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1972,
+ },
+ [0x1973]={
+ category="lo",
+ description="TAI LE LETTER TONE-0x0005",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1973,
+ },
+ [0x1974]={
+ category="lo",
+ description="TAI LE LETTER TONE-0x0006",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1974,
+ },
+ [0x1980]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH QA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1980,
+ },
+ [0x1981]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW QA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1981,
+ },
+ [0x1982]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH KA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1982,
+ },
+ [0x1983]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH XA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1983,
+ },
+ [0x1984]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH NGA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1984,
+ },
+ [0x1985]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW KA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1985,
+ },
+ [0x1986]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW XA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1986,
+ },
+ [0x1987]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW NGA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1987,
+ },
+ [0x1988]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH TSA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1988,
+ },
+ [0x1989]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH SA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1989,
+ },
+ [0x198A]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH YA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x198A,
+ },
+ [0x198B]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW TSA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x198B,
+ },
+ [0x198C]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW SA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x198C,
+ },
+ [0x198D]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW YA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x198D,
+ },
+ [0x198E]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH TA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x198E,
+ },
+ [0x198F]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH THA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x198F,
+ },
+ [0x1990]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH NA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1990,
+ },
+ [0x1991]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW TA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1991,
+ },
+ [0x1992]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW THA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1992,
+ },
+ [0x1993]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW NA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1993,
+ },
+ [0x1994]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH PA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1994,
+ },
+ [0x1995]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH PHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1995,
+ },
+ [0x1996]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH MA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1996,
+ },
+ [0x1997]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW PA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1997,
+ },
+ [0x1998]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW PHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1998,
+ },
+ [0x1999]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW MA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1999,
+ },
+ [0x199A]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH FA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x199A,
+ },
+ [0x199B]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH VA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x199B,
+ },
+ [0x199C]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH LA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x199C,
+ },
+ [0x199D]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW FA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x199D,
+ },
+ [0x199E]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW VA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x199E,
+ },
+ [0x199F]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW LA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x199F,
+ },
+ [0x19A0]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH HA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A0,
+ },
+ [0x19A1]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH DA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A1,
+ },
+ [0x19A2]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH BA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A2,
+ },
+ [0x19A3]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW HA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A3,
+ },
+ [0x19A4]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW DA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A4,
+ },
+ [0x19A5]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW BA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A5,
+ },
+ [0x19A6]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH KVA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A6,
+ },
+ [0x19A7]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH XVA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A7,
+ },
+ [0x19A8]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW KVA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A8,
+ },
+ [0x19A9]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW XVA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19A9,
+ },
+ [0x19AA]={
+ category="lo",
+ description="NEW TAI LUE LETTER HIGH SUA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19AA,
+ },
+ [0x19AB]={
+ category="lo",
+ description="NEW TAI LUE LETTER LOW SUA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19AB,
+ },
+ [0x19B0]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN VOWEL SHORTENER",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B0,
+ },
+ [0x19B1]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN AA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B1,
+ },
+ [0x19B2]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN II",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B2,
+ },
+ [0x19B3]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN U",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B3,
+ },
+ [0x19B4]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN UU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B4,
+ },
+ [0x19B5]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN E",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B5,
+ },
+ [0x19B6]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN AE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B6,
+ },
+ [0x19B7]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN O",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B7,
+ },
+ [0x19B8]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN OA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B8,
+ },
+ [0x19B9]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN UE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19B9,
+ },
+ [0x19BA]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN AY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19BA,
+ },
+ [0x19BB]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN AAY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19BB,
+ },
+ [0x19BC]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN UY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19BC,
+ },
+ [0x19BD]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN OY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19BD,
+ },
+ [0x19BE]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN OAY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19BE,
+ },
+ [0x19BF]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN UEY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19BF,
+ },
+ [0x19C0]={
+ category="mc",
+ description="NEW TAI LUE VOWEL SIGN IY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C0,
+ },
+ [0x19C1]={
+ category="lo",
+ description="NEW TAI LUE LETTER FINAL V",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C1,
+ },
+ [0x19C2]={
+ category="lo",
+ description="NEW TAI LUE LETTER FINAL NG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C2,
+ },
+ [0x19C3]={
+ category="lo",
+ description="NEW TAI LUE LETTER FINAL N",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C3,
+ },
+ [0x19C4]={
+ category="lo",
+ description="NEW TAI LUE LETTER FINAL M",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C4,
+ },
+ [0x19C5]={
+ category="lo",
+ description="NEW TAI LUE LETTER FINAL K",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C5,
+ },
+ [0x19C6]={
+ category="lo",
+ description="NEW TAI LUE LETTER FINAL D",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C6,
+ },
+ [0x19C7]={
+ category="lo",
+ description="NEW TAI LUE LETTER FINAL B",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C7,
+ },
+ [0x19C8]={
+ category="mc",
+ description="NEW TAI LUE TONE MARK-0x0001",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C8,
+ },
+ [0x19C9]={
+ category="mc",
+ description="NEW TAI LUE TONE MARK-0x0002",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19C9,
+ },
+ [0x19D0]={
+ category="nd",
+ description="NEW TAI LUE DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D0,
+ },
+ [0x19D1]={
+ category="nd",
+ description="NEW TAI LUE DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D1,
+ },
+ [0x19D2]={
+ category="nd",
+ description="NEW TAI LUE DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D2,
+ },
+ [0x19D3]={
+ category="nd",
+ description="NEW TAI LUE DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D3,
+ },
+ [0x19D4]={
+ category="nd",
+ description="NEW TAI LUE DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D4,
+ },
+ [0x19D5]={
+ category="nd",
+ description="NEW TAI LUE DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D5,
+ },
+ [0x19D6]={
+ category="nd",
+ description="NEW TAI LUE DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D6,
+ },
+ [0x19D7]={
+ category="nd",
+ description="NEW TAI LUE DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D7,
+ },
+ [0x19D8]={
+ category="nd",
+ description="NEW TAI LUE DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D8,
+ },
+ [0x19D9]={
+ category="nd",
+ description="NEW TAI LUE DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x19D9,
+ },
+ [0x19DA]={
+ category="no",
+ description="NEW TAI LUE THAM DIGIT ONE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x19DA,
+ },
+ [0x19DE]={
+ category="po",
+ description="NEW TAI LUE SIGN LAE",
+ direction="on",
+ linebreak="sa",
+ unicodeslot=0x19DE,
+ },
+ [0x19DF]={
+ category="po",
+ description="NEW TAI LUE SIGN LAEV",
+ direction="on",
+ linebreak="sa",
+ unicodeslot=0x19DF,
+ },
+ [0x19E0]={
+ category="so",
+ description="KHMER SYMBOL PATHAMASAT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E0,
+ },
+ [0x19E1]={
+ category="so",
+ description="KHMER SYMBOL MUOY KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E1,
+ },
+ [0x19E2]={
+ category="so",
+ description="KHMER SYMBOL PII KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E2,
+ },
+ [0x19E3]={
+ category="so",
+ description="KHMER SYMBOL BEI KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E3,
+ },
+ [0x19E4]={
+ category="so",
+ description="KHMER SYMBOL BUON KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E4,
+ },
+ [0x19E5]={
+ category="so",
+ description="KHMER SYMBOL PRAM KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E5,
+ },
+ [0x19E6]={
+ category="so",
+ description="KHMER SYMBOL PRAM-MUOY KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E6,
+ },
+ [0x19E7]={
+ category="so",
+ description="KHMER SYMBOL PRAM-PII KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E7,
+ },
+ [0x19E8]={
+ category="so",
+ description="KHMER SYMBOL PRAM-BEI KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E8,
+ },
+ [0x19E9]={
+ category="so",
+ description="KHMER SYMBOL PRAM-BUON KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19E9,
+ },
+ [0x19EA]={
+ category="so",
+ description="KHMER SYMBOL DAP KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19EA,
+ },
+ [0x19EB]={
+ category="so",
+ description="KHMER SYMBOL DAP-MUOY KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19EB,
+ },
+ [0x19EC]={
+ category="so",
+ description="KHMER SYMBOL DAP-PII KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19EC,
+ },
+ [0x19ED]={
+ category="so",
+ description="KHMER SYMBOL DAP-BEI KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19ED,
+ },
+ [0x19EE]={
+ category="so",
+ description="KHMER SYMBOL DAP-BUON KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19EE,
+ },
+ [0x19EF]={
+ category="so",
+ description="KHMER SYMBOL DAP-PRAM KOET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19EF,
+ },
+ [0x19F0]={
+ category="so",
+ description="KHMER SYMBOL TUTEYASAT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F0,
+ },
+ [0x19F1]={
+ category="so",
+ description="KHMER SYMBOL MUOY ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F1,
+ },
+ [0x19F2]={
+ category="so",
+ description="KHMER SYMBOL PII ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F2,
+ },
+ [0x19F3]={
+ category="so",
+ description="KHMER SYMBOL BEI ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F3,
+ },
+ [0x19F4]={
+ category="so",
+ description="KHMER SYMBOL BUON ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F4,
+ },
+ [0x19F5]={
+ category="so",
+ description="KHMER SYMBOL PRAM ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F5,
+ },
+ [0x19F6]={
+ category="so",
+ description="KHMER SYMBOL PRAM-MUOY ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F6,
+ },
+ [0x19F7]={
+ category="so",
+ description="KHMER SYMBOL PRAM-PII ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F7,
+ },
+ [0x19F8]={
+ category="so",
+ description="KHMER SYMBOL PRAM-BEI ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F8,
+ },
+ [0x19F9]={
+ category="so",
+ description="KHMER SYMBOL PRAM-BUON ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19F9,
+ },
+ [0x19FA]={
+ category="so",
+ description="KHMER SYMBOL DAP ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19FA,
+ },
+ [0x19FB]={
+ category="so",
+ description="KHMER SYMBOL DAP-MUOY ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19FB,
+ },
+ [0x19FC]={
+ category="so",
+ description="KHMER SYMBOL DAP-PII ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19FC,
+ },
+ [0x19FD]={
+ category="so",
+ description="KHMER SYMBOL DAP-BEI ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19FD,
+ },
+ [0x19FE]={
+ category="so",
+ description="KHMER SYMBOL DAP-BUON ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19FE,
+ },
+ [0x19FF]={
+ category="so",
+ description="KHMER SYMBOL DAP-PRAM ROC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x19FF,
+ },
+ [0x1A00]={
+ category="lo",
+ description="BUGINESE LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A00,
+ },
+ [0x1A01]={
+ category="lo",
+ description="BUGINESE LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A01,
+ },
+ [0x1A02]={
+ category="lo",
+ description="BUGINESE LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A02,
+ },
+ [0x1A03]={
+ category="lo",
+ description="BUGINESE LETTER NGKA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A03,
+ },
+ [0x1A04]={
+ category="lo",
+ description="BUGINESE LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A04,
+ },
+ [0x1A05]={
+ category="lo",
+ description="BUGINESE LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A05,
+ },
+ [0x1A06]={
+ category="lo",
+ description="BUGINESE LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A06,
+ },
+ [0x1A07]={
+ category="lo",
+ description="BUGINESE LETTER MPA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A07,
+ },
+ [0x1A08]={
+ category="lo",
+ description="BUGINESE LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A08,
+ },
+ [0x1A09]={
+ category="lo",
+ description="BUGINESE LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A09,
+ },
+ [0x1A0A]={
+ category="lo",
+ description="BUGINESE LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A0A,
+ },
+ [0x1A0B]={
+ category="lo",
+ description="BUGINESE LETTER NRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A0B,
+ },
+ [0x1A0C]={
+ category="lo",
+ description="BUGINESE LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A0C,
+ },
+ [0x1A0D]={
+ category="lo",
+ description="BUGINESE LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A0D,
+ },
+ [0x1A0E]={
+ category="lo",
+ description="BUGINESE LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A0E,
+ },
+ [0x1A0F]={
+ category="lo",
+ description="BUGINESE LETTER NYCA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A0F,
+ },
+ [0x1A10]={
+ category="lo",
+ description="BUGINESE LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A10,
+ },
+ [0x1A11]={
+ category="lo",
+ description="BUGINESE LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A11,
+ },
+ [0x1A12]={
+ category="lo",
+ description="BUGINESE LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A12,
+ },
+ [0x1A13]={
+ category="lo",
+ description="BUGINESE LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A13,
+ },
+ [0x1A14]={
+ category="lo",
+ description="BUGINESE LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A14,
+ },
+ [0x1A15]={
+ category="lo",
+ description="BUGINESE LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A15,
+ },
+ [0x1A16]={
+ category="lo",
+ description="BUGINESE LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A16,
+ },
+ [0x1A17]={
+ category="mn",
+ description="BUGINESE VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1A17,
+ },
+ [0x1A18]={
+ category="mn",
+ description="BUGINESE VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1A18,
+ },
+ [0x1A19]={
+ category="mc",
+ description="BUGINESE VOWEL SIGN E",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1A19,
+ },
+ [0x1A1A]={
+ category="mc",
+ description="BUGINESE VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1A1A,
+ },
+ [0x1A1B]={
+ category="mc",
+ description="BUGINESE VOWEL SIGN AE",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1A1B,
+ },
+ [0x1A1E]={
+ category="po",
+ description="BUGINESE PALLAWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A1E,
+ },
+ [0x1A1F]={
+ category="po",
+ description="BUGINESE END OF SECTION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1A1F,
+ },
+ [0x1A20]={
+ category="lo",
+ description="TAI THAM LETTER HIGH KA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A20,
+ },
+ [0x1A21]={
+ category="lo",
+ description="TAI THAM LETTER HIGH KHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A21,
+ },
+ [0x1A22]={
+ category="lo",
+ description="TAI THAM LETTER HIGH KXA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A22,
+ },
+ [0x1A23]={
+ category="lo",
+ description="TAI THAM LETTER LOW KA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A23,
+ },
+ [0x1A24]={
+ category="lo",
+ description="TAI THAM LETTER LOW KXA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A24,
+ },
+ [0x1A25]={
+ category="lo",
+ description="TAI THAM LETTER LOW KHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A25,
+ },
+ [0x1A26]={
+ category="lo",
+ description="TAI THAM LETTER NGA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A26,
+ },
+ [0x1A27]={
+ category="lo",
+ description="TAI THAM LETTER HIGH CA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A27,
+ },
+ [0x1A28]={
+ category="lo",
+ description="TAI THAM LETTER HIGH CHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A28,
+ },
+ [0x1A29]={
+ category="lo",
+ description="TAI THAM LETTER LOW CA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A29,
+ },
+ [0x1A2A]={
+ category="lo",
+ description="TAI THAM LETTER LOW SA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A2A,
+ },
+ [0x1A2B]={
+ category="lo",
+ description="TAI THAM LETTER LOW CHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A2B,
+ },
+ [0x1A2C]={
+ category="lo",
+ description="TAI THAM LETTER NYA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A2C,
+ },
+ [0x1A2D]={
+ category="lo",
+ description="TAI THAM LETTER RATA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A2D,
+ },
+ [0x1A2E]={
+ category="lo",
+ description="TAI THAM LETTER HIGH RATHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A2E,
+ },
+ [0x1A2F]={
+ category="lo",
+ description="TAI THAM LETTER DA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A2F,
+ },
+ [0x1A30]={
+ category="lo",
+ description="TAI THAM LETTER LOW RATHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A30,
+ },
+ [0x1A31]={
+ category="lo",
+ description="TAI THAM LETTER RANA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A31,
+ },
+ [0x1A32]={
+ category="lo",
+ description="TAI THAM LETTER HIGH TA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A32,
+ },
+ [0x1A33]={
+ category="lo",
+ description="TAI THAM LETTER HIGH THA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A33,
+ },
+ [0x1A34]={
+ category="lo",
+ description="TAI THAM LETTER LOW TA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A34,
+ },
+ [0x1A35]={
+ category="lo",
+ description="TAI THAM LETTER LOW THA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A35,
+ },
+ [0x1A36]={
+ category="lo",
+ description="TAI THAM LETTER NA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A36,
+ },
+ [0x1A37]={
+ category="lo",
+ description="TAI THAM LETTER BA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A37,
+ },
+ [0x1A38]={
+ category="lo",
+ description="TAI THAM LETTER HIGH PA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A38,
+ },
+ [0x1A39]={
+ category="lo",
+ description="TAI THAM LETTER HIGH PHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A39,
+ },
+ [0x1A3A]={
+ category="lo",
+ description="TAI THAM LETTER HIGH FA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A3A,
+ },
+ [0x1A3B]={
+ category="lo",
+ description="TAI THAM LETTER LOW PA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A3B,
+ },
+ [0x1A3C]={
+ category="lo",
+ description="TAI THAM LETTER LOW FA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A3C,
+ },
+ [0x1A3D]={
+ category="lo",
+ description="TAI THAM LETTER LOW PHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A3D,
+ },
+ [0x1A3E]={
+ category="lo",
+ description="TAI THAM LETTER MA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A3E,
+ },
+ [0x1A3F]={
+ category="lo",
+ description="TAI THAM LETTER LOW YA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A3F,
+ },
+ [0x1A40]={
+ category="lo",
+ description="TAI THAM LETTER HIGH YA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A40,
+ },
+ [0x1A41]={
+ category="lo",
+ description="TAI THAM LETTER RA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A41,
+ },
+ [0x1A42]={
+ category="lo",
+ description="TAI THAM LETTER RUE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A42,
+ },
+ [0x1A43]={
+ category="lo",
+ description="TAI THAM LETTER LA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A43,
+ },
+ [0x1A44]={
+ category="lo",
+ description="TAI THAM LETTER LUE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A44,
+ },
+ [0x1A45]={
+ category="lo",
+ description="TAI THAM LETTER WA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A45,
+ },
+ [0x1A46]={
+ category="lo",
+ description="TAI THAM LETTER HIGH SHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A46,
+ },
+ [0x1A47]={
+ category="lo",
+ description="TAI THAM LETTER HIGH SSA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A47,
+ },
+ [0x1A48]={
+ category="lo",
+ description="TAI THAM LETTER HIGH SA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A48,
+ },
+ [0x1A49]={
+ category="lo",
+ description="TAI THAM LETTER HIGH HA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A49,
+ },
+ [0x1A4A]={
+ category="lo",
+ description="TAI THAM LETTER LLA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A4A,
+ },
+ [0x1A4B]={
+ category="lo",
+ description="TAI THAM LETTER A",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A4B,
+ },
+ [0x1A4C]={
+ category="lo",
+ description="TAI THAM LETTER LOW HA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A4C,
+ },
+ [0x1A4D]={
+ category="lo",
+ description="TAI THAM LETTER I",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A4D,
+ },
+ [0x1A4E]={
+ category="lo",
+ description="TAI THAM LETTER II",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A4E,
+ },
+ [0x1A4F]={
+ category="lo",
+ description="TAI THAM LETTER U",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A4F,
+ },
+ [0x1A50]={
+ category="lo",
+ description="TAI THAM LETTER UU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A50,
+ },
+ [0x1A51]={
+ category="lo",
+ description="TAI THAM LETTER EE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A51,
+ },
+ [0x1A52]={
+ category="lo",
+ description="TAI THAM LETTER OO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A52,
+ },
+ [0x1A53]={
+ category="lo",
+ description="TAI THAM LETTER LAE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A53,
+ },
+ [0x1A54]={
+ category="lo",
+ description="TAI THAM LETTER GREAT SA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A54,
+ },
+ [0x1A55]={
+ category="mc",
+ description="TAI THAM CONSONANT SIGN MEDIAL RA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A55,
+ },
+ [0x1A56]={
+ category="mn",
+ description="TAI THAM CONSONANT SIGN MEDIAL LA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A56,
+ },
+ [0x1A57]={
+ category="mc",
+ description="TAI THAM CONSONANT SIGN LA TANG LAI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A57,
+ },
+ [0x1A58]={
+ category="mn",
+ description="TAI THAM SIGN MAI KANG LAI",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A58,
+ },
+ [0x1A59]={
+ category="mn",
+ description="TAI THAM CONSONANT SIGN FINAL NGA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A59,
+ },
+ [0x1A5A]={
+ category="mn",
+ description="TAI THAM CONSONANT SIGN LOW PA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A5A,
+ },
+ [0x1A5B]={
+ category="mn",
+ description="TAI THAM CONSONANT SIGN HIGH RATHA OR LOW PA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A5B,
+ },
+ [0x1A5C]={
+ category="mn",
+ description="TAI THAM CONSONANT SIGN MA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A5C,
+ },
+ [0x1A5D]={
+ category="mn",
+ description="TAI THAM CONSONANT SIGN BA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A5D,
+ },
+ [0x1A5E]={
+ category="mn",
+ description="TAI THAM CONSONANT SIGN SA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A5E,
+ },
+ [0x1A60]={
+ category="mn",
+ description="TAI THAM SIGN SAKOT",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A60,
+ },
+ [0x1A61]={
+ category="mc",
+ description="TAI THAM VOWEL SIGN A",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A61,
+ },
+ [0x1A62]={
+ category="mn",
+ description="TAI THAM VOWEL SIGN MAI SAT",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A62,
+ },
+ [0x1A63]={
+ category="mc",
+ description="TAI THAM VOWEL SIGN AA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A63,
+ },
+ [0x1A64]={
+ category="mc",
+ description="TAI THAM VOWEL SIGN TALL AA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A64,
+ },
+ [0x1A65]={
+ category="mn",
+ description="TAI THAM VOWEL SIGN I",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A65,
+ },
+ [0x1A66]={
+ category="mn",
+ description="TAI THAM VOWEL SIGN II",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A66,
+ },
+ [0x1A67]={
+ category="mn",
+ description="TAI THAM VOWEL SIGN UE",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A67,
+ },
+ [0x1A68]={
+ category="mn",
+ description="TAI THAM VOWEL SIGN UUE",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A68,
+ },
+ [0x1A69]={
+ category="mn",
+ description="TAI THAM VOWEL SIGN U",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A69,
+ },
+ [0x1A6A]={
+ category="mn",
+ description="TAI THAM VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A6A,
+ },
+ [0x1A6B]={
+ category="mn",
+ description="TAI THAM VOWEL SIGN O",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A6B,
+ },
+ [0x1A6C]={
+ category="mn",
+ description="TAI THAM VOWEL SIGN OA BELOW",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A6C,
+ },
+ [0x1A6D]={
+ category="mc",
+ description="TAI THAM VOWEL SIGN OY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A6D,
+ },
+ [0x1A6E]={
+ category="mc",
+ description="TAI THAM VOWEL SIGN E",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A6E,
+ },
+ [0x1A6F]={
+ category="mc",
+ description="TAI THAM VOWEL SIGN AE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A6F,
+ },
+ [0x1A70]={
+ category="mc",
+ description="TAI THAM VOWEL SIGN OO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A70,
+ },
+ [0x1A71]={
+ category="mc",
+ description="TAI THAM VOWEL SIGN AI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A71,
+ },
+ [0x1A72]={
+ category="mc",
+ description="TAI THAM VOWEL SIGN THAM AI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1A72,
+ },
+ [0x1A73]={
+ category="mn",
+ description="TAI THAM VOWEL SIGN OA ABOVE",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A73,
+ },
+ [0x1A74]={
+ category="mn",
+ description="TAI THAM SIGN MAI KANG",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A74,
+ },
+ [0x1A75]={
+ category="mn",
+ description="TAI THAM SIGN TONE-1",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A75,
+ },
+ [0x1A76]={
+ category="mn",
+ description="TAI THAM SIGN TONE-2",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A76,
+ },
+ [0x1A77]={
+ category="mn",
+ description="TAI THAM SIGN KHUEN TONE-3",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A77,
+ },
+ [0x1A78]={
+ category="mn",
+ description="TAI THAM SIGN KHUEN TONE-4",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A78,
+ },
+ [0x1A79]={
+ category="mn",
+ description="TAI THAM SIGN KHUEN TONE-5",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A79,
+ },
+ [0x1A7A]={
+ category="mn",
+ description="TAI THAM SIGN RA HAAM",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A7A,
+ },
+ [0x1A7B]={
+ category="mn",
+ description="TAI THAM SIGN MAI SAM",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A7B,
+ },
+ [0x1A7C]={
+ category="mn",
+ description="TAI THAM SIGN KHUEN-LUE KARAN",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0x1A7C,
+ },
+ [0x1A7F]={
+ category="mn",
+ description="TAI THAM COMBINING CRYPTOGRAMMIC DOT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1A7F,
+ },
+ [0x1A80]={
+ category="nd",
+ description="TAI THAM HORA DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A80,
+ },
+ [0x1A81]={
+ category="nd",
+ description="TAI THAM HORA DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A81,
+ },
+ [0x1A82]={
+ category="nd",
+ description="TAI THAM HORA DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A82,
+ },
+ [0x1A83]={
+ category="nd",
+ description="TAI THAM HORA DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A83,
+ },
+ [0x1A84]={
+ category="nd",
+ description="TAI THAM HORA DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A84,
+ },
+ [0x1A85]={
+ category="nd",
+ description="TAI THAM HORA DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A85,
+ },
+ [0x1A86]={
+ category="nd",
+ description="TAI THAM HORA DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A86,
+ },
+ [0x1A87]={
+ category="nd",
+ description="TAI THAM HORA DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A87,
+ },
+ [0x1A88]={
+ category="nd",
+ description="TAI THAM HORA DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A88,
+ },
+ [0x1A89]={
+ category="nd",
+ description="TAI THAM HORA DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A89,
+ },
+ [0x1A90]={
+ category="nd",
+ description="TAI THAM THAM DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A90,
+ },
+ [0x1A91]={
+ category="nd",
+ description="TAI THAM THAM DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A91,
+ },
+ [0x1A92]={
+ category="nd",
+ description="TAI THAM THAM DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A92,
+ },
+ [0x1A93]={
+ category="nd",
+ description="TAI THAM THAM DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A93,
+ },
+ [0x1A94]={
+ category="nd",
+ description="TAI THAM THAM DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A94,
+ },
+ [0x1A95]={
+ category="nd",
+ description="TAI THAM THAM DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A95,
+ },
+ [0x1A96]={
+ category="nd",
+ description="TAI THAM THAM DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A96,
+ },
+ [0x1A97]={
+ category="nd",
+ description="TAI THAM THAM DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A97,
+ },
+ [0x1A98]={
+ category="nd",
+ description="TAI THAM THAM DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A98,
+ },
+ [0x1A99]={
+ category="nd",
+ description="TAI THAM THAM DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1A99,
+ },
+ [0x1AA0]={
+ category="po",
+ description="TAI THAM SIGN WIANG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA0,
+ },
+ [0x1AA1]={
+ category="po",
+ description="TAI THAM SIGN WIANGWAAK",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA1,
+ },
+ [0x1AA2]={
+ category="po",
+ description="TAI THAM SIGN SAWAN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA2,
+ },
+ [0x1AA3]={
+ category="po",
+ description="TAI THAM SIGN KEOW",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA3,
+ },
+ [0x1AA4]={
+ category="po",
+ description="TAI THAM SIGN HOY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA4,
+ },
+ [0x1AA5]={
+ category="po",
+ description="TAI THAM SIGN DOKMAI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA5,
+ },
+ [0x1AA6]={
+ category="po",
+ description="TAI THAM SIGN REVERSED ROTATED RANA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA6,
+ },
+ [0x1AA7]={
+ category="lm",
+ description="TAI THAM SIGN MAI YAMOK",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA7,
+ },
+ [0x1AA8]={
+ category="po",
+ description="TAI THAM SIGN KAAN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA8,
+ },
+ [0x1AA9]={
+ category="po",
+ description="TAI THAM SIGN KAANKUU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AA9,
+ },
+ [0x1AAA]={
+ category="po",
+ description="TAI THAM SIGN SATKAAN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AAA,
+ },
+ [0x1AAB]={
+ category="po",
+ description="TAI THAM SIGN SATKAANKUU",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AAB,
+ },
+ [0x1AAC]={
+ category="po",
+ description="TAI THAM SIGN HANG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AAC,
+ },
+ [0x1AAD]={
+ category="po",
+ description="TAI THAM SIGN CAANG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0x1AAD,
+ },
+ [0x1B00]={
+ category="mn",
+ description="BALINESE SIGN ULU RICEM",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B00,
+ },
+ [0x1B01]={
+ category="mn",
+ description="BALINESE SIGN ULU CANDRA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B01,
+ },
+ [0x1B02]={
+ category="mn",
+ description="BALINESE SIGN CECEK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B02,
+ },
+ [0x1B03]={
+ category="mn",
+ description="BALINESE SIGN SURANG",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B03,
+ },
+ [0x1B04]={
+ category="mc",
+ description="BALINESE SIGN BISAH",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1B04,
+ },
+ [0x1B05]={
+ category="lo",
+ description="BALINESE LETTER AKARA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B05,
+ },
+ [0x1B06]={
+ category="lo",
+ description="BALINESE LETTER AKARA TEDUNG",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B05, 0x1B35 },
+ unicodeslot=0x1B06,
+ },
+ [0x1B07]={
+ category="lo",
+ description="BALINESE LETTER IKARA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B07,
+ },
+ [0x1B08]={
+ category="lo",
+ description="BALINESE LETTER IKARA TEDUNG",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B07, 0x1B35 },
+ unicodeslot=0x1B08,
+ },
+ [0x1B09]={
+ category="lo",
+ description="BALINESE LETTER UKARA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B09,
+ },
+ [0x1B0A]={
+ category="lo",
+ description="BALINESE LETTER UKARA TEDUNG",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B09, 0x1B35 },
+ unicodeslot=0x1B0A,
+ },
+ [0x1B0B]={
+ category="lo",
+ description="BALINESE LETTER RA REPA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B0B,
+ },
+ [0x1B0C]={
+ category="lo",
+ description="BALINESE LETTER RA REPA TEDUNG",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B0B, 0x1B35 },
+ unicodeslot=0x1B0C,
+ },
+ [0x1B0D]={
+ category="lo",
+ description="BALINESE LETTER LA LENGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B0D,
+ },
+ [0x1B0E]={
+ category="lo",
+ description="BALINESE LETTER LA LENGA TEDUNG",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B0D, 0x1B35 },
+ unicodeslot=0x1B0E,
+ },
+ [0x1B0F]={
+ category="lo",
+ description="BALINESE LETTER EKARA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B0F,
+ },
+ [0x1B10]={
+ category="lo",
+ description="BALINESE LETTER AIKARA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B10,
+ },
+ [0x1B11]={
+ category="lo",
+ description="BALINESE LETTER OKARA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B11,
+ },
+ [0x1B12]={
+ category="lo",
+ description="BALINESE LETTER OKARA TEDUNG",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1B11, 0x1B35 },
+ unicodeslot=0x1B12,
+ },
+ [0x1B13]={
+ category="lo",
+ description="BALINESE LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B13,
+ },
+ [0x1B14]={
+ category="lo",
+ description="BALINESE LETTER KA MAHAPRANA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B14,
+ },
+ [0x1B15]={
+ category="lo",
+ description="BALINESE LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B15,
+ },
+ [0x1B16]={
+ category="lo",
+ description="BALINESE LETTER GA GORA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B16,
+ },
+ [0x1B17]={
+ category="lo",
+ description="BALINESE LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B17,
+ },
+ [0x1B18]={
+ category="lo",
+ description="BALINESE LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B18,
+ },
+ [0x1B19]={
+ category="lo",
+ description="BALINESE LETTER CA LACA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B19,
+ },
+ [0x1B1A]={
+ category="lo",
+ description="BALINESE LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1A,
+ },
+ [0x1B1B]={
+ category="lo",
+ description="BALINESE LETTER JA JERA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1B,
+ },
+ [0x1B1C]={
+ category="lo",
+ description="BALINESE LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1C,
+ },
+ [0x1B1D]={
+ category="lo",
+ description="BALINESE LETTER TA LATIK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1D,
+ },
+ [0x1B1E]={
+ category="lo",
+ description="BALINESE LETTER TA MURDA MAHAPRANA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1E,
+ },
+ [0x1B1F]={
+ category="lo",
+ description="BALINESE LETTER DA MURDA ALPAPRANA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B1F,
+ },
+ [0x1B20]={
+ category="lo",
+ description="BALINESE LETTER DA MURDA MAHAPRANA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B20,
+ },
+ [0x1B21]={
+ category="lo",
+ description="BALINESE LETTER NA RAMBAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B21,
+ },
+ [0x1B22]={
+ category="lo",
+ description="BALINESE LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B22,
+ },
+ [0x1B23]={
+ category="lo",
+ description="BALINESE LETTER TA TAWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B23,
+ },
+ [0x1B24]={
+ category="lo",
+ description="BALINESE LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B24,
+ },
+ [0x1B25]={
+ category="lo",
+ description="BALINESE LETTER DA MADU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B25,
+ },
+ [0x1B26]={
+ category="lo",
+ description="BALINESE LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B26,
+ },
+ [0x1B27]={
+ category="lo",
+ description="BALINESE LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B27,
+ },
+ [0x1B28]={
+ category="lo",
+ description="BALINESE LETTER PA KAPAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B28,
+ },
+ [0x1B29]={
+ category="lo",
+ description="BALINESE LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B29,
+ },
+ [0x1B2A]={
+ category="lo",
+ description="BALINESE LETTER BA KEMBANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2A,
+ },
+ [0x1B2B]={
+ category="lo",
+ description="BALINESE LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2B,
+ },
+ [0x1B2C]={
+ category="lo",
+ description="BALINESE LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2C,
+ },
+ [0x1B2D]={
+ category="lo",
+ description="BALINESE LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2D,
+ },
+ [0x1B2E]={
+ category="lo",
+ description="BALINESE LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2E,
+ },
+ [0x1B2F]={
+ category="lo",
+ description="BALINESE LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B2F,
+ },
+ [0x1B30]={
+ category="lo",
+ description="BALINESE LETTER SA SAGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B30,
+ },
+ [0x1B31]={
+ category="lo",
+ description="BALINESE LETTER SA SAPA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B31,
+ },
+ [0x1B32]={
+ category="lo",
+ description="BALINESE LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B32,
+ },
+ [0x1B33]={
+ category="lo",
+ description="BALINESE LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B33,
+ },
+ [0x1B34]={
+ category="mn",
+ description="BALINESE SIGN REREKAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B34,
+ },
+ [0x1B35]={
+ category="mc",
+ description="BALINESE VOWEL SIGN TEDUNG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1B35,
+ },
+ [0x1B36]={
+ category="mn",
+ description="BALINESE VOWEL SIGN ULU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B36,
+ },
+ [0x1B37]={
+ category="mn",
+ description="BALINESE VOWEL SIGN ULU SARI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B37,
+ },
+ [0x1B38]={
+ category="mn",
+ description="BALINESE VOWEL SIGN SUKU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B38,
+ },
+ [0x1B39]={
+ category="mn",
+ description="BALINESE VOWEL SIGN SUKU ILUT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B39,
+ },
+ [0x1B3A]={
+ category="mn",
+ description="BALINESE VOWEL SIGN RA REPA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B3A,
+ },
+ [0x1B3B]={
+ category="mc",
+ description="BALINESE VOWEL SIGN RA REPA TEDUNG",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x1B3A, 0x1B35 },
+ unicodeslot=0x1B3B,
+ },
+ [0x1B3C]={
+ category="mn",
+ description="BALINESE VOWEL SIGN LA LENGA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B3C,
+ },
+ [0x1B3D]={
+ category="mc",
+ description="BALINESE VOWEL SIGN LA LENGA TEDUNG",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x1B3C, 0x1B35 },
+ unicodeslot=0x1B3D,
+ },
+ [0x1B3E]={
+ category="mc",
+ description="BALINESE VOWEL SIGN TALING",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1B3E,
+ },
+ [0x1B3F]={
+ category="mc",
+ description="BALINESE VOWEL SIGN TALING REPA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1B3F,
+ },
+ [0x1B40]={
+ category="mc",
+ description="BALINESE VOWEL SIGN TALING TEDUNG",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x1B3E, 0x1B35 },
+ unicodeslot=0x1B40,
+ },
+ [0x1B41]={
+ category="mc",
+ description="BALINESE VOWEL SIGN TALING REPA TEDUNG",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x1B3F, 0x1B35 },
+ unicodeslot=0x1B41,
+ },
+ [0x1B42]={
+ category="mn",
+ description="BALINESE VOWEL SIGN PEPET",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B42,
+ },
+ [0x1B43]={
+ category="mc",
+ description="BALINESE VOWEL SIGN PEPET TEDUNG",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x1B42, 0x1B35 },
+ unicodeslot=0x1B43,
+ },
+ [0x1B44]={
+ category="mc",
+ description="BALINESE ADEG ADEG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1B44,
+ },
+ [0x1B45]={
+ category="lo",
+ description="BALINESE LETTER KAF SASAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B45,
+ },
+ [0x1B46]={
+ category="lo",
+ description="BALINESE LETTER KHOT SASAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B46,
+ },
+ [0x1B47]={
+ category="lo",
+ description="BALINESE LETTER TZIR SASAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B47,
+ },
+ [0x1B48]={
+ category="lo",
+ description="BALINESE LETTER EF SASAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B48,
+ },
+ [0x1B49]={
+ category="lo",
+ description="BALINESE LETTER VE SASAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B49,
+ },
+ [0x1B4A]={
+ category="lo",
+ description="BALINESE LETTER ZAL SASAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B4A,
+ },
+ [0x1B4B]={
+ category="lo",
+ description="BALINESE LETTER ASYURA SASAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B4B,
+ },
+ [0x1B50]={
+ category="nd",
+ description="BALINESE DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B50,
+ },
+ [0x1B51]={
+ category="nd",
+ description="BALINESE DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B51,
+ },
+ [0x1B52]={
+ category="nd",
+ description="BALINESE DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B52,
+ },
+ [0x1B53]={
+ category="nd",
+ description="BALINESE DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B53,
+ },
+ [0x1B54]={
+ category="nd",
+ description="BALINESE DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B54,
+ },
+ [0x1B55]={
+ category="nd",
+ description="BALINESE DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B55,
+ },
+ [0x1B56]={
+ category="nd",
+ description="BALINESE DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B56,
+ },
+ [0x1B57]={
+ category="nd",
+ description="BALINESE DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B57,
+ },
+ [0x1B58]={
+ category="nd",
+ description="BALINESE DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B58,
+ },
+ [0x1B59]={
+ category="nd",
+ description="BALINESE DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1B59,
+ },
+ [0x1B5A]={
+ category="po",
+ description="BALINESE PANTI",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1B5A,
+ },
+ [0x1B5B]={
+ category="po",
+ description="BALINESE PAMADA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1B5B,
+ },
+ [0x1B5C]={
+ category="po",
+ description="BALINESE WINDU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B5C,
+ },
+ [0x1B5D]={
+ category="po",
+ description="BALINESE CARIK PAMUNGKAH",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1B5D,
+ },
+ [0x1B5E]={
+ category="po",
+ description="BALINESE CARIK SIKI",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1B5E,
+ },
+ [0x1B5F]={
+ category="po",
+ description="BALINESE CARIK PAREREN",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1B5F,
+ },
+ [0x1B60]={
+ category="po",
+ description="BALINESE PAMENENG",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1B60,
+ },
+ [0x1B61]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL DONG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B61,
+ },
+ [0x1B62]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL DENG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B62,
+ },
+ [0x1B63]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL DUNG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B63,
+ },
+ [0x1B64]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL DANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B64,
+ },
+ [0x1B65]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL DANG SURANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B65,
+ },
+ [0x1B66]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL DING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B66,
+ },
+ [0x1B67]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL DAENG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B67,
+ },
+ [0x1B68]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL DEUNG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B68,
+ },
+ [0x1B69]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL DAING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B69,
+ },
+ [0x1B6A]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL DANG GEDE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B6A,
+ },
+ [0x1B6B]={
+ category="mn",
+ description="BALINESE MUSICAL SYMBOL COMBINING TEGEH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B6B,
+ },
+ [0x1B6C]={
+ category="mn",
+ description="BALINESE MUSICAL SYMBOL COMBINING ENDEP",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B6C,
+ },
+ [0x1B6D]={
+ category="mn",
+ description="BALINESE MUSICAL SYMBOL COMBINING KEMPUL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B6D,
+ },
+ [0x1B6E]={
+ category="mn",
+ description="BALINESE MUSICAL SYMBOL COMBINING KEMPLI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B6E,
+ },
+ [0x1B6F]={
+ category="mn",
+ description="BALINESE MUSICAL SYMBOL COMBINING JEGOGAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B6F,
+ },
+ [0x1B70]={
+ category="mn",
+ description="BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B70,
+ },
+ [0x1B71]={
+ category="mn",
+ description="BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B71,
+ },
+ [0x1B72]={
+ category="mn",
+ description="BALINESE MUSICAL SYMBOL COMBINING BENDE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B72,
+ },
+ [0x1B73]={
+ category="mn",
+ description="BALINESE MUSICAL SYMBOL COMBINING GONG",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B73,
+ },
+ [0x1B74]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B74,
+ },
+ [0x1B75]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B75,
+ },
+ [0x1B76]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TUK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B76,
+ },
+ [0x1B77]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B77,
+ },
+ [0x1B78]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B78,
+ },
+ [0x1B79]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PUNG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B79,
+ },
+ [0x1B7A]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B7A,
+ },
+ [0x1B7B]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B7B,
+ },
+ [0x1B7C]={
+ category="so",
+ description="BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B7C,
+ },
+ [0x1B80]={
+ category="mn",
+ description="SUNDANESE SIGN PANYECEK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B80,
+ },
+ [0x1B81]={
+ category="mn",
+ description="SUNDANESE SIGN PANGLAYAR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1B81,
+ },
+ [0x1B82]={
+ category="mc",
+ description="SUNDANESE SIGN PANGWISAD",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1B82,
+ },
+ [0x1B83]={
+ category="lo",
+ description="SUNDANESE LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B83,
+ },
+ [0x1B84]={
+ category="lo",
+ description="SUNDANESE LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B84,
+ },
+ [0x1B85]={
+ category="lo",
+ description="SUNDANESE LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B85,
+ },
+ [0x1B86]={
+ category="lo",
+ description="SUNDANESE LETTER AE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B86,
+ },
+ [0x1B87]={
+ category="lo",
+ description="SUNDANESE LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B87,
+ },
+ [0x1B88]={
+ category="lo",
+ description="SUNDANESE LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B88,
+ },
+ [0x1B89]={
+ category="lo",
+ description="SUNDANESE LETTER EU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B89,
+ },
+ [0x1B8A]={
+ category="lo",
+ description="SUNDANESE LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8A,
+ },
+ [0x1B8B]={
+ category="lo",
+ description="SUNDANESE LETTER QA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8B,
+ },
+ [0x1B8C]={
+ category="lo",
+ description="SUNDANESE LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8C,
+ },
+ [0x1B8D]={
+ category="lo",
+ description="SUNDANESE LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8D,
+ },
+ [0x1B8E]={
+ category="lo",
+ description="SUNDANESE LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8E,
+ },
+ [0x1B8F]={
+ category="lo",
+ description="SUNDANESE LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B8F,
+ },
+ [0x1B90]={
+ category="lo",
+ description="SUNDANESE LETTER ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B90,
+ },
+ [0x1B91]={
+ category="lo",
+ description="SUNDANESE LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B91,
+ },
+ [0x1B92]={
+ category="lo",
+ description="SUNDANESE LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B92,
+ },
+ [0x1B93]={
+ category="lo",
+ description="SUNDANESE LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B93,
+ },
+ [0x1B94]={
+ category="lo",
+ description="SUNDANESE LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B94,
+ },
+ [0x1B95]={
+ category="lo",
+ description="SUNDANESE LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B95,
+ },
+ [0x1B96]={
+ category="lo",
+ description="SUNDANESE LETTER FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B96,
+ },
+ [0x1B97]={
+ category="lo",
+ description="SUNDANESE LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B97,
+ },
+ [0x1B98]={
+ category="lo",
+ description="SUNDANESE LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B98,
+ },
+ [0x1B99]={
+ category="lo",
+ description="SUNDANESE LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B99,
+ },
+ [0x1B9A]={
+ category="lo",
+ description="SUNDANESE LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9A,
+ },
+ [0x1B9B]={
+ category="lo",
+ description="SUNDANESE LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9B,
+ },
+ [0x1B9C]={
+ category="lo",
+ description="SUNDANESE LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9C,
+ },
+ [0x1B9D]={
+ category="lo",
+ description="SUNDANESE LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9D,
+ },
+ [0x1B9E]={
+ category="lo",
+ description="SUNDANESE LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9E,
+ },
+ [0x1B9F]={
+ category="lo",
+ description="SUNDANESE LETTER XA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1B9F,
+ },
+ [0x1BA0]={
+ category="lo",
+ description="SUNDANESE LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BA0,
+ },
+ [0x1BA1]={
+ category="mc",
+ description="SUNDANESE CONSONANT SIGN PAMINGKAL",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BA1,
+ },
+ [0x1BA2]={
+ category="mn",
+ description="SUNDANESE CONSONANT SIGN PANYAKRA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BA2,
+ },
+ [0x1BA3]={
+ category="mn",
+ description="SUNDANESE CONSONANT SIGN PANYIKU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BA3,
+ },
+ [0x1BA4]={
+ category="mn",
+ description="SUNDANESE VOWEL SIGN PANGHULU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BA4,
+ },
+ [0x1BA5]={
+ category="mn",
+ description="SUNDANESE VOWEL SIGN PANYUKU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BA5,
+ },
+ [0x1BA6]={
+ category="mc",
+ description="SUNDANESE VOWEL SIGN PANAELAENG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BA6,
+ },
+ [0x1BA7]={
+ category="mc",
+ description="SUNDANESE VOWEL SIGN PANOLONG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BA7,
+ },
+ [0x1BA8]={
+ category="mn",
+ description="SUNDANESE VOWEL SIGN PAMEPET",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BA8,
+ },
+ [0x1BA9]={
+ category="mn",
+ description="SUNDANESE VOWEL SIGN PANEULEUNG",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BA9,
+ },
+ [0x1BAA]={
+ category="mc",
+ description="SUNDANESE SIGN PAMAAEH",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BAA,
+ },
+ [0x1BAB]={
+ category="mn",
+ description="SUNDANESE SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BAB,
+ },
+ [0x1BAC]={
+ category="mc",
+ description="SUNDANESE CONSONANT SIGN PASANGAN MA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BAC,
+ },
+ [0x1BAD]={
+ category="mc",
+ description="SUNDANESE CONSONANT SIGN PASANGAN WA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BAD,
+ },
+ [0x1BAE]={
+ category="lo",
+ description="SUNDANESE LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BAE,
+ },
+ [0x1BAF]={
+ category="lo",
+ description="SUNDANESE LETTER SYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BAF,
+ },
+ [0x1BB0]={
+ category="nd",
+ description="SUNDANESE DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB0,
+ },
+ [0x1BB1]={
+ category="nd",
+ description="SUNDANESE DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB1,
+ },
+ [0x1BB2]={
+ category="nd",
+ description="SUNDANESE DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB2,
+ },
+ [0x1BB3]={
+ category="nd",
+ description="SUNDANESE DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB3,
+ },
+ [0x1BB4]={
+ category="nd",
+ description="SUNDANESE DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB4,
+ },
+ [0x1BB5]={
+ category="nd",
+ description="SUNDANESE DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB5,
+ },
+ [0x1BB6]={
+ category="nd",
+ description="SUNDANESE DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB6,
+ },
+ [0x1BB7]={
+ category="nd",
+ description="SUNDANESE DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB7,
+ },
+ [0x1BB8]={
+ category="nd",
+ description="SUNDANESE DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB8,
+ },
+ [0x1BB9]={
+ category="nd",
+ description="SUNDANESE DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1BB9,
+ },
+ [0x1BBA]={
+ category="lo",
+ description="SUNDANESE AVAGRAHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BBA,
+ },
+ [0x1BBB]={
+ category="lo",
+ description="SUNDANESE LETTER REU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BBB,
+ },
+ [0x1BBC]={
+ category="lo",
+ description="SUNDANESE LETTER LEU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BBC,
+ },
+ [0x1BBD]={
+ category="lo",
+ description="SUNDANESE LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BBD,
+ },
+ [0x1BBE]={
+ category="lo",
+ description="SUNDANESE LETTER FINAL K",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BBE,
+ },
+ [0x1BBF]={
+ category="lo",
+ description="SUNDANESE LETTER FINAL M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BBF,
+ },
+ [0x1BC0]={
+ category="lo",
+ description="BATAK LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC0,
+ },
+ [0x1BC1]={
+ category="lo",
+ description="BATAK LETTER SIMALUNGUN A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC1,
+ },
+ [0x1BC2]={
+ category="lo",
+ description="BATAK LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC2,
+ },
+ [0x1BC3]={
+ category="lo",
+ description="BATAK LETTER SIMALUNGUN HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC3,
+ },
+ [0x1BC4]={
+ category="lo",
+ description="BATAK LETTER MANDAILING HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC4,
+ },
+ [0x1BC5]={
+ category="lo",
+ description="BATAK LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC5,
+ },
+ [0x1BC6]={
+ category="lo",
+ description="BATAK LETTER KARO BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC6,
+ },
+ [0x1BC7]={
+ category="lo",
+ description="BATAK LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC7,
+ },
+ [0x1BC8]={
+ category="lo",
+ description="BATAK LETTER SIMALUNGUN PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC8,
+ },
+ [0x1BC9]={
+ category="lo",
+ description="BATAK LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BC9,
+ },
+ [0x1BCA]={
+ category="lo",
+ description="BATAK LETTER MANDAILING NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BCA,
+ },
+ [0x1BCB]={
+ category="lo",
+ description="BATAK LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BCB,
+ },
+ [0x1BCC]={
+ category="lo",
+ description="BATAK LETTER SIMALUNGUN WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BCC,
+ },
+ [0x1BCD]={
+ category="lo",
+ description="BATAK LETTER PAKPAK WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BCD,
+ },
+ [0x1BCE]={
+ category="lo",
+ description="BATAK LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BCE,
+ },
+ [0x1BCF]={
+ category="lo",
+ description="BATAK LETTER SIMALUNGUN GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BCF,
+ },
+ [0x1BD0]={
+ category="lo",
+ description="BATAK LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD0,
+ },
+ [0x1BD1]={
+ category="lo",
+ description="BATAK LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD1,
+ },
+ [0x1BD2]={
+ category="lo",
+ description="BATAK LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD2,
+ },
+ [0x1BD3]={
+ category="lo",
+ description="BATAK LETTER SIMALUNGUN RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD3,
+ },
+ [0x1BD4]={
+ category="lo",
+ description="BATAK LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD4,
+ },
+ [0x1BD5]={
+ category="lo",
+ description="BATAK LETTER SIMALUNGUN MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD5,
+ },
+ [0x1BD6]={
+ category="lo",
+ description="BATAK LETTER SOUTHERN TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD6,
+ },
+ [0x1BD7]={
+ category="lo",
+ description="BATAK LETTER NORTHERN TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD7,
+ },
+ [0x1BD8]={
+ category="lo",
+ description="BATAK LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD8,
+ },
+ [0x1BD9]={
+ category="lo",
+ description="BATAK LETTER SIMALUNGUN SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BD9,
+ },
+ [0x1BDA]={
+ category="lo",
+ description="BATAK LETTER MANDAILING SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BDA,
+ },
+ [0x1BDB]={
+ category="lo",
+ description="BATAK LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BDB,
+ },
+ [0x1BDC]={
+ category="lo",
+ description="BATAK LETTER SIMALUNGUN YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BDC,
+ },
+ [0x1BDD]={
+ category="lo",
+ description="BATAK LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BDD,
+ },
+ [0x1BDE]={
+ category="lo",
+ description="BATAK LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BDE,
+ },
+ [0x1BDF]={
+ category="lo",
+ description="BATAK LETTER SIMALUNGUN LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BDF,
+ },
+ [0x1BE0]={
+ category="lo",
+ description="BATAK LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE0,
+ },
+ [0x1BE1]={
+ category="lo",
+ description="BATAK LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE1,
+ },
+ [0x1BE2]={
+ category="lo",
+ description="BATAK LETTER NDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE2,
+ },
+ [0x1BE3]={
+ category="lo",
+ description="BATAK LETTER MBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE3,
+ },
+ [0x1BE4]={
+ category="lo",
+ description="BATAK LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE4,
+ },
+ [0x1BE5]={
+ category="lo",
+ description="BATAK LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BE5,
+ },
+ [0x1BE6]={
+ category="mn",
+ description="BATAK SIGN TOMPI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BE6,
+ },
+ [0x1BE7]={
+ category="mc",
+ description="BATAK VOWEL SIGN E",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BE7,
+ },
+ [0x1BE8]={
+ category="mn",
+ description="BATAK VOWEL SIGN PAKPAK E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BE8,
+ },
+ [0x1BE9]={
+ category="mn",
+ description="BATAK VOWEL SIGN EE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BE9,
+ },
+ [0x1BEA]={
+ category="mc",
+ description="BATAK VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BEA,
+ },
+ [0x1BEB]={
+ category="mc",
+ description="BATAK VOWEL SIGN KARO I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BEB,
+ },
+ [0x1BEC]={
+ category="mc",
+ description="BATAK VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BEC,
+ },
+ [0x1BED]={
+ category="mn",
+ description="BATAK VOWEL SIGN KARO O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BED,
+ },
+ [0x1BEE]={
+ category="mc",
+ description="BATAK VOWEL SIGN U",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BEE,
+ },
+ [0x1BEF]={
+ category="mn",
+ description="BATAK VOWEL SIGN U FOR SIMALUNGUN SA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BEF,
+ },
+ [0x1BF0]={
+ category="mn",
+ description="BATAK CONSONANT SIGN NG",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BF0,
+ },
+ [0x1BF1]={
+ category="mn",
+ description="BATAK CONSONANT SIGN H",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1BF1,
+ },
+ [0x1BF2]={
+ category="mc",
+ description="BATAK PANGOLAT",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BF2,
+ },
+ [0x1BF3]={
+ category="mc",
+ description="BATAK PANONGONAN",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1BF3,
+ },
+ [0x1BFC]={
+ category="po",
+ description="BATAK SYMBOL BINDU NA METEK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BFC,
+ },
+ [0x1BFD]={
+ category="po",
+ description="BATAK SYMBOL BINDU PINARBORAS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BFD,
+ },
+ [0x1BFE]={
+ category="po",
+ description="BATAK SYMBOL BINDU JUDUL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BFE,
+ },
+ [0x1BFF]={
+ category="po",
+ description="BATAK SYMBOL BINDU PANGOLAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1BFF,
+ },
+ [0x1C00]={
+ category="lo",
+ description="LEPCHA LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C00,
+ },
+ [0x1C01]={
+ category="lo",
+ description="LEPCHA LETTER KLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C01,
+ },
+ [0x1C02]={
+ category="lo",
+ description="LEPCHA LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C02,
+ },
+ [0x1C03]={
+ category="lo",
+ description="LEPCHA LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C03,
+ },
+ [0x1C04]={
+ category="lo",
+ description="LEPCHA LETTER GLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C04,
+ },
+ [0x1C05]={
+ category="lo",
+ description="LEPCHA LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C05,
+ },
+ [0x1C06]={
+ category="lo",
+ description="LEPCHA LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C06,
+ },
+ [0x1C07]={
+ category="lo",
+ description="LEPCHA LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C07,
+ },
+ [0x1C08]={
+ category="lo",
+ description="LEPCHA LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C08,
+ },
+ [0x1C09]={
+ category="lo",
+ description="LEPCHA LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C09,
+ },
+ [0x1C0A]={
+ category="lo",
+ description="LEPCHA LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0A,
+ },
+ [0x1C0B]={
+ category="lo",
+ description="LEPCHA LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0B,
+ },
+ [0x1C0C]={
+ category="lo",
+ description="LEPCHA LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0C,
+ },
+ [0x1C0D]={
+ category="lo",
+ description="LEPCHA LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0D,
+ },
+ [0x1C0E]={
+ category="lo",
+ description="LEPCHA LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0E,
+ },
+ [0x1C0F]={
+ category="lo",
+ description="LEPCHA LETTER PLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C0F,
+ },
+ [0x1C10]={
+ category="lo",
+ description="LEPCHA LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C10,
+ },
+ [0x1C11]={
+ category="lo",
+ description="LEPCHA LETTER FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C11,
+ },
+ [0x1C12]={
+ category="lo",
+ description="LEPCHA LETTER FLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C12,
+ },
+ [0x1C13]={
+ category="lo",
+ description="LEPCHA LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C13,
+ },
+ [0x1C14]={
+ category="lo",
+ description="LEPCHA LETTER BLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C14,
+ },
+ [0x1C15]={
+ category="lo",
+ description="LEPCHA LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C15,
+ },
+ [0x1C16]={
+ category="lo",
+ description="LEPCHA LETTER MLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C16,
+ },
+ [0x1C17]={
+ category="lo",
+ description="LEPCHA LETTER TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C17,
+ },
+ [0x1C18]={
+ category="lo",
+ description="LEPCHA LETTER TSHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C18,
+ },
+ [0x1C19]={
+ category="lo",
+ description="LEPCHA LETTER DZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C19,
+ },
+ [0x1C1A]={
+ category="lo",
+ description="LEPCHA LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1A,
+ },
+ [0x1C1B]={
+ category="lo",
+ description="LEPCHA LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1B,
+ },
+ [0x1C1C]={
+ category="lo",
+ description="LEPCHA LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1C,
+ },
+ [0x1C1D]={
+ category="lo",
+ description="LEPCHA LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1D,
+ },
+ [0x1C1E]={
+ category="lo",
+ description="LEPCHA LETTER HLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1E,
+ },
+ [0x1C1F]={
+ category="lo",
+ description="LEPCHA LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C1F,
+ },
+ [0x1C20]={
+ category="lo",
+ description="LEPCHA LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C20,
+ },
+ [0x1C21]={
+ category="lo",
+ description="LEPCHA LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C21,
+ },
+ [0x1C22]={
+ category="lo",
+ description="LEPCHA LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C22,
+ },
+ [0x1C23]={
+ category="lo",
+ description="LEPCHA LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C23,
+ },
+ [0x1C24]={
+ category="mc",
+ description="LEPCHA SUBJOINED LETTER YA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C24,
+ },
+ [0x1C25]={
+ category="mc",
+ description="LEPCHA SUBJOINED LETTER RA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C25,
+ },
+ [0x1C26]={
+ category="mc",
+ description="LEPCHA VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C26,
+ },
+ [0x1C27]={
+ category="mc",
+ description="LEPCHA VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C27,
+ },
+ [0x1C28]={
+ category="mc",
+ description="LEPCHA VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C28,
+ },
+ [0x1C29]={
+ category="mc",
+ description="LEPCHA VOWEL SIGN OO",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C29,
+ },
+ [0x1C2A]={
+ category="mc",
+ description="LEPCHA VOWEL SIGN U",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C2A,
+ },
+ [0x1C2B]={
+ category="mc",
+ description="LEPCHA VOWEL SIGN UU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C2B,
+ },
+ [0x1C2C]={
+ category="mn",
+ description="LEPCHA VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C2C,
+ },
+ [0x1C2D]={
+ category="mn",
+ description="LEPCHA CONSONANT SIGN K",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C2D,
+ },
+ [0x1C2E]={
+ category="mn",
+ description="LEPCHA CONSONANT SIGN M",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C2E,
+ },
+ [0x1C2F]={
+ category="mn",
+ description="LEPCHA CONSONANT SIGN L",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C2F,
+ },
+ [0x1C30]={
+ category="mn",
+ description="LEPCHA CONSONANT SIGN N",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C30,
+ },
+ [0x1C31]={
+ category="mn",
+ description="LEPCHA CONSONANT SIGN P",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C31,
+ },
+ [0x1C32]={
+ category="mn",
+ description="LEPCHA CONSONANT SIGN R",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C32,
+ },
+ [0x1C33]={
+ category="mn",
+ description="LEPCHA CONSONANT SIGN T",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C33,
+ },
+ [0x1C34]={
+ category="mc",
+ description="LEPCHA CONSONANT SIGN NYIN-DO",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C34,
+ },
+ [0x1C35]={
+ category="mc",
+ description="LEPCHA CONSONANT SIGN KANG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1C35,
+ },
+ [0x1C36]={
+ category="mn",
+ description="LEPCHA SIGN RAN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C36,
+ },
+ [0x1C37]={
+ category="mn",
+ description="LEPCHA SIGN NUKTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1C37,
+ },
+ [0x1C3B]={
+ category="po",
+ description="LEPCHA PUNCTUATION TA-ROL",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C3B,
+ },
+ [0x1C3C]={
+ category="po",
+ description="LEPCHA PUNCTUATION NYET THYOOM TA-ROL",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C3C,
+ },
+ [0x1C3D]={
+ category="po",
+ description="LEPCHA PUNCTUATION CER-WA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C3D,
+ },
+ [0x1C3E]={
+ category="po",
+ description="LEPCHA PUNCTUATION TSHOOK CER-WA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C3E,
+ },
+ [0x1C3F]={
+ category="po",
+ description="LEPCHA PUNCTUATION TSHOOK",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C3F,
+ },
+ [0x1C40]={
+ category="nd",
+ description="LEPCHA DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C40,
+ },
+ [0x1C41]={
+ category="nd",
+ description="LEPCHA DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C41,
+ },
+ [0x1C42]={
+ category="nd",
+ description="LEPCHA DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C42,
+ },
+ [0x1C43]={
+ category="nd",
+ description="LEPCHA DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C43,
+ },
+ [0x1C44]={
+ category="nd",
+ description="LEPCHA DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C44,
+ },
+ [0x1C45]={
+ category="nd",
+ description="LEPCHA DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C45,
+ },
+ [0x1C46]={
+ category="nd",
+ description="LEPCHA DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C46,
+ },
+ [0x1C47]={
+ category="nd",
+ description="LEPCHA DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C47,
+ },
+ [0x1C48]={
+ category="nd",
+ description="LEPCHA DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C48,
+ },
+ [0x1C49]={
+ category="nd",
+ description="LEPCHA DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C49,
+ },
+ [0x1C4D]={
+ category="lo",
+ description="LEPCHA LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C4D,
+ },
+ [0x1C4E]={
+ category="lo",
+ description="LEPCHA LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C4E,
+ },
+ [0x1C4F]={
+ category="lo",
+ description="LEPCHA LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C4F,
+ },
+ [0x1C50]={
+ category="nd",
+ description="OL CHIKI DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C50,
+ },
+ [0x1C51]={
+ category="nd",
+ description="OL CHIKI DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C51,
+ },
+ [0x1C52]={
+ category="nd",
+ description="OL CHIKI DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C52,
+ },
+ [0x1C53]={
+ category="nd",
+ description="OL CHIKI DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C53,
+ },
+ [0x1C54]={
+ category="nd",
+ description="OL CHIKI DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C54,
+ },
+ [0x1C55]={
+ category="nd",
+ description="OL CHIKI DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C55,
+ },
+ [0x1C56]={
+ category="nd",
+ description="OL CHIKI DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C56,
+ },
+ [0x1C57]={
+ category="nd",
+ description="OL CHIKI DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C57,
+ },
+ [0x1C58]={
+ category="nd",
+ description="OL CHIKI DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C58,
+ },
+ [0x1C59]={
+ category="nd",
+ description="OL CHIKI DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1C59,
+ },
+ [0x1C5A]={
+ category="lo",
+ description="OL CHIKI LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C5A,
+ },
+ [0x1C5B]={
+ category="lo",
+ description="OL CHIKI LETTER AT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C5B,
+ },
+ [0x1C5C]={
+ category="lo",
+ description="OL CHIKI LETTER AG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C5C,
+ },
+ [0x1C5D]={
+ category="lo",
+ description="OL CHIKI LETTER ANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C5D,
+ },
+ [0x1C5E]={
+ category="lo",
+ description="OL CHIKI LETTER AL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C5E,
+ },
+ [0x1C5F]={
+ category="lo",
+ description="OL CHIKI LETTER LAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C5F,
+ },
+ [0x1C60]={
+ category="lo",
+ description="OL CHIKI LETTER AAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C60,
+ },
+ [0x1C61]={
+ category="lo",
+ description="OL CHIKI LETTER AAJ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C61,
+ },
+ [0x1C62]={
+ category="lo",
+ description="OL CHIKI LETTER AAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C62,
+ },
+ [0x1C63]={
+ category="lo",
+ description="OL CHIKI LETTER AAW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C63,
+ },
+ [0x1C64]={
+ category="lo",
+ description="OL CHIKI LETTER LI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C64,
+ },
+ [0x1C65]={
+ category="lo",
+ description="OL CHIKI LETTER IS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C65,
+ },
+ [0x1C66]={
+ category="lo",
+ description="OL CHIKI LETTER IH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C66,
+ },
+ [0x1C67]={
+ category="lo",
+ description="OL CHIKI LETTER INY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C67,
+ },
+ [0x1C68]={
+ category="lo",
+ description="OL CHIKI LETTER IR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C68,
+ },
+ [0x1C69]={
+ category="lo",
+ description="OL CHIKI LETTER LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C69,
+ },
+ [0x1C6A]={
+ category="lo",
+ description="OL CHIKI LETTER UC",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C6A,
+ },
+ [0x1C6B]={
+ category="lo",
+ description="OL CHIKI LETTER UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C6B,
+ },
+ [0x1C6C]={
+ category="lo",
+ description="OL CHIKI LETTER UNN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C6C,
+ },
+ [0x1C6D]={
+ category="lo",
+ description="OL CHIKI LETTER UY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C6D,
+ },
+ [0x1C6E]={
+ category="lo",
+ description="OL CHIKI LETTER LE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C6E,
+ },
+ [0x1C6F]={
+ category="lo",
+ description="OL CHIKI LETTER EP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C6F,
+ },
+ [0x1C70]={
+ category="lo",
+ description="OL CHIKI LETTER EDD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C70,
+ },
+ [0x1C71]={
+ category="lo",
+ description="OL CHIKI LETTER EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C71,
+ },
+ [0x1C72]={
+ category="lo",
+ description="OL CHIKI LETTER ERR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C72,
+ },
+ [0x1C73]={
+ category="lo",
+ description="OL CHIKI LETTER LO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C73,
+ },
+ [0x1C74]={
+ category="lo",
+ description="OL CHIKI LETTER OTT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C74,
+ },
+ [0x1C75]={
+ category="lo",
+ description="OL CHIKI LETTER OB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C75,
+ },
+ [0x1C76]={
+ category="lo",
+ description="OL CHIKI LETTER OV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C76,
+ },
+ [0x1C77]={
+ category="lo",
+ description="OL CHIKI LETTER OH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C77,
+ },
+ [0x1C78]={
+ category="lm",
+ description="OL CHIKI MU TTUDDAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C78,
+ },
+ [0x1C79]={
+ category="lm",
+ description="OL CHIKI GAAHLAA TTUDDAAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C79,
+ },
+ [0x1C7A]={
+ category="lm",
+ description="OL CHIKI MU-GAAHLAA TTUDDAAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C7A,
+ },
+ [0x1C7B]={
+ category="lm",
+ description="OL CHIKI RELAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C7B,
+ },
+ [0x1C7C]={
+ category="lm",
+ description="OL CHIKI PHAARKAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C7C,
+ },
+ [0x1C7D]={
+ category="lm",
+ description="OL CHIKI AHAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1C7D,
+ },
+ [0x1C7E]={
+ category="po",
+ description="OL CHIKI PUNCTUATION MUCAAD",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C7E,
+ },
+ [0x1C7F]={
+ category="po",
+ description="OL CHIKI PUNCTUATION DOUBLE MUCAAD",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1C7F,
+ },
+ [0x1CC0]={
+ category="po",
+ description="SUNDANESE PUNCTUATION BINDU SURYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC0,
+ },
+ [0x1CC1]={
+ category="po",
+ description="SUNDANESE PUNCTUATION BINDU PANGLONG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC1,
+ },
+ [0x1CC2]={
+ category="po",
+ description="SUNDANESE PUNCTUATION BINDU PURNAMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC2,
+ },
+ [0x1CC3]={
+ category="po",
+ description="SUNDANESE PUNCTUATION BINDU CAKRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC3,
+ },
+ [0x1CC4]={
+ category="po",
+ description="SUNDANESE PUNCTUATION BINDU LEU SATANGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC4,
+ },
+ [0x1CC5]={
+ category="po",
+ description="SUNDANESE PUNCTUATION BINDU KA SATANGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC5,
+ },
+ [0x1CC6]={
+ category="po",
+ description="SUNDANESE PUNCTUATION BINDU DA SATANGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC6,
+ },
+ [0x1CC7]={
+ category="po",
+ description="SUNDANESE PUNCTUATION BINDU BA SATANGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CC7,
+ },
+ [0x1CD0]={
+ category="mn",
+ description="VEDIC TONE KARSHANA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD0,
+ },
+ [0x1CD1]={
+ category="mn",
+ description="VEDIC TONE SHARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD1,
+ },
+ [0x1CD2]={
+ category="mn",
+ description="VEDIC TONE PRENKHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD2,
+ },
+ [0x1CD3]={
+ category="po",
+ description="VEDIC SIGN NIHSHVASA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CD3,
+ },
+ [0x1CD4]={
+ category="mn",
+ description="VEDIC SIGN YAJURVEDIC MIDLINE SVARITA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD4,
+ },
+ [0x1CD5]={
+ category="mn",
+ description="VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD5,
+ },
+ [0x1CD6]={
+ category="mn",
+ description="VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD6,
+ },
+ [0x1CD7]={
+ category="mn",
+ description="VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD7,
+ },
+ [0x1CD8]={
+ category="mn",
+ description="VEDIC TONE CANDRA BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD8,
+ },
+ [0x1CD9]={
+ category="mn",
+ description="VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CD9,
+ },
+ [0x1CDA]={
+ category="mn",
+ description="VEDIC TONE DOUBLE SVARITA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CDA,
+ },
+ [0x1CDB]={
+ category="mn",
+ description="VEDIC TONE TRIPLE SVARITA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CDB,
+ },
+ [0x1CDC]={
+ category="mn",
+ description="VEDIC TONE KATHAKA ANUDATTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CDC,
+ },
+ [0x1CDD]={
+ category="mn",
+ description="VEDIC TONE DOT BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CDD,
+ },
+ [0x1CDE]={
+ category="mn",
+ description="VEDIC TONE TWO DOTS BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CDE,
+ },
+ [0x1CDF]={
+ category="mn",
+ description="VEDIC TONE THREE DOTS BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CDF,
+ },
+ [0x1CE0]={
+ category="mn",
+ description="VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE0,
+ },
+ [0x1CE1]={
+ category="mc",
+ description="VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1CE1,
+ },
+ [0x1CE2]={
+ category="mn",
+ description="VEDIC SIGN VISARGA SVARITA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE2,
+ },
+ [0x1CE3]={
+ category="mn",
+ description="VEDIC SIGN VISARGA UDATTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE3,
+ },
+ [0x1CE4]={
+ category="mn",
+ description="VEDIC SIGN REVERSED VISARGA UDATTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE4,
+ },
+ [0x1CE5]={
+ category="mn",
+ description="VEDIC SIGN VISARGA ANUDATTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE5,
+ },
+ [0x1CE6]={
+ category="mn",
+ description="VEDIC SIGN REVERSED VISARGA ANUDATTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE6,
+ },
+ [0x1CE7]={
+ category="mn",
+ description="VEDIC SIGN VISARGA UDATTA WITH TAIL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE7,
+ },
+ [0x1CE8]={
+ category="mn",
+ description="VEDIC SIGN VISARGA ANUDATTA WITH TAIL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CE8,
+ },
+ [0x1CE9]={
+ category="lo",
+ description="VEDIC SIGN ANUSVARA ANTARGOMUKHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CE9,
+ },
+ [0x1CEA]={
+ category="lo",
+ description="VEDIC SIGN ANUSVARA BAHIRGOMUKHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CEA,
+ },
+ [0x1CEB]={
+ category="lo",
+ description="VEDIC SIGN ANUSVARA VAMAGOMUKHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CEB,
+ },
+ [0x1CEC]={
+ category="lo",
+ description="VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CEC,
+ },
+ [0x1CED]={
+ category="mn",
+ description="VEDIC SIGN TIRYAK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CED,
+ },
+ [0x1CEE]={
+ category="lo",
+ description="VEDIC SIGN HEXIFORM LONG ANUSVARA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CEE,
+ },
+ [0x1CEF]={
+ category="lo",
+ description="VEDIC SIGN LONG ANUSVARA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CEF,
+ },
+ [0x1CF0]={
+ category="lo",
+ description="VEDIC SIGN RTHANG LONG ANUSVARA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CF0,
+ },
+ [0x1CF1]={
+ category="lo",
+ description="VEDIC SIGN ANUSVARA UBHAYATO MUKHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CF1,
+ },
+ [0x1CF2]={
+ category="mc",
+ description="VEDIC SIGN ARDHAVISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1CF2,
+ },
+ [0x1CF3]={
+ category="mc",
+ description="VEDIC SIGN ROTATED ARDHAVISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1CF3,
+ },
+ [0x1CF4]={
+ category="mn",
+ description="VEDIC TONE CANDRA ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1CF4,
+ },
+ [0x1CF5]={
+ category="lo",
+ description="VEDIC SIGN JIHVAMULIYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CF5,
+ },
+ [0x1CF6]={
+ category="lo",
+ description="VEDIC SIGN UPADHMANIYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1CF6,
+ },
+ [0x1D00]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00,
+ },
+ [0x1D01]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL AE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01,
+ },
+ [0x1D02]={
+ category="ll",
+ description="LATIN SMALL LETTER TURNED AE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02,
+ },
+ [0x1D03]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL BARRED B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03,
+ },
+ [0x1D04]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04,
+ },
+ [0x1D05]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05,
+ },
+ [0x1D06]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL ETH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06,
+ },
+ [0x1D07]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07,
+ },
+ [0x1D08]={
+ category="ll",
+ description="LATIN SMALL LETTER TURNED OPEN E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08,
+ },
+ [0x1D09]={
+ category="ll",
+ description="LATIN SMALL LETTER TURNED I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09,
+ },
+ [0x1D0A]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL J",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A,
+ },
+ [0x1D0B]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL K",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B,
+ },
+ [0x1D0C]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL L WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C,
+ },
+ [0x1D0D]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D,
+ },
+ [0x1D0E]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL REVERSED N",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E,
+ },
+ [0x1D0F]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F,
+ },
+ [0x1D10]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL OPEN O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10,
+ },
+ [0x1D11]={
+ category="ll",
+ description="LATIN SMALL LETTER SIDEWAYS O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11,
+ },
+ [0x1D12]={
+ category="ll",
+ description="LATIN SMALL LETTER SIDEWAYS OPEN O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12,
+ },
+ [0x1D13]={
+ category="ll",
+ description="LATIN SMALL LETTER SIDEWAYS O WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13,
+ },
+ [0x1D14]={
+ category="ll",
+ description="LATIN SMALL LETTER TURNED OE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14,
+ },
+ [0x1D15]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL OU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D15,
+ },
+ [0x1D16]={
+ category="ll",
+ description="LATIN SMALL LETTER TOP HALF O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D16,
+ },
+ [0x1D17]={
+ category="ll",
+ description="LATIN SMALL LETTER BOTTOM HALF O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D17,
+ },
+ [0x1D18]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL P",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D18,
+ },
+ [0x1D19]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL REVERSED R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19,
+ },
+ [0x1D1A]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL TURNED R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A,
+ },
+ [0x1D1B]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL T",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B,
+ },
+ [0x1D1C]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C,
+ },
+ [0x1D1D]={
+ category="ll",
+ description="LATIN SMALL LETTER SIDEWAYS U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D,
+ },
+ [0x1D1E]={
+ category="ll",
+ description="LATIN SMALL LETTER SIDEWAYS DIAERESIZED U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1E,
+ },
+ [0x1D1F]={
+ category="ll",
+ description="LATIN SMALL LETTER SIDEWAYS TURNED M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1F,
+ },
+ [0x1D20]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL V",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D20,
+ },
+ [0x1D21]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL W",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D21,
+ },
+ [0x1D22]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D22,
+ },
+ [0x1D23]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL EZH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D23,
+ },
+ [0x1D24]={
+ category="ll",
+ description="LATIN LETTER VOICED LARYNGEAL SPIRANT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D24,
+ },
+ [0x1D25]={
+ category="ll",
+ description="LATIN LETTER AIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D25,
+ },
+ [0x1D26]={
+ category="ll",
+ description="GREEK LETTER SMALL CAPITAL GAMMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D26,
+ },
+ [0x1D27]={
+ category="ll",
+ description="GREEK LETTER SMALL CAPITAL LAMDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D27,
+ },
+ [0x1D28]={
+ category="ll",
+ description="GREEK LETTER SMALL CAPITAL PI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D28,
+ },
+ [0x1D29]={
+ category="ll",
+ description="GREEK LETTER SMALL CAPITAL RHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D29,
+ },
+ [0x1D2A]={
+ category="ll",
+ description="GREEK LETTER SMALL CAPITAL PSI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2A,
+ },
+ [0x1D2B]={
+ category="ll",
+ description="CYRILLIC LETTER SMALL CAPITAL EL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2B,
+ },
+ [0x1D2C]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0041 },
+ unicodeslot=0x1D2C,
+ },
+ [0x1D2D]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL AE",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x00C6 },
+ unicodeslot=0x1D2D,
+ },
+ [0x1D2E]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0042 },
+ unicodeslot=0x1D2E,
+ },
+ [0x1D2F]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL BARRED B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D2F,
+ },
+ [0x1D30]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0044 },
+ unicodeslot=0x1D30,
+ },
+ [0x1D31]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0045 },
+ unicodeslot=0x1D31,
+ },
+ [0x1D32]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL REVERSED E",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x018E },
+ unicodeslot=0x1D32,
+ },
+ [0x1D33]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0047 },
+ unicodeslot=0x1D33,
+ },
+ [0x1D34]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0048 },
+ unicodeslot=0x1D34,
+ },
+ [0x1D35]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0049 },
+ unicodeslot=0x1D35,
+ },
+ [0x1D36]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x004A },
+ unicodeslot=0x1D36,
+ },
+ [0x1D37]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x004B },
+ unicodeslot=0x1D37,
+ },
+ [0x1D38]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x004C },
+ unicodeslot=0x1D38,
+ },
+ [0x1D39]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x004D },
+ unicodeslot=0x1D39,
+ },
+ [0x1D3A]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x004E },
+ unicodeslot=0x1D3A,
+ },
+ [0x1D3B]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL REVERSED N",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D3B,
+ },
+ [0x1D3C]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x004F },
+ unicodeslot=0x1D3C,
+ },
+ [0x1D3D]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL OU",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0222 },
+ unicodeslot=0x1D3D,
+ },
+ [0x1D3E]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0050 },
+ unicodeslot=0x1D3E,
+ },
+ [0x1D3F]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL R",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0052 },
+ unicodeslot=0x1D3F,
+ },
+ [0x1D40]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0054 },
+ unicodeslot=0x1D40,
+ },
+ [0x1D41]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0055 },
+ unicodeslot=0x1D41,
+ },
+ [0x1D42]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0057 },
+ unicodeslot=0x1D42,
+ },
+ [0x1D43]={
+ category="lm",
+ description="MODIFIER LETTER SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0061 },
+ unicodeslot=0x1D43,
+ },
+ [0x1D44]={
+ category="lm",
+ description="MODIFIER LETTER SMALL TURNED A",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0250 },
+ unicodeslot=0x1D44,
+ },
+ [0x1D45]={
+ category="lm",
+ description="MODIFIER LETTER SMALL ALPHA",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0251 },
+ unicodeslot=0x1D45,
+ },
+ [0x1D46]={
+ category="lm",
+ description="MODIFIER LETTER SMALL TURNED AE",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D02 },
+ unicodeslot=0x1D46,
+ },
+ [0x1D47]={
+ category="lm",
+ description="MODIFIER LETTER SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0062 },
+ unicodeslot=0x1D47,
+ },
+ [0x1D48]={
+ category="lm",
+ description="MODIFIER LETTER SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0064 },
+ unicodeslot=0x1D48,
+ },
+ [0x1D49]={
+ category="lm",
+ description="MODIFIER LETTER SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0065 },
+ unicodeslot=0x1D49,
+ },
+ [0x1D4A]={
+ category="lm",
+ description="MODIFIER LETTER SMALL SCHWA",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0259 },
+ unicodeslot=0x1D4A,
+ },
+ [0x1D4B]={
+ category="lm",
+ description="MODIFIER LETTER SMALL OPEN E",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x025B },
+ unicodeslot=0x1D4B,
+ },
+ [0x1D4C]={
+ category="lm",
+ description="MODIFIER LETTER SMALL TURNED OPEN E",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x025C },
+ unicodeslot=0x1D4C,
+ },
+ [0x1D4D]={
+ category="lm",
+ description="MODIFIER LETTER SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0067 },
+ unicodeslot=0x1D4D,
+ },
+ [0x1D4E]={
+ category="lm",
+ description="MODIFIER LETTER SMALL TURNED I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D4E,
+ },
+ [0x1D4F]={
+ category="lm",
+ description="MODIFIER LETTER SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x006B },
+ unicodeslot=0x1D4F,
+ },
+ [0x1D50]={
+ category="lm",
+ description="MODIFIER LETTER SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x006D },
+ unicodeslot=0x1D50,
+ },
+ [0x1D51]={
+ category="lm",
+ description="MODIFIER LETTER SMALL ENG",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x014B },
+ unicodeslot=0x1D51,
+ },
+ [0x1D52]={
+ category="lm",
+ description="MODIFIER LETTER SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x006F },
+ unicodeslot=0x1D52,
+ },
+ [0x1D53]={
+ category="lm",
+ description="MODIFIER LETTER SMALL OPEN O",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0254 },
+ unicodeslot=0x1D53,
+ },
+ [0x1D54]={
+ category="lm",
+ description="MODIFIER LETTER SMALL TOP HALF O",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D16 },
+ unicodeslot=0x1D54,
+ },
+ [0x1D55]={
+ category="lm",
+ description="MODIFIER LETTER SMALL BOTTOM HALF O",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D17 },
+ unicodeslot=0x1D55,
+ },
+ [0x1D56]={
+ category="lm",
+ description="MODIFIER LETTER SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0070 },
+ unicodeslot=0x1D56,
+ },
+ [0x1D57]={
+ category="lm",
+ description="MODIFIER LETTER SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0074 },
+ unicodeslot=0x1D57,
+ },
+ [0x1D58]={
+ category="lm",
+ description="MODIFIER LETTER SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0075 },
+ unicodeslot=0x1D58,
+ },
+ [0x1D59]={
+ category="lm",
+ description="MODIFIER LETTER SMALL SIDEWAYS U",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D1D },
+ unicodeslot=0x1D59,
+ },
+ [0x1D5A]={
+ category="lm",
+ description="MODIFIER LETTER SMALL TURNED M",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x026F },
+ unicodeslot=0x1D5A,
+ },
+ [0x1D5B]={
+ category="lm",
+ description="MODIFIER LETTER SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0076 },
+ unicodeslot=0x1D5B,
+ },
+ [0x1D5C]={
+ category="lm",
+ description="MODIFIER LETTER SMALL AIN",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D25 },
+ unicodeslot=0x1D5C,
+ },
+ [0x1D5D]={
+ category="lm",
+ description="MODIFIER LETTER SMALL BETA",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x03B2 },
+ unicodeslot=0x1D5D,
+ },
+ [0x1D5E]={
+ category="lm",
+ description="MODIFIER LETTER SMALL GREEK GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x03B3 },
+ unicodeslot=0x1D5E,
+ },
+ [0x1D5F]={
+ category="lm",
+ description="MODIFIER LETTER SMALL DELTA",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x03B4 },
+ unicodeslot=0x1D5F,
+ },
+ [0x1D60]={
+ category="lm",
+ description="MODIFIER LETTER SMALL GREEK PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x03C6 },
+ unicodeslot=0x1D60,
+ },
+ [0x1D61]={
+ category="lm",
+ description="MODIFIER LETTER SMALL CHI",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x03C7 },
+ unicodeslot=0x1D61,
+ },
+ [0x1D62]={
+ category="ll",
+ description="LATIN SUBSCRIPT SMALL LETTER I",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x0069 },
+ unicodeslot=0x1D62,
+ },
+ [0x1D63]={
+ category="ll",
+ description="LATIN SUBSCRIPT SMALL LETTER R",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x0072 },
+ unicodeslot=0x1D63,
+ },
+ [0x1D64]={
+ category="ll",
+ description="LATIN SUBSCRIPT SMALL LETTER U",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x0075 },
+ unicodeslot=0x1D64,
+ },
+ [0x1D65]={
+ category="ll",
+ description="LATIN SUBSCRIPT SMALL LETTER V",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x0076 },
+ unicodeslot=0x1D65,
+ },
+ [0x1D66]={
+ category="ll",
+ description="GREEK SUBSCRIPT SMALL LETTER BETA",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x03B2 },
+ unicodeslot=0x1D66,
+ },
+ [0x1D67]={
+ category="ll",
+ description="GREEK SUBSCRIPT SMALL LETTER GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x03B3 },
+ unicodeslot=0x1D67,
+ },
+ [0x1D68]={
+ category="ll",
+ description="GREEK SUBSCRIPT SMALL LETTER RHO",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x03C1 },
+ unicodeslot=0x1D68,
+ },
+ [0x1D69]={
+ category="ll",
+ description="GREEK SUBSCRIPT SMALL LETTER PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x03C6 },
+ unicodeslot=0x1D69,
+ },
+ [0x1D6A]={
+ category="ll",
+ description="GREEK SUBSCRIPT SMALL LETTER CHI",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x03C7 },
+ unicodeslot=0x1D6A,
+ },
+ [0x1D6B]={
+ category="ll",
+ description="LATIN SMALL LETTER UE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D6B,
+ },
+ [0x1D6C]={
+ category="ll",
+ description="LATIN SMALL LETTER B WITH MIDDLE TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0062,
+ unicodeslot=0x1D6C,
+ },
+ [0x1D6D]={
+ category="ll",
+ description="LATIN SMALL LETTER D WITH MIDDLE TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ unicodeslot=0x1D6D,
+ },
+ [0x1D6E]={
+ category="ll",
+ description="LATIN SMALL LETTER F WITH MIDDLE TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0066,
+ unicodeslot=0x1D6E,
+ },
+ [0x1D6F]={
+ category="ll",
+ description="LATIN SMALL LETTER M WITH MIDDLE TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006D,
+ unicodeslot=0x1D6F,
+ },
+ [0x1D70]={
+ category="ll",
+ description="LATIN SMALL LETTER N WITH MIDDLE TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ unicodeslot=0x1D70,
+ },
+ [0x1D71]={
+ category="ll",
+ description="LATIN SMALL LETTER P WITH MIDDLE TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0070,
+ unicodeslot=0x1D71,
+ },
+ [0x1D72]={
+ category="ll",
+ description="LATIN SMALL LETTER R WITH MIDDLE TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ unicodeslot=0x1D72,
+ },
+ [0x1D73]={
+ category="ll",
+ description="LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ unicodeslot=0x1D73,
+ },
+ [0x1D74]={
+ category="ll",
+ description="LATIN SMALL LETTER S WITH MIDDLE TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ unicodeslot=0x1D74,
+ },
+ [0x1D75]={
+ category="ll",
+ description="LATIN SMALL LETTER T WITH MIDDLE TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ unicodeslot=0x1D75,
+ },
+ [0x1D76]={
+ category="ll",
+ description="LATIN SMALL LETTER Z WITH MIDDLE TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ unicodeslot=0x1D76,
+ },
+ [0x1D77]={
+ category="ll",
+ description="LATIN SMALL LETTER TURNED G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D77,
+ },
+ [0x1D78]={
+ category="lm",
+ description="MODIFIER LETTER CYRILLIC EN",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x043D },
+ unicodeslot=0x1D78,
+ },
+ [0x1D79]={
+ category="ll",
+ description="LATIN SMALL LETTER INSULAR G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D79,
+ },
+ [0x1D7A]={
+ category="ll",
+ description="LATIN SMALL LETTER TH WITH STRIKETHROUGH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D7A,
+ },
+ [0x1D7B]={
+ category="ll",
+ description="LATIN SMALL CAPITAL LETTER I WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D7B,
+ },
+ [0x1D7C]={
+ category="ll",
+ description="LATIN SMALL LETTER IOTA WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0269,
+ unicodeslot=0x1D7C,
+ },
+ [0x1D7D]={
+ category="ll",
+ description="LATIN SMALL LETTER P WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0070,
+ uccode=0x2C63,
+ unicodeslot=0x1D7D,
+ },
+ [0x1D7E]={
+ category="ll",
+ description="LATIN SMALL CAPITAL LETTER U WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D7E,
+ },
+ [0x1D7F]={
+ category="ll",
+ description="LATIN SMALL LETTER UPSILON WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x028A,
+ unicodeslot=0x1D7F,
+ },
+ [0x1D80]={
+ category="ll",
+ description="LATIN SMALL LETTER B WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0062,
+ unicodeslot=0x1D80,
+ },
+ [0x1D81]={
+ category="ll",
+ description="LATIN SMALL LETTER D WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ unicodeslot=0x1D81,
+ },
+ [0x1D82]={
+ category="ll",
+ description="LATIN SMALL LETTER F WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0066,
+ unicodeslot=0x1D82,
+ },
+ [0x1D83]={
+ category="ll",
+ description="LATIN SMALL LETTER G WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0067,
+ unicodeslot=0x1D83,
+ },
+ [0x1D84]={
+ category="ll",
+ description="LATIN SMALL LETTER K WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x006B,
+ unicodeslot=0x1D84,
+ },
+ [0x1D85]={
+ category="ll",
+ description="LATIN SMALL LETTER L WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ unicodeslot=0x1D85,
+ },
+ [0x1D86]={
+ category="ll",
+ description="LATIN SMALL LETTER M WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x006D,
+ unicodeslot=0x1D86,
+ },
+ [0x1D87]={
+ category="ll",
+ description="LATIN SMALL LETTER N WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ unicodeslot=0x1D87,
+ },
+ [0x1D88]={
+ category="ll",
+ description="LATIN SMALL LETTER P WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0070,
+ unicodeslot=0x1D88,
+ },
+ [0x1D89]={
+ category="ll",
+ description="LATIN SMALL LETTER R WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ unicodeslot=0x1D89,
+ },
+ [0x1D8A]={
+ category="ll",
+ description="LATIN SMALL LETTER S WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ unicodeslot=0x1D8A,
+ },
+ [0x1D8B]={
+ category="ll",
+ description="LATIN SMALL LETTER ESH WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0283,
+ unicodeslot=0x1D8B,
+ },
+ [0x1D8C]={
+ category="ll",
+ description="LATIN SMALL LETTER V WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0076,
+ unicodeslot=0x1D8C,
+ },
+ [0x1D8D]={
+ category="ll",
+ description="LATIN SMALL LETTER X WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0078,
+ unicodeslot=0x1D8D,
+ },
+ [0x1D8E]={
+ category="ll",
+ description="LATIN SMALL LETTER Z WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ unicodeslot=0x1D8E,
+ },
+ [0x1D8F]={
+ category="ll",
+ description="LATIN SMALL LETTER A WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ unicodeslot=0x1D8F,
+ },
+ [0x1D90]={
+ category="ll",
+ description="LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0251,
+ unicodeslot=0x1D90,
+ },
+ [0x1D91]={
+ category="ll",
+ description="LATIN SMALL LETTER D WITH HOOK AND TAIL",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ unicodeslot=0x1D91,
+ },
+ [0x1D92]={
+ category="ll",
+ description="LATIN SMALL LETTER E WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ unicodeslot=0x1D92,
+ },
+ [0x1D93]={
+ category="ll",
+ description="LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D93,
+ },
+ [0x1D94]={
+ category="ll",
+ description="LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D94,
+ },
+ [0x1D95]={
+ category="ll",
+ description="LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0259,
+ unicodeslot=0x1D95,
+ },
+ [0x1D96]={
+ category="ll",
+ description="LATIN SMALL LETTER I WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ unicodeslot=0x1D96,
+ },
+ [0x1D97]={
+ category="ll",
+ description="LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D97,
+ },
+ [0x1D98]={
+ category="ll",
+ description="LATIN SMALL LETTER ESH WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0283,
+ unicodeslot=0x1D98,
+ },
+ [0x1D99]={
+ category="ll",
+ description="LATIN SMALL LETTER U WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ unicodeslot=0x1D99,
+ },
+ [0x1D9A]={
+ category="ll",
+ description="LATIN SMALL LETTER EZH WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ shcode=0x0292,
+ unicodeslot=0x1D9A,
+ },
+ [0x1D9B]={
+ category="lm",
+ description="MODIFIER LETTER SMALL TURNED ALPHA",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0252 },
+ unicodeslot=0x1D9B,
+ },
+ [0x1D9C]={
+ category="lm",
+ description="MODIFIER LETTER SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0063 },
+ unicodeslot=0x1D9C,
+ },
+ [0x1D9D]={
+ category="lm",
+ description="MODIFIER LETTER SMALL C WITH CURL",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0255 },
+ unicodeslot=0x1D9D,
+ },
+ [0x1D9E]={
+ category="lm",
+ description="MODIFIER LETTER SMALL ETH",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x00F0 },
+ unicodeslot=0x1D9E,
+ },
+ [0x1D9F]={
+ category="lm",
+ description="MODIFIER LETTER SMALL REVERSED OPEN E",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x025C },
+ unicodeslot=0x1D9F,
+ },
+ [0x1DA0]={
+ category="lm",
+ description="MODIFIER LETTER SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0066 },
+ unicodeslot=0x1DA0,
+ },
+ [0x1DA1]={
+ category="lm",
+ description="MODIFIER LETTER SMALL DOTLESS J WITH STROKE",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x025F },
+ unicodeslot=0x1DA1,
+ },
+ [0x1DA2]={
+ category="lm",
+ description="MODIFIER LETTER SMALL SCRIPT G",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0261 },
+ unicodeslot=0x1DA2,
+ },
+ [0x1DA3]={
+ category="lm",
+ description="MODIFIER LETTER SMALL TURNED H",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0265 },
+ unicodeslot=0x1DA3,
+ },
+ [0x1DA4]={
+ category="lm",
+ description="MODIFIER LETTER SMALL I WITH STROKE",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0268 },
+ unicodeslot=0x1DA4,
+ },
+ [0x1DA5]={
+ category="lm",
+ description="MODIFIER LETTER SMALL IOTA",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0269 },
+ unicodeslot=0x1DA5,
+ },
+ [0x1DA6]={
+ category="lm",
+ description="MODIFIER LETTER SMALL CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x026A },
+ unicodeslot=0x1DA6,
+ },
+ [0x1DA7]={
+ category="lm",
+ description="MODIFIER LETTER SMALL CAPITAL I WITH STROKE",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D7B },
+ unicodeslot=0x1DA7,
+ },
+ [0x1DA8]={
+ category="lm",
+ description="MODIFIER LETTER SMALL J WITH CROSSED-TAIL",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x029D },
+ unicodeslot=0x1DA8,
+ },
+ [0x1DA9]={
+ category="lm",
+ description="MODIFIER LETTER SMALL L WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x026D },
+ unicodeslot=0x1DA9,
+ },
+ [0x1DAA]={
+ category="lm",
+ description="MODIFIER LETTER SMALL L WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D85 },
+ unicodeslot=0x1DAA,
+ },
+ [0x1DAB]={
+ category="lm",
+ description="MODIFIER LETTER SMALL CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x029F },
+ unicodeslot=0x1DAB,
+ },
+ [0x1DAC]={
+ category="lm",
+ description="MODIFIER LETTER SMALL M WITH HOOK",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0271 },
+ unicodeslot=0x1DAC,
+ },
+ [0x1DAD]={
+ category="lm",
+ description="MODIFIER LETTER SMALL TURNED M WITH LONG LEG",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0270 },
+ unicodeslot=0x1DAD,
+ },
+ [0x1DAE]={
+ category="lm",
+ description="MODIFIER LETTER SMALL N WITH LEFT HOOK",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0272 },
+ unicodeslot=0x1DAE,
+ },
+ [0x1DAF]={
+ category="lm",
+ description="MODIFIER LETTER SMALL N WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0273 },
+ unicodeslot=0x1DAF,
+ },
+ [0x1DB0]={
+ category="lm",
+ description="MODIFIER LETTER SMALL CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0274 },
+ unicodeslot=0x1DB0,
+ },
+ [0x1DB1]={
+ category="lm",
+ description="MODIFIER LETTER SMALL BARRED O",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0275 },
+ unicodeslot=0x1DB1,
+ },
+ [0x1DB2]={
+ category="lm",
+ description="MODIFIER LETTER SMALL PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0278 },
+ unicodeslot=0x1DB2,
+ },
+ [0x1DB3]={
+ category="lm",
+ description="MODIFIER LETTER SMALL S WITH HOOK",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0282 },
+ unicodeslot=0x1DB3,
+ },
+ [0x1DB4]={
+ category="lm",
+ description="MODIFIER LETTER SMALL ESH",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0283 },
+ unicodeslot=0x1DB4,
+ },
+ [0x1DB5]={
+ category="lm",
+ description="MODIFIER LETTER SMALL T WITH PALATAL HOOK",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x01AB },
+ unicodeslot=0x1DB5,
+ },
+ [0x1DB6]={
+ category="lm",
+ description="MODIFIER LETTER SMALL U BAR",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0289 },
+ unicodeslot=0x1DB6,
+ },
+ [0x1DB7]={
+ category="lm",
+ description="MODIFIER LETTER SMALL UPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x028A },
+ unicodeslot=0x1DB7,
+ },
+ [0x1DB8]={
+ category="lm",
+ description="MODIFIER LETTER SMALL CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x1D1C },
+ unicodeslot=0x1DB8,
+ },
+ [0x1DB9]={
+ category="lm",
+ description="MODIFIER LETTER SMALL V WITH HOOK",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x028B },
+ unicodeslot=0x1DB9,
+ },
+ [0x1DBA]={
+ category="lm",
+ description="MODIFIER LETTER SMALL TURNED V",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x028C },
+ unicodeslot=0x1DBA,
+ },
+ [0x1DBB]={
+ category="lm",
+ description="MODIFIER LETTER SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x007A },
+ unicodeslot=0x1DBB,
+ },
+ [0x1DBC]={
+ category="lm",
+ description="MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0290 },
+ unicodeslot=0x1DBC,
+ },
+ [0x1DBD]={
+ category="lm",
+ description="MODIFIER LETTER SMALL Z WITH CURL",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0291 },
+ unicodeslot=0x1DBD,
+ },
+ [0x1DBE]={
+ category="lm",
+ description="MODIFIER LETTER SMALL EZH",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0292 },
+ unicodeslot=0x1DBE,
+ },
+ [0x1DBF]={
+ category="lm",
+ description="MODIFIER LETTER SMALL THETA",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x03B8 },
+ unicodeslot=0x1DBF,
+ },
+ [0x1DC0]={
+ category="mn",
+ description="COMBINING DOTTED GRAVE ACCENT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC0,
+ },
+ [0x1DC1]={
+ category="mn",
+ description="COMBINING DOTTED ACUTE ACCENT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC1,
+ },
+ [0x1DC2]={
+ category="mn",
+ description="COMBINING SNAKE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC2,
+ },
+ [0x1DC3]={
+ category="mn",
+ description="COMBINING SUSPENSION MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC3,
+ },
+ [0x1DC4]={
+ category="mn",
+ description="COMBINING MACRON-ACUTE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC4,
+ },
+ [0x1DC5]={
+ category="mn",
+ description="COMBINING GRAVE-MACRON",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC5,
+ },
+ [0x1DC6]={
+ category="mn",
+ description="COMBINING MACRON-GRAVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC6,
+ },
+ [0x1DC7]={
+ category="mn",
+ description="COMBINING ACUTE-MACRON",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC7,
+ },
+ [0x1DC8]={
+ category="mn",
+ description="COMBINING GRAVE-ACUTE-GRAVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC8,
+ },
+ [0x1DC9]={
+ category="mn",
+ description="COMBINING ACUTE-GRAVE-ACUTE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DC9,
+ },
+ [0x1DCA]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER R BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DCA,
+ },
+ [0x1DCB]={
+ category="mn",
+ description="COMBINING BREVE-MACRON",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DCB,
+ },
+ [0x1DCC]={
+ category="mn",
+ description="COMBINING MACRON-BREVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DCC,
+ },
+ [0x1DCD]={
+ category="mn",
+ description="COMBINING DOUBLE CIRCUMFLEX ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DCD,
+ },
+ [0x1DCE]={
+ category="mn",
+ description="COMBINING OGONEK ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DCE,
+ },
+ [0x1DCF]={
+ category="mn",
+ description="COMBINING ZIGZAG BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DCF,
+ },
+ [0x1DD0]={
+ category="mn",
+ description="COMBINING IS BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD0,
+ },
+ [0x1DD1]={
+ category="mn",
+ description="COMBINING UR ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD1,
+ },
+ [0x1DD2]={
+ category="mn",
+ description="COMBINING US ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD2,
+ },
+ [0x1DD3]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD3,
+ },
+ [0x1DD4]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER AE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD4,
+ },
+ [0x1DD5]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER AO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD5,
+ },
+ [0x1DD6]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER AV",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD6,
+ },
+ [0x1DD7]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER C CEDILLA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD7,
+ },
+ [0x1DD8]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER INSULAR D",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD8,
+ },
+ [0x1DD9]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER ETH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DD9,
+ },
+ [0x1DDA]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER G",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DDA,
+ },
+ [0x1DDB]={
+ category="mn",
+ description="COMBINING LATIN LETTER SMALL CAPITAL G",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DDB,
+ },
+ [0x1DDC]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER K",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DDC,
+ },
+ [0x1DDD]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER L",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DDD,
+ },
+ [0x1DDE]={
+ category="mn",
+ description="COMBINING LATIN LETTER SMALL CAPITAL L",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DDE,
+ },
+ [0x1DDF]={
+ category="mn",
+ description="COMBINING LATIN LETTER SMALL CAPITAL M",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DDF,
+ },
+ [0x1DE0]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER N",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE0,
+ },
+ [0x1DE1]={
+ category="mn",
+ description="COMBINING LATIN LETTER SMALL CAPITAL N",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE1,
+ },
+ [0x1DE2]={
+ category="mn",
+ description="COMBINING LATIN LETTER SMALL CAPITAL R",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE2,
+ },
+ [0x1DE3]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER R ROTUNDA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE3,
+ },
+ [0x1DE4]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER S",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE4,
+ },
+ [0x1DE5]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER LONG S",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE5,
+ },
+ [0x1DE6]={
+ category="mn",
+ description="COMBINING LATIN SMALL LETTER Z",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DE6,
+ },
+ [0x1DFC]={
+ category="mn",
+ description="COMBINING DOUBLE INVERTED BREVE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DFC,
+ },
+ [0x1DFD]={
+ category="mn",
+ description="COMBINING ALMOST EQUAL TO BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DFD,
+ },
+ [0x1DFE]={
+ category="mn",
+ description="COMBINING LEFT ARROWHEAD ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DFE,
+ },
+ [0x1DFF]={
+ category="mn",
+ description="COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1DFF,
+ },
+ [0x1E00]={
+ adobename="Aringbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER A WITH RING BELOW",
+ direction="l",
+ lccode=0x1E01,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0325 },
+ unicodeslot=0x1E00,
+ },
+ [0x1E01]={
+ adobename="aringbelow",
+ category="ll",
+ description="LATIN SMALL LETTER A WITH RING BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0325 },
+ uccode=0x1E00,
+ unicodeslot=0x1E01,
+ },
+ [0x1E02]={
+ adobename="Bdotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER B WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E03,
+ linebreak="al",
+ shcode=0x0042,
+ specials={ "char", 0x0042, 0x0307 },
+ unicodeslot=0x1E02,
+ },
+ [0x1E03]={
+ adobename="bdotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER B WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0062,
+ specials={ "char", 0x0062, 0x0307 },
+ uccode=0x1E02,
+ unicodeslot=0x1E03,
+ },
+ [0x1E04]={
+ adobename="Bdotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER B WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E05,
+ linebreak="al",
+ shcode=0x0042,
+ specials={ "char", 0x0042, 0x0323 },
+ unicodeslot=0x1E04,
+ },
+ [0x1E05]={
+ adobename="bdotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER B WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0062,
+ specials={ "char", 0x0062, 0x0323 },
+ uccode=0x1E04,
+ unicodeslot=0x1E05,
+ },
+ [0x1E06]={
+ adobename="Blinebelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER B WITH LINE BELOW",
+ direction="l",
+ lccode=0x1E07,
+ linebreak="al",
+ shcode=0x0042,
+ specials={ "char", 0x0042, 0x0331 },
+ unicodeslot=0x1E06,
+ },
+ [0x1E07]={
+ adobename="blinebelow",
+ category="ll",
+ description="LATIN SMALL LETTER B WITH LINE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0062,
+ specials={ "char", 0x0062, 0x0331 },
+ uccode=0x1E06,
+ unicodeslot=0x1E07,
+ },
+ [0x1E08]={
+ adobename="Ccedillaacute",
+ category="lu",
+ description="LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE",
+ direction="l",
+ lccode=0x1E09,
+ linebreak="al",
+ shcode=0x0043,
+ specials={ "char", 0x00C7, 0x0301 },
+ unicodeslot=0x1E08,
+ },
+ [0x1E09]={
+ adobename="ccedillaacute",
+ category="ll",
+ description="LATIN SMALL LETTER C WITH CEDILLA AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0063,
+ specials={ "char", 0x00E7, 0x0301 },
+ uccode=0x1E08,
+ unicodeslot=0x1E09,
+ },
+ [0x1E0A]={
+ adobename="Ddotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER D WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E0B,
+ linebreak="al",
+ shcode=0x0044,
+ specials={ "char", 0x0044, 0x0307 },
+ unicodeslot=0x1E0A,
+ },
+ [0x1E0B]={
+ adobename="ddotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER D WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ specials={ "char", 0x0064, 0x0307 },
+ uccode=0x1E0A,
+ unicodeslot=0x1E0B,
+ },
+ [0x1E0C]={
+ adobename="Ddotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER D WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E0D,
+ linebreak="al",
+ shcode=0x0044,
+ specials={ "char", 0x0044, 0x0323 },
+ unicodeslot=0x1E0C,
+ },
+ [0x1E0D]={
+ adobename="ddotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER D WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ specials={ "char", 0x0064, 0x0323 },
+ uccode=0x1E0C,
+ unicodeslot=0x1E0D,
+ },
+ [0x1E0E]={
+ adobename="Dlinebelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER D WITH LINE BELOW",
+ direction="l",
+ lccode=0x1E0F,
+ linebreak="al",
+ shcode=0x0044,
+ specials={ "char", 0x0044, 0x0331 },
+ unicodeslot=0x1E0E,
+ },
+ [0x1E0F]={
+ adobename="dlinebelow",
+ category="ll",
+ description="LATIN SMALL LETTER D WITH LINE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ specials={ "char", 0x0064, 0x0331 },
+ uccode=0x1E0E,
+ unicodeslot=0x1E0F,
+ },
+ [0x1E10]={
+ adobename="Dcedilla",
+ category="lu",
+ description="LATIN CAPITAL LETTER D WITH CEDILLA",
+ direction="l",
+ lccode=0x1E11,
+ linebreak="al",
+ shcode=0x0044,
+ specials={ "char", 0x0044, 0x0327 },
+ unicodeslot=0x1E10,
+ },
+ [0x1E11]={
+ adobename="dcedilla",
+ category="ll",
+ description="LATIN SMALL LETTER D WITH CEDILLA",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ specials={ "char", 0x0064, 0x0327 },
+ uccode=0x1E10,
+ unicodeslot=0x1E11,
+ },
+ [0x1E12]={
+ adobename="Dcircumflexbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW",
+ direction="l",
+ lccode=0x1E13,
+ linebreak="al",
+ shcode=0x0044,
+ specials={ "char", 0x0044, 0x032D },
+ unicodeslot=0x1E12,
+ },
+ [0x1E13]={
+ adobename="dcircumflexbelow",
+ category="ll",
+ description="LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0064,
+ specials={ "char", 0x0064, 0x032D },
+ uccode=0x1E12,
+ unicodeslot=0x1E13,
+ },
+ [0x1E14]={
+ adobename="Emacrongrave",
+ category="lu",
+ description="LATIN CAPITAL LETTER E WITH MACRON AND GRAVE",
+ direction="l",
+ lccode=0x1E15,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0112, 0x0300 },
+ unicodeslot=0x1E14,
+ },
+ [0x1E15]={
+ adobename="emacrongrave",
+ category="ll",
+ description="LATIN SMALL LETTER E WITH MACRON AND GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0113, 0x0300 },
+ uccode=0x1E14,
+ unicodeslot=0x1E15,
+ },
+ [0x1E16]={
+ adobename="Emacronacute",
+ category="lu",
+ description="LATIN CAPITAL LETTER E WITH MACRON AND ACUTE",
+ direction="l",
+ lccode=0x1E17,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0112, 0x0301 },
+ unicodeslot=0x1E16,
+ },
+ [0x1E17]={
+ adobename="emacronacute",
+ category="ll",
+ description="LATIN SMALL LETTER E WITH MACRON AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0113, 0x0301 },
+ uccode=0x1E16,
+ unicodeslot=0x1E17,
+ },
+ [0x1E18]={
+ adobename="Ecircumflexbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW",
+ direction="l",
+ lccode=0x1E19,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x032D },
+ unicodeslot=0x1E18,
+ },
+ [0x1E19]={
+ adobename="ecircumflexbelow",
+ category="ll",
+ description="LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x032D },
+ uccode=0x1E18,
+ unicodeslot=0x1E19,
+ },
+ [0x1E1A]={
+ adobename="Etildebelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER E WITH TILDE BELOW",
+ direction="l",
+ lccode=0x1E1B,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0330 },
+ unicodeslot=0x1E1A,
+ },
+ [0x1E1B]={
+ adobename="etildebelow",
+ category="ll",
+ description="LATIN SMALL LETTER E WITH TILDE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0330 },
+ uccode=0x1E1A,
+ unicodeslot=0x1E1B,
+ },
+ [0x1E1C]={
+ adobename="Ecedillabreve",
+ category="lu",
+ description="LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE",
+ direction="l",
+ lccode=0x1E1D,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0228, 0x0306 },
+ unicodeslot=0x1E1C,
+ },
+ [0x1E1D]={
+ adobename="ecedillabreve",
+ category="ll",
+ description="LATIN SMALL LETTER E WITH CEDILLA AND BREVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0229, 0x0306 },
+ uccode=0x1E1C,
+ unicodeslot=0x1E1D,
+ },
+ [0x1E1E]={
+ adobename="Fdotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER F WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E1F,
+ linebreak="al",
+ shcode=0x0046,
+ specials={ "char", 0x0046, 0x0307 },
+ unicodeslot=0x1E1E,
+ },
+ [0x1E1F]={
+ adobename="fdotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER F WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0066,
+ specials={ "char", 0x0066, 0x0307 },
+ uccode=0x1E1E,
+ unicodeslot=0x1E1F,
+ },
+ [0x1E20]={
+ adobename="Gmacron",
+ category="lu",
+ description="LATIN CAPITAL LETTER G WITH MACRON",
+ direction="l",
+ lccode=0x1E21,
+ linebreak="al",
+ shcode=0x0047,
+ specials={ "char", 0x0047, 0x0304 },
+ unicodeslot=0x1E20,
+ },
+ [0x1E21]={
+ adobename="gmacron",
+ category="ll",
+ description="LATIN SMALL LETTER G WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0067,
+ specials={ "char", 0x0067, 0x0304 },
+ uccode=0x1E20,
+ unicodeslot=0x1E21,
+ },
+ [0x1E22]={
+ adobename="Hdotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER H WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E23,
+ linebreak="al",
+ shcode=0x0048,
+ specials={ "char", 0x0048, 0x0307 },
+ unicodeslot=0x1E22,
+ },
+ [0x1E23]={
+ adobename="hdotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER H WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0068,
+ specials={ "char", 0x0068, 0x0307 },
+ uccode=0x1E22,
+ unicodeslot=0x1E23,
+ },
+ [0x1E24]={
+ adobename="Hdotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER H WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E25,
+ linebreak="al",
+ shcode=0x0048,
+ specials={ "char", 0x0048, 0x0323 },
+ unicodeslot=0x1E24,
+ },
+ [0x1E25]={
+ adobename="hdotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER H WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0068,
+ specials={ "char", 0x0068, 0x0323 },
+ uccode=0x1E24,
+ unicodeslot=0x1E25,
+ },
+ [0x1E26]={
+ adobename="Hdieresis",
+ category="lu",
+ description="LATIN CAPITAL LETTER H WITH DIAERESIS",
+ direction="l",
+ lccode=0x1E27,
+ linebreak="al",
+ shcode=0x0048,
+ specials={ "char", 0x0048, 0x0308 },
+ unicodeslot=0x1E26,
+ },
+ [0x1E27]={
+ adobename="hdieresis",
+ category="ll",
+ description="LATIN SMALL LETTER H WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0068,
+ specials={ "char", 0x0068, 0x0308 },
+ uccode=0x1E26,
+ unicodeslot=0x1E27,
+ },
+ [0x1E28]={
+ adobename="Hcedilla",
+ category="lu",
+ description="LATIN CAPITAL LETTER H WITH CEDILLA",
+ direction="l",
+ lccode=0x1E29,
+ linebreak="al",
+ shcode=0x0048,
+ specials={ "char", 0x0048, 0x0327 },
+ unicodeslot=0x1E28,
+ },
+ [0x1E29]={
+ adobename="hcedilla",
+ category="ll",
+ description="LATIN SMALL LETTER H WITH CEDILLA",
+ direction="l",
+ linebreak="al",
+ shcode=0x0068,
+ specials={ "char", 0x0068, 0x0327 },
+ uccode=0x1E28,
+ unicodeslot=0x1E29,
+ },
+ [0x1E2A]={
+ adobename="Hbrevebelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER H WITH BREVE BELOW",
+ direction="l",
+ lccode=0x1E2B,
+ linebreak="al",
+ shcode=0x0048,
+ specials={ "char", 0x0048, 0x032E },
+ unicodeslot=0x1E2A,
+ },
+ [0x1E2B]={
+ adobename="hbrevebelow",
+ category="ll",
+ description="LATIN SMALL LETTER H WITH BREVE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0068,
+ specials={ "char", 0x0068, 0x032E },
+ uccode=0x1E2A,
+ unicodeslot=0x1E2B,
+ },
+ [0x1E2C]={
+ adobename="Itildebelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER I WITH TILDE BELOW",
+ direction="l",
+ lccode=0x1E2D,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0330 },
+ unicodeslot=0x1E2C,
+ },
+ [0x1E2D]={
+ adobename="itildebelow",
+ category="ll",
+ description="LATIN SMALL LETTER I WITH TILDE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x0330 },
+ uccode=0x1E2C,
+ unicodeslot=0x1E2D,
+ },
+ [0x1E2E]={
+ adobename="Idieresisacute",
+ category="lu",
+ description="LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE",
+ direction="l",
+ lccode=0x1E2F,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x00CF, 0x0301 },
+ unicodeslot=0x1E2E,
+ },
+ [0x1E2F]={
+ adobename="idieresisacute",
+ category="ll",
+ description="LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x00EF, 0x0301 },
+ uccode=0x1E2E,
+ unicodeslot=0x1E2F,
+ },
+ [0x1E30]={
+ adobename="Kacute",
+ category="lu",
+ description="LATIN CAPITAL LETTER K WITH ACUTE",
+ direction="l",
+ lccode=0x1E31,
+ linebreak="al",
+ shcode=0x004B,
+ specials={ "char", 0x004B, 0x0301 },
+ unicodeslot=0x1E30,
+ },
+ [0x1E31]={
+ adobename="kacute",
+ category="ll",
+ description="LATIN SMALL LETTER K WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006B,
+ specials={ "char", 0x006B, 0x0301 },
+ uccode=0x1E30,
+ unicodeslot=0x1E31,
+ },
+ [0x1E32]={
+ adobename="Kdotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER K WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E33,
+ linebreak="al",
+ shcode=0x004B,
+ specials={ "char", 0x004B, 0x0323 },
+ unicodeslot=0x1E32,
+ },
+ [0x1E33]={
+ adobename="kdotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER K WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x006B,
+ specials={ "char", 0x006B, 0x0323 },
+ uccode=0x1E32,
+ unicodeslot=0x1E33,
+ },
+ [0x1E34]={
+ adobename="Klinebelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER K WITH LINE BELOW",
+ direction="l",
+ lccode=0x1E35,
+ linebreak="al",
+ shcode=0x004B,
+ specials={ "char", 0x004B, 0x0331 },
+ unicodeslot=0x1E34,
+ },
+ [0x1E35]={
+ adobename="klinebelow",
+ category="ll",
+ description="LATIN SMALL LETTER K WITH LINE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x006B,
+ specials={ "char", 0x006B, 0x0331 },
+ uccode=0x1E34,
+ unicodeslot=0x1E35,
+ },
+ [0x1E36]={
+ adobename="Ldotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER L WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E37,
+ linebreak="al",
+ shcode=0x004C,
+ specials={ "char", 0x004C, 0x0323 },
+ unicodeslot=0x1E36,
+ },
+ [0x1E37]={
+ adobename="ldotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER L WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ specials={ "char", 0x006C, 0x0323 },
+ uccode=0x1E36,
+ unicodeslot=0x1E37,
+ },
+ [0x1E38]={
+ adobename="Ldotbelowmacron",
+ category="lu",
+ description="LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON",
+ direction="l",
+ lccode=0x1E39,
+ linebreak="al",
+ shcode=0x004C,
+ specials={ "char", 0x1E36, 0x0304 },
+ unicodeslot=0x1E38,
+ },
+ [0x1E39]={
+ adobename="ldotbelowmacron",
+ category="ll",
+ description="LATIN SMALL LETTER L WITH DOT BELOW AND MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ specials={ "char", 0x1E37, 0x0304 },
+ uccode=0x1E38,
+ unicodeslot=0x1E39,
+ },
+ [0x1E3A]={
+ adobename="Llinebelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER L WITH LINE BELOW",
+ direction="l",
+ lccode=0x1E3B,
+ linebreak="al",
+ shcode=0x004C,
+ specials={ "char", 0x004C, 0x0331 },
+ unicodeslot=0x1E3A,
+ },
+ [0x1E3B]={
+ adobename="llinebelow",
+ category="ll",
+ description="LATIN SMALL LETTER L WITH LINE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ specials={ "char", 0x006C, 0x0331 },
+ uccode=0x1E3A,
+ unicodeslot=0x1E3B,
+ },
+ [0x1E3C]={
+ adobename="Lcircumflexbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW",
+ direction="l",
+ lccode=0x1E3D,
+ linebreak="al",
+ shcode=0x004C,
+ specials={ "char", 0x004C, 0x032D },
+ unicodeslot=0x1E3C,
+ },
+ [0x1E3D]={
+ adobename="lcircumflexbelow",
+ category="ll",
+ description="LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ specials={ "char", 0x006C, 0x032D },
+ uccode=0x1E3C,
+ unicodeslot=0x1E3D,
+ },
+ [0x1E3E]={
+ adobename="Macute",
+ category="lu",
+ description="LATIN CAPITAL LETTER M WITH ACUTE",
+ direction="l",
+ lccode=0x1E3F,
+ linebreak="al",
+ shcode=0x004D,
+ specials={ "char", 0x004D, 0x0301 },
+ unicodeslot=0x1E3E,
+ },
+ [0x1E3F]={
+ adobename="macute",
+ category="ll",
+ description="LATIN SMALL LETTER M WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006D,
+ specials={ "char", 0x006D, 0x0301 },
+ uccode=0x1E3E,
+ unicodeslot=0x1E3F,
+ },
+ [0x1E40]={
+ adobename="Mdotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER M WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E41,
+ linebreak="al",
+ shcode=0x004D,
+ specials={ "char", 0x004D, 0x0307 },
+ unicodeslot=0x1E40,
+ },
+ [0x1E41]={
+ adobename="mdotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER M WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006D,
+ specials={ "char", 0x006D, 0x0307 },
+ uccode=0x1E40,
+ unicodeslot=0x1E41,
+ },
+ [0x1E42]={
+ adobename="Mdotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER M WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E43,
+ linebreak="al",
+ shcode=0x004D,
+ specials={ "char", 0x004D, 0x0323 },
+ unicodeslot=0x1E42,
+ },
+ [0x1E43]={
+ adobename="mdotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER M WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x006D,
+ specials={ "char", 0x006D, 0x0323 },
+ uccode=0x1E42,
+ unicodeslot=0x1E43,
+ },
+ [0x1E44]={
+ adobename="Ndotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER N WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E45,
+ linebreak="al",
+ shcode=0x004E,
+ specials={ "char", 0x004E, 0x0307 },
+ unicodeslot=0x1E44,
+ },
+ [0x1E45]={
+ adobename="ndotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER N WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ specials={ "char", 0x006E, 0x0307 },
+ uccode=0x1E44,
+ unicodeslot=0x1E45,
+ },
+ [0x1E46]={
+ adobename="Ndotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER N WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E47,
+ linebreak="al",
+ shcode=0x004E,
+ specials={ "char", 0x004E, 0x0323 },
+ unicodeslot=0x1E46,
+ },
+ [0x1E47]={
+ adobename="ndotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER N WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ specials={ "char", 0x006E, 0x0323 },
+ uccode=0x1E46,
+ unicodeslot=0x1E47,
+ },
+ [0x1E48]={
+ adobename="Nlinebelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER N WITH LINE BELOW",
+ direction="l",
+ lccode=0x1E49,
+ linebreak="al",
+ shcode=0x004E,
+ specials={ "char", 0x004E, 0x0331 },
+ unicodeslot=0x1E48,
+ },
+ [0x1E49]={
+ adobename="nlinebelow",
+ category="ll",
+ description="LATIN SMALL LETTER N WITH LINE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ specials={ "char", 0x006E, 0x0331 },
+ uccode=0x1E48,
+ unicodeslot=0x1E49,
+ },
+ [0x1E4A]={
+ adobename="Ncircumflexbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW",
+ direction="l",
+ lccode=0x1E4B,
+ linebreak="al",
+ shcode=0x004E,
+ specials={ "char", 0x004E, 0x032D },
+ unicodeslot=0x1E4A,
+ },
+ [0x1E4B]={
+ adobename="ncircumflexbelow",
+ category="ll",
+ description="LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x006E,
+ specials={ "char", 0x006E, 0x032D },
+ uccode=0x1E4A,
+ unicodeslot=0x1E4B,
+ },
+ [0x1E4C]={
+ adobename="Otildeacute",
+ category="lu",
+ description="LATIN CAPITAL LETTER O WITH TILDE AND ACUTE",
+ direction="l",
+ lccode=0x1E4D,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x00D5, 0x0301 },
+ unicodeslot=0x1E4C,
+ },
+ [0x1E4D]={
+ adobename="otildeacute",
+ category="ll",
+ description="LATIN SMALL LETTER O WITH TILDE AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x00F5, 0x0301 },
+ uccode=0x1E4C,
+ unicodeslot=0x1E4D,
+ },
+ [0x1E4E]={
+ adobename="Otildedieresis",
+ category="lu",
+ description="LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS",
+ direction="l",
+ lccode=0x1E4F,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x00D5, 0x0308 },
+ unicodeslot=0x1E4E,
+ },
+ [0x1E4F]={
+ adobename="otildedieresis",
+ category="ll",
+ description="LATIN SMALL LETTER O WITH TILDE AND DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x00F5, 0x0308 },
+ uccode=0x1E4E,
+ unicodeslot=0x1E4F,
+ },
+ [0x1E50]={
+ adobename="Omacrongrave",
+ category="lu",
+ description="LATIN CAPITAL LETTER O WITH MACRON AND GRAVE",
+ direction="l",
+ lccode=0x1E51,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x014C, 0x0300 },
+ unicodeslot=0x1E50,
+ },
+ [0x1E51]={
+ adobename="omacrongrave",
+ category="ll",
+ description="LATIN SMALL LETTER O WITH MACRON AND GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x014D, 0x0300 },
+ uccode=0x1E50,
+ unicodeslot=0x1E51,
+ },
+ [0x1E52]={
+ adobename="Omacronacute",
+ category="lu",
+ description="LATIN CAPITAL LETTER O WITH MACRON AND ACUTE",
+ direction="l",
+ lccode=0x1E53,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x014C, 0x0301 },
+ unicodeslot=0x1E52,
+ },
+ [0x1E53]={
+ adobename="omacronacute",
+ category="ll",
+ description="LATIN SMALL LETTER O WITH MACRON AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x014D, 0x0301 },
+ uccode=0x1E52,
+ unicodeslot=0x1E53,
+ },
+ [0x1E54]={
+ adobename="Pacute",
+ category="lu",
+ description="LATIN CAPITAL LETTER P WITH ACUTE",
+ direction="l",
+ lccode=0x1E55,
+ linebreak="al",
+ shcode=0x0050,
+ specials={ "char", 0x0050, 0x0301 },
+ unicodeslot=0x1E54,
+ },
+ [0x1E55]={
+ adobename="pacute",
+ category="ll",
+ description="LATIN SMALL LETTER P WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0070,
+ specials={ "char", 0x0070, 0x0301 },
+ uccode=0x1E54,
+ unicodeslot=0x1E55,
+ },
+ [0x1E56]={
+ adobename="Pdotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER P WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E57,
+ linebreak="al",
+ shcode=0x0050,
+ specials={ "char", 0x0050, 0x0307 },
+ unicodeslot=0x1E56,
+ },
+ [0x1E57]={
+ adobename="pdotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER P WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0070,
+ specials={ "char", 0x0070, 0x0307 },
+ uccode=0x1E56,
+ unicodeslot=0x1E57,
+ },
+ [0x1E58]={
+ adobename="Rdotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER R WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E59,
+ linebreak="al",
+ shcode=0x0052,
+ specials={ "char", 0x0052, 0x0307 },
+ unicodeslot=0x1E58,
+ },
+ [0x1E59]={
+ adobename="rdotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER R WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ specials={ "char", 0x0072, 0x0307 },
+ uccode=0x1E58,
+ unicodeslot=0x1E59,
+ },
+ [0x1E5A]={
+ adobename="Rdotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER R WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E5B,
+ linebreak="al",
+ shcode=0x0052,
+ specials={ "char", 0x0052, 0x0323 },
+ unicodeslot=0x1E5A,
+ },
+ [0x1E5B]={
+ adobename="rdotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER R WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ specials={ "char", 0x0072, 0x0323 },
+ uccode=0x1E5A,
+ unicodeslot=0x1E5B,
+ },
+ [0x1E5C]={
+ adobename="Rdotbelowmacron",
+ category="lu",
+ description="LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON",
+ direction="l",
+ lccode=0x1E5D,
+ linebreak="al",
+ shcode=0x0052,
+ specials={ "char", 0x1E5A, 0x0304 },
+ unicodeslot=0x1E5C,
+ },
+ [0x1E5D]={
+ adobename="rdotbelowmacron",
+ category="ll",
+ description="LATIN SMALL LETTER R WITH DOT BELOW AND MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ specials={ "char", 0x1E5B, 0x0304 },
+ uccode=0x1E5C,
+ unicodeslot=0x1E5D,
+ },
+ [0x1E5E]={
+ adobename="Rlinebelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER R WITH LINE BELOW",
+ direction="l",
+ lccode=0x1E5F,
+ linebreak="al",
+ shcode=0x0052,
+ specials={ "char", 0x0052, 0x0331 },
+ unicodeslot=0x1E5E,
+ },
+ [0x1E5F]={
+ adobename="rlinebelow",
+ category="ll",
+ description="LATIN SMALL LETTER R WITH LINE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0072,
+ specials={ "char", 0x0072, 0x0331 },
+ uccode=0x1E5E,
+ unicodeslot=0x1E5F,
+ },
+ [0x1E60]={
+ adobename="Sdotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER S WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E61,
+ linebreak="al",
+ shcode=0x0053,
+ specials={ "char", 0x0053, 0x0307 },
+ unicodeslot=0x1E60,
+ },
+ [0x1E61]={
+ adobename="sdotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER S WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ specials={ "char", 0x0073, 0x0307 },
+ uccode=0x1E60,
+ unicodeslot=0x1E61,
+ },
+ [0x1E62]={
+ adobename="Sdotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER S WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E63,
+ linebreak="al",
+ shcode=0x0053,
+ specials={ "char", 0x0053, 0x0323 },
+ unicodeslot=0x1E62,
+ },
+ [0x1E63]={
+ adobename="sdotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER S WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ specials={ "char", 0x0073, 0x0323 },
+ uccode=0x1E62,
+ unicodeslot=0x1E63,
+ },
+ [0x1E64]={
+ adobename="Sacutedotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE",
+ direction="l",
+ lccode=0x1E65,
+ linebreak="al",
+ shcode=0x0053,
+ specials={ "char", 0x015A, 0x0307 },
+ unicodeslot=0x1E64,
+ },
+ [0x1E65]={
+ adobename="sacutedotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ specials={ "char", 0x015B, 0x0307 },
+ uccode=0x1E64,
+ unicodeslot=0x1E65,
+ },
+ [0x1E66]={
+ adobename="Scarondotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE",
+ direction="l",
+ lccode=0x1E67,
+ linebreak="al",
+ shcode=0x0053,
+ specials={ "char", 0x0160, 0x0307 },
+ unicodeslot=0x1E66,
+ },
+ [0x1E67]={
+ adobename="scarondotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER S WITH CARON AND DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ specials={ "char", 0x0161, 0x0307 },
+ uccode=0x1E66,
+ unicodeslot=0x1E67,
+ },
+ [0x1E68]={
+ adobename="Sdotbelowdotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE",
+ direction="l",
+ lccode=0x1E69,
+ linebreak="al",
+ shcode=0x0053,
+ specials={ "char", 0x1E62, 0x0307 },
+ unicodeslot=0x1E68,
+ },
+ [0x1E69]={
+ adobename="sdotbelowdotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0073,
+ specials={ "char", 0x1E63, 0x0307 },
+ uccode=0x1E68,
+ unicodeslot=0x1E69,
+ },
+ [0x1E6A]={
+ adobename="Tdotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER T WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E6B,
+ linebreak="al",
+ shcode=0x0054,
+ specials={ "char", 0x0054, 0x0307 },
+ unicodeslot=0x1E6A,
+ },
+ [0x1E6B]={
+ adobename="tdotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER T WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ specials={ "char", 0x0074, 0x0307 },
+ uccode=0x1E6A,
+ unicodeslot=0x1E6B,
+ },
+ [0x1E6C]={
+ adobename="Tdotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER T WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E6D,
+ linebreak="al",
+ shcode=0x0054,
+ specials={ "char", 0x0054, 0x0323 },
+ unicodeslot=0x1E6C,
+ },
+ [0x1E6D]={
+ adobename="tdotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER T WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ specials={ "char", 0x0074, 0x0323 },
+ uccode=0x1E6C,
+ unicodeslot=0x1E6D,
+ },
+ [0x1E6E]={
+ adobename="Tlinebelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER T WITH LINE BELOW",
+ direction="l",
+ lccode=0x1E6F,
+ linebreak="al",
+ shcode=0x0054,
+ specials={ "char", 0x0054, 0x0331 },
+ unicodeslot=0x1E6E,
+ },
+ [0x1E6F]={
+ adobename="tlinebelow",
+ category="ll",
+ description="LATIN SMALL LETTER T WITH LINE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ specials={ "char", 0x0074, 0x0331 },
+ uccode=0x1E6E,
+ unicodeslot=0x1E6F,
+ },
+ [0x1E70]={
+ adobename="Tcircumflexbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW",
+ direction="l",
+ lccode=0x1E71,
+ linebreak="al",
+ shcode=0x0054,
+ specials={ "char", 0x0054, 0x032D },
+ unicodeslot=0x1E70,
+ },
+ [0x1E71]={
+ adobename="tcircumflexbelow",
+ category="ll",
+ description="LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ specials={ "char", 0x0074, 0x032D },
+ uccode=0x1E70,
+ unicodeslot=0x1E71,
+ },
+ [0x1E72]={
+ adobename="Udieresisbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER U WITH DIAERESIS BELOW",
+ direction="l",
+ lccode=0x1E73,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0324 },
+ unicodeslot=0x1E72,
+ },
+ [0x1E73]={
+ adobename="udieresisbelow",
+ category="ll",
+ description="LATIN SMALL LETTER U WITH DIAERESIS BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0324 },
+ uccode=0x1E72,
+ unicodeslot=0x1E73,
+ },
+ [0x1E74]={
+ adobename="Utildebelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER U WITH TILDE BELOW",
+ direction="l",
+ lccode=0x1E75,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0330 },
+ unicodeslot=0x1E74,
+ },
+ [0x1E75]={
+ adobename="utildebelow",
+ category="ll",
+ description="LATIN SMALL LETTER U WITH TILDE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0330 },
+ uccode=0x1E74,
+ unicodeslot=0x1E75,
+ },
+ [0x1E76]={
+ adobename="Ucircumflexbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW",
+ direction="l",
+ lccode=0x1E77,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x032D },
+ unicodeslot=0x1E76,
+ },
+ [0x1E77]={
+ adobename="ucircumflexbelow",
+ category="ll",
+ description="LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x032D },
+ uccode=0x1E76,
+ unicodeslot=0x1E77,
+ },
+ [0x1E78]={
+ adobename="Utildeacute",
+ category="lu",
+ description="LATIN CAPITAL LETTER U WITH TILDE AND ACUTE",
+ direction="l",
+ lccode=0x1E79,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0168, 0x0301 },
+ unicodeslot=0x1E78,
+ },
+ [0x1E79]={
+ adobename="utildeacute",
+ category="ll",
+ description="LATIN SMALL LETTER U WITH TILDE AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0169, 0x0301 },
+ uccode=0x1E78,
+ unicodeslot=0x1E79,
+ },
+ [0x1E7A]={
+ adobename="Umacrondieresis",
+ category="lu",
+ description="LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS",
+ direction="l",
+ lccode=0x1E7B,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x016A, 0x0308 },
+ unicodeslot=0x1E7A,
+ },
+ [0x1E7B]={
+ adobename="umacrondieresis",
+ category="ll",
+ description="LATIN SMALL LETTER U WITH MACRON AND DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x016B, 0x0308 },
+ uccode=0x1E7A,
+ unicodeslot=0x1E7B,
+ },
+ [0x1E7C]={
+ adobename="Vtilde",
+ category="lu",
+ description="LATIN CAPITAL LETTER V WITH TILDE",
+ direction="l",
+ lccode=0x1E7D,
+ linebreak="al",
+ shcode=0x0056,
+ specials={ "char", 0x0056, 0x0303 },
+ unicodeslot=0x1E7C,
+ },
+ [0x1E7D]={
+ adobename="vtilde",
+ category="ll",
+ description="LATIN SMALL LETTER V WITH TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0076,
+ specials={ "char", 0x0076, 0x0303 },
+ uccode=0x1E7C,
+ unicodeslot=0x1E7D,
+ },
+ [0x1E7E]={
+ adobename="Vdotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER V WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E7F,
+ linebreak="al",
+ shcode=0x0056,
+ specials={ "char", 0x0056, 0x0323 },
+ unicodeslot=0x1E7E,
+ },
+ [0x1E7F]={
+ adobename="vdotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER V WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0076,
+ specials={ "char", 0x0076, 0x0323 },
+ uccode=0x1E7E,
+ unicodeslot=0x1E7F,
+ },
+ [0x1E80]={
+ adobename="Wgrave",
+ category="lu",
+ description="LATIN CAPITAL LETTER W WITH GRAVE",
+ direction="l",
+ lccode=0x1E81,
+ linebreak="al",
+ shcode=0x0057,
+ specials={ "char", 0x0057, 0x0300 },
+ unicodeslot=0x1E80,
+ },
+ [0x1E81]={
+ adobename="wgrave",
+ category="ll",
+ description="LATIN SMALL LETTER W WITH GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0077,
+ specials={ "char", 0x0077, 0x0300 },
+ uccode=0x1E80,
+ unicodeslot=0x1E81,
+ },
+ [0x1E82]={
+ adobename="Wacute",
+ category="lu",
+ description="LATIN CAPITAL LETTER W WITH ACUTE",
+ direction="l",
+ lccode=0x1E83,
+ linebreak="al",
+ shcode=0x0057,
+ specials={ "char", 0x0057, 0x0301 },
+ unicodeslot=0x1E82,
+ },
+ [0x1E83]={
+ adobename="wacute",
+ category="ll",
+ description="LATIN SMALL LETTER W WITH ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0077,
+ specials={ "char", 0x0077, 0x0301 },
+ uccode=0x1E82,
+ unicodeslot=0x1E83,
+ },
+ [0x1E84]={
+ adobename="Wdieresis",
+ category="lu",
+ description="LATIN CAPITAL LETTER W WITH DIAERESIS",
+ direction="l",
+ lccode=0x1E85,
+ linebreak="al",
+ shcode=0x0057,
+ specials={ "char", 0x0057, 0x0308 },
+ unicodeslot=0x1E84,
+ },
+ [0x1E85]={
+ adobename="wdieresis",
+ category="ll",
+ description="LATIN SMALL LETTER W WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0077,
+ specials={ "char", 0x0077, 0x0308 },
+ uccode=0x1E84,
+ unicodeslot=0x1E85,
+ },
+ [0x1E86]={
+ adobename="Wdotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER W WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E87,
+ linebreak="al",
+ shcode=0x0057,
+ specials={ "char", 0x0057, 0x0307 },
+ unicodeslot=0x1E86,
+ },
+ [0x1E87]={
+ adobename="wdotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER W WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0077,
+ specials={ "char", 0x0077, 0x0307 },
+ uccode=0x1E86,
+ unicodeslot=0x1E87,
+ },
+ [0x1E88]={
+ adobename="Wdotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER W WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E89,
+ linebreak="al",
+ shcode=0x0057,
+ specials={ "char", 0x0057, 0x0323 },
+ unicodeslot=0x1E88,
+ },
+ [0x1E89]={
+ adobename="wdotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER W WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0077,
+ specials={ "char", 0x0077, 0x0323 },
+ uccode=0x1E88,
+ unicodeslot=0x1E89,
+ },
+ [0x1E8A]={
+ adobename="Xdotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER X WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E8B,
+ linebreak="al",
+ shcode=0x0058,
+ specials={ "char", 0x0058, 0x0307 },
+ unicodeslot=0x1E8A,
+ },
+ [0x1E8B]={
+ adobename="xdotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER X WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0078,
+ specials={ "char", 0x0078, 0x0307 },
+ uccode=0x1E8A,
+ unicodeslot=0x1E8B,
+ },
+ [0x1E8C]={
+ adobename="Xdieresis",
+ category="lu",
+ description="LATIN CAPITAL LETTER X WITH DIAERESIS",
+ direction="l",
+ lccode=0x1E8D,
+ linebreak="al",
+ shcode=0x0058,
+ specials={ "char", 0x0058, 0x0308 },
+ unicodeslot=0x1E8C,
+ },
+ [0x1E8D]={
+ adobename="xdieresis",
+ category="ll",
+ description="LATIN SMALL LETTER X WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0078,
+ specials={ "char", 0x0078, 0x0308 },
+ uccode=0x1E8C,
+ unicodeslot=0x1E8D,
+ },
+ [0x1E8E]={
+ adobename="Ydotaccent",
+ category="lu",
+ description="LATIN CAPITAL LETTER Y WITH DOT ABOVE",
+ direction="l",
+ lccode=0x1E8F,
+ linebreak="al",
+ shcode=0x0059,
+ specials={ "char", 0x0059, 0x0307 },
+ unicodeslot=0x1E8E,
+ },
+ [0x1E8F]={
+ adobename="ydotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER Y WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0079,
+ specials={ "char", 0x0079, 0x0307 },
+ uccode=0x1E8E,
+ unicodeslot=0x1E8F,
+ },
+ [0x1E90]={
+ adobename="Zcircumflex",
+ category="lu",
+ description="LATIN CAPITAL LETTER Z WITH CIRCUMFLEX",
+ direction="l",
+ lccode=0x1E91,
+ linebreak="al",
+ shcode=0x005A,
+ specials={ "char", 0x005A, 0x0302 },
+ unicodeslot=0x1E90,
+ },
+ [0x1E91]={
+ adobename="zcircumflex",
+ category="ll",
+ description="LATIN SMALL LETTER Z WITH CIRCUMFLEX",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ specials={ "char", 0x007A, 0x0302 },
+ uccode=0x1E90,
+ unicodeslot=0x1E91,
+ },
+ [0x1E92]={
+ adobename="Zdotbelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER Z WITH DOT BELOW",
+ direction="l",
+ lccode=0x1E93,
+ linebreak="al",
+ shcode=0x005A,
+ specials={ "char", 0x005A, 0x0323 },
+ unicodeslot=0x1E92,
+ },
+ [0x1E93]={
+ adobename="zdotbelow",
+ category="ll",
+ description="LATIN SMALL LETTER Z WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ specials={ "char", 0x007A, 0x0323 },
+ uccode=0x1E92,
+ unicodeslot=0x1E93,
+ },
+ [0x1E94]={
+ adobename="Zlinebelow",
+ category="lu",
+ description="LATIN CAPITAL LETTER Z WITH LINE BELOW",
+ direction="l",
+ lccode=0x1E95,
+ linebreak="al",
+ shcode=0x005A,
+ specials={ "char", 0x005A, 0x0331 },
+ unicodeslot=0x1E94,
+ },
+ [0x1E95]={
+ adobename="zlinebelow",
+ category="ll",
+ description="LATIN SMALL LETTER Z WITH LINE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ specials={ "char", 0x007A, 0x0331 },
+ uccode=0x1E94,
+ unicodeslot=0x1E95,
+ },
+ [0x1E96]={
+ adobename="hlinebelow",
+ category="ll",
+ description="LATIN SMALL LETTER H WITH LINE BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0068,
+ specials={ "char", 0x0068, 0x0331 },
+ unicodeslot=0x1E96,
+ },
+ [0x1E97]={
+ adobename="tdieresis",
+ category="ll",
+ description="LATIN SMALL LETTER T WITH DIAERESIS",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ specials={ "char", 0x0074, 0x0308 },
+ unicodeslot=0x1E97,
+ },
+ [0x1E98]={
+ adobename="wring",
+ category="ll",
+ description="LATIN SMALL LETTER W WITH RING ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0077,
+ specials={ "char", 0x0077, 0x030A },
+ unicodeslot=0x1E98,
+ },
+ [0x1E99]={
+ adobename="yring",
+ category="ll",
+ description="LATIN SMALL LETTER Y WITH RING ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0079,
+ specials={ "char", 0x0079, 0x030A },
+ unicodeslot=0x1E99,
+ },
+ [0x1E9A]={
+ adobename="arighthalfring",
+ category="ll",
+ description="LATIN SMALL LETTER A WITH RIGHT HALF RING",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "compat", 0x0061, 0x02BE },
+ unicodeslot=0x1E9A,
+ },
+ [0x1E9B]={
+ adobename="slongdotaccent",
+ category="ll",
+ description="LATIN SMALL LETTER LONG S WITH DOT ABOVE",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x017F, 0x0307 },
+ uccode=0x1E60,
+ unicodeslot=0x1E9B,
+ },
+ [0x1E9C]={
+ category="ll",
+ description="LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E9C,
+ },
+ [0x1E9D]={
+ category="ll",
+ description="LATIN SMALL LETTER LONG S WITH HIGH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E9D,
+ },
+ [0x1E9E]={
+ category="lu",
+ description="LATIN CAPITAL LETTER SHARP S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E9E,
+ },
+ [0x1E9F]={
+ category="ll",
+ description="LATIN SMALL LETTER DELTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1E9F,
+ },
+ [0x1EA0]={
+ adobename="Adotbelow",
+ category="lu",
+ contextname="Adotbelow",
+ description="LATIN CAPITAL LETTER A WITH DOT BELOW",
+ direction="l",
+ lccode=0x1EA1,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0323 },
+ unicodeslot=0x1EA0,
+ },
+ [0x1EA1]={
+ adobename="adotbelow",
+ category="ll",
+ contextname="adotbelow",
+ description="LATIN SMALL LETTER A WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0323 },
+ uccode=0x1EA0,
+ unicodeslot=0x1EA1,
+ },
+ [0x1EA2]={
+ adobename="Ahookabove",
+ category="lu",
+ contextname="Ahook",
+ description="LATIN CAPITAL LETTER A WITH HOOK ABOVE",
+ direction="l",
+ lccode=0x1EA3,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0041, 0x0309 },
+ unicodeslot=0x1EA2,
+ },
+ [0x1EA3]={
+ adobename="ahookabove",
+ category="ll",
+ contextname="ahook",
+ description="LATIN SMALL LETTER A WITH HOOK ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0061, 0x0309 },
+ uccode=0x1EA2,
+ unicodeslot=0x1EA3,
+ },
+ [0x1EA4]={
+ adobename="Acircumflexacute",
+ category="lu",
+ contextname="Acircumflexacute",
+ description="LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE",
+ direction="l",
+ lccode=0x1EA5,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x00C2, 0x0301 },
+ unicodeslot=0x1EA4,
+ },
+ [0x1EA5]={
+ adobename="acircumflexacute",
+ category="ll",
+ contextname="acircumflexacute",
+ description="LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x00E2, 0x0301 },
+ uccode=0x1EA4,
+ unicodeslot=0x1EA5,
+ },
+ [0x1EA6]={
+ adobename="Acircumflexgrave",
+ category="lu",
+ contextname="Acircumflexgrave",
+ description="LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE",
+ direction="l",
+ lccode=0x1EA7,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x00C2, 0x0300 },
+ unicodeslot=0x1EA6,
+ },
+ [0x1EA7]={
+ adobename="acircumflexgrave",
+ category="ll",
+ contextname="acircumflexgrave",
+ description="LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x00E2, 0x0300 },
+ uccode=0x1EA6,
+ unicodeslot=0x1EA7,
+ },
+ [0x1EA8]={
+ adobename="Acircumflexhookabove",
+ category="lu",
+ contextname="Acircumflexhook",
+ description="LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE",
+ direction="l",
+ lccode=0x1EA9,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x00C2, 0x0309 },
+ unicodeslot=0x1EA8,
+ },
+ [0x1EA9]={
+ adobename="acircumflexhookabove",
+ category="ll",
+ contextname="acircumflexhook",
+ description="LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x00E2, 0x0309 },
+ uccode=0x1EA8,
+ unicodeslot=0x1EA9,
+ },
+ [0x1EAA]={
+ adobename="Acircumflextilde",
+ category="lu",
+ contextname="Acircumflextilde",
+ description="LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE",
+ direction="l",
+ lccode=0x1EAB,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x00C2, 0x0303 },
+ unicodeslot=0x1EAA,
+ },
+ [0x1EAB]={
+ adobename="acircumflextilde",
+ category="ll",
+ contextname="acircumflextilde",
+ description="LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x00E2, 0x0303 },
+ uccode=0x1EAA,
+ unicodeslot=0x1EAB,
+ },
+ [0x1EAC]={
+ adobename="Acircumflexdotbelow",
+ category="lu",
+ contextname="Acircumflexdotbelow",
+ description="LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW",
+ direction="l",
+ lccode=0x1EAD,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x1EA0, 0x0302 },
+ unicodeslot=0x1EAC,
+ },
+ [0x1EAD]={
+ adobename="acircumflexdotbelow",
+ category="ll",
+ contextname="acircumflexdotbelow",
+ description="LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x1EA1, 0x0302 },
+ uccode=0x1EAC,
+ unicodeslot=0x1EAD,
+ },
+ [0x1EAE]={
+ adobename="Abreveacute",
+ category="lu",
+ contextname="Abreveacute",
+ description="LATIN CAPITAL LETTER A WITH BREVE AND ACUTE",
+ direction="l",
+ lccode=0x1EAF,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0102, 0x0301 },
+ unicodeslot=0x1EAE,
+ },
+ [0x1EAF]={
+ adobename="abreveacute",
+ category="ll",
+ contextname="abreveacute",
+ description="LATIN SMALL LETTER A WITH BREVE AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0103, 0x0301 },
+ uccode=0x1EAE,
+ unicodeslot=0x1EAF,
+ },
+ [0x1EB0]={
+ adobename="Abrevegrave",
+ category="lu",
+ contextname="Abrevegrave",
+ description="LATIN CAPITAL LETTER A WITH BREVE AND GRAVE",
+ direction="l",
+ lccode=0x1EB1,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0102, 0x0300 },
+ unicodeslot=0x1EB0,
+ },
+ [0x1EB1]={
+ adobename="abrevegrave",
+ category="ll",
+ contextname="abrevegrave",
+ description="LATIN SMALL LETTER A WITH BREVE AND GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0103, 0x0300 },
+ uccode=0x1EB0,
+ unicodeslot=0x1EB1,
+ },
+ [0x1EB2]={
+ adobename="Abrevehookabove",
+ category="lu",
+ contextname="Abrevehook",
+ description="LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE",
+ direction="l",
+ lccode=0x1EB3,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0102, 0x0309 },
+ unicodeslot=0x1EB2,
+ },
+ [0x1EB3]={
+ adobename="abrevehookabove",
+ category="ll",
+ contextname="abrevehook",
+ description="LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0103, 0x0309 },
+ uccode=0x1EB2,
+ unicodeslot=0x1EB3,
+ },
+ [0x1EB4]={
+ adobename="Abrevetilde",
+ category="lu",
+ contextname="Abrevetilde",
+ description="LATIN CAPITAL LETTER A WITH BREVE AND TILDE",
+ direction="l",
+ lccode=0x1EB5,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x0102, 0x0303 },
+ unicodeslot=0x1EB4,
+ },
+ [0x1EB5]={
+ adobename="abrevetilde",
+ category="ll",
+ contextname="abrevetilde",
+ description="LATIN SMALL LETTER A WITH BREVE AND TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x0103, 0x0303 },
+ uccode=0x1EB4,
+ unicodeslot=0x1EB5,
+ },
+ [0x1EB6]={
+ adobename="Abrevedotbelow",
+ category="lu",
+ contextname="Abrevedotbelow",
+ description="LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW",
+ direction="l",
+ lccode=0x1EB7,
+ linebreak="al",
+ shcode=0x0041,
+ specials={ "char", 0x1EA0, 0x0306 },
+ unicodeslot=0x1EB6,
+ },
+ [0x1EB7]={
+ adobename="abrevedotbelow",
+ category="ll",
+ contextname="abrevedotbelow",
+ description="LATIN SMALL LETTER A WITH BREVE AND DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ specials={ "char", 0x1EA1, 0x0306 },
+ uccode=0x1EB6,
+ unicodeslot=0x1EB7,
+ },
+ [0x1EB8]={
+ adobename="Edotbelow",
+ category="lu",
+ contextname="Edotbelow",
+ description="LATIN CAPITAL LETTER E WITH DOT BELOW",
+ direction="l",
+ lccode=0x1EB9,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0323 },
+ unicodeslot=0x1EB8,
+ },
+ [0x1EB9]={
+ adobename="edotbelow",
+ category="ll",
+ contextname="edotbelow",
+ description="LATIN SMALL LETTER E WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0323 },
+ uccode=0x1EB8,
+ unicodeslot=0x1EB9,
+ },
+ [0x1EBA]={
+ adobename="Ehookabove",
+ category="lu",
+ contextname="Ehook",
+ description="LATIN CAPITAL LETTER E WITH HOOK ABOVE",
+ direction="l",
+ lccode=0x1EBB,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0309 },
+ unicodeslot=0x1EBA,
+ },
+ [0x1EBB]={
+ adobename="ehookabove",
+ category="ll",
+ contextname="ehook",
+ description="LATIN SMALL LETTER E WITH HOOK ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0309 },
+ uccode=0x1EBA,
+ unicodeslot=0x1EBB,
+ },
+ [0x1EBC]={
+ adobename="Etilde",
+ category="lu",
+ contextname="Etilde",
+ description="LATIN CAPITAL LETTER E WITH TILDE",
+ direction="l",
+ lccode=0x1EBD,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x0045, 0x0303 },
+ unicodeslot=0x1EBC,
+ },
+ [0x1EBD]={
+ adobename="etilde",
+ category="ll",
+ contextname="etilde",
+ description="LATIN SMALL LETTER E WITH TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x0065, 0x0303 },
+ uccode=0x1EBC,
+ unicodeslot=0x1EBD,
+ },
+ [0x1EBE]={
+ adobename="Ecircumflexacute",
+ category="lu",
+ contextname="Ecircumflexacute",
+ description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE",
+ direction="l",
+ lccode=0x1EBF,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x00CA, 0x0301 },
+ unicodeslot=0x1EBE,
+ },
+ [0x1EBF]={
+ adobename="ecircumflexacute",
+ category="ll",
+ contextname="ecircumflexacute",
+ description="LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x00EA, 0x0301 },
+ uccode=0x1EBE,
+ unicodeslot=0x1EBF,
+ },
+ [0x1EC0]={
+ adobename="Ecircumflexgrave",
+ category="lu",
+ contextname="Ecircumflexgrave",
+ description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE",
+ direction="l",
+ lccode=0x1EC1,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x00CA, 0x0300 },
+ unicodeslot=0x1EC0,
+ },
+ [0x1EC1]={
+ adobename="ecircumflexgrave",
+ category="ll",
+ contextname="ecircumflexgrave",
+ description="LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x00EA, 0x0300 },
+ uccode=0x1EC0,
+ unicodeslot=0x1EC1,
+ },
+ [0x1EC2]={
+ adobename="Ecircumflexhookabove",
+ category="lu",
+ contextname="Ecircumflexhook",
+ description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE",
+ direction="l",
+ lccode=0x1EC3,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x00CA, 0x0309 },
+ unicodeslot=0x1EC2,
+ },
+ [0x1EC3]={
+ adobename="ecircumflexhookabove",
+ category="ll",
+ contextname="ecircumflexhook",
+ description="LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x00EA, 0x0309 },
+ uccode=0x1EC2,
+ unicodeslot=0x1EC3,
+ },
+ [0x1EC4]={
+ adobename="Ecircumflextilde",
+ category="lu",
+ contextname="Ecircumflextilde",
+ description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE",
+ direction="l",
+ lccode=0x1EC5,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x00CA, 0x0303 },
+ unicodeslot=0x1EC4,
+ },
+ [0x1EC5]={
+ adobename="ecircumflextilde",
+ category="ll",
+ contextname="ecircumflextilde",
+ description="LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x00EA, 0x0303 },
+ uccode=0x1EC4,
+ unicodeslot=0x1EC5,
+ },
+ [0x1EC6]={
+ adobename="Ecircumflexdotbelow",
+ category="lu",
+ contextname="Ecircumflexdotbelow",
+ description="LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW",
+ direction="l",
+ lccode=0x1EC7,
+ linebreak="al",
+ shcode=0x0045,
+ specials={ "char", 0x1EB8, 0x0302 },
+ unicodeslot=0x1EC6,
+ },
+ [0x1EC7]={
+ adobename="ecircumflexdotbelow",
+ category="ll",
+ contextname="ecircumflexdotbelow",
+ description="LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0065,
+ specials={ "char", 0x1EB9, 0x0302 },
+ uccode=0x1EC6,
+ unicodeslot=0x1EC7,
+ },
+ [0x1EC8]={
+ adobename="Ihookabove",
+ category="lu",
+ contextname="Ihook",
+ description="LATIN CAPITAL LETTER I WITH HOOK ABOVE",
+ direction="l",
+ lccode=0x1EC9,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0309 },
+ unicodeslot=0x1EC8,
+ },
+ [0x1EC9]={
+ adobename="ihookabove",
+ category="ll",
+ contextname="ihook",
+ description="LATIN SMALL LETTER I WITH HOOK ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x0309 },
+ uccode=0x1EC8,
+ unicodeslot=0x1EC9,
+ },
+ [0x1ECA]={
+ adobename="Idotbelow",
+ category="lu",
+ contextname="Idotbelow",
+ description="LATIN CAPITAL LETTER I WITH DOT BELOW",
+ direction="l",
+ lccode=0x1ECB,
+ linebreak="al",
+ shcode=0x0049,
+ specials={ "char", 0x0049, 0x0323 },
+ unicodeslot=0x1ECA,
+ },
+ [0x1ECB]={
+ adobename="idotbelow",
+ category="ll",
+ contextname="idotbelow",
+ description="LATIN SMALL LETTER I WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0069,
+ specials={ "char", 0x0069, 0x0323 },
+ uccode=0x1ECA,
+ unicodeslot=0x1ECB,
+ },
+ [0x1ECC]={
+ adobename="Odotbelow",
+ category="lu",
+ contextname="Odotbelow",
+ description="LATIN CAPITAL LETTER O WITH DOT BELOW",
+ direction="l",
+ lccode=0x1ECD,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x0323 },
+ unicodeslot=0x1ECC,
+ },
+ [0x1ECD]={
+ adobename="odotbelow",
+ category="ll",
+ contextname="odotbelow",
+ description="LATIN SMALL LETTER O WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x0323 },
+ uccode=0x1ECC,
+ unicodeslot=0x1ECD,
+ },
+ [0x1ECE]={
+ adobename="Ohookabove",
+ category="lu",
+ contextname="Ohook",
+ description="LATIN CAPITAL LETTER O WITH HOOK ABOVE",
+ direction="l",
+ lccode=0x1ECF,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x004F, 0x0309 },
+ unicodeslot=0x1ECE,
+ },
+ [0x1ECF]={
+ adobename="ohookabove",
+ category="ll",
+ contextname="ohook",
+ description="LATIN SMALL LETTER O WITH HOOK ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x006F, 0x0309 },
+ uccode=0x1ECE,
+ unicodeslot=0x1ECF,
+ },
+ [0x1ED0]={
+ adobename="Ocircumflexacute",
+ category="lu",
+ contextname="Ocircumflexacute",
+ description="LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE",
+ direction="l",
+ lccode=0x1ED1,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x00D4, 0x0301 },
+ unicodeslot=0x1ED0,
+ },
+ [0x1ED1]={
+ adobename="ocircumflexacute",
+ category="ll",
+ contextname="ocircumflexacute",
+ description="LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x00F4, 0x0301 },
+ uccode=0x1ED0,
+ unicodeslot=0x1ED1,
+ },
+ [0x1ED2]={
+ adobename="Ocircumflexgrave",
+ category="lu",
+ contextname="Ocircumflexgrave",
+ description="LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE",
+ direction="l",
+ lccode=0x1ED3,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x00D4, 0x0300 },
+ unicodeslot=0x1ED2,
+ },
+ [0x1ED3]={
+ adobename="ocircumflexgrave",
+ category="ll",
+ contextname="ocircumflexgrave",
+ description="LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x00F4, 0x0300 },
+ uccode=0x1ED2,
+ unicodeslot=0x1ED3,
+ },
+ [0x1ED4]={
+ adobename="Ocircumflexhookabove",
+ category="lu",
+ contextname="Ocircumflexhook",
+ description="LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE",
+ direction="l",
+ lccode=0x1ED5,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x00D4, 0x0309 },
+ unicodeslot=0x1ED4,
+ },
+ [0x1ED5]={
+ adobename="ocircumflexhookabove",
+ category="ll",
+ contextname="ocircumflexhook",
+ description="LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x00F4, 0x0309 },
+ uccode=0x1ED4,
+ unicodeslot=0x1ED5,
+ },
+ [0x1ED6]={
+ adobename="Ocircumflextilde",
+ category="lu",
+ contextname="Ocircumflextilde",
+ description="LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE",
+ direction="l",
+ lccode=0x1ED7,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x00D4, 0x0303 },
+ unicodeslot=0x1ED6,
+ },
+ [0x1ED7]={
+ adobename="ocircumflextilde",
+ category="ll",
+ contextname="ocircumflextilde",
+ description="LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x00F4, 0x0303 },
+ uccode=0x1ED6,
+ unicodeslot=0x1ED7,
+ },
+ [0x1ED8]={
+ adobename="Ocircumflexdotbelow",
+ category="lu",
+ contextname="Ocircumflexdotbelow",
+ description="LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW",
+ direction="l",
+ lccode=0x1ED9,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x1ECC, 0x0302 },
+ unicodeslot=0x1ED8,
+ },
+ [0x1ED9]={
+ adobename="ocircumflexdotbelow",
+ category="ll",
+ contextname="ocircumflexdotbelow",
+ description="LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x1ECD, 0x0302 },
+ uccode=0x1ED8,
+ unicodeslot=0x1ED9,
+ },
+ [0x1EDA]={
+ adobename="Ohornacute",
+ category="lu",
+ contextname="Ohornacute",
+ description="LATIN CAPITAL LETTER O WITH HORN AND ACUTE",
+ direction="l",
+ lccode=0x1EDB,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x01A0, 0x0301 },
+ unicodeslot=0x1EDA,
+ },
+ [0x1EDB]={
+ adobename="ohornacute",
+ category="ll",
+ contextname="ohornacute",
+ description="LATIN SMALL LETTER O WITH HORN AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x01A1, 0x0301 },
+ uccode=0x1EDA,
+ unicodeslot=0x1EDB,
+ },
+ [0x1EDC]={
+ adobename="Ohorngrave",
+ category="lu",
+ contextname="Ohorngrave",
+ description="LATIN CAPITAL LETTER O WITH HORN AND GRAVE",
+ direction="l",
+ lccode=0x1EDD,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x01A0, 0x0300 },
+ unicodeslot=0x1EDC,
+ },
+ [0x1EDD]={
+ adobename="ohorngrave",
+ category="ll",
+ contextname="ohorngrave",
+ description="LATIN SMALL LETTER O WITH HORN AND GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x01A1, 0x0300 },
+ uccode=0x1EDC,
+ unicodeslot=0x1EDD,
+ },
+ [0x1EDE]={
+ adobename="Ohornhookabove",
+ category="lu",
+ contextname="Ohornhook",
+ description="LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE",
+ direction="l",
+ lccode=0x1EDF,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x01A0, 0x0309 },
+ unicodeslot=0x1EDE,
+ },
+ [0x1EDF]={
+ adobename="ohornhookabove",
+ category="ll",
+ contextname="ohornhook",
+ description="LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x01A1, 0x0309 },
+ uccode=0x1EDE,
+ unicodeslot=0x1EDF,
+ },
+ [0x1EE0]={
+ adobename="Ohorntilde",
+ category="lu",
+ contextname="Ohorntilde",
+ description="LATIN CAPITAL LETTER O WITH HORN AND TILDE",
+ direction="l",
+ lccode=0x1EE1,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x01A0, 0x0303 },
+ unicodeslot=0x1EE0,
+ },
+ [0x1EE1]={
+ adobename="ohorntilde",
+ category="ll",
+ contextname="ohorntilde",
+ description="LATIN SMALL LETTER O WITH HORN AND TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x01A1, 0x0303 },
+ uccode=0x1EE0,
+ unicodeslot=0x1EE1,
+ },
+ [0x1EE2]={
+ adobename="Ohorndotbelow",
+ category="lu",
+ contextname="Ohorndotbelow",
+ description="LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW",
+ direction="l",
+ lccode=0x1EE3,
+ linebreak="al",
+ shcode=0x004F,
+ specials={ "char", 0x01A0, 0x0323 },
+ unicodeslot=0x1EE2,
+ },
+ [0x1EE3]={
+ adobename="ohorndotbelow",
+ category="ll",
+ contextname="ohorndotbelow",
+ description="LATIN SMALL LETTER O WITH HORN AND DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x006F,
+ specials={ "char", 0x01A1, 0x0323 },
+ uccode=0x1EE2,
+ unicodeslot=0x1EE3,
+ },
+ [0x1EE4]={
+ adobename="Udotbelow",
+ category="lu",
+ contextname="Udotbelow",
+ description="LATIN CAPITAL LETTER U WITH DOT BELOW",
+ direction="l",
+ lccode=0x1EE5,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0323 },
+ unicodeslot=0x1EE4,
+ },
+ [0x1EE5]={
+ adobename="udotbelow",
+ category="ll",
+ contextname="udotbelow",
+ description="LATIN SMALL LETTER U WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0323 },
+ uccode=0x1EE4,
+ unicodeslot=0x1EE5,
+ },
+ [0x1EE6]={
+ adobename="Uhookabove",
+ category="lu",
+ contextname="Uhook",
+ description="LATIN CAPITAL LETTER U WITH HOOK ABOVE",
+ direction="l",
+ lccode=0x1EE7,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x0055, 0x0309 },
+ unicodeslot=0x1EE6,
+ },
+ [0x1EE7]={
+ adobename="uhookabove",
+ category="ll",
+ contextname="uhook",
+ description="LATIN SMALL LETTER U WITH HOOK ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x0075, 0x0309 },
+ uccode=0x1EE6,
+ unicodeslot=0x1EE7,
+ },
+ [0x1EE8]={
+ adobename="Uhornacute",
+ category="lu",
+ contextname="Uhornacute",
+ description="LATIN CAPITAL LETTER U WITH HORN AND ACUTE",
+ direction="l",
+ lccode=0x1EE9,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x01AF, 0x0301 },
+ unicodeslot=0x1EE8,
+ },
+ [0x1EE9]={
+ adobename="uhornacute",
+ category="ll",
+ contextname="uhornacute",
+ description="LATIN SMALL LETTER U WITH HORN AND ACUTE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x01B0, 0x0301 },
+ uccode=0x1EE8,
+ unicodeslot=0x1EE9,
+ },
+ [0x1EEA]={
+ adobename="Uhorngrave",
+ category="lu",
+ contextname="Uhorngrave",
+ description="LATIN CAPITAL LETTER U WITH HORN AND GRAVE",
+ direction="l",
+ lccode=0x1EEB,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x01AF, 0x0300 },
+ unicodeslot=0x1EEA,
+ },
+ [0x1EEB]={
+ adobename="uhorngrave",
+ category="ll",
+ contextname="uhorngrave",
+ description="LATIN SMALL LETTER U WITH HORN AND GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x01B0, 0x0300 },
+ uccode=0x1EEA,
+ unicodeslot=0x1EEB,
+ },
+ [0x1EEC]={
+ adobename="Uhornhookabove",
+ category="lu",
+ contextname="Uhornhook",
+ description="LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE",
+ direction="l",
+ lccode=0x1EED,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x01AF, 0x0309 },
+ unicodeslot=0x1EEC,
+ },
+ [0x1EED]={
+ adobename="uhornhookabove",
+ category="ll",
+ contextname="uhornhook",
+ description="LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x01B0, 0x0309 },
+ uccode=0x1EEC,
+ unicodeslot=0x1EED,
+ },
+ [0x1EEE]={
+ adobename="Uhorntilde",
+ category="lu",
+ contextname="Uhorntilde",
+ description="LATIN CAPITAL LETTER U WITH HORN AND TILDE",
+ direction="l",
+ lccode=0x1EEF,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x01AF, 0x0303 },
+ unicodeslot=0x1EEE,
+ },
+ [0x1EEF]={
+ adobename="uhorntilde",
+ category="ll",
+ contextname="uhorntilde",
+ description="LATIN SMALL LETTER U WITH HORN AND TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x01B0, 0x0303 },
+ uccode=0x1EEE,
+ unicodeslot=0x1EEF,
+ },
+ [0x1EF0]={
+ adobename="Uhorndotbelow",
+ category="lu",
+ contextname="Uhorndotbelow",
+ description="LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW",
+ direction="l",
+ lccode=0x1EF1,
+ linebreak="al",
+ shcode=0x0055,
+ specials={ "char", 0x01AF, 0x0323 },
+ unicodeslot=0x1EF0,
+ },
+ [0x1EF1]={
+ adobename="uhorndotbelow",
+ category="ll",
+ contextname="uhorndotbelow",
+ description="LATIN SMALL LETTER U WITH HORN AND DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0075,
+ specials={ "char", 0x01B0, 0x0323 },
+ uccode=0x1EF0,
+ unicodeslot=0x1EF1,
+ },
+ [0x1EF2]={
+ adobename="Ygrave",
+ category="lu",
+ contextname="Ygrave",
+ description="LATIN CAPITAL LETTER Y WITH GRAVE",
+ direction="l",
+ lccode=0x1EF3,
+ linebreak="al",
+ shcode=0x0059,
+ specials={ "char", 0x0059, 0x0300 },
+ unicodeslot=0x1EF2,
+ },
+ [0x1EF3]={
+ adobename="ygrave",
+ category="ll",
+ contextname="ygrave",
+ description="LATIN SMALL LETTER Y WITH GRAVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0079,
+ specials={ "char", 0x0079, 0x0300 },
+ uccode=0x1EF2,
+ unicodeslot=0x1EF3,
+ },
+ [0x1EF4]={
+ adobename="Ydotbelow",
+ category="lu",
+ contextname="Ydotbelow",
+ description="LATIN CAPITAL LETTER Y WITH DOT BELOW",
+ direction="l",
+ lccode=0x1EF5,
+ linebreak="al",
+ shcode=0x0059,
+ specials={ "char", 0x0059, 0x0323 },
+ unicodeslot=0x1EF4,
+ },
+ [0x1EF5]={
+ adobename="ydotbelow",
+ category="ll",
+ contextname="ydotbelow",
+ description="LATIN SMALL LETTER Y WITH DOT BELOW",
+ direction="l",
+ linebreak="al",
+ shcode=0x0079,
+ specials={ "char", 0x0079, 0x0323 },
+ uccode=0x1EF4,
+ unicodeslot=0x1EF5,
+ },
+ [0x1EF6]={
+ adobename="Yhookabove",
+ category="lu",
+ contextname="Yhook",
+ description="LATIN CAPITAL LETTER Y WITH HOOK ABOVE",
+ direction="l",
+ lccode=0x1EF7,
+ linebreak="al",
+ shcode=0x0059,
+ specials={ "char", 0x0059, 0x0309 },
+ unicodeslot=0x1EF6,
+ },
+ [0x1EF7]={
+ adobename="yhookabove",
+ category="ll",
+ contextname="yhook",
+ description="LATIN SMALL LETTER Y WITH HOOK ABOVE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0079,
+ specials={ "char", 0x0079, 0x0309 },
+ uccode=0x1EF6,
+ unicodeslot=0x1EF7,
+ },
+ [0x1EF8]={
+ adobename="Ytilde",
+ category="lu",
+ contextname="Ytilde",
+ description="LATIN CAPITAL LETTER Y WITH TILDE",
+ direction="l",
+ lccode=0x1EF9,
+ linebreak="al",
+ shcode=0x0059,
+ specials={ "char", 0x0059, 0x0303 },
+ unicodeslot=0x1EF8,
+ },
+ [0x1EF9]={
+ adobename="ytilde",
+ category="ll",
+ contextname="ytilde",
+ description="LATIN SMALL LETTER Y WITH TILDE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0079,
+ specials={ "char", 0x0079, 0x0303 },
+ uccode=0x1EF8,
+ unicodeslot=0x1EF9,
+ },
+ [0x1EFA]={
+ category="lu",
+ description="LATIN CAPITAL LETTER MIDDLE-WELSH LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1EFA,
+ },
+ [0x1EFB]={
+ category="ll",
+ description="LATIN SMALL LETTER MIDDLE-WELSH LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1EFB,
+ },
+ [0x1EFC]={
+ category="lu",
+ description="LATIN CAPITAL LETTER MIDDLE-WELSH V",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1EFC,
+ },
+ [0x1EFD]={
+ category="ll",
+ description="LATIN SMALL LETTER MIDDLE-WELSH V",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1EFD,
+ },
+ [0x1EFE]={
+ category="lu",
+ description="LATIN CAPITAL LETTER Y WITH LOOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1EFE,
+ },
+ [0x1EFF]={
+ category="ll",
+ description="LATIN SMALL LETTER Y WITH LOOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1EFF,
+ },
+ [0x1F00]={
+ category="ll",
+ contextname="greekalphapsili",
+ description="GREEK SMALL LETTER ALPHA WITH PSILI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x03B1, 0x0313 },
+ uccode=0x1F08,
+ unicodeslot=0x1F00,
+ },
+ [0x1F01]={
+ category="ll",
+ contextname="greekalphadasia",
+ description="GREEK SMALL LETTER ALPHA WITH DASIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x03B1, 0x0314 },
+ uccode=0x1F09,
+ unicodeslot=0x1F01,
+ },
+ [0x1F02]={
+ category="ll",
+ contextname="greekalphapsilivaria",
+ description="GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F00, 0x0300 },
+ uccode=0x1F0A,
+ unicodeslot=0x1F02,
+ },
+ [0x1F03]={
+ category="ll",
+ contextname="greekalphadasiavaria",
+ description="GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F01, 0x0300 },
+ uccode=0x1F0B,
+ unicodeslot=0x1F03,
+ },
+ [0x1F04]={
+ category="ll",
+ contextname="greekalphapsilitonos",
+ description="GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F00, 0x0301 },
+ uccode=0x1F0C,
+ unicodeslot=0x1F04,
+ },
+ [0x1F05]={
+ category="ll",
+ contextname="greekalphadasiatonos",
+ description="GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F01, 0x0301 },
+ uccode=0x1F0D,
+ unicodeslot=0x1F05,
+ },
+ [0x1F06]={
+ category="ll",
+ contextname="greekalphapsiliperispomeni",
+ description="GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F00, 0x0342 },
+ uccode=0x1F0E,
+ unicodeslot=0x1F06,
+ },
+ [0x1F07]={
+ category="ll",
+ contextname="greekalphadasiaperispomeni",
+ description="GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F01, 0x0342 },
+ uccode=0x1F0F,
+ unicodeslot=0x1F07,
+ },
+ [0x1F08]={
+ category="lu",
+ contextname="greekAlphapsili",
+ description="GREEK CAPITAL LETTER ALPHA WITH PSILI",
+ direction="l",
+ lccode=0x1F00,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x0391, 0x0313 },
+ unicodeslot=0x1F08,
+ },
+ [0x1F09]={
+ category="lu",
+ contextname="greekAlphadasia",
+ description="GREEK CAPITAL LETTER ALPHA WITH DASIA",
+ direction="l",
+ lccode=0x1F01,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x0391, 0x0314 },
+ unicodeslot=0x1F09,
+ },
+ [0x1F0A]={
+ category="lu",
+ contextname="greekAlphapsilivaria",
+ description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA",
+ direction="l",
+ lccode=0x1F02,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F08, 0x0300 },
+ unicodeslot=0x1F0A,
+ },
+ [0x1F0B]={
+ category="lu",
+ contextname="greekAlphadasiavaria",
+ description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA",
+ direction="l",
+ lccode=0x1F03,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F09, 0x0300 },
+ unicodeslot=0x1F0B,
+ },
+ [0x1F0C]={
+ category="lu",
+ contextname="greekAlphapsilitonos",
+ description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA",
+ direction="l",
+ lccode=0x1F04,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F08, 0x0301 },
+ unicodeslot=0x1F0C,
+ },
+ [0x1F0D]={
+ category="lu",
+ contextname="greekAlphadasiatonos",
+ description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA",
+ direction="l",
+ lccode=0x1F05,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F09, 0x0301 },
+ unicodeslot=0x1F0D,
+ },
+ [0x1F0E]={
+ category="lu",
+ contextname="greekAlphapsiliperispomeni",
+ description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI",
+ direction="l",
+ lccode=0x1F06,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F08, 0x0342 },
+ unicodeslot=0x1F0E,
+ },
+ [0x1F0F]={
+ category="lu",
+ contextname="greekAlphadasiaperispomeni",
+ description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI",
+ direction="l",
+ lccode=0x1F07,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F09, 0x0342 },
+ unicodeslot=0x1F0F,
+ },
+ [0x1F10]={
+ category="ll",
+ contextname="greekepsilonpsili",
+ description="GREEK SMALL LETTER EPSILON WITH PSILI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B5,
+ specials={ "char", 0x03B5, 0x0313 },
+ uccode=0x1F18,
+ unicodeslot=0x1F10,
+ },
+ [0x1F11]={
+ category="ll",
+ contextname="greekepsilondasia",
+ description="GREEK SMALL LETTER EPSILON WITH DASIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B5,
+ specials={ "char", 0x03B5, 0x0314 },
+ uccode=0x1F19,
+ unicodeslot=0x1F11,
+ },
+ [0x1F12]={
+ category="ll",
+ contextname="greekepsilonpsilivaria",
+ description="GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B5,
+ specials={ "char", 0x1F10, 0x0300 },
+ uccode=0x1F1A,
+ unicodeslot=0x1F12,
+ },
+ [0x1F13]={
+ category="ll",
+ contextname="greekepsilondasiavaria",
+ description="GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B5,
+ specials={ "char", 0x1F11, 0x0300 },
+ uccode=0x1F1B,
+ unicodeslot=0x1F13,
+ },
+ [0x1F14]={
+ category="ll",
+ contextname="greekepsilonpsilitonos",
+ description="GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B5,
+ specials={ "char", 0x1F10, 0x0301 },
+ uccode=0x1F1C,
+ unicodeslot=0x1F14,
+ },
+ [0x1F15]={
+ category="ll",
+ contextname="greekepsilondasiatonos",
+ description="GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B5,
+ specials={ "char", 0x1F11, 0x0301 },
+ uccode=0x1F1D,
+ unicodeslot=0x1F15,
+ },
+ [0x1F18]={
+ category="lu",
+ contextname="greekEpsilonpsili",
+ description="GREEK CAPITAL LETTER EPSILON WITH PSILI",
+ direction="l",
+ lccode=0x1F10,
+ linebreak="al",
+ shcode=0x0395,
+ specials={ "char", 0x0395, 0x0313 },
+ unicodeslot=0x1F18,
+ },
+ [0x1F19]={
+ category="lu",
+ contextname="greekEpsilondasia",
+ description="GREEK CAPITAL LETTER EPSILON WITH DASIA",
+ direction="l",
+ lccode=0x1F11,
+ linebreak="al",
+ shcode=0x0395,
+ specials={ "char", 0x0395, 0x0314 },
+ unicodeslot=0x1F19,
+ },
+ [0x1F1A]={
+ category="lu",
+ contextname="greekEpsilonpsilivaria",
+ description="GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA",
+ direction="l",
+ lccode=0x1F12,
+ linebreak="al",
+ shcode=0x0395,
+ specials={ "char", 0x1F18, 0x0300 },
+ unicodeslot=0x1F1A,
+ },
+ [0x1F1B]={
+ category="lu",
+ contextname="greekEpsilondasiavaria",
+ description="GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA",
+ direction="l",
+ lccode=0x1F13,
+ linebreak="al",
+ shcode=0x0395,
+ specials={ "char", 0x1F19, 0x0300 },
+ unicodeslot=0x1F1B,
+ },
+ [0x1F1C]={
+ category="lu",
+ contextname="greekEpsilonpsilitonos",
+ description="GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA",
+ direction="l",
+ lccode=0x1F14,
+ linebreak="al",
+ shcode=0x0395,
+ specials={ "char", 0x1F18, 0x0301 },
+ unicodeslot=0x1F1C,
+ },
+ [0x1F1D]={
+ category="lu",
+ contextname="greekEpsilondasiatonos",
+ description="GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA",
+ direction="l",
+ lccode=0x1F15,
+ linebreak="al",
+ shcode=0x0395,
+ specials={ "char", 0x1F19, 0x0301 },
+ unicodeslot=0x1F1D,
+ },
+ [0x1F20]={
+ category="ll",
+ contextname="greeketapsili",
+ description="GREEK SMALL LETTER ETA WITH PSILI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x03B7, 0x0313 },
+ uccode=0x1F28,
+ unicodeslot=0x1F20,
+ },
+ [0x1F21]={
+ category="ll",
+ contextname="greeketadasia",
+ description="GREEK SMALL LETTER ETA WITH DASIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x03B7, 0x0314 },
+ uccode=0x1F29,
+ unicodeslot=0x1F21,
+ },
+ [0x1F22]={
+ category="ll",
+ contextname="greeketapsilivaria",
+ description="GREEK SMALL LETTER ETA WITH PSILI AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F20, 0x0300 },
+ uccode=0x1F2A,
+ unicodeslot=0x1F22,
+ },
+ [0x1F23]={
+ category="ll",
+ contextname="greeketadasiavaria",
+ description="GREEK SMALL LETTER ETA WITH DASIA AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F21, 0x0300 },
+ uccode=0x1F2B,
+ unicodeslot=0x1F23,
+ },
+ [0x1F24]={
+ category="ll",
+ contextname="greeketapsilitonos",
+ description="GREEK SMALL LETTER ETA WITH PSILI AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F20, 0x0301 },
+ uccode=0x1F2C,
+ unicodeslot=0x1F24,
+ },
+ [0x1F25]={
+ category="ll",
+ contextname="greeketadasiatonos",
+ description="GREEK SMALL LETTER ETA WITH DASIA AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F21, 0x0301 },
+ uccode=0x1F2D,
+ unicodeslot=0x1F25,
+ },
+ [0x1F26]={
+ category="ll",
+ contextname="greeketapsiliperispomeni",
+ description="GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F20, 0x0342 },
+ uccode=0x1F2E,
+ unicodeslot=0x1F26,
+ },
+ [0x1F27]={
+ category="ll",
+ contextname="greeketadasiaperispomeni",
+ description="GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F21, 0x0342 },
+ uccode=0x1F2F,
+ unicodeslot=0x1F27,
+ },
+ [0x1F28]={
+ category="lu",
+ contextname="greekEtapsili",
+ description="GREEK CAPITAL LETTER ETA WITH PSILI",
+ direction="l",
+ lccode=0x1F20,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x0397, 0x0313 },
+ unicodeslot=0x1F28,
+ },
+ [0x1F29]={
+ category="lu",
+ contextname="greekEtadasia",
+ description="GREEK CAPITAL LETTER ETA WITH DASIA",
+ direction="l",
+ lccode=0x1F21,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x0397, 0x0314 },
+ unicodeslot=0x1F29,
+ },
+ [0x1F2A]={
+ category="lu",
+ contextname="greekEtapsilivaria",
+ description="GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA",
+ direction="l",
+ lccode=0x1F22,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F28, 0x0300 },
+ unicodeslot=0x1F2A,
+ },
+ [0x1F2B]={
+ category="lu",
+ contextname="greekEtadasiavaria",
+ description="GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA",
+ direction="l",
+ lccode=0x1F23,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F29, 0x0300 },
+ unicodeslot=0x1F2B,
+ },
+ [0x1F2C]={
+ category="lu",
+ contextname="greekEtapsilitonos",
+ description="GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA",
+ direction="l",
+ lccode=0x1F24,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F28, 0x0301 },
+ unicodeslot=0x1F2C,
+ },
+ [0x1F2D]={
+ category="lu",
+ contextname="greekEtadasiatonos",
+ description="GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA",
+ direction="l",
+ lccode=0x1F25,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F29, 0x0301 },
+ unicodeslot=0x1F2D,
+ },
+ [0x1F2E]={
+ category="lu",
+ contextname="greekEtapsiliperispomeni",
+ description="GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI",
+ direction="l",
+ lccode=0x1F26,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F28, 0x0342 },
+ unicodeslot=0x1F2E,
+ },
+ [0x1F2F]={
+ category="lu",
+ contextname="greekEtadasiaperispomeni",
+ description="GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI",
+ direction="l",
+ lccode=0x1F27,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F29, 0x0342 },
+ unicodeslot=0x1F2F,
+ },
+ [0x1F30]={
+ category="ll",
+ contextname="greekiotapsili",
+ description="GREEK SMALL LETTER IOTA WITH PSILI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x03B9, 0x0313 },
+ uccode=0x1F38,
+ unicodeslot=0x1F30,
+ },
+ [0x1F31]={
+ category="ll",
+ contextname="greekiotadasia",
+ description="GREEK SMALL LETTER IOTA WITH DASIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x03B9, 0x0314 },
+ uccode=0x1F39,
+ unicodeslot=0x1F31,
+ },
+ [0x1F32]={
+ category="ll",
+ contextname="greekiotapsilivaria",
+ description="GREEK SMALL LETTER IOTA WITH PSILI AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x1F30, 0x0300 },
+ uccode=0x1F3A,
+ unicodeslot=0x1F32,
+ },
+ [0x1F33]={
+ category="ll",
+ contextname="greekiotadasiavaria",
+ description="GREEK SMALL LETTER IOTA WITH DASIA AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x1F31, 0x0300 },
+ uccode=0x1F3B,
+ unicodeslot=0x1F33,
+ },
+ [0x1F34]={
+ category="ll",
+ contextname="greekiotapsilitonos",
+ description="GREEK SMALL LETTER IOTA WITH PSILI AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x1F30, 0x0301 },
+ uccode=0x1F3C,
+ unicodeslot=0x1F34,
+ },
+ [0x1F35]={
+ category="ll",
+ contextname="greekiotadasiatonos",
+ description="GREEK SMALL LETTER IOTA WITH DASIA AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x1F31, 0x0301 },
+ uccode=0x1F3D,
+ unicodeslot=0x1F35,
+ },
+ [0x1F36]={
+ category="ll",
+ contextname="greekiotapsiliperispomeni",
+ description="GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x1F30, 0x0342 },
+ uccode=0x1F3E,
+ unicodeslot=0x1F36,
+ },
+ [0x1F37]={
+ category="ll",
+ contextname="greekiotadasiaperispomeni",
+ description="GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x1F31, 0x0342 },
+ uccode=0x1F3F,
+ unicodeslot=0x1F37,
+ },
+ [0x1F38]={
+ category="lu",
+ contextname="greekIotapsili",
+ description="GREEK CAPITAL LETTER IOTA WITH PSILI",
+ direction="l",
+ lccode=0x1F30,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x0399, 0x0313 },
+ unicodeslot=0x1F38,
+ },
+ [0x1F39]={
+ category="lu",
+ contextname="greekIotadasia",
+ description="GREEK CAPITAL LETTER IOTA WITH DASIA",
+ direction="l",
+ lccode=0x1F31,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x0399, 0x0314 },
+ unicodeslot=0x1F39,
+ },
+ [0x1F3A]={
+ category="lu",
+ contextname="greekIotapsilivaria",
+ description="GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA",
+ direction="l",
+ lccode=0x1F32,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x1F38, 0x0300 },
+ unicodeslot=0x1F3A,
+ },
+ [0x1F3B]={
+ category="lu",
+ contextname="greekIotadasiavaria",
+ description="GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA",
+ direction="l",
+ lccode=0x1F33,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x1F39, 0x0300 },
+ unicodeslot=0x1F3B,
+ },
+ [0x1F3C]={
+ category="lu",
+ contextname="greekIotapsilitonos",
+ description="GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA",
+ direction="l",
+ lccode=0x1F34,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x1F38, 0x0301 },
+ unicodeslot=0x1F3C,
+ },
+ [0x1F3D]={
+ category="lu",
+ contextname="greekIotadasiatonos",
+ description="GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA",
+ direction="l",
+ lccode=0x1F35,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x1F39, 0x0301 },
+ unicodeslot=0x1F3D,
+ },
+ [0x1F3E]={
+ category="lu",
+ contextname="greekIotapsiliperispomeni",
+ description="GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI",
+ direction="l",
+ lccode=0x1F36,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x1F38, 0x0342 },
+ unicodeslot=0x1F3E,
+ },
+ [0x1F3F]={
+ category="lu",
+ contextname="greekIotadasiaperispomeni",
+ description="GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI",
+ direction="l",
+ lccode=0x1F37,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x1F39, 0x0342 },
+ unicodeslot=0x1F3F,
+ },
+ [0x1F40]={
+ category="ll",
+ contextname="greekomicronpsili",
+ description="GREEK SMALL LETTER OMICRON WITH PSILI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03BF,
+ specials={ "char", 0x03BF, 0x0313 },
+ uccode=0x1F48,
+ unicodeslot=0x1F40,
+ },
+ [0x1F41]={
+ category="ll",
+ contextname="greekomicrondasia",
+ description="GREEK SMALL LETTER OMICRON WITH DASIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03BF,
+ specials={ "char", 0x03BF, 0x0314 },
+ uccode=0x1F49,
+ unicodeslot=0x1F41,
+ },
+ [0x1F42]={
+ category="ll",
+ contextname="greekomicronpsilivaria",
+ description="GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03BF,
+ specials={ "char", 0x1F40, 0x0300 },
+ uccode=0x1F4A,
+ unicodeslot=0x1F42,
+ },
+ [0x1F43]={
+ category="ll",
+ contextname="greekomicrondasiavaria",
+ description="GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03BF,
+ specials={ "char", 0x1F41, 0x0300 },
+ uccode=0x1F4B,
+ unicodeslot=0x1F43,
+ },
+ [0x1F44]={
+ category="ll",
+ contextname="greekomicronpsilitonos",
+ description="GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03BF,
+ specials={ "char", 0x1F40, 0x0301 },
+ uccode=0x1F4C,
+ unicodeslot=0x1F44,
+ },
+ [0x1F45]={
+ category="ll",
+ contextname="greekomicrondasiatonos",
+ description="GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03BF,
+ specials={ "char", 0x1F41, 0x0301 },
+ uccode=0x1F4D,
+ unicodeslot=0x1F45,
+ },
+ [0x1F48]={
+ category="lu",
+ contextname="greekOmicronpsili",
+ description="GREEK CAPITAL LETTER OMICRON WITH PSILI",
+ direction="l",
+ lccode=0x1F40,
+ linebreak="al",
+ shcode=0x039F,
+ specials={ "char", 0x039F, 0x0313 },
+ unicodeslot=0x1F48,
+ },
+ [0x1F49]={
+ category="lu",
+ contextname="greekOmicrondasia",
+ description="GREEK CAPITAL LETTER OMICRON WITH DASIA",
+ direction="l",
+ lccode=0x1F41,
+ linebreak="al",
+ shcode=0x039F,
+ specials={ "char", 0x039F, 0x0314 },
+ unicodeslot=0x1F49,
+ },
+ [0x1F4A]={
+ category="lu",
+ contextname="greekOmicronpsilivaria",
+ description="GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA",
+ direction="l",
+ lccode=0x1F42,
+ linebreak="al",
+ shcode=0x039F,
+ specials={ "char", 0x1F48, 0x0300 },
+ unicodeslot=0x1F4A,
+ },
+ [0x1F4B]={
+ category="lu",
+ contextname="greekOmicrondasiavaria",
+ description="GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA",
+ direction="l",
+ lccode=0x1F43,
+ linebreak="al",
+ shcode=0x039F,
+ specials={ "char", 0x1F49, 0x0300 },
+ unicodeslot=0x1F4B,
+ },
+ [0x1F4C]={
+ category="lu",
+ contextname="greekOmicronpsilitonos",
+ description="GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA",
+ direction="l",
+ lccode=0x1F44,
+ linebreak="al",
+ shcode=0x039F,
+ specials={ "char", 0x1F48, 0x0301 },
+ unicodeslot=0x1F4C,
+ },
+ [0x1F4D]={
+ category="lu",
+ contextname="greekOmicrondasiatonos",
+ description="GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA",
+ direction="l",
+ lccode=0x1F45,
+ linebreak="al",
+ shcode=0x039F,
+ specials={ "char", 0x1F49, 0x0301 },
+ unicodeslot=0x1F4D,
+ },
+ [0x1F50]={
+ category="ll",
+ contextname="greekupsilonpsili",
+ description="GREEK SMALL LETTER UPSILON WITH PSILI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03C5, 0x0313 },
+ unicodeslot=0x1F50,
+ },
+ [0x1F51]={
+ category="ll",
+ contextname="greekupsilondasia",
+ description="GREEK SMALL LETTER UPSILON WITH DASIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03C5, 0x0314 },
+ uccode=0x1F59,
+ unicodeslot=0x1F51,
+ },
+ [0x1F52]={
+ category="ll",
+ contextname="greekupsilonpsilivaria",
+ description="GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x1F50, 0x0300 },
+ unicodeslot=0x1F52,
+ },
+ [0x1F53]={
+ category="ll",
+ contextname="greekupsilondasiavaria",
+ description="GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x1F51, 0x0300 },
+ uccode=0x1F5B,
+ unicodeslot=0x1F53,
+ },
+ [0x1F54]={
+ category="ll",
+ contextname="greekupsilonpsilitonos",
+ description="GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x1F50, 0x0301 },
+ unicodeslot=0x1F54,
+ },
+ [0x1F55]={
+ category="ll",
+ contextname="greekupsilondasiatonos",
+ description="GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x1F51, 0x0301 },
+ uccode=0x1F5D,
+ unicodeslot=0x1F55,
+ },
+ [0x1F56]={
+ category="ll",
+ contextname="greekupsilonpsiliperispomeni",
+ description="GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x1F50, 0x0342 },
+ unicodeslot=0x1F56,
+ },
+ [0x1F57]={
+ category="ll",
+ contextname="greekupsilondasiaperispomeni",
+ description="GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x1F51, 0x0342 },
+ uccode=0x1F5F,
+ unicodeslot=0x1F57,
+ },
+ [0x1F59]={
+ category="lu",
+ contextname="greekUpsilondasia",
+ description="GREEK CAPITAL LETTER UPSILON WITH DASIA",
+ direction="l",
+ lccode=0x1F51,
+ linebreak="al",
+ shcode=0x03A5,
+ specials={ "char", 0x03A5, 0x0314 },
+ unicodeslot=0x1F59,
+ },
+ [0x1F5B]={
+ category="lu",
+ contextname="greekUpsilondasiavaria",
+ description="GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA",
+ direction="l",
+ lccode=0x1F53,
+ linebreak="al",
+ shcode=0x03A5,
+ specials={ "char", 0x1F59, 0x0300 },
+ unicodeslot=0x1F5B,
+ },
+ [0x1F5D]={
+ category="lu",
+ contextname="greekUpsilondasiatonos",
+ description="GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA",
+ direction="l",
+ lccode=0x1F55,
+ linebreak="al",
+ shcode=0x03A5,
+ specials={ "char", 0x1F59, 0x0301 },
+ unicodeslot=0x1F5D,
+ },
+ [0x1F5F]={
+ category="lu",
+ contextname="greekUpsilondasiaperispomeni",
+ description="GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI",
+ direction="l",
+ lccode=0x1F57,
+ linebreak="al",
+ shcode=0x03A5,
+ specials={ "char", 0x1F59, 0x0342 },
+ unicodeslot=0x1F5F,
+ },
+ [0x1F60]={
+ category="ll",
+ contextname="greekomegapsili",
+ description="GREEK SMALL LETTER OMEGA WITH PSILI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x03C9, 0x0313 },
+ uccode=0x1F68,
+ unicodeslot=0x1F60,
+ },
+ [0x1F61]={
+ category="ll",
+ contextname="greekomegadasia",
+ description="GREEK SMALL LETTER OMEGA WITH DASIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x03C9, 0x0314 },
+ uccode=0x1F69,
+ unicodeslot=0x1F61,
+ },
+ [0x1F62]={
+ category="ll",
+ contextname="greekomegapsilivaria",
+ description="GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F60, 0x0300 },
+ uccode=0x1F6A,
+ unicodeslot=0x1F62,
+ },
+ [0x1F63]={
+ category="ll",
+ contextname="greekomegadasiavaria",
+ description="GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F61, 0x0300 },
+ uccode=0x1F6B,
+ unicodeslot=0x1F63,
+ },
+ [0x1F64]={
+ category="ll",
+ contextname="greekomegapsilitonos",
+ description="GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F60, 0x0301 },
+ uccode=0x1F6C,
+ unicodeslot=0x1F64,
+ },
+ [0x1F65]={
+ category="ll",
+ contextname="greekomegadasiatonos",
+ description="GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F61, 0x0301 },
+ uccode=0x1F6D,
+ unicodeslot=0x1F65,
+ },
+ [0x1F66]={
+ category="ll",
+ contextname="greekomegapsiliperispomeni",
+ description="GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F60, 0x0342 },
+ uccode=0x1F6E,
+ unicodeslot=0x1F66,
+ },
+ [0x1F67]={
+ category="ll",
+ contextname="greekomegadasiaperispomeni",
+ description="GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F61, 0x0342 },
+ uccode=0x1F6F,
+ unicodeslot=0x1F67,
+ },
+ [0x1F68]={
+ category="lu",
+ contextname="greekOmegapsili",
+ description="GREEK CAPITAL LETTER OMEGA WITH PSILI",
+ direction="l",
+ lccode=0x1F60,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x03A9, 0x0313 },
+ unicodeslot=0x1F68,
+ },
+ [0x1F69]={
+ category="lu",
+ contextname="greekOmegadasia",
+ description="GREEK CAPITAL LETTER OMEGA WITH DASIA",
+ direction="l",
+ lccode=0x1F61,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x03A9, 0x0314 },
+ unicodeslot=0x1F69,
+ },
+ [0x1F6A]={
+ category="lu",
+ contextname="greekOmegapsilivaria",
+ description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA",
+ direction="l",
+ lccode=0x1F62,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F68, 0x0300 },
+ unicodeslot=0x1F6A,
+ },
+ [0x1F6B]={
+ category="lu",
+ contextname="greekOmegadasiavaria",
+ description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA",
+ direction="l",
+ lccode=0x1F63,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F69, 0x0300 },
+ unicodeslot=0x1F6B,
+ },
+ [0x1F6C]={
+ category="lu",
+ contextname="greekOmegapsilitonos",
+ description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA",
+ direction="l",
+ lccode=0x1F64,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F68, 0x0301 },
+ unicodeslot=0x1F6C,
+ },
+ [0x1F6D]={
+ category="lu",
+ contextname="greekOmegadasiatonos",
+ description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA",
+ direction="l",
+ lccode=0x1F65,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F69, 0x0301 },
+ unicodeslot=0x1F6D,
+ },
+ [0x1F6E]={
+ category="lu",
+ contextname="greekOmegapsiliperispomeni",
+ description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI",
+ direction="l",
+ lccode=0x1F66,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F68, 0x0342 },
+ unicodeslot=0x1F6E,
+ },
+ [0x1F6F]={
+ category="lu",
+ contextname="greekOmegadasiaperispomeni",
+ description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI",
+ direction="l",
+ lccode=0x1F67,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F69, 0x0342 },
+ unicodeslot=0x1F6F,
+ },
+ [0x1F70]={
+ category="ll",
+ contextname="greekalphavaria",
+ description="GREEK SMALL LETTER ALPHA WITH VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x03B1, 0x0300 },
+ uccode=0x1FBA,
+ unicodeslot=0x1F70,
+ },
+ [0x1F71]={
+ category="ll",
+ contextname="greekalphaoxia",
+ description="GREEK SMALL LETTER ALPHA WITH OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x03AC },
+ uccode=0x1FBB,
+ unicodeslot=0x1F71,
+ },
+ [0x1F72]={
+ category="ll",
+ contextname="greekepsilonvaria",
+ description="GREEK SMALL LETTER EPSILON WITH VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B5,
+ specials={ "char", 0x03B5, 0x0300 },
+ uccode=0x1FC8,
+ unicodeslot=0x1F72,
+ },
+ [0x1F73]={
+ category="ll",
+ contextname="greekepsilonoxia",
+ description="GREEK SMALL LETTER EPSILON WITH OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B5,
+ specials={ "char", 0x03AD },
+ uccode=0x1FC9,
+ unicodeslot=0x1F73,
+ },
+ [0x1F74]={
+ category="ll",
+ contextname="greeketavaria",
+ description="GREEK SMALL LETTER ETA WITH VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x03B7, 0x0300 },
+ uccode=0x1FCA,
+ unicodeslot=0x1F74,
+ },
+ [0x1F75]={
+ category="ll",
+ contextname="greeketaoxia",
+ description="GREEK SMALL LETTER ETA WITH OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x03AE },
+ uccode=0x1FCB,
+ unicodeslot=0x1F75,
+ },
+ [0x1F76]={
+ category="ll",
+ contextname="greekiotavaria",
+ description="GREEK SMALL LETTER IOTA WITH VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x03B9, 0x0300 },
+ uccode=0x1FDA,
+ unicodeslot=0x1F76,
+ },
+ [0x1F77]={
+ category="ll",
+ contextname="greekiotaoxia",
+ description="GREEK SMALL LETTER IOTA WITH OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x03AF },
+ uccode=0x1FDB,
+ unicodeslot=0x1F77,
+ },
+ [0x1F78]={
+ category="ll",
+ contextname="greekomicronvaria",
+ description="GREEK SMALL LETTER OMICRON WITH VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03BF,
+ specials={ "char", 0x03BF, 0x0300 },
+ uccode=0x1FF8,
+ unicodeslot=0x1F78,
+ },
+ [0x1F79]={
+ category="ll",
+ contextname="greekomicronoxia",
+ description="GREEK SMALL LETTER OMICRON WITH OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03BF,
+ specials={ "char", 0x03CC },
+ uccode=0x1FF9,
+ unicodeslot=0x1F79,
+ },
+ [0x1F7A]={
+ category="ll",
+ contextname="greekupsilonvaria",
+ description="GREEK SMALL LETTER UPSILON WITH VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03C5, 0x0300 },
+ uccode=0x1FEA,
+ unicodeslot=0x1F7A,
+ },
+ [0x1F7B]={
+ category="ll",
+ contextname="greekupsilonoxia",
+ description="GREEK SMALL LETTER UPSILON WITH OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03CD },
+ uccode=0x1FEB,
+ unicodeslot=0x1F7B,
+ },
+ [0x1F7C]={
+ category="ll",
+ contextname="greekomegavaria",
+ description="GREEK SMALL LETTER OMEGA WITH VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x03C9, 0x0300 },
+ uccode=0x1FFA,
+ unicodeslot=0x1F7C,
+ },
+ [0x1F7D]={
+ category="ll",
+ contextname="greekomegaoxia",
+ description="GREEK SMALL LETTER OMEGA WITH OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x03CE },
+ uccode=0x1FFB,
+ unicodeslot=0x1F7D,
+ },
+ [0x1F80]={
+ category="ll",
+ contextname="greekalphaiotasubpsili",
+ description="GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F00, 0x0345 },
+ uccode=0x1F88,
+ unicodeslot=0x1F80,
+ },
+ [0x1F81]={
+ category="ll",
+ contextname="greekalphaiotasubdasia",
+ description="GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F01, 0x0345 },
+ uccode=0x1F89,
+ unicodeslot=0x1F81,
+ },
+ [0x1F82]={
+ category="ll",
+ contextname="greekalphaiotasubpsilivaria",
+ description="GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F02, 0x0345 },
+ uccode=0x1F8A,
+ unicodeslot=0x1F82,
+ },
+ [0x1F83]={
+ category="ll",
+ contextname="greekalphaiotasubdasiavaria",
+ description="GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F03, 0x0345 },
+ uccode=0x1F8B,
+ unicodeslot=0x1F83,
+ },
+ [0x1F84]={
+ category="ll",
+ contextname="greekalphaiotasubpsilitonos",
+ description="GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F04, 0x0345 },
+ uccode=0x1F8C,
+ unicodeslot=0x1F84,
+ },
+ [0x1F85]={
+ category="ll",
+ contextname="greekalphaiotasubdasiatonos",
+ description="GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F05, 0x0345 },
+ uccode=0x1F8D,
+ unicodeslot=0x1F85,
+ },
+ [0x1F86]={
+ category="ll",
+ contextname="greekalphaiotasubpsiliperispomeni",
+ description="GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F06, 0x0345 },
+ uccode=0x1F8E,
+ unicodeslot=0x1F86,
+ },
+ [0x1F87]={
+ category="ll",
+ contextname="greekalphaiotasubdasiaperispomeni",
+ description="GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F07, 0x0345 },
+ uccode=0x1F8F,
+ unicodeslot=0x1F87,
+ },
+ [0x1F88]={
+ category="lt",
+ contextname="greekAlphaiotasubpsili",
+ description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F80,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F08, 0x0345 },
+ unicodeslot=0x1F88,
+ },
+ [0x1F89]={
+ category="lt",
+ contextname="greekAlphaiotasubdasia",
+ description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F81,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F09, 0x0345 },
+ unicodeslot=0x1F89,
+ },
+ [0x1F8A]={
+ category="lt",
+ contextname="greekAlphaiotasubpsilivaria",
+ description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F82,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F0A, 0x0345 },
+ unicodeslot=0x1F8A,
+ },
+ [0x1F8B]={
+ category="lt",
+ contextname="greekAlphaiotasubdasiavaria",
+ description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F83,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F0B, 0x0345 },
+ unicodeslot=0x1F8B,
+ },
+ [0x1F8C]={
+ category="lt",
+ contextname="greekAlphaiotasubpsilitonos",
+ description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F84,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F0C, 0x0345 },
+ unicodeslot=0x1F8C,
+ },
+ [0x1F8D]={
+ category="lt",
+ contextname="greekAlphaiotasubdasiatonos",
+ description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F85,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F0D, 0x0345 },
+ unicodeslot=0x1F8D,
+ },
+ [0x1F8E]={
+ category="lt",
+ contextname="greekAlphaiotasubpsiliperispomeni",
+ description="GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F86,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F0E, 0x0345 },
+ unicodeslot=0x1F8E,
+ },
+ [0x1F8F]={
+ category="lt",
+ contextname="greekAlphaiotasubdasiaperispomeni",
+ description="GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F87,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x1F0F, 0x0345 },
+ unicodeslot=0x1F8F,
+ },
+ [0x1F90]={
+ category="ll",
+ contextname="greeketaiotasubpsili",
+ description="GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F20, 0x0345 },
+ uccode=0x1F98,
+ unicodeslot=0x1F90,
+ },
+ [0x1F91]={
+ category="ll",
+ contextname="greeketaiotasubdasia",
+ description="GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F21, 0x0345 },
+ uccode=0x1F99,
+ unicodeslot=0x1F91,
+ },
+ [0x1F92]={
+ category="ll",
+ contextname="greeketaiotasubpsilivaria",
+ description="GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F22, 0x0345 },
+ uccode=0x1F9A,
+ unicodeslot=0x1F92,
+ },
+ [0x1F93]={
+ category="ll",
+ contextname="greeketaiotasubdasiavaria",
+ description="GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F23, 0x0345 },
+ uccode=0x1F9B,
+ unicodeslot=0x1F93,
+ },
+ [0x1F94]={
+ category="ll",
+ contextname="greeketaiotasubpsilitonos",
+ description="GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F24, 0x0345 },
+ uccode=0x1F9C,
+ unicodeslot=0x1F94,
+ },
+ [0x1F95]={
+ category="ll",
+ contextname="greeketaiotasubdasiatonos",
+ description="GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F25, 0x0345 },
+ uccode=0x1F9D,
+ unicodeslot=0x1F95,
+ },
+ [0x1F96]={
+ category="ll",
+ contextname="greeketaiotasubpsiliperispomeni",
+ description="GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F26, 0x0345 },
+ uccode=0x1F9E,
+ unicodeslot=0x1F96,
+ },
+ [0x1F97]={
+ category="ll",
+ contextname="greeketaiotasubdasiaperispomeni",
+ description="GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F27, 0x0345 },
+ uccode=0x1F9F,
+ unicodeslot=0x1F97,
+ },
+ [0x1F98]={
+ category="lt",
+ contextname="greekEtaiotasubpsili",
+ description="GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F90,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F28, 0x0345 },
+ unicodeslot=0x1F98,
+ },
+ [0x1F99]={
+ category="lt",
+ contextname="greekEtaiotasubdasia",
+ description="GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F91,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F29, 0x0345 },
+ unicodeslot=0x1F99,
+ },
+ [0x1F9A]={
+ category="lt",
+ contextname="greekEtaiotasubpsilivaria",
+ description="GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F92,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F2A, 0x0345 },
+ unicodeslot=0x1F9A,
+ },
+ [0x1F9B]={
+ category="lt",
+ contextname="greekEtaiotasubdasiavaria",
+ description="GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F93,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F2B, 0x0345 },
+ unicodeslot=0x1F9B,
+ },
+ [0x1F9C]={
+ category="lt",
+ contextname="greekEtaiotasubpsilitonos",
+ description="GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F94,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F2C, 0x0345 },
+ unicodeslot=0x1F9C,
+ },
+ [0x1F9D]={
+ category="lt",
+ contextname="greekEtaiotasubdasiatonos",
+ description="GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F95,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F2D, 0x0345 },
+ unicodeslot=0x1F9D,
+ },
+ [0x1F9E]={
+ category="lt",
+ contextname="greekEtaiotasubpsiliperispomeni",
+ description="GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F96,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F2E, 0x0345 },
+ unicodeslot=0x1F9E,
+ },
+ [0x1F9F]={
+ category="lt",
+ contextname="greekEtaiotasubdasiaperispomeni",
+ description="GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1F97,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x1F2F, 0x0345 },
+ unicodeslot=0x1F9F,
+ },
+ [0x1FA0]={
+ category="ll",
+ contextname="greekomegaiotasubpsili",
+ description="GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F60, 0x0345 },
+ uccode=0x1FA8,
+ unicodeslot=0x1FA0,
+ },
+ [0x1FA1]={
+ category="ll",
+ contextname="greekomegaiotasubdasia",
+ description="GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F61, 0x0345 },
+ uccode=0x1FA9,
+ unicodeslot=0x1FA1,
+ },
+ [0x1FA2]={
+ category="ll",
+ contextname="greekomegaiotasubpsilivaria",
+ description="GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F62, 0x0345 },
+ uccode=0x1FAA,
+ unicodeslot=0x1FA2,
+ },
+ [0x1FA3]={
+ category="ll",
+ contextname="greekomegaiotasubdasiavaria",
+ description="GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F63, 0x0345 },
+ uccode=0x1FAB,
+ unicodeslot=0x1FA3,
+ },
+ [0x1FA4]={
+ category="ll",
+ contextname="greekomegaiotasubpsilitonos",
+ description="GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F64, 0x0345 },
+ uccode=0x1FAC,
+ unicodeslot=0x1FA4,
+ },
+ [0x1FA5]={
+ category="ll",
+ contextname="greekomegaiotasubdasiatonos",
+ description="GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F65, 0x0345 },
+ uccode=0x1FAD,
+ unicodeslot=0x1FA5,
+ },
+ [0x1FA6]={
+ category="ll",
+ contextname="greekomegaiotasubpsiliperispomeni",
+ description="GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F66, 0x0345 },
+ uccode=0x1FAE,
+ unicodeslot=0x1FA6,
+ },
+ [0x1FA7]={
+ category="ll",
+ contextname="greekomegaiotasubdasiaperispomeni",
+ description="GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F67, 0x0345 },
+ uccode=0x1FAF,
+ unicodeslot=0x1FA7,
+ },
+ [0x1FA8]={
+ category="lt",
+ contextname="greekOmegaiotasubpsili",
+ description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1FA0,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F68, 0x0345 },
+ unicodeslot=0x1FA8,
+ },
+ [0x1FA9]={
+ category="lt",
+ contextname="greekOmegaiotasubdasia",
+ description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1FA1,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F69, 0x0345 },
+ unicodeslot=0x1FA9,
+ },
+ [0x1FAA]={
+ category="lt",
+ contextname="greekOmegaiotasubpsilivaria",
+ description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1FA2,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F6A, 0x0345 },
+ unicodeslot=0x1FAA,
+ },
+ [0x1FAB]={
+ category="lt",
+ contextname="greekOmegaiotasubdasiavaria",
+ description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1FA3,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F6B, 0x0345 },
+ unicodeslot=0x1FAB,
+ },
+ [0x1FAC]={
+ category="lt",
+ contextname="greekOmegaiotasubpsilitonos",
+ description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1FA4,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F6C, 0x0345 },
+ unicodeslot=0x1FAC,
+ },
+ [0x1FAD]={
+ category="lt",
+ contextname="greekOmegaiotasubdasiatonos",
+ description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1FA5,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F6D, 0x0345 },
+ unicodeslot=0x1FAD,
+ },
+ [0x1FAE]={
+ category="lt",
+ contextname="greekOmegaiotasubpsiliperispomeni",
+ description="GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1FA6,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F6E, 0x0345 },
+ unicodeslot=0x1FAE,
+ },
+ [0x1FAF]={
+ category="lt",
+ contextname="greekOmegaiotasubdasiaperispomeni",
+ description="GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1FA7,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x1F6F, 0x0345 },
+ unicodeslot=0x1FAF,
+ },
+ [0x1FB0]={
+ category="ll",
+ contextname="greekalphavrachy",
+ description="GREEK SMALL LETTER ALPHA WITH VRACHY",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x03B1, 0x0306 },
+ uccode=0x1FB8,
+ unicodeslot=0x1FB0,
+ },
+ [0x1FB1]={
+ category="ll",
+ contextname="greekalphamacron",
+ description="GREEK SMALL LETTER ALPHA WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x03B1, 0x0304 },
+ uccode=0x1FB9,
+ unicodeslot=0x1FB1,
+ },
+ [0x1FB2]={
+ category="ll",
+ contextname="greekalphaiotasubvaria",
+ description="GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1F70, 0x0345 },
+ unicodeslot=0x1FB2,
+ },
+ [0x1FB3]={
+ category="ll",
+ contextname="greekalphaiotasub",
+ description="GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x03B1, 0x0345 },
+ uccode=0x1FBC,
+ unicodeslot=0x1FB3,
+ },
+ [0x1FB4]={
+ category="ll",
+ contextname="greekalphaiotasubtonos",
+ description="GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x03AC, 0x0345 },
+ unicodeslot=0x1FB4,
+ },
+ [0x1FB6]={
+ category="ll",
+ contextname="greekalphaperispomeni",
+ description="GREEK SMALL LETTER ALPHA WITH PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x03B1, 0x0342 },
+ unicodeslot=0x1FB6,
+ },
+ [0x1FB7]={
+ category="ll",
+ contextname="greekalphaiotasubperispomeni",
+ description="GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B1,
+ specials={ "char", 0x1FB6, 0x0345 },
+ unicodeslot=0x1FB7,
+ },
+ [0x1FB8]={
+ category="lu",
+ contextname="greekAlphavrachy",
+ description="GREEK CAPITAL LETTER ALPHA WITH VRACHY",
+ direction="l",
+ lccode=0x1FB0,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x0391, 0x0306 },
+ unicodeslot=0x1FB8,
+ },
+ [0x1FB9]={
+ category="lu",
+ contextname="greekAlphamacron",
+ description="GREEK CAPITAL LETTER ALPHA WITH MACRON",
+ direction="l",
+ lccode=0x1FB1,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x0391, 0x0304 },
+ unicodeslot=0x1FB9,
+ },
+ [0x1FBA]={
+ category="lu",
+ contextname="greekAlphavaria",
+ description="GREEK CAPITAL LETTER ALPHA WITH VARIA",
+ direction="l",
+ lccode=0x1F70,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x0391, 0x0300 },
+ unicodeslot=0x1FBA,
+ },
+ [0x1FBB]={
+ category="lu",
+ contextname="greekAlphatonos",
+ description="GREEK CAPITAL LETTER ALPHA WITH OXIA",
+ direction="l",
+ lccode=0x1F71,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x0386 },
+ unicodeslot=0x1FBB,
+ },
+ [0x1FBC]={
+ category="lt",
+ contextname="greekAlphaiotasub",
+ description="GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1FB3,
+ linebreak="al",
+ shcode=0x0391,
+ specials={ "char", 0x0391, 0x0345 },
+ unicodeslot=0x1FBC,
+ },
+ [0x1FBD]={
+ category="sk",
+ contextname="greekCoronis",
+ description="GREEK KORONIS",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x0020, 0x0313 },
+ unicodeslot=0x1FBD,
+ },
+ [0x1FBE]={
+ category="ll",
+ contextname="greekprosgegrammeni",
+ description="GREEK PROSGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x03B9 },
+ uccode=0x0399,
+ unicodeslot=0x1FBE,
+ },
+ [0x1FBF]={
+ category="sk",
+ contextname="greekpsili",
+ description="GREEK PSILI",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x0020, 0x0313 },
+ unicodeslot=0x1FBF,
+ },
+ [0x1FC0]={
+ category="sk",
+ contextname="greekperispomeni",
+ description="GREEK PERISPOMENI",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x0020, 0x0342 },
+ unicodeslot=0x1FC0,
+ },
+ [0x1FC1]={
+ category="sk",
+ contextname="greekdialytikaperispomeni",
+ description="GREEK DIALYTIKA AND PERISPOMENI",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x00A8, 0x0342 },
+ unicodeslot=0x1FC1,
+ },
+ [0x1FC2]={
+ category="ll",
+ contextname="greeketaiotasubvaria",
+ description="GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1F74, 0x0345 },
+ unicodeslot=0x1FC2,
+ },
+ [0x1FC3]={
+ category="ll",
+ contextname="greeketaiotasub",
+ description="GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x03B7, 0x0345 },
+ uccode=0x1FCC,
+ unicodeslot=0x1FC3,
+ },
+ [0x1FC4]={
+ category="ll",
+ contextname="greeketaiotasubtonos",
+ description="GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x03AE, 0x0345 },
+ unicodeslot=0x1FC4,
+ },
+ [0x1FC6]={
+ category="ll",
+ contextname="greeketaperispomeni",
+ description="GREEK SMALL LETTER ETA WITH PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x03B7, 0x0342 },
+ unicodeslot=0x1FC6,
+ },
+ [0x1FC7]={
+ category="ll",
+ contextname="greeketaiotasubperispomeni",
+ description="GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B7,
+ specials={ "char", 0x1FC6, 0x0345 },
+ unicodeslot=0x1FC7,
+ },
+ [0x1FC8]={
+ category="lu",
+ contextname="greekEpsilonvaria",
+ description="GREEK CAPITAL LETTER EPSILON WITH VARIA",
+ direction="l",
+ lccode=0x1F72,
+ linebreak="al",
+ shcode=0x0395,
+ specials={ "char", 0x0395, 0x0300 },
+ unicodeslot=0x1FC8,
+ },
+ [0x1FC9]={
+ category="lu",
+ contextname="greekEpsilontonos",
+ description="GREEK CAPITAL LETTER EPSILON WITH OXIA",
+ direction="l",
+ lccode=0x1F73,
+ linebreak="al",
+ shcode=0x0395,
+ specials={ "char", 0x0388 },
+ unicodeslot=0x1FC9,
+ },
+ [0x1FCA]={
+ category="lu",
+ contextname="greekEtavaria",
+ description="GREEK CAPITAL LETTER ETA WITH VARIA",
+ direction="l",
+ lccode=0x1F74,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x0397, 0x0300 },
+ unicodeslot=0x1FCA,
+ },
+ [0x1FCB]={
+ category="lu",
+ contextname="greekEtatonos",
+ description="GREEK CAPITAL LETTER ETA WITH OXIA",
+ direction="l",
+ lccode=0x1F75,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x0389 },
+ unicodeslot=0x1FCB,
+ },
+ [0x1FCC]={
+ category="lt",
+ contextname="greekEtaiotasub",
+ description="GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1FC3,
+ linebreak="al",
+ shcode=0x0397,
+ specials={ "char", 0x0397, 0x0345 },
+ unicodeslot=0x1FCC,
+ },
+ [0x1FCD]={
+ category="sk",
+ contextname="greekpsilivaria",
+ description="GREEK PSILI AND VARIA",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x1FBF, 0x0300 },
+ unicodeslot=0x1FCD,
+ },
+ [0x1FCE]={
+ category="sk",
+ contextname="greekpsilitonos",
+ description="GREEK PSILI AND OXIA",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x1FBF, 0x0301 },
+ unicodeslot=0x1FCE,
+ },
+ [0x1FCF]={
+ category="sk",
+ contextname="greekpsiliperispomeni",
+ description="GREEK PSILI AND PERISPOMENI",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x1FBF, 0x0342 },
+ unicodeslot=0x1FCF,
+ },
+ [0x1FD0]={
+ category="ll",
+ contextname="greekiotavrachy",
+ description="GREEK SMALL LETTER IOTA WITH VRACHY",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x03B9, 0x0306 },
+ uccode=0x1FD8,
+ unicodeslot=0x1FD0,
+ },
+ [0x1FD1]={
+ category="ll",
+ contextname="greekiotamacron",
+ description="GREEK SMALL LETTER IOTA WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x03B9, 0x0304 },
+ uccode=0x1FD9,
+ unicodeslot=0x1FD1,
+ },
+ [0x1FD2]={
+ category="ll",
+ contextname="greekiotadialytikavaria",
+ description="GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x03CA, 0x0300 },
+ unicodeslot=0x1FD2,
+ },
+ [0x1FD3]={
+ category="ll",
+ contextname="greekiotadialytikatonos",
+ description="GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x0390 },
+ unicodeslot=0x1FD3,
+ },
+ [0x1FD6]={
+ category="ll",
+ contextname="greekiotaperispomeni",
+ description="GREEK SMALL LETTER IOTA WITH PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x03B9, 0x0342 },
+ unicodeslot=0x1FD6,
+ },
+ [0x1FD7]={
+ category="ll",
+ contextname="greekiotadialytikaperispomeni",
+ description="GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03B9,
+ specials={ "char", 0x03CA, 0x0342 },
+ unicodeslot=0x1FD7,
+ },
+ [0x1FD8]={
+ category="lu",
+ contextname="greekIotavrachy",
+ description="GREEK CAPITAL LETTER IOTA WITH VRACHY",
+ direction="l",
+ lccode=0x1FD0,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x0399, 0x0306 },
+ unicodeslot=0x1FD8,
+ },
+ [0x1FD9]={
+ category="lu",
+ contextname="greekIotamacron",
+ description="GREEK CAPITAL LETTER IOTA WITH MACRON",
+ direction="l",
+ lccode=0x1FD1,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x0399, 0x0304 },
+ unicodeslot=0x1FD9,
+ },
+ [0x1FDA]={
+ category="lu",
+ contextname="greekIotavaria",
+ description="GREEK CAPITAL LETTER IOTA WITH VARIA",
+ direction="l",
+ lccode=0x1F76,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x0399, 0x0300 },
+ unicodeslot=0x1FDA,
+ },
+ [0x1FDB]={
+ category="lu",
+ contextname="greekIotatonos",
+ description="GREEK CAPITAL LETTER IOTA WITH OXIA",
+ direction="l",
+ lccode=0x1F77,
+ linebreak="al",
+ shcode=0x0399,
+ specials={ "char", 0x038A },
+ unicodeslot=0x1FDB,
+ },
+ [0x1FDD]={
+ category="sk",
+ contextname="greekdasiavaria",
+ description="GREEK DASIA AND VARIA",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x1FFE, 0x0300 },
+ unicodeslot=0x1FDD,
+ },
+ [0x1FDE]={
+ category="sk",
+ contextname="greekdasiatonos",
+ description="GREEK DASIA AND OXIA",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x1FFE, 0x0301 },
+ unicodeslot=0x1FDE,
+ },
+ [0x1FDF]={
+ category="sk",
+ contextname="greekdasiaperispomeni",
+ description="GREEK DASIA AND PERISPOMENI",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x1FFE, 0x0342 },
+ unicodeslot=0x1FDF,
+ },
+ [0x1FE0]={
+ category="ll",
+ contextname="greekupsilonvrachy",
+ description="GREEK SMALL LETTER UPSILON WITH VRACHY",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03C5, 0x0306 },
+ uccode=0x1FE8,
+ unicodeslot=0x1FE0,
+ },
+ [0x1FE1]={
+ category="ll",
+ contextname="greekupsilonmacron",
+ description="GREEK SMALL LETTER UPSILON WITH MACRON",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03C5, 0x0304 },
+ uccode=0x1FE9,
+ unicodeslot=0x1FE1,
+ },
+ [0x1FE2]={
+ category="ll",
+ contextname="greekupsilondialytikavaria",
+ description="GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03CB, 0x0300 },
+ unicodeslot=0x1FE2,
+ },
+ [0x1FE3]={
+ category="ll",
+ contextname="greekupsilondialytikatonos",
+ description="GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03B0 },
+ unicodeslot=0x1FE3,
+ },
+ [0x1FE4]={
+ category="ll",
+ contextname="greekrhopsili",
+ description="GREEK SMALL LETTER RHO WITH PSILI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C1,
+ specials={ "char", 0x03C1, 0x0313 },
+ unicodeslot=0x1FE4,
+ },
+ [0x1FE5]={
+ category="ll",
+ contextname="greekrhodasia",
+ description="GREEK SMALL LETTER RHO WITH DASIA",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C1,
+ specials={ "char", 0x03C1, 0x0314 },
+ uccode=0x1FEC,
+ unicodeslot=0x1FE5,
+ },
+ [0x1FE6]={
+ category="ll",
+ contextname="greekupsilonperispomeni",
+ description="GREEK SMALL LETTER UPSILON WITH PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03C5, 0x0342 },
+ unicodeslot=0x1FE6,
+ },
+ [0x1FE7]={
+ category="ll",
+ contextname="greekupsilondialytikaperispomeni",
+ description="GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C5,
+ specials={ "char", 0x03CB, 0x0342 },
+ unicodeslot=0x1FE7,
+ },
+ [0x1FE8]={
+ category="lu",
+ contextname="greekUpsilonvrachy",
+ description="GREEK CAPITAL LETTER UPSILON WITH VRACHY",
+ direction="l",
+ lccode=0x1FE0,
+ linebreak="al",
+ shcode=0x03A5,
+ specials={ "char", 0x03A5, 0x0306 },
+ unicodeslot=0x1FE8,
+ },
+ [0x1FE9]={
+ category="lu",
+ contextname="greekUpsilonmacron",
+ description="GREEK CAPITAL LETTER UPSILON WITH MACRON",
+ direction="l",
+ lccode=0x1FE1,
+ linebreak="al",
+ shcode=0x03A5,
+ specials={ "char", 0x03A5, 0x0304 },
+ unicodeslot=0x1FE9,
+ },
+ [0x1FEA]={
+ category="lu",
+ contextname="greekUpsilonvaria",
+ description="GREEK CAPITAL LETTER UPSILON WITH VARIA",
+ direction="l",
+ lccode=0x1F7A,
+ linebreak="al",
+ shcode=0x03A5,
+ specials={ "char", 0x03A5, 0x0300 },
+ unicodeslot=0x1FEA,
+ },
+ [0x1FEB]={
+ category="lu",
+ contextname="greekUpsilontonos",
+ description="GREEK CAPITAL LETTER UPSILON WITH OXIA",
+ direction="l",
+ lccode=0x1F7B,
+ linebreak="al",
+ shcode=0x03A5,
+ specials={ "char", 0x038E },
+ unicodeslot=0x1FEB,
+ },
+ [0x1FEC]={
+ category="lu",
+ contextname="greekRhodasia",
+ description="GREEK CAPITAL LETTER RHO WITH DASIA",
+ direction="l",
+ lccode=0x1FE5,
+ linebreak="al",
+ shcode=0x03A1,
+ specials={ "char", 0x03A1, 0x0314 },
+ unicodeslot=0x1FEC,
+ },
+ [0x1FED]={
+ category="sk",
+ contextname="greekdialytikavaria",
+ description="GREEK DIALYTIKA AND VARIA",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x00A8, 0x0300 },
+ unicodeslot=0x1FED,
+ },
+ [0x1FEE]={
+ category="sk",
+ contextname="greekdialytikatonos",
+ description="GREEK DIALYTIKA AND OXIA",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x0385 },
+ unicodeslot=0x1FEE,
+ },
+ [0x1FEF]={
+ category="sk",
+ contextname="greekvaria",
+ description="GREEK VARIA",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x0060 },
+ unicodeslot=0x1FEF,
+ },
+ [0x1FF2]={
+ category="ll",
+ contextname="greekomegaiotasubvaria",
+ description="GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1F7C, 0x0345 },
+ unicodeslot=0x1FF2,
+ },
+ [0x1FF3]={
+ category="ll",
+ contextname="greekomegaiotasub",
+ description="GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x03C9, 0x0345 },
+ uccode=0x1FFC,
+ unicodeslot=0x1FF3,
+ },
+ [0x1FF4]={
+ category="ll",
+ contextname="greekomegaiotasubtonos",
+ description="GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x03CE, 0x0345 },
+ unicodeslot=0x1FF4,
+ },
+ [0x1FF6]={
+ category="ll",
+ contextname="greekomegaperispomeni",
+ description="GREEK SMALL LETTER OMEGA WITH PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x03C9, 0x0342 },
+ unicodeslot=0x1FF6,
+ },
+ [0x1FF7]={
+ category="ll",
+ contextname="greekomegaiotasubperispomeni",
+ description="GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI",
+ direction="l",
+ linebreak="al",
+ shcode=0x03C9,
+ specials={ "char", 0x1FF6, 0x0345 },
+ unicodeslot=0x1FF7,
+ },
+ [0x1FF8]={
+ category="lu",
+ contextname="greekOmicronvaria",
+ description="GREEK CAPITAL LETTER OMICRON WITH VARIA",
+ direction="l",
+ lccode=0x1F78,
+ linebreak="al",
+ shcode=0x039F,
+ specials={ "char", 0x039F, 0x0300 },
+ unicodeslot=0x1FF8,
+ },
+ [0x1FF9]={
+ category="lu",
+ contextname="greekOmicrontonos",
+ description="GREEK CAPITAL LETTER OMICRON WITH OXIA",
+ direction="l",
+ lccode=0x1F79,
+ linebreak="al",
+ shcode=0x039F,
+ specials={ "char", 0x038C },
+ unicodeslot=0x1FF9,
+ },
+ [0x1FFA]={
+ category="lu",
+ contextname="greekOmegavaria",
+ description="GREEK CAPITAL LETTER OMEGA WITH VARIA",
+ direction="l",
+ lccode=0x1F7C,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x03A9, 0x0300 },
+ unicodeslot=0x1FFA,
+ },
+ [0x1FFB]={
+ category="lu",
+ contextname="greekOmegatonos",
+ description="GREEK CAPITAL LETTER OMEGA WITH OXIA",
+ direction="l",
+ lccode=0x1F7D,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x038F },
+ unicodeslot=0x1FFB,
+ },
+ [0x1FFC]={
+ category="lt",
+ contextname="greekOmegaiotasub",
+ description="GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI",
+ direction="l",
+ lccode=0x1FF3,
+ linebreak="al",
+ shcode=0x03A9,
+ specials={ "char", 0x03A9, 0x0345 },
+ unicodeslot=0x1FFC,
+ },
+ [0x1FFD]={
+ category="sk",
+ contextname="greekoxia",
+ description="GREEK OXIA",
+ direction="on",
+ linebreak="bb",
+ specials={ "char", 0x00B4 },
+ unicodeslot=0x1FFD,
+ },
+ [0x1FFE]={
+ category="sk",
+ contextname="greekdasia",
+ description="GREEK DASIA",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x0020, 0x0314 },
+ unicodeslot=0x1FFE,
+ },
+ [0x2000]={
+ category="zs",
+ description="EN QUAD",
+ direction="ws",
+ linebreak="ba",
+ specials={ "char", 0x2002 },
+ unicodeslot=0x2000,
+ },
+ [0x2001]={
+ category="zs",
+ description="EM QUAD",
+ direction="ws",
+ linebreak="ba",
+ specials={ "char", 0x2003 },
+ unicodeslot=0x2001,
+ },
+ [0x2002]={
+ adobename="enspace",
+ category="zs",
+ contextname="enspace",
+ description="EN SPACE",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x0020 },
+ unicodeslot=0x2002,
+ },
+ [0x2003]={
+ category="zs",
+ contextname="emspace",
+ description="EM SPACE",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x0020 },
+ unicodeslot=0x2003,
+ },
+ [0x2004]={
+ category="zs",
+ contextname="threeperemspace",
+ description="THREE-PER-EM SPACE",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x0020 },
+ unicodeslot=0x2004,
+ },
+ [0x2005]={
+ category="zs",
+ contextname="fourperemspace",
+ description="FOUR-PER-EM SPACE",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x0020 },
+ unicodeslot=0x2005,
+ },
+ [0x2006]={
+ category="zs",
+ contextname="sixperemspace",
+ description="SIX-PER-EM SPACE",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x0020 },
+ unicodeslot=0x2006,
+ },
+ [0x2007]={
+ category="zs",
+ contextname="figurespace",
+ description="FIGURE SPACE",
+ direction="ws",
+ linebreak="gl",
+ specials={ "nobreak", 0x0020 },
+ unicodeslot=0x2007,
+ },
+ [0x2008]={
+ category="zs",
+ contextname="punctuationspace",
+ description="PUNCTUATION SPACE",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x0020 },
+ unicodeslot=0x2008,
+ },
+ [0x2009]={
+ category="zs",
+ contextname="breakablethinspace",
+ description="THIN SPACE",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x0020 },
+ unicodeslot=0x2009,
+ },
+ [0x200A]={
+ category="zs",
+ contextname="hairspace",
+ description="HAIR SPACE",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x0020 },
+ unicodeslot=0x200A,
+ },
+ [0x200B]={
+ adobename="zerowidthspace",
+ category="cf",
+ contextname="zerowidthspace",
+ description="ZERO WIDTH SPACE",
+ direction="bn",
+ linebreak="zw",
+ unicodeslot=0x200B,
+ },
+ [0x200C]={
+ adobename="zerowidthnonjoiner",
+ arabic="u",
+ category="cf",
+ contextname="zwnj",
+ description="ZERO WIDTH NON-JOINER",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x200C,
+ },
+ [0x200D]={
+ adobename="afii301",
+ arabic="c",
+ category="cf",
+ contextname="zwj",
+ description="ZERO WIDTH JOINER",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x200D,
+ },
+ [0x200E]={
+ adobename="afii299",
+ category="cf",
+ description="LEFT-TO-RIGHT MARK",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x200E,
+ },
+ [0x200F]={
+ adobename="afii300",
+ category="cf",
+ description="RIGHT-TO-LEFT MARK",
+ direction="r",
+ linebreak="cm",
+ unicodeslot=0x200F,
+ },
+ [0x2010]={
+ adobename="hyphentwo",
+ category="pd",
+ cjkwd="a",
+ description="HYPHEN",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2010,
+ },
+ [0x2011]={
+ category="pd",
+ description="NON-BREAKING HYPHEN",
+ direction="on",
+ linebreak="gl",
+ specials={ "nobreak", 0x2010 },
+ unicodeslot=0x2011,
+ },
+ [0x2012]={
+ adobename="figuredash",
+ category="pd",
+ contextname="textminus",
+ description="FIGURE DASH",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2012,
+ },
+ [0x2013]={
+ adobename="endash",
+ category="pd",
+ cjkwd="a",
+ contextname="endash",
+ description="EN DASH",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2013,
+ },
+ [0x2014]={
+ adobename="emdash",
+ category="pd",
+ cjkwd="a",
+ contextname="emdash",
+ description="EM DASH",
+ direction="on",
+ linebreak="b2",
+ unicodeslot=0x2014,
+ },
+ [0x2015]={
+ adobename="horizontalbar",
+ category="pd",
+ cjkwd="a",
+ contextname="texthorizontalbar",
+ description="HORIZONTAL BAR",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2015,
+ },
+ [0x2016]={
+ adobename="dblverticalbar",
+ category="po",
+ cjkwd="a",
+ description="DOUBLE VERTICAL LINE",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="delimiter",
+ name="Vert",
+ },
+ {
+ class="nothing",
+ name="Arrowvert",
+ },
+ {
+ class="open",
+ name="lVert",
+ },
+ {
+ class="close",
+ name="rVert",
+ },
+ },
+ unicodeslot=0x2016,
+ },
+ [0x2017]={
+ adobename="underscoredbl",
+ category="po",
+ description="DOUBLE LOW LINE",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x0020, 0x0333 },
+ unicodeslot=0x2017,
+ },
+ [0x2018]={
+ adobename="quoteleft",
+ category="pi",
+ cjkwd="a",
+ contextname="quoteleft",
+ description="LEFT SINGLE QUOTATION MARK",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2018,
+ },
+ [0x2019]={
+ adobename="quoteright",
+ category="pf",
+ cjkwd="a",
+ contextname="quoteright",
+ description="RIGHT SINGLE QUOTATION MARK",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2019,
+ },
+ [0x201A]={
+ adobename="quotesinglbase",
+ category="ps",
+ contextname="quotesinglebase",
+ description="SINGLE LOW-0x0009 QUOTATION MARK",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0x201A,
+ },
+ [0x201B]={
+ adobename="quotereversed",
+ category="pi",
+ description="SINGLE HIGH-REVERSED-0x0009 QUOTATION MARK",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x201B,
+ },
+ [0x201C]={
+ adobename="quotedblleft",
+ category="pi",
+ cjkwd="a",
+ contextname="quotedblleft",
+ description="LEFT DOUBLE QUOTATION MARK",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x201C,
+ },
+ [0x201D]={
+ adobename="quotedblright",
+ category="pf",
+ cjkwd="a",
+ contextname="quotedblright",
+ description="RIGHT DOUBLE QUOTATION MARK",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x201D,
+ },
+ [0x201E]={
+ adobename="quotedblbase",
+ category="ps",
+ contextname="quotedblbase",
+ description="DOUBLE LOW-0x0009 QUOTATION MARK",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0x201E,
+ },
+ [0x201F]={
+ category="pi",
+ description="DOUBLE HIGH-REVERSED-0x0009 QUOTATION MARK",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x201F,
+ },
+ [0x2020]={
+ adobename="dagger",
+ category="po",
+ cjkwd="a",
+ contextname="textdag",
+ description="DAGGER",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="binary",
+ name="dagger",
+ },
+ {
+ class="box",
+ name="dag",
+ },
+ },
+ unicodeslot=0x2020,
+ },
+ [0x2021]={
+ adobename="daggerdbl",
+ category="po",
+ cjkwd="a",
+ contextname="textddag",
+ description="DOUBLE DAGGER",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="binary",
+ name="ddagger",
+ },
+ {
+ class="box",
+ name="ddag",
+ },
+ },
+ unicodeslot=0x2021,
+ },
+ [0x2022]={
+ adobename="bullet",
+ category="po",
+ cjkwd="a",
+ contextname="textbullet",
+ description="BULLET",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="bullet",
+ unicodeslot=0x2022,
+ },
+ [0x2023]={
+ category="po",
+ description="TRIANGULAR BULLET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2023,
+ },
+ [0x2024]={
+ adobename="onedotenleader",
+ category="po",
+ cjkwd="a",
+ description="ONE DOT LEADER",
+ direction="on",
+ linebreak="in",
+ specials={ "compat", 0x002E },
+ unicodeslot=0x2024,
+ },
+ [0x2025]={
+ adobename="twodotleader",
+ category="po",
+ cjkwd="a",
+ description="TWO DOT LEADER",
+ direction="on",
+ linebreak="in",
+ specials={ "compat", 0x002E, 0x002E },
+ unicodeslot=0x2025,
+ },
+ [0x2026]={
+ adobename="ellipsis",
+ category="po",
+ cjkwd="a",
+ contextname="textellipsis",
+ description="HORIZONTAL ELLIPSIS",
+ direction="on",
+ linebreak="in",
+ mathspec={
+ {
+ class="inner",
+ name="ldots",
+ },
+ {
+ class="inner",
+ name="dots",
+ },
+ },
+ specials={ "compat", 0x002E, 0x002E, 0x002E },
+ unicodeslot=0x2026,
+ },
+ [0x2027]={
+ category="po",
+ cjkwd="a",
+ description="HYPHENATION POINT",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2027,
+ },
+ [0x2028]={
+ category="zl",
+ description="LINE SEPARATOR",
+ direction="ws",
+ linebreak="bk",
+ unicodeslot=0x2028,
+ },
+ [0x2029]={
+ category="zp",
+ description="PARAGRAPH SEPARATOR",
+ direction="b",
+ linebreak="bk",
+ unicodeslot=0x2029,
+ },
+ [0x202A]={
+ category="cf",
+ description="LEFT-TO-RIGHT EMBEDDING",
+ direction="lre",
+ linebreak="cm",
+ unicodeslot=0x202A,
+ },
+ [0x202B]={
+ category="cf",
+ description="RIGHT-TO-LEFT EMBEDDING",
+ direction="rle",
+ linebreak="cm",
+ unicodeslot=0x202B,
+ },
+ [0x202C]={
+ adobename="afii61573",
+ category="cf",
+ description="POP DIRECTIONAL FORMATTING",
+ direction="pdf",
+ linebreak="cm",
+ unicodeslot=0x202C,
+ },
+ [0x202D]={
+ adobename="afii61574",
+ category="cf",
+ description="LEFT-TO-RIGHT OVERRIDE",
+ direction="lro",
+ linebreak="cm",
+ unicodeslot=0x202D,
+ },
+ [0x202E]={
+ adobename="afii61575",
+ category="cf",
+ description="RIGHT-TO-LEFT OVERRIDE",
+ direction="rlo",
+ linebreak="cm",
+ unicodeslot=0x202E,
+ },
+ [0x202F]={
+ category="zs",
+ contextname="narrownobreakspace",
+ description="NARROW NO-BREAK SPACE",
+ direction="cs",
+ linebreak="gl",
+ specials={ "nobreak", 0x0020 },
+ unicodeslot=0x202F,
+ },
+ [0x2030]={
+ adobename="perthousand",
+ category="po",
+ cjkwd="a",
+ contextname="perthousand",
+ description="PER MILLE SIGN",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x2030,
+ },
+ [0x2031]={
+ category="po",
+ description="PER TEN THOUSAND SIGN",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x2031,
+ },
+ [0x2032]={
+ adobename="minute",
+ category="po",
+ cjkwd="a",
+ description="PRIME",
+ direction="et",
+ linebreak="po",
+ mathclass="nothing",
+ mathname="prime",
+ unicodeslot=0x2032,
+ },
+ [0x2033]={
+ adobename="second",
+ category="po",
+ cjkwd="a",
+ description="DOUBLE PRIME",
+ direction="et",
+ linebreak="po",
+ mathclass="nothing",
+ mathname="doubleprime",
+ specials={ "compat", 0x2032, 0x2032 },
+ unicodeslot=0x2033,
+ },
+ [0x2034]={
+ category="po",
+ description="TRIPLE PRIME",
+ direction="et",
+ linebreak="po",
+ mathclass="nothing",
+ mathname="tripleprime",
+ specials={ "compat", 0x2032, 0x2032, 0x2032 },
+ unicodeslot=0x2034,
+ },
+ [0x2035]={
+ adobename="primereversed",
+ category="po",
+ cjkwd="a",
+ description="REVERSED PRIME",
+ direction="on",
+ linebreak="po",
+ unicodeslot=0x2035,
+ },
+ [0x2036]={
+ category="po",
+ description="REVERSED DOUBLE PRIME",
+ direction="on",
+ linebreak="po",
+ specials={ "compat", 0x2035, 0x2035 },
+ unicodeslot=0x2036,
+ },
+ [0x2037]={
+ category="po",
+ description="REVERSED TRIPLE PRIME",
+ direction="on",
+ linebreak="po",
+ specials={ "compat", 0x2035, 0x2035, 0x2035 },
+ unicodeslot=0x2037,
+ },
+ [0x2038]={
+ category="po",
+ description="CARET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2038,
+ },
+ [0x2039]={
+ adobename="guilsinglleft",
+ category="pi",
+ contextname="guilsingleleft",
+ description="SINGLE LEFT-POINTING ANGLE QUOTATION MARK",
+ direction="on",
+ linebreak="qu",
+ mirror=0x203A,
+ textclass="open",
+ unicodeslot=0x2039,
+ },
+ [0x203A]={
+ adobename="guilsinglright",
+ category="pf",
+ contextname="guilsingleright",
+ description="SINGLE RIGHT-POINTING ANGLE QUOTATION MARK",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2039,
+ textclass="close",
+ unicodeslot=0x203A,
+ },
+ [0x203B]={
+ adobename="referencemark",
+ category="po",
+ cjkwd="a",
+ description="REFERENCE MARK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x203B,
+ },
+ [0x203C]={
+ adobename="exclamdbl",
+ category="po",
+ description="DOUBLE EXCLAMATION MARK",
+ direction="on",
+ linebreak="ns",
+ specials={ "compat", 0x0021, 0x0021 },
+ unicodeslot=0x203C,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x203D]={
+ category="po",
+ description="INTERROBANG",
+ direction="on",
+ linebreak="ns",
+ unicodeslot=0x203D,
+ },
+ [0x203E]={
+ adobename="overline",
+ category="po",
+ cjkwd="a",
+ comment=[[mathspec={ { class="topaccent", name="overbar" }, { class="botaccent", name="underbar" } }"]],
+ description="OVERLINE",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ mathfiller="barfill",
+ mathspec={
+ {
+ class="under",
+ name="underbar",
+ },
+ {
+ class="over",
+ name="overbar",
+ },
+ },
+ mathstretch="h",
+ specials={ "compat", 0x0020, 0x0305 },
+ unicodeslot=0x203E,
+ },
+ [0x203F]={
+ category="pc",
+ description="UNDERTIE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x203F,
+ },
+ [0x2040]={
+ category="pc",
+ description="CHARACTER TIE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2040,
+ },
+ [0x2041]={
+ category="po",
+ description="CARET INSERTION POINT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2041,
+ },
+ [0x2042]={
+ adobename="asterism",
+ category="po",
+ description="ASTERISM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2042,
+ },
+ [0x2043]={
+ category="po",
+ description="HYPHEN BULLET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2043,
+ },
+ [0x2044]={
+ adobename="fraction",
+ category="sm",
+ contextname="textfraction",
+ description="FRACTION SLASH",
+ direction="cs",
+ linebreak="is",
+ mathspec={
+ {
+ class="ordinary",
+ name="slash",
+ },
+ {
+ class="close",
+ name="solidus",
+ },
+ },
+ unicodeslot=0x2044,
+ },
+ [0x2045]={
+ category="ps",
+ description="LEFT SQUARE BRACKET WITH QUILL",
+ direction="on",
+ linebreak="op",
+ mirror=0x2046,
+ unicodeslot=0x2045,
+ },
+ [0x2046]={
+ category="pe",
+ description="RIGHT SQUARE BRACKET WITH QUILL",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2045,
+ unicodeslot=0x2046,
+ },
+ [0x2047]={
+ category="po",
+ description="DOUBLE QUESTION MARK",
+ direction="on",
+ linebreak="ns",
+ specials={ "compat", 0x003F, 0x003F },
+ unicodeslot=0x2047,
+ },
+ [0x2048]={
+ category="po",
+ description="QUESTION EXCLAMATION MARK",
+ direction="on",
+ linebreak="ns",
+ specials={ "compat", 0x003F, 0x0021 },
+ unicodeslot=0x2048,
+ },
+ [0x2049]={
+ category="po",
+ description="EXCLAMATION QUESTION MARK",
+ direction="on",
+ linebreak="ns",
+ specials={ "compat", 0x0021, 0x003F },
+ unicodeslot=0x2049,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x204A]={
+ category="po",
+ description="TIRONIAN SIGN ET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x204A,
+ },
+ [0x204B]={
+ category="po",
+ description="REVERSED PILCROW SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x204B,
+ },
+ [0x204C]={
+ category="po",
+ description="BLACK LEFTWARDS BULLET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x204C,
+ },
+ [0x204D]={
+ category="po",
+ description="BLACK RIGHTWARDS BULLET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x204D,
+ },
+ [0x204E]={
+ category="po",
+ description="LOW ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x204E,
+ },
+ [0x204F]={
+ category="po",
+ description="REVERSED SEMICOLON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x204F,
+ },
+ [0x2050]={
+ category="po",
+ description="CLOSE UP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2050,
+ },
+ [0x2051]={
+ category="po",
+ description="TWO ASTERISKS ALIGNED VERTICALLY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2051,
+ },
+ [0x2052]={
+ category="sm",
+ description="COMMERCIAL MINUS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2052,
+ },
+ [0x2053]={
+ category="po",
+ description="SWUNG DASH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2053,
+ },
+ [0x2054]={
+ category="pc",
+ description="INVERTED UNDERTIE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2054,
+ },
+ [0x2055]={
+ category="po",
+ description="FLOWER PUNCTUATION MARK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2055,
+ },
+ [0x2056]={
+ category="po",
+ description="THREE DOT PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2056,
+ },
+ [0x2057]={
+ category="po",
+ description="QUADRUPLE PRIME",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x2032, 0x2032, 0x2032, 0x2032 },
+ unicodeslot=0x2057,
+ },
+ [0x2058]={
+ category="po",
+ description="FOUR DOT PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2058,
+ },
+ [0x2059]={
+ category="po",
+ description="FIVE DOT PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2059,
+ },
+ [0x205A]={
+ category="po",
+ description="TWO DOT PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x205A,
+ },
+ [0x205B]={
+ category="po",
+ description="FOUR DOT MARK",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x205B,
+ },
+ [0x205C]={
+ category="po",
+ description="DOTTED CROSS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x205C,
+ },
+ [0x205D]={
+ category="po",
+ description="TRICOLON",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x205D,
+ },
+ [0x205E]={
+ category="po",
+ description="VERTICAL FOUR DOTS",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x205E,
+ },
+ [0x205F]={
+ category="zs",
+ contextname="medspace",
+ description="MEDIUM MATHEMATICAL SPACE",
+ direction="ws",
+ linebreak="ba",
+ specials={ "compat", 0x0020 },
+ unicodeslot=0x205F,
+ },
+ [0x2060]={
+ category="cf",
+ description="WORD JOINER",
+ direction="bn",
+ linebreak="wj",
+ unicodeslot=0x2060,
+ },
+ [0x2061]={
+ category="cf",
+ comment="maybe: nulloperator",
+ contextname="relax",
+ description="FUNCTION APPLICATION",
+ direction="bn",
+ linebreak="al",
+ unicodeslot=0x2061,
+ },
+ [0x2062]={
+ category="cf",
+ description="INVISIBLE TIMES",
+ direction="bn",
+ linebreak="al",
+ unicodeslot=0x2062,
+ },
+ [0x2063]={
+ category="cf",
+ description="INVISIBLE SEPARATOR",
+ direction="bn",
+ linebreak="al",
+ unicodeslot=0x2063,
+ },
+ [0x2064]={
+ category="cf",
+ description="INVISIBLE PLUS",
+ direction="bn",
+ linebreak="al",
+ unicodeslot=0x2064,
+ },
+ [0x206A]={
+ category="cf",
+ description="INHIBIT SYMMETRIC SWAPPING",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x206A,
+ },
+ [0x206B]={
+ category="cf",
+ description="ACTIVATE SYMMETRIC SWAPPING",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x206B,
+ },
+ [0x206C]={
+ category="cf",
+ description="INHIBIT ARABIC FORM SHAPING",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x206C,
+ },
+ [0x206D]={
+ category="cf",
+ description="ACTIVATE ARABIC FORM SHAPING",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x206D,
+ },
+ [0x206E]={
+ category="cf",
+ description="NATIONAL DIGIT SHAPES",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x206E,
+ },
+ [0x206F]={
+ category="cf",
+ description="NOMINAL DIGIT SHAPES",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x206F,
+ },
+ [0x2070]={
+ adobename="zerosuperior",
+ category="no",
+ description="SUPERSCRIPT ZERO",
+ direction="en",
+ linebreak="al",
+ specials={ "super", 0x0030 },
+ unicodeslot=0x2070,
+ },
+ [0x2071]={
+ category="ll",
+ description="SUPERSCRIPT LATIN SMALL LETTER I",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0069 },
+ unicodeslot=0x2071,
+ },
+ [0x2074]={
+ adobename="foursuperior",
+ category="no",
+ cjkwd="a",
+ description="SUPERSCRIPT FOUR",
+ direction="en",
+ linebreak="ai",
+ specials={ "super", 0x0034 },
+ unicodeslot=0x2074,
+ },
+ [0x2075]={
+ adobename="fivesuperior",
+ category="no",
+ description="SUPERSCRIPT FIVE",
+ direction="en",
+ linebreak="al",
+ specials={ "super", 0x0035 },
+ unicodeslot=0x2075,
+ },
+ [0x2076]={
+ adobename="sixsuperior",
+ category="no",
+ description="SUPERSCRIPT SIX",
+ direction="en",
+ linebreak="al",
+ specials={ "super", 0x0036 },
+ unicodeslot=0x2076,
+ },
+ [0x2077]={
+ adobename="sevensuperior",
+ category="no",
+ description="SUPERSCRIPT SEVEN",
+ direction="en",
+ linebreak="al",
+ specials={ "super", 0x0037 },
+ unicodeslot=0x2077,
+ },
+ [0x2078]={
+ adobename="eightsuperior",
+ category="no",
+ description="SUPERSCRIPT EIGHT",
+ direction="en",
+ linebreak="al",
+ specials={ "super", 0x0038 },
+ unicodeslot=0x2078,
+ },
+ [0x2079]={
+ adobename="ninesuperior",
+ category="no",
+ description="SUPERSCRIPT NINE",
+ direction="en",
+ linebreak="al",
+ specials={ "super", 0x0039 },
+ unicodeslot=0x2079,
+ },
+ [0x207A]={
+ adobename="plussuperior",
+ category="sm",
+ description="SUPERSCRIPT PLUS SIGN",
+ direction="es",
+ linebreak="al",
+ mathclass="binary",
+ mathname="positivesign",
+ specials={ "super", 0x002B },
+ unicodeslot=0x207A,
+ },
+ [0x207B]={
+ category="sm",
+ description="SUPERSCRIPT MINUS",
+ direction="es",
+ linebreak="al",
+ mathclass="binary",
+ mathname="negativesign",
+ specials={ "super", 0x2212 },
+ unicodeslot=0x207B,
+ },
+ [0x207C]={
+ adobename="equalsuperior",
+ category="sm",
+ description="SUPERSCRIPT EQUALS SIGN",
+ direction="on",
+ linebreak="al",
+ specials={ "super", 0x003D },
+ unicodeslot=0x207C,
+ },
+ [0x207D]={
+ adobename="parenleftsuperior",
+ category="ps",
+ description="SUPERSCRIPT LEFT PARENTHESIS",
+ direction="on",
+ linebreak="op",
+ mirror=0x207E,
+ textclass="open",
+ specials={ "super", 0x0028 },
+ unicodeslot=0x207D,
+ },
+ [0x207E]={
+ adobename="parenrightsuperior",
+ category="pe",
+ description="SUPERSCRIPT RIGHT PARENTHESIS",
+ direction="on",
+ linebreak="cl",
+ mirror=0x207D,
+ textclass="close",
+ specials={ "super", 0x0029 },
+ unicodeslot=0x207E,
+ },
+ [0x207F]={
+ adobename="nsuperior",
+ category="ll",
+ cjkwd="a",
+ description="SUPERSCRIPT LATIN SMALL LETTER N",
+ direction="l",
+ linebreak="ai",
+ specials={ "super", 0x006E },
+ unicodeslot=0x207F,
+ },
+ [0x2080]={
+ adobename="zeroinferior",
+ category="no",
+ description="SUBSCRIPT ZERO",
+ direction="en",
+ linebreak="al",
+ specials={ "sub", 0x0030 },
+ unicodeslot=0x2080,
+ },
+ [0x2081]={
+ adobename="oneinferior",
+ category="no",
+ cjkwd="a",
+ description="SUBSCRIPT ONE",
+ direction="en",
+ linebreak="ai",
+ specials={ "sub", 0x0031 },
+ unicodeslot=0x2081,
+ },
+ [0x2082]={
+ adobename="twoinferior",
+ category="no",
+ cjkwd="a",
+ description="SUBSCRIPT TWO",
+ direction="en",
+ linebreak="ai",
+ specials={ "sub", 0x0032 },
+ unicodeslot=0x2082,
+ },
+ [0x2083]={
+ adobename="threeinferior",
+ category="no",
+ cjkwd="a",
+ description="SUBSCRIPT THREE",
+ direction="en",
+ linebreak="ai",
+ specials={ "sub", 0x0033 },
+ unicodeslot=0x2083,
+ },
+ [0x2084]={
+ adobename="fourinferior",
+ category="no",
+ cjkwd="a",
+ description="SUBSCRIPT FOUR",
+ direction="en",
+ linebreak="ai",
+ specials={ "sub", 0x0034 },
+ unicodeslot=0x2084,
+ },
+ [0x2085]={
+ adobename="fiveinferior",
+ category="no",
+ description="SUBSCRIPT FIVE",
+ direction="en",
+ linebreak="al",
+ specials={ "sub", 0x0035 },
+ unicodeslot=0x2085,
+ },
+ [0x2086]={
+ adobename="sixinferior",
+ category="no",
+ description="SUBSCRIPT SIX",
+ direction="en",
+ linebreak="al",
+ specials={ "sub", 0x0036 },
+ unicodeslot=0x2086,
+ },
+ [0x2087]={
+ adobename="seveninferior",
+ category="no",
+ description="SUBSCRIPT SEVEN",
+ direction="en",
+ linebreak="al",
+ specials={ "sub", 0x0037 },
+ unicodeslot=0x2087,
+ },
+ [0x2088]={
+ adobename="eightinferior",
+ category="no",
+ description="SUBSCRIPT EIGHT",
+ direction="en",
+ linebreak="al",
+ specials={ "sub", 0x0038 },
+ unicodeslot=0x2088,
+ },
+ [0x2089]={
+ adobename="nineinferior",
+ category="no",
+ description="SUBSCRIPT NINE",
+ direction="en",
+ linebreak="al",
+ specials={ "sub", 0x0039 },
+ unicodeslot=0x2089,
+ },
+ [0x208A]={
+ category="sm",
+ description="SUBSCRIPT PLUS SIGN",
+ direction="es",
+ linebreak="al",
+ specials={ "sub", 0x002B },
+ unicodeslot=0x208A,
+ },
+ [0x208B]={
+ category="sm",
+ description="SUBSCRIPT MINUS",
+ direction="es",
+ linebreak="al",
+ specials={ "sub", 0x2212 },
+ unicodeslot=0x208B,
+ },
+ [0x208C]={
+ category="sm",
+ description="SUBSCRIPT EQUALS SIGN",
+ direction="on",
+ linebreak="al",
+ specials={ "sub", 0x003D },
+ unicodeslot=0x208C,
+ },
+ [0x208D]={
+ adobename="parenleftinferior",
+ category="ps",
+ description="SUBSCRIPT LEFT PARENTHESIS",
+ direction="on",
+ linebreak="op",
+ mirror=0x208E,
+ textclass="open",
+ specials={ "sub", 0x0028 },
+ unicodeslot=0x208D,
+ },
+ [0x208E]={
+ adobename="parenrightinferior",
+ category="pe",
+ description="SUBSCRIPT RIGHT PARENTHESIS",
+ direction="on",
+ linebreak="cl",
+ mirror=0x208D,
+ textclass="close",
+ specials={ "sub", 0x0029 },
+ unicodeslot=0x208E,
+ },
+ [0x2090]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER A",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x0061 },
+ unicodeslot=0x2090,
+ },
+ [0x2091]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER E",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x0065 },
+ unicodeslot=0x2091,
+ },
+ [0x2092]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER O",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x006F },
+ unicodeslot=0x2092,
+ },
+ [0x2093]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER X",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x0078 },
+ unicodeslot=0x2093,
+ },
+ [0x2094]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER SCHWA",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x0259 },
+ unicodeslot=0x2094,
+ },
+ [0x2095]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER H",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x0068 },
+ unicodeslot=0x2095,
+ },
+ [0x2096]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER K",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x006B },
+ unicodeslot=0x2096,
+ },
+ [0x2097]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER L",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x006C },
+ unicodeslot=0x2097,
+ },
+ [0x2098]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER M",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x006D },
+ unicodeslot=0x2098,
+ },
+ [0x2099]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER N",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x006E },
+ unicodeslot=0x2099,
+ },
+ [0x209A]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER P",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x0070 },
+ unicodeslot=0x209A,
+ },
+ [0x209B]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER S",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x0073 },
+ unicodeslot=0x209B,
+ },
+ [0x209C]={
+ category="lm",
+ description="LATIN SUBSCRIPT SMALL LETTER T",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x0074 },
+ unicodeslot=0x209C,
+ },
+ [0x20A0]={
+ category="sc",
+ description="EURO-CURRENCY SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A0,
+ },
+ [0x20A1]={
+ adobename="colonsign",
+ category="sc",
+ description="COLON SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A1,
+ },
+ [0x20A2]={
+ adobename="cruzeiro",
+ category="sc",
+ description="CRUZEIRO SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A2,
+ },
+ [0x20A3]={
+ adobename="franc",
+ category="sc",
+ description="FRENCH FRANC SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A3,
+ },
+ [0x20A4]={
+ adobename="lira",
+ category="sc",
+ description="LIRA SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A4,
+ },
+ [0x20A5]={
+ category="sc",
+ description="MILL SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A5,
+ },
+ [0x20A6]={
+ category="sc",
+ description="NAIRA SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A6,
+ },
+ [0x20A7]={
+ adobename="peseta",
+ category="sc",
+ description="PESETA SIGN",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x20A7,
+ },
+ [0x20A8]={
+ category="sc",
+ description="RUPEE SIGN",
+ direction="et",
+ linebreak="pr",
+ specials={ "compat", 0x0052, 0x0073 },
+ unicodeslot=0x20A8,
+ },
+ [0x20A9]={
+ adobename="won",
+ category="sc",
+ cjkwd="h",
+ description="WON SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20A9,
+ },
+ [0x20AA]={
+ adobename="sheqelhebrew",
+ category="sc",
+ description="NEW SHEQEL SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20AA,
+ },
+ [0x20AB]={
+ adobename="dong",
+ category="sc",
+ contextname="textdong",
+ description="DONG SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20AB,
+ },
+ [0x20AC]={
+ adobename="euro",
+ category="sc",
+ cjkwd="a",
+ contextname="texteuro",
+ description="EURO SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20AC,
+ },
+ [0x20AD]={
+ category="sc",
+ description="KIP SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20AD,
+ },
+ [0x20AE]={
+ category="sc",
+ description="TUGRIK SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20AE,
+ },
+ [0x20AF]={
+ category="sc",
+ description="DRACHMA SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20AF,
+ },
+ [0x20B0]={
+ category="sc",
+ description="GERMAN PENNY SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B0,
+ },
+ [0x20B1]={
+ category="sc",
+ description="PESO SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B1,
+ },
+ [0x20B2]={
+ category="sc",
+ description="GUARANI SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B2,
+ },
+ [0x20B3]={
+ category="sc",
+ description="AUSTRAL SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B3,
+ },
+ [0x20B4]={
+ category="sc",
+ description="HRYVNIA SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B4,
+ },
+ [0x20B5]={
+ category="sc",
+ description="CEDI SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B5,
+ },
+ [0x20B6]={
+ category="sc",
+ description="LIVRE TOURNOIS SIGN",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0x20B6,
+ },
+ [0x20B7]={
+ category="sc",
+ description="SPESMILO SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B7,
+ },
+ [0x20B8]={
+ category="sc",
+ description="TENGE SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B8,
+ },
+ [0x20B9]={
+ category="sc",
+ description="INDIAN RUPEE SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20B9,
+ },
+ [0x20BA]={
+ category="sc",
+ description="TURKISH LIRA SIGN",
+ direction="et",
+ linebreak="pr",
+ unicodeslot=0x20BA,
+ },
+ [0x20D0]={
+ category="mn",
+ description="COMBINING LEFT HARPOON ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D0,
+ },
+ [0x20D1]={
+ category="mn",
+ description="COMBINING RIGHT HARPOON ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D1,
+ },
+ [0x20D2]={
+ category="mn",
+ description="COMBINING LONG VERTICAL LINE OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D2,
+ },
+ [0x20D3]={
+ category="mn",
+ description="COMBINING SHORT VERTICAL LINE OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D3,
+ },
+ [0x20D4]={
+ category="mn",
+ description="COMBINING ANTICLOCKWISE ARROW ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D4,
+ },
+ [0x20D5]={
+ category="mn",
+ description="COMBINING CLOCKWISE ARROW ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D5,
+ },
+ [0x20D6]={
+ category="mn",
+ description="COMBINING LEFT ARROW ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D6,
+ },
+ [0x20D7]={
+ category="mn",
+ description="COMBINING RIGHT ARROW ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ mathclass="topaccent",
+ mathname="vec",
+ unicodeslot=0x20D7,
+ },
+ [0x20D8]={
+ category="mn",
+ description="COMBINING RING OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D8,
+ },
+ [0x20D9]={
+ category="mn",
+ description="COMBINING CLOCKWISE RING OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20D9,
+ },
+ [0x20DA]={
+ category="mn",
+ description="COMBINING ANTICLOCKWISE RING OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20DA,
+ },
+ [0x20DB]={
+ category="mn",
+ description="COMBINING THREE DOTS ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ mathclass="topaccent",
+ mathname="dddot",
+ unicodeslot=0x20DB,
+ },
+ [0x20DC]={
+ category="mn",
+ description="COMBINING FOUR DOTS ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20DC,
+ },
+ [0x20DD]={
+ category="me",
+ description="COMBINING ENCLOSING CIRCLE",
+ direction="nsm",
+ linebreak="cm",
+ mathspec={
+ {
+ class="default",
+ name="bigcircle",
+ },
+ {
+ class="binary",
+ name="bigcircle",
+ },
+ },
+ unicodeslot=0x20DD,
+ },
+ [0x20DE]={
+ category="me",
+ description="COMBINING ENCLOSING SQUARE",
+ direction="nsm",
+ linebreak="cm",
+ mathclass="default",
+ mathname="bigsquare",
+ unicodeslot=0x20DE,
+ },
+ [0x20DF]={
+ category="me",
+ description="COMBINING ENCLOSING DIAMOND",
+ direction="nsm",
+ linebreak="cm",
+ mathclass="default",
+ mathname="bigdiamond",
+ unicodeslot=0x20DF,
+ },
+ [0x20E0]={
+ category="me",
+ description="COMBINING ENCLOSING CIRCLE BACKSLASH",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E0,
+ },
+ [0x20E1]={
+ category="mn",
+ description="COMBINING LEFT RIGHT ARROW ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E1,
+ },
+ [0x20E2]={
+ category="me",
+ description="COMBINING ENCLOSING SCREEN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E2,
+ },
+ [0x20E3]={
+ category="me",
+ description="COMBINING ENCLOSING KEYCAP",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E3,
+ },
+ [0x20E4]={
+ category="me",
+ description="COMBINING ENCLOSING UPWARD POINTING TRIANGLE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E4,
+ },
+ [0x20E5]={
+ category="mn",
+ description="COMBINING REVERSE SOLIDUS OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E5,
+ },
+ [0x20E6]={
+ category="mn",
+ description="COMBINING DOUBLE VERTICAL STROKE OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E6,
+ },
+ [0x20E7]={
+ category="mn",
+ description="COMBINING ANNUITY SYMBOL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E7,
+ },
+ [0x20E8]={
+ category="mn",
+ description="COMBINING TRIPLE UNDERDOT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20E8,
+ },
+ [0x20E9]={
+ category="mn",
+ description="COMBINING WIDE BRIDGE ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ mathclass="topaccent",
+ unicodeslot=0x20E9,
+ },
+ [0x20EA]={
+ category="mn",
+ description="COMBINING LEFTWARDS ARROW OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20EA,
+ },
+ [0x20EB]={
+ category="mn",
+ description="COMBINING LONG DOUBLE SOLIDUS OVERLAY",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20EB,
+ },
+ [0x20EC]={
+ category="mn",
+ description="COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20EC,
+ },
+ [0x20ED]={
+ category="mn",
+ description="COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20ED,
+ },
+ [0x20EE]={
+ category="mn",
+ description="COMBINING LEFT ARROW BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20EE,
+ },
+ [0x20EF]={
+ category="mn",
+ description="COMBINING RIGHT ARROW BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20EF,
+ },
+ [0x20F0]={
+ category="mn",
+ description="COMBINING ASTERISK ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x20F0,
+ },
+ [0x2100]={
+ category="so",
+ description="ACCOUNT OF",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x0061, 0x002F, 0x0063 },
+ unicodeslot=0x2100,
+ },
+ [0x2101]={
+ category="so",
+ description="ADDRESSED TO THE SUBJECT",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x0061, 0x002F, 0x0073 },
+ unicodeslot=0x2101,
+ },
+ [0x2102]={
+ category="lu",
+ description="DOUBLE-STRUCK CAPITAL C",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="complexes",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x2102,
+ },
+ [0x2103]={
+ adobename="centigrade",
+ category="so",
+ cjkwd="a",
+ contextname="textcelsius",
+ description="DEGREE CELSIUS",
+ direction="on",
+ linebreak="po",
+ specials={ "compat", 0x00B0, 0x0043 },
+ unicodeslot=0x2103,
+ },
+ [0x2104]={
+ category="so",
+ description="CENTRE LINE SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2104,
+ },
+ [0x2105]={
+ adobename="careof",
+ category="so",
+ cjkwd="a",
+ description="CARE OF",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0063, 0x002F, 0x006F },
+ unicodeslot=0x2105,
+ },
+ [0x2106]={
+ category="so",
+ description="CADA UNA",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x0063, 0x002F, 0x0075 },
+ unicodeslot=0x2106,
+ },
+ [0x2107]={
+ category="lu",
+ description="EULER CONSTANT",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="Eulerconst",
+ specials={ "compat", 0x0190 },
+ unicodeslot=0x2107,
+ },
+ [0x2108]={
+ category="so",
+ description="SCRUPLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2108,
+ },
+ [0x2109]={
+ adobename="fahrenheit",
+ category="so",
+ cjkwd="a",
+ description="DEGREE FAHRENHEIT",
+ direction="on",
+ linebreak="po",
+ specials={ "compat", 0x00B0, 0x0046 },
+ unicodeslot=0x2109,
+ },
+ [0x210A]={
+ category="ll",
+ description="SCRIPT SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x210A,
+ },
+ [0x210B]={
+ category="lu",
+ description="SCRIPT CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x210B,
+ },
+ [0x210C]={
+ category="lu",
+ description="BLACK-LETTER CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x210C,
+ },
+ [0x210D]={
+ category="lu",
+ description="DOUBLE-STRUCK CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x210D,
+ },
+ [0x210E]={
+ category="ll",
+ description="PLANCK CONSTANT",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="Plankconst",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x210E,
+ },
+ [0x210F]={
+ category="ll",
+ description="PLANCK CONSTANT OVER TWO PI",
+ direction="l",
+ linebreak="al",
+ mathspec={
+ {
+ class="variable",
+ name="hslash",
+ },
+ {
+ class="ordinary",
+ name="hbar",
+ },
+ },
+ specials={ "font", 0x0127 },
+ unicodeslot=0x210F,
+ },
+ [0x2110]={
+ category="lu",
+ description="SCRIPT CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x2110,
+ },
+ [0x2111]={
+ adobename="Ifraktur",
+ category="lu",
+ description="BLACK-LETTER CAPITAL I",
+ direction="l",
+ linebreak="al",
+ mathclass="default",
+ mathname="Im",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x2111,
+ },
+ [0x2112]={
+ category="lu",
+ description="SCRIPT CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x2112,
+ },
+ [0x2113]={
+ adobename="lsquare",
+ category="ll",
+ cjkwd="a",
+ description="SCRIPT SMALL L",
+ direction="l",
+ linebreak="ai",
+ mathclass="default",
+ mathname="ell",
+ specials={ "font", 0x006C },
+ unicodeslot=0x2113,
+ },
+ [0x2114]={
+ category="so",
+ description="L B BAR SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2114,
+ },
+ [0x2115]={
+ category="lu",
+ description="DOUBLE-STRUCK CAPITAL N",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="naturalnumbers",
+ specials={ "font", 0x004E },
+ unicodeslot=0x2115,
+ },
+ [0x2116]={
+ adobename="numero",
+ category="so",
+ cjkwd="a",
+ contextname="textnumero",
+ description="NUMERO SIGN",
+ direction="on",
+ linebreak="pr",
+ specials={ "compat", 0x004E, 0x006F },
+ unicodeslot=0x2116,
+ },
+ [0x2117]={
+ category="so",
+ contextname="textcircledP",
+ description="SOUND RECORDING COPYRIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2117,
+ },
+ [0x2118]={
+ adobename="weierstrass",
+ category="so",
+ description="SCRIPT CAPITAL P",
+ direction="on",
+ linebreak="al",
+ mathclass="default",
+ mathname="wp",
+ unicodeslot=0x2118,
+ },
+ [0x2119]={
+ category="lu",
+ description="DOUBLE-STRUCK CAPITAL P",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="primes",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x2119,
+ },
+ [0x211A]={
+ category="lu",
+ description="DOUBLE-STRUCK CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="rationals",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x211A,
+ },
+ [0x211B]={
+ category="lu",
+ description="SCRIPT CAPITAL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x211B,
+ },
+ [0x211C]={
+ adobename="Rfraktur",
+ category="lu",
+ description="BLACK-LETTER CAPITAL R",
+ direction="l",
+ linebreak="al",
+ mathclass="default",
+ mathname="Re",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x211C,
+ },
+ [0x211D]={
+ category="lu",
+ description="DOUBLE-STRUCK CAPITAL R",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="reals",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x211D,
+ },
+ [0x211E]={
+ adobename="prescription",
+ category="so",
+ description="PRESCRIPTION TAKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x211E,
+ },
+ [0x211F]={
+ category="so",
+ description="RESPONSE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x211F,
+ },
+ [0x2120]={
+ category="so",
+ description="SERVICE MARK",
+ direction="on",
+ linebreak="al",
+ specials={ "super", 0x0053, 0x004D },
+ unicodeslot=0x2120,
+ },
+ [0x2121]={
+ adobename="telephone",
+ category="so",
+ cjkwd="a",
+ description="TELEPHONE SIGN",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0054, 0x0045, 0x004C },
+ unicodeslot=0x2121,
+ },
+ [0x2122]={
+ adobename="trademark",
+ category="so",
+ cjkwd="a",
+ contextname="trademark",
+ description="TRADE MARK SIGN",
+ direction="on",
+ linebreak="ai",
+ specials={ "super", 0x0054, 0x004D },
+ unicodeslot=0x2122,
+ },
+ [0x2123]={
+ category="so",
+ description="VERSICLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2123,
+ },
+ [0x2124]={
+ category="lu",
+ description="DOUBLE-STRUCK CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="integers",
+ specials={ "font", 0x005A },
+ unicodeslot=0x2124,
+ },
+ [0x2125]={
+ category="so",
+ contextname="textounce",
+ description="OUNCE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2125,
+ },
+ [0x2126]={
+ adobename="Omega",
+ category="lu",
+ cjkwd="a",
+ contextname="textohm",
+ description="OHM SIGN",
+ direction="l",
+ lccode=0x03C9,
+ linebreak="al",
+ mathclass="variable",
+ mathname="ohm",
+ specials={ "char", 0x03A9 },
+ unicodeslot=0x2126,
+ },
+ [0x2127]={
+ category="so",
+ contextname="textmho",
+ description="INVERTED OHM SIGN",
+ direction="on",
+ linebreak="al",
+ mathclass="variable",
+ mathname="mho",
+ unicodeslot=0x2127,
+ },
+ [0x2128]={
+ category="lu",
+ description="BLACK-LETTER CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x005A },
+ unicodeslot=0x2128,
+ },
+ [0x2129]={
+ category="so",
+ description="TURNED GREEK SMALL LETTER IOTA",
+ direction="on",
+ linebreak="al",
+ mathclass="variable",
+ mathname="turnediota",
+ unicodeslot=0x2129,
+ },
+ [0x212A]={
+ category="lu",
+ contextname="textkelvin",
+ description="KELVIN SIGN",
+ direction="l",
+ lccode=0x006B,
+ linebreak="al",
+ specials={ "char", 0x004B },
+ unicodeslot=0x212A,
+ },
+ [0x212B]={
+ adobename="angstrom",
+ category="lu",
+ cjkwd="a",
+ contextname="textAngstrom",
+ description="ANGSTROM SIGN",
+ direction="l",
+ lccode=0x00E5,
+ linebreak="ai",
+ mathclass="variable",
+ mathname="Angstrom",
+ specials={ "char", 0x00C5 },
+ unicodeslot=0x212B,
+ },
+ [0x212C]={
+ category="lu",
+ description="SCRIPT CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x212C,
+ },
+ [0x212D]={
+ category="lu",
+ description="BLACK-LETTER CAPITAL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x212D,
+ },
+ [0x212E]={
+ adobename="estimated",
+ category="so",
+ description="ESTIMATED SYMBOL",
+ direction="et",
+ linebreak="al",
+ unicodeslot=0x212E,
+ },
+ [0x212F]={
+ category="ll",
+ description="SCRIPT SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x212F,
+ },
+ [0x2130]={
+ category="lu",
+ description="SCRIPT CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x2130,
+ },
+ [0x2131]={
+ category="lu",
+ description="SCRIPT CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x2131,
+ },
+ [0x2132]={
+ category="lu",
+ description="TURNED CAPITAL F",
+ direction="l",
+ lccode=0x214E,
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="Finv",
+ unicodeslot=0x2132,
+ },
+ [0x2133]={
+ category="lu",
+ description="SCRIPT CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x2133,
+ },
+ [0x2134]={
+ category="ll",
+ description="SCRIPT SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x2134,
+ },
+ [0x2135]={
+ adobename="aleph",
+ category="lo",
+ description="ALEF SYMBOL",
+ direction="l",
+ linebreak="al",
+ mathclass="default",
+ mathname="aleph",
+ specials={ "compat", 0x05D0 },
+ unicodeslot=0x2135,
+ },
+ [0x2136]={
+ category="lo",
+ description="BET SYMBOL",
+ direction="l",
+ linebreak="al",
+ mathclass="default",
+ mathname="beth",
+ specials={ "compat", 0x05D1 },
+ unicodeslot=0x2136,
+ },
+ [0x2137]={
+ category="lo",
+ description="GIMEL SYMBOL",
+ direction="l",
+ linebreak="al",
+ mathclass="default",
+ mathname="gimel",
+ specials={ "compat", 0x05D2 },
+ unicodeslot=0x2137,
+ },
+ [0x2138]={
+ category="lo",
+ description="DALET SYMBOL",
+ direction="l",
+ linebreak="al",
+ mathclass="default",
+ mathname="daleth",
+ specials={ "compat", 0x05D3 },
+ unicodeslot=0x2138,
+ },
+ [0x2139]={
+ category="ll",
+ description="INFORMATION SOURCE",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x2139,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x213A]={
+ category="so",
+ description="ROTATED CAPITAL Q",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x213A,
+ },
+ [0x213B]={
+ category="so",
+ description="FACSIMILE SIGN",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x0046, 0x0041, 0x0058 },
+ unicodeslot=0x213B,
+ },
+ [0x213C]={
+ category="ll",
+ description="DOUBLE-STRUCK SMALL PI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C0 },
+ unicodeslot=0x213C,
+ },
+ [0x213D]={
+ category="ll",
+ description="DOUBLE-STRUCK SMALL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B3 },
+ unicodeslot=0x213D,
+ },
+ [0x213E]={
+ category="lu",
+ description="DOUBLE-STRUCK CAPITAL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0393 },
+ unicodeslot=0x213E,
+ },
+ [0x213F]={
+ category="lu",
+ description="DOUBLE-STRUCK CAPITAL PI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A0 },
+ unicodeslot=0x213F,
+ },
+ [0x2140]={
+ category="sm",
+ description="DOUBLE-STRUCK N-ARY SUMMATION",
+ direction="on",
+ linebreak="al",
+ specials={ "font", 0x2211 },
+ unicodeslot=0x2140,
+ },
+ [0x2141]={
+ category="sm",
+ description="TURNED SANS-SERIF CAPITAL G",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="Game",
+ unicodeslot=0x2141,
+ },
+ [0x2142]={
+ category="sm",
+ comment="mathname=sansLturned",
+ description="TURNED SANS-SERIF CAPITAL L",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ unicodeslot=0x2142,
+ },
+ [0x2143]={
+ category="sm",
+ comment="mathname=sansLmirrored",
+ description="REVERSED SANS-SERIF CAPITAL L",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ unicodeslot=0x2143,
+ },
+ [0x2144]={
+ category="sm",
+ comment="mathname=Yup",
+ description="TURNED SANS-SERIF CAPITAL Y",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ unicodeslot=0x2144,
+ },
+ [0x2145]={
+ category="lu",
+ description="DOUBLE-STRUCK ITALIC CAPITAL D",
+ direction="l",
+ linebreak="al",
+ mathclass="nothing",
+ mathname="differentialD",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x2145,
+ },
+ [0x2146]={
+ category="ll",
+ description="DOUBLE-STRUCK ITALIC SMALL D",
+ direction="l",
+ linebreak="al",
+ mathclass="nothing",
+ mathname="differentiald",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x2146,
+ },
+ [0x2147]={
+ category="ll",
+ description="DOUBLE-STRUCK ITALIC SMALL E",
+ direction="l",
+ linebreak="al",
+ mathclass="nothing",
+ mathname="exponentiale",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x2147,
+ },
+ [0x2148]={
+ category="ll",
+ description="DOUBLE-STRUCK ITALIC SMALL I",
+ direction="l",
+ linebreak="al",
+ mathclass="nothing",
+ mathname="imaginaryi",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x2148,
+ },
+ [0x2149]={
+ category="ll",
+ description="DOUBLE-STRUCK ITALIC SMALL J",
+ direction="l",
+ linebreak="al",
+ mathclass="nothing",
+ mathname="imaginaryj",
+ specials={ "font", 0x006A },
+ unicodeslot=0x2149,
+ },
+ [0x214A]={
+ category="so",
+ description="PROPERTY LINE",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="PropertyLine",
+ unicodeslot=0x214A,
+ },
+ [0x214B]={
+ category="sm",
+ description="TURNED AMPERSAND",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="upand",
+ unicodeslot=0x214B,
+ },
+ [0x214C]={
+ category="so",
+ description="PER SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x214C,
+ },
+ [0x214D]={
+ category="so",
+ description="AKTIESELSKAB",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x214D,
+ },
+ [0x214E]={
+ category="ll",
+ description="TURNED SMALL F",
+ direction="l",
+ linebreak="al",
+ uccode=0x2132,
+ unicodeslot=0x214E,
+ },
+ [0x214F]={
+ category="so",
+ description="SYMBOL FOR SAMARITAN SOURCE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x214F,
+ },
+ [0x2150]={
+ category="no",
+ description="VULGAR FRACTION ONE SEVENTH",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x0031, 0x2044, 0x0037 },
+ unicodeslot=0x2150,
+ },
+ [0x2151]={
+ category="no",
+ description="VULGAR FRACTION ONE NINTH",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x0031, 0x2044, 0x0039 },
+ unicodeslot=0x2151,
+ },
+ [0x2152]={
+ category="no",
+ description="VULGAR FRACTION ONE TENTH",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x0031, 0x2044, 0x0031, 0x0030 },
+ unicodeslot=0x2152,
+ },
+ [0x2153]={
+ adobename="onethird",
+ category="no",
+ cjkwd="a",
+ contextname="onethird",
+ description="VULGAR FRACTION ONE THIRD",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x0031, 0x2044, 0x0033 },
+ unicodeslot=0x2153,
+ },
+ [0x2154]={
+ adobename="twothirds",
+ category="no",
+ cjkwd="a",
+ contextname="twothirds",
+ description="VULGAR FRACTION TWO THIRDS",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x0032, 0x2044, 0x0033 },
+ unicodeslot=0x2154,
+ },
+ [0x2155]={
+ category="no",
+ contextname="onefifth",
+ description="VULGAR FRACTION ONE FIFTH",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x0031, 0x2044, 0x0035 },
+ unicodeslot=0x2155,
+ },
+ [0x2156]={
+ category="no",
+ contextname="twofifths",
+ description="VULGAR FRACTION TWO FIFTHS",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x0032, 0x2044, 0x0035 },
+ unicodeslot=0x2156,
+ },
+ [0x2157]={
+ category="no",
+ contextname="threefifths",
+ description="VULGAR FRACTION THREE FIFTHS",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x0033, 0x2044, 0x0035 },
+ unicodeslot=0x2157,
+ },
+ [0x2158]={
+ category="no",
+ contextname="fourfifths",
+ description="VULGAR FRACTION FOUR FIFTHS",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x0034, 0x2044, 0x0035 },
+ unicodeslot=0x2158,
+ },
+ [0x2159]={
+ category="no",
+ contextname="onesixth",
+ description="VULGAR FRACTION ONE SIXTH",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x0031, 0x2044, 0x0036 },
+ unicodeslot=0x2159,
+ },
+ [0x215A]={
+ category="no",
+ contextname="fivesixths",
+ description="VULGAR FRACTION FIVE SIXTHS",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x0035, 0x2044, 0x0036 },
+ unicodeslot=0x215A,
+ },
+ [0x215B]={
+ adobename="oneeighth",
+ category="no",
+ cjkwd="a",
+ contextname="oneeighth",
+ description="VULGAR FRACTION ONE EIGHTH",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x0031, 0x2044, 0x0038 },
+ unicodeslot=0x215B,
+ },
+ [0x215C]={
+ adobename="threeeighths",
+ category="no",
+ cjkwd="a",
+ contextname="threeeighths",
+ description="VULGAR FRACTION THREE EIGHTHS",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x0033, 0x2044, 0x0038 },
+ unicodeslot=0x215C,
+ },
+ [0x215D]={
+ adobename="fiveeighths",
+ category="no",
+ cjkwd="a",
+ contextname="fiveeighths",
+ description="VULGAR FRACTION FIVE EIGHTHS",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x0035, 0x2044, 0x0038 },
+ unicodeslot=0x215D,
+ },
+ [0x215E]={
+ adobename="seveneighths",
+ category="no",
+ cjkwd="a",
+ contextname="seveneighths",
+ description="VULGAR FRACTION SEVEN EIGHTHS",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x0037, 0x2044, 0x0038 },
+ unicodeslot=0x215E,
+ },
+ [0x215F]={
+ category="no",
+ description="FRACTION NUMERATOR ONE",
+ direction="on",
+ linebreak="al",
+ specials={ "fraction", 0x0031, 0x2044 },
+ unicodeslot=0x215F,
+ },
+ [0x2160]={
+ adobename="Oneroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanI",
+ description="ROMAN NUMERAL ONE",
+ direction="l",
+ lccode=0x2170,
+ linebreak="ai",
+ specials={ "compat", 0x0049 },
+ unicodeslot=0x2160,
+ },
+ [0x2161]={
+ adobename="Tworoman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanII",
+ description="ROMAN NUMERAL TWO",
+ direction="l",
+ lccode=0x2171,
+ linebreak="ai",
+ specials={ "compat", 0x0049, 0x0049 },
+ unicodeslot=0x2161,
+ },
+ [0x2162]={
+ adobename="Threeroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanIII",
+ description="ROMAN NUMERAL THREE",
+ direction="l",
+ lccode=0x2172,
+ linebreak="ai",
+ specials={ "compat", 0x0049, 0x0049, 0x0049 },
+ unicodeslot=0x2162,
+ },
+ [0x2163]={
+ adobename="Fourroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanIV",
+ description="ROMAN NUMERAL FOUR",
+ direction="l",
+ lccode=0x2173,
+ linebreak="ai",
+ specials={ "compat", 0x0049, 0x0056 },
+ unicodeslot=0x2163,
+ },
+ [0x2164]={
+ adobename="Fiveroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanV",
+ description="ROMAN NUMERAL FIVE",
+ direction="l",
+ lccode=0x2174,
+ linebreak="ai",
+ specials={ "compat", 0x0056 },
+ unicodeslot=0x2164,
+ },
+ [0x2165]={
+ adobename="Sixroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanVI",
+ description="ROMAN NUMERAL SIX",
+ direction="l",
+ lccode=0x2175,
+ linebreak="ai",
+ specials={ "compat", 0x0056, 0x0049 },
+ unicodeslot=0x2165,
+ },
+ [0x2166]={
+ adobename="Sevenroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanVII",
+ description="ROMAN NUMERAL SEVEN",
+ direction="l",
+ lccode=0x2176,
+ linebreak="ai",
+ specials={ "compat", 0x0056, 0x0049, 0x0049 },
+ unicodeslot=0x2166,
+ },
+ [0x2167]={
+ adobename="Eightroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanVIII",
+ description="ROMAN NUMERAL EIGHT",
+ direction="l",
+ lccode=0x2177,
+ linebreak="ai",
+ specials={ "compat", 0x0056, 0x0049, 0x0049, 0x0049 },
+ unicodeslot=0x2167,
+ },
+ [0x2168]={
+ adobename="Nineroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanIX",
+ description="ROMAN NUMERAL NINE",
+ direction="l",
+ lccode=0x2178,
+ linebreak="ai",
+ specials={ "compat", 0x0049, 0x0058 },
+ unicodeslot=0x2168,
+ },
+ [0x2169]={
+ adobename="Tenroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanX",
+ description="ROMAN NUMERAL TEN",
+ direction="l",
+ lccode=0x2179,
+ linebreak="ai",
+ specials={ "compat", 0x0058 },
+ unicodeslot=0x2169,
+ },
+ [0x216A]={
+ adobename="Elevenroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanXI",
+ description="ROMAN NUMERAL ELEVEN",
+ direction="l",
+ lccode=0x217A,
+ linebreak="ai",
+ specials={ "compat", 0x0058, 0x0049 },
+ unicodeslot=0x216A,
+ },
+ [0x216B]={
+ adobename="Twelveroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanXII",
+ description="ROMAN NUMERAL TWELVE",
+ direction="l",
+ lccode=0x217B,
+ linebreak="ai",
+ specials={ "compat", 0x0058, 0x0049, 0x0049 },
+ unicodeslot=0x216B,
+ },
+ [0x216C]={
+ category="nl",
+ contextname="romanL",
+ description="ROMAN NUMERAL FIFTY",
+ direction="l",
+ lccode=0x217C,
+ linebreak="al",
+ specials={ "compat", 0x004C },
+ unicodeslot=0x216C,
+ },
+ [0x216D]={
+ category="nl",
+ contextname="romanC",
+ description="ROMAN NUMERAL ONE HUNDRED",
+ direction="l",
+ lccode=0x217D,
+ linebreak="al",
+ specials={ "compat", 0x0043 },
+ unicodeslot=0x216D,
+ },
+ [0x216E]={
+ category="nl",
+ contextname="romanD",
+ description="ROMAN NUMERAL FIVE HUNDRED",
+ direction="l",
+ lccode=0x217E,
+ linebreak="al",
+ specials={ "compat", 0x0044 },
+ unicodeslot=0x216E,
+ },
+ [0x216F]={
+ category="nl",
+ contextname="romanM",
+ description="ROMAN NUMERAL ONE THOUSAND",
+ direction="l",
+ lccode=0x217F,
+ linebreak="al",
+ specials={ "compat", 0x004D },
+ unicodeslot=0x216F,
+ },
+ [0x2170]={
+ adobename="oneroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romani",
+ description="SMALL ROMAN NUMERAL ONE",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0069 },
+ uccode=0x2160,
+ unicodeslot=0x2170,
+ },
+ [0x2171]={
+ adobename="tworoman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanii",
+ description="SMALL ROMAN NUMERAL TWO",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0069, 0x0069 },
+ uccode=0x2161,
+ unicodeslot=0x2171,
+ },
+ [0x2172]={
+ adobename="threeroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romaniii",
+ description="SMALL ROMAN NUMERAL THREE",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0069, 0x0069, 0x0069 },
+ uccode=0x2162,
+ unicodeslot=0x2172,
+ },
+ [0x2173]={
+ adobename="fourroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romaniv",
+ description="SMALL ROMAN NUMERAL FOUR",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0069, 0x0076 },
+ uccode=0x2163,
+ unicodeslot=0x2173,
+ },
+ [0x2174]={
+ adobename="fiveroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanv",
+ description="SMALL ROMAN NUMERAL FIVE",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0076 },
+ uccode=0x2164,
+ unicodeslot=0x2174,
+ },
+ [0x2175]={
+ adobename="sixroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanvi",
+ description="SMALL ROMAN NUMERAL SIX",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0076, 0x0069 },
+ uccode=0x2165,
+ unicodeslot=0x2175,
+ },
+ [0x2176]={
+ adobename="sevenroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanvii",
+ description="SMALL ROMAN NUMERAL SEVEN",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0076, 0x0069, 0x0069 },
+ uccode=0x2166,
+ unicodeslot=0x2176,
+ },
+ [0x2177]={
+ adobename="eightroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanviii",
+ description="SMALL ROMAN NUMERAL EIGHT",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0076, 0x0069, 0x0069, 0x0069 },
+ uccode=0x2167,
+ unicodeslot=0x2177,
+ },
+ [0x2178]={
+ adobename="nineroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanix",
+ description="SMALL ROMAN NUMERAL NINE",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0069, 0x0078 },
+ uccode=0x2168,
+ unicodeslot=0x2178,
+ },
+ [0x2179]={
+ adobename="tenroman",
+ category="nl",
+ cjkwd="a",
+ contextname="romanx",
+ description="SMALL ROMAN NUMERAL TEN",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0078 },
+ uccode=0x2169,
+ unicodeslot=0x2179,
+ },
+ [0x217A]={
+ adobename="elevenroman",
+ category="nl",
+ contextname="romanxi",
+ description="SMALL ROMAN NUMERAL ELEVEN",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0078, 0x0069 },
+ uccode=0x216A,
+ unicodeslot=0x217A,
+ },
+ [0x217B]={
+ adobename="twelveroman",
+ category="nl",
+ contextname="romanxii",
+ description="SMALL ROMAN NUMERAL TWELVE",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0078, 0x0069, 0x0069 },
+ uccode=0x216B,
+ unicodeslot=0x217B,
+ },
+ [0x217C]={
+ category="nl",
+ contextname="romanl",
+ description="SMALL ROMAN NUMERAL FIFTY",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x006C },
+ uccode=0x216C,
+ unicodeslot=0x217C,
+ },
+ [0x217D]={
+ category="nl",
+ contextname="romanc",
+ description="SMALL ROMAN NUMERAL ONE HUNDRED",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0063 },
+ uccode=0x216D,
+ unicodeslot=0x217D,
+ },
+ [0x217E]={
+ category="nl",
+ contextname="romand",
+ description="SMALL ROMAN NUMERAL FIVE HUNDRED",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0064 },
+ uccode=0x216E,
+ unicodeslot=0x217E,
+ },
+ [0x217F]={
+ category="nl",
+ contextname="romanm",
+ description="SMALL ROMAN NUMERAL ONE THOUSAND",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x006D },
+ uccode=0x216F,
+ unicodeslot=0x217F,
+ },
+ [0x2180]={
+ category="nl",
+ description="ROMAN NUMERAL ONE THOUSAND C D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2180,
+ },
+ [0x2181]={
+ category="nl",
+ description="ROMAN NUMERAL FIVE THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2181,
+ },
+ [0x2182]={
+ category="nl",
+ description="ROMAN NUMERAL TEN THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2182,
+ },
+ [0x2183]={
+ category="lu",
+ description="ROMAN NUMERAL REVERSED ONE HUNDRED",
+ direction="l",
+ lccode=0x2184,
+ linebreak="al",
+ unicodeslot=0x2183,
+ },
+ [0x2184]={
+ category="ll",
+ description="LATIN SMALL LETTER REVERSED C",
+ direction="l",
+ linebreak="al",
+ uccode=0x2183,
+ unicodeslot=0x2184,
+ },
+ [0x2185]={
+ category="nl",
+ description="ROMAN NUMERAL SIX LATE FORM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2185,
+ },
+ [0x2186]={
+ category="nl",
+ description="ROMAN NUMERAL FIFTY EARLY FORM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2186,
+ },
+ [0x2187]={
+ category="nl",
+ description="ROMAN NUMERAL FIFTY THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2187,
+ },
+ [0x2188]={
+ category="nl",
+ description="ROMAN NUMERAL ONE HUNDRED THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2188,
+ },
+ [0x2189]={
+ category="no",
+ cjkwd="a",
+ description="VULGAR FRACTION ZERO THIRDS",
+ direction="on",
+ linebreak="ai",
+ specials={ "fraction", 0x0030, 0x2044, 0x0033 },
+ unicodeslot=0x2189,
+ },
+ [0x2190]={
+ adobename="arrowleft",
+ category="sm",
+ cjkwd="a",
+ description="LEFTWARDS ARROW",
+ direction="on",
+ linebreak="ai",
+ mathextensible="l",
+ mathfiller="leftarrowfill",
+ mathspec={
+ {
+ class="relation",
+ name="leftarrow",
+ },
+ {
+ class="relation",
+ name="gets",
+ },
+ {
+ class="under",
+ name="underleftarrow",
+ },
+ {
+ class="over",
+ name="overleftarrow",
+ },
+ },
+ mathstretch="h",
+ unicodeslot=0x2190,
+ },
+ [0x2191]={
+ adobename="arrowup",
+ category="sm",
+ cjkwd="a",
+ description="UPWARDS ARROW",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathextensible="u",
+ mathname="uparrow",
+ unicodeslot=0x2191,
+ },
+ [0x2192]={
+ adobename="arrowright",
+ category="sm",
+ cjkwd="a",
+ description="RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="ai",
+ mathextensible="r",
+ mathfiller="rightarrowfill",
+ mathspec={
+ {
+ class="relation",
+ name="rightarrow",
+ },
+ {
+ class="relation",
+ name="to",
+ },
+ {
+ class="under",
+ name="underrightarrow",
+ },
+ {
+ class="over",
+ name="overrightarrow",
+ },
+ },
+ mathstretch="h",
+ unicodeslot=0x2192,
+ },
+ [0x2193]={
+ adobename="arrowdown",
+ category="sm",
+ cjkwd="a",
+ description="DOWNWARDS ARROW",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathextensible="d",
+ mathname="downarrow",
+ unicodeslot=0x2193,
+ },
+ [0x2194]={
+ adobename="arrowboth",
+ category="sm",
+ cjkwd="a",
+ description="LEFT RIGHT ARROW",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathextensible="h",
+ mathname="leftrightarrow",
+ unicodeslot=0x2194,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2195]={
+ adobename="arrowupdn",
+ category="so",
+ cjkwd="a",
+ description="UP DOWN ARROW",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathextensible="v",
+ mathname="updownarrow",
+ unicodeslot=0x2195,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2196]={
+ adobename="arrowupleft",
+ category="so",
+ cjkwd="a",
+ description="NORTH WEST ARROW",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="nwarrow",
+ unicodeslot=0x2196,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2197]={
+ adobename="arrowupright",
+ category="so",
+ cjkwd="a",
+ description="NORTH EAST ARROW",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="nearrow",
+ unicodeslot=0x2197,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2198]={
+ adobename="arrowdownright",
+ category="so",
+ cjkwd="a",
+ description="SOUTH EAST ARROW",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="searrow",
+ unicodeslot=0x2198,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2199]={
+ adobename="arrowdownleft",
+ category="so",
+ cjkwd="a",
+ description="SOUTH WEST ARROW",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="swarrow",
+ unicodeslot=0x2199,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x219A]={
+ category="sm",
+ description="LEFTWARDS ARROW WITH STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="nleftarrow",
+ specials={ "char", 0x2190, 0x0338 },
+ unicodeslot=0x219A,
+ },
+ [0x219B]={
+ category="sm",
+ description="RIGHTWARDS ARROW WITH STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="nrightarrow",
+ specials={ "char", 0x2192, 0x0338 },
+ unicodeslot=0x219B,
+ },
+ [0x219C]={
+ category="so",
+ description="LEFTWARDS WAVE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="leftwavearrow",
+ unicodeslot=0x219C,
+ },
+ [0x219D]={
+ category="so",
+ description="RIGHTWARDS WAVE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="rightwavearrow",
+ unicodeslot=0x219D,
+ },
+ [0x219E]={
+ category="so",
+ description="LEFTWARDS TWO HEADED ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathfiller="twoheadleftarrowfill",
+ mathname="twoheadleftarrow",
+ unicodeslot=0x219E,
+ },
+ [0x219F]={
+ category="so",
+ description="UPWARDS TWO HEADED ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="u",
+ mathname="twoheaduparrow",
+ unicodeslot=0x219F,
+ },
+ [0x21A0]={
+ category="sm",
+ description="RIGHTWARDS TWO HEADED ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathfiller="twoheadrightarrowfill",
+ mathname="twoheadrightarrow",
+ unicodeslot=0x21A0,
+ },
+ [0x21A1]={
+ category="so",
+ description="DOWNWARDS TWO HEADED ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="d",
+ mathname="twoheaddownarrow",
+ unicodeslot=0x21A1,
+ },
+ [0x21A2]={
+ category="so",
+ description="LEFTWARDS ARROW WITH TAIL",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="leftarrowtail",
+ unicodeslot=0x21A2,
+ },
+ [0x21A3]={
+ category="sm",
+ description="RIGHTWARDS ARROW WITH TAIL",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="rightarrowtail",
+ unicodeslot=0x21A3,
+ },
+ [0x21A4]={
+ category="so",
+ description="LEFTWARDS ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="mapsfrom",
+ unicodeslot=0x21A4,
+ },
+ [0x21A5]={
+ category="so",
+ description="UPWARDS ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="u",
+ mathname="mapsup",
+ unicodeslot=0x21A5,
+ },
+ [0x21A6]={
+ category="sm",
+ description="RIGHTWARDS ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathfiller="mapstofill",
+ mathname="mapsto",
+ unicodeslot=0x21A6,
+ },
+ [0x21A7]={
+ category="so",
+ description="DOWNWARDS ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="d",
+ mathname="mapsdown",
+ unicodeslot=0x21A7,
+ },
+ [0x21A8]={
+ adobename="arrowupdownbase",
+ category="so",
+ description="UP DOWN ARROW WITH BASE",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathextensible="v",
+ mathname="updownarrowbar",
+ unicodeslot=0x21A8,
+ },
+ [0x21A9]={
+ category="so",
+ description="LEFTWARDS ARROW WITH HOOK",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathfiller="hookleftarrowfill",
+ mathname="hookleftarrow",
+ unicodeslot=0x21A9,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x21AA]={
+ category="so",
+ description="RIGHTWARDS ARROW WITH HOOK",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathfiller="hookrightarrowfill",
+ mathname="hookrightarrow",
+ unicodeslot=0x21AA,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x21AB]={
+ category="so",
+ description="LEFTWARDS ARROW WITH LOOP",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="looparrowleft",
+ unicodeslot=0x21AB,
+ },
+ [0x21AC]={
+ category="so",
+ description="RIGHTWARDS ARROW WITH LOOP",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="looparrowright",
+ unicodeslot=0x21AC,
+ },
+ [0x21AD]={
+ category="so",
+ description="LEFT RIGHT WAVE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathname="leftrightsquigarrow",
+ unicodeslot=0x21AD,
+ },
+ [0x21AE]={
+ category="sm",
+ description="LEFT RIGHT ARROW WITH STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathname="nleftrightarrow",
+ specials={ "char", 0x2194, 0x0338 },
+ unicodeslot=0x21AE,
+ },
+ [0x21AF]={
+ category="so",
+ description="DOWNWARDS ZIGZAG ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="d",
+ mathname="downzigzagarrow",
+ unicodeslot=0x21AF,
+ },
+ [0x21B0]={
+ category="so",
+ description="UPWARDS ARROW WITH TIP LEFTWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="m",
+ mathname="Lsh",
+ unicodeslot=0x21B0,
+ },
+ [0x21B1]={
+ category="so",
+ description="UPWARDS ARROW WITH TIP RIGHTWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="m",
+ mathname="Rsh",
+ unicodeslot=0x21B1,
+ },
+ [0x21B2]={
+ category="so",
+ description="DOWNWARDS ARROW WITH TIP LEFTWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="m",
+ mathname="Ldsh",
+ unicodeslot=0x21B2,
+ },
+ [0x21B3]={
+ category="so",
+ description="DOWNWARDS ARROW WITH TIP RIGHTWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="m",
+ mathname="Rdsh",
+ unicodeslot=0x21B3,
+ },
+ [0x21B4]={
+ category="so",
+ description="RIGHTWARDS ARROW WITH CORNER DOWNWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathextensible="m",
+ mathname="linefeed",
+ unicodeslot=0x21B4,
+ },
+ [0x21B5]={
+ adobename="carriagereturn",
+ category="so",
+ contextname="carriagereturn",
+ description="DOWNWARDS ARROW WITH CORNER LEFTWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathextensible="m",
+ mathname="carriagereturn",
+ unicodeslot=0x21B5,
+ },
+ [0x21B6]={
+ category="so",
+ description="ANTICLOCKWISE TOP SEMICIRCLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="curvearrowleft",
+ unicodeslot=0x21B6,
+ },
+ [0x21B7]={
+ category="so",
+ description="CLOCKWISE TOP SEMICIRCLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="curvearrowright",
+ unicodeslot=0x21B7,
+ },
+ [0x21B8]={
+ category="so",
+ cjkwd="a",
+ description="NORTH WEST ARROW TO LONG BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="barovernorthwestarrow",
+ unicodeslot=0x21B8,
+ },
+ [0x21B9]={
+ category="so",
+ cjkwd="a",
+ description="LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathname="barleftarrowrightarrowbar",
+ unicodeslot=0x21B9,
+ },
+ [0x21BA]={
+ category="so",
+ description="ANTICLOCKWISE OPEN CIRCLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="circlearrowright",
+ },
+ {
+ class="relation",
+ name="acwopencirclearrow",
+ },
+ },
+ unicodeslot=0x21BA,
+ },
+ [0x21BB]={
+ category="so",
+ description="CLOCKWISE OPEN CIRCLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="circlearrowleft",
+ },
+ {
+ class="relation",
+ name="cwopencirclearrow",
+ },
+ },
+ unicodeslot=0x21BB,
+ },
+ [0x21BC]={
+ adobename="harpoonleftbarbup",
+ category="so",
+ description="LEFTWARDS HARPOON WITH BARB UPWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathfiller="leftharpoonupfill",
+ mathname="leftharpoonup",
+ unicodeslot=0x21BC,
+ },
+ [0x21BD]={
+ category="so",
+ description="LEFTWARDS HARPOON WITH BARB DOWNWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathfiller="leftharpoondownfill",
+ mathname="leftharpoondown",
+ unicodeslot=0x21BD,
+ },
+ [0x21BE]={
+ category="so",
+ description="UPWARDS HARPOON WITH BARB RIGHTWARDS",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="upharpoonright",
+ },
+ {
+ class="relation",
+ name="restriction",
+ },
+ },
+ unicodeslot=0x21BE,
+ },
+ [0x21BF]={
+ category="so",
+ description="UPWARDS HARPOON WITH BARB LEFTWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="upharpoonleft",
+ unicodeslot=0x21BF,
+ },
+ [0x21C0]={
+ adobename="harpoonrightbarbup",
+ category="so",
+ description="RIGHTWARDS HARPOON WITH BARB UPWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathfiller="rightharpoonupfill",
+ mathname="rightharpoonup",
+ unicodeslot=0x21C0,
+ },
+ [0x21C1]={
+ category="so",
+ description="RIGHTWARDS HARPOON WITH BARB DOWNWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathfiller="rightharpoondownfill",
+ mathname="rightharpoondown",
+ unicodeslot=0x21C1,
+ },
+ [0x21C2]={
+ category="so",
+ description="DOWNWARDS HARPOON WITH BARB RIGHTWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="downharpoonright",
+ unicodeslot=0x21C2,
+ },
+ [0x21C3]={
+ category="so",
+ description="DOWNWARDS HARPOON WITH BARB LEFTWARDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="downharpoonleft",
+ unicodeslot=0x21C3,
+ },
+ [0x21C4]={
+ adobename="arrowrightoverleft",
+ category="so",
+ description="RIGHTWARDS ARROW OVER LEFTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathfiller="rightoverleftarrowfill",
+ mathname="rightleftarrows",
+ unicodeslot=0x21C4,
+ },
+ [0x21C5]={
+ adobename="arrowupleftofdown",
+ category="so",
+ description="UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="m",
+ mathname="updownarrows",
+ unicodeslot=0x21C5,
+ },
+ [0x21C6]={
+ adobename="arrowleftoverright",
+ category="so",
+ description="LEFTWARDS ARROW OVER RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathfiller="lefgtoverrightarrowfill",
+ mathname="leftrightarrows",
+ unicodeslot=0x21C6,
+ },
+ [0x21C7]={
+ category="so",
+ description="LEFTWARDS PAIRED ARROWS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="leftleftarrows",
+ unicodeslot=0x21C7,
+ },
+ [0x21C8]={
+ category="so",
+ description="UPWARDS PAIRED ARROWS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="u",
+ mathname="upuparrows",
+ unicodeslot=0x21C8,
+ },
+ [0x21C9]={
+ category="so",
+ description="RIGHTWARDS PAIRED ARROWS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="rightrightarrows",
+ unicodeslot=0x21C9,
+ },
+ [0x21CA]={
+ category="so",
+ description="DOWNWARDS PAIRED ARROWS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="d",
+ mathname="downdownarrows",
+ unicodeslot=0x21CA,
+ },
+ [0x21CB]={
+ category="so",
+ description="LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathfiller="leftrightharpoonsfill",
+ mathname="leftrightharpoons",
+ unicodeslot=0x21CB,
+ },
+ [0x21CC]={
+ category="so",
+ description="RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathfiller="rightleftharpoonsfill",
+ mathname="rightleftharpoons",
+ unicodeslot=0x21CC,
+ },
+ [0x21CD]={
+ adobename="arrowleftdblstroke",
+ category="so",
+ description="LEFTWARDS DOUBLE ARROW WITH STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="nLeftarrow",
+ specials={ "char", 0x21D0, 0x0338 },
+ unicodeslot=0x21CD,
+ },
+ [0x21CE]={
+ category="sm",
+ description="LEFT RIGHT DOUBLE ARROW WITH STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathname="nLeftrightarrow",
+ specials={ "char", 0x21D4, 0x0338 },
+ unicodeslot=0x21CE,
+ },
+ [0x21CF]={
+ adobename="arrowrightdblstroke",
+ category="sm",
+ description="RIGHTWARDS DOUBLE ARROW WITH STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="nRightarrow",
+ specials={ "char", 0x21D2, 0x0338 },
+ unicodeslot=0x21CF,
+ },
+ [0x21D0]={
+ adobename="arrowleftdbl",
+ category="so",
+ description="LEFTWARDS DOUBLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="Leftarrow",
+ unicodeslot=0x21D0,
+ },
+ [0x21D1]={
+ adobename="arrowdblup",
+ category="so",
+ description="UPWARDS DOUBLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="u",
+ mathname="Uparrow",
+ unicodeslot=0x21D1,
+ },
+ [0x21D2]={
+ adobename="dblarrowright",
+ category="sm",
+ cjkwd="a",
+ description="RIGHTWARDS DOUBLE ARROW",
+ direction="on",
+ linebreak="ai",
+ mathextensible="r",
+ mathspec={
+ {
+ class="relation",
+ name="Rightarrow",
+ },
+ {
+ class="relation",
+ name="imply",
+ },
+ },
+ unicodeslot=0x21D2,
+ },
+ [0x21D3]={
+ adobename="arrowdbldown",
+ category="so",
+ description="DOWNWARDS DOUBLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="d",
+ mathname="Downarrow",
+ unicodeslot=0x21D3,
+ },
+ [0x21D4]={
+ adobename="dblarrowleft",
+ category="sm",
+ cjkwd="a",
+ description="LEFT RIGHT DOUBLE ARROW",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathextensible="h",
+ mathname="Leftrightarrow",
+ unicodeslot=0x21D4,
+ },
+ [0x21D5]={
+ category="so",
+ description="UP DOWN DOUBLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="v",
+ mathname="Updownarrow",
+ unicodeslot=0x21D5,
+ },
+ [0x21D6]={
+ category="so",
+ description="NORTH WEST DOUBLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="Nwarrow",
+ unicodeslot=0x21D6,
+ },
+ [0x21D7]={
+ category="so",
+ description="NORTH EAST DOUBLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="Nearrow",
+ unicodeslot=0x21D7,
+ },
+ [0x21D8]={
+ category="so",
+ description="SOUTH EAST DOUBLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="Searrow",
+ unicodeslot=0x21D8,
+ },
+ [0x21D9]={
+ category="so",
+ description="SOUTH WEST DOUBLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="Swarrow",
+ unicodeslot=0x21D9,
+ },
+ [0x21DA]={
+ category="so",
+ description="LEFTWARDS TRIPLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="Lleftarrow",
+ unicodeslot=0x21DA,
+ },
+ [0x21DB]={
+ category="so",
+ description="RIGHTWARDS TRIPLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="Rrightarrow",
+ unicodeslot=0x21DB,
+ },
+ [0x21DC]={
+ category="so",
+ description="LEFTWARDS SQUIGGLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="leftsquigarrow",
+ unicodeslot=0x21DC,
+ },
+ [0x21DD]={
+ category="so",
+ description="RIGHTWARDS SQUIGGLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="rightsquigarrow",
+ },
+ {
+ class="relation",
+ name="leadsto",
+ },
+ },
+ unicodeslot=0x21DD,
+ },
+ [0x21DE]={
+ adobename="pageup",
+ category="so",
+ description="UPWARDS ARROW WITH DOUBLE STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="u",
+ mathname="nHuparrow",
+ unicodeslot=0x21DE,
+ },
+ [0x21DF]={
+ adobename="pagedown",
+ category="so",
+ description="DOWNWARDS ARROW WITH DOUBLE STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="d",
+ mathname="nHdownarrow",
+ unicodeslot=0x21DF,
+ },
+ [0x21E0]={
+ adobename="arrowdashleft",
+ category="so",
+ description="LEFTWARDS DASHED ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="leftdasharrow",
+ unicodeslot=0x21E0,
+ },
+ [0x21E1]={
+ adobename="arrowdashup",
+ category="so",
+ description="UPWARDS DASHED ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="u",
+ mathname="updasharrow",
+ unicodeslot=0x21E1,
+ },
+ [0x21E2]={
+ adobename="arrowdashright",
+ category="so",
+ description="RIGHTWARDS DASHED ARROW",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="rightdasharrow",
+ },
+ {
+ class="relation",
+ name="dasharrow",
+ },
+ },
+ unicodeslot=0x21E2,
+ },
+ [0x21E3]={
+ adobename="arrowdashdown",
+ category="so",
+ description="DOWNWARDS DASHED ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="d",
+ mathname="downdasharrow",
+ unicodeslot=0x21E3,
+ },
+ [0x21E4]={
+ adobename="arrowtableft",
+ category="so",
+ description="LEFTWARDS ARROW TO BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="barleftarrow",
+ unicodeslot=0x21E4,
+ },
+ [0x21E5]={
+ adobename="arrowtabright",
+ category="so",
+ description="RIGHTWARDS ARROW TO BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="rightarrowbar",
+ unicodeslot=0x21E5,
+ },
+ [0x21E6]={
+ adobename="arrowleftwhite",
+ category="so",
+ description="LEFTWARDS WHITE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathextensible="l",
+ mathname="leftwhitearrow",
+ unicodeslot=0x21E6,
+ },
+ [0x21E7]={
+ adobename="arrowupwhite",
+ category="so",
+ cjkwd="a",
+ description="UPWARDS WHITE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathextensible="u",
+ mathname="upwhitearrow",
+ unicodeslot=0x21E7,
+ },
+ [0x21E8]={
+ adobename="arrowrightwhite",
+ category="so",
+ description="RIGHTWARDS WHITE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathextensible="r",
+ mathname="rightwhitearrow",
+ unicodeslot=0x21E8,
+ },
+ [0x21E9]={
+ adobename="arrowdownwhite",
+ category="so",
+ description="DOWNWARDS WHITE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathextensible="d",
+ mathname="downwhitearrow",
+ unicodeslot=0x21E9,
+ },
+ [0x21EA]={
+ adobename="capslock",
+ category="so",
+ description="UPWARDS WHITE ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21EA,
+ },
+ [0x21EB]={
+ category="so",
+ description="UPWARDS WHITE ARROW ON PEDESTAL",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathextensible="u",
+ mathname="whitearrowupfrombar",
+ unicodeslot=0x21EB,
+ },
+ [0x21EC]={
+ category="so",
+ description="UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21EC,
+ },
+ [0x21ED]={
+ category="so",
+ description="UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21ED,
+ },
+ [0x21EE]={
+ category="so",
+ description="UPWARDS WHITE DOUBLE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21EE,
+ },
+ [0x21EF]={
+ category="so",
+ description="UPWARDS WHITE DOUBLE ARROW ON PEDESTAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21EF,
+ },
+ [0x21F0]={
+ category="so",
+ description="RIGHTWARDS WHITE ARROW FROM WALL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F0,
+ },
+ [0x21F1]={
+ category="so",
+ description="NORTH WEST ARROW TO CORNER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F1,
+ },
+ [0x21F2]={
+ category="so",
+ description="SOUTH EAST ARROW TO CORNER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F2,
+ },
+ [0x21F3]={
+ category="so",
+ description="UP DOWN WHITE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x21F3,
+ },
+ [0x21F4]={
+ category="sm",
+ description="RIGHT ARROW WITH SMALL CIRCLE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="circleonrightarrow",
+ unicodeslot=0x21F4,
+ },
+ [0x21F5]={
+ category="sm",
+ description="DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="m",
+ mathname="downuparrows",
+ unicodeslot=0x21F5,
+ },
+ [0x21F6]={
+ category="sm",
+ description="THREE RIGHTWARDS ARROWS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="rightthreearrows",
+ unicodeslot=0x21F6,
+ },
+ [0x21F7]={
+ category="sm",
+ description="LEFTWARDS ARROW WITH VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="nvleftarrow",
+ unicodeslot=0x21F7,
+ },
+ [0x21F8]={
+ category="sm",
+ description="RIGHTWARDS ARROW WITH VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="nvrightarrow",
+ unicodeslot=0x21F8,
+ },
+ [0x21F9]={
+ category="sm",
+ description="LEFT RIGHT ARROW WITH VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathname="nvleftrightarrow",
+ unicodeslot=0x21F9,
+ },
+ [0x21FA]={
+ category="sm",
+ description="LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="nVleftarrow",
+ unicodeslot=0x21FA,
+ },
+ [0x21FB]={
+ category="sm",
+ description="RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="nVrightarrow",
+ unicodeslot=0x21FB,
+ },
+ [0x21FC]={
+ category="sm",
+ description="LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathname="nVleftrightarrow",
+ unicodeslot=0x21FC,
+ },
+ [0x21FD]={
+ category="sm",
+ description="LEFTWARDS OPEN-HEADED ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="leftarrowtriangle",
+ unicodeslot=0x21FD,
+ },
+ [0x21FE]={
+ category="sm",
+ description="RIGHTWARDS OPEN-HEADED ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="rightarrowtriangle",
+ unicodeslot=0x21FE,
+ },
+ [0x21FF]={
+ category="sm",
+ description="LEFT RIGHT OPEN-HEADED ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathname="leftrightarrowtriangle",
+ unicodeslot=0x21FF,
+ },
+ [0x2200]={
+ adobename="universal",
+ category="sm",
+ cjkwd="a",
+ description="FOR ALL",
+ direction="on",
+ linebreak="ai",
+ mathclass="ordinary",
+ mathname="forall",
+ unicodeslot=0x2200,
+ },
+ [0x2201]={
+ category="sm",
+ description="COMPLEMENT",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="complement",
+ unicodeslot=0x2201,
+ },
+ [0x2202]={
+ adobename="partialdiff",
+ category="sm",
+ cjkwd="a",
+ description="PARTIAL DIFFERENTIAL",
+ direction="on",
+ linebreak="ai",
+ mathclass="default",
+ mathname="partial",
+ unicodeslot=0x2202,
+ },
+ [0x2203]={
+ adobename="thereexists",
+ category="sm",
+ cjkwd="a",
+ description="THERE EXISTS",
+ direction="on",
+ linebreak="ai",
+ mathclass="ordinary",
+ mathname="exists",
+ unicodeslot=0x2203,
+ },
+ [0x2204]={
+ category="sm",
+ description="THERE DOES NOT EXIST",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="nexists",
+ specials={ "char", 0x2203, 0x0338 },
+ unicodeslot=0x2204,
+ },
+ [0x2205]={
+ adobename="emptyset",
+ category="sm",
+ description="EMPTY SET",
+ direction="on",
+ linebreak="al",
+ mathclass="default",
+ mathname="emptyset",
+ unicodeslot=0x2205,
+ },
+ [0x2206]={
+ adobename="increment",
+ category="sm",
+ description="INCREMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2206,
+ },
+ [0x2207]={
+ adobename="nabla",
+ category="sm",
+ cjkwd="a",
+ description="NABLA",
+ direction="on",
+ linebreak="ai",
+ mathclass="default",
+ mathname="nabla",
+ unicodeslot=0x2207,
+ },
+ [0x2208]={
+ adobename="element",
+ category="sm",
+ cjkwd="a",
+ description="ELEMENT OF",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="in",
+ mirror=0x220B,
+ unicodeslot=0x2208,
+ },
+ [0x2209]={
+ adobename="notelementof",
+ category="sm",
+ description="NOT AN ELEMENT OF",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="notin",
+ },
+ {
+ class="relation",
+ name="nin",
+ },
+ },
+ mirror=0x220C,
+ specials={ "char", 0x2208, 0x0338 },
+ unicodeslot=0x2209,
+ },
+ [0x220A]={
+ category="sm",
+ description="SMALL ELEMENT OF",
+ direction="on",
+ linebreak="al",
+ mirror=0x220D,
+ unicodeslot=0x220A,
+ },
+ [0x220B]={
+ adobename="suchthat",
+ category="sm",
+ cjkwd="a",
+ description="CONTAINS AS MEMBER",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="relation",
+ name="ni",
+ },
+ {
+ class="relation",
+ name="owns",
+ },
+ },
+ mirror=0x2208,
+ unicodeslot=0x220B,
+ },
+ [0x220C]={
+ adobename="notcontains",
+ category="sm",
+ description="DOES NOT CONTAIN AS MEMBER",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="nni",
+ },
+ {
+ class="relation",
+ name="nowns",
+ },
+ },
+ mirror=0x2209,
+ specials={ "char", 0x220B, 0x0338 },
+ unicodeslot=0x220C,
+ },
+ [0x220D]={
+ category="sm",
+ description="SMALL CONTAINS AS MEMBER",
+ direction="on",
+ linebreak="al",
+ mirror=0x220A,
+ unicodeslot=0x220D,
+ },
+ [0x220E]={
+ category="sm",
+ description="END OF PROOF",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x220E,
+ },
+ [0x220F]={
+ adobename="product",
+ category="sm",
+ cjkwd="a",
+ description="N-ARY PRODUCT",
+ direction="on",
+ linebreak="ai",
+ mathclass="limop",
+ mathname="prod",
+ unicodeslot=0x220F,
+ },
+ [0x2210]={
+ category="sm",
+ description="N-ARY COPRODUCT",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="coprod",
+ unicodeslot=0x2210,
+ },
+ [0x2211]={
+ adobename="summation",
+ category="sm",
+ cjkwd="a",
+ description="N-ARY SUMMATION",
+ direction="on",
+ linebreak="ai",
+ mathclass="limop",
+ mathname="sum",
+ unicodeslot=0x2211,
+ },
+ [0x2212]={
+ adobename="minus",
+ category="sm",
+ description="MINUS SIGN",
+ direction="es",
+ linebreak="pr",
+ mathspec={
+ {
+ class="binary",
+ name="minus",
+ },
+ {
+ class="relation",
+ name="relbar",
+ },
+ },
+ unicodeslot=0x2212,
+ },
+ [0x2213]={
+ adobename="minusplus",
+ category="sm",
+ description="MINUS-OR-PLUS SIGN",
+ direction="et",
+ linebreak="pr",
+ mathclass="binary",
+ mathname="mp",
+ unicodeslot=0x2213,
+ },
+ [0x2214]={
+ category="sm",
+ description="DOT PLUS",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="dotplus",
+ unicodeslot=0x2214,
+ },
+ [0x2215]={
+ adobename="divisionslash",
+ category="sm",
+ cjkwd="a",
+ comment="mathclass=ordinary,mathname=diagup",
+ description="DIVISION SLASH",
+ direction="on",
+ linebreak="ai",
+ mirror=0x29F5,
+ unicodeslot=0x2215,
+ },
+ [0x2216]={
+ category="sm",
+ comment="mathclass=ordinary,mathname=diagdown",
+ description="SET MINUS",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="binary",
+ name="setminus",
+ },
+ },
+ unicodeslot=0x2216,
+ },
+ [0x2217]={
+ adobename="asteriskmath",
+ category="sm",
+ description="ASTERISK OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="ast",
+ unicodeslot=0x2217,
+ },
+ [0x2218]={
+ category="sm",
+ description="RING OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="circ",
+ unicodeslot=0x2218,
+ },
+ [0x2219]={
+ adobename="bulletoperator",
+ category="sm",
+ description="BULLET OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="bullet",
+ unicodeslot=0x2219,
+ },
+ [0x221A]={
+ adobename="radical",
+ category="sm",
+ cjkwd="a",
+ description="SQUARE ROOT",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="root",
+ name="rootradical",
+ },
+ {
+ class="radical",
+ name="surdradical",
+ },
+ {
+ class="ordinary",
+ name="surd",
+ },
+ },
+ unicodeslot=0x221A,
+ },
+ [0x221B]={
+ category="sm",
+ description="CUBE ROOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x221B,
+ },
+ [0x221C]={
+ category="sm",
+ description="FOURTH ROOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x221C,
+ },
+ [0x221D]={
+ adobename="proportional",
+ category="sm",
+ cjkwd="a",
+ description="PROPORTIONAL TO",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="propto",
+ unicodeslot=0x221D,
+ },
+ [0x221E]={
+ adobename="infinity",
+ category="sm",
+ cjkwd="a",
+ description="INFINITY",
+ direction="on",
+ linebreak="ai",
+ mathclass="default",
+ mathname="infty",
+ unicodeslot=0x221E,
+ },
+ [0x221F]={
+ adobename="rightangle",
+ category="sm",
+ cjkwd="a",
+ description="RIGHT ANGLE",
+ direction="on",
+ linebreak="ai",
+ mathclass="ordinary",
+ mathname="rightangle",
+ unicodeslot=0x221F,
+ },
+ [0x2220]={
+ adobename="angle",
+ category="sm",
+ cjkwd="a",
+ description="ANGLE",
+ direction="on",
+ linebreak="ai",
+ mathclass="ordinary",
+ mathname="angle",
+ unicodeslot=0x2220,
+ },
+ [0x2221]={
+ category="sm",
+ description="MEASURED ANGLE",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="measuredangle",
+ unicodeslot=0x2221,
+ },
+ [0x2222]={
+ category="sm",
+ description="SPHERICAL ANGLE",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="sphericalangle",
+ unicodeslot=0x2222,
+ },
+ [0x2223]={
+ adobename="divides",
+ category="sm",
+ cjkwd="a",
+ description="DIVIDES",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="divides",
+ unicodeslot=0x2223,
+ },
+ [0x2224]={
+ category="sm",
+ description="DOES NOT DIVIDE",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="binary",
+ name="ndivides",
+ },
+ {
+ class="relation",
+ name="nmid",
+ },
+ },
+ specials={ "char", 0x2223, 0x0338 },
+ unicodeslot=0x2224,
+ },
+ [0x2225]={
+ adobename="parallel",
+ category="sm",
+ cjkwd="a",
+ description="PARALLEL TO",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="relation",
+ name="parallel",
+ },
+ },
+ unicodeslot=0x2225,
+ },
+ [0x2226]={
+ adobename="notparallel",
+ category="sm",
+ description="NOT PARALLEL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nparallel",
+ specials={ "char", 0x2225, 0x0338 },
+ unicodeslot=0x2226,
+ },
+ [0x2227]={
+ adobename="logicaland",
+ category="sm",
+ cjkwd="a",
+ description="LOGICAL AND",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="binary",
+ name="wedge",
+ },
+ {
+ class="binary",
+ name="land",
+ },
+ },
+ unicodeslot=0x2227,
+ },
+ [0x2228]={
+ adobename="logicalor",
+ category="sm",
+ cjkwd="a",
+ description="LOGICAL OR",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="binary",
+ name="vee",
+ },
+ {
+ class="binary",
+ name="lor",
+ },
+ },
+ unicodeslot=0x2228,
+ },
+ [0x2229]={
+ adobename="intersection",
+ category="sm",
+ cjkwd="a",
+ description="INTERSECTION",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="cap",
+ unicodeslot=0x2229,
+ variants={
+ [0xFE00]="with serifs",
+ },
+ },
+ [0x222A]={
+ adobename="union",
+ category="sm",
+ cjkwd="a",
+ description="UNION",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="cup",
+ unicodeslot=0x222A,
+ variants={
+ [0xFE00]="with serifs",
+ },
+ },
+ [0x222B]={
+ adobename="integral",
+ category="sm",
+ cjkwd="a",
+ description="INTEGRAL",
+ direction="on",
+ linebreak="ai",
+ mathclass="limop",
+ mathspec={
+ {
+ class="limop",
+ name="int",
+ },
+ {
+ class="nothing",
+ name="intop",
+ },
+ },
+ unicodeslot=0x222B,
+ },
+ [0x222C]={
+ adobename="dblintegral",
+ category="sm",
+ cjkwd="a",
+ description="DOUBLE INTEGRAL",
+ direction="on",
+ linebreak="ai",
+ mathclass="limop",
+ mathspec={
+ {
+ class="limop",
+ name="iint",
+ },
+ {
+ class="nothing",
+ name="iintop",
+ },
+ },
+ specials={ "compat", 0x222B, 0x222B },
+ unicodeslot=0x222C,
+ },
+ [0x222D]={
+ category="sm",
+ description="TRIPLE INTEGRAL",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathspec={
+ {
+ class="limop",
+ name="iiint",
+ },
+ {
+ class="nothing",
+ name="iiintop",
+ },
+ },
+ specials={ "compat", 0x222B, 0x222B, 0x222B },
+ unicodeslot=0x222D,
+ },
+ [0x222E]={
+ adobename="contourintegral",
+ category="sm",
+ cjkwd="a",
+ description="CONTOUR INTEGRAL",
+ direction="on",
+ linebreak="ai",
+ mathclass="limop",
+ mathname="oint",
+ unicodeslot=0x222E,
+ },
+ [0x222F]={
+ category="sm",
+ description="SURFACE INTEGRAL",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="oiint",
+ specials={ "compat", 0x222E, 0x222E },
+ unicodeslot=0x222F,
+ },
+ [0x2230]={
+ category="sm",
+ description="VOLUME INTEGRAL",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="oiiint",
+ specials={ "compat", 0x222E, 0x222E, 0x222E },
+ unicodeslot=0x2230,
+ },
+ [0x2231]={
+ category="sm",
+ description="CLOCKWISE INTEGRAL",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="intclockwise",
+ unicodeslot=0x2231,
+ },
+ [0x2232]={
+ category="sm",
+ description="CLOCKWISE CONTOUR INTEGRAL",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="ointclockwise",
+ unicodeslot=0x2232,
+ },
+ [0x2233]={
+ category="sm",
+ description="ANTICLOCKWISE CONTOUR INTEGRAL",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="ointctrclockwise",
+ unicodeslot=0x2233,
+ },
+ [0x2234]={
+ adobename="therefore",
+ category="sm",
+ cjkwd="a",
+ description="THEREFORE",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="therefore",
+ unicodeslot=0x2234,
+ },
+ [0x2235]={
+ adobename="because",
+ category="sm",
+ cjkwd="a",
+ description="BECAUSE",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="because",
+ unicodeslot=0x2235,
+ },
+ [0x2236]={
+ adobename="ratio",
+ category="sm",
+ cjkwd="a",
+ description="RATIO",
+ direction="on",
+ linebreak="ai",
+ mathclass="punctuation",
+ mathname="colon",
+ unicodeslot=0x2236,
+ },
+ [0x2237]={
+ adobename="proportion",
+ category="sm",
+ cjkwd="a",
+ description="PROPORTION",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="squaredots",
+ unicodeslot=0x2237,
+ },
+ [0x2238]={
+ category="sm",
+ description="DOT MINUS",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="dotminus",
+ unicodeslot=0x2238,
+ },
+ [0x2239]={
+ category="sm",
+ description="EXCESS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="minuscolon",
+ unicodeslot=0x2239,
+ },
+ [0x223A]={
+ category="sm",
+ description="GEOMETRIC PROPORTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x223A,
+ },
+ [0x223B]={
+ category="sm",
+ description="HOMOTHETIC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x223B,
+ },
+ [0x223C]={
+ adobename="tildeoperator",
+ category="sm",
+ cjkwd="a",
+ description="TILDE OPERATOR",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="sim",
+ mirror=0x223D,
+ unicodeslot=0x223C,
+ },
+ [0x223D]={
+ adobename="reversedtilde",
+ category="sm",
+ cjkwd="a",
+ description="REVERSED TILDE",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="backsim",
+ mirror=0x223C,
+ unicodeslot=0x223D,
+ },
+ [0x223E]={
+ category="sm",
+ description="INVERTED LAZY S",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x223E,
+ },
+ [0x223F]={
+ category="sm",
+ description="SINE WAVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x223F,
+ },
+ [0x2240]={
+ category="sm",
+ description="WREATH PRODUCT",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="wr",
+ unicodeslot=0x2240,
+ },
+ [0x2241]={
+ category="sm",
+ description="NOT TILDE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nsim",
+ specials={ "char", 0x223C, 0x0338 },
+ unicodeslot=0x2241,
+ },
+ [0x2242]={
+ category="sm",
+ description="MINUS TILDE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="eqsim",
+ unicodeslot=0x2242,
+ },
+ [0x2243]={
+ adobename="asymptoticallyequal",
+ category="sm",
+ description="ASYMPTOTICALLY EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="simeq",
+ mirror=0x22CD,
+ unicodeslot=0x2243,
+ },
+ [0x2244]={
+ category="sm",
+ description="NOT ASYMPTOTICALLY EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nsimeq",
+ specials={ "char", 0x2243, 0x0338 },
+ unicodeslot=0x2244,
+ },
+ [0x2245]={
+ adobename="congruent",
+ category="sm",
+ description="APPROXIMATELY EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="approxEq",
+ },
+ {
+ class="relation",
+ name="cong",
+ },
+ },
+ unicodeslot=0x2245,
+ },
+ [0x2246]={
+ category="sm",
+ description="APPROXIMATELY BUT NOT ACTUALLY EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="napproxEq",
+ },
+ {
+ class="relation",
+ name="ncong",
+ },
+ },
+ unicodeslot=0x2246,
+ },
+ [0x2247]={
+ category="sm",
+ description="NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="approxnEq",
+ specials={ "char", 0x2245, 0x0338 },
+ unicodeslot=0x2247,
+ },
+ [0x2248]={
+ adobename="approxequal",
+ category="sm",
+ cjkwd="a",
+ description="ALMOST EQUAL TO",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="approx",
+ unicodeslot=0x2248,
+ },
+ [0x2249]={
+ category="sm",
+ description="NOT ALMOST EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="napprox",
+ specials={ "char", 0x2248, 0x0338 },
+ unicodeslot=0x2249,
+ },
+ [0x224A]={
+ category="sm",
+ description="ALMOST EQUAL OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="approxeq",
+ unicodeslot=0x224A,
+ },
+ [0x224B]={
+ category="sm",
+ description="TRIPLE TILDE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x224B,
+ },
+ [0x224C]={
+ adobename="allequal",
+ category="sm",
+ cjkwd="a",
+ description="ALL EQUAL TO",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ unicodeslot=0x224C,
+ },
+ [0x224D]={
+ category="sm",
+ description="EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="asymp",
+ unicodeslot=0x224D,
+ },
+ [0x224E]={
+ category="sm",
+ description="GEOMETRICALLY EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="Bumpeq",
+ unicodeslot=0x224E,
+ },
+ [0x224F]={
+ category="sm",
+ description="DIFFERENCE BETWEEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x224F,
+ },
+ [0x2250]={
+ adobename="approaches",
+ category="sm",
+ description="APPROACHES THE LIMIT",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="doteq",
+ unicodeslot=0x2250,
+ },
+ [0x2251]={
+ adobename="geometricallyequal",
+ category="sm",
+ description="GEOMETRICALLY EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="doteqdot",
+ },
+ {
+ class="relation",
+ name="Doteq",
+ },
+ },
+ unicodeslot=0x2251,
+ },
+ [0x2252]={
+ adobename="approxequalorimage",
+ category="sm",
+ cjkwd="a",
+ description="APPROXIMATELY EQUAL TO OR THE IMAGE OF",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="fallingdotseq",
+ mirror=0x2253,
+ unicodeslot=0x2252,
+ },
+ [0x2253]={
+ adobename="imageorapproximatelyequal",
+ category="sm",
+ description="IMAGE OF OR APPROXIMATELY EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="risingdotseq",
+ mirror=0x2252,
+ unicodeslot=0x2253,
+ },
+ [0x2254]={
+ category="sm",
+ description="COLON EQUALS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="colonequals",
+ mirror=0x2255,
+ unicodeslot=0x2254,
+ },
+ [0x2255]={
+ category="sm",
+ description="EQUALS COLON",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="equalscolon",
+ mirror=0x2254,
+ unicodeslot=0x2255,
+ },
+ [0x2256]={
+ category="sm",
+ description="RING IN EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="eqcirc",
+ unicodeslot=0x2256,
+ },
+ [0x2257]={
+ category="sm",
+ description="RING EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="circeq",
+ unicodeslot=0x2257,
+ },
+ [0x2258]={
+ category="sm",
+ description="CORRESPONDS TO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2258,
+ },
+ [0x2259]={
+ category="sm",
+ description="ESTIMATES",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="wedgeeq",
+ unicodeslot=0x2259,
+ },
+ [0x225A]={
+ category="sm",
+ description="EQUIANGULAR TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="veeeq",
+ unicodeslot=0x225A,
+ },
+ [0x225B]={
+ category="sm",
+ description="STAR EQUALS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="stareq",
+ unicodeslot=0x225B,
+ },
+ [0x225C]={
+ category="sm",
+ description="DELTA EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="triangleq",
+ unicodeslot=0x225C,
+ },
+ [0x225D]={
+ category="sm",
+ description="EQUAL TO BY DEFINITION",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="definedeq",
+ unicodeslot=0x225D,
+ },
+ [0x225E]={
+ category="sm",
+ description="MEASURED BY",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="measuredeq",
+ unicodeslot=0x225E,
+ },
+ [0x225F]={
+ category="sm",
+ description="QUESTIONED EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="questionedeq",
+ unicodeslot=0x225F,
+ },
+ [0x2260]={
+ adobename="notequal",
+ category="sm",
+ cjkwd="a",
+ description="NOT EQUAL TO",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="relation",
+ name="neq",
+ },
+ {
+ class="relation",
+ name="ne",
+ },
+ },
+ specials={ "char", 0x003D, 0x0338 },
+ unicodeslot=0x2260,
+ },
+ [0x2261]={
+ adobename="equivalence",
+ category="sm",
+ cjkwd="a",
+ description="IDENTICAL TO",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathextensible="h",
+ mathname="equiv",
+ unicodeslot=0x2261,
+ },
+ [0x2262]={
+ adobename="notidentical",
+ category="sm",
+ description="NOT IDENTICAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathfiller="triplerelfill",
+ mathname="nequiv",
+ specials={ "char", 0x2261, 0x0338 },
+ unicodeslot=0x2262,
+ },
+ [0x2263]={
+ category="sm",
+ description="STRICTLY EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ unicodeslot=0x2263,
+ },
+ [0x2264]={
+ adobename="lessequal",
+ category="sm",
+ cjkwd="a",
+ description="LESS-THAN OR EQUAL TO",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="relation",
+ name="leq",
+ },
+ {
+ class="relation",
+ name="le",
+ },
+ },
+ mirror=0x2265,
+ unicodeslot=0x2264,
+ },
+ [0x2265]={
+ adobename="greaterequal",
+ category="sm",
+ cjkwd="a",
+ description="GREATER-THAN OR EQUAL TO",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="relation",
+ name="geq",
+ },
+ {
+ class="relation",
+ name="ge",
+ },
+ },
+ mirror=0x2264,
+ unicodeslot=0x2265,
+ },
+ [0x2266]={
+ adobename="lessoverequal",
+ category="sm",
+ cjkwd="a",
+ description="LESS-THAN OVER EQUAL TO",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="leqq",
+ mirror=0x2267,
+ unicodeslot=0x2266,
+ },
+ [0x2267]={
+ adobename="greateroverequal",
+ category="sm",
+ cjkwd="a",
+ description="GREATER-THAN OVER EQUAL TO",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="geqq",
+ mirror=0x2266,
+ unicodeslot=0x2267,
+ },
+ [0x2268]={
+ category="sm",
+ description="LESS-THAN BUT NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="lneqq",
+ mirror=0x2269,
+ unicodeslot=0x2268,
+ variants={
+ [0xFE00]="with vertical stroke",
+ },
+ },
+ [0x2269]={
+ category="sm",
+ description="GREATER-THAN BUT NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="gneqq",
+ mirror=0x2268,
+ unicodeslot=0x2269,
+ variants={
+ [0xFE00]="with vertical stroke",
+ },
+ },
+ [0x226A]={
+ adobename="muchless",
+ category="sm",
+ cjkwd="a",
+ description="MUCH LESS-THAN",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="ll",
+ mirror=0x226B,
+ unicodeslot=0x226A,
+ },
+ [0x226B]={
+ adobename="muchgreater",
+ category="sm",
+ cjkwd="a",
+ description="MUCH GREATER-THAN",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="gg",
+ mirror=0x226A,
+ unicodeslot=0x226B,
+ },
+ [0x226C]={
+ category="sm",
+ description="BETWEEN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="between",
+ unicodeslot=0x226C,
+ },
+ [0x226D]={
+ category="sm",
+ description="NOT EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nasymp",
+ specials={ "char", 0x224D, 0x0338 },
+ unicodeslot=0x226D,
+ },
+ [0x226E]={
+ adobename="notless",
+ category="sm",
+ cjkwd="a",
+ description="NOT LESS-THAN",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="nless",
+ mirror=0x226F,
+ specials={ "char", 0x003C, 0x0338 },
+ unicodeslot=0x226E,
+ },
+ [0x226F]={
+ adobename="notgreater",
+ category="sm",
+ cjkwd="a",
+ description="NOT GREATER-THAN",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="ngtr",
+ mirror=0x226E,
+ specials={ "char", 0x003E, 0x0338 },
+ unicodeslot=0x226F,
+ },
+ [0x2270]={
+ adobename="notlessnorequal",
+ category="sm",
+ description="NEITHER LESS-THAN NOR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nleq",
+ mirror=0x2271,
+ specials={ "char", 0x2264, 0x0338 },
+ unicodeslot=0x2270,
+ },
+ [0x2271]={
+ adobename="notgreaternorequal",
+ category="sm",
+ description="NEITHER GREATER-THAN NOR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="ngeq",
+ mirror=0x2270,
+ specials={ "char", 0x2265, 0x0338 },
+ unicodeslot=0x2271,
+ },
+ [0x2272]={
+ adobename="lessorequivalent",
+ category="sm",
+ description="LESS-THAN OR EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="lesssim",
+ mirror=0x2273,
+ unicodeslot=0x2272,
+ variants={
+ [0xFE00]="following the slant of the lower leg",
+ },
+ },
+ [0x2273]={
+ adobename="greaterorequivalent",
+ category="sm",
+ description="GREATER-THAN OR EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="gtrsim",
+ mirror=0x2272,
+ unicodeslot=0x2273,
+ variants={
+ [0xFE00]="following the slant of the lower leg",
+ },
+ },
+ [0x2274]={
+ category="sm",
+ description="NEITHER LESS-THAN NOR EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nlesssim",
+ mirror=0x2275,
+ specials={ "char", 0x2272, 0x0338 },
+ unicodeslot=0x2274,
+ },
+ [0x2275]={
+ category="sm",
+ description="NEITHER GREATER-THAN NOR EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="ngtrsim",
+ mirror=0x2274,
+ specials={ "char", 0x2273, 0x0338 },
+ unicodeslot=0x2275,
+ },
+ [0x2276]={
+ adobename="lessorgreater",
+ category="sm",
+ description="LESS-THAN OR GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="lessgtr",
+ mirror=0x2277,
+ unicodeslot=0x2276,
+ },
+ [0x2277]={
+ adobename="greaterorless",
+ category="sm",
+ description="GREATER-THAN OR LESS-THAN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="gtrless",
+ mirror=0x2276,
+ unicodeslot=0x2277,
+ },
+ [0x2278]={
+ category="sm",
+ description="NEITHER LESS-THAN NOR GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nlessgtr",
+ mirror=0x2279,
+ specials={ "char", 0x2276, 0x0338 },
+ unicodeslot=0x2278,
+ },
+ [0x2279]={
+ adobename="notgreaternorless",
+ category="sm",
+ description="NEITHER GREATER-THAN NOR LESS-THAN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="ngtrless",
+ mirror=0x2278,
+ specials={ "char", 0x2277, 0x0338 },
+ unicodeslot=0x2279,
+ },
+ [0x227A]={
+ adobename="precedes",
+ category="sm",
+ description="PRECEDES",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="prec",
+ mirror=0x227B,
+ unicodeslot=0x227A,
+ },
+ [0x227B]={
+ adobename="succeeds",
+ category="sm",
+ description="SUCCEEDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="succ",
+ mirror=0x227A,
+ unicodeslot=0x227B,
+ },
+ [0x227C]={
+ category="sm",
+ description="PRECEDES OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="preccurlyeq",
+ mirror=0x227D,
+ unicodeslot=0x227C,
+ },
+ [0x227D]={
+ category="sm",
+ description="SUCCEEDS OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="succcurlyeq",
+ mirror=0x227C,
+ unicodeslot=0x227D,
+ },
+ [0x227E]={
+ category="sm",
+ description="PRECEDES OR EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="precsim",
+ mirror=0x227F,
+ unicodeslot=0x227E,
+ },
+ [0x227F]={
+ category="sm",
+ description="SUCCEEDS OR EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="succsim",
+ mirror=0x227E,
+ unicodeslot=0x227F,
+ },
+ [0x2280]={
+ adobename="notprecedes",
+ category="sm",
+ description="DOES NOT PRECEDE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nprec",
+ mirror=0x2281,
+ specials={ "char", 0x227A, 0x0338 },
+ unicodeslot=0x2280,
+ },
+ [0x2281]={
+ adobename="notsucceeds",
+ category="sm",
+ description="DOES NOT SUCCEED",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nsucc",
+ mirror=0x2280,
+ specials={ "char", 0x227B, 0x0338 },
+ unicodeslot=0x2281,
+ },
+ [0x2282]={
+ adobename="subset",
+ category="sm",
+ cjkwd="a",
+ description="SUBSET OF",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="subset",
+ mirror=0x2283,
+ unicodeslot=0x2282,
+ },
+ [0x2283]={
+ adobename="superset",
+ category="sm",
+ cjkwd="a",
+ description="SUPERSET OF",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="supset",
+ mirror=0x2282,
+ unicodeslot=0x2283,
+ },
+ [0x2284]={
+ adobename="notsubset",
+ category="sm",
+ description="NOT A SUBSET OF",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nsubset",
+ mirror=0x2285,
+ specials={ "char", 0x2282, 0x0338 },
+ unicodeslot=0x2284,
+ },
+ [0x2285]={
+ adobename="notsuperset",
+ category="sm",
+ description="NOT A SUPERSET OF",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nsupset",
+ mirror=0x2284,
+ specials={ "char", 0x2283, 0x0338 },
+ unicodeslot=0x2285,
+ },
+ [0x2286]={
+ adobename="subsetorequal",
+ category="sm",
+ cjkwd="a",
+ description="SUBSET OF OR EQUAL TO",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="subseteq",
+ mirror=0x2287,
+ unicodeslot=0x2286,
+ },
+ [0x2287]={
+ adobename="supersetorequal",
+ category="sm",
+ cjkwd="a",
+ description="SUPERSET OF OR EQUAL TO",
+ direction="on",
+ linebreak="ai",
+ mathclass="relation",
+ mathname="supseteq",
+ mirror=0x2286,
+ unicodeslot=0x2287,
+ },
+ [0x2288]={
+ category="sm",
+ description="NEITHER A SUBSET OF NOR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nsubseteq",
+ mirror=0x2289,
+ specials={ "char", 0x2286, 0x0338 },
+ unicodeslot=0x2288,
+ },
+ [0x2289]={
+ category="sm",
+ description="NEITHER A SUPERSET OF NOR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nsupseteq",
+ mirror=0x2288,
+ specials={ "char", 0x2287, 0x0338 },
+ unicodeslot=0x2289,
+ },
+ [0x228A]={
+ adobename="subsetnotequal",
+ category="sm",
+ description="SUBSET OF WITH NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="subsetneq",
+ mirror=0x228B,
+ unicodeslot=0x228A,
+ variants={
+ [0xFE00]="with stroke through bottom members",
+ },
+ },
+ [0x228B]={
+ adobename="supersetnotequal",
+ category="sm",
+ description="SUPERSET OF WITH NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="supsetneq",
+ mirror=0x228A,
+ unicodeslot=0x228B,
+ variants={
+ [0xFE00]="with stroke through bottom members",
+ },
+ },
+ [0x228C]={
+ category="sm",
+ description="MULTISET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x228C,
+ },
+ [0x228D]={
+ category="sm",
+ description="MULTISET MULTIPLICATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x228D,
+ },
+ [0x228E]={
+ category="sm",
+ description="MULTISET UNION",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="uplus",
+ unicodeslot=0x228E,
+ },
+ [0x228F]={
+ category="sm",
+ description="SQUARE IMAGE OF",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="sqsubset",
+ mirror=0x2290,
+ unicodeslot=0x228F,
+ },
+ [0x2290]={
+ category="sm",
+ description="SQUARE ORIGINAL OF",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="sqsupset",
+ mirror=0x228F,
+ unicodeslot=0x2290,
+ },
+ [0x2291]={
+ category="sm",
+ description="SQUARE IMAGE OF OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="sqsubseteq",
+ mirror=0x2292,
+ unicodeslot=0x2291,
+ },
+ [0x2292]={
+ category="sm",
+ description="SQUARE ORIGINAL OF OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="sqsupseteq",
+ mirror=0x2291,
+ unicodeslot=0x2292,
+ },
+ [0x2293]={
+ category="sm",
+ description="SQUARE CAP",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="sqcap",
+ unicodeslot=0x2293,
+ variants={
+ [0xFE00]="with serifs",
+ },
+ },
+ [0x2294]={
+ category="sm",
+ description="SQUARE CUP",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="sqcup",
+ unicodeslot=0x2294,
+ variants={
+ [0xFE00]="with serifs",
+ },
+ },
+ [0x2295]={
+ adobename="pluscircle",
+ category="sm",
+ cjkwd="a",
+ description="CIRCLED PLUS",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="oplus",
+ unicodeslot=0x2295,
+ variants={
+ [0xFE00]="with white rim",
+ },
+ },
+ [0x2296]={
+ adobename="minuscircle",
+ category="sm",
+ description="CIRCLED MINUS",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="ominus",
+ unicodeslot=0x2296,
+ },
+ [0x2297]={
+ adobename="timescircle",
+ category="sm",
+ description="CIRCLED TIMES",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="otimes",
+ unicodeslot=0x2297,
+ variants={
+ [0xFE00]="with white rim",
+ },
+ },
+ [0x2298]={
+ category="sm",
+ description="CIRCLED DIVISION SLASH",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="oslash",
+ mirror=0x29B8,
+ unicodeslot=0x2298,
+ },
+ [0x2299]={
+ adobename="circleot",
+ category="sm",
+ cjkwd="a",
+ description="CIRCLED DOT OPERATOR",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="odot",
+ unicodeslot=0x2299,
+ },
+ [0x229A]={
+ category="sm",
+ description="CIRCLED RING OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="circledcirc",
+ unicodeslot=0x229A,
+ },
+ [0x229B]={
+ category="sm",
+ description="CIRCLED ASTERISK OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="circledast",
+ unicodeslot=0x229B,
+ },
+ [0x229C]={
+ category="sm",
+ description="CIRCLED EQUALS",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="circledequals",
+ unicodeslot=0x229C,
+ variants={
+ [0xFE00]="with equal sign touching the circle",
+ },
+ },
+ [0x229D]={
+ category="sm",
+ description="CIRCLED DASH",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="circleddash",
+ unicodeslot=0x229D,
+ },
+ [0x229E]={
+ category="sm",
+ description="SQUARED PLUS",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="boxplus",
+ unicodeslot=0x229E,
+ },
+ [0x229F]={
+ category="sm",
+ description="SQUARED MINUS",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="boxminus",
+ unicodeslot=0x229F,
+ },
+ [0x22A0]={
+ category="sm",
+ description="SQUARED TIMES",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="boxtimes",
+ unicodeslot=0x22A0,
+ },
+ [0x22A1]={
+ category="sm",
+ description="SQUARED DOT OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="boxdot",
+ unicodeslot=0x22A1,
+ },
+ [0x22A2]={
+ category="sm",
+ description="RIGHT TACK",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="vdash",
+ mirror=0x22A3,
+ unicodeslot=0x22A2,
+ },
+ [0x22A3]={
+ adobename="tackleft",
+ category="sm",
+ description="LEFT TACK",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="dashv",
+ mirror=0x22A2,
+ unicodeslot=0x22A3,
+ },
+ [0x22A4]={
+ adobename="tackdown",
+ category="sm",
+ description="DOWN TACK",
+ direction="on",
+ linebreak="al",
+ mathclass="default",
+ mathname="top",
+ unicodeslot=0x22A4,
+ },
+ [0x22A5]={
+ adobename="perpendicular",
+ category="sm",
+ cjkwd="a",
+ description="UP TACK",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="default",
+ name="bot",
+ },
+ {
+ class="relation",
+ name="perp",
+ },
+ },
+ unicodeslot=0x22A5,
+ },
+ [0x22A6]={
+ category="sm",
+ description="ASSERTION",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ADE,
+ unicodeslot=0x22A6,
+ },
+ [0x22A7]={
+ category="sm",
+ description="MODELS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="models",
+ unicodeslot=0x22A7,
+ },
+ [0x22A8]={
+ category="sm",
+ description="TRUE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="vDash",
+ mirror=0x2AE4,
+ unicodeslot=0x22A8,
+ },
+ [0x22A9]={
+ category="sm",
+ description="FORCES",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="Vdash",
+ mirror=0x2AE3,
+ unicodeslot=0x22A9,
+ },
+ [0x22AA]={
+ category="sm",
+ description="TRIPLE VERTICAL BAR RIGHT TURNSTILE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="Vvdash",
+ unicodeslot=0x22AA,
+ },
+ [0x22AB]={
+ category="sm",
+ description="DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="VDash",
+ mirror=0x2AE5,
+ unicodeslot=0x22AB,
+ },
+ [0x22AC]={
+ category="sm",
+ description="DOES NOT PROVE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nvdash",
+ specials={ "char", 0x22A2, 0x0338 },
+ unicodeslot=0x22AC,
+ },
+ [0x22AD]={
+ category="sm",
+ description="NOT TRUE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nvDash",
+ specials={ "char", 0x22A8, 0x0338 },
+ unicodeslot=0x22AD,
+ },
+ [0x22AE]={
+ category="sm",
+ description="DOES NOT FORCE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nVdash",
+ specials={ "char", 0x22A9, 0x0338 },
+ unicodeslot=0x22AE,
+ },
+ [0x22AF]={
+ category="sm",
+ description="NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nVDash",
+ specials={ "char", 0x22AB, 0x0338 },
+ unicodeslot=0x22AF,
+ },
+ [0x22B0]={
+ category="sm",
+ description="PRECEDES UNDER RELATION",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B1,
+ unicodeslot=0x22B0,
+ },
+ [0x22B1]={
+ category="sm",
+ description="SUCCEEDS UNDER RELATION",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B0,
+ unicodeslot=0x22B1,
+ },
+ [0x22B2]={
+ category="sm",
+ comment="cramped triangleleft",
+ description="NORMAL SUBGROUP OF",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mirror=0x22B3,
+ unicodeslot=0x22B2,
+ },
+ [0x22B3]={
+ category="sm",
+ comment="cramped triangleright",
+ description="CONTAINS AS NORMAL SUBGROUP",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mirror=0x22B2,
+ unicodeslot=0x22B3,
+ },
+ [0x22B4]={
+ category="sm",
+ description="NORMAL SUBGROUP OF OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B5,
+ unicodeslot=0x22B4,
+ },
+ [0x22B5]={
+ category="sm",
+ description="CONTAINS AS NORMAL SUBGROUP OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B4,
+ unicodeslot=0x22B5,
+ },
+ [0x22B6]={
+ category="sm",
+ description="ORIGINAL OF",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B7,
+ unicodeslot=0x22B6,
+ },
+ [0x22B7]={
+ category="sm",
+ description="IMAGE OF",
+ direction="on",
+ linebreak="al",
+ mirror=0x22B6,
+ unicodeslot=0x22B7,
+ },
+ [0x22B8]={
+ category="sm",
+ description="MULTIMAP",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="multimap",
+ unicodeslot=0x22B8,
+ },
+ [0x22B9]={
+ category="sm",
+ description="HERMITIAN CONJUGATE MATRIX",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22B9,
+ },
+ [0x22BA]={
+ category="sm",
+ description="INTERCALATE",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="intercal",
+ unicodeslot=0x22BA,
+ },
+ [0x22BB]={
+ category="sm",
+ description="XOR",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="veebar",
+ unicodeslot=0x22BB,
+ },
+ [0x22BC]={
+ category="sm",
+ description="NAND",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="barwedge",
+ unicodeslot=0x22BC,
+ },
+ [0x22BD]={
+ category="sm",
+ description="NOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22BD,
+ },
+ [0x22BE]={
+ category="sm",
+ description="RIGHT ANGLE WITH ARC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22BE,
+ },
+ [0x22BF]={
+ adobename="righttriangle",
+ category="sm",
+ cjkwd="a",
+ description="RIGHT TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x22BF,
+ },
+ [0x22C0]={
+ category="sm",
+ description="N-ARY LOGICAL AND",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="bigwedge",
+ unicodeslot=0x22C0,
+ },
+ [0x22C1]={
+ category="sm",
+ description="N-ARY LOGICAL OR",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="bigvee",
+ unicodeslot=0x22C1,
+ },
+ [0x22C2]={
+ category="sm",
+ description="N-ARY INTERSECTION",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="bigcap",
+ unicodeslot=0x22C2,
+ },
+ [0x22C3]={
+ category="sm",
+ description="N-ARY UNION",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="bigcup",
+ unicodeslot=0x22C3,
+ },
+ [0x22C4]={
+ category="sm",
+ description="DIAMOND OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="diamond",
+ unicodeslot=0x22C4,
+ },
+ [0x22C5]={
+ adobename="dotmath",
+ category="sm",
+ description="DOT OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="binary",
+ name="cdot",
+ },
+ {
+ class="punctuation",
+ name="cdotp",
+ },
+ },
+ unicodeslot=0x22C5,
+ },
+ [0x22C6]={
+ category="sm",
+ description="STAR OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="star",
+ unicodeslot=0x22C6,
+ },
+ [0x22C7]={
+ category="sm",
+ description="DIVISION TIMES",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="divideontimes",
+ unicodeslot=0x22C7,
+ },
+ [0x22C8]={
+ category="sm",
+ description="BOWTIE",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="bowtie",
+ },
+ {
+ class="relation",
+ name="Join",
+ },
+ },
+ unicodeslot=0x22C8,
+ },
+ [0x22C9]={
+ category="sm",
+ description="LEFT NORMAL FACTOR SEMIDIRECT PRODUCT",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="ltimes",
+ mirror=0x22CA,
+ unicodeslot=0x22C9,
+ },
+ [0x22CA]={
+ category="sm",
+ description="RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="rtimes",
+ mirror=0x22C9,
+ unicodeslot=0x22CA,
+ },
+ [0x22CB]={
+ category="sm",
+ description="LEFT SEMIDIRECT PRODUCT",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="leftthreetimes",
+ mirror=0x22CC,
+ unicodeslot=0x22CB,
+ },
+ [0x22CC]={
+ category="sm",
+ description="RIGHT SEMIDIRECT PRODUCT",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="rightthreetimes",
+ mirror=0x22CB,
+ unicodeslot=0x22CC,
+ },
+ [0x22CD]={
+ category="sm",
+ description="REVERSED TILDE EQUALS",
+ direction="on",
+ linebreak="al",
+ mirror=0x2243,
+ unicodeslot=0x22CD,
+ },
+ [0x22CE]={
+ adobename="curlyor",
+ category="sm",
+ description="CURLY LOGICAL OR",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="curlyvee",
+ unicodeslot=0x22CE,
+ },
+ [0x22CF]={
+ adobename="curlyand",
+ category="sm",
+ description="CURLY LOGICAL AND",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="curlywedge",
+ unicodeslot=0x22CF,
+ },
+ [0x22D0]={
+ category="sm",
+ description="DOUBLE SUBSET",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="Subset",
+ mirror=0x22D1,
+ unicodeslot=0x22D0,
+ },
+ [0x22D1]={
+ category="sm",
+ description="DOUBLE SUPERSET",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="Supset",
+ mirror=0x22D0,
+ unicodeslot=0x22D1,
+ },
+ [0x22D2]={
+ category="sm",
+ description="DOUBLE INTERSECTION",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="binary",
+ name="Cap",
+ },
+ {
+ class="binary",
+ name="doublecap",
+ },
+ },
+ unicodeslot=0x22D2,
+ },
+ [0x22D3]={
+ category="sm",
+ description="DOUBLE UNION",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="binary",
+ name="Cup",
+ },
+ {
+ class="binary",
+ name="doublecup",
+ },
+ },
+ unicodeslot=0x22D3,
+ },
+ [0x22D4]={
+ category="sm",
+ description="PITCHFORK",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="pitchfork",
+ unicodeslot=0x22D4,
+ },
+ [0x22D5]={
+ category="sm",
+ description="EQUAL AND PARALLEL TO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22D5,
+ },
+ [0x22D6]={
+ category="sm",
+ description="LESS-THAN WITH DOT",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="lessdot",
+ mirror=0x22D7,
+ unicodeslot=0x22D6,
+ },
+ [0x22D7]={
+ category="sm",
+ description="GREATER-THAN WITH DOT",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="gtrdot",
+ mirror=0x22D6,
+ unicodeslot=0x22D7,
+ },
+ [0x22D8]={
+ category="sm",
+ description="VERY MUCH LESS-THAN",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="lll",
+ },
+ {
+ class="relation",
+ name="llless",
+ },
+ },
+ mirror=0x22D9,
+ unicodeslot=0x22D8,
+ },
+ [0x22D9]={
+ category="sm",
+ description="VERY MUCH GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="relation",
+ name="ggg",
+ },
+ {
+ class="relation",
+ name="gggtr",
+ },
+ },
+ mirror=0x22D8,
+ unicodeslot=0x22D9,
+ },
+ [0x22DA]={
+ adobename="lessequalorgreater",
+ category="sm",
+ description="LESS-THAN EQUAL TO OR GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="lesseqgtr",
+ mirror=0x22DB,
+ unicodeslot=0x22DA,
+ variants={
+ [0xFE00]="with slanted equal",
+ },
+ },
+ [0x22DB]={
+ adobename="greaterequalorless",
+ category="sm",
+ description="GREATER-THAN EQUAL TO OR LESS-THAN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="gtreqless",
+ mirror=0x22DA,
+ unicodeslot=0x22DB,
+ variants={
+ [0xFE00]="with slanted equal",
+ },
+ },
+ [0x22DC]={
+ category="sm",
+ description="EQUAL TO OR LESS-THAN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="eqless",
+ mirror=0x22DD,
+ unicodeslot=0x22DC,
+ },
+ [0x22DD]={
+ category="sm",
+ description="EQUAL TO OR GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="eqgtr",
+ mirror=0x22DC,
+ unicodeslot=0x22DD,
+ },
+ [0x22DE]={
+ category="sm",
+ description="EQUAL TO OR PRECEDES",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="curlyeqprec",
+ mirror=0x22DF,
+ unicodeslot=0x22DE,
+ },
+ [0x22DF]={
+ category="sm",
+ description="EQUAL TO OR SUCCEEDS",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="curlyeqsucc",
+ mirror=0x22DE,
+ unicodeslot=0x22DF,
+ },
+ [0x22E0]={
+ category="sm",
+ description="DOES NOT PRECEDE OR EQUAL",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="npreccurlyeq",
+ mirror=0x22E1,
+ specials={ "char", 0x227C, 0x0338 },
+ unicodeslot=0x22E0,
+ },
+ [0x22E1]={
+ category="sm",
+ description="DOES NOT SUCCEED OR EQUAL",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nsucccurlyeq",
+ mirror=0x22E0,
+ specials={ "char", 0x227D, 0x0338 },
+ unicodeslot=0x22E1,
+ },
+ [0x22E2]={
+ category="sm",
+ description="NOT SQUARE IMAGE OF OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nsqsubseteq",
+ mirror=0x22E3,
+ specials={ "char", 0x2291, 0x0338 },
+ unicodeslot=0x22E2,
+ },
+ [0x22E3]={
+ category="sm",
+ description="NOT SQUARE ORIGINAL OF OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nsqsupseteq",
+ mirror=0x22E2,
+ specials={ "char", 0x2292, 0x0338 },
+ unicodeslot=0x22E3,
+ },
+ [0x22E4]={
+ category="sm",
+ description="SQUARE IMAGE OF OR NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="sqsubsetneq",
+ mirror=0x22E5,
+ unicodeslot=0x22E4,
+ },
+ [0x22E5]={
+ category="sm",
+ description="SQUARE ORIGINAL OF OR NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="sqsupsetneq",
+ mirror=0x22E4,
+ unicodeslot=0x22E5,
+ },
+ [0x22E6]={
+ category="sm",
+ description="LESS-THAN BUT NOT EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="lnsim",
+ mirror=0x22E7,
+ unicodeslot=0x22E6,
+ },
+ [0x22E7]={
+ category="sm",
+ description="GREATER-THAN BUT NOT EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="gnsim",
+ mirror=0x22E6,
+ unicodeslot=0x22E7,
+ },
+ [0x22E8]={
+ category="sm",
+ description="PRECEDES BUT NOT EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="precnsim",
+ mirror=0x22E9,
+ unicodeslot=0x22E8,
+ },
+ [0x22E9]={
+ category="sm",
+ description="SUCCEEDS BUT NOT EQUIVALENT TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="succnsim",
+ mirror=0x22E8,
+ unicodeslot=0x22E9,
+ },
+ [0x22EA]={
+ category="sm",
+ description="NOT NORMAL SUBGROUP OF",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="ntriangleright",
+ mirror=0x22EB,
+ specials={ "char", 0x22B2, 0x0338 },
+ unicodeslot=0x22EA,
+ },
+ [0x22EB]={
+ category="sm",
+ description="DOES NOT CONTAIN AS NORMAL SUBGROUP",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="ntriangleleft",
+ mirror=0x22EA,
+ specials={ "char", 0x22B3, 0x0338 },
+ unicodeslot=0x22EB,
+ },
+ [0x22EC]={
+ category="sm",
+ description="NOT NORMAL SUBGROUP OF OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="ntrianglelefteq",
+ mirror=0x22ED,
+ specials={ "char", 0x22B4, 0x0338 },
+ unicodeslot=0x22EC,
+ },
+ [0x22ED]={
+ category="sm",
+ description="DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="ntrianglerighteq",
+ mirror=0x22EC,
+ specials={ "char", 0x22B5, 0x0338 },
+ unicodeslot=0x22ED,
+ },
+ [0x22EE]={
+ adobename="ellipsisvertical",
+ category="sm",
+ description="VERTICAL ELLIPSIS",
+ direction="on",
+ linebreak="al",
+ mathclass="inner",
+ mathname="vdots",
+ unicodeslot=0x22EE,
+ },
+ [0x22EF]={
+ category="sm",
+ description="MIDLINE HORIZONTAL ELLIPSIS",
+ direction="on",
+ linebreak="al",
+ mathclass="inner",
+ mathname="cdots",
+ unicodeslot=0x22EF,
+ },
+ [0x22F0]={
+ category="sm",
+ description="UP RIGHT DIAGONAL ELLIPSIS",
+ direction="on",
+ linebreak="al",
+ mathclass="inner",
+ mathname="udots",
+ mirror=0x22F1,
+ unicodeslot=0x22F0,
+ },
+ [0x22F1]={
+ category="sm",
+ description="DOWN RIGHT DIAGONAL ELLIPSIS",
+ direction="on",
+ linebreak="al",
+ mathclass="inner",
+ mathname="ddots",
+ mirror=0x22F0,
+ unicodeslot=0x22F1,
+ },
+ [0x22F2]={
+ category="sm",
+ description="ELEMENT OF WITH LONG HORIZONTAL STROKE",
+ direction="on",
+ linebreak="al",
+ mirror=0x22FA,
+ unicodeslot=0x22F2,
+ },
+ [0x22F3]={
+ category="sm",
+ description="ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE",
+ direction="on",
+ linebreak="al",
+ mirror=0x22FB,
+ unicodeslot=0x22F3,
+ },
+ [0x22F4]={
+ category="sm",
+ description="SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE",
+ direction="on",
+ linebreak="al",
+ mirror=0x22FC,
+ unicodeslot=0x22F4,
+ },
+ [0x22F5]={
+ category="sm",
+ description="ELEMENT OF WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22F5,
+ },
+ [0x22F6]={
+ category="sm",
+ description="ELEMENT OF WITH OVERBAR",
+ direction="on",
+ linebreak="al",
+ mirror=0x22FD,
+ unicodeslot=0x22F6,
+ },
+ [0x22F7]={
+ category="sm",
+ description="SMALL ELEMENT OF WITH OVERBAR",
+ direction="on",
+ linebreak="al",
+ mirror=0x22FE,
+ unicodeslot=0x22F7,
+ },
+ [0x22F8]={
+ category="sm",
+ description="ELEMENT OF WITH UNDERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22F8,
+ },
+ [0x22F9]={
+ category="sm",
+ description="ELEMENT OF WITH TWO HORIZONTAL STROKES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22F9,
+ },
+ [0x22FA]={
+ category="sm",
+ description="CONTAINS WITH LONG HORIZONTAL STROKE",
+ direction="on",
+ linebreak="al",
+ mirror=0x22F2,
+ unicodeslot=0x22FA,
+ },
+ [0x22FB]={
+ category="sm",
+ description="CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE",
+ direction="on",
+ linebreak="al",
+ mirror=0x22F3,
+ unicodeslot=0x22FB,
+ },
+ [0x22FC]={
+ category="sm",
+ description="SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE",
+ direction="on",
+ linebreak="al",
+ mirror=0x22F4,
+ unicodeslot=0x22FC,
+ },
+ [0x22FD]={
+ category="sm",
+ description="CONTAINS WITH OVERBAR",
+ direction="on",
+ linebreak="al",
+ mirror=0x22F6,
+ unicodeslot=0x22FD,
+ },
+ [0x22FE]={
+ category="sm",
+ description="SMALL CONTAINS WITH OVERBAR",
+ direction="on",
+ linebreak="al",
+ mirror=0x22F7,
+ unicodeslot=0x22FE,
+ },
+ [0x22FF]={
+ category="sm",
+ description="Z NOTATION BAG MEMBERSHIP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x22FF,
+ },
+ [0x2300]={
+ category="so",
+ description="DIAMETER SIGN",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="varnothing",
+ unicodeslot=0x2300,
+ },
+ [0x2301]={
+ category="so",
+ description="ELECTRIC ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2301,
+ },
+ [0x2302]={
+ adobename="house",
+ category="so",
+ description="HOUSE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2302,
+ },
+ [0x2303]={
+ adobename="control",
+ category="so",
+ description="UP ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2303,
+ },
+ [0x2304]={
+ category="so",
+ description="DOWN ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2304,
+ },
+ [0x2305]={
+ adobename="projective",
+ category="so",
+ description="PROJECTIVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2305,
+ },
+ [0x2306]={
+ category="so",
+ description="PERSPECTIVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2306,
+ },
+ [0x2307]={
+ category="so",
+ description="WAVY LINE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2307,
+ },
+ [0x2308]={
+ category="sm",
+ description="LEFT CEILING",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="open",
+ name="lceil",
+ },
+ {
+ class="open",
+ name="lceiling",
+ },
+ },
+ mirror=0x2309,
+ unicodeslot=0x2308,
+ },
+ [0x2309]={
+ category="sm",
+ description="RIGHT CEILING",
+ direction="on",
+ linebreak="al",
+ mathspec={
+ {
+ class="close",
+ name="rceil",
+ },
+ {
+ class="close",
+ name="rceiling",
+ },
+ },
+ mirror=0x2308,
+ unicodeslot=0x2309,
+ },
+ [0x230A]={
+ category="sm",
+ description="LEFT FLOOR",
+ direction="on",
+ linebreak="al",
+ mathclass="open",
+ mathname="lfloor",
+ mirror=0x230B,
+ unicodeslot=0x230A,
+ },
+ [0x230B]={
+ category="sm",
+ description="RIGHT FLOOR",
+ direction="on",
+ linebreak="al",
+ mathclass="close",
+ mathname="rfloor",
+ mirror=0x230A,
+ unicodeslot=0x230B,
+ },
+ [0x230C]={
+ category="so",
+ description="BOTTOM RIGHT CROP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x230C,
+ },
+ [0x230D]={
+ category="so",
+ description="BOTTOM LEFT CROP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x230D,
+ },
+ [0x230E]={
+ category="so",
+ description="TOP RIGHT CROP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x230E,
+ },
+ [0x230F]={
+ category="so",
+ description="TOP LEFT CROP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x230F,
+ },
+ [0x2310]={
+ adobename="revlogicalnot",
+ category="so",
+ description="REVERSED NOT SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2310,
+ },
+ [0x2311]={
+ category="so",
+ description="SQUARE LOZENGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2311,
+ },
+ [0x2312]={
+ adobename="arc",
+ category="so",
+ cjkwd="a",
+ description="ARC",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2312,
+ },
+ [0x2313]={
+ category="so",
+ description="SEGMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2313,
+ },
+ [0x2314]={
+ category="so",
+ description="SECTOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2314,
+ },
+ [0x2315]={
+ category="so",
+ description="TELEPHONE RECORDER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2315,
+ },
+ [0x2316]={
+ category="so",
+ description="POSITION INDICATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2316,
+ },
+ [0x2317]={
+ category="so",
+ description="VIEWDATA SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2317,
+ },
+ [0x2318]={
+ adobename="propellor",
+ category="so",
+ description="PLACE OF INTEREST SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2318,
+ },
+ [0x2319]={
+ category="so",
+ description="TURNED NOT SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2319,
+ },
+ [0x231A]={
+ category="so",
+ description="WATCH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x231A,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x231B]={
+ category="so",
+ description="HOURGLASS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x231B,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x231C]={
+ category="so",
+ description="TOP LEFT CORNER",
+ direction="on",
+ linebreak="al",
+ mathclass="open",
+ mathname="ulcorner",
+ unicodeslot=0x231C,
+ },
+ [0x231D]={
+ category="so",
+ description="TOP RIGHT CORNER",
+ direction="on",
+ linebreak="al",
+ mathclass="close",
+ mathname="urcorner",
+ unicodeslot=0x231D,
+ },
+ [0x231E]={
+ category="so",
+ description="BOTTOM LEFT CORNER",
+ direction="on",
+ linebreak="al",
+ mathclass="open",
+ mathname="llcorner",
+ unicodeslot=0x231E,
+ },
+ [0x231F]={
+ category="so",
+ description="BOTTOM RIGHT CORNER",
+ direction="on",
+ linebreak="al",
+ mathclass="close",
+ mathname="lrcorner",
+ unicodeslot=0x231F,
+ },
+ [0x2320]={
+ adobename="integraltp",
+ category="sm",
+ description="TOP HALF INTEGRAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2320,
+ },
+ [0x2321]={
+ adobename="integralbt",
+ category="sm",
+ description="BOTTOM HALF INTEGRAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2321,
+ },
+ [0x2322]={
+ category="so",
+ description="FROWN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="frown",
+ unicodeslot=0x2322,
+ },
+ [0x2323]={
+ category="so",
+ description="SMILE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="smile",
+ unicodeslot=0x2323,
+ },
+ [0x2324]={
+ category="so",
+ description="UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2324,
+ },
+ [0x2325]={
+ adobename="option",
+ category="so",
+ description="OPTION KEY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2325,
+ },
+ [0x2326]={
+ adobename="deleteright",
+ category="so",
+ description="ERASE TO THE RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2326,
+ },
+ [0x2327]={
+ adobename="clear",
+ category="so",
+ description="X IN A RECTANGLE BOX",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2327,
+ },
+ [0x2328]={
+ category="so",
+ description="KEYBOARD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2328,
+ },
+ [0x2329]={
+ adobename="angleleft",
+ category="ps",
+ cjkwd="w",
+ description="LEFT-POINTING ANGLE BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x232A,
+ specials={ "char", 0x3008 },
+ unicodeslot=0x2329,
+ },
+ [0x232A]={
+ adobename="angleright",
+ category="pe",
+ cjkwd="w",
+ description="RIGHT-POINTING ANGLE BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2329,
+ specials={ "char", 0x3009 },
+ unicodeslot=0x232A,
+ },
+ [0x232B]={
+ adobename="deleteleft",
+ category="so",
+ description="ERASE TO THE LEFT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x232B,
+ },
+ [0x232C]={
+ category="so",
+ description="BENZENE RING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x232C,
+ },
+ [0x232D]={
+ category="so",
+ description="CYLINDRICITY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x232D,
+ },
+ [0x232E]={
+ category="so",
+ description="ALL AROUND-PROFILE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x232E,
+ },
+ [0x232F]={
+ category="so",
+ description="SYMMETRY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x232F,
+ },
+ [0x2330]={
+ category="so",
+ description="TOTAL RUNOUT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2330,
+ },
+ [0x2331]={
+ category="so",
+ description="DIMENSION ORIGIN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2331,
+ },
+ [0x2332]={
+ category="so",
+ description="CONICAL TAPER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2332,
+ },
+ [0x2333]={
+ category="so",
+ description="SLOPE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2333,
+ },
+ [0x2334]={
+ category="so",
+ description="COUNTERBORE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2334,
+ },
+ [0x2335]={
+ category="so",
+ description="COUNTERSINK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2335,
+ },
+ [0x2336]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL I-BEAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2336,
+ },
+ [0x2337]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL SQUISH QUAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2337,
+ },
+ [0x2338]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD EQUAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2338,
+ },
+ [0x2339]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD DIVIDE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2339,
+ },
+ [0x233A]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD DIAMOND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x233A,
+ },
+ [0x233B]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD JOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x233B,
+ },
+ [0x233C]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD CIRCLE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x233C,
+ },
+ [0x233D]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL CIRCLE STILE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x233D,
+ },
+ [0x233E]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL CIRCLE JOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x233E,
+ },
+ [0x233F]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL SLASH BAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x233F,
+ },
+ [0x2340]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL BACKSLASH BAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2340,
+ },
+ [0x2341]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD SLASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2341,
+ },
+ [0x2342]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD BACKSLASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2342,
+ },
+ [0x2343]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD LESS-THAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2343,
+ },
+ [0x2344]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD GREATER-THAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2344,
+ },
+ [0x2345]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL LEFTWARDS VANE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2345,
+ },
+ [0x2346]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL RIGHTWARDS VANE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2346,
+ },
+ [0x2347]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2347,
+ },
+ [0x2348]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2348,
+ },
+ [0x2349]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2349,
+ },
+ [0x234A]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234A,
+ },
+ [0x234B]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL DELTA STILE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234B,
+ },
+ [0x234C]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD DOWN CARET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234C,
+ },
+ [0x234D]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD DELTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234D,
+ },
+ [0x234E]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL DOWN TACK JOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234E,
+ },
+ [0x234F]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL UPWARDS VANE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x234F,
+ },
+ [0x2350]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2350,
+ },
+ [0x2351]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL UP TACK OVERBAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2351,
+ },
+ [0x2352]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL DEL STILE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2352,
+ },
+ [0x2353]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD UP CARET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2353,
+ },
+ [0x2354]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD DEL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2354,
+ },
+ [0x2355]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL UP TACK JOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2355,
+ },
+ [0x2356]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL DOWNWARDS VANE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2356,
+ },
+ [0x2357]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2357,
+ },
+ [0x2358]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUOTE UNDERBAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2358,
+ },
+ [0x2359]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL DELTA UNDERBAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2359,
+ },
+ [0x235A]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235A,
+ },
+ [0x235B]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL JOT UNDERBAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235B,
+ },
+ [0x235C]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235C,
+ },
+ [0x235D]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL UP SHOE JOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235D,
+ },
+ [0x235E]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUOTE QUAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235E,
+ },
+ [0x235F]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL CIRCLE STAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x235F,
+ },
+ [0x2360]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD COLON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2360,
+ },
+ [0x2361]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL UP TACK DIAERESIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2361,
+ },
+ [0x2362]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL DEL DIAERESIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2362,
+ },
+ [0x2363]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL STAR DIAERESIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2363,
+ },
+ [0x2364]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL JOT DIAERESIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2364,
+ },
+ [0x2365]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2365,
+ },
+ [0x2366]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL DOWN SHOE STILE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2366,
+ },
+ [0x2367]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL LEFT SHOE STILE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2367,
+ },
+ [0x2368]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL TILDE DIAERESIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2368,
+ },
+ [0x2369]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2369,
+ },
+ [0x236A]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL COMMA BAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236A,
+ },
+ [0x236B]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL DEL TILDE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236B,
+ },
+ [0x236C]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL ZILDE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236C,
+ },
+ [0x236D]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL STILE TILDE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236D,
+ },
+ [0x236E]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236E,
+ },
+ [0x236F]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD NOT EQUAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x236F,
+ },
+ [0x2370]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD QUESTION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2370,
+ },
+ [0x2371]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL DOWN CARET TILDE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2371,
+ },
+ [0x2372]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL UP CARET TILDE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2372,
+ },
+ [0x2373]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL IOTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2373,
+ },
+ [0x2374]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL RHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2374,
+ },
+ [0x2375]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL OMEGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2375,
+ },
+ [0x2376]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL ALPHA UNDERBAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2376,
+ },
+ [0x2377]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL EPSILON UNDERBAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2377,
+ },
+ [0x2378]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL IOTA UNDERBAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2378,
+ },
+ [0x2379]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL OMEGA UNDERBAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2379,
+ },
+ [0x237A]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL ALPHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x237A,
+ },
+ [0x237B]={
+ category="so",
+ description="NOT CHECK MARK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x237B,
+ },
+ [0x237C]={
+ category="sm",
+ description="RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x237C,
+ },
+ [0x237D]={
+ category="so",
+ description="SHOULDERED OPEN BOX",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x237D,
+ },
+ [0x237E]={
+ category="so",
+ description="BELL SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x237E,
+ },
+ [0x237F]={
+ category="so",
+ description="VERTICAL LINE WITH MIDDLE DOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x237F,
+ },
+ [0x2380]={
+ category="so",
+ description="INSERTION SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2380,
+ },
+ [0x2381]={
+ category="so",
+ description="CONTINUOUS UNDERLINE SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2381,
+ },
+ [0x2382]={
+ category="so",
+ description="DISCONTINUOUS UNDERLINE SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2382,
+ },
+ [0x2383]={
+ category="so",
+ description="EMPHASIS SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2383,
+ },
+ [0x2384]={
+ category="so",
+ description="COMPOSITION SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2384,
+ },
+ [0x2385]={
+ category="so",
+ description="WHITE SQUARE WITH CENTRE VERTICAL LINE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2385,
+ },
+ [0x2386]={
+ category="so",
+ description="ENTER SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2386,
+ },
+ [0x2387]={
+ category="so",
+ description="ALTERNATIVE KEY SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2387,
+ },
+ [0x2388]={
+ category="so",
+ description="HELM SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2388,
+ },
+ [0x2389]={
+ category="so",
+ description="CIRCLED HORIZONTAL BAR WITH NOTCH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2389,
+ },
+ [0x238A]={
+ category="so",
+ description="CIRCLED TRIANGLE DOWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x238A,
+ },
+ [0x238B]={
+ category="so",
+ description="BROKEN CIRCLE WITH NORTHWEST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x238B,
+ },
+ [0x238C]={
+ category="so",
+ description="UNDO SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x238C,
+ },
+ [0x238D]={
+ category="so",
+ description="MONOSTABLE SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x238D,
+ },
+ [0x238E]={
+ category="so",
+ description="HYSTERESIS SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x238E,
+ },
+ [0x238F]={
+ category="so",
+ description="OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x238F,
+ },
+ [0x2390]={
+ category="so",
+ description="OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2390,
+ },
+ [0x2391]={
+ category="so",
+ description="PASSIVE-PULL-DOWN-OUTPUT SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2391,
+ },
+ [0x2392]={
+ category="so",
+ description="PASSIVE-PULL-UP-OUTPUT SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2392,
+ },
+ [0x2393]={
+ category="so",
+ description="DIRECT CURRENT SYMBOL FORM TWO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2393,
+ },
+ [0x2394]={
+ category="so",
+ description="SOFTWARE-FUNCTION SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2394,
+ },
+ [0x2395]={
+ category="so",
+ description="APL FUNCTIONAL SYMBOL QUAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2395,
+ },
+ [0x2396]={
+ category="so",
+ description="DECIMAL SEPARATOR KEY SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2396,
+ },
+ [0x2397]={
+ category="so",
+ description="PREVIOUS PAGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2397,
+ },
+ [0x2398]={
+ category="so",
+ description="NEXT PAGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2398,
+ },
+ [0x2399]={
+ category="so",
+ description="PRINT SCREEN SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2399,
+ },
+ [0x239A]={
+ category="so",
+ description="CLEAR SCREEN SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x239A,
+ },
+ [0x239B]={
+ category="sm",
+ description="LEFT PARENTHESIS UPPER HOOK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x239B,
+ },
+ [0x239C]={
+ category="sm",
+ description="LEFT PARENTHESIS EXTENSION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x239C,
+ },
+ [0x239D]={
+ category="sm",
+ description="LEFT PARENTHESIS LOWER HOOK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x239D,
+ },
+ [0x239E]={
+ category="sm",
+ description="RIGHT PARENTHESIS UPPER HOOK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x239E,
+ },
+ [0x239F]={
+ category="sm",
+ description="RIGHT PARENTHESIS EXTENSION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x239F,
+ },
+ [0x23A0]={
+ category="sm",
+ description="RIGHT PARENTHESIS LOWER HOOK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A0,
+ },
+ [0x23A1]={
+ category="sm",
+ description="LEFT SQUARE BRACKET UPPER CORNER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A1,
+ },
+ [0x23A2]={
+ category="sm",
+ description="LEFT SQUARE BRACKET EXTENSION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A2,
+ },
+ [0x23A3]={
+ category="sm",
+ description="LEFT SQUARE BRACKET LOWER CORNER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A3,
+ },
+ [0x23A4]={
+ category="sm",
+ description="RIGHT SQUARE BRACKET UPPER CORNER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A4,
+ },
+ [0x23A5]={
+ category="sm",
+ description="RIGHT SQUARE BRACKET EXTENSION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A5,
+ },
+ [0x23A6]={
+ category="sm",
+ description="RIGHT SQUARE BRACKET LOWER CORNER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A6,
+ },
+ [0x23A7]={
+ category="sm",
+ description="LEFT CURLY BRACKET UPPER HOOK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A7,
+ },
+ [0x23A8]={
+ category="sm",
+ description="LEFT CURLY BRACKET MIDDLE PIECE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A8,
+ },
+ [0x23A9]={
+ category="sm",
+ description="LEFT CURLY BRACKET LOWER HOOK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23A9,
+ },
+ [0x23AA]={
+ category="sm",
+ description="CURLY BRACKET EXTENSION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23AA,
+ },
+ [0x23AB]={
+ category="sm",
+ description="RIGHT CURLY BRACKET UPPER HOOK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23AB,
+ },
+ [0x23AC]={
+ category="sm",
+ description="RIGHT CURLY BRACKET MIDDLE PIECE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23AC,
+ },
+ [0x23AD]={
+ category="sm",
+ description="RIGHT CURLY BRACKET LOWER HOOK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23AD,
+ },
+ [0x23AE]={
+ category="sm",
+ description="INTEGRAL EXTENSION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23AE,
+ },
+ [0x23AF]={
+ category="sm",
+ description="HORIZONTAL LINE EXTENSION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23AF,
+ },
+ [0x23B0]={
+ category="sm",
+ description="UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION",
+ direction="on",
+ linebreak="al",
+ mathclass="open",
+ mathname="lmoustache",
+ unicodeslot=0x23B0,
+ },
+ [0x23B1]={
+ category="sm",
+ description="UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION",
+ direction="on",
+ linebreak="al",
+ mathclass="close",
+ mathname="rmoustache",
+ unicodeslot=0x23B1,
+ },
+ [0x23B2]={
+ category="sm",
+ description="SUMMATION TOP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B2,
+ },
+ [0x23B3]={
+ category="sm",
+ description="SUMMATION BOTTOM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B3,
+ },
+ [0x23B4]={
+ category="so",
+ description="TOP SQUARE BRACKET",
+ direction="on",
+ linebreak="al",
+ mathclass="topaccent",
+ mathname="overbracket",
+ unicodeslot=0x23B4,
+ },
+ [0x23B5]={
+ category="so",
+ description="BOTTOM SQUARE BRACKET",
+ direction="on",
+ linebreak="al",
+ mathclass="botaccent",
+ mathname="underbracket",
+ unicodeslot=0x23B5,
+ },
+ [0x23B6]={
+ category="so",
+ description="BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B6,
+ },
+ [0x23B7]={
+ category="so",
+ description="RADICAL SYMBOL BOTTOM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B7,
+ },
+ [0x23B8]={
+ category="so",
+ description="LEFT VERTICAL BOX LINE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B8,
+ },
+ [0x23B9]={
+ category="so",
+ description="RIGHT VERTICAL BOX LINE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23B9,
+ },
+ [0x23BA]={
+ category="so",
+ description="HORIZONTAL SCAN LINE-0x0001",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23BA,
+ },
+ [0x23BB]={
+ category="so",
+ description="HORIZONTAL SCAN LINE-0x0003",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23BB,
+ },
+ [0x23BC]={
+ category="so",
+ description="HORIZONTAL SCAN LINE-0x0007",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23BC,
+ },
+ [0x23BD]={
+ category="so",
+ description="HORIZONTAL SCAN LINE-0x0009",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23BD,
+ },
+ [0x23BE]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23BE,
+ },
+ [0x23BF]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23BF,
+ },
+ [0x23C0]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C0,
+ },
+ [0x23C1]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C1,
+ },
+ [0x23C2]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C2,
+ },
+ [0x23C3]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C3,
+ },
+ [0x23C4]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C4,
+ },
+ [0x23C5]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C5,
+ },
+ [0x23C6]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C6,
+ },
+ [0x23C7]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C7,
+ },
+ [0x23C8]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C8,
+ },
+ [0x23C9]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23C9,
+ },
+ [0x23CA]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23CA,
+ },
+ [0x23CB]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23CB,
+ },
+ [0x23CC]={
+ category="so",
+ description="DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23CC,
+ },
+ [0x23CD]={
+ category="so",
+ description="SQUARE FOOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23CD,
+ },
+ [0x23CE]={
+ category="so",
+ description="RETURN SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23CE,
+ },
+ [0x23CF]={
+ category="so",
+ description="EJECT SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23CF,
+ },
+ [0x23D0]={
+ category="so",
+ description="VERTICAL LINE EXTENSION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D0,
+ },
+ [0x23D1]={
+ category="so",
+ description="METRICAL BREVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D1,
+ },
+ [0x23D2]={
+ category="so",
+ description="METRICAL LONG OVER SHORT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D2,
+ },
+ [0x23D3]={
+ category="so",
+ description="METRICAL SHORT OVER LONG",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D3,
+ },
+ [0x23D4]={
+ category="so",
+ description="METRICAL LONG OVER TWO SHORTS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D4,
+ },
+ [0x23D5]={
+ category="so",
+ description="METRICAL TWO SHORTS OVER LONG",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D5,
+ },
+ [0x23D6]={
+ category="so",
+ description="METRICAL TWO SHORTS JOINED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D6,
+ },
+ [0x23D7]={
+ category="so",
+ description="METRICAL TRISEME",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D7,
+ },
+ [0x23D8]={
+ category="so",
+ description="METRICAL TETRASEME",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D8,
+ },
+ [0x23D9]={
+ category="so",
+ description="METRICAL PENTASEME",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23D9,
+ },
+ [0x23DA]={
+ category="so",
+ description="EARTH GROUND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23DA,
+ },
+ [0x23DB]={
+ category="so",
+ description="FUSE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23DB,
+ },
+ [0x23DC]={
+ category="sm",
+ description="TOP PARENTHESIS",
+ direction="on",
+ linebreak="al",
+ mathclass="topaccent",
+ mathname="overparent",
+ unicodeslot=0x23DC,
+ },
+ [0x23DD]={
+ category="sm",
+ description="BOTTOM PARENTHESIS",
+ direction="on",
+ linebreak="al",
+ mathclass="botaccent",
+ mathname="underparent",
+ unicodeslot=0x23DD,
+ },
+ [0x23DE]={
+ category="sm",
+ description="TOP CURLY BRACKET",
+ direction="on",
+ linebreak="al",
+ mathclass="topaccent",
+ mathname="overbrace",
+ unicodeslot=0x23DE,
+ },
+ [0x23DF]={
+ category="sm",
+ description="BOTTOM CURLY BRACKET",
+ direction="on",
+ linebreak="al",
+ mathclass="botaccent",
+ mathname="underbrace",
+ unicodeslot=0x23DF,
+ },
+ [0x23E0]={
+ category="sm",
+ description="TOP TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="al",
+ mathclass="topaccent",
+ unicodeslot=0x23E0,
+ },
+ [0x23E1]={
+ category="sm",
+ description="BOTTOM TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="al",
+ mathclass="botaccent",
+ unicodeslot=0x23E1,
+ },
+ [0x23E2]={
+ category="so",
+ description="WHITE TRAPEZIUM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E2,
+ },
+ [0x23E3]={
+ category="so",
+ description="BENZENE RING WITH CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E3,
+ },
+ [0x23E4]={
+ category="so",
+ description="STRAIGHTNESS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E4,
+ },
+ [0x23E5]={
+ category="so",
+ description="FLATNESS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E5,
+ },
+ [0x23E6]={
+ category="so",
+ description="AC CURRENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E6,
+ },
+ [0x23E7]={
+ category="so",
+ description="ELECTRICAL INTERSECTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E7,
+ },
+ [0x23E8]={
+ category="so",
+ description="DECIMAL EXPONENT SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E8,
+ },
+ [0x23E9]={
+ category="so",
+ description="BLACK RIGHT-POINTING DOUBLE TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23E9,
+ },
+ [0x23EA]={
+ category="so",
+ description="BLACK LEFT-POINTING DOUBLE TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23EA,
+ },
+ [0x23EB]={
+ category="so",
+ description="BLACK UP-POINTING DOUBLE TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23EB,
+ },
+ [0x23EC]={
+ category="so",
+ description="BLACK DOWN-POINTING DOUBLE TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23EC,
+ },
+ [0x23ED]={
+ category="so",
+ description="BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23ED,
+ },
+ [0x23EE]={
+ category="so",
+ description="BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23EE,
+ },
+ [0x23EF]={
+ category="so",
+ description="BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x23EF,
+ },
+ [0x23F0]={
+ category="so",
+ description="ALARM CLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x23F0,
+ },
+ [0x23F1]={
+ category="so",
+ description="STOPWATCH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x23F1,
+ },
+ [0x23F2]={
+ category="so",
+ description="TIMER CLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x23F2,
+ },
+ [0x23F3]={
+ category="so",
+ description="HOURGLASS WITH FLOWING SAND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x23F3,
+ },
+ [0x2400]={
+ category="so",
+ description="SYMBOL FOR NULL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2400,
+ },
+ [0x2401]={
+ category="so",
+ description="SYMBOL FOR START OF HEADING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2401,
+ },
+ [0x2402]={
+ category="so",
+ description="SYMBOL FOR START OF TEXT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2402,
+ },
+ [0x2403]={
+ category="so",
+ description="SYMBOL FOR END OF TEXT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2403,
+ },
+ [0x2404]={
+ category="so",
+ description="SYMBOL FOR END OF TRANSMISSION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2404,
+ },
+ [0x2405]={
+ category="so",
+ description="SYMBOL FOR ENQUIRY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2405,
+ },
+ [0x2406]={
+ category="so",
+ description="SYMBOL FOR ACKNOWLEDGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2406,
+ },
+ [0x2407]={
+ category="so",
+ description="SYMBOL FOR BELL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2407,
+ },
+ [0x2408]={
+ category="so",
+ description="SYMBOL FOR BACKSPACE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2408,
+ },
+ [0x2409]={
+ category="so",
+ description="SYMBOL FOR HORIZONTAL TABULATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2409,
+ },
+ [0x240A]={
+ category="so",
+ description="SYMBOL FOR LINE FEED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x240A,
+ },
+ [0x240B]={
+ category="so",
+ description="SYMBOL FOR VERTICAL TABULATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x240B,
+ },
+ [0x240C]={
+ category="so",
+ description="SYMBOL FOR FORM FEED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x240C,
+ },
+ [0x240D]={
+ category="so",
+ description="SYMBOL FOR CARRIAGE RETURN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x240D,
+ },
+ [0x240E]={
+ category="so",
+ description="SYMBOL FOR SHIFT OUT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x240E,
+ },
+ [0x240F]={
+ category="so",
+ description="SYMBOL FOR SHIFT IN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x240F,
+ },
+ [0x2410]={
+ category="so",
+ description="SYMBOL FOR DATA LINK ESCAPE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2410,
+ },
+ [0x2411]={
+ category="so",
+ description="SYMBOL FOR DEVICE CONTROL ONE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2411,
+ },
+ [0x2412]={
+ category="so",
+ description="SYMBOL FOR DEVICE CONTROL TWO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2412,
+ },
+ [0x2413]={
+ category="so",
+ description="SYMBOL FOR DEVICE CONTROL THREE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2413,
+ },
+ [0x2414]={
+ category="so",
+ description="SYMBOL FOR DEVICE CONTROL FOUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2414,
+ },
+ [0x2415]={
+ category="so",
+ description="SYMBOL FOR NEGATIVE ACKNOWLEDGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2415,
+ },
+ [0x2416]={
+ category="so",
+ description="SYMBOL FOR SYNCHRONOUS IDLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2416,
+ },
+ [0x2417]={
+ category="so",
+ description="SYMBOL FOR END OF TRANSMISSION BLOCK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2417,
+ },
+ [0x2418]={
+ category="so",
+ description="SYMBOL FOR CANCEL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2418,
+ },
+ [0x2419]={
+ category="so",
+ description="SYMBOL FOR END OF MEDIUM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2419,
+ },
+ [0x241A]={
+ category="so",
+ description="SYMBOL FOR SUBSTITUTE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x241A,
+ },
+ [0x241B]={
+ category="so",
+ description="SYMBOL FOR ESCAPE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x241B,
+ },
+ [0x241C]={
+ category="so",
+ description="SYMBOL FOR FILE SEPARATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x241C,
+ },
+ [0x241D]={
+ category="so",
+ description="SYMBOL FOR GROUP SEPARATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x241D,
+ },
+ [0x241E]={
+ category="so",
+ description="SYMBOL FOR RECORD SEPARATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x241E,
+ },
+ [0x241F]={
+ category="so",
+ description="SYMBOL FOR UNIT SEPARATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x241F,
+ },
+ [0x2420]={
+ category="so",
+ description="SYMBOL FOR SPACE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2420,
+ },
+ [0x2421]={
+ category="so",
+ description="SYMBOL FOR DELETE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2421,
+ },
+ [0x2422]={
+ category="so",
+ description="BLANK SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2422,
+ },
+ [0x2423]={
+ adobename="blank",
+ category="so",
+ description="OPEN BOX",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2423,
+ },
+ [0x2424]={
+ category="so",
+ description="SYMBOL FOR NEWLINE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2424,
+ },
+ [0x2425]={
+ category="so",
+ description="SYMBOL FOR DELETE FORM TWO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2425,
+ },
+ [0x2426]={
+ category="so",
+ description="SYMBOL FOR SUBSTITUTE FORM TWO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2426,
+ },
+ [0x2440]={
+ category="so",
+ description="OCR HOOK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2440,
+ },
+ [0x2441]={
+ category="so",
+ description="OCR CHAIR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2441,
+ },
+ [0x2442]={
+ category="so",
+ description="OCR FORK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2442,
+ },
+ [0x2443]={
+ category="so",
+ description="OCR INVERTED FORK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2443,
+ },
+ [0x2444]={
+ category="so",
+ description="OCR BELT BUCKLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2444,
+ },
+ [0x2445]={
+ category="so",
+ description="OCR BOW TIE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2445,
+ },
+ [0x2446]={
+ category="so",
+ description="OCR BRANCH BANK IDENTIFICATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2446,
+ },
+ [0x2447]={
+ category="so",
+ description="OCR AMOUNT OF CHECK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2447,
+ },
+ [0x2448]={
+ category="so",
+ description="OCR DASH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2448,
+ },
+ [0x2449]={
+ category="so",
+ description="OCR CUSTOMER ACCOUNT NUMBER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2449,
+ },
+ [0x244A]={
+ category="so",
+ description="OCR DOUBLE BACKSLASH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x244A,
+ },
+ [0x2460]={
+ adobename="onecircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED DIGIT ONE",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0031 },
+ unicodeslot=0x2460,
+ },
+ [0x2461]={
+ adobename="twocircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED DIGIT TWO",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0032 },
+ unicodeslot=0x2461,
+ },
+ [0x2462]={
+ adobename="threecircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED DIGIT THREE",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0033 },
+ unicodeslot=0x2462,
+ },
+ [0x2463]={
+ adobename="fourcircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED DIGIT FOUR",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0034 },
+ unicodeslot=0x2463,
+ },
+ [0x2464]={
+ adobename="fivecircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED DIGIT FIVE",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0035 },
+ unicodeslot=0x2464,
+ },
+ [0x2465]={
+ adobename="sixcircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED DIGIT SIX",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0036 },
+ unicodeslot=0x2465,
+ },
+ [0x2466]={
+ adobename="sevencircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED DIGIT SEVEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0037 },
+ unicodeslot=0x2466,
+ },
+ [0x2467]={
+ adobename="eightcircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED DIGIT EIGHT",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0038 },
+ unicodeslot=0x2467,
+ },
+ [0x2468]={
+ adobename="ninecircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED DIGIT NINE",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0039 },
+ unicodeslot=0x2468,
+ },
+ [0x2469]={
+ adobename="tencircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED NUMBER TEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0031, 0x0030 },
+ unicodeslot=0x2469,
+ },
+ [0x246A]={
+ adobename="elevencircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED NUMBER ELEVEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0031, 0x0031 },
+ unicodeslot=0x246A,
+ },
+ [0x246B]={
+ adobename="twelvecircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED NUMBER TWELVE",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0031, 0x0032 },
+ unicodeslot=0x246B,
+ },
+ [0x246C]={
+ adobename="thirteencircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED NUMBER THIRTEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0031, 0x0033 },
+ unicodeslot=0x246C,
+ },
+ [0x246D]={
+ adobename="fourteencircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED NUMBER FOURTEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0031, 0x0034 },
+ unicodeslot=0x246D,
+ },
+ [0x246E]={
+ adobename="fifteencircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED NUMBER FIFTEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0031, 0x0035 },
+ unicodeslot=0x246E,
+ },
+ [0x246F]={
+ adobename="sixteencircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED NUMBER SIXTEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0031, 0x0036 },
+ unicodeslot=0x246F,
+ },
+ [0x2470]={
+ adobename="seventeencircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED NUMBER SEVENTEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0031, 0x0037 },
+ unicodeslot=0x2470,
+ },
+ [0x2471]={
+ adobename="eighteencircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED NUMBER EIGHTEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0031, 0x0038 },
+ unicodeslot=0x2471,
+ },
+ [0x2472]={
+ adobename="nineteencircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED NUMBER NINETEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0031, 0x0039 },
+ unicodeslot=0x2472,
+ },
+ [0x2473]={
+ adobename="twentycircle",
+ category="no",
+ cjkwd="a",
+ description="CIRCLED NUMBER TWENTY",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0032, 0x0030 },
+ unicodeslot=0x2473,
+ },
+ [0x2474]={
+ adobename="oneparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED DIGIT ONE",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0031, 0x0029 },
+ unicodeslot=0x2474,
+ },
+ [0x2475]={
+ adobename="twoparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED DIGIT TWO",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0032, 0x0029 },
+ unicodeslot=0x2475,
+ },
+ [0x2476]={
+ adobename="threeparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED DIGIT THREE",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0033, 0x0029 },
+ unicodeslot=0x2476,
+ },
+ [0x2477]={
+ adobename="fourparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED DIGIT FOUR",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0034, 0x0029 },
+ unicodeslot=0x2477,
+ },
+ [0x2478]={
+ adobename="fiveparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED DIGIT FIVE",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0035, 0x0029 },
+ unicodeslot=0x2478,
+ },
+ [0x2479]={
+ adobename="sixparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED DIGIT SIX",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0036, 0x0029 },
+ unicodeslot=0x2479,
+ },
+ [0x247A]={
+ adobename="sevenparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED DIGIT SEVEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0037, 0x0029 },
+ unicodeslot=0x247A,
+ },
+ [0x247B]={
+ adobename="eightparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED DIGIT EIGHT",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0038, 0x0029 },
+ unicodeslot=0x247B,
+ },
+ [0x247C]={
+ adobename="nineparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED DIGIT NINE",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0039, 0x0029 },
+ unicodeslot=0x247C,
+ },
+ [0x247D]={
+ adobename="tenparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED NUMBER TEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0031, 0x0030, 0x0029 },
+ unicodeslot=0x247D,
+ },
+ [0x247E]={
+ adobename="elevenparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED NUMBER ELEVEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0031, 0x0031, 0x0029 },
+ unicodeslot=0x247E,
+ },
+ [0x247F]={
+ adobename="twelveparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED NUMBER TWELVE",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0031, 0x0032, 0x0029 },
+ unicodeslot=0x247F,
+ },
+ [0x2480]={
+ adobename="thirteenparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED NUMBER THIRTEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0031, 0x0033, 0x0029 },
+ unicodeslot=0x2480,
+ },
+ [0x2481]={
+ adobename="fourteenparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED NUMBER FOURTEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0031, 0x0034, 0x0029 },
+ unicodeslot=0x2481,
+ },
+ [0x2482]={
+ adobename="fifteenparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED NUMBER FIFTEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0031, 0x0035, 0x0029 },
+ unicodeslot=0x2482,
+ },
+ [0x2483]={
+ adobename="sixteenparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED NUMBER SIXTEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0031, 0x0036, 0x0029 },
+ unicodeslot=0x2483,
+ },
+ [0x2484]={
+ adobename="seventeenparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED NUMBER SEVENTEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0031, 0x0037, 0x0029 },
+ unicodeslot=0x2484,
+ },
+ [0x2485]={
+ adobename="eighteenparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED NUMBER EIGHTEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0031, 0x0038, 0x0029 },
+ unicodeslot=0x2485,
+ },
+ [0x2486]={
+ adobename="nineteenparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED NUMBER NINETEEN",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0031, 0x0039, 0x0029 },
+ unicodeslot=0x2486,
+ },
+ [0x2487]={
+ adobename="twentyparen",
+ category="no",
+ cjkwd="a",
+ description="PARENTHESIZED NUMBER TWENTY",
+ direction="on",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0032, 0x0030, 0x0029 },
+ unicodeslot=0x2487,
+ },
+ [0x2488]={
+ adobename="oneperiod",
+ category="no",
+ cjkwd="a",
+ description="DIGIT ONE FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0031, 0x002E },
+ unicodeslot=0x2488,
+ },
+ [0x2489]={
+ adobename="twoperiod",
+ category="no",
+ cjkwd="a",
+ description="DIGIT TWO FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0032, 0x002E },
+ unicodeslot=0x2489,
+ },
+ [0x248A]={
+ adobename="threeperiod",
+ category="no",
+ cjkwd="a",
+ description="DIGIT THREE FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0033, 0x002E },
+ unicodeslot=0x248A,
+ },
+ [0x248B]={
+ adobename="fourperiod",
+ category="no",
+ cjkwd="a",
+ description="DIGIT FOUR FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0034, 0x002E },
+ unicodeslot=0x248B,
+ },
+ [0x248C]={
+ adobename="fiveperiod",
+ category="no",
+ cjkwd="a",
+ description="DIGIT FIVE FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0035, 0x002E },
+ unicodeslot=0x248C,
+ },
+ [0x248D]={
+ adobename="sixperiod",
+ category="no",
+ cjkwd="a",
+ description="DIGIT SIX FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0036, 0x002E },
+ unicodeslot=0x248D,
+ },
+ [0x248E]={
+ adobename="sevenperiod",
+ category="no",
+ cjkwd="a",
+ description="DIGIT SEVEN FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0037, 0x002E },
+ unicodeslot=0x248E,
+ },
+ [0x248F]={
+ adobename="eightperiod",
+ category="no",
+ cjkwd="a",
+ description="DIGIT EIGHT FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0038, 0x002E },
+ unicodeslot=0x248F,
+ },
+ [0x2490]={
+ adobename="nineperiod",
+ category="no",
+ cjkwd="a",
+ description="DIGIT NINE FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0039, 0x002E },
+ unicodeslot=0x2490,
+ },
+ [0x2491]={
+ adobename="tenperiod",
+ category="no",
+ cjkwd="a",
+ description="NUMBER TEN FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0031, 0x0030, 0x002E },
+ unicodeslot=0x2491,
+ },
+ [0x2492]={
+ adobename="elevenperiod",
+ category="no",
+ cjkwd="a",
+ description="NUMBER ELEVEN FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0031, 0x0031, 0x002E },
+ unicodeslot=0x2492,
+ },
+ [0x2493]={
+ adobename="twelveperiod",
+ category="no",
+ cjkwd="a",
+ description="NUMBER TWELVE FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0031, 0x0032, 0x002E },
+ unicodeslot=0x2493,
+ },
+ [0x2494]={
+ adobename="thirteenperiod",
+ category="no",
+ cjkwd="a",
+ description="NUMBER THIRTEEN FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0031, 0x0033, 0x002E },
+ unicodeslot=0x2494,
+ },
+ [0x2495]={
+ adobename="fourteenperiod",
+ category="no",
+ cjkwd="a",
+ description="NUMBER FOURTEEN FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0031, 0x0034, 0x002E },
+ unicodeslot=0x2495,
+ },
+ [0x2496]={
+ adobename="fifteenperiod",
+ category="no",
+ cjkwd="a",
+ description="NUMBER FIFTEEN FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0031, 0x0035, 0x002E },
+ unicodeslot=0x2496,
+ },
+ [0x2497]={
+ adobename="sixteenperiod",
+ category="no",
+ cjkwd="a",
+ description="NUMBER SIXTEEN FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0031, 0x0036, 0x002E },
+ unicodeslot=0x2497,
+ },
+ [0x2498]={
+ adobename="seventeenperiod",
+ category="no",
+ cjkwd="a",
+ description="NUMBER SEVENTEEN FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0031, 0x0037, 0x002E },
+ unicodeslot=0x2498,
+ },
+ [0x2499]={
+ adobename="eighteenperiod",
+ category="no",
+ cjkwd="a",
+ description="NUMBER EIGHTEEN FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0031, 0x0038, 0x002E },
+ unicodeslot=0x2499,
+ },
+ [0x249A]={
+ adobename="nineteenperiod",
+ category="no",
+ cjkwd="a",
+ description="NUMBER NINETEEN FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0031, 0x0039, 0x002E },
+ unicodeslot=0x249A,
+ },
+ [0x249B]={
+ adobename="twentyperiod",
+ category="no",
+ cjkwd="a",
+ description="NUMBER TWENTY FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0032, 0x0030, 0x002E },
+ unicodeslot=0x249B,
+ },
+ [0x249C]={
+ adobename="aparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER A",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0061, 0x0029 },
+ unicodeslot=0x249C,
+ },
+ [0x249D]={
+ adobename="bparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER B",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0062, 0x0029 },
+ unicodeslot=0x249D,
+ },
+ [0x249E]={
+ adobename="cparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER C",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0063, 0x0029 },
+ unicodeslot=0x249E,
+ },
+ [0x249F]={
+ adobename="dparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER D",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0064, 0x0029 },
+ unicodeslot=0x249F,
+ },
+ [0x24A0]={
+ adobename="eparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER E",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0065, 0x0029 },
+ unicodeslot=0x24A0,
+ },
+ [0x24A1]={
+ adobename="fparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER F",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0066, 0x0029 },
+ unicodeslot=0x24A1,
+ },
+ [0x24A2]={
+ adobename="gparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER G",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0067, 0x0029 },
+ unicodeslot=0x24A2,
+ },
+ [0x24A3]={
+ adobename="hparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER H",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0068, 0x0029 },
+ unicodeslot=0x24A3,
+ },
+ [0x24A4]={
+ adobename="iparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER I",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0069, 0x0029 },
+ unicodeslot=0x24A4,
+ },
+ [0x24A5]={
+ adobename="jparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER J",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x006A, 0x0029 },
+ unicodeslot=0x24A5,
+ },
+ [0x24A6]={
+ adobename="kparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER K",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x006B, 0x0029 },
+ unicodeslot=0x24A6,
+ },
+ [0x24A7]={
+ adobename="lparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER L",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x006C, 0x0029 },
+ unicodeslot=0x24A7,
+ },
+ [0x24A8]={
+ adobename="mparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER M",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x006D, 0x0029 },
+ unicodeslot=0x24A8,
+ },
+ [0x24A9]={
+ adobename="nparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER N",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x006E, 0x0029 },
+ unicodeslot=0x24A9,
+ },
+ [0x24AA]={
+ adobename="oparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER O",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x006F, 0x0029 },
+ unicodeslot=0x24AA,
+ },
+ [0x24AB]={
+ adobename="pparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER P",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0070, 0x0029 },
+ unicodeslot=0x24AB,
+ },
+ [0x24AC]={
+ adobename="qparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER Q",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0071, 0x0029 },
+ unicodeslot=0x24AC,
+ },
+ [0x24AD]={
+ adobename="rparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER R",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0072, 0x0029 },
+ unicodeslot=0x24AD,
+ },
+ [0x24AE]={
+ adobename="sparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER S",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0073, 0x0029 },
+ unicodeslot=0x24AE,
+ },
+ [0x24AF]={
+ adobename="tparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER T",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0074, 0x0029 },
+ unicodeslot=0x24AF,
+ },
+ [0x24B0]={
+ adobename="uparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER U",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0075, 0x0029 },
+ unicodeslot=0x24B0,
+ },
+ [0x24B1]={
+ adobename="vparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER V",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0076, 0x0029 },
+ unicodeslot=0x24B1,
+ },
+ [0x24B2]={
+ adobename="wparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER W",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0077, 0x0029 },
+ unicodeslot=0x24B2,
+ },
+ [0x24B3]={
+ adobename="xparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER X",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0078, 0x0029 },
+ unicodeslot=0x24B3,
+ },
+ [0x24B4]={
+ adobename="yparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER Y",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0079, 0x0029 },
+ unicodeslot=0x24B4,
+ },
+ [0x24B5]={
+ adobename="zparen",
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN SMALL LETTER Z",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x007A, 0x0029 },
+ unicodeslot=0x24B5,
+ },
+ [0x24B6]={
+ adobename="Acircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER A",
+ direction="l",
+ lccode=0x24D0,
+ linebreak="ai",
+ specials={ "circle", 0x0041 },
+ unicodeslot=0x24B6,
+ },
+ [0x24B7]={
+ adobename="Bcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER B",
+ direction="l",
+ lccode=0x24D1,
+ linebreak="ai",
+ specials={ "circle", 0x0042 },
+ unicodeslot=0x24B7,
+ },
+ [0x24B8]={
+ adobename="Ccircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER C",
+ direction="l",
+ lccode=0x24D2,
+ linebreak="ai",
+ specials={ "circle", 0x0043 },
+ unicodeslot=0x24B8,
+ },
+ [0x24B9]={
+ adobename="Dcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER D",
+ direction="l",
+ lccode=0x24D3,
+ linebreak="ai",
+ specials={ "circle", 0x0044 },
+ unicodeslot=0x24B9,
+ },
+ [0x24BA]={
+ adobename="Ecircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER E",
+ direction="l",
+ lccode=0x24D4,
+ linebreak="ai",
+ specials={ "circle", 0x0045 },
+ unicodeslot=0x24BA,
+ },
+ [0x24BB]={
+ adobename="Fcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER F",
+ direction="l",
+ lccode=0x24D5,
+ linebreak="ai",
+ specials={ "circle", 0x0046 },
+ unicodeslot=0x24BB,
+ },
+ [0x24BC]={
+ adobename="Gcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER G",
+ direction="l",
+ lccode=0x24D6,
+ linebreak="ai",
+ specials={ "circle", 0x0047 },
+ unicodeslot=0x24BC,
+ },
+ [0x24BD]={
+ adobename="Hcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER H",
+ direction="l",
+ lccode=0x24D7,
+ linebreak="ai",
+ specials={ "circle", 0x0048 },
+ unicodeslot=0x24BD,
+ },
+ [0x24BE]={
+ adobename="Icircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER I",
+ direction="l",
+ lccode=0x24D8,
+ linebreak="ai",
+ specials={ "circle", 0x0049 },
+ unicodeslot=0x24BE,
+ },
+ [0x24BF]={
+ adobename="Jcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER J",
+ direction="l",
+ lccode=0x24D9,
+ linebreak="ai",
+ specials={ "circle", 0x004A },
+ unicodeslot=0x24BF,
+ },
+ [0x24C0]={
+ adobename="Kcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER K",
+ direction="l",
+ lccode=0x24DA,
+ linebreak="ai",
+ specials={ "circle", 0x004B },
+ unicodeslot=0x24C0,
+ },
+ [0x24C1]={
+ adobename="Lcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER L",
+ direction="l",
+ lccode=0x24DB,
+ linebreak="ai",
+ specials={ "circle", 0x004C },
+ unicodeslot=0x24C1,
+ },
+ [0x24C2]={
+ adobename="Mcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER M",
+ direction="l",
+ lccode=0x24DC,
+ linebreak="ai",
+ specials={ "circle", 0x004D },
+ unicodeslot=0x24C2,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x24C3]={
+ adobename="Ncircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER N",
+ direction="l",
+ lccode=0x24DD,
+ linebreak="ai",
+ specials={ "circle", 0x004E },
+ unicodeslot=0x24C3,
+ },
+ [0x24C4]={
+ adobename="Ocircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER O",
+ direction="l",
+ lccode=0x24DE,
+ linebreak="ai",
+ specials={ "circle", 0x004F },
+ unicodeslot=0x24C4,
+ },
+ [0x24C5]={
+ adobename="Pcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER P",
+ direction="l",
+ lccode=0x24DF,
+ linebreak="ai",
+ specials={ "circle", 0x0050 },
+ unicodeslot=0x24C5,
+ },
+ [0x24C6]={
+ adobename="Qcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER Q",
+ direction="l",
+ lccode=0x24E0,
+ linebreak="ai",
+ specials={ "circle", 0x0051 },
+ unicodeslot=0x24C6,
+ },
+ [0x24C7]={
+ adobename="Rcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER R",
+ direction="l",
+ lccode=0x24E1,
+ linebreak="ai",
+ mathclass="ordinary",
+ mathname="circledR",
+ specials={ "circle", 0x0052 },
+ unicodeslot=0x24C7,
+ },
+ [0x24C8]={
+ adobename="Scircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER S",
+ direction="l",
+ lccode=0x24E2,
+ linebreak="ai",
+ mathclass="ordinary",
+ mathname="circledS",
+ specials={ "circle", 0x0053 },
+ unicodeslot=0x24C8,
+ },
+ [0x24C9]={
+ adobename="Tcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER T",
+ direction="l",
+ lccode=0x24E3,
+ linebreak="ai",
+ specials={ "circle", 0x0054 },
+ unicodeslot=0x24C9,
+ },
+ [0x24CA]={
+ adobename="Ucircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER U",
+ direction="l",
+ lccode=0x24E4,
+ linebreak="ai",
+ specials={ "circle", 0x0055 },
+ unicodeslot=0x24CA,
+ },
+ [0x24CB]={
+ adobename="Vcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER V",
+ direction="l",
+ lccode=0x24E5,
+ linebreak="ai",
+ specials={ "circle", 0x0056 },
+ unicodeslot=0x24CB,
+ },
+ [0x24CC]={
+ adobename="Wcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER W",
+ direction="l",
+ lccode=0x24E6,
+ linebreak="ai",
+ specials={ "circle", 0x0057 },
+ unicodeslot=0x24CC,
+ },
+ [0x24CD]={
+ adobename="Xcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER X",
+ direction="l",
+ lccode=0x24E7,
+ linebreak="ai",
+ specials={ "circle", 0x0058 },
+ unicodeslot=0x24CD,
+ },
+ [0x24CE]={
+ adobename="Ycircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER Y",
+ direction="l",
+ lccode=0x24E8,
+ linebreak="ai",
+ specials={ "circle", 0x0059 },
+ unicodeslot=0x24CE,
+ },
+ [0x24CF]={
+ adobename="Zcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN CAPITAL LETTER Z",
+ direction="l",
+ lccode=0x24E9,
+ linebreak="ai",
+ specials={ "circle", 0x005A },
+ unicodeslot=0x24CF,
+ },
+ [0x24D0]={
+ adobename="acircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER A",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0061 },
+ uccode=0x24B6,
+ unicodeslot=0x24D0,
+ },
+ [0x24D1]={
+ adobename="bcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER B",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0062 },
+ uccode=0x24B7,
+ unicodeslot=0x24D1,
+ },
+ [0x24D2]={
+ adobename="ccircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER C",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0063 },
+ uccode=0x24B8,
+ unicodeslot=0x24D2,
+ },
+ [0x24D3]={
+ adobename="dcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER D",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0064 },
+ uccode=0x24B9,
+ unicodeslot=0x24D3,
+ },
+ [0x24D4]={
+ adobename="ecircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER E",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0065 },
+ uccode=0x24BA,
+ unicodeslot=0x24D4,
+ },
+ [0x24D5]={
+ adobename="fcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER F",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0066 },
+ uccode=0x24BB,
+ unicodeslot=0x24D5,
+ },
+ [0x24D6]={
+ adobename="gcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER G",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0067 },
+ uccode=0x24BC,
+ unicodeslot=0x24D6,
+ },
+ [0x24D7]={
+ adobename="hcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER H",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0068 },
+ uccode=0x24BD,
+ unicodeslot=0x24D7,
+ },
+ [0x24D8]={
+ adobename="icircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER I",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0069 },
+ uccode=0x24BE,
+ unicodeslot=0x24D8,
+ },
+ [0x24D9]={
+ adobename="jcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER J",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x006A },
+ uccode=0x24BF,
+ unicodeslot=0x24D9,
+ },
+ [0x24DA]={
+ adobename="kcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER K",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x006B },
+ uccode=0x24C0,
+ unicodeslot=0x24DA,
+ },
+ [0x24DB]={
+ adobename="lcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER L",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x006C },
+ uccode=0x24C1,
+ unicodeslot=0x24DB,
+ },
+ [0x24DC]={
+ adobename="mcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER M",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x006D },
+ uccode=0x24C2,
+ unicodeslot=0x24DC,
+ },
+ [0x24DD]={
+ adobename="ncircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER N",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x006E },
+ uccode=0x24C3,
+ unicodeslot=0x24DD,
+ },
+ [0x24DE]={
+ adobename="ocircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER O",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x006F },
+ uccode=0x24C4,
+ unicodeslot=0x24DE,
+ },
+ [0x24DF]={
+ adobename="pcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER P",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0070 },
+ uccode=0x24C5,
+ unicodeslot=0x24DF,
+ },
+ [0x24E0]={
+ adobename="qcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER Q",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0071 },
+ uccode=0x24C6,
+ unicodeslot=0x24E0,
+ },
+ [0x24E1]={
+ adobename="rcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER R",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0072 },
+ uccode=0x24C7,
+ unicodeslot=0x24E1,
+ },
+ [0x24E2]={
+ adobename="scircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER S",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0073 },
+ uccode=0x24C8,
+ unicodeslot=0x24E2,
+ },
+ [0x24E3]={
+ adobename="tcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER T",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0074 },
+ uccode=0x24C9,
+ unicodeslot=0x24E3,
+ },
+ [0x24E4]={
+ adobename="ucircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER U",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0075 },
+ uccode=0x24CA,
+ unicodeslot=0x24E4,
+ },
+ [0x24E5]={
+ adobename="vcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER V",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0076 },
+ uccode=0x24CB,
+ unicodeslot=0x24E5,
+ },
+ [0x24E6]={
+ adobename="wcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER W",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0077 },
+ uccode=0x24CC,
+ unicodeslot=0x24E6,
+ },
+ [0x24E7]={
+ adobename="xcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER X",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0078 },
+ uccode=0x24CD,
+ unicodeslot=0x24E7,
+ },
+ [0x24E8]={
+ adobename="ycircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER Y",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0079 },
+ uccode=0x24CE,
+ unicodeslot=0x24E8,
+ },
+ [0x24E9]={
+ adobename="zcircle",
+ category="so",
+ cjkwd="a",
+ description="CIRCLED LATIN SMALL LETTER Z",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x007A },
+ uccode=0x24CF,
+ unicodeslot=0x24E9,
+ },
+ [0x24EA]={
+ category="no",
+ description="CIRCLED DIGIT ZERO",
+ direction="on",
+ linebreak="ai",
+ specials={ "circle", 0x0030 },
+ unicodeslot=0x24EA,
+ },
+ [0x24EB]={
+ category="no",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED NUMBER ELEVEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24EB,
+ },
+ [0x24EC]={
+ category="no",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED NUMBER TWELVE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24EC,
+ },
+ [0x24ED]={
+ category="no",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED NUMBER THIRTEEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24ED,
+ },
+ [0x24EE]={
+ category="no",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED NUMBER FOURTEEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24EE,
+ },
+ [0x24EF]={
+ category="no",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED NUMBER FIFTEEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24EF,
+ },
+ [0x24F0]={
+ category="no",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED NUMBER SIXTEEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F0,
+ },
+ [0x24F1]={
+ category="no",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED NUMBER SEVENTEEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F1,
+ },
+ [0x24F2]={
+ category="no",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED NUMBER EIGHTEEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F2,
+ },
+ [0x24F3]={
+ category="no",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED NUMBER NINETEEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F3,
+ },
+ [0x24F4]={
+ category="no",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED NUMBER TWENTY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F4,
+ },
+ [0x24F5]={
+ category="no",
+ cjkwd="a",
+ description="DOUBLE CIRCLED DIGIT ONE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F5,
+ },
+ [0x24F6]={
+ category="no",
+ cjkwd="a",
+ description="DOUBLE CIRCLED DIGIT TWO",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F6,
+ },
+ [0x24F7]={
+ category="no",
+ cjkwd="a",
+ description="DOUBLE CIRCLED DIGIT THREE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F7,
+ },
+ [0x24F8]={
+ category="no",
+ cjkwd="a",
+ description="DOUBLE CIRCLED DIGIT FOUR",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F8,
+ },
+ [0x24F9]={
+ category="no",
+ cjkwd="a",
+ description="DOUBLE CIRCLED DIGIT FIVE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24F9,
+ },
+ [0x24FA]={
+ category="no",
+ cjkwd="a",
+ description="DOUBLE CIRCLED DIGIT SIX",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24FA,
+ },
+ [0x24FB]={
+ category="no",
+ cjkwd="a",
+ description="DOUBLE CIRCLED DIGIT SEVEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24FB,
+ },
+ [0x24FC]={
+ category="no",
+ cjkwd="a",
+ description="DOUBLE CIRCLED DIGIT EIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24FC,
+ },
+ [0x24FD]={
+ category="no",
+ cjkwd="a",
+ description="DOUBLE CIRCLED DIGIT NINE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24FD,
+ },
+ [0x24FE]={
+ category="no",
+ cjkwd="a",
+ description="DOUBLE CIRCLED NUMBER TEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x24FE,
+ },
+ [0x24FF]={
+ category="no",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED DIGIT ZERO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x24FF,
+ },
+ [0x2500]={
+ adobename="SF100000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2500,
+ },
+ [0x2501]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2501,
+ },
+ [0x2502]={
+ adobename="SF110000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT VERTICAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2502,
+ },
+ [0x2503]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY VERTICAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2503,
+ },
+ [0x2504]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2504,
+ },
+ [0x2505]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2505,
+ },
+ [0x2506]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2506,
+ },
+ [0x2507]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2507,
+ },
+ [0x2508]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2508,
+ },
+ [0x2509]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2509,
+ },
+ [0x250A]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x250A,
+ },
+ [0x250B]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x250B,
+ },
+ [0x250C]={
+ adobename="SF010000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT DOWN AND RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x250C,
+ },
+ [0x250D]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x250D,
+ },
+ [0x250E]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x250E,
+ },
+ [0x250F]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY DOWN AND RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x250F,
+ },
+ [0x2510]={
+ adobename="SF030000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT DOWN AND LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2510,
+ },
+ [0x2511]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2511,
+ },
+ [0x2512]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2512,
+ },
+ [0x2513]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY DOWN AND LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2513,
+ },
+ [0x2514]={
+ adobename="SF020000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT UP AND RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2514,
+ },
+ [0x2515]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP LIGHT AND RIGHT HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2515,
+ },
+ [0x2516]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP HEAVY AND RIGHT LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2516,
+ },
+ [0x2517]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY UP AND RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2517,
+ },
+ [0x2518]={
+ adobename="SF040000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT UP AND LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2518,
+ },
+ [0x2519]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP LIGHT AND LEFT HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2519,
+ },
+ [0x251A]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP HEAVY AND LEFT LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x251A,
+ },
+ [0x251B]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY UP AND LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x251B,
+ },
+ [0x251C]={
+ adobename="SF080000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT VERTICAL AND RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x251C,
+ },
+ [0x251D]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x251D,
+ },
+ [0x251E]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x251E,
+ },
+ [0x251F]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x251F,
+ },
+ [0x2520]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2520,
+ },
+ [0x2521]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2521,
+ },
+ [0x2522]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2522,
+ },
+ [0x2523]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY VERTICAL AND RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2523,
+ },
+ [0x2524]={
+ adobename="SF090000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT VERTICAL AND LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2524,
+ },
+ [0x2525]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2525,
+ },
+ [0x2526]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2526,
+ },
+ [0x2527]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2527,
+ },
+ [0x2528]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2528,
+ },
+ [0x2529]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2529,
+ },
+ [0x252A]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x252A,
+ },
+ [0x252B]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY VERTICAL AND LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x252B,
+ },
+ [0x252C]={
+ adobename="SF060000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT DOWN AND HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x252C,
+ },
+ [0x252D]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x252D,
+ },
+ [0x252E]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x252E,
+ },
+ [0x252F]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x252F,
+ },
+ [0x2530]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2530,
+ },
+ [0x2531]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2531,
+ },
+ [0x2532]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2532,
+ },
+ [0x2533]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY DOWN AND HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2533,
+ },
+ [0x2534]={
+ adobename="SF070000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT UP AND HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2534,
+ },
+ [0x2535]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2535,
+ },
+ [0x2536]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2536,
+ },
+ [0x2537]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2537,
+ },
+ [0x2538]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2538,
+ },
+ [0x2539]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2539,
+ },
+ [0x253A]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x253A,
+ },
+ [0x253B]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY UP AND HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x253B,
+ },
+ [0x253C]={
+ adobename="SF050000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x253C,
+ },
+ [0x253D]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x253D,
+ },
+ [0x253E]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x253E,
+ },
+ [0x253F]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x253F,
+ },
+ [0x2540]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2540,
+ },
+ [0x2541]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2541,
+ },
+ [0x2542]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2542,
+ },
+ [0x2543]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2543,
+ },
+ [0x2544]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2544,
+ },
+ [0x2545]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2545,
+ },
+ [0x2546]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2546,
+ },
+ [0x2547]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2547,
+ },
+ [0x2548]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2548,
+ },
+ [0x2549]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2549,
+ },
+ [0x254A]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x254A,
+ },
+ [0x254B]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x254B,
+ },
+ [0x254C]={
+ category="so",
+ description="BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x254C,
+ },
+ [0x254D]={
+ category="so",
+ description="BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x254D,
+ },
+ [0x254E]={
+ category="so",
+ description="BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x254E,
+ },
+ [0x254F]={
+ category="so",
+ description="BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x254F,
+ },
+ [0x2550]={
+ adobename="SF430000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOUBLE HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2550,
+ },
+ [0x2551]={
+ adobename="SF240000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOUBLE VERTICAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2551,
+ },
+ [0x2552]={
+ adobename="SF510000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2552,
+ },
+ [0x2553]={
+ adobename="SF520000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2553,
+ },
+ [0x2554]={
+ adobename="SF390000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOUBLE DOWN AND RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2554,
+ },
+ [0x2555]={
+ adobename="SF220000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2555,
+ },
+ [0x2556]={
+ adobename="SF210000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2556,
+ },
+ [0x2557]={
+ adobename="SF250000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOUBLE DOWN AND LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2557,
+ },
+ [0x2558]={
+ adobename="SF500000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2558,
+ },
+ [0x2559]={
+ adobename="SF490000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2559,
+ },
+ [0x255A]={
+ adobename="SF380000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOUBLE UP AND RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x255A,
+ },
+ [0x255B]={
+ adobename="SF280000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP SINGLE AND LEFT DOUBLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x255B,
+ },
+ [0x255C]={
+ adobename="SF270000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP DOUBLE AND LEFT SINGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x255C,
+ },
+ [0x255D]={
+ adobename="SF260000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOUBLE UP AND LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x255D,
+ },
+ [0x255E]={
+ adobename="SF360000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x255E,
+ },
+ [0x255F]={
+ adobename="SF370000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x255F,
+ },
+ [0x2560]={
+ adobename="SF420000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOUBLE VERTICAL AND RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2560,
+ },
+ [0x2561]={
+ adobename="SF190000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2561,
+ },
+ [0x2562]={
+ adobename="SF200000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2562,
+ },
+ [0x2563]={
+ adobename="SF230000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOUBLE VERTICAL AND LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2563,
+ },
+ [0x2564]={
+ adobename="SF470000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2564,
+ },
+ [0x2565]={
+ adobename="SF480000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2565,
+ },
+ [0x2566]={
+ adobename="SF410000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2566,
+ },
+ [0x2567]={
+ adobename="SF450000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2567,
+ },
+ [0x2568]={
+ adobename="SF460000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2568,
+ },
+ [0x2569]={
+ adobename="SF400000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOUBLE UP AND HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2569,
+ },
+ [0x256A]={
+ adobename="SF540000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x256A,
+ },
+ [0x256B]={
+ adobename="SF530000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x256B,
+ },
+ [0x256C]={
+ adobename="SF440000",
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x256C,
+ },
+ [0x256D]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT ARC DOWN AND RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x256D,
+ },
+ [0x256E]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT ARC DOWN AND LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x256E,
+ },
+ [0x256F]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT ARC UP AND LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x256F,
+ },
+ [0x2570]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT ARC UP AND RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2570,
+ },
+ [0x2571]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2571,
+ },
+ [0x2572]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2572,
+ },
+ [0x2573]={
+ category="so",
+ cjkwd="a",
+ description="BOX DRAWINGS LIGHT DIAGONAL CROSS",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2573,
+ },
+ [0x2574]={
+ category="so",
+ description="BOX DRAWINGS LIGHT LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2574,
+ },
+ [0x2575]={
+ category="so",
+ description="BOX DRAWINGS LIGHT UP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2575,
+ },
+ [0x2576]={
+ category="so",
+ description="BOX DRAWINGS LIGHT RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2576,
+ },
+ [0x2577]={
+ category="so",
+ description="BOX DRAWINGS LIGHT DOWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2577,
+ },
+ [0x2578]={
+ category="so",
+ description="BOX DRAWINGS HEAVY LEFT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2578,
+ },
+ [0x2579]={
+ category="so",
+ description="BOX DRAWINGS HEAVY UP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2579,
+ },
+ [0x257A]={
+ category="so",
+ description="BOX DRAWINGS HEAVY RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x257A,
+ },
+ [0x257B]={
+ category="so",
+ description="BOX DRAWINGS HEAVY DOWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x257B,
+ },
+ [0x257C]={
+ category="so",
+ description="BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x257C,
+ },
+ [0x257D]={
+ category="so",
+ description="BOX DRAWINGS LIGHT UP AND HEAVY DOWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x257D,
+ },
+ [0x257E]={
+ category="so",
+ description="BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x257E,
+ },
+ [0x257F]={
+ category="so",
+ description="BOX DRAWINGS HEAVY UP AND LIGHT DOWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x257F,
+ },
+ [0x2580]={
+ adobename="upblock",
+ category="so",
+ cjkwd="a",
+ description="UPPER HALF BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2580,
+ },
+ [0x2581]={
+ category="so",
+ cjkwd="a",
+ description="LOWER ONE EIGHTH BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2581,
+ },
+ [0x2582]={
+ category="so",
+ cjkwd="a",
+ description="LOWER ONE QUARTER BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2582,
+ },
+ [0x2583]={
+ category="so",
+ cjkwd="a",
+ description="LOWER THREE EIGHTHS BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2583,
+ },
+ [0x2584]={
+ adobename="dnblock",
+ category="so",
+ cjkwd="a",
+ description="LOWER HALF BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2584,
+ },
+ [0x2585]={
+ category="so",
+ cjkwd="a",
+ description="LOWER FIVE EIGHTHS BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2585,
+ },
+ [0x2586]={
+ category="so",
+ cjkwd="a",
+ description="LOWER THREE QUARTERS BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2586,
+ },
+ [0x2587]={
+ category="so",
+ cjkwd="a",
+ description="LOWER SEVEN EIGHTHS BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2587,
+ },
+ [0x2588]={
+ adobename="block",
+ category="so",
+ cjkwd="a",
+ description="FULL BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2588,
+ },
+ [0x2589]={
+ category="so",
+ cjkwd="a",
+ description="LEFT SEVEN EIGHTHS BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2589,
+ },
+ [0x258A]={
+ category="so",
+ cjkwd="a",
+ description="LEFT THREE QUARTERS BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x258A,
+ },
+ [0x258B]={
+ category="so",
+ cjkwd="a",
+ description="LEFT FIVE EIGHTHS BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x258B,
+ },
+ [0x258C]={
+ adobename="lfblock",
+ category="so",
+ cjkwd="a",
+ description="LEFT HALF BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x258C,
+ },
+ [0x258D]={
+ category="so",
+ cjkwd="a",
+ description="LEFT THREE EIGHTHS BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x258D,
+ },
+ [0x258E]={
+ category="so",
+ cjkwd="a",
+ description="LEFT ONE QUARTER BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x258E,
+ },
+ [0x258F]={
+ category="so",
+ cjkwd="a",
+ description="LEFT ONE EIGHTH BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x258F,
+ },
+ [0x2590]={
+ adobename="rtblock",
+ category="so",
+ description="RIGHT HALF BLOCK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2590,
+ },
+ [0x2591]={
+ adobename="shadelight",
+ category="so",
+ description="LIGHT SHADE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2591,
+ },
+ [0x2592]={
+ adobename="shademedium",
+ category="so",
+ cjkwd="a",
+ description="MEDIUM SHADE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2592,
+ },
+ [0x2593]={
+ adobename="shadedark",
+ category="so",
+ cjkwd="a",
+ description="DARK SHADE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2593,
+ },
+ [0x2594]={
+ category="so",
+ cjkwd="a",
+ description="UPPER ONE EIGHTH BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2594,
+ },
+ [0x2595]={
+ category="so",
+ cjkwd="a",
+ description="RIGHT ONE EIGHTH BLOCK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2595,
+ },
+ [0x2596]={
+ category="so",
+ description="QUADRANT LOWER LEFT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2596,
+ },
+ [0x2597]={
+ category="so",
+ description="QUADRANT LOWER RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2597,
+ },
+ [0x2598]={
+ category="so",
+ description="QUADRANT UPPER LEFT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2598,
+ },
+ [0x2599]={
+ category="so",
+ description="QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2599,
+ },
+ [0x259A]={
+ category="so",
+ description="QUADRANT UPPER LEFT AND LOWER RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x259A,
+ },
+ [0x259B]={
+ category="so",
+ description="QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x259B,
+ },
+ [0x259C]={
+ category="so",
+ description="QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x259C,
+ },
+ [0x259D]={
+ category="so",
+ description="QUADRANT UPPER RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x259D,
+ },
+ [0x259E]={
+ category="so",
+ description="QUADRANT UPPER RIGHT AND LOWER LEFT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x259E,
+ },
+ [0x259F]={
+ category="so",
+ description="QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x259F,
+ },
+ [0x25A0]={
+ adobename="filledbox",
+ category="so",
+ cjkwd="a",
+ description="BLACK SQUARE",
+ direction="on",
+ linebreak="ai",
+ mathclass="ordinary",
+ mathname="blacksquare",
+ unicodeslot=0x25A0,
+ },
+ [0x25A1]={
+ adobename="whitesquare",
+ category="so",
+ cjkwd="a",
+ description="WHITE SQUARE",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="ordinary",
+ name="square",
+ },
+ {
+ class="ordinary",
+ name="Box",
+ },
+ },
+ unicodeslot=0x25A1,
+ },
+ [0x25A2]={
+ category="so",
+ description="WHITE SQUARE WITH ROUNDED CORNERS",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ unicodeslot=0x25A2,
+ },
+ [0x25A3]={
+ adobename="squarewhitewithsmallblack",
+ category="so",
+ cjkwd="a",
+ description="WHITE SQUARE CONTAINING BLACK SMALL SQUARE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A3,
+ },
+ [0x25A4]={
+ adobename="squarehorizontalfill",
+ category="so",
+ cjkwd="a",
+ description="SQUARE WITH HORIZONTAL FILL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A4,
+ },
+ [0x25A5]={
+ adobename="squareverticalfill",
+ category="so",
+ cjkwd="a",
+ description="SQUARE WITH VERTICAL FILL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A5,
+ },
+ [0x25A6]={
+ adobename="squareorthogonalcrosshatchfill",
+ category="so",
+ cjkwd="a",
+ description="SQUARE WITH ORTHOGONAL CROSSHATCH FILL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A6,
+ },
+ [0x25A7]={
+ adobename="squareupperlefttolowerrightfill",
+ category="so",
+ cjkwd="a",
+ description="SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A7,
+ },
+ [0x25A8]={
+ adobename="squareupperrighttolowerleftfill",
+ category="so",
+ cjkwd="a",
+ description="SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A8,
+ },
+ [0x25A9]={
+ adobename="squarediagonalcrosshatchfill",
+ category="so",
+ cjkwd="a",
+ description="SQUARE WITH DIAGONAL CROSSHATCH FILL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25A9,
+ },
+ [0x25AA]={
+ adobename="blacksmallsquare",
+ category="so",
+ description="BLACK SMALL SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25AA,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x25AB]={
+ adobename="whitesmallsquare",
+ category="so",
+ description="WHITE SMALL SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25AB,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x25AC]={
+ adobename="filledrect",
+ category="so",
+ description="BLACK RECTANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25AC,
+ },
+ [0x25AD]={
+ category="so",
+ description="WHITE RECTANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25AD,
+ },
+ [0x25AE]={
+ category="so",
+ description="BLACK VERTICAL RECTANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25AE,
+ },
+ [0x25AF]={
+ category="so",
+ description="WHITE VERTICAL RECTANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25AF,
+ },
+ [0x25B0]={
+ category="so",
+ description="BLACK PARALLELOGRAM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25B0,
+ },
+ [0x25B1]={
+ category="so",
+ description="WHITE PARALLELOGRAM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25B1,
+ },
+ [0x25B2]={
+ adobename="triagup",
+ category="so",
+ cjkwd="a",
+ description="BLACK UP-POINTING TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="blacktriangle",
+ unicodeslot=0x25B2,
+ },
+ [0x25B3]={
+ adobename="whiteuppointingtriangle",
+ category="so",
+ cjkwd="a",
+ description="WHITE UP-POINTING TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="ordinary",
+ name="triangle",
+ },
+ {
+ class="binary",
+ name="bigtriangleup",
+ },
+ },
+ unicodeslot=0x25B3,
+ },
+ [0x25B4]={
+ adobename="blackuppointingsmalltriangle",
+ category="so",
+ description="BLACK UP-POINTING SMALL TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25B4,
+ },
+ [0x25B5]={
+ adobename="whiteuppointingsmalltriangle",
+ category="so",
+ description="WHITE UP-POINTING SMALL TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25B5,
+ },
+ [0x25B6]={
+ adobename="blackrightpointingtriangle",
+ category="so",
+ cjkwd="a",
+ description="BLACK RIGHT-POINTING TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="blacktriangleright",
+ unicodeslot=0x25B6,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x25B7]={
+ adobename="whiterightpointingtriangle",
+ category="sm",
+ cjkwd="a",
+ description="WHITE RIGHT-POINTING TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="triangleright",
+ unicodeslot=0x25B7,
+ },
+ [0x25B8]={
+ category="so",
+ description="BLACK RIGHT-POINTING SMALL TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25B8,
+ },
+ [0x25B9]={
+ adobename="whiterightpointingsmalltriangle",
+ category="so",
+ description="WHITE RIGHT-POINTING SMALL TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25B9,
+ },
+ [0x25BA]={
+ adobename="triagrt",
+ category="so",
+ description="BLACK RIGHT-POINTING POINTER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25BA,
+ },
+ [0x25BB]={
+ category="so",
+ description="WHITE RIGHT-POINTING POINTER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25BB,
+ },
+ [0x25BC]={
+ adobename="triagdn",
+ category="so",
+ cjkwd="a",
+ description="BLACK DOWN-POINTING TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="blacktriangledown",
+ unicodeslot=0x25BC,
+ },
+ [0x25BD]={
+ adobename="whitedownpointingtriangle",
+ category="so",
+ cjkwd="a",
+ description="WHITE DOWN-POINTING TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ mathspec={
+ {
+ class="binary",
+ name="triangledown",
+ },
+ {
+ class="binary",
+ name="bigtriangledown",
+ },
+ },
+ unicodeslot=0x25BD,
+ },
+ [0x25BE]={
+ category="so",
+ description="BLACK DOWN-POINTING SMALL TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25BE,
+ },
+ [0x25BF]={
+ adobename="whitedownpointingsmalltriangle",
+ category="so",
+ description="WHITE DOWN-POINTING SMALL TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25BF,
+ },
+ [0x25C0]={
+ adobename="blackleftpointingtriangle",
+ category="so",
+ cjkwd="a",
+ description="BLACK LEFT-POINTING TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="blacktriangleleft",
+ unicodeslot=0x25C0,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x25C1]={
+ adobename="whiteleftpointingtriangle",
+ category="sm",
+ cjkwd="a",
+ description="WHITE LEFT-POINTING TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="triangleleft",
+ unicodeslot=0x25C1,
+ },
+ [0x25C2]={
+ category="so",
+ description="BLACK LEFT-POINTING SMALL TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25C2,
+ },
+ [0x25C3]={
+ adobename="whiteleftpointingsmalltriangle",
+ category="so",
+ description="WHITE LEFT-POINTING SMALL TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25C3,
+ },
+ [0x25C4]={
+ adobename="triaglf",
+ category="so",
+ description="BLACK LEFT-POINTING POINTER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25C4,
+ },
+ [0x25C5]={
+ category="so",
+ description="WHITE LEFT-POINTING POINTER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25C5,
+ },
+ [0x25C6]={
+ adobename="blackdiamond",
+ category="so",
+ cjkwd="a",
+ description="BLACK DIAMOND",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25C6,
+ },
+ [0x25C7]={
+ adobename="whitediamond",
+ category="so",
+ cjkwd="a",
+ description="WHITE DIAMOND",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25C7,
+ },
+ [0x25C8]={
+ adobename="whitediamondcontainingblacksmalldiamond",
+ category="so",
+ cjkwd="a",
+ description="WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25C8,
+ },
+ [0x25C9]={
+ adobename="fisheye",
+ category="so",
+ description="FISHEYE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25C9,
+ },
+ [0x25CA]={
+ adobename="lozenge",
+ category="so",
+ description="LOZENGE",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="lozenge",
+ unicodeslot=0x25CA,
+ },
+ [0x25CB]={
+ adobename="whitecircle",
+ category="so",
+ cjkwd="a",
+ description="WHITE CIRCLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25CB,
+ },
+ [0x25CC]={
+ adobename="dottedcircle",
+ category="so",
+ description="DOTTED CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25CC,
+ },
+ [0x25CD]={
+ category="so",
+ description="CIRCLE WITH VERTICAL FILL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25CD,
+ },
+ [0x25CE]={
+ adobename="bullseye",
+ category="so",
+ cjkwd="a",
+ description="BULLSEYE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25CE,
+ },
+ [0x25CF]={
+ adobename="blackcircle",
+ category="so",
+ cjkwd="a",
+ description="BLACK CIRCLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25CF,
+ },
+ [0x25D0]={
+ adobename="circlewithlefthalfblack",
+ category="so",
+ cjkwd="a",
+ description="CIRCLE WITH LEFT HALF BLACK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25D0,
+ },
+ [0x25D1]={
+ adobename="circlewithrighthalfblack",
+ category="so",
+ cjkwd="a",
+ description="CIRCLE WITH RIGHT HALF BLACK",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25D1,
+ },
+ [0x25D2]={
+ category="so",
+ description="CIRCLE WITH LOWER HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D2,
+ },
+ [0x25D3]={
+ category="so",
+ description="CIRCLE WITH UPPER HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D3,
+ },
+ [0x25D4]={
+ category="so",
+ description="CIRCLE WITH UPPER RIGHT QUADRANT BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D4,
+ },
+ [0x25D5]={
+ category="so",
+ description="CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D5,
+ },
+ [0x25D6]={
+ category="so",
+ description="LEFT HALF BLACK CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D6,
+ },
+ [0x25D7]={
+ category="so",
+ description="RIGHT HALF BLACK CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D7,
+ },
+ [0x25D8]={
+ adobename="invbullet",
+ category="so",
+ description="INVERSE BULLET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D8,
+ },
+ [0x25D9]={
+ adobename="whitecircleinverse",
+ category="so",
+ description="INVERSE WHITE CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25D9,
+ },
+ [0x25DA]={
+ category="so",
+ description="UPPER HALF INVERSE WHITE CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25DA,
+ },
+ [0x25DB]={
+ category="so",
+ description="LOWER HALF INVERSE WHITE CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25DB,
+ },
+ [0x25DC]={
+ category="so",
+ description="UPPER LEFT QUADRANT CIRCULAR ARC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25DC,
+ },
+ [0x25DD]={
+ category="so",
+ description="UPPER RIGHT QUADRANT CIRCULAR ARC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25DD,
+ },
+ [0x25DE]={
+ category="so",
+ description="LOWER RIGHT QUADRANT CIRCULAR ARC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25DE,
+ },
+ [0x25DF]={
+ category="so",
+ description="LOWER LEFT QUADRANT CIRCULAR ARC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25DF,
+ },
+ [0x25E0]={
+ category="so",
+ description="UPPER HALF CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25E0,
+ },
+ [0x25E1]={
+ category="so",
+ description="LOWER HALF CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25E1,
+ },
+ [0x25E2]={
+ adobename="blacklowerrighttriangle",
+ category="so",
+ cjkwd="a",
+ description="BLACK LOWER RIGHT TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25E2,
+ },
+ [0x25E3]={
+ adobename="blacklowerlefttriangle",
+ category="so",
+ cjkwd="a",
+ description="BLACK LOWER LEFT TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25E3,
+ },
+ [0x25E4]={
+ adobename="blackupperlefttriangle",
+ category="so",
+ cjkwd="a",
+ description="BLACK UPPER LEFT TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25E4,
+ },
+ [0x25E5]={
+ adobename="blackupperrighttriangle",
+ category="so",
+ cjkwd="a",
+ description="BLACK UPPER RIGHT TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x25E5,
+ },
+ [0x25E6]={
+ adobename="whitebullet",
+ category="so",
+ description="WHITE BULLET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25E6,
+ },
+ [0x25E7]={
+ category="so",
+ description="SQUARE WITH LEFT HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25E7,
+ },
+ [0x25E8]={
+ category="so",
+ description="SQUARE WITH RIGHT HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25E8,
+ },
+ [0x25E9]={
+ category="so",
+ description="SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25E9,
+ },
+ [0x25EA]={
+ category="so",
+ description="SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25EA,
+ },
+ [0x25EB]={
+ category="so",
+ description="WHITE SQUARE WITH VERTICAL BISECTING LINE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25EB,
+ },
+ [0x25EC]={
+ category="so",
+ description="WHITE UP-POINTING TRIANGLE WITH DOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25EC,
+ },
+ [0x25ED]={
+ category="so",
+ description="UP-POINTING TRIANGLE WITH LEFT HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25ED,
+ },
+ [0x25EE]={
+ category="so",
+ description="UP-POINTING TRIANGLE WITH RIGHT HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25EE,
+ },
+ [0x25EF]={
+ adobename="largecircle",
+ category="so",
+ cjkwd="a",
+ description="LARGE CIRCLE",
+ direction="on",
+ linebreak="ai",
+ mathclass="binary",
+ mathname="bigcirc",
+ unicodeslot=0x25EF,
+ },
+ [0x25F0]={
+ category="so",
+ description="WHITE SQUARE WITH UPPER LEFT QUADRANT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F0,
+ },
+ [0x25F1]={
+ category="so",
+ description="WHITE SQUARE WITH LOWER LEFT QUADRANT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F1,
+ },
+ [0x25F2]={
+ category="so",
+ description="WHITE SQUARE WITH LOWER RIGHT QUADRANT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F2,
+ },
+ [0x25F3]={
+ category="so",
+ description="WHITE SQUARE WITH UPPER RIGHT QUADRANT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F3,
+ },
+ [0x25F4]={
+ category="so",
+ description="WHITE CIRCLE WITH UPPER LEFT QUADRANT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F4,
+ },
+ [0x25F5]={
+ category="so",
+ description="WHITE CIRCLE WITH LOWER LEFT QUADRANT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F5,
+ },
+ [0x25F6]={
+ category="so",
+ description="WHITE CIRCLE WITH LOWER RIGHT QUADRANT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F6,
+ },
+ [0x25F7]={
+ category="so",
+ description="WHITE CIRCLE WITH UPPER RIGHT QUADRANT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F7,
+ },
+ [0x25F8]={
+ category="sm",
+ description="UPPER LEFT TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F8,
+ },
+ [0x25F9]={
+ category="sm",
+ description="UPPER RIGHT TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25F9,
+ },
+ [0x25FA]={
+ category="sm",
+ description="LOWER LEFT TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25FA,
+ },
+ [0x25FB]={
+ category="sm",
+ description="WHITE MEDIUM SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25FB,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x25FC]={
+ category="sm",
+ description="BLACK MEDIUM SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25FC,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x25FD]={
+ category="sm",
+ description="WHITE MEDIUM SMALL SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25FD,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x25FE]={
+ category="sm",
+ description="BLACK MEDIUM SMALL SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25FE,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x25FF]={
+ category="sm",
+ description="LOWER RIGHT TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x25FF,
+ },
+ [0x2600]={
+ category="so",
+ description="BLACK SUN WITH RAYS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2600,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2601]={
+ category="so",
+ description="CLOUD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2601,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2602]={
+ category="so",
+ description="UMBRELLA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2602,
+ },
+ [0x2603]={
+ category="so",
+ description="SNOWMAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2603,
+ },
+ [0x2604]={
+ category="so",
+ description="COMET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2604,
+ },
+ [0x2605]={
+ adobename="blackstar",
+ category="so",
+ cjkwd="a",
+ description="BLACK STAR",
+ direction="on",
+ linebreak="ai",
+ mathclass="ordinary",
+ mathname="bigstar",
+ unicodeslot=0x2605,
+ },
+ [0x2606]={
+ adobename="whitestar",
+ category="so",
+ cjkwd="a",
+ description="WHITE STAR",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2606,
+ },
+ [0x2607]={
+ category="so",
+ description="LIGHTNING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2607,
+ },
+ [0x2608]={
+ category="so",
+ description="THUNDERSTORM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2608,
+ },
+ [0x2609]={
+ category="so",
+ cjkwd="a",
+ description="SUN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2609,
+ },
+ [0x260A]={
+ category="so",
+ description="ASCENDING NODE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x260A,
+ },
+ [0x260B]={
+ category="so",
+ description="DESCENDING NODE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x260B,
+ },
+ [0x260C]={
+ category="so",
+ description="CONJUNCTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x260C,
+ },
+ [0x260D]={
+ category="so",
+ description="OPPOSITION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x260D,
+ },
+ [0x260E]={
+ adobename="telephoneblack",
+ category="so",
+ cjkwd="a",
+ description="BLACK TELEPHONE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x260E,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x260F]={
+ adobename="whitetelephone",
+ category="so",
+ cjkwd="a",
+ description="WHITE TELEPHONE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x260F,
+ },
+ [0x2610]={
+ category="so",
+ description="BALLOT BOX",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2610,
+ },
+ [0x2611]={
+ category="so",
+ description="BALLOT BOX WITH CHECK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2611,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2612]={
+ category="so",
+ description="BALLOT BOX WITH X",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2612,
+ },
+ [0x2613]={
+ category="so",
+ description="SALTIRE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2613,
+ },
+ [0x2614]={
+ category="so",
+ cjkwd="a",
+ description="UMBRELLA WITH RAIN DROPS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2614,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2615]={
+ category="so",
+ cjkwd="a",
+ description="HOT BEVERAGE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2615,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2616]={
+ category="so",
+ description="WHITE SHOGI PIECE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2616,
+ },
+ [0x2617]={
+ category="so",
+ description="BLACK SHOGI PIECE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2617,
+ },
+ [0x2618]={
+ category="so",
+ description="SHAMROCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2618,
+ },
+ [0x2619]={
+ category="so",
+ description="REVERSED ROTATED FLORAL HEART BULLET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2619,
+ },
+ [0x261A]={
+ category="so",
+ description="BLACK LEFT POINTING INDEX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x261A,
+ },
+ [0x261B]={
+ category="so",
+ description="BLACK RIGHT POINTING INDEX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x261B,
+ },
+ [0x261C]={
+ adobename="pointingindexleftwhite",
+ category="so",
+ cjkwd="a",
+ description="WHITE LEFT POINTING INDEX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x261C,
+ },
+ [0x261D]={
+ adobename="pointingindexupwhite",
+ category="so",
+ description="WHITE UP POINTING INDEX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x261D,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x261E]={
+ adobename="pointingindexrightwhite",
+ category="so",
+ cjkwd="a",
+ description="WHITE RIGHT POINTING INDEX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x261E,
+ },
+ [0x261F]={
+ adobename="pointingindexdownwhite",
+ category="so",
+ description="WHITE DOWN POINTING INDEX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x261F,
+ },
+ [0x2620]={
+ category="so",
+ description="SKULL AND CROSSBONES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2620,
+ },
+ [0x2621]={
+ category="so",
+ description="CAUTION SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2621,
+ },
+ [0x2622]={
+ category="so",
+ description="RADIOACTIVE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2622,
+ },
+ [0x2623]={
+ category="so",
+ description="BIOHAZARD SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2623,
+ },
+ [0x2624]={
+ category="so",
+ description="CADUCEUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2624,
+ },
+ [0x2625]={
+ category="so",
+ description="ANKH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2625,
+ },
+ [0x2626]={
+ category="so",
+ description="ORTHODOX CROSS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2626,
+ },
+ [0x2627]={
+ category="so",
+ description="CHI RHO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2627,
+ },
+ [0x2628]={
+ category="so",
+ description="CROSS OF LORRAINE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2628,
+ },
+ [0x2629]={
+ category="so",
+ description="CROSS OF JERUSALEM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2629,
+ },
+ [0x262A]={
+ category="so",
+ description="STAR AND CRESCENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x262A,
+ },
+ [0x262B]={
+ category="so",
+ description="FARSI SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x262B,
+ },
+ [0x262C]={
+ category="so",
+ description="ADI SHAKTI",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x262C,
+ },
+ [0x262D]={
+ category="so",
+ description="HAMMER AND SICKLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x262D,
+ },
+ [0x262E]={
+ category="so",
+ description="PEACE SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x262E,
+ },
+ [0x262F]={
+ adobename="yinyang",
+ category="so",
+ description="YIN YANG",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x262F,
+ },
+ [0x2630]={
+ category="so",
+ description="TRIGRAM FOR HEAVEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2630,
+ },
+ [0x2631]={
+ category="so",
+ description="TRIGRAM FOR LAKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2631,
+ },
+ [0x2632]={
+ category="so",
+ description="TRIGRAM FOR FIRE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2632,
+ },
+ [0x2633]={
+ category="so",
+ description="TRIGRAM FOR THUNDER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2633,
+ },
+ [0x2634]={
+ category="so",
+ description="TRIGRAM FOR WIND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2634,
+ },
+ [0x2635]={
+ category="so",
+ description="TRIGRAM FOR WATER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2635,
+ },
+ [0x2636]={
+ category="so",
+ description="TRIGRAM FOR MOUNTAIN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2636,
+ },
+ [0x2637]={
+ category="so",
+ description="TRIGRAM FOR EARTH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2637,
+ },
+ [0x2638]={
+ category="so",
+ description="WHEEL OF DHARMA",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2638,
+ },
+ [0x2639]={
+ category="so",
+ description="WHITE FROWNING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2639,
+ },
+ [0x263A]={
+ adobename="whitesmilingface",
+ category="so",
+ description="WHITE SMILING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x263A,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x263B]={
+ adobename="invsmileface",
+ category="so",
+ description="BLACK SMILING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x263B,
+ },
+ [0x263C]={
+ adobename="sun",
+ category="so",
+ description="WHITE SUN WITH RAYS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x263C,
+ },
+ [0x263D]={
+ category="so",
+ description="FIRST QUARTER MOON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x263D,
+ },
+ [0x263E]={
+ category="so",
+ description="LAST QUARTER MOON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x263E,
+ },
+ [0x263F]={
+ category="so",
+ description="MERCURY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x263F,
+ },
+ [0x2640]={
+ adobename="venus",
+ category="so",
+ cjkwd="a",
+ description="FEMALE SIGN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2640,
+ },
+ [0x2641]={
+ adobename="earth",
+ category="so",
+ description="EARTH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2641,
+ },
+ [0x2642]={
+ adobename="mars",
+ category="so",
+ cjkwd="a",
+ description="MALE SIGN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2642,
+ },
+ [0x2643]={
+ category="so",
+ description="JUPITER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2643,
+ },
+ [0x2644]={
+ category="so",
+ description="SATURN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2644,
+ },
+ [0x2645]={
+ category="so",
+ description="URANUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2645,
+ },
+ [0x2646]={
+ category="so",
+ description="NEPTUNE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2646,
+ },
+ [0x2647]={
+ category="so",
+ description="PLUTO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2647,
+ },
+ [0x2648]={
+ category="so",
+ description="ARIES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2648,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2649]={
+ category="so",
+ description="TAURUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2649,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x264A]={
+ category="so",
+ description="GEMINI",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x264A,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x264B]={
+ category="so",
+ description="CANCER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x264B,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x264C]={
+ category="so",
+ description="LEO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x264C,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x264D]={
+ category="so",
+ description="VIRGO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x264D,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x264E]={
+ category="so",
+ description="LIBRA",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x264E,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x264F]={
+ category="so",
+ description="SCORPIUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x264F,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2650]={
+ category="so",
+ description="SAGITTARIUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2650,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2651]={
+ category="so",
+ description="CAPRICORN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2651,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2652]={
+ category="so",
+ description="AQUARIUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2652,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2653]={
+ category="so",
+ description="PISCES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2653,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2654]={
+ category="so",
+ description="WHITE CHESS KING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2654,
+ },
+ [0x2655]={
+ category="so",
+ description="WHITE CHESS QUEEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2655,
+ },
+ [0x2656]={
+ category="so",
+ description="WHITE CHESS ROOK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2656,
+ },
+ [0x2657]={
+ category="so",
+ description="WHITE CHESS BISHOP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2657,
+ },
+ [0x2658]={
+ category="so",
+ description="WHITE CHESS KNIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2658,
+ },
+ [0x2659]={
+ category="so",
+ description="WHITE CHESS PAWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2659,
+ },
+ [0x265A]={
+ category="so",
+ description="BLACK CHESS KING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x265A,
+ },
+ [0x265B]={
+ category="so",
+ description="BLACK CHESS QUEEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x265B,
+ },
+ [0x265C]={
+ category="so",
+ description="BLACK CHESS ROOK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x265C,
+ },
+ [0x265D]={
+ category="so",
+ description="BLACK CHESS BISHOP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x265D,
+ },
+ [0x265E]={
+ category="so",
+ description="BLACK CHESS KNIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x265E,
+ },
+ [0x265F]={
+ category="so",
+ description="BLACK CHESS PAWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x265F,
+ },
+ [0x2660]={
+ adobename="spadesuitblack",
+ category="so",
+ cjkwd="a",
+ description="BLACK SPADE SUIT",
+ direction="on",
+ linebreak="ai",
+ mathclass="default",
+ mathname="spadesuit",
+ unicodeslot=0x2660,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2661]={
+ adobename="heartsuitwhite",
+ category="so",
+ cjkwd="a",
+ description="WHITE HEART SUIT",
+ direction="on",
+ linebreak="ai",
+ mathclass="default",
+ mathname="heartsuit",
+ unicodeslot=0x2661,
+ },
+ [0x2662]={
+ adobename="diamondsuitwhite",
+ category="so",
+ description="WHITE DIAMOND SUIT",
+ direction="on",
+ linebreak="al",
+ mathclass="default",
+ mathname="diamondsuit",
+ unicodeslot=0x2662,
+ },
+ [0x2663]={
+ adobename="clubsuitblack",
+ category="so",
+ cjkwd="a",
+ description="BLACK CLUB SUIT",
+ direction="on",
+ linebreak="ai",
+ mathclass="default",
+ mathname="clubsuit",
+ unicodeslot=0x2663,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2664]={
+ adobename="spadesuitwhite",
+ category="so",
+ cjkwd="a",
+ description="WHITE SPADE SUIT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2664,
+ },
+ [0x2665]={
+ adobename="heartsuitblack",
+ category="so",
+ cjkwd="a",
+ description="BLACK HEART SUIT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2665,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2666]={
+ adobename="diamond",
+ category="so",
+ description="BLACK DIAMOND SUIT",
+ direction="on",
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="blacklozenge",
+ unicodeslot=0x2666,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2667]={
+ adobename="clubsuitwhite",
+ category="so",
+ cjkwd="a",
+ description="WHITE CLUB SUIT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2667,
+ },
+ [0x2668]={
+ adobename="hotsprings",
+ category="so",
+ cjkwd="a",
+ description="HOT SPRINGS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2668,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2669]={
+ adobename="quarternote",
+ category="so",
+ cjkwd="a",
+ description="QUARTER NOTE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2669,
+ },
+ [0x266A]={
+ adobename="musicalnote",
+ category="so",
+ cjkwd="a",
+ description="EIGHTH NOTE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x266A,
+ },
+ [0x266B]={
+ adobename="musicalnotedbl",
+ category="so",
+ description="BEAMED EIGHTH NOTES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x266B,
+ },
+ [0x266C]={
+ adobename="beamedsixteenthnotes",
+ category="so",
+ cjkwd="a",
+ description="BEAMED SIXTEENTH NOTES",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x266C,
+ },
+ [0x266D]={
+ adobename="musicflatsign",
+ category="so",
+ cjkwd="a",
+ description="MUSIC FLAT SIGN",
+ direction="on",
+ linebreak="ai",
+ mathclass="default",
+ mathname="flat",
+ unicodeslot=0x266D,
+ },
+ [0x266E]={
+ category="so",
+ description="MUSIC NATURAL SIGN",
+ direction="on",
+ linebreak="al",
+ mathclass="default",
+ mathname="natural",
+ unicodeslot=0x266E,
+ },
+ [0x266F]={
+ adobename="musicsharpsign",
+ category="sm",
+ cjkwd="a",
+ description="MUSIC SHARP SIGN",
+ direction="on",
+ linebreak="ai",
+ mathclass="default",
+ mathname="sharp",
+ unicodeslot=0x266F,
+ },
+ [0x2670]={
+ category="so",
+ description="WEST SYRIAC CROSS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2670,
+ },
+ [0x2671]={
+ category="so",
+ description="EAST SYRIAC CROSS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2671,
+ },
+ [0x2672]={
+ category="so",
+ description="UNIVERSAL RECYCLING SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2672,
+ },
+ [0x2673]={
+ category="so",
+ description="RECYCLING SYMBOL FOR TYPE-0x0001 PLASTICS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2673,
+ },
+ [0x2674]={
+ category="so",
+ description="RECYCLING SYMBOL FOR TYPE-0x0002 PLASTICS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2674,
+ },
+ [0x2675]={
+ category="so",
+ description="RECYCLING SYMBOL FOR TYPE-0x0003 PLASTICS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2675,
+ },
+ [0x2676]={
+ category="so",
+ description="RECYCLING SYMBOL FOR TYPE-0x0004 PLASTICS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2676,
+ },
+ [0x2677]={
+ category="so",
+ description="RECYCLING SYMBOL FOR TYPE-0x0005 PLASTICS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2677,
+ },
+ [0x2678]={
+ category="so",
+ description="RECYCLING SYMBOL FOR TYPE-0x0006 PLASTICS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2678,
+ },
+ [0x2679]={
+ category="so",
+ description="RECYCLING SYMBOL FOR TYPE-0x0007 PLASTICS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2679,
+ },
+ [0x267A]={
+ category="so",
+ description="RECYCLING SYMBOL FOR GENERIC MATERIALS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x267A,
+ },
+ [0x267B]={
+ category="so",
+ description="BLACK UNIVERSAL RECYCLING SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x267B,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x267C]={
+ category="so",
+ description="RECYCLED PAPER SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x267C,
+ },
+ [0x267D]={
+ category="so",
+ description="PARTIALLY-RECYCLED PAPER SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x267D,
+ },
+ [0x267E]={
+ category="so",
+ description="PERMANENT PAPER SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x267E,
+ },
+ [0x267F]={
+ category="so",
+ description="WHEELCHAIR SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x267F,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2680]={
+ category="so",
+ description="DIE FACE-0x0001",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2680,
+ },
+ [0x2681]={
+ category="so",
+ description="DIE FACE-0x0002",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2681,
+ },
+ [0x2682]={
+ category="so",
+ description="DIE FACE-0x0003",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2682,
+ },
+ [0x2683]={
+ category="so",
+ description="DIE FACE-0x0004",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2683,
+ },
+ [0x2684]={
+ category="so",
+ description="DIE FACE-0x0005",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2684,
+ },
+ [0x2685]={
+ category="so",
+ description="DIE FACE-0x0006",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2685,
+ },
+ [0x2686]={
+ category="so",
+ description="WHITE CIRCLE WITH DOT RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2686,
+ },
+ [0x2687]={
+ category="so",
+ description="WHITE CIRCLE WITH TWO DOTS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2687,
+ },
+ [0x2688]={
+ category="so",
+ description="BLACK CIRCLE WITH WHITE DOT RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2688,
+ },
+ [0x2689]={
+ category="so",
+ description="BLACK CIRCLE WITH TWO WHITE DOTS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2689,
+ },
+ [0x268A]={
+ category="so",
+ description="MONOGRAM FOR YANG",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x268A,
+ },
+ [0x268B]={
+ category="so",
+ description="MONOGRAM FOR YIN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x268B,
+ },
+ [0x268C]={
+ category="so",
+ description="DIGRAM FOR GREATER YANG",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x268C,
+ },
+ [0x268D]={
+ category="so",
+ description="DIGRAM FOR LESSER YIN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x268D,
+ },
+ [0x268E]={
+ category="so",
+ description="DIGRAM FOR LESSER YANG",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x268E,
+ },
+ [0x268F]={
+ category="so",
+ description="DIGRAM FOR GREATER YIN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x268F,
+ },
+ [0x2690]={
+ category="so",
+ description="WHITE FLAG",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2690,
+ },
+ [0x2691]={
+ category="so",
+ description="BLACK FLAG",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2691,
+ },
+ [0x2692]={
+ category="so",
+ description="HAMMER AND PICK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2692,
+ },
+ [0x2693]={
+ category="so",
+ description="ANCHOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2693,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2694]={
+ category="so",
+ description="CROSSED SWORDS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2694,
+ },
+ [0x2695]={
+ category="so",
+ description="STAFF OF AESCULAPIUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2695,
+ },
+ [0x2696]={
+ category="so",
+ description="SCALES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2696,
+ },
+ [0x2697]={
+ category="so",
+ description="ALEMBIC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2697,
+ },
+ [0x2698]={
+ category="so",
+ description="FLOWER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2698,
+ },
+ [0x2699]={
+ category="so",
+ description="GEAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2699,
+ },
+ [0x269A]={
+ category="so",
+ description="STAFF OF HERMES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x269A,
+ },
+ [0x269B]={
+ category="so",
+ description="ATOM SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x269B,
+ },
+ [0x269C]={
+ category="so",
+ description="FLEUR-DE-LIS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x269C,
+ },
+ [0x269D]={
+ category="so",
+ description="OUTLINED WHITE STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x269D,
+ },
+ [0x269E]={
+ category="so",
+ cjkwd="a",
+ description="THREE LINES CONVERGING RIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x269E,
+ },
+ [0x269F]={
+ category="so",
+ cjkwd="a",
+ description="THREE LINES CONVERGING LEFT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x269F,
+ },
+ [0x26A0]={
+ category="so",
+ description="WARNING SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A0,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26A1]={
+ category="so",
+ description="HIGH VOLTAGE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A1,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26A2]={
+ category="so",
+ description="DOUBLED FEMALE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A2,
+ },
+ [0x26A3]={
+ category="so",
+ description="DOUBLED MALE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A3,
+ },
+ [0x26A4]={
+ category="so",
+ description="INTERLOCKED FEMALE AND MALE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A4,
+ },
+ [0x26A5]={
+ category="so",
+ description="MALE AND FEMALE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A5,
+ },
+ [0x26A6]={
+ category="so",
+ description="MALE WITH STROKE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A6,
+ },
+ [0x26A7]={
+ category="so",
+ description="MALE WITH STROKE AND MALE AND FEMALE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A7,
+ },
+ [0x26A8]={
+ category="so",
+ description="VERTICAL MALE WITH STROKE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A8,
+ },
+ [0x26A9]={
+ category="so",
+ description="HORIZONTAL MALE WITH STROKE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26A9,
+ },
+ [0x26AA]={
+ category="so",
+ description="MEDIUM WHITE CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26AA,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26AB]={
+ category="so",
+ description="MEDIUM BLACK CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26AB,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26AC]={
+ category="so",
+ description="MEDIUM SMALL WHITE CIRCLE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x26AC,
+ },
+ [0x26AD]={
+ category="so",
+ description="MARRIAGE SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26AD,
+ },
+ [0x26AE]={
+ category="so",
+ description="DIVORCE SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26AE,
+ },
+ [0x26AF]={
+ category="so",
+ description="UNMARRIED PARTNERSHIP SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26AF,
+ },
+ [0x26B0]={
+ category="so",
+ description="COFFIN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B0,
+ },
+ [0x26B1]={
+ category="so",
+ description="FUNERAL URN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B1,
+ },
+ [0x26B2]={
+ category="so",
+ description="NEUTER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B2,
+ },
+ [0x26B3]={
+ category="so",
+ description="CERES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B3,
+ },
+ [0x26B4]={
+ category="so",
+ description="PALLAS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B4,
+ },
+ [0x26B5]={
+ category="so",
+ description="JUNO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B5,
+ },
+ [0x26B6]={
+ category="so",
+ description="VESTA",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B6,
+ },
+ [0x26B7]={
+ category="so",
+ description="CHIRON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B7,
+ },
+ [0x26B8]={
+ category="so",
+ description="BLACK MOON LILITH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B8,
+ },
+ [0x26B9]={
+ category="so",
+ description="SEXTILE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26B9,
+ },
+ [0x26BA]={
+ category="so",
+ description="SEMISEXTILE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26BA,
+ },
+ [0x26BB]={
+ category="so",
+ description="QUINCUNX",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26BB,
+ },
+ [0x26BC]={
+ category="so",
+ description="SESQUIQUADRATE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26BC,
+ },
+ [0x26BD]={
+ category="so",
+ description="SOCCER BALL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26BD,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26BE]={
+ category="so",
+ cjkwd="a",
+ description="BASEBALL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26BE,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26BF]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED KEY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26BF,
+ },
+ [0x26C0]={
+ category="so",
+ description="WHITE DRAUGHTS MAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C0,
+ },
+ [0x26C1]={
+ category="so",
+ description="WHITE DRAUGHTS KING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C1,
+ },
+ [0x26C2]={
+ category="so",
+ description="BLACK DRAUGHTS MAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C2,
+ },
+ [0x26C3]={
+ category="so",
+ description="BLACK DRAUGHTS KING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C3,
+ },
+ [0x26C4]={
+ category="so",
+ cjkwd="a",
+ description="SNOWMAN WITHOUT SNOW",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C4,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26C5]={
+ category="so",
+ cjkwd="a",
+ description="SUN BEHIND CLOUD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C5,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26C6]={
+ category="so",
+ cjkwd="a",
+ description="RAIN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C6,
+ },
+ [0x26C7]={
+ category="so",
+ cjkwd="a",
+ description="BLACK SNOWMAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C7,
+ },
+ [0x26C8]={
+ category="so",
+ cjkwd="a",
+ description="THUNDER CLOUD AND RAIN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26C8,
+ },
+ [0x26C9]={
+ category="so",
+ cjkwd="a",
+ description="TURNED WHITE SHOGI PIECE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26C9,
+ },
+ [0x26CA]={
+ category="so",
+ cjkwd="a",
+ description="TURNED BLACK SHOGI PIECE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26CA,
+ },
+ [0x26CB]={
+ category="so",
+ cjkwd="a",
+ description="WHITE DIAMOND IN SQUARE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26CB,
+ },
+ [0x26CC]={
+ category="so",
+ cjkwd="a",
+ description="CROSSING LANES",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26CC,
+ },
+ [0x26CD]={
+ category="so",
+ cjkwd="a",
+ description="DISABLED CAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26CD,
+ },
+ [0x26CE]={
+ category="so",
+ description="OPHIUCHUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26CE,
+ },
+ [0x26CF]={
+ category="so",
+ cjkwd="a",
+ description="PICK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26CF,
+ },
+ [0x26D0]={
+ category="so",
+ cjkwd="a",
+ description="CAR SLIDING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26D0,
+ },
+ [0x26D1]={
+ category="so",
+ cjkwd="a",
+ description="HELMET WITH WHITE CROSS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26D1,
+ },
+ [0x26D2]={
+ category="so",
+ cjkwd="a",
+ description="CIRCLED CROSSING LANES",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26D2,
+ },
+ [0x26D3]={
+ category="so",
+ cjkwd="a",
+ description="CHAINS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26D3,
+ },
+ [0x26D4]={
+ category="so",
+ cjkwd="a",
+ description="NO ENTRY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26D4,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26D5]={
+ category="so",
+ cjkwd="a",
+ description="ALTERNATE ONE-WAY LEFT WAY TRAFFIC",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26D5,
+ },
+ [0x26D6]={
+ category="so",
+ cjkwd="a",
+ description="BLACK TWO-WAY LEFT WAY TRAFFIC",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26D6,
+ },
+ [0x26D7]={
+ category="so",
+ cjkwd="a",
+ description="WHITE TWO-WAY LEFT WAY TRAFFIC",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26D7,
+ },
+ [0x26D8]={
+ category="so",
+ cjkwd="a",
+ description="BLACK LEFT LANE MERGE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26D8,
+ },
+ [0x26D9]={
+ category="so",
+ cjkwd="a",
+ description="WHITE LEFT LANE MERGE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26D9,
+ },
+ [0x26DA]={
+ category="so",
+ cjkwd="a",
+ description="DRIVE SLOW SIGN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26DA,
+ },
+ [0x26DB]={
+ category="so",
+ cjkwd="a",
+ description="HEAVY WHITE DOWN-POINTING TRIANGLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26DB,
+ },
+ [0x26DC]={
+ category="so",
+ cjkwd="a",
+ description="LEFT CLOSED ENTRY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26DC,
+ },
+ [0x26DD]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED SALTIRE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26DD,
+ },
+ [0x26DE]={
+ category="so",
+ cjkwd="a",
+ description="FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26DE,
+ },
+ [0x26DF]={
+ category="so",
+ cjkwd="a",
+ description="BLACK TRUCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26DF,
+ },
+ [0x26E0]={
+ category="so",
+ cjkwd="a",
+ description="RESTRICTED LEFT ENTRY-1",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26E0,
+ },
+ [0x26E1]={
+ category="so",
+ cjkwd="a",
+ description="RESTRICTED LEFT ENTRY-2",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26E1,
+ },
+ [0x26E2]={
+ category="so",
+ description="ASTRONOMICAL SYMBOL FOR URANUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26E2,
+ },
+ [0x26E3]={
+ category="so",
+ cjkwd="a",
+ description="HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26E3,
+ },
+ [0x26E4]={
+ category="so",
+ description="PENTAGRAM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26E4,
+ },
+ [0x26E5]={
+ category="so",
+ description="RIGHT-HANDED INTERLACED PENTAGRAM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26E5,
+ },
+ [0x26E6]={
+ category="so",
+ description="LEFT-HANDED INTERLACED PENTAGRAM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26E6,
+ },
+ [0x26E7]={
+ category="so",
+ description="INVERTED PENTAGRAM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x26E7,
+ },
+ [0x26E8]={
+ category="so",
+ cjkwd="a",
+ description="BLACK CROSS ON SHIELD",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26E8,
+ },
+ [0x26E9]={
+ category="so",
+ cjkwd="a",
+ description="SHINTO SHRINE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26E9,
+ },
+ [0x26EA]={
+ category="so",
+ cjkwd="a",
+ description="CHURCH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26EA,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26EB]={
+ category="so",
+ cjkwd="a",
+ description="CASTLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26EB,
+ },
+ [0x26EC]={
+ category="so",
+ cjkwd="a",
+ description="HISTORIC SITE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26EC,
+ },
+ [0x26ED]={
+ category="so",
+ cjkwd="a",
+ description="GEAR WITHOUT HUB",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26ED,
+ },
+ [0x26EE]={
+ category="so",
+ cjkwd="a",
+ description="GEAR WITH HANDLES",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26EE,
+ },
+ [0x26EF]={
+ category="so",
+ cjkwd="a",
+ description="MAP SYMBOL FOR LIGHTHOUSE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26EF,
+ },
+ [0x26F0]={
+ category="so",
+ cjkwd="a",
+ description="MOUNTAIN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26F0,
+ },
+ [0x26F1]={
+ category="so",
+ cjkwd="a",
+ description="UMBRELLA ON GROUND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F1,
+ },
+ [0x26F2]={
+ category="so",
+ cjkwd="a",
+ description="FOUNTAIN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F2,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26F3]={
+ category="so",
+ cjkwd="a",
+ description="FLAG IN HOLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F3,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26F4]={
+ category="so",
+ cjkwd="a",
+ description="FERRY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F4,
+ },
+ [0x26F5]={
+ category="so",
+ cjkwd="a",
+ description="SAILBOAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F5,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26F6]={
+ category="so",
+ cjkwd="a",
+ description="SQUARE FOUR CORNERS",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26F6,
+ },
+ [0x26F7]={
+ category="so",
+ cjkwd="a",
+ description="SKIER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F7,
+ },
+ [0x26F8]={
+ category="so",
+ cjkwd="a",
+ description="ICE SKATE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F8,
+ },
+ [0x26F9]={
+ category="so",
+ cjkwd="a",
+ description="PERSON WITH BALL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26F9,
+ },
+ [0x26FA]={
+ category="so",
+ cjkwd="a",
+ description="TENT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26FA,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26FB]={
+ category="so",
+ cjkwd="a",
+ description="JAPANESE BANK SYMBOL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26FB,
+ },
+ [0x26FC]={
+ category="so",
+ cjkwd="a",
+ description="HEADSTONE GRAVEYARD SYMBOL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x26FC,
+ },
+ [0x26FD]={
+ category="so",
+ cjkwd="a",
+ description="FUEL PUMP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26FD,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x26FE]={
+ category="so",
+ cjkwd="a",
+ description="CUP ON BLACK SQUARE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26FE,
+ },
+ [0x26FF]={
+ category="so",
+ cjkwd="a",
+ description="WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x26FF,
+ },
+ [0x2701]={
+ category="so",
+ description="UPPER BLADE SCISSORS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2701,
+ },
+ [0x2702]={
+ category="so",
+ description="BLACK SCISSORS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2702,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2703]={
+ category="so",
+ description="LOWER BLADE SCISSORS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2703,
+ },
+ [0x2704]={
+ category="so",
+ description="WHITE SCISSORS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2704,
+ },
+ [0x2705]={
+ category="so",
+ description="WHITE HEAVY CHECK MARK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2705,
+ },
+ [0x2706]={
+ category="so",
+ description="TELEPHONE LOCATION SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2706,
+ },
+ [0x2707]={
+ category="so",
+ description="TAPE DRIVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2707,
+ },
+ [0x2708]={
+ category="so",
+ description="AIRPLANE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2708,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2709]={
+ category="so",
+ description="ENVELOPE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2709,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x270A]={
+ category="so",
+ description="RAISED FIST",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x270A,
+ },
+ [0x270B]={
+ category="so",
+ description="RAISED HAND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x270B,
+ },
+ [0x270C]={
+ category="so",
+ description="VICTORY HAND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x270C,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x270D]={
+ category="so",
+ description="WRITING HAND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x270D,
+ },
+ [0x270E]={
+ category="so",
+ description="LOWER RIGHT PENCIL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x270E,
+ },
+ [0x270F]={
+ category="so",
+ description="PENCIL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x270F,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2710]={
+ category="so",
+ description="UPPER RIGHT PENCIL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2710,
+ },
+ [0x2711]={
+ category="so",
+ description="WHITE NIB",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2711,
+ },
+ [0x2712]={
+ category="so",
+ description="BLACK NIB",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2712,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2713]={
+ adobename="checkmark",
+ category="so",
+ description="CHECK MARK",
+ direction="on",
+ linebreak="al",
+ mathclass="nothing",
+ mathname="checkmark",
+ unicodeslot=0x2713,
+ },
+ [0x2714]={
+ category="so",
+ description="HEAVY CHECK MARK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2714,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2715]={
+ category="so",
+ description="MULTIPLICATION X",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2715,
+ },
+ [0x2716]={
+ category="so",
+ description="HEAVY MULTIPLICATION X",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2716,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2717]={
+ category="so",
+ description="BALLOT X",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2717,
+ },
+ [0x2718]={
+ category="so",
+ description="HEAVY BALLOT X",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2718,
+ },
+ [0x2719]={
+ category="so",
+ description="OUTLINED GREEK CROSS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2719,
+ },
+ [0x271A]={
+ category="so",
+ description="HEAVY GREEK CROSS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x271A,
+ },
+ [0x271B]={
+ category="so",
+ description="OPEN CENTRE CROSS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x271B,
+ },
+ [0x271C]={
+ category="so",
+ description="HEAVY OPEN CENTRE CROSS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x271C,
+ },
+ [0x271D]={
+ category="so",
+ description="LATIN CROSS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x271D,
+ },
+ [0x271E]={
+ category="so",
+ description="SHADOWED WHITE LATIN CROSS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x271E,
+ },
+ [0x271F]={
+ category="so",
+ description="OUTLINED LATIN CROSS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x271F,
+ },
+ [0x2720]={
+ category="so",
+ description="MALTESE CROSS",
+ direction="on",
+ linebreak="al",
+ mathclass="nothing",
+ mathname="maltese",
+ unicodeslot=0x2720,
+ },
+ [0x2721]={
+ category="so",
+ description="STAR OF DAVID",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2721,
+ },
+ [0x2722]={
+ category="so",
+ description="FOUR TEARDROP-SPOKED ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2722,
+ },
+ [0x2723]={
+ category="so",
+ description="FOUR BALLOON-SPOKED ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2723,
+ },
+ [0x2724]={
+ category="so",
+ description="HEAVY FOUR BALLOON-SPOKED ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2724,
+ },
+ [0x2725]={
+ category="so",
+ description="FOUR CLUB-SPOKED ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2725,
+ },
+ [0x2726]={
+ category="so",
+ description="BLACK FOUR POINTED STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2726,
+ },
+ [0x2727]={
+ category="so",
+ description="WHITE FOUR POINTED STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2727,
+ },
+ [0x2728]={
+ category="so",
+ description="SPARKLES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2728,
+ },
+ [0x2729]={
+ category="so",
+ description="STRESS OUTLINED WHITE STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2729,
+ },
+ [0x272A]={
+ category="so",
+ description="CIRCLED WHITE STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x272A,
+ },
+ [0x272B]={
+ category="so",
+ description="OPEN CENTRE BLACK STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x272B,
+ },
+ [0x272C]={
+ category="so",
+ description="BLACK CENTRE WHITE STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x272C,
+ },
+ [0x272D]={
+ category="so",
+ description="OUTLINED BLACK STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x272D,
+ },
+ [0x272E]={
+ category="so",
+ description="HEAVY OUTLINED BLACK STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x272E,
+ },
+ [0x272F]={
+ category="so",
+ description="PINWHEEL STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x272F,
+ },
+ [0x2730]={
+ category="so",
+ description="SHADOWED WHITE STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2730,
+ },
+ [0x2731]={
+ category="so",
+ description="HEAVY ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2731,
+ },
+ [0x2732]={
+ category="so",
+ description="OPEN CENTRE ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2732,
+ },
+ [0x2733]={
+ category="so",
+ description="EIGHT SPOKED ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2733,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2734]={
+ category="so",
+ description="EIGHT POINTED BLACK STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2734,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2735]={
+ category="so",
+ description="EIGHT POINTED PINWHEEL STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2735,
+ },
+ [0x2736]={
+ category="so",
+ description="SIX POINTED BLACK STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2736,
+ },
+ [0x2737]={
+ category="so",
+ description="EIGHT POINTED RECTILINEAR BLACK STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2737,
+ },
+ [0x2738]={
+ category="so",
+ description="HEAVY EIGHT POINTED RECTILINEAR BLACK STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2738,
+ },
+ [0x2739]={
+ category="so",
+ description="TWELVE POINTED BLACK STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2739,
+ },
+ [0x273A]={
+ category="so",
+ description="SIXTEEN POINTED ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x273A,
+ },
+ [0x273B]={
+ category="so",
+ description="TEARDROP-SPOKED ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x273B,
+ },
+ [0x273C]={
+ category="so",
+ description="OPEN CENTRE TEARDROP-SPOKED ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x273C,
+ },
+ [0x273D]={
+ category="so",
+ cjkwd="a",
+ description="HEAVY TEARDROP-SPOKED ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x273D,
+ },
+ [0x273E]={
+ category="so",
+ description="SIX PETALLED BLACK AND WHITE FLORETTE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x273E,
+ },
+ [0x273F]={
+ category="so",
+ description="BLACK FLORETTE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x273F,
+ },
+ [0x2740]={
+ category="so",
+ description="WHITE FLORETTE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2740,
+ },
+ [0x2741]={
+ category="so",
+ description="EIGHT PETALLED OUTLINED BLACK FLORETTE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2741,
+ },
+ [0x2742]={
+ category="so",
+ description="CIRCLED OPEN CENTRE EIGHT POINTED STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2742,
+ },
+ [0x2743]={
+ category="so",
+ description="HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2743,
+ },
+ [0x2744]={
+ category="so",
+ description="SNOWFLAKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2744,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2745]={
+ category="so",
+ description="TIGHT TRIFOLIATE SNOWFLAKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2745,
+ },
+ [0x2746]={
+ category="so",
+ description="HEAVY CHEVRON SNOWFLAKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2746,
+ },
+ [0x2747]={
+ category="so",
+ description="SPARKLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2747,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2748]={
+ category="so",
+ description="HEAVY SPARKLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2748,
+ },
+ [0x2749]={
+ category="so",
+ description="BALLOON-SPOKED ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2749,
+ },
+ [0x274A]={
+ category="so",
+ description="EIGHT TEARDROP-SPOKED PROPELLER ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x274A,
+ },
+ [0x274B]={
+ category="so",
+ description="HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x274B,
+ },
+ [0x274C]={
+ category="so",
+ description="CROSS MARK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x274C,
+ },
+ [0x274D]={
+ category="so",
+ description="SHADOWED WHITE CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x274D,
+ },
+ [0x274E]={
+ category="so",
+ description="NEGATIVE SQUARED CROSS MARK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x274E,
+ },
+ [0x274F]={
+ category="so",
+ description="LOWER RIGHT DROP-SHADOWED WHITE SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x274F,
+ },
+ [0x2750]={
+ category="so",
+ description="UPPER RIGHT DROP-SHADOWED WHITE SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2750,
+ },
+ [0x2751]={
+ category="so",
+ description="LOWER RIGHT SHADOWED WHITE SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2751,
+ },
+ [0x2752]={
+ category="so",
+ description="UPPER RIGHT SHADOWED WHITE SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2752,
+ },
+ [0x2753]={
+ category="so",
+ description="BLACK QUESTION MARK ORNAMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2753,
+ },
+ [0x2754]={
+ category="so",
+ description="WHITE QUESTION MARK ORNAMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2754,
+ },
+ [0x2755]={
+ category="so",
+ description="WHITE EXCLAMATION MARK ORNAMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2755,
+ },
+ [0x2756]={
+ category="so",
+ description="BLACK DIAMOND MINUS WHITE X",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2756,
+ },
+ [0x2757]={
+ category="so",
+ cjkwd="a",
+ description="HEAVY EXCLAMATION MARK SYMBOL",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2757,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2758]={
+ category="so",
+ description="LIGHT VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2758,
+ },
+ [0x2759]={
+ category="so",
+ description="MEDIUM VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2759,
+ },
+ [0x275A]={
+ category="so",
+ description="HEAVY VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x275A,
+ },
+ [0x275B]={
+ category="so",
+ description="HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x275B,
+ },
+ [0x275C]={
+ category="so",
+ description="HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x275C,
+ },
+ [0x275D]={
+ category="so",
+ description="HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x275D,
+ },
+ [0x275E]={
+ category="so",
+ description="HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x275E,
+ },
+ [0x275F]={
+ category="so",
+ description="HEAVY LOW SINGLE COMMA QUOTATION MARK ORNAMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x275F,
+ },
+ [0x2760]={
+ category="so",
+ description="HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2760,
+ },
+ [0x2761]={
+ category="so",
+ description="CURVED STEM PARAGRAPH SIGN ORNAMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2761,
+ },
+ [0x2762]={
+ category="so",
+ description="HEAVY EXCLAMATION MARK ORNAMENT",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x2762,
+ },
+ [0x2763]={
+ category="so",
+ description="HEAVY HEART EXCLAMATION MARK ORNAMENT",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x2763,
+ },
+ [0x2764]={
+ category="so",
+ description="HEAVY BLACK HEART",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2764,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2765]={
+ category="so",
+ description="ROTATED HEAVY BLACK HEART BULLET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2765,
+ },
+ [0x2766]={
+ category="so",
+ description="FLORAL HEART",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2766,
+ },
+ [0x2767]={
+ category="so",
+ description="ROTATED FLORAL HEART BULLET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2767,
+ },
+ [0x2768]={
+ category="ps",
+ description="MEDIUM LEFT PARENTHESIS ORNAMENT",
+ direction="on",
+ linebreak="op",
+ mirror=0x2769,
+ unicodeslot=0x2768,
+ },
+ [0x2769]={
+ category="pe",
+ description="MEDIUM RIGHT PARENTHESIS ORNAMENT",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2768,
+ unicodeslot=0x2769,
+ },
+ [0x276A]={
+ category="ps",
+ description="MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT",
+ direction="on",
+ linebreak="op",
+ mirror=0x276B,
+ unicodeslot=0x276A,
+ },
+ [0x276B]={
+ category="pe",
+ description="MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT",
+ direction="on",
+ linebreak="cl",
+ mirror=0x276A,
+ unicodeslot=0x276B,
+ },
+ [0x276C]={
+ category="ps",
+ description="MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT",
+ direction="on",
+ linebreak="op",
+ mirror=0x276D,
+ unicodeslot=0x276C,
+ },
+ [0x276D]={
+ category="pe",
+ description="MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT",
+ direction="on",
+ linebreak="cl",
+ mirror=0x276C,
+ unicodeslot=0x276D,
+ },
+ [0x276E]={
+ category="ps",
+ description="HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT",
+ direction="on",
+ linebreak="op",
+ mirror=0x276F,
+ unicodeslot=0x276E,
+ },
+ [0x276F]={
+ category="pe",
+ description="HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT",
+ direction="on",
+ linebreak="cl",
+ mirror=0x276E,
+ unicodeslot=0x276F,
+ },
+ [0x2770]={
+ category="ps",
+ description="HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT",
+ direction="on",
+ linebreak="op",
+ mirror=0x2771,
+ unicodeslot=0x2770,
+ },
+ [0x2771]={
+ category="pe",
+ description="HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2770,
+ unicodeslot=0x2771,
+ },
+ [0x2772]={
+ category="ps",
+ description="LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT",
+ direction="on",
+ linebreak="op",
+ mirror=0x2773,
+ unicodeslot=0x2772,
+ },
+ [0x2773]={
+ category="pe",
+ description="LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2772,
+ unicodeslot=0x2773,
+ },
+ [0x2774]={
+ category="ps",
+ description="MEDIUM LEFT CURLY BRACKET ORNAMENT",
+ direction="on",
+ linebreak="op",
+ mirror=0x2775,
+ unicodeslot=0x2774,
+ },
+ [0x2775]={
+ category="pe",
+ description="MEDIUM RIGHT CURLY BRACKET ORNAMENT",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2774,
+ unicodeslot=0x2775,
+ },
+ [0x2776]={
+ category="no",
+ cjkwd="a",
+ description="DINGBAT NEGATIVE CIRCLED DIGIT ONE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2776,
+ },
+ [0x2777]={
+ category="no",
+ cjkwd="a",
+ description="DINGBAT NEGATIVE CIRCLED DIGIT TWO",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2777,
+ },
+ [0x2778]={
+ category="no",
+ cjkwd="a",
+ description="DINGBAT NEGATIVE CIRCLED DIGIT THREE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2778,
+ },
+ [0x2779]={
+ category="no",
+ cjkwd="a",
+ description="DINGBAT NEGATIVE CIRCLED DIGIT FOUR",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2779,
+ },
+ [0x277A]={
+ category="no",
+ cjkwd="a",
+ description="DINGBAT NEGATIVE CIRCLED DIGIT FIVE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x277A,
+ },
+ [0x277B]={
+ category="no",
+ cjkwd="a",
+ description="DINGBAT NEGATIVE CIRCLED DIGIT SIX",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x277B,
+ },
+ [0x277C]={
+ category="no",
+ cjkwd="a",
+ description="DINGBAT NEGATIVE CIRCLED DIGIT SEVEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x277C,
+ },
+ [0x277D]={
+ category="no",
+ cjkwd="a",
+ description="DINGBAT NEGATIVE CIRCLED DIGIT EIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x277D,
+ },
+ [0x277E]={
+ category="no",
+ cjkwd="a",
+ description="DINGBAT NEGATIVE CIRCLED DIGIT NINE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x277E,
+ },
+ [0x277F]={
+ category="no",
+ cjkwd="a",
+ description="DINGBAT NEGATIVE CIRCLED NUMBER TEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x277F,
+ },
+ [0x2780]={
+ category="no",
+ description="DINGBAT CIRCLED SANS-SERIF DIGIT ONE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2780,
+ },
+ [0x2781]={
+ category="no",
+ description="DINGBAT CIRCLED SANS-SERIF DIGIT TWO",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2781,
+ },
+ [0x2782]={
+ category="no",
+ description="DINGBAT CIRCLED SANS-SERIF DIGIT THREE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2782,
+ },
+ [0x2783]={
+ category="no",
+ description="DINGBAT CIRCLED SANS-SERIF DIGIT FOUR",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2783,
+ },
+ [0x2784]={
+ category="no",
+ description="DINGBAT CIRCLED SANS-SERIF DIGIT FIVE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2784,
+ },
+ [0x2785]={
+ category="no",
+ description="DINGBAT CIRCLED SANS-SERIF DIGIT SIX",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2785,
+ },
+ [0x2786]={
+ category="no",
+ description="DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2786,
+ },
+ [0x2787]={
+ category="no",
+ description="DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2787,
+ },
+ [0x2788]={
+ category="no",
+ description="DINGBAT CIRCLED SANS-SERIF DIGIT NINE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2788,
+ },
+ [0x2789]={
+ category="no",
+ description="DINGBAT CIRCLED SANS-SERIF NUMBER TEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2789,
+ },
+ [0x278A]={
+ adobename="onecircleinversesansserif",
+ category="no",
+ description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x278A,
+ },
+ [0x278B]={
+ adobename="twocircleinversesansserif",
+ category="no",
+ description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x278B,
+ },
+ [0x278C]={
+ adobename="threecircleinversesansserif",
+ category="no",
+ description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x278C,
+ },
+ [0x278D]={
+ adobename="fourcircleinversesansserif",
+ category="no",
+ description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x278D,
+ },
+ [0x278E]={
+ adobename="fivecircleinversesansserif",
+ category="no",
+ description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x278E,
+ },
+ [0x278F]={
+ adobename="sixcircleinversesansserif",
+ category="no",
+ description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x278F,
+ },
+ [0x2790]={
+ adobename="sevencircleinversesansserif",
+ category="no",
+ description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2790,
+ },
+ [0x2791]={
+ adobename="eightcircleinversesansserif",
+ category="no",
+ description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2791,
+ },
+ [0x2792]={
+ adobename="ninecircleinversesansserif",
+ category="no",
+ description="DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2792,
+ },
+ [0x2793]={
+ category="no",
+ description="DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2793,
+ },
+ [0x2794]={
+ category="so",
+ description="HEAVY WIDE-HEADED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2794,
+ },
+ [0x2795]={
+ category="so",
+ description="HEAVY PLUS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2795,
+ },
+ [0x2796]={
+ category="so",
+ description="HEAVY MINUS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2796,
+ },
+ [0x2797]={
+ category="so",
+ description="HEAVY DIVISION SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2797,
+ },
+ [0x2798]={
+ category="so",
+ description="HEAVY SOUTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2798,
+ },
+ [0x2799]={
+ category="so",
+ description="HEAVY RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2799,
+ },
+ [0x279A]={
+ category="so",
+ description="HEAVY NORTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x279A,
+ },
+ [0x279B]={
+ category="so",
+ description="DRAFTING POINT RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x279B,
+ },
+ [0x279C]={
+ category="so",
+ description="HEAVY ROUND-TIPPED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x279C,
+ },
+ [0x279D]={
+ category="so",
+ description="TRIANGLE-HEADED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x279D,
+ },
+ [0x279E]={
+ adobename="arrowrightheavy",
+ category="so",
+ description="HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x279E,
+ },
+ [0x279F]={
+ category="so",
+ description="DASHED TRIANGLE-HEADED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x279F,
+ },
+ [0x27A0]={
+ category="so",
+ description="HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A0,
+ },
+ [0x27A1]={
+ category="so",
+ description="BLACK RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A1,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x27A2]={
+ category="so",
+ description="THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A2,
+ },
+ [0x27A3]={
+ category="so",
+ description="THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A3,
+ },
+ [0x27A4]={
+ category="so",
+ description="BLACK RIGHTWARDS ARROWHEAD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A4,
+ },
+ [0x27A5]={
+ category="so",
+ description="HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A5,
+ },
+ [0x27A6]={
+ category="so",
+ description="HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A6,
+ },
+ [0x27A7]={
+ category="so",
+ description="SQUAT BLACK RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A7,
+ },
+ [0x27A8]={
+ category="so",
+ description="HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A8,
+ },
+ [0x27A9]={
+ category="so",
+ description="RIGHT-SHADED WHITE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27A9,
+ },
+ [0x27AA]={
+ category="so",
+ description="LEFT-SHADED WHITE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27AA,
+ },
+ [0x27AB]={
+ category="so",
+ description="BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27AB,
+ },
+ [0x27AC]={
+ category="so",
+ description="FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27AC,
+ },
+ [0x27AD]={
+ category="so",
+ description="HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27AD,
+ },
+ [0x27AE]={
+ category="so",
+ description="HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27AE,
+ },
+ [0x27AF]={
+ category="so",
+ description="NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27AF,
+ },
+ [0x27B0]={
+ category="so",
+ description="CURLY LOOP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B0,
+ },
+ [0x27B1]={
+ category="so",
+ description="NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B1,
+ },
+ [0x27B2]={
+ category="so",
+ description="CIRCLED HEAVY WHITE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B2,
+ },
+ [0x27B3]={
+ category="so",
+ description="WHITE-FEATHERED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B3,
+ },
+ [0x27B4]={
+ category="so",
+ description="BLACK-FEATHERED SOUTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B4,
+ },
+ [0x27B5]={
+ category="so",
+ description="BLACK-FEATHERED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B5,
+ },
+ [0x27B6]={
+ category="so",
+ description="BLACK-FEATHERED NORTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B6,
+ },
+ [0x27B7]={
+ category="so",
+ description="HEAVY BLACK-FEATHERED SOUTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B7,
+ },
+ [0x27B8]={
+ category="so",
+ description="HEAVY BLACK-FEATHERED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B8,
+ },
+ [0x27B9]={
+ category="so",
+ description="HEAVY BLACK-FEATHERED NORTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27B9,
+ },
+ [0x27BA]={
+ category="so",
+ description="TEARDROP-BARBED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27BA,
+ },
+ [0x27BB]={
+ category="so",
+ description="HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27BB,
+ },
+ [0x27BC]={
+ category="so",
+ description="WEDGE-TAILED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27BC,
+ },
+ [0x27BD]={
+ category="so",
+ description="HEAVY WEDGE-TAILED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27BD,
+ },
+ [0x27BE]={
+ category="so",
+ description="OPEN-OUTLINED RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27BE,
+ },
+ [0x27BF]={
+ category="so",
+ description="DOUBLE CURLY LOOP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27BF,
+ },
+ [0x27C0]={
+ category="sm",
+ description="THREE DIMENSIONAL ANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27C0,
+ },
+ [0x27C1]={
+ category="sm",
+ description="WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27C1,
+ },
+ [0x27C2]={
+ category="sm",
+ description="PERPENDICULAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27C2,
+ },
+ [0x27C3]={
+ category="sm",
+ description="OPEN SUBSET",
+ direction="on",
+ linebreak="al",
+ mirror=0x27C4,
+ unicodeslot=0x27C3,
+ },
+ [0x27C4]={
+ category="sm",
+ description="OPEN SUPERSET",
+ direction="on",
+ linebreak="al",
+ mirror=0x27C3,
+ unicodeslot=0x27C4,
+ },
+ [0x27C5]={
+ category="ps",
+ description="LEFT S-SHAPED BAG DELIMITER",
+ direction="on",
+ linebreak="op",
+ mirror=0x27C6,
+ unicodeslot=0x27C5,
+ },
+ [0x27C6]={
+ category="pe",
+ description="RIGHT S-SHAPED BAG DELIMITER",
+ direction="on",
+ linebreak="cl",
+ mirror=0x27C5,
+ unicodeslot=0x27C6,
+ },
+ [0x27C7]={
+ category="sm",
+ description="OR WITH DOT INSIDE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27C7,
+ },
+ [0x27C8]={
+ category="sm",
+ description="REVERSE SOLIDUS PRECEDING SUBSET",
+ direction="on",
+ linebreak="al",
+ mirror=0x27C9,
+ unicodeslot=0x27C8,
+ },
+ [0x27C9]={
+ category="sm",
+ description="SUPERSET PRECEDING SOLIDUS",
+ direction="on",
+ linebreak="al",
+ mirror=0x27C8,
+ unicodeslot=0x27C9,
+ },
+ [0x27CA]={
+ category="sm",
+ description="VERTICAL BAR WITH HORIZONTAL STROKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27CA,
+ },
+ [0x27CB]={
+ category="sm",
+ comment="check math properties",
+ description="MATHEMATICAL RISING DIAGONAL",
+ direction="on",
+ linebreak="al",
+ mirror=0x27CD,
+ unicodeslot=0x27CB,
+ },
+ [0x27CC]={
+ category="sm",
+ description="LONG DIVISION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27CC,
+ },
+ [0x27CD]={
+ category="sm",
+ comment="check math properties",
+ description="MATHEMATICAL FALLING DIAGONAL",
+ direction="on",
+ linebreak="al",
+ mirror=0x27CB,
+ unicodeslot=0x27CD,
+ },
+ [0x27CE]={
+ category="sm",
+ description="SQUARED LOGICAL AND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27CE,
+ },
+ [0x27CF]={
+ category="sm",
+ description="SQUARED LOGICAL OR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27CF,
+ },
+ [0x27D0]={
+ category="sm",
+ description="WHITE DIAMOND WITH CENTRED DOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D0,
+ },
+ [0x27D1]={
+ category="sm",
+ description="AND WITH DOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D1,
+ },
+ [0x27D2]={
+ category="sm",
+ description="ELEMENT OF OPENING UPWARDS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D2,
+ },
+ [0x27D3]={
+ category="sm",
+ description="LOWER RIGHT CORNER WITH DOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D3,
+ },
+ [0x27D4]={
+ category="sm",
+ description="UPPER LEFT CORNER WITH DOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D4,
+ },
+ [0x27D5]={
+ category="sm",
+ description="LEFT OUTER JOIN",
+ direction="on",
+ linebreak="al",
+ mirror=0x27D6,
+ unicodeslot=0x27D5,
+ },
+ [0x27D6]={
+ category="sm",
+ description="RIGHT OUTER JOIN",
+ direction="on",
+ linebreak="al",
+ mirror=0x27D5,
+ unicodeslot=0x27D6,
+ },
+ [0x27D7]={
+ category="sm",
+ description="FULL OUTER JOIN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D7,
+ },
+ [0x27D8]={
+ category="sm",
+ description="LARGE UP TACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D8,
+ },
+ [0x27D9]={
+ category="sm",
+ description="LARGE DOWN TACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27D9,
+ },
+ [0x27DA]={
+ category="sm",
+ description="LEFT AND RIGHT DOUBLE TURNSTILE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27DA,
+ },
+ [0x27DB]={
+ category="sm",
+ description="LEFT AND RIGHT TACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27DB,
+ },
+ [0x27DC]={
+ category="sm",
+ description="LEFT MULTIMAP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27DC,
+ },
+ [0x27DD]={
+ category="sm",
+ description="LONG RIGHT TACK",
+ direction="on",
+ linebreak="al",
+ mirror=0x27DE,
+ unicodeslot=0x27DD,
+ },
+ [0x27DE]={
+ category="sm",
+ description="LONG LEFT TACK",
+ direction="on",
+ linebreak="al",
+ mirror=0x27DD,
+ unicodeslot=0x27DE,
+ },
+ [0x27DF]={
+ category="sm",
+ description="UP TACK WITH CIRCLE ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27DF,
+ },
+ [0x27E0]={
+ category="sm",
+ description="LOZENGE DIVIDED BY HORIZONTAL RULE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27E0,
+ },
+ [0x27E1]={
+ category="sm",
+ description="WHITE CONCAVE-SIDED DIAMOND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27E1,
+ },
+ [0x27E2]={
+ category="sm",
+ description="WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK",
+ direction="on",
+ linebreak="al",
+ mirror=0x27E3,
+ unicodeslot=0x27E2,
+ },
+ [0x27E3]={
+ category="sm",
+ description="WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK",
+ direction="on",
+ linebreak="al",
+ mirror=0x27E2,
+ unicodeslot=0x27E3,
+ },
+ [0x27E4]={
+ category="sm",
+ description="WHITE SQUARE WITH LEFTWARDS TICK",
+ direction="on",
+ linebreak="al",
+ mirror=0x27E5,
+ unicodeslot=0x27E4,
+ },
+ [0x27E5]={
+ category="sm",
+ description="WHITE SQUARE WITH RIGHTWARDS TICK",
+ direction="on",
+ linebreak="al",
+ mirror=0x27E4,
+ unicodeslot=0x27E5,
+ },
+ [0x27E6]={
+ category="ps",
+ cjkwd="na",
+ description="MATHEMATICAL LEFT WHITE SQUARE BRACKET",
+ direction="on",
+ linebreak="op",
+ mathclass="open",
+ mathname="llbracket",
+ mirror=0x27E7,
+ unicodeslot=0x27E6,
+ },
+ [0x27E7]={
+ category="pe",
+ cjkwd="na",
+ description="MATHEMATICAL RIGHT WHITE SQUARE BRACKET",
+ direction="on",
+ linebreak="cl",
+ mathclass="close",
+ mathname="rrbracket",
+ mirror=0x27E6,
+ unicodeslot=0x27E7,
+ },
+ [0x27E8]={
+ category="ps",
+ cjkwd="na",
+ description="MATHEMATICAL LEFT ANGLE BRACKET",
+ direction="on",
+ linebreak="op",
+ mathclass="open",
+ mathname="langle",
+ mirror=0x27E9,
+ unicodeslot=0x27E8,
+ },
+ [0x27E9]={
+ category="pe",
+ cjkwd="na",
+ description="MATHEMATICAL RIGHT ANGLE BRACKET",
+ direction="on",
+ linebreak="cl",
+ mathclass="close",
+ mathname="rangle",
+ mirror=0x27E8,
+ unicodeslot=0x27E9,
+ },
+ [0x27EA]={
+ category="ps",
+ cjkwd="na",
+ description="MATHEMATICAL LEFT DOUBLE ANGLE BRACKET",
+ direction="on",
+ linebreak="op",
+ mathclass="open",
+ mathname="llangle",
+ mirror=0x27EB,
+ unicodeslot=0x27EA,
+ },
+ [0x27EB]={
+ category="pe",
+ cjkwd="na",
+ description="MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET",
+ direction="on",
+ linebreak="cl",
+ mathclass="close",
+ mathname="rrangle",
+ mirror=0x27EA,
+ unicodeslot=0x27EB,
+ },
+ [0x27EC]={
+ category="ps",
+ cjkwd="na",
+ description="MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x27ED,
+ unicodeslot=0x27EC,
+ },
+ [0x27ED]={
+ category="pe",
+ cjkwd="na",
+ description="MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x27EC,
+ unicodeslot=0x27ED,
+ },
+ [0x27EE]={
+ category="ps",
+ description="MATHEMATICAL LEFT FLATTENED PARENTHESIS",
+ direction="on",
+ linebreak="op",
+ mathclass="open",
+ mathname="lgroup",
+ mirror=0x27EF,
+ unicodeslot=0x27EE,
+ },
+ [0x27EF]={
+ category="pe",
+ description="MATHEMATICAL RIGHT FLATTENED PARENTHESIS",
+ direction="on",
+ linebreak="cl",
+ mathclass="close",
+ mathname="rgroup",
+ mirror=0x27EE,
+ unicodeslot=0x27EF,
+ },
+ [0x27F0]={
+ category="sm",
+ description="UPWARDS QUADRUPLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="u",
+ unicodeslot=0x27F0,
+ },
+ [0x27F1]={
+ category="sm",
+ description="DOWNWARDS QUADRUPLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="v",
+ unicodeslot=0x27F1,
+ },
+ [0x27F2]={
+ category="sm",
+ description="ANTICLOCKWISE GAPPED CIRCLE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27F2,
+ },
+ [0x27F3]={
+ category="sm",
+ description="CLOCKWISE GAPPED CIRCLE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x27F3,
+ },
+ [0x27F4]={
+ category="sm",
+ description="RIGHT ARROW WITH CIRCLED PLUS",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x27F4,
+ },
+ [0x27F5]={
+ category="sm",
+ description="LONG LEFTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="longleftarrow",
+ unicodeslot=0x27F5,
+ },
+ [0x27F6]={
+ category="sm",
+ comment="the parent hack is needed for mathml",
+ description="LONG RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathfiller="rightarrowfill",
+ mathname="longrightarrow",
+ mathparent=0x2192,
+ unicodeslot=0x27F6,
+ },
+ [0x27F7]={
+ category="sm",
+ comment="the parent hack is needed for mathml",
+ description="LONG LEFT RIGHT ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathfiller="leftrightarrowfill",
+ mathname="longleftrightarrow",
+ mathparent=0x2190,
+ unicodeslot=0x27F7,
+ },
+ [0x27F8]={
+ category="sm",
+ description="LONG LEFTWARDS DOUBLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathfiller="Leftarrowfill",
+ mathname="Longleftarrow",
+ unicodeslot=0x27F8,
+ },
+ [0x27F9]={
+ category="sm",
+ description="LONG RIGHTWARDS DOUBLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathfiller="Rightarrowfill",
+ mathname="Longrightarrow",
+ unicodeslot=0x27F9,
+ },
+ [0x27FA]={
+ category="sm",
+ description="LONG LEFT RIGHT DOUBLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="h",
+ mathfiller="Leftrightarrowfill",
+ mathname="Longleftrightarrow",
+ unicodeslot=0x27FA,
+ },
+ [0x27FB]={
+ category="sm",
+ description="LONG LEFTWARDS ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="longmapsfrom",
+ unicodeslot=0x27FB,
+ },
+ [0x27FC]={
+ category="sm",
+ description="LONG RIGHTWARDS ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="longmapsto",
+ unicodeslot=0x27FC,
+ },
+ [0x27FD]={
+ category="sm",
+ description="LONG LEFTWARDS DOUBLE ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="Longmapsfrom",
+ unicodeslot=0x27FD,
+ },
+ [0x27FE]={
+ category="sm",
+ description="LONG RIGHTWARDS DOUBLE ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="Longmapsto",
+ unicodeslot=0x27FE,
+ },
+ [0x27FF]={
+ category="sm",
+ description="LONG RIGHTWARDS SQUIGGLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="longrightsquigarrow",
+ unicodeslot=0x27FF,
+ },
+ [0x2800]={
+ category="so",
+ description="BRAILLE PATTERN BLANK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2800,
+ },
+ [0x2801]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2801,
+ },
+ [0x2802]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2802,
+ },
+ [0x2803]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x000C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2803,
+ },
+ [0x2804]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2804,
+ },
+ [0x2805]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x000D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2805,
+ },
+ [0x2806]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2806,
+ },
+ [0x2807]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x007B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2807,
+ },
+ [0x2808]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2808,
+ },
+ [0x2809]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x000E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2809,
+ },
+ [0x280A]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280A,
+ },
+ [0x280B]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x007C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280B,
+ },
+ [0x280C]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280C,
+ },
+ [0x280D]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0086",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280D,
+ },
+ [0x280E]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x00EA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280E,
+ },
+ [0x280F]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04D2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x280F,
+ },
+ [0x2810]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2810,
+ },
+ [0x2811]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x000F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2811,
+ },
+ [0x2812]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2812,
+ },
+ [0x2813]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x007D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2813,
+ },
+ [0x2814]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2814,
+ },
+ [0x2815]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0087",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2815,
+ },
+ [0x2816]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x00EB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2816,
+ },
+ [0x2817]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04D3",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2817,
+ },
+ [0x2818]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x002D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2818,
+ },
+ [0x2819]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0091",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2819,
+ },
+ [0x281A]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x00F5",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281A,
+ },
+ [0x281B]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04DD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281B,
+ },
+ [0x281C]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0159",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281C,
+ },
+ [0x281D]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0541",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281D,
+ },
+ [0x281E]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0929",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281E,
+ },
+ [0x281F]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3039",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x281F,
+ },
+ [0x2820]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2820,
+ },
+ [0x2821]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2821,
+ },
+ [0x2822]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x001A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2822,
+ },
+ [0x2823]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x007E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2823,
+ },
+ [0x2824]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2824,
+ },
+ [0x2825]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0088",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2825,
+ },
+ [0x2826]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x00EC",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2826,
+ },
+ [0x2827]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04D4",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2827,
+ },
+ [0x2828]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x002E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2828,
+ },
+ [0x2829]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0092",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2829,
+ },
+ [0x282A]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x00F6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282A,
+ },
+ [0x282B]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04DE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282B,
+ },
+ [0x282C]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x015A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282C,
+ },
+ [0x282D]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0542",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282D,
+ },
+ [0x282E]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x092A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282E,
+ },
+ [0x282F]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x303A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x282F,
+ },
+ [0x2830]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2830,
+ },
+ [0x2831]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x009C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2831,
+ },
+ [0x2832]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0100",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2832,
+ },
+ [0x2833]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04E8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2833,
+ },
+ [0x2834]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0164",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2834,
+ },
+ [0x2835]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x054C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2835,
+ },
+ [0x2836]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0934",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2836,
+ },
+ [0x2837]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3044",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2837,
+ },
+ [0x2838]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x01C8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2838,
+ },
+ [0x2839]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x05B0",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2839,
+ },
+ [0x283A]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0998",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283A,
+ },
+ [0x283B]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x30A8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283B,
+ },
+ [0x283C]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0D80",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283C,
+ },
+ [0x283D]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3490",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283D,
+ },
+ [0x283E]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5BA0",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283E,
+ },
+ [0x283F]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E240",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x283F,
+ },
+ [0x2840]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2840,
+ },
+ [0x2841]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2841,
+ },
+ [0x2842]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x001B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2842,
+ },
+ [0x2843]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x007F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2843,
+ },
+ [0x2844]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2844,
+ },
+ [0x2845]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0089",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2845,
+ },
+ [0x2846]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x00ED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2846,
+ },
+ [0x2847]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04D5",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2847,
+ },
+ [0x2848]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x002F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2848,
+ },
+ [0x2849]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0093",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2849,
+ },
+ [0x284A]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x00F7",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284A,
+ },
+ [0x284B]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04DF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284B,
+ },
+ [0x284C]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x015B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284C,
+ },
+ [0x284D]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0543",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284D,
+ },
+ [0x284E]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x092B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284E,
+ },
+ [0x284F]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x303B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x284F,
+ },
+ [0x2850]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0039",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2850,
+ },
+ [0x2851]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x009D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2851,
+ },
+ [0x2852]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0101",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2852,
+ },
+ [0x2853]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04E9",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2853,
+ },
+ [0x2854]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0165",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2854,
+ },
+ [0x2855]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x054D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2855,
+ },
+ [0x2856]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0935",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2856,
+ },
+ [0x2857]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3045",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2857,
+ },
+ [0x2858]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x01C9",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2858,
+ },
+ [0x2859]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x05B1",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2859,
+ },
+ [0x285A]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0999",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285A,
+ },
+ [0x285B]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x30A9",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285B,
+ },
+ [0x285C]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0D81",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285C,
+ },
+ [0x285D]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3491",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285D,
+ },
+ [0x285E]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5BA1",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285E,
+ },
+ [0x285F]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E241",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x285F,
+ },
+ [0x2860]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0043",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2860,
+ },
+ [0x2861]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x00A7",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2861,
+ },
+ [0x2862]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x010B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2862,
+ },
+ [0x2863]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04F3",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2863,
+ },
+ [0x2864]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x016F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2864,
+ },
+ [0x2865]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0557",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2865,
+ },
+ [0x2866]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x093F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2866,
+ },
+ [0x2867]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x304F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2867,
+ },
+ [0x2868]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x01D3",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2868,
+ },
+ [0x2869]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x05BB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2869,
+ },
+ [0x286A]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x09A3",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286A,
+ },
+ [0x286B]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x30B3",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286B,
+ },
+ [0x286C]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0D8B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286C,
+ },
+ [0x286D]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x349B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286D,
+ },
+ [0x286E]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5BAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286E,
+ },
+ [0x286F]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E24B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x286F,
+ },
+ [0x2870]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0237",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2870,
+ },
+ [0x2871]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x061F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2871,
+ },
+ [0x2872]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0A07",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2872,
+ },
+ [0x2873]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3117",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2873,
+ },
+ [0x2874]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0DEF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2874,
+ },
+ [0x2875]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x34FF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2875,
+ },
+ [0x2876]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5C0F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2876,
+ },
+ [0x2877]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E2AF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2877,
+ },
+ [0x2878]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x11D7",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2878,
+ },
+ [0x2879]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x38E7",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2879,
+ },
+ [0x287A]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5FF7",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287A,
+ },
+ [0x287B]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E697",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287B,
+ },
+ [0x287C]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x8707",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287C,
+ },
+ [0x287D]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x20DA7",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287D,
+ },
+ [0x287E]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x39447",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287E,
+ },
+ [0x287F]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x12D687",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x287F,
+ },
+ [0x2880]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2880,
+ },
+ [0x2881]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2881,
+ },
+ [0x2882]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x001C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2882,
+ },
+ [0x2883]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0080",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2883,
+ },
+ [0x2884]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2884,
+ },
+ [0x2885]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x008A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2885,
+ },
+ [0x2886]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x00EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2886,
+ },
+ [0x2887]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04D6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2887,
+ },
+ [0x2888]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2888,
+ },
+ [0x2889]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0094",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2889,
+ },
+ [0x288A]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x00F8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288A,
+ },
+ [0x288B]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04E0",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288B,
+ },
+ [0x288C]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x015C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288C,
+ },
+ [0x288D]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0544",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288D,
+ },
+ [0x288E]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x092C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288E,
+ },
+ [0x288F]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x303C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x288F,
+ },
+ [0x2890]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x003A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2890,
+ },
+ [0x2891]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x009E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2891,
+ },
+ [0x2892]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0102",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2892,
+ },
+ [0x2893]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04EA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2893,
+ },
+ [0x2894]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0166",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2894,
+ },
+ [0x2895]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x054E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2895,
+ },
+ [0x2896]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0936",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2896,
+ },
+ [0x2897]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3046",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2897,
+ },
+ [0x2898]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x01CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2898,
+ },
+ [0x2899]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x05B2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2899,
+ },
+ [0x289A]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x099A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289A,
+ },
+ [0x289B]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x30AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289B,
+ },
+ [0x289C]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0D82",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289C,
+ },
+ [0x289D]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3492",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289D,
+ },
+ [0x289E]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5BA2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289E,
+ },
+ [0x289F]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E242",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x289F,
+ },
+ [0x28A0]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0044",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A0,
+ },
+ [0x28A1]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x00A8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A1,
+ },
+ [0x28A2]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x010C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A2,
+ },
+ [0x28A3]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04F4",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A3,
+ },
+ [0x28A4]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0170",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A4,
+ },
+ [0x28A5]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0558",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A5,
+ },
+ [0x28A6]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0940",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A6,
+ },
+ [0x28A7]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3050",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A7,
+ },
+ [0x28A8]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x01D4",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A8,
+ },
+ [0x28A9]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x05BC",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28A9,
+ },
+ [0x28AA]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x09A4",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28AA,
+ },
+ [0x28AB]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x30B4",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28AB,
+ },
+ [0x28AC]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0D8C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28AC,
+ },
+ [0x28AD]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x349C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28AD,
+ },
+ [0x28AE]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5BAC",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28AE,
+ },
+ [0x28AF]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E24C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28AF,
+ },
+ [0x28B0]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0238",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B0,
+ },
+ [0x28B1]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0620",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B1,
+ },
+ [0x28B2]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0A08",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B2,
+ },
+ [0x28B3]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3118",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B3,
+ },
+ [0x28B4]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0DF0",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B4,
+ },
+ [0x28B5]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3500",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B5,
+ },
+ [0x28B6]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5C10",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B6,
+ },
+ [0x28B7]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E2B0",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B7,
+ },
+ [0x28B8]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x11D8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B8,
+ },
+ [0x28B9]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x38E8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28B9,
+ },
+ [0x28BA]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5FF8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28BA,
+ },
+ [0x28BB]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E698",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28BB,
+ },
+ [0x28BC]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x8708",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28BC,
+ },
+ [0x28BD]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x20DA8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28BD,
+ },
+ [0x28BE]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x39448",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28BE,
+ },
+ [0x28BF]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x12D688",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28BF,
+ },
+ [0x28C0]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x004E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C0,
+ },
+ [0x28C1]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x00B2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C1,
+ },
+ [0x28C2]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0116",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C2,
+ },
+ [0x28C3]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x04FE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C3,
+ },
+ [0x28C4]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x017A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C4,
+ },
+ [0x28C5]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0562",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C5,
+ },
+ [0x28C6]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x094A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C6,
+ },
+ [0x28C7]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x305A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C7,
+ },
+ [0x28C8]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x01DE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C8,
+ },
+ [0x28C9]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x05C6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28C9,
+ },
+ [0x28CA]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x09AE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28CA,
+ },
+ [0x28CB]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x30BE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28CB,
+ },
+ [0x28CC]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0D96",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28CC,
+ },
+ [0x28CD]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x34A6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28CD,
+ },
+ [0x28CE]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5BB6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28CE,
+ },
+ [0x28CF]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E256",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28CF,
+ },
+ [0x28D0]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0242",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D0,
+ },
+ [0x28D1]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x062A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D1,
+ },
+ [0x28D2]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0A12",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D2,
+ },
+ [0x28D3]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3122",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D3,
+ },
+ [0x28D4]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0DFA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D4,
+ },
+ [0x28D5]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x350A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D5,
+ },
+ [0x28D6]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5C1A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D6,
+ },
+ [0x28D7]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E2BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D7,
+ },
+ [0x28D8]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x11E2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D8,
+ },
+ [0x28D9]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x38F2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28D9,
+ },
+ [0x28DA]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x6002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28DA,
+ },
+ [0x28DB]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E6A2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28DB,
+ },
+ [0x28DC]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x8712",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28DC,
+ },
+ [0x28DD]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x20DB2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28DD,
+ },
+ [0x28DE]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x39452",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28DE,
+ },
+ [0x28DF]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x12D692",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28DF,
+ },
+ [0x28E0]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x02A6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E0,
+ },
+ [0x28E1]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x068E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E1,
+ },
+ [0x28E2]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0A76",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E2,
+ },
+ [0x28E3]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3186",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E3,
+ },
+ [0x28E4]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x0E5E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E4,
+ },
+ [0x28E5]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x356E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E5,
+ },
+ [0x28E6]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5C7E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E6,
+ },
+ [0x28E7]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E31E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E7,
+ },
+ [0x28E8]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1246",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E8,
+ },
+ [0x28E9]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3956",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28E9,
+ },
+ [0x28EA]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x6066",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28EA,
+ },
+ [0x28EB]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1E706",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28EB,
+ },
+ [0x28EC]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x8776",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28EC,
+ },
+ [0x28ED]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x20E16",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28ED,
+ },
+ [0x28EE]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x394B6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28EE,
+ },
+ [0x28EF]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x12D6F6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28EF,
+ },
+ [0x28F0]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x162E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F0,
+ },
+ [0x28F1]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3D3E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F1,
+ },
+ [0x28F2]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x644E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F2,
+ },
+ [0x28F3]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1EAEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F3,
+ },
+ [0x28F4]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x8B5E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F4,
+ },
+ [0x28F5]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x211FE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F5,
+ },
+ [0x28F6]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3989E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F6,
+ },
+ [0x28F7]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x12DADE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F7,
+ },
+ [0x28F8]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0xB26E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F8,
+ },
+ [0x28F9]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x2390E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28F9,
+ },
+ [0x28FA]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x3BFAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28FA,
+ },
+ [0x28FB]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x1301EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28FB,
+ },
+ [0x28FC]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x5464E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28FC,
+ },
+ [0x28FD]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x14888E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28FD,
+ },
+ [0x28FE]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0x23CACE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28FE,
+ },
+ [0x28FF]={
+ category="so",
+ description="BRAILLE PATTERN DOTS-0xBC614E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x28FF,
+ },
+ [0x2900]={
+ category="sm",
+ description="RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2900,
+ },
+ [0x2901]={
+ category="sm",
+ description="RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2901,
+ },
+ [0x2902]={
+ category="sm",
+ description="LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2902,
+ },
+ [0x2903]={
+ category="sm",
+ description="RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2903,
+ },
+ [0x2904]={
+ category="sm",
+ description="LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="h",
+ unicodeslot=0x2904,
+ },
+ [0x2905]={
+ category="sm",
+ description="RIGHTWARDS TWO-HEADED ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2905,
+ },
+ [0x2906]={
+ category="sm",
+ description="LEFTWARDS DOUBLE ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="Mapsfrom",
+ unicodeslot=0x2906,
+ },
+ [0x2907]={
+ category="sm",
+ description="RIGHTWARDS DOUBLE ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="Mapsto",
+ unicodeslot=0x2907,
+ },
+ [0x2908]={
+ category="sm",
+ description="DOWNWARDS ARROW WITH HORIZONTAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="d",
+ unicodeslot=0x2908,
+ },
+ [0x2909]={
+ category="sm",
+ description="UPWARDS ARROW WITH HORIZONTAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="u",
+ unicodeslot=0x2909,
+ },
+ [0x290A]={
+ category="sm",
+ description="UPWARDS TRIPLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="u",
+ mathname="Uuparrow",
+ unicodeslot=0x290A,
+ },
+ [0x290B]={
+ category="sm",
+ description="DOWNWARDS TRIPLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="d",
+ mathname="Ddownarrow",
+ unicodeslot=0x290B,
+ },
+ [0x290C]={
+ category="sm",
+ description="LEFTWARDS DOUBLE DASH ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="l",
+ mathname="dashedleftarrow",
+ unicodeslot=0x290C,
+ },
+ [0x290D]={
+ category="sm",
+ description="RIGHTWARDS DOUBLE DASH ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="dashedrightarrow",
+ unicodeslot=0x290D,
+ },
+ [0x290E]={
+ category="sm",
+ description="LEFTWARDS TRIPLE DASH ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x290E,
+ },
+ [0x290F]={
+ category="sm",
+ description="RIGHTWARDS TRIPLE DASH ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x290F,
+ },
+ [0x2910]={
+ category="sm",
+ description="RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2910,
+ },
+ [0x2911]={
+ category="sm",
+ description="RIGHTWARDS ARROW WITH DOTTED STEM",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="dottedrightarrow",
+ unicodeslot=0x2911,
+ },
+ [0x2912]={
+ category="sm",
+ description="UPWARDS ARROW TO BAR",
+ direction="on",
+ linebreak="al",
+ mathextensible="u",
+ unicodeslot=0x2912,
+ },
+ [0x2913]={
+ category="sm",
+ description="DOWNWARDS ARROW TO BAR",
+ direction="on",
+ linebreak="al",
+ mathextensible="d",
+ unicodeslot=0x2913,
+ },
+ [0x2914]={
+ category="sm",
+ description="RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2914,
+ },
+ [0x2915]={
+ category="sm",
+ description="RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2915,
+ },
+ [0x2916]={
+ category="sm",
+ description="RIGHTWARDS TWO-HEADED ARROW WITH TAIL",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ mathname="twoheadrightarrowtail",
+ unicodeslot=0x2916,
+ },
+ [0x2917]={
+ category="sm",
+ description="RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathextensible="r",
+ unicodeslot=0x2917,
+ },
+ [0x2918]={
+ category="sm",
+ description="RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2918,
+ },
+ [0x2919]={
+ category="sm",
+ description="LEFTWARDS ARROW-TAIL",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2919,
+ },
+ [0x291A]={
+ category="sm",
+ description="RIGHTWARDS ARROW-TAIL",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x291A,
+ },
+ [0x291B]={
+ category="sm",
+ description="LEFTWARDS DOUBLE ARROW-TAIL",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x291B,
+ },
+ [0x291C]={
+ category="sm",
+ description="RIGHTWARDS DOUBLE ARROW-TAIL",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x291C,
+ },
+ [0x291D]={
+ category="sm",
+ description="LEFTWARDS ARROW TO BLACK DIAMOND",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x291D,
+ },
+ [0x291E]={
+ category="sm",
+ description="RIGHTWARDS ARROW TO BLACK DIAMOND",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x291E,
+ },
+ [0x291F]={
+ category="sm",
+ description="LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x291F,
+ },
+ [0x2920]={
+ category="sm",
+ description="RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2920,
+ },
+ [0x2921]={
+ category="sm",
+ description="NORTH WEST AND SOUTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="nwsearrow",
+ unicodeslot=0x2921,
+ },
+ [0x2922]={
+ category="sm",
+ description="NORTH EAST AND SOUTH WEST ARROW",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="neswarrow",
+ unicodeslot=0x2922,
+ },
+ [0x2923]={
+ category="sm",
+ description="NORTH WEST ARROW WITH HOOK",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="lhooknwarrow",
+ unicodeslot=0x2923,
+ },
+ [0x2924]={
+ category="sm",
+ description="NORTH EAST ARROW WITH HOOK",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="rhooknearrow",
+ unicodeslot=0x2924,
+ },
+ [0x2925]={
+ category="sm",
+ description="SOUTH EAST ARROW WITH HOOK",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="lhooksearrow",
+ unicodeslot=0x2925,
+ },
+ [0x2926]={
+ category="sm",
+ description="SOUTH WEST ARROW WITH HOOK",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="rhookswarrow",
+ unicodeslot=0x2926,
+ },
+ [0x2927]={
+ category="sm",
+ description="NORTH WEST ARROW AND NORTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2927,
+ },
+ [0x2928]={
+ category="sm",
+ description="NORTH EAST ARROW AND SOUTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2928,
+ },
+ [0x2929]={
+ category="sm",
+ description="SOUTH EAST ARROW AND SOUTH WEST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2929,
+ },
+ [0x292A]={
+ category="sm",
+ description="SOUTH WEST ARROW AND NORTH WEST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x292A,
+ },
+ [0x292B]={
+ category="sm",
+ description="RISING DIAGONAL CROSSING FALLING DIAGONAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x292B,
+ },
+ [0x292C]={
+ category="sm",
+ description="FALLING DIAGONAL CROSSING RISING DIAGONAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x292C,
+ },
+ [0x292D]={
+ category="sm",
+ description="SOUTH EAST ARROW CROSSING NORTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x292D,
+ },
+ [0x292E]={
+ category="sm",
+ description="NORTH EAST ARROW CROSSING SOUTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x292E,
+ },
+ [0x292F]={
+ category="sm",
+ description="FALLING DIAGONAL CROSSING NORTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x292F,
+ },
+ [0x2930]={
+ category="sm",
+ description="RISING DIAGONAL CROSSING SOUTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2930,
+ },
+ [0x2931]={
+ category="sm",
+ description="NORTH EAST ARROW CROSSING NORTH WEST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2931,
+ },
+ [0x2932]={
+ category="sm",
+ description="NORTH WEST ARROW CROSSING NORTH EAST ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2932,
+ },
+ [0x2933]={
+ category="sm",
+ description="WAVE ARROW POINTING DIRECTLY RIGHT",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2933,
+ },
+ [0x2934]={
+ category="sm",
+ description="ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS",
+ direction="on",
+ linebreak="al",
+ mathextensible="m",
+ unicodeslot=0x2934,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2935]={
+ category="sm",
+ description="ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS",
+ direction="on",
+ linebreak="al",
+ mathextensible="m",
+ unicodeslot=0x2935,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2936]={
+ category="sm",
+ description="ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS",
+ direction="on",
+ linebreak="al",
+ mathextensible="m",
+ unicodeslot=0x2936,
+ },
+ [0x2937]={
+ category="sm",
+ description="ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS",
+ direction="on",
+ linebreak="al",
+ mathextensible="m",
+ unicodeslot=0x2937,
+ },
+ [0x2938]={
+ category="sm",
+ description="RIGHT-SIDE ARC CLOCKWISE ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2938,
+ },
+ [0x2939]={
+ category="sm",
+ description="LEFT-SIDE ARC ANTICLOCKWISE ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2939,
+ },
+ [0x293A]={
+ category="sm",
+ description="TOP ARC ANTICLOCKWISE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x293A,
+ },
+ [0x293B]={
+ category="sm",
+ description="BOTTOM ARC ANTICLOCKWISE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x293B,
+ },
+ [0x293C]={
+ category="sm",
+ description="TOP ARC CLOCKWISE ARROW WITH MINUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x293C,
+ },
+ [0x293D]={
+ category="sm",
+ description="TOP ARC ANTICLOCKWISE ARROW WITH PLUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x293D,
+ },
+ [0x293E]={
+ category="sm",
+ description="LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x293E,
+ },
+ [0x293F]={
+ category="sm",
+ description="LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x293F,
+ },
+ [0x2940]={
+ category="sm",
+ description="ANTICLOCKWISE CLOSED CIRCLE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2940,
+ },
+ [0x2941]={
+ category="sm",
+ description="CLOCKWISE CLOSED CIRCLE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2941,
+ },
+ [0x2942]={
+ category="sm",
+ description="RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2942,
+ },
+ [0x2943]={
+ category="sm",
+ description="LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2943,
+ },
+ [0x2944]={
+ category="sm",
+ description="SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2944,
+ },
+ [0x2945]={
+ category="sm",
+ description="RIGHTWARDS ARROW WITH PLUS BELOW",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2945,
+ },
+ [0x2946]={
+ category="sm",
+ description="LEFTWARDS ARROW WITH PLUS BELOW",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2946,
+ },
+ [0x2947]={
+ category="sm",
+ description="RIGHTWARDS ARROW THROUGH X",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2947,
+ },
+ [0x2948]={
+ category="sm",
+ description="LEFT RIGHT ARROW THROUGH SMALL CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2948,
+ },
+ [0x2949]={
+ category="sm",
+ description="UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE",
+ direction="on",
+ linebreak="al",
+ mathextensible="u",
+ unicodeslot=0x2949,
+ },
+ [0x294A]={
+ category="sm",
+ description="LEFT BARB UP RIGHT BARB DOWN HARPOON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x294A,
+ },
+ [0x294B]={
+ category="sm",
+ description="LEFT BARB DOWN RIGHT BARB UP HARPOON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x294B,
+ },
+ [0x294C]={
+ category="sm",
+ description="UP BARB RIGHT DOWN BARB LEFT HARPOON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x294C,
+ },
+ [0x294D]={
+ category="sm",
+ description="UP BARB LEFT DOWN BARB RIGHT HARPOON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x294D,
+ },
+ [0x294E]={
+ category="sm",
+ description="LEFT BARB UP RIGHT BARB UP HARPOON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x294E,
+ },
+ [0x294F]={
+ category="sm",
+ description="UP BARB RIGHT DOWN BARB RIGHT HARPOON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x294F,
+ },
+ [0x2950]={
+ category="sm",
+ description="LEFT BARB DOWN RIGHT BARB DOWN HARPOON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2950,
+ },
+ [0x2951]={
+ category="sm",
+ description="UP BARB LEFT DOWN BARB LEFT HARPOON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2951,
+ },
+ [0x2952]={
+ category="sm",
+ description="LEFTWARDS HARPOON WITH BARB UP TO BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2952,
+ },
+ [0x2953]={
+ category="sm",
+ description="RIGHTWARDS HARPOON WITH BARB UP TO BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2953,
+ },
+ [0x2954]={
+ category="sm",
+ description="UPWARDS HARPOON WITH BARB RIGHT TO BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2954,
+ },
+ [0x2955]={
+ category="sm",
+ description="DOWNWARDS HARPOON WITH BARB RIGHT TO BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2955,
+ },
+ [0x2956]={
+ category="sm",
+ description="LEFTWARDS HARPOON WITH BARB DOWN TO BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2956,
+ },
+ [0x2957]={
+ category="sm",
+ description="RIGHTWARDS HARPOON WITH BARB DOWN TO BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2957,
+ },
+ [0x2958]={
+ category="sm",
+ description="UPWARDS HARPOON WITH BARB LEFT TO BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2958,
+ },
+ [0x2959]={
+ category="sm",
+ description="DOWNWARDS HARPOON WITH BARB LEFT TO BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2959,
+ },
+ [0x295A]={
+ category="sm",
+ description="LEFTWARDS HARPOON WITH BARB UP FROM BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x295A,
+ },
+ [0x295B]={
+ category="sm",
+ description="RIGHTWARDS HARPOON WITH BARB UP FROM BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x295B,
+ },
+ [0x295C]={
+ category="sm",
+ description="UPWARDS HARPOON WITH BARB RIGHT FROM BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x295C,
+ },
+ [0x295D]={
+ category="sm",
+ description="DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x295D,
+ },
+ [0x295E]={
+ category="sm",
+ description="LEFTWARDS HARPOON WITH BARB DOWN FROM BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x295E,
+ },
+ [0x295F]={
+ category="sm",
+ description="RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x295F,
+ },
+ [0x2960]={
+ category="sm",
+ description="UPWARDS HARPOON WITH BARB LEFT FROM BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2960,
+ },
+ [0x2961]={
+ category="sm",
+ description="DOWNWARDS HARPOON WITH BARB LEFT FROM BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2961,
+ },
+ [0x2962]={
+ category="sm",
+ description="LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2962,
+ },
+ [0x2963]={
+ category="sm",
+ description="UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2963,
+ },
+ [0x2964]={
+ category="sm",
+ description="RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2964,
+ },
+ [0x2965]={
+ category="sm",
+ description="DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2965,
+ },
+ [0x2966]={
+ category="sm",
+ description="LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2966,
+ },
+ [0x2967]={
+ category="sm",
+ description="LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2967,
+ },
+ [0x2968]={
+ category="sm",
+ description="RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2968,
+ },
+ [0x2969]={
+ category="sm",
+ description="RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2969,
+ },
+ [0x296A]={
+ category="sm",
+ description="LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x296A,
+ },
+ [0x296B]={
+ category="sm",
+ description="LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x296B,
+ },
+ [0x296C]={
+ category="sm",
+ description="RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x296C,
+ },
+ [0x296D]={
+ category="sm",
+ description="RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x296D,
+ },
+ [0x296E]={
+ category="sm",
+ description="UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x296E,
+ },
+ [0x296F]={
+ category="sm",
+ description="DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x296F,
+ },
+ [0x2970]={
+ category="sm",
+ description="RIGHT DOUBLE ARROW WITH ROUNDED HEAD",
+ direction="on",
+ linebreak="al",
+ mathextensible="r",
+ unicodeslot=0x2970,
+ },
+ [0x2971]={
+ category="sm",
+ description="EQUALS SIGN ABOVE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2971,
+ },
+ [0x2972]={
+ category="sm",
+ description="TILDE OPERATOR ABOVE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2972,
+ },
+ [0x2973]={
+ category="sm",
+ description="LEFTWARDS ARROW ABOVE TILDE OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2973,
+ },
+ [0x2974]={
+ category="sm",
+ description="RIGHTWARDS ARROW ABOVE TILDE OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2974,
+ },
+ [0x2975]={
+ category="sm",
+ description="RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2975,
+ },
+ [0x2976]={
+ category="sm",
+ description="LESS-THAN ABOVE LEFTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2976,
+ },
+ [0x2977]={
+ category="sm",
+ description="LEFTWARDS ARROW THROUGH LESS-THAN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2977,
+ },
+ [0x2978]={
+ category="sm",
+ description="GREATER-THAN ABOVE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2978,
+ },
+ [0x2979]={
+ category="sm",
+ description="SUBSET ABOVE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2979,
+ },
+ [0x297A]={
+ category="sm",
+ description="LEFTWARDS ARROW THROUGH SUBSET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x297A,
+ },
+ [0x297B]={
+ category="sm",
+ description="SUPERSET ABOVE LEFTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x297B,
+ },
+ [0x297C]={
+ category="sm",
+ description="LEFT FISH TAIL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x297C,
+ },
+ [0x297D]={
+ category="sm",
+ description="RIGHT FISH TAIL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x297D,
+ },
+ [0x297E]={
+ category="sm",
+ description="UP FISH TAIL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x297E,
+ },
+ [0x297F]={
+ category="sm",
+ description="DOWN FISH TAIL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x297F,
+ },
+ [0x2980]={
+ category="sm",
+ description="TRIPLE VERTICAL BAR DELIMITER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2980,
+ },
+ [0x2981]={
+ category="sm",
+ description="Z NOTATION SPOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2981,
+ },
+ [0x2982]={
+ category="sm",
+ description="Z NOTATION TYPE COLON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2982,
+ },
+ [0x2983]={
+ category="ps",
+ description="LEFT WHITE CURLY BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x2984,
+ unicodeslot=0x2983,
+ },
+ [0x2984]={
+ category="pe",
+ description="RIGHT WHITE CURLY BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2983,
+ unicodeslot=0x2984,
+ },
+ [0x2985]={
+ category="ps",
+ cjkwd="na",
+ description="LEFT WHITE PARENTHESIS",
+ direction="on",
+ linebreak="op",
+ mirror=0x2986,
+ unicodeslot=0x2985,
+ },
+ [0x2986]={
+ category="pe",
+ cjkwd="na",
+ description="RIGHT WHITE PARENTHESIS",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2985,
+ unicodeslot=0x2986,
+ },
+ [0x2987]={
+ category="ps",
+ description="Z NOTATION LEFT IMAGE BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x2988,
+ unicodeslot=0x2987,
+ },
+ [0x2988]={
+ category="pe",
+ description="Z NOTATION RIGHT IMAGE BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2987,
+ unicodeslot=0x2988,
+ },
+ [0x2989]={
+ category="ps",
+ description="Z NOTATION LEFT BINDING BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x298A,
+ unicodeslot=0x2989,
+ },
+ [0x298A]={
+ category="pe",
+ description="Z NOTATION RIGHT BINDING BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2989,
+ unicodeslot=0x298A,
+ },
+ [0x298B]={
+ category="ps",
+ description="LEFT SQUARE BRACKET WITH UNDERBAR",
+ direction="on",
+ linebreak="op",
+ mirror=0x298C,
+ unicodeslot=0x298B,
+ },
+ [0x298C]={
+ category="pe",
+ description="RIGHT SQUARE BRACKET WITH UNDERBAR",
+ direction="on",
+ linebreak="cl",
+ mirror=0x298B,
+ unicodeslot=0x298C,
+ },
+ [0x298D]={
+ category="ps",
+ description="LEFT SQUARE BRACKET WITH TICK IN TOP CORNER",
+ direction="on",
+ linebreak="op",
+ mirror=0x2990,
+ unicodeslot=0x298D,
+ },
+ [0x298E]={
+ category="pe",
+ description="RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER",
+ direction="on",
+ linebreak="cl",
+ mirror=0x298F,
+ unicodeslot=0x298E,
+ },
+ [0x298F]={
+ category="ps",
+ description="LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER",
+ direction="on",
+ linebreak="op",
+ mirror=0x298E,
+ unicodeslot=0x298F,
+ },
+ [0x2990]={
+ category="pe",
+ description="RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER",
+ direction="on",
+ linebreak="cl",
+ mirror=0x298D,
+ unicodeslot=0x2990,
+ },
+ [0x2991]={
+ category="ps",
+ description="LEFT ANGLE BRACKET WITH DOT",
+ direction="on",
+ linebreak="op",
+ mirror=0x2992,
+ unicodeslot=0x2991,
+ },
+ [0x2992]={
+ category="pe",
+ description="RIGHT ANGLE BRACKET WITH DOT",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2991,
+ unicodeslot=0x2992,
+ },
+ [0x2993]={
+ category="ps",
+ description="LEFT ARC LESS-THAN BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x2994,
+ unicodeslot=0x2993,
+ },
+ [0x2994]={
+ category="pe",
+ description="RIGHT ARC GREATER-THAN BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2993,
+ unicodeslot=0x2994,
+ },
+ [0x2995]={
+ category="ps",
+ description="DOUBLE LEFT ARC GREATER-THAN BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x2996,
+ unicodeslot=0x2995,
+ },
+ [0x2996]={
+ category="pe",
+ description="DOUBLE RIGHT ARC LESS-THAN BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2995,
+ unicodeslot=0x2996,
+ },
+ [0x2997]={
+ category="ps",
+ description="LEFT BLACK TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x2998,
+ unicodeslot=0x2997,
+ },
+ [0x2998]={
+ category="pe",
+ description="RIGHT BLACK TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2997,
+ unicodeslot=0x2998,
+ },
+ [0x2999]={
+ category="sm",
+ description="DOTTED FENCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2999,
+ },
+ [0x299A]={
+ category="sm",
+ description="VERTICAL ZIGZAG LINE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x299A,
+ },
+ [0x299B]={
+ category="sm",
+ description="MEASURED ANGLE OPENING LEFT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x299B,
+ },
+ [0x299C]={
+ category="sm",
+ description="RIGHT ANGLE VARIANT WITH SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x299C,
+ },
+ [0x299D]={
+ category="sm",
+ description="MEASURED RIGHT ANGLE WITH DOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x299D,
+ },
+ [0x299E]={
+ category="sm",
+ description="ANGLE WITH S INSIDE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x299E,
+ },
+ [0x299F]={
+ category="sm",
+ description="ACUTE ANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x299F,
+ },
+ [0x29A0]={
+ category="sm",
+ description="SPHERICAL ANGLE OPENING LEFT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A0,
+ },
+ [0x29A1]={
+ category="sm",
+ description="SPHERICAL ANGLE OPENING UP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A1,
+ },
+ [0x29A2]={
+ category="sm",
+ description="TURNED ANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A2,
+ },
+ [0x29A3]={
+ category="sm",
+ description="REVERSED ANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A3,
+ },
+ [0x29A4]={
+ category="sm",
+ description="ANGLE WITH UNDERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A4,
+ },
+ [0x29A5]={
+ category="sm",
+ description="REVERSED ANGLE WITH UNDERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A5,
+ },
+ [0x29A6]={
+ category="sm",
+ description="OBLIQUE ANGLE OPENING UP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A6,
+ },
+ [0x29A7]={
+ category="sm",
+ description="OBLIQUE ANGLE OPENING DOWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A7,
+ },
+ [0x29A8]={
+ category="sm",
+ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A8,
+ },
+ [0x29A9]={
+ category="sm",
+ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29A9,
+ },
+ [0x29AA]={
+ category="sm",
+ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29AA,
+ },
+ [0x29AB]={
+ category="sm",
+ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29AB,
+ },
+ [0x29AC]={
+ category="sm",
+ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29AC,
+ },
+ [0x29AD]={
+ category="sm",
+ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29AD,
+ },
+ [0x29AE]={
+ category="sm",
+ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29AE,
+ },
+ [0x29AF]={
+ category="sm",
+ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29AF,
+ },
+ [0x29B0]={
+ category="sm",
+ description="REVERSED EMPTY SET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B0,
+ },
+ [0x29B1]={
+ category="sm",
+ description="EMPTY SET WITH OVERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B1,
+ },
+ [0x29B2]={
+ category="sm",
+ description="EMPTY SET WITH SMALL CIRCLE ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B2,
+ },
+ [0x29B3]={
+ category="sm",
+ description="EMPTY SET WITH RIGHT ARROW ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B3,
+ },
+ [0x29B4]={
+ category="sm",
+ description="EMPTY SET WITH LEFT ARROW ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B4,
+ },
+ [0x29B5]={
+ category="sm",
+ description="CIRCLE WITH HORIZONTAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B5,
+ },
+ [0x29B6]={
+ category="sm",
+ description="CIRCLED VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B6,
+ },
+ [0x29B7]={
+ category="sm",
+ description="CIRCLED PARALLEL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B7,
+ },
+ [0x29B8]={
+ category="sm",
+ description="CIRCLED REVERSE SOLIDUS",
+ direction="on",
+ linebreak="al",
+ mirror=0x2298,
+ unicodeslot=0x29B8,
+ },
+ [0x29B9]={
+ category="sm",
+ description="CIRCLED PERPENDICULAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29B9,
+ },
+ [0x29BA]={
+ category="sm",
+ description="CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29BA,
+ },
+ [0x29BB]={
+ category="sm",
+ description="CIRCLE WITH SUPERIMPOSED X",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29BB,
+ },
+ [0x29BC]={
+ category="sm",
+ description="CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29BC,
+ },
+ [0x29BD]={
+ category="sm",
+ description="UP ARROW THROUGH CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29BD,
+ },
+ [0x29BE]={
+ category="sm",
+ description="CIRCLED WHITE BULLET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29BE,
+ },
+ [0x29BF]={
+ category="sm",
+ description="CIRCLED BULLET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29BF,
+ },
+ [0x29C0]={
+ category="sm",
+ description="CIRCLED LESS-THAN",
+ direction="on",
+ linebreak="al",
+ mirror=0x29C1,
+ unicodeslot=0x29C0,
+ },
+ [0x29C1]={
+ category="sm",
+ description="CIRCLED GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ mirror=0x29C0,
+ unicodeslot=0x29C1,
+ },
+ [0x29C2]={
+ category="sm",
+ description="CIRCLE WITH SMALL CIRCLE TO THE RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29C2,
+ },
+ [0x29C3]={
+ category="sm",
+ description="CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29C3,
+ },
+ [0x29C4]={
+ category="sm",
+ description="SQUARED RISING DIAGONAL SLASH",
+ direction="on",
+ linebreak="al",
+ mirror=0x29C5,
+ unicodeslot=0x29C4,
+ },
+ [0x29C5]={
+ category="sm",
+ description="SQUARED FALLING DIAGONAL SLASH",
+ direction="on",
+ linebreak="al",
+ mirror=0x29C4,
+ unicodeslot=0x29C5,
+ },
+ [0x29C6]={
+ category="sm",
+ description="SQUARED ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29C6,
+ },
+ [0x29C7]={
+ category="sm",
+ description="SQUARED SMALL CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29C7,
+ },
+ [0x29C8]={
+ category="sm",
+ description="SQUARED SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29C8,
+ },
+ [0x29C9]={
+ category="sm",
+ description="TWO JOINED SQUARES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29C9,
+ },
+ [0x29CA]={
+ category="sm",
+ description="TRIANGLE WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29CA,
+ },
+ [0x29CB]={
+ category="sm",
+ description="TRIANGLE WITH UNDERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29CB,
+ },
+ [0x29CC]={
+ category="sm",
+ description="S IN TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29CC,
+ },
+ [0x29CD]={
+ category="sm",
+ description="TRIANGLE WITH SERIFS AT BOTTOM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29CD,
+ },
+ [0x29CE]={
+ category="sm",
+ description="RIGHT TRIANGLE ABOVE LEFT TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29CE,
+ },
+ [0x29CF]={
+ category="sm",
+ description="LEFT TRIANGLE BESIDE VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ mirror=0x29D0,
+ unicodeslot=0x29CF,
+ },
+ [0x29D0]={
+ category="sm",
+ description="VERTICAL BAR BESIDE RIGHT TRIANGLE",
+ direction="on",
+ linebreak="al",
+ mirror=0x29CF,
+ unicodeslot=0x29D0,
+ },
+ [0x29D1]={
+ category="sm",
+ description="BOWTIE WITH LEFT HALF BLACK",
+ direction="on",
+ linebreak="al",
+ mirror=0x29D2,
+ unicodeslot=0x29D1,
+ },
+ [0x29D2]={
+ category="sm",
+ description="BOWTIE WITH RIGHT HALF BLACK",
+ direction="on",
+ linebreak="al",
+ mirror=0x29D1,
+ unicodeslot=0x29D2,
+ },
+ [0x29D3]={
+ category="sm",
+ description="BLACK BOWTIE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29D3,
+ },
+ [0x29D4]={
+ category="sm",
+ description="TIMES WITH LEFT HALF BLACK",
+ direction="on",
+ linebreak="al",
+ mirror=0x29D5,
+ unicodeslot=0x29D4,
+ },
+ [0x29D5]={
+ category="sm",
+ description="TIMES WITH RIGHT HALF BLACK",
+ direction="on",
+ linebreak="al",
+ mirror=0x29D4,
+ unicodeslot=0x29D5,
+ },
+ [0x29D6]={
+ category="sm",
+ description="WHITE HOURGLASS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29D6,
+ },
+ [0x29D7]={
+ category="sm",
+ description="BLACK HOURGLASS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29D7,
+ },
+ [0x29D8]={
+ category="ps",
+ description="LEFT WIGGLY FENCE",
+ direction="on",
+ linebreak="op",
+ mirror=0x29D9,
+ unicodeslot=0x29D8,
+ },
+ [0x29D9]={
+ category="pe",
+ description="RIGHT WIGGLY FENCE",
+ direction="on",
+ linebreak="cl",
+ mirror=0x29D8,
+ unicodeslot=0x29D9,
+ },
+ [0x29DA]={
+ category="ps",
+ description="LEFT DOUBLE WIGGLY FENCE",
+ direction="on",
+ linebreak="op",
+ mirror=0x29DB,
+ unicodeslot=0x29DA,
+ },
+ [0x29DB]={
+ category="pe",
+ description="RIGHT DOUBLE WIGGLY FENCE",
+ direction="on",
+ linebreak="cl",
+ mirror=0x29DA,
+ unicodeslot=0x29DB,
+ },
+ [0x29DC]={
+ category="sm",
+ description="INCOMPLETE INFINITY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29DC,
+ },
+ [0x29DD]={
+ category="sm",
+ description="TIE OVER INFINITY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29DD,
+ },
+ [0x29DE]={
+ category="sm",
+ description="INFINITY NEGATED WITH VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29DE,
+ },
+ [0x29DF]={
+ category="sm",
+ description="DOUBLE-ENDED MULTIMAP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29DF,
+ },
+ [0x29E0]={
+ category="sm",
+ description="SQUARE WITH CONTOURED OUTLINE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E0,
+ },
+ [0x29E1]={
+ category="sm",
+ description="INCREASES AS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E1,
+ },
+ [0x29E2]={
+ category="sm",
+ description="SHUFFLE PRODUCT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E2,
+ },
+ [0x29E3]={
+ category="sm",
+ description="EQUALS SIGN AND SLANTED PARALLEL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E3,
+ },
+ [0x29E4]={
+ category="sm",
+ description="EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E4,
+ },
+ [0x29E5]={
+ category="sm",
+ description="IDENTICAL TO AND SLANTED PARALLEL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E5,
+ },
+ [0x29E6]={
+ category="sm",
+ description="GLEICH STARK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E6,
+ },
+ [0x29E7]={
+ category="sm",
+ description="THERMODYNAMIC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E7,
+ },
+ [0x29E8]={
+ category="sm",
+ description="DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E8,
+ },
+ [0x29E9]={
+ category="sm",
+ description="DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29E9,
+ },
+ [0x29EA]={
+ category="sm",
+ description="BLACK DIAMOND WITH DOWN ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="d",
+ unicodeslot=0x29EA,
+ },
+ [0x29EB]={
+ category="sm",
+ description="BLACK LOZENGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29EB,
+ },
+ [0x29EC]={
+ category="sm",
+ description="WHITE CIRCLE WITH DOWN ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="d",
+ unicodeslot=0x29EC,
+ },
+ [0x29ED]={
+ category="sm",
+ description="BLACK CIRCLE WITH DOWN ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="d",
+ unicodeslot=0x29ED,
+ },
+ [0x29EE]={
+ category="sm",
+ description="ERROR-BARRED WHITE SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29EE,
+ },
+ [0x29EF]={
+ category="sm",
+ description="ERROR-BARRED BLACK SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29EF,
+ },
+ [0x29F0]={
+ category="sm",
+ description="ERROR-BARRED WHITE DIAMOND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F0,
+ },
+ [0x29F1]={
+ category="sm",
+ description="ERROR-BARRED BLACK DIAMOND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F1,
+ },
+ [0x29F2]={
+ category="sm",
+ description="ERROR-BARRED WHITE CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F2,
+ },
+ [0x29F3]={
+ category="sm",
+ description="ERROR-BARRED BLACK CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F3,
+ },
+ [0x29F4]={
+ category="sm",
+ description="RULE-DELAYED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F4,
+ },
+ [0x29F5]={
+ category="sm",
+ description="REVERSE SOLIDUS OPERATOR",
+ direction="on",
+ linebreak="al",
+ mirror=0x2215,
+ unicodeslot=0x29F5,
+ },
+ [0x29F6]={
+ category="sm",
+ description="SOLIDUS WITH OVERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F6,
+ },
+ [0x29F7]={
+ category="sm",
+ description="REVERSE SOLIDUS WITH HORIZONTAL STROKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29F7,
+ },
+ [0x29F8]={
+ category="sm",
+ description="BIG SOLIDUS",
+ direction="on",
+ linebreak="al",
+ mirror=0x29F9,
+ unicodeslot=0x29F8,
+ },
+ [0x29F9]={
+ category="sm",
+ description="BIG REVERSE SOLIDUS",
+ direction="on",
+ linebreak="al",
+ mirror=0x29F8,
+ unicodeslot=0x29F9,
+ },
+ [0x29FA]={
+ category="sm",
+ description="DOUBLE PLUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29FA,
+ },
+ [0x29FB]={
+ category="sm",
+ description="TRIPLE PLUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29FB,
+ },
+ [0x29FC]={
+ category="ps",
+ description="LEFT-POINTING CURVED ANGLE BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x29FD,
+ unicodeslot=0x29FC,
+ },
+ [0x29FD]={
+ category="pe",
+ description="RIGHT-POINTING CURVED ANGLE BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x29FC,
+ unicodeslot=0x29FD,
+ },
+ [0x29FE]={
+ category="sm",
+ description="TINY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29FE,
+ },
+ [0x29FF]={
+ category="sm",
+ description="MINY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x29FF,
+ },
+ [0x2A00]={
+ category="sm",
+ description="N-ARY CIRCLED DOT OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="bigodot",
+ unicodeslot=0x2A00,
+ },
+ [0x2A01]={
+ category="sm",
+ description="N-ARY CIRCLED PLUS OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="bigoplus",
+ unicodeslot=0x2A01,
+ },
+ [0x2A02]={
+ category="sm",
+ description="N-ARY CIRCLED TIMES OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="bigotimes",
+ unicodeslot=0x2A02,
+ },
+ [0x2A03]={
+ category="sm",
+ description="N-ARY UNION OPERATOR WITH DOT",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="bigudot",
+ unicodeslot=0x2A03,
+ },
+ [0x2A04]={
+ category="sm",
+ description="N-ARY UNION OPERATOR WITH PLUS",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="biguplus",
+ unicodeslot=0x2A04,
+ },
+ [0x2A05]={
+ category="sm",
+ description="N-ARY SQUARE INTERSECTION OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="bigsqcap",
+ unicodeslot=0x2A05,
+ },
+ [0x2A06]={
+ category="sm",
+ description="N-ARY SQUARE UNION OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="bigsqcup",
+ unicodeslot=0x2A06,
+ },
+ [0x2A07]={
+ category="sm",
+ description="TWO LOGICAL AND OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A07,
+ },
+ [0x2A08]={
+ category="sm",
+ description="TWO LOGICAL OR OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A08,
+ },
+ [0x2A09]={
+ category="sm",
+ description="N-ARY TIMES OPERATOR",
+ direction="on",
+ linebreak="al",
+ mathclass="limop",
+ mathname="bigtimes",
+ unicodeslot=0x2A09,
+ },
+ [0x2A0A]={
+ category="sm",
+ description="MODULO TWO SUM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A0A,
+ },
+ [0x2A0B]={
+ category="sm",
+ description="SUMMATION WITH INTEGRAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A0B,
+ },
+ [0x2A0C]={
+ category="sm",
+ description="QUADRUPLE INTEGRAL OPERATOR",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x222B, 0x222B, 0x222B, 0x222B },
+ unicodeslot=0x2A0C,
+ },
+ [0x2A0D]={
+ category="sm",
+ description="FINITE PART INTEGRAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A0D,
+ },
+ [0x2A0E]={
+ category="sm",
+ description="INTEGRAL WITH DOUBLE STROKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A0E,
+ },
+ [0x2A0F]={
+ category="sm",
+ description="INTEGRAL AVERAGE WITH SLASH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A0F,
+ },
+ [0x2A10]={
+ category="sm",
+ description="CIRCULATION FUNCTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A10,
+ },
+ [0x2A11]={
+ category="sm",
+ description="ANTICLOCKWISE INTEGRATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A11,
+ },
+ [0x2A12]={
+ category="sm",
+ description="LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A12,
+ },
+ [0x2A13]={
+ category="sm",
+ description="LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A13,
+ },
+ [0x2A14]={
+ category="sm",
+ description="LINE INTEGRATION NOT INCLUDING THE POLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A14,
+ },
+ [0x2A15]={
+ category="sm",
+ description="INTEGRAL AROUND A POINT OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A15,
+ },
+ [0x2A16]={
+ category="sm",
+ description="QUATERNION INTEGRAL OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A16,
+ },
+ [0x2A17]={
+ category="sm",
+ description="INTEGRAL WITH LEFTWARDS ARROW WITH HOOK",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2A17,
+ },
+ [0x2A18]={
+ category="sm",
+ description="INTEGRAL WITH TIMES SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A18,
+ },
+ [0x2A19]={
+ category="sm",
+ description="INTEGRAL WITH INTERSECTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A19,
+ },
+ [0x2A1A]={
+ category="sm",
+ description="INTEGRAL WITH UNION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A1A,
+ },
+ [0x2A1B]={
+ category="sm",
+ description="INTEGRAL WITH OVERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A1B,
+ },
+ [0x2A1C]={
+ category="sm",
+ description="INTEGRAL WITH UNDERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A1C,
+ },
+ [0x2A1D]={
+ category="sm",
+ description="JOIN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A1D,
+ },
+ [0x2A1E]={
+ category="sm",
+ description="LARGE LEFT TRIANGLE OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A1E,
+ },
+ [0x2A1F]={
+ category="sm",
+ description="Z NOTATION SCHEMA COMPOSITION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A1F,
+ },
+ [0x2A20]={
+ category="sm",
+ description="Z NOTATION SCHEMA PIPING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A20,
+ },
+ [0x2A21]={
+ category="sm",
+ description="Z NOTATION SCHEMA PROJECTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A21,
+ },
+ [0x2A22]={
+ category="sm",
+ description="PLUS SIGN WITH SMALL CIRCLE ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A22,
+ },
+ [0x2A23]={
+ category="sm",
+ description="PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A23,
+ },
+ [0x2A24]={
+ category="sm",
+ description="PLUS SIGN WITH TILDE ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A24,
+ },
+ [0x2A25]={
+ category="sm",
+ description="PLUS SIGN WITH DOT BELOW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A25,
+ },
+ [0x2A26]={
+ category="sm",
+ description="PLUS SIGN WITH TILDE BELOW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A26,
+ },
+ [0x2A27]={
+ category="sm",
+ description="PLUS SIGN WITH SUBSCRIPT TWO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A27,
+ },
+ [0x2A28]={
+ category="sm",
+ description="PLUS SIGN WITH BLACK TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A28,
+ },
+ [0x2A29]={
+ category="sm",
+ description="MINUS SIGN WITH COMMA ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A29,
+ },
+ [0x2A2A]={
+ category="sm",
+ description="MINUS SIGN WITH DOT BELOW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A2A,
+ },
+ [0x2A2B]={
+ category="sm",
+ description="MINUS SIGN WITH FALLING DOTS",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A2C,
+ unicodeslot=0x2A2B,
+ },
+ [0x2A2C]={
+ category="sm",
+ description="MINUS SIGN WITH RISING DOTS",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A2B,
+ unicodeslot=0x2A2C,
+ },
+ [0x2A2D]={
+ category="sm",
+ description="PLUS SIGN IN LEFT HALF CIRCLE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A2E,
+ unicodeslot=0x2A2D,
+ },
+ [0x2A2E]={
+ category="sm",
+ description="PLUS SIGN IN RIGHT HALF CIRCLE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A2D,
+ unicodeslot=0x2A2E,
+ },
+ [0x2A2F]={
+ category="sm",
+ description="VECTOR OR CROSS PRODUCT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A2F,
+ },
+ [0x2A30]={
+ category="sm",
+ description="MULTIPLICATION SIGN WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A30,
+ },
+ [0x2A31]={
+ category="sm",
+ description="MULTIPLICATION SIGN WITH UNDERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A31,
+ },
+ [0x2A32]={
+ category="sm",
+ description="SEMIDIRECT PRODUCT WITH BOTTOM CLOSED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A32,
+ },
+ [0x2A33]={
+ category="sm",
+ description="SMASH PRODUCT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A33,
+ },
+ [0x2A34]={
+ category="sm",
+ description="MULTIPLICATION SIGN IN LEFT HALF CIRCLE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A35,
+ unicodeslot=0x2A34,
+ },
+ [0x2A35]={
+ category="sm",
+ description="MULTIPLICATION SIGN IN RIGHT HALF CIRCLE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A34,
+ unicodeslot=0x2A35,
+ },
+ [0x2A36]={
+ category="sm",
+ description="CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A36,
+ },
+ [0x2A37]={
+ category="sm",
+ description="MULTIPLICATION SIGN IN DOUBLE CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A37,
+ },
+ [0x2A38]={
+ category="sm",
+ description="CIRCLED DIVISION SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A38,
+ },
+ [0x2A39]={
+ category="sm",
+ description="PLUS SIGN IN TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A39,
+ },
+ [0x2A3A]={
+ category="sm",
+ description="MINUS SIGN IN TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A3A,
+ },
+ [0x2A3B]={
+ category="sm",
+ description="MULTIPLICATION SIGN IN TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A3B,
+ },
+ [0x2A3C]={
+ category="sm",
+ description="INTERIOR PRODUCT",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A3D,
+ unicodeslot=0x2A3C,
+ variants={
+ [0xFE00]="tall variant with narrow foot",
+ },
+ },
+ [0x2A3D]={
+ category="sm",
+ description="RIGHTHAND INTERIOR PRODUCT",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A3C,
+ unicodeslot=0x2A3D,
+ variants={
+ [0xFE00]="tall variant with narrow foot",
+ },
+ },
+ [0x2A3E]={
+ category="sm",
+ description="Z NOTATION RELATIONAL COMPOSITION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A3E,
+ },
+ [0x2A3F]={
+ category="sm",
+ description="AMALGAMATION OR COPRODUCT",
+ direction="on",
+ linebreak="al",
+ mathclass="binary",
+ mathname="amalg",
+ unicodeslot=0x2A3F,
+ },
+ [0x2A40]={
+ category="sm",
+ description="INTERSECTION WITH DOT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A40,
+ },
+ [0x2A41]={
+ category="sm",
+ description="UNION WITH MINUS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A41,
+ },
+ [0x2A42]={
+ category="sm",
+ description="UNION WITH OVERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A42,
+ },
+ [0x2A43]={
+ category="sm",
+ description="INTERSECTION WITH OVERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A43,
+ },
+ [0x2A44]={
+ category="sm",
+ description="INTERSECTION WITH LOGICAL AND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A44,
+ },
+ [0x2A45]={
+ category="sm",
+ description="UNION WITH LOGICAL OR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A45,
+ },
+ [0x2A46]={
+ category="sm",
+ description="UNION ABOVE INTERSECTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A46,
+ },
+ [0x2A47]={
+ category="sm",
+ description="INTERSECTION ABOVE UNION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A47,
+ },
+ [0x2A48]={
+ category="sm",
+ description="UNION ABOVE BAR ABOVE INTERSECTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A48,
+ },
+ [0x2A49]={
+ category="sm",
+ description="INTERSECTION ABOVE BAR ABOVE UNION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A49,
+ },
+ [0x2A4A]={
+ category="sm",
+ description="UNION BESIDE AND JOINED WITH UNION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A4A,
+ },
+ [0x2A4B]={
+ category="sm",
+ description="INTERSECTION BESIDE AND JOINED WITH INTERSECTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A4B,
+ },
+ [0x2A4C]={
+ category="sm",
+ description="CLOSED UNION WITH SERIFS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A4C,
+ },
+ [0x2A4D]={
+ category="sm",
+ description="CLOSED INTERSECTION WITH SERIFS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A4D,
+ },
+ [0x2A4E]={
+ category="sm",
+ description="DOUBLE SQUARE INTERSECTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A4E,
+ },
+ [0x2A4F]={
+ category="sm",
+ description="DOUBLE SQUARE UNION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A4F,
+ },
+ [0x2A50]={
+ category="sm",
+ description="CLOSED UNION WITH SERIFS AND SMASH PRODUCT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A50,
+ },
+ [0x2A51]={
+ category="sm",
+ description="LOGICAL AND WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A51,
+ },
+ [0x2A52]={
+ category="sm",
+ description="LOGICAL OR WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A52,
+ },
+ [0x2A53]={
+ category="sm",
+ description="DOUBLE LOGICAL AND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A53,
+ },
+ [0x2A54]={
+ category="sm",
+ description="DOUBLE LOGICAL OR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A54,
+ },
+ [0x2A55]={
+ category="sm",
+ description="TWO INTERSECTING LOGICAL AND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A55,
+ },
+ [0x2A56]={
+ category="sm",
+ description="TWO INTERSECTING LOGICAL OR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A56,
+ },
+ [0x2A57]={
+ category="sm",
+ description="SLOPING LARGE OR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A57,
+ },
+ [0x2A58]={
+ category="sm",
+ description="SLOPING LARGE AND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A58,
+ },
+ [0x2A59]={
+ category="sm",
+ description="LOGICAL OR OVERLAPPING LOGICAL AND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A59,
+ },
+ [0x2A5A]={
+ category="sm",
+ description="LOGICAL AND WITH MIDDLE STEM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A5A,
+ },
+ [0x2A5B]={
+ category="sm",
+ description="LOGICAL OR WITH MIDDLE STEM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A5B,
+ },
+ [0x2A5C]={
+ category="sm",
+ description="LOGICAL AND WITH HORIZONTAL DASH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A5C,
+ },
+ [0x2A5D]={
+ category="sm",
+ description="LOGICAL OR WITH HORIZONTAL DASH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A5D,
+ },
+ [0x2A5E]={
+ category="sm",
+ description="LOGICAL AND WITH DOUBLE OVERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A5E,
+ },
+ [0x2A5F]={
+ category="sm",
+ description="LOGICAL AND WITH UNDERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A5F,
+ },
+ [0x2A60]={
+ category="sm",
+ description="LOGICAL AND WITH DOUBLE UNDERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A60,
+ },
+ [0x2A61]={
+ category="sm",
+ description="SMALL VEE WITH UNDERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A61,
+ },
+ [0x2A62]={
+ category="sm",
+ description="LOGICAL OR WITH DOUBLE OVERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A62,
+ },
+ [0x2A63]={
+ category="sm",
+ description="LOGICAL OR WITH DOUBLE UNDERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A63,
+ },
+ [0x2A64]={
+ category="sm",
+ description="Z NOTATION DOMAIN ANTIRESTRICTION",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A65,
+ unicodeslot=0x2A64,
+ },
+ [0x2A65]={
+ category="sm",
+ description="Z NOTATION RANGE ANTIRESTRICTION",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A64,
+ unicodeslot=0x2A65,
+ },
+ [0x2A66]={
+ category="sm",
+ description="EQUALS SIGN WITH DOT BELOW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A66,
+ },
+ [0x2A67]={
+ category="sm",
+ description="IDENTICAL WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A67,
+ },
+ [0x2A68]={
+ category="sm",
+ description="TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A68,
+ },
+ [0x2A69]={
+ category="sm",
+ description="TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A69,
+ },
+ [0x2A6A]={
+ category="sm",
+ description="TILDE OPERATOR WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A6A,
+ },
+ [0x2A6B]={
+ category="sm",
+ description="TILDE OPERATOR WITH RISING DOTS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A6B,
+ },
+ [0x2A6C]={
+ category="sm",
+ description="SIMILAR MINUS SIMILAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A6C,
+ },
+ [0x2A6D]={
+ category="sm",
+ description="CONGRUENT WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A6D,
+ },
+ [0x2A6E]={
+ category="sm",
+ description="EQUALS WITH ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A6E,
+ },
+ [0x2A6F]={
+ category="sm",
+ description="ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A6F,
+ },
+ [0x2A70]={
+ category="sm",
+ description="APPROXIMATELY EQUAL OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A70,
+ },
+ [0x2A71]={
+ category="sm",
+ description="EQUALS SIGN ABOVE PLUS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A71,
+ },
+ [0x2A72]={
+ category="sm",
+ description="PLUS SIGN ABOVE EQUALS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A72,
+ },
+ [0x2A73]={
+ category="sm",
+ description="EQUALS SIGN ABOVE TILDE OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A73,
+ },
+ [0x2A74]={
+ category="sm",
+ description="DOUBLE COLON EQUAL",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="coloncolonequals",
+ specials={ "compat", 0x003A, 0x003A, 0x003D },
+ unicodeslot=0x2A74,
+ },
+ [0x2A75]={
+ category="sm",
+ description="TWO CONSECUTIVE EQUALS SIGNS",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x003D, 0x003D },
+ unicodeslot=0x2A75,
+ },
+ [0x2A76]={
+ category="sm",
+ description="THREE CONSECUTIVE EQUALS SIGNS",
+ direction="on",
+ linebreak="al",
+ specials={ "compat", 0x003D, 0x003D, 0x003D },
+ unicodeslot=0x2A76,
+ },
+ [0x2A77]={
+ category="sm",
+ description="EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A77,
+ },
+ [0x2A78]={
+ category="sm",
+ description="EQUIVALENT WITH FOUR DOTS ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A78,
+ },
+ [0x2A79]={
+ category="sm",
+ description="LESS-THAN WITH CIRCLE INSIDE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A7A,
+ unicodeslot=0x2A79,
+ },
+ [0x2A7A]={
+ category="sm",
+ description="GREATER-THAN WITH CIRCLE INSIDE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A79,
+ unicodeslot=0x2A7A,
+ },
+ [0x2A7B]={
+ category="sm",
+ description="LESS-THAN WITH QUESTION MARK ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A7B,
+ },
+ [0x2A7C]={
+ category="sm",
+ description="GREATER-THAN WITH QUESTION MARK ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A7C,
+ },
+ [0x2A7D]={
+ category="sm",
+ description="LESS-THAN OR SLANTED EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="leqslant",
+ mirror=0x2A7E,
+ unicodeslot=0x2A7D,
+ },
+ [0x2A7E]={
+ category="sm",
+ description="GREATER-THAN OR SLANTED EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="geqslant",
+ mirror=0x2A7D,
+ unicodeslot=0x2A7E,
+ },
+ [0x2A7F]={
+ category="sm",
+ description="LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A80,
+ unicodeslot=0x2A7F,
+ },
+ [0x2A80]={
+ category="sm",
+ description="GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A7F,
+ unicodeslot=0x2A80,
+ },
+ [0x2A81]={
+ category="sm",
+ description="LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A82,
+ unicodeslot=0x2A81,
+ },
+ [0x2A82]={
+ category="sm",
+ description="GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A81,
+ unicodeslot=0x2A82,
+ },
+ [0x2A83]={
+ category="sm",
+ description="LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A84,
+ unicodeslot=0x2A83,
+ },
+ [0x2A84]={
+ category="sm",
+ description="GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A83,
+ unicodeslot=0x2A84,
+ },
+ [0x2A85]={
+ category="sm",
+ description="LESS-THAN OR APPROXIMATE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="lessapprox",
+ unicodeslot=0x2A85,
+ },
+ [0x2A86]={
+ category="sm",
+ description="GREATER-THAN OR APPROXIMATE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="gtrapprox",
+ unicodeslot=0x2A86,
+ },
+ [0x2A87]={
+ category="sm",
+ description="LESS-THAN AND SINGLE-LINE NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="lneq",
+ unicodeslot=0x2A87,
+ },
+ [0x2A88]={
+ category="sm",
+ description="GREATER-THAN AND SINGLE-LINE NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="rneq",
+ unicodeslot=0x2A88,
+ },
+ [0x2A89]={
+ category="sm",
+ description="LESS-THAN AND NOT APPROXIMATE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="lnapprox",
+ unicodeslot=0x2A89,
+ },
+ [0x2A8A]={
+ category="sm",
+ description="GREATER-THAN AND NOT APPROXIMATE",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="gnapprox",
+ unicodeslot=0x2A8A,
+ },
+ [0x2A8B]={
+ category="sm",
+ description="LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="lesseqqgtr",
+ mirror=0x2A8C,
+ unicodeslot=0x2A8B,
+ },
+ [0x2A8C]={
+ category="sm",
+ description="GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="gtreqqless",
+ mirror=0x2A8B,
+ unicodeslot=0x2A8C,
+ },
+ [0x2A8D]={
+ category="sm",
+ description="LESS-THAN ABOVE SIMILAR OR EQUAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A8D,
+ },
+ [0x2A8E]={
+ category="sm",
+ description="GREATER-THAN ABOVE SIMILAR OR EQUAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A8E,
+ },
+ [0x2A8F]={
+ category="sm",
+ description="LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A8F,
+ },
+ [0x2A90]={
+ category="sm",
+ description="GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A90,
+ },
+ [0x2A91]={
+ category="sm",
+ description="LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A92,
+ unicodeslot=0x2A91,
+ },
+ [0x2A92]={
+ category="sm",
+ description="GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A91,
+ unicodeslot=0x2A92,
+ },
+ [0x2A93]={
+ category="sm",
+ description="LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A94,
+ unicodeslot=0x2A93,
+ },
+ [0x2A94]={
+ category="sm",
+ description="GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A93,
+ unicodeslot=0x2A94,
+ },
+ [0x2A95]={
+ category="sm",
+ description="SLANTED EQUAL TO OR LESS-THAN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="eqslantless",
+ mirror=0x2A96,
+ unicodeslot=0x2A95,
+ },
+ [0x2A96]={
+ category="sm",
+ description="SLANTED EQUAL TO OR GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="eqslantgtr",
+ mirror=0x2A95,
+ unicodeslot=0x2A96,
+ },
+ [0x2A97]={
+ category="sm",
+ description="SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A98,
+ unicodeslot=0x2A97,
+ },
+ [0x2A98]={
+ category="sm",
+ description="SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A97,
+ unicodeslot=0x2A98,
+ },
+ [0x2A99]={
+ category="sm",
+ description="DOUBLE-LINE EQUAL TO OR LESS-THAN",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A9A,
+ unicodeslot=0x2A99,
+ },
+ [0x2A9A]={
+ category="sm",
+ description="DOUBLE-LINE EQUAL TO OR GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A99,
+ unicodeslot=0x2A9A,
+ },
+ [0x2A9B]={
+ category="sm",
+ description="DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A9C,
+ unicodeslot=0x2A9B,
+ },
+ [0x2A9C]={
+ category="sm",
+ description="DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ mirror=0x2A9B,
+ unicodeslot=0x2A9C,
+ },
+ [0x2A9D]={
+ category="sm",
+ description="SIMILAR OR LESS-THAN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A9D,
+ variants={
+ [0xFE00]="with similar following the slant of the upper leg",
+ },
+ },
+ [0x2A9E]={
+ category="sm",
+ description="SIMILAR OR GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A9E,
+ variants={
+ [0xFE00]="with similar following the slant of the upper leg",
+ },
+ },
+ [0x2A9F]={
+ category="sm",
+ description="SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2A9F,
+ },
+ [0x2AA0]={
+ category="sm",
+ description="SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AA0,
+ },
+ [0x2AA1]={
+ category="sm",
+ description="DOUBLE NESTED LESS-THAN",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA2,
+ unicodeslot=0x2AA1,
+ },
+ [0x2AA2]={
+ category="sm",
+ description="DOUBLE NESTED GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA1,
+ unicodeslot=0x2AA2,
+ },
+ [0x2AA3]={
+ category="sm",
+ description="DOUBLE NESTED LESS-THAN WITH UNDERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AA3,
+ },
+ [0x2AA4]={
+ category="sm",
+ description="GREATER-THAN OVERLAPPING LESS-THAN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AA4,
+ },
+ [0x2AA5]={
+ category="sm",
+ description="GREATER-THAN BESIDE LESS-THAN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AA5,
+ },
+ [0x2AA6]={
+ category="sm",
+ description="LESS-THAN CLOSED BY CURVE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA7,
+ unicodeslot=0x2AA6,
+ },
+ [0x2AA7]={
+ category="sm",
+ description="GREATER-THAN CLOSED BY CURVE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA6,
+ unicodeslot=0x2AA7,
+ },
+ [0x2AA8]={
+ category="sm",
+ description="LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA9,
+ unicodeslot=0x2AA8,
+ },
+ [0x2AA9]={
+ category="sm",
+ description="GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AA8,
+ unicodeslot=0x2AA9,
+ },
+ [0x2AAA]={
+ category="sm",
+ description="SMALLER THAN",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AAB,
+ unicodeslot=0x2AAA,
+ },
+ [0x2AAB]={
+ category="sm",
+ description="LARGER THAN",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AAA,
+ unicodeslot=0x2AAB,
+ },
+ [0x2AAC]={
+ category="sm",
+ description="SMALLER THAN OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AAD,
+ unicodeslot=0x2AAC,
+ variants={
+ [0xFE00]="with slanted equal",
+ },
+ },
+ [0x2AAD]={
+ category="sm",
+ description="LARGER THAN OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AAC,
+ unicodeslot=0x2AAD,
+ variants={
+ [0xFE00]="with slanted equal",
+ },
+ },
+ [0x2AAE]={
+ category="sm",
+ description="EQUALS SIGN WITH BUMPY ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AAE,
+ },
+ [0x2AAF]={
+ category="sm",
+ description="PRECEDES ABOVE SINGLE-LINE EQUALS SIGN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="preceq",
+ mirror=0x2AB0,
+ unicodeslot=0x2AAF,
+ },
+ [0x2AB0]={
+ category="sm",
+ description="SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="succeq",
+ mirror=0x2AAF,
+ unicodeslot=0x2AB0,
+ },
+ [0x2AB1]={
+ category="sm",
+ description="PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="precneq",
+ unicodeslot=0x2AB1,
+ },
+ [0x2AB2]={
+ category="sm",
+ description="SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="succneq",
+ unicodeslot=0x2AB2,
+ },
+ [0x2AB3]={
+ category="sm",
+ description="PRECEDES ABOVE EQUALS SIGN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="preceqq",
+ mirror=0x2AB4,
+ unicodeslot=0x2AB3,
+ },
+ [0x2AB4]={
+ category="sm",
+ description="SUCCEEDS ABOVE EQUALS SIGN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="succeqq",
+ mirror=0x2AB3,
+ unicodeslot=0x2AB4,
+ },
+ [0x2AB5]={
+ category="sm",
+ description="PRECEDES ABOVE NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="precneqq",
+ unicodeslot=0x2AB5,
+ },
+ [0x2AB6]={
+ category="sm",
+ description="SUCCEEDS ABOVE NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="succneqq",
+ unicodeslot=0x2AB6,
+ },
+ [0x2AB7]={
+ category="sm",
+ description="PRECEDES ABOVE ALMOST EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="precapprox",
+ unicodeslot=0x2AB7,
+ },
+ [0x2AB8]={
+ category="sm",
+ description="SUCCEEDS ABOVE ALMOST EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="succapprox",
+ unicodeslot=0x2AB8,
+ },
+ [0x2AB9]={
+ category="sm",
+ description="PRECEDES ABOVE NOT ALMOST EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="precnapprox",
+ unicodeslot=0x2AB9,
+ },
+ [0x2ABA]={
+ category="sm",
+ description="SUCCEEDS ABOVE NOT ALMOST EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="succnapprox",
+ unicodeslot=0x2ABA,
+ },
+ [0x2ABB]={
+ category="sm",
+ description="DOUBLE PRECEDES",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ABC,
+ unicodeslot=0x2ABB,
+ },
+ [0x2ABC]={
+ category="sm",
+ description="DOUBLE SUCCEEDS",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ABB,
+ unicodeslot=0x2ABC,
+ },
+ [0x2ABD]={
+ category="sm",
+ description="SUBSET WITH DOT",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ABE,
+ unicodeslot=0x2ABD,
+ },
+ [0x2ABE]={
+ category="sm",
+ description="SUPERSET WITH DOT",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ABD,
+ unicodeslot=0x2ABE,
+ },
+ [0x2ABF]={
+ category="sm",
+ description="SUBSET WITH PLUS SIGN BELOW",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC0,
+ unicodeslot=0x2ABF,
+ },
+ [0x2AC0]={
+ category="sm",
+ description="SUPERSET WITH PLUS SIGN BELOW",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ABF,
+ unicodeslot=0x2AC0,
+ },
+ [0x2AC1]={
+ category="sm",
+ description="SUBSET WITH MULTIPLICATION SIGN BELOW",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC2,
+ unicodeslot=0x2AC1,
+ },
+ [0x2AC2]={
+ category="sm",
+ description="SUPERSET WITH MULTIPLICATION SIGN BELOW",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC1,
+ unicodeslot=0x2AC2,
+ },
+ [0x2AC3]={
+ category="sm",
+ description="SUBSET OF OR EQUAL TO WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC4,
+ unicodeslot=0x2AC3,
+ },
+ [0x2AC4]={
+ category="sm",
+ description="SUPERSET OF OR EQUAL TO WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AC3,
+ unicodeslot=0x2AC4,
+ },
+ [0x2AC5]={
+ category="sm",
+ description="SUBSET OF ABOVE EQUALS SIGN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="subseteqq",
+ mirror=0x2AC6,
+ unicodeslot=0x2AC5,
+ },
+ [0x2AC6]={
+ category="sm",
+ description="SUPERSET OF ABOVE EQUALS SIGN",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="supseteqq",
+ mirror=0x2AC5,
+ unicodeslot=0x2AC6,
+ },
+ [0x2AC7]={
+ category="sm",
+ description="SUBSET OF ABOVE TILDE OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AC7,
+ },
+ [0x2AC8]={
+ category="sm",
+ description="SUPERSET OF ABOVE TILDE OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AC8,
+ },
+ [0x2AC9]={
+ category="sm",
+ description="SUBSET OF ABOVE ALMOST EQUAL TO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AC9,
+ },
+ [0x2ACA]={
+ category="sm",
+ description="SUPERSET OF ABOVE ALMOST EQUAL TO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2ACA,
+ },
+ [0x2ACB]={
+ category="sm",
+ description="SUBSET OF ABOVE NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="subsetneqq",
+ unicodeslot=0x2ACB,
+ variants={
+ [0xFE00]="with stroke through bottom members",
+ },
+ },
+ [0x2ACC]={
+ category="sm",
+ description="SUPERSET OF ABOVE NOT EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mathclass="relation",
+ mathname="supsetneqq",
+ unicodeslot=0x2ACC,
+ variants={
+ [0xFE00]="with stroke through bottom members",
+ },
+ },
+ [0x2ACD]={
+ category="sm",
+ description="SQUARE LEFT OPEN BOX OPERATOR",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ACE,
+ unicodeslot=0x2ACD,
+ },
+ [0x2ACE]={
+ category="sm",
+ description="SQUARE RIGHT OPEN BOX OPERATOR",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ACD,
+ unicodeslot=0x2ACE,
+ },
+ [0x2ACF]={
+ category="sm",
+ description="CLOSED SUBSET",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD0,
+ unicodeslot=0x2ACF,
+ },
+ [0x2AD0]={
+ category="sm",
+ description="CLOSED SUPERSET",
+ direction="on",
+ linebreak="al",
+ mirror=0x2ACF,
+ unicodeslot=0x2AD0,
+ },
+ [0x2AD1]={
+ category="sm",
+ description="CLOSED SUBSET OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD2,
+ unicodeslot=0x2AD1,
+ },
+ [0x2AD2]={
+ category="sm",
+ description="CLOSED SUPERSET OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD1,
+ unicodeslot=0x2AD2,
+ },
+ [0x2AD3]={
+ category="sm",
+ description="SUBSET ABOVE SUPERSET",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD4,
+ unicodeslot=0x2AD3,
+ },
+ [0x2AD4]={
+ category="sm",
+ description="SUPERSET ABOVE SUBSET",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD3,
+ unicodeslot=0x2AD4,
+ },
+ [0x2AD5]={
+ category="sm",
+ description="SUBSET ABOVE SUBSET",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD6,
+ unicodeslot=0x2AD5,
+ },
+ [0x2AD6]={
+ category="sm",
+ description="SUPERSET ABOVE SUPERSET",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AD5,
+ unicodeslot=0x2AD6,
+ },
+ [0x2AD7]={
+ category="sm",
+ description="SUPERSET BESIDE SUBSET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AD7,
+ },
+ [0x2AD8]={
+ category="sm",
+ description="SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AD8,
+ },
+ [0x2AD9]={
+ category="sm",
+ description="ELEMENT OF OPENING DOWNWARDS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AD9,
+ },
+ [0x2ADA]={
+ category="sm",
+ description="PITCHFORK WITH TEE TOP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2ADA,
+ },
+ [0x2ADB]={
+ category="sm",
+ description="TRANSVERSAL INTERSECTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2ADB,
+ },
+ [0x2ADC]={
+ category="sm",
+ description="FORKING",
+ direction="on",
+ linebreak="al",
+ specials={ "char", 0x2ADD, 0x0338 },
+ unicodeslot=0x2ADC,
+ },
+ [0x2ADD]={
+ category="sm",
+ description="NONFORKING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2ADD,
+ },
+ [0x2ADE]={
+ category="sm",
+ description="SHORT LEFT TACK",
+ direction="on",
+ linebreak="al",
+ mirror=0x22A6,
+ unicodeslot=0x2ADE,
+ },
+ [0x2ADF]={
+ category="sm",
+ description="SHORT DOWN TACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2ADF,
+ },
+ [0x2AE0]={
+ category="sm",
+ description="SHORT UP TACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE0,
+ },
+ [0x2AE1]={
+ category="sm",
+ description="PERPENDICULAR WITH S",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE1,
+ },
+ [0x2AE2]={
+ category="sm",
+ description="VERTICAL BAR TRIPLE RIGHT TURNSTILE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE2,
+ },
+ [0x2AE3]={
+ category="sm",
+ description="DOUBLE VERTICAL BAR LEFT TURNSTILE",
+ direction="on",
+ linebreak="al",
+ mirror=0x22A9,
+ unicodeslot=0x2AE3,
+ },
+ [0x2AE4]={
+ category="sm",
+ description="VERTICAL BAR DOUBLE LEFT TURNSTILE",
+ direction="on",
+ linebreak="al",
+ mirror=0x22A8,
+ unicodeslot=0x2AE4,
+ },
+ [0x2AE5]={
+ category="sm",
+ description="DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE",
+ direction="on",
+ linebreak="al",
+ mirror=0x22AB,
+ unicodeslot=0x2AE5,
+ },
+ [0x2AE6]={
+ category="sm",
+ description="LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE6,
+ },
+ [0x2AE7]={
+ category="sm",
+ description="SHORT DOWN TACK WITH OVERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE7,
+ },
+ [0x2AE8]={
+ category="sm",
+ description="SHORT UP TACK WITH UNDERBAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE8,
+ },
+ [0x2AE9]={
+ category="sm",
+ description="SHORT UP TACK ABOVE SHORT DOWN TACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AE9,
+ },
+ [0x2AEA]={
+ category="sm",
+ description="DOUBLE DOWN TACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AEA,
+ },
+ [0x2AEB]={
+ category="sm",
+ description="DOUBLE UP TACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AEB,
+ },
+ [0x2AEC]={
+ category="sm",
+ description="DOUBLE STROKE NOT SIGN",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AED,
+ unicodeslot=0x2AEC,
+ },
+ [0x2AED]={
+ category="sm",
+ description="REVERSED DOUBLE STROKE NOT SIGN",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AEC,
+ unicodeslot=0x2AED,
+ },
+ [0x2AEE]={
+ category="sm",
+ description="DOES NOT DIVIDE WITH REVERSED NEGATION SLASH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AEE,
+ },
+ [0x2AEF]={
+ category="sm",
+ description="VERTICAL LINE WITH CIRCLE ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AEF,
+ },
+ [0x2AF0]={
+ category="sm",
+ description="VERTICAL LINE WITH CIRCLE BELOW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF0,
+ },
+ [0x2AF1]={
+ category="sm",
+ description="DOWN TACK WITH CIRCLE BELOW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF1,
+ },
+ [0x2AF2]={
+ category="sm",
+ description="PARALLEL WITH HORIZONTAL STROKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF2,
+ },
+ [0x2AF3]={
+ category="sm",
+ description="PARALLEL WITH TILDE OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF3,
+ },
+ [0x2AF4]={
+ category="sm",
+ description="TRIPLE VERTICAL BAR BINARY RELATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF4,
+ },
+ [0x2AF5]={
+ category="sm",
+ description="TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF5,
+ },
+ [0x2AF6]={
+ category="sm",
+ description="TRIPLE COLON OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AF6,
+ },
+ [0x2AF7]={
+ category="sm",
+ description="TRIPLE NESTED LESS-THAN",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AF8,
+ unicodeslot=0x2AF7,
+ },
+ [0x2AF8]={
+ category="sm",
+ description="TRIPLE NESTED GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AF7,
+ unicodeslot=0x2AF8,
+ },
+ [0x2AF9]={
+ category="sm",
+ description="DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AFA,
+ unicodeslot=0x2AF9,
+ },
+ [0x2AFA]={
+ category="sm",
+ description="DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO",
+ direction="on",
+ linebreak="al",
+ mirror=0x2AF9,
+ unicodeslot=0x2AFA,
+ },
+ [0x2AFB]={
+ category="sm",
+ description="TRIPLE SOLIDUS BINARY RELATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AFB,
+ },
+ [0x2AFC]={
+ category="sm",
+ description="LARGE TRIPLE VERTICAL BAR OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AFC,
+ },
+ [0x2AFD]={
+ category="sm",
+ description="DOUBLE SOLIDUS OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AFD,
+ },
+ [0x2AFE]={
+ category="sm",
+ description="WHITE VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AFE,
+ },
+ [0x2AFF]={
+ category="sm",
+ description="N-ARY WHITE VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2AFF,
+ },
+ [0x2B00]={
+ category="so",
+ description="NORTH EAST WHITE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B00,
+ },
+ [0x2B01]={
+ category="so",
+ description="NORTH WEST WHITE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B01,
+ },
+ [0x2B02]={
+ category="so",
+ description="SOUTH EAST WHITE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B02,
+ },
+ [0x2B03]={
+ category="so",
+ description="SOUTH WEST WHITE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B03,
+ },
+ [0x2B04]={
+ category="so",
+ description="LEFT RIGHT WHITE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B04,
+ },
+ [0x2B05]={
+ category="so",
+ description="LEFTWARDS BLACK ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B05,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2B06]={
+ category="so",
+ description="UPWARDS BLACK ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B06,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2B07]={
+ category="so",
+ description="DOWNWARDS BLACK ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B07,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2B08]={
+ category="so",
+ description="NORTH EAST BLACK ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B08,
+ },
+ [0x2B09]={
+ category="so",
+ description="NORTH WEST BLACK ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B09,
+ },
+ [0x2B0A]={
+ category="so",
+ description="SOUTH EAST BLACK ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B0A,
+ },
+ [0x2B0B]={
+ category="so",
+ description="SOUTH WEST BLACK ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B0B,
+ },
+ [0x2B0C]={
+ category="so",
+ description="LEFT RIGHT BLACK ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B0C,
+ },
+ [0x2B0D]={
+ category="so",
+ description="UP DOWN BLACK ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B0D,
+ },
+ [0x2B0E]={
+ category="so",
+ description="RIGHTWARDS ARROW WITH TIP DOWNWARDS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B0E,
+ },
+ [0x2B0F]={
+ category="so",
+ description="RIGHTWARDS ARROW WITH TIP UPWARDS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B0F,
+ },
+ [0x2B10]={
+ category="so",
+ description="LEFTWARDS ARROW WITH TIP DOWNWARDS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B10,
+ },
+ [0x2B11]={
+ category="so",
+ description="LEFTWARDS ARROW WITH TIP UPWARDS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B11,
+ },
+ [0x2B12]={
+ category="so",
+ description="SQUARE WITH TOP HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B12,
+ },
+ [0x2B13]={
+ category="so",
+ description="SQUARE WITH BOTTOM HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B13,
+ },
+ [0x2B14]={
+ category="so",
+ description="SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B14,
+ },
+ [0x2B15]={
+ category="so",
+ description="SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B15,
+ },
+ [0x2B16]={
+ category="so",
+ description="DIAMOND WITH LEFT HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B16,
+ },
+ [0x2B17]={
+ category="so",
+ description="DIAMOND WITH RIGHT HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B17,
+ },
+ [0x2B18]={
+ category="so",
+ description="DIAMOND WITH TOP HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B18,
+ },
+ [0x2B19]={
+ category="so",
+ description="DIAMOND WITH BOTTOM HALF BLACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B19,
+ },
+ [0x2B1A]={
+ category="so",
+ description="DOTTED SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B1A,
+ },
+ [0x2B1B]={
+ category="so",
+ description="BLACK LARGE SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B1B,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2B1C]={
+ category="so",
+ description="WHITE LARGE SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B1C,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2B1D]={
+ category="so",
+ description="BLACK VERY SMALL SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B1D,
+ },
+ [0x2B1E]={
+ category="so",
+ description="WHITE VERY SMALL SQUARE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B1E,
+ },
+ [0x2B1F]={
+ category="so",
+ description="BLACK PENTAGON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B1F,
+ },
+ [0x2B20]={
+ category="so",
+ description="WHITE PENTAGON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B20,
+ },
+ [0x2B21]={
+ category="so",
+ description="WHITE HEXAGON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B21,
+ },
+ [0x2B22]={
+ category="so",
+ description="BLACK HEXAGON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B22,
+ },
+ [0x2B23]={
+ category="so",
+ description="HORIZONTAL BLACK HEXAGON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B23,
+ },
+ [0x2B24]={
+ category="so",
+ description="BLACK LARGE CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B24,
+ },
+ [0x2B25]={
+ category="so",
+ description="BLACK MEDIUM DIAMOND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B25,
+ },
+ [0x2B26]={
+ category="so",
+ description="WHITE MEDIUM DIAMOND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B26,
+ },
+ [0x2B27]={
+ category="so",
+ description="BLACK MEDIUM LOZENGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B27,
+ },
+ [0x2B28]={
+ category="so",
+ description="WHITE MEDIUM LOZENGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B28,
+ },
+ [0x2B29]={
+ category="so",
+ description="BLACK SMALL DIAMOND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B29,
+ },
+ [0x2B2A]={
+ category="so",
+ description="BLACK SMALL LOZENGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B2A,
+ },
+ [0x2B2B]={
+ category="so",
+ description="WHITE SMALL LOZENGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B2B,
+ },
+ [0x2B2C]={
+ category="so",
+ description="BLACK HORIZONTAL ELLIPSE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B2C,
+ },
+ [0x2B2D]={
+ category="so",
+ description="WHITE HORIZONTAL ELLIPSE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B2D,
+ },
+ [0x2B2E]={
+ category="so",
+ description="BLACK VERTICAL ELLIPSE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B2E,
+ },
+ [0x2B2F]={
+ category="so",
+ description="WHITE VERTICAL ELLIPSE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B2F,
+ },
+ [0x2B30]={
+ category="sm",
+ description="LEFT ARROW WITH SMALL CIRCLE",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B30,
+ },
+ [0x2B31]={
+ category="sm",
+ description="THREE LEFTWARDS ARROWS",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B31,
+ },
+ [0x2B32]={
+ category="sm",
+ description="LEFT ARROW WITH CIRCLED PLUS",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B32,
+ },
+ [0x2B33]={
+ category="sm",
+ description="LONG LEFTWARDS SQUIGGLE ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B33,
+ },
+ [0x2B34]={
+ category="sm",
+ description="LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B34,
+ },
+ [0x2B35]={
+ category="sm",
+ description="LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B35,
+ },
+ [0x2B36]={
+ category="sm",
+ description="LEFTWARDS TWO-HEADED ARROW FROM BAR",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B36,
+ },
+ [0x2B37]={
+ category="sm",
+ description="LEFTWARDS TWO-HEADED TRIPLE DASH ARROW",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B37,
+ },
+ [0x2B38]={
+ category="sm",
+ description="LEFTWARDS ARROW WITH DOTTED STEM",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B38,
+ },
+ [0x2B39]={
+ category="sm",
+ description="LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B39,
+ },
+ [0x2B3A]={
+ category="sm",
+ description="LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B3A,
+ },
+ [0x2B3B]={
+ category="sm",
+ description="LEFTWARDS TWO-HEADED ARROW WITH TAIL",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B3B,
+ },
+ [0x2B3C]={
+ category="sm",
+ description="LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B3C,
+ },
+ [0x2B3D]={
+ category="sm",
+ description="LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B3D,
+ },
+ [0x2B3E]={
+ category="sm",
+ description="LEFTWARDS ARROW THROUGH X",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B3E,
+ },
+ [0x2B3F]={
+ category="sm",
+ description="WAVE ARROW POINTING DIRECTLY LEFT",
+ direction="on",
+ linebreak="al",
+ mathextensible="l",
+ unicodeslot=0x2B3F,
+ },
+ [0x2B40]={
+ category="sm",
+ description="EQUALS SIGN ABOVE LEFTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B40,
+ },
+ [0x2B41]={
+ category="sm",
+ description="REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B41,
+ },
+ [0x2B42]={
+ category="sm",
+ description="LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B42,
+ },
+ [0x2B43]={
+ category="sm",
+ description="RIGHTWARDS ARROW THROUGH GREATER-THAN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B43,
+ },
+ [0x2B44]={
+ category="sm",
+ description="RIGHTWARDS ARROW THROUGH SUPERSET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B44,
+ },
+ [0x2B45]={
+ category="so",
+ description="LEFTWARDS QUADRUPLE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B45,
+ },
+ [0x2B46]={
+ category="so",
+ description="RIGHTWARDS QUADRUPLE ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B46,
+ },
+ [0x2B47]={
+ category="sm",
+ description="REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B47,
+ },
+ [0x2B48]={
+ category="sm",
+ description="RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B48,
+ },
+ [0x2B49]={
+ category="sm",
+ description="TILDE OPERATOR ABOVE LEFTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B49,
+ },
+ [0x2B4A]={
+ category="sm",
+ description="LEFTWARDS ARROW ABOVE ALMOST EQUAL TO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B4A,
+ },
+ [0x2B4B]={
+ category="sm",
+ description="LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B4B,
+ },
+ [0x2B4C]={
+ category="sm",
+ description="RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B4C,
+ },
+ [0x2B50]={
+ category="so",
+ description="WHITE MEDIUM STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B50,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2B51]={
+ category="so",
+ description="BLACK SMALL STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B51,
+ },
+ [0x2B52]={
+ category="so",
+ description="WHITE SMALL STAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B52,
+ },
+ [0x2B53]={
+ category="so",
+ description="BLACK RIGHT-POINTING PENTAGON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B53,
+ },
+ [0x2B54]={
+ category="so",
+ description="WHITE RIGHT-POINTING PENTAGON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B54,
+ },
+ [0x2B55]={
+ category="so",
+ cjkwd="a",
+ description="HEAVY LARGE CIRCLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2B55,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x2B56]={
+ category="so",
+ cjkwd="a",
+ description="HEAVY OVAL WITH OVAL INSIDE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2B56,
+ },
+ [0x2B57]={
+ category="so",
+ cjkwd="a",
+ description="HEAVY CIRCLE WITH CIRCLE INSIDE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2B57,
+ },
+ [0x2B58]={
+ category="so",
+ cjkwd="a",
+ description="HEAVY CIRCLE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2B58,
+ },
+ [0x2B59]={
+ category="so",
+ cjkwd="a",
+ description="HEAVY CIRCLED SALTIRE",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0x2B59,
+ },
+ [0x2C00]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER AZU",
+ direction="l",
+ lccode=0x2C30,
+ linebreak="al",
+ unicodeslot=0x2C00,
+ },
+ [0x2C01]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER BUKY",
+ direction="l",
+ lccode=0x2C31,
+ linebreak="al",
+ unicodeslot=0x2C01,
+ },
+ [0x2C02]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER VEDE",
+ direction="l",
+ lccode=0x2C32,
+ linebreak="al",
+ unicodeslot=0x2C02,
+ },
+ [0x2C03]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER GLAGOLI",
+ direction="l",
+ lccode=0x2C33,
+ linebreak="al",
+ unicodeslot=0x2C03,
+ },
+ [0x2C04]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER DOBRO",
+ direction="l",
+ lccode=0x2C34,
+ linebreak="al",
+ unicodeslot=0x2C04,
+ },
+ [0x2C05]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER YESTU",
+ direction="l",
+ lccode=0x2C35,
+ linebreak="al",
+ unicodeslot=0x2C05,
+ },
+ [0x2C06]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER ZHIVETE",
+ direction="l",
+ lccode=0x2C36,
+ linebreak="al",
+ unicodeslot=0x2C06,
+ },
+ [0x2C07]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER DZELO",
+ direction="l",
+ lccode=0x2C37,
+ linebreak="al",
+ unicodeslot=0x2C07,
+ },
+ [0x2C08]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER ZEMLJA",
+ direction="l",
+ lccode=0x2C38,
+ linebreak="al",
+ unicodeslot=0x2C08,
+ },
+ [0x2C09]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER IZHE",
+ direction="l",
+ lccode=0x2C39,
+ linebreak="al",
+ unicodeslot=0x2C09,
+ },
+ [0x2C0A]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER INITIAL IZHE",
+ direction="l",
+ lccode=0x2C3A,
+ linebreak="al",
+ unicodeslot=0x2C0A,
+ },
+ [0x2C0B]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER I",
+ direction="l",
+ lccode=0x2C3B,
+ linebreak="al",
+ unicodeslot=0x2C0B,
+ },
+ [0x2C0C]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER DJERVI",
+ direction="l",
+ lccode=0x2C3C,
+ linebreak="al",
+ unicodeslot=0x2C0C,
+ },
+ [0x2C0D]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER KAKO",
+ direction="l",
+ lccode=0x2C3D,
+ linebreak="al",
+ unicodeslot=0x2C0D,
+ },
+ [0x2C0E]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER LJUDIJE",
+ direction="l",
+ lccode=0x2C3E,
+ linebreak="al",
+ unicodeslot=0x2C0E,
+ },
+ [0x2C0F]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER MYSLITE",
+ direction="l",
+ lccode=0x2C3F,
+ linebreak="al",
+ unicodeslot=0x2C0F,
+ },
+ [0x2C10]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER NASHI",
+ direction="l",
+ lccode=0x2C40,
+ linebreak="al",
+ unicodeslot=0x2C10,
+ },
+ [0x2C11]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER ONU",
+ direction="l",
+ lccode=0x2C41,
+ linebreak="al",
+ unicodeslot=0x2C11,
+ },
+ [0x2C12]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER POKOJI",
+ direction="l",
+ lccode=0x2C42,
+ linebreak="al",
+ unicodeslot=0x2C12,
+ },
+ [0x2C13]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER RITSI",
+ direction="l",
+ lccode=0x2C43,
+ linebreak="al",
+ unicodeslot=0x2C13,
+ },
+ [0x2C14]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER SLOVO",
+ direction="l",
+ lccode=0x2C44,
+ linebreak="al",
+ unicodeslot=0x2C14,
+ },
+ [0x2C15]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER TVRIDO",
+ direction="l",
+ lccode=0x2C45,
+ linebreak="al",
+ unicodeslot=0x2C15,
+ },
+ [0x2C16]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER UKU",
+ direction="l",
+ lccode=0x2C46,
+ linebreak="al",
+ unicodeslot=0x2C16,
+ },
+ [0x2C17]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER FRITU",
+ direction="l",
+ lccode=0x2C47,
+ linebreak="al",
+ unicodeslot=0x2C17,
+ },
+ [0x2C18]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER HERU",
+ direction="l",
+ lccode=0x2C48,
+ linebreak="al",
+ unicodeslot=0x2C18,
+ },
+ [0x2C19]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER OTU",
+ direction="l",
+ lccode=0x2C49,
+ linebreak="al",
+ unicodeslot=0x2C19,
+ },
+ [0x2C1A]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER PE",
+ direction="l",
+ lccode=0x2C4A,
+ linebreak="al",
+ unicodeslot=0x2C1A,
+ },
+ [0x2C1B]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER SHTA",
+ direction="l",
+ lccode=0x2C4B,
+ linebreak="al",
+ unicodeslot=0x2C1B,
+ },
+ [0x2C1C]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER TSI",
+ direction="l",
+ lccode=0x2C4C,
+ linebreak="al",
+ unicodeslot=0x2C1C,
+ },
+ [0x2C1D]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER CHRIVI",
+ direction="l",
+ lccode=0x2C4D,
+ linebreak="al",
+ unicodeslot=0x2C1D,
+ },
+ [0x2C1E]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER SHA",
+ direction="l",
+ lccode=0x2C4E,
+ linebreak="al",
+ unicodeslot=0x2C1E,
+ },
+ [0x2C1F]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER YERU",
+ direction="l",
+ lccode=0x2C4F,
+ linebreak="al",
+ unicodeslot=0x2C1F,
+ },
+ [0x2C20]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER YERI",
+ direction="l",
+ lccode=0x2C50,
+ linebreak="al",
+ unicodeslot=0x2C20,
+ },
+ [0x2C21]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER YATI",
+ direction="l",
+ lccode=0x2C51,
+ linebreak="al",
+ unicodeslot=0x2C21,
+ },
+ [0x2C22]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER SPIDERY HA",
+ direction="l",
+ lccode=0x2C52,
+ linebreak="al",
+ unicodeslot=0x2C22,
+ },
+ [0x2C23]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER YU",
+ direction="l",
+ lccode=0x2C53,
+ linebreak="al",
+ unicodeslot=0x2C23,
+ },
+ [0x2C24]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER SMALL YUS",
+ direction="l",
+ lccode=0x2C54,
+ linebreak="al",
+ unicodeslot=0x2C24,
+ },
+ [0x2C25]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL",
+ direction="l",
+ lccode=0x2C55,
+ linebreak="al",
+ unicodeslot=0x2C25,
+ },
+ [0x2C26]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER YO",
+ direction="l",
+ lccode=0x2C56,
+ linebreak="al",
+ unicodeslot=0x2C26,
+ },
+ [0x2C27]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS",
+ direction="l",
+ lccode=0x2C57,
+ linebreak="al",
+ unicodeslot=0x2C27,
+ },
+ [0x2C28]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER BIG YUS",
+ direction="l",
+ lccode=0x2C58,
+ linebreak="al",
+ unicodeslot=0x2C28,
+ },
+ [0x2C29]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS",
+ direction="l",
+ lccode=0x2C59,
+ linebreak="al",
+ unicodeslot=0x2C29,
+ },
+ [0x2C2A]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER FITA",
+ direction="l",
+ lccode=0x2C5A,
+ linebreak="al",
+ unicodeslot=0x2C2A,
+ },
+ [0x2C2B]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER IZHITSA",
+ direction="l",
+ lccode=0x2C5B,
+ linebreak="al",
+ unicodeslot=0x2C2B,
+ },
+ [0x2C2C]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER SHTAPIC",
+ direction="l",
+ lccode=0x2C5C,
+ linebreak="al",
+ unicodeslot=0x2C2C,
+ },
+ [0x2C2D]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER TROKUTASTI A",
+ direction="l",
+ lccode=0x2C5D,
+ linebreak="al",
+ unicodeslot=0x2C2D,
+ },
+ [0x2C2E]={
+ category="lu",
+ description="GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE",
+ direction="l",
+ lccode=0x2C5E,
+ linebreak="al",
+ unicodeslot=0x2C2E,
+ },
+ [0x2C30]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER AZU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C00,
+ unicodeslot=0x2C30,
+ },
+ [0x2C31]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER BUKY",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C01,
+ unicodeslot=0x2C31,
+ },
+ [0x2C32]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER VEDE",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C02,
+ unicodeslot=0x2C32,
+ },
+ [0x2C33]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER GLAGOLI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C03,
+ unicodeslot=0x2C33,
+ },
+ [0x2C34]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER DOBRO",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C04,
+ unicodeslot=0x2C34,
+ },
+ [0x2C35]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER YESTU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C05,
+ unicodeslot=0x2C35,
+ },
+ [0x2C36]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER ZHIVETE",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C06,
+ unicodeslot=0x2C36,
+ },
+ [0x2C37]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER DZELO",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C07,
+ unicodeslot=0x2C37,
+ },
+ [0x2C38]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER ZEMLJA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C08,
+ unicodeslot=0x2C38,
+ },
+ [0x2C39]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER IZHE",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C09,
+ unicodeslot=0x2C39,
+ },
+ [0x2C3A]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER INITIAL IZHE",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C0A,
+ unicodeslot=0x2C3A,
+ },
+ [0x2C3B]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER I",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C0B,
+ unicodeslot=0x2C3B,
+ },
+ [0x2C3C]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER DJERVI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C0C,
+ unicodeslot=0x2C3C,
+ },
+ [0x2C3D]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER KAKO",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C0D,
+ unicodeslot=0x2C3D,
+ },
+ [0x2C3E]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER LJUDIJE",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C0E,
+ unicodeslot=0x2C3E,
+ },
+ [0x2C3F]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER MYSLITE",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C0F,
+ unicodeslot=0x2C3F,
+ },
+ [0x2C40]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER NASHI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C10,
+ unicodeslot=0x2C40,
+ },
+ [0x2C41]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER ONU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C11,
+ unicodeslot=0x2C41,
+ },
+ [0x2C42]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER POKOJI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C12,
+ unicodeslot=0x2C42,
+ },
+ [0x2C43]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER RITSI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C13,
+ unicodeslot=0x2C43,
+ },
+ [0x2C44]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER SLOVO",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C14,
+ unicodeslot=0x2C44,
+ },
+ [0x2C45]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER TVRIDO",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C15,
+ unicodeslot=0x2C45,
+ },
+ [0x2C46]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER UKU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C16,
+ unicodeslot=0x2C46,
+ },
+ [0x2C47]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER FRITU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C17,
+ unicodeslot=0x2C47,
+ },
+ [0x2C48]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER HERU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C18,
+ unicodeslot=0x2C48,
+ },
+ [0x2C49]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER OTU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C19,
+ unicodeslot=0x2C49,
+ },
+ [0x2C4A]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER PE",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C1A,
+ unicodeslot=0x2C4A,
+ },
+ [0x2C4B]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER SHTA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C1B,
+ unicodeslot=0x2C4B,
+ },
+ [0x2C4C]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER TSI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C1C,
+ unicodeslot=0x2C4C,
+ },
+ [0x2C4D]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER CHRIVI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C1D,
+ unicodeslot=0x2C4D,
+ },
+ [0x2C4E]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER SHA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C1E,
+ unicodeslot=0x2C4E,
+ },
+ [0x2C4F]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER YERU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C1F,
+ unicodeslot=0x2C4F,
+ },
+ [0x2C50]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER YERI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C20,
+ unicodeslot=0x2C50,
+ },
+ [0x2C51]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER YATI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C21,
+ unicodeslot=0x2C51,
+ },
+ [0x2C52]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER SPIDERY HA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C22,
+ unicodeslot=0x2C52,
+ },
+ [0x2C53]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER YU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C23,
+ unicodeslot=0x2C53,
+ },
+ [0x2C54]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER SMALL YUS",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C24,
+ unicodeslot=0x2C54,
+ },
+ [0x2C55]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C25,
+ unicodeslot=0x2C55,
+ },
+ [0x2C56]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER YO",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C26,
+ unicodeslot=0x2C56,
+ },
+ [0x2C57]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER IOTATED SMALL YUS",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C27,
+ unicodeslot=0x2C57,
+ },
+ [0x2C58]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER BIG YUS",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C28,
+ unicodeslot=0x2C58,
+ },
+ [0x2C59]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER IOTATED BIG YUS",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C29,
+ unicodeslot=0x2C59,
+ },
+ [0x2C5A]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER FITA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C2A,
+ unicodeslot=0x2C5A,
+ },
+ [0x2C5B]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER IZHITSA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C2B,
+ unicodeslot=0x2C5B,
+ },
+ [0x2C5C]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER SHTAPIC",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C2C,
+ unicodeslot=0x2C5C,
+ },
+ [0x2C5D]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER TROKUTASTI A",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C2D,
+ unicodeslot=0x2C5D,
+ },
+ [0x2C5E]={
+ category="ll",
+ description="GLAGOLITIC SMALL LETTER LATINATE MYSLITE",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C2E,
+ unicodeslot=0x2C5E,
+ },
+ [0x2C60]={
+ category="lu",
+ description="LATIN CAPITAL LETTER L WITH DOUBLE BAR",
+ direction="l",
+ lccode=0x2C61,
+ linebreak="al",
+ shcode=0x004C,
+ unicodeslot=0x2C60,
+ },
+ [0x2C61]={
+ category="ll",
+ description="LATIN SMALL LETTER L WITH DOUBLE BAR",
+ direction="l",
+ linebreak="al",
+ shcode=0x006C,
+ uccode=0x2C60,
+ unicodeslot=0x2C61,
+ },
+ [0x2C62]={
+ category="lu",
+ description="LATIN CAPITAL LETTER L WITH MIDDLE TILDE",
+ direction="l",
+ lccode=0x026B,
+ linebreak="al",
+ shcode=0x004C,
+ unicodeslot=0x2C62,
+ },
+ [0x2C63]={
+ category="lu",
+ description="LATIN CAPITAL LETTER P WITH STROKE",
+ direction="l",
+ lccode=0x1D7D,
+ linebreak="al",
+ shcode=0x0050,
+ unicodeslot=0x2C63,
+ },
+ [0x2C64]={
+ category="lu",
+ description="LATIN CAPITAL LETTER R WITH TAIL",
+ direction="l",
+ lccode=0x027D,
+ linebreak="al",
+ shcode=0x0052,
+ unicodeslot=0x2C64,
+ },
+ [0x2C65]={
+ category="ll",
+ description="LATIN SMALL LETTER A WITH STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0061,
+ uccode=0x023A,
+ unicodeslot=0x2C65,
+ },
+ [0x2C66]={
+ category="ll",
+ description="LATIN SMALL LETTER T WITH DIAGONAL STROKE",
+ direction="l",
+ linebreak="al",
+ shcode=0x0074,
+ uccode=0x023E,
+ unicodeslot=0x2C66,
+ },
+ [0x2C67]={
+ category="lu",
+ description="LATIN CAPITAL LETTER H WITH DESCENDER",
+ direction="l",
+ lccode=0x2C68,
+ linebreak="al",
+ shcode=0x0048,
+ unicodeslot=0x2C67,
+ },
+ [0x2C68]={
+ category="ll",
+ description="LATIN SMALL LETTER H WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ shcode=0x0068,
+ uccode=0x2C67,
+ unicodeslot=0x2C68,
+ },
+ [0x2C69]={
+ category="lu",
+ description="LATIN CAPITAL LETTER K WITH DESCENDER",
+ direction="l",
+ lccode=0x2C6A,
+ linebreak="al",
+ shcode=0x004B,
+ unicodeslot=0x2C69,
+ },
+ [0x2C6A]={
+ category="ll",
+ description="LATIN SMALL LETTER K WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ shcode=0x006B,
+ uccode=0x2C69,
+ unicodeslot=0x2C6A,
+ },
+ [0x2C6B]={
+ category="lu",
+ description="LATIN CAPITAL LETTER Z WITH DESCENDER",
+ direction="l",
+ lccode=0x2C6C,
+ linebreak="al",
+ shcode=0x005A,
+ unicodeslot=0x2C6B,
+ },
+ [0x2C6C]={
+ category="ll",
+ description="LATIN SMALL LETTER Z WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ shcode=0x007A,
+ uccode=0x2C6B,
+ unicodeslot=0x2C6C,
+ },
+ [0x2C6D]={
+ category="lu",
+ description="LATIN CAPITAL LETTER ALPHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C6D,
+ },
+ [0x2C6E]={
+ category="lu",
+ description="LATIN CAPITAL LETTER M WITH HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C6E,
+ },
+ [0x2C6F]={
+ category="lu",
+ description="LATIN CAPITAL LETTER TURNED A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C6F,
+ },
+ [0x2C70]={
+ category="lu",
+ description="LATIN CAPITAL LETTER TURNED ALPHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C70,
+ },
+ [0x2C71]={
+ category="ll",
+ description="LATIN SMALL LETTER V WITH RIGHT HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C71,
+ },
+ [0x2C72]={
+ category="lu",
+ description="LATIN CAPITAL LETTER W WITH HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C72,
+ },
+ [0x2C73]={
+ category="ll",
+ description="LATIN SMALL LETTER W WITH HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C73,
+ },
+ [0x2C74]={
+ category="ll",
+ description="LATIN SMALL LETTER V WITH CURL",
+ direction="l",
+ linebreak="al",
+ shcode=0x0076,
+ unicodeslot=0x2C74,
+ },
+ [0x2C75]={
+ category="lu",
+ description="LATIN CAPITAL LETTER HALF H",
+ direction="l",
+ lccode=0x2C76,
+ linebreak="al",
+ unicodeslot=0x2C75,
+ },
+ [0x2C76]={
+ category="ll",
+ description="LATIN SMALL LETTER HALF H",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C75,
+ unicodeslot=0x2C76,
+ },
+ [0x2C77]={
+ category="ll",
+ description="LATIN SMALL LETTER TAILLESS PHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C77,
+ },
+ [0x2C78]={
+ category="ll",
+ description="LATIN SMALL LETTER E WITH NOTCH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C78,
+ },
+ [0x2C79]={
+ category="ll",
+ description="LATIN SMALL LETTER TURNED R WITH TAIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C79,
+ },
+ [0x2C7A]={
+ category="ll",
+ description="LATIN SMALL LETTER O WITH LOW RING INSIDE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C7A,
+ },
+ [0x2C7B]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL TURNED E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C7B,
+ },
+ [0x2C7C]={
+ category="ll",
+ description="LATIN SUBSCRIPT SMALL LETTER J",
+ direction="l",
+ linebreak="al",
+ specials={ "sub", 0x006A },
+ unicodeslot=0x2C7C,
+ },
+ [0x2C7D]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0056 },
+ unicodeslot=0x2C7D,
+ },
+ [0x2C7E]={
+ category="lu",
+ description="LATIN CAPITAL LETTER S WITH SWASH TAIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C7E,
+ },
+ [0x2C7F]={
+ category="lu",
+ description="LATIN CAPITAL LETTER Z WITH SWASH TAIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2C7F,
+ },
+ [0x2C80]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER ALFA",
+ direction="l",
+ lccode=0x2C81,
+ linebreak="al",
+ unicodeslot=0x2C80,
+ },
+ [0x2C81]={
+ category="ll",
+ description="COPTIC SMALL LETTER ALFA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C80,
+ unicodeslot=0x2C81,
+ },
+ [0x2C82]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER VIDA",
+ direction="l",
+ lccode=0x2C83,
+ linebreak="al",
+ unicodeslot=0x2C82,
+ },
+ [0x2C83]={
+ category="ll",
+ description="COPTIC SMALL LETTER VIDA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C82,
+ unicodeslot=0x2C83,
+ },
+ [0x2C84]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER GAMMA",
+ direction="l",
+ lccode=0x2C85,
+ linebreak="al",
+ unicodeslot=0x2C84,
+ },
+ [0x2C85]={
+ category="ll",
+ description="COPTIC SMALL LETTER GAMMA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C84,
+ unicodeslot=0x2C85,
+ },
+ [0x2C86]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER DALDA",
+ direction="l",
+ lccode=0x2C87,
+ linebreak="al",
+ unicodeslot=0x2C86,
+ },
+ [0x2C87]={
+ category="ll",
+ description="COPTIC SMALL LETTER DALDA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C86,
+ unicodeslot=0x2C87,
+ },
+ [0x2C88]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER EIE",
+ direction="l",
+ lccode=0x2C89,
+ linebreak="al",
+ unicodeslot=0x2C88,
+ },
+ [0x2C89]={
+ category="ll",
+ description="COPTIC SMALL LETTER EIE",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C88,
+ unicodeslot=0x2C89,
+ },
+ [0x2C8A]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER SOU",
+ direction="l",
+ lccode=0x2C8B,
+ linebreak="al",
+ unicodeslot=0x2C8A,
+ },
+ [0x2C8B]={
+ category="ll",
+ description="COPTIC SMALL LETTER SOU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C8A,
+ unicodeslot=0x2C8B,
+ },
+ [0x2C8C]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER ZATA",
+ direction="l",
+ lccode=0x2C8D,
+ linebreak="al",
+ unicodeslot=0x2C8C,
+ },
+ [0x2C8D]={
+ category="ll",
+ description="COPTIC SMALL LETTER ZATA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C8C,
+ unicodeslot=0x2C8D,
+ },
+ [0x2C8E]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER HATE",
+ direction="l",
+ lccode=0x2C8F,
+ linebreak="al",
+ unicodeslot=0x2C8E,
+ },
+ [0x2C8F]={
+ category="ll",
+ description="COPTIC SMALL LETTER HATE",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C8E,
+ unicodeslot=0x2C8F,
+ },
+ [0x2C90]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER THETHE",
+ direction="l",
+ lccode=0x2C91,
+ linebreak="al",
+ unicodeslot=0x2C90,
+ },
+ [0x2C91]={
+ category="ll",
+ description="COPTIC SMALL LETTER THETHE",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C90,
+ unicodeslot=0x2C91,
+ },
+ [0x2C92]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER IAUDA",
+ direction="l",
+ lccode=0x2C93,
+ linebreak="al",
+ unicodeslot=0x2C92,
+ },
+ [0x2C93]={
+ category="ll",
+ description="COPTIC SMALL LETTER IAUDA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C92,
+ unicodeslot=0x2C93,
+ },
+ [0x2C94]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER KAPA",
+ direction="l",
+ lccode=0x2C95,
+ linebreak="al",
+ unicodeslot=0x2C94,
+ },
+ [0x2C95]={
+ category="ll",
+ description="COPTIC SMALL LETTER KAPA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C94,
+ unicodeslot=0x2C95,
+ },
+ [0x2C96]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER LAULA",
+ direction="l",
+ lccode=0x2C97,
+ linebreak="al",
+ unicodeslot=0x2C96,
+ },
+ [0x2C97]={
+ category="ll",
+ description="COPTIC SMALL LETTER LAULA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C96,
+ unicodeslot=0x2C97,
+ },
+ [0x2C98]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER MI",
+ direction="l",
+ lccode=0x2C99,
+ linebreak="al",
+ unicodeslot=0x2C98,
+ },
+ [0x2C99]={
+ category="ll",
+ description="COPTIC SMALL LETTER MI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C98,
+ unicodeslot=0x2C99,
+ },
+ [0x2C9A]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER NI",
+ direction="l",
+ lccode=0x2C9B,
+ linebreak="al",
+ unicodeslot=0x2C9A,
+ },
+ [0x2C9B]={
+ category="ll",
+ description="COPTIC SMALL LETTER NI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C9A,
+ unicodeslot=0x2C9B,
+ },
+ [0x2C9C]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER KSI",
+ direction="l",
+ lccode=0x2C9D,
+ linebreak="al",
+ unicodeslot=0x2C9C,
+ },
+ [0x2C9D]={
+ category="ll",
+ description="COPTIC SMALL LETTER KSI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C9C,
+ unicodeslot=0x2C9D,
+ },
+ [0x2C9E]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER O",
+ direction="l",
+ lccode=0x2C9F,
+ linebreak="al",
+ unicodeslot=0x2C9E,
+ },
+ [0x2C9F]={
+ category="ll",
+ description="COPTIC SMALL LETTER O",
+ direction="l",
+ linebreak="al",
+ uccode=0x2C9E,
+ unicodeslot=0x2C9F,
+ },
+ [0x2CA0]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER PI",
+ direction="l",
+ lccode=0x2CA1,
+ linebreak="al",
+ unicodeslot=0x2CA0,
+ },
+ [0x2CA1]={
+ category="ll",
+ description="COPTIC SMALL LETTER PI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CA0,
+ unicodeslot=0x2CA1,
+ },
+ [0x2CA2]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER RO",
+ direction="l",
+ lccode=0x2CA3,
+ linebreak="al",
+ unicodeslot=0x2CA2,
+ },
+ [0x2CA3]={
+ category="ll",
+ description="COPTIC SMALL LETTER RO",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CA2,
+ unicodeslot=0x2CA3,
+ },
+ [0x2CA4]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER SIMA",
+ direction="l",
+ lccode=0x2CA5,
+ linebreak="al",
+ unicodeslot=0x2CA4,
+ },
+ [0x2CA5]={
+ category="ll",
+ description="COPTIC SMALL LETTER SIMA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CA4,
+ unicodeslot=0x2CA5,
+ },
+ [0x2CA6]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER TAU",
+ direction="l",
+ lccode=0x2CA7,
+ linebreak="al",
+ unicodeslot=0x2CA6,
+ },
+ [0x2CA7]={
+ category="ll",
+ description="COPTIC SMALL LETTER TAU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CA6,
+ unicodeslot=0x2CA7,
+ },
+ [0x2CA8]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER UA",
+ direction="l",
+ lccode=0x2CA9,
+ linebreak="al",
+ unicodeslot=0x2CA8,
+ },
+ [0x2CA9]={
+ category="ll",
+ description="COPTIC SMALL LETTER UA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CA8,
+ unicodeslot=0x2CA9,
+ },
+ [0x2CAA]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER FI",
+ direction="l",
+ lccode=0x2CAB,
+ linebreak="al",
+ unicodeslot=0x2CAA,
+ },
+ [0x2CAB]={
+ category="ll",
+ description="COPTIC SMALL LETTER FI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CAA,
+ unicodeslot=0x2CAB,
+ },
+ [0x2CAC]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER KHI",
+ direction="l",
+ lccode=0x2CAD,
+ linebreak="al",
+ unicodeslot=0x2CAC,
+ },
+ [0x2CAD]={
+ category="ll",
+ description="COPTIC SMALL LETTER KHI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CAC,
+ unicodeslot=0x2CAD,
+ },
+ [0x2CAE]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER PSI",
+ direction="l",
+ lccode=0x2CAF,
+ linebreak="al",
+ unicodeslot=0x2CAE,
+ },
+ [0x2CAF]={
+ category="ll",
+ description="COPTIC SMALL LETTER PSI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CAE,
+ unicodeslot=0x2CAF,
+ },
+ [0x2CB0]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OOU",
+ direction="l",
+ lccode=0x2CB1,
+ linebreak="al",
+ unicodeslot=0x2CB0,
+ },
+ [0x2CB1]={
+ category="ll",
+ description="COPTIC SMALL LETTER OOU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CB0,
+ unicodeslot=0x2CB1,
+ },
+ [0x2CB2]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER DIALECT-P ALEF",
+ direction="l",
+ lccode=0x2CB3,
+ linebreak="al",
+ unicodeslot=0x2CB2,
+ },
+ [0x2CB3]={
+ category="ll",
+ description="COPTIC SMALL LETTER DIALECT-P ALEF",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CB2,
+ unicodeslot=0x2CB3,
+ },
+ [0x2CB4]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD COPTIC AIN",
+ direction="l",
+ lccode=0x2CB5,
+ linebreak="al",
+ unicodeslot=0x2CB4,
+ },
+ [0x2CB5]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD COPTIC AIN",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CB4,
+ unicodeslot=0x2CB5,
+ },
+ [0x2CB6]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE",
+ direction="l",
+ lccode=0x2CB7,
+ linebreak="al",
+ unicodeslot=0x2CB6,
+ },
+ [0x2CB7]={
+ category="ll",
+ description="COPTIC SMALL LETTER CRYPTOGRAMMIC EIE",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CB6,
+ unicodeslot=0x2CB7,
+ },
+ [0x2CB8]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER DIALECT-P KAPA",
+ direction="l",
+ lccode=0x2CB9,
+ linebreak="al",
+ unicodeslot=0x2CB8,
+ },
+ [0x2CB9]={
+ category="ll",
+ description="COPTIC SMALL LETTER DIALECT-P KAPA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CB8,
+ unicodeslot=0x2CB9,
+ },
+ [0x2CBA]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER DIALECT-P NI",
+ direction="l",
+ lccode=0x2CBB,
+ linebreak="al",
+ unicodeslot=0x2CBA,
+ },
+ [0x2CBB]={
+ category="ll",
+ description="COPTIC SMALL LETTER DIALECT-P NI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CBA,
+ unicodeslot=0x2CBB,
+ },
+ [0x2CBC]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI",
+ direction="l",
+ lccode=0x2CBD,
+ linebreak="al",
+ unicodeslot=0x2CBC,
+ },
+ [0x2CBD]={
+ category="ll",
+ description="COPTIC SMALL LETTER CRYPTOGRAMMIC NI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CBC,
+ unicodeslot=0x2CBD,
+ },
+ [0x2CBE]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD COPTIC OOU",
+ direction="l",
+ lccode=0x2CBF,
+ linebreak="al",
+ unicodeslot=0x2CBE,
+ },
+ [0x2CBF]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD COPTIC OOU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CBE,
+ unicodeslot=0x2CBF,
+ },
+ [0x2CC0]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER SAMPI",
+ direction="l",
+ lccode=0x2CC1,
+ linebreak="al",
+ unicodeslot=0x2CC0,
+ },
+ [0x2CC1]={
+ category="ll",
+ description="COPTIC SMALL LETTER SAMPI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CC0,
+ unicodeslot=0x2CC1,
+ },
+ [0x2CC2]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER CROSSED SHEI",
+ direction="l",
+ lccode=0x2CC3,
+ linebreak="al",
+ unicodeslot=0x2CC2,
+ },
+ [0x2CC3]={
+ category="ll",
+ description="COPTIC SMALL LETTER CROSSED SHEI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CC2,
+ unicodeslot=0x2CC3,
+ },
+ [0x2CC4]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD COPTIC SHEI",
+ direction="l",
+ lccode=0x2CC5,
+ linebreak="al",
+ unicodeslot=0x2CC4,
+ },
+ [0x2CC5]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD COPTIC SHEI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CC4,
+ unicodeslot=0x2CC5,
+ },
+ [0x2CC6]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD COPTIC ESH",
+ direction="l",
+ lccode=0x2CC7,
+ linebreak="al",
+ unicodeslot=0x2CC6,
+ },
+ [0x2CC7]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD COPTIC ESH",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CC6,
+ unicodeslot=0x2CC7,
+ },
+ [0x2CC8]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER AKHMIMIC KHEI",
+ direction="l",
+ lccode=0x2CC9,
+ linebreak="al",
+ unicodeslot=0x2CC8,
+ },
+ [0x2CC9]={
+ category="ll",
+ description="COPTIC SMALL LETTER AKHMIMIC KHEI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CC8,
+ unicodeslot=0x2CC9,
+ },
+ [0x2CCA]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER DIALECT-P HORI",
+ direction="l",
+ lccode=0x2CCB,
+ linebreak="al",
+ unicodeslot=0x2CCA,
+ },
+ [0x2CCB]={
+ category="ll",
+ description="COPTIC SMALL LETTER DIALECT-P HORI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CCA,
+ unicodeslot=0x2CCB,
+ },
+ [0x2CCC]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD COPTIC HORI",
+ direction="l",
+ lccode=0x2CCD,
+ linebreak="al",
+ unicodeslot=0x2CCC,
+ },
+ [0x2CCD]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD COPTIC HORI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CCC,
+ unicodeslot=0x2CCD,
+ },
+ [0x2CCE]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD COPTIC HA",
+ direction="l",
+ lccode=0x2CCF,
+ linebreak="al",
+ unicodeslot=0x2CCE,
+ },
+ [0x2CCF]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD COPTIC HA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CCE,
+ unicodeslot=0x2CCF,
+ },
+ [0x2CD0]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER L-SHAPED HA",
+ direction="l",
+ lccode=0x2CD1,
+ linebreak="al",
+ unicodeslot=0x2CD0,
+ },
+ [0x2CD1]={
+ category="ll",
+ description="COPTIC SMALL LETTER L-SHAPED HA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CD0,
+ unicodeslot=0x2CD1,
+ },
+ [0x2CD2]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD COPTIC HEI",
+ direction="l",
+ lccode=0x2CD3,
+ linebreak="al",
+ unicodeslot=0x2CD2,
+ },
+ [0x2CD3]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD COPTIC HEI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CD2,
+ unicodeslot=0x2CD3,
+ },
+ [0x2CD4]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD COPTIC HAT",
+ direction="l",
+ lccode=0x2CD5,
+ linebreak="al",
+ unicodeslot=0x2CD4,
+ },
+ [0x2CD5]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD COPTIC HAT",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CD4,
+ unicodeslot=0x2CD5,
+ },
+ [0x2CD6]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD COPTIC GANGIA",
+ direction="l",
+ lccode=0x2CD7,
+ linebreak="al",
+ unicodeslot=0x2CD6,
+ },
+ [0x2CD7]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD COPTIC GANGIA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CD6,
+ unicodeslot=0x2CD7,
+ },
+ [0x2CD8]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD COPTIC DJA",
+ direction="l",
+ lccode=0x2CD9,
+ linebreak="al",
+ unicodeslot=0x2CD8,
+ },
+ [0x2CD9]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD COPTIC DJA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CD8,
+ unicodeslot=0x2CD9,
+ },
+ [0x2CDA]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD COPTIC SHIMA",
+ direction="l",
+ lccode=0x2CDB,
+ linebreak="al",
+ unicodeslot=0x2CDA,
+ },
+ [0x2CDB]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD COPTIC SHIMA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CDA,
+ unicodeslot=0x2CDB,
+ },
+ [0x2CDC]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD NUBIAN SHIMA",
+ direction="l",
+ lccode=0x2CDD,
+ linebreak="al",
+ unicodeslot=0x2CDC,
+ },
+ [0x2CDD]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD NUBIAN SHIMA",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CDC,
+ unicodeslot=0x2CDD,
+ },
+ [0x2CDE]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD NUBIAN NGI",
+ direction="l",
+ lccode=0x2CDF,
+ linebreak="al",
+ unicodeslot=0x2CDE,
+ },
+ [0x2CDF]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD NUBIAN NGI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CDE,
+ unicodeslot=0x2CDF,
+ },
+ [0x2CE0]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD NUBIAN NYI",
+ direction="l",
+ lccode=0x2CE1,
+ linebreak="al",
+ unicodeslot=0x2CE0,
+ },
+ [0x2CE1]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD NUBIAN NYI",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CE0,
+ unicodeslot=0x2CE1,
+ },
+ [0x2CE2]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER OLD NUBIAN WAU",
+ direction="l",
+ lccode=0x2CE3,
+ linebreak="al",
+ unicodeslot=0x2CE2,
+ },
+ [0x2CE3]={
+ category="ll",
+ description="COPTIC SMALL LETTER OLD NUBIAN WAU",
+ direction="l",
+ linebreak="al",
+ uccode=0x2CE2,
+ unicodeslot=0x2CE3,
+ },
+ [0x2CE4]={
+ category="ll",
+ description="COPTIC SYMBOL KAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CE4,
+ },
+ [0x2CE5]={
+ category="so",
+ description="COPTIC SYMBOL MI RO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CE5,
+ },
+ [0x2CE6]={
+ category="so",
+ description="COPTIC SYMBOL PI RO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CE6,
+ },
+ [0x2CE7]={
+ category="so",
+ description="COPTIC SYMBOL STAUROS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CE7,
+ },
+ [0x2CE8]={
+ category="so",
+ description="COPTIC SYMBOL TAU RO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CE8,
+ },
+ [0x2CE9]={
+ category="so",
+ description="COPTIC SYMBOL KHI RO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CE9,
+ },
+ [0x2CEA]={
+ category="so",
+ description="COPTIC SYMBOL SHIMA SIMA",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CEA,
+ },
+ [0x2CEB]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CEB,
+ },
+ [0x2CEC]={
+ category="ll",
+ description="COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CEC,
+ },
+ [0x2CED]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CED,
+ },
+ [0x2CEE]={
+ category="ll",
+ description="COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CEE,
+ },
+ [0x2CEF]={
+ category="mn",
+ description="COPTIC COMBINING NI ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2CEF,
+ },
+ [0x2CF0]={
+ category="mn",
+ description="COPTIC COMBINING SPIRITUS ASPER",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2CF0,
+ },
+ [0x2CF1]={
+ category="mn",
+ description="COPTIC COMBINING SPIRITUS LENIS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2CF1,
+ },
+ [0x2CF2]={
+ category="lu",
+ description="COPTIC CAPITAL LETTER BOHAIRIC KHEI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CF2,
+ },
+ [0x2CF3]={
+ category="ll",
+ description="COPTIC SMALL LETTER BOHAIRIC KHEI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2CF3,
+ },
+ [0x2CF9]={
+ category="po",
+ description="COPTIC OLD NUBIAN FULL STOP",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x2CF9,
+ },
+ [0x2CFA]={
+ category="po",
+ description="COPTIC OLD NUBIAN DIRECT QUESTION MARK",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2CFA,
+ },
+ [0x2CFB]={
+ category="po",
+ description="COPTIC OLD NUBIAN INDIRECT QUESTION MARK",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2CFB,
+ },
+ [0x2CFC]={
+ category="po",
+ description="COPTIC OLD NUBIAN VERSE DIVIDER",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2CFC,
+ },
+ [0x2CFD]={
+ category="no",
+ description="COPTIC FRACTION ONE HALF",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2CFD,
+ },
+ [0x2CFE]={
+ category="po",
+ description="COPTIC FULL STOP",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x2CFE,
+ },
+ [0x2CFF]={
+ category="po",
+ description="COPTIC MORPHOLOGICAL DIVIDER",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2CFF,
+ },
+ [0x2D00]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER AN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10A0,
+ unicodeslot=0x2D00,
+ },
+ [0x2D01]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER BAN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10A1,
+ unicodeslot=0x2D01,
+ },
+ [0x2D02]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER GAN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10A2,
+ unicodeslot=0x2D02,
+ },
+ [0x2D03]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER DON",
+ direction="l",
+ linebreak="al",
+ uccode=0x10A3,
+ unicodeslot=0x2D03,
+ },
+ [0x2D04]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER EN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10A4,
+ unicodeslot=0x2D04,
+ },
+ [0x2D05]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER VIN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10A5,
+ unicodeslot=0x2D05,
+ },
+ [0x2D06]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER ZEN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10A6,
+ unicodeslot=0x2D06,
+ },
+ [0x2D07]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER TAN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10A7,
+ unicodeslot=0x2D07,
+ },
+ [0x2D08]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER IN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10A8,
+ unicodeslot=0x2D08,
+ },
+ [0x2D09]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER KAN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10A9,
+ unicodeslot=0x2D09,
+ },
+ [0x2D0A]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER LAS",
+ direction="l",
+ linebreak="al",
+ uccode=0x10AA,
+ unicodeslot=0x2D0A,
+ },
+ [0x2D0B]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER MAN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10AB,
+ unicodeslot=0x2D0B,
+ },
+ [0x2D0C]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER NAR",
+ direction="l",
+ linebreak="al",
+ uccode=0x10AC,
+ unicodeslot=0x2D0C,
+ },
+ [0x2D0D]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER ON",
+ direction="l",
+ linebreak="al",
+ uccode=0x10AD,
+ unicodeslot=0x2D0D,
+ },
+ [0x2D0E]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER PAR",
+ direction="l",
+ linebreak="al",
+ uccode=0x10AE,
+ unicodeslot=0x2D0E,
+ },
+ [0x2D0F]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER ZHAR",
+ direction="l",
+ linebreak="al",
+ uccode=0x10AF,
+ unicodeslot=0x2D0F,
+ },
+ [0x2D10]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER RAE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10B0,
+ unicodeslot=0x2D10,
+ },
+ [0x2D11]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER SAN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10B1,
+ unicodeslot=0x2D11,
+ },
+ [0x2D12]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER TAR",
+ direction="l",
+ linebreak="al",
+ uccode=0x10B2,
+ unicodeslot=0x2D12,
+ },
+ [0x2D13]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER UN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10B3,
+ unicodeslot=0x2D13,
+ },
+ [0x2D14]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER PHAR",
+ direction="l",
+ linebreak="al",
+ uccode=0x10B4,
+ unicodeslot=0x2D14,
+ },
+ [0x2D15]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER KHAR",
+ direction="l",
+ linebreak="al",
+ uccode=0x10B5,
+ unicodeslot=0x2D15,
+ },
+ [0x2D16]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER GHAN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10B6,
+ unicodeslot=0x2D16,
+ },
+ [0x2D17]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER QAR",
+ direction="l",
+ linebreak="al",
+ uccode=0x10B7,
+ unicodeslot=0x2D17,
+ },
+ [0x2D18]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER SHIN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10B8,
+ unicodeslot=0x2D18,
+ },
+ [0x2D19]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER CHIN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10B9,
+ unicodeslot=0x2D19,
+ },
+ [0x2D1A]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER CAN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10BA,
+ unicodeslot=0x2D1A,
+ },
+ [0x2D1B]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER JIL",
+ direction="l",
+ linebreak="al",
+ uccode=0x10BB,
+ unicodeslot=0x2D1B,
+ },
+ [0x2D1C]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER CIL",
+ direction="l",
+ linebreak="al",
+ uccode=0x10BC,
+ unicodeslot=0x2D1C,
+ },
+ [0x2D1D]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER CHAR",
+ direction="l",
+ linebreak="al",
+ uccode=0x10BD,
+ unicodeslot=0x2D1D,
+ },
+ [0x2D1E]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER XAN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10BE,
+ unicodeslot=0x2D1E,
+ },
+ [0x2D1F]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER JHAN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10BF,
+ unicodeslot=0x2D1F,
+ },
+ [0x2D20]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER HAE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10C0,
+ unicodeslot=0x2D20,
+ },
+ [0x2D21]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER HE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10C1,
+ unicodeslot=0x2D21,
+ },
+ [0x2D22]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER HIE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10C2,
+ unicodeslot=0x2D22,
+ },
+ [0x2D23]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER WE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10C3,
+ unicodeslot=0x2D23,
+ },
+ [0x2D24]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER HAR",
+ direction="l",
+ linebreak="al",
+ uccode=0x10C4,
+ unicodeslot=0x2D24,
+ },
+ [0x2D25]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER HOE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10C5,
+ unicodeslot=0x2D25,
+ },
+ [0x2D27]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER YN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D27,
+ },
+ [0x2D2D]={
+ category="ll",
+ description="GEORGIAN SMALL LETTER AEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D2D,
+ },
+ [0x2D30]={
+ category="lo",
+ description="TIFINAGH LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D30,
+ },
+ [0x2D31]={
+ category="lo",
+ description="TIFINAGH LETTER YAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D31,
+ },
+ [0x2D32]={
+ category="lo",
+ description="TIFINAGH LETTER YABH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D32,
+ },
+ [0x2D33]={
+ category="lo",
+ description="TIFINAGH LETTER YAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D33,
+ },
+ [0x2D34]={
+ category="lo",
+ description="TIFINAGH LETTER YAGHH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D34,
+ },
+ [0x2D35]={
+ category="lo",
+ description="TIFINAGH LETTER BERBER ACADEMY YAJ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D35,
+ },
+ [0x2D36]={
+ category="lo",
+ description="TIFINAGH LETTER YAJ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D36,
+ },
+ [0x2D37]={
+ category="lo",
+ description="TIFINAGH LETTER YAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D37,
+ },
+ [0x2D38]={
+ category="lo",
+ description="TIFINAGH LETTER YADH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D38,
+ },
+ [0x2D39]={
+ category="lo",
+ description="TIFINAGH LETTER YADD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D39,
+ },
+ [0x2D3A]={
+ category="lo",
+ description="TIFINAGH LETTER YADDH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D3A,
+ },
+ [0x2D3B]={
+ category="lo",
+ description="TIFINAGH LETTER YEY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D3B,
+ },
+ [0x2D3C]={
+ category="lo",
+ description="TIFINAGH LETTER YAF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D3C,
+ },
+ [0x2D3D]={
+ category="lo",
+ description="TIFINAGH LETTER YAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D3D,
+ },
+ [0x2D3E]={
+ category="lo",
+ description="TIFINAGH LETTER TUAREG YAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D3E,
+ },
+ [0x2D3F]={
+ category="lo",
+ description="TIFINAGH LETTER YAKHH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D3F,
+ },
+ [0x2D40]={
+ category="lo",
+ description="TIFINAGH LETTER YAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D40,
+ },
+ [0x2D41]={
+ category="lo",
+ description="TIFINAGH LETTER BERBER ACADEMY YAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D41,
+ },
+ [0x2D42]={
+ category="lo",
+ description="TIFINAGH LETTER TUAREG YAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D42,
+ },
+ [0x2D43]={
+ category="lo",
+ description="TIFINAGH LETTER YAHH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D43,
+ },
+ [0x2D44]={
+ category="lo",
+ description="TIFINAGH LETTER YAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D44,
+ },
+ [0x2D45]={
+ category="lo",
+ description="TIFINAGH LETTER YAKH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D45,
+ },
+ [0x2D46]={
+ category="lo",
+ description="TIFINAGH LETTER TUAREG YAKH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D46,
+ },
+ [0x2D47]={
+ category="lo",
+ description="TIFINAGH LETTER YAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D47,
+ },
+ [0x2D48]={
+ category="lo",
+ description="TIFINAGH LETTER TUAREG YAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D48,
+ },
+ [0x2D49]={
+ category="lo",
+ description="TIFINAGH LETTER YI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D49,
+ },
+ [0x2D4A]={
+ category="lo",
+ description="TIFINAGH LETTER YAZH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D4A,
+ },
+ [0x2D4B]={
+ category="lo",
+ description="TIFINAGH LETTER AHAGGAR YAZH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D4B,
+ },
+ [0x2D4C]={
+ category="lo",
+ description="TIFINAGH LETTER TUAREG YAZH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D4C,
+ },
+ [0x2D4D]={
+ category="lo",
+ description="TIFINAGH LETTER YAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D4D,
+ },
+ [0x2D4E]={
+ category="lo",
+ description="TIFINAGH LETTER YAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D4E,
+ },
+ [0x2D4F]={
+ category="lo",
+ description="TIFINAGH LETTER YAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D4F,
+ },
+ [0x2D50]={
+ category="lo",
+ description="TIFINAGH LETTER TUAREG YAGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D50,
+ },
+ [0x2D51]={
+ category="lo",
+ description="TIFINAGH LETTER TUAREG YANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D51,
+ },
+ [0x2D52]={
+ category="lo",
+ description="TIFINAGH LETTER YAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D52,
+ },
+ [0x2D53]={
+ category="lo",
+ description="TIFINAGH LETTER YU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D53,
+ },
+ [0x2D54]={
+ category="lo",
+ description="TIFINAGH LETTER YAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D54,
+ },
+ [0x2D55]={
+ category="lo",
+ description="TIFINAGH LETTER YARR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D55,
+ },
+ [0x2D56]={
+ category="lo",
+ description="TIFINAGH LETTER YAGH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D56,
+ },
+ [0x2D57]={
+ category="lo",
+ description="TIFINAGH LETTER TUAREG YAGH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D57,
+ },
+ [0x2D58]={
+ category="lo",
+ description="TIFINAGH LETTER AYER YAGH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D58,
+ },
+ [0x2D59]={
+ category="lo",
+ description="TIFINAGH LETTER YAS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D59,
+ },
+ [0x2D5A]={
+ category="lo",
+ description="TIFINAGH LETTER YASS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D5A,
+ },
+ [0x2D5B]={
+ category="lo",
+ description="TIFINAGH LETTER YASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D5B,
+ },
+ [0x2D5C]={
+ category="lo",
+ description="TIFINAGH LETTER YAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D5C,
+ },
+ [0x2D5D]={
+ category="lo",
+ description="TIFINAGH LETTER YATH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D5D,
+ },
+ [0x2D5E]={
+ category="lo",
+ description="TIFINAGH LETTER YACH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D5E,
+ },
+ [0x2D5F]={
+ category="lo",
+ description="TIFINAGH LETTER YATT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D5F,
+ },
+ [0x2D60]={
+ category="lo",
+ description="TIFINAGH LETTER YAV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D60,
+ },
+ [0x2D61]={
+ category="lo",
+ description="TIFINAGH LETTER YAW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D61,
+ },
+ [0x2D62]={
+ category="lo",
+ description="TIFINAGH LETTER YAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D62,
+ },
+ [0x2D63]={
+ category="lo",
+ description="TIFINAGH LETTER YAZ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D63,
+ },
+ [0x2D64]={
+ category="lo",
+ description="TIFINAGH LETTER TAWELLEMET YAZ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D64,
+ },
+ [0x2D65]={
+ category="lo",
+ description="TIFINAGH LETTER YAZZ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D65,
+ },
+ [0x2D66]={
+ category="lo",
+ description="TIFINAGH LETTER YE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D66,
+ },
+ [0x2D67]={
+ category="lo",
+ description="TIFINAGH LETTER YO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D67,
+ },
+ [0x2D6F]={
+ category="lm",
+ description="TIFINAGH MODIFIER LETTER LABIALIZATION MARK",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x2D61 },
+ unicodeslot=0x2D6F,
+ },
+ [0x2D70]={
+ category="po",
+ description="TIFINAGH SEPARATOR MARK",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x2D70,
+ },
+ [0x2D7F]={
+ category="mn",
+ description="TIFINAGH CONSONANT JOINER",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2D7F,
+ },
+ [0x2D80]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE LOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D80,
+ },
+ [0x2D81]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE MOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D81,
+ },
+ [0x2D82]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ROA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D82,
+ },
+ [0x2D83]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D83,
+ },
+ [0x2D84]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SHOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D84,
+ },
+ [0x2D85]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D85,
+ },
+ [0x2D86]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D86,
+ },
+ [0x2D87]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE COA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D87,
+ },
+ [0x2D88]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D88,
+ },
+ [0x2D89]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE NYOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D89,
+ },
+ [0x2D8A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GLOTTAL OA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D8A,
+ },
+ [0x2D8B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D8B,
+ },
+ [0x2D8C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D8C,
+ },
+ [0x2D8D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D8D,
+ },
+ [0x2D8E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE JOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D8E,
+ },
+ [0x2D8F]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE THOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D8F,
+ },
+ [0x2D90]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CHOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D90,
+ },
+ [0x2D91]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE PHOA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D91,
+ },
+ [0x2D92]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE POA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D92,
+ },
+ [0x2D93]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GGWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D93,
+ },
+ [0x2D94]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GGWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D94,
+ },
+ [0x2D95]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GGWEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D95,
+ },
+ [0x2D96]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GGWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2D96,
+ },
+ [0x2DA0]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA0,
+ },
+ [0x2DA1]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SSU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA1,
+ },
+ [0x2DA2]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SSI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA2,
+ },
+ [0x2DA3]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SSAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA3,
+ },
+ [0x2DA4]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SSEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA4,
+ },
+ [0x2DA5]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SSE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA5,
+ },
+ [0x2DA6]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE SSO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA6,
+ },
+ [0x2DA8]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA8,
+ },
+ [0x2DA9]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DA9,
+ },
+ [0x2DAA]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DAA,
+ },
+ [0x2DAB]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DAB,
+ },
+ [0x2DAC]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DAC,
+ },
+ [0x2DAD]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DAD,
+ },
+ [0x2DAE]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DAE,
+ },
+ [0x2DB0]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB0,
+ },
+ [0x2DB1]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZZU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB1,
+ },
+ [0x2DB2]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZZI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB2,
+ },
+ [0x2DB3]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZZAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB3,
+ },
+ [0x2DB4]={
+ category="lo",
+ cjkwd="w",
+ description="ETHIOPIC SYLLABLE ZZEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB4,
+ },
+ [0x2DB5]={
+ category="lo",
+ cjkwd="w",
+ description="ETHIOPIC SYLLABLE ZZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB5,
+ },
+ [0x2DB6]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE ZZO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB6,
+ },
+ [0x2DB8]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB8,
+ },
+ [0x2DB9]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DB9,
+ },
+ [0x2DBA]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DBA,
+ },
+ [0x2DBB]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHAA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x2DBB,
+ },
+ [0x2DBC]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHEE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x2DBC,
+ },
+ [0x2DBD]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DBD,
+ },
+ [0x2DBE]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DBE,
+ },
+ [0x2DC0]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC0,
+ },
+ [0x2DC1]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QYU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC1,
+ },
+ [0x2DC2]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC2,
+ },
+ [0x2DC3]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QYAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC3,
+ },
+ [0x2DC4]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QYEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC4,
+ },
+ [0x2DC5]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QYE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC5,
+ },
+ [0x2DC6]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE QYO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC6,
+ },
+ [0x2DC8]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC8,
+ },
+ [0x2DC9]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KYU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DC9,
+ },
+ [0x2DCA]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DCA,
+ },
+ [0x2DCB]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KYAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DCB,
+ },
+ [0x2DCC]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KYEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DCC,
+ },
+ [0x2DCD]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KYE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DCD,
+ },
+ [0x2DCE]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE KYO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DCE,
+ },
+ [0x2DD0]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD0,
+ },
+ [0x2DD1]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XYU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD1,
+ },
+ [0x2DD2]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD2,
+ },
+ [0x2DD3]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XYAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD3,
+ },
+ [0x2DD4]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XYEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD4,
+ },
+ [0x2DD5]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XYE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD5,
+ },
+ [0x2DD6]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE XYO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD6,
+ },
+ [0x2DD8]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD8,
+ },
+ [0x2DD9]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GYU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DD9,
+ },
+ [0x2DDA]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DDA,
+ },
+ [0x2DDB]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GYAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DDB,
+ },
+ [0x2DDC]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GYEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DDC,
+ },
+ [0x2DDD]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GYE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DDD,
+ },
+ [0x2DDE]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE GYO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x2DDE,
+ },
+ [0x2DE0]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER BE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE0,
+ },
+ [0x2DE1]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER VE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE1,
+ },
+ [0x2DE2]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER GHE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE2,
+ },
+ [0x2DE3]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER DE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE3,
+ },
+ [0x2DE4]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER ZHE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE4,
+ },
+ [0x2DE5]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER ZE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE5,
+ },
+ [0x2DE6]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER KA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE6,
+ },
+ [0x2DE7]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER EL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE7,
+ },
+ [0x2DE8]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER EM",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE8,
+ },
+ [0x2DE9]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER EN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DE9,
+ },
+ [0x2DEA]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DEA,
+ },
+ [0x2DEB]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER PE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DEB,
+ },
+ [0x2DEC]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER ER",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DEC,
+ },
+ [0x2DED]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER ES",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DED,
+ },
+ [0x2DEE]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER TE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DEE,
+ },
+ [0x2DEF]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER HA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DEF,
+ },
+ [0x2DF0]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER TSE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF0,
+ },
+ [0x2DF1]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER CHE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF1,
+ },
+ [0x2DF2]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER SHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF2,
+ },
+ [0x2DF3]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER SHCHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF3,
+ },
+ [0x2DF4]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER FITA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF4,
+ },
+ [0x2DF5]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER ES-TE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF5,
+ },
+ [0x2DF6]={
+ category="mn",
+ cjkwd="w",
+ description="COMBINING CYRILLIC LETTER A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF6,
+ },
+ [0x2DF7]={
+ category="mn",
+ cjkwd="w",
+ description="COMBINING CYRILLIC LETTER IE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF7,
+ },
+ [0x2DF8]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER DJERV",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF8,
+ },
+ [0x2DF9]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER MONOGRAPH UK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DF9,
+ },
+ [0x2DFA]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER YAT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DFA,
+ },
+ [0x2DFB]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER YU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DFB,
+ },
+ [0x2DFC]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER IOTIFIED A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DFC,
+ },
+ [0x2DFD]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER LITTLE YUS",
+ direction="nsm",
+ linebreak="id",
+ unicodeslot=0x2DFD,
+ },
+ [0x2DFE]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER BIG YUS",
+ direction="nsm",
+ linebreak="id",
+ unicodeslot=0x2DFE,
+ },
+ [0x2DFF]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER IOTIFIED BIG YUS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x2DFF,
+ },
+ [0x2E00]={
+ category="po",
+ description="RIGHT ANGLE SUBSTITUTION MARKER",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2E00,
+ },
+ [0x2E01]={
+ category="po",
+ description="RIGHT ANGLE DOTTED SUBSTITUTION MARKER",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2E01,
+ },
+ [0x2E02]={
+ category="pi",
+ description="LEFT SUBSTITUTION BRACKET",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E03,
+ unicodeslot=0x2E02,
+ },
+ [0x2E03]={
+ category="pf",
+ description="RIGHT SUBSTITUTION BRACKET",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E02,
+ unicodeslot=0x2E03,
+ },
+ [0x2E04]={
+ category="pi",
+ description="LEFT DOTTED SUBSTITUTION BRACKET",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E05,
+ unicodeslot=0x2E04,
+ },
+ [0x2E05]={
+ category="pf",
+ description="RIGHT DOTTED SUBSTITUTION BRACKET",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E04,
+ unicodeslot=0x2E05,
+ },
+ [0x2E06]={
+ category="po",
+ description="RAISED INTERPOLATION MARKER",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2E06,
+ },
+ [0x2E07]={
+ category="po",
+ description="RAISED DOTTED INTERPOLATION MARKER",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2E07,
+ },
+ [0x2E08]={
+ category="po",
+ description="DOTTED TRANSPOSITION MARKER",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2E08,
+ },
+ [0x2E09]={
+ category="pi",
+ description="LEFT TRANSPOSITION BRACKET",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E0A,
+ unicodeslot=0x2E09,
+ },
+ [0x2E0A]={
+ category="pf",
+ description="RIGHT TRANSPOSITION BRACKET",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E09,
+ unicodeslot=0x2E0A,
+ },
+ [0x2E0B]={
+ category="po",
+ description="RAISED SQUARE",
+ direction="on",
+ linebreak="qu",
+ unicodeslot=0x2E0B,
+ },
+ [0x2E0C]={
+ category="pi",
+ description="LEFT RAISED OMISSION BRACKET",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E0D,
+ unicodeslot=0x2E0C,
+ },
+ [0x2E0D]={
+ category="pf",
+ description="RIGHT RAISED OMISSION BRACKET",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E0C,
+ unicodeslot=0x2E0D,
+ },
+ [0x2E0E]={
+ category="po",
+ description="EDITORIAL CORONIS",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E0E,
+ },
+ [0x2E0F]={
+ category="po",
+ description="PARAGRAPHOS",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E0F,
+ },
+ [0x2E10]={
+ category="po",
+ description="FORKED PARAGRAPHOS",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E10,
+ },
+ [0x2E11]={
+ category="po",
+ description="REVERSED FORKED PARAGRAPHOS",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E11,
+ },
+ [0x2E12]={
+ category="po",
+ description="HYPODIASTOLE",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E12,
+ },
+ [0x2E13]={
+ category="po",
+ description="DOTTED OBELOS",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E13,
+ },
+ [0x2E14]={
+ category="po",
+ description="DOWNWARDS ANCORA",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E14,
+ },
+ [0x2E15]={
+ category="po",
+ description="UPWARDS ANCORA",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E15,
+ },
+ [0x2E16]={
+ category="po",
+ description="DOTTED RIGHT-POINTING ANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E16,
+ },
+ [0x2E17]={
+ category="pd",
+ description="DOUBLE OBLIQUE HYPHEN",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E17,
+ },
+ [0x2E18]={
+ category="po",
+ description="INVERTED INTERROBANG",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0x2E18,
+ },
+ [0x2E19]={
+ category="po",
+ description="PALM BRANCH",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E19,
+ },
+ [0x2E1A]={
+ category="pd",
+ description="HYPHEN WITH DIAERESIS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E1A,
+ },
+ [0x2E1B]={
+ category="po",
+ description="TILDE WITH RING ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E1B,
+ },
+ [0x2E1C]={
+ category="pi",
+ description="LEFT LOW PARAPHRASE BRACKET",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E1D,
+ unicodeslot=0x2E1C,
+ },
+ [0x2E1D]={
+ category="pf",
+ description="RIGHT LOW PARAPHRASE BRACKET",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E1C,
+ unicodeslot=0x2E1D,
+ },
+ [0x2E1E]={
+ category="po",
+ description="TILDE WITH DOT ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E1E,
+ },
+ [0x2E1F]={
+ category="po",
+ description="TILDE WITH DOT BELOW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E1F,
+ },
+ [0x2E20]={
+ category="pi",
+ description="LEFT VERTICAL BAR WITH QUILL",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E21,
+ unicodeslot=0x2E20,
+ },
+ [0x2E21]={
+ category="pf",
+ description="RIGHT VERTICAL BAR WITH QUILL",
+ direction="on",
+ linebreak="qu",
+ mirror=0x2E20,
+ unicodeslot=0x2E21,
+ },
+ [0x2E22]={
+ category="ps",
+ description="TOP LEFT HALF BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x2E23,
+ unicodeslot=0x2E22,
+ },
+ [0x2E23]={
+ category="pe",
+ description="TOP RIGHT HALF BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2E22,
+ unicodeslot=0x2E23,
+ },
+ [0x2E24]={
+ category="ps",
+ description="BOTTOM LEFT HALF BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x2E25,
+ unicodeslot=0x2E24,
+ },
+ [0x2E25]={
+ category="pe",
+ description="BOTTOM RIGHT HALF BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2E24,
+ unicodeslot=0x2E25,
+ },
+ [0x2E26]={
+ category="ps",
+ description="LEFT SIDEWAYS U BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x2E27,
+ unicodeslot=0x2E26,
+ },
+ [0x2E27]={
+ category="pe",
+ description="RIGHT SIDEWAYS U BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2E26,
+ unicodeslot=0x2E27,
+ },
+ [0x2E28]={
+ category="ps",
+ description="LEFT DOUBLE PARENTHESIS",
+ direction="on",
+ linebreak="op",
+ mirror=0x2E29,
+ unicodeslot=0x2E28,
+ },
+ [0x2E29]={
+ category="pe",
+ description="RIGHT DOUBLE PARENTHESIS",
+ direction="on",
+ linebreak="cl",
+ mirror=0x2E28,
+ unicodeslot=0x2E29,
+ },
+ [0x2E2A]={
+ category="po",
+ description="TWO DOTS OVER ONE DOT PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E2A,
+ },
+ [0x2E2B]={
+ category="po",
+ description="ONE DOT OVER TWO DOTS PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E2B,
+ },
+ [0x2E2C]={
+ category="po",
+ description="SQUARED FOUR DOT PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E2C,
+ },
+ [0x2E2D]={
+ category="po",
+ description="FIVE DOT MARK",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E2D,
+ },
+ [0x2E2E]={
+ category="po",
+ description="REVERSED QUESTION MARK",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0x2E2E,
+ },
+ [0x2E2F]={
+ category="lm",
+ description="VERTICAL TILDE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E2F,
+ },
+ [0x2E30]={
+ category="po",
+ description="RING POINT",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E30,
+ },
+ [0x2E31]={
+ category="po",
+ description="WORD SEPARATOR MIDDLE DOT",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E31,
+ },
+ [0x2E32]={
+ category="po",
+ description="TURNED COMMA",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E32,
+ },
+ [0x2E33]={
+ category="po",
+ description="RAISED DOT",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E33,
+ },
+ [0x2E34]={
+ category="po",
+ description="RAISED COMMA",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x2E34,
+ },
+ [0x2E35]={
+ category="po",
+ description="TURNED SEMICOLON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E35,
+ },
+ [0x2E36]={
+ category="po",
+ description="DAGGER WITH LEFT GUARD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E36,
+ },
+ [0x2E37]={
+ category="po",
+ description="DAGGER WITH RIGHT GUARD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E37,
+ },
+ [0x2E38]={
+ category="po",
+ description="TURNED DAGGER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E38,
+ },
+ [0x2E39]={
+ category="po",
+ description="TOP HALF SECTION SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E39,
+ },
+ [0x2E3A]={
+ category="pd",
+ description="TWO-EM DASH",
+ direction="on",
+ linebreak="b2",
+ unicodeslot=0x2E3A,
+ },
+ [0x2E3B]={
+ category="pd",
+ description="THREE-EM DASH",
+ direction="on",
+ linebreak="b2",
+ unicodeslot=0x2E3B,
+ },
+ [0x2E80]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL REPEAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E80,
+ },
+ [0x2E81]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL CLIFF",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E81,
+ },
+ [0x2E82]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SECOND ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E82,
+ },
+ [0x2E83]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SECOND TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E83,
+ },
+ [0x2E84]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SECOND THREE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E84,
+ },
+ [0x2E85]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL PERSON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E85,
+ },
+ [0x2E86]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL BOX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E86,
+ },
+ [0x2E87]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL TABLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E87,
+ },
+ [0x2E88]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL KNIFE ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E88,
+ },
+ [0x2E89]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL KNIFE TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E89,
+ },
+ [0x2E8A]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL DIVINATION",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E8A,
+ },
+ [0x2E8B]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SEAL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E8B,
+ },
+ [0x2E8C]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SMALL ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E8C,
+ },
+ [0x2E8D]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SMALL TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E8D,
+ },
+ [0x2E8E]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL LAME ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E8E,
+ },
+ [0x2E8F]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL LAME TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E8F,
+ },
+ [0x2E90]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL LAME THREE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E90,
+ },
+ [0x2E91]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL LAME FOUR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E91,
+ },
+ [0x2E92]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SNAKE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E92,
+ },
+ [0x2E93]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL THREAD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E93,
+ },
+ [0x2E94]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SNOUT ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E94,
+ },
+ [0x2E95]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SNOUT TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E95,
+ },
+ [0x2E96]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL HEART ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E96,
+ },
+ [0x2E97]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL HEART TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E97,
+ },
+ [0x2E98]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL HAND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E98,
+ },
+ [0x2E99]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL RAP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E99,
+ },
+ [0x2E9B]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL CHOKE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E9B,
+ },
+ [0x2E9C]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SUN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E9C,
+ },
+ [0x2E9D]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL MOON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E9D,
+ },
+ [0x2E9E]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL DEATH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2E9E,
+ },
+ [0x2E9F]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL MOTHER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6BCD },
+ unicodeslot=0x2E9F,
+ },
+ [0x2EA0]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL CIVILIAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA0,
+ },
+ [0x2EA1]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL WATER ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA1,
+ },
+ [0x2EA2]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL WATER TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA2,
+ },
+ [0x2EA3]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL FIRE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA3,
+ },
+ [0x2EA4]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL PAW ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA4,
+ },
+ [0x2EA5]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL PAW TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA5,
+ },
+ [0x2EA6]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SIMPLIFIED HALF TREE TRUNK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA6,
+ },
+ [0x2EA7]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL COW",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA7,
+ },
+ [0x2EA8]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL DOG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA8,
+ },
+ [0x2EA9]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL JADE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EA9,
+ },
+ [0x2EAA]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL BOLT OF CLOTH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EAA,
+ },
+ [0x2EAB]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL EYE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EAB,
+ },
+ [0x2EAC]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SPIRIT ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EAC,
+ },
+ [0x2EAD]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SPIRIT TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EAD,
+ },
+ [0x2EAE]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL BAMBOO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EAE,
+ },
+ [0x2EAF]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SILK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EAF,
+ },
+ [0x2EB0]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED SILK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB0,
+ },
+ [0x2EB1]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL NET ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB1,
+ },
+ [0x2EB2]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL NET TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB2,
+ },
+ [0x2EB3]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL NET THREE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB3,
+ },
+ [0x2EB4]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL NET FOUR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB4,
+ },
+ [0x2EB5]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL MESH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB5,
+ },
+ [0x2EB6]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SHEEP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB6,
+ },
+ [0x2EB7]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL RAM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB7,
+ },
+ [0x2EB8]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL EWE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB8,
+ },
+ [0x2EB9]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL OLD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EB9,
+ },
+ [0x2EBA]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL BRUSH ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EBA,
+ },
+ [0x2EBB]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL BRUSH TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EBB,
+ },
+ [0x2EBC]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL MEAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EBC,
+ },
+ [0x2EBD]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL MORTAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EBD,
+ },
+ [0x2EBE]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL GRASS ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EBE,
+ },
+ [0x2EBF]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL GRASS TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EBF,
+ },
+ [0x2EC0]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL GRASS THREE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC0,
+ },
+ [0x2EC1]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL TIGER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC1,
+ },
+ [0x2EC2]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL CLOTHES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC2,
+ },
+ [0x2EC3]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL WEST ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC3,
+ },
+ [0x2EC4]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL WEST TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC4,
+ },
+ [0x2EC5]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED SEE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC5,
+ },
+ [0x2EC6]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SIMPLIFIED HORN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC6,
+ },
+ [0x2EC7]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL HORN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC7,
+ },
+ [0x2EC8]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED SPEECH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC8,
+ },
+ [0x2EC9]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED SHELL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EC9,
+ },
+ [0x2ECA]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL FOOT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ECA,
+ },
+ [0x2ECB]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED CART",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ECB,
+ },
+ [0x2ECC]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SIMPLIFIED WALK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ECC,
+ },
+ [0x2ECD]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL WALK ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ECD,
+ },
+ [0x2ECE]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL WALK TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ECE,
+ },
+ [0x2ECF]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL CITY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ECF,
+ },
+ [0x2ED0]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED GOLD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED0,
+ },
+ [0x2ED1]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL LONG ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED1,
+ },
+ [0x2ED2]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL LONG TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED2,
+ },
+ [0x2ED3]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED LONG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED3,
+ },
+ [0x2ED4]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED GATE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED4,
+ },
+ [0x2ED5]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL MOUND ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED5,
+ },
+ [0x2ED6]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL MOUND TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED6,
+ },
+ [0x2ED7]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL RAIN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED7,
+ },
+ [0x2ED8]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL BLUE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED8,
+ },
+ [0x2ED9]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED TANNED LEATHER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2ED9,
+ },
+ [0x2EDA]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED LEAF",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EDA,
+ },
+ [0x2EDB]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED WIND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EDB,
+ },
+ [0x2EDC]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED FLY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EDC,
+ },
+ [0x2EDD]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL EAT ONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EDD,
+ },
+ [0x2EDE]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL EAT TWO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EDE,
+ },
+ [0x2EDF]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL EAT THREE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EDF,
+ },
+ [0x2EE0]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED EAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE0,
+ },
+ [0x2EE1]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL HEAD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE1,
+ },
+ [0x2EE2]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED HORSE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE2,
+ },
+ [0x2EE3]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL BONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE3,
+ },
+ [0x2EE4]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL GHOST",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE4,
+ },
+ [0x2EE5]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED FISH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE5,
+ },
+ [0x2EE6]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED BIRD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE6,
+ },
+ [0x2EE7]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED SALT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE7,
+ },
+ [0x2EE8]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SIMPLIFIED WHEAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE8,
+ },
+ [0x2EE9]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL SIMPLIFIED YELLOW",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EE9,
+ },
+ [0x2EEA]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED FROG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EEA,
+ },
+ [0x2EEB]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL J-SIMPLIFIED EVEN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EEB,
+ },
+ [0x2EEC]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED EVEN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EEC,
+ },
+ [0x2EED]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL J-SIMPLIFIED TOOTH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EED,
+ },
+ [0x2EEE]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED TOOTH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EEE,
+ },
+ [0x2EEF]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL J-SIMPLIFIED DRAGON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EEF,
+ },
+ [0x2EF0]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED DRAGON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EF0,
+ },
+ [0x2EF1]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL TURTLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EF1,
+ },
+ [0x2EF2]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL J-SIMPLIFIED TURTLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2EF2,
+ },
+ [0x2EF3]={
+ category="so",
+ cjkwd="w",
+ description="CJK RADICAL C-SIMPLIFIED TURTLE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F9F },
+ unicodeslot=0x2EF3,
+ },
+ [0x2F00]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL ONE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E00 },
+ unicodeslot=0x2F00,
+ },
+ [0x2F01]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL LINE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E28 },
+ unicodeslot=0x2F01,
+ },
+ [0x2F02]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DOT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E36 },
+ unicodeslot=0x2F02,
+ },
+ [0x2F03]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SLASH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E3F },
+ unicodeslot=0x2F03,
+ },
+ [0x2F04]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SECOND",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E59 },
+ unicodeslot=0x2F04,
+ },
+ [0x2F05]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL HOOK",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E85 },
+ unicodeslot=0x2F05,
+ },
+ [0x2F06]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TWO",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4E8C },
+ unicodeslot=0x2F06,
+ },
+ [0x2F07]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL LID",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4EA0 },
+ unicodeslot=0x2F07,
+ },
+ [0x2F08]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL MAN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x4EBA },
+ unicodeslot=0x2F08,
+ },
+ [0x2F09]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL LEGS",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x513F },
+ unicodeslot=0x2F09,
+ },
+ [0x2F0A]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL ENTER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5165 },
+ unicodeslot=0x2F0A,
+ },
+ [0x2F0B]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL EIGHT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x516B },
+ unicodeslot=0x2F0B,
+ },
+ [0x2F0C]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DOWN BOX",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5182 },
+ unicodeslot=0x2F0C,
+ },
+ [0x2F0D]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL COVER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5196 },
+ unicodeslot=0x2F0D,
+ },
+ [0x2F0E]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL ICE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x51AB },
+ unicodeslot=0x2F0E,
+ },
+ [0x2F0F]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TABLE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x51E0 },
+ unicodeslot=0x2F0F,
+ },
+ [0x2F10]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL OPEN BOX",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x51F5 },
+ unicodeslot=0x2F10,
+ },
+ [0x2F11]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL KNIFE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5200 },
+ unicodeslot=0x2F11,
+ },
+ [0x2F12]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL POWER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x529B },
+ unicodeslot=0x2F12,
+ },
+ [0x2F13]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WRAP",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x52F9 },
+ unicodeslot=0x2F13,
+ },
+ [0x2F14]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SPOON",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5315 },
+ unicodeslot=0x2F14,
+ },
+ [0x2F15]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL RIGHT OPEN BOX",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x531A },
+ unicodeslot=0x2F15,
+ },
+ [0x2F16]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL HIDING ENCLOSURE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5338 },
+ unicodeslot=0x2F16,
+ },
+ [0x2F17]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TEN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5341 },
+ unicodeslot=0x2F17,
+ },
+ [0x2F18]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DIVINATION",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x535C },
+ unicodeslot=0x2F18,
+ },
+ [0x2F19]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SEAL",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5369 },
+ unicodeslot=0x2F19,
+ },
+ [0x2F1A]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL CLIFF",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5382 },
+ unicodeslot=0x2F1A,
+ },
+ [0x2F1B]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL PRIVATE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x53B6 },
+ unicodeslot=0x2F1B,
+ },
+ [0x2F1C]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL AGAIN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x53C8 },
+ unicodeslot=0x2F1C,
+ },
+ [0x2F1D]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL MOUTH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x53E3 },
+ unicodeslot=0x2F1D,
+ },
+ [0x2F1E]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL ENCLOSURE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x56D7 },
+ unicodeslot=0x2F1E,
+ },
+ [0x2F1F]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL EARTH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x571F },
+ unicodeslot=0x2F1F,
+ },
+ [0x2F20]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SCHOLAR",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x58EB },
+ unicodeslot=0x2F20,
+ },
+ [0x2F21]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL GO",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5902 },
+ unicodeslot=0x2F21,
+ },
+ [0x2F22]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL GO SLOWLY",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x590A },
+ unicodeslot=0x2F22,
+ },
+ [0x2F23]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL EVENING",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5915 },
+ unicodeslot=0x2F23,
+ },
+ [0x2F24]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BIG",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5927 },
+ unicodeslot=0x2F24,
+ },
+ [0x2F25]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WOMAN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5973 },
+ unicodeslot=0x2F25,
+ },
+ [0x2F26]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL CHILD",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5B50 },
+ unicodeslot=0x2F26,
+ },
+ [0x2F27]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL ROOF",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5B80 },
+ unicodeslot=0x2F27,
+ },
+ [0x2F28]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL INCH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5BF8 },
+ unicodeslot=0x2F28,
+ },
+ [0x2F29]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SMALL",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5C0F },
+ unicodeslot=0x2F29,
+ },
+ [0x2F2A]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL LAME",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5C22 },
+ unicodeslot=0x2F2A,
+ },
+ [0x2F2B]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL CORPSE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5C38 },
+ unicodeslot=0x2F2B,
+ },
+ [0x2F2C]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SPROUT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5C6E },
+ unicodeslot=0x2F2C,
+ },
+ [0x2F2D]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL MOUNTAIN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5C71 },
+ unicodeslot=0x2F2D,
+ },
+ [0x2F2E]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL RIVER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5DDB },
+ unicodeslot=0x2F2E,
+ },
+ [0x2F2F]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WORK",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5DE5 },
+ unicodeslot=0x2F2F,
+ },
+ [0x2F30]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL ONESELF",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5DF1 },
+ unicodeslot=0x2F30,
+ },
+ [0x2F31]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TURBAN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5DFE },
+ unicodeslot=0x2F31,
+ },
+ [0x2F32]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DRY",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5E72 },
+ unicodeslot=0x2F32,
+ },
+ [0x2F33]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SHORT THREAD",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5E7A },
+ unicodeslot=0x2F33,
+ },
+ [0x2F34]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DOTTED CLIFF",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5E7F },
+ unicodeslot=0x2F34,
+ },
+ [0x2F35]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL LONG STRIDE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5EF4 },
+ unicodeslot=0x2F35,
+ },
+ [0x2F36]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TWO HANDS",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5EFE },
+ unicodeslot=0x2F36,
+ },
+ [0x2F37]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SHOOT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F0B },
+ unicodeslot=0x2F37,
+ },
+ [0x2F38]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BOW",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F13 },
+ unicodeslot=0x2F38,
+ },
+ [0x2F39]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SNOUT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F50 },
+ unicodeslot=0x2F39,
+ },
+ [0x2F3A]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BRISTLE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F61 },
+ unicodeslot=0x2F3A,
+ },
+ [0x2F3B]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL STEP",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5F73 },
+ unicodeslot=0x2F3B,
+ },
+ [0x2F3C]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL HEART",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x5FC3 },
+ unicodeslot=0x2F3C,
+ },
+ [0x2F3D]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL HALBERD",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6208 },
+ unicodeslot=0x2F3D,
+ },
+ [0x2F3E]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DOOR",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6236 },
+ unicodeslot=0x2F3E,
+ },
+ [0x2F3F]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL HAND",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x624B },
+ unicodeslot=0x2F3F,
+ },
+ [0x2F40]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BRANCH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x652F },
+ unicodeslot=0x2F40,
+ },
+ [0x2F41]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL RAP",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6534 },
+ unicodeslot=0x2F41,
+ },
+ [0x2F42]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SCRIPT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6587 },
+ unicodeslot=0x2F42,
+ },
+ [0x2F43]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DIPPER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6597 },
+ unicodeslot=0x2F43,
+ },
+ [0x2F44]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL AXE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x65A4 },
+ unicodeslot=0x2F44,
+ },
+ [0x2F45]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SQUARE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x65B9 },
+ unicodeslot=0x2F45,
+ },
+ [0x2F46]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL NOT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x65E0 },
+ unicodeslot=0x2F46,
+ },
+ [0x2F47]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SUN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x65E5 },
+ unicodeslot=0x2F47,
+ },
+ [0x2F48]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SAY",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x66F0 },
+ unicodeslot=0x2F48,
+ },
+ [0x2F49]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL MOON",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6708 },
+ unicodeslot=0x2F49,
+ },
+ [0x2F4A]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TREE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6728 },
+ unicodeslot=0x2F4A,
+ },
+ [0x2F4B]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL LACK",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6B20 },
+ unicodeslot=0x2F4B,
+ },
+ [0x2F4C]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL STOP",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6B62 },
+ unicodeslot=0x2F4C,
+ },
+ [0x2F4D]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DEATH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6B79 },
+ unicodeslot=0x2F4D,
+ },
+ [0x2F4E]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WEAPON",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6BB3 },
+ unicodeslot=0x2F4E,
+ },
+ [0x2F4F]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DO NOT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6BCB },
+ unicodeslot=0x2F4F,
+ },
+ [0x2F50]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL COMPARE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6BD4 },
+ unicodeslot=0x2F50,
+ },
+ [0x2F51]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FUR",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6BDB },
+ unicodeslot=0x2F51,
+ },
+ [0x2F52]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL CLAN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6C0F },
+ unicodeslot=0x2F52,
+ },
+ [0x2F53]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL STEAM",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6C14 },
+ unicodeslot=0x2F53,
+ },
+ [0x2F54]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WATER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x6C34 },
+ unicodeslot=0x2F54,
+ },
+ [0x2F55]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FIRE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x706B },
+ unicodeslot=0x2F55,
+ },
+ [0x2F56]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL CLAW",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x722A },
+ unicodeslot=0x2F56,
+ },
+ [0x2F57]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FATHER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7236 },
+ unicodeslot=0x2F57,
+ },
+ [0x2F58]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DOUBLE X",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x723B },
+ unicodeslot=0x2F58,
+ },
+ [0x2F59]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL HALF TREE TRUNK",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x723F },
+ unicodeslot=0x2F59,
+ },
+ [0x2F5A]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SLICE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7247 },
+ unicodeslot=0x2F5A,
+ },
+ [0x2F5B]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FANG",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7259 },
+ unicodeslot=0x2F5B,
+ },
+ [0x2F5C]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL COW",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x725B },
+ unicodeslot=0x2F5C,
+ },
+ [0x2F5D]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DOG",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x72AC },
+ unicodeslot=0x2F5D,
+ },
+ [0x2F5E]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL PROFOUND",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7384 },
+ unicodeslot=0x2F5E,
+ },
+ [0x2F5F]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL JADE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7389 },
+ unicodeslot=0x2F5F,
+ },
+ [0x2F60]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL MELON",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x74DC },
+ unicodeslot=0x2F60,
+ },
+ [0x2F61]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TILE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x74E6 },
+ unicodeslot=0x2F61,
+ },
+ [0x2F62]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SWEET",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7518 },
+ unicodeslot=0x2F62,
+ },
+ [0x2F63]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL LIFE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x751F },
+ unicodeslot=0x2F63,
+ },
+ [0x2F64]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL USE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7528 },
+ unicodeslot=0x2F64,
+ },
+ [0x2F65]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FIELD",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7530 },
+ unicodeslot=0x2F65,
+ },
+ [0x2F66]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BOLT OF CLOTH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x758B },
+ unicodeslot=0x2F66,
+ },
+ [0x2F67]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SICKNESS",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7592 },
+ unicodeslot=0x2F67,
+ },
+ [0x2F68]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DOTTED TENT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7676 },
+ unicodeslot=0x2F68,
+ },
+ [0x2F69]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WHITE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x767D },
+ unicodeslot=0x2F69,
+ },
+ [0x2F6A]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SKIN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x76AE },
+ unicodeslot=0x2F6A,
+ },
+ [0x2F6B]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DISH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x76BF },
+ unicodeslot=0x2F6B,
+ },
+ [0x2F6C]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL EYE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x76EE },
+ unicodeslot=0x2F6C,
+ },
+ [0x2F6D]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SPEAR",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x77DB },
+ unicodeslot=0x2F6D,
+ },
+ [0x2F6E]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL ARROW",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x77E2 },
+ unicodeslot=0x2F6E,
+ },
+ [0x2F6F]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL STONE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x77F3 },
+ unicodeslot=0x2F6F,
+ },
+ [0x2F70]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SPIRIT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x793A },
+ unicodeslot=0x2F70,
+ },
+ [0x2F71]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TRACK",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x79B8 },
+ unicodeslot=0x2F71,
+ },
+ [0x2F72]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL GRAIN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x79BE },
+ unicodeslot=0x2F72,
+ },
+ [0x2F73]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL CAVE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7A74 },
+ unicodeslot=0x2F73,
+ },
+ [0x2F74]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL STAND",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7ACB },
+ unicodeslot=0x2F74,
+ },
+ [0x2F75]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BAMBOO",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7AF9 },
+ unicodeslot=0x2F75,
+ },
+ [0x2F76]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL RICE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7C73 },
+ unicodeslot=0x2F76,
+ },
+ [0x2F77]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SILK",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7CF8 },
+ unicodeslot=0x2F77,
+ },
+ [0x2F78]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL JAR",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7F36 },
+ unicodeslot=0x2F78,
+ },
+ [0x2F79]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL NET",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7F51 },
+ unicodeslot=0x2F79,
+ },
+ [0x2F7A]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SHEEP",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7F8A },
+ unicodeslot=0x2F7A,
+ },
+ [0x2F7B]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FEATHER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x7FBD },
+ unicodeslot=0x2F7B,
+ },
+ [0x2F7C]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL OLD",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8001 },
+ unicodeslot=0x2F7C,
+ },
+ [0x2F7D]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL AND",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x800C },
+ unicodeslot=0x2F7D,
+ },
+ [0x2F7E]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL PLOW",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8012 },
+ unicodeslot=0x2F7E,
+ },
+ [0x2F7F]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL EAR",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8033 },
+ unicodeslot=0x2F7F,
+ },
+ [0x2F80]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BRUSH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x807F },
+ unicodeslot=0x2F80,
+ },
+ [0x2F81]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL MEAT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8089 },
+ unicodeslot=0x2F81,
+ },
+ [0x2F82]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL MINISTER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x81E3 },
+ unicodeslot=0x2F82,
+ },
+ [0x2F83]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SELF",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x81EA },
+ unicodeslot=0x2F83,
+ },
+ [0x2F84]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL ARRIVE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x81F3 },
+ unicodeslot=0x2F84,
+ },
+ [0x2F85]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL MORTAR",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x81FC },
+ unicodeslot=0x2F85,
+ },
+ [0x2F86]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TONGUE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x820C },
+ unicodeslot=0x2F86,
+ },
+ [0x2F87]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL OPPOSE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x821B },
+ unicodeslot=0x2F87,
+ },
+ [0x2F88]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BOAT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x821F },
+ unicodeslot=0x2F88,
+ },
+ [0x2F89]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL STOPPING",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x826E },
+ unicodeslot=0x2F89,
+ },
+ [0x2F8A]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL COLOR",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8272 },
+ unicodeslot=0x2F8A,
+ },
+ [0x2F8B]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL GRASS",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8278 },
+ unicodeslot=0x2F8B,
+ },
+ [0x2F8C]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TIGER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x864D },
+ unicodeslot=0x2F8C,
+ },
+ [0x2F8D]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL INSECT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x866B },
+ unicodeslot=0x2F8D,
+ },
+ [0x2F8E]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BLOOD",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8840 },
+ unicodeslot=0x2F8E,
+ },
+ [0x2F8F]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WALK ENCLOSURE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x884C },
+ unicodeslot=0x2F8F,
+ },
+ [0x2F90]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL CLOTHES",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8863 },
+ unicodeslot=0x2F90,
+ },
+ [0x2F91]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WEST",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x897E },
+ unicodeslot=0x2F91,
+ },
+ [0x2F92]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SEE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x898B },
+ unicodeslot=0x2F92,
+ },
+ [0x2F93]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL HORN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x89D2 },
+ unicodeslot=0x2F93,
+ },
+ [0x2F94]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SPEECH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8A00 },
+ unicodeslot=0x2F94,
+ },
+ [0x2F95]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL VALLEY",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8C37 },
+ unicodeslot=0x2F95,
+ },
+ [0x2F96]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BEAN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8C46 },
+ unicodeslot=0x2F96,
+ },
+ [0x2F97]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL PIG",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8C55 },
+ unicodeslot=0x2F97,
+ },
+ [0x2F98]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BADGER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8C78 },
+ unicodeslot=0x2F98,
+ },
+ [0x2F99]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SHELL",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8C9D },
+ unicodeslot=0x2F99,
+ },
+ [0x2F9A]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL RED",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8D64 },
+ unicodeslot=0x2F9A,
+ },
+ [0x2F9B]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL RUN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8D70 },
+ unicodeslot=0x2F9B,
+ },
+ [0x2F9C]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FOOT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8DB3 },
+ unicodeslot=0x2F9C,
+ },
+ [0x2F9D]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BODY",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8EAB },
+ unicodeslot=0x2F9D,
+ },
+ [0x2F9E]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL CART",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8ECA },
+ unicodeslot=0x2F9E,
+ },
+ [0x2F9F]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BITTER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8F9B },
+ unicodeslot=0x2F9F,
+ },
+ [0x2FA0]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL MORNING",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8FB0 },
+ unicodeslot=0x2FA0,
+ },
+ [0x2FA1]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WALK",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x8FB5 },
+ unicodeslot=0x2FA1,
+ },
+ [0x2FA2]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL CITY",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9091 },
+ unicodeslot=0x2FA2,
+ },
+ [0x2FA3]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WINE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9149 },
+ unicodeslot=0x2FA3,
+ },
+ [0x2FA4]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DISTINGUISH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x91C6 },
+ unicodeslot=0x2FA4,
+ },
+ [0x2FA5]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL VILLAGE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x91CC },
+ unicodeslot=0x2FA5,
+ },
+ [0x2FA6]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL GOLD",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x91D1 },
+ unicodeslot=0x2FA6,
+ },
+ [0x2FA7]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL LONG",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9577 },
+ unicodeslot=0x2FA7,
+ },
+ [0x2FA8]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL GATE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9580 },
+ unicodeslot=0x2FA8,
+ },
+ [0x2FA9]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL MOUND",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x961C },
+ unicodeslot=0x2FA9,
+ },
+ [0x2FAA]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SLAVE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x96B6 },
+ unicodeslot=0x2FAA,
+ },
+ [0x2FAB]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SHORT TAILED BIRD",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x96B9 },
+ unicodeslot=0x2FAB,
+ },
+ [0x2FAC]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL RAIN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x96E8 },
+ unicodeslot=0x2FAC,
+ },
+ [0x2FAD]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BLUE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9751 },
+ unicodeslot=0x2FAD,
+ },
+ [0x2FAE]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WRONG",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x975E },
+ unicodeslot=0x2FAE,
+ },
+ [0x2FAF]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FACE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9762 },
+ unicodeslot=0x2FAF,
+ },
+ [0x2FB0]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL LEATHER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9769 },
+ unicodeslot=0x2FB0,
+ },
+ [0x2FB1]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TANNED LEATHER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x97CB },
+ unicodeslot=0x2FB1,
+ },
+ [0x2FB2]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL LEEK",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x97ED },
+ unicodeslot=0x2FB2,
+ },
+ [0x2FB3]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SOUND",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x97F3 },
+ unicodeslot=0x2FB3,
+ },
+ [0x2FB4]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL LEAF",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9801 },
+ unicodeslot=0x2FB4,
+ },
+ [0x2FB5]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WIND",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x98A8 },
+ unicodeslot=0x2FB5,
+ },
+ [0x2FB6]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FLY",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x98DB },
+ unicodeslot=0x2FB6,
+ },
+ [0x2FB7]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL EAT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x98DF },
+ unicodeslot=0x2FB7,
+ },
+ [0x2FB8]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL HEAD",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9996 },
+ unicodeslot=0x2FB8,
+ },
+ [0x2FB9]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FRAGRANT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9999 },
+ unicodeslot=0x2FB9,
+ },
+ [0x2FBA]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL HORSE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x99AC },
+ unicodeslot=0x2FBA,
+ },
+ [0x2FBB]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BONE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9AA8 },
+ unicodeslot=0x2FBB,
+ },
+ [0x2FBC]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TALL",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9AD8 },
+ unicodeslot=0x2FBC,
+ },
+ [0x2FBD]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL HAIR",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9ADF },
+ unicodeslot=0x2FBD,
+ },
+ [0x2FBE]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FIGHT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9B25 },
+ unicodeslot=0x2FBE,
+ },
+ [0x2FBF]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SACRIFICIAL WINE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9B2F },
+ unicodeslot=0x2FBF,
+ },
+ [0x2FC0]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL CAULDRON",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9B32 },
+ unicodeslot=0x2FC0,
+ },
+ [0x2FC1]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL GHOST",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9B3C },
+ unicodeslot=0x2FC1,
+ },
+ [0x2FC2]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FISH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9B5A },
+ unicodeslot=0x2FC2,
+ },
+ [0x2FC3]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BIRD",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9CE5 },
+ unicodeslot=0x2FC3,
+ },
+ [0x2FC4]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL SALT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9E75 },
+ unicodeslot=0x2FC4,
+ },
+ [0x2FC5]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DEER",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9E7F },
+ unicodeslot=0x2FC5,
+ },
+ [0x2FC6]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL WHEAT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9EA5 },
+ unicodeslot=0x2FC6,
+ },
+ [0x2FC7]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL HEMP",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9EBB },
+ unicodeslot=0x2FC7,
+ },
+ [0x2FC8]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL YELLOW",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9EC3 },
+ unicodeslot=0x2FC8,
+ },
+ [0x2FC9]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL MILLET",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9ECD },
+ unicodeslot=0x2FC9,
+ },
+ [0x2FCA]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL BLACK",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9ED1 },
+ unicodeslot=0x2FCA,
+ },
+ [0x2FCB]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL EMBROIDERY",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9EF9 },
+ unicodeslot=0x2FCB,
+ },
+ [0x2FCC]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FROG",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9EFD },
+ unicodeslot=0x2FCC,
+ },
+ [0x2FCD]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TRIPOD",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F0E },
+ unicodeslot=0x2FCD,
+ },
+ [0x2FCE]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DRUM",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F13 },
+ unicodeslot=0x2FCE,
+ },
+ [0x2FCF]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL RAT",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F20 },
+ unicodeslot=0x2FCF,
+ },
+ [0x2FD0]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL NOSE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F3B },
+ unicodeslot=0x2FD0,
+ },
+ [0x2FD1]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL EVEN",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F4A },
+ unicodeslot=0x2FD1,
+ },
+ [0x2FD2]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TOOTH",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F52 },
+ unicodeslot=0x2FD2,
+ },
+ [0x2FD3]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL DRAGON",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F8D },
+ unicodeslot=0x2FD3,
+ },
+ [0x2FD4]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL TURTLE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9F9C },
+ unicodeslot=0x2FD4,
+ },
+ [0x2FD5]={
+ category="so",
+ cjkwd="w",
+ description="KANGXI RADICAL FLUTE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x9FA0 },
+ unicodeslot=0x2FD5,
+ },
+ [0x2FF0]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF0,
+ },
+ [0x2FF1]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF1,
+ },
+ [0x2FF2]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF2,
+ },
+ [0x2FF3]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF3,
+ },
+ [0x2FF4]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF4,
+ },
+ [0x2FF5]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF5,
+ },
+ [0x2FF6]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF6,
+ },
+ [0x2FF7]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF7,
+ },
+ [0x2FF8]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF8,
+ },
+ [0x2FF9]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FF9,
+ },
+ [0x2FFA]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FFA,
+ },
+ [0x2FFB]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x2FFB,
+ },
+ [0x3000]={
+ adobename="ideographicspace",
+ category="zs",
+ cjkwd="f",
+ contextname="ideographicspace",
+ description="IDEOGRAPHIC SPACE",
+ direction="ws",
+ linebreak="id",
+ specials={ "wide", 0x0020 },
+ unicodeslot=0x3000,
+ },
+ [0x3001]={
+ adobename="ideographiccomma",
+ category="po",
+ cjkwd="w",
+ description="IDEOGRAPHIC COMMA",
+ direction="on",
+ linebreak="cl",
+ unicodeslot=0x3001,
+ },
+ [0x3002]={
+ adobename="ideographicperiod",
+ category="po",
+ cjkwd="w",
+ description="IDEOGRAPHIC FULL STOP",
+ direction="on",
+ linebreak="cl",
+ unicodeslot=0x3002,
+ },
+ [0x3003]={
+ adobename="dittomark",
+ category="po",
+ cjkwd="w",
+ description="DITTO MARK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3003,
+ },
+ [0x3004]={
+ adobename="jis",
+ category="so",
+ cjkwd="w",
+ description="JAPANESE INDUSTRIAL STANDARD SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3004,
+ },
+ [0x3005]={
+ adobename="ideographiciterationmark",
+ category="lm",
+ cjkwd="w",
+ description="IDEOGRAPHIC ITERATION MARK",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x3005,
+ },
+ [0x3006]={
+ adobename="ideographicclose",
+ category="lo",
+ cjkwd="w",
+ description="IDEOGRAPHIC CLOSING MARK",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3006,
+ },
+ [0x3007]={
+ adobename="ideographiczero",
+ category="nl",
+ cjkwd="w",
+ description="IDEOGRAPHIC NUMBER ZERO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3007,
+ },
+ [0x3008]={
+ adobename="anglebracketleft",
+ category="ps",
+ cjkwd="w",
+ description="LEFT ANGLE BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x3009,
+ unicodeslot=0x3008,
+ },
+ [0x3009]={
+ adobename="anglebracketright",
+ category="pe",
+ cjkwd="w",
+ description="RIGHT ANGLE BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x3008,
+ unicodeslot=0x3009,
+ },
+ [0x300A]={
+ adobename="dblanglebracketleft",
+ category="ps",
+ cjkwd="w",
+ description="LEFT DOUBLE ANGLE BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x300B,
+ unicodeslot=0x300A,
+ },
+ [0x300B]={
+ adobename="dblanglebracketright",
+ category="pe",
+ cjkwd="w",
+ description="RIGHT DOUBLE ANGLE BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x300A,
+ unicodeslot=0x300B,
+ },
+ [0x300C]={
+ adobename="cornerbracketleft",
+ category="ps",
+ cjkwd="w",
+ description="LEFT CORNER BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x300D,
+ unicodeslot=0x300C,
+ },
+ [0x300D]={
+ adobename="cornerbracketright",
+ category="pe",
+ cjkwd="w",
+ description="RIGHT CORNER BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x300C,
+ unicodeslot=0x300D,
+ },
+ [0x300E]={
+ adobename="whitecornerbracketleft",
+ category="ps",
+ cjkwd="w",
+ description="LEFT WHITE CORNER BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x300F,
+ unicodeslot=0x300E,
+ },
+ [0x300F]={
+ adobename="whitecornerbracketright",
+ category="pe",
+ cjkwd="w",
+ description="RIGHT WHITE CORNER BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x300E,
+ unicodeslot=0x300F,
+ },
+ [0x3010]={
+ adobename="blacklenticularbracketleft",
+ category="ps",
+ cjkwd="w",
+ description="LEFT BLACK LENTICULAR BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x3011,
+ unicodeslot=0x3010,
+ },
+ [0x3011]={
+ adobename="blacklenticularbracketright",
+ category="pe",
+ cjkwd="w",
+ description="RIGHT BLACK LENTICULAR BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x3010,
+ unicodeslot=0x3011,
+ },
+ [0x3012]={
+ adobename="postalmark",
+ category="so",
+ cjkwd="w",
+ description="POSTAL MARK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3012,
+ },
+ [0x3013]={
+ adobename="getamark",
+ category="so",
+ cjkwd="w",
+ description="GETA MARK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3013,
+ },
+ [0x3014]={
+ adobename="tortoiseshellbracketleft",
+ category="ps",
+ cjkwd="w",
+ description="LEFT TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x3015,
+ unicodeslot=0x3014,
+ },
+ [0x3015]={
+ adobename="tortoiseshellbracketright",
+ category="pe",
+ cjkwd="w",
+ description="RIGHT TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x3014,
+ unicodeslot=0x3015,
+ },
+ [0x3016]={
+ adobename="whitelenticularbracketleft",
+ category="ps",
+ cjkwd="w",
+ description="LEFT WHITE LENTICULAR BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x3017,
+ unicodeslot=0x3016,
+ },
+ [0x3017]={
+ adobename="whitelenticularbracketright",
+ category="pe",
+ cjkwd="w",
+ description="RIGHT WHITE LENTICULAR BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x3016,
+ unicodeslot=0x3017,
+ },
+ [0x3018]={
+ adobename="whitetortoiseshellbracketleft",
+ category="ps",
+ cjkwd="w",
+ description="LEFT WHITE TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x3019,
+ unicodeslot=0x3018,
+ },
+ [0x3019]={
+ adobename="whitetortoiseshellbracketright",
+ category="pe",
+ cjkwd="w",
+ description="RIGHT WHITE TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x3018,
+ unicodeslot=0x3019,
+ },
+ [0x301A]={
+ category="ps",
+ cjkwd="w",
+ description="LEFT WHITE SQUARE BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0x301B,
+ unicodeslot=0x301A,
+ },
+ [0x301B]={
+ category="pe",
+ cjkwd="w",
+ description="RIGHT WHITE SQUARE BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0x301A,
+ unicodeslot=0x301B,
+ },
+ [0x301C]={
+ adobename="wavedash",
+ category="pd",
+ cjkwd="w",
+ description="WAVE DASH",
+ direction="on",
+ linebreak="ns",
+ unicodeslot=0x301C,
+ },
+ [0x301D]={
+ adobename="quotedblprimereversed",
+ category="ps",
+ cjkwd="w",
+ description="REVERSED DOUBLE PRIME QUOTATION MARK",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0x301D,
+ },
+ [0x301E]={
+ adobename="quotedblprime",
+ category="pe",
+ cjkwd="w",
+ description="DOUBLE PRIME QUOTATION MARK",
+ direction="on",
+ linebreak="cl",
+ unicodeslot=0x301E,
+ },
+ [0x301F]={
+ category="pe",
+ cjkwd="w",
+ description="LOW DOUBLE PRIME QUOTATION MARK",
+ direction="on",
+ linebreak="cl",
+ unicodeslot=0x301F,
+ },
+ [0x3020]={
+ adobename="postalmarkface",
+ category="so",
+ cjkwd="w",
+ description="POSTAL MARK FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3020,
+ },
+ [0x3021]={
+ adobename="onehangzhou",
+ category="nl",
+ cjkwd="w",
+ description="HANGZHOU NUMERAL ONE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3021,
+ },
+ [0x3022]={
+ adobename="twohangzhou",
+ category="nl",
+ cjkwd="w",
+ description="HANGZHOU NUMERAL TWO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3022,
+ },
+ [0x3023]={
+ adobename="threehangzhou",
+ category="nl",
+ cjkwd="w",
+ description="HANGZHOU NUMERAL THREE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3023,
+ },
+ [0x3024]={
+ adobename="fourhangzhou",
+ category="nl",
+ cjkwd="w",
+ description="HANGZHOU NUMERAL FOUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3024,
+ },
+ [0x3025]={
+ adobename="fivehangzhou",
+ category="nl",
+ cjkwd="w",
+ description="HANGZHOU NUMERAL FIVE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3025,
+ },
+ [0x3026]={
+ adobename="sixhangzhou",
+ category="nl",
+ cjkwd="w",
+ description="HANGZHOU NUMERAL SIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3026,
+ },
+ [0x3027]={
+ adobename="sevenhangzhou",
+ category="nl",
+ cjkwd="w",
+ description="HANGZHOU NUMERAL SEVEN",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3027,
+ },
+ [0x3028]={
+ adobename="eighthangzhou",
+ category="nl",
+ cjkwd="w",
+ description="HANGZHOU NUMERAL EIGHT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3028,
+ },
+ [0x3029]={
+ adobename="ninehangzhou",
+ category="nl",
+ cjkwd="w",
+ description="HANGZHOU NUMERAL NINE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3029,
+ },
+ [0x302A]={
+ category="mn",
+ cjkwd="w",
+ description="IDEOGRAPHIC LEVEL TONE MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x302A,
+ },
+ [0x302B]={
+ category="mn",
+ cjkwd="w",
+ description="IDEOGRAPHIC RISING TONE MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x302B,
+ },
+ [0x302C]={
+ category="mn",
+ cjkwd="w",
+ description="IDEOGRAPHIC DEPARTING TONE MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x302C,
+ },
+ [0x302D]={
+ category="mn",
+ cjkwd="w",
+ description="IDEOGRAPHIC ENTERING TONE MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x302D,
+ },
+ [0x302E]={
+ category="mn",
+ cjkwd="w",
+ description="HANGUL SINGLE DOT TONE MARK",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x302E,
+ },
+ [0x302F]={
+ category="mn",
+ cjkwd="w",
+ description="HANGUL DOUBLE DOT TONE MARK",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x302F,
+ },
+ [0x3030]={
+ category="pd",
+ cjkwd="w",
+ description="WAVY DASH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3030,
+ },
+ [0x3031]={
+ category="lm",
+ cjkwd="w",
+ description="VERTICAL KANA REPEAT MARK",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3031,
+ },
+ [0x3032]={
+ category="lm",
+ cjkwd="w",
+ description="VERTICAL KANA REPEAT WITH VOICED SOUND MARK",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3032,
+ },
+ [0x3033]={
+ category="lm",
+ cjkwd="w",
+ description="VERTICAL KANA REPEAT MARK UPPER HALF",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3033,
+ },
+ [0x3034]={
+ category="lm",
+ cjkwd="w",
+ description="VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3034,
+ },
+ [0x3035]={
+ category="lm",
+ cjkwd="w",
+ description="VERTICAL KANA REPEAT MARK LOWER HALF",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3035,
+ },
+ [0x3036]={
+ adobename="circlepostalmark",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED POSTAL MARK",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x3012 },
+ unicodeslot=0x3036,
+ },
+ [0x3037]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x3037,
+ },
+ [0x3038]={
+ category="nl",
+ cjkwd="w",
+ description="HANGZHOU NUMERAL TEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x5341 },
+ unicodeslot=0x3038,
+ },
+ [0x3039]={
+ category="nl",
+ cjkwd="w",
+ description="HANGZHOU NUMERAL TWENTY",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x5344 },
+ unicodeslot=0x3039,
+ },
+ [0x303A]={
+ category="nl",
+ cjkwd="w",
+ description="HANGZHOU NUMERAL THIRTY",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x5345 },
+ unicodeslot=0x303A,
+ },
+ [0x303B]={
+ category="lm",
+ cjkwd="w",
+ description="VERTICAL IDEOGRAPHIC ITERATION MARK",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x303B,
+ },
+ [0x303C]={
+ category="lo",
+ cjkwd="w",
+ description="MASU MARK",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x303C,
+ },
+ [0x303D]={
+ category="po",
+ cjkwd="w",
+ description="PART ALTERNATION MARK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x303D,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x303E]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC VARIATION INDICATOR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x303E,
+ },
+ [0x303F]={
+ category="so",
+ contextname="ideographichalffillspace",
+ description="IDEOGRAPHIC HALF FILL SPACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x303F,
+ },
+ [0x3041]={
+ adobename="asmallhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SMALL A",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3041,
+ },
+ [0x3042]={
+ adobename="ahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER A",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3042,
+ },
+ [0x3043]={
+ adobename="ismallhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SMALL I",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3043,
+ },
+ [0x3044]={
+ adobename="ihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER I",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3044,
+ },
+ [0x3045]={
+ adobename="usmallhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SMALL U",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3045,
+ },
+ [0x3046]={
+ adobename="uhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER U",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3046,
+ },
+ [0x3047]={
+ adobename="esmallhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SMALL E",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3047,
+ },
+ [0x3048]={
+ adobename="ehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER E",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3048,
+ },
+ [0x3049]={
+ adobename="osmallhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SMALL O",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3049,
+ },
+ [0x304A]={
+ adobename="ohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER O",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x304A,
+ },
+ [0x304B]={
+ adobename="kahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER KA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x304B,
+ },
+ [0x304C]={
+ adobename="gahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER GA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x304B, 0x3099 },
+ unicodeslot=0x304C,
+ },
+ [0x304D]={
+ adobename="kihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER KI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x304D,
+ },
+ [0x304E]={
+ adobename="gihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER GI",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x304D, 0x3099 },
+ unicodeslot=0x304E,
+ },
+ [0x304F]={
+ adobename="kuhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER KU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x304F,
+ },
+ [0x3050]={
+ adobename="guhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER GU",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x304F, 0x3099 },
+ unicodeslot=0x3050,
+ },
+ [0x3051]={
+ adobename="kehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER KE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3051,
+ },
+ [0x3052]={
+ adobename="gehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER GE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3051, 0x3099 },
+ unicodeslot=0x3052,
+ },
+ [0x3053]={
+ adobename="kohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER KO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3053,
+ },
+ [0x3054]={
+ adobename="gohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER GO",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3053, 0x3099 },
+ unicodeslot=0x3054,
+ },
+ [0x3055]={
+ adobename="sahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3055,
+ },
+ [0x3056]={
+ adobename="zahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER ZA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3055, 0x3099 },
+ unicodeslot=0x3056,
+ },
+ [0x3057]={
+ adobename="sihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3057,
+ },
+ [0x3058]={
+ adobename="zihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER ZI",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3057, 0x3099 },
+ unicodeslot=0x3058,
+ },
+ [0x3059]={
+ adobename="suhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3059,
+ },
+ [0x305A]={
+ adobename="zuhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER ZU",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3059, 0x3099 },
+ unicodeslot=0x305A,
+ },
+ [0x305B]={
+ adobename="sehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x305B,
+ },
+ [0x305C]={
+ adobename="zehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER ZE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x305B, 0x3099 },
+ unicodeslot=0x305C,
+ },
+ [0x305D]={
+ adobename="sohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x305D,
+ },
+ [0x305E]={
+ adobename="zohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER ZO",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x305D, 0x3099 },
+ unicodeslot=0x305E,
+ },
+ [0x305F]={
+ adobename="tahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER TA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x305F,
+ },
+ [0x3060]={
+ adobename="dahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER DA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x305F, 0x3099 },
+ unicodeslot=0x3060,
+ },
+ [0x3061]={
+ adobename="tihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER TI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3061,
+ },
+ [0x3062]={
+ adobename="dihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER DI",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3061, 0x3099 },
+ unicodeslot=0x3062,
+ },
+ [0x3063]={
+ adobename="tusmallhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SMALL TU",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3063,
+ },
+ [0x3064]={
+ adobename="tuhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER TU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3064,
+ },
+ [0x3065]={
+ adobename="duhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER DU",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3064, 0x3099 },
+ unicodeslot=0x3065,
+ },
+ [0x3066]={
+ adobename="tehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER TE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3066,
+ },
+ [0x3067]={
+ adobename="dehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER DE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3066, 0x3099 },
+ unicodeslot=0x3067,
+ },
+ [0x3068]={
+ adobename="tohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER TO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3068,
+ },
+ [0x3069]={
+ adobename="dohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER DO",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3068, 0x3099 },
+ unicodeslot=0x3069,
+ },
+ [0x306A]={
+ adobename="nahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER NA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x306A,
+ },
+ [0x306B]={
+ adobename="nihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER NI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x306B,
+ },
+ [0x306C]={
+ adobename="nuhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER NU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x306C,
+ },
+ [0x306D]={
+ adobename="nehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER NE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x306D,
+ },
+ [0x306E]={
+ adobename="nohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER NO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x306E,
+ },
+ [0x306F]={
+ adobename="hahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER HA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x306F,
+ },
+ [0x3070]={
+ adobename="bahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER BA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x306F, 0x3099 },
+ unicodeslot=0x3070,
+ },
+ [0x3071]={
+ adobename="pahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER PA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x306F, 0x309A },
+ unicodeslot=0x3071,
+ },
+ [0x3072]={
+ adobename="hihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER HI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3072,
+ },
+ [0x3073]={
+ adobename="bihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER BI",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3072, 0x3099 },
+ unicodeslot=0x3073,
+ },
+ [0x3074]={
+ adobename="pihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER PI",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3072, 0x309A },
+ unicodeslot=0x3074,
+ },
+ [0x3075]={
+ adobename="huhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER HU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3075,
+ },
+ [0x3076]={
+ adobename="buhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER BU",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3075, 0x3099 },
+ unicodeslot=0x3076,
+ },
+ [0x3077]={
+ adobename="puhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER PU",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3075, 0x309A },
+ unicodeslot=0x3077,
+ },
+ [0x3078]={
+ adobename="hehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER HE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3078,
+ },
+ [0x3079]={
+ adobename="behiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER BE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3078, 0x3099 },
+ unicodeslot=0x3079,
+ },
+ [0x307A]={
+ adobename="pehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER PE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3078, 0x309A },
+ unicodeslot=0x307A,
+ },
+ [0x307B]={
+ adobename="hohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER HO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x307B,
+ },
+ [0x307C]={
+ adobename="bohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER BO",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x307B, 0x3099 },
+ unicodeslot=0x307C,
+ },
+ [0x307D]={
+ adobename="pohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER PO",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x307B, 0x309A },
+ unicodeslot=0x307D,
+ },
+ [0x307E]={
+ adobename="mahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER MA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x307E,
+ },
+ [0x307F]={
+ adobename="mihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER MI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x307F,
+ },
+ [0x3080]={
+ adobename="muhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER MU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3080,
+ },
+ [0x3081]={
+ adobename="mehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER ME",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3081,
+ },
+ [0x3082]={
+ adobename="mohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER MO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3082,
+ },
+ [0x3083]={
+ adobename="yasmallhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SMALL YA",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3083,
+ },
+ [0x3084]={
+ adobename="yahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER YA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3084,
+ },
+ [0x3085]={
+ adobename="yusmallhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SMALL YU",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3085,
+ },
+ [0x3086]={
+ adobename="yuhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER YU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3086,
+ },
+ [0x3087]={
+ adobename="yosmallhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SMALL YO",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3087,
+ },
+ [0x3088]={
+ adobename="yohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER YO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3088,
+ },
+ [0x3089]={
+ adobename="rahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER RA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3089,
+ },
+ [0x308A]={
+ adobename="rihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER RI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x308A,
+ },
+ [0x308B]={
+ adobename="ruhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER RU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x308B,
+ },
+ [0x308C]={
+ adobename="rehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER RE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x308C,
+ },
+ [0x308D]={
+ adobename="rohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER RO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x308D,
+ },
+ [0x308E]={
+ adobename="wasmallhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SMALL WA",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x308E,
+ },
+ [0x308F]={
+ adobename="wahiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER WA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x308F,
+ },
+ [0x3090]={
+ adobename="wihiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER WI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3090,
+ },
+ [0x3091]={
+ adobename="wehiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER WE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3091,
+ },
+ [0x3092]={
+ adobename="wohiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER WO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3092,
+ },
+ [0x3093]={
+ adobename="nhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER N",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3093,
+ },
+ [0x3094]={
+ adobename="vuhiragana",
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER VU",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3046, 0x3099 },
+ unicodeslot=0x3094,
+ },
+ [0x3095]={
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SMALL KA",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3095,
+ },
+ [0x3096]={
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER SMALL KE",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x3096,
+ },
+ [0x3099]={
+ category="mn",
+ cjkwd="w",
+ description="COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x3099,
+ },
+ [0x309A]={
+ category="mn",
+ cjkwd="w",
+ description="COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x309A,
+ },
+ [0x309B]={
+ adobename="voicedmarkkana",
+ category="sk",
+ cjkwd="w",
+ description="KATAKANA-HIRAGANA VOICED SOUND MARK",
+ direction="on",
+ linebreak="ns",
+ specials={ "compat", 0x0020, 0x3099 },
+ unicodeslot=0x309B,
+ },
+ [0x309C]={
+ adobename="semivoicedmarkkana",
+ category="sk",
+ cjkwd="w",
+ description="KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK",
+ direction="on",
+ linebreak="ns",
+ specials={ "compat", 0x0020, 0x309A },
+ unicodeslot=0x309C,
+ },
+ [0x309D]={
+ adobename="iterationhiragana",
+ category="lm",
+ cjkwd="w",
+ description="HIRAGANA ITERATION MARK",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x309D,
+ },
+ [0x309E]={
+ adobename="voicediterationhiragana",
+ category="lm",
+ cjkwd="w",
+ description="HIRAGANA VOICED ITERATION MARK",
+ direction="l",
+ linebreak="ns",
+ specials={ "char", 0x309D, 0x3099 },
+ unicodeslot=0x309E,
+ },
+ [0x309F]={
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA DIGRAPH YORI",
+ direction="l",
+ linebreak="id",
+ specials={ "vertical", 0x3088, 0x308A },
+ unicodeslot=0x309F,
+ },
+ [0x30A0]={
+ category="pd",
+ cjkwd="w",
+ description="KATAKANA-HIRAGANA DOUBLE HYPHEN",
+ direction="on",
+ linebreak="ns",
+ unicodeslot=0x30A0,
+ },
+ [0x30A1]={
+ adobename="asmallkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL A",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30A1,
+ },
+ [0x30A2]={
+ adobename="akatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER A",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30A2,
+ },
+ [0x30A3]={
+ adobename="ismallkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL I",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30A3,
+ },
+ [0x30A4]={
+ adobename="ikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER I",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30A4,
+ },
+ [0x30A5]={
+ adobename="usmallkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL U",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30A5,
+ },
+ [0x30A6]={
+ adobename="ukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER U",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30A6,
+ },
+ [0x30A7]={
+ adobename="esmallkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL E",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30A7,
+ },
+ [0x30A8]={
+ adobename="ekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER E",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30A8,
+ },
+ [0x30A9]={
+ adobename="osmallkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL O",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30A9,
+ },
+ [0x30AA]={
+ adobename="okatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER O",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30AA,
+ },
+ [0x30AB]={
+ adobename="kakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER KA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30AB,
+ },
+ [0x30AC]={
+ adobename="gakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER GA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30AB, 0x3099 },
+ unicodeslot=0x30AC,
+ },
+ [0x30AD]={
+ adobename="kikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER KI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30AD,
+ },
+ [0x30AE]={
+ adobename="gikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER GI",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30AD, 0x3099 },
+ unicodeslot=0x30AE,
+ },
+ [0x30AF]={
+ adobename="kukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER KU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30AF,
+ },
+ [0x30B0]={
+ adobename="gukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER GU",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30AF, 0x3099 },
+ unicodeslot=0x30B0,
+ },
+ [0x30B1]={
+ adobename="kekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER KE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30B1,
+ },
+ [0x30B2]={
+ adobename="gekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER GE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30B1, 0x3099 },
+ unicodeslot=0x30B2,
+ },
+ [0x30B3]={
+ adobename="kokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER KO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30B3,
+ },
+ [0x30B4]={
+ adobename="gokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER GO",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30B3, 0x3099 },
+ unicodeslot=0x30B4,
+ },
+ [0x30B5]={
+ adobename="sakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30B5,
+ },
+ [0x30B6]={
+ adobename="zakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER ZA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30B5, 0x3099 },
+ unicodeslot=0x30B6,
+ },
+ [0x30B7]={
+ adobename="sikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30B7,
+ },
+ [0x30B8]={
+ adobename="zikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER ZI",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30B7, 0x3099 },
+ unicodeslot=0x30B8,
+ },
+ [0x30B9]={
+ adobename="sukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30B9,
+ },
+ [0x30BA]={
+ adobename="zukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER ZU",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30B9, 0x3099 },
+ unicodeslot=0x30BA,
+ },
+ [0x30BB]={
+ adobename="sekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30BB,
+ },
+ [0x30BC]={
+ adobename="zekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER ZE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30BB, 0x3099 },
+ unicodeslot=0x30BC,
+ },
+ [0x30BD]={
+ adobename="sokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30BD,
+ },
+ [0x30BE]={
+ adobename="zokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER ZO",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30BD, 0x3099 },
+ unicodeslot=0x30BE,
+ },
+ [0x30BF]={
+ adobename="takatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER TA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30BF,
+ },
+ [0x30C0]={
+ adobename="dakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER DA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30BF, 0x3099 },
+ unicodeslot=0x30C0,
+ },
+ [0x30C1]={
+ adobename="tikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER TI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30C1,
+ },
+ [0x30C2]={
+ adobename="dikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER DI",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30C1, 0x3099 },
+ unicodeslot=0x30C2,
+ },
+ [0x30C3]={
+ adobename="tusmallkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL TU",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30C3,
+ },
+ [0x30C4]={
+ adobename="tukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER TU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30C4,
+ },
+ [0x30C5]={
+ adobename="dukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER DU",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30C4, 0x3099 },
+ unicodeslot=0x30C5,
+ },
+ [0x30C6]={
+ adobename="tekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER TE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30C6,
+ },
+ [0x30C7]={
+ adobename="dekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER DE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30C6, 0x3099 },
+ unicodeslot=0x30C7,
+ },
+ [0x30C8]={
+ adobename="tokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER TO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30C8,
+ },
+ [0x30C9]={
+ adobename="dokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER DO",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30C8, 0x3099 },
+ unicodeslot=0x30C9,
+ },
+ [0x30CA]={
+ adobename="nakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER NA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30CA,
+ },
+ [0x30CB]={
+ adobename="nikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER NI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30CB,
+ },
+ [0x30CC]={
+ adobename="nukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER NU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30CC,
+ },
+ [0x30CD]={
+ adobename="nekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER NE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30CD,
+ },
+ [0x30CE]={
+ adobename="nokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER NO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30CE,
+ },
+ [0x30CF]={
+ adobename="hakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER HA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30CF,
+ },
+ [0x30D0]={
+ adobename="bakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER BA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30CF, 0x3099 },
+ unicodeslot=0x30D0,
+ },
+ [0x30D1]={
+ adobename="pakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER PA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30CF, 0x309A },
+ unicodeslot=0x30D1,
+ },
+ [0x30D2]={
+ adobename="hikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER HI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30D2,
+ },
+ [0x30D3]={
+ adobename="bikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER BI",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30D2, 0x3099 },
+ unicodeslot=0x30D3,
+ },
+ [0x30D4]={
+ adobename="pikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER PI",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30D2, 0x309A },
+ unicodeslot=0x30D4,
+ },
+ [0x30D5]={
+ adobename="hukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER HU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30D5,
+ },
+ [0x30D6]={
+ adobename="bukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER BU",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30D5, 0x3099 },
+ unicodeslot=0x30D6,
+ },
+ [0x30D7]={
+ adobename="pukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER PU",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30D5, 0x309A },
+ unicodeslot=0x30D7,
+ },
+ [0x30D8]={
+ adobename="hekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER HE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30D8,
+ },
+ [0x30D9]={
+ adobename="bekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER BE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30D8, 0x3099 },
+ unicodeslot=0x30D9,
+ },
+ [0x30DA]={
+ adobename="pekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER PE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30D8, 0x309A },
+ unicodeslot=0x30DA,
+ },
+ [0x30DB]={
+ adobename="hokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER HO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30DB,
+ },
+ [0x30DC]={
+ adobename="bokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER BO",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30DB, 0x3099 },
+ unicodeslot=0x30DC,
+ },
+ [0x30DD]={
+ adobename="pokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER PO",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30DB, 0x309A },
+ unicodeslot=0x30DD,
+ },
+ [0x30DE]={
+ adobename="makatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER MA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30DE,
+ },
+ [0x30DF]={
+ adobename="mikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER MI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30DF,
+ },
+ [0x30E0]={
+ adobename="mukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER MU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E0,
+ },
+ [0x30E1]={
+ adobename="mekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER ME",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E1,
+ },
+ [0x30E2]={
+ adobename="mokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER MO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E2,
+ },
+ [0x30E3]={
+ adobename="yasmallkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL YA",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30E3,
+ },
+ [0x30E4]={
+ adobename="yakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER YA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E4,
+ },
+ [0x30E5]={
+ adobename="yusmallkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL YU",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30E5,
+ },
+ [0x30E6]={
+ adobename="yukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER YU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E6,
+ },
+ [0x30E7]={
+ adobename="yosmallkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL YO",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30E7,
+ },
+ [0x30E8]={
+ adobename="yokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER YO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E8,
+ },
+ [0x30E9]={
+ adobename="rakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER RA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30E9,
+ },
+ [0x30EA]={
+ adobename="rikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER RI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30EA,
+ },
+ [0x30EB]={
+ adobename="rukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER RU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30EB,
+ },
+ [0x30EC]={
+ adobename="rekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER RE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30EC,
+ },
+ [0x30ED]={
+ adobename="rokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER RO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30ED,
+ },
+ [0x30EE]={
+ adobename="wasmallkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL WA",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30EE,
+ },
+ [0x30EF]={
+ adobename="wakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER WA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30EF,
+ },
+ [0x30F0]={
+ adobename="wikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER WI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30F0,
+ },
+ [0x30F1]={
+ adobename="wekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER WE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30F1,
+ },
+ [0x30F2]={
+ adobename="wokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER WO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30F2,
+ },
+ [0x30F3]={
+ adobename="nkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER N",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x30F3,
+ },
+ [0x30F4]={
+ adobename="vukatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER VU",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30A6, 0x3099 },
+ unicodeslot=0x30F4,
+ },
+ [0x30F5]={
+ adobename="kasmallkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL KA",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30F5,
+ },
+ [0x30F6]={
+ adobename="kesmallkatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL KE",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30F6,
+ },
+ [0x30F7]={
+ adobename="vakatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER VA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30EF, 0x3099 },
+ unicodeslot=0x30F7,
+ },
+ [0x30F8]={
+ adobename="vikatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER VI",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30F0, 0x3099 },
+ unicodeslot=0x30F8,
+ },
+ [0x30F9]={
+ adobename="vekatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER VE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30F1, 0x3099 },
+ unicodeslot=0x30F9,
+ },
+ [0x30FA]={
+ adobename="vokatakana",
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER VO",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x30F2, 0x3099 },
+ unicodeslot=0x30FA,
+ },
+ [0x30FB]={
+ adobename="dotkatakana",
+ category="po",
+ cjkwd="w",
+ description="KATAKANA MIDDLE DOT",
+ direction="on",
+ linebreak="ns",
+ unicodeslot=0x30FB,
+ },
+ [0x30FC]={
+ adobename="prolongedkana",
+ category="lm",
+ cjkwd="w",
+ description="KATAKANA-HIRAGANA PROLONGED SOUND MARK",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x30FC,
+ },
+ [0x30FD]={
+ adobename="iterationkatakana",
+ category="lm",
+ cjkwd="w",
+ description="KATAKANA ITERATION MARK",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0x30FD,
+ },
+ [0x30FE]={
+ adobename="voicediterationkatakana",
+ category="lm",
+ cjkwd="w",
+ description="KATAKANA VOICED ITERATION MARK",
+ direction="l",
+ linebreak="ns",
+ specials={ "char", 0x30FD, 0x3099 },
+ unicodeslot=0x30FE,
+ },
+ [0x30FF]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA DIGRAPH KOTO",
+ direction="l",
+ linebreak="id",
+ specials={ "vertical", 0x30B3, 0x30C8 },
+ unicodeslot=0x30FF,
+ },
+ [0x3105]={
+ adobename="bbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER B",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3105,
+ },
+ [0x3106]={
+ adobename="pbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER P",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3106,
+ },
+ [0x3107]={
+ adobename="mbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER M",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3107,
+ },
+ [0x3108]={
+ adobename="fbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER F",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3108,
+ },
+ [0x3109]={
+ adobename="dbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER D",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3109,
+ },
+ [0x310A]={
+ adobename="tbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER T",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x310A,
+ },
+ [0x310B]={
+ adobename="nbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER N",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x310B,
+ },
+ [0x310C]={
+ adobename="lbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER L",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x310C,
+ },
+ [0x310D]={
+ adobename="gbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER G",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x310D,
+ },
+ [0x310E]={
+ adobename="kbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER K",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x310E,
+ },
+ [0x310F]={
+ adobename="hbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER H",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x310F,
+ },
+ [0x3110]={
+ adobename="jbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER J",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3110,
+ },
+ [0x3111]={
+ adobename="qbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER Q",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3111,
+ },
+ [0x3112]={
+ adobename="xbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER X",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3112,
+ },
+ [0x3113]={
+ adobename="zhbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER ZH",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3113,
+ },
+ [0x3114]={
+ adobename="chbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER CH",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3114,
+ },
+ [0x3115]={
+ adobename="shbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER SH",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3115,
+ },
+ [0x3116]={
+ adobename="rbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER R",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3116,
+ },
+ [0x3117]={
+ adobename="zbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER Z",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3117,
+ },
+ [0x3118]={
+ adobename="cbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER C",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3118,
+ },
+ [0x3119]={
+ adobename="sbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER S",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3119,
+ },
+ [0x311A]={
+ adobename="abopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER A",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x311A,
+ },
+ [0x311B]={
+ adobename="obopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER O",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x311B,
+ },
+ [0x311C]={
+ adobename="ebopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER E",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x311C,
+ },
+ [0x311D]={
+ adobename="ehbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER EH",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x311D,
+ },
+ [0x311E]={
+ adobename="aibopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER AI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x311E,
+ },
+ [0x311F]={
+ adobename="eibopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER EI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x311F,
+ },
+ [0x3120]={
+ adobename="aubopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER AU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3120,
+ },
+ [0x3121]={
+ adobename="oubopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER OU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3121,
+ },
+ [0x3122]={
+ adobename="anbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER AN",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3122,
+ },
+ [0x3123]={
+ adobename="enbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER EN",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3123,
+ },
+ [0x3124]={
+ adobename="angbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER ANG",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3124,
+ },
+ [0x3125]={
+ adobename="engbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER ENG",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3125,
+ },
+ [0x3126]={
+ adobename="erbopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER ER",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3126,
+ },
+ [0x3127]={
+ adobename="ibopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER I",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3127,
+ },
+ [0x3128]={
+ adobename="ubopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER U",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3128,
+ },
+ [0x3129]={
+ adobename="iubopomofo",
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER IU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3129,
+ },
+ [0x312A]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER V",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x312A,
+ },
+ [0x312B]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER NG",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x312B,
+ },
+ [0x312C]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER GN",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x312C,
+ },
+ [0x312D]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER IH",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x312D,
+ },
+ [0x3131]={
+ adobename="kiyeokkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER KIYEOK",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1100 },
+ unicodeslot=0x3131,
+ },
+ [0x3132]={
+ adobename="ssangkiyeokkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SSANGKIYEOK",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1101 },
+ unicodeslot=0x3132,
+ },
+ [0x3133]={
+ adobename="kiyeoksioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER KIYEOK-SIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11AA },
+ unicodeslot=0x3133,
+ },
+ [0x3134]={
+ adobename="nieunkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER NIEUN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1102 },
+ unicodeslot=0x3134,
+ },
+ [0x3135]={
+ adobename="nieuncieuckorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER NIEUN-CIEUC",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11AC },
+ unicodeslot=0x3135,
+ },
+ [0x3136]={
+ adobename="nieunhieuhkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER NIEUN-HIEUH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11AD },
+ unicodeslot=0x3136,
+ },
+ [0x3137]={
+ adobename="tikeutkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER TIKEUT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1103 },
+ unicodeslot=0x3137,
+ },
+ [0x3138]={
+ adobename="ssangtikeutkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SSANGTIKEUT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1104 },
+ unicodeslot=0x3138,
+ },
+ [0x3139]={
+ adobename="rieulkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1105 },
+ unicodeslot=0x3139,
+ },
+ [0x313A]={
+ adobename="rieulkiyeokkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL-KIYEOK",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11B0 },
+ unicodeslot=0x313A,
+ },
+ [0x313B]={
+ adobename="rieulmieumkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL-MIEUM",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11B1 },
+ unicodeslot=0x313B,
+ },
+ [0x313C]={
+ adobename="rieulpieupkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL-PIEUP",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11B2 },
+ unicodeslot=0x313C,
+ },
+ [0x313D]={
+ adobename="rieulsioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL-SIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11B3 },
+ unicodeslot=0x313D,
+ },
+ [0x313E]={
+ adobename="rieulthieuthkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL-THIEUTH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11B4 },
+ unicodeslot=0x313E,
+ },
+ [0x313F]={
+ adobename="rieulphieuphkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL-PHIEUPH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11B5 },
+ unicodeslot=0x313F,
+ },
+ [0x3140]={
+ adobename="rieulhieuhkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL-HIEUH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x111A },
+ unicodeslot=0x3140,
+ },
+ [0x3141]={
+ adobename="mieumkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER MIEUM",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1106 },
+ unicodeslot=0x3141,
+ },
+ [0x3142]={
+ adobename="pieupkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER PIEUP",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1107 },
+ unicodeslot=0x3142,
+ },
+ [0x3143]={
+ adobename="ssangpieupkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SSANGPIEUP",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1108 },
+ unicodeslot=0x3143,
+ },
+ [0x3144]={
+ adobename="pieupsioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER PIEUP-SIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1121 },
+ unicodeslot=0x3144,
+ },
+ [0x3145]={
+ adobename="sioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1109 },
+ unicodeslot=0x3145,
+ },
+ [0x3146]={
+ adobename="ssangsioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SSANGSIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x110A },
+ unicodeslot=0x3146,
+ },
+ [0x3147]={
+ adobename="ieungkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER IEUNG",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x110B },
+ unicodeslot=0x3147,
+ },
+ [0x3148]={
+ adobename="cieuckorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER CIEUC",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x110C },
+ unicodeslot=0x3148,
+ },
+ [0x3149]={
+ adobename="ssangcieuckorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SSANGCIEUC",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x110D },
+ unicodeslot=0x3149,
+ },
+ [0x314A]={
+ adobename="chieuchkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER CHIEUCH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x110E },
+ unicodeslot=0x314A,
+ },
+ [0x314B]={
+ adobename="khieukhkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER KHIEUKH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x110F },
+ unicodeslot=0x314B,
+ },
+ [0x314C]={
+ adobename="thieuthkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER THIEUTH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1110 },
+ unicodeslot=0x314C,
+ },
+ [0x314D]={
+ adobename="phieuphkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER PHIEUPH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1111 },
+ unicodeslot=0x314D,
+ },
+ [0x314E]={
+ adobename="hieuhkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER HIEUH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1112 },
+ unicodeslot=0x314E,
+ },
+ [0x314F]={
+ adobename="akorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1161 },
+ unicodeslot=0x314F,
+ },
+ [0x3150]={
+ adobename="aekorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER AE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1162 },
+ unicodeslot=0x3150,
+ },
+ [0x3151]={
+ adobename="yakorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YA",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1163 },
+ unicodeslot=0x3151,
+ },
+ [0x3152]={
+ adobename="yaekorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YAE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1164 },
+ unicodeslot=0x3152,
+ },
+ [0x3153]={
+ adobename="eokorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER EO",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1165 },
+ unicodeslot=0x3153,
+ },
+ [0x3154]={
+ adobename="ekorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER E",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1166 },
+ unicodeslot=0x3154,
+ },
+ [0x3155]={
+ adobename="yeokorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YEO",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1167 },
+ unicodeslot=0x3155,
+ },
+ [0x3156]={
+ adobename="yekorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1168 },
+ unicodeslot=0x3156,
+ },
+ [0x3157]={
+ adobename="okorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER O",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1169 },
+ unicodeslot=0x3157,
+ },
+ [0x3158]={
+ adobename="wakorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER WA",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x116A },
+ unicodeslot=0x3158,
+ },
+ [0x3159]={
+ adobename="waekorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER WAE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x116B },
+ unicodeslot=0x3159,
+ },
+ [0x315A]={
+ adobename="oekorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER OE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x116C },
+ unicodeslot=0x315A,
+ },
+ [0x315B]={
+ adobename="yokorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YO",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x116D },
+ unicodeslot=0x315B,
+ },
+ [0x315C]={
+ adobename="ukorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER U",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x116E },
+ unicodeslot=0x315C,
+ },
+ [0x315D]={
+ adobename="weokorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER WEO",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x116F },
+ unicodeslot=0x315D,
+ },
+ [0x315E]={
+ adobename="wekorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER WE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1170 },
+ unicodeslot=0x315E,
+ },
+ [0x315F]={
+ adobename="wikorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER WI",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1171 },
+ unicodeslot=0x315F,
+ },
+ [0x3160]={
+ adobename="yukorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YU",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1172 },
+ unicodeslot=0x3160,
+ },
+ [0x3161]={
+ adobename="eukorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER EU",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1173 },
+ unicodeslot=0x3161,
+ },
+ [0x3162]={
+ adobename="yikorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YI",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1174 },
+ unicodeslot=0x3162,
+ },
+ [0x3163]={
+ adobename="ikorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER I",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1175 },
+ unicodeslot=0x3163,
+ },
+ [0x3164]={
+ adobename="hangulfiller",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL FILLER",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1160 },
+ unicodeslot=0x3164,
+ },
+ [0x3165]={
+ adobename="ssangnieunkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SSANGNIEUN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1114 },
+ unicodeslot=0x3165,
+ },
+ [0x3166]={
+ adobename="nieuntikeutkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER NIEUN-TIKEUT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1115 },
+ unicodeslot=0x3166,
+ },
+ [0x3167]={
+ adobename="nieunsioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER NIEUN-SIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11C7 },
+ unicodeslot=0x3167,
+ },
+ [0x3168]={
+ adobename="nieunpansioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER NIEUN-PANSIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11C8 },
+ unicodeslot=0x3168,
+ },
+ [0x3169]={
+ adobename="rieulkiyeoksioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL-KIYEOK-SIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11CC },
+ unicodeslot=0x3169,
+ },
+ [0x316A]={
+ adobename="rieultikeutkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL-TIKEUT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11CE },
+ unicodeslot=0x316A,
+ },
+ [0x316B]={
+ adobename="rieulpieupsioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL-PIEUP-SIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11D3 },
+ unicodeslot=0x316B,
+ },
+ [0x316C]={
+ adobename="rieulpansioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL-PANSIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11D7 },
+ unicodeslot=0x316C,
+ },
+ [0x316D]={
+ adobename="rieulyeorinhieuhkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER RIEUL-YEORINHIEUH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11D9 },
+ unicodeslot=0x316D,
+ },
+ [0x316E]={
+ adobename="mieumpieupkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER MIEUM-PIEUP",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x111C },
+ unicodeslot=0x316E,
+ },
+ [0x316F]={
+ adobename="mieumsioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER MIEUM-SIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11DD },
+ unicodeslot=0x316F,
+ },
+ [0x3170]={
+ adobename="mieumpansioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER MIEUM-PANSIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11DF },
+ unicodeslot=0x3170,
+ },
+ [0x3171]={
+ adobename="kapyeounmieumkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER KAPYEOUNMIEUM",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x111D },
+ unicodeslot=0x3171,
+ },
+ [0x3172]={
+ adobename="pieupkiyeokkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER PIEUP-KIYEOK",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x111E },
+ unicodeslot=0x3172,
+ },
+ [0x3173]={
+ adobename="pieuptikeutkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER PIEUP-TIKEUT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1120 },
+ unicodeslot=0x3173,
+ },
+ [0x3174]={
+ adobename="pieupsioskiyeokkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER PIEUP-SIOS-KIYEOK",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1122 },
+ unicodeslot=0x3174,
+ },
+ [0x3175]={
+ adobename="pieupsiostikeutkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER PIEUP-SIOS-TIKEUT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1123 },
+ unicodeslot=0x3175,
+ },
+ [0x3176]={
+ adobename="pieupcieuckorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER PIEUP-CIEUC",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1127 },
+ unicodeslot=0x3176,
+ },
+ [0x3177]={
+ adobename="pieupthieuthkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER PIEUP-THIEUTH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1129 },
+ unicodeslot=0x3177,
+ },
+ [0x3178]={
+ adobename="kapyeounpieupkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER KAPYEOUNPIEUP",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x112B },
+ unicodeslot=0x3178,
+ },
+ [0x3179]={
+ adobename="kapyeounssangpieupkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER KAPYEOUNSSANGPIEUP",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x112C },
+ unicodeslot=0x3179,
+ },
+ [0x317A]={
+ adobename="sioskiyeokkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SIOS-KIYEOK",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x112D },
+ unicodeslot=0x317A,
+ },
+ [0x317B]={
+ adobename="siosnieunkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SIOS-NIEUN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x112E },
+ unicodeslot=0x317B,
+ },
+ [0x317C]={
+ adobename="siostikeutkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SIOS-TIKEUT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x112F },
+ unicodeslot=0x317C,
+ },
+ [0x317D]={
+ adobename="siospieupkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SIOS-PIEUP",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1132 },
+ unicodeslot=0x317D,
+ },
+ [0x317E]={
+ adobename="sioscieuckorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SIOS-CIEUC",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1136 },
+ unicodeslot=0x317E,
+ },
+ [0x317F]={
+ adobename="pansioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER PANSIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1140 },
+ unicodeslot=0x317F,
+ },
+ [0x3180]={
+ adobename="ssangieungkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SSANGIEUNG",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1147 },
+ unicodeslot=0x3180,
+ },
+ [0x3181]={
+ adobename="yesieungkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YESIEUNG",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x114C },
+ unicodeslot=0x3181,
+ },
+ [0x3182]={
+ adobename="yesieungsioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YESIEUNG-SIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11F1 },
+ unicodeslot=0x3182,
+ },
+ [0x3183]={
+ adobename="yesieungpansioskorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YESIEUNG-PANSIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11F2 },
+ unicodeslot=0x3183,
+ },
+ [0x3184]={
+ adobename="kapyeounphieuphkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER KAPYEOUNPHIEUPH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1157 },
+ unicodeslot=0x3184,
+ },
+ [0x3185]={
+ adobename="ssanghieuhkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER SSANGHIEUH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1158 },
+ unicodeslot=0x3185,
+ },
+ [0x3186]={
+ adobename="yeorinhieuhkorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YEORINHIEUH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1159 },
+ unicodeslot=0x3186,
+ },
+ [0x3187]={
+ adobename="yoyakorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YO-YA",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1184 },
+ unicodeslot=0x3187,
+ },
+ [0x3188]={
+ adobename="yoyaekorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YO-YAE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1185 },
+ unicodeslot=0x3188,
+ },
+ [0x3189]={
+ adobename="yoikorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YO-I",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1188 },
+ unicodeslot=0x3189,
+ },
+ [0x318A]={
+ adobename="yuyeokorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YU-YEO",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1191 },
+ unicodeslot=0x318A,
+ },
+ [0x318B]={
+ adobename="yuyekorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YU-YE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1192 },
+ unicodeslot=0x318B,
+ },
+ [0x318C]={
+ adobename="yuikorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER YU-I",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x1194 },
+ unicodeslot=0x318C,
+ },
+ [0x318D]={
+ adobename="araeakorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER ARAEA",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x119E },
+ unicodeslot=0x318D,
+ },
+ [0x318E]={
+ adobename="araeaekorean",
+ category="lo",
+ cjkwd="w",
+ description="HANGUL LETTER ARAEAE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x11A1 },
+ unicodeslot=0x318E,
+ },
+ [0x3190]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION LINKING MARK",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3190,
+ },
+ [0x3191]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION REVERSE MARK",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x3191,
+ },
+ [0x3192]={
+ category="no",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION ONE MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E00 },
+ unicodeslot=0x3192,
+ },
+ [0x3193]={
+ category="no",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION TWO MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E8C },
+ unicodeslot=0x3193,
+ },
+ [0x3194]={
+ category="no",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION THREE MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E09 },
+ unicodeslot=0x3194,
+ },
+ [0x3195]={
+ category="no",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION FOUR MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x56DB },
+ unicodeslot=0x3195,
+ },
+ [0x3196]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION TOP MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E0A },
+ unicodeslot=0x3196,
+ },
+ [0x3197]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION MIDDLE MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E2D },
+ unicodeslot=0x3197,
+ },
+ [0x3198]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION BOTTOM MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E0B },
+ unicodeslot=0x3198,
+ },
+ [0x3199]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION FIRST MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x7532 },
+ unicodeslot=0x3199,
+ },
+ [0x319A]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION SECOND MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E59 },
+ unicodeslot=0x319A,
+ },
+ [0x319B]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION THIRD MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E19 },
+ unicodeslot=0x319B,
+ },
+ [0x319C]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION FOURTH MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4E01 },
+ unicodeslot=0x319C,
+ },
+ [0x319D]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION HEAVEN MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x5929 },
+ unicodeslot=0x319D,
+ },
+ [0x319E]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION EARTH MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x5730 },
+ unicodeslot=0x319E,
+ },
+ [0x319F]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC ANNOTATION MAN MARK",
+ direction="l",
+ linebreak="id",
+ specials={ "super", 0x4EBA },
+ unicodeslot=0x319F,
+ },
+ [0x31A0]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER BU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A0,
+ },
+ [0x31A1]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER ZI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A1,
+ },
+ [0x31A2]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER JI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A2,
+ },
+ [0x31A3]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER GU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A3,
+ },
+ [0x31A4]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER EE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A4,
+ },
+ [0x31A5]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER ENN",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A5,
+ },
+ [0x31A6]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER OO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A6,
+ },
+ [0x31A7]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER ONN",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A7,
+ },
+ [0x31A8]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER IR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A8,
+ },
+ [0x31A9]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER ANN",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31A9,
+ },
+ [0x31AA]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER INN",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31AA,
+ },
+ [0x31AB]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER UNN",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31AB,
+ },
+ [0x31AC]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER IM",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31AC,
+ },
+ [0x31AD]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER NGG",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31AD,
+ },
+ [0x31AE]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER AINN",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31AE,
+ },
+ [0x31AF]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER AUNN",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31AF,
+ },
+ [0x31B0]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER AM",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B0,
+ },
+ [0x31B1]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER OM",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B1,
+ },
+ [0x31B2]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER ONG",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B2,
+ },
+ [0x31B3]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER INNN",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B3,
+ },
+ [0x31B4]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO FINAL LETTER P",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B4,
+ },
+ [0x31B5]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO FINAL LETTER T",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B5,
+ },
+ [0x31B6]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO FINAL LETTER K",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B6,
+ },
+ [0x31B7]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO FINAL LETTER H",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B7,
+ },
+ [0x31B8]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER GH",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B8,
+ },
+ [0x31B9]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER LH",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31B9,
+ },
+ [0x31BA]={
+ category="lo",
+ cjkwd="w",
+ description="BOPOMOFO LETTER ZY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31BA,
+ },
+ [0x31C0]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE T",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C0,
+ },
+ [0x31C1]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE WG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C1,
+ },
+ [0x31C2]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE XG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C2,
+ },
+ [0x31C3]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE BXG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C3,
+ },
+ [0x31C4]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE SW",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C4,
+ },
+ [0x31C5]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HZZ",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C5,
+ },
+ [0x31C6]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HZG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C6,
+ },
+ [0x31C7]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C7,
+ },
+ [0x31C8]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HZWG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C8,
+ },
+ [0x31C9]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE SZWG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31C9,
+ },
+ [0x31CA]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HZT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31CA,
+ },
+ [0x31CB]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HZZP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31CB,
+ },
+ [0x31CC]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HPWG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31CC,
+ },
+ [0x31CD]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HZW",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31CD,
+ },
+ [0x31CE]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HZZZ",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31CE,
+ },
+ [0x31CF]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE N",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31CF,
+ },
+ [0x31D0]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE H",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D0,
+ },
+ [0x31D1]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE S",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D1,
+ },
+ [0x31D2]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE P",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D2,
+ },
+ [0x31D3]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE SP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D3,
+ },
+ [0x31D4]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE D",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D4,
+ },
+ [0x31D5]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HZ",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D5,
+ },
+ [0x31D6]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D6,
+ },
+ [0x31D7]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE SZ",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D7,
+ },
+ [0x31D8]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE SWZ",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D8,
+ },
+ [0x31D9]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE ST",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31D9,
+ },
+ [0x31DA]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE SG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31DA,
+ },
+ [0x31DB]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE PD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31DB,
+ },
+ [0x31DC]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE PZ",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31DC,
+ },
+ [0x31DD]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE TN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31DD,
+ },
+ [0x31DE]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE SZZ",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31DE,
+ },
+ [0x31DF]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE SWG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31DF,
+ },
+ [0x31E0]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HXWG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31E0,
+ },
+ [0x31E1]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE HZZZG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31E1,
+ },
+ [0x31E2]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE PG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31E2,
+ },
+ [0x31E3]={
+ category="so",
+ cjkwd="w",
+ description="CJK STROKE Q",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x31E3,
+ },
+ [0x31F0]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL KU",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F0,
+ },
+ [0x31F1]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL SI",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F1,
+ },
+ [0x31F2]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL SU",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F2,
+ },
+ [0x31F3]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL TO",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F3,
+ },
+ [0x31F4]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL NU",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F4,
+ },
+ [0x31F5]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL HA",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F5,
+ },
+ [0x31F6]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL HI",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F6,
+ },
+ [0x31F7]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL HU",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F7,
+ },
+ [0x31F8]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL HE",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F8,
+ },
+ [0x31F9]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL HO",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31F9,
+ },
+ [0x31FA]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL MU",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31FA,
+ },
+ [0x31FB]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL RA",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31FB,
+ },
+ [0x31FC]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL RI",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31FC,
+ },
+ [0x31FD]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL RU",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31FD,
+ },
+ [0x31FE]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL RE",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31FE,
+ },
+ [0x31FF]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER SMALL RO",
+ direction="l",
+ linebreak="cj",
+ unicodeslot=0x31FF,
+ },
+ [0x3200]={
+ adobename="kiyeokparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL KIYEOK",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1100, 0x0029 },
+ unicodeslot=0x3200,
+ },
+ [0x3201]={
+ adobename="nieunparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL NIEUN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1102, 0x0029 },
+ unicodeslot=0x3201,
+ },
+ [0x3202]={
+ adobename="tikeutparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL TIKEUT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1103, 0x0029 },
+ unicodeslot=0x3202,
+ },
+ [0x3203]={
+ adobename="rieulparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL RIEUL",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1105, 0x0029 },
+ unicodeslot=0x3203,
+ },
+ [0x3204]={
+ adobename="mieumparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL MIEUM",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1106, 0x0029 },
+ unicodeslot=0x3204,
+ },
+ [0x3205]={
+ adobename="pieupparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL PIEUP",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1107, 0x0029 },
+ unicodeslot=0x3205,
+ },
+ [0x3206]={
+ adobename="siosparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL SIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1109, 0x0029 },
+ unicodeslot=0x3206,
+ },
+ [0x3207]={
+ adobename="ieungparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL IEUNG",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x110B, 0x0029 },
+ unicodeslot=0x3207,
+ },
+ [0x3208]={
+ adobename="cieucparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL CIEUC",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x110C, 0x0029 },
+ unicodeslot=0x3208,
+ },
+ [0x3209]={
+ adobename="chieuchparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL CHIEUCH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x110E, 0x0029 },
+ unicodeslot=0x3209,
+ },
+ [0x320A]={
+ adobename="khieukhparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL KHIEUKH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x110F, 0x0029 },
+ unicodeslot=0x320A,
+ },
+ [0x320B]={
+ adobename="thieuthparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL THIEUTH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1110, 0x0029 },
+ unicodeslot=0x320B,
+ },
+ [0x320C]={
+ adobename="phieuphparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL PHIEUPH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1111, 0x0029 },
+ unicodeslot=0x320C,
+ },
+ [0x320D]={
+ adobename="hieuhparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL HIEUH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1112, 0x0029 },
+ unicodeslot=0x320D,
+ },
+ [0x320E]={
+ adobename="kiyeokaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL KIYEOK A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1100, 0x1161, 0x0029 },
+ unicodeslot=0x320E,
+ },
+ [0x320F]={
+ adobename="nieunaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL NIEUN A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1102, 0x1161, 0x0029 },
+ unicodeslot=0x320F,
+ },
+ [0x3210]={
+ adobename="tikeutaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL TIKEUT A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1103, 0x1161, 0x0029 },
+ unicodeslot=0x3210,
+ },
+ [0x3211]={
+ adobename="rieulaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL RIEUL A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1105, 0x1161, 0x0029 },
+ unicodeslot=0x3211,
+ },
+ [0x3212]={
+ adobename="mieumaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL MIEUM A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1106, 0x1161, 0x0029 },
+ unicodeslot=0x3212,
+ },
+ [0x3213]={
+ adobename="pieupaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL PIEUP A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1107, 0x1161, 0x0029 },
+ unicodeslot=0x3213,
+ },
+ [0x3214]={
+ adobename="siosaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL SIOS A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1109, 0x1161, 0x0029 },
+ unicodeslot=0x3214,
+ },
+ [0x3215]={
+ adobename="ieungaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL IEUNG A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x110B, 0x1161, 0x0029 },
+ unicodeslot=0x3215,
+ },
+ [0x3216]={
+ adobename="cieucaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL CIEUC A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x110C, 0x1161, 0x0029 },
+ unicodeslot=0x3216,
+ },
+ [0x3217]={
+ adobename="chieuchaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL CHIEUCH A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x110E, 0x1161, 0x0029 },
+ unicodeslot=0x3217,
+ },
+ [0x3218]={
+ adobename="khieukhaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL KHIEUKH A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x110F, 0x1161, 0x0029 },
+ unicodeslot=0x3218,
+ },
+ [0x3219]={
+ adobename="thieuthaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL THIEUTH A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1110, 0x1161, 0x0029 },
+ unicodeslot=0x3219,
+ },
+ [0x321A]={
+ adobename="phieuphaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL PHIEUPH A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1111, 0x1161, 0x0029 },
+ unicodeslot=0x321A,
+ },
+ [0x321B]={
+ adobename="hieuhaparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL HIEUH A",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x1112, 0x1161, 0x0029 },
+ unicodeslot=0x321B,
+ },
+ [0x321C]={
+ adobename="cieucuparenkorean",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED HANGUL CIEUC U",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x110C, 0x116E, 0x0029 },
+ unicodeslot=0x321C,
+ },
+ [0x321D]={
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED KOREAN CHARACTER OJEON",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x110B, 0x1169, 0x110C, 0x1165, 0x11AB, 0x0029 },
+ unicodeslot=0x321D,
+ },
+ [0x321E]={
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED KOREAN CHARACTER O HU",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x110B, 0x1169, 0x1112, 0x116E, 0x0029 },
+ unicodeslot=0x321E,
+ },
+ [0x3220]={
+ adobename="oneideographicparen",
+ category="no",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH ONE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x4E00, 0x0029 },
+ unicodeslot=0x3220,
+ },
+ [0x3221]={
+ adobename="twoideographicparen",
+ category="no",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH TWO",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x4E8C, 0x0029 },
+ unicodeslot=0x3221,
+ },
+ [0x3222]={
+ adobename="threeideographicparen",
+ category="no",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH THREE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x4E09, 0x0029 },
+ unicodeslot=0x3222,
+ },
+ [0x3223]={
+ adobename="fourideographicparen",
+ category="no",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH FOUR",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x56DB, 0x0029 },
+ unicodeslot=0x3223,
+ },
+ [0x3224]={
+ adobename="fiveideographicparen",
+ category="no",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH FIVE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x4E94, 0x0029 },
+ unicodeslot=0x3224,
+ },
+ [0x3225]={
+ adobename="sixideographicparen",
+ category="no",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH SIX",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x516D, 0x0029 },
+ unicodeslot=0x3225,
+ },
+ [0x3226]={
+ adobename="sevenideographicparen",
+ category="no",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH SEVEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x4E03, 0x0029 },
+ unicodeslot=0x3226,
+ },
+ [0x3227]={
+ adobename="eightideographicparen",
+ category="no",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH EIGHT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x516B, 0x0029 },
+ unicodeslot=0x3227,
+ },
+ [0x3228]={
+ adobename="nineideographicparen",
+ category="no",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH NINE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x4E5D, 0x0029 },
+ unicodeslot=0x3228,
+ },
+ [0x3229]={
+ adobename="tenideographicparen",
+ category="no",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH TEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x5341, 0x0029 },
+ unicodeslot=0x3229,
+ },
+ [0x322A]={
+ adobename="ideographicmoonparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH MOON",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x6708, 0x0029 },
+ unicodeslot=0x322A,
+ },
+ [0x322B]={
+ adobename="ideographicfireparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH FIRE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x706B, 0x0029 },
+ unicodeslot=0x322B,
+ },
+ [0x322C]={
+ adobename="ideographicwaterparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH WATER",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x6C34, 0x0029 },
+ unicodeslot=0x322C,
+ },
+ [0x322D]={
+ adobename="ideographicwoodparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH WOOD",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x6728, 0x0029 },
+ unicodeslot=0x322D,
+ },
+ [0x322E]={
+ adobename="ideographicmetalparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH METAL",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x91D1, 0x0029 },
+ unicodeslot=0x322E,
+ },
+ [0x322F]={
+ adobename="ideographicearthparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH EARTH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x571F, 0x0029 },
+ unicodeslot=0x322F,
+ },
+ [0x3230]={
+ adobename="ideographicsunparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH SUN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x65E5, 0x0029 },
+ unicodeslot=0x3230,
+ },
+ [0x3231]={
+ adobename="ideographicstockparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH STOCK",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x682A, 0x0029 },
+ unicodeslot=0x3231,
+ },
+ [0x3232]={
+ adobename="ideographichaveparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH HAVE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x6709, 0x0029 },
+ unicodeslot=0x3232,
+ },
+ [0x3233]={
+ adobename="ideographicsocietyparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH SOCIETY",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x793E, 0x0029 },
+ unicodeslot=0x3233,
+ },
+ [0x3234]={
+ adobename="ideographicnameparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH NAME",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x540D, 0x0029 },
+ unicodeslot=0x3234,
+ },
+ [0x3235]={
+ adobename="ideographicspecialparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH SPECIAL",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x7279, 0x0029 },
+ unicodeslot=0x3235,
+ },
+ [0x3236]={
+ adobename="ideographicfinancialparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH FINANCIAL",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x8CA1, 0x0029 },
+ unicodeslot=0x3236,
+ },
+ [0x3237]={
+ adobename="ideographiccongratulationparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH CONGRATULATION",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x795D, 0x0029 },
+ unicodeslot=0x3237,
+ },
+ [0x3238]={
+ adobename="ideographiclaborparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH LABOR",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x52B4, 0x0029 },
+ unicodeslot=0x3238,
+ },
+ [0x3239]={
+ adobename="ideographicrepresentparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH REPRESENT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x4EE3, 0x0029 },
+ unicodeslot=0x3239,
+ },
+ [0x323A]={
+ adobename="ideographiccallparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH CALL",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x547C, 0x0029 },
+ unicodeslot=0x323A,
+ },
+ [0x323B]={
+ adobename="ideographicstudyparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH STUDY",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x5B66, 0x0029 },
+ unicodeslot=0x323B,
+ },
+ [0x323C]={
+ adobename="ideographicsuperviseparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH SUPERVISE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x76E3, 0x0029 },
+ unicodeslot=0x323C,
+ },
+ [0x323D]={
+ adobename="ideographicenterpriseparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH ENTERPRISE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x4F01, 0x0029 },
+ unicodeslot=0x323D,
+ },
+ [0x323E]={
+ adobename="ideographicresourceparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH RESOURCE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x8CC7, 0x0029 },
+ unicodeslot=0x323E,
+ },
+ [0x323F]={
+ adobename="ideographicallianceparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH ALLIANCE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x5354, 0x0029 },
+ unicodeslot=0x323F,
+ },
+ [0x3240]={
+ adobename="ideographicfestivalparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH FESTIVAL",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x796D, 0x0029 },
+ unicodeslot=0x3240,
+ },
+ [0x3241]={
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH REST",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x4F11, 0x0029 },
+ unicodeslot=0x3241,
+ },
+ [0x3242]={
+ adobename="ideographicselfparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH SELF",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x81EA, 0x0029 },
+ unicodeslot=0x3242,
+ },
+ [0x3243]={
+ adobename="ideographicreachparen",
+ category="so",
+ cjkwd="w",
+ description="PARENTHESIZED IDEOGRAPH REACH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0028, 0x81F3, 0x0029 },
+ unicodeslot=0x3243,
+ },
+ [0x3244]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH QUESTION",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x554F },
+ unicodeslot=0x3244,
+ },
+ [0x3245]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH KINDERGARTEN",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5E7C },
+ unicodeslot=0x3245,
+ },
+ [0x3246]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH SCHOOL",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6587 },
+ unicodeslot=0x3246,
+ },
+ [0x3247]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH KOTO",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x7B8F },
+ unicodeslot=0x3247,
+ },
+ [0x3248]={
+ category="so",
+ cjkwd="a",
+ description="CIRCLED NUMBER TEN ON BLACK SQUARE",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x3248,
+ },
+ [0x3249]={
+ category="so",
+ cjkwd="a",
+ description="CIRCLED NUMBER TWENTY ON BLACK SQUARE",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x3249,
+ },
+ [0x324A]={
+ category="so",
+ cjkwd="a",
+ description="CIRCLED NUMBER THIRTY ON BLACK SQUARE",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x324A,
+ },
+ [0x324B]={
+ category="so",
+ cjkwd="a",
+ description="CIRCLED NUMBER FORTY ON BLACK SQUARE",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x324B,
+ },
+ [0x324C]={
+ category="so",
+ cjkwd="a",
+ description="CIRCLED NUMBER FIFTY ON BLACK SQUARE",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x324C,
+ },
+ [0x324D]={
+ category="so",
+ cjkwd="a",
+ description="CIRCLED NUMBER SIXTY ON BLACK SQUARE",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x324D,
+ },
+ [0x324E]={
+ category="so",
+ cjkwd="a",
+ description="CIRCLED NUMBER SEVENTY ON BLACK SQUARE",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x324E,
+ },
+ [0x324F]={
+ category="so",
+ cjkwd="a",
+ description="CIRCLED NUMBER EIGHTY ON BLACK SQUARE",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x324F,
+ },
+ [0x3250]={
+ category="so",
+ cjkwd="w",
+ description="PARTNERSHIP SIGN",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x0050, 0x0054, 0x0045 },
+ unicodeslot=0x3250,
+ },
+ [0x3251]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER TWENTY ONE",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0032, 0x0031 },
+ unicodeslot=0x3251,
+ },
+ [0x3252]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER TWENTY TWO",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0032, 0x0032 },
+ unicodeslot=0x3252,
+ },
+ [0x3253]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER TWENTY THREE",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0032, 0x0033 },
+ unicodeslot=0x3253,
+ },
+ [0x3254]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER TWENTY FOUR",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0032, 0x0034 },
+ unicodeslot=0x3254,
+ },
+ [0x3255]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER TWENTY FIVE",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0032, 0x0035 },
+ unicodeslot=0x3255,
+ },
+ [0x3256]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER TWENTY SIX",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0032, 0x0036 },
+ unicodeslot=0x3256,
+ },
+ [0x3257]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER TWENTY SEVEN",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0032, 0x0037 },
+ unicodeslot=0x3257,
+ },
+ [0x3258]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER TWENTY EIGHT",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0032, 0x0038 },
+ unicodeslot=0x3258,
+ },
+ [0x3259]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER TWENTY NINE",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0032, 0x0039 },
+ unicodeslot=0x3259,
+ },
+ [0x325A]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER THIRTY",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0033, 0x0030 },
+ unicodeslot=0x325A,
+ },
+ [0x325B]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER THIRTY ONE",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0033, 0x0031 },
+ unicodeslot=0x325B,
+ },
+ [0x325C]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER THIRTY TWO",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0033, 0x0032 },
+ unicodeslot=0x325C,
+ },
+ [0x325D]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER THIRTY THREE",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0033, 0x0033 },
+ unicodeslot=0x325D,
+ },
+ [0x325E]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER THIRTY FOUR",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0033, 0x0034 },
+ unicodeslot=0x325E,
+ },
+ [0x325F]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER THIRTY FIVE",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0033, 0x0035 },
+ unicodeslot=0x325F,
+ },
+ [0x3260]={
+ adobename="kiyeokcirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL KIYEOK",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1100 },
+ unicodeslot=0x3260,
+ },
+ [0x3261]={
+ adobename="nieuncirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL NIEUN",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1102 },
+ unicodeslot=0x3261,
+ },
+ [0x3262]={
+ adobename="tikeutcirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL TIKEUT",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1103 },
+ unicodeslot=0x3262,
+ },
+ [0x3263]={
+ adobename="rieulcirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL RIEUL",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1105 },
+ unicodeslot=0x3263,
+ },
+ [0x3264]={
+ adobename="mieumcirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL MIEUM",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1106 },
+ unicodeslot=0x3264,
+ },
+ [0x3265]={
+ adobename="pieupcirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL PIEUP",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1107 },
+ unicodeslot=0x3265,
+ },
+ [0x3266]={
+ adobename="sioscirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL SIOS",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1109 },
+ unicodeslot=0x3266,
+ },
+ [0x3267]={
+ adobename="ieungcirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL IEUNG",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110B },
+ unicodeslot=0x3267,
+ },
+ [0x3268]={
+ adobename="cieuccirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL CIEUC",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110C },
+ unicodeslot=0x3268,
+ },
+ [0x3269]={
+ adobename="chieuchcirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL CHIEUCH",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110E },
+ unicodeslot=0x3269,
+ },
+ [0x326A]={
+ adobename="khieukhcirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL KHIEUKH",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110F },
+ unicodeslot=0x326A,
+ },
+ [0x326B]={
+ adobename="thieuthcirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL THIEUTH",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1110 },
+ unicodeslot=0x326B,
+ },
+ [0x326C]={
+ adobename="phieuphcirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL PHIEUPH",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1111 },
+ unicodeslot=0x326C,
+ },
+ [0x326D]={
+ adobename="hieuhcirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL HIEUH",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1112 },
+ unicodeslot=0x326D,
+ },
+ [0x326E]={
+ adobename="kiyeokacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL KIYEOK A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1100, 0x1161 },
+ unicodeslot=0x326E,
+ },
+ [0x326F]={
+ adobename="nieunacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL NIEUN A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1102, 0x1161 },
+ unicodeslot=0x326F,
+ },
+ [0x3270]={
+ adobename="tikeutacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL TIKEUT A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1103, 0x1161 },
+ unicodeslot=0x3270,
+ },
+ [0x3271]={
+ adobename="rieulacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL RIEUL A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1105, 0x1161 },
+ unicodeslot=0x3271,
+ },
+ [0x3272]={
+ adobename="mieumacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL MIEUM A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1106, 0x1161 },
+ unicodeslot=0x3272,
+ },
+ [0x3273]={
+ adobename="pieupacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL PIEUP A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1107, 0x1161 },
+ unicodeslot=0x3273,
+ },
+ [0x3274]={
+ adobename="siosacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL SIOS A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1109, 0x1161 },
+ unicodeslot=0x3274,
+ },
+ [0x3275]={
+ adobename="ieungacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL IEUNG A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110B, 0x1161 },
+ unicodeslot=0x3275,
+ },
+ [0x3276]={
+ adobename="cieucacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL CIEUC A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110C, 0x1161 },
+ unicodeslot=0x3276,
+ },
+ [0x3277]={
+ adobename="chieuchacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL CHIEUCH A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110E, 0x1161 },
+ unicodeslot=0x3277,
+ },
+ [0x3278]={
+ adobename="khieukhacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL KHIEUKH A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x110F, 0x1161 },
+ unicodeslot=0x3278,
+ },
+ [0x3279]={
+ adobename="thieuthacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL THIEUTH A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1110, 0x1161 },
+ unicodeslot=0x3279,
+ },
+ [0x327A]={
+ adobename="phieuphacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL PHIEUPH A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1111, 0x1161 },
+ unicodeslot=0x327A,
+ },
+ [0x327B]={
+ adobename="hieuhacirclekorean",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL HIEUH A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x1112, 0x1161 },
+ unicodeslot=0x327B,
+ },
+ [0x327C]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KOREAN CHARACTER CHAMKO",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x110E, 0x1161, 0x11B7, 0x1100, 0x1169 },
+ unicodeslot=0x327C,
+ },
+ [0x327D]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KOREAN CHARACTER JUEUI",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x110C, 0x116E, 0x110B, 0x1174 },
+ unicodeslot=0x327D,
+ },
+ [0x327E]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED HANGUL IEUNG U",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x110B, 0x116E },
+ unicodeslot=0x327E,
+ },
+ [0x327F]={
+ adobename="koreanstandardsymbol",
+ category="so",
+ cjkwd="w",
+ description="KOREAN STANDARD SYMBOL",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x327F,
+ },
+ [0x3280]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH ONE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E00 },
+ unicodeslot=0x3280,
+ },
+ [0x3281]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH TWO",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E8C },
+ unicodeslot=0x3281,
+ },
+ [0x3282]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH THREE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E09 },
+ unicodeslot=0x3282,
+ },
+ [0x3283]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH FOUR",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x56DB },
+ unicodeslot=0x3283,
+ },
+ [0x3284]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH FIVE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E94 },
+ unicodeslot=0x3284,
+ },
+ [0x3285]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH SIX",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x516D },
+ unicodeslot=0x3285,
+ },
+ [0x3286]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH SEVEN",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E03 },
+ unicodeslot=0x3286,
+ },
+ [0x3287]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH EIGHT",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x516B },
+ unicodeslot=0x3287,
+ },
+ [0x3288]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH NINE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E5D },
+ unicodeslot=0x3288,
+ },
+ [0x3289]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH TEN",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5341 },
+ unicodeslot=0x3289,
+ },
+ [0x328A]={
+ adobename="ideographmooncircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH MOON",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6708 },
+ unicodeslot=0x328A,
+ },
+ [0x328B]={
+ adobename="ideographfirecircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH FIRE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x706B },
+ unicodeslot=0x328B,
+ },
+ [0x328C]={
+ adobename="ideographwatercircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH WATER",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6C34 },
+ unicodeslot=0x328C,
+ },
+ [0x328D]={
+ adobename="ideographwoodcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH WOOD",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6728 },
+ unicodeslot=0x328D,
+ },
+ [0x328E]={
+ adobename="ideographmetalcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH METAL",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x91D1 },
+ unicodeslot=0x328E,
+ },
+ [0x328F]={
+ adobename="ideographearthcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH EARTH",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x571F },
+ unicodeslot=0x328F,
+ },
+ [0x3290]={
+ adobename="ideographsuncircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH SUN",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x65E5 },
+ unicodeslot=0x3290,
+ },
+ [0x3291]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH STOCK",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x682A },
+ unicodeslot=0x3291,
+ },
+ [0x3292]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH HAVE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6709 },
+ unicodeslot=0x3292,
+ },
+ [0x3293]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH SOCIETY",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x793E },
+ unicodeslot=0x3293,
+ },
+ [0x3294]={
+ adobename="ideographnamecircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH NAME",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x540D },
+ unicodeslot=0x3294,
+ },
+ [0x3295]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH SPECIAL",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x7279 },
+ unicodeslot=0x3295,
+ },
+ [0x3296]={
+ adobename="ideographicfinancialcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH FINANCIAL",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x8CA1 },
+ unicodeslot=0x3296,
+ },
+ [0x3297]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH CONGRATULATION",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x795D },
+ unicodeslot=0x3297,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x3298]={
+ adobename="ideographiclaborcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH LABOR",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x52B4 },
+ unicodeslot=0x3298,
+ },
+ [0x3299]={
+ adobename="ideographicsecretcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH SECRET",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x79D8 },
+ unicodeslot=0x3299,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x329A]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH MALE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x7537 },
+ unicodeslot=0x329A,
+ },
+ [0x329B]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH FEMALE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5973 },
+ unicodeslot=0x329B,
+ },
+ [0x329C]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH SUITABLE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x9069 },
+ unicodeslot=0x329C,
+ },
+ [0x329D]={
+ adobename="ideographicexcellentcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH EXCELLENT",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x512A },
+ unicodeslot=0x329D,
+ },
+ [0x329E]={
+ adobename="ideographicprintcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH PRINT",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5370 },
+ unicodeslot=0x329E,
+ },
+ [0x329F]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH ATTENTION",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6CE8 },
+ unicodeslot=0x329F,
+ },
+ [0x32A0]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH ITEM",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x9805 },
+ unicodeslot=0x32A0,
+ },
+ [0x32A1]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH REST",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4F11 },
+ unicodeslot=0x32A1,
+ },
+ [0x32A2]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH COPY",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5199 },
+ unicodeslot=0x32A2,
+ },
+ [0x32A3]={
+ adobename="ideographiccorrectcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH CORRECT",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x6B63 },
+ unicodeslot=0x32A3,
+ },
+ [0x32A4]={
+ adobename="ideographichighcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH HIGH",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E0A },
+ unicodeslot=0x32A4,
+ },
+ [0x32A5]={
+ adobename="ideographiccentrecircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH CENTRE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E2D },
+ unicodeslot=0x32A5,
+ },
+ [0x32A6]={
+ adobename="ideographiclowcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH LOW",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4E0B },
+ unicodeslot=0x32A6,
+ },
+ [0x32A7]={
+ adobename="ideographicleftcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH LEFT",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5DE6 },
+ unicodeslot=0x32A7,
+ },
+ [0x32A8]={
+ adobename="ideographicrightcircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH RIGHT",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x53F3 },
+ unicodeslot=0x32A8,
+ },
+ [0x32A9]={
+ adobename="ideographicmedicinecircle",
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH MEDICINE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x533B },
+ unicodeslot=0x32A9,
+ },
+ [0x32AA]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH RELIGION",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5B97 },
+ unicodeslot=0x32AA,
+ },
+ [0x32AB]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH STUDY",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5B66 },
+ unicodeslot=0x32AB,
+ },
+ [0x32AC]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH SUPERVISE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x76E3 },
+ unicodeslot=0x32AC,
+ },
+ [0x32AD]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH ENTERPRISE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x4F01 },
+ unicodeslot=0x32AD,
+ },
+ [0x32AE]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH RESOURCE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x8CC7 },
+ unicodeslot=0x32AE,
+ },
+ [0x32AF]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH ALLIANCE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5354 },
+ unicodeslot=0x32AF,
+ },
+ [0x32B0]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH NIGHT",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x591C },
+ unicodeslot=0x32B0,
+ },
+ [0x32B1]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER THIRTY SIX",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0033, 0x0036 },
+ unicodeslot=0x32B1,
+ },
+ [0x32B2]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER THIRTY SEVEN",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0033, 0x0037 },
+ unicodeslot=0x32B2,
+ },
+ [0x32B3]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER THIRTY EIGHT",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0033, 0x0038 },
+ unicodeslot=0x32B3,
+ },
+ [0x32B4]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER THIRTY NINE",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0033, 0x0039 },
+ unicodeslot=0x32B4,
+ },
+ [0x32B5]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER FORTY",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0034, 0x0030 },
+ unicodeslot=0x32B5,
+ },
+ [0x32B6]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER FORTY ONE",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0034, 0x0031 },
+ unicodeslot=0x32B6,
+ },
+ [0x32B7]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER FORTY TWO",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0034, 0x0032 },
+ unicodeslot=0x32B7,
+ },
+ [0x32B8]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER FORTY THREE",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0034, 0x0033 },
+ unicodeslot=0x32B8,
+ },
+ [0x32B9]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER FORTY FOUR",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0034, 0x0034 },
+ unicodeslot=0x32B9,
+ },
+ [0x32BA]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER FORTY FIVE",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0034, 0x0035 },
+ unicodeslot=0x32BA,
+ },
+ [0x32BB]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER FORTY SIX",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0034, 0x0036 },
+ unicodeslot=0x32BB,
+ },
+ [0x32BC]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER FORTY SEVEN",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0034, 0x0037 },
+ unicodeslot=0x32BC,
+ },
+ [0x32BD]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER FORTY EIGHT",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0034, 0x0038 },
+ unicodeslot=0x32BD,
+ },
+ [0x32BE]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER FORTY NINE",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0034, 0x0039 },
+ unicodeslot=0x32BE,
+ },
+ [0x32BF]={
+ category="no",
+ cjkwd="w",
+ description="CIRCLED NUMBER FIFTY",
+ direction="on",
+ linebreak="id",
+ specials={ "circle", 0x0035, 0x0030 },
+ unicodeslot=0x32BF,
+ },
+ [0x32C0]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x6708 },
+ unicodeslot=0x32C0,
+ },
+ [0x32C1]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x6708 },
+ unicodeslot=0x32C1,
+ },
+ [0x32C2]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0033, 0x6708 },
+ unicodeslot=0x32C2,
+ },
+ [0x32C3]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0034, 0x6708 },
+ unicodeslot=0x32C3,
+ },
+ [0x32C4]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0035, 0x6708 },
+ unicodeslot=0x32C4,
+ },
+ [0x32C5]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0036, 0x6708 },
+ unicodeslot=0x32C5,
+ },
+ [0x32C6]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0037, 0x6708 },
+ unicodeslot=0x32C6,
+ },
+ [0x32C7]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0038, 0x6708 },
+ unicodeslot=0x32C7,
+ },
+ [0x32C8]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0039, 0x6708 },
+ unicodeslot=0x32C8,
+ },
+ [0x32C9]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0030, 0x6708 },
+ unicodeslot=0x32C9,
+ },
+ [0x32CA]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0031, 0x6708 },
+ unicodeslot=0x32CA,
+ },
+ [0x32CB]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0032, 0x6708 },
+ unicodeslot=0x32CB,
+ },
+ [0x32CC]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE HG",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x0048, 0x0067 },
+ unicodeslot=0x32CC,
+ },
+ [0x32CD]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE ERG",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x0065, 0x0072, 0x0067 },
+ unicodeslot=0x32CD,
+ },
+ [0x32CE]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE EV",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x0065, 0x0056 },
+ unicodeslot=0x32CE,
+ },
+ [0x32CF]={
+ category="so",
+ cjkwd="w",
+ description="LIMITED LIABILITY SIGN",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x004C, 0x0054, 0x0044 },
+ unicodeslot=0x32CF,
+ },
+ [0x32D0]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA A",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30A2 },
+ unicodeslot=0x32D0,
+ },
+ [0x32D1]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA I",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30A4 },
+ unicodeslot=0x32D1,
+ },
+ [0x32D2]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA U",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30A6 },
+ unicodeslot=0x32D2,
+ },
+ [0x32D3]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA E",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30A8 },
+ unicodeslot=0x32D3,
+ },
+ [0x32D4]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA O",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30AA },
+ unicodeslot=0x32D4,
+ },
+ [0x32D5]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA KA",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30AB },
+ unicodeslot=0x32D5,
+ },
+ [0x32D6]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA KI",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30AD },
+ unicodeslot=0x32D6,
+ },
+ [0x32D7]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA KU",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30AF },
+ unicodeslot=0x32D7,
+ },
+ [0x32D8]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA KE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30B1 },
+ unicodeslot=0x32D8,
+ },
+ [0x32D9]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA KO",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30B3 },
+ unicodeslot=0x32D9,
+ },
+ [0x32DA]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA SA",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30B5 },
+ unicodeslot=0x32DA,
+ },
+ [0x32DB]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA SI",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30B7 },
+ unicodeslot=0x32DB,
+ },
+ [0x32DC]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA SU",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30B9 },
+ unicodeslot=0x32DC,
+ },
+ [0x32DD]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA SE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30BB },
+ unicodeslot=0x32DD,
+ },
+ [0x32DE]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA SO",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30BD },
+ unicodeslot=0x32DE,
+ },
+ [0x32DF]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA TA",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30BF },
+ unicodeslot=0x32DF,
+ },
+ [0x32E0]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA TI",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30C1 },
+ unicodeslot=0x32E0,
+ },
+ [0x32E1]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA TU",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30C4 },
+ unicodeslot=0x32E1,
+ },
+ [0x32E2]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA TE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30C6 },
+ unicodeslot=0x32E2,
+ },
+ [0x32E3]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA TO",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30C8 },
+ unicodeslot=0x32E3,
+ },
+ [0x32E4]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA NA",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30CA },
+ unicodeslot=0x32E4,
+ },
+ [0x32E5]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA NI",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30CB },
+ unicodeslot=0x32E5,
+ },
+ [0x32E6]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA NU",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30CC },
+ unicodeslot=0x32E6,
+ },
+ [0x32E7]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA NE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30CD },
+ unicodeslot=0x32E7,
+ },
+ [0x32E8]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA NO",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30CE },
+ unicodeslot=0x32E8,
+ },
+ [0x32E9]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA HA",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30CF },
+ unicodeslot=0x32E9,
+ },
+ [0x32EA]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA HI",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30D2 },
+ unicodeslot=0x32EA,
+ },
+ [0x32EB]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA HU",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30D5 },
+ unicodeslot=0x32EB,
+ },
+ [0x32EC]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA HE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30D8 },
+ unicodeslot=0x32EC,
+ },
+ [0x32ED]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA HO",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30DB },
+ unicodeslot=0x32ED,
+ },
+ [0x32EE]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA MA",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30DE },
+ unicodeslot=0x32EE,
+ },
+ [0x32EF]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA MI",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30DF },
+ unicodeslot=0x32EF,
+ },
+ [0x32F0]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA MU",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E0 },
+ unicodeslot=0x32F0,
+ },
+ [0x32F1]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA ME",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E1 },
+ unicodeslot=0x32F1,
+ },
+ [0x32F2]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA MO",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E2 },
+ unicodeslot=0x32F2,
+ },
+ [0x32F3]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA YA",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E4 },
+ unicodeslot=0x32F3,
+ },
+ [0x32F4]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA YU",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E6 },
+ unicodeslot=0x32F4,
+ },
+ [0x32F5]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA YO",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E8 },
+ unicodeslot=0x32F5,
+ },
+ [0x32F6]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA RA",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30E9 },
+ unicodeslot=0x32F6,
+ },
+ [0x32F7]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA RI",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30EA },
+ unicodeslot=0x32F7,
+ },
+ [0x32F8]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA RU",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30EB },
+ unicodeslot=0x32F8,
+ },
+ [0x32F9]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA RE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30EC },
+ unicodeslot=0x32F9,
+ },
+ [0x32FA]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA RO",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30ED },
+ unicodeslot=0x32FA,
+ },
+ [0x32FB]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA WA",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30EF },
+ unicodeslot=0x32FB,
+ },
+ [0x32FC]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA WI",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30F0 },
+ unicodeslot=0x32FC,
+ },
+ [0x32FD]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA WE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30F1 },
+ unicodeslot=0x32FD,
+ },
+ [0x32FE]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED KATAKANA WO",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x30F2 },
+ unicodeslot=0x32FE,
+ },
+ [0x3300]={
+ adobename="apaatosquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE APAATO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A2, 0x30D1, 0x30FC, 0x30C8 },
+ unicodeslot=0x3300,
+ },
+ [0x3301]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE ARUHUA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A2, 0x30EB, 0x30D5, 0x30A1 },
+ unicodeslot=0x3301,
+ },
+ [0x3302]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE ANPEA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A2, 0x30F3, 0x30DA, 0x30A2 },
+ unicodeslot=0x3302,
+ },
+ [0x3303]={
+ adobename="aarusquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE AARU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A2, 0x30FC, 0x30EB },
+ unicodeslot=0x3303,
+ },
+ [0x3304]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE ININGU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A4, 0x30CB, 0x30F3, 0x30B0 },
+ unicodeslot=0x3304,
+ },
+ [0x3305]={
+ adobename="intisquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE INTI",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A4, 0x30F3, 0x30C1 },
+ unicodeslot=0x3305,
+ },
+ [0x3306]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE UON",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A6, 0x30A9, 0x30F3 },
+ unicodeslot=0x3306,
+ },
+ [0x3307]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE ESUKUUDO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A8, 0x30B9, 0x30AF, 0x30FC, 0x30C9 },
+ unicodeslot=0x3307,
+ },
+ [0x3308]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE EEKAA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30A8, 0x30FC, 0x30AB, 0x30FC },
+ unicodeslot=0x3308,
+ },
+ [0x3309]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE ONSU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AA, 0x30F3, 0x30B9 },
+ unicodeslot=0x3309,
+ },
+ [0x330A]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE OOMU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AA, 0x30FC, 0x30E0 },
+ unicodeslot=0x330A,
+ },
+ [0x330B]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE KAIRI",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AB, 0x30A4, 0x30EA },
+ unicodeslot=0x330B,
+ },
+ [0x330C]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE KARATTO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AB, 0x30E9, 0x30C3, 0x30C8 },
+ unicodeslot=0x330C,
+ },
+ [0x330D]={
+ adobename="karoriisquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KARORII",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AB, 0x30ED, 0x30EA, 0x30FC },
+ unicodeslot=0x330D,
+ },
+ [0x330E]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE GARON",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AC, 0x30ED, 0x30F3 },
+ unicodeslot=0x330E,
+ },
+ [0x330F]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE GANMA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AC, 0x30F3, 0x30DE },
+ unicodeslot=0x330F,
+ },
+ [0x3310]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE GIGA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AE, 0x30AC },
+ unicodeslot=0x3310,
+ },
+ [0x3311]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE GINII",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AE, 0x30CB, 0x30FC },
+ unicodeslot=0x3311,
+ },
+ [0x3312]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE KYURII",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AD, 0x30E5, 0x30EA, 0x30FC },
+ unicodeslot=0x3312,
+ },
+ [0x3313]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE GIRUDAA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AE, 0x30EB, 0x30C0, 0x30FC },
+ unicodeslot=0x3313,
+ },
+ [0x3314]={
+ adobename="kirosquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KIRO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AD, 0x30ED },
+ unicodeslot=0x3314,
+ },
+ [0x3315]={
+ adobename="kiroguramusquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KIROGURAMU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AD, 0x30ED, 0x30B0, 0x30E9, 0x30E0 },
+ unicodeslot=0x3315,
+ },
+ [0x3316]={
+ adobename="kiromeetorusquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KIROMEETORU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AD, 0x30ED, 0x30E1, 0x30FC, 0x30C8, 0x30EB },
+ unicodeslot=0x3316,
+ },
+ [0x3317]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE KIROWATTO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AD, 0x30ED, 0x30EF, 0x30C3, 0x30C8 },
+ unicodeslot=0x3317,
+ },
+ [0x3318]={
+ adobename="guramusquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE GURAMU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B0, 0x30E9, 0x30E0 },
+ unicodeslot=0x3318,
+ },
+ [0x3319]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE GURAMUTON",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B0, 0x30E9, 0x30E0, 0x30C8, 0x30F3 },
+ unicodeslot=0x3319,
+ },
+ [0x331A]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE KURUZEIRO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AF, 0x30EB, 0x30BC, 0x30A4, 0x30ED },
+ unicodeslot=0x331A,
+ },
+ [0x331B]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE KUROONE",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30AF, 0x30ED, 0x30FC, 0x30CD },
+ unicodeslot=0x331B,
+ },
+ [0x331C]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE KEESU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B1, 0x30FC, 0x30B9 },
+ unicodeslot=0x331C,
+ },
+ [0x331D]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE KORUNA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B3, 0x30EB, 0x30CA },
+ unicodeslot=0x331D,
+ },
+ [0x331E]={
+ adobename="kooposquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KOOPO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B3, 0x30FC, 0x30DD },
+ unicodeslot=0x331E,
+ },
+ [0x331F]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE SAIKURU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B5, 0x30A4, 0x30AF, 0x30EB },
+ unicodeslot=0x331F,
+ },
+ [0x3320]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE SANTIIMU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B5, 0x30F3, 0x30C1, 0x30FC, 0x30E0 },
+ unicodeslot=0x3320,
+ },
+ [0x3321]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE SIRINGU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B7, 0x30EA, 0x30F3, 0x30B0 },
+ unicodeslot=0x3321,
+ },
+ [0x3322]={
+ adobename="sentisquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE SENTI",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30BB, 0x30F3, 0x30C1 },
+ unicodeslot=0x3322,
+ },
+ [0x3323]={
+ adobename="sentosquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE SENTO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30BB, 0x30F3, 0x30C8 },
+ unicodeslot=0x3323,
+ },
+ [0x3324]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE DAASU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30C0, 0x30FC, 0x30B9 },
+ unicodeslot=0x3324,
+ },
+ [0x3325]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE DESI",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30C7, 0x30B7 },
+ unicodeslot=0x3325,
+ },
+ [0x3326]={
+ adobename="dorusquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE DORU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30C9, 0x30EB },
+ unicodeslot=0x3326,
+ },
+ [0x3327]={
+ adobename="tonsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE TON",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30C8, 0x30F3 },
+ unicodeslot=0x3327,
+ },
+ [0x3328]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE NANO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30CA, 0x30CE },
+ unicodeslot=0x3328,
+ },
+ [0x3329]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE NOTTO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30CE, 0x30C3, 0x30C8 },
+ unicodeslot=0x3329,
+ },
+ [0x332A]={
+ adobename="haitusquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE HAITU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30CF, 0x30A4, 0x30C4 },
+ unicodeslot=0x332A,
+ },
+ [0x332B]={
+ adobename="paasentosquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE PAASENTO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D1, 0x30FC, 0x30BB, 0x30F3, 0x30C8 },
+ unicodeslot=0x332B,
+ },
+ [0x332C]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE PAATU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D1, 0x30FC, 0x30C4 },
+ unicodeslot=0x332C,
+ },
+ [0x332D]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE BAARERU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D0, 0x30FC, 0x30EC, 0x30EB },
+ unicodeslot=0x332D,
+ },
+ [0x332E]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE PIASUTORU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D4, 0x30A2, 0x30B9, 0x30C8, 0x30EB },
+ unicodeslot=0x332E,
+ },
+ [0x332F]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE PIKURU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D4, 0x30AF, 0x30EB },
+ unicodeslot=0x332F,
+ },
+ [0x3330]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE PIKO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D4, 0x30B3 },
+ unicodeslot=0x3330,
+ },
+ [0x3331]={
+ adobename="birusquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE BIRU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D3, 0x30EB },
+ unicodeslot=0x3331,
+ },
+ [0x3332]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE HUARADDO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D5, 0x30A1, 0x30E9, 0x30C3, 0x30C9 },
+ unicodeslot=0x3332,
+ },
+ [0x3333]={
+ adobename="huiitosquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE HUIITO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D5, 0x30A3, 0x30FC, 0x30C8 },
+ unicodeslot=0x3333,
+ },
+ [0x3334]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE BUSSYERU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D6, 0x30C3, 0x30B7, 0x30A7, 0x30EB },
+ unicodeslot=0x3334,
+ },
+ [0x3335]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE HURAN",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D5, 0x30E9, 0x30F3 },
+ unicodeslot=0x3335,
+ },
+ [0x3336]={
+ adobename="hekutaarusquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE HEKUTAARU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D8, 0x30AF, 0x30BF, 0x30FC, 0x30EB },
+ unicodeslot=0x3336,
+ },
+ [0x3337]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE PESO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DA, 0x30BD },
+ unicodeslot=0x3337,
+ },
+ [0x3338]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE PENIHI",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DA, 0x30CB, 0x30D2 },
+ unicodeslot=0x3338,
+ },
+ [0x3339]={
+ adobename="herutusquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE HERUTU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D8, 0x30EB, 0x30C4 },
+ unicodeslot=0x3339,
+ },
+ [0x333A]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE PENSU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DA, 0x30F3, 0x30B9 },
+ unicodeslot=0x333A,
+ },
+ [0x333B]={
+ adobename="peezisquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE PEEZI",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DA, 0x30FC, 0x30B8 },
+ unicodeslot=0x333B,
+ },
+ [0x333C]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE BEETA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30D9, 0x30FC, 0x30BF },
+ unicodeslot=0x333C,
+ },
+ [0x333D]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE POINTO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DD, 0x30A4, 0x30F3, 0x30C8 },
+ unicodeslot=0x333D,
+ },
+ [0x333E]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE BORUTO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DC, 0x30EB, 0x30C8 },
+ unicodeslot=0x333E,
+ },
+ [0x333F]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE HON",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DB, 0x30F3 },
+ unicodeslot=0x333F,
+ },
+ [0x3340]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE PONDO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DD, 0x30F3, 0x30C9 },
+ unicodeslot=0x3340,
+ },
+ [0x3341]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE HOORU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DB, 0x30FC, 0x30EB },
+ unicodeslot=0x3341,
+ },
+ [0x3342]={
+ adobename="hoonsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE HOON",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DB, 0x30FC, 0x30F3 },
+ unicodeslot=0x3342,
+ },
+ [0x3343]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE MAIKURO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DE, 0x30A4, 0x30AF, 0x30ED },
+ unicodeslot=0x3343,
+ },
+ [0x3344]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE MAIRU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DE, 0x30A4, 0x30EB },
+ unicodeslot=0x3344,
+ },
+ [0x3345]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE MAHHA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DE, 0x30C3, 0x30CF },
+ unicodeslot=0x3345,
+ },
+ [0x3346]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE MARUKU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DE, 0x30EB, 0x30AF },
+ unicodeslot=0x3346,
+ },
+ [0x3347]={
+ adobename="mansyonsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MANSYON",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DE, 0x30F3, 0x30B7, 0x30E7, 0x30F3 },
+ unicodeslot=0x3347,
+ },
+ [0x3348]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE MIKURON",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DF, 0x30AF, 0x30ED, 0x30F3 },
+ unicodeslot=0x3348,
+ },
+ [0x3349]={
+ adobename="mirisquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MIRI",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DF, 0x30EA },
+ unicodeslot=0x3349,
+ },
+ [0x334A]={
+ adobename="miribaarusquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MIRIBAARU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30DF, 0x30EA, 0x30D0, 0x30FC, 0x30EB },
+ unicodeslot=0x334A,
+ },
+ [0x334B]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE MEGA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30E1, 0x30AC },
+ unicodeslot=0x334B,
+ },
+ [0x334C]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE MEGATON",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30E1, 0x30AC, 0x30C8, 0x30F3 },
+ unicodeslot=0x334C,
+ },
+ [0x334D]={
+ adobename="meetorusquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MEETORU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30E1, 0x30FC, 0x30C8, 0x30EB },
+ unicodeslot=0x334D,
+ },
+ [0x334E]={
+ adobename="yaadosquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE YAADO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30E4, 0x30FC, 0x30C9 },
+ unicodeslot=0x334E,
+ },
+ [0x334F]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE YAARU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30E4, 0x30FC, 0x30EB },
+ unicodeslot=0x334F,
+ },
+ [0x3350]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE YUAN",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30E6, 0x30A2, 0x30F3 },
+ unicodeslot=0x3350,
+ },
+ [0x3351]={
+ adobename="rittorusquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE RITTORU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EA, 0x30C3, 0x30C8, 0x30EB },
+ unicodeslot=0x3351,
+ },
+ [0x3352]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE RIRA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EA, 0x30E9 },
+ unicodeslot=0x3352,
+ },
+ [0x3353]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE RUPII",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EB, 0x30D4, 0x30FC },
+ unicodeslot=0x3353,
+ },
+ [0x3354]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE RUUBURU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EB, 0x30FC, 0x30D6, 0x30EB },
+ unicodeslot=0x3354,
+ },
+ [0x3355]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE REMU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EC, 0x30E0 },
+ unicodeslot=0x3355,
+ },
+ [0x3356]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE RENTOGEN",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EC, 0x30F3, 0x30C8, 0x30B2, 0x30F3 },
+ unicodeslot=0x3356,
+ },
+ [0x3357]={
+ adobename="wattosquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE WATTO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30EF, 0x30C3, 0x30C8 },
+ unicodeslot=0x3357,
+ },
+ [0x3358]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0030, 0x70B9 },
+ unicodeslot=0x3358,
+ },
+ [0x3359]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x70B9 },
+ unicodeslot=0x3359,
+ },
+ [0x335A]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x70B9 },
+ unicodeslot=0x335A,
+ },
+ [0x335B]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0033, 0x70B9 },
+ unicodeslot=0x335B,
+ },
+ [0x335C]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0034, 0x70B9 },
+ unicodeslot=0x335C,
+ },
+ [0x335D]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0035, 0x70B9 },
+ unicodeslot=0x335D,
+ },
+ [0x335E]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0036, 0x70B9 },
+ unicodeslot=0x335E,
+ },
+ [0x335F]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0037, 0x70B9 },
+ unicodeslot=0x335F,
+ },
+ [0x3360]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0038, 0x70B9 },
+ unicodeslot=0x3360,
+ },
+ [0x3361]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0039, 0x70B9 },
+ unicodeslot=0x3361,
+ },
+ [0x3362]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0030, 0x70B9 },
+ unicodeslot=0x3362,
+ },
+ [0x3363]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0031, 0x70B9 },
+ unicodeslot=0x3363,
+ },
+ [0x3364]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0032, 0x70B9 },
+ unicodeslot=0x3364,
+ },
+ [0x3365]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0033, 0x70B9 },
+ unicodeslot=0x3365,
+ },
+ [0x3366]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0034, 0x70B9 },
+ unicodeslot=0x3366,
+ },
+ [0x3367]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0035, 0x70B9 },
+ unicodeslot=0x3367,
+ },
+ [0x3368]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0036, 0x70B9 },
+ unicodeslot=0x3368,
+ },
+ [0x3369]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0037, 0x70B9 },
+ unicodeslot=0x3369,
+ },
+ [0x336A]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0038, 0x70B9 },
+ unicodeslot=0x336A,
+ },
+ [0x336B]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0039, 0x70B9 },
+ unicodeslot=0x336B,
+ },
+ [0x336C]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0030, 0x70B9 },
+ unicodeslot=0x336C,
+ },
+ [0x336D]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0031, 0x70B9 },
+ unicodeslot=0x336D,
+ },
+ [0x336E]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0032, 0x70B9 },
+ unicodeslot=0x336E,
+ },
+ [0x336F]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0033, 0x70B9 },
+ unicodeslot=0x336F,
+ },
+ [0x3370]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0034, 0x70B9 },
+ unicodeslot=0x3370,
+ },
+ [0x3371]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE HPA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0068, 0x0050, 0x0061 },
+ unicodeslot=0x3371,
+ },
+ [0x3372]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE DA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0064, 0x0061 },
+ unicodeslot=0x3372,
+ },
+ [0x3373]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE AU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0041, 0x0055 },
+ unicodeslot=0x3373,
+ },
+ [0x3374]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE BAR",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0062, 0x0061, 0x0072 },
+ unicodeslot=0x3374,
+ },
+ [0x3375]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE OV",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006F, 0x0056 },
+ unicodeslot=0x3375,
+ },
+ [0x3376]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE PC",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0070, 0x0063 },
+ unicodeslot=0x3376,
+ },
+ [0x3377]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE DM",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x0064, 0x006D },
+ unicodeslot=0x3377,
+ },
+ [0x3378]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE DM SQUARED",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x0064, 0x006D, 0x00B2 },
+ unicodeslot=0x3378,
+ },
+ [0x3379]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE DM CUBED",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x0064, 0x006D, 0x00B3 },
+ unicodeslot=0x3379,
+ },
+ [0x337A]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE IU",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x0049, 0x0055 },
+ unicodeslot=0x337A,
+ },
+ [0x337B]={
+ adobename="heiseierasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE ERA NAME HEISEI",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5E73, 0x6210 },
+ unicodeslot=0x337B,
+ },
+ [0x337C]={
+ adobename="syouwaerasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE ERA NAME SYOUWA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x662D, 0x548C },
+ unicodeslot=0x337C,
+ },
+ [0x337D]={
+ adobename="taisyouerasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE ERA NAME TAISYOU",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5927, 0x6B63 },
+ unicodeslot=0x337D,
+ },
+ [0x337E]={
+ adobename="meizierasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE ERA NAME MEIZI",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x660E, 0x6CBB },
+ unicodeslot=0x337E,
+ },
+ [0x337F]={
+ adobename="corporationsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE CORPORATION",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x682A, 0x5F0F, 0x4F1A, 0x793E },
+ unicodeslot=0x337F,
+ },
+ [0x3380]={
+ adobename="paampssquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE PA AMPS",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0070, 0x0041 },
+ unicodeslot=0x3380,
+ },
+ [0x3381]={
+ adobename="nasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE NA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006E, 0x0041 },
+ unicodeslot=0x3381,
+ },
+ [0x3382]={
+ adobename="muasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MU A",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x03BC, 0x0041 },
+ unicodeslot=0x3382,
+ },
+ [0x3383]={
+ adobename="masquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x0041 },
+ unicodeslot=0x3383,
+ },
+ [0x3384]={
+ adobename="kasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x0041 },
+ unicodeslot=0x3384,
+ },
+ [0x3385]={
+ adobename="KBsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KB",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x004B, 0x0042 },
+ unicodeslot=0x3385,
+ },
+ [0x3386]={
+ adobename="MBsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MB",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x004D, 0x0042 },
+ unicodeslot=0x3386,
+ },
+ [0x3387]={
+ adobename="GBsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE GB",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0047, 0x0042 },
+ unicodeslot=0x3387,
+ },
+ [0x3388]={
+ adobename="calsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE CAL",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0063, 0x0061, 0x006C },
+ unicodeslot=0x3388,
+ },
+ [0x3389]={
+ adobename="kcalsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KCAL",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x0063, 0x0061, 0x006C },
+ unicodeslot=0x3389,
+ },
+ [0x338A]={
+ adobename="pfsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE PF",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0070, 0x0046 },
+ unicodeslot=0x338A,
+ },
+ [0x338B]={
+ adobename="nfsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE NF",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006E, 0x0046 },
+ unicodeslot=0x338B,
+ },
+ [0x338C]={
+ adobename="mufsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MU F",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x03BC, 0x0046 },
+ unicodeslot=0x338C,
+ },
+ [0x338D]={
+ adobename="mugsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MU G",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x03BC, 0x0067 },
+ unicodeslot=0x338D,
+ },
+ [0x338E]={
+ adobename="squaremg",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MG",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x0067 },
+ unicodeslot=0x338E,
+ },
+ [0x338F]={
+ adobename="squarekg",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KG",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x0067 },
+ unicodeslot=0x338F,
+ },
+ [0x3390]={
+ adobename="Hzsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE HZ",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0048, 0x007A },
+ unicodeslot=0x3390,
+ },
+ [0x3391]={
+ adobename="khzsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KHZ",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x0048, 0x007A },
+ unicodeslot=0x3391,
+ },
+ [0x3392]={
+ adobename="mhzsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MHZ",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x004D, 0x0048, 0x007A },
+ unicodeslot=0x3392,
+ },
+ [0x3393]={
+ adobename="ghzsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE GHZ",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0047, 0x0048, 0x007A },
+ unicodeslot=0x3393,
+ },
+ [0x3394]={
+ adobename="thzsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE THZ",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0054, 0x0048, 0x007A },
+ unicodeslot=0x3394,
+ },
+ [0x3395]={
+ adobename="mulsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MU L",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x03BC, 0x2113 },
+ unicodeslot=0x3395,
+ },
+ [0x3396]={
+ adobename="mlsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE ML",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x2113 },
+ unicodeslot=0x3396,
+ },
+ [0x3397]={
+ adobename="dlsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE DL",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0064, 0x2113 },
+ unicodeslot=0x3397,
+ },
+ [0x3398]={
+ adobename="klsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KL",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x2113 },
+ unicodeslot=0x3398,
+ },
+ [0x3399]={
+ adobename="fmsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE FM",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0066, 0x006D },
+ unicodeslot=0x3399,
+ },
+ [0x339A]={
+ adobename="nmsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE NM",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006E, 0x006D },
+ unicodeslot=0x339A,
+ },
+ [0x339B]={
+ adobename="mumsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MU M",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x03BC, 0x006D },
+ unicodeslot=0x339B,
+ },
+ [0x339C]={
+ adobename="squaremm",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MM",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x006D },
+ unicodeslot=0x339C,
+ },
+ [0x339D]={
+ adobename="squarecm",
+ category="so",
+ cjkwd="w",
+ description="SQUARE CM",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0063, 0x006D },
+ unicodeslot=0x339D,
+ },
+ [0x339E]={
+ adobename="squarekm",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KM",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x006D },
+ unicodeslot=0x339E,
+ },
+ [0x339F]={
+ adobename="mmsquaredsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MM SQUARED",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x006D, 0x00B2 },
+ unicodeslot=0x339F,
+ },
+ [0x33A0]={
+ adobename="cmsquaredsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE CM SQUARED",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0063, 0x006D, 0x00B2 },
+ unicodeslot=0x33A0,
+ },
+ [0x33A1]={
+ adobename="squaremsquared",
+ category="so",
+ cjkwd="w",
+ description="SQUARE M SQUARED",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x00B2 },
+ unicodeslot=0x33A1,
+ },
+ [0x33A2]={
+ adobename="kmsquaredsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KM SQUARED",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x006D, 0x00B2 },
+ unicodeslot=0x33A2,
+ },
+ [0x33A3]={
+ adobename="mmcubedsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MM CUBED",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x006D, 0x00B3 },
+ unicodeslot=0x33A3,
+ },
+ [0x33A4]={
+ adobename="cmcubedsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE CM CUBED",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0063, 0x006D, 0x00B3 },
+ unicodeslot=0x33A4,
+ },
+ [0x33A5]={
+ adobename="mcubedsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE M CUBED",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x00B3 },
+ unicodeslot=0x33A5,
+ },
+ [0x33A6]={
+ adobename="kmcubedsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KM CUBED",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x006D, 0x00B3 },
+ unicodeslot=0x33A6,
+ },
+ [0x33A7]={
+ adobename="moverssquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE M OVER S",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x2215, 0x0073 },
+ unicodeslot=0x33A7,
+ },
+ [0x33A8]={
+ adobename="moverssquaredsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE M OVER S SQUARED",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x2215, 0x0073, 0x00B2 },
+ unicodeslot=0x33A8,
+ },
+ [0x33A9]={
+ adobename="pasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE PA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0050, 0x0061 },
+ unicodeslot=0x33A9,
+ },
+ [0x33AA]={
+ adobename="kpasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KPA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x0050, 0x0061 },
+ unicodeslot=0x33AA,
+ },
+ [0x33AB]={
+ adobename="mpasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MPA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x004D, 0x0050, 0x0061 },
+ unicodeslot=0x33AB,
+ },
+ [0x33AC]={
+ adobename="gpasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE GPA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0047, 0x0050, 0x0061 },
+ unicodeslot=0x33AC,
+ },
+ [0x33AD]={
+ adobename="radsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE RAD",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0072, 0x0061, 0x0064 },
+ unicodeslot=0x33AD,
+ },
+ [0x33AE]={
+ adobename="radoverssquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE RAD OVER S",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0072, 0x0061, 0x0064, 0x2215, 0x0073 },
+ unicodeslot=0x33AE,
+ },
+ [0x33AF]={
+ adobename="radoverssquaredsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE RAD OVER S SQUARED",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0x00B2 },
+ unicodeslot=0x33AF,
+ },
+ [0x33B0]={
+ adobename="pssquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE PS",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0070, 0x0073 },
+ unicodeslot=0x33B0,
+ },
+ [0x33B1]={
+ adobename="nssquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE NS",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006E, 0x0073 },
+ unicodeslot=0x33B1,
+ },
+ [0x33B2]={
+ adobename="mussquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MU S",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x03BC, 0x0073 },
+ unicodeslot=0x33B2,
+ },
+ [0x33B3]={
+ adobename="mssquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MS",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x0073 },
+ unicodeslot=0x33B3,
+ },
+ [0x33B4]={
+ adobename="pvsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE PV",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0070, 0x0056 },
+ unicodeslot=0x33B4,
+ },
+ [0x33B5]={
+ adobename="nvsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE NV",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006E, 0x0056 },
+ unicodeslot=0x33B5,
+ },
+ [0x33B6]={
+ adobename="muvsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MU V",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x03BC, 0x0056 },
+ unicodeslot=0x33B6,
+ },
+ [0x33B7]={
+ adobename="mvsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MV",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x0056 },
+ unicodeslot=0x33B7,
+ },
+ [0x33B8]={
+ adobename="kvsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KV",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x0056 },
+ unicodeslot=0x33B8,
+ },
+ [0x33B9]={
+ adobename="mvmegasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MV MEGA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x004D, 0x0056 },
+ unicodeslot=0x33B9,
+ },
+ [0x33BA]={
+ adobename="pwsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE PW",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0070, 0x0057 },
+ unicodeslot=0x33BA,
+ },
+ [0x33BB]={
+ adobename="nwsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE NW",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006E, 0x0057 },
+ unicodeslot=0x33BB,
+ },
+ [0x33BC]={
+ adobename="muwsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MU W",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x03BC, 0x0057 },
+ unicodeslot=0x33BC,
+ },
+ [0x33BD]={
+ adobename="mwsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MW",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x0057 },
+ unicodeslot=0x33BD,
+ },
+ [0x33BE]={
+ adobename="kwsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KW",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x0057 },
+ unicodeslot=0x33BE,
+ },
+ [0x33BF]={
+ adobename="mwmegasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MW MEGA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x004D, 0x0057 },
+ unicodeslot=0x33BF,
+ },
+ [0x33C0]={
+ adobename="kohmsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE K OHM",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x03A9 },
+ unicodeslot=0x33C0,
+ },
+ [0x33C1]={
+ adobename="mohmsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE M OHM",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x004D, 0x03A9 },
+ unicodeslot=0x33C1,
+ },
+ [0x33C2]={
+ adobename="amsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE AM",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0061, 0x002E, 0x006D, 0x002E },
+ unicodeslot=0x33C2,
+ },
+ [0x33C3]={
+ adobename="bqsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE BQ",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0042, 0x0071 },
+ unicodeslot=0x33C3,
+ },
+ [0x33C4]={
+ adobename="squarecc",
+ category="so",
+ cjkwd="w",
+ description="SQUARE CC",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0063, 0x0063 },
+ unicodeslot=0x33C4,
+ },
+ [0x33C5]={
+ adobename="cdsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE CD",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0063, 0x0064 },
+ unicodeslot=0x33C5,
+ },
+ [0x33C6]={
+ adobename="coverkgsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE C OVER KG",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0043, 0x2215, 0x006B, 0x0067 },
+ unicodeslot=0x33C6,
+ },
+ [0x33C7]={
+ adobename="cosquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE CO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0043, 0x006F, 0x002E },
+ unicodeslot=0x33C7,
+ },
+ [0x33C8]={
+ adobename="dbsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE DB",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0064, 0x0042 },
+ unicodeslot=0x33C8,
+ },
+ [0x33C9]={
+ adobename="gysquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE GY",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0047, 0x0079 },
+ unicodeslot=0x33C9,
+ },
+ [0x33CA]={
+ adobename="hasquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE HA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0068, 0x0061 },
+ unicodeslot=0x33CA,
+ },
+ [0x33CB]={
+ adobename="HPsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE HP",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0048, 0x0050 },
+ unicodeslot=0x33CB,
+ },
+ [0x33CC]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE IN",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0069, 0x006E },
+ unicodeslot=0x33CC,
+ },
+ [0x33CD]={
+ adobename="KKsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KK",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x004B, 0x004B },
+ unicodeslot=0x33CD,
+ },
+ [0x33CE]={
+ adobename="squarekmcapital",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KM CAPITAL",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x004B, 0x004D },
+ unicodeslot=0x33CE,
+ },
+ [0x33CF]={
+ adobename="ktsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE KT",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006B, 0x0074 },
+ unicodeslot=0x33CF,
+ },
+ [0x33D0]={
+ adobename="lmsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE LM",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006C, 0x006D },
+ unicodeslot=0x33D0,
+ },
+ [0x33D1]={
+ adobename="squareln",
+ category="so",
+ cjkwd="w",
+ description="SQUARE LN",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006C, 0x006E },
+ unicodeslot=0x33D1,
+ },
+ [0x33D2]={
+ adobename="squarelog",
+ category="so",
+ cjkwd="w",
+ description="SQUARE LOG",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006C, 0x006F, 0x0067 },
+ unicodeslot=0x33D2,
+ },
+ [0x33D3]={
+ adobename="lxsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE LX",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006C, 0x0078 },
+ unicodeslot=0x33D3,
+ },
+ [0x33D4]={
+ adobename="mbsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MB SMALL",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x0062 },
+ unicodeslot=0x33D4,
+ },
+ [0x33D5]={
+ adobename="squaremil",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MIL",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x0069, 0x006C },
+ unicodeslot=0x33D5,
+ },
+ [0x33D6]={
+ adobename="molsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE MOL",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x006D, 0x006F, 0x006C },
+ unicodeslot=0x33D6,
+ },
+ [0x33D7]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE PH",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0050, 0x0048 },
+ unicodeslot=0x33D7,
+ },
+ [0x33D8]={
+ adobename="pmsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE PM",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0070, 0x002E, 0x006D, 0x002E },
+ unicodeslot=0x33D8,
+ },
+ [0x33D9]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE PPM",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0050, 0x0050, 0x004D },
+ unicodeslot=0x33D9,
+ },
+ [0x33DA]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE PR",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0050, 0x0052 },
+ unicodeslot=0x33DA,
+ },
+ [0x33DB]={
+ adobename="srsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE SR",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0073, 0x0072 },
+ unicodeslot=0x33DB,
+ },
+ [0x33DC]={
+ adobename="svsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE SV",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0053, 0x0076 },
+ unicodeslot=0x33DC,
+ },
+ [0x33DD]={
+ adobename="wbsquare",
+ category="so",
+ cjkwd="w",
+ description="SQUARE WB",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x0057, 0x0062 },
+ unicodeslot=0x33DD,
+ },
+ [0x33DE]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE V OVER M",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x0056, 0x2215, 0x006D },
+ unicodeslot=0x33DE,
+ },
+ [0x33DF]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE A OVER M",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x0041, 0x2215, 0x006D },
+ unicodeslot=0x33DF,
+ },
+ [0x33E0]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x65E5 },
+ unicodeslot=0x33E0,
+ },
+ [0x33E1]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x65E5 },
+ unicodeslot=0x33E1,
+ },
+ [0x33E2]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0033, 0x65E5 },
+ unicodeslot=0x33E2,
+ },
+ [0x33E3]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0034, 0x65E5 },
+ unicodeslot=0x33E3,
+ },
+ [0x33E4]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0035, 0x65E5 },
+ unicodeslot=0x33E4,
+ },
+ [0x33E5]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0036, 0x65E5 },
+ unicodeslot=0x33E5,
+ },
+ [0x33E6]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0037, 0x65E5 },
+ unicodeslot=0x33E6,
+ },
+ [0x33E7]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0038, 0x65E5 },
+ unicodeslot=0x33E7,
+ },
+ [0x33E8]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0039, 0x65E5 },
+ unicodeslot=0x33E8,
+ },
+ [0x33E9]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0030, 0x65E5 },
+ unicodeslot=0x33E9,
+ },
+ [0x33EA]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0031, 0x65E5 },
+ unicodeslot=0x33EA,
+ },
+ [0x33EB]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0032, 0x65E5 },
+ unicodeslot=0x33EB,
+ },
+ [0x33EC]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0033, 0x65E5 },
+ unicodeslot=0x33EC,
+ },
+ [0x33ED]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0034, 0x65E5 },
+ unicodeslot=0x33ED,
+ },
+ [0x33EE]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0035, 0x65E5 },
+ unicodeslot=0x33EE,
+ },
+ [0x33EF]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0036, 0x65E5 },
+ unicodeslot=0x33EF,
+ },
+ [0x33F0]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0037, 0x65E5 },
+ unicodeslot=0x33F0,
+ },
+ [0x33F1]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0038, 0x65E5 },
+ unicodeslot=0x33F1,
+ },
+ [0x33F2]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0031, 0x0039, 0x65E5 },
+ unicodeslot=0x33F2,
+ },
+ [0x33F3]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0030, 0x65E5 },
+ unicodeslot=0x33F3,
+ },
+ [0x33F4]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0031, 0x65E5 },
+ unicodeslot=0x33F4,
+ },
+ [0x33F5]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0032, 0x65E5 },
+ unicodeslot=0x33F5,
+ },
+ [0x33F6]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0033, 0x65E5 },
+ unicodeslot=0x33F6,
+ },
+ [0x33F7]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0034, 0x65E5 },
+ unicodeslot=0x33F7,
+ },
+ [0x33F8]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0035, 0x65E5 },
+ unicodeslot=0x33F8,
+ },
+ [0x33F9]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0036, 0x65E5 },
+ unicodeslot=0x33F9,
+ },
+ [0x33FA]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0037, 0x65E5 },
+ unicodeslot=0x33FA,
+ },
+ [0x33FB]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0038, 0x65E5 },
+ unicodeslot=0x33FB,
+ },
+ [0x33FC]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0032, 0x0039, 0x65E5 },
+ unicodeslot=0x33FC,
+ },
+ [0x33FD]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0033, 0x0030, 0x65E5 },
+ unicodeslot=0x33FD,
+ },
+ [0x33FE]={
+ category="so",
+ cjkwd="w",
+ description="IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x0033, 0x0031, 0x65E5 },
+ unicodeslot=0x33FE,
+ },
+ [0x33FF]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE GAL",
+ direction="on",
+ linebreak="id",
+ specials={ "square", 0x0067, 0x0061, 0x006C },
+ unicodeslot=0x33FF,
+ },
+ [0x4DC0]={
+ category="so",
+ description="HEXAGRAM FOR THE CREATIVE HEAVEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC0,
+ },
+ [0x4DC1]={
+ category="so",
+ description="HEXAGRAM FOR THE RECEPTIVE EARTH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC1,
+ },
+ [0x4DC2]={
+ category="so",
+ description="HEXAGRAM FOR DIFFICULTY AT THE BEGINNING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC2,
+ },
+ [0x4DC3]={
+ category="so",
+ description="HEXAGRAM FOR YOUTHFUL FOLLY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC3,
+ },
+ [0x4DC4]={
+ category="so",
+ description="HEXAGRAM FOR WAITING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC4,
+ },
+ [0x4DC5]={
+ category="so",
+ description="HEXAGRAM FOR CONFLICT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC5,
+ },
+ [0x4DC6]={
+ category="so",
+ description="HEXAGRAM FOR THE ARMY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC6,
+ },
+ [0x4DC7]={
+ category="so",
+ description="HEXAGRAM FOR HOLDING TOGETHER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC7,
+ },
+ [0x4DC8]={
+ category="so",
+ description="HEXAGRAM FOR SMALL TAMING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC8,
+ },
+ [0x4DC9]={
+ category="so",
+ description="HEXAGRAM FOR TREADING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DC9,
+ },
+ [0x4DCA]={
+ category="so",
+ description="HEXAGRAM FOR PEACE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DCA,
+ },
+ [0x4DCB]={
+ category="so",
+ description="HEXAGRAM FOR STANDSTILL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DCB,
+ },
+ [0x4DCC]={
+ category="so",
+ description="HEXAGRAM FOR FELLOWSHIP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DCC,
+ },
+ [0x4DCD]={
+ category="so",
+ description="HEXAGRAM FOR GREAT POSSESSION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DCD,
+ },
+ [0x4DCE]={
+ category="so",
+ description="HEXAGRAM FOR MODESTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DCE,
+ },
+ [0x4DCF]={
+ category="so",
+ description="HEXAGRAM FOR ENTHUSIASM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DCF,
+ },
+ [0x4DD0]={
+ category="so",
+ description="HEXAGRAM FOR FOLLOWING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD0,
+ },
+ [0x4DD1]={
+ category="so",
+ description="HEXAGRAM FOR WORK ON THE DECAYED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD1,
+ },
+ [0x4DD2]={
+ category="so",
+ description="HEXAGRAM FOR APPROACH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD2,
+ },
+ [0x4DD3]={
+ category="so",
+ description="HEXAGRAM FOR CONTEMPLATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD3,
+ },
+ [0x4DD4]={
+ category="so",
+ description="HEXAGRAM FOR BITING THROUGH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD4,
+ },
+ [0x4DD5]={
+ category="so",
+ description="HEXAGRAM FOR GRACE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD5,
+ },
+ [0x4DD6]={
+ category="so",
+ description="HEXAGRAM FOR SPLITTING APART",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD6,
+ },
+ [0x4DD7]={
+ category="so",
+ description="HEXAGRAM FOR RETURN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD7,
+ },
+ [0x4DD8]={
+ category="so",
+ description="HEXAGRAM FOR INNOCENCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD8,
+ },
+ [0x4DD9]={
+ category="so",
+ description="HEXAGRAM FOR GREAT TAMING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DD9,
+ },
+ [0x4DDA]={
+ category="so",
+ description="HEXAGRAM FOR MOUTH CORNERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DDA,
+ },
+ [0x4DDB]={
+ category="so",
+ description="HEXAGRAM FOR GREAT PREPONDERANCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DDB,
+ },
+ [0x4DDC]={
+ category="so",
+ description="HEXAGRAM FOR THE ABYSMAL WATER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DDC,
+ },
+ [0x4DDD]={
+ category="so",
+ description="HEXAGRAM FOR THE CLINGING FIRE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DDD,
+ },
+ [0x4DDE]={
+ category="so",
+ description="HEXAGRAM FOR INFLUENCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DDE,
+ },
+ [0x4DDF]={
+ category="so",
+ description="HEXAGRAM FOR DURATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DDF,
+ },
+ [0x4DE0]={
+ category="so",
+ description="HEXAGRAM FOR RETREAT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE0,
+ },
+ [0x4DE1]={
+ category="so",
+ description="HEXAGRAM FOR GREAT POWER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE1,
+ },
+ [0x4DE2]={
+ category="so",
+ description="HEXAGRAM FOR PROGRESS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE2,
+ },
+ [0x4DE3]={
+ category="so",
+ description="HEXAGRAM FOR DARKENING OF THE LIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE3,
+ },
+ [0x4DE4]={
+ category="so",
+ description="HEXAGRAM FOR THE FAMILY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE4,
+ },
+ [0x4DE5]={
+ category="so",
+ description="HEXAGRAM FOR OPPOSITION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE5,
+ },
+ [0x4DE6]={
+ category="so",
+ description="HEXAGRAM FOR OBSTRUCTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE6,
+ },
+ [0x4DE7]={
+ category="so",
+ description="HEXAGRAM FOR DELIVERANCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE7,
+ },
+ [0x4DE8]={
+ category="so",
+ description="HEXAGRAM FOR DECREASE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE8,
+ },
+ [0x4DE9]={
+ category="so",
+ description="HEXAGRAM FOR INCREASE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DE9,
+ },
+ [0x4DEA]={
+ category="so",
+ description="HEXAGRAM FOR BREAKTHROUGH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DEA,
+ },
+ [0x4DEB]={
+ category="so",
+ description="HEXAGRAM FOR COMING TO MEET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DEB,
+ },
+ [0x4DEC]={
+ category="so",
+ description="HEXAGRAM FOR GATHERING TOGETHER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DEC,
+ },
+ [0x4DED]={
+ category="so",
+ description="HEXAGRAM FOR PUSHING UPWARD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DED,
+ },
+ [0x4DEE]={
+ category="so",
+ description="HEXAGRAM FOR OPPRESSION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DEE,
+ },
+ [0x4DEF]={
+ category="so",
+ description="HEXAGRAM FOR THE WELL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DEF,
+ },
+ [0x4DF0]={
+ category="so",
+ description="HEXAGRAM FOR REVOLUTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF0,
+ },
+ [0x4DF1]={
+ category="so",
+ description="HEXAGRAM FOR THE CAULDRON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF1,
+ },
+ [0x4DF2]={
+ category="so",
+ description="HEXAGRAM FOR THE AROUSING THUNDER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF2,
+ },
+ [0x4DF3]={
+ category="so",
+ description="HEXAGRAM FOR THE KEEPING STILL MOUNTAIN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF3,
+ },
+ [0x4DF4]={
+ category="so",
+ description="HEXAGRAM FOR DEVELOPMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF4,
+ },
+ [0x4DF5]={
+ category="so",
+ description="HEXAGRAM FOR THE MARRYING MAIDEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF5,
+ },
+ [0x4DF6]={
+ category="so",
+ description="HEXAGRAM FOR ABUNDANCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF6,
+ },
+ [0x4DF7]={
+ category="so",
+ description="HEXAGRAM FOR THE WANDERER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF7,
+ },
+ [0x4DF8]={
+ category="so",
+ description="HEXAGRAM FOR THE GENTLE WIND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF8,
+ },
+ [0x4DF9]={
+ category="so",
+ description="HEXAGRAM FOR THE JOYOUS LAKE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DF9,
+ },
+ [0x4DFA]={
+ category="so",
+ description="HEXAGRAM FOR DISPERSION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DFA,
+ },
+ [0x4DFB]={
+ category="so",
+ description="HEXAGRAM FOR LIMITATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DFB,
+ },
+ [0x4DFC]={
+ category="so",
+ description="HEXAGRAM FOR INNER TRUTH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DFC,
+ },
+ [0x4DFD]={
+ category="so",
+ description="HEXAGRAM FOR SMALL PREPONDERANCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DFD,
+ },
+ [0x4DFE]={
+ category="so",
+ description="HEXAGRAM FOR AFTER COMPLETION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DFE,
+ },
+ [0x4DFF]={
+ category="so",
+ description="HEXAGRAM FOR BEFORE COMPLETION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x4DFF,
+ },
+ [0xA000]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE IT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA000,
+ },
+ [0xA001]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE IX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA001,
+ },
+ [0xA002]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE I",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA002,
+ },
+ [0xA003]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE IP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA003,
+ },
+ [0xA004]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE IET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA004,
+ },
+ [0xA005]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE IEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA005,
+ },
+ [0xA006]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE IE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA006,
+ },
+ [0xA007]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE IEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA007,
+ },
+ [0xA008]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE AT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA008,
+ },
+ [0xA009]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE AX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA009,
+ },
+ [0xA00A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE A",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA00A,
+ },
+ [0xA00B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE AP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA00B,
+ },
+ [0xA00C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE UOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA00C,
+ },
+ [0xA00D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE UO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA00D,
+ },
+ [0xA00E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE UOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA00E,
+ },
+ [0xA00F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE OT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA00F,
+ },
+ [0xA010]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE OX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA010,
+ },
+ [0xA011]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE O",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA011,
+ },
+ [0xA012]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE OP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA012,
+ },
+ [0xA013]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE EX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA013,
+ },
+ [0xA014]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE E",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA014,
+ },
+ [0xA015]={
+ category="lm",
+ cjkwd="w",
+ description="YI SYLLABLE WU",
+ direction="l",
+ linebreak="ns",
+ unicodeslot=0xA015,
+ },
+ [0xA016]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA016,
+ },
+ [0xA017]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA017,
+ },
+ [0xA018]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA018,
+ },
+ [0xA019]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA019,
+ },
+ [0xA01A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA01A,
+ },
+ [0xA01B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA01B,
+ },
+ [0xA01C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA01C,
+ },
+ [0xA01D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA01D,
+ },
+ [0xA01E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA01E,
+ },
+ [0xA01F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA01F,
+ },
+ [0xA020]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA020,
+ },
+ [0xA021]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA021,
+ },
+ [0xA022]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA022,
+ },
+ [0xA023]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA023,
+ },
+ [0xA024]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA024,
+ },
+ [0xA025]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA025,
+ },
+ [0xA026]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA026,
+ },
+ [0xA027]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA027,
+ },
+ [0xA028]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA028,
+ },
+ [0xA029]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA029,
+ },
+ [0xA02A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA02A,
+ },
+ [0xA02B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA02B,
+ },
+ [0xA02C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA02C,
+ },
+ [0xA02D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA02D,
+ },
+ [0xA02E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA02E,
+ },
+ [0xA02F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA02F,
+ },
+ [0xA030]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA030,
+ },
+ [0xA031]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA031,
+ },
+ [0xA032]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA032,
+ },
+ [0xA033]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA033,
+ },
+ [0xA034]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA034,
+ },
+ [0xA035]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA035,
+ },
+ [0xA036]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA036,
+ },
+ [0xA037]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA037,
+ },
+ [0xA038]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA038,
+ },
+ [0xA039]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA039,
+ },
+ [0xA03A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA03A,
+ },
+ [0xA03B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA03B,
+ },
+ [0xA03C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA03C,
+ },
+ [0xA03D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA03D,
+ },
+ [0xA03E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA03E,
+ },
+ [0xA03F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA03F,
+ },
+ [0xA040]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA040,
+ },
+ [0xA041]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA041,
+ },
+ [0xA042]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA042,
+ },
+ [0xA043]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA043,
+ },
+ [0xA044]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA044,
+ },
+ [0xA045]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA045,
+ },
+ [0xA046]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE POT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA046,
+ },
+ [0xA047]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE POX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA047,
+ },
+ [0xA048]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA048,
+ },
+ [0xA049]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE POP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA049,
+ },
+ [0xA04A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA04A,
+ },
+ [0xA04B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA04B,
+ },
+ [0xA04C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA04C,
+ },
+ [0xA04D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA04D,
+ },
+ [0xA04E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA04E,
+ },
+ [0xA04F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA04F,
+ },
+ [0xA050]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA050,
+ },
+ [0xA051]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA051,
+ },
+ [0xA052]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA052,
+ },
+ [0xA053]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA053,
+ },
+ [0xA054]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA054,
+ },
+ [0xA055]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE PYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA055,
+ },
+ [0xA056]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA056,
+ },
+ [0xA057]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA057,
+ },
+ [0xA058]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA058,
+ },
+ [0xA059]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA059,
+ },
+ [0xA05A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA05A,
+ },
+ [0xA05B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA05B,
+ },
+ [0xA05C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA05C,
+ },
+ [0xA05D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA05D,
+ },
+ [0xA05E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA05E,
+ },
+ [0xA05F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA05F,
+ },
+ [0xA060]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA060,
+ },
+ [0xA061]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA061,
+ },
+ [0xA062]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA062,
+ },
+ [0xA063]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA063,
+ },
+ [0xA064]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA064,
+ },
+ [0xA065]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA065,
+ },
+ [0xA066]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA066,
+ },
+ [0xA067]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA067,
+ },
+ [0xA068]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA068,
+ },
+ [0xA069]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA069,
+ },
+ [0xA06A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA06A,
+ },
+ [0xA06B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA06B,
+ },
+ [0xA06C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA06C,
+ },
+ [0xA06D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA06D,
+ },
+ [0xA06E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA06E,
+ },
+ [0xA06F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA06F,
+ },
+ [0xA070]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA070,
+ },
+ [0xA071]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA071,
+ },
+ [0xA072]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA072,
+ },
+ [0xA073]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA073,
+ },
+ [0xA074]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA074,
+ },
+ [0xA075]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE BBYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA075,
+ },
+ [0xA076]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA076,
+ },
+ [0xA077]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA077,
+ },
+ [0xA078]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA078,
+ },
+ [0xA079]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA079,
+ },
+ [0xA07A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA07A,
+ },
+ [0xA07B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA07B,
+ },
+ [0xA07C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA07C,
+ },
+ [0xA07D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA07D,
+ },
+ [0xA07E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA07E,
+ },
+ [0xA07F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA07F,
+ },
+ [0xA080]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA080,
+ },
+ [0xA081]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA081,
+ },
+ [0xA082]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA082,
+ },
+ [0xA083]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA083,
+ },
+ [0xA084]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA084,
+ },
+ [0xA085]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA085,
+ },
+ [0xA086]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA086,
+ },
+ [0xA087]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA087,
+ },
+ [0xA088]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA088,
+ },
+ [0xA089]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA089,
+ },
+ [0xA08A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA08A,
+ },
+ [0xA08B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA08B,
+ },
+ [0xA08C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA08C,
+ },
+ [0xA08D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA08D,
+ },
+ [0xA08E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA08E,
+ },
+ [0xA08F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA08F,
+ },
+ [0xA090]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NBYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA090,
+ },
+ [0xA091]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA091,
+ },
+ [0xA092]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA092,
+ },
+ [0xA093]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA093,
+ },
+ [0xA094]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA094,
+ },
+ [0xA095]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA095,
+ },
+ [0xA096]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA096,
+ },
+ [0xA097]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA097,
+ },
+ [0xA098]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA098,
+ },
+ [0xA099]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA099,
+ },
+ [0xA09A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA09A,
+ },
+ [0xA09B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA09B,
+ },
+ [0xA09C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA09C,
+ },
+ [0xA09D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA09D,
+ },
+ [0xA09E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA09E,
+ },
+ [0xA09F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA09F,
+ },
+ [0xA0A0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A0,
+ },
+ [0xA0A1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A1,
+ },
+ [0xA0A2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A2,
+ },
+ [0xA0A3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A3,
+ },
+ [0xA0A4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A4,
+ },
+ [0xA0A5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A5,
+ },
+ [0xA0A6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A6,
+ },
+ [0xA0A7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A7,
+ },
+ [0xA0A8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A8,
+ },
+ [0xA0A9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0A9,
+ },
+ [0xA0AA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0AA,
+ },
+ [0xA0AB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0AB,
+ },
+ [0xA0AC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0AC,
+ },
+ [0xA0AD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HMYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0AD,
+ },
+ [0xA0AE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0AE,
+ },
+ [0xA0AF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0AF,
+ },
+ [0xA0B0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B0,
+ },
+ [0xA0B1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B1,
+ },
+ [0xA0B2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B2,
+ },
+ [0xA0B3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B3,
+ },
+ [0xA0B4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B4,
+ },
+ [0xA0B5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B5,
+ },
+ [0xA0B6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B6,
+ },
+ [0xA0B7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B7,
+ },
+ [0xA0B8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B8,
+ },
+ [0xA0B9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MUOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0B9,
+ },
+ [0xA0BA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0BA,
+ },
+ [0xA0BB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0BB,
+ },
+ [0xA0BC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0BC,
+ },
+ [0xA0BD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0BD,
+ },
+ [0xA0BE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0BE,
+ },
+ [0xA0BF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0BF,
+ },
+ [0xA0C0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C0,
+ },
+ [0xA0C1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C1,
+ },
+ [0xA0C2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ME",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C2,
+ },
+ [0xA0C3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C3,
+ },
+ [0xA0C4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C4,
+ },
+ [0xA0C5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C5,
+ },
+ [0xA0C6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C6,
+ },
+ [0xA0C7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C7,
+ },
+ [0xA0C8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C8,
+ },
+ [0xA0C9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0C9,
+ },
+ [0xA0CA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0CA,
+ },
+ [0xA0CB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0CB,
+ },
+ [0xA0CC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0CC,
+ },
+ [0xA0CD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0CD,
+ },
+ [0xA0CE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0CE,
+ },
+ [0xA0CF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0CF,
+ },
+ [0xA0D0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D0,
+ },
+ [0xA0D1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D1,
+ },
+ [0xA0D2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D2,
+ },
+ [0xA0D3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D3,
+ },
+ [0xA0D4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D4,
+ },
+ [0xA0D5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D5,
+ },
+ [0xA0D6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D6,
+ },
+ [0xA0D7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D7,
+ },
+ [0xA0D8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D8,
+ },
+ [0xA0D9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0D9,
+ },
+ [0xA0DA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0DA,
+ },
+ [0xA0DB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0DB,
+ },
+ [0xA0DC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0DC,
+ },
+ [0xA0DD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0DD,
+ },
+ [0xA0DE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0DE,
+ },
+ [0xA0DF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0DF,
+ },
+ [0xA0E0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E0,
+ },
+ [0xA0E1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE FYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E1,
+ },
+ [0xA0E2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E2,
+ },
+ [0xA0E3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E3,
+ },
+ [0xA0E4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E4,
+ },
+ [0xA0E5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E5,
+ },
+ [0xA0E6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E6,
+ },
+ [0xA0E7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E7,
+ },
+ [0xA0E8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E8,
+ },
+ [0xA0E9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0E9,
+ },
+ [0xA0EA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0EA,
+ },
+ [0xA0EB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0EB,
+ },
+ [0xA0EC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0EC,
+ },
+ [0xA0ED]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0ED,
+ },
+ [0xA0EE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0EE,
+ },
+ [0xA0EF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0EF,
+ },
+ [0xA0F0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F0,
+ },
+ [0xA0F1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F1,
+ },
+ [0xA0F2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F2,
+ },
+ [0xA0F3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F3,
+ },
+ [0xA0F4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F4,
+ },
+ [0xA0F5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F5,
+ },
+ [0xA0F6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F6,
+ },
+ [0xA0F7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F7,
+ },
+ [0xA0F8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F8,
+ },
+ [0xA0F9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0F9,
+ },
+ [0xA0FA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0FA,
+ },
+ [0xA0FB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0FB,
+ },
+ [0xA0FC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0FC,
+ },
+ [0xA0FD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0FD,
+ },
+ [0xA0FE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0FE,
+ },
+ [0xA0FF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE VYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA0FF,
+ },
+ [0xA100]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA100,
+ },
+ [0xA101]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA101,
+ },
+ [0xA102]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA102,
+ },
+ [0xA103]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA103,
+ },
+ [0xA104]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA104,
+ },
+ [0xA105]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA105,
+ },
+ [0xA106]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA106,
+ },
+ [0xA107]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA107,
+ },
+ [0xA108]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA108,
+ },
+ [0xA109]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA109,
+ },
+ [0xA10A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA10A,
+ },
+ [0xA10B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA10B,
+ },
+ [0xA10C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA10C,
+ },
+ [0xA10D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA10D,
+ },
+ [0xA10E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA10E,
+ },
+ [0xA10F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA10F,
+ },
+ [0xA110]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA110,
+ },
+ [0xA111]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA111,
+ },
+ [0xA112]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA112,
+ },
+ [0xA113]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA113,
+ },
+ [0xA114]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA114,
+ },
+ [0xA115]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA115,
+ },
+ [0xA116]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA116,
+ },
+ [0xA117]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA117,
+ },
+ [0xA118]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA118,
+ },
+ [0xA119]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA119,
+ },
+ [0xA11A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA11A,
+ },
+ [0xA11B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA11B,
+ },
+ [0xA11C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA11C,
+ },
+ [0xA11D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA11D,
+ },
+ [0xA11E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA11E,
+ },
+ [0xA11F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA11F,
+ },
+ [0xA120]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA120,
+ },
+ [0xA121]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA121,
+ },
+ [0xA122]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA122,
+ },
+ [0xA123]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA123,
+ },
+ [0xA124]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA124,
+ },
+ [0xA125]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TUOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA125,
+ },
+ [0xA126]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA126,
+ },
+ [0xA127]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA127,
+ },
+ [0xA128]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA128,
+ },
+ [0xA129]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA129,
+ },
+ [0xA12A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA12A,
+ },
+ [0xA12B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA12B,
+ },
+ [0xA12C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA12C,
+ },
+ [0xA12D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA12D,
+ },
+ [0xA12E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA12E,
+ },
+ [0xA12F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA12F,
+ },
+ [0xA130]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA130,
+ },
+ [0xA131]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA131,
+ },
+ [0xA132]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA132,
+ },
+ [0xA133]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA133,
+ },
+ [0xA134]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA134,
+ },
+ [0xA135]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE TUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA135,
+ },
+ [0xA136]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA136,
+ },
+ [0xA137]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA137,
+ },
+ [0xA138]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA138,
+ },
+ [0xA139]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA139,
+ },
+ [0xA13A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA13A,
+ },
+ [0xA13B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA13B,
+ },
+ [0xA13C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA13C,
+ },
+ [0xA13D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA13D,
+ },
+ [0xA13E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA13E,
+ },
+ [0xA13F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA13F,
+ },
+ [0xA140]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA140,
+ },
+ [0xA141]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA141,
+ },
+ [0xA142]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA142,
+ },
+ [0xA143]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA143,
+ },
+ [0xA144]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA144,
+ },
+ [0xA145]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA145,
+ },
+ [0xA146]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA146,
+ },
+ [0xA147]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA147,
+ },
+ [0xA148]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA148,
+ },
+ [0xA149]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA149,
+ },
+ [0xA14A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA14A,
+ },
+ [0xA14B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA14B,
+ },
+ [0xA14C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA14C,
+ },
+ [0xA14D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA14D,
+ },
+ [0xA14E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA14E,
+ },
+ [0xA14F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA14F,
+ },
+ [0xA150]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE DDUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA150,
+ },
+ [0xA151]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA151,
+ },
+ [0xA152]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA152,
+ },
+ [0xA153]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA153,
+ },
+ [0xA154]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA154,
+ },
+ [0xA155]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA155,
+ },
+ [0xA156]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA156,
+ },
+ [0xA157]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA157,
+ },
+ [0xA158]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA158,
+ },
+ [0xA159]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA159,
+ },
+ [0xA15A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA15A,
+ },
+ [0xA15B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA15B,
+ },
+ [0xA15C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA15C,
+ },
+ [0xA15D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA15D,
+ },
+ [0xA15E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA15E,
+ },
+ [0xA15F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA15F,
+ },
+ [0xA160]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA160,
+ },
+ [0xA161]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA161,
+ },
+ [0xA162]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA162,
+ },
+ [0xA163]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA163,
+ },
+ [0xA164]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA164,
+ },
+ [0xA165]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA165,
+ },
+ [0xA166]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA166,
+ },
+ [0xA167]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NDUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA167,
+ },
+ [0xA168]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA168,
+ },
+ [0xA169]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA169,
+ },
+ [0xA16A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA16A,
+ },
+ [0xA16B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA16B,
+ },
+ [0xA16C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA16C,
+ },
+ [0xA16D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA16D,
+ },
+ [0xA16E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA16E,
+ },
+ [0xA16F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA16F,
+ },
+ [0xA170]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA170,
+ },
+ [0xA171]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA171,
+ },
+ [0xA172]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA172,
+ },
+ [0xA173]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA173,
+ },
+ [0xA174]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA174,
+ },
+ [0xA175]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA175,
+ },
+ [0xA176]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA176,
+ },
+ [0xA177]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA177,
+ },
+ [0xA178]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA178,
+ },
+ [0xA179]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA179,
+ },
+ [0xA17A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA17A,
+ },
+ [0xA17B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA17B,
+ },
+ [0xA17C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HNUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA17C,
+ },
+ [0xA17D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA17D,
+ },
+ [0xA17E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA17E,
+ },
+ [0xA17F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA17F,
+ },
+ [0xA180]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA180,
+ },
+ [0xA181]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA181,
+ },
+ [0xA182]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA182,
+ },
+ [0xA183]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA183,
+ },
+ [0xA184]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA184,
+ },
+ [0xA185]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA185,
+ },
+ [0xA186]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA186,
+ },
+ [0xA187]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA187,
+ },
+ [0xA188]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA188,
+ },
+ [0xA189]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA189,
+ },
+ [0xA18A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA18A,
+ },
+ [0xA18B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA18B,
+ },
+ [0xA18C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA18C,
+ },
+ [0xA18D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA18D,
+ },
+ [0xA18E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA18E,
+ },
+ [0xA18F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA18F,
+ },
+ [0xA190]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA190,
+ },
+ [0xA191]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA191,
+ },
+ [0xA192]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA192,
+ },
+ [0xA193]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA193,
+ },
+ [0xA194]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA194,
+ },
+ [0xA195]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA195,
+ },
+ [0xA196]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA196,
+ },
+ [0xA197]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA197,
+ },
+ [0xA198]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA198,
+ },
+ [0xA199]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA199,
+ },
+ [0xA19A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA19A,
+ },
+ [0xA19B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA19B,
+ },
+ [0xA19C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA19C,
+ },
+ [0xA19D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA19D,
+ },
+ [0xA19E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA19E,
+ },
+ [0xA19F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA19F,
+ },
+ [0xA1A0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A0,
+ },
+ [0xA1A1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A1,
+ },
+ [0xA1A2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A2,
+ },
+ [0xA1A3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A3,
+ },
+ [0xA1A4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A4,
+ },
+ [0xA1A5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A5,
+ },
+ [0xA1A6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A6,
+ },
+ [0xA1A7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A7,
+ },
+ [0xA1A8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A8,
+ },
+ [0xA1A9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1A9,
+ },
+ [0xA1AA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1AA,
+ },
+ [0xA1AB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1AB,
+ },
+ [0xA1AC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1AC,
+ },
+ [0xA1AD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1AD,
+ },
+ [0xA1AE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1AE,
+ },
+ [0xA1AF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1AF,
+ },
+ [0xA1B0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B0,
+ },
+ [0xA1B1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B1,
+ },
+ [0xA1B2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B2,
+ },
+ [0xA1B3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B3,
+ },
+ [0xA1B4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B4,
+ },
+ [0xA1B5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B5,
+ },
+ [0xA1B6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HLYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B6,
+ },
+ [0xA1B7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B7,
+ },
+ [0xA1B8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B8,
+ },
+ [0xA1B9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1B9,
+ },
+ [0xA1BA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1BA,
+ },
+ [0xA1BB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1BB,
+ },
+ [0xA1BC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1BC,
+ },
+ [0xA1BD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1BD,
+ },
+ [0xA1BE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1BE,
+ },
+ [0xA1BF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1BF,
+ },
+ [0xA1C0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C0,
+ },
+ [0xA1C1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C1,
+ },
+ [0xA1C2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C2,
+ },
+ [0xA1C3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LUOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C3,
+ },
+ [0xA1C4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C4,
+ },
+ [0xA1C5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C5,
+ },
+ [0xA1C6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C6,
+ },
+ [0xA1C7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C7,
+ },
+ [0xA1C8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C8,
+ },
+ [0xA1C9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1C9,
+ },
+ [0xA1CA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1CA,
+ },
+ [0xA1CB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1CB,
+ },
+ [0xA1CC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1CC,
+ },
+ [0xA1CD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1CD,
+ },
+ [0xA1CE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1CE,
+ },
+ [0xA1CF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1CF,
+ },
+ [0xA1D0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D0,
+ },
+ [0xA1D1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D1,
+ },
+ [0xA1D2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D2,
+ },
+ [0xA1D3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D3,
+ },
+ [0xA1D4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D4,
+ },
+ [0xA1D5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D5,
+ },
+ [0xA1D6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D6,
+ },
+ [0xA1D7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D7,
+ },
+ [0xA1D8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D8,
+ },
+ [0xA1D9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE LYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1D9,
+ },
+ [0xA1DA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1DA,
+ },
+ [0xA1DB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1DB,
+ },
+ [0xA1DC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1DC,
+ },
+ [0xA1DD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1DD,
+ },
+ [0xA1DE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1DE,
+ },
+ [0xA1DF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1DF,
+ },
+ [0xA1E0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E0,
+ },
+ [0xA1E1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E1,
+ },
+ [0xA1E2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E2,
+ },
+ [0xA1E3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E3,
+ },
+ [0xA1E4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E4,
+ },
+ [0xA1E5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E5,
+ },
+ [0xA1E6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GUOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E6,
+ },
+ [0xA1E7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E7,
+ },
+ [0xA1E8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E8,
+ },
+ [0xA1E9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1E9,
+ },
+ [0xA1EA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1EA,
+ },
+ [0xA1EB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1EB,
+ },
+ [0xA1EC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1EC,
+ },
+ [0xA1ED]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1ED,
+ },
+ [0xA1EE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1EE,
+ },
+ [0xA1EF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1EF,
+ },
+ [0xA1F0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F0,
+ },
+ [0xA1F1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F1,
+ },
+ [0xA1F2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F2,
+ },
+ [0xA1F3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F3,
+ },
+ [0xA1F4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F4,
+ },
+ [0xA1F5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F5,
+ },
+ [0xA1F6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F6,
+ },
+ [0xA1F7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F7,
+ },
+ [0xA1F8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F8,
+ },
+ [0xA1F9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1F9,
+ },
+ [0xA1FA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1FA,
+ },
+ [0xA1FB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1FB,
+ },
+ [0xA1FC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1FC,
+ },
+ [0xA1FD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1FD,
+ },
+ [0xA1FE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1FE,
+ },
+ [0xA1FF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA1FF,
+ },
+ [0xA200]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA200,
+ },
+ [0xA201]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA201,
+ },
+ [0xA202]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA202,
+ },
+ [0xA203]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA203,
+ },
+ [0xA204]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA204,
+ },
+ [0xA205]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA205,
+ },
+ [0xA206]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA206,
+ },
+ [0xA207]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA207,
+ },
+ [0xA208]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA208,
+ },
+ [0xA209]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA209,
+ },
+ [0xA20A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA20A,
+ },
+ [0xA20B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA20B,
+ },
+ [0xA20C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA20C,
+ },
+ [0xA20D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA20D,
+ },
+ [0xA20E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA20E,
+ },
+ [0xA20F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA20F,
+ },
+ [0xA210]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA210,
+ },
+ [0xA211]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA211,
+ },
+ [0xA212]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA212,
+ },
+ [0xA213]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE KUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA213,
+ },
+ [0xA214]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA214,
+ },
+ [0xA215]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA215,
+ },
+ [0xA216]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA216,
+ },
+ [0xA217]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA217,
+ },
+ [0xA218]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA218,
+ },
+ [0xA219]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA219,
+ },
+ [0xA21A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA21A,
+ },
+ [0xA21B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA21B,
+ },
+ [0xA21C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA21C,
+ },
+ [0xA21D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA21D,
+ },
+ [0xA21E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGUOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA21E,
+ },
+ [0xA21F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA21F,
+ },
+ [0xA220]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA220,
+ },
+ [0xA221]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA221,
+ },
+ [0xA222]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA222,
+ },
+ [0xA223]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA223,
+ },
+ [0xA224]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA224,
+ },
+ [0xA225]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA225,
+ },
+ [0xA226]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA226,
+ },
+ [0xA227]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA227,
+ },
+ [0xA228]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA228,
+ },
+ [0xA229]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA229,
+ },
+ [0xA22A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA22A,
+ },
+ [0xA22B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA22B,
+ },
+ [0xA22C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA22C,
+ },
+ [0xA22D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA22D,
+ },
+ [0xA22E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA22E,
+ },
+ [0xA22F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE GGUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA22F,
+ },
+ [0xA230]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA230,
+ },
+ [0xA231]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA231,
+ },
+ [0xA232]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA232,
+ },
+ [0xA233]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA233,
+ },
+ [0xA234]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA234,
+ },
+ [0xA235]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA235,
+ },
+ [0xA236]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA236,
+ },
+ [0xA237]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA237,
+ },
+ [0xA238]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA238,
+ },
+ [0xA239]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA239,
+ },
+ [0xA23A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA23A,
+ },
+ [0xA23B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA23B,
+ },
+ [0xA23C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA23C,
+ },
+ [0xA23D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA23D,
+ },
+ [0xA23E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA23E,
+ },
+ [0xA23F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA23F,
+ },
+ [0xA240]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA240,
+ },
+ [0xA241]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA241,
+ },
+ [0xA242]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA242,
+ },
+ [0xA243]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA243,
+ },
+ [0xA244]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA244,
+ },
+ [0xA245]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE MGUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA245,
+ },
+ [0xA246]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA246,
+ },
+ [0xA247]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA247,
+ },
+ [0xA248]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA248,
+ },
+ [0xA249]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA249,
+ },
+ [0xA24A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA24A,
+ },
+ [0xA24B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA24B,
+ },
+ [0xA24C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA24C,
+ },
+ [0xA24D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA24D,
+ },
+ [0xA24E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA24E,
+ },
+ [0xA24F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA24F,
+ },
+ [0xA250]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA250,
+ },
+ [0xA251]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA251,
+ },
+ [0xA252]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXUOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA252,
+ },
+ [0xA253]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA253,
+ },
+ [0xA254]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA254,
+ },
+ [0xA255]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA255,
+ },
+ [0xA256]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA256,
+ },
+ [0xA257]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA257,
+ },
+ [0xA258]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA258,
+ },
+ [0xA259]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA259,
+ },
+ [0xA25A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA25A,
+ },
+ [0xA25B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA25B,
+ },
+ [0xA25C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HXEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA25C,
+ },
+ [0xA25D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA25D,
+ },
+ [0xA25E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA25E,
+ },
+ [0xA25F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA25F,
+ },
+ [0xA260]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA260,
+ },
+ [0xA261]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA261,
+ },
+ [0xA262]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA262,
+ },
+ [0xA263]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA263,
+ },
+ [0xA264]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGUOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA264,
+ },
+ [0xA265]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA265,
+ },
+ [0xA266]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA266,
+ },
+ [0xA267]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA267,
+ },
+ [0xA268]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA268,
+ },
+ [0xA269]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA269,
+ },
+ [0xA26A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA26A,
+ },
+ [0xA26B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA26B,
+ },
+ [0xA26C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA26C,
+ },
+ [0xA26D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NGEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA26D,
+ },
+ [0xA26E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA26E,
+ },
+ [0xA26F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA26F,
+ },
+ [0xA270]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA270,
+ },
+ [0xA271]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA271,
+ },
+ [0xA272]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA272,
+ },
+ [0xA273]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA273,
+ },
+ [0xA274]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA274,
+ },
+ [0xA275]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HUOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA275,
+ },
+ [0xA276]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA276,
+ },
+ [0xA277]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA277,
+ },
+ [0xA278]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA278,
+ },
+ [0xA279]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA279,
+ },
+ [0xA27A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA27A,
+ },
+ [0xA27B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA27B,
+ },
+ [0xA27C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA27C,
+ },
+ [0xA27D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA27D,
+ },
+ [0xA27E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA27E,
+ },
+ [0xA27F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE HEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA27F,
+ },
+ [0xA280]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA280,
+ },
+ [0xA281]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA281,
+ },
+ [0xA282]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA282,
+ },
+ [0xA283]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA283,
+ },
+ [0xA284]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA284,
+ },
+ [0xA285]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA285,
+ },
+ [0xA286]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA286,
+ },
+ [0xA287]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA287,
+ },
+ [0xA288]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA288,
+ },
+ [0xA289]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA289,
+ },
+ [0xA28A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA28A,
+ },
+ [0xA28B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA28B,
+ },
+ [0xA28C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE WEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA28C,
+ },
+ [0xA28D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA28D,
+ },
+ [0xA28E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA28E,
+ },
+ [0xA28F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA28F,
+ },
+ [0xA290]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA290,
+ },
+ [0xA291]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA291,
+ },
+ [0xA292]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA292,
+ },
+ [0xA293]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA293,
+ },
+ [0xA294]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA294,
+ },
+ [0xA295]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA295,
+ },
+ [0xA296]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA296,
+ },
+ [0xA297]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA297,
+ },
+ [0xA298]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA298,
+ },
+ [0xA299]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA299,
+ },
+ [0xA29A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA29A,
+ },
+ [0xA29B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA29B,
+ },
+ [0xA29C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA29C,
+ },
+ [0xA29D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA29D,
+ },
+ [0xA29E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA29E,
+ },
+ [0xA29F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA29F,
+ },
+ [0xA2A0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A0,
+ },
+ [0xA2A1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A1,
+ },
+ [0xA2A2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A2,
+ },
+ [0xA2A3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A3,
+ },
+ [0xA2A4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A4,
+ },
+ [0xA2A5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A5,
+ },
+ [0xA2A6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A6,
+ },
+ [0xA2A7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A7,
+ },
+ [0xA2A8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A8,
+ },
+ [0xA2A9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2A9,
+ },
+ [0xA2AA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2AA,
+ },
+ [0xA2AB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2AB,
+ },
+ [0xA2AC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2AC,
+ },
+ [0xA2AD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2AD,
+ },
+ [0xA2AE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2AE,
+ },
+ [0xA2AF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2AF,
+ },
+ [0xA2B0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B0,
+ },
+ [0xA2B1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B1,
+ },
+ [0xA2B2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B2,
+ },
+ [0xA2B3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B3,
+ },
+ [0xA2B4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B4,
+ },
+ [0xA2B5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B5,
+ },
+ [0xA2B6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B6,
+ },
+ [0xA2B7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B7,
+ },
+ [0xA2B8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B8,
+ },
+ [0xA2B9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2B9,
+ },
+ [0xA2BA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2BA,
+ },
+ [0xA2BB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2BB,
+ },
+ [0xA2BC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2BC,
+ },
+ [0xA2BD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE COT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2BD,
+ },
+ [0xA2BE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE COX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2BE,
+ },
+ [0xA2BF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2BF,
+ },
+ [0xA2C0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE COP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C0,
+ },
+ [0xA2C1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C1,
+ },
+ [0xA2C2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C2,
+ },
+ [0xA2C3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C3,
+ },
+ [0xA2C4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C4,
+ },
+ [0xA2C5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C5,
+ },
+ [0xA2C6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C6,
+ },
+ [0xA2C7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C7,
+ },
+ [0xA2C8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C8,
+ },
+ [0xA2C9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2C9,
+ },
+ [0xA2CA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2CA,
+ },
+ [0xA2CB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2CB,
+ },
+ [0xA2CC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2CC,
+ },
+ [0xA2CD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2CD,
+ },
+ [0xA2CE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2CE,
+ },
+ [0xA2CF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2CF,
+ },
+ [0xA2D0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D0,
+ },
+ [0xA2D1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D1,
+ },
+ [0xA2D2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D2,
+ },
+ [0xA2D3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D3,
+ },
+ [0xA2D4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D4,
+ },
+ [0xA2D5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D5,
+ },
+ [0xA2D6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D6,
+ },
+ [0xA2D7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D7,
+ },
+ [0xA2D8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D8,
+ },
+ [0xA2D9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2D9,
+ },
+ [0xA2DA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2DA,
+ },
+ [0xA2DB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2DB,
+ },
+ [0xA2DC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2DC,
+ },
+ [0xA2DD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2DD,
+ },
+ [0xA2DE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2DE,
+ },
+ [0xA2DF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2DF,
+ },
+ [0xA2E0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E0,
+ },
+ [0xA2E1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E1,
+ },
+ [0xA2E2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E2,
+ },
+ [0xA2E3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E3,
+ },
+ [0xA2E4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E4,
+ },
+ [0xA2E5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E5,
+ },
+ [0xA2E6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E6,
+ },
+ [0xA2E7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E7,
+ },
+ [0xA2E8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E8,
+ },
+ [0xA2E9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2E9,
+ },
+ [0xA2EA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2EA,
+ },
+ [0xA2EB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2EB,
+ },
+ [0xA2EC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZZYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2EC,
+ },
+ [0xA2ED]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2ED,
+ },
+ [0xA2EE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2EE,
+ },
+ [0xA2EF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2EF,
+ },
+ [0xA2F0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F0,
+ },
+ [0xA2F1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F1,
+ },
+ [0xA2F2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F2,
+ },
+ [0xA2F3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F3,
+ },
+ [0xA2F4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F4,
+ },
+ [0xA2F5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F5,
+ },
+ [0xA2F6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F6,
+ },
+ [0xA2F7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F7,
+ },
+ [0xA2F8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F8,
+ },
+ [0xA2F9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2F9,
+ },
+ [0xA2FA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2FA,
+ },
+ [0xA2FB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2FB,
+ },
+ [0xA2FC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2FC,
+ },
+ [0xA2FD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2FD,
+ },
+ [0xA2FE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2FE,
+ },
+ [0xA2FF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA2FF,
+ },
+ [0xA300]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA300,
+ },
+ [0xA301]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA301,
+ },
+ [0xA302]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA302,
+ },
+ [0xA303]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA303,
+ },
+ [0xA304]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA304,
+ },
+ [0xA305]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA305,
+ },
+ [0xA306]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA306,
+ },
+ [0xA307]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA307,
+ },
+ [0xA308]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NZYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA308,
+ },
+ [0xA309]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA309,
+ },
+ [0xA30A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA30A,
+ },
+ [0xA30B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA30B,
+ },
+ [0xA30C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA30C,
+ },
+ [0xA30D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA30D,
+ },
+ [0xA30E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA30E,
+ },
+ [0xA30F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA30F,
+ },
+ [0xA310]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA310,
+ },
+ [0xA311]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA311,
+ },
+ [0xA312]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA312,
+ },
+ [0xA313]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA313,
+ },
+ [0xA314]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA314,
+ },
+ [0xA315]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA315,
+ },
+ [0xA316]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA316,
+ },
+ [0xA317]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA317,
+ },
+ [0xA318]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA318,
+ },
+ [0xA319]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA319,
+ },
+ [0xA31A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA31A,
+ },
+ [0xA31B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA31B,
+ },
+ [0xA31C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA31C,
+ },
+ [0xA31D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA31D,
+ },
+ [0xA31E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA31E,
+ },
+ [0xA31F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA31F,
+ },
+ [0xA320]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA320,
+ },
+ [0xA321]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA321,
+ },
+ [0xA322]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA322,
+ },
+ [0xA323]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA323,
+ },
+ [0xA324]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA324,
+ },
+ [0xA325]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA325,
+ },
+ [0xA326]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA326,
+ },
+ [0xA327]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA327,
+ },
+ [0xA328]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA328,
+ },
+ [0xA329]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA329,
+ },
+ [0xA32A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA32A,
+ },
+ [0xA32B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA32B,
+ },
+ [0xA32C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA32C,
+ },
+ [0xA32D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA32D,
+ },
+ [0xA32E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA32E,
+ },
+ [0xA32F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA32F,
+ },
+ [0xA330]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA330,
+ },
+ [0xA331]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA331,
+ },
+ [0xA332]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA332,
+ },
+ [0xA333]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA333,
+ },
+ [0xA334]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA334,
+ },
+ [0xA335]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA335,
+ },
+ [0xA336]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA336,
+ },
+ [0xA337]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA337,
+ },
+ [0xA338]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA338,
+ },
+ [0xA339]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA339,
+ },
+ [0xA33A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA33A,
+ },
+ [0xA33B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA33B,
+ },
+ [0xA33C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA33C,
+ },
+ [0xA33D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA33D,
+ },
+ [0xA33E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA33E,
+ },
+ [0xA33F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA33F,
+ },
+ [0xA340]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA340,
+ },
+ [0xA341]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA341,
+ },
+ [0xA342]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA342,
+ },
+ [0xA343]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA343,
+ },
+ [0xA344]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA344,
+ },
+ [0xA345]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SSYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA345,
+ },
+ [0xA346]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA346,
+ },
+ [0xA347]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA347,
+ },
+ [0xA348]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA348,
+ },
+ [0xA349]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA349,
+ },
+ [0xA34A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA34A,
+ },
+ [0xA34B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA34B,
+ },
+ [0xA34C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA34C,
+ },
+ [0xA34D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA34D,
+ },
+ [0xA34E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA34E,
+ },
+ [0xA34F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA34F,
+ },
+ [0xA350]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA350,
+ },
+ [0xA351]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA351,
+ },
+ [0xA352]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA352,
+ },
+ [0xA353]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA353,
+ },
+ [0xA354]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA354,
+ },
+ [0xA355]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA355,
+ },
+ [0xA356]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA356,
+ },
+ [0xA357]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA357,
+ },
+ [0xA358]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA358,
+ },
+ [0xA359]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA359,
+ },
+ [0xA35A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA35A,
+ },
+ [0xA35B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA35B,
+ },
+ [0xA35C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA35C,
+ },
+ [0xA35D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA35D,
+ },
+ [0xA35E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA35E,
+ },
+ [0xA35F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA35F,
+ },
+ [0xA360]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ZHYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA360,
+ },
+ [0xA361]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA361,
+ },
+ [0xA362]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA362,
+ },
+ [0xA363]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA363,
+ },
+ [0xA364]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA364,
+ },
+ [0xA365]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHUOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA365,
+ },
+ [0xA366]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA366,
+ },
+ [0xA367]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA367,
+ },
+ [0xA368]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA368,
+ },
+ [0xA369]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA369,
+ },
+ [0xA36A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA36A,
+ },
+ [0xA36B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA36B,
+ },
+ [0xA36C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA36C,
+ },
+ [0xA36D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA36D,
+ },
+ [0xA36E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA36E,
+ },
+ [0xA36F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA36F,
+ },
+ [0xA370]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA370,
+ },
+ [0xA371]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA371,
+ },
+ [0xA372]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA372,
+ },
+ [0xA373]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA373,
+ },
+ [0xA374]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA374,
+ },
+ [0xA375]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA375,
+ },
+ [0xA376]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA376,
+ },
+ [0xA377]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA377,
+ },
+ [0xA378]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA378,
+ },
+ [0xA379]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA379,
+ },
+ [0xA37A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA37A,
+ },
+ [0xA37B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE CHYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA37B,
+ },
+ [0xA37C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA37C,
+ },
+ [0xA37D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA37D,
+ },
+ [0xA37E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA37E,
+ },
+ [0xA37F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA37F,
+ },
+ [0xA380]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RROT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA380,
+ },
+ [0xA381]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RROX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA381,
+ },
+ [0xA382]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA382,
+ },
+ [0xA383]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RROP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA383,
+ },
+ [0xA384]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA384,
+ },
+ [0xA385]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RREX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA385,
+ },
+ [0xA386]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA386,
+ },
+ [0xA387]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RREP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA387,
+ },
+ [0xA388]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA388,
+ },
+ [0xA389]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA389,
+ },
+ [0xA38A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA38A,
+ },
+ [0xA38B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA38B,
+ },
+ [0xA38C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA38C,
+ },
+ [0xA38D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA38D,
+ },
+ [0xA38E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA38E,
+ },
+ [0xA38F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA38F,
+ },
+ [0xA390]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA390,
+ },
+ [0xA391]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA391,
+ },
+ [0xA392]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA392,
+ },
+ [0xA393]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RRYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA393,
+ },
+ [0xA394]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA394,
+ },
+ [0xA395]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA395,
+ },
+ [0xA396]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA396,
+ },
+ [0xA397]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA397,
+ },
+ [0xA398]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NROX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA398,
+ },
+ [0xA399]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA399,
+ },
+ [0xA39A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NROP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA39A,
+ },
+ [0xA39B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA39B,
+ },
+ [0xA39C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NREX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA39C,
+ },
+ [0xA39D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA39D,
+ },
+ [0xA39E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NREP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA39E,
+ },
+ [0xA39F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA39F,
+ },
+ [0xA3A0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A0,
+ },
+ [0xA3A1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A1,
+ },
+ [0xA3A2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A2,
+ },
+ [0xA3A3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A3,
+ },
+ [0xA3A4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A4,
+ },
+ [0xA3A5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A5,
+ },
+ [0xA3A6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A6,
+ },
+ [0xA3A7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A7,
+ },
+ [0xA3A8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A8,
+ },
+ [0xA3A9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3A9,
+ },
+ [0xA3AA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NRYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3AA,
+ },
+ [0xA3AB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3AB,
+ },
+ [0xA3AC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3AC,
+ },
+ [0xA3AD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3AD,
+ },
+ [0xA3AE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3AE,
+ },
+ [0xA3AF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3AF,
+ },
+ [0xA3B0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B0,
+ },
+ [0xA3B1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B1,
+ },
+ [0xA3B2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B2,
+ },
+ [0xA3B3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B3,
+ },
+ [0xA3B4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B4,
+ },
+ [0xA3B5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B5,
+ },
+ [0xA3B6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B6,
+ },
+ [0xA3B7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B7,
+ },
+ [0xA3B8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B8,
+ },
+ [0xA3B9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3B9,
+ },
+ [0xA3BA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3BA,
+ },
+ [0xA3BB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3BB,
+ },
+ [0xA3BC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3BC,
+ },
+ [0xA3BD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3BD,
+ },
+ [0xA3BE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3BE,
+ },
+ [0xA3BF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3BF,
+ },
+ [0xA3C0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C0,
+ },
+ [0xA3C1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C1,
+ },
+ [0xA3C2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C2,
+ },
+ [0xA3C3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C3,
+ },
+ [0xA3C4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C4,
+ },
+ [0xA3C5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE SHYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C5,
+ },
+ [0xA3C6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RAT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C6,
+ },
+ [0xA3C7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RAX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C7,
+ },
+ [0xA3C8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RA",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C8,
+ },
+ [0xA3C9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RAP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3C9,
+ },
+ [0xA3CA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3CA,
+ },
+ [0xA3CB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3CB,
+ },
+ [0xA3CC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3CC,
+ },
+ [0xA3CD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ROT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3CD,
+ },
+ [0xA3CE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ROX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3CE,
+ },
+ [0xA3CF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3CF,
+ },
+ [0xA3D0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE ROP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D0,
+ },
+ [0xA3D1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE REX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D1,
+ },
+ [0xA3D2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D2,
+ },
+ [0xA3D3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE REP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D3,
+ },
+ [0xA3D4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D4,
+ },
+ [0xA3D5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D5,
+ },
+ [0xA3D6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D6,
+ },
+ [0xA3D7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D7,
+ },
+ [0xA3D8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D8,
+ },
+ [0xA3D9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3D9,
+ },
+ [0xA3DA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3DA,
+ },
+ [0xA3DB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3DB,
+ },
+ [0xA3DC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3DC,
+ },
+ [0xA3DD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3DD,
+ },
+ [0xA3DE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3DE,
+ },
+ [0xA3DF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE RYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3DF,
+ },
+ [0xA3E0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E0,
+ },
+ [0xA3E1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E1,
+ },
+ [0xA3E2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E2,
+ },
+ [0xA3E3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E3,
+ },
+ [0xA3E4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E4,
+ },
+ [0xA3E5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E5,
+ },
+ [0xA3E6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E6,
+ },
+ [0xA3E7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E7,
+ },
+ [0xA3E8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JUOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E8,
+ },
+ [0xA3E9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3E9,
+ },
+ [0xA3EA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3EA,
+ },
+ [0xA3EB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3EB,
+ },
+ [0xA3EC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3EC,
+ },
+ [0xA3ED]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3ED,
+ },
+ [0xA3EE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3EE,
+ },
+ [0xA3EF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3EF,
+ },
+ [0xA3F0]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F0,
+ },
+ [0xA3F1]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F1,
+ },
+ [0xA3F2]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F2,
+ },
+ [0xA3F3]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F3,
+ },
+ [0xA3F4]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F4,
+ },
+ [0xA3F5]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F5,
+ },
+ [0xA3F6]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F6,
+ },
+ [0xA3F7]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F7,
+ },
+ [0xA3F8]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F8,
+ },
+ [0xA3F9]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3F9,
+ },
+ [0xA3FA]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3FA,
+ },
+ [0xA3FB]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3FB,
+ },
+ [0xA3FC]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3FC,
+ },
+ [0xA3FD]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3FD,
+ },
+ [0xA3FE]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3FE,
+ },
+ [0xA3FF]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA3FF,
+ },
+ [0xA400]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA400,
+ },
+ [0xA401]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA401,
+ },
+ [0xA402]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA402,
+ },
+ [0xA403]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA403,
+ },
+ [0xA404]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QUOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA404,
+ },
+ [0xA405]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA405,
+ },
+ [0xA406]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA406,
+ },
+ [0xA407]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA407,
+ },
+ [0xA408]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA408,
+ },
+ [0xA409]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA409,
+ },
+ [0xA40A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA40A,
+ },
+ [0xA40B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA40B,
+ },
+ [0xA40C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA40C,
+ },
+ [0xA40D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA40D,
+ },
+ [0xA40E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA40E,
+ },
+ [0xA40F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA40F,
+ },
+ [0xA410]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA410,
+ },
+ [0xA411]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA411,
+ },
+ [0xA412]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA412,
+ },
+ [0xA413]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA413,
+ },
+ [0xA414]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA414,
+ },
+ [0xA415]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA415,
+ },
+ [0xA416]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA416,
+ },
+ [0xA417]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE QYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA417,
+ },
+ [0xA418]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA418,
+ },
+ [0xA419]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA419,
+ },
+ [0xA41A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA41A,
+ },
+ [0xA41B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA41B,
+ },
+ [0xA41C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA41C,
+ },
+ [0xA41D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA41D,
+ },
+ [0xA41E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA41E,
+ },
+ [0xA41F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA41F,
+ },
+ [0xA420]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA420,
+ },
+ [0xA421]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA421,
+ },
+ [0xA422]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA422,
+ },
+ [0xA423]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA423,
+ },
+ [0xA424]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA424,
+ },
+ [0xA425]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA425,
+ },
+ [0xA426]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA426,
+ },
+ [0xA427]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA427,
+ },
+ [0xA428]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA428,
+ },
+ [0xA429]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA429,
+ },
+ [0xA42A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA42A,
+ },
+ [0xA42B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA42B,
+ },
+ [0xA42C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA42C,
+ },
+ [0xA42D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA42D,
+ },
+ [0xA42E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA42E,
+ },
+ [0xA42F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA42F,
+ },
+ [0xA430]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE JJYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA430,
+ },
+ [0xA431]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA431,
+ },
+ [0xA432]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA432,
+ },
+ [0xA433]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA433,
+ },
+ [0xA434]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA434,
+ },
+ [0xA435]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA435,
+ },
+ [0xA436]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA436,
+ },
+ [0xA437]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA437,
+ },
+ [0xA438]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA438,
+ },
+ [0xA439]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA439,
+ },
+ [0xA43A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA43A,
+ },
+ [0xA43B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA43B,
+ },
+ [0xA43C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA43C,
+ },
+ [0xA43D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA43D,
+ },
+ [0xA43E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA43E,
+ },
+ [0xA43F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA43F,
+ },
+ [0xA440]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA440,
+ },
+ [0xA441]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA441,
+ },
+ [0xA442]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA442,
+ },
+ [0xA443]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA443,
+ },
+ [0xA444]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA444,
+ },
+ [0xA445]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA445,
+ },
+ [0xA446]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA446,
+ },
+ [0xA447]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA447,
+ },
+ [0xA448]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA448,
+ },
+ [0xA449]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NJYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA449,
+ },
+ [0xA44A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA44A,
+ },
+ [0xA44B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA44B,
+ },
+ [0xA44C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA44C,
+ },
+ [0xA44D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA44D,
+ },
+ [0xA44E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA44E,
+ },
+ [0xA44F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA44F,
+ },
+ [0xA450]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA450,
+ },
+ [0xA451]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA451,
+ },
+ [0xA452]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA452,
+ },
+ [0xA453]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA453,
+ },
+ [0xA454]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA454,
+ },
+ [0xA455]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA455,
+ },
+ [0xA456]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA456,
+ },
+ [0xA457]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA457,
+ },
+ [0xA458]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA458,
+ },
+ [0xA459]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA459,
+ },
+ [0xA45A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA45A,
+ },
+ [0xA45B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA45B,
+ },
+ [0xA45C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE NYUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA45C,
+ },
+ [0xA45D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA45D,
+ },
+ [0xA45E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA45E,
+ },
+ [0xA45F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA45F,
+ },
+ [0xA460]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA460,
+ },
+ [0xA461]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA461,
+ },
+ [0xA462]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA462,
+ },
+ [0xA463]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA463,
+ },
+ [0xA464]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA464,
+ },
+ [0xA465]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA465,
+ },
+ [0xA466]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA466,
+ },
+ [0xA467]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA467,
+ },
+ [0xA468]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA468,
+ },
+ [0xA469]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA469,
+ },
+ [0xA46A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA46A,
+ },
+ [0xA46B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA46B,
+ },
+ [0xA46C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA46C,
+ },
+ [0xA46D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA46D,
+ },
+ [0xA46E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA46E,
+ },
+ [0xA46F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA46F,
+ },
+ [0xA470]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE XYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA470,
+ },
+ [0xA471]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YIT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA471,
+ },
+ [0xA472]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YIX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA472,
+ },
+ [0xA473]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YI",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA473,
+ },
+ [0xA474]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YIP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA474,
+ },
+ [0xA475]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YIET",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA475,
+ },
+ [0xA476]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YIEX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA476,
+ },
+ [0xA477]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YIE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA477,
+ },
+ [0xA478]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YIEP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA478,
+ },
+ [0xA479]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YUOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA479,
+ },
+ [0xA47A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YUOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA47A,
+ },
+ [0xA47B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YUO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA47B,
+ },
+ [0xA47C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YUOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA47C,
+ },
+ [0xA47D]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YOT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA47D,
+ },
+ [0xA47E]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YOX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA47E,
+ },
+ [0xA47F]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YO",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA47F,
+ },
+ [0xA480]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YOP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA480,
+ },
+ [0xA481]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YUT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA481,
+ },
+ [0xA482]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YUX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA482,
+ },
+ [0xA483]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YU",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA483,
+ },
+ [0xA484]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YUP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA484,
+ },
+ [0xA485]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YURX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA485,
+ },
+ [0xA486]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YUR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA486,
+ },
+ [0xA487]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YYT",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA487,
+ },
+ [0xA488]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YYX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA488,
+ },
+ [0xA489]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YY",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA489,
+ },
+ [0xA48A]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YYP",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA48A,
+ },
+ [0xA48B]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YYRX",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA48B,
+ },
+ [0xA48C]={
+ category="lo",
+ cjkwd="w",
+ description="YI SYLLABLE YYR",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xA48C,
+ },
+ [0xA490]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL QOT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA490,
+ },
+ [0xA491]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL LI",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA491,
+ },
+ [0xA492]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL KIT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA492,
+ },
+ [0xA493]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL NYIP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA493,
+ },
+ [0xA494]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL CYP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA494,
+ },
+ [0xA495]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL SSI",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA495,
+ },
+ [0xA496]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL GGOP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA496,
+ },
+ [0xA497]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL GEP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA497,
+ },
+ [0xA498]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL MI",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA498,
+ },
+ [0xA499]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL HXIT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA499,
+ },
+ [0xA49A]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL LYR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA49A,
+ },
+ [0xA49B]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL BBUT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA49B,
+ },
+ [0xA49C]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL MOP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA49C,
+ },
+ [0xA49D]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL YO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA49D,
+ },
+ [0xA49E]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL PUT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA49E,
+ },
+ [0xA49F]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL HXUO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA49F,
+ },
+ [0xA4A0]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL TAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A0,
+ },
+ [0xA4A1]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL GA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A1,
+ },
+ [0xA4A2]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL ZUP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A2,
+ },
+ [0xA4A3]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL CYT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A3,
+ },
+ [0xA4A4]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL DDUR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A4,
+ },
+ [0xA4A5]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL BUR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A5,
+ },
+ [0xA4A6]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL GGUO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A6,
+ },
+ [0xA4A7]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL NYOP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A7,
+ },
+ [0xA4A8]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL TU",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A8,
+ },
+ [0xA4A9]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL OP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4A9,
+ },
+ [0xA4AA]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL JJUT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4AA,
+ },
+ [0xA4AB]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL ZOT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4AB,
+ },
+ [0xA4AC]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL PYT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4AC,
+ },
+ [0xA4AD]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL HMO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4AD,
+ },
+ [0xA4AE]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL YIT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4AE,
+ },
+ [0xA4AF]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL VUR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4AF,
+ },
+ [0xA4B0]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL SHY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B0,
+ },
+ [0xA4B1]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL VEP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B1,
+ },
+ [0xA4B2]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL ZA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B2,
+ },
+ [0xA4B3]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL JO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B3,
+ },
+ [0xA4B4]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL NZUP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B4,
+ },
+ [0xA4B5]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL JJY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B5,
+ },
+ [0xA4B6]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL GOT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B6,
+ },
+ [0xA4B7]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL JJIE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B7,
+ },
+ [0xA4B8]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL WO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B8,
+ },
+ [0xA4B9]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL DU",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4B9,
+ },
+ [0xA4BA]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL SHUR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4BA,
+ },
+ [0xA4BB]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL LIE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4BB,
+ },
+ [0xA4BC]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL CY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4BC,
+ },
+ [0xA4BD]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL CUOP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4BD,
+ },
+ [0xA4BE]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL CIP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4BE,
+ },
+ [0xA4BF]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL HXOP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4BF,
+ },
+ [0xA4C0]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL SHAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C0,
+ },
+ [0xA4C1]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL ZUR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C1,
+ },
+ [0xA4C2]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL SHOP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C2,
+ },
+ [0xA4C3]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL CHE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C3,
+ },
+ [0xA4C4]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL ZZIET",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C4,
+ },
+ [0xA4C5]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL NBIE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C5,
+ },
+ [0xA4C6]={
+ category="so",
+ cjkwd="w",
+ description="YI RADICAL KE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xA4C6,
+ },
+ [0xA4D0]={
+ category="lo",
+ description="LISU LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D0,
+ },
+ [0xA4D1]={
+ category="lo",
+ description="LISU LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D1,
+ },
+ [0xA4D2]={
+ category="lo",
+ description="LISU LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D2,
+ },
+ [0xA4D3]={
+ category="lo",
+ description="LISU LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D3,
+ },
+ [0xA4D4]={
+ category="lo",
+ description="LISU LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D4,
+ },
+ [0xA4D5]={
+ category="lo",
+ description="LISU LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D5,
+ },
+ [0xA4D6]={
+ category="lo",
+ description="LISU LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D6,
+ },
+ [0xA4D7]={
+ category="lo",
+ description="LISU LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D7,
+ },
+ [0xA4D8]={
+ category="lo",
+ description="LISU LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D8,
+ },
+ [0xA4D9]={
+ category="lo",
+ description="LISU LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4D9,
+ },
+ [0xA4DA]={
+ category="lo",
+ description="LISU LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4DA,
+ },
+ [0xA4DB]={
+ category="lo",
+ description="LISU LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4DB,
+ },
+ [0xA4DC]={
+ category="lo",
+ description="LISU LETTER DZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4DC,
+ },
+ [0xA4DD]={
+ category="lo",
+ description="LISU LETTER TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4DD,
+ },
+ [0xA4DE]={
+ category="lo",
+ description="LISU LETTER TSHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4DE,
+ },
+ [0xA4DF]={
+ category="lo",
+ description="LISU LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4DF,
+ },
+ [0xA4E0]={
+ category="lo",
+ description="LISU LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E0,
+ },
+ [0xA4E1]={
+ category="lo",
+ description="LISU LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E1,
+ },
+ [0xA4E2]={
+ category="lo",
+ description="LISU LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E2,
+ },
+ [0xA4E3]={
+ category="lo",
+ description="LISU LETTER ZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E3,
+ },
+ [0xA4E4]={
+ category="lo",
+ description="LISU LETTER ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E4,
+ },
+ [0xA4E5]={
+ category="lo",
+ description="LISU LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E5,
+ },
+ [0xA4E6]={
+ category="lo",
+ description="LISU LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E6,
+ },
+ [0xA4E7]={
+ category="lo",
+ description="LISU LETTER XA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E7,
+ },
+ [0xA4E8]={
+ category="lo",
+ description="LISU LETTER HHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E8,
+ },
+ [0xA4E9]={
+ category="lo",
+ description="LISU LETTER FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4E9,
+ },
+ [0xA4EA]={
+ category="lo",
+ description="LISU LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4EA,
+ },
+ [0xA4EB]={
+ category="lo",
+ description="LISU LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4EB,
+ },
+ [0xA4EC]={
+ category="lo",
+ description="LISU LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4EC,
+ },
+ [0xA4ED]={
+ category="lo",
+ description="LISU LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4ED,
+ },
+ [0xA4EE]={
+ category="lo",
+ description="LISU LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4EE,
+ },
+ [0xA4EF]={
+ category="lo",
+ description="LISU LETTER AE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4EF,
+ },
+ [0xA4F0]={
+ category="lo",
+ description="LISU LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F0,
+ },
+ [0xA4F1]={
+ category="lo",
+ description="LISU LETTER EU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F1,
+ },
+ [0xA4F2]={
+ category="lo",
+ description="LISU LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F2,
+ },
+ [0xA4F3]={
+ category="lo",
+ description="LISU LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F3,
+ },
+ [0xA4F4]={
+ category="lo",
+ description="LISU LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F4,
+ },
+ [0xA4F5]={
+ category="lo",
+ description="LISU LETTER UE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F5,
+ },
+ [0xA4F6]={
+ category="lo",
+ description="LISU LETTER UH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F6,
+ },
+ [0xA4F7]={
+ category="lo",
+ description="LISU LETTER OE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F7,
+ },
+ [0xA4F8]={
+ category="lm",
+ description="LISU LETTER TONE MYA TI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F8,
+ },
+ [0xA4F9]={
+ category="lm",
+ description="LISU LETTER TONE NA PO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4F9,
+ },
+ [0xA4FA]={
+ category="lm",
+ description="LISU LETTER TONE MYA CYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4FA,
+ },
+ [0xA4FB]={
+ category="lm",
+ description="LISU LETTER TONE MYA BO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4FB,
+ },
+ [0xA4FC]={
+ category="lm",
+ description="LISU LETTER TONE MYA NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4FC,
+ },
+ [0xA4FD]={
+ category="lm",
+ description="LISU LETTER TONE MYA JEU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA4FD,
+ },
+ [0xA4FE]={
+ category="po",
+ description="LISU PUNCTUATION COMMA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA4FE,
+ },
+ [0xA4FF]={
+ category="po",
+ description="LISU PUNCTUATION FULL STOP",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA4FF,
+ },
+ [0xA500]={
+ category="lo",
+ description="VAI SYLLABLE EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA500,
+ },
+ [0xA501]={
+ category="lo",
+ description="VAI SYLLABLE EEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA501,
+ },
+ [0xA502]={
+ category="lo",
+ description="VAI SYLLABLE HEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA502,
+ },
+ [0xA503]={
+ category="lo",
+ description="VAI SYLLABLE WEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA503,
+ },
+ [0xA504]={
+ category="lo",
+ description="VAI SYLLABLE WEEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA504,
+ },
+ [0xA505]={
+ category="lo",
+ description="VAI SYLLABLE PEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA505,
+ },
+ [0xA506]={
+ category="lo",
+ description="VAI SYLLABLE BHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA506,
+ },
+ [0xA507]={
+ category="lo",
+ description="VAI SYLLABLE BEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA507,
+ },
+ [0xA508]={
+ category="lo",
+ description="VAI SYLLABLE MBEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA508,
+ },
+ [0xA509]={
+ category="lo",
+ description="VAI SYLLABLE KPEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA509,
+ },
+ [0xA50A]={
+ category="lo",
+ description="VAI SYLLABLE MGBEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA50A,
+ },
+ [0xA50B]={
+ category="lo",
+ description="VAI SYLLABLE GBEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA50B,
+ },
+ [0xA50C]={
+ category="lo",
+ description="VAI SYLLABLE FEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA50C,
+ },
+ [0xA50D]={
+ category="lo",
+ description="VAI SYLLABLE VEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA50D,
+ },
+ [0xA50E]={
+ category="lo",
+ description="VAI SYLLABLE TEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA50E,
+ },
+ [0xA50F]={
+ category="lo",
+ description="VAI SYLLABLE THEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA50F,
+ },
+ [0xA510]={
+ category="lo",
+ description="VAI SYLLABLE DHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA510,
+ },
+ [0xA511]={
+ category="lo",
+ description="VAI SYLLABLE DHHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA511,
+ },
+ [0xA512]={
+ category="lo",
+ description="VAI SYLLABLE LEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA512,
+ },
+ [0xA513]={
+ category="lo",
+ description="VAI SYLLABLE REE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA513,
+ },
+ [0xA514]={
+ category="lo",
+ description="VAI SYLLABLE DEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA514,
+ },
+ [0xA515]={
+ category="lo",
+ description="VAI SYLLABLE NDEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA515,
+ },
+ [0xA516]={
+ category="lo",
+ description="VAI SYLLABLE SEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA516,
+ },
+ [0xA517]={
+ category="lo",
+ description="VAI SYLLABLE SHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA517,
+ },
+ [0xA518]={
+ category="lo",
+ description="VAI SYLLABLE ZEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA518,
+ },
+ [0xA519]={
+ category="lo",
+ description="VAI SYLLABLE ZHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA519,
+ },
+ [0xA51A]={
+ category="lo",
+ description="VAI SYLLABLE CEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA51A,
+ },
+ [0xA51B]={
+ category="lo",
+ description="VAI SYLLABLE JEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA51B,
+ },
+ [0xA51C]={
+ category="lo",
+ description="VAI SYLLABLE NJEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA51C,
+ },
+ [0xA51D]={
+ category="lo",
+ description="VAI SYLLABLE YEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA51D,
+ },
+ [0xA51E]={
+ category="lo",
+ description="VAI SYLLABLE KEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA51E,
+ },
+ [0xA51F]={
+ category="lo",
+ description="VAI SYLLABLE NGGEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA51F,
+ },
+ [0xA520]={
+ category="lo",
+ description="VAI SYLLABLE GEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA520,
+ },
+ [0xA521]={
+ category="lo",
+ description="VAI SYLLABLE MEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA521,
+ },
+ [0xA522]={
+ category="lo",
+ description="VAI SYLLABLE NEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA522,
+ },
+ [0xA523]={
+ category="lo",
+ description="VAI SYLLABLE NYEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA523,
+ },
+ [0xA524]={
+ category="lo",
+ description="VAI SYLLABLE I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA524,
+ },
+ [0xA525]={
+ category="lo",
+ description="VAI SYLLABLE IN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA525,
+ },
+ [0xA526]={
+ category="lo",
+ description="VAI SYLLABLE HI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA526,
+ },
+ [0xA527]={
+ category="lo",
+ description="VAI SYLLABLE HIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA527,
+ },
+ [0xA528]={
+ category="lo",
+ description="VAI SYLLABLE WI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA528,
+ },
+ [0xA529]={
+ category="lo",
+ description="VAI SYLLABLE WIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA529,
+ },
+ [0xA52A]={
+ category="lo",
+ description="VAI SYLLABLE PI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA52A,
+ },
+ [0xA52B]={
+ category="lo",
+ description="VAI SYLLABLE BHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA52B,
+ },
+ [0xA52C]={
+ category="lo",
+ description="VAI SYLLABLE BI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA52C,
+ },
+ [0xA52D]={
+ category="lo",
+ description="VAI SYLLABLE MBI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA52D,
+ },
+ [0xA52E]={
+ category="lo",
+ description="VAI SYLLABLE KPI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA52E,
+ },
+ [0xA52F]={
+ category="lo",
+ description="VAI SYLLABLE MGBI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA52F,
+ },
+ [0xA530]={
+ category="lo",
+ description="VAI SYLLABLE GBI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA530,
+ },
+ [0xA531]={
+ category="lo",
+ description="VAI SYLLABLE FI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA531,
+ },
+ [0xA532]={
+ category="lo",
+ description="VAI SYLLABLE VI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA532,
+ },
+ [0xA533]={
+ category="lo",
+ description="VAI SYLLABLE TI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA533,
+ },
+ [0xA534]={
+ category="lo",
+ description="VAI SYLLABLE THI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA534,
+ },
+ [0xA535]={
+ category="lo",
+ description="VAI SYLLABLE DHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA535,
+ },
+ [0xA536]={
+ category="lo",
+ description="VAI SYLLABLE DHHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA536,
+ },
+ [0xA537]={
+ category="lo",
+ description="VAI SYLLABLE LI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA537,
+ },
+ [0xA538]={
+ category="lo",
+ description="VAI SYLLABLE RI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA538,
+ },
+ [0xA539]={
+ category="lo",
+ description="VAI SYLLABLE DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA539,
+ },
+ [0xA53A]={
+ category="lo",
+ description="VAI SYLLABLE NDI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA53A,
+ },
+ [0xA53B]={
+ category="lo",
+ description="VAI SYLLABLE SI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA53B,
+ },
+ [0xA53C]={
+ category="lo",
+ description="VAI SYLLABLE SHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA53C,
+ },
+ [0xA53D]={
+ category="lo",
+ description="VAI SYLLABLE ZI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA53D,
+ },
+ [0xA53E]={
+ category="lo",
+ description="VAI SYLLABLE ZHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA53E,
+ },
+ [0xA53F]={
+ category="lo",
+ description="VAI SYLLABLE CI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA53F,
+ },
+ [0xA540]={
+ category="lo",
+ description="VAI SYLLABLE JI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA540,
+ },
+ [0xA541]={
+ category="lo",
+ description="VAI SYLLABLE NJI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA541,
+ },
+ [0xA542]={
+ category="lo",
+ description="VAI SYLLABLE YI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA542,
+ },
+ [0xA543]={
+ category="lo",
+ description="VAI SYLLABLE KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA543,
+ },
+ [0xA544]={
+ category="lo",
+ description="VAI SYLLABLE NGGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA544,
+ },
+ [0xA545]={
+ category="lo",
+ description="VAI SYLLABLE GI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA545,
+ },
+ [0xA546]={
+ category="lo",
+ description="VAI SYLLABLE MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA546,
+ },
+ [0xA547]={
+ category="lo",
+ description="VAI SYLLABLE NI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA547,
+ },
+ [0xA548]={
+ category="lo",
+ description="VAI SYLLABLE NYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA548,
+ },
+ [0xA549]={
+ category="lo",
+ description="VAI SYLLABLE A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA549,
+ },
+ [0xA54A]={
+ category="lo",
+ description="VAI SYLLABLE AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA54A,
+ },
+ [0xA54B]={
+ category="lo",
+ description="VAI SYLLABLE NGAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA54B,
+ },
+ [0xA54C]={
+ category="lo",
+ description="VAI SYLLABLE HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA54C,
+ },
+ [0xA54D]={
+ category="lo",
+ description="VAI SYLLABLE HAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA54D,
+ },
+ [0xA54E]={
+ category="lo",
+ description="VAI SYLLABLE WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA54E,
+ },
+ [0xA54F]={
+ category="lo",
+ description="VAI SYLLABLE WAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA54F,
+ },
+ [0xA550]={
+ category="lo",
+ description="VAI SYLLABLE PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA550,
+ },
+ [0xA551]={
+ category="lo",
+ description="VAI SYLLABLE BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA551,
+ },
+ [0xA552]={
+ category="lo",
+ description="VAI SYLLABLE BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA552,
+ },
+ [0xA553]={
+ category="lo",
+ description="VAI SYLLABLE MBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA553,
+ },
+ [0xA554]={
+ category="lo",
+ description="VAI SYLLABLE KPA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA554,
+ },
+ [0xA555]={
+ category="lo",
+ description="VAI SYLLABLE KPAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA555,
+ },
+ [0xA556]={
+ category="lo",
+ description="VAI SYLLABLE MGBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA556,
+ },
+ [0xA557]={
+ category="lo",
+ description="VAI SYLLABLE GBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA557,
+ },
+ [0xA558]={
+ category="lo",
+ description="VAI SYLLABLE FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA558,
+ },
+ [0xA559]={
+ category="lo",
+ description="VAI SYLLABLE VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA559,
+ },
+ [0xA55A]={
+ category="lo",
+ description="VAI SYLLABLE TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA55A,
+ },
+ [0xA55B]={
+ category="lo",
+ description="VAI SYLLABLE THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA55B,
+ },
+ [0xA55C]={
+ category="lo",
+ description="VAI SYLLABLE DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA55C,
+ },
+ [0xA55D]={
+ category="lo",
+ description="VAI SYLLABLE DHHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA55D,
+ },
+ [0xA55E]={
+ category="lo",
+ description="VAI SYLLABLE LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA55E,
+ },
+ [0xA55F]={
+ category="lo",
+ description="VAI SYLLABLE RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA55F,
+ },
+ [0xA560]={
+ category="lo",
+ description="VAI SYLLABLE DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA560,
+ },
+ [0xA561]={
+ category="lo",
+ description="VAI SYLLABLE NDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA561,
+ },
+ [0xA562]={
+ category="lo",
+ description="VAI SYLLABLE SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA562,
+ },
+ [0xA563]={
+ category="lo",
+ description="VAI SYLLABLE SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA563,
+ },
+ [0xA564]={
+ category="lo",
+ description="VAI SYLLABLE ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA564,
+ },
+ [0xA565]={
+ category="lo",
+ description="VAI SYLLABLE ZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA565,
+ },
+ [0xA566]={
+ category="lo",
+ description="VAI SYLLABLE CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA566,
+ },
+ [0xA567]={
+ category="lo",
+ description="VAI SYLLABLE JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA567,
+ },
+ [0xA568]={
+ category="lo",
+ description="VAI SYLLABLE NJA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA568,
+ },
+ [0xA569]={
+ category="lo",
+ description="VAI SYLLABLE YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA569,
+ },
+ [0xA56A]={
+ category="lo",
+ description="VAI SYLLABLE KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA56A,
+ },
+ [0xA56B]={
+ category="lo",
+ description="VAI SYLLABLE KAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA56B,
+ },
+ [0xA56C]={
+ category="lo",
+ description="VAI SYLLABLE NGGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA56C,
+ },
+ [0xA56D]={
+ category="lo",
+ description="VAI SYLLABLE GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA56D,
+ },
+ [0xA56E]={
+ category="lo",
+ description="VAI SYLLABLE MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA56E,
+ },
+ [0xA56F]={
+ category="lo",
+ description="VAI SYLLABLE NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA56F,
+ },
+ [0xA570]={
+ category="lo",
+ description="VAI SYLLABLE NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA570,
+ },
+ [0xA571]={
+ category="lo",
+ description="VAI SYLLABLE OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA571,
+ },
+ [0xA572]={
+ category="lo",
+ description="VAI SYLLABLE OON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA572,
+ },
+ [0xA573]={
+ category="lo",
+ description="VAI SYLLABLE HOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA573,
+ },
+ [0xA574]={
+ category="lo",
+ description="VAI SYLLABLE WOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA574,
+ },
+ [0xA575]={
+ category="lo",
+ description="VAI SYLLABLE WOON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA575,
+ },
+ [0xA576]={
+ category="lo",
+ description="VAI SYLLABLE POO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA576,
+ },
+ [0xA577]={
+ category="lo",
+ description="VAI SYLLABLE BHOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA577,
+ },
+ [0xA578]={
+ category="lo",
+ description="VAI SYLLABLE BOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA578,
+ },
+ [0xA579]={
+ category="lo",
+ description="VAI SYLLABLE MBOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA579,
+ },
+ [0xA57A]={
+ category="lo",
+ description="VAI SYLLABLE KPOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA57A,
+ },
+ [0xA57B]={
+ category="lo",
+ description="VAI SYLLABLE MGBOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA57B,
+ },
+ [0xA57C]={
+ category="lo",
+ description="VAI SYLLABLE GBOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA57C,
+ },
+ [0xA57D]={
+ category="lo",
+ description="VAI SYLLABLE FOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA57D,
+ },
+ [0xA57E]={
+ category="lo",
+ description="VAI SYLLABLE VOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA57E,
+ },
+ [0xA57F]={
+ category="lo",
+ description="VAI SYLLABLE TOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA57F,
+ },
+ [0xA580]={
+ category="lo",
+ description="VAI SYLLABLE THOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA580,
+ },
+ [0xA581]={
+ category="lo",
+ description="VAI SYLLABLE DHOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA581,
+ },
+ [0xA582]={
+ category="lo",
+ description="VAI SYLLABLE DHHOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA582,
+ },
+ [0xA583]={
+ category="lo",
+ description="VAI SYLLABLE LOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA583,
+ },
+ [0xA584]={
+ category="lo",
+ description="VAI SYLLABLE ROO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA584,
+ },
+ [0xA585]={
+ category="lo",
+ description="VAI SYLLABLE DOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA585,
+ },
+ [0xA586]={
+ category="lo",
+ description="VAI SYLLABLE NDOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA586,
+ },
+ [0xA587]={
+ category="lo",
+ description="VAI SYLLABLE SOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA587,
+ },
+ [0xA588]={
+ category="lo",
+ description="VAI SYLLABLE SHOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA588,
+ },
+ [0xA589]={
+ category="lo",
+ description="VAI SYLLABLE ZOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA589,
+ },
+ [0xA58A]={
+ category="lo",
+ description="VAI SYLLABLE ZHOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA58A,
+ },
+ [0xA58B]={
+ category="lo",
+ description="VAI SYLLABLE COO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA58B,
+ },
+ [0xA58C]={
+ category="lo",
+ description="VAI SYLLABLE JOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA58C,
+ },
+ [0xA58D]={
+ category="lo",
+ description="VAI SYLLABLE NJOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA58D,
+ },
+ [0xA58E]={
+ category="lo",
+ description="VAI SYLLABLE YOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA58E,
+ },
+ [0xA58F]={
+ category="lo",
+ description="VAI SYLLABLE KOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA58F,
+ },
+ [0xA590]={
+ category="lo",
+ description="VAI SYLLABLE NGGOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA590,
+ },
+ [0xA591]={
+ category="lo",
+ description="VAI SYLLABLE GOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA591,
+ },
+ [0xA592]={
+ category="lo",
+ description="VAI SYLLABLE MOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA592,
+ },
+ [0xA593]={
+ category="lo",
+ description="VAI SYLLABLE NOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA593,
+ },
+ [0xA594]={
+ category="lo",
+ description="VAI SYLLABLE NYOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA594,
+ },
+ [0xA595]={
+ category="lo",
+ description="VAI SYLLABLE U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA595,
+ },
+ [0xA596]={
+ category="lo",
+ description="VAI SYLLABLE UN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA596,
+ },
+ [0xA597]={
+ category="lo",
+ description="VAI SYLLABLE HU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA597,
+ },
+ [0xA598]={
+ category="lo",
+ description="VAI SYLLABLE HUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA598,
+ },
+ [0xA599]={
+ category="lo",
+ description="VAI SYLLABLE WU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA599,
+ },
+ [0xA59A]={
+ category="lo",
+ description="VAI SYLLABLE WUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA59A,
+ },
+ [0xA59B]={
+ category="lo",
+ description="VAI SYLLABLE PU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA59B,
+ },
+ [0xA59C]={
+ category="lo",
+ description="VAI SYLLABLE BHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA59C,
+ },
+ [0xA59D]={
+ category="lo",
+ description="VAI SYLLABLE BU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA59D,
+ },
+ [0xA59E]={
+ category="lo",
+ description="VAI SYLLABLE MBU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA59E,
+ },
+ [0xA59F]={
+ category="lo",
+ description="VAI SYLLABLE KPU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA59F,
+ },
+ [0xA5A0]={
+ category="lo",
+ description="VAI SYLLABLE MGBU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A0,
+ },
+ [0xA5A1]={
+ category="lo",
+ description="VAI SYLLABLE GBU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A1,
+ },
+ [0xA5A2]={
+ category="lo",
+ description="VAI SYLLABLE FU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A2,
+ },
+ [0xA5A3]={
+ category="lo",
+ description="VAI SYLLABLE VU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A3,
+ },
+ [0xA5A4]={
+ category="lo",
+ description="VAI SYLLABLE TU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A4,
+ },
+ [0xA5A5]={
+ category="lo",
+ description="VAI SYLLABLE THU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A5,
+ },
+ [0xA5A6]={
+ category="lo",
+ description="VAI SYLLABLE DHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A6,
+ },
+ [0xA5A7]={
+ category="lo",
+ description="VAI SYLLABLE DHHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A7,
+ },
+ [0xA5A8]={
+ category="lo",
+ description="VAI SYLLABLE LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A8,
+ },
+ [0xA5A9]={
+ category="lo",
+ description="VAI SYLLABLE RU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5A9,
+ },
+ [0xA5AA]={
+ category="lo",
+ description="VAI SYLLABLE DU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5AA,
+ },
+ [0xA5AB]={
+ category="lo",
+ description="VAI SYLLABLE NDU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5AB,
+ },
+ [0xA5AC]={
+ category="lo",
+ description="VAI SYLLABLE SU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5AC,
+ },
+ [0xA5AD]={
+ category="lo",
+ description="VAI SYLLABLE SHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5AD,
+ },
+ [0xA5AE]={
+ category="lo",
+ description="VAI SYLLABLE ZU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5AE,
+ },
+ [0xA5AF]={
+ category="lo",
+ description="VAI SYLLABLE ZHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5AF,
+ },
+ [0xA5B0]={
+ category="lo",
+ description="VAI SYLLABLE CU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B0,
+ },
+ [0xA5B1]={
+ category="lo",
+ description="VAI SYLLABLE JU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B1,
+ },
+ [0xA5B2]={
+ category="lo",
+ description="VAI SYLLABLE NJU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B2,
+ },
+ [0xA5B3]={
+ category="lo",
+ description="VAI SYLLABLE YU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B3,
+ },
+ [0xA5B4]={
+ category="lo",
+ description="VAI SYLLABLE KU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B4,
+ },
+ [0xA5B5]={
+ category="lo",
+ description="VAI SYLLABLE NGGU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B5,
+ },
+ [0xA5B6]={
+ category="lo",
+ description="VAI SYLLABLE GU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B6,
+ },
+ [0xA5B7]={
+ category="lo",
+ description="VAI SYLLABLE MU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B7,
+ },
+ [0xA5B8]={
+ category="lo",
+ description="VAI SYLLABLE NU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B8,
+ },
+ [0xA5B9]={
+ category="lo",
+ description="VAI SYLLABLE NYU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5B9,
+ },
+ [0xA5BA]={
+ category="lo",
+ description="VAI SYLLABLE O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5BA,
+ },
+ [0xA5BB]={
+ category="lo",
+ description="VAI SYLLABLE ON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5BB,
+ },
+ [0xA5BC]={
+ category="lo",
+ description="VAI SYLLABLE NGON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5BC,
+ },
+ [0xA5BD]={
+ category="lo",
+ description="VAI SYLLABLE HO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5BD,
+ },
+ [0xA5BE]={
+ category="lo",
+ description="VAI SYLLABLE HON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5BE,
+ },
+ [0xA5BF]={
+ category="lo",
+ description="VAI SYLLABLE WO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5BF,
+ },
+ [0xA5C0]={
+ category="lo",
+ description="VAI SYLLABLE WON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C0,
+ },
+ [0xA5C1]={
+ category="lo",
+ description="VAI SYLLABLE PO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C1,
+ },
+ [0xA5C2]={
+ category="lo",
+ description="VAI SYLLABLE BHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C2,
+ },
+ [0xA5C3]={
+ category="lo",
+ description="VAI SYLLABLE BO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C3,
+ },
+ [0xA5C4]={
+ category="lo",
+ description="VAI SYLLABLE MBO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C4,
+ },
+ [0xA5C5]={
+ category="lo",
+ description="VAI SYLLABLE KPO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C5,
+ },
+ [0xA5C6]={
+ category="lo",
+ description="VAI SYLLABLE MGBO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C6,
+ },
+ [0xA5C7]={
+ category="lo",
+ description="VAI SYLLABLE GBO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C7,
+ },
+ [0xA5C8]={
+ category="lo",
+ description="VAI SYLLABLE GBON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C8,
+ },
+ [0xA5C9]={
+ category="lo",
+ description="VAI SYLLABLE FO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5C9,
+ },
+ [0xA5CA]={
+ category="lo",
+ description="VAI SYLLABLE VO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5CA,
+ },
+ [0xA5CB]={
+ category="lo",
+ description="VAI SYLLABLE TO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5CB,
+ },
+ [0xA5CC]={
+ category="lo",
+ description="VAI SYLLABLE THO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5CC,
+ },
+ [0xA5CD]={
+ category="lo",
+ description="VAI SYLLABLE DHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5CD,
+ },
+ [0xA5CE]={
+ category="lo",
+ description="VAI SYLLABLE DHHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5CE,
+ },
+ [0xA5CF]={
+ category="lo",
+ description="VAI SYLLABLE LO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5CF,
+ },
+ [0xA5D0]={
+ category="lo",
+ description="VAI SYLLABLE RO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D0,
+ },
+ [0xA5D1]={
+ category="lo",
+ description="VAI SYLLABLE DO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D1,
+ },
+ [0xA5D2]={
+ category="lo",
+ description="VAI SYLLABLE NDO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D2,
+ },
+ [0xA5D3]={
+ category="lo",
+ description="VAI SYLLABLE SO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D3,
+ },
+ [0xA5D4]={
+ category="lo",
+ description="VAI SYLLABLE SHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D4,
+ },
+ [0xA5D5]={
+ category="lo",
+ description="VAI SYLLABLE ZO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D5,
+ },
+ [0xA5D6]={
+ category="lo",
+ description="VAI SYLLABLE ZHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D6,
+ },
+ [0xA5D7]={
+ category="lo",
+ description="VAI SYLLABLE CO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D7,
+ },
+ [0xA5D8]={
+ category="lo",
+ description="VAI SYLLABLE JO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D8,
+ },
+ [0xA5D9]={
+ category="lo",
+ description="VAI SYLLABLE NJO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5D9,
+ },
+ [0xA5DA]={
+ category="lo",
+ description="VAI SYLLABLE YO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5DA,
+ },
+ [0xA5DB]={
+ category="lo",
+ description="VAI SYLLABLE KO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5DB,
+ },
+ [0xA5DC]={
+ category="lo",
+ description="VAI SYLLABLE NGGO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5DC,
+ },
+ [0xA5DD]={
+ category="lo",
+ description="VAI SYLLABLE GO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5DD,
+ },
+ [0xA5DE]={
+ category="lo",
+ description="VAI SYLLABLE MO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5DE,
+ },
+ [0xA5DF]={
+ category="lo",
+ description="VAI SYLLABLE NO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5DF,
+ },
+ [0xA5E0]={
+ category="lo",
+ description="VAI SYLLABLE NYO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E0,
+ },
+ [0xA5E1]={
+ category="lo",
+ description="VAI SYLLABLE E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E1,
+ },
+ [0xA5E2]={
+ category="lo",
+ description="VAI SYLLABLE EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E2,
+ },
+ [0xA5E3]={
+ category="lo",
+ description="VAI SYLLABLE NGEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E3,
+ },
+ [0xA5E4]={
+ category="lo",
+ description="VAI SYLLABLE HE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E4,
+ },
+ [0xA5E5]={
+ category="lo",
+ description="VAI SYLLABLE HEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E5,
+ },
+ [0xA5E6]={
+ category="lo",
+ description="VAI SYLLABLE WE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E6,
+ },
+ [0xA5E7]={
+ category="lo",
+ description="VAI SYLLABLE WEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E7,
+ },
+ [0xA5E8]={
+ category="lo",
+ description="VAI SYLLABLE PE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E8,
+ },
+ [0xA5E9]={
+ category="lo",
+ description="VAI SYLLABLE BHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5E9,
+ },
+ [0xA5EA]={
+ category="lo",
+ description="VAI SYLLABLE BE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5EA,
+ },
+ [0xA5EB]={
+ category="lo",
+ description="VAI SYLLABLE MBE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5EB,
+ },
+ [0xA5EC]={
+ category="lo",
+ description="VAI SYLLABLE KPE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5EC,
+ },
+ [0xA5ED]={
+ category="lo",
+ description="VAI SYLLABLE KPEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5ED,
+ },
+ [0xA5EE]={
+ category="lo",
+ description="VAI SYLLABLE MGBE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5EE,
+ },
+ [0xA5EF]={
+ category="lo",
+ description="VAI SYLLABLE GBE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5EF,
+ },
+ [0xA5F0]={
+ category="lo",
+ description="VAI SYLLABLE GBEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F0,
+ },
+ [0xA5F1]={
+ category="lo",
+ description="VAI SYLLABLE FE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F1,
+ },
+ [0xA5F2]={
+ category="lo",
+ description="VAI SYLLABLE VE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F2,
+ },
+ [0xA5F3]={
+ category="lo",
+ description="VAI SYLLABLE TE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F3,
+ },
+ [0xA5F4]={
+ category="lo",
+ description="VAI SYLLABLE THE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F4,
+ },
+ [0xA5F5]={
+ category="lo",
+ description="VAI SYLLABLE DHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F5,
+ },
+ [0xA5F6]={
+ category="lo",
+ description="VAI SYLLABLE DHHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F6,
+ },
+ [0xA5F7]={
+ category="lo",
+ description="VAI SYLLABLE LE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F7,
+ },
+ [0xA5F8]={
+ category="lo",
+ description="VAI SYLLABLE RE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F8,
+ },
+ [0xA5F9]={
+ category="lo",
+ description="VAI SYLLABLE DE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5F9,
+ },
+ [0xA5FA]={
+ category="lo",
+ description="VAI SYLLABLE NDE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5FA,
+ },
+ [0xA5FB]={
+ category="lo",
+ description="VAI SYLLABLE SE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5FB,
+ },
+ [0xA5FC]={
+ category="lo",
+ description="VAI SYLLABLE SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5FC,
+ },
+ [0xA5FD]={
+ category="lo",
+ description="VAI SYLLABLE ZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5FD,
+ },
+ [0xA5FE]={
+ category="lo",
+ description="VAI SYLLABLE ZHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5FE,
+ },
+ [0xA5FF]={
+ category="lo",
+ description="VAI SYLLABLE CE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA5FF,
+ },
+ [0xA600]={
+ category="lo",
+ description="VAI SYLLABLE JE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA600,
+ },
+ [0xA601]={
+ category="lo",
+ description="VAI SYLLABLE NJE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA601,
+ },
+ [0xA602]={
+ category="lo",
+ description="VAI SYLLABLE YE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA602,
+ },
+ [0xA603]={
+ category="lo",
+ description="VAI SYLLABLE KE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA603,
+ },
+ [0xA604]={
+ category="lo",
+ description="VAI SYLLABLE NGGE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA604,
+ },
+ [0xA605]={
+ category="lo",
+ description="VAI SYLLABLE NGGEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA605,
+ },
+ [0xA606]={
+ category="lo",
+ description="VAI SYLLABLE GE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA606,
+ },
+ [0xA607]={
+ category="lo",
+ description="VAI SYLLABLE GEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA607,
+ },
+ [0xA608]={
+ category="lo",
+ description="VAI SYLLABLE ME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA608,
+ },
+ [0xA609]={
+ category="lo",
+ description="VAI SYLLABLE NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA609,
+ },
+ [0xA60A]={
+ category="lo",
+ description="VAI SYLLABLE NYE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA60A,
+ },
+ [0xA60B]={
+ category="lo",
+ description="VAI SYLLABLE NG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA60B,
+ },
+ [0xA60C]={
+ category="lm",
+ description="VAI SYLLABLE LENGTHENER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA60C,
+ },
+ [0xA60D]={
+ category="po",
+ description="VAI COMMA",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0xA60D,
+ },
+ [0xA60E]={
+ category="po",
+ description="VAI FULL STOP",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0xA60E,
+ },
+ [0xA60F]={
+ category="po",
+ description="VAI QUESTION MARK",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0xA60F,
+ },
+ [0xA610]={
+ category="lo",
+ description="VAI SYLLABLE NDOLE FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA610,
+ },
+ [0xA611]={
+ category="lo",
+ description="VAI SYLLABLE NDOLE KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA611,
+ },
+ [0xA612]={
+ category="lo",
+ description="VAI SYLLABLE NDOLE SOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA612,
+ },
+ [0xA613]={
+ category="lo",
+ description="VAI SYMBOL FEENG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA613,
+ },
+ [0xA614]={
+ category="lo",
+ description="VAI SYMBOL KEENG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA614,
+ },
+ [0xA615]={
+ category="lo",
+ description="VAI SYMBOL TING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA615,
+ },
+ [0xA616]={
+ category="lo",
+ description="VAI SYMBOL NII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA616,
+ },
+ [0xA617]={
+ category="lo",
+ description="VAI SYMBOL BANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA617,
+ },
+ [0xA618]={
+ category="lo",
+ description="VAI SYMBOL FAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA618,
+ },
+ [0xA619]={
+ category="lo",
+ description="VAI SYMBOL TAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA619,
+ },
+ [0xA61A]={
+ category="lo",
+ description="VAI SYMBOL DANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA61A,
+ },
+ [0xA61B]={
+ category="lo",
+ description="VAI SYMBOL DOONG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA61B,
+ },
+ [0xA61C]={
+ category="lo",
+ description="VAI SYMBOL KUNG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA61C,
+ },
+ [0xA61D]={
+ category="lo",
+ description="VAI SYMBOL TONG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA61D,
+ },
+ [0xA61E]={
+ category="lo",
+ description="VAI SYMBOL DO-O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA61E,
+ },
+ [0xA61F]={
+ category="lo",
+ description="VAI SYMBOL JONG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA61F,
+ },
+ [0xA620]={
+ category="nd",
+ description="VAI DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA620,
+ },
+ [0xA621]={
+ category="nd",
+ description="VAI DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA621,
+ },
+ [0xA622]={
+ category="nd",
+ description="VAI DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA622,
+ },
+ [0xA623]={
+ category="nd",
+ description="VAI DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA623,
+ },
+ [0xA624]={
+ category="nd",
+ description="VAI DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA624,
+ },
+ [0xA625]={
+ category="nd",
+ description="VAI DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA625,
+ },
+ [0xA626]={
+ category="nd",
+ description="VAI DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA626,
+ },
+ [0xA627]={
+ category="nd",
+ description="VAI DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA627,
+ },
+ [0xA628]={
+ category="nd",
+ description="VAI DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA628,
+ },
+ [0xA629]={
+ category="nd",
+ description="VAI DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA629,
+ },
+ [0xA62A]={
+ category="lo",
+ description="VAI SYLLABLE NDOLE MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA62A,
+ },
+ [0xA62B]={
+ category="lo",
+ description="VAI SYLLABLE NDOLE DO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA62B,
+ },
+ [0xA640]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER ZEMLYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA640,
+ },
+ [0xA641]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER ZEMLYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA641,
+ },
+ [0xA642]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER DZELO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA642,
+ },
+ [0xA643]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER DZELO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA643,
+ },
+ [0xA644]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER REVERSED DZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA644,
+ },
+ [0xA645]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER REVERSED DZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA645,
+ },
+ [0xA646]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER IOTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA646,
+ },
+ [0xA647]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER IOTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA647,
+ },
+ [0xA648]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER DJERV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA648,
+ },
+ [0xA649]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER DJERV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA649,
+ },
+ [0xA64A]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER MONOGRAPH UK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA64A,
+ },
+ [0xA64B]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER MONOGRAPH UK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA64B,
+ },
+ [0xA64C]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER BROAD OMEGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA64C,
+ },
+ [0xA64D]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER BROAD OMEGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA64D,
+ },
+ [0xA64E]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER NEUTRAL YER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA64E,
+ },
+ [0xA64F]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER NEUTRAL YER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA64F,
+ },
+ [0xA650]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER YERU WITH BACK YER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA650,
+ },
+ [0xA651]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER YERU WITH BACK YER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA651,
+ },
+ [0xA652]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER IOTIFIED YAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA652,
+ },
+ [0xA653]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER IOTIFIED YAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA653,
+ },
+ [0xA654]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER REVERSED YU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA654,
+ },
+ [0xA655]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER REVERSED YU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA655,
+ },
+ [0xA656]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER IOTIFIED A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA656,
+ },
+ [0xA657]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER IOTIFIED A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA657,
+ },
+ [0xA658]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA658,
+ },
+ [0xA659]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER CLOSED LITTLE YUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA659,
+ },
+ [0xA65A]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER BLENDED YUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA65A,
+ },
+ [0xA65B]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER BLENDED YUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA65B,
+ },
+ [0xA65C]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA65C,
+ },
+ [0xA65D]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA65D,
+ },
+ [0xA65E]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER YN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA65E,
+ },
+ [0xA65F]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER YN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA65F,
+ },
+ [0xA660]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER REVERSED TSE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA660,
+ },
+ [0xA661]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER REVERSED TSE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA661,
+ },
+ [0xA662]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER SOFT DE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA662,
+ },
+ [0xA663]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER SOFT DE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA663,
+ },
+ [0xA664]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER SOFT EL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA664,
+ },
+ [0xA665]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER SOFT EL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA665,
+ },
+ [0xA666]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER SOFT EM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA666,
+ },
+ [0xA667]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER SOFT EM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA667,
+ },
+ [0xA668]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER MONOCULAR O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA668,
+ },
+ [0xA669]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER MONOCULAR O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA669,
+ },
+ [0xA66A]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER BINOCULAR O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA66A,
+ },
+ [0xA66B]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER BINOCULAR O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA66B,
+ },
+ [0xA66C]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA66C,
+ },
+ [0xA66D]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER DOUBLE MONOCULAR O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA66D,
+ },
+ [0xA66E]={
+ category="lo",
+ description="CYRILLIC LETTER MULTIOCULAR O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA66E,
+ },
+ [0xA66F]={
+ category="mn",
+ description="COMBINING CYRILLIC VZMET",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA66F,
+ },
+ [0xA670]={
+ category="me",
+ description="COMBINING CYRILLIC TEN MILLIONS SIGN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA670,
+ },
+ [0xA671]={
+ category="me",
+ description="COMBINING CYRILLIC HUNDRED MILLIONS SIGN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA671,
+ },
+ [0xA672]={
+ category="me",
+ description="COMBINING CYRILLIC THOUSAND MILLIONS SIGN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA672,
+ },
+ [0xA673]={
+ category="po",
+ description="SLAVONIC ASTERISK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA673,
+ },
+ [0xA674]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER UKRAINIAN IE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA674,
+ },
+ [0xA675]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA675,
+ },
+ [0xA676]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER YI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA676,
+ },
+ [0xA677]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA677,
+ },
+ [0xA678]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER HARD SIGN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA678,
+ },
+ [0xA679]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER YERU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA679,
+ },
+ [0xA67A]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER SOFT SIGN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA67A,
+ },
+ [0xA67B]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER OMEGA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA67B,
+ },
+ [0xA67C]={
+ category="mn",
+ description="COMBINING CYRILLIC KAVYKA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA67C,
+ },
+ [0xA67D]={
+ category="mn",
+ description="COMBINING CYRILLIC PAYEROK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA67D,
+ },
+ [0xA67E]={
+ category="po",
+ description="CYRILLIC KAVYKA",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA67E,
+ },
+ [0xA67F]={
+ category="lm",
+ description="CYRILLIC PAYEROK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA67F,
+ },
+ [0xA680]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER DWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA680,
+ },
+ [0xA681]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER DWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA681,
+ },
+ [0xA682]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER DZWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA682,
+ },
+ [0xA683]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER DZWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA683,
+ },
+ [0xA684]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER ZHWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA684,
+ },
+ [0xA685]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER ZHWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA685,
+ },
+ [0xA686]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER CCHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA686,
+ },
+ [0xA687]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER CCHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA687,
+ },
+ [0xA688]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER DZZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA688,
+ },
+ [0xA689]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER DZZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA689,
+ },
+ [0xA68A]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA68A,
+ },
+ [0xA68B]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA68B,
+ },
+ [0xA68C]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER TWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA68C,
+ },
+ [0xA68D]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER TWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA68D,
+ },
+ [0xA68E]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER TSWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA68E,
+ },
+ [0xA68F]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER TSWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA68F,
+ },
+ [0xA690]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER TSSE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA690,
+ },
+ [0xA691]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER TSSE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA691,
+ },
+ [0xA692]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER TCHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA692,
+ },
+ [0xA693]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER TCHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA693,
+ },
+ [0xA694]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER HWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA694,
+ },
+ [0xA695]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER HWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA695,
+ },
+ [0xA696]={
+ category="lu",
+ description="CYRILLIC CAPITAL LETTER SHWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA696,
+ },
+ [0xA697]={
+ category="ll",
+ description="CYRILLIC SMALL LETTER SHWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA697,
+ },
+ [0xA69F]={
+ category="mn",
+ description="COMBINING CYRILLIC LETTER IOTIFIED E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA69F,
+ },
+ [0xA6A0]={
+ category="lo",
+ description="BAMUM LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A0,
+ },
+ [0xA6A1]={
+ category="lo",
+ description="BAMUM LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A1,
+ },
+ [0xA6A2]={
+ category="lo",
+ description="BAMUM LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A2,
+ },
+ [0xA6A3]={
+ category="lo",
+ description="BAMUM LETTER KU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A3,
+ },
+ [0xA6A4]={
+ category="lo",
+ description="BAMUM LETTER EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A4,
+ },
+ [0xA6A5]={
+ category="lo",
+ description="BAMUM LETTER REE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A5,
+ },
+ [0xA6A6]={
+ category="lo",
+ description="BAMUM LETTER TAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A6,
+ },
+ [0xA6A7]={
+ category="lo",
+ description="BAMUM LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A7,
+ },
+ [0xA6A8]={
+ category="lo",
+ description="BAMUM LETTER NYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A8,
+ },
+ [0xA6A9]={
+ category="lo",
+ description="BAMUM LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6A9,
+ },
+ [0xA6AA]={
+ category="lo",
+ description="BAMUM LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6AA,
+ },
+ [0xA6AB]={
+ category="lo",
+ description="BAMUM LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6AB,
+ },
+ [0xA6AC]={
+ category="lo",
+ description="BAMUM LETTER RII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6AC,
+ },
+ [0xA6AD]={
+ category="lo",
+ description="BAMUM LETTER RIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6AD,
+ },
+ [0xA6AE]={
+ category="lo",
+ description="BAMUM LETTER LEEEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6AE,
+ },
+ [0xA6AF]={
+ category="lo",
+ description="BAMUM LETTER MEEEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6AF,
+ },
+ [0xA6B0]={
+ category="lo",
+ description="BAMUM LETTER TAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B0,
+ },
+ [0xA6B1]={
+ category="lo",
+ description="BAMUM LETTER NDAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B1,
+ },
+ [0xA6B2]={
+ category="lo",
+ description="BAMUM LETTER NJAEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B2,
+ },
+ [0xA6B3]={
+ category="lo",
+ description="BAMUM LETTER M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B3,
+ },
+ [0xA6B4]={
+ category="lo",
+ description="BAMUM LETTER SUU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B4,
+ },
+ [0xA6B5]={
+ category="lo",
+ description="BAMUM LETTER MU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B5,
+ },
+ [0xA6B6]={
+ category="lo",
+ description="BAMUM LETTER SHII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B6,
+ },
+ [0xA6B7]={
+ category="lo",
+ description="BAMUM LETTER SI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B7,
+ },
+ [0xA6B8]={
+ category="lo",
+ description="BAMUM LETTER SHEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B8,
+ },
+ [0xA6B9]={
+ category="lo",
+ description="BAMUM LETTER SEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6B9,
+ },
+ [0xA6BA]={
+ category="lo",
+ description="BAMUM LETTER KYEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6BA,
+ },
+ [0xA6BB]={
+ category="lo",
+ description="BAMUM LETTER KET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6BB,
+ },
+ [0xA6BC]={
+ category="lo",
+ description="BAMUM LETTER NUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6BC,
+ },
+ [0xA6BD]={
+ category="lo",
+ description="BAMUM LETTER NU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6BD,
+ },
+ [0xA6BE]={
+ category="lo",
+ description="BAMUM LETTER NJUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6BE,
+ },
+ [0xA6BF]={
+ category="lo",
+ description="BAMUM LETTER YOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6BF,
+ },
+ [0xA6C0]={
+ category="lo",
+ description="BAMUM LETTER SHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C0,
+ },
+ [0xA6C1]={
+ category="lo",
+ description="BAMUM LETTER YUQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C1,
+ },
+ [0xA6C2]={
+ category="lo",
+ description="BAMUM LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C2,
+ },
+ [0xA6C3]={
+ category="lo",
+ description="BAMUM LETTER NSHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C3,
+ },
+ [0xA6C4]={
+ category="lo",
+ description="BAMUM LETTER KEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C4,
+ },
+ [0xA6C5]={
+ category="lo",
+ description="BAMUM LETTER PEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C5,
+ },
+ [0xA6C6]={
+ category="lo",
+ description="BAMUM LETTER NJEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C6,
+ },
+ [0xA6C7]={
+ category="lo",
+ description="BAMUM LETTER NTEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C7,
+ },
+ [0xA6C8]={
+ category="lo",
+ description="BAMUM LETTER PUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C8,
+ },
+ [0xA6C9]={
+ category="lo",
+ description="BAMUM LETTER WUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6C9,
+ },
+ [0xA6CA]={
+ category="lo",
+ description="BAMUM LETTER PEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6CA,
+ },
+ [0xA6CB]={
+ category="lo",
+ description="BAMUM LETTER FEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6CB,
+ },
+ [0xA6CC]={
+ category="lo",
+ description="BAMUM LETTER RU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6CC,
+ },
+ [0xA6CD]={
+ category="lo",
+ description="BAMUM LETTER LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6CD,
+ },
+ [0xA6CE]={
+ category="lo",
+ description="BAMUM LETTER MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6CE,
+ },
+ [0xA6CF]={
+ category="lo",
+ description="BAMUM LETTER NI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6CF,
+ },
+ [0xA6D0]={
+ category="lo",
+ description="BAMUM LETTER REUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D0,
+ },
+ [0xA6D1]={
+ category="lo",
+ description="BAMUM LETTER RAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D1,
+ },
+ [0xA6D2]={
+ category="lo",
+ description="BAMUM LETTER KEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D2,
+ },
+ [0xA6D3]={
+ category="lo",
+ description="BAMUM LETTER NGKWAEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D3,
+ },
+ [0xA6D4]={
+ category="lo",
+ description="BAMUM LETTER NGGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D4,
+ },
+ [0xA6D5]={
+ category="lo",
+ description="BAMUM LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D5,
+ },
+ [0xA6D6]={
+ category="lo",
+ description="BAMUM LETTER SHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D6,
+ },
+ [0xA6D7]={
+ category="lo",
+ description="BAMUM LETTER PUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D7,
+ },
+ [0xA6D8]={
+ category="lo",
+ description="BAMUM LETTER FU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D8,
+ },
+ [0xA6D9]={
+ category="lo",
+ description="BAMUM LETTER FOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6D9,
+ },
+ [0xA6DA]={
+ category="lo",
+ description="BAMUM LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6DA,
+ },
+ [0xA6DB]={
+ category="lo",
+ description="BAMUM LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6DB,
+ },
+ [0xA6DC]={
+ category="lo",
+ description="BAMUM LETTER LI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6DC,
+ },
+ [0xA6DD]={
+ category="lo",
+ description="BAMUM LETTER PI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6DD,
+ },
+ [0xA6DE]={
+ category="lo",
+ description="BAMUM LETTER LOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6DE,
+ },
+ [0xA6DF]={
+ category="lo",
+ description="BAMUM LETTER KO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6DF,
+ },
+ [0xA6E0]={
+ category="lo",
+ description="BAMUM LETTER MBEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E0,
+ },
+ [0xA6E1]={
+ category="lo",
+ description="BAMUM LETTER REN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E1,
+ },
+ [0xA6E2]={
+ category="lo",
+ description="BAMUM LETTER MEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E2,
+ },
+ [0xA6E3]={
+ category="lo",
+ description="BAMUM LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E3,
+ },
+ [0xA6E4]={
+ category="lo",
+ description="BAMUM LETTER TI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E4,
+ },
+ [0xA6E5]={
+ category="lo",
+ description="BAMUM LETTER KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E5,
+ },
+ [0xA6E6]={
+ category="nl",
+ description="BAMUM LETTER MO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E6,
+ },
+ [0xA6E7]={
+ category="nl",
+ description="BAMUM LETTER MBAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E7,
+ },
+ [0xA6E8]={
+ category="nl",
+ description="BAMUM LETTER TET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E8,
+ },
+ [0xA6E9]={
+ category="nl",
+ description="BAMUM LETTER KPA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6E9,
+ },
+ [0xA6EA]={
+ category="nl",
+ description="BAMUM LETTER TEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6EA,
+ },
+ [0xA6EB]={
+ category="nl",
+ description="BAMUM LETTER NTUU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6EB,
+ },
+ [0xA6EC]={
+ category="nl",
+ description="BAMUM LETTER SAMBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6EC,
+ },
+ [0xA6ED]={
+ category="nl",
+ description="BAMUM LETTER FAAMAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6ED,
+ },
+ [0xA6EE]={
+ category="nl",
+ description="BAMUM LETTER KOVUU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6EE,
+ },
+ [0xA6EF]={
+ category="nl",
+ description="BAMUM LETTER KOGHOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6EF,
+ },
+ [0xA6F0]={
+ category="mn",
+ description="BAMUM COMBINING MARK KOQNDON",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA6F0,
+ },
+ [0xA6F1]={
+ category="mn",
+ description="BAMUM COMBINING MARK TUKWENTIS",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA6F1,
+ },
+ [0xA6F2]={
+ category="po",
+ description="BAMUM NJAEMLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA6F2,
+ },
+ [0xA6F3]={
+ category="po",
+ description="BAMUM FULL STOP",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA6F3,
+ },
+ [0xA6F4]={
+ category="po",
+ description="BAMUM COLON",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA6F4,
+ },
+ [0xA6F5]={
+ category="po",
+ description="BAMUM COMMA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA6F5,
+ },
+ [0xA6F6]={
+ category="po",
+ description="BAMUM SEMICOLON",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA6F6,
+ },
+ [0xA6F7]={
+ category="po",
+ description="BAMUM QUESTION MARK",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA6F7,
+ },
+ [0xA700]={
+ category="sk",
+ description="MODIFIER LETTER CHINESE TONE YIN PING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA700,
+ },
+ [0xA701]={
+ category="sk",
+ description="MODIFIER LETTER CHINESE TONE YANG PING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA701,
+ },
+ [0xA702]={
+ category="sk",
+ description="MODIFIER LETTER CHINESE TONE YIN SHANG",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA702,
+ },
+ [0xA703]={
+ category="sk",
+ description="MODIFIER LETTER CHINESE TONE YANG SHANG",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA703,
+ },
+ [0xA704]={
+ category="sk",
+ description="MODIFIER LETTER CHINESE TONE YIN QU",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA704,
+ },
+ [0xA705]={
+ category="sk",
+ description="MODIFIER LETTER CHINESE TONE YANG QU",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA705,
+ },
+ [0xA706]={
+ category="sk",
+ description="MODIFIER LETTER CHINESE TONE YIN RU",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA706,
+ },
+ [0xA707]={
+ category="sk",
+ description="MODIFIER LETTER CHINESE TONE YANG RU",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA707,
+ },
+ [0xA708]={
+ category="sk",
+ description="MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA708,
+ },
+ [0xA709]={
+ category="sk",
+ description="MODIFIER LETTER HIGH DOTTED TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA709,
+ },
+ [0xA70A]={
+ category="sk",
+ description="MODIFIER LETTER MID DOTTED TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA70A,
+ },
+ [0xA70B]={
+ category="sk",
+ description="MODIFIER LETTER LOW DOTTED TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA70B,
+ },
+ [0xA70C]={
+ category="sk",
+ description="MODIFIER LETTER EXTRA-LOW DOTTED TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA70C,
+ },
+ [0xA70D]={
+ category="sk",
+ description="MODIFIER LETTER EXTRA-HIGH DOTTED LEFT-STEM TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA70D,
+ },
+ [0xA70E]={
+ category="sk",
+ description="MODIFIER LETTER HIGH DOTTED LEFT-STEM TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA70E,
+ },
+ [0xA70F]={
+ category="sk",
+ description="MODIFIER LETTER MID DOTTED LEFT-STEM TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA70F,
+ },
+ [0xA710]={
+ category="sk",
+ description="MODIFIER LETTER LOW DOTTED LEFT-STEM TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA710,
+ },
+ [0xA711]={
+ category="sk",
+ description="MODIFIER LETTER EXTRA-LOW DOTTED LEFT-STEM TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA711,
+ },
+ [0xA712]={
+ category="sk",
+ description="MODIFIER LETTER EXTRA-HIGH LEFT-STEM TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA712,
+ },
+ [0xA713]={
+ category="sk",
+ description="MODIFIER LETTER HIGH LEFT-STEM TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA713,
+ },
+ [0xA714]={
+ category="sk",
+ description="MODIFIER LETTER MID LEFT-STEM TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA714,
+ },
+ [0xA715]={
+ category="sk",
+ description="MODIFIER LETTER LOW LEFT-STEM TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA715,
+ },
+ [0xA716]={
+ category="sk",
+ description="MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA716,
+ },
+ [0xA717]={
+ category="lm",
+ description="MODIFIER LETTER DOT VERTICAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA717,
+ },
+ [0xA718]={
+ category="lm",
+ description="MODIFIER LETTER DOT SLASH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA718,
+ },
+ [0xA719]={
+ category="lm",
+ description="MODIFIER LETTER DOT HORIZONTAL BAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA719,
+ },
+ [0xA71A]={
+ category="lm",
+ description="MODIFIER LETTER LOWER RIGHT CORNER ANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA71A,
+ },
+ [0xA71B]={
+ category="lm",
+ description="MODIFIER LETTER RAISED UP ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA71B,
+ },
+ [0xA71C]={
+ category="lm",
+ description="MODIFIER LETTER RAISED DOWN ARROW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA71C,
+ },
+ [0xA71D]={
+ category="lm",
+ description="MODIFIER LETTER RAISED EXCLAMATION MARK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA71D,
+ },
+ [0xA71E]={
+ category="lm",
+ description="MODIFIER LETTER RAISED INVERTED EXCLAMATION MARK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA71E,
+ },
+ [0xA71F]={
+ category="lm",
+ description="MODIFIER LETTER LOW INVERTED EXCLAMATION MARK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA71F,
+ },
+ [0xA720]={
+ category="sk",
+ description="MODIFIER LETTER STRESS AND HIGH TONE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA720,
+ },
+ [0xA721]={
+ category="sk",
+ description="MODIFIER LETTER STRESS AND LOW TONE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA721,
+ },
+ [0xA722]={
+ category="lu",
+ description="LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA722,
+ },
+ [0xA723]={
+ category="ll",
+ description="LATIN SMALL LETTER EGYPTOLOGICAL ALEF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA723,
+ },
+ [0xA724]={
+ category="lu",
+ description="LATIN CAPITAL LETTER EGYPTOLOGICAL AIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA724,
+ },
+ [0xA725]={
+ category="ll",
+ description="LATIN SMALL LETTER EGYPTOLOGICAL AIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA725,
+ },
+ [0xA726]={
+ category="lu",
+ description="LATIN CAPITAL LETTER HENG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA726,
+ },
+ [0xA727]={
+ category="ll",
+ description="LATIN SMALL LETTER HENG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA727,
+ },
+ [0xA728]={
+ category="lu",
+ description="LATIN CAPITAL LETTER TZ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA728,
+ },
+ [0xA729]={
+ category="ll",
+ description="LATIN SMALL LETTER TZ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA729,
+ },
+ [0xA72A]={
+ category="lu",
+ description="LATIN CAPITAL LETTER TRESILLO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA72A,
+ },
+ [0xA72B]={
+ category="ll",
+ description="LATIN SMALL LETTER TRESILLO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA72B,
+ },
+ [0xA72C]={
+ category="lu",
+ description="LATIN CAPITAL LETTER CUATRILLO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA72C,
+ },
+ [0xA72D]={
+ category="ll",
+ description="LATIN SMALL LETTER CUATRILLO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA72D,
+ },
+ [0xA72E]={
+ category="lu",
+ description="LATIN CAPITAL LETTER CUATRILLO WITH COMMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA72E,
+ },
+ [0xA72F]={
+ category="ll",
+ description="LATIN SMALL LETTER CUATRILLO WITH COMMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA72F,
+ },
+ [0xA730]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA730,
+ },
+ [0xA731]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA731,
+ },
+ [0xA732]={
+ category="lu",
+ description="LATIN CAPITAL LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA732,
+ },
+ [0xA733]={
+ category="ll",
+ description="LATIN SMALL LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA733,
+ },
+ [0xA734]={
+ category="lu",
+ description="LATIN CAPITAL LETTER AO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA734,
+ },
+ [0xA735]={
+ category="ll",
+ description="LATIN SMALL LETTER AO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA735,
+ },
+ [0xA736]={
+ category="lu",
+ description="LATIN CAPITAL LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA736,
+ },
+ [0xA737]={
+ category="ll",
+ description="LATIN SMALL LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA737,
+ },
+ [0xA738]={
+ category="lu",
+ description="LATIN CAPITAL LETTER AV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA738,
+ },
+ [0xA739]={
+ category="ll",
+ description="LATIN SMALL LETTER AV",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA739,
+ },
+ [0xA73A]={
+ category="lu",
+ description="LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA73A,
+ },
+ [0xA73B]={
+ category="ll",
+ description="LATIN SMALL LETTER AV WITH HORIZONTAL BAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA73B,
+ },
+ [0xA73C]={
+ category="lu",
+ description="LATIN CAPITAL LETTER AY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA73C,
+ },
+ [0xA73D]={
+ category="ll",
+ description="LATIN SMALL LETTER AY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA73D,
+ },
+ [0xA73E]={
+ category="lu",
+ description="LATIN CAPITAL LETTER REVERSED C WITH DOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA73E,
+ },
+ [0xA73F]={
+ category="ll",
+ description="LATIN SMALL LETTER REVERSED C WITH DOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA73F,
+ },
+ [0xA740]={
+ category="lu",
+ description="LATIN CAPITAL LETTER K WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA740,
+ },
+ [0xA741]={
+ category="ll",
+ description="LATIN SMALL LETTER K WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA741,
+ },
+ [0xA742]={
+ category="lu",
+ description="LATIN CAPITAL LETTER K WITH DIAGONAL STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA742,
+ },
+ [0xA743]={
+ category="ll",
+ description="LATIN SMALL LETTER K WITH DIAGONAL STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA743,
+ },
+ [0xA744]={
+ category="lu",
+ description="LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA744,
+ },
+ [0xA745]={
+ category="ll",
+ description="LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA745,
+ },
+ [0xA746]={
+ category="lu",
+ description="LATIN CAPITAL LETTER BROKEN L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA746,
+ },
+ [0xA747]={
+ category="ll",
+ description="LATIN SMALL LETTER BROKEN L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA747,
+ },
+ [0xA748]={
+ category="lu",
+ description="LATIN CAPITAL LETTER L WITH HIGH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA748,
+ },
+ [0xA749]={
+ category="ll",
+ description="LATIN SMALL LETTER L WITH HIGH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA749,
+ },
+ [0xA74A]={
+ category="lu",
+ description="LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA74A,
+ },
+ [0xA74B]={
+ category="ll",
+ description="LATIN SMALL LETTER O WITH LONG STROKE OVERLAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA74B,
+ },
+ [0xA74C]={
+ category="lu",
+ description="LATIN CAPITAL LETTER O WITH LOOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA74C,
+ },
+ [0xA74D]={
+ category="ll",
+ description="LATIN SMALL LETTER O WITH LOOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA74D,
+ },
+ [0xA74E]={
+ category="lu",
+ description="LATIN CAPITAL LETTER OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA74E,
+ },
+ [0xA74F]={
+ category="ll",
+ description="LATIN SMALL LETTER OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA74F,
+ },
+ [0xA750]={
+ category="lu",
+ description="LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA750,
+ },
+ [0xA751]={
+ category="ll",
+ description="LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA751,
+ },
+ [0xA752]={
+ category="lu",
+ description="LATIN CAPITAL LETTER P WITH FLOURISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA752,
+ },
+ [0xA753]={
+ category="ll",
+ description="LATIN SMALL LETTER P WITH FLOURISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA753,
+ },
+ [0xA754]={
+ category="lu",
+ description="LATIN CAPITAL LETTER P WITH SQUIRREL TAIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA754,
+ },
+ [0xA755]={
+ category="ll",
+ description="LATIN SMALL LETTER P WITH SQUIRREL TAIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA755,
+ },
+ [0xA756]={
+ category="lu",
+ description="LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA756,
+ },
+ [0xA757]={
+ category="ll",
+ description="LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA757,
+ },
+ [0xA758]={
+ category="lu",
+ description="LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA758,
+ },
+ [0xA759]={
+ category="ll",
+ description="LATIN SMALL LETTER Q WITH DIAGONAL STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA759,
+ },
+ [0xA75A]={
+ category="lu",
+ description="LATIN CAPITAL LETTER R ROTUNDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA75A,
+ },
+ [0xA75B]={
+ category="ll",
+ description="LATIN SMALL LETTER R ROTUNDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA75B,
+ },
+ [0xA75C]={
+ category="lu",
+ description="LATIN CAPITAL LETTER RUM ROTUNDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA75C,
+ },
+ [0xA75D]={
+ category="ll",
+ description="LATIN SMALL LETTER RUM ROTUNDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA75D,
+ },
+ [0xA75E]={
+ category="lu",
+ description="LATIN CAPITAL LETTER V WITH DIAGONAL STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA75E,
+ },
+ [0xA75F]={
+ category="ll",
+ description="LATIN SMALL LETTER V WITH DIAGONAL STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA75F,
+ },
+ [0xA760]={
+ category="lu",
+ description="LATIN CAPITAL LETTER VY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA760,
+ },
+ [0xA761]={
+ category="ll",
+ description="LATIN SMALL LETTER VY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA761,
+ },
+ [0xA762]={
+ category="lu",
+ description="LATIN CAPITAL LETTER VISIGOTHIC Z",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA762,
+ },
+ [0xA763]={
+ category="ll",
+ description="LATIN SMALL LETTER VISIGOTHIC Z",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA763,
+ },
+ [0xA764]={
+ category="lu",
+ description="LATIN CAPITAL LETTER THORN WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA764,
+ },
+ [0xA765]={
+ category="ll",
+ description="LATIN SMALL LETTER THORN WITH STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA765,
+ },
+ [0xA766]={
+ category="lu",
+ description="LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA766,
+ },
+ [0xA767]={
+ category="ll",
+ description="LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA767,
+ },
+ [0xA768]={
+ category="lu",
+ description="LATIN CAPITAL LETTER VEND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA768,
+ },
+ [0xA769]={
+ category="ll",
+ description="LATIN SMALL LETTER VEND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA769,
+ },
+ [0xA76A]={
+ category="lu",
+ description="LATIN CAPITAL LETTER ET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76A,
+ },
+ [0xA76B]={
+ category="ll",
+ description="LATIN SMALL LETTER ET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76B,
+ },
+ [0xA76C]={
+ category="lu",
+ description="LATIN CAPITAL LETTER IS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76C,
+ },
+ [0xA76D]={
+ category="ll",
+ description="LATIN SMALL LETTER IS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76D,
+ },
+ [0xA76E]={
+ category="lu",
+ description="LATIN CAPITAL LETTER CON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76E,
+ },
+ [0xA76F]={
+ category="ll",
+ description="LATIN SMALL LETTER CON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA76F,
+ },
+ [0xA770]={
+ category="lm",
+ description="MODIFIER LETTER US",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0xA76F },
+ unicodeslot=0xA770,
+ },
+ [0xA771]={
+ category="ll",
+ description="LATIN SMALL LETTER DUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA771,
+ },
+ [0xA772]={
+ category="ll",
+ description="LATIN SMALL LETTER LUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA772,
+ },
+ [0xA773]={
+ category="ll",
+ description="LATIN SMALL LETTER MUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA773,
+ },
+ [0xA774]={
+ category="ll",
+ description="LATIN SMALL LETTER NUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA774,
+ },
+ [0xA775]={
+ category="ll",
+ description="LATIN SMALL LETTER RUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA775,
+ },
+ [0xA776]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL RUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA776,
+ },
+ [0xA777]={
+ category="ll",
+ description="LATIN SMALL LETTER TUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA777,
+ },
+ [0xA778]={
+ category="ll",
+ description="LATIN SMALL LETTER UM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA778,
+ },
+ [0xA779]={
+ category="lu",
+ description="LATIN CAPITAL LETTER INSULAR D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA779,
+ },
+ [0xA77A]={
+ category="ll",
+ description="LATIN SMALL LETTER INSULAR D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA77A,
+ },
+ [0xA77B]={
+ category="lu",
+ description="LATIN CAPITAL LETTER INSULAR F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA77B,
+ },
+ [0xA77C]={
+ category="ll",
+ description="LATIN SMALL LETTER INSULAR F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA77C,
+ },
+ [0xA77D]={
+ category="lu",
+ description="LATIN CAPITAL LETTER INSULAR G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA77D,
+ },
+ [0xA77E]={
+ category="lu",
+ description="LATIN CAPITAL LETTER TURNED INSULAR G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA77E,
+ },
+ [0xA77F]={
+ category="ll",
+ description="LATIN SMALL LETTER TURNED INSULAR G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA77F,
+ },
+ [0xA780]={
+ category="lu",
+ description="LATIN CAPITAL LETTER TURNED L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA780,
+ },
+ [0xA781]={
+ category="ll",
+ description="LATIN SMALL LETTER TURNED L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA781,
+ },
+ [0xA782]={
+ category="lu",
+ description="LATIN CAPITAL LETTER INSULAR R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA782,
+ },
+ [0xA783]={
+ category="ll",
+ description="LATIN SMALL LETTER INSULAR R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA783,
+ },
+ [0xA784]={
+ category="lu",
+ description="LATIN CAPITAL LETTER INSULAR S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA784,
+ },
+ [0xA785]={
+ category="ll",
+ description="LATIN SMALL LETTER INSULAR S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA785,
+ },
+ [0xA786]={
+ category="lu",
+ description="LATIN CAPITAL LETTER INSULAR T",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA786,
+ },
+ [0xA787]={
+ category="ll",
+ description="LATIN SMALL LETTER INSULAR T",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA787,
+ },
+ [0xA788]={
+ category="lm",
+ description="MODIFIER LETTER LOW CIRCUMFLEX ACCENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA788,
+ },
+ [0xA789]={
+ category="sk",
+ description="MODIFIER LETTER COLON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA789,
+ },
+ [0xA78A]={
+ category="sk",
+ description="MODIFIER LETTER SHORT EQUALS SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA78A,
+ },
+ [0xA78B]={
+ category="lu",
+ description="LATIN CAPITAL LETTER SALTILLO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA78B,
+ },
+ [0xA78C]={
+ category="ll",
+ description="LATIN SMALL LETTER SALTILLO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA78C,
+ },
+ [0xA78D]={
+ category="lu",
+ description="LATIN CAPITAL LETTER TURNED H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA78D,
+ },
+ [0xA78E]={
+ category="ll",
+ description="LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA78E,
+ },
+ [0xA790]={
+ category="lu",
+ description="LATIN CAPITAL LETTER N WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA790,
+ },
+ [0xA791]={
+ category="ll",
+ description="LATIN SMALL LETTER N WITH DESCENDER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA791,
+ },
+ [0xA792]={
+ category="lu",
+ description="LATIN CAPITAL LETTER C WITH BAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA792,
+ },
+ [0xA793]={
+ category="ll",
+ description="LATIN SMALL LETTER C WITH BAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA793,
+ },
+ [0xA7A0]={
+ category="lu",
+ description="LATIN CAPITAL LETTER G WITH OBLIQUE STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A0,
+ },
+ [0xA7A1]={
+ category="ll",
+ description="LATIN SMALL LETTER G WITH OBLIQUE STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A1,
+ },
+ [0xA7A2]={
+ category="lu",
+ description="LATIN CAPITAL LETTER K WITH OBLIQUE STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A2,
+ },
+ [0xA7A3]={
+ category="ll",
+ description="LATIN SMALL LETTER K WITH OBLIQUE STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A3,
+ },
+ [0xA7A4]={
+ category="lu",
+ description="LATIN CAPITAL LETTER N WITH OBLIQUE STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A4,
+ },
+ [0xA7A5]={
+ category="ll",
+ description="LATIN SMALL LETTER N WITH OBLIQUE STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A5,
+ },
+ [0xA7A6]={
+ category="lu",
+ description="LATIN CAPITAL LETTER R WITH OBLIQUE STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A6,
+ },
+ [0xA7A7]={
+ category="ll",
+ description="LATIN SMALL LETTER R WITH OBLIQUE STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A7,
+ },
+ [0xA7A8]={
+ category="lu",
+ description="LATIN CAPITAL LETTER S WITH OBLIQUE STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A8,
+ },
+ [0xA7A9]={
+ category="ll",
+ description="LATIN SMALL LETTER S WITH OBLIQUE STROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7A9,
+ },
+ [0xA7AA]={
+ category="lu",
+ description="LATIN CAPITAL LETTER H WITH HOOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7AA,
+ },
+ [0xA7F8]={
+ category="lm",
+ description="MODIFIER LETTER CAPITAL H WITH STROKE",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0126 },
+ unicodeslot=0xA7F8,
+ },
+ [0xA7F9]={
+ category="lm",
+ description="MODIFIER LETTER SMALL LIGATURE OE",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x0153 },
+ unicodeslot=0xA7F9,
+ },
+ [0xA7FA]={
+ category="ll",
+ description="LATIN LETTER SMALL CAPITAL TURNED M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7FA,
+ },
+ [0xA7FB]={
+ category="lo",
+ description="LATIN EPIGRAPHIC LETTER REVERSED F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7FB,
+ },
+ [0xA7FC]={
+ category="lo",
+ description="LATIN EPIGRAPHIC LETTER REVERSED P",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7FC,
+ },
+ [0xA7FD]={
+ category="lo",
+ description="LATIN EPIGRAPHIC LETTER INVERTED M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7FD,
+ },
+ [0xA7FE]={
+ category="lo",
+ description="LATIN EPIGRAPHIC LETTER I LONGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7FE,
+ },
+ [0xA7FF]={
+ category="lo",
+ description="LATIN EPIGRAPHIC LETTER ARCHAIC M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7FF,
+ },
+ [0xA800]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA800,
+ },
+ [0xA801]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA801,
+ },
+ [0xA802]={
+ category="mc",
+ description="SYLOTI NAGRI SIGN DVISVARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA802,
+ },
+ [0xA803]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA803,
+ },
+ [0xA804]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA804,
+ },
+ [0xA805]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA805,
+ },
+ [0xA806]={
+ category="mn",
+ description="SYLOTI NAGRI SIGN HASANTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA806,
+ },
+ [0xA807]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER KO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA807,
+ },
+ [0xA808]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER KHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA808,
+ },
+ [0xA809]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER GO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA809,
+ },
+ [0xA80A]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER GHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA80A,
+ },
+ [0xA80B]={
+ category="mn",
+ description="SYLOTI NAGRI SIGN ANUSVARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA80B,
+ },
+ [0xA80C]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER CO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA80C,
+ },
+ [0xA80D]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER CHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA80D,
+ },
+ [0xA80E]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER JO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA80E,
+ },
+ [0xA80F]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER JHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA80F,
+ },
+ [0xA810]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER TTO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA810,
+ },
+ [0xA811]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER TTHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA811,
+ },
+ [0xA812]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER DDO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA812,
+ },
+ [0xA813]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER DDHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA813,
+ },
+ [0xA814]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER TO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA814,
+ },
+ [0xA815]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER THO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA815,
+ },
+ [0xA816]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER DO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA816,
+ },
+ [0xA817]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER DHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA817,
+ },
+ [0xA818]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER NO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA818,
+ },
+ [0xA819]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER PO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA819,
+ },
+ [0xA81A]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER PHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA81A,
+ },
+ [0xA81B]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER BO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA81B,
+ },
+ [0xA81C]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER BHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA81C,
+ },
+ [0xA81D]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER MO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA81D,
+ },
+ [0xA81E]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER RO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA81E,
+ },
+ [0xA81F]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER LO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA81F,
+ },
+ [0xA820]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER RRO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA820,
+ },
+ [0xA821]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER SO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA821,
+ },
+ [0xA822]={
+ category="lo",
+ description="SYLOTI NAGRI LETTER HO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA822,
+ },
+ [0xA823]={
+ category="mc",
+ description="SYLOTI NAGRI VOWEL SIGN A",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA823,
+ },
+ [0xA824]={
+ category="mc",
+ description="SYLOTI NAGRI VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA824,
+ },
+ [0xA825]={
+ category="mn",
+ description="SYLOTI NAGRI VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA825,
+ },
+ [0xA826]={
+ category="mn",
+ description="SYLOTI NAGRI VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA826,
+ },
+ [0xA827]={
+ category="mc",
+ description="SYLOTI NAGRI VOWEL SIGN OO",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA827,
+ },
+ [0xA828]={
+ category="so",
+ description="SYLOTI NAGRI POETRY MARK-0x0001",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA828,
+ },
+ [0xA829]={
+ category="so",
+ description="SYLOTI NAGRI POETRY MARK-0x0002",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA829,
+ },
+ [0xA82A]={
+ category="so",
+ description="SYLOTI NAGRI POETRY MARK-0x0003",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA82A,
+ },
+ [0xA82B]={
+ category="so",
+ description="SYLOTI NAGRI POETRY MARK-0x0004",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xA82B,
+ },
+ [0xA830]={
+ category="no",
+ description="NORTH INDIC FRACTION ONE QUARTER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA830,
+ },
+ [0xA831]={
+ category="no",
+ description="NORTH INDIC FRACTION ONE HALF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA831,
+ },
+ [0xA832]={
+ category="no",
+ description="NORTH INDIC FRACTION THREE QUARTERS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA832,
+ },
+ [0xA833]={
+ category="no",
+ description="NORTH INDIC FRACTION ONE SIXTEENTH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA833,
+ },
+ [0xA834]={
+ category="no",
+ description="NORTH INDIC FRACTION ONE EIGHTH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA834,
+ },
+ [0xA835]={
+ category="no",
+ description="NORTH INDIC FRACTION THREE SIXTEENTHS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA835,
+ },
+ [0xA836]={
+ category="so",
+ description="NORTH INDIC QUARTER MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA836,
+ },
+ [0xA837]={
+ category="so",
+ description="NORTH INDIC PLACEHOLDER MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA837,
+ },
+ [0xA838]={
+ category="sc",
+ description="NORTH INDIC RUPEE MARK",
+ direction="et",
+ linebreak="po",
+ unicodeslot=0xA838,
+ },
+ [0xA839]={
+ category="so",
+ description="NORTH INDIC QUANTITY MARK",
+ direction="et",
+ linebreak="al",
+ unicodeslot=0xA839,
+ },
+ [0xA840]={
+ category="lo",
+ description="PHAGS-PA LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA840,
+ },
+ [0xA841]={
+ category="lo",
+ description="PHAGS-PA LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA841,
+ },
+ [0xA842]={
+ category="lo",
+ description="PHAGS-PA LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA842,
+ },
+ [0xA843]={
+ category="lo",
+ description="PHAGS-PA LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA843,
+ },
+ [0xA844]={
+ category="lo",
+ description="PHAGS-PA LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA844,
+ },
+ [0xA845]={
+ category="lo",
+ description="PHAGS-PA LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA845,
+ },
+ [0xA846]={
+ category="lo",
+ description="PHAGS-PA LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA846,
+ },
+ [0xA847]={
+ category="lo",
+ description="PHAGS-PA LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA847,
+ },
+ [0xA848]={
+ category="lo",
+ description="PHAGS-PA LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA848,
+ },
+ [0xA849]={
+ category="lo",
+ description="PHAGS-PA LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA849,
+ },
+ [0xA84A]={
+ category="lo",
+ description="PHAGS-PA LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA84A,
+ },
+ [0xA84B]={
+ category="lo",
+ description="PHAGS-PA LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA84B,
+ },
+ [0xA84C]={
+ category="lo",
+ description="PHAGS-PA LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA84C,
+ },
+ [0xA84D]={
+ category="lo",
+ description="PHAGS-PA LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA84D,
+ },
+ [0xA84E]={
+ category="lo",
+ description="PHAGS-PA LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA84E,
+ },
+ [0xA84F]={
+ category="lo",
+ description="PHAGS-PA LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA84F,
+ },
+ [0xA850]={
+ category="lo",
+ description="PHAGS-PA LETTER TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA850,
+ },
+ [0xA851]={
+ category="lo",
+ description="PHAGS-PA LETTER TSHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA851,
+ },
+ [0xA852]={
+ category="lo",
+ description="PHAGS-PA LETTER DZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA852,
+ },
+ [0xA853]={
+ category="lo",
+ description="PHAGS-PA LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA853,
+ },
+ [0xA854]={
+ category="lo",
+ description="PHAGS-PA LETTER ZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA854,
+ },
+ [0xA855]={
+ category="lo",
+ description="PHAGS-PA LETTER ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA855,
+ },
+ [0xA856]={
+ category="lo",
+ description="PHAGS-PA LETTER SMALL A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA856,
+ variants={
+ [0xFE00]="phags-pa letter reversed shaping small a",
+ },
+ },
+ [0xA857]={
+ category="lo",
+ description="PHAGS-PA LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA857,
+ },
+ [0xA858]={
+ category="lo",
+ description="PHAGS-PA LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA858,
+ },
+ [0xA859]={
+ category="lo",
+ description="PHAGS-PA LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA859,
+ },
+ [0xA85A]={
+ category="lo",
+ description="PHAGS-PA LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA85A,
+ },
+ [0xA85B]={
+ category="lo",
+ description="PHAGS-PA LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA85B,
+ },
+ [0xA85C]={
+ category="lo",
+ description="PHAGS-PA LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA85C,
+ variants={
+ [0xFE00]="phags-pa letter reversed shaping ha",
+ },
+ },
+ [0xA85D]={
+ category="lo",
+ description="PHAGS-PA LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA85D,
+ },
+ [0xA85E]={
+ category="lo",
+ description="PHAGS-PA LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA85E,
+ variants={
+ [0xFE00]="phags-pa letter reversed shaping i",
+ },
+ },
+ [0xA85F]={
+ category="lo",
+ description="PHAGS-PA LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA85F,
+ variants={
+ [0xFE00]="phags-pa letter reversed shaping u",
+ },
+ },
+ [0xA860]={
+ category="lo",
+ description="PHAGS-PA LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA860,
+ variants={
+ [0xFE00]="phags-pa letter reversed shaping e",
+ },
+ },
+ [0xA861]={
+ category="lo",
+ description="PHAGS-PA LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA861,
+ },
+ [0xA862]={
+ category="lo",
+ description="PHAGS-PA LETTER QA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA862,
+ },
+ [0xA863]={
+ category="lo",
+ description="PHAGS-PA LETTER XA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA863,
+ },
+ [0xA864]={
+ category="lo",
+ description="PHAGS-PA LETTER FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA864,
+ },
+ [0xA865]={
+ category="lo",
+ description="PHAGS-PA LETTER GGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA865,
+ },
+ [0xA866]={
+ category="lo",
+ description="PHAGS-PA LETTER EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA866,
+ },
+ [0xA867]={
+ category="lo",
+ description="PHAGS-PA SUBJOINED LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA867,
+ },
+ [0xA868]={
+ category="lo",
+ description="PHAGS-PA SUBJOINED LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA868,
+ variants={
+ [0xFE00]="phags-pa letter reversed shaping subjoined ya",
+ },
+ },
+ [0xA869]={
+ category="lo",
+ description="PHAGS-PA LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA869,
+ },
+ [0xA86A]={
+ category="lo",
+ description="PHAGS-PA LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA86A,
+ },
+ [0xA86B]={
+ category="lo",
+ description="PHAGS-PA LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA86B,
+ },
+ [0xA86C]={
+ category="lo",
+ description="PHAGS-PA LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA86C,
+ },
+ [0xA86D]={
+ category="lo",
+ description="PHAGS-PA LETTER ALTERNATE YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA86D,
+ },
+ [0xA86E]={
+ category="lo",
+ description="PHAGS-PA LETTER VOICELESS SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA86E,
+ },
+ [0xA86F]={
+ category="lo",
+ description="PHAGS-PA LETTER VOICED HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA86F,
+ },
+ [0xA870]={
+ category="lo",
+ description="PHAGS-PA LETTER ASPIRATED FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA870,
+ },
+ [0xA871]={
+ category="lo",
+ description="PHAGS-PA SUBJOINED LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA871,
+ },
+ [0xA872]={
+ category="lo",
+ description="PHAGS-PA SUPERFIXED LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA872,
+ },
+ [0xA873]={
+ category="lo",
+ description="PHAGS-PA LETTER CANDRABINDU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA873,
+ },
+ [0xA874]={
+ category="po",
+ description="PHAGS-PA SINGLE HEAD MARK",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0xA874,
+ },
+ [0xA875]={
+ category="po",
+ description="PHAGS-PA DOUBLE HEAD MARK",
+ direction="on",
+ linebreak="bb",
+ unicodeslot=0xA875,
+ },
+ [0xA876]={
+ category="po",
+ description="PHAGS-PA MARK SHAD",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0xA876,
+ },
+ [0xA877]={
+ category="po",
+ description="PHAGS-PA MARK DOUBLE SHAD",
+ direction="on",
+ linebreak="ex",
+ unicodeslot=0xA877,
+ },
+ [0xA880]={
+ category="mc",
+ description="SAURASHTRA SIGN ANUSVARA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA880,
+ },
+ [0xA881]={
+ category="mc",
+ description="SAURASHTRA SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA881,
+ },
+ [0xA882]={
+ category="lo",
+ description="SAURASHTRA LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA882,
+ },
+ [0xA883]={
+ category="lo",
+ description="SAURASHTRA LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA883,
+ },
+ [0xA884]={
+ category="lo",
+ description="SAURASHTRA LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA884,
+ },
+ [0xA885]={
+ category="lo",
+ description="SAURASHTRA LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA885,
+ },
+ [0xA886]={
+ category="lo",
+ description="SAURASHTRA LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA886,
+ },
+ [0xA887]={
+ category="lo",
+ description="SAURASHTRA LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA887,
+ },
+ [0xA888]={
+ category="lo",
+ description="SAURASHTRA LETTER VOCALIC R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA888,
+ },
+ [0xA889]={
+ category="lo",
+ description="SAURASHTRA LETTER VOCALIC RR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA889,
+ },
+ [0xA88A]={
+ category="lo",
+ description="SAURASHTRA LETTER VOCALIC L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA88A,
+ },
+ [0xA88B]={
+ category="lo",
+ description="SAURASHTRA LETTER VOCALIC LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA88B,
+ },
+ [0xA88C]={
+ category="lo",
+ description="SAURASHTRA LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA88C,
+ },
+ [0xA88D]={
+ category="lo",
+ description="SAURASHTRA LETTER EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA88D,
+ },
+ [0xA88E]={
+ category="lo",
+ description="SAURASHTRA LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA88E,
+ },
+ [0xA88F]={
+ category="lo",
+ description="SAURASHTRA LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA88F,
+ },
+ [0xA890]={
+ category="lo",
+ description="SAURASHTRA LETTER OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA890,
+ },
+ [0xA891]={
+ category="lo",
+ description="SAURASHTRA LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA891,
+ },
+ [0xA892]={
+ category="lo",
+ description="SAURASHTRA LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA892,
+ },
+ [0xA893]={
+ category="lo",
+ description="SAURASHTRA LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA893,
+ },
+ [0xA894]={
+ category="lo",
+ description="SAURASHTRA LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA894,
+ },
+ [0xA895]={
+ category="lo",
+ description="SAURASHTRA LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA895,
+ },
+ [0xA896]={
+ category="lo",
+ description="SAURASHTRA LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA896,
+ },
+ [0xA897]={
+ category="lo",
+ description="SAURASHTRA LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA897,
+ },
+ [0xA898]={
+ category="lo",
+ description="SAURASHTRA LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA898,
+ },
+ [0xA899]={
+ category="lo",
+ description="SAURASHTRA LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA899,
+ },
+ [0xA89A]={
+ category="lo",
+ description="SAURASHTRA LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA89A,
+ },
+ [0xA89B]={
+ category="lo",
+ description="SAURASHTRA LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA89B,
+ },
+ [0xA89C]={
+ category="lo",
+ description="SAURASHTRA LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA89C,
+ },
+ [0xA89D]={
+ category="lo",
+ description="SAURASHTRA LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA89D,
+ },
+ [0xA89E]={
+ category="lo",
+ description="SAURASHTRA LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA89E,
+ },
+ [0xA89F]={
+ category="lo",
+ description="SAURASHTRA LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA89F,
+ },
+ [0xA8A0]={
+ category="lo",
+ description="SAURASHTRA LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A0,
+ },
+ [0xA8A1]={
+ category="lo",
+ description="SAURASHTRA LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A1,
+ },
+ [0xA8A2]={
+ category="lo",
+ description="SAURASHTRA LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A2,
+ },
+ [0xA8A3]={
+ category="lo",
+ description="SAURASHTRA LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A3,
+ },
+ [0xA8A4]={
+ category="lo",
+ description="SAURASHTRA LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A4,
+ },
+ [0xA8A5]={
+ category="lo",
+ description="SAURASHTRA LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A5,
+ },
+ [0xA8A6]={
+ category="lo",
+ description="SAURASHTRA LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A6,
+ },
+ [0xA8A7]={
+ category="lo",
+ description="SAURASHTRA LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A7,
+ },
+ [0xA8A8]={
+ category="lo",
+ description="SAURASHTRA LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A8,
+ },
+ [0xA8A9]={
+ category="lo",
+ description="SAURASHTRA LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8A9,
+ },
+ [0xA8AA]={
+ category="lo",
+ description="SAURASHTRA LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8AA,
+ },
+ [0xA8AB]={
+ category="lo",
+ description="SAURASHTRA LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8AB,
+ },
+ [0xA8AC]={
+ category="lo",
+ description="SAURASHTRA LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8AC,
+ },
+ [0xA8AD]={
+ category="lo",
+ description="SAURASHTRA LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8AD,
+ },
+ [0xA8AE]={
+ category="lo",
+ description="SAURASHTRA LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8AE,
+ },
+ [0xA8AF]={
+ category="lo",
+ description="SAURASHTRA LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8AF,
+ },
+ [0xA8B0]={
+ category="lo",
+ description="SAURASHTRA LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8B0,
+ },
+ [0xA8B1]={
+ category="lo",
+ description="SAURASHTRA LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8B1,
+ },
+ [0xA8B2]={
+ category="lo",
+ description="SAURASHTRA LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8B2,
+ },
+ [0xA8B3]={
+ category="lo",
+ description="SAURASHTRA LETTER LLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8B3,
+ },
+ [0xA8B4]={
+ category="mc",
+ description="SAURASHTRA CONSONANT SIGN HAARU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8B4,
+ },
+ [0xA8B5]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8B5,
+ },
+ [0xA8B6]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8B6,
+ },
+ [0xA8B7]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8B7,
+ },
+ [0xA8B8]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN U",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8B8,
+ },
+ [0xA8B9]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN UU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8B9,
+ },
+ [0xA8BA]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN VOCALIC R",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8BA,
+ },
+ [0xA8BB]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN VOCALIC RR",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8BB,
+ },
+ [0xA8BC]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN VOCALIC L",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8BC,
+ },
+ [0xA8BD]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN VOCALIC LL",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8BD,
+ },
+ [0xA8BE]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN E",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8BE,
+ },
+ [0xA8BF]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN EE",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8BF,
+ },
+ [0xA8C0]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN AI",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8C0,
+ },
+ [0xA8C1]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8C1,
+ },
+ [0xA8C2]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN OO",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8C2,
+ },
+ [0xA8C3]={
+ category="mc",
+ description="SAURASHTRA VOWEL SIGN AU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA8C3,
+ },
+ [0xA8C4]={
+ category="mn",
+ description="SAURASHTRA SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8C4,
+ },
+ [0xA8CE]={
+ category="po",
+ description="SAURASHTRA DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA8CE,
+ },
+ [0xA8CF]={
+ category="po",
+ description="SAURASHTRA DOUBLE DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA8CF,
+ },
+ [0xA8D0]={
+ category="nd",
+ description="SAURASHTRA DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D0,
+ },
+ [0xA8D1]={
+ category="nd",
+ description="SAURASHTRA DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D1,
+ },
+ [0xA8D2]={
+ category="nd",
+ description="SAURASHTRA DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D2,
+ },
+ [0xA8D3]={
+ category="nd",
+ description="SAURASHTRA DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D3,
+ },
+ [0xA8D4]={
+ category="nd",
+ description="SAURASHTRA DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D4,
+ },
+ [0xA8D5]={
+ category="nd",
+ description="SAURASHTRA DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D5,
+ },
+ [0xA8D6]={
+ category="nd",
+ description="SAURASHTRA DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D6,
+ },
+ [0xA8D7]={
+ category="nd",
+ description="SAURASHTRA DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D7,
+ },
+ [0xA8D8]={
+ category="nd",
+ description="SAURASHTRA DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D8,
+ },
+ [0xA8D9]={
+ category="nd",
+ description="SAURASHTRA DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA8D9,
+ },
+ [0xA8E0]={
+ category="mn",
+ description="COMBINING DEVANAGARI DIGIT ZERO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8E0,
+ },
+ [0xA8E1]={
+ category="mn",
+ description="COMBINING DEVANAGARI DIGIT ONE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8E1,
+ },
+ [0xA8E2]={
+ category="mn",
+ description="COMBINING DEVANAGARI DIGIT TWO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8E2,
+ },
+ [0xA8E3]={
+ category="mn",
+ description="COMBINING DEVANAGARI DIGIT THREE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8E3,
+ },
+ [0xA8E4]={
+ category="mn",
+ description="COMBINING DEVANAGARI DIGIT FOUR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8E4,
+ },
+ [0xA8E5]={
+ category="mn",
+ description="COMBINING DEVANAGARI DIGIT FIVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8E5,
+ },
+ [0xA8E6]={
+ category="mn",
+ description="COMBINING DEVANAGARI DIGIT SIX",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8E6,
+ },
+ [0xA8E7]={
+ category="mn",
+ description="COMBINING DEVANAGARI DIGIT SEVEN",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8E7,
+ },
+ [0xA8E8]={
+ category="mn",
+ description="COMBINING DEVANAGARI DIGIT EIGHT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8E8,
+ },
+ [0xA8E9]={
+ category="mn",
+ description="COMBINING DEVANAGARI DIGIT NINE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8E9,
+ },
+ [0xA8EA]={
+ category="mn",
+ description="COMBINING DEVANAGARI LETTER A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8EA,
+ },
+ [0xA8EB]={
+ category="mn",
+ description="COMBINING DEVANAGARI LETTER U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8EB,
+ },
+ [0xA8EC]={
+ category="mn",
+ description="COMBINING DEVANAGARI LETTER KA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8EC,
+ },
+ [0xA8ED]={
+ category="mn",
+ description="COMBINING DEVANAGARI LETTER NA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8ED,
+ },
+ [0xA8EE]={
+ category="mn",
+ description="COMBINING DEVANAGARI LETTER PA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8EE,
+ },
+ [0xA8EF]={
+ category="mn",
+ description="COMBINING DEVANAGARI LETTER RA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8EF,
+ },
+ [0xA8F0]={
+ category="mn",
+ description="COMBINING DEVANAGARI LETTER VI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8F0,
+ },
+ [0xA8F1]={
+ category="mn",
+ description="COMBINING DEVANAGARI SIGN AVAGRAHA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA8F1,
+ },
+ [0xA8F2]={
+ category="lo",
+ description="DEVANAGARI SIGN SPACING CANDRABINDU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F2,
+ },
+ [0xA8F3]={
+ category="lo",
+ description="DEVANAGARI SIGN CANDRABINDU VIRAMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F3,
+ },
+ [0xA8F4]={
+ category="lo",
+ description="DEVANAGARI SIGN DOUBLE CANDRABINDU VIRAMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F4,
+ },
+ [0xA8F5]={
+ category="lo",
+ description="DEVANAGARI SIGN CANDRABINDU TWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F5,
+ },
+ [0xA8F6]={
+ category="lo",
+ description="DEVANAGARI SIGN CANDRABINDU THREE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F6,
+ },
+ [0xA8F7]={
+ category="lo",
+ description="DEVANAGARI SIGN CANDRABINDU AVAGRAHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F7,
+ },
+ [0xA8F8]={
+ category="po",
+ description="DEVANAGARI SIGN PUSHPIKA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F8,
+ },
+ [0xA8F9]={
+ category="po",
+ description="DEVANAGARI GAP FILLER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8F9,
+ },
+ [0xA8FA]={
+ category="po",
+ description="DEVANAGARI CARET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8FA,
+ },
+ [0xA8FB]={
+ category="lo",
+ description="DEVANAGARI HEADSTROKE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA8FB,
+ },
+ [0xA900]={
+ category="nd",
+ description="KAYAH LI DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA900,
+ },
+ [0xA901]={
+ category="nd",
+ description="KAYAH LI DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA901,
+ },
+ [0xA902]={
+ category="nd",
+ description="KAYAH LI DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA902,
+ },
+ [0xA903]={
+ category="nd",
+ description="KAYAH LI DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA903,
+ },
+ [0xA904]={
+ category="nd",
+ description="KAYAH LI DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA904,
+ },
+ [0xA905]={
+ category="nd",
+ description="KAYAH LI DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA905,
+ },
+ [0xA906]={
+ category="nd",
+ description="KAYAH LI DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA906,
+ },
+ [0xA907]={
+ category="nd",
+ description="KAYAH LI DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA907,
+ },
+ [0xA908]={
+ category="nd",
+ description="KAYAH LI DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA908,
+ },
+ [0xA909]={
+ category="nd",
+ description="KAYAH LI DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA909,
+ },
+ [0xA90A]={
+ category="lo",
+ description="KAYAH LI LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA90A,
+ },
+ [0xA90B]={
+ category="lo",
+ description="KAYAH LI LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA90B,
+ },
+ [0xA90C]={
+ category="lo",
+ description="KAYAH LI LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA90C,
+ },
+ [0xA90D]={
+ category="lo",
+ description="KAYAH LI LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA90D,
+ },
+ [0xA90E]={
+ category="lo",
+ description="KAYAH LI LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA90E,
+ },
+ [0xA90F]={
+ category="lo",
+ description="KAYAH LI LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA90F,
+ },
+ [0xA910]={
+ category="lo",
+ description="KAYAH LI LETTER ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA910,
+ },
+ [0xA911]={
+ category="lo",
+ description="KAYAH LI LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA911,
+ },
+ [0xA912]={
+ category="lo",
+ description="KAYAH LI LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA912,
+ },
+ [0xA913]={
+ category="lo",
+ description="KAYAH LI LETTER HTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA913,
+ },
+ [0xA914]={
+ category="lo",
+ description="KAYAH LI LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA914,
+ },
+ [0xA915]={
+ category="lo",
+ description="KAYAH LI LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA915,
+ },
+ [0xA916]={
+ category="lo",
+ description="KAYAH LI LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA916,
+ },
+ [0xA917]={
+ category="lo",
+ description="KAYAH LI LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA917,
+ },
+ [0xA918]={
+ category="lo",
+ description="KAYAH LI LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA918,
+ },
+ [0xA919]={
+ category="lo",
+ description="KAYAH LI LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA919,
+ },
+ [0xA91A]={
+ category="lo",
+ description="KAYAH LI LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA91A,
+ },
+ [0xA91B]={
+ category="lo",
+ description="KAYAH LI LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA91B,
+ },
+ [0xA91C]={
+ category="lo",
+ description="KAYAH LI LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA91C,
+ },
+ [0xA91D]={
+ category="lo",
+ description="KAYAH LI LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA91D,
+ },
+ [0xA91E]={
+ category="lo",
+ description="KAYAH LI LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA91E,
+ },
+ [0xA91F]={
+ category="lo",
+ description="KAYAH LI LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA91F,
+ },
+ [0xA920]={
+ category="lo",
+ description="KAYAH LI LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA920,
+ },
+ [0xA921]={
+ category="lo",
+ description="KAYAH LI LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA921,
+ },
+ [0xA922]={
+ category="lo",
+ description="KAYAH LI LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA922,
+ },
+ [0xA923]={
+ category="lo",
+ description="KAYAH LI LETTER OE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA923,
+ },
+ [0xA924]={
+ category="lo",
+ description="KAYAH LI LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA924,
+ },
+ [0xA925]={
+ category="lo",
+ description="KAYAH LI LETTER OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA925,
+ },
+ [0xA926]={
+ category="mn",
+ description="KAYAH LI VOWEL UE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA926,
+ },
+ [0xA927]={
+ category="mn",
+ description="KAYAH LI VOWEL E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA927,
+ },
+ [0xA928]={
+ category="mn",
+ description="KAYAH LI VOWEL U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA928,
+ },
+ [0xA929]={
+ category="mn",
+ description="KAYAH LI VOWEL EE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA929,
+ },
+ [0xA92A]={
+ category="mn",
+ description="KAYAH LI VOWEL O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA92A,
+ },
+ [0xA92B]={
+ category="mn",
+ description="KAYAH LI TONE PLOPHU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA92B,
+ },
+ [0xA92C]={
+ category="mn",
+ description="KAYAH LI TONE CALYA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA92C,
+ },
+ [0xA92D]={
+ category="mn",
+ description="KAYAH LI TONE CALYA PLOPHU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA92D,
+ },
+ [0xA92E]={
+ category="po",
+ description="KAYAH LI SIGN CWI",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA92E,
+ },
+ [0xA92F]={
+ category="po",
+ description="KAYAH LI SIGN SHYA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA92F,
+ },
+ [0xA930]={
+ category="lo",
+ description="REJANG LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA930,
+ },
+ [0xA931]={
+ category="lo",
+ description="REJANG LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA931,
+ },
+ [0xA932]={
+ category="lo",
+ description="REJANG LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA932,
+ },
+ [0xA933]={
+ category="lo",
+ description="REJANG LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA933,
+ },
+ [0xA934]={
+ category="lo",
+ description="REJANG LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA934,
+ },
+ [0xA935]={
+ category="lo",
+ description="REJANG LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA935,
+ },
+ [0xA936]={
+ category="lo",
+ description="REJANG LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA936,
+ },
+ [0xA937]={
+ category="lo",
+ description="REJANG LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA937,
+ },
+ [0xA938]={
+ category="lo",
+ description="REJANG LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA938,
+ },
+ [0xA939]={
+ category="lo",
+ description="REJANG LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA939,
+ },
+ [0xA93A]={
+ category="lo",
+ description="REJANG LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA93A,
+ },
+ [0xA93B]={
+ category="lo",
+ description="REJANG LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA93B,
+ },
+ [0xA93C]={
+ category="lo",
+ description="REJANG LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA93C,
+ },
+ [0xA93D]={
+ category="lo",
+ description="REJANG LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA93D,
+ },
+ [0xA93E]={
+ category="lo",
+ description="REJANG LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA93E,
+ },
+ [0xA93F]={
+ category="lo",
+ description="REJANG LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA93F,
+ },
+ [0xA940]={
+ category="lo",
+ description="REJANG LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA940,
+ },
+ [0xA941]={
+ category="lo",
+ description="REJANG LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA941,
+ },
+ [0xA942]={
+ category="lo",
+ description="REJANG LETTER MBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA942,
+ },
+ [0xA943]={
+ category="lo",
+ description="REJANG LETTER NGGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA943,
+ },
+ [0xA944]={
+ category="lo",
+ description="REJANG LETTER NDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA944,
+ },
+ [0xA945]={
+ category="lo",
+ description="REJANG LETTER NYJA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA945,
+ },
+ [0xA946]={
+ category="lo",
+ description="REJANG LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA946,
+ },
+ [0xA947]={
+ category="mn",
+ description="REJANG VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA947,
+ },
+ [0xA948]={
+ category="mn",
+ description="REJANG VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA948,
+ },
+ [0xA949]={
+ category="mn",
+ description="REJANG VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA949,
+ },
+ [0xA94A]={
+ category="mn",
+ description="REJANG VOWEL SIGN AI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA94A,
+ },
+ [0xA94B]={
+ category="mn",
+ description="REJANG VOWEL SIGN O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA94B,
+ },
+ [0xA94C]={
+ category="mn",
+ description="REJANG VOWEL SIGN AU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA94C,
+ },
+ [0xA94D]={
+ category="mn",
+ description="REJANG VOWEL SIGN EU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA94D,
+ },
+ [0xA94E]={
+ category="mn",
+ description="REJANG VOWEL SIGN EA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA94E,
+ },
+ [0xA94F]={
+ category="mn",
+ description="REJANG CONSONANT SIGN NG",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA94F,
+ },
+ [0xA950]={
+ category="mn",
+ description="REJANG CONSONANT SIGN N",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA950,
+ },
+ [0xA951]={
+ category="mn",
+ description="REJANG CONSONANT SIGN R",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA951,
+ },
+ [0xA952]={
+ category="mc",
+ description="REJANG CONSONANT SIGN H",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA952,
+ },
+ [0xA953]={
+ category="mc",
+ description="REJANG VIRAMA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA953,
+ },
+ [0xA95F]={
+ category="po",
+ description="REJANG SECTION MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA95F,
+ },
+ [0xA960]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG TIKEUT-MIEUM",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA960,
+ },
+ [0xA961]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG TIKEUT-PIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA961,
+ },
+ [0xA962]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG TIKEUT-SIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA962,
+ },
+ [0xA963]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG TIKEUT-CIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA963,
+ },
+ [0xA964]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-KIYEOK",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA964,
+ },
+ [0xA965]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-SSANGKIYEOK",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA965,
+ },
+ [0xA966]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-TIKEUT",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA966,
+ },
+ [0xA967]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-SSANGTIKEUT",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA967,
+ },
+ [0xA968]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-MIEUM",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA968,
+ },
+ [0xA969]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-PIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA969,
+ },
+ [0xA96A]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-SSANGPIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA96A,
+ },
+ [0xA96B]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-KAPYEOUNPIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA96B,
+ },
+ [0xA96C]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-SIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA96C,
+ },
+ [0xA96D]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-CIEUC",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA96D,
+ },
+ [0xA96E]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG RIEUL-KHIEUKH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA96E,
+ },
+ [0xA96F]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG MIEUM-KIYEOK",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA96F,
+ },
+ [0xA970]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG MIEUM-TIKEUT",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA970,
+ },
+ [0xA971]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG MIEUM-SIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA971,
+ },
+ [0xA972]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-SIOS-THIEUTH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA972,
+ },
+ [0xA973]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-KHIEUKH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA973,
+ },
+ [0xA974]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PIEUP-HIEUH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA974,
+ },
+ [0xA975]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGSIOS-PIEUP",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA975,
+ },
+ [0xA976]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG-RIEUL",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA976,
+ },
+ [0xA977]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG IEUNG-HIEUH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA977,
+ },
+ [0xA978]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGCIEUC-HIEUH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA978,
+ },
+ [0xA979]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGTHIEUTH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA979,
+ },
+ [0xA97A]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG PHIEUPH-HIEUH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA97A,
+ },
+ [0xA97B]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG HIEUH-SIOS",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA97B,
+ },
+ [0xA97C]={
+ category="lo",
+ cjkwd="w",
+ description="HANGUL CHOSEONG SSANGYEORINHIEUH",
+ direction="l",
+ linebreak="jl",
+ unicodeslot=0xA97C,
+ },
+ [0xA980]={
+ category="mn",
+ description="JAVANESE SIGN PANYANGGA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA980,
+ },
+ [0xA981]={
+ category="mn",
+ description="JAVANESE SIGN CECAK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA981,
+ },
+ [0xA982]={
+ category="mn",
+ description="JAVANESE SIGN LAYAR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA982,
+ },
+ [0xA983]={
+ category="mc",
+ description="JAVANESE SIGN WIGNYAN",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA983,
+ },
+ [0xA984]={
+ category="lo",
+ description="JAVANESE LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA984,
+ },
+ [0xA985]={
+ category="lo",
+ description="JAVANESE LETTER I KAWI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA985,
+ },
+ [0xA986]={
+ category="lo",
+ description="JAVANESE LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA986,
+ },
+ [0xA987]={
+ category="lo",
+ description="JAVANESE LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA987,
+ },
+ [0xA988]={
+ category="lo",
+ description="JAVANESE LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA988,
+ },
+ [0xA989]={
+ category="lo",
+ description="JAVANESE LETTER PA CEREK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA989,
+ },
+ [0xA98A]={
+ category="lo",
+ description="JAVANESE LETTER NGA LELET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA98A,
+ },
+ [0xA98B]={
+ category="lo",
+ description="JAVANESE LETTER NGA LELET RASWADI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA98B,
+ },
+ [0xA98C]={
+ category="lo",
+ description="JAVANESE LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA98C,
+ },
+ [0xA98D]={
+ category="lo",
+ description="JAVANESE LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA98D,
+ },
+ [0xA98E]={
+ category="lo",
+ description="JAVANESE LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA98E,
+ },
+ [0xA98F]={
+ category="lo",
+ description="JAVANESE LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA98F,
+ },
+ [0xA990]={
+ category="lo",
+ description="JAVANESE LETTER KA SASAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA990,
+ },
+ [0xA991]={
+ category="lo",
+ description="JAVANESE LETTER KA MURDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA991,
+ },
+ [0xA992]={
+ category="lo",
+ description="JAVANESE LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA992,
+ },
+ [0xA993]={
+ category="lo",
+ description="JAVANESE LETTER GA MURDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA993,
+ },
+ [0xA994]={
+ category="lo",
+ description="JAVANESE LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA994,
+ },
+ [0xA995]={
+ category="lo",
+ description="JAVANESE LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA995,
+ },
+ [0xA996]={
+ category="lo",
+ description="JAVANESE LETTER CA MURDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA996,
+ },
+ [0xA997]={
+ category="lo",
+ description="JAVANESE LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA997,
+ },
+ [0xA998]={
+ category="lo",
+ description="JAVANESE LETTER NYA MURDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA998,
+ },
+ [0xA999]={
+ category="lo",
+ description="JAVANESE LETTER JA MAHAPRANA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA999,
+ },
+ [0xA99A]={
+ category="lo",
+ description="JAVANESE LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA99A,
+ },
+ [0xA99B]={
+ category="lo",
+ description="JAVANESE LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA99B,
+ },
+ [0xA99C]={
+ category="lo",
+ description="JAVANESE LETTER TTA MAHAPRANA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA99C,
+ },
+ [0xA99D]={
+ category="lo",
+ description="JAVANESE LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA99D,
+ },
+ [0xA99E]={
+ category="lo",
+ description="JAVANESE LETTER DDA MAHAPRANA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA99E,
+ },
+ [0xA99F]={
+ category="lo",
+ description="JAVANESE LETTER NA MURDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA99F,
+ },
+ [0xA9A0]={
+ category="lo",
+ description="JAVANESE LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A0,
+ },
+ [0xA9A1]={
+ category="lo",
+ description="JAVANESE LETTER TA MURDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A1,
+ },
+ [0xA9A2]={
+ category="lo",
+ description="JAVANESE LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A2,
+ },
+ [0xA9A3]={
+ category="lo",
+ description="JAVANESE LETTER DA MAHAPRANA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A3,
+ },
+ [0xA9A4]={
+ category="lo",
+ description="JAVANESE LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A4,
+ },
+ [0xA9A5]={
+ category="lo",
+ description="JAVANESE LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A5,
+ },
+ [0xA9A6]={
+ category="lo",
+ description="JAVANESE LETTER PA MURDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A6,
+ },
+ [0xA9A7]={
+ category="lo",
+ description="JAVANESE LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A7,
+ },
+ [0xA9A8]={
+ category="lo",
+ description="JAVANESE LETTER BA MURDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A8,
+ },
+ [0xA9A9]={
+ category="lo",
+ description="JAVANESE LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9A9,
+ },
+ [0xA9AA]={
+ category="lo",
+ description="JAVANESE LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9AA,
+ },
+ [0xA9AB]={
+ category="lo",
+ description="JAVANESE LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9AB,
+ },
+ [0xA9AC]={
+ category="lo",
+ description="JAVANESE LETTER RA AGUNG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9AC,
+ },
+ [0xA9AD]={
+ category="lo",
+ description="JAVANESE LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9AD,
+ },
+ [0xA9AE]={
+ category="lo",
+ description="JAVANESE LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9AE,
+ },
+ [0xA9AF]={
+ category="lo",
+ description="JAVANESE LETTER SA MURDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9AF,
+ },
+ [0xA9B0]={
+ category="lo",
+ description="JAVANESE LETTER SA MAHAPRANA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9B0,
+ },
+ [0xA9B1]={
+ category="lo",
+ description="JAVANESE LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9B1,
+ },
+ [0xA9B2]={
+ category="lo",
+ description="JAVANESE LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9B2,
+ },
+ [0xA9B3]={
+ category="mn",
+ description="JAVANESE SIGN CECAK TELU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9B3,
+ },
+ [0xA9B4]={
+ category="mc",
+ description="JAVANESE VOWEL SIGN TARUNG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9B4,
+ },
+ [0xA9B5]={
+ category="mc",
+ description="JAVANESE VOWEL SIGN TOLONG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9B5,
+ },
+ [0xA9B6]={
+ category="mn",
+ description="JAVANESE VOWEL SIGN WULU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9B6,
+ },
+ [0xA9B7]={
+ category="mn",
+ description="JAVANESE VOWEL SIGN WULU MELIK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9B7,
+ },
+ [0xA9B8]={
+ category="mn",
+ description="JAVANESE VOWEL SIGN SUKU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9B8,
+ },
+ [0xA9B9]={
+ category="mn",
+ description="JAVANESE VOWEL SIGN SUKU MENDUT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9B9,
+ },
+ [0xA9BA]={
+ category="mc",
+ description="JAVANESE VOWEL SIGN TALING",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9BA,
+ },
+ [0xA9BB]={
+ category="mc",
+ description="JAVANESE VOWEL SIGN DIRGA MURE",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9BB,
+ },
+ [0xA9BC]={
+ category="mn",
+ description="JAVANESE VOWEL SIGN PEPET",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA9BC,
+ },
+ [0xA9BD]={
+ category="mc",
+ description="JAVANESE CONSONANT SIGN KERET",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9BD,
+ },
+ [0xA9BE]={
+ category="mc",
+ description="JAVANESE CONSONANT SIGN PENGKAL",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9BE,
+ },
+ [0xA9BF]={
+ category="mc",
+ description="JAVANESE CONSONANT SIGN CAKRA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9BF,
+ },
+ [0xA9C0]={
+ category="mc",
+ description="JAVANESE PANGKON",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xA9C0,
+ },
+ [0xA9C1]={
+ category="po",
+ description="JAVANESE LEFT RERENGGAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9C1,
+ },
+ [0xA9C2]={
+ category="po",
+ description="JAVANESE RIGHT RERENGGAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9C2,
+ },
+ [0xA9C3]={
+ category="po",
+ description="JAVANESE PADA ANDAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9C3,
+ },
+ [0xA9C4]={
+ category="po",
+ description="JAVANESE PADA MADYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9C4,
+ },
+ [0xA9C5]={
+ category="po",
+ description="JAVANESE PADA LUHUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9C5,
+ },
+ [0xA9C6]={
+ category="po",
+ description="JAVANESE PADA WINDU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9C6,
+ },
+ [0xA9C7]={
+ category="po",
+ description="JAVANESE PADA PANGKAT",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA9C7,
+ },
+ [0xA9C8]={
+ category="po",
+ description="JAVANESE PADA LINGSA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA9C8,
+ },
+ [0xA9C9]={
+ category="po",
+ description="JAVANESE PADA LUNGSI",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xA9C9,
+ },
+ [0xA9CA]={
+ category="po",
+ description="JAVANESE PADA ADEG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9CA,
+ },
+ [0xA9CB]={
+ category="po",
+ description="JAVANESE PADA ADEG ADEG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9CB,
+ },
+ [0xA9CC]={
+ category="po",
+ description="JAVANESE PADA PISELEH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9CC,
+ },
+ [0xA9CD]={
+ category="po",
+ description="JAVANESE TURNED PADA PISELEH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9CD,
+ },
+ [0xA9CF]={
+ category="lm",
+ description="JAVANESE PANGRANGKEP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9CF,
+ },
+ [0xA9D0]={
+ category="nd",
+ description="JAVANESE DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D0,
+ },
+ [0xA9D1]={
+ category="nd",
+ description="JAVANESE DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D1,
+ },
+ [0xA9D2]={
+ category="nd",
+ description="JAVANESE DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D2,
+ },
+ [0xA9D3]={
+ category="nd",
+ description="JAVANESE DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D3,
+ },
+ [0xA9D4]={
+ category="nd",
+ description="JAVANESE DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D4,
+ },
+ [0xA9D5]={
+ category="nd",
+ description="JAVANESE DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D5,
+ },
+ [0xA9D6]={
+ category="nd",
+ description="JAVANESE DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D6,
+ },
+ [0xA9D7]={
+ category="nd",
+ description="JAVANESE DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D7,
+ },
+ [0xA9D8]={
+ category="nd",
+ description="JAVANESE DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D8,
+ },
+ [0xA9D9]={
+ category="nd",
+ description="JAVANESE DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xA9D9,
+ },
+ [0xA9DE]={
+ category="po",
+ description="JAVANESE PADA TIRTA TUMETES",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9DE,
+ },
+ [0xA9DF]={
+ category="po",
+ description="JAVANESE PADA ISEN-ISEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA9DF,
+ },
+ [0xAA00]={
+ category="lo",
+ description="CHAM LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA00,
+ },
+ [0xAA01]={
+ category="lo",
+ description="CHAM LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA01,
+ },
+ [0xAA02]={
+ category="lo",
+ description="CHAM LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA02,
+ },
+ [0xAA03]={
+ category="lo",
+ description="CHAM LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA03,
+ },
+ [0xAA04]={
+ category="lo",
+ description="CHAM LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA04,
+ },
+ [0xAA05]={
+ category="lo",
+ description="CHAM LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA05,
+ },
+ [0xAA06]={
+ category="lo",
+ description="CHAM LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA06,
+ },
+ [0xAA07]={
+ category="lo",
+ description="CHAM LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA07,
+ },
+ [0xAA08]={
+ category="lo",
+ description="CHAM LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA08,
+ },
+ [0xAA09]={
+ category="lo",
+ description="CHAM LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA09,
+ },
+ [0xAA0A]={
+ category="lo",
+ description="CHAM LETTER NGUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA0A,
+ },
+ [0xAA0B]={
+ category="lo",
+ description="CHAM LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA0B,
+ },
+ [0xAA0C]={
+ category="lo",
+ description="CHAM LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA0C,
+ },
+ [0xAA0D]={
+ category="lo",
+ description="CHAM LETTER CHHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA0D,
+ },
+ [0xAA0E]={
+ category="lo",
+ description="CHAM LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA0E,
+ },
+ [0xAA0F]={
+ category="lo",
+ description="CHAM LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA0F,
+ },
+ [0xAA10]={
+ category="lo",
+ description="CHAM LETTER NHUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA10,
+ },
+ [0xAA11]={
+ category="lo",
+ description="CHAM LETTER NHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA11,
+ },
+ [0xAA12]={
+ category="lo",
+ description="CHAM LETTER NHJA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA12,
+ },
+ [0xAA13]={
+ category="lo",
+ description="CHAM LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA13,
+ },
+ [0xAA14]={
+ category="lo",
+ description="CHAM LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA14,
+ },
+ [0xAA15]={
+ category="lo",
+ description="CHAM LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA15,
+ },
+ [0xAA16]={
+ category="lo",
+ description="CHAM LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA16,
+ },
+ [0xAA17]={
+ category="lo",
+ description="CHAM LETTER NUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA17,
+ },
+ [0xAA18]={
+ category="lo",
+ description="CHAM LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA18,
+ },
+ [0xAA19]={
+ category="lo",
+ description="CHAM LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA19,
+ },
+ [0xAA1A]={
+ category="lo",
+ description="CHAM LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA1A,
+ },
+ [0xAA1B]={
+ category="lo",
+ description="CHAM LETTER PPA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA1B,
+ },
+ [0xAA1C]={
+ category="lo",
+ description="CHAM LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA1C,
+ },
+ [0xAA1D]={
+ category="lo",
+ description="CHAM LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA1D,
+ },
+ [0xAA1E]={
+ category="lo",
+ description="CHAM LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA1E,
+ },
+ [0xAA1F]={
+ category="lo",
+ description="CHAM LETTER MUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA1F,
+ },
+ [0xAA20]={
+ category="lo",
+ description="CHAM LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA20,
+ },
+ [0xAA21]={
+ category="lo",
+ description="CHAM LETTER BBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA21,
+ },
+ [0xAA22]={
+ category="lo",
+ description="CHAM LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA22,
+ },
+ [0xAA23]={
+ category="lo",
+ description="CHAM LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA23,
+ },
+ [0xAA24]={
+ category="lo",
+ description="CHAM LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA24,
+ },
+ [0xAA25]={
+ category="lo",
+ description="CHAM LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA25,
+ },
+ [0xAA26]={
+ category="lo",
+ description="CHAM LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA26,
+ },
+ [0xAA27]={
+ category="lo",
+ description="CHAM LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA27,
+ },
+ [0xAA28]={
+ category="lo",
+ description="CHAM LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA28,
+ },
+ [0xAA29]={
+ category="mn",
+ description="CHAM VOWEL SIGN AA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA29,
+ },
+ [0xAA2A]={
+ category="mn",
+ description="CHAM VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA2A,
+ },
+ [0xAA2B]={
+ category="mn",
+ description="CHAM VOWEL SIGN II",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA2B,
+ },
+ [0xAA2C]={
+ category="mn",
+ description="CHAM VOWEL SIGN EI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA2C,
+ },
+ [0xAA2D]={
+ category="mn",
+ description="CHAM VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA2D,
+ },
+ [0xAA2E]={
+ category="mn",
+ description="CHAM VOWEL SIGN OE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA2E,
+ },
+ [0xAA2F]={
+ category="mc",
+ description="CHAM VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAA2F,
+ },
+ [0xAA30]={
+ category="mc",
+ description="CHAM VOWEL SIGN AI",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAA30,
+ },
+ [0xAA31]={
+ category="mn",
+ description="CHAM VOWEL SIGN AU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA31,
+ },
+ [0xAA32]={
+ category="mn",
+ description="CHAM VOWEL SIGN UE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA32,
+ },
+ [0xAA33]={
+ category="mc",
+ description="CHAM CONSONANT SIGN YA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAA33,
+ },
+ [0xAA34]={
+ category="mc",
+ description="CHAM CONSONANT SIGN RA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAA34,
+ },
+ [0xAA35]={
+ category="mn",
+ description="CHAM CONSONANT SIGN LA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA35,
+ },
+ [0xAA36]={
+ category="mn",
+ description="CHAM CONSONANT SIGN WA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA36,
+ },
+ [0xAA40]={
+ category="lo",
+ description="CHAM LETTER FINAL K",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA40,
+ },
+ [0xAA41]={
+ category="lo",
+ description="CHAM LETTER FINAL G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA41,
+ },
+ [0xAA42]={
+ category="lo",
+ description="CHAM LETTER FINAL NG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA42,
+ },
+ [0xAA43]={
+ category="mn",
+ description="CHAM CONSONANT SIGN FINAL NG",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA43,
+ },
+ [0xAA44]={
+ category="lo",
+ description="CHAM LETTER FINAL CH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA44,
+ },
+ [0xAA45]={
+ category="lo",
+ description="CHAM LETTER FINAL T",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA45,
+ },
+ [0xAA46]={
+ category="lo",
+ description="CHAM LETTER FINAL N",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA46,
+ },
+ [0xAA47]={
+ category="lo",
+ description="CHAM LETTER FINAL P",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA47,
+ },
+ [0xAA48]={
+ category="lo",
+ description="CHAM LETTER FINAL Y",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA48,
+ },
+ [0xAA49]={
+ category="lo",
+ description="CHAM LETTER FINAL R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA49,
+ },
+ [0xAA4A]={
+ category="lo",
+ description="CHAM LETTER FINAL L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA4A,
+ },
+ [0xAA4B]={
+ category="lo",
+ description="CHAM LETTER FINAL SS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA4B,
+ },
+ [0xAA4C]={
+ category="mn",
+ description="CHAM CONSONANT SIGN FINAL M",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAA4C,
+ },
+ [0xAA4D]={
+ category="mc",
+ description="CHAM CONSONANT SIGN FINAL H",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAA4D,
+ },
+ [0xAA50]={
+ category="nd",
+ description="CHAM DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA50,
+ },
+ [0xAA51]={
+ category="nd",
+ description="CHAM DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA51,
+ },
+ [0xAA52]={
+ category="nd",
+ description="CHAM DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA52,
+ },
+ [0xAA53]={
+ category="nd",
+ description="CHAM DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA53,
+ },
+ [0xAA54]={
+ category="nd",
+ description="CHAM DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA54,
+ },
+ [0xAA55]={
+ category="nd",
+ description="CHAM DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA55,
+ },
+ [0xAA56]={
+ category="nd",
+ description="CHAM DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA56,
+ },
+ [0xAA57]={
+ category="nd",
+ description="CHAM DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA57,
+ },
+ [0xAA58]={
+ category="nd",
+ description="CHAM DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA58,
+ },
+ [0xAA59]={
+ category="nd",
+ description="CHAM DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xAA59,
+ },
+ [0xAA5C]={
+ category="po",
+ description="CHAM PUNCTUATION SPIRAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAA5C,
+ },
+ [0xAA5D]={
+ category="po",
+ description="CHAM PUNCTUATION DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xAA5D,
+ },
+ [0xAA5E]={
+ category="po",
+ description="CHAM PUNCTUATION DOUBLE DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xAA5E,
+ },
+ [0xAA5F]={
+ category="po",
+ description="CHAM PUNCTUATION TRIPLE DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xAA5F,
+ },
+ [0xAA60]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI GA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA60,
+ },
+ [0xAA61]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI CA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA61,
+ },
+ [0xAA62]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI CHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA62,
+ },
+ [0xAA63]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI JA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA63,
+ },
+ [0xAA64]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI JHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA64,
+ },
+ [0xAA65]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI NYA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA65,
+ },
+ [0xAA66]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI TTA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA66,
+ },
+ [0xAA67]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI TTHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA67,
+ },
+ [0xAA68]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI DDA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA68,
+ },
+ [0xAA69]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI DDHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA69,
+ },
+ [0xAA6A]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI DHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA6A,
+ },
+ [0xAA6B]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI NA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA6B,
+ },
+ [0xAA6C]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI SA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA6C,
+ },
+ [0xAA6D]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI HA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA6D,
+ },
+ [0xAA6E]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI HHA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA6E,
+ },
+ [0xAA6F]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI FA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA6F,
+ },
+ [0xAA70]={
+ category="lm",
+ description="MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA70,
+ },
+ [0xAA71]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI XA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA71,
+ },
+ [0xAA72]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI ZA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA72,
+ },
+ [0xAA73]={
+ category="lo",
+ description="MYANMAR LETTER KHAMTI RA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA73,
+ },
+ [0xAA74]={
+ category="lo",
+ description="MYANMAR LOGOGRAM KHAMTI OAY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA74,
+ },
+ [0xAA75]={
+ category="lo",
+ description="MYANMAR LOGOGRAM KHAMTI QN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA75,
+ },
+ [0xAA76]={
+ category="lo",
+ description="MYANMAR LOGOGRAM KHAMTI HM",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA76,
+ },
+ [0xAA77]={
+ category="so",
+ description="MYANMAR SYMBOL AITON EXCLAMATION",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA77,
+ },
+ [0xAA78]={
+ category="so",
+ description="MYANMAR SYMBOL AITON ONE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA78,
+ },
+ [0xAA79]={
+ category="so",
+ description="MYANMAR SYMBOL AITON TWO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA79,
+ },
+ [0xAA7A]={
+ category="lo",
+ description="MYANMAR LETTER AITON RA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA7A,
+ },
+ [0xAA7B]={
+ category="mc",
+ description="MYANMAR SIGN PAO KAREN TONE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA7B,
+ },
+ [0xAA80]={
+ category="lo",
+ description="TAI VIET LETTER LOW KO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA80,
+ },
+ [0xAA81]={
+ category="lo",
+ description="TAI VIET LETTER HIGH KO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA81,
+ },
+ [0xAA82]={
+ category="lo",
+ description="TAI VIET LETTER LOW KHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA82,
+ },
+ [0xAA83]={
+ category="lo",
+ description="TAI VIET LETTER HIGH KHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA83,
+ },
+ [0xAA84]={
+ category="lo",
+ description="TAI VIET LETTER LOW KHHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA84,
+ },
+ [0xAA85]={
+ category="lo",
+ description="TAI VIET LETTER HIGH KHHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA85,
+ },
+ [0xAA86]={
+ category="lo",
+ description="TAI VIET LETTER LOW GO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA86,
+ },
+ [0xAA87]={
+ category="lo",
+ description="TAI VIET LETTER HIGH GO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA87,
+ },
+ [0xAA88]={
+ category="lo",
+ description="TAI VIET LETTER LOW NGO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA88,
+ },
+ [0xAA89]={
+ category="lo",
+ description="TAI VIET LETTER HIGH NGO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA89,
+ },
+ [0xAA8A]={
+ category="lo",
+ description="TAI VIET LETTER LOW CO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA8A,
+ },
+ [0xAA8B]={
+ category="lo",
+ description="TAI VIET LETTER HIGH CO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA8B,
+ },
+ [0xAA8C]={
+ category="lo",
+ description="TAI VIET LETTER LOW CHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA8C,
+ },
+ [0xAA8D]={
+ category="lo",
+ description="TAI VIET LETTER HIGH CHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA8D,
+ },
+ [0xAA8E]={
+ category="lo",
+ description="TAI VIET LETTER LOW SO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA8E,
+ },
+ [0xAA8F]={
+ category="lo",
+ description="TAI VIET LETTER HIGH SO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA8F,
+ },
+ [0xAA90]={
+ category="lo",
+ description="TAI VIET LETTER LOW NYO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA90,
+ },
+ [0xAA91]={
+ category="lo",
+ description="TAI VIET LETTER HIGH NYO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA91,
+ },
+ [0xAA92]={
+ category="lo",
+ description="TAI VIET LETTER LOW DO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA92,
+ },
+ [0xAA93]={
+ category="lo",
+ description="TAI VIET LETTER HIGH DO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA93,
+ },
+ [0xAA94]={
+ category="lo",
+ description="TAI VIET LETTER LOW TO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA94,
+ },
+ [0xAA95]={
+ category="lo",
+ description="TAI VIET LETTER HIGH TO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA95,
+ },
+ [0xAA96]={
+ category="lo",
+ description="TAI VIET LETTER LOW THO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA96,
+ },
+ [0xAA97]={
+ category="lo",
+ description="TAI VIET LETTER HIGH THO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA97,
+ },
+ [0xAA98]={
+ category="lo",
+ description="TAI VIET LETTER LOW NO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA98,
+ },
+ [0xAA99]={
+ category="lo",
+ description="TAI VIET LETTER HIGH NO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA99,
+ },
+ [0xAA9A]={
+ category="lo",
+ description="TAI VIET LETTER LOW BO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA9A,
+ },
+ [0xAA9B]={
+ category="lo",
+ description="TAI VIET LETTER HIGH BO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA9B,
+ },
+ [0xAA9C]={
+ category="lo",
+ description="TAI VIET LETTER LOW PO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA9C,
+ },
+ [0xAA9D]={
+ category="lo",
+ description="TAI VIET LETTER HIGH PO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA9D,
+ },
+ [0xAA9E]={
+ category="lo",
+ description="TAI VIET LETTER LOW PHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA9E,
+ },
+ [0xAA9F]={
+ category="lo",
+ description="TAI VIET LETTER HIGH PHO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAA9F,
+ },
+ [0xAAA0]={
+ category="lo",
+ description="TAI VIET LETTER LOW FO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA0,
+ },
+ [0xAAA1]={
+ category="lo",
+ description="TAI VIET LETTER HIGH FO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA1,
+ },
+ [0xAAA2]={
+ category="lo",
+ description="TAI VIET LETTER LOW MO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA2,
+ },
+ [0xAAA3]={
+ category="lo",
+ description="TAI VIET LETTER HIGH MO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA3,
+ },
+ [0xAAA4]={
+ category="lo",
+ description="TAI VIET LETTER LOW YO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA4,
+ },
+ [0xAAA5]={
+ category="lo",
+ description="TAI VIET LETTER HIGH YO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA5,
+ },
+ [0xAAA6]={
+ category="lo",
+ description="TAI VIET LETTER LOW RO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA6,
+ },
+ [0xAAA7]={
+ category="lo",
+ description="TAI VIET LETTER HIGH RO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA7,
+ },
+ [0xAAA8]={
+ category="lo",
+ description="TAI VIET LETTER LOW LO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA8,
+ },
+ [0xAAA9]={
+ category="lo",
+ description="TAI VIET LETTER HIGH LO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAA9,
+ },
+ [0xAAAA]={
+ category="lo",
+ description="TAI VIET LETTER LOW VO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAAA,
+ },
+ [0xAAAB]={
+ category="lo",
+ description="TAI VIET LETTER HIGH VO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAAB,
+ },
+ [0xAAAC]={
+ category="lo",
+ description="TAI VIET LETTER LOW HO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAAC,
+ },
+ [0xAAAD]={
+ category="lo",
+ description="TAI VIET LETTER HIGH HO",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAAD,
+ },
+ [0xAAAE]={
+ category="lo",
+ description="TAI VIET LETTER LOW O",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAAE,
+ },
+ [0xAAAF]={
+ category="lo",
+ description="TAI VIET LETTER HIGH O",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAAF,
+ },
+ [0xAAB0]={
+ category="mn",
+ description="TAI VIET MAI KANG",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAB0,
+ },
+ [0xAAB1]={
+ category="lo",
+ description="TAI VIET VOWEL AA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAB1,
+ },
+ [0xAAB2]={
+ category="mn",
+ description="TAI VIET VOWEL I",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAB2,
+ },
+ [0xAAB3]={
+ category="mn",
+ description="TAI VIET VOWEL UE",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAB3,
+ },
+ [0xAAB4]={
+ category="mn",
+ description="TAI VIET VOWEL U",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAB4,
+ },
+ [0xAAB5]={
+ category="lo",
+ description="TAI VIET VOWEL E",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAB5,
+ },
+ [0xAAB6]={
+ category="lo",
+ description="TAI VIET VOWEL O",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAB6,
+ },
+ [0xAAB7]={
+ category="mn",
+ description="TAI VIET MAI KHIT",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAB7,
+ },
+ [0xAAB8]={
+ category="mn",
+ description="TAI VIET VOWEL IA",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAB8,
+ },
+ [0xAAB9]={
+ category="lo",
+ description="TAI VIET VOWEL UEA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAB9,
+ },
+ [0xAABA]={
+ category="lo",
+ description="TAI VIET VOWEL UA",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAABA,
+ },
+ [0xAABB]={
+ category="lo",
+ description="TAI VIET VOWEL AUE",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAABB,
+ },
+ [0xAABC]={
+ category="lo",
+ description="TAI VIET VOWEL AY",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAABC,
+ },
+ [0xAABD]={
+ category="lo",
+ description="TAI VIET VOWEL AN",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAABD,
+ },
+ [0xAABE]={
+ category="mn",
+ description="TAI VIET VOWEL AM",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAABE,
+ },
+ [0xAABF]={
+ category="mn",
+ description="TAI VIET TONE MAI EK",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAABF,
+ },
+ [0xAAC0]={
+ category="lo",
+ description="TAI VIET TONE MAI NUENG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAC0,
+ },
+ [0xAAC1]={
+ category="mn",
+ description="TAI VIET TONE MAI THO",
+ direction="nsm",
+ linebreak="sa",
+ unicodeslot=0xAAC1,
+ },
+ [0xAAC2]={
+ category="lo",
+ description="TAI VIET TONE MAI SONG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAAC2,
+ },
+ [0xAADB]={
+ category="lo",
+ description="TAI VIET SYMBOL KON",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAADB,
+ },
+ [0xAADC]={
+ category="lo",
+ description="TAI VIET SYMBOL NUENG",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAADC,
+ },
+ [0xAADD]={
+ category="lm",
+ description="TAI VIET SYMBOL SAM",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAADD,
+ },
+ [0xAADE]={
+ category="po",
+ description="TAI VIET SYMBOL HO HOI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAADE,
+ },
+ [0xAADF]={
+ category="po",
+ description="TAI VIET SYMBOL KOI KOI",
+ direction="l",
+ linebreak="sa",
+ unicodeslot=0xAADF,
+ },
+ [0xAAE0]={
+ category="lo",
+ description="MEETEI MAYEK LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE0,
+ },
+ [0xAAE1]={
+ category="lo",
+ description="MEETEI MAYEK LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE1,
+ },
+ [0xAAE2]={
+ category="lo",
+ description="MEETEI MAYEK LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE2,
+ },
+ [0xAAE3]={
+ category="lo",
+ description="MEETEI MAYEK LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE3,
+ },
+ [0xAAE4]={
+ category="lo",
+ description="MEETEI MAYEK LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE4,
+ },
+ [0xAAE5]={
+ category="lo",
+ description="MEETEI MAYEK LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE5,
+ },
+ [0xAAE6]={
+ category="lo",
+ description="MEETEI MAYEK LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE6,
+ },
+ [0xAAE7]={
+ category="lo",
+ description="MEETEI MAYEK LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE7,
+ },
+ [0xAAE8]={
+ category="lo",
+ description="MEETEI MAYEK LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE8,
+ },
+ [0xAAE9]={
+ category="lo",
+ description="MEETEI MAYEK LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAE9,
+ },
+ [0xAAEA]={
+ category="lo",
+ description="MEETEI MAYEK LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAEA,
+ },
+ [0xAAEB]={
+ category="mc",
+ description="MEETEI MAYEK VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAAEB,
+ },
+ [0xAAEC]={
+ category="mn",
+ description="MEETEI MAYEK VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAAEC,
+ },
+ [0xAAED]={
+ category="mn",
+ description="MEETEI MAYEK VOWEL SIGN AAI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAAED,
+ },
+ [0xAAEE]={
+ category="mc",
+ description="MEETEI MAYEK VOWEL SIGN AU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAAEE,
+ },
+ [0xAAEF]={
+ category="mc",
+ description="MEETEI MAYEK VOWEL SIGN AAU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAAEF,
+ },
+ [0xAAF0]={
+ category="po",
+ description="MEETEI MAYEK CHEIKHAN",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xAAF0,
+ },
+ [0xAAF1]={
+ category="po",
+ description="MEETEI MAYEK AHANG KHUDAM",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xAAF1,
+ },
+ [0xAAF2]={
+ category="lo",
+ description="MEETEI MAYEK ANJI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAF2,
+ },
+ [0xAAF3]={
+ category="lm",
+ description="MEETEI MAYEK SYLLABLE REPETITION MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAF3,
+ },
+ [0xAAF4]={
+ category="lm",
+ description="MEETEI MAYEK WORD REPETITION MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAAF4,
+ },
+ [0xAAF5]={
+ category="mc",
+ description="MEETEI MAYEK VOWEL SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xAAF5,
+ },
+ [0xAAF6]={
+ category="mn",
+ description="MEETEI MAYEK VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xAAF6,
+ },
+ [0xAB01]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TTHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB01,
+ },
+ [0xAB02]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TTHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB02,
+ },
+ [0xAB03]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TTHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB03,
+ },
+ [0xAB04]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TTHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB04,
+ },
+ [0xAB05]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TTHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB05,
+ },
+ [0xAB06]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE TTHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB06,
+ },
+ [0xAB09]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB09,
+ },
+ [0xAB0A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB0A,
+ },
+ [0xAB0B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB0B,
+ },
+ [0xAB0C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB0C,
+ },
+ [0xAB0D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB0D,
+ },
+ [0xAB0E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DDHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB0E,
+ },
+ [0xAB11]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DZU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB11,
+ },
+ [0xAB12]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DZI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB12,
+ },
+ [0xAB13]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DZAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB13,
+ },
+ [0xAB14]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DZEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB14,
+ },
+ [0xAB15]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB15,
+ },
+ [0xAB16]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE DZO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB16,
+ },
+ [0xAB20]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB20,
+ },
+ [0xAB21]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB21,
+ },
+ [0xAB22]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB22,
+ },
+ [0xAB23]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB23,
+ },
+ [0xAB24]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB24,
+ },
+ [0xAB25]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB25,
+ },
+ [0xAB26]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE CCHHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB26,
+ },
+ [0xAB28]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB28,
+ },
+ [0xAB29]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BBU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB29,
+ },
+ [0xAB2A]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BBI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB2A,
+ },
+ [0xAB2B]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BBAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB2B,
+ },
+ [0xAB2C]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BBEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB2C,
+ },
+ [0xAB2D]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BBE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB2D,
+ },
+ [0xAB2E]={
+ category="lo",
+ description="ETHIOPIC SYLLABLE BBO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB2E,
+ },
+ [0xABC0]={
+ category="lo",
+ description="MEETEI MAYEK LETTER KOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC0,
+ },
+ [0xABC1]={
+ category="lo",
+ description="MEETEI MAYEK LETTER SAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC1,
+ },
+ [0xABC2]={
+ category="lo",
+ description="MEETEI MAYEK LETTER LAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC2,
+ },
+ [0xABC3]={
+ category="lo",
+ description="MEETEI MAYEK LETTER MIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC3,
+ },
+ [0xABC4]={
+ category="lo",
+ description="MEETEI MAYEK LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC4,
+ },
+ [0xABC5]={
+ category="lo",
+ description="MEETEI MAYEK LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC5,
+ },
+ [0xABC6]={
+ category="lo",
+ description="MEETEI MAYEK LETTER CHIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC6,
+ },
+ [0xABC7]={
+ category="lo",
+ description="MEETEI MAYEK LETTER TIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC7,
+ },
+ [0xABC8]={
+ category="lo",
+ description="MEETEI MAYEK LETTER KHOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC8,
+ },
+ [0xABC9]={
+ category="lo",
+ description="MEETEI MAYEK LETTER NGOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABC9,
+ },
+ [0xABCA]={
+ category="lo",
+ description="MEETEI MAYEK LETTER THOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABCA,
+ },
+ [0xABCB]={
+ category="lo",
+ description="MEETEI MAYEK LETTER WAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABCB,
+ },
+ [0xABCC]={
+ category="lo",
+ description="MEETEI MAYEK LETTER YANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABCC,
+ },
+ [0xABCD]={
+ category="lo",
+ description="MEETEI MAYEK LETTER HUK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABCD,
+ },
+ [0xABCE]={
+ category="lo",
+ description="MEETEI MAYEK LETTER UN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABCE,
+ },
+ [0xABCF]={
+ category="lo",
+ description="MEETEI MAYEK LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABCF,
+ },
+ [0xABD0]={
+ category="lo",
+ description="MEETEI MAYEK LETTER PHAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD0,
+ },
+ [0xABD1]={
+ category="lo",
+ description="MEETEI MAYEK LETTER ATIYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD1,
+ },
+ [0xABD2]={
+ category="lo",
+ description="MEETEI MAYEK LETTER GOK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD2,
+ },
+ [0xABD3]={
+ category="lo",
+ description="MEETEI MAYEK LETTER JHAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD3,
+ },
+ [0xABD4]={
+ category="lo",
+ description="MEETEI MAYEK LETTER RAI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD4,
+ },
+ [0xABD5]={
+ category="lo",
+ description="MEETEI MAYEK LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD5,
+ },
+ [0xABD6]={
+ category="lo",
+ description="MEETEI MAYEK LETTER JIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD6,
+ },
+ [0xABD7]={
+ category="lo",
+ description="MEETEI MAYEK LETTER DIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD7,
+ },
+ [0xABD8]={
+ category="lo",
+ description="MEETEI MAYEK LETTER GHOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD8,
+ },
+ [0xABD9]={
+ category="lo",
+ description="MEETEI MAYEK LETTER DHOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABD9,
+ },
+ [0xABDA]={
+ category="lo",
+ description="MEETEI MAYEK LETTER BHAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABDA,
+ },
+ [0xABDB]={
+ category="lo",
+ description="MEETEI MAYEK LETTER KOK LONSUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABDB,
+ },
+ [0xABDC]={
+ category="lo",
+ description="MEETEI MAYEK LETTER LAI LONSUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABDC,
+ },
+ [0xABDD]={
+ category="lo",
+ description="MEETEI MAYEK LETTER MIT LONSUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABDD,
+ },
+ [0xABDE]={
+ category="lo",
+ description="MEETEI MAYEK LETTER PA LONSUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABDE,
+ },
+ [0xABDF]={
+ category="lo",
+ description="MEETEI MAYEK LETTER NA LONSUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABDF,
+ },
+ [0xABE0]={
+ category="lo",
+ description="MEETEI MAYEK LETTER TIL LONSUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABE0,
+ },
+ [0xABE1]={
+ category="lo",
+ description="MEETEI MAYEK LETTER NGOU LONSUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABE1,
+ },
+ [0xABE2]={
+ category="lo",
+ description="MEETEI MAYEK LETTER I LONSUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xABE2,
+ },
+ [0xABE3]={
+ category="mc",
+ description="MEETEI MAYEK VOWEL SIGN ONAP",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABE3,
+ },
+ [0xABE4]={
+ category="mc",
+ description="MEETEI MAYEK VOWEL SIGN INAP",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABE4,
+ },
+ [0xABE5]={
+ category="mn",
+ description="MEETEI MAYEK VOWEL SIGN ANAP",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xABE5,
+ },
+ [0xABE6]={
+ category="mc",
+ description="MEETEI MAYEK VOWEL SIGN YENAP",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABE6,
+ },
+ [0xABE7]={
+ category="mc",
+ description="MEETEI MAYEK VOWEL SIGN SOUNAP",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABE7,
+ },
+ [0xABE8]={
+ category="mn",
+ description="MEETEI MAYEK VOWEL SIGN UNAP",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xABE8,
+ },
+ [0xABE9]={
+ category="mc",
+ description="MEETEI MAYEK VOWEL SIGN CHEINAP",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABE9,
+ },
+ [0xABEA]={
+ category="mc",
+ description="MEETEI MAYEK VOWEL SIGN NUNG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABEA,
+ },
+ [0xABEB]={
+ category="po",
+ description="MEETEI MAYEK CHEIKHEI",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0xABEB,
+ },
+ [0xABEC]={
+ category="mc",
+ description="MEETEI MAYEK LUM IYEK",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0xABEC,
+ },
+ [0xABED]={
+ category="mn",
+ description="MEETEI MAYEK APUN IYEK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xABED,
+ },
+ [0xABF0]={
+ category="nd",
+ description="MEETEI MAYEK DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF0,
+ },
+ [0xABF1]={
+ category="nd",
+ description="MEETEI MAYEK DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF1,
+ },
+ [0xABF2]={
+ category="nd",
+ description="MEETEI MAYEK DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF2,
+ },
+ [0xABF3]={
+ category="nd",
+ description="MEETEI MAYEK DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF3,
+ },
+ [0xABF4]={
+ category="nd",
+ description="MEETEI MAYEK DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF4,
+ },
+ [0xABF5]={
+ category="nd",
+ description="MEETEI MAYEK DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF5,
+ },
+ [0xABF6]={
+ category="nd",
+ description="MEETEI MAYEK DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF6,
+ },
+ [0xABF7]={
+ category="nd",
+ description="MEETEI MAYEK DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF7,
+ },
+ [0xABF8]={
+ category="nd",
+ description="MEETEI MAYEK DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF8,
+ },
+ [0xABF9]={
+ category="nd",
+ description="MEETEI MAYEK DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0xABF9,
+ },
+ [0xD7B0]={
+ category="lo",
+ description="HANGUL JUNGSEONG O-YEO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B0,
+ },
+ [0xD7B1]={
+ category="lo",
+ description="HANGUL JUNGSEONG O-O-I",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B1,
+ },
+ [0xD7B2]={
+ category="lo",
+ description="HANGUL JUNGSEONG YO-A",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B2,
+ },
+ [0xD7B3]={
+ category="lo",
+ description="HANGUL JUNGSEONG YO-AE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B3,
+ },
+ [0xD7B4]={
+ category="lo",
+ description="HANGUL JUNGSEONG YO-EO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B4,
+ },
+ [0xD7B5]={
+ category="lo",
+ description="HANGUL JUNGSEONG U-YEO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B5,
+ },
+ [0xD7B6]={
+ category="lo",
+ description="HANGUL JUNGSEONG U-I-I",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B6,
+ },
+ [0xD7B7]={
+ category="lo",
+ description="HANGUL JUNGSEONG YU-AE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B7,
+ },
+ [0xD7B8]={
+ category="lo",
+ description="HANGUL JUNGSEONG YU-O",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B8,
+ },
+ [0xD7B9]={
+ category="lo",
+ description="HANGUL JUNGSEONG EU-A",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7B9,
+ },
+ [0xD7BA]={
+ category="lo",
+ description="HANGUL JUNGSEONG EU-EO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7BA,
+ },
+ [0xD7BB]={
+ category="lo",
+ description="HANGUL JUNGSEONG EU-E",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7BB,
+ },
+ [0xD7BC]={
+ category="lo",
+ description="HANGUL JUNGSEONG EU-O",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7BC,
+ },
+ [0xD7BD]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-YA-O",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7BD,
+ },
+ [0xD7BE]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-YAE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7BE,
+ },
+ [0xD7BF]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-YEO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7BF,
+ },
+ [0xD7C0]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-YE",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C0,
+ },
+ [0xD7C1]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-O-I",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C1,
+ },
+ [0xD7C2]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-YO",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C2,
+ },
+ [0xD7C3]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-YU",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C3,
+ },
+ [0xD7C4]={
+ category="lo",
+ description="HANGUL JUNGSEONG I-I",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C4,
+ },
+ [0xD7C5]={
+ category="lo",
+ description="HANGUL JUNGSEONG ARAEA-A",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C5,
+ },
+ [0xD7C6]={
+ category="lo",
+ description="HANGUL JUNGSEONG ARAEA-E",
+ direction="l",
+ linebreak="jv",
+ unicodeslot=0xD7C6,
+ },
+ [0xD7CB]={
+ category="lo",
+ description="HANGUL JONGSEONG NIEUN-RIEUL",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7CB,
+ },
+ [0xD7CC]={
+ category="lo",
+ description="HANGUL JONGSEONG NIEUN-CHIEUCH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7CC,
+ },
+ [0xD7CD]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGTIKEUT",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7CD,
+ },
+ [0xD7CE]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGTIKEUT-PIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7CE,
+ },
+ [0xD7CF]={
+ category="lo",
+ description="HANGUL JONGSEONG TIKEUT-PIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7CF,
+ },
+ [0xD7D0]={
+ category="lo",
+ description="HANGUL JONGSEONG TIKEUT-SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D0,
+ },
+ [0xD7D1]={
+ category="lo",
+ description="HANGUL JONGSEONG TIKEUT-SIOS-KIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D1,
+ },
+ [0xD7D2]={
+ category="lo",
+ description="HANGUL JONGSEONG TIKEUT-CIEUC",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D2,
+ },
+ [0xD7D3]={
+ category="lo",
+ description="HANGUL JONGSEONG TIKEUT-CHIEUCH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D3,
+ },
+ [0xD7D4]={
+ category="lo",
+ description="HANGUL JONGSEONG TIKEUT-THIEUTH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D4,
+ },
+ [0xD7D5]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-SSANGKIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D5,
+ },
+ [0xD7D6]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-KIYEOK-HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D6,
+ },
+ [0xD7D7]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGRIEUL-KHIEUKH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D7,
+ },
+ [0xD7D8]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-MIEUM-HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D8,
+ },
+ [0xD7D9]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-PIEUP-TIKEUT",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7D9,
+ },
+ [0xD7DA]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-PIEUP-PHIEUPH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7DA,
+ },
+ [0xD7DB]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-YESIEUNG",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7DB,
+ },
+ [0xD7DC]={
+ category="lo",
+ description="HANGUL JONGSEONG RIEUL-YEORINHIEUH-HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7DC,
+ },
+ [0xD7DD]={
+ category="lo",
+ description="HANGUL JONGSEONG KAPYEOUNRIEUL",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7DD,
+ },
+ [0xD7DE]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM-NIEUN",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7DE,
+ },
+ [0xD7DF]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM-SSANGNIEUN",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7DF,
+ },
+ [0xD7E0]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGMIEUM",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E0,
+ },
+ [0xD7E1]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM-PIEUP-SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E1,
+ },
+ [0xD7E2]={
+ category="lo",
+ description="HANGUL JONGSEONG MIEUM-CIEUC",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E2,
+ },
+ [0xD7E3]={
+ category="lo",
+ description="HANGUL JONGSEONG PIEUP-TIKEUT",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E3,
+ },
+ [0xD7E4]={
+ category="lo",
+ description="HANGUL JONGSEONG PIEUP-RIEUL-PHIEUPH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E4,
+ },
+ [0xD7E5]={
+ category="lo",
+ description="HANGUL JONGSEONG PIEUP-MIEUM",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E5,
+ },
+ [0xD7E6]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGPIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E6,
+ },
+ [0xD7E7]={
+ category="lo",
+ description="HANGUL JONGSEONG PIEUP-SIOS-TIKEUT",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E7,
+ },
+ [0xD7E8]={
+ category="lo",
+ description="HANGUL JONGSEONG PIEUP-CIEUC",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E8,
+ },
+ [0xD7E9]={
+ category="lo",
+ description="HANGUL JONGSEONG PIEUP-CHIEUCH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7E9,
+ },
+ [0xD7EA]={
+ category="lo",
+ description="HANGUL JONGSEONG SIOS-MIEUM",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7EA,
+ },
+ [0xD7EB]={
+ category="lo",
+ description="HANGUL JONGSEONG SIOS-KAPYEOUNPIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7EB,
+ },
+ [0xD7EC]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGSIOS-KIYEOK",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7EC,
+ },
+ [0xD7ED]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGSIOS-TIKEUT",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7ED,
+ },
+ [0xD7EE]={
+ category="lo",
+ description="HANGUL JONGSEONG SIOS-PANSIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7EE,
+ },
+ [0xD7EF]={
+ category="lo",
+ description="HANGUL JONGSEONG SIOS-CIEUC",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7EF,
+ },
+ [0xD7F0]={
+ category="lo",
+ description="HANGUL JONGSEONG SIOS-CHIEUCH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F0,
+ },
+ [0xD7F1]={
+ category="lo",
+ description="HANGUL JONGSEONG SIOS-THIEUTH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F1,
+ },
+ [0xD7F2]={
+ category="lo",
+ description="HANGUL JONGSEONG SIOS-HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F2,
+ },
+ [0xD7F3]={
+ category="lo",
+ description="HANGUL JONGSEONG PANSIOS-PIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F3,
+ },
+ [0xD7F4]={
+ category="lo",
+ description="HANGUL JONGSEONG PANSIOS-KAPYEOUNPIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F4,
+ },
+ [0xD7F5]={
+ category="lo",
+ description="HANGUL JONGSEONG YESIEUNG-MIEUM",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F5,
+ },
+ [0xD7F6]={
+ category="lo",
+ description="HANGUL JONGSEONG YESIEUNG-HIEUH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F6,
+ },
+ [0xD7F7]={
+ category="lo",
+ description="HANGUL JONGSEONG CIEUC-PIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F7,
+ },
+ [0xD7F8]={
+ category="lo",
+ description="HANGUL JONGSEONG CIEUC-SSANGPIEUP",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F8,
+ },
+ [0xD7F9]={
+ category="lo",
+ description="HANGUL JONGSEONG SSANGCIEUC",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7F9,
+ },
+ [0xD7FA]={
+ category="lo",
+ description="HANGUL JONGSEONG PHIEUPH-SIOS",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7FA,
+ },
+ [0xD7FB]={
+ category="lo",
+ description="HANGUL JONGSEONG PHIEUPH-THIEUTH",
+ direction="l",
+ linebreak="jt",
+ unicodeslot=0xD7FB,
+ },
+ [0xD800]={
+ category="cs",
+ description="<Non Private Use High Surrogate, First>",
+ direction="l",
+ linebreak="sg",
+ unicodeslot=0xD800,
+ },
+ [0xDB7F]={
+ category="cs",
+ description="<Non Private Use High Surrogate, Last>",
+ direction="l",
+ linebreak="sg",
+ unicodeslot=0xDB7F,
+ },
+ [0xDB80]={
+ category="cs",
+ description="<Private Use High Surrogate, First>",
+ direction="l",
+ linebreak="sg",
+ unicodeslot=0xDB80,
+ },
+ [0xDBFF]={
+ category="cs",
+ description="<Private Use High Surrogate, Last>",
+ direction="l",
+ linebreak="sg",
+ unicodeslot=0xDBFF,
+ },
+ [0xDC00]={
+ category="cs",
+ description="<Low Surrogate, First>",
+ direction="l",
+ linebreak="sg",
+ unicodeslot=0xDC00,
+ },
+ [0xDFFF]={
+ category="cs",
+ description="<Low Surrogate, Last>",
+ direction="l",
+ linebreak="sg",
+ unicodeslot=0xDFFF,
+ },
+ [0xE000]={
+ category="co",
+ cjkwd="a",
+ description="<Private Use, First>",
+ direction="l",
+ unicodeslot=0xE000,
+ },
+ [0xF8FF]={
+ adobename="apple",
+ category="co",
+ cjkwd="a",
+ description="<Private Use, Last>",
+ direction="l",
+ unicodeslot=0xF8FF,
+ },
+ [0xF900]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0384",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8C48 },
+ unicodeslot=0xF900,
+ },
+ [0xF901]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0385",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x66F4 },
+ unicodeslot=0xF901,
+ },
+ [0xF902]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0386",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8ECA },
+ unicodeslot=0xF902,
+ },
+ [0xF903]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0387",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8CC8 },
+ unicodeslot=0xF903,
+ },
+ [0xF904]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0388",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6ED1 },
+ unicodeslot=0xF904,
+ },
+ [0xF905]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0389",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E32 },
+ unicodeslot=0xF905,
+ },
+ [0xF906]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x038A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x53E5 },
+ unicodeslot=0xF906,
+ },
+ [0xF907]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x038B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F9C },
+ unicodeslot=0xF907,
+ },
+ [0xF908]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x038C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F9C },
+ unicodeslot=0xF908,
+ },
+ [0xF909]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x038D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5951 },
+ unicodeslot=0xF909,
+ },
+ [0xF90A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005AA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x91D1 },
+ unicodeslot=0xF90A,
+ },
+ [0xF90B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005AB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5587 },
+ unicodeslot=0xF90B,
+ },
+ [0xF90C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005AC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5948 },
+ unicodeslot=0xF90C,
+ },
+ [0xF90D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005AD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61F6 },
+ unicodeslot=0xF90D,
+ },
+ [0xF90E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005AE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7669 },
+ unicodeslot=0xF90E,
+ },
+ [0xF90F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005AF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F85 },
+ unicodeslot=0xF90F,
+ },
+ [0xF910]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x038E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x863F },
+ unicodeslot=0xF910,
+ },
+ [0xF911]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x038F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x87BA },
+ unicodeslot=0xF911,
+ },
+ [0xF912]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0390",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88F8 },
+ unicodeslot=0xF912,
+ },
+ [0xF913]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0391",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x908F },
+ unicodeslot=0xF913,
+ },
+ [0xF914]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0392",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6A02 },
+ unicodeslot=0xF914,
+ },
+ [0xF915]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0393",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D1B },
+ unicodeslot=0xF915,
+ },
+ [0xF916]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0394",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x70D9 },
+ unicodeslot=0xF916,
+ },
+ [0xF917]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0395",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x73DE },
+ unicodeslot=0xF917,
+ },
+ [0xF918]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0396",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x843D },
+ unicodeslot=0xF918,
+ },
+ [0xF919]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0397",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x916A },
+ unicodeslot=0xF919,
+ },
+ [0xF91A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005BA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x99F1 },
+ unicodeslot=0xF91A,
+ },
+ [0xF91B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005BB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E82 },
+ unicodeslot=0xF91B,
+ },
+ [0xF91C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005BC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5375 },
+ unicodeslot=0xF91C,
+ },
+ [0xF91D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005BD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B04 },
+ unicodeslot=0xF91D,
+ },
+ [0xF91E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005BE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x721B },
+ unicodeslot=0xF91E,
+ },
+ [0xF91F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005BF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x862D },
+ unicodeslot=0xF91F,
+ },
+ [0xF920]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0398",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9E1E },
+ unicodeslot=0xF920,
+ },
+ [0xF921]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0399",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5D50 },
+ unicodeslot=0xF921,
+ },
+ [0xF922]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x039A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6FEB },
+ unicodeslot=0xF922,
+ },
+ [0xF923]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x039B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x85CD },
+ unicodeslot=0xF923,
+ },
+ [0xF924]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x039C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8964 },
+ unicodeslot=0xF924,
+ },
+ [0xF925]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x039D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62C9 },
+ unicodeslot=0xF925,
+ },
+ [0xF926]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x039E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x81D8 },
+ unicodeslot=0xF926,
+ },
+ [0xF927]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x039F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x881F },
+ unicodeslot=0xF927,
+ },
+ [0xF928]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03A0",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5ECA },
+ unicodeslot=0xF928,
+ },
+ [0xF929]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03A1",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6717 },
+ unicodeslot=0xF929,
+ },
+ [0xF92A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005CA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D6A },
+ unicodeslot=0xF92A,
+ },
+ [0xF92B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005CB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x72FC },
+ unicodeslot=0xF92B,
+ },
+ [0xF92C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005CC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x90CE },
+ unicodeslot=0xF92C,
+ },
+ [0xF92D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005CD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4F86 },
+ unicodeslot=0xF92D,
+ },
+ [0xF92E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005CE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51B7 },
+ unicodeslot=0xF92E,
+ },
+ [0xF92F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005CF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52DE },
+ unicodeslot=0xF92F,
+ },
+ [0xF930]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03A2",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x64C4 },
+ unicodeslot=0xF930,
+ },
+ [0xF931]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03A3",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6AD3 },
+ unicodeslot=0xF931,
+ },
+ [0xF932]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03A4",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7210 },
+ unicodeslot=0xF932,
+ },
+ [0xF933]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03A5",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x76E7 },
+ unicodeslot=0xF933,
+ },
+ [0xF934]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03A6",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8001 },
+ unicodeslot=0xF934,
+ },
+ [0xF935]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03A7",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8606 },
+ unicodeslot=0xF935,
+ },
+ [0xF936]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03A8",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x865C },
+ unicodeslot=0xF936,
+ },
+ [0xF937]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03A9",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8DEF },
+ unicodeslot=0xF937,
+ },
+ [0xF938]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03AA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9732 },
+ unicodeslot=0xF938,
+ },
+ [0xF939]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03AB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9B6F },
+ unicodeslot=0xF939,
+ },
+ [0xF93A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005DA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9DFA },
+ unicodeslot=0xF93A,
+ },
+ [0xF93B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005DB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x788C },
+ unicodeslot=0xF93B,
+ },
+ [0xF93C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005DC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x797F },
+ unicodeslot=0xF93C,
+ },
+ [0xF93D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005DD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7DA0 },
+ unicodeslot=0xF93D,
+ },
+ [0xF93E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005DE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83C9 },
+ unicodeslot=0xF93E,
+ },
+ [0xF93F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005DF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9304 },
+ unicodeslot=0xF93F,
+ },
+ [0xF940]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03AC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9E7F },
+ unicodeslot=0xF940,
+ },
+ [0xF941]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03AD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AD6 },
+ unicodeslot=0xF941,
+ },
+ [0xF942]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03AE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58DF },
+ unicodeslot=0xF942,
+ },
+ [0xF943]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03AF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F04 },
+ unicodeslot=0xF943,
+ },
+ [0xF944]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03B0",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7C60 },
+ unicodeslot=0xF944,
+ },
+ [0xF945]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03B1",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x807E },
+ unicodeslot=0xF945,
+ },
+ [0xF946]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03B2",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7262 },
+ unicodeslot=0xF946,
+ },
+ [0xF947]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03B3",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x78CA },
+ unicodeslot=0xF947,
+ },
+ [0xF948]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03B4",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8CC2 },
+ unicodeslot=0xF948,
+ },
+ [0xF949]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03B5",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96F7 },
+ unicodeslot=0xF949,
+ },
+ [0xF94A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005EA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58D8 },
+ unicodeslot=0xF94A,
+ },
+ [0xF94B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005EB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C62 },
+ unicodeslot=0xF94B,
+ },
+ [0xF94C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005EC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6A13 },
+ unicodeslot=0xF94C,
+ },
+ [0xF94D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005ED",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6DDA },
+ unicodeslot=0xF94D,
+ },
+ [0xF94E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005EE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6F0F },
+ unicodeslot=0xF94E,
+ },
+ [0xF94F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005EF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7D2F },
+ unicodeslot=0xF94F,
+ },
+ [0xF950]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03B6",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7E37 },
+ unicodeslot=0xF950,
+ },
+ [0xF951]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03B7",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x964B },
+ unicodeslot=0xF951,
+ },
+ [0xF952]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03B8",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52D2 },
+ unicodeslot=0xF952,
+ },
+ [0xF953]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03B9",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x808B },
+ unicodeslot=0xF953,
+ },
+ [0xF954]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03BA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51DC },
+ unicodeslot=0xF954,
+ },
+ [0xF955]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03BB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51CC },
+ unicodeslot=0xF955,
+ },
+ [0xF956]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03BC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7A1C },
+ unicodeslot=0xF956,
+ },
+ [0xF957]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03BD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7DBE },
+ unicodeslot=0xF957,
+ },
+ [0xF958]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03BE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83F1 },
+ unicodeslot=0xF958,
+ },
+ [0xF959]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03BF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9675 },
+ unicodeslot=0xF959,
+ },
+ [0xF95A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005FA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B80 },
+ unicodeslot=0xF95A,
+ },
+ [0xF95B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005FB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62CF },
+ unicodeslot=0xF95B,
+ },
+ [0xF95C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005FC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6A02 },
+ unicodeslot=0xF95C,
+ },
+ [0xF95D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005FD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AFE },
+ unicodeslot=0xF95D,
+ },
+ [0xF95E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005FE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E39 },
+ unicodeslot=0xF95E,
+ },
+ [0xF95F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x005FF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BE7 },
+ unicodeslot=0xF95F,
+ },
+ [0xF960]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03C0",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6012 },
+ unicodeslot=0xF960,
+ },
+ [0xF961]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03C1",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7387 },
+ unicodeslot=0xF961,
+ },
+ [0xF962]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03C2",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7570 },
+ unicodeslot=0xF962,
+ },
+ [0xF963]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03C3",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5317 },
+ unicodeslot=0xF963,
+ },
+ [0xF964]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03C4",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x78FB },
+ unicodeslot=0xF964,
+ },
+ [0xF965]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03C5",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4FBF },
+ unicodeslot=0xF965,
+ },
+ [0xF966]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03C6",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5FA9 },
+ unicodeslot=0xF966,
+ },
+ [0xF967]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03C7",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E0D },
+ unicodeslot=0xF967,
+ },
+ [0xF968]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03C8",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6CCC },
+ unicodeslot=0xF968,
+ },
+ [0xF969]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03C9",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6578 },
+ unicodeslot=0xF969,
+ },
+ [0xF96A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0060A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7D22 },
+ unicodeslot=0xF96A,
+ },
+ [0xF96B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0060B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x53C3 },
+ unicodeslot=0xF96B,
+ },
+ [0xF96C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0060C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x585E },
+ unicodeslot=0xF96C,
+ },
+ [0xF96D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0060D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7701 },
+ unicodeslot=0xF96D,
+ },
+ [0xF96E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0060E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8449 },
+ unicodeslot=0xF96E,
+ },
+ [0xF96F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0060F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AAA },
+ unicodeslot=0xF96F,
+ },
+ [0xF970]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03CA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6BBA },
+ unicodeslot=0xF970,
+ },
+ [0xF971]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03CB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8FB0 },
+ unicodeslot=0xF971,
+ },
+ [0xF972]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03CC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6C88 },
+ unicodeslot=0xF972,
+ },
+ [0xF973]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03CD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62FE },
+ unicodeslot=0xF973,
+ },
+ [0xF974]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03CE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x82E5 },
+ unicodeslot=0xF974,
+ },
+ [0xF975]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03CF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x63A0 },
+ unicodeslot=0xF975,
+ },
+ [0xF976]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03D0",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7565 },
+ unicodeslot=0xF976,
+ },
+ [0xF977]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03D1",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4EAE },
+ unicodeslot=0xF977,
+ },
+ [0xF978]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03D2",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5169 },
+ unicodeslot=0xF978,
+ },
+ [0xF979]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03D3",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51C9 },
+ unicodeslot=0xF979,
+ },
+ [0xF97A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0061A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6881 },
+ unicodeslot=0xF97A,
+ },
+ [0xF97B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0061B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7CE7 },
+ unicodeslot=0xF97B,
+ },
+ [0xF97C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0061C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x826F },
+ unicodeslot=0xF97C,
+ },
+ [0xF97D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0061D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AD2 },
+ unicodeslot=0xF97D,
+ },
+ [0xF97E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0061E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x91CF },
+ unicodeslot=0xF97E,
+ },
+ [0xF97F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0061F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52F5 },
+ unicodeslot=0xF97F,
+ },
+ [0xF980]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03D4",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5442 },
+ unicodeslot=0xF980,
+ },
+ [0xF981]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03D5",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5973 },
+ unicodeslot=0xF981,
+ },
+ [0xF982]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03D6",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EEC },
+ unicodeslot=0xF982,
+ },
+ [0xF983]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03D7",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x65C5 },
+ unicodeslot=0xF983,
+ },
+ [0xF984]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03D8",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6FFE },
+ unicodeslot=0xF984,
+ },
+ [0xF985]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03D9",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x792A },
+ unicodeslot=0xF985,
+ },
+ [0xF986]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03DA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x95AD },
+ unicodeslot=0xF986,
+ },
+ [0xF987]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03DB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9A6A },
+ unicodeslot=0xF987,
+ },
+ [0xF988]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03DC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9E97 },
+ unicodeslot=0xF988,
+ },
+ [0xF989]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03DD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9ECE },
+ unicodeslot=0xF989,
+ },
+ [0xF98A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0062A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x529B },
+ unicodeslot=0xF98A,
+ },
+ [0xF98B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0062B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x66C6 },
+ unicodeslot=0xF98B,
+ },
+ [0xF98C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0062C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B77 },
+ unicodeslot=0xF98C,
+ },
+ [0xF98D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0062D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F62 },
+ unicodeslot=0xF98D,
+ },
+ [0xF98E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0062E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5E74 },
+ unicodeslot=0xF98E,
+ },
+ [0xF98F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0062F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6190 },
+ unicodeslot=0xF98F,
+ },
+ [0xF990]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03DE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6200 },
+ unicodeslot=0xF990,
+ },
+ [0xF991]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03DF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x649A },
+ unicodeslot=0xF991,
+ },
+ [0xF992]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03E0",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6F23 },
+ unicodeslot=0xF992,
+ },
+ [0xF993]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03E1",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7149 },
+ unicodeslot=0xF993,
+ },
+ [0xF994]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03E2",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7489 },
+ unicodeslot=0xF994,
+ },
+ [0xF995]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03E3",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x79CA },
+ unicodeslot=0xF995,
+ },
+ [0xF996]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03E4",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7DF4 },
+ unicodeslot=0xF996,
+ },
+ [0xF997]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03E5",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x806F },
+ unicodeslot=0xF997,
+ },
+ [0xF998]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03E6",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F26 },
+ unicodeslot=0xF998,
+ },
+ [0xF999]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x03E7",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x84EE },
+ unicodeslot=0xF999,
+ },
+ [0xF99A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0063A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9023 },
+ unicodeslot=0xF99A,
+ },
+ [0xF99B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0063B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x934A },
+ unicodeslot=0xF99B,
+ },
+ [0xF99C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0063C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5217 },
+ unicodeslot=0xF99C,
+ },
+ [0xF99D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0063D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52A3 },
+ unicodeslot=0xF99D,
+ },
+ [0xF99E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0063E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x54BD },
+ unicodeslot=0xF99E,
+ },
+ [0xF99F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0063F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x70C8 },
+ unicodeslot=0xF99F,
+ },
+ [0xF9A0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88C2 },
+ unicodeslot=0xF9A0,
+ },
+ [0xF9A1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AAA },
+ unicodeslot=0xF9A1,
+ },
+ [0xF9A2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EC9 },
+ unicodeslot=0xF9A2,
+ },
+ [0xF9A3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5FF5 },
+ unicodeslot=0xF9A3,
+ },
+ [0xF9A4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x637B },
+ unicodeslot=0xF9A4,
+ },
+ [0xF9A5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6BAE },
+ unicodeslot=0xF9A5,
+ },
+ [0xF9A6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7C3E },
+ unicodeslot=0xF9A6,
+ },
+ [0xF9A7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7375 },
+ unicodeslot=0xF9A7,
+ },
+ [0xF9A8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4EE4 },
+ unicodeslot=0xF9A8,
+ },
+ [0xF9A9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009A0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x56F9 },
+ unicodeslot=0xF9A9,
+ },
+ [0xF9AA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009AA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BE7 },
+ unicodeslot=0xF9AA,
+ },
+ [0xF9AB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009AB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5DBA },
+ unicodeslot=0xF9AB,
+ },
+ [0xF9AC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009AC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x601C },
+ unicodeslot=0xF9AC,
+ },
+ [0xF9AD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009AD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x73B2 },
+ unicodeslot=0xF9AD,
+ },
+ [0xF9AE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009AE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7469 },
+ unicodeslot=0xF9AE,
+ },
+ [0xF9AF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009AF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F9A },
+ unicodeslot=0xF9AF,
+ },
+ [0xF9B0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8046 },
+ unicodeslot=0xF9B0,
+ },
+ [0xF9B1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9234 },
+ unicodeslot=0xF9B1,
+ },
+ [0xF9B2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96F6 },
+ unicodeslot=0xF9B2,
+ },
+ [0xF9B3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9748 },
+ unicodeslot=0xF9B3,
+ },
+ [0xF9B4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9818 },
+ unicodeslot=0xF9B4,
+ },
+ [0xF9B5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4F8B },
+ unicodeslot=0xF9B5,
+ },
+ [0xF9B6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x79AE },
+ unicodeslot=0xF9B6,
+ },
+ [0xF9B7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x91B4 },
+ unicodeslot=0xF9B7,
+ },
+ [0xF9B8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96B8 },
+ unicodeslot=0xF9B8,
+ },
+ [0xF9B9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009B0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x60E1 },
+ unicodeslot=0xF9B9,
+ },
+ [0xF9BA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009BA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E86 },
+ unicodeslot=0xF9BA,
+ },
+ [0xF9BB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009BB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x50DA },
+ unicodeslot=0xF9BB,
+ },
+ [0xF9BC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009BC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BEE },
+ unicodeslot=0xF9BC,
+ },
+ [0xF9BD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009BD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C3F },
+ unicodeslot=0xF9BD,
+ },
+ [0xF9BE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009BE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6599 },
+ unicodeslot=0xF9BE,
+ },
+ [0xF9BF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009BF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6A02 },
+ unicodeslot=0xF9BF,
+ },
+ [0xF9C0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x71CE },
+ unicodeslot=0xF9C0,
+ },
+ [0xF9C1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7642 },
+ unicodeslot=0xF9C1,
+ },
+ [0xF9C2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x84FC },
+ unicodeslot=0xF9C2,
+ },
+ [0xF9C3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x907C },
+ unicodeslot=0xF9C3,
+ },
+ [0xF9C4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F8D },
+ unicodeslot=0xF9C4,
+ },
+ [0xF9C5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6688 },
+ unicodeslot=0xF9C5,
+ },
+ [0xF9C6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x962E },
+ unicodeslot=0xF9C6,
+ },
+ [0xF9C7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5289 },
+ unicodeslot=0xF9C7,
+ },
+ [0xF9C8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x677B },
+ unicodeslot=0xF9C8,
+ },
+ [0xF9C9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009C0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x67F3 },
+ unicodeslot=0xF9C9,
+ },
+ [0xF9CA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009CA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D41 },
+ unicodeslot=0xF9CA,
+ },
+ [0xF9CB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009CB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6E9C },
+ unicodeslot=0xF9CB,
+ },
+ [0xF9CC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009CC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7409 },
+ unicodeslot=0xF9CC,
+ },
+ [0xF9CD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009CD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7559 },
+ unicodeslot=0xF9CD,
+ },
+ [0xF9CE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009CE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x786B },
+ unicodeslot=0xF9CE,
+ },
+ [0xF9CF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009CF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7D10 },
+ unicodeslot=0xF9CF,
+ },
+ [0xF9D0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x985E },
+ unicodeslot=0xF9D0,
+ },
+ [0xF9D1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x516D },
+ unicodeslot=0xF9D1,
+ },
+ [0xF9D2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x622E },
+ unicodeslot=0xF9D2,
+ },
+ [0xF9D3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9678 },
+ unicodeslot=0xF9D3,
+ },
+ [0xF9D4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x502B },
+ unicodeslot=0xF9D4,
+ },
+ [0xF9D5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5D19 },
+ unicodeslot=0xF9D5,
+ },
+ [0xF9D6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6DEA },
+ unicodeslot=0xF9D6,
+ },
+ [0xF9D7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F2A },
+ unicodeslot=0xF9D7,
+ },
+ [0xF9D8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F8B },
+ unicodeslot=0xF9D8,
+ },
+ [0xF9D9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009D0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6144 },
+ unicodeslot=0xF9D9,
+ },
+ [0xF9DA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009DA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6817 },
+ unicodeslot=0xF9DA,
+ },
+ [0xF9DB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009DB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7387 },
+ unicodeslot=0xF9DB,
+ },
+ [0xF9DC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009DC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9686 },
+ unicodeslot=0xF9DC,
+ },
+ [0xF9DD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009DD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5229 },
+ unicodeslot=0xF9DD,
+ },
+ [0xF9DE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009DE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x540F },
+ unicodeslot=0xF9DE,
+ },
+ [0xF9DF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009DF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C65 },
+ unicodeslot=0xF9DF,
+ },
+ [0xF9E0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6613 },
+ unicodeslot=0xF9E0,
+ },
+ [0xF9E1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x674E },
+ unicodeslot=0xF9E1,
+ },
+ [0xF9E2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x68A8 },
+ unicodeslot=0xF9E2,
+ },
+ [0xF9E3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6CE5 },
+ unicodeslot=0xF9E3,
+ },
+ [0xF9E4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7406 },
+ unicodeslot=0xF9E4,
+ },
+ [0xF9E5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x75E2 },
+ unicodeslot=0xF9E5,
+ },
+ [0xF9E6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F79 },
+ unicodeslot=0xF9E6,
+ },
+ [0xF9E7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88CF },
+ unicodeslot=0xF9E7,
+ },
+ [0xF9E8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88E1 },
+ unicodeslot=0xF9E8,
+ },
+ [0xF9E9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009E0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x91CC },
+ unicodeslot=0xF9E9,
+ },
+ [0xF9EA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009EA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96E2 },
+ unicodeslot=0xF9EA,
+ },
+ [0xF9EB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009EB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x533F },
+ unicodeslot=0xF9EB,
+ },
+ [0xF9EC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009EC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6EBA },
+ unicodeslot=0xF9EC,
+ },
+ [0xF9ED]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009ED",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x541D },
+ unicodeslot=0xF9ED,
+ },
+ [0xF9EE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009EE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x71D0 },
+ unicodeslot=0xF9EE,
+ },
+ [0xF9EF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009EF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7498 },
+ unicodeslot=0xF9EF,
+ },
+ [0xF9F0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x85FA },
+ unicodeslot=0xF9F0,
+ },
+ [0xF9F1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96A3 },
+ unicodeslot=0xF9F1,
+ },
+ [0xF9F2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9C57 },
+ unicodeslot=0xF9F2,
+ },
+ [0xF9F3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9E9F },
+ unicodeslot=0xF9F3,
+ },
+ [0xF9F4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6797 },
+ unicodeslot=0xF9F4,
+ },
+ [0xF9F5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6DCB },
+ unicodeslot=0xF9F5,
+ },
+ [0xF9F6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x81E8 },
+ unicodeslot=0xF9F6,
+ },
+ [0xF9F7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7ACB },
+ unicodeslot=0xF9F7,
+ },
+ [0xF9F8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7B20 },
+ unicodeslot=0xF9F8,
+ },
+ [0xF9F9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009F0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7C92 },
+ unicodeslot=0xF9F9,
+ },
+ [0xF9FA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009FA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x72C0 },
+ unicodeslot=0xF9FA,
+ },
+ [0xF9FB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009FB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7099 },
+ unicodeslot=0xF9FB,
+ },
+ [0xF9FC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009FC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B58 },
+ unicodeslot=0xF9FC,
+ },
+ [0xF9FD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009FD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4EC0 },
+ unicodeslot=0xF9FD,
+ },
+ [0xF9FE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009FE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8336 },
+ unicodeslot=0xF9FE,
+ },
+ [0xF9FF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-F0x0009FF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x523A },
+ unicodeslot=0xF9FF,
+ },
+ [0xFA00]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5207 },
+ unicodeslot=0xFA00,
+ },
+ [0xFA01]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EA6 },
+ unicodeslot=0xFA01,
+ },
+ [0xFA02]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62D3 },
+ unicodeslot=0xFA02,
+ },
+ [0xFA03]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7CD6 },
+ unicodeslot=0xFA03,
+ },
+ [0xFA04]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5B85 },
+ unicodeslot=0xFA04,
+ },
+ [0xFA05]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D1E },
+ unicodeslot=0xFA05,
+ },
+ [0xFA06]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x66B4 },
+ unicodeslot=0xFA06,
+ },
+ [0xFA07]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F3B },
+ unicodeslot=0xFA07,
+ },
+ [0xFA08]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x884C },
+ unicodeslot=0xFA08,
+ },
+ [0xFA09]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x964D },
+ unicodeslot=0xFA09,
+ },
+ [0xFA0A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x898B },
+ unicodeslot=0xFA0A,
+ },
+ [0xFA0B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5ED3 },
+ unicodeslot=0xFA0B,
+ },
+ [0xFA0C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5140 },
+ unicodeslot=0xFA0C,
+ },
+ [0xFA0D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x55C0 },
+ unicodeslot=0xFA0D,
+ },
+ [0xFA0E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000E",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA0E,
+ },
+ [0xFA0F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0000F",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA0F,
+ },
+ [0xFA10]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x000A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x585A },
+ unicodeslot=0xFA10,
+ },
+ [0xFA11]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x000B",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA11,
+ },
+ [0xFA12]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x000C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6674 },
+ unicodeslot=0xFA12,
+ },
+ [0xFA13]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x000D",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA13,
+ },
+ [0xFA14]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x000E",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA14,
+ },
+ [0xFA15]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x000F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51DE },
+ unicodeslot=0xFA15,
+ },
+ [0xFA16]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0010",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x732A },
+ unicodeslot=0xFA16,
+ },
+ [0xFA17]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0011",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x76CA },
+ unicodeslot=0xFA17,
+ },
+ [0xFA18]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0012",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x793C },
+ unicodeslot=0xFA18,
+ },
+ [0xFA19]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0013",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x795E },
+ unicodeslot=0xFA19,
+ },
+ [0xFA1A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7965 },
+ unicodeslot=0xFA1A,
+ },
+ [0xFA1B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x798F },
+ unicodeslot=0xFA1B,
+ },
+ [0xFA1C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9756 },
+ unicodeslot=0xFA1C,
+ },
+ [0xFA1D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7CBE },
+ unicodeslot=0xFA1D,
+ },
+ [0xFA1E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7FBD },
+ unicodeslot=0xFA1E,
+ },
+ [0xFA1F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0001F",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA1F,
+ },
+ [0xFA20]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0014",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8612 },
+ unicodeslot=0xFA20,
+ },
+ [0xFA21]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0015",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA21,
+ },
+ [0xFA22]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0016",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AF8 },
+ unicodeslot=0xFA22,
+ },
+ [0xFA23]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0017",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA23,
+ },
+ [0xFA24]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0018",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA24,
+ },
+ [0xFA25]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0019",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9038 },
+ unicodeslot=0xFA25,
+ },
+ [0xFA26]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x001A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x90FD },
+ unicodeslot=0xFA26,
+ },
+ [0xFA27]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x001B",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA27,
+ },
+ [0xFA28]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x001C",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA28,
+ },
+ [0xFA29]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x001D",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0xFA29,
+ },
+ [0xFA2A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0002A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x98EF },
+ unicodeslot=0xFA2A,
+ },
+ [0xFA2B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0002B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x98FC },
+ unicodeslot=0xFA2B,
+ },
+ [0xFA2C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0002C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9928 },
+ unicodeslot=0xFA2C,
+ },
+ [0xFA2D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0002D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9DB4 },
+ unicodeslot=0xFA2D,
+ },
+ [0xFA2E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA2E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x90DE },
+ unicodeslot=0xFA2E,
+ },
+ [0xFA2F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA2F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96B7 },
+ unicodeslot=0xFA2F,
+ },
+ [0xFA30]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x001E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4FAE },
+ unicodeslot=0xFA30,
+ },
+ [0xFA31]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x001F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x50E7 },
+ unicodeslot=0xFA31,
+ },
+ [0xFA32]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0020",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x514D },
+ unicodeslot=0xFA32,
+ },
+ [0xFA33]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0021",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52C9 },
+ unicodeslot=0xFA33,
+ },
+ [0xFA34]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0022",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52E4 },
+ unicodeslot=0xFA34,
+ },
+ [0xFA35]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0023",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5351 },
+ unicodeslot=0xFA35,
+ },
+ [0xFA36]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0024",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x559D },
+ unicodeslot=0xFA36,
+ },
+ [0xFA37]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0025",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5606 },
+ unicodeslot=0xFA37,
+ },
+ [0xFA38]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0026",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5668 },
+ unicodeslot=0xFA38,
+ },
+ [0xFA39]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0027",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5840 },
+ unicodeslot=0xFA39,
+ },
+ [0xFA3A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58A8 },
+ unicodeslot=0xFA3A,
+ },
+ [0xFA3B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C64 },
+ unicodeslot=0xFA3B,
+ },
+ [0xFA3C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C6E },
+ unicodeslot=0xFA3C,
+ },
+ [0xFA3D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6094 },
+ unicodeslot=0xFA3D,
+ },
+ [0xFA3E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6168 },
+ unicodeslot=0xFA3E,
+ },
+ [0xFA3F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0003F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x618E },
+ unicodeslot=0xFA3F,
+ },
+ [0xFA40]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0028",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61F2 },
+ unicodeslot=0xFA40,
+ },
+ [0xFA41]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0029",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x654F },
+ unicodeslot=0xFA41,
+ },
+ [0xFA42]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x002A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x65E2 },
+ unicodeslot=0xFA42,
+ },
+ [0xFA43]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x002B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6691 },
+ unicodeslot=0xFA43,
+ },
+ [0xFA44]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x002C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6885 },
+ unicodeslot=0xFA44,
+ },
+ [0xFA45]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x002D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D77 },
+ unicodeslot=0xFA45,
+ },
+ [0xFA46]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x002E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6E1A },
+ unicodeslot=0xFA46,
+ },
+ [0xFA47]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x002F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6F22 },
+ unicodeslot=0xFA47,
+ },
+ [0xFA48]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0030",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x716E },
+ unicodeslot=0xFA48,
+ },
+ [0xFA49]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0031",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x722B },
+ unicodeslot=0xFA49,
+ },
+ [0xFA4A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7422 },
+ unicodeslot=0xFA4A,
+ },
+ [0xFA4B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7891 },
+ unicodeslot=0xFA4B,
+ },
+ [0xFA4C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x793E },
+ unicodeslot=0xFA4C,
+ },
+ [0xFA4D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7949 },
+ unicodeslot=0xFA4D,
+ },
+ [0xFA4E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7948 },
+ unicodeslot=0xFA4E,
+ },
+ [0xFA4F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0004F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7950 },
+ unicodeslot=0xFA4F,
+ },
+ [0xFA50]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0032",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7956 },
+ unicodeslot=0xFA50,
+ },
+ [0xFA51]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0033",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x795D },
+ unicodeslot=0xFA51,
+ },
+ [0xFA52]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0034",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x798D },
+ unicodeslot=0xFA52,
+ },
+ [0xFA53]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0035",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x798E },
+ unicodeslot=0xFA53,
+ },
+ [0xFA54]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0036",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7A40 },
+ unicodeslot=0xFA54,
+ },
+ [0xFA55]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0037",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7A81 },
+ unicodeslot=0xFA55,
+ },
+ [0xFA56]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0038",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7BC0 },
+ unicodeslot=0xFA56,
+ },
+ [0xFA57]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0039",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7DF4 },
+ unicodeslot=0xFA57,
+ },
+ [0xFA58]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x003A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7E09 },
+ unicodeslot=0xFA58,
+ },
+ [0xFA59]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x003B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7E41 },
+ unicodeslot=0xFA59,
+ },
+ [0xFA5A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F72 },
+ unicodeslot=0xFA5A,
+ },
+ [0xFA5B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8005 },
+ unicodeslot=0xFA5B,
+ },
+ [0xFA5C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x81ED },
+ unicodeslot=0xFA5C,
+ },
+ [0xFA5D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8279 },
+ unicodeslot=0xFA5D,
+ },
+ [0xFA5E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8279 },
+ unicodeslot=0xFA5E,
+ },
+ [0xFA5F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0005F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8457 },
+ unicodeslot=0xFA5F,
+ },
+ [0xFA60]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x003C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8910 },
+ unicodeslot=0xFA60,
+ },
+ [0xFA61]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x003D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8996 },
+ unicodeslot=0xFA61,
+ },
+ [0xFA62]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x003E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B01 },
+ unicodeslot=0xFA62,
+ },
+ [0xFA63]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x003F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B39 },
+ unicodeslot=0xFA63,
+ },
+ [0xFA64]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0040",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8CD3 },
+ unicodeslot=0xFA64,
+ },
+ [0xFA65]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0041",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8D08 },
+ unicodeslot=0xFA65,
+ },
+ [0xFA66]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0042",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8FB6 },
+ unicodeslot=0xFA66,
+ },
+ [0xFA67]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0043",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9038 },
+ unicodeslot=0xFA67,
+ },
+ [0xFA68]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0044",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96E3 },
+ unicodeslot=0xFA68,
+ },
+ [0xFA69]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0045",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x97FF },
+ unicodeslot=0xFA69,
+ },
+ [0xFA6A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0006A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x983B },
+ unicodeslot=0xFA6A,
+ },
+ [0xFA6B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA6B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6075 },
+ unicodeslot=0xFA6B,
+ },
+ [0xFA6C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA6C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x242EE },
+ unicodeslot=0xFA6C,
+ },
+ [0xFA6D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA6D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8218 },
+ unicodeslot=0xFA6D,
+ },
+ [0xFA70]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0046",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E26 },
+ unicodeslot=0xFA70,
+ },
+ [0xFA71]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0047",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51B5 },
+ unicodeslot=0xFA71,
+ },
+ [0xFA72]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0048",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5168 },
+ unicodeslot=0xFA72,
+ },
+ [0xFA73]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0049",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4F80 },
+ unicodeslot=0xFA73,
+ },
+ [0xFA74]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x004A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5145 },
+ unicodeslot=0xFA74,
+ },
+ [0xFA75]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x004B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5180 },
+ unicodeslot=0xFA75,
+ },
+ [0xFA76]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x004C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52C7 },
+ unicodeslot=0xFA76,
+ },
+ [0xFA77]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x004D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52FA },
+ unicodeslot=0xFA77,
+ },
+ [0xFA78]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x004E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x559D },
+ unicodeslot=0xFA78,
+ },
+ [0xFA79]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x004F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5555 },
+ unicodeslot=0xFA79,
+ },
+ [0xFA7A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5599 },
+ unicodeslot=0xFA7A,
+ },
+ [0xFA7B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x55E2 },
+ unicodeslot=0xFA7B,
+ },
+ [0xFA7C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x585A },
+ unicodeslot=0xFA7C,
+ },
+ [0xFA7D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58B3 },
+ unicodeslot=0xFA7D,
+ },
+ [0xFA7E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5944 },
+ unicodeslot=0xFA7E,
+ },
+ [0xFA7F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0007F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5954 },
+ unicodeslot=0xFA7F,
+ },
+ [0xFA80]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0050",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5A62 },
+ unicodeslot=0xFA80,
+ },
+ [0xFA81]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0051",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5B28 },
+ unicodeslot=0xFA81,
+ },
+ [0xFA82]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0052",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5ED2 },
+ unicodeslot=0xFA82,
+ },
+ [0xFA83]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0053",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5ED9 },
+ unicodeslot=0xFA83,
+ },
+ [0xFA84]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0054",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F69 },
+ unicodeslot=0xFA84,
+ },
+ [0xFA85]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0055",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5FAD },
+ unicodeslot=0xFA85,
+ },
+ [0xFA86]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0056",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x60D8 },
+ unicodeslot=0xFA86,
+ },
+ [0xFA87]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0057",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x614E },
+ unicodeslot=0xFA87,
+ },
+ [0xFA88]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0058",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6108 },
+ unicodeslot=0xFA88,
+ },
+ [0xFA89]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0059",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x618E },
+ unicodeslot=0xFA89,
+ },
+ [0xFA8A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6160 },
+ unicodeslot=0xFA8A,
+ },
+ [0xFA8B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61F2 },
+ unicodeslot=0xFA8B,
+ },
+ [0xFA8C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6234 },
+ unicodeslot=0xFA8C,
+ },
+ [0xFA8D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x63C4 },
+ unicodeslot=0xFA8D,
+ },
+ [0xFA8E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x641C },
+ unicodeslot=0xFA8E,
+ },
+ [0xFA8F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0008F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6452 },
+ unicodeslot=0xFA8F,
+ },
+ [0xFA90]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x005A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6556 },
+ unicodeslot=0xFA90,
+ },
+ [0xFA91]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x005B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6674 },
+ unicodeslot=0xFA91,
+ },
+ [0xFA92]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x005C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6717 },
+ unicodeslot=0xFA92,
+ },
+ [0xFA93]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x005D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x671B },
+ unicodeslot=0xFA93,
+ },
+ [0xFA94]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x005E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6756 },
+ unicodeslot=0xFA94,
+ },
+ [0xFA95]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x005F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B79 },
+ unicodeslot=0xFA95,
+ },
+ [0xFA96]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0060",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6BBA },
+ unicodeslot=0xFA96,
+ },
+ [0xFA97]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0061",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D41 },
+ unicodeslot=0xFA97,
+ },
+ [0xFA98]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0062",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6EDB },
+ unicodeslot=0xFA98,
+ },
+ [0xFA99]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0063",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6ECB },
+ unicodeslot=0xFA99,
+ },
+ [0xFA9A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6F22 },
+ unicodeslot=0xFA9A,
+ },
+ [0xFA9B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x701E },
+ unicodeslot=0xFA9B,
+ },
+ [0xFA9C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x716E },
+ unicodeslot=0xFA9C,
+ },
+ [0xFA9D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x77A7 },
+ unicodeslot=0xFA9D,
+ },
+ [0xFA9E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7235 },
+ unicodeslot=0xFA9E,
+ },
+ [0xFA9F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FA0x0009F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x72AF },
+ unicodeslot=0xFA9F,
+ },
+ [0xFAA0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x732A },
+ unicodeslot=0xFAA0,
+ },
+ [0xFAA1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7471 },
+ unicodeslot=0xFAA1,
+ },
+ [0xFAA2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7506 },
+ unicodeslot=0xFAA2,
+ },
+ [0xFAA3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x753B },
+ unicodeslot=0xFAA3,
+ },
+ [0xFAA4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x761D },
+ unicodeslot=0xFAA4,
+ },
+ [0xFAA5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x761F },
+ unicodeslot=0xFAA5,
+ },
+ [0xFAA6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x76CA },
+ unicodeslot=0xFAA6,
+ },
+ [0xFAA7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x76DB },
+ unicodeslot=0xFAA7,
+ },
+ [0xFAA8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x76F4 },
+ unicodeslot=0xFAA8,
+ },
+ [0xFAA9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAA0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x774A },
+ unicodeslot=0xFAA9,
+ },
+ [0xFAAA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAAA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7740 },
+ unicodeslot=0xFAAA,
+ },
+ [0xFAAB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAAB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x78CC },
+ unicodeslot=0xFAAB,
+ },
+ [0xFAAC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAAC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7AB1 },
+ unicodeslot=0xFAAC,
+ },
+ [0xFAAD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAAD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7BC0 },
+ unicodeslot=0xFAAD,
+ },
+ [0xFAAE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAAE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7C7B },
+ unicodeslot=0xFAAE,
+ },
+ [0xFAAF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAAF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7D5B },
+ unicodeslot=0xFAAF,
+ },
+ [0xFAB0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7DF4 },
+ unicodeslot=0xFAB0,
+ },
+ [0xFAB1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F3E },
+ unicodeslot=0xFAB1,
+ },
+ [0xFAB2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8005 },
+ unicodeslot=0xFAB2,
+ },
+ [0xFAB3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8352 },
+ unicodeslot=0xFAB3,
+ },
+ [0xFAB4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83EF },
+ unicodeslot=0xFAB4,
+ },
+ [0xFAB5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8779 },
+ unicodeslot=0xFAB5,
+ },
+ [0xFAB6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8941 },
+ unicodeslot=0xFAB6,
+ },
+ [0xFAB7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8986 },
+ unicodeslot=0xFAB7,
+ },
+ [0xFAB8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8996 },
+ unicodeslot=0xFAB8,
+ },
+ [0xFAB9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAB0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8ABF },
+ unicodeslot=0xFAB9,
+ },
+ [0xFABA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FABA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AF8 },
+ unicodeslot=0xFABA,
+ },
+ [0xFABB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FABB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8ACB },
+ unicodeslot=0xFABB,
+ },
+ [0xFABC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FABC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B01 },
+ unicodeslot=0xFABC,
+ },
+ [0xFABD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FABD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AFE },
+ unicodeslot=0xFABD,
+ },
+ [0xFABE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FABE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AED },
+ unicodeslot=0xFABE,
+ },
+ [0xFABF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FABF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B39 },
+ unicodeslot=0xFABF,
+ },
+ [0xFAC0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B8A },
+ unicodeslot=0xFAC0,
+ },
+ [0xFAC1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8D08 },
+ unicodeslot=0xFAC1,
+ },
+ [0xFAC2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F38 },
+ unicodeslot=0xFAC2,
+ },
+ [0xFAC3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9072 },
+ unicodeslot=0xFAC3,
+ },
+ [0xFAC4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9199 },
+ unicodeslot=0xFAC4,
+ },
+ [0xFAC5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9276 },
+ unicodeslot=0xFAC5,
+ },
+ [0xFAC6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x967C },
+ unicodeslot=0xFAC6,
+ },
+ [0xFAC7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96E3 },
+ unicodeslot=0xFAC7,
+ },
+ [0xFAC8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9756 },
+ unicodeslot=0xFAC8,
+ },
+ [0xFAC9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAC0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x97DB },
+ unicodeslot=0xFAC9,
+ },
+ [0xFACA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FACA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x97FF },
+ unicodeslot=0xFACA,
+ },
+ [0xFACB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FACB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x980B },
+ unicodeslot=0xFACB,
+ },
+ [0xFACC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FACC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x983B },
+ unicodeslot=0xFACC,
+ },
+ [0xFACD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FACD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9B12 },
+ unicodeslot=0xFACD,
+ },
+ [0xFACE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FACE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F9C },
+ unicodeslot=0xFACE,
+ },
+ [0xFACF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FACF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2284A },
+ unicodeslot=0xFACF,
+ },
+ [0xFAD0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x22844 },
+ unicodeslot=0xFAD0,
+ },
+ [0xFAD1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x233D5 },
+ unicodeslot=0xFAD1,
+ },
+ [0xFAD2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3B9D },
+ unicodeslot=0xFAD2,
+ },
+ [0xFAD3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4018 },
+ unicodeslot=0xFAD3,
+ },
+ [0xFAD4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4039 },
+ unicodeslot=0xFAD4,
+ },
+ [0xFAD5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25249 },
+ unicodeslot=0xFAD5,
+ },
+ [0xFAD6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25CD0 },
+ unicodeslot=0xFAD6,
+ },
+ [0xFAD7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x27ED3 },
+ unicodeslot=0xFAD7,
+ },
+ [0xFAD8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F43 },
+ unicodeslot=0xFAD8,
+ },
+ [0xFAD9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-FAD0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F8E },
+ unicodeslot=0xFAD9,
+ },
+ [0xFB00]={
+ adobename="ff",
+ category="ll",
+ contextname="ffligature",
+ description="LATIN SMALL LIGATURE FF",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0066, 0x0066 },
+ unicodeslot=0xFB00,
+ },
+ [0xFB01]={
+ adobename="fi",
+ category="ll",
+ contextname="filigature",
+ description="LATIN SMALL LIGATURE FI",
+ direction="l",
+ linebreak="al",
+ shcode={ 0x0066, 0x0069 },
+ specials={ "compat", 0x0066, 0x0069 },
+ unicodeslot=0xFB01,
+ },
+ [0xFB02]={
+ adobename="fl",
+ category="ll",
+ contextname="flligature",
+ description="LATIN SMALL LIGATURE FL",
+ direction="l",
+ linebreak="al",
+ shcode={ 0x0066, 0x006C },
+ specials={ "compat", 0x0066, 0x006C },
+ unicodeslot=0xFB02,
+ },
+ [0xFB03]={
+ adobename="ffi",
+ category="ll",
+ contextname="ffiligature",
+ description="LATIN SMALL LIGATURE FFI",
+ direction="l",
+ linebreak="al",
+ shcode={ 0x0066, 0x0069 },
+ specials={ "compat", 0x0066, 0x0066, 0x0069 },
+ unicodeslot=0xFB03,
+ },
+ [0xFB04]={
+ adobename="ffl",
+ category="ll",
+ contextname="fflligature",
+ description="LATIN SMALL LIGATURE FFL",
+ direction="l",
+ linebreak="al",
+ shcode={ 0x0066, 0x006C },
+ specials={ "compat", 0x0066, 0x0066, 0x006C },
+ unicodeslot=0xFB04,
+ },
+ [0xFB05]={
+ category="ll",
+ description="LATIN SMALL LIGATURE LONG S T",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x017F, 0x0074 },
+ unicodeslot=0xFB05,
+ },
+ [0xFB06]={
+ category="ll",
+ contextname="stligature",
+ description="LATIN SMALL LIGATURE ST",
+ direction="l",
+ linebreak="al",
+ shcode={ 0x0073, 0x0074 },
+ specials={ "compat", 0x0073, 0x0074 },
+ unicodeslot=0xFB06,
+ },
+ [0xFB13]={
+ category="ll",
+ description="ARMENIAN SMALL LIGATURE MEN NOW",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0574, 0x0576 },
+ unicodeslot=0xFB13,
+ },
+ [0xFB14]={
+ category="ll",
+ description="ARMENIAN SMALL LIGATURE MEN ECH",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0574, 0x0565 },
+ unicodeslot=0xFB14,
+ },
+ [0xFB15]={
+ category="ll",
+ description="ARMENIAN SMALL LIGATURE MEN INI",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0574, 0x056B },
+ unicodeslot=0xFB15,
+ },
+ [0xFB16]={
+ category="ll",
+ description="ARMENIAN SMALL LIGATURE VEW NOW",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x057E, 0x0576 },
+ unicodeslot=0xFB16,
+ },
+ [0xFB17]={
+ category="ll",
+ description="ARMENIAN SMALL LIGATURE MEN XEH",
+ direction="l",
+ linebreak="al",
+ specials={ "compat", 0x0574, 0x056D },
+ unicodeslot=0xFB17,
+ },
+ [0xFB1D]={
+ category="lo",
+ description="HEBREW LETTER YOD WITH HIRIQ",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D9,
+ specials={ "char", 0x05D9, 0x05B4 },
+ unicodeslot=0xFB1D,
+ },
+ [0xFB1E]={
+ category="mn",
+ description="HEBREW POINT JUDEO-SPANISH VARIKA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFB1E,
+ },
+ [0xFB1F]={
+ adobename="yodyodpatahhebrew",
+ category="lo",
+ description="HEBREW LIGATURE YIDDISH YOD YOD PATAH",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x05F2, 0x05B7 },
+ unicodeslot=0xFB1F,
+ },
+ [0xFB20]={
+ adobename="ayinaltonehebrew",
+ category="lo",
+ description="HEBREW LETTER ALTERNATIVE AYIN",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x05E2 },
+ unicodeslot=0xFB20,
+ },
+ [0xFB21]={
+ category="lo",
+ description="HEBREW LETTER WIDE ALEF",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x05D0 },
+ unicodeslot=0xFB21,
+ },
+ [0xFB22]={
+ category="lo",
+ description="HEBREW LETTER WIDE DALET",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x05D3 },
+ unicodeslot=0xFB22,
+ },
+ [0xFB23]={
+ category="lo",
+ description="HEBREW LETTER WIDE HE",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x05D4 },
+ unicodeslot=0xFB23,
+ },
+ [0xFB24]={
+ category="lo",
+ description="HEBREW LETTER WIDE KAF",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x05DB },
+ unicodeslot=0xFB24,
+ },
+ [0xFB25]={
+ category="lo",
+ description="HEBREW LETTER WIDE LAMED",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x05DC },
+ unicodeslot=0xFB25,
+ },
+ [0xFB26]={
+ category="lo",
+ description="HEBREW LETTER WIDE FINAL MEM",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x05DD },
+ unicodeslot=0xFB26,
+ },
+ [0xFB27]={
+ category="lo",
+ description="HEBREW LETTER WIDE RESH",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x05E8 },
+ unicodeslot=0xFB27,
+ },
+ [0xFB28]={
+ category="lo",
+ description="HEBREW LETTER WIDE TAV",
+ direction="r",
+ linebreak="hl",
+ specials={ "font", 0x05EA },
+ unicodeslot=0xFB28,
+ },
+ [0xFB29]={
+ category="sm",
+ description="HEBREW LETTER ALTERNATIVE PLUS SIGN",
+ direction="es",
+ linebreak="al",
+ specials={ "font", 0x002B },
+ unicodeslot=0xFB29,
+ },
+ [0xFB2A]={
+ adobename="shinshindothebrew",
+ category="lo",
+ description="HEBREW LETTER SHIN WITH SHIN DOT",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05E9,
+ specials={ "char", 0x05E9, 0x05C1 },
+ unicodeslot=0xFB2A,
+ },
+ [0xFB2B]={
+ adobename="shinsindothebrew",
+ category="lo",
+ description="HEBREW LETTER SHIN WITH SIN DOT",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05E9,
+ specials={ "char", 0x05E9, 0x05C2 },
+ unicodeslot=0xFB2B,
+ },
+ [0xFB2C]={
+ adobename="shindageshshindothebrew",
+ category="lo",
+ description="HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05E9,
+ specials={ "char", 0xFB49, 0x05C1 },
+ unicodeslot=0xFB2C,
+ },
+ [0xFB2D]={
+ adobename="shindageshsindothebrew",
+ category="lo",
+ description="HEBREW LETTER SHIN WITH DAGESH AND SIN DOT",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05E9,
+ specials={ "char", 0xFB49, 0x05C2 },
+ unicodeslot=0xFB2D,
+ },
+ [0xFB2E]={
+ adobename="alefpatahhebrew",
+ category="lo",
+ description="HEBREW LETTER ALEF WITH PATAH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D0,
+ specials={ "char", 0x05D0, 0x05B7 },
+ unicodeslot=0xFB2E,
+ },
+ [0xFB2F]={
+ adobename="alefqamatshebrew",
+ category="lo",
+ description="HEBREW LETTER ALEF WITH QAMATS",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D0,
+ specials={ "char", 0x05D0, 0x05B8 },
+ unicodeslot=0xFB2F,
+ },
+ [0xFB30]={
+ adobename="alefdageshhebrew",
+ category="lo",
+ description="HEBREW LETTER ALEF WITH MAPIQ",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D0,
+ specials={ "char", 0x05D0, 0x05BC },
+ unicodeslot=0xFB30,
+ },
+ [0xFB31]={
+ adobename="betdageshhebrew",
+ category="lo",
+ description="HEBREW LETTER BET WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D1,
+ specials={ "char", 0x05D1, 0x05BC },
+ unicodeslot=0xFB31,
+ },
+ [0xFB32]={
+ adobename="gimeldageshhebrew",
+ category="lo",
+ description="HEBREW LETTER GIMEL WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D2,
+ specials={ "char", 0x05D2, 0x05BC },
+ unicodeslot=0xFB32,
+ },
+ [0xFB33]={
+ adobename="daletdageshhebrew",
+ category="lo",
+ description="HEBREW LETTER DALET WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D3,
+ specials={ "char", 0x05D3, 0x05BC },
+ unicodeslot=0xFB33,
+ },
+ [0xFB34]={
+ adobename="hedageshhebrew",
+ category="lo",
+ description="HEBREW LETTER HE WITH MAPIQ",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D4,
+ specials={ "char", 0x05D4, 0x05BC },
+ unicodeslot=0xFB34,
+ },
+ [0xFB35]={
+ adobename="vavdageshhebrew",
+ category="lo",
+ description="HEBREW LETTER VAV WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D5,
+ specials={ "char", 0x05D5, 0x05BC },
+ unicodeslot=0xFB35,
+ },
+ [0xFB36]={
+ adobename="zayindageshhebrew",
+ category="lo",
+ description="HEBREW LETTER ZAYIN WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D6,
+ specials={ "char", 0x05D6, 0x05BC },
+ unicodeslot=0xFB36,
+ },
+ [0xFB38]={
+ adobename="tetdageshhebrew",
+ category="lo",
+ description="HEBREW LETTER TET WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D8,
+ specials={ "char", 0x05D8, 0x05BC },
+ unicodeslot=0xFB38,
+ },
+ [0xFB39]={
+ adobename="yoddageshhebrew",
+ category="lo",
+ description="HEBREW LETTER YOD WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D9,
+ specials={ "char", 0x05D9, 0x05BC },
+ unicodeslot=0xFB39,
+ },
+ [0xFB3A]={
+ adobename="finalkafdageshhebrew",
+ category="lo",
+ description="HEBREW LETTER FINAL KAF WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x05DA, 0x05BC },
+ unicodeslot=0xFB3A,
+ },
+ [0xFB3B]={
+ adobename="kafdageshhebrew",
+ category="lo",
+ description="HEBREW LETTER KAF WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05DB,
+ specials={ "char", 0x05DB, 0x05BC },
+ unicodeslot=0xFB3B,
+ },
+ [0xFB3C]={
+ adobename="lameddageshhebrew",
+ category="lo",
+ description="HEBREW LETTER LAMED WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05DC,
+ specials={ "char", 0x05DC, 0x05BC },
+ unicodeslot=0xFB3C,
+ },
+ [0xFB3E]={
+ adobename="memdageshhebrew",
+ category="lo",
+ description="HEBREW LETTER MEM WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05DE,
+ specials={ "char", 0x05DE, 0x05BC },
+ unicodeslot=0xFB3E,
+ },
+ [0xFB40]={
+ adobename="nundageshhebrew",
+ category="lo",
+ description="HEBREW LETTER NUN WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05E0,
+ specials={ "char", 0x05E0, 0x05BC },
+ unicodeslot=0xFB40,
+ },
+ [0xFB41]={
+ adobename="samekhdageshhebrew",
+ category="lo",
+ description="HEBREW LETTER SAMEKH WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05E1,
+ specials={ "char", 0x05E1, 0x05BC },
+ unicodeslot=0xFB41,
+ },
+ [0xFB43]={
+ adobename="pefinaldageshhebrew",
+ category="lo",
+ description="HEBREW LETTER FINAL PE WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ specials={ "char", 0x05E3, 0x05BC },
+ unicodeslot=0xFB43,
+ },
+ [0xFB44]={
+ adobename="pedageshhebrew",
+ category="lo",
+ description="HEBREW LETTER PE WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05E4,
+ specials={ "char", 0x05E4, 0x05BC },
+ unicodeslot=0xFB44,
+ },
+ [0xFB46]={
+ adobename="tsadidageshhebrew",
+ category="lo",
+ description="HEBREW LETTER TSADI WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05E6,
+ specials={ "char", 0x05E6, 0x05BC },
+ unicodeslot=0xFB46,
+ },
+ [0xFB47]={
+ adobename="qofdageshhebrew",
+ category="lo",
+ description="HEBREW LETTER QOF WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05E7,
+ specials={ "char", 0x05E7, 0x05BC },
+ unicodeslot=0xFB47,
+ },
+ [0xFB48]={
+ adobename="reshdageshhebrew",
+ category="lo",
+ description="HEBREW LETTER RESH WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05E8,
+ specials={ "char", 0x05E8, 0x05BC },
+ unicodeslot=0xFB48,
+ },
+ [0xFB49]={
+ adobename="shindageshhebrew",
+ category="lo",
+ description="HEBREW LETTER SHIN WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05E9,
+ specials={ "char", 0x05E9, 0x05BC },
+ unicodeslot=0xFB49,
+ },
+ [0xFB4A]={
+ adobename="tavdageshhebrew",
+ category="lo",
+ description="HEBREW LETTER TAV WITH DAGESH",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05EA,
+ specials={ "char", 0x05EA, 0x05BC },
+ unicodeslot=0xFB4A,
+ },
+ [0xFB4B]={
+ adobename="vavholamhebrew",
+ category="lo",
+ description="HEBREW LETTER VAV WITH HOLAM",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D5,
+ specials={ "char", 0x05D5, 0x05B9 },
+ unicodeslot=0xFB4B,
+ },
+ [0xFB4C]={
+ adobename="betrafehebrew",
+ category="lo",
+ description="HEBREW LETTER BET WITH RAFE",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05D1,
+ specials={ "char", 0x05D1, 0x05BF },
+ unicodeslot=0xFB4C,
+ },
+ [0xFB4D]={
+ adobename="kafrafehebrew",
+ category="lo",
+ description="HEBREW LETTER KAF WITH RAFE",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05DB,
+ specials={ "char", 0x05DB, 0x05BF },
+ unicodeslot=0xFB4D,
+ },
+ [0xFB4E]={
+ adobename="perafehebrew",
+ category="lo",
+ description="HEBREW LETTER PE WITH RAFE",
+ direction="r",
+ linebreak="hl",
+ shcode=0x05E4,
+ specials={ "char", 0x05E4, 0x05BF },
+ unicodeslot=0xFB4E,
+ },
+ [0xFB4F]={
+ adobename="aleflamedhebrew",
+ category="lo",
+ description="HEBREW LIGATURE ALEF LAMED",
+ direction="r",
+ linebreak="hl",
+ specials={ "compat", 0x05D0, 0x05DC },
+ unicodeslot=0xFB4F,
+ },
+ [0xFB50]={
+ category="lo",
+ description="ARABIC LETTER ALEF WASLA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0671 },
+ unicodeslot=0xFB50,
+ },
+ [0xFB51]={
+ category="lo",
+ description="ARABIC LETTER ALEF WASLA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0671 },
+ unicodeslot=0xFB51,
+ },
+ [0xFB52]={
+ category="lo",
+ description="ARABIC LETTER BEEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x067B },
+ unicodeslot=0xFB52,
+ },
+ [0xFB53]={
+ category="lo",
+ description="ARABIC LETTER BEEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x067B },
+ unicodeslot=0xFB53,
+ },
+ [0xFB54]={
+ category="lo",
+ description="ARABIC LETTER BEEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x067B },
+ unicodeslot=0xFB54,
+ },
+ [0xFB55]={
+ category="lo",
+ description="ARABIC LETTER BEEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x067B },
+ unicodeslot=0xFB55,
+ },
+ [0xFB56]={
+ category="lo",
+ description="ARABIC LETTER PEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x067E },
+ unicodeslot=0xFB56,
+ },
+ [0xFB57]={
+ adobename="pehfinalarabic",
+ category="lo",
+ description="ARABIC LETTER PEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x067E },
+ unicodeslot=0xFB57,
+ },
+ [0xFB58]={
+ adobename="pehinitialarabic",
+ category="lo",
+ description="ARABIC LETTER PEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x067E },
+ unicodeslot=0xFB58,
+ },
+ [0xFB59]={
+ adobename="pehmedialarabic",
+ category="lo",
+ description="ARABIC LETTER PEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x067E },
+ unicodeslot=0xFB59,
+ },
+ [0xFB5A]={
+ category="lo",
+ description="ARABIC LETTER BEHEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0680 },
+ unicodeslot=0xFB5A,
+ },
+ [0xFB5B]={
+ category="lo",
+ description="ARABIC LETTER BEHEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0680 },
+ unicodeslot=0xFB5B,
+ },
+ [0xFB5C]={
+ category="lo",
+ description="ARABIC LETTER BEHEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0680 },
+ unicodeslot=0xFB5C,
+ },
+ [0xFB5D]={
+ category="lo",
+ description="ARABIC LETTER BEHEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0680 },
+ unicodeslot=0xFB5D,
+ },
+ [0xFB5E]={
+ category="lo",
+ description="ARABIC LETTER TTEHEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x067A },
+ unicodeslot=0xFB5E,
+ },
+ [0xFB5F]={
+ category="lo",
+ description="ARABIC LETTER TTEHEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x067A },
+ unicodeslot=0xFB5F,
+ },
+ [0xFB60]={
+ category="lo",
+ description="ARABIC LETTER TTEHEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x067A },
+ unicodeslot=0xFB60,
+ },
+ [0xFB61]={
+ category="lo",
+ description="ARABIC LETTER TTEHEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x067A },
+ unicodeslot=0xFB61,
+ },
+ [0xFB62]={
+ category="lo",
+ description="ARABIC LETTER TEHEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x067F },
+ unicodeslot=0xFB62,
+ },
+ [0xFB63]={
+ category="lo",
+ description="ARABIC LETTER TEHEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x067F },
+ unicodeslot=0xFB63,
+ },
+ [0xFB64]={
+ category="lo",
+ description="ARABIC LETTER TEHEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x067F },
+ unicodeslot=0xFB64,
+ },
+ [0xFB65]={
+ category="lo",
+ description="ARABIC LETTER TEHEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x067F },
+ unicodeslot=0xFB65,
+ },
+ [0xFB66]={
+ category="lo",
+ description="ARABIC LETTER TTEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0679 },
+ unicodeslot=0xFB66,
+ },
+ [0xFB67]={
+ adobename="ttehfinalarabic",
+ category="lo",
+ description="ARABIC LETTER TTEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0679 },
+ unicodeslot=0xFB67,
+ },
+ [0xFB68]={
+ adobename="ttehinitialarabic",
+ category="lo",
+ description="ARABIC LETTER TTEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0679 },
+ unicodeslot=0xFB68,
+ },
+ [0xFB69]={
+ adobename="ttehmedialarabic",
+ category="lo",
+ description="ARABIC LETTER TTEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0679 },
+ unicodeslot=0xFB69,
+ },
+ [0xFB6A]={
+ category="lo",
+ description="ARABIC LETTER VEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06A4 },
+ unicodeslot=0xFB6A,
+ },
+ [0xFB6B]={
+ adobename="vehfinalarabic",
+ category="lo",
+ description="ARABIC LETTER VEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06A4 },
+ unicodeslot=0xFB6B,
+ },
+ [0xFB6C]={
+ adobename="vehinitialarabic",
+ category="lo",
+ description="ARABIC LETTER VEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x06A4 },
+ unicodeslot=0xFB6C,
+ },
+ [0xFB6D]={
+ adobename="vehmedialarabic",
+ category="lo",
+ description="ARABIC LETTER VEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x06A4 },
+ unicodeslot=0xFB6D,
+ },
+ [0xFB6E]={
+ category="lo",
+ description="ARABIC LETTER PEHEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06A6 },
+ unicodeslot=0xFB6E,
+ },
+ [0xFB6F]={
+ category="lo",
+ description="ARABIC LETTER PEHEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06A6 },
+ unicodeslot=0xFB6F,
+ },
+ [0xFB70]={
+ category="lo",
+ description="ARABIC LETTER PEHEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x06A6 },
+ unicodeslot=0xFB70,
+ },
+ [0xFB71]={
+ category="lo",
+ description="ARABIC LETTER PEHEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x06A6 },
+ unicodeslot=0xFB71,
+ },
+ [0xFB72]={
+ category="lo",
+ description="ARABIC LETTER DYEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0684 },
+ unicodeslot=0xFB72,
+ },
+ [0xFB73]={
+ category="lo",
+ description="ARABIC LETTER DYEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0684 },
+ unicodeslot=0xFB73,
+ },
+ [0xFB74]={
+ category="lo",
+ description="ARABIC LETTER DYEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0684 },
+ unicodeslot=0xFB74,
+ },
+ [0xFB75]={
+ category="lo",
+ description="ARABIC LETTER DYEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0684 },
+ unicodeslot=0xFB75,
+ },
+ [0xFB76]={
+ category="lo",
+ description="ARABIC LETTER NYEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0683 },
+ unicodeslot=0xFB76,
+ },
+ [0xFB77]={
+ category="lo",
+ description="ARABIC LETTER NYEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0683 },
+ unicodeslot=0xFB77,
+ },
+ [0xFB78]={
+ category="lo",
+ description="ARABIC LETTER NYEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0683 },
+ unicodeslot=0xFB78,
+ },
+ [0xFB79]={
+ category="lo",
+ description="ARABIC LETTER NYEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0683 },
+ unicodeslot=0xFB79,
+ },
+ [0xFB7A]={
+ category="lo",
+ description="ARABIC LETTER TCHEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0686 },
+ unicodeslot=0xFB7A,
+ },
+ [0xFB7B]={
+ adobename="tchehfinalarabic",
+ category="lo",
+ description="ARABIC LETTER TCHEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0686 },
+ unicodeslot=0xFB7B,
+ },
+ [0xFB7C]={
+ adobename="tchehmeeminitialarabic",
+ category="lo",
+ description="ARABIC LETTER TCHEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0686 },
+ unicodeslot=0xFB7C,
+ },
+ [0xFB7D]={
+ adobename="tchehmedialarabic",
+ category="lo",
+ description="ARABIC LETTER TCHEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0686 },
+ unicodeslot=0xFB7D,
+ },
+ [0xFB7E]={
+ category="lo",
+ description="ARABIC LETTER TCHEHEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0687 },
+ unicodeslot=0xFB7E,
+ },
+ [0xFB7F]={
+ category="lo",
+ description="ARABIC LETTER TCHEHEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0687 },
+ unicodeslot=0xFB7F,
+ },
+ [0xFB80]={
+ category="lo",
+ description="ARABIC LETTER TCHEHEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0687 },
+ unicodeslot=0xFB80,
+ },
+ [0xFB81]={
+ category="lo",
+ description="ARABIC LETTER TCHEHEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0687 },
+ unicodeslot=0xFB81,
+ },
+ [0xFB82]={
+ category="lo",
+ description="ARABIC LETTER DDAHAL ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x068D },
+ unicodeslot=0xFB82,
+ },
+ [0xFB83]={
+ category="lo",
+ description="ARABIC LETTER DDAHAL FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x068D },
+ unicodeslot=0xFB83,
+ },
+ [0xFB84]={
+ category="lo",
+ description="ARABIC LETTER DAHAL ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x068C },
+ unicodeslot=0xFB84,
+ },
+ [0xFB85]={
+ category="lo",
+ description="ARABIC LETTER DAHAL FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x068C },
+ unicodeslot=0xFB85,
+ },
+ [0xFB86]={
+ category="lo",
+ description="ARABIC LETTER DUL ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x068E },
+ unicodeslot=0xFB86,
+ },
+ [0xFB87]={
+ category="lo",
+ description="ARABIC LETTER DUL FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x068E },
+ unicodeslot=0xFB87,
+ },
+ [0xFB88]={
+ category="lo",
+ description="ARABIC LETTER DDAL ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0688 },
+ unicodeslot=0xFB88,
+ },
+ [0xFB89]={
+ adobename="ddalfinalarabic",
+ category="lo",
+ description="ARABIC LETTER DDAL FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0688 },
+ unicodeslot=0xFB89,
+ },
+ [0xFB8A]={
+ category="lo",
+ description="ARABIC LETTER JEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0698 },
+ unicodeslot=0xFB8A,
+ },
+ [0xFB8B]={
+ adobename="jehfinalarabic",
+ category="lo",
+ description="ARABIC LETTER JEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0698 },
+ unicodeslot=0xFB8B,
+ },
+ [0xFB8C]={
+ category="lo",
+ description="ARABIC LETTER RREH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0691 },
+ unicodeslot=0xFB8C,
+ },
+ [0xFB8D]={
+ adobename="rrehfinalarabic",
+ category="lo",
+ description="ARABIC LETTER RREH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0691 },
+ unicodeslot=0xFB8D,
+ },
+ [0xFB8E]={
+ category="lo",
+ description="ARABIC LETTER KEHEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06A9 },
+ unicodeslot=0xFB8E,
+ },
+ [0xFB8F]={
+ category="lo",
+ description="ARABIC LETTER KEHEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06A9 },
+ unicodeslot=0xFB8F,
+ },
+ [0xFB90]={
+ category="lo",
+ description="ARABIC LETTER KEHEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x06A9 },
+ unicodeslot=0xFB90,
+ },
+ [0xFB91]={
+ category="lo",
+ description="ARABIC LETTER KEHEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x06A9 },
+ unicodeslot=0xFB91,
+ },
+ [0xFB92]={
+ category="lo",
+ description="ARABIC LETTER GAF ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06AF },
+ unicodeslot=0xFB92,
+ },
+ [0xFB93]={
+ adobename="gaffinalarabic",
+ category="lo",
+ description="ARABIC LETTER GAF FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06AF },
+ unicodeslot=0xFB93,
+ },
+ [0xFB94]={
+ adobename="gafinitialarabic",
+ category="lo",
+ description="ARABIC LETTER GAF INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x06AF },
+ unicodeslot=0xFB94,
+ },
+ [0xFB95]={
+ adobename="gafmedialarabic",
+ category="lo",
+ description="ARABIC LETTER GAF MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x06AF },
+ unicodeslot=0xFB95,
+ },
+ [0xFB96]={
+ category="lo",
+ description="ARABIC LETTER GUEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06B3 },
+ unicodeslot=0xFB96,
+ },
+ [0xFB97]={
+ category="lo",
+ description="ARABIC LETTER GUEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06B3 },
+ unicodeslot=0xFB97,
+ },
+ [0xFB98]={
+ category="lo",
+ description="ARABIC LETTER GUEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x06B3 },
+ unicodeslot=0xFB98,
+ },
+ [0xFB99]={
+ category="lo",
+ description="ARABIC LETTER GUEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x06B3 },
+ unicodeslot=0xFB99,
+ },
+ [0xFB9A]={
+ category="lo",
+ description="ARABIC LETTER NGOEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06B1 },
+ unicodeslot=0xFB9A,
+ },
+ [0xFB9B]={
+ category="lo",
+ description="ARABIC LETTER NGOEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06B1 },
+ unicodeslot=0xFB9B,
+ },
+ [0xFB9C]={
+ category="lo",
+ description="ARABIC LETTER NGOEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x06B1 },
+ unicodeslot=0xFB9C,
+ },
+ [0xFB9D]={
+ category="lo",
+ description="ARABIC LETTER NGOEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x06B1 },
+ unicodeslot=0xFB9D,
+ },
+ [0xFB9E]={
+ category="lo",
+ description="ARABIC LETTER NOON GHUNNA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06BA },
+ unicodeslot=0xFB9E,
+ },
+ [0xFB9F]={
+ adobename="noonghunnafinalarabic",
+ category="lo",
+ description="ARABIC LETTER NOON GHUNNA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06BA },
+ unicodeslot=0xFB9F,
+ },
+ [0xFBA0]={
+ category="lo",
+ description="ARABIC LETTER RNOON ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06BB },
+ unicodeslot=0xFBA0,
+ },
+ [0xFBA1]={
+ category="lo",
+ description="ARABIC LETTER RNOON FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06BB },
+ unicodeslot=0xFBA1,
+ },
+ [0xFBA2]={
+ category="lo",
+ description="ARABIC LETTER RNOON INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x06BB },
+ unicodeslot=0xFBA2,
+ },
+ [0xFBA3]={
+ category="lo",
+ description="ARABIC LETTER RNOON MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x06BB },
+ unicodeslot=0xFBA3,
+ },
+ [0xFBA4]={
+ adobename="hehhamzaaboveisolatedarabic",
+ category="lo",
+ description="ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x0647,
+ specials={ "isolated", 0x06C0 },
+ unicodeslot=0xFBA4,
+ },
+ [0xFBA5]={
+ adobename="hehhamzaabovefinalarabic",
+ category="lo",
+ description="ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x0647,
+ specials={ "final", 0x06C0 },
+ unicodeslot=0xFBA5,
+ },
+ [0xFBA6]={
+ category="lo",
+ description="ARABIC LETTER HEH GOAL ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06C1 },
+ unicodeslot=0xFBA6,
+ },
+ [0xFBA7]={
+ adobename="hehfinalaltonearabic",
+ category="lo",
+ description="ARABIC LETTER HEH GOAL FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06C1 },
+ unicodeslot=0xFBA7,
+ },
+ [0xFBA8]={
+ adobename="hehinitialaltonearabic",
+ category="lo",
+ description="ARABIC LETTER HEH GOAL INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x06C1 },
+ unicodeslot=0xFBA8,
+ },
+ [0xFBA9]={
+ adobename="hehmedialaltonearabic",
+ category="lo",
+ description="ARABIC LETTER HEH GOAL MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x06C1 },
+ unicodeslot=0xFBA9,
+ },
+ [0xFBAA]={
+ category="lo",
+ description="ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06BE },
+ unicodeslot=0xFBAA,
+ },
+ [0xFBAB]={
+ category="lo",
+ description="ARABIC LETTER HEH DOACHASHMEE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06BE },
+ unicodeslot=0xFBAB,
+ },
+ [0xFBAC]={
+ category="lo",
+ description="ARABIC LETTER HEH DOACHASHMEE INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x06BE },
+ unicodeslot=0xFBAC,
+ },
+ [0xFBAD]={
+ category="lo",
+ description="ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x06BE },
+ unicodeslot=0xFBAD,
+ },
+ [0xFBAE]={
+ category="lo",
+ description="ARABIC LETTER YEH BARREE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06D2 },
+ unicodeslot=0xFBAE,
+ },
+ [0xFBAF]={
+ adobename="yehbarreefinalarabic",
+ category="lo",
+ description="ARABIC LETTER YEH BARREE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06D2 },
+ unicodeslot=0xFBAF,
+ },
+ [0xFBB0]={
+ category="lo",
+ description="ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06D3 },
+ unicodeslot=0xFBB0,
+ },
+ [0xFBB1]={
+ category="lo",
+ description="ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06D3 },
+ unicodeslot=0xFBB1,
+ },
+ [0xFBB2]={
+ category="sk",
+ description="ARABIC SYMBOL DOT ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB2,
+ },
+ [0xFBB3]={
+ category="sk",
+ description="ARABIC SYMBOL DOT BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB3,
+ },
+ [0xFBB4]={
+ category="sk",
+ description="ARABIC SYMBOL TWO DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB4,
+ },
+ [0xFBB5]={
+ category="sk",
+ description="ARABIC SYMBOL TWO DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB5,
+ },
+ [0xFBB6]={
+ category="sk",
+ description="ARABIC SYMBOL THREE DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB6,
+ },
+ [0xFBB7]={
+ category="sk",
+ description="ARABIC SYMBOL THREE DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB7,
+ },
+ [0xFBB8]={
+ category="sk",
+ description="ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB8,
+ },
+ [0xFBB9]={
+ category="sk",
+ description="ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBB9,
+ },
+ [0xFBBA]={
+ category="sk",
+ description="ARABIC SYMBOL FOUR DOTS ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBBA,
+ },
+ [0xFBBB]={
+ category="sk",
+ description="ARABIC SYMBOL FOUR DOTS BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBBB,
+ },
+ [0xFBBC]={
+ category="sk",
+ description="ARABIC SYMBOL DOUBLE VERTICAL BAR BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBBC,
+ },
+ [0xFBBD]={
+ category="sk",
+ description="ARABIC SYMBOL TWO DOTS VERTICALLY ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBBD,
+ },
+ [0xFBBE]={
+ category="sk",
+ description="ARABIC SYMBOL TWO DOTS VERTICALLY BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBBE,
+ },
+ [0xFBBF]={
+ category="sk",
+ description="ARABIC SYMBOL RING",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBBF,
+ },
+ [0xFBC0]={
+ category="sk",
+ description="ARABIC SYMBOL SMALL TAH ABOVE",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBC0,
+ },
+ [0xFBC1]={
+ category="sk",
+ description="ARABIC SYMBOL SMALL TAH BELOW",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFBC1,
+ },
+ [0xFBD3]={
+ category="lo",
+ description="ARABIC LETTER NG ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06AD },
+ unicodeslot=0xFBD3,
+ },
+ [0xFBD4]={
+ category="lo",
+ description="ARABIC LETTER NG FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06AD },
+ unicodeslot=0xFBD4,
+ },
+ [0xFBD5]={
+ category="lo",
+ description="ARABIC LETTER NG INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x06AD },
+ unicodeslot=0xFBD5,
+ },
+ [0xFBD6]={
+ category="lo",
+ description="ARABIC LETTER NG MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x06AD },
+ unicodeslot=0xFBD6,
+ },
+ [0xFBD7]={
+ category="lo",
+ description="ARABIC LETTER U ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06C7 },
+ unicodeslot=0xFBD7,
+ },
+ [0xFBD8]={
+ category="lo",
+ description="ARABIC LETTER U FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06C7 },
+ unicodeslot=0xFBD8,
+ },
+ [0xFBD9]={
+ category="lo",
+ description="ARABIC LETTER OE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06C6 },
+ unicodeslot=0xFBD9,
+ },
+ [0xFBDA]={
+ category="lo",
+ description="ARABIC LETTER OE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06C6 },
+ unicodeslot=0xFBDA,
+ },
+ [0xFBDB]={
+ category="lo",
+ description="ARABIC LETTER YU ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06C8 },
+ unicodeslot=0xFBDB,
+ },
+ [0xFBDC]={
+ category="lo",
+ description="ARABIC LETTER YU FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06C8 },
+ unicodeslot=0xFBDC,
+ },
+ [0xFBDD]={
+ category="lo",
+ description="ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x06C7,
+ specials={ "isolated", 0x0677 },
+ unicodeslot=0xFBDD,
+ },
+ [0xFBDE]={
+ category="lo",
+ description="ARABIC LETTER VE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06CB },
+ unicodeslot=0xFBDE,
+ },
+ [0xFBDF]={
+ category="lo",
+ description="ARABIC LETTER VE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06CB },
+ unicodeslot=0xFBDF,
+ },
+ [0xFBE0]={
+ category="lo",
+ description="ARABIC LETTER KIRGHIZ OE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06C5 },
+ unicodeslot=0xFBE0,
+ },
+ [0xFBE1]={
+ category="lo",
+ description="ARABIC LETTER KIRGHIZ OE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06C5 },
+ unicodeslot=0xFBE1,
+ },
+ [0xFBE2]={
+ category="lo",
+ description="ARABIC LETTER KIRGHIZ YU ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06C9 },
+ unicodeslot=0xFBE2,
+ },
+ [0xFBE3]={
+ category="lo",
+ description="ARABIC LETTER KIRGHIZ YU FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06C9 },
+ unicodeslot=0xFBE3,
+ },
+ [0xFBE4]={
+ category="lo",
+ description="ARABIC LETTER E ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06D0 },
+ unicodeslot=0xFBE4,
+ },
+ [0xFBE5]={
+ category="lo",
+ description="ARABIC LETTER E FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06D0 },
+ unicodeslot=0xFBE5,
+ },
+ [0xFBE6]={
+ category="lo",
+ description="ARABIC LETTER E INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x06D0 },
+ unicodeslot=0xFBE6,
+ },
+ [0xFBE7]={
+ category="lo",
+ description="ARABIC LETTER E MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x06D0 },
+ unicodeslot=0xFBE7,
+ },
+ [0xFBE8]={
+ category="lo",
+ description="ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0649 },
+ unicodeslot=0xFBE8,
+ },
+ [0xFBE9]={
+ category="lo",
+ description="ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0649 },
+ unicodeslot=0xFBE9,
+ },
+ [0xFBEA]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x0627 },
+ unicodeslot=0xFBEA,
+ },
+ [0xFBEB]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x0627 },
+ unicodeslot=0xFBEB,
+ },
+ [0xFBEC]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x06D5 },
+ unicodeslot=0xFBEC,
+ },
+ [0xFBED]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x06D5 },
+ unicodeslot=0xFBED,
+ },
+ [0xFBEE]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x0648 },
+ unicodeslot=0xFBEE,
+ },
+ [0xFBEF]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x0648 },
+ unicodeslot=0xFBEF,
+ },
+ [0xFBF0]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x06C7 },
+ unicodeslot=0xFBF0,
+ },
+ [0xFBF1]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x06C7 },
+ unicodeslot=0xFBF1,
+ },
+ [0xFBF2]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x06C6 },
+ unicodeslot=0xFBF2,
+ },
+ [0xFBF3]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x06C6 },
+ unicodeslot=0xFBF3,
+ },
+ [0xFBF4]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x06C8 },
+ unicodeslot=0xFBF4,
+ },
+ [0xFBF5]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x06C8 },
+ unicodeslot=0xFBF5,
+ },
+ [0xFBF6]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x06D0 },
+ unicodeslot=0xFBF6,
+ },
+ [0xFBF7]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x06D0 },
+ unicodeslot=0xFBF7,
+ },
+ [0xFBF8]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0626, 0x06D0 },
+ unicodeslot=0xFBF8,
+ },
+ [0xFBF9]={
+ category="lo",
+ description="ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x0649 },
+ unicodeslot=0xFBF9,
+ },
+ [0xFBFA]={
+ category="lo",
+ description="ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x0649 },
+ unicodeslot=0xFBFA,
+ },
+ [0xFBFB]={
+ category="lo",
+ description="ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0626, 0x0649 },
+ unicodeslot=0xFBFB,
+ },
+ [0xFBFC]={
+ category="lo",
+ description="ARABIC LETTER FARSI YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x06CC },
+ unicodeslot=0xFBFC,
+ },
+ [0xFBFD]={
+ category="lo",
+ description="ARABIC LETTER FARSI YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x06CC },
+ unicodeslot=0xFBFD,
+ },
+ [0xFBFE]={
+ category="lo",
+ description="ARABIC LETTER FARSI YEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x06CC },
+ unicodeslot=0xFBFE,
+ },
+ [0xFBFF]={
+ category="lo",
+ description="ARABIC LETTER FARSI YEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x06CC },
+ unicodeslot=0xFBFF,
+ },
+ [0xFC00]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x062C },
+ unicodeslot=0xFC00,
+ },
+ [0xFC01]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x062D },
+ unicodeslot=0xFC01,
+ },
+ [0xFC02]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x0645 },
+ unicodeslot=0xFC02,
+ },
+ [0xFC03]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x0649 },
+ unicodeslot=0xFC03,
+ },
+ [0xFC04]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0626, 0x064A },
+ unicodeslot=0xFC04,
+ },
+ [0xFC05]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0628, 0x062C },
+ unicodeslot=0xFC05,
+ },
+ [0xFC06]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0628, 0x062D },
+ unicodeslot=0xFC06,
+ },
+ [0xFC07]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0628, 0x062E },
+ unicodeslot=0xFC07,
+ },
+ [0xFC08]={
+ adobename="behmeemisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0628, 0x0645 },
+ unicodeslot=0xFC08,
+ },
+ [0xFC09]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0628, 0x0649 },
+ unicodeslot=0xFC09,
+ },
+ [0xFC0A]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0628, 0x064A },
+ unicodeslot=0xFC0A,
+ },
+ [0xFC0B]={
+ adobename="tehjeemisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062A, 0x062C },
+ unicodeslot=0xFC0B,
+ },
+ [0xFC0C]={
+ adobename="tehhahisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062A, 0x062D },
+ unicodeslot=0xFC0C,
+ },
+ [0xFC0D]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062A, 0x062E },
+ unicodeslot=0xFC0D,
+ },
+ [0xFC0E]={
+ adobename="tehmeemisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062A, 0x0645 },
+ unicodeslot=0xFC0E,
+ },
+ [0xFC0F]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062A, 0x0649 },
+ unicodeslot=0xFC0F,
+ },
+ [0xFC10]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062A, 0x064A },
+ unicodeslot=0xFC10,
+ },
+ [0xFC11]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062B, 0x062C },
+ unicodeslot=0xFC11,
+ },
+ [0xFC12]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062B, 0x0645 },
+ unicodeslot=0xFC12,
+ },
+ [0xFC13]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062B, 0x0649 },
+ unicodeslot=0xFC13,
+ },
+ [0xFC14]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062B, 0x064A },
+ unicodeslot=0xFC14,
+ },
+ [0xFC15]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062C, 0x062D },
+ unicodeslot=0xFC15,
+ },
+ [0xFC16]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062C, 0x0645 },
+ unicodeslot=0xFC16,
+ },
+ [0xFC17]={
+ category="lo",
+ description="ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062D, 0x062C },
+ unicodeslot=0xFC17,
+ },
+ [0xFC18]={
+ category="lo",
+ description="ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062D, 0x0645 },
+ unicodeslot=0xFC18,
+ },
+ [0xFC19]={
+ category="lo",
+ description="ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062E, 0x062C },
+ unicodeslot=0xFC19,
+ },
+ [0xFC1A]={
+ category="lo",
+ description="ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062E, 0x062D },
+ unicodeslot=0xFC1A,
+ },
+ [0xFC1B]={
+ category="lo",
+ description="ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062E, 0x0645 },
+ unicodeslot=0xFC1B,
+ },
+ [0xFC1C]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0633, 0x062C },
+ unicodeslot=0xFC1C,
+ },
+ [0xFC1D]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0633, 0x062D },
+ unicodeslot=0xFC1D,
+ },
+ [0xFC1E]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0633, 0x062E },
+ unicodeslot=0xFC1E,
+ },
+ [0xFC1F]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0633, 0x0645 },
+ unicodeslot=0xFC1F,
+ },
+ [0xFC20]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0635, 0x062D },
+ unicodeslot=0xFC20,
+ },
+ [0xFC21]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0635, 0x0645 },
+ unicodeslot=0xFC21,
+ },
+ [0xFC22]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0636, 0x062C },
+ unicodeslot=0xFC22,
+ },
+ [0xFC23]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0636, 0x062D },
+ unicodeslot=0xFC23,
+ },
+ [0xFC24]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0636, 0x062E },
+ unicodeslot=0xFC24,
+ },
+ [0xFC25]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0636, 0x0645 },
+ unicodeslot=0xFC25,
+ },
+ [0xFC26]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0637, 0x062D },
+ unicodeslot=0xFC26,
+ },
+ [0xFC27]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0637, 0x0645 },
+ unicodeslot=0xFC27,
+ },
+ [0xFC28]={
+ category="lo",
+ description="ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0638, 0x0645 },
+ unicodeslot=0xFC28,
+ },
+ [0xFC29]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0639, 0x062C },
+ unicodeslot=0xFC29,
+ },
+ [0xFC2A]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0639, 0x0645 },
+ unicodeslot=0xFC2A,
+ },
+ [0xFC2B]={
+ category="lo",
+ description="ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x063A, 0x062C },
+ unicodeslot=0xFC2B,
+ },
+ [0xFC2C]={
+ category="lo",
+ description="ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x063A, 0x0645 },
+ unicodeslot=0xFC2C,
+ },
+ [0xFC2D]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0641, 0x062C },
+ unicodeslot=0xFC2D,
+ },
+ [0xFC2E]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0641, 0x062D },
+ unicodeslot=0xFC2E,
+ },
+ [0xFC2F]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0641, 0x062E },
+ unicodeslot=0xFC2F,
+ },
+ [0xFC30]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0641, 0x0645 },
+ unicodeslot=0xFC30,
+ },
+ [0xFC31]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0641, 0x0649 },
+ unicodeslot=0xFC31,
+ },
+ [0xFC32]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0641, 0x064A },
+ unicodeslot=0xFC32,
+ },
+ [0xFC33]={
+ category="lo",
+ description="ARABIC LIGATURE QAF WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0642, 0x062D },
+ unicodeslot=0xFC33,
+ },
+ [0xFC34]={
+ category="lo",
+ description="ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0642, 0x0645 },
+ unicodeslot=0xFC34,
+ },
+ [0xFC35]={
+ category="lo",
+ description="ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0642, 0x0649 },
+ unicodeslot=0xFC35,
+ },
+ [0xFC36]={
+ category="lo",
+ description="ARABIC LIGATURE QAF WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0642, 0x064A },
+ unicodeslot=0xFC36,
+ },
+ [0xFC37]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0643, 0x0627 },
+ unicodeslot=0xFC37,
+ },
+ [0xFC38]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0643, 0x062C },
+ unicodeslot=0xFC38,
+ },
+ [0xFC39]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0643, 0x062D },
+ unicodeslot=0xFC39,
+ },
+ [0xFC3A]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0643, 0x062E },
+ unicodeslot=0xFC3A,
+ },
+ [0xFC3B]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH LAM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0643, 0x0644 },
+ unicodeslot=0xFC3B,
+ },
+ [0xFC3C]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0643, 0x0645 },
+ unicodeslot=0xFC3C,
+ },
+ [0xFC3D]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0643, 0x0649 },
+ unicodeslot=0xFC3D,
+ },
+ [0xFC3E]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0643, 0x064A },
+ unicodeslot=0xFC3E,
+ },
+ [0xFC3F]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0644, 0x062C },
+ unicodeslot=0xFC3F,
+ },
+ [0xFC40]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0644, 0x062D },
+ unicodeslot=0xFC40,
+ },
+ [0xFC41]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0644, 0x062E },
+ unicodeslot=0xFC41,
+ },
+ [0xFC42]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0644, 0x0645 },
+ unicodeslot=0xFC42,
+ },
+ [0xFC43]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0644, 0x0649 },
+ unicodeslot=0xFC43,
+ },
+ [0xFC44]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0644, 0x064A },
+ unicodeslot=0xFC44,
+ },
+ [0xFC45]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0645, 0x062C },
+ unicodeslot=0xFC45,
+ },
+ [0xFC46]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0645, 0x062D },
+ unicodeslot=0xFC46,
+ },
+ [0xFC47]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0645, 0x062E },
+ unicodeslot=0xFC47,
+ },
+ [0xFC48]={
+ adobename="meemmeemisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0645, 0x0645 },
+ unicodeslot=0xFC48,
+ },
+ [0xFC49]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0645, 0x0649 },
+ unicodeslot=0xFC49,
+ },
+ [0xFC4A]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0645, 0x064A },
+ unicodeslot=0xFC4A,
+ },
+ [0xFC4B]={
+ adobename="noonjeemisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0646, 0x062C },
+ unicodeslot=0xFC4B,
+ },
+ [0xFC4C]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0646, 0x062D },
+ unicodeslot=0xFC4C,
+ },
+ [0xFC4D]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0646, 0x062E },
+ unicodeslot=0xFC4D,
+ },
+ [0xFC4E]={
+ adobename="noonmeemisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0646, 0x0645 },
+ unicodeslot=0xFC4E,
+ },
+ [0xFC4F]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0646, 0x0649 },
+ unicodeslot=0xFC4F,
+ },
+ [0xFC50]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0646, 0x064A },
+ unicodeslot=0xFC50,
+ },
+ [0xFC51]={
+ category="lo",
+ description="ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0647, 0x062C },
+ unicodeslot=0xFC51,
+ },
+ [0xFC52]={
+ category="lo",
+ description="ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0647, 0x0645 },
+ unicodeslot=0xFC52,
+ },
+ [0xFC53]={
+ category="lo",
+ description="ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0647, 0x0649 },
+ unicodeslot=0xFC53,
+ },
+ [0xFC54]={
+ category="lo",
+ description="ARABIC LIGATURE HEH WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0647, 0x064A },
+ unicodeslot=0xFC54,
+ },
+ [0xFC55]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x064A, 0x062C },
+ unicodeslot=0xFC55,
+ },
+ [0xFC56]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x064A, 0x062D },
+ unicodeslot=0xFC56,
+ },
+ [0xFC57]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x064A, 0x062E },
+ unicodeslot=0xFC57,
+ },
+ [0xFC58]={
+ adobename="yehmeemisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x064A, 0x0645 },
+ unicodeslot=0xFC58,
+ },
+ [0xFC59]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x064A, 0x0649 },
+ unicodeslot=0xFC59,
+ },
+ [0xFC5A]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x064A, 0x064A },
+ unicodeslot=0xFC5A,
+ },
+ [0xFC5B]={
+ category="lo",
+ description="ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0630, 0x0670 },
+ unicodeslot=0xFC5B,
+ },
+ [0xFC5C]={
+ category="lo",
+ description="ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0631, 0x0670 },
+ unicodeslot=0xFC5C,
+ },
+ [0xFC5D]={
+ category="lo",
+ description="ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0649, 0x0670 },
+ unicodeslot=0xFC5D,
+ },
+ [0xFC5E]={
+ adobename="shaddadammatanarabic",
+ category="lo",
+ description="ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x064C, 0x0651 },
+ unicodeslot=0xFC5E,
+ },
+ [0xFC5F]={
+ adobename="shaddakasratanarabic",
+ category="lo",
+ description="ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x064D, 0x0651 },
+ unicodeslot=0xFC5F,
+ },
+ [0xFC60]={
+ adobename="shaddafathaarabic",
+ category="lo",
+ description="ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x064E, 0x0651 },
+ unicodeslot=0xFC60,
+ },
+ [0xFC61]={
+ adobename="shaddadammaarabic",
+ category="lo",
+ description="ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x064F, 0x0651 },
+ unicodeslot=0xFC61,
+ },
+ [0xFC62]={
+ adobename="shaddakasraarabic",
+ category="lo",
+ description="ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x0650, 0x0651 },
+ unicodeslot=0xFC62,
+ },
+ [0xFC63]={
+ category="lo",
+ description="ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x0651, 0x0670 },
+ unicodeslot=0xFC63,
+ },
+ [0xFC64]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x0631 },
+ unicodeslot=0xFC64,
+ },
+ [0xFC65]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x0632 },
+ unicodeslot=0xFC65,
+ },
+ [0xFC66]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x0645 },
+ unicodeslot=0xFC66,
+ },
+ [0xFC67]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x0646 },
+ unicodeslot=0xFC67,
+ },
+ [0xFC68]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x0649 },
+ unicodeslot=0xFC68,
+ },
+ [0xFC69]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0626, 0x064A },
+ unicodeslot=0xFC69,
+ },
+ [0xFC6A]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH REH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0628, 0x0631 },
+ unicodeslot=0xFC6A,
+ },
+ [0xFC6B]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH ZAIN FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0628, 0x0632 },
+ unicodeslot=0xFC6B,
+ },
+ [0xFC6C]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0628, 0x0645 },
+ unicodeslot=0xFC6C,
+ },
+ [0xFC6D]={
+ adobename="behnoonfinalarabic",
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH NOON FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0628, 0x0646 },
+ unicodeslot=0xFC6D,
+ },
+ [0xFC6E]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0628, 0x0649 },
+ unicodeslot=0xFC6E,
+ },
+ [0xFC6F]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0628, 0x064A },
+ unicodeslot=0xFC6F,
+ },
+ [0xFC70]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH REH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x0631 },
+ unicodeslot=0xFC70,
+ },
+ [0xFC71]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH ZAIN FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x0632 },
+ unicodeslot=0xFC71,
+ },
+ [0xFC72]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x0645 },
+ unicodeslot=0xFC72,
+ },
+ [0xFC73]={
+ adobename="tehnoonfinalarabic",
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH NOON FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x0646 },
+ unicodeslot=0xFC73,
+ },
+ [0xFC74]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x0649 },
+ unicodeslot=0xFC74,
+ },
+ [0xFC75]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x064A },
+ unicodeslot=0xFC75,
+ },
+ [0xFC76]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH REH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062B, 0x0631 },
+ unicodeslot=0xFC76,
+ },
+ [0xFC77]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH ZAIN FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062B, 0x0632 },
+ unicodeslot=0xFC77,
+ },
+ [0xFC78]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062B, 0x0645 },
+ unicodeslot=0xFC78,
+ },
+ [0xFC79]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH NOON FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062B, 0x0646 },
+ unicodeslot=0xFC79,
+ },
+ [0xFC7A]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062B, 0x0649 },
+ unicodeslot=0xFC7A,
+ },
+ [0xFC7B]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062B, 0x064A },
+ unicodeslot=0xFC7B,
+ },
+ [0xFC7C]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0641, 0x0649 },
+ unicodeslot=0xFC7C,
+ },
+ [0xFC7D]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0641, 0x064A },
+ unicodeslot=0xFC7D,
+ },
+ [0xFC7E]={
+ category="lo",
+ description="ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0642, 0x0649 },
+ unicodeslot=0xFC7E,
+ },
+ [0xFC7F]={
+ category="lo",
+ description="ARABIC LIGATURE QAF WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0642, 0x064A },
+ unicodeslot=0xFC7F,
+ },
+ [0xFC80]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH ALEF FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0643, 0x0627 },
+ unicodeslot=0xFC80,
+ },
+ [0xFC81]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH LAM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0643, 0x0644 },
+ unicodeslot=0xFC81,
+ },
+ [0xFC82]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0643, 0x0645 },
+ unicodeslot=0xFC82,
+ },
+ [0xFC83]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0643, 0x0649 },
+ unicodeslot=0xFC83,
+ },
+ [0xFC84]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0643, 0x064A },
+ unicodeslot=0xFC84,
+ },
+ [0xFC85]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x0645 },
+ unicodeslot=0xFC85,
+ },
+ [0xFC86]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x0649 },
+ unicodeslot=0xFC86,
+ },
+ [0xFC87]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x064A },
+ unicodeslot=0xFC87,
+ },
+ [0xFC88]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH ALEF FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0645, 0x0627 },
+ unicodeslot=0xFC88,
+ },
+ [0xFC89]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0645, 0x0645 },
+ unicodeslot=0xFC89,
+ },
+ [0xFC8A]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH REH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x0631 },
+ unicodeslot=0xFC8A,
+ },
+ [0xFC8B]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH ZAIN FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x0632 },
+ unicodeslot=0xFC8B,
+ },
+ [0xFC8C]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x0645 },
+ unicodeslot=0xFC8C,
+ },
+ [0xFC8D]={
+ adobename="noonnoonfinalarabic",
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH NOON FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x0646 },
+ unicodeslot=0xFC8D,
+ },
+ [0xFC8E]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x0649 },
+ unicodeslot=0xFC8E,
+ },
+ [0xFC8F]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x064A },
+ unicodeslot=0xFC8F,
+ },
+ [0xFC90]={
+ category="lo",
+ description="ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0649, 0x0670 },
+ unicodeslot=0xFC90,
+ },
+ [0xFC91]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH REH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x064A, 0x0631 },
+ unicodeslot=0xFC91,
+ },
+ [0xFC92]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH ZAIN FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x064A, 0x0632 },
+ unicodeslot=0xFC92,
+ },
+ [0xFC93]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x064A, 0x0645 },
+ unicodeslot=0xFC93,
+ },
+ [0xFC94]={
+ adobename="yehnoonfinalarabic",
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH NOON FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x064A, 0x0646 },
+ unicodeslot=0xFC94,
+ },
+ [0xFC95]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x064A, 0x0649 },
+ unicodeslot=0xFC95,
+ },
+ [0xFC96]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x064A, 0x064A },
+ unicodeslot=0xFC96,
+ },
+ [0xFC97]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0626, 0x062C },
+ unicodeslot=0xFC97,
+ },
+ [0xFC98]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0626, 0x062D },
+ unicodeslot=0xFC98,
+ },
+ [0xFC99]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0626, 0x062E },
+ unicodeslot=0xFC99,
+ },
+ [0xFC9A]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0626, 0x0645 },
+ unicodeslot=0xFC9A,
+ },
+ [0xFC9B]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0626, 0x0647 },
+ unicodeslot=0xFC9B,
+ },
+ [0xFC9C]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0628, 0x062C },
+ unicodeslot=0xFC9C,
+ },
+ [0xFC9D]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0628, 0x062D },
+ unicodeslot=0xFC9D,
+ },
+ [0xFC9E]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0628, 0x062E },
+ unicodeslot=0xFC9E,
+ },
+ [0xFC9F]={
+ adobename="behmeeminitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0628, 0x0645 },
+ unicodeslot=0xFC9F,
+ },
+ [0xFCA0]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH HEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0628, 0x0647 },
+ unicodeslot=0xFCA0,
+ },
+ [0xFCA1]={
+ adobename="tehjeeminitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A, 0x062C },
+ unicodeslot=0xFCA1,
+ },
+ [0xFCA2]={
+ adobename="tehhahinitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A, 0x062D },
+ unicodeslot=0xFCA2,
+ },
+ [0xFCA3]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A, 0x062E },
+ unicodeslot=0xFCA3,
+ },
+ [0xFCA4]={
+ adobename="tehmeeminitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A, 0x0645 },
+ unicodeslot=0xFCA4,
+ },
+ [0xFCA5]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH HEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A, 0x0647 },
+ unicodeslot=0xFCA5,
+ },
+ [0xFCA6]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062B, 0x0645 },
+ unicodeslot=0xFCA6,
+ },
+ [0xFCA7]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062C, 0x062D },
+ unicodeslot=0xFCA7,
+ },
+ [0xFCA8]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062C, 0x0645 },
+ unicodeslot=0xFCA8,
+ },
+ [0xFCA9]={
+ category="lo",
+ description="ARABIC LIGATURE HAH WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062D, 0x062C },
+ unicodeslot=0xFCA9,
+ },
+ [0xFCAA]={
+ category="lo",
+ description="ARABIC LIGATURE HAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062D, 0x0645 },
+ unicodeslot=0xFCAA,
+ },
+ [0xFCAB]={
+ category="lo",
+ description="ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062E, 0x062C },
+ unicodeslot=0xFCAB,
+ },
+ [0xFCAC]={
+ category="lo",
+ description="ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062E, 0x0645 },
+ unicodeslot=0xFCAC,
+ },
+ [0xFCAD]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0633, 0x062C },
+ unicodeslot=0xFCAD,
+ },
+ [0xFCAE]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0633, 0x062D },
+ unicodeslot=0xFCAE,
+ },
+ [0xFCAF]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0633, 0x062E },
+ unicodeslot=0xFCAF,
+ },
+ [0xFCB0]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0633, 0x0645 },
+ unicodeslot=0xFCB0,
+ },
+ [0xFCB1]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0635, 0x062D },
+ unicodeslot=0xFCB1,
+ },
+ [0xFCB2]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0635, 0x062E },
+ unicodeslot=0xFCB2,
+ },
+ [0xFCB3]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0635, 0x0645 },
+ unicodeslot=0xFCB3,
+ },
+ [0xFCB4]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0636, 0x062C },
+ unicodeslot=0xFCB4,
+ },
+ [0xFCB5]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0636, 0x062D },
+ unicodeslot=0xFCB5,
+ },
+ [0xFCB6]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0636, 0x062E },
+ unicodeslot=0xFCB6,
+ },
+ [0xFCB7]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0636, 0x0645 },
+ unicodeslot=0xFCB7,
+ },
+ [0xFCB8]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0637, 0x062D },
+ unicodeslot=0xFCB8,
+ },
+ [0xFCB9]={
+ category="lo",
+ description="ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0638, 0x0645 },
+ unicodeslot=0xFCB9,
+ },
+ [0xFCBA]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0639, 0x062C },
+ unicodeslot=0xFCBA,
+ },
+ [0xFCBB]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0639, 0x0645 },
+ unicodeslot=0xFCBB,
+ },
+ [0xFCBC]={
+ category="lo",
+ description="ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x063A, 0x062C },
+ unicodeslot=0xFCBC,
+ },
+ [0xFCBD]={
+ category="lo",
+ description="ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x063A, 0x0645 },
+ unicodeslot=0xFCBD,
+ },
+ [0xFCBE]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0641, 0x062C },
+ unicodeslot=0xFCBE,
+ },
+ [0xFCBF]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0641, 0x062D },
+ unicodeslot=0xFCBF,
+ },
+ [0xFCC0]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0641, 0x062E },
+ unicodeslot=0xFCC0,
+ },
+ [0xFCC1]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0641, 0x0645 },
+ unicodeslot=0xFCC1,
+ },
+ [0xFCC2]={
+ category="lo",
+ description="ARABIC LIGATURE QAF WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0642, 0x062D },
+ unicodeslot=0xFCC2,
+ },
+ [0xFCC3]={
+ category="lo",
+ description="ARABIC LIGATURE QAF WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0642, 0x0645 },
+ unicodeslot=0xFCC3,
+ },
+ [0xFCC4]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0643, 0x062C },
+ unicodeslot=0xFCC4,
+ },
+ [0xFCC5]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0643, 0x062D },
+ unicodeslot=0xFCC5,
+ },
+ [0xFCC6]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0643, 0x062E },
+ unicodeslot=0xFCC6,
+ },
+ [0xFCC7]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH LAM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0643, 0x0644 },
+ unicodeslot=0xFCC7,
+ },
+ [0xFCC8]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0643, 0x0645 },
+ unicodeslot=0xFCC8,
+ },
+ [0xFCC9]={
+ adobename="lamjeeminitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0644, 0x062C },
+ unicodeslot=0xFCC9,
+ },
+ [0xFCCA]={
+ adobename="lamhahinitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0644, 0x062D },
+ unicodeslot=0xFCCA,
+ },
+ [0xFCCB]={
+ adobename="lamkhahinitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0644, 0x062E },
+ unicodeslot=0xFCCB,
+ },
+ [0xFCCC]={
+ adobename="lammeeminitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0644, 0x0645 },
+ unicodeslot=0xFCCC,
+ },
+ [0xFCCD]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH HEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0644, 0x0647 },
+ unicodeslot=0xFCCD,
+ },
+ [0xFCCE]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0645, 0x062C },
+ unicodeslot=0xFCCE,
+ },
+ [0xFCCF]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0645, 0x062D },
+ unicodeslot=0xFCCF,
+ },
+ [0xFCD0]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0645, 0x062E },
+ unicodeslot=0xFCD0,
+ },
+ [0xFCD1]={
+ adobename="meemmeeminitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0645, 0x0645 },
+ unicodeslot=0xFCD1,
+ },
+ [0xFCD2]={
+ adobename="noonjeeminitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0646, 0x062C },
+ unicodeslot=0xFCD2,
+ },
+ [0xFCD3]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0646, 0x062D },
+ unicodeslot=0xFCD3,
+ },
+ [0xFCD4]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0646, 0x062E },
+ unicodeslot=0xFCD4,
+ },
+ [0xFCD5]={
+ adobename="noonmeeminitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0646, 0x0645 },
+ unicodeslot=0xFCD5,
+ },
+ [0xFCD6]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH HEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0646, 0x0647 },
+ unicodeslot=0xFCD6,
+ },
+ [0xFCD7]={
+ category="lo",
+ description="ARABIC LIGATURE HEH WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0647, 0x062C },
+ unicodeslot=0xFCD7,
+ },
+ [0xFCD8]={
+ category="lo",
+ description="ARABIC LIGATURE HEH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0647, 0x0645 },
+ unicodeslot=0xFCD8,
+ },
+ [0xFCD9]={
+ category="lo",
+ description="ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0647, 0x0670 },
+ unicodeslot=0xFCD9,
+ },
+ [0xFCDA]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x064A, 0x062C },
+ unicodeslot=0xFCDA,
+ },
+ [0xFCDB]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x064A, 0x062D },
+ unicodeslot=0xFCDB,
+ },
+ [0xFCDC]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x064A, 0x062E },
+ unicodeslot=0xFCDC,
+ },
+ [0xFCDD]={
+ adobename="yehmeeminitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x064A, 0x0645 },
+ unicodeslot=0xFCDD,
+ },
+ [0xFCDE]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x064A, 0x0647 },
+ unicodeslot=0xFCDE,
+ },
+ [0xFCDF]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0626, 0x0645 },
+ unicodeslot=0xFCDF,
+ },
+ [0xFCE0]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0626, 0x0647 },
+ unicodeslot=0xFCE0,
+ },
+ [0xFCE1]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0628, 0x0645 },
+ unicodeslot=0xFCE1,
+ },
+ [0xFCE2]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH HEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0628, 0x0647 },
+ unicodeslot=0xFCE2,
+ },
+ [0xFCE3]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x062A, 0x0645 },
+ unicodeslot=0xFCE3,
+ },
+ [0xFCE4]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH HEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x062A, 0x0647 },
+ unicodeslot=0xFCE4,
+ },
+ [0xFCE5]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x062B, 0x0645 },
+ unicodeslot=0xFCE5,
+ },
+ [0xFCE6]={
+ category="lo",
+ description="ARABIC LIGATURE THEH WITH HEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x062B, 0x0647 },
+ unicodeslot=0xFCE6,
+ },
+ [0xFCE7]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0633, 0x0645 },
+ unicodeslot=0xFCE7,
+ },
+ [0xFCE8]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0633, 0x0647 },
+ unicodeslot=0xFCE8,
+ },
+ [0xFCE9]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0634, 0x0645 },
+ unicodeslot=0xFCE9,
+ },
+ [0xFCEA]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0634, 0x0647 },
+ unicodeslot=0xFCEA,
+ },
+ [0xFCEB]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH LAM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0643, 0x0644 },
+ unicodeslot=0xFCEB,
+ },
+ [0xFCEC]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0643, 0x0645 },
+ unicodeslot=0xFCEC,
+ },
+ [0xFCED]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0644, 0x0645 },
+ unicodeslot=0xFCED,
+ },
+ [0xFCEE]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0646, 0x0645 },
+ unicodeslot=0xFCEE,
+ },
+ [0xFCEF]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH HEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0646, 0x0647 },
+ unicodeslot=0xFCEF,
+ },
+ [0xFCF0]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x064A, 0x0645 },
+ unicodeslot=0xFCF0,
+ },
+ [0xFCF1]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x064A, 0x0647 },
+ unicodeslot=0xFCF1,
+ },
+ [0xFCF2]={
+ category="lo",
+ description="ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0640, 0x064E, 0x0651 },
+ unicodeslot=0xFCF2,
+ },
+ [0xFCF3]={
+ category="lo",
+ description="ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0640, 0x064F, 0x0651 },
+ unicodeslot=0xFCF3,
+ },
+ [0xFCF4]={
+ category="lo",
+ description="ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0640, 0x0650, 0x0651 },
+ unicodeslot=0xFCF4,
+ },
+ [0xFCF5]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0637, 0x0649 },
+ unicodeslot=0xFCF5,
+ },
+ [0xFCF6]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0637, 0x064A },
+ unicodeslot=0xFCF6,
+ },
+ [0xFCF7]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0639, 0x0649 },
+ unicodeslot=0xFCF7,
+ },
+ [0xFCF8]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0639, 0x064A },
+ unicodeslot=0xFCF8,
+ },
+ [0xFCF9]={
+ category="lo",
+ description="ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x063A, 0x0649 },
+ unicodeslot=0xFCF9,
+ },
+ [0xFCFA]={
+ category="lo",
+ description="ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x063A, 0x064A },
+ unicodeslot=0xFCFA,
+ },
+ [0xFCFB]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0633, 0x0649 },
+ unicodeslot=0xFCFB,
+ },
+ [0xFCFC]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0633, 0x064A },
+ unicodeslot=0xFCFC,
+ },
+ [0xFCFD]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0634, 0x0649 },
+ unicodeslot=0xFCFD,
+ },
+ [0xFCFE]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0634, 0x064A },
+ unicodeslot=0xFCFE,
+ },
+ [0xFCFF]={
+ category="lo",
+ description="ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062D, 0x0649 },
+ unicodeslot=0xFCFF,
+ },
+ [0xFD00]={
+ category="lo",
+ description="ARABIC LIGATURE HAH WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062D, 0x064A },
+ unicodeslot=0xFD00,
+ },
+ [0xFD01]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062C, 0x0649 },
+ unicodeslot=0xFD01,
+ },
+ [0xFD02]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062C, 0x064A },
+ unicodeslot=0xFD02,
+ },
+ [0xFD03]={
+ category="lo",
+ description="ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062E, 0x0649 },
+ unicodeslot=0xFD03,
+ },
+ [0xFD04]={
+ category="lo",
+ description="ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062E, 0x064A },
+ unicodeslot=0xFD04,
+ },
+ [0xFD05]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0635, 0x0649 },
+ unicodeslot=0xFD05,
+ },
+ [0xFD06]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0635, 0x064A },
+ unicodeslot=0xFD06,
+ },
+ [0xFD07]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0636, 0x0649 },
+ unicodeslot=0xFD07,
+ },
+ [0xFD08]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0636, 0x064A },
+ unicodeslot=0xFD08,
+ },
+ [0xFD09]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0634, 0x062C },
+ unicodeslot=0xFD09,
+ },
+ [0xFD0A]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0634, 0x062D },
+ unicodeslot=0xFD0A,
+ },
+ [0xFD0B]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0634, 0x062E },
+ unicodeslot=0xFD0B,
+ },
+ [0xFD0C]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0634, 0x0645 },
+ unicodeslot=0xFD0C,
+ },
+ [0xFD0D]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0634, 0x0631 },
+ unicodeslot=0xFD0D,
+ },
+ [0xFD0E]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH REH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0633, 0x0631 },
+ unicodeslot=0xFD0E,
+ },
+ [0xFD0F]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH REH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0635, 0x0631 },
+ unicodeslot=0xFD0F,
+ },
+ [0xFD10]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH REH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0636, 0x0631 },
+ unicodeslot=0xFD10,
+ },
+ [0xFD11]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0637, 0x0649 },
+ unicodeslot=0xFD11,
+ },
+ [0xFD12]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0637, 0x064A },
+ unicodeslot=0xFD12,
+ },
+ [0xFD13]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0639, 0x0649 },
+ unicodeslot=0xFD13,
+ },
+ [0xFD14]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0639, 0x064A },
+ unicodeslot=0xFD14,
+ },
+ [0xFD15]={
+ category="lo",
+ description="ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x063A, 0x0649 },
+ unicodeslot=0xFD15,
+ },
+ [0xFD16]={
+ category="lo",
+ description="ARABIC LIGATURE GHAIN WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x063A, 0x064A },
+ unicodeslot=0xFD16,
+ },
+ [0xFD17]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0633, 0x0649 },
+ unicodeslot=0xFD17,
+ },
+ [0xFD18]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0633, 0x064A },
+ unicodeslot=0xFD18,
+ },
+ [0xFD19]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634, 0x0649 },
+ unicodeslot=0xFD19,
+ },
+ [0xFD1A]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634, 0x064A },
+ unicodeslot=0xFD1A,
+ },
+ [0xFD1B]={
+ category="lo",
+ description="ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062D, 0x0649 },
+ unicodeslot=0xFD1B,
+ },
+ [0xFD1C]={
+ category="lo",
+ description="ARABIC LIGATURE HAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062D, 0x064A },
+ unicodeslot=0xFD1C,
+ },
+ [0xFD1D]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062C, 0x0649 },
+ unicodeslot=0xFD1D,
+ },
+ [0xFD1E]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062C, 0x064A },
+ unicodeslot=0xFD1E,
+ },
+ [0xFD1F]={
+ category="lo",
+ description="ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062E, 0x0649 },
+ unicodeslot=0xFD1F,
+ },
+ [0xFD20]={
+ category="lo",
+ description="ARABIC LIGATURE KHAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062E, 0x064A },
+ unicodeslot=0xFD20,
+ },
+ [0xFD21]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0635, 0x0649 },
+ unicodeslot=0xFD21,
+ },
+ [0xFD22]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0635, 0x064A },
+ unicodeslot=0xFD22,
+ },
+ [0xFD23]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0636, 0x0649 },
+ unicodeslot=0xFD23,
+ },
+ [0xFD24]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0636, 0x064A },
+ unicodeslot=0xFD24,
+ },
+ [0xFD25]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634, 0x062C },
+ unicodeslot=0xFD25,
+ },
+ [0xFD26]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH HAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634, 0x062D },
+ unicodeslot=0xFD26,
+ },
+ [0xFD27]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634, 0x062E },
+ unicodeslot=0xFD27,
+ },
+ [0xFD28]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634, 0x0645 },
+ unicodeslot=0xFD28,
+ },
+ [0xFD29]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH REH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634, 0x0631 },
+ unicodeslot=0xFD29,
+ },
+ [0xFD2A]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH REH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0633, 0x0631 },
+ unicodeslot=0xFD2A,
+ },
+ [0xFD2B]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH REH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0635, 0x0631 },
+ unicodeslot=0xFD2B,
+ },
+ [0xFD2C]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH REH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0636, 0x0631 },
+ unicodeslot=0xFD2C,
+ },
+ [0xFD2D]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0634, 0x062C },
+ unicodeslot=0xFD2D,
+ },
+ [0xFD2E]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0634, 0x062D },
+ unicodeslot=0xFD2E,
+ },
+ [0xFD2F]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0634, 0x062E },
+ unicodeslot=0xFD2F,
+ },
+ [0xFD30]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0634, 0x0645 },
+ unicodeslot=0xFD30,
+ },
+ [0xFD31]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH HEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0633, 0x0647 },
+ unicodeslot=0xFD31,
+ },
+ [0xFD32]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0634, 0x0647 },
+ unicodeslot=0xFD32,
+ },
+ [0xFD33]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0637, 0x0645 },
+ unicodeslot=0xFD33,
+ },
+ [0xFD34]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0633, 0x062C },
+ unicodeslot=0xFD34,
+ },
+ [0xFD35]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0633, 0x062D },
+ unicodeslot=0xFD35,
+ },
+ [0xFD36]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0633, 0x062E },
+ unicodeslot=0xFD36,
+ },
+ [0xFD37]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0634, 0x062C },
+ unicodeslot=0xFD37,
+ },
+ [0xFD38]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0634, 0x062D },
+ unicodeslot=0xFD38,
+ },
+ [0xFD39]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0634, 0x062E },
+ unicodeslot=0xFD39,
+ },
+ [0xFD3A]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0637, 0x0645 },
+ unicodeslot=0xFD3A,
+ },
+ [0xFD3B]={
+ category="lo",
+ description="ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0638, 0x0645 },
+ unicodeslot=0xFD3B,
+ },
+ [0xFD3C]={
+ category="lo",
+ description="ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0627, 0x064B },
+ unicodeslot=0xFD3C,
+ },
+ [0xFD3D]={
+ category="lo",
+ description="ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0627, 0x064B },
+ unicodeslot=0xFD3D,
+ },
+ [0xFD3E]={
+ adobename="parenleftaltonearabic",
+ category="ps",
+ description="ORNATE LEFT PARENTHESIS",
+ direction="on",
+ linebreak="op",
+ unicodeslot=0xFD3E,
+ },
+ [0xFD3F]={
+ adobename="parenrightaltonearabic",
+ category="pe",
+ description="ORNATE RIGHT PARENTHESIS",
+ direction="on",
+ linebreak="cl",
+ unicodeslot=0xFD3F,
+ },
+ [0xFD50]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A, 0x062C, 0x0645 },
+ unicodeslot=0xFD50,
+ },
+ [0xFD51]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x062D, 0x062C },
+ unicodeslot=0xFD51,
+ },
+ [0xFD52]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A, 0x062D, 0x062C },
+ unicodeslot=0xFD52,
+ },
+ [0xFD53]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A, 0x062D, 0x0645 },
+ unicodeslot=0xFD53,
+ },
+ [0xFD54]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A, 0x062E, 0x0645 },
+ unicodeslot=0xFD54,
+ },
+ [0xFD55]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A, 0x0645, 0x062C },
+ unicodeslot=0xFD55,
+ },
+ [0xFD56]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A, 0x0645, 0x062D },
+ unicodeslot=0xFD56,
+ },
+ [0xFD57]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A, 0x0645, 0x062E },
+ unicodeslot=0xFD57,
+ },
+ [0xFD58]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062C, 0x0645, 0x062D },
+ unicodeslot=0xFD58,
+ },
+ [0xFD59]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062C, 0x0645, 0x062D },
+ unicodeslot=0xFD59,
+ },
+ [0xFD5A]={
+ category="lo",
+ description="ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062D, 0x0645, 0x064A },
+ unicodeslot=0xFD5A,
+ },
+ [0xFD5B]={
+ category="lo",
+ description="ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062D, 0x0645, 0x0649 },
+ unicodeslot=0xFD5B,
+ },
+ [0xFD5C]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0633, 0x062D, 0x062C },
+ unicodeslot=0xFD5C,
+ },
+ [0xFD5D]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0633, 0x062C, 0x062D },
+ unicodeslot=0xFD5D,
+ },
+ [0xFD5E]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0633, 0x062C, 0x0649 },
+ unicodeslot=0xFD5E,
+ },
+ [0xFD5F]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0633, 0x0645, 0x062D },
+ unicodeslot=0xFD5F,
+ },
+ [0xFD60]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0633, 0x0645, 0x062D },
+ unicodeslot=0xFD60,
+ },
+ [0xFD61]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0633, 0x0645, 0x062C },
+ unicodeslot=0xFD61,
+ },
+ [0xFD62]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0633, 0x0645, 0x0645 },
+ unicodeslot=0xFD62,
+ },
+ [0xFD63]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0633, 0x0645, 0x0645 },
+ unicodeslot=0xFD63,
+ },
+ [0xFD64]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0635, 0x062D, 0x062D },
+ unicodeslot=0xFD64,
+ },
+ [0xFD65]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0635, 0x062D, 0x062D },
+ unicodeslot=0xFD65,
+ },
+ [0xFD66]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0635, 0x0645, 0x0645 },
+ unicodeslot=0xFD66,
+ },
+ [0xFD67]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634, 0x062D, 0x0645 },
+ unicodeslot=0xFD67,
+ },
+ [0xFD68]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0634, 0x062D, 0x0645 },
+ unicodeslot=0xFD68,
+ },
+ [0xFD69]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634, 0x062C, 0x064A },
+ unicodeslot=0xFD69,
+ },
+ [0xFD6A]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634, 0x0645, 0x062E },
+ unicodeslot=0xFD6A,
+ },
+ [0xFD6B]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0634, 0x0645, 0x062E },
+ unicodeslot=0xFD6B,
+ },
+ [0xFD6C]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634, 0x0645, 0x0645 },
+ unicodeslot=0xFD6C,
+ },
+ [0xFD6D]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0634, 0x0645, 0x0645 },
+ unicodeslot=0xFD6D,
+ },
+ [0xFD6E]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0636, 0x062D, 0x0649 },
+ unicodeslot=0xFD6E,
+ },
+ [0xFD6F]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0636, 0x062E, 0x0645 },
+ unicodeslot=0xFD6F,
+ },
+ [0xFD70]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0636, 0x062E, 0x0645 },
+ unicodeslot=0xFD70,
+ },
+ [0xFD71]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0637, 0x0645, 0x062D },
+ unicodeslot=0xFD71,
+ },
+ [0xFD72]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0637, 0x0645, 0x062D },
+ unicodeslot=0xFD72,
+ },
+ [0xFD73]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0637, 0x0645, 0x0645 },
+ unicodeslot=0xFD73,
+ },
+ [0xFD74]={
+ category="lo",
+ description="ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0637, 0x0645, 0x064A },
+ unicodeslot=0xFD74,
+ },
+ [0xFD75]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0639, 0x062C, 0x0645 },
+ unicodeslot=0xFD75,
+ },
+ [0xFD76]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0639, 0x0645, 0x0645 },
+ unicodeslot=0xFD76,
+ },
+ [0xFD77]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0639, 0x0645, 0x0645 },
+ unicodeslot=0xFD77,
+ },
+ [0xFD78]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0639, 0x0645, 0x0649 },
+ unicodeslot=0xFD78,
+ },
+ [0xFD79]={
+ category="lo",
+ description="ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x063A, 0x0645, 0x0645 },
+ unicodeslot=0xFD79,
+ },
+ [0xFD7A]={
+ category="lo",
+ description="ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x063A, 0x0645, 0x064A },
+ unicodeslot=0xFD7A,
+ },
+ [0xFD7B]={
+ category="lo",
+ description="ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x063A, 0x0645, 0x0649 },
+ unicodeslot=0xFD7B,
+ },
+ [0xFD7C]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0641, 0x062E, 0x0645 },
+ unicodeslot=0xFD7C,
+ },
+ [0xFD7D]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0641, 0x062E, 0x0645 },
+ unicodeslot=0xFD7D,
+ },
+ [0xFD7E]={
+ category="lo",
+ description="ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0642, 0x0645, 0x062D },
+ unicodeslot=0xFD7E,
+ },
+ [0xFD7F]={
+ category="lo",
+ description="ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0642, 0x0645, 0x0645 },
+ unicodeslot=0xFD7F,
+ },
+ [0xFD80]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x062D, 0x0645 },
+ unicodeslot=0xFD80,
+ },
+ [0xFD81]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x062D, 0x064A },
+ unicodeslot=0xFD81,
+ },
+ [0xFD82]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x062D, 0x0649 },
+ unicodeslot=0xFD82,
+ },
+ [0xFD83]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0644, 0x062C, 0x062C },
+ unicodeslot=0xFD83,
+ },
+ [0xFD84]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x062C, 0x062C },
+ unicodeslot=0xFD84,
+ },
+ [0xFD85]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x062E, 0x0645 },
+ unicodeslot=0xFD85,
+ },
+ [0xFD86]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0644, 0x062E, 0x0645 },
+ unicodeslot=0xFD86,
+ },
+ [0xFD87]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x0645, 0x062D },
+ unicodeslot=0xFD87,
+ },
+ [0xFD88]={
+ adobename="lammeemhahinitialarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0644, 0x0645, 0x062D },
+ unicodeslot=0xFD88,
+ },
+ [0xFD89]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0645, 0x062D, 0x062C },
+ unicodeslot=0xFD89,
+ },
+ [0xFD8A]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0645, 0x062D, 0x0645 },
+ unicodeslot=0xFD8A,
+ },
+ [0xFD8B]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0645, 0x062D, 0x064A },
+ unicodeslot=0xFD8B,
+ },
+ [0xFD8C]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0645, 0x062C, 0x062D },
+ unicodeslot=0xFD8C,
+ },
+ [0xFD8D]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0645, 0x062C, 0x0645 },
+ unicodeslot=0xFD8D,
+ },
+ [0xFD8E]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0645, 0x062E, 0x062C },
+ unicodeslot=0xFD8E,
+ },
+ [0xFD8F]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0645, 0x062E, 0x0645 },
+ unicodeslot=0xFD8F,
+ },
+ [0xFD92]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0645, 0x062C, 0x062E },
+ unicodeslot=0xFD92,
+ },
+ [0xFD93]={
+ category="lo",
+ description="ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0647, 0x0645, 0x062C },
+ unicodeslot=0xFD93,
+ },
+ [0xFD94]={
+ category="lo",
+ description="ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0647, 0x0645, 0x0645 },
+ unicodeslot=0xFD94,
+ },
+ [0xFD95]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0646, 0x062D, 0x0645 },
+ unicodeslot=0xFD95,
+ },
+ [0xFD96]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x062D, 0x0649 },
+ unicodeslot=0xFD96,
+ },
+ [0xFD97]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x062C, 0x0645 },
+ unicodeslot=0xFD97,
+ },
+ [0xFD98]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0646, 0x062C, 0x0645 },
+ unicodeslot=0xFD98,
+ },
+ [0xFD99]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x062C, 0x0649 },
+ unicodeslot=0xFD99,
+ },
+ [0xFD9A]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x0645, 0x064A },
+ unicodeslot=0xFD9A,
+ },
+ [0xFD9B]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x0645, 0x0649 },
+ unicodeslot=0xFD9B,
+ },
+ [0xFD9C]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x064A, 0x0645, 0x0645 },
+ unicodeslot=0xFD9C,
+ },
+ [0xFD9D]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x064A, 0x0645, 0x0645 },
+ unicodeslot=0xFD9D,
+ },
+ [0xFD9E]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0628, 0x062E, 0x064A },
+ unicodeslot=0xFD9E,
+ },
+ [0xFD9F]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x062C, 0x064A },
+ unicodeslot=0xFD9F,
+ },
+ [0xFDA0]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x062C, 0x0649 },
+ unicodeslot=0xFDA0,
+ },
+ [0xFDA1]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x062E, 0x064A },
+ unicodeslot=0xFDA1,
+ },
+ [0xFDA2]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x062E, 0x0649 },
+ unicodeslot=0xFDA2,
+ },
+ [0xFDA3]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x0645, 0x064A },
+ unicodeslot=0xFDA3,
+ },
+ [0xFDA4]={
+ category="lo",
+ description="ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A, 0x0645, 0x0649 },
+ unicodeslot=0xFDA4,
+ },
+ [0xFDA5]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062C, 0x0645, 0x064A },
+ unicodeslot=0xFDA5,
+ },
+ [0xFDA6]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062C, 0x062D, 0x0649 },
+ unicodeslot=0xFDA6,
+ },
+ [0xFDA7]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062C, 0x0645, 0x0649 },
+ unicodeslot=0xFDA7,
+ },
+ [0xFDA8]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0633, 0x062E, 0x0649 },
+ unicodeslot=0xFDA8,
+ },
+ [0xFDA9]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0635, 0x062D, 0x064A },
+ unicodeslot=0xFDA9,
+ },
+ [0xFDAA]={
+ category="lo",
+ description="ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634, 0x062D, 0x064A },
+ unicodeslot=0xFDAA,
+ },
+ [0xFDAB]={
+ category="lo",
+ description="ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0636, 0x062D, 0x064A },
+ unicodeslot=0xFDAB,
+ },
+ [0xFDAC]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x062C, 0x064A },
+ unicodeslot=0xFDAC,
+ },
+ [0xFDAD]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x0645, 0x064A },
+ unicodeslot=0xFDAD,
+ },
+ [0xFDAE]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x064A, 0x062D, 0x064A },
+ unicodeslot=0xFDAE,
+ },
+ [0xFDAF]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x064A, 0x062C, 0x064A },
+ unicodeslot=0xFDAF,
+ },
+ [0xFDB0]={
+ category="lo",
+ description="ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x064A, 0x0645, 0x064A },
+ unicodeslot=0xFDB0,
+ },
+ [0xFDB1]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0645, 0x0645, 0x064A },
+ unicodeslot=0xFDB1,
+ },
+ [0xFDB2]={
+ category="lo",
+ description="ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0642, 0x0645, 0x064A },
+ unicodeslot=0xFDB2,
+ },
+ [0xFDB3]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x062D, 0x064A },
+ unicodeslot=0xFDB3,
+ },
+ [0xFDB4]={
+ category="lo",
+ description="ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0642, 0x0645, 0x062D },
+ unicodeslot=0xFDB4,
+ },
+ [0xFDB5]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0644, 0x062D, 0x0645 },
+ unicodeslot=0xFDB5,
+ },
+ [0xFDB6]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0639, 0x0645, 0x064A },
+ unicodeslot=0xFDB6,
+ },
+ [0xFDB7]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0643, 0x0645, 0x064A },
+ unicodeslot=0xFDB7,
+ },
+ [0xFDB8]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0646, 0x062C, 0x062D },
+ unicodeslot=0xFDB8,
+ },
+ [0xFDB9]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0645, 0x062E, 0x064A },
+ unicodeslot=0xFDB9,
+ },
+ [0xFDBA]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0644, 0x062C, 0x0645 },
+ unicodeslot=0xFDBA,
+ },
+ [0xFDBB]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0643, 0x0645, 0x0645 },
+ unicodeslot=0xFDBB,
+ },
+ [0xFDBC]={
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x062C, 0x0645 },
+ unicodeslot=0xFDBC,
+ },
+ [0xFDBD]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x062C, 0x062D },
+ unicodeslot=0xFDBD,
+ },
+ [0xFDBE]={
+ category="lo",
+ description="ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062C, 0x062D, 0x064A },
+ unicodeslot=0xFDBE,
+ },
+ [0xFDBF]={
+ category="lo",
+ description="ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062D, 0x062C, 0x064A },
+ unicodeslot=0xFDBF,
+ },
+ [0xFDC0]={
+ category="lo",
+ description="ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0645, 0x062C, 0x064A },
+ unicodeslot=0xFDC0,
+ },
+ [0xFDC1]={
+ category="lo",
+ description="ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0641, 0x0645, 0x064A },
+ unicodeslot=0xFDC1,
+ },
+ [0xFDC2]={
+ category="lo",
+ description="ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0628, 0x062D, 0x064A },
+ unicodeslot=0xFDC2,
+ },
+ [0xFDC3]={
+ category="lo",
+ description="ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0643, 0x0645, 0x0645 },
+ unicodeslot=0xFDC3,
+ },
+ [0xFDC4]={
+ category="lo",
+ description="ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0639, 0x062C, 0x0645 },
+ unicodeslot=0xFDC4,
+ },
+ [0xFDC5]={
+ category="lo",
+ description="ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0635, 0x0645, 0x0645 },
+ unicodeslot=0xFDC5,
+ },
+ [0xFDC6]={
+ category="lo",
+ description="ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0633, 0x062E, 0x064A },
+ unicodeslot=0xFDC6,
+ },
+ [0xFDC7]={
+ category="lo",
+ description="ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646, 0x062C, 0x064A },
+ unicodeslot=0xFDC7,
+ },
+ [0xFDF0]={
+ category="lo",
+ description="ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0635, 0x0644, 0x06D2 },
+ unicodeslot=0xFDF0,
+ },
+ [0xFDF1]={
+ category="lo",
+ description="ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0642, 0x0644, 0x06D2 },
+ unicodeslot=0xFDF1,
+ },
+ [0xFDF2]={
+ adobename="lamlamhehisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE ALLAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0627, 0x0644, 0x0644, 0x0647 },
+ unicodeslot=0xFDF2,
+ },
+ [0xFDF3]={
+ category="lo",
+ description="ARABIC LIGATURE AKBAR ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0627, 0x0643, 0x0628, 0x0631 },
+ unicodeslot=0xFDF3,
+ },
+ [0xFDF4]={
+ category="lo",
+ description="ARABIC LIGATURE MOHAMMAD ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0645, 0x062D, 0x0645, 0x062F },
+ unicodeslot=0xFDF4,
+ },
+ [0xFDF5]={
+ category="lo",
+ description="ARABIC LIGATURE SALAM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0635, 0x0644, 0x0639, 0x0645 },
+ unicodeslot=0xFDF5,
+ },
+ [0xFDF6]={
+ category="lo",
+ description="ARABIC LIGATURE RASOUL ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0631, 0x0633, 0x0648, 0x0644 },
+ unicodeslot=0xFDF6,
+ },
+ [0xFDF7]={
+ category="lo",
+ description="ARABIC LIGATURE ALAYHE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0639, 0x0644, 0x064A, 0x0647 },
+ unicodeslot=0xFDF7,
+ },
+ [0xFDF8]={
+ category="lo",
+ description="ARABIC LIGATURE WASALLAM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0648, 0x0633, 0x0644, 0x0645 },
+ unicodeslot=0xFDF8,
+ },
+ [0xFDF9]={
+ category="lo",
+ description="ARABIC LIGATURE SALLA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0635, 0x0644, 0x0649 },
+ unicodeslot=0xFDF9,
+ },
+ [0xFDFA]={
+ adobename="sallallahoualayhewasallamarabic",
+ category="lo",
+ description="ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0635, 0x0644, 0x0649, 0x0020, 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, 0x0639, 0x0644, 0x064A, 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, 0x0645 },
+ unicodeslot=0xFDFA,
+ },
+ [0xFDFB]={
+ category="lo",
+ description="ARABIC LIGATURE JALLAJALALOUHOU",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062C, 0x0644, 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, 0x0647 },
+ unicodeslot=0xFDFB,
+ },
+ [0xFDFC]={
+ category="sc",
+ description="RIAL SIGN",
+ direction="al",
+ linebreak="po",
+ specials={ "isolated", 0x0631, 0x06CC, 0x0627, 0x0644 },
+ unicodeslot=0xFDFC,
+ },
+ [0xFDFD]={
+ category="so",
+ description="ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xFDFD,
+ },
+ [0xFE00]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0001",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE00,
+ },
+ [0xFE01]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0002",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE01,
+ },
+ [0xFE02]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0003",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE02,
+ },
+ [0xFE03]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0004",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE03,
+ },
+ [0xFE04]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0005",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE04,
+ },
+ [0xFE05]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0006",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE05,
+ },
+ [0xFE06]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0007",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE06,
+ },
+ [0xFE07]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0008",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE07,
+ },
+ [0xFE08]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0009",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE08,
+ },
+ [0xFE09]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x000A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE09,
+ },
+ [0xFE0A]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x000B",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE0A,
+ },
+ [0xFE0B]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x000C",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE0B,
+ },
+ [0xFE0C]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x000D",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE0C,
+ },
+ [0xFE0D]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x000E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE0D,
+ },
+ [0xFE0E]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x000F",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE0E,
+ },
+ [0xFE0F]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0010",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE0F,
+ },
+ [0xFE10]={
+ category="po",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL COMMA",
+ direction="on",
+ linebreak="is",
+ specials={ "vertical", 0x002C },
+ unicodeslot=0xFE10,
+ },
+ [0xFE11]={
+ category="po",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x3001 },
+ unicodeslot=0xFE11,
+ },
+ [0xFE12]={
+ category="po",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x3002 },
+ unicodeslot=0xFE12,
+ },
+ [0xFE13]={
+ category="po",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL COLON",
+ direction="on",
+ linebreak="is",
+ specials={ "vertical", 0x003A },
+ unicodeslot=0xFE13,
+ },
+ [0xFE14]={
+ category="po",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL SEMICOLON",
+ direction="on",
+ linebreak="is",
+ specials={ "vertical", 0x003B },
+ unicodeslot=0xFE14,
+ },
+ [0xFE15]={
+ category="po",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK",
+ direction="on",
+ linebreak="ex",
+ specials={ "vertical", 0x0021 },
+ unicodeslot=0xFE15,
+ },
+ [0xFE16]={
+ category="po",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL QUESTION MARK",
+ direction="on",
+ linebreak="ex",
+ specials={ "vertical", 0x003F },
+ unicodeslot=0xFE16,
+ },
+ [0xFE17]={
+ category="ps",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x3016 },
+ unicodeslot=0xFE17,
+ },
+ [0xFE18]={
+ category="pe",
+ cjkwd="w",
+ comment="corrected description: brakcet",
+ description="PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRACKET",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x3017 },
+ unicodeslot=0xFE18,
+ },
+ [0xFE19]={
+ category="po",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS",
+ direction="on",
+ linebreak="in",
+ specials={ "vertical", 0x2026 },
+ unicodeslot=0xFE19,
+ },
+ [0xFE20]={
+ category="mn",
+ description="COMBINING LIGATURE LEFT HALF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE20,
+ },
+ [0xFE21]={
+ category="mn",
+ description="COMBINING LIGATURE RIGHT HALF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE21,
+ },
+ [0xFE22]={
+ category="mn",
+ description="COMBINING DOUBLE TILDE LEFT HALF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE22,
+ },
+ [0xFE23]={
+ category="mn",
+ description="COMBINING DOUBLE TILDE RIGHT HALF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE23,
+ },
+ [0xFE24]={
+ category="mn",
+ description="COMBINING MACRON LEFT HALF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE24,
+ },
+ [0xFE25]={
+ category="mn",
+ description="COMBINING MACRON RIGHT HALF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE25,
+ },
+ [0xFE26]={
+ category="mn",
+ description="COMBINING CONJOINING MACRON",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xFE26,
+ },
+ [0xFE30]={
+ adobename="twodotleadervertical",
+ category="po",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL TWO DOT LEADER",
+ direction="on",
+ linebreak="id",
+ specials={ "vertical", 0x2025 },
+ unicodeslot=0xFE30,
+ },
+ [0xFE31]={
+ adobename="emdashvertical",
+ category="pd",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL EM DASH",
+ direction="on",
+ linebreak="id",
+ specials={ "vertical", 0x2014 },
+ unicodeslot=0xFE31,
+ },
+ [0xFE32]={
+ adobename="endashvertical",
+ category="pd",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL EN DASH",
+ direction="on",
+ linebreak="id",
+ specials={ "vertical", 0x2013 },
+ unicodeslot=0xFE32,
+ },
+ [0xFE33]={
+ adobename="underscorevertical",
+ category="pc",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL LOW LINE",
+ direction="on",
+ linebreak="id",
+ specials={ "vertical", 0x005F },
+ unicodeslot=0xFE33,
+ },
+ [0xFE34]={
+ adobename="wavyunderscorevertical",
+ category="pc",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL WAVY LOW LINE",
+ direction="on",
+ linebreak="id",
+ specials={ "vertical", 0x005F },
+ unicodeslot=0xFE34,
+ },
+ [0xFE35]={
+ adobename="parenleftvertical",
+ category="ps",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x0028 },
+ unicodeslot=0xFE35,
+ },
+ [0xFE36]={
+ adobename="parenrightvertical",
+ category="pe",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x0029 },
+ unicodeslot=0xFE36,
+ },
+ [0xFE37]={
+ adobename="braceleftvertical",
+ category="ps",
+ cjkwd="w",
+ comment="weird math needed for mathml",
+ description="PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET",
+ direction="on",
+ linebreak="op",
+ mathfiller="downbracefill",
+ specials={ "vertical", 0x007B },
+ unicodeslot=0xFE37,
+ },
+ [0xFE38]={
+ adobename="bracerightvertical",
+ category="pe",
+ cjkwd="w",
+ comment="weird math needed for mathml",
+ description="PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET",
+ direction="on",
+ linebreak="cl",
+ mathfiller="upbracefill",
+ specials={ "vertical", 0x007D },
+ unicodeslot=0xFE38,
+ },
+ [0xFE39]={
+ adobename="tortoiseshellbracketleftvertical",
+ category="ps",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x3014 },
+ unicodeslot=0xFE39,
+ },
+ [0xFE3A]={
+ adobename="tortoiseshellbracketrightvertical",
+ category="pe",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x3015 },
+ unicodeslot=0xFE3A,
+ },
+ [0xFE3B]={
+ adobename="blacklenticularbracketleftvertical",
+ category="ps",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x3010 },
+ unicodeslot=0xFE3B,
+ },
+ [0xFE3C]={
+ adobename="blacklenticularbracketrightvertical",
+ category="pe",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x3011 },
+ unicodeslot=0xFE3C,
+ },
+ [0xFE3D]={
+ adobename="dblanglebracketleftvertical",
+ category="ps",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x300A },
+ unicodeslot=0xFE3D,
+ },
+ [0xFE3E]={
+ adobename="dblanglebracketrightvertical",
+ category="pe",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x300B },
+ unicodeslot=0xFE3E,
+ },
+ [0xFE3F]={
+ adobename="anglebracketleftvertical",
+ category="ps",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x3008 },
+ unicodeslot=0xFE3F,
+ },
+ [0xFE40]={
+ adobename="anglebracketrightvertical",
+ category="pe",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x3009 },
+ unicodeslot=0xFE40,
+ },
+ [0xFE41]={
+ adobename="cornerbracketleftvertical",
+ category="ps",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x300C },
+ unicodeslot=0xFE41,
+ },
+ [0xFE42]={
+ adobename="cornerbracketrightvertical",
+ category="pe",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x300D },
+ unicodeslot=0xFE42,
+ },
+ [0xFE43]={
+ adobename="whitecornerbracketleftvertical",
+ category="ps",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x300E },
+ unicodeslot=0xFE43,
+ },
+ [0xFE44]={
+ adobename="whitecornerbracketrightvertical",
+ category="pe",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x300F },
+ unicodeslot=0xFE44,
+ },
+ [0xFE45]={
+ category="po",
+ cjkwd="w",
+ description="SESAME DOT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xFE45,
+ },
+ [0xFE46]={
+ category="po",
+ cjkwd="w",
+ description="WHITE SESAME DOT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0xFE46,
+ },
+ [0xFE47]={
+ category="ps",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET",
+ direction="on",
+ linebreak="op",
+ specials={ "vertical", 0x005B },
+ unicodeslot=0xFE47,
+ },
+ [0xFE48]={
+ category="pe",
+ cjkwd="w",
+ description="PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET",
+ direction="on",
+ linebreak="cl",
+ specials={ "vertical", 0x005D },
+ unicodeslot=0xFE48,
+ },
+ [0xFE49]={
+ adobename="overlinedashed",
+ category="po",
+ cjkwd="w",
+ description="DASHED OVERLINE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x203E },
+ unicodeslot=0xFE49,
+ },
+ [0xFE4A]={
+ adobename="overlinecenterline",
+ category="po",
+ cjkwd="w",
+ description="CENTRELINE OVERLINE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x203E },
+ unicodeslot=0xFE4A,
+ },
+ [0xFE4B]={
+ adobename="overlinewavy",
+ category="po",
+ cjkwd="w",
+ description="WAVY OVERLINE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x203E },
+ unicodeslot=0xFE4B,
+ },
+ [0xFE4C]={
+ adobename="overlinedblwavy",
+ category="po",
+ cjkwd="w",
+ description="DOUBLE WAVY OVERLINE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x203E },
+ unicodeslot=0xFE4C,
+ },
+ [0xFE4D]={
+ adobename="lowlinedashed",
+ category="pc",
+ cjkwd="w",
+ description="DASHED LOW LINE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x005F },
+ unicodeslot=0xFE4D,
+ },
+ [0xFE4E]={
+ adobename="lowlinecenterline",
+ category="pc",
+ cjkwd="w",
+ description="CENTRELINE LOW LINE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x005F },
+ unicodeslot=0xFE4E,
+ },
+ [0xFE4F]={
+ adobename="underscorewavy",
+ category="pc",
+ cjkwd="w",
+ description="WAVY LOW LINE",
+ direction="on",
+ linebreak="id",
+ specials={ "compat", 0x005F },
+ unicodeslot=0xFE4F,
+ },
+ [0xFE50]={
+ adobename="commasmall",
+ category="po",
+ cjkwd="w",
+ description="SMALL COMMA",
+ direction="cs",
+ linebreak="cl",
+ specials={ "small", 0x002C },
+ unicodeslot=0xFE50,
+ },
+ [0xFE51]={
+ category="po",
+ cjkwd="w",
+ description="SMALL IDEOGRAPHIC COMMA",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x3001 },
+ unicodeslot=0xFE51,
+ },
+ [0xFE52]={
+ adobename="periodsmall",
+ category="po",
+ cjkwd="w",
+ description="SMALL FULL STOP",
+ direction="cs",
+ linebreak="cl",
+ specials={ "small", 0x002E },
+ unicodeslot=0xFE52,
+ },
+ [0xFE54]={
+ adobename="semicolonsmall",
+ category="po",
+ cjkwd="w",
+ description="SMALL SEMICOLON",
+ direction="on",
+ linebreak="ns",
+ specials={ "small", 0x003B },
+ unicodeslot=0xFE54,
+ },
+ [0xFE55]={
+ adobename="colonsmall",
+ category="po",
+ cjkwd="w",
+ description="SMALL COLON",
+ direction="cs",
+ linebreak="ns",
+ specials={ "small", 0x003A },
+ unicodeslot=0xFE55,
+ },
+ [0xFE56]={
+ category="po",
+ cjkwd="w",
+ description="SMALL QUESTION MARK",
+ direction="on",
+ linebreak="ex",
+ specials={ "small", 0x003F },
+ unicodeslot=0xFE56,
+ },
+ [0xFE57]={
+ category="po",
+ cjkwd="w",
+ description="SMALL EXCLAMATION MARK",
+ direction="on",
+ linebreak="ex",
+ specials={ "small", 0x0021 },
+ unicodeslot=0xFE57,
+ },
+ [0xFE58]={
+ category="pd",
+ cjkwd="w",
+ description="SMALL EM DASH",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x2014 },
+ unicodeslot=0xFE58,
+ },
+ [0xFE59]={
+ adobename="parenleftsmall",
+ category="ps",
+ cjkwd="w",
+ description="SMALL LEFT PARENTHESIS",
+ direction="on",
+ linebreak="op",
+ mirror=0xFE5A,
+ textclass="open",
+ specials={ "small", 0x0028 },
+ unicodeslot=0xFE59,
+ },
+ [0xFE5A]={
+ adobename="parenrightsmall",
+ category="pe",
+ cjkwd="w",
+ description="SMALL RIGHT PARENTHESIS",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFE59,
+ textclass="close",
+ specials={ "small", 0x0029 },
+ unicodeslot=0xFE5A,
+ },
+ [0xFE5B]={
+ adobename="braceleftsmall",
+ category="ps",
+ cjkwd="w",
+ description="SMALL LEFT CURLY BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0xFE5C,
+ textclass="open",
+ specials={ "small", 0x007B },
+ unicodeslot=0xFE5B,
+ },
+ [0xFE5C]={
+ adobename="bracerightsmall",
+ category="pe",
+ cjkwd="w",
+ description="SMALL RIGHT CURLY BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFE5B,
+ textclass="close",
+ specials={ "small", 0x007D },
+ unicodeslot=0xFE5C,
+ },
+ [0xFE5D]={
+ adobename="tortoiseshellbracketleftsmall",
+ category="ps",
+ cjkwd="w",
+ description="SMALL LEFT TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0xFE5E,
+ textclass="open",
+ specials={ "small", 0x3014 },
+ unicodeslot=0xFE5D,
+ },
+ [0xFE5E]={
+ adobename="tortoiseshellbracketrightsmall",
+ category="pe",
+ cjkwd="w",
+ description="SMALL RIGHT TORTOISE SHELL BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFE5D,
+ textclass="close",
+ specials={ "small", 0x3015 },
+ unicodeslot=0xFE5E,
+ },
+ [0xFE5F]={
+ adobename="numbersignsmall",
+ category="po",
+ cjkwd="w",
+ description="SMALL NUMBER SIGN",
+ direction="et",
+ linebreak="id",
+ specials={ "small", 0x0023 },
+ unicodeslot=0xFE5F,
+ },
+ [0xFE60]={
+ category="po",
+ cjkwd="w",
+ description="SMALL AMPERSAND",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x0026 },
+ unicodeslot=0xFE60,
+ },
+ [0xFE61]={
+ adobename="asterisksmall",
+ category="po",
+ cjkwd="w",
+ description="SMALL ASTERISK",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x002A },
+ unicodeslot=0xFE61,
+ },
+ [0xFE62]={
+ adobename="plussmall",
+ category="sm",
+ cjkwd="w",
+ description="SMALL PLUS SIGN",
+ direction="es",
+ linebreak="id",
+ specials={ "small", 0x002B },
+ unicodeslot=0xFE62,
+ },
+ [0xFE63]={
+ adobename="hyphensmall",
+ category="pd",
+ cjkwd="w",
+ description="SMALL HYPHEN-MINUS",
+ direction="es",
+ linebreak="id",
+ specials={ "small", 0x002D },
+ unicodeslot=0xFE63,
+ },
+ [0xFE64]={
+ adobename="lesssmall",
+ category="sm",
+ cjkwd="w",
+ description="SMALL LESS-THAN SIGN",
+ direction="on",
+ linebreak="id",
+ mirror=0xFE65,
+ textclass="open",
+ specials={ "small", 0x003C },
+ unicodeslot=0xFE64,
+ },
+ [0xFE65]={
+ adobename="greatersmall",
+ category="sm",
+ cjkwd="w",
+ description="SMALL GREATER-THAN SIGN",
+ direction="on",
+ linebreak="id",
+ mirror=0xFE64,
+ textclass="close",
+ specials={ "small", 0x003E },
+ unicodeslot=0xFE65,
+ },
+ [0xFE66]={
+ adobename="equalsmall",
+ category="sm",
+ cjkwd="w",
+ description="SMALL EQUALS SIGN",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x003D },
+ unicodeslot=0xFE66,
+ },
+ [0xFE68]={
+ category="po",
+ cjkwd="w",
+ description="SMALL REVERSE SOLIDUS",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x005C },
+ unicodeslot=0xFE68,
+ },
+ [0xFE69]={
+ adobename="dollarsmall",
+ category="sc",
+ cjkwd="w",
+ description="SMALL DOLLAR SIGN",
+ direction="et",
+ linebreak="pr",
+ specials={ "small", 0x0024 },
+ unicodeslot=0xFE69,
+ },
+ [0xFE6A]={
+ adobename="percentsmall",
+ category="po",
+ cjkwd="w",
+ description="SMALL PERCENT SIGN",
+ direction="et",
+ linebreak="po",
+ specials={ "small", 0x0025 },
+ unicodeslot=0xFE6A,
+ },
+ [0xFE6B]={
+ adobename="atsmall",
+ category="po",
+ cjkwd="w",
+ description="SMALL COMMERCIAL AT",
+ direction="on",
+ linebreak="id",
+ specials={ "small", 0x0040 },
+ unicodeslot=0xFE6B,
+ },
+ [0xFE70]={
+ category="lo",
+ description="ARABIC FATHATAN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x064B },
+ unicodeslot=0xFE70,
+ },
+ [0xFE71]={
+ category="lo",
+ description="ARABIC TATWEEL WITH FATHATAN ABOVE",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0640, 0x064B },
+ unicodeslot=0xFE71,
+ },
+ [0xFE72]={
+ category="lo",
+ description="ARABIC DAMMATAN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x064C },
+ unicodeslot=0xFE72,
+ },
+ [0xFE73]={
+ category="lo",
+ description="ARABIC TAIL FRAGMENT",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0xFE73,
+ },
+ [0xFE74]={
+ category="lo",
+ description="ARABIC KASRATAN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x064D },
+ unicodeslot=0xFE74,
+ },
+ [0xFE76]={
+ category="lo",
+ description="ARABIC FATHA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x064E },
+ unicodeslot=0xFE76,
+ },
+ [0xFE77]={
+ category="lo",
+ description="ARABIC FATHA MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0640, 0x064E },
+ unicodeslot=0xFE77,
+ },
+ [0xFE78]={
+ category="lo",
+ description="ARABIC DAMMA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x064F },
+ unicodeslot=0xFE78,
+ },
+ [0xFE79]={
+ category="lo",
+ description="ARABIC DAMMA MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0640, 0x064F },
+ unicodeslot=0xFE79,
+ },
+ [0xFE7A]={
+ category="lo",
+ description="ARABIC KASRA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x0650 },
+ unicodeslot=0xFE7A,
+ },
+ [0xFE7B]={
+ category="lo",
+ description="ARABIC KASRA MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0640, 0x0650 },
+ unicodeslot=0xFE7B,
+ },
+ [0xFE7C]={
+ category="lo",
+ description="ARABIC SHADDA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x0651 },
+ unicodeslot=0xFE7C,
+ },
+ [0xFE7D]={
+ category="lo",
+ description="ARABIC SHADDA MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0640, 0x0651 },
+ unicodeslot=0xFE7D,
+ },
+ [0xFE7E]={
+ category="lo",
+ description="ARABIC SUKUN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0020, 0x0652 },
+ unicodeslot=0xFE7E,
+ },
+ [0xFE7F]={
+ category="lo",
+ description="ARABIC SUKUN MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0640, 0x0652 },
+ unicodeslot=0xFE7F,
+ },
+ [0xFE80]={
+ category="lo",
+ description="ARABIC LETTER HAMZA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0621 },
+ unicodeslot=0xFE80,
+ },
+ [0xFE81]={
+ category="lo",
+ description="ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x0627,
+ specials={ "isolated", 0x0622 },
+ unicodeslot=0xFE81,
+ },
+ [0xFE82]={
+ adobename="alefmaddaabovefinalarabic",
+ category="lo",
+ description="ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x0627,
+ specials={ "final", 0x0622 },
+ unicodeslot=0xFE82,
+ },
+ [0xFE83]={
+ category="lo",
+ description="ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x0627,
+ specials={ "isolated", 0x0623 },
+ unicodeslot=0xFE83,
+ },
+ [0xFE84]={
+ adobename="alefhamzaabovefinalarabic",
+ category="lo",
+ description="ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x0627,
+ specials={ "final", 0x0623 },
+ unicodeslot=0xFE84,
+ },
+ [0xFE85]={
+ category="lo",
+ description="ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x0648,
+ specials={ "isolated", 0x0624 },
+ unicodeslot=0xFE85,
+ },
+ [0xFE86]={
+ adobename="wawhamzaabovefinalarabic",
+ category="lo",
+ description="ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x0648,
+ specials={ "final", 0x0624 },
+ unicodeslot=0xFE86,
+ },
+ [0xFE87]={
+ category="lo",
+ description="ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x0627,
+ specials={ "isolated", 0x0625 },
+ unicodeslot=0xFE87,
+ },
+ [0xFE88]={
+ adobename="alefhamzabelowfinalarabic",
+ category="lo",
+ description="ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x0627,
+ specials={ "final", 0x0625 },
+ unicodeslot=0xFE88,
+ },
+ [0xFE89]={
+ category="lo",
+ description="ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x064A,
+ specials={ "isolated", 0x0626 },
+ unicodeslot=0xFE89,
+ },
+ [0xFE8A]={
+ adobename="yehhamzaabovefinalarabic",
+ category="lo",
+ description="ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x064A,
+ specials={ "final", 0x0626 },
+ unicodeslot=0xFE8A,
+ },
+ [0xFE8B]={
+ adobename="yehhamzaaboveinitialarabic",
+ category="lo",
+ description="ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x064A,
+ specials={ "initial", 0x0626 },
+ unicodeslot=0xFE8B,
+ },
+ [0xFE8C]={
+ adobename="yehhamzaabovemedialarabic",
+ category="lo",
+ description="ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ shcode=0x064A,
+ specials={ "medial", 0x0626 },
+ unicodeslot=0xFE8C,
+ },
+ [0xFE8D]={
+ category="lo",
+ description="ARABIC LETTER ALEF ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0627 },
+ unicodeslot=0xFE8D,
+ },
+ [0xFE8E]={
+ adobename="aleffinalarabic",
+ category="lo",
+ description="ARABIC LETTER ALEF FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0627 },
+ unicodeslot=0xFE8E,
+ },
+ [0xFE8F]={
+ category="lo",
+ description="ARABIC LETTER BEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0628 },
+ unicodeslot=0xFE8F,
+ },
+ [0xFE90]={
+ adobename="behfinalarabic",
+ category="lo",
+ description="ARABIC LETTER BEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0628 },
+ unicodeslot=0xFE90,
+ },
+ [0xFE91]={
+ adobename="behinitialarabic",
+ category="lo",
+ description="ARABIC LETTER BEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0628 },
+ unicodeslot=0xFE91,
+ },
+ [0xFE92]={
+ adobename="behmedialarabic",
+ category="lo",
+ description="ARABIC LETTER BEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0628 },
+ unicodeslot=0xFE92,
+ },
+ [0xFE93]={
+ category="lo",
+ description="ARABIC LETTER TEH MARBUTA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0629 },
+ unicodeslot=0xFE93,
+ },
+ [0xFE94]={
+ adobename="tehmarbutafinalarabic",
+ category="lo",
+ description="ARABIC LETTER TEH MARBUTA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0629 },
+ unicodeslot=0xFE94,
+ },
+ [0xFE95]={
+ category="lo",
+ description="ARABIC LETTER TEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062A },
+ unicodeslot=0xFE95,
+ },
+ [0xFE96]={
+ adobename="tehfinalarabic",
+ category="lo",
+ description="ARABIC LETTER TEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062A },
+ unicodeslot=0xFE96,
+ },
+ [0xFE97]={
+ adobename="tehinitialarabic",
+ category="lo",
+ description="ARABIC LETTER TEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062A },
+ unicodeslot=0xFE97,
+ },
+ [0xFE98]={
+ adobename="tehmedialarabic",
+ category="lo",
+ description="ARABIC LETTER TEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x062A },
+ unicodeslot=0xFE98,
+ },
+ [0xFE99]={
+ category="lo",
+ description="ARABIC LETTER THEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062B },
+ unicodeslot=0xFE99,
+ },
+ [0xFE9A]={
+ adobename="thehfinalarabic",
+ category="lo",
+ description="ARABIC LETTER THEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062B },
+ unicodeslot=0xFE9A,
+ },
+ [0xFE9B]={
+ adobename="thehinitialarabic",
+ category="lo",
+ description="ARABIC LETTER THEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062B },
+ unicodeslot=0xFE9B,
+ },
+ [0xFE9C]={
+ adobename="thehmedialarabic",
+ category="lo",
+ description="ARABIC LETTER THEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x062B },
+ unicodeslot=0xFE9C,
+ },
+ [0xFE9D]={
+ category="lo",
+ description="ARABIC LETTER JEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062C },
+ unicodeslot=0xFE9D,
+ },
+ [0xFE9E]={
+ adobename="jeemfinalarabic",
+ category="lo",
+ description="ARABIC LETTER JEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062C },
+ unicodeslot=0xFE9E,
+ },
+ [0xFE9F]={
+ adobename="jeeminitialarabic",
+ category="lo",
+ description="ARABIC LETTER JEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062C },
+ unicodeslot=0xFE9F,
+ },
+ [0xFEA0]={
+ adobename="jeemmedialarabic",
+ category="lo",
+ description="ARABIC LETTER JEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x062C },
+ unicodeslot=0xFEA0,
+ },
+ [0xFEA1]={
+ category="lo",
+ description="ARABIC LETTER HAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062D },
+ unicodeslot=0xFEA1,
+ },
+ [0xFEA2]={
+ adobename="hahfinalarabic",
+ category="lo",
+ description="ARABIC LETTER HAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062D },
+ unicodeslot=0xFEA2,
+ },
+ [0xFEA3]={
+ adobename="hahinitialarabic",
+ category="lo",
+ description="ARABIC LETTER HAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062D },
+ unicodeslot=0xFEA3,
+ },
+ [0xFEA4]={
+ adobename="hahmedialarabic",
+ category="lo",
+ description="ARABIC LETTER HAH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x062D },
+ unicodeslot=0xFEA4,
+ },
+ [0xFEA5]={
+ category="lo",
+ description="ARABIC LETTER KHAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062E },
+ unicodeslot=0xFEA5,
+ },
+ [0xFEA6]={
+ adobename="khahfinalarabic",
+ category="lo",
+ description="ARABIC LETTER KHAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062E },
+ unicodeslot=0xFEA6,
+ },
+ [0xFEA7]={
+ adobename="khahinitialarabic",
+ category="lo",
+ description="ARABIC LETTER KHAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x062E },
+ unicodeslot=0xFEA7,
+ },
+ [0xFEA8]={
+ adobename="khahmedialarabic",
+ category="lo",
+ description="ARABIC LETTER KHAH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x062E },
+ unicodeslot=0xFEA8,
+ },
+ [0xFEA9]={
+ category="lo",
+ description="ARABIC LETTER DAL ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x062F },
+ unicodeslot=0xFEA9,
+ },
+ [0xFEAA]={
+ adobename="dalfinalarabic",
+ category="lo",
+ description="ARABIC LETTER DAL FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x062F },
+ unicodeslot=0xFEAA,
+ },
+ [0xFEAB]={
+ category="lo",
+ description="ARABIC LETTER THAL ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0630 },
+ unicodeslot=0xFEAB,
+ },
+ [0xFEAC]={
+ adobename="thalfinalarabic",
+ category="lo",
+ description="ARABIC LETTER THAL FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0630 },
+ unicodeslot=0xFEAC,
+ },
+ [0xFEAD]={
+ category="lo",
+ description="ARABIC LETTER REH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0631 },
+ unicodeslot=0xFEAD,
+ },
+ [0xFEAE]={
+ adobename="rehfinalarabic",
+ category="lo",
+ description="ARABIC LETTER REH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0631 },
+ unicodeslot=0xFEAE,
+ },
+ [0xFEAF]={
+ category="lo",
+ description="ARABIC LETTER ZAIN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0632 },
+ unicodeslot=0xFEAF,
+ },
+ [0xFEB0]={
+ adobename="zainfinalarabic",
+ category="lo",
+ description="ARABIC LETTER ZAIN FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0632 },
+ unicodeslot=0xFEB0,
+ },
+ [0xFEB1]={
+ category="lo",
+ description="ARABIC LETTER SEEN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0633 },
+ unicodeslot=0xFEB1,
+ },
+ [0xFEB2]={
+ adobename="seenfinalarabic",
+ category="lo",
+ description="ARABIC LETTER SEEN FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0633 },
+ unicodeslot=0xFEB2,
+ },
+ [0xFEB3]={
+ adobename="seeninitialarabic",
+ category="lo",
+ description="ARABIC LETTER SEEN INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0633 },
+ unicodeslot=0xFEB3,
+ },
+ [0xFEB4]={
+ adobename="seenmedialarabic",
+ category="lo",
+ description="ARABIC LETTER SEEN MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0633 },
+ unicodeslot=0xFEB4,
+ },
+ [0xFEB5]={
+ category="lo",
+ description="ARABIC LETTER SHEEN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0634 },
+ unicodeslot=0xFEB5,
+ },
+ [0xFEB6]={
+ adobename="sheenfinalarabic",
+ category="lo",
+ description="ARABIC LETTER SHEEN FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0634 },
+ unicodeslot=0xFEB6,
+ },
+ [0xFEB7]={
+ adobename="sheeninitialarabic",
+ category="lo",
+ description="ARABIC LETTER SHEEN INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0634 },
+ unicodeslot=0xFEB7,
+ },
+ [0xFEB8]={
+ adobename="sheenmedialarabic",
+ category="lo",
+ description="ARABIC LETTER SHEEN MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0634 },
+ unicodeslot=0xFEB8,
+ },
+ [0xFEB9]={
+ category="lo",
+ description="ARABIC LETTER SAD ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0635 },
+ unicodeslot=0xFEB9,
+ },
+ [0xFEBA]={
+ adobename="sadfinalarabic",
+ category="lo",
+ description="ARABIC LETTER SAD FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0635 },
+ unicodeslot=0xFEBA,
+ },
+ [0xFEBB]={
+ adobename="sadinitialarabic",
+ category="lo",
+ description="ARABIC LETTER SAD INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0635 },
+ unicodeslot=0xFEBB,
+ },
+ [0xFEBC]={
+ adobename="sadmedialarabic",
+ category="lo",
+ description="ARABIC LETTER SAD MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0635 },
+ unicodeslot=0xFEBC,
+ },
+ [0xFEBD]={
+ category="lo",
+ description="ARABIC LETTER DAD ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0636 },
+ unicodeslot=0xFEBD,
+ },
+ [0xFEBE]={
+ adobename="dadfinalarabic",
+ category="lo",
+ description="ARABIC LETTER DAD FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0636 },
+ unicodeslot=0xFEBE,
+ },
+ [0xFEBF]={
+ adobename="dadinitialarabic",
+ category="lo",
+ description="ARABIC LETTER DAD INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0636 },
+ unicodeslot=0xFEBF,
+ },
+ [0xFEC0]={
+ adobename="dadmedialarabic",
+ category="lo",
+ description="ARABIC LETTER DAD MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0636 },
+ unicodeslot=0xFEC0,
+ },
+ [0xFEC1]={
+ category="lo",
+ description="ARABIC LETTER TAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0637 },
+ unicodeslot=0xFEC1,
+ },
+ [0xFEC2]={
+ adobename="tahfinalarabic",
+ category="lo",
+ description="ARABIC LETTER TAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0637 },
+ unicodeslot=0xFEC2,
+ },
+ [0xFEC3]={
+ adobename="tahinitialarabic",
+ category="lo",
+ description="ARABIC LETTER TAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0637 },
+ unicodeslot=0xFEC3,
+ },
+ [0xFEC4]={
+ adobename="tahmedialarabic",
+ category="lo",
+ description="ARABIC LETTER TAH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0637 },
+ unicodeslot=0xFEC4,
+ },
+ [0xFEC5]={
+ category="lo",
+ description="ARABIC LETTER ZAH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0638 },
+ unicodeslot=0xFEC5,
+ },
+ [0xFEC6]={
+ adobename="zahfinalarabic",
+ category="lo",
+ description="ARABIC LETTER ZAH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0638 },
+ unicodeslot=0xFEC6,
+ },
+ [0xFEC7]={
+ adobename="zahinitialarabic",
+ category="lo",
+ description="ARABIC LETTER ZAH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0638 },
+ unicodeslot=0xFEC7,
+ },
+ [0xFEC8]={
+ adobename="zahmedialarabic",
+ category="lo",
+ description="ARABIC LETTER ZAH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0638 },
+ unicodeslot=0xFEC8,
+ },
+ [0xFEC9]={
+ category="lo",
+ description="ARABIC LETTER AIN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0639 },
+ unicodeslot=0xFEC9,
+ },
+ [0xFECA]={
+ adobename="ainfinalarabic",
+ category="lo",
+ description="ARABIC LETTER AIN FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0639 },
+ unicodeslot=0xFECA,
+ },
+ [0xFECB]={
+ adobename="aininitialarabic",
+ category="lo",
+ description="ARABIC LETTER AIN INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0639 },
+ unicodeslot=0xFECB,
+ },
+ [0xFECC]={
+ adobename="ainmedialarabic",
+ category="lo",
+ description="ARABIC LETTER AIN MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0639 },
+ unicodeslot=0xFECC,
+ },
+ [0xFECD]={
+ category="lo",
+ description="ARABIC LETTER GHAIN ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x063A },
+ unicodeslot=0xFECD,
+ },
+ [0xFECE]={
+ adobename="ghainfinalarabic",
+ category="lo",
+ description="ARABIC LETTER GHAIN FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x063A },
+ unicodeslot=0xFECE,
+ },
+ [0xFECF]={
+ adobename="ghaininitialarabic",
+ category="lo",
+ description="ARABIC LETTER GHAIN INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x063A },
+ unicodeslot=0xFECF,
+ },
+ [0xFED0]={
+ adobename="ghainmedialarabic",
+ category="lo",
+ description="ARABIC LETTER GHAIN MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x063A },
+ unicodeslot=0xFED0,
+ },
+ [0xFED1]={
+ category="lo",
+ description="ARABIC LETTER FEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0641 },
+ unicodeslot=0xFED1,
+ },
+ [0xFED2]={
+ adobename="fehfinalarabic",
+ category="lo",
+ description="ARABIC LETTER FEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0641 },
+ unicodeslot=0xFED2,
+ },
+ [0xFED3]={
+ adobename="fehinitialarabic",
+ category="lo",
+ description="ARABIC LETTER FEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0641 },
+ unicodeslot=0xFED3,
+ },
+ [0xFED4]={
+ adobename="fehmedialarabic",
+ category="lo",
+ description="ARABIC LETTER FEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0641 },
+ unicodeslot=0xFED4,
+ },
+ [0xFED5]={
+ category="lo",
+ description="ARABIC LETTER QAF ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0642 },
+ unicodeslot=0xFED5,
+ },
+ [0xFED6]={
+ adobename="qaffinalarabic",
+ category="lo",
+ description="ARABIC LETTER QAF FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0642 },
+ unicodeslot=0xFED6,
+ },
+ [0xFED7]={
+ adobename="qafinitialarabic",
+ category="lo",
+ description="ARABIC LETTER QAF INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0642 },
+ unicodeslot=0xFED7,
+ },
+ [0xFED8]={
+ adobename="qafmedialarabic",
+ category="lo",
+ description="ARABIC LETTER QAF MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0642 },
+ unicodeslot=0xFED8,
+ },
+ [0xFED9]={
+ category="lo",
+ description="ARABIC LETTER KAF ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0643 },
+ unicodeslot=0xFED9,
+ },
+ [0xFEDA]={
+ adobename="kaffinalarabic",
+ category="lo",
+ description="ARABIC LETTER KAF FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0643 },
+ unicodeslot=0xFEDA,
+ },
+ [0xFEDB]={
+ adobename="kafinitialarabic",
+ category="lo",
+ description="ARABIC LETTER KAF INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0643 },
+ unicodeslot=0xFEDB,
+ },
+ [0xFEDC]={
+ adobename="kafmedialarabic",
+ category="lo",
+ description="ARABIC LETTER KAF MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0643 },
+ unicodeslot=0xFEDC,
+ },
+ [0xFEDD]={
+ category="lo",
+ description="ARABIC LETTER LAM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0644 },
+ unicodeslot=0xFEDD,
+ },
+ [0xFEDE]={
+ adobename="lamfinalarabic",
+ category="lo",
+ description="ARABIC LETTER LAM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644 },
+ unicodeslot=0xFEDE,
+ },
+ [0xFEDF]={
+ adobename="lammeemkhahinitialarabic",
+ category="lo",
+ description="ARABIC LETTER LAM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0644 },
+ unicodeslot=0xFEDF,
+ },
+ [0xFEE0]={
+ adobename="lammedialarabic",
+ category="lo",
+ description="ARABIC LETTER LAM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0644 },
+ unicodeslot=0xFEE0,
+ },
+ [0xFEE1]={
+ category="lo",
+ description="ARABIC LETTER MEEM ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0645 },
+ unicodeslot=0xFEE1,
+ },
+ [0xFEE2]={
+ adobename="meemfinalarabic",
+ category="lo",
+ description="ARABIC LETTER MEEM FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0645 },
+ unicodeslot=0xFEE2,
+ },
+ [0xFEE3]={
+ adobename="meeminitialarabic",
+ category="lo",
+ description="ARABIC LETTER MEEM INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0645 },
+ unicodeslot=0xFEE3,
+ },
+ [0xFEE4]={
+ adobename="meemmedialarabic",
+ category="lo",
+ description="ARABIC LETTER MEEM MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0645 },
+ unicodeslot=0xFEE4,
+ },
+ [0xFEE5]={
+ category="lo",
+ description="ARABIC LETTER NOON ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0646 },
+ unicodeslot=0xFEE5,
+ },
+ [0xFEE6]={
+ adobename="noonfinalarabic",
+ category="lo",
+ description="ARABIC LETTER NOON FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0646 },
+ unicodeslot=0xFEE6,
+ },
+ [0xFEE7]={
+ adobename="nooninitialarabic",
+ category="lo",
+ description="ARABIC LETTER NOON INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0646 },
+ unicodeslot=0xFEE7,
+ },
+ [0xFEE8]={
+ adobename="noonmedialarabic",
+ category="lo",
+ description="ARABIC LETTER NOON MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0646 },
+ unicodeslot=0xFEE8,
+ },
+ [0xFEE9]={
+ category="lo",
+ description="ARABIC LETTER HEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0647 },
+ unicodeslot=0xFEE9,
+ },
+ [0xFEEA]={
+ adobename="hehfinalarabic",
+ category="lo",
+ description="ARABIC LETTER HEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0647 },
+ unicodeslot=0xFEEA,
+ },
+ [0xFEEB]={
+ adobename="hehinitialarabic",
+ category="lo",
+ description="ARABIC LETTER HEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x0647 },
+ unicodeslot=0xFEEB,
+ },
+ [0xFEEC]={
+ adobename="hehmedialarabic",
+ category="lo",
+ description="ARABIC LETTER HEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x0647 },
+ unicodeslot=0xFEEC,
+ },
+ [0xFEED]={
+ category="lo",
+ description="ARABIC LETTER WAW ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0648 },
+ unicodeslot=0xFEED,
+ },
+ [0xFEEE]={
+ adobename="wawfinalarabic",
+ category="lo",
+ description="ARABIC LETTER WAW FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0648 },
+ unicodeslot=0xFEEE,
+ },
+ [0xFEEF]={
+ category="lo",
+ description="ARABIC LETTER ALEF MAKSURA ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0649 },
+ unicodeslot=0xFEEF,
+ },
+ [0xFEF0]={
+ adobename="alefmaksurafinalarabic",
+ category="lo",
+ description="ARABIC LETTER ALEF MAKSURA FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0649 },
+ unicodeslot=0xFEF0,
+ },
+ [0xFEF1]={
+ category="lo",
+ description="ARABIC LETTER YEH ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x064A },
+ unicodeslot=0xFEF1,
+ },
+ [0xFEF2]={
+ adobename="yehfinalarabic",
+ category="lo",
+ description="ARABIC LETTER YEH FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x064A },
+ unicodeslot=0xFEF2,
+ },
+ [0xFEF3]={
+ adobename="yehinitialarabic",
+ category="lo",
+ description="ARABIC LETTER YEH INITIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "initial", 0x064A },
+ unicodeslot=0xFEF3,
+ },
+ [0xFEF4]={
+ adobename="yehmedialarabic",
+ category="lo",
+ description="ARABIC LETTER YEH MEDIAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "medial", 0x064A },
+ unicodeslot=0xFEF4,
+ },
+ [0xFEF5]={
+ adobename="lamalefmaddaaboveisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0644, 0x0622 },
+ unicodeslot=0xFEF5,
+ },
+ [0xFEF6]={
+ adobename="lamalefmaddaabovefinalarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x0622 },
+ unicodeslot=0xFEF6,
+ },
+ [0xFEF7]={
+ adobename="lamalefhamzaaboveisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0644, 0x0623 },
+ unicodeslot=0xFEF7,
+ },
+ [0xFEF8]={
+ adobename="lamalefhamzaabovefinalarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x0623 },
+ unicodeslot=0xFEF8,
+ },
+ [0xFEF9]={
+ adobename="lamalefhamzabelowisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0644, 0x0625 },
+ unicodeslot=0xFEF9,
+ },
+ [0xFEFA]={
+ adobename="lamalefhamzabelowfinalarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x0625 },
+ unicodeslot=0xFEFA,
+ },
+ [0xFEFB]={
+ adobename="lamalefisolatedarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "isolated", 0x0644, 0x0627 },
+ unicodeslot=0xFEFB,
+ },
+ [0xFEFC]={
+ adobename="lamaleffinalarabic",
+ category="lo",
+ description="ARABIC LIGATURE LAM WITH ALEF FINAL FORM",
+ direction="al",
+ linebreak="al",
+ specials={ "final", 0x0644, 0x0627 },
+ unicodeslot=0xFEFC,
+ },
+ [0xFEFF]={
+ adobename="zerowidthjoiner",
+ category="cf",
+ contextname="zerowidthnobreakspace",
+ description="ZERO WIDTH NO-BREAK SPACE",
+ direction="bn",
+ linebreak="wj",
+ unicodeslot=0xFEFF,
+ },
+ [0xFF01]={
+ adobename="exclammonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH EXCLAMATION MARK",
+ direction="on",
+ linebreak="ex",
+ specials={ "wide", 0x0021 },
+ unicodeslot=0xFF01,
+ },
+ [0xFF02]={
+ adobename="quotedblmonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH QUOTATION MARK",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x0022 },
+ unicodeslot=0xFF02,
+ },
+ [0xFF03]={
+ adobename="numbersignmonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH NUMBER SIGN",
+ direction="et",
+ linebreak="id",
+ specials={ "wide", 0x0023 },
+ unicodeslot=0xFF03,
+ },
+ [0xFF04]={
+ adobename="dollarmonospace",
+ category="sc",
+ cjkwd="f",
+ description="FULLWIDTH DOLLAR SIGN",
+ direction="et",
+ linebreak="pr",
+ specials={ "wide", 0x0024 },
+ unicodeslot=0xFF04,
+ },
+ [0xFF05]={
+ adobename="percentmonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH PERCENT SIGN",
+ direction="et",
+ linebreak="po",
+ specials={ "wide", 0x0025 },
+ unicodeslot=0xFF05,
+ },
+ [0xFF06]={
+ adobename="ampersandmonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH AMPERSAND",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x0026 },
+ unicodeslot=0xFF06,
+ },
+ [0xFF07]={
+ adobename="quotesinglemonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH APOSTROPHE",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x0027 },
+ unicodeslot=0xFF07,
+ },
+ [0xFF08]={
+ adobename="parenleftmonospace",
+ category="ps",
+ cjkwd="f",
+ description="FULLWIDTH LEFT PARENTHESIS",
+ direction="on",
+ linebreak="op",
+ mirror=0xFF09,
+ textclass="open",
+ specials={ "wide", 0x0028 },
+ unicodeslot=0xFF08,
+ },
+ [0xFF09]={
+ adobename="parenrightmonospace",
+ category="pe",
+ cjkwd="f",
+ description="FULLWIDTH RIGHT PARENTHESIS",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFF08,
+ textclass="close",
+ specials={ "wide", 0x0029 },
+ unicodeslot=0xFF09,
+ },
+ [0xFF0A]={
+ adobename="asteriskmonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH ASTERISK",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x002A },
+ unicodeslot=0xFF0A,
+ },
+ [0xFF0B]={
+ adobename="plusmonospace",
+ category="sm",
+ cjkwd="f",
+ description="FULLWIDTH PLUS SIGN",
+ direction="es",
+ linebreak="id",
+ specials={ "wide", 0x002B },
+ unicodeslot=0xFF0B,
+ },
+ [0xFF0C]={
+ adobename="commamonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH COMMA",
+ direction="cs",
+ linebreak="cl",
+ specials={ "wide", 0x002C },
+ unicodeslot=0xFF0C,
+ },
+ [0xFF0D]={
+ adobename="hyphenmonospace",
+ category="pd",
+ cjkwd="f",
+ description="FULLWIDTH HYPHEN-MINUS",
+ direction="es",
+ linebreak="id",
+ specials={ "wide", 0x002D },
+ unicodeslot=0xFF0D,
+ },
+ [0xFF0E]={
+ adobename="periodmonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH FULL STOP",
+ direction="cs",
+ linebreak="cl",
+ specials={ "wide", 0x002E },
+ unicodeslot=0xFF0E,
+ },
+ [0xFF0F]={
+ adobename="slashmonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH SOLIDUS",
+ direction="cs",
+ linebreak="id",
+ specials={ "wide", 0x002F },
+ unicodeslot=0xFF0F,
+ },
+ [0xFF10]={
+ adobename="zeromonospace",
+ category="nd",
+ cjkwd="f",
+ description="FULLWIDTH DIGIT ZERO",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x0030 },
+ unicodeslot=0xFF10,
+ },
+ [0xFF11]={
+ adobename="onemonospace",
+ category="nd",
+ cjkwd="f",
+ description="FULLWIDTH DIGIT ONE",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x0031 },
+ unicodeslot=0xFF11,
+ },
+ [0xFF12]={
+ adobename="twomonospace",
+ category="nd",
+ cjkwd="f",
+ description="FULLWIDTH DIGIT TWO",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x0032 },
+ unicodeslot=0xFF12,
+ },
+ [0xFF13]={
+ adobename="threemonospace",
+ category="nd",
+ cjkwd="f",
+ description="FULLWIDTH DIGIT THREE",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x0033 },
+ unicodeslot=0xFF13,
+ },
+ [0xFF14]={
+ adobename="fourmonospace",
+ category="nd",
+ cjkwd="f",
+ description="FULLWIDTH DIGIT FOUR",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x0034 },
+ unicodeslot=0xFF14,
+ },
+ [0xFF15]={
+ adobename="fivemonospace",
+ category="nd",
+ cjkwd="f",
+ description="FULLWIDTH DIGIT FIVE",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x0035 },
+ unicodeslot=0xFF15,
+ },
+ [0xFF16]={
+ adobename="sixmonospace",
+ category="nd",
+ cjkwd="f",
+ description="FULLWIDTH DIGIT SIX",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x0036 },
+ unicodeslot=0xFF16,
+ },
+ [0xFF17]={
+ adobename="sevenmonospace",
+ category="nd",
+ cjkwd="f",
+ description="FULLWIDTH DIGIT SEVEN",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x0037 },
+ unicodeslot=0xFF17,
+ },
+ [0xFF18]={
+ adobename="eightmonospace",
+ category="nd",
+ cjkwd="f",
+ description="FULLWIDTH DIGIT EIGHT",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x0038 },
+ unicodeslot=0xFF18,
+ },
+ [0xFF19]={
+ adobename="ninemonospace",
+ category="nd",
+ cjkwd="f",
+ description="FULLWIDTH DIGIT NINE",
+ direction="en",
+ linebreak="id",
+ specials={ "wide", 0x0039 },
+ unicodeslot=0xFF19,
+ },
+ [0xFF1A]={
+ adobename="colonmonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH COLON",
+ direction="cs",
+ linebreak="ns",
+ specials={ "wide", 0x003A },
+ unicodeslot=0xFF1A,
+ },
+ [0xFF1B]={
+ adobename="semicolonmonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH SEMICOLON",
+ direction="on",
+ linebreak="ns",
+ specials={ "wide", 0x003B },
+ unicodeslot=0xFF1B,
+ },
+ [0xFF1C]={
+ adobename="lessmonospace",
+ category="sm",
+ cjkwd="f",
+ description="FULLWIDTH LESS-THAN SIGN",
+ direction="on",
+ linebreak="id",
+ mirror=0xFF1E,
+ textclass="open",
+ specials={ "wide", 0x003C },
+ unicodeslot=0xFF1C,
+ },
+ [0xFF1D]={
+ adobename="equalmonospace",
+ category="sm",
+ cjkwd="f",
+ description="FULLWIDTH EQUALS SIGN",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x003D },
+ unicodeslot=0xFF1D,
+ },
+ [0xFF1E]={
+ adobename="greatermonospace",
+ category="sm",
+ cjkwd="f",
+ description="FULLWIDTH GREATER-THAN SIGN",
+ direction="on",
+ linebreak="id",
+ mirror=0xFF1C,
+ textclass="close",
+ specials={ "wide", 0x003E },
+ unicodeslot=0xFF1E,
+ },
+ [0xFF1F]={
+ adobename="questionmonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH QUESTION MARK",
+ direction="on",
+ linebreak="ex",
+ specials={ "wide", 0x003F },
+ unicodeslot=0xFF1F,
+ },
+ [0xFF20]={
+ adobename="atmonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH COMMERCIAL AT",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x0040 },
+ unicodeslot=0xFF20,
+ },
+ [0xFF21]={
+ adobename="Amonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER A",
+ direction="l",
+ lccode=0xFF41,
+ linebreak="id",
+ specials={ "wide", 0x0041 },
+ unicodeslot=0xFF21,
+ },
+ [0xFF22]={
+ adobename="Bmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER B",
+ direction="l",
+ lccode=0xFF42,
+ linebreak="id",
+ specials={ "wide", 0x0042 },
+ unicodeslot=0xFF22,
+ },
+ [0xFF23]={
+ adobename="Cmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER C",
+ direction="l",
+ lccode=0xFF43,
+ linebreak="id",
+ specials={ "wide", 0x0043 },
+ unicodeslot=0xFF23,
+ },
+ [0xFF24]={
+ adobename="Dmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER D",
+ direction="l",
+ lccode=0xFF44,
+ linebreak="id",
+ specials={ "wide", 0x0044 },
+ unicodeslot=0xFF24,
+ },
+ [0xFF25]={
+ adobename="Emonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER E",
+ direction="l",
+ lccode=0xFF45,
+ linebreak="id",
+ specials={ "wide", 0x0045 },
+ unicodeslot=0xFF25,
+ },
+ [0xFF26]={
+ adobename="Fmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER F",
+ direction="l",
+ lccode=0xFF46,
+ linebreak="id",
+ specials={ "wide", 0x0046 },
+ unicodeslot=0xFF26,
+ },
+ [0xFF27]={
+ adobename="Gmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER G",
+ direction="l",
+ lccode=0xFF47,
+ linebreak="id",
+ specials={ "wide", 0x0047 },
+ unicodeslot=0xFF27,
+ },
+ [0xFF28]={
+ adobename="Hmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER H",
+ direction="l",
+ lccode=0xFF48,
+ linebreak="id",
+ specials={ "wide", 0x0048 },
+ unicodeslot=0xFF28,
+ },
+ [0xFF29]={
+ adobename="Imonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER I",
+ direction="l",
+ lccode=0xFF49,
+ linebreak="id",
+ specials={ "wide", 0x0049 },
+ unicodeslot=0xFF29,
+ },
+ [0xFF2A]={
+ adobename="Jmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER J",
+ direction="l",
+ lccode=0xFF4A,
+ linebreak="id",
+ specials={ "wide", 0x004A },
+ unicodeslot=0xFF2A,
+ },
+ [0xFF2B]={
+ adobename="Kmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER K",
+ direction="l",
+ lccode=0xFF4B,
+ linebreak="id",
+ specials={ "wide", 0x004B },
+ unicodeslot=0xFF2B,
+ },
+ [0xFF2C]={
+ adobename="Lmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER L",
+ direction="l",
+ lccode=0xFF4C,
+ linebreak="id",
+ specials={ "wide", 0x004C },
+ unicodeslot=0xFF2C,
+ },
+ [0xFF2D]={
+ adobename="Mmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER M",
+ direction="l",
+ lccode=0xFF4D,
+ linebreak="id",
+ specials={ "wide", 0x004D },
+ unicodeslot=0xFF2D,
+ },
+ [0xFF2E]={
+ adobename="Nmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER N",
+ direction="l",
+ lccode=0xFF4E,
+ linebreak="id",
+ specials={ "wide", 0x004E },
+ unicodeslot=0xFF2E,
+ },
+ [0xFF2F]={
+ adobename="Omonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER O",
+ direction="l",
+ lccode=0xFF4F,
+ linebreak="id",
+ specials={ "wide", 0x004F },
+ unicodeslot=0xFF2F,
+ },
+ [0xFF30]={
+ adobename="Pmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER P",
+ direction="l",
+ lccode=0xFF50,
+ linebreak="id",
+ specials={ "wide", 0x0050 },
+ unicodeslot=0xFF30,
+ },
+ [0xFF31]={
+ adobename="Qmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER Q",
+ direction="l",
+ lccode=0xFF51,
+ linebreak="id",
+ specials={ "wide", 0x0051 },
+ unicodeslot=0xFF31,
+ },
+ [0xFF32]={
+ adobename="Rmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER R",
+ direction="l",
+ lccode=0xFF52,
+ linebreak="id",
+ specials={ "wide", 0x0052 },
+ unicodeslot=0xFF32,
+ },
+ [0xFF33]={
+ adobename="Smonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER S",
+ direction="l",
+ lccode=0xFF53,
+ linebreak="id",
+ specials={ "wide", 0x0053 },
+ unicodeslot=0xFF33,
+ },
+ [0xFF34]={
+ adobename="Tmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER T",
+ direction="l",
+ lccode=0xFF54,
+ linebreak="id",
+ specials={ "wide", 0x0054 },
+ unicodeslot=0xFF34,
+ },
+ [0xFF35]={
+ adobename="Umonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER U",
+ direction="l",
+ lccode=0xFF55,
+ linebreak="id",
+ specials={ "wide", 0x0055 },
+ unicodeslot=0xFF35,
+ },
+ [0xFF36]={
+ adobename="Vmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER V",
+ direction="l",
+ lccode=0xFF56,
+ linebreak="id",
+ specials={ "wide", 0x0056 },
+ unicodeslot=0xFF36,
+ },
+ [0xFF37]={
+ adobename="Wmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER W",
+ direction="l",
+ lccode=0xFF57,
+ linebreak="id",
+ specials={ "wide", 0x0057 },
+ unicodeslot=0xFF37,
+ },
+ [0xFF38]={
+ adobename="Xmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER X",
+ direction="l",
+ lccode=0xFF58,
+ linebreak="id",
+ specials={ "wide", 0x0058 },
+ unicodeslot=0xFF38,
+ },
+ [0xFF39]={
+ adobename="Ymonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER Y",
+ direction="l",
+ lccode=0xFF59,
+ linebreak="id",
+ specials={ "wide", 0x0059 },
+ unicodeslot=0xFF39,
+ },
+ [0xFF3A]={
+ adobename="Zmonospace",
+ category="lu",
+ cjkwd="f",
+ description="FULLWIDTH LATIN CAPITAL LETTER Z",
+ direction="l",
+ lccode=0xFF5A,
+ linebreak="id",
+ specials={ "wide", 0x005A },
+ unicodeslot=0xFF3A,
+ },
+ [0xFF3B]={
+ adobename="bracketleftmonospace",
+ category="ps",
+ cjkwd="f",
+ description="FULLWIDTH LEFT SQUARE BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0xFF3D,
+ textclass="open",
+ specials={ "wide", 0x005B },
+ unicodeslot=0xFF3B,
+ },
+ [0xFF3C]={
+ adobename="backslashmonospace",
+ category="po",
+ cjkwd="f",
+ description="FULLWIDTH REVERSE SOLIDUS",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x005C },
+ unicodeslot=0xFF3C,
+ },
+ [0xFF3D]={
+ adobename="bracketrightmonospace",
+ category="pe",
+ cjkwd="f",
+ description="FULLWIDTH RIGHT SQUARE BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFF3B,
+ textclass="close",
+ specials={ "wide", 0x005D },
+ unicodeslot=0xFF3D,
+ },
+ [0xFF3E]={
+ adobename="asciicircummonospace",
+ category="sk",
+ cjkwd="f",
+ description="FULLWIDTH CIRCUMFLEX ACCENT",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x005E },
+ unicodeslot=0xFF3E,
+ },
+ [0xFF3F]={
+ adobename="underscoremonospace",
+ category="pc",
+ cjkwd="f",
+ description="FULLWIDTH LOW LINE",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x005F },
+ unicodeslot=0xFF3F,
+ },
+ [0xFF40]={
+ adobename="gravemonospace",
+ category="sk",
+ cjkwd="f",
+ description="FULLWIDTH GRAVE ACCENT",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x0060 },
+ unicodeslot=0xFF40,
+ },
+ [0xFF41]={
+ adobename="amonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER A",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0061 },
+ uccode=0xFF21,
+ unicodeslot=0xFF41,
+ },
+ [0xFF42]={
+ adobename="bmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER B",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0062 },
+ uccode=0xFF22,
+ unicodeslot=0xFF42,
+ },
+ [0xFF43]={
+ adobename="cmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER C",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0063 },
+ uccode=0xFF23,
+ unicodeslot=0xFF43,
+ },
+ [0xFF44]={
+ adobename="dmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER D",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0064 },
+ uccode=0xFF24,
+ unicodeslot=0xFF44,
+ },
+ [0xFF45]={
+ adobename="emonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER E",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0065 },
+ uccode=0xFF25,
+ unicodeslot=0xFF45,
+ },
+ [0xFF46]={
+ adobename="fmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER F",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0066 },
+ uccode=0xFF26,
+ unicodeslot=0xFF46,
+ },
+ [0xFF47]={
+ adobename="gmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER G",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0067 },
+ uccode=0xFF27,
+ unicodeslot=0xFF47,
+ },
+ [0xFF48]={
+ adobename="hmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER H",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0068 },
+ uccode=0xFF28,
+ unicodeslot=0xFF48,
+ },
+ [0xFF49]={
+ adobename="imonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER I",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0069 },
+ uccode=0xFF29,
+ unicodeslot=0xFF49,
+ },
+ [0xFF4A]={
+ adobename="jmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER J",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x006A },
+ uccode=0xFF2A,
+ unicodeslot=0xFF4A,
+ },
+ [0xFF4B]={
+ adobename="kmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER K",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x006B },
+ uccode=0xFF2B,
+ unicodeslot=0xFF4B,
+ },
+ [0xFF4C]={
+ adobename="lmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER L",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x006C },
+ uccode=0xFF2C,
+ unicodeslot=0xFF4C,
+ },
+ [0xFF4D]={
+ adobename="mmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER M",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x006D },
+ uccode=0xFF2D,
+ unicodeslot=0xFF4D,
+ },
+ [0xFF4E]={
+ adobename="nmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER N",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x006E },
+ uccode=0xFF2E,
+ unicodeslot=0xFF4E,
+ },
+ [0xFF4F]={
+ adobename="omonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER O",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x006F },
+ uccode=0xFF2F,
+ unicodeslot=0xFF4F,
+ },
+ [0xFF50]={
+ adobename="pmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER P",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0070 },
+ uccode=0xFF30,
+ unicodeslot=0xFF50,
+ },
+ [0xFF51]={
+ adobename="qmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER Q",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0071 },
+ uccode=0xFF31,
+ unicodeslot=0xFF51,
+ },
+ [0xFF52]={
+ adobename="rmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER R",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0072 },
+ uccode=0xFF32,
+ unicodeslot=0xFF52,
+ },
+ [0xFF53]={
+ adobename="smonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER S",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0073 },
+ uccode=0xFF33,
+ unicodeslot=0xFF53,
+ },
+ [0xFF54]={
+ adobename="tmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER T",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0074 },
+ uccode=0xFF34,
+ unicodeslot=0xFF54,
+ },
+ [0xFF55]={
+ adobename="umonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER U",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0075 },
+ uccode=0xFF35,
+ unicodeslot=0xFF55,
+ },
+ [0xFF56]={
+ adobename="vmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER V",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0076 },
+ uccode=0xFF36,
+ unicodeslot=0xFF56,
+ },
+ [0xFF57]={
+ adobename="wmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER W",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0077 },
+ uccode=0xFF37,
+ unicodeslot=0xFF57,
+ },
+ [0xFF58]={
+ adobename="xmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER X",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0078 },
+ uccode=0xFF38,
+ unicodeslot=0xFF58,
+ },
+ [0xFF59]={
+ adobename="ymonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER Y",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x0079 },
+ uccode=0xFF39,
+ unicodeslot=0xFF59,
+ },
+ [0xFF5A]={
+ adobename="zmonospace",
+ category="ll",
+ cjkwd="f",
+ description="FULLWIDTH LATIN SMALL LETTER Z",
+ direction="l",
+ linebreak="id",
+ specials={ "wide", 0x007A },
+ uccode=0xFF3A,
+ unicodeslot=0xFF5A,
+ },
+ [0xFF5B]={
+ adobename="braceleftmonospace",
+ category="ps",
+ cjkwd="f",
+ description="FULLWIDTH LEFT CURLY BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0xFF5D,
+ textclass="open",
+ specials={ "wide", 0x007B },
+ unicodeslot=0xFF5B,
+ },
+ [0xFF5C]={
+ adobename="barmonospace",
+ category="sm",
+ cjkwd="f",
+ description="FULLWIDTH VERTICAL LINE",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x007C },
+ unicodeslot=0xFF5C,
+ },
+ [0xFF5D]={
+ adobename="bracerightmonospace",
+ category="pe",
+ cjkwd="f",
+ description="FULLWIDTH RIGHT CURLY BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFF5B,
+ textclass="close",
+ specials={ "wide", 0x007D },
+ unicodeslot=0xFF5D,
+ },
+ [0xFF5E]={
+ adobename="asciitildemonospace",
+ category="sm",
+ cjkwd="f",
+ description="FULLWIDTH TILDE",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x007E },
+ unicodeslot=0xFF5E,
+ },
+ [0xFF5F]={
+ category="ps",
+ cjkwd="f",
+ description="FULLWIDTH LEFT WHITE PARENTHESIS",
+ direction="on",
+ linebreak="op",
+ mirror=0xFF60,
+ textclass="open",
+ specials={ "wide", 0x2985 },
+ unicodeslot=0xFF5F,
+ },
+ [0xFF60]={
+ category="pe",
+ cjkwd="f",
+ description="FULLWIDTH RIGHT WHITE PARENTHESIS",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFF5F,
+ textclass="close",
+ specials={ "wide", 0x2986 },
+ unicodeslot=0xFF60,
+ },
+ [0xFF61]={
+ adobename="periodhalfwidth",
+ category="po",
+ cjkwd="h",
+ description="HALFWIDTH IDEOGRAPHIC FULL STOP",
+ direction="on",
+ linebreak="cl",
+ specials={ "narrow", 0x3002 },
+ unicodeslot=0xFF61,
+ },
+ [0xFF62]={
+ adobename="cornerbracketlefthalfwidth",
+ category="ps",
+ cjkwd="h",
+ description="HALFWIDTH LEFT CORNER BRACKET",
+ direction="on",
+ linebreak="op",
+ mirror=0xFF63,
+ textclass="open",
+ specials={ "narrow", 0x300C },
+ unicodeslot=0xFF62,
+ },
+ [0xFF63]={
+ adobename="cornerbracketrighthalfwidth",
+ category="pe",
+ cjkwd="h",
+ description="HALFWIDTH RIGHT CORNER BRACKET",
+ direction="on",
+ linebreak="cl",
+ mirror=0xFF62,
+ textclass="close",
+ specials={ "narrow", 0x300D },
+ unicodeslot=0xFF63,
+ },
+ [0xFF64]={
+ adobename="ideographiccommaleft",
+ category="po",
+ cjkwd="h",
+ description="HALFWIDTH IDEOGRAPHIC COMMA",
+ direction="on",
+ linebreak="cl",
+ specials={ "narrow", 0x3001 },
+ unicodeslot=0xFF64,
+ },
+ [0xFF65]={
+ adobename="middledotkatakanahalfwidth",
+ category="po",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA MIDDLE DOT",
+ direction="on",
+ linebreak="ns",
+ specials={ "narrow", 0x30FB },
+ unicodeslot=0xFF65,
+ },
+ [0xFF66]={
+ adobename="wokatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER WO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30F2 },
+ unicodeslot=0xFF66,
+ },
+ [0xFF67]={
+ adobename="asmallkatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SMALL A",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30A1 },
+ unicodeslot=0xFF67,
+ },
+ [0xFF68]={
+ adobename="ismallkatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SMALL I",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30A3 },
+ unicodeslot=0xFF68,
+ },
+ [0xFF69]={
+ adobename="usmallkatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SMALL U",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30A5 },
+ unicodeslot=0xFF69,
+ },
+ [0xFF6A]={
+ adobename="esmallkatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SMALL E",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30A7 },
+ unicodeslot=0xFF6A,
+ },
+ [0xFF6B]={
+ adobename="osmallkatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SMALL O",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30A9 },
+ unicodeslot=0xFF6B,
+ },
+ [0xFF6C]={
+ adobename="yasmallkatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SMALL YA",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30E3 },
+ unicodeslot=0xFF6C,
+ },
+ [0xFF6D]={
+ adobename="yusmallkatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SMALL YU",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30E5 },
+ unicodeslot=0xFF6D,
+ },
+ [0xFF6E]={
+ adobename="yosmallkatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SMALL YO",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30E7 },
+ unicodeslot=0xFF6E,
+ },
+ [0xFF6F]={
+ adobename="tusmallkatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SMALL TU",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30C3 },
+ unicodeslot=0xFF6F,
+ },
+ [0xFF70]={
+ adobename="katahiraprolongmarkhalfwidth",
+ category="lm",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK",
+ direction="l",
+ linebreak="cj",
+ specials={ "narrow", 0x30FC },
+ unicodeslot=0xFF70,
+ },
+ [0xFF71]={
+ adobename="akatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER A",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30A2 },
+ unicodeslot=0xFF71,
+ },
+ [0xFF72]={
+ adobename="ikatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER I",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30A4 },
+ unicodeslot=0xFF72,
+ },
+ [0xFF73]={
+ adobename="ukatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER U",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30A6 },
+ unicodeslot=0xFF73,
+ },
+ [0xFF74]={
+ adobename="ekatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER E",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30A8 },
+ unicodeslot=0xFF74,
+ },
+ [0xFF75]={
+ adobename="okatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER O",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30AA },
+ unicodeslot=0xFF75,
+ },
+ [0xFF76]={
+ adobename="kakatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER KA",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30AB },
+ unicodeslot=0xFF76,
+ },
+ [0xFF77]={
+ adobename="kikatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER KI",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30AD },
+ unicodeslot=0xFF77,
+ },
+ [0xFF78]={
+ adobename="kukatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER KU",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30AF },
+ unicodeslot=0xFF78,
+ },
+ [0xFF79]={
+ adobename="kekatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER KE",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30B1 },
+ unicodeslot=0xFF79,
+ },
+ [0xFF7A]={
+ adobename="kokatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER KO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30B3 },
+ unicodeslot=0xFF7A,
+ },
+ [0xFF7B]={
+ adobename="sakatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SA",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30B5 },
+ unicodeslot=0xFF7B,
+ },
+ [0xFF7C]={
+ adobename="sikatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SI",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30B7 },
+ unicodeslot=0xFF7C,
+ },
+ [0xFF7D]={
+ adobename="sukatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SU",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30B9 },
+ unicodeslot=0xFF7D,
+ },
+ [0xFF7E]={
+ adobename="sekatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SE",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30BB },
+ unicodeslot=0xFF7E,
+ },
+ [0xFF7F]={
+ adobename="sokatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER SO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30BD },
+ unicodeslot=0xFF7F,
+ },
+ [0xFF80]={
+ adobename="takatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER TA",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30BF },
+ unicodeslot=0xFF80,
+ },
+ [0xFF81]={
+ adobename="tikatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER TI",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30C1 },
+ unicodeslot=0xFF81,
+ },
+ [0xFF82]={
+ adobename="tukatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER TU",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30C4 },
+ unicodeslot=0xFF82,
+ },
+ [0xFF83]={
+ adobename="tekatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER TE",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30C6 },
+ unicodeslot=0xFF83,
+ },
+ [0xFF84]={
+ adobename="tokatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER TO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30C8 },
+ unicodeslot=0xFF84,
+ },
+ [0xFF85]={
+ adobename="nakatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER NA",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30CA },
+ unicodeslot=0xFF85,
+ },
+ [0xFF86]={
+ adobename="nikatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER NI",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30CB },
+ unicodeslot=0xFF86,
+ },
+ [0xFF87]={
+ adobename="nukatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER NU",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30CC },
+ unicodeslot=0xFF87,
+ },
+ [0xFF88]={
+ adobename="nekatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER NE",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30CD },
+ unicodeslot=0xFF88,
+ },
+ [0xFF89]={
+ adobename="nokatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER NO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30CE },
+ unicodeslot=0xFF89,
+ },
+ [0xFF8A]={
+ adobename="hakatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER HA",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30CF },
+ unicodeslot=0xFF8A,
+ },
+ [0xFF8B]={
+ adobename="hikatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER HI",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30D2 },
+ unicodeslot=0xFF8B,
+ },
+ [0xFF8C]={
+ adobename="hukatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER HU",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30D5 },
+ unicodeslot=0xFF8C,
+ },
+ [0xFF8D]={
+ adobename="hekatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER HE",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30D8 },
+ unicodeslot=0xFF8D,
+ },
+ [0xFF8E]={
+ adobename="hokatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER HO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30DB },
+ unicodeslot=0xFF8E,
+ },
+ [0xFF8F]={
+ adobename="makatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER MA",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30DE },
+ unicodeslot=0xFF8F,
+ },
+ [0xFF90]={
+ adobename="mikatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER MI",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30DF },
+ unicodeslot=0xFF90,
+ },
+ [0xFF91]={
+ adobename="mukatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER MU",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30E0 },
+ unicodeslot=0xFF91,
+ },
+ [0xFF92]={
+ adobename="mekatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER ME",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30E1 },
+ unicodeslot=0xFF92,
+ },
+ [0xFF93]={
+ adobename="mokatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER MO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30E2 },
+ unicodeslot=0xFF93,
+ },
+ [0xFF94]={
+ adobename="yakatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER YA",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30E4 },
+ unicodeslot=0xFF94,
+ },
+ [0xFF95]={
+ adobename="yukatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER YU",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30E6 },
+ unicodeslot=0xFF95,
+ },
+ [0xFF96]={
+ adobename="yokatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER YO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30E8 },
+ unicodeslot=0xFF96,
+ },
+ [0xFF97]={
+ adobename="rakatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER RA",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30E9 },
+ unicodeslot=0xFF97,
+ },
+ [0xFF98]={
+ adobename="rikatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER RI",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30EA },
+ unicodeslot=0xFF98,
+ },
+ [0xFF99]={
+ adobename="rukatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER RU",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30EB },
+ unicodeslot=0xFF99,
+ },
+ [0xFF9A]={
+ adobename="rekatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER RE",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30EC },
+ unicodeslot=0xFF9A,
+ },
+ [0xFF9B]={
+ adobename="rokatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER RO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30ED },
+ unicodeslot=0xFF9B,
+ },
+ [0xFF9C]={
+ adobename="wakatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER WA",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30EF },
+ unicodeslot=0xFF9C,
+ },
+ [0xFF9D]={
+ adobename="nkatakanahalfwidth",
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA LETTER N",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x30F3 },
+ unicodeslot=0xFF9D,
+ },
+ [0xFF9E]={
+ adobename="voicedmarkkanahalfwidth",
+ category="lm",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA VOICED SOUND MARK",
+ direction="l",
+ linebreak="ns",
+ specials={ "narrow", 0x3099 },
+ unicodeslot=0xFF9E,
+ },
+ [0xFF9F]={
+ adobename="semivoicedmarkkanahalfwidth",
+ category="lm",
+ cjkwd="h",
+ description="HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK",
+ direction="l",
+ linebreak="ns",
+ specials={ "narrow", 0x309A },
+ unicodeslot=0xFF9F,
+ },
+ [0xFFA0]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL FILLER",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3164 },
+ unicodeslot=0xFFA0,
+ },
+ [0xFFA1]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER KIYEOK",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3131 },
+ unicodeslot=0xFFA1,
+ },
+ [0xFFA2]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER SSANGKIYEOK",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3132 },
+ unicodeslot=0xFFA2,
+ },
+ [0xFFA3]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER KIYEOK-SIOS",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3133 },
+ unicodeslot=0xFFA3,
+ },
+ [0xFFA4]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER NIEUN",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3134 },
+ unicodeslot=0xFFA4,
+ },
+ [0xFFA5]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER NIEUN-CIEUC",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3135 },
+ unicodeslot=0xFFA5,
+ },
+ [0xFFA6]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER NIEUN-HIEUH",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3136 },
+ unicodeslot=0xFFA6,
+ },
+ [0xFFA7]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER TIKEUT",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3137 },
+ unicodeslot=0xFFA7,
+ },
+ [0xFFA8]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER SSANGTIKEUT",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3138 },
+ unicodeslot=0xFFA8,
+ },
+ [0xFFA9]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER RIEUL",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3139 },
+ unicodeslot=0xFFA9,
+ },
+ [0xFFAA]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER RIEUL-KIYEOK",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x313A },
+ unicodeslot=0xFFAA,
+ },
+ [0xFFAB]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER RIEUL-MIEUM",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x313B },
+ unicodeslot=0xFFAB,
+ },
+ [0xFFAC]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER RIEUL-PIEUP",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x313C },
+ unicodeslot=0xFFAC,
+ },
+ [0xFFAD]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER RIEUL-SIOS",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x313D },
+ unicodeslot=0xFFAD,
+ },
+ [0xFFAE]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER RIEUL-THIEUTH",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x313E },
+ unicodeslot=0xFFAE,
+ },
+ [0xFFAF]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x313F },
+ unicodeslot=0xFFAF,
+ },
+ [0xFFB0]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER RIEUL-HIEUH",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3140 },
+ unicodeslot=0xFFB0,
+ },
+ [0xFFB1]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER MIEUM",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3141 },
+ unicodeslot=0xFFB1,
+ },
+ [0xFFB2]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER PIEUP",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3142 },
+ unicodeslot=0xFFB2,
+ },
+ [0xFFB3]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER SSANGPIEUP",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3143 },
+ unicodeslot=0xFFB3,
+ },
+ [0xFFB4]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER PIEUP-SIOS",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3144 },
+ unicodeslot=0xFFB4,
+ },
+ [0xFFB5]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER SIOS",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3145 },
+ unicodeslot=0xFFB5,
+ },
+ [0xFFB6]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER SSANGSIOS",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3146 },
+ unicodeslot=0xFFB6,
+ },
+ [0xFFB7]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER IEUNG",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3147 },
+ unicodeslot=0xFFB7,
+ },
+ [0xFFB8]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER CIEUC",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3148 },
+ unicodeslot=0xFFB8,
+ },
+ [0xFFB9]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER SSANGCIEUC",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3149 },
+ unicodeslot=0xFFB9,
+ },
+ [0xFFBA]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER CHIEUCH",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x314A },
+ unicodeslot=0xFFBA,
+ },
+ [0xFFBB]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER KHIEUKH",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x314B },
+ unicodeslot=0xFFBB,
+ },
+ [0xFFBC]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER THIEUTH",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x314C },
+ unicodeslot=0xFFBC,
+ },
+ [0xFFBD]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER PHIEUPH",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x314D },
+ unicodeslot=0xFFBD,
+ },
+ [0xFFBE]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER HIEUH",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x314E },
+ unicodeslot=0xFFBE,
+ },
+ [0xFFC2]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER A",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x314F },
+ unicodeslot=0xFFC2,
+ },
+ [0xFFC3]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER AE",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3150 },
+ unicodeslot=0xFFC3,
+ },
+ [0xFFC4]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER YA",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3151 },
+ unicodeslot=0xFFC4,
+ },
+ [0xFFC5]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER YAE",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3152 },
+ unicodeslot=0xFFC5,
+ },
+ [0xFFC6]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER EO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3153 },
+ unicodeslot=0xFFC6,
+ },
+ [0xFFC7]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER E",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3154 },
+ unicodeslot=0xFFC7,
+ },
+ [0xFFCA]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER YEO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3155 },
+ unicodeslot=0xFFCA,
+ },
+ [0xFFCB]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER YE",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3156 },
+ unicodeslot=0xFFCB,
+ },
+ [0xFFCC]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER O",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3157 },
+ unicodeslot=0xFFCC,
+ },
+ [0xFFCD]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER WA",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3158 },
+ unicodeslot=0xFFCD,
+ },
+ [0xFFCE]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER WAE",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3159 },
+ unicodeslot=0xFFCE,
+ },
+ [0xFFCF]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER OE",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x315A },
+ unicodeslot=0xFFCF,
+ },
+ [0xFFD2]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER YO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x315B },
+ unicodeslot=0xFFD2,
+ },
+ [0xFFD3]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER U",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x315C },
+ unicodeslot=0xFFD3,
+ },
+ [0xFFD4]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER WEO",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x315D },
+ unicodeslot=0xFFD4,
+ },
+ [0xFFD5]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER WE",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x315E },
+ unicodeslot=0xFFD5,
+ },
+ [0xFFD6]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER WI",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x315F },
+ unicodeslot=0xFFD6,
+ },
+ [0xFFD7]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER YU",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3160 },
+ unicodeslot=0xFFD7,
+ },
+ [0xFFDA]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER EU",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3161 },
+ unicodeslot=0xFFDA,
+ },
+ [0xFFDB]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER YI",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3162 },
+ unicodeslot=0xFFDB,
+ },
+ [0xFFDC]={
+ category="lo",
+ cjkwd="h",
+ description="HALFWIDTH HANGUL LETTER I",
+ direction="l",
+ linebreak="al",
+ specials={ "narrow", 0x3163 },
+ unicodeslot=0xFFDC,
+ },
+ [0xFFE0]={
+ adobename="centmonospace",
+ category="sc",
+ cjkwd="f",
+ description="FULLWIDTH CENT SIGN",
+ direction="et",
+ linebreak="po",
+ specials={ "wide", 0x00A2 },
+ unicodeslot=0xFFE0,
+ },
+ [0xFFE1]={
+ adobename="sterlingmonospace",
+ category="sc",
+ cjkwd="f",
+ description="FULLWIDTH POUND SIGN",
+ direction="et",
+ linebreak="pr",
+ specials={ "wide", 0x00A3 },
+ unicodeslot=0xFFE1,
+ },
+ [0xFFE2]={
+ category="sm",
+ cjkwd="f",
+ description="FULLWIDTH NOT SIGN",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x00AC },
+ unicodeslot=0xFFE2,
+ },
+ [0xFFE3]={
+ adobename="macronmonospace",
+ category="sk",
+ cjkwd="f",
+ description="FULLWIDTH MACRON",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x00AF },
+ unicodeslot=0xFFE3,
+ },
+ [0xFFE4]={
+ category="so",
+ cjkwd="f",
+ description="FULLWIDTH BROKEN BAR",
+ direction="on",
+ linebreak="id",
+ specials={ "wide", 0x00A6 },
+ unicodeslot=0xFFE4,
+ },
+ [0xFFE5]={
+ adobename="yenmonospace",
+ category="sc",
+ cjkwd="f",
+ description="FULLWIDTH YEN SIGN",
+ direction="et",
+ linebreak="pr",
+ specials={ "wide", 0x00A5 },
+ unicodeslot=0xFFE5,
+ },
+ [0xFFE6]={
+ adobename="wonmonospace",
+ category="sc",
+ cjkwd="f",
+ description="FULLWIDTH WON SIGN",
+ direction="et",
+ linebreak="pr",
+ specials={ "wide", 0x20A9 },
+ unicodeslot=0xFFE6,
+ },
+ [0xFFE8]={
+ category="so",
+ cjkwd="h",
+ description="HALFWIDTH FORMS LIGHT VERTICAL",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x2502 },
+ unicodeslot=0xFFE8,
+ },
+ [0xFFE9]={
+ category="sm",
+ cjkwd="h",
+ description="HALFWIDTH LEFTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x2190 },
+ unicodeslot=0xFFE9,
+ },
+ [0xFFEA]={
+ category="sm",
+ cjkwd="h",
+ description="HALFWIDTH UPWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x2191 },
+ unicodeslot=0xFFEA,
+ },
+ [0xFFEB]={
+ category="sm",
+ cjkwd="h",
+ description="HALFWIDTH RIGHTWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x2192 },
+ unicodeslot=0xFFEB,
+ },
+ [0xFFEC]={
+ category="sm",
+ cjkwd="h",
+ description="HALFWIDTH DOWNWARDS ARROW",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x2193 },
+ unicodeslot=0xFFEC,
+ },
+ [0xFFED]={
+ category="so",
+ cjkwd="h",
+ description="HALFWIDTH BLACK SQUARE",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x25A0 },
+ unicodeslot=0xFFED,
+ },
+ [0xFFEE]={
+ category="so",
+ cjkwd="h",
+ description="HALFWIDTH WHITE CIRCLE",
+ direction="on",
+ linebreak="al",
+ specials={ "narrow", 0x25CB },
+ unicodeslot=0xFFEE,
+ },
+ [0xFFF9]={
+ category="cf",
+ description="INTERLINEAR ANNOTATION ANCHOR",
+ direction="on",
+ linebreak="cm",
+ unicodeslot=0xFFF9,
+ visible="yes",
+ },
+ [0xFFFA]={
+ category="cf",
+ description="INTERLINEAR ANNOTATION SEPARATOR",
+ direction="on",
+ linebreak="cm",
+ unicodeslot=0xFFFA,
+ visible="yes",
+ },
+ [0xFFFB]={
+ category="cf",
+ description="INTERLINEAR ANNOTATION TERMINATOR",
+ direction="on",
+ linebreak="cm",
+ unicodeslot=0xFFFB,
+ visible="yes",
+ },
+ [0xFFFC]={
+ category="so",
+ description="OBJECT REPLACEMENT CHARACTER",
+ direction="on",
+ linebreak="cb",
+ unicodeslot=0xFFFC,
+ },
+ [0xFFFD]={
+ category="so",
+ cjkwd="a",
+ description="REPLACEMENT CHARACTER",
+ direction="on",
+ linebreak="ai",
+ unicodeslot=0xFFFD,
+ },
+ [0x10000]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0008 A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10000,
+ },
+ [0x10001]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0026 E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10001,
+ },
+ [0x10002]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x001C I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10002,
+ },
+ [0x10003]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x003D O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10003,
+ },
+ [0x10004]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x000A U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10004,
+ },
+ [0x10005]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0001 DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10005,
+ },
+ [0x10006]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x002D DE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10006,
+ },
+ [0x10007]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0007 DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10007,
+ },
+ [0x10008]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x000E DO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10008,
+ },
+ [0x10009]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0033 DU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10009,
+ },
+ [0x1000A]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0039 JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1000A,
+ },
+ [0x1000B]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x002E JE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1000B,
+ },
+ [0x1000D]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0024 JO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1000D,
+ },
+ [0x1000E]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0041 JU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1000E,
+ },
+ [0x1000F]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x004D KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1000F,
+ },
+ [0x10010]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x002C KE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10010,
+ },
+ [0x10011]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0043 KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10011,
+ },
+ [0x10012]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0046 KO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10012,
+ },
+ [0x10013]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0051 KU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10013,
+ },
+ [0x10014]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0050 MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10014,
+ },
+ [0x10015]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x000D ME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10015,
+ },
+ [0x10016]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0049 MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10016,
+ },
+ [0x10017]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x000F MO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10017,
+ },
+ [0x10018]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0017 MU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10018,
+ },
+ [0x10019]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0006 NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10019,
+ },
+ [0x1001A]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0018 NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1001A,
+ },
+ [0x1001B]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x001E NI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1001B,
+ },
+ [0x1001C]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0034 NO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1001C,
+ },
+ [0x1001D]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0037 NU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1001D,
+ },
+ [0x1001E]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0003 PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1001E,
+ },
+ [0x1001F]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0048 PE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1001F,
+ },
+ [0x10020]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0027 PI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10020,
+ },
+ [0x10021]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x000B PO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10021,
+ },
+ [0x10022]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0032 PU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10022,
+ },
+ [0x10023]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0010 QA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10023,
+ },
+ [0x10024]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x004E QE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10024,
+ },
+ [0x10025]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0015 QI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10025,
+ },
+ [0x10026]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0020 QO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10026,
+ },
+ [0x10028]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x003C RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10028,
+ },
+ [0x10029]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x001B RE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10029,
+ },
+ [0x1002A]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0035 RI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1002A,
+ },
+ [0x1002B]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0002 RO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1002B,
+ },
+ [0x1002C]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x001A RU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1002C,
+ },
+ [0x1002D]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x001F SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1002D,
+ },
+ [0x1002E]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0009 SE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1002E,
+ },
+ [0x1002F]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0029 SI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1002F,
+ },
+ [0x10030]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x000C SO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10030,
+ },
+ [0x10031]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x003A SU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10031,
+ },
+ [0x10032]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x003B TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10032,
+ },
+ [0x10033]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0004 TE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10033,
+ },
+ [0x10034]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0025 TI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10034,
+ },
+ [0x10035]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0005 TO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10035,
+ },
+ [0x10036]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0045 TU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10036,
+ },
+ [0x10037]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0036 WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10037,
+ },
+ [0x10038]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x004B WE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10038,
+ },
+ [0x10039]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0028 WI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10039,
+ },
+ [0x1003A]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x002A WO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1003A,
+ },
+ [0x1003C]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0011 ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1003C,
+ },
+ [0x1003D]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x004A ZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1003D,
+ },
+ [0x1003F]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0014 ZO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1003F,
+ },
+ [0x10040]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0019 A0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10040,
+ },
+ [0x10041]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x002B A0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10041,
+ },
+ [0x10042]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0055 AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10042,
+ },
+ [0x10043]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0047 DWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10043,
+ },
+ [0x10044]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x005A DWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10044,
+ },
+ [0x10045]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0030 NWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10045,
+ },
+ [0x10046]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x001D PU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10046,
+ },
+ [0x10047]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x003E PTE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10047,
+ },
+ [0x10048]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x004C RA0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10048,
+ },
+ [0x10049]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0021 RA0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10049,
+ },
+ [0x1004A]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0044 RO0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1004A,
+ },
+ [0x1004B]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0042 TA0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1004B,
+ },
+ [0x1004C]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x0057 TWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1004C,
+ },
+ [0x1004D]={
+ category="lo",
+ description="LINEAR B SYLLABLE B0x005B TWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1004D,
+ },
+ [0x10050]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x0012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10050,
+ },
+ [0x10051]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x0013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10051,
+ },
+ [0x10052]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x0016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10052,
+ },
+ [0x10053]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x0022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10053,
+ },
+ [0x10054]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x002F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10054,
+ },
+ [0x10055]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x0031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10055,
+ },
+ [0x10056]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x0038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10056,
+ },
+ [0x10057]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x003F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10057,
+ },
+ [0x10058]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x0040",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10058,
+ },
+ [0x10059]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x004F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10059,
+ },
+ [0x1005A]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x0052",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1005A,
+ },
+ [0x1005B]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x0053",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1005B,
+ },
+ [0x1005C]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x0056",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1005C,
+ },
+ [0x1005D]={
+ category="lo",
+ description="LINEAR B SYMBOL B0x0059",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1005D,
+ },
+ [0x10080]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0064 MAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10080,
+ },
+ [0x10081]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0066 WOMAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10081,
+ },
+ [0x10082]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0068 DEER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10082,
+ },
+ [0x10083]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0069 EQUID",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10083,
+ },
+ [0x10084]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0069F MARE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10084,
+ },
+ [0x10085]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0069M STALLION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10085,
+ },
+ [0x10086]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x006AF EWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10086,
+ },
+ [0x10087]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x006AM RAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10087,
+ },
+ [0x10088]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x006BF SHE-GOAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10088,
+ },
+ [0x10089]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x006BM HE-GOAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10089,
+ },
+ [0x1008A]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x006CF SOW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1008A,
+ },
+ [0x1008B]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x006CM BOAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1008B,
+ },
+ [0x1008C]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x006DF COW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1008C,
+ },
+ [0x1008D]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x006DM BULL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1008D,
+ },
+ [0x1008E]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0078 WHEAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1008E,
+ },
+ [0x1008F]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0079 BARLEY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1008F,
+ },
+ [0x10090]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x007A OLIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10090,
+ },
+ [0x10091]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x007B SPICE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10091,
+ },
+ [0x10092]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x007D CYPERUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10092,
+ },
+ [0x10093]={
+ category="lo",
+ description="LINEAR B MONOGRAM B0x007F KAPO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10093,
+ },
+ [0x10094]={
+ category="lo",
+ description="LINEAR B MONOGRAM B0x0080 KANAKO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10094,
+ },
+ [0x10095]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0082 OIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10095,
+ },
+ [0x10096]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0083 WINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10096,
+ },
+ [0x10097]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0084",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10097,
+ },
+ [0x10098]={
+ category="lo",
+ description="LINEAR B MONOGRAM B0x0085 AREPA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10098,
+ },
+ [0x10099]={
+ category="lo",
+ description="LINEAR B MONOGRAM B0x0087 MERI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10099,
+ },
+ [0x1009A]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x008C BRONZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1009A,
+ },
+ [0x1009B]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x008D GOLD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1009B,
+ },
+ [0x1009C]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x008E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1009C,
+ },
+ [0x1009D]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0091 WOOL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1009D,
+ },
+ [0x1009E]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0092",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1009E,
+ },
+ [0x1009F]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0096",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1009F,
+ },
+ [0x100A0]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0097 HORN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A0,
+ },
+ [0x100A1]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0098",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A1,
+ },
+ [0x100A2]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0099",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A2,
+ },
+ [0x100A3]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x009A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A3,
+ },
+ [0x100A4]={
+ category="lo",
+ description="LINEAR B MONOGRAM B0x009C TURO0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A4,
+ },
+ [0x100A5]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x009D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A5,
+ },
+ [0x100A6]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x009E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A6,
+ },
+ [0x100A7]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x009F CLOTH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A7,
+ },
+ [0x100A8]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00A0",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A8,
+ },
+ [0x100A9]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00A1",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100A9,
+ },
+ [0x100AA]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00A2 GARMENT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100AA,
+ },
+ [0x100AB]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00A3 ARMOUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100AB,
+ },
+ [0x100AC]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00A4",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100AC,
+ },
+ [0x100AD]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00A5",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100AD,
+ },
+ [0x100AE]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00A6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100AE,
+ },
+ [0x100AF]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00A7",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100AF,
+ },
+ [0x100B0]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00A8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B0,
+ },
+ [0x100B1]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00A9",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B1,
+ },
+ [0x100B2]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B2,
+ },
+ [0x100B3]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00AB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B3,
+ },
+ [0x100B4]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00AC",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B4,
+ },
+ [0x100B5]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00AD MONTH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B5,
+ },
+ [0x100B6]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00AE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B6,
+ },
+ [0x100B7]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00B0 TREE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B7,
+ },
+ [0x100B8]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00B1",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B8,
+ },
+ [0x100B9]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00B2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100B9,
+ },
+ [0x100BA]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00B3",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100BA,
+ },
+ [0x100BB]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00B4",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100BB,
+ },
+ [0x100BC]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00B5",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100BC,
+ },
+ [0x100BD]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00B6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100BD,
+ },
+ [0x100BE]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00B7",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100BE,
+ },
+ [0x100BF]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00B8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100BF,
+ },
+ [0x100C0]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00B9",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C0,
+ },
+ [0x100C1]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00BD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C1,
+ },
+ [0x100C2]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00BE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C2,
+ },
+ [0x100C3]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00BF HELMET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C3,
+ },
+ [0x100C4]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00DC FOOTSTOOL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C4,
+ },
+ [0x100C5]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00E1 BATHTUB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C5,
+ },
+ [0x100C6]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00E6 SPEAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C6,
+ },
+ [0x100C7]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00E7 ARROW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C7,
+ },
+ [0x100C8]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00E8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C8,
+ },
+ [0x100C9]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00E9 SWORD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100C9,
+ },
+ [0x100CA]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00EA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100CA,
+ },
+ [0x100CB]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00EC",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100CB,
+ },
+ [0x100CC]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00F0 WHEELED CHARIOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100CC,
+ },
+ [0x100CD]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00F1 CHARIOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100CD,
+ },
+ [0x100CE]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00F2 CHARIOT FRAME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100CE,
+ },
+ [0x100CF]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00F3 WHEEL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100CF,
+ },
+ [0x100D0]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00F5",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D0,
+ },
+ [0x100D1]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00F6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D1,
+ },
+ [0x100D2]={
+ category="lo",
+ description="LINEAR B MONOGRAM B0x00F7 DIPTE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D2,
+ },
+ [0x100D3]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00F8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D3,
+ },
+ [0x100D4]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00F9",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D4,
+ },
+ [0x100D5]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00FB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D5,
+ },
+ [0x100D6]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00FC",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D6,
+ },
+ [0x100D7]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00FD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D7,
+ },
+ [0x100D8]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00FE DART",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D8,
+ },
+ [0x100D9]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x00FF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100D9,
+ },
+ [0x100DA]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0100",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100DA,
+ },
+ [0x100DB]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0101",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100DB,
+ },
+ [0x100DC]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0102",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100DC,
+ },
+ [0x100DD]={
+ category="lo",
+ description="LINEAR B IDEOGRAM B0x0103",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100DD,
+ },
+ [0x100DE]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x009B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100DE,
+ },
+ [0x100DF]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00C8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100DF,
+ },
+ [0x100E0]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00C9",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E0,
+ },
+ [0x100E1]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E1,
+ },
+ [0x100E2]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00CB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E2,
+ },
+ [0x100E3]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00CC",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E3,
+ },
+ [0x100E4]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00CD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E4,
+ },
+ [0x100E5]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00CE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E5,
+ },
+ [0x100E6]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00CF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E6,
+ },
+ [0x100E7]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00D0",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E7,
+ },
+ [0x100E8]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00D1",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E8,
+ },
+ [0x100E9]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00D2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100E9,
+ },
+ [0x100EA]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00D3",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100EA,
+ },
+ [0x100EB]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00D4",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100EB,
+ },
+ [0x100EC]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00D5",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100EC,
+ },
+ [0x100ED]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00D6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100ED,
+ },
+ [0x100EE]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00D7",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100EE,
+ },
+ [0x100EF]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00D8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100EF,
+ },
+ [0x100F0]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00D9",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F0,
+ },
+ [0x100F1]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F1,
+ },
+ [0x100F2]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00DB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F2,
+ },
+ [0x100F3]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00DD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F3,
+ },
+ [0x100F4]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00DE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F4,
+ },
+ [0x100F5]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00E2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F5,
+ },
+ [0x100F6]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00E3",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F6,
+ },
+ [0x100F7]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00E4",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F7,
+ },
+ [0x100F8]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00E5",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F8,
+ },
+ [0x100F9]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x00FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100F9,
+ },
+ [0x100FA]={
+ category="lo",
+ description="LINEAR B IDEOGRAM VESSEL B0x0131",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x100FA,
+ },
+ [0x10100]={
+ category="po",
+ description="AEGEAN WORD SEPARATOR LINE",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x10100,
+ },
+ [0x10101]={
+ category="po",
+ description="AEGEAN WORD SEPARATOR DOT",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10101,
+ },
+ [0x10102]={
+ category="so",
+ description="AEGEAN CHECK MARK",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x10102,
+ },
+ [0x10107]={
+ category="no",
+ description="AEGEAN NUMBER ONE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10107,
+ },
+ [0x10108]={
+ category="no",
+ description="AEGEAN NUMBER TWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10108,
+ },
+ [0x10109]={
+ category="no",
+ description="AEGEAN NUMBER THREE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10109,
+ },
+ [0x1010A]={
+ category="no",
+ description="AEGEAN NUMBER FOUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1010A,
+ },
+ [0x1010B]={
+ category="no",
+ description="AEGEAN NUMBER FIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1010B,
+ },
+ [0x1010C]={
+ category="no",
+ description="AEGEAN NUMBER SIX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1010C,
+ },
+ [0x1010D]={
+ category="no",
+ description="AEGEAN NUMBER SEVEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1010D,
+ },
+ [0x1010E]={
+ category="no",
+ description="AEGEAN NUMBER EIGHT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1010E,
+ },
+ [0x1010F]={
+ category="no",
+ description="AEGEAN NUMBER NINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1010F,
+ },
+ [0x10110]={
+ category="no",
+ description="AEGEAN NUMBER TEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10110,
+ },
+ [0x10111]={
+ category="no",
+ description="AEGEAN NUMBER TWENTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10111,
+ },
+ [0x10112]={
+ category="no",
+ description="AEGEAN NUMBER THIRTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10112,
+ },
+ [0x10113]={
+ category="no",
+ description="AEGEAN NUMBER FORTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10113,
+ },
+ [0x10114]={
+ category="no",
+ description="AEGEAN NUMBER FIFTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10114,
+ },
+ [0x10115]={
+ category="no",
+ description="AEGEAN NUMBER SIXTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10115,
+ },
+ [0x10116]={
+ category="no",
+ description="AEGEAN NUMBER SEVENTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10116,
+ },
+ [0x10117]={
+ category="no",
+ description="AEGEAN NUMBER EIGHTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10117,
+ },
+ [0x10118]={
+ category="no",
+ description="AEGEAN NUMBER NINETY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10118,
+ },
+ [0x10119]={
+ category="no",
+ description="AEGEAN NUMBER ONE HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10119,
+ },
+ [0x1011A]={
+ category="no",
+ description="AEGEAN NUMBER TWO HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1011A,
+ },
+ [0x1011B]={
+ category="no",
+ description="AEGEAN NUMBER THREE HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1011B,
+ },
+ [0x1011C]={
+ category="no",
+ description="AEGEAN NUMBER FOUR HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1011C,
+ },
+ [0x1011D]={
+ category="no",
+ description="AEGEAN NUMBER FIVE HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1011D,
+ },
+ [0x1011E]={
+ category="no",
+ description="AEGEAN NUMBER SIX HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1011E,
+ },
+ [0x1011F]={
+ category="no",
+ description="AEGEAN NUMBER SEVEN HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1011F,
+ },
+ [0x10120]={
+ category="no",
+ description="AEGEAN NUMBER EIGHT HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10120,
+ },
+ [0x10121]={
+ category="no",
+ description="AEGEAN NUMBER NINE HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10121,
+ },
+ [0x10122]={
+ category="no",
+ description="AEGEAN NUMBER ONE THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10122,
+ },
+ [0x10123]={
+ category="no",
+ description="AEGEAN NUMBER TWO THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10123,
+ },
+ [0x10124]={
+ category="no",
+ description="AEGEAN NUMBER THREE THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10124,
+ },
+ [0x10125]={
+ category="no",
+ description="AEGEAN NUMBER FOUR THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10125,
+ },
+ [0x10126]={
+ category="no",
+ description="AEGEAN NUMBER FIVE THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10126,
+ },
+ [0x10127]={
+ category="no",
+ description="AEGEAN NUMBER SIX THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10127,
+ },
+ [0x10128]={
+ category="no",
+ description="AEGEAN NUMBER SEVEN THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10128,
+ },
+ [0x10129]={
+ category="no",
+ description="AEGEAN NUMBER EIGHT THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10129,
+ },
+ [0x1012A]={
+ category="no",
+ description="AEGEAN NUMBER NINE THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1012A,
+ },
+ [0x1012B]={
+ category="no",
+ description="AEGEAN NUMBER TEN THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1012B,
+ },
+ [0x1012C]={
+ category="no",
+ description="AEGEAN NUMBER TWENTY THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1012C,
+ },
+ [0x1012D]={
+ category="no",
+ description="AEGEAN NUMBER THIRTY THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1012D,
+ },
+ [0x1012E]={
+ category="no",
+ description="AEGEAN NUMBER FORTY THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1012E,
+ },
+ [0x1012F]={
+ category="no",
+ description="AEGEAN NUMBER FIFTY THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1012F,
+ },
+ [0x10130]={
+ category="no",
+ description="AEGEAN NUMBER SIXTY THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10130,
+ },
+ [0x10131]={
+ category="no",
+ description="AEGEAN NUMBER SEVENTY THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10131,
+ },
+ [0x10132]={
+ category="no",
+ description="AEGEAN NUMBER EIGHTY THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10132,
+ },
+ [0x10133]={
+ category="no",
+ description="AEGEAN NUMBER NINETY THOUSAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10133,
+ },
+ [0x10137]={
+ category="so",
+ description="AEGEAN WEIGHT BASE UNIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10137,
+ },
+ [0x10138]={
+ category="so",
+ description="AEGEAN WEIGHT FIRST SUBUNIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10138,
+ },
+ [0x10139]={
+ category="so",
+ description="AEGEAN WEIGHT SECOND SUBUNIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10139,
+ },
+ [0x1013A]={
+ category="so",
+ description="AEGEAN WEIGHT THIRD SUBUNIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1013A,
+ },
+ [0x1013B]={
+ category="so",
+ description="AEGEAN WEIGHT FOURTH SUBUNIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1013B,
+ },
+ [0x1013C]={
+ category="so",
+ description="AEGEAN DRY MEASURE FIRST SUBUNIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1013C,
+ },
+ [0x1013D]={
+ category="so",
+ description="AEGEAN LIQUID MEASURE FIRST SUBUNIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1013D,
+ },
+ [0x1013E]={
+ category="so",
+ description="AEGEAN MEASURE SECOND SUBUNIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1013E,
+ },
+ [0x1013F]={
+ category="so",
+ description="AEGEAN MEASURE THIRD SUBUNIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1013F,
+ },
+ [0x10140]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC ONE QUARTER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10140,
+ },
+ [0x10141]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC ONE HALF",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10141,
+ },
+ [0x10142]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC ONE DRACHMA",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10142,
+ },
+ [0x10143]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10143,
+ },
+ [0x10144]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIFTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10144,
+ },
+ [0x10145]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIVE HUNDRED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10145,
+ },
+ [0x10146]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIVE THOUSAND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10146,
+ },
+ [0x10147]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIFTY THOUSAND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10147,
+ },
+ [0x10148]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIVE TALENTS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10148,
+ },
+ [0x10149]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC TEN TALENTS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10149,
+ },
+ [0x1014A]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIFTY TALENTS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1014A,
+ },
+ [0x1014B]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC ONE HUNDRED TALENTS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1014B,
+ },
+ [0x1014C]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIVE HUNDRED TALENTS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1014C,
+ },
+ [0x1014D]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC ONE THOUSAND TALENTS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1014D,
+ },
+ [0x1014E]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIVE THOUSAND TALENTS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1014E,
+ },
+ [0x1014F]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIVE STATERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1014F,
+ },
+ [0x10150]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC TEN STATERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10150,
+ },
+ [0x10151]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIFTY STATERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10151,
+ },
+ [0x10152]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC ONE HUNDRED STATERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10152,
+ },
+ [0x10153]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIVE HUNDRED STATERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10153,
+ },
+ [0x10154]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC ONE THOUSAND STATERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10154,
+ },
+ [0x10155]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC TEN THOUSAND STATERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10155,
+ },
+ [0x10156]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC FIFTY THOUSAND STATERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10156,
+ },
+ [0x10157]={
+ category="nl",
+ description="GREEK ACROPHONIC ATTIC TEN MNAS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10157,
+ },
+ [0x10158]={
+ category="nl",
+ description="GREEK ACROPHONIC HERAEUM ONE PLETHRON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10158,
+ },
+ [0x10159]={
+ category="nl",
+ description="GREEK ACROPHONIC THESPIAN ONE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10159,
+ },
+ [0x1015A]={
+ category="nl",
+ description="GREEK ACROPHONIC HERMIONIAN ONE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1015A,
+ },
+ [0x1015B]={
+ category="nl",
+ description="GREEK ACROPHONIC EPIDAUREAN TWO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1015B,
+ },
+ [0x1015C]={
+ category="nl",
+ description="GREEK ACROPHONIC THESPIAN TWO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1015C,
+ },
+ [0x1015D]={
+ category="nl",
+ description="GREEK ACROPHONIC CYRENAIC TWO DRACHMAS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1015D,
+ },
+ [0x1015E]={
+ category="nl",
+ description="GREEK ACROPHONIC EPIDAUREAN TWO DRACHMAS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1015E,
+ },
+ [0x1015F]={
+ category="nl",
+ description="GREEK ACROPHONIC TROEZENIAN FIVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1015F,
+ },
+ [0x10160]={
+ category="nl",
+ description="GREEK ACROPHONIC TROEZENIAN TEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10160,
+ },
+ [0x10161]={
+ category="nl",
+ description="GREEK ACROPHONIC TROEZENIAN TEN ALTERNATE FORM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10161,
+ },
+ [0x10162]={
+ category="nl",
+ description="GREEK ACROPHONIC HERMIONIAN TEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10162,
+ },
+ [0x10163]={
+ category="nl",
+ description="GREEK ACROPHONIC MESSENIAN TEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10163,
+ },
+ [0x10164]={
+ category="nl",
+ description="GREEK ACROPHONIC THESPIAN TEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10164,
+ },
+ [0x10165]={
+ category="nl",
+ description="GREEK ACROPHONIC THESPIAN THIRTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10165,
+ },
+ [0x10166]={
+ category="nl",
+ description="GREEK ACROPHONIC TROEZENIAN FIFTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10166,
+ },
+ [0x10167]={
+ category="nl",
+ description="GREEK ACROPHONIC TROEZENIAN FIFTY ALTERNATE FORM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10167,
+ },
+ [0x10168]={
+ category="nl",
+ description="GREEK ACROPHONIC HERMIONIAN FIFTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10168,
+ },
+ [0x10169]={
+ category="nl",
+ description="GREEK ACROPHONIC THESPIAN FIFTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10169,
+ },
+ [0x1016A]={
+ category="nl",
+ description="GREEK ACROPHONIC THESPIAN ONE HUNDRED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1016A,
+ },
+ [0x1016B]={
+ category="nl",
+ description="GREEK ACROPHONIC THESPIAN THREE HUNDRED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1016B,
+ },
+ [0x1016C]={
+ category="nl",
+ description="GREEK ACROPHONIC EPIDAUREAN FIVE HUNDRED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1016C,
+ },
+ [0x1016D]={
+ category="nl",
+ description="GREEK ACROPHONIC TROEZENIAN FIVE HUNDRED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1016D,
+ },
+ [0x1016E]={
+ category="nl",
+ description="GREEK ACROPHONIC THESPIAN FIVE HUNDRED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1016E,
+ },
+ [0x1016F]={
+ category="nl",
+ description="GREEK ACROPHONIC CARYSTIAN FIVE HUNDRED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1016F,
+ },
+ [0x10170]={
+ category="nl",
+ description="GREEK ACROPHONIC NAXIAN FIVE HUNDRED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10170,
+ },
+ [0x10171]={
+ category="nl",
+ description="GREEK ACROPHONIC THESPIAN ONE THOUSAND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10171,
+ },
+ [0x10172]={
+ category="nl",
+ description="GREEK ACROPHONIC THESPIAN FIVE THOUSAND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10172,
+ },
+ [0x10173]={
+ category="nl",
+ description="GREEK ACROPHONIC DELPHIC FIVE MNAS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10173,
+ },
+ [0x10174]={
+ category="nl",
+ description="GREEK ACROPHONIC STRATIAN FIFTY MNAS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10174,
+ },
+ [0x10175]={
+ category="no",
+ description="GREEK ONE HALF SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10175,
+ },
+ [0x10176]={
+ category="no",
+ description="GREEK ONE HALF SIGN ALTERNATE FORM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10176,
+ },
+ [0x10177]={
+ category="no",
+ description="GREEK TWO THIRDS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10177,
+ },
+ [0x10178]={
+ category="no",
+ description="GREEK THREE QUARTERS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10178,
+ },
+ [0x10179]={
+ category="so",
+ description="GREEK YEAR SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10179,
+ },
+ [0x1017A]={
+ category="so",
+ description="GREEK TALENT SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1017A,
+ },
+ [0x1017B]={
+ category="so",
+ description="GREEK DRACHMA SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1017B,
+ },
+ [0x1017C]={
+ category="so",
+ description="GREEK OBOL SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1017C,
+ },
+ [0x1017D]={
+ category="so",
+ description="GREEK TWO OBOLS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1017D,
+ },
+ [0x1017E]={
+ category="so",
+ description="GREEK THREE OBOLS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1017E,
+ },
+ [0x1017F]={
+ category="so",
+ description="GREEK FOUR OBOLS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1017F,
+ },
+ [0x10180]={
+ category="so",
+ description="GREEK FIVE OBOLS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10180,
+ },
+ [0x10181]={
+ category="so",
+ description="GREEK METRETES SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10181,
+ },
+ [0x10182]={
+ category="so",
+ description="GREEK KYATHOS BASE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10182,
+ },
+ [0x10183]={
+ category="so",
+ description="GREEK LITRA SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10183,
+ },
+ [0x10184]={
+ category="so",
+ description="GREEK OUNKIA SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10184,
+ },
+ [0x10185]={
+ category="so",
+ description="GREEK XESTES SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10185,
+ },
+ [0x10186]={
+ category="so",
+ description="GREEK ARTABE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10186,
+ },
+ [0x10187]={
+ category="so",
+ description="GREEK AROURA SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10187,
+ },
+ [0x10188]={
+ category="so",
+ description="GREEK GRAMMA SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10188,
+ },
+ [0x10189]={
+ category="so",
+ description="GREEK TRYBLION BASE SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10189,
+ },
+ [0x1018A]={
+ category="no",
+ description="GREEK ZERO SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1018A,
+ },
+ [0x10190]={
+ category="so",
+ description="ROMAN SEXTANS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10190,
+ },
+ [0x10191]={
+ category="so",
+ description="ROMAN UNCIA SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10191,
+ },
+ [0x10192]={
+ category="so",
+ description="ROMAN SEMUNCIA SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10192,
+ },
+ [0x10193]={
+ category="so",
+ description="ROMAN SEXTULA SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10193,
+ },
+ [0x10194]={
+ category="so",
+ description="ROMAN DIMIDIA SEXTULA SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10194,
+ },
+ [0x10195]={
+ category="so",
+ description="ROMAN SILIQUA SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10195,
+ },
+ [0x10196]={
+ category="so",
+ description="ROMAN DENARIUS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10196,
+ },
+ [0x10197]={
+ category="so",
+ description="ROMAN QUINARIUS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10197,
+ },
+ [0x10198]={
+ category="so",
+ description="ROMAN SESTERTIUS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10198,
+ },
+ [0x10199]={
+ category="so",
+ description="ROMAN DUPONDIUS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x10199,
+ },
+ [0x1019A]={
+ category="so",
+ description="ROMAN AS SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1019A,
+ },
+ [0x1019B]={
+ category="so",
+ description="ROMAN CENTURIAL SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1019B,
+ },
+ [0x101D0]={
+ category="so",
+ description="PHAISTOS DISC SIGN PEDESTRIAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D0,
+ },
+ [0x101D1]={
+ category="so",
+ description="PHAISTOS DISC SIGN PLUMED HEAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D1,
+ },
+ [0x101D2]={
+ category="so",
+ description="PHAISTOS DISC SIGN TATTOOED HEAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D2,
+ },
+ [0x101D3]={
+ category="so",
+ description="PHAISTOS DISC SIGN CAPTIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D3,
+ },
+ [0x101D4]={
+ category="so",
+ description="PHAISTOS DISC SIGN CHILD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D4,
+ },
+ [0x101D5]={
+ category="so",
+ description="PHAISTOS DISC SIGN WOMAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D5,
+ },
+ [0x101D6]={
+ category="so",
+ description="PHAISTOS DISC SIGN HELMET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D6,
+ },
+ [0x101D7]={
+ category="so",
+ description="PHAISTOS DISC SIGN GAUNTLET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D7,
+ },
+ [0x101D8]={
+ category="so",
+ description="PHAISTOS DISC SIGN TIARA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D8,
+ },
+ [0x101D9]={
+ category="so",
+ description="PHAISTOS DISC SIGN ARROW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101D9,
+ },
+ [0x101DA]={
+ category="so",
+ description="PHAISTOS DISC SIGN BOW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101DA,
+ },
+ [0x101DB]={
+ category="so",
+ description="PHAISTOS DISC SIGN SHIELD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101DB,
+ },
+ [0x101DC]={
+ category="so",
+ description="PHAISTOS DISC SIGN CLUB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101DC,
+ },
+ [0x101DD]={
+ category="so",
+ description="PHAISTOS DISC SIGN MANACLES",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101DD,
+ },
+ [0x101DE]={
+ category="so",
+ description="PHAISTOS DISC SIGN MATTOCK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101DE,
+ },
+ [0x101DF]={
+ category="so",
+ description="PHAISTOS DISC SIGN SAW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101DF,
+ },
+ [0x101E0]={
+ category="so",
+ description="PHAISTOS DISC SIGN LID",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E0,
+ },
+ [0x101E1]={
+ category="so",
+ description="PHAISTOS DISC SIGN BOOMERANG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E1,
+ },
+ [0x101E2]={
+ category="so",
+ description="PHAISTOS DISC SIGN CARPENTRY PLANE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E2,
+ },
+ [0x101E3]={
+ category="so",
+ description="PHAISTOS DISC SIGN DOLIUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E3,
+ },
+ [0x101E4]={
+ category="so",
+ description="PHAISTOS DISC SIGN COMB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E4,
+ },
+ [0x101E5]={
+ category="so",
+ description="PHAISTOS DISC SIGN SLING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E5,
+ },
+ [0x101E6]={
+ category="so",
+ description="PHAISTOS DISC SIGN COLUMN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E6,
+ },
+ [0x101E7]={
+ category="so",
+ description="PHAISTOS DISC SIGN BEEHIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E7,
+ },
+ [0x101E8]={
+ category="so",
+ description="PHAISTOS DISC SIGN SHIP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E8,
+ },
+ [0x101E9]={
+ category="so",
+ description="PHAISTOS DISC SIGN HORN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101E9,
+ },
+ [0x101EA]={
+ category="so",
+ description="PHAISTOS DISC SIGN HIDE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101EA,
+ },
+ [0x101EB]={
+ category="so",
+ description="PHAISTOS DISC SIGN BULLS LEG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101EB,
+ },
+ [0x101EC]={
+ category="so",
+ description="PHAISTOS DISC SIGN CAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101EC,
+ },
+ [0x101ED]={
+ category="so",
+ description="PHAISTOS DISC SIGN RAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101ED,
+ },
+ [0x101EE]={
+ category="so",
+ description="PHAISTOS DISC SIGN EAGLE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101EE,
+ },
+ [0x101EF]={
+ category="so",
+ description="PHAISTOS DISC SIGN DOVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101EF,
+ },
+ [0x101F0]={
+ category="so",
+ description="PHAISTOS DISC SIGN TUNNY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F0,
+ },
+ [0x101F1]={
+ category="so",
+ description="PHAISTOS DISC SIGN BEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F1,
+ },
+ [0x101F2]={
+ category="so",
+ description="PHAISTOS DISC SIGN PLANE TREE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F2,
+ },
+ [0x101F3]={
+ category="so",
+ description="PHAISTOS DISC SIGN VINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F3,
+ },
+ [0x101F4]={
+ category="so",
+ description="PHAISTOS DISC SIGN PAPYRUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F4,
+ },
+ [0x101F5]={
+ category="so",
+ description="PHAISTOS DISC SIGN ROSETTE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F5,
+ },
+ [0x101F6]={
+ category="so",
+ description="PHAISTOS DISC SIGN LILY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F6,
+ },
+ [0x101F7]={
+ category="so",
+ description="PHAISTOS DISC SIGN OX BACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F7,
+ },
+ [0x101F8]={
+ category="so",
+ description="PHAISTOS DISC SIGN FLUTE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F8,
+ },
+ [0x101F9]={
+ category="so",
+ description="PHAISTOS DISC SIGN GRATER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101F9,
+ },
+ [0x101FA]={
+ category="so",
+ description="PHAISTOS DISC SIGN STRAINER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101FA,
+ },
+ [0x101FB]={
+ category="so",
+ description="PHAISTOS DISC SIGN SMALL AXE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101FB,
+ },
+ [0x101FC]={
+ category="so",
+ description="PHAISTOS DISC SIGN WAVY BAND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x101FC,
+ },
+ [0x101FD]={
+ category="mn",
+ description="PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x101FD,
+ },
+ [0x10280]={
+ category="lo",
+ description="LYCIAN LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10280,
+ },
+ [0x10281]={
+ category="lo",
+ description="LYCIAN LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10281,
+ },
+ [0x10282]={
+ category="lo",
+ description="LYCIAN LETTER B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10282,
+ },
+ [0x10283]={
+ category="lo",
+ description="LYCIAN LETTER BH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10283,
+ },
+ [0x10284]={
+ category="lo",
+ description="LYCIAN LETTER G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10284,
+ },
+ [0x10285]={
+ category="lo",
+ description="LYCIAN LETTER D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10285,
+ },
+ [0x10286]={
+ category="lo",
+ description="LYCIAN LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10286,
+ },
+ [0x10287]={
+ category="lo",
+ description="LYCIAN LETTER W",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10287,
+ },
+ [0x10288]={
+ category="lo",
+ description="LYCIAN LETTER Z",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10288,
+ },
+ [0x10289]={
+ category="lo",
+ description="LYCIAN LETTER TH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10289,
+ },
+ [0x1028A]={
+ category="lo",
+ description="LYCIAN LETTER J",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1028A,
+ },
+ [0x1028B]={
+ category="lo",
+ description="LYCIAN LETTER K",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1028B,
+ },
+ [0x1028C]={
+ category="lo",
+ description="LYCIAN LETTER Q",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1028C,
+ },
+ [0x1028D]={
+ category="lo",
+ description="LYCIAN LETTER L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1028D,
+ },
+ [0x1028E]={
+ category="lo",
+ description="LYCIAN LETTER M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1028E,
+ },
+ [0x1028F]={
+ category="lo",
+ description="LYCIAN LETTER N",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1028F,
+ },
+ [0x10290]={
+ category="lo",
+ description="LYCIAN LETTER MM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10290,
+ },
+ [0x10291]={
+ category="lo",
+ description="LYCIAN LETTER NN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10291,
+ },
+ [0x10292]={
+ category="lo",
+ description="LYCIAN LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10292,
+ },
+ [0x10293]={
+ category="lo",
+ description="LYCIAN LETTER P",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10293,
+ },
+ [0x10294]={
+ category="lo",
+ description="LYCIAN LETTER KK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10294,
+ },
+ [0x10295]={
+ category="lo",
+ description="LYCIAN LETTER R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10295,
+ },
+ [0x10296]={
+ category="lo",
+ description="LYCIAN LETTER S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10296,
+ },
+ [0x10297]={
+ category="lo",
+ description="LYCIAN LETTER T",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10297,
+ },
+ [0x10298]={
+ category="lo",
+ description="LYCIAN LETTER TT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10298,
+ },
+ [0x10299]={
+ category="lo",
+ description="LYCIAN LETTER AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10299,
+ },
+ [0x1029A]={
+ category="lo",
+ description="LYCIAN LETTER EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1029A,
+ },
+ [0x1029B]={
+ category="lo",
+ description="LYCIAN LETTER H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1029B,
+ },
+ [0x1029C]={
+ category="lo",
+ description="LYCIAN LETTER X",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1029C,
+ },
+ [0x102A0]={
+ category="lo",
+ description="CARIAN LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A0,
+ },
+ [0x102A1]={
+ category="lo",
+ description="CARIAN LETTER P2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A1,
+ },
+ [0x102A2]={
+ category="lo",
+ description="CARIAN LETTER D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A2,
+ },
+ [0x102A3]={
+ category="lo",
+ description="CARIAN LETTER L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A3,
+ },
+ [0x102A4]={
+ category="lo",
+ description="CARIAN LETTER UUU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A4,
+ },
+ [0x102A5]={
+ category="lo",
+ description="CARIAN LETTER R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A5,
+ },
+ [0x102A6]={
+ category="lo",
+ description="CARIAN LETTER LD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A6,
+ },
+ [0x102A7]={
+ category="lo",
+ description="CARIAN LETTER A2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A7,
+ },
+ [0x102A8]={
+ category="lo",
+ description="CARIAN LETTER Q",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A8,
+ },
+ [0x102A9]={
+ category="lo",
+ description="CARIAN LETTER B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102A9,
+ },
+ [0x102AA]={
+ category="lo",
+ description="CARIAN LETTER M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102AA,
+ },
+ [0x102AB]={
+ category="lo",
+ description="CARIAN LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102AB,
+ },
+ [0x102AC]={
+ category="lo",
+ description="CARIAN LETTER D2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102AC,
+ },
+ [0x102AD]={
+ category="lo",
+ description="CARIAN LETTER T",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102AD,
+ },
+ [0x102AE]={
+ category="lo",
+ description="CARIAN LETTER SH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102AE,
+ },
+ [0x102AF]={
+ category="lo",
+ description="CARIAN LETTER SH2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102AF,
+ },
+ [0x102B0]={
+ category="lo",
+ description="CARIAN LETTER S",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B0,
+ },
+ [0x102B1]={
+ category="lo",
+ description="CARIAN LETTER C-18",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B1,
+ },
+ [0x102B2]={
+ category="lo",
+ description="CARIAN LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B2,
+ },
+ [0x102B3]={
+ category="lo",
+ description="CARIAN LETTER NN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B3,
+ },
+ [0x102B4]={
+ category="lo",
+ description="CARIAN LETTER X",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B4,
+ },
+ [0x102B5]={
+ category="lo",
+ description="CARIAN LETTER N",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B5,
+ },
+ [0x102B6]={
+ category="lo",
+ description="CARIAN LETTER TT2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B6,
+ },
+ [0x102B7]={
+ category="lo",
+ description="CARIAN LETTER P",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B7,
+ },
+ [0x102B8]={
+ category="lo",
+ description="CARIAN LETTER SS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B8,
+ },
+ [0x102B9]={
+ category="lo",
+ description="CARIAN LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102B9,
+ },
+ [0x102BA]={
+ category="lo",
+ description="CARIAN LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102BA,
+ },
+ [0x102BB]={
+ category="lo",
+ description="CARIAN LETTER UUUU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102BB,
+ },
+ [0x102BC]={
+ category="lo",
+ description="CARIAN LETTER K",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102BC,
+ },
+ [0x102BD]={
+ category="lo",
+ description="CARIAN LETTER K2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102BD,
+ },
+ [0x102BE]={
+ category="lo",
+ description="CARIAN LETTER ND",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102BE,
+ },
+ [0x102BF]={
+ category="lo",
+ description="CARIAN LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102BF,
+ },
+ [0x102C0]={
+ category="lo",
+ description="CARIAN LETTER G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C0,
+ },
+ [0x102C1]={
+ category="lo",
+ description="CARIAN LETTER G2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C1,
+ },
+ [0x102C2]={
+ category="lo",
+ description="CARIAN LETTER ST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C2,
+ },
+ [0x102C3]={
+ category="lo",
+ description="CARIAN LETTER ST2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C3,
+ },
+ [0x102C4]={
+ category="lo",
+ description="CARIAN LETTER NG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C4,
+ },
+ [0x102C5]={
+ category="lo",
+ description="CARIAN LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C5,
+ },
+ [0x102C6]={
+ category="lo",
+ description="CARIAN LETTER C-39",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C6,
+ },
+ [0x102C7]={
+ category="lo",
+ description="CARIAN LETTER TT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C7,
+ },
+ [0x102C8]={
+ category="lo",
+ description="CARIAN LETTER UUU2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C8,
+ },
+ [0x102C9]={
+ category="lo",
+ description="CARIAN LETTER RR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102C9,
+ },
+ [0x102CA]={
+ category="lo",
+ description="CARIAN LETTER MB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102CA,
+ },
+ [0x102CB]={
+ category="lo",
+ description="CARIAN LETTER MB2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102CB,
+ },
+ [0x102CC]={
+ category="lo",
+ description="CARIAN LETTER MB3",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102CC,
+ },
+ [0x102CD]={
+ category="lo",
+ description="CARIAN LETTER MB4",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102CD,
+ },
+ [0x102CE]={
+ category="lo",
+ description="CARIAN LETTER LD2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102CE,
+ },
+ [0x102CF]={
+ category="lo",
+ description="CARIAN LETTER E2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102CF,
+ },
+ [0x102D0]={
+ category="lo",
+ description="CARIAN LETTER UUU3",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x102D0,
+ },
+ [0x10300]={
+ category="lo",
+ description="OLD ITALIC LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10300,
+ },
+ [0x10301]={
+ category="lo",
+ description="OLD ITALIC LETTER BE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10301,
+ },
+ [0x10302]={
+ category="lo",
+ description="OLD ITALIC LETTER KE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10302,
+ },
+ [0x10303]={
+ category="lo",
+ description="OLD ITALIC LETTER DE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10303,
+ },
+ [0x10304]={
+ category="lo",
+ description="OLD ITALIC LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10304,
+ },
+ [0x10305]={
+ category="lo",
+ description="OLD ITALIC LETTER VE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10305,
+ },
+ [0x10306]={
+ category="lo",
+ description="OLD ITALIC LETTER ZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10306,
+ },
+ [0x10307]={
+ category="lo",
+ description="OLD ITALIC LETTER HE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10307,
+ },
+ [0x10308]={
+ category="lo",
+ description="OLD ITALIC LETTER THE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10308,
+ },
+ [0x10309]={
+ category="lo",
+ description="OLD ITALIC LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10309,
+ },
+ [0x1030A]={
+ category="lo",
+ description="OLD ITALIC LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1030A,
+ },
+ [0x1030B]={
+ category="lo",
+ description="OLD ITALIC LETTER EL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1030B,
+ },
+ [0x1030C]={
+ category="lo",
+ description="OLD ITALIC LETTER EM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1030C,
+ },
+ [0x1030D]={
+ category="lo",
+ description="OLD ITALIC LETTER EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1030D,
+ },
+ [0x1030E]={
+ category="lo",
+ description="OLD ITALIC LETTER ESH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1030E,
+ },
+ [0x1030F]={
+ category="lo",
+ description="OLD ITALIC LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1030F,
+ },
+ [0x10310]={
+ category="lo",
+ description="OLD ITALIC LETTER PE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10310,
+ },
+ [0x10311]={
+ category="lo",
+ description="OLD ITALIC LETTER SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10311,
+ },
+ [0x10312]={
+ category="lo",
+ description="OLD ITALIC LETTER KU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10312,
+ },
+ [0x10313]={
+ category="lo",
+ description="OLD ITALIC LETTER ER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10313,
+ },
+ [0x10314]={
+ category="lo",
+ description="OLD ITALIC LETTER ES",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10314,
+ },
+ [0x10315]={
+ category="lo",
+ description="OLD ITALIC LETTER TE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10315,
+ },
+ [0x10316]={
+ category="lo",
+ description="OLD ITALIC LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10316,
+ },
+ [0x10317]={
+ category="lo",
+ description="OLD ITALIC LETTER EKS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10317,
+ },
+ [0x10318]={
+ category="lo",
+ description="OLD ITALIC LETTER PHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10318,
+ },
+ [0x10319]={
+ category="lo",
+ description="OLD ITALIC LETTER KHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10319,
+ },
+ [0x1031A]={
+ category="lo",
+ description="OLD ITALIC LETTER EF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1031A,
+ },
+ [0x1031B]={
+ category="lo",
+ description="OLD ITALIC LETTER ERS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1031B,
+ },
+ [0x1031C]={
+ category="lo",
+ description="OLD ITALIC LETTER CHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1031C,
+ },
+ [0x1031D]={
+ category="lo",
+ description="OLD ITALIC LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1031D,
+ },
+ [0x1031E]={
+ category="lo",
+ description="OLD ITALIC LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1031E,
+ },
+ [0x10320]={
+ category="no",
+ description="OLD ITALIC NUMERAL ONE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10320,
+ },
+ [0x10321]={
+ category="no",
+ description="OLD ITALIC NUMERAL FIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10321,
+ },
+ [0x10322]={
+ category="no",
+ description="OLD ITALIC NUMERAL TEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10322,
+ },
+ [0x10323]={
+ category="no",
+ description="OLD ITALIC NUMERAL FIFTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10323,
+ },
+ [0x10330]={
+ category="lo",
+ description="GOTHIC LETTER AHSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10330,
+ },
+ [0x10331]={
+ category="lo",
+ description="GOTHIC LETTER BAIRKAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10331,
+ },
+ [0x10332]={
+ category="lo",
+ description="GOTHIC LETTER GIBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10332,
+ },
+ [0x10333]={
+ category="lo",
+ description="GOTHIC LETTER DAGS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10333,
+ },
+ [0x10334]={
+ category="lo",
+ description="GOTHIC LETTER AIHVUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10334,
+ },
+ [0x10335]={
+ category="lo",
+ description="GOTHIC LETTER QAIRTHRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10335,
+ },
+ [0x10336]={
+ category="lo",
+ description="GOTHIC LETTER IUJA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10336,
+ },
+ [0x10337]={
+ category="lo",
+ description="GOTHIC LETTER HAGL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10337,
+ },
+ [0x10338]={
+ category="lo",
+ description="GOTHIC LETTER THIUTH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10338,
+ },
+ [0x10339]={
+ category="lo",
+ description="GOTHIC LETTER EIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10339,
+ },
+ [0x1033A]={
+ category="lo",
+ description="GOTHIC LETTER KUSMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1033A,
+ },
+ [0x1033B]={
+ category="lo",
+ description="GOTHIC LETTER LAGUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1033B,
+ },
+ [0x1033C]={
+ category="lo",
+ description="GOTHIC LETTER MANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1033C,
+ },
+ [0x1033D]={
+ category="lo",
+ description="GOTHIC LETTER NAUTHS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1033D,
+ },
+ [0x1033E]={
+ category="lo",
+ description="GOTHIC LETTER JER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1033E,
+ },
+ [0x1033F]={
+ category="lo",
+ description="GOTHIC LETTER URUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1033F,
+ },
+ [0x10340]={
+ category="lo",
+ description="GOTHIC LETTER PAIRTHRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10340,
+ },
+ [0x10341]={
+ category="nl",
+ description="GOTHIC LETTER NINETY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10341,
+ },
+ [0x10342]={
+ category="lo",
+ description="GOTHIC LETTER RAIDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10342,
+ },
+ [0x10343]={
+ category="lo",
+ description="GOTHIC LETTER SAUIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10343,
+ },
+ [0x10344]={
+ category="lo",
+ description="GOTHIC LETTER TEIWS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10344,
+ },
+ [0x10345]={
+ category="lo",
+ description="GOTHIC LETTER WINJA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10345,
+ },
+ [0x10346]={
+ category="lo",
+ description="GOTHIC LETTER FAIHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10346,
+ },
+ [0x10347]={
+ category="lo",
+ description="GOTHIC LETTER IGGWS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10347,
+ },
+ [0x10348]={
+ category="lo",
+ description="GOTHIC LETTER HWAIR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10348,
+ },
+ [0x10349]={
+ category="lo",
+ description="GOTHIC LETTER OTHAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10349,
+ },
+ [0x1034A]={
+ category="nl",
+ description="GOTHIC LETTER NINE HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1034A,
+ },
+ [0x10380]={
+ category="lo",
+ description="UGARITIC LETTER ALPA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10380,
+ },
+ [0x10381]={
+ category="lo",
+ description="UGARITIC LETTER BETA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10381,
+ },
+ [0x10382]={
+ category="lo",
+ description="UGARITIC LETTER GAMLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10382,
+ },
+ [0x10383]={
+ category="lo",
+ description="UGARITIC LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10383,
+ },
+ [0x10384]={
+ category="lo",
+ description="UGARITIC LETTER DELTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10384,
+ },
+ [0x10385]={
+ category="lo",
+ description="UGARITIC LETTER HO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10385,
+ },
+ [0x10386]={
+ category="lo",
+ description="UGARITIC LETTER WO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10386,
+ },
+ [0x10387]={
+ category="lo",
+ description="UGARITIC LETTER ZETA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10387,
+ },
+ [0x10388]={
+ category="lo",
+ description="UGARITIC LETTER HOTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10388,
+ },
+ [0x10389]={
+ category="lo",
+ description="UGARITIC LETTER TET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10389,
+ },
+ [0x1038A]={
+ category="lo",
+ description="UGARITIC LETTER YOD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1038A,
+ },
+ [0x1038B]={
+ category="lo",
+ description="UGARITIC LETTER KAF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1038B,
+ },
+ [0x1038C]={
+ category="lo",
+ description="UGARITIC LETTER SHIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1038C,
+ },
+ [0x1038D]={
+ category="lo",
+ description="UGARITIC LETTER LAMDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1038D,
+ },
+ [0x1038E]={
+ category="lo",
+ description="UGARITIC LETTER MEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1038E,
+ },
+ [0x1038F]={
+ category="lo",
+ description="UGARITIC LETTER DHAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1038F,
+ },
+ [0x10390]={
+ category="lo",
+ description="UGARITIC LETTER NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10390,
+ },
+ [0x10391]={
+ category="lo",
+ description="UGARITIC LETTER ZU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10391,
+ },
+ [0x10392]={
+ category="lo",
+ description="UGARITIC LETTER SAMKA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10392,
+ },
+ [0x10393]={
+ category="lo",
+ description="UGARITIC LETTER AIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10393,
+ },
+ [0x10394]={
+ category="lo",
+ description="UGARITIC LETTER PU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10394,
+ },
+ [0x10395]={
+ category="lo",
+ description="UGARITIC LETTER SADE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10395,
+ },
+ [0x10396]={
+ category="lo",
+ description="UGARITIC LETTER QOPA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10396,
+ },
+ [0x10397]={
+ category="lo",
+ description="UGARITIC LETTER RASHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10397,
+ },
+ [0x10398]={
+ category="lo",
+ description="UGARITIC LETTER THANNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10398,
+ },
+ [0x10399]={
+ category="lo",
+ description="UGARITIC LETTER GHAIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10399,
+ },
+ [0x1039A]={
+ category="lo",
+ description="UGARITIC LETTER TO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1039A,
+ },
+ [0x1039B]={
+ category="lo",
+ description="UGARITIC LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1039B,
+ },
+ [0x1039C]={
+ category="lo",
+ description="UGARITIC LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1039C,
+ },
+ [0x1039D]={
+ category="lo",
+ description="UGARITIC LETTER SSU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1039D,
+ },
+ [0x1039F]={
+ category="po",
+ description="UGARITIC WORD DIVIDER",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1039F,
+ },
+ [0x103A0]={
+ category="lo",
+ description="OLD PERSIAN SIGN A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A0,
+ },
+ [0x103A1]={
+ category="lo",
+ description="OLD PERSIAN SIGN I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A1,
+ },
+ [0x103A2]={
+ category="lo",
+ description="OLD PERSIAN SIGN U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A2,
+ },
+ [0x103A3]={
+ category="lo",
+ description="OLD PERSIAN SIGN KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A3,
+ },
+ [0x103A4]={
+ category="lo",
+ description="OLD PERSIAN SIGN KU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A4,
+ },
+ [0x103A5]={
+ category="lo",
+ description="OLD PERSIAN SIGN GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A5,
+ },
+ [0x103A6]={
+ category="lo",
+ description="OLD PERSIAN SIGN GU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A6,
+ },
+ [0x103A7]={
+ category="lo",
+ description="OLD PERSIAN SIGN XA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A7,
+ },
+ [0x103A8]={
+ category="lo",
+ description="OLD PERSIAN SIGN CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A8,
+ },
+ [0x103A9]={
+ category="lo",
+ description="OLD PERSIAN SIGN JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103A9,
+ },
+ [0x103AA]={
+ category="lo",
+ description="OLD PERSIAN SIGN JI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103AA,
+ },
+ [0x103AB]={
+ category="lo",
+ description="OLD PERSIAN SIGN TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103AB,
+ },
+ [0x103AC]={
+ category="lo",
+ description="OLD PERSIAN SIGN TU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103AC,
+ },
+ [0x103AD]={
+ category="lo",
+ description="OLD PERSIAN SIGN DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103AD,
+ },
+ [0x103AE]={
+ category="lo",
+ description="OLD PERSIAN SIGN DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103AE,
+ },
+ [0x103AF]={
+ category="lo",
+ description="OLD PERSIAN SIGN DU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103AF,
+ },
+ [0x103B0]={
+ category="lo",
+ description="OLD PERSIAN SIGN THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B0,
+ },
+ [0x103B1]={
+ category="lo",
+ description="OLD PERSIAN SIGN PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B1,
+ },
+ [0x103B2]={
+ category="lo",
+ description="OLD PERSIAN SIGN BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B2,
+ },
+ [0x103B3]={
+ category="lo",
+ description="OLD PERSIAN SIGN FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B3,
+ },
+ [0x103B4]={
+ category="lo",
+ description="OLD PERSIAN SIGN NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B4,
+ },
+ [0x103B5]={
+ category="lo",
+ description="OLD PERSIAN SIGN NU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B5,
+ },
+ [0x103B6]={
+ category="lo",
+ description="OLD PERSIAN SIGN MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B6,
+ },
+ [0x103B7]={
+ category="lo",
+ description="OLD PERSIAN SIGN MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B7,
+ },
+ [0x103B8]={
+ category="lo",
+ description="OLD PERSIAN SIGN MU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B8,
+ },
+ [0x103B9]={
+ category="lo",
+ description="OLD PERSIAN SIGN YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103B9,
+ },
+ [0x103BA]={
+ category="lo",
+ description="OLD PERSIAN SIGN VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103BA,
+ },
+ [0x103BB]={
+ category="lo",
+ description="OLD PERSIAN SIGN VI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103BB,
+ },
+ [0x103BC]={
+ category="lo",
+ description="OLD PERSIAN SIGN RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103BC,
+ },
+ [0x103BD]={
+ category="lo",
+ description="OLD PERSIAN SIGN RU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103BD,
+ },
+ [0x103BE]={
+ category="lo",
+ description="OLD PERSIAN SIGN LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103BE,
+ },
+ [0x103BF]={
+ category="lo",
+ description="OLD PERSIAN SIGN SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103BF,
+ },
+ [0x103C0]={
+ category="lo",
+ description="OLD PERSIAN SIGN ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103C0,
+ },
+ [0x103C1]={
+ category="lo",
+ description="OLD PERSIAN SIGN SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103C1,
+ },
+ [0x103C2]={
+ category="lo",
+ description="OLD PERSIAN SIGN SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103C2,
+ },
+ [0x103C3]={
+ category="lo",
+ description="OLD PERSIAN SIGN HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103C3,
+ },
+ [0x103C8]={
+ category="lo",
+ description="OLD PERSIAN SIGN AURAMAZDAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103C8,
+ },
+ [0x103C9]={
+ category="lo",
+ description="OLD PERSIAN SIGN AURAMAZDAA-0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103C9,
+ },
+ [0x103CA]={
+ category="lo",
+ description="OLD PERSIAN SIGN AURAMAZDAAHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103CA,
+ },
+ [0x103CB]={
+ category="lo",
+ description="OLD PERSIAN SIGN XSHAAYATHIYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103CB,
+ },
+ [0x103CC]={
+ category="lo",
+ description="OLD PERSIAN SIGN DAHYAAUSH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103CC,
+ },
+ [0x103CD]={
+ category="lo",
+ description="OLD PERSIAN SIGN DAHYAAUSH-0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103CD,
+ },
+ [0x103CE]={
+ category="lo",
+ description="OLD PERSIAN SIGN BAGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103CE,
+ },
+ [0x103CF]={
+ category="lo",
+ description="OLD PERSIAN SIGN BUUMISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103CF,
+ },
+ [0x103D0]={
+ category="po",
+ description="OLD PERSIAN WORD DIVIDER",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x103D0,
+ },
+ [0x103D1]={
+ category="nl",
+ description="OLD PERSIAN NUMBER ONE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103D1,
+ },
+ [0x103D2]={
+ category="nl",
+ description="OLD PERSIAN NUMBER TWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103D2,
+ },
+ [0x103D3]={
+ category="nl",
+ description="OLD PERSIAN NUMBER TEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103D3,
+ },
+ [0x103D4]={
+ category="nl",
+ description="OLD PERSIAN NUMBER TWENTY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103D4,
+ },
+ [0x103D5]={
+ category="nl",
+ description="OLD PERSIAN NUMBER HUNDRED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x103D5,
+ },
+ [0x10400]={
+ category="lu",
+ description="DESERET CAPITAL LETTER LONG I",
+ direction="l",
+ lccode=0x10428,
+ linebreak="al",
+ unicodeslot=0x10400,
+ },
+ [0x10401]={
+ category="lu",
+ description="DESERET CAPITAL LETTER LONG E",
+ direction="l",
+ lccode=0x10429,
+ linebreak="al",
+ unicodeslot=0x10401,
+ },
+ [0x10402]={
+ category="lu",
+ description="DESERET CAPITAL LETTER LONG A",
+ direction="l",
+ lccode=0x1042A,
+ linebreak="al",
+ unicodeslot=0x10402,
+ },
+ [0x10403]={
+ category="lu",
+ description="DESERET CAPITAL LETTER LONG AH",
+ direction="l",
+ lccode=0x1042B,
+ linebreak="al",
+ unicodeslot=0x10403,
+ },
+ [0x10404]={
+ category="lu",
+ description="DESERET CAPITAL LETTER LONG O",
+ direction="l",
+ lccode=0x1042C,
+ linebreak="al",
+ unicodeslot=0x10404,
+ },
+ [0x10405]={
+ category="lu",
+ description="DESERET CAPITAL LETTER LONG OO",
+ direction="l",
+ lccode=0x1042D,
+ linebreak="al",
+ unicodeslot=0x10405,
+ },
+ [0x10406]={
+ category="lu",
+ description="DESERET CAPITAL LETTER SHORT I",
+ direction="l",
+ lccode=0x1042E,
+ linebreak="al",
+ unicodeslot=0x10406,
+ },
+ [0x10407]={
+ category="lu",
+ description="DESERET CAPITAL LETTER SHORT E",
+ direction="l",
+ lccode=0x1042F,
+ linebreak="al",
+ unicodeslot=0x10407,
+ },
+ [0x10408]={
+ category="lu",
+ description="DESERET CAPITAL LETTER SHORT A",
+ direction="l",
+ lccode=0x10430,
+ linebreak="al",
+ unicodeslot=0x10408,
+ },
+ [0x10409]={
+ category="lu",
+ description="DESERET CAPITAL LETTER SHORT AH",
+ direction="l",
+ lccode=0x10431,
+ linebreak="al",
+ unicodeslot=0x10409,
+ },
+ [0x1040A]={
+ category="lu",
+ description="DESERET CAPITAL LETTER SHORT O",
+ direction="l",
+ lccode=0x10432,
+ linebreak="al",
+ unicodeslot=0x1040A,
+ },
+ [0x1040B]={
+ category="lu",
+ description="DESERET CAPITAL LETTER SHORT OO",
+ direction="l",
+ lccode=0x10433,
+ linebreak="al",
+ unicodeslot=0x1040B,
+ },
+ [0x1040C]={
+ category="lu",
+ description="DESERET CAPITAL LETTER AY",
+ direction="l",
+ lccode=0x10434,
+ linebreak="al",
+ unicodeslot=0x1040C,
+ },
+ [0x1040D]={
+ category="lu",
+ description="DESERET CAPITAL LETTER OW",
+ direction="l",
+ lccode=0x10435,
+ linebreak="al",
+ unicodeslot=0x1040D,
+ },
+ [0x1040E]={
+ category="lu",
+ description="DESERET CAPITAL LETTER WU",
+ direction="l",
+ lccode=0x10436,
+ linebreak="al",
+ unicodeslot=0x1040E,
+ },
+ [0x1040F]={
+ category="lu",
+ description="DESERET CAPITAL LETTER YEE",
+ direction="l",
+ lccode=0x10437,
+ linebreak="al",
+ unicodeslot=0x1040F,
+ },
+ [0x10410]={
+ category="lu",
+ description="DESERET CAPITAL LETTER H",
+ direction="l",
+ lccode=0x10438,
+ linebreak="al",
+ unicodeslot=0x10410,
+ },
+ [0x10411]={
+ category="lu",
+ description="DESERET CAPITAL LETTER PEE",
+ direction="l",
+ lccode=0x10439,
+ linebreak="al",
+ unicodeslot=0x10411,
+ },
+ [0x10412]={
+ category="lu",
+ description="DESERET CAPITAL LETTER BEE",
+ direction="l",
+ lccode=0x1043A,
+ linebreak="al",
+ unicodeslot=0x10412,
+ },
+ [0x10413]={
+ category="lu",
+ description="DESERET CAPITAL LETTER TEE",
+ direction="l",
+ lccode=0x1043B,
+ linebreak="al",
+ unicodeslot=0x10413,
+ },
+ [0x10414]={
+ category="lu",
+ description="DESERET CAPITAL LETTER DEE",
+ direction="l",
+ lccode=0x1043C,
+ linebreak="al",
+ unicodeslot=0x10414,
+ },
+ [0x10415]={
+ category="lu",
+ description="DESERET CAPITAL LETTER CHEE",
+ direction="l",
+ lccode=0x1043D,
+ linebreak="al",
+ unicodeslot=0x10415,
+ },
+ [0x10416]={
+ category="lu",
+ description="DESERET CAPITAL LETTER JEE",
+ direction="l",
+ lccode=0x1043E,
+ linebreak="al",
+ unicodeslot=0x10416,
+ },
+ [0x10417]={
+ category="lu",
+ description="DESERET CAPITAL LETTER KAY",
+ direction="l",
+ lccode=0x1043F,
+ linebreak="al",
+ unicodeslot=0x10417,
+ },
+ [0x10418]={
+ category="lu",
+ description="DESERET CAPITAL LETTER GAY",
+ direction="l",
+ lccode=0x10440,
+ linebreak="al",
+ unicodeslot=0x10418,
+ },
+ [0x10419]={
+ category="lu",
+ description="DESERET CAPITAL LETTER EF",
+ direction="l",
+ lccode=0x10441,
+ linebreak="al",
+ unicodeslot=0x10419,
+ },
+ [0x1041A]={
+ category="lu",
+ description="DESERET CAPITAL LETTER VEE",
+ direction="l",
+ lccode=0x10442,
+ linebreak="al",
+ unicodeslot=0x1041A,
+ },
+ [0x1041B]={
+ category="lu",
+ description="DESERET CAPITAL LETTER ETH",
+ direction="l",
+ lccode=0x10443,
+ linebreak="al",
+ unicodeslot=0x1041B,
+ },
+ [0x1041C]={
+ category="lu",
+ description="DESERET CAPITAL LETTER THEE",
+ direction="l",
+ lccode=0x10444,
+ linebreak="al",
+ unicodeslot=0x1041C,
+ },
+ [0x1041D]={
+ category="lu",
+ description="DESERET CAPITAL LETTER ES",
+ direction="l",
+ lccode=0x10445,
+ linebreak="al",
+ unicodeslot=0x1041D,
+ },
+ [0x1041E]={
+ category="lu",
+ description="DESERET CAPITAL LETTER ZEE",
+ direction="l",
+ lccode=0x10446,
+ linebreak="al",
+ unicodeslot=0x1041E,
+ },
+ [0x1041F]={
+ category="lu",
+ description="DESERET CAPITAL LETTER ESH",
+ direction="l",
+ lccode=0x10447,
+ linebreak="al",
+ unicodeslot=0x1041F,
+ },
+ [0x10420]={
+ category="lu",
+ description="DESERET CAPITAL LETTER ZHEE",
+ direction="l",
+ lccode=0x10448,
+ linebreak="al",
+ unicodeslot=0x10420,
+ },
+ [0x10421]={
+ category="lu",
+ description="DESERET CAPITAL LETTER ER",
+ direction="l",
+ lccode=0x10449,
+ linebreak="al",
+ unicodeslot=0x10421,
+ },
+ [0x10422]={
+ category="lu",
+ description="DESERET CAPITAL LETTER EL",
+ direction="l",
+ lccode=0x1044A,
+ linebreak="al",
+ unicodeslot=0x10422,
+ },
+ [0x10423]={
+ category="lu",
+ description="DESERET CAPITAL LETTER EM",
+ direction="l",
+ lccode=0x1044B,
+ linebreak="al",
+ unicodeslot=0x10423,
+ },
+ [0x10424]={
+ category="lu",
+ description="DESERET CAPITAL LETTER EN",
+ direction="l",
+ lccode=0x1044C,
+ linebreak="al",
+ unicodeslot=0x10424,
+ },
+ [0x10425]={
+ category="lu",
+ description="DESERET CAPITAL LETTER ENG",
+ direction="l",
+ lccode=0x1044D,
+ linebreak="al",
+ unicodeslot=0x10425,
+ },
+ [0x10426]={
+ category="lu",
+ description="DESERET CAPITAL LETTER OI",
+ direction="l",
+ lccode=0x1044E,
+ linebreak="al",
+ unicodeslot=0x10426,
+ },
+ [0x10427]={
+ category="lu",
+ description="DESERET CAPITAL LETTER EW",
+ direction="l",
+ lccode=0x1044F,
+ linebreak="al",
+ unicodeslot=0x10427,
+ },
+ [0x10428]={
+ category="ll",
+ description="DESERET SMALL LETTER LONG I",
+ direction="l",
+ linebreak="al",
+ uccode=0x10400,
+ unicodeslot=0x10428,
+ },
+ [0x10429]={
+ category="ll",
+ description="DESERET SMALL LETTER LONG E",
+ direction="l",
+ linebreak="al",
+ uccode=0x10401,
+ unicodeslot=0x10429,
+ },
+ [0x1042A]={
+ category="ll",
+ description="DESERET SMALL LETTER LONG A",
+ direction="l",
+ linebreak="al",
+ uccode=0x10402,
+ unicodeslot=0x1042A,
+ },
+ [0x1042B]={
+ category="ll",
+ description="DESERET SMALL LETTER LONG AH",
+ direction="l",
+ linebreak="al",
+ uccode=0x10403,
+ unicodeslot=0x1042B,
+ },
+ [0x1042C]={
+ category="ll",
+ description="DESERET SMALL LETTER LONG O",
+ direction="l",
+ linebreak="al",
+ uccode=0x10404,
+ unicodeslot=0x1042C,
+ },
+ [0x1042D]={
+ category="ll",
+ description="DESERET SMALL LETTER LONG OO",
+ direction="l",
+ linebreak="al",
+ uccode=0x10405,
+ unicodeslot=0x1042D,
+ },
+ [0x1042E]={
+ category="ll",
+ description="DESERET SMALL LETTER SHORT I",
+ direction="l",
+ linebreak="al",
+ uccode=0x10406,
+ unicodeslot=0x1042E,
+ },
+ [0x1042F]={
+ category="ll",
+ description="DESERET SMALL LETTER SHORT E",
+ direction="l",
+ linebreak="al",
+ uccode=0x10407,
+ unicodeslot=0x1042F,
+ },
+ [0x10430]={
+ category="ll",
+ description="DESERET SMALL LETTER SHORT A",
+ direction="l",
+ linebreak="al",
+ uccode=0x10408,
+ unicodeslot=0x10430,
+ },
+ [0x10431]={
+ category="ll",
+ description="DESERET SMALL LETTER SHORT AH",
+ direction="l",
+ linebreak="al",
+ uccode=0x10409,
+ unicodeslot=0x10431,
+ },
+ [0x10432]={
+ category="ll",
+ description="DESERET SMALL LETTER SHORT O",
+ direction="l",
+ linebreak="al",
+ uccode=0x1040A,
+ unicodeslot=0x10432,
+ },
+ [0x10433]={
+ category="ll",
+ description="DESERET SMALL LETTER SHORT OO",
+ direction="l",
+ linebreak="al",
+ uccode=0x1040B,
+ unicodeslot=0x10433,
+ },
+ [0x10434]={
+ category="ll",
+ description="DESERET SMALL LETTER AY",
+ direction="l",
+ linebreak="al",
+ uccode=0x1040C,
+ unicodeslot=0x10434,
+ },
+ [0x10435]={
+ category="ll",
+ description="DESERET SMALL LETTER OW",
+ direction="l",
+ linebreak="al",
+ uccode=0x1040D,
+ unicodeslot=0x10435,
+ },
+ [0x10436]={
+ category="ll",
+ description="DESERET SMALL LETTER WU",
+ direction="l",
+ linebreak="al",
+ uccode=0x1040E,
+ unicodeslot=0x10436,
+ },
+ [0x10437]={
+ category="ll",
+ description="DESERET SMALL LETTER YEE",
+ direction="l",
+ linebreak="al",
+ uccode=0x1040F,
+ unicodeslot=0x10437,
+ },
+ [0x10438]={
+ category="ll",
+ description="DESERET SMALL LETTER H",
+ direction="l",
+ linebreak="al",
+ uccode=0x10410,
+ unicodeslot=0x10438,
+ },
+ [0x10439]={
+ category="ll",
+ description="DESERET SMALL LETTER PEE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10411,
+ unicodeslot=0x10439,
+ },
+ [0x1043A]={
+ category="ll",
+ description="DESERET SMALL LETTER BEE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10412,
+ unicodeslot=0x1043A,
+ },
+ [0x1043B]={
+ category="ll",
+ description="DESERET SMALL LETTER TEE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10413,
+ unicodeslot=0x1043B,
+ },
+ [0x1043C]={
+ category="ll",
+ description="DESERET SMALL LETTER DEE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10414,
+ unicodeslot=0x1043C,
+ },
+ [0x1043D]={
+ category="ll",
+ description="DESERET SMALL LETTER CHEE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10415,
+ unicodeslot=0x1043D,
+ },
+ [0x1043E]={
+ category="ll",
+ description="DESERET SMALL LETTER JEE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10416,
+ unicodeslot=0x1043E,
+ },
+ [0x1043F]={
+ category="ll",
+ description="DESERET SMALL LETTER KAY",
+ direction="l",
+ linebreak="al",
+ uccode=0x10417,
+ unicodeslot=0x1043F,
+ },
+ [0x10440]={
+ category="ll",
+ description="DESERET SMALL LETTER GAY",
+ direction="l",
+ linebreak="al",
+ uccode=0x10418,
+ unicodeslot=0x10440,
+ },
+ [0x10441]={
+ category="ll",
+ description="DESERET SMALL LETTER EF",
+ direction="l",
+ linebreak="al",
+ uccode=0x10419,
+ unicodeslot=0x10441,
+ },
+ [0x10442]={
+ category="ll",
+ description="DESERET SMALL LETTER VEE",
+ direction="l",
+ linebreak="al",
+ uccode=0x1041A,
+ unicodeslot=0x10442,
+ },
+ [0x10443]={
+ category="ll",
+ description="DESERET SMALL LETTER ETH",
+ direction="l",
+ linebreak="al",
+ uccode=0x1041B,
+ unicodeslot=0x10443,
+ },
+ [0x10444]={
+ category="ll",
+ description="DESERET SMALL LETTER THEE",
+ direction="l",
+ linebreak="al",
+ uccode=0x1041C,
+ unicodeslot=0x10444,
+ },
+ [0x10445]={
+ category="ll",
+ description="DESERET SMALL LETTER ES",
+ direction="l",
+ linebreak="al",
+ uccode=0x1041D,
+ unicodeslot=0x10445,
+ },
+ [0x10446]={
+ category="ll",
+ description="DESERET SMALL LETTER ZEE",
+ direction="l",
+ linebreak="al",
+ uccode=0x1041E,
+ unicodeslot=0x10446,
+ },
+ [0x10447]={
+ category="ll",
+ description="DESERET SMALL LETTER ESH",
+ direction="l",
+ linebreak="al",
+ uccode=0x1041F,
+ unicodeslot=0x10447,
+ },
+ [0x10448]={
+ category="ll",
+ description="DESERET SMALL LETTER ZHEE",
+ direction="l",
+ linebreak="al",
+ uccode=0x10420,
+ unicodeslot=0x10448,
+ },
+ [0x10449]={
+ category="ll",
+ description="DESERET SMALL LETTER ER",
+ direction="l",
+ linebreak="al",
+ uccode=0x10421,
+ unicodeslot=0x10449,
+ },
+ [0x1044A]={
+ category="ll",
+ description="DESERET SMALL LETTER EL",
+ direction="l",
+ linebreak="al",
+ uccode=0x10422,
+ unicodeslot=0x1044A,
+ },
+ [0x1044B]={
+ category="ll",
+ description="DESERET SMALL LETTER EM",
+ direction="l",
+ linebreak="al",
+ uccode=0x10423,
+ unicodeslot=0x1044B,
+ },
+ [0x1044C]={
+ category="ll",
+ description="DESERET SMALL LETTER EN",
+ direction="l",
+ linebreak="al",
+ uccode=0x10424,
+ unicodeslot=0x1044C,
+ },
+ [0x1044D]={
+ category="ll",
+ description="DESERET SMALL LETTER ENG",
+ direction="l",
+ linebreak="al",
+ uccode=0x10425,
+ unicodeslot=0x1044D,
+ },
+ [0x1044E]={
+ category="ll",
+ description="DESERET SMALL LETTER OI",
+ direction="l",
+ linebreak="al",
+ uccode=0x10426,
+ unicodeslot=0x1044E,
+ },
+ [0x1044F]={
+ category="ll",
+ description="DESERET SMALL LETTER EW",
+ direction="l",
+ linebreak="al",
+ uccode=0x10427,
+ unicodeslot=0x1044F,
+ },
+ [0x10450]={
+ category="lo",
+ description="SHAVIAN LETTER PEEP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10450,
+ },
+ [0x10451]={
+ category="lo",
+ description="SHAVIAN LETTER TOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10451,
+ },
+ [0x10452]={
+ category="lo",
+ description="SHAVIAN LETTER KICK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10452,
+ },
+ [0x10453]={
+ category="lo",
+ description="SHAVIAN LETTER FEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10453,
+ },
+ [0x10454]={
+ category="lo",
+ description="SHAVIAN LETTER THIGH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10454,
+ },
+ [0x10455]={
+ category="lo",
+ description="SHAVIAN LETTER SO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10455,
+ },
+ [0x10456]={
+ category="lo",
+ description="SHAVIAN LETTER SURE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10456,
+ },
+ [0x10457]={
+ category="lo",
+ description="SHAVIAN LETTER CHURCH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10457,
+ },
+ [0x10458]={
+ category="lo",
+ description="SHAVIAN LETTER YEA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10458,
+ },
+ [0x10459]={
+ category="lo",
+ description="SHAVIAN LETTER HUNG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10459,
+ },
+ [0x1045A]={
+ category="lo",
+ description="SHAVIAN LETTER BIB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1045A,
+ },
+ [0x1045B]={
+ category="lo",
+ description="SHAVIAN LETTER DEAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1045B,
+ },
+ [0x1045C]={
+ category="lo",
+ description="SHAVIAN LETTER GAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1045C,
+ },
+ [0x1045D]={
+ category="lo",
+ description="SHAVIAN LETTER VOW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1045D,
+ },
+ [0x1045E]={
+ category="lo",
+ description="SHAVIAN LETTER THEY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1045E,
+ },
+ [0x1045F]={
+ category="lo",
+ description="SHAVIAN LETTER ZOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1045F,
+ },
+ [0x10460]={
+ category="lo",
+ description="SHAVIAN LETTER MEASURE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10460,
+ },
+ [0x10461]={
+ category="lo",
+ description="SHAVIAN LETTER JUDGE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10461,
+ },
+ [0x10462]={
+ category="lo",
+ description="SHAVIAN LETTER WOE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10462,
+ },
+ [0x10463]={
+ category="lo",
+ description="SHAVIAN LETTER HA-HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10463,
+ },
+ [0x10464]={
+ category="lo",
+ description="SHAVIAN LETTER LOLL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10464,
+ },
+ [0x10465]={
+ category="lo",
+ description="SHAVIAN LETTER MIME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10465,
+ },
+ [0x10466]={
+ category="lo",
+ description="SHAVIAN LETTER IF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10466,
+ },
+ [0x10467]={
+ category="lo",
+ description="SHAVIAN LETTER EGG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10467,
+ },
+ [0x10468]={
+ category="lo",
+ description="SHAVIAN LETTER ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10468,
+ },
+ [0x10469]={
+ category="lo",
+ description="SHAVIAN LETTER ADO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10469,
+ },
+ [0x1046A]={
+ category="lo",
+ description="SHAVIAN LETTER ON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1046A,
+ },
+ [0x1046B]={
+ category="lo",
+ description="SHAVIAN LETTER WOOL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1046B,
+ },
+ [0x1046C]={
+ category="lo",
+ description="SHAVIAN LETTER OUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1046C,
+ },
+ [0x1046D]={
+ category="lo",
+ description="SHAVIAN LETTER AH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1046D,
+ },
+ [0x1046E]={
+ category="lo",
+ description="SHAVIAN LETTER ROAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1046E,
+ },
+ [0x1046F]={
+ category="lo",
+ description="SHAVIAN LETTER NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1046F,
+ },
+ [0x10470]={
+ category="lo",
+ description="SHAVIAN LETTER EAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10470,
+ },
+ [0x10471]={
+ category="lo",
+ description="SHAVIAN LETTER AGE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10471,
+ },
+ [0x10472]={
+ category="lo",
+ description="SHAVIAN LETTER ICE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10472,
+ },
+ [0x10473]={
+ category="lo",
+ description="SHAVIAN LETTER UP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10473,
+ },
+ [0x10474]={
+ category="lo",
+ description="SHAVIAN LETTER OAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10474,
+ },
+ [0x10475]={
+ category="lo",
+ description="SHAVIAN LETTER OOZE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10475,
+ },
+ [0x10476]={
+ category="lo",
+ description="SHAVIAN LETTER OIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10476,
+ },
+ [0x10477]={
+ category="lo",
+ description="SHAVIAN LETTER AWE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10477,
+ },
+ [0x10478]={
+ category="lo",
+ description="SHAVIAN LETTER ARE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10478,
+ },
+ [0x10479]={
+ category="lo",
+ description="SHAVIAN LETTER OR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10479,
+ },
+ [0x1047A]={
+ category="lo",
+ description="SHAVIAN LETTER AIR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1047A,
+ },
+ [0x1047B]={
+ category="lo",
+ description="SHAVIAN LETTER ERR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1047B,
+ },
+ [0x1047C]={
+ category="lo",
+ description="SHAVIAN LETTER ARRAY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1047C,
+ },
+ [0x1047D]={
+ category="lo",
+ description="SHAVIAN LETTER EAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1047D,
+ },
+ [0x1047E]={
+ category="lo",
+ description="SHAVIAN LETTER IAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1047E,
+ },
+ [0x1047F]={
+ category="lo",
+ description="SHAVIAN LETTER YEW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1047F,
+ },
+ [0x10480]={
+ category="lo",
+ description="OSMANYA LETTER ALEF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10480,
+ },
+ [0x10481]={
+ category="lo",
+ description="OSMANYA LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10481,
+ },
+ [0x10482]={
+ category="lo",
+ description="OSMANYA LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10482,
+ },
+ [0x10483]={
+ category="lo",
+ description="OSMANYA LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10483,
+ },
+ [0x10484]={
+ category="lo",
+ description="OSMANYA LETTER XA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10484,
+ },
+ [0x10485]={
+ category="lo",
+ description="OSMANYA LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10485,
+ },
+ [0x10486]={
+ category="lo",
+ description="OSMANYA LETTER DEEL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10486,
+ },
+ [0x10487]={
+ category="lo",
+ description="OSMANYA LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10487,
+ },
+ [0x10488]={
+ category="lo",
+ description="OSMANYA LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10488,
+ },
+ [0x10489]={
+ category="lo",
+ description="OSMANYA LETTER SHIIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10489,
+ },
+ [0x1048A]={
+ category="lo",
+ description="OSMANYA LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1048A,
+ },
+ [0x1048B]={
+ category="lo",
+ description="OSMANYA LETTER CAYN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1048B,
+ },
+ [0x1048C]={
+ category="lo",
+ description="OSMANYA LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1048C,
+ },
+ [0x1048D]={
+ category="lo",
+ description="OSMANYA LETTER FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1048D,
+ },
+ [0x1048E]={
+ category="lo",
+ description="OSMANYA LETTER QAAF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1048E,
+ },
+ [0x1048F]={
+ category="lo",
+ description="OSMANYA LETTER KAAF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1048F,
+ },
+ [0x10490]={
+ category="lo",
+ description="OSMANYA LETTER LAAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10490,
+ },
+ [0x10491]={
+ category="lo",
+ description="OSMANYA LETTER MIIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10491,
+ },
+ [0x10492]={
+ category="lo",
+ description="OSMANYA LETTER NUUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10492,
+ },
+ [0x10493]={
+ category="lo",
+ description="OSMANYA LETTER WAW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10493,
+ },
+ [0x10494]={
+ category="lo",
+ description="OSMANYA LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10494,
+ },
+ [0x10495]={
+ category="lo",
+ description="OSMANYA LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10495,
+ },
+ [0x10496]={
+ category="lo",
+ description="OSMANYA LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10496,
+ },
+ [0x10497]={
+ category="lo",
+ description="OSMANYA LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10497,
+ },
+ [0x10498]={
+ category="lo",
+ description="OSMANYA LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10498,
+ },
+ [0x10499]={
+ category="lo",
+ description="OSMANYA LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x10499,
+ },
+ [0x1049A]={
+ category="lo",
+ description="OSMANYA LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1049A,
+ },
+ [0x1049B]={
+ category="lo",
+ description="OSMANYA LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1049B,
+ },
+ [0x1049C]={
+ category="lo",
+ description="OSMANYA LETTER EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1049C,
+ },
+ [0x1049D]={
+ category="lo",
+ description="OSMANYA LETTER OO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1049D,
+ },
+ [0x104A0]={
+ category="nd",
+ description="OSMANYA DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A0,
+ },
+ [0x104A1]={
+ category="nd",
+ description="OSMANYA DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A1,
+ },
+ [0x104A2]={
+ category="nd",
+ description="OSMANYA DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A2,
+ },
+ [0x104A3]={
+ category="nd",
+ description="OSMANYA DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A3,
+ },
+ [0x104A4]={
+ category="nd",
+ description="OSMANYA DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A4,
+ },
+ [0x104A5]={
+ category="nd",
+ description="OSMANYA DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A5,
+ },
+ [0x104A6]={
+ category="nd",
+ description="OSMANYA DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A6,
+ },
+ [0x104A7]={
+ category="nd",
+ description="OSMANYA DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A7,
+ },
+ [0x104A8]={
+ category="nd",
+ description="OSMANYA DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A8,
+ },
+ [0x104A9]={
+ category="nd",
+ description="OSMANYA DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x104A9,
+ },
+ [0x10800]={
+ category="lo",
+ description="CYPRIOT SYLLABLE A",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10800,
+ },
+ [0x10801]={
+ category="lo",
+ description="CYPRIOT SYLLABLE E",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10801,
+ },
+ [0x10802]={
+ category="lo",
+ description="CYPRIOT SYLLABLE I",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10802,
+ },
+ [0x10803]={
+ category="lo",
+ description="CYPRIOT SYLLABLE O",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10803,
+ },
+ [0x10804]={
+ category="lo",
+ description="CYPRIOT SYLLABLE U",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10804,
+ },
+ [0x10805]={
+ category="lo",
+ description="CYPRIOT SYLLABLE JA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10805,
+ },
+ [0x10808]={
+ category="lo",
+ description="CYPRIOT SYLLABLE JO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10808,
+ },
+ [0x1080A]={
+ category="lo",
+ description="CYPRIOT SYLLABLE KA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1080A,
+ },
+ [0x1080B]={
+ category="lo",
+ description="CYPRIOT SYLLABLE KE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1080B,
+ },
+ [0x1080C]={
+ category="lo",
+ description="CYPRIOT SYLLABLE KI",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1080C,
+ },
+ [0x1080D]={
+ category="lo",
+ description="CYPRIOT SYLLABLE KO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1080D,
+ },
+ [0x1080E]={
+ category="lo",
+ description="CYPRIOT SYLLABLE KU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1080E,
+ },
+ [0x1080F]={
+ category="lo",
+ description="CYPRIOT SYLLABLE LA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1080F,
+ },
+ [0x10810]={
+ category="lo",
+ description="CYPRIOT SYLLABLE LE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10810,
+ },
+ [0x10811]={
+ category="lo",
+ description="CYPRIOT SYLLABLE LI",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10811,
+ },
+ [0x10812]={
+ category="lo",
+ description="CYPRIOT SYLLABLE LO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10812,
+ },
+ [0x10813]={
+ category="lo",
+ description="CYPRIOT SYLLABLE LU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10813,
+ },
+ [0x10814]={
+ category="lo",
+ description="CYPRIOT SYLLABLE MA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10814,
+ },
+ [0x10815]={
+ category="lo",
+ description="CYPRIOT SYLLABLE ME",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10815,
+ },
+ [0x10816]={
+ category="lo",
+ description="CYPRIOT SYLLABLE MI",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10816,
+ },
+ [0x10817]={
+ category="lo",
+ description="CYPRIOT SYLLABLE MO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10817,
+ },
+ [0x10818]={
+ category="lo",
+ description="CYPRIOT SYLLABLE MU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10818,
+ },
+ [0x10819]={
+ category="lo",
+ description="CYPRIOT SYLLABLE NA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10819,
+ },
+ [0x1081A]={
+ category="lo",
+ description="CYPRIOT SYLLABLE NE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1081A,
+ },
+ [0x1081B]={
+ category="lo",
+ description="CYPRIOT SYLLABLE NI",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1081B,
+ },
+ [0x1081C]={
+ category="lo",
+ description="CYPRIOT SYLLABLE NO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1081C,
+ },
+ [0x1081D]={
+ category="lo",
+ description="CYPRIOT SYLLABLE NU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1081D,
+ },
+ [0x1081E]={
+ category="lo",
+ description="CYPRIOT SYLLABLE PA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1081E,
+ },
+ [0x1081F]={
+ category="lo",
+ description="CYPRIOT SYLLABLE PE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1081F,
+ },
+ [0x10820]={
+ category="lo",
+ description="CYPRIOT SYLLABLE PI",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10820,
+ },
+ [0x10821]={
+ category="lo",
+ description="CYPRIOT SYLLABLE PO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10821,
+ },
+ [0x10822]={
+ category="lo",
+ description="CYPRIOT SYLLABLE PU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10822,
+ },
+ [0x10823]={
+ category="lo",
+ description="CYPRIOT SYLLABLE RA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10823,
+ },
+ [0x10824]={
+ category="lo",
+ description="CYPRIOT SYLLABLE RE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10824,
+ },
+ [0x10825]={
+ category="lo",
+ description="CYPRIOT SYLLABLE RI",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10825,
+ },
+ [0x10826]={
+ category="lo",
+ description="CYPRIOT SYLLABLE RO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10826,
+ },
+ [0x10827]={
+ category="lo",
+ description="CYPRIOT SYLLABLE RU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10827,
+ },
+ [0x10828]={
+ category="lo",
+ description="CYPRIOT SYLLABLE SA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10828,
+ },
+ [0x10829]={
+ category="lo",
+ description="CYPRIOT SYLLABLE SE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10829,
+ },
+ [0x1082A]={
+ category="lo",
+ description="CYPRIOT SYLLABLE SI",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1082A,
+ },
+ [0x1082B]={
+ category="lo",
+ description="CYPRIOT SYLLABLE SO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1082B,
+ },
+ [0x1082C]={
+ category="lo",
+ description="CYPRIOT SYLLABLE SU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1082C,
+ },
+ [0x1082D]={
+ category="lo",
+ description="CYPRIOT SYLLABLE TA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1082D,
+ },
+ [0x1082E]={
+ category="lo",
+ description="CYPRIOT SYLLABLE TE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1082E,
+ },
+ [0x1082F]={
+ category="lo",
+ description="CYPRIOT SYLLABLE TI",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1082F,
+ },
+ [0x10830]={
+ category="lo",
+ description="CYPRIOT SYLLABLE TO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10830,
+ },
+ [0x10831]={
+ category="lo",
+ description="CYPRIOT SYLLABLE TU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10831,
+ },
+ [0x10832]={
+ category="lo",
+ description="CYPRIOT SYLLABLE WA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10832,
+ },
+ [0x10833]={
+ category="lo",
+ description="CYPRIOT SYLLABLE WE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10833,
+ },
+ [0x10834]={
+ category="lo",
+ description="CYPRIOT SYLLABLE WI",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10834,
+ },
+ [0x10835]={
+ category="lo",
+ description="CYPRIOT SYLLABLE WO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10835,
+ },
+ [0x10837]={
+ category="lo",
+ description="CYPRIOT SYLLABLE XA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10837,
+ },
+ [0x10838]={
+ category="lo",
+ description="CYPRIOT SYLLABLE XE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10838,
+ },
+ [0x1083C]={
+ category="lo",
+ description="CYPRIOT SYLLABLE ZA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1083C,
+ },
+ [0x1083F]={
+ category="lo",
+ description="CYPRIOT SYLLABLE ZO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1083F,
+ },
+ [0x10840]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER ALEPH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10840,
+ },
+ [0x10841]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER BETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10841,
+ },
+ [0x10842]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER GIMEL",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10842,
+ },
+ [0x10843]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER DALETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10843,
+ },
+ [0x10844]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER HE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10844,
+ },
+ [0x10845]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER WAW",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10845,
+ },
+ [0x10846]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER ZAYIN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10846,
+ },
+ [0x10847]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER HETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10847,
+ },
+ [0x10848]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER TETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10848,
+ },
+ [0x10849]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER YODH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10849,
+ },
+ [0x1084A]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER KAPH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1084A,
+ },
+ [0x1084B]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER LAMEDH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1084B,
+ },
+ [0x1084C]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER MEM",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1084C,
+ },
+ [0x1084D]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER NUN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1084D,
+ },
+ [0x1084E]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER SAMEKH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1084E,
+ },
+ [0x1084F]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER AYIN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1084F,
+ },
+ [0x10850]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER PE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10850,
+ },
+ [0x10851]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER SADHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10851,
+ },
+ [0x10852]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER QOPH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10852,
+ },
+ [0x10853]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER RESH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10853,
+ },
+ [0x10854]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER SHIN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10854,
+ },
+ [0x10855]={
+ category="lo",
+ description="IMPERIAL ARAMAIC LETTER TAW",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10855,
+ },
+ [0x10857]={
+ category="po",
+ description="IMPERIAL ARAMAIC SECTION SIGN",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10857,
+ },
+ [0x10858]={
+ category="no",
+ description="IMPERIAL ARAMAIC NUMBER ONE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10858,
+ },
+ [0x10859]={
+ category="no",
+ description="IMPERIAL ARAMAIC NUMBER TWO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10859,
+ },
+ [0x1085A]={
+ category="no",
+ description="IMPERIAL ARAMAIC NUMBER THREE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1085A,
+ },
+ [0x1085B]={
+ category="no",
+ description="IMPERIAL ARAMAIC NUMBER TEN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1085B,
+ },
+ [0x1085C]={
+ category="no",
+ description="IMPERIAL ARAMAIC NUMBER TWENTY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1085C,
+ },
+ [0x1085D]={
+ category="no",
+ description="IMPERIAL ARAMAIC NUMBER ONE HUNDRED",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1085D,
+ },
+ [0x1085E]={
+ category="no",
+ description="IMPERIAL ARAMAIC NUMBER ONE THOUSAND",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1085E,
+ },
+ [0x1085F]={
+ category="no",
+ description="IMPERIAL ARAMAIC NUMBER TEN THOUSAND",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1085F,
+ },
+ [0x10900]={
+ category="lo",
+ description="PHOENICIAN LETTER ALF",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10900,
+ },
+ [0x10901]={
+ category="lo",
+ description="PHOENICIAN LETTER BET",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10901,
+ },
+ [0x10902]={
+ category="lo",
+ description="PHOENICIAN LETTER GAML",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10902,
+ },
+ [0x10903]={
+ category="lo",
+ description="PHOENICIAN LETTER DELT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10903,
+ },
+ [0x10904]={
+ category="lo",
+ description="PHOENICIAN LETTER HE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10904,
+ },
+ [0x10905]={
+ category="lo",
+ description="PHOENICIAN LETTER WAU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10905,
+ },
+ [0x10906]={
+ category="lo",
+ description="PHOENICIAN LETTER ZAI",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10906,
+ },
+ [0x10907]={
+ category="lo",
+ description="PHOENICIAN LETTER HET",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10907,
+ },
+ [0x10908]={
+ category="lo",
+ description="PHOENICIAN LETTER TET",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10908,
+ },
+ [0x10909]={
+ category="lo",
+ description="PHOENICIAN LETTER YOD",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10909,
+ },
+ [0x1090A]={
+ category="lo",
+ description="PHOENICIAN LETTER KAF",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1090A,
+ },
+ [0x1090B]={
+ category="lo",
+ description="PHOENICIAN LETTER LAMD",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1090B,
+ },
+ [0x1090C]={
+ category="lo",
+ description="PHOENICIAN LETTER MEM",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1090C,
+ },
+ [0x1090D]={
+ category="lo",
+ description="PHOENICIAN LETTER NUN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1090D,
+ },
+ [0x1090E]={
+ category="lo",
+ description="PHOENICIAN LETTER SEMK",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1090E,
+ },
+ [0x1090F]={
+ category="lo",
+ description="PHOENICIAN LETTER AIN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1090F,
+ },
+ [0x10910]={
+ category="lo",
+ description="PHOENICIAN LETTER PE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10910,
+ },
+ [0x10911]={
+ category="lo",
+ description="PHOENICIAN LETTER SADE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10911,
+ },
+ [0x10912]={
+ category="lo",
+ description="PHOENICIAN LETTER QOF",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10912,
+ },
+ [0x10913]={
+ category="lo",
+ description="PHOENICIAN LETTER ROSH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10913,
+ },
+ [0x10914]={
+ category="lo",
+ description="PHOENICIAN LETTER SHIN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10914,
+ },
+ [0x10915]={
+ category="lo",
+ description="PHOENICIAN LETTER TAU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10915,
+ },
+ [0x10916]={
+ category="no",
+ description="PHOENICIAN NUMBER ONE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10916,
+ },
+ [0x10917]={
+ category="no",
+ description="PHOENICIAN NUMBER TEN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10917,
+ },
+ [0x10918]={
+ category="no",
+ description="PHOENICIAN NUMBER TWENTY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10918,
+ },
+ [0x10919]={
+ category="no",
+ description="PHOENICIAN NUMBER ONE HUNDRED",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10919,
+ },
+ [0x1091A]={
+ category="no",
+ description="PHOENICIAN NUMBER TWO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1091A,
+ },
+ [0x1091B]={
+ category="no",
+ description="PHOENICIAN NUMBER THREE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1091B,
+ },
+ [0x1091F]={
+ category="po",
+ description="PHOENICIAN WORD SEPARATOR",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x1091F,
+ },
+ [0x10920]={
+ category="lo",
+ description="LYDIAN LETTER A",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10920,
+ },
+ [0x10921]={
+ category="lo",
+ description="LYDIAN LETTER B",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10921,
+ },
+ [0x10922]={
+ category="lo",
+ description="LYDIAN LETTER G",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10922,
+ },
+ [0x10923]={
+ category="lo",
+ description="LYDIAN LETTER D",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10923,
+ },
+ [0x10924]={
+ category="lo",
+ description="LYDIAN LETTER E",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10924,
+ },
+ [0x10925]={
+ category="lo",
+ description="LYDIAN LETTER V",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10925,
+ },
+ [0x10926]={
+ category="lo",
+ description="LYDIAN LETTER I",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10926,
+ },
+ [0x10927]={
+ category="lo",
+ description="LYDIAN LETTER Y",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10927,
+ },
+ [0x10928]={
+ category="lo",
+ description="LYDIAN LETTER K",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10928,
+ },
+ [0x10929]={
+ category="lo",
+ description="LYDIAN LETTER L",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10929,
+ },
+ [0x1092A]={
+ category="lo",
+ description="LYDIAN LETTER M",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1092A,
+ },
+ [0x1092B]={
+ category="lo",
+ description="LYDIAN LETTER N",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1092B,
+ },
+ [0x1092C]={
+ category="lo",
+ description="LYDIAN LETTER O",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1092C,
+ },
+ [0x1092D]={
+ category="lo",
+ description="LYDIAN LETTER R",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1092D,
+ },
+ [0x1092E]={
+ category="lo",
+ description="LYDIAN LETTER SS",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1092E,
+ },
+ [0x1092F]={
+ category="lo",
+ description="LYDIAN LETTER T",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1092F,
+ },
+ [0x10930]={
+ category="lo",
+ description="LYDIAN LETTER U",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10930,
+ },
+ [0x10931]={
+ category="lo",
+ description="LYDIAN LETTER F",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10931,
+ },
+ [0x10932]={
+ category="lo",
+ description="LYDIAN LETTER Q",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10932,
+ },
+ [0x10933]={
+ category="lo",
+ description="LYDIAN LETTER S",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10933,
+ },
+ [0x10934]={
+ category="lo",
+ description="LYDIAN LETTER TT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10934,
+ },
+ [0x10935]={
+ category="lo",
+ description="LYDIAN LETTER AN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10935,
+ },
+ [0x10936]={
+ category="lo",
+ description="LYDIAN LETTER EN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10936,
+ },
+ [0x10937]={
+ category="lo",
+ description="LYDIAN LETTER LY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10937,
+ },
+ [0x10938]={
+ category="lo",
+ description="LYDIAN LETTER NN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10938,
+ },
+ [0x10939]={
+ category="lo",
+ description="LYDIAN LETTER C",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10939,
+ },
+ [0x1093F]={
+ category="po",
+ description="LYDIAN TRIANGULAR MARK",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1093F,
+ },
+ [0x10980]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER A",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10980,
+ },
+ [0x10981]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER E",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10981,
+ },
+ [0x10982]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER I",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10982,
+ },
+ [0x10983]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER O",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10983,
+ },
+ [0x10984]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER YA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10984,
+ },
+ [0x10985]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER WA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10985,
+ },
+ [0x10986]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER BA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10986,
+ },
+ [0x10987]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER BA-2",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10987,
+ },
+ [0x10988]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER PA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10988,
+ },
+ [0x10989]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER MA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10989,
+ },
+ [0x1098A]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER NA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1098A,
+ },
+ [0x1098B]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER NA-2",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1098B,
+ },
+ [0x1098C]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER NE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1098C,
+ },
+ [0x1098D]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER NE-2",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1098D,
+ },
+ [0x1098E]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER RA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1098E,
+ },
+ [0x1098F]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER RA-2",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1098F,
+ },
+ [0x10990]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER LA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10990,
+ },
+ [0x10991]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER KHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10991,
+ },
+ [0x10992]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER HHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10992,
+ },
+ [0x10993]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER SA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10993,
+ },
+ [0x10994]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER SA-2",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10994,
+ },
+ [0x10995]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER SE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10995,
+ },
+ [0x10996]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER KA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10996,
+ },
+ [0x10997]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER QA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10997,
+ },
+ [0x10998]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER TA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10998,
+ },
+ [0x10999]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER TA-2",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10999,
+ },
+ [0x1099A]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER TE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1099A,
+ },
+ [0x1099B]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER TE-2",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1099B,
+ },
+ [0x1099C]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER TO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1099C,
+ },
+ [0x1099D]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC LETTER DA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1099D,
+ },
+ [0x1099E]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC SYMBOL VIDJ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1099E,
+ },
+ [0x1099F]={
+ category="lo",
+ description="MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x1099F,
+ },
+ [0x109A0]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER A",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A0,
+ },
+ [0x109A1]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER E",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A1,
+ },
+ [0x109A2]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER I",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A2,
+ },
+ [0x109A3]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER O",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A3,
+ },
+ [0x109A4]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER YA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A4,
+ },
+ [0x109A5]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER WA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A5,
+ },
+ [0x109A6]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER BA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A6,
+ },
+ [0x109A7]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER PA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A7,
+ },
+ [0x109A8]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER MA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A8,
+ },
+ [0x109A9]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER NA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109A9,
+ },
+ [0x109AA]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER NE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109AA,
+ },
+ [0x109AB]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER RA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109AB,
+ },
+ [0x109AC]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER LA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109AC,
+ },
+ [0x109AD]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER KHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109AD,
+ },
+ [0x109AE]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER HHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109AE,
+ },
+ [0x109AF]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER SA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109AF,
+ },
+ [0x109B0]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER ARCHAIC SA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B0,
+ },
+ [0x109B1]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER SE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B1,
+ },
+ [0x109B2]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER KA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B2,
+ },
+ [0x109B3]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER QA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B3,
+ },
+ [0x109B4]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER TA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B4,
+ },
+ [0x109B5]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER TE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B5,
+ },
+ [0x109B6]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER TO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B6,
+ },
+ [0x109B7]={
+ category="lo",
+ description="MEROITIC CURSIVE LETTER DA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109B7,
+ },
+ [0x109BE]={
+ category="lo",
+ description="MEROITIC CURSIVE LOGOGRAM RMT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109BE,
+ },
+ [0x109BF]={
+ category="lo",
+ description="MEROITIC CURSIVE LOGOGRAM IMN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x109BF,
+ },
+ [0x10A00]={
+ category="lo",
+ description="KHAROSHTHI LETTER A",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A00,
+ },
+ [0x10A01]={
+ category="mn",
+ description="KHAROSHTHI VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A01,
+ },
+ [0x10A02]={
+ category="mn",
+ description="KHAROSHTHI VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A02,
+ },
+ [0x10A03]={
+ category="mn",
+ description="KHAROSHTHI VOWEL SIGN VOCALIC R",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A03,
+ },
+ [0x10A05]={
+ category="mn",
+ description="KHAROSHTHI VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A05,
+ },
+ [0x10A06]={
+ category="mn",
+ description="KHAROSHTHI VOWEL SIGN O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A06,
+ },
+ [0x10A0C]={
+ category="mn",
+ description="KHAROSHTHI VOWEL LENGTH MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A0C,
+ },
+ [0x10A0D]={
+ category="mn",
+ description="KHAROSHTHI SIGN DOUBLE RING BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A0D,
+ },
+ [0x10A0E]={
+ category="mn",
+ description="KHAROSHTHI SIGN ANUSVARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A0E,
+ },
+ [0x10A0F]={
+ category="mn",
+ description="KHAROSHTHI SIGN VISARGA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A0F,
+ },
+ [0x10A10]={
+ category="lo",
+ description="KHAROSHTHI LETTER KA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A10,
+ },
+ [0x10A11]={
+ category="lo",
+ description="KHAROSHTHI LETTER KHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A11,
+ },
+ [0x10A12]={
+ category="lo",
+ description="KHAROSHTHI LETTER GA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A12,
+ },
+ [0x10A13]={
+ category="lo",
+ description="KHAROSHTHI LETTER GHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A13,
+ },
+ [0x10A15]={
+ category="lo",
+ description="KHAROSHTHI LETTER CA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A15,
+ },
+ [0x10A16]={
+ category="lo",
+ description="KHAROSHTHI LETTER CHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A16,
+ },
+ [0x10A17]={
+ category="lo",
+ description="KHAROSHTHI LETTER JA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A17,
+ },
+ [0x10A19]={
+ category="lo",
+ description="KHAROSHTHI LETTER NYA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A19,
+ },
+ [0x10A1A]={
+ category="lo",
+ description="KHAROSHTHI LETTER TTA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A1A,
+ },
+ [0x10A1B]={
+ category="lo",
+ description="KHAROSHTHI LETTER TTHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A1B,
+ },
+ [0x10A1C]={
+ category="lo",
+ description="KHAROSHTHI LETTER DDA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A1C,
+ },
+ [0x10A1D]={
+ category="lo",
+ description="KHAROSHTHI LETTER DDHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A1D,
+ },
+ [0x10A1E]={
+ category="lo",
+ description="KHAROSHTHI LETTER NNA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A1E,
+ },
+ [0x10A1F]={
+ category="lo",
+ description="KHAROSHTHI LETTER TA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A1F,
+ },
+ [0x10A20]={
+ category="lo",
+ description="KHAROSHTHI LETTER THA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A20,
+ },
+ [0x10A21]={
+ category="lo",
+ description="KHAROSHTHI LETTER DA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A21,
+ },
+ [0x10A22]={
+ category="lo",
+ description="KHAROSHTHI LETTER DHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A22,
+ },
+ [0x10A23]={
+ category="lo",
+ description="KHAROSHTHI LETTER NA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A23,
+ },
+ [0x10A24]={
+ category="lo",
+ description="KHAROSHTHI LETTER PA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A24,
+ },
+ [0x10A25]={
+ category="lo",
+ description="KHAROSHTHI LETTER PHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A25,
+ },
+ [0x10A26]={
+ category="lo",
+ description="KHAROSHTHI LETTER BA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A26,
+ },
+ [0x10A27]={
+ category="lo",
+ description="KHAROSHTHI LETTER BHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A27,
+ },
+ [0x10A28]={
+ category="lo",
+ description="KHAROSHTHI LETTER MA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A28,
+ },
+ [0x10A29]={
+ category="lo",
+ description="KHAROSHTHI LETTER YA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A29,
+ },
+ [0x10A2A]={
+ category="lo",
+ description="KHAROSHTHI LETTER RA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A2A,
+ },
+ [0x10A2B]={
+ category="lo",
+ description="KHAROSHTHI LETTER LA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A2B,
+ },
+ [0x10A2C]={
+ category="lo",
+ description="KHAROSHTHI LETTER VA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A2C,
+ },
+ [0x10A2D]={
+ category="lo",
+ description="KHAROSHTHI LETTER SHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A2D,
+ },
+ [0x10A2E]={
+ category="lo",
+ description="KHAROSHTHI LETTER SSA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A2E,
+ },
+ [0x10A2F]={
+ category="lo",
+ description="KHAROSHTHI LETTER SA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A2F,
+ },
+ [0x10A30]={
+ category="lo",
+ description="KHAROSHTHI LETTER ZA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A30,
+ },
+ [0x10A31]={
+ category="lo",
+ description="KHAROSHTHI LETTER HA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A31,
+ },
+ [0x10A32]={
+ category="lo",
+ description="KHAROSHTHI LETTER KKA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A32,
+ },
+ [0x10A33]={
+ category="lo",
+ description="KHAROSHTHI LETTER TTTHA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A33,
+ },
+ [0x10A38]={
+ category="mn",
+ description="KHAROSHTHI SIGN BAR ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A38,
+ },
+ [0x10A39]={
+ category="mn",
+ description="KHAROSHTHI SIGN CAUDA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A39,
+ },
+ [0x10A3A]={
+ category="mn",
+ description="KHAROSHTHI SIGN DOT BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A3A,
+ },
+ [0x10A3F]={
+ category="mn",
+ description="KHAROSHTHI VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10A3F,
+ },
+ [0x10A40]={
+ category="no",
+ description="KHAROSHTHI DIGIT ONE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A40,
+ },
+ [0x10A41]={
+ category="no",
+ description="KHAROSHTHI DIGIT TWO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A41,
+ },
+ [0x10A42]={
+ category="no",
+ description="KHAROSHTHI DIGIT THREE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A42,
+ },
+ [0x10A43]={
+ category="no",
+ description="KHAROSHTHI DIGIT FOUR",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A43,
+ },
+ [0x10A44]={
+ category="no",
+ description="KHAROSHTHI NUMBER TEN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A44,
+ },
+ [0x10A45]={
+ category="no",
+ description="KHAROSHTHI NUMBER TWENTY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A45,
+ },
+ [0x10A46]={
+ category="no",
+ description="KHAROSHTHI NUMBER ONE HUNDRED",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A46,
+ },
+ [0x10A47]={
+ category="no",
+ description="KHAROSHTHI NUMBER ONE THOUSAND",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A47,
+ },
+ [0x10A50]={
+ category="po",
+ description="KHAROSHTHI PUNCTUATION DOT",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A50,
+ },
+ [0x10A51]={
+ category="po",
+ description="KHAROSHTHI PUNCTUATION SMALL CIRCLE",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A51,
+ },
+ [0x10A52]={
+ category="po",
+ description="KHAROSHTHI PUNCTUATION CIRCLE",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A52,
+ },
+ [0x10A53]={
+ category="po",
+ description="KHAROSHTHI PUNCTUATION CRESCENT BAR",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A53,
+ },
+ [0x10A54]={
+ category="po",
+ description="KHAROSHTHI PUNCTUATION MANGALAM",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A54,
+ },
+ [0x10A55]={
+ category="po",
+ description="KHAROSHTHI PUNCTUATION LOTUS",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A55,
+ },
+ [0x10A56]={
+ category="po",
+ description="KHAROSHTHI PUNCTUATION DANDA",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A56,
+ },
+ [0x10A57]={
+ category="po",
+ description="KHAROSHTHI PUNCTUATION DOUBLE DANDA",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10A57,
+ },
+ [0x10A58]={
+ category="po",
+ description="KHAROSHTHI PUNCTUATION LINES",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A58,
+ },
+ [0x10A60]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER HE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A60,
+ },
+ [0x10A61]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER LAMEDH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A61,
+ },
+ [0x10A62]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER HETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A62,
+ },
+ [0x10A63]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER MEM",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A63,
+ },
+ [0x10A64]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER QOPH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A64,
+ },
+ [0x10A65]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER WAW",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A65,
+ },
+ [0x10A66]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER SHIN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A66,
+ },
+ [0x10A67]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER RESH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A67,
+ },
+ [0x10A68]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER BETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A68,
+ },
+ [0x10A69]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER TAW",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A69,
+ },
+ [0x10A6A]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER SAT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A6A,
+ },
+ [0x10A6B]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER KAPH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A6B,
+ },
+ [0x10A6C]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER NUN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A6C,
+ },
+ [0x10A6D]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER KHETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A6D,
+ },
+ [0x10A6E]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER SADHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A6E,
+ },
+ [0x10A6F]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER SAMEKH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A6F,
+ },
+ [0x10A70]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER FE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A70,
+ },
+ [0x10A71]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER ALEF",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A71,
+ },
+ [0x10A72]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER AYN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A72,
+ },
+ [0x10A73]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER DHADHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A73,
+ },
+ [0x10A74]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER GIMEL",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A74,
+ },
+ [0x10A75]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER DALETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A75,
+ },
+ [0x10A76]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER GHAYN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A76,
+ },
+ [0x10A77]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER TETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A77,
+ },
+ [0x10A78]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER ZAYN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A78,
+ },
+ [0x10A79]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER DHALETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A79,
+ },
+ [0x10A7A]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER YODH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A7A,
+ },
+ [0x10A7B]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER THAW",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A7B,
+ },
+ [0x10A7C]={
+ category="lo",
+ description="OLD SOUTH ARABIAN LETTER THETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A7C,
+ },
+ [0x10A7D]={
+ category="no",
+ description="OLD SOUTH ARABIAN NUMBER ONE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A7D,
+ },
+ [0x10A7E]={
+ category="no",
+ description="OLD SOUTH ARABIAN NUMBER FIFTY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A7E,
+ },
+ [0x10A7F]={
+ category="po",
+ description="OLD SOUTH ARABIAN NUMERIC INDICATOR",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10A7F,
+ },
+ [0x10B00]={
+ category="lo",
+ description="AVESTAN LETTER A",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B00,
+ },
+ [0x10B01]={
+ category="lo",
+ description="AVESTAN LETTER AA",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B01,
+ },
+ [0x10B02]={
+ category="lo",
+ description="AVESTAN LETTER AO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B02,
+ },
+ [0x10B03]={
+ category="lo",
+ description="AVESTAN LETTER AAO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B03,
+ },
+ [0x10B04]={
+ category="lo",
+ description="AVESTAN LETTER AN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B04,
+ },
+ [0x10B05]={
+ category="lo",
+ description="AVESTAN LETTER AAN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B05,
+ },
+ [0x10B06]={
+ category="lo",
+ description="AVESTAN LETTER AE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B06,
+ },
+ [0x10B07]={
+ category="lo",
+ description="AVESTAN LETTER AEE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B07,
+ },
+ [0x10B08]={
+ category="lo",
+ description="AVESTAN LETTER E",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B08,
+ },
+ [0x10B09]={
+ category="lo",
+ description="AVESTAN LETTER EE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B09,
+ },
+ [0x10B0A]={
+ category="lo",
+ description="AVESTAN LETTER O",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B0A,
+ },
+ [0x10B0B]={
+ category="lo",
+ description="AVESTAN LETTER OO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B0B,
+ },
+ [0x10B0C]={
+ category="lo",
+ description="AVESTAN LETTER I",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B0C,
+ },
+ [0x10B0D]={
+ category="lo",
+ description="AVESTAN LETTER II",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B0D,
+ },
+ [0x10B0E]={
+ category="lo",
+ description="AVESTAN LETTER U",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B0E,
+ },
+ [0x10B0F]={
+ category="lo",
+ description="AVESTAN LETTER UU",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B0F,
+ },
+ [0x10B10]={
+ category="lo",
+ description="AVESTAN LETTER KE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B10,
+ },
+ [0x10B11]={
+ category="lo",
+ description="AVESTAN LETTER XE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B11,
+ },
+ [0x10B12]={
+ category="lo",
+ description="AVESTAN LETTER XYE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B12,
+ },
+ [0x10B13]={
+ category="lo",
+ description="AVESTAN LETTER XVE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B13,
+ },
+ [0x10B14]={
+ category="lo",
+ description="AVESTAN LETTER GE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B14,
+ },
+ [0x10B15]={
+ category="lo",
+ description="AVESTAN LETTER GGE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B15,
+ },
+ [0x10B16]={
+ category="lo",
+ description="AVESTAN LETTER GHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B16,
+ },
+ [0x10B17]={
+ category="lo",
+ description="AVESTAN LETTER CE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B17,
+ },
+ [0x10B18]={
+ category="lo",
+ description="AVESTAN LETTER JE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B18,
+ },
+ [0x10B19]={
+ category="lo",
+ description="AVESTAN LETTER TE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B19,
+ },
+ [0x10B1A]={
+ category="lo",
+ description="AVESTAN LETTER THE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B1A,
+ },
+ [0x10B1B]={
+ category="lo",
+ description="AVESTAN LETTER DE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B1B,
+ },
+ [0x10B1C]={
+ category="lo",
+ description="AVESTAN LETTER DHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B1C,
+ },
+ [0x10B1D]={
+ category="lo",
+ description="AVESTAN LETTER TTE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B1D,
+ },
+ [0x10B1E]={
+ category="lo",
+ description="AVESTAN LETTER PE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B1E,
+ },
+ [0x10B1F]={
+ category="lo",
+ description="AVESTAN LETTER FE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B1F,
+ },
+ [0x10B20]={
+ category="lo",
+ description="AVESTAN LETTER BE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B20,
+ },
+ [0x10B21]={
+ category="lo",
+ description="AVESTAN LETTER BHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B21,
+ },
+ [0x10B22]={
+ category="lo",
+ description="AVESTAN LETTER NGE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B22,
+ },
+ [0x10B23]={
+ category="lo",
+ description="AVESTAN LETTER NGYE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B23,
+ },
+ [0x10B24]={
+ category="lo",
+ description="AVESTAN LETTER NGVE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B24,
+ },
+ [0x10B25]={
+ category="lo",
+ description="AVESTAN LETTER NE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B25,
+ },
+ [0x10B26]={
+ category="lo",
+ description="AVESTAN LETTER NYE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B26,
+ },
+ [0x10B27]={
+ category="lo",
+ description="AVESTAN LETTER NNE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B27,
+ },
+ [0x10B28]={
+ category="lo",
+ description="AVESTAN LETTER ME",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B28,
+ },
+ [0x10B29]={
+ category="lo",
+ description="AVESTAN LETTER HME",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B29,
+ },
+ [0x10B2A]={
+ category="lo",
+ description="AVESTAN LETTER YYE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B2A,
+ },
+ [0x10B2B]={
+ category="lo",
+ description="AVESTAN LETTER YE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B2B,
+ },
+ [0x10B2C]={
+ category="lo",
+ description="AVESTAN LETTER VE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B2C,
+ },
+ [0x10B2D]={
+ category="lo",
+ description="AVESTAN LETTER RE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B2D,
+ },
+ [0x10B2E]={
+ category="lo",
+ description="AVESTAN LETTER LE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B2E,
+ },
+ [0x10B2F]={
+ category="lo",
+ description="AVESTAN LETTER SE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B2F,
+ },
+ [0x10B30]={
+ category="lo",
+ description="AVESTAN LETTER ZE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B30,
+ },
+ [0x10B31]={
+ category="lo",
+ description="AVESTAN LETTER SHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B31,
+ },
+ [0x10B32]={
+ category="lo",
+ description="AVESTAN LETTER ZHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B32,
+ },
+ [0x10B33]={
+ category="lo",
+ description="AVESTAN LETTER SHYE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B33,
+ },
+ [0x10B34]={
+ category="lo",
+ description="AVESTAN LETTER SSHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B34,
+ },
+ [0x10B35]={
+ category="lo",
+ description="AVESTAN LETTER HE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B35,
+ },
+ [0x10B39]={
+ category="po",
+ description="AVESTAN ABBREVIATION MARK",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B39,
+ },
+ [0x10B3A]={
+ category="po",
+ description="TINY TWO DOTS OVER ONE DOT PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B3A,
+ },
+ [0x10B3B]={
+ category="po",
+ description="SMALL TWO DOTS OVER ONE DOT PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B3B,
+ },
+ [0x10B3C]={
+ category="po",
+ description="LARGE TWO DOTS OVER ONE DOT PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B3C,
+ },
+ [0x10B3D]={
+ category="po",
+ description="LARGE ONE DOT OVER TWO DOTS PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B3D,
+ },
+ [0x10B3E]={
+ category="po",
+ description="LARGE TWO RINGS OVER ONE RING PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B3E,
+ },
+ [0x10B3F]={
+ category="po",
+ description="LARGE ONE RING OVER TWO RINGS PUNCTUATION",
+ direction="on",
+ linebreak="ba",
+ unicodeslot=0x10B3F,
+ },
+ [0x10B40]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER ALEPH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B40,
+ },
+ [0x10B41]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER BETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B41,
+ },
+ [0x10B42]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER GIMEL",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B42,
+ },
+ [0x10B43]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER DALETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B43,
+ },
+ [0x10B44]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER HE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B44,
+ },
+ [0x10B45]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER WAW",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B45,
+ },
+ [0x10B46]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER ZAYIN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B46,
+ },
+ [0x10B47]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER HETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B47,
+ },
+ [0x10B48]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER TETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B48,
+ },
+ [0x10B49]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER YODH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B49,
+ },
+ [0x10B4A]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER KAPH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B4A,
+ },
+ [0x10B4B]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER LAMEDH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B4B,
+ },
+ [0x10B4C]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER MEM",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B4C,
+ },
+ [0x10B4D]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER NUN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B4D,
+ },
+ [0x10B4E]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER SAMEKH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B4E,
+ },
+ [0x10B4F]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER AYIN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B4F,
+ },
+ [0x10B50]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER PE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B50,
+ },
+ [0x10B51]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER SADHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B51,
+ },
+ [0x10B52]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER QOPH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B52,
+ },
+ [0x10B53]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER RESH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B53,
+ },
+ [0x10B54]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER SHIN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B54,
+ },
+ [0x10B55]={
+ category="lo",
+ description="INSCRIPTIONAL PARTHIAN LETTER TAW",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B55,
+ },
+ [0x10B58]={
+ category="no",
+ description="INSCRIPTIONAL PARTHIAN NUMBER ONE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B58,
+ },
+ [0x10B59]={
+ category="no",
+ description="INSCRIPTIONAL PARTHIAN NUMBER TWO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B59,
+ },
+ [0x10B5A]={
+ category="no",
+ description="INSCRIPTIONAL PARTHIAN NUMBER THREE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B5A,
+ },
+ [0x10B5B]={
+ category="no",
+ description="INSCRIPTIONAL PARTHIAN NUMBER FOUR",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B5B,
+ },
+ [0x10B5C]={
+ category="no",
+ description="INSCRIPTIONAL PARTHIAN NUMBER TEN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B5C,
+ },
+ [0x10B5D]={
+ category="no",
+ description="INSCRIPTIONAL PARTHIAN NUMBER TWENTY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B5D,
+ },
+ [0x10B5E]={
+ category="no",
+ description="INSCRIPTIONAL PARTHIAN NUMBER ONE HUNDRED",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B5E,
+ },
+ [0x10B5F]={
+ category="no",
+ description="INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B5F,
+ },
+ [0x10B60]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER ALEPH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B60,
+ },
+ [0x10B61]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER BETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B61,
+ },
+ [0x10B62]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER GIMEL",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B62,
+ },
+ [0x10B63]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER DALETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B63,
+ },
+ [0x10B64]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER HE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B64,
+ },
+ [0x10B65]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER WAW-AYIN-RESH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B65,
+ },
+ [0x10B66]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER ZAYIN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B66,
+ },
+ [0x10B67]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER HETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B67,
+ },
+ [0x10B68]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER TETH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B68,
+ },
+ [0x10B69]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER YODH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B69,
+ },
+ [0x10B6A]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER KAPH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B6A,
+ },
+ [0x10B6B]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER LAMEDH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B6B,
+ },
+ [0x10B6C]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER MEM-QOPH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B6C,
+ },
+ [0x10B6D]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER NUN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B6D,
+ },
+ [0x10B6E]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER SAMEKH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B6E,
+ },
+ [0x10B6F]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER PE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B6F,
+ },
+ [0x10B70]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER SADHE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B70,
+ },
+ [0x10B71]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER SHIN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B71,
+ },
+ [0x10B72]={
+ category="lo",
+ description="INSCRIPTIONAL PAHLAVI LETTER TAW",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B72,
+ },
+ [0x10B78]={
+ category="no",
+ description="INSCRIPTIONAL PAHLAVI NUMBER ONE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B78,
+ },
+ [0x10B79]={
+ category="no",
+ description="INSCRIPTIONAL PAHLAVI NUMBER TWO",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B79,
+ },
+ [0x10B7A]={
+ category="no",
+ description="INSCRIPTIONAL PAHLAVI NUMBER THREE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B7A,
+ },
+ [0x10B7B]={
+ category="no",
+ description="INSCRIPTIONAL PAHLAVI NUMBER FOUR",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B7B,
+ },
+ [0x10B7C]={
+ category="no",
+ description="INSCRIPTIONAL PAHLAVI NUMBER TEN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B7C,
+ },
+ [0x10B7D]={
+ category="no",
+ description="INSCRIPTIONAL PAHLAVI NUMBER TWENTY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B7D,
+ },
+ [0x10B7E]={
+ category="no",
+ description="INSCRIPTIONAL PAHLAVI NUMBER ONE HUNDRED",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B7E,
+ },
+ [0x10B7F]={
+ category="no",
+ description="INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10B7F,
+ },
+ [0x10C00]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON A",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C00,
+ },
+ [0x10C01]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI A",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C01,
+ },
+ [0x10C02]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C02,
+ },
+ [0x10C03]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON I",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C03,
+ },
+ [0x10C04]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI I",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C04,
+ },
+ [0x10C05]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI E",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C05,
+ },
+ [0x10C06]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON O",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C06,
+ },
+ [0x10C07]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON OE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C07,
+ },
+ [0x10C08]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI OE",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C08,
+ },
+ [0x10C09]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AB",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C09,
+ },
+ [0x10C0A]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AB",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C0A,
+ },
+ [0x10C0B]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AEB",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C0B,
+ },
+ [0x10C0C]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AEB",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C0C,
+ },
+ [0x10C0D]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AG",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C0D,
+ },
+ [0x10C0E]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AG",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C0E,
+ },
+ [0x10C0F]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AEG",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C0F,
+ },
+ [0x10C10]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AEG",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C10,
+ },
+ [0x10C11]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AD",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C11,
+ },
+ [0x10C12]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AD",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C12,
+ },
+ [0x10C13]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AED",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C13,
+ },
+ [0x10C14]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON EZ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C14,
+ },
+ [0x10C15]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI EZ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C15,
+ },
+ [0x10C16]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C16,
+ },
+ [0x10C17]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C17,
+ },
+ [0x10C18]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AEY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C18,
+ },
+ [0x10C19]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AEY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C19,
+ },
+ [0x10C1A]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AEK",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C1A,
+ },
+ [0x10C1B]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AEK",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C1B,
+ },
+ [0x10C1C]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON OEK",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C1C,
+ },
+ [0x10C1D]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI OEK",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C1D,
+ },
+ [0x10C1E]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AL",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C1E,
+ },
+ [0x10C1F]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AL",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C1F,
+ },
+ [0x10C20]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AEL",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C20,
+ },
+ [0x10C21]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON ELT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C21,
+ },
+ [0x10C22]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON EM",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C22,
+ },
+ [0x10C23]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C23,
+ },
+ [0x10C24]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AEN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C24,
+ },
+ [0x10C25]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AEN",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C25,
+ },
+ [0x10C26]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON ENT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C26,
+ },
+ [0x10C27]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI ENT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C27,
+ },
+ [0x10C28]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON ENC",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C28,
+ },
+ [0x10C29]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI ENC",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C29,
+ },
+ [0x10C2A]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON ENY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C2A,
+ },
+ [0x10C2B]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI ENY",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C2B,
+ },
+ [0x10C2C]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI ANG",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C2C,
+ },
+ [0x10C2D]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON ENG",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C2D,
+ },
+ [0x10C2E]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AENG",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C2E,
+ },
+ [0x10C2F]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON EP",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C2F,
+ },
+ [0x10C30]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON OP",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C30,
+ },
+ [0x10C31]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON IC",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C31,
+ },
+ [0x10C32]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON EC",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C32,
+ },
+ [0x10C33]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI EC",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C33,
+ },
+ [0x10C34]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AQ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C34,
+ },
+ [0x10C35]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AQ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C35,
+ },
+ [0x10C36]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON IQ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C36,
+ },
+ [0x10C37]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI IQ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C37,
+ },
+ [0x10C38]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON OQ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C38,
+ },
+ [0x10C39]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI OQ",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C39,
+ },
+ [0x10C3A]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AR",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C3A,
+ },
+ [0x10C3B]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AR",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C3B,
+ },
+ [0x10C3C]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AER",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C3C,
+ },
+ [0x10C3D]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AS",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C3D,
+ },
+ [0x10C3E]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AES",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C3E,
+ },
+ [0x10C3F]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON ASH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C3F,
+ },
+ [0x10C40]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI ASH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C40,
+ },
+ [0x10C41]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON ESH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C41,
+ },
+ [0x10C42]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI ESH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C42,
+ },
+ [0x10C43]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C43,
+ },
+ [0x10C44]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C44,
+ },
+ [0x10C45]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON AET",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C45,
+ },
+ [0x10C46]={
+ category="lo",
+ description="OLD TURKIC LETTER YENISEI AET",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C46,
+ },
+ [0x10C47]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON OT",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C47,
+ },
+ [0x10C48]={
+ category="lo",
+ description="OLD TURKIC LETTER ORKHON BASH",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10C48,
+ },
+ [0x10E60]={
+ category="no",
+ description="RUMI DIGIT ONE",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E60,
+ },
+ [0x10E61]={
+ category="no",
+ description="RUMI DIGIT TWO",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E61,
+ },
+ [0x10E62]={
+ category="no",
+ description="RUMI DIGIT THREE",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E62,
+ },
+ [0x10E63]={
+ category="no",
+ description="RUMI DIGIT FOUR",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E63,
+ },
+ [0x10E64]={
+ category="no",
+ description="RUMI DIGIT FIVE",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E64,
+ },
+ [0x10E65]={
+ category="no",
+ description="RUMI DIGIT SIX",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E65,
+ },
+ [0x10E66]={
+ category="no",
+ description="RUMI DIGIT SEVEN",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E66,
+ },
+ [0x10E67]={
+ category="no",
+ description="RUMI DIGIT EIGHT",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E67,
+ },
+ [0x10E68]={
+ category="no",
+ description="RUMI DIGIT NINE",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E68,
+ },
+ [0x10E69]={
+ category="no",
+ description="RUMI NUMBER TEN",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E69,
+ },
+ [0x10E6A]={
+ category="no",
+ description="RUMI NUMBER TWENTY",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E6A,
+ },
+ [0x10E6B]={
+ category="no",
+ description="RUMI NUMBER THIRTY",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E6B,
+ },
+ [0x10E6C]={
+ category="no",
+ description="RUMI NUMBER FORTY",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E6C,
+ },
+ [0x10E6D]={
+ category="no",
+ description="RUMI NUMBER FIFTY",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E6D,
+ },
+ [0x10E6E]={
+ category="no",
+ description="RUMI NUMBER SIXTY",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E6E,
+ },
+ [0x10E6F]={
+ category="no",
+ description="RUMI NUMBER SEVENTY",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E6F,
+ },
+ [0x10E70]={
+ category="no",
+ description="RUMI NUMBER EIGHTY",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E70,
+ },
+ [0x10E71]={
+ category="no",
+ description="RUMI NUMBER NINETY",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E71,
+ },
+ [0x10E72]={
+ category="no",
+ description="RUMI NUMBER ONE HUNDRED",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E72,
+ },
+ [0x10E73]={
+ category="no",
+ description="RUMI NUMBER TWO HUNDRED",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E73,
+ },
+ [0x10E74]={
+ category="no",
+ description="RUMI NUMBER THREE HUNDRED",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E74,
+ },
+ [0x10E75]={
+ category="no",
+ description="RUMI NUMBER FOUR HUNDRED",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E75,
+ },
+ [0x10E76]={
+ category="no",
+ description="RUMI NUMBER FIVE HUNDRED",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E76,
+ },
+ [0x10E77]={
+ category="no",
+ description="RUMI NUMBER SIX HUNDRED",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E77,
+ },
+ [0x10E78]={
+ category="no",
+ description="RUMI NUMBER SEVEN HUNDRED",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E78,
+ },
+ [0x10E79]={
+ category="no",
+ description="RUMI NUMBER EIGHT HUNDRED",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E79,
+ },
+ [0x10E7A]={
+ category="no",
+ description="RUMI NUMBER NINE HUNDRED",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E7A,
+ },
+ [0x10E7B]={
+ category="no",
+ description="RUMI FRACTION ONE HALF",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E7B,
+ },
+ [0x10E7C]={
+ category="no",
+ description="RUMI FRACTION ONE QUARTER",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E7C,
+ },
+ [0x10E7D]={
+ category="no",
+ description="RUMI FRACTION ONE THIRD",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E7D,
+ },
+ [0x10E7E]={
+ category="no",
+ description="RUMI FRACTION TWO THIRDS",
+ direction="an",
+ linebreak="al",
+ unicodeslot=0x10E7E,
+ },
+ [0x11000]={
+ category="mc",
+ description="BRAHMI SIGN CANDRABINDU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11000,
+ },
+ [0x11001]={
+ category="mn",
+ description="BRAHMI SIGN ANUSVARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11001,
+ },
+ [0x11002]={
+ category="mc",
+ description="BRAHMI SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11002,
+ },
+ [0x11003]={
+ category="lo",
+ description="BRAHMI SIGN JIHVAMULIYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11003,
+ },
+ [0x11004]={
+ category="lo",
+ description="BRAHMI SIGN UPADHMANIYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11004,
+ },
+ [0x11005]={
+ category="lo",
+ description="BRAHMI LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11005,
+ },
+ [0x11006]={
+ category="lo",
+ description="BRAHMI LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11006,
+ },
+ [0x11007]={
+ category="lo",
+ description="BRAHMI LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11007,
+ },
+ [0x11008]={
+ category="lo",
+ description="BRAHMI LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11008,
+ },
+ [0x11009]={
+ category="lo",
+ description="BRAHMI LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11009,
+ },
+ [0x1100A]={
+ category="lo",
+ description="BRAHMI LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1100A,
+ },
+ [0x1100B]={
+ category="lo",
+ description="BRAHMI LETTER VOCALIC R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1100B,
+ },
+ [0x1100C]={
+ category="lo",
+ description="BRAHMI LETTER VOCALIC RR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1100C,
+ },
+ [0x1100D]={
+ category="lo",
+ description="BRAHMI LETTER VOCALIC L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1100D,
+ },
+ [0x1100E]={
+ category="lo",
+ description="BRAHMI LETTER VOCALIC LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1100E,
+ },
+ [0x1100F]={
+ category="lo",
+ description="BRAHMI LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1100F,
+ },
+ [0x11010]={
+ category="lo",
+ description="BRAHMI LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11010,
+ },
+ [0x11011]={
+ category="lo",
+ description="BRAHMI LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11011,
+ },
+ [0x11012]={
+ category="lo",
+ description="BRAHMI LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11012,
+ },
+ [0x11013]={
+ category="lo",
+ description="BRAHMI LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11013,
+ },
+ [0x11014]={
+ category="lo",
+ description="BRAHMI LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11014,
+ },
+ [0x11015]={
+ category="lo",
+ description="BRAHMI LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11015,
+ },
+ [0x11016]={
+ category="lo",
+ description="BRAHMI LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11016,
+ },
+ [0x11017]={
+ category="lo",
+ description="BRAHMI LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11017,
+ },
+ [0x11018]={
+ category="lo",
+ description="BRAHMI LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11018,
+ },
+ [0x11019]={
+ category="lo",
+ description="BRAHMI LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11019,
+ },
+ [0x1101A]={
+ category="lo",
+ description="BRAHMI LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1101A,
+ },
+ [0x1101B]={
+ category="lo",
+ description="BRAHMI LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1101B,
+ },
+ [0x1101C]={
+ category="lo",
+ description="BRAHMI LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1101C,
+ },
+ [0x1101D]={
+ category="lo",
+ description="BRAHMI LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1101D,
+ },
+ [0x1101E]={
+ category="lo",
+ description="BRAHMI LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1101E,
+ },
+ [0x1101F]={
+ category="lo",
+ description="BRAHMI LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1101F,
+ },
+ [0x11020]={
+ category="lo",
+ description="BRAHMI LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11020,
+ },
+ [0x11021]={
+ category="lo",
+ description="BRAHMI LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11021,
+ },
+ [0x11022]={
+ category="lo",
+ description="BRAHMI LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11022,
+ },
+ [0x11023]={
+ category="lo",
+ description="BRAHMI LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11023,
+ },
+ [0x11024]={
+ category="lo",
+ description="BRAHMI LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11024,
+ },
+ [0x11025]={
+ category="lo",
+ description="BRAHMI LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11025,
+ },
+ [0x11026]={
+ category="lo",
+ description="BRAHMI LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11026,
+ },
+ [0x11027]={
+ category="lo",
+ description="BRAHMI LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11027,
+ },
+ [0x11028]={
+ category="lo",
+ description="BRAHMI LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11028,
+ },
+ [0x11029]={
+ category="lo",
+ description="BRAHMI LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11029,
+ },
+ [0x1102A]={
+ category="lo",
+ description="BRAHMI LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1102A,
+ },
+ [0x1102B]={
+ category="lo",
+ description="BRAHMI LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1102B,
+ },
+ [0x1102C]={
+ category="lo",
+ description="BRAHMI LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1102C,
+ },
+ [0x1102D]={
+ category="lo",
+ description="BRAHMI LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1102D,
+ },
+ [0x1102E]={
+ category="lo",
+ description="BRAHMI LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1102E,
+ },
+ [0x1102F]={
+ category="lo",
+ description="BRAHMI LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1102F,
+ },
+ [0x11030]={
+ category="lo",
+ description="BRAHMI LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11030,
+ },
+ [0x11031]={
+ category="lo",
+ description="BRAHMI LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11031,
+ },
+ [0x11032]={
+ category="lo",
+ description="BRAHMI LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11032,
+ },
+ [0x11033]={
+ category="lo",
+ description="BRAHMI LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11033,
+ },
+ [0x11034]={
+ category="lo",
+ description="BRAHMI LETTER LLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11034,
+ },
+ [0x11035]={
+ category="lo",
+ description="BRAHMI LETTER OLD TAMIL LLLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11035,
+ },
+ [0x11036]={
+ category="lo",
+ description="BRAHMI LETTER OLD TAMIL RRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11036,
+ },
+ [0x11037]={
+ category="lo",
+ description="BRAHMI LETTER OLD TAMIL NNNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11037,
+ },
+ [0x11038]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN AA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11038,
+ },
+ [0x11039]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN BHATTIPROLU AA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11039,
+ },
+ [0x1103A]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1103A,
+ },
+ [0x1103B]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN II",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1103B,
+ },
+ [0x1103C]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1103C,
+ },
+ [0x1103D]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1103D,
+ },
+ [0x1103E]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN VOCALIC R",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1103E,
+ },
+ [0x1103F]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN VOCALIC RR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1103F,
+ },
+ [0x11040]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN VOCALIC L",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11040,
+ },
+ [0x11041]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN VOCALIC LL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11041,
+ },
+ [0x11042]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11042,
+ },
+ [0x11043]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN AI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11043,
+ },
+ [0x11044]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11044,
+ },
+ [0x11045]={
+ category="mn",
+ description="BRAHMI VOWEL SIGN AU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11045,
+ },
+ [0x11046]={
+ category="mn",
+ description="BRAHMI VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11046,
+ },
+ [0x11047]={
+ category="po",
+ description="BRAHMI DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11047,
+ },
+ [0x11048]={
+ category="po",
+ description="BRAHMI DOUBLE DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11048,
+ },
+ [0x11049]={
+ category="po",
+ description="BRAHMI PUNCTUATION DOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11049,
+ },
+ [0x1104A]={
+ category="po",
+ description="BRAHMI PUNCTUATION DOUBLE DOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1104A,
+ },
+ [0x1104B]={
+ category="po",
+ description="BRAHMI PUNCTUATION LINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1104B,
+ },
+ [0x1104C]={
+ category="po",
+ description="BRAHMI PUNCTUATION CRESCENT BAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1104C,
+ },
+ [0x1104D]={
+ category="po",
+ description="BRAHMI PUNCTUATION LOTUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1104D,
+ },
+ [0x11052]={
+ category="no",
+ description="BRAHMI NUMBER ONE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11052,
+ },
+ [0x11053]={
+ category="no",
+ description="BRAHMI NUMBER TWO",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11053,
+ },
+ [0x11054]={
+ category="no",
+ description="BRAHMI NUMBER THREE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11054,
+ },
+ [0x11055]={
+ category="no",
+ description="BRAHMI NUMBER FOUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11055,
+ },
+ [0x11056]={
+ category="no",
+ description="BRAHMI NUMBER FIVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11056,
+ },
+ [0x11057]={
+ category="no",
+ description="BRAHMI NUMBER SIX",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11057,
+ },
+ [0x11058]={
+ category="no",
+ description="BRAHMI NUMBER SEVEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11058,
+ },
+ [0x11059]={
+ category="no",
+ description="BRAHMI NUMBER EIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11059,
+ },
+ [0x1105A]={
+ category="no",
+ description="BRAHMI NUMBER NINE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1105A,
+ },
+ [0x1105B]={
+ category="no",
+ description="BRAHMI NUMBER TEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1105B,
+ },
+ [0x1105C]={
+ category="no",
+ description="BRAHMI NUMBER TWENTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1105C,
+ },
+ [0x1105D]={
+ category="no",
+ description="BRAHMI NUMBER THIRTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1105D,
+ },
+ [0x1105E]={
+ category="no",
+ description="BRAHMI NUMBER FORTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1105E,
+ },
+ [0x1105F]={
+ category="no",
+ description="BRAHMI NUMBER FIFTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1105F,
+ },
+ [0x11060]={
+ category="no",
+ description="BRAHMI NUMBER SIXTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11060,
+ },
+ [0x11061]={
+ category="no",
+ description="BRAHMI NUMBER SEVENTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11061,
+ },
+ [0x11062]={
+ category="no",
+ description="BRAHMI NUMBER EIGHTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11062,
+ },
+ [0x11063]={
+ category="no",
+ description="BRAHMI NUMBER NINETY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11063,
+ },
+ [0x11064]={
+ category="no",
+ description="BRAHMI NUMBER ONE HUNDRED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11064,
+ },
+ [0x11065]={
+ category="no",
+ description="BRAHMI NUMBER ONE THOUSAND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x11065,
+ },
+ [0x11066]={
+ category="nd",
+ description="BRAHMI DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11066,
+ },
+ [0x11067]={
+ category="nd",
+ description="BRAHMI DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11067,
+ },
+ [0x11068]={
+ category="nd",
+ description="BRAHMI DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11068,
+ },
+ [0x11069]={
+ category="nd",
+ description="BRAHMI DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11069,
+ },
+ [0x1106A]={
+ category="nd",
+ description="BRAHMI DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1106A,
+ },
+ [0x1106B]={
+ category="nd",
+ description="BRAHMI DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1106B,
+ },
+ [0x1106C]={
+ category="nd",
+ description="BRAHMI DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1106C,
+ },
+ [0x1106D]={
+ category="nd",
+ description="BRAHMI DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1106D,
+ },
+ [0x1106E]={
+ category="nd",
+ description="BRAHMI DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1106E,
+ },
+ [0x1106F]={
+ category="nd",
+ description="BRAHMI DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1106F,
+ },
+ [0x11080]={
+ category="mn",
+ description="KAITHI SIGN CANDRABINDU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11080,
+ },
+ [0x11081]={
+ category="mn",
+ description="KAITHI SIGN ANUSVARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11081,
+ },
+ [0x11082]={
+ category="mc",
+ description="KAITHI SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11082,
+ },
+ [0x11083]={
+ category="lo",
+ description="KAITHI LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11083,
+ },
+ [0x11084]={
+ category="lo",
+ description="KAITHI LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11084,
+ },
+ [0x11085]={
+ category="lo",
+ description="KAITHI LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11085,
+ },
+ [0x11086]={
+ category="lo",
+ description="KAITHI LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11086,
+ },
+ [0x11087]={
+ category="lo",
+ description="KAITHI LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11087,
+ },
+ [0x11088]={
+ category="lo",
+ description="KAITHI LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11088,
+ },
+ [0x11089]={
+ category="lo",
+ description="KAITHI LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11089,
+ },
+ [0x1108A]={
+ category="lo",
+ description="KAITHI LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1108A,
+ },
+ [0x1108B]={
+ category="lo",
+ description="KAITHI LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1108B,
+ },
+ [0x1108C]={
+ category="lo",
+ description="KAITHI LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1108C,
+ },
+ [0x1108D]={
+ category="lo",
+ description="KAITHI LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1108D,
+ },
+ [0x1108E]={
+ category="lo",
+ description="KAITHI LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1108E,
+ },
+ [0x1108F]={
+ category="lo",
+ description="KAITHI LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1108F,
+ },
+ [0x11090]={
+ category="lo",
+ description="KAITHI LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11090,
+ },
+ [0x11091]={
+ category="lo",
+ description="KAITHI LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11091,
+ },
+ [0x11092]={
+ category="lo",
+ description="KAITHI LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11092,
+ },
+ [0x11093]={
+ category="lo",
+ description="KAITHI LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11093,
+ },
+ [0x11094]={
+ category="lo",
+ description="KAITHI LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11094,
+ },
+ [0x11095]={
+ category="lo",
+ description="KAITHI LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11095,
+ },
+ [0x11096]={
+ category="lo",
+ description="KAITHI LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11096,
+ },
+ [0x11097]={
+ category="lo",
+ description="KAITHI LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11097,
+ },
+ [0x11098]={
+ category="lo",
+ description="KAITHI LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11098,
+ },
+ [0x11099]={
+ category="lo",
+ description="KAITHI LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11099,
+ },
+ [0x1109A]={
+ category="lo",
+ description="KAITHI LETTER DDDHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x11099, 0x110BA },
+ unicodeslot=0x1109A,
+ },
+ [0x1109B]={
+ category="lo",
+ description="KAITHI LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1109B,
+ },
+ [0x1109C]={
+ category="lo",
+ description="KAITHI LETTER RHA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1109B, 0x110BA },
+ unicodeslot=0x1109C,
+ },
+ [0x1109D]={
+ category="lo",
+ description="KAITHI LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1109D,
+ },
+ [0x1109E]={
+ category="lo",
+ description="KAITHI LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1109E,
+ },
+ [0x1109F]={
+ category="lo",
+ description="KAITHI LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1109F,
+ },
+ [0x110A0]={
+ category="lo",
+ description="KAITHI LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A0,
+ },
+ [0x110A1]={
+ category="lo",
+ description="KAITHI LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A1,
+ },
+ [0x110A2]={
+ category="lo",
+ description="KAITHI LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A2,
+ },
+ [0x110A3]={
+ category="lo",
+ description="KAITHI LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A3,
+ },
+ [0x110A4]={
+ category="lo",
+ description="KAITHI LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A4,
+ },
+ [0x110A5]={
+ category="lo",
+ description="KAITHI LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A5,
+ },
+ [0x110A6]={
+ category="lo",
+ description="KAITHI LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A6,
+ },
+ [0x110A7]={
+ category="lo",
+ description="KAITHI LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A7,
+ },
+ [0x110A8]={
+ category="lo",
+ description="KAITHI LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A8,
+ },
+ [0x110A9]={
+ category="lo",
+ description="KAITHI LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110A9,
+ },
+ [0x110AA]={
+ category="lo",
+ description="KAITHI LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110AA,
+ },
+ [0x110AB]={
+ category="lo",
+ description="KAITHI LETTER VA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x110A5, 0x110BA },
+ unicodeslot=0x110AB,
+ },
+ [0x110AC]={
+ category="lo",
+ description="KAITHI LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110AC,
+ },
+ [0x110AD]={
+ category="lo",
+ description="KAITHI LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110AD,
+ },
+ [0x110AE]={
+ category="lo",
+ description="KAITHI LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110AE,
+ },
+ [0x110AF]={
+ category="lo",
+ description="KAITHI LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110AF,
+ },
+ [0x110B0]={
+ category="mc",
+ description="KAITHI VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x110B0,
+ },
+ [0x110B1]={
+ category="mc",
+ description="KAITHI VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x110B1,
+ },
+ [0x110B2]={
+ category="mc",
+ description="KAITHI VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x110B2,
+ },
+ [0x110B3]={
+ category="mn",
+ description="KAITHI VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x110B3,
+ },
+ [0x110B4]={
+ category="mn",
+ description="KAITHI VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x110B4,
+ },
+ [0x110B5]={
+ category="mn",
+ description="KAITHI VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x110B5,
+ },
+ [0x110B6]={
+ category="mn",
+ description="KAITHI VOWEL SIGN AI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x110B6,
+ },
+ [0x110B7]={
+ category="mc",
+ description="KAITHI VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x110B7,
+ },
+ [0x110B8]={
+ category="mc",
+ description="KAITHI VOWEL SIGN AU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x110B8,
+ },
+ [0x110B9]={
+ category="mn",
+ description="KAITHI SIGN VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x110B9,
+ },
+ [0x110BA]={
+ category="mn",
+ description="KAITHI SIGN NUKTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x110BA,
+ },
+ [0x110BB]={
+ category="po",
+ description="KAITHI ABBREVIATION SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110BB,
+ },
+ [0x110BC]={
+ category="po",
+ description="KAITHI ENUMERATION SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110BC,
+ },
+ [0x110BD]={
+ category="cf",
+ description="KAITHI NUMBER SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110BD,
+ },
+ [0x110BE]={
+ category="po",
+ description="KAITHI SECTION MARK",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x110BE,
+ },
+ [0x110BF]={
+ category="po",
+ description="KAITHI DOUBLE SECTION MARK",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x110BF,
+ },
+ [0x110C0]={
+ category="po",
+ description="KAITHI DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x110C0,
+ },
+ [0x110C1]={
+ category="po",
+ description="KAITHI DOUBLE DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x110C1,
+ },
+ [0x110D0]={
+ category="lo",
+ description="SORA SOMPENG LETTER SAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D0,
+ },
+ [0x110D1]={
+ category="lo",
+ description="SORA SOMPENG LETTER TAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D1,
+ },
+ [0x110D2]={
+ category="lo",
+ description="SORA SOMPENG LETTER BAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D2,
+ },
+ [0x110D3]={
+ category="lo",
+ description="SORA SOMPENG LETTER CAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D3,
+ },
+ [0x110D4]={
+ category="lo",
+ description="SORA SOMPENG LETTER DAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D4,
+ },
+ [0x110D5]={
+ category="lo",
+ description="SORA SOMPENG LETTER GAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D5,
+ },
+ [0x110D6]={
+ category="lo",
+ description="SORA SOMPENG LETTER MAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D6,
+ },
+ [0x110D7]={
+ category="lo",
+ description="SORA SOMPENG LETTER NGAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D7,
+ },
+ [0x110D8]={
+ category="lo",
+ description="SORA SOMPENG LETTER LAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D8,
+ },
+ [0x110D9]={
+ category="lo",
+ description="SORA SOMPENG LETTER NAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110D9,
+ },
+ [0x110DA]={
+ category="lo",
+ description="SORA SOMPENG LETTER VAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110DA,
+ },
+ [0x110DB]={
+ category="lo",
+ description="SORA SOMPENG LETTER PAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110DB,
+ },
+ [0x110DC]={
+ category="lo",
+ description="SORA SOMPENG LETTER YAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110DC,
+ },
+ [0x110DD]={
+ category="lo",
+ description="SORA SOMPENG LETTER RAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110DD,
+ },
+ [0x110DE]={
+ category="lo",
+ description="SORA SOMPENG LETTER HAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110DE,
+ },
+ [0x110DF]={
+ category="lo",
+ description="SORA SOMPENG LETTER KAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110DF,
+ },
+ [0x110E0]={
+ category="lo",
+ description="SORA SOMPENG LETTER JAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E0,
+ },
+ [0x110E1]={
+ category="lo",
+ description="SORA SOMPENG LETTER NYAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E1,
+ },
+ [0x110E2]={
+ category="lo",
+ description="SORA SOMPENG LETTER AH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E2,
+ },
+ [0x110E3]={
+ category="lo",
+ description="SORA SOMPENG LETTER EEH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E3,
+ },
+ [0x110E4]={
+ category="lo",
+ description="SORA SOMPENG LETTER IH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E4,
+ },
+ [0x110E5]={
+ category="lo",
+ description="SORA SOMPENG LETTER UH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E5,
+ },
+ [0x110E6]={
+ category="lo",
+ description="SORA SOMPENG LETTER OH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E6,
+ },
+ [0x110E7]={
+ category="lo",
+ description="SORA SOMPENG LETTER EH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E7,
+ },
+ [0x110E8]={
+ category="lo",
+ description="SORA SOMPENG LETTER MAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x110E8,
+ },
+ [0x110F0]={
+ category="nd",
+ description="SORA SOMPENG DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F0,
+ },
+ [0x110F1]={
+ category="nd",
+ description="SORA SOMPENG DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F1,
+ },
+ [0x110F2]={
+ category="nd",
+ description="SORA SOMPENG DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F2,
+ },
+ [0x110F3]={
+ category="nd",
+ description="SORA SOMPENG DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F3,
+ },
+ [0x110F4]={
+ category="nd",
+ description="SORA SOMPENG DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F4,
+ },
+ [0x110F5]={
+ category="nd",
+ description="SORA SOMPENG DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F5,
+ },
+ [0x110F6]={
+ category="nd",
+ description="SORA SOMPENG DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F6,
+ },
+ [0x110F7]={
+ category="nd",
+ description="SORA SOMPENG DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F7,
+ },
+ [0x110F8]={
+ category="nd",
+ description="SORA SOMPENG DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F8,
+ },
+ [0x110F9]={
+ category="nd",
+ description="SORA SOMPENG DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x110F9,
+ },
+ [0x11100]={
+ category="mn",
+ description="CHAKMA SIGN CANDRABINDU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11100,
+ },
+ [0x11101]={
+ category="mn",
+ description="CHAKMA SIGN ANUSVARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11101,
+ },
+ [0x11102]={
+ category="mn",
+ description="CHAKMA SIGN VISARGA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11102,
+ },
+ [0x11103]={
+ category="lo",
+ description="CHAKMA LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11103,
+ },
+ [0x11104]={
+ category="lo",
+ description="CHAKMA LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11104,
+ },
+ [0x11105]={
+ category="lo",
+ description="CHAKMA LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11105,
+ },
+ [0x11106]={
+ category="lo",
+ description="CHAKMA LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11106,
+ },
+ [0x11107]={
+ category="lo",
+ description="CHAKMA LETTER KAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11107,
+ },
+ [0x11108]={
+ category="lo",
+ description="CHAKMA LETTER KHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11108,
+ },
+ [0x11109]={
+ category="lo",
+ description="CHAKMA LETTER GAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11109,
+ },
+ [0x1110A]={
+ category="lo",
+ description="CHAKMA LETTER GHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1110A,
+ },
+ [0x1110B]={
+ category="lo",
+ description="CHAKMA LETTER NGAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1110B,
+ },
+ [0x1110C]={
+ category="lo",
+ description="CHAKMA LETTER CAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1110C,
+ },
+ [0x1110D]={
+ category="lo",
+ description="CHAKMA LETTER CHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1110D,
+ },
+ [0x1110E]={
+ category="lo",
+ description="CHAKMA LETTER JAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1110E,
+ },
+ [0x1110F]={
+ category="lo",
+ description="CHAKMA LETTER JHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1110F,
+ },
+ [0x11110]={
+ category="lo",
+ description="CHAKMA LETTER NYAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11110,
+ },
+ [0x11111]={
+ category="lo",
+ description="CHAKMA LETTER TTAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11111,
+ },
+ [0x11112]={
+ category="lo",
+ description="CHAKMA LETTER TTHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11112,
+ },
+ [0x11113]={
+ category="lo",
+ description="CHAKMA LETTER DDAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11113,
+ },
+ [0x11114]={
+ category="lo",
+ description="CHAKMA LETTER DDHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11114,
+ },
+ [0x11115]={
+ category="lo",
+ description="CHAKMA LETTER NNAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11115,
+ },
+ [0x11116]={
+ category="lo",
+ description="CHAKMA LETTER TAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11116,
+ },
+ [0x11117]={
+ category="lo",
+ description="CHAKMA LETTER THAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11117,
+ },
+ [0x11118]={
+ category="lo",
+ description="CHAKMA LETTER DAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11118,
+ },
+ [0x11119]={
+ category="lo",
+ description="CHAKMA LETTER DHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11119,
+ },
+ [0x1111A]={
+ category="lo",
+ description="CHAKMA LETTER NAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1111A,
+ },
+ [0x1111B]={
+ category="lo",
+ description="CHAKMA LETTER PAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1111B,
+ },
+ [0x1111C]={
+ category="lo",
+ description="CHAKMA LETTER PHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1111C,
+ },
+ [0x1111D]={
+ category="lo",
+ description="CHAKMA LETTER BAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1111D,
+ },
+ [0x1111E]={
+ category="lo",
+ description="CHAKMA LETTER BHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1111E,
+ },
+ [0x1111F]={
+ category="lo",
+ description="CHAKMA LETTER MAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1111F,
+ },
+ [0x11120]={
+ category="lo",
+ description="CHAKMA LETTER YYAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11120,
+ },
+ [0x11121]={
+ category="lo",
+ description="CHAKMA LETTER YAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11121,
+ },
+ [0x11122]={
+ category="lo",
+ description="CHAKMA LETTER RAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11122,
+ },
+ [0x11123]={
+ category="lo",
+ description="CHAKMA LETTER LAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11123,
+ },
+ [0x11124]={
+ category="lo",
+ description="CHAKMA LETTER WAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11124,
+ },
+ [0x11125]={
+ category="lo",
+ description="CHAKMA LETTER SAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11125,
+ },
+ [0x11126]={
+ category="lo",
+ description="CHAKMA LETTER HAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11126,
+ },
+ [0x11127]={
+ category="mn",
+ description="CHAKMA VOWEL SIGN A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11127,
+ },
+ [0x11128]={
+ category="mn",
+ description="CHAKMA VOWEL SIGN I",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11128,
+ },
+ [0x11129]={
+ category="mn",
+ description="CHAKMA VOWEL SIGN II",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11129,
+ },
+ [0x1112A]={
+ category="mn",
+ description="CHAKMA VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1112A,
+ },
+ [0x1112B]={
+ category="mn",
+ description="CHAKMA VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1112B,
+ },
+ [0x1112C]={
+ category="mc",
+ description="CHAKMA VOWEL SIGN E",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1112C,
+ },
+ [0x1112D]={
+ category="mn",
+ description="CHAKMA VOWEL SIGN AI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1112D,
+ },
+ [0x1112E]={
+ category="mn",
+ description="CHAKMA VOWEL SIGN O",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x11131, 0x11127 },
+ unicodeslot=0x1112E,
+ },
+ [0x1112F]={
+ category="mn",
+ description="CHAKMA VOWEL SIGN AU",
+ direction="nsm",
+ linebreak="cm",
+ specials={ "char", 0x11132, 0x11127 },
+ unicodeslot=0x1112F,
+ },
+ [0x11130]={
+ category="mn",
+ description="CHAKMA VOWEL SIGN OI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11130,
+ },
+ [0x11131]={
+ category="mn",
+ description="CHAKMA O MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11131,
+ },
+ [0x11132]={
+ category="mn",
+ description="CHAKMA AU MARK",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11132,
+ },
+ [0x11133]={
+ category="mn",
+ description="CHAKMA VIRAMA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11133,
+ },
+ [0x11134]={
+ category="mn",
+ description="CHAKMA MAAYYAA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11134,
+ },
+ [0x11136]={
+ category="nd",
+ description="CHAKMA DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11136,
+ },
+ [0x11137]={
+ category="nd",
+ description="CHAKMA DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11137,
+ },
+ [0x11138]={
+ category="nd",
+ description="CHAKMA DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11138,
+ },
+ [0x11139]={
+ category="nd",
+ description="CHAKMA DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11139,
+ },
+ [0x1113A]={
+ category="nd",
+ description="CHAKMA DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1113A,
+ },
+ [0x1113B]={
+ category="nd",
+ description="CHAKMA DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1113B,
+ },
+ [0x1113C]={
+ category="nd",
+ description="CHAKMA DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1113C,
+ },
+ [0x1113D]={
+ category="nd",
+ description="CHAKMA DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1113D,
+ },
+ [0x1113E]={
+ category="nd",
+ description="CHAKMA DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1113E,
+ },
+ [0x1113F]={
+ category="nd",
+ description="CHAKMA DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x1113F,
+ },
+ [0x11140]={
+ category="po",
+ description="CHAKMA SECTION MARK",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11140,
+ },
+ [0x11141]={
+ category="po",
+ description="CHAKMA DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11141,
+ },
+ [0x11142]={
+ category="po",
+ description="CHAKMA DOUBLE DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11142,
+ },
+ [0x11143]={
+ category="po",
+ description="CHAKMA QUESTION MARK",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11143,
+ },
+ [0x11180]={
+ category="mn",
+ description="SHARADA SIGN CANDRABINDU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11180,
+ },
+ [0x11181]={
+ category="mn",
+ description="SHARADA SIGN ANUSVARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11181,
+ },
+ [0x11182]={
+ category="mc",
+ description="SHARADA SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11182,
+ },
+ [0x11183]={
+ category="lo",
+ description="SHARADA LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11183,
+ },
+ [0x11184]={
+ category="lo",
+ description="SHARADA LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11184,
+ },
+ [0x11185]={
+ category="lo",
+ description="SHARADA LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11185,
+ },
+ [0x11186]={
+ category="lo",
+ description="SHARADA LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11186,
+ },
+ [0x11187]={
+ category="lo",
+ description="SHARADA LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11187,
+ },
+ [0x11188]={
+ category="lo",
+ description="SHARADA LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11188,
+ },
+ [0x11189]={
+ category="lo",
+ description="SHARADA LETTER VOCALIC R",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11189,
+ },
+ [0x1118A]={
+ category="lo",
+ description="SHARADA LETTER VOCALIC RR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1118A,
+ },
+ [0x1118B]={
+ category="lo",
+ description="SHARADA LETTER VOCALIC L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1118B,
+ },
+ [0x1118C]={
+ category="lo",
+ description="SHARADA LETTER VOCALIC LL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1118C,
+ },
+ [0x1118D]={
+ category="lo",
+ description="SHARADA LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1118D,
+ },
+ [0x1118E]={
+ category="lo",
+ description="SHARADA LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1118E,
+ },
+ [0x1118F]={
+ category="lo",
+ description="SHARADA LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1118F,
+ },
+ [0x11190]={
+ category="lo",
+ description="SHARADA LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11190,
+ },
+ [0x11191]={
+ category="lo",
+ description="SHARADA LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11191,
+ },
+ [0x11192]={
+ category="lo",
+ description="SHARADA LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11192,
+ },
+ [0x11193]={
+ category="lo",
+ description="SHARADA LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11193,
+ },
+ [0x11194]={
+ category="lo",
+ description="SHARADA LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11194,
+ },
+ [0x11195]={
+ category="lo",
+ description="SHARADA LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11195,
+ },
+ [0x11196]={
+ category="lo",
+ description="SHARADA LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11196,
+ },
+ [0x11197]={
+ category="lo",
+ description="SHARADA LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11197,
+ },
+ [0x11198]={
+ category="lo",
+ description="SHARADA LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11198,
+ },
+ [0x11199]={
+ category="lo",
+ description="SHARADA LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11199,
+ },
+ [0x1119A]={
+ category="lo",
+ description="SHARADA LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1119A,
+ },
+ [0x1119B]={
+ category="lo",
+ description="SHARADA LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1119B,
+ },
+ [0x1119C]={
+ category="lo",
+ description="SHARADA LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1119C,
+ },
+ [0x1119D]={
+ category="lo",
+ description="SHARADA LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1119D,
+ },
+ [0x1119E]={
+ category="lo",
+ description="SHARADA LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1119E,
+ },
+ [0x1119F]={
+ category="lo",
+ description="SHARADA LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1119F,
+ },
+ [0x111A0]={
+ category="lo",
+ description="SHARADA LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A0,
+ },
+ [0x111A1]={
+ category="lo",
+ description="SHARADA LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A1,
+ },
+ [0x111A2]={
+ category="lo",
+ description="SHARADA LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A2,
+ },
+ [0x111A3]={
+ category="lo",
+ description="SHARADA LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A3,
+ },
+ [0x111A4]={
+ category="lo",
+ description="SHARADA LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A4,
+ },
+ [0x111A5]={
+ category="lo",
+ description="SHARADA LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A5,
+ },
+ [0x111A6]={
+ category="lo",
+ description="SHARADA LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A6,
+ },
+ [0x111A7]={
+ category="lo",
+ description="SHARADA LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A7,
+ },
+ [0x111A8]={
+ category="lo",
+ description="SHARADA LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A8,
+ },
+ [0x111A9]={
+ category="lo",
+ description="SHARADA LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111A9,
+ },
+ [0x111AA]={
+ category="lo",
+ description="SHARADA LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111AA,
+ },
+ [0x111AB]={
+ category="lo",
+ description="SHARADA LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111AB,
+ },
+ [0x111AC]={
+ category="lo",
+ description="SHARADA LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111AC,
+ },
+ [0x111AD]={
+ category="lo",
+ description="SHARADA LETTER LLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111AD,
+ },
+ [0x111AE]={
+ category="lo",
+ description="SHARADA LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111AE,
+ },
+ [0x111AF]={
+ category="lo",
+ description="SHARADA LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111AF,
+ },
+ [0x111B0]={
+ category="lo",
+ description="SHARADA LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111B0,
+ },
+ [0x111B1]={
+ category="lo",
+ description="SHARADA LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111B1,
+ },
+ [0x111B2]={
+ category="lo",
+ description="SHARADA LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111B2,
+ },
+ [0x111B3]={
+ category="mc",
+ description="SHARADA VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x111B3,
+ },
+ [0x111B4]={
+ category="mc",
+ description="SHARADA VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x111B4,
+ },
+ [0x111B5]={
+ category="mc",
+ description="SHARADA VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x111B5,
+ },
+ [0x111B6]={
+ category="mn",
+ description="SHARADA VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111B6,
+ },
+ [0x111B7]={
+ category="mn",
+ description="SHARADA VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111B7,
+ },
+ [0x111B8]={
+ category="mn",
+ description="SHARADA VOWEL SIGN VOCALIC R",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111B8,
+ },
+ [0x111B9]={
+ category="mn",
+ description="SHARADA VOWEL SIGN VOCALIC RR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111B9,
+ },
+ [0x111BA]={
+ category="mn",
+ description="SHARADA VOWEL SIGN VOCALIC L",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111BA,
+ },
+ [0x111BB]={
+ category="mn",
+ description="SHARADA VOWEL SIGN VOCALIC LL",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111BB,
+ },
+ [0x111BC]={
+ category="mn",
+ description="SHARADA VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111BC,
+ },
+ [0x111BD]={
+ category="mn",
+ description="SHARADA VOWEL SIGN AI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111BD,
+ },
+ [0x111BE]={
+ category="mn",
+ description="SHARADA VOWEL SIGN O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111BE,
+ },
+ [0x111BF]={
+ category="mc",
+ description="SHARADA VOWEL SIGN AU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x111BF,
+ },
+ [0x111C0]={
+ category="mc",
+ description="SHARADA SIGN VIRAMA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x111C0,
+ },
+ [0x111C1]={
+ category="lo",
+ description="SHARADA SIGN AVAGRAHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111C1,
+ },
+ [0x111C2]={
+ category="lo",
+ description="SHARADA SIGN JIHVAMULIYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111C2,
+ },
+ [0x111C3]={
+ category="lo",
+ description="SHARADA SIGN UPADHMANIYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111C3,
+ },
+ [0x111C4]={
+ category="lo",
+ description="SHARADA OM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111C4,
+ },
+ [0x111C5]={
+ category="po",
+ description="SHARADA DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x111C5,
+ },
+ [0x111C6]={
+ category="po",
+ description="SHARADA DOUBLE DANDA",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x111C6,
+ },
+ [0x111C7]={
+ category="po",
+ description="SHARADA ABBREVIATION SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x111C7,
+ },
+ [0x111C8]={
+ category="po",
+ description="SHARADA SEPARATOR",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x111C8,
+ },
+ [0x111D0]={
+ category="nd",
+ description="SHARADA DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D0,
+ },
+ [0x111D1]={
+ category="nd",
+ description="SHARADA DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D1,
+ },
+ [0x111D2]={
+ category="nd",
+ description="SHARADA DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D2,
+ },
+ [0x111D3]={
+ category="nd",
+ description="SHARADA DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D3,
+ },
+ [0x111D4]={
+ category="nd",
+ description="SHARADA DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D4,
+ },
+ [0x111D5]={
+ category="nd",
+ description="SHARADA DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D5,
+ },
+ [0x111D6]={
+ category="nd",
+ description="SHARADA DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D6,
+ },
+ [0x111D7]={
+ category="nd",
+ description="SHARADA DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D7,
+ },
+ [0x111D8]={
+ category="nd",
+ description="SHARADA DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D8,
+ },
+ [0x111D9]={
+ category="nd",
+ description="SHARADA DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x111D9,
+ },
+ [0x11680]={
+ category="lo",
+ description="TAKRI LETTER A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11680,
+ },
+ [0x11681]={
+ category="lo",
+ description="TAKRI LETTER AA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11681,
+ },
+ [0x11682]={
+ category="lo",
+ description="TAKRI LETTER I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11682,
+ },
+ [0x11683]={
+ category="lo",
+ description="TAKRI LETTER II",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11683,
+ },
+ [0x11684]={
+ category="lo",
+ description="TAKRI LETTER U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11684,
+ },
+ [0x11685]={
+ category="lo",
+ description="TAKRI LETTER UU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11685,
+ },
+ [0x11686]={
+ category="lo",
+ description="TAKRI LETTER E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11686,
+ },
+ [0x11687]={
+ category="lo",
+ description="TAKRI LETTER AI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11687,
+ },
+ [0x11688]={
+ category="lo",
+ description="TAKRI LETTER O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11688,
+ },
+ [0x11689]={
+ category="lo",
+ description="TAKRI LETTER AU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11689,
+ },
+ [0x1168A]={
+ category="lo",
+ description="TAKRI LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1168A,
+ },
+ [0x1168B]={
+ category="lo",
+ description="TAKRI LETTER KHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1168B,
+ },
+ [0x1168C]={
+ category="lo",
+ description="TAKRI LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1168C,
+ },
+ [0x1168D]={
+ category="lo",
+ description="TAKRI LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1168D,
+ },
+ [0x1168E]={
+ category="lo",
+ description="TAKRI LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1168E,
+ },
+ [0x1168F]={
+ category="lo",
+ description="TAKRI LETTER CA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1168F,
+ },
+ [0x11690]={
+ category="lo",
+ description="TAKRI LETTER CHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11690,
+ },
+ [0x11691]={
+ category="lo",
+ description="TAKRI LETTER JA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11691,
+ },
+ [0x11692]={
+ category="lo",
+ description="TAKRI LETTER JHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11692,
+ },
+ [0x11693]={
+ category="lo",
+ description="TAKRI LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11693,
+ },
+ [0x11694]={
+ category="lo",
+ description="TAKRI LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11694,
+ },
+ [0x11695]={
+ category="lo",
+ description="TAKRI LETTER TTHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11695,
+ },
+ [0x11696]={
+ category="lo",
+ description="TAKRI LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11696,
+ },
+ [0x11697]={
+ category="lo",
+ description="TAKRI LETTER DDHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11697,
+ },
+ [0x11698]={
+ category="lo",
+ description="TAKRI LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11698,
+ },
+ [0x11699]={
+ category="lo",
+ description="TAKRI LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11699,
+ },
+ [0x1169A]={
+ category="lo",
+ description="TAKRI LETTER THA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1169A,
+ },
+ [0x1169B]={
+ category="lo",
+ description="TAKRI LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1169B,
+ },
+ [0x1169C]={
+ category="lo",
+ description="TAKRI LETTER DHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1169C,
+ },
+ [0x1169D]={
+ category="lo",
+ description="TAKRI LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1169D,
+ },
+ [0x1169E]={
+ category="lo",
+ description="TAKRI LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1169E,
+ },
+ [0x1169F]={
+ category="lo",
+ description="TAKRI LETTER PHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1169F,
+ },
+ [0x116A0]={
+ category="lo",
+ description="TAKRI LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A0,
+ },
+ [0x116A1]={
+ category="lo",
+ description="TAKRI LETTER BHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A1,
+ },
+ [0x116A2]={
+ category="lo",
+ description="TAKRI LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A2,
+ },
+ [0x116A3]={
+ category="lo",
+ description="TAKRI LETTER YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A3,
+ },
+ [0x116A4]={
+ category="lo",
+ description="TAKRI LETTER RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A4,
+ },
+ [0x116A5]={
+ category="lo",
+ description="TAKRI LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A5,
+ },
+ [0x116A6]={
+ category="lo",
+ description="TAKRI LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A6,
+ },
+ [0x116A7]={
+ category="lo",
+ description="TAKRI LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A7,
+ },
+ [0x116A8]={
+ category="lo",
+ description="TAKRI LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A8,
+ },
+ [0x116A9]={
+ category="lo",
+ description="TAKRI LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116A9,
+ },
+ [0x116AA]={
+ category="lo",
+ description="TAKRI LETTER RRA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x116AA,
+ },
+ [0x116AB]={
+ category="mn",
+ description="TAKRI SIGN ANUSVARA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116AB,
+ },
+ [0x116AC]={
+ category="mc",
+ description="TAKRI SIGN VISARGA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x116AC,
+ },
+ [0x116AD]={
+ category="mn",
+ description="TAKRI VOWEL SIGN AA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116AD,
+ },
+ [0x116AE]={
+ category="mc",
+ description="TAKRI VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x116AE,
+ },
+ [0x116AF]={
+ category="mc",
+ description="TAKRI VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x116AF,
+ },
+ [0x116B0]={
+ category="mn",
+ description="TAKRI VOWEL SIGN U",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B0,
+ },
+ [0x116B1]={
+ category="mn",
+ description="TAKRI VOWEL SIGN UU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B1,
+ },
+ [0x116B2]={
+ category="mn",
+ description="TAKRI VOWEL SIGN E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B2,
+ },
+ [0x116B3]={
+ category="mn",
+ description="TAKRI VOWEL SIGN AI",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B3,
+ },
+ [0x116B4]={
+ category="mn",
+ description="TAKRI VOWEL SIGN O",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B4,
+ },
+ [0x116B5]={
+ category="mn",
+ description="TAKRI VOWEL SIGN AU",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B5,
+ },
+ [0x116B6]={
+ category="mc",
+ description="TAKRI SIGN VIRAMA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x116B6,
+ },
+ [0x116B7]={
+ category="mn",
+ description="TAKRI SIGN NUKTA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x116B7,
+ },
+ [0x116C0]={
+ category="nd",
+ description="TAKRI DIGIT ZERO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C0,
+ },
+ [0x116C1]={
+ category="nd",
+ description="TAKRI DIGIT ONE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C1,
+ },
+ [0x116C2]={
+ category="nd",
+ description="TAKRI DIGIT TWO",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C2,
+ },
+ [0x116C3]={
+ category="nd",
+ description="TAKRI DIGIT THREE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C3,
+ },
+ [0x116C4]={
+ category="nd",
+ description="TAKRI DIGIT FOUR",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C4,
+ },
+ [0x116C5]={
+ category="nd",
+ description="TAKRI DIGIT FIVE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C5,
+ },
+ [0x116C6]={
+ category="nd",
+ description="TAKRI DIGIT SIX",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C6,
+ },
+ [0x116C7]={
+ category="nd",
+ description="TAKRI DIGIT SEVEN",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C7,
+ },
+ [0x116C8]={
+ category="nd",
+ description="TAKRI DIGIT EIGHT",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C8,
+ },
+ [0x116C9]={
+ category="nd",
+ description="TAKRI DIGIT NINE",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x116C9,
+ },
+ [0x12000]={
+ category="lo",
+ description="CUNEIFORM SIGN A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12000,
+ },
+ [0x12001]={
+ category="lo",
+ description="CUNEIFORM SIGN A TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12001,
+ },
+ [0x12002]={
+ category="lo",
+ description="CUNEIFORM SIGN A TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12002,
+ },
+ [0x12003]={
+ category="lo",
+ description="CUNEIFORM SIGN A TIMES GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12003,
+ },
+ [0x12004]={
+ category="lo",
+ description="CUNEIFORM SIGN A TIMES HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12004,
+ },
+ [0x12005]={
+ category="lo",
+ description="CUNEIFORM SIGN A TIMES IGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12005,
+ },
+ [0x12006]={
+ category="lo",
+ description="CUNEIFORM SIGN A TIMES LAGAR GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12006,
+ },
+ [0x12007]={
+ category="lo",
+ description="CUNEIFORM SIGN A TIMES MUSH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12007,
+ },
+ [0x12008]={
+ category="lo",
+ description="CUNEIFORM SIGN A TIMES SAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12008,
+ },
+ [0x12009]={
+ category="lo",
+ description="CUNEIFORM SIGN A0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12009,
+ },
+ [0x1200A]={
+ category="lo",
+ description="CUNEIFORM SIGN AB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200A,
+ },
+ [0x1200B]={
+ category="lo",
+ description="CUNEIFORM SIGN AB TIMES ASH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200B,
+ },
+ [0x1200C]={
+ category="lo",
+ description="CUNEIFORM SIGN AB TIMES DUN0x0003 GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200C,
+ },
+ [0x1200D]={
+ category="lo",
+ description="CUNEIFORM SIGN AB TIMES GAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200D,
+ },
+ [0x1200E]={
+ category="lo",
+ description="CUNEIFORM SIGN AB TIMES GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200E,
+ },
+ [0x1200F]={
+ category="lo",
+ description="CUNEIFORM SIGN AB TIMES HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1200F,
+ },
+ [0x12010]={
+ category="lo",
+ description="CUNEIFORM SIGN AB TIMES IGI GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12010,
+ },
+ [0x12011]={
+ category="lo",
+ description="CUNEIFORM SIGN AB TIMES IMIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12011,
+ },
+ [0x12012]={
+ category="lo",
+ description="CUNEIFORM SIGN AB TIMES LAGAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12012,
+ },
+ [0x12013]={
+ category="lo",
+ description="CUNEIFORM SIGN AB TIMES SHESH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12013,
+ },
+ [0x12014]={
+ category="lo",
+ description="CUNEIFORM SIGN AB TIMES U PLUS U PLUS U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12014,
+ },
+ [0x12015]={
+ category="lo",
+ description="CUNEIFORM SIGN AB GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12015,
+ },
+ [0x12016]={
+ category="lo",
+ description="CUNEIFORM SIGN AB0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12016,
+ },
+ [0x12017]={
+ category="lo",
+ description="CUNEIFORM SIGN AB0x0002 TIMES BALAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12017,
+ },
+ [0x12018]={
+ category="lo",
+ description="CUNEIFORM SIGN AB0x0002 TIMES GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12018,
+ },
+ [0x12019]={
+ category="lo",
+ description="CUNEIFORM SIGN AB0x0002 TIMES ME PLUS EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12019,
+ },
+ [0x1201A]={
+ category="lo",
+ description="CUNEIFORM SIGN AB0x0002 TIMES SHA0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201A,
+ },
+ [0x1201B]={
+ category="lo",
+ description="CUNEIFORM SIGN AB0x0002 TIMES TAK0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201B,
+ },
+ [0x1201C]={
+ category="lo",
+ description="CUNEIFORM SIGN AD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201C,
+ },
+ [0x1201D]={
+ category="lo",
+ description="CUNEIFORM SIGN AK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201D,
+ },
+ [0x1201E]={
+ category="lo",
+ description="CUNEIFORM SIGN AK TIMES ERIN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201E,
+ },
+ [0x1201F]={
+ category="lo",
+ description="CUNEIFORM SIGN AK TIMES SHITA PLUS GISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1201F,
+ },
+ [0x12020]={
+ category="lo",
+ description="CUNEIFORM SIGN AL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12020,
+ },
+ [0x12021]={
+ category="lo",
+ description="CUNEIFORM SIGN AL TIMES AL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12021,
+ },
+ [0x12022]={
+ category="lo",
+ description="CUNEIFORM SIGN AL TIMES DIM0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12022,
+ },
+ [0x12023]={
+ category="lo",
+ description="CUNEIFORM SIGN AL TIMES GISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12023,
+ },
+ [0x12024]={
+ category="lo",
+ description="CUNEIFORM SIGN AL TIMES HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12024,
+ },
+ [0x12025]={
+ category="lo",
+ description="CUNEIFORM SIGN AL TIMES KAD0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12025,
+ },
+ [0x12026]={
+ category="lo",
+ description="CUNEIFORM SIGN AL TIMES KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12026,
+ },
+ [0x12027]={
+ category="lo",
+ description="CUNEIFORM SIGN AL TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12027,
+ },
+ [0x12028]={
+ category="lo",
+ description="CUNEIFORM SIGN AL TIMES USH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12028,
+ },
+ [0x12029]={
+ category="lo",
+ description="CUNEIFORM SIGN ALAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12029,
+ },
+ [0x1202A]={
+ category="lo",
+ description="CUNEIFORM SIGN ALEPH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202A,
+ },
+ [0x1202B]={
+ category="lo",
+ description="CUNEIFORM SIGN AMAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202B,
+ },
+ [0x1202C]={
+ category="lo",
+ description="CUNEIFORM SIGN AMAR TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202C,
+ },
+ [0x1202D]={
+ category="lo",
+ description="CUNEIFORM SIGN AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202D,
+ },
+ [0x1202E]={
+ category="lo",
+ description="CUNEIFORM SIGN AN OVER AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202E,
+ },
+ [0x1202F]={
+ category="lo",
+ description="CUNEIFORM SIGN AN THREE TIMES",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1202F,
+ },
+ [0x12030]={
+ category="lo",
+ description="CUNEIFORM SIGN AN PLUS NAGA OPPOSING AN PLUS NAGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12030,
+ },
+ [0x12031]={
+ category="lo",
+ description="CUNEIFORM SIGN AN PLUS NAGA SQUARED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12031,
+ },
+ [0x12032]={
+ category="lo",
+ description="CUNEIFORM SIGN ANSHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12032,
+ },
+ [0x12033]={
+ category="lo",
+ description="CUNEIFORM SIGN APIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12033,
+ },
+ [0x12034]={
+ category="lo",
+ description="CUNEIFORM SIGN ARAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12034,
+ },
+ [0x12035]={
+ category="lo",
+ description="CUNEIFORM SIGN ARAD TIMES KUR",
+ direction="l",
+ linebreak="al",
+ mathclass="ordinary",
+ mathname="backprime",
+ unicodeslot=0x12035,
+ },
+ [0x12036]={
+ category="lo",
+ description="CUNEIFORM SIGN ARKAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12036,
+ },
+ [0x12037]={
+ category="lo",
+ description="CUNEIFORM SIGN ASAL0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12037,
+ },
+ [0x12038]={
+ category="lo",
+ description="CUNEIFORM SIGN ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12038,
+ },
+ [0x12039]={
+ category="lo",
+ description="CUNEIFORM SIGN ASH ZIDA TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12039,
+ },
+ [0x1203A]={
+ category="lo",
+ description="CUNEIFORM SIGN ASH KABA TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203A,
+ },
+ [0x1203B]={
+ category="lo",
+ description="CUNEIFORM SIGN ASH OVER ASH TUG0x0002 OVER TUG0x0002 TUG0x0002 OVER TUG0x0002 PAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203B,
+ },
+ [0x1203C]={
+ category="lo",
+ description="CUNEIFORM SIGN ASH OVER ASH OVER ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203C,
+ },
+ [0x1203D]={
+ category="lo",
+ description="CUNEIFORM SIGN ASH OVER ASH OVER ASH CROSSING ASH OVER ASH OVER ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203D,
+ },
+ [0x1203E]={
+ category="lo",
+ description="CUNEIFORM SIGN ASH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203E,
+ },
+ [0x1203F]={
+ category="lo",
+ description="CUNEIFORM SIGN ASHGAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1203F,
+ },
+ [0x12040]={
+ category="lo",
+ description="CUNEIFORM SIGN BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12040,
+ },
+ [0x12041]={
+ category="lo",
+ description="CUNEIFORM SIGN BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12041,
+ },
+ [0x12042]={
+ category="lo",
+ description="CUNEIFORM SIGN BAG0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12042,
+ },
+ [0x12043]={
+ category="lo",
+ description="CUNEIFORM SIGN BAHAR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12043,
+ },
+ [0x12044]={
+ category="lo",
+ description="CUNEIFORM SIGN BAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12044,
+ },
+ [0x12045]={
+ category="lo",
+ description="CUNEIFORM SIGN BAL OVER BAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12045,
+ },
+ [0x12046]={
+ category="lo",
+ description="CUNEIFORM SIGN BALAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12046,
+ },
+ [0x12047]={
+ category="lo",
+ description="CUNEIFORM SIGN BAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12047,
+ },
+ [0x12048]={
+ category="lo",
+ description="CUNEIFORM SIGN BARA0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12048,
+ },
+ [0x12049]={
+ category="lo",
+ description="CUNEIFORM SIGN BI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12049,
+ },
+ [0x1204A]={
+ category="lo",
+ description="CUNEIFORM SIGN BI TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204A,
+ },
+ [0x1204B]={
+ category="lo",
+ description="CUNEIFORM SIGN BI TIMES GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204B,
+ },
+ [0x1204C]={
+ category="lo",
+ description="CUNEIFORM SIGN BI TIMES IGI GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204C,
+ },
+ [0x1204D]={
+ category="lo",
+ description="CUNEIFORM SIGN BU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204D,
+ },
+ [0x1204E]={
+ category="lo",
+ description="CUNEIFORM SIGN BU OVER BU AB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204E,
+ },
+ [0x1204F]={
+ category="lo",
+ description="CUNEIFORM SIGN BU OVER BU UN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1204F,
+ },
+ [0x12050]={
+ category="lo",
+ description="CUNEIFORM SIGN BU CROSSING BU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12050,
+ },
+ [0x12051]={
+ category="lo",
+ description="CUNEIFORM SIGN BULUG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12051,
+ },
+ [0x12052]={
+ category="lo",
+ description="CUNEIFORM SIGN BULUG OVER BULUG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12052,
+ },
+ [0x12053]={
+ category="lo",
+ description="CUNEIFORM SIGN BUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12053,
+ },
+ [0x12054]={
+ category="lo",
+ description="CUNEIFORM SIGN BUR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12054,
+ },
+ [0x12055]={
+ category="lo",
+ description="CUNEIFORM SIGN DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12055,
+ },
+ [0x12056]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12056,
+ },
+ [0x12057]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES A PLUS MASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12057,
+ },
+ [0x12058]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES AMAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12058,
+ },
+ [0x12059]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES BALAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12059,
+ },
+ [0x1205A]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES BI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205A,
+ },
+ [0x1205B]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205B,
+ },
+ [0x1205C]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES GA PLUS MASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205C,
+ },
+ [0x1205D]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES GI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205D,
+ },
+ [0x1205E]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES GIR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205E,
+ },
+ [0x1205F]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES GUD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1205F,
+ },
+ [0x12060]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12060,
+ },
+ [0x12061]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES IR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12061,
+ },
+ [0x12062]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES IR PLUS LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12062,
+ },
+ [0x12063]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES KAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12063,
+ },
+ [0x12064]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12064,
+ },
+ [0x12065]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12065,
+ },
+ [0x12066]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES LU PLUS MASH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12066,
+ },
+ [0x12067]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES LUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12067,
+ },
+ [0x12068]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12068,
+ },
+ [0x12069]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES PAP PLUS PAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12069,
+ },
+ [0x1206A]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES SI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206A,
+ },
+ [0x1206B]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES TAK0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206B,
+ },
+ [0x1206C]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES U0x0002 PLUS GIR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206C,
+ },
+ [0x1206D]={
+ category="lo",
+ description="CUNEIFORM SIGN DAG KISIM0x0005 TIMES USH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206D,
+ },
+ [0x1206E]={
+ category="lo",
+ description="CUNEIFORM SIGN DAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206E,
+ },
+ [0x1206F]={
+ category="lo",
+ description="CUNEIFORM SIGN DAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1206F,
+ },
+ [0x12070]={
+ category="lo",
+ description="CUNEIFORM SIGN DARA0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12070,
+ },
+ [0x12071]={
+ category="lo",
+ description="CUNEIFORM SIGN DARA0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12071,
+ },
+ [0x12072]={
+ category="lo",
+ description="CUNEIFORM SIGN DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12072,
+ },
+ [0x12073]={
+ category="lo",
+ description="CUNEIFORM SIGN DIB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12073,
+ },
+ [0x12074]={
+ category="lo",
+ description="CUNEIFORM SIGN DIM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12074,
+ },
+ [0x12075]={
+ category="lo",
+ description="CUNEIFORM SIGN DIM TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12075,
+ },
+ [0x12076]={
+ category="lo",
+ description="CUNEIFORM SIGN DIM0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12076,
+ },
+ [0x12077]={
+ category="lo",
+ description="CUNEIFORM SIGN DIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12077,
+ },
+ [0x12078]={
+ category="lo",
+ description="CUNEIFORM SIGN DIN KASKAL U GUNU DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12078,
+ },
+ [0x12079]={
+ category="lo",
+ description="CUNEIFORM SIGN DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12079,
+ },
+ [0x1207A]={
+ category="lo",
+ description="CUNEIFORM SIGN DU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207A,
+ },
+ [0x1207B]={
+ category="lo",
+ description="CUNEIFORM SIGN DU OVER DU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207B,
+ },
+ [0x1207C]={
+ category="lo",
+ description="CUNEIFORM SIGN DU GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207C,
+ },
+ [0x1207D]={
+ category="lo",
+ description="CUNEIFORM SIGN DU SHESHIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207D,
+ },
+ [0x1207E]={
+ category="lo",
+ description="CUNEIFORM SIGN DUB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207E,
+ },
+ [0x1207F]={
+ category="lo",
+ description="CUNEIFORM SIGN DUB TIMES ESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1207F,
+ },
+ [0x12080]={
+ category="lo",
+ description="CUNEIFORM SIGN DUB0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12080,
+ },
+ [0x12081]={
+ category="lo",
+ description="CUNEIFORM SIGN DUG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12081,
+ },
+ [0x12082]={
+ category="lo",
+ description="CUNEIFORM SIGN DUGUD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12082,
+ },
+ [0x12083]={
+ category="lo",
+ description="CUNEIFORM SIGN DUH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12083,
+ },
+ [0x12084]={
+ category="lo",
+ description="CUNEIFORM SIGN DUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12084,
+ },
+ [0x12085]={
+ category="lo",
+ description="CUNEIFORM SIGN DUN0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12085,
+ },
+ [0x12086]={
+ category="lo",
+ description="CUNEIFORM SIGN DUN0x0003 GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12086,
+ },
+ [0x12087]={
+ category="lo",
+ description="CUNEIFORM SIGN DUN0x0003 GUNU GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12087,
+ },
+ [0x12088]={
+ category="lo",
+ description="CUNEIFORM SIGN DUN0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12088,
+ },
+ [0x12089]={
+ category="lo",
+ description="CUNEIFORM SIGN DUR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12089,
+ },
+ [0x1208A]={
+ category="lo",
+ description="CUNEIFORM SIGN E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208A,
+ },
+ [0x1208B]={
+ category="lo",
+ description="CUNEIFORM SIGN E TIMES PAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208B,
+ },
+ [0x1208C]={
+ category="lo",
+ description="CUNEIFORM SIGN E OVER E NUN OVER NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208C,
+ },
+ [0x1208D]={
+ category="lo",
+ description="CUNEIFORM SIGN E0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208D,
+ },
+ [0x1208E]={
+ category="lo",
+ description="CUNEIFORM SIGN E0x0002 TIMES A PLUS HA PLUS DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208E,
+ },
+ [0x1208F]={
+ category="lo",
+ description="CUNEIFORM SIGN E0x0002 TIMES GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1208F,
+ },
+ [0x12090]={
+ category="lo",
+ description="CUNEIFORM SIGN E0x0002 TIMES MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12090,
+ },
+ [0x12091]={
+ category="lo",
+ description="CUNEIFORM SIGN E0x0002 TIMES SAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12091,
+ },
+ [0x12092]={
+ category="lo",
+ description="CUNEIFORM SIGN E0x0002 TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12092,
+ },
+ [0x12093]={
+ category="lo",
+ description="CUNEIFORM SIGN E0x0002 TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12093,
+ },
+ [0x12094]={
+ category="lo",
+ description="CUNEIFORM SIGN EDIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12094,
+ },
+ [0x12095]={
+ category="lo",
+ description="CUNEIFORM SIGN EGIR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12095,
+ },
+ [0x12096]={
+ category="lo",
+ description="CUNEIFORM SIGN EL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12096,
+ },
+ [0x12097]={
+ category="lo",
+ description="CUNEIFORM SIGN EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12097,
+ },
+ [0x12098]={
+ category="lo",
+ description="CUNEIFORM SIGN EN TIMES GAN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12098,
+ },
+ [0x12099]={
+ category="lo",
+ description="CUNEIFORM SIGN EN TIMES GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12099,
+ },
+ [0x1209A]={
+ category="lo",
+ description="CUNEIFORM SIGN EN TIMES ME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209A,
+ },
+ [0x1209B]={
+ category="lo",
+ description="CUNEIFORM SIGN EN CROSSING EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209B,
+ },
+ [0x1209C]={
+ category="lo",
+ description="CUNEIFORM SIGN EN OPPOSING EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209C,
+ },
+ [0x1209D]={
+ category="lo",
+ description="CUNEIFORM SIGN EN SQUARED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209D,
+ },
+ [0x1209E]={
+ category="lo",
+ description="CUNEIFORM SIGN EREN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209E,
+ },
+ [0x1209F]={
+ category="lo",
+ description="CUNEIFORM SIGN ERIN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1209F,
+ },
+ [0x120A0]={
+ category="lo",
+ description="CUNEIFORM SIGN ESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A0,
+ },
+ [0x120A1]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A1,
+ },
+ [0x120A2]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A2,
+ },
+ [0x120A3]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES A PLUS LAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A3,
+ },
+ [0x120A4]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES A PLUS LAL TIMES LAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A4,
+ },
+ [0x120A5]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A5,
+ },
+ [0x120A6]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A6,
+ },
+ [0x120A7]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES DUN0x0003 GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A7,
+ },
+ [0x120A8]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES DUN0x0003 GUNU GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A8,
+ },
+ [0x120A9]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120A9,
+ },
+ [0x120AA]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES HA GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120AA,
+ },
+ [0x120AB]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES IGI GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120AB,
+ },
+ [0x120AC]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES KASKAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120AC,
+ },
+ [0x120AD]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES KASKAL SQUARED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120AD,
+ },
+ [0x120AE]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES KU0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120AE,
+ },
+ [0x120AF]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120AF,
+ },
+ [0x120B0]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES LAL TIMES LAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B0,
+ },
+ [0x120B1]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES LI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B1,
+ },
+ [0x120B2]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B2,
+ },
+ [0x120B3]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES U0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B3,
+ },
+ [0x120B4]={
+ category="lo",
+ description="CUNEIFORM SIGN EZEN TIMES UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B4,
+ },
+ [0x120B5]={
+ category="lo",
+ description="CUNEIFORM SIGN GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B5,
+ },
+ [0x120B6]={
+ category="lo",
+ description="CUNEIFORM SIGN GA GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B6,
+ },
+ [0x120B7]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B7,
+ },
+ [0x120B8]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES A PLUS DA PLUS HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B8,
+ },
+ [0x120B9]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES A PLUS HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120B9,
+ },
+ [0x120BA]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES A PLUS IGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120BA,
+ },
+ [0x120BB]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES AB0x0002 TENU PLUS TAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120BB,
+ },
+ [0x120BC]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120BC,
+ },
+ [0x120BD]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120BD,
+ },
+ [0x120BE]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES ASH0x0002 PLUS GAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120BE,
+ },
+ [0x120BF]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120BF,
+ },
+ [0x120C0]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES BAR PLUS RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C0,
+ },
+ [0x120C1]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES BUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C1,
+ },
+ [0x120C2]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES BUR PLUS RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C2,
+ },
+ [0x120C3]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C3,
+ },
+ [0x120C4]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C4,
+ },
+ [0x120C5]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES DIM TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C5,
+ },
+ [0x120C6]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES DUB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C6,
+ },
+ [0x120C7]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES EL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C7,
+ },
+ [0x120C8]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES EL PLUS LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C8,
+ },
+ [0x120C9]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120C9,
+ },
+ [0x120CA]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES EN TIMES GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120CA,
+ },
+ [0x120CB]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120CB,
+ },
+ [0x120CC]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120CC,
+ },
+ [0x120CD]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES GI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120CD,
+ },
+ [0x120CE]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES GI0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120CE,
+ },
+ [0x120CF]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES GI0x0004 PLUS A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120CF,
+ },
+ [0x120D0]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES GIR0x0002 PLUS SU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D0,
+ },
+ [0x120D1]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES HA PLUS LU PLUS ESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D1,
+ },
+ [0x120D2]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES HAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D2,
+ },
+ [0x120D3]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES HAL PLUS LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D3,
+ },
+ [0x120D4]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES HI PLUS LI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D4,
+ },
+ [0x120D5]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES HUB0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D5,
+ },
+ [0x120D6]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES IGI GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D6,
+ },
+ [0x120D7]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES ISH PLUS HU PLUS ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D7,
+ },
+ [0x120D8]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES KAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D8,
+ },
+ [0x120D9]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES KASKAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120D9,
+ },
+ [0x120DA]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES KID",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120DA,
+ },
+ [0x120DB]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES KID PLUS LAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120DB,
+ },
+ [0x120DC]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES KU0x0003 PLUS AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120DC,
+ },
+ [0x120DD]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120DD,
+ },
+ [0x120DE]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES ME PLUS EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120DE,
+ },
+ [0x120DF]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120DF,
+ },
+ [0x120E0]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E0,
+ },
+ [0x120E1]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES NUN OVER NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E1,
+ },
+ [0x120E2]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E2,
+ },
+ [0x120E3]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES SAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E3,
+ },
+ [0x120E4]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES SAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E4,
+ },
+ [0x120E5]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E5,
+ },
+ [0x120E6]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES SHE PLUS TUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E6,
+ },
+ [0x120E7]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES SHID",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E7,
+ },
+ [0x120E8]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES SUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E8,
+ },
+ [0x120E9]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES TAK0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120E9,
+ },
+ [0x120EA]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120EA,
+ },
+ [0x120EB]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120EB,
+ },
+ [0x120EC]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 TIMES UD PLUS DU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120EC,
+ },
+ [0x120ED]={
+ category="lo",
+ description="CUNEIFORM SIGN GA0x0002 OVER GA0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120ED,
+ },
+ [0x120EE]={
+ category="lo",
+ description="CUNEIFORM SIGN GABA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120EE,
+ },
+ [0x120EF]={
+ category="lo",
+ description="CUNEIFORM SIGN GABA CROSSING GABA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120EF,
+ },
+ [0x120F0]={
+ category="lo",
+ description="CUNEIFORM SIGN GAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F0,
+ },
+ [0x120F1]={
+ category="lo",
+ description="CUNEIFORM SIGN GAD OVER GAD GAR OVER GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F1,
+ },
+ [0x120F2]={
+ category="lo",
+ description="CUNEIFORM SIGN GAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F2,
+ },
+ [0x120F3]={
+ category="lo",
+ description="CUNEIFORM SIGN GAL GAD OVER GAD GAR OVER GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F3,
+ },
+ [0x120F4]={
+ category="lo",
+ description="CUNEIFORM SIGN GALAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F4,
+ },
+ [0x120F5]={
+ category="lo",
+ description="CUNEIFORM SIGN GAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F5,
+ },
+ [0x120F6]={
+ category="lo",
+ description="CUNEIFORM SIGN GAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F6,
+ },
+ [0x120F7]={
+ category="lo",
+ description="CUNEIFORM SIGN GAN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F7,
+ },
+ [0x120F8]={
+ category="lo",
+ description="CUNEIFORM SIGN GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F8,
+ },
+ [0x120F9]={
+ category="lo",
+ description="CUNEIFORM SIGN GAN0x0002 OVER GAN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120F9,
+ },
+ [0x120FA]={
+ category="lo",
+ description="CUNEIFORM SIGN GAN0x0002 CROSSING GAN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120FA,
+ },
+ [0x120FB]={
+ category="lo",
+ description="CUNEIFORM SIGN GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120FB,
+ },
+ [0x120FC]={
+ category="lo",
+ description="CUNEIFORM SIGN GAR0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120FC,
+ },
+ [0x120FD]={
+ category="lo",
+ description="CUNEIFORM SIGN GASHAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120FD,
+ },
+ [0x120FE]={
+ category="lo",
+ description="CUNEIFORM SIGN GESHTIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120FE,
+ },
+ [0x120FF]={
+ category="lo",
+ description="CUNEIFORM SIGN GESHTIN TIMES KUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x120FF,
+ },
+ [0x12100]={
+ category="lo",
+ description="CUNEIFORM SIGN GI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12100,
+ },
+ [0x12101]={
+ category="lo",
+ description="CUNEIFORM SIGN GI TIMES E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12101,
+ },
+ [0x12102]={
+ category="lo",
+ description="CUNEIFORM SIGN GI TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12102,
+ },
+ [0x12103]={
+ category="lo",
+ description="CUNEIFORM SIGN GI CROSSING GI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12103,
+ },
+ [0x12104]={
+ category="lo",
+ description="CUNEIFORM SIGN GI0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12104,
+ },
+ [0x12105]={
+ category="lo",
+ description="CUNEIFORM SIGN GI0x0004 OVER GI0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12105,
+ },
+ [0x12106]={
+ category="lo",
+ description="CUNEIFORM SIGN GI0x0004 CROSSING GI0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12106,
+ },
+ [0x12107]={
+ category="lo",
+ description="CUNEIFORM SIGN GIDIM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12107,
+ },
+ [0x12108]={
+ category="lo",
+ description="CUNEIFORM SIGN GIR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12108,
+ },
+ [0x12109]={
+ category="lo",
+ description="CUNEIFORM SIGN GIR0x0002 GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12109,
+ },
+ [0x1210A]={
+ category="lo",
+ description="CUNEIFORM SIGN GIR0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210A,
+ },
+ [0x1210B]={
+ category="lo",
+ description="CUNEIFORM SIGN GIR0x0003 TIMES A PLUS IGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210B,
+ },
+ [0x1210C]={
+ category="lo",
+ description="CUNEIFORM SIGN GIR0x0003 TIMES GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210C,
+ },
+ [0x1210D]={
+ category="lo",
+ description="CUNEIFORM SIGN GIR0x0003 TIMES IGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210D,
+ },
+ [0x1210E]={
+ category="lo",
+ description="CUNEIFORM SIGN GIR0x0003 TIMES LU PLUS IGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210E,
+ },
+ [0x1210F]={
+ category="lo",
+ description="CUNEIFORM SIGN GIR0x0003 TIMES PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1210F,
+ },
+ [0x12110]={
+ category="lo",
+ description="CUNEIFORM SIGN GISAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12110,
+ },
+ [0x12111]={
+ category="lo",
+ description="CUNEIFORM SIGN GISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12111,
+ },
+ [0x12112]={
+ category="lo",
+ description="CUNEIFORM SIGN GISH CROSSING GISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12112,
+ },
+ [0x12113]={
+ category="lo",
+ description="CUNEIFORM SIGN GISH TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12113,
+ },
+ [0x12114]={
+ category="lo",
+ description="CUNEIFORM SIGN GISH TIMES TAK0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12114,
+ },
+ [0x12115]={
+ category="lo",
+ description="CUNEIFORM SIGN GISH TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12115,
+ },
+ [0x12116]={
+ category="lo",
+ description="CUNEIFORM SIGN GU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12116,
+ },
+ [0x12117]={
+ category="lo",
+ description="CUNEIFORM SIGN GU CROSSING GU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12117,
+ },
+ [0x12118]={
+ category="lo",
+ description="CUNEIFORM SIGN GU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12118,
+ },
+ [0x12119]={
+ category="lo",
+ description="CUNEIFORM SIGN GU0x0002 TIMES KAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12119,
+ },
+ [0x1211A]={
+ category="lo",
+ description="CUNEIFORM SIGN GU0x0002 TIMES KAK TIMES IGI GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211A,
+ },
+ [0x1211B]={
+ category="lo",
+ description="CUNEIFORM SIGN GU0x0002 TIMES NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211B,
+ },
+ [0x1211C]={
+ category="lo",
+ description="CUNEIFORM SIGN GU0x0002 TIMES SAL PLUS TUG0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211C,
+ },
+ [0x1211D]={
+ category="lo",
+ description="CUNEIFORM SIGN GU0x0002 GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211D,
+ },
+ [0x1211E]={
+ category="lo",
+ description="CUNEIFORM SIGN GUD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211E,
+ },
+ [0x1211F]={
+ category="lo",
+ description="CUNEIFORM SIGN GUD TIMES A PLUS KUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1211F,
+ },
+ [0x12120]={
+ category="lo",
+ description="CUNEIFORM SIGN GUD TIMES KUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12120,
+ },
+ [0x12121]={
+ category="lo",
+ description="CUNEIFORM SIGN GUD OVER GUD LUGAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12121,
+ },
+ [0x12122]={
+ category="lo",
+ description="CUNEIFORM SIGN GUL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12122,
+ },
+ [0x12123]={
+ category="lo",
+ description="CUNEIFORM SIGN GUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12123,
+ },
+ [0x12124]={
+ category="lo",
+ description="CUNEIFORM SIGN GUM TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12124,
+ },
+ [0x12125]={
+ category="lo",
+ description="CUNEIFORM SIGN GUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12125,
+ },
+ [0x12126]={
+ category="lo",
+ description="CUNEIFORM SIGN GUR0x0007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12126,
+ },
+ [0x12127]={
+ category="lo",
+ description="CUNEIFORM SIGN GURUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12127,
+ },
+ [0x12128]={
+ category="lo",
+ description="CUNEIFORM SIGN GURUSH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12128,
+ },
+ [0x12129]={
+ category="lo",
+ description="CUNEIFORM SIGN HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12129,
+ },
+ [0x1212A]={
+ category="lo",
+ description="CUNEIFORM SIGN HA TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212A,
+ },
+ [0x1212B]={
+ category="lo",
+ description="CUNEIFORM SIGN HA GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212B,
+ },
+ [0x1212C]={
+ category="lo",
+ description="CUNEIFORM SIGN HAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212C,
+ },
+ [0x1212D]={
+ category="lo",
+ description="CUNEIFORM SIGN HI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212D,
+ },
+ [0x1212E]={
+ category="lo",
+ description="CUNEIFORM SIGN HI TIMES ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212E,
+ },
+ [0x1212F]={
+ category="lo",
+ description="CUNEIFORM SIGN HI TIMES ASH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1212F,
+ },
+ [0x12130]={
+ category="lo",
+ description="CUNEIFORM SIGN HI TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12130,
+ },
+ [0x12131]={
+ category="lo",
+ description="CUNEIFORM SIGN HI TIMES DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12131,
+ },
+ [0x12132]={
+ category="lo",
+ description="CUNEIFORM SIGN HI TIMES GAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12132,
+ },
+ [0x12133]={
+ category="lo",
+ description="CUNEIFORM SIGN HI TIMES KIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12133,
+ },
+ [0x12134]={
+ category="lo",
+ description="CUNEIFORM SIGN HI TIMES NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12134,
+ },
+ [0x12135]={
+ category="lo",
+ description="CUNEIFORM SIGN HI TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12135,
+ },
+ [0x12136]={
+ category="lo",
+ description="CUNEIFORM SIGN HI TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12136,
+ },
+ [0x12137]={
+ category="lo",
+ description="CUNEIFORM SIGN HU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12137,
+ },
+ [0x12138]={
+ category="lo",
+ description="CUNEIFORM SIGN HUB0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12138,
+ },
+ [0x12139]={
+ category="lo",
+ description="CUNEIFORM SIGN HUB0x0002 TIMES AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12139,
+ },
+ [0x1213A]={
+ category="lo",
+ description="CUNEIFORM SIGN HUB0x0002 TIMES HAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213A,
+ },
+ [0x1213B]={
+ category="lo",
+ description="CUNEIFORM SIGN HUB0x0002 TIMES KASKAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213B,
+ },
+ [0x1213C]={
+ category="lo",
+ description="CUNEIFORM SIGN HUB0x0002 TIMES LISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213C,
+ },
+ [0x1213D]={
+ category="lo",
+ description="CUNEIFORM SIGN HUB0x0002 TIMES UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213D,
+ },
+ [0x1213E]={
+ category="lo",
+ description="CUNEIFORM SIGN HUL0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213E,
+ },
+ [0x1213F]={
+ category="lo",
+ description="CUNEIFORM SIGN I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1213F,
+ },
+ [0x12140]={
+ category="lo",
+ description="CUNEIFORM SIGN I A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12140,
+ },
+ [0x12141]={
+ category="lo",
+ description="CUNEIFORM SIGN IB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12141,
+ },
+ [0x12142]={
+ category="lo",
+ description="CUNEIFORM SIGN IDIM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12142,
+ },
+ [0x12143]={
+ category="lo",
+ description="CUNEIFORM SIGN IDIM OVER IDIM BUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12143,
+ },
+ [0x12144]={
+ category="lo",
+ description="CUNEIFORM SIGN IDIM OVER IDIM SQUARED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12144,
+ },
+ [0x12145]={
+ category="lo",
+ description="CUNEIFORM SIGN IG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12145,
+ },
+ [0x12146]={
+ category="lo",
+ description="CUNEIFORM SIGN IGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12146,
+ },
+ [0x12147]={
+ category="lo",
+ description="CUNEIFORM SIGN IGI DIB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12147,
+ },
+ [0x12148]={
+ category="lo",
+ description="CUNEIFORM SIGN IGI RI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12148,
+ },
+ [0x12149]={
+ category="lo",
+ description="CUNEIFORM SIGN IGI OVER IGI SHIR OVER SHIR UD OVER UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12149,
+ },
+ [0x1214A]={
+ category="lo",
+ description="CUNEIFORM SIGN IGI GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214A,
+ },
+ [0x1214B]={
+ category="lo",
+ description="CUNEIFORM SIGN IL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214B,
+ },
+ [0x1214C]={
+ category="lo",
+ description="CUNEIFORM SIGN IL TIMES GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214C,
+ },
+ [0x1214D]={
+ category="lo",
+ description="CUNEIFORM SIGN IL0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214D,
+ },
+ [0x1214E]={
+ category="lo",
+ description="CUNEIFORM SIGN IM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214E,
+ },
+ [0x1214F]={
+ category="lo",
+ description="CUNEIFORM SIGN IM TIMES TAK0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1214F,
+ },
+ [0x12150]={
+ category="lo",
+ description="CUNEIFORM SIGN IM CROSSING IM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12150,
+ },
+ [0x12151]={
+ category="lo",
+ description="CUNEIFORM SIGN IM OPPOSING IM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12151,
+ },
+ [0x12152]={
+ category="lo",
+ description="CUNEIFORM SIGN IM SQUARED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12152,
+ },
+ [0x12153]={
+ category="lo",
+ description="CUNEIFORM SIGN IMIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12153,
+ },
+ [0x12154]={
+ category="lo",
+ description="CUNEIFORM SIGN IN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12154,
+ },
+ [0x12155]={
+ category="lo",
+ description="CUNEIFORM SIGN IR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12155,
+ },
+ [0x12156]={
+ category="lo",
+ description="CUNEIFORM SIGN ISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12156,
+ },
+ [0x12157]={
+ category="lo",
+ description="CUNEIFORM SIGN KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12157,
+ },
+ [0x12158]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12158,
+ },
+ [0x12159]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES AD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12159,
+ },
+ [0x1215A]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES AD PLUS KU0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215A,
+ },
+ [0x1215B]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES ASH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215B,
+ },
+ [0x1215C]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215C,
+ },
+ [0x1215D]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES BALAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215D,
+ },
+ [0x1215E]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES BAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215E,
+ },
+ [0x1215F]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES BI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1215F,
+ },
+ [0x12160]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES ERIN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12160,
+ },
+ [0x12161]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES ESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12161,
+ },
+ [0x12162]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12162,
+ },
+ [0x12163]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES GAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12163,
+ },
+ [0x12164]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12164,
+ },
+ [0x12165]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12165,
+ },
+ [0x12166]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES GAR PLUS SHA0x0003 PLUS A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12166,
+ },
+ [0x12167]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES GI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12167,
+ },
+ [0x12168]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES GIR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12168,
+ },
+ [0x12169]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES GISH PLUS SAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12169,
+ },
+ [0x1216A]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES GISH CROSSING GISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216A,
+ },
+ [0x1216B]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES GU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216B,
+ },
+ [0x1216C]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES GUR0x0007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216C,
+ },
+ [0x1216D]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES IGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216D,
+ },
+ [0x1216E]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES IM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216E,
+ },
+ [0x1216F]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES KAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1216F,
+ },
+ [0x12170]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12170,
+ },
+ [0x12171]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES KID",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12171,
+ },
+ [0x12172]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES LI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12172,
+ },
+ [0x12173]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12173,
+ },
+ [0x12174]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES ME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12174,
+ },
+ [0x12175]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES ME PLUS DU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12175,
+ },
+ [0x12176]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES ME PLUS GI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12176,
+ },
+ [0x12177]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES ME PLUS TE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12177,
+ },
+ [0x12178]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12178,
+ },
+ [0x12179]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES MI PLUS NUNUZ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12179,
+ },
+ [0x1217A]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217A,
+ },
+ [0x1217B]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217B,
+ },
+ [0x1217C]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES PI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217C,
+ },
+ [0x1217D]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES RU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217D,
+ },
+ [0x1217E]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217E,
+ },
+ [0x1217F]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES SAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1217F,
+ },
+ [0x12180]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12180,
+ },
+ [0x12181]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12181,
+ },
+ [0x12182]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES SHID",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12182,
+ },
+ [0x12183]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES SHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12183,
+ },
+ [0x12184]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES SIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12184,
+ },
+ [0x12185]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES SUHUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12185,
+ },
+ [0x12186]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES TAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12186,
+ },
+ [0x12187]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12187,
+ },
+ [0x12188]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES U0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12188,
+ },
+ [0x12189]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12189,
+ },
+ [0x1218A]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES UMUM TIMES PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218A,
+ },
+ [0x1218B]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES USH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218B,
+ },
+ [0x1218C]={
+ category="lo",
+ description="CUNEIFORM SIGN KA TIMES ZI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218C,
+ },
+ [0x1218D]={
+ category="lo",
+ description="CUNEIFORM SIGN KA0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218D,
+ },
+ [0x1218E]={
+ category="lo",
+ description="CUNEIFORM SIGN KA0x0002 CROSSING KA0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218E,
+ },
+ [0x1218F]={
+ category="lo",
+ description="CUNEIFORM SIGN KAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1218F,
+ },
+ [0x12190]={
+ category="lo",
+ description="CUNEIFORM SIGN KAD0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12190,
+ },
+ [0x12191]={
+ category="lo",
+ description="CUNEIFORM SIGN KAD0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12191,
+ },
+ [0x12192]={
+ category="lo",
+ description="CUNEIFORM SIGN KAD0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12192,
+ },
+ [0x12193]={
+ category="lo",
+ description="CUNEIFORM SIGN KAD0x0005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12193,
+ },
+ [0x12194]={
+ category="lo",
+ description="CUNEIFORM SIGN KAD0x0005 OVER KAD0x0005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12194,
+ },
+ [0x12195]={
+ category="lo",
+ description="CUNEIFORM SIGN KAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12195,
+ },
+ [0x12196]={
+ category="lo",
+ description="CUNEIFORM SIGN KAK TIMES IGI GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12196,
+ },
+ [0x12197]={
+ category="lo",
+ description="CUNEIFORM SIGN KAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12197,
+ },
+ [0x12198]={
+ category="lo",
+ description="CUNEIFORM SIGN KAL TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12198,
+ },
+ [0x12199]={
+ category="lo",
+ description="CUNEIFORM SIGN KAL CROSSING KAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12199,
+ },
+ [0x1219A]={
+ category="lo",
+ description="CUNEIFORM SIGN KAM0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219A,
+ },
+ [0x1219B]={
+ category="lo",
+ description="CUNEIFORM SIGN KAM0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219B,
+ },
+ [0x1219C]={
+ category="lo",
+ description="CUNEIFORM SIGN KASKAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219C,
+ },
+ [0x1219D]={
+ category="lo",
+ description="CUNEIFORM SIGN KASKAL LAGAB TIMES U OVER LAGAB TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219D,
+ },
+ [0x1219E]={
+ category="lo",
+ description="CUNEIFORM SIGN KASKAL OVER KASKAL LAGAB TIMES U OVER LAGAB TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219E,
+ },
+ [0x1219F]={
+ category="lo",
+ description="CUNEIFORM SIGN KESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1219F,
+ },
+ [0x121A0]={
+ category="lo",
+ description="CUNEIFORM SIGN KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A0,
+ },
+ [0x121A1]={
+ category="lo",
+ description="CUNEIFORM SIGN KI TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A1,
+ },
+ [0x121A2]={
+ category="lo",
+ description="CUNEIFORM SIGN KI TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A2,
+ },
+ [0x121A3]={
+ category="lo",
+ description="CUNEIFORM SIGN KI TIMES UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A3,
+ },
+ [0x121A4]={
+ category="lo",
+ description="CUNEIFORM SIGN KID",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A4,
+ },
+ [0x121A5]={
+ category="lo",
+ description="CUNEIFORM SIGN KIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A5,
+ },
+ [0x121A6]={
+ category="lo",
+ description="CUNEIFORM SIGN KISAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A6,
+ },
+ [0x121A7]={
+ category="lo",
+ description="CUNEIFORM SIGN KISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A7,
+ },
+ [0x121A8]={
+ category="lo",
+ description="CUNEIFORM SIGN KISIM0x0005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A8,
+ },
+ [0x121A9]={
+ category="lo",
+ description="CUNEIFORM SIGN KISIM0x0005 OVER KISIM0x0005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121A9,
+ },
+ [0x121AA]={
+ category="lo",
+ description="CUNEIFORM SIGN KU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121AA,
+ },
+ [0x121AB]={
+ category="lo",
+ description="CUNEIFORM SIGN KU OVER HI TIMES ASH0x0002 KU OVER HI TIMES ASH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121AB,
+ },
+ [0x121AC]={
+ category="lo",
+ description="CUNEIFORM SIGN KU0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121AC,
+ },
+ [0x121AD]={
+ category="lo",
+ description="CUNEIFORM SIGN KU0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121AD,
+ },
+ [0x121AE]={
+ category="lo",
+ description="CUNEIFORM SIGN KU0x0004 VARIANT FORM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121AE,
+ },
+ [0x121AF]={
+ category="lo",
+ description="CUNEIFORM SIGN KU0x0007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121AF,
+ },
+ [0x121B0]={
+ category="lo",
+ description="CUNEIFORM SIGN KUL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B0,
+ },
+ [0x121B1]={
+ category="lo",
+ description="CUNEIFORM SIGN KUL GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B1,
+ },
+ [0x121B2]={
+ category="lo",
+ description="CUNEIFORM SIGN KUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B2,
+ },
+ [0x121B3]={
+ category="lo",
+ description="CUNEIFORM SIGN KUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B3,
+ },
+ [0x121B4]={
+ category="lo",
+ description="CUNEIFORM SIGN KUR OPPOSING KUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B4,
+ },
+ [0x121B5]={
+ category="lo",
+ description="CUNEIFORM SIGN KUSHU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B5,
+ },
+ [0x121B6]={
+ category="lo",
+ description="CUNEIFORM SIGN KWU0x013E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B6,
+ },
+ [0x121B7]={
+ category="lo",
+ description="CUNEIFORM SIGN LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B7,
+ },
+ [0x121B8]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B8,
+ },
+ [0x121B9]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121B9,
+ },
+ [0x121BA]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES A PLUS DA PLUS HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121BA,
+ },
+ [0x121BB]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES A PLUS GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121BB,
+ },
+ [0x121BC]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES A PLUS LAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121BC,
+ },
+ [0x121BD]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES AL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121BD,
+ },
+ [0x121BE]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121BE,
+ },
+ [0x121BF]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES ASH ZIDA TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121BF,
+ },
+ [0x121C0]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C0,
+ },
+ [0x121C1]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES BI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C1,
+ },
+ [0x121C2]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES DAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C2,
+ },
+ [0x121C3]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C3,
+ },
+ [0x121C4]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C4,
+ },
+ [0x121C5]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C5,
+ },
+ [0x121C6]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES GUD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C6,
+ },
+ [0x121C7]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES GUD PLUS GUD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C7,
+ },
+ [0x121C8]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C8,
+ },
+ [0x121C9]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES HAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121C9,
+ },
+ [0x121CA]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES HI TIMES NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121CA,
+ },
+ [0x121CB]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES IGI GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121CB,
+ },
+ [0x121CC]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES IM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121CC,
+ },
+ [0x121CD]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES IM PLUS HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121CD,
+ },
+ [0x121CE]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES IM PLUS LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121CE,
+ },
+ [0x121CF]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121CF,
+ },
+ [0x121D0]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES KIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D0,
+ },
+ [0x121D1]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES KU0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D1,
+ },
+ [0x121D2]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES KUL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D2,
+ },
+ [0x121D3]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES KUL PLUS HI PLUS A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D3,
+ },
+ [0x121D4]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES LAGAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D4,
+ },
+ [0x121D5]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES LISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D5,
+ },
+ [0x121D6]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D6,
+ },
+ [0x121D7]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES LUL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D7,
+ },
+ [0x121D8]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES ME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D8,
+ },
+ [0x121D9]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES ME PLUS EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121D9,
+ },
+ [0x121DA]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES MUSH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121DA,
+ },
+ [0x121DB]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121DB,
+ },
+ [0x121DC]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES SHE PLUS SUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121DC,
+ },
+ [0x121DD]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH PLUS ERIN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121DD,
+ },
+ [0x121DE]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121DE,
+ },
+ [0x121DF]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES SHU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121DF,
+ },
+ [0x121E0]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES SHU0x0002 PLUS SHU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E0,
+ },
+ [0x121E1]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES SUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E1,
+ },
+ [0x121E2]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES TAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E2,
+ },
+ [0x121E3]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES TAK0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E3,
+ },
+ [0x121E4]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES TE PLUS A PLUS SU PLUS NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E4,
+ },
+ [0x121E5]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E5,
+ },
+ [0x121E6]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES U PLUS A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E6,
+ },
+ [0x121E7]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES U PLUS U PLUS U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E7,
+ },
+ [0x121E8]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES U0x0002 PLUS ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E8,
+ },
+ [0x121E9]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121E9,
+ },
+ [0x121EA]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB TIMES USH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121EA,
+ },
+ [0x121EB]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAB SQUARED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121EB,
+ },
+ [0x121EC]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121EC,
+ },
+ [0x121ED]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAR TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121ED,
+ },
+ [0x121EE]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAR TIMES SHE PLUS SUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121EE,
+ },
+ [0x121EF]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAR GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121EF,
+ },
+ [0x121F0]={
+ category="lo",
+ description="CUNEIFORM SIGN LAGAR GUNU OVER LAGAR GUNU SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F0,
+ },
+ [0x121F1]={
+ category="lo",
+ description="CUNEIFORM SIGN LAHSHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F1,
+ },
+ [0x121F2]={
+ category="lo",
+ description="CUNEIFORM SIGN LAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F2,
+ },
+ [0x121F3]={
+ category="lo",
+ description="CUNEIFORM SIGN LAL TIMES LAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F3,
+ },
+ [0x121F4]={
+ category="lo",
+ description="CUNEIFORM SIGN LAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F4,
+ },
+ [0x121F5]={
+ category="lo",
+ description="CUNEIFORM SIGN LAM TIMES KUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F5,
+ },
+ [0x121F6]={
+ category="lo",
+ description="CUNEIFORM SIGN LAM TIMES KUR PLUS RU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F6,
+ },
+ [0x121F7]={
+ category="lo",
+ description="CUNEIFORM SIGN LI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F7,
+ },
+ [0x121F8]={
+ category="lo",
+ description="CUNEIFORM SIGN LIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F8,
+ },
+ [0x121F9]={
+ category="lo",
+ description="CUNEIFORM SIGN LIMMU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121F9,
+ },
+ [0x121FA]={
+ category="lo",
+ description="CUNEIFORM SIGN LISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121FA,
+ },
+ [0x121FB]={
+ category="lo",
+ description="CUNEIFORM SIGN LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121FB,
+ },
+ [0x121FC]={
+ category="lo",
+ description="CUNEIFORM SIGN LU TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121FC,
+ },
+ [0x121FD]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121FD,
+ },
+ [0x121FE]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES AL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121FE,
+ },
+ [0x121FF]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x121FF,
+ },
+ [0x12200]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES ESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12200,
+ },
+ [0x12201]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES ESH0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12201,
+ },
+ [0x12202]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12202,
+ },
+ [0x12203]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES HI TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12203,
+ },
+ [0x12204]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES IM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12204,
+ },
+ [0x12205]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES KAD0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12205,
+ },
+ [0x12206]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES KAD0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12206,
+ },
+ [0x12207]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES KAD0x0003 PLUS ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12207,
+ },
+ [0x12208]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12208,
+ },
+ [0x12209]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES LA PLUS ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12209,
+ },
+ [0x1220A]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES LAGAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220A,
+ },
+ [0x1220B]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES ME PLUS EN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220B,
+ },
+ [0x1220C]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220C,
+ },
+ [0x1220D]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES NU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220D,
+ },
+ [0x1220E]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES SI PLUS ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220E,
+ },
+ [0x1220F]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES SIK0x0002 PLUS BU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1220F,
+ },
+ [0x12210]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TIMES TUG0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12210,
+ },
+ [0x12211]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12211,
+ },
+ [0x12212]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 CROSSING LU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12212,
+ },
+ [0x12213]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 OPPOSING LU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12213,
+ },
+ [0x12214]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 SQUARED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12214,
+ },
+ [0x12215]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0002 SHESHIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12215,
+ },
+ [0x12216]={
+ category="lo",
+ description="CUNEIFORM SIGN LU0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12216,
+ },
+ [0x12217]={
+ category="lo",
+ description="CUNEIFORM SIGN LUGAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12217,
+ },
+ [0x12218]={
+ category="lo",
+ description="CUNEIFORM SIGN LUGAL OVER LUGAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12218,
+ },
+ [0x12219]={
+ category="lo",
+ description="CUNEIFORM SIGN LUGAL OPPOSING LUGAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12219,
+ },
+ [0x1221A]={
+ category="lo",
+ description="CUNEIFORM SIGN LUGAL SHESHIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221A,
+ },
+ [0x1221B]={
+ category="lo",
+ description="CUNEIFORM SIGN LUH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221B,
+ },
+ [0x1221C]={
+ category="lo",
+ description="CUNEIFORM SIGN LUL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221C,
+ },
+ [0x1221D]={
+ category="lo",
+ description="CUNEIFORM SIGN LUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221D,
+ },
+ [0x1221E]={
+ category="lo",
+ description="CUNEIFORM SIGN LUM OVER LUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221E,
+ },
+ [0x1221F]={
+ category="lo",
+ description="CUNEIFORM SIGN LUM OVER LUM GAR OVER GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1221F,
+ },
+ [0x12220]={
+ category="lo",
+ description="CUNEIFORM SIGN MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12220,
+ },
+ [0x12221]={
+ category="lo",
+ description="CUNEIFORM SIGN MA TIMES TAK0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12221,
+ },
+ [0x12222]={
+ category="lo",
+ description="CUNEIFORM SIGN MA GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12222,
+ },
+ [0x12223]={
+ category="lo",
+ description="CUNEIFORM SIGN MA0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12223,
+ },
+ [0x12224]={
+ category="lo",
+ description="CUNEIFORM SIGN MAH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12224,
+ },
+ [0x12225]={
+ category="lo",
+ description="CUNEIFORM SIGN MAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12225,
+ },
+ [0x12226]={
+ category="lo",
+ description="CUNEIFORM SIGN MASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12226,
+ },
+ [0x12227]={
+ category="lo",
+ description="CUNEIFORM SIGN MASH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12227,
+ },
+ [0x12228]={
+ category="lo",
+ description="CUNEIFORM SIGN ME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12228,
+ },
+ [0x12229]={
+ category="lo",
+ description="CUNEIFORM SIGN MES",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12229,
+ },
+ [0x1222A]={
+ category="lo",
+ description="CUNEIFORM SIGN MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222A,
+ },
+ [0x1222B]={
+ category="lo",
+ description="CUNEIFORM SIGN MIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222B,
+ },
+ [0x1222C]={
+ category="lo",
+ description="CUNEIFORM SIGN MU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222C,
+ },
+ [0x1222D]={
+ category="lo",
+ description="CUNEIFORM SIGN MU OVER MU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222D,
+ },
+ [0x1222E]={
+ category="lo",
+ description="CUNEIFORM SIGN MUG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222E,
+ },
+ [0x1222F]={
+ category="lo",
+ description="CUNEIFORM SIGN MUG GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1222F,
+ },
+ [0x12230]={
+ category="lo",
+ description="CUNEIFORM SIGN MUNSUB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12230,
+ },
+ [0x12231]={
+ category="lo",
+ description="CUNEIFORM SIGN MURGU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12231,
+ },
+ [0x12232]={
+ category="lo",
+ description="CUNEIFORM SIGN MUSH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12232,
+ },
+ [0x12233]={
+ category="lo",
+ description="CUNEIFORM SIGN MUSH TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12233,
+ },
+ [0x12234]={
+ category="lo",
+ description="CUNEIFORM SIGN MUSH TIMES KUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12234,
+ },
+ [0x12235]={
+ category="lo",
+ description="CUNEIFORM SIGN MUSH TIMES ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12235,
+ },
+ [0x12236]={
+ category="lo",
+ description="CUNEIFORM SIGN MUSH OVER MUSH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12236,
+ },
+ [0x12237]={
+ category="lo",
+ description="CUNEIFORM SIGN MUSH OVER MUSH TIMES A PLUS NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12237,
+ },
+ [0x12238]={
+ category="lo",
+ description="CUNEIFORM SIGN MUSH CROSSING MUSH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12238,
+ },
+ [0x12239]={
+ category="lo",
+ description="CUNEIFORM SIGN MUSH0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12239,
+ },
+ [0x1223A]={
+ category="lo",
+ description="CUNEIFORM SIGN MUSH0x0003 TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223A,
+ },
+ [0x1223B]={
+ category="lo",
+ description="CUNEIFORM SIGN MUSH0x0003 TIMES A PLUS DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223B,
+ },
+ [0x1223C]={
+ category="lo",
+ description="CUNEIFORM SIGN MUSH0x0003 TIMES DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223C,
+ },
+ [0x1223D]={
+ category="lo",
+ description="CUNEIFORM SIGN MUSH0x0003 GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223D,
+ },
+ [0x1223E]={
+ category="lo",
+ description="CUNEIFORM SIGN NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223E,
+ },
+ [0x1223F]={
+ category="lo",
+ description="CUNEIFORM SIGN NA0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1223F,
+ },
+ [0x12240]={
+ category="lo",
+ description="CUNEIFORM SIGN NAGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12240,
+ },
+ [0x12241]={
+ category="lo",
+ description="CUNEIFORM SIGN NAGA INVERTED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12241,
+ },
+ [0x12242]={
+ category="lo",
+ description="CUNEIFORM SIGN NAGA TIMES SHU TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12242,
+ },
+ [0x12243]={
+ category="lo",
+ description="CUNEIFORM SIGN NAGA OPPOSING NAGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12243,
+ },
+ [0x12244]={
+ category="lo",
+ description="CUNEIFORM SIGN NAGAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12244,
+ },
+ [0x12245]={
+ category="lo",
+ description="CUNEIFORM SIGN NAM NUTILLU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12245,
+ },
+ [0x12246]={
+ category="lo",
+ description="CUNEIFORM SIGN NAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12246,
+ },
+ [0x12247]={
+ category="lo",
+ description="CUNEIFORM SIGN NAM0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12247,
+ },
+ [0x12248]={
+ category="lo",
+ description="CUNEIFORM SIGN NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12248,
+ },
+ [0x12249]={
+ category="lo",
+ description="CUNEIFORM SIGN NE TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12249,
+ },
+ [0x1224A]={
+ category="lo",
+ description="CUNEIFORM SIGN NE TIMES UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224A,
+ },
+ [0x1224B]={
+ category="lo",
+ description="CUNEIFORM SIGN NE SHESHIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224B,
+ },
+ [0x1224C]={
+ category="lo",
+ description="CUNEIFORM SIGN NI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224C,
+ },
+ [0x1224D]={
+ category="lo",
+ description="CUNEIFORM SIGN NI TIMES E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224D,
+ },
+ [0x1224E]={
+ category="lo",
+ description="CUNEIFORM SIGN NI0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224E,
+ },
+ [0x1224F]={
+ category="lo",
+ description="CUNEIFORM SIGN NIM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1224F,
+ },
+ [0x12250]={
+ category="lo",
+ description="CUNEIFORM SIGN NIM TIMES GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12250,
+ },
+ [0x12251]={
+ category="lo",
+ description="CUNEIFORM SIGN NIM TIMES GAR PLUS GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12251,
+ },
+ [0x12252]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12252,
+ },
+ [0x12253]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12253,
+ },
+ [0x12254]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12254,
+ },
+ [0x12255]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES ASH PLUS ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12255,
+ },
+ [0x12256]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES GUD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12256,
+ },
+ [0x12257]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES ME PLUS GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12257,
+ },
+ [0x12258]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12258,
+ },
+ [0x12259]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12259,
+ },
+ [0x1225A]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225A,
+ },
+ [0x1225B]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES SHE PLUS A AN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225B,
+ },
+ [0x1225C]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES SHE PLUS ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225C,
+ },
+ [0x1225D]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES SHE PLUS ASH PLUS ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225D,
+ },
+ [0x1225E]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES U0x0002 PLUS ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225E,
+ },
+ [0x1225F]={
+ category="lo",
+ description="CUNEIFORM SIGN NINDA0x0002 TIMES USH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1225F,
+ },
+ [0x12260]={
+ category="lo",
+ description="CUNEIFORM SIGN NISAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12260,
+ },
+ [0x12261]={
+ category="lo",
+ description="CUNEIFORM SIGN NU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12261,
+ },
+ [0x12262]={
+ category="lo",
+ description="CUNEIFORM SIGN NU0x000B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12262,
+ },
+ [0x12263]={
+ category="lo",
+ description="CUNEIFORM SIGN NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12263,
+ },
+ [0x12264]={
+ category="lo",
+ description="CUNEIFORM SIGN NUN LAGAR TIMES GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12264,
+ },
+ [0x12265]={
+ category="lo",
+ description="CUNEIFORM SIGN NUN LAGAR TIMES MASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12265,
+ },
+ [0x12266]={
+ category="lo",
+ description="CUNEIFORM SIGN NUN LAGAR TIMES SAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12266,
+ },
+ [0x12267]={
+ category="lo",
+ description="CUNEIFORM SIGN NUN LAGAR TIMES SAL OVER NUN LAGAR TIMES SAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12267,
+ },
+ [0x12268]={
+ category="lo",
+ description="CUNEIFORM SIGN NUN LAGAR TIMES USH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12268,
+ },
+ [0x12269]={
+ category="lo",
+ description="CUNEIFORM SIGN NUN TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12269,
+ },
+ [0x1226A]={
+ category="lo",
+ description="CUNEIFORM SIGN NUN OVER NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226A,
+ },
+ [0x1226B]={
+ category="lo",
+ description="CUNEIFORM SIGN NUN CROSSING NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226B,
+ },
+ [0x1226C]={
+ category="lo",
+ description="CUNEIFORM SIGN NUN CROSSING NUN LAGAR OVER LAGAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226C,
+ },
+ [0x1226D]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226D,
+ },
+ [0x1226E]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES ASHGAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226E,
+ },
+ [0x1226F]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES BI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1226F,
+ },
+ [0x12270]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES DUG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12270,
+ },
+ [0x12271]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES GUD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12271,
+ },
+ [0x12272]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES IGI GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12272,
+ },
+ [0x12273]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES KAD0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12273,
+ },
+ [0x12274]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12274,
+ },
+ [0x12275]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12275,
+ },
+ [0x12276]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES SILA0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12276,
+ },
+ [0x12277]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ AB0x0002 TIMES U0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12277,
+ },
+ [0x12278]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ KISIM0x0005 TIMES BI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12278,
+ },
+ [0x12279]={
+ category="lo",
+ description="CUNEIFORM SIGN NUNUZ KISIM0x0005 TIMES BI U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12279,
+ },
+ [0x1227A]={
+ category="lo",
+ description="CUNEIFORM SIGN PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227A,
+ },
+ [0x1227B]={
+ category="lo",
+ description="CUNEIFORM SIGN PAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227B,
+ },
+ [0x1227C]={
+ category="lo",
+ description="CUNEIFORM SIGN PAN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227C,
+ },
+ [0x1227D]={
+ category="lo",
+ description="CUNEIFORM SIGN PAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227D,
+ },
+ [0x1227E]={
+ category="lo",
+ description="CUNEIFORM SIGN PESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227E,
+ },
+ [0x1227F]={
+ category="lo",
+ description="CUNEIFORM SIGN PI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1227F,
+ },
+ [0x12280]={
+ category="lo",
+ description="CUNEIFORM SIGN PI TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12280,
+ },
+ [0x12281]={
+ category="lo",
+ description="CUNEIFORM SIGN PI TIMES AB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12281,
+ },
+ [0x12282]={
+ category="lo",
+ description="CUNEIFORM SIGN PI TIMES BI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12282,
+ },
+ [0x12283]={
+ category="lo",
+ description="CUNEIFORM SIGN PI TIMES BU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12283,
+ },
+ [0x12284]={
+ category="lo",
+ description="CUNEIFORM SIGN PI TIMES E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12284,
+ },
+ [0x12285]={
+ category="lo",
+ description="CUNEIFORM SIGN PI TIMES I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12285,
+ },
+ [0x12286]={
+ category="lo",
+ description="CUNEIFORM SIGN PI TIMES IB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12286,
+ },
+ [0x12287]={
+ category="lo",
+ description="CUNEIFORM SIGN PI TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12287,
+ },
+ [0x12288]={
+ category="lo",
+ description="CUNEIFORM SIGN PI TIMES U0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12288,
+ },
+ [0x12289]={
+ category="lo",
+ description="CUNEIFORM SIGN PI CROSSING PI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12289,
+ },
+ [0x1228A]={
+ category="lo",
+ description="CUNEIFORM SIGN PIRIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228A,
+ },
+ [0x1228B]={
+ category="lo",
+ description="CUNEIFORM SIGN PIRIG TIMES KAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228B,
+ },
+ [0x1228C]={
+ category="lo",
+ description="CUNEIFORM SIGN PIRIG TIMES UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228C,
+ },
+ [0x1228D]={
+ category="lo",
+ description="CUNEIFORM SIGN PIRIG TIMES ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228D,
+ },
+ [0x1228E]={
+ category="lo",
+ description="CUNEIFORM SIGN PIRIG OPPOSING PIRIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228E,
+ },
+ [0x1228F]={
+ category="lo",
+ description="CUNEIFORM SIGN RA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1228F,
+ },
+ [0x12290]={
+ category="lo",
+ description="CUNEIFORM SIGN RAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12290,
+ },
+ [0x12291]={
+ category="lo",
+ description="CUNEIFORM SIGN RI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12291,
+ },
+ [0x12292]={
+ category="lo",
+ description="CUNEIFORM SIGN RU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12292,
+ },
+ [0x12293]={
+ category="lo",
+ description="CUNEIFORM SIGN SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12293,
+ },
+ [0x12294]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG NUTILLU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12294,
+ },
+ [0x12295]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12295,
+ },
+ [0x12296]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12296,
+ },
+ [0x12297]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES DU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12297,
+ },
+ [0x12298]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES DUB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12298,
+ },
+ [0x12299]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12299,
+ },
+ [0x1229A]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES KAK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229A,
+ },
+ [0x1229B]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES KUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229B,
+ },
+ [0x1229C]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES LUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229C,
+ },
+ [0x1229D]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229D,
+ },
+ [0x1229E]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229E,
+ },
+ [0x1229F]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES SAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1229F,
+ },
+ [0x122A0]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES SHID",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A0,
+ },
+ [0x122A1]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES TAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A1,
+ },
+ [0x122A2]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES U0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A2,
+ },
+ [0x122A3]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES UB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A3,
+ },
+ [0x122A4]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES UM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A4,
+ },
+ [0x122A5]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES UR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A5,
+ },
+ [0x122A6]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG TIMES USH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A6,
+ },
+ [0x122A7]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG OVER SAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A7,
+ },
+ [0x122A8]={
+ category="lo",
+ description="CUNEIFORM SIGN SAG GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A8,
+ },
+ [0x122A9]={
+ category="lo",
+ description="CUNEIFORM SIGN SAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122A9,
+ },
+ [0x122AA]={
+ category="lo",
+ description="CUNEIFORM SIGN SAL LAGAB TIMES ASH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122AA,
+ },
+ [0x122AB]={
+ category="lo",
+ description="CUNEIFORM SIGN SANGA0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122AB,
+ },
+ [0x122AC]={
+ category="lo",
+ description="CUNEIFORM SIGN SAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122AC,
+ },
+ [0x122AD]={
+ category="lo",
+ description="CUNEIFORM SIGN SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122AD,
+ },
+ [0x122AE]={
+ category="lo",
+ description="CUNEIFORM SIGN SHA0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122AE,
+ },
+ [0x122AF]={
+ category="lo",
+ description="CUNEIFORM SIGN SHA0x0003 TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122AF,
+ },
+ [0x122B0]={
+ category="lo",
+ description="CUNEIFORM SIGN SHA0x0003 TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B0,
+ },
+ [0x122B1]={
+ category="lo",
+ description="CUNEIFORM SIGN SHA0x0003 TIMES GISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B1,
+ },
+ [0x122B2]={
+ category="lo",
+ description="CUNEIFORM SIGN SHA0x0003 TIMES NE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B2,
+ },
+ [0x122B3]={
+ category="lo",
+ description="CUNEIFORM SIGN SHA0x0003 TIMES SHU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B3,
+ },
+ [0x122B4]={
+ category="lo",
+ description="CUNEIFORM SIGN SHA0x0003 TIMES TUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B4,
+ },
+ [0x122B5]={
+ category="lo",
+ description="CUNEIFORM SIGN SHA0x0003 TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B5,
+ },
+ [0x122B6]={
+ category="lo",
+ description="CUNEIFORM SIGN SHA0x0003 TIMES U PLUS A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B6,
+ },
+ [0x122B7]={
+ category="lo",
+ description="CUNEIFORM SIGN SHA0x0006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B7,
+ },
+ [0x122B8]={
+ category="lo",
+ description="CUNEIFORM SIGN SHAB0x0006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B8,
+ },
+ [0x122B9]={
+ category="lo",
+ description="CUNEIFORM SIGN SHAR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122B9,
+ },
+ [0x122BA]={
+ category="lo",
+ description="CUNEIFORM SIGN SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122BA,
+ },
+ [0x122BB]={
+ category="lo",
+ description="CUNEIFORM SIGN SHE HU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122BB,
+ },
+ [0x122BC]={
+ category="lo",
+ description="CUNEIFORM SIGN SHE OVER SHE GAD OVER GAD GAR OVER GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122BC,
+ },
+ [0x122BD]={
+ category="lo",
+ description="CUNEIFORM SIGN SHE OVER SHE TAB OVER TAB GAR OVER GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122BD,
+ },
+ [0x122BE]={
+ category="lo",
+ description="CUNEIFORM SIGN SHEG0x0009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122BE,
+ },
+ [0x122BF]={
+ category="lo",
+ description="CUNEIFORM SIGN SHEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122BF,
+ },
+ [0x122C0]={
+ category="lo",
+ description="CUNEIFORM SIGN SHESH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C0,
+ },
+ [0x122C1]={
+ category="lo",
+ description="CUNEIFORM SIGN SHESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C1,
+ },
+ [0x122C2]={
+ category="lo",
+ description="CUNEIFORM SIGN SHESHLAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C2,
+ },
+ [0x122C3]={
+ category="lo",
+ description="CUNEIFORM SIGN SHID",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C3,
+ },
+ [0x122C4]={
+ category="lo",
+ description="CUNEIFORM SIGN SHID TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C4,
+ },
+ [0x122C5]={
+ category="lo",
+ description="CUNEIFORM SIGN SHID TIMES IM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C5,
+ },
+ [0x122C6]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C6,
+ },
+ [0x122C7]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIM TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C7,
+ },
+ [0x122C8]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIM TIMES BAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C8,
+ },
+ [0x122C9]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIM TIMES BULUG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122C9,
+ },
+ [0x122CA]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIM TIMES DIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122CA,
+ },
+ [0x122CB]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIM TIMES GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122CB,
+ },
+ [0x122CC]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIM TIMES IGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122CC,
+ },
+ [0x122CD]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIM TIMES IGI GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122CD,
+ },
+ [0x122CE]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIM TIMES KUSHU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122CE,
+ },
+ [0x122CF]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIM TIMES LUL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122CF,
+ },
+ [0x122D0]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIM TIMES MUG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D0,
+ },
+ [0x122D1]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIM TIMES SAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D1,
+ },
+ [0x122D2]={
+ category="lo",
+ description="CUNEIFORM SIGN SHINIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D2,
+ },
+ [0x122D3]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D3,
+ },
+ [0x122D4]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIR TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D4,
+ },
+ [0x122D5]={
+ category="lo",
+ description="CUNEIFORM SIGN SHIR OVER SHIR BUR OVER BUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D5,
+ },
+ [0x122D6]={
+ category="lo",
+ description="CUNEIFORM SIGN SHITA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D6,
+ },
+ [0x122D7]={
+ category="lo",
+ description="CUNEIFORM SIGN SHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D7,
+ },
+ [0x122D8]={
+ category="lo",
+ description="CUNEIFORM SIGN SHU OVER INVERTED SHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D8,
+ },
+ [0x122D9]={
+ category="lo",
+ description="CUNEIFORM SIGN SHU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122D9,
+ },
+ [0x122DA]={
+ category="lo",
+ description="CUNEIFORM SIGN SHUBUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122DA,
+ },
+ [0x122DB]={
+ category="lo",
+ description="CUNEIFORM SIGN SI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122DB,
+ },
+ [0x122DC]={
+ category="lo",
+ description="CUNEIFORM SIGN SI GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122DC,
+ },
+ [0x122DD]={
+ category="lo",
+ description="CUNEIFORM SIGN SIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122DD,
+ },
+ [0x122DE]={
+ category="lo",
+ description="CUNEIFORM SIGN SIG0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122DE,
+ },
+ [0x122DF]={
+ category="lo",
+ description="CUNEIFORM SIGN SIG0x0004 OVER SIG0x0004 SHU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122DF,
+ },
+ [0x122E0]={
+ category="lo",
+ description="CUNEIFORM SIGN SIK0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E0,
+ },
+ [0x122E1]={
+ category="lo",
+ description="CUNEIFORM SIGN SILA0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E1,
+ },
+ [0x122E2]={
+ category="lo",
+ description="CUNEIFORM SIGN SU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E2,
+ },
+ [0x122E3]={
+ category="lo",
+ description="CUNEIFORM SIGN SU OVER SU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E3,
+ },
+ [0x122E4]={
+ category="lo",
+ description="CUNEIFORM SIGN SUD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E4,
+ },
+ [0x122E5]={
+ category="lo",
+ description="CUNEIFORM SIGN SUD0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E5,
+ },
+ [0x122E6]={
+ category="lo",
+ description="CUNEIFORM SIGN SUHUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E6,
+ },
+ [0x122E7]={
+ category="lo",
+ description="CUNEIFORM SIGN SUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E7,
+ },
+ [0x122E8]={
+ category="lo",
+ description="CUNEIFORM SIGN SUMASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E8,
+ },
+ [0x122E9]={
+ category="lo",
+ description="CUNEIFORM SIGN SUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122E9,
+ },
+ [0x122EA]={
+ category="lo",
+ description="CUNEIFORM SIGN SUR0x0009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122EA,
+ },
+ [0x122EB]={
+ category="lo",
+ description="CUNEIFORM SIGN TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122EB,
+ },
+ [0x122EC]={
+ category="lo",
+ description="CUNEIFORM SIGN TA ASTERISK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122EC,
+ },
+ [0x122ED]={
+ category="lo",
+ description="CUNEIFORM SIGN TA TIMES HI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122ED,
+ },
+ [0x122EE]={
+ category="lo",
+ description="CUNEIFORM SIGN TA TIMES MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122EE,
+ },
+ [0x122EF]={
+ category="lo",
+ description="CUNEIFORM SIGN TA GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122EF,
+ },
+ [0x122F0]={
+ category="lo",
+ description="CUNEIFORM SIGN TAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F0,
+ },
+ [0x122F1]={
+ category="lo",
+ description="CUNEIFORM SIGN TAB OVER TAB NI OVER NI DISH OVER DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F1,
+ },
+ [0x122F2]={
+ category="lo",
+ description="CUNEIFORM SIGN TAB SQUARED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F2,
+ },
+ [0x122F3]={
+ category="lo",
+ description="CUNEIFORM SIGN TAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F3,
+ },
+ [0x122F4]={
+ category="lo",
+ description="CUNEIFORM SIGN TAG TIMES BI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F4,
+ },
+ [0x122F5]={
+ category="lo",
+ description="CUNEIFORM SIGN TAG TIMES GUD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F5,
+ },
+ [0x122F6]={
+ category="lo",
+ description="CUNEIFORM SIGN TAG TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F6,
+ },
+ [0x122F7]={
+ category="lo",
+ description="CUNEIFORM SIGN TAG TIMES SHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F7,
+ },
+ [0x122F8]={
+ category="lo",
+ description="CUNEIFORM SIGN TAG TIMES TUG0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F8,
+ },
+ [0x122F9]={
+ category="lo",
+ description="CUNEIFORM SIGN TAG TIMES UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122F9,
+ },
+ [0x122FA]={
+ category="lo",
+ description="CUNEIFORM SIGN TAK0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122FA,
+ },
+ [0x122FB]={
+ category="lo",
+ description="CUNEIFORM SIGN TAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122FB,
+ },
+ [0x122FC]={
+ category="lo",
+ description="CUNEIFORM SIGN TE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122FC,
+ },
+ [0x122FD]={
+ category="lo",
+ description="CUNEIFORM SIGN TE GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122FD,
+ },
+ [0x122FE]={
+ category="lo",
+ description="CUNEIFORM SIGN TI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122FE,
+ },
+ [0x122FF]={
+ category="lo",
+ description="CUNEIFORM SIGN TI TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x122FF,
+ },
+ [0x12300]={
+ category="lo",
+ description="CUNEIFORM SIGN TIL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12300,
+ },
+ [0x12301]={
+ category="lo",
+ description="CUNEIFORM SIGN TIR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12301,
+ },
+ [0x12302]={
+ category="lo",
+ description="CUNEIFORM SIGN TIR TIMES TAK0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12302,
+ },
+ [0x12303]={
+ category="lo",
+ description="CUNEIFORM SIGN TIR OVER TIR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12303,
+ },
+ [0x12304]={
+ category="lo",
+ description="CUNEIFORM SIGN TIR OVER TIR GAD OVER GAD GAR OVER GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12304,
+ },
+ [0x12305]={
+ category="lo",
+ description="CUNEIFORM SIGN TU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12305,
+ },
+ [0x12306]={
+ category="lo",
+ description="CUNEIFORM SIGN TUG0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12306,
+ },
+ [0x12307]={
+ category="lo",
+ description="CUNEIFORM SIGN TUK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12307,
+ },
+ [0x12308]={
+ category="lo",
+ description="CUNEIFORM SIGN TUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12308,
+ },
+ [0x12309]={
+ category="lo",
+ description="CUNEIFORM SIGN TUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12309,
+ },
+ [0x1230A]={
+ category="lo",
+ description="CUNEIFORM SIGN TUR OVER TUR ZA OVER ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230A,
+ },
+ [0x1230B]={
+ category="lo",
+ description="CUNEIFORM SIGN U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230B,
+ },
+ [0x1230C]={
+ category="lo",
+ description="CUNEIFORM SIGN U GUD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230C,
+ },
+ [0x1230D]={
+ category="lo",
+ description="CUNEIFORM SIGN U U U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230D,
+ },
+ [0x1230E]={
+ category="lo",
+ description="CUNEIFORM SIGN U OVER U PA OVER PA GAR OVER GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230E,
+ },
+ [0x1230F]={
+ category="lo",
+ description="CUNEIFORM SIGN U OVER U SUR OVER SUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1230F,
+ },
+ [0x12310]={
+ category="lo",
+ description="CUNEIFORM SIGN U OVER U U REVERSED OVER U REVERSED",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12310,
+ },
+ [0x12311]={
+ category="lo",
+ description="CUNEIFORM SIGN U0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12311,
+ },
+ [0x12312]={
+ category="lo",
+ description="CUNEIFORM SIGN UB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12312,
+ },
+ [0x12313]={
+ category="lo",
+ description="CUNEIFORM SIGN UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12313,
+ },
+ [0x12314]={
+ category="lo",
+ description="CUNEIFORM SIGN UD KUSHU0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12314,
+ },
+ [0x12315]={
+ category="lo",
+ description="CUNEIFORM SIGN UD TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12315,
+ },
+ [0x12316]={
+ category="lo",
+ description="CUNEIFORM SIGN UD TIMES MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12316,
+ },
+ [0x12317]={
+ category="lo",
+ description="CUNEIFORM SIGN UD TIMES U PLUS U PLUS U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12317,
+ },
+ [0x12318]={
+ category="lo",
+ description="CUNEIFORM SIGN UD TIMES U PLUS U PLUS U GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12318,
+ },
+ [0x12319]={
+ category="lo",
+ description="CUNEIFORM SIGN UD GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12319,
+ },
+ [0x1231A]={
+ category="lo",
+ description="CUNEIFORM SIGN UD SHESHIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231A,
+ },
+ [0x1231B]={
+ category="lo",
+ description="CUNEIFORM SIGN UD SHESHIG TIMES BAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231B,
+ },
+ [0x1231C]={
+ category="lo",
+ description="CUNEIFORM SIGN UDUG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231C,
+ },
+ [0x1231D]={
+ category="lo",
+ description="CUNEIFORM SIGN UM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231D,
+ },
+ [0x1231E]={
+ category="lo",
+ description="CUNEIFORM SIGN UM TIMES LAGAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231E,
+ },
+ [0x1231F]={
+ category="lo",
+ description="CUNEIFORM SIGN UM TIMES ME PLUS DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1231F,
+ },
+ [0x12320]={
+ category="lo",
+ description="CUNEIFORM SIGN UM TIMES SHA0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12320,
+ },
+ [0x12321]={
+ category="lo",
+ description="CUNEIFORM SIGN UM TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12321,
+ },
+ [0x12322]={
+ category="lo",
+ description="CUNEIFORM SIGN UMBIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12322,
+ },
+ [0x12323]={
+ category="lo",
+ description="CUNEIFORM SIGN UMUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12323,
+ },
+ [0x12324]={
+ category="lo",
+ description="CUNEIFORM SIGN UMUM TIMES KASKAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12324,
+ },
+ [0x12325]={
+ category="lo",
+ description="CUNEIFORM SIGN UMUM TIMES PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12325,
+ },
+ [0x12326]={
+ category="lo",
+ description="CUNEIFORM SIGN UN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12326,
+ },
+ [0x12327]={
+ category="lo",
+ description="CUNEIFORM SIGN UN GUNU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12327,
+ },
+ [0x12328]={
+ category="lo",
+ description="CUNEIFORM SIGN UR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12328,
+ },
+ [0x12329]={
+ category="lo",
+ description="CUNEIFORM SIGN UR CROSSING UR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12329,
+ },
+ [0x1232A]={
+ category="lo",
+ description="CUNEIFORM SIGN UR SHESHIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232A,
+ },
+ [0x1232B]={
+ category="lo",
+ description="CUNEIFORM SIGN UR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232B,
+ },
+ [0x1232C]={
+ category="lo",
+ description="CUNEIFORM SIGN UR0x0002 TIMES A PLUS HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232C,
+ },
+ [0x1232D]={
+ category="lo",
+ description="CUNEIFORM SIGN UR0x0002 TIMES A PLUS NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232D,
+ },
+ [0x1232E]={
+ category="lo",
+ description="CUNEIFORM SIGN UR0x0002 TIMES AL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232E,
+ },
+ [0x1232F]={
+ category="lo",
+ description="CUNEIFORM SIGN UR0x0002 TIMES HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1232F,
+ },
+ [0x12330]={
+ category="lo",
+ description="CUNEIFORM SIGN UR0x0002 TIMES NUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12330,
+ },
+ [0x12331]={
+ category="lo",
+ description="CUNEIFORM SIGN UR0x0002 TIMES U0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12331,
+ },
+ [0x12332]={
+ category="lo",
+ description="CUNEIFORM SIGN UR0x0002 TIMES U0x0002 PLUS ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12332,
+ },
+ [0x12333]={
+ category="lo",
+ description="CUNEIFORM SIGN UR0x0002 TIMES U0x0002 PLUS BI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12333,
+ },
+ [0x12334]={
+ category="lo",
+ description="CUNEIFORM SIGN UR0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12334,
+ },
+ [0x12335]={
+ category="lo",
+ description="CUNEIFORM SIGN URI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12335,
+ },
+ [0x12336]={
+ category="lo",
+ description="CUNEIFORM SIGN URI0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12336,
+ },
+ [0x12337]={
+ category="lo",
+ description="CUNEIFORM SIGN URU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12337,
+ },
+ [0x12338]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12338,
+ },
+ [0x12339]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES ASHGAB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12339,
+ },
+ [0x1233A]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES BAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233A,
+ },
+ [0x1233B]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES DUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233B,
+ },
+ [0x1233C]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233C,
+ },
+ [0x1233D]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES GAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233D,
+ },
+ [0x1233E]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES GAN0x0002 TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233E,
+ },
+ [0x1233F]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES GAR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1233F,
+ },
+ [0x12340]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES GU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12340,
+ },
+ [0x12341]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12341,
+ },
+ [0x12342]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES IGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12342,
+ },
+ [0x12343]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES IM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12343,
+ },
+ [0x12344]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES ISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12344,
+ },
+ [0x12345]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12345,
+ },
+ [0x12346]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES LUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12346,
+ },
+ [0x12347]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES MIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12347,
+ },
+ [0x12348]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12348,
+ },
+ [0x12349]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES SHE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12349,
+ },
+ [0x1234A]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES SIG0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234A,
+ },
+ [0x1234B]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES TU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234B,
+ },
+ [0x1234C]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES U PLUS GUD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234C,
+ },
+ [0x1234D]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES UD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234D,
+ },
+ [0x1234E]={
+ category="lo",
+ description="CUNEIFORM SIGN URU TIMES URUDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234E,
+ },
+ [0x1234F]={
+ category="lo",
+ description="CUNEIFORM SIGN URUDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1234F,
+ },
+ [0x12350]={
+ category="lo",
+ description="CUNEIFORM SIGN URUDA TIMES U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12350,
+ },
+ [0x12351]={
+ category="lo",
+ description="CUNEIFORM SIGN USH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12351,
+ },
+ [0x12352]={
+ category="lo",
+ description="CUNEIFORM SIGN USH TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12352,
+ },
+ [0x12353]={
+ category="lo",
+ description="CUNEIFORM SIGN USH TIMES KU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12353,
+ },
+ [0x12354]={
+ category="lo",
+ description="CUNEIFORM SIGN USH TIMES KUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12354,
+ },
+ [0x12355]={
+ category="lo",
+ description="CUNEIFORM SIGN USH TIMES TAK0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12355,
+ },
+ [0x12356]={
+ category="lo",
+ description="CUNEIFORM SIGN USHX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12356,
+ },
+ [0x12357]={
+ category="lo",
+ description="CUNEIFORM SIGN USH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12357,
+ },
+ [0x12358]={
+ category="lo",
+ description="CUNEIFORM SIGN USHUMX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12358,
+ },
+ [0x12359]={
+ category="lo",
+ description="CUNEIFORM SIGN UTUKI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12359,
+ },
+ [0x1235A]={
+ category="lo",
+ description="CUNEIFORM SIGN UZ0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235A,
+ },
+ [0x1235B]={
+ category="lo",
+ description="CUNEIFORM SIGN UZ0x0003 TIMES KASKAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235B,
+ },
+ [0x1235C]={
+ category="lo",
+ description="CUNEIFORM SIGN UZU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235C,
+ },
+ [0x1235D]={
+ category="lo",
+ description="CUNEIFORM SIGN ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235D,
+ },
+ [0x1235E]={
+ category="lo",
+ description="CUNEIFORM SIGN ZA TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235E,
+ },
+ [0x1235F]={
+ category="lo",
+ description="CUNEIFORM SIGN ZA SQUARED TIMES KUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1235F,
+ },
+ [0x12360]={
+ category="lo",
+ description="CUNEIFORM SIGN ZAG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12360,
+ },
+ [0x12361]={
+ category="lo",
+ description="CUNEIFORM SIGN ZAMX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12361,
+ },
+ [0x12362]={
+ category="lo",
+ description="CUNEIFORM SIGN ZE0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12362,
+ },
+ [0x12363]={
+ category="lo",
+ description="CUNEIFORM SIGN ZI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12363,
+ },
+ [0x12364]={
+ category="lo",
+ description="CUNEIFORM SIGN ZI OVER ZI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12364,
+ },
+ [0x12365]={
+ category="lo",
+ description="CUNEIFORM SIGN ZI0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12365,
+ },
+ [0x12366]={
+ category="lo",
+ description="CUNEIFORM SIGN ZIB",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12366,
+ },
+ [0x12367]={
+ category="lo",
+ description="CUNEIFORM SIGN ZIB KABA TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12367,
+ },
+ [0x12368]={
+ category="lo",
+ description="CUNEIFORM SIGN ZIG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12368,
+ },
+ [0x12369]={
+ category="lo",
+ description="CUNEIFORM SIGN ZIZ0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12369,
+ },
+ [0x1236A]={
+ category="lo",
+ description="CUNEIFORM SIGN ZU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236A,
+ },
+ [0x1236B]={
+ category="lo",
+ description="CUNEIFORM SIGN ZU0x0005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236B,
+ },
+ [0x1236C]={
+ category="lo",
+ description="CUNEIFORM SIGN ZU0x0005 TIMES A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236C,
+ },
+ [0x1236D]={
+ category="lo",
+ description="CUNEIFORM SIGN ZUBUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236D,
+ },
+ [0x1236E]={
+ category="lo",
+ description="CUNEIFORM SIGN ZUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1236E,
+ },
+ [0x12400]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN TWO ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12400,
+ },
+ [0x12401]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12401,
+ },
+ [0x12402]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12402,
+ },
+ [0x12403]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FIVE ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12403,
+ },
+ [0x12404]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SIX ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12404,
+ },
+ [0x12405]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SEVEN ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12405,
+ },
+ [0x12406]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN EIGHT ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12406,
+ },
+ [0x12407]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN NINE ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12407,
+ },
+ [0x12408]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12408,
+ },
+ [0x12409]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12409,
+ },
+ [0x1240A]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FIVE DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240A,
+ },
+ [0x1240B]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SIX DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240B,
+ },
+ [0x1240C]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SEVEN DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240C,
+ },
+ [0x1240D]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN EIGHT DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240D,
+ },
+ [0x1240E]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN NINE DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240E,
+ },
+ [0x1240F]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1240F,
+ },
+ [0x12410]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FIVE U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12410,
+ },
+ [0x12411]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SIX U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12411,
+ },
+ [0x12412]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SEVEN U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12412,
+ },
+ [0x12413]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN EIGHT U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12413,
+ },
+ [0x12414]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN NINE U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12414,
+ },
+ [0x12415]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN ONE GESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12415,
+ },
+ [0x12416]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN TWO GESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12416,
+ },
+ [0x12417]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE GESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12417,
+ },
+ [0x12418]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR GESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12418,
+ },
+ [0x12419]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FIVE GESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12419,
+ },
+ [0x1241A]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SIX GESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241A,
+ },
+ [0x1241B]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SEVEN GESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241B,
+ },
+ [0x1241C]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN EIGHT GESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241C,
+ },
+ [0x1241D]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN NINE GESH0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241D,
+ },
+ [0x1241E]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN ONE GESHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241E,
+ },
+ [0x1241F]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN TWO GESHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1241F,
+ },
+ [0x12420]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE GESHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12420,
+ },
+ [0x12421]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR GESHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12421,
+ },
+ [0x12422]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FIVE GESHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12422,
+ },
+ [0x12423]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN TWO SHAR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12423,
+ },
+ [0x12424]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE SHAR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12424,
+ },
+ [0x12425]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE SHAR0x0002 VARIANT FORM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12425,
+ },
+ [0x12426]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR SHAR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12426,
+ },
+ [0x12427]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FIVE SHAR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12427,
+ },
+ [0x12428]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SIX SHAR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12428,
+ },
+ [0x12429]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SEVEN SHAR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12429,
+ },
+ [0x1242A]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN EIGHT SHAR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242A,
+ },
+ [0x1242B]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN NINE SHAR0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242B,
+ },
+ [0x1242C]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN ONE SHARU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242C,
+ },
+ [0x1242D]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN TWO SHARU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242D,
+ },
+ [0x1242E]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE SHARU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242E,
+ },
+ [0x1242F]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1242F,
+ },
+ [0x12430]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR SHARU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12430,
+ },
+ [0x12431]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FIVE SHARU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12431,
+ },
+ [0x12432]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SHAR0x0002 TIMES GAL PLUS DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12432,
+ },
+ [0x12433]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SHAR0x0002 TIMES GAL PLUS MIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12433,
+ },
+ [0x12434]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN ONE BURU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12434,
+ },
+ [0x12435]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN TWO BURU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12435,
+ },
+ [0x12436]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE BURU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12436,
+ },
+ [0x12437]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE BURU VARIANT FORM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12437,
+ },
+ [0x12438]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR BURU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12438,
+ },
+ [0x12439]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FIVE BURU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12439,
+ },
+ [0x1243A]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH0x0010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243A,
+ },
+ [0x1243B]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH0x0015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243B,
+ },
+ [0x1243C]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243C,
+ },
+ [0x1243D]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243D,
+ },
+ [0x1243E]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243E,
+ },
+ [0x1243F]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1243F,
+ },
+ [0x12440]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SIX VARIANT FORM ASH0x0009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12440,
+ },
+ [0x12441]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12441,
+ },
+ [0x12442]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12442,
+ },
+ [0x12443]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12443,
+ },
+ [0x12444]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12444,
+ },
+ [0x12445]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12445,
+ },
+ [0x12446]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12446,
+ },
+ [0x12447]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12447,
+ },
+ [0x12448]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12448,
+ },
+ [0x12449]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12449,
+ },
+ [0x1244A]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN TWO ASH TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244A,
+ },
+ [0x1244B]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE ASH TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244B,
+ },
+ [0x1244C]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR ASH TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244C,
+ },
+ [0x1244D]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FIVE ASH TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244D,
+ },
+ [0x1244E]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN SIX ASH TENU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244E,
+ },
+ [0x1244F]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN ONE BAN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1244F,
+ },
+ [0x12450]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN TWO BAN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12450,
+ },
+ [0x12451]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN THREE BAN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12451,
+ },
+ [0x12452]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR BAN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12452,
+ },
+ [0x12453]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FOUR BAN0x0002 VARIANT FORM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12453,
+ },
+ [0x12454]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FIVE BAN0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12454,
+ },
+ [0x12455]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FIVE BAN0x0002 VARIANT FORM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12455,
+ },
+ [0x12456]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN NIGIDAMIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12456,
+ },
+ [0x12457]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN NIGIDAESH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12457,
+ },
+ [0x12458]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN ONE ESHE0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12458,
+ },
+ [0x12459]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN TWO ESHE0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12459,
+ },
+ [0x1245A]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN ONE THIRD DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245A,
+ },
+ [0x1245B]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN TWO THIRDS DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245B,
+ },
+ [0x1245C]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN FIVE SIXTHS DISH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245C,
+ },
+ [0x1245D]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN ONE THIRD VARIANT FORM A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245D,
+ },
+ [0x1245E]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN TWO THIRDS VARIANT FORM A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245E,
+ },
+ [0x1245F]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN ONE EIGHTH ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1245F,
+ },
+ [0x12460]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN ONE QUARTER ASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12460,
+ },
+ [0x12461]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE SIXTH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12461,
+ },
+ [0x12462]={
+ category="nl",
+ description="CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x12462,
+ },
+ [0x12470]={
+ category="po",
+ description="CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x12470,
+ },
+ [0x12471]={
+ category="po",
+ description="CUNEIFORM PUNCTUATION SIGN VERTICAL COLON",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x12471,
+ },
+ [0x12472]={
+ category="po",
+ description="CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x12472,
+ },
+ [0x12473]={
+ category="po",
+ description="CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x12473,
+ },
+ [0x13000]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13000,
+ },
+ [0x13001]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13001,
+ },
+ [0x13002]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13002,
+ },
+ [0x13003]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13003,
+ },
+ [0x13004]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13004,
+ },
+ [0x13005]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A005A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13005,
+ },
+ [0x13006]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13006,
+ },
+ [0x13007]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A006A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13007,
+ },
+ [0x13008]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A006B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13008,
+ },
+ [0x13009]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13009,
+ },
+ [0x1300A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300A,
+ },
+ [0x1300B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300B,
+ },
+ [0x1300C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300C,
+ },
+ [0x1300D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300D,
+ },
+ [0x1300E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300E,
+ },
+ [0x1300F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1300F,
+ },
+ [0x13010]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13010,
+ },
+ [0x13011]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A014A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13011,
+ },
+ [0x13012]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13012,
+ },
+ [0x13013]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13013,
+ },
+ [0x13014]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13014,
+ },
+ [0x13015]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A017A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13015,
+ },
+ [0x13016]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13016,
+ },
+ [0x13017]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13017,
+ },
+ [0x13018]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13018,
+ },
+ [0x13019]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13019,
+ },
+ [0x1301A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301A,
+ },
+ [0x1301B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301B,
+ },
+ [0x1301C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301C,
+ },
+ [0x1301D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301D,
+ },
+ [0x1301E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301E,
+ },
+ [0x1301F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1301F,
+ },
+ [0x13020]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13020,
+ },
+ [0x13021]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13021,
+ },
+ [0x13022]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13022,
+ },
+ [0x13023]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13023,
+ },
+ [0x13024]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13024,
+ },
+ [0x13025]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A032A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13025,
+ },
+ [0x13026]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A033",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13026,
+ },
+ [0x13027]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A034",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13027,
+ },
+ [0x13028]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A035",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13028,
+ },
+ [0x13029]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A036",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13029,
+ },
+ [0x1302A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A037",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302A,
+ },
+ [0x1302B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302B,
+ },
+ [0x1302C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A039",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302C,
+ },
+ [0x1302D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A040",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302D,
+ },
+ [0x1302E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A040A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302E,
+ },
+ [0x1302F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A041",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1302F,
+ },
+ [0x13030]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A042",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13030,
+ },
+ [0x13031]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A042A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13031,
+ },
+ [0x13032]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A043",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13032,
+ },
+ [0x13033]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A043A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13033,
+ },
+ [0x13034]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A044",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13034,
+ },
+ [0x13035]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A045",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13035,
+ },
+ [0x13036]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A045A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13036,
+ },
+ [0x13037]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A046",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13037,
+ },
+ [0x13038]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A047",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13038,
+ },
+ [0x13039]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A048",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13039,
+ },
+ [0x1303A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A049",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303A,
+ },
+ [0x1303B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A050",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303B,
+ },
+ [0x1303C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A051",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303C,
+ },
+ [0x1303D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A052",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303D,
+ },
+ [0x1303E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A053",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303E,
+ },
+ [0x1303F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A054",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1303F,
+ },
+ [0x13040]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A055",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13040,
+ },
+ [0x13041]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A056",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13041,
+ },
+ [0x13042]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A057",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13042,
+ },
+ [0x13043]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A058",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13043,
+ },
+ [0x13044]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A059",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13044,
+ },
+ [0x13045]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A060",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13045,
+ },
+ [0x13046]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A061",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13046,
+ },
+ [0x13047]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A062",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13047,
+ },
+ [0x13048]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A063",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13048,
+ },
+ [0x13049]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A064",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13049,
+ },
+ [0x1304A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A065",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304A,
+ },
+ [0x1304B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A066",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304B,
+ },
+ [0x1304C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A067",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304C,
+ },
+ [0x1304D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A068",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304D,
+ },
+ [0x1304E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A069",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304E,
+ },
+ [0x1304F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH A070",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1304F,
+ },
+ [0x13050]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH B001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13050,
+ },
+ [0x13051]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH B002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13051,
+ },
+ [0x13052]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH B003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13052,
+ },
+ [0x13053]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH B004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13053,
+ },
+ [0x13054]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH B005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13054,
+ },
+ [0x13055]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH B005A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13055,
+ },
+ [0x13056]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH B006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13056,
+ },
+ [0x13057]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH B007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13057,
+ },
+ [0x13058]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH B008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13058,
+ },
+ [0x13059]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH B009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13059,
+ },
+ [0x1305A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305A,
+ },
+ [0x1305B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305B,
+ },
+ [0x1305C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C002A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305C,
+ },
+ [0x1305D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C002B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305D,
+ },
+ [0x1305E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C002C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305E,
+ },
+ [0x1305F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1305F,
+ },
+ [0x13060]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13060,
+ },
+ [0x13061]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13061,
+ },
+ [0x13062]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13062,
+ },
+ [0x13063]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13063,
+ },
+ [0x13064]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13064,
+ },
+ [0x13065]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13065,
+ },
+ [0x13066]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13066,
+ },
+ [0x13067]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C010A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13067,
+ },
+ [0x13068]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13068,
+ },
+ [0x13069]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13069,
+ },
+ [0x1306A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306A,
+ },
+ [0x1306B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306B,
+ },
+ [0x1306C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306C,
+ },
+ [0x1306D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306D,
+ },
+ [0x1306E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306E,
+ },
+ [0x1306F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1306F,
+ },
+ [0x13070]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13070,
+ },
+ [0x13071]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13071,
+ },
+ [0x13072]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13072,
+ },
+ [0x13073]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13073,
+ },
+ [0x13074]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13074,
+ },
+ [0x13075]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH C024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13075,
+ },
+ [0x13076]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13076,
+ },
+ [0x13077]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13077,
+ },
+ [0x13078]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13078,
+ },
+ [0x13079]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13079,
+ },
+ [0x1307A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307A,
+ },
+ [0x1307B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307B,
+ },
+ [0x1307C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307C,
+ },
+ [0x1307D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307D,
+ },
+ [0x1307E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D008A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307E,
+ },
+ [0x1307F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1307F,
+ },
+ [0x13080]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13080,
+ },
+ [0x13081]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13081,
+ },
+ [0x13082]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13082,
+ },
+ [0x13083]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13083,
+ },
+ [0x13084]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13084,
+ },
+ [0x13085]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13085,
+ },
+ [0x13086]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13086,
+ },
+ [0x13087]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13087,
+ },
+ [0x13088]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13088,
+ },
+ [0x13089]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13089,
+ },
+ [0x1308A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308A,
+ },
+ [0x1308B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308B,
+ },
+ [0x1308C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308C,
+ },
+ [0x1308D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308D,
+ },
+ [0x1308E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308E,
+ },
+ [0x1308F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1308F,
+ },
+ [0x13090]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13090,
+ },
+ [0x13091]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13091,
+ },
+ [0x13092]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D027A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13092,
+ },
+ [0x13093]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13093,
+ },
+ [0x13094]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13094,
+ },
+ [0x13095]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13095,
+ },
+ [0x13096]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13096,
+ },
+ [0x13097]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D031A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13097,
+ },
+ [0x13098]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13098,
+ },
+ [0x13099]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D033",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13099,
+ },
+ [0x1309A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D034",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309A,
+ },
+ [0x1309B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D034A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309B,
+ },
+ [0x1309C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D035",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309C,
+ },
+ [0x1309D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D036",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309D,
+ },
+ [0x1309E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D037",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309E,
+ },
+ [0x1309F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1309F,
+ },
+ [0x130A0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D039",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A0,
+ },
+ [0x130A1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D040",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A1,
+ },
+ [0x130A2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D041",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A2,
+ },
+ [0x130A3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D042",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A3,
+ },
+ [0x130A4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D043",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A4,
+ },
+ [0x130A5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D044",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A5,
+ },
+ [0x130A6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D045",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A6,
+ },
+ [0x130A7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D046",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A7,
+ },
+ [0x130A8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D046A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A8,
+ },
+ [0x130A9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D047",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130A9,
+ },
+ [0x130AA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D048",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130AA,
+ },
+ [0x130AB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D048A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130AB,
+ },
+ [0x130AC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D049",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130AC,
+ },
+ [0x130AD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D050",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130AD,
+ },
+ [0x130AE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D050A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130AE,
+ },
+ [0x130AF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D050B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130AF,
+ },
+ [0x130B0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D050C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B0,
+ },
+ [0x130B1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D050D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B1,
+ },
+ [0x130B2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D050E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B2,
+ },
+ [0x130B3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D050F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B3,
+ },
+ [0x130B4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D050G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B4,
+ },
+ [0x130B5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D050H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B5,
+ },
+ [0x130B6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D050I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B6,
+ },
+ [0x130B7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D051",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B7,
+ },
+ [0x130B8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D052",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B8,
+ },
+ [0x130B9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D052A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130B9,
+ },
+ [0x130BA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D053",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130BA,
+ },
+ [0x130BB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D054",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130BB,
+ },
+ [0x130BC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D054A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130BC,
+ },
+ [0x130BD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D055",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130BD,
+ },
+ [0x130BE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D056",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130BE,
+ },
+ [0x130BF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D057",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130BF,
+ },
+ [0x130C0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D058",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C0,
+ },
+ [0x130C1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D059",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C1,
+ },
+ [0x130C2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D060",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C2,
+ },
+ [0x130C3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D061",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C3,
+ },
+ [0x130C4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D062",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C4,
+ },
+ [0x130C5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D063",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C5,
+ },
+ [0x130C6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D064",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C6,
+ },
+ [0x130C7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D065",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C7,
+ },
+ [0x130C8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D066",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C8,
+ },
+ [0x130C9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D067",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130C9,
+ },
+ [0x130CA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D067A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130CA,
+ },
+ [0x130CB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D067B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130CB,
+ },
+ [0x130CC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D067C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130CC,
+ },
+ [0x130CD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D067D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130CD,
+ },
+ [0x130CE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D067E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130CE,
+ },
+ [0x130CF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D067F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130CF,
+ },
+ [0x130D0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D067G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D0,
+ },
+ [0x130D1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH D067H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D1,
+ },
+ [0x130D2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D2,
+ },
+ [0x130D3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D3,
+ },
+ [0x130D4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D4,
+ },
+ [0x130D5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D5,
+ },
+ [0x130D6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D6,
+ },
+ [0x130D7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D7,
+ },
+ [0x130D8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D8,
+ },
+ [0x130D9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130D9,
+ },
+ [0x130DA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E008A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130DA,
+ },
+ [0x130DB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130DB,
+ },
+ [0x130DC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E009A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130DC,
+ },
+ [0x130DD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130DD,
+ },
+ [0x130DE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130DE,
+ },
+ [0x130DF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130DF,
+ },
+ [0x130E0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E0,
+ },
+ [0x130E1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E1,
+ },
+ [0x130E2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E2,
+ },
+ [0x130E3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E3,
+ },
+ [0x130E4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E016A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E4,
+ },
+ [0x130E5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E5,
+ },
+ [0x130E6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E017A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E6,
+ },
+ [0x130E7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E7,
+ },
+ [0x130E8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E8,
+ },
+ [0x130E9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130E9,
+ },
+ [0x130EA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E020A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130EA,
+ },
+ [0x130EB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130EB,
+ },
+ [0x130EC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130EC,
+ },
+ [0x130ED]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130ED,
+ },
+ [0x130EE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130EE,
+ },
+ [0x130EF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130EF,
+ },
+ [0x130F0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F0,
+ },
+ [0x130F1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F1,
+ },
+ [0x130F2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F2,
+ },
+ [0x130F3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E028A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F3,
+ },
+ [0x130F4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F4,
+ },
+ [0x130F5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F5,
+ },
+ [0x130F6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F6,
+ },
+ [0x130F7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F7,
+ },
+ [0x130F8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E033",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F8,
+ },
+ [0x130F9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E034",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130F9,
+ },
+ [0x130FA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E034A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130FA,
+ },
+ [0x130FB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E036",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130FB,
+ },
+ [0x130FC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E037",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130FC,
+ },
+ [0x130FD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH E038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130FD,
+ },
+ [0x130FE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130FE,
+ },
+ [0x130FF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F001A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x130FF,
+ },
+ [0x13100]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13100,
+ },
+ [0x13101]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13101,
+ },
+ [0x13102]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13102,
+ },
+ [0x13103]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13103,
+ },
+ [0x13104]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13104,
+ },
+ [0x13105]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13105,
+ },
+ [0x13106]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13106,
+ },
+ [0x13107]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13107,
+ },
+ [0x13108]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13108,
+ },
+ [0x13109]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13109,
+ },
+ [0x1310A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310A,
+ },
+ [0x1310B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310B,
+ },
+ [0x1310C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F013A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310C,
+ },
+ [0x1310D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310D,
+ },
+ [0x1310E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310E,
+ },
+ [0x1310F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1310F,
+ },
+ [0x13110]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13110,
+ },
+ [0x13111]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13111,
+ },
+ [0x13112]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13112,
+ },
+ [0x13113]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13113,
+ },
+ [0x13114]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13114,
+ },
+ [0x13115]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F021A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13115,
+ },
+ [0x13116]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13116,
+ },
+ [0x13117]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13117,
+ },
+ [0x13118]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13118,
+ },
+ [0x13119]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13119,
+ },
+ [0x1311A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1311A,
+ },
+ [0x1311B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1311B,
+ },
+ [0x1311C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1311C,
+ },
+ [0x1311D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1311D,
+ },
+ [0x1311E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1311E,
+ },
+ [0x1311F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1311F,
+ },
+ [0x13120]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F031A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13120,
+ },
+ [0x13121]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13121,
+ },
+ [0x13122]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F033",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13122,
+ },
+ [0x13123]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F034",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13123,
+ },
+ [0x13124]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F035",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13124,
+ },
+ [0x13125]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F036",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13125,
+ },
+ [0x13126]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F037",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13126,
+ },
+ [0x13127]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F037A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13127,
+ },
+ [0x13128]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13128,
+ },
+ [0x13129]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F038A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13129,
+ },
+ [0x1312A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F039",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312A,
+ },
+ [0x1312B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F040",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312B,
+ },
+ [0x1312C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F041",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312C,
+ },
+ [0x1312D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F042",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312D,
+ },
+ [0x1312E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F043",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312E,
+ },
+ [0x1312F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F044",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1312F,
+ },
+ [0x13130]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F045",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13130,
+ },
+ [0x13131]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F045A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13131,
+ },
+ [0x13132]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F046",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13132,
+ },
+ [0x13133]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F046A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13133,
+ },
+ [0x13134]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F047",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13134,
+ },
+ [0x13135]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F047A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13135,
+ },
+ [0x13136]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F048",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13136,
+ },
+ [0x13137]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F049",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13137,
+ },
+ [0x13138]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F050",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13138,
+ },
+ [0x13139]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F051",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13139,
+ },
+ [0x1313A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F051A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313A,
+ },
+ [0x1313B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F051B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313B,
+ },
+ [0x1313C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F051C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313C,
+ },
+ [0x1313D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F052",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313D,
+ },
+ [0x1313E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH F053",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313E,
+ },
+ [0x1313F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1313F,
+ },
+ [0x13140]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13140,
+ },
+ [0x13141]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13141,
+ },
+ [0x13142]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13142,
+ },
+ [0x13143]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13143,
+ },
+ [0x13144]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13144,
+ },
+ [0x13145]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G006A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13145,
+ },
+ [0x13146]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13146,
+ },
+ [0x13147]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G007A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13147,
+ },
+ [0x13148]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G007B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13148,
+ },
+ [0x13149]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13149,
+ },
+ [0x1314A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314A,
+ },
+ [0x1314B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314B,
+ },
+ [0x1314C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314C,
+ },
+ [0x1314D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G011A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314D,
+ },
+ [0x1314E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314E,
+ },
+ [0x1314F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1314F,
+ },
+ [0x13150]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13150,
+ },
+ [0x13151]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13151,
+ },
+ [0x13152]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13152,
+ },
+ [0x13153]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13153,
+ },
+ [0x13154]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13154,
+ },
+ [0x13155]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13155,
+ },
+ [0x13156]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13156,
+ },
+ [0x13157]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G020A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13157,
+ },
+ [0x13158]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13158,
+ },
+ [0x13159]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13159,
+ },
+ [0x1315A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315A,
+ },
+ [0x1315B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315B,
+ },
+ [0x1315C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315C,
+ },
+ [0x1315D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315D,
+ },
+ [0x1315E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G026A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315E,
+ },
+ [0x1315F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1315F,
+ },
+ [0x13160]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13160,
+ },
+ [0x13161]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13161,
+ },
+ [0x13162]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13162,
+ },
+ [0x13163]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13163,
+ },
+ [0x13164]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13164,
+ },
+ [0x13165]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G033",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13165,
+ },
+ [0x13166]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G034",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13166,
+ },
+ [0x13167]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G035",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13167,
+ },
+ [0x13168]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G036",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13168,
+ },
+ [0x13169]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G036A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13169,
+ },
+ [0x1316A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G037",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1316A,
+ },
+ [0x1316B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G037A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1316B,
+ },
+ [0x1316C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1316C,
+ },
+ [0x1316D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G039",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1316D,
+ },
+ [0x1316E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G040",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1316E,
+ },
+ [0x1316F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G041",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1316F,
+ },
+ [0x13170]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G042",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13170,
+ },
+ [0x13171]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G043",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13171,
+ },
+ [0x13172]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G043A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13172,
+ },
+ [0x13173]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G044",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13173,
+ },
+ [0x13174]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G045",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13174,
+ },
+ [0x13175]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G045A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13175,
+ },
+ [0x13176]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G046",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13176,
+ },
+ [0x13177]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G047",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13177,
+ },
+ [0x13178]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G048",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13178,
+ },
+ [0x13179]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G049",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13179,
+ },
+ [0x1317A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G050",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1317A,
+ },
+ [0x1317B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G051",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1317B,
+ },
+ [0x1317C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G052",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1317C,
+ },
+ [0x1317D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G053",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1317D,
+ },
+ [0x1317E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH G054",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1317E,
+ },
+ [0x1317F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH H001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1317F,
+ },
+ [0x13180]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH H002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13180,
+ },
+ [0x13181]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH H003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13181,
+ },
+ [0x13182]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH H004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13182,
+ },
+ [0x13183]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH H005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13183,
+ },
+ [0x13184]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH H006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13184,
+ },
+ [0x13185]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH H006A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13185,
+ },
+ [0x13186]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH H007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13186,
+ },
+ [0x13187]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH H008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13187,
+ },
+ [0x13188]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13188,
+ },
+ [0x13189]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13189,
+ },
+ [0x1318A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318A,
+ },
+ [0x1318B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318B,
+ },
+ [0x1318C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318C,
+ },
+ [0x1318D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I005A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318D,
+ },
+ [0x1318E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318E,
+ },
+ [0x1318F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1318F,
+ },
+ [0x13190]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13190,
+ },
+ [0x13191]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13191,
+ },
+ [0x13192]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I009A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13192,
+ },
+ [0x13193]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13193,
+ },
+ [0x13194]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I010A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13194,
+ },
+ [0x13195]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13195,
+ },
+ [0x13196]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I011A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13196,
+ },
+ [0x13197]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13197,
+ },
+ [0x13198]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13198,
+ },
+ [0x13199]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13199,
+ },
+ [0x1319A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH I015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319A,
+ },
+ [0x1319B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH K001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319B,
+ },
+ [0x1319C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH K002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319C,
+ },
+ [0x1319D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH K003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319D,
+ },
+ [0x1319E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH K004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319E,
+ },
+ [0x1319F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH K005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1319F,
+ },
+ [0x131A0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH K006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A0,
+ },
+ [0x131A1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH K007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A1,
+ },
+ [0x131A2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH K008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A2,
+ },
+ [0x131A3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH L001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A3,
+ },
+ [0x131A4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH L002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A4,
+ },
+ [0x131A5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH L002A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A5,
+ },
+ [0x131A6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH L003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A6,
+ },
+ [0x131A7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH L004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A7,
+ },
+ [0x131A8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH L005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A8,
+ },
+ [0x131A9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH L006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131A9,
+ },
+ [0x131AA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH L006A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131AA,
+ },
+ [0x131AB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH L007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131AB,
+ },
+ [0x131AC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH L008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131AC,
+ },
+ [0x131AD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131AD,
+ },
+ [0x131AE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M001A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131AE,
+ },
+ [0x131AF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M001B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131AF,
+ },
+ [0x131B0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B0,
+ },
+ [0x131B1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B1,
+ },
+ [0x131B2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M003A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B2,
+ },
+ [0x131B3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B3,
+ },
+ [0x131B4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B4,
+ },
+ [0x131B5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B5,
+ },
+ [0x131B6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B6,
+ },
+ [0x131B7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B7,
+ },
+ [0x131B8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B8,
+ },
+ [0x131B9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131B9,
+ },
+ [0x131BA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M010A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131BA,
+ },
+ [0x131BB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131BB,
+ },
+ [0x131BC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131BC,
+ },
+ [0x131BD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M012A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131BD,
+ },
+ [0x131BE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M012B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131BE,
+ },
+ [0x131BF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M012C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131BF,
+ },
+ [0x131C0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M012D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C0,
+ },
+ [0x131C1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M012E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C1,
+ },
+ [0x131C2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M012F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C2,
+ },
+ [0x131C3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M012G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C3,
+ },
+ [0x131C4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M012H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C4,
+ },
+ [0x131C5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C5,
+ },
+ [0x131C6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C6,
+ },
+ [0x131C7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C7,
+ },
+ [0x131C8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M015A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C8,
+ },
+ [0x131C9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131C9,
+ },
+ [0x131CA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M016A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131CA,
+ },
+ [0x131CB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131CB,
+ },
+ [0x131CC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M017A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131CC,
+ },
+ [0x131CD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131CD,
+ },
+ [0x131CE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131CE,
+ },
+ [0x131CF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131CF,
+ },
+ [0x131D0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D0,
+ },
+ [0x131D1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D1,
+ },
+ [0x131D2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M022A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D2,
+ },
+ [0x131D3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D3,
+ },
+ [0x131D4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D4,
+ },
+ [0x131D5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M024A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D5,
+ },
+ [0x131D6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D6,
+ },
+ [0x131D7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D7,
+ },
+ [0x131D8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D8,
+ },
+ [0x131D9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131D9,
+ },
+ [0x131DA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M028A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131DA,
+ },
+ [0x131DB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131DB,
+ },
+ [0x131DC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131DC,
+ },
+ [0x131DD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131DD,
+ },
+ [0x131DE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M031A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131DE,
+ },
+ [0x131DF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131DF,
+ },
+ [0x131E0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M033",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E0,
+ },
+ [0x131E1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M033A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E1,
+ },
+ [0x131E2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M033B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E2,
+ },
+ [0x131E3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M034",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E3,
+ },
+ [0x131E4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M035",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E4,
+ },
+ [0x131E5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M036",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E5,
+ },
+ [0x131E6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M037",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E6,
+ },
+ [0x131E7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E7,
+ },
+ [0x131E8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M039",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E8,
+ },
+ [0x131E9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M040",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131E9,
+ },
+ [0x131EA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M040A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131EA,
+ },
+ [0x131EB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M041",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131EB,
+ },
+ [0x131EC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M042",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131EC,
+ },
+ [0x131ED]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M043",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131ED,
+ },
+ [0x131EE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH M044",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131EE,
+ },
+ [0x131EF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131EF,
+ },
+ [0x131F0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F0,
+ },
+ [0x131F1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F1,
+ },
+ [0x131F2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F2,
+ },
+ [0x131F3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F3,
+ },
+ [0x131F4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F4,
+ },
+ [0x131F5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F5,
+ },
+ [0x131F6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F6,
+ },
+ [0x131F7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F7,
+ },
+ [0x131F8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F8,
+ },
+ [0x131F9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131F9,
+ },
+ [0x131FA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131FA,
+ },
+ [0x131FB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131FB,
+ },
+ [0x131FC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131FC,
+ },
+ [0x131FD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131FD,
+ },
+ [0x131FE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131FE,
+ },
+ [0x131FF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x131FF,
+ },
+ [0x13200]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13200,
+ },
+ [0x13201]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N018A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13201,
+ },
+ [0x13202]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N018B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13202,
+ },
+ [0x13203]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13203,
+ },
+ [0x13204]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13204,
+ },
+ [0x13205]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13205,
+ },
+ [0x13206]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13206,
+ },
+ [0x13207]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13207,
+ },
+ [0x13208]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13208,
+ },
+ [0x13209]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13209,
+ },
+ [0x1320A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N025A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320A,
+ },
+ [0x1320B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320B,
+ },
+ [0x1320C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320C,
+ },
+ [0x1320D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320D,
+ },
+ [0x1320E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320E,
+ },
+ [0x1320F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1320F,
+ },
+ [0x13210]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13210,
+ },
+ [0x13211]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13211,
+ },
+ [0x13212]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N033",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13212,
+ },
+ [0x13213]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N033A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13213,
+ },
+ [0x13214]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N034",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13214,
+ },
+ [0x13215]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N034A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13215,
+ },
+ [0x13216]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N035",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13216,
+ },
+ [0x13217]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N035A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13217,
+ },
+ [0x13218]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N036",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13218,
+ },
+ [0x13219]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N037",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13219,
+ },
+ [0x1321A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N037A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321A,
+ },
+ [0x1321B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321B,
+ },
+ [0x1321C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N039",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321C,
+ },
+ [0x1321D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N040",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321D,
+ },
+ [0x1321E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N041",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321E,
+ },
+ [0x1321F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH N042",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1321F,
+ },
+ [0x13220]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13220,
+ },
+ [0x13221]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13221,
+ },
+ [0x13222]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13222,
+ },
+ [0x13223]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13223,
+ },
+ [0x13224]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13224,
+ },
+ [0x13225]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL005A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13225,
+ },
+ [0x13226]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13226,
+ },
+ [0x13227]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13227,
+ },
+ [0x13228]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13228,
+ },
+ [0x13229]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13229,
+ },
+ [0x1322A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322A,
+ },
+ [0x1322B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322B,
+ },
+ [0x1322C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322C,
+ },
+ [0x1322D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322D,
+ },
+ [0x1322E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322E,
+ },
+ [0x1322F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1322F,
+ },
+ [0x13230]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13230,
+ },
+ [0x13231]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13231,
+ },
+ [0x13232]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL017A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13232,
+ },
+ [0x13233]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13233,
+ },
+ [0x13234]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13234,
+ },
+ [0x13235]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NL020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13235,
+ },
+ [0x13236]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13236,
+ },
+ [0x13237]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13237,
+ },
+ [0x13238]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13238,
+ },
+ [0x13239]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13239,
+ },
+ [0x1323A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323A,
+ },
+ [0x1323B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323B,
+ },
+ [0x1323C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323C,
+ },
+ [0x1323D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323D,
+ },
+ [0x1323E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323E,
+ },
+ [0x1323F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1323F,
+ },
+ [0x13240]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU010A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13240,
+ },
+ [0x13241]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13241,
+ },
+ [0x13242]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU011A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13242,
+ },
+ [0x13243]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13243,
+ },
+ [0x13244]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13244,
+ },
+ [0x13245]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13245,
+ },
+ [0x13246]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13246,
+ },
+ [0x13247]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13247,
+ },
+ [0x13248]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13248,
+ },
+ [0x13249]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13249,
+ },
+ [0x1324A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU018A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324A,
+ },
+ [0x1324B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324B,
+ },
+ [0x1324C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324C,
+ },
+ [0x1324D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324D,
+ },
+ [0x1324E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324E,
+ },
+ [0x1324F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH NU022A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1324F,
+ },
+ [0x13250]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13250,
+ },
+ [0x13251]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O001A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13251,
+ },
+ [0x13252]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13252,
+ },
+ [0x13253]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13253,
+ },
+ [0x13254]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13254,
+ },
+ [0x13255]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13255,
+ },
+ [0x13256]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O005A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13256,
+ },
+ [0x13257]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13257,
+ },
+ [0x13258]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O006A",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x13258,
+ },
+ [0x13259]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O006B",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x13259,
+ },
+ [0x1325A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O006C",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x1325A,
+ },
+ [0x1325B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O006D",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x1325B,
+ },
+ [0x1325C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O006E",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x1325C,
+ },
+ [0x1325D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O006F",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x1325D,
+ },
+ [0x1325E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1325E,
+ },
+ [0x1325F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1325F,
+ },
+ [0x13260]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13260,
+ },
+ [0x13261]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13261,
+ },
+ [0x13262]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O010A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13262,
+ },
+ [0x13263]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O010B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13263,
+ },
+ [0x13264]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O010C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13264,
+ },
+ [0x13265]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13265,
+ },
+ [0x13266]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13266,
+ },
+ [0x13267]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13267,
+ },
+ [0x13268]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13268,
+ },
+ [0x13269]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13269,
+ },
+ [0x1326A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326A,
+ },
+ [0x1326B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326B,
+ },
+ [0x1326C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326C,
+ },
+ [0x1326D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326D,
+ },
+ [0x1326E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O019A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326E,
+ },
+ [0x1326F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1326F,
+ },
+ [0x13270]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O020A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13270,
+ },
+ [0x13271]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13271,
+ },
+ [0x13272]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13272,
+ },
+ [0x13273]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13273,
+ },
+ [0x13274]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13274,
+ },
+ [0x13275]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O024A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13275,
+ },
+ [0x13276]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13276,
+ },
+ [0x13277]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O025A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13277,
+ },
+ [0x13278]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13278,
+ },
+ [0x13279]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13279,
+ },
+ [0x1327A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327A,
+ },
+ [0x1327B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327B,
+ },
+ [0x1327C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O029A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327C,
+ },
+ [0x1327D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327D,
+ },
+ [0x1327E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O030A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327E,
+ },
+ [0x1327F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1327F,
+ },
+ [0x13280]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13280,
+ },
+ [0x13281]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O033",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13281,
+ },
+ [0x13282]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O033A",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x13282,
+ },
+ [0x13283]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O034",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13283,
+ },
+ [0x13284]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O035",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13284,
+ },
+ [0x13285]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O036",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13285,
+ },
+ [0x13286]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O036A",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x13286,
+ },
+ [0x13287]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O036B",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x13287,
+ },
+ [0x13288]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O036C",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x13288,
+ },
+ [0x13289]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O036D",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x13289,
+ },
+ [0x1328A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O037",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328A,
+ },
+ [0x1328B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328B,
+ },
+ [0x1328C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O039",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328C,
+ },
+ [0x1328D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O040",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328D,
+ },
+ [0x1328E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O041",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328E,
+ },
+ [0x1328F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O042",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1328F,
+ },
+ [0x13290]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O043",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13290,
+ },
+ [0x13291]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O044",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13291,
+ },
+ [0x13292]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O045",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13292,
+ },
+ [0x13293]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O046",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13293,
+ },
+ [0x13294]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O047",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13294,
+ },
+ [0x13295]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O048",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13295,
+ },
+ [0x13296]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O049",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13296,
+ },
+ [0x13297]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O050",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13297,
+ },
+ [0x13298]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O050A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13298,
+ },
+ [0x13299]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O050B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13299,
+ },
+ [0x1329A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH O051",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329A,
+ },
+ [0x1329B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329B,
+ },
+ [0x1329C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P001A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329C,
+ },
+ [0x1329D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329D,
+ },
+ [0x1329E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329E,
+ },
+ [0x1329F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P003A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1329F,
+ },
+ [0x132A0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A0,
+ },
+ [0x132A1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A1,
+ },
+ [0x132A2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A2,
+ },
+ [0x132A3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A3,
+ },
+ [0x132A4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A4,
+ },
+ [0x132A5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A5,
+ },
+ [0x132A6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A6,
+ },
+ [0x132A7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH P011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A7,
+ },
+ [0x132A8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Q001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A8,
+ },
+ [0x132A9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Q002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132A9,
+ },
+ [0x132AA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Q003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132AA,
+ },
+ [0x132AB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Q004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132AB,
+ },
+ [0x132AC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Q005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132AC,
+ },
+ [0x132AD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Q006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132AD,
+ },
+ [0x132AE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Q007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132AE,
+ },
+ [0x132AF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132AF,
+ },
+ [0x132B0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B0,
+ },
+ [0x132B1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R002A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B1,
+ },
+ [0x132B2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B2,
+ },
+ [0x132B3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R003A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B3,
+ },
+ [0x132B4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R003B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B4,
+ },
+ [0x132B5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B5,
+ },
+ [0x132B6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B6,
+ },
+ [0x132B7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B7,
+ },
+ [0x132B8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B8,
+ },
+ [0x132B9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132B9,
+ },
+ [0x132BA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132BA,
+ },
+ [0x132BB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132BB,
+ },
+ [0x132BC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R010A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132BC,
+ },
+ [0x132BD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132BD,
+ },
+ [0x132BE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132BE,
+ },
+ [0x132BF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132BF,
+ },
+ [0x132C0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C0,
+ },
+ [0x132C1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C1,
+ },
+ [0x132C2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C2,
+ },
+ [0x132C3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R016A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C3,
+ },
+ [0x132C4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C4,
+ },
+ [0x132C5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C5,
+ },
+ [0x132C6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C6,
+ },
+ [0x132C7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C7,
+ },
+ [0x132C8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C8,
+ },
+ [0x132C9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132C9,
+ },
+ [0x132CA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132CA,
+ },
+ [0x132CB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132CB,
+ },
+ [0x132CC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132CC,
+ },
+ [0x132CD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132CD,
+ },
+ [0x132CE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132CE,
+ },
+ [0x132CF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132CF,
+ },
+ [0x132D0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH R029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D0,
+ },
+ [0x132D1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D1,
+ },
+ [0x132D2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D2,
+ },
+ [0x132D3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S002A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D3,
+ },
+ [0x132D4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D4,
+ },
+ [0x132D5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D5,
+ },
+ [0x132D6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D6,
+ },
+ [0x132D7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D7,
+ },
+ [0x132D8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S006A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D8,
+ },
+ [0x132D9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132D9,
+ },
+ [0x132DA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132DA,
+ },
+ [0x132DB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132DB,
+ },
+ [0x132DC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132DC,
+ },
+ [0x132DD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132DD,
+ },
+ [0x132DE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132DE,
+ },
+ [0x132DF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132DF,
+ },
+ [0x132E0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E0,
+ },
+ [0x132E1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S014A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E1,
+ },
+ [0x132E2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S014B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E2,
+ },
+ [0x132E3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E3,
+ },
+ [0x132E4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E4,
+ },
+ [0x132E5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E5,
+ },
+ [0x132E6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S017A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E6,
+ },
+ [0x132E7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E7,
+ },
+ [0x132E8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E8,
+ },
+ [0x132E9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132E9,
+ },
+ [0x132EA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132EA,
+ },
+ [0x132EB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132EB,
+ },
+ [0x132EC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132EC,
+ },
+ [0x132ED]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132ED,
+ },
+ [0x132EE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132EE,
+ },
+ [0x132EF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132EF,
+ },
+ [0x132F0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S026A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F0,
+ },
+ [0x132F1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S026B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F1,
+ },
+ [0x132F2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F2,
+ },
+ [0x132F3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F3,
+ },
+ [0x132F4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F4,
+ },
+ [0x132F5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F5,
+ },
+ [0x132F6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F6,
+ },
+ [0x132F7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F7,
+ },
+ [0x132F8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S033",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F8,
+ },
+ [0x132F9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S034",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132F9,
+ },
+ [0x132FA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S035",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132FA,
+ },
+ [0x132FB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S035A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132FB,
+ },
+ [0x132FC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S036",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132FC,
+ },
+ [0x132FD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S037",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132FD,
+ },
+ [0x132FE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132FE,
+ },
+ [0x132FF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S039",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x132FF,
+ },
+ [0x13300]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S040",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13300,
+ },
+ [0x13301]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S041",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13301,
+ },
+ [0x13302]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S042",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13302,
+ },
+ [0x13303]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S043",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13303,
+ },
+ [0x13304]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S044",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13304,
+ },
+ [0x13305]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S045",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13305,
+ },
+ [0x13306]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH S046",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13306,
+ },
+ [0x13307]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13307,
+ },
+ [0x13308]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13308,
+ },
+ [0x13309]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13309,
+ },
+ [0x1330A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T003A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330A,
+ },
+ [0x1330B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330B,
+ },
+ [0x1330C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330C,
+ },
+ [0x1330D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330D,
+ },
+ [0x1330E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330E,
+ },
+ [0x1330F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T007A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1330F,
+ },
+ [0x13310]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13310,
+ },
+ [0x13311]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T008A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13311,
+ },
+ [0x13312]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13312,
+ },
+ [0x13313]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T009A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13313,
+ },
+ [0x13314]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13314,
+ },
+ [0x13315]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13315,
+ },
+ [0x13316]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T011A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13316,
+ },
+ [0x13317]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13317,
+ },
+ [0x13318]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13318,
+ },
+ [0x13319]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13319,
+ },
+ [0x1331A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331A,
+ },
+ [0x1331B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331B,
+ },
+ [0x1331C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T016A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331C,
+ },
+ [0x1331D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331D,
+ },
+ [0x1331E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331E,
+ },
+ [0x1331F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1331F,
+ },
+ [0x13320]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13320,
+ },
+ [0x13321]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13321,
+ },
+ [0x13322]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13322,
+ },
+ [0x13323]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13323,
+ },
+ [0x13324]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13324,
+ },
+ [0x13325]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13325,
+ },
+ [0x13326]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13326,
+ },
+ [0x13327]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13327,
+ },
+ [0x13328]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13328,
+ },
+ [0x13329]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13329,
+ },
+ [0x1332A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332A,
+ },
+ [0x1332B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332B,
+ },
+ [0x1332C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332C,
+ },
+ [0x1332D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T032A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332D,
+ },
+ [0x1332E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T033",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332E,
+ },
+ [0x1332F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T033A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1332F,
+ },
+ [0x13330]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T034",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13330,
+ },
+ [0x13331]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T035",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13331,
+ },
+ [0x13332]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH T036",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13332,
+ },
+ [0x13333]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13333,
+ },
+ [0x13334]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13334,
+ },
+ [0x13335]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13335,
+ },
+ [0x13336]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13336,
+ },
+ [0x13337]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13337,
+ },
+ [0x13338]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13338,
+ },
+ [0x13339]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U006A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13339,
+ },
+ [0x1333A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U006B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333A,
+ },
+ [0x1333B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333B,
+ },
+ [0x1333C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333C,
+ },
+ [0x1333D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333D,
+ },
+ [0x1333E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333E,
+ },
+ [0x1333F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1333F,
+ },
+ [0x13340]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13340,
+ },
+ [0x13341]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13341,
+ },
+ [0x13342]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13342,
+ },
+ [0x13343]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13343,
+ },
+ [0x13344]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13344,
+ },
+ [0x13345]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13345,
+ },
+ [0x13346]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13346,
+ },
+ [0x13347]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13347,
+ },
+ [0x13348]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13348,
+ },
+ [0x13349]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13349,
+ },
+ [0x1334A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334A,
+ },
+ [0x1334B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334B,
+ },
+ [0x1334C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U023A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334C,
+ },
+ [0x1334D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334D,
+ },
+ [0x1334E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334E,
+ },
+ [0x1334F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1334F,
+ },
+ [0x13350]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13350,
+ },
+ [0x13351]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13351,
+ },
+ [0x13352]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13352,
+ },
+ [0x13353]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U029A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13353,
+ },
+ [0x13354]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13354,
+ },
+ [0x13355]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13355,
+ },
+ [0x13356]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13356,
+ },
+ [0x13357]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U032A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13357,
+ },
+ [0x13358]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U033",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13358,
+ },
+ [0x13359]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U034",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13359,
+ },
+ [0x1335A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U035",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335A,
+ },
+ [0x1335B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U036",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335B,
+ },
+ [0x1335C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U037",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335C,
+ },
+ [0x1335D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335D,
+ },
+ [0x1335E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U039",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335E,
+ },
+ [0x1335F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U040",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1335F,
+ },
+ [0x13360]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U041",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13360,
+ },
+ [0x13361]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH U042",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13361,
+ },
+ [0x13362]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13362,
+ },
+ [0x13363]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V001A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13363,
+ },
+ [0x13364]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V001B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13364,
+ },
+ [0x13365]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V001C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13365,
+ },
+ [0x13366]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V001D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13366,
+ },
+ [0x13367]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V001E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13367,
+ },
+ [0x13368]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V001F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13368,
+ },
+ [0x13369]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V001G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13369,
+ },
+ [0x1336A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V001H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336A,
+ },
+ [0x1336B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V001I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336B,
+ },
+ [0x1336C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336C,
+ },
+ [0x1336D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V002A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336D,
+ },
+ [0x1336E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336E,
+ },
+ [0x1336F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1336F,
+ },
+ [0x13370]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13370,
+ },
+ [0x13371]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13371,
+ },
+ [0x13372]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13372,
+ },
+ [0x13373]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V007A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13373,
+ },
+ [0x13374]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V007B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13374,
+ },
+ [0x13375]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13375,
+ },
+ [0x13376]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13376,
+ },
+ [0x13377]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13377,
+ },
+ [0x13378]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13378,
+ },
+ [0x13379]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V011A",
+ direction="l",
+ linebreak="op",
+ unicodeslot=0x13379,
+ },
+ [0x1337A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V011B",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x1337A,
+ },
+ [0x1337B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V011C",
+ direction="l",
+ linebreak="cl",
+ unicodeslot=0x1337B,
+ },
+ [0x1337C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1337C,
+ },
+ [0x1337D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V012A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1337D,
+ },
+ [0x1337E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V012B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1337E,
+ },
+ [0x1337F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1337F,
+ },
+ [0x13380]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13380,
+ },
+ [0x13381]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13381,
+ },
+ [0x13382]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13382,
+ },
+ [0x13383]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13383,
+ },
+ [0x13384]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13384,
+ },
+ [0x13385]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13385,
+ },
+ [0x13386]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13386,
+ },
+ [0x13387]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13387,
+ },
+ [0x13388]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13388,
+ },
+ [0x13389]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13389,
+ },
+ [0x1338A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338A,
+ },
+ [0x1338B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338B,
+ },
+ [0x1338C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338C,
+ },
+ [0x1338D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338D,
+ },
+ [0x1338E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338E,
+ },
+ [0x1338F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1338F,
+ },
+ [0x13390]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020J",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13390,
+ },
+ [0x13391]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020K",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13391,
+ },
+ [0x13392]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V020L",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13392,
+ },
+ [0x13393]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13393,
+ },
+ [0x13394]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13394,
+ },
+ [0x13395]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13395,
+ },
+ [0x13396]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V023A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13396,
+ },
+ [0x13397]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13397,
+ },
+ [0x13398]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13398,
+ },
+ [0x13399]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13399,
+ },
+ [0x1339A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339A,
+ },
+ [0x1339B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339B,
+ },
+ [0x1339C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V028A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339C,
+ },
+ [0x1339D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339D,
+ },
+ [0x1339E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V029A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339E,
+ },
+ [0x1339F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1339F,
+ },
+ [0x133A0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V030A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A0,
+ },
+ [0x133A1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A1,
+ },
+ [0x133A2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V031A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A2,
+ },
+ [0x133A3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A3,
+ },
+ [0x133A4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V033",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A4,
+ },
+ [0x133A5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V033A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A5,
+ },
+ [0x133A6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V034",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A6,
+ },
+ [0x133A7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V035",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A7,
+ },
+ [0x133A8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V036",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A8,
+ },
+ [0x133A9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V037",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133A9,
+ },
+ [0x133AA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V037A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133AA,
+ },
+ [0x133AB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V038",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133AB,
+ },
+ [0x133AC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V039",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133AC,
+ },
+ [0x133AD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V040",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133AD,
+ },
+ [0x133AE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH V040A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133AE,
+ },
+ [0x133AF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133AF,
+ },
+ [0x133B0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B0,
+ },
+ [0x133B1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B1,
+ },
+ [0x133B2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W003A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B2,
+ },
+ [0x133B3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B3,
+ },
+ [0x133B4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B4,
+ },
+ [0x133B5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B5,
+ },
+ [0x133B6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B6,
+ },
+ [0x133B7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B7,
+ },
+ [0x133B8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B8,
+ },
+ [0x133B9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W009A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133B9,
+ },
+ [0x133BA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133BA,
+ },
+ [0x133BB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W010A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133BB,
+ },
+ [0x133BC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133BC,
+ },
+ [0x133BD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133BD,
+ },
+ [0x133BE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133BE,
+ },
+ [0x133BF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133BF,
+ },
+ [0x133C0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W014A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C0,
+ },
+ [0x133C1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C1,
+ },
+ [0x133C2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C2,
+ },
+ [0x133C3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C3,
+ },
+ [0x133C4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W017A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C4,
+ },
+ [0x133C5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C5,
+ },
+ [0x133C6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W018A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C6,
+ },
+ [0x133C7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C7,
+ },
+ [0x133C8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C8,
+ },
+ [0x133C9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133C9,
+ },
+ [0x133CA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133CA,
+ },
+ [0x133CB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133CB,
+ },
+ [0x133CC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133CC,
+ },
+ [0x133CD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W024A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133CD,
+ },
+ [0x133CE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH W025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133CE,
+ },
+ [0x133CF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH X001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133CF,
+ },
+ [0x133D0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH X002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D0,
+ },
+ [0x133D1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH X003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D1,
+ },
+ [0x133D2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH X004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D2,
+ },
+ [0x133D3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH X004A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D3,
+ },
+ [0x133D4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH X004B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D4,
+ },
+ [0x133D5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH X005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D5,
+ },
+ [0x133D6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH X006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D6,
+ },
+ [0x133D7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH X006A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D7,
+ },
+ [0x133D8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH X007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D8,
+ },
+ [0x133D9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH X008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133D9,
+ },
+ [0x133DA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH X008A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133DA,
+ },
+ [0x133DB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Y001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133DB,
+ },
+ [0x133DC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Y001A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133DC,
+ },
+ [0x133DD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Y002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133DD,
+ },
+ [0x133DE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Y003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133DE,
+ },
+ [0x133DF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Y004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133DF,
+ },
+ [0x133E0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Y005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E0,
+ },
+ [0x133E1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Y006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E1,
+ },
+ [0x133E2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Y007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E2,
+ },
+ [0x133E3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Y008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E3,
+ },
+ [0x133E4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E4,
+ },
+ [0x133E5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E5,
+ },
+ [0x133E6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z002A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E6,
+ },
+ [0x133E7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z002B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E7,
+ },
+ [0x133E8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z002C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E8,
+ },
+ [0x133E9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z002D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133E9,
+ },
+ [0x133EA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133EA,
+ },
+ [0x133EB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z003A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133EB,
+ },
+ [0x133EC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z003B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133EC,
+ },
+ [0x133ED]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133ED,
+ },
+ [0x133EE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z004A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133EE,
+ },
+ [0x133EF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133EF,
+ },
+ [0x133F0]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z005A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F0,
+ },
+ [0x133F1]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F1,
+ },
+ [0x133F2]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F2,
+ },
+ [0x133F3]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F3,
+ },
+ [0x133F4]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F4,
+ },
+ [0x133F5]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F5,
+ },
+ [0x133F6]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F6,
+ },
+ [0x133F7]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F7,
+ },
+ [0x133F8]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F8,
+ },
+ [0x133F9]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133F9,
+ },
+ [0x133FA]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133FA,
+ },
+ [0x133FB]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z015A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133FB,
+ },
+ [0x133FC]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z015B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133FC,
+ },
+ [0x133FD]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z015C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133FD,
+ },
+ [0x133FE]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z015D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133FE,
+ },
+ [0x133FF]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z015E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x133FF,
+ },
+ [0x13400]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z015F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13400,
+ },
+ [0x13401]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z015G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13401,
+ },
+ [0x13402]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z015H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13402,
+ },
+ [0x13403]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z015I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13403,
+ },
+ [0x13404]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13404,
+ },
+ [0x13405]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z016A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13405,
+ },
+ [0x13406]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z016B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13406,
+ },
+ [0x13407]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z016C",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13407,
+ },
+ [0x13408]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z016D",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13408,
+ },
+ [0x13409]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z016E",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13409,
+ },
+ [0x1340A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z016F",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340A,
+ },
+ [0x1340B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z016G",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340B,
+ },
+ [0x1340C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH Z016H",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340C,
+ },
+ [0x1340D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340D,
+ },
+ [0x1340E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340E,
+ },
+ [0x1340F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1340F,
+ },
+ [0x13410]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13410,
+ },
+ [0x13411]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13411,
+ },
+ [0x13412]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13412,
+ },
+ [0x13413]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13413,
+ },
+ [0x13414]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA007A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13414,
+ },
+ [0x13415]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA007B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13415,
+ },
+ [0x13416]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13416,
+ },
+ [0x13417]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13417,
+ },
+ [0x13418]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA010",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13418,
+ },
+ [0x13419]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA011",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13419,
+ },
+ [0x1341A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA012",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341A,
+ },
+ [0x1341B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA013",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341B,
+ },
+ [0x1341C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA014",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341C,
+ },
+ [0x1341D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA015",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341D,
+ },
+ [0x1341E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA016",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341E,
+ },
+ [0x1341F]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA017",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1341F,
+ },
+ [0x13420]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA018",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13420,
+ },
+ [0x13421]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA019",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13421,
+ },
+ [0x13422]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA020",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13422,
+ },
+ [0x13423]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA021",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13423,
+ },
+ [0x13424]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA022",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13424,
+ },
+ [0x13425]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA023",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13425,
+ },
+ [0x13426]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA024",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13426,
+ },
+ [0x13427]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA025",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13427,
+ },
+ [0x13428]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA026",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13428,
+ },
+ [0x13429]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA027",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x13429,
+ },
+ [0x1342A]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA028",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1342A,
+ },
+ [0x1342B]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA029",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1342B,
+ },
+ [0x1342C]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA030",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1342C,
+ },
+ [0x1342D]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA031",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1342D,
+ },
+ [0x1342E]={
+ category="lo",
+ description="EGYPTIAN HIEROGLYPH AA032",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1342E,
+ },
+ [0x16800]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NGKUE MFON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16800,
+ },
+ [0x16801]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A GBIEE FON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16801,
+ },
+ [0x16802]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A PON MFON PIPAEMGBIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16802,
+ },
+ [0x16803]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A PON MFON PIPAEMBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16803,
+ },
+ [0x16804]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NAA MFON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16804,
+ },
+ [0x16805]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A SHUENSHUET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16805,
+ },
+ [0x16806]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A TITA MFON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16806,
+ },
+ [0x16807]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NZA MFON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16807,
+ },
+ [0x16808]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A SHINDA PA NJI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16808,
+ },
+ [0x16809]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A PON PA NJI PIPAEMGBIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16809,
+ },
+ [0x1680A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A PON PA NJI PIPAEMBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1680A,
+ },
+ [0x1680B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MAEMBGBIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1680B,
+ },
+ [0x1680C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A TU MAEMBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1680C,
+ },
+ [0x1680D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NGANGU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1680D,
+ },
+ [0x1680E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MAEMVEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1680E,
+ },
+ [0x1680F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MANSUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1680F,
+ },
+ [0x16810]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MVEUAENGAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16810,
+ },
+ [0x16811]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A SEUNYAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16811,
+ },
+ [0x16812]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NTOQPEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16812,
+ },
+ [0x16813]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A KEUKEUTNDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16813,
+ },
+ [0x16814]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NKINDI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16814,
+ },
+ [0x16815]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A SUU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16815,
+ },
+ [0x16816]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NGKUENZEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16816,
+ },
+ [0x16817]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A LAPAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16817,
+ },
+ [0x16818]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A LET KUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16818,
+ },
+ [0x16819]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NTAP MFAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16819,
+ },
+ [0x1681A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MAEKEUP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681A,
+ },
+ [0x1681B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A PASHAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681B,
+ },
+ [0x1681C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A GHEUAERAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681C,
+ },
+ [0x1681D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A PAMSHAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681D,
+ },
+ [0x1681E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MON NGGEUAET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681E,
+ },
+ [0x1681F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NZUN MEUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1681F,
+ },
+ [0x16820]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A U YUQ NAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16820,
+ },
+ [0x16821]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A GHEUAEGHEUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16821,
+ },
+ [0x16822]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NTAP NTAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16822,
+ },
+ [0x16823]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A SISA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16823,
+ },
+ [0x16824]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MGBASA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16824,
+ },
+ [0x16825]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MEUNJOMNDEUQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16825,
+ },
+ [0x16826]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MOOMPUQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16826,
+ },
+ [0x16827]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A KAFA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16827,
+ },
+ [0x16828]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A PA LEERAEWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16828,
+ },
+ [0x16829]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NDA LEERAEWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16829,
+ },
+ [0x1682A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A PET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682A,
+ },
+ [0x1682B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MAEMKPEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682B,
+ },
+ [0x1682C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NIKA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682C,
+ },
+ [0x1682D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A PUP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682D,
+ },
+ [0x1682E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A TUAEP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682E,
+ },
+ [0x1682F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A LUAEP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1682F,
+ },
+ [0x16830]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A SONJAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16830,
+ },
+ [0x16831]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A TEUTEUWEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16831,
+ },
+ [0x16832]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MAENYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16832,
+ },
+ [0x16833]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A KET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16833,
+ },
+ [0x16834]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NDAANGGEUAET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16834,
+ },
+ [0x16835]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A KUOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16835,
+ },
+ [0x16836]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MOOMEUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16836,
+ },
+ [0x16837]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A SHUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16837,
+ },
+ [0x16838]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A LOMMAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16838,
+ },
+ [0x16839]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A FIRI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16839,
+ },
+ [0x1683A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A ROM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683A,
+ },
+ [0x1683B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A KPOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683B,
+ },
+ [0x1683C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A SOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683C,
+ },
+ [0x1683D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MAP PIEET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683D,
+ },
+ [0x1683E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A SHIRAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683E,
+ },
+ [0x1683F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NTAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1683F,
+ },
+ [0x16840]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A SHOQ NSHUT YUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16840,
+ },
+ [0x16841]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NYIT MONGKEUAEQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16841,
+ },
+ [0x16842]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A PAARAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16842,
+ },
+ [0x16843]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NKAARAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16843,
+ },
+ [0x16844]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A UNKNOWN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16844,
+ },
+ [0x16845]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NGGEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16845,
+ },
+ [0x16846]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MAESI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16846,
+ },
+ [0x16847]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NJAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16847,
+ },
+ [0x16848]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MBANYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16848,
+ },
+ [0x16849]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NYET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16849,
+ },
+ [0x1684A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A TEUAEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684A,
+ },
+ [0x1684B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A SOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684B,
+ },
+ [0x1684C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A PAAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684C,
+ },
+ [0x1684D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NSHIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684D,
+ },
+ [0x1684E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MAEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684E,
+ },
+ [0x1684F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1684F,
+ },
+ [0x16850]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A KAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16850,
+ },
+ [0x16851]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NSHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16851,
+ },
+ [0x16852]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A VEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16852,
+ },
+ [0x16853]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16853,
+ },
+ [0x16854]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16854,
+ },
+ [0x16855]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A NAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16855,
+ },
+ [0x16856]={
+ category="lo",
+ description="BAMUM LETTER PHASE-A MBAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16856,
+ },
+ [0x16857]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B NSHUET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16857,
+ },
+ [0x16858]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B TU MAEMGBIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16858,
+ },
+ [0x16859]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B SIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16859,
+ },
+ [0x1685A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B SET TU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685A,
+ },
+ [0x1685B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B LOM NTEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685B,
+ },
+ [0x1685C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MBA MAELEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685C,
+ },
+ [0x1685D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B KIEEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685D,
+ },
+ [0x1685E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B YEURAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685E,
+ },
+ [0x1685F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MBAARAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1685F,
+ },
+ [0x16860]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B KAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16860,
+ },
+ [0x16861]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B PEESHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16861,
+ },
+ [0x16862]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B YAFU LEERAEWA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16862,
+ },
+ [0x16863]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B LAM NSHUT NYAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16863,
+ },
+ [0x16864]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B NTIEE SHEUOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16864,
+ },
+ [0x16865]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B NDU NJAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16865,
+ },
+ [0x16866]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B GHEUGHEUAEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16866,
+ },
+ [0x16867]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B PIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16867,
+ },
+ [0x16868]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B TU NSIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16868,
+ },
+ [0x16869]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B SHET NJAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16869,
+ },
+ [0x1686A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B SHEUAEQTU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686A,
+ },
+ [0x1686B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MFON TEUAEQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686B,
+ },
+ [0x1686C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MBIT MBAAKET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686C,
+ },
+ [0x1686D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B NYI NTEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686D,
+ },
+ [0x1686E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B KEUPUQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686E,
+ },
+ [0x1686F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B GHEUGHEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1686F,
+ },
+ [0x16870]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B KEUYEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16870,
+ },
+ [0x16871]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B LAANAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16871,
+ },
+ [0x16872]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B PARUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16872,
+ },
+ [0x16873]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B VEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16873,
+ },
+ [0x16874]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B NGKINDI MVOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16874,
+ },
+ [0x16875]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B NGGEU MBU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16875,
+ },
+ [0x16876]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B WUAET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16876,
+ },
+ [0x16877]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B SAKEUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16877,
+ },
+ [0x16878]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B TAAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16878,
+ },
+ [0x16879]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MEUQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16879,
+ },
+ [0x1687A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B NGGUOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687A,
+ },
+ [0x1687B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B NGGUOQ LARGE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687B,
+ },
+ [0x1687C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MFIYAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687C,
+ },
+ [0x1687D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B SUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687D,
+ },
+ [0x1687E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MBEURI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687E,
+ },
+ [0x1687F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MONTIEEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1687F,
+ },
+ [0x16880]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B NYAEMAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16880,
+ },
+ [0x16881]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B PUNGAAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16881,
+ },
+ [0x16882]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MEUT NGGEET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16882,
+ },
+ [0x16883]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B FEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16883,
+ },
+ [0x16884]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MBUOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16884,
+ },
+ [0x16885]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B FEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16885,
+ },
+ [0x16886]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B KEUAEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16886,
+ },
+ [0x16887]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MA NJEUAENA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16887,
+ },
+ [0x16888]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MA NJUQA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16888,
+ },
+ [0x16889]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B LET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16889,
+ },
+ [0x1688A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B NGGAAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688A,
+ },
+ [0x1688B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B NSEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688B,
+ },
+ [0x1688C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688C,
+ },
+ [0x1688D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B KIQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688D,
+ },
+ [0x1688E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-B NGOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688E,
+ },
+ [0x1688F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NGKUE MAEMBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1688F,
+ },
+ [0x16890]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16890,
+ },
+ [0x16891]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C YUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16891,
+ },
+ [0x16892]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C WANGKUOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16892,
+ },
+ [0x16893]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NGGEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16893,
+ },
+ [0x16894]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NDEUAEREE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16894,
+ },
+ [0x16895]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NGKAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16895,
+ },
+ [0x16896]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C GHARAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16896,
+ },
+ [0x16897]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MBEEKEET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16897,
+ },
+ [0x16898]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C GBAYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16898,
+ },
+ [0x16899]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NYIR MKPARAQ MEUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16899,
+ },
+ [0x1689A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NTU MBIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689A,
+ },
+ [0x1689B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MBEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689B,
+ },
+ [0x1689C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C PIRIEEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689C,
+ },
+ [0x1689D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NDOMBU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689D,
+ },
+ [0x1689E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MBAA CABBAGE-TREE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689E,
+ },
+ [0x1689F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C KEUSHEUAEP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1689F,
+ },
+ [0x168A0]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C GHAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A0,
+ },
+ [0x168A1]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C KEUKAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A1,
+ },
+ [0x168A2]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C YU MUOMAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A2,
+ },
+ [0x168A3]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NZEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A3,
+ },
+ [0x168A4]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MBUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A4,
+ },
+ [0x168A5]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NSEUAEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A5,
+ },
+ [0x168A6]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MBIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A6,
+ },
+ [0x168A7]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C YEUQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A7,
+ },
+ [0x168A8]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C KPARAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A8,
+ },
+ [0x168A9]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C KAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168A9,
+ },
+ [0x168AA]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C SEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168AA,
+ },
+ [0x168AB]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NDIDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168AB,
+ },
+ [0x168AC]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C TAASHAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168AC,
+ },
+ [0x168AD]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NJUEQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168AD,
+ },
+ [0x168AE]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C TITA YUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168AE,
+ },
+ [0x168AF]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C SUAET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168AF,
+ },
+ [0x168B0]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NGGUAEN NYAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B0,
+ },
+ [0x168B1]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C VEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B1,
+ },
+ [0x168B2]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NANSANAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B2,
+ },
+ [0x168B3]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MA KEUAERI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B3,
+ },
+ [0x168B4]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NTAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B4,
+ },
+ [0x168B5]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NGGUON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B5,
+ },
+ [0x168B6]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C LAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B6,
+ },
+ [0x168B7]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MBIRIEEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B7,
+ },
+ [0x168B8]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MGBASAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B8,
+ },
+ [0x168B9]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NTEUNGBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168B9,
+ },
+ [0x168BA]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C TEUTEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168BA,
+ },
+ [0x168BB]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NGGUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168BB,
+ },
+ [0x168BC]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C FUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168BC,
+ },
+ [0x168BD]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NDEUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168BD,
+ },
+ [0x168BE]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168BE,
+ },
+ [0x168BF]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NSHAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168BF,
+ },
+ [0x168C0]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C BUNG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C0,
+ },
+ [0x168C1]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C VEUAEPEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C1,
+ },
+ [0x168C2]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MBERAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C2,
+ },
+ [0x168C3]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C RU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C3,
+ },
+ [0x168C4]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NJAEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C4,
+ },
+ [0x168C5]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C LAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C5,
+ },
+ [0x168C6]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C TITUAEP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C6,
+ },
+ [0x168C7]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NSUOT NGOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C7,
+ },
+ [0x168C8]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NJEEEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C8,
+ },
+ [0x168C9]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C KET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168C9,
+ },
+ [0x168CA]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NGGU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168CA,
+ },
+ [0x168CB]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MAESI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168CB,
+ },
+ [0x168CC]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MBUAEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168CC,
+ },
+ [0x168CD]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168CD,
+ },
+ [0x168CE]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C KUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168CE,
+ },
+ [0x168CF]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NJAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168CF,
+ },
+ [0x168D0]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NGOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D0,
+ },
+ [0x168D1]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C WUP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D1,
+ },
+ [0x168D2]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NGGUEET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D2,
+ },
+ [0x168D3]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NSOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D3,
+ },
+ [0x168D4]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NTEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D4,
+ },
+ [0x168D5]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C KUOP NKAARAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D5,
+ },
+ [0x168D6]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NSUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D6,
+ },
+ [0x168D7]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NDAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D7,
+ },
+ [0x168D8]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MA NSIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D8,
+ },
+ [0x168D9]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C YAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168D9,
+ },
+ [0x168DA]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NDAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168DA,
+ },
+ [0x168DB]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C SHUEQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168DB,
+ },
+ [0x168DC]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C SETFON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168DC,
+ },
+ [0x168DD]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MBI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168DD,
+ },
+ [0x168DE]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MAEMBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168DE,
+ },
+ [0x168DF]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MBANYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168DF,
+ },
+ [0x168E0]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C KEUSEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E0,
+ },
+ [0x168E1]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MBEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E1,
+ },
+ [0x168E2]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C KEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E2,
+ },
+ [0x168E3]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MBAA PICKET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E3,
+ },
+ [0x168E4]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C YUWOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E4,
+ },
+ [0x168E5]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NJEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E5,
+ },
+ [0x168E6]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E6,
+ },
+ [0x168E7]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C MUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E7,
+ },
+ [0x168E8]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C SHIQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E8,
+ },
+ [0x168E9]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C KEN LAW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168E9,
+ },
+ [0x168EA]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C KEN FATIGUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168EA,
+ },
+ [0x168EB]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NGAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168EB,
+ },
+ [0x168EC]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C NAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168EC,
+ },
+ [0x168ED]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C LIQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168ED,
+ },
+ [0x168EE]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C PIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168EE,
+ },
+ [0x168EF]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C PEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168EF,
+ },
+ [0x168F0]={
+ category="lo",
+ description="BAMUM LETTER PHASE-C TET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F0,
+ },
+ [0x168F1]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MBUO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F1,
+ },
+ [0x168F2]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D WAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F2,
+ },
+ [0x168F3]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NJI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F3,
+ },
+ [0x168F4]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MFON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F4,
+ },
+ [0x168F5]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NJIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F5,
+ },
+ [0x168F6]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D LIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F6,
+ },
+ [0x168F7]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NJEUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F7,
+ },
+ [0x168F8]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NSHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F8,
+ },
+ [0x168F9]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NGGAAMAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168F9,
+ },
+ [0x168FA]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NYAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168FA,
+ },
+ [0x168FB]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D WUAEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168FB,
+ },
+ [0x168FC]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NGKUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168FC,
+ },
+ [0x168FD]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SHEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168FD,
+ },
+ [0x168FE]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NGKAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168FE,
+ },
+ [0x168FF]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D KEUAETMEUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x168FF,
+ },
+ [0x16900]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D TEUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16900,
+ },
+ [0x16901]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SHEUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16901,
+ },
+ [0x16902]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NJAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16902,
+ },
+ [0x16903]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16903,
+ },
+ [0x16904]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D KET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16904,
+ },
+ [0x16905]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D YAEMMAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16905,
+ },
+ [0x16906]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D KUOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16906,
+ },
+ [0x16907]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16907,
+ },
+ [0x16908]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MFEUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16908,
+ },
+ [0x16909]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NDEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16909,
+ },
+ [0x1690A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MALEERI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690A,
+ },
+ [0x1690B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MEUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690B,
+ },
+ [0x1690C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SEUAEQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690C,
+ },
+ [0x1690D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D YEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690D,
+ },
+ [0x1690E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NJEUAEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690E,
+ },
+ [0x1690F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D KEUOT MBUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1690F,
+ },
+ [0x16910]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NGKEURI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16910,
+ },
+ [0x16911]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D TU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16911,
+ },
+ [0x16912]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D GHAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16912,
+ },
+ [0x16913]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NGKYEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16913,
+ },
+ [0x16914]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D FEUFEUAET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16914,
+ },
+ [0x16915]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NDEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16915,
+ },
+ [0x16916]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MGBOFUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16916,
+ },
+ [0x16917]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D LEUAEP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16917,
+ },
+ [0x16918]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NDON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16918,
+ },
+ [0x16919]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MONI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16919,
+ },
+ [0x1691A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MGBEUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691A,
+ },
+ [0x1691B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D PUUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691B,
+ },
+ [0x1691C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MGBIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691C,
+ },
+ [0x1691D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MFO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691D,
+ },
+ [0x1691E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D LUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691E,
+ },
+ [0x1691F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NSIEEP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1691F,
+ },
+ [0x16920]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MBAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16920,
+ },
+ [0x16921]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D KWAET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16921,
+ },
+ [0x16922]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NYET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16922,
+ },
+ [0x16923]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D TEUAEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16923,
+ },
+ [0x16924]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16924,
+ },
+ [0x16925]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D YUWOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16925,
+ },
+ [0x16926]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D KEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16926,
+ },
+ [0x16927]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D RAEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16927,
+ },
+ [0x16928]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D TEEEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16928,
+ },
+ [0x16929]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NGKEUAEQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16929,
+ },
+ [0x1692A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MFEUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692A,
+ },
+ [0x1692B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NSIEET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692B,
+ },
+ [0x1692C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D KEUP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692C,
+ },
+ [0x1692D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D PIP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692D,
+ },
+ [0x1692E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D PEUTAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692E,
+ },
+ [0x1692F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NYUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1692F,
+ },
+ [0x16930]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D LET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16930,
+ },
+ [0x16931]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NGGAAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16931,
+ },
+ [0x16932]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MFIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16932,
+ },
+ [0x16933]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NGGWAEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16933,
+ },
+ [0x16934]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D YUOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16934,
+ },
+ [0x16935]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D PAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16935,
+ },
+ [0x16936]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D YUOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16936,
+ },
+ [0x16937]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NDAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16937,
+ },
+ [0x16938]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NTEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16938,
+ },
+ [0x16939]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16939,
+ },
+ [0x1693A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D KUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693A,
+ },
+ [0x1693B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NGGEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693B,
+ },
+ [0x1693C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NGKIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693C,
+ },
+ [0x1693D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D TUOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693D,
+ },
+ [0x1693E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MEUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693E,
+ },
+ [0x1693F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D KUQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1693F,
+ },
+ [0x16940]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NSUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16940,
+ },
+ [0x16941]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D TEUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16941,
+ },
+ [0x16942]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MAENJET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16942,
+ },
+ [0x16943]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NGGAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16943,
+ },
+ [0x16944]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D LEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16944,
+ },
+ [0x16945]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NGGUOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16945,
+ },
+ [0x16946]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NSHUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16946,
+ },
+ [0x16947]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NJUEQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16947,
+ },
+ [0x16948]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D GHEUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16948,
+ },
+ [0x16949]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D KU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16949,
+ },
+ [0x1694A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D REN OLD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694A,
+ },
+ [0x1694B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D TAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694B,
+ },
+ [0x1694C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D TOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694C,
+ },
+ [0x1694D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694D,
+ },
+ [0x1694E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D RII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694E,
+ },
+ [0x1694F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D LEEEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1694F,
+ },
+ [0x16950]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MEEEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16950,
+ },
+ [0x16951]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16951,
+ },
+ [0x16952]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SUU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16952,
+ },
+ [0x16953]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16953,
+ },
+ [0x16954]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SHII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16954,
+ },
+ [0x16955]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SHEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16955,
+ },
+ [0x16956]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D KYEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16956,
+ },
+ [0x16957]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16957,
+ },
+ [0x16958]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16958,
+ },
+ [0x16959]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NTEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16959,
+ },
+ [0x1695A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D PEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695A,
+ },
+ [0x1695B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695B,
+ },
+ [0x1695C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SHOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695C,
+ },
+ [0x1695D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D PUQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695D,
+ },
+ [0x1695E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MVOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695E,
+ },
+ [0x1695F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D LOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1695F,
+ },
+ [0x16960]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D REN MUCH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16960,
+ },
+ [0x16961]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D TI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16961,
+ },
+ [0x16962]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D NTUU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16962,
+ },
+ [0x16963]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D MBAA SEVEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16963,
+ },
+ [0x16964]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D SAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16964,
+ },
+ [0x16965]={
+ category="lo",
+ description="BAMUM LETTER PHASE-D FAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16965,
+ },
+ [0x16966]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NDAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16966,
+ },
+ [0x16967]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TOON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16967,
+ },
+ [0x16968]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MBEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16968,
+ },
+ [0x16969]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E LAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16969,
+ },
+ [0x1696A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E VOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696A,
+ },
+ [0x1696B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E LOON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696B,
+ },
+ [0x1696C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696C,
+ },
+ [0x1696D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E SOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696D,
+ },
+ [0x1696E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E RAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696E,
+ },
+ [0x1696F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NSHUOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1696F,
+ },
+ [0x16970]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NDUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16970,
+ },
+ [0x16971]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16971,
+ },
+ [0x16972]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16972,
+ },
+ [0x16973]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGKA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16973,
+ },
+ [0x16974]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E KPEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16974,
+ },
+ [0x16975]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E WUO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16975,
+ },
+ [0x16976]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E SEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16976,
+ },
+ [0x16977]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGGEUAET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16977,
+ },
+ [0x16978]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PAAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16978,
+ },
+ [0x16979]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TOO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16979,
+ },
+ [0x1697A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E KUOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697A,
+ },
+ [0x1697B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E LOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697B,
+ },
+ [0x1697C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NSHIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697C,
+ },
+ [0x1697D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGOP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697D,
+ },
+ [0x1697E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MAEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697E,
+ },
+ [0x1697F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGKEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1697F,
+ },
+ [0x16980]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16980,
+ },
+ [0x16981]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NSHUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16981,
+ },
+ [0x16982]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E RIMGBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16982,
+ },
+ [0x16983]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NJEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16983,
+ },
+ [0x16984]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PEEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16984,
+ },
+ [0x16985]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E SAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16985,
+ },
+ [0x16986]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGGURAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16986,
+ },
+ [0x16987]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MGBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16987,
+ },
+ [0x16988]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E GHEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16988,
+ },
+ [0x16989]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGKEUAEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16989,
+ },
+ [0x1698A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NJAEMLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698A,
+ },
+ [0x1698B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698B,
+ },
+ [0x1698C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E LOOT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698C,
+ },
+ [0x1698D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGGEEEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698D,
+ },
+ [0x1698E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NDIQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698E,
+ },
+ [0x1698F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TAEN NTEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1698F,
+ },
+ [0x16990]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E SET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16990,
+ },
+ [0x16991]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16991,
+ },
+ [0x16992]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NDAA SOFTNESS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16992,
+ },
+ [0x16993]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGGUAESHAE NYAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16993,
+ },
+ [0x16994]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16994,
+ },
+ [0x16995]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E GHEUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16995,
+ },
+ [0x16996]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16996,
+ },
+ [0x16997]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YEUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16997,
+ },
+ [0x16998]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16998,
+ },
+ [0x16999]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TUMAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16999,
+ },
+ [0x1699A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E KEUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699A,
+ },
+ [0x1699B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E SUAEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699B,
+ },
+ [0x1699C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TEUAEQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699C,
+ },
+ [0x1699D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E VEUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699D,
+ },
+ [0x1699E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E WEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699E,
+ },
+ [0x1699F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E LAAM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1699F,
+ },
+ [0x169A0]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A0,
+ },
+ [0x169A1]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TAAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A1,
+ },
+ [0x169A2]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E GHAAMAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A2,
+ },
+ [0x169A3]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGEUREUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A3,
+ },
+ [0x169A4]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E SHEUAEQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A4,
+ },
+ [0x169A5]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MGBEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A5,
+ },
+ [0x169A6]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MBEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A6,
+ },
+ [0x169A7]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NZAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A7,
+ },
+ [0x169A8]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NKOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A8,
+ },
+ [0x169A9]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E GBET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169A9,
+ },
+ [0x169AA]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169AA,
+ },
+ [0x169AB]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E KUET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169AB,
+ },
+ [0x169AC]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169AC,
+ },
+ [0x169AD]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NYI CLEAVER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169AD,
+ },
+ [0x169AE]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YIT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169AE,
+ },
+ [0x169AF]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MFEUQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169AF,
+ },
+ [0x169B0]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NDIAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B0,
+ },
+ [0x169B1]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PIEEQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B1,
+ },
+ [0x169B2]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YUEQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B2,
+ },
+ [0x169B3]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E LEUAEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B3,
+ },
+ [0x169B4]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E FUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B4,
+ },
+ [0x169B5]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E GBEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B5,
+ },
+ [0x169B6]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGKUP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B6,
+ },
+ [0x169B7]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E KET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B7,
+ },
+ [0x169B8]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B8,
+ },
+ [0x169B9]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGKAAMI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169B9,
+ },
+ [0x169BA]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E GHET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169BA,
+ },
+ [0x169BB]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169BB,
+ },
+ [0x169BC]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NTUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169BC,
+ },
+ [0x169BD]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PEUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169BD,
+ },
+ [0x169BE]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YEUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169BE,
+ },
+ [0x169BF]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGGEUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169BF,
+ },
+ [0x169C0]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NYI BETWEEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C0,
+ },
+ [0x169C1]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NZUQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C1,
+ },
+ [0x169C2]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E POON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C2,
+ },
+ [0x169C3]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C3,
+ },
+ [0x169C4]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E FUET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C4,
+ },
+ [0x169C5]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C5,
+ },
+ [0x169C6]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C6,
+ },
+ [0x169C7]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E GHEUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C7,
+ },
+ [0x169C8]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E FU I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C8,
+ },
+ [0x169C9]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MVI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169C9,
+ },
+ [0x169CA]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PUAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169CA,
+ },
+ [0x169CB]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGKUM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169CB,
+ },
+ [0x169CC]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E KUT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169CC,
+ },
+ [0x169CD]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PIET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169CD,
+ },
+ [0x169CE]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NTAP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169CE,
+ },
+ [0x169CF]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YEUAET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169CF,
+ },
+ [0x169D0]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGGUP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D0,
+ },
+ [0x169D1]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PA PEOPLE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D1,
+ },
+ [0x169D2]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E FU CALL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D2,
+ },
+ [0x169D3]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E FOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D3,
+ },
+ [0x169D4]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NJEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D4,
+ },
+ [0x169D5]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D5,
+ },
+ [0x169D6]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D6,
+ },
+ [0x169D7]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E O",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D7,
+ },
+ [0x169D8]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E I",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D8,
+ },
+ [0x169D9]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E LAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169D9,
+ },
+ [0x169DA]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PA PLURAL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169DA,
+ },
+ [0x169DB]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169DB,
+ },
+ [0x169DC]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169DC,
+ },
+ [0x169DD]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NDAA MY HOUSE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169DD,
+ },
+ [0x169DE]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E SHIQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169DE,
+ },
+ [0x169DF]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169DF,
+ },
+ [0x169E0]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E0,
+ },
+ [0x169E1]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YUAEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E1,
+ },
+ [0x169E2]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YOQ SWIMMING",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E2,
+ },
+ [0x169E3]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YOQ COVER",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E3,
+ },
+ [0x169E4]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YUQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E4,
+ },
+ [0x169E5]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E YUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E5,
+ },
+ [0x169E6]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E KEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E6,
+ },
+ [0x169E7]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E7,
+ },
+ [0x169E8]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NJEE EPOCH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E8,
+ },
+ [0x169E9]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169E9,
+ },
+ [0x169EA]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E WUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169EA,
+ },
+ [0x169EB]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E FEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169EB,
+ },
+ [0x169EC]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E VEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169EC,
+ },
+ [0x169ED]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E LU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169ED,
+ },
+ [0x169EE]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169EE,
+ },
+ [0x169EF]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E REUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169EF,
+ },
+ [0x169F0]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E RAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F0,
+ },
+ [0x169F1]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGUAET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F1,
+ },
+ [0x169F2]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F2,
+ },
+ [0x169F3]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E SHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F3,
+ },
+ [0x169F4]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E SHOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F4,
+ },
+ [0x169F5]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E FU REMEDY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F5,
+ },
+ [0x169F6]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F6,
+ },
+ [0x169F7]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E PI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F7,
+ },
+ [0x169F8]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E LOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F8,
+ },
+ [0x169F9]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E KO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169F9,
+ },
+ [0x169FA]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169FA,
+ },
+ [0x169FB]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169FB,
+ },
+ [0x169FC]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169FC,
+ },
+ [0x169FD]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TEU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169FD,
+ },
+ [0x169FE]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E KI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169FE,
+ },
+ [0x169FF]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E MON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x169FF,
+ },
+ [0x16A00]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E TEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A00,
+ },
+ [0x16A01]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E FAQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A01,
+ },
+ [0x16A02]={
+ category="lo",
+ description="BAMUM LETTER PHASE-E GHOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A02,
+ },
+ [0x16A03]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A03,
+ },
+ [0x16A04]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F U",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A04,
+ },
+ [0x16A05]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F KU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A05,
+ },
+ [0x16A06]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F EE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A06,
+ },
+ [0x16A07]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F REE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A07,
+ },
+ [0x16A08]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F TAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A08,
+ },
+ [0x16A09]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F NYI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A09,
+ },
+ [0x16A0A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0A,
+ },
+ [0x16A0B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F RII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0B,
+ },
+ [0x16A0C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F RIEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0C,
+ },
+ [0x16A0D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F MEEEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0D,
+ },
+ [0x16A0E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F TAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0E,
+ },
+ [0x16A0F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F NDAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A0F,
+ },
+ [0x16A10]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F NJAEM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A10,
+ },
+ [0x16A11]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F M",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A11,
+ },
+ [0x16A12]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F SUU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A12,
+ },
+ [0x16A13]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F SHII",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A13,
+ },
+ [0x16A14]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F SI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A14,
+ },
+ [0x16A15]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F SEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A15,
+ },
+ [0x16A16]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F KYEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A16,
+ },
+ [0x16A17]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F KET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A17,
+ },
+ [0x16A18]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F NUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A18,
+ },
+ [0x16A19]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F NU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A19,
+ },
+ [0x16A1A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F NJUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1A,
+ },
+ [0x16A1B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F YOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1B,
+ },
+ [0x16A1C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F SHU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1C,
+ },
+ [0x16A1D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F YA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1D,
+ },
+ [0x16A1E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F NSHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1E,
+ },
+ [0x16A1F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F PEUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A1F,
+ },
+ [0x16A20]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F NTEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A20,
+ },
+ [0x16A21]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F WUE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A21,
+ },
+ [0x16A22]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F PEE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A22,
+ },
+ [0x16A23]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F RU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A23,
+ },
+ [0x16A24]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F NI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A24,
+ },
+ [0x16A25]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F REUX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A25,
+ },
+ [0x16A26]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F KEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A26,
+ },
+ [0x16A27]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F NGKWAEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A27,
+ },
+ [0x16A28]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F NGGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A28,
+ },
+ [0x16A29]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F SHO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A29,
+ },
+ [0x16A2A]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F PUAE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2A,
+ },
+ [0x16A2B]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F FOM",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2B,
+ },
+ [0x16A2C]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2C,
+ },
+ [0x16A2D]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F LI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2D,
+ },
+ [0x16A2E]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F LOQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2E,
+ },
+ [0x16A2F]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F KO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A2F,
+ },
+ [0x16A30]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F MBEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A30,
+ },
+ [0x16A31]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F REN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A31,
+ },
+ [0x16A32]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A32,
+ },
+ [0x16A33]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F MO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A33,
+ },
+ [0x16A34]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F MBAA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A34,
+ },
+ [0x16A35]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F TET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A35,
+ },
+ [0x16A36]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F KPA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A36,
+ },
+ [0x16A37]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F SAMBA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A37,
+ },
+ [0x16A38]={
+ category="lo",
+ description="BAMUM LETTER PHASE-F VUEQ",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16A38,
+ },
+ [0x16F00]={
+ category="lo",
+ description="MIAO LETTER PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F00,
+ },
+ [0x16F01]={
+ category="lo",
+ description="MIAO LETTER BA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F01,
+ },
+ [0x16F02]={
+ category="lo",
+ description="MIAO LETTER YI PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F02,
+ },
+ [0x16F03]={
+ category="lo",
+ description="MIAO LETTER PLA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F03,
+ },
+ [0x16F04]={
+ category="lo",
+ description="MIAO LETTER MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F04,
+ },
+ [0x16F05]={
+ category="lo",
+ description="MIAO LETTER MHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F05,
+ },
+ [0x16F06]={
+ category="lo",
+ description="MIAO LETTER ARCHAIC MA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F06,
+ },
+ [0x16F07]={
+ category="lo",
+ description="MIAO LETTER FA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F07,
+ },
+ [0x16F08]={
+ category="lo",
+ description="MIAO LETTER VA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F08,
+ },
+ [0x16F09]={
+ category="lo",
+ description="MIAO LETTER VFA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F09,
+ },
+ [0x16F0A]={
+ category="lo",
+ description="MIAO LETTER TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0A,
+ },
+ [0x16F0B]={
+ category="lo",
+ description="MIAO LETTER DA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0B,
+ },
+ [0x16F0C]={
+ category="lo",
+ description="MIAO LETTER YI TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0C,
+ },
+ [0x16F0D]={
+ category="lo",
+ description="MIAO LETTER YI TA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0D,
+ },
+ [0x16F0E]={
+ category="lo",
+ description="MIAO LETTER TTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0E,
+ },
+ [0x16F0F]={
+ category="lo",
+ description="MIAO LETTER DDA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F0F,
+ },
+ [0x16F10]={
+ category="lo",
+ description="MIAO LETTER NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F10,
+ },
+ [0x16F11]={
+ category="lo",
+ description="MIAO LETTER NHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F11,
+ },
+ [0x16F12]={
+ category="lo",
+ description="MIAO LETTER YI NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F12,
+ },
+ [0x16F13]={
+ category="lo",
+ description="MIAO LETTER ARCHAIC NA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F13,
+ },
+ [0x16F14]={
+ category="lo",
+ description="MIAO LETTER NNA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F14,
+ },
+ [0x16F15]={
+ category="lo",
+ description="MIAO LETTER NNHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F15,
+ },
+ [0x16F16]={
+ category="lo",
+ description="MIAO LETTER LA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F16,
+ },
+ [0x16F17]={
+ category="lo",
+ description="MIAO LETTER LYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F17,
+ },
+ [0x16F18]={
+ category="lo",
+ description="MIAO LETTER LHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F18,
+ },
+ [0x16F19]={
+ category="lo",
+ description="MIAO LETTER LHYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F19,
+ },
+ [0x16F1A]={
+ category="lo",
+ description="MIAO LETTER TLHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1A,
+ },
+ [0x16F1B]={
+ category="lo",
+ description="MIAO LETTER DLHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1B,
+ },
+ [0x16F1C]={
+ category="lo",
+ description="MIAO LETTER TLHYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1C,
+ },
+ [0x16F1D]={
+ category="lo",
+ description="MIAO LETTER DLHYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1D,
+ },
+ [0x16F1E]={
+ category="lo",
+ description="MIAO LETTER KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1E,
+ },
+ [0x16F1F]={
+ category="lo",
+ description="MIAO LETTER GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F1F,
+ },
+ [0x16F20]={
+ category="lo",
+ description="MIAO LETTER YI KA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F20,
+ },
+ [0x16F21]={
+ category="lo",
+ description="MIAO LETTER QA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F21,
+ },
+ [0x16F22]={
+ category="lo",
+ description="MIAO LETTER QGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F22,
+ },
+ [0x16F23]={
+ category="lo",
+ description="MIAO LETTER NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F23,
+ },
+ [0x16F24]={
+ category="lo",
+ description="MIAO LETTER NGHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F24,
+ },
+ [0x16F25]={
+ category="lo",
+ description="MIAO LETTER ARCHAIC NGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F25,
+ },
+ [0x16F26]={
+ category="lo",
+ description="MIAO LETTER HA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F26,
+ },
+ [0x16F27]={
+ category="lo",
+ description="MIAO LETTER XA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F27,
+ },
+ [0x16F28]={
+ category="lo",
+ description="MIAO LETTER GHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F28,
+ },
+ [0x16F29]={
+ category="lo",
+ description="MIAO LETTER GHHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F29,
+ },
+ [0x16F2A]={
+ category="lo",
+ description="MIAO LETTER TSSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2A,
+ },
+ [0x16F2B]={
+ category="lo",
+ description="MIAO LETTER DZZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2B,
+ },
+ [0x16F2C]={
+ category="lo",
+ description="MIAO LETTER NYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2C,
+ },
+ [0x16F2D]={
+ category="lo",
+ description="MIAO LETTER NYHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2D,
+ },
+ [0x16F2E]={
+ category="lo",
+ description="MIAO LETTER TSHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2E,
+ },
+ [0x16F2F]={
+ category="lo",
+ description="MIAO LETTER DZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F2F,
+ },
+ [0x16F30]={
+ category="lo",
+ description="MIAO LETTER YI TSHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F30,
+ },
+ [0x16F31]={
+ category="lo",
+ description="MIAO LETTER YI DZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F31,
+ },
+ [0x16F32]={
+ category="lo",
+ description="MIAO LETTER REFORMED TSHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F32,
+ },
+ [0x16F33]={
+ category="lo",
+ description="MIAO LETTER SHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F33,
+ },
+ [0x16F34]={
+ category="lo",
+ description="MIAO LETTER SSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F34,
+ },
+ [0x16F35]={
+ category="lo",
+ description="MIAO LETTER ZHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F35,
+ },
+ [0x16F36]={
+ category="lo",
+ description="MIAO LETTER ZSHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F36,
+ },
+ [0x16F37]={
+ category="lo",
+ description="MIAO LETTER TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F37,
+ },
+ [0x16F38]={
+ category="lo",
+ description="MIAO LETTER DZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F38,
+ },
+ [0x16F39]={
+ category="lo",
+ description="MIAO LETTER YI TSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F39,
+ },
+ [0x16F3A]={
+ category="lo",
+ description="MIAO LETTER SA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3A,
+ },
+ [0x16F3B]={
+ category="lo",
+ description="MIAO LETTER ZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3B,
+ },
+ [0x16F3C]={
+ category="lo",
+ description="MIAO LETTER ZSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3C,
+ },
+ [0x16F3D]={
+ category="lo",
+ description="MIAO LETTER ZZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3D,
+ },
+ [0x16F3E]={
+ category="lo",
+ description="MIAO LETTER ZZSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3E,
+ },
+ [0x16F3F]={
+ category="lo",
+ description="MIAO LETTER ARCHAIC ZZA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F3F,
+ },
+ [0x16F40]={
+ category="lo",
+ description="MIAO LETTER ZZYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F40,
+ },
+ [0x16F41]={
+ category="lo",
+ description="MIAO LETTER ZZSYA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F41,
+ },
+ [0x16F42]={
+ category="lo",
+ description="MIAO LETTER WA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F42,
+ },
+ [0x16F43]={
+ category="lo",
+ description="MIAO LETTER AH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F43,
+ },
+ [0x16F44]={
+ category="lo",
+ description="MIAO LETTER HHA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F44,
+ },
+ [0x16F50]={
+ category="lo",
+ description="MIAO LETTER NASALIZATION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F50,
+ },
+ [0x16F51]={
+ category="mc",
+ description="MIAO SIGN ASPIRATION",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F51,
+ },
+ [0x16F52]={
+ category="mc",
+ description="MIAO SIGN REFORMED VOICING",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F52,
+ },
+ [0x16F53]={
+ category="mc",
+ description="MIAO SIGN REFORMED ASPIRATION",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F53,
+ },
+ [0x16F54]={
+ category="mc",
+ description="MIAO VOWEL SIGN A",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F54,
+ },
+ [0x16F55]={
+ category="mc",
+ description="MIAO VOWEL SIGN AA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F55,
+ },
+ [0x16F56]={
+ category="mc",
+ description="MIAO VOWEL SIGN AHH",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F56,
+ },
+ [0x16F57]={
+ category="mc",
+ description="MIAO VOWEL SIGN AN",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F57,
+ },
+ [0x16F58]={
+ category="mc",
+ description="MIAO VOWEL SIGN ANG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F58,
+ },
+ [0x16F59]={
+ category="mc",
+ description="MIAO VOWEL SIGN O",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F59,
+ },
+ [0x16F5A]={
+ category="mc",
+ description="MIAO VOWEL SIGN OO",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F5A,
+ },
+ [0x16F5B]={
+ category="mc",
+ description="MIAO VOWEL SIGN WO",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F5B,
+ },
+ [0x16F5C]={
+ category="mc",
+ description="MIAO VOWEL SIGN W",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F5C,
+ },
+ [0x16F5D]={
+ category="mc",
+ description="MIAO VOWEL SIGN E",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F5D,
+ },
+ [0x16F5E]={
+ category="mc",
+ description="MIAO VOWEL SIGN EN",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F5E,
+ },
+ [0x16F5F]={
+ category="mc",
+ description="MIAO VOWEL SIGN ENG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F5F,
+ },
+ [0x16F60]={
+ category="mc",
+ description="MIAO VOWEL SIGN OEY",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F60,
+ },
+ [0x16F61]={
+ category="mc",
+ description="MIAO VOWEL SIGN I",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F61,
+ },
+ [0x16F62]={
+ category="mc",
+ description="MIAO VOWEL SIGN IA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F62,
+ },
+ [0x16F63]={
+ category="mc",
+ description="MIAO VOWEL SIGN IAN",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F63,
+ },
+ [0x16F64]={
+ category="mc",
+ description="MIAO VOWEL SIGN IANG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F64,
+ },
+ [0x16F65]={
+ category="mc",
+ description="MIAO VOWEL SIGN IO",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F65,
+ },
+ [0x16F66]={
+ category="mc",
+ description="MIAO VOWEL SIGN IE",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F66,
+ },
+ [0x16F67]={
+ category="mc",
+ description="MIAO VOWEL SIGN II",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F67,
+ },
+ [0x16F68]={
+ category="mc",
+ description="MIAO VOWEL SIGN IU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F68,
+ },
+ [0x16F69]={
+ category="mc",
+ description="MIAO VOWEL SIGN ING",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F69,
+ },
+ [0x16F6A]={
+ category="mc",
+ description="MIAO VOWEL SIGN U",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F6A,
+ },
+ [0x16F6B]={
+ category="mc",
+ description="MIAO VOWEL SIGN UA",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F6B,
+ },
+ [0x16F6C]={
+ category="mc",
+ description="MIAO VOWEL SIGN UAN",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F6C,
+ },
+ [0x16F6D]={
+ category="mc",
+ description="MIAO VOWEL SIGN UANG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F6D,
+ },
+ [0x16F6E]={
+ category="mc",
+ description="MIAO VOWEL SIGN UU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F6E,
+ },
+ [0x16F6F]={
+ category="mc",
+ description="MIAO VOWEL SIGN UEI",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F6F,
+ },
+ [0x16F70]={
+ category="mc",
+ description="MIAO VOWEL SIGN UNG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F70,
+ },
+ [0x16F71]={
+ category="mc",
+ description="MIAO VOWEL SIGN Y",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F71,
+ },
+ [0x16F72]={
+ category="mc",
+ description="MIAO VOWEL SIGN YI",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F72,
+ },
+ [0x16F73]={
+ category="mc",
+ description="MIAO VOWEL SIGN AE",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F73,
+ },
+ [0x16F74]={
+ category="mc",
+ description="MIAO VOWEL SIGN AEE",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F74,
+ },
+ [0x16F75]={
+ category="mc",
+ description="MIAO VOWEL SIGN ERR",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F75,
+ },
+ [0x16F76]={
+ category="mc",
+ description="MIAO VOWEL SIGN ROUNDED ERR",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F76,
+ },
+ [0x16F77]={
+ category="mc",
+ description="MIAO VOWEL SIGN ER",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F77,
+ },
+ [0x16F78]={
+ category="mc",
+ description="MIAO VOWEL SIGN ROUNDED ER",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F78,
+ },
+ [0x16F79]={
+ category="mc",
+ description="MIAO VOWEL SIGN AI",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F79,
+ },
+ [0x16F7A]={
+ category="mc",
+ description="MIAO VOWEL SIGN EI",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F7A,
+ },
+ [0x16F7B]={
+ category="mc",
+ description="MIAO VOWEL SIGN AU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F7B,
+ },
+ [0x16F7C]={
+ category="mc",
+ description="MIAO VOWEL SIGN OU",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F7C,
+ },
+ [0x16F7D]={
+ category="mc",
+ description="MIAO VOWEL SIGN N",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F7D,
+ },
+ [0x16F7E]={
+ category="mc",
+ description="MIAO VOWEL SIGN NG",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16F7E,
+ },
+ [0x16F8F]={
+ category="mn",
+ description="MIAO TONE RIGHT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16F8F,
+ },
+ [0x16F90]={
+ category="mn",
+ description="MIAO TONE TOP RIGHT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16F90,
+ },
+ [0x16F91]={
+ category="mn",
+ description="MIAO TONE ABOVE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16F91,
+ },
+ [0x16F92]={
+ category="mn",
+ description="MIAO TONE BELOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x16F92,
+ },
+ [0x16F93]={
+ category="lm",
+ description="MIAO LETTER TONE-2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F93,
+ },
+ [0x16F94]={
+ category="lm",
+ description="MIAO LETTER TONE-3",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F94,
+ },
+ [0x16F95]={
+ category="lm",
+ description="MIAO LETTER TONE-4",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F95,
+ },
+ [0x16F96]={
+ category="lm",
+ description="MIAO LETTER TONE-5",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F96,
+ },
+ [0x16F97]={
+ category="lm",
+ description="MIAO LETTER TONE-6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F97,
+ },
+ [0x16F98]={
+ category="lm",
+ description="MIAO LETTER TONE-7",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F98,
+ },
+ [0x16F99]={
+ category="lm",
+ description="MIAO LETTER TONE-8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F99,
+ },
+ [0x16F9A]={
+ category="lm",
+ description="MIAO LETTER REFORMED TONE-1",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F9A,
+ },
+ [0x16F9B]={
+ category="lm",
+ description="MIAO LETTER REFORMED TONE-2",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F9B,
+ },
+ [0x16F9C]={
+ category="lm",
+ description="MIAO LETTER REFORMED TONE-4",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F9C,
+ },
+ [0x16F9D]={
+ category="lm",
+ description="MIAO LETTER REFORMED TONE-5",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F9D,
+ },
+ [0x16F9E]={
+ category="lm",
+ description="MIAO LETTER REFORMED TONE-6",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F9E,
+ },
+ [0x16F9F]={
+ category="lm",
+ description="MIAO LETTER REFORMED TONE-8",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x16F9F,
+ },
+ [0x1B000]={
+ category="lo",
+ cjkwd="w",
+ description="KATAKANA LETTER ARCHAIC E",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B000,
+ },
+ [0x1B001]={
+ category="lo",
+ cjkwd="w",
+ description="HIRAGANA LETTER ARCHAIC YE",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x1B001,
+ },
+ [0x1D000]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PSILI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D000,
+ },
+ [0x1D001]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DASEIA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D001,
+ },
+ [0x1D002]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PERISPOMENI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D002,
+ },
+ [0x1D003]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D003,
+ },
+ [0x1D004]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL OXEIA DIPLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D004,
+ },
+ [0x1D005]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D005,
+ },
+ [0x1D006]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL VAREIA DIPLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D006,
+ },
+ [0x1D007]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KATHISTI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D007,
+ },
+ [0x1D008]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SYRMATIKI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D008,
+ },
+ [0x1D009]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PARAKLITIKI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D009,
+ },
+ [0x1D00A]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL YPOKRISIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00A,
+ },
+ [0x1D00B]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00B,
+ },
+ [0x1D00C]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KREMASTI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00C,
+ },
+ [0x1D00D]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00D,
+ },
+ [0x1D00E]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00E,
+ },
+ [0x1D00F]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TELEIA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D00F,
+ },
+ [0x1D010]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KENTIMATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D010,
+ },
+ [0x1D011]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL APOSTROFOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D011,
+ },
+ [0x1D012]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D012,
+ },
+ [0x1D013]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SYNEVMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D013,
+ },
+ [0x1D014]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL THITA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D014,
+ },
+ [0x1D015]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D015,
+ },
+ [0x1D016]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL GORGON ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D016,
+ },
+ [0x1D017]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PSILON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D017,
+ },
+ [0x1D018]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL CHAMILON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D018,
+ },
+ [0x1D019]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL VATHY",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D019,
+ },
+ [0x1D01A]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ISON ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01A,
+ },
+ [0x1D01B]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01B,
+ },
+ [0x1D01C]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01C,
+ },
+ [0x1D01D]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SAXIMATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01D,
+ },
+ [0x1D01E]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PARICHON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01E,
+ },
+ [0x1D01F]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D01F,
+ },
+ [0x1D020]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D020,
+ },
+ [0x1D021]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D021,
+ },
+ [0x1D022]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D022,
+ },
+ [0x1D023]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL APOTHEMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D023,
+ },
+ [0x1D024]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KLASMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D024,
+ },
+ [0x1D025]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL REVMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D025,
+ },
+ [0x1D026]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D026,
+ },
+ [0x1D027]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TINAGMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D027,
+ },
+ [0x1D028]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ANATRICHISMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D028,
+ },
+ [0x1D029]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SEISMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D029,
+ },
+ [0x1D02A]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02A,
+ },
+ [0x1D02B]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02B,
+ },
+ [0x1D02C]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02C,
+ },
+ [0x1D02D]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL THEMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02D,
+ },
+ [0x1D02E]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL LEMOI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02E,
+ },
+ [0x1D02F]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DYO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D02F,
+ },
+ [0x1D030]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TRIA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D030,
+ },
+ [0x1D031]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TESSERA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D031,
+ },
+ [0x1D032]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KRATIMATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D032,
+ },
+ [0x1D033]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL APESO EXO NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D033,
+ },
+ [0x1D034]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D034,
+ },
+ [0x1D035]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL IMIFTHORA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D035,
+ },
+ [0x1D036]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D036,
+ },
+ [0x1D037]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D037,
+ },
+ [0x1D038]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PELASTON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D038,
+ },
+ [0x1D039]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PSIFISTON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D039,
+ },
+ [0x1D03A]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KONTEVMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03A,
+ },
+ [0x1D03B]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03B,
+ },
+ [0x1D03C]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL RAPISMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03C,
+ },
+ [0x1D03D]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03D,
+ },
+ [0x1D03E]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03E,
+ },
+ [0x1D03F]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ICHADIN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D03F,
+ },
+ [0x1D040]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL NANA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D040,
+ },
+ [0x1D041]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PETASMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D041,
+ },
+ [0x1D042]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D042,
+ },
+ [0x1D043]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TROMIKON ALLO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D043,
+ },
+ [0x1D044]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL STRAGGISMATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D044,
+ },
+ [0x1D045]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL GRONTHISMATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D045,
+ },
+ [0x1D046]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ISON NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D046,
+ },
+ [0x1D047]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL OLIGON NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D047,
+ },
+ [0x1D048]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL OXEIA NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D048,
+ },
+ [0x1D049]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PETASTI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D049,
+ },
+ [0x1D04A]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KOUFISMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04A,
+ },
+ [0x1D04B]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04B,
+ },
+ [0x1D04C]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04C,
+ },
+ [0x1D04D]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PELASTON NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04D,
+ },
+ [0x1D04E]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04E,
+ },
+ [0x1D04F]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D04F,
+ },
+ [0x1D050]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL YPSILI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D050,
+ },
+ [0x1D051]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D051,
+ },
+ [0x1D052]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D052,
+ },
+ [0x1D053]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL YPORROI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D053,
+ },
+ [0x1D054]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D054,
+ },
+ [0x1D055]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ELAFRON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D055,
+ },
+ [0x1D056]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL CHAMILI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D056,
+ },
+ [0x1D057]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MIKRON ISON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D057,
+ },
+ [0x1D058]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL VAREIA NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D058,
+ },
+ [0x1D059]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PIASMA NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D059,
+ },
+ [0x1D05A]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PSIFISTON NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05A,
+ },
+ [0x1D05B]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL OMALON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05B,
+ },
+ [0x1D05C]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ANTIKENOMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05C,
+ },
+ [0x1D05D]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL LYGISMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05D,
+ },
+ [0x1D05E]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05E,
+ },
+ [0x1D05F]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D05F,
+ },
+ [0x1D060]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D060,
+ },
+ [0x1D061]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KYLISMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D061,
+ },
+ [0x1D062]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D062,
+ },
+ [0x1D063]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TROMIKON NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D063,
+ },
+ [0x1D064]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL EKSTREPTON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D064,
+ },
+ [0x1D065]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SYNAGMA NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D065,
+ },
+ [0x1D066]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SYRMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D066,
+ },
+ [0x1D067]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL CHOREVMA NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D067,
+ },
+ [0x1D068]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL EPEGERMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D068,
+ },
+ [0x1D069]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SEISMA NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D069,
+ },
+ [0x1D06A]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL XIRON KLASMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06A,
+ },
+ [0x1D06B]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06B,
+ },
+ [0x1D06C]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06C,
+ },
+ [0x1D06D]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06D,
+ },
+ [0x1D06E]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06E,
+ },
+ [0x1D06F]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D06F,
+ },
+ [0x1D070]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D070,
+ },
+ [0x1D071]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D071,
+ },
+ [0x1D072]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D072,
+ },
+ [0x1D073]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D073,
+ },
+ [0x1D074]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D074,
+ },
+ [0x1D075]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL OYRANISMA NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D075,
+ },
+ [0x1D076]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D076,
+ },
+ [0x1D077]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D077,
+ },
+ [0x1D078]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL THEMA APLOUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D078,
+ },
+ [0x1D079]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL THES KAI APOTHES",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D079,
+ },
+ [0x1D07A]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KATAVASMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07A,
+ },
+ [0x1D07B]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ENDOFONON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07B,
+ },
+ [0x1D07C]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL YFEN KATO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07C,
+ },
+ [0x1D07D]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL YFEN ANO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07D,
+ },
+ [0x1D07E]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL STAVROS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07E,
+ },
+ [0x1D07F]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KLASMA ANO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D07F,
+ },
+ [0x1D080]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D080,
+ },
+ [0x1D081]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D081,
+ },
+ [0x1D082]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KRATIMA ALLO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D082,
+ },
+ [0x1D083]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KRATIMA NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D083,
+ },
+ [0x1D084]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL APODERMA NEO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D084,
+ },
+ [0x1D085]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL APLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D085,
+ },
+ [0x1D086]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIPLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D086,
+ },
+ [0x1D087]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TRIPLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D087,
+ },
+ [0x1D088]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TETRAPLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D088,
+ },
+ [0x1D089]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KORONIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D089,
+ },
+ [0x1D08A]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08A,
+ },
+ [0x1D08B]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08B,
+ },
+ [0x1D08C]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08C,
+ },
+ [0x1D08D]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08D,
+ },
+ [0x1D08E]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08E,
+ },
+ [0x1D08F]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL GORGON NEO ANO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D08F,
+ },
+ [0x1D090]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D090,
+ },
+ [0x1D091]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D091,
+ },
+ [0x1D092]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIGORGON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D092,
+ },
+ [0x1D093]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D093,
+ },
+ [0x1D094]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D094,
+ },
+ [0x1D095]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D095,
+ },
+ [0x1D096]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL TRIGORGON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D096,
+ },
+ [0x1D097]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ARGON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D097,
+ },
+ [0x1D098]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL IMIDIARGON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D098,
+ },
+ [0x1D099]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIARGON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D099,
+ },
+ [0x1D09A]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09A,
+ },
+ [0x1D09B]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09B,
+ },
+ [0x1D09C]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL AGOGI ARGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09C,
+ },
+ [0x1D09D]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL AGOGI METRIA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09D,
+ },
+ [0x1D09E]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL AGOGI MESI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09E,
+ },
+ [0x1D09F]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL AGOGI GORGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D09F,
+ },
+ [0x1D0A0]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A0,
+ },
+ [0x1D0A1]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A1,
+ },
+ [0x1D0A2]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A2,
+ },
+ [0x1D0A3]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A3,
+ },
+ [0x1D0A4]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A4,
+ },
+ [0x1D0A5]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A5,
+ },
+ [0x1D0A6]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A6,
+ },
+ [0x1D0A7]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A7,
+ },
+ [0x1D0A8]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A8,
+ },
+ [0x1D0A9]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0A9,
+ },
+ [0x1D0AA]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0AA,
+ },
+ [0x1D0AB]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0AB,
+ },
+ [0x1D0AC]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0AC,
+ },
+ [0x1D0AD]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0AD,
+ },
+ [0x1D0AE]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0AE,
+ },
+ [0x1D0AF]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0AF,
+ },
+ [0x1D0B0]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B0,
+ },
+ [0x1D0B1]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B1,
+ },
+ [0x1D0B2]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B2,
+ },
+ [0x1D0B3]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B3,
+ },
+ [0x1D0B4]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B4,
+ },
+ [0x1D0B5]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B5,
+ },
+ [0x1D0B6]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B6,
+ },
+ [0x1D0B7]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL IMIFONON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B7,
+ },
+ [0x1D0B8]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL IMIFTHORON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B8,
+ },
+ [0x1D0B9]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0B9,
+ },
+ [0x1D0BA]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0BA,
+ },
+ [0x1D0BB]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0BB,
+ },
+ [0x1D0BC]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0BC,
+ },
+ [0x1D0BD]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0BD,
+ },
+ [0x1D0BE]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0BE,
+ },
+ [0x1D0BF]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0BF,
+ },
+ [0x1D0C0]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C0,
+ },
+ [0x1D0C1]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C1,
+ },
+ [0x1D0C2]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C2,
+ },
+ [0x1D0C3]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C3,
+ },
+ [0x1D0C4]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C4,
+ },
+ [0x1D0C5]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C5,
+ },
+ [0x1D0C6]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C6,
+ },
+ [0x1D0C7]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA NENANO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C7,
+ },
+ [0x1D0C8]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL CHROA ZYGOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C8,
+ },
+ [0x1D0C9]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL CHROA KLITON",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0C9,
+ },
+ [0x1D0CA]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL CHROA SPATHI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0CA,
+ },
+ [0x1D0CB]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0CB,
+ },
+ [0x1D0CC]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0CC,
+ },
+ [0x1D0CD]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0CD,
+ },
+ [0x1D0CE]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0CE,
+ },
+ [0x1D0CF]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0CF,
+ },
+ [0x1D0D0]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D0,
+ },
+ [0x1D0D1]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D1,
+ },
+ [0x1D0D2]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D2,
+ },
+ [0x1D0D3]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D3,
+ },
+ [0x1D0D4]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D4,
+ },
+ [0x1D0D5]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D5,
+ },
+ [0x1D0D6]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D6,
+ },
+ [0x1D0D7]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D7,
+ },
+ [0x1D0D8]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL GENIKI DIESIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D8,
+ },
+ [0x1D0D9]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL GENIKI YFESIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0D9,
+ },
+ [0x1D0DA]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0DA,
+ },
+ [0x1D0DB]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0DB,
+ },
+ [0x1D0DC]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0DC,
+ },
+ [0x1D0DD]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0DD,
+ },
+ [0x1D0DE]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0DE,
+ },
+ [0x1D0DF]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0DF,
+ },
+ [0x1D0E0]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E0,
+ },
+ [0x1D0E1]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E1,
+ },
+ [0x1D0E2]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E2,
+ },
+ [0x1D0E3]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E3,
+ },
+ [0x1D0E4]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E4,
+ },
+ [0x1D0E5]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E5,
+ },
+ [0x1D0E6]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIGRAMMA GG",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E6,
+ },
+ [0x1D0E7]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E7,
+ },
+ [0x1D0E8]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL STIGMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E8,
+ },
+ [0x1D0E9]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ARKTIKO PA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0E9,
+ },
+ [0x1D0EA]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ARKTIKO VOU",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0EA,
+ },
+ [0x1D0EB]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ARKTIKO GA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0EB,
+ },
+ [0x1D0EC]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ARKTIKO DI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0EC,
+ },
+ [0x1D0ED]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ARKTIKO KE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0ED,
+ },
+ [0x1D0EE]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ARKTIKO ZO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0EE,
+ },
+ [0x1D0EF]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL ARKTIKO NI",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0EF,
+ },
+ [0x1D0F0]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F0,
+ },
+ [0x1D0F1]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F1,
+ },
+ [0x1D0F2]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F2,
+ },
+ [0x1D0F3]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F3,
+ },
+ [0x1D0F4]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL KLASMA KATO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F4,
+ },
+ [0x1D0F5]={
+ category="so",
+ description="BYZANTINE MUSICAL SYMBOL GORGON NEO KATO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D0F5,
+ },
+ [0x1D100]={
+ category="so",
+ description="MUSICAL SYMBOL SINGLE BARLINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D100,
+ },
+ [0x1D101]={
+ category="so",
+ description="MUSICAL SYMBOL DOUBLE BARLINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D101,
+ },
+ [0x1D102]={
+ category="so",
+ description="MUSICAL SYMBOL FINAL BARLINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D102,
+ },
+ [0x1D103]={
+ category="so",
+ description="MUSICAL SYMBOL REVERSE FINAL BARLINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D103,
+ },
+ [0x1D104]={
+ category="so",
+ description="MUSICAL SYMBOL DASHED BARLINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D104,
+ },
+ [0x1D105]={
+ category="so",
+ description="MUSICAL SYMBOL SHORT BARLINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D105,
+ },
+ [0x1D106]={
+ category="so",
+ description="MUSICAL SYMBOL LEFT REPEAT SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D106,
+ },
+ [0x1D107]={
+ category="so",
+ description="MUSICAL SYMBOL RIGHT REPEAT SIGN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D107,
+ },
+ [0x1D108]={
+ category="so",
+ description="MUSICAL SYMBOL REPEAT DOTS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D108,
+ },
+ [0x1D109]={
+ category="so",
+ description="MUSICAL SYMBOL DAL SEGNO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D109,
+ },
+ [0x1D10A]={
+ category="so",
+ description="MUSICAL SYMBOL DA CAPO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10A,
+ },
+ [0x1D10B]={
+ category="so",
+ description="MUSICAL SYMBOL SEGNO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10B,
+ },
+ [0x1D10C]={
+ category="so",
+ description="MUSICAL SYMBOL CODA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10C,
+ },
+ [0x1D10D]={
+ category="so",
+ description="MUSICAL SYMBOL REPEATED FIGURE-0x0001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10D,
+ },
+ [0x1D10E]={
+ category="so",
+ description="MUSICAL SYMBOL REPEATED FIGURE-0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10E,
+ },
+ [0x1D10F]={
+ category="so",
+ description="MUSICAL SYMBOL REPEATED FIGURE-0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D10F,
+ },
+ [0x1D110]={
+ category="so",
+ description="MUSICAL SYMBOL FERMATA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D110,
+ },
+ [0x1D111]={
+ category="so",
+ description="MUSICAL SYMBOL FERMATA BELOW",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D111,
+ },
+ [0x1D112]={
+ category="so",
+ description="MUSICAL SYMBOL BREATH MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D112,
+ },
+ [0x1D113]={
+ category="so",
+ description="MUSICAL SYMBOL CAESURA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D113,
+ },
+ [0x1D114]={
+ category="so",
+ description="MUSICAL SYMBOL BRACE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D114,
+ },
+ [0x1D115]={
+ category="so",
+ description="MUSICAL SYMBOL BRACKET",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D115,
+ },
+ [0x1D116]={
+ category="so",
+ description="MUSICAL SYMBOL ONE-LINE STAFF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D116,
+ },
+ [0x1D117]={
+ category="so",
+ description="MUSICAL SYMBOL TWO-LINE STAFF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D117,
+ },
+ [0x1D118]={
+ category="so",
+ description="MUSICAL SYMBOL THREE-LINE STAFF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D118,
+ },
+ [0x1D119]={
+ category="so",
+ description="MUSICAL SYMBOL FOUR-LINE STAFF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D119,
+ },
+ [0x1D11A]={
+ category="so",
+ description="MUSICAL SYMBOL FIVE-LINE STAFF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11A,
+ },
+ [0x1D11B]={
+ category="so",
+ description="MUSICAL SYMBOL SIX-LINE STAFF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11B,
+ },
+ [0x1D11C]={
+ category="so",
+ description="MUSICAL SYMBOL SIX-STRING FRETBOARD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11C,
+ },
+ [0x1D11D]={
+ category="so",
+ description="MUSICAL SYMBOL FOUR-STRING FRETBOARD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11D,
+ },
+ [0x1D11E]={
+ category="so",
+ description="MUSICAL SYMBOL G CLEF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11E,
+ },
+ [0x1D11F]={
+ category="so",
+ description="MUSICAL SYMBOL G CLEF OTTAVA ALTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D11F,
+ },
+ [0x1D120]={
+ category="so",
+ description="MUSICAL SYMBOL G CLEF OTTAVA BASSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D120,
+ },
+ [0x1D121]={
+ category="so",
+ description="MUSICAL SYMBOL C CLEF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D121,
+ },
+ [0x1D122]={
+ category="so",
+ description="MUSICAL SYMBOL F CLEF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D122,
+ },
+ [0x1D123]={
+ category="so",
+ description="MUSICAL SYMBOL F CLEF OTTAVA ALTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D123,
+ },
+ [0x1D124]={
+ category="so",
+ description="MUSICAL SYMBOL F CLEF OTTAVA BASSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D124,
+ },
+ [0x1D125]={
+ category="so",
+ description="MUSICAL SYMBOL DRUM CLEF-0x0001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D125,
+ },
+ [0x1D126]={
+ category="so",
+ description="MUSICAL SYMBOL DRUM CLEF-0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D126,
+ },
+ [0x1D129]={
+ category="so",
+ description="MUSICAL SYMBOL MULTIPLE MEASURE REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D129,
+ },
+ [0x1D12A]={
+ category="so",
+ description="MUSICAL SYMBOL DOUBLE SHARP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12A,
+ },
+ [0x1D12B]={
+ category="so",
+ description="MUSICAL SYMBOL DOUBLE FLAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12B,
+ },
+ [0x1D12C]={
+ category="so",
+ description="MUSICAL SYMBOL FLAT UP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12C,
+ },
+ [0x1D12D]={
+ category="so",
+ description="MUSICAL SYMBOL FLAT DOWN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12D,
+ },
+ [0x1D12E]={
+ category="so",
+ description="MUSICAL SYMBOL NATURAL UP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12E,
+ },
+ [0x1D12F]={
+ category="so",
+ description="MUSICAL SYMBOL NATURAL DOWN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D12F,
+ },
+ [0x1D130]={
+ category="so",
+ description="MUSICAL SYMBOL SHARP UP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D130,
+ },
+ [0x1D131]={
+ category="so",
+ description="MUSICAL SYMBOL SHARP DOWN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D131,
+ },
+ [0x1D132]={
+ category="so",
+ description="MUSICAL SYMBOL QUARTER TONE SHARP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D132,
+ },
+ [0x1D133]={
+ category="so",
+ description="MUSICAL SYMBOL QUARTER TONE FLAT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D133,
+ },
+ [0x1D134]={
+ category="so",
+ description="MUSICAL SYMBOL COMMON TIME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D134,
+ },
+ [0x1D135]={
+ category="so",
+ description="MUSICAL SYMBOL CUT TIME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D135,
+ },
+ [0x1D136]={
+ category="so",
+ description="MUSICAL SYMBOL OTTAVA ALTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D136,
+ },
+ [0x1D137]={
+ category="so",
+ description="MUSICAL SYMBOL OTTAVA BASSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D137,
+ },
+ [0x1D138]={
+ category="so",
+ description="MUSICAL SYMBOL QUINDICESIMA ALTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D138,
+ },
+ [0x1D139]={
+ category="so",
+ description="MUSICAL SYMBOL QUINDICESIMA BASSA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D139,
+ },
+ [0x1D13A]={
+ category="so",
+ description="MUSICAL SYMBOL MULTI REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13A,
+ },
+ [0x1D13B]={
+ category="so",
+ description="MUSICAL SYMBOL WHOLE REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13B,
+ },
+ [0x1D13C]={
+ category="so",
+ description="MUSICAL SYMBOL HALF REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13C,
+ },
+ [0x1D13D]={
+ category="so",
+ description="MUSICAL SYMBOL QUARTER REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13D,
+ },
+ [0x1D13E]={
+ category="so",
+ description="MUSICAL SYMBOL EIGHTH REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13E,
+ },
+ [0x1D13F]={
+ category="so",
+ description="MUSICAL SYMBOL SIXTEENTH REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D13F,
+ },
+ [0x1D140]={
+ category="so",
+ description="MUSICAL SYMBOL THIRTY-SECOND REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D140,
+ },
+ [0x1D141]={
+ category="so",
+ description="MUSICAL SYMBOL SIXTY-FOURTH REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D141,
+ },
+ [0x1D142]={
+ category="so",
+ description="MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D142,
+ },
+ [0x1D143]={
+ category="so",
+ description="MUSICAL SYMBOL X NOTEHEAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D143,
+ },
+ [0x1D144]={
+ category="so",
+ description="MUSICAL SYMBOL PLUS NOTEHEAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D144,
+ },
+ [0x1D145]={
+ category="so",
+ description="MUSICAL SYMBOL CIRCLE X NOTEHEAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D145,
+ },
+ [0x1D146]={
+ category="so",
+ description="MUSICAL SYMBOL SQUARE NOTEHEAD WHITE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D146,
+ },
+ [0x1D147]={
+ category="so",
+ description="MUSICAL SYMBOL SQUARE NOTEHEAD BLACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D147,
+ },
+ [0x1D148]={
+ category="so",
+ description="MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D148,
+ },
+ [0x1D149]={
+ category="so",
+ description="MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D149,
+ },
+ [0x1D14A]={
+ category="so",
+ description="MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14A,
+ },
+ [0x1D14B]={
+ category="so",
+ description="MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14B,
+ },
+ [0x1D14C]={
+ category="so",
+ description="MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14C,
+ },
+ [0x1D14D]={
+ category="so",
+ description="MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14D,
+ },
+ [0x1D14E]={
+ category="so",
+ description="MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14E,
+ },
+ [0x1D14F]={
+ category="so",
+ description="MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D14F,
+ },
+ [0x1D150]={
+ category="so",
+ description="MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D150,
+ },
+ [0x1D151]={
+ category="so",
+ description="MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D151,
+ },
+ [0x1D152]={
+ category="so",
+ description="MUSICAL SYMBOL MOON NOTEHEAD WHITE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D152,
+ },
+ [0x1D153]={
+ category="so",
+ description="MUSICAL SYMBOL MOON NOTEHEAD BLACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D153,
+ },
+ [0x1D154]={
+ category="so",
+ description="MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D154,
+ },
+ [0x1D155]={
+ category="so",
+ description="MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D155,
+ },
+ [0x1D156]={
+ category="so",
+ description="MUSICAL SYMBOL PARENTHESIS NOTEHEAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D156,
+ },
+ [0x1D157]={
+ category="so",
+ description="MUSICAL SYMBOL VOID NOTEHEAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D157,
+ },
+ [0x1D158]={
+ category="so",
+ description="MUSICAL SYMBOL NOTEHEAD BLACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D158,
+ },
+ [0x1D159]={
+ category="so",
+ description="MUSICAL SYMBOL NULL NOTEHEAD",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D159,
+ },
+ [0x1D15A]={
+ category="so",
+ description="MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D15A,
+ },
+ [0x1D15B]={
+ category="so",
+ description="MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D15B,
+ },
+ [0x1D15C]={
+ category="so",
+ description="MUSICAL SYMBOL BREVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D15C,
+ },
+ [0x1D15D]={
+ category="so",
+ description="MUSICAL SYMBOL WHOLE NOTE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D15D,
+ },
+ [0x1D15E]={
+ category="so",
+ description="MUSICAL SYMBOL HALF NOTE",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D157, 0x1D165 },
+ unicodeslot=0x1D15E,
+ },
+ [0x1D15F]={
+ category="so",
+ description="MUSICAL SYMBOL QUARTER NOTE",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D158, 0x1D165 },
+ unicodeslot=0x1D15F,
+ },
+ [0x1D160]={
+ category="so",
+ description="MUSICAL SYMBOL EIGHTH NOTE",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D15F, 0x1D16E },
+ unicodeslot=0x1D160,
+ },
+ [0x1D161]={
+ category="so",
+ description="MUSICAL SYMBOL SIXTEENTH NOTE",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D15F, 0x1D16F },
+ unicodeslot=0x1D161,
+ },
+ [0x1D162]={
+ category="so",
+ description="MUSICAL SYMBOL THIRTY-SECOND NOTE",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D15F, 0x1D170 },
+ unicodeslot=0x1D162,
+ },
+ [0x1D163]={
+ category="so",
+ description="MUSICAL SYMBOL SIXTY-FOURTH NOTE",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D15F, 0x1D171 },
+ unicodeslot=0x1D163,
+ },
+ [0x1D164]={
+ category="so",
+ description="MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D15F, 0x1D172 },
+ unicodeslot=0x1D164,
+ },
+ [0x1D165]={
+ category="mc",
+ description="MUSICAL SYMBOL COMBINING STEM",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D165,
+ },
+ [0x1D166]={
+ category="mc",
+ description="MUSICAL SYMBOL COMBINING SPRECHGESANG STEM",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D166,
+ },
+ [0x1D167]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING TREMOLO-0x0001",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D167,
+ },
+ [0x1D168]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING TREMOLO-0x0002",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D168,
+ },
+ [0x1D169]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING TREMOLO-0x0003",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D169,
+ },
+ [0x1D16A]={
+ category="so",
+ description="MUSICAL SYMBOL FINGERED TREMOLO-0x0001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D16A,
+ },
+ [0x1D16B]={
+ category="so",
+ description="MUSICAL SYMBOL FINGERED TREMOLO-0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D16B,
+ },
+ [0x1D16C]={
+ category="so",
+ description="MUSICAL SYMBOL FINGERED TREMOLO-0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D16C,
+ },
+ [0x1D16D]={
+ category="mc",
+ description="MUSICAL SYMBOL COMBINING AUGMENTATION DOT",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D16D,
+ },
+ [0x1D16E]={
+ category="mc",
+ description="MUSICAL SYMBOL COMBINING FLAG-0x0001",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D16E,
+ },
+ [0x1D16F]={
+ category="mc",
+ description="MUSICAL SYMBOL COMBINING FLAG-0x0002",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D16F,
+ },
+ [0x1D170]={
+ category="mc",
+ description="MUSICAL SYMBOL COMBINING FLAG-0x0003",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D170,
+ },
+ [0x1D171]={
+ category="mc",
+ description="MUSICAL SYMBOL COMBINING FLAG-0x0004",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D171,
+ },
+ [0x1D172]={
+ category="mc",
+ description="MUSICAL SYMBOL COMBINING FLAG-0x0005",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1D172,
+ },
+ [0x1D173]={
+ category="cf",
+ description="MUSICAL SYMBOL BEGIN BEAM",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D173,
+ },
+ [0x1D174]={
+ category="cf",
+ description="MUSICAL SYMBOL END BEAM",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D174,
+ },
+ [0x1D175]={
+ category="cf",
+ description="MUSICAL SYMBOL BEGIN TIE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D175,
+ },
+ [0x1D176]={
+ category="cf",
+ description="MUSICAL SYMBOL END TIE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D176,
+ },
+ [0x1D177]={
+ category="cf",
+ description="MUSICAL SYMBOL BEGIN SLUR",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D177,
+ },
+ [0x1D178]={
+ category="cf",
+ description="MUSICAL SYMBOL END SLUR",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D178,
+ },
+ [0x1D179]={
+ category="cf",
+ description="MUSICAL SYMBOL BEGIN PHRASE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D179,
+ },
+ [0x1D17A]={
+ category="cf",
+ description="MUSICAL SYMBOL END PHRASE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0x1D17A,
+ },
+ [0x1D17B]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING ACCENT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D17B,
+ },
+ [0x1D17C]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING STACCATO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D17C,
+ },
+ [0x1D17D]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING TENUTO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D17D,
+ },
+ [0x1D17E]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING STACCATISSIMO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D17E,
+ },
+ [0x1D17F]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING MARCATO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D17F,
+ },
+ [0x1D180]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING MARCATO-STACCATO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D180,
+ },
+ [0x1D181]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING ACCENT-STACCATO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D181,
+ },
+ [0x1D182]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING LOURE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D182,
+ },
+ [0x1D183]={
+ category="so",
+ description="MUSICAL SYMBOL ARPEGGIATO UP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D183,
+ },
+ [0x1D184]={
+ category="so",
+ description="MUSICAL SYMBOL ARPEGGIATO DOWN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D184,
+ },
+ [0x1D185]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING DOIT",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D185,
+ },
+ [0x1D186]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING RIP",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D186,
+ },
+ [0x1D187]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING FLIP",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D187,
+ },
+ [0x1D188]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING SMEAR",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D188,
+ },
+ [0x1D189]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING BEND",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D189,
+ },
+ [0x1D18A]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING DOUBLE TONGUE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D18A,
+ },
+ [0x1D18B]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING TRIPLE TONGUE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D18B,
+ },
+ [0x1D18C]={
+ category="so",
+ description="MUSICAL SYMBOL RINFORZANDO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D18C,
+ },
+ [0x1D18D]={
+ category="so",
+ description="MUSICAL SYMBOL SUBITO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D18D,
+ },
+ [0x1D18E]={
+ category="so",
+ description="MUSICAL SYMBOL Z",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D18E,
+ },
+ [0x1D18F]={
+ category="so",
+ description="MUSICAL SYMBOL PIANO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D18F,
+ },
+ [0x1D190]={
+ category="so",
+ description="MUSICAL SYMBOL MEZZO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D190,
+ },
+ [0x1D191]={
+ category="so",
+ description="MUSICAL SYMBOL FORTE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D191,
+ },
+ [0x1D192]={
+ category="so",
+ description="MUSICAL SYMBOL CRESCENDO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D192,
+ },
+ [0x1D193]={
+ category="so",
+ description="MUSICAL SYMBOL DECRESCENDO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D193,
+ },
+ [0x1D194]={
+ category="so",
+ description="MUSICAL SYMBOL GRACE NOTE SLASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D194,
+ },
+ [0x1D195]={
+ category="so",
+ description="MUSICAL SYMBOL GRACE NOTE NO SLASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D195,
+ },
+ [0x1D196]={
+ category="so",
+ description="MUSICAL SYMBOL TR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D196,
+ },
+ [0x1D197]={
+ category="so",
+ description="MUSICAL SYMBOL TURN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D197,
+ },
+ [0x1D198]={
+ category="so",
+ description="MUSICAL SYMBOL INVERTED TURN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D198,
+ },
+ [0x1D199]={
+ category="so",
+ description="MUSICAL SYMBOL TURN SLASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D199,
+ },
+ [0x1D19A]={
+ category="so",
+ description="MUSICAL SYMBOL TURN UP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19A,
+ },
+ [0x1D19B]={
+ category="so",
+ description="MUSICAL SYMBOL ORNAMENT STROKE-0x0001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19B,
+ },
+ [0x1D19C]={
+ category="so",
+ description="MUSICAL SYMBOL ORNAMENT STROKE-0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19C,
+ },
+ [0x1D19D]={
+ category="so",
+ description="MUSICAL SYMBOL ORNAMENT STROKE-0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19D,
+ },
+ [0x1D19E]={
+ category="so",
+ description="MUSICAL SYMBOL ORNAMENT STROKE-0x0004",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19E,
+ },
+ [0x1D19F]={
+ category="so",
+ description="MUSICAL SYMBOL ORNAMENT STROKE-0x0005",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D19F,
+ },
+ [0x1D1A0]={
+ category="so",
+ description="MUSICAL SYMBOL ORNAMENT STROKE-0x0006",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A0,
+ },
+ [0x1D1A1]={
+ category="so",
+ description="MUSICAL SYMBOL ORNAMENT STROKE-0x0007",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A1,
+ },
+ [0x1D1A2]={
+ category="so",
+ description="MUSICAL SYMBOL ORNAMENT STROKE-0x0008",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A2,
+ },
+ [0x1D1A3]={
+ category="so",
+ description="MUSICAL SYMBOL ORNAMENT STROKE-0x0009",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A3,
+ },
+ [0x1D1A4]={
+ category="so",
+ description="MUSICAL SYMBOL ORNAMENT STROKE-0x000A",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A4,
+ },
+ [0x1D1A5]={
+ category="so",
+ description="MUSICAL SYMBOL ORNAMENT STROKE-0x000B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A5,
+ },
+ [0x1D1A6]={
+ category="so",
+ description="MUSICAL SYMBOL HAUPTSTIMME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A6,
+ },
+ [0x1D1A7]={
+ category="so",
+ description="MUSICAL SYMBOL NEBENSTIMME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A7,
+ },
+ [0x1D1A8]={
+ category="so",
+ description="MUSICAL SYMBOL END OF STIMME",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A8,
+ },
+ [0x1D1A9]={
+ category="so",
+ description="MUSICAL SYMBOL DEGREE SLASH",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1A9,
+ },
+ [0x1D1AA]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING DOWN BOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D1AA,
+ },
+ [0x1D1AB]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING UP BOW",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D1AB,
+ },
+ [0x1D1AC]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING HARMONIC",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D1AC,
+ },
+ [0x1D1AD]={
+ category="mn",
+ description="MUSICAL SYMBOL COMBINING SNAP PIZZICATO",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D1AD,
+ },
+ [0x1D1AE]={
+ category="so",
+ description="MUSICAL SYMBOL PEDAL MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1AE,
+ },
+ [0x1D1AF]={
+ category="so",
+ description="MUSICAL SYMBOL PEDAL UP MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1AF,
+ },
+ [0x1D1B0]={
+ category="so",
+ description="MUSICAL SYMBOL HALF PEDAL MARK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B0,
+ },
+ [0x1D1B1]={
+ category="so",
+ description="MUSICAL SYMBOL GLISSANDO UP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B1,
+ },
+ [0x1D1B2]={
+ category="so",
+ description="MUSICAL SYMBOL GLISSANDO DOWN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B2,
+ },
+ [0x1D1B3]={
+ category="so",
+ description="MUSICAL SYMBOL WITH FINGERNAILS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B3,
+ },
+ [0x1D1B4]={
+ category="so",
+ description="MUSICAL SYMBOL DAMP",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B4,
+ },
+ [0x1D1B5]={
+ category="so",
+ description="MUSICAL SYMBOL DAMP ALL",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B5,
+ },
+ [0x1D1B6]={
+ category="so",
+ description="MUSICAL SYMBOL MAXIMA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B6,
+ },
+ [0x1D1B7]={
+ category="so",
+ description="MUSICAL SYMBOL LONGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B7,
+ },
+ [0x1D1B8]={
+ category="so",
+ description="MUSICAL SYMBOL BREVIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B8,
+ },
+ [0x1D1B9]={
+ category="so",
+ description="MUSICAL SYMBOL SEMIBREVIS WHITE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1B9,
+ },
+ [0x1D1BA]={
+ category="so",
+ description="MUSICAL SYMBOL SEMIBREVIS BLACK",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1BA,
+ },
+ [0x1D1BB]={
+ category="so",
+ description="MUSICAL SYMBOL MINIMA",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D1B9, 0x1D165 },
+ unicodeslot=0x1D1BB,
+ },
+ [0x1D1BC]={
+ category="so",
+ description="MUSICAL SYMBOL MINIMA BLACK",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D1BA, 0x1D165 },
+ unicodeslot=0x1D1BC,
+ },
+ [0x1D1BD]={
+ category="so",
+ description="MUSICAL SYMBOL SEMIMINIMA WHITE",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D1BB, 0x1D16E },
+ unicodeslot=0x1D1BD,
+ },
+ [0x1D1BE]={
+ category="so",
+ description="MUSICAL SYMBOL SEMIMINIMA BLACK",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D1BC, 0x1D16E },
+ unicodeslot=0x1D1BE,
+ },
+ [0x1D1BF]={
+ category="so",
+ description="MUSICAL SYMBOL FUSA WHITE",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D1BB, 0x1D16F },
+ unicodeslot=0x1D1BF,
+ },
+ [0x1D1C0]={
+ category="so",
+ description="MUSICAL SYMBOL FUSA BLACK",
+ direction="l",
+ linebreak="al",
+ specials={ "char", 0x1D1BC, 0x1D16F },
+ unicodeslot=0x1D1C0,
+ },
+ [0x1D1C1]={
+ category="so",
+ description="MUSICAL SYMBOL LONGA PERFECTA REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C1,
+ },
+ [0x1D1C2]={
+ category="so",
+ description="MUSICAL SYMBOL LONGA IMPERFECTA REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C2,
+ },
+ [0x1D1C3]={
+ category="so",
+ description="MUSICAL SYMBOL BREVIS REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C3,
+ },
+ [0x1D1C4]={
+ category="so",
+ description="MUSICAL SYMBOL SEMIBREVIS REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C4,
+ },
+ [0x1D1C5]={
+ category="so",
+ description="MUSICAL SYMBOL MINIMA REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C5,
+ },
+ [0x1D1C6]={
+ category="so",
+ description="MUSICAL SYMBOL SEMIMINIMA REST",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C6,
+ },
+ [0x1D1C7]={
+ category="so",
+ description="MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C7,
+ },
+ [0x1D1C8]={
+ category="so",
+ description="MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C8,
+ },
+ [0x1D1C9]={
+ category="so",
+ description="MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-0x0001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1C9,
+ },
+ [0x1D1CA]={
+ category="so",
+ description="MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1CA,
+ },
+ [0x1D1CB]={
+ category="so",
+ description="MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1CB,
+ },
+ [0x1D1CC]={
+ category="so",
+ description="MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-0x0001",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1CC,
+ },
+ [0x1D1CD]={
+ category="so",
+ description="MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-0x0002",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1CD,
+ },
+ [0x1D1CE]={
+ category="so",
+ description="MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-0x0003",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1CE,
+ },
+ [0x1D1CF]={
+ category="so",
+ description="MUSICAL SYMBOL CROIX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1CF,
+ },
+ [0x1D1D0]={
+ category="so",
+ description="MUSICAL SYMBOL GREGORIAN C CLEF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D0,
+ },
+ [0x1D1D1]={
+ category="so",
+ description="MUSICAL SYMBOL GREGORIAN F CLEF",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D1,
+ },
+ [0x1D1D2]={
+ category="so",
+ description="MUSICAL SYMBOL SQUARE B",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D2,
+ },
+ [0x1D1D3]={
+ category="so",
+ description="MUSICAL SYMBOL VIRGA",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D3,
+ },
+ [0x1D1D4]={
+ category="so",
+ description="MUSICAL SYMBOL PODATUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D4,
+ },
+ [0x1D1D5]={
+ category="so",
+ description="MUSICAL SYMBOL CLIVIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D5,
+ },
+ [0x1D1D6]={
+ category="so",
+ description="MUSICAL SYMBOL SCANDICUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D6,
+ },
+ [0x1D1D7]={
+ category="so",
+ description="MUSICAL SYMBOL CLIMACUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D7,
+ },
+ [0x1D1D8]={
+ category="so",
+ description="MUSICAL SYMBOL TORCULUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D8,
+ },
+ [0x1D1D9]={
+ category="so",
+ description="MUSICAL SYMBOL PORRECTUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1D9,
+ },
+ [0x1D1DA]={
+ category="so",
+ description="MUSICAL SYMBOL PORRECTUS FLEXUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1DA,
+ },
+ [0x1D1DB]={
+ category="so",
+ description="MUSICAL SYMBOL SCANDICUS FLEXUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1DB,
+ },
+ [0x1D1DC]={
+ category="so",
+ description="MUSICAL SYMBOL TORCULUS RESUPINUS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1DC,
+ },
+ [0x1D1DD]={
+ category="so",
+ description="MUSICAL SYMBOL PES SUBPUNCTIS",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D1DD,
+ },
+ [0x1D200]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0001",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D200,
+ },
+ [0x1D201]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0002",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D201,
+ },
+ [0x1D202]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0003",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D202,
+ },
+ [0x1D203]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0004",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D203,
+ },
+ [0x1D204]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0005",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D204,
+ },
+ [0x1D205]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0006",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D205,
+ },
+ [0x1D206]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0007",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D206,
+ },
+ [0x1D207]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0008",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D207,
+ },
+ [0x1D208]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0009",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D208,
+ },
+ [0x1D209]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x000A",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D209,
+ },
+ [0x1D20A]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x000B",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D20A,
+ },
+ [0x1D20B]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x000C",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D20B,
+ },
+ [0x1D20C]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x000D",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D20C,
+ },
+ [0x1D20D]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x000E",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D20D,
+ },
+ [0x1D20E]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x000F",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D20E,
+ },
+ [0x1D20F]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0010",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D20F,
+ },
+ [0x1D210]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0011",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D210,
+ },
+ [0x1D211]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0012",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D211,
+ },
+ [0x1D212]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0013",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D212,
+ },
+ [0x1D213]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0014",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D213,
+ },
+ [0x1D214]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0015",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D214,
+ },
+ [0x1D215]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0016",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D215,
+ },
+ [0x1D216]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0017",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D216,
+ },
+ [0x1D217]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0018",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D217,
+ },
+ [0x1D218]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0032",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D218,
+ },
+ [0x1D219]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0033",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D219,
+ },
+ [0x1D21A]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0034",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D21A,
+ },
+ [0x1D21B]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0035",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D21B,
+ },
+ [0x1D21C]={
+ category="so",
+ description="GREEK VOCAL NOTATION SYMBOL-0x0036",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D21C,
+ },
+ [0x1D21D]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0001",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D21D,
+ },
+ [0x1D21E]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0002",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D21E,
+ },
+ [0x1D21F]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0004",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D21F,
+ },
+ [0x1D220]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0005",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D220,
+ },
+ [0x1D221]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0007",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D221,
+ },
+ [0x1D222]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0008",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D222,
+ },
+ [0x1D223]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x000B",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D223,
+ },
+ [0x1D224]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x000C",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D224,
+ },
+ [0x1D225]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x000D",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D225,
+ },
+ [0x1D226]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x000E",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D226,
+ },
+ [0x1D227]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0011",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D227,
+ },
+ [0x1D228]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0012",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D228,
+ },
+ [0x1D229]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0013",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D229,
+ },
+ [0x1D22A]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0017",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D22A,
+ },
+ [0x1D22B]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0018",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D22B,
+ },
+ [0x1D22C]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0019",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D22C,
+ },
+ [0x1D22D]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x001A",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D22D,
+ },
+ [0x1D22E]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x001B",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D22E,
+ },
+ [0x1D22F]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x001D",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D22F,
+ },
+ [0x1D230]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x001E",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D230,
+ },
+ [0x1D231]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0020",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D231,
+ },
+ [0x1D232]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0024",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D232,
+ },
+ [0x1D233]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0025",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D233,
+ },
+ [0x1D234]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0026",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D234,
+ },
+ [0x1D235]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0027",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D235,
+ },
+ [0x1D236]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0028",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D236,
+ },
+ [0x1D237]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x002A",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D237,
+ },
+ [0x1D238]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x002B",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D238,
+ },
+ [0x1D239]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x002D",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D239,
+ },
+ [0x1D23A]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x002F",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D23A,
+ },
+ [0x1D23B]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0030",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D23B,
+ },
+ [0x1D23C]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0031",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D23C,
+ },
+ [0x1D23D]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0032",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D23D,
+ },
+ [0x1D23E]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0033",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D23E,
+ },
+ [0x1D23F]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0034",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D23F,
+ },
+ [0x1D240]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0035",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D240,
+ },
+ [0x1D241]={
+ category="so",
+ description="GREEK INSTRUMENTAL NOTATION SYMBOL-0x0036",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D241,
+ },
+ [0x1D242]={
+ category="mn",
+ description="COMBINING GREEK MUSICAL TRISEME",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D242,
+ },
+ [0x1D243]={
+ category="mn",
+ description="COMBINING GREEK MUSICAL TETRASEME",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D243,
+ },
+ [0x1D244]={
+ category="mn",
+ description="COMBINING GREEK MUSICAL PENTASEME",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1D244,
+ },
+ [0x1D245]={
+ category="so",
+ description="GREEK MUSICAL LEIMMA",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D245,
+ },
+ [0x1D300]={
+ category="so",
+ description="MONOGRAM FOR EARTH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D300,
+ },
+ [0x1D301]={
+ category="so",
+ description="DIGRAM FOR HEAVENLY EARTH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D301,
+ },
+ [0x1D302]={
+ category="so",
+ description="DIGRAM FOR HUMAN EARTH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D302,
+ },
+ [0x1D303]={
+ category="so",
+ description="DIGRAM FOR EARTHLY HEAVEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D303,
+ },
+ [0x1D304]={
+ category="so",
+ description="DIGRAM FOR EARTHLY HUMAN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D304,
+ },
+ [0x1D305]={
+ category="so",
+ description="DIGRAM FOR EARTH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D305,
+ },
+ [0x1D306]={
+ category="so",
+ description="TETRAGRAM FOR CENTRE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D306,
+ },
+ [0x1D307]={
+ category="so",
+ description="TETRAGRAM FOR FULL CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D307,
+ },
+ [0x1D308]={
+ category="so",
+ description="TETRAGRAM FOR MIRED",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D308,
+ },
+ [0x1D309]={
+ category="so",
+ description="TETRAGRAM FOR BARRIER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D309,
+ },
+ [0x1D30A]={
+ category="so",
+ description="TETRAGRAM FOR KEEPING SMALL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D30A,
+ },
+ [0x1D30B]={
+ category="so",
+ description="TETRAGRAM FOR CONTRARIETY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D30B,
+ },
+ [0x1D30C]={
+ category="so",
+ description="TETRAGRAM FOR ASCENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D30C,
+ },
+ [0x1D30D]={
+ category="so",
+ description="TETRAGRAM FOR OPPOSITION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D30D,
+ },
+ [0x1D30E]={
+ category="so",
+ description="TETRAGRAM FOR BRANCHING OUT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D30E,
+ },
+ [0x1D30F]={
+ category="so",
+ description="TETRAGRAM FOR DEFECTIVENESS OR DISTORTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D30F,
+ },
+ [0x1D310]={
+ category="so",
+ description="TETRAGRAM FOR DIVERGENCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D310,
+ },
+ [0x1D311]={
+ category="so",
+ description="TETRAGRAM FOR YOUTHFULNESS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D311,
+ },
+ [0x1D312]={
+ category="so",
+ description="TETRAGRAM FOR INCREASE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D312,
+ },
+ [0x1D313]={
+ category="so",
+ description="TETRAGRAM FOR PENETRATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D313,
+ },
+ [0x1D314]={
+ category="so",
+ description="TETRAGRAM FOR REACH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D314,
+ },
+ [0x1D315]={
+ category="so",
+ description="TETRAGRAM FOR CONTACT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D315,
+ },
+ [0x1D316]={
+ category="so",
+ description="TETRAGRAM FOR HOLDING BACK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D316,
+ },
+ [0x1D317]={
+ category="so",
+ description="TETRAGRAM FOR WAITING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D317,
+ },
+ [0x1D318]={
+ category="so",
+ description="TETRAGRAM FOR FOLLOWING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D318,
+ },
+ [0x1D319]={
+ category="so",
+ description="TETRAGRAM FOR ADVANCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D319,
+ },
+ [0x1D31A]={
+ category="so",
+ description="TETRAGRAM FOR RELEASE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D31A,
+ },
+ [0x1D31B]={
+ category="so",
+ description="TETRAGRAM FOR RESISTANCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D31B,
+ },
+ [0x1D31C]={
+ category="so",
+ description="TETRAGRAM FOR EASE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D31C,
+ },
+ [0x1D31D]={
+ category="so",
+ description="TETRAGRAM FOR JOY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D31D,
+ },
+ [0x1D31E]={
+ category="so",
+ description="TETRAGRAM FOR CONTENTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D31E,
+ },
+ [0x1D31F]={
+ category="so",
+ description="TETRAGRAM FOR ENDEAVOUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D31F,
+ },
+ [0x1D320]={
+ category="so",
+ description="TETRAGRAM FOR DUTIES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D320,
+ },
+ [0x1D321]={
+ category="so",
+ description="TETRAGRAM FOR CHANGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D321,
+ },
+ [0x1D322]={
+ category="so",
+ description="TETRAGRAM FOR DECISIVENESS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D322,
+ },
+ [0x1D323]={
+ category="so",
+ description="TETRAGRAM FOR BOLD RESOLUTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D323,
+ },
+ [0x1D324]={
+ category="so",
+ description="TETRAGRAM FOR PACKING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D324,
+ },
+ [0x1D325]={
+ category="so",
+ description="TETRAGRAM FOR LEGION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D325,
+ },
+ [0x1D326]={
+ category="so",
+ description="TETRAGRAM FOR CLOSENESS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D326,
+ },
+ [0x1D327]={
+ category="so",
+ description="TETRAGRAM FOR KINSHIP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D327,
+ },
+ [0x1D328]={
+ category="so",
+ description="TETRAGRAM FOR GATHERING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D328,
+ },
+ [0x1D329]={
+ category="so",
+ description="TETRAGRAM FOR STRENGTH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D329,
+ },
+ [0x1D32A]={
+ category="so",
+ description="TETRAGRAM FOR PURITY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D32A,
+ },
+ [0x1D32B]={
+ category="so",
+ description="TETRAGRAM FOR FULLNESS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D32B,
+ },
+ [0x1D32C]={
+ category="so",
+ description="TETRAGRAM FOR RESIDENCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D32C,
+ },
+ [0x1D32D]={
+ category="so",
+ description="TETRAGRAM FOR LAW OR MODEL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D32D,
+ },
+ [0x1D32E]={
+ category="so",
+ description="TETRAGRAM FOR RESPONSE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D32E,
+ },
+ [0x1D32F]={
+ category="so",
+ description="TETRAGRAM FOR GOING TO MEET",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D32F,
+ },
+ [0x1D330]={
+ category="so",
+ description="TETRAGRAM FOR ENCOUNTERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D330,
+ },
+ [0x1D331]={
+ category="so",
+ description="TETRAGRAM FOR STOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D331,
+ },
+ [0x1D332]={
+ category="so",
+ description="TETRAGRAM FOR GREATNESS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D332,
+ },
+ [0x1D333]={
+ category="so",
+ description="TETRAGRAM FOR ENLARGEMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D333,
+ },
+ [0x1D334]={
+ category="so",
+ description="TETRAGRAM FOR PATTERN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D334,
+ },
+ [0x1D335]={
+ category="so",
+ description="TETRAGRAM FOR RITUAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D335,
+ },
+ [0x1D336]={
+ category="so",
+ description="TETRAGRAM FOR FLIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D336,
+ },
+ [0x1D337]={
+ category="so",
+ description="TETRAGRAM FOR VASTNESS OR WASTING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D337,
+ },
+ [0x1D338]={
+ category="so",
+ description="TETRAGRAM FOR CONSTANCY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D338,
+ },
+ [0x1D339]={
+ category="so",
+ description="TETRAGRAM FOR MEASURE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D339,
+ },
+ [0x1D33A]={
+ category="so",
+ description="TETRAGRAM FOR ETERNITY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D33A,
+ },
+ [0x1D33B]={
+ category="so",
+ description="TETRAGRAM FOR UNITY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D33B,
+ },
+ [0x1D33C]={
+ category="so",
+ description="TETRAGRAM FOR DIMINISHMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D33C,
+ },
+ [0x1D33D]={
+ category="so",
+ description="TETRAGRAM FOR CLOSED MOUTH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D33D,
+ },
+ [0x1D33E]={
+ category="so",
+ description="TETRAGRAM FOR GUARDEDNESS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D33E,
+ },
+ [0x1D33F]={
+ category="so",
+ description="TETRAGRAM FOR GATHERING IN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D33F,
+ },
+ [0x1D340]={
+ category="so",
+ description="TETRAGRAM FOR MASSING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D340,
+ },
+ [0x1D341]={
+ category="so",
+ description="TETRAGRAM FOR ACCUMULATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D341,
+ },
+ [0x1D342]={
+ category="so",
+ description="TETRAGRAM FOR EMBELLISHMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D342,
+ },
+ [0x1D343]={
+ category="so",
+ description="TETRAGRAM FOR DOUBT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D343,
+ },
+ [0x1D344]={
+ category="so",
+ description="TETRAGRAM FOR WATCH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D344,
+ },
+ [0x1D345]={
+ category="so",
+ description="TETRAGRAM FOR SINKING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D345,
+ },
+ [0x1D346]={
+ category="so",
+ description="TETRAGRAM FOR INNER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D346,
+ },
+ [0x1D347]={
+ category="so",
+ description="TETRAGRAM FOR DEPARTURE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D347,
+ },
+ [0x1D348]={
+ category="so",
+ description="TETRAGRAM FOR DARKENING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D348,
+ },
+ [0x1D349]={
+ category="so",
+ description="TETRAGRAM FOR DIMMING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D349,
+ },
+ [0x1D34A]={
+ category="so",
+ description="TETRAGRAM FOR EXHAUSTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D34A,
+ },
+ [0x1D34B]={
+ category="so",
+ description="TETRAGRAM FOR SEVERANCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D34B,
+ },
+ [0x1D34C]={
+ category="so",
+ description="TETRAGRAM FOR STOPPAGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D34C,
+ },
+ [0x1D34D]={
+ category="so",
+ description="TETRAGRAM FOR HARDNESS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D34D,
+ },
+ [0x1D34E]={
+ category="so",
+ description="TETRAGRAM FOR COMPLETION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D34E,
+ },
+ [0x1D34F]={
+ category="so",
+ description="TETRAGRAM FOR CLOSURE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D34F,
+ },
+ [0x1D350]={
+ category="so",
+ description="TETRAGRAM FOR FAILURE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D350,
+ },
+ [0x1D351]={
+ category="so",
+ description="TETRAGRAM FOR AGGRAVATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D351,
+ },
+ [0x1D352]={
+ category="so",
+ description="TETRAGRAM FOR COMPLIANCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D352,
+ },
+ [0x1D353]={
+ category="so",
+ description="TETRAGRAM FOR ON THE VERGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D353,
+ },
+ [0x1D354]={
+ category="so",
+ description="TETRAGRAM FOR DIFFICULTIES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D354,
+ },
+ [0x1D355]={
+ category="so",
+ description="TETRAGRAM FOR LABOURING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D355,
+ },
+ [0x1D356]={
+ category="so",
+ description="TETRAGRAM FOR FOSTERING",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1D356,
+ },
+ [0x1D360]={
+ category="no",
+ description="COUNTING ROD UNIT DIGIT ONE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D360,
+ },
+ [0x1D361]={
+ category="no",
+ description="COUNTING ROD UNIT DIGIT TWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D361,
+ },
+ [0x1D362]={
+ category="no",
+ description="COUNTING ROD UNIT DIGIT THREE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D362,
+ },
+ [0x1D363]={
+ category="no",
+ description="COUNTING ROD UNIT DIGIT FOUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D363,
+ },
+ [0x1D364]={
+ category="no",
+ description="COUNTING ROD UNIT DIGIT FIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D364,
+ },
+ [0x1D365]={
+ category="no",
+ description="COUNTING ROD UNIT DIGIT SIX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D365,
+ },
+ [0x1D366]={
+ category="no",
+ description="COUNTING ROD UNIT DIGIT SEVEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D366,
+ },
+ [0x1D367]={
+ category="no",
+ description="COUNTING ROD UNIT DIGIT EIGHT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D367,
+ },
+ [0x1D368]={
+ category="no",
+ description="COUNTING ROD UNIT DIGIT NINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D368,
+ },
+ [0x1D369]={
+ category="no",
+ description="COUNTING ROD TENS DIGIT ONE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D369,
+ },
+ [0x1D36A]={
+ category="no",
+ description="COUNTING ROD TENS DIGIT TWO",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D36A,
+ },
+ [0x1D36B]={
+ category="no",
+ description="COUNTING ROD TENS DIGIT THREE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D36B,
+ },
+ [0x1D36C]={
+ category="no",
+ description="COUNTING ROD TENS DIGIT FOUR",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D36C,
+ },
+ [0x1D36D]={
+ category="no",
+ description="COUNTING ROD TENS DIGIT FIVE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D36D,
+ },
+ [0x1D36E]={
+ category="no",
+ description="COUNTING ROD TENS DIGIT SIX",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D36E,
+ },
+ [0x1D36F]={
+ category="no",
+ description="COUNTING ROD TENS DIGIT SEVEN",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D36F,
+ },
+ [0x1D370]={
+ category="no",
+ description="COUNTING ROD TENS DIGIT EIGHT",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D370,
+ },
+ [0x1D371]={
+ category="no",
+ description="COUNTING ROD TENS DIGIT NINE",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1D371,
+ },
+ [0x1D400]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D400,
+ visual="bf",
+ },
+ [0x1D401]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x1D401,
+ visual="bf",
+ },
+ [0x1D402]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x1D402,
+ visual="bf",
+ },
+ [0x1D403]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D403,
+ visual="bf",
+ },
+ [0x1D404]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x1D404,
+ visual="bf",
+ },
+ [0x1D405]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x1D405,
+ visual="bf",
+ },
+ [0x1D406]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D406,
+ visual="bf",
+ },
+ [0x1D407]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x1D407,
+ visual="bf",
+ },
+ [0x1D408]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x1D408,
+ visual="bf",
+ },
+ [0x1D409]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D409,
+ visual="bf",
+ },
+ [0x1D40A]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D40A,
+ visual="bf",
+ },
+ [0x1D40B]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x1D40B,
+ visual="bf",
+ },
+ [0x1D40C]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x1D40C,
+ visual="bf",
+ },
+ [0x1D40D]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004E },
+ unicodeslot=0x1D40D,
+ visual="bf",
+ },
+ [0x1D40E]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D40E,
+ visual="bf",
+ },
+ [0x1D40F]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x1D40F,
+ visual="bf",
+ },
+ [0x1D410]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x1D410,
+ visual="bf",
+ },
+ [0x1D411]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x1D411,
+ visual="bf",
+ },
+ [0x1D412]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D412,
+ visual="bf",
+ },
+ [0x1D413]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D413,
+ visual="bf",
+ },
+ [0x1D414]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D414,
+ visual="bf",
+ },
+ [0x1D415]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D415,
+ visual="bf",
+ },
+ [0x1D416]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D416,
+ visual="bf",
+ },
+ [0x1D417]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D417,
+ visual="bf",
+ },
+ [0x1D418]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D418,
+ visual="bf",
+ },
+ [0x1D419]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x005A },
+ unicodeslot=0x1D419,
+ visual="bf",
+ },
+ [0x1D41A]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D41A,
+ visual="bf",
+ },
+ [0x1D41B]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D41B,
+ visual="bf",
+ },
+ [0x1D41C]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D41C,
+ visual="bf",
+ },
+ [0x1D41D]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D41D,
+ visual="bf",
+ },
+ [0x1D41E]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x1D41E,
+ visual="bf",
+ },
+ [0x1D41F]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D41F,
+ visual="bf",
+ },
+ [0x1D420]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x1D420,
+ visual="bf",
+ },
+ [0x1D421]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x1D421,
+ visual="bf",
+ },
+ [0x1D422]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D422,
+ visual="bf",
+ },
+ [0x1D423]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D423,
+ visual="bf",
+ },
+ [0x1D424]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D424,
+ visual="bf",
+ },
+ [0x1D425]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D425,
+ visual="bf",
+ },
+ [0x1D426]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D426,
+ visual="bf",
+ },
+ [0x1D427]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D427,
+ visual="bf",
+ },
+ [0x1D428]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x1D428,
+ visual="bf",
+ },
+ [0x1D429]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D429,
+ visual="bf",
+ },
+ [0x1D42A]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D42A,
+ visual="bf",
+ },
+ [0x1D42B]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D42B,
+ visual="bf",
+ },
+ [0x1D42C]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D42C,
+ visual="bf",
+ },
+ [0x1D42D]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D42D,
+ visual="bf",
+ },
+ [0x1D42E]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D42E,
+ visual="bf",
+ },
+ [0x1D42F]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D42F,
+ visual="bf",
+ },
+ [0x1D430]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D430,
+ visual="bf",
+ },
+ [0x1D431]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D431,
+ visual="bf",
+ },
+ [0x1D432]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D432,
+ visual="bf",
+ },
+ [0x1D433]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D433,
+ visual="bf",
+ },
+ [0x1D434]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D434,
+ visual="it",
+ },
+ [0x1D435]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x1D435,
+ visual="it",
+ },
+ [0x1D436]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x1D436,
+ visual="it",
+ },
+ [0x1D437]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D437,
+ visual="it",
+ },
+ [0x1D438]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x1D438,
+ visual="it",
+ },
+ [0x1D439]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x1D439,
+ visual="it",
+ },
+ [0x1D43A]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D43A,
+ visual="it",
+ },
+ [0x1D43B]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x1D43B,
+ visual="it",
+ },
+ [0x1D43C]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x1D43C,
+ visual="it",
+ },
+ [0x1D43D]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D43D,
+ visual="it",
+ },
+ [0x1D43E]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D43E,
+ visual="it",
+ },
+ [0x1D43F]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x1D43F,
+ visual="it",
+ },
+ [0x1D440]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x1D440,
+ visual="it",
+ },
+ [0x1D441]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004E },
+ unicodeslot=0x1D441,
+ visual="it",
+ },
+ [0x1D442]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D442,
+ visual="it",
+ },
+ [0x1D443]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x1D443,
+ visual="it",
+ },
+ [0x1D444]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x1D444,
+ visual="it",
+ },
+ [0x1D445]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x1D445,
+ visual="it",
+ },
+ [0x1D446]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D446,
+ visual="it",
+ },
+ [0x1D447]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D447,
+ visual="it",
+ },
+ [0x1D448]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D448,
+ visual="it",
+ },
+ [0x1D449]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D449,
+ visual="it",
+ },
+ [0x1D44A]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D44A,
+ visual="it",
+ },
+ [0x1D44B]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D44B,
+ visual="it",
+ },
+ [0x1D44C]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D44C,
+ visual="it",
+ },
+ [0x1D44D]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x005A },
+ unicodeslot=0x1D44D,
+ visual="it",
+ },
+ [0x1D44E]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D44E,
+ visual="it",
+ },
+ [0x1D44F]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D44F,
+ visual="it",
+ },
+ [0x1D450]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D450,
+ visual="it",
+ },
+ [0x1D451]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D451,
+ visual="it",
+ },
+ [0x1D452]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x1D452,
+ visual="it",
+ },
+ [0x1D453]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D453,
+ visual="it",
+ },
+ [0x1D454]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x1D454,
+ visual="it",
+ },
+ [0x1D456]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D456,
+ visual="it",
+ },
+ [0x1D457]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D457,
+ visual="it",
+ },
+ [0x1D458]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D458,
+ visual="it",
+ },
+ [0x1D459]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D459,
+ visual="it",
+ },
+ [0x1D45A]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D45A,
+ visual="it",
+ },
+ [0x1D45B]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D45B,
+ visual="it",
+ },
+ [0x1D45C]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x1D45C,
+ visual="it",
+ },
+ [0x1D45D]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D45D,
+ visual="it",
+ },
+ [0x1D45E]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D45E,
+ visual="it",
+ },
+ [0x1D45F]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D45F,
+ visual="it",
+ },
+ [0x1D460]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D460,
+ visual="it",
+ },
+ [0x1D461]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D461,
+ visual="it",
+ },
+ [0x1D462]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D462,
+ visual="it",
+ },
+ [0x1D463]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D463,
+ visual="it",
+ },
+ [0x1D464]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D464,
+ visual="it",
+ },
+ [0x1D465]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D465,
+ visual="it",
+ },
+ [0x1D466]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D466,
+ visual="it",
+ },
+ [0x1D467]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D467,
+ visual="it",
+ },
+ [0x1D468]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D468,
+ visual="bi",
+ },
+ [0x1D469]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x1D469,
+ visual="bi",
+ },
+ [0x1D46A]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x1D46A,
+ visual="bi",
+ },
+ [0x1D46B]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D46B,
+ visual="bi",
+ },
+ [0x1D46C]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x1D46C,
+ visual="bi",
+ },
+ [0x1D46D]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x1D46D,
+ visual="bi",
+ },
+ [0x1D46E]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D46E,
+ visual="bi",
+ },
+ [0x1D46F]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x1D46F,
+ visual="bi",
+ },
+ [0x1D470]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x1D470,
+ visual="bi",
+ },
+ [0x1D471]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D471,
+ visual="bi",
+ },
+ [0x1D472]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D472,
+ visual="bi",
+ },
+ [0x1D473]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x1D473,
+ visual="bi",
+ },
+ [0x1D474]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x1D474,
+ visual="bi",
+ },
+ [0x1D475]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004E },
+ unicodeslot=0x1D475,
+ visual="bi",
+ },
+ [0x1D476]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D476,
+ visual="bi",
+ },
+ [0x1D477]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x1D477,
+ visual="bi",
+ },
+ [0x1D478]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x1D478,
+ visual="bi",
+ },
+ [0x1D479]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x1D479,
+ visual="bi",
+ },
+ [0x1D47A]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D47A,
+ visual="bi",
+ },
+ [0x1D47B]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D47B,
+ visual="bi",
+ },
+ [0x1D47C]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D47C,
+ visual="bi",
+ },
+ [0x1D47D]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D47D,
+ visual="bi",
+ },
+ [0x1D47E]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D47E,
+ visual="bi",
+ },
+ [0x1D47F]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D47F,
+ visual="bi",
+ },
+ [0x1D480]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D480,
+ visual="bi",
+ },
+ [0x1D481]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x005A },
+ unicodeslot=0x1D481,
+ visual="bi",
+ },
+ [0x1D482]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D482,
+ visual="bi",
+ },
+ [0x1D483]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D483,
+ visual="bi",
+ },
+ [0x1D484]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D484,
+ visual="bi",
+ },
+ [0x1D485]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D485,
+ visual="bi",
+ },
+ [0x1D486]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x1D486,
+ visual="bi",
+ },
+ [0x1D487]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D487,
+ visual="bi",
+ },
+ [0x1D488]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x1D488,
+ visual="bi",
+ },
+ [0x1D489]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x1D489,
+ visual="bi",
+ },
+ [0x1D48A]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D48A,
+ visual="bi",
+ },
+ [0x1D48B]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D48B,
+ visual="bi",
+ },
+ [0x1D48C]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D48C,
+ visual="bi",
+ },
+ [0x1D48D]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D48D,
+ visual="bi",
+ },
+ [0x1D48E]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D48E,
+ visual="bi",
+ },
+ [0x1D48F]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D48F,
+ visual="bi",
+ },
+ [0x1D490]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x1D490,
+ visual="bi",
+ },
+ [0x1D491]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D491,
+ visual="bi",
+ },
+ [0x1D492]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D492,
+ visual="bi",
+ },
+ [0x1D493]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D493,
+ visual="bi",
+ },
+ [0x1D494]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D494,
+ visual="bi",
+ },
+ [0x1D495]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D495,
+ visual="bi",
+ },
+ [0x1D496]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D496,
+ visual="bi",
+ },
+ [0x1D497]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D497,
+ visual="bi",
+ },
+ [0x1D498]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D498,
+ visual="bi",
+ },
+ [0x1D499]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D499,
+ visual="bi",
+ },
+ [0x1D49A]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D49A,
+ visual="bi",
+ },
+ [0x1D49B]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D49B,
+ visual="bi",
+ },
+ [0x1D49C]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D49C,
+ },
+ [0x1D49E]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x1D49E,
+ },
+ [0x1D49F]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D49F,
+ },
+ [0x1D4A2]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D4A2,
+ },
+ [0x1D4A5]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D4A5,
+ },
+ [0x1D4A6]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D4A6,
+ },
+ [0x1D4A9]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004E },
+ unicodeslot=0x1D4A9,
+ },
+ [0x1D4AA]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D4AA,
+ },
+ [0x1D4AB]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x1D4AB,
+ },
+ [0x1D4AC]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x1D4AC,
+ },
+ [0x1D4AE]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D4AE,
+ },
+ [0x1D4AF]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D4AF,
+ },
+ [0x1D4B0]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D4B0,
+ },
+ [0x1D4B1]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D4B1,
+ },
+ [0x1D4B2]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D4B2,
+ },
+ [0x1D4B3]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D4B3,
+ },
+ [0x1D4B4]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D4B4,
+ },
+ [0x1D4B5]={
+ category="lu",
+ description="MATHEMATICAL SCRIPT CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x005A },
+ unicodeslot=0x1D4B5,
+ },
+ [0x1D4B6]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D4B6,
+ },
+ [0x1D4B7]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D4B7,
+ },
+ [0x1D4B8]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D4B8,
+ },
+ [0x1D4B9]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D4B9,
+ },
+ [0x1D4BB]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D4BB,
+ },
+ [0x1D4BD]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x1D4BD,
+ },
+ [0x1D4BE]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D4BE,
+ },
+ [0x1D4BF]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D4BF,
+ },
+ [0x1D4C0]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D4C0,
+ },
+ [0x1D4C1]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D4C1,
+ },
+ [0x1D4C2]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D4C2,
+ },
+ [0x1D4C3]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D4C3,
+ },
+ [0x1D4C5]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D4C5,
+ },
+ [0x1D4C6]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D4C6,
+ },
+ [0x1D4C7]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D4C7,
+ },
+ [0x1D4C8]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D4C8,
+ },
+ [0x1D4C9]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D4C9,
+ },
+ [0x1D4CA]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D4CA,
+ },
+ [0x1D4CB]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D4CB,
+ },
+ [0x1D4CC]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D4CC,
+ },
+ [0x1D4CD]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D4CD,
+ },
+ [0x1D4CE]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D4CE,
+ },
+ [0x1D4CF]={
+ category="ll",
+ description="MATHEMATICAL SCRIPT SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D4CF,
+ },
+ [0x1D4D0]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D4D0,
+ visual="bf",
+ },
+ [0x1D4D1]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x1D4D1,
+ visual="bf",
+ },
+ [0x1D4D2]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x1D4D2,
+ visual="bf",
+ },
+ [0x1D4D3]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D4D3,
+ visual="bf",
+ },
+ [0x1D4D4]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x1D4D4,
+ visual="bf",
+ },
+ [0x1D4D5]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x1D4D5,
+ visual="bf",
+ },
+ [0x1D4D6]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D4D6,
+ visual="bf",
+ },
+ [0x1D4D7]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x1D4D7,
+ visual="bf",
+ },
+ [0x1D4D8]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x1D4D8,
+ visual="bf",
+ },
+ [0x1D4D9]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D4D9,
+ visual="bf",
+ },
+ [0x1D4DA]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D4DA,
+ visual="bf",
+ },
+ [0x1D4DB]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x1D4DB,
+ visual="bf",
+ },
+ [0x1D4DC]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x1D4DC,
+ visual="bf",
+ },
+ [0x1D4DD]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004E },
+ unicodeslot=0x1D4DD,
+ visual="bf",
+ },
+ [0x1D4DE]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D4DE,
+ visual="bf",
+ },
+ [0x1D4DF]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x1D4DF,
+ visual="bf",
+ },
+ [0x1D4E0]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x1D4E0,
+ visual="bf",
+ },
+ [0x1D4E1]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x1D4E1,
+ visual="bf",
+ },
+ [0x1D4E2]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D4E2,
+ visual="bf",
+ },
+ [0x1D4E3]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D4E3,
+ visual="bf",
+ },
+ [0x1D4E4]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D4E4,
+ visual="bf",
+ },
+ [0x1D4E5]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D4E5,
+ visual="bf",
+ },
+ [0x1D4E6]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D4E6,
+ visual="bf",
+ },
+ [0x1D4E7]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D4E7,
+ visual="bf",
+ },
+ [0x1D4E8]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D4E8,
+ visual="bf",
+ },
+ [0x1D4E9]={
+ category="lu",
+ description="MATHEMATICAL BOLD SCRIPT CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x005A },
+ unicodeslot=0x1D4E9,
+ visual="bf",
+ },
+ [0x1D4EA]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D4EA,
+ visual="bf",
+ },
+ [0x1D4EB]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D4EB,
+ visual="bf",
+ },
+ [0x1D4EC]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D4EC,
+ visual="bf",
+ },
+ [0x1D4ED]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D4ED,
+ visual="bf",
+ },
+ [0x1D4EE]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x1D4EE,
+ visual="bf",
+ },
+ [0x1D4EF]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D4EF,
+ visual="bf",
+ },
+ [0x1D4F0]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x1D4F0,
+ visual="bf",
+ },
+ [0x1D4F1]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x1D4F1,
+ visual="bf",
+ },
+ [0x1D4F2]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D4F2,
+ visual="bf",
+ },
+ [0x1D4F3]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D4F3,
+ visual="bf",
+ },
+ [0x1D4F4]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D4F4,
+ visual="bf",
+ },
+ [0x1D4F5]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D4F5,
+ visual="bf",
+ },
+ [0x1D4F6]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D4F6,
+ visual="bf",
+ },
+ [0x1D4F7]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D4F7,
+ visual="bf",
+ },
+ [0x1D4F8]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x1D4F8,
+ visual="bf",
+ },
+ [0x1D4F9]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D4F9,
+ visual="bf",
+ },
+ [0x1D4FA]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D4FA,
+ visual="bf",
+ },
+ [0x1D4FB]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D4FB,
+ visual="bf",
+ },
+ [0x1D4FC]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D4FC,
+ visual="bf",
+ },
+ [0x1D4FD]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D4FD,
+ visual="bf",
+ },
+ [0x1D4FE]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D4FE,
+ visual="bf",
+ },
+ [0x1D4FF]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D4FF,
+ visual="bf",
+ },
+ [0x1D500]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D500,
+ visual="bf",
+ },
+ [0x1D501]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D501,
+ visual="bf",
+ },
+ [0x1D502]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D502,
+ visual="bf",
+ },
+ [0x1D503]={
+ category="ll",
+ description="MATHEMATICAL BOLD SCRIPT SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D503,
+ visual="bf",
+ },
+ [0x1D504]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D504,
+ },
+ [0x1D505]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x1D505,
+ },
+ [0x1D507]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D507,
+ },
+ [0x1D508]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x1D508,
+ },
+ [0x1D509]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x1D509,
+ },
+ [0x1D50A]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D50A,
+ },
+ [0x1D50D]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D50D,
+ },
+ [0x1D50E]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D50E,
+ },
+ [0x1D50F]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x1D50F,
+ },
+ [0x1D510]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x1D510,
+ },
+ [0x1D511]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004E },
+ unicodeslot=0x1D511,
+ },
+ [0x1D512]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D512,
+ },
+ [0x1D513]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x1D513,
+ },
+ [0x1D514]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x1D514,
+ },
+ [0x1D516]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D516,
+ },
+ [0x1D517]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D517,
+ },
+ [0x1D518]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D518,
+ },
+ [0x1D519]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D519,
+ },
+ [0x1D51A]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D51A,
+ },
+ [0x1D51B]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D51B,
+ },
+ [0x1D51C]={
+ category="lu",
+ description="MATHEMATICAL FRAKTUR CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D51C,
+ },
+ [0x1D51E]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D51E,
+ },
+ [0x1D51F]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D51F,
+ },
+ [0x1D520]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D520,
+ },
+ [0x1D521]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D521,
+ },
+ [0x1D522]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x1D522,
+ },
+ [0x1D523]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D523,
+ },
+ [0x1D524]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x1D524,
+ },
+ [0x1D525]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x1D525,
+ },
+ [0x1D526]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D526,
+ },
+ [0x1D527]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D527,
+ },
+ [0x1D528]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D528,
+ },
+ [0x1D529]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D529,
+ },
+ [0x1D52A]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D52A,
+ },
+ [0x1D52B]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D52B,
+ },
+ [0x1D52C]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x1D52C,
+ },
+ [0x1D52D]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D52D,
+ },
+ [0x1D52E]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D52E,
+ },
+ [0x1D52F]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D52F,
+ },
+ [0x1D530]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D530,
+ },
+ [0x1D531]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D531,
+ },
+ [0x1D532]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D532,
+ },
+ [0x1D533]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D533,
+ },
+ [0x1D534]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D534,
+ },
+ [0x1D535]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D535,
+ },
+ [0x1D536]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D536,
+ },
+ [0x1D537]={
+ category="ll",
+ description="MATHEMATICAL FRAKTUR SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D537,
+ },
+ [0x1D538]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D538,
+ },
+ [0x1D539]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x1D539,
+ },
+ [0x1D53B]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D53B,
+ },
+ [0x1D53C]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x1D53C,
+ },
+ [0x1D53D]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x1D53D,
+ },
+ [0x1D53E]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D53E,
+ },
+ [0x1D540]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x1D540,
+ },
+ [0x1D541]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D541,
+ },
+ [0x1D542]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D542,
+ },
+ [0x1D543]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x1D543,
+ },
+ [0x1D544]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x1D544,
+ },
+ [0x1D546]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D546,
+ },
+ [0x1D54A]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D54A,
+ },
+ [0x1D54B]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D54B,
+ },
+ [0x1D54C]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D54C,
+ },
+ [0x1D54D]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D54D,
+ },
+ [0x1D54E]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D54E,
+ },
+ [0x1D54F]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D54F,
+ },
+ [0x1D550]={
+ category="lu",
+ description="MATHEMATICAL DOUBLE-STRUCK CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D550,
+ },
+ [0x1D552]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D552,
+ },
+ [0x1D553]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D553,
+ },
+ [0x1D554]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D554,
+ },
+ [0x1D555]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D555,
+ },
+ [0x1D556]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x1D556,
+ },
+ [0x1D557]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D557,
+ },
+ [0x1D558]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x1D558,
+ },
+ [0x1D559]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x1D559,
+ },
+ [0x1D55A]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D55A,
+ },
+ [0x1D55B]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D55B,
+ },
+ [0x1D55C]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D55C,
+ },
+ [0x1D55D]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D55D,
+ },
+ [0x1D55E]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D55E,
+ },
+ [0x1D55F]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D55F,
+ },
+ [0x1D560]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x1D560,
+ },
+ [0x1D561]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D561,
+ },
+ [0x1D562]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D562,
+ },
+ [0x1D563]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D563,
+ },
+ [0x1D564]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D564,
+ },
+ [0x1D565]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D565,
+ },
+ [0x1D566]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D566,
+ },
+ [0x1D567]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D567,
+ },
+ [0x1D568]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D568,
+ },
+ [0x1D569]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D569,
+ },
+ [0x1D56A]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D56A,
+ },
+ [0x1D56B]={
+ category="ll",
+ description="MATHEMATICAL DOUBLE-STRUCK SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D56B,
+ },
+ [0x1D56C]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D56C,
+ visual="bf",
+ },
+ [0x1D56D]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x1D56D,
+ visual="bf",
+ },
+ [0x1D56E]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x1D56E,
+ visual="bf",
+ },
+ [0x1D56F]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D56F,
+ visual="bf",
+ },
+ [0x1D570]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x1D570,
+ visual="bf",
+ },
+ [0x1D571]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x1D571,
+ visual="bf",
+ },
+ [0x1D572]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D572,
+ visual="bf",
+ },
+ [0x1D573]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x1D573,
+ visual="bf",
+ },
+ [0x1D574]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x1D574,
+ visual="bf",
+ },
+ [0x1D575]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D575,
+ visual="bf",
+ },
+ [0x1D576]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D576,
+ visual="bf",
+ },
+ [0x1D577]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x1D577,
+ visual="bf",
+ },
+ [0x1D578]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x1D578,
+ visual="bf",
+ },
+ [0x1D579]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004E },
+ unicodeslot=0x1D579,
+ visual="bf",
+ },
+ [0x1D57A]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D57A,
+ visual="bf",
+ },
+ [0x1D57B]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x1D57B,
+ visual="bf",
+ },
+ [0x1D57C]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x1D57C,
+ visual="bf",
+ },
+ [0x1D57D]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x1D57D,
+ visual="bf",
+ },
+ [0x1D57E]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D57E,
+ visual="bf",
+ },
+ [0x1D57F]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D57F,
+ visual="bf",
+ },
+ [0x1D580]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D580,
+ visual="bf",
+ },
+ [0x1D581]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D581,
+ visual="bf",
+ },
+ [0x1D582]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D582,
+ visual="bf",
+ },
+ [0x1D583]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D583,
+ visual="bf",
+ },
+ [0x1D584]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D584,
+ visual="bf",
+ },
+ [0x1D585]={
+ category="lu",
+ description="MATHEMATICAL BOLD FRAKTUR CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x005A },
+ unicodeslot=0x1D585,
+ visual="bf",
+ },
+ [0x1D586]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D586,
+ visual="bf",
+ },
+ [0x1D587]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D587,
+ visual="bf",
+ },
+ [0x1D588]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D588,
+ visual="bf",
+ },
+ [0x1D589]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D589,
+ visual="bf",
+ },
+ [0x1D58A]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x1D58A,
+ visual="bf",
+ },
+ [0x1D58B]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D58B,
+ visual="bf",
+ },
+ [0x1D58C]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x1D58C,
+ visual="bf",
+ },
+ [0x1D58D]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x1D58D,
+ visual="bf",
+ },
+ [0x1D58E]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D58E,
+ visual="bf",
+ },
+ [0x1D58F]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D58F,
+ visual="bf",
+ },
+ [0x1D590]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D590,
+ visual="bf",
+ },
+ [0x1D591]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D591,
+ visual="bf",
+ },
+ [0x1D592]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D592,
+ visual="bf",
+ },
+ [0x1D593]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D593,
+ visual="bf",
+ },
+ [0x1D594]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x1D594,
+ visual="bf",
+ },
+ [0x1D595]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D595,
+ visual="bf",
+ },
+ [0x1D596]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D596,
+ visual="bf",
+ },
+ [0x1D597]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D597,
+ visual="bf",
+ },
+ [0x1D598]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D598,
+ visual="bf",
+ },
+ [0x1D599]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D599,
+ visual="bf",
+ },
+ [0x1D59A]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D59A,
+ visual="bf",
+ },
+ [0x1D59B]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D59B,
+ visual="bf",
+ },
+ [0x1D59C]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D59C,
+ visual="bf",
+ },
+ [0x1D59D]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D59D,
+ visual="bf",
+ },
+ [0x1D59E]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D59E,
+ visual="bf",
+ },
+ [0x1D59F]={
+ category="ll",
+ description="MATHEMATICAL BOLD FRAKTUR SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D59F,
+ visual="bf",
+ },
+ [0x1D5A0]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D5A0,
+ },
+ [0x1D5A1]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x1D5A1,
+ },
+ [0x1D5A2]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x1D5A2,
+ },
+ [0x1D5A3]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D5A3,
+ },
+ [0x1D5A4]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x1D5A4,
+ },
+ [0x1D5A5]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x1D5A5,
+ },
+ [0x1D5A6]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D5A6,
+ },
+ [0x1D5A7]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x1D5A7,
+ },
+ [0x1D5A8]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x1D5A8,
+ },
+ [0x1D5A9]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D5A9,
+ },
+ [0x1D5AA]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D5AA,
+ },
+ [0x1D5AB]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x1D5AB,
+ },
+ [0x1D5AC]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x1D5AC,
+ },
+ [0x1D5AD]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004E },
+ unicodeslot=0x1D5AD,
+ },
+ [0x1D5AE]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D5AE,
+ },
+ [0x1D5AF]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x1D5AF,
+ },
+ [0x1D5B0]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x1D5B0,
+ },
+ [0x1D5B1]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x1D5B1,
+ },
+ [0x1D5B2]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D5B2,
+ },
+ [0x1D5B3]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D5B3,
+ },
+ [0x1D5B4]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D5B4,
+ },
+ [0x1D5B5]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D5B5,
+ },
+ [0x1D5B6]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D5B6,
+ },
+ [0x1D5B7]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D5B7,
+ },
+ [0x1D5B8]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D5B8,
+ },
+ [0x1D5B9]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x005A },
+ unicodeslot=0x1D5B9,
+ },
+ [0x1D5BA]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D5BA,
+ },
+ [0x1D5BB]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D5BB,
+ },
+ [0x1D5BC]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D5BC,
+ },
+ [0x1D5BD]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D5BD,
+ },
+ [0x1D5BE]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x1D5BE,
+ },
+ [0x1D5BF]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D5BF,
+ },
+ [0x1D5C0]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x1D5C0,
+ },
+ [0x1D5C1]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x1D5C1,
+ },
+ [0x1D5C2]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D5C2,
+ },
+ [0x1D5C3]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D5C3,
+ },
+ [0x1D5C4]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D5C4,
+ },
+ [0x1D5C5]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D5C5,
+ },
+ [0x1D5C6]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D5C6,
+ },
+ [0x1D5C7]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D5C7,
+ },
+ [0x1D5C8]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x1D5C8,
+ },
+ [0x1D5C9]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D5C9,
+ },
+ [0x1D5CA]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D5CA,
+ },
+ [0x1D5CB]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D5CB,
+ },
+ [0x1D5CC]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D5CC,
+ },
+ [0x1D5CD]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D5CD,
+ },
+ [0x1D5CE]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D5CE,
+ },
+ [0x1D5CF]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D5CF,
+ },
+ [0x1D5D0]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D5D0,
+ },
+ [0x1D5D1]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D5D1,
+ },
+ [0x1D5D2]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D5D2,
+ },
+ [0x1D5D3]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D5D3,
+ },
+ [0x1D5D4]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D5D4,
+ visual="bf",
+ },
+ [0x1D5D5]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x1D5D5,
+ visual="bf",
+ },
+ [0x1D5D6]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x1D5D6,
+ visual="bf",
+ },
+ [0x1D5D7]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D5D7,
+ visual="bf",
+ },
+ [0x1D5D8]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x1D5D8,
+ visual="bf",
+ },
+ [0x1D5D9]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x1D5D9,
+ visual="bf",
+ },
+ [0x1D5DA]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D5DA,
+ visual="bf",
+ },
+ [0x1D5DB]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x1D5DB,
+ visual="bf",
+ },
+ [0x1D5DC]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x1D5DC,
+ visual="bf",
+ },
+ [0x1D5DD]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D5DD,
+ visual="bf",
+ },
+ [0x1D5DE]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D5DE,
+ visual="bf",
+ },
+ [0x1D5DF]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x1D5DF,
+ visual="bf",
+ },
+ [0x1D5E0]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x1D5E0,
+ visual="bf",
+ },
+ [0x1D5E1]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004E },
+ unicodeslot=0x1D5E1,
+ visual="bf",
+ },
+ [0x1D5E2]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D5E2,
+ visual="bf",
+ },
+ [0x1D5E3]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x1D5E3,
+ visual="bf",
+ },
+ [0x1D5E4]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x1D5E4,
+ visual="bf",
+ },
+ [0x1D5E5]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x1D5E5,
+ visual="bf",
+ },
+ [0x1D5E6]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D5E6,
+ visual="bf",
+ },
+ [0x1D5E7]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D5E7,
+ visual="bf",
+ },
+ [0x1D5E8]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D5E8,
+ visual="bf",
+ },
+ [0x1D5E9]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D5E9,
+ visual="bf",
+ },
+ [0x1D5EA]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D5EA,
+ visual="bf",
+ },
+ [0x1D5EB]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D5EB,
+ visual="bf",
+ },
+ [0x1D5EC]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D5EC,
+ visual="bf",
+ },
+ [0x1D5ED]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x005A },
+ unicodeslot=0x1D5ED,
+ visual="bf",
+ },
+ [0x1D5EE]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D5EE,
+ visual="bf",
+ },
+ [0x1D5EF]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D5EF,
+ visual="bf",
+ },
+ [0x1D5F0]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D5F0,
+ visual="bf",
+ },
+ [0x1D5F1]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D5F1,
+ visual="bf",
+ },
+ [0x1D5F2]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x1D5F2,
+ visual="bf",
+ },
+ [0x1D5F3]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D5F3,
+ visual="bf",
+ },
+ [0x1D5F4]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x1D5F4,
+ visual="bf",
+ },
+ [0x1D5F5]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x1D5F5,
+ visual="bf",
+ },
+ [0x1D5F6]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D5F6,
+ visual="bf",
+ },
+ [0x1D5F7]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D5F7,
+ visual="bf",
+ },
+ [0x1D5F8]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D5F8,
+ visual="bf",
+ },
+ [0x1D5F9]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D5F9,
+ visual="bf",
+ },
+ [0x1D5FA]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D5FA,
+ visual="bf",
+ },
+ [0x1D5FB]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D5FB,
+ visual="bf",
+ },
+ [0x1D5FC]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x1D5FC,
+ visual="bf",
+ },
+ [0x1D5FD]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D5FD,
+ visual="bf",
+ },
+ [0x1D5FE]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D5FE,
+ visual="bf",
+ },
+ [0x1D5FF]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D5FF,
+ visual="bf",
+ },
+ [0x1D600]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D600,
+ visual="bf",
+ },
+ [0x1D601]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D601,
+ visual="bf",
+ },
+ [0x1D602]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D602,
+ visual="bf",
+ },
+ [0x1D603]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D603,
+ visual="bf",
+ },
+ [0x1D604]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D604,
+ visual="bf",
+ },
+ [0x1D605]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D605,
+ visual="bf",
+ },
+ [0x1D606]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D606,
+ visual="bf",
+ },
+ [0x1D607]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D607,
+ visual="bf",
+ },
+ [0x1D608]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D608,
+ visual="it",
+ },
+ [0x1D609]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x1D609,
+ visual="it",
+ },
+ [0x1D60A]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x1D60A,
+ visual="it",
+ },
+ [0x1D60B]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D60B,
+ visual="it",
+ },
+ [0x1D60C]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x1D60C,
+ visual="it",
+ },
+ [0x1D60D]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x1D60D,
+ visual="it",
+ },
+ [0x1D60E]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D60E,
+ visual="it",
+ },
+ [0x1D60F]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x1D60F,
+ visual="it",
+ },
+ [0x1D610]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x1D610,
+ visual="it",
+ },
+ [0x1D611]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D611,
+ visual="it",
+ },
+ [0x1D612]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D612,
+ visual="it",
+ },
+ [0x1D613]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x1D613,
+ visual="it",
+ },
+ [0x1D614]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x1D614,
+ visual="it",
+ },
+ [0x1D615]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004E },
+ unicodeslot=0x1D615,
+ visual="it",
+ },
+ [0x1D616]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D616,
+ visual="it",
+ },
+ [0x1D617]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x1D617,
+ visual="it",
+ },
+ [0x1D618]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x1D618,
+ visual="it",
+ },
+ [0x1D619]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x1D619,
+ visual="it",
+ },
+ [0x1D61A]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D61A,
+ visual="it",
+ },
+ [0x1D61B]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D61B,
+ visual="it",
+ },
+ [0x1D61C]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D61C,
+ visual="it",
+ },
+ [0x1D61D]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D61D,
+ visual="it",
+ },
+ [0x1D61E]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D61E,
+ visual="it",
+ },
+ [0x1D61F]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D61F,
+ visual="it",
+ },
+ [0x1D620]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D620,
+ visual="it",
+ },
+ [0x1D621]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x005A },
+ unicodeslot=0x1D621,
+ visual="it",
+ },
+ [0x1D622]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D622,
+ visual="it",
+ },
+ [0x1D623]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D623,
+ visual="it",
+ },
+ [0x1D624]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D624,
+ visual="it",
+ },
+ [0x1D625]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D625,
+ visual="it",
+ },
+ [0x1D626]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x1D626,
+ visual="it",
+ },
+ [0x1D627]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D627,
+ visual="it",
+ },
+ [0x1D628]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x1D628,
+ visual="it",
+ },
+ [0x1D629]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x1D629,
+ visual="it",
+ },
+ [0x1D62A]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D62A,
+ visual="it",
+ },
+ [0x1D62B]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D62B,
+ visual="it",
+ },
+ [0x1D62C]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D62C,
+ visual="it",
+ },
+ [0x1D62D]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D62D,
+ visual="it",
+ },
+ [0x1D62E]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D62E,
+ visual="it",
+ },
+ [0x1D62F]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D62F,
+ visual="it",
+ },
+ [0x1D630]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x1D630,
+ visual="it",
+ },
+ [0x1D631]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D631,
+ visual="it",
+ },
+ [0x1D632]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D632,
+ visual="it",
+ },
+ [0x1D633]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D633,
+ visual="it",
+ },
+ [0x1D634]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D634,
+ visual="it",
+ },
+ [0x1D635]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D635,
+ visual="it",
+ },
+ [0x1D636]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D636,
+ visual="it",
+ },
+ [0x1D637]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D637,
+ visual="it",
+ },
+ [0x1D638]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D638,
+ visual="it",
+ },
+ [0x1D639]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D639,
+ visual="it",
+ },
+ [0x1D63A]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D63A,
+ visual="it",
+ },
+ [0x1D63B]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF ITALIC SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D63B,
+ visual="it",
+ },
+ [0x1D63C]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D63C,
+ visual="bi",
+ },
+ [0x1D63D]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x1D63D,
+ visual="bi",
+ },
+ [0x1D63E]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x1D63E,
+ visual="bi",
+ },
+ [0x1D63F]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D63F,
+ visual="bi",
+ },
+ [0x1D640]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x1D640,
+ visual="bi",
+ },
+ [0x1D641]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x1D641,
+ visual="bi",
+ },
+ [0x1D642]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D642,
+ visual="bi",
+ },
+ [0x1D643]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x1D643,
+ visual="bi",
+ },
+ [0x1D644]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x1D644,
+ visual="bi",
+ },
+ [0x1D645]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D645,
+ visual="bi",
+ },
+ [0x1D646]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D646,
+ visual="bi",
+ },
+ [0x1D647]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x1D647,
+ visual="bi",
+ },
+ [0x1D648]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x1D648,
+ visual="bi",
+ },
+ [0x1D649]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004E },
+ unicodeslot=0x1D649,
+ visual="bi",
+ },
+ [0x1D64A]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D64A,
+ visual="bi",
+ },
+ [0x1D64B]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x1D64B,
+ visual="bi",
+ },
+ [0x1D64C]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x1D64C,
+ visual="bi",
+ },
+ [0x1D64D]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x1D64D,
+ visual="bi",
+ },
+ [0x1D64E]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D64E,
+ visual="bi",
+ },
+ [0x1D64F]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D64F,
+ visual="bi",
+ },
+ [0x1D650]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D650,
+ visual="bi",
+ },
+ [0x1D651]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D651,
+ visual="bi",
+ },
+ [0x1D652]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D652,
+ visual="bi",
+ },
+ [0x1D653]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D653,
+ visual="bi",
+ },
+ [0x1D654]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D654,
+ visual="bi",
+ },
+ [0x1D655]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x005A },
+ unicodeslot=0x1D655,
+ visual="bi",
+ },
+ [0x1D656]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D656,
+ visual="bi",
+ },
+ [0x1D657]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D657,
+ visual="bi",
+ },
+ [0x1D658]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D658,
+ visual="bi",
+ },
+ [0x1D659]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D659,
+ visual="bi",
+ },
+ [0x1D65A]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x1D65A,
+ visual="bi",
+ },
+ [0x1D65B]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D65B,
+ visual="bi",
+ },
+ [0x1D65C]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x1D65C,
+ visual="bi",
+ },
+ [0x1D65D]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x1D65D,
+ visual="bi",
+ },
+ [0x1D65E]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D65E,
+ visual="bi",
+ },
+ [0x1D65F]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D65F,
+ visual="bi",
+ },
+ [0x1D660]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D660,
+ visual="bi",
+ },
+ [0x1D661]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D661,
+ visual="bi",
+ },
+ [0x1D662]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D662,
+ visual="bi",
+ },
+ [0x1D663]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D663,
+ visual="bi",
+ },
+ [0x1D664]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x1D664,
+ visual="bi",
+ },
+ [0x1D665]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D665,
+ visual="bi",
+ },
+ [0x1D666]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D666,
+ visual="bi",
+ },
+ [0x1D667]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D667,
+ visual="bi",
+ },
+ [0x1D668]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D668,
+ visual="bi",
+ },
+ [0x1D669]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D669,
+ visual="bi",
+ },
+ [0x1D66A]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D66A,
+ visual="bi",
+ },
+ [0x1D66B]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D66B,
+ visual="bi",
+ },
+ [0x1D66C]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D66C,
+ visual="bi",
+ },
+ [0x1D66D]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D66D,
+ visual="bi",
+ },
+ [0x1D66E]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D66E,
+ visual="bi",
+ },
+ [0x1D66F]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D66F,
+ visual="bi",
+ },
+ [0x1D670]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0041 },
+ unicodeslot=0x1D670,
+ },
+ [0x1D671]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0042 },
+ unicodeslot=0x1D671,
+ },
+ [0x1D672]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0043 },
+ unicodeslot=0x1D672,
+ },
+ [0x1D673]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0044 },
+ unicodeslot=0x1D673,
+ },
+ [0x1D674]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0045 },
+ unicodeslot=0x1D674,
+ },
+ [0x1D675]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0046 },
+ unicodeslot=0x1D675,
+ },
+ [0x1D676]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0047 },
+ unicodeslot=0x1D676,
+ },
+ [0x1D677]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0048 },
+ unicodeslot=0x1D677,
+ },
+ [0x1D678]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0049 },
+ unicodeslot=0x1D678,
+ },
+ [0x1D679]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004A },
+ unicodeslot=0x1D679,
+ },
+ [0x1D67A]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004B },
+ unicodeslot=0x1D67A,
+ },
+ [0x1D67B]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004C },
+ unicodeslot=0x1D67B,
+ },
+ [0x1D67C]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004D },
+ unicodeslot=0x1D67C,
+ },
+ [0x1D67D]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004E },
+ unicodeslot=0x1D67D,
+ },
+ [0x1D67E]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x004F },
+ unicodeslot=0x1D67E,
+ },
+ [0x1D67F]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0050 },
+ unicodeslot=0x1D67F,
+ },
+ [0x1D680]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0051 },
+ unicodeslot=0x1D680,
+ },
+ [0x1D681]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0052 },
+ unicodeslot=0x1D681,
+ },
+ [0x1D682]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0053 },
+ unicodeslot=0x1D682,
+ },
+ [0x1D683]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0054 },
+ unicodeslot=0x1D683,
+ },
+ [0x1D684]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0055 },
+ unicodeslot=0x1D684,
+ },
+ [0x1D685]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0056 },
+ unicodeslot=0x1D685,
+ },
+ [0x1D686]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0057 },
+ unicodeslot=0x1D686,
+ },
+ [0x1D687]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0058 },
+ unicodeslot=0x1D687,
+ },
+ [0x1D688]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0059 },
+ unicodeslot=0x1D688,
+ },
+ [0x1D689]={
+ category="lu",
+ description="MATHEMATICAL MONOSPACE CAPITAL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x005A },
+ unicodeslot=0x1D689,
+ },
+ [0x1D68A]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL A",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0061 },
+ unicodeslot=0x1D68A,
+ },
+ [0x1D68B]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL B",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0062 },
+ unicodeslot=0x1D68B,
+ },
+ [0x1D68C]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL C",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0063 },
+ unicodeslot=0x1D68C,
+ },
+ [0x1D68D]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL D",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0064 },
+ unicodeslot=0x1D68D,
+ },
+ [0x1D68E]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL E",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0065 },
+ unicodeslot=0x1D68E,
+ },
+ [0x1D68F]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL F",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0066 },
+ unicodeslot=0x1D68F,
+ },
+ [0x1D690]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL G",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0067 },
+ unicodeslot=0x1D690,
+ },
+ [0x1D691]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL H",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0068 },
+ unicodeslot=0x1D691,
+ },
+ [0x1D692]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL I",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0069 },
+ unicodeslot=0x1D692,
+ },
+ [0x1D693]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL J",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006A },
+ unicodeslot=0x1D693,
+ },
+ [0x1D694]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL K",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006B },
+ unicodeslot=0x1D694,
+ },
+ [0x1D695]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL L",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006C },
+ unicodeslot=0x1D695,
+ },
+ [0x1D696]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL M",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006D },
+ unicodeslot=0x1D696,
+ },
+ [0x1D697]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL N",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006E },
+ unicodeslot=0x1D697,
+ },
+ [0x1D698]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL O",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x006F },
+ unicodeslot=0x1D698,
+ },
+ [0x1D699]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL P",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0070 },
+ unicodeslot=0x1D699,
+ },
+ [0x1D69A]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL Q",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0071 },
+ unicodeslot=0x1D69A,
+ },
+ [0x1D69B]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL R",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0072 },
+ unicodeslot=0x1D69B,
+ },
+ [0x1D69C]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL S",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0073 },
+ unicodeslot=0x1D69C,
+ },
+ [0x1D69D]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL T",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0074 },
+ unicodeslot=0x1D69D,
+ },
+ [0x1D69E]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL U",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0075 },
+ unicodeslot=0x1D69E,
+ },
+ [0x1D69F]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL V",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0076 },
+ unicodeslot=0x1D69F,
+ },
+ [0x1D6A0]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL W",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0077 },
+ unicodeslot=0x1D6A0,
+ },
+ [0x1D6A1]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL X",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0078 },
+ unicodeslot=0x1D6A1,
+ },
+ [0x1D6A2]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL Y",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0079 },
+ unicodeslot=0x1D6A2,
+ },
+ [0x1D6A3]={
+ category="ll",
+ description="MATHEMATICAL MONOSPACE SMALL Z",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x007A },
+ unicodeslot=0x1D6A3,
+ },
+ [0x1D6A4]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL DOTLESS I",
+ direction="l",
+ linebreak="al",
+ mathclass="default",
+ mathname="imath",
+ specials={ "font", 0x0131 },
+ unicodeslot=0x1D6A4,
+ visual="it",
+ },
+ [0x1D6A5]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL DOTLESS J",
+ direction="l",
+ linebreak="al",
+ mathclass="default",
+ mathname="jmath",
+ specials={ "font", 0x0237 },
+ unicodeslot=0x1D6A5,
+ visual="it",
+ },
+ [0x1D6A8]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL ALPHA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0391 },
+ unicodeslot=0x1D6A8,
+ visual="bf",
+ },
+ [0x1D6A9]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL BETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0392 },
+ unicodeslot=0x1D6A9,
+ visual="bf",
+ },
+ [0x1D6AA]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0393 },
+ unicodeslot=0x1D6AA,
+ visual="bf",
+ },
+ [0x1D6AB]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL DELTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0394 },
+ unicodeslot=0x1D6AB,
+ visual="bf",
+ },
+ [0x1D6AC]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL EPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0395 },
+ unicodeslot=0x1D6AC,
+ visual="bf",
+ },
+ [0x1D6AD]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL ZETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0396 },
+ unicodeslot=0x1D6AD,
+ visual="bf",
+ },
+ [0x1D6AE]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL ETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0397 },
+ unicodeslot=0x1D6AE,
+ visual="bf",
+ },
+ [0x1D6AF]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL THETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0398 },
+ unicodeslot=0x1D6AF,
+ visual="bf",
+ },
+ [0x1D6B0]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL IOTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0399 },
+ unicodeslot=0x1D6B0,
+ visual="bf",
+ },
+ [0x1D6B1]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL KAPPA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039A },
+ unicodeslot=0x1D6B1,
+ visual="bf",
+ },
+ [0x1D6B2]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL LAMDA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039B },
+ unicodeslot=0x1D6B2,
+ visual="bf",
+ },
+ [0x1D6B3]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL MU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039C },
+ unicodeslot=0x1D6B3,
+ visual="bf",
+ },
+ [0x1D6B4]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL NU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039D },
+ unicodeslot=0x1D6B4,
+ visual="bf",
+ },
+ [0x1D6B5]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL XI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039E },
+ unicodeslot=0x1D6B5,
+ visual="bf",
+ },
+ [0x1D6B6]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL OMICRON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039F },
+ unicodeslot=0x1D6B6,
+ visual="bf",
+ },
+ [0x1D6B7]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL PI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A0 },
+ unicodeslot=0x1D6B7,
+ visual="bf",
+ },
+ [0x1D6B8]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL RHO",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A1 },
+ unicodeslot=0x1D6B8,
+ visual="bf",
+ },
+ [0x1D6B9]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL THETA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F4 },
+ unicodeslot=0x1D6B9,
+ visual="bf",
+ },
+ [0x1D6BA]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A3 },
+ unicodeslot=0x1D6BA,
+ visual="bf",
+ },
+ [0x1D6BB]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL TAU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A4 },
+ unicodeslot=0x1D6BB,
+ visual="bf",
+ },
+ [0x1D6BC]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL UPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A5 },
+ unicodeslot=0x1D6BC,
+ visual="bf",
+ },
+ [0x1D6BD]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A6 },
+ unicodeslot=0x1D6BD,
+ visual="bf",
+ },
+ [0x1D6BE]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL CHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A7 },
+ unicodeslot=0x1D6BE,
+ visual="bf",
+ },
+ [0x1D6BF]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL PSI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A8 },
+ unicodeslot=0x1D6BF,
+ visual="bf",
+ },
+ [0x1D6C0]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL OMEGA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A9 },
+ unicodeslot=0x1D6C0,
+ visual="bf",
+ },
+ [0x1D6C1]={
+ category="sm",
+ description="MATHEMATICAL BOLD NABLA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x2207 },
+ unicodeslot=0x1D6C1,
+ visual="bf",
+ },
+ [0x1D6C2]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL ALPHA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B1 },
+ unicodeslot=0x1D6C2,
+ visual="bf",
+ },
+ [0x1D6C3]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL BETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B2 },
+ unicodeslot=0x1D6C3,
+ visual="bf",
+ },
+ [0x1D6C4]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B3 },
+ unicodeslot=0x1D6C4,
+ visual="bf",
+ },
+ [0x1D6C5]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL DELTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B4 },
+ unicodeslot=0x1D6C5,
+ visual="bf",
+ },
+ [0x1D6C6]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL EPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B5 },
+ unicodeslot=0x1D6C6,
+ visual="bf",
+ },
+ [0x1D6C7]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL ZETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B6 },
+ unicodeslot=0x1D6C7,
+ visual="bf",
+ },
+ [0x1D6C8]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL ETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B7 },
+ unicodeslot=0x1D6C8,
+ visual="bf",
+ },
+ [0x1D6C9]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL THETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B8 },
+ unicodeslot=0x1D6C9,
+ visual="bf",
+ },
+ [0x1D6CA]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL IOTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B9 },
+ unicodeslot=0x1D6CA,
+ visual="bf",
+ },
+ [0x1D6CB]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL KAPPA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BA },
+ unicodeslot=0x1D6CB,
+ visual="bf",
+ },
+ [0x1D6CC]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL LAMDA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BB },
+ unicodeslot=0x1D6CC,
+ visual="bf",
+ },
+ [0x1D6CD]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL MU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BC },
+ unicodeslot=0x1D6CD,
+ visual="bf",
+ },
+ [0x1D6CE]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL NU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BD },
+ unicodeslot=0x1D6CE,
+ visual="bf",
+ },
+ [0x1D6CF]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL XI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BE },
+ unicodeslot=0x1D6CF,
+ visual="bf",
+ },
+ [0x1D6D0]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL OMICRON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BF },
+ unicodeslot=0x1D6D0,
+ visual="bf",
+ },
+ [0x1D6D1]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL PI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C0 },
+ unicodeslot=0x1D6D1,
+ visual="bf",
+ },
+ [0x1D6D2]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL RHO",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C1 },
+ unicodeslot=0x1D6D2,
+ visual="bf",
+ },
+ [0x1D6D3]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL FINAL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C2 },
+ unicodeslot=0x1D6D3,
+ visual="bf",
+ },
+ [0x1D6D4]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C3 },
+ unicodeslot=0x1D6D4,
+ visual="bf",
+ },
+ [0x1D6D5]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL TAU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C4 },
+ unicodeslot=0x1D6D5,
+ visual="bf",
+ },
+ [0x1D6D6]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL UPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C5 },
+ unicodeslot=0x1D6D6,
+ visual="bf",
+ },
+ [0x1D6D7]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C6 },
+ unicodeslot=0x1D6D7,
+ visual="bf",
+ },
+ [0x1D6D8]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL CHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C7 },
+ unicodeslot=0x1D6D8,
+ visual="bf",
+ },
+ [0x1D6D9]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL PSI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C8 },
+ unicodeslot=0x1D6D9,
+ visual="bf",
+ },
+ [0x1D6DA]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL OMEGA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C9 },
+ unicodeslot=0x1D6DA,
+ visual="bf",
+ },
+ [0x1D6DB]={
+ category="sm",
+ description="MATHEMATICAL BOLD PARTIAL DIFFERENTIAL",
+ direction="on",
+ linebreak="al",
+ specials={ "font", 0x2202 },
+ unicodeslot=0x1D6DB,
+ visual="bf",
+ },
+ [0x1D6DC]={
+ category="ll",
+ description="MATHEMATICAL BOLD EPSILON SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F5 },
+ unicodeslot=0x1D6DC,
+ visual="bf",
+ },
+ [0x1D6DD]={
+ category="ll",
+ description="MATHEMATICAL BOLD THETA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D1 },
+ unicodeslot=0x1D6DD,
+ visual="bf",
+ },
+ [0x1D6DE]={
+ category="ll",
+ description="MATHEMATICAL BOLD KAPPA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F0 },
+ unicodeslot=0x1D6DE,
+ visual="bf",
+ },
+ [0x1D6DF]={
+ category="ll",
+ description="MATHEMATICAL BOLD PHI SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D5 },
+ unicodeslot=0x1D6DF,
+ visual="bf",
+ },
+ [0x1D6E0]={
+ category="ll",
+ description="MATHEMATICAL BOLD RHO SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F1 },
+ unicodeslot=0x1D6E0,
+ visual="bf",
+ },
+ [0x1D6E1]={
+ category="ll",
+ description="MATHEMATICAL BOLD PI SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D6 },
+ unicodeslot=0x1D6E1,
+ visual="bf",
+ },
+ [0x1D6E2]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL ALPHA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0391 },
+ unicodeslot=0x1D6E2,
+ visual="it",
+ },
+ [0x1D6E3]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL BETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0392 },
+ unicodeslot=0x1D6E3,
+ visual="it",
+ },
+ [0x1D6E4]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0393 },
+ unicodeslot=0x1D6E4,
+ visual="it",
+ },
+ [0x1D6E5]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL DELTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0394 },
+ unicodeslot=0x1D6E5,
+ visual="it",
+ },
+ [0x1D6E6]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL EPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0395 },
+ unicodeslot=0x1D6E6,
+ visual="it",
+ },
+ [0x1D6E7]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL ZETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0396 },
+ unicodeslot=0x1D6E7,
+ visual="it",
+ },
+ [0x1D6E8]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL ETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0397 },
+ unicodeslot=0x1D6E8,
+ visual="it",
+ },
+ [0x1D6E9]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL THETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0398 },
+ unicodeslot=0x1D6E9,
+ visual="it",
+ },
+ [0x1D6EA]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL IOTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0399 },
+ unicodeslot=0x1D6EA,
+ visual="it",
+ },
+ [0x1D6EB]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL KAPPA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039A },
+ unicodeslot=0x1D6EB,
+ visual="it",
+ },
+ [0x1D6EC]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL LAMDA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039B },
+ unicodeslot=0x1D6EC,
+ visual="it",
+ },
+ [0x1D6ED]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL MU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039C },
+ unicodeslot=0x1D6ED,
+ visual="it",
+ },
+ [0x1D6EE]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL NU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039D },
+ unicodeslot=0x1D6EE,
+ visual="it",
+ },
+ [0x1D6EF]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL XI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039E },
+ unicodeslot=0x1D6EF,
+ visual="it",
+ },
+ [0x1D6F0]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL OMICRON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039F },
+ unicodeslot=0x1D6F0,
+ visual="it",
+ },
+ [0x1D6F1]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL PI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A0 },
+ unicodeslot=0x1D6F1,
+ visual="it",
+ },
+ [0x1D6F2]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL RHO",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A1 },
+ unicodeslot=0x1D6F2,
+ visual="it",
+ },
+ [0x1D6F3]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL THETA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F4 },
+ unicodeslot=0x1D6F3,
+ visual="it",
+ },
+ [0x1D6F4]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A3 },
+ unicodeslot=0x1D6F4,
+ visual="it",
+ },
+ [0x1D6F5]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL TAU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A4 },
+ unicodeslot=0x1D6F5,
+ visual="it",
+ },
+ [0x1D6F6]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL UPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A5 },
+ unicodeslot=0x1D6F6,
+ visual="it",
+ },
+ [0x1D6F7]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A6 },
+ unicodeslot=0x1D6F7,
+ visual="it",
+ },
+ [0x1D6F8]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL CHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A7 },
+ unicodeslot=0x1D6F8,
+ visual="it",
+ },
+ [0x1D6F9]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL PSI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A8 },
+ unicodeslot=0x1D6F9,
+ visual="it",
+ },
+ [0x1D6FA]={
+ category="lu",
+ description="MATHEMATICAL ITALIC CAPITAL OMEGA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A9 },
+ unicodeslot=0x1D6FA,
+ visual="it",
+ },
+ [0x1D6FB]={
+ category="sm",
+ description="MATHEMATICAL ITALIC NABLA",
+ direction="l",
+ linebreak="al",
+ mathclass="default",
+ specials={ "font", 0x2207 },
+ unicodeslot=0x1D6FB,
+ visual="it",
+ },
+ [0x1D6FC]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL ALPHA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B1 },
+ unicodeslot=0x1D6FC,
+ visual="it",
+ },
+ [0x1D6FD]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL BETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B2 },
+ unicodeslot=0x1D6FD,
+ visual="it",
+ },
+ [0x1D6FE]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B3 },
+ unicodeslot=0x1D6FE,
+ visual="it",
+ },
+ [0x1D6FF]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL DELTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B4 },
+ unicodeslot=0x1D6FF,
+ visual="it",
+ },
+ [0x1D700]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL EPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B5 },
+ unicodeslot=0x1D700,
+ visual="it",
+ },
+ [0x1D701]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL ZETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B6 },
+ unicodeslot=0x1D701,
+ visual="it",
+ },
+ [0x1D702]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL ETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B7 },
+ unicodeslot=0x1D702,
+ visual="it",
+ },
+ [0x1D703]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL THETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B8 },
+ unicodeslot=0x1D703,
+ visual="it",
+ },
+ [0x1D704]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL IOTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B9 },
+ unicodeslot=0x1D704,
+ visual="it",
+ },
+ [0x1D705]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL KAPPA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BA },
+ unicodeslot=0x1D705,
+ visual="it",
+ },
+ [0x1D706]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL LAMDA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BB },
+ unicodeslot=0x1D706,
+ visual="it",
+ },
+ [0x1D707]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL MU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BC },
+ unicodeslot=0x1D707,
+ visual="it",
+ },
+ [0x1D708]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL NU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BD },
+ unicodeslot=0x1D708,
+ visual="it",
+ },
+ [0x1D709]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL XI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BE },
+ unicodeslot=0x1D709,
+ visual="it",
+ },
+ [0x1D70A]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL OMICRON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BF },
+ unicodeslot=0x1D70A,
+ visual="it",
+ },
+ [0x1D70B]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL PI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C0 },
+ unicodeslot=0x1D70B,
+ visual="it",
+ },
+ [0x1D70C]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL RHO",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C1 },
+ unicodeslot=0x1D70C,
+ visual="it",
+ },
+ [0x1D70D]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL FINAL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C2 },
+ unicodeslot=0x1D70D,
+ visual="it",
+ },
+ [0x1D70E]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C3 },
+ unicodeslot=0x1D70E,
+ visual="it",
+ },
+ [0x1D70F]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL TAU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C4 },
+ unicodeslot=0x1D70F,
+ visual="it",
+ },
+ [0x1D710]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL UPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C5 },
+ unicodeslot=0x1D710,
+ visual="it",
+ },
+ [0x1D711]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C6 },
+ unicodeslot=0x1D711,
+ visual="it",
+ },
+ [0x1D712]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL CHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C7 },
+ unicodeslot=0x1D712,
+ visual="it",
+ },
+ [0x1D713]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL PSI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C8 },
+ unicodeslot=0x1D713,
+ visual="it",
+ },
+ [0x1D714]={
+ category="ll",
+ description="MATHEMATICAL ITALIC SMALL OMEGA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C9 },
+ unicodeslot=0x1D714,
+ visual="it",
+ },
+ [0x1D715]={
+ category="sm",
+ description="MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL",
+ direction="on",
+ linebreak="al",
+ specials={ "font", 0x2202 },
+ unicodeslot=0x1D715,
+ visual="it",
+ },
+ [0x1D716]={
+ category="ll",
+ description="MATHEMATICAL ITALIC EPSILON SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F5 },
+ unicodeslot=0x1D716,
+ visual="it",
+ },
+ [0x1D717]={
+ category="ll",
+ description="MATHEMATICAL ITALIC THETA SYMBOL",
+ direction="l",
+ linebreak="al",
+ mathclass="default",
+ mathname="vartheta",
+ specials={ "font", 0x03D1 },
+ unicodeslot=0x1D717,
+ visual="it",
+ },
+ [0x1D718]={
+ category="ll",
+ description="MATHEMATICAL ITALIC KAPPA SYMBOL",
+ direction="l",
+ linebreak="al",
+ mathclass="default",
+ mathname="varkappa",
+ specials={ "font", 0x03F0 },
+ unicodeslot=0x1D718,
+ visual="it",
+ },
+ [0x1D719]={
+ category="ll",
+ description="MATHEMATICAL ITALIC PHI SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D5 },
+ unicodeslot=0x1D719,
+ visual="it",
+ },
+ [0x1D71A]={
+ category="ll",
+ description="MATHEMATICAL ITALIC RHO SYMBOL",
+ direction="l",
+ linebreak="al",
+ mathclass="variable",
+ mathname="varrho",
+ specials={ "font", 0x03F1 },
+ unicodeslot=0x1D71A,
+ visual="it",
+ },
+ [0x1D71B]={
+ category="ll",
+ description="MATHEMATICAL ITALIC PI SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D6 },
+ unicodeslot=0x1D71B,
+ visual="it",
+ },
+ [0x1D71C]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL ALPHA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0391 },
+ unicodeslot=0x1D71C,
+ visual="bi",
+ },
+ [0x1D71D]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL BETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0392 },
+ unicodeslot=0x1D71D,
+ visual="bi",
+ },
+ [0x1D71E]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0393 },
+ unicodeslot=0x1D71E,
+ visual="bi",
+ },
+ [0x1D71F]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL DELTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0394 },
+ unicodeslot=0x1D71F,
+ visual="bi",
+ },
+ [0x1D720]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL EPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0395 },
+ unicodeslot=0x1D720,
+ visual="bi",
+ },
+ [0x1D721]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL ZETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0396 },
+ unicodeslot=0x1D721,
+ visual="bi",
+ },
+ [0x1D722]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL ETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0397 },
+ unicodeslot=0x1D722,
+ visual="bi",
+ },
+ [0x1D723]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL THETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0398 },
+ unicodeslot=0x1D723,
+ visual="bi",
+ },
+ [0x1D724]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL IOTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0399 },
+ unicodeslot=0x1D724,
+ visual="bi",
+ },
+ [0x1D725]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL KAPPA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039A },
+ unicodeslot=0x1D725,
+ visual="bi",
+ },
+ [0x1D726]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL LAMDA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039B },
+ unicodeslot=0x1D726,
+ visual="bi",
+ },
+ [0x1D727]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL MU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039C },
+ unicodeslot=0x1D727,
+ visual="bi",
+ },
+ [0x1D728]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL NU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039D },
+ unicodeslot=0x1D728,
+ visual="bi",
+ },
+ [0x1D729]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL XI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039E },
+ unicodeslot=0x1D729,
+ visual="bi",
+ },
+ [0x1D72A]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL OMICRON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039F },
+ unicodeslot=0x1D72A,
+ visual="bi",
+ },
+ [0x1D72B]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL PI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A0 },
+ unicodeslot=0x1D72B,
+ visual="bi",
+ },
+ [0x1D72C]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL RHO",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A1 },
+ unicodeslot=0x1D72C,
+ visual="bi",
+ },
+ [0x1D72D]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F4 },
+ unicodeslot=0x1D72D,
+ visual="bi",
+ },
+ [0x1D72E]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A3 },
+ unicodeslot=0x1D72E,
+ visual="bi",
+ },
+ [0x1D72F]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL TAU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A4 },
+ unicodeslot=0x1D72F,
+ visual="bi",
+ },
+ [0x1D730]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL UPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A5 },
+ unicodeslot=0x1D730,
+ visual="bi",
+ },
+ [0x1D731]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A6 },
+ unicodeslot=0x1D731,
+ visual="bi",
+ },
+ [0x1D732]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL CHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A7 },
+ unicodeslot=0x1D732,
+ visual="bi",
+ },
+ [0x1D733]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL PSI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A8 },
+ unicodeslot=0x1D733,
+ visual="bi",
+ },
+ [0x1D734]={
+ category="lu",
+ description="MATHEMATICAL BOLD ITALIC CAPITAL OMEGA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A9 },
+ unicodeslot=0x1D734,
+ visual="bi",
+ },
+ [0x1D735]={
+ category="sm",
+ description="MATHEMATICAL BOLD ITALIC NABLA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x2207 },
+ unicodeslot=0x1D735,
+ visual="bi",
+ },
+ [0x1D736]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL ALPHA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B1 },
+ unicodeslot=0x1D736,
+ visual="bi",
+ },
+ [0x1D737]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL BETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B2 },
+ unicodeslot=0x1D737,
+ visual="bi",
+ },
+ [0x1D738]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B3 },
+ unicodeslot=0x1D738,
+ visual="bi",
+ },
+ [0x1D739]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL DELTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B4 },
+ unicodeslot=0x1D739,
+ visual="bi",
+ },
+ [0x1D73A]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL EPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B5 },
+ unicodeslot=0x1D73A,
+ visual="bi",
+ },
+ [0x1D73B]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL ZETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B6 },
+ unicodeslot=0x1D73B,
+ visual="bi",
+ },
+ [0x1D73C]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL ETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B7 },
+ unicodeslot=0x1D73C,
+ visual="bi",
+ },
+ [0x1D73D]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL THETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B8 },
+ unicodeslot=0x1D73D,
+ visual="bi",
+ },
+ [0x1D73E]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL IOTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B9 },
+ unicodeslot=0x1D73E,
+ visual="bi",
+ },
+ [0x1D73F]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL KAPPA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BA },
+ unicodeslot=0x1D73F,
+ visual="bi",
+ },
+ [0x1D740]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL LAMDA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BB },
+ unicodeslot=0x1D740,
+ visual="bi",
+ },
+ [0x1D741]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL MU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BC },
+ unicodeslot=0x1D741,
+ visual="bi",
+ },
+ [0x1D742]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL NU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BD },
+ unicodeslot=0x1D742,
+ visual="bi",
+ },
+ [0x1D743]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL XI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BE },
+ unicodeslot=0x1D743,
+ visual="bi",
+ },
+ [0x1D744]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL OMICRON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BF },
+ unicodeslot=0x1D744,
+ visual="bi",
+ },
+ [0x1D745]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL PI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C0 },
+ unicodeslot=0x1D745,
+ visual="bi",
+ },
+ [0x1D746]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL RHO",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C1 },
+ unicodeslot=0x1D746,
+ visual="bi",
+ },
+ [0x1D747]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C2 },
+ unicodeslot=0x1D747,
+ visual="bi",
+ },
+ [0x1D748]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C3 },
+ unicodeslot=0x1D748,
+ visual="bi",
+ },
+ [0x1D749]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL TAU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C4 },
+ unicodeslot=0x1D749,
+ visual="bi",
+ },
+ [0x1D74A]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL UPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C5 },
+ unicodeslot=0x1D74A,
+ visual="bi",
+ },
+ [0x1D74B]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C6 },
+ unicodeslot=0x1D74B,
+ visual="bi",
+ },
+ [0x1D74C]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL CHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C7 },
+ unicodeslot=0x1D74C,
+ visual="bi",
+ },
+ [0x1D74D]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL PSI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C8 },
+ unicodeslot=0x1D74D,
+ visual="bi",
+ },
+ [0x1D74E]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC SMALL OMEGA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C9 },
+ unicodeslot=0x1D74E,
+ visual="bi",
+ },
+ [0x1D74F]={
+ category="sm",
+ description="MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL",
+ direction="on",
+ linebreak="al",
+ specials={ "font", 0x2202 },
+ unicodeslot=0x1D74F,
+ visual="bi",
+ },
+ [0x1D750]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC EPSILON SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F5 },
+ unicodeslot=0x1D750,
+ visual="bi",
+ },
+ [0x1D751]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC THETA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D1 },
+ unicodeslot=0x1D751,
+ visual="bi",
+ },
+ [0x1D752]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC KAPPA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F0 },
+ unicodeslot=0x1D752,
+ visual="bi",
+ },
+ [0x1D753]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC PHI SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D5 },
+ unicodeslot=0x1D753,
+ visual="bi",
+ },
+ [0x1D754]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC RHO SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F1 },
+ unicodeslot=0x1D754,
+ visual="bi",
+ },
+ [0x1D755]={
+ category="ll",
+ description="MATHEMATICAL BOLD ITALIC PI SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D6 },
+ unicodeslot=0x1D755,
+ visual="bi",
+ },
+ [0x1D756]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0391 },
+ unicodeslot=0x1D756,
+ visual="bf",
+ },
+ [0x1D757]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0392 },
+ unicodeslot=0x1D757,
+ visual="bf",
+ },
+ [0x1D758]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0393 },
+ unicodeslot=0x1D758,
+ visual="bf",
+ },
+ [0x1D759]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0394 },
+ unicodeslot=0x1D759,
+ visual="bf",
+ },
+ [0x1D75A]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0395 },
+ unicodeslot=0x1D75A,
+ visual="bf",
+ },
+ [0x1D75B]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0396 },
+ unicodeslot=0x1D75B,
+ visual="bf",
+ },
+ [0x1D75C]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0397 },
+ unicodeslot=0x1D75C,
+ visual="bf",
+ },
+ [0x1D75D]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0398 },
+ unicodeslot=0x1D75D,
+ visual="bf",
+ },
+ [0x1D75E]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0399 },
+ unicodeslot=0x1D75E,
+ visual="bf",
+ },
+ [0x1D75F]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039A },
+ unicodeslot=0x1D75F,
+ visual="bf",
+ },
+ [0x1D760]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039B },
+ unicodeslot=0x1D760,
+ visual="bf",
+ },
+ [0x1D761]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL MU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039C },
+ unicodeslot=0x1D761,
+ visual="bf",
+ },
+ [0x1D762]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL NU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039D },
+ unicodeslot=0x1D762,
+ visual="bf",
+ },
+ [0x1D763]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL XI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039E },
+ unicodeslot=0x1D763,
+ visual="bf",
+ },
+ [0x1D764]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039F },
+ unicodeslot=0x1D764,
+ visual="bf",
+ },
+ [0x1D765]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL PI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A0 },
+ unicodeslot=0x1D765,
+ visual="bf",
+ },
+ [0x1D766]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A1 },
+ unicodeslot=0x1D766,
+ visual="bf",
+ },
+ [0x1D767]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F4 },
+ unicodeslot=0x1D767,
+ visual="bf",
+ },
+ [0x1D768]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A3 },
+ unicodeslot=0x1D768,
+ visual="bf",
+ },
+ [0x1D769]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A4 },
+ unicodeslot=0x1D769,
+ visual="bf",
+ },
+ [0x1D76A]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A5 },
+ unicodeslot=0x1D76A,
+ visual="bf",
+ },
+ [0x1D76B]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A6 },
+ unicodeslot=0x1D76B,
+ visual="bf",
+ },
+ [0x1D76C]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A7 },
+ unicodeslot=0x1D76C,
+ visual="bf",
+ },
+ [0x1D76D]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A8 },
+ unicodeslot=0x1D76D,
+ visual="bf",
+ },
+ [0x1D76E]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A9 },
+ unicodeslot=0x1D76E,
+ visual="bf",
+ },
+ [0x1D76F]={
+ category="sm",
+ description="MATHEMATICAL SANS-SERIF BOLD NABLA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x2207 },
+ unicodeslot=0x1D76F,
+ visual="bf",
+ },
+ [0x1D770]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B1 },
+ unicodeslot=0x1D770,
+ visual="bf",
+ },
+ [0x1D771]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL BETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B2 },
+ unicodeslot=0x1D771,
+ visual="bf",
+ },
+ [0x1D772]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B3 },
+ unicodeslot=0x1D772,
+ visual="bf",
+ },
+ [0x1D773]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL DELTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B4 },
+ unicodeslot=0x1D773,
+ visual="bf",
+ },
+ [0x1D774]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B5 },
+ unicodeslot=0x1D774,
+ visual="bf",
+ },
+ [0x1D775]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL ZETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B6 },
+ unicodeslot=0x1D775,
+ visual="bf",
+ },
+ [0x1D776]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL ETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B7 },
+ unicodeslot=0x1D776,
+ visual="bf",
+ },
+ [0x1D777]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL THETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B8 },
+ unicodeslot=0x1D777,
+ visual="bf",
+ },
+ [0x1D778]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL IOTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B9 },
+ unicodeslot=0x1D778,
+ visual="bf",
+ },
+ [0x1D779]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BA },
+ unicodeslot=0x1D779,
+ visual="bf",
+ },
+ [0x1D77A]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BB },
+ unicodeslot=0x1D77A,
+ visual="bf",
+ },
+ [0x1D77B]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL MU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BC },
+ unicodeslot=0x1D77B,
+ visual="bf",
+ },
+ [0x1D77C]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL NU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BD },
+ unicodeslot=0x1D77C,
+ visual="bf",
+ },
+ [0x1D77D]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL XI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BE },
+ unicodeslot=0x1D77D,
+ visual="bf",
+ },
+ [0x1D77E]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BF },
+ unicodeslot=0x1D77E,
+ visual="bf",
+ },
+ [0x1D77F]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL PI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C0 },
+ unicodeslot=0x1D77F,
+ visual="bf",
+ },
+ [0x1D780]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL RHO",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C1 },
+ unicodeslot=0x1D780,
+ visual="bf",
+ },
+ [0x1D781]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C2 },
+ unicodeslot=0x1D781,
+ visual="bf",
+ },
+ [0x1D782]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C3 },
+ unicodeslot=0x1D782,
+ visual="bf",
+ },
+ [0x1D783]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL TAU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C4 },
+ unicodeslot=0x1D783,
+ visual="bf",
+ },
+ [0x1D784]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C5 },
+ unicodeslot=0x1D784,
+ visual="bf",
+ },
+ [0x1D785]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C6 },
+ unicodeslot=0x1D785,
+ visual="bf",
+ },
+ [0x1D786]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL CHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C7 },
+ unicodeslot=0x1D786,
+ visual="bf",
+ },
+ [0x1D787]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL PSI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C8 },
+ unicodeslot=0x1D787,
+ visual="bf",
+ },
+ [0x1D788]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C9 },
+ unicodeslot=0x1D788,
+ visual="bf",
+ },
+ [0x1D789]={
+ category="sm",
+ description="MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL",
+ direction="on",
+ linebreak="al",
+ specials={ "font", 0x2202 },
+ unicodeslot=0x1D789,
+ visual="bf",
+ },
+ [0x1D78A]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F5 },
+ unicodeslot=0x1D78A,
+ visual="bf",
+ },
+ [0x1D78B]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D1 },
+ unicodeslot=0x1D78B,
+ visual="bf",
+ },
+ [0x1D78C]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F0 },
+ unicodeslot=0x1D78C,
+ visual="bf",
+ },
+ [0x1D78D]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D5 },
+ unicodeslot=0x1D78D,
+ visual="bf",
+ },
+ [0x1D78E]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F1 },
+ unicodeslot=0x1D78E,
+ visual="bf",
+ },
+ [0x1D78F]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD PI SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D6 },
+ unicodeslot=0x1D78F,
+ visual="bf",
+ },
+ [0x1D790]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0391 },
+ unicodeslot=0x1D790,
+ visual="bi",
+ },
+ [0x1D791]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0392 },
+ unicodeslot=0x1D791,
+ visual="bi",
+ },
+ [0x1D792]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0393 },
+ unicodeslot=0x1D792,
+ visual="bi",
+ },
+ [0x1D793]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0394 },
+ unicodeslot=0x1D793,
+ visual="bi",
+ },
+ [0x1D794]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0395 },
+ unicodeslot=0x1D794,
+ visual="bi",
+ },
+ [0x1D795]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0396 },
+ unicodeslot=0x1D795,
+ visual="bi",
+ },
+ [0x1D796]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0397 },
+ unicodeslot=0x1D796,
+ visual="bi",
+ },
+ [0x1D797]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0398 },
+ unicodeslot=0x1D797,
+ visual="bi",
+ },
+ [0x1D798]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x0399 },
+ unicodeslot=0x1D798,
+ visual="bi",
+ },
+ [0x1D799]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039A },
+ unicodeslot=0x1D799,
+ visual="bi",
+ },
+ [0x1D79A]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039B },
+ unicodeslot=0x1D79A,
+ visual="bi",
+ },
+ [0x1D79B]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039C },
+ unicodeslot=0x1D79B,
+ visual="bi",
+ },
+ [0x1D79C]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039D },
+ unicodeslot=0x1D79C,
+ visual="bi",
+ },
+ [0x1D79D]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039E },
+ unicodeslot=0x1D79D,
+ visual="bi",
+ },
+ [0x1D79E]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x039F },
+ unicodeslot=0x1D79E,
+ visual="bi",
+ },
+ [0x1D79F]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A0 },
+ unicodeslot=0x1D79F,
+ visual="bi",
+ },
+ [0x1D7A0]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A1 },
+ unicodeslot=0x1D7A0,
+ visual="bi",
+ },
+ [0x1D7A1]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F4 },
+ unicodeslot=0x1D7A1,
+ visual="bi",
+ },
+ [0x1D7A2]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A3 },
+ unicodeslot=0x1D7A2,
+ visual="bi",
+ },
+ [0x1D7A3]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A4 },
+ unicodeslot=0x1D7A3,
+ visual="bi",
+ },
+ [0x1D7A4]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A5 },
+ unicodeslot=0x1D7A4,
+ visual="bi",
+ },
+ [0x1D7A5]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A6 },
+ unicodeslot=0x1D7A5,
+ visual="bi",
+ },
+ [0x1D7A6]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A7 },
+ unicodeslot=0x1D7A6,
+ visual="bi",
+ },
+ [0x1D7A7]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A8 },
+ unicodeslot=0x1D7A7,
+ visual="bi",
+ },
+ [0x1D7A8]={
+ category="lu",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03A9 },
+ unicodeslot=0x1D7A8,
+ visual="bi",
+ },
+ [0x1D7A9]={
+ category="sm",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x2207 },
+ unicodeslot=0x1D7A9,
+ visual="bi",
+ },
+ [0x1D7AA]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B1 },
+ unicodeslot=0x1D7AA,
+ visual="bi",
+ },
+ [0x1D7AB]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B2 },
+ unicodeslot=0x1D7AB,
+ visual="bi",
+ },
+ [0x1D7AC]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B3 },
+ unicodeslot=0x1D7AC,
+ visual="bi",
+ },
+ [0x1D7AD]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B4 },
+ unicodeslot=0x1D7AD,
+ visual="bi",
+ },
+ [0x1D7AE]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B5 },
+ unicodeslot=0x1D7AE,
+ visual="bi",
+ },
+ [0x1D7AF]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B6 },
+ unicodeslot=0x1D7AF,
+ visual="bi",
+ },
+ [0x1D7B0]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B7 },
+ unicodeslot=0x1D7B0,
+ visual="bi",
+ },
+ [0x1D7B1]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B8 },
+ unicodeslot=0x1D7B1,
+ visual="bi",
+ },
+ [0x1D7B2]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03B9 },
+ unicodeslot=0x1D7B2,
+ visual="bi",
+ },
+ [0x1D7B3]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BA },
+ unicodeslot=0x1D7B3,
+ visual="bi",
+ },
+ [0x1D7B4]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BB },
+ unicodeslot=0x1D7B4,
+ visual="bi",
+ },
+ [0x1D7B5]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BC },
+ unicodeslot=0x1D7B5,
+ visual="bi",
+ },
+ [0x1D7B6]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BD },
+ unicodeslot=0x1D7B6,
+ visual="bi",
+ },
+ [0x1D7B7]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BE },
+ unicodeslot=0x1D7B7,
+ visual="bi",
+ },
+ [0x1D7B8]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03BF },
+ unicodeslot=0x1D7B8,
+ visual="bi",
+ },
+ [0x1D7B9]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C0 },
+ unicodeslot=0x1D7B9,
+ visual="bi",
+ },
+ [0x1D7BA]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C1 },
+ unicodeslot=0x1D7BA,
+ visual="bi",
+ },
+ [0x1D7BB]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C2 },
+ unicodeslot=0x1D7BB,
+ visual="bi",
+ },
+ [0x1D7BC]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C3 },
+ unicodeslot=0x1D7BC,
+ visual="bi",
+ },
+ [0x1D7BD]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C4 },
+ unicodeslot=0x1D7BD,
+ visual="bi",
+ },
+ [0x1D7BE]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C5 },
+ unicodeslot=0x1D7BE,
+ visual="bi",
+ },
+ [0x1D7BF]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C6 },
+ unicodeslot=0x1D7BF,
+ visual="bi",
+ },
+ [0x1D7C0]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C7 },
+ unicodeslot=0x1D7C0,
+ visual="bi",
+ },
+ [0x1D7C1]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C8 },
+ unicodeslot=0x1D7C1,
+ visual="bi",
+ },
+ [0x1D7C2]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03C9 },
+ unicodeslot=0x1D7C2,
+ visual="bi",
+ },
+ [0x1D7C3]={
+ category="sm",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL",
+ direction="on",
+ linebreak="al",
+ specials={ "font", 0x2202 },
+ unicodeslot=0x1D7C3,
+ visual="bi",
+ },
+ [0x1D7C4]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F5 },
+ unicodeslot=0x1D7C4,
+ visual="bi",
+ },
+ [0x1D7C5]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D1 },
+ unicodeslot=0x1D7C5,
+ visual="bi",
+ },
+ [0x1D7C6]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F0 },
+ unicodeslot=0x1D7C6,
+ visual="bi",
+ },
+ [0x1D7C7]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D5 },
+ unicodeslot=0x1D7C7,
+ visual="bi",
+ },
+ [0x1D7C8]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03F1 },
+ unicodeslot=0x1D7C8,
+ visual="bi",
+ },
+ [0x1D7C9]={
+ category="ll",
+ description="MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03D6 },
+ unicodeslot=0x1D7C9,
+ visual="bi",
+ },
+ [0x1D7CA]={
+ category="lu",
+ description="MATHEMATICAL BOLD CAPITAL DIGAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03DC },
+ unicodeslot=0x1D7CA,
+ visual="bf",
+ },
+ [0x1D7CB]={
+ category="ll",
+ description="MATHEMATICAL BOLD SMALL DIGAMMA",
+ direction="l",
+ linebreak="al",
+ specials={ "font", 0x03DD },
+ unicodeslot=0x1D7CB,
+ visual="bf",
+ },
+ [0x1D7CE]={
+ category="nd",
+ description="MATHEMATICAL BOLD DIGIT ZERO",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0030 },
+ unicodeslot=0x1D7CE,
+ visual="bf",
+ },
+ [0x1D7CF]={
+ category="nd",
+ description="MATHEMATICAL BOLD DIGIT ONE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0031 },
+ unicodeslot=0x1D7CF,
+ visual="bf",
+ },
+ [0x1D7D0]={
+ category="nd",
+ description="MATHEMATICAL BOLD DIGIT TWO",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0032 },
+ unicodeslot=0x1D7D0,
+ visual="bf",
+ },
+ [0x1D7D1]={
+ category="nd",
+ description="MATHEMATICAL BOLD DIGIT THREE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0033 },
+ unicodeslot=0x1D7D1,
+ visual="bf",
+ },
+ [0x1D7D2]={
+ category="nd",
+ description="MATHEMATICAL BOLD DIGIT FOUR",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0034 },
+ unicodeslot=0x1D7D2,
+ visual="bf",
+ },
+ [0x1D7D3]={
+ category="nd",
+ description="MATHEMATICAL BOLD DIGIT FIVE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0035 },
+ unicodeslot=0x1D7D3,
+ visual="bf",
+ },
+ [0x1D7D4]={
+ category="nd",
+ description="MATHEMATICAL BOLD DIGIT SIX",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0036 },
+ unicodeslot=0x1D7D4,
+ visual="bf",
+ },
+ [0x1D7D5]={
+ category="nd",
+ description="MATHEMATICAL BOLD DIGIT SEVEN",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0037 },
+ unicodeslot=0x1D7D5,
+ visual="bf",
+ },
+ [0x1D7D6]={
+ category="nd",
+ description="MATHEMATICAL BOLD DIGIT EIGHT",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0038 },
+ unicodeslot=0x1D7D6,
+ visual="bf",
+ },
+ [0x1D7D7]={
+ category="nd",
+ description="MATHEMATICAL BOLD DIGIT NINE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0039 },
+ unicodeslot=0x1D7D7,
+ visual="bf",
+ },
+ [0x1D7D8]={
+ category="nd",
+ description="MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0030 },
+ unicodeslot=0x1D7D8,
+ },
+ [0x1D7D9]={
+ category="nd",
+ description="MATHEMATICAL DOUBLE-STRUCK DIGIT ONE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0031 },
+ unicodeslot=0x1D7D9,
+ },
+ [0x1D7DA]={
+ category="nd",
+ description="MATHEMATICAL DOUBLE-STRUCK DIGIT TWO",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0032 },
+ unicodeslot=0x1D7DA,
+ },
+ [0x1D7DB]={
+ category="nd",
+ description="MATHEMATICAL DOUBLE-STRUCK DIGIT THREE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0033 },
+ unicodeslot=0x1D7DB,
+ },
+ [0x1D7DC]={
+ category="nd",
+ description="MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0034 },
+ unicodeslot=0x1D7DC,
+ },
+ [0x1D7DD]={
+ category="nd",
+ description="MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0035 },
+ unicodeslot=0x1D7DD,
+ },
+ [0x1D7DE]={
+ category="nd",
+ description="MATHEMATICAL DOUBLE-STRUCK DIGIT SIX",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0036 },
+ unicodeslot=0x1D7DE,
+ },
+ [0x1D7DF]={
+ category="nd",
+ description="MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0037 },
+ unicodeslot=0x1D7DF,
+ },
+ [0x1D7E0]={
+ category="nd",
+ description="MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0038 },
+ unicodeslot=0x1D7E0,
+ },
+ [0x1D7E1]={
+ category="nd",
+ description="MATHEMATICAL DOUBLE-STRUCK DIGIT NINE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0039 },
+ unicodeslot=0x1D7E1,
+ },
+ [0x1D7E2]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF DIGIT ZERO",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0030 },
+ unicodeslot=0x1D7E2,
+ },
+ [0x1D7E3]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF DIGIT ONE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0031 },
+ unicodeslot=0x1D7E3,
+ },
+ [0x1D7E4]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF DIGIT TWO",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0032 },
+ unicodeslot=0x1D7E4,
+ },
+ [0x1D7E5]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF DIGIT THREE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0033 },
+ unicodeslot=0x1D7E5,
+ },
+ [0x1D7E6]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF DIGIT FOUR",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0034 },
+ unicodeslot=0x1D7E6,
+ },
+ [0x1D7E7]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF DIGIT FIVE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0035 },
+ unicodeslot=0x1D7E7,
+ },
+ [0x1D7E8]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF DIGIT SIX",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0036 },
+ unicodeslot=0x1D7E8,
+ },
+ [0x1D7E9]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF DIGIT SEVEN",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0037 },
+ unicodeslot=0x1D7E9,
+ },
+ [0x1D7EA]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF DIGIT EIGHT",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0038 },
+ unicodeslot=0x1D7EA,
+ },
+ [0x1D7EB]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF DIGIT NINE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0039 },
+ unicodeslot=0x1D7EB,
+ },
+ [0x1D7EC]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0030 },
+ unicodeslot=0x1D7EC,
+ visual="bf",
+ },
+ [0x1D7ED]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF BOLD DIGIT ONE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0031 },
+ unicodeslot=0x1D7ED,
+ visual="bf",
+ },
+ [0x1D7EE]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF BOLD DIGIT TWO",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0032 },
+ unicodeslot=0x1D7EE,
+ visual="bf",
+ },
+ [0x1D7EF]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF BOLD DIGIT THREE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0033 },
+ unicodeslot=0x1D7EF,
+ visual="bf",
+ },
+ [0x1D7F0]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0034 },
+ unicodeslot=0x1D7F0,
+ visual="bf",
+ },
+ [0x1D7F1]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0035 },
+ unicodeslot=0x1D7F1,
+ visual="bf",
+ },
+ [0x1D7F2]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF BOLD DIGIT SIX",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0036 },
+ unicodeslot=0x1D7F2,
+ visual="bf",
+ },
+ [0x1D7F3]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0037 },
+ unicodeslot=0x1D7F3,
+ visual="bf",
+ },
+ [0x1D7F4]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0038 },
+ unicodeslot=0x1D7F4,
+ visual="bf",
+ },
+ [0x1D7F5]={
+ category="nd",
+ description="MATHEMATICAL SANS-SERIF BOLD DIGIT NINE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0039 },
+ unicodeslot=0x1D7F5,
+ visual="bf",
+ },
+ [0x1D7F6]={
+ category="nd",
+ description="MATHEMATICAL MONOSPACE DIGIT ZERO",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0030 },
+ unicodeslot=0x1D7F6,
+ },
+ [0x1D7F7]={
+ category="nd",
+ description="MATHEMATICAL MONOSPACE DIGIT ONE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0031 },
+ unicodeslot=0x1D7F7,
+ },
+ [0x1D7F8]={
+ category="nd",
+ description="MATHEMATICAL MONOSPACE DIGIT TWO",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0032 },
+ unicodeslot=0x1D7F8,
+ },
+ [0x1D7F9]={
+ category="nd",
+ description="MATHEMATICAL MONOSPACE DIGIT THREE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0033 },
+ unicodeslot=0x1D7F9,
+ },
+ [0x1D7FA]={
+ category="nd",
+ description="MATHEMATICAL MONOSPACE DIGIT FOUR",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0034 },
+ unicodeslot=0x1D7FA,
+ },
+ [0x1D7FB]={
+ category="nd",
+ description="MATHEMATICAL MONOSPACE DIGIT FIVE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0035 },
+ unicodeslot=0x1D7FB,
+ },
+ [0x1D7FC]={
+ category="nd",
+ description="MATHEMATICAL MONOSPACE DIGIT SIX",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0036 },
+ unicodeslot=0x1D7FC,
+ },
+ [0x1D7FD]={
+ category="nd",
+ description="MATHEMATICAL MONOSPACE DIGIT SEVEN",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0037 },
+ unicodeslot=0x1D7FD,
+ },
+ [0x1D7FE]={
+ category="nd",
+ description="MATHEMATICAL MONOSPACE DIGIT EIGHT",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0038 },
+ unicodeslot=0x1D7FE,
+ },
+ [0x1D7FF]={
+ category="nd",
+ description="MATHEMATICAL MONOSPACE DIGIT NINE",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x0039 },
+ unicodeslot=0x1D7FF,
+ },
+ [0x1EE00]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL ALEF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0627 },
+ unicodeslot=0x1EE00,
+ },
+ [0x1EE01]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL BEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0628 },
+ unicodeslot=0x1EE01,
+ },
+ [0x1EE02]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL JEEM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062C },
+ unicodeslot=0x1EE02,
+ },
+ [0x1EE03]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DAL",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062F },
+ unicodeslot=0x1EE03,
+ },
+ [0x1EE05]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL WAW",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0648 },
+ unicodeslot=0x1EE05,
+ },
+ [0x1EE06]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL ZAIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0632 },
+ unicodeslot=0x1EE06,
+ },
+ [0x1EE07]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL HAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062D },
+ unicodeslot=0x1EE07,
+ },
+ [0x1EE08]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0637 },
+ unicodeslot=0x1EE08,
+ },
+ [0x1EE09]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL YEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x064A },
+ unicodeslot=0x1EE09,
+ },
+ [0x1EE0A]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL KAF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0643 },
+ unicodeslot=0x1EE0A,
+ },
+ [0x1EE0B]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LAM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0644 },
+ unicodeslot=0x1EE0B,
+ },
+ [0x1EE0C]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL MEEM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0645 },
+ unicodeslot=0x1EE0C,
+ },
+ [0x1EE0D]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL NOON",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0646 },
+ unicodeslot=0x1EE0D,
+ },
+ [0x1EE0E]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL SEEN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0633 },
+ unicodeslot=0x1EE0E,
+ },
+ [0x1EE0F]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL AIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0639 },
+ unicodeslot=0x1EE0F,
+ },
+ [0x1EE10]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL FEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0641 },
+ unicodeslot=0x1EE10,
+ },
+ [0x1EE11]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL SAD",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0635 },
+ unicodeslot=0x1EE11,
+ },
+ [0x1EE12]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL QAF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0642 },
+ unicodeslot=0x1EE12,
+ },
+ [0x1EE13]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL REH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0631 },
+ unicodeslot=0x1EE13,
+ },
+ [0x1EE14]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL SHEEN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0634 },
+ unicodeslot=0x1EE14,
+ },
+ [0x1EE15]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062A },
+ unicodeslot=0x1EE15,
+ },
+ [0x1EE16]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL THEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062B },
+ unicodeslot=0x1EE16,
+ },
+ [0x1EE17]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL KHAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062E },
+ unicodeslot=0x1EE17,
+ },
+ [0x1EE18]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL THAL",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0630 },
+ unicodeslot=0x1EE18,
+ },
+ [0x1EE19]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DAD",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0636 },
+ unicodeslot=0x1EE19,
+ },
+ [0x1EE1A]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL ZAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0638 },
+ unicodeslot=0x1EE1A,
+ },
+ [0x1EE1B]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL GHAIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x063A },
+ unicodeslot=0x1EE1B,
+ },
+ [0x1EE1C]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOTLESS BEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x066E },
+ unicodeslot=0x1EE1C,
+ },
+ [0x1EE1D]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOTLESS NOON",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x06BA },
+ unicodeslot=0x1EE1D,
+ },
+ [0x1EE1E]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOTLESS FEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x06A1 },
+ unicodeslot=0x1EE1E,
+ },
+ [0x1EE1F]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOTLESS QAF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x066F },
+ unicodeslot=0x1EE1F,
+ },
+ [0x1EE21]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL BEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0628 },
+ unicodeslot=0x1EE21,
+ },
+ [0x1EE22]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL JEEM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062C },
+ unicodeslot=0x1EE22,
+ },
+ [0x1EE24]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL HEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0647 },
+ unicodeslot=0x1EE24,
+ },
+ [0x1EE27]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL HAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062D },
+ unicodeslot=0x1EE27,
+ },
+ [0x1EE29]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL YEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x064A },
+ unicodeslot=0x1EE29,
+ },
+ [0x1EE2A]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL KAF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0643 },
+ unicodeslot=0x1EE2A,
+ },
+ [0x1EE2B]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL LAM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0644 },
+ unicodeslot=0x1EE2B,
+ },
+ [0x1EE2C]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL MEEM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0645 },
+ unicodeslot=0x1EE2C,
+ },
+ [0x1EE2D]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL NOON",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0646 },
+ unicodeslot=0x1EE2D,
+ },
+ [0x1EE2E]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL SEEN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0633 },
+ unicodeslot=0x1EE2E,
+ },
+ [0x1EE2F]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL AIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0639 },
+ unicodeslot=0x1EE2F,
+ },
+ [0x1EE30]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL FEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0641 },
+ unicodeslot=0x1EE30,
+ },
+ [0x1EE31]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL SAD",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0635 },
+ unicodeslot=0x1EE31,
+ },
+ [0x1EE32]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL QAF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0642 },
+ unicodeslot=0x1EE32,
+ },
+ [0x1EE34]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL SHEEN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0634 },
+ unicodeslot=0x1EE34,
+ },
+ [0x1EE35]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL TEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062A },
+ unicodeslot=0x1EE35,
+ },
+ [0x1EE36]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL THEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062B },
+ unicodeslot=0x1EE36,
+ },
+ [0x1EE37]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL KHAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062E },
+ unicodeslot=0x1EE37,
+ },
+ [0x1EE39]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL DAD",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0636 },
+ unicodeslot=0x1EE39,
+ },
+ [0x1EE3B]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL INITIAL GHAIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x063A },
+ unicodeslot=0x1EE3B,
+ },
+ [0x1EE42]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED JEEM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062C },
+ unicodeslot=0x1EE42,
+ },
+ [0x1EE47]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED HAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062D },
+ unicodeslot=0x1EE47,
+ },
+ [0x1EE49]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED YEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x064A },
+ unicodeslot=0x1EE49,
+ },
+ [0x1EE4B]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED LAM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0644 },
+ unicodeslot=0x1EE4B,
+ },
+ [0x1EE4D]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED NOON",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0646 },
+ unicodeslot=0x1EE4D,
+ },
+ [0x1EE4E]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED SEEN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0633 },
+ unicodeslot=0x1EE4E,
+ },
+ [0x1EE4F]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED AIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0639 },
+ unicodeslot=0x1EE4F,
+ },
+ [0x1EE51]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED SAD",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0635 },
+ unicodeslot=0x1EE51,
+ },
+ [0x1EE52]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED QAF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0642 },
+ unicodeslot=0x1EE52,
+ },
+ [0x1EE54]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED SHEEN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0634 },
+ unicodeslot=0x1EE54,
+ },
+ [0x1EE57]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED KHAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062E },
+ unicodeslot=0x1EE57,
+ },
+ [0x1EE59]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED DAD",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0636 },
+ unicodeslot=0x1EE59,
+ },
+ [0x1EE5B]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED GHAIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x063A },
+ unicodeslot=0x1EE5B,
+ },
+ [0x1EE5D]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED DOTLESS NOON",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x06BA },
+ unicodeslot=0x1EE5D,
+ },
+ [0x1EE5F]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL TAILED DOTLESS QAF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x066F },
+ unicodeslot=0x1EE5F,
+ },
+ [0x1EE61]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED BEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0628 },
+ unicodeslot=0x1EE61,
+ },
+ [0x1EE62]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED JEEM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062C },
+ unicodeslot=0x1EE62,
+ },
+ [0x1EE64]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED HEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0647 },
+ unicodeslot=0x1EE64,
+ },
+ [0x1EE67]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED HAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062D },
+ unicodeslot=0x1EE67,
+ },
+ [0x1EE68]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED TAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0637 },
+ unicodeslot=0x1EE68,
+ },
+ [0x1EE69]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED YEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x064A },
+ unicodeslot=0x1EE69,
+ },
+ [0x1EE6A]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED KAF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0643 },
+ unicodeslot=0x1EE6A,
+ },
+ [0x1EE6C]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED MEEM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0645 },
+ unicodeslot=0x1EE6C,
+ },
+ [0x1EE6D]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED NOON",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0646 },
+ unicodeslot=0x1EE6D,
+ },
+ [0x1EE6E]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED SEEN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0633 },
+ unicodeslot=0x1EE6E,
+ },
+ [0x1EE6F]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED AIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0639 },
+ unicodeslot=0x1EE6F,
+ },
+ [0x1EE70]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED FEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0641 },
+ unicodeslot=0x1EE70,
+ },
+ [0x1EE71]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED SAD",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0635 },
+ unicodeslot=0x1EE71,
+ },
+ [0x1EE72]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED QAF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0642 },
+ unicodeslot=0x1EE72,
+ },
+ [0x1EE74]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED SHEEN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0634 },
+ unicodeslot=0x1EE74,
+ },
+ [0x1EE75]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED TEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062A },
+ unicodeslot=0x1EE75,
+ },
+ [0x1EE76]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED THEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062B },
+ unicodeslot=0x1EE76,
+ },
+ [0x1EE77]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED KHAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062E },
+ unicodeslot=0x1EE77,
+ },
+ [0x1EE79]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED DAD",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0636 },
+ unicodeslot=0x1EE79,
+ },
+ [0x1EE7A]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED ZAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0638 },
+ unicodeslot=0x1EE7A,
+ },
+ [0x1EE7B]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED GHAIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x063A },
+ unicodeslot=0x1EE7B,
+ },
+ [0x1EE7C]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED DOTLESS BEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x066E },
+ unicodeslot=0x1EE7C,
+ },
+ [0x1EE7E]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL STRETCHED DOTLESS FEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x06A1 },
+ unicodeslot=0x1EE7E,
+ },
+ [0x1EE80]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED ALEF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0627 },
+ unicodeslot=0x1EE80,
+ },
+ [0x1EE81]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED BEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0628 },
+ unicodeslot=0x1EE81,
+ },
+ [0x1EE82]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED JEEM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062C },
+ unicodeslot=0x1EE82,
+ },
+ [0x1EE83]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED DAL",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062F },
+ unicodeslot=0x1EE83,
+ },
+ [0x1EE84]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED HEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0647 },
+ unicodeslot=0x1EE84,
+ },
+ [0x1EE85]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED WAW",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0648 },
+ unicodeslot=0x1EE85,
+ },
+ [0x1EE86]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED ZAIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0632 },
+ unicodeslot=0x1EE86,
+ },
+ [0x1EE87]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED HAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062D },
+ unicodeslot=0x1EE87,
+ },
+ [0x1EE88]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED TAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0637 },
+ unicodeslot=0x1EE88,
+ },
+ [0x1EE89]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED YEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x064A },
+ unicodeslot=0x1EE89,
+ },
+ [0x1EE8B]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED LAM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0644 },
+ unicodeslot=0x1EE8B,
+ },
+ [0x1EE8C]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED MEEM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0645 },
+ unicodeslot=0x1EE8C,
+ },
+ [0x1EE8D]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED NOON",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0646 },
+ unicodeslot=0x1EE8D,
+ },
+ [0x1EE8E]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED SEEN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0633 },
+ unicodeslot=0x1EE8E,
+ },
+ [0x1EE8F]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED AIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0639 },
+ unicodeslot=0x1EE8F,
+ },
+ [0x1EE90]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED FEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0641 },
+ unicodeslot=0x1EE90,
+ },
+ [0x1EE91]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED SAD",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0635 },
+ unicodeslot=0x1EE91,
+ },
+ [0x1EE92]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED QAF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0642 },
+ unicodeslot=0x1EE92,
+ },
+ [0x1EE93]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED REH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0631 },
+ unicodeslot=0x1EE93,
+ },
+ [0x1EE94]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED SHEEN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0634 },
+ unicodeslot=0x1EE94,
+ },
+ [0x1EE95]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED TEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062A },
+ unicodeslot=0x1EE95,
+ },
+ [0x1EE96]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED THEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062B },
+ unicodeslot=0x1EE96,
+ },
+ [0x1EE97]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED KHAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062E },
+ unicodeslot=0x1EE97,
+ },
+ [0x1EE98]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED THAL",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0630 },
+ unicodeslot=0x1EE98,
+ },
+ [0x1EE99]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED DAD",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0636 },
+ unicodeslot=0x1EE99,
+ },
+ [0x1EE9A]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED ZAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0638 },
+ unicodeslot=0x1EE9A,
+ },
+ [0x1EE9B]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL LOOPED GHAIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x063A },
+ unicodeslot=0x1EE9B,
+ },
+ [0x1EEA1]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK BEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0628 },
+ unicodeslot=0x1EEA1,
+ },
+ [0x1EEA2]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK JEEM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062C },
+ unicodeslot=0x1EEA2,
+ },
+ [0x1EEA3]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK DAL",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062F },
+ unicodeslot=0x1EEA3,
+ },
+ [0x1EEA5]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK WAW",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0648 },
+ unicodeslot=0x1EEA5,
+ },
+ [0x1EEA6]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK ZAIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0632 },
+ unicodeslot=0x1EEA6,
+ },
+ [0x1EEA7]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK HAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062D },
+ unicodeslot=0x1EEA7,
+ },
+ [0x1EEA8]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK TAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0637 },
+ unicodeslot=0x1EEA8,
+ },
+ [0x1EEA9]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK YEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x064A },
+ unicodeslot=0x1EEA9,
+ },
+ [0x1EEAB]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK LAM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0644 },
+ unicodeslot=0x1EEAB,
+ },
+ [0x1EEAC]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK MEEM",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0645 },
+ unicodeslot=0x1EEAC,
+ },
+ [0x1EEAD]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK NOON",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0646 },
+ unicodeslot=0x1EEAD,
+ },
+ [0x1EEAE]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK SEEN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0633 },
+ unicodeslot=0x1EEAE,
+ },
+ [0x1EEAF]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK AIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0639 },
+ unicodeslot=0x1EEAF,
+ },
+ [0x1EEB0]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK FEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0641 },
+ unicodeslot=0x1EEB0,
+ },
+ [0x1EEB1]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK SAD",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0635 },
+ unicodeslot=0x1EEB1,
+ },
+ [0x1EEB2]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK QAF",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0642 },
+ unicodeslot=0x1EEB2,
+ },
+ [0x1EEB3]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK REH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0631 },
+ unicodeslot=0x1EEB3,
+ },
+ [0x1EEB4]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK SHEEN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0634 },
+ unicodeslot=0x1EEB4,
+ },
+ [0x1EEB5]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK TEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062A },
+ unicodeslot=0x1EEB5,
+ },
+ [0x1EEB6]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK THEH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062B },
+ unicodeslot=0x1EEB6,
+ },
+ [0x1EEB7]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK KHAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x062E },
+ unicodeslot=0x1EEB7,
+ },
+ [0x1EEB8]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK THAL",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0630 },
+ unicodeslot=0x1EEB8,
+ },
+ [0x1EEB9]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK DAD",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0636 },
+ unicodeslot=0x1EEB9,
+ },
+ [0x1EEBA]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK ZAH",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x0638 },
+ unicodeslot=0x1EEBA,
+ },
+ [0x1EEBB]={
+ category="lo",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN",
+ direction="al",
+ linebreak="al",
+ specials={ "font", 0x063A },
+ unicodeslot=0x1EEBB,
+ },
+ [0x1EEF0]={
+ category="sm",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1EEF0,
+ },
+ [0x1EEF1]={
+ category="sm",
+ comment="check math properties",
+ description="ARABIC MATHEMATICAL OPERATOR HAH WITH DAL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1EEF1,
+ },
+ [0x1F000]={
+ category="so",
+ description="MAHJONG TILE EAST WIND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F000,
+ },
+ [0x1F001]={
+ category="so",
+ description="MAHJONG TILE SOUTH WIND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F001,
+ },
+ [0x1F002]={
+ category="so",
+ description="MAHJONG TILE WEST WIND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F002,
+ },
+ [0x1F003]={
+ category="so",
+ description="MAHJONG TILE NORTH WIND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F003,
+ },
+ [0x1F004]={
+ category="so",
+ description="MAHJONG TILE RED DRAGON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F004,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x1F005]={
+ category="so",
+ description="MAHJONG TILE GREEN DRAGON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F005,
+ },
+ [0x1F006]={
+ category="so",
+ description="MAHJONG TILE WHITE DRAGON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F006,
+ },
+ [0x1F007]={
+ category="so",
+ description="MAHJONG TILE ONE OF CHARACTERS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F007,
+ },
+ [0x1F008]={
+ category="so",
+ description="MAHJONG TILE TWO OF CHARACTERS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F008,
+ },
+ [0x1F009]={
+ category="so",
+ description="MAHJONG TILE THREE OF CHARACTERS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F009,
+ },
+ [0x1F00A]={
+ category="so",
+ description="MAHJONG TILE FOUR OF CHARACTERS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F00A,
+ },
+ [0x1F00B]={
+ category="so",
+ description="MAHJONG TILE FIVE OF CHARACTERS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F00B,
+ },
+ [0x1F00C]={
+ category="so",
+ description="MAHJONG TILE SIX OF CHARACTERS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F00C,
+ },
+ [0x1F00D]={
+ category="so",
+ description="MAHJONG TILE SEVEN OF CHARACTERS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F00D,
+ },
+ [0x1F00E]={
+ category="so",
+ description="MAHJONG TILE EIGHT OF CHARACTERS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F00E,
+ },
+ [0x1F00F]={
+ category="so",
+ description="MAHJONG TILE NINE OF CHARACTERS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F00F,
+ },
+ [0x1F010]={
+ category="so",
+ description="MAHJONG TILE ONE OF BAMBOOS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F010,
+ },
+ [0x1F011]={
+ category="so",
+ description="MAHJONG TILE TWO OF BAMBOOS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F011,
+ },
+ [0x1F012]={
+ category="so",
+ description="MAHJONG TILE THREE OF BAMBOOS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F012,
+ },
+ [0x1F013]={
+ category="so",
+ description="MAHJONG TILE FOUR OF BAMBOOS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F013,
+ },
+ [0x1F014]={
+ category="so",
+ description="MAHJONG TILE FIVE OF BAMBOOS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F014,
+ },
+ [0x1F015]={
+ category="so",
+ description="MAHJONG TILE SIX OF BAMBOOS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F015,
+ },
+ [0x1F016]={
+ category="so",
+ description="MAHJONG TILE SEVEN OF BAMBOOS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F016,
+ },
+ [0x1F017]={
+ category="so",
+ description="MAHJONG TILE EIGHT OF BAMBOOS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F017,
+ },
+ [0x1F018]={
+ category="so",
+ description="MAHJONG TILE NINE OF BAMBOOS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F018,
+ },
+ [0x1F019]={
+ category="so",
+ description="MAHJONG TILE ONE OF CIRCLES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F019,
+ },
+ [0x1F01A]={
+ category="so",
+ description="MAHJONG TILE TWO OF CIRCLES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F01A,
+ },
+ [0x1F01B]={
+ category="so",
+ description="MAHJONG TILE THREE OF CIRCLES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F01B,
+ },
+ [0x1F01C]={
+ category="so",
+ description="MAHJONG TILE FOUR OF CIRCLES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F01C,
+ },
+ [0x1F01D]={
+ category="so",
+ description="MAHJONG TILE FIVE OF CIRCLES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F01D,
+ },
+ [0x1F01E]={
+ category="so",
+ description="MAHJONG TILE SIX OF CIRCLES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F01E,
+ },
+ [0x1F01F]={
+ category="so",
+ description="MAHJONG TILE SEVEN OF CIRCLES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F01F,
+ },
+ [0x1F020]={
+ category="so",
+ description="MAHJONG TILE EIGHT OF CIRCLES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F020,
+ },
+ [0x1F021]={
+ category="so",
+ description="MAHJONG TILE NINE OF CIRCLES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F021,
+ },
+ [0x1F022]={
+ category="so",
+ description="MAHJONG TILE PLUM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F022,
+ },
+ [0x1F023]={
+ category="so",
+ description="MAHJONG TILE ORCHID",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F023,
+ },
+ [0x1F024]={
+ category="so",
+ description="MAHJONG TILE BAMBOO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F024,
+ },
+ [0x1F025]={
+ category="so",
+ description="MAHJONG TILE CHRYSANTHEMUM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F025,
+ },
+ [0x1F026]={
+ category="so",
+ description="MAHJONG TILE SPRING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F026,
+ },
+ [0x1F027]={
+ category="so",
+ description="MAHJONG TILE SUMMER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F027,
+ },
+ [0x1F028]={
+ category="so",
+ description="MAHJONG TILE AUTUMN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F028,
+ },
+ [0x1F029]={
+ category="so",
+ description="MAHJONG TILE WINTER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F029,
+ },
+ [0x1F02A]={
+ category="so",
+ description="MAHJONG TILE JOKER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F02A,
+ },
+ [0x1F02B]={
+ category="so",
+ description="MAHJONG TILE BACK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F02B,
+ },
+ [0x1F030]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL BACK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F030,
+ },
+ [0x1F031]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-00-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F031,
+ },
+ [0x1F032]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-00-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F032,
+ },
+ [0x1F033]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-00-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F033,
+ },
+ [0x1F034]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-00-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F034,
+ },
+ [0x1F035]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-00-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F035,
+ },
+ [0x1F036]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-00-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F036,
+ },
+ [0x1F037]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-00-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F037,
+ },
+ [0x1F038]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-01-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F038,
+ },
+ [0x1F039]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-01-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F039,
+ },
+ [0x1F03A]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-01-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F03A,
+ },
+ [0x1F03B]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-01-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F03B,
+ },
+ [0x1F03C]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-01-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F03C,
+ },
+ [0x1F03D]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-01-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F03D,
+ },
+ [0x1F03E]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-01-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F03E,
+ },
+ [0x1F03F]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-02-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F03F,
+ },
+ [0x1F040]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-02-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F040,
+ },
+ [0x1F041]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-02-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F041,
+ },
+ [0x1F042]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-02-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F042,
+ },
+ [0x1F043]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-02-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F043,
+ },
+ [0x1F044]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-02-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F044,
+ },
+ [0x1F045]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-02-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F045,
+ },
+ [0x1F046]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-03-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F046,
+ },
+ [0x1F047]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-03-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F047,
+ },
+ [0x1F048]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-03-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F048,
+ },
+ [0x1F049]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-03-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F049,
+ },
+ [0x1F04A]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-03-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F04A,
+ },
+ [0x1F04B]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-03-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F04B,
+ },
+ [0x1F04C]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-03-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F04C,
+ },
+ [0x1F04D]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-04-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F04D,
+ },
+ [0x1F04E]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-04-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F04E,
+ },
+ [0x1F04F]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-04-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F04F,
+ },
+ [0x1F050]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-04-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F050,
+ },
+ [0x1F051]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-04-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F051,
+ },
+ [0x1F052]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-04-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F052,
+ },
+ [0x1F053]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-04-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F053,
+ },
+ [0x1F054]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-05-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F054,
+ },
+ [0x1F055]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-05-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F055,
+ },
+ [0x1F056]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-05-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F056,
+ },
+ [0x1F057]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-05-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F057,
+ },
+ [0x1F058]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-05-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F058,
+ },
+ [0x1F059]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-05-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F059,
+ },
+ [0x1F05A]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-05-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F05A,
+ },
+ [0x1F05B]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-06-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F05B,
+ },
+ [0x1F05C]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-06-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F05C,
+ },
+ [0x1F05D]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-06-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F05D,
+ },
+ [0x1F05E]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-06-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F05E,
+ },
+ [0x1F05F]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-06-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F05F,
+ },
+ [0x1F060]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-06-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F060,
+ },
+ [0x1F061]={
+ category="so",
+ description="DOMINO TILE HORIZONTAL-06-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F061,
+ },
+ [0x1F062]={
+ category="so",
+ description="DOMINO TILE VERTICAL BACK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F062,
+ },
+ [0x1F063]={
+ category="so",
+ description="DOMINO TILE VERTICAL-00-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F063,
+ },
+ [0x1F064]={
+ category="so",
+ description="DOMINO TILE VERTICAL-00-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F064,
+ },
+ [0x1F065]={
+ category="so",
+ description="DOMINO TILE VERTICAL-00-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F065,
+ },
+ [0x1F066]={
+ category="so",
+ description="DOMINO TILE VERTICAL-00-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F066,
+ },
+ [0x1F067]={
+ category="so",
+ description="DOMINO TILE VERTICAL-00-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F067,
+ },
+ [0x1F068]={
+ category="so",
+ description="DOMINO TILE VERTICAL-00-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F068,
+ },
+ [0x1F069]={
+ category="so",
+ description="DOMINO TILE VERTICAL-00-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F069,
+ },
+ [0x1F06A]={
+ category="so",
+ description="DOMINO TILE VERTICAL-01-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F06A,
+ },
+ [0x1F06B]={
+ category="so",
+ description="DOMINO TILE VERTICAL-01-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F06B,
+ },
+ [0x1F06C]={
+ category="so",
+ description="DOMINO TILE VERTICAL-01-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F06C,
+ },
+ [0x1F06D]={
+ category="so",
+ description="DOMINO TILE VERTICAL-01-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F06D,
+ },
+ [0x1F06E]={
+ category="so",
+ description="DOMINO TILE VERTICAL-01-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F06E,
+ },
+ [0x1F06F]={
+ category="so",
+ description="DOMINO TILE VERTICAL-01-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F06F,
+ },
+ [0x1F070]={
+ category="so",
+ description="DOMINO TILE VERTICAL-01-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F070,
+ },
+ [0x1F071]={
+ category="so",
+ description="DOMINO TILE VERTICAL-02-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F071,
+ },
+ [0x1F072]={
+ category="so",
+ description="DOMINO TILE VERTICAL-02-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F072,
+ },
+ [0x1F073]={
+ category="so",
+ description="DOMINO TILE VERTICAL-02-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F073,
+ },
+ [0x1F074]={
+ category="so",
+ description="DOMINO TILE VERTICAL-02-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F074,
+ },
+ [0x1F075]={
+ category="so",
+ description="DOMINO TILE VERTICAL-02-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F075,
+ },
+ [0x1F076]={
+ category="so",
+ description="DOMINO TILE VERTICAL-02-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F076,
+ },
+ [0x1F077]={
+ category="so",
+ description="DOMINO TILE VERTICAL-02-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F077,
+ },
+ [0x1F078]={
+ category="so",
+ description="DOMINO TILE VERTICAL-03-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F078,
+ },
+ [0x1F079]={
+ category="so",
+ description="DOMINO TILE VERTICAL-03-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F079,
+ },
+ [0x1F07A]={
+ category="so",
+ description="DOMINO TILE VERTICAL-03-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F07A,
+ },
+ [0x1F07B]={
+ category="so",
+ description="DOMINO TILE VERTICAL-03-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F07B,
+ },
+ [0x1F07C]={
+ category="so",
+ description="DOMINO TILE VERTICAL-03-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F07C,
+ },
+ [0x1F07D]={
+ category="so",
+ description="DOMINO TILE VERTICAL-03-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F07D,
+ },
+ [0x1F07E]={
+ category="so",
+ description="DOMINO TILE VERTICAL-03-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F07E,
+ },
+ [0x1F07F]={
+ category="so",
+ description="DOMINO TILE VERTICAL-04-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F07F,
+ },
+ [0x1F080]={
+ category="so",
+ description="DOMINO TILE VERTICAL-04-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F080,
+ },
+ [0x1F081]={
+ category="so",
+ description="DOMINO TILE VERTICAL-04-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F081,
+ },
+ [0x1F082]={
+ category="so",
+ description="DOMINO TILE VERTICAL-04-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F082,
+ },
+ [0x1F083]={
+ category="so",
+ description="DOMINO TILE VERTICAL-04-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F083,
+ },
+ [0x1F084]={
+ category="so",
+ description="DOMINO TILE VERTICAL-04-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F084,
+ },
+ [0x1F085]={
+ category="so",
+ description="DOMINO TILE VERTICAL-04-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F085,
+ },
+ [0x1F086]={
+ category="so",
+ description="DOMINO TILE VERTICAL-05-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F086,
+ },
+ [0x1F087]={
+ category="so",
+ description="DOMINO TILE VERTICAL-05-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F087,
+ },
+ [0x1F088]={
+ category="so",
+ description="DOMINO TILE VERTICAL-05-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F088,
+ },
+ [0x1F089]={
+ category="so",
+ description="DOMINO TILE VERTICAL-05-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F089,
+ },
+ [0x1F08A]={
+ category="so",
+ description="DOMINO TILE VERTICAL-05-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F08A,
+ },
+ [0x1F08B]={
+ category="so",
+ description="DOMINO TILE VERTICAL-05-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F08B,
+ },
+ [0x1F08C]={
+ category="so",
+ description="DOMINO TILE VERTICAL-05-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F08C,
+ },
+ [0x1F08D]={
+ category="so",
+ description="DOMINO TILE VERTICAL-06-00",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F08D,
+ },
+ [0x1F08E]={
+ category="so",
+ description="DOMINO TILE VERTICAL-06-01",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F08E,
+ },
+ [0x1F08F]={
+ category="so",
+ description="DOMINO TILE VERTICAL-06-02",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F08F,
+ },
+ [0x1F090]={
+ category="so",
+ description="DOMINO TILE VERTICAL-06-03",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F090,
+ },
+ [0x1F091]={
+ category="so",
+ description="DOMINO TILE VERTICAL-06-04",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F091,
+ },
+ [0x1F092]={
+ category="so",
+ description="DOMINO TILE VERTICAL-06-05",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F092,
+ },
+ [0x1F093]={
+ category="so",
+ description="DOMINO TILE VERTICAL-06-06",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F093,
+ },
+ [0x1F0A0]={
+ category="so",
+ description="PLAYING CARD BACK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A0,
+ },
+ [0x1F0A1]={
+ category="so",
+ description="PLAYING CARD ACE OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A1,
+ },
+ [0x1F0A2]={
+ category="so",
+ description="PLAYING CARD TWO OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A2,
+ },
+ [0x1F0A3]={
+ category="so",
+ description="PLAYING CARD THREE OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A3,
+ },
+ [0x1F0A4]={
+ category="so",
+ description="PLAYING CARD FOUR OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A4,
+ },
+ [0x1F0A5]={
+ category="so",
+ description="PLAYING CARD FIVE OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A5,
+ },
+ [0x1F0A6]={
+ category="so",
+ description="PLAYING CARD SIX OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A6,
+ },
+ [0x1F0A7]={
+ category="so",
+ description="PLAYING CARD SEVEN OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A7,
+ },
+ [0x1F0A8]={
+ category="so",
+ description="PLAYING CARD EIGHT OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A8,
+ },
+ [0x1F0A9]={
+ category="so",
+ description="PLAYING CARD NINE OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0A9,
+ },
+ [0x1F0AA]={
+ category="so",
+ description="PLAYING CARD TEN OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0AA,
+ },
+ [0x1F0AB]={
+ category="so",
+ description="PLAYING CARD JACK OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0AB,
+ },
+ [0x1F0AC]={
+ category="so",
+ description="PLAYING CARD KNIGHT OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0AC,
+ },
+ [0x1F0AD]={
+ category="so",
+ description="PLAYING CARD QUEEN OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0AD,
+ },
+ [0x1F0AE]={
+ category="so",
+ description="PLAYING CARD KING OF SPADES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0AE,
+ },
+ [0x1F0B1]={
+ category="so",
+ description="PLAYING CARD ACE OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B1,
+ },
+ [0x1F0B2]={
+ category="so",
+ description="PLAYING CARD TWO OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B2,
+ },
+ [0x1F0B3]={
+ category="so",
+ description="PLAYING CARD THREE OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B3,
+ },
+ [0x1F0B4]={
+ category="so",
+ description="PLAYING CARD FOUR OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B4,
+ },
+ [0x1F0B5]={
+ category="so",
+ description="PLAYING CARD FIVE OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B5,
+ },
+ [0x1F0B6]={
+ category="so",
+ description="PLAYING CARD SIX OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B6,
+ },
+ [0x1F0B7]={
+ category="so",
+ description="PLAYING CARD SEVEN OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B7,
+ },
+ [0x1F0B8]={
+ category="so",
+ description="PLAYING CARD EIGHT OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B8,
+ },
+ [0x1F0B9]={
+ category="so",
+ description="PLAYING CARD NINE OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0B9,
+ },
+ [0x1F0BA]={
+ category="so",
+ description="PLAYING CARD TEN OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0BA,
+ },
+ [0x1F0BB]={
+ category="so",
+ description="PLAYING CARD JACK OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0BB,
+ },
+ [0x1F0BC]={
+ category="so",
+ description="PLAYING CARD KNIGHT OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0BC,
+ },
+ [0x1F0BD]={
+ category="so",
+ description="PLAYING CARD QUEEN OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0BD,
+ },
+ [0x1F0BE]={
+ category="so",
+ description="PLAYING CARD KING OF HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0BE,
+ },
+ [0x1F0C1]={
+ category="so",
+ description="PLAYING CARD ACE OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C1,
+ },
+ [0x1F0C2]={
+ category="so",
+ description="PLAYING CARD TWO OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C2,
+ },
+ [0x1F0C3]={
+ category="so",
+ description="PLAYING CARD THREE OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C3,
+ },
+ [0x1F0C4]={
+ category="so",
+ description="PLAYING CARD FOUR OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C4,
+ },
+ [0x1F0C5]={
+ category="so",
+ description="PLAYING CARD FIVE OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C5,
+ },
+ [0x1F0C6]={
+ category="so",
+ description="PLAYING CARD SIX OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C6,
+ },
+ [0x1F0C7]={
+ category="so",
+ description="PLAYING CARD SEVEN OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C7,
+ },
+ [0x1F0C8]={
+ category="so",
+ description="PLAYING CARD EIGHT OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C8,
+ },
+ [0x1F0C9]={
+ category="so",
+ description="PLAYING CARD NINE OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0C9,
+ },
+ [0x1F0CA]={
+ category="so",
+ description="PLAYING CARD TEN OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0CA,
+ },
+ [0x1F0CB]={
+ category="so",
+ description="PLAYING CARD JACK OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0CB,
+ },
+ [0x1F0CC]={
+ category="so",
+ description="PLAYING CARD KNIGHT OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0CC,
+ },
+ [0x1F0CD]={
+ category="so",
+ description="PLAYING CARD QUEEN OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0CD,
+ },
+ [0x1F0CE]={
+ category="so",
+ description="PLAYING CARD KING OF DIAMONDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0CE,
+ },
+ [0x1F0CF]={
+ category="so",
+ description="PLAYING CARD BLACK JOKER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0CF,
+ },
+ [0x1F0D1]={
+ category="so",
+ description="PLAYING CARD ACE OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D1,
+ },
+ [0x1F0D2]={
+ category="so",
+ description="PLAYING CARD TWO OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D2,
+ },
+ [0x1F0D3]={
+ category="so",
+ description="PLAYING CARD THREE OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D3,
+ },
+ [0x1F0D4]={
+ category="so",
+ description="PLAYING CARD FOUR OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D4,
+ },
+ [0x1F0D5]={
+ category="so",
+ description="PLAYING CARD FIVE OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D5,
+ },
+ [0x1F0D6]={
+ category="so",
+ description="PLAYING CARD SIX OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D6,
+ },
+ [0x1F0D7]={
+ category="so",
+ description="PLAYING CARD SEVEN OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D7,
+ },
+ [0x1F0D8]={
+ category="so",
+ description="PLAYING CARD EIGHT OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D8,
+ },
+ [0x1F0D9]={
+ category="so",
+ description="PLAYING CARD NINE OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0D9,
+ },
+ [0x1F0DA]={
+ category="so",
+ description="PLAYING CARD TEN OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0DA,
+ },
+ [0x1F0DB]={
+ category="so",
+ description="PLAYING CARD JACK OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0DB,
+ },
+ [0x1F0DC]={
+ category="so",
+ description="PLAYING CARD KNIGHT OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0DC,
+ },
+ [0x1F0DD]={
+ category="so",
+ description="PLAYING CARD QUEEN OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0DD,
+ },
+ [0x1F0DE]={
+ category="so",
+ description="PLAYING CARD KING OF CLUBS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0DE,
+ },
+ [0x1F0DF]={
+ category="so",
+ description="PLAYING CARD WHITE JOKER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F0DF,
+ },
+ [0x1F100]={
+ category="no",
+ cjkwd="a",
+ description="DIGIT ZERO FULL STOP",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0030, 0x002E },
+ unicodeslot=0x1F100,
+ },
+ [0x1F101]={
+ category="no",
+ cjkwd="a",
+ description="DIGIT ZERO COMMA",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0030, 0x002C },
+ unicodeslot=0x1F101,
+ },
+ [0x1F102]={
+ category="no",
+ cjkwd="a",
+ description="DIGIT ONE COMMA",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0031, 0x002C },
+ unicodeslot=0x1F102,
+ },
+ [0x1F103]={
+ category="no",
+ cjkwd="a",
+ description="DIGIT TWO COMMA",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0032, 0x002C },
+ unicodeslot=0x1F103,
+ },
+ [0x1F104]={
+ category="no",
+ cjkwd="a",
+ description="DIGIT THREE COMMA",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0033, 0x002C },
+ unicodeslot=0x1F104,
+ },
+ [0x1F105]={
+ category="no",
+ cjkwd="a",
+ description="DIGIT FOUR COMMA",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0034, 0x002C },
+ unicodeslot=0x1F105,
+ },
+ [0x1F106]={
+ category="no",
+ cjkwd="a",
+ description="DIGIT FIVE COMMA",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0035, 0x002C },
+ unicodeslot=0x1F106,
+ },
+ [0x1F107]={
+ category="no",
+ cjkwd="a",
+ description="DIGIT SIX COMMA",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0036, 0x002C },
+ unicodeslot=0x1F107,
+ },
+ [0x1F108]={
+ category="no",
+ cjkwd="a",
+ description="DIGIT SEVEN COMMA",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0037, 0x002C },
+ unicodeslot=0x1F108,
+ },
+ [0x1F109]={
+ category="no",
+ cjkwd="a",
+ description="DIGIT EIGHT COMMA",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0038, 0x002C },
+ unicodeslot=0x1F109,
+ },
+ [0x1F10A]={
+ category="no",
+ cjkwd="a",
+ description="DIGIT NINE COMMA",
+ direction="en",
+ linebreak="ai",
+ specials={ "compat", 0x0039, 0x002C },
+ unicodeslot=0x1F10A,
+ },
+ [0x1F110]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER A",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0041, 0x0029 },
+ unicodeslot=0x1F110,
+ },
+ [0x1F111]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER B",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0042, 0x0029 },
+ unicodeslot=0x1F111,
+ },
+ [0x1F112]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER C",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0043, 0x0029 },
+ unicodeslot=0x1F112,
+ },
+ [0x1F113]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER D",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0044, 0x0029 },
+ unicodeslot=0x1F113,
+ },
+ [0x1F114]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER E",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0045, 0x0029 },
+ unicodeslot=0x1F114,
+ },
+ [0x1F115]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER F",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0046, 0x0029 },
+ unicodeslot=0x1F115,
+ },
+ [0x1F116]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER G",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0047, 0x0029 },
+ unicodeslot=0x1F116,
+ },
+ [0x1F117]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER H",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0048, 0x0029 },
+ unicodeslot=0x1F117,
+ },
+ [0x1F118]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER I",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0049, 0x0029 },
+ unicodeslot=0x1F118,
+ },
+ [0x1F119]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER J",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x004A, 0x0029 },
+ unicodeslot=0x1F119,
+ },
+ [0x1F11A]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER K",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x004B, 0x0029 },
+ unicodeslot=0x1F11A,
+ },
+ [0x1F11B]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER L",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x004C, 0x0029 },
+ unicodeslot=0x1F11B,
+ },
+ [0x1F11C]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER M",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x004D, 0x0029 },
+ unicodeslot=0x1F11C,
+ },
+ [0x1F11D]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER N",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x004E, 0x0029 },
+ unicodeslot=0x1F11D,
+ },
+ [0x1F11E]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER O",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x004F, 0x0029 },
+ unicodeslot=0x1F11E,
+ },
+ [0x1F11F]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER P",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0050, 0x0029 },
+ unicodeslot=0x1F11F,
+ },
+ [0x1F120]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER Q",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0051, 0x0029 },
+ unicodeslot=0x1F120,
+ },
+ [0x1F121]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER R",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0052, 0x0029 },
+ unicodeslot=0x1F121,
+ },
+ [0x1F122]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER S",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0053, 0x0029 },
+ unicodeslot=0x1F122,
+ },
+ [0x1F123]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER T",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0054, 0x0029 },
+ unicodeslot=0x1F123,
+ },
+ [0x1F124]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER U",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0055, 0x0029 },
+ unicodeslot=0x1F124,
+ },
+ [0x1F125]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER V",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0056, 0x0029 },
+ unicodeslot=0x1F125,
+ },
+ [0x1F126]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER W",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0057, 0x0029 },
+ unicodeslot=0x1F126,
+ },
+ [0x1F127]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER X",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0058, 0x0029 },
+ unicodeslot=0x1F127,
+ },
+ [0x1F128]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER Y",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x0059, 0x0029 },
+ unicodeslot=0x1F128,
+ },
+ [0x1F129]={
+ category="so",
+ cjkwd="a",
+ description="PARENTHESIZED LATIN CAPITAL LETTER Z",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x0028, 0x005A, 0x0029 },
+ unicodeslot=0x1F129,
+ },
+ [0x1F12A]={
+ category="so",
+ cjkwd="a",
+ description="TORTOISE SHELL BRACKETED LATIN CAPITAL LETTER S",
+ direction="l",
+ linebreak="ai",
+ specials={ "compat", 0x3014, 0x0053, 0x3015 },
+ unicodeslot=0x1F12A,
+ },
+ [0x1F12B]={
+ category="so",
+ cjkwd="a",
+ description="CIRCLED ITALIC LATIN CAPITAL LETTER C",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0043 },
+ unicodeslot=0x1F12B,
+ },
+ [0x1F12C]={
+ category="so",
+ cjkwd="a",
+ description="CIRCLED ITALIC LATIN CAPITAL LETTER R",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0052 },
+ unicodeslot=0x1F12C,
+ },
+ [0x1F12D]={
+ category="so",
+ cjkwd="a",
+ description="CIRCLED CD",
+ direction="l",
+ linebreak="ai",
+ specials={ "circle", 0x0043, 0x0044 },
+ unicodeslot=0x1F12D,
+ },
+ [0x1F12E]={
+ category="so",
+ description="CIRCLED WZ",
+ direction="l",
+ linebreak="al",
+ specials={ "circle", 0x0057, 0x005A },
+ unicodeslot=0x1F12E,
+ },
+ [0x1F130]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER A",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0041 },
+ unicodeslot=0x1F130,
+ },
+ [0x1F131]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER B",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0042 },
+ unicodeslot=0x1F131,
+ },
+ [0x1F132]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER C",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0043 },
+ unicodeslot=0x1F132,
+ },
+ [0x1F133]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER D",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0044 },
+ unicodeslot=0x1F133,
+ },
+ [0x1F134]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER E",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0045 },
+ unicodeslot=0x1F134,
+ },
+ [0x1F135]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER F",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0046 },
+ unicodeslot=0x1F135,
+ },
+ [0x1F136]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER G",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0047 },
+ unicodeslot=0x1F136,
+ },
+ [0x1F137]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER H",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0048 },
+ unicodeslot=0x1F137,
+ },
+ [0x1F138]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER I",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0049 },
+ unicodeslot=0x1F138,
+ },
+ [0x1F139]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER J",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x004A },
+ unicodeslot=0x1F139,
+ },
+ [0x1F13A]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER K",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x004B },
+ unicodeslot=0x1F13A,
+ },
+ [0x1F13B]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER L",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x004C },
+ unicodeslot=0x1F13B,
+ },
+ [0x1F13C]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER M",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x004D },
+ unicodeslot=0x1F13C,
+ },
+ [0x1F13D]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER N",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x004E },
+ unicodeslot=0x1F13D,
+ },
+ [0x1F13E]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER O",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x004F },
+ unicodeslot=0x1F13E,
+ },
+ [0x1F13F]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER P",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0050 },
+ unicodeslot=0x1F13F,
+ },
+ [0x1F140]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER Q",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0051 },
+ unicodeslot=0x1F140,
+ },
+ [0x1F141]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER R",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0052 },
+ unicodeslot=0x1F141,
+ },
+ [0x1F142]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER S",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0053 },
+ unicodeslot=0x1F142,
+ },
+ [0x1F143]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER T",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0054 },
+ unicodeslot=0x1F143,
+ },
+ [0x1F144]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER U",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0055 },
+ unicodeslot=0x1F144,
+ },
+ [0x1F145]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER V",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0056 },
+ unicodeslot=0x1F145,
+ },
+ [0x1F146]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER W",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0057 },
+ unicodeslot=0x1F146,
+ },
+ [0x1F147]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER X",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0058 },
+ unicodeslot=0x1F147,
+ },
+ [0x1F148]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER Y",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0059 },
+ unicodeslot=0x1F148,
+ },
+ [0x1F149]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED LATIN CAPITAL LETTER Z",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x005A },
+ unicodeslot=0x1F149,
+ },
+ [0x1F14A]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED HV",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0048, 0x0056 },
+ unicodeslot=0x1F14A,
+ },
+ [0x1F14B]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED MV",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x004D, 0x0056 },
+ unicodeslot=0x1F14B,
+ },
+ [0x1F14C]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED SD",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0053, 0x0044 },
+ unicodeslot=0x1F14C,
+ },
+ [0x1F14D]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED SS",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0053, 0x0053 },
+ unicodeslot=0x1F14D,
+ },
+ [0x1F14E]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED PPV",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0050, 0x0050, 0x0056 },
+ unicodeslot=0x1F14E,
+ },
+ [0x1F14F]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED WC",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0057, 0x0043 },
+ unicodeslot=0x1F14F,
+ },
+ [0x1F150]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER A",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F150,
+ },
+ [0x1F151]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER B",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F151,
+ },
+ [0x1F152]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER C",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F152,
+ },
+ [0x1F153]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER D",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F153,
+ },
+ [0x1F154]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER E",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F154,
+ },
+ [0x1F155]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER F",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F155,
+ },
+ [0x1F156]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER G",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F156,
+ },
+ [0x1F157]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER H",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F157,
+ },
+ [0x1F158]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER I",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F158,
+ },
+ [0x1F159]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER J",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F159,
+ },
+ [0x1F15A]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER K",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F15A,
+ },
+ [0x1F15B]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER L",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F15B,
+ },
+ [0x1F15C]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER M",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F15C,
+ },
+ [0x1F15D]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER N",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F15D,
+ },
+ [0x1F15E]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER O",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F15E,
+ },
+ [0x1F15F]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER P",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F15F,
+ },
+ [0x1F160]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER Q",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F160,
+ },
+ [0x1F161]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER R",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F161,
+ },
+ [0x1F162]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER S",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F162,
+ },
+ [0x1F163]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER T",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F163,
+ },
+ [0x1F164]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER U",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F164,
+ },
+ [0x1F165]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER V",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F165,
+ },
+ [0x1F166]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER W",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F166,
+ },
+ [0x1F167]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER X",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F167,
+ },
+ [0x1F168]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER Y",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F168,
+ },
+ [0x1F169]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE CIRCLED LATIN CAPITAL LETTER Z",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F169,
+ },
+ [0x1F16A]={
+ category="so",
+ description="RAISED MC SIGN",
+ direction="on",
+ linebreak="al",
+ specials={ "super", 0x004D, 0x0043 },
+ unicodeslot=0x1F16A,
+ },
+ [0x1F16B]={
+ category="so",
+ description="RAISED MD SIGN",
+ direction="on",
+ linebreak="al",
+ specials={ "super", 0x004D, 0x0044 },
+ unicodeslot=0x1F16B,
+ },
+ [0x1F170]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER A",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F170,
+ },
+ [0x1F171]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER B",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F171,
+ },
+ [0x1F172]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER C",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F172,
+ },
+ [0x1F173]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER D",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F173,
+ },
+ [0x1F174]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER E",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F174,
+ },
+ [0x1F175]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER F",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F175,
+ },
+ [0x1F176]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER G",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F176,
+ },
+ [0x1F177]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER H",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F177,
+ },
+ [0x1F178]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER I",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F178,
+ },
+ [0x1F179]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER J",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F179,
+ },
+ [0x1F17A]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER K",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F17A,
+ },
+ [0x1F17B]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER L",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F17B,
+ },
+ [0x1F17C]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER M",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F17C,
+ },
+ [0x1F17D]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER N",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F17D,
+ },
+ [0x1F17E]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER O",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F17E,
+ },
+ [0x1F17F]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER P",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F17F,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x1F180]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER Q",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F180,
+ },
+ [0x1F181]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER R",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F181,
+ },
+ [0x1F182]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER S",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F182,
+ },
+ [0x1F183]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER T",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F183,
+ },
+ [0x1F184]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER U",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F184,
+ },
+ [0x1F185]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER V",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F185,
+ },
+ [0x1F186]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER W",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F186,
+ },
+ [0x1F187]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER X",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F187,
+ },
+ [0x1F188]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER Y",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F188,
+ },
+ [0x1F189]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED LATIN CAPITAL LETTER Z",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F189,
+ },
+ [0x1F18A]={
+ category="so",
+ cjkwd="a",
+ description="CROSSED NEGATIVE SQUARED LATIN CAPITAL LETTER P",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F18A,
+ },
+ [0x1F18B]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED IC",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F18B,
+ },
+ [0x1F18C]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED PA",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F18C,
+ },
+ [0x1F18D]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED SA",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F18D,
+ },
+ [0x1F18E]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED AB",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F18E,
+ },
+ [0x1F18F]={
+ category="so",
+ cjkwd="a",
+ description="NEGATIVE SQUARED WC",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F18F,
+ },
+ [0x1F190]={
+ category="so",
+ cjkwd="a",
+ description="SQUARE DJ",
+ direction="l",
+ linebreak="ai",
+ specials={ "square", 0x0044, 0x004A },
+ unicodeslot=0x1F190,
+ },
+ [0x1F191]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED CL",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F191,
+ },
+ [0x1F192]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED COOL",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F192,
+ },
+ [0x1F193]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED FREE",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F193,
+ },
+ [0x1F194]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED ID",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F194,
+ },
+ [0x1F195]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED NEW",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F195,
+ },
+ [0x1F196]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED NG",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F196,
+ },
+ [0x1F197]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED OK",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F197,
+ },
+ [0x1F198]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED SOS",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F198,
+ },
+ [0x1F199]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED UP WITH EXCLAMATION MARK",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F199,
+ },
+ [0x1F19A]={
+ category="so",
+ cjkwd="a",
+ description="SQUARED VS",
+ direction="l",
+ linebreak="ai",
+ unicodeslot=0x1F19A,
+ },
+ [0x1F1E6]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER A",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1E6,
+ },
+ [0x1F1E7]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER B",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1E7,
+ },
+ [0x1F1E8]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER C",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1E8,
+ },
+ [0x1F1E9]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER D",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1E9,
+ },
+ [0x1F1EA]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER E",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1EA,
+ },
+ [0x1F1EB]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER F",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1EB,
+ },
+ [0x1F1EC]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER G",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1EC,
+ },
+ [0x1F1ED]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER H",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1ED,
+ },
+ [0x1F1EE]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER I",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1EE,
+ },
+ [0x1F1EF]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER J",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1EF,
+ },
+ [0x1F1F0]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER K",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F0,
+ },
+ [0x1F1F1]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER L",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F1,
+ },
+ [0x1F1F2]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER M",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F2,
+ },
+ [0x1F1F3]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER N",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F3,
+ },
+ [0x1F1F4]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER O",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F4,
+ },
+ [0x1F1F5]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER P",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F5,
+ },
+ [0x1F1F6]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER Q",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F6,
+ },
+ [0x1F1F7]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER R",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F7,
+ },
+ [0x1F1F8]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER S",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F8,
+ },
+ [0x1F1F9]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER T",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1F9,
+ },
+ [0x1F1FA]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER U",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1FA,
+ },
+ [0x1F1FB]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER V",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1FB,
+ },
+ [0x1F1FC]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER W",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1FC,
+ },
+ [0x1F1FD]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER X",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1FD,
+ },
+ [0x1F1FE]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER Y",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1FE,
+ },
+ [0x1F1FF]={
+ category="so",
+ description="REGIONAL INDICATOR SYMBOL LETTER Z",
+ direction="l",
+ linebreak="ri",
+ unicodeslot=0x1F1FF,
+ },
+ [0x1F200]={
+ category="so",
+ cjkwd="w",
+ description="SQUARE HIRAGANA HOKA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x307B, 0x304B },
+ unicodeslot=0x1F200,
+ },
+ [0x1F201]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED KATAKANA KOKO",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B3, 0x30B3 },
+ unicodeslot=0x1F201,
+ },
+ [0x1F202]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED KATAKANA SA",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30B5 },
+ unicodeslot=0x1F202,
+ },
+ [0x1F210]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-624B",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x624B },
+ unicodeslot=0x1F210,
+ },
+ [0x1F211]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-5B57",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5B57 },
+ unicodeslot=0x1F211,
+ },
+ [0x1F212]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-53CC",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x53CC },
+ unicodeslot=0x1F212,
+ },
+ [0x1F213]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED KATAKANA DE",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x30C7 },
+ unicodeslot=0x1F213,
+ },
+ [0x1F214]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-4E8C",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4E8C },
+ unicodeslot=0x1F214,
+ },
+ [0x1F215]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-591A",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x591A },
+ unicodeslot=0x1F215,
+ },
+ [0x1F216]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-89E3",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x89E3 },
+ unicodeslot=0x1F216,
+ },
+ [0x1F217]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-5929",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5929 },
+ unicodeslot=0x1F217,
+ },
+ [0x1F218]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-4EA4",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4EA4 },
+ unicodeslot=0x1F218,
+ },
+ [0x1F219]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-6620",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6620 },
+ unicodeslot=0x1F219,
+ },
+ [0x1F21A]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-7121",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x7121 },
+ unicodeslot=0x1F21A,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x1F21B]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-6599",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6599 },
+ unicodeslot=0x1F21B,
+ },
+ [0x1F21C]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-524D",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x524D },
+ unicodeslot=0x1F21C,
+ },
+ [0x1F21D]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-5F8C",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5F8C },
+ unicodeslot=0x1F21D,
+ },
+ [0x1F21E]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-518D",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x518D },
+ unicodeslot=0x1F21E,
+ },
+ [0x1F21F]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-65B0",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x65B0 },
+ unicodeslot=0x1F21F,
+ },
+ [0x1F220]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-521D",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x521D },
+ unicodeslot=0x1F220,
+ },
+ [0x1F221]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-7D42",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x7D42 },
+ unicodeslot=0x1F221,
+ },
+ [0x1F222]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-751F",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x751F },
+ unicodeslot=0x1F222,
+ },
+ [0x1F223]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-8CA9",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x8CA9 },
+ unicodeslot=0x1F223,
+ },
+ [0x1F224]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-58F0",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x58F0 },
+ unicodeslot=0x1F224,
+ },
+ [0x1F225]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-5439",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5439 },
+ unicodeslot=0x1F225,
+ },
+ [0x1F226]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-6F14",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6F14 },
+ unicodeslot=0x1F226,
+ },
+ [0x1F227]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-6295",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6295 },
+ unicodeslot=0x1F227,
+ },
+ [0x1F228]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-6355",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6355 },
+ unicodeslot=0x1F228,
+ },
+ [0x1F229]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-4E00",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4E00 },
+ unicodeslot=0x1F229,
+ },
+ [0x1F22A]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-4E09",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4E09 },
+ unicodeslot=0x1F22A,
+ },
+ [0x1F22B]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-904A",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x904A },
+ unicodeslot=0x1F22B,
+ },
+ [0x1F22C]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-5DE6",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5DE6 },
+ unicodeslot=0x1F22C,
+ },
+ [0x1F22D]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-4E2D",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x4E2D },
+ unicodeslot=0x1F22D,
+ },
+ [0x1F22E]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-53F3",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x53F3 },
+ unicodeslot=0x1F22E,
+ },
+ [0x1F22F]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-6307",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6307 },
+ unicodeslot=0x1F22F,
+ variants={
+ [0xFE0E]="text style",
+ [0xFE0F]="emoji style",
+ },
+ },
+ [0x1F230]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-8D70",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x8D70 },
+ unicodeslot=0x1F230,
+ },
+ [0x1F231]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-6253",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6253 },
+ unicodeslot=0x1F231,
+ },
+ [0x1F232]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-7981",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x7981 },
+ unicodeslot=0x1F232,
+ },
+ [0x1F233]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-7A7A",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x7A7A },
+ unicodeslot=0x1F233,
+ },
+ [0x1F234]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-5408",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5408 },
+ unicodeslot=0x1F234,
+ },
+ [0x1F235]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-6E80",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6E80 },
+ unicodeslot=0x1F235,
+ },
+ [0x1F236]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-6709",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6709 },
+ unicodeslot=0x1F236,
+ },
+ [0x1F237]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-6708",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x6708 },
+ unicodeslot=0x1F237,
+ },
+ [0x1F238]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-7533",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x7533 },
+ unicodeslot=0x1F238,
+ },
+ [0x1F239]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-5272",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x5272 },
+ unicodeslot=0x1F239,
+ },
+ [0x1F23A]={
+ category="so",
+ cjkwd="w",
+ description="SQUARED CJK UNIFIED IDEOGRAPH-55B6",
+ direction="l",
+ linebreak="id",
+ specials={ "square", 0x55B6 },
+ unicodeslot=0x1F23A,
+ },
+ [0x1F240]={
+ category="so",
+ cjkwd="w",
+ description="TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x672C, 0x3015 },
+ unicodeslot=0x1F240,
+ },
+ [0x1F241]={
+ category="so",
+ cjkwd="w",
+ description="TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x4E09, 0x3015 },
+ unicodeslot=0x1F241,
+ },
+ [0x1F242]={
+ category="so",
+ cjkwd="w",
+ description="TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E8C",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x4E8C, 0x3015 },
+ unicodeslot=0x1F242,
+ },
+ [0x1F243]={
+ category="so",
+ cjkwd="w",
+ description="TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-5B89",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x5B89, 0x3015 },
+ unicodeslot=0x1F243,
+ },
+ [0x1F244]={
+ category="so",
+ cjkwd="w",
+ description="TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-70B9",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x70B9, 0x3015 },
+ unicodeslot=0x1F244,
+ },
+ [0x1F245]={
+ category="so",
+ cjkwd="w",
+ description="TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6253",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x6253, 0x3015 },
+ unicodeslot=0x1F245,
+ },
+ [0x1F246]={
+ category="so",
+ cjkwd="w",
+ description="TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-76D7",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x76D7, 0x3015 },
+ unicodeslot=0x1F246,
+ },
+ [0x1F247]={
+ category="so",
+ cjkwd="w",
+ description="TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-52DD",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x52DD, 0x3015 },
+ unicodeslot=0x1F247,
+ },
+ [0x1F248]={
+ category="so",
+ cjkwd="w",
+ description="TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557",
+ direction="l",
+ linebreak="id",
+ specials={ "compat", 0x3014, 0x6557, 0x3015 },
+ unicodeslot=0x1F248,
+ },
+ [0x1F250]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH ADVANTAGE",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x5F97 },
+ unicodeslot=0x1F250,
+ },
+ [0x1F251]={
+ category="so",
+ cjkwd="w",
+ description="CIRCLED IDEOGRAPH ACCEPT",
+ direction="l",
+ linebreak="id",
+ specials={ "circle", 0x53EF },
+ unicodeslot=0x1F251,
+ },
+ [0x1F300]={
+ category="so",
+ description="CYCLONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F300,
+ },
+ [0x1F301]={
+ category="so",
+ description="FOGGY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F301,
+ },
+ [0x1F302]={
+ category="so",
+ description="CLOSED UMBRELLA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F302,
+ },
+ [0x1F303]={
+ category="so",
+ description="NIGHT WITH STARS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F303,
+ },
+ [0x1F304]={
+ category="so",
+ description="SUNRISE OVER MOUNTAINS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F304,
+ },
+ [0x1F305]={
+ category="so",
+ description="SUNRISE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F305,
+ },
+ [0x1F306]={
+ category="so",
+ description="CITYSCAPE AT DUSK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F306,
+ },
+ [0x1F307]={
+ category="so",
+ description="SUNSET OVER BUILDINGS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F307,
+ },
+ [0x1F308]={
+ category="so",
+ description="RAINBOW",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F308,
+ },
+ [0x1F309]={
+ category="so",
+ description="BRIDGE AT NIGHT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F309,
+ },
+ [0x1F30A]={
+ category="so",
+ description="WATER WAVE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F30A,
+ },
+ [0x1F30B]={
+ category="so",
+ description="VOLCANO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F30B,
+ },
+ [0x1F30C]={
+ category="so",
+ description="MILKY WAY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F30C,
+ },
+ [0x1F30D]={
+ category="so",
+ description="EARTH GLOBE EUROPE-AFRICA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F30D,
+ },
+ [0x1F30E]={
+ category="so",
+ description="EARTH GLOBE AMERICAS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F30E,
+ },
+ [0x1F30F]={
+ category="so",
+ description="EARTH GLOBE ASIA-AUSTRALIA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F30F,
+ },
+ [0x1F310]={
+ category="so",
+ description="GLOBE WITH MERIDIANS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F310,
+ },
+ [0x1F311]={
+ category="so",
+ description="NEW MOON SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F311,
+ },
+ [0x1F312]={
+ category="so",
+ description="WAXING CRESCENT MOON SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F312,
+ },
+ [0x1F313]={
+ category="so",
+ description="FIRST QUARTER MOON SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F313,
+ },
+ [0x1F314]={
+ category="so",
+ description="WAXING GIBBOUS MOON SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F314,
+ },
+ [0x1F315]={
+ category="so",
+ description="FULL MOON SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F315,
+ },
+ [0x1F316]={
+ category="so",
+ description="WANING GIBBOUS MOON SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F316,
+ },
+ [0x1F317]={
+ category="so",
+ description="LAST QUARTER MOON SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F317,
+ },
+ [0x1F318]={
+ category="so",
+ description="WANING CRESCENT MOON SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F318,
+ },
+ [0x1F319]={
+ category="so",
+ description="CRESCENT MOON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F319,
+ },
+ [0x1F31A]={
+ category="so",
+ description="NEW MOON WITH FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F31A,
+ },
+ [0x1F31B]={
+ category="so",
+ description="FIRST QUARTER MOON WITH FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F31B,
+ },
+ [0x1F31C]={
+ category="so",
+ description="LAST QUARTER MOON WITH FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F31C,
+ },
+ [0x1F31D]={
+ category="so",
+ description="FULL MOON WITH FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F31D,
+ },
+ [0x1F31E]={
+ category="so",
+ description="SUN WITH FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F31E,
+ },
+ [0x1F31F]={
+ category="so",
+ description="GLOWING STAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F31F,
+ },
+ [0x1F320]={
+ category="so",
+ description="SHOOTING STAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F320,
+ },
+ [0x1F330]={
+ category="so",
+ description="CHESTNUT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F330,
+ },
+ [0x1F331]={
+ category="so",
+ description="SEEDLING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F331,
+ },
+ [0x1F332]={
+ category="so",
+ description="EVERGREEN TREE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F332,
+ },
+ [0x1F333]={
+ category="so",
+ description="DECIDUOUS TREE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F333,
+ },
+ [0x1F334]={
+ category="so",
+ description="PALM TREE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F334,
+ },
+ [0x1F335]={
+ category="so",
+ description="CACTUS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F335,
+ },
+ [0x1F337]={
+ category="so",
+ description="TULIP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F337,
+ },
+ [0x1F338]={
+ category="so",
+ description="CHERRY BLOSSOM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F338,
+ },
+ [0x1F339]={
+ category="so",
+ description="ROSE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F339,
+ },
+ [0x1F33A]={
+ category="so",
+ description="HIBISCUS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F33A,
+ },
+ [0x1F33B]={
+ category="so",
+ description="SUNFLOWER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F33B,
+ },
+ [0x1F33C]={
+ category="so",
+ description="BLOSSOM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F33C,
+ },
+ [0x1F33D]={
+ category="so",
+ description="EAR OF MAIZE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F33D,
+ },
+ [0x1F33E]={
+ category="so",
+ description="EAR OF RICE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F33E,
+ },
+ [0x1F33F]={
+ category="so",
+ description="HERB",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F33F,
+ },
+ [0x1F340]={
+ category="so",
+ description="FOUR LEAF CLOVER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F340,
+ },
+ [0x1F341]={
+ category="so",
+ description="MAPLE LEAF",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F341,
+ },
+ [0x1F342]={
+ category="so",
+ description="FALLEN LEAF",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F342,
+ },
+ [0x1F343]={
+ category="so",
+ description="LEAF FLUTTERING IN WIND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F343,
+ },
+ [0x1F344]={
+ category="so",
+ description="MUSHROOM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F344,
+ },
+ [0x1F345]={
+ category="so",
+ description="TOMATO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F345,
+ },
+ [0x1F346]={
+ category="so",
+ description="AUBERGINE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F346,
+ },
+ [0x1F347]={
+ category="so",
+ description="GRAPES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F347,
+ },
+ [0x1F348]={
+ category="so",
+ description="MELON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F348,
+ },
+ [0x1F349]={
+ category="so",
+ description="WATERMELON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F349,
+ },
+ [0x1F34A]={
+ category="so",
+ description="TANGERINE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F34A,
+ },
+ [0x1F34B]={
+ category="so",
+ description="LEMON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F34B,
+ },
+ [0x1F34C]={
+ category="so",
+ description="BANANA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F34C,
+ },
+ [0x1F34D]={
+ category="so",
+ description="PINEAPPLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F34D,
+ },
+ [0x1F34E]={
+ category="so",
+ description="RED APPLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F34E,
+ },
+ [0x1F34F]={
+ category="so",
+ description="GREEN APPLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F34F,
+ },
+ [0x1F350]={
+ category="so",
+ description="PEAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F350,
+ },
+ [0x1F351]={
+ category="so",
+ description="PEACH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F351,
+ },
+ [0x1F352]={
+ category="so",
+ description="CHERRIES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F352,
+ },
+ [0x1F353]={
+ category="so",
+ description="STRAWBERRY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F353,
+ },
+ [0x1F354]={
+ category="so",
+ description="HAMBURGER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F354,
+ },
+ [0x1F355]={
+ category="so",
+ description="SLICE OF PIZZA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F355,
+ },
+ [0x1F356]={
+ category="so",
+ description="MEAT ON BONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F356,
+ },
+ [0x1F357]={
+ category="so",
+ description="POULTRY LEG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F357,
+ },
+ [0x1F358]={
+ category="so",
+ description="RICE CRACKER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F358,
+ },
+ [0x1F359]={
+ category="so",
+ description="RICE BALL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F359,
+ },
+ [0x1F35A]={
+ category="so",
+ description="COOKED RICE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F35A,
+ },
+ [0x1F35B]={
+ category="so",
+ description="CURRY AND RICE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F35B,
+ },
+ [0x1F35C]={
+ category="so",
+ description="STEAMING BOWL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F35C,
+ },
+ [0x1F35D]={
+ category="so",
+ description="SPAGHETTI",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F35D,
+ },
+ [0x1F35E]={
+ category="so",
+ description="BREAD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F35E,
+ },
+ [0x1F35F]={
+ category="so",
+ description="FRENCH FRIES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F35F,
+ },
+ [0x1F360]={
+ category="so",
+ description="ROASTED SWEET POTATO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F360,
+ },
+ [0x1F361]={
+ category="so",
+ description="DANGO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F361,
+ },
+ [0x1F362]={
+ category="so",
+ description="ODEN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F362,
+ },
+ [0x1F363]={
+ category="so",
+ description="SUSHI",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F363,
+ },
+ [0x1F364]={
+ category="so",
+ description="FRIED SHRIMP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F364,
+ },
+ [0x1F365]={
+ category="so",
+ description="FISH CAKE WITH SWIRL DESIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F365,
+ },
+ [0x1F366]={
+ category="so",
+ description="SOFT ICE CREAM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F366,
+ },
+ [0x1F367]={
+ category="so",
+ description="SHAVED ICE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F367,
+ },
+ [0x1F368]={
+ category="so",
+ description="ICE CREAM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F368,
+ },
+ [0x1F369]={
+ category="so",
+ description="DOUGHNUT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F369,
+ },
+ [0x1F36A]={
+ category="so",
+ description="COOKIE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F36A,
+ },
+ [0x1F36B]={
+ category="so",
+ description="CHOCOLATE BAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F36B,
+ },
+ [0x1F36C]={
+ category="so",
+ description="CANDY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F36C,
+ },
+ [0x1F36D]={
+ category="so",
+ description="LOLLIPOP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F36D,
+ },
+ [0x1F36E]={
+ category="so",
+ description="CUSTARD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F36E,
+ },
+ [0x1F36F]={
+ category="so",
+ description="HONEY POT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F36F,
+ },
+ [0x1F370]={
+ category="so",
+ description="SHORTCAKE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F370,
+ },
+ [0x1F371]={
+ category="so",
+ description="BENTO BOX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F371,
+ },
+ [0x1F372]={
+ category="so",
+ description="POT OF FOOD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F372,
+ },
+ [0x1F373]={
+ category="so",
+ description="COOKING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F373,
+ },
+ [0x1F374]={
+ category="so",
+ description="FORK AND KNIFE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F374,
+ },
+ [0x1F375]={
+ category="so",
+ description="TEACUP WITHOUT HANDLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F375,
+ },
+ [0x1F376]={
+ category="so",
+ description="SAKE BOTTLE AND CUP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F376,
+ },
+ [0x1F377]={
+ category="so",
+ description="WINE GLASS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F377,
+ },
+ [0x1F378]={
+ category="so",
+ description="COCKTAIL GLASS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F378,
+ },
+ [0x1F379]={
+ category="so",
+ description="TROPICAL DRINK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F379,
+ },
+ [0x1F37A]={
+ category="so",
+ description="BEER MUG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F37A,
+ },
+ [0x1F37B]={
+ category="so",
+ description="CLINKING BEER MUGS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F37B,
+ },
+ [0x1F37C]={
+ category="so",
+ description="BABY BOTTLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F37C,
+ },
+ [0x1F380]={
+ category="so",
+ description="RIBBON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F380,
+ },
+ [0x1F381]={
+ category="so",
+ description="WRAPPED PRESENT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F381,
+ },
+ [0x1F382]={
+ category="so",
+ description="BIRTHDAY CAKE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F382,
+ },
+ [0x1F383]={
+ category="so",
+ description="JACK-O-LANTERN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F383,
+ },
+ [0x1F384]={
+ category="so",
+ description="CHRISTMAS TREE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F384,
+ },
+ [0x1F385]={
+ category="so",
+ description="FATHER CHRISTMAS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F385,
+ },
+ [0x1F386]={
+ category="so",
+ description="FIREWORKS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F386,
+ },
+ [0x1F387]={
+ category="so",
+ description="FIREWORK SPARKLER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F387,
+ },
+ [0x1F388]={
+ category="so",
+ description="BALLOON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F388,
+ },
+ [0x1F389]={
+ category="so",
+ description="PARTY POPPER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F389,
+ },
+ [0x1F38A]={
+ category="so",
+ description="CONFETTI BALL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F38A,
+ },
+ [0x1F38B]={
+ category="so",
+ description="TANABATA TREE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F38B,
+ },
+ [0x1F38C]={
+ category="so",
+ description="CROSSED FLAGS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F38C,
+ },
+ [0x1F38D]={
+ category="so",
+ description="PINE DECORATION",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F38D,
+ },
+ [0x1F38E]={
+ category="so",
+ description="JAPANESE DOLLS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F38E,
+ },
+ [0x1F38F]={
+ category="so",
+ description="CARP STREAMER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F38F,
+ },
+ [0x1F390]={
+ category="so",
+ description="WIND CHIME",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F390,
+ },
+ [0x1F391]={
+ category="so",
+ description="MOON VIEWING CEREMONY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F391,
+ },
+ [0x1F392]={
+ category="so",
+ description="SCHOOL SATCHEL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F392,
+ },
+ [0x1F393]={
+ category="so",
+ description="GRADUATION CAP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F393,
+ },
+ [0x1F3A0]={
+ category="so",
+ description="CAROUSEL HORSE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A0,
+ },
+ [0x1F3A1]={
+ category="so",
+ description="FERRIS WHEEL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A1,
+ },
+ [0x1F3A2]={
+ category="so",
+ description="ROLLER COASTER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A2,
+ },
+ [0x1F3A3]={
+ category="so",
+ description="FISHING POLE AND FISH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A3,
+ },
+ [0x1F3A4]={
+ category="so",
+ description="MICROPHONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A4,
+ },
+ [0x1F3A5]={
+ category="so",
+ description="MOVIE CAMERA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A5,
+ },
+ [0x1F3A6]={
+ category="so",
+ description="CINEMA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A6,
+ },
+ [0x1F3A7]={
+ category="so",
+ description="HEADPHONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A7,
+ },
+ [0x1F3A8]={
+ category="so",
+ description="ARTIST PALETTE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A8,
+ },
+ [0x1F3A9]={
+ category="so",
+ description="TOP HAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3A9,
+ },
+ [0x1F3AA]={
+ category="so",
+ description="CIRCUS TENT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3AA,
+ },
+ [0x1F3AB]={
+ category="so",
+ description="TICKET",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3AB,
+ },
+ [0x1F3AC]={
+ category="so",
+ description="CLAPPER BOARD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3AC,
+ },
+ [0x1F3AD]={
+ category="so",
+ description="PERFORMING ARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3AD,
+ },
+ [0x1F3AE]={
+ category="so",
+ description="VIDEO GAME",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3AE,
+ },
+ [0x1F3AF]={
+ category="so",
+ description="DIRECT HIT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3AF,
+ },
+ [0x1F3B0]={
+ category="so",
+ description="SLOT MACHINE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B0,
+ },
+ [0x1F3B1]={
+ category="so",
+ description="BILLIARDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B1,
+ },
+ [0x1F3B2]={
+ category="so",
+ description="GAME DIE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B2,
+ },
+ [0x1F3B3]={
+ category="so",
+ description="BOWLING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B3,
+ },
+ [0x1F3B4]={
+ category="so",
+ description="FLOWER PLAYING CARDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B4,
+ },
+ [0x1F3B5]={
+ category="so",
+ description="MUSICAL NOTE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F3B5,
+ },
+ [0x1F3B6]={
+ category="so",
+ description="MULTIPLE MUSICAL NOTES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F3B6,
+ },
+ [0x1F3B7]={
+ category="so",
+ description="SAXOPHONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B7,
+ },
+ [0x1F3B8]={
+ category="so",
+ description="GUITAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B8,
+ },
+ [0x1F3B9]={
+ category="so",
+ description="MUSICAL KEYBOARD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3B9,
+ },
+ [0x1F3BA]={
+ category="so",
+ description="TRUMPET",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3BA,
+ },
+ [0x1F3BB]={
+ category="so",
+ description="VIOLIN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3BB,
+ },
+ [0x1F3BC]={
+ category="so",
+ description="MUSICAL SCORE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F3BC,
+ },
+ [0x1F3BD]={
+ category="so",
+ description="RUNNING SHIRT WITH SASH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3BD,
+ },
+ [0x1F3BE]={
+ category="so",
+ description="TENNIS RACQUET AND BALL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3BE,
+ },
+ [0x1F3BF]={
+ category="so",
+ description="SKI AND SKI BOOT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3BF,
+ },
+ [0x1F3C0]={
+ category="so",
+ description="BASKETBALL AND HOOP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C0,
+ },
+ [0x1F3C1]={
+ category="so",
+ description="CHEQUERED FLAG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C1,
+ },
+ [0x1F3C2]={
+ category="so",
+ description="SNOWBOARDER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C2,
+ },
+ [0x1F3C3]={
+ category="so",
+ description="RUNNER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C3,
+ },
+ [0x1F3C4]={
+ category="so",
+ description="SURFER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C4,
+ },
+ [0x1F3C6]={
+ category="so",
+ description="TROPHY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C6,
+ },
+ [0x1F3C7]={
+ category="so",
+ description="HORSE RACING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C7,
+ },
+ [0x1F3C8]={
+ category="so",
+ description="AMERICAN FOOTBALL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C8,
+ },
+ [0x1F3C9]={
+ category="so",
+ description="RUGBY FOOTBALL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3C9,
+ },
+ [0x1F3CA]={
+ category="so",
+ description="SWIMMER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3CA,
+ },
+ [0x1F3E0]={
+ category="so",
+ description="HOUSE BUILDING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E0,
+ },
+ [0x1F3E1]={
+ category="so",
+ description="HOUSE WITH GARDEN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E1,
+ },
+ [0x1F3E2]={
+ category="so",
+ description="OFFICE BUILDING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E2,
+ },
+ [0x1F3E3]={
+ category="so",
+ description="JAPANESE POST OFFICE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E3,
+ },
+ [0x1F3E4]={
+ category="so",
+ description="EUROPEAN POST OFFICE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E4,
+ },
+ [0x1F3E5]={
+ category="so",
+ description="HOSPITAL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E5,
+ },
+ [0x1F3E6]={
+ category="so",
+ description="BANK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E6,
+ },
+ [0x1F3E7]={
+ category="so",
+ description="AUTOMATED TELLER MACHINE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E7,
+ },
+ [0x1F3E8]={
+ category="so",
+ description="HOTEL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E8,
+ },
+ [0x1F3E9]={
+ category="so",
+ description="LOVE HOTEL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3E9,
+ },
+ [0x1F3EA]={
+ category="so",
+ description="CONVENIENCE STORE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3EA,
+ },
+ [0x1F3EB]={
+ category="so",
+ description="SCHOOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3EB,
+ },
+ [0x1F3EC]={
+ category="so",
+ description="DEPARTMENT STORE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3EC,
+ },
+ [0x1F3ED]={
+ category="so",
+ description="FACTORY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3ED,
+ },
+ [0x1F3EE]={
+ category="so",
+ description="IZAKAYA LANTERN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3EE,
+ },
+ [0x1F3EF]={
+ category="so",
+ description="JAPANESE CASTLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3EF,
+ },
+ [0x1F3F0]={
+ category="so",
+ description="EUROPEAN CASTLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F3F0,
+ },
+ [0x1F400]={
+ category="so",
+ description="RAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F400,
+ },
+ [0x1F401]={
+ category="so",
+ description="MOUSE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F401,
+ },
+ [0x1F402]={
+ category="so",
+ description="OX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F402,
+ },
+ [0x1F403]={
+ category="so",
+ description="WATER BUFFALO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F403,
+ },
+ [0x1F404]={
+ category="so",
+ description="COW",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F404,
+ },
+ [0x1F405]={
+ category="so",
+ description="TIGER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F405,
+ },
+ [0x1F406]={
+ category="so",
+ description="LEOPARD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F406,
+ },
+ [0x1F407]={
+ category="so",
+ description="RABBIT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F407,
+ },
+ [0x1F408]={
+ category="so",
+ description="CAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F408,
+ },
+ [0x1F409]={
+ category="so",
+ description="DRAGON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F409,
+ },
+ [0x1F40A]={
+ category="so",
+ description="CROCODILE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F40A,
+ },
+ [0x1F40B]={
+ category="so",
+ description="WHALE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F40B,
+ },
+ [0x1F40C]={
+ category="so",
+ description="SNAIL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F40C,
+ },
+ [0x1F40D]={
+ category="so",
+ description="SNAKE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F40D,
+ },
+ [0x1F40E]={
+ category="so",
+ description="HORSE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F40E,
+ },
+ [0x1F40F]={
+ category="so",
+ description="RAM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F40F,
+ },
+ [0x1F410]={
+ category="so",
+ description="GOAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F410,
+ },
+ [0x1F411]={
+ category="so",
+ description="SHEEP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F411,
+ },
+ [0x1F412]={
+ category="so",
+ description="MONKEY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F412,
+ },
+ [0x1F413]={
+ category="so",
+ description="ROOSTER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F413,
+ },
+ [0x1F414]={
+ category="so",
+ description="CHICKEN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F414,
+ },
+ [0x1F415]={
+ category="so",
+ description="DOG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F415,
+ },
+ [0x1F416]={
+ category="so",
+ description="PIG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F416,
+ },
+ [0x1F417]={
+ category="so",
+ description="BOAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F417,
+ },
+ [0x1F418]={
+ category="so",
+ description="ELEPHANT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F418,
+ },
+ [0x1F419]={
+ category="so",
+ description="OCTOPUS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F419,
+ },
+ [0x1F41A]={
+ category="so",
+ description="SPIRAL SHELL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F41A,
+ },
+ [0x1F41B]={
+ category="so",
+ description="BUG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F41B,
+ },
+ [0x1F41C]={
+ category="so",
+ description="ANT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F41C,
+ },
+ [0x1F41D]={
+ category="so",
+ description="HONEYBEE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F41D,
+ },
+ [0x1F41E]={
+ category="so",
+ description="LADY BEETLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F41E,
+ },
+ [0x1F41F]={
+ category="so",
+ description="FISH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F41F,
+ },
+ [0x1F420]={
+ category="so",
+ description="TROPICAL FISH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F420,
+ },
+ [0x1F421]={
+ category="so",
+ description="BLOWFISH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F421,
+ },
+ [0x1F422]={
+ category="so",
+ description="TURTLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F422,
+ },
+ [0x1F423]={
+ category="so",
+ description="HATCHING CHICK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F423,
+ },
+ [0x1F424]={
+ category="so",
+ description="BABY CHICK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F424,
+ },
+ [0x1F425]={
+ category="so",
+ description="FRONT-FACING BABY CHICK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F425,
+ },
+ [0x1F426]={
+ category="so",
+ description="BIRD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F426,
+ },
+ [0x1F427]={
+ category="so",
+ description="PENGUIN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F427,
+ },
+ [0x1F428]={
+ category="so",
+ description="KOALA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F428,
+ },
+ [0x1F429]={
+ category="so",
+ description="POODLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F429,
+ },
+ [0x1F42A]={
+ category="so",
+ description="DROMEDARY CAMEL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F42A,
+ },
+ [0x1F42B]={
+ category="so",
+ description="BACTRIAN CAMEL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F42B,
+ },
+ [0x1F42C]={
+ category="so",
+ description="DOLPHIN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F42C,
+ },
+ [0x1F42D]={
+ category="so",
+ description="MOUSE FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F42D,
+ },
+ [0x1F42E]={
+ category="so",
+ description="COW FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F42E,
+ },
+ [0x1F42F]={
+ category="so",
+ description="TIGER FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F42F,
+ },
+ [0x1F430]={
+ category="so",
+ description="RABBIT FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F430,
+ },
+ [0x1F431]={
+ category="so",
+ description="CAT FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F431,
+ },
+ [0x1F432]={
+ category="so",
+ description="DRAGON FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F432,
+ },
+ [0x1F433]={
+ category="so",
+ description="SPOUTING WHALE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F433,
+ },
+ [0x1F434]={
+ category="so",
+ description="HORSE FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F434,
+ },
+ [0x1F435]={
+ category="so",
+ description="MONKEY FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F435,
+ },
+ [0x1F436]={
+ category="so",
+ description="DOG FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F436,
+ },
+ [0x1F437]={
+ category="so",
+ description="PIG FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F437,
+ },
+ [0x1F438]={
+ category="so",
+ description="FROG FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F438,
+ },
+ [0x1F439]={
+ category="so",
+ description="HAMSTER FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F439,
+ },
+ [0x1F43A]={
+ category="so",
+ description="WOLF FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F43A,
+ },
+ [0x1F43B]={
+ category="so",
+ description="BEAR FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F43B,
+ },
+ [0x1F43C]={
+ category="so",
+ description="PANDA FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F43C,
+ },
+ [0x1F43D]={
+ category="so",
+ description="PIG NOSE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F43D,
+ },
+ [0x1F43E]={
+ category="so",
+ description="PAW PRINTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F43E,
+ },
+ [0x1F440]={
+ category="so",
+ description="EYES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F440,
+ },
+ [0x1F442]={
+ category="so",
+ description="EAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F442,
+ },
+ [0x1F443]={
+ category="so",
+ description="NOSE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F443,
+ },
+ [0x1F444]={
+ category="so",
+ description="MOUTH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F444,
+ },
+ [0x1F445]={
+ category="so",
+ description="TONGUE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F445,
+ },
+ [0x1F446]={
+ category="so",
+ description="WHITE UP POINTING BACKHAND INDEX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F446,
+ },
+ [0x1F447]={
+ category="so",
+ description="WHITE DOWN POINTING BACKHAND INDEX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F447,
+ },
+ [0x1F448]={
+ category="so",
+ description="WHITE LEFT POINTING BACKHAND INDEX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F448,
+ },
+ [0x1F449]={
+ category="so",
+ description="WHITE RIGHT POINTING BACKHAND INDEX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F449,
+ },
+ [0x1F44A]={
+ category="so",
+ description="FISTED HAND SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F44A,
+ },
+ [0x1F44B]={
+ category="so",
+ description="WAVING HAND SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F44B,
+ },
+ [0x1F44C]={
+ category="so",
+ description="OK HAND SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F44C,
+ },
+ [0x1F44D]={
+ category="so",
+ description="THUMBS UP SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F44D,
+ },
+ [0x1F44E]={
+ category="so",
+ description="THUMBS DOWN SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F44E,
+ },
+ [0x1F44F]={
+ category="so",
+ description="CLAPPING HANDS SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F44F,
+ },
+ [0x1F450]={
+ category="so",
+ description="OPEN HANDS SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F450,
+ },
+ [0x1F451]={
+ category="so",
+ description="CROWN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F451,
+ },
+ [0x1F452]={
+ category="so",
+ description="WOMANS HAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F452,
+ },
+ [0x1F453]={
+ category="so",
+ description="EYEGLASSES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F453,
+ },
+ [0x1F454]={
+ category="so",
+ description="NECKTIE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F454,
+ },
+ [0x1F455]={
+ category="so",
+ description="T-SHIRT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F455,
+ },
+ [0x1F456]={
+ category="so",
+ description="JEANS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F456,
+ },
+ [0x1F457]={
+ category="so",
+ description="DRESS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F457,
+ },
+ [0x1F458]={
+ category="so",
+ description="KIMONO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F458,
+ },
+ [0x1F459]={
+ category="so",
+ description="BIKINI",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F459,
+ },
+ [0x1F45A]={
+ category="so",
+ description="WOMANS CLOTHES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F45A,
+ },
+ [0x1F45B]={
+ category="so",
+ description="PURSE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F45B,
+ },
+ [0x1F45C]={
+ category="so",
+ description="HANDBAG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F45C,
+ },
+ [0x1F45D]={
+ category="so",
+ description="POUCH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F45D,
+ },
+ [0x1F45E]={
+ category="so",
+ description="MANS SHOE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F45E,
+ },
+ [0x1F45F]={
+ category="so",
+ description="ATHLETIC SHOE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F45F,
+ },
+ [0x1F460]={
+ category="so",
+ description="HIGH-HEELED SHOE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F460,
+ },
+ [0x1F461]={
+ category="so",
+ description="WOMANS SANDAL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F461,
+ },
+ [0x1F462]={
+ category="so",
+ description="WOMANS BOOTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F462,
+ },
+ [0x1F463]={
+ category="so",
+ description="FOOTPRINTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F463,
+ },
+ [0x1F464]={
+ category="so",
+ description="BUST IN SILHOUETTE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F464,
+ },
+ [0x1F465]={
+ category="so",
+ description="BUSTS IN SILHOUETTE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F465,
+ },
+ [0x1F466]={
+ category="so",
+ description="BOY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F466,
+ },
+ [0x1F467]={
+ category="so",
+ description="GIRL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F467,
+ },
+ [0x1F468]={
+ category="so",
+ description="MAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F468,
+ },
+ [0x1F469]={
+ category="so",
+ description="WOMAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F469,
+ },
+ [0x1F46A]={
+ category="so",
+ description="FAMILY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F46A,
+ },
+ [0x1F46B]={
+ category="so",
+ description="MAN AND WOMAN HOLDING HANDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F46B,
+ },
+ [0x1F46C]={
+ category="so",
+ description="TWO MEN HOLDING HANDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F46C,
+ },
+ [0x1F46D]={
+ category="so",
+ description="TWO WOMEN HOLDING HANDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F46D,
+ },
+ [0x1F46E]={
+ category="so",
+ description="POLICE OFFICER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F46E,
+ },
+ [0x1F46F]={
+ category="so",
+ description="WOMAN WITH BUNNY EARS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F46F,
+ },
+ [0x1F470]={
+ category="so",
+ description="BRIDE WITH VEIL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F470,
+ },
+ [0x1F471]={
+ category="so",
+ description="PERSON WITH BLOND HAIR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F471,
+ },
+ [0x1F472]={
+ category="so",
+ description="MAN WITH GUA PI MAO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F472,
+ },
+ [0x1F473]={
+ category="so",
+ description="MAN WITH TURBAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F473,
+ },
+ [0x1F474]={
+ category="so",
+ description="OLDER MAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F474,
+ },
+ [0x1F475]={
+ category="so",
+ description="OLDER WOMAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F475,
+ },
+ [0x1F476]={
+ category="so",
+ description="BABY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F476,
+ },
+ [0x1F477]={
+ category="so",
+ description="CONSTRUCTION WORKER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F477,
+ },
+ [0x1F478]={
+ category="so",
+ description="PRINCESS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F478,
+ },
+ [0x1F479]={
+ category="so",
+ description="JAPANESE OGRE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F479,
+ },
+ [0x1F47A]={
+ category="so",
+ description="JAPANESE GOBLIN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F47A,
+ },
+ [0x1F47B]={
+ category="so",
+ description="GHOST",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F47B,
+ },
+ [0x1F47C]={
+ category="so",
+ description="BABY ANGEL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F47C,
+ },
+ [0x1F47D]={
+ category="so",
+ description="EXTRATERRESTRIAL ALIEN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F47D,
+ },
+ [0x1F47E]={
+ category="so",
+ description="ALIEN MONSTER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F47E,
+ },
+ [0x1F47F]={
+ category="so",
+ description="IMP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F47F,
+ },
+ [0x1F480]={
+ category="so",
+ description="SKULL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F480,
+ },
+ [0x1F481]={
+ category="so",
+ description="INFORMATION DESK PERSON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F481,
+ },
+ [0x1F482]={
+ category="so",
+ description="GUARDSMAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F482,
+ },
+ [0x1F483]={
+ category="so",
+ description="DANCER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F483,
+ },
+ [0x1F484]={
+ category="so",
+ description="LIPSTICK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F484,
+ },
+ [0x1F485]={
+ category="so",
+ description="NAIL POLISH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F485,
+ },
+ [0x1F486]={
+ category="so",
+ description="FACE MASSAGE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F486,
+ },
+ [0x1F487]={
+ category="so",
+ description="HAIRCUT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F487,
+ },
+ [0x1F488]={
+ category="so",
+ description="BARBER POLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F488,
+ },
+ [0x1F489]={
+ category="so",
+ description="SYRINGE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F489,
+ },
+ [0x1F48A]={
+ category="so",
+ description="PILL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F48A,
+ },
+ [0x1F48B]={
+ category="so",
+ description="KISS MARK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F48B,
+ },
+ [0x1F48C]={
+ category="so",
+ description="LOVE LETTER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F48C,
+ },
+ [0x1F48D]={
+ category="so",
+ description="RING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F48D,
+ },
+ [0x1F48E]={
+ category="so",
+ description="GEM STONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F48E,
+ },
+ [0x1F48F]={
+ category="so",
+ description="KISS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F48F,
+ },
+ [0x1F490]={
+ category="so",
+ description="BOUQUET",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F490,
+ },
+ [0x1F491]={
+ category="so",
+ description="COUPLE WITH HEART",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F491,
+ },
+ [0x1F492]={
+ category="so",
+ description="WEDDING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F492,
+ },
+ [0x1F493]={
+ category="so",
+ description="BEATING HEART",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F493,
+ },
+ [0x1F494]={
+ category="so",
+ description="BROKEN HEART",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F494,
+ },
+ [0x1F495]={
+ category="so",
+ description="TWO HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F495,
+ },
+ [0x1F496]={
+ category="so",
+ description="SPARKLING HEART",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F496,
+ },
+ [0x1F497]={
+ category="so",
+ description="GROWING HEART",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F497,
+ },
+ [0x1F498]={
+ category="so",
+ description="HEART WITH ARROW",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F498,
+ },
+ [0x1F499]={
+ category="so",
+ description="BLUE HEART",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F499,
+ },
+ [0x1F49A]={
+ category="so",
+ description="GREEN HEART",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F49A,
+ },
+ [0x1F49B]={
+ category="so",
+ description="YELLOW HEART",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F49B,
+ },
+ [0x1F49C]={
+ category="so",
+ description="PURPLE HEART",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F49C,
+ },
+ [0x1F49D]={
+ category="so",
+ description="HEART WITH RIBBON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F49D,
+ },
+ [0x1F49E]={
+ category="so",
+ description="REVOLVING HEARTS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F49E,
+ },
+ [0x1F49F]={
+ category="so",
+ description="HEART DECORATION",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F49F,
+ },
+ [0x1F4A0]={
+ category="so",
+ description="DIAMOND SHAPE WITH A DOT INSIDE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F4A0,
+ },
+ [0x1F4A1]={
+ category="so",
+ description="ELECTRIC LIGHT BULB",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A1,
+ },
+ [0x1F4A2]={
+ category="so",
+ description="ANGER SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F4A2,
+ },
+ [0x1F4A3]={
+ category="so",
+ description="BOMB",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A3,
+ },
+ [0x1F4A4]={
+ category="so",
+ description="SLEEPING SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F4A4,
+ },
+ [0x1F4A5]={
+ category="so",
+ description="COLLISION SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A5,
+ },
+ [0x1F4A6]={
+ category="so",
+ description="SPLASHING SWEAT SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A6,
+ },
+ [0x1F4A7]={
+ category="so",
+ description="DROPLET",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A7,
+ },
+ [0x1F4A8]={
+ category="so",
+ description="DASH SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A8,
+ },
+ [0x1F4A9]={
+ category="so",
+ description="PILE OF POO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4A9,
+ },
+ [0x1F4AA]={
+ category="so",
+ description="FLEXED BICEPS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4AA,
+ },
+ [0x1F4AB]={
+ category="so",
+ description="DIZZY SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4AB,
+ },
+ [0x1F4AC]={
+ category="so",
+ description="SPEECH BALLOON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4AC,
+ },
+ [0x1F4AD]={
+ category="so",
+ description="THOUGHT BALLOON",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4AD,
+ },
+ [0x1F4AE]={
+ category="so",
+ description="WHITE FLOWER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4AE,
+ },
+ [0x1F4AF]={
+ category="so",
+ description="HUNDRED POINTS SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F4AF,
+ },
+ [0x1F4B0]={
+ category="so",
+ description="MONEY BAG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B0,
+ },
+ [0x1F4B1]={
+ category="so",
+ description="CURRENCY EXCHANGE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F4B1,
+ },
+ [0x1F4B2]={
+ category="so",
+ description="HEAVY DOLLAR SIGN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F4B2,
+ },
+ [0x1F4B3]={
+ category="so",
+ description="CREDIT CARD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B3,
+ },
+ [0x1F4B4]={
+ category="so",
+ description="BANKNOTE WITH YEN SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B4,
+ },
+ [0x1F4B5]={
+ category="so",
+ description="BANKNOTE WITH DOLLAR SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B5,
+ },
+ [0x1F4B6]={
+ category="so",
+ description="BANKNOTE WITH EURO SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B6,
+ },
+ [0x1F4B7]={
+ category="so",
+ description="BANKNOTE WITH POUND SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B7,
+ },
+ [0x1F4B8]={
+ category="so",
+ description="MONEY WITH WINGS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B8,
+ },
+ [0x1F4B9]={
+ category="so",
+ description="CHART WITH UPWARDS TREND AND YEN SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4B9,
+ },
+ [0x1F4BA]={
+ category="so",
+ description="SEAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4BA,
+ },
+ [0x1F4BB]={
+ category="so",
+ description="PERSONAL COMPUTER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4BB,
+ },
+ [0x1F4BC]={
+ category="so",
+ description="BRIEFCASE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4BC,
+ },
+ [0x1F4BD]={
+ category="so",
+ description="MINIDISC",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4BD,
+ },
+ [0x1F4BE]={
+ category="so",
+ description="FLOPPY DISK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4BE,
+ },
+ [0x1F4BF]={
+ category="so",
+ description="OPTICAL DISC",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4BF,
+ },
+ [0x1F4C0]={
+ category="so",
+ description="DVD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C0,
+ },
+ [0x1F4C1]={
+ category="so",
+ description="FILE FOLDER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C1,
+ },
+ [0x1F4C2]={
+ category="so",
+ description="OPEN FILE FOLDER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C2,
+ },
+ [0x1F4C3]={
+ category="so",
+ description="PAGE WITH CURL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C3,
+ },
+ [0x1F4C4]={
+ category="so",
+ description="PAGE FACING UP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C4,
+ },
+ [0x1F4C5]={
+ category="so",
+ description="CALENDAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C5,
+ },
+ [0x1F4C6]={
+ category="so",
+ description="TEAR-OFF CALENDAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C6,
+ },
+ [0x1F4C7]={
+ category="so",
+ description="CARD INDEX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C7,
+ },
+ [0x1F4C8]={
+ category="so",
+ description="CHART WITH UPWARDS TREND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C8,
+ },
+ [0x1F4C9]={
+ category="so",
+ description="CHART WITH DOWNWARDS TREND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4C9,
+ },
+ [0x1F4CA]={
+ category="so",
+ description="BAR CHART",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4CA,
+ },
+ [0x1F4CB]={
+ category="so",
+ description="CLIPBOARD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4CB,
+ },
+ [0x1F4CC]={
+ category="so",
+ description="PUSHPIN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4CC,
+ },
+ [0x1F4CD]={
+ category="so",
+ description="ROUND PUSHPIN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4CD,
+ },
+ [0x1F4CE]={
+ category="so",
+ description="PAPERCLIP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4CE,
+ },
+ [0x1F4CF]={
+ category="so",
+ description="STRAIGHT RULER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4CF,
+ },
+ [0x1F4D0]={
+ category="so",
+ description="TRIANGULAR RULER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D0,
+ },
+ [0x1F4D1]={
+ category="so",
+ description="BOOKMARK TABS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D1,
+ },
+ [0x1F4D2]={
+ category="so",
+ description="LEDGER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D2,
+ },
+ [0x1F4D3]={
+ category="so",
+ description="NOTEBOOK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D3,
+ },
+ [0x1F4D4]={
+ category="so",
+ description="NOTEBOOK WITH DECORATIVE COVER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D4,
+ },
+ [0x1F4D5]={
+ category="so",
+ description="CLOSED BOOK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D5,
+ },
+ [0x1F4D6]={
+ category="so",
+ description="OPEN BOOK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D6,
+ },
+ [0x1F4D7]={
+ category="so",
+ description="GREEN BOOK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D7,
+ },
+ [0x1F4D8]={
+ category="so",
+ description="BLUE BOOK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D8,
+ },
+ [0x1F4D9]={
+ category="so",
+ description="ORANGE BOOK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4D9,
+ },
+ [0x1F4DA]={
+ category="so",
+ description="BOOKS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4DA,
+ },
+ [0x1F4DB]={
+ category="so",
+ description="NAME BADGE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4DB,
+ },
+ [0x1F4DC]={
+ category="so",
+ description="SCROLL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4DC,
+ },
+ [0x1F4DD]={
+ category="so",
+ description="MEMO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4DD,
+ },
+ [0x1F4DE]={
+ category="so",
+ description="TELEPHONE RECEIVER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4DE,
+ },
+ [0x1F4DF]={
+ category="so",
+ description="PAGER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4DF,
+ },
+ [0x1F4E0]={
+ category="so",
+ description="FAX MACHINE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E0,
+ },
+ [0x1F4E1]={
+ category="so",
+ description="SATELLITE ANTENNA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E1,
+ },
+ [0x1F4E2]={
+ category="so",
+ description="PUBLIC ADDRESS LOUDSPEAKER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E2,
+ },
+ [0x1F4E3]={
+ category="so",
+ description="CHEERING MEGAPHONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E3,
+ },
+ [0x1F4E4]={
+ category="so",
+ description="OUTBOX TRAY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E4,
+ },
+ [0x1F4E5]={
+ category="so",
+ description="INBOX TRAY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E5,
+ },
+ [0x1F4E6]={
+ category="so",
+ description="PACKAGE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E6,
+ },
+ [0x1F4E7]={
+ category="so",
+ description="E-MAIL SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E7,
+ },
+ [0x1F4E8]={
+ category="so",
+ description="INCOMING ENVELOPE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E8,
+ },
+ [0x1F4E9]={
+ category="so",
+ description="ENVELOPE WITH DOWNWARDS ARROW ABOVE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4E9,
+ },
+ [0x1F4EA]={
+ category="so",
+ description="CLOSED MAILBOX WITH LOWERED FLAG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4EA,
+ },
+ [0x1F4EB]={
+ category="so",
+ description="CLOSED MAILBOX WITH RAISED FLAG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4EB,
+ },
+ [0x1F4EC]={
+ category="so",
+ description="OPEN MAILBOX WITH RAISED FLAG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4EC,
+ },
+ [0x1F4ED]={
+ category="so",
+ description="OPEN MAILBOX WITH LOWERED FLAG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4ED,
+ },
+ [0x1F4EE]={
+ category="so",
+ description="POSTBOX",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4EE,
+ },
+ [0x1F4EF]={
+ category="so",
+ description="POSTAL HORN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4EF,
+ },
+ [0x1F4F0]={
+ category="so",
+ description="NEWSPAPER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F0,
+ },
+ [0x1F4F1]={
+ category="so",
+ description="MOBILE PHONE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F1,
+ },
+ [0x1F4F2]={
+ category="so",
+ description="MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F2,
+ },
+ [0x1F4F3]={
+ category="so",
+ description="VIBRATION MODE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F3,
+ },
+ [0x1F4F4]={
+ category="so",
+ description="MOBILE PHONE OFF",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F4,
+ },
+ [0x1F4F5]={
+ category="so",
+ description="NO MOBILE PHONES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F5,
+ },
+ [0x1F4F6]={
+ category="so",
+ description="ANTENNA WITH BARS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F6,
+ },
+ [0x1F4F7]={
+ category="so",
+ description="CAMERA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F7,
+ },
+ [0x1F4F9]={
+ category="so",
+ description="VIDEO CAMERA",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4F9,
+ },
+ [0x1F4FA]={
+ category="so",
+ description="TELEVISION",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4FA,
+ },
+ [0x1F4FB]={
+ category="so",
+ description="RADIO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4FB,
+ },
+ [0x1F4FC]={
+ category="so",
+ description="VIDEOCASSETTE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F4FC,
+ },
+ [0x1F500]={
+ category="so",
+ description="TWISTED RIGHTWARDS ARROWS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F500,
+ },
+ [0x1F501]={
+ category="so",
+ description="CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F501,
+ },
+ [0x1F502]={
+ category="so",
+ description="CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F502,
+ },
+ [0x1F503]={
+ category="so",
+ description="CLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F503,
+ },
+ [0x1F504]={
+ category="so",
+ description="ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F504,
+ },
+ [0x1F505]={
+ category="so",
+ description="LOW BRIGHTNESS SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F505,
+ },
+ [0x1F506]={
+ category="so",
+ description="HIGH BRIGHTNESS SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F506,
+ },
+ [0x1F507]={
+ category="so",
+ description="SPEAKER WITH CANCELLATION STROKE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F507,
+ },
+ [0x1F508]={
+ category="so",
+ description="SPEAKER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F508,
+ },
+ [0x1F509]={
+ category="so",
+ description="SPEAKER WITH ONE SOUND WAVE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F509,
+ },
+ [0x1F50A]={
+ category="so",
+ description="SPEAKER WITH THREE SOUND WAVES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F50A,
+ },
+ [0x1F50B]={
+ category="so",
+ description="BATTERY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F50B,
+ },
+ [0x1F50C]={
+ category="so",
+ description="ELECTRIC PLUG",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F50C,
+ },
+ [0x1F50D]={
+ category="so",
+ description="LEFT-POINTING MAGNIFYING GLASS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F50D,
+ },
+ [0x1F50E]={
+ category="so",
+ description="RIGHT-POINTING MAGNIFYING GLASS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F50E,
+ },
+ [0x1F50F]={
+ category="so",
+ description="LOCK WITH INK PEN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F50F,
+ },
+ [0x1F510]={
+ category="so",
+ description="CLOSED LOCK WITH KEY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F510,
+ },
+ [0x1F511]={
+ category="so",
+ description="KEY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F511,
+ },
+ [0x1F512]={
+ category="so",
+ description="LOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F512,
+ },
+ [0x1F513]={
+ category="so",
+ description="OPEN LOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F513,
+ },
+ [0x1F514]={
+ category="so",
+ description="BELL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F514,
+ },
+ [0x1F515]={
+ category="so",
+ description="BELL WITH CANCELLATION STROKE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F515,
+ },
+ [0x1F516]={
+ category="so",
+ description="BOOKMARK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F516,
+ },
+ [0x1F517]={
+ category="so",
+ description="LINK SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F517,
+ },
+ [0x1F518]={
+ category="so",
+ description="RADIO BUTTON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F518,
+ },
+ [0x1F519]={
+ category="so",
+ description="BACK WITH LEFTWARDS ARROW ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F519,
+ },
+ [0x1F51A]={
+ category="so",
+ description="END WITH LEFTWARDS ARROW ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F51A,
+ },
+ [0x1F51B]={
+ category="so",
+ description="ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F51B,
+ },
+ [0x1F51C]={
+ category="so",
+ description="SOON WITH RIGHTWARDS ARROW ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F51C,
+ },
+ [0x1F51D]={
+ category="so",
+ description="TOP WITH UPWARDS ARROW ABOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F51D,
+ },
+ [0x1F51E]={
+ category="so",
+ description="NO ONE UNDER EIGHTEEN SYMBOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F51E,
+ },
+ [0x1F51F]={
+ category="so",
+ description="KEYCAP TEN",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F51F,
+ },
+ [0x1F520]={
+ category="so",
+ description="INPUT SYMBOL FOR LATIN CAPITAL LETTERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F520,
+ },
+ [0x1F521]={
+ category="so",
+ description="INPUT SYMBOL FOR LATIN SMALL LETTERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F521,
+ },
+ [0x1F522]={
+ category="so",
+ description="INPUT SYMBOL FOR NUMBERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F522,
+ },
+ [0x1F523]={
+ category="so",
+ description="INPUT SYMBOL FOR SYMBOLS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F523,
+ },
+ [0x1F524]={
+ category="so",
+ description="INPUT SYMBOL FOR LATIN LETTERS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F524,
+ },
+ [0x1F525]={
+ category="so",
+ description="FIRE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F525,
+ },
+ [0x1F526]={
+ category="so",
+ description="ELECTRIC TORCH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F526,
+ },
+ [0x1F527]={
+ category="so",
+ description="WRENCH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F527,
+ },
+ [0x1F528]={
+ category="so",
+ description="HAMMER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F528,
+ },
+ [0x1F529]={
+ category="so",
+ description="NUT AND BOLT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F529,
+ },
+ [0x1F52A]={
+ category="so",
+ description="HOCHO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F52A,
+ },
+ [0x1F52B]={
+ category="so",
+ description="PISTOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F52B,
+ },
+ [0x1F52C]={
+ category="so",
+ description="MICROSCOPE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F52C,
+ },
+ [0x1F52D]={
+ category="so",
+ description="TELESCOPE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F52D,
+ },
+ [0x1F52E]={
+ category="so",
+ description="CRYSTAL BALL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F52E,
+ },
+ [0x1F52F]={
+ category="so",
+ description="SIX POINTED STAR WITH MIDDLE DOT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F52F,
+ },
+ [0x1F530]={
+ category="so",
+ description="JAPANESE SYMBOL FOR BEGINNER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F530,
+ },
+ [0x1F531]={
+ category="so",
+ description="TRIDENT EMBLEM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F531,
+ },
+ [0x1F532]={
+ category="so",
+ description="BLACK SQUARE BUTTON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F532,
+ },
+ [0x1F533]={
+ category="so",
+ description="WHITE SQUARE BUTTON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F533,
+ },
+ [0x1F534]={
+ category="so",
+ description="LARGE RED CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F534,
+ },
+ [0x1F535]={
+ category="so",
+ description="LARGE BLUE CIRCLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F535,
+ },
+ [0x1F536]={
+ category="so",
+ description="LARGE ORANGE DIAMOND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F536,
+ },
+ [0x1F537]={
+ category="so",
+ description="LARGE BLUE DIAMOND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F537,
+ },
+ [0x1F538]={
+ category="so",
+ description="SMALL ORANGE DIAMOND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F538,
+ },
+ [0x1F539]={
+ category="so",
+ description="SMALL BLUE DIAMOND",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F539,
+ },
+ [0x1F53A]={
+ category="so",
+ description="UP-POINTING RED TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F53A,
+ },
+ [0x1F53B]={
+ category="so",
+ description="DOWN-POINTING RED TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F53B,
+ },
+ [0x1F53C]={
+ category="so",
+ description="UP-POINTING SMALL RED TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F53C,
+ },
+ [0x1F53D]={
+ category="so",
+ description="DOWN-POINTING SMALL RED TRIANGLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F53D,
+ },
+ [0x1F540]={
+ category="so",
+ description="CIRCLED CROSS POMMEE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F540,
+ },
+ [0x1F541]={
+ category="so",
+ description="CROSS POMMEE WITH HALF-CIRCLE BELOW",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F541,
+ },
+ [0x1F542]={
+ category="so",
+ description="CROSS POMMEE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F542,
+ },
+ [0x1F543]={
+ category="so",
+ description="NOTCHED LEFT SEMICIRCLE WITH THREE DOTS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F543,
+ },
+ [0x1F550]={
+ category="so",
+ description="CLOCK FACE ONE OCLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F550,
+ },
+ [0x1F551]={
+ category="so",
+ description="CLOCK FACE TWO OCLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F551,
+ },
+ [0x1F552]={
+ category="so",
+ description="CLOCK FACE THREE OCLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F552,
+ },
+ [0x1F553]={
+ category="so",
+ description="CLOCK FACE FOUR OCLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F553,
+ },
+ [0x1F554]={
+ category="so",
+ description="CLOCK FACE FIVE OCLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F554,
+ },
+ [0x1F555]={
+ category="so",
+ description="CLOCK FACE SIX OCLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F555,
+ },
+ [0x1F556]={
+ category="so",
+ description="CLOCK FACE SEVEN OCLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F556,
+ },
+ [0x1F557]={
+ category="so",
+ description="CLOCK FACE EIGHT OCLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F557,
+ },
+ [0x1F558]={
+ category="so",
+ description="CLOCK FACE NINE OCLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F558,
+ },
+ [0x1F559]={
+ category="so",
+ description="CLOCK FACE TEN OCLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F559,
+ },
+ [0x1F55A]={
+ category="so",
+ description="CLOCK FACE ELEVEN OCLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F55A,
+ },
+ [0x1F55B]={
+ category="so",
+ description="CLOCK FACE TWELVE OCLOCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F55B,
+ },
+ [0x1F55C]={
+ category="so",
+ description="CLOCK FACE ONE-THIRTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F55C,
+ },
+ [0x1F55D]={
+ category="so",
+ description="CLOCK FACE TWO-THIRTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F55D,
+ },
+ [0x1F55E]={
+ category="so",
+ description="CLOCK FACE THREE-THIRTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F55E,
+ },
+ [0x1F55F]={
+ category="so",
+ description="CLOCK FACE FOUR-THIRTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F55F,
+ },
+ [0x1F560]={
+ category="so",
+ description="CLOCK FACE FIVE-THIRTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F560,
+ },
+ [0x1F561]={
+ category="so",
+ description="CLOCK FACE SIX-THIRTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F561,
+ },
+ [0x1F562]={
+ category="so",
+ description="CLOCK FACE SEVEN-THIRTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F562,
+ },
+ [0x1F563]={
+ category="so",
+ description="CLOCK FACE EIGHT-THIRTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F563,
+ },
+ [0x1F564]={
+ category="so",
+ description="CLOCK FACE NINE-THIRTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F564,
+ },
+ [0x1F565]={
+ category="so",
+ description="CLOCK FACE TEN-THIRTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F565,
+ },
+ [0x1F566]={
+ category="so",
+ description="CLOCK FACE ELEVEN-THIRTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F566,
+ },
+ [0x1F567]={
+ category="so",
+ description="CLOCK FACE TWELVE-THIRTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F567,
+ },
+ [0x1F5FB]={
+ category="so",
+ description="MOUNT FUJI",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5FB,
+ },
+ [0x1F5FC]={
+ category="so",
+ description="TOKYO TOWER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5FC,
+ },
+ [0x1F5FD]={
+ category="so",
+ description="STATUE OF LIBERTY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5FD,
+ },
+ [0x1F5FE]={
+ category="so",
+ description="SILHOUETTE OF JAPAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5FE,
+ },
+ [0x1F5FF]={
+ category="so",
+ description="MOYAI",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F5FF,
+ },
+ [0x1F600]={
+ category="so",
+ description="GRINNING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F600,
+ },
+ [0x1F601]={
+ category="so",
+ description="GRINNING FACE WITH SMILING EYES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F601,
+ },
+ [0x1F602]={
+ category="so",
+ description="FACE WITH TEARS OF JOY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F602,
+ },
+ [0x1F603]={
+ category="so",
+ description="SMILING FACE WITH OPEN MOUTH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F603,
+ },
+ [0x1F604]={
+ category="so",
+ description="SMILING FACE WITH OPEN MOUTH AND SMILING EYES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F604,
+ },
+ [0x1F605]={
+ category="so",
+ description="SMILING FACE WITH OPEN MOUTH AND COLD SWEAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F605,
+ },
+ [0x1F606]={
+ category="so",
+ description="SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F606,
+ },
+ [0x1F607]={
+ category="so",
+ description="SMILING FACE WITH HALO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F607,
+ },
+ [0x1F608]={
+ category="so",
+ description="SMILING FACE WITH HORNS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F608,
+ },
+ [0x1F609]={
+ category="so",
+ description="WINKING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F609,
+ },
+ [0x1F60A]={
+ category="so",
+ description="SMILING FACE WITH SMILING EYES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F60A,
+ },
+ [0x1F60B]={
+ category="so",
+ description="FACE SAVOURING DELICIOUS FOOD",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F60B,
+ },
+ [0x1F60C]={
+ category="so",
+ description="RELIEVED FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F60C,
+ },
+ [0x1F60D]={
+ category="so",
+ description="SMILING FACE WITH HEART-SHAPED EYES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F60D,
+ },
+ [0x1F60E]={
+ category="so",
+ description="SMILING FACE WITH SUNGLASSES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F60E,
+ },
+ [0x1F60F]={
+ category="so",
+ description="SMIRKING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F60F,
+ },
+ [0x1F610]={
+ category="so",
+ description="NEUTRAL FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F610,
+ },
+ [0x1F611]={
+ category="so",
+ description="EXPRESSIONLESS FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F611,
+ },
+ [0x1F612]={
+ category="so",
+ description="UNAMUSED FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F612,
+ },
+ [0x1F613]={
+ category="so",
+ description="FACE WITH COLD SWEAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F613,
+ },
+ [0x1F614]={
+ category="so",
+ description="PENSIVE FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F614,
+ },
+ [0x1F615]={
+ category="so",
+ description="CONFUSED FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F615,
+ },
+ [0x1F616]={
+ category="so",
+ description="CONFOUNDED FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F616,
+ },
+ [0x1F617]={
+ category="so",
+ description="KISSING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F617,
+ },
+ [0x1F618]={
+ category="so",
+ description="FACE THROWING A KISS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F618,
+ },
+ [0x1F619]={
+ category="so",
+ description="KISSING FACE WITH SMILING EYES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F619,
+ },
+ [0x1F61A]={
+ category="so",
+ description="KISSING FACE WITH CLOSED EYES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F61A,
+ },
+ [0x1F61B]={
+ category="so",
+ description="FACE WITH STUCK-OUT TONGUE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F61B,
+ },
+ [0x1F61C]={
+ category="so",
+ description="FACE WITH STUCK-OUT TONGUE AND WINKING EYE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F61C,
+ },
+ [0x1F61D]={
+ category="so",
+ description="FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F61D,
+ },
+ [0x1F61E]={
+ category="so",
+ description="DISAPPOINTED FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F61E,
+ },
+ [0x1F61F]={
+ category="so",
+ description="WORRIED FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F61F,
+ },
+ [0x1F620]={
+ category="so",
+ description="ANGRY FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F620,
+ },
+ [0x1F621]={
+ category="so",
+ description="POUTING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F621,
+ },
+ [0x1F622]={
+ category="so",
+ description="CRYING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F622,
+ },
+ [0x1F623]={
+ category="so",
+ description="PERSEVERING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F623,
+ },
+ [0x1F624]={
+ category="so",
+ description="FACE WITH LOOK OF TRIUMPH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F624,
+ },
+ [0x1F625]={
+ category="so",
+ description="DISAPPOINTED BUT RELIEVED FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F625,
+ },
+ [0x1F626]={
+ category="so",
+ description="FROWNING FACE WITH OPEN MOUTH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F626,
+ },
+ [0x1F627]={
+ category="so",
+ description="ANGUISHED FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F627,
+ },
+ [0x1F628]={
+ category="so",
+ description="FEARFUL FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F628,
+ },
+ [0x1F629]={
+ category="so",
+ description="WEARY FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F629,
+ },
+ [0x1F62A]={
+ category="so",
+ description="SLEEPY FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F62A,
+ },
+ [0x1F62B]={
+ category="so",
+ description="TIRED FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F62B,
+ },
+ [0x1F62C]={
+ category="so",
+ description="GRIMACING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F62C,
+ },
+ [0x1F62D]={
+ category="so",
+ description="LOUDLY CRYING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F62D,
+ },
+ [0x1F62E]={
+ category="so",
+ description="FACE WITH OPEN MOUTH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F62E,
+ },
+ [0x1F62F]={
+ category="so",
+ description="HUSHED FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F62F,
+ },
+ [0x1F630]={
+ category="so",
+ description="FACE WITH OPEN MOUTH AND COLD SWEAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F630,
+ },
+ [0x1F631]={
+ category="so",
+ description="FACE SCREAMING IN FEAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F631,
+ },
+ [0x1F632]={
+ category="so",
+ description="ASTONISHED FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F632,
+ },
+ [0x1F633]={
+ category="so",
+ description="FLUSHED FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F633,
+ },
+ [0x1F634]={
+ category="so",
+ description="SLEEPING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F634,
+ },
+ [0x1F635]={
+ category="so",
+ description="DIZZY FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F635,
+ },
+ [0x1F636]={
+ category="so",
+ description="FACE WITHOUT MOUTH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F636,
+ },
+ [0x1F637]={
+ category="so",
+ description="FACE WITH MEDICAL MASK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F637,
+ },
+ [0x1F638]={
+ category="so",
+ description="GRINNING CAT FACE WITH SMILING EYES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F638,
+ },
+ [0x1F639]={
+ category="so",
+ description="CAT FACE WITH TEARS OF JOY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F639,
+ },
+ [0x1F63A]={
+ category="so",
+ description="SMILING CAT FACE WITH OPEN MOUTH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F63A,
+ },
+ [0x1F63B]={
+ category="so",
+ description="SMILING CAT FACE WITH HEART-SHAPED EYES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F63B,
+ },
+ [0x1F63C]={
+ category="so",
+ description="CAT FACE WITH WRY SMILE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F63C,
+ },
+ [0x1F63D]={
+ category="so",
+ description="KISSING CAT FACE WITH CLOSED EYES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F63D,
+ },
+ [0x1F63E]={
+ category="so",
+ description="POUTING CAT FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F63E,
+ },
+ [0x1F63F]={
+ category="so",
+ description="CRYING CAT FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F63F,
+ },
+ [0x1F640]={
+ category="so",
+ description="WEARY CAT FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F640,
+ },
+ [0x1F645]={
+ category="so",
+ description="FACE WITH NO GOOD GESTURE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F645,
+ },
+ [0x1F646]={
+ category="so",
+ description="FACE WITH OK GESTURE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F646,
+ },
+ [0x1F647]={
+ category="so",
+ description="PERSON BOWING DEEPLY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F647,
+ },
+ [0x1F648]={
+ category="so",
+ description="SEE-NO-EVIL MONKEY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F648,
+ },
+ [0x1F649]={
+ category="so",
+ description="HEAR-NO-EVIL MONKEY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F649,
+ },
+ [0x1F64A]={
+ category="so",
+ description="SPEAK-NO-EVIL MONKEY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F64A,
+ },
+ [0x1F64B]={
+ category="so",
+ description="HAPPY PERSON RAISING ONE HAND",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F64B,
+ },
+ [0x1F64C]={
+ category="so",
+ description="PERSON RAISING BOTH HANDS IN CELEBRATION",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F64C,
+ },
+ [0x1F64D]={
+ category="so",
+ description="PERSON FROWNING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F64D,
+ },
+ [0x1F64E]={
+ category="so",
+ description="PERSON WITH POUTING FACE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F64E,
+ },
+ [0x1F64F]={
+ category="so",
+ description="PERSON WITH FOLDED HANDS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F64F,
+ },
+ [0x1F680]={
+ category="so",
+ description="ROCKET",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F680,
+ },
+ [0x1F681]={
+ category="so",
+ description="HELICOPTER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F681,
+ },
+ [0x1F682]={
+ category="so",
+ description="STEAM LOCOMOTIVE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F682,
+ },
+ [0x1F683]={
+ category="so",
+ description="RAILWAY CAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F683,
+ },
+ [0x1F684]={
+ category="so",
+ description="HIGH-SPEED TRAIN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F684,
+ },
+ [0x1F685]={
+ category="so",
+ description="HIGH-SPEED TRAIN WITH BULLET NOSE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F685,
+ },
+ [0x1F686]={
+ category="so",
+ description="TRAIN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F686,
+ },
+ [0x1F687]={
+ category="so",
+ description="METRO",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F687,
+ },
+ [0x1F688]={
+ category="so",
+ description="LIGHT RAIL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F688,
+ },
+ [0x1F689]={
+ category="so",
+ description="STATION",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F689,
+ },
+ [0x1F68A]={
+ category="so",
+ description="TRAM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F68A,
+ },
+ [0x1F68B]={
+ category="so",
+ description="TRAM CAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F68B,
+ },
+ [0x1F68C]={
+ category="so",
+ description="BUS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F68C,
+ },
+ [0x1F68D]={
+ category="so",
+ description="ONCOMING BUS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F68D,
+ },
+ [0x1F68E]={
+ category="so",
+ description="TROLLEYBUS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F68E,
+ },
+ [0x1F68F]={
+ category="so",
+ description="BUS STOP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F68F,
+ },
+ [0x1F690]={
+ category="so",
+ description="MINIBUS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F690,
+ },
+ [0x1F691]={
+ category="so",
+ description="AMBULANCE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F691,
+ },
+ [0x1F692]={
+ category="so",
+ description="FIRE ENGINE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F692,
+ },
+ [0x1F693]={
+ category="so",
+ description="POLICE CAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F693,
+ },
+ [0x1F694]={
+ category="so",
+ description="ONCOMING POLICE CAR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F694,
+ },
+ [0x1F695]={
+ category="so",
+ description="TAXI",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F695,
+ },
+ [0x1F696]={
+ category="so",
+ description="ONCOMING TAXI",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F696,
+ },
+ [0x1F697]={
+ category="so",
+ description="AUTOMOBILE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F697,
+ },
+ [0x1F698]={
+ category="so",
+ description="ONCOMING AUTOMOBILE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F698,
+ },
+ [0x1F699]={
+ category="so",
+ description="RECREATIONAL VEHICLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F699,
+ },
+ [0x1F69A]={
+ category="so",
+ description="DELIVERY TRUCK",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F69A,
+ },
+ [0x1F69B]={
+ category="so",
+ description="ARTICULATED LORRY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F69B,
+ },
+ [0x1F69C]={
+ category="so",
+ description="TRACTOR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F69C,
+ },
+ [0x1F69D]={
+ category="so",
+ description="MONORAIL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F69D,
+ },
+ [0x1F69E]={
+ category="so",
+ description="MOUNTAIN RAILWAY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F69E,
+ },
+ [0x1F69F]={
+ category="so",
+ description="SUSPENSION RAILWAY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F69F,
+ },
+ [0x1F6A0]={
+ category="so",
+ description="MOUNTAIN CABLEWAY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A0,
+ },
+ [0x1F6A1]={
+ category="so",
+ description="AERIAL TRAMWAY",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A1,
+ },
+ [0x1F6A2]={
+ category="so",
+ description="SHIP",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A2,
+ },
+ [0x1F6A3]={
+ category="so",
+ description="ROWBOAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A3,
+ },
+ [0x1F6A4]={
+ category="so",
+ description="SPEEDBOAT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A4,
+ },
+ [0x1F6A5]={
+ category="so",
+ description="HORIZONTAL TRAFFIC LIGHT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A5,
+ },
+ [0x1F6A6]={
+ category="so",
+ description="VERTICAL TRAFFIC LIGHT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A6,
+ },
+ [0x1F6A7]={
+ category="so",
+ description="CONSTRUCTION SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A7,
+ },
+ [0x1F6A8]={
+ category="so",
+ description="POLICE CARS REVOLVING LIGHT",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A8,
+ },
+ [0x1F6A9]={
+ category="so",
+ description="TRIANGULAR FLAG ON POST",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6A9,
+ },
+ [0x1F6AA]={
+ category="so",
+ description="DOOR",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6AA,
+ },
+ [0x1F6AB]={
+ category="so",
+ description="NO ENTRY SIGN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6AB,
+ },
+ [0x1F6AC]={
+ category="so",
+ description="SMOKING SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6AC,
+ },
+ [0x1F6AD]={
+ category="so",
+ description="NO SMOKING SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6AD,
+ },
+ [0x1F6AE]={
+ category="so",
+ description="PUT LITTER IN ITS PLACE SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6AE,
+ },
+ [0x1F6AF]={
+ category="so",
+ description="DO NOT LITTER SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6AF,
+ },
+ [0x1F6B0]={
+ category="so",
+ description="POTABLE WATER SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B0,
+ },
+ [0x1F6B1]={
+ category="so",
+ description="NON-POTABLE WATER SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B1,
+ },
+ [0x1F6B2]={
+ category="so",
+ description="BICYCLE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B2,
+ },
+ [0x1F6B3]={
+ category="so",
+ description="NO BICYCLES",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B3,
+ },
+ [0x1F6B4]={
+ category="so",
+ description="BICYCLIST",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B4,
+ },
+ [0x1F6B5]={
+ category="so",
+ description="MOUNTAIN BICYCLIST",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B5,
+ },
+ [0x1F6B6]={
+ category="so",
+ description="PEDESTRIAN",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B6,
+ },
+ [0x1F6B7]={
+ category="so",
+ description="NO PEDESTRIANS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B7,
+ },
+ [0x1F6B8]={
+ category="so",
+ description="CHILDREN CROSSING",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B8,
+ },
+ [0x1F6B9]={
+ category="so",
+ description="MENS SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6B9,
+ },
+ [0x1F6BA]={
+ category="so",
+ description="WOMENS SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6BA,
+ },
+ [0x1F6BB]={
+ category="so",
+ description="RESTROOM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6BB,
+ },
+ [0x1F6BC]={
+ category="so",
+ description="BABY SYMBOL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6BC,
+ },
+ [0x1F6BD]={
+ category="so",
+ description="TOILET",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6BD,
+ },
+ [0x1F6BE]={
+ category="so",
+ description="WATER CLOSET",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6BE,
+ },
+ [0x1F6BF]={
+ category="so",
+ description="SHOWER",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6BF,
+ },
+ [0x1F6C0]={
+ category="so",
+ description="BATH",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C0,
+ },
+ [0x1F6C1]={
+ category="so",
+ description="BATHTUB",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C1,
+ },
+ [0x1F6C2]={
+ category="so",
+ description="PASSPORT CONTROL",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C2,
+ },
+ [0x1F6C3]={
+ category="so",
+ description="CUSTOMS",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C3,
+ },
+ [0x1F6C4]={
+ category="so",
+ description="BAGGAGE CLAIM",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C4,
+ },
+ [0x1F6C5]={
+ category="so",
+ description="LEFT LUGGAGE",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6C5,
+ },
+ [0x1F700]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR QUINTESSENCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F700,
+ },
+ [0x1F701]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR AIR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F701,
+ },
+ [0x1F702]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR FIRE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F702,
+ },
+ [0x1F703]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR EARTH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F703,
+ },
+ [0x1F704]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR WATER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F704,
+ },
+ [0x1F705]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR AQUAFORTIS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F705,
+ },
+ [0x1F706]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR AQUA REGIA",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F706,
+ },
+ [0x1F707]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR AQUA REGIA-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F707,
+ },
+ [0x1F708]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR AQUA VITAE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F708,
+ },
+ [0x1F709]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR AQUA VITAE-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F709,
+ },
+ [0x1F70A]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR VINEGAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F70A,
+ },
+ [0x1F70B]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR VINEGAR-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F70B,
+ },
+ [0x1F70C]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR VINEGAR-3",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F70C,
+ },
+ [0x1F70D]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SULFUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F70D,
+ },
+ [0x1F70E]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR PHILOSOPHERS SULFUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F70E,
+ },
+ [0x1F70F]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR BLACK SULFUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F70F,
+ },
+ [0x1F710]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F710,
+ },
+ [0x1F711]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F711,
+ },
+ [0x1F712]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-3",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F712,
+ },
+ [0x1F713]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR CINNABAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F713,
+ },
+ [0x1F714]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SALT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F714,
+ },
+ [0x1F715]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR NITRE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F715,
+ },
+ [0x1F716]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR VITRIOL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F716,
+ },
+ [0x1F717]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR VITRIOL-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F717,
+ },
+ [0x1F718]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR ROCK SALT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F718,
+ },
+ [0x1F719]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR ROCK SALT-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F719,
+ },
+ [0x1F71A]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR GOLD",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F71A,
+ },
+ [0x1F71B]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SILVER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F71B,
+ },
+ [0x1F71C]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR IRON ORE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F71C,
+ },
+ [0x1F71D]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR IRON ORE-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F71D,
+ },
+ [0x1F71E]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR CROCUS OF IRON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F71E,
+ },
+ [0x1F71F]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR REGULUS OF IRON",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F71F,
+ },
+ [0x1F720]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR COPPER ORE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F720,
+ },
+ [0x1F721]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR IRON-COPPER ORE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F721,
+ },
+ [0x1F722]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SUBLIMATE OF COPPER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F722,
+ },
+ [0x1F723]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR CROCUS OF COPPER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F723,
+ },
+ [0x1F724]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR CROCUS OF COPPER-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F724,
+ },
+ [0x1F725]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR COPPER ANTIMONIATE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F725,
+ },
+ [0x1F726]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SALT OF COPPER ANTIMONIATE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F726,
+ },
+ [0x1F727]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF COPPER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F727,
+ },
+ [0x1F728]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR VERDIGRIS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F728,
+ },
+ [0x1F729]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR TIN ORE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F729,
+ },
+ [0x1F72A]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR LEAD ORE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F72A,
+ },
+ [0x1F72B]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR ANTIMONY ORE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F72B,
+ },
+ [0x1F72C]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SUBLIMATE OF ANTIMONY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F72C,
+ },
+ [0x1F72D]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SALT OF ANTIMONY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F72D,
+ },
+ [0x1F72E]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF ANTIMONY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F72E,
+ },
+ [0x1F72F]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR VINEGAR OF ANTIMONY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F72F,
+ },
+ [0x1F730]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F730,
+ },
+ [0x1F731]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F731,
+ },
+ [0x1F732]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR REGULUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F732,
+ },
+ [0x1F733]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR REGULUS-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F733,
+ },
+ [0x1F734]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR REGULUS-3",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F734,
+ },
+ [0x1F735]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR REGULUS-4",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F735,
+ },
+ [0x1F736]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR ALKALI",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F736,
+ },
+ [0x1F737]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR ALKALI-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F737,
+ },
+ [0x1F738]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR MARCASITE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F738,
+ },
+ [0x1F739]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SAL-AMMONIAC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F739,
+ },
+ [0x1F73A]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR ARSENIC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F73A,
+ },
+ [0x1F73B]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR REALGAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F73B,
+ },
+ [0x1F73C]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR REALGAR-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F73C,
+ },
+ [0x1F73D]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR AURIPIGMENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F73D,
+ },
+ [0x1F73E]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR BISMUTH ORE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F73E,
+ },
+ [0x1F73F]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR TARTAR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F73F,
+ },
+ [0x1F740]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR TARTAR-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F740,
+ },
+ [0x1F741]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR QUICK LIME",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F741,
+ },
+ [0x1F742]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR BORAX",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F742,
+ },
+ [0x1F743]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR BORAX-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F743,
+ },
+ [0x1F744]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR BORAX-3",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F744,
+ },
+ [0x1F745]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR ALUM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F745,
+ },
+ [0x1F746]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR OIL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F746,
+ },
+ [0x1F747]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SPIRIT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F747,
+ },
+ [0x1F748]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR TINCTURE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F748,
+ },
+ [0x1F749]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR GUM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F749,
+ },
+ [0x1F74A]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR WAX",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F74A,
+ },
+ [0x1F74B]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR POWDER",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F74B,
+ },
+ [0x1F74C]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR CALX",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F74C,
+ },
+ [0x1F74D]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR TUTTY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F74D,
+ },
+ [0x1F74E]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR CAPUT MORTUUM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F74E,
+ },
+ [0x1F74F]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SCEPTER OF JOVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F74F,
+ },
+ [0x1F750]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR CADUCEUS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F750,
+ },
+ [0x1F751]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR TRIDENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F751,
+ },
+ [0x1F752]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR STARRED TRIDENT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F752,
+ },
+ [0x1F753]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR LODESTONE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F753,
+ },
+ [0x1F754]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SOAP",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F754,
+ },
+ [0x1F755]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR URINE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F755,
+ },
+ [0x1F756]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR HORSE DUNG",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F756,
+ },
+ [0x1F757]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR ASHES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F757,
+ },
+ [0x1F758]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR POT ASHES",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F758,
+ },
+ [0x1F759]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR BRICK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F759,
+ },
+ [0x1F75A]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR POWDERED BRICK",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F75A,
+ },
+ [0x1F75B]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR AMALGAM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F75B,
+ },
+ [0x1F75C]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F75C,
+ },
+ [0x1F75D]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F75D,
+ },
+ [0x1F75E]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR SUBLIMATION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F75E,
+ },
+ [0x1F75F]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR PRECIPITATE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F75F,
+ },
+ [0x1F760]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR DISTILL",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F760,
+ },
+ [0x1F761]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR DISSOLVE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F761,
+ },
+ [0x1F762]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR DISSOLVE-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F762,
+ },
+ [0x1F763]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR PURIFY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F763,
+ },
+ [0x1F764]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR PUTREFACTION",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F764,
+ },
+ [0x1F765]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR CRUCIBLE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F765,
+ },
+ [0x1F766]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR CRUCIBLE-2",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F766,
+ },
+ [0x1F767]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR CRUCIBLE-3",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F767,
+ },
+ [0x1F768]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR CRUCIBLE-4",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F768,
+ },
+ [0x1F769]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR CRUCIBLE-5",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F769,
+ },
+ [0x1F76A]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR ALEMBIC",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F76A,
+ },
+ [0x1F76B]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR BATH OF MARY",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F76B,
+ },
+ [0x1F76C]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR BATH OF VAPOURS",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F76C,
+ },
+ [0x1F76D]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR RETORT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F76D,
+ },
+ [0x1F76E]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR HOUR",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F76E,
+ },
+ [0x1F76F]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR NIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F76F,
+ },
+ [0x1F770]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR DAY-NIGHT",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F770,
+ },
+ [0x1F771]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR MONTH",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F771,
+ },
+ [0x1F772]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR HALF DRAM",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F772,
+ },
+ [0x1F773]={
+ category="so",
+ description="ALCHEMICAL SYMBOL FOR HALF OUNCE",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1F773,
+ },
+ [0x2F800]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0320",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E3D },
+ unicodeslot=0x2F800,
+ },
+ [0x2F801]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0321",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E38 },
+ unicodeslot=0x2F801,
+ },
+ [0x2F802]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0322",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4E41 },
+ unicodeslot=0x2F802,
+ },
+ [0x2F803]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0323",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x20122 },
+ unicodeslot=0x2F803,
+ },
+ [0x2F804]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0324",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4F60 },
+ unicodeslot=0x2F804,
+ },
+ [0x2F805]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0325",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4FAE },
+ unicodeslot=0x2F805,
+ },
+ [0x2F806]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0326",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4FBB },
+ unicodeslot=0x2F806,
+ },
+ [0x2F807]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0327",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5002 },
+ unicodeslot=0x2F807,
+ },
+ [0x2F808]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0328",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x507A },
+ unicodeslot=0x2F808,
+ },
+ [0x2F809]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0329",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5099 },
+ unicodeslot=0x2F809,
+ },
+ [0x2F80A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0050A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x50E7 },
+ unicodeslot=0x2F80A,
+ },
+ [0x2F80B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0050B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x50CF },
+ unicodeslot=0x2F80B,
+ },
+ [0x2F80C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0050C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x349E },
+ unicodeslot=0x2F80C,
+ },
+ [0x2F80D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0050D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2063A },
+ unicodeslot=0x2F80D,
+ },
+ [0x2F80E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0050E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x514D },
+ unicodeslot=0x2F80E,
+ },
+ [0x2F80F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0050F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5154 },
+ unicodeslot=0x2F80F,
+ },
+ [0x2F810]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x032A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5164 },
+ unicodeslot=0x2F810,
+ },
+ [0x2F811]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x032B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5177 },
+ unicodeslot=0x2F811,
+ },
+ [0x2F812]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x032C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2051C },
+ unicodeslot=0x2F812,
+ },
+ [0x2F813]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x032D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x34B9 },
+ unicodeslot=0x2F813,
+ },
+ [0x2F814]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x032E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5167 },
+ unicodeslot=0x2F814,
+ },
+ [0x2F815]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x032F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x518D },
+ unicodeslot=0x2F815,
+ },
+ [0x2F816]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0330",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2054B },
+ unicodeslot=0x2F816,
+ },
+ [0x2F817]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0331",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5197 },
+ unicodeslot=0x2F817,
+ },
+ [0x2F818]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0332",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51A4 },
+ unicodeslot=0x2F818,
+ },
+ [0x2F819]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0333",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4ECC },
+ unicodeslot=0x2F819,
+ },
+ [0x2F81A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0051A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51AC },
+ unicodeslot=0x2F81A,
+ },
+ [0x2F81B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0051B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51B5 },
+ unicodeslot=0x2F81B,
+ },
+ [0x2F81C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0051C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x291DF },
+ unicodeslot=0x2F81C,
+ },
+ [0x2F81D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0051D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x51F5 },
+ unicodeslot=0x2F81D,
+ },
+ [0x2F81E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0051E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5203 },
+ unicodeslot=0x2F81E,
+ },
+ [0x2F81F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0051F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x34DF },
+ unicodeslot=0x2F81F,
+ },
+ [0x2F820]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0334",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x523B },
+ unicodeslot=0x2F820,
+ },
+ [0x2F821]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0335",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5246 },
+ unicodeslot=0x2F821,
+ },
+ [0x2F822]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0336",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5272 },
+ unicodeslot=0x2F822,
+ },
+ [0x2F823]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0337",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5277 },
+ unicodeslot=0x2F823,
+ },
+ [0x2F824]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0338",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3515 },
+ unicodeslot=0x2F824,
+ },
+ [0x2F825]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0339",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52C7 },
+ unicodeslot=0x2F825,
+ },
+ [0x2F826]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x033A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52C9 },
+ unicodeslot=0x2F826,
+ },
+ [0x2F827]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x033B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52E4 },
+ unicodeslot=0x2F827,
+ },
+ [0x2F828]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x033C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52FA },
+ unicodeslot=0x2F828,
+ },
+ [0x2F829]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x033D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5305 },
+ unicodeslot=0x2F829,
+ },
+ [0x2F82A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0052A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5306 },
+ unicodeslot=0x2F82A,
+ },
+ [0x2F82B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0052B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5317 },
+ unicodeslot=0x2F82B,
+ },
+ [0x2F82C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0052C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5349 },
+ unicodeslot=0x2F82C,
+ },
+ [0x2F82D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0052D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5351 },
+ unicodeslot=0x2F82D,
+ },
+ [0x2F82E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0052E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x535A },
+ unicodeslot=0x2F82E,
+ },
+ [0x2F82F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0052F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5373 },
+ unicodeslot=0x2F82F,
+ },
+ [0x2F830]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x033E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x537D },
+ unicodeslot=0x2F830,
+ },
+ [0x2F831]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x033F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x537F },
+ unicodeslot=0x2F831,
+ },
+ [0x2F832]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0340",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x537F },
+ unicodeslot=0x2F832,
+ },
+ [0x2F833]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0341",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x537F },
+ unicodeslot=0x2F833,
+ },
+ [0x2F834]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0342",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x20A2C },
+ unicodeslot=0x2F834,
+ },
+ [0x2F835]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0343",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7070 },
+ unicodeslot=0x2F835,
+ },
+ [0x2F836]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0344",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x53CA },
+ unicodeslot=0x2F836,
+ },
+ [0x2F837]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0345",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x53DF },
+ unicodeslot=0x2F837,
+ },
+ [0x2F838]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0346",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x20B63 },
+ unicodeslot=0x2F838,
+ },
+ [0x2F839]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0347",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x53EB },
+ unicodeslot=0x2F839,
+ },
+ [0x2F83A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0053A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x53F1 },
+ unicodeslot=0x2F83A,
+ },
+ [0x2F83B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0053B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5406 },
+ unicodeslot=0x2F83B,
+ },
+ [0x2F83C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0053C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x549E },
+ unicodeslot=0x2F83C,
+ },
+ [0x2F83D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0053D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5438 },
+ unicodeslot=0x2F83D,
+ },
+ [0x2F83E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0053E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5448 },
+ unicodeslot=0x2F83E,
+ },
+ [0x2F83F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0053F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5468 },
+ unicodeslot=0x2F83F,
+ },
+ [0x2F840]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0348",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x54A2 },
+ unicodeslot=0x2F840,
+ },
+ [0x2F841]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0349",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x54F6 },
+ unicodeslot=0x2F841,
+ },
+ [0x2F842]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x034A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5510 },
+ unicodeslot=0x2F842,
+ },
+ [0x2F843]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x034B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5553 },
+ unicodeslot=0x2F843,
+ },
+ [0x2F844]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x034C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5563 },
+ unicodeslot=0x2F844,
+ },
+ [0x2F845]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x034D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5584 },
+ unicodeslot=0x2F845,
+ },
+ [0x2F846]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x034E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5584 },
+ unicodeslot=0x2F846,
+ },
+ [0x2F847]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x034F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5599 },
+ unicodeslot=0x2F847,
+ },
+ [0x2F848]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0350",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x55AB },
+ unicodeslot=0x2F848,
+ },
+ [0x2F849]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0351",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x55B3 },
+ unicodeslot=0x2F849,
+ },
+ [0x2F84A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0054A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x55C2 },
+ unicodeslot=0x2F84A,
+ },
+ [0x2F84B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0054B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5716 },
+ unicodeslot=0x2F84B,
+ },
+ [0x2F84C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0054C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5606 },
+ unicodeslot=0x2F84C,
+ },
+ [0x2F84D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0054D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5717 },
+ unicodeslot=0x2F84D,
+ },
+ [0x2F84E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0054E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5651 },
+ unicodeslot=0x2F84E,
+ },
+ [0x2F84F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0054F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5674 },
+ unicodeslot=0x2F84F,
+ },
+ [0x2F850]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0352",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5207 },
+ unicodeslot=0x2F850,
+ },
+ [0x2F851]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0353",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58EE },
+ unicodeslot=0x2F851,
+ },
+ [0x2F852]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0354",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x57CE },
+ unicodeslot=0x2F852,
+ },
+ [0x2F853]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0355",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x57F4 },
+ unicodeslot=0x2F853,
+ },
+ [0x2F854]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0356",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x580D },
+ unicodeslot=0x2F854,
+ },
+ [0x2F855]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0357",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x578B },
+ unicodeslot=0x2F855,
+ },
+ [0x2F856]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0358",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5832 },
+ unicodeslot=0x2F856,
+ },
+ [0x2F857]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0359",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5831 },
+ unicodeslot=0x2F857,
+ },
+ [0x2F858]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x035A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58AC },
+ unicodeslot=0x2F858,
+ },
+ [0x2F859]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x035B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x214E4 },
+ unicodeslot=0x2F859,
+ },
+ [0x2F85A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0055A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58F2 },
+ unicodeslot=0x2F85A,
+ },
+ [0x2F85B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0055B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x58F7 },
+ unicodeslot=0x2F85B,
+ },
+ [0x2F85C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0055C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5906 },
+ unicodeslot=0x2F85C,
+ },
+ [0x2F85D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0055D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x591A },
+ unicodeslot=0x2F85D,
+ },
+ [0x2F85E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0055E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5922 },
+ unicodeslot=0x2F85E,
+ },
+ [0x2F85F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0055F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5962 },
+ unicodeslot=0x2F85F,
+ },
+ [0x2F860]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x035C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x216A8 },
+ unicodeslot=0x2F860,
+ },
+ [0x2F861]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x035D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x216EA },
+ unicodeslot=0x2F861,
+ },
+ [0x2F862]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x035E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x59EC },
+ unicodeslot=0x2F862,
+ },
+ [0x2F863]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x035F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5A1B },
+ unicodeslot=0x2F863,
+ },
+ [0x2F864]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0360",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5A27 },
+ unicodeslot=0x2F864,
+ },
+ [0x2F865]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0361",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x59D8 },
+ unicodeslot=0x2F865,
+ },
+ [0x2F866]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0362",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5A66 },
+ unicodeslot=0x2F866,
+ },
+ [0x2F867]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0363",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x36EE },
+ unicodeslot=0x2F867,
+ },
+ [0x2F868]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0364",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x36FC },
+ unicodeslot=0x2F868,
+ },
+ [0x2F869]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0365",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5B08 },
+ unicodeslot=0x2F869,
+ },
+ [0x2F86A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0056A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5B3E },
+ unicodeslot=0x2F86A,
+ },
+ [0x2F86B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0056B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5B3E },
+ unicodeslot=0x2F86B,
+ },
+ [0x2F86C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0056C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x219C8 },
+ unicodeslot=0x2F86C,
+ },
+ [0x2F86D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0056D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BC3 },
+ unicodeslot=0x2F86D,
+ },
+ [0x2F86E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0056E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BD8 },
+ unicodeslot=0x2F86E,
+ },
+ [0x2F86F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0056F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BE7 },
+ unicodeslot=0x2F86F,
+ },
+ [0x2F870]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0366",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BF3 },
+ unicodeslot=0x2F870,
+ },
+ [0x2F871]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0367",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x21B18 },
+ unicodeslot=0x2F871,
+ },
+ [0x2F872]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0368",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5BFF },
+ unicodeslot=0x2F872,
+ },
+ [0x2F873]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0369",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C06 },
+ unicodeslot=0x2F873,
+ },
+ [0x2F874]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x036A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F53 },
+ unicodeslot=0x2F874,
+ },
+ [0x2F875]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x036B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C22 },
+ unicodeslot=0x2F875,
+ },
+ [0x2F876]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x036C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3781 },
+ unicodeslot=0x2F876,
+ },
+ [0x2F877]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x036D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C60 },
+ unicodeslot=0x2F877,
+ },
+ [0x2F878]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x036E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C6E },
+ unicodeslot=0x2F878,
+ },
+ [0x2F879]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x036F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5CC0 },
+ unicodeslot=0x2F879,
+ },
+ [0x2F87A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0057A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5C8D },
+ unicodeslot=0x2F87A,
+ },
+ [0x2F87B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0057B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x21DE4 },
+ unicodeslot=0x2F87B,
+ },
+ [0x2F87C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0057C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5D43 },
+ unicodeslot=0x2F87C,
+ },
+ [0x2F87D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0057D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x21DE6 },
+ unicodeslot=0x2F87D,
+ },
+ [0x2F87E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0057E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5D6E },
+ unicodeslot=0x2F87E,
+ },
+ [0x2F87F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0057F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5D6B },
+ unicodeslot=0x2F87F,
+ },
+ [0x2F880]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0370",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5D7C },
+ unicodeslot=0x2F880,
+ },
+ [0x2F881]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0371",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5DE1 },
+ unicodeslot=0x2F881,
+ },
+ [0x2F882]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0372",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5DE2 },
+ unicodeslot=0x2F882,
+ },
+ [0x2F883]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0373",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x382F },
+ unicodeslot=0x2F883,
+ },
+ [0x2F884]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0374",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5DFD },
+ unicodeslot=0x2F884,
+ },
+ [0x2F885]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0375",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5E28 },
+ unicodeslot=0x2F885,
+ },
+ [0x2F886]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0376",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5E3D },
+ unicodeslot=0x2F886,
+ },
+ [0x2F887]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0377",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5E69 },
+ unicodeslot=0x2F887,
+ },
+ [0x2F888]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0378",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3862 },
+ unicodeslot=0x2F888,
+ },
+ [0x2F889]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0379",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x22183 },
+ unicodeslot=0x2F889,
+ },
+ [0x2F88A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0058A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x387C },
+ unicodeslot=0x2F88A,
+ },
+ [0x2F88B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0058B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EB0 },
+ unicodeslot=0x2F88B,
+ },
+ [0x2F88C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0058C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EB3 },
+ unicodeslot=0x2F88C,
+ },
+ [0x2F88D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0058D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EB6 },
+ unicodeslot=0x2F88D,
+ },
+ [0x2F88E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0058E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5ECA },
+ unicodeslot=0x2F88E,
+ },
+ [0x2F88F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0058F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2A392 },
+ unicodeslot=0x2F88F,
+ },
+ [0x2F890]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x037A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5EFE },
+ unicodeslot=0x2F890,
+ },
+ [0x2F891]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x037B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x22331 },
+ unicodeslot=0x2F891,
+ },
+ [0x2F892]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x037C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x22331 },
+ unicodeslot=0x2F892,
+ },
+ [0x2F893]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x037D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8201 },
+ unicodeslot=0x2F893,
+ },
+ [0x2F894]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x037E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F22 },
+ unicodeslot=0x2F894,
+ },
+ [0x2F895]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x037F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F22 },
+ unicodeslot=0x2F895,
+ },
+ [0x2F896]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0380",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x38C7 },
+ unicodeslot=0x2F896,
+ },
+ [0x2F897]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0381",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x232B8 },
+ unicodeslot=0x2F897,
+ },
+ [0x2F898]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0382",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x261DA },
+ unicodeslot=0x2F898,
+ },
+ [0x2F899]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0383",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F62 },
+ unicodeslot=0x2F899,
+ },
+ [0x2F89A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0059A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F6B },
+ unicodeslot=0x2F89A,
+ },
+ [0x2F89B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0059B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x38E3 },
+ unicodeslot=0x2F89B,
+ },
+ [0x2F89C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0059C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5F9A },
+ unicodeslot=0x2F89C,
+ },
+ [0x2F89D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0059D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5FCD },
+ unicodeslot=0x2F89D,
+ },
+ [0x2F89E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0059E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5FD7 },
+ unicodeslot=0x2F89E,
+ },
+ [0x2F89F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0059F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5FF9 },
+ unicodeslot=0x2F89F,
+ },
+ [0x2F8A0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6081 },
+ unicodeslot=0x2F8A0,
+ },
+ [0x2F8A1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x393A },
+ unicodeslot=0x2F8A1,
+ },
+ [0x2F8A2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x391C },
+ unicodeslot=0x2F8A2,
+ },
+ [0x2F8A3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6094 },
+ unicodeslot=0x2F8A3,
+ },
+ [0x2F8A4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x226D4 },
+ unicodeslot=0x2F8A4,
+ },
+ [0x2F8A5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x60C7 },
+ unicodeslot=0x2F8A5,
+ },
+ [0x2F8A6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6148 },
+ unicodeslot=0x2F8A6,
+ },
+ [0x2F8A7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x614C },
+ unicodeslot=0x2F8A7,
+ },
+ [0x2F8A8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x614E },
+ unicodeslot=0x2F8A8,
+ },
+ [0x2F8A9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008A0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x614C },
+ unicodeslot=0x2F8A9,
+ },
+ [0x2F8AA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008AA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x617A },
+ unicodeslot=0x2F8AA,
+ },
+ [0x2F8AB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008AB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x618E },
+ unicodeslot=0x2F8AB,
+ },
+ [0x2F8AC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008AC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61B2 },
+ unicodeslot=0x2F8AC,
+ },
+ [0x2F8AD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008AD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61A4 },
+ unicodeslot=0x2F8AD,
+ },
+ [0x2F8AE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008AE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61AF },
+ unicodeslot=0x2F8AE,
+ },
+ [0x2F8AF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008AF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61DE },
+ unicodeslot=0x2F8AF,
+ },
+ [0x2F8B0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61F2 },
+ unicodeslot=0x2F8B0,
+ },
+ [0x2F8B1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x61F6 },
+ unicodeslot=0x2F8B1,
+ },
+ [0x2F8B2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6210 },
+ unicodeslot=0x2F8B2,
+ },
+ [0x2F8B3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x621B },
+ unicodeslot=0x2F8B3,
+ },
+ [0x2F8B4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x625D },
+ unicodeslot=0x2F8B4,
+ },
+ [0x2F8B5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62B1 },
+ unicodeslot=0x2F8B5,
+ },
+ [0x2F8B6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62D4 },
+ unicodeslot=0x2F8B6,
+ },
+ [0x2F8B7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6350 },
+ unicodeslot=0x2F8B7,
+ },
+ [0x2F8B8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x22B0C },
+ unicodeslot=0x2F8B8,
+ },
+ [0x2F8B9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008B0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x633D },
+ unicodeslot=0x2F8B9,
+ },
+ [0x2F8BA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008BA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x62FC },
+ unicodeslot=0x2F8BA,
+ },
+ [0x2F8BB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008BB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6368 },
+ unicodeslot=0x2F8BB,
+ },
+ [0x2F8BC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008BC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6383 },
+ unicodeslot=0x2F8BC,
+ },
+ [0x2F8BD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008BD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x63E4 },
+ unicodeslot=0x2F8BD,
+ },
+ [0x2F8BE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008BE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x22BF1 },
+ unicodeslot=0x2F8BE,
+ },
+ [0x2F8BF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008BF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6422 },
+ unicodeslot=0x2F8BF,
+ },
+ [0x2F8C0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x63C5 },
+ unicodeslot=0x2F8C0,
+ },
+ [0x2F8C1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x63A9 },
+ unicodeslot=0x2F8C1,
+ },
+ [0x2F8C2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3A2E },
+ unicodeslot=0x2F8C2,
+ },
+ [0x2F8C3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6469 },
+ unicodeslot=0x2F8C3,
+ },
+ [0x2F8C4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x647E },
+ unicodeslot=0x2F8C4,
+ },
+ [0x2F8C5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x649D },
+ unicodeslot=0x2F8C5,
+ },
+ [0x2F8C6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6477 },
+ unicodeslot=0x2F8C6,
+ },
+ [0x2F8C7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3A6C },
+ unicodeslot=0x2F8C7,
+ },
+ [0x2F8C8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x654F },
+ unicodeslot=0x2F8C8,
+ },
+ [0x2F8C9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008C0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x656C },
+ unicodeslot=0x2F8C9,
+ },
+ [0x2F8CA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008CA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2300A },
+ unicodeslot=0x2F8CA,
+ },
+ [0x2F8CB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008CB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x65E3 },
+ unicodeslot=0x2F8CB,
+ },
+ [0x2F8CC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008CC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x66F8 },
+ unicodeslot=0x2F8CC,
+ },
+ [0x2F8CD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008CD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6649 },
+ unicodeslot=0x2F8CD,
+ },
+ [0x2F8CE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008CE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3B19 },
+ unicodeslot=0x2F8CE,
+ },
+ [0x2F8CF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008CF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6691 },
+ unicodeslot=0x2F8CF,
+ },
+ [0x2F8D0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3B08 },
+ unicodeslot=0x2F8D0,
+ },
+ [0x2F8D1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3AE4 },
+ unicodeslot=0x2F8D1,
+ },
+ [0x2F8D2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5192 },
+ unicodeslot=0x2F8D2,
+ },
+ [0x2F8D3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5195 },
+ unicodeslot=0x2F8D3,
+ },
+ [0x2F8D4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6700 },
+ unicodeslot=0x2F8D4,
+ },
+ [0x2F8D5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x669C },
+ unicodeslot=0x2F8D5,
+ },
+ [0x2F8D6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x80AD },
+ unicodeslot=0x2F8D6,
+ },
+ [0x2F8D7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x43D9 },
+ unicodeslot=0x2F8D7,
+ },
+ [0x2F8D8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6717 },
+ unicodeslot=0x2F8D8,
+ },
+ [0x2F8D9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008D0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x671B },
+ unicodeslot=0x2F8D9,
+ },
+ [0x2F8DA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008DA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6721 },
+ unicodeslot=0x2F8DA,
+ },
+ [0x2F8DB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008DB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x675E },
+ unicodeslot=0x2F8DB,
+ },
+ [0x2F8DC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008DC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6753 },
+ unicodeslot=0x2F8DC,
+ },
+ [0x2F8DD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008DD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x233C3 },
+ unicodeslot=0x2F8DD,
+ },
+ [0x2F8DE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008DE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3B49 },
+ unicodeslot=0x2F8DE,
+ },
+ [0x2F8DF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008DF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x67FA },
+ unicodeslot=0x2F8DF,
+ },
+ [0x2F8E0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6785 },
+ unicodeslot=0x2F8E0,
+ },
+ [0x2F8E1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6852 },
+ unicodeslot=0x2F8E1,
+ },
+ [0x2F8E2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6885 },
+ unicodeslot=0x2F8E2,
+ },
+ [0x2F8E3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2346D },
+ unicodeslot=0x2F8E3,
+ },
+ [0x2F8E4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x688E },
+ unicodeslot=0x2F8E4,
+ },
+ [0x2F8E5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x681F },
+ unicodeslot=0x2F8E5,
+ },
+ [0x2F8E6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6914 },
+ unicodeslot=0x2F8E6,
+ },
+ [0x2F8E7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3B9D },
+ unicodeslot=0x2F8E7,
+ },
+ [0x2F8E8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6942 },
+ unicodeslot=0x2F8E8,
+ },
+ [0x2F8E9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008E0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x69A3 },
+ unicodeslot=0x2F8E9,
+ },
+ [0x2F8EA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008EA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x69EA },
+ unicodeslot=0x2F8EA,
+ },
+ [0x2F8EB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008EB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6AA8 },
+ unicodeslot=0x2F8EB,
+ },
+ [0x2F8EC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008EC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x236A3 },
+ unicodeslot=0x2F8EC,
+ },
+ [0x2F8ED]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008ED",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6ADB },
+ unicodeslot=0x2F8ED,
+ },
+ [0x2F8EE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008EE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3C18 },
+ unicodeslot=0x2F8EE,
+ },
+ [0x2F8EF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008EF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B21 },
+ unicodeslot=0x2F8EF,
+ },
+ [0x2F8F0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x238A7 },
+ unicodeslot=0x2F8F0,
+ },
+ [0x2F8F1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B54 },
+ unicodeslot=0x2F8F1,
+ },
+ [0x2F8F2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3C4E },
+ unicodeslot=0x2F8F2,
+ },
+ [0x2F8F3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B72 },
+ unicodeslot=0x2F8F3,
+ },
+ [0x2F8F4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6B9F },
+ unicodeslot=0x2F8F4,
+ },
+ [0x2F8F5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6BBA },
+ unicodeslot=0x2F8F5,
+ },
+ [0x2F8F6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6BBB },
+ unicodeslot=0x2F8F6,
+ },
+ [0x2F8F7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23A8D },
+ unicodeslot=0x2F8F7,
+ },
+ [0x2F8F8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x21D0B },
+ unicodeslot=0x2F8F8,
+ },
+ [0x2F8F9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008F0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23AFA },
+ unicodeslot=0x2F8F9,
+ },
+ [0x2F8FA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008FA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6C4E },
+ unicodeslot=0x2F8FA,
+ },
+ [0x2F8FB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008FB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23CBC },
+ unicodeslot=0x2F8FB,
+ },
+ [0x2F8FC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008FC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6CBF },
+ unicodeslot=0x2F8FC,
+ },
+ [0x2F8FD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008FD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6CCD },
+ unicodeslot=0x2F8FD,
+ },
+ [0x2F8FE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008FE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6C67 },
+ unicodeslot=0x2F8FE,
+ },
+ [0x2F8FF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0008FF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D16 },
+ unicodeslot=0x2F8FF,
+ },
+ [0x2F900]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0384",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D3E },
+ unicodeslot=0x2F900,
+ },
+ [0x2F901]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0385",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D77 },
+ unicodeslot=0x2F901,
+ },
+ [0x2F902]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0386",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D41 },
+ unicodeslot=0x2F902,
+ },
+ [0x2F903]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0387",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D69 },
+ unicodeslot=0x2F903,
+ },
+ [0x2F904]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0388",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D78 },
+ unicodeslot=0x2F904,
+ },
+ [0x2F905]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0389",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D85 },
+ unicodeslot=0x2F905,
+ },
+ [0x2F906]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x038A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23D1E },
+ unicodeslot=0x2F906,
+ },
+ [0x2F907]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x038B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6D34 },
+ unicodeslot=0x2F907,
+ },
+ [0x2F908]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x038C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6E2F },
+ unicodeslot=0x2F908,
+ },
+ [0x2F909]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x038D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6E6E },
+ unicodeslot=0x2F909,
+ },
+ [0x2F90A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005AA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3D33 },
+ unicodeslot=0x2F90A,
+ },
+ [0x2F90B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005AB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6ECB },
+ unicodeslot=0x2F90B,
+ },
+ [0x2F90C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005AC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6EC7 },
+ unicodeslot=0x2F90C,
+ },
+ [0x2F90D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005AD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23ED1 },
+ unicodeslot=0x2F90D,
+ },
+ [0x2F90E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005AE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6DF9 },
+ unicodeslot=0x2F90E,
+ },
+ [0x2F90F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005AF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6F6E },
+ unicodeslot=0x2F90F,
+ },
+ [0x2F910]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x038E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23F5E },
+ unicodeslot=0x2F910,
+ },
+ [0x2F911]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x038F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23F8E },
+ unicodeslot=0x2F911,
+ },
+ [0x2F912]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0390",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x6FC6 },
+ unicodeslot=0x2F912,
+ },
+ [0x2F913]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0391",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7039 },
+ unicodeslot=0x2F913,
+ },
+ [0x2F914]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0392",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x701E },
+ unicodeslot=0x2F914,
+ },
+ [0x2F915]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0393",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x701B },
+ unicodeslot=0x2F915,
+ },
+ [0x2F916]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0394",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3D96 },
+ unicodeslot=0x2F916,
+ },
+ [0x2F917]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0395",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x704A },
+ unicodeslot=0x2F917,
+ },
+ [0x2F918]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0396",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x707D },
+ unicodeslot=0x2F918,
+ },
+ [0x2F919]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0397",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7077 },
+ unicodeslot=0x2F919,
+ },
+ [0x2F91A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005BA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x70AD },
+ unicodeslot=0x2F91A,
+ },
+ [0x2F91B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005BB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x20525 },
+ unicodeslot=0x2F91B,
+ },
+ [0x2F91C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005BC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7145 },
+ unicodeslot=0x2F91C,
+ },
+ [0x2F91D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005BD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24263 },
+ unicodeslot=0x2F91D,
+ },
+ [0x2F91E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005BE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x719C },
+ unicodeslot=0x2F91E,
+ },
+ [0x2F91F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005BF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x243AB },
+ unicodeslot=0x2F91F,
+ },
+ [0x2F920]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0398",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7228 },
+ unicodeslot=0x2F920,
+ },
+ [0x2F921]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0399",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7235 },
+ unicodeslot=0x2F921,
+ },
+ [0x2F922]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x039A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7250 },
+ unicodeslot=0x2F922,
+ },
+ [0x2F923]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x039B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24608 },
+ unicodeslot=0x2F923,
+ },
+ [0x2F924]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x039C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7280 },
+ unicodeslot=0x2F924,
+ },
+ [0x2F925]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x039D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7295 },
+ unicodeslot=0x2F925,
+ },
+ [0x2F926]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x039E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24735 },
+ unicodeslot=0x2F926,
+ },
+ [0x2F927]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x039F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24814 },
+ unicodeslot=0x2F927,
+ },
+ [0x2F928]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A0",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x737A },
+ unicodeslot=0x2F928,
+ },
+ [0x2F929]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A1",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x738B },
+ unicodeslot=0x2F929,
+ },
+ [0x2F92A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005CA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3EAC },
+ unicodeslot=0x2F92A,
+ },
+ [0x2F92B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005CB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x73A5 },
+ unicodeslot=0x2F92B,
+ },
+ [0x2F92C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005CC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3EB8 },
+ unicodeslot=0x2F92C,
+ },
+ [0x2F92D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005CD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3EB8 },
+ unicodeslot=0x2F92D,
+ },
+ [0x2F92E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005CE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7447 },
+ unicodeslot=0x2F92E,
+ },
+ [0x2F92F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005CF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x745C },
+ unicodeslot=0x2F92F,
+ },
+ [0x2F930]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A2",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7471 },
+ unicodeslot=0x2F930,
+ },
+ [0x2F931]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A3",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7485 },
+ unicodeslot=0x2F931,
+ },
+ [0x2F932]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A4",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x74CA },
+ unicodeslot=0x2F932,
+ },
+ [0x2F933]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A5",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3F1B },
+ unicodeslot=0x2F933,
+ },
+ [0x2F934]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A6",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7524 },
+ unicodeslot=0x2F934,
+ },
+ [0x2F935]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A7",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24C36 },
+ unicodeslot=0x2F935,
+ },
+ [0x2F936]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A8",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x753E },
+ unicodeslot=0x2F936,
+ },
+ [0x2F937]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03A9",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24C92 },
+ unicodeslot=0x2F937,
+ },
+ [0x2F938]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03AA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7570 },
+ unicodeslot=0x2F938,
+ },
+ [0x2F939]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03AB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2219F },
+ unicodeslot=0x2F939,
+ },
+ [0x2F93A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005DA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7610 },
+ unicodeslot=0x2F93A,
+ },
+ [0x2F93B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005DB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24FA1 },
+ unicodeslot=0x2F93B,
+ },
+ [0x2F93C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005DC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x24FB8 },
+ unicodeslot=0x2F93C,
+ },
+ [0x2F93D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005DD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25044 },
+ unicodeslot=0x2F93D,
+ },
+ [0x2F93E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005DE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x3FFC },
+ unicodeslot=0x2F93E,
+ },
+ [0x2F93F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005DF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4008 },
+ unicodeslot=0x2F93F,
+ },
+ [0x2F940]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03AC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x76F4 },
+ unicodeslot=0x2F940,
+ },
+ [0x2F941]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03AD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x250F3 },
+ unicodeslot=0x2F941,
+ },
+ [0x2F942]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03AE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x250F2 },
+ unicodeslot=0x2F942,
+ },
+ [0x2F943]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03AF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25119 },
+ unicodeslot=0x2F943,
+ },
+ [0x2F944]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B0",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25133 },
+ unicodeslot=0x2F944,
+ },
+ [0x2F945]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B1",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x771E },
+ unicodeslot=0x2F945,
+ },
+ [0x2F946]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B2",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x771F },
+ unicodeslot=0x2F946,
+ },
+ [0x2F947]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B3",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x771F },
+ unicodeslot=0x2F947,
+ },
+ [0x2F948]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B4",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x774A },
+ unicodeslot=0x2F948,
+ },
+ [0x2F949]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B5",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4039 },
+ unicodeslot=0x2F949,
+ },
+ [0x2F94A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005EA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x778B },
+ unicodeslot=0x2F94A,
+ },
+ [0x2F94B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005EB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4046 },
+ unicodeslot=0x2F94B,
+ },
+ [0x2F94C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005EC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4096 },
+ unicodeslot=0x2F94C,
+ },
+ [0x2F94D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005ED",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2541D },
+ unicodeslot=0x2F94D,
+ },
+ [0x2F94E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005EE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x784E },
+ unicodeslot=0x2F94E,
+ },
+ [0x2F94F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005EF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x788C },
+ unicodeslot=0x2F94F,
+ },
+ [0x2F950]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B6",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x78CC },
+ unicodeslot=0x2F950,
+ },
+ [0x2F951]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B7",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x40E3 },
+ unicodeslot=0x2F951,
+ },
+ [0x2F952]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B8",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25626 },
+ unicodeslot=0x2F952,
+ },
+ [0x2F953]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03B9",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7956 },
+ unicodeslot=0x2F953,
+ },
+ [0x2F954]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03BA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2569A },
+ unicodeslot=0x2F954,
+ },
+ [0x2F955]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03BB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x256C5 },
+ unicodeslot=0x2F955,
+ },
+ [0x2F956]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03BC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x798F },
+ unicodeslot=0x2F956,
+ },
+ [0x2F957]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03BD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x79EB },
+ unicodeslot=0x2F957,
+ },
+ [0x2F958]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03BE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x412F },
+ unicodeslot=0x2F958,
+ },
+ [0x2F959]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03BF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7A40 },
+ unicodeslot=0x2F959,
+ },
+ [0x2F95A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005FA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7A4A },
+ unicodeslot=0x2F95A,
+ },
+ [0x2F95B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005FB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7A4F },
+ unicodeslot=0x2F95B,
+ },
+ [0x2F95C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005FC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2597C },
+ unicodeslot=0x2F95C,
+ },
+ [0x2F95D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005FD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25AA7 },
+ unicodeslot=0x2F95D,
+ },
+ [0x2F95E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005FE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25AA7 },
+ unicodeslot=0x2F95E,
+ },
+ [0x2F95F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x005FF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7AEE },
+ unicodeslot=0x2F95F,
+ },
+ [0x2F960]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C0",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4202 },
+ unicodeslot=0x2F960,
+ },
+ [0x2F961]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C1",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25BAB },
+ unicodeslot=0x2F961,
+ },
+ [0x2F962]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C2",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7BC6 },
+ unicodeslot=0x2F962,
+ },
+ [0x2F963]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C3",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7BC9 },
+ unicodeslot=0x2F963,
+ },
+ [0x2F964]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C4",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4227 },
+ unicodeslot=0x2F964,
+ },
+ [0x2F965]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C5",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25C80 },
+ unicodeslot=0x2F965,
+ },
+ [0x2F966]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C6",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7CD2 },
+ unicodeslot=0x2F966,
+ },
+ [0x2F967]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C7",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x42A0 },
+ unicodeslot=0x2F967,
+ },
+ [0x2F968]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C8",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7CE8 },
+ unicodeslot=0x2F968,
+ },
+ [0x2F969]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03C9",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7CE3 },
+ unicodeslot=0x2F969,
+ },
+ [0x2F96A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0060A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7D00 },
+ unicodeslot=0x2F96A,
+ },
+ [0x2F96B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0060B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x25F86 },
+ unicodeslot=0x2F96B,
+ },
+ [0x2F96C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0060C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7D63 },
+ unicodeslot=0x2F96C,
+ },
+ [0x2F96D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0060D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4301 },
+ unicodeslot=0x2F96D,
+ },
+ [0x2F96E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0060E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7DC7 },
+ unicodeslot=0x2F96E,
+ },
+ [0x2F96F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0060F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7E02 },
+ unicodeslot=0x2F96F,
+ },
+ [0x2F970]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03CA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7E45 },
+ unicodeslot=0x2F970,
+ },
+ [0x2F971]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03CB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4334 },
+ unicodeslot=0x2F971,
+ },
+ [0x2F972]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03CC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26228 },
+ unicodeslot=0x2F972,
+ },
+ [0x2F973]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03CD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26247 },
+ unicodeslot=0x2F973,
+ },
+ [0x2F974]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03CE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4359 },
+ unicodeslot=0x2F974,
+ },
+ [0x2F975]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03CF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x262D9 },
+ unicodeslot=0x2F975,
+ },
+ [0x2F976]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D0",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F7A },
+ unicodeslot=0x2F976,
+ },
+ [0x2F977]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D1",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2633E },
+ unicodeslot=0x2F977,
+ },
+ [0x2F978]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D2",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7F95 },
+ unicodeslot=0x2F978,
+ },
+ [0x2F979]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D3",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x7FFA },
+ unicodeslot=0x2F979,
+ },
+ [0x2F97A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0061A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8005 },
+ unicodeslot=0x2F97A,
+ },
+ [0x2F97B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0061B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x264DA },
+ unicodeslot=0x2F97B,
+ },
+ [0x2F97C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0061C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26523 },
+ unicodeslot=0x2F97C,
+ },
+ [0x2F97D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0061D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8060 },
+ unicodeslot=0x2F97D,
+ },
+ [0x2F97E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0061E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x265A8 },
+ unicodeslot=0x2F97E,
+ },
+ [0x2F97F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0061F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8070 },
+ unicodeslot=0x2F97F,
+ },
+ [0x2F980]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D4",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2335F },
+ unicodeslot=0x2F980,
+ },
+ [0x2F981]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D5",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x43D5 },
+ unicodeslot=0x2F981,
+ },
+ [0x2F982]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D6",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x80B2 },
+ unicodeslot=0x2F982,
+ },
+ [0x2F983]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D7",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8103 },
+ unicodeslot=0x2F983,
+ },
+ [0x2F984]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D8",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x440B },
+ unicodeslot=0x2F984,
+ },
+ [0x2F985]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03D9",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x813E },
+ unicodeslot=0x2F985,
+ },
+ [0x2F986]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03DA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5AB5 },
+ unicodeslot=0x2F986,
+ },
+ [0x2F987]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03DB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x267A7 },
+ unicodeslot=0x2F987,
+ },
+ [0x2F988]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03DC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x267B5 },
+ unicodeslot=0x2F988,
+ },
+ [0x2F989]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03DD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x23393 },
+ unicodeslot=0x2F989,
+ },
+ [0x2F98A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0062A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2339C },
+ unicodeslot=0x2F98A,
+ },
+ [0x2F98B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0062B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8201 },
+ unicodeslot=0x2F98B,
+ },
+ [0x2F98C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0062C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8204 },
+ unicodeslot=0x2F98C,
+ },
+ [0x2F98D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0062D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F9E },
+ unicodeslot=0x2F98D,
+ },
+ [0x2F98E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0062E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x446B },
+ unicodeslot=0x2F98E,
+ },
+ [0x2F98F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0062F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8291 },
+ unicodeslot=0x2F98F,
+ },
+ [0x2F990]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03DE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x828B },
+ unicodeslot=0x2F990,
+ },
+ [0x2F991]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03DF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x829D },
+ unicodeslot=0x2F991,
+ },
+ [0x2F992]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E0",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x52B3 },
+ unicodeslot=0x2F992,
+ },
+ [0x2F993]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E1",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x82B1 },
+ unicodeslot=0x2F993,
+ },
+ [0x2F994]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E2",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x82B3 },
+ unicodeslot=0x2F994,
+ },
+ [0x2F995]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E3",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x82BD },
+ unicodeslot=0x2F995,
+ },
+ [0x2F996]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E4",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x82E6 },
+ unicodeslot=0x2F996,
+ },
+ [0x2F997]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E5",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26B3C },
+ unicodeslot=0x2F997,
+ },
+ [0x2F998]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E6",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x82E5 },
+ unicodeslot=0x2F998,
+ },
+ [0x2F999]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x03E7",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x831D },
+ unicodeslot=0x2F999,
+ },
+ [0x2F99A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0063A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8363 },
+ unicodeslot=0x2F99A,
+ },
+ [0x2F99B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0063B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83AD },
+ unicodeslot=0x2F99B,
+ },
+ [0x2F99C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0063C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8323 },
+ unicodeslot=0x2F99C,
+ },
+ [0x2F99D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0063D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83BD },
+ unicodeslot=0x2F99D,
+ },
+ [0x2F99E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0063E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83E7 },
+ unicodeslot=0x2F99E,
+ },
+ [0x2F99F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0063F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8457 },
+ unicodeslot=0x2F99F,
+ },
+ [0x2F9A0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8353 },
+ unicodeslot=0x2F9A0,
+ },
+ [0x2F9A1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83CA },
+ unicodeslot=0x2F9A1,
+ },
+ [0x2F9A2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83CC },
+ unicodeslot=0x2F9A2,
+ },
+ [0x2F9A3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x83DC },
+ unicodeslot=0x2F9A3,
+ },
+ [0x2F9A4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26C36 },
+ unicodeslot=0x2F9A4,
+ },
+ [0x2F9A5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26D6B },
+ unicodeslot=0x2F9A5,
+ },
+ [0x2F9A6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26CD5 },
+ unicodeslot=0x2F9A6,
+ },
+ [0x2F9A7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x452B },
+ unicodeslot=0x2F9A7,
+ },
+ [0x2F9A8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x84F1 },
+ unicodeslot=0x2F9A8,
+ },
+ [0x2F9A9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009A0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x84F3 },
+ unicodeslot=0x2F9A9,
+ },
+ [0x2F9AA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009AA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8516 },
+ unicodeslot=0x2F9AA,
+ },
+ [0x2F9AB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009AB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x273CA },
+ unicodeslot=0x2F9AB,
+ },
+ [0x2F9AC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009AC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8564 },
+ unicodeslot=0x2F9AC,
+ },
+ [0x2F9AD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009AD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26F2C },
+ unicodeslot=0x2F9AD,
+ },
+ [0x2F9AE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009AE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x455D },
+ unicodeslot=0x2F9AE,
+ },
+ [0x2F9AF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009AF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4561 },
+ unicodeslot=0x2F9AF,
+ },
+ [0x2F9B0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x26FB1 },
+ unicodeslot=0x2F9B0,
+ },
+ [0x2F9B1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x270D2 },
+ unicodeslot=0x2F9B1,
+ },
+ [0x2F9B2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x456B },
+ unicodeslot=0x2F9B2,
+ },
+ [0x2F9B3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8650 },
+ unicodeslot=0x2F9B3,
+ },
+ [0x2F9B4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x865C },
+ unicodeslot=0x2F9B4,
+ },
+ [0x2F9B5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8667 },
+ unicodeslot=0x2F9B5,
+ },
+ [0x2F9B6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8669 },
+ unicodeslot=0x2F9B6,
+ },
+ [0x2F9B7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x86A9 },
+ unicodeslot=0x2F9B7,
+ },
+ [0x2F9B8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8688 },
+ unicodeslot=0x2F9B8,
+ },
+ [0x2F9B9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009B0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x870E },
+ unicodeslot=0x2F9B9,
+ },
+ [0x2F9BA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009BA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x86E2 },
+ unicodeslot=0x2F9BA,
+ },
+ [0x2F9BB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009BB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8779 },
+ unicodeslot=0x2F9BB,
+ },
+ [0x2F9BC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009BC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8728 },
+ unicodeslot=0x2F9BC,
+ },
+ [0x2F9BD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009BD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x876B },
+ unicodeslot=0x2F9BD,
+ },
+ [0x2F9BE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009BE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8786 },
+ unicodeslot=0x2F9BE,
+ },
+ [0x2F9BF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009BF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x45D7 },
+ unicodeslot=0x2F9BF,
+ },
+ [0x2F9C0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x87E1 },
+ unicodeslot=0x2F9C0,
+ },
+ [0x2F9C1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8801 },
+ unicodeslot=0x2F9C1,
+ },
+ [0x2F9C2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x45F9 },
+ unicodeslot=0x2F9C2,
+ },
+ [0x2F9C3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8860 },
+ unicodeslot=0x2F9C3,
+ },
+ [0x2F9C4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8863 },
+ unicodeslot=0x2F9C4,
+ },
+ [0x2F9C5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x27667 },
+ unicodeslot=0x2F9C5,
+ },
+ [0x2F9C6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88D7 },
+ unicodeslot=0x2F9C6,
+ },
+ [0x2F9C7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88DE },
+ unicodeslot=0x2F9C7,
+ },
+ [0x2F9C8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4635 },
+ unicodeslot=0x2F9C8,
+ },
+ [0x2F9C9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009C0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x88FA },
+ unicodeslot=0x2F9C9,
+ },
+ [0x2F9CA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009CA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x34BB },
+ unicodeslot=0x2F9CA,
+ },
+ [0x2F9CB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009CB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x278AE },
+ unicodeslot=0x2F9CB,
+ },
+ [0x2F9CC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009CC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x27966 },
+ unicodeslot=0x2F9CC,
+ },
+ [0x2F9CD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009CD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x46BE },
+ unicodeslot=0x2F9CD,
+ },
+ [0x2F9CE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009CE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x46C7 },
+ unicodeslot=0x2F9CE,
+ },
+ [0x2F9CF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009CF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AA0 },
+ unicodeslot=0x2F9CF,
+ },
+ [0x2F9D0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8AED },
+ unicodeslot=0x2F9D0,
+ },
+ [0x2F9D1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8B8A },
+ unicodeslot=0x2F9D1,
+ },
+ [0x2F9D2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8C55 },
+ unicodeslot=0x2F9D2,
+ },
+ [0x2F9D3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x27CA8 },
+ unicodeslot=0x2F9D3,
+ },
+ [0x2F9D4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8CAB },
+ unicodeslot=0x2F9D4,
+ },
+ [0x2F9D5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8CC1 },
+ unicodeslot=0x2F9D5,
+ },
+ [0x2F9D6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8D1B },
+ unicodeslot=0x2F9D6,
+ },
+ [0x2F9D7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8D77 },
+ unicodeslot=0x2F9D7,
+ },
+ [0x2F9D8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x27F2F },
+ unicodeslot=0x2F9D8,
+ },
+ [0x2F9D9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009D0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x20804 },
+ unicodeslot=0x2F9D9,
+ },
+ [0x2F9DA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009DA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8DCB },
+ unicodeslot=0x2F9DA,
+ },
+ [0x2F9DB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009DB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8DBC },
+ unicodeslot=0x2F9DB,
+ },
+ [0x2F9DC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009DC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8DF0 },
+ unicodeslot=0x2F9DC,
+ },
+ [0x2F9DD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009DD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x208DE },
+ unicodeslot=0x2F9DD,
+ },
+ [0x2F9DE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009DE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8ED4 },
+ unicodeslot=0x2F9DE,
+ },
+ [0x2F9DF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009DF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x8F38 },
+ unicodeslot=0x2F9DF,
+ },
+ [0x2F9E0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x285D2 },
+ unicodeslot=0x2F9E0,
+ },
+ [0x2F9E1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x285ED },
+ unicodeslot=0x2F9E1,
+ },
+ [0x2F9E2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9094 },
+ unicodeslot=0x2F9E2,
+ },
+ [0x2F9E3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x90F1 },
+ unicodeslot=0x2F9E3,
+ },
+ [0x2F9E4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9111 },
+ unicodeslot=0x2F9E4,
+ },
+ [0x2F9E5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2872E },
+ unicodeslot=0x2F9E5,
+ },
+ [0x2F9E6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x911B },
+ unicodeslot=0x2F9E6,
+ },
+ [0x2F9E7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9238 },
+ unicodeslot=0x2F9E7,
+ },
+ [0x2F9E8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x92D7 },
+ unicodeslot=0x2F9E8,
+ },
+ [0x2F9E9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009E0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x92D8 },
+ unicodeslot=0x2F9E9,
+ },
+ [0x2F9EA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009EA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x927C },
+ unicodeslot=0x2F9EA,
+ },
+ [0x2F9EB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009EB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x93F9 },
+ unicodeslot=0x2F9EB,
+ },
+ [0x2F9EC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009EC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9415 },
+ unicodeslot=0x2F9EC,
+ },
+ [0x2F9ED]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009ED",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x28BFA },
+ unicodeslot=0x2F9ED,
+ },
+ [0x2F9EE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009EE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x958B },
+ unicodeslot=0x2F9EE,
+ },
+ [0x2F9EF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009EF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4995 },
+ unicodeslot=0x2F9EF,
+ },
+ [0x2F9F0]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x95B7 },
+ unicodeslot=0x2F9F0,
+ },
+ [0x2F9F1]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x28D77 },
+ unicodeslot=0x2F9F1,
+ },
+ [0x2F9F2]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x49E6 },
+ unicodeslot=0x2F9F2,
+ },
+ [0x2F9F3]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x96C3 },
+ unicodeslot=0x2F9F3,
+ },
+ [0x2F9F4]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x5DB2 },
+ unicodeslot=0x2F9F4,
+ },
+ [0x2F9F5]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9723 },
+ unicodeslot=0x2F9F5,
+ },
+ [0x2F9F6]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x29145 },
+ unicodeslot=0x2F9F6,
+ },
+ [0x2F9F7]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2921A },
+ unicodeslot=0x2F9F7,
+ },
+ [0x2F9F8]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4A6E },
+ unicodeslot=0x2F9F8,
+ },
+ [0x2F9F9]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009F0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4A76 },
+ unicodeslot=0x2F9F9,
+ },
+ [0x2F9FA]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009FA",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x97E0 },
+ unicodeslot=0x2F9FA,
+ },
+ [0x2F9FB]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009FB",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2940A },
+ unicodeslot=0x2F9FB,
+ },
+ [0x2F9FC]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009FC",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4AB2 },
+ unicodeslot=0x2F9FC,
+ },
+ [0x2F9FD]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009FD",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x29496 },
+ unicodeslot=0x2F9FD,
+ },
+ [0x2F9FE]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009FE",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x980B },
+ unicodeslot=0x2F9FE,
+ },
+ [0x2F9FF]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002F0x0009FF",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x980B },
+ unicodeslot=0x2F9FF,
+ },
+ [0x2FA00]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9829 },
+ unicodeslot=0x2FA00,
+ },
+ [0x2FA01]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0001",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x295B6 },
+ unicodeslot=0x2FA01,
+ },
+ [0x2FA02]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0002",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x98E2 },
+ unicodeslot=0x2FA02,
+ },
+ [0x2FA03]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0003",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4B33 },
+ unicodeslot=0x2FA03,
+ },
+ [0x2FA04]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0004",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9929 },
+ unicodeslot=0x2FA04,
+ },
+ [0x2FA05]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0005",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x99A7 },
+ unicodeslot=0x2FA05,
+ },
+ [0x2FA06]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0006",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x99C2 },
+ unicodeslot=0x2FA06,
+ },
+ [0x2FA07]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0007",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x99FE },
+ unicodeslot=0x2FA07,
+ },
+ [0x2FA08]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0008",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4BCE },
+ unicodeslot=0x2FA08,
+ },
+ [0x2FA09]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0009",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x29B30 },
+ unicodeslot=0x2FA09,
+ },
+ [0x2FA0A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9B12 },
+ unicodeslot=0x2FA0A,
+ },
+ [0x2FA0B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9C40 },
+ unicodeslot=0x2FA0B,
+ },
+ [0x2FA0C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9CFD },
+ unicodeslot=0x2FA0C,
+ },
+ [0x2FA0D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4CCE },
+ unicodeslot=0x2FA0D,
+ },
+ [0x2FA0E]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4CED },
+ unicodeslot=0x2FA0E,
+ },
+ [0x2FA0F]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0000F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9D67 },
+ unicodeslot=0x2FA0F,
+ },
+ [0x2FA10]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x000A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2A0CE },
+ unicodeslot=0x2FA10,
+ },
+ [0x2FA11]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x000B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4CF8 },
+ unicodeslot=0x2FA11,
+ },
+ [0x2FA12]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x000C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2A105 },
+ unicodeslot=0x2FA12,
+ },
+ [0x2FA13]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x000D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2A20E },
+ unicodeslot=0x2FA13,
+ },
+ [0x2FA14]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x000E",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2A291 },
+ unicodeslot=0x2FA14,
+ },
+ [0x2FA15]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x000F",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9EBB },
+ unicodeslot=0x2FA15,
+ },
+ [0x2FA16]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0010",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x4D56 },
+ unicodeslot=0x2FA16,
+ },
+ [0x2FA17]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0011",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9EF9 },
+ unicodeslot=0x2FA17,
+ },
+ [0x2FA18]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0012",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9EFE },
+ unicodeslot=0x2FA18,
+ },
+ [0x2FA19]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0013",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F05 },
+ unicodeslot=0x2FA19,
+ },
+ [0x2FA1A]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0001A",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F0F },
+ unicodeslot=0x2FA1A,
+ },
+ [0x2FA1B]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0001B",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F16 },
+ unicodeslot=0x2FA1B,
+ },
+ [0x2FA1C]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0001C",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x9F3B },
+ unicodeslot=0x2FA1C,
+ },
+ [0x2FA1D]={
+ category="lo",
+ cjkwd="w",
+ description="CJK COMPATIBILITY IDEOGRAPH-0x0002FA0x0001D",
+ direction="l",
+ linebreak="id",
+ specials={ "char", 0x2A600 },
+ unicodeslot=0x2FA1D,
+ },
+ [0xE0001]={
+ category="cf",
+ description="LANGUAGE TAG",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0001,
+ },
+ [0xE0020]={
+ category="cf",
+ description="TAG SPACE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0020,
+ },
+ [0xE0021]={
+ category="cf",
+ description="TAG EXCLAMATION MARK",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0021,
+ },
+ [0xE0022]={
+ category="cf",
+ description="TAG QUOTATION MARK",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0022,
+ },
+ [0xE0023]={
+ category="cf",
+ description="TAG NUMBER SIGN",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0023,
+ },
+ [0xE0024]={
+ category="cf",
+ description="TAG DOLLAR SIGN",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0024,
+ },
+ [0xE0025]={
+ category="cf",
+ description="TAG PERCENT SIGN",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0025,
+ },
+ [0xE0026]={
+ category="cf",
+ description="TAG AMPERSAND",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0026,
+ },
+ [0xE0027]={
+ category="cf",
+ description="TAG APOSTROPHE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0027,
+ },
+ [0xE0028]={
+ category="cf",
+ description="TAG LEFT PARENTHESIS",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0028,
+ },
+ [0xE0029]={
+ category="cf",
+ description="TAG RIGHT PARENTHESIS",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0029,
+ },
+ [0xE002A]={
+ category="cf",
+ description="TAG ASTERISK",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE002A,
+ },
+ [0xE002B]={
+ category="cf",
+ description="TAG PLUS SIGN",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE002B,
+ },
+ [0xE002C]={
+ category="cf",
+ description="TAG COMMA",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE002C,
+ },
+ [0xE002D]={
+ category="cf",
+ description="TAG HYPHEN-MINUS",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE002D,
+ },
+ [0xE002E]={
+ category="cf",
+ description="TAG FULL STOP",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE002E,
+ },
+ [0xE002F]={
+ category="cf",
+ description="TAG SOLIDUS",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE002F,
+ },
+ [0xE0030]={
+ category="cf",
+ description="TAG DIGIT ZERO",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0030,
+ },
+ [0xE0031]={
+ category="cf",
+ description="TAG DIGIT ONE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0031,
+ },
+ [0xE0032]={
+ category="cf",
+ description="TAG DIGIT TWO",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0032,
+ },
+ [0xE0033]={
+ category="cf",
+ description="TAG DIGIT THREE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0033,
+ },
+ [0xE0034]={
+ category="cf",
+ description="TAG DIGIT FOUR",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0034,
+ },
+ [0xE0035]={
+ category="cf",
+ description="TAG DIGIT FIVE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0035,
+ },
+ [0xE0036]={
+ category="cf",
+ description="TAG DIGIT SIX",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0036,
+ },
+ [0xE0037]={
+ category="cf",
+ description="TAG DIGIT SEVEN",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0037,
+ },
+ [0xE0038]={
+ category="cf",
+ description="TAG DIGIT EIGHT",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0038,
+ },
+ [0xE0039]={
+ category="cf",
+ description="TAG DIGIT NINE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0039,
+ },
+ [0xE003A]={
+ category="cf",
+ description="TAG COLON",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE003A,
+ },
+ [0xE003B]={
+ category="cf",
+ description="TAG SEMICOLON",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE003B,
+ },
+ [0xE003C]={
+ category="cf",
+ description="TAG LESS-THAN SIGN",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE003C,
+ },
+ [0xE003D]={
+ category="cf",
+ description="TAG EQUALS SIGN",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE003D,
+ },
+ [0xE003E]={
+ category="cf",
+ description="TAG GREATER-THAN SIGN",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE003E,
+ },
+ [0xE003F]={
+ category="cf",
+ description="TAG QUESTION MARK",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE003F,
+ },
+ [0xE0040]={
+ category="cf",
+ description="TAG COMMERCIAL AT",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0040,
+ },
+ [0xE0041]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER A",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0041,
+ },
+ [0xE0042]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER B",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0042,
+ },
+ [0xE0043]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER C",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0043,
+ },
+ [0xE0044]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER D",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0044,
+ },
+ [0xE0045]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER E",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0045,
+ },
+ [0xE0046]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER F",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0046,
+ },
+ [0xE0047]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER G",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0047,
+ },
+ [0xE0048]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER H",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0048,
+ },
+ [0xE0049]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER I",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0049,
+ },
+ [0xE004A]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER J",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE004A,
+ },
+ [0xE004B]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER K",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE004B,
+ },
+ [0xE004C]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER L",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE004C,
+ },
+ [0xE004D]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER M",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE004D,
+ },
+ [0xE004E]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER N",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE004E,
+ },
+ [0xE004F]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER O",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE004F,
+ },
+ [0xE0050]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER P",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0050,
+ },
+ [0xE0051]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER Q",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0051,
+ },
+ [0xE0052]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER R",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0052,
+ },
+ [0xE0053]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER S",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0053,
+ },
+ [0xE0054]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER T",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0054,
+ },
+ [0xE0055]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER U",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0055,
+ },
+ [0xE0056]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER V",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0056,
+ },
+ [0xE0057]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER W",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0057,
+ },
+ [0xE0058]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER X",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0058,
+ },
+ [0xE0059]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER Y",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0059,
+ },
+ [0xE005A]={
+ category="cf",
+ description="TAG LATIN CAPITAL LETTER Z",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE005A,
+ },
+ [0xE005B]={
+ category="cf",
+ description="TAG LEFT SQUARE BRACKET",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE005B,
+ },
+ [0xE005C]={
+ category="cf",
+ description="TAG REVERSE SOLIDUS",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE005C,
+ },
+ [0xE005D]={
+ category="cf",
+ description="TAG RIGHT SQUARE BRACKET",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE005D,
+ },
+ [0xE005E]={
+ category="cf",
+ description="TAG CIRCUMFLEX ACCENT",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE005E,
+ },
+ [0xE005F]={
+ category="cf",
+ description="TAG LOW LINE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE005F,
+ },
+ [0xE0060]={
+ category="cf",
+ description="TAG GRAVE ACCENT",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0060,
+ },
+ [0xE0061]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER A",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0061,
+ },
+ [0xE0062]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER B",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0062,
+ },
+ [0xE0063]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER C",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0063,
+ },
+ [0xE0064]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER D",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0064,
+ },
+ [0xE0065]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER E",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0065,
+ },
+ [0xE0066]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER F",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0066,
+ },
+ [0xE0067]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER G",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0067,
+ },
+ [0xE0068]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER H",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0068,
+ },
+ [0xE0069]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER I",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0069,
+ },
+ [0xE006A]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER J",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE006A,
+ },
+ [0xE006B]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER K",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE006B,
+ },
+ [0xE006C]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER L",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE006C,
+ },
+ [0xE006D]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER M",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE006D,
+ },
+ [0xE006E]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER N",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE006E,
+ },
+ [0xE006F]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER O",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE006F,
+ },
+ [0xE0070]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER P",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0070,
+ },
+ [0xE0071]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER Q",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0071,
+ },
+ [0xE0072]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER R",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0072,
+ },
+ [0xE0073]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER S",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0073,
+ },
+ [0xE0074]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER T",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0074,
+ },
+ [0xE0075]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER U",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0075,
+ },
+ [0xE0076]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER V",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0076,
+ },
+ [0xE0077]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER W",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0077,
+ },
+ [0xE0078]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER X",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0078,
+ },
+ [0xE0079]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER Y",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE0079,
+ },
+ [0xE007A]={
+ category="cf",
+ description="TAG LATIN SMALL LETTER Z",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE007A,
+ },
+ [0xE007B]={
+ category="cf",
+ description="TAG LEFT CURLY BRACKET",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE007B,
+ },
+ [0xE007C]={
+ category="cf",
+ description="TAG VERTICAL LINE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE007C,
+ },
+ [0xE007D]={
+ category="cf",
+ description="TAG RIGHT CURLY BRACKET",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE007D,
+ },
+ [0xE007E]={
+ category="cf",
+ description="TAG TILDE",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE007E,
+ },
+ [0xE007F]={
+ category="cf",
+ description="CANCEL TAG",
+ direction="bn",
+ linebreak="cm",
+ unicodeslot=0xE007F,
+ },
+ [0xE0100]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0011",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0100,
+ },
+ [0xE0101]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0012",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0101,
+ },
+ [0xE0102]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0013",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0102,
+ },
+ [0xE0103]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0014",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0103,
+ },
+ [0xE0104]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0015",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0104,
+ },
+ [0xE0105]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0016",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0105,
+ },
+ [0xE0106]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0017",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0106,
+ },
+ [0xE0107]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0018",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0107,
+ },
+ [0xE0108]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0019",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0108,
+ },
+ [0xE0109]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x001A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0109,
+ },
+ [0xE010A]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x001B",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE010A,
+ },
+ [0xE010B]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x001C",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE010B,
+ },
+ [0xE010C]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x001D",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE010C,
+ },
+ [0xE010D]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x001E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE010D,
+ },
+ [0xE010E]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x001F",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE010E,
+ },
+ [0xE010F]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0020",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE010F,
+ },
+ [0xE0110]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0021",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0110,
+ },
+ [0xE0111]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0022",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0111,
+ },
+ [0xE0112]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0023",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0112,
+ },
+ [0xE0113]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0024",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0113,
+ },
+ [0xE0114]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0025",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0114,
+ },
+ [0xE0115]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0026",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0115,
+ },
+ [0xE0116]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0027",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0116,
+ },
+ [0xE0117]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0028",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0117,
+ },
+ [0xE0118]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0029",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0118,
+ },
+ [0xE0119]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x002A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0119,
+ },
+ [0xE011A]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x002B",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE011A,
+ },
+ [0xE011B]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x002C",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE011B,
+ },
+ [0xE011C]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x002D",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE011C,
+ },
+ [0xE011D]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x002E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE011D,
+ },
+ [0xE011E]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x002F",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE011E,
+ },
+ [0xE011F]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0030",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE011F,
+ },
+ [0xE0120]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0031",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0120,
+ },
+ [0xE0121]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0032",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0121,
+ },
+ [0xE0122]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0033",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0122,
+ },
+ [0xE0123]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0034",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0123,
+ },
+ [0xE0124]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0035",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0124,
+ },
+ [0xE0125]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0036",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0125,
+ },
+ [0xE0126]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0037",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0126,
+ },
+ [0xE0127]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0038",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0127,
+ },
+ [0xE0128]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0039",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0128,
+ },
+ [0xE0129]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x003A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0129,
+ },
+ [0xE012A]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x003B",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE012A,
+ },
+ [0xE012B]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x003C",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE012B,
+ },
+ [0xE012C]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x003D",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE012C,
+ },
+ [0xE012D]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x003E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE012D,
+ },
+ [0xE012E]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x003F",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE012E,
+ },
+ [0xE012F]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0040",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE012F,
+ },
+ [0xE0130]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0041",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0130,
+ },
+ [0xE0131]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0042",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0131,
+ },
+ [0xE0132]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0043",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0132,
+ },
+ [0xE0133]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0044",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0133,
+ },
+ [0xE0134]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0045",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0134,
+ },
+ [0xE0135]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0046",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0135,
+ },
+ [0xE0136]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0047",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0136,
+ },
+ [0xE0137]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0048",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0137,
+ },
+ [0xE0138]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0049",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0138,
+ },
+ [0xE0139]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x004A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0139,
+ },
+ [0xE013A]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x004B",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE013A,
+ },
+ [0xE013B]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x004C",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE013B,
+ },
+ [0xE013C]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x004D",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE013C,
+ },
+ [0xE013D]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x004E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE013D,
+ },
+ [0xE013E]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x004F",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE013E,
+ },
+ [0xE013F]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0050",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE013F,
+ },
+ [0xE0140]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0051",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0140,
+ },
+ [0xE0141]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0052",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0141,
+ },
+ [0xE0142]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0053",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0142,
+ },
+ [0xE0143]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0054",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0143,
+ },
+ [0xE0144]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0055",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0144,
+ },
+ [0xE0145]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0056",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0145,
+ },
+ [0xE0146]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0057",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0146,
+ },
+ [0xE0147]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0058",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0147,
+ },
+ [0xE0148]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0059",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0148,
+ },
+ [0xE0149]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x005A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0149,
+ },
+ [0xE014A]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x005B",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE014A,
+ },
+ [0xE014B]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x005C",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE014B,
+ },
+ [0xE014C]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x005D",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE014C,
+ },
+ [0xE014D]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x005E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE014D,
+ },
+ [0xE014E]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x005F",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE014E,
+ },
+ [0xE014F]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0060",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE014F,
+ },
+ [0xE0150]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0061",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0150,
+ },
+ [0xE0151]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0062",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0151,
+ },
+ [0xE0152]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0063",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0152,
+ },
+ [0xE0153]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0064",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0153,
+ },
+ [0xE0154]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0065",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0154,
+ },
+ [0xE0155]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0066",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0155,
+ },
+ [0xE0156]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0067",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0156,
+ },
+ [0xE0157]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0068",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0157,
+ },
+ [0xE0158]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0069",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0158,
+ },
+ [0xE0159]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x006A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0159,
+ },
+ [0xE015A]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x006B",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE015A,
+ },
+ [0xE015B]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x006C",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE015B,
+ },
+ [0xE015C]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x006D",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE015C,
+ },
+ [0xE015D]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x006E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE015D,
+ },
+ [0xE015E]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x006F",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE015E,
+ },
+ [0xE015F]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0070",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE015F,
+ },
+ [0xE0160]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0071",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0160,
+ },
+ [0xE0161]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0072",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0161,
+ },
+ [0xE0162]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0073",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0162,
+ },
+ [0xE0163]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0074",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0163,
+ },
+ [0xE0164]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0075",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0164,
+ },
+ [0xE0165]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0076",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0165,
+ },
+ [0xE0166]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0077",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0166,
+ },
+ [0xE0167]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0078",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0167,
+ },
+ [0xE0168]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0079",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0168,
+ },
+ [0xE0169]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x007A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0169,
+ },
+ [0xE016A]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x007B",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE016A,
+ },
+ [0xE016B]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x007C",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE016B,
+ },
+ [0xE016C]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x007D",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE016C,
+ },
+ [0xE016D]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x007E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE016D,
+ },
+ [0xE016E]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x007F",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE016E,
+ },
+ [0xE016F]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0080",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE016F,
+ },
+ [0xE0170]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0081",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0170,
+ },
+ [0xE0171]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0082",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0171,
+ },
+ [0xE0172]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0083",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0172,
+ },
+ [0xE0173]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0084",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0173,
+ },
+ [0xE0174]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0085",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0174,
+ },
+ [0xE0175]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0086",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0175,
+ },
+ [0xE0176]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0087",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0176,
+ },
+ [0xE0177]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0088",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0177,
+ },
+ [0xE0178]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0089",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0178,
+ },
+ [0xE0179]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x008A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0179,
+ },
+ [0xE017A]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x008B",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE017A,
+ },
+ [0xE017B]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x008C",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE017B,
+ },
+ [0xE017C]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x008D",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE017C,
+ },
+ [0xE017D]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x008E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE017D,
+ },
+ [0xE017E]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x008F",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE017E,
+ },
+ [0xE017F]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0090",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE017F,
+ },
+ [0xE0180]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0091",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0180,
+ },
+ [0xE0181]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0092",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0181,
+ },
+ [0xE0182]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0093",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0182,
+ },
+ [0xE0183]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0094",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0183,
+ },
+ [0xE0184]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0095",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0184,
+ },
+ [0xE0185]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0096",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0185,
+ },
+ [0xE0186]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0097",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0186,
+ },
+ [0xE0187]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0098",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0187,
+ },
+ [0xE0188]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0099",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0188,
+ },
+ [0xE0189]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x009A",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0189,
+ },
+ [0xE018A]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x009B",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE018A,
+ },
+ [0xE018B]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x009C",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE018B,
+ },
+ [0xE018C]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x009D",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE018C,
+ },
+ [0xE018D]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x009E",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE018D,
+ },
+ [0xE018E]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x009F",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE018E,
+ },
+ [0xE018F]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00A0",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE018F,
+ },
+ [0xE0190]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00A1",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0190,
+ },
+ [0xE0191]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00A2",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0191,
+ },
+ [0xE0192]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00A3",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0192,
+ },
+ [0xE0193]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00A4",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0193,
+ },
+ [0xE0194]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00A5",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0194,
+ },
+ [0xE0195]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00A6",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0195,
+ },
+ [0xE0196]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00A7",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0196,
+ },
+ [0xE0197]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00A8",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0197,
+ },
+ [0xE0198]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00A9",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0198,
+ },
+ [0xE0199]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00AA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE0199,
+ },
+ [0xE019A]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00AB",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE019A,
+ },
+ [0xE019B]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00AC",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE019B,
+ },
+ [0xE019C]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00AD",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE019C,
+ },
+ [0xE019D]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00AE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE019D,
+ },
+ [0xE019E]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00AF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE019E,
+ },
+ [0xE019F]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00B0",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE019F,
+ },
+ [0xE01A0]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00B1",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01A0,
+ },
+ [0xE01A1]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00B2",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01A1,
+ },
+ [0xE01A2]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00B3",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01A2,
+ },
+ [0xE01A3]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00B4",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01A3,
+ },
+ [0xE01A4]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00B5",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01A4,
+ },
+ [0xE01A5]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00B6",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01A5,
+ },
+ [0xE01A6]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00B7",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01A6,
+ },
+ [0xE01A7]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00B8",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01A7,
+ },
+ [0xE01A8]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00B9",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01A8,
+ },
+ [0xE01A9]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00BA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01A9,
+ },
+ [0xE01AA]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00BB",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01AA,
+ },
+ [0xE01AB]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00BC",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01AB,
+ },
+ [0xE01AC]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00BD",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01AC,
+ },
+ [0xE01AD]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00BE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01AD,
+ },
+ [0xE01AE]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00BF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01AE,
+ },
+ [0xE01AF]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00C0",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01AF,
+ },
+ [0xE01B0]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00C1",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01B0,
+ },
+ [0xE01B1]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00C2",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01B1,
+ },
+ [0xE01B2]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00C3",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01B2,
+ },
+ [0xE01B3]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00C4",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01B3,
+ },
+ [0xE01B4]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00C5",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01B4,
+ },
+ [0xE01B5]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00C6",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01B5,
+ },
+ [0xE01B6]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00C7",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01B6,
+ },
+ [0xE01B7]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00C8",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01B7,
+ },
+ [0xE01B8]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00C9",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01B8,
+ },
+ [0xE01B9]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00CA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01B9,
+ },
+ [0xE01BA]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00CB",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01BA,
+ },
+ [0xE01BB]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00CC",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01BB,
+ },
+ [0xE01BC]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00CD",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01BC,
+ },
+ [0xE01BD]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00CE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01BD,
+ },
+ [0xE01BE]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00CF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01BE,
+ },
+ [0xE01BF]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00D0",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01BF,
+ },
+ [0xE01C0]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00D1",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01C0,
+ },
+ [0xE01C1]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00D2",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01C1,
+ },
+ [0xE01C2]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00D3",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01C2,
+ },
+ [0xE01C3]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00D4",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01C3,
+ },
+ [0xE01C4]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00D5",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01C4,
+ },
+ [0xE01C5]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00D6",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01C5,
+ },
+ [0xE01C6]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00D7",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01C6,
+ },
+ [0xE01C7]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00D8",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01C7,
+ },
+ [0xE01C8]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00D9",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01C8,
+ },
+ [0xE01C9]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00DA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01C9,
+ },
+ [0xE01CA]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00DB",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01CA,
+ },
+ [0xE01CB]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00DC",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01CB,
+ },
+ [0xE01CC]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00DD",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01CC,
+ },
+ [0xE01CD]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00DE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01CD,
+ },
+ [0xE01CE]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00DF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01CE,
+ },
+ [0xE01CF]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00E0",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01CF,
+ },
+ [0xE01D0]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00E1",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01D0,
+ },
+ [0xE01D1]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00E2",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01D1,
+ },
+ [0xE01D2]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00E3",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01D2,
+ },
+ [0xE01D3]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00E4",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01D3,
+ },
+ [0xE01D4]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00E5",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01D4,
+ },
+ [0xE01D5]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00E6",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01D5,
+ },
+ [0xE01D6]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00E7",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01D6,
+ },
+ [0xE01D7]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00E8",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01D7,
+ },
+ [0xE01D8]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00E9",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01D8,
+ },
+ [0xE01D9]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00EA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01D9,
+ },
+ [0xE01DA]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00EB",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01DA,
+ },
+ [0xE01DB]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00EC",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01DB,
+ },
+ [0xE01DC]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00ED",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01DC,
+ },
+ [0xE01DD]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00EE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01DD,
+ },
+ [0xE01DE]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00EF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01DE,
+ },
+ [0xE01DF]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00F0",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01DF,
+ },
+ [0xE01E0]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00F1",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01E0,
+ },
+ [0xE01E1]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00F2",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01E1,
+ },
+ [0xE01E2]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00F3",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01E2,
+ },
+ [0xE01E3]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00F4",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01E3,
+ },
+ [0xE01E4]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00F5",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01E4,
+ },
+ [0xE01E5]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00F6",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01E5,
+ },
+ [0xE01E6]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00F7",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01E6,
+ },
+ [0xE01E7]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00F8",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01E7,
+ },
+ [0xE01E8]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00F9",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01E8,
+ },
+ [0xE01E9]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00FA",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01E9,
+ },
+ [0xE01EA]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00FB",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01EA,
+ },
+ [0xE01EB]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00FC",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01EB,
+ },
+ [0xE01EC]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00FD",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01EC,
+ },
+ [0xE01ED]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00FE",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01ED,
+ },
+ [0xE01EE]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x00FF",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01EE,
+ },
+ [0xE01EF]={
+ category="mn",
+ cjkwd="a",
+ description="VARIATION SELECTOR-0x0100",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xE01EF,
+ },
+}
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-char-ini.lua b/macros/luatex/latex/simurgh/tex/simurgh-char-ini.lua
new file mode 100644
index 0000000000..605bfd7950
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-char-ini.lua
@@ -0,0 +1,1191 @@
+if not modules then modules = { } end modules ['simurgh-char-ini'] = {
+ version = 0.01,
+ comment = "character initialization",
+ author = "Vafa Khalighi",
+ copyright = "Vafa Khalighi",
+ license = "see simurgh package documentation",
+ derived = "derived from char-ini by Hans Hagen"
+}
+
+-- todo: make two files, one for format generation, one for format use
+
+-- we can remove the tag range starting at 0xE0000 (special applications)
+
+local utfchar, utfbyte, utfvalues, ustring = utf.char, utf.byte, utf.values, utf.ustring
+local concat, unpack, tohash = table.concat, table.unpack, table.tohash
+local next, tonumber, type, rawget, rawset = next, tonumber, type, rawget, rawset
+local format, lower, gsub, match, gmatch = string.format, string.lower, string.gsub, string.match, string.match, string.gmatch
+local P, R, Cs, lpegmatch, patterns = lpeg.P, lpeg.R, lpeg.Cs, lpeg.match, lpeg.patterns
+
+local utf8byte = patterns.utf8byte
+local utf8char = patterns.utf8char
+
+local allocate = utilities.storage.allocate
+local mark = utilities.storage.mark
+
+local setmetatableindex = table.setmetatableindex
+
+local trace_defining = false trackers.register("characters.defining", function(v) characters_defining = v end)
+
+local report_defining = logs.reporter("characters")
+
+--[[ldx--
+<p>This module implements some methods and creates additional datastructured
+from the big character table that we use for all kind of purposes:
+<type>char-def.lua</type>.</p>
+
+<p>We assume that at this point <type>characters.data</type> is already
+loaded!</p>
+--ldx]]--
+
+characters = characters or { }
+local characters = characters
+local data = characters.data
+
+if data then
+ mark(data) -- why does this fail
+else
+ report_defining("fatal error: 'char-def.lua' is not loaded")
+ os.exit()
+end
+
+--[[ldx--
+<p>This converts a string (if given) into a number.</p>
+--ldx]]--
+
+local pattern = (P("0x") + P("U+")) * ((R("09","AF")^1 * P(-1)) / function(s) return tonumber(s,16) end)
+
+patterns.chartonumber = pattern
+
+local function chartonumber(k)
+ if type(k) == "string" then
+ local u = lpegmatch(pattern,k)
+ if u then
+ return utfbyte(u)
+ else
+ return utfbyte(k) or 0
+ end
+ else
+ return k or 0
+ end
+end
+
+local function charfromnumber(k)
+ if type(k) == "number" then
+ return utfchar(k) or ""
+ else
+ local u = lpegmatch(pattern,k)
+ if u then
+ return utfchar(u)
+ else
+ return k
+ end
+ end
+end
+
+--~ print(chartonumber(97), chartonumber("a"), chartonumber("0x61"), chartonumber("U+61"))
+
+characters.tonumber = chartonumber
+characters.fromnumber = charfromnumber
+
+local private = {
+ description = "PRIVATE SLOT",
+}
+
+local ranges = allocate()
+characters.ranges = ranges
+
+setmetatableindex(data, function(t,k)
+ local tk = type(k)
+ if tk == "string" then
+ k = lpegmatch(pattern,k) or utfbyte(k)
+ if k then
+ local v = rawget(t,k)
+ if v then
+ return v
+ else
+ tk = "number" -- fall through to range
+ end
+ else
+ return private
+ end
+ end
+ if tk == "number" and k < 0xF0000 then
+ for r=1,#ranges do
+ local rr = ranges[r]
+ if k >= rr.first and k <= rr.last then
+ local extender = rr.extender
+ if extender then
+ local v = extender(k,v)
+ t[k] = v
+ return v
+ end
+ end
+ end
+ end
+ return private -- handy for when we loop over characters in fonts and check for a property
+end)
+
+local blocks = allocate {
+ ["aegeannumbers"] = { first = 0x10100, last = 0x1013F, description = "Aegean Numbers" },
+ ["alchemicalsymbols"] = { first = 0x1F700, last = 0x1F77F, description = "Alchemical Symbols" },
+ ["alphabeticpresentationforms"] = { first = 0x0FB00, last = 0x0FB4F, otf="latn", description = "Alphabetic Presentation Forms" },
+ ["ancientgreekmusicalnotation"] = { first = 0x1D200, last = 0x1D24F, otf="grek", description = "Ancient Greek Musical Notation" },
+ ["ancientgreeknumbers"] = { first = 0x10140, last = 0x1018F, otf="grek", description = "Ancient Greek Numbers" },
+ ["ancientsymbols"] = { first = 0x10190, last = 0x101CF, otf="grek", description = "Ancient Symbols" },
+ ["arabic"] = { first = 0x00600, last = 0x006FF, otf="arab", description = "Arabic" },
+ ["arabicextendeda"] = { first = 0x008A0, last = 0x008FF, description = "Arabic Extended-A" },
+ ["arabicmathematicalalphabeticsymbols"] = { first = 0x1EE00, last = 0x1EEFF, description = "Arabic Mathematical Alphabetic Symbols" },
+ ["arabicpresentationformsa"] = { first = 0x0FB50, last = 0x0FDFF, otf="arab", description = "Arabic Presentation Forms-A" },
+ ["arabicpresentationformsb"] = { first = 0x0FE70, last = 0x0FEFF, otf="arab", description = "Arabic Presentation Forms-B" },
+ ["arabicsupplement"] = { first = 0x00750, last = 0x0077F, otf="arab", description = "Arabic Supplement" },
+ ["armenian"] = { first = 0x00530, last = 0x0058F, otf="armn", description = "Armenian" },
+ ["arrows"] = { first = 0x02190, last = 0x021FF, description = "Arrows" },
+ ["avestan"] = { first = 0x10B00, last = 0x10B3F, description = "Avestan" },
+ ["balinese"] = { first = 0x01B00, last = 0x01B7F, otf="bali", description = "Balinese" },
+ ["bamum"] = { first = 0x0A6A0, last = 0x0A6FF, description = "Bamum" },
+ ["bamumsupplement"] = { first = 0x16800, last = 0x16A3F, description = "Bamum Supplement" },
+ ["basiclatin"] = { first = 0x00000, last = 0x0007F, otf="latn", description = "Basic Latin" },
+ ["batak"] = { first = 0x01BC0, last = 0x01BFF, description = "Batak" },
+ ["bengali"] = { first = 0x00980, last = 0x009FF, otf="beng", description = "Bengali" },
+ ["blockelements"] = { first = 0x02580, last = 0x0259F, otf="bopo", description = "Block Elements" },
+ ["bopomofo"] = { first = 0x03100, last = 0x0312F, otf="bopo", description = "Bopomofo" },
+ ["bopomofoextended"] = { first = 0x031A0, last = 0x031BF, otf="bopo", description = "Bopomofo Extended" },
+ ["boxdrawing"] = { first = 0x02500, last = 0x0257F, description = "Box Drawing" },
+ ["brahmi"] = { first = 0x11000, last = 0x1107F, description = "Brahmi" },
+ ["braillepatterns"] = { first = 0x02800, last = 0x028FF, otf="brai", description = "Braille Patterns" },
+ ["buginese"] = { first = 0x01A00, last = 0x01A1F, otf="bugi", description = "Buginese" },
+ ["buhid"] = { first = 0x01740, last = 0x0175F, otf="buhd", description = "Buhid" },
+ ["byzantinemusicalsymbols"] = { first = 0x1D000, last = 0x1D0FF, otf="byzm", description = "Byzantine Musical Symbols" },
+ ["commonindicnumberforms"] = { first = 0x0A830, last = 0x0A83F, description = "Common Indic Number Forms" },
+ ["carian"] = { first = 0x102A0, last = 0x102DF, description = "Carian" },
+ ["cham"] = { first = 0x0AA00, last = 0x0AA5F, description = "Cham" },
+ ["cherokee"] = { first = 0x013A0, last = 0x013FF, otf="cher", description = "Cherokee" },
+ ["cjkcompatibility"] = { first = 0x03300, last = 0x033FF, otf="hang", description = "CJK Compatibility" },
+ ["cjkcompatibilityforms"] = { first = 0x0FE30, last = 0x0FE4F, otf="hang", description = "CJK Compatibility Forms" },
+ ["cjkcompatibilityideographs"] = { first = 0x0F900, last = 0x0FAFF, otf="hang", description = "CJK Compatibility Ideographs" },
+ ["cjkcompatibilityideographssupplement"] = { first = 0x2F800, last = 0x2FA1F, otf="hang", description = "CJK Compatibility Ideographs Supplement" },
+ ["cjkradicalssupplement"] = { first = 0x02E80, last = 0x02EFF, otf="hang", description = "CJK Radicals Supplement" },
+ ["cjkstrokes"] = { first = 0x031C0, last = 0x031EF, otf="hang", description = "CJK Strokes" },
+ ["cjksymbolsandpunctuation"] = { first = 0x03000, last = 0x0303F, otf="hang", description = "CJK Symbols and Punctuation" },
+ ["cjkunifiedideographs"] = { first = 0x04E00, last = 0x09FFF, otf="hang", description = "CJK Unified Ideographs" },
+ ["cjkunifiedideographsextensiona"] = { first = 0x03400, last = 0x04DBF, otf="hang", description = "CJK Unified Ideographs Extension A" },
+ ["cjkunifiedideographsextensionb"] = { first = 0x20000, last = 0x2A6DF, otf="hang", description = "CJK Unified Ideographs Extension B" },
+ ["combiningdiacriticalmarks"] = { first = 0x00300, last = 0x0036F, description = "Combining Diacritical Marks" },
+ ["combiningdiacriticalmarksforsymbols"] = { first = 0x020D0, last = 0x020FF, description = "Combining Diacritical Marks for Symbols" },
+ ["combiningdiacriticalmarkssupplement"] = { first = 0x01DC0, last = 0x01DFF, description = "Combining Diacritical Marks Supplement" },
+ ["combininghalfmarks"] = { first = 0x0FE20, last = 0x0FE2F, description = "Combining Half Marks" },
+ ["controlpictures"] = { first = 0x02400, last = 0x0243F, description = "Control Pictures" },
+ ["coptic"] = { first = 0x02C80, last = 0x02CFF, otf="copt", description = "Coptic" },
+ ["countingrodnumerals"] = { first = 0x1D360, last = 0x1D37F, description = "Counting Rod Numerals" },
+ ["cuneiform"] = { first = 0x12000, last = 0x123FF, otf="xsux", description = "Cuneiform" },
+ ["cuneiformnumbersandpunctuation"] = { first = 0x12400, last = 0x1247F, otf="xsux", description = "Cuneiform Numbers and Punctuation" },
+ ["currencysymbols"] = { first = 0x020A0, last = 0x020CF, description = "Currency Symbols" },
+ ["cypriotsyllabary"] = { first = 0x10800, last = 0x1083F, otf="cprt", description = "Cypriot Syllabary" },
+ ["cyrillic"] = { first = 0x00400, last = 0x004FF, otf="cyrl", description = "Cyrillic" },
+ ["cyrillicextendeda"] = { first = 0x02DE0, last = 0x02DFF, otf="cyrl", description = "Cyrillic Extended-A" },
+ ["cyrillicextendedb"] = { first = 0x0A640, last = 0x0A69F, otf="cyrl", description = "Cyrillic Extended-B" },
+ ["cyrillicsupplement"] = { first = 0x00500, last = 0x0052F, otf="cyrl", description = "Cyrillic Supplement" },
+ ["deseret"] = { first = 0x10400, last = 0x1044F, otf="dsrt", description = "Deseret" },
+ ["devanagari"] = { first = 0x00900, last = 0x0097F, otf="deva", description = "Devanagari" },
+ ["devanagariextended"] = { first = 0x0A8E0, last = 0x0A8FF, description = "Devanagari Extended" },
+ ["dingbats"] = { first = 0x02700, last = 0x027BF, description = "Dingbats" },
+ ["dominotiles"] = { first = 0x1F030, last = 0x1F09F, description = "Domino Tiles" },
+ ["egyptianhieroglyphs"] = { first = 0x13000, last = 0x1342F, description = "Egyptian Hieroglyphs" },
+ ["emoticons"] = { first = 0x1F600, last = 0x1F64F, description = "Emoticons" },
+ ["enclosedalphanumericsupplement"] = { first = 0x1F100, last = 0x1F1FF, description = "Enclosed Alphanumeric Supplement" },
+ ["enclosedalphanumerics"] = { first = 0x02460, last = 0x024FF, description = "Enclosed Alphanumerics" },
+ ["enclosedcjklettersandmonths"] = { first = 0x03200, last = 0x032FF, description = "Enclosed CJK Letters and Months" },
+ ["enclosedideographicsupplement"] = { first = 0x1F200, last = 0x1F2FF, description = "Enclosed Ideographic Supplement" },
+ ["ethiopic"] = { first = 0x01200, last = 0x0137F, otf="ethi", description = "Ethiopic" },
+ ["ethiopicextended"] = { first = 0x02D80, last = 0x02DDF, otf="ethi", description = "Ethiopic Extended" },
+ ["ethiopicextendeda"] = { first = 0x0AB00, last = 0x0AB2F, description = "Ethiopic Extended-A" },
+ ["ethiopicsupplement"] = { first = 0x01380, last = 0x0139F, otf="ethi", description = "Ethiopic Supplement" },
+ ["generalpunctuation"] = { first = 0x02000, last = 0x0206F, description = "General Punctuation" },
+ ["geometricshapes"] = { first = 0x025A0, last = 0x025FF, description = "Geometric Shapes" },
+ ["georgian"] = { first = 0x010A0, last = 0x010FF, otf="geor", description = "Georgian" },
+ ["georgiansupplement"] = { first = 0x02D00, last = 0x02D2F, otf="geor", description = "Georgian Supplement" },
+ ["glagolitic"] = { first = 0x02C00, last = 0x02C5F, otf="glag", description = "Glagolitic" },
+ ["gothic"] = { first = 0x10330, last = 0x1034F, otf="goth", description = "Gothic" },
+ ["greekandcoptic"] = { first = 0x00370, last = 0x003FF, otf="grek", description = "Greek and Coptic" },
+ ["greekextended"] = { first = 0x01F00, last = 0x01FFF, otf="grek", description = "Greek Extended" },
+ ["gujarati"] = { first = 0x00A80, last = 0x00AFF, otf="gujr", description = "Gujarati" },
+ ["gurmukhi"] = { first = 0x00A00, last = 0x00A7F, otf="guru", description = "Gurmukhi" },
+ ["halfwidthandfullwidthforms"] = { first = 0x0FF00, last = 0x0FFEF, description = "Halfwidth and Fullwidth Forms" },
+ ["hangulcompatibilityjamo"] = { first = 0x03130, last = 0x0318F, otf="jamo", description = "Hangul Compatibility Jamo" },
+ ["hanguljamo"] = { first = 0x01100, last = 0x011FF, otf="jamo", description = "Hangul Jamo" },
+ ["hanguljamoextendeda"] = { first = 0x0A960, last = 0x0A97F, description = "Hangul Jamo Extended-A" },
+ ["hanguljamoextendedb"] = { first = 0x0D7B0, last = 0x0D7FF, description = "Hangul Jamo Extended-B" },
+ ["hangulsyllables"] = { first = 0x0AC00, last = 0x0D7AF, otf="hang", description = "Hangul Syllables" },
+ ["hanunoo"] = { first = 0x01720, last = 0x0173F, otf="hano", description = "Hanunoo" },
+ ["hebrew"] = { first = 0x00590, last = 0x005FF, otf="hebr", description = "Hebrew" },
+ ["highprivateusesurrogates"] = { first = 0x0DB80, last = 0x0DBFF, description = "High Private Use Surrogates" },
+ ["highsurrogates"] = { first = 0x0D800, last = 0x0DB7F, description = "High Surrogates" },
+ ["hiragana"] = { first = 0x03040, last = 0x0309F, otf="kana", description = "Hiragana" },
+ ["ideographicdescriptioncharacters"] = { first = 0x02FF0, last = 0x02FFF, description = "Ideographic Description Characters" },
+ ["imperialaramaic"] = { first = 0x10840, last = 0x1085F, description = "Imperial Aramaic" },
+ ["inscriptionalpahlavi"] = { first = 0x10B60, last = 0x10B7F, description = "Inscriptional Pahlavi" },
+ ["inscriptionalparthian"] = { first = 0x10B40, last = 0x10B5F, description = "Inscriptional Parthian" },
+ ["ipaextensions"] = { first = 0x00250, last = 0x002AF, description = "IPA Extensions" },
+ ["javanese"] = { first = 0x0A980, last = 0x0A9DF, description = "Javanese" },
+ ["kaithi"] = { first = 0x11080, last = 0x110CF, description = "Kaithi" },
+ ["kanasupplement"] = { first = 0x1B000, last = 0x1B0FF, description = "Kana Supplement" },
+ ["kanbun"] = { first = 0x03190, last = 0x0319F, description = "Kanbun" },
+ ["kangxiradicals"] = { first = 0x02F00, last = 0x02FDF, description = "Kangxi Radicals" },
+ ["kannada"] = { first = 0x00C80, last = 0x00CFF, otf="knda", description = "Kannada" },
+ ["katakana"] = { first = 0x030A0, last = 0x030FF, otf="kana", description = "Katakana" },
+ ["katakanaphoneticextensions"] = { first = 0x031F0, last = 0x031FF, otf="kana", description = "Katakana Phonetic Extensions" },
+ ["kayahli"] = { first = 0x0A900, last = 0x0A92F, description = "Kayah Li" },
+ ["kharoshthi"] = { first = 0x10A00, last = 0x10A5F, otf="khar", description = "Kharoshthi" },
+ ["khmer"] = { first = 0x01780, last = 0x017FF, otf="khmr", description = "Khmer" },
+ ["khmersymbols"] = { first = 0x019E0, last = 0x019FF, otf="khmr", description = "Khmer Symbols" },
+ ["lao"] = { first = 0x00E80, last = 0x00EFF, otf="lao", description = "Lao" },
+ ["latinextendeda"] = { first = 0x00100, last = 0x0017F, otf="latn", description = "Latin Extended-A" },
+ ["latinextendedadditional"] = { first = 0x01E00, last = 0x01EFF, otf="latn", description = "Latin Extended Additional" },
+ ["latinextendedb"] = { first = 0x00180, last = 0x0024F, otf="latn", description = "Latin Extended-B" },
+ ["latinextendedc"] = { first = 0x02C60, last = 0x02C7F, otf="latn", description = "Latin Extended-C" },
+ ["latinextendedd"] = { first = 0x0A720, last = 0x0A7FF, otf="latn", description = "Latin Extended-D" },
+ ["latinsupplement"] = { first = 0x00080, last = 0x000FF, otf="latn", description = "Latin-1 Supplement" },
+ ["lepcha"] = { first = 0x01C00, last = 0x01C4F, description = "Lepcha" },
+ ["letterlikesymbols"] = { first = 0x02100, last = 0x0214F, description = "Letterlike Symbols" },
+ ["limbu"] = { first = 0x01900, last = 0x0194F, otf="limb", description = "Limbu" },
+ ["linearbideograms"] = { first = 0x10080, last = 0x100FF, otf="linb", description = "Linear B Ideograms" },
+ ["linearbsyllabary"] = { first = 0x10000, last = 0x1007F, otf="linb", description = "Linear B Syllabary" },
+ ["lisu"] = { first = 0x0A4D0, last = 0x0A4FF, description = "Lisu" },
+ ["lowsurrogates"] = { first = 0x0DC00, last = 0x0DFFF, description = "Low Surrogates" },
+ ["lycian"] = { first = 0x10280, last = 0x1029F, description = "Lycian" },
+ ["lydian"] = { first = 0x10920, last = 0x1093F, description = "Lydian" },
+ ["mahjongtiles"] = { first = 0x1F000, last = 0x1F02F, description = "Mahjong Tiles" },
+ ["malayalam"] = { first = 0x00D00, last = 0x00D7F, otf="mlym", description = "Malayalam" },
+ ["mandiac"] = { first = 0x00840, last = 0x0085F, otf="mand", description = "Mandaic" },
+ ["mathematicalalphanumericsymbols"] = { first = 0x1D400, last = 0x1D7FF, description = "Mathematical Alphanumeric Symbols" },
+ ["mathematicaloperators"] = { first = 0x02200, last = 0x022FF, description = "Mathematical Operators" },
+ ["meeteimayek"] = { first = 0x0ABC0, last = 0x0ABFF, description = "Meetei Mayek" },
+ ["meeteimayekextensions"] = { first = 0x0AAE0, last = 0x0AAFF, description = "Meetei Mayek Extensions" },
+ ["meroiticcursive"] = { first = 0x109A0, last = 0x109FF, description = "Meroitic Cursive" },
+ ["meroitichieroglyphs"] = { first = 0x10980, last = 0x1099F, description = "Meroitic Hieroglyphs" },
+ ["miao"] = { first = 0x16F00, last = 0x16F9F, description = "Miao" },
+ ["miscellaneousmathematicalsymbolsa"] = { first = 0x027C0, last = 0x027EF, description = "Miscellaneous Mathematical Symbols-A" },
+ ["miscellaneousmathematicalsymbolsb"] = { first = 0x02980, last = 0x029FF, description = "Miscellaneous Mathematical Symbols-B" },
+ ["miscellaneoussymbols"] = { first = 0x02600, last = 0x026FF, description = "Miscellaneous Symbols" },
+ ["miscellaneoussymbolsandarrows"] = { first = 0x02B00, last = 0x02BFF, description = "Miscellaneous Symbols and Arrows" },
+ ["miscellaneoussymbolsandpictographs"] = { first = 0x1F300, last = 0x1F5FF, description = "Miscellaneous Symbols And Pictographs" },
+ ["miscellaneoustechnical"] = { first = 0x02300, last = 0x023FF, description = "Miscellaneous Technical" },
+ ["modifiertoneletters"] = { first = 0x0A700, last = 0x0A71F, description = "Modifier Tone Letters" },
+ ["mongolian"] = { first = 0x01800, last = 0x018AF, otf="mong", description = "Mongolian" },
+ ["musicalsymbols"] = { first = 0x1D100, last = 0x1D1FF, otf="musc", description = "Musical Symbols" },
+ ["myanmar"] = { first = 0x01000, last = 0x0109F, otf="mymr", description = "Myanmar" },
+ ["myanmarextendeda"] = { first = 0x0AA60, last = 0x0AA7F, description = "Myanmar Extended-A" },
+ ["newtailue"] = { first = 0x01980, last = 0x019DF, description = "New Tai Lue" },
+ ["nko"] = { first = 0x007C0, last = 0x007FF, otf="nko", description = "NKo" },
+ ["numberforms"] = { first = 0x02150, last = 0x0218F, description = "Number Forms" },
+ ["ogham"] = { first = 0x01680, last = 0x0169F, otf="ogam", description = "Ogham" },
+ ["olchiki"] = { first = 0x01C50, last = 0x01C7F, description = "Ol Chiki" },
+ ["olditalic"] = { first = 0x10300, last = 0x1032F, otf="ital", description = "Old Italic" },
+ ["oldpersian"] = { first = 0x103A0, last = 0x103DF, otf="xpeo", description = "Old Persian" },
+ ["oldsoutharabian"] = { first = 0x10A60, last = 0x10A7F, description = "Old South Arabian" },
+ ["odlturkic"] = { first = 0x10C00, last = 0x10C4F, description = "Old Turkic" },
+ ["opticalcharacterrecognition"] = { first = 0x02440, last = 0x0245F, description = "Optical Character Recognition" },
+ ["oriya"] = { first = 0x00B00, last = 0x00B7F, otf="orya", description = "Oriya" },
+ ["osmanya"] = { first = 0x10480, last = 0x104AF, otf="osma", description = "Osmanya" },
+ ["phagspa"] = { first = 0x0A840, last = 0x0A87F, otf="phag", description = "Phags-pa" },
+ ["phaistosdisc"] = { first = 0x101D0, last = 0x101FF, description = "Phaistos Disc" },
+ ["phoenician"] = { first = 0x10900, last = 0x1091F, otf="phnx", description = "Phoenician" },
+ ["phoneticextensions"] = { first = 0x01D00, last = 0x01D7F, description = "Phonetic Extensions" },
+ ["phoneticextensionssupplement"] = { first = 0x01D80, last = 0x01DBF, description = "Phonetic Extensions Supplement" },
+ ["playingcards"] = { first = 0x1F0A0, last = 0x1F0FF, description = "Playing Cards" },
+ ["privateusearea"] = { first = 0x0E000, last = 0x0F8FF, description = "Private Use Area" },
+ ["rejang"] = { first = 0x0A930, last = 0x0A95F, description = "Rejang" },
+ ["ruminumeralsymbols"] = { first = 0x10E60, last = 0x10E7F, description = "Rumi Numeral Symbols" },
+ ["runic"] = { first = 0x016A0, last = 0x016FF, otf="runr", description = "Runic" },
+ ["samaritan"] = { first = 0x00800, last = 0x0083F, description = "Samaritan" },
+ ["saurashtra"] = { first = 0x0A880, last = 0x0A8DF, description = "Saurashtra" },
+ ["sharada"] = { first = 0x11180, last = 0x111DF, description = "Sharada" },
+ ["shavian"] = { first = 0x10450, last = 0x1047F, otf="shaw", description = "Shavian" },
+ ["sinhala"] = { first = 0x00D80, last = 0x00DFF, otf="sinh", description = "Sinhala" },
+ ["smallformvariants"] = { first = 0x0FE50, last = 0x0FE6F, description = "Small Form Variants" },
+ ["sorasompeng"] = { first = 0x110D0, last = 0x110FF, description = "Sora Sompeng" },
+ ["spacingmodifierletters"] = { first = 0x002B0, last = 0x002FF, description = "Spacing Modifier Letters" },
+ ["specials"] = { first = 0x0FFF0, last = 0x0FFFF, description = "Specials" },
+ ["sundanese"] = { first = 0x01B80, last = 0x01BBF, description = "Sundanese" },
+ ["sundanesesupplement"] = { first = 0x01CC0, last = 0x01CCF, description = "Sundanese Supplement" },
+ ["superscriptsandsubscripts"] = { first = 0x02070, last = 0x0209F, description = "Superscripts and Subscripts" },
+ ["supplementalarrowsa"] = { first = 0x027F0, last = 0x027FF, description = "Supplemental Arrows-A" },
+ ["supplementalarrowsb"] = { first = 0x02900, last = 0x0297F, description = "Supplemental Arrows-B" },
+ ["supplementalmathematicaloperators"] = { first = 0x02A00, last = 0x02AFF, description = "Supplemental Mathematical Operators" },
+ ["supplementalpunctuation"] = { first = 0x02E00, last = 0x02E7F, description = "Supplemental Punctuation" },
+ ["supplementaryprivateuseareaa"] = { first = 0xF0000, last = 0xFFFFF, description = "Supplementary Private Use Area-A" },
+ ["supplementaryprivateuseareab"] = { first = 0x100000,last = 0x10FFFF, description = "Supplementary Private Use Area-B" },
+ ["sylotinagri"] = { first = 0x0A800, last = 0x0A82F, otf="sylo", description = "Syloti Nagri" },
+ ["syriac"] = { first = 0x00700, last = 0x0074F, otf="syrc", description = "Syriac" },
+ ["tagalog"] = { first = 0x01700, last = 0x0171F, otf="tglg", description = "Tagalog" },
+ ["tagbanwa"] = { first = 0x01760, last = 0x0177F, otf="tagb", description = "Tagbanwa" },
+ ["tags"] = { first = 0xE0000, last = 0xE007F, description = "Tags" },
+ ["taile"] = { first = 0x01950, last = 0x0197F, otf="tale", description = "Tai Le" },
+ ["taitham"] = { first = 0x01A20, last = 0x01AAF, description = "Tai Tham" },
+ ["taiviet"] = { first = 0x0AA80, last = 0x0AADF, description = "Tai Viet" },
+ ["taixuanjingsymbols"] = { first = 0x1D300, last = 0x1D35F, description = "Tai Xuan Jing Symbols" },
+ ["takri"] = { first = 0x11680, last = 0x116CF, description = "Takri" },
+ ["tamil"] = { first = 0x00B80, last = 0x00BFF, otf="taml", description = "Tamil" },
+ ["telugu"] = { first = 0x00C00, last = 0x00C7F, otf="telu", description = "Telugu" },
+ ["thaana"] = { first = 0x00780, last = 0x007BF, otf="thaa", description = "Thaana" },
+ ["thai"] = { first = 0x00E00, last = 0x00E7F, otf="thai", description = "Thai" },
+ ["tibetan"] = { first = 0x00F00, last = 0x00FFF, otf="tibt", description = "Tibetan" },
+ ["tifinagh"] = { first = 0x02D30, last = 0x02D7F, otf="tfng", description = "Tifinagh" },
+ ["transportandmapsymbols"] = { first = 0x1F680, last = 0x1F6FF, description = "Transport And Map Symbols" },
+ ["ugaritic"] = { first = 0x10380, last = 0x1039F, otf="ugar", description = "Ugaritic" },
+ ["unifiedcanadianaboriginalsyllabics"] = { first = 0x01400, last = 0x0167F, otf="cans", description = "Unified Canadian Aboriginal Syllabics" },
+ ["unifiedcanadianaboriginalsyllabicsextended"] = { first = 0x018B0, last = 0x018FF, description = "Unified Canadian Aboriginal Syllabics Extended" },
+ ["vai"] = { first = 0x0A500, last = 0x0A63F, description = "Vai" },
+ ["variationselectors"] = { first = 0x0FE00, last = 0x0FE0F, description = "Variation Selectors" },
+ ["variationselectorssupplement"] = { first = 0xE0100, last = 0xE01EF, description = "Variation Selectors Supplement" },
+ ["vedicextensions"] = { first = 0x01CD0, last = 0x01CFF, description = "Vedic Extensions" },
+ ["verticalforms"] = { first = 0x0FE10, last = 0x0FE1F, description = "Vertical Forms" },
+ ["yijinghexagramsymbols"] = { first = 0x04DC0, last = 0x04DFF, otf="yi", description = "Yijing Hexagram Symbols" },
+ ["yiradicals"] = { first = 0x0A490, last = 0x0A4CF, otf="yi", description = "Yi Radicals" },
+ ["yisyllables"] = { first = 0x0A000, last = 0x0A48F, otf="yi", description = "Yi Syllables" },
+}
+
+characters.blocks = blocks
+
+function characters.blockrange(name)
+ local b = blocks[name]
+ if b then
+ return b.first, b.last
+ else
+ return 0, 0
+ end
+end
+
+setmetatableindex(blocks, function(t,k) -- we could use an intermediate table if called often
+ return k and rawget(t,lower(gsub(k,"[^a-zA-Z]","")))
+end)
+
+local otfscripts = utilities.storage.allocate()
+characters.otfscripts = otfscripts
+
+setmetatableindex(otfscripts,function(t,unicode)
+ for k, v in next, blocks do
+ local first, last = v.first, v.last
+ if unicode >= first and unicode <= last then
+ local script = v.otf or "dflt"
+ for u=first,last do
+ t[u] = script
+ end
+ return script
+ end
+ end
+ -- pretty slow when we're here
+ t[unicode] = "dflt"
+ return "dflt"
+end)
+
+function characters.getrange(name) -- used in font fallback definitions (name or range)
+ local range = blocks[name]
+ if range then
+ return range.first, range.last, range.description
+ end
+ name = gsub(name,'"',"0x") -- goodie: tex hex notation
+ local start, stop = match(name,"^(.-)[%-%:](.-)$")
+ if start and stop then
+ start, stop = tonumber(start,16) or tonumber(start), tonumber(stop,16) or tonumber(stop)
+ if start and stop then
+ return start, stop, nil
+ end
+ end
+ local slot = tonumber(name,16) or tonumber(name)
+ return slot, slot, nil
+end
+
+local categorytags = allocate {
+ lu = "Letter Uppercase",
+ ll = "Letter Lowercase",
+ lt = "Letter Titlecase",
+ lm = "Letter Modifier",
+ lo = "Letter Other",
+ mn = "Mark Nonspacing",
+ mc = "Mark Spacing Combining",
+ me = "Mark Enclosing",
+ nd = "Number Decimal Digit",
+ nl = "Number Letter",
+ no = "Number Other",
+ pc = "Punctuation Connector",
+ pd = "Punctuation Dash",
+ ps = "Punctuation Open",
+ pe = "Punctuation Close",
+ pi = "Punctuation Initial Quote",
+ pf = "Punctuation Final Quote",
+ po = "Punctuation Other",
+ sm = "Symbol Math",
+ sc = "Symbol Currency",
+ sk = "Symbol Modifier",
+ so = "Symbol Other",
+ zs = "Separator Space",
+ zl = "Separator Line",
+ zp = "Separator Paragraph",
+ cc = "Other Control",
+ cf = "Other Format",
+ cs = "Other Surrogate",
+ co = "Other Private Use",
+ cn = "Other Not Assigned",
+}
+
+characters.categorytags = categorytags
+
+--~ special : cf (softhyphen) zs (emspace)
+--~ characters: ll lm lo lt lu mn nl no pc pd pe pf pi po ps sc sk sm so
+
+local is_character = allocate ( tohash {
+ "lu","ll","lt","lm","lo",
+ "nd","nl","no",
+ "mn",
+ "nl","no",
+ "pc","pd","ps","pe","pi","pf","po",
+ "sm","sc","sk","so"
+} )
+
+local is_letter = allocate ( tohash {
+ "ll","lm","lo","lt","lu"
+} )
+
+local is_command = allocate ( tohash {
+ "cf","zs"
+} )
+
+local is_spacing = allocate ( tohash {
+ "zs", "zl","zp",
+} )
+
+local is_mark = allocate ( tohash {
+ "mn", "ms",
+} )
+
+-- to be redone: store checked characters
+
+characters.is_character = is_character
+characters.is_letter = is_letter
+characters.is_command = is_command
+characters.is_spacing = is_spacing
+characters.is_mark = is_mark
+
+local mt = { -- yes or no ?
+ __index = function(t,k)
+ if type(k) == "number" then
+ local c = data[k].category
+ return c and rawget(t,c)
+ else
+ -- avoid auto conversion in data.characters lookups
+ end
+ end
+}
+
+setmetatableindex(characters.is_character, mt)
+setmetatableindex(characters.is_letter, mt)
+setmetatableindex(characters.is_command, mt)
+setmetatableindex(characters.is_spacing, mt)
+
+-- todo: also define callers for the above
+
+-- linebreak: todo: hash
+--
+-- normative : BK CR LF CM SG GL CB SP ZW NL WJ JL JV JT H2 H3
+-- informative : XX OP CL QU NS EX SY IS PR PO NU AL ID IN HY BB BA SA AI B2 new:CP
+
+-- east asian width:
+--
+-- N A H W F Na
+
+characters.bidi = allocate {
+ l = "Left-to-Right",
+ lre = "Left-to-Right Embedding",
+ lro = "Left-to-Right Override",
+ r = "Right-to-Left",
+ al = "Right-to-Left Arabic",
+ rle = "Right-to-Left Embedding",
+ rlo = "Right-to-Left Override",
+ pdf = "Pop Directional Format",
+ en = "European Number",
+ es = "European Number Separator",
+ et = "European Number Terminator",
+ an = "Arabic Number",
+ cs = "Common Number Separator",
+ nsm = "Non-Spacing Mark",
+ bn = "Boundary Neutral",
+ b = "Paragraph Separator",
+ s = "Segment Separator",
+ ws = "Whitespace",
+ on = "Other Neutrals",
+}
+
+--[[ldx--
+<p>At this point we assume that the big data table is loaded. From this
+table we derive a few more.</p>
+--ldx]]--
+
+if not characters.fallbacks then
+
+ characters.fallbacks = { } -- not than many
+
+ local fallbacks = characters.fallbacks
+
+ for k, d in next, data do
+ local specials = d.specials
+ if specials and specials[1] == "compat" and specials[2] == 0x0020 then
+ local s = specials[3]
+ if s then
+ fallbacks[k] = s
+ fallbacks[s] = k
+ end
+ end
+ end
+
+end
+
+if storage then
+ storage.register("characters/fallbacks", characters.fallbacks, "characters.fallbacks") -- accents and such
+end
+
+characters.directions = { }
+
+setmetatableindex(characters.directions,function(t,k)
+ local d = data[k]
+ if d then
+ local v = d.direction
+ if v then
+ t[k] = v
+ return v
+ end
+ end
+ t[k] = false -- maybe 'l'
+ return v
+end)
+
+characters.mirrors = { }
+
+setmetatableindex(characters.mirrors,function(t,k)
+ local d = data[k]
+ if d then
+ local v = d.mirror
+ if v then
+ t[k] = v
+ return v
+ end
+ end
+ t[k] = false
+ return v
+end)
+
+characters.textclasses = { }
+
+setmetatableindex(characters.textclasses,function(t,k)
+ local d = data[k]
+ if d then
+ local v = d.textclass
+ if v then
+ t[k] = v
+ return v
+ end
+ end
+ t[k] = false
+ return v
+end)
+
+--[[ldx--
+<p>Next comes a whole series of helper methods. These are (will be) part
+of the official <l n='api'/>.</p>
+--ldx]]--
+
+-- we could make them virtual: characters.contextnames[n]
+
+function characters.contextname(n) return data[n].contextname or "" end
+function characters.adobename (n) return data[n].adobename or "" end
+function characters.description(n) return data[n].description or "" end
+-------- characters.category (n) return data[n].category or "" end
+
+function characters.category(n,verbose)
+ local c = data[n].category
+ if not c then
+ return ""
+ elseif verbose then
+ return categorytags[c]
+ else
+ return c
+ end
+end
+
+-- -- some day we will make a table .. not that many calls to utfchar
+--
+-- local utfchar = utf.char
+-- local utfbyte = utf.byte
+-- local utfbytes = { }
+-- local utfchars = { }
+--
+-- table.setmetatableindex(utfbytes,function(t,k) local v = utfchar(k) t[k] = v return v end)
+-- table.setmetatableindex(utfchars,function(t,k) local v = utfbyte(k) t[k] = v return v end)
+
+local function toutfstring(s)
+ if type(s) == "table" then
+ return utfchar(unpack(s)) -- concat { utfchar( unpack(s) ) }
+ else
+ return utfchar(s)
+ end
+end
+
+utf.tostring = toutfstring
+
+local categories = allocate() characters.categories = categories -- lazy table
+
+setmetatableindex(categories, function(t,u) if u then local c = data[u] c = c and c.category or u t[u] = c return c end end)
+
+local lccodes = allocate() characters.lccodes = lccodes -- lazy table
+local uccodes = allocate() characters.uccodes = uccodes -- lazy table
+local shcodes = allocate() characters.shcodes = shcodes -- lazy table
+local fscodes = allocate() characters.fscodes = fscodes -- lazy table
+
+setmetatableindex(lccodes, function(t,u) if u then local c = data[u] c = c and c.lccode or (type(u) == "string" and utfbyte(u)) or u t[u] = c return c end end)
+setmetatableindex(uccodes, function(t,u) if u then local c = data[u] c = c and c.uccode or (type(u) == "string" and utfbyte(u)) or u t[u] = c return c end end)
+setmetatableindex(shcodes, function(t,u) if u then local c = data[u] c = c and c.shcode or (type(u) == "string" and utfbyte(u)) or u t[u] = c return c end end)
+setmetatableindex(fscodes, function(t,u) if u then local c = data[u] c = c and c.fscode or (type(u) == "string" and utfbyte(u)) or u t[u] = c return c end end)
+
+local lcchars = allocate() characters.lcchars = lcchars -- lazy table
+local ucchars = allocate() characters.ucchars = ucchars -- lazy table
+local shchars = allocate() characters.shchars = shchars -- lazy table
+local fschars = allocate() characters.fschars = fschars -- lazy table
+
+setmetatableindex(lcchars, function(t,u) if u then local c = data[u] c = c and c.lccode c = c and toutfstring(c) or (type(u) == "number" and utfchar(u)) or u t[u] = c return c end end)
+setmetatableindex(ucchars, function(t,u) if u then local c = data[u] c = c and c.uccode c = c and toutfstring(c) or (type(u) == "number" and utfchar(u)) or u t[u] = c return c end end)
+setmetatableindex(shchars, function(t,u) if u then local c = data[u] c = c and c.shcode c = c and toutfstring(c) or (type(u) == "number" and utfchar(u)) or u t[u] = c return c end end)
+setmetatableindex(fschars, function(t,u) if u then local c = data[u] c = c and c.fscode c = c and toutfstring(c) or (type(u) == "number" and utfchar(u)) or u t[u] = c return c end end)
+
+local decomposed = allocate() characters.decomposed = decomposed -- lazy table
+local specials = allocate() characters.specials = specials -- lazy table
+
+setmetatableindex(decomposed, function(t,u) -- either a table or false
+ if u then
+ local c = data[u]
+ local s = c and c.decomposed or false -- could fall back to specials
+ t[u] = s
+ return s
+ end
+end)
+
+setmetatableindex(specials, function(t,u) -- either a table or false
+ if u then
+ local c = data[u]
+ local s = c and c.specials or false
+ t[u] = s
+ return s
+ end
+end)
+
+local specialchars = allocate() characters.specialchars = specialchars -- lazy table
+local descriptions = allocate() characters.descriptions = descriptions -- lazy table
+
+setmetatableindex(specialchars, function(t,u)
+ if u then
+ local c = data[u]
+ local s = c and c.specials
+ if s then
+ local tt, ttn = { }, 0
+ for i=2,#s do
+ local si = s[i]
+ local c = data[si]
+ if is_letter[c.category] then
+ ttn = ttn + 1
+ tt[ttn] = utfchar(si)
+ end
+ end
+ c = concat(tt)
+ t[u] = c
+ return c
+ else
+ if type(u) == "number" then
+ u = utfchar(u)
+ end
+ t[u] = u
+ return u
+ end
+ end
+end)
+
+setmetatableindex(descriptions, function(t,k)
+ -- 0.05 - 0.10 sec
+ for u, c in next, data do
+ local d = c.description
+ if d then
+ d = gsub(d," ","")
+ d = lower(d)
+ t[d] = u
+ end
+ end
+ local d = rawget(t,k)
+ if not d then
+ t[k] = k
+ end
+ return d
+end)
+
+function characters.unicodechar(asked)
+ local n = tonumber(asked)
+ if n then
+ return n
+ elseif type(asked) == "string" then
+ return descriptions[asked] or descriptions[gsub(asked," ","")]
+ end
+end
+
+-- function characters.lower(str)
+-- local new, n = { }, 0
+-- for u in utfvalues(str) do
+-- n = n + 1
+-- new[n] = lcchars[u]
+-- end
+-- return concat(new)
+-- end
+--
+-- function characters.upper(str)
+-- local new, n = { }, 0
+-- for u in utfvalues(str) do
+-- n = n + 1
+-- new[n] = ucchars[u]
+-- end
+-- return concat(new)
+-- end
+--
+-- function characters.shaped(str)
+-- local new, n = { }, 0
+-- for u in utfvalues(str) do
+-- n = n + 1
+-- new[n] = shchars[u]
+-- end
+-- return concat(new)
+-- end
+
+----- tolower = Cs((utf8byte/lcchars)^0)
+----- toupper = Cs((utf8byte/ucchars)^0)
+----- toshape = Cs((utf8byte/shchars)^0)
+
+local tolower = Cs((utf8char/lcchars)^0)
+local toupper = Cs((utf8char/ucchars)^0)
+local toshape = Cs((utf8char/shchars)^0)
+
+patterns.tolower = tolower
+patterns.toupper = toupper
+patterns.toshape = toshape
+
+function characters.lower (str) return lpegmatch(tolower,str) end
+function characters.upper (str) return lpegmatch(toupper,str) end
+function characters.shaped(str) return lpegmatch(toshape,str) end
+
+function characters.lettered(str,spacing)
+ local new, n = { }, 0
+ if spacing then
+ local done = false
+ for u in utfvalues(str) do
+ local c = data[u].category
+ if is_letter[c] then
+ if done and n > 1 then
+ n = n + 1
+ new[n] = " "
+ done = false
+ end
+ n = n + 1
+ new[n] = utfchar(u)
+ elseif spacing and is_spacing[c] then
+ done = true
+ end
+ end
+ else
+ for u in utfvalues(str) do
+ if is_letter[data[u].category] then
+ n = n + 1
+ new[n] = utfchar(u)
+ end
+ end
+ end
+ return concat(new)
+end
+
+--[[ldx--
+<p>Requesting lower and uppercase codes:</p>
+--ldx]]--
+
+function characters.uccode(n) return uccodes[n] end -- obsolete
+function characters.lccode(n) return lccodes[n] end -- obsolete
+
+function characters.safechar(n)
+ local c = data[n]
+ if c and c.contextname then
+ return "\\" .. c.contextname
+ else
+ return utfchar(n)
+ end
+end
+
+function characters.shape(n)
+ local shcode = shcodes[n]
+ if not shcode then
+ return n, nil
+ elseif type(shcode) == "table" then
+ return shcode[1], shcode[#shcode]
+ else
+ return shcode, nil
+ end
+end
+
+-- -- some day we might go this route, but it does not really save that much
+-- -- so not now (we can generate a lot using mtx-unicode that operates on the
+-- -- database)
+--
+-- -- category cjkwd direction linebreak
+--
+-- -- adobename comment contextcommand contextname description fallback lccode
+-- -- mathclass mathfiller mathname mathspec mathstretch mathsymbol mirror
+-- -- range shcode specials uccode uccodes unicodeslot
+--
+-- local data = {
+-- ['one']={
+-- common = {
+-- category="cc",
+-- direction="bn",
+-- linebreak="cm",
+-- },
+-- vector = {
+-- [0x0000] = {
+-- description="NULL",
+-- group='one',
+-- unicodeslot=0x0000,
+-- },
+-- {
+-- description="START OF HEADING",
+-- group='one',
+-- unicodeslot=0x0001,
+-- },
+-- }
+-- }
+-- }
+--
+-- local chardata, groupdata = { }, { }
+--
+-- for group, gdata in next, data do
+-- local common, vector = { __index = gdata.common }, gdata.vector
+-- for character, cdata in next, vector do
+-- chardata[character] = cdata
+-- setmetatable(cdata,common)
+-- end
+-- groupdata[group] = gdata
+-- end
+
+--~ characters.data, characters.groups = chardata, groupdata
+
+--~ [0xF0000]={
+--~ category="co",
+--~ cjkwd="a",
+--~ description="<Plane 0x000F Private Use, First>",
+--~ direction="l",
+--~ unicodeslot=0xF0000,
+--~ },
+--~ [0xFFFFD]={
+--~ category="co",
+--~ cjkwd="a",
+--~ description="<Plane 0x000F Private Use, Last>",
+--~ direction="l",
+--~ unicodeslot=0xFFFFD,
+--~ },
+--~ [0x100000]={
+--~ category="co",
+--~ cjkwd="a",
+--~ description="<Plane 0x0010 Private Use, First>",
+--~ direction="l",
+--~ unicodeslot=0x100000,
+--~ },
+--~ [0x10FFFD]={
+--~ category="co",
+--~ cjkwd="a",
+--~ description="<Plane 0x0010 Private Use, Last>",
+--~ direction="l",
+--~ unicodeslot=0x10FFFD,
+--~ },
+
+if not characters.superscripts then
+
+ local superscripts = allocate() characters.superscripts = superscripts
+ local subscripts = allocate() characters.subscripts = subscripts
+
+ -- skipping U+02120 (service mark) U+02122 (trademark)
+
+ for k, v in next, data do
+ local specials = v.specials
+ if specials then
+ local what = specials[1]
+ if what == "super" then
+ if #specials == 2 then
+ superscripts[k] = specials[2]
+ else
+ report_defining("ignoring %s %a, char %c, description %a","superscript",ustring(k),k,v.description)
+ end
+ elseif what == "sub" then
+ if #specials == 2 then
+ subscripts[k] = specials[2]
+ else
+ report_defining("ignoring %s %a, char %c, description %a","subscript",ustring(k),k,v.description)
+ end
+ end
+ end
+ end
+
+ -- print(table.serialize(superscripts, "superscripts", { hexify = true }))
+ -- print(table.serialize(subscripts, "subscripts", { hexify = true }))
+
+ if storage then
+ storage.register("characters/superscripts", superscripts, "characters.superscripts")
+ storage.register("characters/subscripts", subscripts, "characters.subscripts")
+ end
+
+end
+
+-- for the moment only a few
+
+local tracedchars = utilities.strings.tracers
+
+tracedchars[0x00] = "[signal]"
+tracedchars[0x20] = "[space]"
+
+-- the following code will move to char-tex.lua
+
+-- tex
+
+if not tex or not context or not commands then return characters end
+
+local tex = tex
+local texsetlccode = tex.setlccode
+local texsetuccode = tex.setuccode
+local texsetsfcode = tex.setsfcode
+local texsetcatcode = tex.setcatcode
+
+local contextsprint = context.sprint
+local ctxcatcodes = catcodes.numbers.ctxcatcodes
+
+--[[ldx--
+<p>Instead of using a <l n='tex'/> file to define the named glyphs, we
+use the table. After all, we have this information available anyway.</p>
+--ldx]]--
+
+function commands.makeactive(n,name) --
+ contextsprint(ctxcatcodes,format("\\catcode%s=13\\unexpanded\\def %s{\\%s}",n,utfchar(n),name))
+ -- context("\\catcode%s=13\\unexpanded\\def %s{\\%s}",n,utfchar(n),name)
+end
+
+function commands.utfchar(c,n)
+ if n then
+ -- contextsprint(c,charfromnumber(n))
+ contextsprint(c,utfchar(n))
+ else
+ -- contextsprint(charfromnumber(c))
+ contextsprint(utfchar(c))
+ end
+end
+
+function commands.safechar(n)
+ local c = data[n]
+ if c and c.contextname then
+ contextsprint("\\" .. c.contextname) -- context[c.contextname]()
+ else
+ contextsprint(utfchar(n))
+ end
+end
+
+tex.uprint = commands.utfchar
+
+local forbidden = tohash { -- at least now
+ 0x00A0,
+ 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x200B, 0x200C, 0x200D,
+ 0x202F,
+ 0x205F,
+ -- 0xFEFF,
+}
+
+function characters.define(tobelettered, tobeactivated) -- catcodetables
+
+ if trace_defining then
+ report_defining("defining active character commands")
+ end
+
+ local activated, a = { }, 0
+
+ for u, chr in next, data do -- these will be commands
+ local fallback = chr.fallback
+ if fallback then
+ contextsprint("{\\catcode",u,"=13\\unexpanded\\gdef ",utfchar(u),"{\\checkedchar{",u,"}{",fallback,"}}}")
+ a = a + 1
+ activated[a] = u
+ else
+ local contextname = chr.contextname
+ if contextname then
+ local category = chr.category
+ if is_character[category] then
+ if chr.unicodeslot < 128 then
+ if is_letter[category] then
+ contextsprint(ctxcatcodes,format("\\def\\%s{%s}",contextname,utfchar(u))) -- has no s
+ else
+ contextsprint(ctxcatcodes,format("\\chardef\\%s=%s",contextname,u)) -- has no s
+ end
+ else
+ contextsprint(ctxcatcodes,format("\\def\\%s{%s}",contextname,utfchar(u))) -- has no s
+ end
+ elseif is_command[category] and not forbidden[u] then
+ contextsprint("{\\catcode",u,"=13\\unexpanded\\gdef ",utfchar(u),"{\\"..contextname,"}}")
+ a = a + 1
+ activated[a] = u
+ end
+ end
+ end
+ end
+
+ if tobelettered then -- shared
+ local saved = tex.catcodetable
+ for i=1,#tobelettered do
+ tex.catcodetable = tobelettered[i]
+ if trace_defining then
+ report_defining("defining letters (global, shared)")
+ end
+ for u, chr in next, data do
+ if not chr.fallback and is_letter[chr.category] and u >= 128 and u <= 65536 then
+ texsetcatcode(u,11)
+ end
+ local range = chr.range
+ if range then
+ for i=1,range.first,range.last do
+ texsetcatcode(i,11)
+ end
+ end
+ end
+ texsetcatcode(0x200C,11) -- non-joiner
+ texsetcatcode(0x200D,11) -- joiner
+ end
+ tex.catcodetable = saved
+ end
+
+ local nofactivated = #tobeactivated
+ if tobeactivated and nofactivated > 0 then
+ for i=1,nofactivated do
+ local u = activated[i]
+ if u then
+ report_defining("character %U is active in set %a, containing %a",u,data[u].description,tobeactivated)
+ end
+ end
+ local saved = tex.catcodetable
+ for i=1,#tobeactivated do
+ local vector = tobeactivated[i]
+ if trace_defining then
+ report_defining("defining %a active characters in vector %a",nofactivated,vector)
+ end
+ tex.catcodetable = vector
+ for i=1,nofactivated do
+ local u = activated[i]
+ if u then
+ texsetcatcode(u,13)
+ end
+ end
+ end
+ tex.catcodetable = saved
+ end
+
+end
+
+--[[ldx--
+<p>Setting the lccodes is also done in a loop over the data table.</p>
+--ldx]]--
+
+local sfmode = "unset" -- unset, traditional, normal
+
+function characters.setcodes()
+ if trace_defining then
+ report_defining("defining lc and uc codes")
+ end
+ local traditional = sfstate == "traditional" or sfstate == "unset"
+ for code, chr in next, data do
+ local cc = chr.category
+ if is_letter[cc] then
+ local range = chr.range
+ if range then
+ for i=range.first,range.last do
+ texsetcatcode(i,11) -- letter
+ texsetlccode(i,i,i) -- self self
+ end
+ else
+ local lc, uc = chr.lccode, chr.uccode
+ if not lc then
+ chr.lccode, lc = code, code
+ elseif type(lc) == "table" then
+ lc = code
+ end
+ if not uc then
+ chr.uccode, uc = code, code
+ elseif type(uc) == "table" then
+ uc = code
+ end
+ texsetcatcode(code,11) -- letter
+ texsetlccode(code,lc,uc)
+ if traditional and cc == "lu" then
+ texsetsfcode(code,999)
+ end
+ end
+ elseif is_mark[cc] then
+ texsetlccode(code,code,code) -- for hyphenation
+ end
+ end
+ if traditional then
+ sfstate = "traditional"
+ end
+end
+
+-- If this is something that is not documentwide and used a lot, then we
+-- need a more clever approach (trivial but not now).
+
+local function setuppersfcodes(v,n)
+ if sfstate ~= "unset" then
+ report_defining("setting uppercase sf codes to %a",n)
+ for code, chr in next, data do
+ if chr.category == "lu" then
+ texsetsfcode(code,n)
+ end
+ end
+ end
+ sfstate = v
+end
+
+directives.register("characters.spaceafteruppercase",function(v)
+ if v == "traditional" then
+ setuppersfcodes(v,999)
+ elseif v == "normal" then
+ setuppersfcodes(v,1000)
+ end
+end)
+
+-- xml
+
+characters.activeoffset = 0x10000 -- there will be remapped in that byte range
+
+function commands.remapentity(chr,slot)
+ contextsprint(format("{\\catcode%s=13\\xdef%s{\\string%s}}",slot,utfchar(slot),chr))
+end
+
+-- xml.entities = xml.entities or { }
+--
+-- storage.register("xml/entities",xml.entities,"xml.entities") -- this will move to lxml
+--
+-- function characters.setmkiventities()
+-- local entities = xml.entities
+-- entities.lt = "<"
+-- entities.amp = "&"
+-- entities.gt = ">"
+-- end
+--
+-- function characters.setmkiientities()
+-- local entities = xml.entities
+-- entities.lt = utfchar(characters.activeoffset + utfbyte("<"))
+-- entities.amp = utfchar(characters.activeoffset + utfbyte("&"))
+-- entities.gt = utfchar(characters.activeoffset + utfbyte(">"))
+-- end
+
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-chkeng.sty b/macros/luatex/latex/simurgh/tex/simurgh-chkeng.sty
new file mode 100644
index 0000000000..e272e67ab2
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-chkeng.sty
@@ -0,0 +1,18 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-chkeng}[2013/09/18 v0.01a check typesetting engine]
+\RequirePackage{ifluatex}
+\ifluatex
+\else
+ \begingroup
+ \errorcontextlines=-1\relax
+ \newlinechar=10\relax
+ \errmessage{^^J
+ ********************************************^^J
+ * lualatex is required to compile this document.^^J
+ * sorry!^^J
+ ********************************************}%
+ \endgroup
+\fi
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-clss.sty b/macros/luatex/latex/simurgh/tex/simurgh-clss.sty
new file mode 100644
index 0000000000..5b20057659
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-clss.sty
@@ -0,0 +1,48 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-clss}[2013/09/18 v0.01a changes to classes]
+
+\@ifclassloaded{amsart}{\RequirePackage{simurgh-amsart}}{}
+\@ifclassloaded{amsbook}{\RequirePackage{simurgh-amsbook}}{}
+\@ifclassloaded{article}{\RequirePackage{simurgh-article}}{}
+\@ifclassloaded{artikel1}{\RequirePackage{simurgh-artikel1}}{}
+\@ifclassloaded{artikel2}{\RequirePackage{simurgh-artikel2}}{}
+\@ifclassloaded{artikel3}{\RequirePackage{simurgh-artikel3}}{}
+\@ifclassloaded{boek}{\RequirePackage{simurgh-boek}}{}
+\@ifclassloaded{boek3}{\RequirePackage{simurgh-boek3}}{}
+\@ifclassloaded{book}{\RequirePackage{simurgh-book}}{}
+\@ifclassloaded{bookest}{\RequirePackage{simurgh-bookest}}{}
+\@ifclassloaded{extarticle}{\RequirePackage{simurgh-extarticle}}{}
+\@ifclassloaded{extbook}{\RequirePackage{simurgh-extbook}}{}
+\@ifclassloaded{extletter}{\RequirePackage{simurgh-extletter}}{}
+\@ifclassloaded{extreport}{\RequirePackage{simurgh-extreport}}{}
+\@ifclassloaded{letter}{\RequirePackage{simurgh-letter}}{}
+\@ifclassloaded{memoir}{\RequirePackage{simurgh-memoir}}{}
+\@ifclassloaded{rapport1}{\RequirePackage{simurgh-rapport1}}{}
+\@ifclassloaded{rapport3}{\RequirePackage{simurgh-rapport3}}{}
+\@ifclassloaded{refrep}{\RequirePackage{simurgh-refrep}}{}
+\@ifclassloaded{report}{\RequirePackage{simurgh-report}}{}
+\@ifclassloaded{scrartcl}{\RequirePackage{simurgh-scrartcl}}{}
+\@ifclassloaded{scrbook}{\RequirePackage{simurgh-scrbook}}{}
+\@ifclassloaded{scrlettr}{\RequirePackage{simurgh-scrlettr}}{}
+\@ifclassloaded{scrreprt}{\RequirePackage{simurgh-scrreprt}}{}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-counters.sty b/macros/luatex/latex/simurgh/tex/simurgh-counters.sty
new file mode 100644
index 0000000000..f744752461
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-counters.sty
@@ -0,0 +1,7 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-counters}[2013/09/18 v0.01a counters]
+\RequirePackage{simurgh-harfi}
+\RequirePackage{simurgh-adadi}
+\RequirePackage{simurgh-tartibi}
+\RequirePackage{simurgh-abjad}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-cptns.sty b/macros/luatex/latex/simurgh/tex/simurgh-cptns.sty
new file mode 100644
index 0000000000..a6e0384aa1
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-cptns.sty
@@ -0,0 +1,23 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-cptns}[2013/09/18 v0.01a captions]
+\def\figurename{\if@RTL Ø´Ú©Ù„\else Figure\fi}
+\def\tablename{\if@RTL جدول\else Table\fi}
+\def\contentsname{\if@RTL Ùهرست مطالب\else Contents\fi}
+\def\listfigurename{\if@RTL Ùهرست تصاویر\else List of Figures\fi}
+\def\listtablename{\if@RTL Ùهرست جداول\else List of Tables\fi}
+\def\appendixname{\if@RTL پیوست\else Appendix\fi}
+\def\indexname{\if@RTL نمایه\else Index\fi}
+\def\refname{\if@RTL مراجع\else References\fi}
+\def\abstractname{\if@RTL چکیده\else Abstract\fi}
+\def\partname{\if@RTL بخش\else Part\fi}
+\def\datename{\if@RTL تاریخ:\else Date:\fi}
+\def\@@and{\if@RTL Ùˆ\else and\fi}
+\def\bibname{\if@RTL کتاب‌نامه\else Bibliography\fi}
+\def\chaptername{\if@RTL Ùصل\else Chapter\fi}
+\def\ccname{\if@RTL رونوشت\else cc\fi}
+\def\enclname{\if@RTL پیوست\else encl\fi}
+\def\pagename{\if@RTL صÙحه\else Page\fi}
+\def\headtoname{\if@RTL به\else To\fi}
+\def\proofname{\if@RTL اثبات\else Proof\fi}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-doc.cls b/macros/luatex/latex/simurgh/tex/simurgh-doc.cls
new file mode 100644
index 0000000000..934204bf4a
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-doc.cls
@@ -0,0 +1,247 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{simurgh-doc}
+ [2013/09/18 v0.01a simurgh documentation class]
+\DeclareOption*{%
+ \PassOptionsToClass {\CurrentOption}{ltxdoc}}
+\ProcessOptions
+\LoadClass{ltxdoc}
+\RequirePackage{xcolor}
+\RequirePackage{minted}
+\RequirePackage{graphicx}
+\RequirePackage{fontspec}
+\RequirePackage[pdfborder={0 0 0},bookmarksnumbered]{hyperref}
+\RequirePackage[left=4cm,right=2.25cm,top=2.5cm,bottom=2.5cm,nohead]{geometry}
+\RequirePackage{makeidx}
+\RequirePackage{microtype}
+
+\def\simurgh{\textsc{simurgh}}
+
+\newbox\simurghlogobox
+\sbox\simurghlogobox{\includegraphics[height=0.5in,keepaspectratio=true]{simurgh-logo}}
+
+\def\ps@docheadings{%
+ \let\@oddhead\@empty
+ \def\@oddfoot{\parbox{\textwidth}{\hfill\raisebox{0.2in}{\leftmark}\quad\raisebox{0.2in}{\thepage}\qquad\usebox\simurghlogobox}}%
+ \let\@mkboth\markboth
+ \def\sectionmark##1{%
+ \markboth {%
+ ##1}{}}}
+
+\renewcommand\section{\@startsection {section}{1}{\z@}%
+ {-3.5ex \@plus -1ex \@minus -.2ex}%
+ {2.3ex \@plus.2ex}%
+ {\normalfont\Large\bfseries\color{red!65!black}}}
+\renewcommand\subsection{\@startsection{subsection}{2}{\z@}%
+ {-3.25ex\@plus -1ex \@minus -.2ex}%
+ {1.5ex \@plus .2ex}%
+ {\normalfont\large\bfseries\color{red!65!black}}}
+\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}%
+ {-3.25ex\@plus -1ex \@minus -.2ex}%
+ {1.5ex \@plus .2ex}%
+ {\normalfont\normalsize\bfseries\color{red!65!black}}}
+\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}%
+ {3.25ex \@plus1ex \@minus.2ex}%
+ {-1em}%
+ {\normalfont\normalsize\bfseries\color{red!65!black}}}
+\renewcommand\subparagraph{\@startsection{subparagraph}{5}{\parindent}%
+ {3.25ex \@plus1ex \@minus .2ex}%
+ {-1em}%
+ {\normalfont\normalsize\bfseries\color{red!65!black}}}
+
+
+\def\@undottedtocline#1#2#3#4#5{%
+ \ifnum #1>\c@tocdepth \else
+ \vskip \z@ \@plus.2\p@
+ {\leftskip #2\relax \rightskip \@tocrmarg \parfillskip -\rightskip
+ \parindent #2\relax\@afterindenttrue
+ \interlinepenalty\@M
+ \leavevmode
+ \@tempdima #3\relax
+ \advance\leftskip \@tempdima \null\nobreak\hskip -\leftskip
+ {#4}\nobreak
+ \hfill
+ \nobreak
+ \hb@xt@\@pnumwidth{\hfil\normalfont \normalcolor #5}%
+ \par}%
+ \fi}
+\renewcommand*\l@subsection{\@undottedtocline{2}{\z@}{2.3em}}
+\renewcommand*\l@subsubsection{\@undottedtocline{3}{\z@}{3.2em}}
+\renewcommand*\l@paragraph{\@undottedtocline{4}{\z@}{4.1em}}
+\renewcommand*\l@subparagraph{\@undottedtocline{5}{\z@}{5em}}
+\renewcommand*\l@figure{\@undottedtocline{1}{\z@}{2.3em}}
+\let\l@table\l@figure
+
+\renewcommand\tableofcontents{%
+ \section*{\contentsname
+ \@mkboth{%
+ \contentsname}{\contentsname}}%
+ \@starttoc{toc}%
+ }
+
+\providecommand\href[2]{\texttt{#1}}
+
+\colorlet{examplefill}{yellow!80!black}
+\definecolor{graphicbackground}{rgb}{0.96,0.96,0.8}
+\definecolor{codebackground}{rgb}{0.8,0.8,1}
+
+\newcommand{\smplfile}[1]{\par\smallskip\noindent\llap{\color{blue!65!black}\vtop to0pt{\llap{\textbf{\textsc{sample}}}\vskip-3pt\llap{\texttt{#1}}\vss}\ \ }}
+\newcommand{\defaultkeyval}{\llap{\color{orange!85!black}\textbf{\textsc{default}}\hskip\leftmargin}}
+
+\newenvironment{simurghmanualentry}{\list{}{\leftmargin=2em\itemindent-\leftmargin\def\makelabel##1{\hss##1}}}{\endlist}
+\newcommand\simurghmanualentryheadline[1]{\itemsep=0pt\parskip=0pt\item\strut#1\par\topsep=0pt}
+\newcommand\simurghmanualbody{\parskip3pt}
+
+\newenvironment{command}[1]{
+ \begin{simurghmanualentry}
+ \extractcommand#1\@@
+ \simurghmanualbody
+}
+{
+ \end{simurghmanualentry}
+}
+
+\def\extractcommand#1#2\@@{%
+ \simurghmanualentryheadline{\declare{\texttt{\string#1}}#2}%
+ \removeats{#1}%
+ \index{\strippedat @\protect\myprintocmmand{\strippedat}}}
+
+
+\renewenvironment{environment}[1]{
+ \begin{simurghmanualentry}
+ \extractenvironement#1\@@
+ \simurghmanualbody
+}
+{
+ \end{simurghmanualentry}
+}
+
+\def\extractenvironement#1#2\@@{%
+ \simurghmanualentryheadline{{\ttfamily\char`\\begin\char`\{\declare{#1}\char`\}}#2}%
+ \simurghmanualentryheadline{{\ttfamily\ \ }\meta{environment contents}}%
+ \simurghmanualentryheadline{{\ttfamily\char`\\end\char`\{\declare{#1}\char`\}}}%
+ \index{#1@\protect\texttt{#1} environment}%
+ \index{Environments!#1@\protect\texttt{#1}}}
+
+\newenvironment{package}[1]{
+ \begin{simurghmanualentry}
+ \simurghmanualentryheadline{{\ttfamily\char`\\usepackage\opt{[\meta{options}]}\char`\{\declare{#1}\char`\}}}
+ \index{#1@\protect\texttt{#1} package}%
+ \index{Packages and files!#1@\protect\texttt{#1}}%
+ \simurghmanualbody
+}
+{
+ \end{simurghmanualentry}
+}
+
+
+
+\newenvironment{filedescription}[1]{
+ \begin{simurghmanualentry}
+ \simurghmanualentryheadline{File {\ttfamily\declare{#1}}}%
+ \index{#1@\protect\texttt{#1} file}%
+ \index{Packages and files!#1@\protect\texttt{#1}}%
+ \simurghmanualbody
+}
+{
+ \end{simurghmanualentry}
+}
+
+
+\newenvironment{packageoption}[1]{
+ \begin{simurghmanualentry}
+ \simurghmanualentryheadline{{\ttfamily\char`\\usepackage[\declare{#1}]\char`\{simurgh\char`\}}}
+ \index{#1@\protect\texttt{#1} package option}%
+ \index{Package options for \textsc{simurgh}!#1@\protect\texttt{#1}}%
+ \simurghmanualbody
+}
+{
+ \end{simurghmanualentry}
+}
+
+
+
+\newcommand\opt[1]{{\color{black!50!green}#1}}
+\newcommand\ooarg[1]{{\ttfamily[}\meta{#1}{\ttfamily]}}
+
+\let\oarg\simurgh@undefined
+\providecommand\oarg[1]{%
+ {\color{black!50!green}{\ttfamily[}\meta{#1}{\ttfamily]}}}
+
+
+
+
+\def\opt{\afterassignment\simurghmanualopt\let\next=}
+\def\simurghmanualopt{\ifx\next\bgroup\bgroup\color{black!50!green}\else{\color{black!50!green}\next}\fi}
+
+
+
+
+\def\pdf{\textsc{pdf}}
+
+
+{
+ \makeatletter
+ \global\let\myempty=\@empty
+ \global\let\mygobble=\@gobble
+ \makeatother
+ \gdef\getridofats#1@#2\relax{%
+ \def\getridtest{#2}%
+ \ifx\getridtest\myempty%
+ \expandafter\def\expandafter\strippedat\expandafter{\strippedat#1}
+ \else%
+ \expandafter\def\expandafter\strippedat\expandafter{\strippedat#1\protect\printanat}
+ \getridofats#2\relax%
+ \fi%
+ }
+
+ \gdef\removeats#1{%
+ \let\strippedat\myempty%
+ \edef\strippedtext{\stripcommand#1}%
+ \expandafter\getridofats\strippedtext @\relax%
+ }
+
+ \gdef\stripcommand#1{\expandafter\mygobble\string#1}
+}
+
+\def\printanat{\char`\@}
+
+\def\declare{\afterassignment\simurghmanualdeclare\let\next=}
+\def\simurghmanualdeclare{\ifx\next\bgroup\bgroup\color{red!75!black}\else{\color{red!75!black}\next}\fi}
+
+\def\example{\par\smallskip\noindent\textit{Example: }}
+
+\def\itemoption#1{\item \declare{\texttt{#1}}%
+ \indexoption{#1}%
+}
+
+\def\indexoption#1{%
+ \index{#1@\protect\texttt{#1} option}%
+ \index{Options!#1@\protect\texttt{#1}}%
+}
+
+\let\textoken=\command
+\let\endtextoken=\endcommand
+
+\def\myprintocmmand#1{\texttt{\char`\\#1}}
+
+
+\def\index@prologue{\section*{Index}\addcontentsline{toc}{section}{Index}}
+\c@IndexColumns=2
+ \def\theindex{\@restonecoltrue
+ \columnseprule \z@ \columnsep 35\p@
+ \twocolumn[\index@prologue]%
+ \@mkboth{\indexname}%
+ {\indexname}%
+ \parindent -30pt
+ \columnsep 15pt
+ \parskip 0pt plus 1pt
+ \leftskip 30pt
+ \rightskip 0pt plus 2cm
+ \small
+ \def\@idxitem{\par}%
+ \let\item\@idxitem \ignorespaces}
+ \def\endtheindex{\onecolumn}
+\def\noindexing{\let\index=\@gobble}
+
+
+\endinput
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-empheq.sty b/macros/luatex/latex/simurgh/tex/simurgh-empheq.sty
new file mode 100644
index 0000000000..00a8fbbc96
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-empheq.sty
@@ -0,0 +1,132 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-empheq}[2013/09/22 v0.01b changes to `empheq.sty']
+\MHInternalSyntaxOn
+\def\EQ_post_process:{%
+ \EQ_initialize:
+ \EQ_begin_equation:
+ \MH_if_boolean:nT {outer_mult}{
+ \setkeys{\MT_options_name:}{
+ firstline-afterskip=0pt,
+ lastline-preskip=0pt,
+ multlined-width=0pt,
+ }
+ \ifodd \l_EQ_alignmentmode_int
+ \setkeys{\MT_options_name:}{multlined-pos=b}
+ \else:
+ \setkeys{\MT_options_name:}{multlined-pos=t}
+ \fi:
+ \g@addto@macro\EQ_complete_mathdisplay:{
+ \begin{MTmultlined}\relax}
+ }
+ \g@addto@macro\EQ_complete_mathdisplay:\EQ_mathbody:
+ \MH_if_boolean:nT {outer_mult}{
+ \g@addto@macro\EQ_complete_mathdisplay:{\end{MTmultlined}}
+ }
+ \EQ_end_equation:
+ \edef\EQ_hyperref_link_fint{\number\Hy@linkcounter}
+ \savecounters@
+ \EQ_typeset_tags:
+ \edef\l_EQ_equation_fint{\number\c@equation}
+ \restorecounters@
+ \Hy@linkcounter=\EQ_hyperref_link_fint
+ \settowidth\l_EQ_totalwidth_dim{%
+ $\EQ_left_side:\EQ_innerbox:{}\EQ_right_side:$}%
+ \MH_if_boolean:nTF {outer_mult}
+ { \def\EQ_next:{_mult} }
+ { \def\EQ_next:{} }
+ \@nameuse{EQ_modify_linewidth_
+ \romannumeral\l_EQ_equationtype_int\EQ_next: :}%
+ \EQ_typeset_display:
+ \@nameuse{find_displaywidth_
+ \romannumeral\l_EQ_equationtype_int\EQ_next: :}
+ \MH_addtolength:dn
+ \l_EQ_totalwidth_dim{\l_EQ_displaywidth_dim}
+ \savebox\EQ_mathdisplay_box[\l_EQ_totalwidth_dim][c]{%
+ $\EQ_left_side:
+ \EQ_innerbox:{%
+ \if_case:w \l_EQ_alignmentmode_int\or:
+ \makebox[\l_EQ_displaywidth_dim][c]
+ {\usebox{\EQ_mathdisplay_box}}%
+ \or:
+ \makebox[\l_EQ_displaywidth_dim][c]
+ {\usebox{\EQ_mathdisplay_box}}%
+ \or:
+ \if@RTL\makebox[\l_EQ_displaywidth_dim][r]{%op
+ \if_num:w \l_EQ_equationtype_int=5 \else:
+ \if_num:w \l_EQ_equationtype_int=6 \else:
+ \kern-\@mathmargin
+ \fi:
+ \fi:
+ \usebox{\EQ_mathdisplay_box}}\else%
+ \makebox[\l_EQ_displaywidth_dim][l]{%op
+ \if_num:w \l_EQ_equationtype_int=5 \else:
+ \if_num:w \l_EQ_equationtype_int=6 \else:
+ \kern-\@mathmargin
+ \fi:
+ \fi:
+ \usebox{\EQ_mathdisplay_box}}\fi%
+ \or:
+ \if@RTL\makebox[\l_EQ_displaywidth_dim][r]{%
+ \if_num:w \l_EQ_equationtype_int=5 \else:
+ \if_num:w \l_EQ_equationtype_int=6 \else:
+ \kern-\@mathmargin
+ \fi:
+ \fi:
+ \usebox{\EQ_mathdisplay_box}}\else%
+ \makebox[\l_EQ_displaywidth_dim][l]{%
+ \if_num:w \l_EQ_equationtype_int=5 \else:
+ \if_num:w \l_EQ_equationtype_int=6 \else:
+ \kern-\@mathmargin
+ \fi:
+ \fi:
+ \usebox{\EQ_mathdisplay_box}}\fi%
+ \fi:}%
+ \EQ_right_side:$}%
+ \begin{AmSequation*}
+ \@nameuse{EQ_place_display_
+ \romannumeral\l_EQ_equationtype_int\EQ_next: :}
+ \if_dim:w \g_EQ_widesttag_dim>\z@
+ \MH_set_boolean_T:n {show_manual_tags}
+ \if_case:w \l_EQ_alignmentmode_int
+ \or: \EQ_place_tag:N r %#1
+ \or: \EQ_place_tag:N l %#2
+ \or: \EQ_place_tag:N r %#3
+ \or: \EQ_place_tag:N l %#4
+ \fi:
+ \fi:
+ \end{AmSequation*}
+ \global\c@equation=\l_EQ_equation_fint\relax
+}
+\AtBeginDocument{%
+ \@ifpackageloaded{fancybox}{%
+ \@ifpackageloaded{color}{\definecolor{shadowcolor}{rgb}{0,0,0}}%
+ {\renewcommand*\textcolor[2]{\normalcolor{#2}}}%
+ \renewcommand*\shadowbox{%
+ \@ifstar{\MH_set_boolean_T:n {shadowbox_star}
+ \VerbBox\EQ_shadowbox:n}
+ {\MH_set_boolean_F:n {shadowbox_star}
+ \VerbBox\EQ_shadowbox:n}}
+ \def\EQ_shadowbox:n #1{%
+ \sbox{\z@}{\fbox{#1}}%
+ \MH_if_boolean:nTF {shadowbox_star}{
+ \MH_setlength:dn \@tempdima{\z@}%
+ }{
+ \MH_setlength:dn \@tempdima{\dp\z@+\shadowsize}%
+ }
+ \raisebox{\@tempdima}{%
+ \if@RTL\makebox[\z@][r]{%
+ \kern\shadowsize \textcolor{shadowcolor}{%
+ \rule[-\dp\z@-\shadowsize]{\wd\z@}{\shadowsize}}%
+ }%
+ \else\makebox[\z@][l]{%
+ \kern\shadowsize \textcolor{shadowcolor}{%
+ \rule[-\dp\z@-\shadowsize]{\wd\z@}{\shadowsize}}%
+ }\fi%
+ \usebox\z@\textcolor{shadowcolor}{%
+ \rule[-\dp\z@-\shadowsize]{\shadowsize}{\ht\z@+\dp\z@}}}}%
+ }{}%
+}
+\MHInternalSyntaxOff
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-extarticle.sty b/macros/luatex/latex/simurgh/tex/simurgh-extarticle.sty
new file mode 100644
index 0000000000..3f4e26e725
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-extarticle.sty
@@ -0,0 +1,85 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-extarticle}[2013/09/18 v0.01a changes to `extarticle.cls']
+
+ \def\@part[#1]#2{%
+ \ifnum \c@secnumdepth >\m@ne
+ \refstepcounter{part}%
+ \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}%
+ \else
+ \addcontentsline{toc}{part}{#1}%
+ \fi
+ {\parindent \z@ \simurgh@raggedright
+ \interlinepenalty \@M
+ \normalfont
+ \ifnum \c@secnumdepth >\m@ne
+ \Large\bfseries \partname~\thepart
+ \par\nobreak
+ \fi
+ \huge \bfseries #2%
+ \markboth{}{}\par}%
+ \nobreak
+ \vskip 3ex
+ \@afterheading}
+ \def\@spart#1{%
+ {\parindent \z@ \simurgh@raggedright
+ \interlinepenalty \@M
+ \normalfont
+ \huge \bfseries #1\par}%
+ \nobreak
+ \vskip 3ex
+ \@afterheading}
+\renewenvironment{thebibliography}[1]
+ {\section*{\refname
+ \@mkboth{\MakeUppercase\refname}{\MakeUppercase\refname}}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy\clubpenalty4000\widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+\renewcommand\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern2.6\p@}\hfil}}
+\renewcommand\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern2.6\p@}\hfil}}
+
+\renewcommand\thesubsection {\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand\thesubsubsection{\thesubsection \@SepMark\@arabic\c@subsubsection}
+\renewcommand\theparagraph {\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand\thesubparagraph {\theparagraph\@SepMark\@arabic\c@subparagraph}%%
+
+
+\renewcommand\thepart {\@tartibi\c@part}
+\renewcommand\appendix{\par
+ \setcounter{section}{0}%
+ \setcounter{subsection}{0}%
+ \gdef\thesection{\@harfi\c@section}}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-extbook.sty b/macros/luatex/latex/simurgh/tex/simurgh-extbook.sty
new file mode 100644
index 0000000000..87c5329857
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-extbook.sty
@@ -0,0 +1,85 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-extbook}[2013/09/18 v0.01a changes to `extbook.cls']
+\renewcommand\theequation
+ {\ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@equation}
+\renewcommand \thefigure
+ {\ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@figure}
+\renewcommand \thetable
+ {\ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@table}
+\renewcommand \thechapter {\@arabic\c@chapter}
+\renewcommand \thesection {\thechapter\@SepMark\@arabic\c@section}
+\renewcommand\thesubsection {\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand\thesubsubsection{\thesubsection \@SepMark\@arabic\c@subsubsection}
+\renewcommand\theparagraph {\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand\thesubparagraph {\theparagraph\@SepMark\@arabic\c@subparagraph}
+
+\def\@makechapterhead#1{%
+ \vspace*{50\p@}%
+ {\parindent \z@ \simurgh@raggedright \normalfont
+ \ifnum \c@secnumdepth >\m@ne
+ \if@mainmatter
+ \huge\bfseries \@chapapp\space \thechapter
+ \par\nobreak
+ \vskip 20\p@
+ \fi
+ \fi
+ \interlinepenalty\@M
+ \Huge \bfseries #1\par\nobreak
+ \vskip 40\p@
+ }}
+
+\def\@makeschapterhead#1{%
+ \vspace*{50\p@}%
+ {\parindent \z@ \simurgh@raggedright
+ \normalfont
+ \interlinepenalty\@M
+ \Huge \bfseries #1\par\nobreak
+ \vskip 40\p@
+ }}
+
+\renewenvironment{thebibliography}[1]
+ {\chapter*{\bibname
+ \@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy
+ \clubpenalty4000
+ \@clubpenalty \clubpenalty
+ \widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+
+\renewcommand\frontmatter{%
+ \cleardoublepage
+ \@mainmatterfalse
+ \pagenumbering{harfi}}
+\renewcommand \thepart {\@tartibi\c@part}
+\renewcommand\appendix{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}
+}%end appendix
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-extletter.sty b/macros/luatex/latex/simurgh/tex/simurgh-extletter.sty
new file mode 100644
index 0000000000..d55df189ad
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-extletter.sty
@@ -0,0 +1,41 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-extletter}[2013/09/18 v0.01a changes to `extletter.cls']
+\renewcommand*{\opening}[1]{\ifx\@empty\fromaddress
+ \thispagestyle{firstpage}%
+ {\simurgh@raggedleft\@date\par}%
+ \else % home address
+ \thispagestyle{empty}%
+ {\simurgh@raggedleft\if@RTL\begin{tabular}{r@{}}\else\begin{tabular}{l@{}}\fi\ignorespaces
+ \fromaddress \\*[2\parskip]%
+ \@date \end{tabular}\par}%
+ \fi
+ \vspace{2\parskip}%
+ {\simurgh@raggedright \toname \\ \toaddress \par}%
+ \vspace{2\parskip}%
+ #1\par\nobreak}
+\renewcommand{\closing}[1]{\par\nobreak\vspace{\parskip}%
+ \stopbreaks
+ \noindent
+ \ifx\@empty\fromaddress\else
+ \hspace*{\longindentation}\fi
+ \parbox{\indentedwidth}{\simurgh@raggedright
+ \ignorespaces #1\\[6\medskipamount]%
+ \ifx\@empty\fromsig
+ \fromname
+ \else \fromsig \fi\strut}%
+ \par}
+\renewcommand\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-\p@
+ \hrule \@width .4\columnwidth
+ \kern .6\p@}\hfil}}
+\renewcommand\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-\p@
+ \hrule \@width .4\columnwidth
+ \kern .6\p@}\hfil}}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-extreport.sty b/macros/luatex/latex/simurgh/tex/simurgh-extreport.sty
new file mode 100644
index 0000000000..b7f92e316d
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-extreport.sty
@@ -0,0 +1,85 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-extreport}[2013/09/18 v0.01a changes to `extreport.cls']
+\def\@makechapterhead#1{%
+ \vspace*{50\p@}%
+ {\parindent \z@ \simurgh@raggedright \normalfont
+ \ifnum \c@secnumdepth >\m@ne
+ \huge\bfseries \@chapapp\space \thechapter
+ \par\nobreak
+ \vskip 20\p@
+ \fi
+ \interlinepenalty\@M
+ \Huge \bfseries #1\par\nobreak
+ \vskip 40\p@
+ }}
+\def\@makeschapterhead#1{%
+ \vspace*{50\p@}%
+ {\parindent \z@ \simurgh@raggedright
+ \normalfont
+ \interlinepenalty\@M
+ \Huge \bfseries #1\par\nobreak
+ \vskip 40\p@
+ }}
+\renewcommand\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern2.6\p@}\hfil}}
+\renewcommand\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern2.6\p@}\hfil}}
+\renewenvironment{thebibliography}[1]
+ {\chapter*{\bibname
+ \@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy\clubpenalty4000\widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+
+\renewcommand\thesection {\thechapter\@SepMark\@arabic\c@section}
+\renewcommand\thesubsection {\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand\thesubsubsection{\thesubsection \@SepMark\@arabic\c@subsubsection}
+\renewcommand\theparagraph {\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand\thesubparagraph {\theparagraph\@SepMark\@arabic\c@subparagraph}
+\renewcommand\theequation{%
+ \ifnum \c@chapter>\z@ \thechapter\@SepMark\fi\@arabic\c@equation}
+\renewcommand\thefigure{%
+ \ifnum \c@chapter>\z@\thechapter\@SepMark\fi \@arabic\c@figure}
+\renewcommand\thetable{%
+ \ifnum \c@chapter>\z@\thechapter\@SepMark\fi\@arabic\c@table}
+
+\renewcommand\thepart {\@tartibi\c@part}
+\renewcommand\appendix{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-fleqn.sty b/macros/luatex/latex/simurgh/tex/simurgh-fleqn.sty
new file mode 100644
index 0000000000..bb7cb480d6
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-fleqn.sty
@@ -0,0 +1,27 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-fleqn}[2013/09/22 v0.01a fleqn]
+\renewcommand\[{\relax
+ \ifmmode\@badmath
+ \else
+ \begin{trivlist}%
+ \@beginparpenalty\predisplaypenalty
+ \@endparpenalty\postdisplaypenalty
+ \item[]\leavevmode
+ \hbox dir TLT to \linewidth\bgroup $\m@th\displaystyle %$
+ \hskip\mathindent\bgroup
+ \fi}
+
+
+\renewenvironment{equation}%
+ {\@beginparpenalty\predisplaypenalty
+ \@endparpenalty\postdisplaypenalty
+ \refstepcounter{equation}%
+ \trivlist \item[]\leavevmode
+ \hbox dir TLT to \linewidth\bgroup $\m@th% $
+ \displaystyle
+ \hskip\mathindent}%
+ {$\hfil % $
+ \displaywidth\linewidth\if@RTL\hboxR\else\hboxL\fi{\@eqnnum}%
+ \egroup
+ \endtrivlist}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-fonts.sty b/macros/luatex/latex/simurgh/tex/simurgh-fonts.sty
new file mode 100644
index 0000000000..d44055abc9
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-fonts.sty
@@ -0,0 +1,128 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-fonts}[2013/09/18 v0.01a fonts]
+\newfontscript{Parsi}{arab}
+\newfontlanguage{Parsi}{FAR}
+\aliasfontfeatureoption{Numbers}{Arabic}{Parsi}
+\ExplSyntaxOn
+\DeclareDocumentCommand \setmainparsifont { O{} m } {
+ \fontspec_select:nn{Script=Parsi,Numbers=Parsi,Language=Parsi,#1}{#2}
+ \use:x {
+ \exp_not:N \DeclareRobustCommand \exp_not:N \parsimainfont {
+ \exp_not:N \fontencoding {\g_fontspec_encoding_tl}
+ \exp_not:N \fontfamily {\l_fontspec_family_tl} \exp_not:N \selectfont
+ }
+ }
+ \cs_set_eq:NN \rmdefault \l_fontspec_family_tl
+ \normalfont
+}
+\DeclareDocumentCommand \setmainlatinfont { O{} m } {
+ \fontspec_select:nn{Ligatures=TeX,#1}{#2}
+ \use:x {
+ \exp_not:N \DeclareRobustCommand \exp_not:N \latinmainfont {
+ \exp_not:N \fontencoding {\g_fontspec_encoding_tl}
+ \exp_not:N \fontfamily {\l_fontspec_family_tl} \exp_not:N \selectfont
+ }
+ }
+}
+\cs_set_eq:NN \setlatinsansfont \setsansfont
+\cs_set_eq:NN \setlatinmonofont \setmonofont
+\DeclareDocumentCommand \loadnewparsifont { m O{} m } {
+ \fontspec_select:nn{Script=Parsi,Numbers=Parsi,Language=Parsi,#2}{#3}
+ \use:x {
+ \exp_not:N \DeclareRobustCommand \exp_not:N #1 {
+ \exp_not:N \fontencoding {\g_fontspec_encoding_tl}
+ \exp_not:N \fontfamily {\l_fontspec_family_tl} \exp_not:N \selectfont
+ }
+ }
+}
+\DeclareDocumentCommand \loadnewlatinfont { m O{} m } {
+ \fontspec_select:nn{Ligatures=TeX,#2}{#3}
+ \use:x {
+ \exp_not:N \DeclareRobustCommand \exp_not:N #1 {
+ \exp_not:N \fontencoding {\g_fontspec_encoding_tl}
+ \exp_not:N \fontfamily {\l_fontspec_family_tl} \exp_not:N \selectfont
+ }
+ }
+}
+\newcommand\parsisfdefault{}
+\newcommand\parsittdefault{}
+\newcommand\iranicdefault{}
+\newcommand\navardefault{}
+\newcommand\pookdefault{}
+\newcommand\sayehdefault{}
+\DeclareRobustCommand\parsisffamily
+ {\not@math@alphabet\parsisffamily\mathparsisf
+ \fontfamily\parsisfdefault\selectfont}
+\DeclareRobustCommand\parsittfamily
+ {\not@math@alphabet\parsittfamily\mathparsitt
+ \fontfamily\parsittdefault\selectfont}
+\DeclareRobustCommand\iranicfamily
+ {\not@math@alphabet\iranicfamily\mathiranic
+ \fontfamily\iranicdefault\selectfont}
+\DeclareRobustCommand\navarfamily
+ {\not@math@alphabet\navarfamily\mathnavar
+ \fontfamily\navardefault\selectfont}
+\DeclareRobustCommand\pookfamily
+ {\not@math@alphabet\pookfamily\mathpook
+ \fontfamily\pookdefault\selectfont}
+\DeclareRobustCommand\sayehfamily
+ {\not@math@alphabet\sayehfamily\mathsayeh
+ \fontfamily\sayehdefault\selectfont}
+\DeclareTextFontCommand{\textparsisf}{\parsisffamily}
+\DeclareTextFontCommand{\textparsitt}{\parsittfamily}
+\DeclareTextFontCommand{\textiranic}{\iranicfamily}
+\DeclareTextFontCommand{\textnavar}{\navarfamily}
+\DeclareTextFontCommand{\textpook}{\pookfamily}
+\DeclareTextFontCommand{\textsayeh}{\sayehfamily}
+\DeclareDocumentCommand \setparsisansfont { O{} m } {
+ \fontspec_set_family:Nnn \parsisfdefault {Script=Parsi,Numbers=Parsi,Language=Parsi,#1}{#2}
+ \normalfont
+}
+\DeclareDocumentCommand \setparsimonofont { O{} m } {
+ \fontspec_set_family:Nnn \parsittdefault {Script=Parsi,Numbers=Parsi,Language=Parsi,#1}{#2}
+ \normalfont
+}
+\DeclareDocumentCommand \setnavarfont { O{} m } {
+ \fontspec_set_family:Nnn \navardefault {Script=Parsi,Numbers=Parsi,Language=Parsi,#1}{#2}
+ \normalfont
+}
+\DeclareDocumentCommand \setpookfont { O{} m } {
+ \fontspec_set_family:Nnn \pookdefault {Script=Parsi,Numbers=Parsi,Language=Parsi,#1}{#2}
+ \normalfont
+}
+
+\DeclareDocumentCommand \setsayehfont { O{} m } {
+ \fontspec_set_family:Nnn \sayehdefault {Script=Parsi,Numbers=Parsi,Language=Parsi,#1}{#2}
+ \normalfont
+}
+
+\DeclareDocumentCommand \setiranicfont { O{} m } {
+ \fontspec_set_family:Nnn \iranicdefault {Script=Parsi,Numbers=Parsi,Language=Parsi,#1}{#2}
+ \normalfont
+}
+\ExplSyntaxOff
+
+\def\reset@latinfont{%
+\let\normalfont\latinmainfont%
+\let\reset@font\normalfont%
+\latinmainfont}
+
+
+\def\reset@parsifont{%
+\let\normalfont\parsimainfont%
+\let\reset@font\normalfont%
+\parsimainfont}
+
+
+\simurgh@AtEndPreamble{%
+ \if@simurgh@csundef{parsimainfont}{%
+ \simurgh@error{choose the main parsi font}{}}%
+ {}%
+}
+
+
+
+% this is not good at all; it requires heaps of improvements
+\setmainlatinfont[ExternalLocation,BoldFont={lmroman10-bold},BoldItalicFont={lmroman10-bolditalic},ItalicFont={lmroman10-italic},SmallCapsFont={lmromancaps10-regular},SlantedFont={lmromanslant10-regular},BoldSlantedFont={lmromanslant10-bold}]{lmroman10-regular}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-footnotes.sty b/macros/luatex/latex/simurgh/tex/simurgh-footnotes.sty
new file mode 100644
index 0000000000..96526d98e4
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-footnotes.sty
@@ -0,0 +1,361 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-footnotes}[2013/09/18 v0.01a footnotes]
+\RequirePackage{zref-abspage}
+\RequirePackage{auxhook}
+\RequirePackage{ltxcmds}
+\newif\if@RTL@footnote
+\newif\if@autofootnoterule
+\newif\iffootdir@debug
+
+\def\simurgh@mpfootnoterule{\footnoterule}
+\newcounter{footdir@label}
+\renewcommand*{\thefootdir@label}{footdir@\the\value{footdir@label}}
+\newcommand*{\footdir@write}{%
+ \stepcounter{footdir@label}%
+ \zref@labelbyprops{\thefootdir@label}{abspage}%
+}
+
+\newcommand*{\debugfootnotedirection}{\footdir@debugtrue}
+\newtoks\footdir@toks
+\newcommand*{\footdir@debug}[1]{%
+ \iffootdir@debug
+ \typeout{[footdir] #1}%
+ \fi
+}
+\@ifpackagelater{zref-abspage}{2012/10/27}{%
+ \newcommand*{\footdir@LeftRightElse}{%
+ \ltx@ifundefined{footdir@\the\value{zabspage}}{%
+ \footdir@debug{abspage \the\value{zabspage}: else}%
+ \ltx@thirdofthree
+ }{%
+ \if\csname footdir@\the\value{zabspage}\endcsname L%
+ \footdir@debug{abspage \the\value{zabspage}: left}%
+ \expandafter\ltx@firstofthree
+ \else
+ \footdir@debug{abspage \the\value{zabspage}: right}%
+ \expandafter\ltx@secondofthree
+ \fi
+ }%
+ }%
+}{%
+ \providecommand*{\c@zabspage}{\c@abspage}%
+ \newcommand*{\footdir@LeftRightElse}{%
+ \footdir@write
+ \zifrefundefined{\thefootdir@label}{%
+ \footdir@debug{abspage ??: else}%
+ \ltx@thirdofthree
+ }{%
+ \edef\footdir@abspage{%
+ \zref@extractdefault{\thefootdir@label}{abspage}{0}%
+ }%
+ \ltx@ifundefined{footdir@\footdir@abspage}{%
+ \footdir@debug{\footdir@abspage: else}%
+ \ltx@thirdofthree
+ }{%
+ \if\csname footdir@\footdir@abspage\endcsname L%
+ \footdir@debug{\footdir@abspage: left}%
+ \expandafter\ltx@firstofthree
+ \else
+ \footdir@debug{\footdir@abspage: right}%
+ \expandafter\ltx@secondofthree
+ \fi
+ }%
+ }%
+ }%
+}
+\newcommand*{\footdir@fntext}[1]{%
+ \zifrefundefined{\thefootdir@label}{%
+ }{%
+ \edef\footdir@name{%
+ footdir@\zref@extractdefault{\thefootdir@label}{abspage}{0}%
+ }%
+ \@ifundefined{\footdir@name}{%
+ \expandafter\gdef\csname\footdir@name\endcsname{#1}%
+ }{}%
+ }%
+}
+
+\newcommand*{\footdir@temp}[3]{%
+ \@ifdefinable{#1}{%
+ \let#1#2%
+ \renewcommand{#2}[1]{%
+ \footdir@write
+ \footdir@fntext{#3}%
+ \stepcounter{footdir@label}%
+ \footdir@fntext{#3}%
+ \footdir@toks{##1}%
+ \footdir@toks\expandafter{%
+ \the\expandafter\footdir@toks
+ \expandafter
+ \zref@labelbyprops\expandafter{\thefootdir@label}{abspage}%
+ }%
+ \expandafter#1\expandafter{\the\footdir@toks}%
+ }%
+ }%
+}
+
+\def\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{\kern -3\p@
+ \hrule width .4\columnwidth \kern2.6\p@}\hfil}}
+\def\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{\kern -3\p@
+ \hrule width .4\columnwidth \kern2.6\p@}\hfil}}
+\def\textwidth@footnoterule{\kern-3\p@
+ \hrule \@width \columnwidth \kern 2.6\p@}
+\def\leftfootnoterule{%
+\@autofootnoterulefalse%
+\def\footnoterule{\left@footnoterule}}
+\def\rightfootnoterule{%
+\@autofootnoterulefalse%
+\def\footnoterule{\right@footnoterule}}
+\def\textwidthfootnoterule{%
+\@autofootnoterulefalse%
+\def\footnoterule{\textwidth@footnoterule}}
+
+\def\auto@footnoterule{%
+\footdir@LeftRightElse%
+\left@footnoterule%
+\right@footnoterule%
+\left@footnoterule%
+}
+
+\def\autofootnoterule{%
+\@autofootnoteruletrue%
+\def\footnoterule{\auto@footnoterule}%
+}
+
+\newcommand*{\SplitFootnoteRule}{%
+ \gdef\split@prev{0}
+ \let\pagefootnoterule\footnoterule
+ \let\mpfootnoterule\footnoterule
+ \def\splitfootnoterule{\kern-3\p@ \hrule \kern2.6\p@}
+ \def\footnoterule{\relax
+ \ifx \@listdepth\@mplistdepth
+ \mpfootnoterule
+ \else
+ \ifnum\split@prev=\z@
+ \pagefootnoterule
+ \else
+ \splitfootnoterule
+ \fi
+ \xdef\split@prev{\the\insertpenalties}%
+ \fi
+ }%
+}
+
+\def\RTLfootnote{\@ifnextchar[\@xRTLfootnote{\stepcounter\@mpfn
+ \protected@xdef\@thefnmark{\thempfn}%
+ \@footnotemark\@RTLfootnotetext}}
+\def\@xRTLfootnote[#1]{%
+ \begingroup
+ \csname c@\@mpfn\endcsname #1\relax
+ \unrestored@protected@xdef\@thefnmark{\thempfn}%
+ \endgroup
+ \@footnotemark\@RTLfootnotetext}
+\def\LTRfootnote{\@ifnextchar[\@xLTRfootnote{\stepcounter\@mpfn
+ \protected@xdef\@thefnmark{\thempfn}%
+ \@footnotemark\@LTRfootnotetext}}
+\def\@xLTRfootnote[#1]{%
+ \begingroup
+ \csname c@\@mpfn\endcsname #1\relax
+ \unrestored@protected@xdef\@thefnmark{\thempfn}%
+ \endgroup
+ \@footnotemark\@LTRfootnotetext}
+
+
+
+\long\def\@footnotetext#1{\insert\footins{%
+ \if@RTL@footnote%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \reset@parsifont%
+ \else%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \reset@latinfont%
+ \fi%
+ \footnotesize
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\footnotesep
+ \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
+ \hsize\columnwidth \@parboxrestore
+ \protected@edef\@currentlabel{%
+ \csname p@footnote\endcsname\@thefnmark
+ }%
+ \color@begingroup
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+ \color@endgroup}}%
+
+\long\def\@RTLfootnotetext#1{\insert\footins{%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \reset@parsifont\footnotesize
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\footnotesep
+ \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
+ \hsize\columnwidth \@parboxrestore
+ \protected@edef\@currentlabel{%
+ \csname p@footnote\endcsname\@thefnmark
+ }%
+ \color@begingroup
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+ \color@endgroup}}%
+
+\long\def\@LTRfootnotetext#1{\insert\footins{%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \reset@latinfont\footnotesize
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\footnotesep
+ \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
+ \hsize\columnwidth \@parboxrestore
+ \protected@edef\@currentlabel{%
+ \csname p@footnote\endcsname\@thefnmark
+ }%
+ \color@begingroup
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+ \color@endgroup}}%
+
+\AtBeginDocument{%
+\if@RTL@footnote
+ \newcommand*{\simurgh@footdir@footnote}{R}
+\else
+ \newcommand*{\simurgh@footdir@footnote}{L}
+\fi%
+}
+
+\footdir@temp\footdir@ORG@simurgh@footnotetext\@footnotetext{\simurgh@footdir@footnote}%
+\footdir@temp\footdir@ORG@simurgh@RTLfootnotetext\@RTLfootnotetext{R}%
+\footdir@temp\footdir@ORG@simurgh@LTRfootnotetext\@LTRfootnotetext{L}%
+
+\long\def\@mpRTLfootnotetext#1{%
+ \if@autofootnoterule\ifnum\c@mpfootnote=\@ne\global\let\simurgh@mpfootnoterule\right@footnoterule\fi\fi%
+ \global\setbox\@mpfootins\vbox{%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \unvbox\@mpfootins
+ \reset@parsifont\footnotesize
+ \hsize\columnwidth
+ \@parboxrestore
+ \protected@edef\@currentlabel
+ {\csname p@mpfootnote\endcsname\@thefnmark}%
+ \color@begingroup
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+ \color@endgroup}}
+\long\def\@mpLTRfootnotetext#1{%
+ \if@autofootnoterule\ifnum\c@mpfootnote=\@ne\global\let\simurgh@mpfootnoterule\left@footnoterule\fi\fi%
+ \global\setbox\@mpfootins\vbox{%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \unvbox\@mpfootins
+ \reset@latinfont\footnotesize
+ \hsize\columnwidth
+ \@parboxrestore
+ \protected@edef\@currentlabel
+ {\csname p@mpfootnote\endcsname\@thefnmark}%
+ \color@begingroup
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+ \color@endgroup}}
+\long\def\@mpfootnotetext#1{%
+ \if@autofootnoterule\ifnum\c@mpfootnote=\@ne\if@RTL@footnote\global\let\simurgh@mpfootnoterule\right@footnoterule\else\global\let\simurgh@mpfootnoterule\left@footnoterule\fi\fi\fi%
+ \global\setbox\@mpfootins\vbox{%
+ \if@RTL@footnote%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \reset@parsifont%
+ \else%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \reset@latinfont%
+ \fi%
+ \unvbox\@mpfootins
+ \footnotesize
+ \hsize\columnwidth
+ \@parboxrestore
+ \protected@edef\@currentlabel
+ {\csname p@mpfootnote\endcsname\@thefnmark}%
+ \color@begingroup
+ \@makefntext{%
+ \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+ \color@endgroup}}
+
+\def\@iiiminipage#1#2[#3]#4{%
+ \leavevmode
+ \@pboxswfalse
+ \setlength\@tempdima{#4}%
+ \def\@mpargs{{#1}{#2}[#3]{#4}}%
+ \setbox\@tempboxa\vbox\bgroup
+ \color@begingroup
+ \hsize\@tempdima
+ \textwidth\hsize \columnwidth\hsize
+ \@parboxrestore
+ \def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@
+ \let\@footnotetext\@mpfootnotetext
+ \let\@LTRfootnotetext\@mpLTRfootnotetext
+ \let\@RTLfootnotetext\@mpRTLfootnotetext
+ \let\@listdepth\@mplistdepth \@mplistdepth\z@
+ \@minipagerestore
+ \@setminipage}
+
+\def\endminipage{%
+ \par
+ \unskip
+ \ifvoid\@mpfootins\else
+ \vskip\skip\@mpfootins
+ \normalcolor
+ \simurgh@mpfootnoterule
+ \unvbox\@mpfootins
+ \fi
+ \@minipagefalse %% added 24 May 89
+ \color@endgroup
+ \egroup
+ \expandafter\@iiiparbox\@mpargs{\unvbox\@tempboxa}}
+
+
+\def\LTRthanks#1{\footnotemark
+ \protected@xdef\@thanks{\@thanks
+ \protect\LTRfootnotetext[\the\c@footnote]{#1}}%
+}
+\def\LTRfootnotetext{%
+ \@ifnextchar [\@xLTRfootnotenext
+ {\protected@xdef\@thefnmark{\thempfn}%
+ \@LTRfootnotetext}}
+\def\@xLTRfootnotenext[#1]{%
+ \begingroup
+ \csname c@\@mpfn\endcsname #1\relax
+ \unrestored@protected@xdef\@thefnmark{\thempfn}%
+ \endgroup
+ \@LTRfootnotetext}
+\def\RTLthanks#1{\footnotemark
+ \protected@xdef\@thanks{\@thanks
+ \protect\RTLfootnotetext[\the\c@footnote]{#1}}%
+}
+\let\@thanks\@empty
+\def\RTLfootnotetext{%
+ \@ifnextchar [\@xRTLfootnotenext
+ {\protected@xdef\@thefnmark{\thempfn}%
+ \@RTLfootnotetext}}
+\def\@xRTLfootnotenext[#1]{%
+ \begingroup
+ \csname c@\@mpfn\endcsname #1\relax
+ \unrestored@protected@xdef\@thefnmark{\thempfn}%
+ \endgroup
+ \@RTLfootnotetext}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-ftnxtra.sty b/macros/luatex/latex/simurgh/tex/simurgh-ftnxtra.sty
new file mode 100644
index 0000000000..3fb4106b01
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-ftnxtra.sty
@@ -0,0 +1,189 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-ftnxtra}[2013/09/18 v0.01a extend the applicability of footnotes]
+\newtoks\simurgh@p@ftn
+\let\FN@sf@@footnote\footnote
+\let\FN@sf@@LTRfootnote\LTRfootnote
+\let\FN@sf@@RTLfootnote\RTLfootnote
+\def\footnote{\ifx\protect\@typeset@protect
+ \expandafter\FN@sf@@footnote
+ \else
+ \expandafter\FN@sf@gobble@opt
+ \fi
+}
+\def\LTRfootnote{\ifx\protect\@typeset@protect
+ \expandafter\FN@sf@@LTRfootnote
+ \else
+ \expandafter\FN@sf@gobble@opt
+ \fi
+}
+\def\RTLfootnote{\ifx\protect\@typeset@protect
+ \expandafter\FN@sf@@RTLfootnote
+ \else
+ \expandafter\FN@sf@gobble@opt
+ \fi
+}
+\edef\FN@sf@gobble@opt{\noexpand\protect
+ \expandafter\noexpand\csname FN@sf@gobble@opt \endcsname}
+\expandafter\def\csname FN@sf@gobble@opt \endcsname{%
+ \@ifnextchar[%]
+ \FN@sf@gobble@twobracket
+ \@gobble
+}
+\def\FN@sf@gobble@twobracket[#1]#2{}
+\let\FN@sf@@footnotemark\footnotemark
+\def\footnotemark{\ifx\protect\@typeset@protect
+ \expandafter\FN@sf@@footnotemark
+ \else
+ \expandafter\FN@sf@gobble@optonly
+ \fi
+}
+\edef\FN@sf@gobble@optonly{\noexpand\protect
+ \expandafter\noexpand\csname FN@sf@gobble@optonly \endcsname}
+\expandafter\def\csname FN@sf@gobble@optonly \endcsname{%
+ \@ifnextchar[%]
+ \FN@sf@gobble@bracket
+ {}%
+}
+\def\FN@sf@gobble@bracket[#1]{}
+\def\@tabular{\if@RTL\@RTLtabtrue\fi
+ \leavevmode \hbox \bgroup
+ \let\@footnotetext\simurgh@p@ftntext
+ \let\@LTRfootnotetext\simurgh@p@LTRftntext
+ \let\@RTLfootnotetext\simurgh@p@RTLftntext
+ \let\@xfootnotenext\simurgh@p@xftntext
+ \let\@xfootnote\simurgh@p@xfootnote
+ \let\@xLTRfootnotenext\simurgh@p@xLTRftntext
+ \let\@xLTRfootnote\simurgh@p@xLTRfootnote
+ \let\@xRTLfootnotenext\simurgh@p@xRTLftntext
+ \let\@xRTLfootnote\simurgh@p@xRTLfootnote
+ $\let\@acol\@tabacol
+ \let\@classz\@tabclassz
+ \let\@classiv\@tabclassiv \let\\\@tabularcr\@tabarray}
+\def\endtabular{\crcr\egroup
+ \egroup $\egroup
+ \ifx\@captype\@undefined
+ \global\simurgh@p@ftn\expandafter{\expandafter}\the\simurgh@p@ftn\fi%
+ \@RTLtabfalse}
+\long\def\simurgh@p@ftntext#1{%
+ \edef\@tempy{\the\simurgh@p@ftn\noexpand\footnotetext[\the\csname c@\@mpfn\endcsname]}%
+ \global\simurgh@p@ftn\expandafter{\@tempy{#1}}}%
+\long\def\simurgh@p@LTRftntext#1{%
+ \edef\@tempyi{\the\simurgh@p@ftn\noexpand\LTRfootnotetext[\the\csname c@\@mpfn\endcsname]}%
+ \global\simurgh@p@ftn\expandafter{\@tempyi{#1}}}%
+\long\def\simurgh@p@RTLftntext#1{%
+ \edef\@tempyii{\the\simurgh@p@ftn\noexpand\RTLfootnotetext[\the\csname c@\@mpfn\endcsname]}%
+ \global\simurgh@p@ftn\expandafter{\@tempyii{#1}}}%
+
+\long\def\simurgh@p@xftntext[#1]#2{%
+ \global\simurgh@p@ftn\expandafter{\the\simurgh@p@ftn\footnotetext[#1]{#2}}}
+
+\long\def\simurgh@p@xLTRftntext[#1]#2{%
+ \global\simurgh@p@ftn\expandafter{\the\simurgh@p@ftn\LTRfootnotetext[#1]{#2}}}
+
+\long\def\simurgh@p@xRTLftntext[#1]#2{%
+ \global\simurgh@p@ftn\expandafter{\the\simurgh@p@ftn\RTLfootnotetext[#1]{#2}}}
+
+\def\simurgh@p@xfootnote[#1]{%
+ \begingroup
+ \csname c@\@mpfn\endcsname #1\relax
+ \unrestored@protected@xdef\@thefnmark{\thempfn}%
+ \endgroup
+ \@footnotemark\simurgh@p@xftntext[#1]}
+
+\def\simurgh@p@xLTRfootnote[#1]{%
+ \begingroup
+ \csname c@\@mpfn\endcsname #1\relax
+ \unrestored@protected@xdef\@thefnmark{\thempfn}%
+ \endgroup
+ \@footnotemark\simurgh@p@xLTRftntext[#1]}
+
+\def\simurgh@p@xRTLfootnote[#1]{%
+ \begingroup
+ \csname c@\@mpfn\endcsname #1\relax
+ \unrestored@protected@xdef\@thefnmark{\thempfn}%
+ \endgroup
+ \@footnotemark\simurgh@p@xRTLftntext[#1]}
+
+\def\@xfloat #1[#2]{%
+ \@nodocument
+ \def \@captype {#1}%
+ \def \@fps {#2}%
+ \@onelevel@sanitize \@fps
+ \def \reserved@b {!}%
+ \ifx \reserved@b \@fps
+ \@fpsadddefault
+ \else
+ \ifx \@fps \@empty
+ \@fpsadddefault
+ \fi
+ \fi
+ \ifhmode
+ \@bsphack
+ \@floatpenalty -\@Mii
+ \else
+ \@floatpenalty-\@Miii
+ \fi
+ \ifinner
+ \@parmoderr\@floatpenalty\z@
+ \else
+ \@next\@currbox\@freelist
+ {%
+ \@tempcnta \sixt@@n
+ \expandafter \@tfor \expandafter \reserved@a
+ \expandafter :\expandafter =\@fps
+ \do
+ {%
+ \if \reserved@a h%
+ \ifodd \@tempcnta
+ \else
+ \advance \@tempcnta \@ne
+ \fi
+ \fi
+ \if \reserved@a t%
+ \@setfpsbit \tw@
+ \fi
+ \if \reserved@a b%
+ \@setfpsbit 4%
+ \fi
+ \if \reserved@a p%
+ \@setfpsbit 8%
+ \fi
+ \if \reserved@a !%
+ \ifnum \@tempcnta>15
+ \advance\@tempcnta -\sixt@@n\relax
+ \fi
+ \fi
+ }%
+ \@tempcntb \csname ftype@\@captype \endcsname
+ \multiply \@tempcntb \@xxxii
+ \advance \@tempcnta \@tempcntb
+ \global \count\@currbox \@tempcnta
+ }%
+ \@fltovf
+ \fi
+ \global \setbox\@currbox
+ \color@vbox
+ \normalcolor
+ \vbox \bgroup
+ \let\@footnotetext\simurgh@p@ftntext
+ \let\@LTRfootnotetext\simurgh@p@LTRftntext
+ \let\@RTLfootnotetext\simurgh@p@RTLftntext
+ \let\@xfootnotenext\simurgh@p@xftntext
+ \let\@xfootnote\simurgh@p@xfootnote
+ \let\@xLTRfootnotenext\simurgh@p@xLTRftntext
+ \let\@xLTRfootnote\simurgh@p@xLTRfootnote
+ \let\@xRTLfootnotenext\simurgh@p@xRTLftntext
+ \let\@xRTLfootnote\simurgh@p@xRTLfootnote
+ \hsize\columnwidth
+ \@parboxrestore
+ \@floatboxreset
+}
+\def \@endfloatbox{%
+ \par\vskip\z@skip %% \par\vskip\z@ added 15 Dec 87
+ \@minipagefalse
+ \outer@nobreak
+ \egroup %% end of vbox
+ \global\simurgh@p@ftn\expandafter{\expandafter}\the\simurgh@p@ftn
+ \color@endbox
+}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-glossaries.sty b/macros/luatex/latex/simurgh/tex/simurgh-glossaries.sty
new file mode 100644
index 0000000000..c89144998f
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-glossaries.sty
@@ -0,0 +1,79 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-glossaries}[2013/09/18 v0.01a changes to `glossaries.sty']
+\newcommand*{\gls@harfipage}{\@harfi\c@page}
+\newcommand*{\gls@tartibipage}{\@tartibi\c@page}
+\newcommand*{\gls@adadipage}{\@adadi\c@page}
+\renewcommand{\gls@protected@pagefmts}{%
+ \gls@numberpage,\gls@alphpage,\gls@Alphpage,\gls@romanpage,\gls@Romanpage,\gls@harfipage,\gls@tartibipage,\gls@adadipage%
+}
+\renewcommand*{\@@do@wrglossary}[1]{%
+ \begingroup
+ \let\orgthe\the
+ \let\orgnumber\number
+ \let\orgromannumeral\romannumeral
+ \let\orgalph\@alph
+ \let\orgAlph\@Alph
+ \let\orgRoman\@Roman
+ \let\orgharfi\@harfi
+ \let\orgadadi\@adadi
+ \let\orgtartibi\@tartibi
+ \def\the##1{%
+ \ifx##1\c@page \gls@numberpage\else\orgthe##1\fi}%
+ \def\number##1{%
+ \ifx##1\c@page \gls@numberpage\else\orgnumber##1\fi}%
+ \def\romannumeral##1{%
+ \ifx##1\c@page \gls@romanpage\else\orgromannumeral##1\fi}%
+ \def\@Roman##1{%
+ \ifx##1\c@page \gls@Romanpage\else\orgRoman##1\fi}%
+ \def\@alph##1{%
+ \ifx##1\c@page \gls@alphpage\else\orgalph##1\fi}%
+ \def\@Alph##1{%
+ \ifx##1\c@page \gls@Alphpage\else\orgAlph##1\fi}%
+ \def\@harfi##1{%
+ \ifx##1\c@page \gls@harfipage\else\orgharfi##1\fi}%
+ \def\@adadi##1{%
+ \ifx##1\c@page \gls@adadipage\else\orgadadi##1\fi}%
+ \def\@tartibi##1{%
+ \ifx##1\c@page \gls@tartibipage\else\orgtartibi##1\fi}%
+ \gls@disablepagerefexpansion
+ \protected@xdef\@glslocref{\theglsentrycounter}%
+ \endgroup
+ \@gls@checkmkidxchars\@glslocref
+ \expandafter\ifx\theHglsentrycounter\theglsentrycounter
+ \def\@glo@counterprefix{}%
+ \else
+ \protected@edef\@glsHlocref{\theHglsentrycounter}%
+ \@gls@checkmkidxchars\@glsHlocref
+ \edef\@do@gls@getcounterprefix{\noexpand\@gls@getcounterprefix
+ {\@glslocref}{\@glsHlocref}%
+ }%
+ \@do@gls@getcounterprefix
+ \fi
+ \ifglsxindy
+ \expandafter\@glo@check@mkidxrangechar\@glsnumberformat\@nil
+ \def\@glo@range{}%
+ \expandafter\if\@glo@prefix(\relax
+ \def\@glo@range{:open-range}%
+ \else
+ \expandafter\if\@glo@prefix)\relax
+ \def\@glo@range{:close-range}%
+ \fi
+ \fi
+ \glossary[\csname glo@#1@type\endcsname]{%
+ (indexentry :tkey (\csname glo@#1@index\endcsname)
+ :locref \string"{\@glo@counterprefix}{\@glslocref}\string" %
+ :attr \string"\@gls@counter\@glo@suffix\string"
+ \@glo@range
+ )
+ }%
+ \else
+ \@set@glo@numformat{\@glo@numfmt}{\@gls@counter}{\@glsnumberformat}%
+ {\@glo@counterprefix}%
+ \glossary[\csname glo@#1@type\endcsname]{%
+ \string\glossaryentry{\csname glo@#1@index\endcsname
+ \@gls@encapchar\@glo@numfmt}{\@glslocref}}%
+ \fi
+}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-harfi.sty b/macros/luatex/latex/simurgh/tex/simurgh-harfi.sty
new file mode 100644
index 0000000000..13b041eb57
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-harfi.sty
@@ -0,0 +1,10 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-harfi}[2013/09/18 v0.01a harfi counter]
+
+\def\@harfi#1{\ifcase#1\or Ø¢â€\or ب\or Ù¾\or ت\or Ø«\or
+ج\or چ\or ح\or خ\or د\or ذ\or ر\or ز\or ژ\or س\or ش\or ص\or ض\or ط\or ظ\or ع\or غ\or
+Ù\or Ù‚\or Ú©\or Ú¯\or Ù„\or Ù…\or Ù†\or Ùˆ\or Ù‡\or ÛŒ\else\@ctrerr\fi}
+\def\harfi#1{\expandafter\@harfi\csname c@#1\endcsname}
+\let\harfinumeral\@harfi
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-jalalical.sty b/macros/luatex/latex/simurgh/tex/simurgh-jalalical.sty
new file mode 100644
index 0000000000..ee0bbb5c42
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-jalalical.sty
@@ -0,0 +1,176 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-jalalical}[2013/09/18 v0.01a jalali calendar]
+% jalali calendar needs to be done entirely in lua
+\newif\ifsimurgh@leap \newif\ifsimurgh@kabiseh
+\newcount\simurgh@i \newcount\simurgh@year \newcount\simurgh@month \newcount\simurgh@day
+\newcount\simurgh@latini \newcount\simurgh@jalalii
+\newcount\simurgh@latinii \newcount\simurgh@jalaliii
+\newcount\simurgh@latiniii \newcount\simurgh@jalaliiii
+\newcount\simurgh@latiniv \newcount\simurgh@jalaliiv
+\newcount\simurgh@latinv \newcount\simurgh@jalaliv
+\newcount\simurgh@latinvi \newcount\simurgh@jalalivi
+\newcount\simurgh@latinvii \newcount\simurgh@jalalivii
+\newcount\simurgh@latinviii \newcount\simurgh@jalaliviii
+\newcount\simurgh@latinix \newcount\simurgh@jalaliix
+\newcount\simurgh@latinx \newcount\simurgh@jalalix
+\newcount\simurgh@latinxi \newcount\simurgh@jalalixi
+\newcount\simurgh@latinxii \newcount\simurgh@jalalixii
+ \newcount\simurgh@jalalixiii
+
+\newcount\simurgh@temp
+\newcount\simurgh@temptwo
+\newcount\simurgh@tempthree
+\newcount\simurgh@yearModHundred
+\newcount\simurgh@thirtytwo
+\newcount\simurgh@dayn
+\newcount\simurgh@sn
+\newcount\simurgh@monthminusone
+
+\simurgh@year=\year \simurgh@month=\month \simurgh@day=\day
+\simurgh@temp=\simurgh@year
+\divide\simurgh@temp by 100\relax
+\multiply\simurgh@temp by 100\relax
+\simurgh@yearModHundred=\simurgh@year
+\advance\simurgh@yearModHundred by -\simurgh@temp\relax
+\ifodd\simurgh@yearModHundred
+ \simurgh@leapfalse
+\else
+ \simurgh@temp=\simurgh@yearModHundred
+ \divide\simurgh@temp by 2\relax
+ \ifodd\simurgh@temp\simurgh@leapfalse
+ \else
+ \ifnum\simurgh@yearModHundred=0%
+ \simurgh@temp=\simurgh@year
+ \divide\simurgh@temp by 400\relax
+ \multiply\simurgh@temp by 400\relax
+ \ifnum\simurgh@year=\simurgh@temp\simurgh@leaptrue\else\simurgh@leapfalse\fi
+ \else\simurgh@leaptrue
+ \fi
+ \fi
+\fi
+\simurgh@latini=31\relax
+\ifsimurgh@leap
+ \simurgh@latinii = 29\relax
+\else
+ \simurgh@latinii = 28\relax
+\fi
+\simurgh@latiniii = 31\relax
+\simurgh@latiniv = 30\relax
+\simurgh@latinv = 31\relax
+\simurgh@latinvi = 30\relax
+\simurgh@latinvii = 31\relax
+\simurgh@latinviii = 31\relax
+\simurgh@latinix = 30\relax
+\simurgh@latinx = 31\relax
+\simurgh@latinxi = 30\relax
+\simurgh@latinxii = 31\relax
+\simurgh@thirtytwo=32\relax
+\simurgh@temp=\simurgh@year
+\advance\simurgh@temp by -17\relax
+\simurgh@temptwo=\simurgh@temp
+\divide\simurgh@temptwo by 33\relax
+\multiply\simurgh@temptwo by 33\relax
+\advance\simurgh@temp by -\simurgh@temptwo
+\ifnum\simurgh@temp=\simurgh@thirtytwo\simurgh@kabisehfalse
+\else
+ \simurgh@temptwo=\simurgh@temp
+ \divide\simurgh@temptwo by 4\relax
+ \multiply\simurgh@temptwo by 4\relax
+ \advance\simurgh@temp by -\simurgh@temptwo
+ \ifnum\simurgh@temp=\z@\simurgh@kabisehtrue\else\simurgh@kabisehfalse\fi
+\fi
+\simurgh@tempthree=\simurgh@year % Number of Leap years
+\advance\simurgh@tempthree by -1
+\simurgh@temp=\simurgh@tempthree % T := (MY-1) div 4
+\divide\simurgh@temp by 4\relax
+\simurgh@temptwo=\simurgh@tempthree % T := T - ((MY-1) div 100)
+\divide\simurgh@temptwo by 100\relax
+\advance\simurgh@temp by -\simurgh@temptwo
+\simurgh@temptwo=\simurgh@tempthree % T := T + ((MY-1) div 400)
+\divide\simurgh@temptwo by 400\relax
+\advance\simurgh@temp by \simurgh@temptwo
+\advance\simurgh@tempthree by -611 % Number of Kabise years
+\simurgh@temptwo=\simurgh@tempthree % T := T - ((SY+10) div 33) * 8
+\divide\simurgh@temptwo by 33\relax
+\multiply\simurgh@temptwo by 8\relax
+\advance\simurgh@temp by -\simurgh@temptwo
+\simurgh@temptwo=\simurgh@tempthree %
+\divide\simurgh@temptwo by 33\relax
+\multiply\simurgh@temptwo by 33\relax
+\advance\simurgh@tempthree by -\simurgh@temptwo
+\ifnum\simurgh@tempthree=32\advance\simurgh@temp by 1\fi % if (SY+10) mod 33=32 then Inc(T);
+\divide\simurgh@tempthree by 4\relax % T := T - ((SY+10) mod 33) div 4
+\advance\simurgh@temp by -\simurgh@tempthree
+\advance\simurgh@temp by -137 % T := T - 137 Adjust the value
+\simurgh@jalalii=31
+\advance\simurgh@jalalii by -\simurgh@temp % now 31 - T is the jalalii
+\simurgh@jalaliii = 30\relax
+\ifsimurgh@kabiseh
+ \simurgh@jalaliiii = 30\relax
+\else
+ \simurgh@jalaliiii = 29\relax
+\fi
+\simurgh@jalaliiv = 31\relax
+\simurgh@jalaliv = 31\relax
+\simurgh@jalalivi = 31\relax
+\simurgh@jalalivii = 31\relax
+\simurgh@jalaliviii= 31\relax
+\simurgh@jalaliix = 31\relax
+\simurgh@jalalix = 30\relax
+\simurgh@jalalixi = 30\relax
+\simurgh@jalalixii = 30\relax
+\simurgh@jalalixiii= 30\relax
+\simurgh@dayn= 0\relax
+\simurgh@sn= 0\relax
+\simurgh@monthminusone=\simurgh@month
+\advance\simurgh@monthminusone by -1\relax
+\simurgh@i=0\relax
+\ifnum\simurgh@i < \simurgh@monthminusone
+\loop
+\advance \simurgh@i by 1\relax
+\advance\simurgh@dayn by \csname simurgh@latin\romannumeral\the\simurgh@i\endcsname
+\ifnum\simurgh@i<\simurgh@monthminusone \repeat
+\fi
+\advance \simurgh@dayn by \simurgh@day
+\simurgh@i=1\relax
+\simurgh@sn = \simurgh@jalalii
+\ifnum \simurgh@sn<\simurgh@dayn
+\loop
+\advance \simurgh@i by 1\relax
+\advance\simurgh@sn by \csname simurgh@jalali\romannumeral\the\simurgh@i\endcsname
+\ifnum \simurgh@sn<\simurgh@dayn \repeat
+\fi
+\ifnum \simurgh@i < 4
+ \simurgh@month = 9 \advance\simurgh@month by \simurgh@i
+ \advance \simurgh@year by -622\relax
+\else
+ \simurgh@month = \simurgh@i \advance \simurgh@month by -3\relax
+ \advance \simurgh@year by -621\relax
+\fi
+\advance\simurgh@sn by -\csname simurgh@jalali\romannumeral\the\simurgh@i%
+\endcsname
+\ifnum\simurgh@i = 1
+ \simurgh@day = \simurgh@dayn \advance \simurgh@day by 30 \advance\simurgh@day by -\simurgh@jalalii
+\else
+ \simurgh@day = \simurgh@dayn \advance \simurgh@day by -\simurgh@sn
+\fi
+\newcommand*{\jalalitoday}{%
+\number\simurgh@day\space%
+\simurgh@jalali@month{\simurgh@month}\space\number\simurgh@year%
+}
+\let\jalaliyear\simurgh@year
+\let\jalalimonth\simurgh@month
+\let\jalaliday\simurgh@day
+\def\simurgh@jalali@month#1{\ifcase#1\or Ùروردین\or
+اردیبهشت\or
+خرداد\or تیر\or
+مرداد\or
+شهریور\or مهر\or
+آبان\or آذر\or
+دی\or بهمن\or
+اسÙند\fi}
+
+\let\simurgh@ltx@today\today
+\def\gregoriantoday{\ensurelatintext{\simurgh@ltx@today}}
+\def\today{\ensureparsitext{\jalalitoday}}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-leqno.sty b/macros/luatex/latex/simurgh/tex/simurgh-leqno.sty
new file mode 100644
index 0000000000..d29f8823f1
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-leqno.sty
@@ -0,0 +1,13 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-leqno}[2013/09/22 v0.01a leqno]
+\renewcommand\@eqnnum{\hb@xt@.01\p@{}%
+ \if@RTL
+ \llapR{\normalfont\normalcolor
+ (\theequation)\hskip -\displaywidth}
+ \else
+ \rlapL{\normalfont\normalcolor
+ \hskip -\displaywidth(\theequation)}
+ \fi}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-letter.sty b/macros/luatex/latex/simurgh/tex/simurgh-letter.sty
new file mode 100644
index 0000000000..3ecbb5b088
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-letter.sty
@@ -0,0 +1,30 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-letter}[2013/09/22 v0.01a changes to `letter.cls']
+\renewcommand*{\opening}[1]{\ifx\@empty\fromaddress
+ \thispagestyle{firstpage}%
+ {\simurgh@raggedleft\@date\par}%
+ \else % home address
+ \thispagestyle{empty}%
+ {\simurgh@raggedleft\if@RTL\begin{tabular}{r@{}}\else\begin{tabular}{l@{}}\fi\ignorespaces
+ \fromaddress \\*[2\parskip]%
+ \@date \end{tabular}\par}%
+ \fi
+ \vspace{2\parskip}%
+ {\simurgh@raggedright \toname \\ \toaddress \par}%
+ \vspace{2\parskip}%
+ #1\par\nobreak}
+\renewcommand\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-\p@
+ \hrule \@width .4\columnwidth
+ \kern .6\p@}\hfil}}
+\renewcommand\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-\p@
+ \hrule \@width .4\columnwidth
+ \kern .6\p@}\hfil}}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-lettrine.sty b/macros/luatex/latex/simurgh/tex/simurgh-lettrine.sty
new file mode 100644
index 0000000000..379ff6ff61
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-lettrine.sty
@@ -0,0 +1,96 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-lettrine}[2013/09/18 v0.01a changes to `lettrine.sty']
+\def\@lettrine[#1]#2#3{%
+ \setcounter{L@lines}{\theDefaultLines}%
+ \renewcommand*{\L@hang}{\DefaultLhang}%
+ \renewcommand*{\L@oversize}{\DefaultLoversize}%
+ \renewcommand*{\L@raise}{\DefaultLraise}%
+ \renewcommand*{\L@ante}{}%
+ \setlength{\L@Findent}{\DefaultFindent}%
+ \setlength{\L@Nindent}{\DefaultNindent}%
+ \setlength{\L@slope}{\DefaultSlope}%
+ \ifLettrineImage\L@imagetrue\else\L@imagefalse\fi
+ \if\DefaultOptionsFile\relax
+ \else
+ \begingroup
+ \InputIfFileExists{\DefaultOptionsFile}%
+ {}%
+ {\PackageWarning{lettrine.sty}%
+ {File \DefaultOptionsFile\space not found}%
+ }%
+ \def\color##1##{\l@color{##1}}%
+ \let\l@color\@gobbletwo
+ \def\textcolor##1##{\l@textcolor{##1}}%
+ \def\l@textcolor##1##2##3{##3}%
+ \expandafter\ifx\csname l@#2-keys\endcsname\relax
+ \gdef\l@LOKeys{}%
+ \else
+ \xdef\l@LOKeys{\csname l@#2-keys\endcsname}%
+ \fi
+ \endgroup
+ \def\KV@prefix{KV@L@}%
+ \let\@tempc\relax
+ \expandafter\KV@do\l@LOKeys,\relax,
+ \sbox{\L@lbox}{\LettrineFont #2}%
+ \settowidth{\LettrineWidth}{\usebox{\L@lbox}}%
+ \def\KV@prefix{KV@L@}%
+ \let\@tempc\relax
+ \expandafter\KV@do\l@LOKeys,\relax,
+ \fi
+ \setkeys{L}{#1}%
+ \ifL@image
+ \sbox{\L@lbox}{\LettrineFontEPS{#2}}%
+ \else
+ \sbox{\L@lbox}{\LettrineFont #2}%
+ \fi
+ \sbox{\L@tbox}{\LettrineTextFont{#3}}%
+ \@tempdima=\baselineskip
+ \ifnum\theL@lines=1
+ \setlength{\L@first}{\ht\L@lbox}%
+ \addtolength{\L@first}{-\ht\L@tbox}%
+ \setlength{\L@lraise}{\z@}%
+ \else
+ \setlength{\L@first}{-\theL@lines\@tempdima}%
+ \addtolength{\L@first}{\@tempdima}%
+ \sbox{\@tempboxa}{\LettrineTextFont x}%
+ \addtolength{\L@first}{-\ht\@tempboxa}%
+ \setlength{\L@lraise}{-\L@raise\L@first}%
+ \addtolength{\L@first}{\L@lraise}%
+ \addtolength{\L@first}{\ht\L@lbox}%
+ \addtolength{\L@lraise}{-\theL@lines\@tempdima}%
+ \addtolength{\L@lraise}{\@tempdima}%
+ \fi
+ \par
+ \ifdim\L@first>0.2\p@\vskip\L@first\fi
+ \setlength{\L@Pindent}{\wd\L@lbox}%
+ \addtolength{\L@Pindent}{-\L@hang\wd\L@lbox}%
+ \settowidth{\L@first}{\L@ante}%
+ \addtolength{\L@Pindent}{\L@first}%
+ \addtolength{\L@Pindent}{\L@Findent}%
+ \setlength{\L@first}{\linewidth}%
+ \addtolength{\L@first}{-\L@Pindent}%
+ \addtolength{\L@Nindent}{\L@Pindent}%
+ \setlength{\L@next}{\linewidth}%
+ \addtolength{\L@next}{-\L@Nindent}%
+ \addtolength{\L@Pindent}{\rightmargin}%
+ \addtolength{\L@Nindent}{\rightmargin}%
+ \addtocounter{L@lines}{1}%
+ \if@RTL\def\L@parshape{\c@L@lines \the\L@Pindent \the\L@first}%
+ \else\def\L@parshape{\c@L@lines \z@ \the\L@first}\fi%
+ \@tempcnta=\tw@
+ \@whilenum \@tempcnta<\c@L@lines\do{%
+ \if@RTL\edef\L@parshape{\L@parshape \the\L@Nindent \the\L@next}%
+ \else\edef\L@parshape{\L@parshape \z@ \the\L@next}\fi%
+ \addtolength{\L@Nindent}{\L@slope}%
+ \addtolength{\L@next}{-\L@slope}%
+ \advance\@tempcnta\@ne}%
+ \if@RTL\edef\L@parshape{\L@parshape \rightmargin \the\linewidth}%
+ \else\edef\L@parshape{\L@parshape \z@ \the\linewidth}\fi%
+ \noindent
+ \parshape=\L@parshape\relax
+ \smash{\llap{\mbox{\L@ante}\raisebox{\L@lraise}{\usebox{\L@lbox}}%
+ \hskip \the\L@Findent}}%
+ \usebox{\L@tbox}}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-loader.sty b/macros/luatex/latex/simurgh/tex/simurgh-loader.sty
new file mode 100644
index 0000000000..6395833e43
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-loader.sty
@@ -0,0 +1,12 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-loader}[2013/09/18 v0.01a loading simurgh last]
+\newcommand\simurgh@isloaded[2][]{
+ \expandafter\ifx\csname if@simurgh@#2loaded@\endcsname\relax
+ \expandafter\newif\csname if@simurgh@#2loaded@\endcsname
+ \fi
+ \@ifpackageloaded{#2}
+ {\csname @simurgh@#2loaded@true\endcsname #1}
+ {\csname @simurgh@#2loaded@false\endcsname}}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-ltx.sty b/macros/luatex/latex/simurgh/tex/simurgh-ltx.sty
new file mode 100644
index 0000000000..d4be533583
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-ltx.sty
@@ -0,0 +1,668 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-ltx}[2013/09/18 v0.01a changes to `latex.ltx']
+\newif\if@RTLtab
+\newif\if@RTLmarginpar
+\newif\if@LTRmarginpar
+\newif\if@LTRbibitems
+\newif\if@RTLbibitems
+
+\def\SepMark#1{\gdef\@SepMark{\if@RTLâ€\fi#1\if@RTLâ€\fi}}
+\SepMark{.}
+\def\CaptionLabelSep#1{\gdef\@CaptionLabelSep{\if@RTLâ€\fi#1\if@RTLâ€\fi}}
+\CaptionLabelSep{:}
+
+\def\setRTLbibitems{\@RTLbibitemstrue\@LTRbibitemsfalse}
+\def\setLTRbibitems{\@LTRbibitemstrue\@RTLbibitemsfalse}
+\def\setdefaultbibitems{\@RTLbibitemsfalse\@LTRbibitemsfalse}
+
+\def\setRTLmarginpar{\@RTLmarginpartrue\@LTRmarginparfalse}
+\def\setLTRmarginpar{\@LTRmarginpartrue\@RTLmarginparfalse}
+\def\setdefaultmarginpar{\@RTLmarginparfalse\@LTRmarginparfalse}
+
+\let\simurgh@TeX\TeX
+\def\TeX{\ensurelatintext{\simurgh@TeX}}
+\let\simurgh@LaTeX\LaTeX
+\def\LaTeX{\ensurelatintext{\simurgh@LaTeX}}
+\let\simurgh@LaTeXe\LaTeXe
+\def\LaTeXe{\ensurelatintext{\simurgh@LaTeXe}}
+
+\def\RTLcases#1{\left\}\vcenter{\normalbaselines\m@th
+ \ialign{$##\hfil$&\quad{##}\hfil\crcr#1\crcr}}\,\right\.}
+
+\def\@thmcountersep{\@SepMark}
+
+\def\@mklab#1{\hfil \if@RTL\hboxR\else\hboxL\fi{#1}}
+
+\def\list#1#2{%
+ \ifnum \@listdepth >5\relax
+ \@toodeep
+ \else
+ \global\advance\@listdepth\@ne
+ \fi
+ \rightmargin\z@
+ \listparindent\z@
+ \itemindent\z@
+ \csname @list\romannumeral\the\@listdepth\endcsname
+ \def\@itemlabel{#1}%
+ \let\makelabel\@mklab
+ \@nmbrlistfalse
+ #2\relax
+ \@trivlist
+ \parskip\parsep
+ \parindent\listparindent
+ \advance\linewidth -\rightmargin
+ \advance\linewidth -\leftmargin
+ \if@RTL%
+ \advance\@totalleftmargin \leftmargin%
+ \else%
+ \advance\@totalleftmargin \rightmargin%
+ \fi%
+ \parshape \@ne \@totalleftmargin \linewidth
+ \ignorespaces}
+
+
+
+\def\@item[#1]{%
+ \if@noparitem
+ \@donoparitem
+ \else
+ \if@inlabel
+ \indent \par
+ \fi
+ \ifhmode
+ \unskip\unskip \par
+ \fi
+ \if@newlist
+ \if@nobreak
+ \@nbitem
+ \else
+ \addpenalty\@beginparpenalty
+ \addvspace\@topsep
+ \addvspace{-\parskip}%
+ \fi
+ \else
+ \addpenalty\@itempenalty
+ \addvspace\itemsep
+ \fi
+ \global\@inlabeltrue
+ \fi
+ \everypar{%
+ \@minipagefalse
+ \global\@newlistfalse
+ \if@inlabel
+ \global\@inlabelfalse
+ {\setbox\z@\lastbox
+ \ifvoid\z@
+ \kern-\itemindent
+ \fi}%
+ \box\@labels
+ \penalty\z@
+ \fi
+ \if@nobreak
+ \@nobreakfalse
+ \clubpenalty \@M
+ \else
+ \clubpenalty \@clubpenalty
+ \everypar{}%
+ \fi}%
+ \if@noitemarg
+ \@noitemargfalse
+ \if@nmbrlist
+ \refstepcounter\@listctr
+ \fi
+ \fi
+ \ensuresboxdir\@tempboxa{\makelabel{#1}}%
+ \if@RTL%
+ \global\setbox\@labels\hbox dir TRT{%
+ \unhbox\@labels
+ \hskip \itemindent
+ \hskip -\labelwidth
+ \hskip -\labelsep
+ \ifdim \wd\@tempboxa >\labelwidth
+ \box\@tempboxa
+ \else
+ \hbox to\labelwidth {\unhbox\@tempboxa}%
+ \fi
+ \hskip \labelsep}%
+ \else%
+ \global\setbox\@labels\hbox dir TLT{%
+ \unhbox\@labels
+ \hskip \itemindent
+ \hskip -\labelwidth
+ \hskip -\labelsep
+ \ifdim \wd\@tempboxa >\labelwidth
+ \box\@tempboxa
+ \else
+ \hbox to\labelwidth {\unhbox\@tempboxa}%
+ \fi
+ \hskip \labelsep}%
+ \fi%
+ \ignorespaces}
+
+
+\long\def\@iiiparbox#1#2[#3]#4#5{%
+ \leavevmode
+ \@pboxswfalse
+ \setlength\@tempdima{#4}%
+ \@begin@tempboxa\vbox{\hsize\@tempdima\@parboxrestore#5\@@par}%
+ \ifx\relax#2\else
+ \setlength\@tempdimb{#2}%
+ \edef\@parboxto{to\the\@tempdimb}%
+ \fi
+ \if#1b\vbox
+ \else\if #1t\vtop
+ \else\ifmmode\vcenter
+ \else\@pboxswtrue \if@RTL\mathdir TRT\fi$\vcenter
+ \fi\fi\fi
+ \@parboxto{\let\hss\vss\let\unhbox\unvbox
+ \csname bm@#3\endcsname}%
+ \if@pboxsw \m@th$\fi
+ \@end@tempboxa}
+
+\newenvironment{LTRitems}
+ {\par\@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \parshape \@ne \dimexpr(\@totalleftmargin-\leftmargin) \linewidth%
+ \ignorespaces}{\vskip\z@}
+
+\newenvironment{RTLitems}
+ {\par\@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \parshape \@ne \dimexpr(\@totalleftmargin+\leftmargin) \linewidth%
+ \ignorespaces}{\vskip\z@}
+
+
+\newenvironment{latinitems}{\begin{LTRitems}\reset@latinfont}{\end{LTRitems}}
+\newenvironment{parsiitems}{\begin{RTLitems}\reset@parsifont}{\end{RTLitems}}
+
+\let\simurgh@raggedleft\raggedleft
+\let\simurgh@raggedright\raggedright
+\def\raggedleft{%
+ \if@RTL%
+ \simurgh@raggedright%
+ \else%
+ \simurgh@raggedleft%
+ \fi}
+\def\raggedright{%
+ \if@RTL%
+ \simurgh@raggedleft%
+ \else%
+ \simurgh@raggedright%
+ \fi}
+
+
+\def\leftline#1{%
+ \if@RTL%
+ \@@line{\hss#1}%
+ \else%
+ \ifvmode%
+ \@@line{\hss#1}%
+ \else%
+ \@@line{#1\hss}%
+ \fi%
+\fi%
+}
+
+\def\rightline#1{%
+ \if@RTL%
+ \@@line{#1\hss}%
+ \else%
+ \ifvmode%
+ \@@line{#1\hss}%
+ \else%
+ \@@line{\hss#1}%
+ \fi%
+\fi%
+}
+
+% here we redefine \rlap and \llap so that right means `at the end of line' and left means `at the beggining of the line'
+% independent of the mode (RTL or LTR) we are in. this way, we make sure that specific macros that has to deal with
+% `at the beginning of the line' or `at the end of the line' still works correctly and there is no need to modify them.
+\def\rlapR#1{\hbox to \z@{\textdir TRT #1\hss}}
+\def\rlapL#1{\hbox dir TLT to \z@{\textdir TLT #1\hss}}
+\def\llapR#1{\hbox to \z@{\hss \textdir TRT #1}}
+\def\llapL#1{\hbox dir TLT to \z@{\hss \textdir TLT #1}}
+\def\llap#1{\if@RTL\llapR{#1}\else\llapL{#1}\fi}
+\def\rlap#1{\if@RTL\rlapR{#1}\else\rlapL{#1}\fi}
+
+% logical \llap and \rlap macros
+
+\def\simurghllap#1{\if@RTL\rlapR{#1}\else\llapL{#1}\fi}
+\def\simurghrlap#1{\if@RTL\llapR{#1}\else\rlapL{#1}\fi}
+
+
+\def\@hangfrom#1{\setbox\@tempboxa\hbox{{#1}}%
+ \hangindent%
+ \if@RTL%
+ \else%
+ -%
+ \fi%
+ \wd\@tempboxa\noindent\box\@tempboxa}
+
+\def\bm@l{\if@RTL\hss\unhbox\@tempboxa\else\unhbox\@tempboxa\hss\fi}
+\def\bm@r{\if@RTL\unhbox\@tempboxa\hss\else\hss\unhbox\@tempboxa\fi}
+\def\bm@t{\unhbox\@tempboxa\hss}
+\def\bm@b{\hss\unhbox\@tempboxa}
+
+
+\def\LTRmarginpar{%
+ \ifhmode
+ \@bsphack
+ \@floatpenalty -\@Mii
+ \else
+ \@floatpenalty-\@Miii
+ \fi
+ \ifinner
+ \@parmoderr
+ \@floatpenalty\z@
+ \else
+ \@next\@currbox\@freelist{}{}%
+ \@next\@marbox\@freelist{\global\count\@marbox\m@ne}%
+ {\@floatpenalty\z@
+ \@fltovf\def\@currbox{\@tempboxa}\def\@marbox{\@tempboxa}}%
+ \fi
+ \@ifnextchar [\@LTRxmpar\@LTRympar}
+\long\def\@LTRxmpar[#1]#2{%
+ \@LTRsavemarbox\@marbox{#1}%
+ \@LTRsavemarbox\@currbox{#2}%
+ \@xympar}
+\long\def\@LTRympar#1{%
+ \@LTRsavemarbox\@marbox{#1}%
+ \global\setbox\@currbox\copy\@marbox
+ \@xympar}
+\long\def \@LTRsavemarbox #1#2{%
+ \global\setbox #1%
+ \color@vbox
+ \vtop dir TLT{%
+ \@RTLfalse%
+ \hsize\marginparwidth
+ \@parboxrestore
+ \@LTRmarginparreset
+ #2%
+ \@minipagefalse
+ \outer@nobreak
+ }%
+ \color@endbox
+}
+
+\def \@LTRmarginparreset {%
+ \reset@latinfont
+ \normalsize
+ \@setminipage
+}
+
+\def\RTLmarginpar{%
+ \ifhmode
+ \@bsphack
+ \@floatpenalty -\@Mii
+ \else
+ \@floatpenalty-\@Miii
+ \fi
+ \ifinner
+ \@parmoderr
+ \@floatpenalty\z@
+ \else
+ \@next\@currbox\@freelist{}{}%
+ \@next\@marbox\@freelist{\global\count\@marbox\m@ne}%
+ {\@floatpenalty\z@
+ \@fltovf\def\@currbox{\@tempboxa}\def\@marbox{\@tempboxa}}%
+ \fi
+ \@ifnextchar [\@RTLxmpar\@RTLympar}
+\long\def\@RTLxmpar[#1]#2{%
+ \@RTLsavemarbox\@marbox{#1}%
+ \@RTLsavemarbox\@currbox{#2}%
+ \@xympar}
+\long\def\@RTLympar#1{%
+ \@RTLsavemarbox\@marbox{#1}%
+ \global\setbox\@currbox\copy\@marbox
+ \@xympar}
+\long\def \@RTLsavemarbox #1#2{%
+ \global\setbox #1%
+ \color@vbox
+ \vtop dir TRT{%
+ \@RTLtrue%
+ \hsize\marginparwidth
+ \@parboxrestore
+ \@RTLmarginparreset
+ #2%
+ \@minipagefalse
+ \outer@nobreak
+ }%
+ \color@endbox
+}
+
+\def \@RTLmarginparreset {%
+ \reset@parsifont
+ \normalsize
+ \@setminipage
+}
+
+\def \@marginparreset {%
+ \if@Latin%
+ \reset@latinfont%
+ \else%
+ \reset@parsifont%
+ \fi%
+ \reset@font
+ \normalsize
+ \@setminipage
+}
+
+
+\def\hb@xt@addmarginpar@{%
+ \if@RTL%
+ \if@LTRmarginpar%
+ \hbox dir TLT to%
+ \else%
+ \hbox dir TRT to%
+ \fi%
+ \else%
+ \if@RTLmarginpar%
+ \hbox dir TRT to%
+ \else%
+ \hbox dir TLT to%
+ \fi%
+ \fi}
+
+\def\vtop@addmarginpar{%
+ \if@RTL%
+ \if@LTRmarginpar%
+ \vtop dir TLT%
+ \else%
+ \vtop dir TRT%
+ \fi%
+ \else%
+ \if@RTLmarginpar%
+ \vtop dir TRT%
+ \else%
+ \vtop dir TLT%
+ \fi%
+ \fi}
+
+
+\def\@addmarginpar{\@next\@marbox\@currlist{\@cons\@freelist\@marbox
+ \@cons\@freelist\@currbox}\@latexbug\@tempcnta\@ne
+ \if@twocolumn
+ \if@firstcolumn \@tempcnta\m@ne \fi
+ \else
+ \if@mparswitch
+ \ifodd\c@page \else\@tempcnta\m@ne \fi
+ \fi
+ \if@reversemargin \@tempcnta -\@tempcnta \fi
+ \fi
+ \ifnum\@tempcnta <\z@ \global\setbox\@marbox\box\@currbox \fi
+ \@tempdima\@mparbottom
+ \advance\@tempdima -\@pageht
+ \advance\@tempdima\ht\@marbox
+ \ifdim\@tempdima >\z@
+ \@latex@warning@no@line {Marginpar on page \thepage\space moved}%
+ \else
+ \@tempdima\z@
+ \fi
+ \global\@mparbottom\@pageht
+ \global\advance\@mparbottom\@tempdima
+ \global\advance\@mparbottom\dp\@marbox
+ \global\advance\@mparbottom\marginparpush
+ \advance\@tempdima -\ht\@marbox
+ \global\setbox \@marbox
+ \vbox {\vskip \@tempdima
+ \box \@marbox}%
+ \global \ht\@marbox \z@
+ \global \dp\@marbox \z@
+ \kern -\@pagedp
+ \nointerlineskip
+ \hb@xt@addmarginpar@\columnwidth
+ {\ifnum \@tempcnta >\z@
+ \hskip\columnwidth \hskip\marginparsep
+ \else
+ \hskip -\marginparsep \hskip -\marginparwidth
+ \fi
+ \box\@marbox \hss}%
+ \nointerlineskip
+ \hbox{\vrule \@height\z@ \@width\z@ \@depth\@pagedp}}
+
+\long\def \@savemarbox #1#2{%
+ \global\setbox #1%
+ \color@vbox
+ \vtop@addmarginpar{%
+ \hsize\marginparwidth
+ \@parboxrestore
+ \@marginparreset
+ #2%
+ \@minipagefalse
+ \outer@nobreak
+ }%
+ \color@endbox
+}
+
+\gdef\@stopline{%
+ \unskip
+ \@stopfield
+ \if@rjfield
+ \global\@rjfieldfalse
+ \@tempdima\@totalleftmargin
+ \advance\@tempdima\linewidth
+ \hb@xt@\@tempdima{%
+ \@itemfudge\hskip\dimen\@curtabmar
+ \box\@curline
+ \hfil
+ \box\@curfield}%
+ \else
+ \@addfield
+ \hb@xt@\linewidth{\@itemfudge\hskip\dimen\@curtabmar\box\@curline\hfil}%
+ \fi}
+
+
+\def\LTR@outputdblcol{%
+ \if@firstcolumn
+ \global \@firstcolumnfalse
+ \global \setbox\@leftcolumn \box\@outputbox
+ \else
+ \global \@firstcolumntrue
+ \setbox\@outputbox \vbox dir TLT {%
+ \hb@xt@\textwidth {%
+ \hb@xt@\columnwidth {%
+ \box\@leftcolumn \hss}%
+ \hfil
+ {\normalcolor\vrule \@width\columnseprule}%
+ \hfil
+ \hb@xt@\columnwidth {%
+ \box\@outputbox \hss}%
+ }%
+ }%
+ \@combinedblfloats
+ \@outputpage
+ \begingroup
+ \@dblfloatplacement
+ \@startdblcolumn
+ \@whilesw\if@fcolmade \fi
+ {\@outputpage
+ \@startdblcolumn}%
+ \endgroup
+ \fi
+}
+
+\def\RTL@outputdblcol{%
+ \if@firstcolumn
+ \global \@firstcolumnfalse
+ \global \setbox\@leftcolumn \box\@outputbox
+ \else
+ \global \@firstcolumntrue
+ \setbox\@outputbox \vbox dir TRT {%
+ \hb@xt@\textwidth {%
+ \hb@xt@\columnwidth {%
+ \box\@leftcolumn \hss}%
+ \hfil
+ {\normalcolor\vrule \@width\columnseprule}%
+ \hfil
+ \hb@xt@\columnwidth {%
+ \box\@outputbox \hss}%
+ }%
+ }%
+ \@combinedblfloats
+ \@outputpage
+ \begingroup
+ \@dblfloatplacement
+ \@startdblcolumn
+ \@whilesw\if@fcolmade \fi
+ {\@outputpage
+ \@startdblcolumn}%
+ \endgroup
+ \fi
+}
+
+
+
+\newcommand*{\RTLdblcol}{\renewcommand*{\@outputdblcol}{\RTL@outputdblcol}}
+\newcommand*{\LTRdblcol}{\renewcommand*{\@outputdblcol}{\LTR@outputdblcol}}
+
+\def\@outputpage{%
+\begingroup % the \endgroup is put in by \aftergroup
+ \let \protect \noexpand
+ \@resetactivechars
+ \global\let\@@if@newlist\if@newlist
+ \global\@newlistfalse
+ \@parboxrestore
+ \shipout \vbox{%
+ \set@typeset@protect
+ \aftergroup \endgroup
+ \aftergroup \set@typeset@protect
+ % correct? or just restore by ending
+ % the group?
+ \if@specialpage
+ \global\@specialpagefalse\@nameuse{ps@\@specialstyle}%
+ \fi
+ \if@twoside
+ \ifodd\count\z@ \let\@thehead\@oddhead \let\@thefoot\@oddfoot
+ \let\@themargin\oddsidemargin
+ \else \let\@thehead\@evenhead
+ \let\@thefoot\@evenfoot \let\@themargin\evensidemargin
+ \fi
+ \fi
+ \if@RTLmain%
+ \reset@parsifont%
+ \else%
+ \reset@latinfont%
+ \fi%
+ \normalsize
+ \normalsfcodes
+ \let\label\@gobble
+ \let\index\@gobble
+ \let\glossary\@gobble
+ \baselineskip\z@skip \lineskip\z@skip \lineskiplimit\z@
+ \@begindvi
+ \vskip \topmargin
+ \moveright\@themargin \vbox {%
+ \setbox\@tempboxa \vbox to\headheight{%
+ \vfil
+ \color@hbox
+ \normalcolor
+ \hb@xt@\textwidth{\@thehead}%
+ \color@endbox
+ }% %% 22 Feb 87
+ \dp\@tempboxa \z@
+ \box\@tempboxa
+ \vskip \headsep
+ \box\@outputbox
+ \baselineskip \footskip
+ \color@hbox
+ \normalcolor
+ \hb@xt@\textwidth{\@thefoot}%
+ \color@endbox
+ }%
+ }%
+ \global\let\if@newlist\@@if@newlist
+ \global \@colht \textheight
+ \stepcounter{page}%
+ \let\firstmark\botmark
+}
+
+\global\@RTLtabfalse
+\def\@tabular{\if@RTL\@RTLtabtrue\fi%
+ \leavevmode \hbox \bgroup $\let\@acol\@tabacol
+ \let\@classz\@tabclassz
+ \let\@classiv\@tabclassiv \let\\\@tabularcr\@tabarray}
+\def\endtabular{\crcr\egroup\egroup $\egroup\@RTLtabfalse}
+\expandafter \let \csname endtabular*\endcsname = \endtabular
+\def\@array[#1]#2{%
+ \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi
+ \bgroup
+ \setbox\@arstrutbox\hbox{%
+ \vrule \@height\arraystretch\ht\strutbox
+ \@depth\arraystretch \dp\strutbox
+ \@width\z@}%
+ \@mkpream{#2}%
+ \edef\@preamble{%
+ \ialign \noexpand\@halignto
+ \bgroup \@arstrut \@preamble \tabskip\z@skip \cr}%
+ \let\@startpbox\@@startpbox \let\@endpbox\@@endpbox
+ \let\tabularnewline\\%
+ \let\par\@empty
+ \let\@sharp##%
+ \set@typeset@protect
+ \lineskip\z@skip\baselineskip\z@skip
+ \ifhmode \@preamerr\z@ \@@par\fi
+ \if@RTLtab\textdir TRT\fi%
+ \@preamble}
+\def\array{\let\@acol\@arrayacol \let\@classz\@arrayclassz
+ \let\@classiv\@arrayclassiv
+ \let\\\@arraycr\let\@halignto\@empty\@RTLtabfalse\@tabarray}
+\def\@testpach#1{\@chclass \ifnum \@lastchclass=\tw@ 4 \else
+ \ifnum \@lastchclass=3 5 \else
+ \z@ \if #1c\@chnum \z@ \else
+ \if \if@RTLtab#1r\else#1l\fi\@chnum \@ne \else
+ \if \if@RTLtab#1l\else#1r\fi\@chnum \tw@ \else
+ \@chclass \if #1|\@ne \else
+ \if #1@\tw@ \else
+ \if #1p3 \else \z@ \@preamerr 0\fi
+ \fi \fi \fi \fi \fi \fi
+\fi}
+
+
+\DeclareRobustCommand\Latincite{%
+ \@ifnextchar [{\@tempswatrue\@Latincitex}{\@tempswafalse\@Latincitex[]}}
+\def\@Latincitex[#1]#2{\leavevmode
+ \let\@citea\@empty
+ \@cite{\textLatin{\@for\@citeb:=#2\do
+ {\@citea\def\@citea{,\penalty\@m\ }%
+ \edef\@citeb{\expandafter\@firstofone\@citeb\@empty}%
+ \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi
+ \@ifundefined{b@\@citeb}{\hbox{\reset@font\bfseries ?}%
+ \G@refundefinedtrue
+ \@latex@warning
+ {Citation `\@citeb' on page \thepage \space undefined}}%
+ {\@cite@ofmt{\csname b@\@citeb\endcsname}}}}}{#1}}
+
+
+
+
+
+\RequirePackage{simurgh-footnotes}
+\if@twocolumn
+ \let\autofootnoterule\relax
+ \let\leftfootnoterule\relax
+ \let\rightfootnoterule\relax
+ \textwidthfootnoterule
+\fi
+
+
+% math macros
+\everydisplay\expandafter{\the\everydisplay\predisplaydirection\z@}
+\@ifpackageloaded{amsmath}{}{%
+\def\endequation{\eqno \if@RTL\hboxR\else\hboxL\fi{\@eqnnum}$$\@ignoretrue}}
+\def\@@eqncr{\let\reserved@a\relax
+ \ifcase\@eqcnt \def\reserved@a{& & &}\or \def\reserved@a{& &}%
+ \or \def\reserved@a{&}\else
+ \let\reserved@a\@empty
+ \@latex@error{Too many columns in eqnarray environment}\@ehc\fi
+ \reserved@a \if@eqnsw\if@RTL\hboxR\else\hboxL\fi{\@eqnnum}\stepcounter{equation}\fi
+ \global\@eqnswtrue\global\@eqcnt\z@\cr}
+
+
+
+\simurgh@newrobustcmd*{\parsirq}{«}
+\simurgh@newrobustcmd*{\parsilq}{»}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-mathdigitspec.sty b/macros/luatex/latex/simurgh/tex/simurgh-mathdigitspec.sty
new file mode 100644
index 0000000000..f63cd6230f
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-mathdigitspec.sty
@@ -0,0 +1,206 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-mathdigitspec}[2013/09/18 v0.01a unicode parsi math digits]
+\def\new@mathgroup{\alloc@8\mathgroup\chardef\@cclvi}
+\let\newfam\new@mathgroup
+\def\select@group#1#2#3#4{%
+ \ifx\math@bgroup\bgroup\else\relax\expandafter\@firstofone\fi
+ {%
+ \ifmmode
+ \ifnum\csname c@mv@\math@version\endcsname<\@cclvi
+ \begingroup
+ \escapechar\m@ne
+ \getanddefine@fonts{\csname c@mv@\math@version\endcsname}#3%
+ \globaldefs\@ne \math@fonts
+ \endgroup
+ \init@restore@version
+ \xdef#1{\noexpand\use@mathgroup\noexpand#2%
+ {\number\csname c@mv@\math@version\endcsname}}%
+ \global\advance\csname c@mv@\math@version\endcsname\@ne
+ \else
+ \let#1\relax
+ \@latex@error{Too many math alphabets used in
+ version \math@version}%
+ \@eha
+ \fi
+ \else \expandafter\non@alpherr\fi
+ #1{#4}%
+ }%
+}
+\def\document@select@group#1#2#3#4{%
+ \ifx\math@bgroup\bgroup\else\relax\expandafter\@firstofone\fi
+ {%
+ \ifmmode
+ \ifnum\csname c@mv@\math@version\endcsname<\@cclvi
+ \begingroup
+ \escapechar\m@ne
+ \getanddefine@fonts{\csname c@mv@\math@version\endcsname}#3%
+ \globaldefs\@ne \math@fonts
+ \endgroup
+ \expandafter\extract@alph@from@version
+ \csname mv@\math@version\expandafter\endcsname
+ \expandafter{\number\csname
+ c@mv@\math@version\endcsname}%
+ #1%
+ \global\advance\csname c@mv@\math@version\endcsname\@ne
+ \else
+ \let#1\relax
+ \@latex@error{Too many math alphabets used
+ in version \math@version}%
+ \@eha
+ \fi
+ \else \expandafter\non@alpherr\fi
+ #1{#4}%
+ }%
+}
+\ExplSyntaxOn
+\bool_set_false:N \g_fontspec_math_bool
+\ExplSyntaxOff
+\def\@preamblecmds{}
+\newcommand\simurgh@not@onlypreamble[1]{{%
+ \def\do##1{\ifx#1##1\else\noexpand\do\noexpand##1\fi}%
+ \xdef\@preamblecmds{\@preamblecmds}}}
+\simurgh@not@onlypreamble\@preamblecmds
+\def\simurgh@notprerr{ can be used only in preamble (\on@line)}
+\AtBeginDocument{%
+ \def\do#1{\noexpand\do\noexpand#1}%
+ \edef\@preamblecmds{%
+ \def\noexpand\do##1{%
+ \def##1{\noexpand\simurgh@NotprerrMessage##1}\noexpand\@eha}}%
+ \@preamblecmds}
+\def\simurgh@NotprerrMessage#1{%
+ \simurgh@error%
+ {\noexpand\string#1 \noexpand\simurgh@notprerr}{}%
+}
+\def\nocite#1{%
+ \@bsphack{\setbox0=\hbox{\cite{#1}}}\@esphack}
+\newcommand\SetMathCode[4]{%
+ \Umathcode#1="\mathchar@type#2 \csname sym#3\endcsname #4\relax}
+\newcommand\SetMathCharDef[4]{%
+ \Umathchardef#1="\mathchar@type#2 \csname sym#3\endcsname #4\relax}
+\ExplSyntaxOn
+\cs_new_eq:NN \orig_mathbf:n \mathbf
+\cs_new_eq:NN \orig_mathit:n \mathit
+\cs_new_eq:NN \orig_mathrm:n \mathrm
+\cs_new_eq:NN \orig_mathsf:n \mathsf
+\cs_new_eq:NN \orig_mathtt:n \mathtt
+\NewDocumentCommand \new@mathbf { m } {
+ \orig_mathbf:n {
+ \int_step_inline:nnnn { `0 } { \c_one } { `9 } {
+ \mathcode ##1 = \numexpr "100 * \symnew@mathbf@font@digits + ##1 \relax
+ }
+ #1
+ }
+}
+\NewDocumentCommand \new@mathit { m } {
+ \orig_mathit:n {
+ \int_step_inline:nnnn { `0 } { \c_one } { `9 } {
+ \mathcode ##1 = \numexpr "100 * \symnew@mathit@font@digits + ##1 \relax
+ }
+ #1
+ }
+}
+\NewDocumentCommand \new@mathrm { m } {
+ \orig_mathrm:n {
+ \int_step_inline:nnnn { `0 } { \c_one } { `9 } {
+ \mathcode ##1 = \numexpr "100 * \symnew@mathrm@font@digits + ##1 \relax
+ }
+ #1
+ }
+}
+\NewDocumentCommand \new@mathsf{ m } {
+ \orig_mathsf:n {
+ \int_step_inline:nnnn { `0 } { \c_one } { `9 } {
+ \mathcode ##1 = \numexpr "100 * \symnew@mathsf@font@digits + ##1 \relax
+ }
+ #1
+ }
+}
+\NewDocumentCommand \new@mathtt{ m } {
+ \orig_mathtt:n {
+ \int_step_inline:nnnn { `0 } { \c_one } { `9 } {
+ \mathcode ##1 = \numexpr "100 * \symnew@mathtt@font@digits + ##1 \relax
+ }
+ #1
+ }
+}
+\newcommand\setmathparsidigitfont[2][]{%
+ \let\glb@currsize\relax
+ \fontspec_set_family:Nnn \simurgh@digits@family {#1}{#2}
+ \simurgh@info{defining the default parsi math digits font as '#2'}
+ \DeclareSymbolFont{OPERATORS} {EU2}{\simurgh@digits@family} {m}{n}
+ \DeclareSymbolFont{new@mathbf@font@digits}{EU2}{\simurgh@digits@family}{bx}{n}
+ \DeclareSymbolFont{new@mathit@font@digits}{EU2}{\simurgh@digits@family}{m}{it}
+ \DeclareSymbolFont{new@mathrm@font@digits}{EU2}{\simurgh@digits@family}{m}{n}
+ \def\parsimathdigits{%
+ \SetMathCode{`0}{\mathalpha}{OPERATORS}{`Û°}
+ \SetMathCode{`1}{\mathalpha}{OPERATORS}{`Û±}
+ \SetMathCode{`2}{\mathalpha}{OPERATORS}{`Û²}
+ \SetMathCode{`3}{\mathalpha}{OPERATORS}{`Û³}
+ \SetMathCode{`4}{\mathalpha}{OPERATORS}{`Û´}
+ \SetMathCode{`5}{\mathalpha}{OPERATORS}{`Ûµ}
+ \SetMathCode{`6}{\mathalpha}{OPERATORS}{`Û¶}
+ \SetMathCode{`7}{\mathalpha}{OPERATORS}{`Û·}
+ \SetMathCode{`8}{\mathalpha}{OPERATORS}{`Û¸}
+ \SetMathCode{`9}{\mathalpha}{OPERATORS}{`Û¹}
+ \SetMathCharDef{\%}{\mathbin}{OPERATORS}{`Ùª}
+ \SetMathCharDef{\decimalseparator}{\mathpunct}{OPERATORS}{"066B}
+ \cs_set_eq:NN \mathbf \new@mathbf
+ \cs_set_eq:NN \mathit \new@mathit
+ \cs_set_eq:NN \mathrm \new@mathrm}
+}
+\DeclareDocumentCommand \setmathsfparsidigitfont { O{} m } {
+ \fontspec_set_family:Nnn \g_fontspec_mathsf_tl {#1}{#2}
+ \DeclareSymbolFont{new@mathsf@font@digits}{EU2}{\g_fontspec_mathsf_tl}{m}{n}
+ \def\parsimathsfdigits{\cs_set_eq:NN \mathsf \new@mathsf}
+}
+\DeclareDocumentCommand \setmathttparsidigitfont { O{} m } {
+ \fontspec_set_family:Nnn \g_fontspec_mathtt_tl {#1}{#2}
+ \DeclareSymbolFont{new@mathtt@font@digits}{EU2}{\g_fontspec_mathtt_tl}{m}{n}
+ \def\parsimathttdigits{\cs_set_eq:NN \mathtt \new@mathtt}
+}
+\ExplSyntaxOff
+\ifx\newcommand\undefined\else
+ \newcommand{\ZifferAn}{}
+\fi
+\mathchardef\ziffer@DotOri="013A
+{\ZifferAn
+ \catcode`\.=\active\gdef.{\begingroup\obeyspaces\futurelet\n\ziffer@dcheck}}
+\def\ziffer@dcheck{\ziffer@check\ZifferLeer\ziffer@DotOri}
+\def\ziffer@check#1#2{%
+ \ifx\n1\endgroup#1\else
+ \ifx\n2\endgroup#1\else
+ \ifx\n3\endgroup#1\else
+ \ifx\n4\endgroup#1\else
+ \ifx\n5\endgroup#1\else
+ \ifx\n6\endgroup#1\else
+ \ifx\n7\endgroup#1\else
+ \ifx\n8\endgroup#1\else
+ \ifx\n9\endgroup#1\else
+ \ifx\n0\endgroup#1\else
+ \endgroup#2%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi}
+\mathcode`.="8000\relax
+\def\ZifferLeer{\ifx\decimalseparator\undefied .\else \decimalseparator\fi}
+\def\DefaultMathDigits{\def\SetMathDigits{}}
+\def\ParsiMathDigits{\def\SetMathDigits{%
+\ifx\parsimathdigits\undefied\else\parsimathdigits\fi%
+\ifx\parsimathsfdigits\undefied\else\parsimathsfdigits\fi%
+\ifx\parsimathttdigits\undefied\else\parsimathttdigits\fi}}
+\def\AutoMathDigits{\def\SetMathDigits{%
+\ifx\parsimathdigits\undefied\else\if@Latin\else\parsimathdigits\fi\fi%
+\ifx\parsimathsfdigits\undefied\else\if@Latin\else\parsimathsfdigits\fi\fi%
+\ifx\parsimathttdigits\undefied\else\if@Latin\else\parsimathttdigits\fi\fi}}
+
+\everymath\expandafter{\the\everymath\SetMathDigits}
+\g@addto@macro\document{\everydisplay\expandafter{\the\everydisplay\SetMathDigits}}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-memoir.sty b/macros/luatex/latex/simurgh/tex/simurgh-memoir.sty
new file mode 100644
index 0000000000..514bcace58
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-memoir.sty
@@ -0,0 +1,48 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-memoir}[2013/09/22 v0.01a changes to `]
+\renewcommand*{\memRTLraggedright}{\simurgh@raggedright}
+\renewcommand*{\memRTLraggedleft}{\simurgh@raggedleft}
+\renewcommand*{\thesection}{\thechapter\@SepMark\@arabic\c@section}
+\renewcommand*{\thesubsection}{%
+ \thesection\@SepMark\@arabic\c@subsection}
+\renewcommand*{\thesubsubsection}{%
+ \thesubsection\@SepMark\@arabic\c@subsubsection}
+\renewcommand*{\theparagraph}{%
+ \thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand*{\thesubparagraph}{%
+ \theparagraph\@SepMark\@arabic\c@subparagraph}
+\renewcommand{\setthesection}{\thechapter\@SepMark\Alph{section}}
+\renewcommand{\theequation}{%
+ \ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@equation}
+\renewcommand{\thefigure}{\thechapter\@SepMark\@arabic\c@figure}
+\renewcommand{\thetable}{\thechapter\@SepMark\@arabic\c@table}
+
+\renewenvironment{thebibliography}[1]{%
+ \bibsection
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \begin{bibitemlist}{#1}}{\end{bibitemlist}\postbibhook}
+
+\renewcommand{\@memfront}{%
+ \@smemfront\pagenumbering{harfi}}
+\renewcommand{\setthesection}{\thechapter\@SepMark\harfi{section}}
+\renewcommand*{\thebook}{\@tartibi\c@book}
+\renewcommand*{\thepart}{\@tartibi\c@part}
+\renewcommand{\appendix}{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}%
+ \anappendixtrue}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-minitoc.sty b/macros/luatex/latex/simurgh/tex/simurgh-minitoc.sty
new file mode 100644
index 0000000000..8f40ffa6b2
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-minitoc.sty
@@ -0,0 +1,14 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-minitoc}[2013/09/18 v0.01a changes to `minitoc.sty']
+\def\ptctitle{\if@RTL Ùهرست مطالب\else Table of Contents\fi}%
+\def\plftitle{\if@RTL Ùهرست تصاویر\else List of Figures\fi}%
+\def\plttitle{\if@RTL Ùهرست جداول\else List of Tables\fi}%
+\def\mtctitle{\if@RTL عناوین\else Contents\fi}%
+\def\mlftitle{\if@RTL اشکال\else Figures\fi}%
+\def\mlttitle{\if@RTL جداول\else Tables\fi}%
+\def\stctitle{\if@RTL عناوین\else Contents\fi}%
+\def\slftitle{\if@RTL اشکال\else Figures\fi}%
+\def\slttitle{\if@RTL جداول\else Tables\fi}%
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-natbib.sty b/macros/luatex/latex/simurgh/tex/simurgh-natbib.sty
new file mode 100644
index 0000000000..92784a226d
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-natbib.sty
@@ -0,0 +1,258 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-natbib}[2013/09/18 v0.01a changes to `natbib.sty']
+\renewenvironment{thebibliography}[1]{%
+ \bibsection
+ \parindent\z@
+ \bibpreamble
+ \bibfont
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \simurgh@pardir TLT%
+ \simurgh@textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \simurgh@pardir TRT%
+ \simurgh@textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\the\c@NAT@ctr}}{\@bibsetup{#1}\global\c@NAT@ctr\z@}%
+ \ifNAT@openbib
+ \renewcommand\newblock{\par}%
+ \else
+ \renewcommand\newblock{\hskip .11em \@plus.33em \@minus.07em}%
+ \fi
+ \sloppy\clubpenalty4000\widowpenalty4000
+ \sfcode`\.\@m
+ \let\NAT@bibitem@first@sw\@firstoftwo
+ \let\citeN\cite \let\shortcite\cite
+ \let\citeasnoun\cite
+}{%
+ \bibitem@fin
+ \bibpostamble
+ \def\@noitemerr{%
+ \PackageWarning{natbib}{Empty `thebibliography' environment}%
+ }%
+ \endlist
+ \bibcleanup
+}%
+
+
+\renewcommand\NAT@set@cites{%
+ \ifNAT@numbers
+ \ifNAT@super \let\@cite\NAT@citesuper
+ \def\NAT@mbox##1{\unskip\nobreak\textsuperscript{##1}}%
+ \let\citeyearpar=\citeyear
+ \let\NAT@space\relax
+ \def\NAT@super@kern{\kern\p@}%
+ \else
+ \let\NAT@mbox=\mbox
+ \let\@cite\NAT@citenum
+ \let\NAT@space\NAT@spacechar
+ \let\NAT@super@kern\relax
+ \fi
+ \let\@citex\NAT@citexnum
+ \let\@Latincitex\NAT@Latin@citexnum
+ \let\@biblabel\NAT@biblabelnum
+ \let\@bibsetup\NAT@bibsetnum
+ \renewcommand\NAT@idxtxt{\NAT@name\NAT@spacechar\NAT@open\NAT@num\NAT@close}%
+ \def\natexlab##1{}%
+ \def\NAT@penalty{\penalty\@m}%
+ \else
+ \let\@cite\NAT@cite
+ \let\@citex\NAT@citex
+ \let\@Latincitex\NAT@Latin@citex
+ \let\@biblabel\NAT@biblabel
+ \let\@bibsetup\NAT@bibsetup
+ \let\NAT@space\NAT@spacechar
+ \let\NAT@penalty\@empty
+ \renewcommand\NAT@idxtxt{\NAT@name\NAT@spacechar\NAT@open\NAT@date\NAT@close}%
+ \def\natexlab##1{##1}%
+ \fi}
+\newcommand\NAT@Latin@citex{}
+\def\NAT@Latin@citex%
+ [#1][#2]#3{%
+ \NAT@reset@parser
+ \NAT@sort@cites{#3}%
+ \NAT@reset@citea
+ \@cite{\textLatin{\let\NAT@nm\@empty\let\NAT@year\@empty
+ \@for\@citeb:=\NAT@cite@list\do
+ {\@safe@activestrue
+ \edef\@citeb{\expandafter\@firstofone\@citeb\@empty}%
+ \@safe@activesfalse
+ \@ifundefined{b@\@citeb\@extra@b@citeb}{\@citea%
+ {\reset@font\bfseries ?}\NAT@citeundefined
+ \PackageWarning{natbib}%
+ {Citation `\@citeb' on page \thepage \space undefined}\def\NAT@date{}}%
+ {\let\NAT@last@nm=\NAT@nm\let\NAT@last@yr=\NAT@year
+ \NAT@parse{\@citeb}%
+ \ifNAT@longnames\@ifundefined{bv@\@citeb\@extra@b@citeb}{%
+ \let\NAT@name=\NAT@all@names
+ \global\@namedef{bv@\@citeb\@extra@b@citeb}{}}{}%
+ \fi
+ \ifNAT@full\let\NAT@nm\NAT@all@names\else
+ \let\NAT@nm\NAT@name\fi
+ \ifNAT@swa\ifcase\NAT@ctype
+ \if\relax\NAT@date\relax
+ \@citea\NAT@hyper@{\NAT@nmfmt{\NAT@nm}\NAT@date}%
+ \else
+ \ifx\NAT@last@nm\NAT@nm\NAT@yrsep
+ \ifx\NAT@last@yr\NAT@year
+ \def\NAT@temp{{?}}%
+ \ifx\NAT@temp\NAT@exlab\PackageWarningNoLine{natbib}%
+ {Multiple citation on page \thepage: same authors and
+ year\MessageBreak without distinguishing extra
+ letter,\MessageBreak appears as question mark}\fi
+ \NAT@hyper@{\NAT@exlab}%
+ \else\unskip\NAT@spacechar
+ \NAT@hyper@{\NAT@date}%
+ \fi
+ \else
+ \@citea\NAT@hyper@{%
+ \NAT@nmfmt{\NAT@nm}%
+ \hyper@natlinkbreak{%
+ \NAT@aysep\NAT@spacechar}{\@citeb\@extra@b@citeb
+ }%
+ \NAT@date
+ }%
+ \fi
+ \fi
+ \or\@citea\NAT@hyper@{\NAT@nmfmt{\NAT@nm}}%
+ \or\@citea\NAT@hyper@{\NAT@date}%
+ \or\@citea\NAT@hyper@{\NAT@alias}%
+ \fi \NAT@def@citea
+ \else
+ \ifcase\NAT@ctype
+ \if\relax\NAT@date\relax
+ \@citea\NAT@hyper@{\NAT@nmfmt{\NAT@nm}}%
+ \else
+ \ifx\NAT@last@nm\NAT@nm\NAT@yrsep
+ \ifx\NAT@last@yr\NAT@year
+ \def\NAT@temp{{?}}%
+ \ifx\NAT@temp\NAT@exlab\PackageWarningNoLine{natbib}%
+ {Multiple citation on page \thepage: same authors and
+ year\MessageBreak without distinguishing extra
+ letter,\MessageBreak appears as question mark}\fi
+ \NAT@hyper@{\NAT@exlab}%
+ \else
+ \unskip\NAT@spacechar
+ \NAT@hyper@{\NAT@date}%
+ \fi
+ \else
+ \@citea\NAT@hyper@{%
+ \NAT@nmfmt{\NAT@nm}%
+ \hyper@natlinkbreak{\NAT@spacechar\NAT@@open\if*#1*\else#1\NAT@spacechar\fi}%
+ {\@citeb\@extra@b@citeb}%
+ \NAT@date
+ }%
+ \fi
+ \fi
+ \or\@citea\NAT@hyper@{\NAT@nmfmt{\NAT@nm}}%
+ \or\@citea\NAT@hyper@{\NAT@date}%
+ \or\@citea\NAT@hyper@{\NAT@alias}%
+ \fi
+ \if\relax\NAT@date\relax
+ \NAT@def@citea
+ \else
+ \NAT@def@citea@close
+ \fi
+ \fi
+ }}\ifNAT@swa\else\if*#2*\else\NAT@cmt#2\fi
+ \if\relax\NAT@date\relax\else\NAT@@close\fi\fi}}{#1}{#2}}
+\newcommand\NAT@Latin@citexnum{}
+\def\NAT@Latin@citexnum[#1][#2]#3{%
+ \NAT@reset@parser
+ \NAT@sort@cites{#3}%
+ \NAT@reset@citea
+ \@cite{\textLatin{\def\NAT@num{-1}\let\NAT@last@yr\relax\let\NAT@nm\@empty
+ \@for\@citeb:=\NAT@cite@list\do
+ {\@safe@activestrue
+ \edef\@citeb{\expandafter\@firstofone\@citeb\@empty}%
+ \@safe@activesfalse
+ \@ifundefined{b@\@citeb\@extra@b@citeb}{%
+ {\reset@font\bfseries?}
+ \NAT@citeundefined\PackageWarning{natbib}%
+ {Citation `\@citeb' on page \thepage \space undefined}}%
+ {\let\NAT@last@num\NAT@num\let\NAT@last@nm\NAT@nm
+ \NAT@parse{\@citeb}%
+ \ifNAT@longnames\@ifundefined{bv@\@citeb\@extra@b@citeb}{%
+ \let\NAT@name=\NAT@all@names
+ \global\@namedef{bv@\@citeb\@extra@b@citeb}{}}{}%
+ \fi
+ \ifNAT@full\let\NAT@nm\NAT@all@names\else
+ \let\NAT@nm\NAT@name\fi
+ \ifNAT@swa
+ \@ifnum{\NAT@ctype>\@ne}{%
+ \@citea
+ \NAT@hyper@{\@ifnum{\NAT@ctype=\tw@}{\NAT@test{\NAT@ctype}}{\NAT@alias}}%
+ }{%
+ \@ifnum{\NAT@cmprs>\z@}{%
+ \NAT@ifcat@num\NAT@num
+ {\let\NAT@nm=\NAT@num}%
+ {\def\NAT@nm{-2}}%
+ \NAT@ifcat@num\NAT@last@num
+ {\@tempcnta=\NAT@last@num\relax}%
+ {\@tempcnta\m@ne}%
+ \@ifnum{\NAT@nm=\@tempcnta}{%
+ \@ifnum{\NAT@merge>\@ne}{}{\NAT@last@yr@mbox}%
+ }{%
+ \advance\@tempcnta by\@ne
+ \@ifnum{\NAT@nm=\@tempcnta}{%
+ \ifx\NAT@last@yr\relax
+ \def@NAT@last@yr{\@citea}%
+ \else
+ \def@NAT@last@yr{--\NAT@penalty}%
+ \fi
+ }{%
+ \NAT@last@yr@mbox
+ }%
+ }%
+ }{%
+ \@tempswatrue
+ \@ifnum{\NAT@merge>\@ne}{\@ifnum{\NAT@last@num=\NAT@num\relax}{\@tempswafalse}{}}{}%
+ \if@tempswa\NAT@citea@mbox\fi
+ }%
+ }%
+ \NAT@def@citea
+ \else
+ \ifcase\NAT@ctype
+ \ifx\NAT@last@nm\NAT@nm \NAT@yrsep\NAT@penalty\NAT@space\else
+ \@citea \NAT@test{\@ne}\NAT@spacechar\NAT@mbox{\NAT@super@kern\NAT@@open}%
+ \fi
+ \if*#1*\else#1\NAT@spacechar\fi
+ \NAT@mbox{\NAT@hyper@{{\citenumfont{\NAT@num}}}}%
+ \NAT@def@citea@box
+ \or
+ \NAT@hyper@citea@space{\NAT@test{\NAT@ctype}}%
+ \or
+ \NAT@hyper@citea@space{\NAT@test{\NAT@ctype}}%
+ \or
+ \NAT@hyper@citea@space\NAT@alias
+ \fi
+ \fi
+ }%
+ }%
+ \@ifnum{\NAT@cmprs>\z@}{\NAT@last@yr}{}%
+ \ifNAT@swa\else
+ \@ifnum{\NAT@ctype=\z@}{%
+ \if*#2*\else\NAT@cmt#2\fi
+ }{}%
+ \NAT@mbox{\NAT@@close}%
+ \fi
+ }}{#1}{#2}%
+}%
+\AtBeginDocument{\NAT@set@cites}
+\DeclareRobustCommand\Latincite
+ {\begingroup\let\NAT@ctype\z@\NAT@partrue\NAT@swatrue
+ \@ifstar{\NAT@fulltrue\NAT@Latin@cites}{\NAT@fullfalse\NAT@Latin@cites}}
+\newcommand\NAT@Latin@cites{\@ifnextchar [{\NAT@@Latin@@citetp}{%
+ \ifNAT@numbers\else
+ \NAT@swafalse
+ \fi
+ \NAT@@Latin@@citetp[]}}
+\newcommand\NAT@@Latin@@citetp{}
+\def\NAT@@Latin@@citetp[#1]{\@ifnextchar[{\@Latincitex[#1]}{\@Latincitex[][#1]}}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-pkgs.sty b/macros/luatex/latex/simurgh/tex/simurgh-pkgs.sty
new file mode 100644
index 0000000000..a23a60f33d
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-pkgs.sty
@@ -0,0 +1,17 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-pkgs}[2013/09/18 v0.01a changes to packages]
+\@ifpackageloaded{algorithm}{\RequirePackage{simurgh-algorithm}}{}
+\@ifpackageloaded{algorithmic}{\RequirePackage{simurgh-algorithmic}}{}
+\@ifpackageloaded{amsmath}{\RequirePackage{simurgh-amsmath}}{}
+\@ifpackageloaded{amstext}{\RequirePackage{simurgh-amstext}}{}
+\@ifpackageloaded{amsthm}{\RequirePackage{simurgh-amsthm}}{}
+\@ifpackageloaded{array}{\RequirePackage{simurgh-array}}{}
+\@ifpackageloaded{arydshln}{\RequirePackage{simurgh-arydshln}}{}
+\@ifpackageloaded{backref}{\RequirePackage{simurgh-backref}}{}
+\@ifpackageloaded{caption3}{\RequirePackage{simurgh-caption3}}{}
+\@ifpackageloaded{empheq}{\RequirePackage{simurgh-empheq}}{}
+\@ifpackageloaded{glossaries}{\RequirePackage{simurgh-glossaries}}{}
+\@ifpackageloaded{lettrine}{\RequirePackage{simurgh-lettrine}}{}
+\@ifpackageloaded{minitoc}{\RequirePackage{simurgh-minitoc}}{}
+\@ifpackageloaded{natbib}{\RequirePackage{simurgh-natbib}}{}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-poem.sty b/macros/luatex/latex/simurgh/tex/simurgh-poem.sty
new file mode 100644
index 0000000000..46545c119d
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-poem.sty
@@ -0,0 +1,271 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-poem}%
+[2013/09/18 v0.01a typesetting Persian traditional and modern poems]
+\def\poemcolsepskip{.1\versewidth plus .1\versewidth minus .05\versewidth}
+\def\poemmarginskip{1em plus 1fil minus 1em}
+\def\poemextrabaselineskip{0\baselineskip}
+\def\poemskip{\medskip}
+\newcommand{\simurghpoem@openbox}{\leavevmode
+ \hbox to.77778em{%
+ \hfil\vrule
+ \vbox to.675em{\hrule width.6em\vfil\hrule}%
+ \vrule\hfil}}
+\def\poemblocksep{\quad\hbox{\simurghpoem@openbox}}
+\newdimen\versewidth
+\newtoks\simurghpoem@p@ftn
+\def\poem@verse#1{%
+\ifdim\wd#1>\new@poem@width
+\xdef\new@poem@width{\the\wd#1}%
+\ifdim\new@poem@width>\poem@width
+\xdef\poem@width{\new@poem@width}%
+\global\let\poem@needrun\relax
+\fi
+\fi
+\hbox to\poem@width{\unhbox#1}%
+\global\simurghpoem@p@ftn\expandafter{\expandafter}\the\simurghpoem@p@ftn%
+}
+\def\poem@linebegin{\vadjust{}\hskip\@flushglue\hskip\poemmarginskip\relax}
+\def\poem@lineend{\nobreak\hskip\poemmarginskip\hskip\@flushglue\vadjust{}}
+\def\poem@lineversesep{%
+\nobreak
+\hskip\z@ plus 1filll%
+\penalty600%
+\hskip\poemcolsepskip
+\hskip\z@ plus -2filll%
+\vadjust{}%
+\nobreak
+\hskip\z@ plus 1filll%
+}
+\def\poem@lineparsebegin{%
+\halign\bgroup
+\global\setbox\verse@i=\hbox{%
+\let\@footnotetext\simurghpoem@p@ftntext%
+\let\@LTRfootnotetext\simurghpoem@p@LTRftntext%
+\let\@RTLfootnotetext\simurghpoem@p@RTLftntext%
+\let\@xfootnotenext\simurghpoem@p@xftntext%
+\let\@xfootnote\simurghpoem@p@xfootnote%
+\let\@xLTRfootnotenext\simurghpoem@p@xLTRftntext%
+\let\@xLTRfootnote\simurghpoem@p@xLTRfootnote%
+\let\@xRTLfootnotenext\simurghpoem@p@xRTLftntext%
+\let\@xRTLfootnote\simurghpoem@p@xRTLfootnote%
+\ignorespaces##\unskip}&&
+\global\setbox\verse@ii=\hbox{%
+\let\@footnotetext\simurghpoem@p@ftntext%
+\let\@LTRfootnotetext\simurghpoem@p@LTRftntext%
+\let\@RTLfootnotetext\simurghpoem@p@RTLftntext%
+\let\@xfootnotenext\simurghpoem@p@xftntext%
+\let\@xfootnote\simurghpoem@p@xfootnote%
+\let\@xLTRfootnotenext\simurghpoem@p@xLTRftntext%
+\let\@xLTRfootnote\simurghpoem@p@xLTRfootnote%
+\let\@xRTLfootnotenext\simurghpoem@p@xRTLftntext%
+\let\@xRTLfootnote\simurghpoem@p@xRTLfootnote%
+\ignorespaces##\unskip}
+\cr
+}
+\def\poem@lineparseend{%
+\crcr\egroup
+\vskip-\baselineskip
+}
+\def\oldpoem@cr{%
+ \cr\poem@line
+}
+\newbox\verse@i
+\newbox\verse@ii
+\newif\ifpoem@started
+
+\def\poem@line{%
+\poem@lineparseend
+\ifdim\wd\verse@i>\z@\global\poem@startedtrue\fi
+\ifdim\wd\verse@ii>\z@\global\poem@startedtrue\fi
+\ifpoem@started
+ \ifdim\wd\verse@ii>\z@\else
+ \nopagebreak[3]
+ \fi
+ \leavevmode
+ \poem@linebegin
+ \poem@verse\verse@i
+ \ifdim\wd\verse@ii>\z@
+ \poem@lineversesep
+ \poem@verse\verse@ii
+ \fi
+ \poem@lineend
+ \nopagebreak
+ \endgraf
+ \vskip\poemextrabaselineskip
+\fi
+\poem@lineparsebegin
+}
+\def\@traditionalpoem{%
+\stepcounter{poem@no}
+ \ifnum\max@poem@no<\number\c@poem@no%
+\xdef\poem@width{\z@}%
+ \else
+\xdef\poem@width{\poem@prop{poem@width}}%
+\fi
+\xdef\new@poem@width{\z@}%
+\global\versewidth=\poem@width
+\poemskip\leavevmode\par
+\begingroup
+\tabskip=\z@
+\parskip=\z@
+\parindent=\z@
+\parfillskip=\z@
+\rightskip=\z@
+\leftskip=\z@
+\widowpenalty=10000% No break between verses of the same line.
+\clubpenalty=10000% Same as above. Not really needed.
+\def\newblock{\hfil\poemblocksep\hfil\null}%
+\def\par{\oldpoem@cr}% Redefine \par for possible \obeylines
+\def\\{\global\poem@startedtrue\oldpoem@cr}%
+\global\poem@startedfalse
+\csname poem@obeylines\endcsname
+\let\poem@obeylines\relax
+\poem@lineparsebegin
+}
+\def\@endtraditionalpoem{%
+\cr
+\ifdim\wd\verse@i>\z@\poem@line\else\ifdim\wd\verse@ii>\z@\poem@line\else
+\noalign{%
+\skip0=\poemextrabaselineskip
+\vskip-\skip0
+\vskip-\baselineskip
+}%
+\fi\fi
+\poem@lineparseend
+\endgroup
+\par
+\vskip\baselineskip
+\poemskip
+\ifdim\new@poem@width<\poem@width
+\global\let\poem@needrun\relax
+\fi
+ \poem@write@aux{poem@width@\romannumeral\c@poem@no}{\new@poem@width}%
+\ifx\AtEndDocument\undefined\poem@finish\fi
+}
+
+\long\def\simurghpoem@p@ftntext#1{%
+ \edef\@tempx{\the\simurghpoem@p@ftn\noexpand\footnotetext[\the\csname c@\@mpfn\endcsname]}%
+ \global\simurghpoem@p@ftn\expandafter{\@tempx{#1}}}%
+\long\def\simurghpoem@p@LTRftntext#1{%
+ \edef\@tempxi{\the\simurghpoem@p@ftn\noexpand\LTRfootnotetext[\the\csname c@\@mpfn\endcsname]}%
+ \global\simurghpoem@p@ftn\expandafter{\@tempxi{#1}}}%
+\long\def\simurghpoem@p@RTLftntext#1{%
+ \edef\@tempxii{\the\simurghpoem@p@ftn\noexpand\RTLfootnotetext[\the\csname c@\@mpfn\endcsname]}%
+ \global\simurghpoem@p@ftn\expandafter{\@tempxii{#1}}}%
+
+\long\def\simurghpoem@p@xftntext[#1]#2{%
+ \global\simurghpoem@p@ftn\expandafter{\the\simurghpoem@p@ftn\footnotetext[#1]{#2}}}
+
+\long\def\simurghpoem@p@xLTRftntext[#1]#2{%
+ \global\simurghpoem@p@ftn\expandafter{\the\simurghpoem@p@ftn\LTRfootnotetext[#1]{#2}}}
+
+\long\def\simurghpoem@p@xRTLftntext[#1]#2{%
+ \global\simurghpoem@p@ftn\expandafter{\the\simurghpoem@p@ftn\RTLfootnotetext[#1]{#2}}}
+
+\def\simurghpoem@p@xfootnote[#1]{%
+ \begingroup
+ \csname c@\@mpfn\endcsname #1\relax
+ \unrestored@protected@xdef\@thefnmark{\thempfn}%
+ \endgroup
+ \@footnotemark\simurghpoem@p@xftntext[#1]}
+
+\def\simurghpoem@p@xLTRfootnote[#1]{%
+ \begingroup
+ \csname c@\@mpfn\endcsname #1\relax
+ \unrestored@protected@xdef\@thefnmark{\thempfn}%
+ \endgroup
+ \@footnotemark\simurghpoem@p@xLTRftntext[#1]}
+
+\def\simurghpoem@p@xRTLfootnote[#1]{%
+ \begingroup
+ \csname c@\@mpfn\endcsname #1\relax
+ \unrestored@protected@xdef\@thefnmark{\thempfn}%
+ \endgroup
+ \@footnotemark\simurghpoem@p@xRTLftntext[#1]}
+
+\newenvironment{traditionalpoem}{\@traditionalpoem}{\@endtraditionalpoem}
+\expandafter\def\csname traditionalpoem*\endcsname{\let\poem@obeylines=\obeylines\traditionalpoem}
+\expandafter\def\csname endtraditionalpoem*\endcsname{\endtraditionalpoem}
+\def\poem@finish{%
+\poem@write@aux{max@poem@no}{\number\c@poem@no}%
+\ifx\poem@needrun\relax
+\simurgh@warning{unjustified poem. rerun lualatex to get poem right}%
+\global\let\poem@needrun\undefined
+\fi
+}
+\ifx\AtEndDocument\undefined\else\AtEndDocument\poem@finish\fi
+\newcounter{poem@no}\setcounter{poem@no}{\z@}
+\ifx\max@poem@no\undefined
+ \def\max@poem@no{0}%
+\fi
+\newcommand{\poem@prop}[1]{\@nameuse{#1@\romannumeral\c@poem@no}}
+\newcommand{\poem@write@aux}[2]{%
+ \def\@x{\immediate\write\@auxout{\global\noexpand\@namedef{#1}{#2}}}%
+ \@x
+}
+\def\@modernpoem{%
+\par
+\begingroup
+\parskip=\z@
+\parindent=\z@
+\def\[{\@settab\@tabplus\ignorespaces}%
+\def\]{\@tabminus\ignorespaces}%
+\def\newblock{\poemblocksep}%
+\let\newpoem@tabcr\@tabcr
+\def\par{% Redefine \par for possible \obeylines
+ \ifpoem@started\else
+ \ifdim\wd\@curline>\z@\global\poem@startedtrue\else
+ \@stopfield
+ \ifdim\wd\@curfield>\z@\global\poem@startedtrue\fi
+ \@contfield
+ \fi
+ \fi
+ \ifpoem@started\newpoem@tabcr\fi}%
+\def\@tabcr{\global\poem@startedtrue\newpoem@tabcr}%
+\global\poem@startedfalse
+\csname poem@obeylines\endcsname
+\let\poem@obeylines\relax
+\begin{tabbing}%
+}
+\def\@endmodernpoem{%
+\global\poem@startedfalse
+\ifdim\wd\@curline>\z@\global\poem@startedtrue\else
+ \@stopfield
+ \ifdim\wd\@curfield>\z@\global\poem@startedtrue\fi
+ \@contfield
+\fi
+\ifpoem@started\else\let\@stopline\@stopfield\fi
+\end{tabbing}%
+\endgroup
+\par
+}
+\newenvironment{modernpoem}{\@modernpoem}{\@endmodernpoem}
+\expandafter\def\csname modernpoem*\endcsname{\let\poem@obeylines=\obeylines\modernpoem}
+\expandafter\def\csname endmodernpoem*\endcsname{\endmodernpoem}
+\gdef\@startfield{%
+\global\setbox\@curfield\hbox\bgroup%
+\let\@footnotetext\simurghpoem@p@ftntext%
+\let\@LTRfootnotetext\simurghpoem@p@LTRftntext%
+\let\@RTLfootnotetext\simurghpoem@p@RTLftntext%
+\let\@xfootnotenext\simurghpoem@p@xftntext%
+\let\@xfootnote\simurghpoem@p@xfootnote%
+\let\@xLTRfootnotenext\simurghpoem@p@xLTRftntext%
+\let\@xLTRfootnote\simurghpoem@p@xLTRfootnote%
+\let\@xRTLfootnotenext\simurghpoem@p@xRTLftntext%
+\let\@xRTLfootnote\simurghpoem@p@xRTLfootnote%
+\color@begingroup}
+\gdef\@stopfield{%
+ \color@endgroup\egroup\global\simurghpoem@p@ftn\expandafter{\expandafter}\the\simurghpoem@p@ftn}
+\gdef\@contfield{%
+\global\setbox\@curfield\hbox\bgroup%
+\let\@footnotetext\simurghpoem@p@ftntext%
+\let\@LTRfootnotetext\simurghpoem@p@LTRftntext%
+\let\@RTLfootnotetext\simurghpoem@p@RTLftntext%
+\let\@xfootnotenext\simurghpoem@p@xftntext%
+\let\@xfootnote\simurghpoem@p@xfootnote%
+\let\@xLTRfootnotenext\simurghpoem@p@xLTRftntext%
+\let\@xLTRfootnote\simurghpoem@p@xLTRfootnote%
+\let\@xRTLfootnotenext\simurghpoem@p@xRTLftntext%
+\let\@xRTLfootnote\simurghpoem@p@xRTLfootnote%
+\color@begingroup\unhbox\@curfield}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-rapport1.sty b/macros/luatex/latex/simurgh/tex/simurgh-rapport1.sty
new file mode 100644
index 0000000000..a22311d8ec
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-rapport1.sty
@@ -0,0 +1,68 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-rappport1}[2013/09/22 v0.01a changes to `rapport1.cls']
+
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \kern.5\baselineskip
+ \hrule\@width\unitindent
+ \kern.4\baselineskip}\hfil}
+}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \kern.5\baselineskip
+ \hrule\@width\unitindent
+ \kern.4\baselineskip}\hfil}
+}
+\renewenvironment{thebibliography}[1]
+ {\chapter*{\bibname}%
+ \@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand*\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy\clubpenalty4000\widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+\renewcommand*\thesection{\thechapter\@SepMark\@arabic\c@section}
+\renewcommand*\thesubsection{\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand*\thesubsubsection{\thesubsection\@SepMark\@arabic\c@subsubsection}
+\renewcommand*\theparagraph{\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand*\thesubparagraph{\theparagraph\@SepMark\@arabic\c@subparagraph}
+\renewcommand*\theequation{%
+ \ifnum \c@chapter>\z@ \thechapter\@SepMark\fi\@arabic\c@equation}
+\renewcommand*\thefigure{%
+ \ifnum\c@chapter>\z@\thechapter\@SepMark\fi\@arabic\c@figure}
+\renewcommand*\thetable{%
+ \ifnum\c@chapter>\z@\thechapter\@SepMark\fi\@arabic\c@table}
+
+\renewcommand*\thepart{\@tartibi\c@part}
+\renewcommand*\appendix{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-rapport3.sty b/macros/luatex/latex/simurgh/tex/simurgh-rapport3.sty
new file mode 100644
index 0000000000..8c73b6448f
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-rapport3.sty
@@ -0,0 +1,66 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-rapport3}[2013/09/22 v0.01a changes to `rapport3.cls']
+\renewcommand*\thesection{\thechapter\@SepMark\@arabic\c@section}
+\renewcommand*\thesubsection{\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand*\thesubsubsection{\thesubsection\@SepMark\@arabic\c@subsubsection}
+\renewcommand*\theparagraph{\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand*\thesubparagraph{\theparagraph\@SepMark\@arabic\c@subparagraph}
+\renewcommand*\thefigure{%
+ \ifnum\c@chapter>\z@\thechapter\@SepMark\fi\@arabic\c@figure}
+\renewcommand*\thetable{%
+ \ifnum\c@chapter>\z@\thechapter\@SepMark\fi\@arabic\c@table}
+\renewcommand*\theequation{%
+ \ifnum \c@chapter>\z@ \thechapter\@SepMark\fi\@arabic\c@equation}
+\renewenvironment{thebibliography}[1]
+ {\chapter*{\bibname}%
+ \@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand*\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy\clubpenalty4000\widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \kern.5\baselineskip
+ \hrule\@width\unitindent
+ \kern.4\baselineskip}\hfil}
+}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \kern.5\baselineskip
+ \hrule\@width\unitindent
+ \kern.4\baselineskip}\hfil}
+}
+
+\renewcommand*\thepart{\@tartibi\c@part}
+\renewcommand*\appendix{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-refrep.sty b/macros/luatex/latex/simurgh/tex/simurgh-refrep.sty
new file mode 100644
index 0000000000..f2154da224
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-refrep.sty
@@ -0,0 +1,66 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-refrep}[2013/09/22 v0.01a changes to `refrep.cls']
+\renewcommand\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern 2.6\p@}\hfil}}
+\renewcommand\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern 2.6\p@}\hfil}}
+\renewcommand\theequation
+{\ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@equation}
+\renewcommand\thefigure
+ {\ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@figure}
+\renewcommand\thetable%
+ {\ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@table}
+\renewcommand\thesection {\thechapter\@SepMark\@arabic\c@section}
+\renewcommand\thesubsection {\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand\thesubsubsection {\thesubsection \@SepMark\@arabic\c@subsubsection}
+\renewcommand\theparagraph {\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand\thesubparagraph {\theparagraph\@SepMark\@arabic\c@subparagraph}
+\renewenvironment{thebibliography}[1]
+ {\chapter*{\bibname
+ \@mkboth{\bibname}{\bibname}}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy
+ \clubpenalty4000
+ \@clubpenalty \clubpenalty
+ \widowpenalty4000%
+ \sfcode`\.=\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+
+\renewcommand \thepart {\@tartibi\c@part}
+\renewcommand\appendix{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}
+}%end appendix
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-report.sty b/macros/luatex/latex/simurgh/tex/simurgh-report.sty
new file mode 100644
index 0000000000..66d7364c15
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-report.sty
@@ -0,0 +1,90 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-report}[2013/09/22 v0.01a changes to `report.cls']
+\renewcommand\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern2.6\p@}\hfil}}
+\renewcommand\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \hrule\@width.4\columnwidth
+ \kern2.6\p@}\hfil}}
+\renewcommand\theequation
+ {\ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@equation}
+\renewcommand \thefigure
+ {\ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@figure}
+\renewcommand \thetable
+ {\ifnum \c@chapter>\z@ \thechapter\@SepMark\fi \@arabic\c@table}
+\renewcommand \thechapter {\@arabic\c@chapter}
+\renewcommand \thesection {\thechapter\@SepMark\@arabic\c@section}
+\renewcommand\thesubsection {\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand\thesubsubsection{\thesubsection \@SepMark\@arabic\c@subsubsection}
+\renewcommand\theparagraph {\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand\thesubparagraph {\theparagraph\@SepMark\@arabic\c@subparagraph}
+\def\@makechapterhead#1{%
+ \vspace*{50\p@}%
+ {\parindent \z@ \simurgh@raggedright \normalfont
+ \ifnum \c@secnumdepth >\m@ne
+ \huge\bfseries \@chapapp\space \thechapter
+ \par\nobreak
+ \vskip 20\p@
+ \fi
+ \interlinepenalty\@M
+ \Huge \bfseries #1\par\nobreak
+ \vskip 40\p@
+ }}
+\def\@makeschapterhead#1{%
+ \vspace*{50\p@}%
+ {\parindent \z@ \simurgh@raggedright
+ \normalfont
+ \interlinepenalty\@M
+ \Huge \bfseries #1\par\nobreak
+ \vskip 40\p@
+ }}
+\renewenvironment{thebibliography}[1]
+ {\chapter*{\bibname}%
+ \@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{\@biblabel{\@arabic\c@enumiv}}%
+ {\settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \renewcommand\theenumiv{\@arabic\c@enumiv}}%
+ \sloppy
+ \clubpenalty4000
+ \@clubpenalty \clubpenalty
+ \widowpenalty4000%
+ \sfcode`\.\@m}
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}
+
+
+\renewcommand \thepart {\@tartibi\c@part}
+\renewcommand\appendix{\par
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}
+}%end appendix
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-scrartcl.sty b/macros/luatex/latex/simurgh/tex/simurgh-scrartcl.sty
new file mode 100644
index 0000000000..889401085d
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-scrartcl.sty
@@ -0,0 +1,296 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-scrartcl}[2013/09/22 v0.01a changes to `scrartcl.cls']
+\newcommand{\scr@saved@LTRfootnotetext}{}
+\newcommand{\scr@saved@RTLfootnotetext}{}
+\let\scr@saved@footnotetext\@footnotetext
+\let\scr@saved@LTRfootnotetext\@LTRfootnotetext
+\let\scr@saved@RTLfootnotetext\@RTLfootnotetext
+\renewcommand{\@footnotetext}[1]{%
+ \scr@saved@footnotetext{#1}%
+ \csname FN@mf@prepare\endcsname
+}
+\renewcommand{\@LTRfootnotetext}[1]{%
+ \scr@saved@LTRfootnotetext{#1}%
+ \csname FN@mf@prepare\endcsname
+}
+\renewcommand{\@RTLfootnotetext}[1]{%
+ \scr@saved@RTLfootnotetext{#1}%
+ \csname FN@mf@prepare\endcsname
+}
+\renewcommand\deffootnote[4][]{%
+ \long\def\@makefntext##1{%
+ \setlength{\@tempdimc}{#3}%
+ \def\@tempa{#1}\ifx\@tempa\@empty
+ \@setpar{\@@par
+ \@tempdima = \hsize
+ \addtolength{\@tempdima}{-#2}%
+ \if@RTL\parshape \@ne #2 \@tempdima\else\parshape \@ne \z@ \@tempdima\fi}%
+ \else
+ \addtolength{\@tempdimc}{#2}%
+ \addtolength{\@tempdimc}{-#1}%
+ \@setpar{\@@par
+ \@tempdima = \hsize
+ \addtolength{\@tempdima}{-#1}%
+ \@tempdimb = \hsize
+ \addtolength{\@tempdimb}{-#2}%
+ \if@RTL\parshape \tw@ #1 \@tempdima #2 \@tempdimb\else\parshape \tw@ \z@ \@tempdima \z@ \@tempdimb\fi
+ }%
+ \fi
+ \par
+ \parindent\@tempdimc\noindent
+ \ftn@font\hbox to \z@{\hss\@@makefnmark}##1%
+ }%
+ \def\@@makefnmark{\hbox{\ftnm@font{#4}}}%
+}
+\deffootnote[1em]{1.5em}{1em}{\textsuperscript{\thefootnotemark}}
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{\kern -3\p@
+ \normalsize\ftn@rule@test@values
+ \kern-\dimexpr 2.6\p@+\ftn@rule@height\relax
+ \ifx\@textbottom\relax\else\vskip \z@ \@plus.05fil\fi
+ {\usekomafont{footnoterule}{%
+ \hrule \@height\ftn@rule@height \@width\ftn@rule@width}}%
+ \kern 2.6\p@}\hfil}}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{\kern -3\p@
+ \normalsize\ftn@rule@test@values
+ \kern-\dimexpr 2.6\p@+\ftn@rule@height\relax
+ \ifx\@textbottom\relax\else\vskip \z@ \@plus.05fil\fi
+ {\usekomafont{footnoterule}{%
+ \hrule \@height\ftn@rule@height \@width\ftn@rule@width}}%
+ \kern 2.6\p@}\hfil}}
+
+\def\raggedsection{\simurgh@raggedright}
+\def\raggedpart{\simurgh@raggedright}
+\renewcommand*\autodot{\if@altsecnumformat\@SepMark\fi}
+\renewcommand*{\thesubsection}{\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand*{\thesubsubsection}{%
+ \thesubsection\@SepMark\@arabic\c@subsubsection
+}
+\renewcommand*{\theparagraph}{\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand*{\thesubparagraph}{%
+ \theparagraph\@SepMark\@arabic\c@subparagraph
+}
+
+\renewenvironment{thebibliography}[1]{%
+ \if@bib@break@
+ \bib@beginhook
+ \else
+ \bib@heading
+ \ifx\bibpreamble\relax\else\ifx\bibpreamble\@empty\else
+ \noindent\bibpreamble\par\nobreak
+ \fi\fi
+ \bib@beginhook
+ \bib@before@hook
+ \fi
+ \renewcommand{\BreakBibliography}[1]{%
+ \@bib@break
+ \end{thebibliography}%
+ \begingroup ##1\endgroup
+ \begin{thebibliography}{#1}
+ }%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{%
+ \@biblabel{\@arabic\c@enumiv}%
+ }{%
+ \settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \if@bib@break@
+ \edef\@tempa{%
+ \noexpand\usecounter{enumiv}%
+ \noexpand\setcounter{enumiv}{\the\c@enumiv}%
+ }\@tempa
+ \no@bib@break
+ \else
+ \usecounter{enumiv}%
+ \fi
+ \let\p@enumiv\@empty
+ \renewcommand*\theenumiv{\@arabic\c@enumiv}%
+ }%
+ \sloppy\clubpenalty4000 \widowpenalty4000
+ \sfcode`\.=\@m
+}{%
+ \if@bib@break@
+ \def\@noitemerr{%
+ \@latex@warning{%
+ \string\BreakBibliography\space at begin of `thebibliography'
+ environment\MessageBreak
+ or following \string\BreakBibliography}%
+ }%
+ \else
+ \def\@noitemerr{%
+ \@latex@warning{%
+ Empty `thebibliography' environment or
+ \string\BreakBibliography\MessageBreak
+ before end of `thebibliography' environment}%
+ }%
+ \fi
+ \endlist
+ \if@bib@break@
+ \else
+ \bib@after@hook
+ \let\bib@before@hook\@empty
+ \let\bib@after@hook\@empty
+ \fi
+ \bib@endhook
+}
+
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \ifx\@textbottom\relax\else\vskip \z@ \@plus.05fil\fi
+ \hrule\@width.4\columnwidth
+ \kern 2.6\p@}\hfil}}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \ifx\@textbottom\relax\else\vskip \z@ \@plus.05fil\fi
+ \hrule\@width.4\columnwidth
+ \kern 2.6\p@}\hfil}}
+\renewcommand*{\raggeddictum}{\simurgh@raggedleft}
+\renewcommand*{\raggeddictumtext}{\simurgh@raggedright}
+\renewcommand*{\raggeddictumauthor}{\simurgh@raggedleft}
+\renewcommand\marginline[1]{%
+ \marginpar[\simurgh@raggedleft{#1}]{\simurgh@raggedright #1}%
+}
+
+\renewcommand{\@@makecaption}[3]{%
+ \cap@margin
+ \ifonelinecaptions
+ \@tempcnta=\value{mpfootnote}\@tempcntb=\value{footnote}%
+ \let\scr@tmp@footnotetext=\@footnotetext
+ \let\@footnotetext=\@gobble
+ \let\scr@tmp@LTRfootnotetext=\@LTRfootnotetext
+ \let\@LTRfootnotetext=\@gobble
+ \let\scr@tmp@RTLfootnotetext=\@RTLfootnotetext
+ \let\@RTLfootnotetext=\@gobble
+ \sbox\@tempboxa{%
+ {\capfont{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat}}}%
+ #3\unskip\strut}}%
+ }%
+ \let\@footnotetext=\scr@tmp@footnotetext
+ \let\scr@tmp@footnotetext=\undefined
+ \let\@LTRfootnotetext=\scr@tmp@LTRfootnotetext
+ \let\scr@tmp@LTRfootnotetext=\undefined
+ \let\@RTLfootnotetext=\scr@tmp@RTLfootnotetext
+ \let\scr@tmp@RTLfootnotetext=\undefined
+ \setcounter{footnote}{\@tempcntb}%
+ \setcounter{mpfootnote}{\@tempcnta}%
+ \else
+ \sbox\@tempboxa{\hspace*{2\cap@width}}%
+ \fi
+ \begingroup%
+ \setlength{\@tempdima}{\cap@width}%
+ \ifdim \wd\@tempboxa >\@tempdima
+ \hb@xt@\hsize{%
+ \setbox\@tempboxa\vbox{\hsize=\cap@width
+ \ifdofullc@p
+ {\capfont{\@hangfrom{\scr@smashdp{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat}}}}}%
+ {#3\unskip\strut\par}}}%
+ \else%
+ \ifdim\cap@indent<\z@
+ {\capfont{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat\par}}}%
+ \noindent\hspace*{-\cap@indent}#3\unskip\strut\par}}%
+ \else%
+ \if@capbreak
+ {\capfont{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat\par}}}%
+ \noindent\@hangfrom{\hspace*{\cap@indent}}{#3\par}}}%
+ \else
+ {\capfont{\@hangfrom{\scr@smashdp\strut\hspace*{\cap@indent}}%
+ {\hspace{-\cap@indent}\scr@smashdp{\ignorespaces#1%
+ {{\caplabelfont{#2\captionformat}}}}#3\unskip\strut\par}}}%
+ \fi
+ \fi
+ \fi
+ }%
+ \setlength{\@tempdima}{\ht\@tempboxa}%
+ \addtolength{\@tempdima}{\dp\@tempboxa}%
+ \addtolength{\@tempdima}{-\ht\strutbox}%
+ \ht\@tempboxa\ht\strutbox
+ \dp\@tempboxa\@tempdima
+ \strut\cap@left
+ \box\@tempboxa
+ \cap@right\strut
+ }%
+ \else
+ \global \@minipagefalse
+ \sbox\@tempboxa{%
+ {\capfont{\scr@smashdp{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat}}}}%
+ #3}}%
+ }%
+ {\capfont{\hb@xt@\hsize{\strut\cap@left\box\@tempboxa\cap@right\strut}}}%
+ \fi
+ \endgroup
+}
+\renewcommand{\@makecaption}[2]{%
+ \if@captionabove
+ \vskip\belowcaptionskip
+ \else
+ \vskip\abovecaptionskip
+ \fi
+ \@@makecaption\@firstofone{#1}{#2}%
+ \if@captionabove
+ \vskip\abovecaptionskip
+ \else
+ \vskip\belowcaptionskip
+ \fi
+}
+
+
+\renewcommand*{\thepart}{\@tartibi\c@part}
+\renewcommand*\appendix{\par%
+ \setcounter{section}{0}%
+ \setcounter{subsection}{0}%
+ \gdef\thesection{\@harfi\c@section}%
+ \csname appendixmore\endcsname
+}
+\renewcommand*{\@@maybeautodot}[1]{%
+ \ifx #1\@stop\let\@@maybeautodot\relax
+ \else
+ \ifx #1\harfi \@autodottrue\fi
+ \ifx #1\adadi \@autodottrue\fi
+ \ifx #1\tartibi \@autodottrue\fi
+ \ifx #1\Alph \@autodottrue\fi
+ \ifx #1\alph \@autodottrue\fi
+ \ifx #1\Roman \@autodottrue\fi
+ \ifx #1\roman \@autodottrue\fi
+ \ifx #1\@harfi \@autodottrue\fi
+ \ifx #1\@adadi \@autodottrue\fi
+ \ifx #1\@tartibi \@autodottrue\fi
+ \ifx #1\@Alph \@autodottrue\fi
+ \ifx #1\@alph \@autodottrue\fi
+ \ifx #1\@Roman \@autodottrue\fi
+ \ifx #1\@roman \@autodottrue\fi
+ \ifx #1\romannumeral \@autodottrue\fi
+ \fi
+ \@@maybeautodot
+}
+
+
+
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-scrbook.sty b/macros/luatex/latex/simurgh/tex/simurgh-scrbook.sty
new file mode 100644
index 0000000000..c21de8f75a
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-scrbook.sty
@@ -0,0 +1,328 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-scrbook}[2013/09/22 v0.01a changes to `scrbook.cls']
+\newcommand{\scr@saved@LTRfootnotetext}{}
+\newcommand{\scr@saved@RTLfootnotetext}{}
+\let\scr@saved@footnotetext\@footnotetext
+\let\scr@saved@LTRfootnotetext\@LTRfootnotetext
+\let\scr@saved@RTLfootnotetext\@RTLfootnotetext
+\renewcommand{\@footnotetext}[1]{%
+ \scr@saved@footnotetext{#1}%
+ \csname FN@mf@prepare\endcsname
+}
+\renewcommand{\@LTRfootnotetext}[1]{%
+ \scr@saved@LTRfootnotetext{#1}%
+ \csname FN@mf@prepare\endcsname
+}
+\renewcommand{\@RTLfootnotetext}[1]{%
+ \scr@saved@RTLfootnotetext{#1}%
+ \csname FN@mf@prepare\endcsname
+}
+\renewcommand\deffootnote[4][]{%
+ \long\def\@makefntext##1{%
+ \setlength{\@tempdimc}{#3}%
+ \def\@tempa{#1}\ifx\@tempa\@empty
+ \@setpar{\@@par
+ \@tempdima = \hsize
+ \addtolength{\@tempdima}{-#2}%
+ \if@RTL\parshape \@ne #2 \@tempdima\else\parshape \@ne \z@ \@tempdima\fi}%
+ \else
+ \addtolength{\@tempdimc}{#2}%
+ \addtolength{\@tempdimc}{-#1}%
+ \@setpar{\@@par
+ \@tempdima = \hsize
+ \addtolength{\@tempdima}{-#1}%
+ \@tempdimb = \hsize
+ \addtolength{\@tempdimb}{-#2}%
+ \if@RTL\parshape \tw@ #1 \@tempdima #2 \@tempdimb\else\parshape \tw@ \z@ \@tempdima \z@ \@tempdimb\fi
+ }%
+ \fi
+ \par
+ \parindent\@tempdimc\noindent
+ \ftn@font\hbox to \z@{\hss\@@makefnmark}##1%
+ }%
+ \def\@@makefnmark{\hbox{\ftnm@font{#4}}}%
+}
+\deffootnote[1em]{1.5em}{1em}{\textsuperscript{\thefootnotemark}}
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{\kern -3\p@
+ \normalsize\ftn@rule@test@values
+ \kern-\dimexpr 2.6\p@+\ftn@rule@height\relax
+ \ifx\@textbottom\relax\else\vskip \z@ \@plus.05fil\fi
+ {\usekomafont{footnoterule}{%
+ \hrule \@height\ftn@rule@height \@width\ftn@rule@width}}%
+ \kern 2.6\p@}\hfil}}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{\kern -3\p@
+ \normalsize\ftn@rule@test@values
+ \kern-\dimexpr 2.6\p@+\ftn@rule@height\relax
+ \ifx\@textbottom\relax\else\vskip \z@ \@plus.05fil\fi
+ {\usekomafont{footnoterule}{%
+ \hrule \@height\ftn@rule@height \@width\ftn@rule@width}}%
+ \kern 2.6\p@}\hfil}}
+
+
+\def\raggedsection{\simurgh@raggedright}
+\renewcommand*\autodot{\if@altsecnumformat\@SepMark\fi}
+\renewcommand*\thesection{%
+ \ifnum \scr@compatibility>\@nameuse{scr@v@2.97d}\relax
+ \if@mainmatter\thechapter\@SepMark\fi
+ \else
+ \thechapter\@SepMark%
+ \fi
+ \@arabic\c@section
+}
+\renewcommand*{\thesubsection}{\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand*{\thesubsubsection}{%
+ \thesubsection\@SepMark\@arabic\c@subsubsection
+}
+\renewcommand*{\theparagraph}{\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand*{\thesubparagraph}{%
+ \theparagraph\@SepMark\@arabic\c@subparagraph
+}
+\renewcommand*\thefigure{%
+ \ifnum \scr@compatibility>\@nameuse{scr@v@2.97d}\relax
+ \if@mainmatter\thechapter\@SepMark\fi
+ \else
+ \thechapter\@SepMark%
+ \fi
+ \@arabic\c@figure
+}
+\renewcommand*\thetable{%
+ \ifnum \scr@compatibility>\@nameuse{scr@v@2.97d}\relax
+ \if@mainmatter\thechapter\@SepMark\fi
+ \else
+ \thechapter\@SepMark%
+ \fi
+ \@arabic\c@table
+}
+\renewcommand*\theequation{%
+ \ifnum \scr@compatibility>\@nameuse{scr@v@2.97d}\relax
+ \if@mainmatter\thechapter\@SepMark\fi
+ \else
+ \thechapter\@SepMark%
+ \fi
+ \@arabic\c@equation
+}
+
+\renewenvironment{thebibliography}[1]{%
+ \if@bib@break@
+ \bib@beginhook
+ \else
+ \ifx\bibpreamble\relax\else\ifx\bibpreamble\@empty\else
+ \setchapterpreamble{\bibpreamble}%
+ \fi\fi
+ \bib@heading
+ \bib@beginhook
+ \bib@before@hook
+ \fi
+ \renewcommand{\BreakBibliography}[1]{%
+ \@bib@break
+ \end{thebibliography}%
+ \begingroup ##1\endgroup
+ \begin{thebibliography}{#1}
+ }%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{%
+ \@biblabel{\@arabic\c@enumiv}%
+ }{%
+ \settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \if@bib@break@
+ \edef\@tempa{%
+ \noexpand\usecounter{enumiv}%
+ \noexpand\setcounter{enumiv}{\the\c@enumiv}%
+ }\@tempa
+ \no@bib@break
+ \else
+ \usecounter{enumiv}%
+ \fi
+ \let\p@enumiv\@empty
+ \renewcommand*\theenumiv{\@arabic\c@enumiv}%
+ }%
+ \sloppy\clubpenalty4000 \widowpenalty4000
+ \sfcode`\.=\@m
+}{%
+ \if@bib@break@
+ \def\@noitemerr{%
+ \@latex@warning{%
+ \string\BreakBibliography\space at begin of `thebibliography'
+ environment\MessageBreak
+ or following \string\BreakBibliography}%
+ }%
+ \else
+ \def\@noitemerr{%
+ \@latex@warning{%
+ Empty `thebibliography' environment or
+ \string\BreakBibliography\MessageBreak
+ before end of `thebibliography' environment}%
+ }%
+ \fi
+ \endlist
+ \if@bib@break@
+ \else
+ \bib@after@hook
+ \let\bib@before@hook\@empty
+ \let\bib@after@hook\@empty
+ \fi
+ \bib@endhook
+}
+
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \ifx\@textbottom\relax\else\vskip \z@ \@plus.05fil\fi
+ \hrule\@width.4\columnwidth
+ \kern 2.6\p@}\hfil}}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \ifx\@textbottom\relax\else\vskip \z@ \@plus.05fil\fi
+ \hrule\@width.4\columnwidth
+ \kern 2.6\p@}\hfil}}
+\renewcommand*{\raggeddictum}{\simurgh@raggedleft}
+\renewcommand*{\raggeddictumtext}{\simurgh@raggedright}
+\renewcommand*{\raggeddictumauthor}{\simurgh@raggedleft}
+\renewcommand\marginline[1]{%
+ \marginpar[\simurgh@raggedleft{#1}]{\simurgh@raggedright #1}%
+}
+
+\renewcommand{\@@makecaption}[3]{%
+ \cap@margin
+ \ifonelinecaptions
+ \@tempcnta=\value{mpfootnote}\@tempcntb=\value{footnote}%
+ \let\scr@tmp@footnotetext=\@footnotetext
+ \let\@footnotetext=\@gobble
+ \let\scr@tmp@LTRfootnotetext=\@LTRfootnotetext
+ \let\@LTRfootnotetext=\@gobble
+ \let\scr@tmp@RTLfootnotetext=\@RTLfootnotetext
+ \let\@RTLfootnotetext=\@gobble
+ \sbox\@tempboxa{%
+ {\capfont{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat}}}%
+ #3\unskip\strut}}%
+ }%
+ \let\@footnotetext=\scr@tmp@footnotetext
+ \let\scr@tmp@footnotetext=\undefined
+ \let\@LTRfootnotetext=\scr@tmp@LTRfootnotetext
+ \let\scr@tmp@LTRfootnotetext=\undefined
+ \let\@RTLfootnotetext=\scr@tmp@RTLfootnotetext
+ \let\scr@tmp@RTLfootnotetext=\undefined
+ \setcounter{footnote}{\@tempcntb}%
+ \setcounter{mpfootnote}{\@tempcnta}%
+ \else
+ \sbox\@tempboxa{\hspace*{2\cap@width}}%
+ \fi
+ \begingroup%
+ \setlength{\@tempdima}{\cap@width}%
+ \ifdim \wd\@tempboxa >\@tempdima
+ \hb@xt@\hsize{%
+ \setbox\@tempboxa\vbox{\hsize=\cap@width
+ \ifdofullc@p
+ {\capfont{\@hangfrom{\scr@smashdp{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat}}}}}%
+ {#3\unskip\strut\par}}}%
+ \else%
+ \ifdim\cap@indent<\z@
+ {\capfont{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat\par}}}%
+ \noindent\hspace*{-\cap@indent}#3\unskip\strut\par}}%
+ \else%
+ \if@capbreak
+ {\capfont{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat\par}}}%
+ \noindent\@hangfrom{\hspace*{\cap@indent}}{#3\par}}}%
+ \else
+ {\capfont{\@hangfrom{\scr@smashdp\strut\hspace*{\cap@indent}}%
+ {\hspace{-\cap@indent}\scr@smashdp{\ignorespaces#1%
+ {{\caplabelfont{#2\captionformat}}}}#3\unskip\strut\par}}}%
+ \fi
+ \fi
+ \fi
+ }%
+ \setlength{\@tempdima}{\ht\@tempboxa}%
+ \addtolength{\@tempdima}{\dp\@tempboxa}%
+ \addtolength{\@tempdima}{-\ht\strutbox}%
+ \ht\@tempboxa\ht\strutbox
+ \dp\@tempboxa\@tempdima
+ \strut\cap@left
+ \box\@tempboxa
+ \cap@right\strut
+ }%
+ \else
+ \global \@minipagefalse
+ \sbox\@tempboxa{%
+ {\capfont{\scr@smashdp{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat}}}}%
+ #3}}%
+ }%
+ {\capfont{\hb@xt@\hsize{\strut\cap@left\box\@tempboxa\cap@right\strut}}}%
+ \fi
+ \endgroup
+}
+\renewcommand{\@makecaption}[2]{%
+ \if@captionabove
+ \vskip\belowcaptionskip
+ \else
+ \vskip\abovecaptionskip
+ \fi
+ \@@makecaption\@firstofone{#1}{#2}%
+ \if@captionabove
+ \vskip\abovecaptionskip
+ \else
+ \vskip\belowcaptionskip
+ \fi
+}
+
+\renewcommand*\frontmatter{%
+ \if@twoside\cleardoubleoddpage\else\clearpage\fi
+ \@mainmatterfalse\pagenumbering{harfi}%
+}
+\renewcommand*{\thepart}{\@tartibi\c@part}
+\renewcommand*\appendix{\par%
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}%
+ \csname appendixmore\endcsname
+}
+\renewcommand*{\@@maybeautodot}[1]{%
+ \ifx #1\@stop\let\@@maybeautodot\relax
+ \else
+ \ifx #1\harfi \@autodottrue\fi
+ \ifx #1\adadi \@autodottrue\fi
+ \ifx #1\tartibi \@autodottrue\fi
+ \ifx #1\Alph \@autodottrue\fi
+ \ifx #1\alph \@autodottrue\fi
+ \ifx #1\Roman \@autodottrue\fi
+ \ifx #1\roman \@autodottrue\fi
+ \ifx #1\@harfi \@autodottrue\fi
+ \ifx #1\@adadi \@autodottrue\fi
+ \ifx #1\@tartibi \@autodottrue\fi
+ \ifx #1\@Alph \@autodottrue\fi
+ \ifx #1\@alph \@autodottrue\fi
+ \ifx #1\@Roman \@autodottrue\fi
+ \ifx #1\@roman \@autodottrue\fi
+ \ifx #1\romannumeral \@autodottrue\fi
+ \fi
+ \@@maybeautodot
+}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-scrlettr.sty b/macros/luatex/latex/simurgh/tex/simurgh-scrlettr.sty
new file mode 100644
index 0000000000..e229d60962
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-scrlettr.sty
@@ -0,0 +1,117 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-scrlettr}[2013/09/22 v0.01a changes to `scrlettr.cls']
+\renewcommand\deffootnote[4][]{%
+ \long\def\@makefntext##1{%
+ \edef\@tempa{#1}\ifx\@tempa\@empty
+ \@setpar{\@@par
+ \@tempdima = \hsize
+ \addtolength{\@tempdima}{-#2}
+ \if@RTL\parshape \@ne #2 \@tempdima\else\parshape \@ne \z@ \@tempdima\fi}%
+ \else
+ \@setpar{\@@par
+ \@tempdima = \hsize
+ \addtolength{\@tempdima}{-#1}
+ \@tempdimb = \hsize
+ \addtolength{\@tempdimb}{-#2}
+ \if@RTL\parshape \tw@ #1 \@tempdima #2 \@tempdimb\else\parshape \tw@ \z@ \@tempdima \z@ \@tempdimb\fi}%
+ \fi
+ \par
+ \parindent #3\noindent
+ \hbox to \z@{\hss\@@makefnmark}##1}
+ \def\@@makefnmark{\hbox{#4}}
+}
+\deffootnote[1em]{1.5em}{1em}
+ {\textsuperscript{\thefootnotemark}}
+\def\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{\kern -3\p@
+ \kern-1\p@
+ \hrule width 0.4\columnwidth
+ \kern .6\p@}\hfil}}
+\def\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{\kern -3\p@
+ \kern-1\p@
+ \hrule width 0.4\columnwidth
+ \kern .6\p@}\hfil}}
+\def\@datefield{\@reffalse
+ \ifx\varyourref\@empty \else \@reftrue \fi
+ \ifx\varyourmail\@empty \else \@reftrue \fi
+ \ifx\varmyref\@empty \else \@reftrue \fi
+ \ifx\varcustomer\@empty \else \@reftrue \fi
+ \ifx\varinvoice\@empty \else \@reftrue \fi
+ \ifx\varrefitemi\@empty \else \@reftrue \fi
+ \ifx\varrefitemii\@empty \else \@reftrue \fi
+ \ifx\varrefitemiii\@empty \else \@reftrue \fi
+ \vskip -\parskip
+ \vskip \refvskip
+ \if@ref
+ \ifx\varyourref\@empty \else
+ \settowidth{\sc@temp}{\varyourref}
+ \setbox0\hbox{\scriptsize \sf \yourrefname}
+ \ifdim \sc@temp > \wd0 \sc@@temp\sc@temp \else \sc@@temp\wd0 \fi
+ \parbox[t]{\sc@@temp}{\noindent \box0\par \varyourref}\hfill
+ \fi
+ \ifx\varyourmail\@empty \else
+ \settowidth{\sc@temp}{\varyourmail}
+ \setbox0\hbox{\scriptsize \sf \yourmailname}
+ \ifdim \sc@temp > \wd0 \sc@@temp\sc@temp \else \sc@@temp\wd0 \fi
+ \parbox[t]{\sc@@temp}{\noindent \box0\par \varyourmail}\hfill
+ \fi
+ \ifx\varmyref\@empty \else
+ \settowidth{\sc@temp}{\varmyref}
+ \setbox0\hbox{\scriptsize \sf \myrefname}
+ \ifdim \sc@temp > \wd0 \sc@@temp\sc@temp \else \sc@@temp\wd0 \fi
+ \parbox[t]{\sc@@temp}{\noindent \box0\par \varmyref}\hfill
+ \fi
+ \ifx\varcustomer\@empty \else
+ \settowidth{\sc@temp}{\varcustomer}
+ \setbox0\hbox{\scriptsize \sf \customername}
+ \ifdim \sc@temp > \wd0 \sc@@temp\sc@temp \else \sc@@temp\wd0 \fi
+ \parbox[t]{\sc@@temp}{\noindent \box0\par \varcustomer}\hfill
+ \fi
+ \ifx\varinvoice\@empty \else
+ \settowidth{\sc@temp}{\varinvoice}
+ \setbox0\hbox{\scriptsize \sf \invoicename}
+ \ifdim \sc@temp > \wd0 \sc@@temp\sc@temp \else \sc@@temp\wd0 \fi
+ \parbox[t]{\sc@@temp}{\noindent \box0\par \varinvoice}\hfill
+ \fi
+ \ifx\varrefitemi\@empty \else
+ \settowidth{\sc@temp}{\varrefitemi}
+ \setbox0\hbox{\scriptsize \sf \varrefitemnamei}
+ \ifdim \sc@temp > \wd0 \sc@@temp\sc@temp \else \sc@@temp\wd0 \fi
+ \parbox[t]{\sc@@temp}{\noindent \box0\par \varrefitemi}\hfill
+ \fi
+ \ifx\varrefitemii\@empty \else
+ \settowidth{\sc@temp}{\varrefitemii}
+ \setbox0\hbox{\scriptsize \sf \varrefitemnameii}
+ \ifdim \sc@temp > \wd0 \sc@@temp\sc@temp \else \sc@@temp\wd0 \fi
+ \parbox[t]{\sc@@temp}{\noindent \box0\par \varrefitemii}\hfill
+ \fi
+ \ifx\varrefitemiii\@empty \else
+ \settowidth{\sc@temp}{\varrefitemiii}
+ \setbox0\hbox{\scriptsize \sf \varrefitemnameiii}
+ \ifdim \sc@temp > \wd0 \sc@@temp\sc@temp \else \sc@@temp\wd0 \fi
+ \parbox[t]{\sc@@temp}{\noindent \box0\par \varrefitemiii}\hfill
+ \fi
+ \ifx\@date\@empty \else
+ \settowidth{\sc@temp}{\@date}
+ \setbox0\hbox{\scriptsize \sf \datename}
+ \ifdim \sc@temp > \wd0 \sc@@temp\sc@temp \else \sc@@temp\wd0 \fi
+ \parbox[t]{\sc@@temp}{\noindent \box0\par \@date}
+ \fi
+ \par
+ \vspace{2.5\baselineskip}
+ \else
+ {\ifx\@date\@empty \else \simurgh@raggedleft\fromplace\ \@date\par \fi}
+ \vspace{1.5\baselineskip}
+ \fi}
+\long\def\closing#1{\par\nobreak\vspace{0.5\baselineskip}
+ \stopbreaks \noindent \sc@temp\textwidth \advance\sc@temp by
+ -\sigindent \hspace{\sigindent}%
+ \parbox{\sc@temp}{\simurgh@raggedright\ignorespaces #1\mbox{}\\[\presig@skip]
+ \fromsig\strut}\par
+ \vspace{1.5\baselineskip}}
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-scrreprt.sty b/macros/luatex/latex/simurgh/tex/simurgh-scrreprt.sty
new file mode 100644
index 0000000000..1310021c7a
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-scrreprt.sty
@@ -0,0 +1,315 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-scrreprt}[2013/09/22 v0.01a changes to `scrreprt.cls']
+\newcommand{\scr@saved@LTRfootnotetext}{}
+\newcommand{\scr@saved@RTLfootnotetext}{}
+\let\scr@saved@footnotetext\@footnotetext
+\let\scr@saved@LTRfootnotetext\@LTRfootnotetext
+\let\scr@saved@RTLfootnotetext\@RTLfootnotetext
+\renewcommand{\@footnotetext}[1]{%
+ \scr@saved@footnotetext{#1}%
+ \csname FN@mf@prepare\endcsname
+}
+\renewcommand{\@LTRfootnotetext}[1]{%
+ \scr@saved@LTRfootnotetext{#1}%
+ \csname FN@mf@prepare\endcsname
+}
+\renewcommand{\@RTLfootnotetext}[1]{%
+ \scr@saved@RTLfootnotetext{#1}%
+ \csname FN@mf@prepare\endcsname
+}
+\renewcommand\deffootnote[4][]{%
+ \long\def\@makefntext##1{%
+ \setlength{\@tempdimc}{#3}%
+ \def\@tempa{#1}\ifx\@tempa\@empty
+ \@setpar{\@@par
+ \@tempdima = \hsize
+ \addtolength{\@tempdima}{-#2}%
+ \if@RTL\parshape \@ne #2 \@tempdima\else\parshape \@ne \z@ \@tempdima\fi}%
+ \else
+ \addtolength{\@tempdimc}{#2}%
+ \addtolength{\@tempdimc}{-#1}%
+ \@setpar{\@@par
+ \@tempdima = \hsize
+ \addtolength{\@tempdima}{-#1}%
+ \@tempdimb = \hsize
+ \addtolength{\@tempdimb}{-#2}%
+ \if@RTL\parshape \tw@ #1 \@tempdima #2 \@tempdimb\else\parshape \tw@ \z@ \@tempdima \z@ \@tempdimb\fi
+ }%
+ \fi
+ \par
+ \parindent\@tempdimc\noindent
+ \ftn@font\hbox to \z@{\hss\@@makefnmark}##1%
+ }%
+ \def\@@makefnmark{\hbox{\ftnm@font{#4}}}%
+}
+\deffootnote[1em]{1.5em}{1em}{\textsuperscript{\thefootnotemark}}
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{\kern -3\p@
+ \normalsize\ftn@rule@test@values
+ \kern-\dimexpr 2.6\p@+\ftn@rule@height\relax
+ \ifx\@textbottom\relax\else\vskip \z@ \@plus.05fil\fi
+ {\usekomafont{footnoterule}{%
+ \hrule \@height\ftn@rule@height \@width\ftn@rule@width}}%
+ \kern 2.6\p@}\hfil}}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{\kern -3\p@
+ \normalsize\ftn@rule@test@values
+ \kern-\dimexpr 2.6\p@+\ftn@rule@height\relax
+ \ifx\@textbottom\relax\else\vskip \z@ \@plus.05fil\fi
+ {\usekomafont{footnoterule}{%
+ \hrule \@height\ftn@rule@height \@width\ftn@rule@width}}%
+ \kern 2.6\p@}\hfil}}
+
+\def\raggedsection{\simurgh@raggedright}
+\renewcommand*\autodot{\if@altsecnumformat\@SepMark\fi}
+\renewcommand*\thesection{%
+ \thechapter\@SepMark%
+ \@arabic\c@section
+}
+\renewcommand*{\thesubsection}{\thesection\@SepMark\@arabic\c@subsection}
+\renewcommand*{\thesubsubsection}{%
+ \thesubsection\@SepMark\@arabic\c@subsubsection
+}
+\renewcommand*{\theparagraph}{\thesubsubsection\@SepMark\@arabic\c@paragraph}
+\renewcommand*{\thesubparagraph}{%
+ \theparagraph\@SepMark\@arabic\c@subparagraph
+}
+\renewcommand*\thefigure{%
+ \thechapter\@SepMark%
+ \@arabic\c@figure
+}
+\renewcommand*\thetable{%
+ \thechapter\@SepMark%
+ \@arabic\c@table
+}
+\renewcommand*\theequation{%
+ \thechapter\@SepMark%
+ \@arabic\c@equation
+}
+
+
+\renewenvironment{thebibliography}[1]{%
+ \if@bib@break@
+ \bib@beginhook
+ \else
+ \ifx\bibpreamble\relax\else\ifx\bibpreamble\@empty\else
+ \setchapterpreamble{\bibpreamble}%
+ \fi\fi
+ \bib@heading
+ \bib@beginhook
+ \bib@before@hook
+ \fi
+ \renewcommand{\BreakBibliography}[1]{%
+ \@bib@break
+ \end{thebibliography}%
+ \begingroup ##1\endgroup
+ \begin{thebibliography}{#1}
+ }%
+ \if@RTL%
+ \if@LTRbibitems%
+ \@RTLfalse%
+ \pardir TLT%
+ \textdir TLT%
+ \fi%
+ \else%
+ \if@RTLbibitems%
+ \@RTLtrue%
+ \pardir TRT%
+ \textdir TRT%
+ \fi%
+ \fi%
+ \list{%
+ \@biblabel{\@arabic\c@enumiv}%
+ }{%
+ \settowidth\labelwidth{\@biblabel{#1}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \@openbib@code
+ \if@bib@break@
+ \edef\@tempa{%
+ \noexpand\usecounter{enumiv}%
+ \noexpand\setcounter{enumiv}{\the\c@enumiv}%
+ }\@tempa
+ \no@bib@break
+ \else
+ \usecounter{enumiv}%
+ \fi
+ \let\p@enumiv\@empty
+ \renewcommand*\theenumiv{\@arabic\c@enumiv}%
+ }%
+ \sloppy\clubpenalty4000 \widowpenalty4000
+ \sfcode`\.=\@m
+}{%
+ \if@bib@break@
+ \def\@noitemerr{%
+ \@latex@warning{%
+ \string\BreakBibliography\space at begin of `thebibliography'
+ environment\MessageBreak
+ or following \string\BreakBibliography}%
+ }%
+ \else
+ \def\@noitemerr{%
+ \@latex@warning{%
+ Empty `thebibliography' environment or
+ \string\BreakBibliography\MessageBreak
+ before end of `thebibliography' environment}%
+ }%
+ \fi
+ \endlist
+ \if@bib@break@
+ \else
+ \bib@after@hook
+ \let\bib@before@hook\@empty
+ \let\bib@after@hook\@empty
+ \fi
+ \bib@endhook
+}
+
+
+\renewcommand*\left@footnoterule{%
+ \hbox dir TLT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \ifx\@textbottom\relax\else\vskip \z@ \@plus.05fil\fi
+ \hrule\@width.4\columnwidth
+ \kern 2.6\p@}\hfil}}
+\renewcommand*\right@footnoterule{%
+ \hbox dir TRT to \columnwidth
+ {\vbox{%
+ \kern-3\p@
+ \ifx\@textbottom\relax\else\vskip \z@ \@plus.05fil\fi
+ \hrule\@width.4\columnwidth
+ \kern 2.6\p@}\hfil}}
+\renewcommand*{\raggeddictum}{\simurgh@raggedleft}
+\renewcommand*{\raggeddictumtext}{\simurgh@raggedright}
+\renewcommand*{\raggeddictumauthor}{\simurgh@raggedleft}
+\renewcommand\marginline[1]{%
+ \marginpar[\simurgh@raggedleft{#1}]{\simurgh@raggedright #1}%
+}
+
+\renewcommand{\@@makecaption}[3]{%
+ \cap@margin
+ \ifonelinecaptions
+ \@tempcnta=\value{mpfootnote}\@tempcntb=\value{footnote}%
+ \let\scr@tmp@footnotetext=\@footnotetext
+ \let\@footnotetext=\@gobble
+ \let\scr@tmp@LTRfootnotetext=\@LTRfootnotetext
+ \let\@LTRfootnotetext=\@gobble
+ \let\scr@tmp@RTLfootnotetext=\@RTLfootnotetext
+ \let\@RTLfootnotetext=\@gobble
+ \sbox\@tempboxa{%
+ {\capfont{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat}}}%
+ #3\unskip\strut}}%
+ }%
+ \let\@footnotetext=\scr@tmp@footnotetext
+ \let\scr@tmp@footnotetext=\undefined
+ \let\@LTRfootnotetext=\scr@tmp@LTRfootnotetext
+ \let\scr@tmp@LTRfootnotetext=\undefined
+ \let\@RTLfootnotetext=\scr@tmp@RTLfootnotetext
+ \let\scr@tmp@RTLfootnotetext=\undefined
+ \setcounter{footnote}{\@tempcntb}%
+ \setcounter{mpfootnote}{\@tempcnta}%
+ \else
+ \sbox\@tempboxa{\hspace*{2\cap@width}}%
+ \fi
+ \begingroup%
+ \setlength{\@tempdima}{\cap@width}%
+ \ifdim \wd\@tempboxa >\@tempdima
+ \hb@xt@\hsize{%
+ \setbox\@tempboxa\vbox{\hsize=\cap@width
+ \ifdofullc@p
+ {\capfont{\@hangfrom{\scr@smashdp{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat}}}}}%
+ {#3\unskip\strut\par}}}%
+ \else%
+ \ifdim\cap@indent<\z@
+ {\capfont{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat\par}}}%
+ \noindent\hspace*{-\cap@indent}#3\unskip\strut\par}}%
+ \else%
+ \if@capbreak
+ {\capfont{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat\par}}}%
+ \noindent\@hangfrom{\hspace*{\cap@indent}}{#3\par}}}%
+ \else
+ {\capfont{\@hangfrom{\scr@smashdp\strut\hspace*{\cap@indent}}%
+ {\hspace{-\cap@indent}\scr@smashdp{\ignorespaces#1%
+ {{\caplabelfont{#2\captionformat}}}}#3\unskip\strut\par}}}%
+ \fi
+ \fi
+ \fi
+ }%
+ \setlength{\@tempdima}{\ht\@tempboxa}%
+ \addtolength{\@tempdima}{\dp\@tempboxa}%
+ \addtolength{\@tempdima}{-\ht\strutbox}%
+ \ht\@tempboxa\ht\strutbox
+ \dp\@tempboxa\@tempdima
+ \strut\cap@left
+ \box\@tempboxa
+ \cap@right\strut
+ }%
+ \else
+ \global \@minipagefalse
+ \sbox\@tempboxa{%
+ {\capfont{\scr@smashdp{\strut\ignorespaces
+ #1{{\caplabelfont{#2\captionformat}}}}%
+ #3}}%
+ }%
+ {\capfont{\hb@xt@\hsize{\strut\cap@left\box\@tempboxa\cap@right\strut}}}%
+ \fi
+ \endgroup
+}
+\renewcommand{\@makecaption}[2]{%
+ \if@captionabove
+ \vskip\belowcaptionskip
+ \else
+ \vskip\abovecaptionskip
+ \fi
+ \@@makecaption\@firstofone{#1}{#2}%
+ \if@captionabove
+ \vskip\abovecaptionskip
+ \else
+ \vskip\belowcaptionskip
+ \fi
+}
+
+
+
+\renewcommand*{\thepart}{\@tartibi\c@part}
+\renewcommand*\appendix{\par%
+ \setcounter{chapter}{0}%
+ \setcounter{section}{0}%
+ \gdef\@chapapp{\appendixname}%
+ \gdef\thechapter{\@harfi\c@chapter}%
+ \csname appendixmore\endcsname
+}
+\renewcommand*{\@@maybeautodot}[1]{%
+ \ifx #1\@stop\let\@@maybeautodot\relax
+ \else
+ \ifx #1\harfi \@autodottrue\fi
+ \ifx #1\adadi \@autodottrue\fi
+ \ifx #1\tartibi \@autodottrue\fi
+ \ifx #1\Alph \@autodottrue\fi
+ \ifx #1\alph \@autodottrue\fi
+ \ifx #1\Roman \@autodottrue\fi
+ \ifx #1\roman \@autodottrue\fi
+ \ifx #1\@harfi \@autodottrue\fi
+ \ifx #1\@adadi \@autodottrue\fi
+ \ifx #1\@tartibi \@autodottrue\fi
+ \ifx #1\@Alph \@autodottrue\fi
+ \ifx #1\@alph \@autodottrue\fi
+ \ifx #1\@Roman \@autodottrue\fi
+ \ifx #1\@roman \@autodottrue\fi
+ \ifx #1\romannumeral \@autodottrue\fi
+ \fi
+ \@@maybeautodot
+}
+
+
+
+
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-shellescape.sty b/macros/luatex/latex/simurgh/tex/simurgh-shellescape.sty
new file mode 100644
index 0000000000..fe24a6eb12
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-shellescape.sty
@@ -0,0 +1,10 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-shellescape}[2013/09/18 v0.01a shellescape]
+\RequirePackage{pdftexcmds}
+\newif\ifwritexviii
+\ifnum\pdf@shellescape=1\relax
+ \writexviiitrue
+\else
+\writexviiifalse
+\fi
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-tags.sty b/macros/luatex/latex/simurgh/tex/simurgh-tags.sty
new file mode 100644
index 0000000000..cda9e3333b
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-tags.sty
@@ -0,0 +1,7 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-tags}[2013/09/22 v0.01a tags]
+\@ifpackageloaded{amsmath}{}{%
+\@iftagloaded{leqno}{\RequirePackage{simurgh-leqno}}{}
+\@iftagloaded{fleqn}{\RequirePackage{simurgh-fleqn}}{}
+}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-tartibi.sty b/macros/luatex/latex/simurgh/tex/simurgh-tartibi.sty
new file mode 100644
index 0000000000..729dc7cd2d
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-tartibi.sty
@@ -0,0 +1,97 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-tartibi}[2013/09/18 v0.01a tartibi counter]
+\newcommand{\tartibi}[1]{%
+\expandafter\@tartibi\csname c@#1\endcsname%
+}
+\newcommand{\@tartibi}[1]{%
+\simurgh@numberstring@tartibi{#1}\simurgh@tartibi{صÙرم}{Ù…}%
+}
+\let\tartibinumeral\@tartibi%
+\def\simurgh@numberstring@tartibi#1#2#3#4{%
+\ifnum\number#1<\@ne%
+#3%
+\else\ifnum\number#1<1000000000 %
+\expandafter\simurgh@adadi@tartibi\expandafter{\number#1}#2%
+\else%
+\simurgh@numberoutofrange{#1}{#4}%
+\fi\fi%
+}
+\def\simurgh@adadi@tartibi#1#2{%
+\expandafter\simurgh@@adadi@tartibi%
+\ifcase%
+\ifnum#1<10 1%
+\else\ifnum#1<100 2%
+\else\ifnum#1<\@m 3%
+\else\ifnum#1<\@M 4%
+\else\ifnum#1<100000 5%
+\else\ifnum#1<1000000 6%
+\else\ifnum#1<10000000 7%
+\else\ifnum#1<100000000 8%
+\else9%
+\fi\fi\fi\fi\fi\fi\fi\fi %
+\or00000000#1% case 1: Add 8 leading zeros
+\or0000000#1% case 2: Add 7 leading zeros
+\or000000#1% case 3: Add 6 leading zeros
+\or00000#1% case 4: Add 5 leading zeros
+\or0000#1% case 5: Add 4 leading zeros
+\or000#1% case 6: Add 3 leading zeros
+\or00#1% case 7: Add 2 leading zeros
+\or0#1% case 8: Add 1 leading zero
+\or#1% case 9: Add no leading zeros
+\or%
+\@nil#2%
+\fi%
+}
+\def\simurgh@@adadi@tartibi#1#2#3#4#5#6#7\or#8\@nil#9{%
+\ifnum#1#2#3>\z@
+\simurgh@milyoongan@tartibi#1#2#3%
+\ifnum#7>\z@\ifnum#4#5#6>\z@\ Ùˆ \else\ Ùˆ \fi\else\ifnum#4#5#6>\z@\ Ùˆ \fi\fi%
+\fi%
+\ifnum#4#5#6>\z@%
+\simurgh@sadgan#4#5#6{#1#2#3}{#4#5}\simurgh@yekani%
+\ifnum#4#5#6>\@ne ‌\fi%
+هزار%
+\ifnum#7>\z@\ Ùˆ \fi%
+\fi%
+\simurgh@sadgan@tartibi#7{#4#5#6}1#9%
+}
+\def\simurgh@milyoongan@tartibi#1#2#3{%
+\ifnum#1#2#3=\@ne%
+\simurgh@sadgan@tartibi#1#2#301\simurgh@yekaniii%
+‌%
+میلیون%
+\else%
+\simurgh@sadgan#1#2#301\simurgh@yekanii%
+‌%
+میلیون%
+\fi%
+}
+\def\simurgh@sadgan@tartibi#1#2#3#4#5#6{%
+\ifnum#1>\z@%
+\ifnum#4#1>\@ne\simurgh@yekaniv#1\fi%
+صد%
+\ifnum#2#3>\z@\ Ùˆ \fi%
+\fi%
+\ifnum#2#3<20%
+\ifnum#5#2#3>\@ne\ifnum#1#2#3#4#5=10001 اول\else#6{#2#3}\fi\fi%
+\else%
+\simurgh@dahgan#2%
+\ifnum#3>\z@\ Ùˆ \simurgh@yekanv#3\fi%
+#60%
+\fi%
+}
+\def\simurgh@tartibi#1{%
+\ifcase#1م\or یکم\or دوم\or سوم\or چهارم%
+\or پنجم\or ششم\or Ù‡Ùتم\or هشتم\or نهم%
+\or دهم\or یازدهم\or دوازدهم\or سیزدهم%
+\or چهاردهم\or پانزدهم\or شانزدهم%
+\or Ù‡Ùدهم\or هجدهم\or نوزدهم\fi%
+}
+\def\simurgh@yekanv#1{%
+\ifcase#1\@empty\or یک\or دو\or سو\or چهار\or پنج\or شش%
+\or Ù‡Ùت\or هشت\or نه\or ده\or یازده\or دوازده\or سیزده%
+\or چهارده\or پانزده\or شانزده\or Ù‡Ùده%
+\or هجده\or نوزده\fi%
+}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-tools.sty b/macros/luatex/latex/simurgh/tex/simurgh-tools.sty
new file mode 100644
index 0000000000..ebe4ff4b0c
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-tools.sty
@@ -0,0 +1,507 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-tools}[2013/09/18 v0.01a programming tools]
+\providecommand{\@simurgh@saveprimitive}[2]{\begingroup\escapechar`\\\relax
+ \edef\@tempa{\string#1}\edef\@tempb{\meaning#1}%
+ \ifx\@tempa\@tempb \global\let#2#1%
+ \else
+ \edef\@tempb{\meaning#2}%
+ \ifx\@tempa\@tempb
+ \else
+ \@latex@error{Unable to properly define \string#2; primitive
+ \noexpand#1no longer primitive}\@eha
+ \fi
+ \fi
+ \endgroup}
+\def\eqnewif#1#2{%
+ \count@\escapechar \escapechar\m@ne
+ \let#1\iffalse
+ \let#2\iffalse
+ \eq@if#1#2\iftrue
+ \eq@if#1#2\iffalse
+ \escapechar\count@}
+\def\eq@if#1#2#3{%
+ \expandafter\def\csname\expandafter\@gobbletwo\string#1%
+ \expandafter\@gobbletwo\string#3\endcsname
+ {\let#1#3%
+ \let#2#3}%
+ \expandafter\def\csname\expandafter\@gobbletwo\string#2%
+ \expandafter\@gobbletwo\string#3\endcsname
+ {\let#2#3%
+ \let#1#3}}
+\newcommand*{\if@simurgh@csdef}[1]{%
+ \ifcsname#1\endcsname
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi}
+\newcommand*{\if@simurgh@csundef}[1]{%
+ \ifcsname#1\endcsname
+ \expandafter\ifx\csname#1\endcsname\relax
+ \expandafter\expandafter
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\expandafter
+ \expandafter\@secondoftwo
+ \fi
+ \else
+ \expandafter\@firstoftwo
+ \fi}
+\newcommand{\if@simurgh@def}[1]{%
+ \ifdefined#1%
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi}
+\newcommand{\if@simurgh@undef}[1]{%
+ \ifdefined#1%
+ \ifx#1\relax
+ \expandafter\expandafter
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\expandafter
+ \expandafter\@secondoftwo
+ \fi
+ \else
+ \expandafter\@firstoftwo
+ \fi}
+\newcommand{\if@simurgh@blank}[1]{% from url.sty
+ \simurgh@ifblank@i#1&&\@secondoftwo\@firstoftwo:}
+\long\def\simurgh@ifblank@i#1#2&#3#4#5:{#4}
+\newcommand{\simurgh@notblank}[1]{%
+ \simurgh@ifblank@i#1&&\@firstoftwo\@secondoftwo:}
+\newcommand{\if@simurgh@defmacro}{}
+\long\edef\if@simurgh@defmacro#1{%
+ \noexpand\expandafter\noexpand\simurgh@ifdefmacro
+ \noexpand\meaning#1\detokenize{macro}:&}
+\edef\simurgh@ifdefmacro{%
+ \def\noexpand\simurgh@ifdefmacro##1\detokenize{macro}:##2&}
+\simurgh@ifdefmacro{\simurgh@notblank{#2}}
+\newcommand*{\if@simurgh@csmacro}[1]{%
+ \if@simurgh@csdef{#1}
+ {\expandafter\if@simurgh@defmacro\csname#1\endcsname}
+ {\@secondoftwo}}
+\newcommand{\if@simurgh@defprimitive}[1]{%
+ \ifpdfprimitive#1%
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi}
+\newcommand{\if@simurgh@csprimitive}[1]{%
+ \begingroup\expandafter\expandafter\expandafter\endgroup%
+ \expandafter\ifpdfprimitive\csname#1\endcsname%
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi}
+\newcommand*{\simurgh@csdefcs}[2]{%
+\expandafter\@ifdefinable \csname#1\endcsname{%
+\expandafter\def\csname#1\expandafter\endcsname{\csname#2\endcsname}}}
+\newcommand*{\simurgh@csletcs}[2]{%
+\expandafter\@ifdefinable \csname#1\endcsname{%
+\expandafter\let\csname#1\expandafter\endcsname\csname#2\endcsname}}
+\newcommand*{\simurgh@cslet}[2]{%
+\expandafter\@ifdefinable \csname#1\endcsname{%
+\expandafter\let\csname#1\endcsname#2}}
+\newcommand{\simurgh@namelongdef}[1]{%
+ \long\expandafter\def\csname #1\endcsname}
+
+
+\protected\def\simurgh@error{\PackageError{simurgh}}
+\protected\def\simurgh@warning{\PackageWarning{simurgh}}
+\protected\def\simurgh@info{\PackageInfo{simurgh}}
+
+\newcommand*{\simurgh@newrobustcmd}{}
+\protected\def\simurgh@newrobustcmd{\@star@or@long\simurgh@new@command}
+
+\def\simurgh@new@command#1{\@testopt{\simurgh@newcommand#1}0}
+
+\def\simurgh@newcommand#1[#2]{%
+ \@ifnextchar[%]
+ {\simurgh@xargdef#1[#2]}
+ {\ifx\l@ngrel@x\relax
+ \let\l@ngrel@x\protected
+ \else
+ \protected\def\l@ngrel@x{\protected\long}%
+ \fi
+ \@argdef#1[#2]}}
+
+\long\def\simurgh@xargdef#1[#2][#3]#4{%
+ \@ifdefinable#1{%
+ \expandafter\protected
+ \expandafter\def
+ \expandafter#1%
+ \expandafter{%
+ \expandafter\@testopt
+ \csname\string#1\endcsname{#3}}%
+ \expandafter\@yargdef\csname\string#1\endcsname\tw@{#2}{#4}}}
+
+\simurgh@newrobustcmd*{\simurgh@renewrobustcmd}{\@star@or@long\simurgh@renew@command}
+
+\def\simurgh@renew@command#1{%
+ \if@simurgh@undef{#1}
+ {\simurgh@error{\string#1 undefined}\@ehc}
+ {}%
+ \let\@ifdefinable\@rc@ifdefinable
+ \simurgh@new@command#1}
+
+\simurgh@newrobustcmd*{\@tagextension}{clo}
+\simurgh@newrobustcmd*{\@iftagloaded}{\@ifl@aded\@tagextension}
+
+\simurgh@newrobustcmd*{\simurgh@providerobustcmd}{\@star@or@long\simurgh@provide@command}
+
+\def\simurgh@provide@command#1{%
+ \if@simurgh@undef{#1}
+ {\def\reserved@a{\simurgh@new@command#1}}
+ {\def\reserved@a{\simurgh@renew@command\reserved@a}}%
+ \reserved@a}
+
+\newcommand*{\simurgh@csuse}[1]{%
+ \ifcsname#1\endcsname
+ \csname#1\expandafter\endcsname
+ \fi}
+
+\newcommand{\simurgh@expandonce}[1]{%
+ \unexpanded\expandafter{#1}}
+
+\def\simurgh@protected{%
+ \let\@@protect\protect
+ \let\protect\@unexpandable@protect
+ \afterassignment\restore@protect}
+
+\simurgh@newrobustcmd{\simurgh@appto}[2]{%
+ \if@simurgh@undef{#1}
+ {\edef#1{\unexpanded{#2}}}
+ {\edef#1{\simurgh@expandonce#1\unexpanded{#2}}}}
+\simurgh@newrobustcmd{\simurgh@eappto}[2]{%
+ \if@simurgh@undef{#1}
+ {\edef#1{#2}}
+ {\edef#1{\simurgh@expandonce#1#2}}}
+\simurgh@newrobustcmd{\simurgh@gappto}[2]{%
+ \if@simurgh@undef{#1}
+ {\xdef#1{\unexpanded{#2}}}
+ {\xdef#1{\simurgh@expandonce#1\unexpanded{#2}}}}
+\simurgh@newrobustcmd{\simurgh@xappto}[2]{%
+ \if@simurgh@undef{#1}
+ {\xdef#1{#2}}
+ {\xdef#1{\simurgh@expandonce#1#2}}}
+
+\simurgh@newrobustcmd*{\simurgh@protected@eappto}{\simurgh@protected\simurgh@eappto}
+\simurgh@newrobustcmd*{\simurgh@protected@xappto}{\simurgh@protected\simurgh@xappto}
+
+\simurgh@newrobustcmd{\simurgh@preto}[2]{%
+ \if@simurgh@undef{#1}
+ {\edef#1{\unexpanded{#2}}}
+ {\edef#1{\unexpanded{#2}\simurgh@expandonce#1}}}
+\simurgh@newrobustcmd{\simurgh@epreto}[2]{%
+ \if@simurgh@undef{#1}
+ {\edef#1{#2}}
+ {\edef#1{#2\simurgh@expandonce#1}}}
+\simurgh@newrobustcmd{\simurgh@gpreto}[2]{%
+ \if@simurgh@undef{#1}
+ {\xdef#1{\unexpanded{#2}}}
+ {\xdef#1{\unexpanded{#2}\simurgh@expandonce#1}}}
+\simurgh@newrobustcmd{\simurgh@xpreto}[2]{%
+ \if@simurgh@undef{#1}
+ {\xdef#1{#2}}
+ {\xdef#1{#2\simurgh@expandonce#1}}}
+
+\simurgh@newrobustcmd*{\simurgh@protected@epreto}{\simurgh@protected\simurgh@epreto}
+\simurgh@newrobustcmd*{\simurgh@protected@xpreto}{\simurgh@protected\simurgh@xpreto}
+
+\simurgh@newrobustcmd*{\simurgh@csappto}[1]{\expandafter\simurgh@appto\csname#1\endcsname}
+\simurgh@newrobustcmd*{\simurgh@cseappto}[1]{\expandafter\simurgh@eappto\csname#1\endcsname}
+\simurgh@newrobustcmd*{\simurgh@csgappto}[1]{\expandafter\simurgh@gappto\csname#1\endcsname}
+\simurgh@newrobustcmd*{\simurgh@csxappto}[1]{\expandafter\simurgh@xappto\csname#1\endcsname}
+\simurgh@newrobustcmd*{\simurgh@protected@cseappto}{\simurgh@protected\simurgh@cseappto}
+\simurgh@newrobustcmd*{\simurgh@protected@csxappto}{\simurgh@protected\simurgh@csxappto}
+
+\simurgh@newrobustcmd*{\simurgh@cspreto}[1]{\expandafter\simurgh@preto\csname#1\endcsname}
+\simurgh@newrobustcmd*{\simurgh@csepreto}[1]{\expandafter\simurgh@epreto\csname#1\endcsname}
+\simurgh@newrobustcmd*{\simurgh@csgpreto}[1]{\expandafter\simurgh@gpreto\csname#1\endcsname}
+\simurgh@newrobustcmd*{\simurgh@csxpreto}[1]{\expandafter\simurgh@xpreto\csname#1\endcsname}
+\simurgh@newrobustcmd*{\simurgh@protected@csepreto}{\simurgh@protected\simurgh@csepreto}
+\simurgh@newrobustcmd*{\simurgh@protected@csxpreto}{\simurgh@protected\simurgh@csxpreto}
+
+\simurgh@newrobustcmd{\if@simurgh@patchable}{%
+ \simurgh@dbg@trce\if@simurgh@patchable
+ \begingroup
+ \@makeother\#%
+ \@ifstar\simurgh@ifpatchable@i\simurgh@ifpatchable}
+
+\long\def\simurgh@ifpatchable#1#2{%
+ \endgroup
+ \simurgh@dbg@init#1%
+ \if@simurgh@undef{#1}
+ {\simurgh@dbg@fail{def}\@secondoftwo}
+ {\simurgh@dbg@info{def}%
+ \if@simurgh@defmacro{#1}
+ {\simurgh@dbg@info{mac}%
+ \simurgh@ifscanable{#1}
+ {\simurgh@ifhashcheck{#2}
+ {\simurgh@dbg@info{tok}%
+ \simurgh@ifpattern#1{#2}
+ {\simurgh@dbg@info{pat}%
+ \simurgh@dbg@info{pos}\@firstoftwo}
+ {\simurgh@dbg@fail{pat}\@secondoftwo}}
+ {\simurgh@dbg@fail{hsh}\@secondoftwo}}
+ {\simurgh@dbg@fail{tok}\@secondoftwo}}
+ {\simurgh@dbg@fail{mac}\@secondoftwo}}}
+
+\long\def\simurgh@ifpatchable@i#1{%
+ \endgroup
+ \simurgh@dbg@init#1%
+ \if@simurgh@undef{#1}
+ {\simurgh@dbg@fail{def}\@secondoftwo}
+ {\simurgh@dbg@info{def}%
+ \if@simurgh@defmacro{#1}
+ {\simurgh@dbg@info{mac}%
+ \if@simurgh@defparam{#1}
+ {\simurgh@dbg@info{prm}%
+ \simurgh@ifscanable{#1}
+ {\simurgh@dbg@info{tok}%
+ \simurgh@dbg@info{pos}\@firstoftwo}
+ {\simurgh@dbg@fail{tok}\@secondoftwo}}
+ {\simurgh@dbg@info{prl}%
+ \if@simurgh@defprotected{#1}
+ {\simurgh@dbg@info{pro}}
+ {}%
+ \simurgh@dbg@info{pos}\@firstoftwo}}
+ {\simurgh@dbg@fail{mac}\@secondoftwo}}}
+
+\simurgh@newrobustcmd*{\simurgh@patchcmd}{%
+ \simurgh@dbg@trce\simurgh@patchcmd
+ \begingroup
+ \@makeother\#%
+ \simurgh@@patchcmd}
+
+\newcommand{\simurgh@@patchcmd}[4][########1]{%
+ \simurgh@ifpatchable#2{#3}
+ {\simurgh@dbg@succ{ret}%
+ \begingroup
+ \edef\simurgh@resrvda{%
+ \def\noexpand\simurgh@resrvda####1\detokenize{macro:}####2->####3&{%
+ #1\def\string\simurgh@resrvda\space####2{\noexpand\simurgh@resrvdb####3&}}%
+ \def\noexpand\simurgh@resrvdb####1\detokenize{#3}####2&{%
+ ####1\detokenize{#4}####2}%
+ \edef\noexpand\simurgh@resrvda{%
+ \noexpand\simurgh@resrvda\meaning#2&}}%
+ \simurgh@resrvda
+ \simurgh@patchcmd@scantoks\simurgh@resrvda
+ \let#2\simurgh@resrvda
+ \simurgh@undef\simurgh@resrvda
+ \@firstoftwo}
+ {\@secondoftwo}}
+
+\def\simurgh@patchcmd@scantoks#1{%
+ \edef\simurgh@resrvda{\endgroup
+ \unexpanded{\makeatletter\scantokens}{#1}%
+ \catcode\number`\@=\the\catcode`\@\relax}%
+ \simurgh@resrvda}
+
+
+\protected\def\simurgh@ifscanable#1{%
+ \begingroup
+ \edef\simurgh@resrvda{%
+ \def\noexpand\simurgh@resrvda####1\detokenize{macro}:####2->####3&{%
+ ####1\def\string\simurgh@resrvda####2{####3}}%
+ \edef\noexpand\simurgh@resrvda{\noexpand\simurgh@resrvda\meaning#1&}}%
+ \simurgh@resrvda
+ \makeatletter
+ \scantokens\expandafter{\simurgh@resrvda}%
+ \expandafter\endgroup\ifx#1\simurgh@resrvda
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi}
+
+\protected\long\def\simurgh@ifhashcheck#1{%
+ \begingroup
+ \edef\simurgh@resrvda{\detokenize{#1}}%
+ \expandafter\endgroup
+ \expandafter\simurgh@ifhashcheck@i\meaning\simurgh@resrvda&}
+
+\edef\simurgh@ifhashcheck@i#1&{%
+ \noexpand\expandafter
+ \noexpand\simurgh@ifhashcheck@ii
+ \noexpand\strip@prefix#1\string#\string#&}
+
+\edef\simurgh@ifhashcheck@ii{%
+ \def\noexpand\simurgh@ifhashcheck@ii##1\string#\string###2&}
+\simurgh@ifhashcheck@ii{\if@simurgh@blank{#2}}
+
+\protected\long\def\simurgh@ifpattern#1#2{%
+ \begingroup
+ \edef\simurgh@resrvda{%
+ \def\noexpand\simurgh@resrvda####1\detokenize{#2}####2&{%
+ \endgroup\noexpand\noexpand\noexpand\if@simurgh@blank{####2}}%
+ \edef\noexpand\simurgh@resrvda{\noexpand\simurgh@resrvda
+ \expandafter\strip@prefix\meaning#1\detokenize{#2}&}%
+ \noexpand\simurgh@resrvda}
+ \simurgh@resrvda\@secondoftwo\@firstoftwo}
+
+\newcommand{\if@simurgh@defparam}{}
+\long\edef\if@simurgh@defparam#1{%
+ \noexpand\expandafter\noexpand\simurgh@ifdefparam
+ \noexpand\meaning#1\detokenize{macro}:->&}
+\edef\simurgh@ifdefparam{%
+ \def\noexpand\simurgh@ifdefparam##1\detokenize{macro}:##2->##3&}
+\simurgh@ifdefparam{\simurgh@notblank{#2}}
+
+\newcommand{\if@simurgh@defprotected}{}
+\long\edef\if@simurgh@defprotected#1{%
+ \noexpand\expandafter\noexpand\simurgh@ifdefprotected
+ \noexpand\meaning#1\string\protected&}
+\edef\simurgh@ifdefprotected{%
+ \def\noexpand\simurgh@ifdefprotected##1\string\protected##2&}
+\simurgh@ifdefprotected{\simurgh@notblank{#2}}
+
+\simurgh@newrobustcmd{\simurgh@undef}[1]{\let#1\simurgh@undefined}
+
+\let\simurgh@dbg@trce\@gobble
+\let\simurgh@dbg@init\@gobble
+\let\simurgh@dbg@info\@gobble
+\let\simurgh@dbg@succ\@gobble
+\let\simurgh@dbg@fail\@gobble
+
+\simurgh@newrobustcmd*{\simurgh@apptocmd}{%
+ \simurgh@dbg@trce\simurgh@apptocmd
+ \begingroup
+ \@makeother\#%
+ \simurgh@hooktocmd\simurgh@append}
+
+\simurgh@newrobustcmd*{\simurgh@pretocmd}{%
+ \simurgh@dbg@trce\simurgh@pretocmd
+ \begingroup
+ \@makeother\#%
+ \simurgh@hooktocmd\simurgh@prepend}
+
+\long\def\simurgh@hooktocmd#1#2#3{%
+ \endgroup
+ \simurgh@dbg@init#2%
+ \if@simurgh@undef{#2}
+ {\simurgh@dbg@fail{def}\@secondoftwo}
+ {\simurgh@dbg@info{def}%
+ \if@simurgh@defmacro{#2}
+ {\simurgh@dbg@info{mac}%
+ \if@simurgh@defparam{#2}
+ {\simurgh@dbg@info{prm}%
+ \simurgh@ifscanable{#2}
+ {\simurgh@ifhashcheck{#3}
+ {\simurgh@dbg@info{tok}%
+ \simurgh@dbg@succ{ret}%
+ \simurgh@hooktocmd@i#1#2{#3}%
+ \@firstoftwo}
+ {\simurgh@dbg@fail{hsh}\@secondoftwo}}
+ {\simurgh@dbg@fail{tok}\@secondoftwo}}
+ {\simurgh@dbg@info{prl}%
+ \if@simurgh@defprotected{#2}
+ {\simurgh@dbg@info{pro}%
+ \simurgh@dbg@succ{red}%
+ \protected}
+ {\simurgh@dbg@succ{red}}%
+ \edef#2{#1{\simurgh@expandonce#2}{\unexpanded{#3}}}%
+ \@firstoftwo}}
+ {\simurgh@dbg@fail{mac}\@secondoftwo}}}
+
+\long\def\simurgh@hooktocmd@i#1#2#3{%
+ \begingroup
+ \edef\simurgh@resrvda{%
+ \def\noexpand\simurgh@resrvda####1\detokenize{macro}:####2->####3&{%
+ ####1\def\string\simurgh@resrvda\space####2{#1{####3}{\detokenize{#3}}}}%
+ \edef\noexpand\simurgh@resrvda{%
+ \noexpand\simurgh@resrvda\meaning#2&}}%
+ \simurgh@resrvda
+ \simurgh@patchcmd@scantoks\simurgh@resrvda
+ \let#2\simurgh@resrvda
+ \simurgh@undef\simurgh@resrvda}
+
+\long\def\simurgh@append#1#2{#1#2}
+\long\def\simurgh@prepend#1#2{#2#1}
+
+\simurgh@newrobustcmd*{\simurgh@AtEndPreamble}{\simurgh@gappto\simurgh@endpreamblehook}
+\newcommand*{\simurgh@endpreamblehook}{}
+
+\simurgh@preto\document{%
+ \endgroup
+ \let\simurgh@AtEndPreamble\@firstofone
+ \simurgh@endpreamblehook
+ \protected\def\simurgh@AtEndPreamble{\@notprerr\@gobble}%
+ \simurgh@undef\simurgh@endpreamblehook
+ \begingroup}
+
+\simurgh@newrobustcmd*{\simurgh@AfterPreamble}{\AtBeginDocument}
+\simurgh@AtEndPreamble{\let\simurgh@AfterPreamble\@firstofone}
+
+\simurgh@newrobustcmd*{\simurgh@AfterEndPreamble}{\simurgh@gappto\simurgh@afterendpreamblehook}
+\newcommand*{\simurgh@afterendpreamblehook}{}
+
+\simurgh@appto\document{%
+ \let\simurgh@AfterEndPreamble\@firstofone
+ \simurgh@afterendpreamblehook
+ \protected\def\simurgh@AfterEndPreamble{\@notprerr\@gobble}%
+ \simurgh@undef\simurgh@afterendpreamblehook
+ \ignorespaces}
+
+\AtEndDocument{\let\simurgh@AfterEndPreamble\@gobble}
+
+\simurgh@newrobustcmd*{\simurgh@AfterEndDocument}{\simurgh@gappto\simurgh@afterenddocumenthook}
+\newcommand*{\simurgh@afterenddocumenthook}{}
+
+\simurgh@patchcmd\enddocument
+ {\deadcycles}
+ {\let\simurgh@AfterEndDocument\@firstofone
+ \simurgh@afterenddocumenthook
+ \deadcycles}
+ {}
+ {\let\simurgh@@end\@@end
+ \def\@@end{%
+ \let\simurgh@AfterEndDocument\@firstofone
+ \simurgh@afterenddocumenthook
+ \simurgh@@end}}
+
+\simurgh@newrobustcmd{\simurgh@AtBeginEnvironment}[1]{%
+ \simurgh@csgappto{@begin@#1@hook}}
+
+\simurgh@patchcmd\begin
+ {\csname #1\endcsname}
+ {\simurgh@csuse{@begin@#1@hook}%
+ \csname #1\endcsname}
+ {}
+ {\simurgh@warning{%
+ Patching '\string\begin' failed!\MessageBreak
+ '\string\simurgh@AtBeginEnvironment' will not work\@gobble}}
+
+\simurgh@newrobustcmd{\simurgh@AtEndEnvironment}[1]{%
+ \simurgh@csgappto{@end@#1@hook}}
+
+\simurgh@patchcmd\end
+ {\csname end#1\endcsname}
+ {\simurgh@csuse{@end@#1@hook}%
+ \csname end#1\endcsname}
+ {}
+ {\simurgh@warning{%
+ Patching '\string\end' failed!\MessageBreak
+ '\string\simurgh@AtEndEnvironment' will not work\@gobble}}
+
+\simurgh@newrobustcmd{\simurgh@BeforeBeginEnvironment}[1]{%
+ \simurgh@csgappto{@beforebegin@#1@hook}}
+
+\simurgh@pretocmd\begin
+ {\simurgh@csuse{@beforebegin@#1@hook}}
+ {}
+ {\simurgh@warning{%
+ Patching '\string\begin' failed!\MessageBreak
+ '\string\simurgh@BeforeBeginEnvironment' will not work\@gobble}}
+
+\simurgh@newrobustcmd{\simurgh@AfterEndEnvironment}[1]{%
+ \simurgh@csgappto{@afterend@#1@hook}}
+
+\simurgh@patchcmd\end
+ {\if@ignore}
+ {\simurgh@csuse{@afterend@#1@hook}%
+ \if@ignore}
+ {}
+ {\simurgh@warning{%
+ Patching '\string\end' failed!\MessageBreak
+ '\string\simurgh@AfterEndEnvironment' will not work\@gobble}}
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-unibidi-core.lua b/macros/luatex/latex/simurgh/tex/simurgh-unibidi-core.lua
new file mode 100644
index 0000000000..f4a10c5448
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-unibidi-core.lua
@@ -0,0 +1,375 @@
+if not modules then modules = { } end modules ['simurgh-unibidi-core'] = {
+ version = 0.01,
+ comment = "unicode bidi",
+ author = "Vafa Khalighi",
+ copyright = "Vafa Khalighi",
+ license = "see simurgh package documentation",
+ derived = "derived from typo-dha by Hans Hagen"
+}
+
+-- Some analysis:
+--
+-- 1. Assuming the reading- vs word-order distinction (bidi-char types) is governing;
+-- 2. Assuming that 'PARSI' represents an actual parsi string in raw input order, not word-order;
+-- 3. Assuming that 'ISRAP' represent the correct RL word order;
+--
+-- Then we have, with input: LATIN PARSI
+--
+-- \textdir TLT LATIN PARSI => LATIN ISRAP
+-- \textdir TRT LATIN PARSI => LATIN ISRAP
+-- \textdir TRT LRO LATIN PARSI => LATIN PARSI
+-- \textdir TLT LRO LATIN PARSI => LATIN PARSI
+-- \textdir TLT RLO LATIN PARSI => NITAL PARSI
+-- \textdir TRT RLO LATIN PARSI => NITAL PARSI
+
+-- elseif d == "es" then -- European Number Separator
+-- elseif d == "et" then -- European Number Terminator
+-- elseif d == "cs" then -- Common Number Separator
+-- elseif d == "nsm" then -- Non-Spacing Mark
+-- elseif d == "bn" then -- Boundary Neutral
+-- elseif d == "b" then -- Paragraph Separator
+-- elseif d == "s" then -- Segment Separator
+-- elseif d == "ws" then -- Whitespace
+-- elseif d == "on" then -- Other Neutrals
+
+-- todo : delayed inserts here
+-- todo : get rid of local functions here
+-- beware: math adds whatsits afterwards so that will mess things up
+-- todo : use new dir functions
+-- todo : make faster
+-- todo : move dir info into nodes
+-- todo : swappable tables and floats i.e. start-end overloads (probably loop in builders)
+-- todo : check if we still have crashes in luatex when non-matched (used to be the case)
+
+local nodes, node = nodes, node
+
+local trace_directions = false trackers.register("typesetters.directions.default", function(v) trace_directions = v end)
+
+local report_directions = logs.reporter("typesetting","text directions")
+
+
+local insert_node_before = nodes.insert_before
+local insert_node_after = nodes.insert_after
+local remove_node = nodes.remove
+local end_of_math = nodes.end_of_math
+
+local nodepool = nodes.pool
+
+local nodecodes = nodes.nodecodes
+local whatcodes = nodes.whatcodes
+local mathcodes = nodes.mathcodes
+
+local glyph_code = nodecodes.glyph
+local whatsit_code = nodecodes.whatsit
+local math_code = nodecodes.math
+local penalty_code = nodecodes.penalty
+local kern_code = nodecodes.kern
+local glue_code = nodecodes.glue
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+
+local localpar_code = whatcodes.localpar
+local dir_code = whatcodes.dir
+
+local new_textdir = nodepool.textdir
+
+local hasbit = number.hasbit
+local formatters = string.formatters
+local insert = table.insert
+
+local fonthashes = fonts.hashes
+local fontdata = fonthashes.identifiers
+local fontchar = fonthashes.characters
+
+local chardirections = characters.directions
+local charmirrors = characters.mirrors
+local charclasses = characters.textclasses
+
+local directions = typesetters.directions
+local getglobal = directions.getglobal
+
+local a_state = attributes.private('state')
+local a_directions = attributes.private('directions')
+
+local strip = false
+
+local s_isol = fonts.analyzers.states.isol
+
+local function stopdir(finish)
+ return new_textdir(finish == "TRT" and "-TRT" or "-TLT")
+end
+
+local function startdir(finish)
+ return new_textdir(finish == "TRT" and "+TRT" or "+TLT")
+end
+
+local function process(namespace,attribute,start)
+
+ local head = start
+
+ local current = head
+ local inserted = nil
+ local finish = nil
+ local autodir = 0
+ local embedded = 0
+ local override = 0
+ local pardir = 1
+ local textdir = 1
+ local done = false
+ local finished = nil
+ local finidir = nil
+ local stack = { }
+ local top = 0
+ local obsolete = { }
+ local lro = false
+ local lro = false
+ local prevattr = false
+ local fences = { }
+
+ local function finish_auto_before()
+ head, inserted = insert_node_before(head,current,stopdir(finish))
+ finished, finidir, autodir = inserted, finish, 0
+ finish, done = nil, true
+ end
+
+ local function finish_auto_after()
+ head, current = insert_node_after(head,current,stopdir(finish))
+ finished, finidir, autodir = current, finish, 0
+ finish, done = nil, true
+ end
+
+ local function force_auto_left_before(direction)
+ if finish then
+ head, inserted = insert_node_before(head,current,stopdir(finish))
+ finished = inserted
+ finidir = finish
+ end
+ if embedded >= 0 then
+ finish, autodir = "TLT", 1
+ else
+ finish, autodir = "TRT", -1
+ end
+ done = true
+ if finidir == finish then
+ head = remove_node(head,finished,true)
+ else
+ head, inserted = insert_node_before(head,current,startdir(finish))
+ end
+ end
+
+ local function force_auto_right_before(direction)
+ if finish then
+ head, inserted = insert_node_before(head,current,stopdir(finish))
+ finished = inserted
+ finidir = finish
+ end
+ if embedded <= 0 then
+ finish, autodir, done = "TRT", -1
+ else
+ finish, autodir, done = "TLT", 1
+ end
+ done = true
+ if finidir == finish then
+ head = remove_node(head,finished,true)
+ else
+ head, inserted = insert_node_before(head,current,startdir(finish))
+ end
+ end
+
+ local function nextisright(current)
+ current = current.next
+ local id = current.id
+ if id == glyph_code then
+ local character = current.char
+ local direction = chardirections[character]
+ return direction == "r" or direction == "al" or direction == "an"
+ end
+ end
+
+ local function previsright(current)
+ current = current.prev
+ local id = current.id
+ if id == glyph_code then
+ local char = current.char
+ local direction = chardirections[character]
+ return direction == "r" or direction == "al" or direction == "an"
+ end
+ end
+
+ while current do
+ local id = current.id
+ if id == math_code then
+ current = end_of_math(current.next).next
+ else
+ local attr = current[attribute]
+ if attr and attr > 0 and attr ~= prevattr then
+ if not getglobal(a) then
+ lro, rlo = false, false
+ end
+ prevattr = attr
+ end
+ if id == glyph_code then
+ if attr and attr > 0 then
+ local character = current.char
+ local direction = chardirections[character]
+ local reversed = false
+ if rlo or override > 0 then
+ if direction == "l" then
+ direction = "r"
+ reversed = true
+ end
+ elseif lro or override < 0 then
+ if direction == "r" or direction == "al" then
+ current[a_state] = s_isol
+ direction = "l"
+ reversed = true
+ end
+ end
+ if direction == "on" then
+ local mirror = charmirrors[character]
+ if mirror and fontchar[current.font][mirror] then
+ local class = charclasses[character]
+ if class == "open" then
+ if nextisright(current) then
+ if autodir >= 0 then
+ force_auto_right_before(direction)
+ end
+ current.char = mirror
+ done = true
+ elseif autodir < 0 then
+ current.char = mirror
+ done = true
+ else
+ mirror = false
+ end
+ local fencedir = autodir == 0 and textdir or autodir
+ fences[#fences+1] = fencedir
+ elseif class == "close" and #fences > 0 then
+ local fencedir = fences[#fences]
+ fences[#fences] = nil
+ if fencedir < 0 then
+ current.char = mirror
+ done = true
+ force_auto_right_before(direction)
+ else
+ mirror = false
+ end
+ elseif autodir < 0 then
+ current.char = mirror
+ done = true
+ else
+ mirror = false
+ end
+ end
+ elseif direction == "l" then
+ if autodir <= 0 then -- could be option
+ force_auto_left_before(direction)
+ end
+ elseif direction == "r" then
+ if autodir >= 0 then
+ force_auto_right_before(direction)
+ end
+ elseif direction == "en" then -- european number
+ if autodir <= 0 then -- could be option
+ force_auto_left_before(direction)
+ end
+ elseif direction == "al" then -- arabic number
+ if autodir >= 0 then
+ force_auto_right_before(direction)
+ end
+ elseif direction == "an" then -- arabic number
+ if autodir >= 0 then
+ force_auto_right_before(direction)
+ end
+ elseif direction == "lro" then -- Left-to-Right Override -> right becomes left
+ top = top + 1
+ stack[top] = { override, embedded }
+ override = -1
+ obsolete[#obsolete+1] = current
+ elseif direction == "rlo" then -- Right-to-Left Override -> left becomes right
+ top = top + 1
+ stack[top] = { override, embedded }
+ override = 1
+ obsolete[#obsolete+1] = current
+ elseif direction == "lre" then -- Left-to-Right Embedding -> TLT
+ top = top + 1
+ stack[top] = { override, embedded }
+ embedded = 1
+ obsolete[#obsolete+1] = current
+ elseif direction == "rle" then -- Right-to-Left Embedding -> TRT
+ top = top + 1
+ stack[top] = { override, embedded }
+ embedded = -1
+ obsolete[#obsolete+1] = current
+ elseif direction == "pdf" then -- Pop Directional Format
+ if top > 0 then
+ local s = stack[top]
+ override, embedded = s[1], s[2]
+ top = top - 1
+ end
+ obsolete[#obsolete+1] = current
+ end
+ else
+ -- we do nothing
+ end
+ elseif id == whatsit_code then
+ local subtype = current.subtype
+ if subtype == localpar_code then
+ local dir = current.dir
+ if dir == 'TRT' then
+ autodir = -1
+ elseif dir == 'TLT' then
+ autodir = 1
+ end
+ pardir = autodir
+ textdir = pardir
+ elseif subtype == dir_code then
+ -- todo: also treat as lro|rlo and stack
+ if finish then
+ finish_auto_before()
+ end
+ local dir = current.dir
+ if dir == "+TRT" then
+ finish, autodir = "TRT", -1
+ elseif dir == "-TRT" then
+ finish, autodir = nil, 0
+ elseif dir == "+TLT" then
+ finish, autodir = "TLT", 1
+ elseif dir == "-TLT" then
+ finish, autodir = nil, 0
+ end
+ textdir = autodir
+ else
+ if finish then
+ finish_auto_before()
+ end
+ end
+ elseif finish then
+ finish_auto_before()
+ end
+ local cn = current.next
+ if cn then
+ -- we're okay
+ elseif finish then
+ finish_auto_after()
+ end
+ current = cn
+ end
+ end
+
+ if done and strip then
+ local n = #obsolete
+ if n > 0 then
+ for i=1,n do
+ remove_node(head,obsolete[i],true)
+ end
+ report_directions("%s character nodes removed",n)
+ end
+ end
+
+ return head, done
+
+end
+
+directions.installhandler(interfaces.variables.default,process)
+
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-unibidi-ini.lua b/macros/luatex/latex/simurgh/tex/simurgh-unibidi-ini.lua
new file mode 100644
index 0000000000..983a3a077c
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-unibidi-ini.lua
@@ -0,0 +1,219 @@
+if not modules then modules = { } end modules ['simurgh-unibidi-ini'] = {
+ version = 0.01,
+ comment = "unicode bidi",
+ author = "Vafa Khalighi",
+ copyright = "Vafa Khalighi",
+ license = "see simurgh package documentation",
+ derived = "derived from typo-dir by Hans Hagen"
+}
+
+-- When we started with this, there were some issues in luatex so we needed to take care of
+-- intereferences. Some has been improved but we stil might end up with each node having a
+-- dir property. Now, the biggest problem is that there is an official bidi algorithm but
+-- some searching on the web shows that there are many confusing aspects and therefore
+-- proposals circulate about (sometimes imcompatible ?) improvements. In the end it all boils
+-- down to the lack of willingness to tag an input source. Of course tagging of each number
+-- and fenced strip is somewhat over the top, but now it has to be captured in logic. Texies
+-- normally have no problem with tagging but we need to handle any input. So, what we have
+-- done here (over the years) is starting from what we expect to see happen, especially with
+-- respect to punctation, numbers and fences. Eventually alternative algorithms will be provides
+-- so that users can choose (the reason why suggestion sfor improvements circulate on the web
+-- is that it is non trivial to predict the expected behaviour so one hopes that the ditor
+-- and the rest of the machinery match somehow. Anyway, the fun of tex is that it has no hard
+-- coded behavior. And ... we also want to have more debugging and extras and ... so we want
+-- a flexible approach.
+
+local next, type = next, type
+local format, insert, sub, find, match = string.format, table.insert, string.sub, string.find, string.match
+local utfchar = utf.char
+local formatters = string.formatters
+
+local nodes, node = nodes, node
+
+local trace_textdirections = false trackers.register("typesetters.directions.text", function(v) trace_textdirections = v end)
+local trace_mathdirections = false trackers.register("typesetters.directions.math", function(v) trace_mathdirections = v end)
+local trace_directions = false trackers.register("typesetters.directions", function(v) trace_textdirections = v trace_mathdirections = v end)
+
+local report_textdirections = logs.reporter("typesetting","text directions")
+local report_mathdirections = logs.reporter("typesetting","math directions")
+
+
+
+
+local traverse_id = node.traverse_id
+local insert_node_before = node.insert_before
+local insert_node_after = node.insert_after
+local remove_node = nodes.remove
+local end_of_math = nodes.end_of_math
+
+local texsetattribute = tex.setattribute
+local texsetcount = tex.setcount
+local unsetvalue = attributes.unsetvalue
+
+local hasbit = number.hasbit
+
+local nodecodes = nodes.nodecodes
+local whatcodes = nodes.whatcodes
+local mathcodes = nodes.mathcodes
+
+local tasks = nodes.tasks
+
+local glyph_code = nodecodes.glyph
+local whatsit_code = nodecodes.whatsit
+local math_code = nodecodes.math
+local penalty_code = nodecodes.penalty
+local kern_code = nodecodes.kern
+local glue_code = nodecodes.glue
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+
+local localpar_code = whatcodes.localpar
+local dir_code = whatcodes.dir
+
+local nodepool = nodes.pool
+
+local new_textdir = nodepool.textdir
+
+local fonthashes = fonts.hashes
+local fontdata = fonthashes.identifiers
+local fontchar = fonthashes.characters
+
+local chardirections = characters.directions
+local charmirrors = characters.mirrors
+local charclasses = characters.textclasses
+
+local directions = typesetters.directions or { }
+typesetters.directions = directions
+
+local a_state = attributes.private('state')
+local a_directions = attributes.private('directions')
+local a_mathbidi = attributes.private('mathbidi')
+
+local strip = false
+
+local s_isol = fonts.analyzers.states.isol
+
+local variables = interfaces.variables
+local v_global = variables["global"]
+local v_local = variables["local"]
+local v_on = variables.on
+local v_yes = variables.yes
+
+local m_enabled = 2^6 -- 64
+local m_global = 2^7
+local m_fences = 2^8
+
+local handlers = { }
+local methods = { }
+local lastmethod = 0
+
+local function installhandler(name,handler)
+ local method = methods[name]
+ if not method then
+ lastmethod = lastmethod + 1
+ method = lastmethod
+ methods[name] = method
+ end
+ handlers[method] = handler
+ return method
+end
+
+directions.handlers = handlers
+directions.installhandler = installhandler
+
+local function tomode(specification)
+ local scope = specification.scope
+ local mode
+ if scope == v_global or scope == v_on then
+ mode = m_enabled + m_global
+ elseif scope == v_local then
+ mode = m_enabled
+ else
+ return 0
+ end
+ local method = methods[specification.method]
+ if method then
+ mode = mode + method
+ else
+ return 0
+ end
+ if specification.fences == v_yes then
+ mode = mode + m_fences
+ end
+ return mode
+end
+
+local function getglobal(a)
+ return a and a > 0 and hasbit(a,m_global)
+end
+
+local function getfences(a)
+ return a and a > 0 and hasbit(a,m_fences)
+end
+
+local function getmethod(a)
+ return a and a > 0 and a % m_enabled or 0
+end
+
+directions.tomode = tomode
+directions.getglobal = getglobal
+directions.getfences = getfences
+directions.getmethod = getmethod
+directions.installhandler = installhandler
+
+
+function commands.getbidimode(specification)
+ context(tomode(specification)) -- hash at tex end
+end
+
+local enabled = false
+
+local starttiming = statistics.starttiming
+local stoptiming = statistics.stoptiming
+
+function directions.process(namespace,attribute,head) -- for the moment nodes and not nuts
+ if not head.next then
+ return head, false
+ end
+ local attr = head[a_directions]
+ if not attr or attr == 0 then
+ return head, false
+ end
+ local method = getmethod(attr)
+ local handler = handlers[method]
+ if not handler then
+ return head, false
+ end
+ starttiming(directions)
+ local head, done = handler(namespace,attribute,head)
+ stoptiming(directions)
+ return head, done
+end
+
+
+-- function directions.enable()
+-- tasks.enableaction("processors","directions.handler")
+-- end
+
+function directions.set(n) -- todo: names and numbers
+ if not enabled then
+ if trace_textdirections then
+ report_textdirections("enabling directions handler")
+ end
+ tasks.enableaction("processors","typesetters.directions.handler")
+ enabled = true
+ end
+ if not n or n == 0 then
+ n = unsetvalue
+ -- maybe tracing
+ end
+ texsetattribute(a_directions,n)
+end
+
+commands.setdirection = directions.set
+
+directions.handler = nodes.installattributehandler {
+ name = "directions",
+ namespace = directions,
+ processor = directions.process,
+}
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-unibidi-math.lua b/macros/luatex/latex/simurgh/tex/simurgh-unibidi-math.lua
new file mode 100644
index 0000000000..edc4750f36
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-unibidi-math.lua
@@ -0,0 +1,152 @@
+if not modules then modules = { } end modules ['simurgh-unibidi-math'] = {
+ version = 0.01,
+ comment = "unicode bidi (numbers) in mathematics",
+ author = "Vafa Khalighi",
+ copyright = "Vafa Khalighi",
+ license = "see simurgh package documentation",
+ derived = "derived from math-dir by Hans Hagen"
+}
+
+-- As I'm wrapping up the updated math support (for CTX/TUG 2013) I wondered about numbers in
+-- r2l math mode. Googling lead me to TUGboat, Volume 25 (2004), No. 2 where I see numbers
+-- running from left to right. Makes me wonder how far we should go. And as I was looking
+-- into bidi anyway, it's a nice distraction.
+--
+-- I first tried to hook something into noads but that gets pretty messy due to indirectness
+-- char noads. If needed, I'll do it that way. With regards to spacing: as we can assume that
+-- only numbers are involved we can safely swap them and the same is true for mirroring. But
+-- anyway, I'm not too happy with this solution so eventually I'll do something with noads (as
+-- an alternative method). Yet another heuristic approach.
+
+local nodes, node = nodes, node
+
+local trace_directions = false trackers.register("typesetters.directions.math", function(v) trace_directions = v end)
+
+local report_directions = logs.reporter("typesetting","math directions")
+
+local insert_node_before = nodes.insert_before
+local insert_node_after = nodes.insert_after
+
+local nodecodes = nodes.nodecodes
+local tasks = nodes.tasks
+
+local glyph_code = nodecodes.glyph
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+
+local nodepool = nodes.pool
+
+local new_textdir = nodepool.textdir
+
+local chardirections = characters.directions
+local charmirrors = characters.mirrors
+local charclasses = characters.textclasses
+
+local directions = typesetters.directions or { }
+
+local a_mathbidi = attributes.private('mathbidi')
+
+local function processmath(head)
+ local current = head
+ local done = false
+ local start = nil
+ local stop = nil
+ local function capsulate()
+ head = insert_node_before(head,start,new_textdir("+TLT"))
+ insert_node_after(head,stop,new_textdir("-TLT"))
+ if trace_directions then
+ report_directions("reversed: %s",nodes.listtoutf(start,false,false,stop))
+ end
+ done = true
+ start = false
+ stop = nil
+ end
+ while current do
+ local id = current.id
+ if id == glyph_code then
+ local char = current.char
+ local cdir = chardirections[char]
+ if cdir == "en" or cdir == "an" then -- we could check for mathclass punctuation
+ if not start then
+ start = current
+ end
+ stop = current
+ else
+ if not start then
+ -- nothing
+ elseif start == stop then
+ start = nil
+ else
+ capsulate()
+ end
+ if cdir == "on" then
+ local mirror = charmirrors[char]
+ if mirror then
+ local class = charclasses[char]
+ if class == "open" or class == "close" then
+ current.char = mirror
+ if trace_directions then
+ report_directions("mirrored: %C to %C",char,mirror)
+ end
+ done = true
+ end
+ end
+ end
+ end
+ elseif not start then
+ -- nothing
+ elseif start == stop then
+ start = nil
+ else
+ capsulate(head,start,stop)
+ -- math can pack things into hlists .. we need to make sure we don't process
+ -- too often: needs checking
+ if id == hlist_code or id == vlist_code then
+ local list, d = processmath(current.list)
+ current.list = list
+ if d then
+ done = true
+ end
+ end
+ end
+ current = current.next
+ end
+ if not start then
+ -- nothing
+ elseif start == stop then
+ -- nothing
+ else
+ capsulate()
+ end
+ return head, done
+end
+
+local enabled = false
+
+function directions.processmath(head) -- style, penalties
+ if enabled then
+ local a = head[a_mathbidi]
+ if a and a > 0 then
+ return processmath(head)
+ end
+ end
+ return head, false
+end
+
+function directions.setmath(n)
+ if not enabled and n and n > 0 then
+ if trace_directions then
+ report_directions("enabling directions handler")
+ end
+ tasks.enableaction("math","typesetters.directions.processmath")
+ enabled = true
+ end
+end
+
+commands.setmathdirection = directions.setmath
+
+-- directions.mathhandler = nodes.installattributehandler {
+-- name = "directions",
+-- namespace = directions,
+-- processor = directions.processmath,
+-- }
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-unibidi.lua b/macros/luatex/latex/simurgh/tex/simurgh-unibidi.lua
new file mode 100644
index 0000000000..4b62c06561
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-unibidi.lua
@@ -0,0 +1,319 @@
+local err, warn, info = luatexbase.provides_module {
+ name = "simurgh-unibidi",
+ version = 0.01,
+ comment = "unicode bidi",
+ author = "Vafa Khalighi",
+ copyright = "Vafa Khalighi",
+ license = "see simurgh package documentation",
+ derived = "derived from import-typo-dir by Philipp Gesang"
+}
+
+info "unicode bidi"
+
+
+
+
+
+
+require "lualibs" -- we need the extended set
+
+local texsprint = tex.sprint
+local stringformat = string.format
+local tableconcat = table.concat
+local copynode = node.copy
+
+-----------------------------------------------------------------------
+--- prepare
+-----------------------------------------------------------------------
+
+--- 1) wrap Luatexbase attribute handler in a Context style interface
+
+attributes = attributes or { }
+local texsetattribute = tex.setattribute
+
+
+local hidden = {
+ state = luatexbase.new_attribute ("typo-dir:state", true),
+ directions = luatexbase.new_attribute ("typo-dir:directions", true),
+ mathbidi = luatexbase.new_attribute ("typo-dir:mathbidi", true),
+}
+
+local a_directions = hidden.directions
+
+attributes.private = attributes.private or function (attr_name)
+ local res = hidden [attr_name]
+ if not res then
+ res = luatexbase.new_attribute (attr_name)
+ end
+ return res
+end
+
+local unsetvalue = luatexbase.get_unset_value ()
+attributes.unsetvalue = unsetvalue
+
+--- 2) simulate the multilingual interface; safe to purge afterwards
+--- since Context uses local copies
+
+interfaces = interfaces or { }
+interfaces.variables = interfaces.variables or { }
+interfaces.variables.global = "global"
+interfaces.variables["local"] = "local"
+interfaces.variables.default = "default"
+interfaces.variables.on = "on"
+interfaces.variables.yes = "yes"
+
+--- 3) node tasks; we don’t have real node processors so we will need
+--- to set up a makeshift interface
+
+nodes.tasks = nodes.tasks or { }
+nodes.tasks.enableaction = function () end
+
+--- 4) commands namespace
+
+commands = commands or { } -- already present due to luaotfload-extrablibs
+
+--- 5) typesetters namespace
+---
+
+-- require "typo-krn"
+
+typesetters = typesetters or { }
+
+--- 6) the Context namespace; cannot be cleaned up without breaking
+--- things; srsly there needs to be a non-Context equivalent for
+--- this
+
+context = context or { }
+
+setmetatable (context, {
+
+ --- this is quite primitive and considerably less functional than
+ --- the real deal as defined in cldf-ini.lua, but we already get
+ --- quite far with this reduced version
+
+ __index = function (t, k)
+
+ if k == "sprint" then
+ return function (...) texsprint (...) end
+
+ elseif type (k) == "string" then
+ local command = [[\]] .. k
+ return function (...)
+ local res = { command }
+ for i = 1, select ("#", ...) do
+ --- just simple grouped arguments
+ res [#res + 1] = "{"
+ res [#res + 1] = select (i, ...)
+ res [#res + 1] = "}"
+ end
+ texsprint (tableconcat (res))
+ end
+
+ else
+ return context
+ end
+ end,
+
+ __call = function (t, fmt, first, ...)
+
+ if t == nil or fmt == nil then
+ return
+ end
+
+ local tf = type (fmt)
+
+ if tf == "string" then
+ if first then
+ texsprint (-1, stringformat (fmt, first, ...))
+ else
+ texsprint (-1, fmt)
+ end
+ elseif tf == "function" then
+ texsprint (-1, fmt (first, ...))
+ elseif first then --- and so on,
+ texsprint (-1, tostring (fmt), first, ...)
+ else
+ texsprint (-1, tostring (fmt))
+ end
+ end,
+})
+
+--- 7) catcodes namespace
+
+catcodes = catcodes or { }
+catcodes.numbers = catcodes.numbers or { }
+catcodes.numbers.ctxcatcodes = -1
+
+--- 8) whatsit prototype; expected to be present in the nodepool
+
+local n_textdir = node.new (node.id "whatsit", nodes.whatsitcodes.dir)
+nodes.pool = nodes.pool or { }
+
+nodes.pool.textdir = function (dir)
+ local n = copynode (n_textdir)
+ n.dir = dir
+ return n
+end
+
+--- 9) node identifiers
+
+nodes.nodecodes = table.mirrored (nodes.nodecodes) --> convenience
+
+----------------------------------------------------------------------
+--- import
+-----------------------------------------------------------------------
+
+if not characters.directions then
+ require "simurgh-char-def" --> characters.data (unicode)
+ require "simurgh-char-ini" --> characters.*
+end
+--- the next three used to share “typo-dir.lua†before it was split
+require "simurgh-unibidi-ini" --> typesetters.directions
+require "simurgh-unibidi-core" --> typesetters.directions
+require "simurgh-unibidi-math" --> typesetters.directions
+
+-----------------------------------------------------------------------
+--- wrappers
+-----------------------------------------------------------------------
+
+--- we use the *packagedata* namespace which should become canonical
+--- anyways; also we keep a copy of typesetters.directions in a
+--- subtable
+
+packagedata = packagedata or { }
+local directions = typesetters.directions
+local typo_dir = { directions = directions }
+packagedata.typo_dir = typo_dir
+local directionprocessor = directions.process
+local mathdirectionprocessor = directions.processmath
+local processorid = "typesetters.directions"
+
+--- emulate node tasks capability; we override the original definitions
+--- of set() and setmath() with surrogates that work with Luatexbase
+--- callback handlers
+
+directions.set = nil
+directions.setmath = nil
+
+
+--- we need to track which callbacks the node processor is hooked
+--- into since we lack the combined version Context has
+
+local registered_as = { } --- procname -> callbacks
+
+
+--- (node_t -> node_t) -> string -> string list -> bool
+
+local add_processor = function (processor, name, ...)
+
+ for i=1, select ("#", ...) do
+ local callback = select (i, ...)
+ --- *IMPORTANT* the processor must be inserted at the top,
+ --- i.e. with a priority higher than any other callback!
+ luatexbase.add_to_callback (callback, processor, name, 1)
+ end
+
+ registered_as [name] = { ... }
+ return true
+
+end
+
+
+--- string -> bool
+
+local remove_processor = function (name)
+
+ local callbacks = registered_as [name]
+
+ if callbacks then
+ for i=1, #callbacks do
+ luatexbase.remove_from_callback (callbacks [i], name)
+ end
+ return true
+ end
+
+ return false
+end
+
+--- we use the same callbacks as a node processor in Context
+--- unit -> bool
+
+local enabledirectionprocessor = function (math)
+
+ local processor
+
+ if math == true then
+ processor = function (hd)
+ --- different signature from the normal one
+ return mathdirectionprocessor (hd)
+ end
+ else
+ processor = function (hd)
+ return directionprocessor ("directions", a_directions, hd)
+ end
+ end
+
+ return add_processor (processor,
+ processorid,
+ "pre_linebreak_filter",
+ "hpack_filter")
+end
+
+typo_dir.enable = enabledirectionprocessor
+
+
+--- unit -> bool
+local disabledirectionprocessor = function ( )
+ return remove_processor (processorid)
+end
+
+typo_dir.disable = disabledirectionprocessor
+
+
+local active = false --- activation state of direction processor
+
+typo_dir.set = function (n)
+
+ if not n or n == 0 then
+ n = unsetvalue
+ end
+
+ if not active then
+ info ("Installing simurgh direction handler (%d).", n)
+ enabledirectionprocessor ()
+ active = true
+ end
+
+ texsetattribute (a_directions, n)
+end
+
+
+local active = false --- activation state of math direction processor
+
+typo_dir.setmath = function (n)
+
+ if not active and n and n > 0 then
+ info ("Installing simurgh math direction handler (%d).", n)
+ enabledirectionprocessor (true)
+ active = true
+ end
+end
+
+typo_dir.getbidimode = directions.getbidimode
+
+typo_dir.getbidimode = function (specification)
+ context (directions.tomode (specification))
+end
+
+-----------------------------------------------------------------------
+--- clean
+-----------------------------------------------------------------------
+
+attributes.private = nil
+attributes = nil
+interfaces.variables = nil
+interfaces = nil
+nodes.tasks = nil
+
+collectgarbage "collect"
+
diff --git a/macros/luatex/latex/simurgh/tex/simurgh-unibidi.sty b/macros/luatex/latex/simurgh/tex/simurgh-unibidi.sty
new file mode 100644
index 0000000000..575c994736
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh-unibidi.sty
@@ -0,0 +1,23 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh-unibidi}[2013/09/18 v0.01a unicode bidi]
+\RequireLuaModule {simurgh-unibidi}
+\simurgh@newrobustcmd*{\simurgh@unibidi@cs}[1]{\directlua {packagedata.typo_dir.#1}}
+\simurgh@newrobustcmd*{\simurgh@unibidi@setdir}[1]{\simurgh@unibidi@cs{set (#1)}}
+\simurgh@newrobustcmd*{\simurgh@unibidi@setmode}[1]{% scope, method, fences
+ \if@simurgh@csundef{simurgh@unibidi@currentmode}{%
+ \simurgh@newrobustcmd*{\simurgh@unibidi@currentmode}{\simurgh@unibidi@cs{getbidimode {
+ scope = [[#1]],
+ method = [[default]],
+ fences = [[yes]]
+ }}}%
+ }{%
+ \simurgh@renewrobustcmd*{\simurgh@unibidi@currentmode}{\simurgh@unibidi@cs{getbidimode {
+ scope = [[#1]],
+ method = [[default]],
+ fences = [[yes]]
+ }}}%
+ }%
+ \simurgh@unibidi@setdir{\number\simurgh@unibidi@currentmode}%
+}
+
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/simurgh/tex/simurgh.sty b/macros/luatex/latex/simurgh/tex/simurgh.sty
new file mode 100644
index 0000000000..2658f47682
--- /dev/null
+++ b/macros/luatex/latex/simurgh/tex/simurgh.sty
@@ -0,0 +1,93 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{simurgh}[2013/09/22 v0.01b parsi typesetting]
+\RequirePackage{xkeyval}
+\RequirePackage{simurgh-tools}
+\RequirePackage{simurgh-chkeng}
+\RequirePackage{simurgh-shellescape}
+\RequirePackage{fontspec}
+\RequirePackage{simurgh-fonts}
+\RequirePackage{simurgh-jalalical}
+\RequirePackage{simurgh-mathdigitspec}
+\RequirePackage{simurgh-bidi}
+\RequirePackage{simurgh-unibidi}
+\RequirePackage{simurgh-cptns}
+\RequirePackage{simurgh-counters}
+\RequirePackage{simurgh-ltx}
+\RequirePackage{simurgh-tags}
+\RequirePackage{simurgh-clss}
+\RequirePackage{simurgh-pkgs}
+\RequirePackage{simurgh-loader}
+
+
+\define@choicekey{simurgh.sty}{maindirection}[\simurgh@tempa\simurgh@tempb]{righttoleft,lefttoright}{%
+ \ifcase\simurgh@tempb\relax
+ \@RTLtrue%
+ \pagedir TRT%
+ \bodydir TRT%
+ \pardir TRT%
+ \textdir TRT%
+ \or
+ \@RTLfalse%
+ \pagedir TLT%
+ \bodydir TLT%
+ \pardir TLT%
+ \textdir TLT%
+ \fi}
+
+\define@choicekey{simurgh.sty}{mathdirection}[\simurgh@tempa\simurgh@tempb]{righttoleft,lefttoright}{%
+ \ifcase\simurgh@tempb\relax
+ \mathdir TRT%
+ \or
+ \mathdir TLT%
+ \fi}
+
+
+\define@choicekey{simurgh.sty}{mathdigits}[\simurgh@tempa\simurgh@tempb]{automatic,default,parsi}{%
+ \ifcase\simurgh@tempb\relax
+ \AutoMathDigits%
+ \or
+ \DefaultMathDigits%
+ \or
+ \ParsiMathDigits%
+ \fi}
+
+\define@choicekey{simurgh.sty}{footnoterule}[\simurgh@tempa\simurgh@tempb]{automatic,left,right,split,textwidth}{%
+ \ifcase\simurgh@tempb\relax
+ \autofootnoterule%
+ \or
+ \leftfootnoterule%
+ \or
+ \rightfootnoterule%
+ \or
+ \SplitFootnoteRule%
+ \or
+ \textwidthfootnoterule%
+ \fi}
+
+\define@choicekey{simurgh.sty}{footnotedirection}[\simurgh@tempa\simurgh@tempb]{righttoleft,lefttoright}{%
+ \ifcase\simurgh@tempb\relax
+ \@RTL@footnotetrue%
+ \or
+ \@RTL@footnotefalse%
+ \fi}
+
+\define@choicekey{simurgh.sty}{debugfootnotedirection}[\simurgh@tempa\simurgh@tempb]{on,off}{%
+ \ifcase\simurgh@tempb\relax
+ \footdir@debugtrue
+ \or
+ \footdir@debugfalse
+ \fi}
+
+\DeclareOptionX{unicodebidi}{\simurgh@unibidi@setmode{#1}}
+
+\ExecuteOptionsX{%
+ maindirection=righttoleft,%
+ mathdirection=lefttoright,%
+ mathdigits=automatic,%
+ footnoterule=automatic,%
+ footnotedirection=righttoleft,%
+ debugfootnotedirection=off,%
+ unicodebidi=global%
+}
+\ProcessOptionsX
+\endinput \ No newline at end of file
diff --git a/macros/luatex/latex/typewriter/README.md b/macros/luatex/latex/typewriter/README.md
new file mode 100644
index 0000000000..a2e1fc3881
--- /dev/null
+++ b/macros/luatex/latex/typewriter/README.md
@@ -0,0 +1,10 @@
+The typewriter package for LaTeX
+
+Typeset with a randomly variable monospace font.
+
+Requires LuaLaTeX and the Computer Modern Unicode OpenType fonts.
+
+David Carlisle
+
+Licence: LPPL
+https://www.latex-project.org/lppl/ \ No newline at end of file
diff --git a/macros/luatex/latex/typewriter/typewriter-guide.pdf b/macros/luatex/latex/typewriter/typewriter-guide.pdf
new file mode 100644
index 0000000000..a5a8e30d47
--- /dev/null
+++ b/macros/luatex/latex/typewriter/typewriter-guide.pdf
Binary files differ
diff --git a/macros/luatex/latex/typewriter/typewriter-guide.tex b/macros/luatex/latex/typewriter/typewriter-guide.tex
new file mode 100644
index 0000000000..5ecb6df160
--- /dev/null
+++ b/macros/luatex/latex/typewriter/typewriter-guide.tex
@@ -0,0 +1,121 @@
+\documentclass{article}
+\usepackage{amsmath}
+\usepackage{typewriter}
+
+\begin{document}
+\title{The Typewriter Package for LaTeX}
+\author{David Carlisle \thanks{https://github.com/davidcarlisle/dpctex/}}
+\date{2018-02-10}
+
+\maketitle
+
+\section{Introduction}
+The typewriter Package uses the OpenType Computer Modern Unicode
+Typewriter font, together with a LuaTeX virtual font setup that
+introduces random variability in grey level and angle of each
+character. It was originally an answer to a question on stackexchange,
+http://tex.stackexchange.com/questions/344214/use-latex-to-simulate-old-typewriter-written-texts
+
+
+\hrule
+
+Currently there are no options to the package, However there are several parameters that control the offsets
+and grey levels used to generate the variation. Any of the following
+commands may be defined before loading the package to change the defaults shown below.
+
+\begin{verbatim}
+\providecommand\ttgreyone{0.6}
+\providecommand\ttgreytwo{0.3}
+\providecommand\ttrotatebold{12}
+\providecommand\ttdownbold{20000}
+\providecommand\ttrightbold{35000}
+\providecommand\ttdownshifttwo{20000}
+
+\providecommand\ttrotatenormal{8}
+\providecommand\ttrightnormal{20000}
+\providecommand\ttdownnormal{20000}
+\end{verbatim}
+
+The grey levels should be between 0 and 1 and control the maximim
+amount grey level.
+
+The rotate values can be any angle (measured degrees), but setting values more than 20 makes the text more or less unreadable.
+
+The right and down offsets (which are in the font design units) control the
+maximum horizontal and vertical offsets of the overprinted characters
+
+There is random variability in each letter as you can see by repeating
+a letter repeatededly:
+
+OOOOOOOOOOOOONNNNNNNNNNNNNNEEEEEEEEEE
+
+TTTTTTTTTTTTwwwwwwwwwwwwwwwwwwwwooooooooooooooooo
+
+
+
+
+\subsection{Text}
+
+one two three
+
+\textbf{one two three}
+
+[some greek text θ]
+
+a rule: \rule{3cm}{1pt}
+
+\subsection{Math}
+
+$\alpha^2=0$ and bold {\boldmath $\alpha^2=0$}
+
+
+
+more math $x^2-\cos θ$
+
+
+display math:
+\[\left(\frac{x^2}{\sqrt{1+y}}\right)\]
+and
+\[\int_{x=0}^n f(x) dx = \sum_0^m q(y)\]
+
+and alignments:
+\begin{align}
+A &\rightarrow B\\
+\mupGamma &\Rightarrow C
+\end{align}
+
+
+\subsection{Lists}
+
+\begin{enumerate}
+\item red yellow blue green
+\item black blue purple
+\end{enumerate}
+
+\begin{itemize}
+\item this
+\item that
+\item and the other
+\end{itemize}
+
+
+\subsection{Tables}
+
+
+
+\begin{center}
+
+\begin{tabular}{|l|l|l|}
+\cline{1-3}
+one & two & three\\
+$\alpha$ & $\beta$ & $\gamma$\\
+\cline{1-3}
+\end{tabular}
+
+\end{center}
+
+\subsection{Colophon}
+\raggedleft
+typeset by egreg design services
+
+\end{document}
diff --git a/macros/luatex/latex/typewriter/typewriter.sty b/macros/luatex/latex/typewriter/typewriter.sty
new file mode 100644
index 0000000000..722fb3f633
--- /dev/null
+++ b/macros/luatex/latex/typewriter/typewriter.sty
@@ -0,0 +1,2798 @@
+% typewriter.sty
+% David Carlisle 2016-2018
+% Licence: LPPL
+% See http://tex.stackexchange.com/questions/344214/use-latex-to-simulate-old-typewriter-written-texts
+
+
+\ProvidesPackage{typewriter}[2018-02-10 v1.1 typewriter package]
+
+\ifx\directlua\@undefined
+\endinput\PackageError{typewriter}{LuaLaTeX required for this package}\@ehc\fi
+
+\providecommand\ttgreyone{0.6}
+\providecommand\ttgreytwo{0.3}
+\providecommand\ttrotatebold{12}
+\providecommand\ttdownbold{20000}
+\providecommand\ttrightbold{35000}
+\providecommand\ttdownshifttwo{20000}
+
+
+\providecommand\ttrotatenormal{8}
+\providecommand\ttrightnormal{20000}
+\providecommand\ttdownnormal{20000}
+
+% luaotfload exlicitly loaded for latex formats before 2017/01/01
+\usepackage{luaotfload}
+
+% load cmuntt here not from lua (for everyone except me, it seems)
+\font\cmuntt = file:cmuntt.otf at 12pt \cmuntt
+\edef\cmunttid{\fontid\cmuntt}
+
+
+\expandafter\let\expandafter\%\csname @percentchar\endcsname
+\directlua {
+ local cbl=luatexbase.callback_descriptions('define_font')
+% print('\string\n======' .. cbl[1] .. '===\string\n')
+original_fontloader=luatexbase.remove_from_callback('define_font',cbl[1])
+luatexbase.add_to_callback('define_font',
+function(name,size,i)
+ if (name=='cmtt10x' or name=='cmtt10bx') then
+% this works in my dev version but for older setups
+% make sure cmuntt.otf has been loaded before we mess
+% up the font loader.
+% f = original_fontloader('cmuntt.otf',size)
+ f = font.getfont(\cmunttid)
+ f.name = 'cmtt10x'
+ f.type = 'virtual'
+ f.fonts = {{ name = 'file:cmuntt', size = size}}
+for j,v in pairs(f.characters) do
+ local gr = \ttgreyone*math.random()
+ local gr2 = \ttgreytwo*math.random()
+if name == 'cmtt10bx' then
+ v.commands = {
+{'lua','
+ r1 = math.rad(0.1*\ttrotatebold*math.random(-10,10))
+pdf.print
+(string.format(" q \%f \%f \%f \%f 0 0 cm ",
+math.cos(r1), - math.sin(r1), math.sin(r1), math.cos(r1)
+))'},
+ {'special','pdf: ' .. string.format("\%f",gr2) .. ' g'},
+{'push'},
+{'right', math.random(-\ttrightbold,\ttrightbold)},
+{'down', math.random(-\ttdownbold,\ttdownbold)},
+ {'char',j},
+{'pop'},
+{'push'},
+{'right', math.random(-\ttrightbold,\ttrightbold)},
+{'down', math.random(-\ttdownbold,\ttdownbold)},
+ {'char',j},
+{'pop'},
+{'push'},
+{'right', math.random(-\ttrightbold,\ttrightbold)},
+{'down', math.random(-\ttdownbold,\ttdownbold)},
+ {'char',j},
+{'pop'},
+{'lua','pdf.print(" Q ")'},
+{'down', math.random(-\ttdownbold,\ttdownbold)},
+ {'special','pdf: ' .. string.format("\%f",gr) .. ' g'},
+ {'char',j},
+ {'special','pdf: 0 g'}
+
+ }
+else
+ v.commands = {
+{'lua','
+ r1 = math.rad(0.1*\ttrotatenormal*math.random(-10,10))
+pdf.print
+(string.format(" q \%f \%f \%f \%f 0 0 cm ",
+math.cos(r1), math.sin(r1), - math.sin(r1), math.cos(r1)
+))'},
+ {'special','pdf: ' .. gr2 .. ' g'},
+{'push'},
+{'right', math.random(-\ttrightnormal,\ttrightnormal)},
+{'down', math.random(-\ttdownshifttwo,\ttdownshifttwo)},
+ {'char',j},
+{'pop'},
+{'lua','pdf.print(" Q ")'},
+{'down', math.random(-\ttdownnormal,\ttdownnormal)},
+ {'special','pdf: ' .. gr .. ' g'},
+ {'char',j},
+ {'special','pdf: 0 g'}
+
+ }
+end
+end
+return f
+else
+return original_fontloader(name,size,i)
+end
+end,
+'define font')
+}
+
+{\count0=0
+\loop
+\global\mathcode\count0=\count0
+\ifnum\count0<256
+\advance\count0 1
+\repeat
+}
+
+\def\boldmath{%
+\textfont0=\mybfont \scriptfont0=\mybfonts \scriptscriptfont0=\mybfonts
+\textfont1=\mybfont \textfont2=\mybfont \textfont3=\mybfont
+}
+
+\AtBeginDocument{%
+\sbox0{$\relax$}%
+
+\font\myfont= cmtt10x at 12pt \myfont
+\font\myfonts= cmtt10x at 9pt
+\font\mybfont= cmtt10bx at 12pt
+\font\mybfonts= cmtt10bx at 9pt
+\let\bfseries\mybfont
+\let\selectfont\relax
+\let\large\relax
+\let\LARGE\relax
+\let\small\relax
+\let\footnotesize\relax
+
+\textfont0=\myfont \scriptfont0=\myfonts \scriptscriptfont0=\myfonts
+\textfont1=\myfont \textfont2=\myfont \textfont3=\myfont
+}
+
+
+\emergencystretch\textwidth
+
+
+
+
+
+% must find a better tt int.
+\def\int{\mathop{\leavevmode\strut\raise.5ex\hbox to 1em{$\scriptstyle\mathchar"352$}}\nolimits}
+\setbox0\hbox{$\int$}\setbox0\hbox{}
+\def\sum{\mathop{\char"03A3\relax}}
+
+\renewcommand\sqrt[2][\relax]{%
+\ifx\relax#1\relax\else{}^{#1}\fi
+^^^^221a\overline{#2}}
+
+\def\overline#1{%
+\vbox{\m@th\ialign{##\crcr
+ \leaders\hbox{\string_}\hfil\crcr\noalign{\kern-\p@\nointerlineskip}
+ $(#1)$\crcr}}}
+
+\def\underline#1{%
+\leavevmode\vtop{\m@th\ialign{##\crcr
+ #1\cr\noalign{\kern-\p@\nointerlineskip}%
+ \leaders\hbox{\string_}\hfil\crcr
+ }}}
+
+
+\def\xUnicodeMathSymbol#1#2#3#4{\def#2{\char#1\relax}}
+\def\xxUnicodeMathSymbol#1#2#3{%
+\mathcode#1="8000
+\begingroup\lccode`\~=#1\lowercase{\endgroup\def~}{#2}%
+\def#2{#3}}
+
+% Copy of Will's unicode-math-table (then abused:-)
+
+\xUnicodeMathSymbol{"00021}{\mathexclam }{\mathpunct}{exclamation mark}%
+\xUnicodeMathSymbol{"00023}{\mathoctothorpe }{\mathord}{number sign}%
+\xUnicodeMathSymbol{"00024}{\mathdollar }{\mathord}{dollar sign}%
+\xUnicodeMathSymbol{"00025}{\mathpercent }{\mathord}{percent sign}%
+\xUnicodeMathSymbol{"00026}{\mathampersand }{\mathord}{ampersand}%
+\xUnicodeMathSymbol{"00028}{\lparen }{\mathopen}{left parenthesis}%
+\xUnicodeMathSymbol{"00029}{\rparen }{\mathclose}{right parenthesis}%
+\xUnicodeMathSymbol{"0002B}{\mathplus }{\mathbin}{plus sign b:}%
+\xUnicodeMathSymbol{"0002C}{\mathcomma }{\mathpunct}{comma}%
+\xUnicodeMathSymbol{"0002E}{\mathperiod }{\mathord}{full stop, period}%
+\xUnicodeMathSymbol{"0002F}{\mathslash }{\mathord}{solidus}%
+\xUnicodeMathSymbol{"0003A}{\mathcolon }{\mathpunct}{colon}%
+\xUnicodeMathSymbol{"0003B}{\mathsemicolon }{\mathpunct}{semicolon p:}%
+\xUnicodeMathSymbol{"0003C}{\less }{\mathrel}{less-than sign r:}%
+\xUnicodeMathSymbol{"0003D}{\equal }{\mathrel}{equals sign r:}%
+\xUnicodeMathSymbol{"0003E}{\greater }{\mathrel}{greater-than sign r:}%
+\xUnicodeMathSymbol{"0003F}{\mathquestion }{\mathord}{question mark}%
+\xUnicodeMathSymbol{"00040}{\mathatsign }{\mathord}{commercial at}%
+\xUnicodeMathSymbol{"0005B}{\lbrack }{\mathopen}{left square bracket}%
+\xUnicodeMathSymbol{"0005C}{\backslash }{\mathord}{reverse solidus}%
+\xUnicodeMathSymbol{"0005D}{\rbrack }{\mathclose}{right square bracket}%
+\xUnicodeMathSymbol{"0007B}{\lbrace }{\mathopen}{left curly bracket}%
+\xUnicodeMathSymbol{"0007C}{\vert }{\mathfence}{vertical bar}%
+\xUnicodeMathSymbol{"0007D}{\rbrace }{\mathclose}{right curly bracket}%
+\xUnicodeMathSymbol{"000A3}{\mathsterling }{\mathord}{pound sign}%
+\xUnicodeMathSymbol{"000A5}{\mathyen }{\mathord}{yen sign}%
+\xUnicodeMathSymbol{"000AC}{\neg }{\mathord}{/neg /lnot not sign}%
+\xUnicodeMathSymbol{"000B1}{\pm }{\mathbin}{plus-or-minus sign}%
+\xUnicodeMathSymbol{"000B7}{\cdotp }{\mathbin}{/centerdot b: middle dot}%
+\xUnicodeMathSymbol{"000D7}{\times }{\mathbin}{multiply sign}%
+\xUnicodeMathSymbol{"000F0}{\matheth }{\mathalpha}{eth}%
+\xUnicodeMathSymbol{"000F7}{\div }{\mathbin}{divide sign}%
+\xUnicodeMathSymbol{"001B5}{\Zbar }{\mathord}{impedance (latin capital letter z with stroke)}%
+\xUnicodeMathSymbol{"00300}{\grave }{\mathaccent}{grave accent}%
+\xUnicodeMathSymbol{"00301}{\acute }{\mathaccent}{acute accent}%
+\xUnicodeMathSymbol{"00302}{\hat }{\mathaccent}{circumflex accent}%
+\xUnicodeMathSymbol{"00302}{\widehat }{\mathaccentwide}{circumflex accent}%
+\xUnicodeMathSymbol{"00303}{\tilde }{\mathaccent}{tilde}%
+\xUnicodeMathSymbol{"00303}{\widetilde }{\mathaccentwide}{tilde}%
+\xUnicodeMathSymbol{"00304}{\bar }{\mathaccent}{macron}%
+\xUnicodeMathSymbol{"00305}{\overbar }{\mathaccent}{overbar embellishment}%
+\xUnicodeMathSymbol{"00306}{\breve }{\mathaccent}{breve}%
+\xUnicodeMathSymbol{"00307}{\dot }{\mathaccent}{dot above}%
+\xUnicodeMathSymbol{"00308}{\ddot }{\mathaccent}{dieresis}%
+\xUnicodeMathSymbol{"00309}{\ovhook }{\mathaccent}{combining hook above}%
+\xUnicodeMathSymbol{"0030A}{\ocirc }{\mathaccent}{ring}%
+\xUnicodeMathSymbol{"0030C}{\check }{\mathaccent}{caron}%
+\xUnicodeMathSymbol{"00310}{\candra }{\mathaccent}{candrabindu (non-spacing)}%
+\xUnicodeMathSymbol{"00312}{\oturnedcomma }{\mathaccent}{combining turned comma above}%
+\xUnicodeMathSymbol{"00315}{\ocommatopright }{\mathaccent}{combining comma above right}%
+\xUnicodeMathSymbol{"0031A}{\droang }{\mathaccent}{left angle above (non-spacing)}%
+\xUnicodeMathSymbol{"00330}{\wideutilde }{\mathbotaccentwide}{under tilde accent (multiple characters and non-spacing)}%
+\xUnicodeMathSymbol{"00332}{\mathunderbar }{\mathbotaccentwide}{combining low line}%
+\xUnicodeMathSymbol{"00338}{\not }{\mathaccent}{combining long solidus overlay}%
+\xUnicodeMathSymbol{"0034D}{\underleftrightarrow }{\mathbotaccentwide}{underleftrightarrow accent}%
+\xUnicodeMathSymbol{"00391}{\mupAlpha }{\mathalpha}{capital alpha, greek}%
+\xUnicodeMathSymbol{"00392}{\mupBeta }{\mathalpha}{capital beta, greek}%
+\xUnicodeMathSymbol{"00393}{\mupGamma }{\mathalpha}{capital gamma, greek}%
+\xUnicodeMathSymbol{"00394}{\mupDelta }{\mathalpha}{capital delta, greek}%
+\xUnicodeMathSymbol{"00395}{\mupEpsilon }{\mathalpha}{capital epsilon, greek}%
+\xUnicodeMathSymbol{"00396}{\mupZeta }{\mathalpha}{capital zeta, greek}%
+\xUnicodeMathSymbol{"00397}{\mupEta }{\mathalpha}{capital eta, greek}%
+\xUnicodeMathSymbol{"00398}{\mupTheta }{\mathalpha}{capital theta, greek}%
+\xUnicodeMathSymbol{"00399}{\mupIota }{\mathalpha}{capital iota, greek}%
+\xUnicodeMathSymbol{"0039A}{\mupKappa }{\mathalpha}{capital kappa, greek}%
+\xUnicodeMathSymbol{"0039B}{\mupLambda }{\mathalpha}{capital lambda, greek}%
+\xUnicodeMathSymbol{"0039C}{\mupMu }{\mathalpha}{capital mu, greek}%
+\xUnicodeMathSymbol{"0039D}{\mupNu }{\mathalpha}{capital nu, greek}%
+\xUnicodeMathSymbol{"0039E}{\mupXi }{\mathalpha}{capital xi, greek}%
+\xUnicodeMathSymbol{"0039F}{\mupOmicron }{\mathalpha}{capital omicron, greek}%
+\xUnicodeMathSymbol{"003A0}{\mupPi }{\mathalpha}{capital pi, greek}%
+\xUnicodeMathSymbol{"003A1}{\mupRho }{\mathalpha}{capital rho, greek}%
+\xUnicodeMathSymbol{"003A3}{\mupSigma }{\mathalpha}{capital sigma, greek}%
+\xUnicodeMathSymbol{"003A4}{\mupTau }{\mathalpha}{capital tau, greek}%
+\xUnicodeMathSymbol{"003A5}{\mupUpsilon }{\mathalpha}{capital upsilon, greek}%
+\xUnicodeMathSymbol{"003A6}{\mupPhi }{\mathalpha}{capital phi, greek}%
+\xUnicodeMathSymbol{"003A7}{\mupChi }{\mathalpha}{capital chi, greek}%
+\xUnicodeMathSymbol{"003A8}{\mupPsi }{\mathalpha}{capital psi, greek}%
+\xUnicodeMathSymbol{"003A9}{\mupOmega }{\mathalpha}{capital omega, greek}%
+\xUnicodeMathSymbol{"003B1}{\mupalpha }{\mathalpha}{small alpha, greek}%
+\xUnicodeMathSymbol{"003B2}{\mupbeta }{\mathalpha}{small beta, greek}%
+\xUnicodeMathSymbol{"003B3}{\mupgamma }{\mathalpha}{small gamma, greek}%
+\xUnicodeMathSymbol{"003B4}{\mupdelta }{\mathalpha}{small delta, greek}%
+\xUnicodeMathSymbol{"003B5}{\mupepsilon }{\mathalpha}{rounded small epsilon, greek}%
+\xUnicodeMathSymbol{"003B6}{\mupzeta }{\mathalpha}{small zeta, greek}%
+\xUnicodeMathSymbol{"003B7}{\mupeta }{\mathalpha}{small eta, greek}%
+\xUnicodeMathSymbol{"003B8}{\muptheta }{\mathalpha}{straight theta, small theta, greek}%
+\xUnicodeMathSymbol{"003B9}{\mupiota }{\mathalpha}{small iota, greek}%
+\xUnicodeMathSymbol{"003BA}{\mupkappa }{\mathalpha}{small kappa, greek}%
+\xUnicodeMathSymbol{"003BB}{\muplambda }{\mathalpha}{small lambda, greek}%
+\xUnicodeMathSymbol{"003BC}{\mupmu }{\mathalpha}{small mu, greek}%
+\xUnicodeMathSymbol{"003BD}{\mupnu }{\mathalpha}{small nu, greek}%
+\xUnicodeMathSymbol{"003BE}{\mupxi }{\mathalpha}{small xi, greek}%
+\xUnicodeMathSymbol{"003BF}{\mupomicron }{\mathalpha}{small omicron, greek}%
+\xUnicodeMathSymbol{"003C0}{\muppi }{\mathalpha}{small pi, greek}%
+\xUnicodeMathSymbol{"003C1}{\muprho }{\mathalpha}{small rho, greek}%
+\xUnicodeMathSymbol{"003C2}{\mupvarsigma }{\mathalpha}{terminal sigma, greek}%
+\xUnicodeMathSymbol{"003C3}{\mupsigma }{\mathalpha}{small sigma, greek}%
+\xUnicodeMathSymbol{"003C4}{\muptau }{\mathalpha}{small tau, greek}%
+\xUnicodeMathSymbol{"003C5}{\mupupsilon }{\mathalpha}{small upsilon, greek}%
+\xUnicodeMathSymbol{"003C6}{\mupvarphi }{\mathalpha}{curly or open small phi, greek}%
+\xUnicodeMathSymbol{"003C7}{\mupchi }{\mathalpha}{small chi, greek}%
+\xUnicodeMathSymbol{"003C8}{\muppsi }{\mathalpha}{small psi, greek}%
+\xUnicodeMathSymbol{"003C9}{\mupomega }{\mathalpha}{small omega, greek}%
+\xUnicodeMathSymbol{"003D0}{\mupvarbeta }{\mathalpha}{rounded small beta, greek}%
+\xUnicodeMathSymbol{"003D1}{\mupvartheta }{\mathalpha}{/vartheta - curly or open theta}%
+\xUnicodeMathSymbol{"003D5}{\mupphi }{\mathalpha}{/straightphi - small phi, greek}%
+\xUnicodeMathSymbol{"003D6}{\mupvarpi }{\mathalpha}{rounded small pi (pomega), greek}%
+\xUnicodeMathSymbol{"003D8}{\upoldKoppa }{\mathord}{greek letter archaic koppa}%
+\xUnicodeMathSymbol{"003D9}{\upoldkoppa }{\mathord}{greek small letter archaic koppa}%
+\xUnicodeMathSymbol{"003DA}{\upStigma }{\mathalpha}{capital stigma}%
+\xUnicodeMathSymbol{"003DB}{\upstigma }{\mathalpha}{greek small letter stigma}%
+\xUnicodeMathSymbol{"003DC}{\upDigamma }{\mathalpha}{capital digamma}%
+\xUnicodeMathSymbol{"003DD}{\updigamma }{\mathalpha}{old greek small letter digamma}%
+\xUnicodeMathSymbol{"003DE}{\upKoppa }{\mathalpha}{capital koppa}%
+\xUnicodeMathSymbol{"003DF}{\upkoppa }{\mathalpha}{greek small letter koppa}%
+\xUnicodeMathSymbol{"003E0}{\upSampi }{\mathalpha}{capital sampi}%
+\xUnicodeMathSymbol{"003E1}{\upsampi }{\mathalpha}{greek small letter sampi}%
+\xUnicodeMathSymbol{"003F0}{\mupvarkappa }{\mathalpha}{rounded small kappa, greek}%
+\xUnicodeMathSymbol{"003F1}{\mupvarrho }{\mathalpha}{rounded small rho, greek}%
+\xUnicodeMathSymbol{"003F4}{\mupvarTheta }{\mathalpha}{greek capital theta symbol}%
+\xUnicodeMathSymbol{"003F5}{\mupvarepsilon }{\mathalpha}{greek lunate epsilon symbol}%
+\xUnicodeMathSymbol{"003F6}{\upbackepsilon }{\mathord}{greek reversed lunate epsilon symbol}%
+
+\xUnicodeMathSymbol{"00391}{\Alpha }{\mathalpha}{capital alpha, greek}%
+\xUnicodeMathSymbol{"00392}{\Beta }{\mathalpha}{capital beta, greek}%
+\xUnicodeMathSymbol{"00393}{\Gamma }{\mathalpha}{capital gamma, greek}%
+\xUnicodeMathSymbol{"00394}{\Delta }{\mathalpha}{capital delta, greek}%
+\xUnicodeMathSymbol{"00395}{\Epsilon }{\mathalpha}{capital epsilon, greek}%
+\xUnicodeMathSymbol{"00396}{\Zeta }{\mathalpha}{capital zeta, greek}%
+\xUnicodeMathSymbol{"00397}{\Eta }{\mathalpha}{capital eta, greek}%
+\xUnicodeMathSymbol{"00398}{\Theta }{\mathalpha}{capital theta, greek}%
+\xUnicodeMathSymbol{"00399}{\Iota }{\mathalpha}{capital iota, greek}%
+\xUnicodeMathSymbol{"0039A}{\Kappa }{\mathalpha}{capital kappa, greek}%
+\xUnicodeMathSymbol{"0039B}{\Lambda }{\mathalpha}{capital lambda, greek}%
+\xUnicodeMathSymbol{"0039C}{\Mu }{\mathalpha}{capital mu, greek}%
+\xUnicodeMathSymbol{"0039D}{\Nu }{\mathalpha}{capital nu, greek}%
+\xUnicodeMathSymbol{"0039E}{\Xi }{\mathalpha}{capital xi, greek}%
+\xUnicodeMathSymbol{"0039F}{\Omicron }{\mathalpha}{capital omicron, greek}%
+\xUnicodeMathSymbol{"003A0}{\Pi }{\mathalpha}{capital pi, greek}%
+\xUnicodeMathSymbol{"003A1}{\Rho }{\mathalpha}{capital rho, greek}%
+\xUnicodeMathSymbol{"003A3}{\Sigma }{\mathalpha}{capital sigma, greek}%
+\xUnicodeMathSymbol{"003A4}{\Tau }{\mathalpha}{capital tau, greek}%
+\xUnicodeMathSymbol{"003A5}{\Upsilon }{\mathalpha}{capital upsilon, greek}%
+\xUnicodeMathSymbol{"003A6}{\Phi }{\mathalpha}{capital phi, greek}%
+\xUnicodeMathSymbol{"003A7}{\Chi }{\mathalpha}{capital chi, greek}%
+\xUnicodeMathSymbol{"003A8}{\Psi }{\mathalpha}{capital psi, greek}%
+\xUnicodeMathSymbol{"003A9}{\Omega }{\mathalpha}{capital omega, greek}%
+\xUnicodeMathSymbol{"003B1}{\alpha }{\mathalpha}{small alpha, greek}%
+\xUnicodeMathSymbol{"003B2}{\beta }{\mathalpha}{small beta, greek}%
+\xUnicodeMathSymbol{"003B3}{\gamma }{\mathalpha}{small gamma, greek}%
+\xUnicodeMathSymbol{"003B4}{\delta }{\mathalpha}{small delta, greek}%
+\xUnicodeMathSymbol{"003B5}{\epsilon }{\mathalpha}{rounded small epsilon, greek}%
+\xUnicodeMathSymbol{"003B6}{\zeta }{\mathalpha}{small zeta, greek}%
+\xUnicodeMathSymbol{"003B7}{\eta }{\mathalpha}{small eta, greek}%
+\xUnicodeMathSymbol{"003B8}{\theta }{\mathalpha}{straight theta, small theta, greek}%
+\xUnicodeMathSymbol{"003B9}{\iota }{\mathalpha}{small iota, greek}%
+\xUnicodeMathSymbol{"003BA}{\kappa }{\mathalpha}{small kappa, greek}%
+\xUnicodeMathSymbol{"003BB}{\lambda }{\mathalpha}{small lambda, greek}%
+\xUnicodeMathSymbol{"003BC}{\mu }{\mathalpha}{small mu, greek}%
+\xUnicodeMathSymbol{"003BD}{\nu }{\mathalpha}{small nu, greek}%
+\xUnicodeMathSymbol{"003BE}{\xi }{\mathalpha}{small xi, greek}%
+\xUnicodeMathSymbol{"003BF}{\omicron }{\mathalpha}{small omicron, greek}%
+\xUnicodeMathSymbol{"003C0}{\pi }{\mathalpha}{small pi, greek}%
+\xUnicodeMathSymbol{"003C1}{\rho }{\mathalpha}{small rho, greek}%
+\xUnicodeMathSymbol{"003C2}{\varsigma }{\mathalpha}{terminal sigma, greek}%
+\xUnicodeMathSymbol{"003C3}{\sigma }{\mathalpha}{small sigma, greek}%
+\xUnicodeMathSymbol{"003C4}{\tau }{\mathalpha}{small tau, greek}%
+\xUnicodeMathSymbol{"003C5}{\upsilon }{\mathalpha}{small upsilon, greek}%
+\xUnicodeMathSymbol{"003C6}{\varphi }{\mathalpha}{curly or open small phi, greek}%
+\xUnicodeMathSymbol{"003C7}{\chi }{\mathalpha}{small chi, greek}%
+\xUnicodeMathSymbol{"003C8}{\psi }{\mathalpha}{small psi, greek}%
+\xUnicodeMathSymbol{"003C9}{\omega }{\mathalpha}{small omega, greek}%
+\xUnicodeMathSymbol{"003D0}{\varbeta }{\mathalpha}{rounded small beta, greek}%
+\xUnicodeMathSymbol{"003D1}{\vartheta }{\mathalpha}{/vartheta - curly or open theta}%
+\xUnicodeMathSymbol{"003D5}{\phi }{\mathalpha}{/straightphi - small phi, greek}%
+\xUnicodeMathSymbol{"003D6}{\varpi }{\mathalpha}{rounded small pi (pomega), greek}%
+\xUnicodeMathSymbol{"003D8}{\oldKoppa }{\mathord}{greek letter archaic koppa}%
+\xUnicodeMathSymbol{"003D9}{\oldkoppa }{\mathord}{greek small letter archaic koppa}%
+\xUnicodeMathSymbol{"003DA}{\Stigma }{\mathalpha}{capital stigma}%
+\xUnicodeMathSymbol{"003DB}{\stigma }{\mathalpha}{greek small letter stigma}%
+\xUnicodeMathSymbol{"003DC}{\Digamma }{\mathalpha}{capital digamma}%
+\xUnicodeMathSymbol{"003DD}{\digamma }{\mathalpha}{old greek small letter digamma}%
+\xUnicodeMathSymbol{"003DE}{\Koppa }{\mathalpha}{capital koppa}%
+\xUnicodeMathSymbol{"003DF}{\koppa }{\mathalpha}{greek small letter koppa}%
+\xUnicodeMathSymbol{"003E0}{\Sampi }{\mathalpha}{capital sampi}%
+\xUnicodeMathSymbol{"003E1}{\sampi }{\mathalpha}{greek small letter sampi}%
+\xUnicodeMathSymbol{"003F0}{\varkappa }{\mathalpha}{rounded small kappa, greek}%
+\xUnicodeMathSymbol{"003F1}{\varrho }{\mathalpha}{rounded small rho, greek}%
+\xUnicodeMathSymbol{"003F4}{\varTheta }{\mathalpha}{greek capital theta symbol}%
+\xUnicodeMathSymbol{"003F5}{\varepsilon }{\mathalpha}{greek lunate epsilon symbol}%
+\xUnicodeMathSymbol{"003F6}{\upbackepsilon }{\mathord}{greek reversed lunate epsilon symbol}%
+
+
+
+
+\xUnicodeMathSymbol{"02015}{\horizbar }{\mathord}{horizontal bar}%
+\xUnicodeMathSymbol{"02016}{\Vert }{\mathfence}{double vertical bar}%
+\xUnicodeMathSymbol{"02017}{\twolowline }{\mathord}{double low line (spacing)}%
+\xUnicodeMathSymbol{"02020}{\dagger }{\mathbin}{dagger relation}%
+\xUnicodeMathSymbol{"02021}{\ddagger }{\mathbin}{double dagger relation}%
+\xUnicodeMathSymbol{"02022}{\smblkcircle }{\mathbin}{/bullet b: round bullet, filled}%
+\xUnicodeMathSymbol{"02025}{\enleadertwodots }{\mathord}{double baseline dot (en leader)}%
+\xUnicodeMathSymbol{"02026}{\unicodeellipsis }{\mathord}{ellipsis (horizontal)}%
+\xUnicodeMathSymbol{"02032}{\prime }{\mathord}{prime or minute, not superscripted}%
+\xUnicodeMathSymbol{"02033}{\dprime }{\mathord}{double prime or second, not superscripted}%
+\xUnicodeMathSymbol{"02034}{\trprime }{\mathord}{triple prime (not superscripted)}%
+\xUnicodeMathSymbol{"02035}{\backprime }{\mathord}{reverse prime, not superscripted}%
+\xUnicodeMathSymbol{"02036}{\backdprime }{\mathord}{double reverse prime, not superscripted}%
+\xUnicodeMathSymbol{"02037}{\backtrprime }{\mathord}{triple reverse prime, not superscripted}%
+\xUnicodeMathSymbol{"02038}{\caretinsert }{\mathord}{caret (insertion mark)}%
+\xUnicodeMathSymbol{"0203C}{\Exclam }{\mathord}{double exclamation mark}%
+\xUnicodeMathSymbol{"02040}{\tieconcat }{\mathbin}{character tie, z notation sequence concatenation}%
+\xUnicodeMathSymbol{"02043}{\hyphenbullet }{\mathord}{rectangle, filled (hyphen bullet)}%
+\xUnicodeMathSymbol{"02044}{\fracslash }{\mathbin}{fraction slash}%
+\xUnicodeMathSymbol{"02047}{\Question }{\mathord}{double question mark}%
+\xUnicodeMathSymbol{"02050}{\closure }{\mathrel}{close up}%
+\xUnicodeMathSymbol{"02057}{\qprime }{\mathord}{quadruple prime, not superscripted}%
+\xUnicodeMathSymbol{"020AC}{\euro }{\mathord}{euro sign}%
+\xUnicodeMathSymbol{"020D0}{\leftharpoonaccent }{\mathaccent}{combining left harpoon above}%
+\xUnicodeMathSymbol{"020D0}{\overleftharpoon }{\mathaccentwide}{combining left harpoon above}%
+\xUnicodeMathSymbol{"020D1}{\rightharpoonaccent }{\mathaccent}{combining right harpoon above}%
+\xUnicodeMathSymbol{"020D1}{\overrightharpoon }{\mathaccentwide}{combining right harpoon above}%
+\xUnicodeMathSymbol{"020D2}{\vertoverlay }{\mathaccent}{combining long vertical line overlay}%
+\xUnicodeMathSymbol{"020D6}{\overleftarrow }{\mathaccentwide}{combining left arrow above}%
+\xUnicodeMathSymbol{"020D7}{\overrightarrow }{\mathaccentwide}{combining left arrow above}%
+\xUnicodeMathSymbol{"020D7}{\vec }{\mathaccent}{combining right arrow above}%
+\xUnicodeMathSymbol{"020DB}{\dddot }{\mathaccent}{combining three dots above}%
+\xUnicodeMathSymbol{"020DC}{\ddddot }{\mathaccent}{combining four dots above}%
+\xUnicodeMathSymbol{"020DD}{\enclosecircle }{\mathord}{combining enclosing circle}%
+\xUnicodeMathSymbol{"020DE}{\enclosesquare }{\mathord}{combining enclosing square}%
+\xUnicodeMathSymbol{"020DF}{\enclosediamond }{\mathord}{combining enclosing diamond}%
+\xUnicodeMathSymbol{"020E1}{\overleftrightarrow }{\mathaccentwide}{combining left right arrow above}%
+\xUnicodeMathSymbol{"020E4}{\enclosetriangle }{\mathord}{combining enclosing upward pointing triangle}%
+\xUnicodeMathSymbol{"020E7}{\annuity }{\mathaccent}{combining annuity symbol}%
+\xUnicodeMathSymbol{"020E8}{\threeunderdot }{\mathbotaccent}{combining triple underdot}%
+\xUnicodeMathSymbol{"020E9}{\widebridgeabove }{\mathaccent}{combining wide bridge above}%
+\xUnicodeMathSymbol{"020EC}{\underrightharpoondown }{\mathbotaccentwide}{combining rightwards harpoon with barb downwards}%
+\xUnicodeMathSymbol{"020ED}{\underleftharpoondown }{\mathbotaccentwide}{combining leftwards harpoon with barb downwards}%
+\xUnicodeMathSymbol{"020EE}{\underleftarrow }{\mathbotaccentwide}{combining left arrow below}%
+\xUnicodeMathSymbol{"020EF}{\underrightarrow }{\mathbotaccentwide}{combining right arrow below}%
+\xUnicodeMathSymbol{"020F0}{\asteraccent }{\mathaccent}{combining asterisk above}%
+%\xUnicodeMathSymbol{"02102}{\BbbC }{\mathalpha}{/bbb c, open face c}%
+\xxUnicodeMathSymbol{"02102}{\BbbC}{|\!\!\!C}
+\xUnicodeMathSymbol{"02107}{\Eulerconst }{\mathord}{euler constant}%
+\xUnicodeMathSymbol{"0210A}{\mscrg }{\mathalpha}{/scr g, script letter g}%
+\xUnicodeMathSymbol{"0210B}{\mscrH }{\mathalpha}{hamiltonian (script capital h)}%
+\xUnicodeMathSymbol{"0210C}{\mfrakH }{\mathalpha}{/frak h, upper case h}%
+\xUnicodeMathSymbol{"0210D}{\BbbH }{\mathalpha}{/bbb h, open face h}%
+\xUnicodeMathSymbol{"0210E}{\Planckconst }{\mathord}{planck constant}%
+\xUnicodeMathSymbol{"0210F}{\hslash }{\mathalpha}{/hslash - variant planck's over 2pi}%
+\xUnicodeMathSymbol{"02110}{\mscrI }{\mathalpha}{/scr i, script letter i}%
+\xUnicodeMathSymbol{"02111}{\Im }{\mathalpha}{imaginary part}%
+\xUnicodeMathSymbol{"02112}{\mscrL }{\mathalpha}{lagrangian (script capital l)}%
+\xUnicodeMathSymbol{"02113}{\ell }{\mathalpha}{cursive small l}%
+\xUnicodeMathSymbol{"02115}{\BbbN }{\mathalpha}{/bbb n, open face n}%
+\xUnicodeMathSymbol{"02118}{\wp }{\mathalpha}{weierstrass p}%
+\xUnicodeMathSymbol{"02119}{\BbbP }{\mathalpha}{/bbb p, open face p}%
+\xUnicodeMathSymbol{"0211A}{\BbbQ }{\mathalpha}{/bbb q, open face q}%
+\xUnicodeMathSymbol{"0211B}{\mscrR }{\mathalpha}{/scr r, script letter r}%
+\xUnicodeMathSymbol{"0211C}{\Re }{\mathalpha}{real part}%
+%\xUnicodeMathSymbol{"0211D}{\BbbR }{\mathalpha}{/bbb r, open face r}%
+\xxUnicodeMathSymbol{"0211D}{\BbbR}{I\!\!R}
+\xUnicodeMathSymbol{"02124}{\BbbZ }{\mathalpha}{/bbb z, open face z}%
+\xUnicodeMathSymbol{"02127}{\mho }{\mathord}{conductance}%
+\xUnicodeMathSymbol{"02128}{\mfrakZ }{\mathalpha}{/frak z, upper case z}%
+\xUnicodeMathSymbol{"02129}{\turnediota }{\mathalpha}{turned iota}%
+\xUnicodeMathSymbol{"0212B}{\Angstrom }{\mathalpha}{angstrom capital a, ring}%
+\xUnicodeMathSymbol{"0212C}{\mscrB }{\mathalpha}{bernoulli function (script capital b)}%
+\xUnicodeMathSymbol{"0212D}{\mfrakC }{\mathalpha}{black-letter capital c}%
+\xUnicodeMathSymbol{"0212F}{\mscre }{\mathalpha}{/scr e, script letter e}%
+\xUnicodeMathSymbol{"02130}{\mscrE }{\mathalpha}{/scr e, script letter e}%
+\xUnicodeMathSymbol{"02131}{\mscrF }{\mathalpha}{/scr f, script letter f}%
+\xUnicodeMathSymbol{"02132}{\Finv }{\mathord}{turned capital f}%
+\xUnicodeMathSymbol{"02133}{\mscrM }{\mathalpha}{physics m-matrix (script capital m)}%
+\xUnicodeMathSymbol{"02134}{\mscro }{\mathalpha}{order of (script small o)}%
+\xUnicodeMathSymbol{"02135}{\aleph }{\mathalpha}{aleph, hebrew}%
+\xUnicodeMathSymbol{"02136}{\beth }{\mathalpha}{beth, hebrew}%
+\xUnicodeMathSymbol{"02137}{\gimel }{\mathalpha}{gimel, hebrew}%
+\xUnicodeMathSymbol{"02138}{\daleth }{\mathalpha}{daleth, hebrew}%
+\xUnicodeMathSymbol{"0213C}{\Bbbpi }{\mathord}{double-struck small pi}%
+\xUnicodeMathSymbol{"0213D}{\Bbbgamma }{\mathalpha}{double-struck small gamma}%
+\xUnicodeMathSymbol{"0213E}{\BbbGamma }{\mathalpha}{double-struck capital gamma}%
+\xUnicodeMathSymbol{"0213F}{\BbbPi }{\mathalpha}{double-struck capital pi}%
+\xUnicodeMathSymbol{"02140}{\Bbbsum }{\mathop}{double-struck n-ary summation}%
+\xUnicodeMathSymbol{"02141}{\Game }{\mathord}{turned sans-serif capital g}%
+\xUnicodeMathSymbol{"02142}{\sansLturned }{\mathord}{turned sans-serif capital l}%
+\xUnicodeMathSymbol{"02143}{\sansLmirrored }{\mathord}{reversed sans-serif capital l}%
+\xUnicodeMathSymbol{"02144}{\Yup }{\mathord}{turned sans-serif capital y}%
+\xUnicodeMathSymbol{"02145}{\mitBbbD }{\mathord}{double-struck italic capital d}%
+\xUnicodeMathSymbol{"02146}{\mitBbbd }{\mathord}{double-struck italic small d}%
+\xUnicodeMathSymbol{"02147}{\mitBbbe }{\mathord}{double-struck italic small e}%
+\xUnicodeMathSymbol{"02148}{\mitBbbi }{\mathord}{double-struck italic small i}%
+\xUnicodeMathSymbol{"02149}{\mitBbbj }{\mathord}{double-struck italic small j}%
+\xUnicodeMathSymbol{"0214A}{\PropertyLine }{\mathord}{property line}%
+\xUnicodeMathSymbol{"0214B}{\upand }{\mathbin}{turned ampersand}%
+%\xUnicodeMathSymbol{"02190}{\leftarrow }{\mathrel}{/leftarrow /gets a: leftward arrow}%
+\xxUnicodeMathSymbol{"02190}{\leftarrow}{<-}
+\xUnicodeMathSymbol{"02191}{\uparrow }{\mathrel}{upward arrow}%
+%\xUnicodeMathSymbol{"02192}{\rightarrow }{\mathrel}{/rightarrow /to a: rightward arrow}%
+\xxUnicodeMathSymbol{"02192}{\rightarrow}{->}
+\xUnicodeMathSymbol{"02193}{\downarrow }{\mathrel}{downward arrow}%
+%\xUnicodeMathSymbol{"02194}{\leftrightarrow }{\mathrel}{left and right arrow}%
+\xxUnicodeMathSymbol{"02194}{\leftrightarrow}{<->}
+\xUnicodeMathSymbol{"02195}{\updownarrow }{\mathrel}{up and down arrow}%
+\xUnicodeMathSymbol{"02196}{\nwarrow }{\mathrel}{nw pointing arrow}%
+\xUnicodeMathSymbol{"02197}{\nearrow }{\mathrel}{ne pointing arrow}%
+\xUnicodeMathSymbol{"02198}{\searrow }{\mathrel}{se pointing arrow}%
+\xUnicodeMathSymbol{"02199}{\swarrow }{\mathrel}{sw pointing arrow}%
+\xUnicodeMathSymbol{"0219A}{\nleftarrow }{\mathrel}{not left arrow}%
+\xUnicodeMathSymbol{"0219B}{\nrightarrow }{\mathrel}{not right arrow}%
+\xUnicodeMathSymbol{"0219C}{\leftwavearrow }{\mathrel}{left arrow-wavy}%
+\xUnicodeMathSymbol{"0219D}{\rightwavearrow }{\mathrel}{right arrow-wavy}%
+\xUnicodeMathSymbol{"0219E}{\twoheadleftarrow }{\mathrel}{left two-headed arrow}%
+\xUnicodeMathSymbol{"0219F}{\twoheaduparrow }{\mathrel}{up two-headed arrow}%
+\xUnicodeMathSymbol{"021A0}{\twoheadrightarrow }{\mathrel}{right two-headed arrow}%
+\xUnicodeMathSymbol{"021A1}{\twoheaddownarrow }{\mathrel}{down two-headed arrow}%
+\xUnicodeMathSymbol{"021A2}{\leftarrowtail }{\mathrel}{left arrow-tailed}%
+\xUnicodeMathSymbol{"021A3}{\rightarrowtail }{\mathrel}{right arrow-tailed}%
+\xUnicodeMathSymbol{"021A4}{\mapsfrom }{\mathrel}{maps to, leftward}%
+\xUnicodeMathSymbol{"021A5}{\mapsup }{\mathrel}{maps to, upward}%
+%\xUnicodeMathSymbol{"021A6}{\mapsto }{\mathrel}{maps to, rightward}%
+\xxUnicodeMathSymbol{"021A6}{\mapsto}{{|\!->}}
+\xUnicodeMathSymbol{"021A7}{\mapsdown }{\mathrel}{maps to, downward}%
+\xUnicodeMathSymbol{"021A8}{\updownarrowbar }{\mathord}{up down arrow with base (perpendicular)}%
+\xUnicodeMathSymbol{"021A9}{\hookleftarrow }{\mathrel}{left arrow-hooked}%
+\xUnicodeMathSymbol{"021AA}{\hookrightarrow }{\mathrel}{right arrow-hooked}%
+\xUnicodeMathSymbol{"021AB}{\looparrowleft }{\mathrel}{left arrow-looped}%
+\xUnicodeMathSymbol{"021AC}{\looparrowright }{\mathrel}{right arrow-looped}%
+\xUnicodeMathSymbol{"021AD}{\leftrightsquigarrow }{\mathrel}{left and right arr-wavy}%
+\xUnicodeMathSymbol{"021AE}{\nleftrightarrow }{\mathrel}{not left and right arrow}%
+\xUnicodeMathSymbol{"021AF}{\downzigzagarrow }{\mathrel}{downwards zigzag arrow}%
+\xUnicodeMathSymbol{"021B0}{\Lsh }{\mathrel}{/lsh a:}%
+\xUnicodeMathSymbol{"021B1}{\Rsh }{\mathrel}{/rsh a:}%
+\xUnicodeMathSymbol{"021B2}{\Ldsh }{\mathrel}{left down angled arrow}%
+\xUnicodeMathSymbol{"021B3}{\Rdsh }{\mathrel}{right down angled arrow}%
+\xUnicodeMathSymbol{"021B4}{\linefeed }{\mathord}{rightwards arrow with corner downwards}%
+\xUnicodeMathSymbol{"021B5}{\carriagereturn }{\mathord}{downwards arrow with corner leftward = carriage return}%
+\xUnicodeMathSymbol{"021B6}{\curvearrowleft }{\mathrel}{left curved arrow}%
+\xUnicodeMathSymbol{"021B7}{\curvearrowright }{\mathrel}{right curved arrow}%
+\xUnicodeMathSymbol{"021B8}{\barovernorthwestarrow }{\mathord}{north west arrow to long bar}%
+\xUnicodeMathSymbol{"021B9}{\barleftarrowrightarrowbar}{\mathord}{leftwards arrow to bar over rightwards arrow to bar}%
+\xUnicodeMathSymbol{"021BA}{\acwopencirclearrow }{\mathord}{anticlockwise open circle arrow}%
+\xUnicodeMathSymbol{"021BB}{\cwopencirclearrow }{\mathord}{clockwise open circle arrow}%
+\xUnicodeMathSymbol{"021BC}{\leftharpoonup }{\mathrel}{left harpoon-up}%
+\xUnicodeMathSymbol{"021BD}{\leftharpoondown }{\mathrel}{left harpoon-down}%
+\xUnicodeMathSymbol{"021BE}{\upharpoonright }{\mathrel}{/upharpoonright /restriction a: up harpoon-right}%
+\xUnicodeMathSymbol{"021BF}{\upharpoonleft }{\mathrel}{up harpoon-left}%
+\xUnicodeMathSymbol{"021C0}{\rightharpoonup }{\mathrel}{right harpoon-up}%
+\xUnicodeMathSymbol{"021C1}{\rightharpoondown }{\mathrel}{right harpoon-down}%
+\xUnicodeMathSymbol{"021C2}{\downharpoonright }{\mathrel}{down harpoon-right}%
+\xUnicodeMathSymbol{"021C3}{\downharpoonleft }{\mathrel}{down harpoon-left}%
+\xUnicodeMathSymbol{"021C4}{\rightleftarrows }{\mathrel}{right arrow over left arrow}%
+\xUnicodeMathSymbol{"021C5}{\updownarrows }{\mathrel}{up arrow, down arrow}%
+\xUnicodeMathSymbol{"021C6}{\leftrightarrows }{\mathrel}{left arrow over right arrow}%
+\xUnicodeMathSymbol{"021C7}{\leftleftarrows }{\mathrel}{two left arrows}%
+\xUnicodeMathSymbol{"021C8}{\upuparrows }{\mathrel}{two up arrows}%
+\xUnicodeMathSymbol{"021C9}{\rightrightarrows }{\mathrel}{two right arrows}%
+\xUnicodeMathSymbol{"021CA}{\downdownarrows }{\mathrel}{two down arrows}%
+\xUnicodeMathSymbol{"021CB}{\leftrightharpoons }{\mathrel}{left harpoon over right}%
+\xUnicodeMathSymbol{"021CC}{\rightleftharpoons }{\mathrel}{right harpoon over left}%
+\xUnicodeMathSymbol{"021CD}{\nLeftarrow }{\mathrel}{not implied by}%
+\xUnicodeMathSymbol{"021CE}{\nLeftrightarrow }{\mathrel}{not left and right double arrows}%
+\xUnicodeMathSymbol{"021CF}{\nRightarrow }{\mathrel}{not implies}%
+\xUnicodeMathSymbol{"021D0}{\Leftarrow }{\mathrel}{is implied by}%
+\xUnicodeMathSymbol{"021D1}{\Uparrow }{\mathrel}{up double arrow}%
+%\xUnicodeMathSymbol{"021D2}{\Rightarrow }{\mathrel}{implies}%
+\xxUnicodeMathSymbol{"02192}{\Rightarrow}{=>}
+\xUnicodeMathSymbol{"021D3}{\Downarrow }{\mathrel}{down double arrow}%
+\xUnicodeMathSymbol{"021D4}{\Leftrightarrow }{\mathrel}{left and right double arrow}%
+\xUnicodeMathSymbol{"021D5}{\Updownarrow }{\mathrel}{up and down double arrow}%
+\xUnicodeMathSymbol{"021D6}{\Nwarrow }{\mathrel}{nw pointing double arrow}%
+\xUnicodeMathSymbol{"021D7}{\Nearrow }{\mathrel}{ne pointing double arrow}%
+\xUnicodeMathSymbol{"021D8}{\Searrow }{\mathrel}{se pointing double arrow}%
+\xUnicodeMathSymbol{"021D9}{\Swarrow }{\mathrel}{sw pointing double arrow}%
+\xUnicodeMathSymbol{"021DA}{\Lleftarrow }{\mathrel}{left triple arrow}%
+\xUnicodeMathSymbol{"021DB}{\Rrightarrow }{\mathrel}{right triple arrow}%
+\xUnicodeMathSymbol{"021DC}{\leftsquigarrow }{\mathrel}{leftwards squiggle arrow}%
+\xUnicodeMathSymbol{"021DD}{\rightsquigarrow }{\mathrel}{rightwards squiggle arrow}%
+\xUnicodeMathSymbol{"021DE}{\nHuparrow }{\mathord}{upwards arrow with double stroke}%
+\xUnicodeMathSymbol{"021DF}{\nHdownarrow }{\mathord}{downwards arrow with double stroke}%
+\xUnicodeMathSymbol{"021E0}{\leftdasharrow }{\mathord}{leftwards dashed arrow}%
+\xUnicodeMathSymbol{"021E1}{\updasharrow }{\mathord}{upwards dashed arrow}%
+\xUnicodeMathSymbol{"021E2}{\rightdasharrow }{\mathord}{rightwards dashed arrow}%
+\xUnicodeMathSymbol{"021E3}{\downdasharrow }{\mathord}{downwards dashed arrow}%
+\xUnicodeMathSymbol{"021E4}{\barleftarrow }{\mathrel}{leftwards arrow to bar}%
+\xUnicodeMathSymbol{"021E5}{\rightarrowbar }{\mathrel}{rightwards arrow to bar}%
+\xUnicodeMathSymbol{"021E6}{\leftwhitearrow }{\mathord}{leftwards white arrow}%
+\xUnicodeMathSymbol{"021E7}{\upwhitearrow }{\mathord}{upwards white arrow}%
+\xUnicodeMathSymbol{"021E8}{\rightwhitearrow }{\mathord}{rightwards white arrow}%
+\xUnicodeMathSymbol{"021E9}{\downwhitearrow }{\mathord}{downwards white arrow}%
+\xUnicodeMathSymbol{"021EA}{\whitearrowupfrombar }{\mathord}{upwards white arrow from bar}%
+\xUnicodeMathSymbol{"021F4}{\circleonrightarrow }{\mathrel}{right arrow with small circle}%
+\xUnicodeMathSymbol{"021F5}{\downuparrows }{\mathrel}{downwards arrow leftwards of upwards arrow}%
+\xUnicodeMathSymbol{"021F6}{\rightthreearrows }{\mathrel}{three rightwards arrows}%
+\xUnicodeMathSymbol{"021F7}{\nvleftarrow }{\mathrel}{leftwards arrow with vertical stroke}%
+\xUnicodeMathSymbol{"021F8}{\nvrightarrow }{\mathrel}{rightwards arrow with vertical stroke}%
+\xUnicodeMathSymbol{"021F9}{\nvleftrightarrow }{\mathrel}{left right arrow with vertical stroke}%
+\xUnicodeMathSymbol{"021FA}{\nVleftarrow }{\mathrel}{leftwards arrow with double vertical stroke}%
+\xUnicodeMathSymbol{"021FB}{\nVrightarrow }{\mathrel}{rightwards arrow with double vertical stroke}%
+\xUnicodeMathSymbol{"021FC}{\nVleftrightarrow }{\mathrel}{left right arrow with double vertical stroke}%
+\xUnicodeMathSymbol{"021FD}{\leftarrowtriangle }{\mathrel}{leftwards open-headed arrow}%
+\xUnicodeMathSymbol{"021FE}{\rightarrowtriangle }{\mathrel}{rightwards open-headed arrow}%
+\xUnicodeMathSymbol{"021FF}{\leftrightarrowtriangle }{\mathrel}{left right open-headed arrow}%
+\xUnicodeMathSymbol{"02200}{\forall }{\mathord}{for all}%
+\xUnicodeMathSymbol{"02201}{\complement }{\mathord}{complement sign}%
+\xUnicodeMathSymbol{"02202}{\partial }{\mathalpha}{partial differential}%
+\xUnicodeMathSymbol{"02203}{\exists }{\mathord}{at least one exists}%
+\xUnicodeMathSymbol{"02204}{\nexists }{\mathord}{negated exists}%
+\xUnicodeMathSymbol{"02205}{\varnothing }{\mathord}{circle, slash}%
+\xUnicodeMathSymbol{"02206}{\increment }{\mathord}{laplacian (delta; nabla\string^2)}%
+\xUnicodeMathSymbol{"02207}{\nabla }{\mathalpha}{nabla, del, hamilton operator}%
+\xUnicodeMathSymbol{"02208}{\in }{\mathrel}{set membership, variant}%
+\xUnicodeMathSymbol{"02209}{\notin }{\mathrel}{negated set membership}%
+\xUnicodeMathSymbol{"0220A}{\smallin }{\mathrel}{set membership (small set membership)}%
+\xUnicodeMathSymbol{"0220B}{\ni }{\mathrel}{contains, variant}%
+\xUnicodeMathSymbol{"0220C}{\nni }{\mathrel}{negated contains, variant}%
+\xUnicodeMathSymbol{"0220D}{\smallni }{\mathrel}{/ni /owns r: contains (small contains as member)}%
+\xUnicodeMathSymbol{"0220E}{\QED }{\mathord}{end of proof}%
+\xUnicodeMathSymbol{"0220F}{\prod }{\mathop}{product operator}%
+\xUnicodeMathSymbol{"02210}{\coprod }{\mathop}{coproduct operator}%
+\xUnicodeMathSymbol{"02211}{\sum }{\mathop}{summation operator}%
+\xUnicodeMathSymbol{"02212}{\minus }{\mathbin}{minus sign}%
+\xUnicodeMathSymbol{"02213}{\mp }{\mathbin}{minus-or-plus sign}%
+\xUnicodeMathSymbol{"02214}{\dotplus }{\mathbin}{plus sign, dot above}%
+\xUnicodeMathSymbol{"02215}{\divslash }{\mathbin}{division slash}%
+\xUnicodeMathSymbol{"02216}{\smallsetminus }{\mathbin}{small set minus (cf. reverse solidus)}%
+\xUnicodeMathSymbol{"02217}{\ast }{\mathbin}{centered asterisk}%
+\xUnicodeMathSymbol{"02218}{\vysmwhtcircle }{\mathbin}{composite function (small circle)}%
+\xUnicodeMathSymbol{"02219}{\vysmblkcircle }{\mathbin}{bullet operator}%
+\xUnicodeMathSymbol{"0221A}{\sqrt }{\mathopen}{radical}%
+\xUnicodeMathSymbol{"0221B}{\cuberoot }{\mathopen}{cube root}%
+\xUnicodeMathSymbol{"0221C}{\fourthroot }{\mathopen}{fourth root}%
+\xUnicodeMathSymbol{"0221D}{\propto }{\mathrel}{is proportional to}%
+\xUnicodeMathSymbol{"0221E}{\infty }{\mathord}{infinity}%
+\xUnicodeMathSymbol{"0221F}{\rightangle }{\mathord}{right (90 degree) angle}%
+\xUnicodeMathSymbol{"02220}{\angle }{\mathord}{angle}%
+\xUnicodeMathSymbol{"02221}{\measuredangle }{\mathord}{angle-measured}%
+\xUnicodeMathSymbol{"02222}{\sphericalangle }{\mathord}{angle-spherical}%
+\xUnicodeMathSymbol{"02223}{\mid }{\mathrel}{/mid r:}%
+\xUnicodeMathSymbol{"02224}{\nmid }{\mathrel}{negated mid}%
+\xUnicodeMathSymbol{"02225}{\parallel }{\mathrel}{parallel}%
+\xUnicodeMathSymbol{"02226}{\nparallel }{\mathrel}{not parallel}%
+\xUnicodeMathSymbol{"02227}{\wedge }{\mathbin}{/wedge /land b: logical and}%
+\xUnicodeMathSymbol{"02228}{\vee }{\mathbin}{/vee /lor b: logical or}%
+\xUnicodeMathSymbol{"02229}{\cap }{\mathbin}{intersection}%
+\xUnicodeMathSymbol{"0222A}{\cup }{\mathbin}{union or logical sum}%
+%\xUnicodeMathSymbol{"0222B}{\int }{\mathop}{integral operator}%
+\xUnicodeMathSymbol{"0222C}{\iint }{\mathop}{double integral operator}%
+\xUnicodeMathSymbol{"0222D}{\iiint }{\mathop}{triple integral operator}%
+\xUnicodeMathSymbol{"0222E}{\oint }{\mathop}{contour integral operator}%
+\xUnicodeMathSymbol{"0222F}{\oiint }{\mathop}{double contour integral operator}%
+\xUnicodeMathSymbol{"02230}{\oiiint }{\mathop}{triple contour integral operator}%
+\xUnicodeMathSymbol{"02231}{\intclockwise }{\mathop}{clockwise integral}%
+\xUnicodeMathSymbol{"02232}{\varointclockwise }{\mathop}{contour integral, clockwise}%
+\xUnicodeMathSymbol{"02233}{\ointctrclockwise }{\mathop}{contour integral, anticlockwise}%
+\xUnicodeMathSymbol{"02234}{\therefore }{\mathord}{therefore}%
+\xUnicodeMathSymbol{"02235}{\because }{\mathord}{because}%
+\xUnicodeMathSymbol{"02236}{\mathratio }{\mathrel}{ratio}%
+\xUnicodeMathSymbol{"02237}{\Colon }{\mathrel}{two colons}%
+\xUnicodeMathSymbol{"02238}{\dotminus }{\mathbin}{minus sign, dot above}%
+\xUnicodeMathSymbol{"02239}{\dashcolon }{\mathrel}{excess (-:)}%
+\xUnicodeMathSymbol{"0223A}{\dotsminusdots }{\mathrel}{minus with four dots, geometric properties}%
+\xUnicodeMathSymbol{"0223B}{\kernelcontraction }{\mathrel}{homothetic}%
+\xUnicodeMathSymbol{"0223C}{\sim }{\mathrel}{similar}%
+\xUnicodeMathSymbol{"0223D}{\backsim }{\mathrel}{reverse similar}%
+\xUnicodeMathSymbol{"0223E}{\invlazys }{\mathbin}{most positive [inverted lazy s]}%
+\xUnicodeMathSymbol{"0223F}{\sinewave }{\mathord}{sine wave}%
+\xUnicodeMathSymbol{"02240}{\wr }{\mathbin}{wreath product}%
+\xUnicodeMathSymbol{"02241}{\nsim }{\mathrel}{not similar}%
+\xUnicodeMathSymbol{"02242}{\eqsim }{\mathrel}{equals, similar}%
+\xUnicodeMathSymbol{"02243}{\simeq }{\mathrel}{similar, equals}%
+\xUnicodeMathSymbol{"02244}{\nsime }{\mathrel}{not similar, equals}%
+\xUnicodeMathSymbol{"02245}{\cong }{\mathrel}{congruent with}%
+\xUnicodeMathSymbol{"02246}{\simneqq }{\mathrel}{similar, not equals [vert only for 9573 entity]}%
+\xUnicodeMathSymbol{"02247}{\ncong }{\mathrel}{not congruent with}%
+\xUnicodeMathSymbol{"02248}{\approx }{\mathrel}{approximate}%
+\xUnicodeMathSymbol{"02249}{\napprox }{\mathrel}{not approximate}%
+\xUnicodeMathSymbol{"0224A}{\approxeq }{\mathrel}{approximate, equals}%
+\xUnicodeMathSymbol{"0224B}{\approxident }{\mathrel}{approximately identical to}%
+\xUnicodeMathSymbol{"0224C}{\backcong }{\mathrel}{all equal to}%
+\xUnicodeMathSymbol{"0224D}{\asymp }{\mathrel}{asymptotically equal to}%
+\xUnicodeMathSymbol{"0224E}{\Bumpeq }{\mathrel}{bumpy equals}%
+\xUnicodeMathSymbol{"0224F}{\bumpeq }{\mathrel}{bumpy equals, equals}%
+\xUnicodeMathSymbol{"02250}{\doteq }{\mathrel}{equals, single dot above}%
+\xUnicodeMathSymbol{"02251}{\Doteq }{\mathrel}{/doteqdot /doteq r: equals, even dots}%
+\xUnicodeMathSymbol{"02252}{\fallingdotseq }{\mathrel}{equals, falling dots}%
+\xUnicodeMathSymbol{"02253}{\risingdotseq }{\mathrel}{equals, rising dots}%
+\xUnicodeMathSymbol{"02254}{\coloneq }{\mathrel}{colon, equals}%
+\xUnicodeMathSymbol{"02255}{\eqcolon }{\mathrel}{equals, colon}%
+\xUnicodeMathSymbol{"02256}{\eqcirc }{\mathrel}{circle on equals sign}%
+\xUnicodeMathSymbol{"02257}{\circeq }{\mathrel}{circle, equals}%
+\xUnicodeMathSymbol{"02258}{\arceq }{\mathrel}{arc, equals; corresponds to}%
+\xUnicodeMathSymbol{"02259}{\wedgeq }{\mathrel}{corresponds to (wedge, equals)}%
+\xUnicodeMathSymbol{"0225A}{\veeeq }{\mathrel}{logical or, equals}%
+\xUnicodeMathSymbol{"0225B}{\stareq }{\mathrel}{star equals}%
+\xUnicodeMathSymbol{"0225C}{\triangleq }{\mathrel}{triangle, equals}%
+\xUnicodeMathSymbol{"0225D}{\eqdef }{\mathrel}{equals by definition}%
+\xUnicodeMathSymbol{"0225E}{\measeq }{\mathrel}{measured by (m over equals)}%
+\xUnicodeMathSymbol{"0225F}{\questeq }{\mathrel}{equal with questionmark}%
+\xUnicodeMathSymbol{"02260}{\ne }{\mathrel}{/ne /neq r: not equal}%
+\xUnicodeMathSymbol{"02261}{\equiv }{\mathrel}{identical with}%
+\xUnicodeMathSymbol{"02262}{\nequiv }{\mathrel}{not identical with}%
+\xUnicodeMathSymbol{"02263}{\Equiv }{\mathrel}{strict equivalence (4 lines)}%
+\xUnicodeMathSymbol{"02264}{\leq }{\mathrel}{/leq /le r: less-than-or-equal}%
+\xUnicodeMathSymbol{"02265}{\geq }{\mathrel}{/geq /ge r: greater-than-or-equal}%
+\xUnicodeMathSymbol{"02266}{\leqq }{\mathrel}{less, double equals}%
+\xUnicodeMathSymbol{"02267}{\geqq }{\mathrel}{greater, double equals}%
+\xUnicodeMathSymbol{"02268}{\lneqq }{\mathrel}{less, not double equals}%
+\xUnicodeMathSymbol{"02269}{\gneqq }{\mathrel}{greater, not double equals}%
+\xUnicodeMathSymbol{"0226A}{\ll }{\mathrel}{much less than, type 2}%
+\xUnicodeMathSymbol{"0226B}{\gg }{\mathrel}{much greater than, type 2}%
+\xUnicodeMathSymbol{"0226C}{\between }{\mathrel}{between}%
+\xUnicodeMathSymbol{"0226D}{\nasymp }{\mathrel}{not asymptotically equal to}%
+\xUnicodeMathSymbol{"0226E}{\nless }{\mathrel}{not less-than}%
+\xUnicodeMathSymbol{"0226F}{\ngtr }{\mathrel}{not greater-than}%
+\xUnicodeMathSymbol{"02270}{\nleq }{\mathrel}{not less-than-or-equal}%
+\xUnicodeMathSymbol{"02271}{\ngeq }{\mathrel}{not greater-than-or-equal}%
+\xUnicodeMathSymbol{"02272}{\lesssim }{\mathrel}{less, similar}%
+\xUnicodeMathSymbol{"02273}{\gtrsim }{\mathrel}{greater, similar}%
+\xUnicodeMathSymbol{"02274}{\nlesssim }{\mathrel}{not less, similar}%
+\xUnicodeMathSymbol{"02275}{\ngtrsim }{\mathrel}{not greater, similar}%
+\xUnicodeMathSymbol{"02276}{\lessgtr }{\mathrel}{less, greater}%
+\xUnicodeMathSymbol{"02277}{\gtrless }{\mathrel}{greater, less}%
+\xUnicodeMathSymbol{"02278}{\nlessgtr }{\mathrel}{not less, greater}%
+\xUnicodeMathSymbol{"02279}{\ngtrless }{\mathrel}{not greater, less}%
+\xUnicodeMathSymbol{"0227A}{\prec }{\mathrel}{precedes}%
+\xUnicodeMathSymbol{"0227B}{\succ }{\mathrel}{succeeds}%
+\xUnicodeMathSymbol{"0227C}{\preccurlyeq }{\mathrel}{precedes, curly equals}%
+\xUnicodeMathSymbol{"0227D}{\succcurlyeq }{\mathrel}{succeeds, curly equals}%
+\xUnicodeMathSymbol{"0227E}{\precsim }{\mathrel}{precedes, similar}%
+\xUnicodeMathSymbol{"0227F}{\succsim }{\mathrel}{succeeds, similar}%
+\xUnicodeMathSymbol{"02280}{\nprec }{\mathrel}{not precedes}%
+\xUnicodeMathSymbol{"02281}{\nsucc }{\mathrel}{not succeeds}%
+\xUnicodeMathSymbol{"02282}{\subset }{\mathrel}{subset or is implied by}%
+\xUnicodeMathSymbol{"02283}{\supset }{\mathrel}{superset or implies}%
+\xUnicodeMathSymbol{"02284}{\nsubset }{\mathrel}{not subset, variant [slash negation]}%
+\xUnicodeMathSymbol{"02285}{\nsupset }{\mathrel}{not superset, variant [slash negation]}%
+\xUnicodeMathSymbol{"02286}{\subseteq }{\mathrel}{subset, equals}%
+\xUnicodeMathSymbol{"02287}{\supseteq }{\mathrel}{superset, equals}%
+\xUnicodeMathSymbol{"02288}{\nsubseteq }{\mathrel}{not subset, equals}%
+\xUnicodeMathSymbol{"02289}{\nsupseteq }{\mathrel}{not superset, equals}%
+\xUnicodeMathSymbol{"0228A}{\subsetneq }{\mathrel}{subset, not equals}%
+\xUnicodeMathSymbol{"0228B}{\supsetneq }{\mathrel}{superset, not equals}%
+\xUnicodeMathSymbol{"0228C}{\cupleftarrow }{\mathbin}{multiset}%
+\xUnicodeMathSymbol{"0228D}{\cupdot }{\mathbin}{union, with dot}%
+\xUnicodeMathSymbol{"0228E}{\uplus }{\mathbin}{plus sign in union}%
+\xUnicodeMathSymbol{"0228F}{\sqsubset }{\mathrel}{square subset}%
+\xUnicodeMathSymbol{"02290}{\sqsupset }{\mathrel}{square superset}%
+\xUnicodeMathSymbol{"02291}{\sqsubseteq }{\mathrel}{square subset, equals}%
+\xUnicodeMathSymbol{"02292}{\sqsupseteq }{\mathrel}{square superset, equals}%
+\xUnicodeMathSymbol{"02293}{\sqcap }{\mathbin}{square intersection}%
+\xUnicodeMathSymbol{"02294}{\sqcup }{\mathbin}{square union}%
+\xUnicodeMathSymbol{"02295}{\oplus }{\mathbin}{plus sign in circle}%
+\xUnicodeMathSymbol{"02296}{\ominus }{\mathbin}{minus sign in circle}%
+\xUnicodeMathSymbol{"02297}{\otimes }{\mathbin}{multiply sign in circle}%
+\xUnicodeMathSymbol{"02298}{\oslash }{\mathbin}{solidus in circle}%
+\xUnicodeMathSymbol{"02299}{\odot }{\mathbin}{middle dot in circle}%
+\xUnicodeMathSymbol{"0229A}{\circledcirc }{\mathbin}{small circle in circle}%
+\xUnicodeMathSymbol{"0229B}{\circledast }{\mathbin}{asterisk in circle}%
+\xUnicodeMathSymbol{"0229C}{\circledequal }{\mathbin}{equal in circle}%
+\xUnicodeMathSymbol{"0229D}{\circleddash }{\mathbin}{hyphen in circle}%
+\xUnicodeMathSymbol{"0229E}{\boxplus }{\mathbin}{plus sign in box}%
+\xUnicodeMathSymbol{"0229F}{\boxminus }{\mathbin}{minus sign in box}%
+\xUnicodeMathSymbol{"022A0}{\boxtimes }{\mathbin}{multiply sign in box}%
+\xUnicodeMathSymbol{"022A1}{\boxdot }{\mathbin}{/dotsquare /boxdot b: small dot in box}%
+\xUnicodeMathSymbol{"022A2}{\vdash }{\mathrel}{vertical, dash}%
+\xUnicodeMathSymbol{"022A3}{\dashv }{\mathrel}{dash, vertical}%
+\xUnicodeMathSymbol{"022A4}{\top }{\mathord}{top}%
+\xUnicodeMathSymbol{"022A5}{\bot }{\mathord}{bottom}%
+\xUnicodeMathSymbol{"022A6}{\assert }{\mathrel}{assertion (vertical, short dash)}%
+\xUnicodeMathSymbol{"022A7}{\models }{\mathrel}{models (vertical, short double dash)}%
+\xUnicodeMathSymbol{"022A8}{\vDash }{\mathrel}{vertical, double dash}%
+\xUnicodeMathSymbol{"022A9}{\Vdash }{\mathrel}{double vertical, dash}%
+\xUnicodeMathSymbol{"022AA}{\Vvdash }{\mathrel}{triple vertical, dash}%
+\xUnicodeMathSymbol{"022AB}{\VDash }{\mathrel}{double vert, double dash}%
+\xUnicodeMathSymbol{"022AC}{\nvdash }{\mathrel}{not vertical, dash}%
+\xUnicodeMathSymbol{"022AD}{\nvDash }{\mathrel}{not vertical, double dash}%
+\xUnicodeMathSymbol{"022AE}{\nVdash }{\mathrel}{not double vertical, dash}%
+\xUnicodeMathSymbol{"022AF}{\nVDash }{\mathrel}{not double vert, double dash}%
+\xUnicodeMathSymbol{"022B0}{\prurel }{\mathrel}{element precedes under relation}%
+\xUnicodeMathSymbol{"022B1}{\scurel }{\mathrel}{succeeds under relation}%
+\xUnicodeMathSymbol{"022B2}{\vartriangleleft }{\mathrel}{left triangle, open, variant}%
+\xUnicodeMathSymbol{"022B3}{\vartriangleright }{\mathrel}{right triangle, open, variant}%
+\xUnicodeMathSymbol{"022B4}{\trianglelefteq }{\mathrel}{left triangle, equals}%
+\xUnicodeMathSymbol{"022B5}{\trianglerighteq }{\mathrel}{right triangle, equals}%
+\xUnicodeMathSymbol{"022B6}{\origof }{\mathrel}{original of}%
+\xUnicodeMathSymbol{"022B7}{\imageof }{\mathrel}{image of}%
+\xUnicodeMathSymbol{"022B8}{\multimap }{\mathrel}{/multimap a:}%
+\xUnicodeMathSymbol{"022B9}{\hermitmatrix }{\mathord}{hermitian conjugate matrix}%
+\xUnicodeMathSymbol{"022BA}{\intercal }{\mathbin}{intercal}%
+\xUnicodeMathSymbol{"022BB}{\veebar }{\mathbin}{logical or, bar below (large vee); exclusive disjunction}%
+\xUnicodeMathSymbol{"022BC}{\barwedge }{\mathbin}{bar, wedge (large wedge)}%
+\xUnicodeMathSymbol{"022BD}{\barvee }{\mathbin}{bar, vee (large vee)}%
+\xUnicodeMathSymbol{"022BE}{\measuredrightangle }{\mathord}{right angle-measured [with arc]}%
+\xUnicodeMathSymbol{"022BF}{\varlrtriangle }{\mathord}{right triangle}%
+\xUnicodeMathSymbol{"022C0}{\bigwedge }{\mathop}{logical or operator}%
+\xUnicodeMathSymbol{"022C1}{\bigvee }{\mathop}{logical and operator}%
+\xUnicodeMathSymbol{"022C2}{\bigcap }{\mathop}{intersection operator}%
+\xUnicodeMathSymbol{"022C3}{\bigcup }{\mathop}{union operator}%
+\xUnicodeMathSymbol{"022C4}{\smwhtdiamond }{\mathbin}{white diamond}%
+\xUnicodeMathSymbol{"022C5}{\cdot }{\mathbin}{small middle dot}%
+\xUnicodeMathSymbol{"022C6}{\star }{\mathbin}{small star, filled, low}%
+\xUnicodeMathSymbol{"022C7}{\divideontimes }{\mathbin}{division on times}%
+\xUnicodeMathSymbol{"022C8}{\bowtie }{\mathrel}{bowtie}%
+\xUnicodeMathSymbol{"022C9}{\ltimes }{\mathbin}{times sign, left closed}%
+\xUnicodeMathSymbol{"022CA}{\rtimes }{\mathbin}{times sign, right closed}%
+\xUnicodeMathSymbol{"022CB}{\leftthreetimes }{\mathbin}{left semidirect product}%
+\xUnicodeMathSymbol{"022CC}{\rightthreetimes }{\mathbin}{right semidirect product}%
+\xUnicodeMathSymbol{"022CD}{\backsimeq }{\mathrel}{reverse similar, equals}%
+\xUnicodeMathSymbol{"022CE}{\curlyvee }{\mathbin}{curly logical or}%
+\xUnicodeMathSymbol{"022CF}{\curlywedge }{\mathbin}{curly logical and}%
+\xUnicodeMathSymbol{"022D0}{\Subset }{\mathrel}{double subset}%
+\xUnicodeMathSymbol{"022D1}{\Supset }{\mathrel}{double superset}%
+\xUnicodeMathSymbol{"022D2}{\Cap }{\mathbin}{/cap /doublecap b: double intersection}%
+\xUnicodeMathSymbol{"022D3}{\Cup }{\mathbin}{/cup /doublecup b: double union}%
+\xUnicodeMathSymbol{"022D4}{\pitchfork }{\mathrel}{pitchfork}%
+\xUnicodeMathSymbol{"022D5}{\equalparallel }{\mathrel}{parallel, equal; equal or parallel}%
+\xUnicodeMathSymbol{"022D6}{\lessdot }{\mathrel}{less than, with dot}%
+\xUnicodeMathSymbol{"022D7}{\gtrdot }{\mathrel}{greater than, with dot}%
+\xUnicodeMathSymbol{"022D8}{\lll }{\mathrel}{/ll /lll /llless r: triple less-than}%
+\xUnicodeMathSymbol{"022D9}{\ggg }{\mathrel}{/ggg /gg /gggtr r: triple greater-than}%
+\xUnicodeMathSymbol{"022DA}{\lesseqgtr }{\mathrel}{less, equals, greater}%
+\xUnicodeMathSymbol{"022DB}{\gtreqless }{\mathrel}{greater, equals, less}%
+\xUnicodeMathSymbol{"022DC}{\eqless }{\mathrel}{equal-or-less}%
+\xUnicodeMathSymbol{"022DD}{\eqgtr }{\mathrel}{equal-or-greater}%
+\xUnicodeMathSymbol{"022DE}{\curlyeqprec }{\mathrel}{curly equals, precedes}%
+\xUnicodeMathSymbol{"022DF}{\curlyeqsucc }{\mathrel}{curly equals, succeeds}%
+\xUnicodeMathSymbol{"022E0}{\npreccurlyeq }{\mathrel}{not precedes, curly equals}%
+\xUnicodeMathSymbol{"022E1}{\nsucccurlyeq }{\mathrel}{not succeeds, curly equals}%
+\xUnicodeMathSymbol{"022E2}{\nsqsubseteq }{\mathrel}{not, square subset, equals}%
+\xUnicodeMathSymbol{"022E3}{\nsqsupseteq }{\mathrel}{not, square superset, equals}%
+\xUnicodeMathSymbol{"022E4}{\sqsubsetneq }{\mathrel}{square subset, not equals}%
+\xUnicodeMathSymbol{"022E5}{\sqsupsetneq }{\mathrel}{square superset, not equals}%
+\xUnicodeMathSymbol{"022E6}{\lnsim }{\mathrel}{less, not similar}%
+\xUnicodeMathSymbol{"022E7}{\gnsim }{\mathrel}{greater, not similar}%
+\xUnicodeMathSymbol{"022E8}{\precnsim }{\mathrel}{precedes, not similar}%
+\xUnicodeMathSymbol{"022E9}{\succnsim }{\mathrel}{succeeds, not similar}%
+\xUnicodeMathSymbol{"022EA}{\nvartriangleleft }{\mathrel}{not left triangle}%
+\xUnicodeMathSymbol{"022EB}{\nvartriangleright }{\mathrel}{not right triangle}%
+\xUnicodeMathSymbol{"022EC}{\ntrianglelefteq }{\mathrel}{not left triangle, equals}%
+\xUnicodeMathSymbol{"022ED}{\ntrianglerighteq }{\mathrel}{not right triangle, equals}%
+\xUnicodeMathSymbol{"022EE}{\vdots }{\mathrel}{vertical ellipsis}%
+\xUnicodeMathSymbol{"022EF}{\unicodecdots }{\mathord}{three dots, centered}%
+\xUnicodeMathSymbol{"022F0}{\adots }{\mathrel}{three dots, ascending}%
+\xUnicodeMathSymbol{"022F1}{\ddots }{\mathrel}{three dots, descending}%
+\xUnicodeMathSymbol{"022F2}{\disin }{\mathrel}{element of with long horizontal stroke}%
+\xUnicodeMathSymbol{"022F3}{\varisins }{\mathrel}{element of with vertical bar at end of horizontal stroke}%
+\xUnicodeMathSymbol{"022F4}{\isins }{\mathrel}{small element of with vertical bar at end of horizontal stroke}%
+\xUnicodeMathSymbol{"022F5}{\isindot }{\mathrel}{element of with dot above}%
+\xUnicodeMathSymbol{"022F6}{\varisinobar }{\mathrel}{element of with overbar}%
+\xUnicodeMathSymbol{"022F7}{\isinobar }{\mathrel}{small element of with overbar}%
+\xUnicodeMathSymbol{"022F8}{\isinvb }{\mathrel}{element of with underbar}%
+\xUnicodeMathSymbol{"022F9}{\isinE }{\mathrel}{element of with two horizontal strokes}%
+\xUnicodeMathSymbol{"022FA}{\nisd }{\mathrel}{contains with long horizontal stroke}%
+\xUnicodeMathSymbol{"022FB}{\varnis }{\mathrel}{contains with vertical bar at end of horizontal stroke}%
+\xUnicodeMathSymbol{"022FC}{\nis }{\mathrel}{small contains with vertical bar at end of horizontal stroke}%
+\xUnicodeMathSymbol{"022FD}{\varniobar }{\mathrel}{contains with overbar}%
+\xUnicodeMathSymbol{"022FE}{\niobar }{\mathrel}{small contains with overbar}%
+\xUnicodeMathSymbol{"022FF}{\bagmember }{\mathrel}{z notation bag membership}%
+\xUnicodeMathSymbol{"02300}{\diameter }{\mathord}{diameter sign}%
+\xUnicodeMathSymbol{"02302}{\house }{\mathord}{house}%
+\xUnicodeMathSymbol{"02305}{\varbarwedge }{\mathbin}{/barwedge b: logical and, bar above [projective (bar over small wedge)]}%
+\xUnicodeMathSymbol{"02306}{\vardoublebarwedge }{\mathbin}{/doublebarwedge b: logical and, double bar above [perspective (double bar over small wedge)]}%
+\xUnicodeMathSymbol{"02308}{\lceil }{\mathopen}{left ceiling}%
+\xUnicodeMathSymbol{"02309}{\rceil }{\mathclose}{right ceiling}%
+\xUnicodeMathSymbol{"0230A}{\lfloor }{\mathopen}{left floor}%
+\xUnicodeMathSymbol{"0230B}{\rfloor }{\mathclose}{right floor}%
+\xUnicodeMathSymbol{"02310}{\invnot }{\mathord}{reverse not}%
+\xUnicodeMathSymbol{"02311}{\sqlozenge }{\mathord}{square lozenge}%
+\xUnicodeMathSymbol{"02312}{\profline }{\mathord}{profile of a line}%
+\xUnicodeMathSymbol{"02313}{\profsurf }{\mathord}{profile of a surface}%
+\xUnicodeMathSymbol{"02317}{\viewdata }{\mathord}{viewdata square}%
+\xUnicodeMathSymbol{"02319}{\turnednot }{\mathord}{turned not sign}%
+\xUnicodeMathSymbol{"0231C}{\ulcorner }{\mathopen}{upper left corner}%
+\xUnicodeMathSymbol{"0231D}{\urcorner }{\mathclose}{upper right corner}%
+\xUnicodeMathSymbol{"0231E}{\llcorner }{\mathopen}{lower left corner}%
+\xUnicodeMathSymbol{"0231F}{\lrcorner }{\mathclose}{lower right corner}%
+\xUnicodeMathSymbol{"02320}{\inttop }{\mathord}{top half integral}%
+\xUnicodeMathSymbol{"02321}{\intbottom }{\mathord}{bottom half integral}%
+\xUnicodeMathSymbol{"02322}{\frown }{\mathrel}{down curve}%
+\xUnicodeMathSymbol{"02323}{\smile }{\mathrel}{up curve}%
+\xUnicodeMathSymbol{"0232C}{\varhexagonlrbonds }{\mathord}{six carbon ring, corner down, double bonds lower right etc}%
+\xUnicodeMathSymbol{"02332}{\conictaper }{\mathord}{conical taper }%
+\xUnicodeMathSymbol{"02336}{\topbot }{\mathord}{top and bottom}%
+\xUnicodeMathSymbol{"0233D}{\obar }{\mathbin}{circle with vertical bar}%
+\xUnicodeMathSymbol{"0233F}{\APLnotslash }{\mathrel}{solidus, bar through (apl functional symbol slash bar)}%
+\xUnicodeMathSymbol{"02340}{\APLnotbackslash }{\mathord}{apl functional symbol backslash bar}%
+\xUnicodeMathSymbol{"02353}{\APLboxupcaret }{\mathord}{boxed up caret}%
+\xUnicodeMathSymbol{"02370}{\APLboxquestion }{\mathord}{boxed question mark}%
+\xUnicodeMathSymbol{"0237C}{\rangledownzigzagarrow }{\mathord}{right angle with downwards zigzag arrow}%
+\xUnicodeMathSymbol{"02394}{\hexagon }{\mathord}{horizontal benzene ring [hexagon flat open]}%
+\xUnicodeMathSymbol{"0239B}{\lparenuend }{\mathord}{left parenthesis upper hook}%
+\xUnicodeMathSymbol{"0239C}{\lparenextender }{\mathord}{left parenthesis extension}%
+\xUnicodeMathSymbol{"0239D}{\lparenlend }{\mathord}{left parenthesis lower hook}%
+\xUnicodeMathSymbol{"0239E}{\rparenuend }{\mathord}{right parenthesis upper hook}%
+\xUnicodeMathSymbol{"0239F}{\rparenextender }{\mathord}{right parenthesis extension}%
+\xUnicodeMathSymbol{"023A0}{\rparenlend }{\mathord}{right parenthesis lower hook}%
+\xUnicodeMathSymbol{"023A1}{\lbrackuend }{\mathord}{left square bracket upper corner}%
+\xUnicodeMathSymbol{"023A2}{\lbrackextender }{\mathord}{left square bracket extension}%
+\xUnicodeMathSymbol{"023A3}{\lbracklend }{\mathord}{left square bracket lower corner}%
+\xUnicodeMathSymbol{"023A4}{\rbrackuend }{\mathord}{right square bracket upper corner}%
+\xUnicodeMathSymbol{"023A5}{\rbrackextender }{\mathord}{right square bracket extension}%
+\xUnicodeMathSymbol{"023A6}{\rbracklend }{\mathord}{right square bracket lower corner}%
+\xUnicodeMathSymbol{"023A7}{\lbraceuend }{\mathord}{left curly bracket upper hook}%
+\xUnicodeMathSymbol{"023A8}{\lbracemid }{\mathord}{left curly bracket middle piece}%
+\xUnicodeMathSymbol{"023A9}{\lbracelend }{\mathord}{left curly bracket lower hook}%
+\xUnicodeMathSymbol{"023AA}{\vbraceextender }{\mathord}{curly bracket extension}%
+\xUnicodeMathSymbol{"023AB}{\rbraceuend }{\mathord}{right curly bracket upper hook}%
+\xUnicodeMathSymbol{"023AC}{\rbracemid }{\mathord}{right curly bracket middle piece}%
+\xUnicodeMathSymbol{"023AD}{\rbracelend }{\mathord}{right curly bracket lower hook}%
+\xUnicodeMathSymbol{"023AE}{\intextender }{\mathord}{integral extension}%
+\xUnicodeMathSymbol{"023AF}{\harrowextender }{\mathord}{horizontal line extension (used to extend arrows)}%
+\xUnicodeMathSymbol{"023B0}{\lmoustache }{\mathopen}{upper left or lower right curly bracket section}%
+\xUnicodeMathSymbol{"023B1}{\rmoustache }{\mathclose}{upper right or lower left curly bracket section}%
+\xUnicodeMathSymbol{"023B2}{\sumtop }{\mathord}{summation top}%
+\xUnicodeMathSymbol{"023B3}{\sumbottom }{\mathord}{summation bottom}%
+\xUnicodeMathSymbol{"023B4}{\overbracket }{\mathover}{top square bracket}%
+\xUnicodeMathSymbol{"023B5}{\underbracket }{\mathunder}{bottom square bracket}%
+\xUnicodeMathSymbol{"023B6}{\bbrktbrk }{\mathord}{bottom square bracket over top square bracket}%
+\xUnicodeMathSymbol{"023B7}{\sqrtbottom }{\mathord}{radical symbol bottom}%
+\xUnicodeMathSymbol{"023B8}{\lvboxline }{\mathord}{left vertical box line}%
+\xUnicodeMathSymbol{"023B9}{\rvboxline }{\mathord}{right vertical box line}%
+\xUnicodeMathSymbol{"023CE}{\varcarriagereturn }{\mathord}{return symbol}%
+\xUnicodeMathSymbol{"023DC}{\overparen }{\mathover}{top parenthesis (mathematical use)}%
+\xUnicodeMathSymbol{"023DD}{\underparen }{\mathunder}{bottom parenthesis (mathematical use)}%
+\xUnicodeMathSymbol{"023DE}{\overbrace }{\mathover}{top curly bracket (mathematical use)}%
+\xUnicodeMathSymbol{"023DF}{\underbrace }{\mathunder}{bottom curly bracket (mathematical use)}%
+\xUnicodeMathSymbol{"023E0}{\obrbrak }{\mathord}{top tortoise shell bracket (mathematical use)}%
+\xUnicodeMathSymbol{"023E1}{\ubrbrak }{\mathord}{bottom tortoise shell bracket (mathematical use)}%
+\xUnicodeMathSymbol{"023E2}{\trapezium }{\mathord}{white trapezium}%
+\xUnicodeMathSymbol{"023E3}{\benzenr }{\mathord}{benzene ring with circle}%
+\xUnicodeMathSymbol{"023E4}{\strns }{\mathord}{straightness}%
+\xUnicodeMathSymbol{"023E5}{\fltns }{\mathord}{flatness}%
+\xUnicodeMathSymbol{"023E6}{\accurrent }{\mathord}{ac current}%
+\xUnicodeMathSymbol{"023E7}{\elinters }{\mathord}{electrical intersection}%
+\xUnicodeMathSymbol{"02422}{\blanksymbol }{\mathord}{blank symbol}%
+\xUnicodeMathSymbol{"02423}{\mathvisiblespace }{\mathord}{open box}%
+\xUnicodeMathSymbol{"02506}{\bdtriplevdash }{\mathord}{doubly broken vert}%
+\xUnicodeMathSymbol{"02580}{\blockuphalf }{\mathord}{upper half block}%
+\xUnicodeMathSymbol{"02584}{\blocklowhalf }{\mathord}{lower half block}%
+\xUnicodeMathSymbol{"02588}{\blockfull }{\mathord}{full block}%
+\xUnicodeMathSymbol{"0258C}{\blocklefthalf }{\mathord}{left half block}%
+\xUnicodeMathSymbol{"02590}{\blockrighthalf }{\mathord}{right half block}%
+\xUnicodeMathSymbol{"02591}{\blockqtrshaded }{\mathord}{25\% shaded block}%
+\xUnicodeMathSymbol{"02592}{\blockhalfshaded }{\mathord}{50\% shaded block}%
+\xUnicodeMathSymbol{"02593}{\blockthreeqtrshaded }{\mathord}{75\% shaded block}%
+\xUnicodeMathSymbol{"025A0}{\mdlgblksquare }{\mathord}{square, filled}%
+\xUnicodeMathSymbol{"025A1}{\mdlgwhtsquare }{\mathord}{square, open}%
+\xUnicodeMathSymbol{"025A2}{\squoval }{\mathord}{white square with rounded corners}%
+\xUnicodeMathSymbol{"025A3}{\blackinwhitesquare }{\mathord}{white square containing black small square}%
+\xUnicodeMathSymbol{"025A4}{\squarehfill }{\mathord}{square, horizontal rule filled}%
+\xUnicodeMathSymbol{"025A5}{\squarevfill }{\mathord}{square, vertical rule filled}%
+\xUnicodeMathSymbol{"025A6}{\squarehvfill }{\mathord}{square with orthogonal crosshatch fill}%
+\xUnicodeMathSymbol{"025A7}{\squarenwsefill }{\mathord}{square, nw-to-se rule filled}%
+\xUnicodeMathSymbol{"025A8}{\squareneswfill }{\mathord}{square, ne-to-sw rule filled}%
+\xUnicodeMathSymbol{"025A9}{\squarecrossfill }{\mathord}{square with diagonal crosshatch fill}%
+\xUnicodeMathSymbol{"025AA}{\smblksquare }{\mathord}{/blacksquare - sq bullet, filled}%
+\xUnicodeMathSymbol{"025AB}{\smwhtsquare }{\mathord}{white small square}%
+\xUnicodeMathSymbol{"025AC}{\hrectangleblack }{\mathord}{black rectangle}%
+\xUnicodeMathSymbol{"025AD}{\hrectangle }{\mathord}{horizontal rectangle, open}%
+\xUnicodeMathSymbol{"025AE}{\vrectangleblack }{\mathord}{black vertical rectangle}%
+\xUnicodeMathSymbol{"025AF}{\vrectangle }{\mathord}{rectangle, white (vertical)}%
+\xUnicodeMathSymbol{"025B0}{\parallelogramblack }{\mathord}{black parallelogram}%
+\xUnicodeMathSymbol{"025B1}{\parallelogram }{\mathord}{parallelogram, open}%
+\xUnicodeMathSymbol{"025B2}{\bigblacktriangleup }{\mathord}{ 0x25b2 6 6d black up-pointing triangle}%
+\xUnicodeMathSymbol{"025B3}{\bigtriangleup }{\mathbin}{big up triangle, open}%
+\xUnicodeMathSymbol{"025B4}{\blacktriangle }{\mathord}{up triangle, filled}%
+\xUnicodeMathSymbol{"025B5}{\vartriangle }{\mathrel}{/triangle - up triangle, open}%
+\xUnicodeMathSymbol{"025B6}{\blacktriangleright }{\mathord}{(large) right triangle, filled}%
+\xUnicodeMathSymbol{"025B7}{\triangleright }{\mathbin}{(large) right triangle, open; z notation range restriction}%
+\xUnicodeMathSymbol{"025B8}{\smallblacktriangleright }{\mathord}{right triangle, filled}%
+\xUnicodeMathSymbol{"025B9}{\smalltriangleright }{\mathord}{right triangle, open}%
+\xUnicodeMathSymbol{"025BA}{\blackpointerright }{\mathord}{black right-pointing pointer}%
+\xUnicodeMathSymbol{"025BB}{\whitepointerright }{\mathord}{white right-pointing pointer}%
+\xUnicodeMathSymbol{"025BC}{\bigblacktriangledown }{\mathord}{big down triangle, filled}%
+\xUnicodeMathSymbol{"025BD}{\bigtriangledown }{\mathord}{big down triangle, open}%
+\xUnicodeMathSymbol{"025BE}{\blacktriangledown }{\mathord}{down triangle, filled}%
+\xUnicodeMathSymbol{"025BF}{\triangledown }{\mathord}{down triangle, open}%
+\xUnicodeMathSymbol{"025C0}{\blacktriangleleft }{\mathord}{(large) left triangle, filled}%
+\xUnicodeMathSymbol{"025C1}{\triangleleft }{\mathbin}{(large) left triangle, open; z notation domain restriction}%
+\xUnicodeMathSymbol{"025C2}{\smallblacktriangleleft }{\mathord}{left triangle, filled}%
+\xUnicodeMathSymbol{"025C3}{\smalltriangleleft }{\mathord}{left triangle, open}%
+\xUnicodeMathSymbol{"025C4}{\blackpointerleft }{\mathord}{black left-pointing pointer}%
+\xUnicodeMathSymbol{"025C5}{\whitepointerleft }{\mathord}{white left-pointing pointer}%
+\xUnicodeMathSymbol{"025C6}{\mdlgblkdiamond }{\mathord}{black diamond}%
+\xUnicodeMathSymbol{"025C7}{\mdlgwhtdiamond }{\mathord}{white diamond; diamond, open}%
+\xUnicodeMathSymbol{"025C8}{\blackinwhitediamond }{\mathord}{white diamond containing black small diamond}%
+\xUnicodeMathSymbol{"025C9}{\fisheye }{\mathord}{fisheye}%
+\xUnicodeMathSymbol{"025CA}{\mdlgwhtlozenge }{\mathord}{lozenge or total mark}%
+\xUnicodeMathSymbol{"025CB}{\mdlgwhtcircle }{\mathbin}{medium large circle}%
+\xUnicodeMathSymbol{"025CC}{\dottedcircle }{\mathord}{dotted circle}%
+\xUnicodeMathSymbol{"025CD}{\circlevertfill }{\mathord}{circle with vertical fill}%
+\xUnicodeMathSymbol{"025CE}{\bullseye }{\mathord}{bullseye}%
+\xUnicodeMathSymbol{"025CF}{\mdlgblkcircle }{\mathord}{circle, filled}%
+\xUnicodeMathSymbol{"025D0}{\circlelefthalfblack }{\mathord}{circle, filled left half [harvey ball]}%
+\xUnicodeMathSymbol{"025D1}{\circlerighthalfblack }{\mathord}{circle, filled right half}%
+\xUnicodeMathSymbol{"025D2}{\circlebottomhalfblack }{\mathord}{circle, filled bottom half}%
+\xUnicodeMathSymbol{"025D3}{\circletophalfblack }{\mathord}{circle, filled top half}%
+\xUnicodeMathSymbol{"025D4}{\circleurquadblack }{\mathord}{circle with upper right quadrant black}%
+\xUnicodeMathSymbol{"025D5}{\blackcircleulquadwhite }{\mathord}{circle with all but upper left quadrant black}%
+\xUnicodeMathSymbol{"025D6}{\blacklefthalfcircle }{\mathord}{left half black circle}%
+\xUnicodeMathSymbol{"025D7}{\blackrighthalfcircle }{\mathord}{right half black circle}%
+\xUnicodeMathSymbol{"025D8}{\inversebullet }{\mathord}{inverse bullet }%
+\xUnicodeMathSymbol{"025D9}{\inversewhitecircle }{\mathord}{inverse white circle}%
+\xUnicodeMathSymbol{"025DA}{\invwhiteupperhalfcircle }{\mathord}{upper half inverse white circle}%
+\xUnicodeMathSymbol{"025DB}{\invwhitelowerhalfcircle }{\mathord}{lower half inverse white circle}%
+\xUnicodeMathSymbol{"025DC}{\ularc }{\mathord}{upper left quadrant circular arc}%
+\xUnicodeMathSymbol{"025DD}{\urarc }{\mathord}{upper right quadrant circular arc}%
+\xUnicodeMathSymbol{"025DE}{\lrarc }{\mathord}{lower right quadrant circular arc}%
+\xUnicodeMathSymbol{"025DF}{\llarc }{\mathord}{lower left quadrant circular arc}%
+\xUnicodeMathSymbol{"025E0}{\topsemicircle }{\mathord}{upper half circle}%
+\xUnicodeMathSymbol{"025E1}{\botsemicircle }{\mathord}{lower half circle}%
+\xUnicodeMathSymbol{"025E2}{\lrblacktriangle }{\mathord}{lower right triangle, filled}%
+\xUnicodeMathSymbol{"025E3}{\llblacktriangle }{\mathord}{lower left triangle, filled}%
+\xUnicodeMathSymbol{"025E4}{\ulblacktriangle }{\mathord}{upper left triangle, filled}%
+\xUnicodeMathSymbol{"025E5}{\urblacktriangle }{\mathord}{upper right triangle, filled}%
+\xUnicodeMathSymbol{"025E6}{\smwhtcircle }{\mathord}{white bullet}%
+\xUnicodeMathSymbol{"025E7}{\squareleftblack }{\mathord}{square, filled left half}%
+\xUnicodeMathSymbol{"025E8}{\squarerightblack }{\mathord}{square, filled right half}%
+\xUnicodeMathSymbol{"025E9}{\squareulblack }{\mathord}{square, filled top left corner}%
+\xUnicodeMathSymbol{"025EA}{\squarelrblack }{\mathord}{square, filled bottom right corner}%
+\xUnicodeMathSymbol{"025EB}{\boxbar }{\mathbin}{vertical bar in box}%
+\xUnicodeMathSymbol{"025EC}{\trianglecdot }{\mathord}{triangle with centered dot}%
+\xUnicodeMathSymbol{"025ED}{\triangleleftblack }{\mathord}{up-pointing triangle with left half black}%
+\xUnicodeMathSymbol{"025EE}{\trianglerightblack }{\mathord}{up-pointing triangle with right half black}%
+\xUnicodeMathSymbol{"025EF}{\lgwhtcircle }{\mathord}{large circle}%
+\xUnicodeMathSymbol{"025F0}{\squareulquad }{\mathord}{white square with upper left quadrant}%
+\xUnicodeMathSymbol{"025F1}{\squarellquad }{\mathord}{white square with lower left quadrant}%
+\xUnicodeMathSymbol{"025F2}{\squarelrquad }{\mathord}{white square with lower right quadrant}%
+\xUnicodeMathSymbol{"025F3}{\squareurquad }{\mathord}{white square with upper right quadrant}%
+\xUnicodeMathSymbol{"025F4}{\circleulquad }{\mathord}{white circle with upper left quadrant}%
+\xUnicodeMathSymbol{"025F5}{\circlellquad }{\mathord}{white circle with lower left quadrant}%
+\xUnicodeMathSymbol{"025F6}{\circlelrquad }{\mathord}{white circle with lower right quadrant}%
+\xUnicodeMathSymbol{"025F7}{\circleurquad }{\mathord}{white circle with upper right quadrant}%
+\xUnicodeMathSymbol{"025F8}{\ultriangle }{\mathord}{upper left triangle}%
+\xUnicodeMathSymbol{"025F9}{\urtriangle }{\mathord}{upper right triangle}%
+\xUnicodeMathSymbol{"025FA}{\lltriangle }{\mathord}{lower left triangle}%
+\xUnicodeMathSymbol{"025FB}{\mdwhtsquare }{\mathord}{white medium square}%
+\xUnicodeMathSymbol{"025FC}{\mdblksquare }{\mathord}{black medium square}%
+\xUnicodeMathSymbol{"025FD}{\mdsmwhtsquare }{\mathord}{white medium small square}%
+\xUnicodeMathSymbol{"025FE}{\mdsmblksquare }{\mathord}{black medium small square}%
+\xUnicodeMathSymbol{"025FF}{\lrtriangle }{\mathord}{lower right triangle}%
+\xUnicodeMathSymbol{"02605}{\bigstar }{\mathord}{star, filled}%
+\xUnicodeMathSymbol{"02606}{\bigwhitestar }{\mathord}{star, open}%
+\xUnicodeMathSymbol{"02609}{\astrosun }{\mathord}{sun}%
+\xUnicodeMathSymbol{"02621}{\danger }{\mathord}{dangerous bend (caution sign)}%
+\xUnicodeMathSymbol{"0263B}{\blacksmiley }{\mathord}{black smiling face}%
+\xUnicodeMathSymbol{"0263C}{\sun }{\mathord}{white sun with rays}%
+\xUnicodeMathSymbol{"0263D}{\rightmoon }{\mathord}{first quarter moon}%
+\xUnicodeMathSymbol{"0263E}{\leftmoon }{\mathord}{last quarter moon}%
+\xUnicodeMathSymbol{"02640}{\female }{\mathord}{venus, female}%
+\xUnicodeMathSymbol{"02642}{\male }{\mathord}{mars, male}%
+\xUnicodeMathSymbol{"02660}{\spadesuit }{\mathord}{spades suit symbol}%
+\xUnicodeMathSymbol{"02661}{\heartsuit }{\mathord}{heart suit symbol}%
+\xUnicodeMathSymbol{"02662}{\diamondsuit }{\mathord}{diamond suit symbol}%
+\xUnicodeMathSymbol{"02663}{\clubsuit }{\mathord}{club suit symbol}%
+\xUnicodeMathSymbol{"02664}{\varspadesuit }{\mathord}{spade, white (card suit)}%
+\xUnicodeMathSymbol{"02665}{\varheartsuit }{\mathord}{filled heart (card suit)}%
+\xUnicodeMathSymbol{"02666}{\vardiamondsuit }{\mathord}{filled diamond (card suit)}%
+\xUnicodeMathSymbol{"02667}{\varclubsuit }{\mathord}{club, white (card suit)}%
+\xUnicodeMathSymbol{"02669}{\quarternote }{\mathord}{music note (sung text sign)}%
+\xUnicodeMathSymbol{"0266A}{\eighthnote }{\mathord}{eighth note}%
+\xUnicodeMathSymbol{"0266B}{\twonotes }{\mathord}{beamed eighth notes}%
+\xUnicodeMathSymbol{"0266D}{\flat }{\mathord}{musical flat}%
+\xUnicodeMathSymbol{"0266E}{\natural }{\mathord}{music natural}%
+\xUnicodeMathSymbol{"0266F}{\sharp }{\mathord}{musical sharp}%
+\xUnicodeMathSymbol{"0267E}{\acidfree }{\mathord}{permanent paper sign}%
+\xUnicodeMathSymbol{"02680}{\dicei }{\mathord}{die face-1}%
+\xUnicodeMathSymbol{"02681}{\diceii }{\mathord}{die face-2}%
+\xUnicodeMathSymbol{"02682}{\diceiii }{\mathord}{die face-3}%
+\xUnicodeMathSymbol{"02683}{\diceiv }{\mathord}{die face-4}%
+\xUnicodeMathSymbol{"02684}{\dicev }{\mathord}{die face-5}%
+\xUnicodeMathSymbol{"02685}{\dicevi }{\mathord}{die face-6}%
+\xUnicodeMathSymbol{"02686}{\circledrightdot }{\mathord}{white circle with dot right}%
+\xUnicodeMathSymbol{"02687}{\circledtwodots }{\mathord}{white circle with two dots}%
+\xUnicodeMathSymbol{"02688}{\blackcircledrightdot }{\mathord}{black circle with white dot right}%
+\xUnicodeMathSymbol{"02689}{\blackcircledtwodots }{\mathord}{black circle with two white dots}%
+\xUnicodeMathSymbol{"026A5}{\Hermaphrodite }{\mathord}{male and female sign}%
+\xUnicodeMathSymbol{"026AA}{\mdwhtcircle }{\mathord}{medium white circle}%
+\xUnicodeMathSymbol{"026AB}{\mdblkcircle }{\mathord}{medium black circle}%
+\xUnicodeMathSymbol{"026AC}{\mdsmwhtcircle }{\mathord}{medium small white circle}%
+\xUnicodeMathSymbol{"026B2}{\neuter }{\mathord}{neuter}%
+\xUnicodeMathSymbol{"02713}{\checkmark }{\mathord}{tick, check mark}%
+\xUnicodeMathSymbol{"02720}{\maltese }{\mathord}{maltese cross}%
+\xUnicodeMathSymbol{"0272A}{\circledstar }{\mathord}{circled white star}%
+\xUnicodeMathSymbol{"02736}{\varstar }{\mathord}{six pointed black star}%
+\xUnicodeMathSymbol{"0273D}{\dingasterisk }{\mathord}{heavy teardrop-spoked asterisk}%
+\xUnicodeMathSymbol{"02772}{\lbrbrak }{\mathopen}{light left tortoise shell bracket ornament}%
+\xUnicodeMathSymbol{"02773}{\rbrbrak }{\mathclose}{light right tortoise shell bracket ornament}%
+\xUnicodeMathSymbol{"0279B}{\draftingarrow }{\mathord}{right arrow with bold head (drafting)}%
+\xUnicodeMathSymbol{"027C0}{\threedangle }{\mathord}{three dimensional angle}%
+\xUnicodeMathSymbol{"027C1}{\whiteinwhitetriangle }{\mathord}{white triangle containing small white triangle}%
+\xUnicodeMathSymbol{"027C2}{\perp }{\mathrel}{perpendicular}%
+\xUnicodeMathSymbol{"027C3}{\subsetcirc }{\mathord}{open subset}%
+\xUnicodeMathSymbol{"027C4}{\supsetcirc }{\mathord}{open superset}%
+\xUnicodeMathSymbol{"027C5}{\lbag }{\mathopen}{left s-shaped bag delimiter}%
+\xUnicodeMathSymbol{"027C6}{\rbag }{\mathclose}{right s-shaped bag delimiter}%
+\xUnicodeMathSymbol{"027C7}{\veedot }{\mathbin}{or with dot inside}%
+\xUnicodeMathSymbol{"027C8}{\bsolhsub }{\mathrel}{reverse solidus preceding subset}%
+\xUnicodeMathSymbol{"027C9}{\suphsol }{\mathrel}{superset preceding solidus}%
+\xUnicodeMathSymbol{"027CC}{\longdivision }{\mathopen}{long division}%
+\xUnicodeMathSymbol{"027D0}{\diamondcdot }{\mathord}{white diamond with centred dot}%
+\xUnicodeMathSymbol{"027D1}{\wedgedot }{\mathbin}{and with dot}%
+\xUnicodeMathSymbol{"027D2}{\upin }{\mathrel}{element of opening upwards}%
+\xUnicodeMathSymbol{"027D3}{\pullback }{\mathrel}{lower right corner with dot}%
+\xUnicodeMathSymbol{"027D4}{\pushout }{\mathrel}{upper left corner with dot}%
+\xUnicodeMathSymbol{"027D5}{\leftouterjoin }{\mathop}{left outer join}%
+\xUnicodeMathSymbol{"027D6}{\rightouterjoin }{\mathop}{right outer join}%
+\xUnicodeMathSymbol{"027D7}{\fullouterjoin }{\mathop}{full outer join}%
+\xUnicodeMathSymbol{"027D8}{\bigbot }{\mathop}{large up tack}%
+\xUnicodeMathSymbol{"027D9}{\bigtop }{\mathop}{large down tack}%
+\xUnicodeMathSymbol{"027DA}{\DashVDash }{\mathrel}{left and right double turnstile}%
+\xUnicodeMathSymbol{"027DB}{\dashVdash }{\mathrel}{left and right tack}%
+\xUnicodeMathSymbol{"027DC}{\multimapinv }{\mathrel}{left multimap}%
+\xUnicodeMathSymbol{"027DD}{\vlongdash }{\mathrel}{long left tack}%
+\xUnicodeMathSymbol{"027DE}{\longdashv }{\mathrel}{long right tack}%
+\xUnicodeMathSymbol{"027DF}{\cirbot }{\mathrel}{up tack with circle above}%
+\xUnicodeMathSymbol{"027E0}{\lozengeminus }{\mathbin}{lozenge divided by horizontal rule}%
+\xUnicodeMathSymbol{"027E1}{\concavediamond }{\mathbin}{white concave-sided diamond}%
+\xUnicodeMathSymbol{"027E2}{\concavediamondtickleft }{\mathbin}{white concave-sided diamond with leftwards tick}%
+\xUnicodeMathSymbol{"027E3}{\concavediamondtickright }{\mathbin}{white concave-sided diamond with rightwards tick}%
+\xUnicodeMathSymbol{"027E4}{\whitesquaretickleft }{\mathbin}{white square with leftwards tick}%
+\xUnicodeMathSymbol{"027E5}{\whitesquaretickright }{\mathbin}{white square with rightwards tick}%
+\xUnicodeMathSymbol{"027E6}{\lBrack }{\mathopen}{mathematical left white square bracket}%
+\xUnicodeMathSymbol{"027E7}{\rBrack }{\mathclose}{mathematical right white square bracket}%
+\xUnicodeMathSymbol{"027E8}{\langle }{\mathopen}{mathematical left angle bracket}%
+\xUnicodeMathSymbol{"027E9}{\rangle }{\mathclose}{mathematical right angle bracket}%
+\xUnicodeMathSymbol{"027EA}{\lAngle }{\mathopen}{mathematical left double angle bracket}%
+\xUnicodeMathSymbol{"027EB}{\rAngle }{\mathclose}{mathematical right double angle bracket}%
+\xUnicodeMathSymbol{"027EC}{\Lbrbrak }{\mathopen}{mathematical left white tortoise shell bracket}%
+\xUnicodeMathSymbol{"027ED}{\Rbrbrak }{\mathclose}{mathematical right white tortoise shell bracket}%
+\xUnicodeMathSymbol{"027EE}{\lgroup }{\mathopen}{mathematical left flattened parenthesis}%
+\xUnicodeMathSymbol{"027EF}{\rgroup }{\mathclose}{mathematical right flattened parenthesis}%
+\xUnicodeMathSymbol{"027F0}{\UUparrow }{\mathrel}{upwards quadruple arrow}%
+\xUnicodeMathSymbol{"027F1}{\DDownarrow }{\mathrel}{downwards quadruple arrow}%
+\xUnicodeMathSymbol{"027F2}{\acwgapcirclearrow }{\mathrel}{anticlockwise gapped circle arrow}%
+\xUnicodeMathSymbol{"027F3}{\cwgapcirclearrow }{\mathrel}{clockwise gapped circle arrow}%
+\xUnicodeMathSymbol{"027F4}{\rightarrowonoplus }{\mathrel}{right arrow with circled plus}%
+\xUnicodeMathSymbol{"027F5}{\longleftarrow }{\mathrel}{long leftwards arrow}%
+%\xUnicodeMathSymbol{"027F6}{\longrightarrow }{\mathrel}{long rightwards arrow}%
+\xxUnicodeMathSymbol{"027F6}{\longrightarrow}{{-\!->}}
+\xUnicodeMathSymbol{"027F7}{\longleftrightarrow }{\mathrel}{long left right arrow}%
+\xUnicodeMathSymbol{"027F8}{\Longleftarrow }{\mathrel}{long leftwards double arrow}%
+\xUnicodeMathSymbol{"027F9}{\Longrightarrow }{\mathrel}{long rightwards double arrow}%
+\xUnicodeMathSymbol{"027FA}{\Longleftrightarrow }{\mathrel}{long left right double arrow}%
+\xUnicodeMathSymbol{"027FB}{\longmapsfrom }{\mathrel}{long leftwards arrow from bar}%
+\xUnicodeMathSymbol{"027FC}{\longmapsto }{\mathrel}{long rightwards arrow from bar}%
+\xUnicodeMathSymbol{"027FD}{\Longmapsfrom }{\mathrel}{long leftwards double arrow from bar}%
+\xUnicodeMathSymbol{"027FE}{\Longmapsto }{\mathrel}{long rightwards double arrow from bar}%
+\xUnicodeMathSymbol{"027FF}{\longrightsquigarrow }{\mathrel}{long rightwards squiggle arrow}%
+\xUnicodeMathSymbol{"02900}{\nvtwoheadrightarrow }{\mathrel}{rightwards two-headed arrow with vertical stroke}%
+\xUnicodeMathSymbol{"02901}{\nVtwoheadrightarrow }{\mathrel}{rightwards two-headed arrow with double vertical stroke}%
+\xUnicodeMathSymbol{"02902}{\nvLeftarrow }{\mathrel}{leftwards double arrow with vertical stroke}%
+\xUnicodeMathSymbol{"02903}{\nvRightarrow }{\mathrel}{rightwards double arrow with vertical stroke}%
+\xUnicodeMathSymbol{"02904}{\nvLeftrightarrow }{\mathrel}{left right double arrow with vertical stroke}%
+\xUnicodeMathSymbol{"02905}{\twoheadmapsto }{\mathrel}{rightwards two-headed arrow from bar}%
+\xUnicodeMathSymbol{"02906}{\Mapsfrom }{\mathrel}{leftwards double arrow from bar}%
+\xUnicodeMathSymbol{"02907}{\Mapsto }{\mathrel}{rightwards double arrow from bar}%
+\xUnicodeMathSymbol{"02908}{\downarrowbarred }{\mathrel}{downwards arrow with horizontal stroke}%
+\xUnicodeMathSymbol{"02909}{\uparrowbarred }{\mathrel}{upwards arrow with horizontal stroke}%
+\xUnicodeMathSymbol{"0290A}{\Uuparrow }{\mathrel}{upwards triple arrow}%
+\xUnicodeMathSymbol{"0290B}{\Ddownarrow }{\mathrel}{downwards triple arrow}%
+\xUnicodeMathSymbol{"0290C}{\leftbkarrow }{\mathrel}{leftwards double dash arrow}%
+\xUnicodeMathSymbol{"0290D}{\rightbkarrow }{\mathrel}{rightwards double dash arrow}%
+\xUnicodeMathSymbol{"0290E}{\leftdbkarrow }{\mathrel}{leftwards triple dash arrow}%
+\xUnicodeMathSymbol{"0290F}{\dbkarrow }{\mathrel}{rightwards triple dash arrow}%
+\xUnicodeMathSymbol{"02910}{\drbkarrow }{\mathrel}{rightwards two-headed triple dash arrow}%
+\xUnicodeMathSymbol{"02911}{\rightdotarrow }{\mathrel}{rightwards arrow with dotted stem}%
+\xUnicodeMathSymbol{"02912}{\baruparrow }{\mathrel}{upwards arrow to bar}%
+\xUnicodeMathSymbol{"02913}{\downarrowbar }{\mathrel}{downwards arrow to bar}%
+\xUnicodeMathSymbol{"02914}{\nvrightarrowtail }{\mathrel}{rightwards arrow with tail with vertical stroke}%
+\xUnicodeMathSymbol{"02915}{\nVrightarrowtail }{\mathrel}{rightwards arrow with tail with double vertical stroke}%
+\xUnicodeMathSymbol{"02916}{\twoheadrightarrowtail }{\mathrel}{rightwards two-headed arrow with tail}%
+\xUnicodeMathSymbol{"02917}{\nvtwoheadrightarrowtail }{\mathrel}{rightwards two-headed arrow with tail with vertical stroke}%
+\xUnicodeMathSymbol{"02918}{\nVtwoheadrightarrowtail }{\mathrel}{rightwards two-headed arrow with tail with double vertical stroke}%
+\xUnicodeMathSymbol{"02919}{\lefttail }{\mathrel}{leftwards arrow-tail}%
+\xUnicodeMathSymbol{"0291A}{\righttail }{\mathrel}{rightwards arrow-tail}%
+\xUnicodeMathSymbol{"0291B}{\leftdbltail }{\mathrel}{leftwards double arrow-tail}%
+\xUnicodeMathSymbol{"0291C}{\rightdbltail }{\mathrel}{rightwards double arrow-tail}%
+\xUnicodeMathSymbol{"0291D}{\diamondleftarrow }{\mathrel}{leftwards arrow to black diamond}%
+\xUnicodeMathSymbol{"0291E}{\rightarrowdiamond }{\mathrel}{rightwards arrow to black diamond}%
+\xUnicodeMathSymbol{"0291F}{\diamondleftarrowbar }{\mathrel}{leftwards arrow from bar to black diamond}%
+\xUnicodeMathSymbol{"02920}{\barrightarrowdiamond }{\mathrel}{rightwards arrow from bar to black diamond}%
+\xUnicodeMathSymbol{"02921}{\nwsearrow }{\mathrel}{north west and south east arrow}%
+\xUnicodeMathSymbol{"02922}{\neswarrow }{\mathrel}{north east and south west arrow}%
+\xUnicodeMathSymbol{"02923}{\hknwarrow }{\mathrel}{north west arrow with hook}%
+\xUnicodeMathSymbol{"02924}{\hknearrow }{\mathrel}{north east arrow with hook}%
+\xUnicodeMathSymbol{"02925}{\hksearrow }{\mathrel}{south east arrow with hook}%
+\xUnicodeMathSymbol{"02926}{\hkswarrow }{\mathrel}{south west arrow with hook}%
+\xUnicodeMathSymbol{"02927}{\tona }{\mathrel}{north west arrow and north east arrow}%
+\xUnicodeMathSymbol{"02928}{\toea }{\mathrel}{north east arrow and south east arrow}%
+\xUnicodeMathSymbol{"02929}{\tosa }{\mathrel}{south east arrow and south west arrow}%
+\xUnicodeMathSymbol{"0292A}{\towa }{\mathrel}{south west arrow and north west arrow}%
+\xUnicodeMathSymbol{"0292B}{\rdiagovfdiag }{\mathord}{rising diagonal crossing falling diagonal}%
+\xUnicodeMathSymbol{"0292C}{\fdiagovrdiag }{\mathord}{falling diagonal crossing rising diagonal}%
+\xUnicodeMathSymbol{"0292D}{\seovnearrow }{\mathord}{south east arrow crossing north east arrow}%
+\xUnicodeMathSymbol{"0292E}{\neovsearrow }{\mathord}{north east arrow crossing south east arrow}%
+\xUnicodeMathSymbol{"0292F}{\fdiagovnearrow }{\mathord}{falling diagonal crossing north east arrow}%
+\xUnicodeMathSymbol{"02930}{\rdiagovsearrow }{\mathord}{rising diagonal crossing south east arrow}%
+\xUnicodeMathSymbol{"02931}{\neovnwarrow }{\mathord}{north east arrow crossing north west arrow}%
+\xUnicodeMathSymbol{"02932}{\nwovnearrow }{\mathord}{north west arrow crossing north east arrow}%
+\xUnicodeMathSymbol{"02933}{\rightcurvedarrow }{\mathrel}{wave arrow pointing directly right}%
+\xUnicodeMathSymbol{"02934}{\uprightcurvearrow }{\mathord}{arrow pointing rightwards then curving upwards}%
+\xUnicodeMathSymbol{"02935}{\downrightcurvedarrow }{\mathord}{arrow pointing rightwards then curving downwards}%
+\xUnicodeMathSymbol{"02936}{\leftdowncurvedarrow }{\mathrel}{arrow pointing downwards then curving leftwards}%
+\xUnicodeMathSymbol{"02937}{\rightdowncurvedarrow }{\mathrel}{arrow pointing downwards then curving rightwards}%
+\xUnicodeMathSymbol{"02938}{\cwrightarcarrow }{\mathrel}{right-side arc clockwise arrow}%
+\xUnicodeMathSymbol{"02939}{\acwleftarcarrow }{\mathrel}{left-side arc anticlockwise arrow}%
+\xUnicodeMathSymbol{"0293A}{\acwoverarcarrow }{\mathrel}{top arc anticlockwise arrow}%
+\xUnicodeMathSymbol{"0293B}{\acwunderarcarrow }{\mathrel}{bottom arc anticlockwise arrow}%
+\xUnicodeMathSymbol{"0293C}{\curvearrowrightminus }{\mathrel}{top arc clockwise arrow with minus}%
+\xUnicodeMathSymbol{"0293D}{\curvearrowleftplus }{\mathrel}{top arc anticlockwise arrow with plus}%
+\xUnicodeMathSymbol{"0293E}{\cwundercurvearrow }{\mathrel}{lower right semicircular clockwise arrow}%
+\xUnicodeMathSymbol{"0293F}{\ccwundercurvearrow }{\mathrel}{lower left semicircular anticlockwise arrow}%
+\xUnicodeMathSymbol{"02940}{\acwcirclearrow }{\mathrel}{anticlockwise closed circle arrow}%
+\xUnicodeMathSymbol{"02941}{\cwcirclearrow }{\mathrel}{clockwise closed circle arrow}%
+\xUnicodeMathSymbol{"02942}{\rightarrowshortleftarrow }{\mathrel}{rightwards arrow above short leftwards arrow}%
+\xUnicodeMathSymbol{"02943}{\leftarrowshortrightarrow }{\mathrel}{leftwards arrow above short rightwards arrow}%
+\xUnicodeMathSymbol{"02944}{\shortrightarrowleftarrow }{\mathrel}{short rightwards arrow above leftwards arrow}%
+\xUnicodeMathSymbol{"02945}{\rightarrowplus }{\mathrel}{rightwards arrow with plus below}%
+\xUnicodeMathSymbol{"02946}{\leftarrowplus }{\mathrel}{leftwards arrow with plus below}%
+\xUnicodeMathSymbol{"02947}{\rightarrowx }{\mathrel}{rightwards arrow through x}%
+\xUnicodeMathSymbol{"02948}{\leftrightarrowcircle }{\mathrel}{left right arrow through small circle}%
+\xUnicodeMathSymbol{"02949}{\twoheaduparrowcircle }{\mathrel}{upwards two-headed arrow from small circle}%
+\xUnicodeMathSymbol{"0294A}{\leftrightharpoonupdown }{\mathrel}{left barb up right barb down harpoon}%
+\xUnicodeMathSymbol{"0294B}{\leftrightharpoondownup }{\mathrel}{left barb down right barb up harpoon}%
+\xUnicodeMathSymbol{"0294C}{\updownharpoonrightleft }{\mathrel}{up barb right down barb left harpoon}%
+\xUnicodeMathSymbol{"0294D}{\updownharpoonleftright }{\mathrel}{up barb left down barb right harpoon}%
+\xUnicodeMathSymbol{"0294E}{\leftrightharpoonupup }{\mathrel}{left barb up right barb up harpoon}%
+\xUnicodeMathSymbol{"0294F}{\updownharpoonrightright }{\mathrel}{up barb right down barb right harpoon}%
+\xUnicodeMathSymbol{"02950}{\leftrightharpoondowndown }{\mathrel}{left barb down right barb down harpoon}%
+\xUnicodeMathSymbol{"02951}{\updownharpoonleftleft }{\mathrel}{up barb left down barb left harpoon}%
+\xUnicodeMathSymbol{"02952}{\barleftharpoonup }{\mathrel}{leftwards harpoon with barb up to bar}%
+\xUnicodeMathSymbol{"02953}{\rightharpoonupbar }{\mathrel}{rightwards harpoon with barb up to bar}%
+\xUnicodeMathSymbol{"02954}{\barupharpoonright }{\mathrel}{upwards harpoon with barb right to bar}%
+\xUnicodeMathSymbol{"02955}{\downharpoonrightbar }{\mathrel}{downwards harpoon with barb right to bar}%
+\xUnicodeMathSymbol{"02956}{\barleftharpoondown }{\mathrel}{leftwards harpoon with barb down to bar}%
+\xUnicodeMathSymbol{"02957}{\rightharpoondownbar }{\mathrel}{rightwards harpoon with barb down to bar}%
+\xUnicodeMathSymbol{"02958}{\barupharpoonleft }{\mathrel}{upwards harpoon with barb left to bar}%
+\xUnicodeMathSymbol{"02959}{\downharpoonleftbar }{\mathrel}{downwards harpoon with barb left to bar}%
+\xUnicodeMathSymbol{"0295A}{\leftharpoonupbar }{\mathrel}{leftwards harpoon with barb up from bar}%
+\xUnicodeMathSymbol{"0295B}{\barrightharpoonup }{\mathrel}{rightwards harpoon with barb up from bar}%
+\xUnicodeMathSymbol{"0295C}{\upharpoonrightbar }{\mathrel}{upwards harpoon with barb right from bar}%
+\xUnicodeMathSymbol{"0295D}{\bardownharpoonright }{\mathrel}{downwards harpoon with barb right from bar}%
+\xUnicodeMathSymbol{"0295E}{\leftharpoondownbar }{\mathrel}{leftwards harpoon with barb down from bar}%
+\xUnicodeMathSymbol{"0295F}{\barrightharpoondown }{\mathrel}{rightwards harpoon with barb down from bar}%
+\xUnicodeMathSymbol{"02960}{\upharpoonleftbar }{\mathrel}{upwards harpoon with barb left from bar}%
+\xUnicodeMathSymbol{"02961}{\bardownharpoonleft }{\mathrel}{downwards harpoon with barb left from bar}%
+\xUnicodeMathSymbol{"02962}{\leftharpoonsupdown }{\mathrel}{leftwards harpoon with barb up above leftwards harpoon with barb down}%
+\xUnicodeMathSymbol{"02963}{\upharpoonsleftright }{\mathrel}{upwards harpoon with barb left beside upwards harpoon with barb right}%
+\xUnicodeMathSymbol{"02964}{\rightharpoonsupdown }{\mathrel}{rightwards harpoon with barb up above rightwards harpoon with barb down}%
+\xUnicodeMathSymbol{"02965}{\downharpoonsleftright }{\mathrel}{downwards harpoon with barb left beside downwards harpoon with barb right}%
+\xUnicodeMathSymbol{"02966}{\leftrightharpoonsup }{\mathrel}{leftwards harpoon with barb up above rightwards harpoon with barb up}%
+\xUnicodeMathSymbol{"02967}{\leftrightharpoonsdown }{\mathrel}{leftwards harpoon with barb down above rightwards harpoon with barb down}%
+\xUnicodeMathSymbol{"02968}{\rightleftharpoonsup }{\mathrel}{rightwards harpoon with barb up above leftwards harpoon with barb up}%
+\xUnicodeMathSymbol{"02969}{\rightleftharpoonsdown }{\mathrel}{rightwards harpoon with barb down above leftwards harpoon with barb down}%
+\xUnicodeMathSymbol{"0296A}{\leftharpoonupdash }{\mathrel}{leftwards harpoon with barb up above long dash}%
+\xUnicodeMathSymbol{"0296B}{\dashleftharpoondown }{\mathrel}{leftwards harpoon with barb down below long dash}%
+\xUnicodeMathSymbol{"0296C}{\rightharpoonupdash }{\mathrel}{rightwards harpoon with barb up above long dash}%
+\xUnicodeMathSymbol{"0296D}{\dashrightharpoondown }{\mathrel}{rightwards harpoon with barb down below long dash}%
+\xUnicodeMathSymbol{"0296E}{\updownharpoonsleftright }{\mathrel}{upwards harpoon with barb left beside downwards harpoon with barb right}%
+\xUnicodeMathSymbol{"0296F}{\downupharpoonsleftright }{\mathrel}{downwards harpoon with barb left beside upwards harpoon with barb right}%
+\xUnicodeMathSymbol{"02970}{\rightimply }{\mathrel}{right double arrow with rounded head}%
+\xUnicodeMathSymbol{"02971}{\equalrightarrow }{\mathrel}{equals sign above rightwards arrow}%
+\xUnicodeMathSymbol{"02972}{\similarrightarrow }{\mathrel}{tilde operator above rightwards arrow}%
+\xUnicodeMathSymbol{"02973}{\leftarrowsimilar }{\mathrel}{leftwards arrow above tilde operator}%
+\xUnicodeMathSymbol{"02974}{\rightarrowsimilar }{\mathrel}{rightwards arrow above tilde operator}%
+\xUnicodeMathSymbol{"02975}{\rightarrowapprox }{\mathrel}{rightwards arrow above almost equal to}%
+\xUnicodeMathSymbol{"02976}{\ltlarr }{\mathrel}{less-than above leftwards arrow}%
+\xUnicodeMathSymbol{"02977}{\leftarrowless }{\mathrel}{leftwards arrow through less-than}%
+\xUnicodeMathSymbol{"02978}{\gtrarr }{\mathrel}{greater-than above rightwards arrow}%
+\xUnicodeMathSymbol{"02979}{\subrarr }{\mathrel}{subset above rightwards arrow}%
+\xUnicodeMathSymbol{"0297A}{\leftarrowsubset }{\mathrel}{leftwards arrow through subset}%
+\xUnicodeMathSymbol{"0297B}{\suplarr }{\mathrel}{superset above leftwards arrow}%
+\xUnicodeMathSymbol{"0297C}{\leftfishtail }{\mathrel}{left fish tail}%
+\xUnicodeMathSymbol{"0297D}{\rightfishtail }{\mathrel}{right fish tail}%
+\xUnicodeMathSymbol{"0297E}{\upfishtail }{\mathrel}{up fish tail}%
+\xUnicodeMathSymbol{"0297F}{\downfishtail }{\mathrel}{down fish tail}%
+\xUnicodeMathSymbol{"02980}{\Vvert }{\mathfence}{triple vertical bar delimiter}%
+\xUnicodeMathSymbol{"02981}{\mdsmblkcircle }{\mathord}{z notation spot}%
+\xUnicodeMathSymbol{"02982}{\typecolon }{\mathbin}{z notation type colon}%
+\xUnicodeMathSymbol{"02983}{\lBrace }{\mathopen}{left white curly bracket}%
+\xUnicodeMathSymbol{"02984}{\rBrace }{\mathclose}{right white curly bracket}%
+\xUnicodeMathSymbol{"02985}{\lParen }{\mathopen}{left white parenthesis}%
+\xUnicodeMathSymbol{"02986}{\rParen }{\mathclose}{right white parenthesis}%
+\xUnicodeMathSymbol{"02987}{\llparenthesis }{\mathopen}{z notation left image bracket}%
+\xUnicodeMathSymbol{"02988}{\rrparenthesis }{\mathclose}{z notation right image bracket}%
+\xUnicodeMathSymbol{"02989}{\llangle }{\mathopen}{z notation left binding bracket}%
+\xUnicodeMathSymbol{"0298A}{\rrangle }{\mathclose}{z notation right binding bracket}%
+\xUnicodeMathSymbol{"0298B}{\lbrackubar }{\mathopen}{left square bracket with underbar}%
+\xUnicodeMathSymbol{"0298C}{\rbrackubar }{\mathclose}{right square bracket with underbar}%
+\xUnicodeMathSymbol{"0298D}{\lbrackultick }{\mathopen}{left square bracket with tick in top corner}%
+\xUnicodeMathSymbol{"0298E}{\rbracklrtick }{\mathclose}{right square bracket with tick in bottom corner}%
+\xUnicodeMathSymbol{"0298F}{\lbracklltick }{\mathopen}{left square bracket with tick in bottom corner}%
+\xUnicodeMathSymbol{"02990}{\rbrackurtick }{\mathclose}{right square bracket with tick in top corner}%
+\xUnicodeMathSymbol{"02991}{\langledot }{\mathopen}{left angle bracket with dot}%
+\xUnicodeMathSymbol{"02992}{\rangledot }{\mathclose}{right angle bracket with dot}%
+\xUnicodeMathSymbol{"02993}{\lparenless }{\mathopen}{left arc less-than bracket}%
+\xUnicodeMathSymbol{"02994}{\rparengtr }{\mathclose}{right arc greater-than bracket}%
+\xUnicodeMathSymbol{"02995}{\Lparengtr }{\mathopen}{double left arc greater-than bracket}%
+\xUnicodeMathSymbol{"02996}{\Rparenless }{\mathclose}{double right arc less-than bracket}%
+\xUnicodeMathSymbol{"02997}{\lblkbrbrak }{\mathopen}{left black tortoise shell bracket}%
+\xUnicodeMathSymbol{"02998}{\rblkbrbrak }{\mathclose}{right black tortoise shell bracket}%
+\xUnicodeMathSymbol{"02999}{\fourvdots }{\mathord}{dotted fence}%
+\xUnicodeMathSymbol{"0299A}{\vzigzag }{\mathord}{vertical zigzag line}%
+\xUnicodeMathSymbol{"0299B}{\measuredangleleft }{\mathord}{measured angle opening left}%
+\xUnicodeMathSymbol{"0299C}{\rightanglesqr }{\mathord}{right angle variant with square}%
+\xUnicodeMathSymbol{"0299D}{\rightanglemdot }{\mathord}{measured right angle with dot}%
+\xUnicodeMathSymbol{"0299E}{\angles }{\mathord}{angle with s inside}%
+\xUnicodeMathSymbol{"0299F}{\angdnr }{\mathord}{acute angle}%
+\xUnicodeMathSymbol{"029A0}{\gtlpar }{\mathord}{spherical angle opening left}%
+\xUnicodeMathSymbol{"029A1}{\sphericalangleup }{\mathord}{spherical angle opening up}%
+\xUnicodeMathSymbol{"029A2}{\turnangle }{\mathord}{turned angle}%
+\xUnicodeMathSymbol{"029A3}{\revangle }{\mathord}{reversed angle}%
+\xUnicodeMathSymbol{"029A4}{\angleubar }{\mathord}{angle with underbar}%
+\xUnicodeMathSymbol{"029A5}{\revangleubar }{\mathord}{reversed angle with underbar}%
+\xUnicodeMathSymbol{"029A6}{\wideangledown }{\mathord}{oblique angle opening up}%
+\xUnicodeMathSymbol{"029A7}{\wideangleup }{\mathord}{oblique angle opening down}%
+\xUnicodeMathSymbol{"029A8}{\measanglerutone }{\mathord}{measured angle with open arm ending in arrow pointing up and right}%
+\xUnicodeMathSymbol{"029A9}{\measanglelutonw }{\mathord}{measured angle with open arm ending in arrow pointing up and left}%
+\xUnicodeMathSymbol{"029AA}{\measanglerdtose }{\mathord}{measured angle with open arm ending in arrow pointing down and right}%
+\xUnicodeMathSymbol{"029AB}{\measangleldtosw }{\mathord}{measured angle with open arm ending in arrow pointing down and left}%
+\xUnicodeMathSymbol{"029AC}{\measangleurtone }{\mathord}{measured angle with open arm ending in arrow pointing right and up}%
+\xUnicodeMathSymbol{"029AD}{\measangleultonw }{\mathord}{measured angle with open arm ending in arrow pointing left and up}%
+\xUnicodeMathSymbol{"029AE}{\measangledrtose }{\mathord}{measured angle with open arm ending in arrow pointing right and down}%
+\xUnicodeMathSymbol{"029AF}{\measangledltosw }{\mathord}{measured angle with open arm ending in arrow pointing left and down}%
+\xUnicodeMathSymbol{"029B0}{\revemptyset }{\mathord}{reversed empty set}%
+\xUnicodeMathSymbol{"029B1}{\emptysetobar }{\mathord}{empty set with overbar}%
+\xUnicodeMathSymbol{"029B2}{\emptysetocirc }{\mathord}{empty set with small circle above}%
+\xUnicodeMathSymbol{"029B3}{\emptysetoarr }{\mathord}{empty set with right arrow above}%
+\xUnicodeMathSymbol{"029B4}{\emptysetoarrl }{\mathord}{empty set with left arrow above}%
+\xUnicodeMathSymbol{"029B5}{\circlehbar }{\mathbin}{circle with horizontal bar}%
+\xUnicodeMathSymbol{"029B6}{\circledvert }{\mathbin}{circled vertical bar}%
+\xUnicodeMathSymbol{"029B7}{\circledparallel }{\mathbin}{circled parallel}%
+\xUnicodeMathSymbol{"029B8}{\obslash }{\mathbin}{circled reverse solidus}%
+\xUnicodeMathSymbol{"029B9}{\operp }{\mathbin}{circled perpendicular}%
+\xUnicodeMathSymbol{"029BA}{\obot }{\mathord}{circle divided by horizontal bar and top half divided by vertical bar}%
+\xUnicodeMathSymbol{"029BB}{\olcross }{\mathord}{circle with superimposed x}%
+\xUnicodeMathSymbol{"029BC}{\odotslashdot }{\mathord}{circled anticlockwise-rotated division sign}%
+\xUnicodeMathSymbol{"029BD}{\uparrowoncircle }{\mathord}{up arrow through circle}%
+\xUnicodeMathSymbol{"029BE}{\circledwhitebullet }{\mathord}{circled white bullet}%
+\xUnicodeMathSymbol{"029BF}{\circledbullet }{\mathord}{circled bullet}%
+\xUnicodeMathSymbol{"029C0}{\olessthan }{\mathbin}{circled less-than}%
+\xUnicodeMathSymbol{"029C1}{\ogreaterthan }{\mathbin}{circled greater-than}%
+\xUnicodeMathSymbol{"029C2}{\cirscir }{\mathord}{circle with small circle to the right}%
+\xUnicodeMathSymbol{"029C3}{\cirE }{\mathord}{circle with two horizontal strokes to the right}%
+\xUnicodeMathSymbol{"029C4}{\boxdiag }{\mathbin}{squared rising diagonal slash}%
+\xUnicodeMathSymbol{"029C5}{\boxbslash }{\mathbin}{squared falling diagonal slash}%
+\xUnicodeMathSymbol{"029C6}{\boxast }{\mathbin}{squared asterisk}%
+\xUnicodeMathSymbol{"029C7}{\boxcircle }{\mathbin}{squared small circle}%
+\xUnicodeMathSymbol{"029C8}{\boxbox }{\mathbin}{squared square}%
+\xUnicodeMathSymbol{"029C9}{\boxonbox }{\mathord}{two joined squares}%
+\xUnicodeMathSymbol{"029CA}{\triangleodot }{\mathord}{triangle with dot above}%
+\xUnicodeMathSymbol{"029CB}{\triangleubar }{\mathord}{triangle with underbar}%
+\xUnicodeMathSymbol{"029CC}{\triangles }{\mathord}{s in triangle}%
+\xUnicodeMathSymbol{"029CD}{\triangleserifs }{\mathbin}{triangle with serifs at bottom}%
+\xUnicodeMathSymbol{"029CE}{\rtriltri }{\mathrel}{right triangle above left triangle}%
+\xUnicodeMathSymbol{"029CF}{\ltrivb }{\mathrel}{left triangle beside vertical bar}%
+\xUnicodeMathSymbol{"029D0}{\vbrtri }{\mathrel}{vertical bar beside right triangle}%
+\xUnicodeMathSymbol{"029D1}{\lfbowtie }{\mathrel}{left black bowtie}%
+\xUnicodeMathSymbol{"029D2}{\rfbowtie }{\mathrel}{right black bowtie}%
+\xUnicodeMathSymbol{"029D3}{\fbowtie }{\mathrel}{black bowtie}%
+\xUnicodeMathSymbol{"029D4}{\lftimes }{\mathrel}{left black times}%
+\xUnicodeMathSymbol{"029D5}{\rftimes }{\mathrel}{right black times}%
+\xUnicodeMathSymbol{"029D6}{\hourglass }{\mathbin}{white hourglass}%
+\xUnicodeMathSymbol{"029D7}{\blackhourglass }{\mathbin}{black hourglass}%
+\xUnicodeMathSymbol{"029D8}{\lvzigzag }{\mathopen}{left wiggly fence}%
+\xUnicodeMathSymbol{"029D9}{\rvzigzag }{\mathclose}{right wiggly fence}%
+\xUnicodeMathSymbol{"029DA}{\Lvzigzag }{\mathopen}{left double wiggly fence}%
+\xUnicodeMathSymbol{"029DB}{\Rvzigzag }{\mathclose}{right double wiggly fence}%
+\xUnicodeMathSymbol{"029DC}{\iinfin }{\mathord}{incomplete infinity}%
+\xUnicodeMathSymbol{"029DD}{\tieinfty }{\mathord}{tie over infinity}%
+\xUnicodeMathSymbol{"029DE}{\nvinfty }{\mathord}{infinity negated with vertical bar}%
+\xUnicodeMathSymbol{"029DF}{\dualmap }{\mathrel}{double-ended multimap}%
+\xUnicodeMathSymbol{"029E0}{\laplac }{\mathord}{square with contoured outline}%
+\xUnicodeMathSymbol{"029E1}{\lrtriangleeq }{\mathrel}{increases as}%
+\xUnicodeMathSymbol{"029E2}{\shuffle }{\mathbin}{shuffle product}%
+\xUnicodeMathSymbol{"029E3}{\eparsl }{\mathrel}{equals sign and slanted parallel}%
+\xUnicodeMathSymbol{"029E4}{\smeparsl }{\mathrel}{equals sign and slanted parallel with tilde above}%
+\xUnicodeMathSymbol{"029E5}{\eqvparsl }{\mathrel}{identical to and slanted parallel}%
+\xUnicodeMathSymbol{"029E6}{\gleichstark }{\mathrel}{gleich stark}%
+\xUnicodeMathSymbol{"029E7}{\thermod }{\mathord}{thermodynamic}%
+\xUnicodeMathSymbol{"029E8}{\downtriangleleftblack }{\mathord}{down-pointing triangle with left half black}%
+\xUnicodeMathSymbol{"029E9}{\downtrianglerightblack }{\mathord}{down-pointing triangle with right half black}%
+\xUnicodeMathSymbol{"029EA}{\blackdiamonddownarrow }{\mathord}{black diamond with down arrow}%
+\xUnicodeMathSymbol{"029EB}{\mdlgblklozenge }{\mathbin}{black lozenge}%
+\xUnicodeMathSymbol{"029EC}{\circledownarrow }{\mathord}{white circle with down arrow}%
+\xUnicodeMathSymbol{"029ED}{\blackcircledownarrow }{\mathord}{black circle with down arrow}%
+\xUnicodeMathSymbol{"029EE}{\errbarsquare }{\mathord}{error-barred white square}%
+\xUnicodeMathSymbol{"029EF}{\errbarblacksquare }{\mathord}{error-barred black square}%
+\xUnicodeMathSymbol{"029F0}{\errbardiamond }{\mathord}{error-barred white diamond}%
+\xUnicodeMathSymbol{"029F1}{\errbarblackdiamond }{\mathord}{error-barred black diamond}%
+\xUnicodeMathSymbol{"029F2}{\errbarcircle }{\mathord}{error-barred white circle}%
+\xUnicodeMathSymbol{"029F3}{\errbarblackcircle }{\mathord}{error-barred black circle}%
+\xUnicodeMathSymbol{"029F4}{\ruledelayed }{\mathrel}{rule-delayed}%
+\xUnicodeMathSymbol{"029F5}{\setminus }{\mathbin}{reverse solidus operator}%
+\xUnicodeMathSymbol{"029F6}{\dsol }{\mathbin}{solidus with overbar}%
+\xUnicodeMathSymbol{"029F7}{\rsolbar }{\mathbin}{reverse solidus with horizontal stroke}%
+\xUnicodeMathSymbol{"029F8}{\xsol }{\mathop}{big solidus}%
+\xUnicodeMathSymbol{"029F9}{\xbsol }{\mathop}{big reverse solidus}%
+\xUnicodeMathSymbol{"029FA}{\doubleplus }{\mathbin}{double plus}%
+\xUnicodeMathSymbol{"029FB}{\tripleplus }{\mathbin}{triple plus}%
+\xUnicodeMathSymbol{"029FC}{\lcurvyangle }{\mathopen}{left pointing curved angle bracket}%
+\xUnicodeMathSymbol{"029FD}{\rcurvyangle }{\mathclose}{right pointing curved angle bracket}%
+\xUnicodeMathSymbol{"029FE}{\tplus }{\mathbin}{tiny}%
+\xUnicodeMathSymbol{"029FF}{\tminus }{\mathbin}{miny}%
+\xUnicodeMathSymbol{"02A00}{\bigodot }{\mathop}{n-ary circled dot operator}%
+\xUnicodeMathSymbol{"02A01}{\bigoplus }{\mathop}{n-ary circled plus operator}%
+\xUnicodeMathSymbol{"02A02}{\bigotimes }{\mathop}{n-ary circled times operator}%
+\xUnicodeMathSymbol{"02A03}{\bigcupdot }{\mathop}{n-ary union operator with dot}%
+\xUnicodeMathSymbol{"02A04}{\biguplus }{\mathop}{n-ary union operator with plus}%
+\xUnicodeMathSymbol{"02A05}{\bigsqcap }{\mathop}{n-ary square intersection operator}%
+\xUnicodeMathSymbol{"02A06}{\bigsqcup }{\mathop}{n-ary square union operator}%
+\xUnicodeMathSymbol{"02A07}{\conjquant }{\mathop}{two logical and operator}%
+\xUnicodeMathSymbol{"02A08}{\disjquant }{\mathop}{two logical or operator}%
+\xUnicodeMathSymbol{"02A09}{\bigtimes }{\mathop}{n-ary times operator}%
+\xUnicodeMathSymbol{"02A0A}{\modtwosum }{\mathop}{modulo two sum}%
+\xUnicodeMathSymbol{"02A0B}{\sumint }{\mathop}{summation with integral}%
+\xUnicodeMathSymbol{"02A0C}{\iiiint }{\mathop}{quadruple integral operator}%
+\xUnicodeMathSymbol{"02A0D}{\intbar }{\mathop}{finite part integral}%
+\xUnicodeMathSymbol{"02A0E}{\intBar }{\mathop}{integral with double stroke}%
+\xUnicodeMathSymbol{"02A0F}{\fint }{\mathop}{integral average with slash}%
+\xUnicodeMathSymbol{"02A10}{\cirfnint }{\mathop}{circulation function}%
+\xUnicodeMathSymbol{"02A11}{\awint }{\mathop}{anticlockwise integration}%
+\xUnicodeMathSymbol{"02A12}{\rppolint }{\mathop}{line integration with rectangular path around pole}%
+\xUnicodeMathSymbol{"02A13}{\scpolint }{\mathop}{line integration with semicircular path around pole}%
+\xUnicodeMathSymbol{"02A14}{\npolint }{\mathop}{line integration not including the pole}%
+\xUnicodeMathSymbol{"02A15}{\pointint }{\mathop}{integral around a point operator}%
+\xUnicodeMathSymbol{"02A16}{\sqint }{\mathop}{quaternion integral operator}%
+\xUnicodeMathSymbol{"02A17}{\intlarhk }{\mathop}{integral with leftwards arrow with hook}%
+\xUnicodeMathSymbol{"02A18}{\intx }{\mathop}{integral with times sign}%
+\xUnicodeMathSymbol{"02A19}{\intcap }{\mathop}{integral with intersection}%
+\xUnicodeMathSymbol{"02A1A}{\intcup }{\mathop}{integral with union}%
+\xUnicodeMathSymbol{"02A1B}{\upint }{\mathop}{integral with overbar}%
+\xUnicodeMathSymbol{"02A1C}{\lowint }{\mathop}{integral with underbar}%
+\xUnicodeMathSymbol{"02A1D}{\Join }{\mathop}{join}%
+\xUnicodeMathSymbol{"02A1E}{\bigtriangleleft }{\mathop}{large left triangle operator}%
+\xUnicodeMathSymbol{"02A1F}{\zcmp }{\mathop}{z notation schema composition}%
+\xUnicodeMathSymbol{"02A20}{\zpipe }{\mathop}{z notation schema piping}%
+\xUnicodeMathSymbol{"02A21}{\zproject }{\mathop}{z notation schema projection}%
+\xUnicodeMathSymbol{"02A22}{\ringplus }{\mathbin}{plus sign with small circle above}%
+\xUnicodeMathSymbol{"02A23}{\plushat }{\mathbin}{plus sign with circumflex accent above}%
+\xUnicodeMathSymbol{"02A24}{\simplus }{\mathbin}{plus sign with tilde above}%
+\xUnicodeMathSymbol{"02A25}{\plusdot }{\mathbin}{plus sign with dot below}%
+\xUnicodeMathSymbol{"02A26}{\plussim }{\mathbin}{plus sign with tilde below}%
+\xUnicodeMathSymbol{"02A27}{\plussubtwo }{\mathbin}{plus sign with subscript two}%
+\xUnicodeMathSymbol{"02A28}{\plustrif }{\mathbin}{plus sign with black triangle}%
+\xUnicodeMathSymbol{"02A29}{\commaminus }{\mathbin}{minus sign with comma above}%
+\xUnicodeMathSymbol{"02A2A}{\minusdot }{\mathbin}{minus sign with dot below}%
+\xUnicodeMathSymbol{"02A2B}{\minusfdots }{\mathbin}{minus sign with falling dots}%
+\xUnicodeMathSymbol{"02A2C}{\minusrdots }{\mathbin}{minus sign with rising dots}%
+\xUnicodeMathSymbol{"02A2D}{\opluslhrim }{\mathbin}{plus sign in left half circle}%
+\xUnicodeMathSymbol{"02A2E}{\oplusrhrim }{\mathbin}{plus sign in right half circle}%
+\xUnicodeMathSymbol{"02A2F}{\vectimes }{\mathbin}{vector or cross product}%
+\xUnicodeMathSymbol{"02A30}{\dottimes }{\mathbin}{multiplication sign with dot above}%
+\xUnicodeMathSymbol{"02A31}{\timesbar }{\mathbin}{multiplication sign with underbar}%
+\xUnicodeMathSymbol{"02A32}{\btimes }{\mathbin}{semidirect product with bottom closed}%
+\xUnicodeMathSymbol{"02A33}{\smashtimes }{\mathbin}{smash product}%
+\xUnicodeMathSymbol{"02A34}{\otimeslhrim }{\mathbin}{multiplication sign in left half circle}%
+\xUnicodeMathSymbol{"02A35}{\otimesrhrim }{\mathbin}{multiplication sign in right half circle}%
+\xUnicodeMathSymbol{"02A36}{\otimeshat }{\mathbin}{circled multiplication sign with circumflex accent}%
+\xUnicodeMathSymbol{"02A37}{\Otimes }{\mathbin}{multiplication sign in double circle}%
+\xUnicodeMathSymbol{"02A38}{\odiv }{\mathbin}{circled division sign}%
+\xUnicodeMathSymbol{"02A39}{\triangleplus }{\mathbin}{plus sign in triangle}%
+\xUnicodeMathSymbol{"02A3A}{\triangleminus }{\mathbin}{minus sign in triangle}%
+\xUnicodeMathSymbol{"02A3B}{\triangletimes }{\mathbin}{multiplication sign in triangle}%
+\xUnicodeMathSymbol{"02A3C}{\intprod }{\mathbin}{interior product}%
+\xUnicodeMathSymbol{"02A3D}{\intprodr }{\mathbin}{righthand interior product}%
+\xUnicodeMathSymbol{"02A3E}{\fcmp }{\mathbin}{z notation relational composition}%
+\xUnicodeMathSymbol{"02A3F}{\amalg }{\mathbin}{amalgamation or coproduct}%
+\xUnicodeMathSymbol{"02A40}{\capdot }{\mathbin}{intersection with dot}%
+\xUnicodeMathSymbol{"02A41}{\uminus }{\mathbin}{union with minus sign}%
+\xUnicodeMathSymbol{"02A42}{\barcup }{\mathbin}{union with overbar}%
+\xUnicodeMathSymbol{"02A43}{\barcap }{\mathbin}{intersection with overbar}%
+\xUnicodeMathSymbol{"02A44}{\capwedge }{\mathbin}{intersection with logical and}%
+\xUnicodeMathSymbol{"02A45}{\cupvee }{\mathbin}{union with logical or}%
+\xUnicodeMathSymbol{"02A46}{\cupovercap }{\mathbin}{union above intersection}%
+\xUnicodeMathSymbol{"02A47}{\capovercup }{\mathbin}{intersection above union}%
+\xUnicodeMathSymbol{"02A48}{\cupbarcap }{\mathbin}{union above bar above intersection}%
+\xUnicodeMathSymbol{"02A49}{\capbarcup }{\mathbin}{intersection above bar above union}%
+\xUnicodeMathSymbol{"02A4A}{\twocups }{\mathbin}{union beside and joined with union}%
+\xUnicodeMathSymbol{"02A4B}{\twocaps }{\mathbin}{intersection beside and joined with intersection}%
+\xUnicodeMathSymbol{"02A4C}{\closedvarcup }{\mathbin}{closed union with serifs}%
+\xUnicodeMathSymbol{"02A4D}{\closedvarcap }{\mathbin}{closed intersection with serifs}%
+\xUnicodeMathSymbol{"02A4E}{\Sqcap }{\mathbin}{double square intersection}%
+\xUnicodeMathSymbol{"02A4F}{\Sqcup }{\mathbin}{double square union}%
+\xUnicodeMathSymbol{"02A50}{\closedvarcupsmashprod }{\mathbin}{closed union with serifs and smash product}%
+\xUnicodeMathSymbol{"02A51}{\wedgeodot }{\mathbin}{logical and with dot above}%
+\xUnicodeMathSymbol{"02A52}{\veeodot }{\mathbin}{logical or with dot above}%
+\xUnicodeMathSymbol{"02A53}{\Wedge }{\mathbin}{double logical and}%
+\xUnicodeMathSymbol{"02A54}{\Vee }{\mathbin}{double logical or}%
+\xUnicodeMathSymbol{"02A55}{\wedgeonwedge }{\mathbin}{two intersecting logical and}%
+\xUnicodeMathSymbol{"02A56}{\veeonvee }{\mathbin}{two intersecting logical or}%
+\xUnicodeMathSymbol{"02A57}{\bigslopedvee }{\mathbin}{sloping large or}%
+\xUnicodeMathSymbol{"02A58}{\bigslopedwedge }{\mathbin}{sloping large and}%
+\xUnicodeMathSymbol{"02A59}{\veeonwedge }{\mathrel}{logical or overlapping logical and}%
+\xUnicodeMathSymbol{"02A5A}{\wedgemidvert }{\mathbin}{logical and with middle stem}%
+\xUnicodeMathSymbol{"02A5B}{\veemidvert }{\mathbin}{logical or with middle stem}%
+\xUnicodeMathSymbol{"02A5C}{\midbarwedge }{\mathbin}{ogical and with horizontal dash}%
+\xUnicodeMathSymbol{"02A5D}{\midbarvee }{\mathbin}{logical or with horizontal dash}%
+\xUnicodeMathSymbol{"02A5E}{\doublebarwedge }{\mathbin}{logical and with double overbar}%
+\xUnicodeMathSymbol{"02A5F}{\wedgebar }{\mathbin}{logical and with underbar}%
+\xUnicodeMathSymbol{"02A60}{\wedgedoublebar }{\mathbin}{logical and with double underbar}%
+\xUnicodeMathSymbol{"02A61}{\varveebar }{\mathbin}{small vee with underbar}%
+\xUnicodeMathSymbol{"02A62}{\doublebarvee }{\mathbin}{logical or with double overbar}%
+\xUnicodeMathSymbol{"02A63}{\veedoublebar }{\mathbin}{logical or with double underbar}%
+\xUnicodeMathSymbol{"02A64}{\dsub }{\mathbin}{z notation domain antirestriction}%
+\xUnicodeMathSymbol{"02A65}{\rsub }{\mathbin}{z notation range antirestriction}%
+\xUnicodeMathSymbol{"02A66}{\eqdot }{\mathrel}{equals sign with dot below}%
+\xUnicodeMathSymbol{"02A67}{\dotequiv }{\mathrel}{identical with dot above}%
+\xUnicodeMathSymbol{"02A68}{\equivVert }{\mathrel}{triple horizontal bar with double vertical stroke}%
+\xUnicodeMathSymbol{"02A69}{\equivVvert }{\mathrel}{triple horizontal bar with triple vertical stroke}%
+\xUnicodeMathSymbol{"02A6A}{\dotsim }{\mathrel}{tilde operator with dot above}%
+\xUnicodeMathSymbol{"02A6B}{\simrdots }{\mathrel}{tilde operator with rising dots}%
+\xUnicodeMathSymbol{"02A6C}{\simminussim }{\mathrel}{similar minus similar}%
+\xUnicodeMathSymbol{"02A6D}{\congdot }{\mathrel}{congruent with dot above}%
+\xUnicodeMathSymbol{"02A6E}{\asteq }{\mathrel}{equals with asterisk}%
+\xUnicodeMathSymbol{"02A6F}{\hatapprox }{\mathrel}{almost equal to with circumflex accent}%
+\xUnicodeMathSymbol{"02A70}{\approxeqq }{\mathrel}{approximately equal or equal to}%
+\xUnicodeMathSymbol{"02A71}{\eqqplus }{\mathbin}{equals sign above plus sign}%
+\xUnicodeMathSymbol{"02A72}{\pluseqq }{\mathbin}{plus sign above equals sign}%
+\xUnicodeMathSymbol{"02A73}{\eqqsim }{\mathrel}{equals sign above tilde operator}%
+\xUnicodeMathSymbol{"02A74}{\Coloneq }{\mathrel}{double colon equal}%
+\xUnicodeMathSymbol{"02A75}{\eqeq }{\mathrel}{two consecutive equals signs}%
+\xUnicodeMathSymbol{"02A76}{\eqeqeq }{\mathrel}{three consecutive equals signs}%
+\xUnicodeMathSymbol{"02A77}{\ddotseq }{\mathrel}{equals sign with two dots above and two dots below}%
+\xUnicodeMathSymbol{"02A78}{\equivDD }{\mathrel}{equivalent with four dots above}%
+\xUnicodeMathSymbol{"02A79}{\ltcir }{\mathrel}{less-than with circle inside}%
+\xUnicodeMathSymbol{"02A7A}{\gtcir }{\mathrel}{greater-than with circle inside}%
+\xUnicodeMathSymbol{"02A7B}{\ltquest }{\mathrel}{less-than with question mark above}%
+\xUnicodeMathSymbol{"02A7C}{\gtquest }{\mathrel}{greater-than with question mark above}%
+\xUnicodeMathSymbol{"02A7D}{\leqslant }{\mathrel}{less-than or slanted equal to}%
+\xUnicodeMathSymbol{"02A7E}{\geqslant }{\mathrel}{greater-than or slanted equal to}%
+\xUnicodeMathSymbol{"02A7F}{\lesdot }{\mathrel}{less-than or slanted equal to with dot inside}%
+\xUnicodeMathSymbol{"02A80}{\gesdot }{\mathrel}{greater-than or slanted equal to with dot inside}%
+\xUnicodeMathSymbol{"02A81}{\lesdoto }{\mathrel}{less-than or slanted equal to with dot above}%
+\xUnicodeMathSymbol{"02A82}{\gesdoto }{\mathrel}{greater-than or slanted equal to with dot above}%
+\xUnicodeMathSymbol{"02A83}{\lesdotor }{\mathrel}{less-than or slanted equal to with dot above right}%
+\xUnicodeMathSymbol{"02A84}{\gesdotol }{\mathrel}{greater-than or slanted equal to with dot above left}%
+\xUnicodeMathSymbol{"02A85}{\lessapprox }{\mathrel}{less-than or approximate}%
+\xUnicodeMathSymbol{"02A86}{\gtrapprox }{\mathrel}{greater-than or approximate}%
+\xUnicodeMathSymbol{"02A87}{\lneq }{\mathrel}{less-than and single-line not equal to}%
+\xUnicodeMathSymbol{"02A88}{\gneq }{\mathrel}{greater-than and single-line not equal to}%
+\xUnicodeMathSymbol{"02A89}{\lnapprox }{\mathrel}{less-than and not approximate}%
+\xUnicodeMathSymbol{"02A8A}{\gnapprox }{\mathrel}{greater-than and not approximate}%
+\xUnicodeMathSymbol{"02A8B}{\lesseqqgtr }{\mathrel}{less-than above double-line equal above greater-than}%
+\xUnicodeMathSymbol{"02A8C}{\gtreqqless }{\mathrel}{greater-than above double-line equal above less-than}%
+\xUnicodeMathSymbol{"02A8D}{\lsime }{\mathrel}{less-than above similar or equal}%
+\xUnicodeMathSymbol{"02A8E}{\gsime }{\mathrel}{greater-than above similar or equal}%
+\xUnicodeMathSymbol{"02A8F}{\lsimg }{\mathrel}{less-than above similar above greater-than}%
+\xUnicodeMathSymbol{"02A90}{\gsiml }{\mathrel}{greater-than above similar above less-than}%
+\xUnicodeMathSymbol{"02A91}{\lgE }{\mathrel}{less-than above greater-than above double-line equal}%
+\xUnicodeMathSymbol{"02A92}{\glE }{\mathrel}{greater-than above less-than above double-line equal}%
+\xUnicodeMathSymbol{"02A93}{\lesges }{\mathrel}{less-than above slanted equal above greater-than above slanted equal}%
+\xUnicodeMathSymbol{"02A94}{\gesles }{\mathrel}{greater-than above slanted equal above less-than above slanted equal}%
+\xUnicodeMathSymbol{"02A95}{\eqslantless }{\mathrel}{slanted equal to or less-than}%
+\xUnicodeMathSymbol{"02A96}{\eqslantgtr }{\mathrel}{slanted equal to or greater-than}%
+\xUnicodeMathSymbol{"02A97}{\elsdot }{\mathrel}{slanted equal to or less-than with dot inside}%
+\xUnicodeMathSymbol{"02A98}{\egsdot }{\mathrel}{slanted equal to or greater-than with dot inside}%
+\xUnicodeMathSymbol{"02A99}{\eqqless }{\mathrel}{double-line equal to or less-than}%
+\xUnicodeMathSymbol{"02A9A}{\eqqgtr }{\mathrel}{double-line equal to or greater-than}%
+\xUnicodeMathSymbol{"02A9B}{\eqqslantless }{\mathrel}{double-line slanted equal to or less-than}%
+\xUnicodeMathSymbol{"02A9C}{\eqqslantgtr }{\mathrel}{double-line slanted equal to or greater-than}%
+\xUnicodeMathSymbol{"02A9D}{\simless }{\mathrel}{similar or less-than}%
+\xUnicodeMathSymbol{"02A9E}{\simgtr }{\mathrel}{similar or greater-than}%
+\xUnicodeMathSymbol{"02A9F}{\simlE }{\mathrel}{similar above less-than above equals sign}%
+\xUnicodeMathSymbol{"02AA0}{\simgE }{\mathrel}{similar above greater-than above equals sign}%
+\xUnicodeMathSymbol{"02AA1}{\Lt }{\mathrel}{double nested less-than}%
+\xUnicodeMathSymbol{"02AA2}{\Gt }{\mathrel}{double nested greater-than}%
+\xUnicodeMathSymbol{"02AA3}{\partialmeetcontraction }{\mathrel}{double less-than with underbar}%
+\xUnicodeMathSymbol{"02AA4}{\glj }{\mathrel}{greater-than overlapping less-than}%
+\xUnicodeMathSymbol{"02AA5}{\gla }{\mathrel}{greater-than beside less-than}%
+\xUnicodeMathSymbol{"02AA6}{\ltcc }{\mathrel}{less-than closed by curve}%
+\xUnicodeMathSymbol{"02AA7}{\gtcc }{\mathrel}{greater-than closed by curve}%
+\xUnicodeMathSymbol{"02AA8}{\lescc }{\mathrel}{less-than closed by curve above slanted equal}%
+\xUnicodeMathSymbol{"02AA9}{\gescc }{\mathrel}{greater-than closed by curve above slanted equal}%
+\xUnicodeMathSymbol{"02AAA}{\smt }{\mathrel}{smaller than}%
+\xUnicodeMathSymbol{"02AAB}{\lat }{\mathrel}{larger than}%
+\xUnicodeMathSymbol{"02AAC}{\smte }{\mathrel}{smaller than or equal to}%
+\xUnicodeMathSymbol{"02AAD}{\late }{\mathrel}{larger than or equal to}%
+\xUnicodeMathSymbol{"02AAE}{\bumpeqq }{\mathrel}{equals sign with bumpy above}%
+\xUnicodeMathSymbol{"02AAF}{\preceq }{\mathrel}{precedes above single-line equals sign}%
+\xUnicodeMathSymbol{"02AB0}{\succeq }{\mathrel}{succeeds above single-line equals sign}%
+\xUnicodeMathSymbol{"02AB1}{\precneq }{\mathrel}{precedes above single-line not equal to}%
+\xUnicodeMathSymbol{"02AB2}{\succneq }{\mathrel}{succeeds above single-line not equal to}%
+\xUnicodeMathSymbol{"02AB3}{\preceqq }{\mathrel}{precedes above equals sign}%
+\xUnicodeMathSymbol{"02AB4}{\succeqq }{\mathrel}{succeeds above equals sign}%
+\xUnicodeMathSymbol{"02AB5}{\precneqq }{\mathrel}{precedes above not equal to}%
+\xUnicodeMathSymbol{"02AB6}{\succneqq }{\mathrel}{succeeds above not equal to}%
+\xUnicodeMathSymbol{"02AB7}{\precapprox }{\mathrel}{precedes above almost equal to}%
+\xUnicodeMathSymbol{"02AB8}{\succapprox }{\mathrel}{succeeds above almost equal to}%
+\xUnicodeMathSymbol{"02AB9}{\precnapprox }{\mathrel}{precedes above not almost equal to}%
+\xUnicodeMathSymbol{"02ABA}{\succnapprox }{\mathrel}{succeeds above not almost equal to}%
+\xUnicodeMathSymbol{"02ABB}{\Prec }{\mathrel}{double precedes}%
+\xUnicodeMathSymbol{"02ABC}{\Succ }{\mathrel}{double succeeds}%
+\xUnicodeMathSymbol{"02ABD}{\subsetdot }{\mathrel}{subset with dot}%
+\xUnicodeMathSymbol{"02ABE}{\supsetdot }{\mathrel}{superset with dot}%
+\xUnicodeMathSymbol{"02ABF}{\subsetplus }{\mathrel}{subset with plus sign below}%
+\xUnicodeMathSymbol{"02AC0}{\supsetplus }{\mathrel}{superset with plus sign below}%
+\xUnicodeMathSymbol{"02AC1}{\submult }{\mathrel}{subset with multiplication sign below}%
+\xUnicodeMathSymbol{"02AC2}{\supmult }{\mathrel}{superset with multiplication sign below}%
+\xUnicodeMathSymbol{"02AC3}{\subedot }{\mathrel}{subset of or equal to with dot above}%
+\xUnicodeMathSymbol{"02AC4}{\supedot }{\mathrel}{superset of or equal to with dot above}%
+\xUnicodeMathSymbol{"02AC5}{\subseteqq }{\mathrel}{subset of above equals sign}%
+\xUnicodeMathSymbol{"02AC6}{\supseteqq }{\mathrel}{superset of above equals sign}%
+\xUnicodeMathSymbol{"02AC7}{\subsim }{\mathrel}{subset of above tilde operator}%
+\xUnicodeMathSymbol{"02AC8}{\supsim }{\mathrel}{superset of above tilde operator}%
+\xUnicodeMathSymbol{"02AC9}{\subsetapprox }{\mathrel}{subset of above almost equal to}%
+\xUnicodeMathSymbol{"02ACA}{\supsetapprox }{\mathrel}{superset of above almost equal to}%
+\xUnicodeMathSymbol{"02ACB}{\subsetneqq }{\mathrel}{subset of above not equal to}%
+\xUnicodeMathSymbol{"02ACC}{\supsetneqq }{\mathrel}{superset of above not equal to}%
+\xUnicodeMathSymbol{"02ACD}{\lsqhook }{\mathrel}{square left open box operator}%
+\xUnicodeMathSymbol{"02ACE}{\rsqhook }{\mathrel}{square right open box operator}%
+\xUnicodeMathSymbol{"02ACF}{\csub }{\mathrel}{closed subset}%
+\xUnicodeMathSymbol{"02AD0}{\csup }{\mathrel}{closed superset}%
+\xUnicodeMathSymbol{"02AD1}{\csube }{\mathrel}{closed subset or equal to}%
+\xUnicodeMathSymbol{"02AD2}{\csupe }{\mathrel}{closed superset or equal to}%
+\xUnicodeMathSymbol{"02AD3}{\subsup }{\mathrel}{subset above superset}%
+\xUnicodeMathSymbol{"02AD4}{\supsub }{\mathrel}{superset above subset}%
+\xUnicodeMathSymbol{"02AD5}{\subsub }{\mathrel}{subset above subset}%
+\xUnicodeMathSymbol{"02AD6}{\supsup }{\mathrel}{superset above superset}%
+\xUnicodeMathSymbol{"02AD7}{\suphsub }{\mathrel}{superset beside subset}%
+\xUnicodeMathSymbol{"02AD8}{\supdsub }{\mathrel}{superset beside and joined by dash with subset}%
+\xUnicodeMathSymbol{"02AD9}{\forkv }{\mathrel}{element of opening downwards}%
+\xUnicodeMathSymbol{"02ADA}{\topfork }{\mathrel}{pitchfork with tee top}%
+\xUnicodeMathSymbol{"02ADB}{\mlcp }{\mathrel}{transversal intersection}%
+\xUnicodeMathSymbol{"02ADC}{\forks }{\mathrel}{forking}%
+\xUnicodeMathSymbol{"02ADD}{\forksnot }{\mathrel}{nonforking}%
+\xUnicodeMathSymbol{"02ADE}{\shortlefttack }{\mathrel}{short left tack}%
+\xUnicodeMathSymbol{"02ADF}{\shortdowntack }{\mathrel}{short down tack}%
+\xUnicodeMathSymbol{"02AE0}{\shortuptack }{\mathrel}{short up tack}%
+\xUnicodeMathSymbol{"02AE1}{\perps }{\mathord}{perpendicular with s}%
+\xUnicodeMathSymbol{"02AE2}{\vDdash }{\mathrel}{vertical bar triple right turnstile}%
+\xUnicodeMathSymbol{"02AE3}{\dashV }{\mathrel}{double vertical bar left turnstile}%
+\xUnicodeMathSymbol{"02AE4}{\Dashv }{\mathrel}{vertical bar double left turnstile}%
+\xUnicodeMathSymbol{"02AE5}{\DashV }{\mathrel}{double vertical bar double left turnstile}%
+\xUnicodeMathSymbol{"02AE6}{\varVdash }{\mathrel}{long dash from left member of double vertical}%
+\xUnicodeMathSymbol{"02AE7}{\Barv }{\mathrel}{short down tack with overbar}%
+\xUnicodeMathSymbol{"02AE8}{\vBar }{\mathrel}{short up tack with underbar}%
+\xUnicodeMathSymbol{"02AE9}{\vBarv }{\mathrel}{short up tack above short down tack}%
+\xUnicodeMathSymbol{"02AEA}{\barV }{\mathrel}{double down tack}%
+\xUnicodeMathSymbol{"02AEB}{\Vbar }{\mathrel}{double up tack}%
+\xUnicodeMathSymbol{"02AEC}{\Not }{\mathrel}{double stroke not sign}%
+\xUnicodeMathSymbol{"02AED}{\bNot }{\mathrel}{reversed double stroke not sign}%
+\xUnicodeMathSymbol{"02AEE}{\revnmid }{\mathrel}{does not divide with reversed negation slash}%
+\xUnicodeMathSymbol{"02AEF}{\cirmid }{\mathrel}{vertical line with circle above}%
+\xUnicodeMathSymbol{"02AF0}{\midcir }{\mathrel}{vertical line with circle below}%
+\xUnicodeMathSymbol{"02AF1}{\topcir }{\mathord}{down tack with circle below}%
+\xUnicodeMathSymbol{"02AF2}{\nhpar }{\mathrel}{parallel with horizontal stroke}%
+\xUnicodeMathSymbol{"02AF3}{\parsim }{\mathrel}{parallel with tilde operator}%
+\xUnicodeMathSymbol{"02AF4}{\interleave }{\mathbin}{triple vertical bar binary relation}%
+\xUnicodeMathSymbol{"02AF5}{\nhVvert }{\mathbin}{triple vertical bar with horizontal stroke}%
+\xUnicodeMathSymbol{"02AF6}{\threedotcolon }{\mathbin}{triple colon operator}%
+\xUnicodeMathSymbol{"02AF7}{\lllnest }{\mathrel}{stacked very much less-than}%
+\xUnicodeMathSymbol{"02AF8}{\gggnest }{\mathrel}{stacked very much greater-than}%
+\xUnicodeMathSymbol{"02AF9}{\leqqslant }{\mathrel}{double-line slanted less-than or equal to}%
+\xUnicodeMathSymbol{"02AFA}{\geqqslant }{\mathrel}{double-line slanted greater-than or equal to}%
+\xUnicodeMathSymbol{"02AFB}{\trslash }{\mathbin}{triple solidus binary relation}%
+\xUnicodeMathSymbol{"02AFC}{\biginterleave }{\mathop}{large triple vertical bar operator}%
+\xUnicodeMathSymbol{"02AFD}{\sslash }{\mathbin}{double solidus operator}%
+\xUnicodeMathSymbol{"02AFE}{\talloblong }{\mathbin}{white vertical bar}%
+\xUnicodeMathSymbol{"02AFF}{\bigtalloblong }{\mathop}{n-ary white vertical bar}%
+\xUnicodeMathSymbol{"02B12}{\squaretopblack }{\mathord}{square with top half black}%
+\xUnicodeMathSymbol{"02B13}{\squarebotblack }{\mathord}{square with bottom half black}%
+\xUnicodeMathSymbol{"02B14}{\squareurblack }{\mathord}{square with upper right diagonal half black}%
+\xUnicodeMathSymbol{"02B15}{\squarellblack }{\mathord}{square with lower left diagonal half black}%
+\xUnicodeMathSymbol{"02B16}{\diamondleftblack }{\mathord}{diamond with left half black}%
+\xUnicodeMathSymbol{"02B17}{\diamondrightblack }{\mathord}{diamond with right half black}%
+\xUnicodeMathSymbol{"02B18}{\diamondtopblack }{\mathord}{diamond with top half black}%
+\xUnicodeMathSymbol{"02B19}{\diamondbotblack }{\mathord}{diamond with bottom half black}%
+\xUnicodeMathSymbol{"02B1A}{\dottedsquare }{\mathord}{dotted square}%
+\xUnicodeMathSymbol{"02B1B}{\lgblksquare }{\mathord}{black large square}%
+\xUnicodeMathSymbol{"02B1C}{\lgwhtsquare }{\mathord}{white large square}%
+\xUnicodeMathSymbol{"02B1D}{\vysmblksquare }{\mathord}{black very small square}%
+\xUnicodeMathSymbol{"02B1E}{\vysmwhtsquare }{\mathord}{white very small square}%
+\xUnicodeMathSymbol{"02B1F}{\pentagonblack }{\mathord}{black pentagon}%
+\xUnicodeMathSymbol{"02B20}{\pentagon }{\mathord}{white pentagon}%
+\xUnicodeMathSymbol{"02B21}{\varhexagon }{\mathord}{white hexagon}%
+\xUnicodeMathSymbol{"02B22}{\varhexagonblack }{\mathord}{black hexagon}%
+\xUnicodeMathSymbol{"02B23}{\hexagonblack }{\mathord}{horizontal black hexagon}%
+\xUnicodeMathSymbol{"02B24}{\lgblkcircle }{\mathord}{black large circle}%
+\xUnicodeMathSymbol{"02B25}{\mdblkdiamond }{\mathord}{black medium diamond}%
+\xUnicodeMathSymbol{"02B26}{\mdwhtdiamond }{\mathord}{white medium diamond}%
+\xUnicodeMathSymbol{"02B27}{\mdblklozenge }{\mathord}{black medium lozenge}%
+\xUnicodeMathSymbol{"02B28}{\mdwhtlozenge }{\mathord}{white medium lozenge}%
+\xUnicodeMathSymbol{"02B29}{\smblkdiamond }{\mathord}{black small diamond}%
+\xUnicodeMathSymbol{"02B2A}{\smblklozenge }{\mathord}{black small lozenge}%
+\xUnicodeMathSymbol{"02B2B}{\smwhtlozenge }{\mathord}{white small lozenge}%
+\xUnicodeMathSymbol{"02B2C}{\blkhorzoval }{\mathord}{black horizontal ellipse}%
+\xUnicodeMathSymbol{"02B2D}{\whthorzoval }{\mathord}{white horizontal ellipse}%
+\xUnicodeMathSymbol{"02B2E}{\blkvertoval }{\mathord}{black vertical ellipse}%
+\xUnicodeMathSymbol{"02B2F}{\whtvertoval }{\mathord}{white vertical ellipse}%
+\xUnicodeMathSymbol{"02B30}{\circleonleftarrow }{\mathrel}{left arrow with small circle}%
+\xUnicodeMathSymbol{"02B31}{\leftthreearrows }{\mathrel}{three leftwards arrows}%
+\xUnicodeMathSymbol{"02B32}{\leftarrowonoplus }{\mathrel}{left arrow with circled plus}%
+\xUnicodeMathSymbol{"02B33}{\longleftsquigarrow }{\mathrel}{long leftwards squiggle arrow}%
+\xUnicodeMathSymbol{"02B34}{\nvtwoheadleftarrow }{\mathrel}{leftwards two-headed arrow with vertical stroke}%
+\xUnicodeMathSymbol{"02B35}{\nVtwoheadleftarrow }{\mathrel}{leftwards two-headed arrow with double vertical stroke}%
+\xUnicodeMathSymbol{"02B36}{\twoheadmapsfrom }{\mathrel}{leftwards two-headed arrow from bar}%
+\xUnicodeMathSymbol{"02B37}{\twoheadleftdbkarrow }{\mathrel}{leftwards two-headed triple-dash arrow}%
+\xUnicodeMathSymbol{"02B38}{\leftdotarrow }{\mathrel}{leftwards arrow with dotted stem}%
+\xUnicodeMathSymbol{"02B39}{\nvleftarrowtail }{\mathrel}{leftwards arrow with tail with vertical stroke}%
+\xUnicodeMathSymbol{"02B3A}{\nVleftarrowtail }{\mathrel}{leftwards arrow with tail with double vertical stroke}%
+\xUnicodeMathSymbol{"02B3B}{\twoheadleftarrowtail }{\mathrel}{leftwards two-headed arrow with tail}%
+\xUnicodeMathSymbol{"02B3C}{\nvtwoheadleftarrowtail }{\mathrel}{leftwards two-headed arrow with tail with vertical stroke}%
+\xUnicodeMathSymbol{"02B3D}{\nVtwoheadleftarrowtail }{\mathrel}{leftwards two-headed arrow with tail with double vertical stroke}%
+\xUnicodeMathSymbol{"02B3E}{\leftarrowx }{\mathrel}{leftwards arrow through x}%
+\xUnicodeMathSymbol{"02B3F}{\leftcurvedarrow }{\mathrel}{wave arrow pointing directly left}%
+\xUnicodeMathSymbol{"02B40}{\equalleftarrow }{\mathrel}{equals sign above leftwards arrow}%
+\xUnicodeMathSymbol{"02B41}{\bsimilarleftarrow }{\mathrel}{reverse tilde operator above leftwards arrow}%
+\xUnicodeMathSymbol{"02B42}{\leftarrowbackapprox }{\mathrel}{leftwards arrow above reverse almost equal to}%
+\xUnicodeMathSymbol{"02B43}{\rightarrowgtr }{\mathrel}{rightwards arrow through greater-than}%
+\xUnicodeMathSymbol{"02B44}{\rightarrowsupset }{\mathrel}{rightwards arrow through subset}%
+\xUnicodeMathSymbol{"02B45}{\LLeftarrow }{\mathrel}{leftwards quadruple arrow}%
+\xUnicodeMathSymbol{"02B46}{\RRightarrow }{\mathrel}{rightwards quadruple arrow}%
+\xUnicodeMathSymbol{"02B47}{\bsimilarrightarrow }{\mathrel}{reverse tilde operator above rightwards arrow}%
+\xUnicodeMathSymbol{"02B48}{\rightarrowbackapprox }{\mathrel}{rightwards arrow above reverse almost equal to}%
+\xUnicodeMathSymbol{"02B49}{\similarleftarrow }{\mathrel}{tilde operator above leftwards arrow}%
+\xUnicodeMathSymbol{"02B4A}{\leftarrowapprox }{\mathrel}{leftwards arrow above almost equal to}%
+\xUnicodeMathSymbol{"02B4B}{\leftarrowbsimilar }{\mathrel}{leftwards arrow above reverse tilde operator}%
+\xUnicodeMathSymbol{"02B4C}{\rightarrowbsimilar }{\mathrel}{righttwards arrow above reverse tilde operator}%
+\xUnicodeMathSymbol{"02B50}{\medwhitestar }{\mathord}{white medium star}%
+\xUnicodeMathSymbol{"02B51}{\medblackstar }{\mathord}{black medium star}%
+\xUnicodeMathSymbol{"02B52}{\smwhitestar }{\mathord}{white small star}%
+\xUnicodeMathSymbol{"02B53}{\rightpentagonblack }{\mathord}{black right-pointing pentagon}%
+\xUnicodeMathSymbol{"02B54}{\rightpentagon }{\mathord}{white right-pointing pentagon}%
+\xUnicodeMathSymbol{"03012}{\postalmark }{\mathord}{postal mark}%
+\xUnicodeMathSymbol{"03030}{\hzigzag }{\mathord}{zigzag}%
+\xUnicodeMathSymbol{"1D400}{\mbfA }{\mathalpha}{mathematical bold capital a}%
+\xUnicodeMathSymbol{"1D401}{\mbfB }{\mathalpha}{mathematical bold capital b}%
+\xUnicodeMathSymbol{"1D402}{\mbfC }{\mathalpha}{mathematical bold capital c}%
+\xUnicodeMathSymbol{"1D403}{\mbfD }{\mathalpha}{mathematical bold capital d}%
+\xUnicodeMathSymbol{"1D404}{\mbfE }{\mathalpha}{mathematical bold capital e}%
+\xUnicodeMathSymbol{"1D405}{\mbfF }{\mathalpha}{mathematical bold capital f}%
+\xUnicodeMathSymbol{"1D406}{\mbfG }{\mathalpha}{mathematical bold capital g}%
+\xUnicodeMathSymbol{"1D407}{\mbfH }{\mathalpha}{mathematical bold capital h}%
+\xUnicodeMathSymbol{"1D408}{\mbfI }{\mathalpha}{mathematical bold capital i}%
+\xUnicodeMathSymbol{"1D409}{\mbfJ }{\mathalpha}{mathematical bold capital j}%
+\xUnicodeMathSymbol{"1D40A}{\mbfK }{\mathalpha}{mathematical bold capital k}%
+\xUnicodeMathSymbol{"1D40B}{\mbfL }{\mathalpha}{mathematical bold capital l}%
+\xUnicodeMathSymbol{"1D40C}{\mbfM }{\mathalpha}{mathematical bold capital m}%
+\xUnicodeMathSymbol{"1D40D}{\mbfN }{\mathalpha}{mathematical bold capital n}%
+\xUnicodeMathSymbol{"1D40E}{\mbfO }{\mathalpha}{mathematical bold capital o}%
+\xUnicodeMathSymbol{"1D40F}{\mbfP }{\mathalpha}{mathematical bold capital p}%
+\xUnicodeMathSymbol{"1D410}{\mbfQ }{\mathalpha}{mathematical bold capital q}%
+\xUnicodeMathSymbol{"1D411}{\mbfR }{\mathalpha}{mathematical bold capital r}%
+\xUnicodeMathSymbol{"1D412}{\mbfS }{\mathalpha}{mathematical bold capital s}%
+\xUnicodeMathSymbol{"1D413}{\mbfT }{\mathalpha}{mathematical bold capital t}%
+\xUnicodeMathSymbol{"1D414}{\mbfU }{\mathalpha}{mathematical bold capital u}%
+\xUnicodeMathSymbol{"1D415}{\mbfV }{\mathalpha}{mathematical bold capital v}%
+\xUnicodeMathSymbol{"1D416}{\mbfW }{\mathalpha}{mathematical bold capital w}%
+\xUnicodeMathSymbol{"1D417}{\mbfX }{\mathalpha}{mathematical bold capital x}%
+\xUnicodeMathSymbol{"1D418}{\mbfY }{\mathalpha}{mathematical bold capital y}%
+\xUnicodeMathSymbol{"1D419}{\mbfZ }{\mathalpha}{mathematical bold capital z}%
+\xUnicodeMathSymbol{"1D41A}{\mbfa }{\mathalpha}{mathematical bold small a}%
+\xUnicodeMathSymbol{"1D41B}{\mbfb }{\mathalpha}{mathematical bold small b}%
+\xUnicodeMathSymbol{"1D41C}{\mbfc }{\mathalpha}{mathematical bold small c}%
+\xUnicodeMathSymbol{"1D41D}{\mbfd }{\mathalpha}{mathematical bold small d}%
+\xUnicodeMathSymbol{"1D41E}{\mbfe }{\mathalpha}{mathematical bold small e}%
+\xUnicodeMathSymbol{"1D41F}{\mbff }{\mathalpha}{mathematical bold small f}%
+\xUnicodeMathSymbol{"1D420}{\mbfg }{\mathalpha}{mathematical bold small g}%
+\xUnicodeMathSymbol{"1D421}{\mbfh }{\mathalpha}{mathematical bold small h}%
+\xUnicodeMathSymbol{"1D422}{\mbfi }{\mathalpha}{mathematical bold small i}%
+\xUnicodeMathSymbol{"1D423}{\mbfj }{\mathalpha}{mathematical bold small j}%
+\xUnicodeMathSymbol{"1D424}{\mbfk }{\mathalpha}{mathematical bold small k}%
+\xUnicodeMathSymbol{"1D425}{\mbfl }{\mathalpha}{mathematical bold small l}%
+\xUnicodeMathSymbol{"1D426}{\mbfm }{\mathalpha}{mathematical bold small m}%
+\xUnicodeMathSymbol{"1D427}{\mbfn }{\mathalpha}{mathematical bold small n}%
+\xUnicodeMathSymbol{"1D428}{\mbfo }{\mathalpha}{mathematical bold small o}%
+\xUnicodeMathSymbol{"1D429}{\mbfp }{\mathalpha}{mathematical bold small p}%
+\xUnicodeMathSymbol{"1D42A}{\mbfq }{\mathalpha}{mathematical bold small q}%
+\xUnicodeMathSymbol{"1D42B}{\mbfr }{\mathalpha}{mathematical bold small r}%
+\xUnicodeMathSymbol{"1D42C}{\mbfs }{\mathalpha}{mathematical bold small s}%
+\xUnicodeMathSymbol{"1D42D}{\mbft }{\mathalpha}{mathematical bold small t}%
+\xUnicodeMathSymbol{"1D42E}{\mbfu }{\mathalpha}{mathematical bold small u}%
+\xUnicodeMathSymbol{"1D42F}{\mbfv }{\mathalpha}{mathematical bold small v}%
+\xUnicodeMathSymbol{"1D430}{\mbfw }{\mathalpha}{mathematical bold small w}%
+\xUnicodeMathSymbol{"1D431}{\mbfx }{\mathalpha}{mathematical bold small x}%
+\xUnicodeMathSymbol{"1D432}{\mbfy }{\mathalpha}{mathematical bold small y}%
+\xUnicodeMathSymbol{"1D433}{\mbfz }{\mathalpha}{mathematical bold small z}%
+\xUnicodeMathSymbol{"1D434}{\mitA }{\mathalpha}{mathematical italic capital a}%
+\xUnicodeMathSymbol{"1D435}{\mitB }{\mathalpha}{mathematical italic capital b}%
+\xUnicodeMathSymbol{"1D436}{\mitC }{\mathalpha}{mathematical italic capital c}%
+\xUnicodeMathSymbol{"1D437}{\mitD }{\mathalpha}{mathematical italic capital d}%
+\xUnicodeMathSymbol{"1D438}{\mitE }{\mathalpha}{mathematical italic capital e}%
+\xUnicodeMathSymbol{"1D439}{\mitF }{\mathalpha}{mathematical italic capital f}%
+\xUnicodeMathSymbol{"1D43A}{\mitG }{\mathalpha}{mathematical italic capital g}%
+\xUnicodeMathSymbol{"1D43B}{\mitH }{\mathalpha}{mathematical italic capital h}%
+\xUnicodeMathSymbol{"1D43C}{\mitI }{\mathalpha}{mathematical italic capital i}%
+\xUnicodeMathSymbol{"1D43D}{\mitJ }{\mathalpha}{mathematical italic capital j}%
+\xUnicodeMathSymbol{"1D43E}{\mitK }{\mathalpha}{mathematical italic capital k}%
+\xUnicodeMathSymbol{"1D43F}{\mitL }{\mathalpha}{mathematical italic capital l}%
+\xUnicodeMathSymbol{"1D440}{\mitM }{\mathalpha}{mathematical italic capital m}%
+\xUnicodeMathSymbol{"1D441}{\mitN }{\mathalpha}{mathematical italic capital n}%
+\xUnicodeMathSymbol{"1D442}{\mitO }{\mathalpha}{mathematical italic capital o}%
+\xUnicodeMathSymbol{"1D443}{\mitP }{\mathalpha}{mathematical italic capital p}%
+\xUnicodeMathSymbol{"1D444}{\mitQ }{\mathalpha}{mathematical italic capital q}%
+\xUnicodeMathSymbol{"1D445}{\mitR }{\mathalpha}{mathematical italic capital r}%
+\xUnicodeMathSymbol{"1D446}{\mitS }{\mathalpha}{mathematical italic capital s}%
+\xUnicodeMathSymbol{"1D447}{\mitT }{\mathalpha}{mathematical italic capital t}%
+\xUnicodeMathSymbol{"1D448}{\mitU }{\mathalpha}{mathematical italic capital u}%
+\xUnicodeMathSymbol{"1D449}{\mitV }{\mathalpha}{mathematical italic capital v}%
+\xUnicodeMathSymbol{"1D44A}{\mitW }{\mathalpha}{mathematical italic capital w}%
+\xUnicodeMathSymbol{"1D44B}{\mitX }{\mathalpha}{mathematical italic capital x}%
+\xUnicodeMathSymbol{"1D44C}{\mitY }{\mathalpha}{mathematical italic capital y}%
+\xUnicodeMathSymbol{"1D44D}{\mitZ }{\mathalpha}{mathematical italic capital z}%
+\xUnicodeMathSymbol{"1D44E}{\mita }{\mathalpha}{mathematical italic small a}%
+\xUnicodeMathSymbol{"1D44F}{\mitb }{\mathalpha}{mathematical italic small b}%
+\xUnicodeMathSymbol{"1D450}{\mitc }{\mathalpha}{mathematical italic small c}%
+\xUnicodeMathSymbol{"1D451}{\mitd }{\mathalpha}{mathematical italic small d}%
+\xUnicodeMathSymbol{"1D452}{\mite }{\mathalpha}{mathematical italic small e}%
+\xUnicodeMathSymbol{"1D453}{\mitf }{\mathalpha}{mathematical italic small f}%
+\xUnicodeMathSymbol{"1D454}{\mitg }{\mathalpha}{mathematical italic small g}%
+\xUnicodeMathSymbol{"1D456}{\miti }{\mathalpha}{mathematical italic small i}%
+\xUnicodeMathSymbol{"1D457}{\mitj }{\mathalpha}{mathematical italic small j}%
+\xUnicodeMathSymbol{"1D458}{\mitk }{\mathalpha}{mathematical italic small k}%
+\xUnicodeMathSymbol{"1D459}{\mitl }{\mathalpha}{mathematical italic small l}%
+\xUnicodeMathSymbol{"1D45A}{\mitm }{\mathalpha}{mathematical italic small m}%
+\xUnicodeMathSymbol{"1D45B}{\mitn }{\mathalpha}{mathematical italic small n}%
+\xUnicodeMathSymbol{"1D45C}{\mito }{\mathalpha}{mathematical italic small o}%
+\xUnicodeMathSymbol{"1D45D}{\mitp }{\mathalpha}{mathematical italic small p}%
+\xUnicodeMathSymbol{"1D45E}{\mitq }{\mathalpha}{mathematical italic small q}%
+\xUnicodeMathSymbol{"1D45F}{\mitr }{\mathalpha}{mathematical italic small r}%
+\xUnicodeMathSymbol{"1D460}{\mits }{\mathalpha}{mathematical italic small s}%
+\xUnicodeMathSymbol{"1D461}{\mitt }{\mathalpha}{mathematical italic small t}%
+\xUnicodeMathSymbol{"1D462}{\mitu }{\mathalpha}{mathematical italic small u}%
+\xUnicodeMathSymbol{"1D463}{\mitv }{\mathalpha}{mathematical italic small v}%
+\xUnicodeMathSymbol{"1D464}{\mitw }{\mathalpha}{mathematical italic small w}%
+\xUnicodeMathSymbol{"1D465}{\mitx }{\mathalpha}{mathematical italic small x}%
+\xUnicodeMathSymbol{"1D466}{\mity }{\mathalpha}{mathematical italic small y}%
+\xUnicodeMathSymbol{"1D467}{\mitz }{\mathalpha}{mathematical italic small z}%
+\xUnicodeMathSymbol{"1D468}{\mbfitA }{\mathalpha}{mathematical bold italic capital a}%
+\xUnicodeMathSymbol{"1D469}{\mbfitB }{\mathalpha}{mathematical bold italic capital b}%
+\xUnicodeMathSymbol{"1D46A}{\mbfitC }{\mathalpha}{mathematical bold italic capital c}%
+\xUnicodeMathSymbol{"1D46B}{\mbfitD }{\mathalpha}{mathematical bold italic capital d}%
+\xUnicodeMathSymbol{"1D46C}{\mbfitE }{\mathalpha}{mathematical bold italic capital e}%
+\xUnicodeMathSymbol{"1D46D}{\mbfitF }{\mathalpha}{mathematical bold italic capital f}%
+\xUnicodeMathSymbol{"1D46E}{\mbfitG }{\mathalpha}{mathematical bold italic capital g}%
+\xUnicodeMathSymbol{"1D46F}{\mbfitH }{\mathalpha}{mathematical bold italic capital h}%
+\xUnicodeMathSymbol{"1D470}{\mbfitI }{\mathalpha}{mathematical bold italic capital i}%
+\xUnicodeMathSymbol{"1D471}{\mbfitJ }{\mathalpha}{mathematical bold italic capital j}%
+\xUnicodeMathSymbol{"1D472}{\mbfitK }{\mathalpha}{mathematical bold italic capital k}%
+\xUnicodeMathSymbol{"1D473}{\mbfitL }{\mathalpha}{mathematical bold italic capital l}%
+\xUnicodeMathSymbol{"1D474}{\mbfitM }{\mathalpha}{mathematical bold italic capital m}%
+\xUnicodeMathSymbol{"1D475}{\mbfitN }{\mathalpha}{mathematical bold italic capital n}%
+\xUnicodeMathSymbol{"1D476}{\mbfitO }{\mathalpha}{mathematical bold italic capital o}%
+\xUnicodeMathSymbol{"1D477}{\mbfitP }{\mathalpha}{mathematical bold italic capital p}%
+\xUnicodeMathSymbol{"1D478}{\mbfitQ }{\mathalpha}{mathematical bold italic capital q}%
+\xUnicodeMathSymbol{"1D479}{\mbfitR }{\mathalpha}{mathematical bold italic capital r}%
+\xUnicodeMathSymbol{"1D47A}{\mbfitS }{\mathalpha}{mathematical bold italic capital s}%
+\xUnicodeMathSymbol{"1D47B}{\mbfitT }{\mathalpha}{mathematical bold italic capital t}%
+\xUnicodeMathSymbol{"1D47C}{\mbfitU }{\mathalpha}{mathematical bold italic capital u}%
+\xUnicodeMathSymbol{"1D47D}{\mbfitV }{\mathalpha}{mathematical bold italic capital v}%
+\xUnicodeMathSymbol{"1D47E}{\mbfitW }{\mathalpha}{mathematical bold italic capital w}%
+\xUnicodeMathSymbol{"1D47F}{\mbfitX }{\mathalpha}{mathematical bold italic capital x}%
+\xUnicodeMathSymbol{"1D480}{\mbfitY }{\mathalpha}{mathematical bold italic capital y}%
+\xUnicodeMathSymbol{"1D481}{\mbfitZ }{\mathalpha}{mathematical bold italic capital z}%
+\xUnicodeMathSymbol{"1D482}{\mbfita }{\mathalpha}{mathematical bold italic small a}%
+\xUnicodeMathSymbol{"1D483}{\mbfitb }{\mathalpha}{mathematical bold italic small b}%
+\xUnicodeMathSymbol{"1D484}{\mbfitc }{\mathalpha}{mathematical bold italic small c}%
+\xUnicodeMathSymbol{"1D485}{\mbfitd }{\mathalpha}{mathematical bold italic small d}%
+\xUnicodeMathSymbol{"1D486}{\mbfite }{\mathalpha}{mathematical bold italic small e}%
+\xUnicodeMathSymbol{"1D487}{\mbfitf }{\mathalpha}{mathematical bold italic small f}%
+\xUnicodeMathSymbol{"1D488}{\mbfitg }{\mathalpha}{mathematical bold italic small g}%
+\xUnicodeMathSymbol{"1D489}{\mbfith }{\mathalpha}{mathematical bold italic small h}%
+\xUnicodeMathSymbol{"1D48A}{\mbfiti }{\mathalpha}{mathematical bold italic small i}%
+\xUnicodeMathSymbol{"1D48B}{\mbfitj }{\mathalpha}{mathematical bold italic small j}%
+\xUnicodeMathSymbol{"1D48C}{\mbfitk }{\mathalpha}{mathematical bold italic small k}%
+\xUnicodeMathSymbol{"1D48D}{\mbfitl }{\mathalpha}{mathematical bold italic small l}%
+\xUnicodeMathSymbol{"1D48E}{\mbfitm }{\mathalpha}{mathematical bold italic small m}%
+\xUnicodeMathSymbol{"1D48F}{\mbfitn }{\mathalpha}{mathematical bold italic small n}%
+\xUnicodeMathSymbol{"1D490}{\mbfito }{\mathalpha}{mathematical bold italic small o}%
+\xUnicodeMathSymbol{"1D491}{\mbfitp }{\mathalpha}{mathematical bold italic small p}%
+\xUnicodeMathSymbol{"1D492}{\mbfitq }{\mathalpha}{mathematical bold italic small q}%
+\xUnicodeMathSymbol{"1D493}{\mbfitr }{\mathalpha}{mathematical bold italic small r}%
+\xUnicodeMathSymbol{"1D494}{\mbfits }{\mathalpha}{mathematical bold italic small s}%
+\xUnicodeMathSymbol{"1D495}{\mbfitt }{\mathalpha}{mathematical bold italic small t}%
+\xUnicodeMathSymbol{"1D496}{\mbfitu }{\mathalpha}{mathematical bold italic small u}%
+\xUnicodeMathSymbol{"1D497}{\mbfitv }{\mathalpha}{mathematical bold italic small v}%
+\xUnicodeMathSymbol{"1D498}{\mbfitw }{\mathalpha}{mathematical bold italic small w}%
+\xUnicodeMathSymbol{"1D499}{\mbfitx }{\mathalpha}{mathematical bold italic small x}%
+\xUnicodeMathSymbol{"1D49A}{\mbfity }{\mathalpha}{mathematical bold italic small y}%
+\xUnicodeMathSymbol{"1D49B}{\mbfitz }{\mathalpha}{mathematical bold italic small z}%
+\xUnicodeMathSymbol{"1D49C}{\mscrA }{\mathalpha}{mathematical script capital a}%
+\xUnicodeMathSymbol{"1D49E}{\mscrC }{\mathalpha}{mathematical script capital c}%
+\xUnicodeMathSymbol{"1D49F}{\mscrD }{\mathalpha}{mathematical script capital d}%
+\xUnicodeMathSymbol{"1D4A2}{\mscrG }{\mathalpha}{mathematical script capital g}%
+\xUnicodeMathSymbol{"1D4A5}{\mscrJ }{\mathalpha}{mathematical script capital j}%
+\xUnicodeMathSymbol{"1D4A6}{\mscrK }{\mathalpha}{mathematical script capital k}%
+\xUnicodeMathSymbol{"1D4A9}{\mscrN }{\mathalpha}{mathematical script capital n}%
+\xUnicodeMathSymbol{"1D4AA}{\mscrO }{\mathalpha}{mathematical script capital o}%
+\xUnicodeMathSymbol{"1D4AB}{\mscrP }{\mathalpha}{mathematical script capital p}%
+\xUnicodeMathSymbol{"1D4AC}{\mscrQ }{\mathalpha}{mathematical script capital q}%
+\xUnicodeMathSymbol{"1D4AE}{\mscrS }{\mathalpha}{mathematical script capital s}%
+\xUnicodeMathSymbol{"1D4AF}{\mscrT }{\mathalpha}{mathematical script capital t}%
+\xUnicodeMathSymbol{"1D4B0}{\mscrU }{\mathalpha}{mathematical script capital u}%
+\xUnicodeMathSymbol{"1D4B1}{\mscrV }{\mathalpha}{mathematical script capital v}%
+\xUnicodeMathSymbol{"1D4B2}{\mscrW }{\mathalpha}{mathematical script capital w}%
+\xUnicodeMathSymbol{"1D4B3}{\mscrX }{\mathalpha}{mathematical script capital x}%
+\xUnicodeMathSymbol{"1D4B4}{\mscrY }{\mathalpha}{mathematical script capital y}%
+\xUnicodeMathSymbol{"1D4B5}{\mscrZ }{\mathalpha}{mathematical script capital z}%
+\xUnicodeMathSymbol{"1D4B6}{\mscra }{\mathalpha}{mathematical script small a}%
+\xUnicodeMathSymbol{"1D4B7}{\mscrb }{\mathalpha}{mathematical script small b}%
+\xUnicodeMathSymbol{"1D4B8}{\mscrc }{\mathalpha}{mathematical script small c}%
+\xUnicodeMathSymbol{"1D4B9}{\mscrd }{\mathalpha}{mathematical script small d}%
+\xUnicodeMathSymbol{"1D4BB}{\mscrf }{\mathalpha}{mathematical script small f}%
+\xUnicodeMathSymbol{"1D4BD}{\mscrh }{\mathalpha}{mathematical script small h}%
+\xUnicodeMathSymbol{"1D4BE}{\mscri }{\mathalpha}{mathematical script small i}%
+\xUnicodeMathSymbol{"1D4BF}{\mscrj }{\mathalpha}{mathematical script small j}%
+\xUnicodeMathSymbol{"1D4C0}{\mscrk }{\mathalpha}{mathematical script small k}%
+\xUnicodeMathSymbol{"1D4C1}{\mscrl }{\mathalpha}{mathematical script small l}%
+\xUnicodeMathSymbol{"1D4C2}{\mscrm }{\mathalpha}{mathematical script small m}%
+\xUnicodeMathSymbol{"1D4C3}{\mscrn }{\mathalpha}{mathematical script small n}%
+\xUnicodeMathSymbol{"1D4C5}{\mscrp }{\mathalpha}{mathematical script small p}%
+\xUnicodeMathSymbol{"1D4C6}{\mscrq }{\mathalpha}{mathematical script small q}%
+\xUnicodeMathSymbol{"1D4C7}{\mscrr }{\mathalpha}{mathematical script small r}%
+\xUnicodeMathSymbol{"1D4C8}{\mscrs }{\mathalpha}{mathematical script small s}%
+\xUnicodeMathSymbol{"1D4C9}{\mscrt }{\mathalpha}{mathematical script small t}%
+\xUnicodeMathSymbol{"1D4CA}{\mscru }{\mathalpha}{mathematical script small u}%
+\xUnicodeMathSymbol{"1D4CB}{\mscrv }{\mathalpha}{mathematical script small v}%
+\xUnicodeMathSymbol{"1D4CC}{\mscrw }{\mathalpha}{mathematical script small w}%
+\xUnicodeMathSymbol{"1D4CD}{\mscrx }{\mathalpha}{mathematical script small x}%
+\xUnicodeMathSymbol{"1D4CE}{\mscry }{\mathalpha}{mathematical script small y}%
+\xUnicodeMathSymbol{"1D4CF}{\mscrz }{\mathalpha}{mathematical script small z}%
+\xUnicodeMathSymbol{"1D4D0}{\mbfscrA }{\mathalpha}{mathematical bold script capital a}%
+\xUnicodeMathSymbol{"1D4D1}{\mbfscrB }{\mathalpha}{mathematical bold script capital b}%
+\xUnicodeMathSymbol{"1D4D2}{\mbfscrC }{\mathalpha}{mathematical bold script capital c}%
+\xUnicodeMathSymbol{"1D4D3}{\mbfscrD }{\mathalpha}{mathematical bold script capital d}%
+\xUnicodeMathSymbol{"1D4D4}{\mbfscrE }{\mathalpha}{mathematical bold script capital e}%
+\xUnicodeMathSymbol{"1D4D5}{\mbfscrF }{\mathalpha}{mathematical bold script capital f}%
+\xUnicodeMathSymbol{"1D4D6}{\mbfscrG }{\mathalpha}{mathematical bold script capital g}%
+\xUnicodeMathSymbol{"1D4D7}{\mbfscrH }{\mathalpha}{mathematical bold script capital h}%
+\xUnicodeMathSymbol{"1D4D8}{\mbfscrI }{\mathalpha}{mathematical bold script capital i}%
+\xUnicodeMathSymbol{"1D4D9}{\mbfscrJ }{\mathalpha}{mathematical bold script capital j}%
+\xUnicodeMathSymbol{"1D4DA}{\mbfscrK }{\mathalpha}{mathematical bold script capital k}%
+\xUnicodeMathSymbol{"1D4DB}{\mbfscrL }{\mathalpha}{mathematical bold script capital l}%
+\xUnicodeMathSymbol{"1D4DC}{\mbfscrM }{\mathalpha}{mathematical bold script capital m}%
+\xUnicodeMathSymbol{"1D4DD}{\mbfscrN }{\mathalpha}{mathematical bold script capital n}%
+\xUnicodeMathSymbol{"1D4DE}{\mbfscrO }{\mathalpha}{mathematical bold script capital o}%
+\xUnicodeMathSymbol{"1D4DF}{\mbfscrP }{\mathalpha}{mathematical bold script capital p}%
+\xUnicodeMathSymbol{"1D4E0}{\mbfscrQ }{\mathalpha}{mathematical bold script capital q}%
+\xUnicodeMathSymbol{"1D4E1}{\mbfscrR }{\mathalpha}{mathematical bold script capital r}%
+\xUnicodeMathSymbol{"1D4E2}{\mbfscrS }{\mathalpha}{mathematical bold script capital s}%
+\xUnicodeMathSymbol{"1D4E3}{\mbfscrT }{\mathalpha}{mathematical bold script capital t}%
+\xUnicodeMathSymbol{"1D4E4}{\mbfscrU }{\mathalpha}{mathematical bold script capital u}%
+\xUnicodeMathSymbol{"1D4E5}{\mbfscrV }{\mathalpha}{mathematical bold script capital v}%
+\xUnicodeMathSymbol{"1D4E6}{\mbfscrW }{\mathalpha}{mathematical bold script capital w}%
+\xUnicodeMathSymbol{"1D4E7}{\mbfscrX }{\mathalpha}{mathematical bold script capital x}%
+\xUnicodeMathSymbol{"1D4E8}{\mbfscrY }{\mathalpha}{mathematical bold script capital y}%
+\xUnicodeMathSymbol{"1D4E9}{\mbfscrZ }{\mathalpha}{mathematical bold script capital z}%
+\xUnicodeMathSymbol{"1D4EA}{\mbfscra }{\mathalpha}{mathematical bold script small a}%
+\xUnicodeMathSymbol{"1D4EB}{\mbfscrb }{\mathalpha}{mathematical bold script small b}%
+\xUnicodeMathSymbol{"1D4EC}{\mbfscrc }{\mathalpha}{mathematical bold script small c}%
+\xUnicodeMathSymbol{"1D4ED}{\mbfscrd }{\mathalpha}{mathematical bold script small d}%
+\xUnicodeMathSymbol{"1D4EE}{\mbfscre }{\mathalpha}{mathematical bold script small e}%
+\xUnicodeMathSymbol{"1D4EF}{\mbfscrf }{\mathalpha}{mathematical bold script small f}%
+\xUnicodeMathSymbol{"1D4F0}{\mbfscrg }{\mathalpha}{mathematical bold script small g}%
+\xUnicodeMathSymbol{"1D4F1}{\mbfscrh }{\mathalpha}{mathematical bold script small h}%
+\xUnicodeMathSymbol{"1D4F2}{\mbfscri }{\mathalpha}{mathematical bold script small i}%
+\xUnicodeMathSymbol{"1D4F3}{\mbfscrj }{\mathalpha}{mathematical bold script small j}%
+\xUnicodeMathSymbol{"1D4F4}{\mbfscrk }{\mathalpha}{mathematical bold script small k}%
+\xUnicodeMathSymbol{"1D4F5}{\mbfscrl }{\mathalpha}{mathematical bold script small l}%
+\xUnicodeMathSymbol{"1D4F6}{\mbfscrm }{\mathalpha}{mathematical bold script small m}%
+\xUnicodeMathSymbol{"1D4F7}{\mbfscrn }{\mathalpha}{mathematical bold script small n}%
+\xUnicodeMathSymbol{"1D4F8}{\mbfscro }{\mathalpha}{mathematical bold script small o}%
+\xUnicodeMathSymbol{"1D4F9}{\mbfscrp }{\mathalpha}{mathematical bold script small p}%
+\xUnicodeMathSymbol{"1D4FA}{\mbfscrq }{\mathalpha}{mathematical bold script small q}%
+\xUnicodeMathSymbol{"1D4FB}{\mbfscrr }{\mathalpha}{mathematical bold script small r}%
+\xUnicodeMathSymbol{"1D4FC}{\mbfscrs }{\mathalpha}{mathematical bold script small s}%
+\xUnicodeMathSymbol{"1D4FD}{\mbfscrt }{\mathalpha}{mathematical bold script small t}%
+\xUnicodeMathSymbol{"1D4FE}{\mbfscru }{\mathalpha}{mathematical bold script small u}%
+\xUnicodeMathSymbol{"1D4FF}{\mbfscrv }{\mathalpha}{mathematical bold script small v}%
+\xUnicodeMathSymbol{"1D500}{\mbfscrw }{\mathalpha}{mathematical bold script small w}%
+\xUnicodeMathSymbol{"1D501}{\mbfscrx }{\mathalpha}{mathematical bold script small x}%
+\xUnicodeMathSymbol{"1D502}{\mbfscry }{\mathalpha}{mathematical bold script small y}%
+\xUnicodeMathSymbol{"1D503}{\mbfscrz }{\mathalpha}{mathematical bold script small z}%
+\xUnicodeMathSymbol{"1D504}{\mfrakA }{\mathalpha}{mathematical fraktur capital a}%
+\xUnicodeMathSymbol{"1D505}{\mfrakB }{\mathalpha}{mathematical fraktur capital b}%
+\xUnicodeMathSymbol{"1D507}{\mfrakD }{\mathalpha}{mathematical fraktur capital d}%
+\xUnicodeMathSymbol{"1D508}{\mfrakE }{\mathalpha}{mathematical fraktur capital e}%
+\xUnicodeMathSymbol{"1D509}{\mfrakF }{\mathalpha}{mathematical fraktur capital f}%
+\xUnicodeMathSymbol{"1D50A}{\mfrakG }{\mathalpha}{mathematical fraktur capital g}%
+\xUnicodeMathSymbol{"1D50D}{\mfrakJ }{\mathalpha}{mathematical fraktur capital j}%
+\xUnicodeMathSymbol{"1D50E}{\mfrakK }{\mathalpha}{mathematical fraktur capital k}%
+\xUnicodeMathSymbol{"1D50F}{\mfrakL }{\mathalpha}{mathematical fraktur capital l}%
+\xUnicodeMathSymbol{"1D510}{\mfrakM }{\mathalpha}{mathematical fraktur capital m}%
+\xUnicodeMathSymbol{"1D511}{\mfrakN }{\mathalpha}{mathematical fraktur capital n}%
+\xUnicodeMathSymbol{"1D512}{\mfrakO }{\mathalpha}{mathematical fraktur capital o}%
+\xUnicodeMathSymbol{"1D513}{\mfrakP }{\mathalpha}{mathematical fraktur capital p}%
+\xUnicodeMathSymbol{"1D514}{\mfrakQ }{\mathalpha}{mathematical fraktur capital q}%
+\xUnicodeMathSymbol{"1D516}{\mfrakS }{\mathalpha}{mathematical fraktur capital s}%
+\xUnicodeMathSymbol{"1D517}{\mfrakT }{\mathalpha}{mathematical fraktur capital t}%
+\xUnicodeMathSymbol{"1D518}{\mfrakU }{\mathalpha}{mathematical fraktur capital u}%
+\xUnicodeMathSymbol{"1D519}{\mfrakV }{\mathalpha}{mathematical fraktur capital v}%
+\xUnicodeMathSymbol{"1D51A}{\mfrakW }{\mathalpha}{mathematical fraktur capital w}%
+\xUnicodeMathSymbol{"1D51B}{\mfrakX }{\mathalpha}{mathematical fraktur capital x}%
+\xUnicodeMathSymbol{"1D51C}{\mfrakY }{\mathalpha}{mathematical fraktur capital y}%
+\xUnicodeMathSymbol{"1D51E}{\mfraka }{\mathalpha}{mathematical fraktur small a}%
+\xUnicodeMathSymbol{"1D51F}{\mfrakb }{\mathalpha}{mathematical fraktur small b}%
+\xUnicodeMathSymbol{"1D520}{\mfrakc }{\mathalpha}{mathematical fraktur small c}%
+\xUnicodeMathSymbol{"1D521}{\mfrakd }{\mathalpha}{mathematical fraktur small d}%
+\xUnicodeMathSymbol{"1D522}{\mfrake }{\mathalpha}{mathematical fraktur small e}%
+\xUnicodeMathSymbol{"1D523}{\mfrakf }{\mathalpha}{mathematical fraktur small f}%
+\xUnicodeMathSymbol{"1D524}{\mfrakg }{\mathalpha}{mathematical fraktur small g}%
+\xUnicodeMathSymbol{"1D525}{\mfrakh }{\mathalpha}{mathematical fraktur small h}%
+\xUnicodeMathSymbol{"1D526}{\mfraki }{\mathalpha}{mathematical fraktur small i}%
+\xUnicodeMathSymbol{"1D527}{\mfrakj }{\mathalpha}{mathematical fraktur small j}%
+\xUnicodeMathSymbol{"1D528}{\mfrakk }{\mathalpha}{mathematical fraktur small k}%
+\xUnicodeMathSymbol{"1D529}{\mfrakl }{\mathalpha}{mathematical fraktur small l}%
+\xUnicodeMathSymbol{"1D52A}{\mfrakm }{\mathalpha}{mathematical fraktur small m}%
+\xUnicodeMathSymbol{"1D52B}{\mfrakn }{\mathalpha}{mathematical fraktur small n}%
+\xUnicodeMathSymbol{"1D52C}{\mfrako }{\mathalpha}{mathematical fraktur small o}%
+\xUnicodeMathSymbol{"1D52D}{\mfrakp }{\mathalpha}{mathematical fraktur small p}%
+\xUnicodeMathSymbol{"1D52E}{\mfrakq }{\mathalpha}{mathematical fraktur small q}%
+\xUnicodeMathSymbol{"1D52F}{\mfrakr }{\mathalpha}{mathematical fraktur small r}%
+\xUnicodeMathSymbol{"1D530}{\mfraks }{\mathalpha}{mathematical fraktur small s}%
+\xUnicodeMathSymbol{"1D531}{\mfrakt }{\mathalpha}{mathematical fraktur small t}%
+\xUnicodeMathSymbol{"1D532}{\mfraku }{\mathalpha}{mathematical fraktur small u}%
+\xUnicodeMathSymbol{"1D533}{\mfrakv }{\mathalpha}{mathematical fraktur small v}%
+\xUnicodeMathSymbol{"1D534}{\mfrakw }{\mathalpha}{mathematical fraktur small w}%
+\xUnicodeMathSymbol{"1D535}{\mfrakx }{\mathalpha}{mathematical fraktur small x}%
+\xUnicodeMathSymbol{"1D536}{\mfraky }{\mathalpha}{mathematical fraktur small y}%
+\xUnicodeMathSymbol{"1D537}{\mfrakz }{\mathalpha}{mathematical fraktur small z}%
+\xUnicodeMathSymbol{"1D538}{\BbbA }{\mathalpha}{mathematical double-struck capital a}%
+\xUnicodeMathSymbol{"1D539}{\BbbB }{\mathalpha}{mathematical double-struck capital b}%
+\xUnicodeMathSymbol{"1D53B}{\BbbD }{\mathalpha}{mathematical double-struck capital d}%
+\xUnicodeMathSymbol{"1D53C}{\BbbE }{\mathalpha}{mathematical double-struck capital e}%
+\xUnicodeMathSymbol{"1D53D}{\BbbF }{\mathalpha}{mathematical double-struck capital f}%
+\xUnicodeMathSymbol{"1D53E}{\BbbG }{\mathalpha}{mathematical double-struck capital g}%
+\xUnicodeMathSymbol{"1D540}{\BbbI }{\mathalpha}{mathematical double-struck capital i}%
+\xUnicodeMathSymbol{"1D541}{\BbbJ }{\mathalpha}{mathematical double-struck capital j}%
+\xUnicodeMathSymbol{"1D542}{\BbbK }{\mathalpha}{mathematical double-struck capital k}%
+\xUnicodeMathSymbol{"1D543}{\BbbL }{\mathalpha}{mathematical double-struck capital l}%
+\xUnicodeMathSymbol{"1D544}{\BbbM }{\mathalpha}{mathematical double-struck capital m}%
+\xUnicodeMathSymbol{"1D546}{\BbbO }{\mathalpha}{mathematical double-struck capital o}%
+\xUnicodeMathSymbol{"1D54A}{\BbbS }{\mathalpha}{mathematical double-struck capital s}%
+\xUnicodeMathSymbol{"1D54B}{\BbbT }{\mathalpha}{mathematical double-struck capital t}%
+\xUnicodeMathSymbol{"1D54C}{\BbbU }{\mathalpha}{mathematical double-struck capital u}%
+\xUnicodeMathSymbol{"1D54D}{\BbbV }{\mathalpha}{mathematical double-struck capital v}%
+\xUnicodeMathSymbol{"1D54E}{\BbbW }{\mathalpha}{mathematical double-struck capital w}%
+\xUnicodeMathSymbol{"1D54F}{\BbbX }{\mathalpha}{mathematical double-struck capital x}%
+\xUnicodeMathSymbol{"1D550}{\BbbY }{\mathalpha}{mathematical double-struck capital y}%
+\xUnicodeMathSymbol{"1D552}{\Bbba }{\mathalpha}{mathematical double-struck small a}%
+\xUnicodeMathSymbol{"1D553}{\Bbbb }{\mathalpha}{mathematical double-struck small b}%
+\xUnicodeMathSymbol{"1D554}{\Bbbc }{\mathalpha}{mathematical double-struck small c}%
+\xUnicodeMathSymbol{"1D555}{\Bbbd }{\mathalpha}{mathematical double-struck small d}%
+\xUnicodeMathSymbol{"1D556}{\Bbbe }{\mathalpha}{mathematical double-struck small e}%
+\xUnicodeMathSymbol{"1D557}{\Bbbf }{\mathalpha}{mathematical double-struck small f}%
+\xUnicodeMathSymbol{"1D558}{\Bbbg }{\mathalpha}{mathematical double-struck small g}%
+\xUnicodeMathSymbol{"1D559}{\Bbbh }{\mathalpha}{mathematical double-struck small h}%
+\xUnicodeMathSymbol{"1D55A}{\Bbbi }{\mathalpha}{mathematical double-struck small i}%
+\xUnicodeMathSymbol{"1D55B}{\Bbbj }{\mathalpha}{mathematical double-struck small j}%
+\xUnicodeMathSymbol{"1D55C}{\Bbbk }{\mathalpha}{mathematical double-struck small k}%
+\xUnicodeMathSymbol{"1D55D}{\Bbbl }{\mathalpha}{mathematical double-struck small l}%
+\xUnicodeMathSymbol{"1D55E}{\Bbbm }{\mathalpha}{mathematical double-struck small m}%
+\xUnicodeMathSymbol{"1D55F}{\Bbbn }{\mathalpha}{mathematical double-struck small n}%
+\xUnicodeMathSymbol{"1D560}{\Bbbo }{\mathalpha}{mathematical double-struck small o}%
+\xUnicodeMathSymbol{"1D561}{\Bbbp }{\mathalpha}{mathematical double-struck small p}%
+\xUnicodeMathSymbol{"1D562}{\Bbbq }{\mathalpha}{mathematical double-struck small q}%
+\xUnicodeMathSymbol{"1D563}{\Bbbr }{\mathalpha}{mathematical double-struck small r}%
+\xUnicodeMathSymbol{"1D564}{\Bbbs }{\mathalpha}{mathematical double-struck small s}%
+\xUnicodeMathSymbol{"1D565}{\Bbbt }{\mathalpha}{mathematical double-struck small t}%
+\xUnicodeMathSymbol{"1D566}{\Bbbu }{\mathalpha}{mathematical double-struck small u}%
+\xUnicodeMathSymbol{"1D567}{\Bbbv }{\mathalpha}{mathematical double-struck small v}%
+\xUnicodeMathSymbol{"1D568}{\Bbbw }{\mathalpha}{mathematical double-struck small w}%
+\xUnicodeMathSymbol{"1D569}{\Bbbx }{\mathalpha}{mathematical double-struck small x}%
+\xUnicodeMathSymbol{"1D56A}{\Bbby }{\mathalpha}{mathematical double-struck small y}%
+\xUnicodeMathSymbol{"1D56B}{\Bbbz }{\mathalpha}{mathematical double-struck small z}%
+\xUnicodeMathSymbol{"1D56C}{\mbffrakA }{\mathalpha}{mathematical bold fraktur capital a}%
+\xUnicodeMathSymbol{"1D56D}{\mbffrakB }{\mathalpha}{mathematical bold fraktur capital b}%
+\xUnicodeMathSymbol{"1D56E}{\mbffrakC }{\mathalpha}{mathematical bold fraktur capital c}%
+\xUnicodeMathSymbol{"1D56F}{\mbffrakD }{\mathalpha}{mathematical bold fraktur capital d}%
+\xUnicodeMathSymbol{"1D570}{\mbffrakE }{\mathalpha}{mathematical bold fraktur capital e}%
+\xUnicodeMathSymbol{"1D571}{\mbffrakF }{\mathalpha}{mathematical bold fraktur capital f}%
+\xUnicodeMathSymbol{"1D572}{\mbffrakG }{\mathalpha}{mathematical bold fraktur capital g}%
+\xUnicodeMathSymbol{"1D573}{\mbffrakH }{\mathalpha}{mathematical bold fraktur capital h}%
+\xUnicodeMathSymbol{"1D574}{\mbffrakI }{\mathalpha}{mathematical bold fraktur capital i}%
+\xUnicodeMathSymbol{"1D575}{\mbffrakJ }{\mathalpha}{mathematical bold fraktur capital j}%
+\xUnicodeMathSymbol{"1D576}{\mbffrakK }{\mathalpha}{mathematical bold fraktur capital k}%
+\xUnicodeMathSymbol{"1D577}{\mbffrakL }{\mathalpha}{mathematical bold fraktur capital l}%
+\xUnicodeMathSymbol{"1D578}{\mbffrakM }{\mathalpha}{mathematical bold fraktur capital m}%
+\xUnicodeMathSymbol{"1D579}{\mbffrakN }{\mathalpha}{mathematical bold fraktur capital n}%
+\xUnicodeMathSymbol{"1D57A}{\mbffrakO }{\mathalpha}{mathematical bold fraktur capital o}%
+\xUnicodeMathSymbol{"1D57B}{\mbffrakP }{\mathalpha}{mathematical bold fraktur capital p}%
+\xUnicodeMathSymbol{"1D57C}{\mbffrakQ }{\mathalpha}{mathematical bold fraktur capital q}%
+\xUnicodeMathSymbol{"1D57D}{\mbffrakR }{\mathalpha}{mathematical bold fraktur capital r}%
+\xUnicodeMathSymbol{"1D57E}{\mbffrakS }{\mathalpha}{mathematical bold fraktur capital s}%
+\xUnicodeMathSymbol{"1D57F}{\mbffrakT }{\mathalpha}{mathematical bold fraktur capital t}%
+\xUnicodeMathSymbol{"1D580}{\mbffrakU }{\mathalpha}{mathematical bold fraktur capital u}%
+\xUnicodeMathSymbol{"1D581}{\mbffrakV }{\mathalpha}{mathematical bold fraktur capital v}%
+\xUnicodeMathSymbol{"1D582}{\mbffrakW }{\mathalpha}{mathematical bold fraktur capital w}%
+\xUnicodeMathSymbol{"1D583}{\mbffrakX }{\mathalpha}{mathematical bold fraktur capital x}%
+\xUnicodeMathSymbol{"1D584}{\mbffrakY }{\mathalpha}{mathematical bold fraktur capital y}%
+\xUnicodeMathSymbol{"1D585}{\mbffrakZ }{\mathalpha}{mathematical bold fraktur capital z}%
+\xUnicodeMathSymbol{"1D586}{\mbffraka }{\mathalpha}{mathematical bold fraktur small a}%
+\xUnicodeMathSymbol{"1D587}{\mbffrakb }{\mathalpha}{mathematical bold fraktur small b}%
+\xUnicodeMathSymbol{"1D588}{\mbffrakc }{\mathalpha}{mathematical bold fraktur small c}%
+\xUnicodeMathSymbol{"1D589}{\mbffrakd }{\mathalpha}{mathematical bold fraktur small d}%
+\xUnicodeMathSymbol{"1D58A}{\mbffrake }{\mathalpha}{mathematical bold fraktur small e}%
+\xUnicodeMathSymbol{"1D58B}{\mbffrakf }{\mathalpha}{mathematical bold fraktur small f}%
+\xUnicodeMathSymbol{"1D58C}{\mbffrakg }{\mathalpha}{mathematical bold fraktur small g}%
+\xUnicodeMathSymbol{"1D58D}{\mbffrakh }{\mathalpha}{mathematical bold fraktur small h}%
+\xUnicodeMathSymbol{"1D58E}{\mbffraki }{\mathalpha}{mathematical bold fraktur small i}%
+\xUnicodeMathSymbol{"1D58F}{\mbffrakj }{\mathalpha}{mathematical bold fraktur small j}%
+\xUnicodeMathSymbol{"1D590}{\mbffrakk }{\mathalpha}{mathematical bold fraktur small k}%
+\xUnicodeMathSymbol{"1D591}{\mbffrakl }{\mathalpha}{mathematical bold fraktur small l}%
+\xUnicodeMathSymbol{"1D592}{\mbffrakm }{\mathalpha}{mathematical bold fraktur small m}%
+\xUnicodeMathSymbol{"1D593}{\mbffrakn }{\mathalpha}{mathematical bold fraktur small n}%
+\xUnicodeMathSymbol{"1D594}{\mbffrako }{\mathalpha}{mathematical bold fraktur small o}%
+\xUnicodeMathSymbol{"1D595}{\mbffrakp }{\mathalpha}{mathematical bold fraktur small p}%
+\xUnicodeMathSymbol{"1D596}{\mbffrakq }{\mathalpha}{mathematical bold fraktur small q}%
+\xUnicodeMathSymbol{"1D597}{\mbffrakr }{\mathalpha}{mathematical bold fraktur small r}%
+\xUnicodeMathSymbol{"1D598}{\mbffraks }{\mathalpha}{mathematical bold fraktur small s}%
+\xUnicodeMathSymbol{"1D599}{\mbffrakt }{\mathalpha}{mathematical bold fraktur small t}%
+\xUnicodeMathSymbol{"1D59A}{\mbffraku }{\mathalpha}{mathematical bold fraktur small u}%
+\xUnicodeMathSymbol{"1D59B}{\mbffrakv }{\mathalpha}{mathematical bold fraktur small v}%
+\xUnicodeMathSymbol{"1D59C}{\mbffrakw }{\mathalpha}{mathematical bold fraktur small w}%
+\xUnicodeMathSymbol{"1D59D}{\mbffrakx }{\mathalpha}{mathematical bold fraktur small x}%
+\xUnicodeMathSymbol{"1D59E}{\mbffraky }{\mathalpha}{mathematical bold fraktur small y}%
+\xUnicodeMathSymbol{"1D59F}{\mbffrakz }{\mathalpha}{mathematical bold fraktur small z}%
+\xUnicodeMathSymbol{"1D5A0}{\msansA }{\mathalpha}{mathematical sans-serif capital a}%
+\xUnicodeMathSymbol{"1D5A1}{\msansB }{\mathalpha}{mathematical sans-serif capital b}%
+\xUnicodeMathSymbol{"1D5A2}{\msansC }{\mathalpha}{mathematical sans-serif capital c}%
+\xUnicodeMathSymbol{"1D5A3}{\msansD }{\mathalpha}{mathematical sans-serif capital d}%
+\xUnicodeMathSymbol{"1D5A4}{\msansE }{\mathalpha}{mathematical sans-serif capital e}%
+\xUnicodeMathSymbol{"1D5A5}{\msansF }{\mathalpha}{mathematical sans-serif capital f}%
+\xUnicodeMathSymbol{"1D5A6}{\msansG }{\mathalpha}{mathematical sans-serif capital g}%
+\xUnicodeMathSymbol{"1D5A7}{\msansH }{\mathalpha}{mathematical sans-serif capital h}%
+\xUnicodeMathSymbol{"1D5A8}{\msansI }{\mathalpha}{mathematical sans-serif capital i}%
+\xUnicodeMathSymbol{"1D5A9}{\msansJ }{\mathalpha}{mathematical sans-serif capital j}%
+\xUnicodeMathSymbol{"1D5AA}{\msansK }{\mathalpha}{mathematical sans-serif capital k}%
+\xUnicodeMathSymbol{"1D5AB}{\msansL }{\mathalpha}{mathematical sans-serif capital l}%
+\xUnicodeMathSymbol{"1D5AC}{\msansM }{\mathalpha}{mathematical sans-serif capital m}%
+\xUnicodeMathSymbol{"1D5AD}{\msansN }{\mathalpha}{mathematical sans-serif capital n}%
+\xUnicodeMathSymbol{"1D5AE}{\msansO }{\mathalpha}{mathematical sans-serif capital o}%
+\xUnicodeMathSymbol{"1D5AF}{\msansP }{\mathalpha}{mathematical sans-serif capital p}%
+\xUnicodeMathSymbol{"1D5B0}{\msansQ }{\mathalpha}{mathematical sans-serif capital q}%
+\xUnicodeMathSymbol{"1D5B1}{\msansR }{\mathalpha}{mathematical sans-serif capital r}%
+\xUnicodeMathSymbol{"1D5B2}{\msansS }{\mathalpha}{mathematical sans-serif capital s}%
+\xUnicodeMathSymbol{"1D5B3}{\msansT }{\mathalpha}{mathematical sans-serif capital t}%
+\xUnicodeMathSymbol{"1D5B4}{\msansU }{\mathalpha}{mathematical sans-serif capital u}%
+\xUnicodeMathSymbol{"1D5B5}{\msansV }{\mathalpha}{mathematical sans-serif capital v}%
+\xUnicodeMathSymbol{"1D5B6}{\msansW }{\mathalpha}{mathematical sans-serif capital w}%
+\xUnicodeMathSymbol{"1D5B7}{\msansX }{\mathalpha}{mathematical sans-serif capital x}%
+\xUnicodeMathSymbol{"1D5B8}{\msansY }{\mathalpha}{mathematical sans-serif capital y}%
+\xUnicodeMathSymbol{"1D5B9}{\msansZ }{\mathalpha}{mathematical sans-serif capital z}%
+\xUnicodeMathSymbol{"1D5BA}{\msansa }{\mathalpha}{mathematical sans-serif small a}%
+\xUnicodeMathSymbol{"1D5BB}{\msansb }{\mathalpha}{mathematical sans-serif small b}%
+\xUnicodeMathSymbol{"1D5BC}{\msansc }{\mathalpha}{mathematical sans-serif small c}%
+\xUnicodeMathSymbol{"1D5BD}{\msansd }{\mathalpha}{mathematical sans-serif small d}%
+\xUnicodeMathSymbol{"1D5BE}{\msanse }{\mathalpha}{mathematical sans-serif small e}%
+\xUnicodeMathSymbol{"1D5BF}{\msansf }{\mathalpha}{mathematical sans-serif small f}%
+\xUnicodeMathSymbol{"1D5C0}{\msansg }{\mathalpha}{mathematical sans-serif small g}%
+\xUnicodeMathSymbol{"1D5C1}{\msansh }{\mathalpha}{mathematical sans-serif small h}%
+\xUnicodeMathSymbol{"1D5C2}{\msansi }{\mathalpha}{mathematical sans-serif small i}%
+\xUnicodeMathSymbol{"1D5C3}{\msansj }{\mathalpha}{mathematical sans-serif small j}%
+\xUnicodeMathSymbol{"1D5C4}{\msansk }{\mathalpha}{mathematical sans-serif small k}%
+\xUnicodeMathSymbol{"1D5C5}{\msansl }{\mathalpha}{mathematical sans-serif small l}%
+\xUnicodeMathSymbol{"1D5C6}{\msansm }{\mathalpha}{mathematical sans-serif small m}%
+\xUnicodeMathSymbol{"1D5C7}{\msansn }{\mathalpha}{mathematical sans-serif small n}%
+\xUnicodeMathSymbol{"1D5C8}{\msanso }{\mathalpha}{mathematical sans-serif small o}%
+\xUnicodeMathSymbol{"1D5C9}{\msansp }{\mathalpha}{mathematical sans-serif small p}%
+\xUnicodeMathSymbol{"1D5CA}{\msansq }{\mathalpha}{mathematical sans-serif small q}%
+\xUnicodeMathSymbol{"1D5CB}{\msansr }{\mathalpha}{mathematical sans-serif small r}%
+\xUnicodeMathSymbol{"1D5CC}{\msanss }{\mathalpha}{mathematical sans-serif small s}%
+\xUnicodeMathSymbol{"1D5CD}{\msanst }{\mathalpha}{mathematical sans-serif small t}%
+\xUnicodeMathSymbol{"1D5CE}{\msansu }{\mathalpha}{mathematical sans-serif small u}%
+\xUnicodeMathSymbol{"1D5CF}{\msansv }{\mathalpha}{mathematical sans-serif small v}%
+\xUnicodeMathSymbol{"1D5D0}{\msansw }{\mathalpha}{mathematical sans-serif small w}%
+\xUnicodeMathSymbol{"1D5D1}{\msansx }{\mathalpha}{mathematical sans-serif small x}%
+\xUnicodeMathSymbol{"1D5D2}{\msansy }{\mathalpha}{mathematical sans-serif small y}%
+\xUnicodeMathSymbol{"1D5D3}{\msansz }{\mathalpha}{mathematical sans-serif small z}%
+\xUnicodeMathSymbol{"1D5D4}{\mbfsansA }{\mathalpha}{mathematical sans-serif bold capital a}%
+\xUnicodeMathSymbol{"1D5D5}{\mbfsansB }{\mathalpha}{mathematical sans-serif bold capital b}%
+\xUnicodeMathSymbol{"1D5D6}{\mbfsansC }{\mathalpha}{mathematical sans-serif bold capital c}%
+\xUnicodeMathSymbol{"1D5D7}{\mbfsansD }{\mathalpha}{mathematical sans-serif bold capital d}%
+\xUnicodeMathSymbol{"1D5D8}{\mbfsansE }{\mathalpha}{mathematical sans-serif bold capital e}%
+\xUnicodeMathSymbol{"1D5D9}{\mbfsansF }{\mathalpha}{mathematical sans-serif bold capital f}%
+\xUnicodeMathSymbol{"1D5DA}{\mbfsansG }{\mathalpha}{mathematical sans-serif bold capital g}%
+\xUnicodeMathSymbol{"1D5DB}{\mbfsansH }{\mathalpha}{mathematical sans-serif bold capital h}%
+\xUnicodeMathSymbol{"1D5DC}{\mbfsansI }{\mathalpha}{mathematical sans-serif bold capital i}%
+\xUnicodeMathSymbol{"1D5DD}{\mbfsansJ }{\mathalpha}{mathematical sans-serif bold capital j}%
+\xUnicodeMathSymbol{"1D5DE}{\mbfsansK }{\mathalpha}{mathematical sans-serif bold capital k}%
+\xUnicodeMathSymbol{"1D5DF}{\mbfsansL }{\mathalpha}{mathematical sans-serif bold capital l}%
+\xUnicodeMathSymbol{"1D5E0}{\mbfsansM }{\mathalpha}{mathematical sans-serif bold capital m}%
+\xUnicodeMathSymbol{"1D5E1}{\mbfsansN }{\mathalpha}{mathematical sans-serif bold capital n}%
+\xUnicodeMathSymbol{"1D5E2}{\mbfsansO }{\mathalpha}{mathematical sans-serif bold capital o}%
+\xUnicodeMathSymbol{"1D5E3}{\mbfsansP }{\mathalpha}{mathematical sans-serif bold capital p}%
+\xUnicodeMathSymbol{"1D5E4}{\mbfsansQ }{\mathalpha}{mathematical sans-serif bold capital q}%
+\xUnicodeMathSymbol{"1D5E5}{\mbfsansR }{\mathalpha}{mathematical sans-serif bold capital r}%
+\xUnicodeMathSymbol{"1D5E6}{\mbfsansS }{\mathalpha}{mathematical sans-serif bold capital s}%
+\xUnicodeMathSymbol{"1D5E7}{\mbfsansT }{\mathalpha}{mathematical sans-serif bold capital t}%
+\xUnicodeMathSymbol{"1D5E8}{\mbfsansU }{\mathalpha}{mathematical sans-serif bold capital u}%
+\xUnicodeMathSymbol{"1D5E9}{\mbfsansV }{\mathalpha}{mathematical sans-serif bold capital v}%
+\xUnicodeMathSymbol{"1D5EA}{\mbfsansW }{\mathalpha}{mathematical sans-serif bold capital w}%
+\xUnicodeMathSymbol{"1D5EB}{\mbfsansX }{\mathalpha}{mathematical sans-serif bold capital x}%
+\xUnicodeMathSymbol{"1D5EC}{\mbfsansY }{\mathalpha}{mathematical sans-serif bold capital y}%
+\xUnicodeMathSymbol{"1D5ED}{\mbfsansZ }{\mathalpha}{mathematical sans-serif bold capital z}%
+\xUnicodeMathSymbol{"1D5EE}{\mbfsansa }{\mathalpha}{mathematical sans-serif bold small a}%
+\xUnicodeMathSymbol{"1D5EF}{\mbfsansb }{\mathalpha}{mathematical sans-serif bold small b}%
+\xUnicodeMathSymbol{"1D5F0}{\mbfsansc }{\mathalpha}{mathematical sans-serif bold small c}%
+\xUnicodeMathSymbol{"1D5F1}{\mbfsansd }{\mathalpha}{mathematical sans-serif bold small d}%
+\xUnicodeMathSymbol{"1D5F2}{\mbfsanse }{\mathalpha}{mathematical sans-serif bold small e}%
+\xUnicodeMathSymbol{"1D5F3}{\mbfsansf }{\mathalpha}{mathematical sans-serif bold small f}%
+\xUnicodeMathSymbol{"1D5F4}{\mbfsansg }{\mathalpha}{mathematical sans-serif bold small g}%
+\xUnicodeMathSymbol{"1D5F5}{\mbfsansh }{\mathalpha}{mathematical sans-serif bold small h}%
+\xUnicodeMathSymbol{"1D5F6}{\mbfsansi }{\mathalpha}{mathematical sans-serif bold small i}%
+\xUnicodeMathSymbol{"1D5F7}{\mbfsansj }{\mathalpha}{mathematical sans-serif bold small j}%
+\xUnicodeMathSymbol{"1D5F8}{\mbfsansk }{\mathalpha}{mathematical sans-serif bold small k}%
+\xUnicodeMathSymbol{"1D5F9}{\mbfsansl }{\mathalpha}{mathematical sans-serif bold small l}%
+\xUnicodeMathSymbol{"1D5FA}{\mbfsansm }{\mathalpha}{mathematical sans-serif bold small m}%
+\xUnicodeMathSymbol{"1D5FB}{\mbfsansn }{\mathalpha}{mathematical sans-serif bold small n}%
+\xUnicodeMathSymbol{"1D5FC}{\mbfsanso }{\mathalpha}{mathematical sans-serif bold small o}%
+\xUnicodeMathSymbol{"1D5FD}{\mbfsansp }{\mathalpha}{mathematical sans-serif bold small p}%
+\xUnicodeMathSymbol{"1D5FE}{\mbfsansq }{\mathalpha}{mathematical sans-serif bold small q}%
+\xUnicodeMathSymbol{"1D5FF}{\mbfsansr }{\mathalpha}{mathematical sans-serif bold small r}%
+\xUnicodeMathSymbol{"1D600}{\mbfsanss }{\mathalpha}{mathematical sans-serif bold small s}%
+\xUnicodeMathSymbol{"1D601}{\mbfsanst }{\mathalpha}{mathematical sans-serif bold small t}%
+\xUnicodeMathSymbol{"1D602}{\mbfsansu }{\mathalpha}{mathematical sans-serif bold small u}%
+\xUnicodeMathSymbol{"1D603}{\mbfsansv }{\mathalpha}{mathematical sans-serif bold small v}%
+\xUnicodeMathSymbol{"1D604}{\mbfsansw }{\mathalpha}{mathematical sans-serif bold small w}%
+\xUnicodeMathSymbol{"1D605}{\mbfsansx }{\mathalpha}{mathematical sans-serif bold small x}%
+\xUnicodeMathSymbol{"1D606}{\mbfsansy }{\mathalpha}{mathematical sans-serif bold small y}%
+\xUnicodeMathSymbol{"1D607}{\mbfsansz }{\mathalpha}{mathematical sans-serif bold small z}%
+\xUnicodeMathSymbol{"1D608}{\mitsansA }{\mathalpha}{mathematical sans-serif italic capital a}%
+\xUnicodeMathSymbol{"1D609}{\mitsansB }{\mathalpha}{mathematical sans-serif italic capital b}%
+\xUnicodeMathSymbol{"1D60A}{\mitsansC }{\mathalpha}{mathematical sans-serif italic capital c}%
+\xUnicodeMathSymbol{"1D60B}{\mitsansD }{\mathalpha}{mathematical sans-serif italic capital d}%
+\xUnicodeMathSymbol{"1D60C}{\mitsansE }{\mathalpha}{mathematical sans-serif italic capital e}%
+\xUnicodeMathSymbol{"1D60D}{\mitsansF }{\mathalpha}{mathematical sans-serif italic capital f}%
+\xUnicodeMathSymbol{"1D60E}{\mitsansG }{\mathalpha}{mathematical sans-serif italic capital g}%
+\xUnicodeMathSymbol{"1D60F}{\mitsansH }{\mathalpha}{mathematical sans-serif italic capital h}%
+\xUnicodeMathSymbol{"1D610}{\mitsansI }{\mathalpha}{mathematical sans-serif italic capital i}%
+\xUnicodeMathSymbol{"1D611}{\mitsansJ }{\mathalpha}{mathematical sans-serif italic capital j}%
+\xUnicodeMathSymbol{"1D612}{\mitsansK }{\mathalpha}{mathematical sans-serif italic capital k}%
+\xUnicodeMathSymbol{"1D613}{\mitsansL }{\mathalpha}{mathematical sans-serif italic capital l}%
+\xUnicodeMathSymbol{"1D614}{\mitsansM }{\mathalpha}{mathematical sans-serif italic capital m}%
+\xUnicodeMathSymbol{"1D615}{\mitsansN }{\mathalpha}{mathematical sans-serif italic capital n}%
+\xUnicodeMathSymbol{"1D616}{\mitsansO }{\mathalpha}{mathematical sans-serif italic capital o}%
+\xUnicodeMathSymbol{"1D617}{\mitsansP }{\mathalpha}{mathematical sans-serif italic capital p}%
+\xUnicodeMathSymbol{"1D618}{\mitsansQ }{\mathalpha}{mathematical sans-serif italic capital q}%
+\xUnicodeMathSymbol{"1D619}{\mitsansR }{\mathalpha}{mathematical sans-serif italic capital r}%
+\xUnicodeMathSymbol{"1D61A}{\mitsansS }{\mathalpha}{mathematical sans-serif italic capital s}%
+\xUnicodeMathSymbol{"1D61B}{\mitsansT }{\mathalpha}{mathematical sans-serif italic capital t}%
+\xUnicodeMathSymbol{"1D61C}{\mitsansU }{\mathalpha}{mathematical sans-serif italic capital u}%
+\xUnicodeMathSymbol{"1D61D}{\mitsansV }{\mathalpha}{mathematical sans-serif italic capital v}%
+\xUnicodeMathSymbol{"1D61E}{\mitsansW }{\mathalpha}{mathematical sans-serif italic capital w}%
+\xUnicodeMathSymbol{"1D61F}{\mitsansX }{\mathalpha}{mathematical sans-serif italic capital x}%
+\xUnicodeMathSymbol{"1D620}{\mitsansY }{\mathalpha}{mathematical sans-serif italic capital y}%
+\xUnicodeMathSymbol{"1D621}{\mitsansZ }{\mathalpha}{mathematical sans-serif italic capital z}%
+\xUnicodeMathSymbol{"1D622}{\mitsansa }{\mathalpha}{mathematical sans-serif italic small a}%
+\xUnicodeMathSymbol{"1D623}{\mitsansb }{\mathalpha}{mathematical sans-serif italic small b}%
+\xUnicodeMathSymbol{"1D624}{\mitsansc }{\mathalpha}{mathematical sans-serif italic small c}%
+\xUnicodeMathSymbol{"1D625}{\mitsansd }{\mathalpha}{mathematical sans-serif italic small d}%
+\xUnicodeMathSymbol{"1D626}{\mitsanse }{\mathalpha}{mathematical sans-serif italic small e}%
+\xUnicodeMathSymbol{"1D627}{\mitsansf }{\mathalpha}{mathematical sans-serif italic small f}%
+\xUnicodeMathSymbol{"1D628}{\mitsansg }{\mathalpha}{mathematical sans-serif italic small g}%
+\xUnicodeMathSymbol{"1D629}{\mitsansh }{\mathalpha}{mathematical sans-serif italic small h}%
+\xUnicodeMathSymbol{"1D62A}{\mitsansi }{\mathalpha}{mathematical sans-serif italic small i}%
+\xUnicodeMathSymbol{"1D62B}{\mitsansj }{\mathalpha}{mathematical sans-serif italic small j}%
+\xUnicodeMathSymbol{"1D62C}{\mitsansk }{\mathalpha}{mathematical sans-serif italic small k}%
+\xUnicodeMathSymbol{"1D62D}{\mitsansl }{\mathalpha}{mathematical sans-serif italic small l}%
+\xUnicodeMathSymbol{"1D62E}{\mitsansm }{\mathalpha}{mathematical sans-serif italic small m}%
+\xUnicodeMathSymbol{"1D62F}{\mitsansn }{\mathalpha}{mathematical sans-serif italic small n}%
+\xUnicodeMathSymbol{"1D630}{\mitsanso }{\mathalpha}{mathematical sans-serif italic small o}%
+\xUnicodeMathSymbol{"1D631}{\mitsansp }{\mathalpha}{mathematical sans-serif italic small p}%
+\xUnicodeMathSymbol{"1D632}{\mitsansq }{\mathalpha}{mathematical sans-serif italic small q}%
+\xUnicodeMathSymbol{"1D633}{\mitsansr }{\mathalpha}{mathematical sans-serif italic small r}%
+\xUnicodeMathSymbol{"1D634}{\mitsanss }{\mathalpha}{mathematical sans-serif italic small s}%
+\xUnicodeMathSymbol{"1D635}{\mitsanst }{\mathalpha}{mathematical sans-serif italic small t}%
+\xUnicodeMathSymbol{"1D636}{\mitsansu }{\mathalpha}{mathematical sans-serif italic small u}%
+\xUnicodeMathSymbol{"1D637}{\mitsansv }{\mathalpha}{mathematical sans-serif italic small v}%
+\xUnicodeMathSymbol{"1D638}{\mitsansw }{\mathalpha}{mathematical sans-serif italic small w}%
+\xUnicodeMathSymbol{"1D639}{\mitsansx }{\mathalpha}{mathematical sans-serif italic small x}%
+\xUnicodeMathSymbol{"1D63A}{\mitsansy }{\mathalpha}{mathematical sans-serif italic small y}%
+\xUnicodeMathSymbol{"1D63B}{\mitsansz }{\mathalpha}{mathematical sans-serif italic small z}%
+\xUnicodeMathSymbol{"1D63C}{\mbfitsansA }{\mathalpha}{mathematical sans-serif bold italic capital a}%
+\xUnicodeMathSymbol{"1D63D}{\mbfitsansB }{\mathalpha}{mathematical sans-serif bold italic capital b}%
+\xUnicodeMathSymbol{"1D63E}{\mbfitsansC }{\mathalpha}{mathematical sans-serif bold italic capital c}%
+\xUnicodeMathSymbol{"1D63F}{\mbfitsansD }{\mathalpha}{mathematical sans-serif bold italic capital d}%
+\xUnicodeMathSymbol{"1D640}{\mbfitsansE }{\mathalpha}{mathematical sans-serif bold italic capital e}%
+\xUnicodeMathSymbol{"1D641}{\mbfitsansF }{\mathalpha}{mathematical sans-serif bold italic capital f}%
+\xUnicodeMathSymbol{"1D642}{\mbfitsansG }{\mathalpha}{mathematical sans-serif bold italic capital g}%
+\xUnicodeMathSymbol{"1D643}{\mbfitsansH }{\mathalpha}{mathematical sans-serif bold italic capital h}%
+\xUnicodeMathSymbol{"1D644}{\mbfitsansI }{\mathalpha}{mathematical sans-serif bold italic capital i}%
+\xUnicodeMathSymbol{"1D645}{\mbfitsansJ }{\mathalpha}{mathematical sans-serif bold italic capital j}%
+\xUnicodeMathSymbol{"1D646}{\mbfitsansK }{\mathalpha}{mathematical sans-serif bold italic capital k}%
+\xUnicodeMathSymbol{"1D647}{\mbfitsansL }{\mathalpha}{mathematical sans-serif bold italic capital l}%
+\xUnicodeMathSymbol{"1D648}{\mbfitsansM }{\mathalpha}{mathematical sans-serif bold italic capital m}%
+\xUnicodeMathSymbol{"1D649}{\mbfitsansN }{\mathalpha}{mathematical sans-serif bold italic capital n}%
+\xUnicodeMathSymbol{"1D64A}{\mbfitsansO }{\mathalpha}{mathematical sans-serif bold italic capital o}%
+\xUnicodeMathSymbol{"1D64B}{\mbfitsansP }{\mathalpha}{mathematical sans-serif bold italic capital p}%
+\xUnicodeMathSymbol{"1D64C}{\mbfitsansQ }{\mathalpha}{mathematical sans-serif bold italic capital q}%
+\xUnicodeMathSymbol{"1D64D}{\mbfitsansR }{\mathalpha}{mathematical sans-serif bold italic capital r}%
+\xUnicodeMathSymbol{"1D64E}{\mbfitsansS }{\mathalpha}{mathematical sans-serif bold italic capital s}%
+\xUnicodeMathSymbol{"1D64F}{\mbfitsansT }{\mathalpha}{mathematical sans-serif bold italic capital t}%
+\xUnicodeMathSymbol{"1D650}{\mbfitsansU }{\mathalpha}{mathematical sans-serif bold italic capital u}%
+\xUnicodeMathSymbol{"1D651}{\mbfitsansV }{\mathalpha}{mathematical sans-serif bold italic capital v}%
+\xUnicodeMathSymbol{"1D652}{\mbfitsansW }{\mathalpha}{mathematical sans-serif bold italic capital w}%
+\xUnicodeMathSymbol{"1D653}{\mbfitsansX }{\mathalpha}{mathematical sans-serif bold italic capital x}%
+\xUnicodeMathSymbol{"1D654}{\mbfitsansY }{\mathalpha}{mathematical sans-serif bold italic capital y}%
+\xUnicodeMathSymbol{"1D655}{\mbfitsansZ }{\mathalpha}{mathematical sans-serif bold italic capital z}%
+\xUnicodeMathSymbol{"1D656}{\mbfitsansa }{\mathalpha}{mathematical sans-serif bold italic small a}%
+\xUnicodeMathSymbol{"1D657}{\mbfitsansb }{\mathalpha}{mathematical sans-serif bold italic small b}%
+\xUnicodeMathSymbol{"1D658}{\mbfitsansc }{\mathalpha}{mathematical sans-serif bold italic small c}%
+\xUnicodeMathSymbol{"1D659}{\mbfitsansd }{\mathalpha}{mathematical sans-serif bold italic small d}%
+\xUnicodeMathSymbol{"1D65A}{\mbfitsanse }{\mathalpha}{mathematical sans-serif bold italic small e}%
+\xUnicodeMathSymbol{"1D65B}{\mbfitsansf }{\mathalpha}{mathematical sans-serif bold italic small f}%
+\xUnicodeMathSymbol{"1D65C}{\mbfitsansg }{\mathalpha}{mathematical sans-serif bold italic small g}%
+\xUnicodeMathSymbol{"1D65D}{\mbfitsansh }{\mathalpha}{mathematical sans-serif bold italic small h}%
+\xUnicodeMathSymbol{"1D65E}{\mbfitsansi }{\mathalpha}{mathematical sans-serif bold italic small i}%
+\xUnicodeMathSymbol{"1D65F}{\mbfitsansj }{\mathalpha}{mathematical sans-serif bold italic small j}%
+\xUnicodeMathSymbol{"1D660}{\mbfitsansk }{\mathalpha}{mathematical sans-serif bold italic small k}%
+\xUnicodeMathSymbol{"1D661}{\mbfitsansl }{\mathalpha}{mathematical sans-serif bold italic small l}%
+\xUnicodeMathSymbol{"1D662}{\mbfitsansm }{\mathalpha}{mathematical sans-serif bold italic small m}%
+\xUnicodeMathSymbol{"1D663}{\mbfitsansn }{\mathalpha}{mathematical sans-serif bold italic small n}%
+\xUnicodeMathSymbol{"1D664}{\mbfitsanso }{\mathalpha}{mathematical sans-serif bold italic small o}%
+\xUnicodeMathSymbol{"1D665}{\mbfitsansp }{\mathalpha}{mathematical sans-serif bold italic small p}%
+\xUnicodeMathSymbol{"1D666}{\mbfitsansq }{\mathalpha}{mathematical sans-serif bold italic small q}%
+\xUnicodeMathSymbol{"1D667}{\mbfitsansr }{\mathalpha}{mathematical sans-serif bold italic small r}%
+\xUnicodeMathSymbol{"1D668}{\mbfitsanss }{\mathalpha}{mathematical sans-serif bold italic small s}%
+\xUnicodeMathSymbol{"1D669}{\mbfitsanst }{\mathalpha}{mathematical sans-serif bold italic small t}%
+\xUnicodeMathSymbol{"1D66A}{\mbfitsansu }{\mathalpha}{mathematical sans-serif bold italic small u}%
+\xUnicodeMathSymbol{"1D66B}{\mbfitsansv }{\mathalpha}{mathematical sans-serif bold italic small v}%
+\xUnicodeMathSymbol{"1D66C}{\mbfitsansw }{\mathalpha}{mathematical sans-serif bold italic small w}%
+\xUnicodeMathSymbol{"1D66D}{\mbfitsansx }{\mathalpha}{mathematical sans-serif bold italic small x}%
+\xUnicodeMathSymbol{"1D66E}{\mbfitsansy }{\mathalpha}{mathematical sans-serif bold italic small y}%
+\xUnicodeMathSymbol{"1D66F}{\mbfitsansz }{\mathalpha}{mathematical sans-serif bold italic small z}%
+\xUnicodeMathSymbol{"1D670}{\mttA }{\mathalpha}{mathematical monospace capital a}%
+\xUnicodeMathSymbol{"1D671}{\mttB }{\mathalpha}{mathematical monospace capital b}%
+\xUnicodeMathSymbol{"1D672}{\mttC }{\mathalpha}{mathematical monospace capital c}%
+\xUnicodeMathSymbol{"1D673}{\mttD }{\mathalpha}{mathematical monospace capital d}%
+\xUnicodeMathSymbol{"1D674}{\mttE }{\mathalpha}{mathematical monospace capital e}%
+\xUnicodeMathSymbol{"1D675}{\mttF }{\mathalpha}{mathematical monospace capital f}%
+\xUnicodeMathSymbol{"1D676}{\mttG }{\mathalpha}{mathematical monospace capital g}%
+\xUnicodeMathSymbol{"1D677}{\mttH }{\mathalpha}{mathematical monospace capital h}%
+\xUnicodeMathSymbol{"1D678}{\mttI }{\mathalpha}{mathematical monospace capital i}%
+\xUnicodeMathSymbol{"1D679}{\mttJ }{\mathalpha}{mathematical monospace capital j}%
+\xUnicodeMathSymbol{"1D67A}{\mttK }{\mathalpha}{mathematical monospace capital k}%
+\xUnicodeMathSymbol{"1D67B}{\mttL }{\mathalpha}{mathematical monospace capital l}%
+\xUnicodeMathSymbol{"1D67C}{\mttM }{\mathalpha}{mathematical monospace capital m}%
+\xUnicodeMathSymbol{"1D67D}{\mttN }{\mathalpha}{mathematical monospace capital n}%
+\xUnicodeMathSymbol{"1D67E}{\mttO }{\mathalpha}{mathematical monospace capital o}%
+\xUnicodeMathSymbol{"1D67F}{\mttP }{\mathalpha}{mathematical monospace capital p}%
+\xUnicodeMathSymbol{"1D680}{\mttQ }{\mathalpha}{mathematical monospace capital q}%
+\xUnicodeMathSymbol{"1D681}{\mttR }{\mathalpha}{mathematical monospace capital r}%
+\xUnicodeMathSymbol{"1D682}{\mttS }{\mathalpha}{mathematical monospace capital s}%
+\xUnicodeMathSymbol{"1D683}{\mttT }{\mathalpha}{mathematical monospace capital t}%
+\xUnicodeMathSymbol{"1D684}{\mttU }{\mathalpha}{mathematical monospace capital u}%
+\xUnicodeMathSymbol{"1D685}{\mttV }{\mathalpha}{mathematical monospace capital v}%
+\xUnicodeMathSymbol{"1D686}{\mttW }{\mathalpha}{mathematical monospace capital w}%
+\xUnicodeMathSymbol{"1D687}{\mttX }{\mathalpha}{mathematical monospace capital x}%
+\xUnicodeMathSymbol{"1D688}{\mttY }{\mathalpha}{mathematical monospace capital y}%
+\xUnicodeMathSymbol{"1D689}{\mttZ }{\mathalpha}{mathematical monospace capital z}%
+\xUnicodeMathSymbol{"1D68A}{\mtta }{\mathalpha}{mathematical monospace small a}%
+\xUnicodeMathSymbol{"1D68B}{\mttb }{\mathalpha}{mathematical monospace small b}%
+\xUnicodeMathSymbol{"1D68C}{\mttc }{\mathalpha}{mathematical monospace small c}%
+\xUnicodeMathSymbol{"1D68D}{\mttd }{\mathalpha}{mathematical monospace small d}%
+\xUnicodeMathSymbol{"1D68E}{\mtte }{\mathalpha}{mathematical monospace small e}%
+\xUnicodeMathSymbol{"1D68F}{\mttf }{\mathalpha}{mathematical monospace small f}%
+\xUnicodeMathSymbol{"1D690}{\mttg }{\mathalpha}{mathematical monospace small g}%
+\xUnicodeMathSymbol{"1D691}{\mtth }{\mathalpha}{mathematical monospace small h}%
+\xUnicodeMathSymbol{"1D692}{\mtti }{\mathalpha}{mathematical monospace small i}%
+\xUnicodeMathSymbol{"1D693}{\mttj }{\mathalpha}{mathematical monospace small j}%
+\xUnicodeMathSymbol{"1D694}{\mttk }{\mathalpha}{mathematical monospace small k}%
+\xUnicodeMathSymbol{"1D695}{\mttl }{\mathalpha}{mathematical monospace small l}%
+\xUnicodeMathSymbol{"1D696}{\mttm }{\mathalpha}{mathematical monospace small m}%
+\xUnicodeMathSymbol{"1D697}{\mttn }{\mathalpha}{mathematical monospace small n}%
+\xUnicodeMathSymbol{"1D698}{\mtto }{\mathalpha}{mathematical monospace small o}%
+\xUnicodeMathSymbol{"1D699}{\mttp }{\mathalpha}{mathematical monospace small p}%
+\xUnicodeMathSymbol{"1D69A}{\mttq }{\mathalpha}{mathematical monospace small q}%
+\xUnicodeMathSymbol{"1D69B}{\mttr }{\mathalpha}{mathematical monospace small r}%
+\xUnicodeMathSymbol{"1D69C}{\mtts }{\mathalpha}{mathematical monospace small s}%
+\xUnicodeMathSymbol{"1D69D}{\mttt }{\mathalpha}{mathematical monospace small t}%
+\xUnicodeMathSymbol{"1D69E}{\mttu }{\mathalpha}{mathematical monospace small u}%
+\xUnicodeMathSymbol{"1D69F}{\mttv }{\mathalpha}{mathematical monospace small v}%
+\xUnicodeMathSymbol{"1D6A0}{\mttw }{\mathalpha}{mathematical monospace small w}%
+\xUnicodeMathSymbol{"1D6A1}{\mttx }{\mathalpha}{mathematical monospace small x}%
+\xUnicodeMathSymbol{"1D6A2}{\mtty }{\mathalpha}{mathematical monospace small y}%
+\xUnicodeMathSymbol{"1D6A3}{\mttz }{\mathalpha}{mathematical monospace small z}%
+\xUnicodeMathSymbol{"1D6A4}{\imath }{\mathalpha}{mathematical italic small dotless i}%
+\xUnicodeMathSymbol{"1D6A5}{\jmath }{\mathalpha}{mathematical italic small dotless j}%
+\xUnicodeMathSymbol{"1D6A8}{\mbfAlpha }{\mathalpha}{mathematical bold capital alpha}%
+\xUnicodeMathSymbol{"1D6A9}{\mbfBeta }{\mathalpha}{mathematical bold capital beta}%
+\xUnicodeMathSymbol{"1D6AA}{\mbfGamma }{\mathalpha}{mathematical bold capital gamma}%
+\xUnicodeMathSymbol{"1D6AB}{\mbfDelta }{\mathalpha}{mathematical bold capital delta}%
+\xUnicodeMathSymbol{"1D6AC}{\mbfEpsilon }{\mathalpha}{mathematical bold capital epsilon}%
+\xUnicodeMathSymbol{"1D6AD}{\mbfZeta }{\mathalpha}{mathematical bold capital zeta}%
+\xUnicodeMathSymbol{"1D6AE}{\mbfEta }{\mathalpha}{mathematical bold capital eta}%
+\xUnicodeMathSymbol{"1D6AF}{\mbfTheta }{\mathalpha}{mathematical bold capital theta}%
+\xUnicodeMathSymbol{"1D6B0}{\mbfIota }{\mathalpha}{mathematical bold capital iota}%
+\xUnicodeMathSymbol{"1D6B1}{\mbfKappa }{\mathalpha}{mathematical bold capital kappa}%
+\xUnicodeMathSymbol{"1D6B2}{\mbfLambda }{\mathalpha}{mathematical bold capital lambda}%
+\xUnicodeMathSymbol{"1D6B3}{\mbfMu }{\mathalpha}{mathematical bold capital mu}%
+\xUnicodeMathSymbol{"1D6B4}{\mbfNu }{\mathalpha}{mathematical bold capital nu}%
+\xUnicodeMathSymbol{"1D6B5}{\mbfXi }{\mathalpha}{mathematical bold capital xi}%
+\xUnicodeMathSymbol{"1D6B6}{\mbfOmicron }{\mathalpha}{mathematical bold capital omicron}%
+\xUnicodeMathSymbol{"1D6B7}{\mbfPi }{\mathalpha}{mathematical bold capital pi}%
+\xUnicodeMathSymbol{"1D6B8}{\mbfRho }{\mathalpha}{mathematical bold capital rho}%
+\xUnicodeMathSymbol{"1D6B9}{\mbfvarTheta }{\mathalpha}{mathematical bold capital theta symbol}%
+\xUnicodeMathSymbol{"1D6BA}{\mbfSigma }{\mathalpha}{mathematical bold capital sigma}%
+\xUnicodeMathSymbol{"1D6BB}{\mbfTau }{\mathalpha}{mathematical bold capital tau}%
+\xUnicodeMathSymbol{"1D6BC}{\mbfUpsilon }{\mathalpha}{mathematical bold capital upsilon}%
+\xUnicodeMathSymbol{"1D6BD}{\mbfPhi }{\mathalpha}{mathematical bold capital phi}%
+\xUnicodeMathSymbol{"1D6BE}{\mbfChi }{\mathalpha}{mathematical bold capital chi}%
+\xUnicodeMathSymbol{"1D6BF}{\mbfPsi }{\mathalpha}{mathematical bold capital psi}%
+\xUnicodeMathSymbol{"1D6C0}{\mbfOmega }{\mathalpha}{mathematical bold capital omega}%
+\xUnicodeMathSymbol{"1D6C1}{\mbfnabla }{\mathalpha}{mathematical bold nabla}%
+\xUnicodeMathSymbol{"1D6C2}{\mbfalpha }{\mathalpha}{mathematical bold small alpha}%
+\xUnicodeMathSymbol{"1D6C3}{\mbfbeta }{\mathalpha}{mathematical bold small beta}%
+\xUnicodeMathSymbol{"1D6C4}{\mbfgamma }{\mathalpha}{mathematical bold small gamma}%
+\xUnicodeMathSymbol{"1D6C5}{\mbfdelta }{\mathalpha}{mathematical bold small delta}%
+\xUnicodeMathSymbol{"1D6C6}{\mbfepsilon }{\mathalpha}{mathematical bold small epsilon}%
+\xUnicodeMathSymbol{"1D6C7}{\mbfzeta }{\mathalpha}{mathematical bold small zeta}%
+\xUnicodeMathSymbol{"1D6C8}{\mbfeta }{\mathalpha}{mathematical bold small eta}%
+\xUnicodeMathSymbol{"1D6C9}{\mbftheta }{\mathalpha}{mathematical bold small theta}%
+\xUnicodeMathSymbol{"1D6CA}{\mbfiota }{\mathalpha}{mathematical bold small iota}%
+\xUnicodeMathSymbol{"1D6CB}{\mbfkappa }{\mathalpha}{mathematical bold small kappa}%
+\xUnicodeMathSymbol{"1D6CC}{\mbflambda }{\mathalpha}{mathematical bold small lambda}%
+\xUnicodeMathSymbol{"1D6CD}{\mbfmu }{\mathalpha}{mathematical bold small mu}%
+\xUnicodeMathSymbol{"1D6CE}{\mbfnu }{\mathalpha}{mathematical bold small nu}%
+\xUnicodeMathSymbol{"1D6CF}{\mbfxi }{\mathalpha}{mathematical bold small xi}%
+\xUnicodeMathSymbol{"1D6D0}{\mbfomicron }{\mathalpha}{mathematical bold small omicron}%
+\xUnicodeMathSymbol{"1D6D1}{\mbfpi }{\mathalpha}{mathematical bold small pi}%
+\xUnicodeMathSymbol{"1D6D2}{\mbfrho }{\mathalpha}{mathematical bold small rho}%
+\xUnicodeMathSymbol{"1D6D3}{\mbfvarsigma }{\mathalpha}{mathematical bold small final sigma}%
+\xUnicodeMathSymbol{"1D6D4}{\mbfsigma }{\mathalpha}{mathematical bold small sigma}%
+\xUnicodeMathSymbol{"1D6D5}{\mbftau }{\mathalpha}{mathematical bold small tau}%
+\xUnicodeMathSymbol{"1D6D6}{\mbfupsilon }{\mathalpha}{mathematical bold small upsilon}%
+\xUnicodeMathSymbol{"1D6D7}{\mbfvarphi }{\mathalpha}{mathematical bold small phi}%
+\xUnicodeMathSymbol{"1D6D8}{\mbfchi }{\mathalpha}{mathematical bold small chi}%
+\xUnicodeMathSymbol{"1D6D9}{\mbfpsi }{\mathalpha}{mathematical bold small psi}%
+\xUnicodeMathSymbol{"1D6DA}{\mbfomega }{\mathalpha}{mathematical bold small omega}%
+\xUnicodeMathSymbol{"1D6DB}{\mbfpartial }{\mathalpha}{mathematical bold partial differential}%
+\xUnicodeMathSymbol{"1D6DC}{\mbfvarepsilon }{\mathalpha}{mathematical bold epsilon symbol}%
+\xUnicodeMathSymbol{"1D6DD}{\mbfvartheta }{\mathalpha}{mathematical bold theta symbol}%
+\xUnicodeMathSymbol{"1D6DE}{\mbfvarkappa }{\mathalpha}{mathematical bold kappa symbol}%
+\xUnicodeMathSymbol{"1D6DF}{\mbfphi }{\mathalpha}{mathematical bold phi symbol}%
+\xUnicodeMathSymbol{"1D6E0}{\mbfvarrho }{\mathalpha}{mathematical bold rho symbol}%
+\xUnicodeMathSymbol{"1D6E1}{\mbfvarpi }{\mathalpha}{mathematical bold pi symbol}%
+\xUnicodeMathSymbol{"1D6E2}{\mitAlpha }{\mathalpha}{mathematical italic capital alpha}%
+\xUnicodeMathSymbol{"1D6E3}{\mitBeta }{\mathalpha}{mathematical italic capital beta}%
+\xUnicodeMathSymbol{"1D6E4}{\mitGamma }{\mathalpha}{mathematical italic capital gamma}%
+\xUnicodeMathSymbol{"1D6E5}{\mitDelta }{\mathalpha}{mathematical italic capital delta}%
+\xUnicodeMathSymbol{"1D6E6}{\mitEpsilon }{\mathalpha}{mathematical italic capital epsilon}%
+\xUnicodeMathSymbol{"1D6E7}{\mitZeta }{\mathalpha}{mathematical italic capital zeta}%
+\xUnicodeMathSymbol{"1D6E8}{\mitEta }{\mathalpha}{mathematical italic capital eta}%
+\xUnicodeMathSymbol{"1D6E9}{\mitTheta }{\mathalpha}{mathematical italic capital theta}%
+\xUnicodeMathSymbol{"1D6EA}{\mitIota }{\mathalpha}{mathematical italic capital iota}%
+\xUnicodeMathSymbol{"1D6EB}{\mitKappa }{\mathalpha}{mathematical italic capital kappa}%
+\xUnicodeMathSymbol{"1D6EC}{\mitLambda }{\mathalpha}{mathematical italic capital lambda}%
+\xUnicodeMathSymbol{"1D6ED}{\mitMu }{\mathalpha}{mathematical italic capital mu}%
+\xUnicodeMathSymbol{"1D6EE}{\mitNu }{\mathalpha}{mathematical italic capital nu}%
+\xUnicodeMathSymbol{"1D6EF}{\mitXi }{\mathalpha}{mathematical italic capital xi}%
+\xUnicodeMathSymbol{"1D6F0}{\mitOmicron }{\mathalpha}{mathematical italic capital omicron}%
+\xUnicodeMathSymbol{"1D6F1}{\mitPi }{\mathalpha}{mathematical italic capital pi}%
+\xUnicodeMathSymbol{"1D6F2}{\mitRho }{\mathalpha}{mathematical italic capital rho}%
+\xUnicodeMathSymbol{"1D6F3}{\mitvarTheta }{\mathalpha}{mathematical italic capital theta symbol}%
+\xUnicodeMathSymbol{"1D6F4}{\mitSigma }{\mathalpha}{mathematical italic capital sigma}%
+\xUnicodeMathSymbol{"1D6F5}{\mitTau }{\mathalpha}{mathematical italic capital tau}%
+\xUnicodeMathSymbol{"1D6F6}{\mitUpsilon }{\mathalpha}{mathematical italic capital upsilon}%
+\xUnicodeMathSymbol{"1D6F7}{\mitPhi }{\mathalpha}{mathematical italic capital phi}%
+\xUnicodeMathSymbol{"1D6F8}{\mitChi }{\mathalpha}{mathematical italic capital chi}%
+\xUnicodeMathSymbol{"1D6F9}{\mitPsi }{\mathalpha}{mathematical italic capital psi}%
+\xUnicodeMathSymbol{"1D6FA}{\mitOmega }{\mathalpha}{mathematical italic capital omega}%
+\xUnicodeMathSymbol{"1D6FB}{\mitnabla }{\mathalpha}{mathematical italic nabla}%
+\xUnicodeMathSymbol{"1D6FC}{\mitalpha }{\mathalpha}{mathematical italic small alpha}%
+\xUnicodeMathSymbol{"1D6FD}{\mitbeta }{\mathalpha}{mathematical italic small beta}%
+\xUnicodeMathSymbol{"1D6FE}{\mitgamma }{\mathalpha}{mathematical italic small gamma}%
+\xUnicodeMathSymbol{"1D6FF}{\mitdelta }{\mathalpha}{mathematical italic small delta}%
+\xUnicodeMathSymbol{"1D700}{\mitepsilon }{\mathalpha}{mathematical italic small epsilon}%
+\xUnicodeMathSymbol{"1D701}{\mitzeta }{\mathalpha}{mathematical italic small zeta}%
+\xUnicodeMathSymbol{"1D702}{\miteta }{\mathalpha}{mathematical italic small eta}%
+\xUnicodeMathSymbol{"1D703}{\mittheta }{\mathalpha}{mathematical italic small theta}%
+\xUnicodeMathSymbol{"1D704}{\mitiota }{\mathalpha}{mathematical italic small iota}%
+\xUnicodeMathSymbol{"1D705}{\mitkappa }{\mathalpha}{mathematical italic small kappa}%
+\xUnicodeMathSymbol{"1D706}{\mitlambda }{\mathalpha}{mathematical italic small lambda}%
+\xUnicodeMathSymbol{"1D707}{\mitmu }{\mathalpha}{mathematical italic small mu}%
+\xUnicodeMathSymbol{"1D708}{\mitnu }{\mathalpha}{mathematical italic small nu}%
+\xUnicodeMathSymbol{"1D709}{\mitxi }{\mathalpha}{mathematical italic small xi}%
+\xUnicodeMathSymbol{"1D70A}{\mitomicron }{\mathalpha}{mathematical italic small omicron}%
+\xUnicodeMathSymbol{"1D70B}{\mitpi }{\mathalpha}{mathematical italic small pi}%
+\xUnicodeMathSymbol{"1D70C}{\mitrho }{\mathalpha}{mathematical italic small rho}%
+\xUnicodeMathSymbol{"1D70D}{\mitvarsigma }{\mathalpha}{mathematical italic small final sigma}%
+\xUnicodeMathSymbol{"1D70E}{\mitsigma }{\mathalpha}{mathematical italic small sigma}%
+\xUnicodeMathSymbol{"1D70F}{\mittau }{\mathalpha}{mathematical italic small tau}%
+\xUnicodeMathSymbol{"1D710}{\mitupsilon }{\mathalpha}{mathematical italic small upsilon}%
+\xUnicodeMathSymbol{"1D711}{\mitphi }{\mathalpha}{mathematical italic small phi}%
+\xUnicodeMathSymbol{"1D712}{\mitchi }{\mathalpha}{mathematical italic small chi}%
+\xUnicodeMathSymbol{"1D713}{\mitpsi }{\mathalpha}{mathematical italic small psi}%
+\xUnicodeMathSymbol{"1D714}{\mitomega }{\mathalpha}{mathematical italic small omega}%
+\xUnicodeMathSymbol{"1D715}{\mitpartial }{\mathalpha}{mathematical italic partial differential}%
+\xUnicodeMathSymbol{"1D716}{\mitvarepsilon }{\mathalpha}{mathematical italic epsilon symbol}%
+\xUnicodeMathSymbol{"1D717}{\mitvartheta }{\mathalpha}{mathematical italic theta symbol}%
+\xUnicodeMathSymbol{"1D718}{\mitvarkappa }{\mathalpha}{mathematical italic kappa symbol}%
+\xUnicodeMathSymbol{"1D719}{\mitvarphi }{\mathalpha}{mathematical italic phi symbol}%
+\xUnicodeMathSymbol{"1D71A}{\mitvarrho }{\mathalpha}{mathematical italic rho symbol}%
+\xUnicodeMathSymbol{"1D71B}{\mitvarpi }{\mathalpha}{mathematical italic pi symbol}%
+\xUnicodeMathSymbol{"1D71C}{\mbfitAlpha }{\mathalpha}{mathematical bold italic capital alpha}%
+\xUnicodeMathSymbol{"1D71D}{\mbfitBeta }{\mathalpha}{mathematical bold italic capital beta}%
+\xUnicodeMathSymbol{"1D71E}{\mbfitGamma }{\mathalpha}{mathematical bold italic capital gamma}%
+\xUnicodeMathSymbol{"1D71F}{\mbfitDelta }{\mathalpha}{mathematical bold italic capital delta}%
+\xUnicodeMathSymbol{"1D720}{\mbfitEpsilon }{\mathalpha}{mathematical bold italic capital epsilon}%
+\xUnicodeMathSymbol{"1D721}{\mbfitZeta }{\mathalpha}{mathematical bold italic capital zeta}%
+\xUnicodeMathSymbol{"1D722}{\mbfitEta }{\mathalpha}{mathematical bold italic capital eta}%
+\xUnicodeMathSymbol{"1D723}{\mbfitTheta }{\mathalpha}{mathematical bold italic capital theta}%
+\xUnicodeMathSymbol{"1D724}{\mbfitIota }{\mathalpha}{mathematical bold italic capital iota}%
+\xUnicodeMathSymbol{"1D725}{\mbfitKappa }{\mathalpha}{mathematical bold italic capital kappa}%
+\xUnicodeMathSymbol{"1D726}{\mbfitLambda }{\mathalpha}{mathematical bold italic capital lambda}%
+\xUnicodeMathSymbol{"1D727}{\mbfitMu }{\mathalpha}{mathematical bold italic capital mu}%
+\xUnicodeMathSymbol{"1D728}{\mbfitNu }{\mathalpha}{mathematical bold italic capital nu}%
+\xUnicodeMathSymbol{"1D729}{\mbfitXi }{\mathalpha}{mathematical bold italic capital xi}%
+\xUnicodeMathSymbol{"1D72A}{\mbfitOmicron }{\mathalpha}{mathematical bold italic capital omicron}%
+\xUnicodeMathSymbol{"1D72B}{\mbfitPi }{\mathalpha}{mathematical bold italic capital pi}%
+\xUnicodeMathSymbol{"1D72C}{\mbfitRho }{\mathalpha}{mathematical bold italic capital rho}%
+\xUnicodeMathSymbol{"1D72D}{\mbfitvarTheta }{\mathalpha}{mathematical bold italic capital theta symbol}%
+\xUnicodeMathSymbol{"1D72E}{\mbfitSigma }{\mathalpha}{mathematical bold italic capital sigma}%
+\xUnicodeMathSymbol{"1D72F}{\mbfitTau }{\mathalpha}{mathematical bold italic capital tau}%
+\xUnicodeMathSymbol{"1D730}{\mbfitUpsilon }{\mathalpha}{mathematical bold italic capital upsilon}%
+\xUnicodeMathSymbol{"1D731}{\mbfitPhi }{\mathalpha}{mathematical bold italic capital phi}%
+\xUnicodeMathSymbol{"1D732}{\mbfitChi }{\mathalpha}{mathematical bold italic capital chi}%
+\xUnicodeMathSymbol{"1D733}{\mbfitPsi }{\mathalpha}{mathematical bold italic capital psi}%
+\xUnicodeMathSymbol{"1D734}{\mbfitOmega }{\mathalpha}{mathematical bold italic capital omega}%
+\xUnicodeMathSymbol{"1D735}{\mbfitnabla }{\mathalpha}{mathematical bold italic nabla}%
+\xUnicodeMathSymbol{"1D736}{\mbfitalpha }{\mathalpha}{mathematical bold italic small alpha}%
+\xUnicodeMathSymbol{"1D737}{\mbfitbeta }{\mathalpha}{mathematical bold italic small beta}%
+\xUnicodeMathSymbol{"1D738}{\mbfitgamma }{\mathalpha}{mathematical bold italic small gamma}%
+\xUnicodeMathSymbol{"1D739}{\mbfitdelta }{\mathalpha}{mathematical bold italic small delta}%
+\xUnicodeMathSymbol{"1D73A}{\mbfitepsilon }{\mathalpha}{mathematical bold italic small epsilon}%
+\xUnicodeMathSymbol{"1D73B}{\mbfitzeta }{\mathalpha}{mathematical bold italic small zeta}%
+\xUnicodeMathSymbol{"1D73C}{\mbfiteta }{\mathalpha}{mathematical bold italic small eta}%
+\xUnicodeMathSymbol{"1D73D}{\mbfittheta }{\mathalpha}{mathematical bold italic small theta}%
+\xUnicodeMathSymbol{"1D73E}{\mbfitiota }{\mathalpha}{mathematical bold italic small iota}%
+\xUnicodeMathSymbol{"1D73F}{\mbfitkappa }{\mathalpha}{mathematical bold italic small kappa}%
+\xUnicodeMathSymbol{"1D740}{\mbfitlambda }{\mathalpha}{mathematical bold italic small lambda}%
+\xUnicodeMathSymbol{"1D741}{\mbfitmu }{\mathalpha}{mathematical bold italic small mu}%
+\xUnicodeMathSymbol{"1D742}{\mbfitnu }{\mathalpha}{mathematical bold italic small nu}%
+\xUnicodeMathSymbol{"1D743}{\mbfitxi }{\mathalpha}{mathematical bold italic small xi}%
+\xUnicodeMathSymbol{"1D744}{\mbfitomicron }{\mathalpha}{mathematical bold italic small omicron}%
+\xUnicodeMathSymbol{"1D745}{\mbfitpi }{\mathalpha}{mathematical bold italic small pi}%
+\xUnicodeMathSymbol{"1D746}{\mbfitrho }{\mathalpha}{mathematical bold italic small rho}%
+\xUnicodeMathSymbol{"1D747}{\mbfitvarsigma }{\mathalpha}{mathematical bold italic small final sigma}%
+\xUnicodeMathSymbol{"1D748}{\mbfitsigma }{\mathalpha}{mathematical bold italic small sigma}%
+\xUnicodeMathSymbol{"1D749}{\mbfittau }{\mathalpha}{mathematical bold italic small tau}%
+\xUnicodeMathSymbol{"1D74A}{\mbfitupsilon }{\mathalpha}{mathematical bold italic small upsilon}%
+\xUnicodeMathSymbol{"1D74B}{\mbfitphi }{\mathalpha}{mathematical bold italic small phi}%
+\xUnicodeMathSymbol{"1D74C}{\mbfitchi }{\mathalpha}{mathematical bold italic small chi}%
+\xUnicodeMathSymbol{"1D74D}{\mbfitpsi }{\mathalpha}{mathematical bold italic small psi}%
+\xUnicodeMathSymbol{"1D74E}{\mbfitomega }{\mathalpha}{mathematical bold italic small omega}%
+\xUnicodeMathSymbol{"1D74F}{\mbfitpartial }{\mathalpha}{mathematical bold italic partial differential}%
+\xUnicodeMathSymbol{"1D750}{\mbfitvarepsilon }{\mathalpha}{mathematical bold italic epsilon symbol}%
+\xUnicodeMathSymbol{"1D751}{\mbfitvartheta }{\mathalpha}{mathematical bold italic theta symbol}%
+\xUnicodeMathSymbol{"1D752}{\mbfitvarkappa }{\mathalpha}{mathematical bold italic kappa symbol}%
+\xUnicodeMathSymbol{"1D753}{\mbfitvarphi }{\mathalpha}{mathematical bold italic phi symbol}%
+\xUnicodeMathSymbol{"1D754}{\mbfitvarrho }{\mathalpha}{mathematical bold italic rho symbol}%
+\xUnicodeMathSymbol{"1D755}{\mbfitvarpi }{\mathalpha}{mathematical bold italic pi symbol}%
+\xUnicodeMathSymbol{"1D756}{\mbfsansAlpha }{\mathalpha}{mathematical sans-serif bold capital alpha}%
+\xUnicodeMathSymbol{"1D757}{\mbfsansBeta }{\mathalpha}{mathematical sans-serif bold capital beta}%
+\xUnicodeMathSymbol{"1D758}{\mbfsansGamma }{\mathalpha}{mathematical sans-serif bold capital gamma}%
+\xUnicodeMathSymbol{"1D759}{\mbfsansDelta }{\mathalpha}{mathematical sans-serif bold capital delta}%
+\xUnicodeMathSymbol{"1D75A}{\mbfsansEpsilon }{\mathalpha}{mathematical sans-serif bold capital epsilon}%
+\xUnicodeMathSymbol{"1D75B}{\mbfsansZeta }{\mathalpha}{mathematical sans-serif bold capital zeta}%
+\xUnicodeMathSymbol{"1D75C}{\mbfsansEta }{\mathalpha}{mathematical sans-serif bold capital eta}%
+\xUnicodeMathSymbol{"1D75D}{\mbfsansTheta }{\mathalpha}{mathematical sans-serif bold capital theta}%
+\xUnicodeMathSymbol{"1D75E}{\mbfsansIota }{\mathalpha}{mathematical sans-serif bold capital iota}%
+\xUnicodeMathSymbol{"1D75F}{\mbfsansKappa }{\mathalpha}{mathematical sans-serif bold capital kappa}%
+\xUnicodeMathSymbol{"1D760}{\mbfsansLambda }{\mathalpha}{mathematical sans-serif bold capital lambda}%
+\xUnicodeMathSymbol{"1D761}{\mbfsansMu }{\mathalpha}{mathematical sans-serif bold capital mu}%
+\xUnicodeMathSymbol{"1D762}{\mbfsansNu }{\mathalpha}{mathematical sans-serif bold capital nu}%
+\xUnicodeMathSymbol{"1D763}{\mbfsansXi }{\mathalpha}{mathematical sans-serif bold capital xi}%
+\xUnicodeMathSymbol{"1D764}{\mbfsansOmicron }{\mathalpha}{mathematical sans-serif bold capital omicron}%
+\xUnicodeMathSymbol{"1D765}{\mbfsansPi }{\mathalpha}{mathematical sans-serif bold capital pi}%
+\xUnicodeMathSymbol{"1D766}{\mbfsansRho }{\mathalpha}{mathematical sans-serif bold capital rho}%
+\xUnicodeMathSymbol{"1D767}{\mbfsansvarTheta }{\mathalpha}{mathematical sans-serif bold capital theta symbol}%
+\xUnicodeMathSymbol{"1D768}{\mbfsansSigma }{\mathalpha}{mathematical sans-serif bold capital sigma}%
+\xUnicodeMathSymbol{"1D769}{\mbfsansTau }{\mathalpha}{mathematical sans-serif bold capital tau}%
+\xUnicodeMathSymbol{"1D76A}{\mbfsansUpsilon }{\mathalpha}{mathematical sans-serif bold capital upsilon}%
+\xUnicodeMathSymbol{"1D76B}{\mbfsansPhi }{\mathalpha}{mathematical sans-serif bold capital phi}%
+\xUnicodeMathSymbol{"1D76C}{\mbfsansChi }{\mathalpha}{mathematical sans-serif bold capital chi}%
+\xUnicodeMathSymbol{"1D76D}{\mbfsansPsi }{\mathalpha}{mathematical sans-serif bold capital psi}%
+\xUnicodeMathSymbol{"1D76E}{\mbfsansOmega }{\mathalpha}{mathematical sans-serif bold capital omega}%
+\xUnicodeMathSymbol{"1D76F}{\mbfsansnabla }{\mathalpha}{mathematical sans-serif bold nabla}%
+\xUnicodeMathSymbol{"1D770}{\mbfsansalpha }{\mathalpha}{mathematical sans-serif bold small alpha}%
+\xUnicodeMathSymbol{"1D771}{\mbfsansbeta }{\mathalpha}{mathematical sans-serif bold small beta}%
+\xUnicodeMathSymbol{"1D772}{\mbfsansgamma }{\mathalpha}{mathematical sans-serif bold small gamma}%
+\xUnicodeMathSymbol{"1D773}{\mbfsansdelta }{\mathalpha}{mathematical sans-serif bold small delta}%
+\xUnicodeMathSymbol{"1D774}{\mbfsansepsilon }{\mathalpha}{mathematical sans-serif bold small epsilon}%
+\xUnicodeMathSymbol{"1D775}{\mbfsanszeta }{\mathalpha}{mathematical sans-serif bold small zeta}%
+\xUnicodeMathSymbol{"1D776}{\mbfsanseta }{\mathalpha}{mathematical sans-serif bold small eta}%
+\xUnicodeMathSymbol{"1D777}{\mbfsanstheta }{\mathalpha}{mathematical sans-serif bold small theta}%
+\xUnicodeMathSymbol{"1D778}{\mbfsansiota }{\mathalpha}{mathematical sans-serif bold small iota}%
+\xUnicodeMathSymbol{"1D779}{\mbfsanskappa }{\mathalpha}{mathematical sans-serif bold small kappa}%
+\xUnicodeMathSymbol{"1D77A}{\mbfsanslambda }{\mathalpha}{mathematical sans-serif bold small lambda}%
+\xUnicodeMathSymbol{"1D77B}{\mbfsansmu }{\mathalpha}{mathematical sans-serif bold small mu}%
+\xUnicodeMathSymbol{"1D77C}{\mbfsansnu }{\mathalpha}{mathematical sans-serif bold small nu}%
+\xUnicodeMathSymbol{"1D77D}{\mbfsansxi }{\mathalpha}{mathematical sans-serif bold small xi}%
+\xUnicodeMathSymbol{"1D77E}{\mbfsansomicron }{\mathalpha}{mathematical sans-serif bold small omicron}%
+\xUnicodeMathSymbol{"1D77F}{\mbfsanspi }{\mathalpha}{mathematical sans-serif bold small pi}%
+\xUnicodeMathSymbol{"1D780}{\mbfsansrho }{\mathalpha}{mathematical sans-serif bold small rho}%
+\xUnicodeMathSymbol{"1D781}{\mbfsansvarsigma }{\mathalpha}{mathematical sans-serif bold small final sigma}%
+\xUnicodeMathSymbol{"1D782}{\mbfsanssigma }{\mathalpha}{mathematical sans-serif bold small sigma}%
+\xUnicodeMathSymbol{"1D783}{\mbfsanstau }{\mathalpha}{mathematical sans-serif bold small tau}%
+\xUnicodeMathSymbol{"1D784}{\mbfsansupsilon }{\mathalpha}{mathematical sans-serif bold small upsilon}%
+\xUnicodeMathSymbol{"1D785}{\mbfsansphi }{\mathalpha}{mathematical sans-serif bold small phi}%
+\xUnicodeMathSymbol{"1D786}{\mbfsanschi }{\mathalpha}{mathematical sans-serif bold small chi}%
+\xUnicodeMathSymbol{"1D787}{\mbfsanspsi }{\mathalpha}{mathematical sans-serif bold small psi}%
+\xUnicodeMathSymbol{"1D788}{\mbfsansomega }{\mathalpha}{mathematical sans-serif bold small omega}%
+\xUnicodeMathSymbol{"1D789}{\mbfsanspartial }{\mathalpha}{mathematical sans-serif bold partial differential}%
+\xUnicodeMathSymbol{"1D78A}{\mbfsansvarepsilon }{\mathalpha}{mathematical sans-serif bold epsilon symbol}%
+\xUnicodeMathSymbol{"1D78B}{\mbfsansvartheta }{\mathalpha}{mathematical sans-serif bold theta symbol}%
+\xUnicodeMathSymbol{"1D78C}{\mbfsansvarkappa }{\mathalpha}{mathematical sans-serif bold kappa symbol}%
+\xUnicodeMathSymbol{"1D78D}{\mbfsansvarphi }{\mathalpha}{mathematical sans-serif bold phi symbol}%
+\xUnicodeMathSymbol{"1D78E}{\mbfsansvarrho }{\mathalpha}{mathematical sans-serif bold rho symbol}%
+\xUnicodeMathSymbol{"1D78F}{\mbfsansvarpi }{\mathalpha}{mathematical sans-serif bold pi symbol}%
+\xUnicodeMathSymbol{"1D790}{\mbfitsansAlpha }{\mathalpha}{mathematical sans-serif bold italic capital alpha}%
+\xUnicodeMathSymbol{"1D791}{\mbfitsansBeta }{\mathalpha}{mathematical sans-serif bold italic capital beta}%
+\xUnicodeMathSymbol{"1D792}{\mbfitsansGamma }{\mathalpha}{mathematical sans-serif bold italic capital gamma}%
+\xUnicodeMathSymbol{"1D793}{\mbfitsansDelta }{\mathalpha}{mathematical sans-serif bold italic capital delta}%
+\xUnicodeMathSymbol{"1D794}{\mbfitsansEpsilon }{\mathalpha}{mathematical sans-serif bold italic capital epsilon}%
+\xUnicodeMathSymbol{"1D795}{\mbfitsansZeta }{\mathalpha}{mathematical sans-serif bold italic capital zeta}%
+\xUnicodeMathSymbol{"1D796}{\mbfitsansEta }{\mathalpha}{mathematical sans-serif bold italic capital eta}%
+\xUnicodeMathSymbol{"1D797}{\mbfitsansTheta }{\mathalpha}{mathematical sans-serif bold italic capital theta}%
+\xUnicodeMathSymbol{"1D798}{\mbfitsansIota }{\mathalpha}{mathematical sans-serif bold italic capital iota}%
+\xUnicodeMathSymbol{"1D799}{\mbfitsansKappa }{\mathalpha}{mathematical sans-serif bold italic capital kappa}%
+\xUnicodeMathSymbol{"1D79A}{\mbfitsansLambda }{\mathalpha}{mathematical sans-serif bold italic capital lambda}%
+\xUnicodeMathSymbol{"1D79B}{\mbfitsansMu }{\mathalpha}{mathematical sans-serif bold italic capital mu}%
+\xUnicodeMathSymbol{"1D79C}{\mbfitsansNu }{\mathalpha}{mathematical sans-serif bold italic capital nu}%
+\xUnicodeMathSymbol{"1D79D}{\mbfitsansXi }{\mathalpha}{mathematical sans-serif bold italic capital xi}%
+\xUnicodeMathSymbol{"1D79E}{\mbfitsansOmicron }{\mathalpha}{mathematical sans-serif bold italic capital omicron}%
+\xUnicodeMathSymbol{"1D79F}{\mbfitsansPi }{\mathalpha}{mathematical sans-serif bold italic capital pi}%
+\xUnicodeMathSymbol{"1D7A0}{\mbfitsansRho }{\mathalpha}{mathematical sans-serif bold italic capital rho}%
+\xUnicodeMathSymbol{"1D7A1}{\mbfitsansvarTheta }{\mathalpha}{mathematical sans-serif bold italic capital theta symbol}%
+\xUnicodeMathSymbol{"1D7A2}{\mbfitsansSigma }{\mathalpha}{mathematical sans-serif bold italic capital sigma}%
+\xUnicodeMathSymbol{"1D7A3}{\mbfitsansTau }{\mathalpha}{mathematical sans-serif bold italic capital tau}%
+\xUnicodeMathSymbol{"1D7A4}{\mbfitsansUpsilon }{\mathalpha}{mathematical sans-serif bold italic capital upsilon}%
+\xUnicodeMathSymbol{"1D7A5}{\mbfitsansPhi }{\mathalpha}{mathematical sans-serif bold italic capital phi}%
+\xUnicodeMathSymbol{"1D7A6}{\mbfitsansChi }{\mathalpha}{mathematical sans-serif bold italic capital chi}%
+\xUnicodeMathSymbol{"1D7A7}{\mbfitsansPsi }{\mathalpha}{mathematical sans-serif bold italic capital psi}%
+\xUnicodeMathSymbol{"1D7A8}{\mbfitsansOmega }{\mathalpha}{mathematical sans-serif bold italic capital omega}%
+\xUnicodeMathSymbol{"1D7A9}{\mbfitsansnabla }{\mathalpha}{mathematical sans-serif bold italic nabla}%
+\xUnicodeMathSymbol{"1D7AA}{\mbfitsansalpha }{\mathalpha}{mathematical sans-serif bold italic small alpha}%
+\xUnicodeMathSymbol{"1D7AB}{\mbfitsansbeta }{\mathalpha}{mathematical sans-serif bold italic small beta}%
+\xUnicodeMathSymbol{"1D7AC}{\mbfitsansgamma }{\mathalpha}{mathematical sans-serif bold italic small gamma}%
+\xUnicodeMathSymbol{"1D7AD}{\mbfitsansdelta }{\mathalpha}{mathematical sans-serif bold italic small delta}%
+\xUnicodeMathSymbol{"1D7AE}{\mbfitsansepsilon }{\mathalpha}{mathematical sans-serif bold italic small epsilon}%
+\xUnicodeMathSymbol{"1D7AF}{\mbfitsanszeta }{\mathalpha}{mathematical sans-serif bold italic small zeta}%
+\xUnicodeMathSymbol{"1D7B0}{\mbfitsanseta }{\mathalpha}{mathematical sans-serif bold italic small eta}%
+\xUnicodeMathSymbol{"1D7B1}{\mbfitsanstheta }{\mathalpha}{mathematical sans-serif bold italic small theta}%
+\xUnicodeMathSymbol{"1D7B2}{\mbfitsansiota }{\mathalpha}{mathematical sans-serif bold italic small iota}%
+\xUnicodeMathSymbol{"1D7B3}{\mbfitsanskappa }{\mathalpha}{mathematical sans-serif bold italic small kappa}%
+\xUnicodeMathSymbol{"1D7B4}{\mbfitsanslambda }{\mathalpha}{mathematical sans-serif bold italic small lambda}%
+\xUnicodeMathSymbol{"1D7B5}{\mbfitsansmu }{\mathalpha}{mathematical sans-serif bold italic small mu}%
+\xUnicodeMathSymbol{"1D7B6}{\mbfitsansnu }{\mathalpha}{mathematical sans-serif bold italic small nu}%
+\xUnicodeMathSymbol{"1D7B7}{\mbfitsansxi }{\mathalpha}{mathematical sans-serif bold italic small xi}%
+\xUnicodeMathSymbol{"1D7B8}{\mbfitsansomicron }{\mathalpha}{mathematical sans-serif bold italic small omicron}%
+\xUnicodeMathSymbol{"1D7B9}{\mbfitsanspi }{\mathalpha}{mathematical sans-serif bold italic small pi}%
+\xUnicodeMathSymbol{"1D7BA}{\mbfitsansrho }{\mathalpha}{mathematical sans-serif bold italic small rho}%
+\xUnicodeMathSymbol{"1D7BB}{\mbfitsansvarsigma }{\mathalpha}{mathematical sans-serif bold italic small final sigma}%
+\xUnicodeMathSymbol{"1D7BC}{\mbfitsanssigma }{\mathalpha}{mathematical sans-serif bold italic small sigma}%
+\xUnicodeMathSymbol{"1D7BD}{\mbfitsanstau }{\mathalpha}{mathematical sans-serif bold italic small tau}%
+\xUnicodeMathSymbol{"1D7BE}{\mbfitsansupsilon }{\mathalpha}{mathematical sans-serif bold italic small upsilon}%
+\xUnicodeMathSymbol{"1D7BF}{\mbfitsansphi }{\mathalpha}{mathematical sans-serif bold italic small phi}%
+\xUnicodeMathSymbol{"1D7C0}{\mbfitsanschi }{\mathalpha}{mathematical sans-serif bold italic small chi}%
+\xUnicodeMathSymbol{"1D7C1}{\mbfitsanspsi }{\mathalpha}{mathematical sans-serif bold italic small psi}%
+\xUnicodeMathSymbol{"1D7C2}{\mbfitsansomega }{\mathalpha}{mathematical sans-serif bold italic small omega}%
+\xUnicodeMathSymbol{"1D7C3}{\mbfitsanspartial }{\mathalpha}{mathematical sans-serif bold italic partial differential}%
+\xUnicodeMathSymbol{"1D7C4}{\mbfitsansvarepsilon }{\mathalpha}{mathematical sans-serif bold italic epsilon symbol}%
+\xUnicodeMathSymbol{"1D7C5}{\mbfitsansvartheta }{\mathalpha}{mathematical sans-serif bold italic theta symbol}%
+\xUnicodeMathSymbol{"1D7C6}{\mbfitsansvarkappa }{\mathalpha}{mathematical sans-serif bold italic kappa symbol}%
+\xUnicodeMathSymbol{"1D7C7}{\mbfitsansvarphi }{\mathalpha}{mathematical sans-serif bold italic phi symbol}%
+\xUnicodeMathSymbol{"1D7C8}{\mbfitsansvarrho }{\mathalpha}{mathematical sans-serif bold italic rho symbol}%
+\xUnicodeMathSymbol{"1D7C9}{\mbfitsansvarpi }{\mathalpha}{mathematical sans-serif bold italic pi symbol}%
+\xUnicodeMathSymbol{"1D7CA}{\mbfDigamma }{\mathalpha}{mathematical bold capital digamma}%
+\xUnicodeMathSymbol{"1D7CB}{\mbfdigamma }{\mathalpha}{mathematical bold small digamma}%
+\xUnicodeMathSymbol{"1D7CE}{\mbfzero }{\mathord}{mathematical bold digit 0}%
+\xUnicodeMathSymbol{"1D7CF}{\mbfone }{\mathord}{mathematical bold digit 1}%
+\xUnicodeMathSymbol{"1D7D0}{\mbftwo }{\mathord}{mathematical bold digit 2}%
+\xUnicodeMathSymbol{"1D7D1}{\mbfthree }{\mathord}{mathematical bold digit 3}%
+\xUnicodeMathSymbol{"1D7D2}{\mbffour }{\mathord}{mathematical bold digit 4}%
+\xUnicodeMathSymbol{"1D7D3}{\mbffive }{\mathord}{mathematical bold digit 5}%
+\xUnicodeMathSymbol{"1D7D4}{\mbfsix }{\mathord}{mathematical bold digit 6}%
+\xUnicodeMathSymbol{"1D7D5}{\mbfseven }{\mathord}{mathematical bold digit 7}%
+\xUnicodeMathSymbol{"1D7D6}{\mbfeight }{\mathord}{mathematical bold digit 8}%
+\xUnicodeMathSymbol{"1D7D7}{\mbfnine }{\mathord}{mathematical bold digit 9}%
+\xUnicodeMathSymbol{"1D7D8}{\Bbbzero }{\mathord}{mathematical double-struck digit 0}%
+\xUnicodeMathSymbol{"1D7D9}{\Bbbone }{\mathord}{mathematical double-struck digit 1}%
+\xUnicodeMathSymbol{"1D7DA}{\Bbbtwo }{\mathord}{mathematical double-struck digit 2}%
+\xUnicodeMathSymbol{"1D7DB}{\Bbbthree }{\mathord}{mathematical double-struck digit 3}%
+\xUnicodeMathSymbol{"1D7DC}{\Bbbfour }{\mathord}{mathematical double-struck digit 4}%
+\xUnicodeMathSymbol{"1D7DD}{\Bbbfive }{\mathord}{mathematical double-struck digit 5}%
+\xUnicodeMathSymbol{"1D7DE}{\Bbbsix }{\mathord}{mathematical double-struck digit 6}%
+\xUnicodeMathSymbol{"1D7DF}{\Bbbseven }{\mathord}{mathematical double-struck digit 7}%
+\xUnicodeMathSymbol{"1D7E0}{\Bbbeight }{\mathord}{mathematical double-struck digit 8}%
+\xUnicodeMathSymbol{"1D7E1}{\Bbbnine }{\mathord}{mathematical double-struck digit 9}%
+\xUnicodeMathSymbol{"1D7E2}{\msanszero }{\mathord}{mathematical sans-serif digit 0}%
+\xUnicodeMathSymbol{"1D7E3}{\msansone }{\mathord}{mathematical sans-serif digit 1}%
+\xUnicodeMathSymbol{"1D7E4}{\msanstwo }{\mathord}{mathematical sans-serif digit 2}%
+\xUnicodeMathSymbol{"1D7E5}{\msansthree }{\mathord}{mathematical sans-serif digit 3}%
+\xUnicodeMathSymbol{"1D7E6}{\msansfour }{\mathord}{mathematical sans-serif digit 4}%
+\xUnicodeMathSymbol{"1D7E7}{\msansfive }{\mathord}{mathematical sans-serif digit 5}%
+\xUnicodeMathSymbol{"1D7E8}{\msanssix }{\mathord}{mathematical sans-serif digit 6}%
+\xUnicodeMathSymbol{"1D7E9}{\msansseven }{\mathord}{mathematical sans-serif digit 7}%
+\xUnicodeMathSymbol{"1D7EA}{\msanseight }{\mathord}{mathematical sans-serif digit 8}%
+\xUnicodeMathSymbol{"1D7EB}{\msansnine }{\mathord}{mathematical sans-serif digit 9}%
+\xUnicodeMathSymbol{"1D7EC}{\mbfsanszero }{\mathord}{mathematical sans-serif bold digit 0}%
+\xUnicodeMathSymbol{"1D7ED}{\mbfsansone }{\mathord}{mathematical sans-serif bold digit 1}%
+\xUnicodeMathSymbol{"1D7EE}{\mbfsanstwo }{\mathord}{mathematical sans-serif bold digit 2}%
+\xUnicodeMathSymbol{"1D7EF}{\mbfsansthree }{\mathord}{mathematical sans-serif bold digit 3}%
+\xUnicodeMathSymbol{"1D7F0}{\mbfsansfour }{\mathord}{mathematical sans-serif bold digit 4}%
+\xUnicodeMathSymbol{"1D7F1}{\mbfsansfive }{\mathord}{mathematical sans-serif bold digit 5}%
+\xUnicodeMathSymbol{"1D7F2}{\mbfsanssix }{\mathord}{mathematical sans-serif bold digit 6}%
+\xUnicodeMathSymbol{"1D7F3}{\mbfsansseven }{\mathord}{mathematical sans-serif bold digit 7}%
+\xUnicodeMathSymbol{"1D7F4}{\mbfsanseight }{\mathord}{mathematical sans-serif bold digit 8}%
+\xUnicodeMathSymbol{"1D7F5}{\mbfsansnine }{\mathord}{mathematical sans-serif bold digit 9}%
+\xUnicodeMathSymbol{"1D7F6}{\mttzero }{\mathord}{mathematical monospace digit 0}%
+\xUnicodeMathSymbol{"1D7F7}{\mttone }{\mathord}{mathematical monospace digit 1}%
+\xUnicodeMathSymbol{"1D7F8}{\mtttwo }{\mathord}{mathematical monospace digit 2}%
+\xUnicodeMathSymbol{"1D7F9}{\mttthree }{\mathord}{mathematical monospace digit 3}%
+\xUnicodeMathSymbol{"1D7FA}{\mttfour }{\mathord}{mathematical monospace digit 4}%
+\xUnicodeMathSymbol{"1D7FB}{\mttfive }{\mathord}{mathematical monospace digit 5}%
+\xUnicodeMathSymbol{"1D7FC}{\mttsix }{\mathord}{mathematical monospace digit 6}%
+\xUnicodeMathSymbol{"1D7FD}{\mttseven }{\mathord}{mathematical monospace digit 7}%
+\xUnicodeMathSymbol{"1D7FE}{\mtteight }{\mathord}{mathematical monospace digit 8}%
+\xUnicodeMathSymbol{"1D7FF}{\mttnine }{\mathord}{mathematical monospace digit 9}%
+\xUnicodeMathSymbol{"1EEF0}{\arabicmaj }{\mathop}{arabic mathematical operator meem with hah with tatweel}%
+\xUnicodeMathSymbol{"1EEF1}{\arabichad }{\mathop}{arabic mathematical operator hah with dal}%
+
+\def\mathbb#1{\csname Bbb\string#1\endcsname}
+
+\def\mathbf#1{{#1\mkern1mu#1}}
+
+
+% full width tables only
+\def\hline{%
+ \noalign{\ifnum0=`}\fi
+ \hbox to \hsize{\leaders\hbox{\string_}\hfill}\futurelet
+ \reserved@a\@xhline}
+
+\def\@cline#1-#2\@nil{%
+ \omit
+ \@multicnt#1%
+ \advance\@multispan\m@ne
+ \ifnum\@multicnt=\@ne\@firstofone{&\omit}\fi
+ \@multicnt#2%
+ \advance\@multicnt-#1%
+ \advance\@multispan\@ne
+ \leaders\hbox{\string_}\hfill
+ \cr
+ \noalign{\vskip-\arrayrulewidth}}
+
+\def\vline{|}
+
+\def\@arrayrule{\@addtopreamble{\hskip -.5\arrayrulewidth
+ |\hskip -.5\arrayrulewidth}}
+
+\let\oldhrule\hrule
+\def\hrule{\directlua{
+local h,w,d,hh,ww,dd,lw
+h=token.scan_keyword("height")
+if(h) then
+hh=token.scan_dimen()
+end
+d=token.scan_keyword("depth")
+if(d) then
+dd=token.scan_dimen()
+end
+w=token.scan_keyword("width")
+if(w) then
+ww=token.scan_dimen()
+end
+if(not(h)) then
+h=token.scan_keyword("height")
+if(h) then
+hh=token.scan_dimen()
+end
+end
+if(not(d)) then
+d=token.scan_keyword("depth")
+if(d) then
+dd=token.scan_dimen()
+end
+end
+if(not(w)) then
+w=token.scan_keyword("width")
+if(w) then
+ww=token.scan_dimen()
+end
+end
+if(not(h)) then
+h=token.scan_keyword("height")
+if(h) then
+hh=token.scan_dimen()
+end
+end
+if(not(d)) then
+d=token.scan_keyword("depth")
+if(d) then
+dd=token.scan_dimen()
+end
+end
+if(not(w)) then
+w=token.scan_keyword("width")
+if(w) then
+ww=token.scan_dimen()
+end
+end
+%print('\string\n=====')
+%print('h' .. tostring(h) .. (hh or '*'))
+%print('d' .. tostring(d) .. (dd or '*'))
+%print('w' .. tostring(w) .. (ww or '*'))
+%print('=====\string\n')
+if(ww) then
+lw="\string\\hskip " .. ww .. "sp\string\\hbox{}"
+else
+lw="\string\\hfill\string\\space"
+end
+tex.sprint('\string\\par\string\\noindent\string\\leaders\string\\hbox{\string\\string_}' .. lw)%
+}} \ No newline at end of file
diff --git a/macros/luatex/latex/wallcalendar/LICENSE.txt b/macros/luatex/latex/wallcalendar/LICENSE.txt
new file mode 100644
index 0000000000..4913054404
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/LICENSE.txt
@@ -0,0 +1,7 @@
+Wallcalendar Document Class
+
+(c) Gambhiro Bhikkhu, 2017
+gambhiro.bhikkhu.85@gmail.com
+
+LPPL LaTeX Public Project License
+
diff --git a/macros/luatex/latex/wallcalendar/README.md b/macros/luatex/latex/wallcalendar/README.md
new file mode 100644
index 0000000000..f603f05c50
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/README.md
@@ -0,0 +1,29 @@
+# Wallcalendar LaTeX documentclass
+
+A wall calendar class with custom layouts and support for internationalization.
+
+The documentclass comes with the following layouts:
+
+- Full page photo, the calendar days overlaid with opacity
+- Full page photo, the photo above the calendar days
+- Small landscape photo, with a calendar grid
+- Year planner
+- Thumbnails and captions
+- Varnish mask
+
+There is also support for loading event marks from a CSV file.
+
+See `wallcalendar.pdf` for the user manual, and `wallcalendar-code.pdf` for the
+commented code documentation.
+
+The manual includes examples and tutorials, but you may also want to see the [doc/examples][examples] folder on Github.
+
+![wallcalendar layouts](./wallcalendar-layouts.png)
+
+Github: https://github.com/profound-labs/wallcalendar
+
+[examples]: https://github.com/profound-labs/wallcalendar/tree/master/doc/examples
+
+Contact: Gambhiro Bhikkhu <gambhiro.bhikkhu.85@gmail.com>
+
+LPPL LaTeX Public Project License
diff --git a/macros/luatex/latex/wallcalendar/doc/Makefile b/macros/luatex/latex/wallcalendar/doc/Makefile
new file mode 100644
index 0000000000..3bc42f78d7
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/Makefile
@@ -0,0 +1,10 @@
+all: wallcalendar wallcalendar-code
+
+wallcalendar:
+ latexmk wallcalendar.tex
+
+wallcalendar-code:
+ latexmk wallcalendar-code.tex
+
+clean:
+ rm -v *.dvi *.ps *.aux *.log *.bbl *.blg *.bcf *.toc
diff --git a/macros/luatex/latex/wallcalendar/doc/auto/wallcalendar-code.el b/macros/luatex/latex/wallcalendar/doc/auto/wallcalendar-code.el
new file mode 100644
index 0000000000..6f04500ee6
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/auto/wallcalendar-code.el
@@ -0,0 +1,243 @@
+(TeX-add-style-hook
+ "wallcalendar-code"
+ (lambda ()
+ (TeX-add-to-alist 'LaTeX-provided-class-options
+ '(("memoir-article" "11pt" "oneside") ("memoir" "11pt" "oneside")))
+ (TeX-add-to-alist 'LaTeX-provided-package-options
+ '(("xcolor" "cmyk") ("microtype" "final" "babel=true")))
+ (TeX-run-style-hooks
+ "latex2e"
+ "memoir-article"
+ "memoir-article11"
+ "local"
+ "pgfopts"
+ "calc"
+ "memoir"
+ "memoir11"
+ "nag"
+ "xcolor"
+ "graphicx"
+ "eso-pic"
+ "ccicons"
+ "multicol"
+ "wasysym"
+ "pdftexcmds"
+ "etoolbox"
+ "luacode"
+ "xcoffins"
+ "microtype"
+ "tikz")
+ (TeX-add-symbols
+ '("parseYearEvents" ["argument"] 0)
+ '("parseMonthEvents" ["argument"] 0)
+ '("MonthPage" ["argument"] 1)
+ '("SetEvents" ["argument"] 3)
+ '("SetQuote" ["argument"] 2)
+ '("SetCalendar" ["argument"] 1)
+ '("SetPhoto" ["argument"] 1)
+ '("placeholder" ["argument"] 2)
+ '("monthName" 1)
+ '("monthToNum" 1)
+ '("plannerLandscapeDateDayFormat" 1)
+ '("parseMonthMarksNoteUsing" 1)
+ '("parseMonthMarksDayTextMonthUsing" 2)
+ '("parseMonthMarksDayTextUsing" 1)
+ '("parseMonthMarksDayTextMonth" 1)
+ '("txt" 1)
+ '("SetTxt" 2)
+ '("plannerMoonFormat" 1)
+ '("strcmpblank" 3)
+ "theMonthName"
+ "StarMark"
+ "NoteStarMark"
+ "KiteMark"
+ "NoteKiteMark"
+ "NewMoon"
+ "FirstQuarter"
+ "FullMoon"
+ "LastQuarter"
+ "plannerMoonSize"
+ "monthMarkFmt"
+ "symbolSpace"
+ "symbolSeparator"
+ "parseMonthMarksDayText"
+ "parseMonthMarksNote"
+ "monthFmt"
+ "yearFmt"
+ "dayLetterFmt"
+ "dayTextFmt"
+ "quoteFmt"
+ "headingFmt"
+ "calendarFmt"
+ "eventsFmt"
+ "fullPageFmt"
+ "tikzMonthCalendar"
+ "smallLandscapeFmt"
+ "gridRows"
+ "gridLines"
+ "n"
+ "plannerPortraitMonthFmt"
+ "plannerPortraitDayFmt"
+ "plannerLandscapeDateDayFont"
+ "plannerLandscapeDayFont"
+ "plannerLandscapeMonthFont"
+ "plannerLandscapeMonthFmt"
+ "plannerLandscapeDayFmt"
+ "plannerLandscapeBeginDayScopeHook"
+ "plannerGridMonthFont"
+ "plannerGridDateDayFont"
+ "plannerGridNotesFont"
+ "plannerGridDayFont"
+ "plannerGridYearNumberFont"
+ "plannerGridYearNumberFmt"
+ "plannerGridMonthFmt"
+ "plannerGridDayFmt"
+ "plannerGridDateDayFmt"
+ "plannerGridNotesFmt"
+ "plannerGridBeginDayScopeHook"
+ "plannerMarksDayTextCSV"
+ "plannerMarksNoteCSV"
+ "plannerMarkDefaultsCsv"
+ "plannerEvents"
+ "YearPlannerPortrait"
+ "YearPlannerLandscape"
+ "YearPlannerLandscapeGrid"
+ "YearPlannerLandscapeGridPage"
+ "LoadTranslations"
+ "eIdx"
+ "eMaxIdx"
+ "eMark"
+ "eIsoDate"
+ "eYear"
+ "eMonth"
+ "eMonthShort"
+ "eDay"
+ "eDayText"
+ "eNote"
+ "dayLetterColor"
+ "l"
+ "daylabelcolor")
+ (LaTeX-add-labels
+ "sec:org96389a7"
+ "sec:org45bc02b"
+ "sec:org29781fd"
+ "sec:org2ebd68a"
+ "sec:orgf63949e"
+ "sec:org1544dc5"
+ "sec:org2d3abb2"
+ "sec:orge07ee5a"
+ "sec:orgd636a69"
+ "sec:org281ee7a"
+ "sec:orgf70f7fe"
+ "sec:org215fe38"
+ "sec:org4c3f5ae"
+ "sec:orge5d42f4"
+ "sec:org198eca9"
+ "sec:orgbfbfe40"
+ "sec:orgfc6858a"
+ "sec:orgd6a2f68"
+ "sec:org9996966"
+ "sec:org412e39a"
+ "sec:orgab06397"
+ "sec:org3b4e036"
+ "sec:org9c1a6a1"
+ "sec:orgb28c6c4"
+ "sec:org711444c"
+ "sec:orgcb9bf42"
+ "sec:org8981ab6"
+ "sec:org4aef638"
+ "sec:org6c9c7a1"
+ "sec:orgde29618"
+ "sec:org6cd54c1"
+ "sec:org5f9e367"
+ "sec:org396a316"
+ "sec:org3b370cc"
+ "sec:orgb89e36b"
+ "sec:org24e0024"
+ "sec:orgcf04e30"
+ "sec:orga2e07dc"
+ "sec:org2e41aed"
+ "sec:orga58446b"
+ "sec:orgbe4e6d6"
+ "sec:orgab25392"
+ "sec:org7522fd9"
+ "sec:orge4db85d"
+ "sec:orge713968"
+ "sec:org28b2a27"
+ "sec:orge5a9400"
+ "sec:orgf5b7748"
+ "sec:orgf57fc27"
+ "sec:org4335a91"
+ "sec:org66a8015"
+ "sec:orgec90d96"
+ "sec:org19590f3"
+ "sec:org11161c1"
+ "sec:orgcdfd5b1"
+ "sec:orgfa049f6"
+ "sec:orgd581032"
+ "sec:orgcdcedfd"
+ "sec:orgf62996c"
+ "sec:orga66f8a7"
+ "sec:org8b1a47f"
+ "sec:orgfa12564"
+ "sec:org4ba160c"
+ "sec:org20ae9c5"
+ "sec:org9d1f8e2"
+ "sec:org7b7858d"
+ "sec:org3b7f33a"
+ "sec:orgf40f335"
+ "sec:orge85789c"
+ "sec:orga6a744a"
+ "sec:orgdf6c24d"
+ "sec:org69cdabb"
+ "sec:orgdfb1023"
+ "sec:org64a6ea5"
+ "sec:orgf7b001f"
+ "sec:orgce2473c"
+ "sec:org772519b"
+ "sec:org9ce89e8"
+ "sec:org3563e80"
+ "sec:org8f36044")
+ (LaTeX-add-counters
+ "verticalCount")
+ (LaTeX-add-lengths
+ "calPaperWidth"
+ "calPaperHeight"
+ "dayTextXshift"
+ "dayTextYshift"
+ "markNumberAbove"
+ "markNumberRight"
+ "markDayTextAbove"
+ "markDayTextRight"
+ "plannerLandscapeDayXShift"
+ "plannerLandscapeMonthYShift"
+ "plannerGridColXShift"
+ "plannerGridRowYShift"
+ "plannerGridCalendarWidth"
+ "plannerGridCalendarHeight"
+ "plannerGridDayHeadingsHeight"
+ "plannerGridMonthNamesWidth"
+ "plannerGridNotesHeight")
+ (LaTeX-add-xcolor-definecolors
+ "textbody"
+ "gold"
+ "darkgold"
+ "orangegold"
+ "gridcolor"
+ "weekday"
+ "weekend"
+ "mooncolor"
+ "datenum"
+ "plannerdatenum"
+ "quote"
+ "notes"
+ "pagebgcolor"
+ "photo-frame"
+ "quote-frame"
+ "heading-frame"
+ "calendar-frame"
+ "events-frame"
+ "calendarbg"
+ "varnishmask"))
+ :latex)
+
diff --git a/macros/luatex/latex/wallcalendar/doc/auto/wallcalendar.el b/macros/luatex/latex/wallcalendar/doc/auto/wallcalendar.el
new file mode 100644
index 0000000000..ac1461482c
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/auto/wallcalendar.el
@@ -0,0 +1,71 @@
+(TeX-add-style-hook
+ "wallcalendar"
+ (lambda ()
+ (TeX-add-to-alist 'LaTeX-provided-class-options
+ '(("memoir-article" "11pt" "oneside") ("wallcalendar" "year=2018" "language=english" "imageFolder=./photos/" "" "language=japanese" "translationsInputFile=frog-japanese.tex" "translationsInputFile=frog-english.tex" "language=hungarian" "translationsInputFile=frog-hungarian.tex" "eventsCsv=./data/holidays.csv" "markDefaultsCsv=./data/mark_defaults.csv")))
+ (TeX-run-style-hooks
+ "latex2e"
+ "frontpage"
+ "./frog"
+ "memoir-article"
+ "memoir-article11"
+ "local"
+ "wallcalendar10"
+ "fontspec"
+ "local-japanese"
+ "local-english"
+ "local-hungarian")
+ (TeX-add-symbols
+ '("ThumbWithCaptionRightSide" 1)
+ '("ThumbWithCaptionLeftSide" 1)
+ "SeptMarks"
+ "plannerYearFmt"
+ "preYearPlannerPageHook"
+ "postYearPlannerPageHook"
+ "printPlannerTitle"
+ "YearPlannerPage"
+ "thumbFmt"
+ "thumbMonthFmt"
+ "thumbCaptionFmt"
+ "ThumbsPage")
+ (LaTeX-add-labels
+ "sec:org9e1c3d1"
+ "sec:orgbba6dea"
+ "sec:org30e28c2"
+ "sec:org6815f95"
+ "sec:orgda955cc"
+ "sec:org522c828"
+ "sec:org80f370d"
+ "sec:org28303a7"
+ "sec:orga8965a9"
+ "sec:org2adcd24"
+ "sec:org736afc3"
+ "sec:org12d351e"
+ "sec:orgba9e3f8"
+ "sec:orgbf5aa37"
+ "sec:orgb56123b"
+ "sec:org24663e1"
+ "sec:org85fac7e"
+ "sec:org0124cf4"
+ "sec:org70f504f"
+ "sec:org0431559"
+ "sec:orgc4970c9"
+ "sec:orge74d943"
+ "sec:org7af4bd6"
+ "sec:org9571a13"
+ "sec:org1bdd209"
+ "sec:org23c0fca"
+ "sec:org5024f18"
+ "sec:org02a2f80"
+ "sec:org2801ae6"
+ "sec:orgc9e6d1d")
+ (LaTeX-add-lengths
+ "plannerNotesSep"
+ "thumbColumnWidth"
+ "thumbColumnHeight"
+ "thumbSep")
+ (LaTeX-add-fontspec-newfontcmds
+ "dejaVuSans"
+ "mincho"))
+ :latex)
+
diff --git a/macros/luatex/latex/wallcalendar/doc/doc-setup.org b/macros/luatex/latex/wallcalendar/doc/doc-setup.org
new file mode 100644
index 0000000000..c40a23c91c
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/doc-setup.org
@@ -0,0 +1,9 @@
+#+LATEX_CLASS: memoir-article
+#+LATEX_HEADER: \usepackage{local}
+#+LATEX_HEADER: \renewcommand{\docVersion}{v1.3.1}
+#+LATEX_HEADER: \renewcommand{\docUrl}{\href{https://github.com/profound-labs/wallcalendar/}{link}}
+#+LATEX_HEADER: \hypersetup{ pdfauthor={Gambhīro Bhikkhu}, }
+#+OPTIONS: toc:nil tasks:nil ':t H:4
+#+SOURCES_URL: https://github.com/profound-labs/wallcalendar/
+#+AUTHOR: Gambhīro Bhikkhu
+#+EMAIL: gambhiro.bhikkhu.85@gmail.com
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/Makefile b/macros/luatex/latex/wallcalendar/doc/examples/Makefile
new file mode 100644
index 0000000000..51e413300d
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/Makefile
@@ -0,0 +1,61 @@
+LATEX=lualatex
+LATEX_OPTS=-interaction=nonstopmode -halt-on-error
+
+all: calendars bursts
+
+test: ./diff-cal.sh
+
+calendars: cal-plain cal-showtrims cal-showframe cal-varnishmask cal-translations cal-marks cal-year-planner cal-thumbnails
+
+bursts: cal-plain-burst cal-showtrims-burst cal-showframe-burst cal-varnishmask-burst
+
+cal-plain:
+ $(LATEX) $(LATEX_OPTS) cal-plain.tex
+
+cal-plain-burst:
+ pdftk cal-plain.pdf burst output ./cal-burst/cal-plain-%02d.pdf
+
+cal-showtrims:
+ $(LATEX) $(LATEX_OPTS) cal-showtrims.tex
+
+cal-showtrims-burst:
+ pdftk cal-showtrims.pdf burst output ./cal-burst/cal-showtrims-%02d.pdf
+
+cal-showframe:
+ $(LATEX) $(LATEX_OPTS) cal-showframe.tex
+
+cal-showframe-burst:
+ pdftk cal-showframe.pdf burst output ./cal-burst/cal-showframe-%02d.pdf
+
+cal-varnishmask:
+ $(LATEX) $(LATEX_OPTS) cal-varnishmask.tex
+
+cal-varnishmask-burst:
+ pdftk cal-varnishmask.pdf burst output ./cal-burst/cal-varnishmask-%02d.pdf
+
+cal-translations-japanese:
+ $(LATEX) $(LATEX_OPTS) cal-translations-japanese.tex
+
+cal-translations-english:
+ $(LATEX) $(LATEX_OPTS) cal-translations-english.tex
+
+cal-translations-hungarian:
+ $(LATEX) $(LATEX_OPTS) cal-translations-hungarian.tex
+
+cal-translations: cal-translations-japanese cal-translations-english cal-translations-hungarian
+
+cal-marks:
+ $(LATEX) $(LATEX_OPTS) cal-marks.tex
+
+cal-year-planner:
+ $(LATEX) $(LATEX_OPTS) cal-year-planner.tex
+
+cal-thumbnails:
+ $(LATEX) $(LATEX_OPTS) cal-thumbnails.tex
+
+# For developing snippets in isolation.
+mwe:
+ $(LATEX) $(LATEX_OPTS) mwe.tex
+
+clean:
+ rm -v *.dvi *.ps *.aux *.log *.bbl *.blg *.bcf *.toc
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-plain-01.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-plain-01.pdf
new file mode 100644
index 0000000000..b069f4cc5b
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-plain-01.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-plain-02.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-plain-02.pdf
new file mode 100644
index 0000000000..43ff48fd05
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-plain-02.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-plain-03.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-plain-03.pdf
new file mode 100644
index 0000000000..50072a5416
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-plain-03.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showframe-01.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showframe-01.pdf
new file mode 100644
index 0000000000..b49ca920ff
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showframe-01.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showframe-02.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showframe-02.pdf
new file mode 100644
index 0000000000..b1110979de
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showframe-02.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showframe-03.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showframe-03.pdf
new file mode 100644
index 0000000000..cb535bdc9a
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showframe-03.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showtrims-01.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showtrims-01.pdf
new file mode 100644
index 0000000000..b0db97dabf
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showtrims-01.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showtrims-02.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showtrims-02.pdf
new file mode 100644
index 0000000000..2e6f248898
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showtrims-02.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showtrims-03.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showtrims-03.pdf
new file mode 100644
index 0000000000..fcef54e452
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-showtrims-03.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-varnishmask-01.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-varnishmask-01.pdf
new file mode 100644
index 0000000000..00fc6638d0
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-varnishmask-01.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-varnishmask-02.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-varnishmask-02.pdf
new file mode 100644
index 0000000000..260f773b65
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-varnishmask-02.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-varnishmask-03.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-varnishmask-03.pdf
new file mode 100644
index 0000000000..0d37c6070b
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-burst/cal-varnishmask-03.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-marks.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-marks.pdf
new file mode 100644
index 0000000000..eadb9f7d39
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-marks.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-marks.tex b/macros/luatex/latex/wallcalendar/doc/examples/cal-marks.tex
new file mode 100644
index 0000000000..d041ceab81
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-marks.tex
@@ -0,0 +1,50 @@
+\documentclass[
+ year = 2018,
+ eventsCsv = ./data/holidays.csv,
+ markDefaultsCsv = ./data/mark_defaults.csv,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\makeatletter
+
+\colorlet{mooncolor}{darkgold}
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+
+\SetPhoto[bleed=3mm, file={frog-crop}]{September}
+
+\SetQuote[xOffset=0pt, yOffset=-140mm]{September}{%
+\raggedleft\setlength{\parskip}{10pt}\HUGE\color{white}%
+silent new lake\\
+let the frog jump\\
+not even a sound
+
+\textit{-- Ryokan}%
+}
+
+\SetCalendar[bg/.style={opacity=0.4}]{September}
+
+\SetEvents{September}{%
+\parseMonthMarksDayTextUsing{./data/moonphases.csv}%
+\parseMonthMarksDayText%
+\parseMonthMarksNote%
+}{%
+\raggedright
+\parseMonthEvents[%
+ format cmd = {%
+ \textsuperscript{\eMark}~\eMonthShort~\eDay:\space%
+ \eNote\ifnumless{\eIdx}{\eMaxIdx}{,\space}{.}%
+ },
+]%
+}
+
+\makeatother
+
+\begin{document}
+
+\MonthPage[layout=full page, put photo=full page]{September}
+
+\end{document}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-plain.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-plain.pdf
new file mode 100644
index 0000000000..6c5be0df5e
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-plain.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-plain.tex b/macros/luatex/latex/wallcalendar/doc/examples/cal-plain.tex
new file mode 100644
index 0000000000..7c02e1e8b6
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-plain.tex
@@ -0,0 +1,7 @@
+\documentclass[
+ year=2018,
+ language=english,
+ imageFolder=./photos/,
+]{wallcalendar}
+
+\input{./forest.tex} \ No newline at end of file
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-showframe.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-showframe.pdf
new file mode 100644
index 0000000000..cf3872c1b9
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-showframe.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-showframe.tex b/macros/luatex/latex/wallcalendar/doc/examples/cal-showframe.tex
new file mode 100644
index 0000000000..5f7ea0499a
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-showframe.tex
@@ -0,0 +1,9 @@
+\documentclass[
+ year=2018,
+ language=english,
+ imageFolder=./photos/,
+ showtrims,
+ showframe,
+]{wallcalendar}
+
+\input{./forest.tex} \ No newline at end of file
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-showtrims.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-showtrims.pdf
new file mode 100644
index 0000000000..23f9a9ce6c
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-showtrims.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-showtrims.tex b/macros/luatex/latex/wallcalendar/doc/examples/cal-showtrims.tex
new file mode 100644
index 0000000000..3e57a536b8
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-showtrims.tex
@@ -0,0 +1,8 @@
+\documentclass[
+ year=2018,
+ language=english,
+ imageFolder=./photos/,
+ showtrims,
+]{wallcalendar}
+
+\input{./forest.tex} \ No newline at end of file
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-thumbnails.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-thumbnails.pdf
new file mode 100644
index 0000000000..1e8fad0769
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-thumbnails.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-thumbnails.tex b/macros/luatex/latex/wallcalendar/doc/examples/cal-thumbnails.tex
new file mode 100644
index 0000000000..510c38885f
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-thumbnails.tex
@@ -0,0 +1,200 @@
+\documentclass[
+ year = 2018,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\makeatletter
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+
+\newlength\@wall@tmp@a
+\newlength\@wall@tmp@b
+
+\newlength\@wall@thumbWidth
+\newlength\@wall@thumbHeight
+\newlength\@wall@thumbCaptionWidth
+\setlength{\@wall@thumbWidth}{0.1749\calPaperWidth}% 30mm at the 6.75in page width, 0.1749 = 1/5.715
+\setlength{\@wall@thumbHeight}{\@wall@thumbWidth}
+\setlength{\@wall@thumbCaptionWidth}{0.2333\calPaperWidth}% 40mm at 6.75in page width
+
+\newcommand\thumbFmt{}
+\newcommand\thumbMonthFmt{\fontsize{10}{13}\selectfont\bfseries}
+\newcommand\thumbCaptionFmt{\fontsize{10}{13}\selectfont}
+
+\def\@wall@thumbFile{}
+\def\@wall@photoCaption{}
+
+\newcommand\ThumbWithCaptionLeftSide[1]{%
+\pgfkeys{/Photo/#1/thumbFile/.get=\@wall@thumbFile}%
+\ifx\@wall@thumbFile\empty
+ \pgfkeys{/Photo/#1/file/.get=\@wall@thumbFile}%
+\fi
+\pgfkeys{/Photo/#1/caption/.get=\@wall@photoCaption}%
+% Thumbnail caption
+\ifvarnishmask%
+\hspace*{\@wall@thumbWidth}
+\else%
+\begin{minipage}[b][\@wall@thumbHeight][t]{\@wall@thumbCaptionWidth}%
+\raggedleft
+\thumbFmt
+{\thumbMonthFmt \@tr@monthNumName{\monthToNum{#1}}}\par
+{\thumbCaptionFmt \@wall@photoCaption}%
+\end{minipage}%
+\fi%
+\hspace*{3mm}
+% Thumbnail photo
+\begin{minipage}[b][\@wall@thumbHeight]{\@wall@thumbWidth}%
+% FIXME placeholder
+%\placeholder{%
+\includegraphics[ keepaspectratio, height=\@wall@thumbHeight ]{\@wall@thumbFile}%
+%}%
+\end{minipage}%
+}
+
+\newcommand\ThumbWithCaptionRightSide[1]{%
+\pgfkeys{/Photo/#1/thumbFile/.get=\@wall@thumbFile}%
+\ifx\@wall@thumbFile\empty
+ \pgfkeys{/Photo/#1/file/.get=\@wall@thumbFile}%
+\fi
+\pgfkeys{/Photo/#1/caption/.get=\@wall@photoCaption}%
+% Thumbnail photo
+\begin{minipage}[b][\@wall@thumbHeight]{\@wall@thumbWidth}%
+% FIXME placeholder
+%\placeholder{%
+\includegraphics[ keepaspectratio, height=\@wall@thumbHeight ]{\@wall@thumbFile}%
+%}%
+\end{minipage}%
+\hspace*{3mm}
+% Thumbnail caption
+\ifvarnishmask%
+\hspace*{\@wall@thumbWidth}
+\else%
+\begin{minipage}[b][\@wall@thumbHeight][t]{\@wall@thumbCaptionWidth}%
+\raggedright
+\thumbFmt
+{\thumbMonthFmt \@tr@monthNumName{\monthToNum{#1}}}\par
+{\thumbCaptionFmt \@wall@photoCaption}%
+\end{minipage}%
+\fi%
+}
+
+\newlength{\thumbColumnWidth}
+\newlength{\thumbColumnHeight}
+\newlength{\thumbSep}
+\newlength{\@t@a}
+\newlength{\@t@b}
+
+% vertical spacing
+\setlength{\@t@a}{0.2\textheight}
+
+% horizontal spacing
+\setlength{\@t@b}{0.2\@wall@thumbCaptionWidth}% 8mm at 40mm caption width
+
+\ifdimcomp{\@t@a}{<}{\@t@b}{
+ \setlength{\thumbSep}{\@t@a}
+}{
+ \setlength{\thumbSep}{\@t@b}
+}
+
+\setlength{\thumbColumnWidth}{0.5\calPaperWidth - \thumbSep}
+\setlength{\thumbColumnHeight}{\textheight}
+
+\newcommand\ThumbsPage{%
+\clearpage
+
+\hspace*{-\@wall@leftMargin}%
+\hspace*{-1pt}% small correction, space gets in somewhere
+% Wrap
+\begin{minipage}[t][\thumbColumnHeight]{\calPaperWidth}%
+\centering%
+\setlength{\parindent}{0pt}%
+\setlength{\parskip}{0pt}%
+
+% NOTE: multicols will not \vfill
+% Left Column
+\begin{minipage}[t][\thumbColumnHeight]{\thumbColumnWidth}%
+\raggedleft
+
+\ThumbWithCaptionLeftSide{January}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{March}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{May}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{July}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{September}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{November}
+
+% End of left column
+\end{minipage}%
+%
+\hspace*{\thumbSep}%
+%
+% Right column
+\begin{minipage}[t][\thumbColumnHeight]{\thumbColumnWidth}%
+\raggedright
+
+\ThumbWithCaptionRightSide{February}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{April}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{June}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{August}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{October}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{December}
+
+% End of right column
+\end{minipage}%
+
+% End of wrap
+\end{minipage}%
+}
+
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{January}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{February}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{March}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{April}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{May}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{June}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{July}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{August}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{September}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{October}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{November}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{December}
+
+\makeatother
+
+\begin{document}
+
+\ThumbsPage
+
+\end{document}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-english.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-english.pdf
new file mode 100644
index 0000000000..3ce0981c4c
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-english.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-english.tex b/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-english.tex
new file mode 100644
index 0000000000..4dc56ec10d
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-english.tex
@@ -0,0 +1,16 @@
+\documentclass[
+ year = 2018,
+ language = english,
+ translationsInputFile = frog-english.tex,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\usepackage{local-english}
+
+\input{./frog.tex}
+
+\begin{document}
+
+\MonthPage[layout=full page, put photo=full page]{September}
+
+\end{document}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-hungarian.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-hungarian.pdf
new file mode 100644
index 0000000000..1c5404d2d2
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-hungarian.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-hungarian.tex b/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-hungarian.tex
new file mode 100644
index 0000000000..9626ab3c23
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-hungarian.tex
@@ -0,0 +1,16 @@
+\documentclass[
+ year = 2018,
+ language = hungarian,
+ translationsInputFile = frog-hungarian.tex,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\usepackage{local-hungarian}
+
+\input{./frog.tex}
+
+\begin{document}
+
+\MonthPage[layout=full page, put photo=full page]{September}
+
+\end{document}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-japanese.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-japanese.pdf
new file mode 100644
index 0000000000..e88c290060
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-japanese.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-japanese.tex b/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-japanese.tex
new file mode 100644
index 0000000000..5b89d1bf9c
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-translations-japanese.tex
@@ -0,0 +1,18 @@
+\documentclass[
+ year = 2018,
+ language = japanese,
+ translationsInputFile = frog-japanese.tex,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\usepackage{local-japanese}
+
+% Content is the same across translations
+\input{./frog.tex}
+
+\begin{document}
+
+% Just one month
+\MonthPage[layout=full page, put photo=full page]{September}
+
+\end{document}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-varnishmask.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-varnishmask.pdf
new file mode 100644
index 0000000000..2ae0cb6e49
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-varnishmask.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-varnishmask.tex b/macros/luatex/latex/wallcalendar/doc/examples/cal-varnishmask.tex
new file mode 100644
index 0000000000..37b5d89d6b
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-varnishmask.tex
@@ -0,0 +1,9 @@
+\documentclass[
+ year=2018,
+ language=english,
+ imageFolder=./photos/,
+ showtrims,
+ varnishmask,
+]{wallcalendar}
+
+\input{./forest.tex} \ No newline at end of file
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-year-planner.pdf b/macros/luatex/latex/wallcalendar/doc/examples/cal-year-planner.pdf
new file mode 100644
index 0000000000..773acbc296
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-year-planner.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/cal-year-planner.tex b/macros/luatex/latex/wallcalendar/doc/examples/cal-year-planner.tex
new file mode 100644
index 0000000000..a9738309f7
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/cal-year-planner.tex
@@ -0,0 +1,75 @@
+\documentclass[
+ year = 2018,
+ eventsCsv = ./data/holidays.csv,
+ markDefaultsCsv = ./data/mark_defaults.csv,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\makeatletter
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+
+% Use two CSV files for day text input to include the moon phases
+\renewcommand\@wall@plm[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{#1}, nil, \luastring{\plannerMarksDayTextCSV})
+monthMarksDayText(\luastring{#1}, nil, \luastring{./data/moonphases.csv})
+tex.sprint(';')
+}}
+
+\newcommand\plannerYearFmt{\fontsize{26}{26}\selectfont\color{orangegold}}
+
+\newlength\plannerNotesSep
+\setlength{\plannerNotesSep}{3mm}
+
+\newcommand\preYearPlannerPageHook{%
+ \setlength{\markNumberAbove}{-9pt}%
+ \setlength{\markNumberRight}{-6pt}%
+ \setlength{\markDayTextAbove}{-11pt}%
+ \setlength{\markDayTextRight}{-6pt}%
+}
+
+\newcommand\postYearPlannerPageHook{%
+ \setlength{\markNumberAbove}{-10pt}%
+ \setlength{\markNumberRight}{-3pt}%
+ \setlength{\markDayTextAbove}{-10pt}%
+ \setlength{\markDayTextRight}{-3pt}%
+}
+
+\newcommand\printPlannerTitle{\plannerYearFmt \CalendarYear}
+
+\newcommand\YearPlannerPage{%
+\newpage
+\ifvarnishmask
+\mbox{}
+\else
+\preYearPlannerPageHook
+{\centering
+
+{\printPlannerTitle}
+
+\vspace*{7mm}
+
+\YearPlannerPortrait
+
+\vspace*{\plannerNotesSep}
+
+\plannerEvents
+
+}
+\postYearPlannerPageHook
+
+\fi
+}
+
+\makeatother
+
+\begin{document}
+
+\YearPlannerPage
+
+\end{document}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/data/astro-2018.json b/macros/luatex/latex/wallcalendar/doc/examples/data/astro-2018.json
new file mode 100644
index 0000000000..4a5633ed07
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/data/astro-2018.json
@@ -0,0 +1 @@
+{"success":true,"error":null,"response":[{"timestamp":1514859929,"dateTimeISO":"2018-01-02T02:25:29+00:00","code":2,"name":"full moon"},{"timestamp":1515450393,"dateTimeISO":"2018-01-08T22:26:33+00:00","code":3,"name":"last quarter"},{"timestamp":1516155498,"dateTimeISO":"2018-01-17T02:18:18+00:00","code":0,"name":"new moon"},{"timestamp":1516832433,"dateTimeISO":"2018-01-24T22:20:33+00:00","code":1,"name":"first quarter"},{"timestamp":1517405266,"dateTimeISO":"2018-01-31T13:27:46+00:00","code":2,"name":"full moon"},{"timestamp":1518018949,"dateTimeISO":"2018-02-07T15:55:49+00:00","code":3,"name":"last quarter"},{"timestamp":1518728811,"dateTimeISO":"2018-02-15T21:06:51+00:00","code":0,"name":"new moon"},{"timestamp":1519373361,"dateTimeISO":"2018-02-23T08:09:21+00:00","code":1,"name":"first quarter"},{"timestamp":1519951930,"dateTimeISO":"2018-03-02T00:52:10+00:00","code":2,"name":"full moon"},{"timestamp":1520594574,"dateTimeISO":"2018-03-09T11:22:54+00:00","code":3,"name":"last quarter"},{"timestamp":1521292459,"dateTimeISO":"2018-03-17T13:14:19+00:00","code":0,"name":"new moon"},{"timestamp":1521905752,"dateTimeISO":"2018-03-24T15:35:52+00:00","code":1,"name":"first quarter"},{"timestamp":1522499867,"dateTimeISO":"2018-03-31T13:37:47+01:00","code":2,"name":"full moon"},{"timestamp":1523172061,"dateTimeISO":"2018-04-08T08:21:01+01:00","code":3,"name":"last quarter"},{"timestamp":1523843993,"dateTimeISO":"2018-04-16T02:59:53+01:00","code":0,"name":"new moon"},{"timestamp":1524433610,"dateTimeISO":"2018-04-22T22:46:50+01:00","code":1,"name":"first quarter"},{"timestamp":1525049954,"dateTimeISO":"2018-04-30T01:59:14+01:00","code":2,"name":"full moon"},{"timestamp":1525745494,"dateTimeISO":"2018-05-08T03:11:34+01:00","code":3,"name":"last quarter"},{"timestamp":1526384989,"dateTimeISO":"2018-05-15T12:49:49+01:00","code":0,"name":"new moon"},{"timestamp":1526961039,"dateTimeISO":"2018-05-22T04:50:39+01:00","code":1,"name":"first quarter"},{"timestamp":1527603648,"dateTimeISO":"2018-05-29T15:20:48+01:00","code":2,"name":"full moon"},{"timestamp":1528310048,"dateTimeISO":"2018-06-06T19:34:08+01:00","code":3,"name":"last quarter"},{"timestamp":1528919104,"dateTimeISO":"2018-06-13T20:45:04+01:00","code":0,"name":"new moon"},{"timestamp":1529491954,"dateTimeISO":"2018-06-20T11:52:34+01:00","code":1,"name":"first quarter"},{"timestamp":1530161675,"dateTimeISO":"2018-06-28T05:54:35+01:00","code":2,"name":"full moon"},{"timestamp":1530863569,"dateTimeISO":"2018-07-06T08:52:49+01:00","code":3,"name":"last quarter"},{"timestamp":1531450175,"dateTimeISO":"2018-07-13T03:49:35+01:00","code":0,"name":"new moon"},{"timestamp":1532030037,"dateTimeISO":"2018-07-19T20:53:57+01:00","code":1,"name":"first quarter"},{"timestamp":1532722939,"dateTimeISO":"2018-07-27T21:22:19+01:00","code":2,"name":"full moon"},{"timestamp":1533406790,"dateTimeISO":"2018-08-04T19:19:50+01:00","code":3,"name":"last quarter"},{"timestamp":1533981547,"dateTimeISO":"2018-08-11T10:59:07+01:00","code":0,"name":"new moon"},{"timestamp":1534578594,"dateTimeISO":"2018-08-18T08:49:54+01:00","code":1,"name":"first quarter"},{"timestamp":1535284704,"dateTimeISO":"2018-08-26T12:58:24+01:00","code":2,"name":"full moon"},{"timestamp":1535942350,"dateTimeISO":"2018-09-03T03:39:10+01:00","code":3,"name":"last quarter"},{"timestamp":1536516161,"dateTimeISO":"2018-09-09T19:02:41+01:00","code":0,"name":"new moon"},{"timestamp":1537139765,"dateTimeISO":"2018-09-17T00:16:05+01:00","code":1,"name":"first quarter"},{"timestamp":1537844089,"dateTimeISO":"2018-09-25T03:54:49+01:00","code":2,"name":"full moon"},{"timestamp":1538473635,"dateTimeISO":"2018-10-02T10:47:15+01:00","code":3,"name":"last quarter"},{"timestamp":1539056870,"dateTimeISO":"2018-10-09T04:47:50+01:00","code":0,"name":"new moon"},{"timestamp":1539712949,"dateTimeISO":"2018-10-16T19:02:29+01:00","code":1,"name":"first quarter"},{"timestamp":1540399654,"dateTimeISO":"2018-10-24T17:47:34+01:00","code":2,"name":"full moon"},{"timestamp":1541004147,"dateTimeISO":"2018-10-31T16:42:27+00:00","code":3,"name":"last quarter"},{"timestamp":1541606572,"dateTimeISO":"2018-11-07T16:02:52+00:00","code":0,"name":"new moon"},{"timestamp":1542293669,"dateTimeISO":"2018-11-15T14:54:29+00:00","code":1,"name":"first quarter"},{"timestamp":1542951686,"dateTimeISO":"2018-11-23T05:41:26+00:00","code":2,"name":"full moon"},{"timestamp":1543537278,"dateTimeISO":"2018-11-30T00:21:18+00:00","code":3,"name":"last quarter"},{"timestamp":1544167302,"dateTimeISO":"2018-12-07T07:21:42+00:00","code":0,"name":"new moon"},{"timestamp":1544874577,"dateTimeISO":"2018-12-15T11:49:37+00:00","code":1,"name":"first quarter"},{"timestamp":1545501027,"dateTimeISO":"2018-12-22T17:50:27+00:00","code":2,"name":"full moon"},{"timestamp":1546076202,"dateTimeISO":"2018-12-29T09:36:42+00:00","code":3,"name":"last quarter"}]} \ No newline at end of file
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/data/holidays.csv b/macros/luatex/latex/wallcalendar/doc/examples/data/holidays.csv
new file mode 100644
index 0000000000..1143a5a389
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/data/holidays.csv
@@ -0,0 +1,10 @@
+date;day_text;note
+2018-09-10;G;Gandalf escapes from Orthanc
+2018-09-14;F;Frodo \& Bilbo's birthday
+2018-09-15;;Black riders enter the Shire
+2018-09-18;;Frodo and company rescued by Bombadil
+2018-09-25;;Full Moon
+2018-09-28;W;Wraith attack
+2018-10-05;F;Frodo crosses bridge of Mitheithel
+2018-10-16;B;Boromir reaches Rivendell
+2018-10-17;E;Council of Elrond
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/data/mark_defaults.csv b/macros/luatex/latex/wallcalendar/doc/examples/data/mark_defaults.csv
new file mode 100644
index 0000000000..8ead82c8b5
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/data/mark_defaults.csv
@@ -0,0 +1,3 @@
+number_symbol;day_text_symbol;note_symbol;number_above_offset;number_right_offset;day_text_above_offset;day_text_right_offset
+\StarMark;\StarMark;\StarMark;-13pt;-3pt;-13pt;-3pt
+\KiteMark;\KiteMark;\NoteKiteMark;-13pt;-2pt;-13pt;-2pt \ No newline at end of file
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/data/moonphases.csv b/macros/luatex/latex/wallcalendar/doc/examples/data/moonphases.csv
new file mode 100644
index 0000000000..4f31c2222c
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/data/moonphases.csv
@@ -0,0 +1,51 @@
+date;day_text;note
+2018-01-02;\FullMoon;
+2018-01-08;\LastQuarter;
+2018-01-17;\NewMoon;
+2018-01-24;\FirstQuarter;
+2018-01-31;\FullMoon;
+2018-02-07;\LastQuarter;
+2018-02-15;\NewMoon;
+2018-02-23;\FirstQuarter;
+2018-03-02;\FullMoon;
+2018-03-09;\LastQuarter;
+2018-03-17;\NewMoon;
+2018-03-24;\FirstQuarter;
+2018-03-31;\FullMoon;
+2018-04-08;\LastQuarter;
+2018-04-16;\NewMoon;
+2018-04-22;\FirstQuarter;
+2018-04-30;\FullMoon;
+2018-05-08;\LastQuarter;
+2018-05-15;\NewMoon;
+2018-05-22;\FirstQuarter;
+2018-05-29;\FullMoon;
+2018-06-06;\LastQuarter;
+2018-06-13;\NewMoon;
+2018-06-20;\FirstQuarter;
+2018-06-28;\FullMoon;
+2018-07-06;\LastQuarter;
+2018-07-13;\NewMoon;
+2018-07-19;\FirstQuarter;
+2018-07-27;\FullMoon;
+2018-08-04;\LastQuarter;
+2018-08-11;\NewMoon;
+2018-08-18;\FirstQuarter;
+2018-08-26;\FullMoon;
+2018-09-03;\LastQuarter;
+2018-09-09;\NewMoon;
+2018-09-17;\FirstQuarter;
+2018-09-25;\FullMoon;
+2018-10-02;\LastQuarter;
+2018-10-09;\NewMoon;
+2018-10-16;\FirstQuarter;
+2018-10-24;\FullMoon;
+2018-10-31;\LastQuarter;
+2018-11-07;\NewMoon;
+2018-11-15;\FirstQuarter;
+2018-11-23;\FullMoon;
+2018-11-30;\LastQuarter;
+2018-12-07;\NewMoon;
+2018-12-15;\FirstQuarter;
+2018-12-22;\FullMoon;
+2018-12-29;\LastQuarter;
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/diff-cal.sh b/macros/luatex/latex/wallcalendar/doc/examples/diff-cal.sh
new file mode 100755
index 0000000000..92e141b26a
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/diff-cal.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+# TODO get the list of calendar name from listing the .pdf in doc/examples/
+
+for i in marks plain showframe showtrims thumbnails translations-english translations-hungarian translations-japanese varnishmask year-planner; do
+ name="cal-$i"
+ git checkout "$name".pdf
+ pdftk "$name".pdf burst output ./diff-old/"$name"-%02d.pdf
+ make "$name" > out.log 2>&1
+ if [[ $? -ne 0 ]]; then
+ echo "ERROR: compiling '$name.pdf' failed. See out.log"
+ exit 2
+ fi
+ pdftk "$name".pdf burst output ./diff-new/"$name"-%02d.pdf
+done
+
+for i in ./diff-old/*.pdf; do
+ name=`basename $i`
+
+ echo -n "Compare $name, AE: ... "
+
+ compare \
+ -metric AE \
+ ./diff-old/"$name" \
+ ./diff-new/"$name" \
+ -compose src \
+ -alpha off \
+ ./diff-compare/`basename -s .pdf $i`.jpg
+
+ if [[ $? -eq 1 ]]; then
+ echo -e "\nDIFFER: $name\n"
+ else
+ echo -e "\n"
+ fi
+done
+
+for i in plain showframe showtrims varnishmask; do
+ name="cal-$i"
+ git checkout "$name".pdf
+done
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/forest.tex b/macros/luatex/latex/wallcalendar/doc/examples/forest.tex
new file mode 100644
index 0000000000..03f93b8993
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/forest.tex
@@ -0,0 +1,116 @@
+\makeatletter
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+
+\SetPhoto[bleed=3mm, file={obscure-crop}]{June}
+
+\SetQuote[xOffset=-5mm, yOffset=-20mm]{June}{%
+\raggedright
+\setlength{\parskip}{10pt}%
+\Large
+\color{white}
+
+I shall set forth for somewhere,\\
+I shall make the reckless choice\\
+Some day when they are in voice\\
+And tossing so as to scare\\
+The white clouds over them on.\\
+I shall have less to say,\\
+But I shall be gone.
+
+\textit{The Sound of the Trees} by Robert Frost
+}
+
+\ifshowframe
+ \SetCalendar[bg/.style={opacity=0.5, fill=white}]{June}
+\else
+ \SetCalendar[bg/.style={opacity=0.8}]{June}
+\fi
+
+\SetEvents{June}{%
+ if (equals=2018-06-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}{%
+\raggedleft
+{\dejaVuSans\char"263C} June 21: Summer Solstice
+}
+
+\SetPhoto[bleed=3mm, file={obscure-crop}]{July}
+
+\SetQuote[%
+ xOffset=0.5\linewidth - 0.5\paperwidth -3mm,
+ yOffset=-20mm,
+]{July}{%
+\begin{tikzpicture}%
+\node [
+ fill=white, opacity=0.6, minimum width={\paperwidth + 3mm},
+ minimum height=30mm] {};%
+\node [] {%
+\begin{minipage}{\paperwidth + 3mm}%
+\centering
+\Large
+\color{white}
+
+I shall have less to say,\\
+But I shall be gone.
+
+\textit{The Sound of the Trees} by Robert Frost
+\end{minipage}%
+};
+\end{tikzpicture}%
+}
+
+\ifshowframe
+ \SetCalendar[bg/.style={opacity=0.5}]{July}
+\else
+ \SetCalendar[bg/.style={opacity=1}]{July}
+\fi
+
+\SetEvents{July}{
+ if (equals=2018-07-27) [day text={\dejaVuSans\char"263C}];
+}{%
+\raggedleft
+{\dejaVuSans\char"263C} July 27: Mars at Opposition
+}
+
+\SetPhoto[bleed=3mm, file={obscure-crop}, yOffset=-150mm]{August}
+
+\SetQuote[yOffset=-3mm]{August}{%
+\centering
+\setlength{\parskip}{10pt}%
+\Large
+\color{black!80}
+
+I shall have less to say,\\
+But I shall be gone.
+
+\textit{The Sound of the Trees} by Robert Frost
+}
+
+\ifshowframe
+ \SetCalendar[bg/.style={opacity=0.5}]{August}
+\else
+ \SetCalendar[bg/.style={opacity=1}]{August}
+\fi
+
+\SetEvents{August}{
+ if (equals=2018-08-12) [day text={\dejaVuSans\char"263C}];
+}{%
+\raggedleft
+{\dejaVuSans\char"263C} August 12, 13: Perseids Meteor Shower
+}
+
+\makeatother
+
+\begin{document}
+
+\MonthPage[layout=full page, put photo=full page]{June}
+
+\MonthPage[layout=full page, put photo=full width above calendar]{July}
+
+\MonthPage[layout=small landscape, put photo=full width]{August}
+
+\end{document}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/frog-english.tex b/macros/luatex/latex/wallcalendar/doc/examples/frog-english.tex
new file mode 100644
index 0000000000..92500dbf1a
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/frog-english.tex
@@ -0,0 +1,16 @@
+\SetTxt{September Quote}{%
+silent new lake\\
+let the frog jump\\
+not even a sound
+
+\textit{-- Ryokan}%
+}
+
+\newcommand\SeptMarks{%
+ if (equals=2018-09-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}
+
+\SetTxt{Sept Events}{%
+{\dejaVuSans\char"263C} Sept 21: September 21
+}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/frog-hungarian.tex b/macros/luatex/latex/wallcalendar/doc/examples/frog-hungarian.tex
new file mode 100644
index 0000000000..b1feb00444
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/frog-hungarian.tex
@@ -0,0 +1,16 @@
+\SetTxt{September Quote}{%
+hallgat az új tó\\
+ugorhat béka belé\\
+vize se csobban
+
+\textit{-- Rjókan}%
+}
+
+\newcommand\SeptMarks{%
+ if (equals=2018-09-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}
+
+\SetTxt{Sept Events}{%
+{\dejaVuSans\char"263C} Szept 21: Szeptember 21
+}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/frog-japanese.tex b/macros/luatex/latex/wallcalendar/doc/examples/frog-japanese.tex
new file mode 100644
index 0000000000..b98bd8d9d9
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/frog-japanese.tex
@@ -0,0 +1,16 @@
+\SetTxt{September Quote}{%
+{\mincho æ–°æ± ã‚„è›™ã¨ã³ã“む音もãªã—}
+
+{\Large\textit{araike ya / kawazu tobikomu / oto mo nashi}}
+
+{\mincho 良寛}%
+}
+
+\newcommand\SeptMarks{%
+ if (equals=2018-09-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}
+
+\SetTxt{Sept Events}{%
+{\dejaVuSans\char"263C} {\mincho 9月 21æ—¥: ã¾ã“ã¨ã« 9月 21æ—¥}
+}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/frog.tex b/macros/luatex/latex/wallcalendar/doc/examples/frog.tex
new file mode 100644
index 0000000000..0041921bdf
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/frog.tex
@@ -0,0 +1,19 @@
+\makeatletter
+
+\SetPhoto[bleed=3mm, file={frog-crop}]{September}
+
+\SetQuote[xOffset=0pt, yOffset=-140mm]{September}{%
+\raggedleft\setlength{\parskip}{10pt}\HUGE\color{white}%
+\txt{September Quote}%
+}
+
+\SetCalendar[bg/.style={opacity=0.4}]{September}
+
+\SetEvents{September}{%
+\SeptMarks%
+}{%
+\raggedleft
+\txt{Sept Events}
+}
+
+\makeatother
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/local-english.sty b/macros/luatex/latex/wallcalendar/doc/examples/local-english.sty
new file mode 100644
index 0000000000..24b4238b04
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/local-english.sty
@@ -0,0 +1,6 @@
+\ProvidesPackage{local-english}
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/local-hungarian.sty b/macros/luatex/latex/wallcalendar/doc/examples/local-hungarian.sty
new file mode 100644
index 0000000000..d63edb10ed
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/local-hungarian.sty
@@ -0,0 +1,6 @@
+\ProvidesPackage{local-hungarian}
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/local-japanese.sty b/macros/luatex/latex/wallcalendar/doc/examples/local-japanese.sty
new file mode 100644
index 0000000000..dfe1af5a14
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/local-japanese.sty
@@ -0,0 +1,23 @@
+\ProvidesPackage{local-japanese}
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+% Japanese font
+\newfontfamily\mincho{IPAPMincho}
+
+% Renew formatting hooks to use the \mincho font
+\renewcommand\fullPageFmt{%
+ \renewcommand*\monthFmt{\LARGE\mincho}%
+ \renewcommand*\yearFmt{\LARGE\mincho}%
+ \renewcommand*\dayLetterColor{}%
+ \renewcommand*\dayLetterFmt{\tiny\mincho}%
+ \renewcommand*\dayTextFmt{\small}%
+ \renewcommand*\quoteFmt{}%
+ \renewcommand*\headingFmt{\centering}%
+ \renewcommand*\calendarFmt{\centering}%
+ \renewcommand*\eventsFmt{%
+ \setlength{\parindent}{0pt}\raggedleft\footnotesize%
+ }%
+}
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/photos/frog-crop-thumb.jpg b/macros/luatex/latex/wallcalendar/doc/examples/photos/frog-crop-thumb.jpg
new file mode 100644
index 0000000000..1786521952
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/photos/frog-crop-thumb.jpg
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/photos/frog-crop.jpg b/macros/luatex/latex/wallcalendar/doc/examples/photos/frog-crop.jpg
new file mode 100644
index 0000000000..e02e07bf4e
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/photos/frog-crop.jpg
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/photos/frog.jpg b/macros/luatex/latex/wallcalendar/doc/examples/photos/frog.jpg
new file mode 100644
index 0000000000..d91cc82add
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/photos/frog.jpg
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/examples/photos/obscure-crop.jpg b/macros/luatex/latex/wallcalendar/doc/examples/photos/obscure-crop.jpg
new file mode 100644
index 0000000000..98d26552ee
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/examples/photos/obscure-crop.jpg
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/doc/frontpage.tex b/macros/luatex/latex/wallcalendar/doc/frontpage.tex
new file mode 100644
index 0000000000..8b18f4267b
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/frontpage.tex
@@ -0,0 +1,103 @@
+\bigskip
+
+\thispagestyle{empty}
+
+This is the \textbf{User Manual} for the \texttt{wallcalendar} class.
+\textbf{Source documentation} is in \texttt{wallcalendar-code.pdf}. Clone or
+download from Github:
+
+\href{https://github.com/profound-labs/wallcalendar/}{https://github.com/profound-labs/wallcalendar/}
+
+The documentclass comes with the following layouts:
+
+\bigskip
+
+\makeatletter
+\newlength\exampleWidth
+\setlength{\exampleWidth}{45mm}
+\makeatother
+
+\begin{extrafullwidth}
+
+\hfill
+\begin{minipage}{0.31\linewidth}
+\centering
+
+Full page photo, the calendar days\\
+overlaid with opacity
+
+\bigskip
+
+\frame{\includegraphics[width=\exampleWidth]{cal-plain-01}}
+
+\end{minipage}%
+\begin{minipage}{0.31\linewidth}
+\centering
+
+Full page photo, the photo above\\
+the calendar days
+
+\bigskip
+
+\frame{\includegraphics[width=\exampleWidth]{cal-plain-02}}
+
+\end{minipage}%
+\begin{minipage}{0.31\linewidth}
+\centering
+
+Small landscape photo, with a\\
+calendar grid
+
+\bigskip
+
+\frame{\includegraphics[width=\exampleWidth]{cal-plain-03}}
+
+\end{minipage}
+\hfill\mbox{}
+
+\end{extrafullwidth}
+
+\bigskip
+
+\begin{extrafullwidth}
+
+\hfill
+\begin{minipage}{0.31\linewidth}
+\centering
+
+Load event marks from CSV file
+
+\bigskip
+
+\frame{\includegraphics[width=\exampleWidth]{./examples/cal-marks.pdf}}
+
+\end{minipage}%
+\begin{minipage}{0.31\linewidth}
+\centering
+
+Year planner
+
+\bigskip
+
+\frame{\includegraphics[width=\exampleWidth]{./examples/cal-year-planner.pdf}}
+
+\end{minipage}%
+\begin{minipage}{0.31\linewidth}
+\centering
+
+Thumbnails and captions
+
+\bigskip
+
+\frame{\includegraphics[width=\exampleWidth]{./examples/cal-thumbnails.pdf}}
+
+\end{minipage}
+\hfill\mbox{}
+
+\end{extrafullwidth}
+
+\clearpage
+
+\tableofcontents*
+\clearpage
+
diff --git a/macros/luatex/latex/wallcalendar/doc/latexmkrc b/macros/luatex/latex/wallcalendar/doc/latexmkrc
new file mode 100644
index 0000000000..cc8e5bd5c9
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/latexmkrc
@@ -0,0 +1,4 @@
+$pdf_mode = 4;
+$postscript_mode = $dvi_mode = 0;
+$lualatex = 'lualatex -shell-escape -interaction=nonstopmode -halt-on-error %O %S';
+$pdf_previewer = 'evince %O %S';
diff --git a/macros/luatex/latex/wallcalendar/doc/local.sty b/macros/luatex/latex/wallcalendar/doc/local.sty
new file mode 100644
index 0000000000..d57f87f567
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/local.sty
@@ -0,0 +1,70 @@
+\ProvidesPackage{local}
+
+\maxtocdepth{chapter}
+
+\definecolor{base03}{HTML}{002B36}
+\definecolor{base02}{HTML}{073642}
+\definecolor{base01}{HTML}{586E75}
+\definecolor{base00}{HTML}{657B83}
+\definecolor{base0}{HTML}{839496}
+\definecolor{base1}{HTML}{93A1A1}
+\definecolor{base2}{HTML}{EEE8D5}
+\definecolor{base3}{HTML}{FDF6E3}
+\definecolor{yellow}{HTML}{B58900}
+\definecolor{orange}{HTML}{CB4B16}
+\definecolor{red}{HTML}{DC322F}
+\definecolor{magenta}{HTML}{D33682}
+\definecolor{violet}{HTML}{6C71C4}
+\definecolor{blue}{HTML}{268BD2}
+\definecolor{cyan}{HTML}{2AA198}
+\definecolor{green}{HTML}{859900}
+
+\colorlet{background}{base3}
+\colorlet{primary-content}{base00}
+\colorlet{bg-highlight}{base2}
+\colorlet{secondary-content}{base1}
+%\colorlet{list-content}{base0}
+\colorlet{list-content}{primary-content}
+\colorlet{list-bullets}{orange}
+\colorlet{lvl1-color}{primary-content}
+\colorlet{lvl2-color}{primary-content}
+\colorlet{lvl3-color}{yellow}
+\colorlet{lvl4-color}{green}
+
+\colorlet{code-bg}{base3}
+
+\usepackage{minted}
+
+\setminted{bgcolor=code-bg, fontsize=\footnotesize}
+\setmintedinline{bgcolor={}}
+
+\newminted{tex}{frame=single}
+
+\renewenvironment{verbatim}{%
+ \VerbatimEnvironment%
+ \begin{texcode}%
+}{%
+ \end{texcode}%
+}
+
+\newcommand{\twocol}[2]{%
+\begin{minipage}[b][8.7cm][c]{0.5\linewidth}%
+\centering
+#1%
+\end{minipage}%
+\begin{minipage}[b][8.7cm][c]{0.5\linewidth}%
+\centering
+#2%
+\end{minipage}%
+}
+
+\newcommand{\twocolcaption}[2]{%
+\begin{minipage}{0.5\linewidth}%
+\centering
+#1%
+\end{minipage}%
+\begin{minipage}{0.5\linewidth}%
+\centering
+#2%
+\end{minipage}%
+} \ No newline at end of file
diff --git a/macros/luatex/latex/wallcalendar/doc/memoir-article.cls b/macros/luatex/latex/wallcalendar/doc/memoir-article.cls
new file mode 100644
index 0000000000..5e73997d69
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/memoir-article.cls
@@ -0,0 +1,401 @@
+% Memoir Article Class
+%
+% A memoir-based documentclass for org-mode exports.
+%
+% (c) Gambhiro Bhikkhu, 2016
+% gambhiro.bhikkhu.85@gmail.com
+%
+% LPPL LaTeX Pubic Project Licence
+%
+
+% ==============
+% Identification
+% ==============
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{memoir-article}[2016/08/13 v0.2 A memoir-based documentclass for org-mode exports.]
+
+% ========================
+% Preliminary Declarations
+% ========================
+
+% =======
+% Options
+% =======
+
+\RequirePackage{pgfopts}
+\RequirePackage{calc}
+
+\pgfkeys{
+ /BOOK/.cd,
+}
+
+% Pass all unknown options to memoir
+\DeclareOption*{%
+ \PassOptionsToClass{\CurrentOption}{memoir}
+}
+
+\ProcessPgfOptions{/BOOK}
+\ProcessOptions\relax
+
+% ======================
+% All Other Declarations
+% ======================
+
+\LoadClass{memoir}
+
+\RequirePackage[british]{babel}
+
+%\RequirePackage{amssymb}% Does any symbol need it?
+\RequirePackage{amsmath}
+\RequirePackage[bitstream-charter]{mathdesign}
+
+\RequirePackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont[
+ ItalicFont = Crimson Italic,
+ BoldFont = Crimson Bold,
+ BoldItalicFont = Crimson BoldItalic,
+ Numbers = Lining,
+]{Crimson Roman}
+
+\newfontfamily\crimsonRomanFont[
+ ItalicFont = Crimson Italic,
+ BoldFont = Crimson Bold,
+ BoldItalicFont = Crimson BoldItalic,
+ Numbers = Lining,
+]{Crimson Roman}
+
+\newfontfamily\crimsonRomanFontOldNum[
+ ItalicFont = Crimson Italic,
+ BoldFont = Crimson Bold,
+ BoldItalicFont = Crimson BoldItalic,
+ Numbers = OldStyle,
+]{Crimson Roman}
+
+\newfontfamily\logicFont[
+ SmallCapsFont = Crimson Bold,
+ SmallCapsFeatures= { Ligatures = TeX, Letters = SmallCaps, Scale = 0.8, LetterSpace = 0.2 },
+]{Crimson Roman}
+
+\RequirePackage{xcolor}
+\RequirePackage{graphicx}
+\RequirePackage{enumitem}
+\RequirePackage{multicol}
+\RequirePackage{hyperref}
+\RequirePackage{titletoc}
+\RequirePackage{eso-pic}
+
+\graphicspath{{./includes/}}
+
+\hypersetup{
+ colorlinks=true,
+ linkcolor=link,
+ citecolor=link,
+ filecolor=link,
+ urlcolor=link,
+ unicode=true,
+}
+
+\RequirePackage[
+ open,
+ openlevel=2
+]{bookmark}
+
+\setlist[itemize]{
+ itemindent=0pt,
+ leftmargin=15pt,
+ rightmargin=0pt,
+ itemsep=3pt,
+ topsep=0pt,
+ parsep=0pt,
+ partopsep=0pt,
+}
+
+\hyphenation{under-lying astron-o-mer}
+
+% === penalties ===
+
+\midsloppy
+
+% === normalsize ===
+
+\definecolor{textbody}{gray}{0}
+\definecolor{linkred}{HTML}{DC322F}
+% Red is better for printing than blue or dark blue
+\colorlet{link}{linkred}
+
+\definecolor{tocleftside}{gray}{0.5}
+\definecolor{tocleftsidepart}{gray}{0.2}
+\definecolor{partname}{gray}{0.5}
+\definecolor{parttitle}{gray}{0.5}
+
+\def\BOOK@apt{11}
+\def\BOOK@bpt{14}
+
+\renewcommand{\normalsize}{%
+ \@setfontsize\normalsize\BOOK@apt\BOOK@bpt
+ \abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@
+ \abovedisplayshortskip \z@ \@plus3\p@
+ \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
+ \belowdisplayskip \abovedisplayskip
+ \color{textbody}
+ \let\@listi\@listI}
+\normalsize
+
+% === indentations ===
+
+\setlength{\parskip}{5pt}
+\setlength{\parindent}{0pt}
+
+\setlength{\columnsep}{18pt}
+\setlength{\columnseprule}{0pt}
+%\setlength{\columnseprule}{0.1pt}
+%\flushcolumns
+\raggedcolumns
+
+%\columnseprulecolor
+
+% === setup page layout ===
+
+\stockaiv
+\settrimmedsize{\stockheight}{\stockwidth}{*}
+\settrims{0pt}{0pt}
+\setlrmarginsandblock{0.1\paperwidth}{*}{3}
+\setulmarginsandblock{0.1\paperheight}{0.1\paperheight - 2\baselineskip}{*}
+\setheadfoot{\baselineskip}{\baselineskip}
+\setheaderspaces{*}{15pt}{*}
+\setfootins{2\baselineskip}{\bigskipamount}
+
+\setmarginnotes{17pt}{45mm}{20pt}
+%\addtolength{\marginparsep}{10pt}
+%\addtolength{\marginparwidth}{-18mm}
+
+\checkandfixthelayout
+
+\setcounter{secnumdepth}{4}
+
+%% abstract
+
+\setlength{\absparindent}{0pt}
+%\setlength{\absleftindent}{0.15\linewidth}
+%\setlength{\absrightindent}{0.15\linewidth}
+\setlength{\absleftindent}{2em}
+\setlength{\absrightindent}{2em}
+
+%% summary
+
+\newenvironment{summary}%
+ {\list{}{\listparindent 0pt%
+ \itemindent \listparindent
+ \rightmargin \leftmargin
+ \parsep \z@ \@plus\p@}%
+ \item[]}%
+ {\endlist}
+
+% === TOC settings ===
+
+\maxtocdepth{subsection}
+
+% Fixes Undefined control sequence error for \@chapapp@head
+\renewcommand\chapternumberline[1]{\numberline{#1}}
+\renewcommand\partnumberline[1]{\numberline{#1}}
+
+% Fixes Missing number error when chapter number is not numeric, as in
+% Appendix A
+\let\ttll@appendix\ttll@chapter
+
+% the right TOC margin
+\contentsmargin{0pt}
+
+\newlength\tocLeftWidth
+\setlength\tocLeftWidth{6pc}
+
+\titlecontents{chapter}[\tocLeftWidth]
+{\addvspace{10pt}%
+\Large\crimsonRomanFont}%
+{%
+ \contentsmargin{0pt}%
+ \makebox[0pt][r]{%
+ {\color{tocleftside}%
+ \Large Section~{\crimsonRomanFont\thecontentslabel}}%
+ \hspace*{0.5em}$\cdot$\hspace*{0.5em}%
+ }%
+}
+{\contentsmargin{0pt}%
+\vspace*{-10pt}%
+\itshape}
+{\enspace\hfill\normalsize\crimsonRomanFont\thecontentspage}
+[\addvspace{5pt}]
+
+\titlecontents{section}[\tocLeftWidth]
+{\addvspace{2pt}%
+\normalsize\crimsonRomanFont}
+{%
+ \contentsmargin{0pt}%
+ \makebox[0pt][r]{%
+ {\color{tocleftside}%
+ \normalsize {\crimsonRomanFont\thecontentslabel}}%
+ \hspace*{1.53em}%
+ }%
+}
+{}
+{\hfill\normalsize\crimsonRomanFont\thecontentspage}
+
+\titlecontents{subsection}[\tocLeftWidth]
+{\addvspace{2pt}%
+\normalsize\crimsonRomanFont}
+{%
+ \contentsmargin{0pt}%
+ \makebox[0pt][r]{%
+ {\color{tocleftside}%
+ \normalsize {\crimsonRomanFont\thecontentslabel}}%
+ \hspace*{1.53em}%
+ }%
+}
+{}
+{\hfill\normalsize\crimsonRomanFont\thecontentspage}
+
+% === end of TOC settings ===
+
+%\setmarginfloatcaptionadjustment{figure}{\captionstyle{\mpjustification}}
+\captionnamefont{\footnotesize}
+\captiontitlefont{\footnotesize}
+
+\newenvironment{fullwidth}{%
+ \begin{minipage}{\textwidth + \marginparsep + \marginparwidth}%
+}{%
+ \end{minipage}%
+}
+
+\newenvironment{extrafullwidth}{%
+ \hskip -\spinemargin
+ \hskip 5mm
+ \begin{minipage}{\paperwidth - 10mm}%
+}{%
+ \end{minipage}%
+}
+
+\newlength\marginDiff
+\newcommand\includemap[1]{%
+ {\centering
+ \setlength\marginDiff{0.98\paperwidth - \linewidth}
+ \hspace*{-0.5\marginDiff}
+ \includegraphics[width=0.98\paperwidth]{#1}
+ \par}
+}
+
+\usepackage[normalem]{ulem}
+
+\newcommand\secunderline[1]{%
+ \begingroup%
+ \renewcommand{\ULdepth}{4pt}%
+ \renewcommand{\ULthickness}{0.5pt}%
+ \uline{#1}%
+ \endgroup%
+}
+
+\newcommand{\sectionFmt}[1]{%
+ \normalfont\memRTLraggedright\scshape
+ \secunderline{#1}%
+}
+
+\newcommand\mA\textasteriskcentered
+
+\newcommand\docVersion{v0.1}
+\newcommand\docUrl{\href{http://github.com/profound-labs/}{download}}
+
+\newif\ifshowdocinfo
+\showdocinfotrue
+
+\def\@maketitle{%
+ \begin{minipage}{\linewidth}%
+ \raggedright
+ \LARGE\scshape\MakeTextLowercase{\thetitle}
+ \vskip\onelineskip \hrule
+ \ifshowdocinfo
+ \vskip 5pt
+ {\upshape\footnotesize \docVersion\ $\cdot$ \today\ $\cdot$ \docUrl}
+ \fi
+ \vskip\onelineskip
+ \end{minipage}%
+}
+
+\renewcommand{\backmatter}{%
+ \@mainmatterfalse
+ \setcounter{secnumdepth}{-10}
+ \ifartopt\else
+ \@memback@floats
+ \fi}
+
+\hangsecnum
+
+\gdef\clearforchapter{\par\bigskip}
+
+\makechapterstyle{vinaya-class}{%
+ \chapterstyle{default}
+ \renewcommand*{\chaptitlefont}{\LARGE\scshape}
+ \renewcommand*{\chapnumfont}{\chaptitlefont}
+ \settowidth{\chapindent}{\normalsize 999}
+ \renewcommand*{\chapterheadstart}{}
+ \renewcommand*{\printchaptername}{}
+ \renewcommand*{\chapternamenum}{}
+ \renewcommand*{\printchapternum}{%
+ \noindent\llap{\makebox[\chapindent][l]{\chapnumfont \MakeTextLowercase{\thechapter}}}}
+ \renewcommand*{\afterchapternum}{}
+ \renewcommand*{\printchaptertitle}[1]{%
+ \memRTLraggedright\chaptitlefont\MakeTextLowercase{##1}}
+ \renewcommand*{\afterchaptertitle}{}}
+
+\makeheadstyles{vinaya-class}{%
+\chapterstyle{vinaya-class}
+ \setbeforesecskip{1\onelineskip
+ \@plus -0.5\onelineskip \@minus -.5\onelineskip}%
+ \setaftersecskip{1\onelineskip \@plus 0.1\onelineskip}%
+ \setsecheadstyle{\sectionFmt}%
+ \setbeforesubsecskip{-1.0\onelineskip
+ \@plus -0.25\onelineskip \@minus -0.25\onelineskip}%
+ \setaftersubsecskip{1.0\onelineskip \@plus 0.1\onelineskip}%
+ \setsubsecheadstyle{\sethangfrom{\noindent ####1}\normalfont\itshape\memRTLraggedright}%
+ \setbeforesubsubsecskip{1.0\onelineskip
+ \@plus 0.5\onelineskip \@minus 0.2\onelineskip}%
+ \setaftersubsubsecskip{-1em}%
+ \setsubsubsecheadstyle{\normalfont\normalsize\scshape\MakeTextLowercase}%
+ \setbeforeparaskip{1.0\onelineskip
+ \@plus 0.5\onelineskip \@minus 0.2\onelineskip}%
+ \setafterparaskip{-1em}%
+ \setparaheadstyle{\normalfont\normalsize\itshape\addperiod}%
+ \setsubparaindent{\parindent}%
+ \setbeforesubparaskip{1.0\onelineskip
+ \@plus 0.5\onelineskip \@minus 0.2\onelineskip}%
+ \setaftersubparaskip{-1em}%
+ \setsubparaheadstyle{\normalfont\normalsize\itshape\addperiod}}
+
+%% Based on bringhurst from memoir.
+\headstyles{vinaya-class}
+\aliaspagestyle{chapter}{empty}
+
+\makepagestyle{normalpage}
+ \makeevenhead{normalpage}{\thepage}{}{}
+ \makeoddhead{normalpage}{}{}{\thepage}
+
+\pagestyle{normalpage}
+
+\newcommand\fullpage[1]{%
+\clearpage
+\pagestyle{empty}
+\mbox{}
+\AddToShipoutPictureFG*{\put(0,0)%
+{\begin{minipage}[b][\paperheight][t]{\paperwidth}%
+#1
+\end{minipage}%
+}}%
+}
+
+\newfontfamily\articleThaiFont{Kinnari}
+
+\newcommand*\thai[1]{{\articleThaiFont #1}}
+
+\newcommand*\logic[1]{\textsc{\logicFont \MakeTextUppercase{#1}}}
+
+\RequirePackage[final,babel=true]{microtype}
diff --git a/macros/luatex/latex/wallcalendar/doc/wallcalendar-code.fdb_latexmk b/macros/luatex/latex/wallcalendar/doc/wallcalendar-code.fdb_latexmk
new file mode 100644
index 0000000000..c57a7c6582
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/wallcalendar-code.fdb_latexmk
@@ -0,0 +1,315 @@
+# Fdb version 3
+["lualatex"] 1508557085 "wallcalendar-code.tex" "wallcalendar-code.pdf" "wallcalendar-code" 1508557092
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/cm/cmr10.tfm" 1480098701 1296 45809c5a464d5f32c8f98ba97c1bb47f ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/latex-fonts/lasy6.tfm" 1480098711 520 4889cce2180234b97cad636b6039c722 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7m.tfm" 1480098713 1096 439ec4b98c555f12eea982637b110636 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7t.tfm" 1480098713 824 e84dc8fd7ce1699c13a4cf301fc14b98 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7v.tfm" 1480098713 1716 e946b26d80be2b9854dce098cc7d4fd7 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7y.tfm" 1480098713 1292 7fc44b79287974dee41abfbedfb7865b ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8t.tfm" 1480098713 992 b635bd892c5f064cc4c7d172e94c7fc9 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8y.tfm" 1480098713 1604 95b3dfa8282f3b7807ebdf0f30ea7999 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri7m.tfm" 1480098713 1224 9850779b08ad329e12c2833d0dafbe70 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri8y.tfm" 1480098713 1756 3d33d9b711f92f3b1d172cbde87d8eb9 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrma.tfm" 1480098713 1556 c4bf54c8a83dd5442e3b71832eaeadb9 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrmb.tfm" 1480098713 952 1926e68757e9e379908f2c92702ff79e ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7m.tfm" 1480098713 1912 3774e5b1985837341ac15e2fbf989d37 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7t.tfm" 1480098713 2432 cf1427228b6c296ea72c1f8156ad979e ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7v.tfm" 1480098713 1704 f91561740916e2d61a9058a84b4d9fc1 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7y.tfm" 1480098713 1572 3fc0444ad8dd329928c5ca8defbcf7a6 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr8t.tfm" 1480098713 8360 341689117e63b5758239dd13e95d159f ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchri7m.tfm" 1480098713 2368 27f64c6ef12e9897228332e172c5c52e ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrma.tfm" 1480098713 1540 0350be4ad7ceeb70ba36a7382ef56de3 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrmb.tfm" 1480098713 952 664d6d6cf6e32bba3afae5d25cb251fa ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/type1/public/mathdesign/mdbch/md-chr7y.pfb" 1480098742 26162 bd4b2cdc5229167b72fc13a07768bc17 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7m.vf" 1480098768 976 49b9aa83c3e7a1ac811f7895854cc7a4 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7t.vf" 1480098768 976 862fa3ae193f69aabcce6a8c0b3499c2 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7v.vf" 1480098768 1612 6fe703a6a685d4c4f84414e8687e1785 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7y.vf" 1480098768 836 7c23d0fba34243bfaba30e51eed87f22 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr8t.vf" 1480098768 2224 103bf0af1df04f28e57b118a8f5d1915 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchri7m.vf" 1480098768 1148 f010126386d8bba99c9c766ac714b8b8 ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrma.vf" 1480098768 1408 9effdb6efbd1999b4c7c1e048c3f8d4c ""
+ "/home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrmb.vf" 1480098768 472 a41d9bc80344ccff0e35bfcc60398f89 ""
+ "/home/yume/texlive/2017/texmf-dist/scripts/oberdiek/oberdiek.luatex.lua" 1480098773 1972 1fb7c07d88e23d4594015b8b0aa21544 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/context/base/mkii/supp-pdf.mkii" 1480098806 71627 94eb9990bed73c364d7f53f960cc8c5b ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/babel-english/british.ldf" 1496785618 2764 33eb54e29f49ae828edec697cf357f2c ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/babel-english/english.ldf" 1496785618 7008 9ff5fdcc865b01beca2b0fe4a46231d4 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/babel/babel.def" 1495227874 56906 5fe966833cc01ad71361044f6df6de8f ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/babel/babel.sty" 1495227874 15289 de2791ae2b2b7f83883060d1307dfea0 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/babel/luababel.def" 1493414436 12715 d432e759d832bd2bbb3d7c3c4b471ddc ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/hyph-utf8/loadhyph/loadhyph-en-gb.tex" 1480098814 632 24008d5464e24adac94ddcaefe61e6c3 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/hyph-utf8/patterns/tex/hyph-en-gb.tex" 1480098814 57395 a8d3e207a4c0880029ff8d88d96aa7de ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/ifxetex/ifxetex.sty" 1480098815 1458 43ab4710dc82f3edeabecd0d099626b2 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/luatex85/luatex85.sty" 1480098815 5870 5c4dd54f0f0c0983167985107b28c800 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/catchfile.sty" 1480098815 8493 e586100f117d095256a1a5c630c3fa25 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/gettitlestring.sty" 1480098815 8237 3b62ef1f7e2c23a328c814b3893bc11f ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty" 1490564930 185082 1fb09d7d24834377f95006300bc91fd2 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty" 1480098815 70864 bcd5b216757bd619ae692a151d90085d ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/ifluatex.sty" 1480098815 7324 2310d1247db0114eb4726807c8837a0e ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/ifpdf.sty" 1490564930 1251 d170e11a3246c3392bc7f59595af42cb ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex" 1480098816 36194 e194ef4e0b396b531a3891feb4b1cc22 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex" 1480098816 33377 af391d6ad1bfcbe2278e191f48e43ba8 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/ulem/ulem.sty" 1480098819 23756 854c01b779030ff5b2aad88ba7a119f2 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/unicode-data/CaseFolding.txt" 1480098819 78161 e3fbf2f626f10070000fe66f3a2ff5ef ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/unicode-data/SpecialCasing.txt" 1480098819 16830 fea30f45a2f81ffa474fd984d297e2ea ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/unicode-data/UnicodeData.txt" 1480098819 1686443 dde25b1cf9bbb4ba1140ac12e4128b0b ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/xkeyval/xkeyval.tex" 1480098819 19231 26434a5656c684f5ffb1f26f98006baa ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/xkeyval/xkvutils.tex" 1480098819 7677 6f5ce7c1124cad7ec57d05b2562bd8fe ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/xstring/xstring.sty" 1480098819 144 0ca8d67b000b795a4d9ec000e0fd09c7 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/generic/xstring/xstring.tex" 1480098819 54373 fd4487ae3e45d4074bc89aea1d2b6807 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amsbsy.sty" 1480098820 2210 5c54ab129b848a5071554186d0168766 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amsgen.sty" 1480098820 4160 c115536cf8d4ff25aa8c1c9bc4ecb79a ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amsmath.sty" 1485129665 84329 81aa65c5042562f79cb421feff9b8bdc ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amsopn.sty" 1480098820 4115 318a66090112f3aa3f415aeb6fe8540f ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amstext.sty" 1480098820 2431 fe3078ec12fc30287f568596f8e0b948 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/base/fontenc.sty" 1492297155 4571 13977df0eda144b93597fc709035ad1f ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/base/ifthen.sty" 1480098821 5159 a08c9bbd48fc492f15b22e458bef961f ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/base/t1enc.def" 1492297155 10006 a90ba4035cf778f32f424e297d92e235 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/base/textcomp.sty" 1492297155 16154 f2c73e20ca771d534a8516c62c6b0eae ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/base/ts1cmr.fd" 1480098821 2217 d274654bda1292013bdf48d5f720a495 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/base/ts1enc.def" 1480098821 7767 aa88823823f5e767d79ea1166ab1ae74 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/base/tuenc.def" 1492297155 27166 081ef1345bf363faf81b61c2450b871f ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/enumitem/enumitem.sty" 1480098827 42666 6fa770e3485520a6a5f2ea7d259c8f8d ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/eso-pic/eso-pic.sty" 1480098827 11954 3abdeb9fbc956bcd048295dd83dd5e7c ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/etoolbox/etoolbox.sty" 1483484472 42324 d951db30d0cb2b811f084fa3f92aec16 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/fancyvrb/fancyvrb.sty" 1480098827 45360 a0833d32f1b541964596b02870342d5a ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/float/float.sty" 1480098828 6749 16d2656a1984957e674b149555f1ea1d ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/fontspec/fontspec-luatex.sty" 1491002578 133545 96f02df61cf9a85971280bdcd04d4cac ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/fontspec/fontspec.cfg" 1491002578 549 e7553134efaf62922106a54300834ab9 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/fontspec/fontspec.sty" 1491002578 1704 f155bd31324526584df93d8880629e82 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/framed/framed.sty" 1480098829 22449 7ec15c16d0d66790f28e90343c5434a3 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/fvextra/fvextra.sty" 1480098829 47730 6185e4a6ef29955beffed43ff00f29f2 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/graphics-cfg/color.cfg" 1480098830 1213 620bba36b25224fa9b7e1ccb4ecb76fd ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/graphics-cfg/graphics.cfg" 1480098830 1224 978390e9c2234eab29404bc21b268d1e ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/graphics-def/luatex.def" 1498170935 15753 2523b785bfc0cfc8d314c17b8a4e7fdc ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/graphics/graphics.sty" 1497474997 15252 cc34a2eaf7d6619154fcdb710437d969 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/graphics/graphicx.sty" 1497303813 9009 1d5a6dabcb8a84c292887f6216d2e358 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/graphics/keyval.sty" 1480098830 2594 d18d5e19aa8239cf867fa670c556d2e9 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/graphics/trig.sty" 1480098830 3980 0a268fbfda01e381fa95821ab13b6aee ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/hluatex.def" 1489964469 51673 195795251fcdb21aa9ed776b343cb613 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/hyperref.sty" 1489964469 233808 b63d91422c362e723c6e8b1a2fffcba5 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/nameref.sty" 1480098831 12949 81e4e808884a8f0e276b69410e234656 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/pd1enc.def" 1489964469 14098 7631f11156e5f9cd76010dbd230aa268 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/puenc.def" 1489964469 122411 7c1f7e015c7fc4bfb7dc052d55755ce3 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/ifetex/ifetex.sty" 1480098831 1571 45d3cd316bdf45071542b57b1784c273 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/ifplatform/ifplatform.sty" 1480098831 3847 7836cfc12cc39575e0ea1f4b4bc16b1a ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/l3kernel/expl3-code.tex" 1496704628 814030 ad0edaa2c394049a04bca4a0710c7645 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/l3kernel/expl3.sty" 1496704628 9344 6ab2e01e9c1ab6ce737738fc1114e67c ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/l3kernel/l3pdfmode.def" 1496704628 12430 d675b0ae6b2df644da3a987c178c95b3 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/l3packages/xparse/xparse.sty" 1496704628 76757 b04b2093556b41ac7708c6010bf0b6b6 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg" 1480098833 678 4792914a8f45be57bb98413425e4c7af ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/latexconfig/hyperref.cfg" 1480098833 235 6031e5765137be07eed51a510b2b8fb7 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/lineno/lineno.sty" 1480098833 151738 8cd767481920f0eb785302dacfc87057 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mathdesign.sty" 1480098833 9111 d865fc87f99dbc5273fb00f1d7091d76 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdacmr.fd" 1480098833 579 116e648415099e5e059da594ef56c9f0 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/mdamdbch.fd" 1480098833 466 324e7624bf5a1f058d84a000f896be0e ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/mdbch.cfg" 1480098833 3290 abec71f631daf0a248e163831a11c44a ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/mdbch.sty" 1480098833 44904 3ab78ef74bc1c8fe8dfba974db6c0530 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/mdbmdbch.fd" 1480098833 466 5beaec62907c8aeedee3450e356ef2b0 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/omlmdbch.fd" 1480098833 874 5a879826c52b0deec25c4c5a08bf428f ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/omsmdbch.fd" 1480098833 485 0da1597752b6fe9df95c05be6167a1d2 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/omxmdbch.fd" 1480098833 466 4c44b6662bc4833f3658bac38cfff58c ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/ot1mdbch.fd" 1480098833 895 2fc6be6e6eeeac5bb6ad0987e5118413 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/t1mdbch.fd" 1480098833 1576 ef5fa780517f1888ed11274c3aff9276 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbcmr.fd" 1480098833 579 ddcbed007a246f2b5a98aedc86efeed0 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdfont.def" 1480098833 5878 bba53c9220a1555c41919107cf6f41c3 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdsffont.def" 1480098833 16973 0d74f58659233f7bbf4e2551e5c1b6ba ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdttfont.def" 1480098833 9718 378a12581d907c0af4433a9e908339df ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/memoir/mem11.clo" 1480098834 4077 2f2af8e7cb6e684fbd08a4498608691a ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/memoir/memhfixc.sty" 1480098834 11285 dbd4440be337fece041abdf4e6e17516 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/memoir/memoir.cls" 1480098834 403550 cf3b1268347cbf0206bbe925178c9579 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/memoir/mempatch.sty" 1480098834 1325 61d651ec19190481219253f142256d58 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/microtype/microtype-luatex.def" 1480098834 39150 722d307664351328b536ba38404a0f79 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/microtype/microtype.cfg" 1480098834 23387 9deaa7c030891bce421bba5f9c5433a7 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/microtype/microtype.sty" 1480098834 69336 602ce3b04d564c4a68a410d44eb7653e ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/microtype/mt-bch.cfg" 1480098834 8928 53d515d1f327f48b6b4d06ca2e798a43 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/minted/minted.sty" 1480098835 47560 318a27606ddee4b82123bf3746fcc8a8 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/auxhook.sty" 1480098836 3834 4363110eb0ef1eb2b71c8fcbcdb6c357 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/bkm-pdftex.def" 1480098836 8382 d027b9fab7440aa0716d4a2e9455eeca ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/bookmark.sty" 1480098836 18920 32621f3a02f5d05b1e35f55abc232aab ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/epstopdf-base.sty" 1480098836 12095 5337833c991d80788a43d3ce26bd1c46 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/grfext.sty" 1480098836 7075 2fe3d848bba95f139de11ded085e74aa ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/kvoptions.sty" 1480098836 22417 1d9df1eb66848aa31b18a593099cf45c ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty" 1480098836 9581 023642318cef9f4677efe364de1e2a27 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/pgf/utilities/pgfkeys.sty" 1480098837 274 4cad6e665cc93ac2ac979039a94fa1e1 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/pgfopts/pgfopts.sty" 1480098837 5540 d5c60cf09c59da351aa4023ed084e4eb ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/titlesec/titletoc.sty" 1480098841 18361 6f2961ec45ee4ad03439efe5de257c61 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/tools/calc.sty" 1480098841 10214 d03d065f799d54f6b7e9b175f8d84279 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/tools/multicol.sty" 1492297155 30180 4d723b83c66873ba53f72c4a8730d6d3 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/tools/shellesc.sty" 1480098841 3270 e11dab94d1e3fce5344c1b70f2af4abd ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/upquote/upquote.sty" 1480098842 1048 517e01cde97c1c0baf72e69d43aa5a2e ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/url/url.sty" 1480098842 12796 8edb7d69a20b857904dd0ea757c14ec9 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/xcolor/xcolor.sty" 1480098843 55589 34128738f682d033422ca125f82e5d62 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/latex/xkeyval/xkeyval.sty" 1480098843 4962 9c1069474ff71dbc47d5006555e352d3 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/ctablestack/ctablestack.sty" 1480098844 1510 9c109bd1f6a9fc69b2f6096ee416d958 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua" 1486339267 2685 01cf68c81eccdf10366f3f84158d2bc8 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-boolean.lua" 1480098844 1850 abe28515dd33e8f6c416c09bca351cf8 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-compat.lua" 1480098844 603 398583cb619d20952d67edcedae41608 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-dir.lua" 1486339267 17703 9ea92204a66366c1e44e5616f84f46a2 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua" 1486339267 4826 f09108bac11f85bb9fa04d868d666e63 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-file.lua" 1486339267 20997 32d9ba0a5cdd3509a3847bb050bfb800 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-function.lua" 1480098844 361 a7e68a9703c35238729da41a474e951b ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-gzip.lua" 1480098844 1211 9cdb8f316bdef565fb312b1099590701 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-io.lua" 1486339267 10014 ee77e357f5965196f9559b8fcccc6e71 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-lpeg.lua" 1480098845 37012 93b90b22d7d3600ddd9def9f3ad9a7bb ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-lua.lua" 1486339267 4535 5466b2db6d8cc3b9786a398bb4230ea1 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-math.lua" 1480098845 974 51275e81c652e3fbd7d02b1c383d3049 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-md5.lua" 1480098845 3248 8cad752e187261eabf9cde462a1eef81 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-number.lua" 1486339267 5358 bacbf8f2ff767e317d6ac2ba5930ec6a ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-os.lua" 1480098845 15832 a5a96e495876a7ccea203ac3cdcac40b ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-package.lua" 1480098845 10587 ecf99777107151998d886199ef5589dd ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-set.lua" 1480098845 1923 17868172ce396e1c5d0e9a672b8bdcb9 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-string.lua" 1486339267 5863 2ca01eeb225c09e73ff4f3a2d101827a ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-table.lua" 1486339267 37480 92978e5ea9ca13dae04fb606f5be4a1c ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua" 1486339267 6844 aeb4a209d048a47dc0526a1915da2258 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-unicode.lua" 1480098845 37427 eb7ac141175e74f69b1f303064ed91f8 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-url.lua" 1480098845 12531 555c5d1e1134654b5e5a679150cf11d2 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-deb.lua" 1480098845 3898 dedc408152fed20d666d41b93124de05 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-dim.lua" 1480098845 13522 456eee0716ac9758c73a82b638b97ef4 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-fil.lua" 1486339267 5548 0573e91847e722ffe0fcdb465ba89e6b ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua" 1486339267 5291 07fff8fbc3b6542771b6f5ee9ce8c8c3 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-lua.lua" 1486339267 5396 03f3d11a20846a41f46e89c4aebb457d ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-prs.lua" 1486339267 22883 9246f0f89dc599d472ce1b0b5ee9baee ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-sta.lua" 1480098845 9178 4840e537d4ecc144f7058d768e93715b ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-sto.lua" 1480098845 3926 bea61790df64287215ffa7dd1759a63f ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua" 1486339267 35499 513836cfea6a8027c1451a95bc74649f ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua" 1486339267 28471 cb1ae792cb08c524e4bc09b4f005f7f8 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-tpl.lua" 1480098845 7100 ccfb5023bc761673396964848d85b5e2 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/luaotfload/luaotfload-characters.lua" 1485820867 1548690 99578c3eff8b68cae3da45a4a7cbfcf2 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/luatex/luatexbase/luatexbase.sty" 1480098845 10170 b1a2248f43cab899e3fe36f676176865 ""
+ "/home/yume/texlive/2017/texmf-dist/tex/plain/ifetex/ifetex.tex" 1480098846 1166 4b66ad073c6073cb1bde651c18b7dbb2 ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/crimson-bold.luc" 1508251106 319783 6ffc6c1fee4a015e0b5a6dd2c3fdc243 ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/crimson-bolditalic.luc" 1508251107 213421 1b5e8536d6177dea5765d3d87d038a8a ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/crimson-italic.luc" 1508557082 288097 802201147b4e94b494251c27f2630e12 ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/crimson-roman.luc" 1508557082 406209 bd9fdb0c47bc81217f60e967e6f2f30a ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/kinnari-bold.luc" 1498655042 56575 5b99cf655cccc7b71b1c414b343a6345 ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/kinnari-bolditalic.luc" 1498655042 56897 4b2503dbbb116959342e677dd7a2b2bf ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/kinnari-oblique.luc" 1498655042 56893 2a7601c463cf9e701f6b375233cbf6f3 ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/kinnari.luc" 1508557082 56510 a1b595a01399b6181080d04fc7e014e2 ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmmono10-italic.luc" 1508251110 88435 8e7ae4209415f0980a6f82af03bb0f68 ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmmono12-regular.luc" 1500201767 87231 829b8f4073311294fee80ecce2b1fcca ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmmono9-regular.luc" 1499615145 87334 66dfd2bfed1ade9b3382ceafd2c1028e ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmmonolt10-bold.luc" 1508251109 87535 5e7f3f8496d49e104342ba9b7cc94506 ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmroman10-italic.luc" 1498655029 136748 2938cfabc4958f3102c65f9fdbb50dfa ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmroman10-regular.luc" 1498655028 134930 21ae8e5ca4a670444e1c1eec7381dfc4 ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmroman9-regular.luc" 1498655028 134723 b975b3691dd65fd7eceeefcc075110e0 ""
+ "/home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmromandemi10-regular.luc" 1508251104 135615 e9d81af70133f198d15d11c8b3bcf072 ""
+ "/home/yume/texlive/2017/texmf-var/tex/generic/config/language.dat" 1498457149 6539 4b4d7cb4ed3e101658be4b7ef5c92d33 ""
+ "/home/yume/texlive/2017/texmf-var/web2c/luatex/lualatex.fmt" 1498458080 1296757 8d6afb7dfa1c27ca3c4396511804af79 ""
+ "_minted-wallcalendar-code/033BBD01DF821E53BEF1F76066548A1B43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251386 688 50f14b90c87bc9191eaceea1570633c4 ""
+ "_minted-wallcalendar-code/0563FB1B1C7CB725F0CB598E22A0F9EE43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252519 685 c113e37556b731a97716ec27dbdbc79a ""
+ "_minted-wallcalendar-code/059DFC4ED0F176E43AAD50BAAFE2496F43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251398 230 04a5b850e506b9b2b291c88bfdf3764f ""
+ "_minted-wallcalendar-code/09AD78D3F767ADD7015D0F7C1E2E329043C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251384 277 2855eb5dc784ee569620b11f63e1e4d0 ""
+ "_minted-wallcalendar-code/0CCC8B6CA129D064C36E9FD59B79C03C43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251384 238 0c84ceac8e50b8b0f509f7117bf8fb01 ""
+ "_minted-wallcalendar-code/1937A9361D6B964B6AFB29EAFC328DDE43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251384 171 98910a1fbf5e09416d3b593252c803ef ""
+ "_minted-wallcalendar-code/1A403559330D34AB149955B0E49EFEA543C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251391 419 9fe47a2a101688baa4025cdf574b5557 ""
+ "_minted-wallcalendar-code/1DB198D4F7116DD69F7A04C4C14A2C1D43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252519 3887 090c257059f8326932178a2d1d4ac484 ""
+ "_minted-wallcalendar-code/20F302AA63B75FCF0DB80B4819F23BB243C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251399 7873 cde53a94b40425601c7f85e35e8804cc ""
+ "_minted-wallcalendar-code/2672FBDBB9C494A251B1E94C0B38F8AD43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251384 155 adeaaa9fd2846334a5e513f9612c9145 ""
+ "_minted-wallcalendar-code/2861AE1225599268F74201F1C39B8AE943C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251396 810 f3da100d4b2f96b3032488d7d651aa3b ""
+ "_minted-wallcalendar-code/2B0F8C8A59BC16AA0256551F14B0891443C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251394 1656 27924d631bf5eedeba43a5fe7997934c ""
+ "_minted-wallcalendar-code/2B8FA52DE44D075231C4F02C4F679D2D43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252515 5528 4530815349f7c623f611237a5a767dfa ""
+ "_minted-wallcalendar-code/2F06DBA698783215D435A40A9050C18A43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251401 885 d2ff32f9e7165f76d1a888d1e71064b2 ""
+ "_minted-wallcalendar-code/2FFBF4A9DD6C48CBB7F1A1C8B293876143C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251399 867 91b2c5018d57e93b656d8eebea98425a ""
+ "_minted-wallcalendar-code/2FFFE812EB41DFA6019BEA560375B44343C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251391 409 33027d70816ceb61cb4f05ab65cf6ce3 ""
+ "_minted-wallcalendar-code/31481FB1D71CFBA463DCBB8A9620A8CE43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251394 320 060b2fd3c79a7cfd4cda79d5213a05f2 ""
+ "_minted-wallcalendar-code/379DD89CC25851871F34E010BBB1011A43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252515 2194 6fe92c5099cf4a8fa36c2a7f2a259eca ""
+ "_minted-wallcalendar-code/383F6801D0D02631F227C89636CB7F0B43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252516 625 303bea98e1baa49e19c9513203f02a2e ""
+ "_minted-wallcalendar-code/3CEAED90711AA7777C8A1C13C07934D943C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251390 157 693beb83e865d61fa269fb3cda9515d9 ""
+ "_minted-wallcalendar-code/3D7CCFC54583085468F7261D866A27F843C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252520 533 dcb2357134c2a10e5d456a9d1c13585a ""
+ "_minted-wallcalendar-code/4297B4AC95CDD41DA3D88186813DF75A43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251402 764 47416d064ce8a04e883f6d93a0d022f1 ""
+ "_minted-wallcalendar-code/42B225A3BF77B8F70D28A4C5B19A4F1943C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251392 345 19bf92e93e4cc2673d4e462e70e54dd0 ""
+ "_minted-wallcalendar-code/4370CF835A691F3BBF85CAB364AF7ED343C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252514 609 328843a6e21b7e2ca3f45845f898f60b ""
+ "_minted-wallcalendar-code/4BC7FBD3FDCF3D17C3DE267E7C9EFE2343C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251395 557 6792ea9f92a5b9a75d1b475f99ceb28b ""
+ "_minted-wallcalendar-code/51469FF43A74F0C0DAA85BCCDC1064A043C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251388 149 3bf3cb74b41484c377a8b8054386158d ""
+ "_minted-wallcalendar-code/51ACFBE3FC71C4C2692463FAD05CE2F843C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251394 584 0bb80509a4220160e4ea58589807e04a ""
+ "_minted-wallcalendar-code/51EA9D0FE4EC3BCB835ADFA28E9D8EA943C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508557083 320 b45453cb3e4056990687685aae53419f ""
+ "_minted-wallcalendar-code/520CAE24A8DF3B947ECA15F54D5D308343C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251392 74 af7fc7f11e71ae1df381ea7f3357182c ""
+ "_minted-wallcalendar-code/54BADB0513C788DB85CB1B39953178B443C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251397 1524 6f69c4c1a135e43d40e1588ade8e6052 ""
+ "_minted-wallcalendar-code/5B5D6F67DE99E311EBA0A1C0FF1BD0D643C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251393 300 b5dd2a5d018f81ef12735d1a5206c8d0 ""
+ "_minted-wallcalendar-code/5E894CC9D1C6BCFD681CFF379A80DA5543C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252514 4808 bb9d2cd242191952e51214f7013e8892 ""
+ "_minted-wallcalendar-code/5F4D89201689122D618CEE759CE17D7443C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251390 135 2b8c4b6822cd923bd9b8e71b494d549f ""
+ "_minted-wallcalendar-code/606BD6B87E960111CD2BF9681F39965243C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251397 735 dc12dc4b421dfecbf6410f5047a00a29 ""
+ "_minted-wallcalendar-code/6120E3D3CBF828CA5D9BE5373C7BB14E43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252516 1372 2c658ca0ebdb820a14c9c6973e58c781 ""
+ "_minted-wallcalendar-code/669AA15B908BDCC617CD78B674EDA1A043C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251389 175 8f3d4c953f9cdde3e921482e61e0909a ""
+ "_minted-wallcalendar-code/6B5B3ADC99ED502A13CB46185013B51043C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252519 7137 bdb95d8323e53920924cdf9f5b27868b ""
+ "_minted-wallcalendar-code/6FAD878364DC870D016D3C164ECD0BD243C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508557085 1374 7dfaef8fd007302e1d456f38c5b9f1b6 ""
+ "_minted-wallcalendar-code/750C712D706F8031BCEAC46748DC1E2D43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251395 811 0733349472e1059855571ac3de455eb0 ""
+ "_minted-wallcalendar-code/7A2F035FB49711BCD77581500E36A7C843C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251388 462 ed9b40b7830f3a03111bc3f115b31754 ""
+ "_minted-wallcalendar-code/7CFBCC78D9E97011795B1ECB6F9D81BF43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251391 129 32a56332ade816861c335e5c5cd3c76b ""
+ "_minted-wallcalendar-code/7D8B1E7153256C89540C886D8AE1264243C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252517 2111 5904d70806151a6011bfdf5186ac4a1f ""
+ "_minted-wallcalendar-code/7E0D52810181AF5D8047851D50675C5643C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251396 3922 3520c6479122c6272f0a7f23b8c54a98 ""
+ "_minted-wallcalendar-code/81A4D4A32B22519B0327A0477A5601BB43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252518 2571 b2d19a6bab2c653d87a8a784dfa2ffb5 ""
+ "_minted-wallcalendar-code/844CBE462BF13CAF71F1DA97B8D3DEF143C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251389 281 91dba4436dcb86d207d02324b3282024 ""
+ "_minted-wallcalendar-code/844D88D1C52FF3D999528F065B03F0D343C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251394 3076 e81e0ee3ffb3eb9831e4f7a9b7715bef ""
+ "_minted-wallcalendar-code/86A7D3E081CA07C3EBC1EE0341154F2E43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251385 2805 4761e029846e7bd454cb3f6371cb03f6 ""
+ "_minted-wallcalendar-code/8F5254955AE2D4830630515383BC487943C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252517 1704 4e3ae427b379f8906967875c7c9390e3 ""
+ "_minted-wallcalendar-code/90CA41A0AF0C525B7E2B39F926D8FB6843C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251390 652 7ab3478b9531ce67768114ba81043ecf ""
+ "_minted-wallcalendar-code/92FF7E2AC8A71877AEB439C1283088C943C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251399 360 14c1e90dc863e9a41acf89dd8f03cd58 ""
+ "_minted-wallcalendar-code/948DF7F481173E7D9DF2ACDDC71961F643C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252518 1434 6e627941d3f32fbd2143fa7eed1a033d ""
+ "_minted-wallcalendar-code/95532C3B3A0072BBDE308ED35E1E085743C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251388 236 35944153d07d8f358c2eb550f1c02835 ""
+ "_minted-wallcalendar-code/969BA54A1B919C45CF406BB3C125D51043C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251391 88 59da408fe24a32a947577f3e1cfac724 ""
+ "_minted-wallcalendar-code/976FEA6DF15213DB1789E3947B8632EC43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251393 734 23d23439c929ac67d73fd8c29ef47a8f ""
+ "_minted-wallcalendar-code/999590BB6BDD1CE5D2CB78B703B5B03543C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251400 3439 fd2e362ef3a0985789a832f3f05ef9ba ""
+ "_minted-wallcalendar-code/9A012B9BE1259AA1EFB4BAE63268100443C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251387 447 b52c87679785f1f0304e19bfed322a98 ""
+ "_minted-wallcalendar-code/9F580BAA1F31C0E44D11DD51C2460F0943C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251387 353 d6ece7c35d181e648c087d8df64fc98a ""
+ "_minted-wallcalendar-code/9FE91E71AAA73820FF760D419464EC9D43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251401 117 508175761a4c142038925b741b7dadc0 ""
+ "_minted-wallcalendar-code/A2E37B0FCA28F4CA90CAD045199926C743C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251396 224 edcfa602734078179f43aef1cb67064a ""
+ "_minted-wallcalendar-code/A4E2FA74544C29B792A4CC5DFB8F751543C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251397 596 0d30803aea6693c0e53e081b0a95dfc7 ""
+ "_minted-wallcalendar-code/A78D22BD38A7B8278071084C48B5A7F243C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251387 1277 a7b7b5034992776a093dd651ad658bb0 ""
+ "_minted-wallcalendar-code/AC2D64784236E506BAAF014D827450DD43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251386 346 90f6b557c64d2f116cee349dc8de443f ""
+ "_minted-wallcalendar-code/AC6A7412F572E2B3C8B4E65D35553D7C43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252519 2028 cba4f394c608237fe2605552796aa4db ""
+ "_minted-wallcalendar-code/AFD9FB21AF5D630B2207FE2CE5BE2EC143C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252519 687 c8d417c016e8f2cd938b4367c459a2e5 ""
+ "_minted-wallcalendar-code/B1C28C6742025AC1F6EE9C9A8CC791DA43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251399 1614 bf958e391dd42f605a28a6145bc9c545 ""
+ "_minted-wallcalendar-code/B71909C35B142E9FCAFA186C4CB6C46543C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251389 415 052f74b1cbe936b2f0f65757bcd7b5a2 ""
+ "_minted-wallcalendar-code/BF736320BECC8D4A61121695356AF98D43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251388 2143 0ef73d6b2015bfdf763ebb37df9b4ba5 ""
+ "_minted-wallcalendar-code/BF9BDC605EF3480C1157C70B368FAB1643C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252516 968 86a28c9c14290bab55314d2c8a3f9e12 ""
+ "_minted-wallcalendar-code/C376C9FA4787640DD61E926B00D5104743C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251394 1478 dd278fa2795ebda542105fddf28766bf ""
+ "_minted-wallcalendar-code/C49AC9E5FF2D3559F3E74784F64F4FC343C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252518 7877 a17eeaf558c31ffc03109dc2cb7dd303 ""
+ "_minted-wallcalendar-code/C5D82B350107DCC91ACDBE8C816DD68B43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251395 205 e7ea6ed3c79557477c3c71780939be4f ""
+ "_minted-wallcalendar-code/CA40B33B1781E3BA5CCC5A1E77253D6F43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251390 526 d70bf1d6f0c029bffb23d9d3a1df935d ""
+ "_minted-wallcalendar-code/CA9D90ECD412CE9E8AD55CE634599F4B43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251389 352 a5b7025626a9a3edf1e50f9a29fc1642 ""
+ "_minted-wallcalendar-code/CBA1F475B3F7B3D50733EA23375DF1F743C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251387 1757 7e3025cbc2f09e4a7bce8236fc36a71a ""
+ "_minted-wallcalendar-code/CD5B3E5BF633FD733572F3D0CB30E26043C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251395 194 1690820292b80c64047a520c7ca8cc0f ""
+ "_minted-wallcalendar-code/CD8FB75626D15E77809A21AA2664914643C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252517 622 838937819384e02b7196251f10bb806e ""
+ "_minted-wallcalendar-code/CFEE4A322F46D5312230F0134E15F8D143C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251397 683 9efdf68a72b6bdcb87b1e4a989562562 ""
+ "_minted-wallcalendar-code/D14580909254F48553986863DB545E1343C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251398 1877 1dedf23b215c92feb87abc098e348506 ""
+ "_minted-wallcalendar-code/D1C7EDB1DD088EB59794BD340AFF010943C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251399 794 8a44e422c2a36d44f21214411ed53e1b ""
+ "_minted-wallcalendar-code/D4C6423B912CA52700C589AA135BA19343C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251402 108 983a6d87a8abfe78593fab2c65a3062e ""
+ "_minted-wallcalendar-code/D71F3F7B6B80A5B699557F870FC10A6343C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252516 2291 21953d2173b8955fd983521a280de675 ""
+ "_minted-wallcalendar-code/D74A299E1C80B0FABE737F418D3D788443C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251383 859 e189bb79a16000f4e916996257b0ff67 ""
+ "_minted-wallcalendar-code/D864525C12085A138D29D9EBF9FE07B643C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251401 116 05b6dc0c80b16ce95f312d64f7de8a92 ""
+ "_minted-wallcalendar-code/D952ABF0F4AB98FC3DE904B8ADD9A73C43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251391 204 8e476a1ac1c601509d1d5ce602ea235a ""
+ "_minted-wallcalendar-code/DA2E3F6142F6C771D0E8165DA48F4C1443C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251397 100 f897c12a900e025224fda2d051daf414 ""
+ "_minted-wallcalendar-code/DCF96EB9A28745B85E3AB5432A4F2AC043C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251386 522 b68bb073cea79248d7378a5f69f70aba ""
+ "_minted-wallcalendar-code/DD33110A63943720732CF351D860C7DF43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251395 633 6a17d6b4adc089cba8694172fb6f5b9d ""
+ "_minted-wallcalendar-code/E2A699C201D5AB8FA5EA292AB85F1DF843C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252516 2217 0e451930dd8c0f639e08b0fcf6b159b5 ""
+ "_minted-wallcalendar-code/E3F0723B43AD79B6E2B8CF4776C06B6543C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251389 462 40188f1d081ba8d0813bd7f44b438fbd ""
+ "_minted-wallcalendar-code/E5A458FEDF52EB2B0A32B7824AB4EB8E43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251386 3365 412020ed9874c1361b3e95591b582e5c ""
+ "_minted-wallcalendar-code/E7A5B4842B2306A61DA53D9F8DB3563D43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252518 6384 0475c0d9913eaf000367d2c260e8ad96 ""
+ "_minted-wallcalendar-code/E979D14CAF5656D4DCC3101646D9B8A343C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251400 104 1f8fb70ea7276fa1a6a35979dfb273f0 ""
+ "_minted-wallcalendar-code/E9D48774E2D196EC8935C8C411FE7FF143C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251385 1956 c9808ef8b3eb8fdd36e282b9ee21baa5 ""
+ "_minted-wallcalendar-code/EA45012636BAEFC8155FD6C5CB0F7F8C43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251385 982 c8cae84fc73684262e2b4c9c8014711f ""
+ "_minted-wallcalendar-code/ECD65CCC2E385029B6F062A27A34C38E43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508252515 2986 3b4a92eb553e31400772c5a60ed77c72 ""
+ "_minted-wallcalendar-code/EE32C2715E7E58EF630F7C8FC0F4868643C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251390 257 1f07513da0ca151849083a29702776db ""
+ "_minted-wallcalendar-code/F022940264AF9658599C7E1E2532983343C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251398 692 b3430b447bfdc61d4b8166943be5636a ""
+ "_minted-wallcalendar-code/F6680E8CE5FDDA244B4F72DF28FB9F1B43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251402 96 0e8c13eea1a448fdfd7597088991b760 ""
+ "_minted-wallcalendar-code/F8C6A5C012529160D87602BD8A3A84F243C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251386 2638 d629ccd665547258f79e7d1d0f164a6c ""
+ "_minted-wallcalendar-code/F9AFC411DF5AAE92BF302DE34D2C47A943C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251398 4110 c8171fcc4a87b5e4598537f359a23a1c ""
+ "_minted-wallcalendar-code/FB42E737002CB8C0507CCA6855761CB343C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251396 613 a4387a5dbf77b8e4c06b1bd837c32290 ""
+ "_minted-wallcalendar-code/FD1F46CC6C9149CBB3E066952ECDED2D43C43E3E67E44C81AF28C8B61108D25C.pygtex" 1508251387 551 0c4949e2605540efd88db0c93869dc7f ""
+ "_minted-wallcalendar-code/default-pyg-prefix.pygstyle" 1508251382 7493 51cba9593a43acb2bf88b9295207f4be ""
+ "_minted-wallcalendar-code/default.pygstyle" 1508251383 8823 a696bc1f647813ce5aee4d8373a873f7 ""
+ "local.sty" 1479751244 1575 83d98cf5fc486519d148b43844b85ede ""
+ "memoir-article.cls" 1479751244 9569 287a7d4646e8a29b3f9dbd405e4c8624 ""
+ "wallcalendar-code.aex" 0 -1 0 ""
+ "wallcalendar-code.aux" 1508557088 44705 f6f7ce393805edfe12002f8b7f5c10e3 ""
+ "wallcalendar-code.pyg" 0 -1 0 ""
+ "wallcalendar-code.tex" 1508557038 61372 0123c3a1a06eec75e44ab86eb67ea5f3 ""
+ "wallcalendar-code.toc" 1508557088 6728 3e6090fa134df12dc51eaf3aa419a54a ""
+ "wallcalendar-code.w18" 0 -1 0 ""
+ (generated)
+ "wallcalendar-code.pdf"
+ "wallcalendar-code.aux"
+ "wallcalendar-code.toc"
+ "wallcalendar-code.pyg"
+ "wallcalendar-code.log"
diff --git a/macros/luatex/latex/wallcalendar/doc/wallcalendar-code.fls b/macros/luatex/latex/wallcalendar/doc/wallcalendar-code.fls
new file mode 100644
index 0000000000..783faf0372
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/wallcalendar-code.fls
@@ -0,0 +1,1072 @@
+PWD /home/yume/prods/libs/wallcalendar/doc
+INPUT /home/yume/texlive/2017/texmf-var/web2c/luatex/lualatex.fmt
+INPUT ./wallcalendar-code.tex
+OUTPUT wallcalendar-code.log
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-lua.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-package.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-lpeg.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-function.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-string.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-table.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-boolean.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-number.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-math.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-io.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-os.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-file.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-gzip.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-md5.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-dir.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-unicode.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-url.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-set.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-compat.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-fil.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-sto.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-prs.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-dim.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-lua.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-deb.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-tpl.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/lualibs/lualibs-util-sta.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/luaotfload/luaotfload-characters.lua
+INPUT ./memoir-article.cls
+INPUT ./memoir-article.cls
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/pgfopts/pgfopts.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/pgfopts/pgfopts.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/pgf/utilities/pgfkeys.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/pgf/utilities/pgfkeys.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/tools/calc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/tools/calc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/memoir/memoir.cls
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/memoir/memoir.cls
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/luatex85/luatex85.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/luatex85/luatex85.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/ifpdf.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/ifpdf.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/ifpdf.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/ifetex/ifetex.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/ifetex/ifetex.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/ifetex/ifetex.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/plain/ifetex/ifetex.tex
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/ifxetex/ifxetex.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/ifxetex/ifxetex.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/ifxetex/ifxetex.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/ifluatex.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/ifluatex.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/ifluatex.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/memoir/mem11.clo
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/memoir/mem11.clo
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmroman10-regular.luc
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmroman9-regular.luc
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/memoir/mempatch.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/memoir/mempatch.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/memoir/mempatch.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/babel/babel.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/babel/babel.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/babel/luababel.def
+INPUT /home/yume/texlive/2017/texmf-var/tex/generic/config/language.dat
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/babel-english/british.ldf
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/babel-english/british.ldf
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/babel-english/english.ldf
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/babel/babel.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/babel/luababel.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/hyph-utf8/loadhyph/loadhyph-en-gb.tex
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/hyph-utf8/patterns/tex/hyph-en-gb.tex
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amsmath.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amsmath.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amstext.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amstext.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amsgen.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amsgen.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amsbsy.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amsbsy.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amsopn.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/amsmath/amsopn.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mathdesign.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mathdesign.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics/keyval.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics/keyval.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/ifthen.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/ifthen.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/mdbch.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/mdbch.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/mdbch.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/mdbch.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdfont.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdfont.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdsffont.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdsffont.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdttfont.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdttfont.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/xkeyval/xkeyval.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/xkeyval/xkeyval.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/xkeyval/xkeyval.tex
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/xkeyval/xkvutils.tex
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/fontenc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/fontenc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/t1enc.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/t1enc.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/t1mdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/t1mdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr8t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr8t.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/fontspec/fontspec.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/fontspec/fontspec.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/l3kernel/expl3.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/l3kernel/expl3.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/l3kernel/expl3-code.tex
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/l3kernel/expl3-code.tex
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/unicode-data/UnicodeData.txt
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/unicode-data/CaseFolding.txt
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/unicode-data/SpecialCasing.txt
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/cm/cmr10.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/cm/cmr10.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/cm/cmr10.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/cm/cmr10.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/cm/cmr10.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/cm/cmr10.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/cm/cmr10.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/cm/cmr10.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/l3kernel/l3pdfmode.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/l3kernel/l3pdfmode.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/l3packages/xparse/xparse.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/l3packages/xparse/xparse.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/fontspec/fontspec-luatex.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/fontspec/fontspec-luatex.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/tuenc.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/fontenc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/fontenc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/tuenc.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/tuenc.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/fontspec/fontspec.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/fontspec/fontspec.cfg
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmromandemi10-regular.luc
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmroman10-italic.luc
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/crimson-roman.luc
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/crimson-bold.luc
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/crimson-italic.luc
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/crimson-bolditalic.luc
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/xcolor/xcolor.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/xcolor/xcolor.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics-cfg/color.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics-cfg/color.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics-def/luatex.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics-def/luatex.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics/graphicx.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics/graphicx.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics/graphics.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics/graphics.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics/trig.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics/trig.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics-cfg/graphics.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/graphics-cfg/graphics.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/enumitem/enumitem.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/enumitem/enumitem.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/tools/multicol.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/tools/multicol.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/hyperref.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/hyperref.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty
+INPUT /home/yume/texlive/2017/texmf-dist/scripts/oberdiek/oberdiek.luatex.lua
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/auxhook.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/auxhook.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/kvoptions.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/kvoptions.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/pd1enc.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/pd1enc.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/latexconfig/hyperref.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/latexconfig/hyperref.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/url/url.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/url/url.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/memoir/memhfixc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/memoir/memhfixc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/hluatex.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/hluatex.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/titlesec/titletoc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/titlesec/titletoc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/eso-pic/eso-pic.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/eso-pic/eso-pic.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/puenc.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/puenc.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/bookmark.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/bookmark.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/bkm-pdftex.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/bkm-pdftex.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/ulem/ulem.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/ulem/ulem.sty
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/latex-fonts/lasy6.tfm
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/kinnari.luc
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/kinnari-bolditalic.luc
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/kinnari-bold.luc
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/kinnari-oblique.luc
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/microtype/microtype.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/microtype/microtype.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/microtype/microtype-luatex.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/microtype/microtype-luatex.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/luatexbase/luatexbase.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/luatexbase/luatexbase.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/ctablestack/ctablestack.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/luatex/ctablestack/ctablestack.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/microtype/microtype.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/microtype/microtype.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/microtype/microtype.cfg
+INPUT ./local.sty
+INPUT ./local.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/minted/minted.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/minted/minted.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/fvextra/fvextra.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/fvextra/fvextra.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/etoolbox/etoolbox.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/etoolbox/etoolbox.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/fancyvrb/fancyvrb.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/fancyvrb/fancyvrb.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/upquote/upquote.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/upquote/upquote.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/textcomp.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/textcomp.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/ts1enc.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/ts1enc.def
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/lineno/lineno.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/lineno/lineno.sty
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmmono12-regular.luc
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/float/float.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/float/float.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/tools/shellesc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/tools/shellesc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/tools/shellesc.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/ifplatform/ifplatform.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/ifplatform/ifplatform.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/catchfile.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/catchfile.sty
+INPUT ./wallcalendar-code.w18
+INPUT ./wallcalendar-code.w18
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/xstring/xstring.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/xstring/xstring.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/xstring/xstring.tex
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/framed/framed.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/framed/framed.sty
+INPUT ./wallcalendar-code.aex
+INPUT ./wallcalendar-code.aex
+INPUT ./wallcalendar-code.aux
+INPUT ./wallcalendar-code.aux
+OUTPUT wallcalendar-code.aux
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdacmr.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdacmr.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbcmr.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbcmr.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/ts1cmr.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/base/ts1cmr.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
+INPUT /home/yume/texlive/2017/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/epstopdf-base.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/epstopdf-base.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/grfext.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/oberdiek/grfext.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/nameref.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/hyperref/nameref.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/gettitlestring.sty
+INPUT /home/yume/texlive/2017/texmf-dist/tex/generic/oberdiek/gettitlestring.sty
+OUTPUT wallcalendar-code.pdf
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/ot1mdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/ot1mdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7t.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/microtype/mt-bch.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/microtype/mt-bch.cfg
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7t.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7t.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/omlmdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/omlmdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchri7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchri7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchri7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/omsmdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/omsmdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7y.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7y.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7y.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/omxmdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/omxmdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7v.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7v.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7v.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/mdamdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/mdamdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrma.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrma.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrma.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/mdbmdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/tex/latex/mathdesign/mdbch/mdbmdbch.fd
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrmb.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrmb.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrmb.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7t.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7t.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7t.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchri7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchri7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchri7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7y.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7y.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7y.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7v.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7v.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7v.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrma.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrma.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrma.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrmb.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrmb.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrmb.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrmb.tfm
+INPUT ./wallcalendar-code.toc
+INPUT ./wallcalendar-code.toc
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7t.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7t.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7t.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7t.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchri7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchri7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchri7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chri8y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7y.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7y.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7y.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7y.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7v.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7v.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7v.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7v.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchr7m.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chr7m.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrma.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrma.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrma.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrma.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrmb.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrmb.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/mdbchrmb.tfm
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/vf/public/mathdesign/mdbch/mdbchrmb.vf
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/tfm/public/mathdesign/mdbch/md-chrmb.tfm
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/default-pyg-prefix.pygstyle
+INPUT ./_minted-wallcalendar-code/default-pyg-prefix.pygstyle
+INPUT ./_minted-wallcalendar-code/default-pyg-prefix.pygstyle
+INPUT ./_minted-wallcalendar-code/default-pyg-prefix.pygstyle
+INPUT ./_minted-wallcalendar-code/default.pygstyle
+INPUT ./_minted-wallcalendar-code/default.pygstyle
+INPUT ./_minted-wallcalendar-code/default.pygstyle
+INPUT ./_minted-wallcalendar-code/default.pygstyle
+INPUT ./_minted-wallcalendar-code/4370CF835A691F3BBF85CAB364AF7ED343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/4370CF835A691F3BBF85CAB364AF7ED343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/4370CF835A691F3BBF85CAB364AF7ED343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/4370CF835A691F3BBF85CAB364AF7ED343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmmono9-regular.luc
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmmono10-italic.luc
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/51EA9D0FE4EC3BCB835ADFA28E9D8EA943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/51EA9D0FE4EC3BCB835ADFA28E9D8EA943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/51EA9D0FE4EC3BCB835ADFA28E9D8EA943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/51EA9D0FE4EC3BCB835ADFA28E9D8EA943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT /home/yume/texlive/2017/texmf-var/luatex-cache/generic/fonts/otl/lmmonolt10-bold.luc
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/D74A299E1C80B0FABE737F418D3D788443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D74A299E1C80B0FABE737F418D3D788443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D74A299E1C80B0FABE737F418D3D788443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D74A299E1C80B0FABE737F418D3D788443C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/1937A9361D6B964B6AFB29EAFC328DDE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/1937A9361D6B964B6AFB29EAFC328DDE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/1937A9361D6B964B6AFB29EAFC328DDE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/1937A9361D6B964B6AFB29EAFC328DDE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/0CCC8B6CA129D064C36E9FD59B79C03C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/0CCC8B6CA129D064C36E9FD59B79C03C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/0CCC8B6CA129D064C36E9FD59B79C03C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/0CCC8B6CA129D064C36E9FD59B79C03C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/5E894CC9D1C6BCFD681CFF379A80DA5543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/5E894CC9D1C6BCFD681CFF379A80DA5543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/5E894CC9D1C6BCFD681CFF379A80DA5543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/5E894CC9D1C6BCFD681CFF379A80DA5543C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/2672FBDBB9C494A251B1E94C0B38F8AD43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2672FBDBB9C494A251B1E94C0B38F8AD43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2672FBDBB9C494A251B1E94C0B38F8AD43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2672FBDBB9C494A251B1E94C0B38F8AD43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/09AD78D3F767ADD7015D0F7C1E2E329043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/09AD78D3F767ADD7015D0F7C1E2E329043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/09AD78D3F767ADD7015D0F7C1E2E329043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/09AD78D3F767ADD7015D0F7C1E2E329043C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/ECD65CCC2E385029B6F062A27A34C38E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/ECD65CCC2E385029B6F062A27A34C38E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/ECD65CCC2E385029B6F062A27A34C38E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/ECD65CCC2E385029B6F062A27A34C38E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/379DD89CC25851871F34E010BBB1011A43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/379DD89CC25851871F34E010BBB1011A43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/379DD89CC25851871F34E010BBB1011A43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/379DD89CC25851871F34E010BBB1011A43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/EA45012636BAEFC8155FD6C5CB0F7F8C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/EA45012636BAEFC8155FD6C5CB0F7F8C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/EA45012636BAEFC8155FD6C5CB0F7F8C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/EA45012636BAEFC8155FD6C5CB0F7F8C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/86A7D3E081CA07C3EBC1EE0341154F2E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/86A7D3E081CA07C3EBC1EE0341154F2E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/86A7D3E081CA07C3EBC1EE0341154F2E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/86A7D3E081CA07C3EBC1EE0341154F2E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/E9D48774E2D196EC8935C8C411FE7FF143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E9D48774E2D196EC8935C8C411FE7FF143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E9D48774E2D196EC8935C8C411FE7FF143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E9D48774E2D196EC8935C8C411FE7FF143C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/AC2D64784236E506BAAF014D827450DD43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/AC2D64784236E506BAAF014D827450DD43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/AC2D64784236E506BAAF014D827450DD43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/AC2D64784236E506BAAF014D827450DD43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/F8C6A5C012529160D87602BD8A3A84F243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/F8C6A5C012529160D87602BD8A3A84F243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/F8C6A5C012529160D87602BD8A3A84F243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/F8C6A5C012529160D87602BD8A3A84F243C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/E5A458FEDF52EB2B0A32B7824AB4EB8E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E5A458FEDF52EB2B0A32B7824AB4EB8E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E5A458FEDF52EB2B0A32B7824AB4EB8E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E5A458FEDF52EB2B0A32B7824AB4EB8E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/033BBD01DF821E53BEF1F76066548A1B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/033BBD01DF821E53BEF1F76066548A1B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/033BBD01DF821E53BEF1F76066548A1B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/033BBD01DF821E53BEF1F76066548A1B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/DCF96EB9A28745B85E3AB5432A4F2AC043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/DCF96EB9A28745B85E3AB5432A4F2AC043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/DCF96EB9A28745B85E3AB5432A4F2AC043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/DCF96EB9A28745B85E3AB5432A4F2AC043C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/9A012B9BE1259AA1EFB4BAE63268100443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/9A012B9BE1259AA1EFB4BAE63268100443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/9A012B9BE1259AA1EFB4BAE63268100443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/9A012B9BE1259AA1EFB4BAE63268100443C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/FD1F46CC6C9149CBB3E066952ECDED2D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/FD1F46CC6C9149CBB3E066952ECDED2D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/FD1F46CC6C9149CBB3E066952ECDED2D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/FD1F46CC6C9149CBB3E066952ECDED2D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/9F580BAA1F31C0E44D11DD51C2460F0943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/9F580BAA1F31C0E44D11DD51C2460F0943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/9F580BAA1F31C0E44D11DD51C2460F0943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/9F580BAA1F31C0E44D11DD51C2460F0943C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/CBA1F475B3F7B3D50733EA23375DF1F743C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CBA1F475B3F7B3D50733EA23375DF1F743C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CBA1F475B3F7B3D50733EA23375DF1F743C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CBA1F475B3F7B3D50733EA23375DF1F743C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/A78D22BD38A7B8278071084C48B5A7F243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/A78D22BD38A7B8278071084C48B5A7F243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/A78D22BD38A7B8278071084C48B5A7F243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/A78D22BD38A7B8278071084C48B5A7F243C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/95532C3B3A0072BBDE308ED35E1E085743C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/95532C3B3A0072BBDE308ED35E1E085743C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/95532C3B3A0072BBDE308ED35E1E085743C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/95532C3B3A0072BBDE308ED35E1E085743C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/BF736320BECC8D4A61121695356AF98D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/BF736320BECC8D4A61121695356AF98D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/BF736320BECC8D4A61121695356AF98D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/BF736320BECC8D4A61121695356AF98D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/2B8FA52DE44D075231C4F02C4F679D2D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2B8FA52DE44D075231C4F02C4F679D2D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2B8FA52DE44D075231C4F02C4F679D2D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2B8FA52DE44D075231C4F02C4F679D2D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/51469FF43A74F0C0DAA85BCCDC1064A043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/51469FF43A74F0C0DAA85BCCDC1064A043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/51469FF43A74F0C0DAA85BCCDC1064A043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/51469FF43A74F0C0DAA85BCCDC1064A043C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/7A2F035FB49711BCD77581500E36A7C843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/7A2F035FB49711BCD77581500E36A7C843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/7A2F035FB49711BCD77581500E36A7C843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/7A2F035FB49711BCD77581500E36A7C843C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/669AA15B908BDCC617CD78B674EDA1A043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/669AA15B908BDCC617CD78B674EDA1A043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/669AA15B908BDCC617CD78B674EDA1A043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/669AA15B908BDCC617CD78B674EDA1A043C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/B71909C35B142E9FCAFA186C4CB6C46543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/B71909C35B142E9FCAFA186C4CB6C46543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/B71909C35B142E9FCAFA186C4CB6C46543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/B71909C35B142E9FCAFA186C4CB6C46543C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/CA9D90ECD412CE9E8AD55CE634599F4B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CA9D90ECD412CE9E8AD55CE634599F4B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CA9D90ECD412CE9E8AD55CE634599F4B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CA9D90ECD412CE9E8AD55CE634599F4B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/E3F0723B43AD79B6E2B8CF4776C06B6543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E3F0723B43AD79B6E2B8CF4776C06B6543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E3F0723B43AD79B6E2B8CF4776C06B6543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E3F0723B43AD79B6E2B8CF4776C06B6543C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/844CBE462BF13CAF71F1DA97B8D3DEF143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/844CBE462BF13CAF71F1DA97B8D3DEF143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/844CBE462BF13CAF71F1DA97B8D3DEF143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/844CBE462BF13CAF71F1DA97B8D3DEF143C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/5F4D89201689122D618CEE759CE17D7443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/5F4D89201689122D618CEE759CE17D7443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/5F4D89201689122D618CEE759CE17D7443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/5F4D89201689122D618CEE759CE17D7443C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/CA40B33B1781E3BA5CCC5A1E77253D6F43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CA40B33B1781E3BA5CCC5A1E77253D6F43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CA40B33B1781E3BA5CCC5A1E77253D6F43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CA40B33B1781E3BA5CCC5A1E77253D6F43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/90CA41A0AF0C525B7E2B39F926D8FB6843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/90CA41A0AF0C525B7E2B39F926D8FB6843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/90CA41A0AF0C525B7E2B39F926D8FB6843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/90CA41A0AF0C525B7E2B39F926D8FB6843C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/EE32C2715E7E58EF630F7C8FC0F4868643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/EE32C2715E7E58EF630F7C8FC0F4868643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/EE32C2715E7E58EF630F7C8FC0F4868643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/EE32C2715E7E58EF630F7C8FC0F4868643C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/3CEAED90711AA7777C8A1C13C07934D943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/3CEAED90711AA7777C8A1C13C07934D943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/3CEAED90711AA7777C8A1C13C07934D943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/3CEAED90711AA7777C8A1C13C07934D943C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/2FFFE812EB41DFA6019BEA560375B44343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2FFFE812EB41DFA6019BEA560375B44343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2FFFE812EB41DFA6019BEA560375B44343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2FFFE812EB41DFA6019BEA560375B44343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/D952ABF0F4AB98FC3DE904B8ADD9A73C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D952ABF0F4AB98FC3DE904B8ADD9A73C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D952ABF0F4AB98FC3DE904B8ADD9A73C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D952ABF0F4AB98FC3DE904B8ADD9A73C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/969BA54A1B919C45CF406BB3C125D51043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/969BA54A1B919C45CF406BB3C125D51043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/969BA54A1B919C45CF406BB3C125D51043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/969BA54A1B919C45CF406BB3C125D51043C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/1A403559330D34AB149955B0E49EFEA543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/1A403559330D34AB149955B0E49EFEA543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/1A403559330D34AB149955B0E49EFEA543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/1A403559330D34AB149955B0E49EFEA543C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/7CFBCC78D9E97011795B1ECB6F9D81BF43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/7CFBCC78D9E97011795B1ECB6F9D81BF43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/7CFBCC78D9E97011795B1ECB6F9D81BF43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/7CFBCC78D9E97011795B1ECB6F9D81BF43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/520CAE24A8DF3B947ECA15F54D5D308343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/520CAE24A8DF3B947ECA15F54D5D308343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/520CAE24A8DF3B947ECA15F54D5D308343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/520CAE24A8DF3B947ECA15F54D5D308343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/42B225A3BF77B8F70D28A4C5B19A4F1943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/42B225A3BF77B8F70D28A4C5B19A4F1943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/42B225A3BF77B8F70D28A4C5B19A4F1943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/42B225A3BF77B8F70D28A4C5B19A4F1943C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/D71F3F7B6B80A5B699557F870FC10A6343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D71F3F7B6B80A5B699557F870FC10A6343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D71F3F7B6B80A5B699557F870FC10A6343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D71F3F7B6B80A5B699557F870FC10A6343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/6120E3D3CBF828CA5D9BE5373C7BB14E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/6120E3D3CBF828CA5D9BE5373C7BB14E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/6120E3D3CBF828CA5D9BE5373C7BB14E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/6120E3D3CBF828CA5D9BE5373C7BB14E43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/E2A699C201D5AB8FA5EA292AB85F1DF843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E2A699C201D5AB8FA5EA292AB85F1DF843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E2A699C201D5AB8FA5EA292AB85F1DF843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E2A699C201D5AB8FA5EA292AB85F1DF843C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/BF9BDC605EF3480C1157C70B368FAB1643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/BF9BDC605EF3480C1157C70B368FAB1643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/BF9BDC605EF3480C1157C70B368FAB1643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/BF9BDC605EF3480C1157C70B368FAB1643C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/383F6801D0D02631F227C89636CB7F0B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/383F6801D0D02631F227C89636CB7F0B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/383F6801D0D02631F227C89636CB7F0B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/383F6801D0D02631F227C89636CB7F0B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/CD8FB75626D15E77809A21AA2664914643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CD8FB75626D15E77809A21AA2664914643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CD8FB75626D15E77809A21AA2664914643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CD8FB75626D15E77809A21AA2664914643C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/976FEA6DF15213DB1789E3947B8632EC43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/976FEA6DF15213DB1789E3947B8632EC43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/976FEA6DF15213DB1789E3947B8632EC43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/976FEA6DF15213DB1789E3947B8632EC43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/5B5D6F67DE99E311EBA0A1C0FF1BD0D643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/5B5D6F67DE99E311EBA0A1C0FF1BD0D643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/5B5D6F67DE99E311EBA0A1C0FF1BD0D643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/5B5D6F67DE99E311EBA0A1C0FF1BD0D643C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/2B0F8C8A59BC16AA0256551F14B0891443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2B0F8C8A59BC16AA0256551F14B0891443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2B0F8C8A59BC16AA0256551F14B0891443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2B0F8C8A59BC16AA0256551F14B0891443C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/844D88D1C52FF3D999528F065B03F0D343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/844D88D1C52FF3D999528F065B03F0D343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/844D88D1C52FF3D999528F065B03F0D343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/844D88D1C52FF3D999528F065B03F0D343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/C376C9FA4787640DD61E926B00D5104743C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/C376C9FA4787640DD61E926B00D5104743C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/C376C9FA4787640DD61E926B00D5104743C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/C376C9FA4787640DD61E926B00D5104743C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/51ACFBE3FC71C4C2692463FAD05CE2F843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/51ACFBE3FC71C4C2692463FAD05CE2F843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/51ACFBE3FC71C4C2692463FAD05CE2F843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/51ACFBE3FC71C4C2692463FAD05CE2F843C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/31481FB1D71CFBA463DCBB8A9620A8CE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/31481FB1D71CFBA463DCBB8A9620A8CE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/31481FB1D71CFBA463DCBB8A9620A8CE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/31481FB1D71CFBA463DCBB8A9620A8CE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/C5D82B350107DCC91ACDBE8C816DD68B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/C5D82B350107DCC91ACDBE8C816DD68B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/C5D82B350107DCC91ACDBE8C816DD68B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/C5D82B350107DCC91ACDBE8C816DD68B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/750C712D706F8031BCEAC46748DC1E2D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/750C712D706F8031BCEAC46748DC1E2D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/750C712D706F8031BCEAC46748DC1E2D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/750C712D706F8031BCEAC46748DC1E2D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/CD5B3E5BF633FD733572F3D0CB30E26043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CD5B3E5BF633FD733572F3D0CB30E26043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CD5B3E5BF633FD733572F3D0CB30E26043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CD5B3E5BF633FD733572F3D0CB30E26043C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/DD33110A63943720732CF351D860C7DF43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/DD33110A63943720732CF351D860C7DF43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/DD33110A63943720732CF351D860C7DF43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/DD33110A63943720732CF351D860C7DF43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/4BC7FBD3FDCF3D17C3DE267E7C9EFE2343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/4BC7FBD3FDCF3D17C3DE267E7C9EFE2343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/4BC7FBD3FDCF3D17C3DE267E7C9EFE2343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/4BC7FBD3FDCF3D17C3DE267E7C9EFE2343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/FB42E737002CB8C0507CCA6855761CB343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/FB42E737002CB8C0507CCA6855761CB343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/FB42E737002CB8C0507CCA6855761CB343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/FB42E737002CB8C0507CCA6855761CB343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/2861AE1225599268F74201F1C39B8AE943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2861AE1225599268F74201F1C39B8AE943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2861AE1225599268F74201F1C39B8AE943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2861AE1225599268F74201F1C39B8AE943C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/7E0D52810181AF5D8047851D50675C5643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/7E0D52810181AF5D8047851D50675C5643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/7E0D52810181AF5D8047851D50675C5643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/7E0D52810181AF5D8047851D50675C5643C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/7D8B1E7153256C89540C886D8AE1264243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/7D8B1E7153256C89540C886D8AE1264243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/7D8B1E7153256C89540C886D8AE1264243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/7D8B1E7153256C89540C886D8AE1264243C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/A2E37B0FCA28F4CA90CAD045199926C743C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/A2E37B0FCA28F4CA90CAD045199926C743C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/A2E37B0FCA28F4CA90CAD045199926C743C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/A2E37B0FCA28F4CA90CAD045199926C743C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/DA2E3F6142F6C771D0E8165DA48F4C1443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/DA2E3F6142F6C771D0E8165DA48F4C1443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/DA2E3F6142F6C771D0E8165DA48F4C1443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/DA2E3F6142F6C771D0E8165DA48F4C1443C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/CFEE4A322F46D5312230F0134E15F8D143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CFEE4A322F46D5312230F0134E15F8D143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CFEE4A322F46D5312230F0134E15F8D143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CFEE4A322F46D5312230F0134E15F8D143C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/54BADB0513C788DB85CB1B39953178B443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/54BADB0513C788DB85CB1B39953178B443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/54BADB0513C788DB85CB1B39953178B443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/54BADB0513C788DB85CB1B39953178B443C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/A4E2FA74544C29B792A4CC5DFB8F751543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/A4E2FA74544C29B792A4CC5DFB8F751543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/A4E2FA74544C29B792A4CC5DFB8F751543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/A4E2FA74544C29B792A4CC5DFB8F751543C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/31481FB1D71CFBA463DCBB8A9620A8CE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/31481FB1D71CFBA463DCBB8A9620A8CE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/31481FB1D71CFBA463DCBB8A9620A8CE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/31481FB1D71CFBA463DCBB8A9620A8CE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/C5D82B350107DCC91ACDBE8C816DD68B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/C5D82B350107DCC91ACDBE8C816DD68B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/C5D82B350107DCC91ACDBE8C816DD68B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/C5D82B350107DCC91ACDBE8C816DD68B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/606BD6B87E960111CD2BF9681F39965243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/606BD6B87E960111CD2BF9681F39965243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/606BD6B87E960111CD2BF9681F39965243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/606BD6B87E960111CD2BF9681F39965243C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/CD5B3E5BF633FD733572F3D0CB30E26043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CD5B3E5BF633FD733572F3D0CB30E26043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CD5B3E5BF633FD733572F3D0CB30E26043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/CD5B3E5BF633FD733572F3D0CB30E26043C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/D14580909254F48553986863DB545E1343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D14580909254F48553986863DB545E1343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D14580909254F48553986863DB545E1343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D14580909254F48553986863DB545E1343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/4BC7FBD3FDCF3D17C3DE267E7C9EFE2343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/4BC7FBD3FDCF3D17C3DE267E7C9EFE2343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/4BC7FBD3FDCF3D17C3DE267E7C9EFE2343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/4BC7FBD3FDCF3D17C3DE267E7C9EFE2343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/FB42E737002CB8C0507CCA6855761CB343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/FB42E737002CB8C0507CCA6855761CB343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/FB42E737002CB8C0507CCA6855761CB343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/FB42E737002CB8C0507CCA6855761CB343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/2861AE1225599268F74201F1C39B8AE943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2861AE1225599268F74201F1C39B8AE943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2861AE1225599268F74201F1C39B8AE943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2861AE1225599268F74201F1C39B8AE943C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/F9AFC411DF5AAE92BF302DE34D2C47A943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/F9AFC411DF5AAE92BF302DE34D2C47A943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/F9AFC411DF5AAE92BF302DE34D2C47A943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/F9AFC411DF5AAE92BF302DE34D2C47A943C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/8F5254955AE2D4830630515383BC487943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/8F5254955AE2D4830630515383BC487943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/8F5254955AE2D4830630515383BC487943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/8F5254955AE2D4830630515383BC487943C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/059DFC4ED0F176E43AAD50BAAFE2496F43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/059DFC4ED0F176E43AAD50BAAFE2496F43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/059DFC4ED0F176E43AAD50BAAFE2496F43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/059DFC4ED0F176E43AAD50BAAFE2496F43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/DA2E3F6142F6C771D0E8165DA48F4C1443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/DA2E3F6142F6C771D0E8165DA48F4C1443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/DA2E3F6142F6C771D0E8165DA48F4C1443C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/DA2E3F6142F6C771D0E8165DA48F4C1443C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/F022940264AF9658599C7E1E2532983343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/F022940264AF9658599C7E1E2532983343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/F022940264AF9658599C7E1E2532983343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/F022940264AF9658599C7E1E2532983343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/B1C28C6742025AC1F6EE9C9A8CC791DA43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/B1C28C6742025AC1F6EE9C9A8CC791DA43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/B1C28C6742025AC1F6EE9C9A8CC791DA43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/B1C28C6742025AC1F6EE9C9A8CC791DA43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/20F302AA63B75FCF0DB80B4819F23BB243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/20F302AA63B75FCF0DB80B4819F23BB243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/20F302AA63B75FCF0DB80B4819F23BB243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/20F302AA63B75FCF0DB80B4819F23BB243C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/2FFBF4A9DD6C48CBB7F1A1C8B293876143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2FFBF4A9DD6C48CBB7F1A1C8B293876143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2FFBF4A9DD6C48CBB7F1A1C8B293876143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2FFBF4A9DD6C48CBB7F1A1C8B293876143C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/92FF7E2AC8A71877AEB439C1283088C943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/92FF7E2AC8A71877AEB439C1283088C943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/92FF7E2AC8A71877AEB439C1283088C943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/92FF7E2AC8A71877AEB439C1283088C943C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/D1C7EDB1DD088EB59794BD340AFF010943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D1C7EDB1DD088EB59794BD340AFF010943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D1C7EDB1DD088EB59794BD340AFF010943C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D1C7EDB1DD088EB59794BD340AFF010943C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/999590BB6BDD1CE5D2CB78B703B5B03543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/999590BB6BDD1CE5D2CB78B703B5B03543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/999590BB6BDD1CE5D2CB78B703B5B03543C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/999590BB6BDD1CE5D2CB78B703B5B03543C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/948DF7F481173E7D9DF2ACDDC71961F643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/948DF7F481173E7D9DF2ACDDC71961F643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/948DF7F481173E7D9DF2ACDDC71961F643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/948DF7F481173E7D9DF2ACDDC71961F643C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/E7A5B4842B2306A61DA53D9F8DB3563D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E7A5B4842B2306A61DA53D9F8DB3563D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E7A5B4842B2306A61DA53D9F8DB3563D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E7A5B4842B2306A61DA53D9F8DB3563D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/C49AC9E5FF2D3559F3E74784F64F4FC343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/C49AC9E5FF2D3559F3E74784F64F4FC343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/C49AC9E5FF2D3559F3E74784F64F4FC343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/C49AC9E5FF2D3559F3E74784F64F4FC343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/81A4D4A32B22519B0327A0477A5601BB43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/81A4D4A32B22519B0327A0477A5601BB43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/81A4D4A32B22519B0327A0477A5601BB43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/81A4D4A32B22519B0327A0477A5601BB43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/1DB198D4F7116DD69F7A04C4C14A2C1D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/1DB198D4F7116DD69F7A04C4C14A2C1D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/1DB198D4F7116DD69F7A04C4C14A2C1D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/1DB198D4F7116DD69F7A04C4C14A2C1D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/0563FB1B1C7CB725F0CB598E22A0F9EE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/0563FB1B1C7CB725F0CB598E22A0F9EE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/0563FB1B1C7CB725F0CB598E22A0F9EE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/0563FB1B1C7CB725F0CB598E22A0F9EE43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/6B5B3ADC99ED502A13CB46185013B51043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/6B5B3ADC99ED502A13CB46185013B51043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/6B5B3ADC99ED502A13CB46185013B51043C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/6B5B3ADC99ED502A13CB46185013B51043C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/AC6A7412F572E2B3C8B4E65D35553D7C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/AC6A7412F572E2B3C8B4E65D35553D7C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/AC6A7412F572E2B3C8B4E65D35553D7C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/AC6A7412F572E2B3C8B4E65D35553D7C43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/6FAD878364DC870D016D3C164ECD0BD243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/6FAD878364DC870D016D3C164ECD0BD243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/6FAD878364DC870D016D3C164ECD0BD243C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/6FAD878364DC870D016D3C164ECD0BD243C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/E979D14CAF5656D4DCC3101646D9B8A343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E979D14CAF5656D4DCC3101646D9B8A343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E979D14CAF5656D4DCC3101646D9B8A343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/E979D14CAF5656D4DCC3101646D9B8A343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/AFD9FB21AF5D630B2207FE2CE5BE2EC143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/AFD9FB21AF5D630B2207FE2CE5BE2EC143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/AFD9FB21AF5D630B2207FE2CE5BE2EC143C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/AFD9FB21AF5D630B2207FE2CE5BE2EC143C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/9FE91E71AAA73820FF760D419464EC9D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/9FE91E71AAA73820FF760D419464EC9D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/9FE91E71AAA73820FF760D419464EC9D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/9FE91E71AAA73820FF760D419464EC9D43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/3D7CCFC54583085468F7261D866A27F843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/3D7CCFC54583085468F7261D866A27F843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/3D7CCFC54583085468F7261D866A27F843C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/3D7CCFC54583085468F7261D866A27F843C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/D864525C12085A138D29D9EBF9FE07B643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D864525C12085A138D29D9EBF9FE07B643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D864525C12085A138D29D9EBF9FE07B643C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D864525C12085A138D29D9EBF9FE07B643C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/2F06DBA698783215D435A40A9050C18A43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2F06DBA698783215D435A40A9050C18A43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2F06DBA698783215D435A40A9050C18A43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/2F06DBA698783215D435A40A9050C18A43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/D4C6423B912CA52700C589AA135BA19343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D4C6423B912CA52700C589AA135BA19343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D4C6423B912CA52700C589AA135BA19343C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/D4C6423B912CA52700C589AA135BA19343C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/4297B4AC95CDD41DA3D88186813DF75A43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/4297B4AC95CDD41DA3D88186813DF75A43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/4297B4AC95CDD41DA3D88186813DF75A43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/4297B4AC95CDD41DA3D88186813DF75A43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.pyg
+INPUT ./_minted-wallcalendar-code/F6680E8CE5FDDA244B4F72DF28FB9F1B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/F6680E8CE5FDDA244B4F72DF28FB9F1B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/F6680E8CE5FDDA244B4F72DF28FB9F1B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+INPUT ./_minted-wallcalendar-code/F6680E8CE5FDDA244B4F72DF28FB9F1B43C43E3E67E44C81AF28C8B61108D25C.pygtex
+OUTPUT wallcalendar-code.toc
+INPUT ./wallcalendar-code.aux
+INPUT ./wallcalendar-code.pyg
+INPUT /home/yume/texlive/2017/texmf-dist/fonts/type1/public/mathdesign/mdbch/md-chr7y.pfb
diff --git a/macros/luatex/latex/wallcalendar/doc/wallcalendar-code.org b/macros/luatex/latex/wallcalendar/doc/wallcalendar-code.org
new file mode 100644
index 0000000000..b62e0fa7a8
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/wallcalendar-code.org
@@ -0,0 +1,2238 @@
+#+TITLE: Wallcalendar Code Documentation
+#+SETUPFILE: doc-setup.org
+#+LATEX_HEADER: \maxtocdepth{section}
+#+PROPERTY: header-args:tex :tangle ../wallcalendar.cls :padline yes
+
+* Tasks :noexport:
+** TODO small landscape: move the photo with /Photo/#2/xOffset and yOffset as at the full page layout
+** TODO clip photo beyond the bleed, the photo covers the cropmarks (esp. when when using yOffset)
+** option for the photo to be scaled vertically, not horizontally
+** option for the quote to have a bg with opacity
+* Introduction
+
+#+begin_latex
+\bigskip
+
+This is the code documentation for the \texttt{wallcalendar} documentclass.
+
+The \textbf{User Guide} is in \texttt{wallcalendar.pdf}. Clone or download from Github:
+
+\href{https://github.com/profound-labs/wallcalendar/}{https://github.com/profound-labs/wallcalendar/}
+
+\bigskip
+
+\tableofcontents*
+
+\clearpage
+#+end_latex
+
+* Header
+
+#+begin_src tex
+% wallcalendar.cls; Don't edit this file. Edit wallcalendar-code.org with emacs org-mode and call 'org-babel-tangle'.
+%
+% Wall Calendar
+%
+% A wall calendar document class with custom layouts and support for internationalization.
+%
+% (c) Gambhiro Bhikkhu, 2017
+% gambhiro.bhikkhu.85@gmail.com
+%
+% LPPL LaTeX Public Project License
+#+end_src
+
+* Identification
+
+#+begin_src tex
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{wallcalendar}[2017/10/21 v1.3.1 A wall calendar class with custom layouts and support for internationalization.]
+#+end_src
+
+* Preliminary Declarations
+
+#+begin_src tex
+\RequirePackage{pgfopts}
+\RequirePackage{calc}
+
+\newlength\calPaperWidth
+\newlength\calPaperHeight
+\newlength\@wall@leftMargin
+\newlength\@wall@rightMargin
+\newlength\@wall@topMargin
+\newlength\@wall@bottomMargin
+
+\def\@wall@eventsCsv{}
+\def\@wall@markDefaultsCsv{}
+\def\@wall@translationsInputFile{}
+
+\newcommand*\theMonthName{}
+#+end_src
+
+* Options
+
+Paper sizes and ratios.
+
+: Choral Octavo = 6.75in x 10.5in = 171.45mm x 266.7mm , r = 1.5555
+: The calendar row is 40mm (without bleed) = 1.5748in
+
+: When photo is above the calendar row, it has only three side bleed.
+: So aspect ratio:
+: (10.5in - 40mm + 3mm) / (6.75in + 6mm) =
+: (266.7 - 40 + 3) / (171.45 + 6) =
+: = 1.2944
+
+#+begin_src tex
+\newif\ifvarnishmask
+\newif\ifshowframe
+\newif\iftranslationsAutoload
+\newif\ifloadBabel
+
+\pgfkeys{
+ /wall/.is family, /wall,
+ defaults/.style = {
+ year = \the\year,
+ altyear = \empty,
+ loadBabel = false,
+ language = english,
+ translationsAutoload = true,
+ imageFolder = {./src-images},
+ choralOctavoPaper,
+ hMargin = 17mm,
+ topMargin = 20.5mm,
+ bottomMargin = 10mm,
+ },
+ year/.store in = \CalendarYear,
+ year/.initial = \the\year,
+ altyear/.store in = \CalendarAltYear,
+ altyear/.initial = \empty,
+ language/.store in = \@wall@calendarLanguage,
+ loadBabel/.is if = loadBabel,
+ translationsInputFile/.store in = \@wall@translationsInputFile,
+ translationsInputFile/.initial = {},
+ translationsAutoload/.is if = translationsAutoload,
+ eventsCsv/.store in = \@wall@eventsCsv,
+ eventsCsv/.initial = {},
+ markDefaultsCsv/.store in = \@wall@markDefaultsCsv,
+ markDefaultsCsv/.initial = {},
+ varnishmask/.is if = varnishmask,
+ showframe/.is if = showframe,
+ imageFolder/.store in = \@wall@imageFolder,
+ paperWidth/.code = {\setlength{\calPaperWidth}{#1}},
+ paperHeight/.code = {\setlength{\calPaperHeight}{#1}},
+ hMargin/.code = {\setlength{\@wall@leftMargin}{#1}%
+ \setlength{\@wall@rightMargin}{#1}},
+ leftMargin/.code = {\setlength{\@wall@leftMargin}{#1}},
+ rightMargin/.code = {\setlength{\@wall@rightMargin}{#1}},
+ topMargin/.code = {\setlength{\@wall@topMargin}{#1}},
+ bottomMargin/.code = {\setlength{\@wall@bottomMargin}{#1}},
+ % Paper sizes
+ choralOctavoPaper/.style = {paperWidth = 6.75in, paperHeight = 10.5in},
+ a2Paper/.style = {paperWidth = 420mm, paperHeight = 594mm},
+ a2PaperLandscape/.style = {paperWidth = 594mm, paperHeight = 420mm},
+ a3Paper/.style = {paperWidth = 297mm, paperHeight = 420mm},
+ a3PaperLandscape/.style = {paperWidth = 420mm, paperHeight = 297mm},
+ a4Paper/.style = {paperWidth = 210mm, paperHeight = 297mm},
+ a4PaperLandscape/.style = {paperWidth = 297mm, paperHeight = 210mm},
+ a5Paper/.style = {paperWidth = 148mm, paperHeight = 210mm},% r = 1.4142 = sqrt(2)
+ prevPaper/.style = {paperWidth = 170mm, paperHeight = 250mm},% r = 1.4705
+}
+
+% Debug with: \wlog{YEA: \the\@wall@bottomMargin}
+
+\DeclareOption*{%
+ \PassOptionsToClass{\CurrentOption}{memoir}
+}
+
+\pgfkeys{/wall, defaults}
+\ProcessPgfOptions{/wall}
+\ProcessOptions\relax
+#+end_src
+
+* More Declarations
+** Load memoir
+
+#+begin_src tex
+\LoadClass[11pt,oneside]{memoir}
+#+end_src
+
+** Temp variables
+
+#+begin_src tex
+\newlength\@tmp@a
+\newlength\@tmp@b
+\newlength\@tmp@c
+\newlength\@tmp@width
+\newlength\@tmp@height
+#+end_src
+
+** Require packages
+
+#+begin_src tex
+\ifloadBabel
+\RequirePackage[\@wall@calendarLanguage]{babel}
+\fi
+
+\RequirePackage{nag}
+%\RequirePackage{textcomp}
+\RequirePackage[cmyk]{xcolor}
+\RequirePackage{graphicx}
+\DeclareGraphicsExtensions{.pdf,.png,.jpg}
+\graphicspath{{\@wall@imageFolder}}
+
+\RequirePackage{eso-pic}
+\RequirePackage{ccicons}
+\RequirePackage{multicol}
+\RequirePackage{wasysym}
+
+\RequirePackage{pdftexcmds}
+\RequirePackage{etoolbox}
+\RequirePackage{luacode}
+
+\RequirePackage{xcoffins}
+%\RequirePackage{xstring}
+%\RequirePackage{stringstrings}
+
+\ifloadBabel
+\RequirePackage[final,babel=true]{microtype}
+\else
+\RequirePackage[final]{microtype}
+\fi
+
+\RequirePackage{tikz}
+\usetikzlibrary{calendar}
+\usetikzlibrary{positioning}
+\usetikzlibrary{fit}
+\usetikzlibrary{shapes.geometric}
+
+% http://tex.stackexchange.com/a/20426/831
+\pgfdeclarelayer{one}
+\pgfdeclarelayer{two}
+\pgfsetlayers{main,one,two}
+
+\pgfkeys{%
+ /tikz/on layer/.code={
+ \pgfonlayer{#1}\begingroup
+ \aftergroup\endpgfonlayer
+ \aftergroup\endgroup
+ }
+}
+#+end_src
+
+** Colors
+
+#+begin_src tex
+\definecolor{textbody}{gray}{0.15}
+
+% pantone 1245C, RGB 191,145,12 HEX: #BF910C
+% pantone 1255C, CMYK 0,27.5,100,34
+\definecolor{gold}{cmyk}{0,0.275,1,0.34}
+\definecolor{darkgold}{cmyk}{0.27,0.53,1,0.09}
+%\definecolor{orangegold}{cmyk}{0,0.31,0.89,0}
+\colorlet{orangegold}{darkgold}
+
+\colorlet{gridcolor}{black!30}
+\colorlet{weekday}{black}
+\colorlet{weekend}{black!50}
+\colorlet{mooncolor}{textbody}
+
+\definecolor{datenum}{gray}{0.3}
+\definecolor{plannerdatenum}{gray}{0.15}
+\definecolor{quote}{gray}{0.3}
+\definecolor{notes}{gray}{0.3}
+
+\definecolor{gridcolor}{gray}{0.5}
+\colorlet{pagebgcolor}{gridcolor!60}
+#+end_src
+
+=showframe= option colors:
+
+#+begin_src tex
+\colorlet{photo-frame}{blue}
+\colorlet{quote-frame}{red}
+\colorlet{heading-frame}{brown}
+\colorlet{calendar-frame}{orange}
+\colorlet{events-frame}{green}
+
+\ifshowframe
+ \colorlet{calendarbg}{black!50}
+\else
+ \colorlet{calendarbg}{white}
+\fi
+#+end_src
+
+** Page Size and Trim Marks
+
+#+begin_src tex
+\ifshowtrims
+ \setstocksize{\calPaperHeight + 35mm}{\calPaperWidth + 35mm}
+ \setlength{\paperheight}{\calPaperHeight}
+ \setlength{\paperwidth}{\calPaperWidth}
+ \trimXmarks
+ \trimLmarks
+ \quarkmarks
+ \settrims{0.5\stockheight - 0.5\paperheight}{0.5\stockwidth - 0.5\paperwidth}
+ \settrimmedsize{\calPaperHeight}{\calPaperWidth}{*}
+\else\relax
+ \setstocksize{\calPaperHeight}{\calPaperWidth}
+ \settrims{0pt}{0pt}
+ \settrimmedsize{\stockheight}{\stockwidth}{*}
+\fi
+
+%\settypeblocksize{\stockheight}{\stockwidth}{*}
+% TODO: calculate margins by ratios to paper size
+\setlrmarginsandblock{\@wall@leftMargin}{\@wall@rightMargin}{*}
+\setulmarginsandblock{\@wall@topMargin}{\@wall@bottomMargin}{*}
+\setheadfoot{0pt}{0pt}
+\setheaderspaces{0pt}{*}{*}
+
+\checkandfixthelayout% This will typeout values in pt.
+\settypeoutlayoutunit{mm}% It is useful to see layout values in mm too.
+\typeoutlayout
+#+end_src
+
+** Base font sizes and indents
+
+#+begin_src tex
+\def\@wall@fontSize{11}
+\def\@wall@lineHeight{13.6}
+
+\renewcommand{\normalsize}{%
+ \@setfontsize\normalsize\@wall@fontSize\@wall@lineHeight
+ \abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@
+ \abovedisplayshortskip \z@ \@plus3\p@
+ \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
+ \belowdisplayskip \abovedisplayskip
+ \color{textbody}
+ \let\@listi\@listI}
+\normalsize
+
+\setlength{\vgap}{1.5em}
+\setlength{\vindent}{\vgap}
+\setlength{\vleftmargin}{2em}
+
+\setlength{\parskip}{0pt}
+\setlength{\parindent}{0pt}
+
+\setlength{\fboxsep}{0pt}
+#+end_src
+
+** Helpers
+
+: #1 -- [fill=red, opacity=0.2], additional options used for showframe
+: #2 -- "hasvarnish", to indicate varnishmask color replacement when =varnishmask= option is used
+: #3 -- the content to hold the place for
+
+The =varnishmask= and =showframe= options are handled by the same =\placeholder=
+helper command to avoid having to use two commands and repeating the content
+argument.
+
+#+begin_src tex
+\definecolor{varnishmask}{gray}{0}
+
+% http://tex.stackexchange.com/a/59571/831
+\newcommand*{\strcmpblank}[3]{%
+ \ifnum\pdf@strcmp{#1}{}=\z@ #2\else #3\fi
+}
+
+\newcommand\@placeholder@pre[1]{%
+ \settowidth{\@tmp@width}{#1}%
+ \settototalheight{\@tmp@height}{#1}%
+ \def\@spacer{\rule{\@tmp@width}{0pt}\rule{0pt}{\@tmp@height}}%
+}
+
+\newcommand\placeholder[3][]{%
+ \ifvarnishmask%
+ \ifstrequal{#2}{hasvarnish}{%
+ \@placeholder@pre{#3}%
+ \tikz\node[fill=varnishmask, inner sep=0pt]{\@spacer};%
+ }{}%
+ \else%
+ \ifshowframe%
+ \@placeholder@pre{#3}%
+ \tikz\node[inner sep=0pt, opacity=0.6, #1]{\@spacer};%
+ \else%
+ #3%
+ \fi%
+ \fi%
+}
+#+end_src
+
+* Keys setup
+** /put photo
+
+#+begin_src tex
+\def\@wall@photo@putPhoto#1{#1}
+\def\@wall@photo@setYOffset{}
+
+\pgfkeys{
+ /put photo/.is family, /put photo,
+ simple/.code = {%
+ \def\@wall@photo@putPhoto##1{%
+ \includegraphics{##1}%
+ }%
+ \def\@wall@photo@setYOffset{}%
+ },
+ full page/.code = {%
+ \def\@wall@photo@putPhoto##1{%
+ \includegraphics[%
+ keepaspectratio,%
+ width={\calPaperWidth + 2\@t@bleed},%
+ ]{##1}%
+ }%
+ \def\@wall@photo@setYOffset{}%
+ },
+ full width above calendar/.code = {%
+ \def\@wall@photo@putPhoto##1{%
+ \includegraphics[%
+ keepaspectratio,%
+ width={\calPaperWidth + 2\@t@bleed},%
+ ]{##1}%
+ }%
+ \def\@wall@photo@setYOffset{%
+ \setlength{\@t@yOffset}{\@t@calendar@height + \@t@bleed + 1pt}%
+ }%
+ },
+ full width/.code = {%
+ \def\@wall@photo@putPhoto##1{%
+ \includegraphics[%
+ keepaspectratio,%
+ width={\calPaperWidth + 2\@t@bleed},%
+ ]{##1}%
+ }%
+ \def\@wall@photo@setYOffset{%
+ \setlength{\@t@yOffset}{\@t@calendar@height + \@t@bleed}%
+ }%
+ },
+}
+#+end_src
+
+** /Photo
+
+#+begin_src tex
+\pgfkeys{
+ /Photo/.is family, /Photo,
+ init/.style = {
+ defaults/.style = {file = {}, thumbFile = {}, caption = {}, bleed = 0pt, xOffset=0pt, yOffset=0pt},
+ file/.initial = {},
+ thumbFile/.initial = {},
+ caption/.initial = {},
+ bleed/.initial = 0pt,
+ xOffset/.initial = 0pt,
+ yOffset/.initial = 0pt,
+ },
+}
+#+end_src
+
+** /Quote
+
+#+begin_src tex
+\pgfkeys{
+ /Quote/.is family, /Quote,
+ init/.style = {
+ defaults/.style = {position=center, text={}, xOffset=0pt, yOffset=0pt},
+ position/.initial = {},
+ text/.initial = {},
+ xOffset/.initial = 0pt,
+ yOffset/.initial = 0pt,
+ },
+}
+#+end_src
+
+** /Calendar
+
+#+begin_src tex
+\pgfkeys{
+ /Calendar/.is family, /Calendar,
+ init/.style = {
+ defaults/.style = {bg/.style={opacity=0.5}},
+ bg/.style = {},
+ minimum height/.initial = {},
+ },
+}
+#+end_src
+
+** /Events
+
+#+begin_src tex
+\pgfkeys{
+ /Events/.is family, /Events,
+ init/.style = {
+ defaults/.style = {day code = {}, marks = {}, text = {}},
+ day code/.initial = {},
+ marks/.initial = {},
+ text/.initial = {},
+ },
+}
+#+end_src
+
+** /Txt
+
+#+begin_src tex
+\pgfkeys{
+ /Txt/.is family, /Txt,
+ init/.style = {
+ defaults/.style = {text = {}},
+ text/.initial = {},
+ },
+}
+#+end_src
+
+** /parseMonthEvents
+
+#+begin_src tex
+\def\eIdx{}
+\def\eMaxIdx{}
+\def\eMark{}
+\def\eIsoDate{}
+\def\eYear{}
+\def\eMonth{}
+\def\eMonthShort{}
+\def\eDay{}
+\def\eDayText{}
+\def\eNote{}
+
+\pgfkeys{
+ /parseMonthEvents/.is family, /parseMonthEvents,
+ month/.initial = {},
+ filter pred/.initial = nil,
+ format func/.initial = nil,
+ format cmd/.initial = {},
+ events csv/.initial = {},
+ mark defaults csv/.initial = {},
+ min events/.initial = {},
+ defaults/.style = {
+ month = \theMonthName,
+ filter pred = nil,
+ format func = nil,
+ format cmd = {\textsuperscript{\eIdx}~\eMonthShort~\eDay:~\eNote\par},
+ events csv = \@wall@eventsCsv,
+ mark defaults csv = \@wall@markDefaultsCsv,
+ min events = nil,
+ },
+}
+#+end_src
+
+** /parseYearEvents
+
+#+begin_src tex
+\pgfkeys{
+ /parseYearEvents/.is family, /parseYearEvents,
+ year/.initial = {},
+ filter pred/.initial = nil,
+ format func/.initial = nil,
+ format cmd/.initial = {},
+ events csv/.initial = {},
+ mark defaults csv/.initial = {},
+ min events/.initial = {},
+ defaults/.style = {
+ year = \CalendarYear,
+ filter pred = nil,
+ format func = nil,
+ format cmd = {\textsuperscript{\eIdx}~\eMonthShort~\eDay:~\eNote\ifnumless{\eIdx}{\eMaxIdx}{,\space}{.}},
+ events csv = \@wall@eventsCsv,
+ mark defaults csv = \@wall@markDefaultsCsv,
+ min events = nil,
+ },
+}
+#+end_src
+
+* Event Marks
+** Kite
+
+#+begin_src tex
+\newcommand\StarMark{*}
+
+\newcommand\NoteStarMark{*}
+#+end_src
+
+A kite mark that is the same height as the =\StarMark=. Note that the star (*)
+character is usually higher than the x-height, so it is not in the vertical
+center of its glyph box (i.e. not at the center of the character x):
+
+#+latex: \frame{x} \frame{*}
+
+#+begin_src tex
+\newlength\@wall@starHeight
+
+% Measure the star's height here, so that we are measuring with the current typeface.
+\newcommand\KiteMark{%
+\setlength{\@wall@starHeight}{\totalheightof{*}}%
+\begin{tikzpicture}
+ \node (box) [
+ rectangle, minimum height=\@wall@starHeight, minimum width=3.4pt,
+ inner sep=0pt, line width=0pt,
+ ] {};
+ \node[
+ kite, draw, textbody, fill=textbody,
+ scale=0.15, kite vertex angles=60,
+ above=0pt of box.north, anchor=north,
+ ] {};%
+\end{tikzpicture}%
+}
+
+% Same as \KiteMark but with scale=0.2
+\newcommand\NoteKiteMark{\raisebox{1pt}{%
+\setlength{\@wall@starHeight}{\totalheightof{*}}%
+\begin{tikzpicture}
+ \node (box) [
+ rectangle, minimum height=\@wall@starHeight, minimum width=3.4pt,
+ inner sep=0pt, line width=0pt,
+ ] {};
+ \node[
+ kite, draw, textbody, fill=textbody,
+ scale=0.2, kite vertex angles=60,
+ above=0pt of box.north, anchor=north,
+ ] {};%
+\end{tikzpicture}%
+}}
+#+end_src
+
+** Moons
+
+#+begin_src tex
+\tikzstyle{moon circle}=[
+ circle,
+ inner sep=0pt,
+ line width=0pt,
+ minimum height=8pt,
+]
+
+\newlength\@wall@moonRaise
+\setlength{\@wall@moonRaise}{-0.7pt}
+
+\newcommand\NewMoon{}
+\newcommand\FirstQuarter{}
+\newcommand\FullMoon{}
+\newcommand\LastQuarter{}
+
+\newcommand\@wall@NewMoon{%
+\raisebox{\@wall@moonRaise}{%
+ \tikz\node[moon circle, fill=mooncolor] {};%
+}}
+
+\newcommand\@wall@FullMoon{%
+\raisebox{\@wall@moonRaise}{%
+ \tikz\node[moon circle, draw, mooncolor, line width=0.3pt] {};%
+}}
+
+\newcommand\@wall@FirstQuarter{%
+\raisebox{\@wall@moonRaise}{%
+\begin{tikzpicture}
+\node [moon circle, name=waxing] {};
+\path[fill=mooncolor]
+ (waxing.north) --
+ (waxing.south) to[out=-180,in=-90]
+ (waxing.west) to[out=90,in=-180]
+ (waxing.north);
+\end{tikzpicture}%
+}}
+
+\newcommand\@wall@LastQuarter{%
+\raisebox{\@wall@moonRaise}{%
+\begin{tikzpicture}
+\node [moon circle, name=waning] {};
+\path[fill=mooncolor]
+ (waning.north) --
+ (waning.south) to[out=0,in=-90]
+ (waning.east) to[out=90,in=0]
+ (waning.north);
+\end{tikzpicture}%
+}}
+
+\newcommand\@wall@useDefaultMoons{%
+\renewcommand\NewMoon{\@wall@NewMoon}%
+\renewcommand\FirstQuarter{\@wall@FirstQuarter}%
+\renewcommand\FullMoon{\@wall@FullMoon}%
+\renewcommand\LastQuarter{\@wall@LastQuarter}%
+}
+
+\newcommand\plannerMoonSize{\@setfontsize\plannerMoonSize{14}{14}}
+\newcommand*\plannerMoonFormat[1]{{\plannerMoonSize #1}}
+
+\newcommand\@wall@planner@NewMoon{\plannerMoonFormat{\CIRCLE}}
+\newcommand\@wall@planner@FirstQuarter{\plannerMoonFormat{\LEFTcircle}}
+\newcommand\@wall@planner@FullMoon{\plannerMoonFormat{\Circle}}
+\newcommand\@wall@planner@LastQuarter{\plannerMoonFormat{\RIGHTcircle}}
+
+\newcommand\@wall@usePlannerMoons{%
+\renewcommand\NewMoon{\@wall@planner@NewMoon}%
+\renewcommand\FirstQuarter{\@wall@planner@FirstQuarter}%
+\renewcommand\FullMoon{\@wall@planner@FullMoon}%
+\renewcommand\LastQuarter{\@wall@planner@LastQuarter}%
+}
+
+\@wall@useDefaultMoons
+#+end_src
+
+* User Commands
+** \textbackslash SetPhoto
+
+: \SetPhoto[bleed=3mm]{June}
+
+#+begin_src tex
+\newcommand\SetPhoto[2][]{%
+ \pgfkeys{%
+ /Photo/#2/.is family, /Photo/#2,
+ /Photo/init,
+ defaults, file={#2},
+ #1%
+ }%
+}
+#+end_src
+
+** \textbackslash SetCalendar
+
+: \SetCalendar[bg={opacity=0.8}]{June}
+
+#+begin_src tex
+\newcommand\SetCalendar[2][]{%
+ \pgfkeys{%
+ /Calendar/#2/.is family, /Calendar/#2,
+ /Calendar/init,
+ defaults,
+ #1%
+ }%
+}
+#+end_src
+
+** \textbackslash SetQuote
+
+: \SetQuote[position=top right, text align=right]{June}{%
+: first line\\
+: second line\\
+: third line\\
+: fourth line
+: }
+
+#+begin_src tex
+\newcommand\SetQuote[3][]{%
+ \pgfkeys{%
+ /Quote/#2/.is family, /Quote/#2,
+ /Quote/init,
+ defaults, text={#3},
+ #1%
+ }%
+}
+#+end_src
+
+** \textbackslash SetEvents
+
+FIXME: Needs at least a =\SetEvents{#2}= to set defaults.
+
+: \SetEvents[yshift={10pt}]{August}{%
+: marks
+: }{%
+: text
+: }
+
+: #1 : options
+: #2 : month name
+: #3 : marks
+: #4 : text
+
+#+begin_src tex
+\newcommand\SetEvents[4][]{%
+ \pgfkeys{%
+ /Events/#2/.is family, /Events/#2,
+ /Events/init,
+ defaults, marks={#3}, text={#4},
+ #1%
+ }%
+}
+#+end_src
+
+** \textbackslash MonthPage
+
+The =/MonthPage= key is set in-place for each page, not collecting options per month.
+
+#+begin_src tex
+\pgfkeys{
+ /MonthPage/.is family, /MonthPage,
+ layout/.style = {layout handlers/#1/.get = \@wall@month@doLayout},
+ put photo/.style = {/put photo/#1},
+ defaults/.style = {layout = small landscape, put photo = simple},
+ layout handlers/.cd,
+ full page/.initial = \@wall@fullPageLayout,
+ small landscape/.initial = \@wall@smallLandscapeLayout,
+}
+#+end_src
+
+FIXME: handle case when no =\SetPhoto{#2}= was called, and so options are not
+initialized. This happens for example when bleed value is missing, and =.get=
+returns =\@val=:
+
+: ! Missing number, treated as zero.
+: <to be read again>
+: \@val
+: l.30 \MonthPage[layout=full page]{August}
+
+For now, just make sure there is a =\SetPhoto{August}= before =\MonthPage{August}=.
+
+: \MonthPage[layout=full page]{June}
+
+#+begin_src tex
+\newcommand\MonthPage[2][]{%
+ \pgfkeys{/MonthPage, defaults, #1}%
+ \@wall@month@doLayout{#2}%
+}
+#+end_src
+
+** \textbackslash SetTxt
+
+: \SetTxt{August Quote}{%
+: The text of the quote.
+: }
+
+: #1 : key
+: #2 : text
+
+#+begin_src tex
+\newcommand\SetTxt[2]{%
+ \pgfkeys{%
+ /Txt/#1/.is family, /Txt/#1,
+ /Txt/init,
+ defaults, text={#2},
+ }%
+}
+#+end_src
+
+** \textbackslash txt
+
+: \txt{August Quote}
+
+: #1: text key
+
+#+begin_src tex
+\newcommand\txt[1]{%
+\pgfkeys{/Txt/#1/text/.get=\@val}%
+\@val%
+}
+#+end_src
+
+** \textbackslash parseMonthEvents
+
+#+begin_src tex
+\def\@t@monthName{}
+\def\@t@eventsCsv{}
+\def\@t@markDefaultsCsv{}
+\def\@t@filterPred{}
+\def\@t@formatFunc{}
+\def\@t@formatCmd{}
+\def\@t@minEvents{}
+
+\newcommand\monthMarkFmt{\color{textbody}}
+
+\newcommand\symbolSpace{\thinspace}
+\newcommand\symbolSeparator{,\symbolSpace}
+
+% #1 = option keys
+\newcommand*\parseMonthEvents[1][]{%
+\pgfkeys{/parseMonthEvents, defaults, #1,
+ month/.get=\@t@monthName,
+ filter pred/.get=\@t@filterPred,
+ format func/.get=\@t@formatFunc,
+ format cmd/.get=\@t@formatCmd,
+ events csv/.get=\@t@eventsCsv,
+ mark defaults csv/.get=\@t@markDefaultsCsv,
+ min events/.get=\@t@minEvents,
+}%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthEvents(
+ \luastring{\@t@monthName},
+ \@t@filterPred,
+ \@t@formatFunc,
+ \luastringO{\@t@formatCmd},
+ \luastring{\@t@eventsCsv},
+ \luastring{\@t@markDefaultsCsv},
+ \@t@minEvents
+)}}
+#+end_src
+
+** \textbackslash parseYearEvents
+
+#+begin_src tex
+\def\@t@yearNum{}
+
+% #1 = option keys
+\newcommand*\parseYearEvents[1][]{%
+\pgfkeys{/parseYearEvents, defaults, #1,
+ year/.get=\@t@year,
+ filter pred/.get=\@t@filterPred,
+ format func/.get=\@t@formatFunc,
+ format cmd/.get=\@t@formatCmd,
+ events csv/.get=\@t@eventsCsv,
+ mark defaults csv/.get=\@t@markDefaultsCsv,
+ min events/.get=\@t@minEvents,
+}%
+\luadirect{
+require("wallcalendar-helpers.lua")
+yearEvents(
+ tonumber(\@t@year),
+ \@t@filterPred,
+ \@t@formatFunc,
+ \luastringO{\@t@formatCmd},
+ \luastring{\@t@eventsCsv},
+ \luastring{\@t@markDefaultsCsv},
+ \@t@minEvents
+)}}
+#+end_src
+
+** \textbackslash parseMonthMarksDayText
+
+NOTE: Tikz will not work with parsing options as with =\parseMonthEvents=.
+
+It will parse the CSV file set with the =eventsCsv= class option.
+
+#+begin_src tex
+\newlength\dayTextXshift
+\newlength\dayTextYshift
+\setlength{\dayTextXshift}{0pt}
+\setlength{\dayTextYshift}{0pt}
+
+\newlength\markNumberAbove
+\newlength\markNumberRight
+\setlength{\markNumberAbove}{-10pt}
+\setlength{\markNumberRight}{-3pt}
+
+\newlength\markDayTextAbove
+\newlength\markDayTextRight
+\setlength{\markDayTextAbove}{-10pt}
+\setlength{\markDayTextRight}{-3pt}
+
+\newcommand\parseMonthMarksDayText{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{\theMonthName}, nil, \luastring{\@wall@eventsCsv})
+tex.sprint(';')
+}}
+
+\newcommand\parseMonthMarksDayTextMonth[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{#1}, nil, \luastring{\@wall@eventsCsv})
+tex.sprint(';')
+}}
+#+end_src
+
+** \textbackslash parseMonthMarksDayTextUsing
+
+#+begin_src tex
+\newcommand*\parseMonthMarksDayTextUsing[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{\theMonthName}, nil, \luastring{#1})
+}}
+
+\newcommand\parseMonthMarksDayTextMonthUsing[2]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{#1}, nil, \luastring{#2})
+}}
+#+end_src
+
+** \textbackslash parseMonthMarksNote
+
+#+begin_src tex
+\newcommand*\parseMonthMarksNote{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksNote(\luastring{\theMonthName}, nil, \luastring{\@wall@eventsCsv}, \luastring{\@wall@markDefaultsCsv})
+}}
+#+end_src
+
+** \textbackslash parseMonthMarksNoteUsing
+
+#+begin_src tex
+\newcommand*\parseMonthMarksNoteUsing[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksNote(\luastring{\theMonthName}, nil, \luastring{#1}, \luastring{\@wall@markDefaultsCsv})
+}}
+#+end_src
+
+* Page Layouts
+** Initial setup
+
+Applying a blank, bare pagestyle, the layout macro should position the parts of
+the page.
+
+#+begin_src tex
+\makepagestyle{month}
+\makeoddhead{month}{}{}{}
+\makeevenhead{month}{}{}{}
+\makeoddfoot{month}{}{}{}
+\makeevenfoot{month}{}{}{}
+
+\pagestyle{month}
+#+end_src
+
+These elements are common to all layouts. One Coffin for each part of the
+page:
+
+- Photo
+- Quote
+- Calendar
+- Events
+
+#+begin_src tex
+\NewCoffin\@wall@pageWrap
+\NewCoffin\@wall@photo
+\NewCoffin\@wall@quote
+\NewCoffin\@wall@calendar
+\NewCoffin\@wall@events
+#+end_src
+
+** Formatting hooks and temp vars
+
+#+begin_src tex
+\newlength\@t@bleed
+\newlength\@t@rightOffset
+\newlength\@t@minipageWidth
+\newlength\@t@calendar@height
+\newlength\@t@calendar@hmargin
+\newlength\@t@calendar@dayYshift
+\newlength\@t@calendar@dayXshift
+\newlength\@t@calendar@gridHeight
+\newlength\@t@calendar@gridHeightFiveRows
+\newlength\@t@calendar@gridHeightSixRows
+\newlength\@t@xOffset
+\newlength\@t@yOffset
+\def\@t@file{}
+
+\newcommand*\monthFmt{}%
+\newcommand*\yearFmt{}%
+\newcommand*\dayLetterColor{}%
+\newcommand*\dayLetterFmt{}%
+\newcommand*\dayTextFmt{}%
+\newcommand*\quoteFmt{}%
+\newcommand*\headingFmt{}%
+\newcommand*\calendarFmt{}%
+\newcommand*\eventsFmt{}%
+#+end_src
+
+** Layout Reset, \textbackslash @wall@layout@reset
+
+A reset macro for the beginning of a layout, to make sure parameters are not
+carried from one layout to the next.
+
+#+begin_src tex
+\newcommand\@wall@layout@reset{%
+ \renewcommand*\monthFmt{}%
+ \renewcommand*\yearFmt{}%
+ \renewcommand*\dayLetterColor{}%
+ \renewcommand*\dayLetterFmt{}%
+ \renewcommand*\dayTextFmt{}%
+ \renewcommand*\quoteFmt{}%
+ \renewcommand*\headingFmt{}%
+ \renewcommand*\calendarFmt{}%
+ \renewcommand*\eventsFmt{}%
+ \def\@t@file{}%
+ \setlength{\@t@calendar@height}{0pt}%
+ \setlength{\@t@calendar@hmargin}{0pt}%
+ \setlength{\@t@calendar@dayYshift}{0pt}%
+ \setlength{\@t@calendar@dayXshift}{0pt}%
+ \setlength{\@t@bleed}{0pt}%
+ \setlength{\@t@rightOffset}{0pt}%
+ \setlength{\@t@minipageWidth}{0pt}%
+ \setlength{\@t@xOffset}{0pt}%
+ \setlength{\@t@yOffset}{0pt}%
+ \setlength{\@t@calendar@gridHeight}{0pt}%
+ \setlength{\@t@calendar@gridHeightFiveRows}{0pt}%
+ \setlength{\@t@calendar@gridHeightSixRows}{0pt}%
+}
+#+end_src
+
+** Full Page, \textbackslash @wall@fullPageLayout
+*** Setup formatting hooks
+
+Renew this in your document when customizing the variables for this layout.
+
+This must not introduce paragraph breaks or whitespace characters, so follow
+everything with =%=.
+
+#+begin_src tex
+\newcommand\fullPageFmt{%
+ \renewcommand*\monthFmt{\LARGE}%
+ \renewcommand*\yearFmt{\LARGE}%
+ \renewcommand*\dayLetterColor{}%
+ \renewcommand*\dayLetterFmt{\tiny}%
+ \renewcommand*\dayTextFmt{\small}%
+ \renewcommand*\quoteFmt{}%
+ \renewcommand*\headingFmt{\centering}%
+ \renewcommand*\calendarFmt{\centering}%
+ \renewcommand*\eventsFmt{\setlength{\parindent}{0pt}\raggedleft\footnotesize}%
+}
+#+end_src
+
+*** Init
+
+#+begin_src tex
+\newcommand\@wall@fullPageLayout[2][]{%
+\makeatletter
+\renewcommand*\theMonthName{#2}
+\@wall@layout@reset
+\fullPageFmt
+
+\colorlet{weekday}{black}
+\colorlet{weekend}{black!70}
+#+end_src
+
+*** Lengths and sizes
+
+Bleed:
+
+#+begin_src tex
+\pgfkeys{/Photo/#2/bleed/.get=\@val}
+\setlength{\@t@bleed}{\@val}
+#+end_src
+
+#+begin_src tex
+\def\@t@monthnum{\monthToNum{#2}}
+#+end_src
+
+Calendar height:
+
+#+begin_src tex
+% 40mm = 1.5748 inch
+% 43mm = 1.6929 inch
+\setlength{\@t@calendar@height}{40mm + \@t@bleed}
+
+% See if there was a height given in the options
+\pgfkeys{/Calendar/#2/minimum height/.get=\@val}
+\ifx\@val\empty \relax
+\else
+ \setlength{\@t@calendar@height}{\@val + \@t@bleed}
+\fi
+#+end_src
+
+Calendar horizontal margin:
+
+#+begin_src tex
+\setlength{\@t@calendar@hmargin}{20pt}
+#+end_src
+
+Calculate offsets:
+
+#+begin_src tex
+% NOTE: the -4pt and -2pt offset is somehow necessary for the sides to align
+% with the edges
+\setlength{\@t@rightOffset}{\@t@bleed +\@t@calendar@hmargin -4pt}
+\setlength{\@t@minipageWidth}{\calPaperWidth -2\@t@calendar@hmargin -2pt}
+#+end_src
+
+*** Set the coffin contents
+
+Page wrap:
+
+#+begin_src tex
+\SetHorizontalCoffin\@wall@pageWrap{%
+ \color{white}%
+ \rule{\textwidth}{0pt}%
+ \rule{0pt}{\textheight}%
+}
+#+end_src
+
+Photo:
+
+#+begin_src tex
+\pgfkeys{/Photo/#2/file/.get=\@t@file}
+
+\SetHorizontalCoffin\@wall@photo{%
+ \placeholder[fill=photo-frame]{hasvarnish}{%
+ \@wall@photo@putPhoto{\@t@file}%
+ }%
+}
+#+end_src
+
+Quote:
+
+#+begin_src tex
+\SetHorizontalCoffin\@wall@quote{%
+ \placeholder[fill=quote-frame]{}{%
+ \begin{minipage}{\linewidth}%
+ \quoteFmt
+ \pgfkeys{/Quote/#2/text/.get=\@val}%
+ \@val%
+ \end{minipage}%
+ }%
+}
+#+end_src
+
+Calendar:
+
+#+begin_src tex
+\SetHorizontalCoffin\@wall@calendar{%
+\ifvarnishmask\relax
+\else
+\begin{tikzpicture}
+
+\node (bg) [
+ fill = calendarbg,
+ opacity = 0.5,
+ minimum width = {\calPaperWidth + 2\@t@bleed},
+ anchor=north west,
+ /Calendar/#2/bg,
+ % override the style, in case bleed was set above
+ minimum height = {\@t@calendar@height},
+] at (0,0) {};
+
+\node (heading) [
+ below right=10pt and {\@t@rightOffset} of bg.north west,
+ anchor=north west,
+] {%
+\placeholder[fill=heading-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\headingFmt
+{\monthFmt\@tr@monthNumName{\@t@monthnum}}
+\hfill
+\strcmpblank{\CalendarAltYear}{%
+ {\yearFmt\CalendarYear}%
+}{%
+ {\yearFmt\CalendarYear/\CalendarAltYear}%
+}%
+\end{minipage}%
+}%
+};
+
+\node (calendar) [
+ below right=35pt and {\@t@rightOffset} of bg.north west,
+ anchor=north west,
+] {%
+\placeholder[fill=calendar-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\calendarFmt
+\tikz{\tikzMonthCalendar@fullpage{\@t@monthnum};}%
+\end{minipage}%
+}%
+};
+
+\node (events) [
+ below=0pt of calendar.south west,
+ anchor=north west,
+] {%
+\placeholder[fill=events-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\eventsFmt
+\pgfkeys{/Events/#2/text/.get=\@val}%
+\@val%
+\end{minipage}%
+}%
+};
+
+\end{tikzpicture}%
+\fi
+}% \SetHorizontalCoffin
+#+end_src
+
+*** Join the coffins
+
+#+begin_src tex
+\@wall@photo@setYOffset
+
+\pgfkeys{/Photo/#2/xOffset/.get=\@val}
+\addtolength{\@t@xOffset}{\@val}
+\pgfkeys{/Photo/#2/yOffset/.get=\@val}
+\addtolength{\@t@yOffset}{\@val}
+
+% NOTE: a small whitespace is visible on the left edge of the page when bleed is 0pt, a space must be getting in somewhere.
+\JoinCoffins*\@wall@pageWrap[l,t]\@wall@photo[l,t](-\spinemargin -\@t@bleed + \@t@xOffset, \uppermargin + \@t@bleed + \@t@yOffset)
+
+\pgfkeys{/Quote/#2/xOffset/.get=\@val}
+\setlength{\@t@xOffset}{\@val}
+\pgfkeys{/Quote/#2/yOffset/.get=\@val}
+\setlength{\@t@yOffset}{\@val}
+
+\JoinCoffins*\@wall@pageWrap[l,t]\@wall@quote[l,t](\@t@xOffset, \@t@yOffset)
+
+\JoinCoffins*\@wall@pageWrap[l,b]\@wall@calendar[l,b](-\spinemargin -\@t@bleed, \textheight +\uppermargin -\paperheight -\@t@bleed)
+
+\makeatother
+#+end_src
+
+*** Typeset
+
+#+begin_src tex
+\clearpage
+\TypesetCoffin\@wall@pageWrap%
+}% \@wall@fullPageLayout
+#+end_src
+
+*** Tikz calendar
+
+: #1 = number of month with leading zero
+
+#+begin_src tex
+\newcommand*{\tikzMonthCalendar@fullpage}[1]{%
+\pgfkeys{/Events/\monthName{#1}/marks/.get=\@eventmarks}%
+\calendar (cal#1) [alnitak, dates=\CalendarYear-#1-01 to \CalendarYear-#1-last] \@eventmarks;%
+}
+#+end_src
+
+** Small Landscape, \textbackslash @wall@smallLandscapeLayout
+*** Setup formatting hooks
+
+Renew this in your document when customizing the variables for this layout.
+
+This must not introduce paragraph breaks or whitespace characters, so follow
+everything with =%=.
+
+#+begin_src tex
+\newcommand\smallLandscapeFmt{%
+ \renewcommand*\monthFmt{\LARGE}%
+ \renewcommand*\yearFmt{\LARGE}%
+ \renewcommand*\dayLetterColor{}%
+ \renewcommand*\dayLetterFmt{\tiny}%
+ \renewcommand*\dayTextFmt{\small}%
+ \renewcommand*\quoteFmt{\centering}%
+ \renewcommand*\headingFmt{\centering}%
+ \renewcommand*\calendarFmt{\centering}%
+ \renewcommand*\eventsFmt{\setlength{\parindent}{0pt}\raggedright\footnotesize}%
+}
+#+end_src
+
+*** Init
+
+#+begin_src tex
+\newcommand\@wall@smallLandscapeLayout[2][]{%
+\makeatletter
+\renewcommand*\theMonthName{#2}
+\@wall@layout@reset
+\smallLandscapeFmt
+
+\colorlet{weekday}{black}
+\colorlet{weekend}{black!70}
+#+end_src
+
+*** Lengths and sizes
+
+Bleed:
+
+#+begin_src tex
+\pgfkeys{/Photo/#2/bleed/.get=\@val}
+\setlength{\@t@bleed}{\@val}
+#+end_src
+
+#+begin_src tex
+\def\@t@monthnum{\monthToNum{#2}}
+#+end_src
+
+Calendar height:
+
+Default height to fit:
+
+- day headings
+- days in a grid, 6 rows
+- events
+- bottom bleed
+
+#+begin_src tex
+\setlength{\@t@calendar@height}{85mm + \@t@bleed}
+
+% See if there was a height given in the options
+\pgfkeys{/Calendar/#2/minimum height/.get=\@val}
+\ifx\@val\empty \relax
+\else
+ \setlength{\@t@calendar@height}{\@val + \@t@bleed}
+\fi
+#+end_src
+
+Calendar horizontal margin:
+
+#+begin_src tex
+\setlength{\@t@calendar@hmargin}{20pt}
+#+end_src
+
+Calculate offsets:
+
+#+begin_src tex
+% 5mm: day headings
+% 20mm: events
+% 6.5mm: vertical spacing
+\setlength{\@tmp@a}{20mm + 5mm + 6.5mm}
+\setlength{\@tmp@b}{\@t@calendar@height -\@tmp@a}
+\setlength{\@t@calendar@dayYshift}{0.1666\@tmp@b}% 1/6 = 0.1666
+
+\setlength{\@t@calendar@gridHeightSixRows}{\@tmp@b}
+\setlength{\@t@calendar@gridHeightFiveRows}{\@tmp@b -0.1666\@tmp@b}
+
+% NOTE: the -4pt and -2pt offset is somehow necessary for the sides to align
+% with the edges
+\setlength{\@t@rightOffset}{\@t@bleed +\@t@calendar@hmargin -4pt}
+\setlength{\@t@minipageWidth}{\calPaperWidth -2\@t@calendar@hmargin -2pt}
+
+\setlength{\@t@calendar@dayXshift}{0.1428\@t@minipageWidth}% 1/7 = 0.1428
+#+end_src
+
+*** Set the coffin contents
+
+Page wrap:
+
+#+begin_src tex
+\SetHorizontalCoffin\@wall@pageWrap{%
+ \color{white}%
+ \rule{\textwidth}{0pt}%
+ \rule{0pt}{\textheight}%
+}
+#+end_src
+
+Photo:
+
+#+begin_src tex
+\pgfkeys{/Photo/#2/file/.get=\@t@file}
+
+\SetHorizontalCoffin\@wall@photo{%
+ \placeholder[fill=photo-frame]{hasvarnish}{%
+ \@wall@photo@putPhoto{\@t@file}%
+ }%
+}
+#+end_src
+
+Quote:
+
+#+begin_src tex
+\SetHorizontalCoffin\@wall@quote{%
+ \placeholder[fill=quote-frame]{}{%
+ \begin{minipage}{\linewidth}%
+ \quoteFmt
+ \pgfkeys{/Quote/#2/text/.get=\@val}%
+ \@val%
+ \end{minipage}%
+ }%
+}
+#+end_src
+
+Calendar:
+
+#+begin_src tex
+\SetHorizontalCoffin\@wall@calendar{%
+\ifvarnishmask\relax
+\else
+\begin{tikzpicture}
+
+\node (bg) [
+ fill = calendarbg,
+ opacity = 1,
+ minimum width = {\calPaperWidth + 2\@t@bleed},
+ anchor=north west,
+ /Calendar/#2/bg,
+ % override the style, in case bleed was set above
+ minimum height = {\@t@calendar@height},
+] at (0,0) {};
+
+\node (heading) [
+ below right=10pt and {\@t@rightOffset} of bg.north west,
+ anchor=north west,
+] {%
+\placeholder[fill=heading-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\headingFmt
+{\monthFmt\@tr@monthNumName{\@t@monthnum}}
+\hfill
+\strcmpblank{\CalendarAltYear}{%
+ {\yearFmt\CalendarYear}%
+}{%
+ {\yearFmt\CalendarYear/\CalendarAltYear}%
+}%
+\end{minipage}%
+}%
+};
+
+\node (calendar) [
+ below right=35pt and {\@t@rightOffset} of bg.north west,
+ anchor=north west,
+] {%
+\placeholder[fill=calendar-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\calendarFmt
+\hspace*{-5pt}% FIXME
+\tikz{\tikzMonthCalendar@smallLandscape{\@t@monthnum};}%
+\end{minipage}%
+}%
+};
+
+\node (events) [
+ above right=10mm and {\@t@rightOffset} of bg.south west,
+ anchor=south west,
+] {%
+\placeholder[fill=events-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\eventsFmt
+\pgfkeys{/Events/#2/text/.get=\@val}%
+\@val%
+\end{minipage}%
+}%
+};
+
+\end{tikzpicture}%
+\fi
+}% \SetHorizontalCoffin
+#+end_src
+
+*** Join the coffins
+
+Only using =yOffset=. The quote should be centered on the x axis.
+
+Join coffins so that the photo is in a fixed position, i.e. relative to the
+pageWrap, not relative to other coffins. It prevents accidental shifts when the
+other coffins are empty (when =varnishmask= is on) or have too much content.
+
+#+begin_src tex
+% The quote has to be centered between the photo and the calendar with manual tweaking.
+% The height of the quote is not known, the height of the calendar plus its heading is not known.
+
+% TODO move the photo with /Photo/#2/xOffset and yOffset as at the full page layout
+
+\pgfkeys{/Quote/#2/yOffset/.get=\@val}
+\setlength{\@t@yOffset}{\@val}
+
+\JoinCoffins*\@wall@photo[hc,b]\@wall@quote[hc,t](0pt, \@t@yOffset)
+
+\pgfkeys{/Photo/#2/yOffset/.get=\@val}
+\setlength{\@t@yOffset}{\@val}
+
+% NOTE: Taking the bottom edge of the photo as fixed.
+% yOffset must be set to pull the photo down into position
+
+\JoinCoffins*\@wall@pageWrap[hc,t]\@wall@photo[hc,b](0pt, \uppermargin + \@t@yOffset)
+
+% Calendar is aligned to the bottom of the page.
+
+\JoinCoffins*\@wall@pageWrap[hc,b]\@wall@calendar[hc,b](0pt, \textheight +\uppermargin -\paperheight -\@t@bleed)
+
+\makeatother
+#+end_src
+
+*** Typeset
+
+#+begin_src tex
+\clearpage
+\TypesetCoffin\@wall@pageWrap%
+}% \@wall@smallLandscapeLayout
+#+end_src
+
+*** Tikz calendar
+
+: #1 = number of month with leading zero
+
+#+begin_src tex
+\newcommand*{\tikzMonthCalendar@smallLandscape}[1]{%
+\pgfkeys{/Events/\monthName{#1}/marks/.get=\@eventmarks}%
+\calendar (cal#1) [betelgeuse, dates=\CalendarYear-#1-01 to \CalendarYear-#1-last] \@eventmarks;%
+}
+#+end_src
+
+** Tikz styles
+*** day letter headings
+
+#+begin_src tex
+\tikzstyle{day letter headings}=[%
+ day heading/.style={black!90},
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ \pgfmathsetlength\pgf@xa{\tikz@lib@cal@xshift}%
+ \pgfmathsetlength\pgf@ya{\tikz@lib@cal@yshift}%
+ \foreach \d in {0,1,2,3,4,5,6} {%
+ \pgf@xa=\d\pgf@xa%
+ \pgftransformxshift{\pgf@xa}%
+ \pgftransformyshift{\pgf@ya}%
+ \node (d\d) [anchor=south, day heading] {\dayLetterFmt\@tr@dayLetter{\d}};%
+ };%
+ }{}%
+ },%
+]
+#+end_src
+
+*** days grid
+
+#+begin_src tex
+\newcount\gridRows
+\newcount\gridLines
+\newcount\n
+
+\newif\ifGridNoSurround
+\GridNoSurroundfalse
+
+\tikzstyle{no grid surround}=[execute before day scope={\GridNoSurroundtrue}]
+\tikzstyle{grid surround}=[execute before day scope={\GridNoSurroundfalse}]
+
+\tikzstyle{days grid}=[%
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ %
+ % Determine if the grid is five or six rows
+ %
+ % 31 day months
+ \ifdate{between=01-01 and 01-31, between=03-01 and 03-31, between=05-01 and 05-31, between=07-01 and 07-31, between=08-01 and 08-31, between=10-01 and 10-31, between=12-01 and 12-31}{%
+ \ifdate{Saturday,Sunday}{%
+ \gridRows=6%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightSixRows}%
+ }{%
+ \gridRows=5%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightFiveRows}%
+ }
+ }{
+ % 30 day months and February
+ \ifdate{between=02-01 and 02-last}{%
+ \gridRows=5%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightFiveRows}%
+ }{%
+ \ifdate{Sunday}{%
+ \gridRows=6%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightSixRows}%
+ }{%
+ \gridRows=5%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightFiveRows}%
+ }
+ }
+ }
+ %
+ % Horizontal lines
+ %
+ \gridLines=\gridRows
+ \ifGridNoSurround\relax
+ \else
+ \advance\gridLines by 1
+ \n=0
+ \draw [
+ gridcolor,
+ line width=0.3pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ ] (0,{-\n\@t@calendar@dayYshift}) -- (7\@t@calendar@dayXshift,{-\n\@t@calendar@dayYshift});
+ \fi
+ \foreach \n in {1,2,3,4,5,6} {
+ \ifnum\n<\gridLines
+ \draw [
+ gridcolor,
+ line width=0.3pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ ] (0,{-\n\@t@calendar@dayYshift}) -- (7\@t@calendar@dayXshift,{-\n\@t@calendar@dayYshift});
+ \fi
+ }
+ %
+ % Vertical lines
+ %
+ \gridLines=7
+ \ifGridNoSurround\relax
+ \else
+ \advance\gridLines by 1
+ \n=0
+ \draw [
+ gridcolor,
+ line width=0.3pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ ] ({\n\@t@calendar@dayXshift},0) -- ({\n\@t@calendar@dayXshift},{-\gridRows\@t@calendar@dayYshift});
+ \fi
+ \foreach \n in {1,2,3,4,5,6,7} {
+ \ifnum\n<\gridLines
+ \draw [
+ gridcolor,
+ line width=0.3pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ ] ({\n\@t@calendar@dayXshift},0) -- ({\n\@t@calendar@dayXshift},{-\gridRows\@t@calendar@dayYshift});
+ \fi
+ }
+ %
+ % If we are not drawing the surrounding lines, it looks better to hide
+ % some of the top and bottom edges
+ %
+ \ifGridNoSurround
+ \draw [
+ color=white,
+ line width=6pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift={0.5\@t@calendar@dayYshift -1pt},
+ ] (0,0) -- (7\@t@calendar@dayXshift,0);
+ \draw [
+ color=white,
+ line width=6pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift={0.5\@t@calendar@dayYshift +1pt},
+ ] (0,-\gridRows\@t@calendar@dayYshift) -- (7\@t@calendar@dayXshift,-\gridRows\@t@calendar@dayYshift);
+ \fi
+ }{}%
+ }
+]
+#+end_src
+
+*** headings background rule
+
+#+begin_src tex
+\tikzstyle{headings background rule}=[
+ background rule/.style={black!90, line width=0.3pt, yshift={0.3\@t@calendar@dayYshift -3pt}},
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ \draw [
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ background rule,
+ ] (0,0) -- (7\@t@calendar@dayXshift,0);
+ }{}%
+ }
+]
+#+end_src
+
+*** headings background bar
+
+#+begin_src tex
+\tikzstyle{headings background bar}=[
+ headings background rule,
+ background rule/.style={black!20, line width=10pt, yshift={0.3\@t@calendar@dayYshift +3.5pt}},
+]
+#+end_src
+
+** Tikz calendar styles
+*** Betelgeuse, days in a grid
+
+(Alpha Orionis)
+
+#+begin_src tex
+\tikzstyle{betelgeuse}=[
+ no grid surround,
+ days grid,
+ week list,
+ day xshift=\@t@calendar@dayXshift,
+ day yshift=\@t@calendar@dayYshift,
+ headings background bar,
+ day letter headings,
+ day heading/.style={black!90, yshift={-0.3\@t@calendar@dayYshift}},
+ every day/.append style={anchor=base, inner xsep=0pt, yshift={-0.25\baselineskip}},
+ day text={\dayTextFmt\%d-},
+]
+#+end_src
+
+*** Alnitak, days in one line
+
+(Zeta Orionis)
+
+#+begin_src tex
+\tikzstyle{alnitak}=[
+ day list right,
+ day xshift={0pt},
+ every month/.append style={anchor=base, inner xsep=0pt, yshift=4mm, xshift=-\widthof{\space}},
+ day text={\dayTextFmt\%d-},
+ every day/.append style={anchor=base, inner xsep=0pt},
+ execute before day scope={
+ %
+ % === Moving the day number ===
+ %
+ % A small offset seems to improve the result, the last day gets closer to the end of the linewidth
+ \pgftransformxshift{0.01em}
+ \pgfcalendarjuliantodate{\pgfcalendarendjulian}{\currentyear}{\currentmonth}{\lastday}
+ % Width of month day digits from 1 - 28
+ \setlength{\@tmp@a}{\widthof{12345678910111213141516171819202122232425262728}}
+ \setlength{\@tmp@b}{\widthof{30}}
+ \pgfmathparse{(\linewidth - \@tmp@a - \@tmp@b * (\lastday-28)) / \lastday}
+ \pgftransformxshift{\pgfmathresult}
+ \let\%=\pgfcalendarshorthand
+ \setlength{\@tmp@a}{\widthof{\%d-}}
+ \pgftransformxshift{\@tmp@a}
+ %
+ % === Weekday letter above the day ===
+ %
+ \ifdate{weekend}{\def\dayLetterColor{\color{weekend}}}{\def\dayLetterColor{\color{weekday}}}%
+ \node[anchor=south,yshift=5mm,inner sep=0pt]{%
+ \dayLetterColor\dayLetterFmt\@tr@dayLetter{\pgfcalendarcurrentweekday}%
+ };%
+ },
+]
+#+end_src
+
+* Year Planner
+** Tikz calendar styles
+*** Year Planner Portrait
+
+#+begin_src tex
+\newcommand\plannerPortraitMonthFmt{\fontsize{11}{11}\selectfont\color{darkgold}}
+\newcommand\plannerPortraitDayFmt{\fontsize{8}{8}\selectfont\color{plannerdatenum}}
+
+\tikzstyle{year planner portrait}=[
+ week list,
+ month text={\plannerPortraitMonthFmt\@tr@monthNumName{\pgfcalendarcurrentmonth}},
+ day text={\plannerPortraitDayFmt\%d-},
+ every month/.append style={%
+ anchor=south,
+ inner xsep=0pt,
+ yshift=5mm,
+ xshift=2.5mm,
+ },
+ day letter headings,
+ day heading/.style={gray, xshift=0pt, scale=0.85},
+ month label above centered,
+ every day/.style={anchor=mid},
+]
+#+end_src
+
+*** Year Planner Landscape
+
+#+begin_src tex
+\newcommand\plannerLandscapeDateDayFont{}
+\newcommand\plannerLandscapeDayFont{}
+\newcommand\plannerLandscapeMonthFont{}
+
+\newcommand\plannerLandscapeMonthFmt{%
+ \plannerLandscapeMonthFont%
+ \fontsize{15}{18}\selectfont%
+ \color{gold}\bfseries%
+}
+
+\newcommand\plannerLandscapeDayFmt{%
+ \plannerLandscapeDayFont%
+ \fontsize{10}{12}\selectfont%
+}
+
+\newcommand*\plannerLandscapeDateDayFormat[1]{%
+ \plannerLandscapeDateDayFont%
+ \fontsize{8}{11}\selectfont%
+ #1%
+}
+
+\newcommand\plannerLandscapeBeginDayScopeHook{%
+ \ifdate{weekend}{\color{black!60}}{}
+}
+
+\newlength\plannerLandscapeDayXShift
+\newlength\plannerLandscapeMonthYShift
+
+% Assuming 25mm to fit 'September'
+\setlength{\@tmp@a}{\calPaperWidth - \@wall@leftMargin - \@wall@rightMargin - 25mm}
+% Max week shift is 6 = Sunday. 31 days + 6 = 37. 1/37 = 0.027
+\setlength{\plannerLandscapeDayXShift}{0.027\@tmp@a}
+
+% Assuming 10mm for day headings (M T W...) and some padding
+\setlength{\@tmp@a}{\calPaperHeight - \@wall@topMargin - \@wall@bottomMargin - 10mm}
+% 1/12 = 0.0833
+\setlength{\plannerLandscapeMonthYShift}{0.0833\@tmp@a}
+
+\tikzstyle{year planner landscape}=[
+ month list,
+ day xshift=\plannerLandscapeDayXShift,
+ month yshift=\plannerLandscapeMonthYShift,
+ every month/.append style={anchor=base, inner xsep=0pt},
+ month text={\plannerLandscapeMonthFmt \%mt},
+ day text={\plannerLandscapeDayFmt \%d-},
+ every day/.append style={anchor=base, inner xsep=0pt},
+ month label left,
+ execute at begin day scope={
+ \plannerLandscapeBeginDayScopeHook
+ % Weekday headers in January
+ \ifdate{between=01-01 and 01-31}{
+ \def\l{\ifcase\pgfcalendarcurrentweekday M\or T\or W\or T\or F\or S\or S\fi}%
+ \ifdate{weekend}{\def\daylabelcolor{gold}}{\def\daylabelcolor{black}}%
+ \node[anchor=south,yshift=5mm,inner sep=0pt]{\color{\daylabelcolor}\plannerLandscapeDateDayFormat{\l}};%
+ }{}
+ % Weekday headers in December
+ \ifdate{between=12-01 and 12-31}{
+ \pgftransformyshift{-3mm}%
+ \def\l{\ifcase\pgfcalendarcurrentweekday M\or T\or W\or T\or F\or S\or S\fi}%
+ \ifdate{weekend}{\def\daylabelcolor{gold}}{\def\daylabelcolor{black}}%
+ \node[anchor=south,yshift=5mm,inner sep=0pt]{\color{\daylabelcolor}\plannerLandscapeDateDayFormat{\l}};%
+ }{}
+ }
+]
+#+end_src
+
+*** Year Planner Landscape Grid
+
+#+begin_src tex
+\newcommand\plannerGridMonthFont{}
+\newcommand\plannerGridDateDayFont{}
+\newcommand\plannerGridNotesFont{}
+\newcommand\plannerGridDayFont{}
+\newcommand\plannerGridYearNumberFont{}
+
+\newcommand\plannerGridYearNumberFmt{%
+ \plannerGridYearNumberFont%
+ \fontsize{11}{11}\selectfont%
+ \color{white}%
+}
+
+\newcommand\plannerGridMonthFmt{%
+ \plannerGridMonthFont%
+ \fontsize{13}{13}\selectfont%
+ \color{white}%
+}
+
+\newcommand\plannerGridDayFmt{%
+ \plannerGridDayFont%
+ \fontsize{11}{11}\selectfont%
+}
+
+\newcommand\plannerGridDateDayFmt{%
+ \plannerGridDateDayFont%
+ \fontsize{9}{9}\selectfont%
+ \color{black!80}%
+}
+
+\newcommand{\plannerGridNotesFmt}{%
+ \plannerGridNotesFont%
+ \fontsize{11}{11}\selectfont%
+}
+
+\newcommand\plannerGridBeginDayScopeHook{%
+ \ifdate{weekend}{\color{black!60}}{}
+}
+
+\newlength\plannerGridColXShift
+\newlength\plannerGridRowYShift
+
+\newlength\plannerGridCalendarWidth
+\newlength\plannerGridCalendarHeight
+
+\newlength\plannerGridDayHeadingsHeight
+\newlength\plannerGridMonthNamesWidth
+
+\newlength\plannerGridNotesHeight
+\setlength{\plannerGridNotesHeight}{10mm}
+
+\setlength{\plannerGridCalendarWidth}{\calPaperWidth - \@wall@leftMargin - \@wall@rightMargin}
+\setlength{\plannerGridCalendarHeight}{\calPaperHeight - \@wall@topMargin - \@wall@bottomMargin - \plannerGridNotesHeight}
+
+\setlength{\plannerGridDayHeadingsHeight}{10mm}
+\setlength{\plannerGridMonthNamesWidth}{10mm}
+
+\setlength{\@tmp@a}{\plannerGridCalendarWidth - \plannerGridMonthNamesWidth}
+% 37 columns. 1/37 = 0.027. Max week shift is 6 = Sunday. 31 days + 6 = 37.
+\setlength{\plannerGridColXShift}{0.027\@tmp@a}
+
+\setlength{\@tmp@a}{\plannerGridCalendarHeight - 2\plannerGridDayHeadingsHeight}
+% 12 rows. 1/12 = 0.0833
+\setlength{\plannerGridRowYShift}{0.0833\@tmp@a}
+
+\newcounter{verticalCount}
+
+\tikzstyle{year planner landscape grid days}=[
+ month list,
+ day xshift=\plannerGridColXShift,
+ month yshift=\plannerGridRowYShift,
+ day text={\plannerGridDayFmt \%d-},
+ every day/.append style={anchor=base, yshift=-12pt, inner xsep=0pt},
+ execute at begin day scope={%
+ % White fill to cover the page background color
+ \node (cell) [
+ rectangle,
+ fill = white,
+ minimum height = \plannerGridRowYShift - 1pt,
+ minimum width = \plannerGridColXShift - 1pt,
+ xshift = -0.5\plannerGridColXShift,
+ yshift = 4.5pt,
+ ] {};%
+ %
+ \ifdate{Monday}{%
+ \node (a) [above left = 15pt and -3.5pt of cell.west] {};
+ \node (b) [below left = 15pt and -3.5pt of cell.west] {};
+ \node (c) [right = 10pt of cell.west] {};
+ \path [on layer = one, fill = pagebgcolor] (a.south) -- (b.north) -- (c.west) -- (a.south);%
+ }{}%
+ %
+ \ifdate{Sunday}{%
+ \node (a) [above left = 15pt and {-3.5pt + 1pt} of cell.east] {};
+ \node (b) [below left = 15pt and {-3.5pt + 1pt} of cell.east] {};
+ \node (c) [right = {10pt - 1pt} of cell.east] {};
+ \path [on layer = two, fill = white] (a.south) -- (b.north) -- (c.west) -- (a.south);%
+ }{}%
+ %
+ \plannerGridBeginDayScopeHook%
+ },
+]
+#+end_src
+** Helpers
+
+#+begin_src tex
+\newcommand\plannerMarksDayTextCSV{\@wall@eventsCsv}
+\newcommand\plannerMarksNoteCSV{\@wall@eventsCsv}
+\newcommand\plannerMarkDefaultsCsv{}
+
+\newcommand\@wall@plm[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{#1}, nil, \luastring{\plannerMarksDayTextCSV})
+tex.sprint(';')
+}}
+
+\newcommand\@wall@plmYear{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+yearMarksDayText(tonumber(\CalendarYear), nil, \luastring{\plannerMarksDayTextCSV})
+tex.sprint(';')
+}}
+
+\newcommand\@wall@plNotes{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+yearMarksNote(tonumber(\CalendarYear), nil, \luastring{\plannerMarksNoteCSV}, \luastring{\plannerMarkDefaultsCsv}, false)
+}}
+
+\newcommand\@wall@plNotesOneCalendar{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+yearMarksNote(tonumber(\CalendarYear), nil, \luastring{\plannerMarksNoteCSV}, \luastring{\plannerMarkDefaultsCsv}, true)
+}}
+
+\newcommand\plannerEvents{%
+\parseYearEvents[filter pred = hasNote]%
+}
+
+#+end_src
+
+** \textbackslash YearPlannerPortrait
+
+#+begin_src tex
+\newcommand\YearPlannerPortrait{%
+\@wall@useDefaultMoons%
+\begin{tikzpicture}[every calendar/.style={year planner portrait}]%
+ \matrix[column sep=1.5em, row sep=5mm] {
+ \calendar(cal01)[dates=\CalendarYear-01-01 to \CalendarYear-01-last] \@wall@plm{January}; \pgfmatrixnextcell
+ \calendar(cal02)[dates=\CalendarYear-02-01 to \CalendarYear-02-last] \@wall@plm{February}; \pgfmatrixnextcell
+ \calendar(cal03)[dates=\CalendarYear-03-01 to \CalendarYear-03-last] \@wall@plm{March}; \\
+ \calendar(cal04)[dates=\CalendarYear-04-01 to \CalendarYear-04-last] \@wall@plm{April}; \pgfmatrixnextcell
+ \calendar(cal05)[dates=\CalendarYear-05-01 to \CalendarYear-05-last] \@wall@plm{May}; \pgfmatrixnextcell
+ \calendar(cal06)[dates=\CalendarYear-06-01 to \CalendarYear-06-last] \@wall@plm{June}; \\
+ \calendar(cal07)[dates=\CalendarYear-07-01 to \CalendarYear-07-last] \@wall@plm{July}; \pgfmatrixnextcell
+ \calendar(cal08)[dates=\CalendarYear-08-01 to \CalendarYear-08-last] \@wall@plm{August}; \pgfmatrixnextcell
+ \calendar(cal09)[dates=\CalendarYear-09-01 to \CalendarYear-09-last] \@wall@plm{September}; \\
+ \calendar(cal10)[dates=\CalendarYear-10-01 to \CalendarYear-10-last] \@wall@plm{October}; \pgfmatrixnextcell
+ \calendar(cal11)[dates=\CalendarYear-11-01 to \CalendarYear-11-last] \@wall@plm{November}; \pgfmatrixnextcell
+ \calendar(cal12)[dates=\CalendarYear-12-01 to \CalendarYear-12-last] \@wall@plm{December}; \\
+ };
+ \@wall@plNotes
+\end{tikzpicture}%
+}
+#+end_src
+
+** \textbackslash YearPlannerLandscape
+
+#+begin_src tex
+\newcommand\YearPlannerLandscape{%
+\@wall@usePlannerMoons%
+\begin{tikzpicture}%
+ \calendar (cal) [
+ year planner landscape,
+ dates=\CalendarYear-01-01 to \CalendarYear-12-31,
+ ] \@wall@plmYear;
+ \@wall@plNotesOneCalendar
+\end{tikzpicture}%
+}
+#+end_src
+
+** \textbackslash YearPlannerLandscapeGrid
+
+#+begin_src tex
+\newcommand\YearPlannerLandscapeGrid{%
+\@wall@usePlannerMoons%
+\begin{tikzpicture}
+
+ % Background frame
+
+ \node (bg) [
+ rectangle,
+ inner sep = 0pt,
+ minimum width = \plannerGridCalendarWidth,
+ minimum height = \plannerGridCalendarHeight,
+ ] {};
+
+ \foreach \x/\m in {1/\xJanShort, 2/\xFebShort, 3/\xMarShort, 4/\xAprShort,
+ 5/\xMayShort, 6/\xJunShort, 7/\xJulShort, 8/\xAugShort, 9/\xSepShort,
+ 10/\xOctShort, 11/\xNovShort, 12/\xDecShort}
+ {
+ \setlength{\@tmp@a}{\x\plannerGridRowYShift + \plannerGridDayHeadingsHeight}
+
+ % Month labels
+
+ \node [
+ below = \@tmp@a of bg.north west,
+ yshift = 0.5\plannerGridRowYShift,
+ xshift = 0.5\plannerGridColXShift - 2pt,
+ anchor = base,
+ rotate = 90,
+ ] {\plannerGridMonthFmt\MakeUppercase{\textls*{\m}}};
+
+ % Horizontal lines
+
+ \addtolength{\@tmp@a}{-\plannerGridRowYShift}
+
+ \node (h-a-\x) [below = \@tmp@a of bg.north west] {};
+ \node (h-b-\x) [below = \@tmp@a of bg.north east] {};
+ \draw [gridcolor] (h-a-\x) -- (h-b-\x);
+ }
+
+ % 13th line
+ \setlength{\@tmp@a}{12\plannerGridRowYShift + \plannerGridDayHeadingsHeight}
+ \node (h-a-13) [below = \@tmp@a of bg.north west] {};
+ \node (h-b-13) [below = \@tmp@a of bg.north east] {};
+ \draw [gridcolor] (h-a-13) -- (h-b-13);
+
+ % Year number in the corner
+ \node [
+ right = 0pt of bg.north west,
+ xshift = 0.5\plannerGridMonthNamesWidth,
+ yshift = -0.5\plannerGridDayHeadingsHeight - 5pt,
+ anchor = base,
+ ] {\plannerGridYearNumberFmt\CalendarYear};
+
+ \setcounter{verticalCount}{1}
+
+ \foreach \i in {0,1,2,3,4,5} {
+ \foreach \j/\d in {
+ 0/\xMondayDayLetter,
+ 1/\xTuesdayDayLetter,
+ 2/\xWednesdayDayLetter,
+ 3/\xThursdayDayLetter,
+ 4/\xFridayDayLetter,
+ 5/\xSaturdayDayLetter,
+ 6/\xSundayDayLetter}
+ {
+ \addtocounter{verticalCount}{1}
+ \ifnumgreater{\value{verticalCount}}{38}{\relax}{
+ \setlength{\@tmp@a}{7\plannerGridColXShift}
+ \setlength{\@tmp@a}{\i\@tmp@a + \j\plannerGridColXShift + \plannerGridMonthNamesWidth}
+
+ % Day headings (top and bottom)
+
+ \node [
+ right = \@tmp@a of bg.north west,
+ xshift = 0.5\plannerGridColXShift + 4pt,
+ yshift = -0.5\plannerGridDayHeadingsHeight - 5pt,
+ anchor = base,
+ ] {\plannerGridDateDayFmt \d};
+
+ \node [
+ right = \@tmp@a of bg.south west,
+ xshift = 0.5\plannerGridColXShift + 4pt,
+ yshift = 0.5\plannerGridDayHeadingsHeight - 5pt,
+ anchor = base,
+ ] {\plannerGridDateDayFmt \d};
+
+ % % Vertical lines
+
+ % \node (v-a-\i-\j) [right = \@tmp@a of bg.north west] {};
+ % \node (v-b-\i-\j) [right = \@tmp@a of bg.south west] {};
+ % \draw [gridcolor] (v-a-\i-\j) -- (v-b-\i-\j);
+ }
+ }
+ }
+
+ \calendar (cal) [
+ year planner landscape grid days,
+ dates=\CalendarYear-01-01 to \CalendarYear-12-31,
+ below right = 0pt and 0pt of bg.north west,
+ anchor = north west,
+ yshift = -\plannerGridDayHeadingsHeight - 3mm,
+ xshift = \plannerGridMonthNamesWidth + 0.5\plannerGridColXShift + 4pt,
+ ] \@wall@plmYear;
+
+ \@wall@plNotesOneCalendar
+
+\end{tikzpicture}%
+}
+#+end_src
+
+** \textbackslash YearPlannerLandscapeGridPage
+
+#+begin_src tex
+\newcommand{\YearPlannerLandscapeGridPage}{%
+\pagecolor{pagebgcolor}%
+\AddToShipoutPictureFG*{\put(\LenToUnit{\@wall@leftMargin},\LenToUnit{\@wall@bottomMargin})%
+{\begin{minipage}[b]{\plannerGridCalendarWidth}%
+\YearPlannerLandscapeGrid
+
+\begin{minipage}[b][10mm][c]{\plannerGridCalendarWidth}%
+\plannerGridNotesFmt
+\hspace*{2mm}%
+\parseYearEvents[%
+ filter pred = hasNote,
+ format cmd = {\textsuperscript{\eIdx}~\eMonthShort~\eDay:~\textit{\eNote}\ifnumless{\eIdx}{\eMaxIdx}{,\space}{.}},
+]%
+\end{minipage}%
+\end{minipage}%
+}}}
+#+end_src
+
+* Translation keys
+
+#+begin_src tex
+% Load internal translations
+\InputIfFileExists{i18n/wallcalendar-\@wall@calendarLanguage.tex}{}%
+{\ClassError{wallcalendar}{File Not Found: i18n/wallcalendar-\@wall@calendarLanguage.tex}{}}
+
+% Load user translations if the option was set and translationsAutoload is true
+
+\newcommand\LoadTranslations{%
+\InputIfFileExists{\@wall@translationsInputFile}{}%
+{\ClassWarning{wallcalendar}{File Not Found: \@wall@translationsInputFile}{}}}
+
+\notblank{\@wall@translationsInputFile}{%
+\iftranslationsAutoload \LoadTranslations \fi}
+#+end_src
+
+Use =\ifcase= instead of a =\luadirect= array lookup, otherwise Portuguese day
+headings such as =\def\xMondayDayLetter{{2\textsuperscript{a}}}= cause an error.
+
+: #1 : month number, returns the translation
+
+#+begin_src tex
+\newcommand*\@tr@monthNumName[1]{%
+\ifcase#1 \relax\or \xJanuary\or \xFebruary\or \xMarch\or \xApril\or \xMay\or \xJune\or
+\xJuly\or \xAugust\or \xSeptember\or \xOctober\or \xNovember\or \xDecember\fi}
+#+end_src
+
+: #1 : weekday number, returns the one letter translation
+
+#+begin_src tex
+\newcommand*\@tr@dayLetter[1]{%
+\ifcase#1 \xMondayDayLetter\or \xTuesdayDayLetter\or \xWednesdayDayLetter\or
+\xThursdayDayLetter\or \xFridayDayLetter\or \xSaturdayDayLetter\or \xSundayDayLetter\fi}
+#+end_src
+
+* Helper macros
+
+Doing this in Lua to make blasted sure the result is just a string
+
+: #1 : month name in English, returns zero padded number
+
+#+begin_src tex
+\newcommand*{\monthToNum}[1]{%
+\luadirect{
+ local monthToNum = {
+ january = '01',
+ february = '02',
+ march = '03',
+ april = '04',
+ may = '05',
+ june = '06',
+ july = '07',
+ august = '08',
+ september = '09',
+ october = '10',
+ november = '11',
+ december = '12',
+ }
+ local key = string.lower('#1')
+ tex.sprint(monthToNum[key])
+}}
+#+end_src
+
+: #1 : month number, returns the name in English
+
+#+begin_src tex
+\newcommand*\monthName[1]{%
+% \ifcase might be just fine here
+\luadirect{
+ local monthName = {
+ 'January', 'February', 'March', 'April', 'May', 'June', 'July',
+ 'August', 'September', 'October', 'November', 'December',
+ }
+ local key = tonumber('#1')
+ tex.sprint(monthName[key])
+}}
+#+end_src
+
+* Epilogue
+
+#+begin_src tex
+% End of wallcalendar.cls
+#+end_src
diff --git a/macros/luatex/latex/wallcalendar/doc/wallcalendar-code.tex b/macros/luatex/latex/wallcalendar/doc/wallcalendar-code.tex
new file mode 100644
index 0000000000..fd8309927a
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/wallcalendar-code.tex
@@ -0,0 +1,2371 @@
+\documentclass[11pt,oneside]{memoir-article}
+\usepackage{local}
+\renewcommand{\docVersion}{v1.3.1}
+\renewcommand{\docUrl}{\href{https://github.com/profound-labs/wallcalendar/}{link}}
+\hypersetup{ pdfauthor={Gambhīro Bhikkhu}, }
+\maxtocdepth{section}
+\author{Gambhīro Bhikkhu}
+\date{\today}
+\title{Wallcalendar Code Documentation}
+\hypersetup{
+ pdfauthor={Gambhīro Bhikkhu},
+ pdftitle={Wallcalendar Code Documentation},
+ pdfkeywords={},
+ pdfsubject={},
+ pdfcreator={Emacs 25.1.1 (Org mode 9.0.9)},
+ pdflang={English}}
+\begin{document}
+
+\maketitle
+
+\chapter{Introduction}
+\label{sec:org96389a7}
+
+\bigskip
+
+This is the code documentation for the \texttt{wallcalendar} documentclass.
+
+The \textbf{User Guide} is in \texttt{wallcalendar.pdf}. Clone or download from Github:
+
+\href{https://github.com/profound-labs/wallcalendar/}{https://github.com/profound-labs/wallcalendar/}
+
+\bigskip
+
+\tableofcontents*
+
+\clearpage
+
+\chapter{Header}
+\label{sec:org45bc02b}
+
+\begin{verbatim}
+% wallcalendar.cls; Don't edit this file. Edit wallcalendar-code.org with emacs org-mode and call 'org-babel-tangle'.
+%
+% Wall Calendar
+%
+% A wall calendar document class with custom layouts and support for internationalization.
+%
+% (c) Gambhiro Bhikkhu, 2017
+% gambhiro.bhikkhu.85@gmail.com
+%
+% LPPL LaTeX Public Project License
+\end{verbatim}
+
+\chapter{Identification}
+\label{sec:org29781fd}
+
+\begin{verbatim}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{wallcalendar}[2017/10/21 v1.3.1 A wall calendar class with custom layouts and support for internationalization.]
+\end{verbatim}
+
+\chapter{Preliminary Declarations}
+\label{sec:org2ebd68a}
+
+\begin{verbatim}
+\RequirePackage{pgfopts}
+\RequirePackage{calc}
+
+\newlength\calPaperWidth
+\newlength\calPaperHeight
+\newlength\@wall@leftMargin
+\newlength\@wall@rightMargin
+\newlength\@wall@topMargin
+\newlength\@wall@bottomMargin
+
+\def\@wall@eventsCsv{}
+\def\@wall@markDefaultsCsv{}
+\def\@wall@translationsInputFile{}
+
+\newcommand*\theMonthName{}
+\end{verbatim}
+
+\chapter{Options}
+\label{sec:orgf63949e}
+
+Paper sizes and ratios.
+
+\begin{verbatim}
+Choral Octavo = 6.75in x 10.5in = 171.45mm x 266.7mm , r = 1.5555
+The calendar row is 40mm (without bleed) = 1.5748in
+\end{verbatim}
+
+\begin{verbatim}
+When photo is above the calendar row, it has only three side bleed.
+So aspect ratio:
+(10.5in - 40mm + 3mm) / (6.75in + 6mm) =
+(266.7 - 40 + 3) / (171.45 + 6) =
+= 1.2944
+\end{verbatim}
+
+\begin{verbatim}
+\newif\ifvarnishmask
+\newif\ifshowframe
+\newif\iftranslationsAutoload
+\newif\ifloadBabel
+
+\pgfkeys{
+ /wall/.is family, /wall,
+ defaults/.style = {
+ year = \the\year,
+ altyear = \empty,
+ loadBabel = false,
+ language = english,
+ translationsAutoload = true,
+ imageFolder = {./src-images},
+ choralOctavoPaper,
+ hMargin = 17mm,
+ topMargin = 20.5mm,
+ bottomMargin = 10mm,
+ },
+ year/.store in = \CalendarYear,
+ year/.initial = \the\year,
+ altyear/.store in = \CalendarAltYear,
+ altyear/.initial = \empty,
+ language/.store in = \@wall@calendarLanguage,
+ loadBabel/.is if = loadBabel,
+ translationsInputFile/.store in = \@wall@translationsInputFile,
+ translationsInputFile/.initial = {},
+ translationsAutoload/.is if = translationsAutoload,
+ eventsCsv/.store in = \@wall@eventsCsv,
+ eventsCsv/.initial = {},
+ markDefaultsCsv/.store in = \@wall@markDefaultsCsv,
+ markDefaultsCsv/.initial = {},
+ varnishmask/.is if = varnishmask,
+ showframe/.is if = showframe,
+ imageFolder/.store in = \@wall@imageFolder,
+ paperWidth/.code = {\setlength{\calPaperWidth}{#1}},
+ paperHeight/.code = {\setlength{\calPaperHeight}{#1}},
+ hMargin/.code = {\setlength{\@wall@leftMargin}{#1}%
+ \setlength{\@wall@rightMargin}{#1}},
+ leftMargin/.code = {\setlength{\@wall@leftMargin}{#1}},
+ rightMargin/.code = {\setlength{\@wall@rightMargin}{#1}},
+ topMargin/.code = {\setlength{\@wall@topMargin}{#1}},
+ bottomMargin/.code = {\setlength{\@wall@bottomMargin}{#1}},
+ % Paper sizes
+ choralOctavoPaper/.style = {paperWidth = 6.75in, paperHeight = 10.5in},
+ a2Paper/.style = {paperWidth = 420mm, paperHeight = 594mm},
+ a2PaperLandscape/.style = {paperWidth = 594mm, paperHeight = 420mm},
+ a3Paper/.style = {paperWidth = 297mm, paperHeight = 420mm},
+ a3PaperLandscape/.style = {paperWidth = 420mm, paperHeight = 297mm},
+ a4Paper/.style = {paperWidth = 210mm, paperHeight = 297mm},
+ a4PaperLandscape/.style = {paperWidth = 297mm, paperHeight = 210mm},
+ a5Paper/.style = {paperWidth = 148mm, paperHeight = 210mm},% r = 1.4142 = sqrt(2)
+ prevPaper/.style = {paperWidth = 170mm, paperHeight = 250mm},% r = 1.4705
+}
+
+% Debug with: \wlog{YEA: \the\@wall@bottomMargin}
+
+\DeclareOption*{%
+ \PassOptionsToClass{\CurrentOption}{memoir}
+}
+
+\pgfkeys{/wall, defaults}
+\ProcessPgfOptions{/wall}
+\ProcessOptions\relax
+\end{verbatim}
+
+\chapter{More Declarations}
+\label{sec:org1544dc5}
+\section{Load memoir}
+\label{sec:org2d3abb2}
+
+\begin{verbatim}
+\LoadClass[11pt,oneside]{memoir}
+\end{verbatim}
+
+\section{Temp variables}
+\label{sec:orge07ee5a}
+
+\begin{verbatim}
+\newlength\@tmp@a
+\newlength\@tmp@b
+\newlength\@tmp@c
+\newlength\@tmp@width
+\newlength\@tmp@height
+\end{verbatim}
+
+\section{Require packages}
+\label{sec:orgd636a69}
+
+\begin{verbatim}
+\ifloadBabel
+\RequirePackage[\@wall@calendarLanguage]{babel}
+\fi
+
+\RequirePackage{nag}
+%\RequirePackage{textcomp}
+\RequirePackage[cmyk]{xcolor}
+\RequirePackage{graphicx}
+\DeclareGraphicsExtensions{.pdf,.png,.jpg}
+\graphicspath{{\@wall@imageFolder}}
+
+\RequirePackage{eso-pic}
+\RequirePackage{ccicons}
+\RequirePackage{multicol}
+\RequirePackage{wasysym}
+
+\RequirePackage{pdftexcmds}
+\RequirePackage{etoolbox}
+\RequirePackage{luacode}
+
+\RequirePackage{xcoffins}
+%\RequirePackage{xstring}
+%\RequirePackage{stringstrings}
+
+\ifloadBabel
+\RequirePackage[final,babel=true]{microtype}
+\else
+\RequirePackage[final]{microtype}
+\fi
+
+\RequirePackage{tikz}
+\usetikzlibrary{calendar}
+\usetikzlibrary{positioning}
+\usetikzlibrary{fit}
+\usetikzlibrary{shapes.geometric}
+
+% http://tex.stackexchange.com/a/20426/831
+\pgfdeclarelayer{one}
+\pgfdeclarelayer{two}
+\pgfsetlayers{main,one,two}
+
+\pgfkeys{%
+ /tikz/on layer/.code={
+ \pgfonlayer{#1}\begingroup
+ \aftergroup\endpgfonlayer
+ \aftergroup\endgroup
+ }
+}
+\end{verbatim}
+
+\section{Colors}
+\label{sec:org281ee7a}
+
+\begin{verbatim}
+\definecolor{textbody}{gray}{0.15}
+
+% pantone 1245C, RGB 191,145,12 HEX: #BF910C
+% pantone 1255C, CMYK 0,27.5,100,34
+\definecolor{gold}{cmyk}{0,0.275,1,0.34}
+\definecolor{darkgold}{cmyk}{0.27,0.53,1,0.09}
+%\definecolor{orangegold}{cmyk}{0,0.31,0.89,0}
+\colorlet{orangegold}{darkgold}
+
+\colorlet{gridcolor}{black!30}
+\colorlet{weekday}{black}
+\colorlet{weekend}{black!50}
+\colorlet{mooncolor}{textbody}
+
+\definecolor{datenum}{gray}{0.3}
+\definecolor{plannerdatenum}{gray}{0.15}
+\definecolor{quote}{gray}{0.3}
+\definecolor{notes}{gray}{0.3}
+
+\definecolor{gridcolor}{gray}{0.5}
+\colorlet{pagebgcolor}{gridcolor!60}
+\end{verbatim}
+
+\texttt{showframe} option colors:
+
+\begin{verbatim}
+\colorlet{photo-frame}{blue}
+\colorlet{quote-frame}{red}
+\colorlet{heading-frame}{brown}
+\colorlet{calendar-frame}{orange}
+\colorlet{events-frame}{green}
+
+\ifshowframe
+ \colorlet{calendarbg}{black!50}
+\else
+ \colorlet{calendarbg}{white}
+\fi
+\end{verbatim}
+
+\section{Page Size and Trim Marks}
+\label{sec:orgf70f7fe}
+
+\begin{verbatim}
+\ifshowtrims
+ \setstocksize{\calPaperHeight + 35mm}{\calPaperWidth + 35mm}
+ \setlength{\paperheight}{\calPaperHeight}
+ \setlength{\paperwidth}{\calPaperWidth}
+ \trimXmarks
+ \trimLmarks
+ \quarkmarks
+ \settrims{0.5\stockheight - 0.5\paperheight}{0.5\stockwidth - 0.5\paperwidth}
+ \settrimmedsize{\calPaperHeight}{\calPaperWidth}{*}
+\else\relax
+ \setstocksize{\calPaperHeight}{\calPaperWidth}
+ \settrims{0pt}{0pt}
+ \settrimmedsize{\stockheight}{\stockwidth}{*}
+\fi
+
+%\settypeblocksize{\stockheight}{\stockwidth}{*}
+% TODO: calculate margins by ratios to paper size
+\setlrmarginsandblock{\@wall@leftMargin}{\@wall@rightMargin}{*}
+\setulmarginsandblock{\@wall@topMargin}{\@wall@bottomMargin}{*}
+\setheadfoot{0pt}{0pt}
+\setheaderspaces{0pt}{*}{*}
+
+\checkandfixthelayout% This will typeout values in pt.
+\settypeoutlayoutunit{mm}% It is useful to see layout values in mm too.
+\typeoutlayout
+\end{verbatim}
+
+\section{Base font sizes and indents}
+\label{sec:org215fe38}
+
+\begin{verbatim}
+\def\@wall@fontSize{11}
+\def\@wall@lineHeight{13.6}
+
+\renewcommand{\normalsize}{%
+ \@setfontsize\normalsize\@wall@fontSize\@wall@lineHeight
+ \abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@
+ \abovedisplayshortskip \z@ \@plus3\p@
+ \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
+ \belowdisplayskip \abovedisplayskip
+ \color{textbody}
+ \let\@listi\@listI}
+\normalsize
+
+\setlength{\vgap}{1.5em}
+\setlength{\vindent}{\vgap}
+\setlength{\vleftmargin}{2em}
+
+\setlength{\parskip}{0pt}
+\setlength{\parindent}{0pt}
+
+\setlength{\fboxsep}{0pt}
+\end{verbatim}
+
+\section{Helpers}
+\label{sec:org4c3f5ae}
+
+\begin{verbatim}
+#1 -- [fill=red, opacity=0.2], additional options used for showframe
+#2 -- "hasvarnish", to indicate varnishmask color replacement when =varnishmask= option is used
+#3 -- the content to hold the place for
+\end{verbatim}
+
+The \texttt{varnishmask} and \texttt{showframe} options are handled by the same \texttt{\textbackslash{}placeholder}
+helper command to avoid having to use two commands and repeating the content
+argument.
+
+\begin{verbatim}
+\definecolor{varnishmask}{gray}{0}
+
+% http://tex.stackexchange.com/a/59571/831
+\newcommand*{\strcmpblank}[3]{%
+ \ifnum\pdf@strcmp{#1}{}=\z@ #2\else #3\fi
+}
+
+\newcommand\@placeholder@pre[1]{%
+ \settowidth{\@tmp@width}{#1}%
+ \settototalheight{\@tmp@height}{#1}%
+ \def\@spacer{\rule{\@tmp@width}{0pt}\rule{0pt}{\@tmp@height}}%
+}
+
+\newcommand\placeholder[3][]{%
+ \ifvarnishmask%
+ \ifstrequal{#2}{hasvarnish}{%
+ \@placeholder@pre{#3}%
+ \tikz\node[fill=varnishmask, inner sep=0pt]{\@spacer};%
+ }{}%
+ \else%
+ \ifshowframe%
+ \@placeholder@pre{#3}%
+ \tikz\node[inner sep=0pt, opacity=0.6, #1]{\@spacer};%
+ \else%
+ #3%
+ \fi%
+ \fi%
+}
+\end{verbatim}
+
+\chapter{Keys setup}
+\label{sec:orge5d42f4}
+\section{/put photo}
+\label{sec:org198eca9}
+
+\begin{verbatim}
+\def\@wall@photo@putPhoto#1{#1}
+\def\@wall@photo@setYOffset{}
+
+\pgfkeys{
+ /put photo/.is family, /put photo,
+ simple/.code = {%
+ \def\@wall@photo@putPhoto##1{%
+ \includegraphics{##1}%
+ }%
+ \def\@wall@photo@setYOffset{}%
+ },
+ full page/.code = {%
+ \def\@wall@photo@putPhoto##1{%
+ \includegraphics[%
+ keepaspectratio,%
+ width={\calPaperWidth + 2\@t@bleed},%
+ ]{##1}%
+ }%
+ \def\@wall@photo@setYOffset{}%
+ },
+ full width above calendar/.code = {%
+ \def\@wall@photo@putPhoto##1{%
+ \includegraphics[%
+ keepaspectratio,%
+ width={\calPaperWidth + 2\@t@bleed},%
+ ]{##1}%
+ }%
+ \def\@wall@photo@setYOffset{%
+ \setlength{\@t@yOffset}{\@t@calendar@height + \@t@bleed + 1pt}%
+ }%
+ },
+ full width/.code = {%
+ \def\@wall@photo@putPhoto##1{%
+ \includegraphics[%
+ keepaspectratio,%
+ width={\calPaperWidth + 2\@t@bleed},%
+ ]{##1}%
+ }%
+ \def\@wall@photo@setYOffset{%
+ \setlength{\@t@yOffset}{\@t@calendar@height + \@t@bleed}%
+ }%
+ },
+}
+\end{verbatim}
+
+\section{/Photo}
+\label{sec:orgbfbfe40}
+
+\begin{verbatim}
+\pgfkeys{
+ /Photo/.is family, /Photo,
+ init/.style = {
+ defaults/.style = {file = {}, thumbFile = {}, caption = {}, bleed = 0pt, xOffset=0pt, yOffset=0pt},
+ file/.initial = {},
+ thumbFile/.initial = {},
+ caption/.initial = {},
+ bleed/.initial = 0pt,
+ xOffset/.initial = 0pt,
+ yOffset/.initial = 0pt,
+ },
+}
+\end{verbatim}
+
+\section{/Quote}
+\label{sec:orgfc6858a}
+
+\begin{verbatim}
+\pgfkeys{
+ /Quote/.is family, /Quote,
+ init/.style = {
+ defaults/.style = {position=center, text={}, xOffset=0pt, yOffset=0pt},
+ position/.initial = {},
+ text/.initial = {},
+ xOffset/.initial = 0pt,
+ yOffset/.initial = 0pt,
+ },
+}
+\end{verbatim}
+
+\section{/Calendar}
+\label{sec:orgd6a2f68}
+
+\begin{verbatim}
+\pgfkeys{
+ /Calendar/.is family, /Calendar,
+ init/.style = {
+ defaults/.style = {bg/.style={opacity=0.5}},
+ bg/.style = {},
+ minimum height/.initial = {},
+ },
+}
+\end{verbatim}
+
+\section{/Events}
+\label{sec:org9996966}
+
+\begin{verbatim}
+\pgfkeys{
+ /Events/.is family, /Events,
+ init/.style = {
+ defaults/.style = {day code = {}, marks = {}, text = {}},
+ day code/.initial = {},
+ marks/.initial = {},
+ text/.initial = {},
+ },
+}
+\end{verbatim}
+
+\section{/Txt}
+\label{sec:org412e39a}
+
+\begin{verbatim}
+\pgfkeys{
+ /Txt/.is family, /Txt,
+ init/.style = {
+ defaults/.style = {text = {}},
+ text/.initial = {},
+ },
+}
+\end{verbatim}
+
+\section{/parseMonthEvents}
+\label{sec:orgab06397}
+
+\begin{verbatim}
+\def\eIdx{}
+\def\eMaxIdx{}
+\def\eMark{}
+\def\eIsoDate{}
+\def\eYear{}
+\def\eMonth{}
+\def\eMonthShort{}
+\def\eDay{}
+\def\eDayText{}
+\def\eNote{}
+
+\pgfkeys{
+ /parseMonthEvents/.is family, /parseMonthEvents,
+ month/.initial = {},
+ filter pred/.initial = nil,
+ format func/.initial = nil,
+ format cmd/.initial = {},
+ events csv/.initial = {},
+ mark defaults csv/.initial = {},
+ min events/.initial = {},
+ defaults/.style = {
+ month = \theMonthName,
+ filter pred = nil,
+ format func = nil,
+ format cmd = {\textsuperscript{\eIdx}~\eMonthShort~\eDay:~\eNote\par},
+ events csv = \@wall@eventsCsv,
+ mark defaults csv = \@wall@markDefaultsCsv,
+ min events = nil,
+ },
+}
+\end{verbatim}
+
+\section{/parseYearEvents}
+\label{sec:org3b4e036}
+
+\begin{verbatim}
+\pgfkeys{
+ /parseYearEvents/.is family, /parseYearEvents,
+ year/.initial = {},
+ filter pred/.initial = nil,
+ format func/.initial = nil,
+ format cmd/.initial = {},
+ events csv/.initial = {},
+ mark defaults csv/.initial = {},
+ min events/.initial = {},
+ defaults/.style = {
+ year = \CalendarYear,
+ filter pred = nil,
+ format func = nil,
+ format cmd = {\textsuperscript{\eIdx}~\eMonthShort~\eDay:~\eNote\ifnumless{\eIdx}{\eMaxIdx}{,\space}{.}},
+ events csv = \@wall@eventsCsv,
+ mark defaults csv = \@wall@markDefaultsCsv,
+ min events = nil,
+ },
+}
+\end{verbatim}
+
+\chapter{Event Marks}
+\label{sec:org9c1a6a1}
+\section{Kite}
+\label{sec:orgb28c6c4}
+
+\begin{verbatim}
+\newcommand\StarMark{*}
+
+\newcommand\NoteStarMark{*}
+\end{verbatim}
+
+A kite mark that is the same height as the \texttt{\textbackslash{}StarMark}. Note that the star (*)
+character is usually higher than the x-height, so it is not in the vertical
+center of its glyph box (i.e. not at the center of the character x):
+
+\frame{x} \frame{*}
+
+\begin{verbatim}
+\newlength\@wall@starHeight
+
+% Measure the star's height here, so that we are measuring with the current typeface.
+\newcommand\KiteMark{%
+\setlength{\@wall@starHeight}{\totalheightof{*}}%
+\begin{tikzpicture}
+ \node (box) [
+ rectangle, minimum height=\@wall@starHeight, minimum width=3.4pt,
+ inner sep=0pt, line width=0pt,
+ ] {};
+ \node[
+ kite, draw, textbody, fill=textbody,
+ scale=0.15, kite vertex angles=60,
+ above=0pt of box.north, anchor=north,
+ ] {};%
+\end{tikzpicture}%
+}
+
+% Same as \KiteMark but with scale=0.2
+\newcommand\NoteKiteMark{\raisebox{1pt}{%
+\setlength{\@wall@starHeight}{\totalheightof{*}}%
+\begin{tikzpicture}
+ \node (box) [
+ rectangle, minimum height=\@wall@starHeight, minimum width=3.4pt,
+ inner sep=0pt, line width=0pt,
+ ] {};
+ \node[
+ kite, draw, textbody, fill=textbody,
+ scale=0.2, kite vertex angles=60,
+ above=0pt of box.north, anchor=north,
+ ] {};%
+\end{tikzpicture}%
+}}
+\end{verbatim}
+
+\section{Moons}
+\label{sec:org711444c}
+
+\begin{verbatim}
+\tikzstyle{moon circle}=[
+ circle,
+ inner sep=0pt,
+ line width=0pt,
+ minimum height=8pt,
+]
+
+\newlength\@wall@moonRaise
+\setlength{\@wall@moonRaise}{-0.7pt}
+
+\newcommand\NewMoon{}
+\newcommand\FirstQuarter{}
+\newcommand\FullMoon{}
+\newcommand\LastQuarter{}
+
+\newcommand\@wall@NewMoon{%
+\raisebox{\@wall@moonRaise}{%
+ \tikz\node[moon circle, fill=mooncolor] {};%
+}}
+
+\newcommand\@wall@FullMoon{%
+\raisebox{\@wall@moonRaise}{%
+ \tikz\node[moon circle, draw, mooncolor, line width=0.3pt] {};%
+}}
+
+\newcommand\@wall@FirstQuarter{%
+\raisebox{\@wall@moonRaise}{%
+\begin{tikzpicture}
+\node [moon circle, name=waxing] {};
+\path[fill=mooncolor]
+ (waxing.north) --
+ (waxing.south) to[out=-180,in=-90]
+ (waxing.west) to[out=90,in=-180]
+ (waxing.north);
+\end{tikzpicture}%
+}}
+
+\newcommand\@wall@LastQuarter{%
+\raisebox{\@wall@moonRaise}{%
+\begin{tikzpicture}
+\node [moon circle, name=waning] {};
+\path[fill=mooncolor]
+ (waning.north) --
+ (waning.south) to[out=0,in=-90]
+ (waning.east) to[out=90,in=0]
+ (waning.north);
+\end{tikzpicture}%
+}}
+
+\newcommand\@wall@useDefaultMoons{%
+\renewcommand\NewMoon{\@wall@NewMoon}%
+\renewcommand\FirstQuarter{\@wall@FirstQuarter}%
+\renewcommand\FullMoon{\@wall@FullMoon}%
+\renewcommand\LastQuarter{\@wall@LastQuarter}%
+}
+
+\newcommand\plannerMoonSize{\@setfontsize\plannerMoonSize{14}{14}}
+\newcommand*\plannerMoonFormat[1]{{\plannerMoonSize #1}}
+
+\newcommand\@wall@planner@NewMoon{\plannerMoonFormat{\CIRCLE}}
+\newcommand\@wall@planner@FirstQuarter{\plannerMoonFormat{\LEFTcircle}}
+\newcommand\@wall@planner@FullMoon{\plannerMoonFormat{\Circle}}
+\newcommand\@wall@planner@LastQuarter{\plannerMoonFormat{\RIGHTcircle}}
+
+\newcommand\@wall@usePlannerMoons{%
+\renewcommand\NewMoon{\@wall@planner@NewMoon}%
+\renewcommand\FirstQuarter{\@wall@planner@FirstQuarter}%
+\renewcommand\FullMoon{\@wall@planner@FullMoon}%
+\renewcommand\LastQuarter{\@wall@planner@LastQuarter}%
+}
+
+\@wall@useDefaultMoons
+\end{verbatim}
+
+\chapter{User Commands}
+\label{sec:orgcb9bf42}
+\section{\textbackslash SetPhoto}
+\label{sec:org8981ab6}
+
+\begin{verbatim}
+\SetPhoto[bleed=3mm]{June}
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand\SetPhoto[2][]{%
+ \pgfkeys{%
+ /Photo/#2/.is family, /Photo/#2,
+ /Photo/init,
+ defaults, file={#2},
+ #1%
+ }%
+}
+\end{verbatim}
+
+\section{\textbackslash SetCalendar}
+\label{sec:org4aef638}
+
+\begin{verbatim}
+\SetCalendar[bg={opacity=0.8}]{June}
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand\SetCalendar[2][]{%
+ \pgfkeys{%
+ /Calendar/#2/.is family, /Calendar/#2,
+ /Calendar/init,
+ defaults,
+ #1%
+ }%
+}
+\end{verbatim}
+
+\section{\textbackslash SetQuote}
+\label{sec:org6c9c7a1}
+
+\begin{verbatim}
+\SetQuote[position=top right, text align=right]{June}{%
+first line\\
+second line\\
+third line\\
+fourth line
+}
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand\SetQuote[3][]{%
+ \pgfkeys{%
+ /Quote/#2/.is family, /Quote/#2,
+ /Quote/init,
+ defaults, text={#3},
+ #1%
+ }%
+}
+\end{verbatim}
+
+\section{\textbackslash SetEvents}
+\label{sec:orgde29618}
+
+FIXME: Needs at least a \texttt{\textbackslash{}SetEvents\{\#2\}} to set defaults.
+
+\begin{verbatim}
+\SetEvents[yshift={10pt}]{August}{%
+marks
+}{%
+text
+}
+\end{verbatim}
+
+\begin{verbatim}
+#1 : options
+#2 : month name
+#3 : marks
+#4 : text
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand\SetEvents[4][]{%
+ \pgfkeys{%
+ /Events/#2/.is family, /Events/#2,
+ /Events/init,
+ defaults, marks={#3}, text={#4},
+ #1%
+ }%
+}
+\end{verbatim}
+
+\section{\textbackslash MonthPage}
+\label{sec:org6cd54c1}
+
+The \texttt{/MonthPage} key is set in-place for each page, not collecting options per month.
+
+\begin{verbatim}
+\pgfkeys{
+ /MonthPage/.is family, /MonthPage,
+ layout/.style = {layout handlers/#1/.get = \@wall@month@doLayout},
+ put photo/.style = {/put photo/#1},
+ defaults/.style = {layout = small landscape, put photo = simple},
+ layout handlers/.cd,
+ full page/.initial = \@wall@fullPageLayout,
+ small landscape/.initial = \@wall@smallLandscapeLayout,
+}
+\end{verbatim}
+
+FIXME: handle case when no \texttt{\textbackslash{}SetPhoto\{\#2\}} was called, and so options are not
+initialized. This happens for example when bleed value is missing, and \texttt{.get}
+returns \texttt{\textbackslash{}@val}:
+
+\begin{verbatim}
+! Missing number, treated as zero.
+<to be read again>
+\@val
+l.30 \MonthPage[layout=full page]{August}
+\end{verbatim}
+
+For now, just make sure there is a \texttt{\textbackslash{}SetPhoto\{August\}} before \texttt{\textbackslash{}MonthPage\{August\}}.
+
+\begin{verbatim}
+\MonthPage[layout=full page]{June}
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand\MonthPage[2][]{%
+ \pgfkeys{/MonthPage, defaults, #1}%
+ \@wall@month@doLayout{#2}%
+}
+\end{verbatim}
+
+\section{\textbackslash SetTxt}
+\label{sec:org5f9e367}
+
+\begin{verbatim}
+\SetTxt{August Quote}{%
+The text of the quote.
+}
+\end{verbatim}
+
+\begin{verbatim}
+#1 : key
+#2 : text
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand\SetTxt[2]{%
+ \pgfkeys{%
+ /Txt/#1/.is family, /Txt/#1,
+ /Txt/init,
+ defaults, text={#2},
+ }%
+}
+\end{verbatim}
+
+\section{\textbackslash txt}
+\label{sec:org396a316}
+
+\begin{verbatim}
+\txt{August Quote}
+\end{verbatim}
+
+\begin{verbatim}
+#1: text key
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand\txt[1]{%
+\pgfkeys{/Txt/#1/text/.get=\@val}%
+\@val%
+}
+\end{verbatim}
+
+\section{\textbackslash parseMonthEvents}
+\label{sec:org3b370cc}
+
+\begin{verbatim}
+\def\@t@monthName{}
+\def\@t@eventsCsv{}
+\def\@t@markDefaultsCsv{}
+\def\@t@filterPred{}
+\def\@t@formatFunc{}
+\def\@t@formatCmd{}
+\def\@t@minEvents{}
+
+\newcommand\monthMarkFmt{\color{textbody}}
+
+\newcommand\symbolSpace{\thinspace}
+\newcommand\symbolSeparator{,\symbolSpace}
+
+% #1 = option keys
+\newcommand*\parseMonthEvents[1][]{%
+\pgfkeys{/parseMonthEvents, defaults, #1,
+ month/.get=\@t@monthName,
+ filter pred/.get=\@t@filterPred,
+ format func/.get=\@t@formatFunc,
+ format cmd/.get=\@t@formatCmd,
+ events csv/.get=\@t@eventsCsv,
+ mark defaults csv/.get=\@t@markDefaultsCsv,
+ min events/.get=\@t@minEvents,
+}%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthEvents(
+ \luastring{\@t@monthName},
+ \@t@filterPred,
+ \@t@formatFunc,
+ \luastringO{\@t@formatCmd},
+ \luastring{\@t@eventsCsv},
+ \luastring{\@t@markDefaultsCsv},
+ \@t@minEvents
+)}}
+\end{verbatim}
+
+\section{\textbackslash parseYearEvents}
+\label{sec:orgb89e36b}
+
+\begin{verbatim}
+\def\@t@yearNum{}
+
+% #1 = option keys
+\newcommand*\parseYearEvents[1][]{%
+\pgfkeys{/parseYearEvents, defaults, #1,
+ year/.get=\@t@year,
+ filter pred/.get=\@t@filterPred,
+ format func/.get=\@t@formatFunc,
+ format cmd/.get=\@t@formatCmd,
+ events csv/.get=\@t@eventsCsv,
+ mark defaults csv/.get=\@t@markDefaultsCsv,
+ min events/.get=\@t@minEvents,
+}%
+\luadirect{
+require("wallcalendar-helpers.lua")
+yearEvents(
+ tonumber(\@t@year),
+ \@t@filterPred,
+ \@t@formatFunc,
+ \luastringO{\@t@formatCmd},
+ \luastring{\@t@eventsCsv},
+ \luastring{\@t@markDefaultsCsv},
+ \@t@minEvents
+)}}
+\end{verbatim}
+
+\section{\textbackslash parseMonthMarksDayText}
+\label{sec:org24e0024}
+
+NOTE: Tikz will not work with parsing options as with \texttt{\textbackslash{}parseMonthEvents}.
+
+It will parse the CSV file set with the \texttt{eventsCsv} class option.
+
+\begin{verbatim}
+\newlength\dayTextXshift
+\newlength\dayTextYshift
+\setlength{\dayTextXshift}{0pt}
+\setlength{\dayTextYshift}{0pt}
+
+\newlength\markNumberAbove
+\newlength\markNumberRight
+\setlength{\markNumberAbove}{-10pt}
+\setlength{\markNumberRight}{-3pt}
+
+\newlength\markDayTextAbove
+\newlength\markDayTextRight
+\setlength{\markDayTextAbove}{-10pt}
+\setlength{\markDayTextRight}{-3pt}
+
+\newcommand\parseMonthMarksDayText{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{\theMonthName}, nil, \luastring{\@wall@eventsCsv})
+tex.sprint(';')
+}}
+
+\newcommand\parseMonthMarksDayTextMonth[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{#1}, nil, \luastring{\@wall@eventsCsv})
+tex.sprint(';')
+}}
+\end{verbatim}
+
+\section{\textbackslash parseMonthMarksDayTextUsing}
+\label{sec:orgcf04e30}
+
+\begin{verbatim}
+\newcommand*\parseMonthMarksDayTextUsing[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{\theMonthName}, nil, \luastring{#1})
+}}
+
+\newcommand\parseMonthMarksDayTextMonthUsing[2]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{#1}, nil, \luastring{#2})
+}}
+\end{verbatim}
+
+\section{\textbackslash parseMonthMarksNote}
+\label{sec:orga2e07dc}
+
+\begin{verbatim}
+\newcommand*\parseMonthMarksNote{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksNote(\luastring{\theMonthName}, nil, \luastring{\@wall@eventsCsv}, \luastring{\@wall@markDefaultsCsv})
+}}
+\end{verbatim}
+
+\section{\textbackslash parseMonthMarksNoteUsing}
+\label{sec:org2e41aed}
+
+\begin{verbatim}
+\newcommand*\parseMonthMarksNoteUsing[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksNote(\luastring{\theMonthName}, nil, \luastring{#1}, \luastring{\@wall@markDefaultsCsv})
+}}
+\end{verbatim}
+
+\chapter{Page Layouts}
+\label{sec:orga58446b}
+\section{Initial setup}
+\label{sec:orgbe4e6d6}
+
+Applying a blank, bare pagestyle, the layout macro should position the parts of
+the page.
+
+\begin{verbatim}
+\makepagestyle{month}
+\makeoddhead{month}{}{}{}
+\makeevenhead{month}{}{}{}
+\makeoddfoot{month}{}{}{}
+\makeevenfoot{month}{}{}{}
+
+\pagestyle{month}
+\end{verbatim}
+
+These elements are common to all layouts. One Coffin for each part of the
+page:
+
+\begin{itemize}
+\item Photo
+\item Quote
+\item Calendar
+\item Events
+\end{itemize}
+
+\begin{verbatim}
+\NewCoffin\@wall@pageWrap
+\NewCoffin\@wall@photo
+\NewCoffin\@wall@quote
+\NewCoffin\@wall@calendar
+\NewCoffin\@wall@events
+\end{verbatim}
+
+\section{Formatting hooks and temp vars}
+\label{sec:orgab25392}
+
+\begin{verbatim}
+\newlength\@t@bleed
+\newlength\@t@rightOffset
+\newlength\@t@minipageWidth
+\newlength\@t@calendar@height
+\newlength\@t@calendar@hmargin
+\newlength\@t@calendar@dayYshift
+\newlength\@t@calendar@dayXshift
+\newlength\@t@calendar@gridHeight
+\newlength\@t@calendar@gridHeightFiveRows
+\newlength\@t@calendar@gridHeightSixRows
+\newlength\@t@xOffset
+\newlength\@t@yOffset
+\def\@t@file{}
+
+\newcommand*\monthFmt{}%
+\newcommand*\yearFmt{}%
+\newcommand*\dayLetterColor{}%
+\newcommand*\dayLetterFmt{}%
+\newcommand*\dayTextFmt{}%
+\newcommand*\quoteFmt{}%
+\newcommand*\headingFmt{}%
+\newcommand*\calendarFmt{}%
+\newcommand*\eventsFmt{}%
+\end{verbatim}
+
+\section{Layout Reset, \textbackslash @wall@layout@reset}
+\label{sec:org7522fd9}
+
+A reset macro for the beginning of a layout, to make sure parameters are not
+carried from one layout to the next.
+
+\begin{verbatim}
+\newcommand\@wall@layout@reset{%
+ \renewcommand*\monthFmt{}%
+ \renewcommand*\yearFmt{}%
+ \renewcommand*\dayLetterColor{}%
+ \renewcommand*\dayLetterFmt{}%
+ \renewcommand*\dayTextFmt{}%
+ \renewcommand*\quoteFmt{}%
+ \renewcommand*\headingFmt{}%
+ \renewcommand*\calendarFmt{}%
+ \renewcommand*\eventsFmt{}%
+ \def\@t@file{}%
+ \setlength{\@t@calendar@height}{0pt}%
+ \setlength{\@t@calendar@hmargin}{0pt}%
+ \setlength{\@t@calendar@dayYshift}{0pt}%
+ \setlength{\@t@calendar@dayXshift}{0pt}%
+ \setlength{\@t@bleed}{0pt}%
+ \setlength{\@t@rightOffset}{0pt}%
+ \setlength{\@t@minipageWidth}{0pt}%
+ \setlength{\@t@xOffset}{0pt}%
+ \setlength{\@t@yOffset}{0pt}%
+ \setlength{\@t@calendar@gridHeight}{0pt}%
+ \setlength{\@t@calendar@gridHeightFiveRows}{0pt}%
+ \setlength{\@t@calendar@gridHeightSixRows}{0pt}%
+}
+\end{verbatim}
+
+\section{Full Page, \textbackslash @wall@fullPageLayout}
+\label{sec:orge4db85d}
+\subsection{Setup formatting hooks}
+\label{sec:orge713968}
+
+Renew this in your document when customizing the variables for this layout.
+
+This must not introduce paragraph breaks or whitespace characters, so follow
+everything with \texttt{\%}.
+
+\begin{verbatim}
+\newcommand\fullPageFmt{%
+ \renewcommand*\monthFmt{\LARGE}%
+ \renewcommand*\yearFmt{\LARGE}%
+ \renewcommand*\dayLetterColor{}%
+ \renewcommand*\dayLetterFmt{\tiny}%
+ \renewcommand*\dayTextFmt{\small}%
+ \renewcommand*\quoteFmt{}%
+ \renewcommand*\headingFmt{\centering}%
+ \renewcommand*\calendarFmt{\centering}%
+ \renewcommand*\eventsFmt{\setlength{\parindent}{0pt}\raggedleft\footnotesize}%
+}
+\end{verbatim}
+
+\subsection{Init}
+\label{sec:org28b2a27}
+
+\begin{verbatim}
+\newcommand\@wall@fullPageLayout[2][]{%
+\makeatletter
+\renewcommand*\theMonthName{#2}
+\@wall@layout@reset
+\fullPageFmt
+
+\colorlet{weekday}{black}
+\colorlet{weekend}{black!70}
+\end{verbatim}
+
+\subsection{Lengths and sizes}
+\label{sec:orge5a9400}
+
+Bleed:
+
+\begin{verbatim}
+\pgfkeys{/Photo/#2/bleed/.get=\@val}
+\setlength{\@t@bleed}{\@val}
+\end{verbatim}
+
+\begin{verbatim}
+\def\@t@monthnum{\monthToNum{#2}}
+\end{verbatim}
+
+Calendar height:
+
+\begin{verbatim}
+% 40mm = 1.5748 inch
+% 43mm = 1.6929 inch
+\setlength{\@t@calendar@height}{40mm + \@t@bleed}
+
+% See if there was a height given in the options
+\pgfkeys{/Calendar/#2/minimum height/.get=\@val}
+\ifx\@val\empty \relax
+\else
+ \setlength{\@t@calendar@height}{\@val + \@t@bleed}
+\fi
+\end{verbatim}
+
+Calendar horizontal margin:
+
+\begin{verbatim}
+\setlength{\@t@calendar@hmargin}{20pt}
+\end{verbatim}
+
+Calculate offsets:
+
+\begin{verbatim}
+% NOTE: the -4pt and -2pt offset is somehow necessary for the sides to align
+% with the edges
+\setlength{\@t@rightOffset}{\@t@bleed +\@t@calendar@hmargin -4pt}
+\setlength{\@t@minipageWidth}{\calPaperWidth -2\@t@calendar@hmargin -2pt}
+\end{verbatim}
+
+\subsection{Set the coffin contents}
+\label{sec:orgf5b7748}
+
+Page wrap:
+
+\begin{verbatim}
+\SetHorizontalCoffin\@wall@pageWrap{%
+ \color{white}%
+ \rule{\textwidth}{0pt}%
+ \rule{0pt}{\textheight}%
+}
+\end{verbatim}
+
+Photo:
+
+\begin{verbatim}
+\pgfkeys{/Photo/#2/file/.get=\@t@file}
+
+\SetHorizontalCoffin\@wall@photo{%
+ \placeholder[fill=photo-frame]{hasvarnish}{%
+ \@wall@photo@putPhoto{\@t@file}%
+ }%
+}
+\end{verbatim}
+
+Quote:
+
+\begin{verbatim}
+\SetHorizontalCoffin\@wall@quote{%
+ \placeholder[fill=quote-frame]{}{%
+ \begin{minipage}{\linewidth}%
+ \quoteFmt
+ \pgfkeys{/Quote/#2/text/.get=\@val}%
+ \@val%
+ \end{minipage}%
+ }%
+}
+\end{verbatim}
+
+Calendar:
+
+\begin{verbatim}
+\SetHorizontalCoffin\@wall@calendar{%
+\ifvarnishmask\relax
+\else
+\begin{tikzpicture}
+
+\node (bg) [
+ fill = calendarbg,
+ opacity = 0.5,
+ minimum width = {\calPaperWidth + 2\@t@bleed},
+ anchor=north west,
+ /Calendar/#2/bg,
+ % override the style, in case bleed was set above
+ minimum height = {\@t@calendar@height},
+] at (0,0) {};
+
+\node (heading) [
+ below right=10pt and {\@t@rightOffset} of bg.north west,
+ anchor=north west,
+] {%
+\placeholder[fill=heading-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\headingFmt
+{\monthFmt\@tr@monthNumName{\@t@monthnum}}
+\hfill
+\strcmpblank{\CalendarAltYear}{%
+ {\yearFmt\CalendarYear}%
+}{%
+ {\yearFmt\CalendarYear/\CalendarAltYear}%
+}%
+\end{minipage}%
+}%
+};
+
+\node (calendar) [
+ below right=35pt and {\@t@rightOffset} of bg.north west,
+ anchor=north west,
+] {%
+\placeholder[fill=calendar-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\calendarFmt
+\tikz{\tikzMonthCalendar@fullpage{\@t@monthnum};}%
+\end{minipage}%
+}%
+};
+
+\node (events) [
+ below=0pt of calendar.south west,
+ anchor=north west,
+] {%
+\placeholder[fill=events-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\eventsFmt
+\pgfkeys{/Events/#2/text/.get=\@val}%
+\@val%
+\end{minipage}%
+}%
+};
+
+\end{tikzpicture}%
+\fi
+}% \SetHorizontalCoffin
+\end{verbatim}
+
+\subsection{Join the coffins}
+\label{sec:orgf57fc27}
+
+\begin{verbatim}
+\@wall@photo@setYOffset
+
+\pgfkeys{/Photo/#2/xOffset/.get=\@val}
+\addtolength{\@t@xOffset}{\@val}
+\pgfkeys{/Photo/#2/yOffset/.get=\@val}
+\addtolength{\@t@yOffset}{\@val}
+
+% NOTE: a small whitespace is visible on the left edge of the page when bleed is 0pt, a space must be getting in somewhere.
+\JoinCoffins*\@wall@pageWrap[l,t]\@wall@photo[l,t](-\spinemargin -\@t@bleed + \@t@xOffset, \uppermargin + \@t@bleed + \@t@yOffset)
+
+\pgfkeys{/Quote/#2/xOffset/.get=\@val}
+\setlength{\@t@xOffset}{\@val}
+\pgfkeys{/Quote/#2/yOffset/.get=\@val}
+\setlength{\@t@yOffset}{\@val}
+
+\JoinCoffins*\@wall@pageWrap[l,t]\@wall@quote[l,t](\@t@xOffset, \@t@yOffset)
+
+\JoinCoffins*\@wall@pageWrap[l,b]\@wall@calendar[l,b](-\spinemargin -\@t@bleed, \textheight +\uppermargin -\paperheight -\@t@bleed)
+
+\makeatother
+\end{verbatim}
+
+\subsection{Typeset}
+\label{sec:org4335a91}
+
+\begin{verbatim}
+\clearpage
+\TypesetCoffin\@wall@pageWrap%
+}% \@wall@fullPageLayout
+\end{verbatim}
+
+\subsection{Tikz calendar}
+\label{sec:org66a8015}
+
+\begin{verbatim}
+#1 = number of month with leading zero
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand*{\tikzMonthCalendar@fullpage}[1]{%
+\pgfkeys{/Events/\monthName{#1}/marks/.get=\@eventmarks}%
+\calendar (cal#1) [alnitak, dates=\CalendarYear-#1-01 to \CalendarYear-#1-last] \@eventmarks;%
+}
+\end{verbatim}
+
+\section{Small Landscape, \textbackslash @wall@smallLandscapeLayout}
+\label{sec:orgec90d96}
+\subsection{Setup formatting hooks}
+\label{sec:org19590f3}
+
+Renew this in your document when customizing the variables for this layout.
+
+This must not introduce paragraph breaks or whitespace characters, so follow
+everything with \texttt{\%}.
+
+\begin{verbatim}
+\newcommand\smallLandscapeFmt{%
+ \renewcommand*\monthFmt{\LARGE}%
+ \renewcommand*\yearFmt{\LARGE}%
+ \renewcommand*\dayLetterColor{}%
+ \renewcommand*\dayLetterFmt{\tiny}%
+ \renewcommand*\dayTextFmt{\small}%
+ \renewcommand*\quoteFmt{\centering}%
+ \renewcommand*\headingFmt{\centering}%
+ \renewcommand*\calendarFmt{\centering}%
+ \renewcommand*\eventsFmt{\setlength{\parindent}{0pt}\raggedright\footnotesize}%
+}
+\end{verbatim}
+
+\subsection{Init}
+\label{sec:org11161c1}
+
+\begin{verbatim}
+\newcommand\@wall@smallLandscapeLayout[2][]{%
+\makeatletter
+\renewcommand*\theMonthName{#2}
+\@wall@layout@reset
+\smallLandscapeFmt
+
+\colorlet{weekday}{black}
+\colorlet{weekend}{black!70}
+\end{verbatim}
+
+\subsection{Lengths and sizes}
+\label{sec:orgcdfd5b1}
+
+Bleed:
+
+\begin{verbatim}
+\pgfkeys{/Photo/#2/bleed/.get=\@val}
+\setlength{\@t@bleed}{\@val}
+\end{verbatim}
+
+\begin{verbatim}
+\def\@t@monthnum{\monthToNum{#2}}
+\end{verbatim}
+
+Calendar height:
+
+Default height to fit:
+
+\begin{itemize}
+\item day headings
+\item days in a grid, 6 rows
+\item events
+\item bottom bleed
+\end{itemize}
+
+\begin{verbatim}
+\setlength{\@t@calendar@height}{85mm + \@t@bleed}
+
+% See if there was a height given in the options
+\pgfkeys{/Calendar/#2/minimum height/.get=\@val}
+\ifx\@val\empty \relax
+\else
+ \setlength{\@t@calendar@height}{\@val + \@t@bleed}
+\fi
+\end{verbatim}
+
+Calendar horizontal margin:
+
+\begin{verbatim}
+\setlength{\@t@calendar@hmargin}{20pt}
+\end{verbatim}
+
+Calculate offsets:
+
+\begin{verbatim}
+% 5mm: day headings
+% 20mm: events
+% 6.5mm: vertical spacing
+\setlength{\@tmp@a}{20mm + 5mm + 6.5mm}
+\setlength{\@tmp@b}{\@t@calendar@height -\@tmp@a}
+\setlength{\@t@calendar@dayYshift}{0.1666\@tmp@b}% 1/6 = 0.1666
+
+\setlength{\@t@calendar@gridHeightSixRows}{\@tmp@b}
+\setlength{\@t@calendar@gridHeightFiveRows}{\@tmp@b -0.1666\@tmp@b}
+
+% NOTE: the -4pt and -2pt offset is somehow necessary for the sides to align
+% with the edges
+\setlength{\@t@rightOffset}{\@t@bleed +\@t@calendar@hmargin -4pt}
+\setlength{\@t@minipageWidth}{\calPaperWidth -2\@t@calendar@hmargin -2pt}
+
+\setlength{\@t@calendar@dayXshift}{0.1428\@t@minipageWidth}% 1/7 = 0.1428
+\end{verbatim}
+
+\subsection{Set the coffin contents}
+\label{sec:orgfa049f6}
+
+Page wrap:
+
+\begin{verbatim}
+\SetHorizontalCoffin\@wall@pageWrap{%
+ \color{white}%
+ \rule{\textwidth}{0pt}%
+ \rule{0pt}{\textheight}%
+}
+\end{verbatim}
+
+Photo:
+
+\begin{verbatim}
+\pgfkeys{/Photo/#2/file/.get=\@t@file}
+
+\SetHorizontalCoffin\@wall@photo{%
+ \placeholder[fill=photo-frame]{hasvarnish}{%
+ \@wall@photo@putPhoto{\@t@file}%
+ }%
+}
+\end{verbatim}
+
+Quote:
+
+\begin{verbatim}
+\SetHorizontalCoffin\@wall@quote{%
+ \placeholder[fill=quote-frame]{}{%
+ \begin{minipage}{\linewidth}%
+ \quoteFmt
+ \pgfkeys{/Quote/#2/text/.get=\@val}%
+ \@val%
+ \end{minipage}%
+ }%
+}
+\end{verbatim}
+
+Calendar:
+
+\begin{verbatim}
+\SetHorizontalCoffin\@wall@calendar{%
+\ifvarnishmask\relax
+\else
+\begin{tikzpicture}
+
+\node (bg) [
+ fill = calendarbg,
+ opacity = 1,
+ minimum width = {\calPaperWidth + 2\@t@bleed},
+ anchor=north west,
+ /Calendar/#2/bg,
+ % override the style, in case bleed was set above
+ minimum height = {\@t@calendar@height},
+] at (0,0) {};
+
+\node (heading) [
+ below right=10pt and {\@t@rightOffset} of bg.north west,
+ anchor=north west,
+] {%
+\placeholder[fill=heading-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\headingFmt
+{\monthFmt\@tr@monthNumName{\@t@monthnum}}
+\hfill
+\strcmpblank{\CalendarAltYear}{%
+ {\yearFmt\CalendarYear}%
+}{%
+ {\yearFmt\CalendarYear/\CalendarAltYear}%
+}%
+\end{minipage}%
+}%
+};
+
+\node (calendar) [
+ below right=35pt and {\@t@rightOffset} of bg.north west,
+ anchor=north west,
+] {%
+\placeholder[fill=calendar-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\calendarFmt
+\hspace*{-5pt}% FIXME
+\tikz{\tikzMonthCalendar@smallLandscape{\@t@monthnum};}%
+\end{minipage}%
+}%
+};
+
+\node (events) [
+ above right=10mm and {\@t@rightOffset} of bg.south west,
+ anchor=south west,
+] {%
+\placeholder[fill=events-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\eventsFmt
+\pgfkeys{/Events/#2/text/.get=\@val}%
+\@val%
+\end{minipage}%
+}%
+};
+
+\end{tikzpicture}%
+\fi
+}% \SetHorizontalCoffin
+\end{verbatim}
+
+\subsection{Join the coffins}
+\label{sec:orgd581032}
+
+Only using \texttt{yOffset}. The quote should be centered on the x axis.
+
+Join coffins so that the photo is in a fixed position, i.e. relative to the
+pageWrap, not relative to other coffins. It prevents accidental shifts when the
+other coffins are empty (when \texttt{varnishmask} is on) or have too much content.
+
+\begin{verbatim}
+% The quote has to be centered between the photo and the calendar with manual tweaking.
+% The height of the quote is not known, the height of the calendar plus its heading is not known.
+
+% TODO move the photo with /Photo/#2/xOffset and yOffset as at the full page layout
+
+\pgfkeys{/Quote/#2/yOffset/.get=\@val}
+\setlength{\@t@yOffset}{\@val}
+
+\JoinCoffins*\@wall@photo[hc,b]\@wall@quote[hc,t](0pt, \@t@yOffset)
+
+\pgfkeys{/Photo/#2/yOffset/.get=\@val}
+\setlength{\@t@yOffset}{\@val}
+
+% NOTE: Taking the bottom edge of the photo as fixed.
+% yOffset must be set to pull the photo down into position
+
+\JoinCoffins*\@wall@pageWrap[hc,t]\@wall@photo[hc,b](0pt, \uppermargin + \@t@yOffset)
+
+% Calendar is aligned to the bottom of the page.
+
+\JoinCoffins*\@wall@pageWrap[hc,b]\@wall@calendar[hc,b](0pt, \textheight +\uppermargin -\paperheight -\@t@bleed)
+
+\makeatother
+\end{verbatim}
+
+\subsection{Typeset}
+\label{sec:orgcdcedfd}
+
+\begin{verbatim}
+\clearpage
+\TypesetCoffin\@wall@pageWrap%
+}% \@wall@smallLandscapeLayout
+\end{verbatim}
+
+\subsection{Tikz calendar}
+\label{sec:orgf62996c}
+
+\begin{verbatim}
+#1 = number of month with leading zero
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand*{\tikzMonthCalendar@smallLandscape}[1]{%
+\pgfkeys{/Events/\monthName{#1}/marks/.get=\@eventmarks}%
+\calendar (cal#1) [betelgeuse, dates=\CalendarYear-#1-01 to \CalendarYear-#1-last] \@eventmarks;%
+}
+\end{verbatim}
+
+\section{Tikz styles}
+\label{sec:orga66f8a7}
+\subsection{day letter headings}
+\label{sec:org8b1a47f}
+
+\begin{verbatim}
+\tikzstyle{day letter headings}=[%
+ day heading/.style={black!90},
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ \pgfmathsetlength\pgf@xa{\tikz@lib@cal@xshift}%
+ \pgfmathsetlength\pgf@ya{\tikz@lib@cal@yshift}%
+ \foreach \d in {0,1,2,3,4,5,6} {%
+ \pgf@xa=\d\pgf@xa%
+ \pgftransformxshift{\pgf@xa}%
+ \pgftransformyshift{\pgf@ya}%
+ \node (d\d) [anchor=south, day heading] {\dayLetterFmt\@tr@dayLetter{\d}};%
+ };%
+ }{}%
+ },%
+]
+\end{verbatim}
+
+\subsection{days grid}
+\label{sec:orgfa12564}
+
+\begin{verbatim}
+\newcount\gridRows
+\newcount\gridLines
+\newcount\n
+
+\newif\ifGridNoSurround
+\GridNoSurroundfalse
+
+\tikzstyle{no grid surround}=[execute before day scope={\GridNoSurroundtrue}]
+\tikzstyle{grid surround}=[execute before day scope={\GridNoSurroundfalse}]
+
+\tikzstyle{days grid}=[%
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ %
+ % Determine if the grid is five or six rows
+ %
+ % 31 day months
+ \ifdate{between=01-01 and 01-31, between=03-01 and 03-31, between=05-01 and 05-31, between=07-01 and 07-31, between=08-01 and 08-31, between=10-01 and 10-31, between=12-01 and 12-31}{%
+ \ifdate{Saturday,Sunday}{%
+ \gridRows=6%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightSixRows}%
+ }{%
+ \gridRows=5%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightFiveRows}%
+ }
+ }{
+ % 30 day months and February
+ \ifdate{between=02-01 and 02-last}{%
+ \gridRows=5%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightFiveRows}%
+ }{%
+ \ifdate{Sunday}{%
+ \gridRows=6%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightSixRows}%
+ }{%
+ \gridRows=5%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightFiveRows}%
+ }
+ }
+ }
+ %
+ % Horizontal lines
+ %
+ \gridLines=\gridRows
+ \ifGridNoSurround\relax
+ \else
+ \advance\gridLines by 1
+ \n=0
+ \draw [
+ gridcolor,
+ line width=0.3pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ ] (0,{-\n\@t@calendar@dayYshift}) -- (7\@t@calendar@dayXshift,{-\n\@t@calendar@dayYshift});
+ \fi
+ \foreach \n in {1,2,3,4,5,6} {
+ \ifnum\n<\gridLines
+ \draw [
+ gridcolor,
+ line width=0.3pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ ] (0,{-\n\@t@calendar@dayYshift}) -- (7\@t@calendar@dayXshift,{-\n\@t@calendar@dayYshift});
+ \fi
+ }
+ %
+ % Vertical lines
+ %
+ \gridLines=7
+ \ifGridNoSurround\relax
+ \else
+ \advance\gridLines by 1
+ \n=0
+ \draw [
+ gridcolor,
+ line width=0.3pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ ] ({\n\@t@calendar@dayXshift},0) -- ({\n\@t@calendar@dayXshift},{-\gridRows\@t@calendar@dayYshift});
+ \fi
+ \foreach \n in {1,2,3,4,5,6,7} {
+ \ifnum\n<\gridLines
+ \draw [
+ gridcolor,
+ line width=0.3pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ ] ({\n\@t@calendar@dayXshift},0) -- ({\n\@t@calendar@dayXshift},{-\gridRows\@t@calendar@dayYshift});
+ \fi
+ }
+ %
+ % If we are not drawing the surrounding lines, it looks better to hide
+ % some of the top and bottom edges
+ %
+ \ifGridNoSurround
+ \draw [
+ color=white,
+ line width=6pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift={0.5\@t@calendar@dayYshift -1pt},
+ ] (0,0) -- (7\@t@calendar@dayXshift,0);
+ \draw [
+ color=white,
+ line width=6pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift={0.5\@t@calendar@dayYshift +1pt},
+ ] (0,-\gridRows\@t@calendar@dayYshift) -- (7\@t@calendar@dayXshift,-\gridRows\@t@calendar@dayYshift);
+ \fi
+ }{}%
+ }
+]
+\end{verbatim}
+
+\subsection{headings background rule}
+\label{sec:org4ba160c}
+
+\begin{verbatim}
+\tikzstyle{headings background rule}=[
+ background rule/.style={black!90, line width=0.3pt, yshift={0.3\@t@calendar@dayYshift -3pt}},
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ \draw [
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ background rule,
+ ] (0,0) -- (7\@t@calendar@dayXshift,0);
+ }{}%
+ }
+]
+\end{verbatim}
+
+\subsection{headings background bar}
+\label{sec:org20ae9c5}
+
+\begin{verbatim}
+\tikzstyle{headings background bar}=[
+ headings background rule,
+ background rule/.style={black!20, line width=10pt, yshift={0.3\@t@calendar@dayYshift +3.5pt}},
+]
+\end{verbatim}
+
+\section{Tikz calendar styles}
+\label{sec:org9d1f8e2}
+\subsection{Betelgeuse, days in a grid}
+\label{sec:org7b7858d}
+
+(Alpha Orionis)
+
+\begin{verbatim}
+\tikzstyle{betelgeuse}=[
+ no grid surround,
+ days grid,
+ week list,
+ day xshift=\@t@calendar@dayXshift,
+ day yshift=\@t@calendar@dayYshift,
+ headings background bar,
+ day letter headings,
+ day heading/.style={black!90, yshift={-0.3\@t@calendar@dayYshift}},
+ every day/.append style={anchor=base, inner xsep=0pt, yshift={-0.25\baselineskip}},
+ day text={\dayTextFmt\%d-},
+]
+\end{verbatim}
+
+\subsection{Alnitak, days in one line}
+\label{sec:org3b7f33a}
+
+(Zeta Orionis)
+
+\begin{verbatim}
+\tikzstyle{alnitak}=[
+ day list right,
+ day xshift={0pt},
+ every month/.append style={anchor=base, inner xsep=0pt, yshift=4mm, xshift=-\widthof{\space}},
+ day text={\dayTextFmt\%d-},
+ every day/.append style={anchor=base, inner xsep=0pt},
+ execute before day scope={
+ %
+ % === Moving the day number ===
+ %
+ % A small offset seems to improve the result, the last day gets closer to the end of the linewidth
+ \pgftransformxshift{0.01em}
+ \pgfcalendarjuliantodate{\pgfcalendarendjulian}{\currentyear}{\currentmonth}{\lastday}
+ % Width of month day digits from 1 - 28
+ \setlength{\@tmp@a}{\widthof{12345678910111213141516171819202122232425262728}}
+ \setlength{\@tmp@b}{\widthof{30}}
+ \pgfmathparse{(\linewidth - \@tmp@a - \@tmp@b * (\lastday-28)) / \lastday}
+ \pgftransformxshift{\pgfmathresult}
+ \let\%=\pgfcalendarshorthand
+ \setlength{\@tmp@a}{\widthof{\%d-}}
+ \pgftransformxshift{\@tmp@a}
+ %
+ % === Weekday letter above the day ===
+ %
+ \ifdate{weekend}{\def\dayLetterColor{\color{weekend}}}{\def\dayLetterColor{\color{weekday}}}%
+ \node[anchor=south,yshift=5mm,inner sep=0pt]{%
+ \dayLetterColor\dayLetterFmt\@tr@dayLetter{\pgfcalendarcurrentweekday}%
+ };%
+ },
+]
+\end{verbatim}
+
+\chapter{Year Planner}
+\label{sec:orgf40f335}
+\section{Tikz calendar styles}
+\label{sec:orge85789c}
+\subsection{Year Planner Portrait}
+\label{sec:orga6a744a}
+
+\begin{verbatim}
+\newcommand\plannerPortraitMonthFmt{\fontsize{11}{11}\selectfont\color{darkgold}}
+\newcommand\plannerPortraitDayFmt{\fontsize{8}{8}\selectfont\color{plannerdatenum}}
+
+\tikzstyle{year planner portrait}=[
+ week list,
+ month text={\plannerPortraitMonthFmt\@tr@monthNumName{\pgfcalendarcurrentmonth}},
+ day text={\plannerPortraitDayFmt\%d-},
+ every month/.append style={%
+ anchor=south,
+ inner xsep=0pt,
+ yshift=5mm,
+ xshift=2.5mm,
+ },
+ day letter headings,
+ day heading/.style={gray, xshift=0pt, scale=0.85},
+ month label above centered,
+ every day/.style={anchor=mid},
+]
+\end{verbatim}
+
+\subsection{Year Planner Landscape}
+\label{sec:orgdf6c24d}
+
+\begin{verbatim}
+\newcommand\plannerLandscapeDateDayFont{}
+\newcommand\plannerLandscapeDayFont{}
+\newcommand\plannerLandscapeMonthFont{}
+
+\newcommand\plannerLandscapeMonthFmt{%
+ \plannerLandscapeMonthFont%
+ \fontsize{15}{18}\selectfont%
+ \color{gold}\bfseries%
+}
+
+\newcommand\plannerLandscapeDayFmt{%
+ \plannerLandscapeDayFont%
+ \fontsize{10}{12}\selectfont%
+}
+
+\newcommand*\plannerLandscapeDateDayFormat[1]{%
+ \plannerLandscapeDateDayFont%
+ \fontsize{8}{11}\selectfont%
+ #1%
+}
+
+\newcommand\plannerLandscapeBeginDayScopeHook{%
+ \ifdate{weekend}{\color{black!60}}{}
+}
+
+\newlength\plannerLandscapeDayXShift
+\newlength\plannerLandscapeMonthYShift
+
+% Assuming 25mm to fit 'September'
+\setlength{\@tmp@a}{\calPaperWidth - \@wall@leftMargin - \@wall@rightMargin - 25mm}
+% Max week shift is 6 = Sunday. 31 days + 6 = 37. 1/37 = 0.027
+\setlength{\plannerLandscapeDayXShift}{0.027\@tmp@a}
+
+% Assuming 10mm for day headings (M T W...) and some padding
+\setlength{\@tmp@a}{\calPaperHeight - \@wall@topMargin - \@wall@bottomMargin - 10mm}
+% 1/12 = 0.0833
+\setlength{\plannerLandscapeMonthYShift}{0.0833\@tmp@a}
+
+\tikzstyle{year planner landscape}=[
+ month list,
+ day xshift=\plannerLandscapeDayXShift,
+ month yshift=\plannerLandscapeMonthYShift,
+ every month/.append style={anchor=base, inner xsep=0pt},
+ month text={\plannerLandscapeMonthFmt \%mt},
+ day text={\plannerLandscapeDayFmt \%d-},
+ every day/.append style={anchor=base, inner xsep=0pt},
+ month label left,
+ execute at begin day scope={
+ \plannerLandscapeBeginDayScopeHook
+ % Weekday headers in January
+ \ifdate{between=01-01 and 01-31}{
+ \def\l{\ifcase\pgfcalendarcurrentweekday M\or T\or W\or T\or F\or S\or S\fi}%
+ \ifdate{weekend}{\def\daylabelcolor{gold}}{\def\daylabelcolor{black}}%
+ \node[anchor=south,yshift=5mm,inner sep=0pt]{\color{\daylabelcolor}\plannerLandscapeDateDayFormat{\l}};%
+ }{}
+ % Weekday headers in December
+ \ifdate{between=12-01 and 12-31}{
+ \pgftransformyshift{-3mm}%
+ \def\l{\ifcase\pgfcalendarcurrentweekday M\or T\or W\or T\or F\or S\or S\fi}%
+ \ifdate{weekend}{\def\daylabelcolor{gold}}{\def\daylabelcolor{black}}%
+ \node[anchor=south,yshift=5mm,inner sep=0pt]{\color{\daylabelcolor}\plannerLandscapeDateDayFormat{\l}};%
+ }{}
+ }
+]
+\end{verbatim}
+
+\subsection{Year Planner Landscape Grid}
+\label{sec:org69cdabb}
+
+\begin{verbatim}
+\newcommand\plannerGridMonthFont{}
+\newcommand\plannerGridDateDayFont{}
+\newcommand\plannerGridNotesFont{}
+\newcommand\plannerGridDayFont{}
+\newcommand\plannerGridYearNumberFont{}
+
+\newcommand\plannerGridYearNumberFmt{%
+ \plannerGridYearNumberFont%
+ \fontsize{11}{11}\selectfont%
+ \color{white}%
+}
+
+\newcommand\plannerGridMonthFmt{%
+ \plannerGridMonthFont%
+ \fontsize{13}{13}\selectfont%
+ \color{white}%
+}
+
+\newcommand\plannerGridDayFmt{%
+ \plannerGridDayFont%
+ \fontsize{11}{11}\selectfont%
+}
+
+\newcommand\plannerGridDateDayFmt{%
+ \plannerGridDateDayFont%
+ \fontsize{9}{9}\selectfont%
+ \color{black!80}%
+}
+
+\newcommand{\plannerGridNotesFmt}{%
+ \plannerGridNotesFont%
+ \fontsize{11}{11}\selectfont%
+}
+
+\newcommand\plannerGridBeginDayScopeHook{%
+ \ifdate{weekend}{\color{black!60}}{}
+}
+
+\newlength\plannerGridColXShift
+\newlength\plannerGridRowYShift
+
+\newlength\plannerGridCalendarWidth
+\newlength\plannerGridCalendarHeight
+
+\newlength\plannerGridDayHeadingsHeight
+\newlength\plannerGridMonthNamesWidth
+
+\newlength\plannerGridNotesHeight
+\setlength{\plannerGridNotesHeight}{10mm}
+
+\setlength{\plannerGridCalendarWidth}{\calPaperWidth - \@wall@leftMargin - \@wall@rightMargin}
+\setlength{\plannerGridCalendarHeight}{\calPaperHeight - \@wall@topMargin - \@wall@bottomMargin - \plannerGridNotesHeight}
+
+\setlength{\plannerGridDayHeadingsHeight}{10mm}
+\setlength{\plannerGridMonthNamesWidth}{10mm}
+
+\setlength{\@tmp@a}{\plannerGridCalendarWidth - \plannerGridMonthNamesWidth}
+% 37 columns. 1/37 = 0.027. Max week shift is 6 = Sunday. 31 days + 6 = 37.
+\setlength{\plannerGridColXShift}{0.027\@tmp@a}
+
+\setlength{\@tmp@a}{\plannerGridCalendarHeight - 2\plannerGridDayHeadingsHeight}
+% 12 rows. 1/12 = 0.0833
+\setlength{\plannerGridRowYShift}{0.0833\@tmp@a}
+
+\newcounter{verticalCount}
+
+\tikzstyle{year planner landscape grid days}=[
+ month list,
+ day xshift=\plannerGridColXShift,
+ month yshift=\plannerGridRowYShift,
+ day text={\plannerGridDayFmt \%d-},
+ every day/.append style={anchor=base, yshift=-12pt, inner xsep=0pt},
+ execute at begin day scope={%
+ % White fill to cover the page background color
+ \node (cell) [
+ rectangle,
+ fill = white,
+ minimum height = \plannerGridRowYShift - 1pt,
+ minimum width = \plannerGridColXShift - 1pt,
+ xshift = -0.5\plannerGridColXShift,
+ yshift = 4.5pt,
+ ] {};%
+ %
+ \ifdate{Monday}{%
+ \node (a) [above left = 15pt and -3.5pt of cell.west] {};
+ \node (b) [below left = 15pt and -3.5pt of cell.west] {};
+ \node (c) [right = 10pt of cell.west] {};
+ \path [on layer = one, fill = pagebgcolor] (a.south) -- (b.north) -- (c.west) -- (a.south);%
+ }{}%
+ %
+ \ifdate{Sunday}{%
+ \node (a) [above left = 15pt and {-3.5pt + 1pt} of cell.east] {};
+ \node (b) [below left = 15pt and {-3.5pt + 1pt} of cell.east] {};
+ \node (c) [right = {10pt - 1pt} of cell.east] {};
+ \path [on layer = two, fill = white] (a.south) -- (b.north) -- (c.west) -- (a.south);%
+ }{}%
+ %
+ \plannerGridBeginDayScopeHook%
+ },
+]
+\end{verbatim}
+\section{Helpers}
+\label{sec:orgdfb1023}
+
+\begin{verbatim}
+\newcommand\plannerMarksDayTextCSV{\@wall@eventsCsv}
+\newcommand\plannerMarksNoteCSV{\@wall@eventsCsv}
+\newcommand\plannerMarkDefaultsCsv{}
+
+\newcommand\@wall@plm[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{#1}, nil, \luastring{\plannerMarksDayTextCSV})
+tex.sprint(';')
+}}
+
+\newcommand\@wall@plmYear{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+yearMarksDayText(tonumber(\CalendarYear), nil, \luastring{\plannerMarksDayTextCSV})
+tex.sprint(';')
+}}
+
+\newcommand\@wall@plNotes{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+yearMarksNote(tonumber(\CalendarYear), nil, \luastring{\plannerMarksNoteCSV}, \luastring{\plannerMarkDefaultsCsv}, false)
+}}
+
+\newcommand\@wall@plNotesOneCalendar{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+yearMarksNote(tonumber(\CalendarYear), nil, \luastring{\plannerMarksNoteCSV}, \luastring{\plannerMarkDefaultsCsv}, true)
+}}
+
+\newcommand\plannerEvents{%
+\parseYearEvents[filter pred = hasNote]%
+}
+
+\end{verbatim}
+
+\section{\textbackslash YearPlannerPortrait}
+\label{sec:org64a6ea5}
+
+\begin{verbatim}
+\newcommand\YearPlannerPortrait{%
+\@wall@useDefaultMoons%
+\begin{tikzpicture}[every calendar/.style={year planner portrait}]%
+ \matrix[column sep=1.5em, row sep=5mm] {
+ \calendar(cal01)[dates=\CalendarYear-01-01 to \CalendarYear-01-last] \@wall@plm{January}; \pgfmatrixnextcell
+ \calendar(cal02)[dates=\CalendarYear-02-01 to \CalendarYear-02-last] \@wall@plm{February}; \pgfmatrixnextcell
+ \calendar(cal03)[dates=\CalendarYear-03-01 to \CalendarYear-03-last] \@wall@plm{March}; \\
+ \calendar(cal04)[dates=\CalendarYear-04-01 to \CalendarYear-04-last] \@wall@plm{April}; \pgfmatrixnextcell
+ \calendar(cal05)[dates=\CalendarYear-05-01 to \CalendarYear-05-last] \@wall@plm{May}; \pgfmatrixnextcell
+ \calendar(cal06)[dates=\CalendarYear-06-01 to \CalendarYear-06-last] \@wall@plm{June}; \\
+ \calendar(cal07)[dates=\CalendarYear-07-01 to \CalendarYear-07-last] \@wall@plm{July}; \pgfmatrixnextcell
+ \calendar(cal08)[dates=\CalendarYear-08-01 to \CalendarYear-08-last] \@wall@plm{August}; \pgfmatrixnextcell
+ \calendar(cal09)[dates=\CalendarYear-09-01 to \CalendarYear-09-last] \@wall@plm{September}; \\
+ \calendar(cal10)[dates=\CalendarYear-10-01 to \CalendarYear-10-last] \@wall@plm{October}; \pgfmatrixnextcell
+ \calendar(cal11)[dates=\CalendarYear-11-01 to \CalendarYear-11-last] \@wall@plm{November}; \pgfmatrixnextcell
+ \calendar(cal12)[dates=\CalendarYear-12-01 to \CalendarYear-12-last] \@wall@plm{December}; \\
+ };
+ \@wall@plNotes
+\end{tikzpicture}%
+}
+\end{verbatim}
+
+\section{\textbackslash YearPlannerLandscape}
+\label{sec:orgf7b001f}
+
+\begin{verbatim}
+\newcommand\YearPlannerLandscape{%
+\@wall@usePlannerMoons%
+\begin{tikzpicture}%
+ \calendar (cal) [
+ year planner landscape,
+ dates=\CalendarYear-01-01 to \CalendarYear-12-31,
+ ] \@wall@plmYear;
+ \@wall@plNotesOneCalendar
+\end{tikzpicture}%
+}
+\end{verbatim}
+
+\section{\textbackslash YearPlannerLandscapeGrid}
+\label{sec:orgce2473c}
+
+\begin{verbatim}
+\newcommand\YearPlannerLandscapeGrid{%
+\@wall@usePlannerMoons%
+\begin{tikzpicture}
+
+ % Background frame
+
+ \node (bg) [
+ rectangle,
+ inner sep = 0pt,
+ minimum width = \plannerGridCalendarWidth,
+ minimum height = \plannerGridCalendarHeight,
+ ] {};
+
+ \foreach \x/\m in {1/\xJanShort, 2/\xFebShort, 3/\xMarShort, 4/\xAprShort,
+ 5/\xMayShort, 6/\xJunShort, 7/\xJulShort, 8/\xAugShort, 9/\xSepShort,
+ 10/\xOctShort, 11/\xNovShort, 12/\xDecShort}
+ {
+ \setlength{\@tmp@a}{\x\plannerGridRowYShift + \plannerGridDayHeadingsHeight}
+
+ % Month labels
+
+ \node [
+ below = \@tmp@a of bg.north west,
+ yshift = 0.5\plannerGridRowYShift,
+ xshift = 0.5\plannerGridColXShift - 2pt,
+ anchor = base,
+ rotate = 90,
+ ] {\plannerGridMonthFmt\MakeUppercase{\textls*{\m}}};
+
+ % Horizontal lines
+
+ \addtolength{\@tmp@a}{-\plannerGridRowYShift}
+
+ \node (h-a-\x) [below = \@tmp@a of bg.north west] {};
+ \node (h-b-\x) [below = \@tmp@a of bg.north east] {};
+ \draw [gridcolor] (h-a-\x) -- (h-b-\x);
+ }
+
+ % 13th line
+ \setlength{\@tmp@a}{12\plannerGridRowYShift + \plannerGridDayHeadingsHeight}
+ \node (h-a-13) [below = \@tmp@a of bg.north west] {};
+ \node (h-b-13) [below = \@tmp@a of bg.north east] {};
+ \draw [gridcolor] (h-a-13) -- (h-b-13);
+
+ % Year number in the corner
+ \node [
+ right = 0pt of bg.north west,
+ xshift = 0.5\plannerGridMonthNamesWidth,
+ yshift = -0.5\plannerGridDayHeadingsHeight - 5pt,
+ anchor = base,
+ ] {\plannerGridYearNumberFmt\CalendarYear};
+
+ \setcounter{verticalCount}{1}
+
+ \foreach \i in {0,1,2,3,4,5} {
+ \foreach \j/\d in {
+ 0/\xMondayDayLetter,
+ 1/\xTuesdayDayLetter,
+ 2/\xWednesdayDayLetter,
+ 3/\xThursdayDayLetter,
+ 4/\xFridayDayLetter,
+ 5/\xSaturdayDayLetter,
+ 6/\xSundayDayLetter}
+ {
+ \addtocounter{verticalCount}{1}
+ \ifnumgreater{\value{verticalCount}}{38}{\relax}{
+ \setlength{\@tmp@a}{7\plannerGridColXShift}
+ \setlength{\@tmp@a}{\i\@tmp@a + \j\plannerGridColXShift + \plannerGridMonthNamesWidth}
+
+ % Day headings (top and bottom)
+
+ \node [
+ right = \@tmp@a of bg.north west,
+ xshift = 0.5\plannerGridColXShift + 4pt,
+ yshift = -0.5\plannerGridDayHeadingsHeight - 5pt,
+ anchor = base,
+ ] {\plannerGridDateDayFmt \d};
+
+ \node [
+ right = \@tmp@a of bg.south west,
+ xshift = 0.5\plannerGridColXShift + 4pt,
+ yshift = 0.5\plannerGridDayHeadingsHeight - 5pt,
+ anchor = base,
+ ] {\plannerGridDateDayFmt \d};
+
+ % % Vertical lines
+
+ % \node (v-a-\i-\j) [right = \@tmp@a of bg.north west] {};
+ % \node (v-b-\i-\j) [right = \@tmp@a of bg.south west] {};
+ % \draw [gridcolor] (v-a-\i-\j) -- (v-b-\i-\j);
+ }
+ }
+ }
+
+ \calendar (cal) [
+ year planner landscape grid days,
+ dates=\CalendarYear-01-01 to \CalendarYear-12-31,
+ below right = 0pt and 0pt of bg.north west,
+ anchor = north west,
+ yshift = -\plannerGridDayHeadingsHeight - 3mm,
+ xshift = \plannerGridMonthNamesWidth + 0.5\plannerGridColXShift + 4pt,
+ ] \@wall@plmYear;
+
+ \@wall@plNotesOneCalendar
+
+\end{tikzpicture}%
+}
+\end{verbatim}
+
+\section{\textbackslash YearPlannerLandscapeGridPage}
+\label{sec:org772519b}
+
+\begin{verbatim}
+\newcommand{\YearPlannerLandscapeGridPage}{%
+\pagecolor{pagebgcolor}%
+\AddToShipoutPictureFG*{\put(\LenToUnit{\@wall@leftMargin},\LenToUnit{\@wall@bottomMargin})%
+{\begin{minipage}[b]{\plannerGridCalendarWidth}%
+\YearPlannerLandscapeGrid
+
+\begin{minipage}[b][10mm][c]{\plannerGridCalendarWidth}%
+\plannerGridNotesFmt
+\hspace*{2mm}%
+\parseYearEvents[%
+ filter pred = hasNote,
+ format cmd = {\textsuperscript{\eIdx}~\eMonthShort~\eDay:~\textit{\eNote}\ifnumless{\eIdx}{\eMaxIdx}{,\space}{.}},
+]%
+\end{minipage}%
+\end{minipage}%
+}}}
+\end{verbatim}
+
+\chapter{Translation keys}
+\label{sec:org9ce89e8}
+
+\begin{verbatim}
+% Load internal translations
+\InputIfFileExists{i18n/wallcalendar-\@wall@calendarLanguage.tex}{}%
+{\ClassError{wallcalendar}{File Not Found: i18n/wallcalendar-\@wall@calendarLanguage.tex}{}}
+
+% Load user translations if the option was set and translationsAutoload is true
+
+\newcommand\LoadTranslations{%
+\InputIfFileExists{\@wall@translationsInputFile}{}%
+{\ClassWarning{wallcalendar}{File Not Found: \@wall@translationsInputFile}{}}}
+
+\notblank{\@wall@translationsInputFile}{%
+\iftranslationsAutoload \LoadTranslations \fi}
+\end{verbatim}
+
+Use \texttt{\textbackslash{}ifcase} instead of a \texttt{\textbackslash{}luadirect} array lookup, otherwise Portuguese day
+headings such as \texttt{\textbackslash{}def\textbackslash{}xMondayDayLetter\{\{2\textbackslash{}textsuperscript\{a\}\}\}} cause an error.
+
+\begin{verbatim}
+#1 : month number, returns the translation
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand*\@tr@monthNumName[1]{%
+\ifcase#1 \relax\or \xJanuary\or \xFebruary\or \xMarch\or \xApril\or \xMay\or \xJune\or
+\xJuly\or \xAugust\or \xSeptember\or \xOctober\or \xNovember\or \xDecember\fi}
+\end{verbatim}
+
+\begin{verbatim}
+#1 : weekday number, returns the one letter translation
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand*\@tr@dayLetter[1]{%
+\ifcase#1 \xMondayDayLetter\or \xTuesdayDayLetter\or \xWednesdayDayLetter\or
+\xThursdayDayLetter\or \xFridayDayLetter\or \xSaturdayDayLetter\or \xSundayDayLetter\fi}
+\end{verbatim}
+
+\chapter{Helper macros}
+\label{sec:org3563e80}
+
+Doing this in Lua to make blasted sure the result is just a string
+
+\begin{verbatim}
+#1 : month name in English, returns zero padded number
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand*{\monthToNum}[1]{%
+\luadirect{
+ local monthToNum = {
+ january = '01',
+ february = '02',
+ march = '03',
+ april = '04',
+ may = '05',
+ june = '06',
+ july = '07',
+ august = '08',
+ september = '09',
+ october = '10',
+ november = '11',
+ december = '12',
+ }
+ local key = string.lower('#1')
+ tex.sprint(monthToNum[key])
+}}
+\end{verbatim}
+
+\begin{verbatim}
+#1 : month number, returns the name in English
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand*\monthName[1]{%
+% \ifcase might be just fine here
+\luadirect{
+ local monthName = {
+ 'January', 'February', 'March', 'April', 'May', 'June', 'July',
+ 'August', 'September', 'October', 'November', 'December',
+ }
+ local key = tonumber('#1')
+ tex.sprint(monthName[key])
+}}
+\end{verbatim}
+
+\chapter{Epilogue}
+\label{sec:org8f36044}
+
+\begin{verbatim}
+% End of wallcalendar.cls
+\end{verbatim}
+\end{document}
diff --git a/macros/luatex/latex/wallcalendar/doc/wallcalendar.org b/macros/luatex/latex/wallcalendar/doc/wallcalendar.org
new file mode 100644
index 0000000000..5c8496bbc8
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/wallcalendar.org
@@ -0,0 +1,1125 @@
+#+TITLE: Wallcalendar User Manual
+#+SETUPFILE: doc-setup.org
+
+#+latex: \input{frontpage.tex}
+
+* Tasks :noexport:
+** TODO basic things should work without any class options
+** setup A5 desk page layout
+*** new example on the front page
+** describe \fullPageFmt and \smallLandscapeFmt
+** can use env variables for class options with Lua? language, resolution, etc.
+* Tutorial: Forest Calendar
+
+In this tutorial we will produce the three example pages seen in the summary.
+
+Set the parameters of the month pages in advance, either in the preamble or in
+the document body, but before calling =\MonthPage{ month }= to typeset it.
+
+A month page can have four areas:
+
+- Photo
+- Quote
+- Calendar
+- Events
+
+Their parameters are set separately for each month:
+
+: \SetPhoto[ options ]{ month }
+: \SetQuote[ options ]{ month }{ quote text }
+: \SetCalendar[ options ]{ month }
+: \SetEvents[ options ]{ month }{ calendar tikz marks }{ events text }
+
+The month page will be typeset with:
+
+: \MonthPage[ options ]{ month }
+
+** Documentclass
+
+To start, load the documentclass and set =year=, =language= and the =imageFolder=:
+
+#+begin_src tex
+\documentclass[
+ year=2018,
+ language=english,
+ imageFolder=./photos/,
+]{wallcalendar}
+#+end_src
+
+Let's start the preamble with =\makeatletter= to be safe.
+
+#+begin_src tex :tangle ./examples/forest.tex
+\makeatletter
+#+end_src
+
+** Font settings
+
+For this example we'll use TeX Gyre Pagella as the main typeface. We also load
+DejaVu Sans to use a particular glyph as a mark in the calendar (=U+263C= white
+sun with rays).
+
+#+begin_src tex :tangle ./examples/forest.tex
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+#+end_src
+
+#+latex: \clearpage
+
+** June
+
+#+begin_latex
+\twocol{%
+ \frame{\includegraphics[width=5cm]{cal-plain-01}}%
+}{%
+ \includegraphics[width=6.12cm]{cal-showframe-01}%
+}
+
+\twocolcaption{\mbox{}}{%
+ \raggedright
+ \texttt{showtrims} and \texttt{showframe} class options show the page structure.
+}
+
+\bigskip
+#+end_latex
+
+It will be a full page photo, with 3mm bleed on all four sides. You can see the
+bleed if you enable the =showtrims= class option. We also specify the file name
+of the photo (no extension), this will be the argument of =\includegraphics=.
+
+#+begin_src tex :tangle ./examples/forest.tex
+\SetPhoto[bleed=3mm, file={obscure-crop}]{June}
+#+end_src
+
+A quote will be positioned over the photo. The quote is in a =\linewidth= wide
+minipage, attached to the top left corner of the page. Use =\raggedleft=,
+=\raggedright=, or =\centering= for alignment, and the =xOffset= and =yOffset=
+options to move the quote's minipage to the exact position.
+
+#+begin_src tex :tangle ./examples/forest.tex
+\SetQuote[xOffset=-5mm, yOffset=-20mm]{June}{%
+\raggedright
+\setlength{\parskip}{10pt}%
+\Large
+\color{white}
+
+I shall set forth for somewhere,\\
+I shall make the reckless choice\\
+Some day when they are in voice\\
+And tossing so as to scare\\
+The white clouds over them on.\\
+I shall have less to say,\\
+But I shall be gone.
+
+\textit{The Sound of the Trees} by Robert Frost
+}
+#+end_src
+
+The layout macro will place the calendar at the bottom, dates in a single line.
+
+Here we use a conditional to use a different calendar style when =showframe= is
+turned on, this helps with debugging or tuning the position.
+
+#+begin_src tex :tangle ./examples/forest.tex
+\ifshowframe
+ \SetCalendar[bg/.style={opacity=0.5, fill=white}]{June}
+\else
+ \SetCalendar[bg/.style={opacity=0.8}]{June}
+\fi
+#+end_src
+
+Events for particular days are printed under the calendar.
+
+#+begin_src tex :tangle ./examples/forest.tex
+\SetEvents{June}{%
+ if (equals=2018-06-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}{%
+\raggedleft
+{\dejaVuSans\char"263C} June 21: Summer Solstice
+}
+#+end_src
+
+** July
+
+#+begin_latex
+\twocol{%
+ \frame{\includegraphics[width=5cm]{cal-plain-02}}%
+}{%
+ \includegraphics[width=6.12cm]{cal-showframe-02}%
+}
+#+end_latex
+
+Same as June, but we will set the image to be placed above the calendar, and we
+add a transparent background for the quote.
+
+This layout is a good option when the top or the bottom of the photo has to be
+cropped, and you can't use the full page aspect ratio for the photo.
+
+#+begin_src tex :tangle ./examples/forest.tex
+\SetPhoto[bleed=3mm, file={obscure-crop}]{July}
+
+\SetQuote[%
+ xOffset=0.5\linewidth - 0.5\paperwidth -3mm,
+ yOffset=-20mm,
+]{July}{%
+\begin{tikzpicture}%
+\node [
+ fill=white, opacity=0.6, minimum width={\paperwidth + 3mm},
+ minimum height=30mm] {};%
+\node [] {%
+\begin{minipage}{\paperwidth + 3mm}%
+\centering
+\Large
+\color{white}
+
+I shall have less to say,\\
+But I shall be gone.
+
+\textit{The Sound of the Trees} by Robert Frost
+\end{minipage}%
+};
+\end{tikzpicture}%
+}
+
+\ifshowframe
+ \SetCalendar[bg/.style={opacity=0.5}]{July}
+\else
+ \SetCalendar[bg/.style={opacity=1}]{July}
+\fi
+
+\SetEvents{July}{
+ if (equals=2018-07-27) [day text={\dejaVuSans\char"263C}];
+}{%
+\raggedleft
+{\dejaVuSans\char"263C} July 27: Mars at Opposition
+}
+#+end_src
+
+** August
+
+#+begin_latex
+\twocol{%
+ \frame{\includegraphics[width=5cm]{cal-plain-03}}%
+}{%
+ \includegraphics[width=6.12cm]{cal-showframe-03}%
+}
+#+end_latex
+
+This layout works for photos that are horizontal (landscape orientation), scaled
+into the bleed margin on three sides.
+
+#+begin_src tex :tangle ./examples/forest.tex
+\SetPhoto[bleed=3mm, file={obscure-crop}, yOffset=-150mm]{August}
+
+\SetQuote[yOffset=-3mm]{August}{%
+\centering
+\setlength{\parskip}{10pt}%
+\Large
+\color{black!80}
+
+I shall have less to say,\\
+But I shall be gone.
+
+\textit{The Sound of the Trees} by Robert Frost
+}
+
+\ifshowframe
+ \SetCalendar[bg/.style={opacity=0.5}]{August}
+\else
+ \SetCalendar[bg/.style={opacity=1}]{August}
+\fi
+
+\SetEvents{August}{
+ if (equals=2018-08-12) [day text={\dejaVuSans\char"263C}];
+}{%
+\raggedleft
+{\dejaVuSans\char"263C} August 12, 13: Perseids Meteor Shower
+}
+#+end_src
+
+End of the preamble.
+
+#+begin_src tex :tangle ./examples/forest.tex
+\makeatother
+#+end_src
+
+** The document
+
+Typesetting the month pages in the document is now just this much:
+
+#+begin_src tex :tangle ./examples/forest.tex
+\begin{document}
+
+\MonthPage[layout=full page, put photo=full page]{June}
+
+\MonthPage[layout=full page, put photo=full width above calendar]{July}
+
+\MonthPage[layout=small landscape, put photo=full width]{August}
+
+\end{document}
+#+end_src
+
+#+latex: \clearpage
+
+* Tutorial: Translations
+
+In this tutorial we will produce the same calendar in three languages: Japanese,
+English and Hungarian.
+
+We are going to use =IPAPMincho= font for the Japanese.
+
+#+begin_latex
+\begin{extrafullwidth}
+
+\hfill
+\begin{minipage}{0.31\linewidth}
+\centering
+
+\frame{\includegraphics[width=5cm]{./examples/cal-translations-japanese.pdf}}
+
+\end{minipage}%
+\begin{minipage}{0.31\linewidth}
+\centering
+
+\frame{\includegraphics[width=5cm]{./examples/cal-translations-english.pdf}}
+
+\end{minipage}%
+\begin{minipage}{0.31\linewidth}
+\centering
+
+\frame{\includegraphics[width=5cm]{./examples/cal-translations-hungarian.pdf}}
+
+\end{minipage}
+\hfill\mbox{}
+
+\end{extrafullwidth}
+#+end_latex
+
+** Files
+
+The main document files:
+
+: cal-translations-japanese.tex
+: cal-translations-english.tex
+: cal-translations-hungarian.tex
+
+Fonts, formatting settings, etc.:
+
+: local-japanese.sty
+: local-english.sty
+: local-hungarian.sty
+
+Translation text input:
+
+: frog-japanese.tex
+: frog-english.tex
+: frog-hungarian.tex
+
+Setup month pages (same across translations):
+
+: frog.tex
+
+** Translations setup
+
+Create the =frog-english.tex= file and use the =\SetTxt{ key }{ content }=
+command to set text content for translation keys.
+
+=frog-japanese.tex=
+
+#+begin_src tex :tangle ./examples/frog-japanese.tex
+\SetTxt{September Quote}{%
+{\mincho æ–°æ± ã‚„è›™ã¨ã³ã“む音もãªã—}
+
+{\Large\textit{araike ya / kawazu tobikomu / oto mo nashi}}
+
+{\mincho 良寛}%
+}
+
+\newcommand\SeptMarks{%
+ if (equals=2018-09-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}
+
+\SetTxt{Sept Events}{%
+{\dejaVuSans\char"263C} {\mincho 9月 21æ—¥: ã¾ã“ã¨ã« 9月 21æ—¥}
+}
+#+end_src
+
+=frog-english.tex=
+
+#+begin_src tex :tangle ./examples/frog-english.tex
+\SetTxt{September Quote}{%
+silent new lake\\
+let the frog jump\\
+not even a sound
+
+\textit{-- Ryokan}%
+}
+
+\newcommand\SeptMarks{%
+ if (equals=2018-09-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}
+
+\SetTxt{Sept Events}{%
+{\dejaVuSans\char"263C} Sept 21: September 21
+}
+#+end_src
+
+=frog-hungarian.tex=
+
+#+begin_src tex :tangle ./examples/frog-hungarian.tex
+\SetTxt{September Quote}{%
+hallgat az új tó\\
+ugorhat béka belé\\
+vize se csobban
+
+\textit{-- Rjókan}%
+}
+
+\newcommand\SeptMarks{%
+ if (equals=2018-09-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}
+
+\SetTxt{Sept Events}{%
+{\dejaVuSans\char"263C} Szept 21: Szeptember 21
+}
+#+end_src
+
+*NOTE:* Using =\SetTxt{}= to store values intended as tikz marks on the calendar
+will not work. The =\txt{}= command will be the value of =\@eventmarks= and tikz
+can't resolve it there.
+
+Put the calendar marks in a command instead, as above with =\SeptMarks=.
+
+#+begin_src tex
+\calendar (cal#1)
+ [alnitak, dates=\CalendarYear-#1-01 to \CalendarYear-#1-last]
+ \@eventmarks;%
+#+end_src
+
+#+begin_src tex
+% NOTE This code below will not work.
+% Put the calendar marks in a command instead.
+
+\SetTxt{Sept Marks}{%
+ if (equals=2018-09-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}
+
+% ...
+
+\SetEvents{September}{%
+\txt{Sept Marks}
+}{%
+\raggedleft
+\txt{Sept Events}
+}
+#+end_src
+
+** Document setup
+
+Load the documentclass. We are setting the =translations= option to define the
+file where translation keys are set. This file is loaded by the documentclass as
+an =\input=.
+
+=cal-translations-japanese.tex=
+
+#+begin_src tex :tangle ./examples/cal-translations-japanese.tex
+\documentclass[
+ year = 2018,
+ language = japanese,
+ translationsInputFile = frog-japanese.tex,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\usepackage{local-japanese}
+
+% Content is the same across translations
+\input{./frog.tex}
+
+\begin{document}
+
+% Just one month
+\MonthPage[layout=full page, put photo=full page]{September}
+
+\end{document}
+#+end_src
+
+=local-japanese.sty=
+
+#+begin_src tex :tangle ./examples/local-japanese.sty
+\ProvidesPackage{local-japanese}
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+% Japanese font
+\newfontfamily\mincho{IPAPMincho}
+
+% Renew formatting hooks to use the \mincho font
+\renewcommand\fullPageFmt{%
+ \renewcommand*\monthFmt{\LARGE\mincho}%
+ \renewcommand*\yearFmt{\LARGE\mincho}%
+ \renewcommand*\dayLetterColor{}%
+ \renewcommand*\dayLetterFmt{\tiny\mincho}%
+ \renewcommand*\dayTextFmt{\small}%
+ \renewcommand*\quoteFmt{}%
+ \renewcommand*\headingFmt{\centering}%
+ \renewcommand*\calendarFmt{\centering}%
+ \renewcommand*\eventsFmt{%
+ \setlength{\parindent}{0pt}\raggedleft\footnotesize%
+ }%
+}
+#+end_src
+
+=cal-translations-english.tex=
+
+#+begin_src tex :tangle ./examples/cal-translations-english.tex
+\documentclass[
+ year = 2018,
+ language = english,
+ translationsInputFile = frog-english.tex,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\usepackage{local-english}
+
+\input{./frog.tex}
+
+\begin{document}
+
+\MonthPage[layout=full page, put photo=full page]{September}
+
+\end{document}
+#+end_src
+
+=local-english.sty=
+
+#+begin_src tex :tangle ./examples/local-english.sty
+\ProvidesPackage{local-english}
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+#+end_src
+
+=cal-translations-hungarian.tex=
+
+#+begin_src tex :tangle ./examples/cal-translations-hungarian.tex
+\documentclass[
+ year = 2018,
+ language = hungarian,
+ translationsInputFile = frog-hungarian.tex,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\usepackage{local-hungarian}
+
+\input{./frog.tex}
+
+\begin{document}
+
+\MonthPage[layout=full page, put photo=full page]{September}
+
+\end{document}
+#+end_src
+
+=local-hungarian.sty=
+
+#+begin_src tex :tangle ./examples/local-hungarian.sty
+\ProvidesPackage{local-hungarian}
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+#+end_src
+
+=frog.tex=
+
+#+begin_src tex :tangle ./examples/frog.tex
+\makeatletter
+
+\SetPhoto[bleed=3mm, file={frog-crop}]{September}
+#+end_src
+
+Use the =\txt{ key }= command to load text from translation keys:
+
+#+begin_src tex :tangle ./examples/frog.tex
+
+\SetQuote[xOffset=0pt, yOffset=-140mm]{September}{%
+\raggedleft\setlength{\parskip}{10pt}\HUGE\color{white}%
+\txt{September Quote}%
+}
+#+end_src
+
+Calendar settings for the month, using =\txt= to access translated parts.
+
+#+begin_src tex :tangle ./examples/frog.tex
+\SetCalendar[bg/.style={opacity=0.4}]{September}
+
+\SetEvents{September}{%
+\SeptMarks%
+}{%
+\raggedleft
+\txt{Sept Events}
+}
+
+\makeatother
+#+end_src
+
+#+latex: \clearpage
+
+* Tutorial: Load Events from CSV
+
+#+begin_latex
+\begin{fullwidth}
+\begin{minipage}{\linewidth}
+\centering
+
+\frame{\includegraphics[width=\linewidth, clip, trim=0pt 0pt 0pt 22cm]{./examples/cal-marks.pdf}}
+
+\end{minipage}%
+\end{fullwidth}
+#+end_latex
+
+** CSV files
+
+Events in the CSV should be already sorted by date.
+
+If you are using more than one CSV, put all events with notes (i.e. indexed
+entries) in the same CSV. The index number of the mark is taken from the row
+number in the CSV, so a second CSV with notes would start the count from 1
+again.
+
+We're going to use the following csv files, see in the =./doc/examples/data/= folder.
+
+=holidays.csv=
+
+=moonphases.csv=
+
+=mark_defaults.csv=
+
+** Event formatting
+
+You can format the event output by setting the =format cmd= key:
+
+#+begin_src tex
+\parseMonthEvents[%
+ format cmd = {%
+ \textsuperscript{\eMark}~\eMonthShort~\eDay:\space%
+ \eNote\ifnumless{\eIdx}{\eMaxIdx}{,\space}{.}%
+ },
+]%
+#+end_src
+
+Or define a Lua formatting function and set it with the =format func= key:
+
+=helpers.lua=
+
+#+begin_src lua
+function eventFmtCustom(idx, max_idx, event, event_date, mark)
+ local d = event_date
+ tex.sprint(string.format(
+ "\\textsuperscript{%s} & %s %s: & %s \\\\",
+ mark.symbol, d:fmt("%b"), d:getday(), event.note
+ ))
+end
+#+end_src
+
+#+begin_src tex
+\parseMonthEvents[format func = eventFmtCustom]%
+#+end_src
+
+** Document setup
+
+=cal-marks.tex=
+
+#+begin_src tex :tangle ./examples/cal-marks.tex
+\documentclass[
+ year = 2018,
+ eventsCsv = ./data/holidays.csv,
+ markDefaultsCsv = ./data/mark_defaults.csv,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\makeatletter
+
+\colorlet{mooncolor}{darkgold}
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+
+\SetPhoto[bleed=3mm, file={frog-crop}]{September}
+
+\SetQuote[xOffset=0pt, yOffset=-140mm]{September}{%
+\raggedleft\setlength{\parskip}{10pt}\HUGE\color{white}%
+silent new lake\\
+let the frog jump\\
+not even a sound
+
+\textit{-- Ryokan}%
+}
+
+\SetCalendar[bg/.style={opacity=0.4}]{September}
+
+\SetEvents{September}{%
+\parseMonthMarksDayTextUsing{./data/moonphases.csv}%
+\parseMonthMarksDayText%
+\parseMonthMarksNote%
+}{%
+\raggedright
+\parseMonthEvents[%
+ format cmd = {%
+ \textsuperscript{\eMark}~\eMonthShort~\eDay:\space%
+ \eNote\ifnumless{\eIdx}{\eMaxIdx}{,\space}{.}%
+ },
+]%
+}
+
+\makeatother
+
+\begin{document}
+
+\MonthPage[layout=full page, put photo=full page]{September}
+
+\end{document}
+#+end_src
+
+#+latex: \clearpage
+
+* Example: Year Planner Page
+
+#+begin_latex
+\begin{fullwidth}
+\begin{minipage}{0.31\linewidth}
+\centering
+
+\frame{\includegraphics[width=5cm]{./examples/cal-year-planner.pdf}}
+
+\end{minipage}%
+\end{fullwidth}
+#+end_latex
+
+** Document setup
+
+=cal-year-planner.tex=
+
+#+begin_src tex :tangle ./examples/cal-year-planner.tex
+\documentclass[
+ year = 2018,
+ eventsCsv = ./data/holidays.csv,
+ markDefaultsCsv = ./data/mark_defaults.csv,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\makeatletter
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+
+% Use two CSV files for day text input to include the moon phases
+\renewcommand\@wall@plm[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{#1}, nil, \luastring{\plannerMarksDayTextCSV})
+monthMarksDayText(\luastring{#1}, nil, \luastring{./data/moonphases.csv})
+tex.sprint(';')
+}}
+#+end_src
+
+** \textbackslash YearPlannerPage
+
+#+begin_src tex :tangle ./examples/cal-year-planner.tex
+\newcommand\plannerYearFmt{\fontsize{26}{26}\selectfont\color{orangegold}}
+
+\newlength\plannerNotesSep
+\setlength{\plannerNotesSep}{3mm}
+
+\newcommand\preYearPlannerPageHook{%
+ \setlength{\markNumberAbove}{-9pt}%
+ \setlength{\markNumberRight}{-6pt}%
+ \setlength{\markDayTextAbove}{-11pt}%
+ \setlength{\markDayTextRight}{-6pt}%
+}
+
+\newcommand\postYearPlannerPageHook{%
+ \setlength{\markNumberAbove}{-10pt}%
+ \setlength{\markNumberRight}{-3pt}%
+ \setlength{\markDayTextAbove}{-10pt}%
+ \setlength{\markDayTextRight}{-3pt}%
+}
+
+\newcommand\printPlannerTitle{\plannerYearFmt \CalendarYear}
+
+\newcommand\YearPlannerPage{%
+\newpage
+\ifvarnishmask
+\mbox{}
+\else
+\preYearPlannerPageHook
+{\centering
+
+{\printPlannerTitle}
+
+\vspace*{7mm}
+
+\YearPlannerPortrait
+
+\vspace*{\plannerNotesSep}
+
+\plannerEvents
+
+}
+\postYearPlannerPageHook
+
+\fi
+}
+
+\makeatother
+#+end_src
+
+** Use it
+
+#+begin_src tex :tangle ./examples/cal-year-planner.tex
+\begin{document}
+
+\YearPlannerPage
+
+\end{document}
+#+end_src
+
+#+latex: \clearpage
+
+* Example: Photo Thumbnails Page
+
+#+begin_latex
+\begin{fullwidth}
+\begin{minipage}{0.31\linewidth}
+\centering
+
+\frame{\includegraphics[width=5cm]{./examples/cal-thumbnails.pdf}}
+
+\end{minipage}%
+\end{fullwidth}
+#+end_latex
+
+** Document setup
+
+=cal-thumbnails.tex=
+
+#+begin_src tex :tangle ./examples/cal-thumbnails.tex
+\documentclass[
+ year = 2018,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\makeatletter
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+
+\newlength\@wall@tmp@a
+\newlength\@wall@tmp@b
+#+end_src
+
+** \textbackslash ThumbWithCaptionLeftSide
+
+Typesets the photo thumb image with its caption text on the left side.
+
+: \ThumbWithCaptionLeftSide{January}
+
+#+begin_src tex :tangle ./examples/cal-thumbnails.tex
+\newlength\@wall@thumbWidth
+\newlength\@wall@thumbHeight
+\newlength\@wall@thumbCaptionWidth
+\setlength{\@wall@thumbWidth}{0.1749\calPaperWidth}% 30mm at the 6.75in page width, 0.1749 = 1/5.715
+\setlength{\@wall@thumbHeight}{\@wall@thumbWidth}
+\setlength{\@wall@thumbCaptionWidth}{0.2333\calPaperWidth}% 40mm at 6.75in page width
+
+\newcommand\thumbFmt{}
+\newcommand\thumbMonthFmt{\fontsize{10}{13}\selectfont\bfseries}
+\newcommand\thumbCaptionFmt{\fontsize{10}{13}\selectfont}
+
+\def\@wall@thumbFile{}
+\def\@wall@photoCaption{}
+
+\newcommand\ThumbWithCaptionLeftSide[1]{%
+\pgfkeys{/Photo/#1/thumbFile/.get=\@wall@thumbFile}%
+\ifx\@wall@thumbFile\empty
+ \pgfkeys{/Photo/#1/file/.get=\@wall@thumbFile}%
+\fi
+\pgfkeys{/Photo/#1/caption/.get=\@wall@photoCaption}%
+% Thumbnail caption
+\ifvarnishmask%
+\hspace*{\@wall@thumbWidth}
+\else%
+\begin{minipage}[b][\@wall@thumbHeight][t]{\@wall@thumbCaptionWidth}%
+\raggedleft
+\thumbFmt
+{\thumbMonthFmt \@tr@monthNumName{\monthToNum{#1}}}\par
+{\thumbCaptionFmt \@wall@photoCaption}%
+\end{minipage}%
+\fi%
+\hspace*{3mm}
+% Thumbnail photo
+\begin{minipage}[b][\@wall@thumbHeight]{\@wall@thumbWidth}%
+% FIXME placeholder
+%\placeholder{%
+\includegraphics[ keepaspectratio, height=\@wall@thumbHeight ]{\@wall@thumbFile}%
+%}%
+\end{minipage}%
+}
+#+end_src
+
+** \textbackslash ThumbWithCaptionRightSide
+
+Typesets the photo thumb image with its caption text on the right side.
+
+: \ThumbWithCaptionRightSide{January}
+
+#+begin_src tex :tangle ./examples/cal-thumbnails.tex
+\newcommand\ThumbWithCaptionRightSide[1]{%
+\pgfkeys{/Photo/#1/thumbFile/.get=\@wall@thumbFile}%
+\ifx\@wall@thumbFile\empty
+ \pgfkeys{/Photo/#1/file/.get=\@wall@thumbFile}%
+\fi
+\pgfkeys{/Photo/#1/caption/.get=\@wall@photoCaption}%
+% Thumbnail photo
+\begin{minipage}[b][\@wall@thumbHeight]{\@wall@thumbWidth}%
+% FIXME placeholder
+%\placeholder{%
+\includegraphics[ keepaspectratio, height=\@wall@thumbHeight ]{\@wall@thumbFile}%
+%}%
+\end{minipage}%
+\hspace*{3mm}
+% Thumbnail caption
+\ifvarnishmask%
+\hspace*{\@wall@thumbWidth}
+\else%
+\begin{minipage}[b][\@wall@thumbHeight][t]{\@wall@thumbCaptionWidth}%
+\raggedright
+\thumbFmt
+{\thumbMonthFmt \@tr@monthNumName{\monthToNum{#1}}}\par
+{\thumbCaptionFmt \@wall@photoCaption}%
+\end{minipage}%
+\fi%
+}
+#+end_src
+
+** \textbackslash ThumbsPage
+
+#+begin_src tex :tangle ./examples/cal-thumbnails.tex
+\newlength{\thumbColumnWidth}
+\newlength{\thumbColumnHeight}
+\newlength{\thumbSep}
+\newlength{\@t@a}
+\newlength{\@t@b}
+
+% vertical spacing
+\setlength{\@t@a}{0.2\textheight}
+
+% horizontal spacing
+\setlength{\@t@b}{0.2\@wall@thumbCaptionWidth}% 8mm at 40mm caption width
+
+\ifdimcomp{\@t@a}{<}{\@t@b}{
+ \setlength{\thumbSep}{\@t@a}
+}{
+ \setlength{\thumbSep}{\@t@b}
+}
+
+\setlength{\thumbColumnWidth}{0.5\calPaperWidth - \thumbSep}
+\setlength{\thumbColumnHeight}{\textheight}
+
+\newcommand\ThumbsPage{%
+\clearpage
+
+\hspace*{-\@wall@leftMargin}%
+\hspace*{-1pt}% small correction, space gets in somewhere
+% Wrap
+\begin{minipage}[t][\thumbColumnHeight]{\calPaperWidth}%
+\centering%
+\setlength{\parindent}{0pt}%
+\setlength{\parskip}{0pt}%
+
+% NOTE: multicols will not \vfill
+% Left Column
+\begin{minipage}[t][\thumbColumnHeight]{\thumbColumnWidth}%
+\raggedleft
+
+\ThumbWithCaptionLeftSide{January}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{March}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{May}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{July}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{September}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{November}
+
+% End of left column
+\end{minipage}%
+%
+\hspace*{\thumbSep}%
+%
+% Right column
+\begin{minipage}[t][\thumbColumnHeight]{\thumbColumnWidth}%
+\raggedright
+
+\ThumbWithCaptionRightSide{February}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{April}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{June}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{August}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{October}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{December}
+
+% End of right column
+\end{minipage}%
+
+% End of wrap
+\end{minipage}%
+}
+#+end_src
+
+** Setup the photo keys
+
+#+begin_src tex :tangle ./examples/cal-thumbnails.tex
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{January}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{February}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{March}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{April}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{May}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{June}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{July}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{August}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{September}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{October}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{November}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{December}
+
+\makeatother
+#+end_src
+
+** Use it
+
+#+begin_src tex :tangle ./examples/cal-thumbnails.tex
+\begin{document}
+
+\ThumbsPage
+
+\end{document}
+#+end_src
+
+* Documentclass Options
+
+: year
+
+: language
+
+: imageFolder
+
+: showframe
+
+: showtrims
+
+: varnishmask
+
+* User Commands
+
+: \SetPhoto[ options ]{ month }
+
+: \SetQuote[ options ]{ month }{ quote text }
+
+: \SetCalendar[ options ]{ month }
+
+: \SetEvents[ options ]{ month }{ calendar tikz marks }{ events text }
+
+: \MonthPage[ options ]{ month }
+
+#+latex: \clearpage
+
+* Page Layout
+
+We will review how the page layout happens when we call =\MonthPage=.
+
+Before calling =\MonthPage= to typeset a particular month, be sure that the
+content for the given month has been already set with =\SetPhoto=, =\SetQuote=,
+=\SetCalendar= and =\SetEvents=.
+
+Then we can typeset that month, for example:
+
+: \MonthPage[layout=full page, put photo=full page]{June}
+
+This will be a full page portrait month with the photo scaled to cover the
+entire page with additional bleed on all four sides.
+
+#+begin_latex
+\twocol{%
+ \frame{\includegraphics[width=5cm]{cal-plain-01}}%
+}{%
+ \includegraphics[width=6.12cm]{cal-showframe-01}%
+}
+#+end_latex
+
+The above =showframe= figure shows the structural elements of the page.
+
+Every layout is implemented by a single handler macro which will deal with all
+the typesetting of the given page. The =full page= key is set to the
+=\@wall@fullPageLayout= macro by default, and so this gets called.
+
+The layout macro is just a free-style placeholder. It can access the photo,
+quote, calendar and events as set earlier, but it is up to the macro to
+implement what to do with them.
+
+This is for the convenience of setting the page elements using the same
+interface, but being able to execute different layouts for different pages.
+
+The class contains two layout examples. The =full page= layout is best for
+portrait photos that can be scaled to cover the entire page. The =small
+landscape= layout is for landscape photos which can be scaled horizontally,
+possibly bleeding into the side margins.
+
+* Contact
+
+Github: <https://github.com/profound-labs/wallcalendar/>
+
+Email: =Gambhīro Bhikkhu <gambhiro.bhikkhu.85@gmail.com>=
diff --git a/macros/luatex/latex/wallcalendar/doc/wallcalendar.tex b/macros/luatex/latex/wallcalendar/doc/wallcalendar.tex
new file mode 100644
index 0000000000..91b5a4ef3f
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/doc/wallcalendar.tex
@@ -0,0 +1,1190 @@
+\documentclass[11pt,oneside]{memoir-article}
+\usepackage{local}
+\renewcommand{\docVersion}{v1.3.1}
+\renewcommand{\docUrl}{\href{https://github.com/profound-labs/wallcalendar/}{link}}
+\hypersetup{ pdfauthor={Gambhīro Bhikkhu}, }
+\author{Gambhīro Bhikkhu}
+\date{\today}
+\title{Wallcalendar User Manual}
+\hypersetup{
+ pdfauthor={Gambhīro Bhikkhu},
+ pdftitle={Wallcalendar User Manual},
+ pdfkeywords={},
+ pdfsubject={},
+ pdfcreator={Emacs 25.1.1 (Org mode 9.0.9)},
+ pdflang={English}}
+\begin{document}
+
+\maketitle
+\input{frontpage.tex}
+
+\chapter{Tutorial: Forest Calendar}
+\label{sec:org9e1c3d1}
+
+In this tutorial we will produce the three example pages seen in the summary.
+
+Set the parameters of the month pages in advance, either in the preamble or in
+the document body, but before calling \texttt{\textbackslash{}MonthPage\{ month \}} to typeset it.
+
+A month page can have four areas:
+
+\begin{itemize}
+\item Photo
+\item Quote
+\item Calendar
+\item Events
+\end{itemize}
+
+Their parameters are set separately for each month:
+
+\begin{verbatim}
+\SetPhoto[ options ]{ month }
+\SetQuote[ options ]{ month }{ quote text }
+\SetCalendar[ options ]{ month }
+\SetEvents[ options ]{ month }{ calendar tikz marks }{ events text }
+\end{verbatim}
+
+The month page will be typeset with:
+
+\begin{verbatim}
+\MonthPage[ options ]{ month }
+\end{verbatim}
+
+\section{Documentclass}
+\label{sec:orgbba6dea}
+
+To start, load the documentclass and set \texttt{year}, \texttt{language} and the \texttt{imageFolder}:
+
+\begin{verbatim}
+\documentclass[
+ year=2018,
+ language=english,
+ imageFolder=./photos/,
+]{wallcalendar}
+\end{verbatim}
+
+Let's start the preamble with \texttt{\textbackslash{}makeatletter} to be safe.
+
+\begin{verbatim}
+\makeatletter
+\end{verbatim}
+
+\section{Font settings}
+\label{sec:org30e28c2}
+
+For this example we'll use \TeX{} Gyre Pagella as the main typeface. We also load
+DejaVu Sans to use a particular glyph as a mark in the calendar (\texttt{U+263C} white
+sun with rays).
+
+\begin{verbatim}
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+\end{verbatim}
+
+\clearpage
+
+\section{June}
+\label{sec:org6815f95}
+
+\twocol{%
+ \frame{\includegraphics[width=5cm]{cal-plain-01}}%
+}{%
+ \includegraphics[width=6.12cm]{cal-showframe-01}%
+}
+
+\twocolcaption{\mbox{}}{%
+ \raggedright
+ \texttt{showtrims} and \texttt{showframe} class options show the page structure.
+}
+
+\bigskip
+
+It will be a full page photo, with 3mm bleed on all four sides. You can see the
+bleed if you enable the \texttt{showtrims} class option. We also specify the file name
+of the photo (no extension), this will be the argument of \texttt{\textbackslash{}includegraphics}.
+
+\begin{verbatim}
+\SetPhoto[bleed=3mm, file={obscure-crop}]{June}
+\end{verbatim}
+
+A quote will be positioned over the photo. The quote is in a \texttt{\textbackslash{}linewidth} wide
+minipage, attached to the top left corner of the page. Use \texttt{\textbackslash{}raggedleft},
+\texttt{\textbackslash{}raggedright}, or \texttt{\textbackslash{}centering} for alignment, and the \texttt{xOffset} and \texttt{yOffset}
+options to move the quote's minipage to the exact position.
+
+\begin{verbatim}
+\SetQuote[xOffset=-5mm, yOffset=-20mm]{June}{%
+\raggedright
+\setlength{\parskip}{10pt}%
+\Large
+\color{white}
+
+I shall set forth for somewhere,\\
+I shall make the reckless choice\\
+Some day when they are in voice\\
+And tossing so as to scare\\
+The white clouds over them on.\\
+I shall have less to say,\\
+But I shall be gone.
+
+\textit{The Sound of the Trees} by Robert Frost
+}
+\end{verbatim}
+
+The layout macro will place the calendar at the bottom, dates in a single line.
+
+Here we use a conditional to use a different calendar style when \texttt{showframe} is
+turned on, this helps with debugging or tuning the position.
+
+\begin{verbatim}
+\ifshowframe
+ \SetCalendar[bg/.style={opacity=0.5, fill=white}]{June}
+\else
+ \SetCalendar[bg/.style={opacity=0.8}]{June}
+\fi
+\end{verbatim}
+
+Events for particular days are printed under the calendar.
+
+\begin{verbatim}
+\SetEvents{June}{%
+ if (equals=2018-06-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}{%
+\raggedleft
+{\dejaVuSans\char"263C} June 21: Summer Solstice
+}
+\end{verbatim}
+
+\section{July}
+\label{sec:orgda955cc}
+
+\twocol{%
+ \frame{\includegraphics[width=5cm]{cal-plain-02}}%
+}{%
+ \includegraphics[width=6.12cm]{cal-showframe-02}%
+}
+
+Same as June, but we will set the image to be placed above the calendar, and we
+add a transparent background for the quote.
+
+This layout is a good option when the top or the bottom of the photo has to be
+cropped, and you can't use the full page aspect ratio for the photo.
+
+\begin{verbatim}
+\SetPhoto[bleed=3mm, file={obscure-crop}]{July}
+
+\SetQuote[%
+ xOffset=0.5\linewidth - 0.5\paperwidth -3mm,
+ yOffset=-20mm,
+]{July}{%
+\begin{tikzpicture}%
+\node [
+ fill=white, opacity=0.6, minimum width={\paperwidth + 3mm},
+ minimum height=30mm] {};%
+\node [] {%
+\begin{minipage}{\paperwidth + 3mm}%
+\centering
+\Large
+\color{white}
+
+I shall have less to say,\\
+But I shall be gone.
+
+\textit{The Sound of the Trees} by Robert Frost
+\end{minipage}%
+};
+\end{tikzpicture}%
+}
+
+\ifshowframe
+ \SetCalendar[bg/.style={opacity=0.5}]{July}
+\else
+ \SetCalendar[bg/.style={opacity=1}]{July}
+\fi
+
+\SetEvents{July}{
+ if (equals=2018-07-27) [day text={\dejaVuSans\char"263C}];
+}{%
+\raggedleft
+{\dejaVuSans\char"263C} July 27: Mars at Opposition
+}
+\end{verbatim}
+
+\section{August}
+\label{sec:org522c828}
+
+\twocol{%
+ \frame{\includegraphics[width=5cm]{cal-plain-03}}%
+}{%
+ \includegraphics[width=6.12cm]{cal-showframe-03}%
+}
+
+This layout works for photos that are horizontal (landscape orientation), scaled
+into the bleed margin on three sides.
+
+\begin{verbatim}
+\SetPhoto[bleed=3mm, file={obscure-crop}, yOffset=-150mm]{August}
+
+\SetQuote[yOffset=-3mm]{August}{%
+\centering
+\setlength{\parskip}{10pt}%
+\Large
+\color{black!80}
+
+I shall have less to say,\\
+But I shall be gone.
+
+\textit{The Sound of the Trees} by Robert Frost
+}
+
+\ifshowframe
+ \SetCalendar[bg/.style={opacity=0.5}]{August}
+\else
+ \SetCalendar[bg/.style={opacity=1}]{August}
+\fi
+
+\SetEvents{August}{
+ if (equals=2018-08-12) [day text={\dejaVuSans\char"263C}];
+}{%
+\raggedleft
+{\dejaVuSans\char"263C} August 12, 13: Perseids Meteor Shower
+}
+\end{verbatim}
+
+End of the preamble.
+
+\begin{verbatim}
+\makeatother
+\end{verbatim}
+
+\section{The document}
+\label{sec:org80f370d}
+
+Typesetting the month pages in the document is now just this much:
+
+\begin{verbatim}
+\begin{document}
+
+\MonthPage[layout=full page, put photo=full page]{June}
+
+\MonthPage[layout=full page, put photo=full width above calendar]{July}
+
+\MonthPage[layout=small landscape, put photo=full width]{August}
+
+\end{document}
+\end{verbatim}
+
+\clearpage
+
+\chapter{Tutorial: Translations}
+\label{sec:org28303a7}
+
+In this tutorial we will produce the same calendar in three languages: Japanese,
+English and Hungarian.
+
+We are going to use \texttt{IPAPMincho} font for the Japanese.
+
+\begin{extrafullwidth}
+
+\hfill
+\begin{minipage}{0.31\linewidth}
+\centering
+
+\frame{\includegraphics[width=5cm]{./examples/cal-translations-japanese.pdf}}
+
+\end{minipage}%
+\begin{minipage}{0.31\linewidth}
+\centering
+
+\frame{\includegraphics[width=5cm]{./examples/cal-translations-english.pdf}}
+
+\end{minipage}%
+\begin{minipage}{0.31\linewidth}
+\centering
+
+\frame{\includegraphics[width=5cm]{./examples/cal-translations-hungarian.pdf}}
+
+\end{minipage}
+\hfill\mbox{}
+
+\end{extrafullwidth}
+
+\section{Files}
+\label{sec:orga8965a9}
+
+The main document files:
+
+\begin{verbatim}
+cal-translations-japanese.tex
+cal-translations-english.tex
+cal-translations-hungarian.tex
+\end{verbatim}
+
+Fonts, formatting settings, etc.:
+
+\begin{verbatim}
+local-japanese.sty
+local-english.sty
+local-hungarian.sty
+\end{verbatim}
+
+Translation text input:
+
+\begin{verbatim}
+frog-japanese.tex
+frog-english.tex
+frog-hungarian.tex
+\end{verbatim}
+
+Setup month pages (same across translations):
+
+\begin{verbatim}
+frog.tex
+\end{verbatim}
+
+\section{Translations setup}
+\label{sec:org2adcd24}
+
+Create the \texttt{frog-english.tex} file and use the \texttt{\textbackslash{}SetTxt\{ key \}\{ content \}}
+command to set text content for translation keys.
+
+\texttt{frog-japanese.tex}
+
+\begin{verbatim}
+\SetTxt{September Quote}{%
+{\mincho æ–°æ± ã‚„è›™ã¨ã³ã“む音もãªã—}
+
+{\Large\textit{araike ya / kawazu tobikomu / oto mo nashi}}
+
+{\mincho 良寛}%
+}
+
+\newcommand\SeptMarks{%
+ if (equals=2018-09-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}
+
+\SetTxt{Sept Events}{%
+{\dejaVuSans\char"263C} {\mincho 9月 21æ—¥: ã¾ã“ã¨ã« 9月 21æ—¥}
+}
+\end{verbatim}
+
+\texttt{frog-english.tex}
+
+\begin{verbatim}
+\SetTxt{September Quote}{%
+silent new lake\\
+let the frog jump\\
+not even a sound
+
+\textit{-- Ryokan}%
+}
+
+\newcommand\SeptMarks{%
+ if (equals=2018-09-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}
+
+\SetTxt{Sept Events}{%
+{\dejaVuSans\char"263C} Sept 21: September 21
+}
+\end{verbatim}
+
+\texttt{frog-hungarian.tex}
+
+\begin{verbatim}
+\SetTxt{September Quote}{%
+hallgat az új tó\\
+ugorhat béka belé\\
+vize se csobban
+
+\textit{-- Rjókan}%
+}
+
+\newcommand\SeptMarks{%
+ if (equals=2018-09-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}
+
+\SetTxt{Sept Events}{%
+{\dejaVuSans\char"263C} Szept 21: Szeptember 21
+}
+\end{verbatim}
+
+\textbf{NOTE:} Using \texttt{\textbackslash{}SetTxt\{\}} to store values intended as tikz marks on the calendar
+will not work. The \texttt{\textbackslash{}txt\{\}} command will be the value of \texttt{\textbackslash{}@eventmarks} and tikz
+can't resolve it there.
+
+Put the calendar marks in a command instead, as above with \texttt{\textbackslash{}SeptMarks}.
+
+\begin{verbatim}
+\calendar (cal#1)
+ [alnitak, dates=\CalendarYear-#1-01 to \CalendarYear-#1-last]
+ \@eventmarks;%
+\end{verbatim}
+
+\begin{verbatim}
+% NOTE This code below will not work.
+% Put the calendar marks in a command instead.
+
+\SetTxt{Sept Marks}{%
+ if (equals=2018-09-21)
+ [day text={\dejaVuSans\char"263C}];% U+263C white sun with rays
+}
+
+% ...
+
+\SetEvents{September}{%
+\txt{Sept Marks}
+}{%
+\raggedleft
+\txt{Sept Events}
+}
+\end{verbatim}
+
+\section{Document setup}
+\label{sec:org736afc3}
+
+Load the documentclass. We are setting the \texttt{translations} option to define the
+file where translation keys are set. This file is loaded by the documentclass as
+an \texttt{\textbackslash{}input}.
+
+\texttt{cal-translations-japanese.tex}
+
+\begin{verbatim}
+\documentclass[
+ year = 2018,
+ language = japanese,
+ translationsInputFile = frog-japanese.tex,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\usepackage{local-japanese}
+
+% Content is the same across translations
+\input{./frog.tex}
+
+\begin{document}
+
+% Just one month
+\MonthPage[layout=full page, put photo=full page]{September}
+
+\end{document}
+\end{verbatim}
+
+\texttt{local-japanese.sty}
+
+\begin{verbatim}
+\ProvidesPackage{local-japanese}
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+% Japanese font
+\newfontfamily\mincho{IPAPMincho}
+
+% Renew formatting hooks to use the \mincho font
+\renewcommand\fullPageFmt{%
+ \renewcommand*\monthFmt{\LARGE\mincho}%
+ \renewcommand*\yearFmt{\LARGE\mincho}%
+ \renewcommand*\dayLetterColor{}%
+ \renewcommand*\dayLetterFmt{\tiny\mincho}%
+ \renewcommand*\dayTextFmt{\small}%
+ \renewcommand*\quoteFmt{}%
+ \renewcommand*\headingFmt{\centering}%
+ \renewcommand*\calendarFmt{\centering}%
+ \renewcommand*\eventsFmt{%
+ \setlength{\parindent}{0pt}\raggedleft\footnotesize%
+ }%
+}
+\end{verbatim}
+
+\texttt{cal-translations-english.tex}
+
+\begin{verbatim}
+\documentclass[
+ year = 2018,
+ language = english,
+ translationsInputFile = frog-english.tex,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\usepackage{local-english}
+
+\input{./frog.tex}
+
+\begin{document}
+
+\MonthPage[layout=full page, put photo=full page]{September}
+
+\end{document}
+\end{verbatim}
+
+\texttt{local-english.sty}
+
+\begin{verbatim}
+\ProvidesPackage{local-english}
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+\end{verbatim}
+
+\texttt{cal-translations-hungarian.tex}
+
+\begin{verbatim}
+\documentclass[
+ year = 2018,
+ language = hungarian,
+ translationsInputFile = frog-hungarian.tex,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\usepackage{local-hungarian}
+
+\input{./frog.tex}
+
+\begin{document}
+
+\MonthPage[layout=full page, put photo=full page]{September}
+
+\end{document}
+\end{verbatim}
+
+\texttt{local-hungarian.sty}
+
+\begin{verbatim}
+\ProvidesPackage{local-hungarian}
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+\end{verbatim}
+
+\texttt{frog.tex}
+
+\begin{verbatim}
+\makeatletter
+
+\SetPhoto[bleed=3mm, file={frog-crop}]{September}
+\end{verbatim}
+
+Use the \texttt{\textbackslash{}txt\{ key \}} command to load text from translation keys:
+
+\begin{verbatim}
+\SetQuote[xOffset=0pt, yOffset=-140mm]{September}{%
+\raggedleft\setlength{\parskip}{10pt}\HUGE\color{white}%
+\txt{September Quote}%
+}
+\end{verbatim}
+
+Calendar settings for the month, using \texttt{\textbackslash{}txt} to access translated parts.
+
+\begin{verbatim}
+\SetCalendar[bg/.style={opacity=0.4}]{September}
+
+\SetEvents{September}{%
+\SeptMarks%
+}{%
+\raggedleft
+\txt{Sept Events}
+}
+
+\makeatother
+\end{verbatim}
+
+\clearpage
+
+\chapter{Tutorial: Load Events from CSV}
+\label{sec:org12d351e}
+
+\begin{fullwidth}
+\begin{minipage}{\linewidth}
+\centering
+
+\frame{\includegraphics[width=\linewidth, clip, trim=0pt 0pt 0pt 22cm]{./examples/cal-marks.pdf}}
+
+\end{minipage}%
+\end{fullwidth}
+
+\section{CSV files}
+\label{sec:orgba9e3f8}
+
+Events in the CSV should be already sorted by date.
+
+If you are using more than one CSV, put all events with notes (i.e. indexed
+entries) in the same CSV. The index number of the mark is taken from the row
+number in the CSV, so a second CSV with notes would start the count from 1
+again.
+
+We're going to use the following csv files, see in the \texttt{./doc/examples/data/} folder.
+
+\texttt{holidays.csv}
+
+\texttt{moonphases.csv}
+
+\texttt{mark\_defaults.csv}
+
+\section{Event formatting}
+\label{sec:orgbf5aa37}
+
+You can format the event output by setting the \texttt{format cmd} key:
+
+\begin{verbatim}
+\parseMonthEvents[%
+ format cmd = {%
+ \textsuperscript{\eMark}~\eMonthShort~\eDay:\space%
+ \eNote\ifnumless{\eIdx}{\eMaxIdx}{,\space}{.}%
+ },
+]%
+\end{verbatim}
+
+Or define a Lua formatting function and set it with the \texttt{format func} key:
+
+\texttt{helpers.lua}
+
+\begin{verbatim}
+function eventFmtCustom(idx, max_idx, event, event_date, mark)
+ local d = event_date
+ tex.sprint(string.format(
+ "\\textsuperscript{%s} & %s %s: & %s \\\\",
+ mark.symbol, d:fmt("%b"), d:getday(), event.note
+ ))
+end
+\end{verbatim}
+
+\begin{verbatim}
+\parseMonthEvents[format func = eventFmtCustom]%
+\end{verbatim}
+
+\section{Document setup}
+\label{sec:orgb56123b}
+
+\texttt{cal-marks.tex}
+
+\begin{verbatim}
+\documentclass[
+ year = 2018,
+ eventsCsv = ./data/holidays.csv,
+ markDefaultsCsv = ./data/mark_defaults.csv,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\makeatletter
+
+\colorlet{mooncolor}{darkgold}
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+
+\SetPhoto[bleed=3mm, file={frog-crop}]{September}
+
+\SetQuote[xOffset=0pt, yOffset=-140mm]{September}{%
+\raggedleft\setlength{\parskip}{10pt}\HUGE\color{white}%
+silent new lake\\
+let the frog jump\\
+not even a sound
+
+\textit{-- Ryokan}%
+}
+
+\SetCalendar[bg/.style={opacity=0.4}]{September}
+
+\SetEvents{September}{%
+\parseMonthMarksDayTextUsing{./data/moonphases.csv}%
+\parseMonthMarksDayText%
+\parseMonthMarksNote%
+}{%
+\raggedright
+\parseMonthEvents[%
+ format cmd = {%
+ \textsuperscript{\eMark}~\eMonthShort~\eDay:\space%
+ \eNote\ifnumless{\eIdx}{\eMaxIdx}{,\space}{.}%
+ },
+]%
+}
+
+\makeatother
+
+\begin{document}
+
+\MonthPage[layout=full page, put photo=full page]{September}
+
+\end{document}
+\end{verbatim}
+
+\clearpage
+
+\chapter{Example: Year Planner Page}
+\label{sec:org24663e1}
+
+\begin{fullwidth}
+\begin{minipage}{0.31\linewidth}
+\centering
+
+\frame{\includegraphics[width=5cm]{./examples/cal-year-planner.pdf}}
+
+\end{minipage}%
+\end{fullwidth}
+
+\section{Document setup}
+\label{sec:org85fac7e}
+
+\texttt{cal-year-planner.tex}
+
+\begin{verbatim}
+\documentclass[
+ year = 2018,
+ eventsCsv = ./data/holidays.csv,
+ markDefaultsCsv = ./data/mark_defaults.csv,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\makeatletter
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+
+% Use two CSV files for day text input to include the moon phases
+\renewcommand\@wall@plm[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{#1}, nil, \luastring{\plannerMarksDayTextCSV})
+monthMarksDayText(\luastring{#1}, nil, \luastring{./data/moonphases.csv})
+tex.sprint(';')
+}}
+\end{verbatim}
+
+\section{\textbackslash YearPlannerPage}
+\label{sec:org0124cf4}
+
+\begin{verbatim}
+\newcommand\plannerYearFmt{\fontsize{26}{26}\selectfont\color{orangegold}}
+
+\newlength\plannerNotesSep
+\setlength{\plannerNotesSep}{3mm}
+
+\newcommand\preYearPlannerPageHook{%
+ \setlength{\markNumberAbove}{-9pt}%
+ \setlength{\markNumberRight}{-6pt}%
+ \setlength{\markDayTextAbove}{-11pt}%
+ \setlength{\markDayTextRight}{-6pt}%
+}
+
+\newcommand\postYearPlannerPageHook{%
+ \setlength{\markNumberAbove}{-10pt}%
+ \setlength{\markNumberRight}{-3pt}%
+ \setlength{\markDayTextAbove}{-10pt}%
+ \setlength{\markDayTextRight}{-3pt}%
+}
+
+\newcommand\printPlannerTitle{\plannerYearFmt \CalendarYear}
+
+\newcommand\YearPlannerPage{%
+\newpage
+\ifvarnishmask
+\mbox{}
+\else
+\preYearPlannerPageHook
+{\centering
+
+{\printPlannerTitle}
+
+\vspace*{7mm}
+
+\YearPlannerPortrait
+
+\vspace*{\plannerNotesSep}
+
+\plannerEvents
+
+}
+\postYearPlannerPageHook
+
+\fi
+}
+
+\makeatother
+\end{verbatim}
+
+\section{Use it}
+\label{sec:org70f504f}
+
+\begin{verbatim}
+\begin{document}
+
+\YearPlannerPage
+
+\end{document}
+\end{verbatim}
+
+\clearpage
+
+\chapter{Example: Photo Thumbnails Page}
+\label{sec:org0431559}
+
+\begin{fullwidth}
+\begin{minipage}{0.31\linewidth}
+\centering
+
+\frame{\includegraphics[width=5cm]{./examples/cal-thumbnails.pdf}}
+
+\end{minipage}%
+\end{fullwidth}
+
+\section{Document setup}
+\label{sec:orgc4970c9}
+
+\texttt{cal-thumbnails.tex}
+
+\begin{verbatim}
+\documentclass[
+ year = 2018,
+ imageFolder = ./photos/,
+]{wallcalendar}
+
+\makeatletter
+
+\usepackage{fontspec}
+\defaultfontfeatures{Ligatures={TeX}}
+\setmainfont{TeX Gyre Pagella}
+\newfontfamily\dejaVuSans{DejaVu Sans}
+
+\newlength\@wall@tmp@a
+\newlength\@wall@tmp@b
+\end{verbatim}
+
+\section{\textbackslash ThumbWithCaptionLeftSide}
+\label{sec:orge74d943}
+
+Typesets the photo thumb image with its caption text on the left side.
+
+\begin{verbatim}
+\ThumbWithCaptionLeftSide{January}
+\end{verbatim}
+
+\begin{verbatim}
+\newlength\@wall@thumbWidth
+\newlength\@wall@thumbHeight
+\newlength\@wall@thumbCaptionWidth
+\setlength{\@wall@thumbWidth}{0.1749\calPaperWidth}% 30mm at the 6.75in page width, 0.1749 = 1/5.715
+\setlength{\@wall@thumbHeight}{\@wall@thumbWidth}
+\setlength{\@wall@thumbCaptionWidth}{0.2333\calPaperWidth}% 40mm at 6.75in page width
+
+\newcommand\thumbFmt{}
+\newcommand\thumbMonthFmt{\fontsize{10}{13}\selectfont\bfseries}
+\newcommand\thumbCaptionFmt{\fontsize{10}{13}\selectfont}
+
+\def\@wall@thumbFile{}
+\def\@wall@photoCaption{}
+
+\newcommand\ThumbWithCaptionLeftSide[1]{%
+\pgfkeys{/Photo/#1/thumbFile/.get=\@wall@thumbFile}%
+\ifx\@wall@thumbFile\empty
+ \pgfkeys{/Photo/#1/file/.get=\@wall@thumbFile}%
+\fi
+\pgfkeys{/Photo/#1/caption/.get=\@wall@photoCaption}%
+% Thumbnail caption
+\ifvarnishmask%
+\hspace*{\@wall@thumbWidth}
+\else%
+\begin{minipage}[b][\@wall@thumbHeight][t]{\@wall@thumbCaptionWidth}%
+\raggedleft
+\thumbFmt
+{\thumbMonthFmt \@tr@monthNumName{\monthToNum{#1}}}\par
+{\thumbCaptionFmt \@wall@photoCaption}%
+\end{minipage}%
+\fi%
+\hspace*{3mm}
+% Thumbnail photo
+\begin{minipage}[b][\@wall@thumbHeight]{\@wall@thumbWidth}%
+% FIXME placeholder
+%\placeholder{%
+\includegraphics[ keepaspectratio, height=\@wall@thumbHeight ]{\@wall@thumbFile}%
+%}%
+\end{minipage}%
+}
+\end{verbatim}
+
+\section{\textbackslash ThumbWithCaptionRightSide}
+\label{sec:org7af4bd6}
+
+Typesets the photo thumb image with its caption text on the right side.
+
+\begin{verbatim}
+\ThumbWithCaptionRightSide{January}
+\end{verbatim}
+
+\begin{verbatim}
+\newcommand\ThumbWithCaptionRightSide[1]{%
+\pgfkeys{/Photo/#1/thumbFile/.get=\@wall@thumbFile}%
+\ifx\@wall@thumbFile\empty
+ \pgfkeys{/Photo/#1/file/.get=\@wall@thumbFile}%
+\fi
+\pgfkeys{/Photo/#1/caption/.get=\@wall@photoCaption}%
+% Thumbnail photo
+\begin{minipage}[b][\@wall@thumbHeight]{\@wall@thumbWidth}%
+% FIXME placeholder
+%\placeholder{%
+\includegraphics[ keepaspectratio, height=\@wall@thumbHeight ]{\@wall@thumbFile}%
+%}%
+\end{minipage}%
+\hspace*{3mm}
+% Thumbnail caption
+\ifvarnishmask%
+\hspace*{\@wall@thumbWidth}
+\else%
+\begin{minipage}[b][\@wall@thumbHeight][t]{\@wall@thumbCaptionWidth}%
+\raggedright
+\thumbFmt
+{\thumbMonthFmt \@tr@monthNumName{\monthToNum{#1}}}\par
+{\thumbCaptionFmt \@wall@photoCaption}%
+\end{minipage}%
+\fi%
+}
+\end{verbatim}
+
+\section{\textbackslash ThumbsPage}
+\label{sec:org9571a13}
+
+\begin{verbatim}
+\newlength{\thumbColumnWidth}
+\newlength{\thumbColumnHeight}
+\newlength{\thumbSep}
+\newlength{\@t@a}
+\newlength{\@t@b}
+
+% vertical spacing
+\setlength{\@t@a}{0.2\textheight}
+
+% horizontal spacing
+\setlength{\@t@b}{0.2\@wall@thumbCaptionWidth}% 8mm at 40mm caption width
+
+\ifdimcomp{\@t@a}{<}{\@t@b}{
+ \setlength{\thumbSep}{\@t@a}
+}{
+ \setlength{\thumbSep}{\@t@b}
+}
+
+\setlength{\thumbColumnWidth}{0.5\calPaperWidth - \thumbSep}
+\setlength{\thumbColumnHeight}{\textheight}
+
+\newcommand\ThumbsPage{%
+\clearpage
+
+\hspace*{-\@wall@leftMargin}%
+\hspace*{-1pt}% small correction, space gets in somewhere
+% Wrap
+\begin{minipage}[t][\thumbColumnHeight]{\calPaperWidth}%
+\centering%
+\setlength{\parindent}{0pt}%
+\setlength{\parskip}{0pt}%
+
+% NOTE: multicols will not \vfill
+% Left Column
+\begin{minipage}[t][\thumbColumnHeight]{\thumbColumnWidth}%
+\raggedleft
+
+\ThumbWithCaptionLeftSide{January}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{March}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{May}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{July}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{September}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionLeftSide{November}
+
+% End of left column
+\end{minipage}%
+%
+\hspace*{\thumbSep}%
+%
+% Right column
+\begin{minipage}[t][\thumbColumnHeight]{\thumbColumnWidth}%
+\raggedright
+
+\ThumbWithCaptionRightSide{February}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{April}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{June}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{August}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{October}
+
+\vspace*{\thumbSep}
+
+\ThumbWithCaptionRightSide{December}
+
+% End of right column
+\end{minipage}%
+
+% End of wrap
+\end{minipage}%
+}
+\end{verbatim}
+
+\section{Setup the photo keys}
+\label{sec:org1bdd209}
+
+\begin{verbatim}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{January}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{February}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{March}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{April}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{May}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{June}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{July}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{August}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{September}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{October}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{November}
+\SetPhoto[file={frog-crop}, thumbFile={frog-crop-thumb}, caption={Let the frog jump}]{December}
+
+\makeatother
+\end{verbatim}
+
+\section{Use it}
+\label{sec:org23c0fca}
+
+\begin{verbatim}
+\begin{document}
+
+\ThumbsPage
+
+\end{document}
+\end{verbatim}
+
+\chapter{Documentclass Options}
+\label{sec:org5024f18}
+
+\begin{verbatim}
+year
+\end{verbatim}
+
+\begin{verbatim}
+language
+\end{verbatim}
+
+\begin{verbatim}
+imageFolder
+\end{verbatim}
+
+\begin{verbatim}
+showframe
+\end{verbatim}
+
+\begin{verbatim}
+showtrims
+\end{verbatim}
+
+\begin{verbatim}
+varnishmask
+\end{verbatim}
+
+\chapter{User Commands}
+\label{sec:org02a2f80}
+
+\begin{verbatim}
+\SetPhoto[ options ]{ month }
+\end{verbatim}
+
+\begin{verbatim}
+\SetQuote[ options ]{ month }{ quote text }
+\end{verbatim}
+
+\begin{verbatim}
+\SetCalendar[ options ]{ month }
+\end{verbatim}
+
+\begin{verbatim}
+\SetEvents[ options ]{ month }{ calendar tikz marks }{ events text }
+\end{verbatim}
+
+\begin{verbatim}
+\MonthPage[ options ]{ month }
+\end{verbatim}
+
+\clearpage
+
+\chapter{Page Layout}
+\label{sec:org2801ae6}
+
+We will review how the page layout happens when we call \texttt{\textbackslash{}MonthPage}.
+
+Before calling \texttt{\textbackslash{}MonthPage} to typeset a particular month, be sure that the
+content for the given month has been already set with \texttt{\textbackslash{}SetPhoto}, \texttt{\textbackslash{}SetQuote},
+\texttt{\textbackslash{}SetCalendar} and \texttt{\textbackslash{}SetEvents}.
+
+Then we can typeset that month, for example:
+
+\begin{verbatim}
+\MonthPage[layout=full page, put photo=full page]{June}
+\end{verbatim}
+
+This will be a full page portrait month with the photo scaled to cover the
+entire page with additional bleed on all four sides.
+
+\twocol{%
+ \frame{\includegraphics[width=5cm]{cal-plain-01}}%
+}{%
+ \includegraphics[width=6.12cm]{cal-showframe-01}%
+}
+
+The above \texttt{showframe} figure shows the structural elements of the page.
+
+Every layout is implemented by a single handler macro which will deal with all
+the typesetting of the given page. The \texttt{full page} key is set to the
+\texttt{\textbackslash{}@wall@fullPageLayout} macro by default, and so this gets called.
+
+The layout macro is just a free-style placeholder. It can access the photo,
+quote, calendar and events as set earlier, but it is up to the macro to
+implement what to do with them.
+
+This is for the convenience of setting the page elements using the same
+interface, but being able to execute different layouts for different pages.
+
+The class contains two layout examples. The \texttt{full page} layout is best for
+portrait photos that can be scaled to cover the entire page. The \texttt{small
+landscape} layout is for landscape photos which can be scaled horizontally,
+possibly bleeding into the side margins.
+
+\chapter{Contact}
+\label{sec:orgc9e6d1d}
+
+Github: \url{https://github.com/profound-labs/wallcalendar/}
+
+Email: \texttt{Gambhīro Bhikkhu <gambhiro.bhikkhu.85@gmail.com>}
+\end{document}
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-czech.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-czech.tex
new file mode 100644
index 0000000000..91623f4e57
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-czech.tex
@@ -0,0 +1,36 @@
+% Czech
+
+\def\xJanuary{Leden}
+\def\xFebruary{Únor}
+\def\xMarch{Březen}
+\def\xApril{Duben}
+\def\xMay{Květen}
+\def\xJune{ÄŒerven}
+\def\xJuly{ÄŒervenec}
+\def\xAugust{Srpen}
+\def\xSeptember{Září}
+\def\xOctober{Říjen}
+\def\xNovember{Listopad}
+\def\xDecember{Prosinec}
+
+\def\xJanShort{Led}
+\def\xFebShort{Úno}
+\def\xMarShort{Bře}
+\def\xAprShort{Dub}
+\def\xMayShort{KvÄ›}
+\def\xJunShort{ÄŒer}
+\def\xJulShort{ÄŒer}
+\def\xAugShort{Srp}
+\def\xSepShort{Zář}
+\def\xOctShort{Říj}
+\def\xNovShort{Lis}
+\def\xDecShort{Pro}
+
+\def\xMondayDayLetter{Po}
+\def\xTuesdayDayLetter{Út}
+\def\xWednesdayDayLetter{St}
+\def\xThursdayDayLetter{ÄŒt}
+\def\xFridayDayLetter{Pá}
+\def\xSaturdayDayLetter{So}
+\def\xSundayDayLetter{Ne}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-dutch.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-dutch.tex
new file mode 100644
index 0000000000..ceb14a5216
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-dutch.tex
@@ -0,0 +1,36 @@
+% Dutch
+
+\def\xJanuary{Januari}
+\def\xFebruary{Februari}
+\def\xMarch{Maart}
+\def\xApril{April}
+\def\xMay{Mei}
+\def\xJune{Juni}
+\def\xJuly{Juli}
+\def\xAugust{Augustus}
+\def\xSeptember{September}
+\def\xOctober{Oktober}
+\def\xNovember{November}
+\def\xDecember{December}
+
+\def\xJanShort{Jan}
+\def\xFebShort{Feb}
+\def\xMarShort{Maa}
+\def\xAprShort{Apr}
+\def\xMayShort{Mei}
+\def\xJunShort{Jun}
+\def\xJulShort{Jul}
+\def\xAugShort{Aug}
+\def\xSepShort{Sep}
+\def\xOctShort{Okt}
+\def\xNovShort{Nov}
+\def\xDecShort{Dec}
+
+\def\xMondayDayLetter{ma}
+\def\xTuesdayDayLetter{di}
+\def\xWednesdayDayLetter{wo}
+\def\xThursdayDayLetter{do}
+\def\xFridayDayLetter{vr}
+\def\xSaturdayDayLetter{za}
+\def\xSundayDayLetter{zo}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-english.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-english.tex
new file mode 100644
index 0000000000..55746a05e8
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-english.tex
@@ -0,0 +1,36 @@
+% English
+
+\def\xJanuary{January}
+\def\xFebruary{February}
+\def\xMarch{March}
+\def\xApril{April}
+\def\xMay{May}
+\def\xJune{June}
+\def\xJuly{July}
+\def\xAugust{August}
+\def\xSeptember{September}
+\def\xOctober{October}
+\def\xNovember{November}
+\def\xDecember{December}
+
+\def\xJanShort{Jan}
+\def\xFebShort{Feb}
+\def\xMarShort{Mar}
+\def\xAprShort{Apr}
+\def\xMayShort{May}
+\def\xJunShort{Jun}
+\def\xJulShort{Jul}
+\def\xAugShort{Aug}
+\def\xSepShort{Sep}
+\def\xOctShort{Oct}
+\def\xNovShort{Nov}
+\def\xDecShort{Dec}
+
+\def\xMondayDayLetter{M}
+\def\xTuesdayDayLetter{T}
+\def\xWednesdayDayLetter{W}
+\def\xThursdayDayLetter{T}
+\def\xFridayDayLetter{F}
+\def\xSaturdayDayLetter{S}
+\def\xSundayDayLetter{S}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-french.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-french.tex
new file mode 100644
index 0000000000..28e48f4540
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-french.tex
@@ -0,0 +1,36 @@
+% French
+
+\def\xJanuary{Janvier}
+\def\xFebruary{Février}
+\def\xMarch{Mars}
+\def\xApril{Avril}
+\def\xMay{Mai}
+\def\xJune{Juin}
+\def\xJuly{Juillet}
+\def\xAugust{Août}
+\def\xSeptember{Septembre}
+\def\xOctober{Octobre}
+\def\xNovember{Novembre}
+\def\xDecember{Décembre}
+
+\def\xJanShort{Jan}
+\def\xFebShort{Fév}
+\def\xMarShort{Mar}
+\def\xAprShort{Avr}
+\def\xMayShort{Mai}
+\def\xJunShort{Jui}
+\def\xJulShort{Jui}
+\def\xAugShort{Aoû}
+\def\xSepShort{Sep}
+\def\xOctShort{Oct}
+\def\xNovShort{Nov}
+\def\xDecShort{Déc}
+
+\def\xMondayDayLetter{L}
+\def\xTuesdayDayLetter{M}
+\def\xWednesdayDayLetter{M}
+\def\xThursdayDayLetter{J}
+\def\xFridayDayLetter{V}
+\def\xSaturdayDayLetter{S}
+\def\xSundayDayLetter{D}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-german.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-german.tex
new file mode 100644
index 0000000000..fb8a51958f
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-german.tex
@@ -0,0 +1,36 @@
+% German
+
+\def\xJanuary{Januar}
+\def\xFebruary{Februar}
+\def\xMarch{März}
+\def\xApril{April}
+\def\xMay{Mai}
+\def\xJune{Juni}
+\def\xJuly{Juli}
+\def\xAugust{August}
+\def\xSeptember{September}
+\def\xOctober{Oktober}
+\def\xNovember{November}
+\def\xDecember{Dezember}
+
+\def\xJanShort{Jan}
+\def\xFebShort{Feb}
+\def\xMarShort{Mär}
+\def\xAprShort{Apr}
+\def\xMayShort{Mai}
+\def\xJunShort{Jun}
+\def\xJulShort{Jul}
+\def\xAugShort{Aug}
+\def\xSepShort{Sep}
+\def\xOctShort{Okt}
+\def\xNovShort{Nov}
+\def\xDecShort{Dez}
+
+\def\xMondayDayLetter{Mo}
+\def\xTuesdayDayLetter{Di}
+\def\xWednesdayDayLetter{Mi}
+\def\xThursdayDayLetter{Do}
+\def\xFridayDayLetter{Fr}
+\def\xSaturdayDayLetter{Sa}
+\def\xSundayDayLetter{So}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-hungarian.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-hungarian.tex
new file mode 100644
index 0000000000..b0a8a45a4a
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-hungarian.tex
@@ -0,0 +1,36 @@
+% Hungarian
+
+\def\xJanuary{Január}
+\def\xFebruary{Február}
+\def\xMarch{Március}
+\def\xApril{Ãprilis}
+\def\xMay{Május}
+\def\xJune{Június}
+\def\xJuly{Július}
+\def\xAugust{Augusztus}
+\def\xSeptember{Szeptember}
+\def\xOctober{Október}
+\def\xNovember{November}
+\def\xDecember{December}
+
+\def\xJanShort{Jan}
+\def\xFebShort{Feb}
+\def\xMarShort{Már}
+\def\xAprShort{Ãpr}
+\def\xMayShort{Máj}
+\def\xJunShort{Jún}
+\def\xJulShort{Júl}
+\def\xAugShort{Aug}
+\def\xSepShort{Szep}
+\def\xOctShort{Okt}
+\def\xNovShort{Nov}
+\def\xDecShort{Dec}
+
+\def\xMondayDayLetter{H}
+\def\xTuesdayDayLetter{K}
+\def\xWednesdayDayLetter{Sz}
+\def\xThursdayDayLetter{Cs}
+\def\xFridayDayLetter{P}
+\def\xSaturdayDayLetter{Sz}
+\def\xSundayDayLetter{V}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-italian.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-italian.tex
new file mode 100644
index 0000000000..8de9bd9dae
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-italian.tex
@@ -0,0 +1,36 @@
+% Italian
+
+\def\xJanuary{Gennaio}
+\def\xFebruary{Febbraio}
+\def\xMarch{Marzo}
+\def\xApril{Aprile}
+\def\xMay{Maggio}
+\def\xJune{Giugno}
+\def\xJuly{Luglio}
+\def\xAugust{Agosto}
+\def\xSeptember{Settembre}
+\def\xOctober{Ottobre}
+\def\xNovember{Novembre}
+\def\xDecember{Dicembre}
+
+\def\xJanShort{Gen}
+\def\xFebShort{Feb}
+\def\xMarShort{Mar}
+\def\xAprShort{Apr}
+\def\xMayShort{Mag}
+\def\xJunShort{Giu}
+\def\xJulShort{Lug}
+\def\xAugShort{Ago}
+\def\xSepShort{Set}
+\def\xOctShort{Ott}
+\def\xNovShort{Nov}
+\def\xDecShort{Dic}
+
+\def\xMondayDayLetter{L}
+\def\xTuesdayDayLetter{M}
+\def\xWednesdayDayLetter{M}
+\def\xThursdayDayLetter{G}
+\def\xFridayDayLetter{V}
+\def\xSaturdayDayLetter{S}
+\def\xSundayDayLetter{D}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-japanese.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-japanese.tex
new file mode 100644
index 0000000000..368265614e
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-japanese.tex
@@ -0,0 +1,35 @@
+% Japanese
+
+\def\xJanuary{一月}
+\def\xFebruary{二月}
+\def\xMarch{三月}
+\def\xApril{四月}
+\def\xMay{五月}
+\def\xJune{六月}
+\def\xJuly{七月}
+\def\xAugust{八月}
+\def\xSeptember{ä¹æœˆ}
+\def\xOctober{å月}
+\def\xNovember{å一月}
+\def\xDecember{å二月}
+
+\def\xJanShort{1月}
+\def\xFebShort{2月}
+\def\xMarShort{3月}
+\def\xAprShort{4月}
+\def\xMayShort{5月}
+\def\xJunShort{6月}
+\def\xJulShort{7月}
+\def\xAugShort{8月}
+\def\xSepShort{9月}
+\def\xOctShort{10月}
+\def\xNovShort{11月}
+\def\xDecShort{12月}
+
+\def\xMondayDayLetter{ã’}
+\def\xTuesdayDayLetter{ã‹}
+\def\xWednesdayDayLetter{ã™}
+\def\xThursdayDayLetter{ã‚‚}
+\def\xFridayDayLetter{ã}
+\def\xSaturdayDayLetter{ã©}
+\def\xSundayDayLetter{ã«}
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-norwegian.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-norwegian.tex
new file mode 100644
index 0000000000..c69b18ebee
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-norwegian.tex
@@ -0,0 +1,36 @@
+% Norwegian
+
+\def\xJanuary{Januar}
+\def\xFebruary{Februar}
+\def\xMarch{Mars}
+\def\xApril{April}
+\def\xMay{Mai}
+\def\xJune{Juni}
+\def\xJuly{Juli}
+\def\xAugust{August}
+\def\xSeptember{September}
+\def\xOctober{Oktober}
+\def\xNovember{November}
+\def\xDecember{Desember}
+
+\def\xJanShort{Jan}
+\def\xFebShort{Feb}
+\def\xMarShort{Mar}
+\def\xAprShort{Apr}
+\def\xMayShort{Mai}
+\def\xJunShort{Jun}
+\def\xJulShort{Jul}
+\def\xAugShort{Aug}
+\def\xSepShort{Sep}
+\def\xOctShort{Okt}
+\def\xNovShort{Nov}
+\def\xDecShort{Des}
+
+\def\xMondayDayLetter{M}
+\def\xTuesdayDayLetter{T}
+\def\xWednesdayDayLetter{O}
+\def\xThursdayDayLetter{T}
+\def\xFridayDayLetter{F}
+\def\xSaturdayDayLetter{L}
+\def\xSundayDayLetter{S}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-portuguese.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-portuguese.tex
new file mode 100644
index 0000000000..d15f82f2de
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-portuguese.tex
@@ -0,0 +1,35 @@
+% Portuguese
+
+\def\xJanuary{Janeiro}
+\def\xFebruary{Fevereiro}
+\def\xMarch{Março}
+\def\xApril{Abril}
+\def\xMay{Maio}
+\def\xJune{Junho}
+\def\xJuly{Julho}
+\def\xAugust{Agosto}
+\def\xSeptember{Setembro}
+\def\xOctober{Outubro}
+\def\xNovember{Novembro}
+\def\xDecember{Dezembro}
+
+\def\xJanShort{Jan}
+\def\xFebShort{Fev}
+\def\xMarShort{Mar}
+\def\xAprShort{Abr}
+\def\xMayShort{Mai}
+\def\xJunShort{Jun}
+\def\xJulShort{Jul}
+\def\xAugShort{Ago}
+\def\xSepShort{Set}
+\def\xOctShort{Out}
+\def\xNovShort{Nov}
+\def\xDecShort{Dez}
+
+\def\xMondayDayLetter{{2\textsuperscript{a}}}
+\def\xTuesdayDayLetter{{3\textsuperscript{a}}}
+\def\xWednesdayDayLetter{{4\textsuperscript{a}}}
+\def\xThursdayDayLetter{{5\textsuperscript{a}}}
+\def\xFridayDayLetter{{6\textsuperscript{a}}}
+\def\xSaturdayDayLetter{S}
+\def\xSundayDayLetter{D}
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-romanian.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-romanian.tex
new file mode 100644
index 0000000000..2bb1deba46
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-romanian.tex
@@ -0,0 +1,36 @@
+% Romanian
+
+\def\xJanuary{Ianuarie}
+\def\xFebruary{Februarie}
+\def\xMarch{Martie}
+\def\xApril{Aprilie}
+\def\xMay{Mai}
+\def\xJune{Iunie}
+\def\xJuly{Iulie}
+\def\xAugust{August}
+\def\xSeptember{Septembrie}
+\def\xOctober{Octombrie}
+\def\xNovember{Noiembrie}
+\def\xDecember{Decembrie}
+
+\def\xJanShort{Ian}
+\def\xFebShort{Feb}
+\def\xMarShort{Mar}
+\def\xAprShort{Apr}
+\def\xMayShort{Mai}
+\def\xJunShort{Iun}
+\def\xJulShort{Iul}
+\def\xAugShort{Aug}
+\def\xSepShort{Sep}
+\def\xOctShort{Oct}
+\def\xNovShort{Noi}
+\def\xDecShort{Dec}
+
+\def\xMondayDayLetter{L}
+\def\xTuesdayDayLetter{M}
+\def\xWednesdayDayLetter{M}
+\def\xThursdayDayLetter{J}
+\def\xFridayDayLetter{V}
+\def\xSaturdayDayLetter{S}
+\def\xSundayDayLetter{D}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-serbian.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-serbian.tex
new file mode 100644
index 0000000000..7a078e8c15
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-serbian.tex
@@ -0,0 +1,36 @@
+% Serbian
+
+\def\xJanuary{Januar}
+\def\xFebruary{Februar}
+\def\xMarch{Mart}
+\def\xApril{April}
+\def\xMay{Maj}
+\def\xJune{Juni}
+\def\xJuly{Juli}
+\def\xAugust{Avgust}
+\def\xSeptember{Septembar}
+\def\xOctober{Oktobar}
+\def\xNovember{Novembar}
+\def\xDecember{Decembar}
+
+\def\xJanShort{Jan}
+\def\xFebShort{Feb}
+\def\xMarShort{Mar}
+\def\xAprShort{Apr}
+\def\xMayShort{Maj}
+\def\xJunShort{Jun}
+\def\xJulShort{Jul}
+\def\xAugShort{Avg}
+\def\xSepShort{Sep}
+\def\xOctShort{Okt}
+\def\xNovShort{Nov}
+\def\xDecShort{Dec}
+
+\def\xMondayDayLetter{Po}
+\def\xTuesdayDayLetter{Ut}
+\def\xWednesdayDayLetter{Sr}
+\def\xThursdayDayLetter{ÄŒe}
+\def\xFridayDayLetter{Pe}
+\def\xSaturdayDayLetter{Su}
+\def\xSundayDayLetter{Ne}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-slovakian.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-slovakian.tex
new file mode 100644
index 0000000000..589e58d8a1
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-slovakian.tex
@@ -0,0 +1,36 @@
+% Slovakian
+
+\def\xJanuary{Január}
+\def\xFebruary{Február}
+\def\xMarch{Marec}
+\def\xApril{Apríl}
+\def\xMay{Máj}
+\def\xJune{Jún}
+\def\xJuly{Júl}
+\def\xAugust{August}
+\def\xSeptember{September}
+\def\xOctober{Október}
+\def\xNovember{November}
+\def\xDecember{December}
+
+\def\xJanShort{Jan}
+\def\xFebShort{Feb}
+\def\xMarShort{Mar}
+\def\xAprShort{Apr}
+\def\xMayShort{Máj}
+\def\xJunShort{Jún}
+\def\xJulShort{Júl}
+\def\xAugShort{Aug}
+\def\xSepShort{Sep}
+\def\xOctShort{Okt}
+\def\xNovShort{Nov}
+\def\xDecShort{Dec}
+
+\def\xMondayDayLetter{P}
+\def\xTuesdayDayLetter{U}
+\def\xWednesdayDayLetter{S}
+\def\xThursdayDayLetter{Å }
+\def\xFridayDayLetter{P}
+\def\xSaturdayDayLetter{S}
+\def\xSundayDayLetter{N}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-slovenian.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-slovenian.tex
new file mode 100644
index 0000000000..918a635dc5
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-slovenian.tex
@@ -0,0 +1,36 @@
+% Slovenian
+
+\def\xJanuary{Januar}
+\def\xFebruary{Februar}
+\def\xMarch{Marec}
+\def\xApril{April}
+\def\xMay{Maj}
+\def\xJune{Junij}
+\def\xJuly{Julij}
+\def\xAugust{Avgust}
+\def\xSeptember{September}
+\def\xOctober{Oktober}
+\def\xNovember{November}
+\def\xDecember{December}
+
+\def\xJanShort{Jan}
+\def\xFebShort{Feb}
+\def\xMarShort{Mar}
+\def\xAprShort{Apr}
+\def\xMayShort{Maj}
+\def\xJunShort{Jun}
+\def\xJulShort{Jul}
+\def\xAugShort{Avg}
+\def\xSepShort{Sep}
+\def\xOctShort{Okt}
+\def\xNovShort{Nov}
+\def\xDecShort{Dec}
+
+\def\xMondayDayLetter{Po}
+\def\xTuesdayDayLetter{To}
+\def\xWednesdayDayLetter{Sr}
+\def\xThursdayDayLetter{ÄŒe}
+\def\xFridayDayLetter{Pe}
+\def\xSaturdayDayLetter{So}
+\def\xSundayDayLetter{Ne}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-spanish.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-spanish.tex
new file mode 100644
index 0000000000..36370da3d4
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-spanish.tex
@@ -0,0 +1,36 @@
+% Spanish
+
+\def\xJanuary{Enero}
+\def\xFebruary{Febrero}
+\def\xMarch{Marzo}
+\def\xApril{Abril}
+\def\xMay{Mayo}
+\def\xJune{Junio}
+\def\xJuly{Julio}
+\def\xAugust{Agosto}
+\def\xSeptember{Septiembre}
+\def\xOctober{Octubre}
+\def\xNovember{Noviembre}
+\def\xDecember{Diciembre}
+
+\def\xJanShort{Ene}
+\def\xFebShort{Feb}
+\def\xMarShort{Mar}
+\def\xAprShort{Abr}
+\def\xMayShort{May}
+\def\xJunShort{Jun}
+\def\xJulShort{Jul}
+\def\xAugShort{Ago}
+\def\xSepShort{Sep}
+\def\xOctShort{Oct}
+\def\xNovShort{Nov}
+\def\xDecShort{Dic}
+
+\def\xMondayDayLetter{Lu}
+\def\xTuesdayDayLetter{Ma}
+\def\xWednesdayDayLetter{Mi}
+\def\xThursdayDayLetter{Ju}
+\def\xFridayDayLetter{Vi}
+\def\xSaturdayDayLetter{Sá}
+\def\xSundayDayLetter{Do}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-swedish.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-swedish.tex
new file mode 100644
index 0000000000..c6c687f8f5
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-swedish.tex
@@ -0,0 +1,36 @@
+% Swedish
+
+\def\xJanuary{Januari}
+\def\xFebruary{Februari}
+\def\xMarch{Mars}
+\def\xApril{April}
+\def\xMay{Maj}
+\def\xJune{Juni}
+\def\xJuly{Juli}
+\def\xAugust{Augusti}
+\def\xSeptember{September}
+\def\xOctober{Oktober}
+\def\xNovember{November}
+\def\xDecember{December}
+
+\def\xJanShort{Jan}
+\def\xFebShort{Feb}
+\def\xMarShort{Mar}
+\def\xAprShort{Apr}
+\def\xMayShort{Maj}
+\def\xJunShort{Jun}
+\def\xJulShort{Jul}
+\def\xAugShort{Aug}
+\def\xSepShort{Sep}
+\def\xOctShort{Okt}
+\def\xNovShort{Nov}
+\def\xDecShort{Dec}
+
+\def\xMondayDayLetter{MÃ¥}
+\def\xTuesdayDayLetter{Ti}
+\def\xWednesdayDayLetter{On}
+\def\xThursdayDayLetter{To}
+\def\xFridayDayLetter{Fr}
+\def\xSaturdayDayLetter{Lö}
+\def\xSundayDayLetter{Sö}
+
diff --git a/macros/luatex/latex/wallcalendar/i18n/wallcalendar-thai.tex b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-thai.tex
new file mode 100644
index 0000000000..56297b7be7
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/i18n/wallcalendar-thai.tex
@@ -0,0 +1,36 @@
+% Thai
+
+\def\xJanuary{มà¸à¸£à¸²à¸„ม}
+\def\xFebruary{à¸à¸¸à¸¡à¸ à¸²à¸žà¸±à¸™à¸˜à¹Œ}
+\def\xMarch{มีนาคม}
+\def\xApril{เมษายน}
+\def\xMay{พฤษภาคม}
+\def\xJune{มิถุนายน}
+\def\xJuly{à¸à¸£à¸à¸Žà¸²à¸„ม}
+\def\xAugust{สิงหาคม}
+\def\xSeptember{à¸à¸±à¸™à¸¢à¸²à¸¢à¸™}
+\def\xOctober{ตุลาคม}
+\def\xNovember{พฤศจิà¸à¸²à¸¢à¸™}
+\def\xDecember{ธันวาคม}
+
+\def\xJanShort{มà¸à¸£}
+\def\xFebShort{à¸à¸¸à¸¡à¸ }
+\def\xMarShort{มีนา}
+\def\xAprShort{เมษ}
+\def\xMayShort{พฤษ}
+\def\xJunShort{มิถุน}
+\def\xJulShort{à¸à¸£à¸}
+\def\xAugShort{สิงห}
+\def\xSepShort{à¸à¸±à¸™à¸¢}
+\def\xOctShort{ตุลา}
+\def\xNovShort{พฤศ}
+\def\xDecShort{ธันว}
+
+\def\xMondayDayLetter{จ}
+\def\xTuesdayDayLetter{อ}
+\def\xWednesdayDayLetter{พ}
+\def\xThursdayDayLetter{พฤ}
+\def\xFridayDayLetter{ศ}
+\def\xSaturdayDayLetter{ส}
+\def\xSundayDayLetter{อา}
+
diff --git a/macros/luatex/latex/wallcalendar/wallcalendar-code.pdf b/macros/luatex/latex/wallcalendar/wallcalendar-code.pdf
new file mode 100644
index 0000000000..697036296a
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/wallcalendar-code.pdf
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/wallcalendar-csv.lua b/macros/luatex/latex/wallcalendar/wallcalendar-csv.lua
new file mode 100644
index 0000000000..64196c07da
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/wallcalendar-csv.lua
@@ -0,0 +1,557 @@
+--- Read a comma or tab (or other delimiter) separated file.
+-- This version of a CSV reader differs from others I've seen in that it
+--
+-- + handles embedded newlines in fields (if they're delimited with double
+-- quotes)
+-- + is line-ending agnostic
+-- + reads the file line-by-line, so it can potientially handle large
+-- files.
+--
+-- Of course, for such a simple format, CSV is horribly complicated, so it
+-- likely gets something wrong.
+
+-- (c) Copyright 2013-2014 Incremental IP Limited.
+-- (c) Copyright 2014 Kevin Martin
+-- Available under the MIT licence. See LICENSE for more information.
+
+local DEFAULT_BUFFER_BLOCK_SIZE = 1024 * 1024
+
+
+------------------------------------------------------------------------------
+
+local function trim_space(s)
+ return s:match("^%s*(.-)%s*$")
+end
+
+
+local function fix_quotes(s)
+ -- the sub(..., -2) is to strip the trailing quote
+ return string.sub(s:gsub('""', '"'), 1, -2)
+end
+
+
+------------------------------------------------------------------------------
+
+local column_map = {}
+column_map.__index = column_map
+
+
+local function normalise_string(s)
+ return (s:lower():gsub("[^%w%d]+", " "):gsub("^ *(.-) *$", "%1"))
+end
+
+
+--- Parse a list of columns.
+-- The main job here is normalising column names and dealing with columns
+-- for which we have more than one possible name in the header.
+function column_map:new(columns)
+ local name_map = {}
+ for n, v in pairs(columns) do
+ local names
+ local t
+ if type(v) == "table" then
+ t = { transform = v.transform, default = v.default }
+ if v.name then
+ names = { normalise_string(v.name) }
+ elseif v.names then
+ names = v.names
+ for i, n in ipairs(names) do names[i] = normalise_string(n) end
+ end
+ else
+ if type(v) == "function" then
+ t = { transform = v }
+ else
+ t = {}
+ if type(v) == "string" then
+ names = { normalise_string(v) }
+ end
+ end
+ end
+
+ if not names then
+ names = { (n:lower():gsub("[^%w%d]+", " ")) }
+ end
+
+ t.name = n
+ for _, n in ipairs(names) do
+ name_map[n:lower()] = t
+ end
+ end
+
+ return setmetatable({ name_map = name_map }, column_map)
+end
+
+
+--- Map "virtual" columns to file columns.
+-- Once we've read the header, work out which columns we're interested in and
+-- what to do with them. Mostly this is about checking we've got the columns
+-- we need and writing a nice complaint if we haven't.
+function column_map:read_header(header)
+ local index_map = {}
+
+ -- Match the columns in the file to the columns in the name map
+ local found = {}
+ local found_any
+ for i, word in ipairs(header) do
+ word = normalise_string(word)
+ local r = self.name_map[word]
+ if r then
+ index_map[i] = r
+ found[r.name] = true
+ found_any = true
+ end
+ end
+
+ if not found_any then return end
+
+ -- check we found all the columns we need
+ local not_found = {}
+ for name, r in pairs(self.name_map) do
+ if not found[r.name] then
+ local nf = not_found[r.name]
+ if nf then
+ nf[#nf+1] = name
+ else
+ not_found[r.name] = { name }
+ end
+ end
+ end
+ -- If any columns are missing, assemble an error message
+ if next(not_found) then
+ local problems = {}
+ for k, v in pairs(not_found) do
+ local missing
+ if #v == 1 then
+ missing = "'"..v[1].."'"
+ else
+ missing = v[1]
+ for i = 2, #v - 1 do
+ missing = missing..", '"..v[i].."'"
+ end
+ missing = missing.." or '"..v[#v].."'"
+ end
+ problems[#problems+1] = "Couldn't find a column named "..missing
+ end
+ error(table.concat(problems, "\n"), 0)
+ end
+
+ self.index_map = index_map
+ return true
+end
+
+
+function column_map:transform(value, index)
+ local field = self.index_map[index]
+ if field then
+ if field.transform then
+ local ok
+ ok, value = pcall(field.transform, value)
+ if not ok then
+ error(("Error reading field '%s': %s"):format(field.name, value), 0)
+ end
+ end
+ return value or field.default, field.name
+ end
+end
+
+
+------------------------------------------------------------------------------
+
+local file_buffer = {}
+file_buffer.__index = file_buffer
+
+function file_buffer:new(file, buffer_block_size)
+ return setmetatable({
+ file = file,
+ buffer_block_size = buffer_block_size or DEFAULT_BUFFER_BLOCK_SIZE,
+ buffer_start = 0,
+ buffer = "",
+ }, file_buffer)
+end
+
+
+--- Cut the front off the buffer if we've already read it
+function file_buffer:truncate(p)
+ p = p - self.buffer_start
+ if p > self.buffer_block_size then
+ local remove = self.buffer_block_size *
+ math.floor((p-1) / self.buffer_block_size)
+ self.buffer = self.buffer:sub(remove + 1)
+ self.buffer_start = self.buffer_start + remove
+ end
+end
+
+
+--- Find something in the buffer, extending it if necessary
+function file_buffer:find(pattern, init)
+ while true do
+ local first, last, capture =
+ self.buffer:find(pattern, init - self.buffer_start)
+ -- if we found nothing, or the last character is at the end of the
+ -- buffer (and the match could potentially be longer) then read some
+ -- more.
+ if not first or last == #self.buffer then
+ local s = self.file:read(self.buffer_block_size)
+ if not s then
+ if not first then
+ return
+ else
+ return first + self.buffer_start, last + self.buffer_start, capture
+ end
+ end
+ self.buffer = self.buffer..s
+ else
+ return first + self.buffer_start, last + self.buffer_start, capture
+ end
+ end
+end
+
+
+--- Extend the buffer so we can see more
+function file_buffer:extend(offset)
+ local extra = offset - #self.buffer - self.buffer_start
+ if extra > 0 then
+ local size = self.buffer_block_size *
+ math.ceil(extra / self.buffer_block_size)
+ local s = self.file:read(size)
+ if not s then return end
+ self.buffer = self.buffer..s
+ end
+end
+
+
+--- Get a substring from the buffer, extending it if necessary
+function file_buffer:sub(a, b)
+ self:extend(b)
+ b = b == -1 and b or b - self.buffer_start
+ return self.buffer:sub(a - self.buffer_start, b)
+end
+
+
+--- Close a file buffer
+function file_buffer:close()
+ self.file:close()
+ self.file = nil
+end
+
+
+------------------------------------------------------------------------------
+
+local separator_candidates = { ",", "\t", "|" }
+local guess_separator_params = { record_limit = 8; }
+
+
+local function try_separator(buffer, sep, f)
+ guess_separator_params.separator = sep
+ local min, max = math.huge, 0
+ local lines, split_lines = 0, 0
+ local iterator = coroutine.wrap(function() f(buffer, guess_separator_params) end)
+ for t in iterator do
+ min = math.min(min, #t)
+ max = math.max(max, #t)
+ split_lines = split_lines + (t[2] and 1 or 0)
+ lines = lines + 1
+ end
+ if split_lines / lines > 0.75 then
+ return max - min
+ else
+ return math.huge
+ end
+end
+
+
+--- If the user hasn't specified a separator, try to work out what it is.
+function guess_separator(buffer, f)
+ local best_separator, lowest_diff = "", math.huge
+ for _, s in ipairs(separator_candidates) do
+ local ok, diff = pcall(function() return try_separator(buffer, s, f) end)
+ if ok and diff < lowest_diff then
+ best_separator = s
+ lowest_diff = diff
+ end
+ end
+
+ return best_separator
+end
+
+
+local unicode_BOMS =
+{
+ {
+ length = 2,
+ BOMS =
+ {
+ ["\254\255"] = true, -- UTF-16 big-endian
+ ["\255\254"] = true, -- UTF-16 little-endian
+ }
+ },
+ {
+ length = 3,
+ BOMS =
+ {
+ ["\239\187\191"] = true, -- UTF-8
+ }
+ }
+}
+
+
+local function find_unicode_BOM(sub)
+ for _, x in ipairs(unicode_BOMS) do
+ local code = sub(1, x.length)
+ if x.BOMS[code] then
+ return x.length
+ end
+ end
+ return 0
+end
+
+
+--- Iterate through the records in a file
+-- Since records might be more than one line (if there's a newline in quotes)
+-- and line-endings might not be native, we read the file in chunks of
+-- we read the file in chunks using a file_buffer, rather than line-by-line
+-- using io.lines.
+local function separated_values_iterator(buffer, parameters)
+ local field_start = 1
+
+ local advance
+ if buffer.truncate then
+ advance = function(n)
+ field_start = field_start + n
+ buffer:truncate(field_start)
+ end
+ else
+ advance = function(n)
+ field_start = field_start + n
+ end
+ end
+
+
+ local function field_sub(a, b)
+ b = b == -1 and b or b + field_start - 1
+ return buffer:sub(a + field_start - 1, b)
+ end
+
+
+ local function field_find(pattern, init)
+ init = init or 1
+ local f, l, c = buffer:find(pattern, init + field_start - 1)
+ if not f then return end
+ return f - field_start + 1, l - field_start + 1, c
+ end
+
+
+ -- Is there some kind of Unicode BOM here?
+ advance(find_unicode_BOM(field_sub))
+
+
+ -- Start reading the file
+ local sep = "(["..(parameters.separator or
+ guess_separator(buffer, separated_values_iterator)).."\n\r])"
+ local line_start = 1
+ local line = 1
+ local field_count, fields, starts, nonblanks = 0, {}, {}
+ local header, header_read
+ local field_start_line, field_start_column
+ local record_count = 0
+
+
+ local function problem(message)
+ error(("%s:%d:%d: %s"):
+ format(parameters.filename, field_start_line, field_start_column,
+ message), 0)
+ end
+
+
+ while true do
+ local field_end, sep_end, this_sep
+ local tidy
+ field_start_line = line
+ field_start_column = field_start - line_start + 1
+
+ -- If the field is quoted, go find the other quote
+ if field_sub(1, 1) == '"' then
+ advance(1)
+ local current_pos = 0
+ repeat
+ local a, b, c = field_find('"("?)', current_pos + 1)
+ current_pos = b
+ until c ~= '"'
+ if not current_pos then problem("unmatched quote") end
+ tidy = fix_quotes
+ field_end, sep_end, this_sep = field_find(" *([^ ])", current_pos+1)
+ if this_sep and not this_sep:match(sep) then problem("unmatched quote") end
+ else
+ field_end, sep_end, this_sep = field_find(sep, 1)
+ tidy = trim_space
+ end
+
+ -- Look for the separator or a newline or the end of the file
+ field_end = (field_end or 0) - 1
+
+ -- Read the field, then convert all the line endings to \n, and
+ -- count any embedded line endings
+ local value = field_sub(1, field_end)
+ value = value:gsub("\r\n", "\n"):gsub("\r", "\n")
+ for nl in value:gmatch("\n()") do
+ line = line + 1
+ line_start = nl + field_start
+ end
+
+ value = tidy(value)
+ if #value > 0 then nonblanks = true end
+ field_count = field_count + 1
+
+ -- Insert the value into the table for this "line"
+ local key
+ if parameters.column_map and header_read then
+ local ok
+ ok, value, key = pcall(parameters.column_map.transform,
+ parameters.column_map, value, field_count)
+ if not ok then problem(value) end
+ elseif header then
+ key = header[field_count]
+ else
+ key = field_count
+ end
+ if key then
+ fields[key] = value
+ starts[key] = { line=field_start_line, column=field_start_column }
+ end
+
+ -- if we ended on a newline then yield the fields on this line.
+ if not this_sep or this_sep == "\r" or this_sep == "\n" then
+ if parameters.column_map and not header_read then
+ header_read = parameters.column_map:read_header(fields)
+ elseif parameters.header and not header_read then
+ if nonblanks or field_count > 1 then -- ignore blank lines
+ header = fields
+ header_read = true
+ end
+ else
+ if nonblanks or field_count > 1 then -- ignore blank lines
+ coroutine.yield(fields, starts)
+ record_count = record_count + 1
+ if parameters.record_limit and
+ record_count >= parameters.record_limit then
+ break
+ end
+ end
+ end
+ field_count, fields, starts, nonblanks = 0, {}, {}
+ end
+
+ -- If we *really* didn't find a separator then we're done.
+ if not sep_end then break end
+
+ -- If we ended on a newline then count it.
+ if this_sep == "\r" or this_sep == "\n" then
+ if this_sep == "\r" and field_sub(sep_end+1, sep_end+1) == "\n" then
+ sep_end = sep_end + 1
+ end
+ line = line + 1
+ line_start = field_start + sep_end
+ end
+
+ advance(sep_end)
+ end
+end
+
+
+------------------------------------------------------------------------------
+
+local buffer_mt =
+{
+ lines = function(t)
+ return coroutine.wrap(function()
+ separated_values_iterator(t.buffer, t.parameters)
+ end)
+ end,
+ close = function(t)
+ if t.buffer.close then t.buffer:close() end
+ end,
+ name = function(t)
+ return t.parameters.filename
+ end,
+}
+buffer_mt.__index = buffer_mt
+
+
+--- Use an existing file or buffer as a stream to read csv from.
+-- (A buffer is just something that looks like a string in that we can do
+-- `buffer:sub()` and `buffer:find()`)
+-- @return a file object
+local function use(
+ buffer, -- ?string|file|buffer: the buffer to read from. If it's:
+ -- - a string, read from that;
+ -- - a file, turn it into a file_buffer;
+ -- - nil, read from stdin
+ -- otherwise assume it's already a a buffer.
+ parameters) -- ?table: parameters controlling reading the file.
+ -- See README.md
+ parameters = parameters or {}
+ parameters.filename = parameters.filename or "<unknown>"
+ parameters.column_map = parameters.columns and
+ column_map:new(parameters.columns)
+
+ if not buffer then
+ buffer = file_buffer:new(io.stdin)
+ elseif io.type(buffer) == "file" then
+ buffer = file_buffer:new(buffer)
+ end
+
+ local f = { buffer = buffer, parameters = parameters }
+ return setmetatable(f, buffer_mt)
+end
+
+
+------------------------------------------------------------------------------
+
+--- Open a file for reading as a delimited file
+-- @return a file object
+local function open(
+ filename, -- string: name of the file to open
+ parameters) -- ?table: parameters controlling reading the file.
+ -- See README.md
+ local file, message = io.open(filename, "r")
+ if not file then return nil, message end
+
+ parameters = parameters or {}
+ parameters.filename = filename
+ return use(file_buffer:new(file), parameters)
+end
+
+
+------------------------------------------------------------------------------
+
+local function makename(s)
+ local t = {}
+ t[#t+1] = "<(String) "
+ t[#t+1] = (s:gmatch("[^\n]+")() or ""):sub(1,15)
+ if #t[#t] > 14 then t[#t+1] = "..." end
+ t[#t+1] = " >"
+ return table.concat(t)
+end
+
+
+--- Open a string for reading as a delimited file
+-- @return a file object
+local function openstring(
+ filecontents, -- string: The contents of the delimited file
+ parameters) -- ?table: parameters controlling reading the file.
+ -- See README.md
+
+ parameters = parameters or {}
+
+
+ parameters.filename = parameters.filename or makename(filecontents)
+ parameters.buffer_size = parameters.buffer_size or #filecontents
+ return use(filecontents, parameters)
+end
+
+
+------------------------------------------------------------------------------
+
+return { open = open, openstring = openstring, use = use }
+
+------------------------------------------------------------------------------
diff --git a/macros/luatex/latex/wallcalendar/wallcalendar-date.lua b/macros/luatex/latex/wallcalendar/wallcalendar-date.lua
new file mode 100644
index 0000000000..14aa47577f
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/wallcalendar-date.lua
@@ -0,0 +1,747 @@
+---------------------------------------------------------------------------------------
+-- Module for date and time calculations
+--
+-- Version 2.1.1
+-- Copyright (C) 2006, by Jas Latrix (jastejada@yahoo.com)
+-- Copyright (C) 2013-2014, by Thijs Schreijer
+-- Licensed under MIT, http://opensource.org/licenses/MIT
+
+--[[ CONSTANTS ]]--
+ local HOURPERDAY = 24
+ local MINPERHOUR = 60
+ local MINPERDAY = 1440 -- 24*60
+ local SECPERMIN = 60
+ local SECPERHOUR = 3600 -- 60*60
+ local SECPERDAY = 86400 -- 24*60*60
+ local TICKSPERSEC = 1000000
+ local TICKSPERDAY = 86400000000
+ local TICKSPERHOUR = 3600000000
+ local TICKSPERMIN = 60000000
+ local DAYNUM_MAX = 365242500 -- Sat Jan 01 1000000 00:00:00
+ local DAYNUM_MIN = -365242500 -- Mon Jan 01 1000000 BCE 00:00:00
+ local DAYNUM_DEF = 0 -- Mon Jan 01 0001 00:00:00
+ local _;
+--[[ LOCAL ARE FASTER ]]--
+ local type = type
+ local pairs = pairs
+ local error = error
+ local assert = assert
+ local tonumber = tonumber
+ local tostring = tostring
+ local string = string
+ local math = math
+ local os = os
+ local unpack = unpack or table.unpack
+ local pack = table.pack or function(...) return { n = select('#', ...), ... } end
+ local setmetatable = setmetatable
+ local getmetatable = getmetatable
+--[[ EXTRA FUNCTIONS ]]--
+ local fmt = string.format
+ local lwr = string.lower
+ local upr = string.upper
+ local rep = string.rep
+ local len = string.len
+ local sub = string.sub
+ local gsub = string.gsub
+ local gmatch = string.gmatch or string.gfind
+ local find = string.find
+ local ostime = os.time
+ local osdate = os.date
+ local floor = math.floor
+ local ceil = math.ceil
+ local abs = math.abs
+ -- removes the decimal part of a number
+ local function fix(n) n = tonumber(n) return n and ((n > 0 and floor or ceil)(n)) end
+ -- returns the modulo n % d;
+ local function mod(n,d) return n - d*floor(n/d) end
+ -- rounds a number;
+ local function round(n, d) d=d^10 return floor((n*d)+.5)/d end
+ -- rounds a number to whole;
+ local function whole(n)return floor(n+.5)end
+ -- is `str` in string list `tbl`, `ml` is the minimun len
+ local function inlist(str, tbl, ml, tn)
+ local sl = len(str)
+ if sl < (ml or 0) then return nil end
+ str = lwr(str)
+ for k, v in pairs(tbl) do
+ if str == lwr(sub(v, 1, sl)) then
+ if tn then tn[0] = k end
+ return k
+ end
+ end
+ end
+ local function fnil() end
+ local function fret(x)return x;end
+--[[ DATE FUNCTIONS ]]--
+ local DATE_EPOCH -- to be set later
+ local sl_weekdays = {
+ [0]="Sunday",[1]="Monday",[2]="Tuesday",[3]="Wednesday",[4]="Thursday",[5]="Friday",[6]="Saturday",
+ [7]="Sun",[8]="Mon",[9]="Tue",[10]="Wed",[11]="Thu",[12]="Fri",[13]="Sat",
+ }
+ local sl_meridian = {[-1]="AM", [1]="PM"}
+ local sl_months = {
+ [00]="January", [01]="February", [02]="March",
+ [03]="April", [04]="May", [05]="June",
+ [06]="July", [07]="August", [08]="September",
+ [09]="October", [10]="November", [11]="December",
+ [12]="Jan", [13]="Feb", [14]="Mar",
+ [15]="Apr", [16]="May", [17]="Jun",
+ [18]="Jul", [19]="Aug", [20]="Sep",
+ [21]="Oct", [22]="Nov", [23]="Dec",
+ }
+ -- added the '.2' to avoid collision, use `fix` to remove
+ local sl_timezone = {
+ [000]="utc", [0.2]="gmt",
+ [300]="est", [240]="edt",
+ [360]="cst", [300.2]="cdt",
+ [420]="mst", [360.2]="mdt",
+ [480]="pst", [420.2]="pdt",
+ }
+ -- set the day fraction resolution
+ local function setticks(t)
+ TICKSPERSEC = t;
+ TICKSPERDAY = SECPERDAY*TICKSPERSEC
+ TICKSPERHOUR= SECPERHOUR*TICKSPERSEC
+ TICKSPERMIN = SECPERMIN*TICKSPERSEC
+ end
+ -- is year y leap year?
+ local function isleapyear(y) -- y must be int!
+ return (mod(y, 4) == 0 and (mod(y, 100) ~= 0 or mod(y, 400) == 0))
+ end
+ -- day since year 0
+ local function dayfromyear(y) -- y must be int!
+ return 365*y + floor(y/4) - floor(y/100) + floor(y/400)
+ end
+ -- day number from date, month is zero base
+ local function makedaynum(y, m, d)
+ local mm = mod(mod(m,12) + 10, 12)
+ return dayfromyear(y + floor(m/12) - floor(mm/10)) + floor((mm*306 + 5)/10) + d - 307
+ --local yy = y + floor(m/12) - floor(mm/10)
+ --return dayfromyear(yy) + floor((mm*306 + 5)/10) + (d - 1)
+ end
+ -- date from day number, month is zero base
+ local function breakdaynum(g)
+ local g = g + 306
+ local y = floor((10000*g + 14780)/3652425)
+ local d = g - dayfromyear(y)
+ if d < 0 then y = y - 1; d = g - dayfromyear(y) end
+ local mi = floor((100*d + 52)/3060)
+ return (floor((mi + 2)/12) + y), mod(mi + 2,12), (d - floor((mi*306 + 5)/10) + 1)
+ end
+ --[[ for floats or int32 Lua Number data type
+ local function breakdaynum2(g)
+ local g, n = g + 306;
+ local n400 = floor(g/DI400Y);n = mod(g,DI400Y);
+ local n100 = floor(n/DI100Y);n = mod(n,DI100Y);
+ local n004 = floor(n/DI4Y); n = mod(n,DI4Y);
+ local n001 = floor(n/365); n = mod(n,365);
+ local y = (n400*400) + (n100*100) + (n004*4) + n001 - ((n001 == 4 or n100 == 4) and 1 or 0)
+ local d = g - dayfromyear(y)
+ local mi = floor((100*d + 52)/3060)
+ return (floor((mi + 2)/12) + y), mod(mi + 2,12), (d - floor((mi*306 + 5)/10) + 1)
+ end
+ ]]
+ -- day fraction from time
+ local function makedayfrc(h,r,s,t)
+ return ((h*60 + r)*60 + s)*TICKSPERSEC + t
+ end
+ -- time from day fraction
+ local function breakdayfrc(df)
+ return
+ mod(floor(df/TICKSPERHOUR),HOURPERDAY),
+ mod(floor(df/TICKSPERMIN ),MINPERHOUR),
+ mod(floor(df/TICKSPERSEC ),SECPERMIN),
+ mod(df,TICKSPERSEC)
+ end
+ -- weekday sunday = 0, monday = 1 ...
+ local function weekday(dn) return mod(dn + 1, 7) end
+ -- yearday 0 based ...
+ local function yearday(dn)
+ return dn - dayfromyear((breakdaynum(dn))-1)
+ end
+ -- parse v as a month
+ local function getmontharg(v)
+ local m = tonumber(v);
+ return (m and fix(m - 1)) or inlist(tostring(v) or "", sl_months, 2)
+ end
+ -- get daynum of isoweek one of year y
+ local function isow1(y)
+ local f = makedaynum(y, 0, 4) -- get the date for the 4-Jan of year `y`
+ local d = weekday(f)
+ d = d == 0 and 7 or d -- get the ISO day number, 1 == Monday, 7 == Sunday
+ return f + (1 - d)
+ end
+ local function isowy(dn)
+ local w1;
+ local y = (breakdaynum(dn))
+ if dn >= makedaynum(y, 11, 29) then
+ w1 = isow1(y + 1);
+ if dn < w1 then
+ w1 = isow1(y);
+ else
+ y = y + 1;
+ end
+ else
+ w1 = isow1(y);
+ if dn < w1 then
+ w1 = isow1(y-1)
+ y = y - 1
+ end
+ end
+ return floor((dn-w1)/7)+1, y
+ end
+ local function isoy(dn)
+ local y = (breakdaynum(dn))
+ return y + (((dn >= makedaynum(y, 11, 29)) and (dn >= isow1(y + 1))) and 1 or (dn < isow1(y) and -1 or 0))
+ end
+ local function makedaynum_isoywd(y,w,d)
+ return isow1(y) + 7*w + d - 8 -- simplified: isow1(y) + ((w-1)*7) + (d-1)
+ end
+--[[ THE DATE MODULE ]]--
+ local fmtstr = "%x %X";
+--#if not DATE_OBJECT_AFX then
+ local date = {}
+ setmetatable(date, date)
+-- Version: VMMMRRRR; V-Major, M-Minor, R-Revision; e.g. 5.45.321 == 50450321
+ date.version = 20010001 -- 2.1.1
+--#end -- not DATE_OBJECT_AFX
+--[[ THE DATE OBJECT ]]--
+ local dobj = {}
+ dobj.__index = dobj
+ dobj.__metatable = dobj
+ -- shout invalid arg
+ local function date_error_arg() return error("invalid argument(s)",0) end
+ -- create new date object
+ local function date_new(dn, df)
+ return setmetatable({daynum=dn, dayfrc=df}, dobj)
+ end
+ -- is `v` a date object?
+ local function date_isdobj(v)
+ return (type(v) == 'table' and getmetatable(v) == dobj) and v
+ end
+
+--#if not NO_LOCAL_TIME_SUPPORT then
+ -- magic year table
+ local date_epoch, yt;
+ local function getequivyear(y)
+ assert(not yt)
+ yt = {}
+ local de, dw, dy = date_epoch:copy()
+ for i = 0, 3000 do
+ de:setyear(de:getyear() + 1, 1, 1)
+ dy = de:getyear()
+ dw = de:getweekday() * (isleapyear(dy) and -1 or 1)
+ if not yt[dw] then yt[dw] = dy end --print(de)
+ if yt[1] and yt[2] and yt[3] and yt[4] and yt[5] and yt[6] and yt[7] and yt[-1] and yt[-2] and yt[-3] and yt[-4] and yt[-5] and yt[-6] and yt[-7] then
+ getequivyear = function(y) return yt[ (weekday(makedaynum(y, 0, 1)) + 1) * (isleapyear(y) and -1 or 1) ] end
+ return getequivyear(y)
+ end
+ end
+ end
+ -- TimeValue from daynum and dayfrc
+ local function dvtotv(dn, df)
+ return fix(dn - DATE_EPOCH) * SECPERDAY + (df/1000)
+ end
+ -- TimeValue from date and time
+ local function totv(y,m,d,h,r,s)
+ return (makedaynum(y, m, d) - DATE_EPOCH) * SECPERDAY + ((h*60 + r)*60 + s)
+ end
+ -- TimeValue from TimeTable
+ local function tmtotv(tm)
+ return tm and totv(tm.year, tm.month - 1, tm.day, tm.hour, tm.min, tm.sec)
+ end
+ -- Returns the bias in seconds of utc time daynum and dayfrc
+ local function getbiasutc2(self)
+ local y,m,d = breakdaynum(self.daynum)
+ local h,r,s = breakdayfrc(self.dayfrc)
+ local tvu = totv(y,m,d,h,r,s) -- get the utc TimeValue of date and time
+ local tml = osdate("*t", tvu) -- get the local TimeTable of tvu
+ if (not tml) or (tml.year > (y+1) or tml.year < (y-1)) then -- failed try the magic
+ y = getequivyear(y)
+ tvu = totv(y,m,d,h,r,s)
+ tml = osdate("*t", tvu)
+ end
+ local tvl = tmtotv(tml)
+ if tvu and tvl then
+ return tvu - tvl, tvu, tvl
+ else
+ return error("failed to get bias from utc time")
+ end
+ end
+ -- Returns the bias in seconds of local time daynum and dayfrc
+ local function getbiasloc2(daynum, dayfrc)
+ local tvu
+ -- extract date and time
+ local y,m,d = breakdaynum(daynum)
+ local h,r,s = breakdayfrc(dayfrc)
+ -- get equivalent TimeTable
+ local tml = {year=y, month=m+1, day=d, hour=h, min=r, sec=s}
+ -- get equivalent TimeValue
+ local tvl = tmtotv(tml)
+
+ local function chkutc()
+ tml.isdst = nil; local tvug = ostime(tml) if tvug and (tvl == tmtotv(osdate("*t", tvug))) then tvu = tvug return end
+ tml.isdst = true; local tvud = ostime(tml) if tvud and (tvl == tmtotv(osdate("*t", tvud))) then tvu = tvud return end
+ tvu = tvud or tvug
+ end
+ chkutc()
+ if not tvu then
+ tml.year = getequivyear(y)
+ tvl = tmtotv(tml)
+ chkutc()
+ end
+ return ((tvu and tvl) and (tvu - tvl)) or error("failed to get bias from local time"), tvu, tvl
+ end
+--#end -- not NO_LOCAL_TIME_SUPPORT
+
+--#if not DATE_OBJECT_AFX then
+ -- the date parser
+ local strwalker = {} -- ^Lua regular expression is not as powerful as Perl$
+ strwalker.__index = strwalker
+ local function newstrwalker(s)return setmetatable({s=s, i=1, e=1, c=len(s)}, strwalker) end
+ function strwalker:aimchr() return "\n" .. self.s .. "\n" .. rep(".",self.e-1) .. "^" end
+ function strwalker:finish() return self.i > self.c end
+ function strwalker:back() self.i = self.e return self end
+ function strwalker:restart() self.i, self.e = 1, 1 return self end
+ function strwalker:match(s) return (find(self.s, s, self.i)) end
+ function strwalker:__call(s, f)-- print("strwalker:__call "..s..self:aimchr())
+ local is, ie; is, ie, self[1], self[2], self[3], self[4], self[5] = find(self.s, s, self.i)
+ if is then self.e, self.i = self.i, 1+ie; if f then f(unpack(self)) end return self end
+ end
+ local function date_parse(str)
+ local y,m,d, h,r,s, z, w,u, j, e, k, x,v,c, chkfin, dn,df;
+ local sw = newstrwalker(gsub(gsub(str, "(%b())", ""),"^(%s*)","")) -- remove comment, trim leading space
+ --local function error_out() print(y,m,d,h,r,s) end
+ local function error_dup(q) --[[error_out()]] error("duplicate value: " .. (q or "") .. sw:aimchr()) end
+ local function error_syn(q) --[[error_out()]] error("syntax error: " .. (q or "") .. sw:aimchr()) end
+ local function error_inv(q) --[[error_out()]] error("invalid date: " .. (q or "") .. sw:aimchr()) end
+ local function sety(q) y = y and error_dup() or tonumber(q); end
+ local function setm(q) m = (m or w or j) and error_dup(m or w or j) or tonumber(q) end
+ local function setd(q) d = d and error_dup() or tonumber(q) end
+ local function seth(q) h = h and error_dup() or tonumber(q) end
+ local function setr(q) r = r and error_dup() or tonumber(q) end
+ local function sets(q) s = s and error_dup() or tonumber(q) end
+ local function adds(q) s = s + tonumber(q) end
+ local function setj(q) j = (m or w or j) and error_dup() or tonumber(q); end
+ local function setz(q) z = (z ~= 0 and z) and error_dup() or q end
+ local function setzn(zs,zn) zn = tonumber(zn); setz( ((zn<24) and (zn*60) or (mod(zn,100) + floor(zn/100) * 60))*( zs=='+' and -1 or 1) ) end
+ local function setzc(zs,zh,zm) setz( ((tonumber(zh)*60) + tonumber(zm))*( zs=='+' and -1 or 1) ) end
+
+ if not (sw("^(%d%d%d%d)",sety) and (sw("^(%-?)(%d%d)%1(%d%d)",function(_,a,b) setm(tonumber(a)); setd(tonumber(b)) end) or sw("^(%-?)[Ww](%d%d)%1(%d?)",function(_,a,b) w, u = tonumber(a), tonumber(b or 1) end) or sw("^%-?(%d%d%d)",setj) or sw("^%-?(%d%d)",function(a) setm(a);setd(1) end))
+ and ((sw("^%s*[Tt]?(%d%d):?",seth) and sw("^(%d%d):?",setr) and sw("^(%d%d)",sets) and sw("^(%.%d+)",adds))
+ or sw:finish() or (sw"^%s*$" or sw"^%s*[Zz]%s*$" or sw("^%s-([%+%-])(%d%d):?(%d%d)%s*$",setzc) or sw("^%s*([%+%-])(%d%d)%s*$",setzn))
+ ) )
+ then --print(y,m,d,h,r,s,z,w,u,j)
+ sw:restart(); y,m,d,h,r,s,z,w,u,j = nil;
+ repeat -- print(sw:aimchr())
+ if sw("^[tT:]?%s*(%d%d?):",seth) then --print("$Time")
+ _ = sw("^%s*(%d%d?)",setr) and sw("^%s*:%s*(%d%d?)",sets) and sw("^(%.%d+)",adds)
+ elseif sw("^(%d+)[/\\%s,-]?%s*") then --print("$Digits")
+ x, c = tonumber(sw[1]), len(sw[1])
+ if (x >= 70) or (m and d and (not y)) or (c > 3) then
+ sety( x + ((x >= 100 or c>3)and 0 or 1900) )
+ else
+ if m then setd(x) else m = x end
+ end
+ elseif sw("^(%a+)[/\\%s,-]?%s*") then --print("$Words")
+ x = sw[1]
+ if inlist(x, sl_months, 2, sw) then
+ if m and (not d) and (not y) then d, m = m, false end
+ setm(mod(sw[0],12)+1)
+ elseif inlist(x, sl_timezone, 2, sw) then
+ c = fix(sw[0]) -- ignore gmt and utc
+ if c ~= 0 then setz(c, x) end
+ elseif inlist(x, sl_weekdays, 2, sw) then
+ k = sw[0]
+ else
+ sw:back()
+ -- am pm bce ad ce bc
+ if sw("^([bB])%s*(%.?)%s*[Cc]%s*(%2)%s*[Ee]%s*(%2)%s*") or sw("^([bB])%s*(%.?)%s*[Cc]%s*(%2)%s*") then
+ e = e and error_dup() or -1
+ elseif sw("^([aA])%s*(%.?)%s*[Dd]%s*(%2)%s*") or sw("^([cC])%s*(%.?)%s*[Ee]%s*(%2)%s*") then
+ e = e and error_dup() or 1
+ elseif sw("^([PApa])%s*(%.?)%s*[Mm]?%s*(%2)%s*") then
+ x = lwr(sw[1]) -- there should be hour and it must be correct
+ if (not h) or (h > 12) or (h < 0) then return error_inv() end
+ if x == 'a' and h == 12 then h = 0 end -- am
+ if x == 'p' and h ~= 12 then h = h + 12 end -- pm
+ else error_syn() end
+ end
+ elseif not(sw("^([+-])(%d%d?):(%d%d)",setzc) or sw("^([+-])(%d+)",setzn) or sw("^[Zz]%s*$")) then -- sw{"([+-])",{"(%d%d?):(%d%d)","(%d+)"}}
+ error_syn("?")
+ end
+ sw("^%s*") until sw:finish()
+ --else print("$Iso(Date|Time|Zone)")
+ end
+ -- if date is given, it must be complete year, month & day
+ if (not y and not h) or ((m and not d) or (d and not m)) or ((m and w) or (m and j) or (j and w)) then return error_inv("!") end
+ -- fix month
+ if m then m = m - 1 end
+ -- fix year if we are on BCE
+ if e and e < 0 and y > 0 then y = 1 - y end
+ -- create date object
+ dn = (y and ((w and makedaynum_isoywd(y,w,u)) or (j and makedaynum(y, 0, j)) or makedaynum(y, m, d))) or DAYNUM_DEF
+ df = makedayfrc(h or 0, r or 0, s or 0, 0) + ((z or 0)*TICKSPERMIN)
+ --print("Zone",h,r,s,z,m,d,y,df)
+ return date_new(dn, df) -- no need to :normalize();
+ end
+ local function date_fromtable(v)
+ local y, m, d = fix(v.year), getmontharg(v.month), fix(v.day)
+ local h, r, s, t = tonumber(v.hour), tonumber(v.min), tonumber(v.sec), tonumber(v.ticks)
+ -- atleast there is time or complete date
+ if (y or m or d) and (not(y and m and d)) then return error("incomplete table") end
+ return (y or h or r or s or t) and date_new(y and makedaynum(y, m, d) or DAYNUM_DEF, makedayfrc(h or 0, r or 0, s or 0, t or 0))
+ end
+ local tmap = {
+ ['number'] = function(v) return date_epoch:copy():addseconds(v) end,
+ ['string'] = function(v) return date_parse(v) end,
+ ['boolean']= function(v) return date_fromtable(osdate(v and "!*t" or "*t")) end,
+ ['table'] = function(v) local ref = getmetatable(v) == dobj; return ref and v or date_fromtable(v), ref end
+ }
+ local function date_getdobj(v)
+ local o, r = (tmap[type(v)] or fnil)(v);
+ return (o and o:normalize() or error"invalid date time value"), r -- if r is true then o is a reference to a date obj
+ end
+--#end -- not DATE_OBJECT_AFX
+ local function date_from(...)
+ local arg = pack(...)
+ local y, m, d = fix(arg[1]), getmontharg(arg[2]), fix(arg[3])
+ local h, r, s, t = tonumber(arg[4] or 0), tonumber(arg[5] or 0), tonumber(arg[6] or 0), tonumber(arg[7] or 0)
+ if y and m and d and h and r and s and t then
+ return date_new(makedaynum(y, m, d), makedayfrc(h, r, s, t)):normalize()
+ else
+ return date_error_arg()
+ end
+ end
+
+ --[[ THE DATE OBJECT METHODS ]]--
+ function dobj:normalize()
+ local dn, df = fix(self.daynum), self.dayfrc
+ self.daynum, self.dayfrc = dn + floor(df/TICKSPERDAY), mod(df, TICKSPERDAY)
+ return (dn >= DAYNUM_MIN and dn <= DAYNUM_MAX) and self or error("date beyond imposed limits:"..self)
+ end
+
+ function dobj:getdate() local y, m, d = breakdaynum(self.daynum) return y, m+1, d end
+ function dobj:gettime() return breakdayfrc(self.dayfrc) end
+
+ function dobj:getclockhour() local h = self:gethours() return h>12 and mod(h,12) or (h==0 and 12 or h) end
+
+ function dobj:getyearday() return yearday(self.daynum) + 1 end
+ function dobj:getweekday() return weekday(self.daynum) + 1 end -- in lua weekday is sunday = 1, monday = 2 ...
+
+ function dobj:getyear() local r,_,_ = breakdaynum(self.daynum) return r end
+ function dobj:getmonth() local _,r,_ = breakdaynum(self.daynum) return r+1 end-- in lua month is 1 base
+ function dobj:getday() local _,_,r = breakdaynum(self.daynum) return r end
+ function dobj:gethours() return mod(floor(self.dayfrc/TICKSPERHOUR),HOURPERDAY) end
+ function dobj:getminutes() return mod(floor(self.dayfrc/TICKSPERMIN), MINPERHOUR) end
+ function dobj:getseconds() return mod(floor(self.dayfrc/TICKSPERSEC ),SECPERMIN) end
+ function dobj:getfracsec() return mod(floor(self.dayfrc/TICKSPERSEC ),SECPERMIN)+(mod(self.dayfrc,TICKSPERSEC)/TICKSPERSEC) end
+ function dobj:getticks(u) local x = mod(self.dayfrc,TICKSPERSEC) return u and ((x*u)/TICKSPERSEC) or x end
+
+ function dobj:getweeknumber(wdb)
+ local wd, yd = weekday(self.daynum), yearday(self.daynum)
+ if wdb then
+ wdb = tonumber(wdb)
+ if wdb then
+ wd = mod(wd-(wdb-1),7)-- shift the week day base
+ else
+ return date_error_arg()
+ end
+ end
+ return (yd < wd and 0) or (floor(yd/7) + ((mod(yd, 7)>=wd) and 1 or 0))
+ end
+
+ function dobj:getisoweekday() return mod(weekday(self.daynum)-1,7)+1 end -- sunday = 7, monday = 1 ...
+ function dobj:getisoweeknumber() return (isowy(self.daynum)) end
+ function dobj:getisoyear() return isoy(self.daynum) end
+ function dobj:getisodate()
+ local w, y = isowy(self.daynum)
+ return y, w, self:getisoweekday()
+ end
+ function dobj:setisoyear(y, w, d)
+ local cy, cw, cd = self:getisodate()
+ if y then cy = fix(tonumber(y))end
+ if w then cw = fix(tonumber(w))end
+ if d then cd = fix(tonumber(d))end
+ if cy and cw and cd then
+ self.daynum = makedaynum_isoywd(cy, cw, cd)
+ return self:normalize()
+ else
+ return date_error_arg()
+ end
+ end
+
+ function dobj:setisoweekday(d) return self:setisoyear(nil, nil, d) end
+ function dobj:setisoweeknumber(w,d) return self:setisoyear(nil, w, d) end
+
+ function dobj:setyear(y, m, d)
+ local cy, cm, cd = breakdaynum(self.daynum)
+ if y then cy = fix(tonumber(y))end
+ if m then cm = getmontharg(m) end
+ if d then cd = fix(tonumber(d))end
+ if cy and cm and cd then
+ self.daynum = makedaynum(cy, cm, cd)
+ return self:normalize()
+ else
+ return date_error_arg()
+ end
+ end
+
+ function dobj:setmonth(m, d)return self:setyear(nil, m, d) end
+ function dobj:setday(d) return self:setyear(nil, nil, d) end
+
+ function dobj:sethours(h, m, s, t)
+ local ch,cm,cs,ck = breakdayfrc(self.dayfrc)
+ ch, cm, cs, ck = tonumber(h or ch), tonumber(m or cm), tonumber(s or cs), tonumber(t or ck)
+ if ch and cm and cs and ck then
+ self.dayfrc = makedayfrc(ch, cm, cs, ck)
+ return self:normalize()
+ else
+ return date_error_arg()
+ end
+ end
+
+ function dobj:setminutes(m,s,t) return self:sethours(nil, m, s, t) end
+ function dobj:setseconds(s, t) return self:sethours(nil, nil, s, t) end
+ function dobj:setticks(t) return self:sethours(nil, nil, nil, t) end
+
+ function dobj:spanticks() return (self.daynum*TICKSPERDAY + self.dayfrc) end
+ function dobj:spanseconds() return (self.daynum*TICKSPERDAY + self.dayfrc)/TICKSPERSEC end
+ function dobj:spanminutes() return (self.daynum*TICKSPERDAY + self.dayfrc)/TICKSPERMIN end
+ function dobj:spanhours() return (self.daynum*TICKSPERDAY + self.dayfrc)/TICKSPERHOUR end
+ function dobj:spandays() return (self.daynum*TICKSPERDAY + self.dayfrc)/TICKSPERDAY end
+
+ function dobj:addyears(y, m, d)
+ local cy, cm, cd = breakdaynum(self.daynum)
+ if y then y = fix(tonumber(y))else y = 0 end
+ if m then m = fix(tonumber(m))else m = 0 end
+ if d then d = fix(tonumber(d))else d = 0 end
+ if y and m and d then
+ self.daynum = makedaynum(cy+y, cm+m, cd+d)
+ return self:normalize()
+ else
+ return date_error_arg()
+ end
+ end
+
+ function dobj:addmonths(m, d)
+ return self:addyears(nil, m, d)
+ end
+
+ local function dobj_adddayfrc(self,n,pt,pd)
+ n = tonumber(n)
+ if n then
+ local x = floor(n/pd);
+ self.daynum = self.daynum + x;
+ self.dayfrc = self.dayfrc + (n-x*pd)*pt;
+ return self:normalize()
+ else
+ return date_error_arg()
+ end
+ end
+ function dobj:adddays(n) return dobj_adddayfrc(self,n,TICKSPERDAY,1) end
+ function dobj:addhours(n) return dobj_adddayfrc(self,n,TICKSPERHOUR,HOURPERDAY) end
+ function dobj:addminutes(n) return dobj_adddayfrc(self,n,TICKSPERMIN,MINPERDAY) end
+ function dobj:addseconds(n) return dobj_adddayfrc(self,n,TICKSPERSEC,SECPERDAY) end
+ function dobj:addticks(n) return dobj_adddayfrc(self,n,1,TICKSPERDAY) end
+ local tvspec = {
+ -- Abbreviated weekday name (Sun)
+ ['%a']=function(self) return sl_weekdays[weekday(self.daynum) + 7] end,
+ -- Full weekday name (Sunday)
+ ['%A']=function(self) return sl_weekdays[weekday(self.daynum)] end,
+ -- Abbreviated month name (Dec)
+ ['%b']=function(self) return sl_months[self:getmonth() - 1 + 12] end,
+ -- Full month name (December)
+ ['%B']=function(self) return sl_months[self:getmonth() - 1] end,
+ -- Year/100 (19, 20, 30)
+ ['%C']=function(self) return fmt("%.2d", fix(self:getyear()/100)) end,
+ -- The day of the month as a number (range 1 - 31)
+ ['%d']=function(self) return fmt("%.2d", self:getday()) end,
+ -- year for ISO 8601 week, from 00 (79)
+ ['%g']=function(self) return fmt("%.2d", mod(self:getisoyear() ,100)) end,
+ -- year for ISO 8601 week, from 0000 (1979)
+ ['%G']=function(self) return fmt("%.4d", self:getisoyear()) end,
+ -- same as %b
+ ['%h']=function(self) return self:fmt0("%b") end,
+ -- hour of the 24-hour day, from 00 (06)
+ ['%H']=function(self) return fmt("%.2d", self:gethours()) end,
+ -- The hour as a number using a 12-hour clock (01 - 12)
+ ['%I']=function(self) return fmt("%.2d", self:getclockhour()) end,
+ -- The day of the year as a number (001 - 366)
+ ['%j']=function(self) return fmt("%.3d", self:getyearday()) end,
+ -- Month of the year, from 01 to 12
+ ['%m']=function(self) return fmt("%.2d", self:getmonth()) end,
+ -- Minutes after the hour 55
+ ['%M']=function(self) return fmt("%.2d", self:getminutes())end,
+ -- AM/PM indicator (AM)
+ ['%p']=function(self) return sl_meridian[self:gethours() > 11 and 1 or -1] end, --AM/PM indicator (AM)
+ -- The second as a number (59, 20 , 01)
+ ['%S']=function(self) return fmt("%.2d", self:getseconds()) end,
+ -- ISO 8601 day of the week, to 7 for Sunday (7, 1)
+ ['%u']=function(self) return self:getisoweekday() end,
+ -- Sunday week of the year, from 00 (48)
+ ['%U']=function(self) return fmt("%.2d", self:getweeknumber()) end,
+ -- ISO 8601 week of the year, from 01 (48)
+ ['%V']=function(self) return fmt("%.2d", self:getisoweeknumber()) end,
+ -- The day of the week as a decimal, Sunday being 0
+ ['%w']=function(self) return self:getweekday() - 1 end,
+ -- Monday week of the year, from 00 (48)
+ ['%W']=function(self) return fmt("%.2d", self:getweeknumber(2)) end,
+ -- The year as a number without a century (range 00 to 99)
+ ['%y']=function(self) return fmt("%.2d", mod(self:getyear() ,100)) end,
+ -- Year with century (2000, 1914, 0325, 0001)
+ ['%Y']=function(self) return fmt("%.4d", self:getyear()) end,
+ -- Time zone offset, the date object is assumed local time (+1000, -0230)
+ ['%z']=function(self) local b = -self:getbias(); local x = abs(b); return fmt("%s%.4d", b < 0 and "-" or "+", fix(x/60)*100 + floor(mod(x,60))) end,
+ -- Time zone name, the date object is assumed local time
+ ['%Z']=function(self) return self:gettzname() end,
+ -- Misc --
+ -- Year, if year is in BCE, prints the BCE Year representation, otherwise result is similar to "%Y" (1 BCE, 40 BCE)
+ ['%\b']=function(self) local x = self:getyear() return fmt("%.4d%s", x>0 and x or (-x+1), x>0 and "" or " BCE") end,
+ -- Seconds including fraction (59.998, 01.123)
+ ['%\f']=function(self) local x = self:getfracsec() return fmt("%s%.9f",x >= 10 and "" or "0", x) end,
+ -- percent character %
+ ['%%']=function(self) return "%" end,
+ -- Group Spec --
+ -- 12-hour time, from 01:00:00 AM (06:55:15 AM); same as "%I:%M:%S %p"
+ ['%r']=function(self) return self:fmt0("%I:%M:%S %p") end,
+ -- hour:minute, from 01:00 (06:55); same as "%I:%M"
+ ['%R']=function(self) return self:fmt0("%I:%M") end,
+ -- 24-hour time, from 00:00:00 (06:55:15); same as "%H:%M:%S"
+ ['%T']=function(self) return self:fmt0("%H:%M:%S") end,
+ -- month/day/year from 01/01/00 (12/02/79); same as "%m/%d/%y"
+ ['%D']=function(self) return self:fmt0("%m/%d/%y") end,
+ -- year-month-day (1979-12-02); same as "%Y-%m-%d"
+ ['%F']=function(self) return self:fmt0("%Y-%m-%d") end,
+ -- The preferred date and time representation; same as "%x %X"
+ ['%c']=function(self) return self:fmt0("%x %X") end,
+ -- The preferred date representation, same as "%a %b %d %\b"
+ ['%x']=function(self) return self:fmt0("%a %b %d %\b") end,
+ -- The preferred time representation, same as "%H:%M:%\f"
+ ['%X']=function(self) return self:fmt0("%H:%M:%\f") end,
+ -- GroupSpec --
+ -- Iso format, same as "%Y-%m-%dT%T"
+ ['${iso}'] = function(self) return self:fmt0("%Y-%m-%dT%T") end,
+ -- http format, same as "%a, %d %b %Y %T GMT"
+ ['${http}'] = function(self) return self:fmt0("%a, %d %b %Y %T GMT") end,
+ -- ctime format, same as "%a %b %d %T GMT %Y"
+ ['${ctime}'] = function(self) return self:fmt0("%a %b %d %T GMT %Y") end,
+ -- RFC850 format, same as "%A, %d-%b-%y %T GMT"
+ ['${rfc850}'] = function(self) return self:fmt0("%A, %d-%b-%y %T GMT") end,
+ -- RFC1123 format, same as "%a, %d %b %Y %T GMT"
+ ['${rfc1123}'] = function(self) return self:fmt0("%a, %d %b %Y %T GMT") end,
+ -- asctime format, same as "%a %b %d %T %Y"
+ ['${asctime}'] = function(self) return self:fmt0("%a %b %d %T %Y") end,
+ }
+ function dobj:fmt0(str) return (gsub(str, "%%[%a%%\b\f]", function(x) local f = tvspec[x];return (f and f(self)) or x end)) end
+ function dobj:fmt(str)
+ str = str or self.fmtstr or fmtstr
+ return self:fmt0((gmatch(str, "${%w+}")) and (gsub(str, "${%w+}", function(x)local f=tvspec[x];return (f and f(self)) or x end)) or str)
+ end
+
+ function dobj.__lt(a, b) if (a.daynum == b.daynum) then return (a.dayfrc < b.dayfrc) else return (a.daynum < b.daynum) end end
+ function dobj.__le(a, b) if (a.daynum == b.daynum) then return (a.dayfrc <= b.dayfrc) else return (a.daynum <= b.daynum) end end
+ function dobj.__eq(a, b)return (a.daynum == b.daynum) and (a.dayfrc == b.dayfrc) end
+ function dobj.__sub(a,b)
+ local d1, d2 = date_getdobj(a), date_getdobj(b)
+ local d0 = d1 and d2 and date_new(d1.daynum - d2.daynum, d1.dayfrc - d2.dayfrc)
+ return d0 and d0:normalize()
+ end
+ function dobj.__add(a,b)
+ local d1, d2 = date_getdobj(a), date_getdobj(b)
+ local d0 = d1 and d2 and date_new(d1.daynum + d2.daynum, d1.dayfrc + d2.dayfrc)
+ return d0 and d0:normalize()
+ end
+ function dobj.__concat(a, b) return tostring(a) .. tostring(b) end
+ function dobj:__tostring() return self:fmt() end
+
+ function dobj:copy() return date_new(self.daynum, self.dayfrc) end
+
+--[[ THE LOCAL DATE OBJECT METHODS ]]--
+ function dobj:tolocal()
+ local dn,df = self.daynum, self.dayfrc
+ local bias = getbiasutc2(self)
+ if bias then
+ -- utc = local + bias; local = utc - bias
+ self.daynum = dn
+ self.dayfrc = df - bias*TICKSPERSEC
+ return self:normalize()
+ else
+ return nil
+ end
+ end
+
+ function dobj:toutc()
+ local dn,df = self.daynum, self.dayfrc
+ local bias = getbiasloc2(dn, df)
+ if bias then
+ -- utc = local + bias;
+ self.daynum = dn
+ self.dayfrc = df + bias*TICKSPERSEC
+ return self:normalize()
+ else
+ return nil
+ end
+ end
+
+ function dobj:getbias() return (getbiasloc2(self.daynum, self.dayfrc))/SECPERMIN end
+
+ function dobj:gettzname()
+ local _, tvu, _ = getbiasloc2(self.daynum, self.dayfrc)
+ return tvu and osdate("%Z",tvu) or ""
+ end
+
+--#if not DATE_OBJECT_AFX then
+ function date.time(h, r, s, t)
+ h, r, s, t = tonumber(h or 0), tonumber(r or 0), tonumber(s or 0), tonumber(t or 0)
+ if h and r and s and t then
+ return date_new(DAYNUM_DEF, makedayfrc(h, r, s, t))
+ else
+ return date_error_arg()
+ end
+ end
+
+ function date:__call(...)
+ local arg = pack(...)
+ if arg.n > 1 then return (date_from(...))
+ elseif arg.n == 0 then return (date_getdobj(false))
+ else local o, r = date_getdobj(arg[1]); return r and o:copy() or o end
+ end
+
+ date.diff = dobj.__sub
+
+ function date.isleapyear(v)
+ local y = fix(v);
+ if not y then
+ y = date_getdobj(v)
+ y = y and y:getyear()
+ end
+ return isleapyear(y+0)
+ end
+
+ function date.epoch() return date_epoch:copy() end
+
+ function date.isodate(y,w,d) return date_new(makedaynum_isoywd(y + 0, w and (w+0) or 1, d and (d+0) or 1), 0) end
+
+-- Internal functions
+ function date.fmt(str) if str then fmtstr = str end; return fmtstr end
+ function date.daynummin(n) DAYNUM_MIN = (n and n < DAYNUM_MAX) and n or DAYNUM_MIN return n and DAYNUM_MIN or date_new(DAYNUM_MIN, 0):normalize()end
+ function date.daynummax(n) DAYNUM_MAX = (n and n > DAYNUM_MIN) and n or DAYNUM_MAX return n and DAYNUM_MAX or date_new(DAYNUM_MAX, 0):normalize()end
+ function date.ticks(t) if t then setticks(t) end return TICKSPERSEC end
+--#end -- not DATE_OBJECT_AFX
+
+ local tm = osdate("!*t", 0);
+ if tm then
+ date_epoch = date_new(makedaynum(tm.year, tm.month - 1, tm.day), makedayfrc(tm.hour, tm.min, tm.sec, 0))
+ -- the distance from our epoch to os epoch in daynum
+ DATE_EPOCH = date_epoch and date_epoch:spandays()
+ else -- error will be raise only if called!
+ date_epoch = setmetatable({},{__index = function() error("failed to get the epoch date") end})
+ end
+
+--#if not DATE_OBJECT_AFX then
+return date
+--#else
+--$return date_from
+--#end
+
diff --git a/macros/luatex/latex/wallcalendar/wallcalendar-helpers.lua b/macros/luatex/latex/wallcalendar/wallcalendar-helpers.lua
new file mode 100644
index 0000000000..99314dd0bf
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/wallcalendar-helpers.lua
@@ -0,0 +1,279 @@
+-- paths are relative to wallcalendar.cls
+local csv = require("wallcalendar-csv.lua")
+local date = require("wallcalendar-date.lua")
+local tp = tex.print
+local tsp = tex.sprint
+
+function loadCsv(csv_path)
+ local f = csv.open(csv_path, {separator = ";", header = true})
+ local data = {}
+ for fields in f:lines() do
+ data[#data + 1] = fields
+ end
+ return data
+end
+
+function ok(x)
+ return x ~= nil and x ~= ""
+end
+
+function hasNote(event)
+ return ok(event.note)
+end
+
+function monthNameToNum(monthName)
+ local months = {january = 1, february = 2, march = 3, april = 4, may = 5, june = 6, july = 7, august = 8, september = 9, october = 10, november = 11, december = 12}
+ return months[string.lower(monthName)]
+end
+
+function getMark(idx, events, markDefaults, isNote)
+ local event = events[idx]
+ local default_mark = {}
+ default_mark.number = {}
+ default_mark.day_text = {}
+ default_mark.note = {}
+
+ default_mark.number.symbol = idx
+ default_mark.number.above_offset = "\\markNumberAbove"
+ default_mark.number.right_offset = "\\markNumberRight"
+
+ default_mark.day_text.symbol = idx
+ default_mark.day_text.above_offset = "\\markDayTextAbove"
+ default_mark.day_text.right_offset = "\\markDayTextRight"
+
+ default_mark.note.symbol = idx
+ default_mark.note.above_offset = "" -- placeholder, not used for note
+ default_mark.note.right_offset = "" -- placeholder, not used for note
+
+ local mark = {}
+
+ for k,v in pairs(default_mark.number) do
+ local m = {}
+ local mark_key = ""
+ local csv_key = ""
+
+ if ok(isNote) then
+ mark_key = "note"
+ elseif ok(event.day_text) then
+ mark_key = "day_text"
+ else
+ mark_key = "number"
+ end
+
+ m = default_mark[mark_key]
+ csv_key = mark_key .. "_" .. k
+
+ if not ok(markDefaults) or not ok(markDefaults[idx]) or not ok(markDefaults[idx][csv_key]) then
+ mark[k] = m[k]
+ else
+ mark[k] = markDefaults[idx][csv_key]
+ end
+ end
+
+ return mark
+end
+
+function getCombinedMark(idx, events, markDefaults, isNote)
+ local event = events[idx]
+ local mark = getMark(idx, events, markDefaults, isNote)
+
+ mark.symbol = ""
+ for i,e in pairs(events) do
+ if e.date == event.date then
+ local m = getMark(i, events, markDefaults, isNote)
+ if mark.symbol == "" then
+ mark.symbol = m.symbol
+ else
+ mark.symbol = mark.symbol .. "\\symbolSeparator " .. m.symbol
+ end
+ end
+ end
+
+ return mark
+end
+
+function collectEvents(byWhat, events, byValue, filterPred)
+ local data = {}
+ for idx,row in pairs(events) do
+ d = date(row.date)
+
+ if filterPred ~= nil then
+ if byWhat == 'month' then
+ if d:getmonth() == byValue and filterPred(row) then
+ data[#data + 1] = row
+ end
+ elseif byWhat == 'year' then
+ if d:getyear() == byValue and filterPred(row) then
+ data[#data + 1] = row
+ end
+ end
+ else
+ if byWhat == 'month' then
+ if d:getmonth() == byValue then
+ data[#data + 1] = row
+ end
+ elseif byWhat == 'year' then
+ if d:getyear() == byValue then
+ data[#data + 1] = row
+ end
+ end
+ end
+
+ end
+ return data
+end
+
+function eventsInMonth(events, month, filterPred)
+ return collectEvents('month', events, month, filterPred)
+end
+
+function eventsInYear(events, year, filterPred)
+ return collectEvents('year', events, year, filterPred)
+end
+
+function formatEvents(events, formatFunc, formatCmd, markDefaultsCsv, minEvents)
+ if ok(minEvents) and #events < minEvents then
+ d = minEvents - #events
+ for i=0,d,1 do
+ events[#events + 1] = {}
+ end
+ end
+
+ local markDefaults = nil
+ if ok(markDefaultsCsv) then
+ markDefaults = loadCsv(markDefaultsCsv)
+ end
+
+ for idx,event in pairs(events) do
+ local mark = {}
+ local d = {}
+
+ if ok(event.date) then
+ -- don't use getCombinedMark here, events on the same day will be printed one after the other
+ mark = getMark(idx, events, markDefaults, true)
+ d = date(event.date)
+ end
+
+ if formatFunc then
+
+ formatFunc(idx, #events, event, d, mark)
+
+ else
+
+ tsp("\\def\\eIdx{"..idx .."}") -- \def\eIdx{1}
+ tsp("\\def\\eMaxIdx{"..#events .."}") -- \def\eMaxIdx{8}
+ tsp("\\def\\eMark{"..mark.symbol .."}") -- \def\eMark{\kiteMark}
+ tsp("\\def\\eIsoDate{"..event.date .."}") -- \def\eIsoDate{2018-01-12}
+ tsp("\\def\\eYear{"..d:getyear() .."}") -- \def\eYear{2018}
+ tsp("\\def\\eMonth{\\x"..d:fmt("%B") .."}") -- \def\eMonth\xJanuary
+ tsp("\\def\\eMonthShort{\\x"..d:fmt("%b").."Short" .."}") -- \def\eMonthShort\xJanShort
+ tsp("\\def\\eDay{"..d:getday() .."}") -- \def\eDay{12}
+ if ok(event.day_text) then
+ tsp("\\def\\eDayText{"..event.day_text .."}") -- \def\eDayText{\dejaVuSans\char"263C}
+ else
+ tsp("\\def\\eDayText{}")
+ end
+ if ok(event.note) then
+ tsp("\\def\\eNote{"..event.note .."}") -- \def\eNote{Anniversary Day}
+ else
+ tsp("\\def\\eNote{}")
+ end
+
+ tsp(formatCmd)
+
+ end
+ end
+end
+
+-- It's better to call it with the name of the month than its number because it
+-- fits the wrapper commands better.
+function monthEvents(monthName, filterPred, formatFunc, formatCmd, eventsCsv, markDefaultsCsv, minEvents)
+ local monthNum = monthNameToNum(monthName)
+ local events = eventsInMonth(loadCsv(eventsCsv), monthNum, filterPred)
+
+ formatEvents(events, formatFunc, formatCmd, markDefaultsCsv, minEvents)
+end
+
+function yearEvents(yearNum, filterPred, formatFunc, formatCmd, eventsCsv, markDefaultsCsv, minEvents)
+ local events = eventsInYear(loadCsv(eventsCsv), yearNum, filterPred)
+
+ formatEvents(events, formatFunc, formatCmd, markDefaultsCsv, minEvents)
+end
+
+-- monthName is better for argument than monthNum
+function monthMarksDayText(monthName, filterPred, eventsCsv)
+ local monthNum = monthNameToNum(monthName)
+ local events = eventsInMonth(loadCsv(eventsCsv), monthNum, filterPred);
+
+ for idx,event in pairs(events) do
+ if ok(event.day_text) then
+ tsp(string.format(" if (equals=%s) [day text={%s}, xshift=\\dayTextXshift, yshift=\\dayTextYshift] ", event.date, event.day_text))
+ end
+ end
+end
+
+function yearMarksDayText(yearNum, filterPred, eventsCsv)
+ local events = eventsInYear(loadCsv(eventsCsv), yearNum, filterPred);
+
+ for idx,event in pairs(events) do
+ if ok(event.day_text) then
+ tsp(string.format(" if (equals=%s) [day text={%s}, xshift=\\dayTextXshift, yshift=\\dayTextYshift] ", event.date, event.day_text))
+ end
+ end
+end
+
+function formatMarksNote(events, filterPred, markDefaultsCsv, isOneCalendar)
+ local markDefaults = nil
+ if ok(markDefaultsCsv) then
+ markDefaults = loadCsv(markDefaultsCsv)
+ end
+
+ local alreadyMarkedDates = {}
+
+ for idx,event in pairs(events) do
+ if ok(event.note) and alreadyMarkedDates[event.date] == nil then
+ alreadyMarkedDates[event.date] = true
+ local d = date(event.date)
+
+ local mark = getCombinedMark(idx, events, markDefaults)
+
+ if ok(isOneCalendar) and isOneCalendar == true then
+ tsp(string.format(" \\draw node [above right=%s and %s of cal-%s.north east] {\\monthMarkFmt %s}; ",
+ mark.above_offset,
+ mark.right_offset,
+ event.date,
+ mark.symbol))
+ else
+ tsp(string.format(" \\draw node [above right=%s and %s of cal%s-%s.north east] {\\monthMarkFmt %s}; ",
+ mark.above_offset,
+ mark.right_offset,
+ d:fmt("%m"),
+ event.date,
+ mark.symbol))
+ end
+ end
+ end
+end
+
+-- monthName is better for argument than monthNum
+function monthMarksNote(monthName, filterPred, eventsCsv, markDefaultsCsv)
+ local monthNum = monthNameToNum(monthName)
+
+ if not ok(filterPred) then
+ filterPred = function(e) return ok(e.note) end
+ end
+
+ local events = eventsInMonth(loadCsv(eventsCsv), monthNum, filterPred);
+
+ formatMarksNote(events, filterPred, markDefaultsCsv, false)
+end
+
+function yearMarksNote(yearNum, filterPred, eventsCsv, markDefaultsCsv, isOneCalendar)
+ if not ok(filterPred) then
+ filterPred = function(e) return ok(e.note) end
+ end
+
+ local events = eventsInYear(loadCsv(eventsCsv), yearNum, filterPred);
+
+ formatMarksNote(events, filterPred, markDefaultsCsv, isOneCalendar)
+end
diff --git a/macros/luatex/latex/wallcalendar/wallcalendar-layouts.png b/macros/luatex/latex/wallcalendar/wallcalendar-layouts.png
new file mode 100644
index 0000000000..f2cf5a240b
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/wallcalendar-layouts.png
Binary files differ
diff --git a/macros/luatex/latex/wallcalendar/wallcalendar.cls b/macros/luatex/latex/wallcalendar/wallcalendar.cls
new file mode 100644
index 0000000000..be0cc5ef96
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/wallcalendar.cls
@@ -0,0 +1,1714 @@
+% wallcalendar.cls; Don't edit this file. Edit wallcalendar-code.org with emacs org-mode and call 'org-babel-tangle'.
+%
+% Wall Calendar
+%
+% A wall calendar document class with custom layouts and support for internationalization.
+%
+% (c) Gambhiro Bhikkhu, 2017
+% gambhiro.bhikkhu.85@gmail.com
+%
+% LPPL LaTeX Public Project License
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{wallcalendar}[2017/10/21 v1.3.1 A wall calendar class with custom layouts and support for internationalization.]
+
+\RequirePackage{pgfopts}
+\RequirePackage{calc}
+
+\newlength\calPaperWidth
+\newlength\calPaperHeight
+\newlength\@wall@leftMargin
+\newlength\@wall@rightMargin
+\newlength\@wall@topMargin
+\newlength\@wall@bottomMargin
+
+\def\@wall@eventsCsv{}
+\def\@wall@markDefaultsCsv{}
+\def\@wall@translationsInputFile{}
+
+\newcommand*\theMonthName{}
+
+\newif\ifvarnishmask
+\newif\ifshowframe
+\newif\iftranslationsAutoload
+\newif\ifloadBabel
+
+\pgfkeys{
+ /wall/.is family, /wall,
+ defaults/.style = {
+ year = \the\year,
+ altyear = \empty,
+ loadBabel = false,
+ language = english,
+ translationsAutoload = true,
+ imageFolder = {./src-images},
+ choralOctavoPaper,
+ hMargin = 17mm,
+ topMargin = 20.5mm,
+ bottomMargin = 10mm,
+ },
+ year/.store in = \CalendarYear,
+ year/.initial = \the\year,
+ altyear/.store in = \CalendarAltYear,
+ altyear/.initial = \empty,
+ language/.store in = \@wall@calendarLanguage,
+ loadBabel/.is if = loadBabel,
+ translationsInputFile/.store in = \@wall@translationsInputFile,
+ translationsInputFile/.initial = {},
+ translationsAutoload/.is if = translationsAutoload,
+ eventsCsv/.store in = \@wall@eventsCsv,
+ eventsCsv/.initial = {},
+ markDefaultsCsv/.store in = \@wall@markDefaultsCsv,
+ markDefaultsCsv/.initial = {},
+ varnishmask/.is if = varnishmask,
+ showframe/.is if = showframe,
+ imageFolder/.store in = \@wall@imageFolder,
+ paperWidth/.code = {\setlength{\calPaperWidth}{#1}},
+ paperHeight/.code = {\setlength{\calPaperHeight}{#1}},
+ hMargin/.code = {\setlength{\@wall@leftMargin}{#1}%
+ \setlength{\@wall@rightMargin}{#1}},
+ leftMargin/.code = {\setlength{\@wall@leftMargin}{#1}},
+ rightMargin/.code = {\setlength{\@wall@rightMargin}{#1}},
+ topMargin/.code = {\setlength{\@wall@topMargin}{#1}},
+ bottomMargin/.code = {\setlength{\@wall@bottomMargin}{#1}},
+ % Paper sizes
+ choralOctavoPaper/.style = {paperWidth = 6.75in, paperHeight = 10.5in},
+ a2Paper/.style = {paperWidth = 420mm, paperHeight = 594mm},
+ a2PaperLandscape/.style = {paperWidth = 594mm, paperHeight = 420mm},
+ a3Paper/.style = {paperWidth = 297mm, paperHeight = 420mm},
+ a3PaperLandscape/.style = {paperWidth = 420mm, paperHeight = 297mm},
+ a4Paper/.style = {paperWidth = 210mm, paperHeight = 297mm},
+ a4PaperLandscape/.style = {paperWidth = 297mm, paperHeight = 210mm},
+ a5Paper/.style = {paperWidth = 148mm, paperHeight = 210mm},% r = 1.4142 = sqrt(2)
+ prevPaper/.style = {paperWidth = 170mm, paperHeight = 250mm},% r = 1.4705
+}
+
+% Debug with: \wlog{YEA: \the\@wall@bottomMargin}
+
+\DeclareOption*{%
+ \PassOptionsToClass{\CurrentOption}{memoir}
+}
+
+\pgfkeys{/wall, defaults}
+\ProcessPgfOptions{/wall}
+\ProcessOptions\relax
+
+\LoadClass[11pt,oneside]{memoir}
+
+\newlength\@tmp@a
+\newlength\@tmp@b
+\newlength\@tmp@c
+\newlength\@tmp@width
+\newlength\@tmp@height
+
+\ifloadBabel
+\RequirePackage[\@wall@calendarLanguage]{babel}
+\fi
+
+\RequirePackage{nag}
+%\RequirePackage{textcomp}
+\RequirePackage[cmyk]{xcolor}
+\RequirePackage{graphicx}
+\DeclareGraphicsExtensions{.pdf,.png,.jpg}
+\graphicspath{{\@wall@imageFolder}}
+
+\RequirePackage{eso-pic}
+\RequirePackage{ccicons}
+\RequirePackage{multicol}
+\RequirePackage{wasysym}
+
+\RequirePackage{pdftexcmds}
+\RequirePackage{etoolbox}
+\RequirePackage{luacode}
+
+\RequirePackage{xcoffins}
+%\RequirePackage{xstring}
+%\RequirePackage{stringstrings}
+
+\ifloadBabel
+\RequirePackage[final,babel=true]{microtype}
+\else
+\RequirePackage[final]{microtype}
+\fi
+
+\RequirePackage{tikz}
+\usetikzlibrary{calendar}
+\usetikzlibrary{positioning}
+\usetikzlibrary{fit}
+\usetikzlibrary{shapes.geometric}
+
+% http://tex.stackexchange.com/a/20426/831
+\pgfdeclarelayer{one}
+\pgfdeclarelayer{two}
+\pgfsetlayers{main,one,two}
+
+\pgfkeys{%
+ /tikz/on layer/.code={
+ \pgfonlayer{#1}\begingroup
+ \aftergroup\endpgfonlayer
+ \aftergroup\endgroup
+ }
+}
+
+\definecolor{textbody}{gray}{0.15}
+
+% pantone 1245C, RGB 191,145,12 HEX: #BF910C
+% pantone 1255C, CMYK 0,27.5,100,34
+\definecolor{gold}{cmyk}{0,0.275,1,0.34}
+\definecolor{darkgold}{cmyk}{0.27,0.53,1,0.09}
+%\definecolor{orangegold}{cmyk}{0,0.31,0.89,0}
+\colorlet{orangegold}{darkgold}
+
+\colorlet{gridcolor}{black!30}
+\colorlet{weekday}{black}
+\colorlet{weekend}{black!50}
+\colorlet{mooncolor}{textbody}
+
+\definecolor{datenum}{gray}{0.3}
+\definecolor{plannerdatenum}{gray}{0.15}
+\definecolor{quote}{gray}{0.3}
+\definecolor{notes}{gray}{0.3}
+
+\definecolor{gridcolor}{gray}{0.5}
+\colorlet{pagebgcolor}{gridcolor!60}
+
+\colorlet{photo-frame}{blue}
+\colorlet{quote-frame}{red}
+\colorlet{heading-frame}{brown}
+\colorlet{calendar-frame}{orange}
+\colorlet{events-frame}{green}
+
+\ifshowframe
+ \colorlet{calendarbg}{black!50}
+\else
+ \colorlet{calendarbg}{white}
+\fi
+
+\ifshowtrims
+ \setstocksize{\calPaperHeight + 35mm}{\calPaperWidth + 35mm}
+ \setlength{\paperheight}{\calPaperHeight}
+ \setlength{\paperwidth}{\calPaperWidth}
+ \trimXmarks
+ \trimLmarks
+ \quarkmarks
+ \settrims{0.5\stockheight - 0.5\paperheight}{0.5\stockwidth - 0.5\paperwidth}
+ \settrimmedsize{\calPaperHeight}{\calPaperWidth}{*}
+\else\relax
+ \setstocksize{\calPaperHeight}{\calPaperWidth}
+ \settrims{0pt}{0pt}
+ \settrimmedsize{\stockheight}{\stockwidth}{*}
+\fi
+
+%\settypeblocksize{\stockheight}{\stockwidth}{*}
+% TODO: calculate margins by ratios to paper size
+\setlrmarginsandblock{\@wall@leftMargin}{\@wall@rightMargin}{*}
+\setulmarginsandblock{\@wall@topMargin}{\@wall@bottomMargin}{*}
+\setheadfoot{0pt}{0pt}
+\setheaderspaces{0pt}{*}{*}
+
+\checkandfixthelayout% This will typeout values in pt.
+\settypeoutlayoutunit{mm}% It is useful to see layout values in mm too.
+\typeoutlayout
+
+\def\@wall@fontSize{11}
+\def\@wall@lineHeight{13.6}
+
+\renewcommand{\normalsize}{%
+ \@setfontsize\normalsize\@wall@fontSize\@wall@lineHeight
+ \abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@
+ \abovedisplayshortskip \z@ \@plus3\p@
+ \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
+ \belowdisplayskip \abovedisplayskip
+ \color{textbody}
+ \let\@listi\@listI}
+\normalsize
+
+\setlength{\vgap}{1.5em}
+\setlength{\vindent}{\vgap}
+\setlength{\vleftmargin}{2em}
+
+\setlength{\parskip}{0pt}
+\setlength{\parindent}{0pt}
+
+\setlength{\fboxsep}{0pt}
+
+\definecolor{varnishmask}{gray}{0}
+
+% http://tex.stackexchange.com/a/59571/831
+\newcommand*{\strcmpblank}[3]{%
+ \ifnum\pdf@strcmp{#1}{}=\z@ #2\else #3\fi
+}
+
+\newcommand\@placeholder@pre[1]{%
+ \settowidth{\@tmp@width}{#1}%
+ \settototalheight{\@tmp@height}{#1}%
+ \def\@spacer{\rule{\@tmp@width}{0pt}\rule{0pt}{\@tmp@height}}%
+}
+
+\newcommand\placeholder[3][]{%
+ \ifvarnishmask%
+ \ifstrequal{#2}{hasvarnish}{%
+ \@placeholder@pre{#3}%
+ \tikz\node[fill=varnishmask, inner sep=0pt]{\@spacer};%
+ }{}%
+ \else%
+ \ifshowframe%
+ \@placeholder@pre{#3}%
+ \tikz\node[inner sep=0pt, opacity=0.6, #1]{\@spacer};%
+ \else%
+ #3%
+ \fi%
+ \fi%
+}
+
+\def\@wall@photo@putPhoto#1{#1}
+\def\@wall@photo@setYOffset{}
+
+\pgfkeys{
+ /put photo/.is family, /put photo,
+ simple/.code = {%
+ \def\@wall@photo@putPhoto##1{%
+ \includegraphics{##1}%
+ }%
+ \def\@wall@photo@setYOffset{}%
+ },
+ full page/.code = {%
+ \def\@wall@photo@putPhoto##1{%
+ \includegraphics[%
+ keepaspectratio,%
+ width={\calPaperWidth + 2\@t@bleed},%
+ ]{##1}%
+ }%
+ \def\@wall@photo@setYOffset{}%
+ },
+ full width above calendar/.code = {%
+ \def\@wall@photo@putPhoto##1{%
+ \includegraphics[%
+ keepaspectratio,%
+ width={\calPaperWidth + 2\@t@bleed},%
+ ]{##1}%
+ }%
+ \def\@wall@photo@setYOffset{%
+ \setlength{\@t@yOffset}{\@t@calendar@height + \@t@bleed + 1pt}%
+ }%
+ },
+ full width/.code = {%
+ \def\@wall@photo@putPhoto##1{%
+ \includegraphics[%
+ keepaspectratio,%
+ width={\calPaperWidth + 2\@t@bleed},%
+ ]{##1}%
+ }%
+ \def\@wall@photo@setYOffset{%
+ \setlength{\@t@yOffset}{\@t@calendar@height + \@t@bleed}%
+ }%
+ },
+}
+
+\pgfkeys{
+ /Photo/.is family, /Photo,
+ init/.style = {
+ defaults/.style = {file = {}, thumbFile = {}, caption = {}, bleed = 0pt, xOffset=0pt, yOffset=0pt},
+ file/.initial = {},
+ thumbFile/.initial = {},
+ caption/.initial = {},
+ bleed/.initial = 0pt,
+ xOffset/.initial = 0pt,
+ yOffset/.initial = 0pt,
+ },
+}
+
+\pgfkeys{
+ /Quote/.is family, /Quote,
+ init/.style = {
+ defaults/.style = {position=center, text={}, xOffset=0pt, yOffset=0pt},
+ position/.initial = {},
+ text/.initial = {},
+ xOffset/.initial = 0pt,
+ yOffset/.initial = 0pt,
+ },
+}
+
+\pgfkeys{
+ /Calendar/.is family, /Calendar,
+ init/.style = {
+ defaults/.style = {bg/.style={opacity=0.5}},
+ bg/.style = {},
+ minimum height/.initial = {},
+ },
+}
+
+\pgfkeys{
+ /Events/.is family, /Events,
+ init/.style = {
+ defaults/.style = {day code = {}, marks = {}, text = {}},
+ day code/.initial = {},
+ marks/.initial = {},
+ text/.initial = {},
+ },
+}
+
+\pgfkeys{
+ /Txt/.is family, /Txt,
+ init/.style = {
+ defaults/.style = {text = {}},
+ text/.initial = {},
+ },
+}
+
+\def\eIdx{}
+\def\eMaxIdx{}
+\def\eMark{}
+\def\eIsoDate{}
+\def\eYear{}
+\def\eMonth{}
+\def\eMonthShort{}
+\def\eDay{}
+\def\eDayText{}
+\def\eNote{}
+
+\pgfkeys{
+ /parseMonthEvents/.is family, /parseMonthEvents,
+ month/.initial = {},
+ filter pred/.initial = nil,
+ format func/.initial = nil,
+ format cmd/.initial = {},
+ events csv/.initial = {},
+ mark defaults csv/.initial = {},
+ min events/.initial = {},
+ defaults/.style = {
+ month = \theMonthName,
+ filter pred = nil,
+ format func = nil,
+ format cmd = {\textsuperscript{\eIdx}~\eMonthShort~\eDay:~\eNote\par},
+ events csv = \@wall@eventsCsv,
+ mark defaults csv = \@wall@markDefaultsCsv,
+ min events = nil,
+ },
+}
+
+\pgfkeys{
+ /parseYearEvents/.is family, /parseYearEvents,
+ year/.initial = {},
+ filter pred/.initial = nil,
+ format func/.initial = nil,
+ format cmd/.initial = {},
+ events csv/.initial = {},
+ mark defaults csv/.initial = {},
+ min events/.initial = {},
+ defaults/.style = {
+ year = \CalendarYear,
+ filter pred = nil,
+ format func = nil,
+ format cmd = {\textsuperscript{\eIdx}~\eMonthShort~\eDay:~\eNote\ifnumless{\eIdx}{\eMaxIdx}{,\space}{.}},
+ events csv = \@wall@eventsCsv,
+ mark defaults csv = \@wall@markDefaultsCsv,
+ min events = nil,
+ },
+}
+
+\newcommand\StarMark{*}
+
+\newcommand\NoteStarMark{*}
+
+\newlength\@wall@starHeight
+
+% Measure the star's height here, so that we are measuring with the current typeface.
+\newcommand\KiteMark{%
+\setlength{\@wall@starHeight}{\totalheightof{*}}%
+\begin{tikzpicture}
+ \node (box) [
+ rectangle, minimum height=\@wall@starHeight, minimum width=3.4pt,
+ inner sep=0pt, line width=0pt,
+ ] {};
+ \node[
+ kite, draw, textbody, fill=textbody,
+ scale=0.15, kite vertex angles=60,
+ above=0pt of box.north, anchor=north,
+ ] {};%
+\end{tikzpicture}%
+}
+
+% Same as \KiteMark but with scale=0.2
+\newcommand\NoteKiteMark{\raisebox{1pt}{%
+\setlength{\@wall@starHeight}{\totalheightof{*}}%
+\begin{tikzpicture}
+ \node (box) [
+ rectangle, minimum height=\@wall@starHeight, minimum width=3.4pt,
+ inner sep=0pt, line width=0pt,
+ ] {};
+ \node[
+ kite, draw, textbody, fill=textbody,
+ scale=0.2, kite vertex angles=60,
+ above=0pt of box.north, anchor=north,
+ ] {};%
+\end{tikzpicture}%
+}}
+
+\tikzstyle{moon circle}=[
+ circle,
+ inner sep=0pt,
+ line width=0pt,
+ minimum height=8pt,
+]
+
+\newlength\@wall@moonRaise
+\setlength{\@wall@moonRaise}{-0.7pt}
+
+\newcommand\NewMoon{}
+\newcommand\FirstQuarter{}
+\newcommand\FullMoon{}
+\newcommand\LastQuarter{}
+
+\newcommand\@wall@NewMoon{%
+\raisebox{\@wall@moonRaise}{%
+ \tikz\node[moon circle, fill=mooncolor] {};%
+}}
+
+\newcommand\@wall@FullMoon{%
+\raisebox{\@wall@moonRaise}{%
+ \tikz\node[moon circle, draw, mooncolor, line width=0.3pt] {};%
+}}
+
+\newcommand\@wall@FirstQuarter{%
+\raisebox{\@wall@moonRaise}{%
+\begin{tikzpicture}
+\node [moon circle, name=waxing] {};
+\path[fill=mooncolor]
+ (waxing.north) --
+ (waxing.south) to[out=-180,in=-90]
+ (waxing.west) to[out=90,in=-180]
+ (waxing.north);
+\end{tikzpicture}%
+}}
+
+\newcommand\@wall@LastQuarter{%
+\raisebox{\@wall@moonRaise}{%
+\begin{tikzpicture}
+\node [moon circle, name=waning] {};
+\path[fill=mooncolor]
+ (waning.north) --
+ (waning.south) to[out=0,in=-90]
+ (waning.east) to[out=90,in=0]
+ (waning.north);
+\end{tikzpicture}%
+}}
+
+\newcommand\@wall@useDefaultMoons{%
+\renewcommand\NewMoon{\@wall@NewMoon}%
+\renewcommand\FirstQuarter{\@wall@FirstQuarter}%
+\renewcommand\FullMoon{\@wall@FullMoon}%
+\renewcommand\LastQuarter{\@wall@LastQuarter}%
+}
+
+\newcommand\plannerMoonSize{\@setfontsize\plannerMoonSize{14}{14}}
+\newcommand*\plannerMoonFormat[1]{{\plannerMoonSize #1}}
+
+\newcommand\@wall@planner@NewMoon{\plannerMoonFormat{\CIRCLE}}
+\newcommand\@wall@planner@FirstQuarter{\plannerMoonFormat{\LEFTcircle}}
+\newcommand\@wall@planner@FullMoon{\plannerMoonFormat{\Circle}}
+\newcommand\@wall@planner@LastQuarter{\plannerMoonFormat{\RIGHTcircle}}
+
+\newcommand\@wall@usePlannerMoons{%
+\renewcommand\NewMoon{\@wall@planner@NewMoon}%
+\renewcommand\FirstQuarter{\@wall@planner@FirstQuarter}%
+\renewcommand\FullMoon{\@wall@planner@FullMoon}%
+\renewcommand\LastQuarter{\@wall@planner@LastQuarter}%
+}
+
+\@wall@useDefaultMoons
+
+\newcommand\SetPhoto[2][]{%
+ \pgfkeys{%
+ /Photo/#2/.is family, /Photo/#2,
+ /Photo/init,
+ defaults, file={#2},
+ #1%
+ }%
+}
+
+\newcommand\SetCalendar[2][]{%
+ \pgfkeys{%
+ /Calendar/#2/.is family, /Calendar/#2,
+ /Calendar/init,
+ defaults,
+ #1%
+ }%
+}
+
+\newcommand\SetQuote[3][]{%
+ \pgfkeys{%
+ /Quote/#2/.is family, /Quote/#2,
+ /Quote/init,
+ defaults, text={#3},
+ #1%
+ }%
+}
+
+\newcommand\SetEvents[4][]{%
+ \pgfkeys{%
+ /Events/#2/.is family, /Events/#2,
+ /Events/init,
+ defaults, marks={#3}, text={#4},
+ #1%
+ }%
+}
+
+\pgfkeys{
+ /MonthPage/.is family, /MonthPage,
+ layout/.style = {layout handlers/#1/.get = \@wall@month@doLayout},
+ put photo/.style = {/put photo/#1},
+ defaults/.style = {layout = small landscape, put photo = simple},
+ layout handlers/.cd,
+ full page/.initial = \@wall@fullPageLayout,
+ small landscape/.initial = \@wall@smallLandscapeLayout,
+}
+
+\newcommand\MonthPage[2][]{%
+ \pgfkeys{/MonthPage, defaults, #1}%
+ \@wall@month@doLayout{#2}%
+}
+
+\newcommand\SetTxt[2]{%
+ \pgfkeys{%
+ /Txt/#1/.is family, /Txt/#1,
+ /Txt/init,
+ defaults, text={#2},
+ }%
+}
+
+\newcommand\txt[1]{%
+\pgfkeys{/Txt/#1/text/.get=\@val}%
+\@val%
+}
+
+\def\@t@monthName{}
+\def\@t@eventsCsv{}
+\def\@t@markDefaultsCsv{}
+\def\@t@filterPred{}
+\def\@t@formatFunc{}
+\def\@t@formatCmd{}
+\def\@t@minEvents{}
+
+\newcommand\monthMarkFmt{\color{textbody}}
+
+\newcommand\symbolSpace{\thinspace}
+\newcommand\symbolSeparator{,\symbolSpace}
+
+% #1 = option keys
+\newcommand*\parseMonthEvents[1][]{%
+\pgfkeys{/parseMonthEvents, defaults, #1,
+ month/.get=\@t@monthName,
+ filter pred/.get=\@t@filterPred,
+ format func/.get=\@t@formatFunc,
+ format cmd/.get=\@t@formatCmd,
+ events csv/.get=\@t@eventsCsv,
+ mark defaults csv/.get=\@t@markDefaultsCsv,
+ min events/.get=\@t@minEvents,
+}%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthEvents(
+ \luastring{\@t@monthName},
+ \@t@filterPred,
+ \@t@formatFunc,
+ \luastringO{\@t@formatCmd},
+ \luastring{\@t@eventsCsv},
+ \luastring{\@t@markDefaultsCsv},
+ \@t@minEvents
+)}}
+
+\def\@t@yearNum{}
+
+% #1 = option keys
+\newcommand*\parseYearEvents[1][]{%
+\pgfkeys{/parseYearEvents, defaults, #1,
+ year/.get=\@t@year,
+ filter pred/.get=\@t@filterPred,
+ format func/.get=\@t@formatFunc,
+ format cmd/.get=\@t@formatCmd,
+ events csv/.get=\@t@eventsCsv,
+ mark defaults csv/.get=\@t@markDefaultsCsv,
+ min events/.get=\@t@minEvents,
+}%
+\luadirect{
+require("wallcalendar-helpers.lua")
+yearEvents(
+ tonumber(\@t@year),
+ \@t@filterPred,
+ \@t@formatFunc,
+ \luastringO{\@t@formatCmd},
+ \luastring{\@t@eventsCsv},
+ \luastring{\@t@markDefaultsCsv},
+ \@t@minEvents
+)}}
+
+\newlength\dayTextXshift
+\newlength\dayTextYshift
+\setlength{\dayTextXshift}{0pt}
+\setlength{\dayTextYshift}{0pt}
+
+\newlength\markNumberAbove
+\newlength\markNumberRight
+\setlength{\markNumberAbove}{-10pt}
+\setlength{\markNumberRight}{-3pt}
+
+\newlength\markDayTextAbove
+\newlength\markDayTextRight
+\setlength{\markDayTextAbove}{-10pt}
+\setlength{\markDayTextRight}{-3pt}
+
+\newcommand\parseMonthMarksDayText{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{\theMonthName}, nil, \luastring{\@wall@eventsCsv})
+tex.sprint(';')
+}}
+
+\newcommand\parseMonthMarksDayTextMonth[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{#1}, nil, \luastring{\@wall@eventsCsv})
+tex.sprint(';')
+}}
+
+\newcommand*\parseMonthMarksDayTextUsing[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{\theMonthName}, nil, \luastring{#1})
+}}
+
+\newcommand\parseMonthMarksDayTextMonthUsing[2]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{#1}, nil, \luastring{#2})
+}}
+
+\newcommand*\parseMonthMarksNote{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksNote(\luastring{\theMonthName}, nil, \luastring{\@wall@eventsCsv}, \luastring{\@wall@markDefaultsCsv})
+}}
+
+\newcommand*\parseMonthMarksNoteUsing[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksNote(\luastring{\theMonthName}, nil, \luastring{#1}, \luastring{\@wall@markDefaultsCsv})
+}}
+
+\makepagestyle{month}
+\makeoddhead{month}{}{}{}
+\makeevenhead{month}{}{}{}
+\makeoddfoot{month}{}{}{}
+\makeevenfoot{month}{}{}{}
+
+\pagestyle{month}
+
+\NewCoffin\@wall@pageWrap
+\NewCoffin\@wall@photo
+\NewCoffin\@wall@quote
+\NewCoffin\@wall@calendar
+\NewCoffin\@wall@events
+
+\newlength\@t@bleed
+\newlength\@t@rightOffset
+\newlength\@t@minipageWidth
+\newlength\@t@calendar@height
+\newlength\@t@calendar@hmargin
+\newlength\@t@calendar@dayYshift
+\newlength\@t@calendar@dayXshift
+\newlength\@t@calendar@gridHeight
+\newlength\@t@calendar@gridHeightFiveRows
+\newlength\@t@calendar@gridHeightSixRows
+\newlength\@t@xOffset
+\newlength\@t@yOffset
+\def\@t@file{}
+
+\newcommand*\monthFmt{}%
+\newcommand*\yearFmt{}%
+\newcommand*\dayLetterColor{}%
+\newcommand*\dayLetterFmt{}%
+\newcommand*\dayTextFmt{}%
+\newcommand*\quoteFmt{}%
+\newcommand*\headingFmt{}%
+\newcommand*\calendarFmt{}%
+\newcommand*\eventsFmt{}%
+
+\newcommand\@wall@layout@reset{%
+ \renewcommand*\monthFmt{}%
+ \renewcommand*\yearFmt{}%
+ \renewcommand*\dayLetterColor{}%
+ \renewcommand*\dayLetterFmt{}%
+ \renewcommand*\dayTextFmt{}%
+ \renewcommand*\quoteFmt{}%
+ \renewcommand*\headingFmt{}%
+ \renewcommand*\calendarFmt{}%
+ \renewcommand*\eventsFmt{}%
+ \def\@t@file{}%
+ \setlength{\@t@calendar@height}{0pt}%
+ \setlength{\@t@calendar@hmargin}{0pt}%
+ \setlength{\@t@calendar@dayYshift}{0pt}%
+ \setlength{\@t@calendar@dayXshift}{0pt}%
+ \setlength{\@t@bleed}{0pt}%
+ \setlength{\@t@rightOffset}{0pt}%
+ \setlength{\@t@minipageWidth}{0pt}%
+ \setlength{\@t@xOffset}{0pt}%
+ \setlength{\@t@yOffset}{0pt}%
+ \setlength{\@t@calendar@gridHeight}{0pt}%
+ \setlength{\@t@calendar@gridHeightFiveRows}{0pt}%
+ \setlength{\@t@calendar@gridHeightSixRows}{0pt}%
+}
+
+\newcommand\fullPageFmt{%
+ \renewcommand*\monthFmt{\LARGE}%
+ \renewcommand*\yearFmt{\LARGE}%
+ \renewcommand*\dayLetterColor{}%
+ \renewcommand*\dayLetterFmt{\tiny}%
+ \renewcommand*\dayTextFmt{\small}%
+ \renewcommand*\quoteFmt{}%
+ \renewcommand*\headingFmt{\centering}%
+ \renewcommand*\calendarFmt{\centering}%
+ \renewcommand*\eventsFmt{\setlength{\parindent}{0pt}\raggedleft\footnotesize}%
+}
+
+\newcommand\@wall@fullPageLayout[2][]{%
+\makeatletter
+\renewcommand*\theMonthName{#2}
+\@wall@layout@reset
+\fullPageFmt
+
+\colorlet{weekday}{black}
+\colorlet{weekend}{black!70}
+
+\pgfkeys{/Photo/#2/bleed/.get=\@val}
+\setlength{\@t@bleed}{\@val}
+
+\def\@t@monthnum{\monthToNum{#2}}
+
+% 40mm = 1.5748 inch
+% 43mm = 1.6929 inch
+\setlength{\@t@calendar@height}{40mm + \@t@bleed}
+
+% See if there was a height given in the options
+\pgfkeys{/Calendar/#2/minimum height/.get=\@val}
+\ifx\@val\empty \relax
+\else
+ \setlength{\@t@calendar@height}{\@val + \@t@bleed}
+\fi
+
+\setlength{\@t@calendar@hmargin}{20pt}
+
+% NOTE: the -4pt and -2pt offset is somehow necessary for the sides to align
+% with the edges
+\setlength{\@t@rightOffset}{\@t@bleed +\@t@calendar@hmargin -4pt}
+\setlength{\@t@minipageWidth}{\calPaperWidth -2\@t@calendar@hmargin -2pt}
+
+\SetHorizontalCoffin\@wall@pageWrap{%
+ \color{white}%
+ \rule{\textwidth}{0pt}%
+ \rule{0pt}{\textheight}%
+}
+
+\pgfkeys{/Photo/#2/file/.get=\@t@file}
+
+\SetHorizontalCoffin\@wall@photo{%
+ \placeholder[fill=photo-frame]{hasvarnish}{%
+ \@wall@photo@putPhoto{\@t@file}%
+ }%
+}
+
+\SetHorizontalCoffin\@wall@quote{%
+ \placeholder[fill=quote-frame]{}{%
+ \begin{minipage}{\linewidth}%
+ \quoteFmt
+ \pgfkeys{/Quote/#2/text/.get=\@val}%
+ \@val%
+ \end{minipage}%
+ }%
+}
+
+\SetHorizontalCoffin\@wall@calendar{%
+\ifvarnishmask\relax
+\else
+\begin{tikzpicture}
+
+\node (bg) [
+ fill = calendarbg,
+ opacity = 0.5,
+ minimum width = {\calPaperWidth + 2\@t@bleed},
+ anchor=north west,
+ /Calendar/#2/bg,
+ % override the style, in case bleed was set above
+ minimum height = {\@t@calendar@height},
+] at (0,0) {};
+
+\node (heading) [
+ below right=10pt and {\@t@rightOffset} of bg.north west,
+ anchor=north west,
+] {%
+\placeholder[fill=heading-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\headingFmt
+{\monthFmt\@tr@monthNumName{\@t@monthnum}}
+\hfill
+\strcmpblank{\CalendarAltYear}{%
+ {\yearFmt\CalendarYear}%
+}{%
+ {\yearFmt\CalendarYear/\CalendarAltYear}%
+}%
+\end{minipage}%
+}%
+};
+
+\node (calendar) [
+ below right=35pt and {\@t@rightOffset} of bg.north west,
+ anchor=north west,
+] {%
+\placeholder[fill=calendar-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\calendarFmt
+\tikz{\tikzMonthCalendar@fullpage{\@t@monthnum};}%
+\end{minipage}%
+}%
+};
+
+\node (events) [
+ below=0pt of calendar.south west,
+ anchor=north west,
+] {%
+\placeholder[fill=events-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\eventsFmt
+\pgfkeys{/Events/#2/text/.get=\@val}%
+\@val%
+\end{minipage}%
+}%
+};
+
+\end{tikzpicture}%
+\fi
+}% \SetHorizontalCoffin
+
+\@wall@photo@setYOffset
+
+\pgfkeys{/Photo/#2/xOffset/.get=\@val}
+\addtolength{\@t@xOffset}{\@val}
+\pgfkeys{/Photo/#2/yOffset/.get=\@val}
+\addtolength{\@t@yOffset}{\@val}
+
+% NOTE: a small whitespace is visible on the left edge of the page when bleed is 0pt, a space must be getting in somewhere.
+\JoinCoffins*\@wall@pageWrap[l,t]\@wall@photo[l,t](-\spinemargin -\@t@bleed + \@t@xOffset, \uppermargin + \@t@bleed + \@t@yOffset)
+
+\pgfkeys{/Quote/#2/xOffset/.get=\@val}
+\setlength{\@t@xOffset}{\@val}
+\pgfkeys{/Quote/#2/yOffset/.get=\@val}
+\setlength{\@t@yOffset}{\@val}
+
+\JoinCoffins*\@wall@pageWrap[l,t]\@wall@quote[l,t](\@t@xOffset, \@t@yOffset)
+
+\JoinCoffins*\@wall@pageWrap[l,b]\@wall@calendar[l,b](-\spinemargin -\@t@bleed, \textheight +\uppermargin -\paperheight -\@t@bleed)
+
+\makeatother
+
+\clearpage
+\TypesetCoffin\@wall@pageWrap%
+}% \@wall@fullPageLayout
+
+\newcommand*{\tikzMonthCalendar@fullpage}[1]{%
+\pgfkeys{/Events/\monthName{#1}/marks/.get=\@eventmarks}%
+\calendar (cal#1) [alnitak, dates=\CalendarYear-#1-01 to \CalendarYear-#1-last] \@eventmarks;%
+}
+
+\newcommand\smallLandscapeFmt{%
+ \renewcommand*\monthFmt{\LARGE}%
+ \renewcommand*\yearFmt{\LARGE}%
+ \renewcommand*\dayLetterColor{}%
+ \renewcommand*\dayLetterFmt{\tiny}%
+ \renewcommand*\dayTextFmt{\small}%
+ \renewcommand*\quoteFmt{\centering}%
+ \renewcommand*\headingFmt{\centering}%
+ \renewcommand*\calendarFmt{\centering}%
+ \renewcommand*\eventsFmt{\setlength{\parindent}{0pt}\raggedright\footnotesize}%
+}
+
+\newcommand\@wall@smallLandscapeLayout[2][]{%
+\makeatletter
+\renewcommand*\theMonthName{#2}
+\@wall@layout@reset
+\smallLandscapeFmt
+
+\colorlet{weekday}{black}
+\colorlet{weekend}{black!70}
+
+\pgfkeys{/Photo/#2/bleed/.get=\@val}
+\setlength{\@t@bleed}{\@val}
+
+\def\@t@monthnum{\monthToNum{#2}}
+
+\setlength{\@t@calendar@height}{85mm + \@t@bleed}
+
+% See if there was a height given in the options
+\pgfkeys{/Calendar/#2/minimum height/.get=\@val}
+\ifx\@val\empty \relax
+\else
+ \setlength{\@t@calendar@height}{\@val + \@t@bleed}
+\fi
+
+\setlength{\@t@calendar@hmargin}{20pt}
+
+% 5mm: day headings
+% 20mm: events
+% 6.5mm: vertical spacing
+\setlength{\@tmp@a}{20mm + 5mm + 6.5mm}
+\setlength{\@tmp@b}{\@t@calendar@height -\@tmp@a}
+\setlength{\@t@calendar@dayYshift}{0.1666\@tmp@b}% 1/6 = 0.1666
+
+\setlength{\@t@calendar@gridHeightSixRows}{\@tmp@b}
+\setlength{\@t@calendar@gridHeightFiveRows}{\@tmp@b -0.1666\@tmp@b}
+
+% NOTE: the -4pt and -2pt offset is somehow necessary for the sides to align
+% with the edges
+\setlength{\@t@rightOffset}{\@t@bleed +\@t@calendar@hmargin -4pt}
+\setlength{\@t@minipageWidth}{\calPaperWidth -2\@t@calendar@hmargin -2pt}
+
+\setlength{\@t@calendar@dayXshift}{0.1428\@t@minipageWidth}% 1/7 = 0.1428
+
+\SetHorizontalCoffin\@wall@pageWrap{%
+ \color{white}%
+ \rule{\textwidth}{0pt}%
+ \rule{0pt}{\textheight}%
+}
+
+\pgfkeys{/Photo/#2/file/.get=\@t@file}
+
+\SetHorizontalCoffin\@wall@photo{%
+ \placeholder[fill=photo-frame]{hasvarnish}{%
+ \@wall@photo@putPhoto{\@t@file}%
+ }%
+}
+
+\SetHorizontalCoffin\@wall@quote{%
+ \placeholder[fill=quote-frame]{}{%
+ \begin{minipage}{\linewidth}%
+ \quoteFmt
+ \pgfkeys{/Quote/#2/text/.get=\@val}%
+ \@val%
+ \end{minipage}%
+ }%
+}
+
+\SetHorizontalCoffin\@wall@calendar{%
+\ifvarnishmask\relax
+\else
+\begin{tikzpicture}
+
+\node (bg) [
+ fill = calendarbg,
+ opacity = 1,
+ minimum width = {\calPaperWidth + 2\@t@bleed},
+ anchor=north west,
+ /Calendar/#2/bg,
+ % override the style, in case bleed was set above
+ minimum height = {\@t@calendar@height},
+] at (0,0) {};
+
+\node (heading) [
+ below right=10pt and {\@t@rightOffset} of bg.north west,
+ anchor=north west,
+] {%
+\placeholder[fill=heading-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\headingFmt
+{\monthFmt\@tr@monthNumName{\@t@monthnum}}
+\hfill
+\strcmpblank{\CalendarAltYear}{%
+ {\yearFmt\CalendarYear}%
+}{%
+ {\yearFmt\CalendarYear/\CalendarAltYear}%
+}%
+\end{minipage}%
+}%
+};
+
+\node (calendar) [
+ below right=35pt and {\@t@rightOffset} of bg.north west,
+ anchor=north west,
+] {%
+\placeholder[fill=calendar-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\calendarFmt
+\hspace*{-5pt}% FIXME
+\tikz{\tikzMonthCalendar@smallLandscape{\@t@monthnum};}%
+\end{minipage}%
+}%
+};
+
+\node (events) [
+ above right=10mm and {\@t@rightOffset} of bg.south west,
+ anchor=south west,
+] {%
+\placeholder[fill=events-frame]{}{%
+\begin{minipage}{\@t@minipageWidth}%
+\eventsFmt
+\pgfkeys{/Events/#2/text/.get=\@val}%
+\@val%
+\end{minipage}%
+}%
+};
+
+\end{tikzpicture}%
+\fi
+}% \SetHorizontalCoffin
+
+% The quote has to be centered betweeen the photo and the calendar with manual tweaking.
+% The height of the quote is not known, the height of the calendar plus its heading is not known.
+
+% TODO move the photo with /Photo/#2/xOffset and yOffset as at the full page layout
+
+\pgfkeys{/Quote/#2/yOffset/.get=\@val}
+\setlength{\@t@yOffset}{\@val}
+
+\JoinCoffins*\@wall@photo[hc,b]\@wall@quote[hc,t](0pt, \@t@yOffset)
+
+\pgfkeys{/Photo/#2/yOffset/.get=\@val}
+\setlength{\@t@yOffset}{\@val}
+
+% NOTE: Taking the bottom edge of the photo as fixed.
+% yOffset must be set to pull the photo down into position
+
+\JoinCoffins*\@wall@pageWrap[hc,t]\@wall@photo[hc,b](0pt, \uppermargin + \@t@yOffset)
+
+% Calendar is aligned to the bottom of the page.
+
+\JoinCoffins*\@wall@pageWrap[hc,b]\@wall@calendar[hc,b](0pt, \textheight +\uppermargin -\paperheight -\@t@bleed)
+
+\makeatother
+
+\clearpage
+\TypesetCoffin\@wall@pageWrap%
+}% \@wall@smallLandscapeLayout
+
+\newcommand*{\tikzMonthCalendar@smallLandscape}[1]{%
+\pgfkeys{/Events/\monthName{#1}/marks/.get=\@eventmarks}%
+\calendar (cal#1) [betelgeuse, dates=\CalendarYear-#1-01 to \CalendarYear-#1-last] \@eventmarks;%
+}
+
+\tikzstyle{day letter headings}=[%
+ day heading/.style={black!90},
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ \pgfmathsetlength\pgf@xa{\tikz@lib@cal@xshift}%
+ \pgfmathsetlength\pgf@ya{\tikz@lib@cal@yshift}%
+ \foreach \d in {0,1,2,3,4,5,6} {%
+ \pgf@xa=\d\pgf@xa%
+ \pgftransformxshift{\pgf@xa}%
+ \pgftransformyshift{\pgf@ya}%
+ \node (d\d) [anchor=south, day heading] {\dayLetterFmt\@tr@dayLetter{\d}};%
+ };%
+ }{}%
+ },%
+]
+
+\newcount\gridRows
+\newcount\gridLines
+\newcount\n
+
+\newif\ifGridNoSurround
+\GridNoSurroundfalse
+
+\tikzstyle{no grid surround}=[execute before day scope={\GridNoSurroundtrue}]
+\tikzstyle{grid surround}=[execute before day scope={\GridNoSurroundfalse}]
+
+\tikzstyle{days grid}=[%
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ %
+ % Determine if the grid is five or six rows
+ %
+ % 31 day months
+ \ifdate{between=01-01 and 01-31, between=03-01 and 03-31, between=05-01 and 05-31, between=07-01 and 07-31, between=08-01 and 08-31, between=10-01 and 10-31, between=12-01 and 12-31}{%
+ \ifdate{Saturday,Sunday}{%
+ \gridRows=6%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightSixRows}%
+ }{%
+ \gridRows=5%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightFiveRows}%
+ }
+ }{
+ % 30 day months and February
+ \ifdate{between=02-01 and 02-last}{%
+ \gridRows=5%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightFiveRows}%
+ }{%
+ \ifdate{Sunday}{%
+ \gridRows=6%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightSixRows}%
+ }{%
+ \gridRows=5%
+ \setlength\@t@calendar@gridHeight{\@t@calendar@gridHeightFiveRows}%
+ }
+ }
+ }
+ %
+ % Horizontal lines
+ %
+ \gridLines=\gridRows
+ \ifGridNoSurround\relax
+ \else
+ \advance\gridLines by 1
+ \n=0
+ \draw [
+ gridcolor,
+ line width=0.3pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ ] (0,{-\n\@t@calendar@dayYshift}) -- (7\@t@calendar@dayXshift,{-\n\@t@calendar@dayYshift});
+ \fi
+ \foreach \n in {1,2,3,4,5,6} {
+ \ifnum\n<\gridLines
+ \draw [
+ gridcolor,
+ line width=0.3pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ ] (0,{-\n\@t@calendar@dayYshift}) -- (7\@t@calendar@dayXshift,{-\n\@t@calendar@dayYshift});
+ \fi
+ }
+ %
+ % Vertical lines
+ %
+ \gridLines=7
+ \ifGridNoSurround\relax
+ \else
+ \advance\gridLines by 1
+ \n=0
+ \draw [
+ gridcolor,
+ line width=0.3pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ ] ({\n\@t@calendar@dayXshift},0) -- ({\n\@t@calendar@dayXshift},{-\gridRows\@t@calendar@dayYshift});
+ \fi
+ \foreach \n in {1,2,3,4,5,6,7} {
+ \ifnum\n<\gridLines
+ \draw [
+ gridcolor,
+ line width=0.3pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ ] ({\n\@t@calendar@dayXshift},0) -- ({\n\@t@calendar@dayXshift},{-\gridRows\@t@calendar@dayYshift});
+ \fi
+ }
+ %
+ % If we are not drawing the surrounding lines, it looks better to hide
+ % some of the top and bottom edges
+ %
+ \ifGridNoSurround
+ \draw [
+ color=white,
+ line width=6pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift={0.5\@t@calendar@dayYshift -1pt},
+ ] (0,0) -- (7\@t@calendar@dayXshift,0);
+ \draw [
+ color=white,
+ line width=6pt,
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift={0.5\@t@calendar@dayYshift +1pt},
+ ] (0,-\gridRows\@t@calendar@dayYshift) -- (7\@t@calendar@dayXshift,-\gridRows\@t@calendar@dayYshift);
+ \fi
+ }{}%
+ }
+]
+
+\tikzstyle{headings background rule}=[
+ background rule/.style={black!90, line width=0.3pt, yshift={0.3\@t@calendar@dayYshift -3pt}},
+ execute before day scope={%
+ \ifdate{day of month=1}{%
+ \draw [
+ xshift=-0.5\@t@calendar@dayXshift,
+ yshift=0.5\@t@calendar@dayYshift,
+ background rule,
+ ] (0,0) -- (7\@t@calendar@dayXshift,0);
+ }{}%
+ }
+]
+
+\tikzstyle{headings background bar}=[
+ headings background rule,
+ background rule/.style={black!20, line width=10pt, yshift={0.3\@t@calendar@dayYshift +3.5pt}},
+]
+
+\tikzstyle{betelgeuse}=[
+ no grid surround,
+ days grid,
+ week list,
+ day xshift=\@t@calendar@dayXshift,
+ day yshift=\@t@calendar@dayYshift,
+ headings background bar,
+ day letter headings,
+ day heading/.style={black!90, yshift={-0.3\@t@calendar@dayYshift}},
+ every day/.append style={anchor=base, inner xsep=0pt, yshift={-0.25\baselineskip}},
+ day text={\dayTextFmt\%d-},
+]
+
+\tikzstyle{alnitak}=[
+ day list right,
+ day xshift={0pt},
+ every month/.append style={anchor=base, inner xsep=0pt, yshift=4mm, xshift=-\widthof{\space}},
+ day text={\dayTextFmt\%d-},
+ every day/.append style={anchor=base, inner xsep=0pt},
+ execute before day scope={
+ %
+ % === Moving the day number ===
+ %
+ % A small offset seems to improve the result, the last day gets closer to the end of the linewidth
+ \pgftransformxshift{0.01em}
+ \pgfcalendarjuliantodate{\pgfcalendarendjulian}{\currentyear}{\currentmonth}{\lastday}
+ % Width of month day digits from 1 - 28
+ \setlength{\@tmp@a}{\widthof{12345678910111213141516171819202122232425262728}}
+ \setlength{\@tmp@b}{\widthof{30}}
+ \pgfmathparse{(\linewidth - \@tmp@a - \@tmp@b * (\lastday-28)) / \lastday}
+ \pgftransformxshift{\pgfmathresult}
+ \let\%=\pgfcalendarshorthand
+ \setlength{\@tmp@a}{\widthof{\%d-}}
+ \pgftransformxshift{\@tmp@a}
+ %
+ % === Weekday letter above the day ===
+ %
+ \ifdate{weekend}{\def\dayLetterColor{\color{weekend}}}{\def\dayLetterColor{\color{weekday}}}%
+ \node[anchor=south,yshift=5mm,inner sep=0pt]{%
+ \dayLetterColor\dayLetterFmt\@tr@dayLetter{\pgfcalendarcurrentweekday}%
+ };%
+ },
+]
+
+\newcommand\plannerPortraitMonthFmt{\fontsize{11}{11}\selectfont\color{darkgold}}
+\newcommand\plannerPortraitDayFmt{\fontsize{8}{8}\selectfont\color{plannerdatenum}}
+
+\tikzstyle{year planner portrait}=[
+ week list,
+ month text={\plannerPortraitMonthFmt\@tr@monthNumName{\pgfcalendarcurrentmonth}},
+ day text={\plannerPortraitDayFmt\%d-},
+ every month/.append style={%
+ anchor=south,
+ inner xsep=0pt,
+ yshift=5mm,
+ xshift=2.5mm,
+ },
+ day letter headings,
+ day heading/.style={gray, xshift=0pt, scale=0.85},
+ month label above centered,
+ every day/.style={anchor=mid},
+]
+
+\newcommand\plannerLandscapeDateDayFont{}
+\newcommand\plannerLandscapeDayFont{}
+\newcommand\plannerLandscapeMonthFont{}
+
+\newcommand\plannerLandscapeMonthFmt{%
+ \plannerLandscapeMonthFont%
+ \fontsize{15}{18}\selectfont%
+ \color{gold}\bfseries%
+}
+
+\newcommand\plannerLandscapeDayFmt{%
+ \plannerLandscapeDayFont%
+ \fontsize{10}{12}\selectfont%
+}
+
+\newcommand*\plannerLandscapeDateDayFormat[1]{%
+ \plannerLandscapeDateDayFont%
+ \fontsize{8}{11}\selectfont%
+ #1%
+}
+
+\newcommand\plannerLandscapeBeginDayScopeHook{%
+ \ifdate{weekend}{\color{black!60}}{}
+}
+
+\newlength\plannerLandscapeDayXShift
+\newlength\plannerLandscapeMonthYShift
+
+% Assuming 25mm to fit 'September'
+\setlength{\@tmp@a}{\calPaperWidth - \@wall@leftMargin - \@wall@rightMargin - 25mm}
+% Max week shift is 6 = Sunday. 31 days + 6 = 37. 1/37 = 0.027
+\setlength{\plannerLandscapeDayXShift}{0.027\@tmp@a}
+
+% Assuming 10mm for day headings (M T W...) and some padding
+\setlength{\@tmp@a}{\calPaperHeight - \@wall@topMargin - \@wall@bottomMargin - 10mm}
+% 1/12 = 0.0833
+\setlength{\plannerLandscapeMonthYShift}{0.0833\@tmp@a}
+
+\tikzstyle{year planner landscape}=[
+ month list,
+ day xshift=\plannerLandscapeDayXShift,
+ month yshift=\plannerLandscapeMonthYShift,
+ every month/.append style={anchor=base, inner xsep=0pt},
+ month text={\plannerLandscapeMonthFmt \%mt},
+ day text={\plannerLandscapeDayFmt \%d-},
+ every day/.append style={anchor=base, inner xsep=0pt},
+ month label left,
+ execute at begin day scope={
+ \plannerLandscapeBeginDayScopeHook
+ % Weekday headers in January
+ \ifdate{between=01-01 and 01-31}{
+ \def\l{\ifcase\pgfcalendarcurrentweekday M\or T\or W\or T\or F\or S\or S\fi}%
+ \ifdate{weekend}{\def\daylabelcolor{gold}}{\def\daylabelcolor{black}}%
+ \node[anchor=south,yshift=5mm,inner sep=0pt]{\color{\daylabelcolor}\plannerLandscapeDateDayFormat{\l}};%
+ }{}
+ % Weekday headers in December
+ \ifdate{between=12-01 and 12-31}{
+ \pgftransformyshift{-3mm}%
+ \def\l{\ifcase\pgfcalendarcurrentweekday M\or T\or W\or T\or F\or S\or S\fi}%
+ \ifdate{weekend}{\def\daylabelcolor{gold}}{\def\daylabelcolor{black}}%
+ \node[anchor=south,yshift=5mm,inner sep=0pt]{\color{\daylabelcolor}\plannerLandscapeDateDayFormat{\l}};%
+ }{}
+ }
+]
+
+\newcommand\plannerGridMonthFont{}
+\newcommand\plannerGridDateDayFont{}
+\newcommand\plannerGridNotesFont{}
+\newcommand\plannerGridDayFont{}
+\newcommand\plannerGridYearNumberFont{}
+
+\newcommand\plannerGridYearNumberFmt{%
+ \plannerGridYearNumberFont%
+ \fontsize{11}{11}\selectfont%
+ \color{white}%
+}
+
+\newcommand\plannerGridMonthFmt{%
+ \plannerGridMonthFont%
+ \fontsize{13}{13}\selectfont%
+ \color{white}%
+}
+
+\newcommand\plannerGridDayFmt{%
+ \plannerGridDayFont%
+ \fontsize{11}{11}\selectfont%
+}
+
+\newcommand\plannerGridDateDayFmt{%
+ \plannerGridDateDayFont%
+ \fontsize{9}{9}\selectfont%
+ \color{black!80}%
+}
+
+\newcommand{\plannerGridNotesFmt}{%
+ \plannerGridNotesFont%
+ \fontsize{11}{11}\selectfont%
+}
+
+\newcommand\plannerGridBeginDayScopeHook{%
+ \ifdate{weekend}{\color{black!60}}{}
+}
+
+\newlength\plannerGridColXShift
+\newlength\plannerGridRowYShift
+
+\newlength\plannerGridCalendarWidth
+\newlength\plannerGridCalendarHeight
+
+\newlength\plannerGridDayHeadingsHeight
+\newlength\plannerGridMonthNamesWidth
+
+\newlength\plannerGridNotesHeight
+\setlength{\plannerGridNotesHeight}{10mm}
+
+\setlength{\plannerGridCalendarWidth}{\calPaperWidth - \@wall@leftMargin - \@wall@rightMargin}
+\setlength{\plannerGridCalendarHeight}{\calPaperHeight - \@wall@topMargin - \@wall@bottomMargin - \plannerGridNotesHeight}
+
+\setlength{\plannerGridDayHeadingsHeight}{10mm}
+\setlength{\plannerGridMonthNamesWidth}{10mm}
+
+\setlength{\@tmp@a}{\plannerGridCalendarWidth - \plannerGridMonthNamesWidth}
+% 37 columns. 1/37 = 0.027. Max week shift is 6 = Sunday. 31 days + 6 = 37.
+\setlength{\plannerGridColXShift}{0.027\@tmp@a}
+
+\setlength{\@tmp@a}{\plannerGridCalendarHeight - 2\plannerGridDayHeadingsHeight}
+% 12 rows. 1/12 = 0.0833
+\setlength{\plannerGridRowYShift}{0.0833\@tmp@a}
+
+\newcounter{verticalCount}
+
+\tikzstyle{year planner landscape grid days}=[
+ month list,
+ day xshift=\plannerGridColXShift,
+ month yshift=\plannerGridRowYShift,
+ day text={\plannerGridDayFmt \%d-},
+ every day/.append style={anchor=base, yshift=-12pt, inner xsep=0pt},
+ execute at begin day scope={%
+ % White fill to cover the page background color
+ \node (cell) [
+ rectangle,
+ fill = white,
+ minimum height = \plannerGridRowYShift - 1pt,
+ minimum width = \plannerGridColXShift - 1pt,
+ xshift = -0.5\plannerGridColXShift,
+ yshift = 4.5pt,
+ ] {};%
+ %
+ \ifdate{Monday}{%
+ \node (a) [above left = 15pt and -3.5pt of cell.west] {};
+ \node (b) [below left = 15pt and -3.5pt of cell.west] {};
+ \node (c) [right = 10pt of cell.west] {};
+ \path [on layer = one, fill = pagebgcolor] (a.south) -- (b.north) -- (c.west) -- (a.south);%
+ }{}%
+ %
+ \ifdate{Sunday}{%
+ \node (a) [above left = 15pt and {-3.5pt + 1pt} of cell.east] {};
+ \node (b) [below left = 15pt and {-3.5pt + 1pt} of cell.east] {};
+ \node (c) [right = {10pt - 1pt} of cell.east] {};
+ \path [on layer = two, fill = white] (a.south) -- (b.north) -- (c.west) -- (a.south);%
+ }{}%
+ %
+ \plannerGridBeginDayScopeHook%
+ },
+]
+
+\newcommand\plannerMarksDayTextCSV{\@wall@eventsCsv}
+\newcommand\plannerMarksNoteCSV{\@wall@eventsCsv}
+\newcommand\plannerMarkDefaultsCsv{}
+
+\newcommand\@wall@plm[1]{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+monthMarksDayText(\luastring{#1}, nil, \luastring{\plannerMarksDayTextCSV})
+tex.sprint(';')
+}}
+
+\newcommand\@wall@plmYear{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+yearMarksDayText(tonumber(\CalendarYear), nil, \luastring{\plannerMarksDayTextCSV})
+tex.sprint(';')
+}}
+
+\newcommand\@wall@plNotes{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+yearMarksNote(tonumber(\CalendarYear), nil, \luastring{\plannerMarksNoteCSV}, \luastring{\plannerMarkDefaultsCsv}, false)
+}}
+
+\newcommand\@wall@plNotesOneCalendar{%
+\luadirect{
+require("wallcalendar-helpers.lua")
+yearMarksNote(tonumber(\CalendarYear), nil, \luastring{\plannerMarksNoteCSV}, \luastring{\plannerMarkDefaultsCsv}, true)
+}}
+
+\newcommand\plannerEvents{%
+\parseYearEvents[filter pred = hasNote]%
+}
+
+\newcommand\YearPlannerPortrait{%
+\@wall@useDefaultMoons%
+\begin{tikzpicture}[every calendar/.style={year planner portrait}]%
+ \matrix[column sep=1.5em, row sep=5mm] {
+ \calendar(cal01)[dates=\CalendarYear-01-01 to \CalendarYear-01-last] \@wall@plm{January}; \pgfmatrixnextcell
+ \calendar(cal02)[dates=\CalendarYear-02-01 to \CalendarYear-02-last] \@wall@plm{February}; \pgfmatrixnextcell
+ \calendar(cal03)[dates=\CalendarYear-03-01 to \CalendarYear-03-last] \@wall@plm{March}; \\
+ \calendar(cal04)[dates=\CalendarYear-04-01 to \CalendarYear-04-last] \@wall@plm{April}; \pgfmatrixnextcell
+ \calendar(cal05)[dates=\CalendarYear-05-01 to \CalendarYear-05-last] \@wall@plm{May}; \pgfmatrixnextcell
+ \calendar(cal06)[dates=\CalendarYear-06-01 to \CalendarYear-06-last] \@wall@plm{June}; \\
+ \calendar(cal07)[dates=\CalendarYear-07-01 to \CalendarYear-07-last] \@wall@plm{July}; \pgfmatrixnextcell
+ \calendar(cal08)[dates=\CalendarYear-08-01 to \CalendarYear-08-last] \@wall@plm{August}; \pgfmatrixnextcell
+ \calendar(cal09)[dates=\CalendarYear-09-01 to \CalendarYear-09-last] \@wall@plm{September}; \\
+ \calendar(cal10)[dates=\CalendarYear-10-01 to \CalendarYear-10-last] \@wall@plm{October}; \pgfmatrixnextcell
+ \calendar(cal11)[dates=\CalendarYear-11-01 to \CalendarYear-11-last] \@wall@plm{November}; \pgfmatrixnextcell
+ \calendar(cal12)[dates=\CalendarYear-12-01 to \CalendarYear-12-last] \@wall@plm{December}; \\
+ };
+ \@wall@plNotes
+\end{tikzpicture}%
+}
+
+\newcommand\YearPlannerLandscape{%
+\@wall@usePlannerMoons%
+\begin{tikzpicture}%
+ \calendar (cal) [
+ year planner landscape,
+ dates=\CalendarYear-01-01 to \CalendarYear-12-31,
+ ] \@wall@plmYear;
+ \@wall@plNotesOneCalendar
+\end{tikzpicture}%
+}
+
+\newcommand\YearPlannerLandscapeGrid{%
+\@wall@usePlannerMoons%
+\begin{tikzpicture}
+
+ % Background frame
+
+ \node (bg) [
+ rectangle,
+ inner sep = 0pt,
+ minimum width = \plannerGridCalendarWidth,
+ minimum height = \plannerGridCalendarHeight,
+ ] {};
+
+ \foreach \x/\m in {1/\xJanShort, 2/\xFebShort, 3/\xMarShort, 4/\xAprShort,
+ 5/\xMayShort, 6/\xJunShort, 7/\xJulShort, 8/\xAugShort, 9/\xSepShort,
+ 10/\xOctShort, 11/\xNovShort, 12/\xDecShort}
+ {
+ \setlength{\@tmp@a}{\x\plannerGridRowYShift + \plannerGridDayHeadingsHeight}
+
+ % Month labels
+
+ \node [
+ below = \@tmp@a of bg.north west,
+ yshift = 0.5\plannerGridRowYShift,
+ xshift = 0.5\plannerGridColXShift - 2pt,
+ anchor = base,
+ rotate = 90,
+ ] {\plannerGridMonthFmt\MakeUppercase{\textls*{\m}}};
+
+ % Horizontal lines
+
+ \addtolength{\@tmp@a}{-\plannerGridRowYShift}
+
+ \node (h-a-\x) [below = \@tmp@a of bg.north west] {};
+ \node (h-b-\x) [below = \@tmp@a of bg.north east] {};
+ \draw [gridcolor] (h-a-\x) -- (h-b-\x);
+ }
+
+ % 13th line
+ \setlength{\@tmp@a}{12\plannerGridRowYShift + \plannerGridDayHeadingsHeight}
+ \node (h-a-13) [below = \@tmp@a of bg.north west] {};
+ \node (h-b-13) [below = \@tmp@a of bg.north east] {};
+ \draw [gridcolor] (h-a-13) -- (h-b-13);
+
+ % Year number in the corner
+ \node [
+ right = 0pt of bg.north west,
+ xshift = 0.5\plannerGridMonthNamesWidth,
+ yshift = -0.5\plannerGridDayHeadingsHeight - 5pt,
+ anchor = base,
+ ] {\plannerGridYearNumberFmt\CalendarYear};
+
+ \setcounter{verticalCount}{1}
+
+ \foreach \i in {0,1,2,3,4,5} {
+ \foreach \j/\d in {
+ 0/\xMondayDayLetter,
+ 1/\xTuesdayDayLetter,
+ 2/\xWednesdayDayLetter,
+ 3/\xThursdayDayLetter,
+ 4/\xFridayDayLetter,
+ 5/\xSaturdayDayLetter,
+ 6/\xSundayDayLetter}
+ {
+ \addtocounter{verticalCount}{1}
+ \ifnumgreater{\value{verticalCount}}{38}{\relax}{
+ \setlength{\@tmp@a}{7\plannerGridColXShift}
+ \setlength{\@tmp@a}{\i\@tmp@a + \j\plannerGridColXShift + \plannerGridMonthNamesWidth}
+
+ % Day headings (top and bottom)
+
+ \node [
+ right = \@tmp@a of bg.north west,
+ xshift = 0.5\plannerGridColXShift + 4pt,
+ yshift = -0.5\plannerGridDayHeadingsHeight - 5pt,
+ anchor = base,
+ ] {\plannerGridDateDayFmt \d};
+
+ \node [
+ right = \@tmp@a of bg.south west,
+ xshift = 0.5\plannerGridColXShift + 4pt,
+ yshift = 0.5\plannerGridDayHeadingsHeight - 5pt,
+ anchor = base,
+ ] {\plannerGridDateDayFmt \d};
+
+ % % Vertical lines
+
+ % \node (v-a-\i-\j) [right = \@tmp@a of bg.north west] {};
+ % \node (v-b-\i-\j) [right = \@tmp@a of bg.south west] {};
+ % \draw [gridcolor] (v-a-\i-\j) -- (v-b-\i-\j);
+ }
+ }
+ }
+
+ \calendar (cal) [
+ year planner landscape grid days,
+ dates=\CalendarYear-01-01 to \CalendarYear-12-31,
+ below right = 0pt and 0pt of bg.north west,
+ anchor = north west,
+ yshift = -\plannerGridDayHeadingsHeight - 3mm,
+ xshift = \plannerGridMonthNamesWidth + 0.5\plannerGridColXShift + 4pt,
+ ] \@wall@plmYear;
+
+ \@wall@plNotesOneCalendar
+
+\end{tikzpicture}%
+}
+
+\newcommand{\YearPlannerLandscapeGridPage}{%
+\pagecolor{pagebgcolor}%
+\AddToShipoutPictureFG*{\put(\LenToUnit{\@wall@leftMargin},\LenToUnit{\@wall@bottomMargin})%
+{\begin{minipage}[b]{\plannerGridCalendarWidth}%
+\YearPlannerLandscapeGrid
+
+\begin{minipage}[b][10mm][c]{\plannerGridCalendarWidth}%
+\plannerGridNotesFmt
+\hspace*{2mm}%
+\parseYearEvents[%
+ filter pred = hasNote,
+ format cmd = {\textsuperscript{\eIdx}~\eMonthShort~\eDay:~\textit{\eNote}\ifnumless{\eIdx}{\eMaxIdx}{,\space}{.}},
+]%
+\end{minipage}%
+\end{minipage}%
+}}}
+
+% Load internal translations
+\InputIfFileExists{i18n/wallcalendar-\@wall@calendarLanguage.tex}{}%
+{\ClassError{wallcalendar}{File Not Found: i18n/wallcalendar-\@wall@calendarLanguage.tex}{}}
+
+% Load user translations if the option was set and translationsAutoload is true
+
+\newcommand\LoadTranslations{%
+\InputIfFileExists{\@wall@translationsInputFile}{}%
+{\ClassWarning{wallcalendar}{File Not Found: \@wall@translationsInputFile}{}}}
+
+\notblank{\@wall@translationsInputFile}{%
+\iftranslationsAutoload \LoadTranslations \fi}
+
+\newcommand*\@tr@monthNumName[1]{%
+\ifcase#1 \relax\or \xJanuary\or \xFebruary\or \xMarch\or \xApril\or \xMay\or \xJune\or
+\xJuly\or \xAugust\or \xSeptember\or \xOctober\or \xNovember\or \xDecember\fi}
+
+\newcommand*\@tr@dayLetter[1]{%
+\ifcase#1 \xMondayDayLetter\or \xTuesdayDayLetter\or \xWednesdayDayLetter\or
+\xThursdayDayLetter\or \xFridayDayLetter\or \xSaturdayDayLetter\or \xSundayDayLetter\fi}
+
+\newcommand*{\monthToNum}[1]{%
+\luadirect{
+ local monthToNum = {
+ january = '01',
+ february = '02',
+ march = '03',
+ april = '04',
+ may = '05',
+ june = '06',
+ july = '07',
+ august = '08',
+ september = '09',
+ october = '10',
+ november = '11',
+ december = '12',
+ }
+ local key = string.lower('#1')
+ tex.sprint(monthToNum[key])
+}}
+
+\newcommand*\monthName[1]{%
+% \ifcase might be just fine here
+\luadirect{
+ local monthName = {
+ 'January', 'February', 'March', 'April', 'May', 'June', 'July',
+ 'August', 'September', 'October', 'November', 'December',
+ }
+ local key = tonumber('#1')
+ tex.sprint(monthName[key])
+}}
+
+% End of wallcalendar.cls
diff --git a/macros/luatex/latex/wallcalendar/wallcalendar.pdf b/macros/luatex/latex/wallcalendar/wallcalendar.pdf
new file mode 100644
index 0000000000..2ee862c318
--- /dev/null
+++ b/macros/luatex/latex/wallcalendar/wallcalendar.pdf
Binary files differ